From 85b7bc695629926641c7cb752fd478adfdf374f3 Mon Sep 17 00:00:00 2001 From: Marius Date: Sun, 4 Jul 2010 15:32:09 +0300 Subject: stable 2010-05-24 13:10 --- tex/context/base/anch-bar.mkii | 194 + tex/context/base/anch-bar.mkiv | 179 + tex/context/base/anch-pgr.mkii | 1687 + tex/context/base/anch-pgr.mkiv | 1727 + tex/context/base/anch-pos.lua | 166 + tex/context/base/anch-pos.mkii | 877 + tex/context/base/anch-pos.mkiv | 784 + tex/context/base/anch-snc.mkii | 177 + tex/context/base/anch-snc.mkiv | 185 + tex/context/base/attr-ini.lua | 648 + tex/context/base/attr-ini.mkiv | 170 + tex/context/base/back-ini.lua | 143 + tex/context/base/back-ini.mkiv | 168 + tex/context/base/back-pdf.lua | 469 + tex/context/base/back-pdf.mkiv | 178 + tex/context/base/back-u3d.mkiv | 156 + tex/context/base/bibl-bib.lua | 762 + tex/context/base/bibl-bib.mkiv | 962 + tex/context/base/bibl-tra.lua | 194 + tex/context/base/bibl-tra.mkii | 1778 + tex/context/base/bibl-tra.mkiv | 1552 + tex/context/base/bibl-tst.lua | 21 + tex/context/base/blob-ini.lua | 165 + tex/context/base/blob-ini.mkiv | 34 + tex/context/base/buff-ini.lua | 838 + tex/context/base/buff-ini.mkii | 348 + tex/context/base/buff-ini.mkiv | 355 + tex/context/base/buff-ver.mkii | 1340 + tex/context/base/buff-ver.mkiv | 1193 + tex/context/base/bxml-apa.mkiv | 613 + tex/context/base/catc-act.tex | 61 + tex/context/base/catc-ctx.tex | 250 + tex/context/base/catc-def.tex | 142 + tex/context/base/catc-ini.lua | 33 + tex/context/base/catc-ini.mkii | 249 + tex/context/base/catc-ini.mkiv | 317 + tex/context/base/catc-sym.tex | 187 + tex/context/base/char-act.mkiv | 138 + tex/context/base/char-cmp.lua | 268 + tex/context/base/char-def.lua | 141127 +++++++++++++++++++++++++ tex/context/base/char-enc.lua | 163 + tex/context/base/char-enc.mkiv | 18 + tex/context/base/char-ini.lua | 698 + tex/context/base/char-ini.mkiv | 76 + tex/context/base/char-map.lua | 1069 + tex/context/base/char-tex.lua | 89 + tex/context/base/char-utf.lua | 273 + tex/context/base/char-utf.mkiv | 47 + tex/context/base/chem-ini.lua | 75 + tex/context/base/chem-ini.mkiv | 47 + tex/context/base/chem-str.lua | 490 + tex/context/base/chem-str.mkiv | 529 + tex/context/base/colo-ema.tex | 590 + tex/context/base/colo-ext.mkii | 59 + tex/context/base/colo-ext.mkiv | 103 + tex/context/base/colo-hex.mkii | 125 + tex/context/base/colo-hex.mkiv | 28 + tex/context/base/colo-hex.tex | 3 + tex/context/base/colo-ini.lua | 480 + tex/context/base/colo-ini.mkii | 2776 + tex/context/base/colo-ini.mkiv | 1091 + tex/context/base/colo-rgb.tex | 530 + tex/context/base/colo-run.tex | 257 + tex/context/base/colo-x11.tex | 677 + tex/context/base/colo-xwi.tex | 142 + tex/context/base/cont-cs.tex | 39 + tex/context/base/cont-de.tex | 44 + tex/context/base/cont-en.tex | 46 + tex/context/base/cont-err.tex | 18 + tex/context/base/cont-fil.tex | 124 + tex/context/base/cont-fr.tex | 42 + tex/context/base/cont-gb.tex | 42 + tex/context/base/cont-it.tex | 41 + tex/context/base/cont-log.tex | 359 + tex/context/base/cont-mtx.tex | 25 + tex/context/base/cont-new.mkii | 22 + tex/context/base/cont-new.mkiv | 40 + tex/context/base/cont-new.tex | 992 + tex/context/base/cont-nl.tex | 42 + tex/context/base/cont-old.tex | 48 + tex/context/base/cont-pe.tex | 45 + tex/context/base/cont-ro.tex | 38 + tex/context/base/cont-sys.ori | 182 + tex/context/base/cont-usr.ori | 109 + tex/context/base/context-base.lmx | 76 + tex/context/base/context-characters.lmx | 110 + tex/context/base/context-debug.lmx | 112 + tex/context/base/context-error.lmx | 59 + 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 | 241 + tex/context/base/context.mkii | 391 + tex/context/base/context.mkiv | 380 + tex/context/base/context.rme | 85 + tex/context/base/context.tex | 225 + tex/context/base/core-con.lua | 605 + tex/context/base/core-con.mkii | 969 + tex/context/base/core-con.mkiv | 860 + tex/context/base/core-ctx.lua | 93 + tex/context/base/core-ctx.mkii | 203 + tex/context/base/core-ctx.mkiv | 28 + tex/context/base/core-def.mkii | 105 + tex/context/base/core-def.mkiv | 94 + tex/context/base/core-env.mkii | 543 + tex/context/base/core-env.mkiv | 388 + tex/context/base/core-fil.mkii | 347 + tex/context/base/core-fil.mkiv | 284 + tex/context/base/core-fnt.mkii | 726 + tex/context/base/core-fnt.mkiv | 293 + tex/context/base/core-gen.mkii | 166 + tex/context/base/core-gen.mkiv | 166 + tex/context/base/core-ini.mkii | 67 + tex/context/base/core-ini.mkiv | 66 + tex/context/base/core-job.lua | 202 + tex/context/base/core-job.mkii | 415 + tex/context/base/core-job.mkiv | 309 + tex/context/base/core-mis.mkii | 2742 + tex/context/base/core-mis.mkiv | 2505 + tex/context/base/core-par.mkii | 300 + tex/context/base/core-stg.mkii | 72 + tex/context/base/core-sys.lua | 22 + tex/context/base/core-sys.mkii | 396 + tex/context/base/core-sys.mkiv | 432 + tex/context/base/core-two.lua | 137 + tex/context/base/core-two.mkii | 206 + tex/context/base/core-two.mkiv | 106 + tex/context/base/core-uti.lua | 294 + tex/context/base/core-uti.mkii | 349 + tex/context/base/core-uti.mkiv | 66 + tex/context/base/core-var.mkii | 286 + tex/context/base/core-var.mkiv | 270 + tex/context/base/data-aux.lua | 57 + tex/context/base/data-bin.lua | 27 + tex/context/base/data-con.lua | 120 + tex/context/base/data-crl.lua | 60 + tex/context/base/data-ctx.lua | 31 + 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 | 63 + tex/context/base/data-lua.lua | 152 + tex/context/base/data-out.lua | 10 + tex/context/base/data-pre.lua | 109 + tex/context/base/data-res.lua | 2181 + tex/context/base/data-sch.lua | 142 + tex/context/base/data-tex.lua | 226 + tex/context/base/data-tmf.lua | 75 + tex/context/base/data-tmp.lua | 178 + tex/context/base/data-tre.lua | 47 + tex/context/base/data-use.lua | 129 + tex/context/base/data-zip.lua | 241 + tex/context/base/enco-032.mkii | 82 + tex/context/base/enco-037.mkii | 276 + tex/context/base/enco-acc.mkii | 139 + tex/context/base/enco-agr.mkii | 364 + tex/context/base/enco-ans.mkii | 237 + tex/context/base/enco-cas.mkii | 143 + tex/context/base/enco-chi.mkii | 371 + tex/context/base/enco-com.mkii | 37 + tex/context/base/enco-cyr.mkii | 1037 + tex/context/base/enco-def.mkii | 922 + tex/context/base/enco-ec.mkii | 295 + tex/context/base/enco-ecm.mkii | 33 + tex/context/base/enco-el.mkii | 272 + tex/context/base/enco-fde.mkii | 128 + tex/context/base/enco-ffr.mkii | 57 + tex/context/base/enco-fpl.mkii | 98 + tex/context/base/enco-fro.mkii | 35 + tex/context/base/enco-fsl.mkii | 32 + tex/context/base/enco-grk.mkii | 190 + tex/context/base/enco-heb.mkii | 16 + tex/context/base/enco-ibm.mkii | 7 + tex/context/base/enco-il2.mkii | 157 + tex/context/base/enco-ini.mkii | 1137 + tex/context/base/enco-ini.mkiv | 536 + tex/context/base/enco-l7x.mkii | 236 + tex/context/base/enco-lat.mkii | 7 + tex/context/base/enco-mis.mkii | 188 + tex/context/base/enco-pdf.mkii | 278 + tex/context/base/enco-pfr.mkii | 305 + tex/context/base/enco-pol.mkii | 276 + tex/context/base/enco-qx.mkii | 266 + tex/context/base/enco-raw.mkii | 119 + tex/context/base/enco-run.mkii | 149 + tex/context/base/enco-t5.mkii | 244 + tex/context/base/enco-tbo.mkii | 222 + tex/context/base/enco-uc.mkii | 1091 + tex/context/base/enco-vis.mkii | 3 + tex/context/base/enco-vna.mkii | 145 + tex/context/base/enco-win.mkii | 7 + tex/context/base/enco-x5.mkii | 218 + tex/context/base/filt-bas.mkii | 63 + tex/context/base/filt-ini.mkii | 121 + tex/context/base/font-afm.lua | 855 + tex/context/base/font-agl.lua | 3695 + tex/context/base/font-arb.mkii | 5 + tex/context/base/font-bfm.mkii | 196 + tex/context/base/font-chi.mkii | 1156 + tex/context/base/font-chk.lua | 90 + tex/context/base/font-cid.lua | 147 + tex/context/base/font-col.lua | 216 + tex/context/base/font-col.mkiv | 148 + tex/context/base/font-ctx.lua | 624 + tex/context/base/font-def.lua | 651 + tex/context/base/font-dum.lua | 301 + tex/context/base/font-enc.lua | 122 + tex/context/base/font-enh.lua | 201 + tex/context/base/font-ext.lua | 623 + tex/context/base/font-fbk.lua | 316 + tex/context/base/font-gds.lua | 294 + tex/context/base/font-gds.mkiv | 83 + tex/context/base/font-heb.mkii | 5 + tex/context/base/font-ini.lua | 95 + tex/context/base/font-ini.mkii | 4573 + tex/context/base/font-ini.mkiv | 3896 + tex/context/base/font-jap.mkii | 83 + tex/context/base/font-log.lua | 58 + tex/context/base/font-map.lua | 370 + tex/context/base/font-mis.lua | 101 + tex/context/base/font-ota.lua | 286 + tex/context/base/font-otb.lua | 373 + tex/context/base/font-otc.lua | 213 + tex/context/base/font-otd.lua | 78 + tex/context/base/font-otf.lua | 1752 + tex/context/base/font-oti.lua | 57 + tex/context/base/font-otn.lua | 2660 + tex/context/base/font-otp.lua | 504 + tex/context/base/font-ott.lua | 956 + tex/context/base/font-pat.lua | 126 + tex/context/base/font-run.mkii | 326 + tex/context/base/font-run.mkiv | 337 + tex/context/base/font-syn.lua | 1454 + tex/context/base/font-tfm.lua | 736 + 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-unk.mkii | 187 + tex/context/base/font-unk.mkiv | 162 + tex/context/base/font-vf.lua | 213 + tex/context/base/font-xtx.lua | 122 + tex/context/base/font-xtx.mkii | 376 + tex/context/base/grph-fig.mkii | 559 + tex/context/base/grph-fig.mkiv | 640 + tex/context/base/grph-fil.lua | 42 + tex/context/base/grph-inc.lua | 1115 + tex/context/base/grph-inc.mkii | 1243 + tex/context/base/grph-inc.mkiv | 433 + tex/context/base/grph-swf.lua | 43 + tex/context/base/grph-trf.mkii | 579 + tex/context/base/grph-trf.mkiv | 580 + tex/context/base/grph-u3d.lua | 49 + tex/context/base/hand-def.mkii | 577 + tex/context/base/hand-ini.mkii | 483 + tex/context/base/hand-ini.mkiv | 74 + tex/context/base/java-ans.tex | 28 + tex/context/base/java-exa.tex | 395 + tex/context/base/java-fil.tex | 48 + tex/context/base/java-fld.tex | 282 + tex/context/base/java-ini.lua | 120 + tex/context/base/java-ini.mkii | 713 + tex/context/base/java-ini.mkiv | 164 + tex/context/base/java-stp.tex | 121 + tex/context/base/l-aux.lua | 261 + tex/context/base/l-boolean.lua | 55 + tex/context/base/l-dimen.lua | 432 + tex/context/base/l-dir.lua | 363 + tex/context/base/l-file.lua | 314 + tex/context/base/l-io.lua | 187 + tex/context/base/l-lpeg.lua | 165 + tex/context/base/l-math.lua | 41 + tex/context/base/l-md5.lua | 72 + tex/context/base/l-number.lua | 58 + tex/context/base/l-os.lua | 301 + tex/context/base/l-pdfview.lua | 95 + tex/context/base/l-set.lua | 84 + tex/context/base/l-string.lua | 288 + tex/context/base/l-table.lua | 910 + tex/context/base/l-unicode.lua | 199 + tex/context/base/l-url.lua | 134 + tex/context/base/l-utils.lua | 176 + tex/context/base/l-xml.lua | 23 + tex/context/base/lang-all.xml | 376 + tex/context/base/lang-alt.tex | 152 + tex/context/base/lang-ana.tex | 24 + tex/context/base/lang-ara.mkiv | 150 + tex/context/base/lang-art.tex | 26 + tex/context/base/lang-bal.tex | 118 + tex/context/base/lang-cel.tex | 26 + tex/context/base/lang-chi.mkii | 305 + tex/context/base/lang-cjk.mkiv | 328 + tex/context/base/lang-ctx.mkii | 53 + tex/context/base/lang-cyr.tex | 371 + tex/context/base/lang-dis.mkii | 59 + tex/context/base/lang-frd.tex | 140 + tex/context/base/lang-frq.tex | 207 + tex/context/base/lang-ger.tex | 738 + tex/context/base/lang-grk.tex | 94 + tex/context/base/lang-ind.tex | 26 + tex/context/base/lang-ini.lua | 321 + tex/context/base/lang-ini.mkii | 696 + tex/context/base/lang-ini.mkiv | 560 + tex/context/base/lang-ita.tex | 518 + tex/context/base/lang-jap.mkii | 234 + tex/context/base/lang-lab.mkii | 295 + tex/context/base/lang-lab.mkiv | 283 + tex/context/base/lang-mis.mkii | 683 + tex/context/base/lang-mis.mkiv | 689 + tex/context/base/lang-run.mkii | 36 + tex/context/base/lang-sla.mkii | 30 + tex/context/base/lang-sla.mkiv | 17 + tex/context/base/lang-sla.tex | 497 + tex/context/base/lang-spa.tex | 74 + tex/context/base/lang-spe.mkii | 244 + tex/context/base/lang-ura.tex | 158 + tex/context/base/lang-url.lua | 101 + tex/context/base/lang-url.mkii | 306 + tex/context/base/lang-url.mkiv | 117 + tex/context/base/lang-vn.tex | 92 + tex/context/base/lang-wrd.lua | 225 + tex/context/base/lang-wrd.mkiv | 54 + tex/context/base/lpdf-ano.lua | 589 + tex/context/base/lpdf-col.lua | 150 + tex/context/base/lpdf-fld.lua | 885 + tex/context/base/lpdf-grp.lua | 68 + tex/context/base/lpdf-ini.lua | 670 + tex/context/base/lpdf-ini.mkiv | 271 + tex/context/base/lpdf-mis.lua | 292 + tex/context/base/lpdf-nod.lua | 53 + tex/context/base/lpdf-pdx.lua | 139 + tex/context/base/lpdf-pdx.mkiv | 71 + tex/context/base/lpdf-ren.lua | 207 + tex/context/base/lpdf-swf.lua | 109 + tex/context/base/lpdf-u3d.lua | 474 + tex/context/base/lpdf-wid.lua | 355 + tex/context/base/lpdf-xmp.lua | 165 + tex/context/base/lpdf-xmp.xml | 43 + tex/context/base/luat-bas.mkiv | 65 + tex/context/base/luat-cbk.lua | 247 + tex/context/base/luat-cnf.lua | 115 + tex/context/base/luat-cod.mkiv | 161 + tex/context/base/luat-dum.lua | 126 + tex/context/base/luat-env.lua | 283 + tex/context/base/luat-exe.lua | 71 + tex/context/base/luat-fio.lua | 83 + tex/context/base/luat-ini.lua | 162 + tex/context/base/luat-ini.mkiv | 243 + tex/context/base/luat-iop.lua | 148 + tex/context/base/luat-lib.mkiv | 70 + tex/context/base/luat-lua.lua | 43 + tex/context/base/luat-run.lua | 74 + tex/context/base/luat-soc.lua | 11 + tex/context/base/luat-sta.lua | 196 + tex/context/base/luat-sto.lua | 135 + tex/context/base/lxml-aux.lua | 543 + tex/context/base/lxml-ctx.lua | 131 + tex/context/base/lxml-ctx.mkiv | 64 + tex/context/base/lxml-dir.lua | 112 + tex/context/base/lxml-ent.lua | 69 + tex/context/base/lxml-inf.lua | 53 + tex/context/base/lxml-ini.mkiv | 414 + tex/context/base/lxml-lpt.lua | 1259 + tex/context/base/lxml-mis.lua | 99 + tex/context/base/lxml-sor.lua | 158 + tex/context/base/lxml-sor.mkiv | 94 + tex/context/base/lxml-tab.lua | 1174 + tex/context/base/lxml-tex.lua | 1410 + tex/context/base/lxml-xml.lua | 288 + tex/context/base/m-arabtex.tex | 450 + tex/context/base/m-barcodes.mkiv | 122 + tex/context/base/m-chart.mkii | 48 + tex/context/base/m-chart.mkiv | 20 + tex/context/base/m-chart.tex | 1285 + tex/context/base/m-chemic.mkii | 21 + tex/context/base/m-chemic.mkiv | 20 + tex/context/base/m-chemic.tex | 17 + tex/context/base/m-cweb.tex | 1371 + tex/context/base/m-database.tex | 421 + tex/context/base/m-datastrc.tex | 228 + tex/context/base/m-directives.tex | 5 + tex/context/base/m-dratex.tex | 21 + tex/context/base/m-edtsnc.tex | 207 + tex/context/base/m-educat.tex | 217 + tex/context/base/m-format.tex | 409 + tex/context/base/m-graph.mkii | 72 + tex/context/base/m-graph.mkiv | 63 + tex/context/base/m-graph.tex | 175 + tex/context/base/m-layout.tex | 102 + tex/context/base/m-level.tex | 94 + tex/context/base/m-mkii.mkiv | 21 + tex/context/base/m-mkivhacks.tex | 52 + tex/context/base/m-narrowtt.tex | 39 + tex/context/base/m-newmat.tex | 337 + tex/context/base/m-obsolete.tex | 5 + tex/context/base/m-pdfsnc.tex | 200 + tex/context/base/m-pictex.tex | 255 + tex/context/base/m-plus.tex | 30 + tex/context/base/m-pstricks.lua | 73 + tex/context/base/m-pstricks.mkii | 127 + tex/context/base/m-pstricks.mkiv | 66 + tex/context/base/m-pstricks.tex | 16 + tex/context/base/m-punk.mkiv | 243 + tex/context/base/m-punk.tex | 3 + tex/context/base/m-quest.tex | 232 + tex/context/base/m-r.tex | 174 + tex/context/base/m-steps.mkii | 83 + tex/context/base/m-steps.mkiv | 20 + tex/context/base/m-steps.tex | 835 + tex/context/base/m-streams.tex | 446 + tex/context/base/m-subsub.tex | 76 + tex/context/base/m-tex4ht.tex | 9 + tex/context/base/m-timing.tex | 102 + tex/context/base/m-trackers.tex | 5 + tex/context/base/m-translate.tex | 88 + tex/context/base/m-tryout.tex | 55 + tex/context/base/m-units.tex | 825 + tex/context/base/m-visual.tex | 316 + tex/context/base/math-ali.mkiv | 1296 + tex/context/base/math-ams.mkii | 336 + tex/context/base/math-arr.mkii | 391 + tex/context/base/math-arr.mkiv | 439 + tex/context/base/math-cow.mkii | 31 + tex/context/base/math-def.mkiv | 374 + tex/context/base/math-del.mkiv | 63 + tex/context/base/math-dim.lua | 313 + tex/context/base/math-dis.mkiv | 20 + tex/context/base/math-ent.lua | 2102 + tex/context/base/math-eul.mkii | 277 + tex/context/base/math-ext.lua | 154 + tex/context/base/math-for.mkiv | 79 + tex/context/base/math-fou.mkii | 196 + tex/context/base/math-frc.mkii | 66 + tex/context/base/math-frc.mkiv | 209 + tex/context/base/math-ini.lua | 340 + tex/context/base/math-ini.mkii | 684 + tex/context/base/math-ini.mkiv | 657 + tex/context/base/math-inl.mkiv | 26 + tex/context/base/math-int.mkiv | 90 + tex/context/base/math-lan.mkiv | 67 + tex/context/base/math-lbr.mkii | 481 + tex/context/base/math-map.lua | 440 + tex/context/base/math-noa.lua | 369 + tex/context/base/math-pln.mkii | 360 + tex/context/base/math-pln.mkiv | 298 + tex/context/base/math-run.mkii | 105 + tex/context/base/math-scr.mkiv | 135 + tex/context/base/math-tex.mkii | 720 + tex/context/base/math-tim.mkii | 371 + tex/context/base/math-uni.mkii | 237 + tex/context/base/math-vfu.lua | 1379 + tex/context/base/meta-clp.tex | 164 + tex/context/base/meta-dum.tex | 123 + tex/context/base/meta-fig.mkii | 89 + tex/context/base/meta-fig.mkiv | 84 + tex/context/base/meta-fun.lua | 55 + tex/context/base/meta-fun.mkiv | 20 + tex/context/base/meta-ini.mkii | 1054 + tex/context/base/meta-ini.mkiv | 1275 + tex/context/base/meta-mis.tex | 54 + tex/context/base/meta-nav.tex | 65 + tex/context/base/meta-pag.mkii | 226 + tex/context/base/meta-pag.mkiv | 223 + tex/context/base/meta-pdf.lua | 553 + tex/context/base/meta-pdf.mkii | 2761 + tex/context/base/meta-pdf.mkiv | 474 + tex/context/base/meta-pdh.lua | 602 + tex/context/base/meta-pdh.mkiv | 780 + tex/context/base/meta-pre.tex | 68 + tex/context/base/meta-tex.mkii | 350 + tex/context/base/meta-tex.mkiv | 72 + tex/context/base/meta-txt.tex | 304 + tex/context/base/meta-xml.tex | 29 + tex/context/base/metatex.tex | 154 + tex/context/base/mlib-ctx.lua | 84 + tex/context/base/mlib-ctx.mkiv | 81 + tex/context/base/mlib-pdf.lua | 530 + tex/context/base/mlib-pdf.mkiv | 91 + tex/context/base/mlib-pps.lua | 897 + tex/context/base/mlib-pps.mkiv | 70 + tex/context/base/mlib-run.lua | 379 + tex/context/base/mtx-context-arrange.tex | 111 + tex/context/base/mtx-context-combine.tex | 116 + tex/context/base/mtx-context-common.tex | 43 + tex/context/base/mtx-context-ideas.tex | 52 + tex/context/base/mtx-context-listing.tex | 100 + tex/context/base/mtx-context-timing.tex | 44 + tex/context/base/mult-chk.lua | 66 + tex/context/base/mult-chk.mkii | 29 + tex/context/base/mult-chk.mkiv | 103 + tex/context/base/mult-cld.lua | 212 + tex/context/base/mult-cld.mkiv | 29 + tex/context/base/mult-clm.lua | 184 + tex/context/base/mult-com.tex | 31 + tex/context/base/mult-con.tex | 53 + tex/context/base/mult-de.tex | 1693 + tex/context/base/mult-def.lua | 16149 +++ tex/context/base/mult-def.tex | 35 + tex/context/base/mult-en.tex | 1693 + tex/context/base/mult-fr.tex | 1693 + tex/context/base/mult-fst.tex | 53 + tex/context/base/mult-ini.lua | 105 + tex/context/base/mult-ini.mkii | 935 + tex/context/base/mult-ini.mkiv | 865 + tex/context/base/mult-it.tex | 1693 + tex/context/base/mult-mcs.tex | 208 + tex/context/base/mult-mde.tex | 208 + tex/context/base/mult-men.tex | 208 + tex/context/base/mult-mes.lua | 2046 + tex/context/base/mult-mfr.tex | 208 + tex/context/base/mult-mit.tex | 208 + tex/context/base/mult-mnl.tex | 208 + tex/context/base/mult-mno.tex | 208 + tex/context/base/mult-mpe.tex | 208 + tex/context/base/mult-mro.tex | 208 + tex/context/base/mult-nl.tex | 1693 + tex/context/base/mult-ro.tex | 1693 + tex/context/base/mult-sys.tex | 882 + tex/context/base/node-aux.lua | 145 + tex/context/base/node-bck.lua | 119 + tex/context/base/node-bck.mkiv | 163 + tex/context/base/node-dir.lua | 308 + tex/context/base/node-dum.lua | 19 + tex/context/base/node-ext.lua | 30 + tex/context/base/node-fin.lua | 442 + tex/context/base/node-fin.mkiv | 74 + tex/context/base/node-fnt.lua | 207 + tex/context/base/node-ini.lua | 244 + tex/context/base/node-ini.mkiv | 90 + tex/context/base/node-inj.lua | 466 + tex/context/base/node-mig.lua | 120 + tex/context/base/node-mig.mkiv | 60 + tex/context/base/node-pag.lua | 30 + tex/context/base/node-pag.mkiv | 20 + tex/context/base/node-par.lua | 101 + tex/context/base/node-par.mkiv | 78 + tex/context/base/node-pro.lua | 149 + tex/context/base/node-ref.lua | 533 + tex/context/base/node-res.lua | 302 + tex/context/base/node-rul.lua | 288 + tex/context/base/node-rul.mkiv | 343 + tex/context/base/node-seq.lua | 186 + tex/context/base/node-ser.lua | 276 + tex/context/base/node-shp.lua | 58 + tex/context/base/node-tex.lua | 39 + tex/context/base/node-tra.lua | 474 + tex/context/base/node-tsk.lua | 315 + tex/context/base/node-tst.lua | 119 + tex/context/base/node-typ.lua | 53 + 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/pack-bar.mkiv | 67 + tex/context/base/pack-box.mkii | 954 + tex/context/base/pack-box.mkiv | 944 + tex/context/base/pack-lyr.mkii | 755 + tex/context/base/pack-lyr.mkiv | 786 + tex/context/base/pack-obj.lua | 54 + tex/context/base/pack-obj.mkii | 371 + tex/context/base/pack-obj.mkiv | 399 + tex/context/base/pack-rul.lua | 53 + tex/context/base/pack-rul.mkii | 3650 + tex/context/base/pack-rul.mkiv | 3686 + tex/context/base/page-app.mkii | 225 + tex/context/base/page-app.mkiv | 225 + tex/context/base/page-bck.mkii | 593 + tex/context/base/page-bck.mkiv | 563 + tex/context/base/page-flt.lua | 227 + tex/context/base/page-flt.mkiv | 233 + tex/context/base/page-flw.mkii | 107 + tex/context/base/page-flw.mkiv | 107 + tex/context/base/page-imp.mkii | 1314 + tex/context/base/page-imp.mkiv | 1299 + tex/context/base/page-ini.mkii | 1558 + tex/context/base/page-ini.mkiv | 1512 + tex/context/base/page-ins.mkii | 103 + tex/context/base/page-ins.mkiv | 94 + tex/context/base/page-lay.mkii | 1429 + tex/context/base/page-lay.mkiv | 1425 + tex/context/base/page-lin.lua | 215 + tex/context/base/page-lin.mkii | 312 + tex/context/base/page-lin.mkiv | 498 + tex/context/base/page-log.mkii | 202 + tex/context/base/page-mak.mkii | 234 + tex/context/base/page-mak.mkiv | 233 + tex/context/base/page-mar.mkii | 867 + tex/context/base/page-mar.mkiv | 824 + tex/context/base/page-mis.mkii | 268 + tex/context/base/page-mis.mkiv | 239 + tex/context/base/page-mul.mkii | 1773 + tex/context/base/page-mul.mkiv | 1751 + tex/context/base/page-not.mkii | 72 + tex/context/base/page-not.mkiv | 69 + tex/context/base/page-one.mkii | 659 + tex/context/base/page-one.mkiv | 532 + tex/context/base/page-par.mkii | 58 + tex/context/base/page-par.mkiv | 58 + tex/context/base/page-plg.mkii | 202 + tex/context/base/page-plg.mkiv | 198 + tex/context/base/page-run.mkii | 382 + tex/context/base/page-run.mkiv | 382 + tex/context/base/page-set.mkii | 2766 + tex/context/base/page-set.mkiv | 2674 + tex/context/base/page-sid.mkii | 931 + tex/context/base/page-sid.mkiv | 795 + tex/context/base/page-spr.mkii | 104 + tex/context/base/page-spr.mkiv | 103 + tex/context/base/page-str.lua | 221 + tex/context/base/page-str.mkii | 376 + tex/context/base/page-str.mkiv | 144 + tex/context/base/page-txt.mkii | 784 + tex/context/base/page-txt.mkiv | 850 + tex/context/base/pdfr-def.mkii | 843 + tex/context/base/pdfr-ec.mkii | 145 + tex/context/base/pdfr-il2.mkii | 233 + tex/context/base/ppchtex.mkii | 3554 + tex/context/base/ppchtex.mkiv | 3460 + tex/context/base/pret-lua.lua | 319 + tex/context/base/pret-mp.lua | 236 + tex/context/base/pret-tex.lua | 87 + tex/context/base/pret-xml.lua | 136 + tex/context/base/prop-ini.mkii | 150 + tex/context/base/prop-ini.mkiv | 150 + tex/context/base/prop-lay.mkii | 143 + tex/context/base/prop-lay.mkiv | 140 + tex/context/base/prop-mis.mkii | 189 + tex/context/base/prop-mis.mkiv | 74 + tex/context/base/regi-8859-1.lua | 26 + tex/context/base/regi-8859-1.mkii | 154 + tex/context/base/regi-8859-10.lua | 26 + tex/context/base/regi-8859-10.mkii | 152 + tex/context/base/regi-8859-11.lua | 26 + tex/context/base/regi-8859-13.lua | 26 + tex/context/base/regi-8859-13.mkii | 152 + tex/context/base/regi-8859-14.lua | 26 + tex/context/base/regi-8859-15.lua | 26 + tex/context/base/regi-8859-15.mkii | 154 + tex/context/base/regi-8859-16.lua | 26 + tex/context/base/regi-8859-16.mkii | 151 + tex/context/base/regi-8859-2.lua | 26 + tex/context/base/regi-8859-2.mkii | 152 + tex/context/base/regi-8859-3.lua | 26 + tex/context/base/regi-8859-3.mkii | 145 + tex/context/base/regi-8859-4.lua | 26 + tex/context/base/regi-8859-4.mkii | 152 + tex/context/base/regi-8859-5.lua | 26 + tex/context/base/regi-8859-5.mkii | 152 + tex/context/base/regi-8859-6.lua | 26 + tex/context/base/regi-8859-7.lua | 26 + tex/context/base/regi-8859-7.mkii | 153 + tex/context/base/regi-8859-8.lua | 26 + tex/context/base/regi-8859-9.lua | 26 + tex/context/base/regi-8859-9.mkii | 152 + tex/context/base/regi-cp1250.lua | 26 + tex/context/base/regi-cp1250.mkii | 153 + tex/context/base/regi-cp1251.lua | 26 + tex/context/base/regi-cp1251.mkii | 152 + tex/context/base/regi-cp1252.lua | 26 + tex/context/base/regi-cp1252.mkii | 156 + tex/context/base/regi-cp1253.lua | 26 + tex/context/base/regi-cp1253.mkii | 153 + tex/context/base/regi-cp1254.lua | 26 + tex/context/base/regi-cp1254.mkii | 153 + tex/context/base/regi-cp1255.lua | 26 + tex/context/base/regi-cp1256.lua | 26 + tex/context/base/regi-cp1257.lua | 26 + tex/context/base/regi-cp1257.mkii | 153 + tex/context/base/regi-cp1258.lua | 26 + tex/context/base/regi-cyp.mkii | 1169 + tex/context/base/regi-cyr.mkii | 722 + tex/context/base/regi-def.mkii | 21 + tex/context/base/regi-ibm.mkii | 73 + tex/context/base/regi-ini.lua | 88 + tex/context/base/regi-ini.mkii | 248 + tex/context/base/regi-ini.mkiv | 55 + tex/context/base/regi-mac.mkii | 147 + tex/context/base/regi-syn.tex | 73 + tex/context/base/regi-uni.mkii | 24 + tex/context/base/regi-utf.mkii | 52 + tex/context/base/regi-vis.mkii | 158 + tex/context/base/rlxcache.rlx | 71 + tex/context/base/rlxtools.rlx | 136 + tex/context/base/s-abr-01.tex | 324 + tex/context/base/s-abr-02.tex | 22 + tex/context/base/s-abr-03.tex | 22 + tex/context/base/s-cdr-01.tex | 131 + tex/context/base/s-chi-00.tex | 76 + tex/context/base/s-faq-00.tex | 93 + tex/context/base/s-faq-01.tex | 215 + tex/context/base/s-faq-02.tex | 63 + tex/context/base/s-faq-03.tex | 70 + tex/context/base/s-fnt-01.tex | 61 + tex/context/base/s-fnt-02.tex | 133 + tex/context/base/s-fnt-10.tex | 163 + 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 | 194 + tex/context/base/s-fnt-26.tex | 73 + tex/context/base/s-fnt-30.tex | 42 + tex/context/base/s-grk-00.tex | 77 + tex/context/base/s-inf-01.tex | 203 + tex/context/base/s-inf-02.tex | 27 + tex/context/base/s-jap-00.tex | 23 + tex/context/base/s-mag-01.tex | 406 + tex/context/base/s-map-10.tex | 488 + tex/context/base/s-mod-00.tex | 512 + tex/context/base/s-mod-01.tex | 157 + tex/context/base/s-mod-02.tex | 420 + tex/context/base/s-mod.ctx | 24 + tex/context/base/s-pre-00.tex | 202 + tex/context/base/s-pre-01.tex | 404 + tex/context/base/s-pre-02.tex | 381 + tex/context/base/s-pre-03.tex | 257 + tex/context/base/s-pre-04.tex | 377 + tex/context/base/s-pre-05.tex | 240 + tex/context/base/s-pre-06.tex | 325 + tex/context/base/s-pre-07.tex | 212 + tex/context/base/s-pre-08.tex | 271 + tex/context/base/s-pre-09.tex | 380 + tex/context/base/s-pre-10.tex | 308 + tex/context/base/s-pre-11.tex | 220 + tex/context/base/s-pre-12.tex | 226 + tex/context/base/s-pre-13.tex | 302 + tex/context/base/s-pre-14.tex | 264 + tex/context/base/s-pre-15.tex | 186 + tex/context/base/s-pre-16.tex | 203 + tex/context/base/s-pre-17.tex | 399 + tex/context/base/s-pre-18.tex | 177 + tex/context/base/s-pre-19.tex | 347 + tex/context/base/s-pre-22.tex | 319 + tex/context/base/s-pre-23.tex | 109 + tex/context/base/s-pre-26.tex | 255 + tex/context/base/s-pre-27.tex | 181 + tex/context/base/s-pre-30.tex | 258 + tex/context/base/s-pre-50.tex | 101 + tex/context/base/s-pre-60.tex | 159 + tex/context/base/s-pre-61.tex | 273 + tex/context/base/s-pre-62.tex | 228 + tex/context/base/s-pre-63.tex | 73 + tex/context/base/s-pre-64.tex | 203 + tex/context/base/s-pre-66.tex | 133 + tex/context/base/s-pre-67.tex | 144 + tex/context/base/s-pre-70.tex | 170 + tex/context/base/s-pre-71.tex | 210 + tex/context/base/s-pre-93.tex | 210 + tex/context/base/s-ptj-01.tex | 425 + tex/context/base/s-reg-01.tex | 50 + tex/context/base/s-syn-01.tex | 54 + tex/context/base/s-sys-01.tex | 61 + tex/context/base/scrn-bar.mkiv | 398 + tex/context/base/scrn-but.mkiv | 127 + tex/context/base/scrn-fld.mkii | 1247 + tex/context/base/scrn-fld.mkiv | 686 + tex/context/base/scrn-hlp.mkii | 171 + tex/context/base/scrn-hlp.mkiv | 179 + tex/context/base/scrn-int.lua | 111 + tex/context/base/scrn-int.mkii | 2311 + tex/context/base/scrn-int.mkiv | 610 + tex/context/base/scrn-men.mkiv | 615 + tex/context/base/scrn-nav.mkii | 379 + tex/context/base/scrn-nav.mkiv | 256 + tex/context/base/scrp-cjk.lua | 577 + tex/context/base/scrp-ini.lua | 388 + tex/context/base/scrp-ini.mkiv | 91 + tex/context/base/sort-def.mkii | 450 + tex/context/base/sort-ini.lua | 317 + tex/context/base/sort-ini.mkii | 161 + tex/context/base/sort-ini.mkiv | 19 + tex/context/base/sort-lan.lua | 319 + tex/context/base/sort-lan.mkii | 217 + tex/context/base/spac-ali.mkiv | 677 + tex/context/base/spac-def.mkiv | 118 + tex/context/base/spac-fnt.mkiv | 94 + tex/context/base/spac-gen.mkii | 4652 + tex/context/base/spac-grd.mkii | 1074 + tex/context/base/spac-grd.mkiv | 259 + tex/context/base/spac-hor.lua | 32 + tex/context/base/spac-hor.mkiv | 946 + tex/context/base/spac-pag.mkiv | 199 + tex/context/base/spac-par.mkiv | 192 + tex/context/base/spac-ver.lua | 1185 + tex/context/base/spac-ver.mkiv | 2078 + tex/context/base/spec-def.mkii | 1016 + tex/context/base/spec-dpm.mkii | 446 + tex/context/base/spec-dpx.mkii | 794 + tex/context/base/spec-dvi.mkii | 118 + tex/context/base/spec-fdf.mkii | 3531 + tex/context/base/spec-ini.mkii | 559 + tex/context/base/spec-mis.mkii | 286 + tex/context/base/spec-pdf.mkii | 484 + tex/context/base/spec-ps.mkii | 229 + tex/context/base/spec-tpd.mkii | 1334 + tex/context/base/spec-tr.mkii | 107 + tex/context/base/spec-tst.mkii | 52 + tex/context/base/spec-var.mkii | 83 + tex/context/base/spec-win.mkii | 99 + tex/context/base/spec-xet.mkii | 66 + tex/context/base/spec-xtx.mkii | 87 + tex/context/base/spec-yy.mkii | 90 + tex/context/base/strc-bkm.lua | 131 + tex/context/base/strc-bkm.mkiv | 93 + tex/context/base/strc-blk.lua | 146 + tex/context/base/strc-blk.mkii | 548 + tex/context/base/strc-blk.mkiv | 112 + tex/context/base/strc-def.mkiv | 309 + tex/context/base/strc-des.lua | 9 + tex/context/base/strc-des.mkii | 921 + tex/context/base/strc-des.mkiv | 1097 + tex/context/base/strc-doc.lua | 702 + tex/context/base/strc-doc.mkiv | 216 + tex/context/base/strc-flt.lua | 9 + tex/context/base/strc-flt.mkii | 2143 + tex/context/base/strc-flt.mkiv | 1964 + tex/context/base/strc-ini.lua | 302 + tex/context/base/strc-ini.mkiv | 88 + tex/context/base/strc-itm.lua | 24 + tex/context/base/strc-itm.mkii | 1335 + tex/context/base/strc-itm.mkiv | 1365 + tex/context/base/strc-lnt.mkii | 197 + tex/context/base/strc-lnt.mkiv | 173 + tex/context/base/strc-lst.lua | 486 + tex/context/base/strc-lst.mkii | 1150 + tex/context/base/strc-lst.mkiv | 963 + tex/context/base/strc-mar.lua | 18 + tex/context/base/strc-mar.mkii | 318 + tex/context/base/strc-mar.mkiv | 495 + tex/context/base/strc-mat.lua | 51 + tex/context/base/strc-mat.mkii | 2925 + tex/context/base/strc-mat.mkiv | 771 + tex/context/base/strc-not.lua | 338 + tex/context/base/strc-not.mkii | 1472 + tex/context/base/strc-not.mkiv | 1280 + tex/context/base/strc-num.lua | 521 + tex/context/base/strc-num.mkii | 151 + tex/context/base/strc-num.mkiv | 511 + tex/context/base/strc-pag.lua | 241 + tex/context/base/strc-pag.mkii | 534 + tex/context/base/strc-pag.mkiv | 496 + tex/context/base/strc-prc.lua | 9 + tex/context/base/strc-prc.mkiv | 84 + tex/context/base/strc-ref.lua | 1243 + tex/context/base/strc-ref.mkii | 3041 + tex/context/base/strc-ref.mkiv | 1851 + tex/context/base/strc-reg.lua | 735 + tex/context/base/strc-reg.mkii | 1243 + tex/context/base/strc-reg.mkiv | 1137 + tex/context/base/strc-ren.mkiv | 492 + tex/context/base/strc-sbe.mkiv | 141 + tex/context/base/strc-sec.mkii | 2591 + tex/context/base/strc-sec.mkiv | 792 + tex/context/base/strc-swd.mkii | 127 + tex/context/base/strc-syn.lua | 189 + tex/context/base/strc-syn.mkii | 438 + tex/context/base/strc-syn.mkiv | 431 + tex/context/base/strc-xml.mkiv | 144 + tex/context/base/supp-ali.tex | 173 + tex/context/base/supp-box.tex | 3126 + tex/context/base/supp-dir.mkii | 41 + tex/context/base/supp-dir.mkiv | 41 + tex/context/base/supp-emp.mkii | 398 + tex/context/base/supp-eps.mkii | 202 + tex/context/base/supp-fil.lua | 279 + tex/context/base/supp-fil.mkii | 710 + tex/context/base/supp-fil.mkiv | 464 + tex/context/base/supp-fun.tex | 746 + tex/context/base/supp-mat.mkii | 293 + tex/context/base/supp-mat.mkiv | 293 + tex/context/base/supp-mis.mkii | 733 + tex/context/base/supp-mis.tex | 4 + tex/context/base/supp-mpe.mkii | 1370 + tex/context/base/supp-mpe.tex | 4 + tex/context/base/supp-mps.mkii | 2134 + tex/context/base/supp-mrk.mkii | 591 + tex/context/base/supp-num.tex | 443 + tex/context/base/supp-pat.mkii | 179 + tex/context/base/supp-pdf.mkii | 2187 + tex/context/base/supp-pdf.tex | 1 + tex/context/base/supp-ran.lua | 67 + tex/context/base/supp-ran.mkii | 122 + tex/context/base/supp-ran.mkiv | 30 + tex/context/base/supp-spe.mkii | 164 + tex/context/base/supp-tpi.mkii | 353 + tex/context/base/supp-vis.tex | 1907 + tex/context/base/symb-cow.tex | 132 + tex/context/base/symb-eur.tex | 64 + tex/context/base/symb-glm.tex | 79 + tex/context/base/symb-ini.mkii | 281 + tex/context/base/symb-ini.mkiv | 281 + tex/context/base/symb-jmn.tex | 204 + tex/context/base/symb-mis.tex | 139 + tex/context/base/symb-mvs.tex | 217 + tex/context/base/symb-nav.tex | 126 + tex/context/base/symb-run.mkii | 54 + tex/context/base/symb-run.mkiv | 54 + tex/context/base/symb-uni.tex | 1123 + tex/context/base/symb-was.tex | 205 + tex/context/base/syst-aux.mkiv | 7018 ++ tex/context/base/syst-con.lua | 25 + tex/context/base/syst-con.mkii | 243 + tex/context/base/syst-con.mkiv | 145 + tex/context/base/syst-ext.mkii | 5025 + tex/context/base/syst-fnt.mkii | 46 + tex/context/base/syst-fnt.mkiv | 46 + tex/context/base/syst-gen.mkii | 4454 + tex/context/base/syst-ini.tex | 888 + tex/context/base/syst-ltx.tex | 56 + tex/context/base/syst-lua.lua | 109 + tex/context/base/syst-lua.mkiv | 37 + tex/context/base/syst-new.mkii | 868 + tex/context/base/syst-pln.tex | 118 + tex/context/base/syst-rtp.mkii | 18 + tex/context/base/syst-rtp.mkiv | 18 + tex/context/base/syst-str.mkii | 124 + tex/context/base/syst-str.mkiv | 36 + tex/context/base/syst-tex.mkii | 314 + tex/context/base/tabl-com.mkii | 21 + tex/context/base/tabl-com.mkiv | 21 + tex/context/base/tabl-ltb.mkii | 866 + tex/context/base/tabl-ltb.mkiv | 866 + tex/context/base/tabl-ntb.mkii | 1586 + tex/context/base/tabl-ntb.mkiv | 1622 + tex/context/base/tabl-nte.mkii | 107 + tex/context/base/tabl-nte.mkiv | 107 + tex/context/base/tabl-pln.mkii | 91 + tex/context/base/tabl-pln.mkiv | 91 + tex/context/base/tabl-tab.mkii | 2515 + tex/context/base/tabl-tab.mkiv | 2516 + tex/context/base/tabl-tbl.mkii | 1440 + tex/context/base/tabl-tbl.mkiv | 1516 + tex/context/base/tabl-tsp.mkii | 427 + tex/context/base/tabl-tsp.mkiv | 429 + tex/context/base/task-ini.lua | 94 + tex/context/base/task-ini.mkiv | 22 + tex/context/base/thrd-pic.tex | 3694 + tex/context/base/thrd-ran.mkii | 168 + tex/context/base/thrd-tab.tex | 2006 + tex/context/base/thrd-trg.mkii | 127 + tex/context/base/toks-ini.lua | 326 + tex/context/base/toks-ini.mkiv | 78 + tex/context/base/trac-deb.lua | 187 + tex/context/base/trac-deb.mkiv | 51 + tex/context/base/trac-inf.lua | 197 + tex/context/base/trac-lmx.lua | 223 + tex/context/base/trac-lmx.mkiv | 16 + tex/context/base/trac-log.lua | 320 + tex/context/base/trac-tex.mkiv | 55 + tex/context/base/trac-tim.lua | 160 + tex/context/base/trac-tra.lua | 341 + tex/context/base/trac-vis.mkii | 748 + tex/context/base/trac-vis.mkiv | 709 + tex/context/base/type-buy.mkii | 571 + tex/context/base/type-buy.mkiv | 82 + tex/context/base/type-cbg.mkii | 352 + tex/context/base/type-cow.mkii | 85 + tex/context/base/type-cow.mkiv | 85 + tex/context/base/type-def.mkii | 86 + tex/context/base/type-def.mkiv | 48 + tex/context/base/type-exp.mkii | 95 + tex/context/base/type-fsf.mkii | 94 + tex/context/base/type-ghz.mkii | 409 + tex/context/base/type-ghz.mkiv | 322 + tex/context/base/type-hgz.mkii | 1 + tex/context/base/type-hgz.mkiv | 1 + tex/context/base/type-husayni-default.mkiv | 146 + tex/context/base/type-ini.mkii | 725 + tex/context/base/type-ini.mkiv | 578 + tex/context/base/type-lua.mkiv | 88 + tex/context/base/type-mac.mkii | 593 + tex/context/base/type-mac.mkiv | 593 + tex/context/base/type-msw.mkii | 1 + tex/context/base/type-msw.mkiv | 1 + tex/context/base/type-one.mkii | 2748 + tex/context/base/type-one.mkiv | 113 + tex/context/base/type-otf.mkii | 2033 + tex/context/base/type-otf.mkiv | 1796 + tex/context/base/type-pre.mkii | 253 + tex/context/base/type-run.mkii | 51 + tex/context/base/type-run.mkiv | 51 + tex/context/base/type-set.mkii | 81 + tex/context/base/type-set.mkiv | 77 + tex/context/base/type-siz.mkii | 748 + tex/context/base/type-siz.mkiv | 398 + tex/context/base/type-tmf.mkii | 14 + tex/context/base/type-tmf.mkiv | 14 + tex/context/base/type-win.mkii | 69 + tex/context/base/type-win.mkiv | 118 + tex/context/base/type-xtx.mkii | 563 + tex/context/base/typo-brk.lua | 208 + tex/context/base/typo-brk.mkiv | 93 + tex/context/base/typo-cap.lua | 210 + tex/context/base/typo-cap.mkiv | 212 + tex/context/base/typo-dig.lua | 106 + tex/context/base/typo-dig.mkiv | 51 + tex/context/base/typo-ini.mkii | 40 + tex/context/base/typo-ini.mkiv | 40 + tex/context/base/typo-krn.lua | 223 + tex/context/base/typo-krn.mkiv | 79 + tex/context/base/typo-mir.lua | 419 + tex/context/base/typo-mir.mkiv | 144 + tex/context/base/typo-rep.lua | 135 + tex/context/base/typo-rep.mkiv | 53 + tex/context/base/typo-spa.lua | 167 + tex/context/base/typo-spa.mkiv | 69 + tex/context/base/unic-000.mkii | 135 + tex/context/base/unic-001.mkii | 220 + tex/context/base/unic-002.mkii | 104 + tex/context/base/unic-003.mkii | 147 + tex/context/base/unic-004.mkii | 291 + tex/context/base/unic-005.mkii | 50 + tex/context/base/unic-030.mkii | 113 + tex/context/base/unic-031.mkii | 273 + tex/context/base/unic-032.mkii | 278 + tex/context/base/unic-033.mkii | 275 + tex/context/base/unic-034.mkii | 274 + tex/context/base/unic-035.mkii | 32 + tex/context/base/unic-037.mkii | 278 + tex/context/base/unic-039.mkii | 68 + tex/context/base/unic-251.mkii | 34 + tex/context/base/unic-cjk.mkii | 22 + tex/context/base/unic-exp.mkii | 82 + tex/context/base/unic-ini.mkii | 777 + tex/context/base/unic-ini.mkiv | 29 + tex/context/base/unic-run.mkii | 130 + tex/context/base/verb-c.mkii | 484 + tex/context/base/verb-eif.mkii | 211 + tex/context/base/verb-ini.mkii | 1789 + tex/context/base/verb-js.mkii | 171 + tex/context/base/verb-jv.mkii | 222 + tex/context/base/verb-mp.mkii | 364 + tex/context/base/verb-pas.mkii | 266 + tex/context/base/verb-pl.mkii | 547 + tex/context/base/verb-raw.mkii | 7 + tex/context/base/verb-sql.mkii | 230 + tex/context/base/verb-tex.mkii | 294 + tex/context/base/verb-xml.mkii | 441 + tex/context/base/x-asciimath.lua | 267 + tex/context/base/x-asciimath.mkiv | 96 + tex/context/base/x-calcmath.lua | 363 + tex/context/base/x-calcmath.mkii | 24 + tex/context/base/x-calcmath.mkiv | 87 + tex/context/base/x-cals.lua | 209 + tex/context/base/x-cals.mkiv | 36 + tex/context/base/x-chemml.mkii | 212 + tex/context/base/x-chemml.mkiv | 262 + tex/context/base/x-chemml.tex | 16 + tex/context/base/x-chemml.xsd | 93 + tex/context/base/x-contml.mkii | 491 + tex/context/base/x-contml.xsd | 375 + tex/context/base/x-corres.mkii | 136 + tex/context/base/x-corres.rng | 170 + tex/context/base/x-ct.lua | 182 + tex/context/base/x-ct.mkiv | 29 + tex/context/base/x-dir-01.tex | 145 + tex/context/base/x-dir-05.mkii | 51 + tex/context/base/x-dir-05.mkiv | 72 + tex/context/base/x-fdf-00.tex | 41 + tex/context/base/x-fe.mkii | 143 + tex/context/base/x-fig-00.dtd | 24 + tex/context/base/x-fig-00.tex | 252 + tex/context/base/x-fig-00.xsd | 77 + tex/context/base/x-fig-01.tex | 461 + tex/context/base/x-fig-02.tex | 78 + tex/context/base/x-fig-03.tex | 44 + tex/context/base/x-fo.mkii | 4059 + tex/context/base/x-foxet.mkii | 28 + tex/context/base/x-foxet.mkiv | 29 + tex/context/base/x-ldx.ctx | 23 + tex/context/base/x-ldx.tex | 191 + tex/context/base/x-mathml.lua | 784 + tex/context/base/x-mathml.mkii | 28 + tex/context/base/x-mathml.mkiv | 2369 + tex/context/base/x-mathml.tex | 16 + tex/context/base/x-mathml.xsd | 11 + tex/context/base/x-newcml.tex | 456 + tex/context/base/x-newmme.tex | 423 + tex/context/base/x-newmml.mkii | 2744 + tex/context/base/x-newmml.mkiv | 16 + tex/context/base/x-newmml.tex | 16 + tex/context/base/x-newmmo.tex | 210 + tex/context/base/x-newpml.tex | 250 + tex/context/base/x-om2cml.xsl | 1342 + tex/context/base/x-openmath.tex | 4 + tex/context/base/x-openmath.xsl | 35 + tex/context/base/x-pending.mkiv | 39 + tex/context/base/x-physml.mkii | 16 + tex/context/base/x-physml.mkiv | 16 + tex/context/base/x-physml.tex | 16 + tex/context/base/x-physml.xsd | 172 + tex/context/base/x-res-00.tex | 67 + tex/context/base/x-res-01.tex | 487 + tex/context/base/x-res-02.tex | 72 + tex/context/base/x-res-03.tex | 44 + tex/context/base/x-res-04.tex | 336 + tex/context/base/x-res-08.tex | 131 + tex/context/base/x-res-09.tex | 69 + tex/context/base/x-res-10.tex | 75 + tex/context/base/x-res-11.tex | 110 + tex/context/base/x-res-12.tex | 53 + tex/context/base/x-res-20.tex | 231 + tex/context/base/x-res-50.tex | 425 + tex/context/base/x-sch-00.tex | 382 + tex/context/base/x-sch-01.tex | 122 + tex/context/base/x-set-01.tex | 79 + tex/context/base/x-set-02.tex | 30 + tex/context/base/x-set-11.mkii | 573 + tex/context/base/x-set-11.mkiv | 476 + tex/context/base/x-set-11.tex | 110 + tex/context/base/x-set-12.tex | 258 + tex/context/base/x-set-99.tex | 283 + tex/context/base/x-sm2om.xsl | 233 + tex/context/base/x-xml-01.tex | 91 + tex/context/base/x-xml-02.tex | 91 + tex/context/base/x-xml-11.tex | 134 + tex/context/base/x-xtag.mkiv | 23 + tex/context/base/xetx-chr.mkii | 1167 + tex/context/base/xetx-cls.mkii | 378 + tex/context/base/xetx-ini.mkii | 132 + tex/context/base/xetx-utf.mkii | 1989 + tex/context/base/xtag-cml.tex | 228 + tex/context/base/xtag-ent.tex | 117 + tex/context/base/xtag-exp.tex | 88 + tex/context/base/xtag-ext.tex | 439 + tex/context/base/xtag-hyp.tex | 69 + tex/context/base/xtag-ini.tex | 2999 + tex/context/base/xtag-map.tex | 746 + tex/context/base/xtag-mea.tex | 152 + tex/context/base/xtag-meb.tex | 124 + tex/context/base/xtag-mec.tex | 28 + tex/context/base/xtag-meh.tex | 166 + tex/context/base/xtag-men.tex | 98 + tex/context/base/xtag-meo.tex | 58 + tex/context/base/xtag-mer.tex | 185 + tex/context/base/xtag-mmc.tex | 1265 + tex/context/base/xtag-mml.tex | 515 + tex/context/base/xtag-mmp.tex | 553 + tex/context/base/xtag-mxa.tex | 101 + tex/context/base/xtag-mxb.tex | 55 + tex/context/base/xtag-mxc.tex | 10 + tex/context/base/xtag-mxh.tex | 67 + tex/context/base/xtag-mxn.tex | 84 + tex/context/base/xtag-mxo.tex | 14 + tex/context/base/xtag-mxr.tex | 112 + tex/context/base/xtag-pml.tex | 85 + tex/context/base/xtag-pmu.tex | 188 + tex/context/base/xtag-pre.tex | 435 + tex/context/base/xtag-prs.tex | 42 + tex/context/base/xtag-raw.tex | 37 + tex/context/base/xtag-rng.tex | 28 + tex/context/base/xtag-run.tex | 319 + tex/context/base/xtag-stk.tex | 230 + tex/context/base/xtag-utf.tex | 21 + tex/context/base/xtag-xsd.tex | 28 + tex/context/base/xtag-xsl.tex | 224 + tex/context/bib/bibl-ams.tex | 437 + tex/context/bib/bibl-apa-de.tex | 386 + tex/context/bib/bibl-apa-fr.tex | 389 + tex/context/bib/bibl-apa.tex | 390 + tex/context/bib/bibl-aps.tex | 441 + tex/context/bib/bibl-num-fr.tex | 427 + tex/context/bib/bibl-num.tex | 427 + tex/context/bib/bibl-ssa.tex | 486 + tex/context/config/cont-usr.tex | 109 + tex/context/extra/mag-0000.tex | 44 + tex/context/extra/setup-qr.tex | 77 + tex/context/extra/showunic.tex | 130 + tex/context/fonts/antykwa-math.lfg | 57 + tex/context/fonts/charter-math.lfg | 28 + tex/context/fonts/garamond-math.lfg | 28 + tex/context/fonts/husayni.lfg | 178 + tex/context/fonts/hvmath-math.lfg | 24 + tex/context/fonts/informal-math.lfg | 22 + tex/context/fonts/iwona-math.lfg | 57 + tex/context/fonts/lm-math.lfg | 230 + tex/context/fonts/lucida-math.lfg | 320 + tex/context/fonts/mathtimes-math.lfg | 24 + tex/context/fonts/px-math.lfg | 24 + tex/context/fonts/symbol-math.lfg | 17 + tex/context/fonts/tx-math.lfg | 24 + tex/context/fonts/utopia-math.lfg | 28 + tex/context/foxet/fe-bryson.xml | 12 + tex/context/foxet/fe-ward.xml | 8 + tex/context/foxet/fe-zapf.xml | 14 + tex/context/foxet/fo-0101.fo | 17 + tex/context/foxet/fo-0102.fo | 25 + tex/context/foxet/fo-0103.fo | 21 + tex/context/foxet/fo-0201.fo | 22 + tex/context/foxet/fo-0301.fo | 56 + tex/context/foxet/fo-0601.fo | 29 + tex/context/foxet/fo-0602.fo | 27 + tex/context/foxet/fo-0603.fo | 26 + tex/context/foxet/fo-0604.fo | 26 + tex/context/foxet/fo-0611.fo | 21 + tex/context/foxet/fo-0612.fo | 21 + tex/context/foxet/fo-0613.fo | 21 + tex/context/foxet/fo-0621.fo | 106 + tex/context/foxet/fo-0641.fo | 25 + tex/context/foxet/fo-0642.fo | 27 + tex/context/foxet/fo-0643.fo | 27 + tex/context/foxet/fo-0644.fo | 27 + tex/context/foxet/fo-0650.fo | 26 + tex/context/foxet/fo-0651.fo | 26 + tex/context/foxet/fo-0701.fo | 39 + tex/context/foxet/fo-0801.fo | 55 + tex/context/foxet/fo-0901.fo | 58 + tex/context/foxet/fo-0902.fo | 33 + tex/context/foxet/fo-1001.fo | 63 + tex/context/foxet/fo-1002.fo | 31 + tex/context/foxet/fo-1003.fo | 31 + tex/context/foxet/fo-1004.fo | 35 + tex/context/foxet/fo-1101.fo | 63 + tex/context/foxet/fo-1102.fo | 128 + tex/context/foxet/fo-1103.fo | 85 + tex/context/foxet/fo-1104.fo | 28 + tex/context/foxet/fo-1201.fo | 40 + tex/context/interface/cont-cs.xml | 10290 ++ tex/context/interface/cont-de.xml | 10290 ++ tex/context/interface/cont-en.xml | 10290 ++ tex/context/interface/cont-fr.xml | 10290 ++ tex/context/interface/cont-it.xml | 10290 ++ tex/context/interface/cont-nl.xml | 10290 ++ tex/context/interface/cont-pe.xml | 10290 ++ tex/context/interface/cont-ro.xml | 10290 ++ tex/context/interface/keys-cs.xml | 1706 + tex/context/interface/keys-cz.xml | 1590 + tex/context/interface/keys-de.xml | 1706 + tex/context/interface/keys-en.xml | 1706 + tex/context/interface/keys-fr.xml | 1706 + tex/context/interface/keys-it.xml | 1706 + tex/context/interface/keys-nl.xml | 1706 + tex/context/interface/keys-pe.xml | 1706 + tex/context/interface/keys-ro.xml | 1706 + tex/context/patterns/lang-agr.hyp | 32 + tex/context/patterns/lang-agr.pat | 2880 + tex/context/patterns/lang-bg.hyp | 8 + tex/context/patterns/lang-bg.pat | 1667 + tex/context/patterns/lang-bg.rme | 43 + tex/context/patterns/lang-ca.hyp | 33 + tex/context/patterns/lang-ca.pat | 876 + tex/context/patterns/lang-ca.rme | 125 + tex/context/patterns/lang-cs.hyp | 12 + tex/context/patterns/lang-cs.pat | 3643 + tex/context/patterns/lang-cs.rme | 85 + tex/context/patterns/lang-cy.hyp | 8 + tex/context/patterns/lang-cy.pat | 6735 ++ tex/context/patterns/lang-cy.rme | 64 + tex/context/patterns/lang-da.hyp | 8 + tex/context/patterns/lang-da.pat | 1151 + tex/context/patterns/lang-da.rme | 74 + tex/context/patterns/lang-de.hyp | 8 + tex/context/patterns/lang-de.pat | 14218 +++ tex/context/patterns/lang-de.rme | 31 + tex/context/patterns/lang-deo.hyp | 8 + tex/context/patterns/lang-deo.pat | 14386 +++ tex/context/patterns/lang-deo.rme | 31 + tex/context/patterns/lang-es.hyp | 8 + tex/context/patterns/lang-es.pat | 3378 + tex/context/patterns/lang-es.rme | 25 + tex/context/patterns/lang-et.hyp | 8 + tex/context/patterns/lang-et.pat | 3698 + tex/context/patterns/lang-et.rme | 80 + tex/context/patterns/lang-eu.hyp | 8 + tex/context/patterns/lang-eu.pat | 199 + tex/context/patterns/lang-eu.rme | 45 + tex/context/patterns/lang-fi.hyp | 8 + tex/context/patterns/lang-fi.pat | 293 + tex/context/patterns/lang-fi.rme | 78 + tex/context/patterns/lang-fr.hyp | 8 + tex/context/patterns/lang-fr.pat | 1081 + tex/context/patterns/lang-fr.rme | 106 + tex/context/patterns/lang-gb.hyp | 15 + tex/context/patterns/lang-gb.pat | 8534 ++ tex/context/patterns/lang-gb.rme | 60 + tex/context/patterns/lang-hr.hyp | 8 + tex/context/patterns/lang-hr.pat | 1482 + tex/context/patterns/lang-hr.rme | 70 + tex/context/patterns/lang-hu.hyp | 8 + tex/context/patterns/lang-hu.pat | 62819 +++++++++++ tex/context/patterns/lang-hu.rme | 11 + tex/context/patterns/lang-is.hyp | 8 + tex/context/patterns/lang-is.pat | 4195 + tex/context/patterns/lang-is.rme | 79 + tex/context/patterns/lang-it.hyp | 8 + tex/context/patterns/lang-it.pat | 324 + tex/context/patterns/lang-it.rme | 88 + tex/context/patterns/lang-la.hyp | 8 + tex/context/patterns/lang-la.pat | 342 + tex/context/patterns/lang-la.rme | 105 + tex/context/patterns/lang-lt.hyp | 8 + tex/context/patterns/lang-lt.pat | 1553 + tex/context/patterns/lang-lt.rme | 47 + tex/context/patterns/lang-mn.hyp | 8 + tex/context/patterns/lang-mn.pat | 995 + tex/context/patterns/lang-mn.rme | 86 + tex/context/patterns/lang-nb.hyp | 52 + tex/context/patterns/lang-nb.pat | 27154 +++++ tex/context/patterns/lang-nb.rme | 134 + tex/context/patterns/lang-nl.hyp | 47 + tex/context/patterns/lang-nl.pat | 12731 +++ tex/context/patterns/lang-nl.rhl | 2907 + tex/context/patterns/lang-nl.rme | 98 + tex/context/patterns/lang-nl.rpl | 12948 +++ tex/context/patterns/lang-nn.hyp | 52 + tex/context/patterns/lang-nn.pat | 27154 +++++ tex/context/patterns/lang-nn.rme | 134 + tex/context/patterns/lang-pl.hyp | 27 + tex/context/patterns/lang-pl.pat | 4060 + tex/context/patterns/lang-pl.rme | 88 + tex/context/patterns/lang-pt.hyp | 9 + tex/context/patterns/lang-pt.pat | 313 + tex/context/patterns/lang-pt.rme | 86 + tex/context/patterns/lang-ro.hyp | 8 + tex/context/patterns/lang-ro.pat | 654 + tex/context/patterns/lang-ro.rme | 110 + tex/context/patterns/lang-ru.hyp | 191 + tex/context/patterns/lang-ru.pat | 4815 + tex/context/patterns/lang-ru.rme | 77 + tex/context/patterns/lang-sk.hyp | 12 + tex/context/patterns/lang-sk.pat | 2474 + tex/context/patterns/lang-sk.rme | 83 + tex/context/patterns/lang-sl.hyp | 8 + tex/context/patterns/lang-sl.pat | 1075 + tex/context/patterns/lang-sl.rme | 94 + tex/context/patterns/lang-sr.hyp | 137 + tex/context/patterns/lang-sr.pat | 2432 + tex/context/patterns/lang-sr.rme | 80 + tex/context/patterns/lang-sv.hyp | 8 + tex/context/patterns/lang-sv.pat | 4700 + tex/context/patterns/lang-sv.rme | 112 + tex/context/patterns/lang-tk.hyp | 8 + tex/context/patterns/lang-tk.pat | 2378 + tex/context/patterns/lang-tk.rme | 18 + tex/context/patterns/lang-tr.hyp | 8 + tex/context/patterns/lang-tr.pat | 604 + tex/context/patterns/lang-tr.rme | 26 + tex/context/patterns/lang-uk.hyp | 8 + tex/context/patterns/lang-uk.pat | 1905 + tex/context/patterns/lang-uk.rme | 70 + tex/context/patterns/lang-us.hyp | 21 + tex/context/patterns/lang-us.pat | 4945 + tex/context/patterns/lang-us.rme | 40 + tex/context/patterns/lang-zh.hyp | 8 + tex/context/patterns/lang-zh.pat | 195 + tex/context/patterns/lang-zh.rme | 88 + tex/context/sample/aesop-de.tex | 25 + tex/context/sample/bryson.tex | 9 + tex/context/sample/davis.tex | 13 + tex/context/sample/dawkins.tex | 20 + tex/context/sample/demo-mps.tex | 23 + tex/context/sample/demo-tex.tex | 23 + tex/context/sample/demo-xml.tex | 53 + tex/context/sample/douglas.tex | 23 + tex/context/sample/hawking.tex | 7 + tex/context/sample/knuth.tex | 16 + tex/context/sample/linden.tex | 8 + tex/context/sample/materie.tex | 50 + tex/context/sample/montgomery.tex | 13 + tex/context/sample/reich.tex | 11 + tex/context/sample/sample.tex | 75 + tex/context/sample/thuan.tex | 10 + tex/context/sample/tufte.tex | 13 + tex/context/sample/ward.tex | 5 + tex/context/sample/weisman.tex | 5 + tex/context/sample/zapf.tex | 11 + tex/context/test/context-test.tex | 27 + tex/context/user/cont-sys.rme | 182 + tex/generic/context/luatex-basics.tex | 21 + tex/generic/context/luatex-fonts-merged.lua | 12389 +++ tex/generic/context/luatex-fonts.lua | 140 + 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 | 53 + tex/generic/context/m-ch-de.tex | 10 + tex/generic/context/m-ch-en.tex | 10 + tex/generic/context/m-ch-nl.tex | 10 + tex/generic/context/m-metapo.tex | 89 + tex/generic/context/mptopdf.tex | 176 + tex/generic/context/ppchtex.noc | 212 + tex/latex/context/m-ch-de.sty | 19 + tex/latex/context/m-ch-en.sty | 19 + tex/latex/context/m-ch-nl.sty | 19 + tex/latex/context/m-metapo.sty | 5 + tex/latex/context/m-pictex.sty | 5 + 1390 files changed, 982379 insertions(+) create mode 100644 tex/context/base/anch-bar.mkii create mode 100644 tex/context/base/anch-bar.mkiv create mode 100644 tex/context/base/anch-pgr.mkii create mode 100644 tex/context/base/anch-pgr.mkiv create mode 100644 tex/context/base/anch-pos.lua create mode 100644 tex/context/base/anch-pos.mkii create mode 100644 tex/context/base/anch-pos.mkiv create mode 100644 tex/context/base/anch-snc.mkii create mode 100644 tex/context/base/anch-snc.mkiv create mode 100644 tex/context/base/attr-ini.lua create mode 100644 tex/context/base/attr-ini.mkiv create mode 100644 tex/context/base/back-ini.lua create mode 100644 tex/context/base/back-ini.mkiv create mode 100644 tex/context/base/back-pdf.lua create mode 100644 tex/context/base/back-pdf.mkiv create mode 100644 tex/context/base/back-u3d.mkiv create mode 100644 tex/context/base/bibl-bib.lua create mode 100644 tex/context/base/bibl-bib.mkiv create mode 100644 tex/context/base/bibl-tra.lua create mode 100644 tex/context/base/bibl-tra.mkii create mode 100644 tex/context/base/bibl-tra.mkiv create mode 100644 tex/context/base/bibl-tst.lua create mode 100644 tex/context/base/blob-ini.lua create mode 100644 tex/context/base/blob-ini.mkiv create mode 100644 tex/context/base/buff-ini.lua create mode 100644 tex/context/base/buff-ini.mkii create mode 100644 tex/context/base/buff-ini.mkiv create mode 100644 tex/context/base/buff-ver.mkii create mode 100644 tex/context/base/buff-ver.mkiv create mode 100644 tex/context/base/bxml-apa.mkiv 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-act.mkiv create mode 100644 tex/context/base/char-cmp.lua create mode 100644 tex/context/base/char-def.lua create mode 100644 tex/context/base/char-enc.lua create mode 100644 tex/context/base/char-enc.mkiv create mode 100644 tex/context/base/char-ini.lua create mode 100644 tex/context/base/char-ini.mkiv create mode 100644 tex/context/base/char-map.lua create mode 100644 tex/context/base/char-tex.lua create mode 100644 tex/context/base/char-utf.lua create mode 100644 tex/context/base/char-utf.mkiv 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.lua create mode 100644 tex/context/base/chem-str.mkiv create mode 100644 tex/context/base/colo-ema.tex create mode 100644 tex/context/base/colo-ext.mkii create mode 100644 tex/context/base/colo-ext.mkiv create mode 100644 tex/context/base/colo-hex.mkii create mode 100644 tex/context/base/colo-hex.mkiv create mode 100644 tex/context/base/colo-hex.tex create mode 100644 tex/context/base/colo-ini.lua create mode 100644 tex/context/base/colo-ini.mkii create mode 100644 tex/context/base/colo-ini.mkiv create mode 100644 tex/context/base/colo-rgb.tex create mode 100644 tex/context/base/colo-run.tex create mode 100644 tex/context/base/colo-x11.tex create mode 100644 tex/context/base/colo-xwi.tex create mode 100644 tex/context/base/cont-cs.tex create mode 100644 tex/context/base/cont-de.tex create mode 100644 tex/context/base/cont-en.tex create mode 100644 tex/context/base/cont-err.tex create mode 100644 tex/context/base/cont-fil.tex create mode 100644 tex/context/base/cont-fr.tex create mode 100644 tex/context/base/cont-gb.tex create mode 100644 tex/context/base/cont-it.tex create mode 100644 tex/context/base/cont-log.tex create mode 100644 tex/context/base/cont-mtx.tex create mode 100644 tex/context/base/cont-new.mkii create mode 100644 tex/context/base/cont-new.mkiv create mode 100644 tex/context/base/cont-new.tex create mode 100644 tex/context/base/cont-nl.tex create mode 100644 tex/context/base/cont-old.tex create mode 100644 tex/context/base/cont-pe.tex create mode 100644 tex/context/base/cont-ro.tex create mode 100644 tex/context/base/cont-sys.ori create mode 100644 tex/context/base/cont-usr.ori create mode 100644 tex/context/base/context-base.lmx create mode 100644 tex/context/base/context-characters.lmx create mode 100644 tex/context/base/context-debug.lmx create mode 100644 tex/context/base/context-error.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.css create mode 100644 tex/context/base/context.mkii create mode 100644 tex/context/base/context.mkiv create mode 100644 tex/context/base/context.rme create mode 100644 tex/context/base/context.tex create mode 100644 tex/context/base/core-con.lua create mode 100644 tex/context/base/core-con.mkii create mode 100644 tex/context/base/core-con.mkiv create mode 100644 tex/context/base/core-ctx.lua create mode 100644 tex/context/base/core-ctx.mkii create mode 100644 tex/context/base/core-ctx.mkiv create mode 100644 tex/context/base/core-def.mkii create mode 100644 tex/context/base/core-def.mkiv 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-fil.mkii create mode 100644 tex/context/base/core-fil.mkiv create mode 100644 tex/context/base/core-fnt.mkii create mode 100644 tex/context/base/core-fnt.mkiv create mode 100644 tex/context/base/core-gen.mkii create mode 100644 tex/context/base/core-gen.mkiv create mode 100644 tex/context/base/core-ini.mkii create mode 100644 tex/context/base/core-ini.mkiv create mode 100644 tex/context/base/core-job.lua create mode 100644 tex/context/base/core-job.mkii create mode 100644 tex/context/base/core-job.mkiv create mode 100644 tex/context/base/core-mis.mkii create mode 100644 tex/context/base/core-mis.mkiv create mode 100644 tex/context/base/core-par.mkii create mode 100644 tex/context/base/core-stg.mkii create mode 100644 tex/context/base/core-sys.lua create mode 100644 tex/context/base/core-sys.mkii create mode 100644 tex/context/base/core-sys.mkiv create mode 100644 tex/context/base/core-two.lua create mode 100644 tex/context/base/core-two.mkii create mode 100644 tex/context/base/core-two.mkiv create mode 100644 tex/context/base/core-uti.lua create mode 100644 tex/context/base/core-uti.mkii create mode 100644 tex/context/base/core-uti.mkiv create mode 100644 tex/context/base/core-var.mkii create mode 100644 tex/context/base/core-var.mkiv 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-sch.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 create mode 100644 tex/context/base/enco-032.mkii create mode 100644 tex/context/base/enco-037.mkii create mode 100644 tex/context/base/enco-acc.mkii create mode 100644 tex/context/base/enco-agr.mkii create mode 100644 tex/context/base/enco-ans.mkii create mode 100644 tex/context/base/enco-cas.mkii create mode 100644 tex/context/base/enco-chi.mkii create mode 100644 tex/context/base/enco-com.mkii create mode 100644 tex/context/base/enco-cyr.mkii create mode 100644 tex/context/base/enco-def.mkii create mode 100644 tex/context/base/enco-ec.mkii create mode 100644 tex/context/base/enco-ecm.mkii create mode 100644 tex/context/base/enco-el.mkii create mode 100644 tex/context/base/enco-fde.mkii create mode 100644 tex/context/base/enco-ffr.mkii create mode 100644 tex/context/base/enco-fpl.mkii create mode 100644 tex/context/base/enco-fro.mkii create mode 100644 tex/context/base/enco-fsl.mkii create mode 100644 tex/context/base/enco-grk.mkii create mode 100644 tex/context/base/enco-heb.mkii create mode 100644 tex/context/base/enco-ibm.mkii create mode 100644 tex/context/base/enco-il2.mkii create mode 100644 tex/context/base/enco-ini.mkii create mode 100644 tex/context/base/enco-ini.mkiv create mode 100644 tex/context/base/enco-l7x.mkii create mode 100644 tex/context/base/enco-lat.mkii create mode 100644 tex/context/base/enco-mis.mkii create mode 100644 tex/context/base/enco-pdf.mkii create mode 100644 tex/context/base/enco-pfr.mkii create mode 100644 tex/context/base/enco-pol.mkii create mode 100644 tex/context/base/enco-qx.mkii create mode 100644 tex/context/base/enco-raw.mkii create mode 100644 tex/context/base/enco-run.mkii create mode 100644 tex/context/base/enco-t5.mkii create mode 100644 tex/context/base/enco-tbo.mkii create mode 100644 tex/context/base/enco-uc.mkii create mode 100644 tex/context/base/enco-vis.mkii create mode 100644 tex/context/base/enco-vna.mkii create mode 100644 tex/context/base/enco-win.mkii create mode 100644 tex/context/base/enco-x5.mkii create mode 100644 tex/context/base/filt-bas.mkii create mode 100644 tex/context/base/filt-ini.mkii create mode 100644 tex/context/base/font-afm.lua create mode 100644 tex/context/base/font-agl.lua create mode 100644 tex/context/base/font-arb.mkii create mode 100644 tex/context/base/font-bfm.mkii create mode 100644 tex/context/base/font-chi.mkii 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.lua create mode 100644 tex/context/base/font-col.mkiv create mode 100644 tex/context/base/font-ctx.lua create mode 100644 tex/context/base/font-def.lua create mode 100644 tex/context/base/font-dum.lua create mode 100644 tex/context/base/font-enc.lua create mode 100644 tex/context/base/font-enh.lua create mode 100644 tex/context/base/font-ext.lua create mode 100644 tex/context/base/font-fbk.lua create mode 100644 tex/context/base/font-gds.lua create mode 100644 tex/context/base/font-gds.mkiv create mode 100644 tex/context/base/font-heb.mkii create mode 100644 tex/context/base/font-ini.lua create mode 100644 tex/context/base/font-ini.mkii create mode 100644 tex/context/base/font-ini.mkiv create mode 100644 tex/context/base/font-jap.mkii create mode 100644 tex/context/base/font-log.lua create mode 100644 tex/context/base/font-map.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-otf.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-pat.lua create mode 100644 tex/context/base/font-run.mkii create mode 100644 tex/context/base/font-run.mkiv create mode 100644 tex/context/base/font-syn.lua create mode 100644 tex/context/base/font-tfm.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 create mode 100644 tex/context/base/font-unk.mkii create mode 100644 tex/context/base/font-unk.mkiv create mode 100644 tex/context/base/font-vf.lua create mode 100644 tex/context/base/font-xtx.lua create mode 100644 tex/context/base/font-xtx.mkii create mode 100644 tex/context/base/grph-fig.mkii create mode 100644 tex/context/base/grph-fig.mkiv create mode 100644 tex/context/base/grph-fil.lua create mode 100644 tex/context/base/grph-inc.lua create mode 100644 tex/context/base/grph-inc.mkii create mode 100644 tex/context/base/grph-inc.mkiv create mode 100644 tex/context/base/grph-swf.lua create mode 100644 tex/context/base/grph-trf.mkii create mode 100644 tex/context/base/grph-trf.mkiv create mode 100644 tex/context/base/grph-u3d.lua create mode 100644 tex/context/base/hand-def.mkii create mode 100644 tex/context/base/hand-ini.mkii create mode 100644 tex/context/base/hand-ini.mkiv create mode 100644 tex/context/base/java-ans.tex create mode 100644 tex/context/base/java-exa.tex create mode 100644 tex/context/base/java-fil.tex create mode 100644 tex/context/base/java-fld.tex create mode 100644 tex/context/base/java-ini.lua create mode 100644 tex/context/base/java-ini.mkii create mode 100644 tex/context/base/java-ini.mkiv create mode 100644 tex/context/base/java-stp.tex create mode 100644 tex/context/base/l-aux.lua create mode 100644 tex/context/base/l-boolean.lua create mode 100644 tex/context/base/l-dimen.lua create mode 100644 tex/context/base/l-dir.lua create mode 100644 tex/context/base/l-file.lua create mode 100644 tex/context/base/l-io.lua create mode 100644 tex/context/base/l-lpeg.lua create mode 100644 tex/context/base/l-math.lua create mode 100644 tex/context/base/l-md5.lua create mode 100644 tex/context/base/l-number.lua create mode 100644 tex/context/base/l-os.lua create mode 100644 tex/context/base/l-pdfview.lua create mode 100644 tex/context/base/l-set.lua create mode 100644 tex/context/base/l-string.lua create mode 100644 tex/context/base/l-table.lua create mode 100644 tex/context/base/l-unicode.lua create mode 100644 tex/context/base/l-url.lua create mode 100644 tex/context/base/l-utils.lua create mode 100644 tex/context/base/l-xml.lua create mode 100644 tex/context/base/lang-all.xml create mode 100644 tex/context/base/lang-alt.tex create mode 100644 tex/context/base/lang-ana.tex create mode 100644 tex/context/base/lang-ara.mkiv create mode 100644 tex/context/base/lang-art.tex create mode 100644 tex/context/base/lang-bal.tex create mode 100644 tex/context/base/lang-cel.tex create mode 100644 tex/context/base/lang-chi.mkii create mode 100644 tex/context/base/lang-cjk.mkiv create mode 100644 tex/context/base/lang-ctx.mkii create mode 100644 tex/context/base/lang-cyr.tex create mode 100644 tex/context/base/lang-dis.mkii create mode 100644 tex/context/base/lang-frd.tex create mode 100644 tex/context/base/lang-frq.tex create mode 100644 tex/context/base/lang-ger.tex create mode 100644 tex/context/base/lang-grk.tex create mode 100644 tex/context/base/lang-ind.tex create mode 100644 tex/context/base/lang-ini.lua create mode 100644 tex/context/base/lang-ini.mkii create mode 100644 tex/context/base/lang-ini.mkiv create mode 100644 tex/context/base/lang-ita.tex create mode 100644 tex/context/base/lang-jap.mkii create mode 100644 tex/context/base/lang-lab.mkii create mode 100644 tex/context/base/lang-lab.mkiv create mode 100644 tex/context/base/lang-mis.mkii create mode 100644 tex/context/base/lang-mis.mkiv create mode 100644 tex/context/base/lang-run.mkii create mode 100644 tex/context/base/lang-sla.mkii create mode 100644 tex/context/base/lang-sla.mkiv create mode 100644 tex/context/base/lang-sla.tex create mode 100644 tex/context/base/lang-spa.tex create mode 100644 tex/context/base/lang-spe.mkii create mode 100644 tex/context/base/lang-ura.tex create mode 100644 tex/context/base/lang-url.lua create mode 100644 tex/context/base/lang-url.mkii create mode 100644 tex/context/base/lang-url.mkiv create mode 100644 tex/context/base/lang-vn.tex create mode 100644 tex/context/base/lang-wrd.lua create mode 100644 tex/context/base/lang-wrd.mkiv create mode 100644 tex/context/base/lpdf-ano.lua create mode 100644 tex/context/base/lpdf-col.lua create mode 100644 tex/context/base/lpdf-fld.lua create mode 100644 tex/context/base/lpdf-grp.lua create mode 100644 tex/context/base/lpdf-ini.lua create mode 100644 tex/context/base/lpdf-ini.mkiv create mode 100644 tex/context/base/lpdf-mis.lua create mode 100644 tex/context/base/lpdf-nod.lua create mode 100644 tex/context/base/lpdf-pdx.lua create mode 100644 tex/context/base/lpdf-pdx.mkiv create mode 100644 tex/context/base/lpdf-ren.lua create mode 100644 tex/context/base/lpdf-swf.lua create mode 100644 tex/context/base/lpdf-u3d.lua create mode 100644 tex/context/base/lpdf-wid.lua create mode 100644 tex/context/base/lpdf-xmp.lua create mode 100644 tex/context/base/lpdf-xmp.xml create mode 100644 tex/context/base/luat-bas.mkiv create mode 100644 tex/context/base/luat-cbk.lua create mode 100644 tex/context/base/luat-cnf.lua create mode 100644 tex/context/base/luat-cod.mkiv create mode 100644 tex/context/base/luat-dum.lua create mode 100644 tex/context/base/luat-env.lua create mode 100644 tex/context/base/luat-exe.lua create mode 100644 tex/context/base/luat-fio.lua create mode 100644 tex/context/base/luat-ini.lua create mode 100644 tex/context/base/luat-ini.mkiv create mode 100644 tex/context/base/luat-iop.lua create mode 100644 tex/context/base/luat-lib.mkiv create mode 100644 tex/context/base/luat-lua.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-sta.lua create mode 100644 tex/context/base/luat-sto.lua create mode 100644 tex/context/base/lxml-aux.lua create mode 100644 tex/context/base/lxml-ctx.lua create mode 100644 tex/context/base/lxml-ctx.mkiv create mode 100644 tex/context/base/lxml-dir.lua create mode 100644 tex/context/base/lxml-ent.lua create mode 100644 tex/context/base/lxml-inf.lua create mode 100644 tex/context/base/lxml-ini.mkiv create mode 100644 tex/context/base/lxml-lpt.lua create mode 100644 tex/context/base/lxml-mis.lua create mode 100644 tex/context/base/lxml-sor.lua create mode 100644 tex/context/base/lxml-sor.mkiv create mode 100644 tex/context/base/lxml-tab.lua create mode 100644 tex/context/base/lxml-tex.lua create mode 100644 tex/context/base/lxml-xml.lua create mode 100644 tex/context/base/m-arabtex.tex create mode 100644 tex/context/base/m-barcodes.mkiv create mode 100644 tex/context/base/m-chart.mkii create mode 100644 tex/context/base/m-chart.mkiv create mode 100644 tex/context/base/m-chart.tex create mode 100644 tex/context/base/m-chemic.mkii create mode 100644 tex/context/base/m-chemic.mkiv create mode 100644 tex/context/base/m-chemic.tex create mode 100644 tex/context/base/m-cweb.tex create mode 100644 tex/context/base/m-database.tex create mode 100644 tex/context/base/m-datastrc.tex create mode 100644 tex/context/base/m-directives.tex create mode 100644 tex/context/base/m-dratex.tex create mode 100644 tex/context/base/m-edtsnc.tex create mode 100644 tex/context/base/m-educat.tex create mode 100644 tex/context/base/m-format.tex create mode 100644 tex/context/base/m-graph.mkii create mode 100644 tex/context/base/m-graph.mkiv create mode 100644 tex/context/base/m-graph.tex create mode 100644 tex/context/base/m-layout.tex create mode 100644 tex/context/base/m-level.tex create mode 100644 tex/context/base/m-mkii.mkiv create mode 100644 tex/context/base/m-mkivhacks.tex create mode 100644 tex/context/base/m-narrowtt.tex create mode 100644 tex/context/base/m-newmat.tex create mode 100644 tex/context/base/m-obsolete.tex create mode 100644 tex/context/base/m-pdfsnc.tex create mode 100644 tex/context/base/m-pictex.tex create mode 100644 tex/context/base/m-plus.tex create mode 100644 tex/context/base/m-pstricks.lua create mode 100644 tex/context/base/m-pstricks.mkii create mode 100644 tex/context/base/m-pstricks.mkiv create mode 100644 tex/context/base/m-pstricks.tex create mode 100644 tex/context/base/m-punk.mkiv create mode 100644 tex/context/base/m-punk.tex create mode 100644 tex/context/base/m-quest.tex create mode 100644 tex/context/base/m-r.tex create mode 100644 tex/context/base/m-steps.mkii create mode 100644 tex/context/base/m-steps.mkiv create mode 100644 tex/context/base/m-steps.tex create mode 100644 tex/context/base/m-streams.tex create mode 100644 tex/context/base/m-subsub.tex create mode 100644 tex/context/base/m-tex4ht.tex create mode 100644 tex/context/base/m-timing.tex create mode 100644 tex/context/base/m-trackers.tex create mode 100644 tex/context/base/m-translate.tex create mode 100644 tex/context/base/m-tryout.tex create mode 100644 tex/context/base/m-units.tex create mode 100644 tex/context/base/m-visual.tex create mode 100644 tex/context/base/math-ali.mkiv create mode 100644 tex/context/base/math-ams.mkii 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-cow.mkii 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-ent.lua create mode 100644 tex/context/base/math-eul.mkii create mode 100644 tex/context/base/math-ext.lua create mode 100644 tex/context/base/math-for.mkiv create mode 100644 tex/context/base/math-fou.mkii create mode 100644 tex/context/base/math-frc.mkii create mode 100644 tex/context/base/math-frc.mkiv create mode 100644 tex/context/base/math-ini.lua create mode 100644 tex/context/base/math-ini.mkii create mode 100644 tex/context/base/math-ini.mkiv 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-lan.mkiv create mode 100644 tex/context/base/math-lbr.mkii create mode 100644 tex/context/base/math-map.lua 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 create mode 100644 tex/context/base/math-run.mkii create mode 100644 tex/context/base/math-scr.mkiv create mode 100644 tex/context/base/math-tex.mkii create mode 100644 tex/context/base/math-tim.mkii create mode 100644 tex/context/base/math-uni.mkii create mode 100644 tex/context/base/math-vfu.lua create mode 100644 tex/context/base/meta-clp.tex create mode 100644 tex/context/base/meta-dum.tex create mode 100644 tex/context/base/meta-fig.mkii create mode 100644 tex/context/base/meta-fig.mkiv create mode 100644 tex/context/base/meta-fun.lua create mode 100644 tex/context/base/meta-fun.mkiv create mode 100644 tex/context/base/meta-ini.mkii create mode 100644 tex/context/base/meta-ini.mkiv create mode 100644 tex/context/base/meta-mis.tex create mode 100644 tex/context/base/meta-nav.tex create mode 100644 tex/context/base/meta-pag.mkii create mode 100644 tex/context/base/meta-pag.mkiv create mode 100644 tex/context/base/meta-pdf.lua create mode 100644 tex/context/base/meta-pdf.mkii create mode 100644 tex/context/base/meta-pdf.mkiv create mode 100644 tex/context/base/meta-pdh.lua create mode 100644 tex/context/base/meta-pdh.mkiv create mode 100644 tex/context/base/meta-pre.tex create mode 100644 tex/context/base/meta-tex.mkii create mode 100644 tex/context/base/meta-tex.mkiv create mode 100644 tex/context/base/meta-txt.tex create mode 100644 tex/context/base/meta-xml.tex create mode 100644 tex/context/base/metatex.tex create mode 100644 tex/context/base/mlib-ctx.lua create mode 100644 tex/context/base/mlib-ctx.mkiv create mode 100644 tex/context/base/mlib-pdf.lua create mode 100644 tex/context/base/mlib-pdf.mkiv create mode 100644 tex/context/base/mlib-pps.lua create mode 100644 tex/context/base/mlib-pps.mkiv create mode 100644 tex/context/base/mlib-run.lua 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-common.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-cld.lua create mode 100644 tex/context/base/mult-cld.mkiv create mode 100644 tex/context/base/mult-clm.lua create mode 100644 tex/context/base/mult-com.tex create mode 100644 tex/context/base/mult-con.tex create mode 100644 tex/context/base/mult-de.tex create mode 100644 tex/context/base/mult-def.lua create mode 100644 tex/context/base/mult-def.tex create mode 100644 tex/context/base/mult-en.tex create mode 100644 tex/context/base/mult-fr.tex create mode 100644 tex/context/base/mult-fst.tex create mode 100644 tex/context/base/mult-ini.lua create mode 100644 tex/context/base/mult-ini.mkii create mode 100644 tex/context/base/mult-ini.mkiv create mode 100644 tex/context/base/mult-it.tex 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/mult-nl.tex create mode 100644 tex/context/base/mult-ro.tex create mode 100644 tex/context/base/mult-sys.tex create mode 100644 tex/context/base/node-aux.lua create mode 100644 tex/context/base/node-bck.lua create mode 100644 tex/context/base/node-bck.mkiv create mode 100644 tex/context/base/node-dir.lua 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.mkiv create mode 100644 tex/context/base/node-fnt.lua create mode 100644 tex/context/base/node-ini.lua create mode 100644 tex/context/base/node-ini.mkiv create mode 100644 tex/context/base/node-inj.lua create mode 100644 tex/context/base/node-mig.lua create mode 100644 tex/context/base/node-mig.mkiv create mode 100644 tex/context/base/node-pag.lua create mode 100644 tex/context/base/node-pag.mkiv create mode 100644 tex/context/base/node-par.lua create mode 100644 tex/context/base/node-par.mkiv create mode 100644 tex/context/base/node-pro.lua create mode 100644 tex/context/base/node-ref.lua create mode 100644 tex/context/base/node-res.lua create mode 100644 tex/context/base/node-rul.lua create mode 100644 tex/context/base/node-rul.mkiv create mode 100644 tex/context/base/node-seq.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/node-typ.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/pack-bar.mkiv create mode 100644 tex/context/base/pack-box.mkii create mode 100644 tex/context/base/pack-box.mkiv create mode 100644 tex/context/base/pack-lyr.mkii create mode 100644 tex/context/base/pack-lyr.mkiv create mode 100644 tex/context/base/pack-obj.lua create mode 100644 tex/context/base/pack-obj.mkii create mode 100644 tex/context/base/pack-obj.mkiv create mode 100644 tex/context/base/pack-rul.lua create mode 100644 tex/context/base/pack-rul.mkii create mode 100644 tex/context/base/pack-rul.mkiv create mode 100644 tex/context/base/page-app.mkii create mode 100644 tex/context/base/page-app.mkiv create mode 100644 tex/context/base/page-bck.mkii create mode 100644 tex/context/base/page-bck.mkiv create mode 100644 tex/context/base/page-flt.lua create mode 100644 tex/context/base/page-flt.mkiv create mode 100644 tex/context/base/page-flw.mkii create mode 100644 tex/context/base/page-flw.mkiv create mode 100644 tex/context/base/page-imp.mkii create mode 100644 tex/context/base/page-imp.mkiv create mode 100644 tex/context/base/page-ini.mkii create mode 100644 tex/context/base/page-ini.mkiv create mode 100644 tex/context/base/page-ins.mkii create mode 100644 tex/context/base/page-ins.mkiv create mode 100644 tex/context/base/page-lay.mkii create mode 100644 tex/context/base/page-lay.mkiv create mode 100644 tex/context/base/page-lin.lua create mode 100644 tex/context/base/page-lin.mkii create mode 100644 tex/context/base/page-lin.mkiv create mode 100644 tex/context/base/page-log.mkii create mode 100644 tex/context/base/page-mak.mkii create mode 100644 tex/context/base/page-mak.mkiv create mode 100644 tex/context/base/page-mar.mkii create mode 100644 tex/context/base/page-mar.mkiv create mode 100644 tex/context/base/page-mis.mkii create mode 100644 tex/context/base/page-mis.mkiv create mode 100644 tex/context/base/page-mul.mkii create mode 100644 tex/context/base/page-mul.mkiv create mode 100644 tex/context/base/page-not.mkii create mode 100644 tex/context/base/page-not.mkiv create mode 100644 tex/context/base/page-one.mkii create mode 100644 tex/context/base/page-one.mkiv create mode 100644 tex/context/base/page-par.mkii create mode 100644 tex/context/base/page-par.mkiv create mode 100644 tex/context/base/page-plg.mkii create mode 100644 tex/context/base/page-plg.mkiv create mode 100644 tex/context/base/page-run.mkii create mode 100644 tex/context/base/page-run.mkiv create mode 100644 tex/context/base/page-set.mkii create mode 100644 tex/context/base/page-set.mkiv create mode 100644 tex/context/base/page-sid.mkii create mode 100644 tex/context/base/page-sid.mkiv create mode 100644 tex/context/base/page-spr.mkii create mode 100644 tex/context/base/page-spr.mkiv create mode 100644 tex/context/base/page-str.lua create mode 100644 tex/context/base/page-str.mkii create mode 100644 tex/context/base/page-str.mkiv create mode 100644 tex/context/base/page-txt.mkii create mode 100644 tex/context/base/page-txt.mkiv create mode 100644 tex/context/base/pdfr-def.mkii create mode 100644 tex/context/base/pdfr-ec.mkii create mode 100644 tex/context/base/pdfr-il2.mkii create mode 100644 tex/context/base/ppchtex.mkii create mode 100644 tex/context/base/ppchtex.mkiv create mode 100644 tex/context/base/pret-lua.lua create mode 100644 tex/context/base/pret-mp.lua create mode 100644 tex/context/base/pret-tex.lua create mode 100644 tex/context/base/pret-xml.lua create mode 100644 tex/context/base/prop-ini.mkii create mode 100644 tex/context/base/prop-ini.mkiv create mode 100644 tex/context/base/prop-lay.mkii create mode 100644 tex/context/base/prop-lay.mkiv create mode 100644 tex/context/base/prop-mis.mkii create mode 100644 tex/context/base/prop-mis.mkiv create mode 100644 tex/context/base/regi-8859-1.lua create mode 100644 tex/context/base/regi-8859-1.mkii create mode 100644 tex/context/base/regi-8859-10.lua create mode 100644 tex/context/base/regi-8859-10.mkii create mode 100644 tex/context/base/regi-8859-11.lua create mode 100644 tex/context/base/regi-8859-13.lua create mode 100644 tex/context/base/regi-8859-13.mkii create mode 100644 tex/context/base/regi-8859-14.lua create mode 100644 tex/context/base/regi-8859-15.lua create mode 100644 tex/context/base/regi-8859-15.mkii create mode 100644 tex/context/base/regi-8859-16.lua create mode 100644 tex/context/base/regi-8859-16.mkii create mode 100644 tex/context/base/regi-8859-2.lua create mode 100644 tex/context/base/regi-8859-2.mkii create mode 100644 tex/context/base/regi-8859-3.lua create mode 100644 tex/context/base/regi-8859-3.mkii create mode 100644 tex/context/base/regi-8859-4.lua create mode 100644 tex/context/base/regi-8859-4.mkii create mode 100644 tex/context/base/regi-8859-5.lua create mode 100644 tex/context/base/regi-8859-5.mkii create mode 100644 tex/context/base/regi-8859-6.lua create mode 100644 tex/context/base/regi-8859-7.lua create mode 100644 tex/context/base/regi-8859-7.mkii create mode 100644 tex/context/base/regi-8859-8.lua create mode 100644 tex/context/base/regi-8859-9.lua create mode 100644 tex/context/base/regi-8859-9.mkii create mode 100644 tex/context/base/regi-cp1250.lua create mode 100644 tex/context/base/regi-cp1250.mkii create mode 100644 tex/context/base/regi-cp1251.lua create mode 100644 tex/context/base/regi-cp1251.mkii create mode 100644 tex/context/base/regi-cp1252.lua create mode 100644 tex/context/base/regi-cp1252.mkii create mode 100644 tex/context/base/regi-cp1253.lua create mode 100644 tex/context/base/regi-cp1253.mkii create mode 100644 tex/context/base/regi-cp1254.lua create mode 100644 tex/context/base/regi-cp1254.mkii create mode 100644 tex/context/base/regi-cp1255.lua create mode 100644 tex/context/base/regi-cp1256.lua create mode 100644 tex/context/base/regi-cp1257.lua create mode 100644 tex/context/base/regi-cp1257.mkii create mode 100644 tex/context/base/regi-cp1258.lua create mode 100644 tex/context/base/regi-cyp.mkii create mode 100644 tex/context/base/regi-cyr.mkii create mode 100644 tex/context/base/regi-def.mkii create mode 100644 tex/context/base/regi-ibm.mkii create mode 100644 tex/context/base/regi-ini.lua create mode 100644 tex/context/base/regi-ini.mkii create mode 100644 tex/context/base/regi-ini.mkiv create mode 100644 tex/context/base/regi-mac.mkii create mode 100644 tex/context/base/regi-syn.tex create mode 100644 tex/context/base/regi-uni.mkii create mode 100644 tex/context/base/regi-utf.mkii create mode 100644 tex/context/base/regi-vis.mkii create mode 100644 tex/context/base/rlxcache.rlx create mode 100644 tex/context/base/rlxtools.rlx create mode 100644 tex/context/base/s-abr-01.tex create mode 100644 tex/context/base/s-abr-02.tex create mode 100644 tex/context/base/s-abr-03.tex create mode 100644 tex/context/base/s-cdr-01.tex create mode 100644 tex/context/base/s-chi-00.tex create mode 100644 tex/context/base/s-faq-00.tex create mode 100644 tex/context/base/s-faq-01.tex create mode 100644 tex/context/base/s-faq-02.tex create mode 100644 tex/context/base/s-faq-03.tex create mode 100644 tex/context/base/s-fnt-01.tex create mode 100644 tex/context/base/s-fnt-02.tex create mode 100644 tex/context/base/s-fnt-10.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-26.tex create mode 100644 tex/context/base/s-fnt-30.tex create mode 100644 tex/context/base/s-grk-00.tex create mode 100644 tex/context/base/s-inf-01.tex create mode 100644 tex/context/base/s-inf-02.tex create mode 100644 tex/context/base/s-jap-00.tex create mode 100644 tex/context/base/s-mag-01.tex create mode 100644 tex/context/base/s-map-10.tex create mode 100644 tex/context/base/s-mod-00.tex create mode 100644 tex/context/base/s-mod-01.tex create mode 100644 tex/context/base/s-mod-02.tex create mode 100644 tex/context/base/s-mod.ctx create mode 100644 tex/context/base/s-pre-00.tex create mode 100644 tex/context/base/s-pre-01.tex create mode 100644 tex/context/base/s-pre-02.tex create mode 100644 tex/context/base/s-pre-03.tex create mode 100644 tex/context/base/s-pre-04.tex create mode 100644 tex/context/base/s-pre-05.tex create mode 100644 tex/context/base/s-pre-06.tex create mode 100644 tex/context/base/s-pre-07.tex create mode 100644 tex/context/base/s-pre-08.tex create mode 100644 tex/context/base/s-pre-09.tex create mode 100644 tex/context/base/s-pre-10.tex create mode 100644 tex/context/base/s-pre-11.tex create mode 100644 tex/context/base/s-pre-12.tex create mode 100644 tex/context/base/s-pre-13.tex create mode 100644 tex/context/base/s-pre-14.tex create mode 100644 tex/context/base/s-pre-15.tex create mode 100644 tex/context/base/s-pre-16.tex create mode 100644 tex/context/base/s-pre-17.tex create mode 100644 tex/context/base/s-pre-18.tex create mode 100644 tex/context/base/s-pre-19.tex create mode 100644 tex/context/base/s-pre-22.tex create mode 100644 tex/context/base/s-pre-23.tex create mode 100644 tex/context/base/s-pre-26.tex create mode 100644 tex/context/base/s-pre-27.tex create mode 100644 tex/context/base/s-pre-30.tex create mode 100644 tex/context/base/s-pre-50.tex create mode 100644 tex/context/base/s-pre-60.tex create mode 100644 tex/context/base/s-pre-61.tex create mode 100644 tex/context/base/s-pre-62.tex create mode 100644 tex/context/base/s-pre-63.tex create mode 100644 tex/context/base/s-pre-64.tex create mode 100644 tex/context/base/s-pre-66.tex create mode 100644 tex/context/base/s-pre-67.tex create mode 100644 tex/context/base/s-pre-70.tex create mode 100644 tex/context/base/s-pre-71.tex create mode 100644 tex/context/base/s-pre-93.tex create mode 100644 tex/context/base/s-ptj-01.tex create mode 100644 tex/context/base/s-reg-01.tex create mode 100644 tex/context/base/s-syn-01.tex create mode 100644 tex/context/base/s-sys-01.tex create mode 100644 tex/context/base/scrn-bar.mkiv create mode 100644 tex/context/base/scrn-but.mkiv create mode 100644 tex/context/base/scrn-fld.mkii create mode 100644 tex/context/base/scrn-fld.mkiv create mode 100644 tex/context/base/scrn-hlp.mkii create mode 100644 tex/context/base/scrn-hlp.mkiv create mode 100644 tex/context/base/scrn-int.lua create mode 100644 tex/context/base/scrn-int.mkii create mode 100644 tex/context/base/scrn-int.mkiv create mode 100644 tex/context/base/scrn-men.mkiv create mode 100644 tex/context/base/scrn-nav.mkii create mode 100644 tex/context/base/scrn-nav.mkiv 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.mkiv create mode 100644 tex/context/base/sort-def.mkii create mode 100644 tex/context/base/sort-ini.lua create mode 100644 tex/context/base/sort-ini.mkii create mode 100644 tex/context/base/sort-ini.mkiv create mode 100644 tex/context/base/sort-lan.lua create mode 100644 tex/context/base/sort-lan.mkii create mode 100644 tex/context/base/spac-ali.mkiv create mode 100644 tex/context/base/spac-def.mkiv create mode 100644 tex/context/base/spac-fnt.mkiv create mode 100644 tex/context/base/spac-gen.mkii create mode 100644 tex/context/base/spac-grd.mkii create mode 100644 tex/context/base/spac-grd.mkiv create mode 100644 tex/context/base/spac-hor.lua create mode 100644 tex/context/base/spac-hor.mkiv create mode 100644 tex/context/base/spac-pag.mkiv create mode 100644 tex/context/base/spac-par.mkiv create mode 100644 tex/context/base/spac-ver.lua create mode 100644 tex/context/base/spac-ver.mkiv create mode 100644 tex/context/base/spec-def.mkii create mode 100644 tex/context/base/spec-dpm.mkii create mode 100644 tex/context/base/spec-dpx.mkii create mode 100644 tex/context/base/spec-dvi.mkii create mode 100644 tex/context/base/spec-fdf.mkii create mode 100644 tex/context/base/spec-ini.mkii create mode 100644 tex/context/base/spec-mis.mkii create mode 100644 tex/context/base/spec-pdf.mkii create mode 100644 tex/context/base/spec-ps.mkii create mode 100644 tex/context/base/spec-tpd.mkii create mode 100644 tex/context/base/spec-tr.mkii create mode 100644 tex/context/base/spec-tst.mkii create mode 100644 tex/context/base/spec-var.mkii create mode 100644 tex/context/base/spec-win.mkii create mode 100644 tex/context/base/spec-xet.mkii create mode 100644 tex/context/base/spec-xtx.mkii create mode 100644 tex/context/base/spec-yy.mkii create mode 100644 tex/context/base/strc-bkm.lua create mode 100644 tex/context/base/strc-bkm.mkiv create mode 100644 tex/context/base/strc-blk.lua create mode 100644 tex/context/base/strc-blk.mkii create mode 100644 tex/context/base/strc-blk.mkiv create mode 100644 tex/context/base/strc-def.mkiv create mode 100644 tex/context/base/strc-des.lua create mode 100644 tex/context/base/strc-des.mkii create mode 100644 tex/context/base/strc-des.mkiv create mode 100644 tex/context/base/strc-doc.lua create mode 100644 tex/context/base/strc-doc.mkiv create mode 100644 tex/context/base/strc-flt.lua create mode 100644 tex/context/base/strc-flt.mkii create mode 100644 tex/context/base/strc-flt.mkiv create mode 100644 tex/context/base/strc-ini.lua create mode 100644 tex/context/base/strc-ini.mkiv create mode 100644 tex/context/base/strc-itm.lua create mode 100644 tex/context/base/strc-itm.mkii create mode 100644 tex/context/base/strc-itm.mkiv create mode 100644 tex/context/base/strc-lnt.mkii create mode 100644 tex/context/base/strc-lnt.mkiv create mode 100644 tex/context/base/strc-lst.lua create mode 100644 tex/context/base/strc-lst.mkii create mode 100644 tex/context/base/strc-lst.mkiv create mode 100644 tex/context/base/strc-mar.lua create mode 100644 tex/context/base/strc-mar.mkii create mode 100644 tex/context/base/strc-mar.mkiv create mode 100644 tex/context/base/strc-mat.lua create mode 100644 tex/context/base/strc-mat.mkii create mode 100644 tex/context/base/strc-mat.mkiv create mode 100644 tex/context/base/strc-not.lua create mode 100644 tex/context/base/strc-not.mkii create mode 100644 tex/context/base/strc-not.mkiv create mode 100644 tex/context/base/strc-num.lua create mode 100644 tex/context/base/strc-num.mkii create mode 100644 tex/context/base/strc-num.mkiv create mode 100644 tex/context/base/strc-pag.lua create mode 100644 tex/context/base/strc-pag.mkii create mode 100644 tex/context/base/strc-pag.mkiv create mode 100644 tex/context/base/strc-prc.lua create mode 100644 tex/context/base/strc-prc.mkiv create mode 100644 tex/context/base/strc-ref.lua create mode 100644 tex/context/base/strc-ref.mkii create mode 100644 tex/context/base/strc-ref.mkiv create mode 100644 tex/context/base/strc-reg.lua create mode 100644 tex/context/base/strc-reg.mkii create mode 100644 tex/context/base/strc-reg.mkiv create mode 100644 tex/context/base/strc-ren.mkiv create mode 100644 tex/context/base/strc-sbe.mkiv create mode 100644 tex/context/base/strc-sec.mkii create mode 100644 tex/context/base/strc-sec.mkiv create mode 100644 tex/context/base/strc-swd.mkii create mode 100644 tex/context/base/strc-syn.lua create mode 100644 tex/context/base/strc-syn.mkii create mode 100644 tex/context/base/strc-syn.mkiv create mode 100644 tex/context/base/strc-xml.mkiv create mode 100644 tex/context/base/supp-ali.tex create mode 100644 tex/context/base/supp-box.tex create mode 100644 tex/context/base/supp-dir.mkii create mode 100644 tex/context/base/supp-dir.mkiv create mode 100644 tex/context/base/supp-emp.mkii create mode 100644 tex/context/base/supp-eps.mkii create mode 100644 tex/context/base/supp-fil.lua create mode 100644 tex/context/base/supp-fil.mkii create mode 100644 tex/context/base/supp-fil.mkiv create mode 100644 tex/context/base/supp-fun.tex create mode 100644 tex/context/base/supp-mat.mkii create mode 100644 tex/context/base/supp-mat.mkiv create mode 100644 tex/context/base/supp-mis.mkii create mode 100644 tex/context/base/supp-mis.tex create mode 100644 tex/context/base/supp-mpe.mkii create mode 100644 tex/context/base/supp-mpe.tex create mode 100644 tex/context/base/supp-mps.mkii create mode 100644 tex/context/base/supp-mrk.mkii create mode 100644 tex/context/base/supp-num.tex create mode 100644 tex/context/base/supp-pat.mkii create mode 100644 tex/context/base/supp-pdf.mkii create mode 100644 tex/context/base/supp-pdf.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 create mode 100644 tex/context/base/supp-spe.mkii create mode 100644 tex/context/base/supp-tpi.mkii create mode 100644 tex/context/base/supp-vis.tex create mode 100644 tex/context/base/symb-cow.tex create mode 100644 tex/context/base/symb-eur.tex create mode 100644 tex/context/base/symb-glm.tex create mode 100644 tex/context/base/symb-ini.mkii create mode 100644 tex/context/base/symb-ini.mkiv create mode 100644 tex/context/base/symb-jmn.tex create mode 100644 tex/context/base/symb-mis.tex create mode 100644 tex/context/base/symb-mvs.tex create mode 100644 tex/context/base/symb-nav.tex create mode 100644 tex/context/base/symb-run.mkii create mode 100644 tex/context/base/symb-run.mkiv create mode 100644 tex/context/base/symb-uni.tex create mode 100644 tex/context/base/symb-was.tex create mode 100644 tex/context/base/syst-aux.mkiv create mode 100644 tex/context/base/syst-con.lua create mode 100644 tex/context/base/syst-con.mkii create mode 100644 tex/context/base/syst-con.mkiv create mode 100644 tex/context/base/syst-ext.mkii create mode 100644 tex/context/base/syst-fnt.mkii create mode 100644 tex/context/base/syst-fnt.mkiv create mode 100644 tex/context/base/syst-gen.mkii create mode 100644 tex/context/base/syst-ini.tex create mode 100644 tex/context/base/syst-ltx.tex create mode 100644 tex/context/base/syst-lua.lua create mode 100644 tex/context/base/syst-lua.mkiv create mode 100644 tex/context/base/syst-new.mkii create mode 100644 tex/context/base/syst-pln.tex create mode 100644 tex/context/base/syst-rtp.mkii create mode 100644 tex/context/base/syst-rtp.mkiv create mode 100644 tex/context/base/syst-str.mkii create mode 100644 tex/context/base/syst-str.mkiv create mode 100644 tex/context/base/syst-tex.mkii create mode 100644 tex/context/base/tabl-com.mkii create mode 100644 tex/context/base/tabl-com.mkiv create mode 100644 tex/context/base/tabl-ltb.mkii create mode 100644 tex/context/base/tabl-ltb.mkiv 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.mkii create mode 100644 tex/context/base/tabl-nte.mkiv create mode 100644 tex/context/base/tabl-pln.mkii create mode 100644 tex/context/base/tabl-pln.mkiv create mode 100644 tex/context/base/tabl-tab.mkii create mode 100644 tex/context/base/tabl-tab.mkiv create mode 100644 tex/context/base/tabl-tbl.mkii create mode 100644 tex/context/base/tabl-tbl.mkiv create mode 100644 tex/context/base/tabl-tsp.mkii create mode 100644 tex/context/base/tabl-tsp.mkiv create mode 100644 tex/context/base/task-ini.lua create mode 100644 tex/context/base/task-ini.mkiv create mode 100644 tex/context/base/thrd-pic.tex create mode 100644 tex/context/base/thrd-ran.mkii create mode 100644 tex/context/base/thrd-tab.tex create mode 100644 tex/context/base/thrd-trg.mkii create mode 100644 tex/context/base/toks-ini.lua create mode 100644 tex/context/base/toks-ini.mkiv create mode 100644 tex/context/base/trac-deb.lua create mode 100644 tex/context/base/trac-deb.mkiv 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.mkiv create mode 100644 tex/context/base/trac-log.lua create mode 100644 tex/context/base/trac-tex.mkiv create mode 100644 tex/context/base/trac-tim.lua create mode 100644 tex/context/base/trac-tra.lua create mode 100644 tex/context/base/trac-vis.mkii create mode 100644 tex/context/base/trac-vis.mkiv create mode 100644 tex/context/base/type-buy.mkii create mode 100644 tex/context/base/type-buy.mkiv create mode 100644 tex/context/base/type-cbg.mkii create mode 100644 tex/context/base/type-cow.mkii create mode 100644 tex/context/base/type-cow.mkiv create mode 100644 tex/context/base/type-def.mkii create mode 100644 tex/context/base/type-def.mkiv create mode 100644 tex/context/base/type-exp.mkii create mode 100644 tex/context/base/type-fsf.mkii create mode 100644 tex/context/base/type-ghz.mkii create mode 100644 tex/context/base/type-ghz.mkiv create mode 100644 tex/context/base/type-hgz.mkii create mode 100644 tex/context/base/type-hgz.mkiv create mode 100644 tex/context/base/type-husayni-default.mkiv create mode 100644 tex/context/base/type-ini.mkii create mode 100644 tex/context/base/type-ini.mkiv create mode 100644 tex/context/base/type-lua.mkiv 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-msw.mkii create mode 100644 tex/context/base/type-msw.mkiv create mode 100644 tex/context/base/type-one.mkii create mode 100644 tex/context/base/type-one.mkiv 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-pre.mkii create mode 100644 tex/context/base/type-run.mkii create mode 100644 tex/context/base/type-run.mkiv create mode 100644 tex/context/base/type-set.mkii create mode 100644 tex/context/base/type-set.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-tmf.mkii create mode 100644 tex/context/base/type-tmf.mkiv create mode 100644 tex/context/base/type-win.mkii create mode 100644 tex/context/base/type-win.mkiv create mode 100644 tex/context/base/type-xtx.mkii create mode 100644 tex/context/base/typo-brk.lua create mode 100644 tex/context/base/typo-brk.mkiv create mode 100644 tex/context/base/typo-cap.lua create mode 100644 tex/context/base/typo-cap.mkiv create mode 100644 tex/context/base/typo-dig.lua create mode 100644 tex/context/base/typo-dig.mkiv create mode 100644 tex/context/base/typo-ini.mkii create mode 100644 tex/context/base/typo-ini.mkiv create mode 100644 tex/context/base/typo-krn.lua create mode 100644 tex/context/base/typo-krn.mkiv create mode 100644 tex/context/base/typo-mir.lua create mode 100644 tex/context/base/typo-mir.mkiv create mode 100644 tex/context/base/typo-rep.lua create mode 100644 tex/context/base/typo-rep.mkiv create mode 100644 tex/context/base/typo-spa.lua create mode 100644 tex/context/base/typo-spa.mkiv create mode 100644 tex/context/base/unic-000.mkii create mode 100644 tex/context/base/unic-001.mkii create mode 100644 tex/context/base/unic-002.mkii create mode 100644 tex/context/base/unic-003.mkii create mode 100644 tex/context/base/unic-004.mkii create mode 100644 tex/context/base/unic-005.mkii create mode 100644 tex/context/base/unic-030.mkii create mode 100644 tex/context/base/unic-031.mkii create mode 100644 tex/context/base/unic-032.mkii create mode 100644 tex/context/base/unic-033.mkii create mode 100644 tex/context/base/unic-034.mkii create mode 100644 tex/context/base/unic-035.mkii create mode 100644 tex/context/base/unic-037.mkii create mode 100644 tex/context/base/unic-039.mkii create mode 100644 tex/context/base/unic-251.mkii create mode 100644 tex/context/base/unic-cjk.mkii create mode 100644 tex/context/base/unic-exp.mkii create mode 100644 tex/context/base/unic-ini.mkii create mode 100644 tex/context/base/unic-ini.mkiv create mode 100644 tex/context/base/unic-run.mkii create mode 100644 tex/context/base/verb-c.mkii create mode 100644 tex/context/base/verb-eif.mkii create mode 100644 tex/context/base/verb-ini.mkii create mode 100644 tex/context/base/verb-js.mkii create mode 100644 tex/context/base/verb-jv.mkii create mode 100644 tex/context/base/verb-mp.mkii create mode 100644 tex/context/base/verb-pas.mkii create mode 100644 tex/context/base/verb-pl.mkii create mode 100644 tex/context/base/verb-raw.mkii create mode 100644 tex/context/base/verb-sql.mkii create mode 100644 tex/context/base/verb-tex.mkii create mode 100644 tex/context/base/verb-xml.mkii create mode 100644 tex/context/base/x-asciimath.lua create mode 100644 tex/context/base/x-asciimath.mkiv create mode 100644 tex/context/base/x-calcmath.lua create mode 100644 tex/context/base/x-calcmath.mkii create mode 100644 tex/context/base/x-calcmath.mkiv create mode 100644 tex/context/base/x-cals.lua create mode 100644 tex/context/base/x-cals.mkiv create mode 100644 tex/context/base/x-chemml.mkii create mode 100644 tex/context/base/x-chemml.mkiv create mode 100644 tex/context/base/x-chemml.tex create mode 100644 tex/context/base/x-chemml.xsd create mode 100644 tex/context/base/x-contml.mkii create mode 100644 tex/context/base/x-contml.xsd create mode 100644 tex/context/base/x-corres.mkii create mode 100644 tex/context/base/x-corres.rng create mode 100644 tex/context/base/x-ct.lua create mode 100644 tex/context/base/x-ct.mkiv create mode 100644 tex/context/base/x-dir-01.tex create mode 100644 tex/context/base/x-dir-05.mkii create mode 100644 tex/context/base/x-dir-05.mkiv create mode 100644 tex/context/base/x-fdf-00.tex create mode 100644 tex/context/base/x-fe.mkii create mode 100644 tex/context/base/x-fig-00.dtd create mode 100644 tex/context/base/x-fig-00.tex create mode 100644 tex/context/base/x-fig-00.xsd create mode 100644 tex/context/base/x-fig-01.tex create mode 100644 tex/context/base/x-fig-02.tex create mode 100644 tex/context/base/x-fig-03.tex create mode 100644 tex/context/base/x-fo.mkii create mode 100644 tex/context/base/x-foxet.mkii create mode 100644 tex/context/base/x-foxet.mkiv create mode 100644 tex/context/base/x-ldx.ctx create mode 100644 tex/context/base/x-ldx.tex create mode 100644 tex/context/base/x-mathml.lua create mode 100644 tex/context/base/x-mathml.mkii create mode 100644 tex/context/base/x-mathml.mkiv create mode 100644 tex/context/base/x-mathml.tex create mode 100644 tex/context/base/x-mathml.xsd create mode 100644 tex/context/base/x-newcml.tex create mode 100644 tex/context/base/x-newmme.tex create mode 100644 tex/context/base/x-newmml.mkii create mode 100644 tex/context/base/x-newmml.mkiv create mode 100644 tex/context/base/x-newmml.tex create mode 100644 tex/context/base/x-newmmo.tex create mode 100644 tex/context/base/x-newpml.tex create mode 100644 tex/context/base/x-om2cml.xsl create mode 100644 tex/context/base/x-openmath.tex create mode 100644 tex/context/base/x-openmath.xsl create mode 100644 tex/context/base/x-pending.mkiv create mode 100644 tex/context/base/x-physml.mkii create mode 100644 tex/context/base/x-physml.mkiv create mode 100644 tex/context/base/x-physml.tex create mode 100644 tex/context/base/x-physml.xsd create mode 100644 tex/context/base/x-res-00.tex create mode 100644 tex/context/base/x-res-01.tex create mode 100644 tex/context/base/x-res-02.tex create mode 100644 tex/context/base/x-res-03.tex create mode 100644 tex/context/base/x-res-04.tex create mode 100644 tex/context/base/x-res-08.tex create mode 100644 tex/context/base/x-res-09.tex create mode 100644 tex/context/base/x-res-10.tex create mode 100644 tex/context/base/x-res-11.tex create mode 100644 tex/context/base/x-res-12.tex create mode 100644 tex/context/base/x-res-20.tex create mode 100644 tex/context/base/x-res-50.tex create mode 100644 tex/context/base/x-sch-00.tex create mode 100644 tex/context/base/x-sch-01.tex create mode 100644 tex/context/base/x-set-01.tex create mode 100644 tex/context/base/x-set-02.tex create mode 100644 tex/context/base/x-set-11.mkii create mode 100644 tex/context/base/x-set-11.mkiv create mode 100644 tex/context/base/x-set-11.tex create mode 100644 tex/context/base/x-set-12.tex create mode 100644 tex/context/base/x-set-99.tex create mode 100644 tex/context/base/x-sm2om.xsl create mode 100644 tex/context/base/x-xml-01.tex create mode 100644 tex/context/base/x-xml-02.tex create mode 100644 tex/context/base/x-xml-11.tex create mode 100644 tex/context/base/x-xtag.mkiv create mode 100644 tex/context/base/xetx-chr.mkii create mode 100644 tex/context/base/xetx-cls.mkii create mode 100644 tex/context/base/xetx-ini.mkii create mode 100644 tex/context/base/xetx-utf.mkii create mode 100644 tex/context/base/xtag-cml.tex create mode 100644 tex/context/base/xtag-ent.tex create mode 100644 tex/context/base/xtag-exp.tex create mode 100644 tex/context/base/xtag-ext.tex create mode 100644 tex/context/base/xtag-hyp.tex create mode 100644 tex/context/base/xtag-ini.tex create mode 100644 tex/context/base/xtag-map.tex create mode 100644 tex/context/base/xtag-mea.tex create mode 100644 tex/context/base/xtag-meb.tex create mode 100644 tex/context/base/xtag-mec.tex create mode 100644 tex/context/base/xtag-meh.tex create mode 100644 tex/context/base/xtag-men.tex create mode 100644 tex/context/base/xtag-meo.tex create mode 100644 tex/context/base/xtag-mer.tex create mode 100644 tex/context/base/xtag-mmc.tex create mode 100644 tex/context/base/xtag-mml.tex create mode 100644 tex/context/base/xtag-mmp.tex create mode 100644 tex/context/base/xtag-mxa.tex create mode 100644 tex/context/base/xtag-mxb.tex create mode 100644 tex/context/base/xtag-mxc.tex create mode 100644 tex/context/base/xtag-mxh.tex create mode 100644 tex/context/base/xtag-mxn.tex create mode 100644 tex/context/base/xtag-mxo.tex create mode 100644 tex/context/base/xtag-mxr.tex create mode 100644 tex/context/base/xtag-pml.tex create mode 100644 tex/context/base/xtag-pmu.tex create mode 100644 tex/context/base/xtag-pre.tex create mode 100644 tex/context/base/xtag-prs.tex create mode 100644 tex/context/base/xtag-raw.tex create mode 100644 tex/context/base/xtag-rng.tex create mode 100644 tex/context/base/xtag-run.tex create mode 100644 tex/context/base/xtag-stk.tex create mode 100644 tex/context/base/xtag-utf.tex create mode 100644 tex/context/base/xtag-xsd.tex create mode 100644 tex/context/base/xtag-xsl.tex create mode 100644 tex/context/bib/bibl-ams.tex create mode 100644 tex/context/bib/bibl-apa-de.tex create mode 100644 tex/context/bib/bibl-apa-fr.tex create mode 100644 tex/context/bib/bibl-apa.tex create mode 100644 tex/context/bib/bibl-aps.tex create mode 100644 tex/context/bib/bibl-num-fr.tex create mode 100644 tex/context/bib/bibl-num.tex create mode 100644 tex/context/bib/bibl-ssa.tex create mode 100644 tex/context/config/cont-usr.tex create mode 100644 tex/context/extra/mag-0000.tex create mode 100644 tex/context/extra/setup-qr.tex create mode 100644 tex/context/extra/showunic.tex create mode 100644 tex/context/fonts/antykwa-math.lfg create mode 100644 tex/context/fonts/charter-math.lfg create mode 100644 tex/context/fonts/garamond-math.lfg create mode 100644 tex/context/fonts/husayni.lfg create mode 100644 tex/context/fonts/hvmath-math.lfg create mode 100644 tex/context/fonts/informal-math.lfg create mode 100644 tex/context/fonts/iwona-math.lfg create mode 100644 tex/context/fonts/lm-math.lfg create mode 100644 tex/context/fonts/lucida-math.lfg create mode 100644 tex/context/fonts/mathtimes-math.lfg create mode 100644 tex/context/fonts/px-math.lfg create mode 100644 tex/context/fonts/symbol-math.lfg create mode 100644 tex/context/fonts/tx-math.lfg create mode 100644 tex/context/fonts/utopia-math.lfg create mode 100644 tex/context/foxet/fe-bryson.xml create mode 100644 tex/context/foxet/fe-ward.xml create mode 100644 tex/context/foxet/fe-zapf.xml create mode 100644 tex/context/foxet/fo-0101.fo create mode 100644 tex/context/foxet/fo-0102.fo create mode 100644 tex/context/foxet/fo-0103.fo create mode 100644 tex/context/foxet/fo-0201.fo create mode 100644 tex/context/foxet/fo-0301.fo create mode 100644 tex/context/foxet/fo-0601.fo create mode 100644 tex/context/foxet/fo-0602.fo create mode 100644 tex/context/foxet/fo-0603.fo create mode 100644 tex/context/foxet/fo-0604.fo create mode 100644 tex/context/foxet/fo-0611.fo create mode 100644 tex/context/foxet/fo-0612.fo create mode 100644 tex/context/foxet/fo-0613.fo create mode 100644 tex/context/foxet/fo-0621.fo create mode 100644 tex/context/foxet/fo-0641.fo create mode 100644 tex/context/foxet/fo-0642.fo create mode 100644 tex/context/foxet/fo-0643.fo create mode 100644 tex/context/foxet/fo-0644.fo create mode 100644 tex/context/foxet/fo-0650.fo create mode 100644 tex/context/foxet/fo-0651.fo create mode 100644 tex/context/foxet/fo-0701.fo create mode 100644 tex/context/foxet/fo-0801.fo create mode 100644 tex/context/foxet/fo-0901.fo create mode 100644 tex/context/foxet/fo-0902.fo create mode 100644 tex/context/foxet/fo-1001.fo create mode 100644 tex/context/foxet/fo-1002.fo create mode 100644 tex/context/foxet/fo-1003.fo create mode 100644 tex/context/foxet/fo-1004.fo create mode 100644 tex/context/foxet/fo-1101.fo create mode 100644 tex/context/foxet/fo-1102.fo create mode 100644 tex/context/foxet/fo-1103.fo create mode 100644 tex/context/foxet/fo-1104.fo create mode 100644 tex/context/foxet/fo-1201.fo create mode 100644 tex/context/interface/cont-cs.xml create mode 100644 tex/context/interface/cont-de.xml create mode 100644 tex/context/interface/cont-en.xml create mode 100644 tex/context/interface/cont-fr.xml create mode 100644 tex/context/interface/cont-it.xml create mode 100644 tex/context/interface/cont-nl.xml create mode 100644 tex/context/interface/cont-pe.xml create mode 100644 tex/context/interface/cont-ro.xml create mode 100644 tex/context/interface/keys-cs.xml create mode 100644 tex/context/interface/keys-cz.xml create mode 100644 tex/context/interface/keys-de.xml create mode 100644 tex/context/interface/keys-en.xml create mode 100644 tex/context/interface/keys-fr.xml create mode 100644 tex/context/interface/keys-it.xml create mode 100644 tex/context/interface/keys-nl.xml create mode 100644 tex/context/interface/keys-pe.xml create mode 100644 tex/context/interface/keys-ro.xml create mode 100644 tex/context/patterns/lang-agr.hyp create mode 100644 tex/context/patterns/lang-agr.pat create mode 100644 tex/context/patterns/lang-bg.hyp create mode 100644 tex/context/patterns/lang-bg.pat create mode 100644 tex/context/patterns/lang-bg.rme create mode 100644 tex/context/patterns/lang-ca.hyp create mode 100644 tex/context/patterns/lang-ca.pat create mode 100644 tex/context/patterns/lang-ca.rme create mode 100644 tex/context/patterns/lang-cs.hyp create mode 100644 tex/context/patterns/lang-cs.pat create mode 100644 tex/context/patterns/lang-cs.rme create mode 100644 tex/context/patterns/lang-cy.hyp create mode 100644 tex/context/patterns/lang-cy.pat create mode 100644 tex/context/patterns/lang-cy.rme create mode 100644 tex/context/patterns/lang-da.hyp create mode 100644 tex/context/patterns/lang-da.pat create mode 100644 tex/context/patterns/lang-da.rme create mode 100644 tex/context/patterns/lang-de.hyp create mode 100644 tex/context/patterns/lang-de.pat create mode 100644 tex/context/patterns/lang-de.rme create mode 100644 tex/context/patterns/lang-deo.hyp create mode 100644 tex/context/patterns/lang-deo.pat create mode 100644 tex/context/patterns/lang-deo.rme create mode 100644 tex/context/patterns/lang-es.hyp create mode 100644 tex/context/patterns/lang-es.pat create mode 100644 tex/context/patterns/lang-es.rme create mode 100644 tex/context/patterns/lang-et.hyp create mode 100644 tex/context/patterns/lang-et.pat create mode 100644 tex/context/patterns/lang-et.rme create mode 100644 tex/context/patterns/lang-eu.hyp create mode 100644 tex/context/patterns/lang-eu.pat create mode 100644 tex/context/patterns/lang-eu.rme create mode 100644 tex/context/patterns/lang-fi.hyp create mode 100644 tex/context/patterns/lang-fi.pat create mode 100644 tex/context/patterns/lang-fi.rme create mode 100644 tex/context/patterns/lang-fr.hyp create mode 100644 tex/context/patterns/lang-fr.pat create mode 100644 tex/context/patterns/lang-fr.rme create mode 100644 tex/context/patterns/lang-gb.hyp create mode 100644 tex/context/patterns/lang-gb.pat create mode 100644 tex/context/patterns/lang-gb.rme create mode 100644 tex/context/patterns/lang-hr.hyp create mode 100644 tex/context/patterns/lang-hr.pat create mode 100644 tex/context/patterns/lang-hr.rme create mode 100644 tex/context/patterns/lang-hu.hyp create mode 100644 tex/context/patterns/lang-hu.pat create mode 100644 tex/context/patterns/lang-hu.rme create mode 100644 tex/context/patterns/lang-is.hyp create mode 100644 tex/context/patterns/lang-is.pat create mode 100644 tex/context/patterns/lang-is.rme create mode 100644 tex/context/patterns/lang-it.hyp create mode 100644 tex/context/patterns/lang-it.pat create mode 100644 tex/context/patterns/lang-it.rme create mode 100644 tex/context/patterns/lang-la.hyp create mode 100644 tex/context/patterns/lang-la.pat create mode 100644 tex/context/patterns/lang-la.rme create mode 100644 tex/context/patterns/lang-lt.hyp create mode 100644 tex/context/patterns/lang-lt.pat create mode 100644 tex/context/patterns/lang-lt.rme create mode 100644 tex/context/patterns/lang-mn.hyp create mode 100644 tex/context/patterns/lang-mn.pat create mode 100644 tex/context/patterns/lang-mn.rme create mode 100644 tex/context/patterns/lang-nb.hyp create mode 100644 tex/context/patterns/lang-nb.pat create mode 100644 tex/context/patterns/lang-nb.rme create mode 100644 tex/context/patterns/lang-nl.hyp create mode 100644 tex/context/patterns/lang-nl.pat create mode 100644 tex/context/patterns/lang-nl.rhl create mode 100644 tex/context/patterns/lang-nl.rme create mode 100644 tex/context/patterns/lang-nl.rpl create mode 100644 tex/context/patterns/lang-nn.hyp create mode 100644 tex/context/patterns/lang-nn.pat create mode 100644 tex/context/patterns/lang-nn.rme create mode 100644 tex/context/patterns/lang-pl.hyp create mode 100644 tex/context/patterns/lang-pl.pat create mode 100644 tex/context/patterns/lang-pl.rme create mode 100644 tex/context/patterns/lang-pt.hyp create mode 100644 tex/context/patterns/lang-pt.pat create mode 100644 tex/context/patterns/lang-pt.rme create mode 100644 tex/context/patterns/lang-ro.hyp create mode 100644 tex/context/patterns/lang-ro.pat create mode 100644 tex/context/patterns/lang-ro.rme create mode 100644 tex/context/patterns/lang-ru.hyp create mode 100644 tex/context/patterns/lang-ru.pat create mode 100644 tex/context/patterns/lang-ru.rme create mode 100644 tex/context/patterns/lang-sk.hyp create mode 100644 tex/context/patterns/lang-sk.pat create mode 100644 tex/context/patterns/lang-sk.rme create mode 100644 tex/context/patterns/lang-sl.hyp create mode 100644 tex/context/patterns/lang-sl.pat create mode 100644 tex/context/patterns/lang-sl.rme create mode 100644 tex/context/patterns/lang-sr.hyp create mode 100644 tex/context/patterns/lang-sr.pat create mode 100644 tex/context/patterns/lang-sr.rme create mode 100644 tex/context/patterns/lang-sv.hyp create mode 100644 tex/context/patterns/lang-sv.pat create mode 100644 tex/context/patterns/lang-sv.rme create mode 100644 tex/context/patterns/lang-tk.hyp create mode 100644 tex/context/patterns/lang-tk.pat create mode 100644 tex/context/patterns/lang-tk.rme create mode 100644 tex/context/patterns/lang-tr.hyp create mode 100644 tex/context/patterns/lang-tr.pat create mode 100644 tex/context/patterns/lang-tr.rme 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/patterns/lang-us.hyp create mode 100644 tex/context/patterns/lang-us.pat create mode 100644 tex/context/patterns/lang-us.rme create mode 100644 tex/context/patterns/lang-zh.hyp create mode 100644 tex/context/patterns/lang-zh.pat create mode 100644 tex/context/patterns/lang-zh.rme create mode 100644 tex/context/sample/aesop-de.tex create mode 100644 tex/context/sample/bryson.tex create mode 100644 tex/context/sample/davis.tex create mode 100644 tex/context/sample/dawkins.tex create mode 100644 tex/context/sample/demo-mps.tex create mode 100644 tex/context/sample/demo-tex.tex create mode 100644 tex/context/sample/demo-xml.tex create mode 100644 tex/context/sample/douglas.tex create mode 100644 tex/context/sample/hawking.tex create mode 100644 tex/context/sample/knuth.tex create mode 100644 tex/context/sample/linden.tex create mode 100644 tex/context/sample/materie.tex create mode 100644 tex/context/sample/montgomery.tex create mode 100644 tex/context/sample/reich.tex create mode 100644 tex/context/sample/sample.tex create mode 100644 tex/context/sample/thuan.tex create mode 100644 tex/context/sample/tufte.tex create mode 100644 tex/context/sample/ward.tex create mode 100644 tex/context/sample/weisman.tex create mode 100644 tex/context/sample/zapf.tex create mode 100644 tex/context/test/context-test.tex create mode 100644 tex/context/user/cont-sys.rme 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 create mode 100644 tex/generic/context/m-ch-de.tex create mode 100644 tex/generic/context/m-ch-en.tex create mode 100644 tex/generic/context/m-ch-nl.tex create mode 100644 tex/generic/context/m-metapo.tex create mode 100644 tex/generic/context/mptopdf.tex create mode 100644 tex/generic/context/ppchtex.noc create mode 100644 tex/latex/context/m-ch-de.sty create mode 100644 tex/latex/context/m-ch-en.sty create mode 100644 tex/latex/context/m-ch-nl.sty create mode 100644 tex/latex/context/m-metapo.sty create mode 100644 tex/latex/context/m-pictex.sty (limited to 'tex') diff --git a/tex/context/base/anch-bar.mkii b/tex/context/base/anch-bar.mkii new file mode 100644 index 000000000..d08573c0f --- /dev/null +++ b/tex/context/base/anch-bar.mkii @@ -0,0 +1,194 @@ +%D \module +%D [ file=anch-bar, +%D version=2003.03.16, +%D title=\CONTEXT\ Anchoring Macros, +%D subtitle=Margin Bars and alike, +%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 Anchoring Macros / Margin Bars} + +\unprotect + +%D We will implement a sidebar mechanism using the +%D functionality from \type {core-pos}. +%D +%D \starttyping +%D \definesidebar[whow][rulecolor=green,distance=] +%D +%D \input tufte \par +%D \startsidebar +%D \input tufte \par +%D \input tufte \par +%D \startsidebar[whow] +%D \input tufte \par +%D \input tufte \par +%D \input tufte +%D \stopsidebar \par +%D \input tufte \par +%D \input tufte +%D \stopsidebar \par +%D \input tufte \par +%D \input tufte \par +%D \startsidebar +%D \input tufte \par +%D \input tufte \par +%D \input tufte \par +%D \input tufte \par +%D \input tufte +%D \stopsidebar \par +%D \input tufte \par +%D \input tufte \par +%D \startsidebar +%D \input tufte +%D \input tufte +%D \input tufte +%D \input tufte +%D \input tufte +%D \stopsidebar +%D \stoptyping + +\newcount\currentsidebar +\newdimen\sidebardistance + +\def\setupsidebars + {\dodoubleargument\dosetupsidebars} + +\def\dosetupsidebars[#1][#2]% + {\ifsecondargument + \getparameters[\??br#1][#2]% + \else + \getparameters[\??br][#1]% + \fi} + +% \setupMPvariables +% [mpos:bar] +% [linecolor=red, +% linewidth=2pt, +% distance=5pt] + +\setupsidebars + [\c!rulethickness=2pt, + \c!rulecolor=red, + \c!distance=.5\bodyfontsize] + +\def\definesidebar + {\dodoubleempty\dodefinesidebar} + +\def\dodefinesidebar[#1][#2]% + {\copyparameters + [\??br#1][\??br] + [\c!rulethickness,\c!rulecolor,\c!distance]% + \getparameters + [\??br#1][#2]} + +\def\startsidebar + {\dosingleempty\dostartsidebar} + +\def\dostartsidebar[#1]% + {\bgroup + \dontleavehmode + \checktextbackgrounds + \global\advance\currentsidebar\plusone + \doifelsenothing{#1} + {\advance\sidebardistance\@@brdistance} + {\doifelsevaluenothing{\??br#1\c!distance} + {\advance\sidebardistance\@@brdistance} + {\sidebardistance\getvalue{\??br#1\c!distance}}}% + \startpositionoverlay{text-1}% + \expanded{\setMPpositiongraphicrange + {b:side:\the\currentsidebar}% + {e:side:\the\currentsidebar}% + {mpos:bar}% + {self=side:\the\currentsidebar, + linewidth=\getvalue{\??br#1\c!rulethickness}, + linecolor=\getvalue{\??br#1\c!rulecolor}, + distance=\the\sidebardistance}}% + \stoppositionoverlay + \bpos{side:\the\currentsidebar}\ignorespaces} + +% \def\dostopsidebar#1% +% {\removelastspace\tpos{side:#1}\carryoverpar\egroup} + +\def\stopsidebar + {\removelastspace\tpos{side:\the\currentsidebar}\carryoverpar\egroup} + +\startMPpositionmethod{mpos:bar} + \startMPpositiongraphic{mpos:bar}{linecolor,linewidth,distance}% + StartPage ; + path p ; p := + if \MPp\MPbself=\MPp\MPeself : + (xpart ulcorner Field[Text][Text],\MPy\MPbself+\MPh\MPbself) -- + (xpart llcorner Field[Text][Text],\MPy\MPeself-\MPd\MPeself) ; + elseif RealPageNumber=\MPp\MPbself : + (xpart ulcorner Field[Text][Text],\MPy\MPbself+\MPh\MPbself) -- + (llcorner Field[Text][Text]) ; + elseif RealPageNumber=\MPp\MPeself : + (ulcorner Field[Text][Text]) -- + (xpart llcorner Field[Text][Text],\MPy\MPeself-\MPd\MPeself) ; + else : + (ulcorner Field[Text][Text]) -- + (llcorner Field[Text][Text]) ; + fi ; + p := p shifted (-llcorner Field[Text][Text]-(\MPvar{distance},0)) ; + interim linecap := butt ; + draw p + withpen pencircle scaled \MPvar{linewidth} + withcolor \MPvar{linecolor} ; + StopPage ; + \stopMPpositiongraphic + \MPpositiongraphic{mpos:bar}{}% +\stopMPpositionmethod + +%D We now reimplement the margin rules handler defined in +%D \type {core-rul}: +%D +%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 + +\definesidebar + [\v!margin] + [\c!rulecolor=\s!black, + \c!rulethickness=\@@karulethickness, + \c!distance=\dimexpr\leftmargindistance-\@@karulethickness/2\relax] + +\definecomplexorsimple\startmarginrule + +\def\simplestartmarginrule + {\complexstartmarginrule[1]} + +\def\complexstartmarginrule[#1]% + {\bgroup + \ifnum#1<\@@kalevel\relax + \let\stopmarginrule\egroup + \else + \def\@@kadefaultwidth{#1}% + \let\stopmarginrule\dostopmarginrule + \@EA\startsidebar\@EA[\@EA\v!margin\@EA]% + \fi} + +\def\dostopmarginrule + {\stopsidebar + \egroup} + +\protect \endinput diff --git a/tex/context/base/anch-bar.mkiv b/tex/context/base/anch-bar.mkiv new file mode 100644 index 000000000..1013e7609 --- /dev/null +++ b/tex/context/base/anch-bar.mkiv @@ -0,0 +1,179 @@ +%D \module +%D [ file=anch-bar, +%D version=2003.03.16, +%D title=\CONTEXT\ Anchoring Macros, +%D subtitle=Margin Bars and alike, +%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 Anchoring Macros / Margin Bars} + +\unprotect + +%D We will implement a sidebar mechanism using the +%D functionality from \type {core-pos}. +%D +%D \starttyping +%D \definesidebar[whow][rulecolor=green,distance=] +%D +%D \input tufte \par +%D \startsidebar +%D \input tufte \par +%D \input tufte \par +%D \startsidebar[whow] +%D \input tufte \par +%D \input tufte \par +%D \input tufte +%D \stopsidebar \par +%D \input tufte \par +%D \input tufte +%D \stopsidebar \par +%D \input tufte \par +%D \input tufte \par +%D \startsidebar +%D \input tufte \par +%D \input tufte \par +%D \input tufte \par +%D \input tufte \par +%D \input tufte +%D \stopsidebar \par +%D \input tufte \par +%D \input tufte \par +%D \startsidebar +%D \input tufte +%D \input tufte +%D \input tufte +%D \input tufte +%D \input tufte +%D \stopsidebar +%D \stoptyping + +\newcount\currentsidebar +\newdimen\sidebardistance + +\unexpanded\def\setupsidebars + {\dodoubleargument\dosetupsidebars} + +\def\dosetupsidebars[#1][#2]% + {\ifsecondargument + \getparameters[\??br#1][#2]% + \else + \getparameters[\??br][#1]% + \fi} + +% \setupMPvariables +% [mpos:bar] +% [linecolor=red, +% linewidth=2pt, +% distance=5pt] + +\setupsidebars + [\c!rulethickness=2pt, + \c!rulecolor=red, + \c!distance=.5\bodyfontsize] + +\unexpanded\def\definesidebar + {\dodoubleempty\dodefinesidebar} + +\def\dodefinesidebar[#1][#2]% + {\copyparameters + [\??br#1][\??br] + [\c!rulethickness,\c!rulecolor,\c!distance]% + \getparameters + [\??br#1][#2]} + +\unexpanded\def\startsidebar + {\dosingleempty\dostartsidebar} + +\def\dostartsidebar[#1]% + {\bgroup + \dontleavehmode + \checktextbackgrounds + \global\advance\currentsidebar\plusone + \doifelsenothing{#1} + {\advance\sidebardistance\@@brdistance} + {\doifelsevaluenothing{\??br#1\c!distance} + {\advance\sidebardistance\@@brdistance} + {\sidebardistance\getvalue{\??br#1\c!distance}}}% + \startpositionoverlay{text-1}% + \expanded{\setMPpositiongraphicrange + {b:side:\the\currentsidebar}% + {e:side:\the\currentsidebar}% + {mpos:bar}% + {self=side:\the\currentsidebar, + linewidth=\getvalue{\??br#1\c!rulethickness}, + linecolor=\getvalue{\??br#1\c!rulecolor}, + distance=\the\sidebardistance}}% + \stoppositionoverlay + \bpos{side:\the\currentsidebar}\ignorespaces} + +% \def\dostopsidebar#1% +% {\removelastspace\tpos{side:#1}\carryoverpar\egroup} + +\unexpanded\def\stopsidebar + {\removelastspace\tpos{side:\the\currentsidebar}\carryoverpar\egroup} + +\startMPpositionmethod{mpos:bar} + \startMPpositiongraphic{mpos:bar}{linecolor,linewidth,distance}% + position_anchor_bar ( + \MPp\MPbself, \MPp\MPeself, + \MPy\MPbself, \MPy\MPeself, + \MPh\MPbself, \MPd\MPeself, + \MPvar{distance}, \MPvar{linewidth}, \MPvar{linecolor} + ) ; + \stopMPpositiongraphic + \MPpositiongraphic{mpos:bar}{}% +\stopMPpositionmethod + +%D We now reimplement the margin rules handler defined in +%D \type {core-rul}: +%D +%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 + +\definesidebar + [\v!margin] + [\c!rulecolor=\s!black, + \c!rulethickness=\@@karulethickness, + \c!distance=\dimexpr\leftmargindistance-\@@karulethickness/2\relax] + +\definecomplexorsimple\startmarginrule + +\def\simplestartmarginrule + {\complexstartmarginrule[1]} + +\def\complexstartmarginrule[#1]% + {\bgroup + \ifnum#1<\@@kalevel\relax + \let\stopmarginrule\egroup + \else + \def\@@kadefaultwidth{#1}% + \let\stopmarginrule\dostopmarginrule + \@EA\startsidebar\@EA[\@EA\v!margin\@EA]% + \fi} + +\def\dostopmarginrule + {\stopsidebar + \egroup} + +\protect \endinput diff --git a/tex/context/base/anch-pgr.mkii b/tex/context/base/anch-pgr.mkii new file mode 100644 index 000000000..194f19755 --- /dev/null +++ b/tex/context/base/anch-pgr.mkii @@ -0,0 +1,1687 @@ +%D \module +%D [ file=anch-pgr, % split off core-pos +%D version=1999.08.01, +%D title=\CONTEXT\ Anchoring Macros, +%D subtitle=Positioning Graphics, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 Anchoring Macros / 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 +%D is hooked into the page building routine. + +\unprotect + +% in the future, the depth of tail will reflect page depth + +\ifx\textheight\undefined \def\textheight{\vsize} \fi + +%D The next macros so some housekeeping. + +\def\pageanchor{page:0} % for the moment only one pagesize +\def\textanchor{text:\realfolio} +\def\headanchor{head:\realfolio} % virtual position +\def\tailanchor{tail:\realfolio} % virtual position + +%D Anchors: + +\def\dopresetpositionanchors % also mkii + {\bgroup + \!!dimena\ifdim\topskip>\strutht\topskip\else\strutht\fi + \!!dimenb\dimexpr\MPy\textanchor+\MPh\textanchor-\!!dimena\relax + \!!dimenc\dimexpr\MPy\textanchor+\strutdp\relax + \!!dimend\MPx\textanchor + \!!dimene\MPw\textanchor + \replacepospxywhd\headanchor\realfolio\!!dimend\!!dimenb\!!dimene\!!dimena\strutdp + \replacepospxywhd\tailanchor\realfolio\!!dimend\!!dimenc\!!dimene\strutht \strutdp + \egroup} + +\def\presetpositionanchors% compatibility hack (still needed?) + {\ifpositioning + \dopresetpositionanchors + \fi} + +%D The first version of this module implemented head and tail +%D anchors. Currently we stick to just one anchor and derive +%D the head and tail anchors from this one. + +\def\showanchor#1% + {\expanded{\writestatus{#1} + {\MPp{#1}\string|\MPx{#1}\string|\MPy{#1}\string|% + \MPw{#1}\string|\MPh{#1}\string|\MPd{#1}}}} + +%D We set these anchors before and after each page. + +\appendtoks \presetpositionanchors \to \beforeeverypage +\appendtoks \presetpositionanchors \to \aftereverypage + +% todo: change with each page size change + +\def\registerpageposition#1% this one is flushed first ! + {\ifpositioning\ifcase\realpageno\or + \ifdim\printpaperheight=\paperheight\else + \ifdim\printpaperwidth=\paperwidth\else + \setbox#1\hbox{\hpos\pageanchor{\box#1}}% + \fi + \fi + \fi\fi} + +\def\placepositionanchors % todo : depth pagebox + {\ifpositioning + \setbox\scratchbox\vbox to \textheight + {\simpletopskipcorrection + \hbox{\strut\dopositionaction\headanchor}% + \vfill + \hbox{\strut\dopositionaction\tailanchor}}% + \dp\scratchbox\zeropoint + \wd\scratchbox\makeupwidth % not \zeropoint, else wrong text backgrounds + \hpos\textanchor{\box\scratchbox}% + \else + \vskip\textheight + \fi} + +%D \macros +%D {positionoverlay,startpositionoverlay} +%D +%D As long as we're dealing with graphics it makes much sense +%D to use the available overlay mechanism. For this purpose, we +%D define some dedicated overlay extensions. +%D +%D \startbuffer[sample] +%D \defineoverlay [sample] [\positionoverlay{sample}] +%D +%D \startpositionoverlay{sample} +%D \setMPpositiongraphic{A-1}{connectcenter}{from=A-1,to=A-2} +%D \stoppositionoverlay +%D \stopbuffer +%D +%D \typebuffer[sample] +%D +%D \startbuffer[graphic] +%D \startMPpositiongraphic{connectcenter} +%D path pa, pb ; pair ca, cb ; +%D initialize_box(\MPpos{\MPvar{from}}) ; pa := pxy ; ca := cxy ; +%D initialize_box(\MPpos{\MPvar{to}}) ; pb := pxy ; cb := cxy ; +%D draw pa withcolor red ; +%D draw pb withcolor red ; +%D draw ca -- cb withcolor blue ; +%D anchor_box(\MPanchor{\MPvar{from}}) ; +%D \stopMPpositiongraphic +%D \stopbuffer +%D +%D We can best demonstrate this in an example, say: +%D +%D \startbuffer[text] +%D \framed +%D [backgroundachtergrond=sample,align=middle,width=7cm] +%D {We want to connect \hpos {A-1} {this} word with its +%D grammatical cousin \hpos {A-2} {that}.} +%D \stopbuffer +%D +%D \typebuffer[text] +%D +%D \startlinecorrection +%D %\getbuffer[graphic,sample,text] +%D \stoplinecorrection +%D +%D The graphic is defined in the following way, using some +%D macros defined in an auxiliary \METAPOST\ module that is +%D preloaded. +%D +%D \typebuffer[graphic] + +\def\MPanchoridentifier{mpa} % {mp-anchor} +\def\MPoverlayposprefix{MO::} + +% obsolete and wrong anyway +% +% \long\def\defineMPpositiongraphic#1% +% {\long\setvalue{\MPoverlayposprefix#1}} + +%D The rest of the definitions concerning such overlays may +%D look complicated, + +\let\currentpositionoverlay\empty + +%D Position actions are automatically executed when a position +%D is set. + +\let\MPanchornumber\realfolio + +\def\positionoverlay#1% the test prevents too many redundant positions + {\ifpositioning % in (not used) text* position layers + \vbox to \overlayheight + {\doifpositionactionelse{#1::\MPanchoridentifier}% + {\edef\MPanchorid{#1::\MPanchoridentifier:\MPanchornumber}% + \edef\MPanchor##1{\MPpos{\MPanchorid}}% + \the\everyinsertpositionaction + \copyposition{#1::\MPanchoridentifier}{#1::\MPanchoridentifier:\MPanchornumber}% + \hpos + {#1::\MPanchoridentifier:\MPanchornumber}% + % this is ok + %{\hbox to \overlaywidth{\dopositionaction{#1::\MPanchoridentifier}\hss}}}% + % but this one prevents cyclic runs due to + % rounding errors + {\setbox\scratchbox\hbox to \overlaywidth{\dopositionaction{#1::\MPanchoridentifier}\hss}% + \ht\scratchbox\overlayheight + \dp\scratchbox\zeropoint + \box\scratchbox}}% + {\hbox to \overlaywidth{\hss}}% + \vfill}% + \fi} + +\def\startpositionoverlay#1% + {\iftrialtypesetting % we don't want redundant entries in the list + \@EA\gobbleuntil\@EA\stoppositionoverlay + \else + \def\currentpositionoverlay{#1}% + \fi} + +\def\stoppositionoverlay + {\let\currentpositionoverlay\empty} + +\def\resetpositionoverlay#1% + {\dosetpositionaction{#1::\MPanchoridentifier::}{}} + +%D Here the complication has to do with collecting actions +%D for later execution. This collection is especially handy +%D when we want to move actions to a specific layer. +%D Such series of actions are stored in a macro (the one +%D with the funny \type {++}) which is cleaned up after each +%D invocation. + +\newtoks\everycleanpositionaction +\newtoks\everyinsertpositionaction + +\def\cleanuppositionaction#1% not in trialtypesetting + {\ifcsname\POSactionprefix#1++\endcsname % \ifundefined{\POSactionprefix#1++}\else + \the\everycleanpositionaction + \iflocalpositioning + \letgvalue{\POSactionprefix#1++}\empty + \else + \setxvalue{\POSactionprefix#1++}{\getvalue{\POSactionprefix#1++}}% + \fi + \fi} + +% \def\cleanuppositionaction#1% not in trialtypesetting +% {\ifcsname\POSactionprefix#1++\endcsname +% \the\everycleanpositionaction +% \iflocalpositioning +% \global\expandafter\let\csname\POSactionprefix#1++\endcsname\empty +% \else +% \global\expandafter\let\csname\POSactionprefix#1++\expandafter\endcsname\csname\POSactionprefix#1++\endcsname +% \fi +% \fi} + +\def\handlepositionaction#1\with#2\on#3% + {\bgroup + \ifx\currentpositionoverlay\empty + \edef\!!stringa{#3}% no layer, just pos itself as anchor + \else + \edef\!!stringa{\currentpositionoverlay::\MPanchoridentifier}% + \fi + \edef\!!stringc{\POSactionprefix\!!stringa++}% + \expanded{\dosetpositionaction{\!!stringa}{\noexpand\getvalue{\!!stringc}}}% + \global\let#1\relax + \edef\!!stringb{\executeifdefined\!!stringc\empty}% + \setxvalue\!!stringc{\!!stringb#1#2}% + \egroup} + +%D The indirectness enables us redefine macros for special +%D purposes, like a cleanup. + +\def\handlepositionboxes#1#2#3% + {\handlepositionaction\dohandlepositionboxes\with{#1}{#2}{#3}\on{#2}} + +\def\doinsertpositionboxes#1#2#3% pos tag setups + {\ifnum\MPp{#1}=\realpageno\relax % can be sped up + \executeifdefined{\MPoverlayposprefix#1}\gobblethreearguments{#1}{#2}{#3}% + \fi} + +\appendtoks + \let\dohandlepositionboxes\doinsertpositionboxes % was handle ? +\to \everyinsertpositionaction + +\def\docleanpositionboxes#1#2#3% pos tag setups + {\ifnum\MPp{#1}<\realpageno \else + \noexpand \dohandlepositionboxes{#1}{#2}{#3}% reinsert + \fi} + +\appendtoks + \let\dohandlepositionboxes\docleanpositionboxes +\to \everycleanpositionaction + +%D A position graphic is a normal (non||reused) \METAPOST\ +%D graphic, used immediately, with zero dimensions, so that a +%D sequence of them does not harm. + +\newbox\positiongraphicbox + +\def\startMPpositiongraphic % id setups + {\dodoublegroupempty\dostartMPpositiongraphic} + +\long\def\dostartMPpositiongraphic#1#2#3\stopMPpositiongraphic + {\long\setgvalue{MPG:#1}% tag list mpcode + {\useMPpositiongraphic{#1}{#2}{#3}}} + +\let\stopMPpositiongraphic\relax + +% \def\prepareMPpositionvariables +% {\ifundefined{\@@meta self}\setvalue{\@@meta self}{\currentposition}\fi +% \ifundefined{\@@meta from}\setvalue{\@@meta from}{\currentposition}\fi} + +\def\prepareMPpositionvariables + {\ifcsname\@@meta self\endcsname\else\setvalue{\@@meta self}{\currentposition}\fi + \ifcsname\@@meta from\endcsname\else\setvalue{\@@meta from}{\currentposition}\fi} + +\newif\ifcollectMPpositiongraphics \collectMPpositiongraphicstrue + +\long\def\useMPpositiongraphic#1#2#3% + {\bgroup + \prepareMPvariables{#2}% + \prepareMPpositionvariables + \enableincludeMPgraphics + \ifcollectMPpositiongraphics % no longer needed in mkiv + \expanded{\startMPdrawing#3\noexpand\stopMPdrawing}% + \global\MPdrawingdonetrue + \else\ifx\startMPgraphic\undefined + \startMPcode#3\stopMPcode + \else + \startMPgraphic#3\stopMPgraphic + \loadMPgraphic{\MPgraphicfile.\the\currentMPgraphic}{}% + \deallocateMPslot\currentMPgraphic + \placeMPgraphic + \fi\fi + \egroup} + +% Now we need a adapted action handler: + +\def\dopositionaction#1% test saves hash entry in etex + {\ifundefined{\POSactionprefix#1::}\else + \ifnum\MPp{#1}>\zerocount % new + \bgroup + \setbox\scratchbox\hbox + \bgroup + \traceposstring\clap\red{<#1>}% + \the\everyinsertpositionaction + \the\everypositionaction + \ifcollectMPpositiongraphics + % can save a lot of run time + \pushMPdrawing + \MPshiftdrawingtrue + \resetMPdrawing + \getvalue{\POSactionprefix#1::}% + \ifMPdrawingdone + \getMPdrawing + \fi + \resetMPdrawing + \popMPdrawing + \else + \getvalue{\POSactionprefix#1::}% + \fi + \cleanuppositionaction{#1}% + \egroup % smashed is really needed else + \smashedbox\scratchbox % we get problems with too big + \egroup % overlays (s-pre-0x.tex) + \else + % shouldn't happen too often + \traceposstring\clap\cyan{<#1>}% + \fi + \fi} + +\def\MPpositiongraphic + {\dodoublegroupempty\doMPpositiongraphic} + +\def\doMPpositiongraphic#1#2% tag setups + {\bgroup + \def\@@meta{#1:}% + \setupMPvariables[#2]% + \prepareMPpositionvariables + \MPshiftdrawingtrue + \def\doMPpositiongraphic##1##2% + {{% new, see (techniek) + \def\@@meta{##1:}% + \setupMPvariables[#2,##2]% + \prepareMPpositionvariables + % and needed + \getvalue{MPG:##1}}}% temp hack + \setbox\positiongraphicbox\hbox + {\ignorespaces + \executeifdefined{MPM:#1}{\executeifdefined{MPG:#1}\donothing}% + \removelastspace}% + \smashbox\positiongraphicbox + \box\positiongraphicbox + \egroup} + +\long\def\startMPpositionmethod#1#2\stopMPpositionmethod + {\long\setgvalue{MPM:#1}{#2}} % todo: var list here + +\let\stopMPpositionmethod\relax + +%D Simple one position graphics. + +\def\setMPpositiongraphic + {\dotriplegroupempty\dosetMPpositiongraphic} + +\def\dosetMPpositiongraphic#1#2#3% pos tag vars + {\ifx\currentpositionoverlay\empty + \dosetpositionaction{#1}{\MPpositiongraphic{#2}{#3}}% + \else % silly can be one + \handlepositiongraphics{#1}{#2}{#3}% + \fi} + +\def\handlepositiongraphics#1#2#3% combine with boxes + {\handlepositionaction\dohandleMPpositiongraphic\with{#1}{#2}{#3}\on{#2}} + +\def\doinsertMPpositiongraphic#1#2#3% pos tag setups + {\ifnum\MPp{#1}=\realpageno\relax % extra saveguard + \def\currentposition{#1}\MPpositiongraphic{#2}{#3}% + \fi} + +\appendtoks + \let\dohandleMPpositiongraphic\doinsertMPpositiongraphic +\to \everyinsertpositionaction + +\def\docleanMPpositiongraphic#1#2#3% pos tag setups + {\ifnum\MPp{#1}<\realpageno \else + \noexpand \dohandleMPpositiongraphic{#1}{#2}{#3}% + \fi} + +\appendtoks + \let\dohandleMPpositiongraphic\docleanMPpositiongraphic +\to \everycleanpositionaction + +%D Graphics that span two positions. + +\def\setMPpositiongraphicrange + {\doquadruplegroupempty\dosetMPpositiongraphicrange} + +\def\dosetMPpositiongraphicrange#1#2#3#4% bpos epos tag vars + {\ifx\currentpositionoverlay\empty + \dosetpositionaction{#1}{\MPpositiongraphic{#3}{#4}}% + \else + \handlepositiongraphicsrange{#1}{#2}{#3}{#4}% + \fi} + +\def\handlepositiongraphicsrange#1#2#3#4% + {\handlepositionaction\dohandleMPpositiongraphicrange\with{#1}{#2}{#3}{#4}\on{#2}} + +\def\doinsertMPpositiongraphicrange#1#2#3#4% pos pos tag setups + {\ifnum\MPp{#1}\MPp{#2}>\zerocount + \iflocalpositioning + \donetrue + \else + \donefalse + \ifnum\MPp{#1}=\realpageno + \donetrue + \else\ifnum\MPp{#2}=\realpageno + \donetrue + \else\ifnum\MPp{#1}<\realpageno\relax\ifnum\MPp{#2}>\realpageno + \donetrue + \fi\fi\fi\fi + \fi + \ifdone + \def\currentposition{#1}\MPpositiongraphic{#3}{#4}% + \fi + \fi} + +\appendtoks + \let\dohandleMPpositiongraphicrange\doinsertMPpositiongraphicrange +\to \everyinsertpositionaction + +\def\docleanMPpositiongraphicrange#1#2#3#4% pos tag setups + {\ifnum\MPp{#2}<\realpageno \else + \noexpand \dohandleMPpositiongraphicrange{#1}{#2}{#3}{#4}% + \fi} + +\appendtoks + \let\dohandleMPpositiongraphicrange\docleanMPpositiongraphicrange +\to \everycleanpositionaction + +% will be overloaded, and/or code below moved to core-box + +\defineoverlay[\v!text-2][\positionoverlay{\v!text-2}] +\defineoverlay[\v!text-1][\positionoverlay{\v!text-1}] +\defineoverlay[\v!text+1][\positionoverlay{\v!text+1}] +\defineoverlay[\v!text+2][\positionoverlay{\v!text+2}] + +%D The auxiliary \METAPOST\ macros are defined by default, +%D by saying: + +\startMPextensions + if unknown context_core : input mp-core.mp ; fi ; +\stopMPextensions + +%D Some of these macros are pretty clever but too complicated +%D to be nice. When things are kind of stable I'll clean up +%D this mess. + +%D THIS NEEDS A CLEANUP + +\setupMPvariables + [mpos:box] + [linecolor=blue, + linewidth=\linewidth, + fillcolor=lightgray, + filloffset=\!!zeropoint] + +\startMPpositiongraphic{mpos:box}{fillcolor,linecolor,linewidth} + initialize_box(\MPpos{\MPvar{self}}) ; + boxfillcolor := \MPvar{fillcolor} ; + boxlinecolor := \MPvar{linecolor} ; + boxlinewidth := \MPvar{linewidth} ; + boxfilloffset := \MPvar{filloffset} ; + draw_box ; + anchor_box(\MPanchor{\MPvar{self}}) ; +\stopMPpositiongraphic + +\setupMPvariables + [mpos:area] + [linecolor=blue, + linewidth=\linewidth, + fillcolor=lightgray, + filloffset=\!!zeropoint] + +\startMPpositiongraphic{mpos:area}{fillcolor,linecolor,linewidth} + initialize_area(\MPpos{b:\MPvar{self}},\MPpos{e:\MPvar{self}}) ; + boxfillcolor := \MPvar{fillcolor} ; + boxlinecolor := \MPvar{linecolor} ; + boxlinewidth := \MPvar{linewidth} ; + boxfilloffset := \MPvar{filloffset} ; + draw_area ; + anchor_area(\MPanchor{b:\MPvar{self}}) ; +\stopMPpositiongraphic + +%D This is already cleaned up. + +% gridtype = 1 => baseline +% gridtype = 2 => betweenline + +\setupMPvariables + [mpos:par] + [mp=mpos:par:shape, + gridtype=0, + linetype=1, + filltype=1, + dashtype=0, % 1 = dashed, 2 = dashed with background + %snaptops=true, % not that nice: true/false + gridcolor=red, + linecolor=blue, + fillcolor=lightgray, + filloffset=\!!zeropoint, + linewidth=\linewidth, + gridwidth=\linewidth, + gridshift=\!!zeropoint, + lineradius=.5\bodyfontsize, + dashtype=1] + +\startuseMPgraphic{mpos:par:shape} + \iftracepositions show_par \else draw_par \fi ; +\stopuseMPgraphic + +\startuseMPgraphic{mpos:par:setup} + boxgridtype := \MPvar{gridtype} ; + boxlinetype := \MPvar{linetype} ; + boxfilltype := \MPvar{filltype} ; + boxdashtype := \MPvar{dashtype} ; + boxgridcolor := \MPvar{gridcolor} ; + boxlinecolor := \MPvar{linecolor} ; + boxfillcolor := \MPvar{fillcolor} ; + boxfilloffset := \MPvar{filloffset} ; + boxlinewidth := \MPvar{linewidth} ; + boxgridwidth := \MPvar{gridwidth} ; + boxgridshift := \MPvar{gridshift} ; + boxlineradius := \MPvar{lineradius} ; + %snap_multi_par_tops := \MPvar{snaptops} ; +\stopuseMPgraphic + +\startuseMPgraphic{mpos:par:extra} + % user stuff, like: + % snap_multi_par_tops := false ; +\stopuseMPgraphic + +\ifx\MPparcounter\undefined \newcounter\MPparcounter \fi + +\def\MPself {\MPvar{self}} +\def\MPbself {b:\MPself} +\def\MPeself {e:\MPself} +\def\MPwself {w:\MPself} +\def\MPparanchor{p:\MPparcounter} + +\def\MPl#1{\MPplus{#1}20} +\def\MPr#1{\MPplus{#1}30} + +\startMPpositionmethod{mpos:par} %%%%%%%%%%% will become obsolete + \edef\MPparcounter{\MPv\MPbself{1}{0}}% + \doifpositionelse\MPwself + {\startMPpositiongraphic{mpos:par}{fillcolor,filloffset,linecolor,gridcolor,linewidth,gridwidth,gridshift,lineradius} + initialize_area_par(\MPpos\MPbself, + \MPpos\MPeself, + \MPpos\MPwself) ; + \includeMPgraphic{mpos:par:setup} ; + \includeMPgraphic{mpos:par:extra} ; + \includeMPgraphic{\MPvar{mp}} ; + anchor_par(\MPanchor\MPbself) ; + \stopMPpositiongraphic} + {\startMPpositiongraphic{mpos:par}{fillcolor,filloffset,linecolor,gridcolor,linewidth,gridwidth,gridshift,lineradius} + initialize_par(\MPpos\MPbself, + \MPpos\MPeself, + \MPpos\textanchor, + \MPpos\MPparanchor, + \MPvv \MPparanchor{0pt,0pt,0pt,0pt,0,0pt}) ; + \includeMPgraphic{mpos:par:setup} ; + \includeMPgraphic{mpos:par:extra} ; + \includeMPgraphic{\MPvar{mp}} ; + anchor_par(\MPanchor\MPbself) ; + \stopMPpositiongraphic}% + \MPpositiongraphic{mpos:par}{}% +\stopMPpositionmethod + +%D The next alternative works in columnsets : + +% \iftracepositions show\else draw\fi_multi_pars ; + +\startuseMPgraphic{mpos:par:columnset} + \iftracepositions show_multi_pars \else draw_multi_pars \fi ; +\stopuseMPgraphic + +\startuseMPgraphic{mpos:par:sideline}{linecolor,lineoffset} + for i=1 upto nofmultipars : + fill leftboundary multipars[i] + shifted (-\MPvar{lineoffset},0) + rightenlarged 1mm withcolor \MPvar{linecolor} ; + endfor ; +\stopuseMPgraphic + +\startMPpositionmethod{mpos:par:columnset} + \edef\MPparcounter{\MPv\MPbself{1}{0}}% + \startMPpositiongraphic{mpos:par}{fillcolor,filloffset,linecolor,gridcolor,linewidth,gridwidth,gridshift,lineradius} + \includeMPgraphic{mpos:par:setup} ; + \includeMPgraphic{mpos:par:extra} ; + prepare_multi_pars(\MPpos\MPbself,\MPpos\MPeself,\MPpos\MPwself, + \MPpos\MPparanchor,\MPvv\MPparanchor{0pt,0pt,0pt,0pt,0,0pt}) ; + relocate_multipars(-\MPxy\MPanchorid) ; % inside layerpos + \includeMPgraphic{\MPvar{mp}} ; + \stopMPpositiongraphic + \MPpositiongraphic{mpos:par}{}% +\stopMPpositionmethod + +%D \starttyping +%D \setupbackground +%D [test] +%D [mp=mpos:par:columnset, +%D method=mpos:par:columnset] +%D \stoptyping + +%D We need to treat floats in a special way. + +\startMPinitializations + local_multi_par_area:=\iflocalpositioning true\else false\fi; +\stopMPinitializations + +\def\textbackgroundoverlay#1% + {\iflocalpositioning\v!local\else\v!text\fi#1} + +\newcounter\localpositionnumber + +\def\MPanchornumber + {\iflocalpositioning\localpositionnumber\else\realfolio\fi} + +%D So far for the trickery. + +\newcount\textbackgrounddepth + +\appendtoks + \expanded{\savecurrentvalue\noexpand\totalnofparbackgrounds{\number\nofparbackgrounds}}% +\to \everybye + +\appendtoks + \initializeparbackgrounds +\to \everystarttext + +\ifx\totalnofparbackgrounds\undefined \newcounter\totalnofparbackgrounds \fi +\ifx\nofparbackgrounds \undefined \newcount \nofparbackgrounds \fi + +\def\initializeparbackgrounds + {\ifcase\totalnofparbackgrounds\else + \enableparpositions + \fi} + +\unexpanded\def\starttextbackground + {\bgroup + \advance\textbackgrounddepth\plusone + \dodoubleempty\dostarttextbackground} + +\let\dodostarttextbackground\relax +\let\dodostoptextbackground \relax + +\def\currentparbackground{pbg:0} +\def\nextparbackground {pbg:1} + +\def\btbanchor{b:\currentparbackground} +\def\etbanchor{e:\currentparbackground} + +\def\nextbtbanchor{b:\nextparbackground} +\def\nextetbanchor{e:\nextparbackground} + +\def\textbackgroundparameter#1% + {\csname\??td\currenttextbackground#1\endcsname} + +\let\backgroundvariable\textbackgroundparameter % will become obsolete + +% \definetextbackground[more][state=start,backgroundcolor=red] % location=paragraph +% \definetextbackground[test][state=start,backgroundcolor=green] +% +% \page \placefigure[left]{}{} +% +% \starttextbackground[test] +% \readfile{ward}{}{} +% \starttextbackground[more] +% \readfile{ward}{}{} +% \stoptextbackground +% \readfile{ward}{}{} +% \stoptextbackground +% +% \page \placefigure[right]{}{} +% +% \starttextbackground[test] +% \readfile{ward}{}{} +% \starttextbackground[more] +% \readfile{ward}{}{} +% \stoptextbackground +% \readfile{ward}{}{} +% \stoptextbackground + +\def\dostarttextbackground[#1][#2]% + {\checktextbackgrounds + \def\currenttextbackground{#1}% + \global\advance\nofparbackgrounds\plusone + \edef\currentparbackground{pbg:\number\nofparbackgrounds}% +% \bgroup +% \advance\nofparbackgrounds\plusone +% \xdef\nextparbackground{pbg:\number\nofparbackgrounds}% +% \egroup + \xdef\nextparbackground{pbg:\number\numexpr\nofparbackgrounds+\plusone\relax}% still xdef ? + % todo : \synchonizepositionpage{b:\currentparbackground}{s:\currentparbackground}% + \setuptextbackground[#1][#2]% + \let\dodostarttextbackground\relax + \let\dodostoptextbackground \relax + \doif{\textbackgroundparameter\c!state}\v!start{\dopresettextbackground{#1}}% + \dodostarttextbackground} + +% todo \backgroundvariable\c!variant + +\def\dopresettextbackground#1% todo: \backgroundparameter + {\ExpandFirstAfter\processaction % \EFA niet echt nodig + [\textbackgroundparameter\c!location] + [ \v!text=>\let\dodostarttextbackground\dostarttextbackgroundtxt + \let\dodostoptextbackground \dostoptextbackgroundtxt, + \v!paragraph=>\let\dodostarttextbackground\dostarttextbackgroundpar + \let\dodostoptextbackground \dostoptextbackgroundpar, + \v!none=>\let\dodostarttextbackground\relax + \let\dodostoptextbackground \relax]% + \ifx\dodostarttextbackground\dostarttextbackgroundpar % untested + \ifnum\textbackgrounddepth>\plusone % new + \let\dodostarttextbackground\dostarttextbackgroundtxt + \let\dodostoptextbackground \dostoptextbackgroundtxt + \fi + \fi + \doifelse{\textbackgroundparameter\c!frame}\v!on + {\doifelse{\textbackgroundparameter\c!corner}\v!round + {\setvalue{\??td#1\c!frame}{2}} + {\setvalue{\??td#1\c!frame}{1}}} + {\setvalue{\??td#1\c!frame}{0}}% + \doifelse{\textbackgroundparameter\c!background}\v!color + {\setvalue{\??td#1\c!background}{1}} + {\setvalue{\??td#1\c!background}{0}}% + %\startpositionoverlay{\v!text\getvalue{\??td#1\c!level}}% + \startpositionoverlay{\textbackgroundoverlay{\textbackgroundparameter\c!level}}% + \expanded + {\setMPpositiongraphicrange % moet veel efficienter + {\btbanchor}% {b:\currentparbackground}% + {\etbanchor}% {e:\currentparbackground}% + {\textbackgroundparameter\c!method}% + {self=\currentparbackground, + mp=\textbackgroundparameter\c!mp, + gridtype=\textbackgroundparameter\c!alternative, + filltype=\textbackgroundparameter\c!background, + linetype=\textbackgroundparameter\c!frame, + dashtype=\textbackgroundparameter{dash}, % to be internationalized + gridcolor=\textbackgroundparameter\c!framecolor, + linecolor=\textbackgroundparameter\c!framecolor, + lineoffset=\textbackgroundparameter\c!frameoffset, + fillcolor=\textbackgroundparameter\c!backgroundcolor, + filloffset=\textbackgroundparameter\c!backgroundoffset, + gridwidth=\textbackgroundparameter\c!rulethickness, + gridshift=\textbackgroundparameter\c!voffset, + linewidth=\textbackgroundparameter\c!rulethickness, + lineradius=\textbackgroundparameter\c!radius}}% + \stoppositionoverlay} + +\def\stoptextbackground + {\dodostoptextbackground + \carryoverpar\egroup} + +\def\starttextbackgroundmanual + {\dostartattributes{\??td\currenttextbackground}\c!style\c!color\empty + \fpos\currentparbackground\ignorespaces} + +\def\stoptextbackgroundmanual + {\tpos\currentparbackground + \dostopattributes} + +\def\dostarttextbackgroundtxt + {\ifvmode \dontleavehmode \fi % was leavevmode, brrr + \dostartattributes{\??td\currenttextbackground}\c!style\c!color\empty + \fpos\currentparbackground\ignorespaces} + +\def\dostoptextbackgroundtxt + {\tpos\currentparbackground + \dostopattributes} + +% keep this simple one, it's used in prikkels and alike +% +% \def\dostarttextbackgroundpar +% {\endgraf % new +% \getvalue{\??td\currenttextbackground\c!before}% +% \noindent\fpos\currentparbackground\ignorespaces +% \bgroup +% \nobreak \vskip-\lineheight \nobreak +% \doassignsomeskip\getvalue{\??td\currenttextbackground\c!topoffset}\to\scratchskip +% \kern\scratchskip\nobreak +% \dosetleftskipadaption{\getvalue{\??td\currenttextbackground\c!leftoffset}}% +% \advance\leftskip\leftskipadaption +% \dosetleftskipadaption{\getvalue{\??td\currenttextbackground\c!rightoffset}}% +% \advance\rightskip\leftskipadaption +% \dostartattributes{\??td\currenttextbackground}\c!style\c!color{}% +% \nowhitespace +% \seteffectivehsize +% \par} +% +% \def\dostoptextbackgroundpar +% {\par +% \dostopattributes +% \doassignsomeskip\getvalue{\??td\currenttextbackground\c!bottomoffset}\to\scratchskip +% \kern\scratchskip\nobreak +% \nobreak \vskip-\lineheight \nobreak +% \nowhitespace +% \egroup +% \nobreak \noindent \strut \hfill \kern\zeropoint \tpos\currentparbackground +% \endgraf % new +% \getvalue{\??td\currenttextbackground\c!after}} + +\newskip\textbackgroundskip + +\def\dostarttextbackgroundpar + {\endgraf % new + \textbackgroundparameter\c!before + \noindent + \ifgridsnapping + \doassignsomeskip\textbackgroundparameter\c!topoffset\to\textbackgroundskip + \ifdim\textbackgroundskip>\zeropoint + \struttedbox{\hbox{\raise\textbackgroundskip\hbox{\fpos\currentparbackground}}}% + \else + \fpos\currentparbackground + \fi + \else + \fpos\currentparbackground + \fi + \bgroup + \endgraf % we need a vertical nobreak - 29/06/2004 + \nobreak \vskip-\lineheight \nobreak + \ifgridsnapping \else + \doassignsomeskip\textbackgroundparameter\c!topoffset\to\textbackgroundskip + \ifdim\textbackgroundskip>\zeropoint + \kern\textbackgroundskip\nobreak + \fi + \fi + \dosetleftskipadaption{\textbackgroundparameter\c!leftoffset}% + \advance\leftskip\leftskipadaption + \dosetleftskipadaption{\textbackgroundparameter\c!rightoffset}% + \advance\rightskip\leftskipadaption + % new + \dosetraggedcommand{\textbackgroundparameter\c!align}% + \raggedcommand + % + \dostartattributes{\??td\currenttextbackground}\c!style\c!color\empty + \nowhitespace +\nobreak % new per 23/04/2006 (else potential break when whitespace) + \seteffectivehsize + \doinhibitblank % \blank[\v!disable]% new + \par} + +\def\dostoptextbackgroundpar + {\par + \removelastskip % new + \dostopattributes + \doassignsomeskip\textbackgroundparameter\c!bottomoffset\to\textbackgroundskip + \ifdim\lastskip>\zeropoint + \advance\textbackgroundskip-\lastskip + \fi + \ifgridsnapping \else \ifdim\textbackgroundskip>\zeropoint + \kern\textbackgroundskip\nobreak + \fi \fi + \nobreak \vskip-\lineheight \nobreak + \nowhitespace + \egroup +\bgroup \forgeteverypar % NOT REALLY NEEDED, SAVES HASH/MEM + \nobreak \noindent \strut \hfill \kern\zeropoint + \doassignsomeskip\textbackgroundparameter\c!bottomoffset\to\textbackgroundskip + \ifgridsnapping % experimental, pascal (todo: topoffset in same way) + \ifdim\textbackgroundskip>\zeropoint + \struttedbox{\hbox{\lower\textbackgroundskip\hbox{\tpos\currentparbackground}}}% + \else + \tpos\currentparbackground + \fi + \else + \tpos\currentparbackground + \fi +\egroup + \endgraf % new + \textbackgroundparameter\c!after} + +\let\textparpages \!!zeropoint +\let\textparheight\!!zeropoint +\let\textparwidth \!!zeropoint + +\def\calculatetextpardimensions + {\docalculatetextpardimensions\btbanchor \etbanchor \MPparanchor} + +\def\calculatenexttextpardimensions + {\docalculatetextpardimensions\nextbtbanchor\nextetbanchor\relax} + +\def\docalculatetextpardimensions#1#2#3% todo: dimexpr + {\scratchcounter\MPp#2%\etbanchor + \advance\scratchcounter-\MPp#1%\btanchor + \edef\textparpages{\the\scratchcounter}% + \ifcase\scratchcounter + % one page + \scratchdimen \MPy#1%\btanchor + \advance\scratchdimen-\MPy#2%\etbanchor + \else + % two or more pages + \scratchdimen \MPy#1%\btanchor + \advance\scratchdimen-\MPy#2%\etbanchor + \advance\scratchdimen-\MPy\textanchor + \advance\scratchdimen \MPy\textanchor % - and then + ? + \advance\scratchdimen \MPh\textanchor\relax + \ifcase\scratchcounter>2 \ifnum\scratchcounter<5 + % more pages + \scratchdimen\textheight + \advance\scratchcounter \minusone + \multiply\scratchdimen \scratchcounter + \else + % keep'm small + \scratchdimen5\textheight + \fi \fi + \fi + \edef\textparheight{\the\scratchdimen}% + \ifcase\scratchcounter + % one page + \scratchdimen \MPx#2%\etbanchor + \advance\scratchdimen-\MPx#1%\btanchor + \else + % two or more pages / maybe also hang + \ifx#3\relax + \scratchdimen\makeupwidth % \textwidth + \else + \scratchdimen\MPw\MPparanchor + \advance\scratchdimen-\MPl\MPparanchor + \advance\scratchdimen-\MPr\MPparanchor + \fi + \fi + \edef\textparwidth{\the\scratchdimen}} + +\def\mintextparheight{4\lineheight} + +\def\dontsplitnexttextbackground % dangerous but useful + {\ifdim\pagetotal>\textheight \else + \ifdim\pagegoal=\maxdimen \else + \calculatenexttextpardimensions + % too tricky + % \scratchdimen=\textparheight + % \advance\scratchdimen\pagetotal\relax + % \ifdim\scratchdimen>\pagegoal + % \page + % \fi + \ifdim\textparheight>\zeropoint + \ifdim\textparheight>\mintextparheight\else + \page % option + \fi + \fi + \fi + \fi} + +\def\definetextbackground + {\dodoubleempty\dodefinetextbackground} + +\def\dodefinetextbackground[#1][#2]% + {\ifsecondargument % why ? + \copyparameters[\??td#1][\??td] + [\c!state,\c!location,\c!alternative,\c!mp,\c!method, + \c!background,\c!backgroundcolor,\c!corner,\c!level, + \c!backgroundoffset,\c!before,\c!after,\c!align,dash, % dash not yet internationalized + \c!radius,\c!frame,\c!framecolor,\c!rulethickness,\c!voffset,\c!frameoffset, + \c!leftoffset,\c!rightoffset,\c!topoffset,\c!bottomoffset]% + \getparameters[\??td#1][#2]% + \doifvalue{\??td#1\c!state}\v!start\checktextbackgrounds + \unexpanded\setvalue{#1}% + {\groupedcommand{\starttextbackground[#1]}{\stoptextbackground}}% + \setvalue{\e!start#1}{\starttextbackground[#1]}% + \setvalue{\e!stop #1}{\stoptextbackground}% + \fi} + +\def\setuptextbackground + {\dodoubleargument\dosetuptextbackground} + +\def\dosetuptextbackground[#1][#2]% + {\ifsecondargument + \doifelsenothing{#1} + {\dodosetuptextbackground{#2}\empty} + {\processcommalist[#1]{\dodosetuptextbackground{#2}}}% + \else + \dodosetuptextbackground{#1}\empty + \fi} + +\def\dodosetuptextbackground#1#2% + {\getparameters[\??td#2][#1]% + \def\currenttextbackground{#2}% + \doifvalue{\??td#2\c!state}\v!start\checktextbackgrounds} + +\let\currenttextbackground\empty + +\def\checktextbackgrounds + {\ifproductionrun + \enabletextarearegistration + \enablehiddenbackground + \fi} + +\setuptextbackground + [\c!mp=mpos:par:columnset, % buggy: mpos:par:shape + \c!method=mpos:par:columnset, % + \c!state=\v!start, + \c!location=\v!text, + \c!leftoffset=\!!zeropoint, % 1em, + \c!rightoffset=\textbackgroundparameter\c!leftoffset, + \c!topoffset=\!!zeropoint, % \v!medium, + \c!bottomoffset=\textbackgroundparameter\c!topoffset, + \c!level=-1, + \c!alternative=0, + \c!align=, + dash=0, % to be internationalized + \c!background=\v!color, + \c!backgroundcolor=lightgray, + \c!backgroundoffset=\!!zeropoint, + \c!corner=\v!rectangular, + \c!radius=.5\bodyfontsize, + \c!voffset=\!!zeropoint, + \c!frame=\v!on, + \c!framecolor=blue, + \c!rulethickness=\linewidth] + +%D As an example we define a grid background: + +\definetextbackground + [\v!grid] + [\c!state=\v!stop, + \c!location=\v!paragraph, + \c!frame=\v!off, + \c!framecolor=red, + \c!background=, + \c!alternative=1] + +\ifx\basegrid\undefined \else \letvalue\v!grid=\basegrid \fi + +% lelijk, aanpassen, opties + +\setupMPvariables + [mpos:connect] + [linecolor=red, + linewidth=1pt] + +\setupMPvariables + [mpos:encircle] + [fillcolor=lightgray, + filloffset=\!!zeropoint, + linecolor=blue, + linewidth=1pt] + +\startuseMPgraphic{mpos:common:ec} + path pa ; pair ca ; color lc ; numeric lw ; + lw := \MPvar{linewidth} ; + lc := \MPvar{linecolor} ; + initialize_box(\MPpos{\MPvar{self}}) ; + pa := pxy ; ca := cxy ; pa := boundingbox pa enlarged 2lw ; + pa := llcorner pa...lrcorner pa...urcorner pa...ulcorner pa...cycle ; + drawoptions (withpen pencircle scaled lw withcolor lc) ; +\stopuseMPgraphic + +\startMPpositiongraphic{mpos:encircle}{linecolor,fillcolor,linewidth} + \includeMPgraphic{mpos:common:ec} + fill pa withcolor \MPvar{fillcolor} ; draw pa ; + anchor_box(\MPanchor{\MPvar{self}}) ; +\stopMPpositiongraphic + +\startMPpositiongraphic{mpos:connect}{linecolor,linewidth} + path pb, pc ; pair cb, cc ; + \includeMPgraphic{mpos:common:ec} + initialize_box(\MPpos{\MPvar{to}}) ; + pb := pxy ; cb := cxy ; pb := boundingbox pb enlarged 2lw ; + pb := llcorner pb...lrcorner pb...urcorner pb...ulcorner pb...cycle ; + pc := ca {up} .. {down} cb ; + cc := (pc intersection_point pa) ; + if intersection_found : + pc := pc cutbefore cc ; + cc := (pc intersection_point pb) ; + if intersection_found : + pc := pc cutafter cc ; + drawarrow pc ; drawarrow reverse pc ; + fi ; + fi ; + anchor_box(\MPanchor{\MPvar{self}}) ; +\stopMPpositiongraphic + +%D \macros +%D {stackposdown, stackposup, stackposleft,stackposright} +%D +%D A non graphic example of the use of positioning, is to stack +%D text in for instance the margin. +%D +%D \stackposdown \inleft {some text}The text \type {some text} +%D goes into the left margin, and \stackposdown \inleft {some +%D more}\type {some more} as well. When they overlap, they +%D will not touch. +%D +%D Here we said \type {\stackposdown \inleft{some text}}. Instead +%D of \stackposleft \inleft {one}stacking \stackposleft \inleft +%D {two}vertically, one can stack horizontally by \stackposleft +%D \inleft {three}using \type {\stackposleft}. +%D +%D We can go in all four directions, using \type {\stackposdown}, +%D \type {\stackposup}, \type {\stackposleft} and \type +%D {\stackposright}. + +\def\stackposdistance{.5em} + +\newcount\currentautopos +\newcount\previousautopos + +\def\POSstackprefix{stack:} + +\def\dostackposbox#1#2% + {\dowithnextbox + {#2{\previousautopos\currentautopos + \global\advance\currentautopos\plusone + \edef\currentposition {\POSstackprefix\number\currentautopos}% + \edef\previousposition{\POSstackprefix\number\previousautopos}% + \hpos\currentposition{\doifoverlappingelse\currentposition\previousposition{#1}{\flushnextbox}}}}% + \hbox} + +\def\stackposup {\dostackposbox{\raise\lineheight\flushnextbox}} +\def\stackposdown {\dostackposbox{\lower\lineheight\flushnextbox}} +\def\stackposleft {\dostackposbox{\copy\nextbox\hskip\nextboxwd\hskip\stackposdistance}} +\def\stackposright{\dostackposbox{\hskip\stackposdistance\hskip\nextboxwd\flushnextbox}} + +%D \macros +%D {stackeddown} +%D +%D However, a better implementation is possible with the +%D following macro. We now have an extra key \type {stack} for +%D margin settings. When set to \type {yes}, this macro comes +%D into action. + +% Because there can be many stacked items in a line and successive lines, we +% play dirty and adapt the position and height of the current node so that +% this becomes visible to a next pass. +% +% \startbuffer +% \inleft {test 1} test 1 \inleft {test 2} test 2 \endgraf +% \inleft {test 3} test 3 +% \stopbuffer +% \getbuffer \typebuffer \flushstatus \page +% +% \startbuffer +% \inleft {test 1} test 1 \inleft {test 2} test 2 \inleft {test 3} test 3 \endgraf +% \inleft {test 4} test 4 +% \stopbuffer +% \getbuffer \typebuffer \flushstatus \page +% +% \startbuffer +% \inleft {test 1} test 1 \endgraf +% \inleft {test 2} test 2 \endgraf +% \inleft {test 3} test 3 +% \stopbuffer +% \getbuffer \typebuffer \flushstatus \page +% +% \startbuffer +% \inleft {test 1\\test 1} test 1 \inleft {test 2} test 2 \endgraf +% \inleft {test 3} test 3 +% \stopbuffer +% \getbuffer \typebuffer \flushstatus \page +% +% \startbuffer +% \inleft {test 1\\test 1\\test 1\\test 1\\test 1} test 1 \endgraf +% test 2 \endgraf +% \inleft {test 3} test 3 +% \stopbuffer +% \getbuffer \typebuffer \flushstatus \page +% +% \startbuffer +% \inleft{test 1} test \inleft{test 2} test \inleft{test 3\\test 3} test +% \stopbuffer +% \getbuffer \typebuffer \flushstatus \page +% +% \startbuffer +% \inleft{test 1\\test 1\\test 1} test \inleft{test 2\\test 2} test \inleft{test 3\\test 3\\test 3} test \endgraf +% \inleft{test 1\\test 1\\test 1} test \inleft{test 2\\test 2} test \inleft{test 3\\test 3\\test 3} test +% \stopbuffer +% \getbuffer \typebuffer \flushstatus \page + +\newdimen\laststackvmove % use \scratchdimenone instead of skip + +\def\stackeddown + {\bgroup + % this macro assumes a few things and is meant to work for margin notes + \dowithnextbox + {\global\advance\currentautopos\plusone + \global\laststackvmove\zeropoint + \hpos{\POSstackprefix\number\currentautopos} + {\edef\next + {\nextboxht\the\nextboxht + \nextboxdp\the\nextboxdp + \nextboxwd\the\nextboxwd}% + \previousautopos\currentautopos + \scratchdimen\zeropoint + \scratchcounter\zerocount + \doloop + {\advance\previousautopos\minusone + \edef\currentposition {\POSstackprefix\number\currentautopos}% + \edef\previousposition{\POSstackprefix\number\previousautopos}% + \ifnum\MPp\currentposition=\MPp\previousposition\relax + %\registerstatus{doing \number\currentautopos/\number\previousautopos}% + \doifoverlappingelse\currentposition\previousposition + {\scratchskip\dimexpr + \MPy\currentposition + -\MPy\previousposition + -\MPd\currentposition % untested + +\MPd\previousposition % untested + +\MPh\currentposition + \relax\relax % second relax realy needed, forgotten while dimexpressing + % todo: also take depth into account + \ifdim\scratchskip<\scratchdimen + %\registerstatus{no \the\scratchskip}% + \else + %\registerstatus{yes \the\scratchskip}% + \scratchdimen\scratchskip + \fi}% + \donothing % {\registerstatus{next}}% + \ifnum\previousautopos<\zerocount\exitloop\fi + \else + \exitloop + \fi}% + \ifdim\scratchdimen=\zeropoint \else + \bgroup + \edef\currentposition{\POSstackprefix\number\currentautopos}% + \scratchskip\scratchdimen + \advance\scratchskip\MPh\currentposition + \scratchdimen-\scratchdimen + \advance\scratchdimen\MPy\currentposition + %\registerstatus{old \number\currentautopos: \MPy\currentposition/\MPh\currentposition}% + \expanded{\replacepospxywhd + {\currentposition}{\MPp\currentposition}{\MPx\currentposition}{\the\scratchdimen}% + {\MPw\currentposition}{\the\scratchskip}{\MPd\currentposition}}% + %\registerstatus{new \number\currentautopos: \MPy\currentposition/\MPh\currentposition}% + \egroup + \global\laststackvmove\scratchdimen % new + \setbox\nextbox\iftracepositions\@EA\ruledhbox\else\@EA\hbox\fi + {\lower\scratchdimen\flushnextbox}% + \next + %\registerstatus{\strut}% + \fi + \flushnextbox}% + \egroup}} + +%D The next hack make sure that margin texts near faulty +%D strutted lines are handled ok. + +\newif\ifrepositionmarginbox \repositionmarginboxtrue + +\newcount\currentmarginpos + +\def\dopositionmarginbox#1% + {\bgroup + \ifrepositionmarginbox + \global\advance\currentmarginpos\plusone + %\setposition{\s!margin:\number\currentmarginpos}% not always + \ifcase\marginrepositionmethod + % nothing + \or + % nothing + \or + % stack / page check yet untested + \setposition{\s!margin:\number\currentmarginpos}% + \scratchdimen\MPy{\s!margin:\number\currentmarginpos}% + \global\advance\currentmarginpos\plusone + \advance\scratchdimen -\MPy{\s!margin:\number\currentmarginpos}% + \advance\scratchdimen -\strutdp + % new but bugged + % \setbox#1\hbox + % {\hskip-\MPx{\s!margin:\number\currentmarginpos}% + % \hskip\MPx{head:\realfolio}% + % \box#1}% + % so far + \setbox#1\hbox + {\setposition{\s!margin:\number\currentmarginpos}% + \raise\scratchdimen\box#1}% + \or + % move up + \setposition{\s!margin:\number\currentmarginpos}% + \ifnum\MPp{p:\number\parposcounter}=\MPp{\s!margin:\number\currentmarginpos}\relax + \scratchdimen\dimexpr\MPy{p:\number\parposcounter}-\MPy{\s!margin:\number\currentmarginpos}\relax + \expanded{\setbox#1\hbox{\raise\scratchdimen\box#1}\ht#1\the\ht#1\dp#1\the\dp#1}% + \fi + \or + % move up, assume end of par + \setposition{\s!margin:\number\currentmarginpos}% + \ifnum\MPp{p:\number\parposcounter}=\MPp{\s!margin:\number\currentmarginpos}\relax + \getnoflines\margincontentheight + \advance\noflines\minusone + \scratchdimen\noflines\lineheight + \else + \scratchdimen\dimexpr\MPy{p:\number\parposcounter}-\MPy{\s!margin:\number\currentmarginpos}\relax + \fi + \expanded{\setbox#1\hbox{\raise\scratchdimen\box#1}\ht#1\the\ht#1\dp#1\the\dp#1}% + \fi + \dp#1\zeropoint + \ht#1\zeropoint + \fi + \graphicvadjust{\box#1}% + \egroup} + +\chardef\marginrepositionmethod\plusone % sidemethod +\chardef\margincontentmethod \plusthree % textmethod % beware: 1 = old method +\chardef\marginpagecheckmethod \plusone % splitmethod + +%D For a right menu, a sequence of calls to \type +%D {right_menu_button} is generated. +%D +%D \starttyping +%D right_menu_button (n, p, s=0/1/2, x, y, w, h, d) ; +%D \stoptyping +%D +%D Here, n is the number of the button, s a status variable, +%D while the rest is positional info. The status variable is +%D 0, 1 or~2: not found, found and found but current page. + +% 0=not found 1=found 2=current page + +% geen leeg + +\newtoks\MPmenutoks + +\def\MPmenubuttons#1{\the\MPmenutoks} + +\appendtoks \global\MPmenutoks\emptytoks \to \everyshipout + +% 0=notfound 1=found 2=currentpage + +\def\do@@amposition#1#2#3% + {\doifelsevalue{\??am#1\c!position}\v!yes + {\doglobal\increment\currentamposition + \doifnumberelse{#2} + {\docheckrealreferencepage{#2}% + \global\chardef\currentamrealpage\ifrealreferencepage2\else1\fi} + {\doifreferencefoundelse{#2} + {\global\chardef\currentamrealpage\ifrealreferencepage2\else1\fi} + {\global\chardef\currentamrealpage0}}% % not found + \expanded + {\doglobal\noexpand\appendtoks + #1_menu_button(\currentamposition,\the\currentamrealpage,\MPpos{#1:\currentamposition}) ; + \to \MPmenutoks}% + \hpos{#1:\currentamposition}{#3}} + {#3}} + +\def\do@@ammenuposition#1% + {\ifnum\currentamposition>0 + \dowithnextbox{\hpos{menu:#1:\realfolio}{\flushnextbox}}\hbox + % \hpos{menu:#1:\realfolio} % also ok if we skip over fi + \fi} + +%D \macros +%D {GFC, GTC, GSC} +%D +%D The next macros extend tables and tabulation with +%D backgrounds and position related features. Areas are +%D specified with symbolic names, and symbolic references to +%D the graphics involved. Each table has its own namespace. + +\newcount\noftabpositions +\newtoks \posXCtoks + +\def\tbPOSprefix + {tbp:\number\noftabpositions:} + +\def\tablepos + {\scratchtoks\posXCtoks + \global\posXCtoks\emptytoks + \the\scratchtoks} + +\let\tabulatepos\tablepos + +\def\dodododoGSC[#1:#2]% + {\remappositionframed{#2}{\tbPOSprefix#1}% + \bpos{\tbPOSprefix#1}% + \doglobal\appendtoks\@EA\epos\@EA{\tbPOSprefix#1}\to\posXCtoks} + +\def\dododoGSC[#1:#2:#3]% + {\doglobal\appendtoks\dodododoGSC[#1:#2]\to\posXCtoks\NC} + +\def\dodoGSC[#1]% + {\def\docommand##1{\dododoGSC[##1:##1]}% + \processcommalist[#1]\docommand} + +\def\dodododoGFC[#1:#2:#3]% + {\remappositionframed{#2}{\tbPOSprefix#1}% + \bpos{\tbPOSprefix#1}} + +\def\dododoGFC[#1]% + {\def\docommand##1{\dodododoGFC[##1:##1]}% + \processcommalist[#1]\docommand} + +\def\dodoGFC[#1]% + {\doglobal\appendtoks\dododoGFC[#1]\to\posXCtoks\NC} + +\def\dododododoGTC[#1:#2]% + {\epos{\tbPOSprefix#1}} + +\def\dodododoGTC[#1]% + {\def\docommand##1{\dododododoGTC[##1:##1]}% + \processcommalist[#1]\docommand} + +\def\dododoGTC[#1]% + {\doglobal\appendtoks\dodododoGTC[#1]\to\posXCtoks} + +\def\dodoGTC[#1]% + {\doglobal\appendtoks\dododoGTC[#1]\to\posXCtoks\NC} + +\def\dodododoXC[#1#2]% + {\if#1>\dodoGFC [#2:#2]\else + \if#1+\dodoGFC [#2:#2]\else + \if#1<\dodoGTC [#2:#2]\else + \if#1-\dodoGTC [#2:#2]\else + \if#1=\dodoGSC [#2:#2]\else + \dodoGSC[#1#2:#1#2]\fi\fi\fi\fi\fi} + +\def\dododoXC#1% + {\dodododoXC[#1]} + +\def\dodoXC[#1]% + {{\let\NC\relax\processcommalist[#1]\dododoXC}} + +\def\doGSC[#1]{\iffirstargument\dodoGSC[#1]\else\expandafter\NC\fi} +\def\doGFC[#1]{\iffirstargument\dodoGFC[#1]\else\expandafter\NC\fi} +\def\doGTC[#1]{\iffirstargument\dodoGTC[#1]\else\expandafter\NC\fi} +\def\doXC [#1]{\iffirstargument\dodoXC [#1]\else\expandafter\fi\NC} + +\def\tbGSC{\dosingleempty\doGSC} +\def\tbGFC{\dosingleempty\doGFC} +\def\tbGTC{\dosingleempty\doGTC} +\def\tbXC {\dosingleempty\doXC } + +%D The amount of code to support tables and tabulation is +%D rather minimalistic. + +\let\tabulatepos\tablepos + +\def\tabulatenormalpos + {\hss\tabulatepos\hss} + +\def\tabulateequalpos + {\setbox\scratchbox\hbox{\tabulateEQ}% + \hbox to \wd\scratchbox{\hss\kern\zeropoint\tabulatepos\hss}% + \hskip-\wd\scratchbox + \box\scratchbox} + +\def\tabulatenormalcolumn#1% overloaded + {&\iftabulateequal\tabulateequalpos\else\tabulatenormalpos\fi + &\global\chardef\tabulatetype#1&} + +\def\tabulateequalcolumn#1% overloaded + {&\tabulateequalpos + &\global\chardef\tabulatetype#1&} + +\appendtoks + \global\advance\noftabpositions\plusone +\to \everytabulate + +%D In order to prevent potential clashes with abbreviations, +%D postpone the mapping. + +\appendtoks + \let\GSC\tbGSC \let\GFC\tbGFC \let\GTC\tbGTC \let\XC\tbXC +\to \everytabulate + +%D \macros +%D {definepositionframed} +%D +%D The next example show how to provide backgrounds to table +%D cells. First we define some framed backgrounds. +%D +%D \startbuffer +%D \definepositionframed[x][background=color,backgroundcolor=red] +%D \definepositionframed[y][background=color,backgroundcolor=green] +%D \definepositionframed[z][background=color,backgroundcolor=blue] +%D \stopbuffer +%D +%D \typebuffer +%D +%D % \getbuffer +%D +%D \startbuffer +%D \starttabulate[|c|c|c|] +%D \GFC[f:x] this is a small \NC table \NC in which we \NC \FR +%D \NC will demonstrate \GFC[g:z] that this \GTC[g] positioning \NC \MR +%D \GSC[e:y] mechanism also \GTC[f] works quite well \NC in tables \NC \LR +%D \stoptabulate +%D \stopbuffer +%D +%D The table itself defines three areas (a, b and~c) using +%D these frames. +%D +%D \typebuffer +%D % \getbuffer +%D +%D Tables (based on \TABLE) are supported by: + +\def\normalTABLEsimplebar {\unskip\!ttRightGlue&\tablepos&} % | +\def\normalTABLEcomplexbar{\unskip\!ttRightGlue&\omit\tablepos\!ttAlternateVrule} % \| +\def\normalTABLEquote {\unskip\!ttRightGlue&\omit\tablepos&} % " + +\appendtoks + \global\advance\noftabpositions\plusone +\to \everytable + +%D Since we don't want nameclashes: + +\appendtoks + \let\GSC\tbGSC \let\GFC\tbGFC \let\GTC\tbGTC \let\XC\tbXC +\to \everytable + +%D In the previous example, we could have provided an overlay to +%D the framed definition. A more direct approach is demonstrated +%D below: +%D +%D \startbuffer +%D \def\cw#1{\color[white]{#1}} +%D +%D \startMPpositiongraphic{tableshade} +%D initialize_area(\MPpos{\MPvar{from}},\MPpos{\MPvar{to}}) ; +%D color c ; c := \MPvar{color} ; +%D linear_shade(pxy,0,.4c,.9c) ; +%D anchor_area(\MPanchor{\MPvar{from}}) ; +%D \stopMPpositiongraphic +%D +%D \setMPpositiongraphic{b:x}{tableshade}{from=b:x,to=e:x,color=red} +%D \setMPpositiongraphic{b:y}{tableshade}{from=b:y,to=e:y,color=green} +%D \setMPpositiongraphic{b:z}{tableshade}{from=b:z,to=e:z,color=blue} +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D The definition of the table looks about the same as the +%D previous one: +%D +%D \startbuffer +%D \starttable[|c|c|c|] +%D \GFC[b:z] \cw{this is a small} \NC \cw{table} \NC in which we \NC \FR +%D \NC \cw{will demonstrate} \GFC[c:y] \cw{that this} \GTC[c] \cw{positioning} \NC \MR +%D \GSC[a:x] \cw{mechanism also} \GTC[b] \cw{works quite well} \NC in tables \NC \LR +%D \stoptable +%D \stopbuffer +%D +%D \typebuffer +%D +%D \getbuffer + +% \definepositionframed[w][background=color,backgroundcolor=yellow] +% \definepositionframed[x][background=color,backgroundcolor=red] +% \definepositionframed[y][background=color,backgroundcolor=green] +% \definepositionframed[z][background=color,backgroundcolor=blue] +% +% \starttabulate[|c|c|c|] +% \NC this is a small \NC table \NC in which we \NC \FR +% \NC will demonstrate \NC that this \NC positioning \NC \MR +% \NC mechanism also \NC works quite well \NC in tables \NC \LR +% \stoptabulate +% +% \starttabulate[|c|c|c|] +% \GFC[f:x] this is a small \GTC table \NC in which we \NC \FR +% \NC will demonstrate \GFC[g:z] that this \GTC[g] positioning \NC \MR +% \GSC[e:y] mechanism also \GTC[f] works quite well \NC in tables \NC \LR +% \stoptabulate +% +% \starttabulate[|c|c|c|] +% \GFC[f:x,d:w] this is a small \GTC[d] table \NC in which we \NC \FR +% \NC will demonstrate \GFC[g:z] that this \GTC[g] positioning \NC \MR +% \GSC[e:y] mechanism also \GTC[f] works quite well \NC in tables \NC \LR +% \stoptabulate +% +% \starttabulate[|c|c|c|] +% \XC[+f:x] this is a small \XC table \NC in which we \NC \FR +% \NC will demonstrate \XC[+g:z] that this \XC[-g] positioning \NC \MR +% \XC[=e:y] mechanism also \XC[-f] works quite well \NC in tables \NC \LR +% \stoptabulate +% +% \starttabulate[|c|c|c|] +% \XC[+f:x,+d:w] this is a small \XC[-d] table \NC in which we \NC \FR +% \NC will demonstrate \XC[+g:z] that this \XC[-g] positioning \NC \MR +% \XC[=e:y] mechanism also \XC[-f] works quite well \NC in tables \NC \LR +% \stoptabulate + +% evt [b:x] +% +% \definepositionframed[x][background=color,fillcolor=red] +% \definepositionframed[y][background=color,fillcolor=green] +% \definepositionframed[z][background=color,fillcolor=blue] + +\def\remappositionframed#1#2% from to + {\copyposition{b:#1}{b:#2}% + \copyposition{e:#1}{e:#2}% + \dosetpositionaction{b:#2}{\dopositionaction{b:#1}}} + +\def\definepositionframed + {\dodoubleargument\dodefinepositionframed} + +\def\dodefinepositionframed[#1][#2]% + {\dosetpositionaction{b:#1}{\dopositionframed[#1][#2]}} + +\def\positionframed + {\dodoubleempty\dopositionframed} + +\def\dopositionframed[#1][#2]% + {\bgroup + \setbox\scratchbox\hbox + {\dimen0=\MPx{e:#1}% + \advance\dimen0 -\MPx{b:#1}% + \dimen2=\MPy{b:#1}% + \advance\dimen2 -\MPy{e:#1}% + \advance\dimen2 \MPd{e:#1}% + \lower\dimen2\hbox + {\advance\dimen2 \MPh{b:#1}% + \framed + [\c!width=\dimen0,\c!height=\dimen2, + \c!offset=\v!overlay,#2]{}}}% + \smashedbox\scratchbox + \egroup} + +% \def\sethdistances#1% +% {\hbox{\lpos{ml:#1}\hpos{mh:#1}{\strut}\rpos{mr:#1}}} +% +% \def\gethdistances#1% +% {\scratchdimen\MPx{mh:#1}% +% \advance\scratchdimen -\MPx{ml#1}% +% \edef\lefthdistance{\the\scratchdimen}% +% \scratchdimen\MPx{mr:#1}% +% \advance\scratchdimen -\MPx{mh:#1}% +% \edef\righthdistance{\the\scratchdimen}} + +\protect \endinput + +% todo 1: shift down option + +% \startuseMPgraphic{mpos:par:columnset} +% \iftracepositions show_multi_pars \else draw_multi_pars \fi ; +% path p ; p := boundingbox currentpicture ; +% currentpicture := currentpicture shifted (0,-StrutDepth/2) ; +% setbounds currentpicture to p ; +% \stopuseMPgraphic + +\definetextbackground[underline] [location=text,alternative=1,background=,frame=off] +\definetextbackground[overstrike] [location=text,alternative=2,background=,frame=off] +\definetextbackground[exlines] [location=text,alternative=3,background=,frame=off] +\definetextbackground[strikethrough][location=text,alternative=4,background=,frame=off] + +\definestartstop [underline] + [before={\starttextbackground[underline]}, + after=\stoptextbackground] + +\definestartstop + [overstrike] + [before={\starttextbackground[overstrike]}, + after=\stoptextbackground] + +\definestartstop + [exlines] + [before={\starttextbackground[exlines]}, + after=\stoptextbackground] + +\definestartstop + [strikethrough] + [before={\starttextbackground[strikethrough]}, + after=\stoptextbackground] + +\definetextbackground + [sideline] + [mp=mpos:par:sideline, + location=paragraph, + framecolor=red, + frameoffset=5mm] + +\definestartstop [sideline] + [before={\starttextbackground[sideline]}, + after=\stoptextbackground] + +\starttext + \startunderline \input tufte \stopunderline \blank + \startoverstrike \input tufte \stopoverstrike \blank + \startexlines \input tufte \stopexlines \blank + \startstrikethrough \input tufte \stopstrikethrough \blank + \startsideline \input tufte \stopsideline \blank +\stoptext diff --git a/tex/context/base/anch-pgr.mkiv b/tex/context/base/anch-pgr.mkiv new file mode 100644 index 000000000..248b9ca5e --- /dev/null +++ b/tex/context/base/anch-pgr.mkiv @@ -0,0 +1,1727 @@ +%D \module +%D [ file=anch-pgr, % split off core-pos +%D version=1999.08.01, +%D title=\CONTEXT\ Anchoring Macros, +%D subtitle=Positioning Graphics, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 Anchoring Macros / 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 +%D is hooked into the page building routine. + +%D I will speed up this module when I have a proper torture +%D test file. + +\unprotect + +% in the future, the depth of tail will reflect page depth + +\ifx\textheight\undefined \def\textheight{\vsize} \fi + +%D The next macros so some housekeeping. + +\def\pageanchor{page:0} % for the moment only one pagesize +\def\textanchor{text:\the\realpageno} +\def\headanchor{head:\the\realpageno} % virtual position +\def\tailanchor{tail:\the\realpageno} % virtual position + +%D Anchors: + +\def\dopresetpositionanchors % also mkii + {\bgroup + \!!dimena\ifdim\topskip>\strutht\topskip\else\strutht\fi + \!!dimenb\dimexpr\MPy\textanchor+\MPh\textanchor-\!!dimena\relax + \!!dimenc\dimexpr\MPy\textanchor+\strutdp\relax + \!!dimend\MPx\textanchor + \!!dimene\MPw\textanchor + \replacepospxywhd\headanchor\realfolio\!!dimend\!!dimenb\!!dimene\!!dimena\strutdp + \replacepospxywhd\tailanchor\realfolio\!!dimend\!!dimenc\!!dimene\strutht \strutdp + \egroup} + +\def\presetpositionanchors% compatibility hack (still needed?) + {\ifpositioning + \dopresetpositionanchors + \fi} + +%D The first version of this module implemented head and tail +%D anchors. Currently we stick to just one anchor and derive +%D the head and tail anchors from this one. + +\def\showanchor#1% + {\expanded{\writestatus{#1} + {\MPp{#1}\string|\MPx{#1}\string|\MPy{#1}\string|% + \MPw{#1}\string|\MPh{#1}\string|\MPd{#1}}}} + +%D We set these anchors before and after each page. + +\appendtoks \presetpositionanchors \to \beforeeverypage +\appendtoks \presetpositionanchors \to \aftereverypage + +% todo: change with each page size change + +\def\registerpageposition#1% this one is flushed first ! + {\ifpositioning\ifcase\realpageno\or + \ifdim\printpaperheight=\paperheight\else + \ifdim\printpaperwidth=\paperwidth\else + \setbox#1\hbox{\hpos\pageanchor{\box#1}}% + \fi + \fi + \fi\fi} + +\unexpanded\def\placepositionanchors % todo : depth pagebox + {\ifpositioning + \setbox\scratchbox\vbox to \textheight + {\simpletopskipcorrection + \hbox{\strut\dopositionaction\headanchor}% + \vfill + \hbox{\strut\dopositionaction\tailanchor}}% + \dp\scratchbox\zeropoint + \wd\scratchbox\makeupwidth % not \zeropoint, else wrong text backgrounds + \hpos\textanchor{\box\scratchbox}% + \else + \vskip\textheight + \fi} + +%D \macros +%D {positionoverlay,startpositionoverlay} +%D +%D As long as we're dealing with graphics it makes much sense +%D to use the available overlay mechanism. For this purpose, we +%D define some dedicated overlay extensions. +%D +%D \startbuffer[sample] +%D \defineoverlay [sample] [\positionoverlay{sample}] +%D +%D \startpositionoverlay{sample} +%D \setMPpositiongraphic{A-1}{connectcenter}{from=A-1,to=A-2} +%D \stoppositionoverlay +%D \stopbuffer +%D +%D \typebuffer[sample] +%D +%D \startbuffer[graphic] +%D \startMPpositiongraphic{connectcenter} +%D path pa, pb ; pair ca, cb ; +%D initialize_box(\MPpos{\MPvar{from}}) ; pa := pxy ; ca := cxy ; +%D initialize_box(\MPpos{\MPvar{to}}) ; pb := pxy ; cb := cxy ; +%D draw pa withcolor red ; +%D draw pb withcolor red ; +%D draw ca -- cb withcolor blue ; +%D anchor_box(\MPanchor{\MPvar{from}}) ; +%D \stopMPpositiongraphic +%D \stopbuffer +%D +%D We can best demonstrate this in an example, say: +%D +%D \startbuffer[text] +%D \framed +%D [backgroundachtergrond=sample,align=middle,width=7cm] +%D {We want to connect \hpos {A-1} {this} word with its +%D grammatical cousin \hpos {A-2} {that}.} +%D \stopbuffer +%D +%D \typebuffer[text] +%D +%D \startlinecorrection +%D %\getbuffer[graphic,sample,text] +%D \stoplinecorrection +%D +%D The graphic is defined in the following way, using some +%D macros defined in an auxiliary \METAPOST\ module that is +%D preloaded. +%D +%D \typebuffer[graphic] + +\def\MPanchoridentifier{mpa} % {mp-anchor} +\def\MPoverlayposprefix{MO::} + +% obsolete and wrong anyway +% +% \long\unexpanded\def\defineMPpositiongraphic#1% +% {\long\setvalue{\MPoverlayposprefix#1}} + +%D The rest of the definitions concerning such overlays may +%D look complicated, + +\let\currentpositionoverlay\empty + +%D Position actions are automatically executed when a position +%D is set. + +\let\MPanchornumber\realfolio + +\def\positionoverlay#1% the test prevents too many redundant positions + {\ifpositioning % in (not used) text* position layers + \vbox to \overlayheight + {\doifpositionactionelse{#1::\MPanchoridentifier}% + {\edef\MPanchorid{#1::\MPanchoridentifier:\MPanchornumber}% + \edef\MPanchor##1{\MPpos{\MPanchorid}}% + \the\everyinsertpositionaction + \copyposition{#1::\MPanchoridentifier}{#1::\MPanchoridentifier:\MPanchornumber}% + \hpos + {#1::\MPanchoridentifier:\MPanchornumber}% + % this is ok + %{\hbox to \overlaywidth{\dopositionaction{#1::\MPanchoridentifier}\hss}}}% + % but this one prevents cyclic runs due to + % rounding errors + {\setbox\scratchbox\hbox to \overlaywidth{\dopositionaction{#1::\MPanchoridentifier}\hss}% + \ht\scratchbox\overlayheight + \dp\scratchbox\zeropoint + \box\scratchbox}}% + {\hbox to \overlaywidth{\hss}}% + \vfill}% + \fi} + +\unexpanded\def\startpositionoverlay#1% + {\iftrialtypesetting % we don't want redundant entries in the list + \@EA\gobbleuntil\@EA\stoppositionoverlay + \else + \def\currentpositionoverlay{#1}% + \fi} + +\unexpanded\def\stoppositionoverlay + {\let\currentpositionoverlay\empty} + +\def\resetpositionoverlay#1% + {\dosetpositionaction{#1::\MPanchoridentifier::}{}} + +%D Here the complication has to do with collecting actions +%D for later execution. This collection is especially handy +%D when we want to move actions to a specific layer. +%D Such series of actions are stored in a macro (the one +%D with the funny \type {++}) which is cleaned up after each +%D invocation. + +\newtoks\everycleanpositionaction +\newtoks\everyinsertpositionaction + +\def\cleanuppositionaction#1% not in trialtypesetting + {\ifcsname\POSactionprefix#1++\endcsname + \the\everycleanpositionaction + \iflocalpositioning + \letgvalue{\POSactionprefix#1++}\empty + \else + \setxvalue{\POSactionprefix#1++}{\getvalue{\POSactionprefix#1++}}% + \fi + \fi} + +% \def\cleanuppositionaction#1% not in trialtypesetting +% {\ifcsname\POSactionprefix#1++\endcsname +% \the\everycleanpositionaction +% \iflocalpositioning +% \global\expandafter\let\csname\POSactionprefix#1++\endcsname\empty +% \else +% \global\expandafter\let\csname\POSactionprefix#1++\expandafter\endcsname\csname\POSactionprefix#1++\endcsname +% \fi +% \fi} + +\def\handlepositionaction#1\with#2\on#3% + {\bgroup + \ifx\currentpositionoverlay\empty + \edef\!!stringa{#3}% no layer, just pos itself as anchor + \else + \edef\!!stringa{\currentpositionoverlay::\MPanchoridentifier}% + \fi + \edef\!!stringc{\POSactionprefix\!!stringa++}% + \expanded{\dosetpositionaction{\!!stringa}{\noexpand\getvalue{\!!stringc}}}% + \global\let#1\relax + \edef\!!stringb{\executeifdefined\!!stringc\empty}% + \setxvalue\!!stringc{\!!stringb#1#2}% + \egroup} + +%D The indirectness enables us redefine macros for special +%D purposes, like a cleanup. + +\def\handlepositionboxes#1#2#3% + {\handlepositionaction\dohandlepositionboxes\with{#1}{#2}{#3}\on{#2}} + +\def\doinsertpositionboxes#1#2#3% pos tag setups + {\ifnum\MPp{#1}=\realpageno\relax % can be sped up + \executeifdefined{\MPoverlayposprefix#1}\gobblethreearguments{#1}{#2}{#3}% + \fi} + +\appendtoks + \let\dohandlepositionboxes\doinsertpositionboxes % was handle ? +\to \everyinsertpositionaction + +\def\docleanpositionboxes#1#2#3% pos tag setups + {\ifnum\MPp{#1}<\realpageno \else + \noexpand \dohandlepositionboxes{#1}{#2}{#3}% reinsert + \fi} + +\appendtoks + \let\dohandlepositionboxes\docleanpositionboxes +\to \everycleanpositionaction + +%D A position graphic is a normal (non||reused) \METAPOST\ +%D graphic, used immediately, with zero dimensions, so that a +%D sequence of them does not harm. + +\newbox\positiongraphicbox + +\def\startMPpositiongraphic % id setups + {\dodoublegroupempty\dostartMPpositiongraphic} + +\long\def\dostartMPpositiongraphic#1#2#3\stopMPpositiongraphic + {\long\setgvalue{MPG:#1}% tag list mpcode + {\useMPpositiongraphic{#1}{#2}{#3}}} + +\let\stopMPpositiongraphic\relax + +\def\prepareMPpositionvariables + {\ifcsname\@@meta self\endcsname\else\setvalue{\@@meta self}{\currentposition}\fi + \ifcsname\@@meta from\endcsname\else\setvalue{\@@meta from}{\currentposition}\fi} + +\long\def\useMPpositiongraphic#1#2#3% + {\bgroup + \prepareMPvariables{#2}% + \prepareMPpositionvariables + \enableincludeMPgraphics + \startMPcode#3\stopMPcode + \egroup} + +% Now we need a adapted action handler: + +\def\dopositionaction#1% test saves hash entry in etex + {\ifcsname\POSactionprefix#1::\endcsname + \dodopositionaction{#1}% + \fi} + +\def\dodopositionaction#1% + {\ifnum\MPp{#1}>\zerocount % new + \bgroup + \setbox\scratchbox\hbox + \bgroup + \traceposstring\clap\red{<#1>}% + \the\everyinsertpositionaction + \the\everypositionaction + \csname\POSactionprefix#1::\endcsname + \cleanuppositionaction{#1}% + \egroup % smashed is really needed else + \smashedbox\scratchbox % we get problems with too big + \egroup % overlays (s-pre-0x.tex) + \else + % shouldn't happen too often + \traceposstring\clap\cyan{<#1>}% + \fi} + +\def\MPpositiongraphic + {\dodoublegroupempty\doMPpositiongraphic} + +\def\doMPpositiongraphic#1#2% tag setups + {\bgroup + \def\@@meta{#1:}% + \setupMPvariables[#2]% + \prepareMPpositionvariables + \MPshiftdrawingtrue + \def\doMPpositiongraphic##1##2% + {{% new, see (techniek) + \def\@@meta{##1:}% + \setupMPvariables[#2,##2]% + \prepareMPpositionvariables + % and needed + \getvalue{MPG:##1}}}% temp hack + \setbox\positiongraphicbox\hbox + {\ignorespaces + \executeifdefined{MPM:#1}{\executeifdefined{MPG:#1}\donothing}% + \removelastspace}% + \smashbox\positiongraphicbox + \box\positiongraphicbox + \egroup} + +\long\def\startMPpositionmethod#1#2\stopMPpositionmethod + {\long\setgvalue{MPM:#1}{#2}} % todo: var list here + +\let\stopMPpositionmethod\relax + +%D Simple one position graphics. + +\def\setMPpositiongraphic + {\dotriplegroupempty\dosetMPpositiongraphic} + +\def\dosetMPpositiongraphic#1#2#3% pos tag vars + {\ifx\currentpositionoverlay\empty + \dosetpositionaction{#1}{\MPpositiongraphic{#2}{#3}}% + \else % silly can be one + \handlepositiongraphics{#1}{#2}{#3}% + \fi} + +\def\handlepositiongraphics#1#2#3% combine with boxes + {\handlepositionaction\dohandleMPpositiongraphic\with{#1}{#2}{#3}\on{#2}} + +\def\doinsertMPpositiongraphic#1#2#3% pos tag setups + {\ifnum\MPp{#1}=\realpageno\relax % extra saveguard + \def\currentposition{#1}\MPpositiongraphic{#2}{#3}% + \fi} + +\appendtoks + \let\dohandleMPpositiongraphic\doinsertMPpositiongraphic +\to \everyinsertpositionaction + +\def\docleanMPpositiongraphic#1#2#3% pos tag setups + {\ifnum\MPp{#1}<\realpageno \else + \noexpand \dohandleMPpositiongraphic{#1}{#2}{#3}% + \fi} + +\appendtoks + \let\dohandleMPpositiongraphic\docleanMPpositiongraphic +\to \everycleanpositionaction + +%D Graphics that span two positions (beware, does not cross pages). + +\def\setMPpositiongraphicrange + {\doquadruplegroupempty\dosetMPpositiongraphicrange} + +\def\dosetMPpositiongraphicrange#1#2#3#4% bpos epos tag vars + {\ifx\currentpositionoverlay\empty + \dosetpositionaction{#1}{\MPpositiongraphic{#3}{#4}}% + \else + \handlepositiongraphicsrange{#1}{#2}{#3}{#4}% + \fi} + +\def\handlepositiongraphicsrange#1#2#3#4% + {\handlepositionaction\dohandleMPpositiongraphicrange\with{#1}{#2}{#3}{#4}\on{#2}} + +\def\doinsertMPpositiongraphicrange#1#2#3#4% pos pos tag setups + {\ifnum\MPp{#1}\MPp{#2}>\zerocount + \iflocalpositioning + \donetrue + \else + \donefalse + \ifnum\MPp{#1}=\realpageno + \donetrue + \else\ifnum\MPp{#2}=\realpageno + \donetrue + \else\ifnum\MPp{#1}<\realpageno\relax\ifnum\MPp{#2}>\realpageno + \donetrue + \fi\fi\fi\fi + \fi + \ifdone + \def\currentposition{#1}\MPpositiongraphic{#3}{#4}% + \fi + \fi} + +\appendtoks + \let\dohandleMPpositiongraphicrange\doinsertMPpositiongraphicrange +\to \everyinsertpositionaction + +\def\docleanMPpositiongraphicrange#1#2#3#4% pos tag setups + {\ifnum\MPp{#2}<\realpageno \else + \noexpand \dohandleMPpositiongraphicrange{#1}{#2}{#3}{#4}% + \fi} + +\appendtoks + \let\dohandleMPpositiongraphicrange\docleanMPpositiongraphicrange +\to \everycleanpositionaction + +% will be overloaded, and/or code below moved to core-box + +\defineoverlay[\v!text-2][\positionoverlay{\v!text-2}] +\defineoverlay[\v!text-1][\positionoverlay{\v!text-1}] +\defineoverlay[\v!text+1][\positionoverlay{\v!text+1}] +\defineoverlay[\v!text+2][\positionoverlay{\v!text+2}] + +%D The auxiliary \METAPOST\ macros are defined by default, +%D by saying: + +\startMPextensions + if unknown context_core : input mp-core.mp ; fi ; +\stopMPextensions + +%D Some of these macros are pretty clever but too complicated +%D to be nice. When things are kind of stable I'll clean up +%D this mess. + +%D THIS NEEDS A CLEANUP + +\setupMPvariables + [mpos:box] + [linecolor=blue, + linewidth=\linewidth, + fillcolor=lightgray, + filloffset=\!!zeropoint] + +\startMPpositiongraphic{mpos:box}{fillcolor,linecolor,linewidth} + initialize_box(\MPpos{\MPvar{self}}) ; + boxfillcolor := \MPvar{fillcolor} ; + boxlinecolor := \MPvar{linecolor} ; + boxlinewidth := \MPvar{linewidth} ; + boxfilloffset := \MPvar{filloffset} ; + draw_box ; + anchor_box(\MPanchor{\MPvar{self}}) ; +\stopMPpositiongraphic + +\setupMPvariables + [mpos:area] + [linecolor=blue, + linewidth=\linewidth, + fillcolor=lightgray, + filloffset=\!!zeropoint] + +\startMPpositiongraphic{mpos:area}{fillcolor,linecolor,linewidth} + initialize_area(\MPpos{b:\MPvar{self}},\MPpos{e:\MPvar{self}}) ; + boxfillcolor := \MPvar{fillcolor} ; + boxlinecolor := \MPvar{linecolor} ; + boxlinewidth := \MPvar{linewidth} ; + boxfilloffset := \MPvar{filloffset} ; + draw_area ; + anchor_area(\MPanchor{b:\MPvar{self}}) ; +\stopMPpositiongraphic + +%D This is already cleaned up. + +% gridtype = 1 => baseline +% gridtype = 2 => betweenline + +\setupMPvariables + [mpos:par] + [mp=mpos:par:shape, + gridtype=0, + linetype=1, + filltype=1, + dashtype=0, % 1 = dashed, 2 = dashed with background + %snaptops=true, % not that nice: true/false + gridcolor=red, + linecolor=blue, + fillcolor=lightgray, + filloffset=\!!zeropoint, + linewidth=\linewidth, + gridwidth=\linewidth, + gridshift=\!!zeropoint, + lineradius=.5\bodyfontsize, + dashtype=1] + +\startuseMPgraphic{mpos:par:shape} + \iftracepositions show_par \else draw_par \fi ; +\stopuseMPgraphic + +\startuseMPgraphic{mpos:par:setup} + boxgridtype := \MPvar{gridtype} ; + boxlinetype := \MPvar{linetype} ; + boxfilltype := \MPvar{filltype} ; + boxdashtype := \MPvar{dashtype} ; + boxgridcolor := \MPvar{gridcolor} ; + boxlinecolor := \MPvar{linecolor} ; + boxfillcolor := \MPvar{fillcolor} ; + boxfilloffset := \MPvar{filloffset} ; + boxlinewidth := \MPvar{linewidth} ; + boxgridwidth := \MPvar{gridwidth} ; + boxgridshift := \MPvar{gridshift} ; + boxlineradius := \MPvar{lineradius} ; + %snap_multi_par_tops := \MPvar{snaptops} ; +\stopuseMPgraphic + +\startuseMPgraphic{mpos:par:extra} + % user stuff, like: + % snap_multi_par_tops := false ; +\stopuseMPgraphic + +\ifx\MPparcounter\undefined \newcounter\MPparcounter \fi + +\def\MPself {\MPvar{self}} +\def\MPbself {b:\MPself} +\def\MPeself {e:\MPself} +\def\MPwself {w:\MPself} +\def\MPparanchor{p:\MPparcounter} + +\def\MPl#1{\MPplus{#1}20} +\def\MPr#1{\MPplus{#1}30} + +\startMPpositionmethod{mpos:par} %%%%%%%%%%% will become obsolete + \edef\MPparcounter{\MPv\MPbself{1}{0}}% + \doifpositionelse\MPwself + {\startMPpositiongraphic{mpos:par}{fillcolor,filloffset,linecolor,gridcolor,linewidth,gridwidth,gridshift,lineradius} + initialize_area_par(\MPpos\MPbself, + \MPpos\MPeself, + \MPpos\MPwself) ; + \includeMPgraphic{mpos:par:setup} ; + \includeMPgraphic{mpos:par:extra} ; + \includeMPgraphic{\MPvar{mp}} ; + anchor_par(\MPanchor\MPbself) ; + \stopMPpositiongraphic} + {\startMPpositiongraphic{mpos:par}{fillcolor,filloffset,linecolor,gridcolor,linewidth,gridwidth,gridshift,lineradius} + initialize_par(\MPpos\MPbself, + \MPpos\MPeself, + \MPpos\textanchor, + \MPpos\MPparanchor, + \MPvv \MPparanchor{0pt,0pt,0pt,0pt,0,0pt}) ; + \includeMPgraphic{mpos:par:setup} ; + \includeMPgraphic{mpos:par:extra} ; + \includeMPgraphic{\MPvar{mp}} ; + anchor_par(\MPanchor\MPbself) ; + \stopMPpositiongraphic}% + \MPpositiongraphic{mpos:par}{}% +\stopMPpositionmethod + +%D The next alternative works in columnsets : + +% \iftracepositions show\else draw\fi_multi_pars ; + +\startuseMPgraphic{mpos:par:columnset} + \iftracepositions show_multi_pars \else draw_multi_pars \fi ; +\stopuseMPgraphic + +\startuseMPgraphic{mpos:par:sideline}{linecolor,lineoffset} + for i=1 upto nofmultipars : + fill leftboundary multipars[i] + shifted (-\MPvar{lineoffset},0) + rightenlarged 1mm withcolor \MPvar{linecolor} ; + endfor ; +\stopuseMPgraphic + +\startMPpositionmethod{mpos:par:columnset} + \edef\MPparcounter{\MPv\MPbself{1}{0}}% + \startMPpositiongraphic{mpos:par}{fillcolor,filloffset,linecolor,gridcolor,linewidth,gridwidth,gridshift,lineradius} + \includeMPgraphic{mpos:par:setup} ; + \includeMPgraphic{mpos:par:extra} ; + prepare_multi_pars(\MPpos\MPbself,\MPpos\MPeself,\MPpos\MPwself, + \MPpos\MPparanchor,\MPvv\MPparanchor{0pt,0pt,0pt,0pt,0,0pt}) ; + relocate_multipars(-\MPxy\MPanchorid) ; % inside layerpos + \includeMPgraphic{\MPvar{mp}} ; + \stopMPpositiongraphic + \MPpositiongraphic{mpos:par}{}% +\stopMPpositionmethod + +%D \starttyping +%D \setupbackground +%D [test] +%D [mp=mpos:par:columnset, +%D method=mpos:par:columnset] +%D \stoptyping + +%D We need to treat floats in a special way. + +\startMPinitializations + local_multi_par_area:=\iflocalpositioning true\else false\fi; +\stopMPinitializations + +\def\textbackgroundoverlay#1% + {\iflocalpositioning\v!local\else\v!text\fi#1} + +\newcounter\localpositionnumber + +\def\MPanchornumber + {\iflocalpositioning\localpositionnumber\else\the\realpageno\fi} + +%D So far for the trickery. + +\newcount\textbackgrounddepth + +\ifdefined\nofparbackgrounds\else \newcount\nofparbackgrounds \fi + +\ifx\totalnofparbackgrounds\undefined \newcounter\totalnofparbackgrounds \fi + +\appendtoks + \expanded{\savecurrentvalue\noexpand\totalnofparbackgrounds{\number\nofparbackgrounds}}% +\to \everybye + +% actually we can just ask lua to give us the nofpositions (or a least n<>0) + +\appendtoks + % a position can be mid paragraph in which case we're behind + \initializeparbackgrounds +\to \everystarttext + +\def\initializeparbackgrounds + {\ifcase\totalnofparbackgrounds\else + \enableparpositions + \fi} + +\unexpanded\def\starttextbackground + {\bgroup + \advance\textbackgrounddepth\plusone + \dodoubleempty\dostarttextbackground} + +\let\dodostarttextbackground\relax +\let\dodostoptextbackground \relax + +\def\currentparbackground{pbg:0} +\def\nextparbackground {pbg:1} + +\def\btbanchor{b:\currentparbackground} +\def\etbanchor{e:\currentparbackground} + +\def\nextbtbanchor{b:\nextparbackground} +\def\nextetbanchor{e:\nextparbackground} + +\def\textbackgroundparameter#1% + {\csname\??td\currenttextbackground#1\endcsname} + +\let\backgroundvariable\textbackgroundparameter % will become obsolete + +% \definetextbackground[more][state=start,backgroundcolor=red] % location=paragraph +% \definetextbackground[test][state=start,backgroundcolor=green] +% +% \page \placefigure[left]{}{} +% +% \starttextbackground[test] +% \readfile{ward}{}{} +% \starttextbackground[more] +% \readfile{ward}{}{} +% \stoptextbackground +% \readfile{ward}{}{} +% \stoptextbackground +% +% \page \placefigure[right]{}{} +% +% \starttextbackground[test] +% \readfile{ward}{}{} +% \starttextbackground[more] +% \readfile{ward}{}{} +% \stoptextbackground +% \readfile{ward}{}{} +% \stoptextbackground + +\def\dostarttextbackground[#1][#2]% + {\checktextbackgrounds + \def\currenttextbackground{#1}% + \global\advance\nofparbackgrounds\plusone + \edef\currentparbackground{pbg:\number\nofparbackgrounds}% + \xdef\nextparbackground{pbg:\number\numexpr\nofparbackgrounds+\plusone\relax}% still xdef ? + % todo : \synchonizepositionpage{b:\currentparbackground}{s:\currentparbackground}% + \setuptextbackground[#1][#2]% + \let\dodostarttextbackground\relax + \let\dodostoptextbackground \relax + \doif{\textbackgroundparameter\c!state}\v!start{\dopresettextbackground{#1}}% + \dodostarttextbackground} + +% todo \backgroundvariable\c!variant + +\def\dopresettextbackground#1% todo: \backgroundparameter + {\normalexpanded{\noexpand\processaction[\textbackgroundparameter\c!location]} + [ \v!text=>\let\dodostarttextbackground\dostarttextbackgroundtxt + \let\dodostoptextbackground \dostoptextbackgroundtxt, + \v!paragraph=>\let\dodostarttextbackground\dostarttextbackgroundpar + \let\dodostoptextbackground \dostoptextbackgroundpar, + \v!none=>\let\dodostarttextbackground\relax + \let\dodostoptextbackground \relax]% + \ifx\dodostarttextbackground\dostarttextbackgroundpar % untested + \ifnum\textbackgrounddepth>\plusone % new + \let\dodostarttextbackground\dostarttextbackgroundtxt + \let\dodostoptextbackground \dostoptextbackgroundtxt + \fi + \fi + \doifelse{\textbackgroundparameter\c!frame}\v!on + {\doifelse{\textbackgroundparameter\c!corner}\v!round + {\setvalue{\??td#1\c!frame}{2}} + {\setvalue{\??td#1\c!frame}{1}}} + {\setvalue{\??td#1\c!frame}{0}}% + \doifelse{\textbackgroundparameter\c!background}\v!color + {\setvalue{\??td#1\c!background}{1}} + {\setvalue{\??td#1\c!background}{0}}% + %\startpositionoverlay{\v!text\getvalue{\??td#1\c!level}}% + \startpositionoverlay{\textbackgroundoverlay{\textbackgroundparameter\c!level}}% + \expanded + {\setMPpositiongraphicrange % moet veel efficienter + {\btbanchor}% {b:\currentparbackground}% + {\etbanchor}% {e:\currentparbackground}% + {\textbackgroundparameter\c!method}% + {self=\currentparbackground, + mp=\textbackgroundparameter\c!mp, + gridtype=\textbackgroundparameter\c!alternative, + filltype=\textbackgroundparameter\c!background, + linetype=\textbackgroundparameter\c!frame, + dashtype=\textbackgroundparameter{dash}, % to be internationalized + gridcolor=\textbackgroundparameter\c!framecolor, + linecolor=\textbackgroundparameter\c!framecolor, + lineoffset=\textbackgroundparameter\c!frameoffset, + fillcolor=\textbackgroundparameter\c!backgroundcolor, + filloffset=\textbackgroundparameter\c!backgroundoffset, + gridwidth=\textbackgroundparameter\c!rulethickness, + gridshift=\textbackgroundparameter\c!voffset, + linewidth=\textbackgroundparameter\c!rulethickness, + lineradius=\textbackgroundparameter\c!radius}}% + \stoppositionoverlay} + +\unexpanded\def\stoptextbackground + {\dodostoptextbackground + \carryoverpar\egroup} + +\unexpanded\def\starttextbackgroundmanual + {\dostartattributes{\??td\currenttextbackground}\c!style\c!color\empty + \fpos\currentparbackground\ignorespaces} + +\unexpanded\def\stoptextbackgroundmanual + {\tpos\currentparbackground + \dostopattributes} + +\def\dostarttextbackgroundtxt + {\ifvmode \dontleavehmode \fi + \dostartattributes{\??td\currenttextbackground}\c!style\c!color\empty + \fpos\currentparbackground\ignorespaces} + +\def\dostoptextbackgroundtxt + {\tpos\currentparbackground + \dostopattributes} + +\newskip\textbackgroundskip + +\def\dostarttextbackgroundpar + {\endgraf % new + \textbackgroundparameter\c!before + \noindent + \ifgridsnapping + \doassignsomeskip\textbackgroundparameter\c!topoffset\to\textbackgroundskip + \ifdim\textbackgroundskip>\zeropoint + \struttedbox{\hbox{\raise\textbackgroundskip\hbox{\fpos\currentparbackground}}}% + \else + \fpos\currentparbackground + \fi + \else + \fpos\currentparbackground + \fi + \bgroup + \endgraf % we need a vertical nobreak - 29/06/2004 + \nobreak \vskip-\lineheight \nobreak + \ifgridsnapping \else + \doassignsomeskip\textbackgroundparameter\c!topoffset\to\textbackgroundskip + \ifdim\textbackgroundskip>\zeropoint + \kern\textbackgroundskip\nobreak + \fi + \fi + \dosetleftskipadaption{\textbackgroundparameter\c!leftoffset}% + \advance\leftskip\leftskipadaption + \dosetleftskipadaption{\textbackgroundparameter\c!rightoffset}% + \advance\rightskip\leftskipadaption + % new + \dosetraggedcommand{\textbackgroundparameter\c!align}% + \raggedcommand + % + \dostartattributes{\??td\currenttextbackground}\c!style\c!color\empty + \nowhitespace + \nobreak % new per 23/04/2006 (else potential break when whitespace) + \seteffectivehsize + \doinhibitblank % \blank[\v!disable]% new + \par} + +\def\dostoptextbackgroundpar + {\par + \removelastskip % new + \dostopattributes + \doassignsomeskip\textbackgroundparameter\c!bottomoffset\to\textbackgroundskip + \ifdim\lastskip>\zeropoint + \advance\textbackgroundskip-\lastskip + \fi + \ifgridsnapping \else \ifdim\textbackgroundskip>\zeropoint + \kern\textbackgroundskip\nobreak + \fi \fi + \nobreak \vskip-\lineheight \nobreak + \nowhitespace + \egroup + \bgroup \forgeteverypar % NOT REALLY NEEDED, SAVES HASH/MEM + \nobreak \noindent \strut \hfill \kern\zeropoint + \doassignsomeskip\textbackgroundparameter\c!bottomoffset\to\textbackgroundskip + \ifgridsnapping % experimental, pascal (todo: topoffset in same way) + \ifdim\textbackgroundskip>\zeropoint + \struttedbox{\hbox{\lower\textbackgroundskip\hbox{\tpos\currentparbackground}}}% + \else + \tpos\currentparbackground + \fi + \else + \tpos\currentparbackground + \fi + \egroup + \endgraf % new + \textbackgroundparameter\c!after} + +\let\textparpages \!!zeropoint +\let\textparheight\!!zeropoint +\let\textparwidth \!!zeropoint + +\def\calculatetextpardimensions + {\docalculatetextpardimensions\btbanchor\etbanchor\MPparanchor} + +\def\calculatenexttextpardimensions + {\docalculatetextpardimensions\nextbtbanchor\nextetbanchor\relax} + +% \def\docalculatetextpardimensions#1#2#3% #1=\btbanchor #2=\etbanchor +% {\scratchcounter\numexpr\MPp#2-\MPp#1\relax +% \edef\textparpages{\the\scratchcounter}% +% \ifcase\scratchcounter +% % one page +% \scratchdimen\dimexpr\MPy#1-\MPy#2\relax +% \else +% % two or more pages +% \ifnum\scratchcounter>2 +% \ifnum\scratchcounter<5 +% % more pages +% \scratchdimen\textheight +% \advance\scratchcounter \minusone +% \multiply\scratchdimen \scratchcounter +% \else +% % keep'm small +% \scratchdimen5\textheight +% \fi +% \else +% \scratchdimen\dimexpr\MPy#1-\MPy#2-\MPy\textanchor+\MPy\textanchor+\MPh\textanchor\relax +% \fi +% \fi +% \edef\textparheight{\the\scratchdimen}% +% \ifcase\scratchcounter +% % one page +% \scratchdimen\dimexpr\MPx#2-\MPx#1\relax +% \else +% % two or more pages / maybe also hang +% \ifx#3\relax +% \scratchdimen\makeupwidth % \textwidth +% \else +% \scratchdimen\dimexpr\MPw\MPparanchor-\MPl\MPparanchor-\MPr\MPparanchor\relax +% \fi +% \fi +% \edef\textparwidth{\the\scratchdimen}} + +\def\docalculatetextpardimensions#1#2#3% #1=\btbanchor #2=\etbanchor (adapted 8/6/2009) + {\scratchcounter\numexpr\MPp#2-\MPp#1\relax + \edef\textparpages + {\the\scratchcounter}% + \edef\textparheight + {\the\dimexpr + \ifcase\scratchcounter + % one page + \MPy#1-\MPy#2% + \else + % two or more pages + \ifnum\scratchcounter>2 + \ifnum\scratchcounter<5 + % more pages + \textheight*\numexpr\scratchcounter+\minusone + \else + % keep'm small + 5\textheight + \fi + \else + \MPy#1-\MPy#2-\MPy\textanchor+\MPy\textanchor+\MPh\textanchor + \fi + \fi + \relax}% + \edef\textparwidth + {\the\dimexpr + \ifcase\scratchcounter + % one page + \MPx#2-\MPx#1% + \else + % two or more pages / maybe also hang + \ifx#3\relax + \makeupwidth % \textwidth + \else + \MPw\MPparanchor-\MPl\MPparanchor-\MPr\MPparanchor + \fi + \fi + \relax}} + +\def\mintextparheight{4\lineheight} + +\def\dontsplitnexttextbackground % dangerous but useful + {\ifdim\pagetotal>\textheight \else + \ifdim\pagegoal=\maxdimen \else + \calculatenexttextpardimensions + % too tricky + % \scratchdimen=\textparheight + % \advance\scratchdimen\pagetotal\relax + % \ifdim\scratchdimen>\pagegoal + % \page + % \fi + \ifdim\textparheight>\zeropoint + \ifdim\textparheight>\mintextparheight\else + \page % option + \fi + \fi + \fi + \fi} + +\unexpanded\def\definetextbackground + {\dodoubleempty\dodefinetextbackground} + +\def\dodefinetextbackground[#1][#2]% parent and ..parameter + {\ifsecondargument % why ? + \copyparameters[\??td#1][\??td] + [\c!state,\c!location,\c!alternative,\c!mp,\c!method, + \c!background,\c!backgroundcolor,\c!corner,\c!level, + \c!backgroundoffset,\c!before,\c!after,\c!align,dash, % dash not yet internationalized + \c!radius,\c!frame,\c!framecolor,\c!rulethickness,\c!voffset,\c!frameoffset, + \c!leftoffset,\c!rightoffset,\c!topoffset,\c!bottomoffset]% + \getparameters[\??td#1][#2]% + \doifvalue{\??td#1\c!state}\v!start\checktextbackgrounds + \setuvalue{#1}% + {\groupedcommand{\starttextbackground[#1]}{\stoptextbackground}}% + \setvalue{\e!start#1}{\starttextbackground[#1]}% + \setvalue{\e!stop #1}{\stoptextbackground}% + \fi} + +\unexpanded\def\setuptextbackground + {\dodoubleargument\dosetuptextbackground} + +\def\dosetuptextbackground[#1][#2]% + {\ifsecondargument + \doifelsenothing{#1} + {\dodosetuptextbackground{#2}\empty} + {\processcommalist[#1]{\dodosetuptextbackground{#2}}}% + \else + \dodosetuptextbackground{#1}\empty + \fi} + +\def\dodosetuptextbackground#1#2% + {\getparameters[\??td#2][#1]% + \def\currenttextbackground{#2}% + \doifvalue{\??td#2\c!state}\v!start\checktextbackgrounds} + +\let\currenttextbackground\empty + +\def\checktextbackgrounds + {\ifproductionrun + \enabletextarearegistration + \enablehiddenbackground + \fi} + +\setuptextbackground + [\c!mp=mpos:par:columnset, % buggy: mpos:par:shape + \c!method=mpos:par:columnset, % + \c!state=\v!start, + \c!location=\v!text, + \c!leftoffset=\!!zeropoint, % 1em, + \c!rightoffset=\textbackgroundparameter\c!leftoffset, + \c!topoffset=\!!zeropoint, % \v!medium, + \c!bottomoffset=\textbackgroundparameter\c!topoffset, + \c!level=-1, + \c!alternative=0, + \c!align=, + dash=0, % to be internationalized + \c!background=\v!color, + \c!backgroundcolor=lightgray, + \c!backgroundoffset=\!!zeropoint, + \c!corner=\v!rectangular, + \c!radius=.5\bodyfontsize, + \c!voffset=\!!zeropoint, + \c!frame=\v!on, + \c!framecolor=blue, + \c!rulethickness=\linewidth] + +%D As an example we define a grid background: + +\definetextbackground + [\v!grid] + [\c!state=\v!stop, + \c!location=\v!paragraph, + \c!frame=\v!off, + \c!framecolor=red, + \c!background=, + \c!alternative=1] + +\ifx\basegrid\undefined \else \letvalue\v!grid=\basegrid \fi + +% lelijk, aanpassen, opties + +\setupMPvariables + [mpos:connect] + [linecolor=red, + linewidth=1pt] + +\setupMPvariables + [mpos:encircle] + [fillcolor=lightgray, + filloffset=\!!zeropoint, + linecolor=blue, + linewidth=1pt] + +% these might become macros in mp-page + +\startuseMPgraphic{mpos:common:ec} + path pa ; pair ca ; color lc ; numeric lw ; + lw := \MPvar{linewidth} ; + lc := \MPvar{linecolor} ; + initialize_box(\MPpos{\MPvar{self}}) ; + pa := pxy ; ca := cxy ; pa := boundingbox pa enlarged 2lw ; + pa := llcorner pa...lrcorner pa...urcorner pa...ulcorner pa...cycle ; + drawoptions (withpen pencircle scaled lw withcolor lc) ; +\stopuseMPgraphic + +\startMPpositiongraphic{mpos:encircle}{linecolor,fillcolor,linewidth} + \includeMPgraphic{mpos:common:ec} + fill pa withcolor \MPvar{fillcolor} ; draw pa ; + anchor_box(\MPanchor{\MPvar{self}}) ; +\stopMPpositiongraphic + +\startMPpositiongraphic{mpos:connect}{linecolor,linewidth} + path pb, pc ; pair cb, cc ; + \includeMPgraphic{mpos:common:ec} + initialize_box(\MPpos{\MPvar{to}}) ; + pb := pxy ; cb := cxy ; pb := boundingbox pb enlarged 2lw ; + pb := llcorner pb...lrcorner pb...urcorner pb...ulcorner pb...cycle ; + pc := ca {up} .. {down} cb ; + cc := (pc intersection_point pa) ; + if intersection_found : + pc := pc cutbefore cc ; + cc := (pc intersection_point pb) ; + if intersection_found : + pc := pc cutafter cc ; + drawarrow pc ; drawarrow reverse pc ; + fi ; + fi ; + anchor_box(\MPanchor{\MPvar{self}}) ; +\stopMPpositiongraphic + +%D \macros +%D {stackposdown, stackposup, stackposleft,stackposright} +%D +%D A non graphic example of the use of positioning, is to stack +%D text in for instance the margin. +%D +%D \stackposdown \inleft {some text}The text \type {some text} +%D goes into the left margin, and \stackposdown \inleft {some +%D more}\type {some more} as well. When they overlap, they +%D will not touch. +%D +%D Here we said \type {\stackposdown \inleft{some text}}. Instead +%D of \stackposleft \inleft {one}stacking \stackposleft \inleft +%D {two}vertically, one can stack horizontally by \stackposleft +%D \inleft {three}using \type {\stackposleft}. +%D +%D We can go in all four directions, using \type {\stackposdown}, +%D \type {\stackposup}, \type {\stackposleft} and \type +%D {\stackposright}. + +\def\stackposdistance{.5em} + +\newcount\currentautopos +\newcount\previousautopos + +\def\POSstackprefix{stack:} + +\def\dostackposbox#1#2% + {\dowithnextbox + {#2{\previousautopos\currentautopos + \global\advance\currentautopos\plusone + \edef\currentposition {\POSstackprefix\number\currentautopos}% + \edef\previousposition{\POSstackprefix\number\previousautopos}% + \hpos\currentposition{\doifoverlappingelse\currentposition\previousposition{#1}{\flushnextbox}}}}% + \hbox} + +\def\stackposup {\dostackposbox{\raise\lineheight\flushnextbox}} +\def\stackposdown {\dostackposbox{\lower\lineheight\flushnextbox}} +\def\stackposleft {\dostackposbox{\copy\nextbox\hskip\nextboxwd\hskip\stackposdistance}} +\def\stackposright{\dostackposbox{\hskip\stackposdistance\hskip\nextboxwd\flushnextbox}} + +%D \macros +%D {stackeddown} +%D +%D However, a better implementation is possible with the +%D following macro. We now have an extra key \type {stack} for +%D margin settings. When set to \type {yes}, this macro comes +%D into action. + +% Because there can be many stacked items in a line and successive lines, we +% play dirty and adapt the position and height of the current node so that +% this becomes visible to a next pass. +% +% \startbuffer +% \inleft {test 1} test 1 \inleft {test 2} test 2 \endgraf +% \inleft {test 3} test 3 +% \stopbuffer +% \getbuffer \typebuffer \flushstatus \page +% +% \startbuffer +% \inleft {test 1} test 1 \inleft {test 2} test 2 \inleft {test 3} test 3 \endgraf +% \inleft {test 4} test 4 +% \stopbuffer +% \getbuffer \typebuffer \flushstatus \page +% +% \startbuffer +% \inleft {test 1} test 1 \endgraf +% \inleft {test 2} test 2 \endgraf +% \inleft {test 3} test 3 +% \stopbuffer +% \getbuffer \typebuffer \flushstatus \page +% +% \startbuffer +% \inleft {test 1\\test 1} test 1 \inleft {test 2} test 2 \endgraf +% \inleft {test 3} test 3 +% \stopbuffer +% \getbuffer \typebuffer \flushstatus \page +% +% \startbuffer +% \inleft {test 1\\test 1\\test 1\\test 1\\test 1} test 1 \endgraf +% test 2 \endgraf +% \inleft {test 3} test 3 +% \stopbuffer +% \getbuffer \typebuffer \flushstatus \page +% +% \startbuffer +% \inleft{test 1} test \inleft{test 2} test \inleft{test 3\\test 3} test +% \stopbuffer +% \getbuffer \typebuffer \flushstatus \page +% +% \startbuffer +% \inleft{test 1\\test 1\\test 1} test \inleft{test 2\\test 2} test \inleft{test 3\\test 3\\test 3} test \endgraf +% \inleft{test 1\\test 1\\test 1} test \inleft{test 2\\test 2} test \inleft{test 3\\test 3\\test 3} test +% \stopbuffer +% \getbuffer \typebuffer \flushstatus \page + +\newdimen\laststackvmove % use \scratchdimenone instead of skip + +\def\stackeddown + {\bgroup + % this macro assumes a few things and is meant to work for margin notes + \dowithnextbox + {\global\advance\currentautopos\plusone + \global\laststackvmove\zeropoint + \hpos{\POSstackprefix\number\currentautopos} + {\edef\next + {\nextboxht\the\nextboxht + \nextboxdp\the\nextboxdp + \nextboxwd\the\nextboxwd}% + \previousautopos\currentautopos + \scratchdimen\zeropoint + \scratchcounter\zerocount + \doloop + {\advance\previousautopos\minusone + \edef\currentposition {\POSstackprefix\number\currentautopos}% + \edef\previousposition{\POSstackprefix\number\previousautopos}% + \ifnum\MPp\currentposition=\MPp\previousposition\relax + %\registerstatus{doing \number\currentautopos/\number\previousautopos}% + \doifoverlappingelse\currentposition\previousposition + {\scratchskip\dimexpr + \MPy\currentposition + -\MPy\previousposition + -\MPd\currentposition % untested + +\MPd\previousposition % untested + +\MPh\currentposition + \relax\relax % second relax realy needed, forgotten while dimexpressing + % todo: also take depth into account + \ifdim\scratchskip<\scratchdimen + %\registerstatus{no \the\scratchskip}% + \else + %\registerstatus{yes \the\scratchskip}% + \scratchdimen\scratchskip + \fi}% + \donothing % {\registerstatus{next}}% + \ifnum\previousautopos<\zerocount\exitloop\fi + \else + \exitloop + \fi}% + \ifdim\scratchdimen=\zeropoint \else + \bgroup + \edef\currentposition{\POSstackprefix\number\currentautopos}% + \scratchskip\scratchdimen + \advance\scratchskip\MPh\currentposition + \scratchdimen-\scratchdimen + \advance\scratchdimen\MPy\currentposition + %\registerstatus{old \number\currentautopos: \MPy\currentposition/\MPh\currentposition}% + \expanded{\replacepospxywhd + {\currentposition}{\MPp\currentposition}{\MPx\currentposition}{\the\scratchdimen}% + {\MPw\currentposition}{\the\scratchskip}{\MPd\currentposition}}% + %\registerstatus{new \number\currentautopos: \MPy\currentposition/\MPh\currentposition}% + \egroup + \global\laststackvmove\scratchdimen % new + \setbox\nextbox\iftracepositions\@EA\ruledhbox\else\@EA\hbox\fi + {\lower\scratchdimen\flushnextbox}% + \next + %\registerstatus{\strut}% + \fi + \flushnextbox}% + \egroup}} + +%D The next hack make sure that margin texts near faulty +%D strutted lines are handled ok. + +\newif\ifrepositionmarginbox \repositionmarginboxtrue + +\newcount\currentmarginpos + +\def\dopositionmarginbox#1% + {\bgroup + \ifrepositionmarginbox + \global\advance\currentmarginpos\plusone + %\setposition{\s!margin:\number\currentmarginpos}% not always + \ifcase\marginrepositionmethod + % nothing + \or + % nothing + \or + % stack / page check yet untested + \setposition{\s!margin:\number\currentmarginpos}% + \scratchdimen\MPy{\s!margin:\number\currentmarginpos}% + \global\advance\currentmarginpos\plusone + \advance\scratchdimen -\MPy{\s!margin:\number\currentmarginpos}% + \advance\scratchdimen -\strutdp + % new but bugged + % \setbox#1\hbox + % {\hskip-\MPx{\s!margin:\number\currentmarginpos}% + % \hskip\MPx{head:\the\realpageno}% + % \box#1}% + % so far + \setbox#1\hbox + {\setposition{\s!margin:\number\currentmarginpos}% + \raise\scratchdimen\box#1}% + \or + % move up + \setposition{\s!margin:\number\currentmarginpos}% + \ifnum\MPp{p:\number\parposcounter}=\MPp{\s!margin:\number\currentmarginpos}\relax + \scratchdimen\dimexpr\MPy{p:\number\parposcounter}-\MPy{\s!margin:\number\currentmarginpos}\relax + \expanded{\setbox#1\hbox{\raise\scratchdimen\box#1}\ht#1\the\ht#1\dp#1\the\dp#1}% + \fi + \or + % move up, assume end of par + \setposition{\s!margin:\number\currentmarginpos}% + \ifnum\MPp{p:\number\parposcounter}=\MPp{\s!margin:\number\currentmarginpos}\relax + \getnoflines\margincontentheight + \advance\noflines\minusone + \scratchdimen\noflines\lineheight + \else + \scratchdimen\dimexpr\MPy{p:\number\parposcounter}-\MPy{\s!margin:\number\currentmarginpos}\relax + \fi + \expanded{\setbox#1\hbox{\raise\scratchdimen\box#1}\ht#1\the\ht#1\dp#1\the\dp#1}% + \fi + \dp#1\zeropoint + \ht#1\zeropoint + \fi + \graphicvadjust{\dontleavehmode\box#1}% dontleavehmode is needed to get direction right + \egroup} + +\chardef\marginrepositionmethod\plusone % sidemethod +\chardef\margincontentmethod \plusthree % textmethod % beware: 1 = old method +\chardef\marginpagecheckmethod \plusone % splitmethod + +%D For a right menu, a sequence of calls to \type +%D {right_menu_button} is generated. +%D +%D \starttyping +%D right_menu_button (n, p, s=0/1/2, x, y, w, h, d) ; +%D \stoptyping +%D +%D Here, n is the number of the button, s a status variable, +%D while the rest is positional info. The status variable is +%D 0, 1 or~2: not found, found and found but current page. + +% 0=not found 1=found 2=current page + +% geen leeg + +\newtoks\MPmenutoks + +\def\MPmenubuttons#1{\the\MPmenutoks} + +\appendtoks \global\MPmenutoks\emptytoks \to \everyshipout + +% 0=notfound 1=found 2=currentpage + +\def\domenuitemposition#1#2#3% + {\doifelsevalue{\??am#1\c!position}\v!yes + {\doglobal\increment\currentamposition + \doifreferencefoundelse{#2}% 0=not found, 1=same page, >1=elsewhere + {\chardef\currentamrealpage\ifnum\currentreferencerealpage=\realpageno\plusone\else\plustwo\fi}% + {\chardef\currentamrealpage\plustwo}% + \expanded + {\doglobal\noexpand\appendtoks + #1_menu_button(\number\currentamposition,\the\currentamrealpage,\MPpos{#1:\currentamposition}) ; + \to \MPmenutoks}% + \hpos{#1:\currentamposition}{#3}} + {#3}} + +\def\dowholemenuposition#1% + {\ifnum\currentamposition>0 + \dowithnextbox{\hpos{menu:#1:\the\realpageno}{\flushnextbox}}\hbox + \fi} + +%D \macros +%D {GFC, GTC, GSC} +%D +%D The next macros extend tables and tabulation with +%D backgrounds and position related features. Areas are +%D specified with symbolic names, and symbolic references to +%D the graphics involved. Each table has its own namespace. + +\newconditional\tablehaspositions +\newcount\noftabpositions +\newtoks \posXCtoks + +\def\dotablebpos{\bpos} +\def\dotableepos{\epos} + +\def\tbPOSprefix + {tbp:\number\noftabpositions:} + +% \def\tableposindeed +% {\scratchtoks\posXCtoks +% \global\posXCtoks\emptytoks +% \the\scratchtoks} + +\def\tablepos + {\normalexpanded{\global\posXCtoks\emptytoks\the\posXCtoks}} + +\let\tabulatepos\tablepos + +\def\dodododoGSC[#1:#2]% + {\remappositionframed{#2}{\tbPOSprefix#1}% + \dotablebpos{\tbPOSprefix#1}% + \doglobal\appendtoks\@EA\dotableepos\@EA{\tbPOSprefix#1}\to\posXCtoks} + +\def\dododoGSC[#1:#2:#3]% + {\doglobal\appendtoks\dodododoGSC[#1:#2]\to\posXCtoks\NC} + +\def\dodoGSC[#1]% + {\def\docommand##1{\dododoGSC[##1:##1]}% + \processcommalist[#1]\docommand} + +\def\dodododoGFC[#1:#2:#3]% + {\remappositionframed{#2}{\tbPOSprefix#1}% + \dotablebpos{\tbPOSprefix#1}} + +\def\dododoGFC[#1]% + {\def\docommand##1{\dodododoGFC[##1:##1]}% + \processcommalist[#1]\docommand} + +\def\dodoGFC[#1]% + {\doglobal\appendtoks\dododoGFC[#1]\to\posXCtoks\NC} + +\def\dododododoGTC[#1:#2]% + {\dotableepos{\tbPOSprefix#1}} + +\def\dodododoGTC[#1]% + {\def\docommand##1{\dododododoGTC[##1:##1]}% + \processcommalist[#1]\docommand} + +\def\dododoGTC[#1]% + {\doglobal\appendtoks\dodododoGTC[#1]\to\posXCtoks} + +\def\dodoGTC[#1]% + {\doglobal\appendtoks\dododoGTC[#1]\to\posXCtoks\NC} + +\def\dodododoXC[#1#2]% + {\if#1>\dodoGFC [#2:#2]\else + \if#1+\dodoGFC [#2:#2]\else + \if#1<\dodoGTC [#2:#2]\else + \if#1-\dodoGTC [#2:#2]\else + \if#1=\dodoGSC [#2:#2]\else + \dodoGSC[#1#2:#1#2]\fi\fi\fi\fi\fi} + +\def\dododoXC#1% + {\dodododoXC[#1]} + +\def\dodoXC[#1]% + {{\let\NC\relax\processcommalist[#1]\dododoXC}} + +\def\@@checktablepositionstate + {\iftrialtypesetting + \global\settrue\tablehaspositions + \firstargumentfalse + \fi} + +\def\doGSC[#1]{\@@checktablepositionstate\iffirstargument\dodoGSC[#1]\else\expandafter\NC\fi} +\def\doGFC[#1]{\@@checktablepositionstate\iffirstargument\dodoGFC[#1]\else\expandafter\NC\fi} +\def\doGTC[#1]{\@@checktablepositionstate\iffirstargument\dodoGTC[#1]\else\expandafter\NC\fi} +\def\doXC [#1]{\@@checktablepositionstate\iffirstargument\dodoXC [#1]\else\expandafter\fi\NC} + +\def\tbGSC{\dosingleempty\doGSC} +\def\tbGFC{\dosingleempty\doGFC} +\def\tbGTC{\dosingleempty\doGTC} +\def\tbXC {\dosingleempty\doXC } + +%D The amount of code to support tables and tabulation is +%D rather minimalistic. + +\let\tabulatepos\tablepos + +\def\tabulatenormalpos + {\iftrialtypesetting + % nothing + \else\ifconditional\tablehaspositions + \hss\tabulatepos\hss + \else + % nothing + \fi\fi} + +\def\tabulateequalpos + {\iftrialtypesetting + \tabulateEQ + \else\ifconditional\tablehaspositions + \tabulateEQpos + \else + \tabulateEQ + \fi\fi} + +\def\tabulateEQpos + {\setbox\scratchbox\hbox{\tabulateEQ}% + \hbox to \wd\scratchbox{\hss\kern\zeropoint\tabulatepos\hss}% + \hskip-\wd\scratchbox + \box\scratchbox} + +\def\tabulatenormalcolumn#1% overloaded later in node-bck + {&\iftabulateequal\tabulateequalpos\else\tabulatenormalpos\fi + &\global\chardef\tabulatetype#1&} + +\def\tabulateequalcolumn#1% overloaded + {&\tabulateequalpos + &\global\chardef\tabulatetype#1&} + +\appendtoks + \global\advance\noftabpositions\plusone + \global\setfalse\tablehaspositions +\to \everytabulate + +% We need to handle paragraphs as well. + +\let\doflushtabulateepos\relax + +\def\dotabulatebpos + {\bpos} + +\def\dotabulateepos#1% + {\ifvoid\tablebox\tabulatecolumn + \epos{#1}% + \glet\doflushtabulateepos\relax + \else + \gdef\doflushtabulateepos{\epos{#1}}% + \fi} + +\def\splitofftabulatebox % overloaded in node-bck + {\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 + \iftrialtypesetting\else\ifconditional\tablehaspositions\doflushtabulateepos\fi\fi} + +\appendtoks + \let\dotablebpos\dotabulatebpos + \let\dotableepos\dotabulateepos + \glet\doflushtabulateepos\relax +\to \everytabulate + +%D In order to prevent potential clashes with abbreviations, +%D postpone the mapping. + +\appendtoks + \let\GSC\tbGSC \let\GFC\tbGFC \let\GTC\tbGTC \let\XC\tbXC +\to \everytabulate + +%D \macros +%D {definepositionframed} +%D +%D The next example show how to provide backgrounds to table +%D cells. First we define some framed backgrounds. +%D +%D \startbuffer +%D \definepositionframed[x][background=color,backgroundcolor=red] +%D \definepositionframed[y][background=color,backgroundcolor=green] +%D \definepositionframed[z][background=color,backgroundcolor=blue] +%D \stopbuffer +%D +%D \typebuffer +%D +%D % \getbuffer +%D +%D \startbuffer +%D \starttabulate[|c|c|c|] +%D \GFC[f:x] this is a small \NC table \NC in which we \NC \FR +%D \NC will demonstrate \GFC[g:z] that this \GTC[g] positioning \NC \MR +%D \GSC[e:y] mechanism also \GTC[f] works quite well \NC in tables \NC \LR +%D \stoptabulate +%D \stopbuffer +%D +%D The table itself defines three areas (a, b and~c) using +%D these frames. +%D +%D \typebuffer +%D % \getbuffer +%D +%D Tables (based on \TABLE) are supported by: + +\def\normalTABLEsimplebar {\unskip\!ttRightGlue&\tablepos&} % | +\def\normalTABLEcomplexbar{\unskip\!ttRightGlue&\omit\tablepos\!ttAlternateVrule} % \| +\def\normalTABLEquote {\unskip\!ttRightGlue&\omit\tablepos&} % " + +\appendtoks + \global\advance\noftabpositions\plusone + \global\setfalse\tablehaspositions +\to \everytable + +%D Since we don't want nameclashes: + +\appendtoks + \let\GSC\tbGSC \let\GFC\tbGFC \let\GTC\tbGTC \let\XC\tbXC +\to \everytable + +%D In the previous example, we could have provided an overlay to +%D the framed definition. A more direct approach is demonstrated +%D below: +%D +%D \startbuffer +%D \def\cw#1{\color[white]{#1}} +%D +%D \startMPpositiongraphic{tableshade} +%D initialize_area(\MPpos{\MPvar{from}},\MPpos{\MPvar{to}}) ; +%D color c ; c := \MPvar{color} ; +%D linear_shade(pxy,0,.4c,.9c) ; +%D anchor_area(\MPanchor{\MPvar{from}}) ; +%D \stopMPpositiongraphic +%D +%D \setMPpositiongraphic{b:x}{tableshade}{from=b:x,to=e:x,color=red} +%D \setMPpositiongraphic{b:y}{tableshade}{from=b:y,to=e:y,color=green} +%D \setMPpositiongraphic{b:z}{tableshade}{from=b:z,to=e:z,color=blue} +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D The definition of the table looks about the same as the +%D previous one: +%D +%D \startbuffer +%D \starttable[|c|c|c|] +%D \GFC[b:z] \cw{this is a small} \NC \cw{table} \NC in which we \NC \FR +%D \NC \cw{will demonstrate} \GFC[c:y] \cw{that this} \GTC[c] \cw{positioning} \NC \MR +%D \GSC[a:x] \cw{mechanism also} \GTC[b] \cw{works quite well} \NC in tables \NC \LR +%D \stoptable +%D \stopbuffer +%D +%D \typebuffer +%D +%D \getbuffer + +% \definepositionframed[w][background=color,backgroundcolor=yellow] +% \definepositionframed[x][background=color,backgroundcolor=red] +% \definepositionframed[y][background=color,backgroundcolor=green] +% \definepositionframed[z][background=color,backgroundcolor=blue] +% +% \starttabulate[|c|c|c|] +% \NC this is a small \NC table \NC in which we \NC \FR +% \NC will demonstrate \NC that this \NC positioning \NC \MR +% \NC mechanism also \NC works quite well \NC in tables \NC \LR +% \stoptabulate +% +% \starttabulate[|c|c|c|] +% \GFC[f:x] this is a small \GTC table \NC in which we \NC \FR +% \NC will demonstrate \GFC[g:z] that this \GTC[g] positioning \NC \MR +% \GSC[e:y] mechanism also \GTC[f] works quite well \NC in tables \NC \LR +% \stoptabulate +% +% \starttabulate[|c|c|c|] +% \GFC[f:x,d:w] this is a small \GTC[d] table \NC in which we \NC \FR +% \NC will demonstrate \GFC[g:z] that this \GTC[g] positioning \NC \MR +% \GSC[e:y] mechanism also \GTC[f] works quite well \NC in tables \NC \LR +% \stoptabulate +% +% \starttabulate[|c|c|c|] +% \XC[+f:x] this is a small \XC table \NC in which we \NC \FR +% \NC will demonstrate \XC[+g:z] that this \XC[-g] positioning \NC \MR +% \XC[=e:y] mechanism also \XC[-f] works quite well \NC in tables \NC \LR +% \stoptabulate +% +% \starttabulate[|c|c|c|] +% \XC[+f:x,+d:w] this is a small \XC[-d] table \NC in which we \NC \FR +% \NC will demonstrate \XC[+g:z] that this \XC[-g] positioning \NC \MR +% \XC[=e:y] mechanism also \XC[-f] works quite well \NC in tables \NC \LR +% \stoptabulate + +% evt [b:x] +% +% \definepositionframed[x][background=color,fillcolor=red] +% \definepositionframed[y][background=color,fillcolor=green] +% \definepositionframed[z][background=color,fillcolor=blue] + +\def\remappositionframed#1#2% from to + {\copyposition{b:#1}{b:#2}% + \copyposition{e:#1}{e:#2}% + \dosetpositionaction{b:#2}{\dopositionaction{b:#1}}} + +\unexpanded\def\definepositionframed + {\dodoubleargument\dodefinepositionframed} + +\def\dodefinepositionframed[#1][#2]% + {\dosetpositionaction{b:#1}{\dopositionframed[#1][#2]}} + +\def\positionframed + {\dodoubleempty\dopositionframed} + +\def\dopositionframed[#1][#2]% + {\bgroup + \setbox\scratchbox\hbox + {\dimen0=\MPx{e:#1}% + \advance\dimen0 -\MPx{b:#1}% + \dimen2=\MPy{b:#1}% + \advance\dimen2 -\MPy{e:#1}% + \advance\dimen2 \MPd{e:#1}% + \lower\dimen2\hbox + {\advance\dimen2 \MPh{b:#1}% + \framed + [\c!width=\dimen0,\c!height=\dimen2, + \c!offset=\v!overlay,#2]{}}}% + \smashedbox\scratchbox + \egroup} + +% \def\sethdistances#1% +% {\hbox{\lpos{ml:#1}\hpos{mh:#1}{\strut}\rpos{mr:#1}}} +% +% \def\gethdistances#1% +% {\scratchdimen\MPx{mh:#1}% +% \advance\scratchdimen -\MPx{ml#1}% +% \edef\lefthdistance{\the\scratchdimen}% +% \scratchdimen\MPx{mr:#1}% +% \advance\scratchdimen -\MPx{mh:#1}% +% \edef\righthdistance{\the\scratchdimen}} + +\protect \endinput + +% todo 1: shift down option + +% \startuseMPgraphic{mpos:par:columnset} +% \iftracepositions show_multi_pars \else draw_multi_pars \fi ; +% path p ; p := boundingbox currentpicture ; +% currentpicture := currentpicture shifted (0,-StrutDepth/2) ; +% setbounds currentpicture to p ; +% \stopuseMPgraphic + +\definetextbackground[underline] [location=text,alternative=1,background=,frame=off] +\definetextbackground[overstrike] [location=text,alternative=2,background=,frame=off] +\definetextbackground[exlines] [location=text,alternative=3,background=,frame=off] +\definetextbackground[strikethrough][location=text,alternative=4,background=,frame=off] + +\definestartstop [underline] + [before={\starttextbackground[underline]}, + after=\stoptextbackground] + +\definestartstop + [overstrike] + [before={\starttextbackground[overstrike]}, + after=\stoptextbackground] + +\definestartstop + [exlines] + [before={\starttextbackground[exlines]}, + after=\stoptextbackground] + +\definestartstop + [strikethrough] + [before={\starttextbackground[strikethrough]}, + after=\stoptextbackground] + +\definetextbackground + [sideline] + [mp=mpos:par:sideline, + location=paragraph, + framecolor=red, + frameoffset=5mm] + +\definestartstop [sideline] + [before={\starttextbackground[sideline]}, + after=\stoptextbackground] + +\starttext + \startunderline \input tufte \stopunderline \blank + \startoverstrike \input tufte \stopoverstrike \blank + \startexlines \input tufte \stopexlines \blank + \startstrikethrough \input tufte \stopstrikethrough \blank + \startsideline \input tufte \stopsideline \blank +\stoptext diff --git a/tex/context/base/anch-pos.lua b/tex/context/base/anch-pos.lua new file mode 100644 index 000000000..8066af4ce --- /dev/null +++ b/tex/context/base/anch-pos.lua @@ -0,0 +1,166 @@ +if not modules then modules = { } end modules ['anch-pos'] = { + version = 1.001, + comment = "companion to anch-pos.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--[[ldx-- +

We save positional information in the main utility table. Not only +can we store much more information in but it's also +more efficient.

+--ldx]]-- + +local concat, format = table.concat, string.format +local texprint, ctxcatcodes = tex.print, tex.ctxcatcodes +local lpegmatch = lpeg.match + +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 + +-- \the\dimexpr #2\ifnum\positionanchormode=\plusone-\MPx\pageanchor\fi\relax +-- \the\dimexpr #3\ifnum\positionanchormode=\plusone-\MPy\pageanchor\fi\relax + +ptbs, pcol = jobpositions.tobesaved, jobpositions.collected -- global + +local dx, dy = "0pt", "0pt" + +local function initializer() + ptbs, pcol = jobpositions.tobesaved, jobpositions.collected + local p = pcol["page:0"] -- page:1 + if p then +-- to be checked ! +--~ dx, dy = p[2] or "0pt", p[3] or "0pt" + end +end + +job.register('jobpositions.collected', jobpositions.tobesaved, initializer) + +function jobpositions.copy(target,source) + jobpositions.collected[target] = jobpositions.collected[source] or ptbs[source] +end + +function jobpositions.replace(name,...) + jobpositions.collected[name] = {...} +end + +function jobpositions.doifelse(name) + commands.testcase(jobpositions.collected[name] or ptbs[name]) +end + +function jobpositions.MPp(id) local jpi = pcol[id] or ptbs[id] texprint(ctxcatcodes,(jpi and jpi[1]) or '0' ) end +function jobpositions.MPx(id) local jpi = pcol[id] or ptbs[id] texprint(ctxcatcodes,(jpi and jpi[2]) or '0pt') end +function jobpositions.MPy(id) local jpi = pcol[id] or ptbs[id] texprint(ctxcatcodes,(jpi and jpi[3]) or '0pt') end +function jobpositions.MPw(id) local jpi = pcol[id] or ptbs[id] texprint(ctxcatcodes,(jpi and jpi[4]) or '0pt') end +function jobpositions.MPh(id) local jpi = pcol[id] or ptbs[id] texprint(ctxcatcodes,(jpi and jpi[5]) or '0pt') end +function jobpositions.MPd(id) local jpi = pcol[id] or ptbs[id] texprint(ctxcatcodes,(jpi and jpi[6]) or '0pt') end + + +function jobpositions.MPx(id) + local jpi = pcol[id] or ptbs[id] + local x = jpi and jpi[2] + if x then + texprint(ctxcatcodes,format('\\the\\dimexpr%s-%s\\relax',x,dx)) -- no space after dimexpr ! + else + texprint(ctxcatcodes,'0pt') + end +end + +function jobpositions.MPy(id) + local jpi = pcol[id] or ptbs[id] + local y = jpi and jpi[3] + if y then + texprint(ctxcatcodes,format('\\the\\dimexpr%s-%s\\relax',y,dy)) -- no space after dimexpr ! + else + texprint(ctxcatcodes,'0pt') + end +end + +-- the following are only for MP so there we can leave out the pt + +-- can be writes and no format needed any more + +function jobpositions.MPxy(id) + local jpi = pcol[id] or ptbs[id] + if jpi then + texprint(ctxcatcodes,format('(%s-%s,%s-%s)',jpi[2],dx,jpi[3],dy)) +--~ texprint(ctxcatcodes,'(',jpi[2],'-',dx,',',jpi[3],'-',dy,')') + else + texprint(ctxcatcodes,'(0,0)') + end +end + +function jobpositions.MPll(id) + local jpi = pcol[id] or ptbs[id] + if jpi then + texprint(ctxcatcodes,format('(%s-%s,%s-%s-%s)',jpi[2],dx,jpi[3],jpi[6],dy)) +--~ texprint(ctxcatcodes,'(',jpi[2],'-',dx,',',jpi[3],'-',jpi[6],'-',dy,')') + else + texprint(ctxcatcodes,'(0,0)') + end +end + +function jobpositions.MPlr(id) + local jpi = pcol[id] or ptbs[id] + if jpi then + texprint(ctxcatcodes,format('(%s+%s-%s,%s-%s-%s)',jpi[2],jpi[4],dx,jpi[3],jpi[6],dy)) +--~ texprint(ctxcatcodes,'(',jpi[2],'+',jpi[4],'-',dx,',',jpi[3],'-',jpi[6],'-',dy,')') + else + texprint(ctxcatcodes,'(0,0)') + end +end + +function jobpositions.MPur(id) + local jpi = pcol[id] or ptbs[id] + if jpi then + texprint(ctxcatcodes,format('(%s+%s-%s,%s+%s-%s)',jpi[2],jpi[4],dx,jpi[3],jpi[5],dy)) +--~ texprint(ctxcatcodes,'(',jpi[2],'+',jpi[4],'-',dx,',',jpi[3],'+',jpi[5],'-',dy,')') + else + texprint(ctxcatcodes,'(0,0)') + end +end + +function jobpositions.MPul(id) + local jpi = pcol[id] or ptbs[id] + if jpi then + texprint(ctxcatcodes,format('(%s-%s,%s+%s-%s)',jpi[2],dx,jpi[3],jpi[5],dy)) +--~ texprint(ctxcatcodes,'(',jpi[2],'-',dx,',',jpi[3],'+',jpi[5],'-',dy,')') + else + texprint(ctxcatcodes,'(0,0)') + end +end + +function jobpositions.MPpos(id) + local jpi = pcol[id] or ptbs[id] + if jpi then + texprint(ctxcatcodes,concat(jpi,',',1,6)) + else + texprint(ctxcatcodes,'0,0,0,0,0,0') + end +end + +local splitter = lpeg.Ct(lpeg.splitat(",")) + +function jobpositions.MPplus(id,n,default) + local jpi = pcol[id] or ptbs[id] + if not jpi then + texprint(ctxcatcodes,default) + else + local split = jpi[0] + if not split then + split = lpegmatch(splitter,jpi[7]) + jpi[0] = split + end + texprint(ctxcatcodes,split[n] or default) + end +end + +function jobpositions.MPrest(id,default) + local jpi = pcol[id] or ptbs[id] + -- texprint(ctxcatcodes,(jpi and jpi[7] and concat(jpi,",",7,#jpi)) or default) + texprint(ctxcatcodes,(jpi and jpi[7]) or default) +end diff --git a/tex/context/base/anch-pos.mkii b/tex/context/base/anch-pos.mkii new file mode 100644 index 000000000..589c4aa26 --- /dev/null +++ b/tex/context/base/anch-pos.mkii @@ -0,0 +1,877 @@ +%D \module +%D [ file=anch-pos, +%D version=1999.08.01, +%D title=\CONTEXT\ Anchoring 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 Anchoring Macros / Positioning} + +% 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::} + +\def\setpospxy#1#2#3#4% + {\@EA\xdef\csname\POSprefix#1\endcsname + {\number#2,% + \the\dimexpr#3\ifnum\positionanchormode=\plusone-\MPx\pageanchor\fi\relax,% + \the\dimexpr#4\ifnum\positionanchormode=\plusone-\MPy\pageanchor\fi\relax}} + +\def\setpospxywhd#1#2#3#4#5#6#7% + {\@EA\xdef\csname\POSprefix#1\endcsname + {\number#2,% + \the\dimexpr#3\ifnum\positionanchormode=\plusone-\MPx\pageanchor\fi\relax,% + \the\dimexpr#4\ifnum\positionanchormode=\plusone-\MPy\pageanchor\fi\relax,% + \the\dimexpr#5\relax,% + \the\dimexpr#6\relax,% + \the\dimexpr#7\relax}} + +\def\setpospxyplus#1#2#3#4#5#6#7#8% + {\@EA\xdef\csname\POSprefix#1\endcsname + {\number#2,% + \the\dimexpr#3\ifnum\positionanchormode=\plusone-\MPx\pageanchor\fi\relax,% + \the\dimexpr#4\ifnum\positionanchormode=\plusone-\MPy\pageanchor\fi\relax,% + \the\dimexpr#5\relax,% + \the\dimexpr#6\relax,% + \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% + {\@EA\xdef\csname\POSprefix#1\endcsname + {\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 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 + {#1}{#2}{#3}{#4}}}} + +\def\dolazysavepositionwhd#1#2#3#4#5#6#7% tag page x y w h d + {\expanded{\writeutilitycommand{\noexpand\pospxywhd + {#1}{#2}{#3}{#4}{#5}{#6}{#7}}}} + +\def\dolazysavepositionplus#1#2#3#4#5#6#7#8% tag page x y w h d list + {\expanded{\writeutilitycommand{\noexpand\pospxyplus + {#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}}}} + +\def\dosaveposition#1#2#3#4% tag page x y + {\expanded{\immediatewriteutilitycommand{\noexpand\pospxy + {#1}{#2}{#3}{#4}}}} + +\def\dosavepositionwhd#1#2#3#4#5#6#7% tag page x y w h d + {\expanded{\immediatewriteutilitycommand{\noexpand\pospxywhd + {#1}{#2}{#3}{#4}{#5}{#6}{#7}}}} + +\def\dosavepositionplus#1#2#3#4#5#6#7#8% tag page x y w h d list + {\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 } +\def\MPw {\doMPxyhdwlr\doMPw } +\def\MPh {\doMPxyhdwlr\doMPh } +\def\MPd {\doMPxyhdwlr\doMPd } +\def\MPxy {\doMPxyhdwlr\doMPxy } +\def\MPll {\doMPxyhdwlr\doMPll } +\def\MPlr {\doMPxyhdwlr\doMPlr } +\def\MPur {\doMPxyhdwlr\doMPur } +\def\MPul {\doMPxyhdwlr\doMPul } +\def\MPpos{\doMPxyhdwlr\doMPpos} + +\def\doMPp #1,#2,#3,#4,#5,#6,#7\relax{#1} +\def\doMPx #1,#2,#3,#4,#5,#6,#7\relax{#2} +\def\doMPy #1,#2,#3,#4,#5,#6,#7\relax{#3} +\def\doMPw #1,#2,#3,#4,#5,#6,#7\relax{#4} +\def\doMPh #1,#2,#3,#4,#5,#6,#7\relax{#5} +\def\doMPd #1,#2,#3,#4,#5,#6,#7\relax{#6} +\def\doMPxy #1,#2,#3,#4,#5,#6,#7\relax{(#2,#3)} +\def\doMPll #1,#2,#3,#4,#5,#6,#7\relax{(#2,#3-#6)} +\def\doMPlr #1,#2,#3,#4,#5,#6,#7\relax{(#2+#4,#3-#6)} +\def\doMPur #1,#2,#3,#4,#5,#6,#7\relax{(#2+#4,#3+#5)} +\def\doMPul #1,#2,#3,#4,#5,#6,#7\relax{(#2,#3+#5)} +\def\doMPpos#1,#2,#3,#4,#5,#6,#7\relax{#1,#2,#3,#4,#5,#6} + +\def\doMPxyhdwlr#1#2% + {\ifcsname\POSprefix#2\endcsname + \@EA\@EA\@EA#1\csname\POSprefix#2\endcsname,0pt,0pt,0pt,0pt\relax + \else + #10,0pt,0pt,0pt,0pt,0pt,0pt\relax + \fi} + +%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}{}} + +\def\MPdoplus#1#2#3#4% + {\ifcsname\POSprefix#2\endcsname + \@EA\@EA\@EA#1\csname\POSprefix#2\endcsname,,,,,,,,,\relax{#3}% + \else + #4% + \fi} + +\def\doMPplus#1,#2,#3,#4,#5,#6,% + {\dodoMPplus} + +\def\dodoMPplus#1,#2,#3,#4,#5,#6,#7,#8\relax#9% + {\ifcase#9\or#1\or#2\or#3\or#4\or#5\or#6\or#7\else\dododoMPplus#8\relax{#9}\fi} + +\def\dododoMPplus#1,#2,#3,#4,#5,#6,#7,#8\relax#9% + {\ifcase#9\or\or\or\or\or\or\or\or#1\or#2\or#3\or#4\or#5\or#6\or#7\fi} + +\def\doMPrest#1,#2,#3,#4,#5,#6,#7,,#8\relax#9% + {#7} + +%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 + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +%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\enableparpositions % global + {\global\positioningtrue + \global\positioningpartrue} + +\def\disableparpositions % local + {\positioningparfalse} + +\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\!!zerocount} +\def\doifpositionsonthispageelse{\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/anch-pos.mkiv b/tex/context/base/anch-pos.mkiv new file mode 100644 index 000000000..e454747da --- /dev/null +++ b/tex/context/base/anch-pos.mkiv @@ -0,0 +1,784 @@ +%D \module +%D [ file=anch-pos, % was core-pos +%D version=1999.08.01, +%D title=\CONTEXT\ Anchoring 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 Anchoring Macros / Positioning} + +% saveposition : tag page x y +% savepositionwhd : tag page x y w h d +% savepositionplus : tag page x y w h d list +% +% at some point (when we no longer share code) we will move to numbers +% do that we have less garbage collection and hashing +% +% the global table ptbs is equivalent to jobpositions.tobesaved +% +% btw, using a function is more efficient than passing longer code +% snippets to ctxlua + +\registerctxluafile{anch-pos}{1.001} + +% 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. + +% are the next 6 still used? + +\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"}}}} +\def\dolazysavepositionplus#1#2#3#4#5#6#7#8{\normalexpanded{\ctxlatelua{ptbs['#1']={#2,"#3","#4","#5","#6","#7","#8"}}}} +\def\dosaveposition #1#2#3#4{\normalexpanded{\ctxlua {ptbs['#1']={#2,"#3","#4"}}}} +\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\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 + +%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 + +%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. + +% \the\dimexpr\noexpand\lastsavedpositionx\ifnum\positionanchormode=\plusone-\MPx\pageanchor\fi\relax +% \the\dimexpr\noexpand\lastsavedpositiony\ifnum\positionanchormode=\plusone-\MPx\pageanchor\fi\relax + +\def\MPp #1{\ctxlua{jobpositions.MPp("#1")}} +\def\MPx #1{\ctxlua{jobpositions.MPx("#1")}} +\def\MPy #1{\ctxlua{jobpositions.MPy("#1")}} +\def\MPw #1{\ctxlua{jobpositions.MPw("#1")}} +\def\MPh #1{\ctxlua{jobpositions.MPh("#1")}} +\def\MPd #1{\ctxlua{jobpositions.MPd("#1")}} +\def\MPxy #1{\ctxlua{jobpositions.MPxy("#1")}} +\def\MPll #1{\ctxlua{jobpositions.MPll("#1")}} +\def\MPlr #1{\ctxlua{jobpositions.MPlr("#1")}} +\def\MPur #1{\ctxlua{jobpositions.MPur("#1")}} +\def\MPul #1{\ctxlua{jobpositions.MPul("#1")}} +\def\MPpos#1{\ctxlua{jobpositions.MPpos("#1")}} + +%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 +\chardef \parposstrut = 1 % 0 => no strut data, so fall backs used +\newif \iftracepositions + +% we can check for used entries, and if not, then not add one + +\def\enableparpositions % global + {\global\let\registerparoptions\doregisterparoptions + \global\positioningtrue + \global\positioningpartrue} + +\def\disableparpositions % local + {\positioningparfalse} + +\let\registerparoptions\relax + +\def\doregisterparoptions + {\ifpositioningpar \ifpositioning \iftrialtypesetting \else + \ifinpagebody \else \ifmmode \else \ifinformula \else + \ifprocessingverbatim + \iflinepar \dodoregisterparoptions \fi + \else + \dodoregisterparoptions + \fi + \fi \fi \fi + \fi \fi \fi} + +\def\dodoregisterparoptions + {\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\overlappingcheckone#1#2% + {\ifdim#1<\!!dimena \else \ifdim#1>\!!dimenb \else + \ifdim#2<\!!dimenc \else \ifdim#2>\!!dimend \else + \donetrue + \fi\fi + \fi\fi} + +\def\overlappingchecktwo#1#2% + {\ifdim#1<\!!dimene \else \ifdim#1>\!!dimenf \else + \ifdim#2<\!!dimeng \else \ifdim#2>\!!dimenh \else + \donetrue + \fi\fi + \fi\fi} + +\def\doifoverlappingelse#1#2% maybe do this in lua + {\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 + \overlappingcheckone\!!dimene\!!dimeng \ifdone \else + \overlappingcheckone\!!dimene\!!dimenh \ifdone \else + \overlappingcheckone\!!dimenf\!!dimeng \ifdone \else + \overlappingcheckone\!!dimenf\!!dimenh \ifdone \else + \overlappingchecktwo\!!dimena\!!dimenc \ifdone \else + \overlappingchecktwo\!!dimena\!!dimend \ifdone \else + \overlappingchecktwo\!!dimenb\!!dimene \ifdone \else + \overlappingchecktwo\!!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\dododoifpositionsonsamepageelse#1% + {\ifcase\scratchcounter + \scratchcounter\MPp{##}\donetrue + \else + \ifnum\scratchcounter=\MPp{#1}\relax\else\donefalse\fi + \fi}% + +\def\dodoifpositionsonsamepageelse#1#2% + {\begingroup + \scratchcounter#1\donefalse + \rawprocesscommalist[#2]\dododoifpositionsonsamepageelse + \ifdone + \endgroup\expandafter\firstoftwoarguments + \else + \endgroup\expandafter\secondoftwoarguments + \fi} + +\def\doifpositionsonsamepageelse{\dodoifpositionsonsamepageelse\!!zerocount} +\def\doifpositionsonthispageelse{\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/anch-snc.mkii b/tex/context/base/anch-snc.mkii new file mode 100644 index 000000000..cf5b35d69 --- /dev/null +++ b/tex/context/base/anch-snc.mkii @@ -0,0 +1,177 @@ +%D \module +%D [ file=anch-snc, +%D version=2003.12.01, +%D title=\CONTEXT\ Anchoring Macros, +%D subtitle=Synchronization, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 Anchoring Macros / Synchronization} + +\unprotect + +\ifx\s!set \undefined \def\s!set {set} \fi +\ifx\s!reset \undefined \def\s!reset {reset} \fi +\ifx\s!preset \undefined \def\s!preset {preset} \fi +\ifx\s!syncpos\undefined \def\s!syncpos{syncpos} \fi + +\def\definesyncpositions[#1]% + {\setcounter{\s!num:\s!syncpos:#1}{0}% + \doglobal\appendtoksonce\getvalue {\s!reset:\s!syncpos:#1}\to\resetsyncpositions + \doglobal\appendtoksonce\getvalue{\s!preset:\s!syncpos:#1}\to\presetsyncpositions + \setgvalue{\s!syncpos:#1}{sync_n[#1] := 0 ;}% + \setgvalue{\s!set:\s!syncpos:#1}{\dosetsyncpositions{#1}}} + +\def\syncposition + {\dodoubleempty\dosyncposition} + +\def\dosyncposition[#1][#2]% + {\letgvalue{\s!reset:\s!syncpos:#1}\relax + \letgvalue{\s!preset:\s!syncpos:#1}\relax + \dontleavehmode + \dodosyncposition{#1}{#2}\s!set + \ignorespaces} + +\def\doifelselastsyncposition#1#2% + {\doifelse{\lastsyncclass\lastsyncposition}{#1#2}} + +\def\dodosyncposition#1#2#3% + {\letgvalue{\s!reset:\s!syncpos:#1}\relax + \letgvalue{\s!preset:\s!syncpos:#1}\relax + \ifundefined{\s!syncpos:#1}% + \strut + \else + \pluscounter{\s!num:\s!syncpos:#1}% + \setsyncpositions{#1}% + % option: geen w/h, alleen p 0 0 0 data + \setpositionplus + {\s!syncpos:#1:\countervalue{\s!num:\s!syncpos:#1}}% + {#2}% + \hbox{\strut\traceposstring\llap\green{#3/\countervalue{\s!num:\s!syncpos:#1}/#1/#2>>}}% + \fi} + +\def\setsyncpositions#1% + {\enabletextarearegistration + \getvalue {\s!set:\s!syncpos:#1}% + \letgvalue{\s!set:\s!syncpos:#1}\relax} + +\def\dosetsyncpositions#1% + {\startnointerference % removing out of sync can best be done in mp + \!!dimena\maxdimen + \!!counta\zerocount + \!!countc\zerocount + \doloop + {\doifpositionelse{\s!syncpos:#1:\recurselevel} + {\!!dimenb\MPy{\s!syncpos:#1:\recurselevel}\relax + \!!countb\MPp{\s!syncpos:#1:\recurselevel}\relax + \ifnum\!!countb=\!!counta % same page + \ifdim\!!dimenb>\!!dimena + \donefalse % out of order nodes + \else + \donetrue % nodes in order + \fi + \else + \donetrue % different page + \fi + \ifdone + \!!counta\!!countb + \!!dimena\!!dimenb + \advance\!!countc\plusone + \edef\!!stringa{[#1][\the\!!countc]:=}% + \edef\!!stringc{\s!syncpos:#1:\the\!!countc}% + \edef\!!stringd{\MPplus\!!stringc{1}{0}}% + \setxvalue{\s!syncpos:#1}% + {\getsyncpositions{#1}% + sync_p \!!stringa \MPp \!!stringc ; + sync_xy\!!stringa \MPxy\!!stringc ; + sync_w \!!stringa \MPw \!!stringc ; + sync_h \!!stringa \MPh \!!stringc ; + sync_d \!!stringa \MPd \!!stringc ; + \ifx\!!stringd\empty \else sync_t \!!stringa \MPplus\!!stringc{1}{0} ; \fi}% + \fi} + {\setxvalue{\s!syncpos:#1}% + {\getsyncpositions{#1}% + sync_n[#1] := \the\!!countc ;} + \exitloop}}% + \stopnointerference} + +\def\getsyncpositions#1% + {\getvalue{\s!syncpos:#1}} + +\newtoks\resetsyncpositions +\newtoks\presetsyncpositions + +\def\resyncposition {\dodoubleargument\doresyncposition} +\def\presyncposition{\dodoubleargument\dopresyncposition} + +\def\dodoresyncposition #1#2{\dodosyncposition{#1}{#2}\s!reset} +\def\dodopresyncposition#1#2{\dodosyncposition{#1}{#2}\s!preset} + +\def\doresyncposition [#1][#2]{\setxvalue{\s!reset :\s!syncpos:#1}{\noexpand\dodoresyncposition{#1}{#2}}} +\def\dopresyncposition[#1][#2]{\setxvalue{\s!preset:\s!syncpos:#1}{\noexpand\dodopresyncposition{#1}{#2}}} + +\def\flushsyncpositions % this order ! + {\begingroup + \the\presetsyncpositions + \the\resetsyncpositions + \endgroup} + +\def\flushsyncxxsets#1% + {\setbox\scratchbox\hbox{\the#1}% + \ifvoid\scratchbox\else + \prewordbreak \let\prewordbreak\relax % only once + \smashbox\scratchbox + \box\scratchbox + \fi} + +\def\flushsyncresets {\flushsyncxxsets\resetsyncpositions } +\def\flushsyncpresets{\flushsyncxxsets\presetsyncpositions} + +% \appendtoks \flushsyncpositions \to \everypar +% \appendtoks \flushsyncpositions \to \everyheadstart + +% \explicitneverypar -> in grid snapper, eerst testen +% +% \appendtoks \flushsyncpositions \to \neverypar + +\protect \endinput + +\starttext + +\definesyncpositions[1] + +\startuseMPgraphic{sync} + StartPage ; + \getsyncpositions{1} ; + SyncThreshold := 2LineHeight ; + SyncLeftOffset := -.5LeftMarginDistance ; + % SetSyncThreshold(1,3,3LineHeight) ; + SyncWidth := - (BackSpace + SyncLeftOffset) ; + SetSyncColor(1,1,\MPcolor{red}) ; + SetSyncColor(1,2,\MPcolor{green}) ; + SetSyncColor(1,3,\MPcolor{blue}) ; + SetSyncColor(1,4,\MPcolor{yellow}) ; + PrepareSyncTasks(1,true,true,false) ; + for i = 1 upto NOfSyncPaths : + fill SyncPaths[i] + withcolor TheSyncColor(CurrentSyncClass,sync_t[CurrentSyncClass][SyncTasks[i]]) ; + endfor ; + setbounds currentpicture to Page ; + StopPage ; +\stopuseMPgraphic + +\defineoverlay[tempoverlay][\useMPgraphic{sync}] + +\setupbackgrounds[page][background=tempoverlay] + +\syncposition[1][1] \input ward \endgraf +\syncposition[1][2] \input ward \endgraf +\syncposition[1][3] \input ward \endgraf +\syncposition[1][4] \input ward \endgraf + +\stoptext diff --git a/tex/context/base/anch-snc.mkiv b/tex/context/base/anch-snc.mkiv new file mode 100644 index 000000000..f976047c9 --- /dev/null +++ b/tex/context/base/anch-snc.mkiv @@ -0,0 +1,185 @@ +%D \module +%D [ file=anch-snc, +%D version=2003.12.01, +%D title=\CONTEXT\ Anchoring Macros, +%D subtitle=Synchronization, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 can be optimized (will do when used again) + +\writestatus{loading}{ConTeXt Anchoring Macros / Synchronization} + +\unprotect + +\ifx\s!set \undefined \def\s!set {set} \fi +\ifx\s!reset \undefined \def\s!reset {reset} \fi +\ifx\s!preset \undefined \def\s!preset {preset} \fi +\ifx\s!syncpos\undefined \def\s!syncpos{syncpos} \fi + +\unexpanded\def\definesyncpositions[#1]% + {\global\let\flushsyncpositions\doflushsyncpositions % only when used + \setcounter{\s!num:\s!syncpos:#1}{0}% + \doglobal\appendtoksonce\csname\s!reset :\s!syncpos:#1\endcsname\to\resetsyncpositions + \doglobal\appendtoksonce\csname\s!preset:\s!syncpos:#1\endcsname\to\presetsyncpositions +% to be tested: +% \doglobal\expandafter\appendtoksonce\csname\s!reset :\s!syncpos:#1\endcsname\to\resetsyncpositions +% \doglobal\expandafter\appendtoksonce\csname\s!preset:\s!syncpos:#1\endcsname\to\presetsyncpositions + \setgvalue{\s!syncpos:#1}{sync_n[#1] := 0 ;}% + \setgvalue{\s!set:\s!syncpos:#1}{\dosetsyncpositions{#1}}} + +\def\syncposition + {\dodoubleempty\dosyncposition} + +\def\dosyncposition[#1][#2]% + {\letgvalue{\s!reset :\s!syncpos:#1}\relax + \letgvalue{\s!preset:\s!syncpos:#1}\relax + \dontleavehmode + \dodosyncposition{#1}{#2}\s!set + \ignorespaces} + +\def\doifelselastsyncposition#1#2% + {\doifelse{\lastsyncclass\lastsyncposition}{#1#2}} + +\def\dodosyncposition#1#2#3% + {\letgvalue{\s!reset:\s!syncpos:#1}\relax + \letgvalue{\s!preset:\s!syncpos:#1}\relax + \ifcsname\s!syncpos:#1\endcsname + \pluscounter{\s!num:\s!syncpos:#1}% + \setsyncpositions{#1}% + % option: geen w/h, alleen p 0 0 0 data + \setpositionplus + {\s!syncpos:#1:\countervalue{\s!num:\s!syncpos:#1}}% + {#2}% + \hbox{\strut\traceposstring\llap\green{#3/\countervalue{\s!num:\s!syncpos:#1}/#1/#2>>}}% + \else + \strut + \fi} + +\def\setsyncpositions#1% + {\enabletextarearegistration + \getvalue {\s!set:\s!syncpos:#1}% + \letgvalue{\s!set:\s!syncpos:#1}\relax} + +\def\dosetsyncpositions#1% + {\startnointerference % removing out of sync can best be done in mp + \!!dimena\maxdimen + \!!counta\zerocount + \!!countc\zerocount + \doloop + {\doifpositionelse{\s!syncpos:#1:\recurselevel} + {\!!dimenb\MPy{\s!syncpos:#1:\recurselevel}\relax + \!!countb\MPp{\s!syncpos:#1:\recurselevel}\relax + \ifnum\!!countb=\!!counta % same page + \ifdim\!!dimenb>\!!dimena + \donefalse % out of order nodes + \else + \donetrue % nodes in order + \fi + \else + \donetrue % different page + \fi + \ifdone + \!!counta\!!countb + \!!dimena\!!dimenb + \advance\!!countc\plusone + \edef\!!stringa{[#1][\the\!!countc]:=}% + \edef\!!stringc{\s!syncpos:#1:\the\!!countc}% + \edef\!!stringd{\MPplus\!!stringc{1}{0}}% + \setxvalue{\s!syncpos:#1}% + {\getsyncpositions{#1}% + sync_p \!!stringa \MPp \!!stringc ; + sync_xy\!!stringa \MPxy\!!stringc ; + sync_w \!!stringa \MPw \!!stringc ; + sync_h \!!stringa \MPh \!!stringc ; + sync_d \!!stringa \MPd \!!stringc ; + \ifx\!!stringd\empty \else sync_t \!!stringa \MPplus\!!stringc{1}{0} ; \fi}% + \fi} + {\setxvalue{\s!syncpos:#1}% + {\getsyncpositions{#1}% + sync_n[#1] := \the\!!countc ;} + \exitloop}}% + \stopnointerference} + +\def\getsyncpositions#1% + {\getvalue{\s!syncpos:#1}} + +\newtoks\resetsyncpositions +\newtoks\presetsyncpositions + +\def\resyncposition {\dodoubleargument\doresyncposition} +\def\presyncposition{\dodoubleargument\dopresyncposition} + +\def\dodoresyncposition #1#2{\dodosyncposition{#1}{#2}\s!reset} +\def\dodopresyncposition#1#2{\dodosyncposition{#1}{#2}\s!preset} + +\def\doresyncposition [#1][#2]{\setxvalue{\s!reset :\s!syncpos:#1}{\noexpand\dodoresyncposition{#1}{#2}}} +\def\dopresyncposition[#1][#2]{\setxvalue{\s!preset:\s!syncpos:#1}{\noexpand\dodopresyncposition{#1}{#2}}} + +\let\flushsyncpositions\relax + +\def\doflushsyncpositions % this order ! + {\begingroup + \the\presetsyncpositions + \the\resetsyncpositions + \endgroup} + +\def\flushsyncxxsets#1% + {\setbox\scratchbox\hbox{\the#1}% + \ifvoid\scratchbox\else + \prewordbreak \let\prewordbreak\relax % only once + \smashbox\scratchbox + \box\scratchbox + \fi} + +\def\flushsyncresets {\flushsyncxxsets\resetsyncpositions } +\def\flushsyncpresets{\flushsyncxxsets\presetsyncpositions} + +% \appendtoks \flushsyncpositions \to \everypar +% \appendtoks \flushsyncpositions \to \everyheadstart + +% \explicitneverypar -> in grid snapper, eerst testen +% +% \appendtoks \flushsyncpositions \to \neverypar + +\protect \endinput + +\starttext + +\definesyncpositions[1] + +\startuseMPgraphic{sync} + StartPage ; + \getsyncpositions{1} ; + SyncThreshold := 2LineHeight ; + SyncLeftOffset := -.5LeftMarginDistance ; + % SetSyncThreshold(1,3,3LineHeight) ; + SyncWidth := - (BackSpace + SyncLeftOffset) ; + SetSyncColor(1,1,\MPcolor{red}) ; + SetSyncColor(1,2,\MPcolor{green}) ; + SetSyncColor(1,3,\MPcolor{blue}) ; + SetSyncColor(1,4,\MPcolor{yellow}) ; + PrepareSyncTasks(1,true,true,false) ; + for i = 1 upto NOfSyncPaths : + fill SyncPaths[i] + withcolor TheSyncColor(CurrentSyncClass,sync_t[CurrentSyncClass][SyncTasks[i]]) ; + endfor ; + setbounds currentpicture to Page ; + StopPage ; +\stopuseMPgraphic + +\defineoverlay[tempoverlay][\useMPgraphic{sync}] + +\setupbackgrounds[page][background=tempoverlay] + +\syncposition[1][1] \input ward \endgraf +\syncposition[1][2] \input ward \endgraf +\syncposition[1][3] \input ward \endgraf +\syncposition[1][4] \input ward \endgraf + +\stoptext diff --git a/tex/context/base/attr-ini.lua b/tex/context/base/attr-ini.lua new file mode 100644 index 000000000..81c2f4744 --- /dev/null +++ b/tex/context/base/attr-ini.lua @@ -0,0 +1,648 @@ +if not modules then modules = { } end modules ['attr-ini'] = { + version = 1.001, + comment = "companion to attr-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- this module is being reconstructed +-- we can also do the nsnone via a metatable and then also se index 0 + +local type = type +local format, gmatch = string.format, string.gmatch +local concat = table.concat +local texsprint = tex.sprint + +local ctxcatcodes = tex.ctxcatcodes +local unsetvalue = attributes.unsetvalue + +-- todo: document this but first reimplement this as it reflects the early +-- days of luatex / mkiv and we have better ways now + +-- nb: attributes: color etc is much slower than normal (marks + literals) but ... +-- nb. too many "0 g"s + +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 +-- costs more resourses for transparencies. So why bother. + +-- +-- colors +-- + +-- we can also collapse the two attributes: n, n+1, n+2 and then +-- 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 +-- +-- 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 +-- at runtime (after reading from storage). Think of: +-- +-- colors.strings = colors.strings or { } +-- +-- if environment.initex then +-- colors.strings[color] = "return colors." .. colorspace .. "(" .. concat({...},",") .. ")" +-- end +-- +-- storage.register("colors/data", colors.strings, "colors.data") -- evaluated +-- +-- We assume that only processcolors are defined in the format. + +colors = colors or { } +colors.data = colors.data or { } +colors.values = colors.values or { } +colors.registered = colors.registered or { } + +colors.weightgray = true +colors.attribute = attributes.private('color') +colors.selector = attributes.private('colormodel') +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") + +local templates = { + rgb = "r:%s:%s:%s", + cmyk = "c:%s:%s:%s:%s", + gray = "s:%s", + spot = "p:%s:%s:%s:%s" +} + +local models = { + [interfaces.variables.none] = unsetvalue, + black = unsetvalue, + bw = unsetvalue, + all = 1, + gray = 2, + rgb = 3, + cmyk = 4, +} + +colors.model = "all" + +local data = colors.data +local values = colors.values +local registered = colors.registered + +local numbers = attributes.numbers +local list = attributes.list + +local min, max, floor = math.min, math.max, math.floor + +local nodeinjections = backends.nodeinjections +local codeinjections = backends.codeinjections +local registrations = backends.registrations + +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 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 + +-- http://en.wikipedia.org/wiki/HSI_color_space +-- http://nl.wikipedia.org/wiki/HSV_(kleurruimte) + + +local function hsvtorgb(h,s,v) + -- h = h % 360 + local hd = h/60 + local hf = floor(hd) + local hi = hf % 6 + -- local f = hd - hi + local f = hd - hf + local p = v * (1 - s) + local q = v * (1 - f * s) + local t = v * (1 - (1 - f) * s) + if hi == 0 then + return v, t, p + elseif hi == 1 then + return q, v, p + elseif hi == 2 then + return p, v, t + elseif hi == 3 then + return p, q, v + elseif hi == 4 then + return t, p, v + elseif hi == 5 then + return v, p, q + else + print("error in hsv -> rgb",hi,h,s,v) + end +end + +function rgbtohsv(r,g,b) + local offset, maximum, other_1, other_2 + if r >= g and r >= b then + offset, maximum, other_1, other_2 = 0, r, g, b + elseif g >= r and g >= b then + offset, maximum, other_1, other_2 = 2, g, b, r + else + offset, maximum, other_1, other_2 = 4, b, r, g + end + if maximum == 0 then + return 0, 0, 0 + end + local minimum = other_1 < other_2 and other_1 or other_2 + if maximum == minimum then + return 0, 0, maximum + end + local delta = maximum - minimum + return (offset + (other_1-other_2)/delta)*60, delta/maximum, maximum +end + +function graytorgb(s) -- unweighted + return 1-s, 1-s, 1-s +end + +function hsvtogray(h,s,v) + return rgb_to_gray(hsv_to_rgb(h,s,v)) +end + +function grayto_hsv(s) + return 0, 0, s +end + +colors.rgbtocmyk = rgbtocmyk +colors.rgbtogray = rgbtogray +colors.cmyktorgb = cmyktorgb +colors.cmyktogray = cmyktogray +colors.rgbtohsv = rgbtohsv +colors.hsvtorgb = hsvtorgb +colors.hsvtogray = hsvtogray +colors.graytohsv = graytohsv + +-- 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.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.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 = 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 + 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 } +end + +local function graycolor(...) graycolor = nodeinjections.graycolor return graycolor(...) end +local function rgbcolor (...) rgbcolor = nodeinjections.rgbcolor return rgbcolor (...) end +local function cmykcolor(...) cmykcolor = nodeinjections.cmykcolor return cmykcolor(...) end +local function spotcolor(...) spotcolor = nodeinjections.spotcolor return spotcolor(...) end + +local function extender(colors,key) + if key == "none" then + local d = graycolor(0) + colors.none = d + return d + end +end + +local function reviver(data,n) + local v = values[n] + local d + if not v then + local gray = graycolor(0) + d = { gray, gray, gray, gray } + logs.report("attributes","unable to revive color %s",n or "?") + else + local kind = v[1] + if kind == 2 then + local gray= graycolor(v[2]) + d = { gray, gray, gray, gray } + elseif kind == 3 then + local gray, rgb, cmyk = graycolor(v[2]), rgbcolor(v[3],v[4],v[5]), cmykcolor(v[6],v[7],v[8],v[9]) + d = { rgb, gray, rgb, cmyk } + elseif kind == 4 then + local gray, rgb, cmyk = graycolor(v[2]), rgbcolor(v[3],v[4],v[5]), cmykcolor(v[6],v[7],v[8],v[9]) + d = { cmyk, gray, rgb, cmyk } + elseif kind == 5 then + local spot = spotcolor(v[10],v[11],v[12],v[13]) + -- d = { spot, gray, rgb, cmyk } + d = { spot, spot, spot, spot } + end + end + data[n] = d + return d +end + +setmetatable(colors, { __index = extender }) +setmetatable(colors.data, { __index = reviver }) + +function colors.filter(n) + return concat(data[n],":",5) +end + +function colors.setmodel(name,weightgray) + colors.model = name + colors.default = models[name] or 1 + colors.weightgray = weightgray ~= false + return colors.default +end + +function colors.register(name, colorspace, ...) -- passing 9 vars is faster (but not called that often) + local stamp = format(templates[colorspace],...) + local color = registered[stamp] + if not color then + color = #values + 1 + values[color] = colors[colorspace](...) + registered[stamp] = color + -- colors.reviver(color) + end + if name then + list[colors.attribute][name] = color -- not grouped, so only global colors + end + return registered[stamp] +end + +function colors.value(id) + return values[id] +end + +shipouts.handle_color = nodes.install_attribute_handler { + name = "color", + namespace = colors, + initializer = states.initialize, + finalizer = states.finalize, + processor = states.selective, + resolver = function() return colors.main end, +} + +function colors.enable() + tasks.enableaction("shipouts","shipouts.handle_color") +end + +-- transparencies + +transparencies = transparencies or { } +transparencies.registered = transparencies.registered or { } +transparencies.data = transparencies.data or { } +transparencies.values = transparencies.values or { } +transparencies.triggering = true +transparencies.attribute = attributes.private('transparency') + +storage.register("transparencies/registered", transparencies.registered, "transparencies.registered") +storage.register("transparencies/values", transparencies.values, "transparencies.values") + +local registered = transparencies.registered -- we could use a 2 dimensional table instead +local data = transparencies.data +local values = transparencies.values +local template = "%s:%s" + +local function inject_transparency (...) + inject_transparency = nodeinjections.transparency + return inject_transparency(...) +end + +local function register_transparency(...) + register_transparency = registrations.transparency + return register_transparency(...) +end + +function transparencies.register(name,a,t,force) -- name is irrelevant here (can even be nil) + -- Force needed here for metapost converter. We could always force + -- but then we'd end up with transparencies resources even if we + -- would not use transparencies (but define them only). This is + -- somewhat messy. + local stamp = format(template,a,t) + local n = registered[stamp] + if not n then + n = #values + 1 + values[n] = { a, t } + registered[stamp] = n + if force then + register_transparency(n,a,t) + end + elseif force and not data[n] then + register_transparency(n,a,t) + end + return registered[stamp] +end + +local function extender(transparencies,key) + if key == "none" then + local d = inject_transparency(0) + transparencies.none = d + return d + end +end + +local function reviver(data,n) + local v = values[n] + local d + if not v then + d = inject_transparency(0) + else + d = inject_transparency(n) + register_transparency(n,v[1],v[2]) + end + data[n] = d + return d +end + +setmetatable(transparencies, { __index = extender }) +setmetatable(transparencies.data, { __index = reviver }) -- register if used + +-- check if there is an identity + +function transparencies.value(id) + return values[id] +end + +shipouts.handle_transparency = nodes.install_attribute_handler { + name = "transparency", + namespace = transparencies, + initializer = states.initialize, + finalizer = states.finalize, + processor = states.process, +} + +function transparencies.enable() + tasks.enableaction("shipouts","shipouts.handle_transparency") +end + +--- colorintents: overprint / knockout + +colorintents = colorintents or { } +colorintents.data = colorintents.data or { } +colorintents.attribute = attributes.private('colorintent') + +colorintents.registered = { + overprint = 1, + knockout = 2, +} + +local data, registered = colorintents.data, colorintents.registered + +local function extender(colorintents,key) + if key == "none" then + local d = data[2] + colorintents.none = d + return d + end +end + +local function reviver(data,n) + if n == 1 then + local d = nodeinjections.overprint() -- called once + data[1] = d + return d + elseif n == 2 then + local d = nodeinjections.knockout() -- called once + data[2] = d + return d + end +end + +setmetatable(colorintents, { __index = extender }) +setmetatable(colorintents.data, { __index = reviver }) + +function colorintents.register(stamp) + return registered[stamp] or registered.overprint +end + +shipouts.handle_colorintent = nodes.install_attribute_handler { + name = "colorintent", + namespace = colorintents, + initializer = states.initialize, + finalizer = states.finalize, + processor = states.process, +} + +function colorintents.enable() + tasks.enableaction("shipouts","shipouts.handle_colorintent") +end + +--- negative / positive + +negatives = negatives or { } +negatives.data = negatives.data or { } +negatives.attribute = attributes.private("negative") + +negatives.registered = { + positive = 1, + negative = 2, +} + +local data, registered = negatives.data, negatives.registered + +local function extender(negatives,key) + if key == "none" then + local d = data[1] + negatives.none = d + return d + end +end + +local function reviver(data,n) + if n == 1 then + local d = nodeinjections.positive() -- called once + data[1] = d + return d + elseif n == 2 then + local d = nodeinjections.negative() -- called once + data[2] = d + return d + end +end + +setmetatable(negatives, { __index = extender }) +setmetatable(negatives.data, { __index = reviver }) + +function negatives.register(stamp) + return registered[stamp] or registered.positive +end + +shipouts.handle_negative = nodes.install_attribute_handler { + name = "negative", + namespace = negatives, + initializer = states.initialize, + finalizer = states.finalize, + processor = states.process, +} + +function negatives.enable() + tasks.enableaction("shipouts","shipouts.handle_negative") +end + +-- effects -- can be optimized (todo: metatables) + +effects = effects or { } +effects.data = effects.data or { } +effects.values = effects.values or { } +effects.registered = effects.registered or { } +effects.stamp = "%s:%s:%s" +effects.attribute = attributes.private("effect") + +storage.register("effects/registered", effects.registered, "effects.registered") +storage.register("effects/values", effects.values, "effects.values") + +local data, registered, values = effects.data, effects.registered, effects.values + +-- valid effects: normal inner outer both hidden (stretch,rulethickness,effect) + +local function effect(...) effect = nodeinjections.effect return effect(...) end + +local function extender(effects,key) + if key == "none" then + local d = effect(0,0,0) + effects.none = d + return d + end +end + +local function reviver(data,n) + local e = values[n] -- we could nil values[n] now but hardly needed + local d = effect(e[1],e[2],e[3]) + data[n] = d + return d +end + +setmetatable(effects, { __index = extender }) +setmetatable(effects.data, { __index = reviver }) + +function effects.register(effect,stretch,rulethickness) + local stamp = format(effects.stamp,effect,stretch,rulethickness) + local n = registered[stamp] + if not n then + n = #values + 1 + values[n] = { effect, stretch, rulethickness } + registered[stamp] = n + end + return n +end + +shipouts.handle_effect = nodes.install_attribute_handler { + name = "effect", + namespace = effects, + initializer = states.initialize, + finalizer = states.finalize, + processor = states.process, +} + +function effects.enable() + tasks.enableaction("shipouts","shipouts.handle_effect") +end + +-- layers (ugly code, due to no grouping and such); currently we use exclusive layers +-- but when we need it stacked layers might show up too; the next function based +-- approach can be replaced by static (metatable driven) resolvers + +viewerlayers = viewerlayers or { } +viewerlayers.data = viewerlayers.data or { } +viewerlayers.registered = viewerlayers.registered or { } +viewerlayers.values = viewerlayers.values or { } +viewerlayers.listwise = viewerlayers.listwise or { } +viewerlayers.attribute = attributes.private("viewerlayer") + +storage.register("viewerlayers/registered", viewerlayers.registered, "viewerlayers.registered") +storage.register("viewerlayers/values", viewerlayers.values, "viewerlayers.values") + +local data = viewerlayers.data +local values = viewerlayers.values +local listwise = viewerlayers.listwise +local registered = viewerlayers.registered +local template = "%s" + +-- stacked + +local function extender(viewerlayers,key) + if key == "none" then + local d = nodeinjections.stoplayer() + viewerlayers.none = d + return d + end +end + +local function reviver(data,n) + local d = nodeinjections.startlayer(values[n]) + data[n] = d + return d +end + +setmetatable(viewerlayers, { __index = extender }) +setmetatable(viewerlayers.data, { __index = reviver }) + +local function initializer(...) + return states.initialize(...) +end + +viewerlayers.register = function(name,lw) -- if not inimode redefine data[n] in first call + local stamp = format(template,name) + local n = registered[stamp] + if not n then + n = #values + 1 + values[n] = name + registered[stamp] = n + listwise[n] = lw or false + end + return registered[stamp] -- == n +end + +shipouts.handle_viewerlayer = nodes.install_attribute_handler { + name = "viewerlayer", + namespace = viewerlayers, + initializer = initializer, + finalizer = states.finalize, + processor = states.stacked, +} + +function viewerlayers.enable() + tasks.enableaction("shipouts","shipouts.handle_viewerlayer") +end diff --git a/tex/context/base/attr-ini.mkiv b/tex/context/base/attr-ini.mkiv new file mode 100644 index 000000000..87d06c48a --- /dev/null +++ b/tex/context/base/attr-ini.mkiv @@ -0,0 +1,170 @@ +%D \module +%D [ file=attr-ini, +%D version=2007.06.06, +%D title=\CONTEXT\ Attribute Macros, +%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 Attribute Macros / Initialization} + +%D Although it's still somewhat experimental, here we introduce code +%D related to attributes. + +\unprotect + +\registerctxluafile{attr-ini}{1.001} + +%D This might move: + +\def\pushattribute#1% + {\global\advance\csname\??ae:\string#1\endcsname\plusone + \global\expandafter\mathchardef\csname\??ae:\string#1:\number\csname\??ae:\string#1\endcsname\endcsname\attribute#1} + +\def\popattribute#1% + {\attribute#1\csname\??ae:\string#1:\number\csname\??ae:\string#1\endcsname\endcsname + \global\advance\csname\??ae:\string#1\endcsname\minusone} + +\def\installattributestack#1% + {\expandafter\newcount\csname\??ae:\string#1\endcsname} + +%D For the moment we put this here (later it will move to where it's used): + +\definesystemattribute[state] +\definesystemattribute[skip] +\definesystemattribute[penalty] +\definesystemattribute[colormodel][global] \chardef\colormodelattribute \dogetattributeid{colormodel} +\definesystemattribute[color] \chardef\colorattribute \dogetattributeid{color} +\definesystemattribute[transparency] \chardef\transparencyattribute \dogetattributeid{transparency} +\definesystemattribute[background] \chardef\backgroundattribute \dogetattributeid{background} +\definesystemattribute[colorintent] \chardef\colorintentattribute \dogetattributeid{colorintent} +\definesystemattribute[negative] \chardef\negativeattribute \dogetattributeid{negative} +\definesystemattribute[effect] \chardef\effectattribute \dogetattributeid{effect} +\definesystemattribute[viewerlayer] \chardef\viewerlayerattribute \dogetattributeid{viewerlayer} +\definesystemattribute[layoutcomponent] \chardef\layoutcomponentattribute\dogetattributeid{layoutcomponent} +\definesystemattribute[reference] \chardef\referenceattribute \dogetattributeid{reference} +\definesystemattribute[destination] \chardef\destinationattribute \dogetattributeid{destination} +\definesystemattribute[graphicvadjust] \chardef\graphicvadjustattribute \dogetattributeid{graphicvadjust} +\definesystemattribute[ruled] \chardef\ruledattribute \dogetattributeid{ruled} +\definesystemattribute[shifted] \chardef\shiftedattribute \dogetattributeid{shifted} + +% \definesystemattribute[ignore] +% +% \edef\startignorecontent{\dosetattribute{ignore}\plusone} +% \edef\stopignorecontent {\doresetattribute{ignore}} + +% todo: no need for 'color' argument, we can set that once at startup; currently +% a bit inconsistent + +% 1=off 2=gray 3=spot 4=rgb 5=cmyk 6=cmy % only 1/2/4/5 are supported +% +% We could combine this in one attribute but this is not faster and also +% less flexible because sometimes we want to freeze the attribute bit. +% +% Watch out: real color support will be implemented later. + +\newcount\currentcolormodel + +\def\dosetcolormodel#1% + {\currentcolormodel\ctxlua{tex.print(colors.setmodel('#1'))}% + \attribute\colormodelattribute\currentcolormodel} + +\dosetcolormodel{all} + +\appendtoks + \dosetcolormodel{all}% redundant? +\to \everyjob + +\def\registerrgbcolor #1#2#3#4{\ctxlua{colors.register('#1','rgb' ,#2,#3,#4)}} +\def\registercmykcolor#1#2#3#4#5{\ctxlua{colors.register('#1','cmyk',#2,#3,#4,#5)}} +\def\registergraycolor #1#2{\ctxlua{colors.register('#1','gray',#2)}} + +% transparency + +\def\registertransparency#1#2#3% + {\setevalue{(ts:#1)}{\attribute\transparencyattribute\ctxlua{tex.write(transparencies.register(#2,#3))} }} + +\def\sometransparencyswitch#1{\csname(ts:#1)\endcsname} + +\def\sometransparencyswitch + {\ctxlua{transparencies.enable()}% + \gdef\sometransparencyswitch##1{\csname(ts:##1)\endcsname}% + \sometransparencyswitch} + +% \registertransparency {one} {1} {.5} +% \registertransparency {two} {1} {.6} + +% overprint + +\def\registercolorintent#1#2% + {\setevalue{(os:#1)}{\attribute\colorintentattribute\ctxlua{tex.write(colorintents.register('#2'))} }} + +\def\dotriggercolorintent + {\ctxlua{colorintents.enable()}% + \gdef\dotriggercolorintent##1{\csname(os:##1)\endcsname}% + \dotriggercolorintent} + +\registercolorintent{knockout} {knockout} +\registercolorintent{overprint}{overprint} + +\installattributestack\colorintentattribute + +\setevalue{(os:#\v!none}{\attribute\colorintentattribute\attributeunsetvalue} % does this work out ok? + +% negative + +\def\registernegative#1#2% + {\setevalue{(ns:#1)}{\attribute\negativeattribute\ctxlua{tex.write(negatives.register('#2'))} }} + +\def\dotriggernegative + {\ctxlua{negatives.enable()}% + \gdef\dotriggernegative##1{\csname(ns:##1)\endcsname}% + \dotriggernegative} + +\registernegative{positive}{positive} +\registernegative{negative}{negative} + +% effect + +\def\registereffect#1#2#3% #2=stretch #3=rulethickness + {\setxvalue{(es:#1:#2:\number\dimexpr#3\relax)}% + {\attribute\effectattribute\ctxlua{tex.write(effects.register('#1',#2,\number\dimexpr#3\relax))} }} + +\def\dotriggereffect + {\ctxlua{effects.enable()}% + \gdef\dotriggereffect##1##2##3% + {\ifcsname(es:##1:##2:\number\dimexpr##3\relax)\endcsname\else\registereffect{##1}{##2}{##3}\fi + \csname(es:##1:##2:\number\dimexpr##3\relax)\endcsname}% + \dotriggereffect} + +% \registereffect{normal} +% \registereffect{inner} +% \registereffect{outer} +% \registereffect{both} +% \registereffect{hidden} + +% viewerlayers (will probably change a bit) + +% needs to work over stopitemize grouping etc + +\def\registerviewerlayer#1#2% global ! + {\setxvalue{(vl:#1)}{\global\attribute\viewerlayerattribute\ctxlua{tex.write(viewerlayers.register('#2'))} }} + +\setevalue{(vl:)}{\global\attribute\viewerlayerattribute\attributeunsetvalue} + +\def\dotriggerviewerlayer + {\ctxlua{viewerlayers.enable()}% + \gdef\dotriggerviewerlayer##1{\csname(vl:##1)\endcsname}% + \dotriggerviewerlayer} + +\protect \endinput + +% test case +% +% {\green \hbox to \hsize{\leaders\hrule \hfill a}\par} +% {\red \hbox to \hsize{\leaders\hbox{x}\hfill a}\par} diff --git a/tex/context/base/back-ini.lua b/tex/context/base/back-ini.lua new file mode 100644 index 000000000..12a487dd4 --- /dev/null +++ b/tex/context/base/back-ini.lua @@ -0,0 +1,143 @@ +if not modules then modules = { } end modules ['back-ini'] = { + version = 1.001, + comment = "companion to back-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +backends = backends or { } + +local trace_backend = false + +local function nothing() return nil end + +backends.nothing = nothing + +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, + + reference = nothing, + destination = nothing, + +} + +backends.codeinjections = { + + prerollreference = nothing, + + insertmovie = nothing, + insertsound = nothing, + + presetsymbollist = nothing, + registersymbol = nothing, + registeredsymbol = nothing, + + registercomment = nothing, + embedfile = nothing, + attachfile = nothing, + adddocumentinfo = nothing, + setupidentity = nothing, + setpagetransition = nothing, + defineviewerlayer = nothing, + addbookmarks = nothing, + addtransparencygroup = nothing, + + typesetfield = nothing, + doiffieldelse = nothing, + doiffieldgroupelse = nothing, + definefield = nothing, + clonefield = nothing, + definefieldset = nothing, + getfieldgroup = nothing, + setformsmethod = nothing, + getdefaultfieldvalue = nothing, + + setupcanvas = nothing, + + initializepage = nothing, + initializedocument = nothing, + finalizepage = nothing, + finalizedocument = nothing, + + flushpageactions = nothing, + flushdocumentactions = nothing, + + insertrenderingwindow = nothing, + processrendering = nothing, + kindofrendering = nothing, + flushrenderingwindow = nothing, + + setfigurecolorspace = nothing, + setfigurealternative = 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 + local backend = backends[what] + if backend then + if trace_backend then + logs.report("backend", "initializing backend %s (%s)",what,backend.comment or "no comment") + end + backends.current = what + for _, category in next, { "nodeinjections", "codeinjections", "registrations"} do + local plugin = backend[category] + if plugin then + local whereto = backends[category] + for name, meaning in next, whereto do + if plugin[name] then + whereto[name] = plugin[name] + -- logs.report("backend", "installing function %s in category %s of %s",name,category,what) + elseif trace_backend then + logs.report("backend", "no function %s in category %s of %s",name,category,what) + end + end + elseif trace_backend then + logs.report("backend", "no category %s in %s",category,what) + end + end + backends.helpers = backend.helpers + elseif trace_backend then + logs.report("backend", "no backend named %s",what) + end + end +end + +statistics.register("used backend", function() + local bc = backends.current + if bc ~= "unknown" then + return string.format("%s (%s)",bc,backends[bc].comment or "no comment") + else + return nil + end +end) diff --git a/tex/context/base/back-ini.mkiv b/tex/context/base/back-ini.mkiv new file mode 100644 index 000000000..b7bbdb56f --- /dev/null +++ b/tex/context/base/back-ini.mkiv @@ -0,0 +1,168 @@ +%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. + +%D Most will go away here as it is replaced by \LUA\ calls to +%D backend functions. + +\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 + +\ifdefined\everybackendshipout \else \newtoks\everybackendshipout \fi +\ifdefined\everylastbackendshipout \else \newtoks\everylastbackendshipout \fi + +%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. + +\let \dostartrotation \gobbleoneargument +\let \dostoprotation \donothing +\let \dostartscaling \gobbletwoarguments +\let \dostopscaling \donothing +\let \dostartmirroring \donothing +\let \dostopmirroring \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 {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 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 % not yet interfaced in mkiv + +%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}. + +\def\jobsuffix{pdf} + +\ifdefined\resetsystemmode \else + \let\setsystemmode \gobbleoneargument + \let\resetsystemmode\gobbleoneargument +\fi + +\def\setjobsuffix#1% + {\resetsystemmode\jobsuffix + \edef\jobsuffix{#1}% + \setsystemmode\jobsuffix} + +\unexpanded\def\setupoutput[#1]{} % will be command line switch + +\protect \endinput diff --git a/tex/context/base/back-pdf.lua b/tex/context/base/back-pdf.lua new file mode 100644 index 000000000..54e22f1a2 --- /dev/null +++ b/tex/context/base/back-pdf.lua @@ -0,0 +1,469 @@ +if not modules then modules = { } end modules ['back-pdf'] = { + version = 1.001, + comment = "companion to back-pdf.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- we will move code to lpdf-* files (second cleanup stage) + +--[[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, tostring = type, next, tostring +local char, byte, format, gsub, rep, gmatch = string.char, string.byte, string.format, string.gsub, string.rep, string.gmatch +local concat = table.concat +local round = math.round +local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues +local texsprint, texwrite = tex.sprint, tex.write +local ctxcatcodes = tex.ctxcatcodes + +local copy_node = node.copy + +local nodeinjections = backends.pdf.nodeinjections +local codeinjections = backends.pdf.codeinjections +local registrations = backends.pdf.registrations + +local pdfliteral, register = nodes.pdfliteral, nodes.register + +local pdfconstant = lpdf.constant +local pdfstring = lpdf.string +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfreference = lpdf.reference +local pdfverbose = lpdf.verbose +local pdfflushobject = lpdf.flushobject +local pdfreserveobject = lpdf.reserveobject +local pdfannotation = nodes.pdfannotation + +local pdfreserveobj = pdf.reserveobj +local pdfimmediateobj = pdf.immediateobj + +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) -- caching 0/1 does not pay off + return register(pdfliteral(format("%s g %s G",s,s))) +end + +function nodeinjections.spotcolor(n,f,d,p) + if type(p) == "string" then + p = gsub(p,","," ") -- 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 + +local effects = { + normal = 0, + inner = 0, + outer = 1, + both = 2, + hidden = 3, +} + +function nodeinjections.effect(effect,stretch,rulethickness) + -- 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 + +-- cached .. + +local cache = { } + +function nodeinjections.startlayer(name) + local c = cache[name] + if not c then + c = register(pdfliteral(format("/OC /%s BDC",name))) + cache[name] = c + end + return copy_node(c) +end + +local stop = register(pdfliteral("EMC")) + +function nodeinjections.stoplayer() + return copy_node(stop) +end + +local cache = { } + +function nodeinjections.switchlayer(name) + local c = cache[name] + if not c then + c = register(pdfliteral(format("EMC /OC /%s BDC",name))) + end + return copy_node(c) +end + +-- code + +function codeinjections.insertmovie(specification) + -- managed in figure inclusion: width, height, factor, repeat, controls, preview, label, foundname + local width = specification.width + local height = specification.height + local factor = specification.factor or number.dimenfactors.bp + local moviedict = pdfdictionary { + F = specification.foundname, + Aspect = pdfarray { factor * width, factor * height }, + Poster = (specification.preview and true) or false, + } + local controldict = pdfdictionary { + ShowControls = (specification.controls and true) or false, + Mode = (specification["repeat"] and pdfconstant("Repeat")) or nil, + } + local action = pdfdictionary { + Subtype = pdfconstant("Movie"), + Border = pdfarray { 0, 0, 0 }, + T = format("movie %s",specification.label), + Movie = moviedict, + A = controldict, + } + node.write(pdfannotation(width,height,0,action())) +end + +function codeinjections.insertsound(specification) + -- rmanaged in interaction: repeat, label, foundname + local soundclip = interactions.soundclip(specification.label) + if soundclip then + local controldict = pdfdictionary { + Mode = (specification["repeat"] and pdfconstant("Repeat")) or nil + } + local sounddict = pdfdictionary { + F = soundclip.filename + } + local action = pdfdictionary { + Subtype = pdfconstant("Movie"), + Border = pdfarray { 0, 0, 0 }, + T = format("sound %s",specification.label), + Movie = sounddict, + A = controldict, + } + node.write(pdfannotation(0,0,0,action())) + end +end + +-- spot- and indexcolors + +local pdf_separation = pdfconstant("Separation") +local pdf_indexed = pdfconstant("Indexed") +local pdf_device_n = pdfconstant("DeviceN") +local pdf_device_rgb = pdfconstant("DeviceRGB") +local pdf_device_cmyk = pdfconstant("DeviceCMYK") +local pdf_device_gray = pdfconstant("DeviceGray") +local pdf_extgstate = pdfconstant("ExtGState") + +local pdf_rbg_range = pdfarray { 0, 1, 0, 1, 0, 1 } +local pdf_cmyk_range = pdfarray { 0, 1, 0, 1, 0, 1, 0, 1 } +local pdf_gray_range = pdfarray { 0, 1 } + +local rgb_function = "dup %s mul exch dup %s mul exch %s mul" +local cmyk_function = "dup %s mul exch dup %s mul exch dup %s mul exch %s mul" +local gray_function = "%s mul" + +local documentcolorspaces = pdfdictionary() + +local spotcolorhash = { } -- not needed +local spotcolornames = { } +local indexcolorhash = { } +local delayedindexcolors = { } + +function registrations.spotcolorname(name,e) + spotcolornames[name] = e or name +end + +local function registersomespotcolor(name,noffractions,names,p,colorspace,range,funct) + noffractions = tonumber(noffractions) or 1 -- to be checked + if noffractions == 0 then + -- can't happen + elseif noffractions == 1 then + local dictionary = pdfdictionary { + FunctionType = 4, + Domain = { 0, 1 }, + Range = range, + } + local n = pdfimmediateobj("stream",format("{ %s }",funct),dictionary()) + local array = pdfarray { + pdf_separation, + pdfconstant(spotcolornames[name] or name), + colorspace, + pdfreference(n), + } + local m = pdfimmediateobj(tostring(array)) + local mr = pdfreference(m) + spotcolorhash[name] = m + documentcolorspaces[name] = mr + lpdf.adddocumentcolorspace(name,mr) + else + local cnames = pdfarray() + local domain = pdfarray() + for n in gmatch(names,"[^,]+") do + cnames[#cnames+1] = pdfconstant(spotcolornames[n] or n) + domain[#domain+1] = 0 + domain[#domain+1] = 1 + end + local dictionary = pdfdictionary { + FunctionType = 4, + Domain = domain, + Range = range, + } + local n = pdfimmediateobj("stream",format("{ %s %s }",rep("pop ",noffractions),funct),dictionary()) + local array = pdfarray { + pdf_device_n, + cnames, + colorspace, + pdfreference(n), + } + local m = pdfimmediateobj(tostring(array)) + local mr = pdfreference(m) + spotcolorhash[name] = m + documentcolorspaces[name] = mr + lpdf.adddocumentcolorspace(name,mr) + end +end + +function registersomeindexcolor(name,noffractions,names,p,colorspace,range,funct) + noffractions = tonumber(noffractions) or 1 -- to be checked + local cnames = pdfarray() + local domain = pdfarray() + if names == "" then + names = name .. ",None" + else + names = names .. ",None" + end + for n in gmatch(names,"[^,]+") do + cnames[#cnames+1] = pdfconstant(spotcolornames[n] or n) + domain[#domain+1] = 0 + domain[#domain+1] = 1 + end + local dictionary = pdfdictionary { + FunctionType = 4, + Domain = domain, + Range = range, + } + local n = pdfimmediateobj("stream",format("{ %s %s }",rep("exch pop ",noffractions),funct),dictionary()) -- exch pop + local a = pdfarray { + pdf_device_n, + cnames, + colorspace, + pdfreference(n), + } + if p == "" then + p = "1" + else + p = p .. ",1" + end + local pi = { } + for pp in gmatch(p,"[^,]+") do + pi[#pi+1] = tonumber(pp) + end + local vector, set, n = { }, { }, #pi + for i=255,0,-1 do + for j=1,n do + set[j] = format("%02X",round(pi[j]*i)) + end + vector[#vector+1] = concat(set) + end + vector = pdfverbose { "<", concat(vector, " "), ">" } + local n = pdfimmediateobj(tostring(pdfarray{ pdf_indexed, a, 255, vector })) + lpdf.adddocumentcolorspace(format("%s_indexed",name),pdfreference(n)) + return n +end + +-- actually, names (parent) is the hash + +local function delayindexcolor(name,names,func) + local hash = (names ~= "" and names) or name + -- logs.report("index colors","delaying '%s'",name) + delayedindexcolors[hash] = func +end + +local function indexcolorref(name) -- actually, names (parent) is the hash + if not indexcolorhash[name] then + -- logs.report("index colors","registering '%s'",name) + local delayedindexcolor = delayedindexcolors[name] + if type(delayedindexcolor) == "function" then + indexcolorhash[name] = delayedindexcolor() + delayedindexcolors[name] = true + end + end + return indexcolorhash[name] +end + +function registrations.rgbspotcolor(name,noffractions,names,p,r,g,b) +--~ print(name,noffractions,names,p,r,g,b) + if noffractions == 1 then + registersomespotcolor(name,noffractions,names,p,pdf_device_rgb,pdf_rbg_range,format(rgb_function,r,g,b)) + else + registersomespotcolor(name,noffractions,names,p,pdf_device_rgb,pdf_rbg_range,format("%s %s %s",r,g,b)) + end + delayindexcolor(name,names,function() + return registersomeindexcolor(name,noffractions,names,p,pdf_device_rgb,pdf_rgb_range,format(rgb_function,r,g,b)) + end) +end + +function registrations.cmykspotcolor(name,noffractions,names,p,c,m,y,k) + if noffractions == 1 then + registersomespotcolor(name,noffractions,names,p,pdf_device_cmyk,pdf_cmyk_range,format(cmyk_function,c,m,y,k)) + else + registersomespotcolor(name,noffractions,names,p,pdf_device_cmyk,pdf_cmyk_range,format("%s %s %s %s",c,m,y,k)) + end + delayindexcolor(name,names,function() + return registersomeindexcolor(name,noffractions,names,p,pdf_device_cmyk,pdf_cmyk_range,format(cmyk_function,c,m,y,k)) + end) +end + +function registrations.grayspotcolor(name,noffractions,names,p,s) + if noffractions == 1 then + registersomespotcolor(name,noffractions,names,p,pdf_device_gray,pdf_gray_range,format(gray_function,s)) + else + registersomespotcolor(name,noffractions,names,p,pdf_device_gray,pdf_gray_range,s) + end + delayindexcolor(name,names,function() + return registersomeindexcolor(name,noffractions,names,p,pdf_device_gray,pdf_gray_range,format(gray_function,s)) + end) +end + +function registrations.rgbindexcolor(name,noffractions,names,p,r,g,b) + registersomeindexcolor(name,noffractions,names,p,pdf_device_rgb,pdf_rgb_range,format(rgb_function,r,g,b)) +end + +function registrations.cmykindexcolor(name,noffractions,names,p,c,m,y,k) + registersomeindexcolor(name,noffractions,names,p,pdf_device_cmyk,pdf_cmyk_range,format(cmyk_function,c,m,y,k)) +end + +function registrations.grayindexcolor(name,noffractions,names,p,s) + registersomeindexcolor(name,noffractions,names,p,pdf_device_gray,pdf_gray_range,gray_function) +end + +function codeinjections.setfigurecolorspace(data,figure) + local color = data.request.color + if color then + local ref = indexcolorref(color) + if ref then + figure.colorspace = ref + data.used.color = color + end + end +end + +-- transparency + +local transparencies = { [0] = + pdfconstant("Normal"), + pdfconstant("Normal"), + pdfconstant("Multiply"), + pdfconstant("Screen"), + pdfconstant("Overlay"), + pdfconstant("SoftLight"), + pdfconstant("HardLight"), + pdfconstant("ColorDodge"), + pdfconstant("ColorBurn"), + pdfconstant("Darken"), + pdfconstant("Lighten"), + pdfconstant("Difference"), + pdfconstant("Exclusion"), + pdfconstant("Compatible"), +} + +local documenttransparencies = { } +local transparencyhash = { } -- share objects + +local done = false + +function registrations.transparency(n,a,t) + if not done then + local d = pdfdictionary { + Type = pdf_extgstate, + ca = 1, + CA = 1, + BM = transparencies[1], + AIS = false, + } + local m = pdfimmediateobj(tostring(d)) + local mr = pdfreference(m) + transparencyhash[0] = m + documenttransparencies[0] = mr + lpdf.adddocumentextgstate("Tr0",mr) + done = true + end + if n > 0 and not transparencyhash[n] then + local d = pdfdictionary { + Type = pdf_extgstate, + ca = tonumber(t), + CA = tonumber(t), + BM = transparencies[a] or transparencies[0], + AIS = false, + } + local m = pdfimmediateobj(tostring(d)) + local mr = pdfreference(m) + transparencyhash[n] = m + documenttransparencies[n] = mr + lpdf.adddocumentextgstate(format("Tr%s",n),mr) + end +end + +function codeinjections.adddocumentinfo(key,value) + lpdf.addtoinfo(key,lpdf.tosixteen(value)) +end + +-- graphics + +function codeinjections.setfigurealternative(data,figure) + local display = data.request.display + if display and display ~= "" then + local request = data.request + figures.push { + name = request.display, + page = request.page, + size = request.size, + prefix = request.prefix, + cache = request.cache, + width = request.width, + height = request.height, + } + figures.identify() + local displayfigure = figures.check() + if displayfigure then + -- figure.aform = true + img.immediatewrite(figure) + local a = lpdf.array { + lpdf.dictionary { + Image = lpdf.reference(figure.objnum), + DefaultForPrinting = true, + } + } + local d = lpdf.dictionary { + Alternates = lpdf.reference(pdf.immediateobj(tostring(a))), + } + displayfigure.attr = d() + return displayfigure, figures.current() + end + end +end + +-- 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 + +codeinjections.finalizepage = lpdf.finalizepage +codeinjections.finalizedocument = lpdf.finalizedocument + +backends.install("pdf") diff --git a/tex/context/base/back-pdf.mkiv b/tex/context/base/back-pdf.mkiv new file mode 100644 index 000000000..a10afd5b9 --- /dev/null +++ b/tex/context/base/back-pdf.mkiv @@ -0,0 +1,178 @@ +%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} % this will change + +\unprotect + +%D We will minimize the number of calls to \PDF\ specific primitives +%D and delegate all management and injection of code to the backend. +%D +%D Here we initialize some internal quantities. + +\pdfoutput = 1 +\pdfhorigin = 1 true in +\pdfvorigin = 1 true in +\pdfimageresolution = 300 +\pdfpkresolution = 600 +\pdfdecimaldigits = 10 +\pdfinclusionerrorlevel = 0 +\pdfminorversion = 6 % maybe even 7 +%pdfuniqueresname = 1 + +%D This one can be consulted by users although the suffix is also +%D a system mode. + +\setjobsuffix{pdf} + +%D For the moment we keep these. + +\newtoks \pdfbackendeveryximage +\newtoks \pdfbackendeveryxform + +%D These are the only official methods to add stuff to the resources. + +\def\pdfbackendsetcatalog #1#2{\ctxlua{lpdf.addtocatalog ("#1",\!!bs#2\!!es)}} +\def\pdfbackendsetinfo #1#2{\ctxlua{lpdf.addtoinfo ("#1",\!!bs#2\!!es)}} +\def\pdfbackendsetname #1#2{\ctxlua{lpdf.addtonames ("#1",\!!bs#2\!!es)}} + +\def\pdfbackendsetpageattribute #1#2{\ctxlua{lpdf.addtopageattributes ("#1",\!!bs#2\!!es)}} +\def\pdfbackendsetpagesattribute#1#2{\ctxlua{lpdf.addtopagesattributes("#1",\!!bs#2\!!es)}} +\def\pdfbackendsetpageresource #1#2{\ctxlua{lpdf.addtopageresources ("#1",\!!bs#2\!!es)}} + +\def\pdfbackendsetextgstate #1#2{\ctxlua{lpdf.adddocumentextgstate ("#1",lpdf.verbose(\!!bs#2\!!es))}} +\def\pdfbackendsetcolorspace #1#2{\ctxlua{lpdf.adddocumentcolorspace("#1",lpdf.verbose(\!!bs#2\!!es))}} +\def\pdfbackendsetpattern #1#2{\ctxlua{lpdf.adddocumentpattern ("#1",lpdf.verbose(\!!bs#2\!!es))}} +\def\pdfbackendsetshade #1#2{\ctxlua{lpdf.adddocumentshade ("#1",lpdf.verbose(\!!bs#2\!!es))}} + +\def\pdfbackendcurrentresources {\ctxlua{lpdf.collectedresources()}} + +%D Let's block these: + +\let\pdfcatalog \relax \newtoks\pdfcatalog +\let\pdfinfo \relax \newtoks\pdfinfo +\let\pdfnames \relax \newtoks\pdfnames +\let\pdfpageresources\relax \newtoks\pdfpageresources +\let\pdfpageattr \relax \newtoks\pdfpageattr +\let\pdfpagesattr \relax \newtoks\pdfpagesattr + +%D An example of usage is: + +\appendtoks + \pdfbackendsetinfo{ConTeXt.Version}{\contextversion}% + \pdfbackendsetinfo{ConTeXt.Time} {\number\normalyear.\twodigits\normalmonth.\twodigits\normalday\space \twodigits\currenthour:\twodigits\currentminute}% + \pdfbackendsetinfo{ConTeXt.Jobname}{\jobname}% + \pdfbackendsetinfo{ConTeXt.Url} {www.pragma-ade.com}% +\to \everylastbackendshipout + +%D Unfortunately this is still needed (also for \METAPOST\ to +%D \PDF\ converter): + +% \def\doresetmapfilelist +% {\global\let\doresetmapfilelist\relax +% \pdfmapfile{original-empty.map}} +% +% \appendtoksonce \loadallfontmapfiles \to \pdfbackendeveryxform +% \appendtoksonce \loadallfontmapfiles \to \pdfbackendeveryximage + +%D Transformations. Some day we will use primitives (once they're fixed). + +\def\dostartrotation#1% grouped + {\forcecolorhack + \pdfliteral{q \ctxlua{lpdf.rotationcm(#1)}}} + +\def\dostoprotation + {\pdfliteral{Q}} + +\def\dostartscaling#1#2% the test is needed because acrobat is bugged! + {\forcecolorhack + \pdfliteral{q \ifdim#1\points=\zeropoint.0001\else#1\fi\space 0 0 + \ifdim#2\points=\zeropoint.0001\else#2\fi\space 0 0 cm}} + +\def\dostopscaling + {\pdfliteral{Q}} + +\def\dostartmirroring{\pdfliteral{-1 0 0 1 0 0 cm}} +\def\dostopmirroring {\pdfliteral{-1 0 0 1 0 0 cm}} + +\def\dostartclipping#1#2#3% todo (still needed?) + {\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{q 0 w \MPclippath\space W n}} + +\def\dostopclipping + {\pdfliteral{Q n}} + +%D The following will move to the backend \LUA\ code: + +\appendtoks \ctxlua{backends.codeinjections.finalizepage ()}\to \everybackendshipout % is immediate +\appendtoks \ctxlua{backends.codeinjections.finalizedocument()}\to \everylastbackendshipout % is immediate + +%D Temporary hack, will be removed or improved or default. + +\def\TransparencyHack{\ctxlua{backends.codeinjections.addtransparencygroup()}} + +%D \macros +%D {dostartobject,dostopobject,doinsertobject} + +%D This will change: + +\newbox\objectbox + +\def\dostartobject#1#2#3#4#5% + {\bgroup + \setbox\objectbox\vbox\bgroup + \def\dodostopobject{\egroup\doregisterobject{#1}{#2}}} + +\def\dostopobject + {\dodostopobject + \egroup} + +\def\doregisterobject#1#2% + {\the\pdfbackendeveryxform + \finalizeobjectbox\objectbox + \immediate\pdfxform resources {\pdfbackendcurrentresources}\objectbox + \dosetobjectreference{#1}{#2}{\the\pdflastxform}} + +\def\doresetobjects + {} + +\def\doinsertobject#1#2% + {\begingroup + \doifobjectreferencefoundelse{#1}{#2} + {\dogetobjectreference{#1}{#2}\PDFobjectreference\pdfrefxform\PDFobjectreference}% + \donothing + \endgroup} + +\def\doPDFgetobjectpage#1#2#3% + {\dogetobjectreferencepage{#1}{#2}#3% + \ifx#3\empty\def#3{\realfolio}\fi} + +\def\doPDFgetobjectpagereference#1#2#3% + {\dogetobjectreferencepage{#1}{#2}#3% + \doPDFgetpagereference{\ifx#3\empty\realfolio\else#3\fi}#3} + +\let\lastpredefinedsymbol\empty % some day we can do more at the lua end + +\def\predefinesymbol[#1]% + {\begingroup + \xdef\lastpredefinedsymbol{#1}% + \settightobject{SYM}{#1}\hbox{\symbol[#1]}% to be checked ... maybe only fitting + \dogetobjectreference{SYM}{#1}\lastref + \ctxlua{backends.codeinjections.registersymbol("#1",\lastref)}% + \endgroup} + +\protect \endinput diff --git a/tex/context/base/back-u3d.mkiv b/tex/context/base/back-u3d.mkiv new file mode 100644 index 000000000..398159feb --- /dev/null +++ b/tex/context/base/back-u3d.mkiv @@ -0,0 +1,156 @@ +%D \module +%D [ file=back-u3d, +%D version=2009.04.15, +%D title=\CONTEXT\ Backend Macros, +%D subtitle=U3D Experiment, +%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. + +% This is only a placeholder that demonstrates the usage of u3d +% resources. The user interface is rather messy an might be +% improved. The files and setup is derived from an example by +% Michael Vidiassov. + +\endinput + +\starttext + +\startluaparameterset [u3d:myset:controls:1] + view = { + name = 'default', + bg = {1,1,1}, + mag = 100, + coo = {0,0,0}, + c2c = {0,0,1}, + rot = {40,0,60}, + roo = 6, + lights = 'CAD' + }, + js = 'cloudq.js' +\stopluaparameterset + +\startluaparameterset [u3d:myset:controls:2] + views = { + { + name = 'AnglePositioning', + bg = {1,1,1}, + azimuth = 45, + altitude = 45, + roo = 50, + aac = 2.5, + lights = 'Artwork' + }, + { + name = 'RotationPositioning', + bg = {1,1,1}, + rot = {0,45,45}, + roo = 50, + aac = 2.5, + lights = 'Artwork' + }, + { + name = 'VectorPositioning', + bg = {1,0,0}, + c2c = {1,1,math.sqrt(2)}, + roo = 50, + aac = 2.5, + lights = 'CAD' + }, + { + name = 'PositionPositioning', + bg = {1,0,0}, + pos = {1+25,1+25,1+50/math.sqrt(2)}, + aac = 2.5, + lights = 'CAD' + }, + { + name = 'ortho', + bg = {1,1,1}, + mag = 300, + lights = 'CAD', + crossection = {} + } + }, + view = { + name = 'default', + bg = {1,1,1}, + c2c = {-1,-1,0}, + roo = 50, + aac = 2.5, + roll = 45, + lights = 'CAD', + crossection = { + normal = {-1,-1,-1}, + transparent = true + }, + nodes = { + { + name = 'xlabel', + visible = false + }, + { + name = 'ylabel', + opacity = 0.5 + }, + { + name = 'zlabel', + rendermode = 'Wireframe' + } + } + } +\stopluaparameterset + +\useexternalfigure + [cloudq] + [cloudq.u3d] + [width=0.7\textwidth, + height=.7\textwidth, + display=u3d:myset:display:1, + controls=u3d:myset:controls:1] + +\useexternalfigure + [axes] + [axes.u3d] + [width=0.7\textwidth, + height=.7\textwidth, + controls=u3d:myset:controls:1] + +\startluaparameterset[u3d:myset:display:2] + toolbar = true, + preview = 'cloudq.png' +\stopluaparameterset +\startluaparameterset[u3d:myset:display:3] + toolbar = true, + tree = false, + preview = 'area.png' +\stopluaparameterset +\startluaparameterset[u3d:myset:display:4] + toolbar = true, + tree = false, + view = { + name = 'view', + bg = {0.1,0.1,0.1}, + c2c = {-1,-1,0}, + roo = 50, + aac = 2.5, + roll = 45, + lights = 'Red' + } +\stopluaparameterset +\startluaparameterset[u3d:myset:display:5] + toolbar = true, + tree = false, + view = 'ortho' +\stopluaparameterset + +\placefigure[here]{none}{\externalfigure[cloudq][display=u3d:myset:display:2]} +\placefigure[here]{none}{\externalfigure[axes] [display=u3d:myset:display:3]} +\placefigure[here]{none}{\externalfigure[axes] [display=u3d:myset:display:4]} +\placefigure[here]{none}{\externalfigure[axes] [display=u3d:myset:display:5,width=0.5\textwidth,height=.5\textwidth]} + +\stoptext diff --git a/tex/context/base/bibl-bib.lua b/tex/context/base/bibl-bib.lua new file mode 100644 index 000000000..3c0dad2fa --- /dev/null +++ b/tex/context/base/bibl-bib.lua @@ -0,0 +1,762 @@ +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 utf = unicode.utf8 +local lower, format, gsub, concat = string.lower, string.format, string.gsub, table.concat +local next = next +local utfchar = utf.char +local lpegmatch = lpeg.match +local textoutf = characters and characters.tex.toutf +local variables = interfaces and interfaces.variables + +local finalizers = xml.finalizers.tex +local xmlfilter, xmltext = xml.filter, xml.text + +local trace_bibxml = false trackers.register("publications.bibxml", function(v) trace_bibtex = v end) + +bibtex = bibtex or { } + +bibtex.size = 0 +bibtex.definitions = 0 +bibtex.shortcuts = 0 + +local defaultshortcuts = { + jan = "1", + feb = "2", + mar = "3", + apr = "4", + may = "5", + jun = "6", + jul = "7", + aug = "8", + sep = "9", + oct = "10", + nov = "11", + dec = "12", +} + +local shortcuts = { } +local data = { } +local entries + +-- Currently we expand shortcuts and for large ones (like the acknowledgements +-- in tugboat.bib this is not that efficient. However, eventually strings get +-- hashed again. + +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 defaultshortcuts[s] or s -- can be number +end + +local P, R, S, C, Cc, Cs, Ct = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct + +local percent = P("%") +local start = P("@") +local comma = P(",") +local hash = P("#") +local escape = P("\\") +local single = P("'") +local double = P('"') +local left = P('{') +local right = P('}') +local both = left + right +local lineending = S("\n\r") +local space = S(" \t\n\r\f") +local spacing = space^0 +local equal = P("=") +local collapsed = (space^1)/ " " + +local function add(a,b) if b then return a..b else return a end end + +local keyword = C((lpeg.R("az","AZ","09") + 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.patterns.balanced + +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 = 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 + session.size = session.size + #content + lpegmatch(grammar,content or "") + statistics.stoptiming(bibtex) +end + +function bibtex.load(session,filename) + local filename = resolvers.find_file(filename,"bib") + if filename ~= "" then + local data = io.loaddata(filename) or "" + if data == "" then + logs.report("publications","empty file '%s', no conversion to xml",filename) + elseif trace_bibxml then + logs.report("publications","converting file '%s' to xml",filename) + end + bibtex.convert(session,data) + end +end + +function bibtex.new() + return { + data = { }, + shortcuts = { }, + xml = xml.convert("\n"), + size = 0, + entries = nil, + loaded = false, + } +end + +local escaped_pattern = xml.escaped_pattern + +local ihatethis = { + f = "\\f", + n = "\\n", + r = "\\r", + s = "\\s", + t = "\\t", + v = "\\v", + z = "\\z", +} + +local command = P("\\")/"" * Cc("\\bibtexcommand{") * (R("az","AZ")^1) * Cc("}") +local any = P(1) +local done = P(-1) +local one_l = P("{") / "" +local one_r = P("}") / "" +local two_l = P("{{") / "" +local two_r = P("}}") / "" + +local filter = Cs( + two_l * (command + any - two_r - done)^0 * two_r * done + + one_l * (command + any - one_r - done)^0 * one_r * done + + (command + any )^0 +) + +function bibtex.toxml(session,options) + if session.loaded then + return + else + session.loaded = true + end + -- we can always speed this up if needed + -- format slows down things a bit but who cares + statistics.starttiming(bibtex) + local result = { } + local options = aux.settings_to_hash(options) + local convert = options.convert -- todo: interface + local strip = options.strip -- todo: interface + local entries = session.entries + result[#result+1] = format("") + result[#result+1] = format("") + for id, categories in next, session.data do + id = lower(gsub(id,"^@","")) + for name, entry in next, categories do + if not entries or entries[name] then + result[#result+1] = format("",lower(name),id) + for key, value in next, entry do + value = gsub(value,"\\(.)",ihatethis) + value = lpegmatch(escaped_pattern,value) + + if value ~= "" then + if convert then + value = textoutf(value,true) + end + if strip then + -- as there is no proper namespace in bibtex we need this + -- kind of hackery ... bibtex databases are quite unportable + value = lpegmatch(filter,value) or value + end + result[#result+1] = format(" %s",key,value) + end + end + result[#result+1] = format("") + end + end + end + result[#result+1] = format("") + result = concat(result,"\n") + -- alternatively we could use lxml.convert + session.xml = xml.convert(result, { + resolve_entities = true, + resolve_predefined_entities = true, -- in case we have escaped entities + -- unify_predefined_entities = true, -- & -> & + utfize_entities = true, + } ) + session.data = nil + session.shortcuts = nil + 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)) + +if not characters then dofile(resolvers.find_file("char-def.lua")) end + +local chardata = characters.data +local concat = table.concat + +local P, Ct, lpegmatch = lpeg.P, lpeg.Ct, lpeg.match + +local space, comma = P(" "), P(",") + +local andsplitter = Ct(lpeg.splitat(space^1 * "and" * space^1)) +local commasplitter = Ct(lpeg.splitat(space^0 * comma * space^0)) +local spacesplitter = Ct(lpeg.splitat(space^1)) +local firstcharacter = lpeg.patterns.utf8byte + +function is_upper(str) + local first = lpegmatch(firstcharacter,str) + local okay = chardata[first] + return okay and okay.category == "lu" +end + +local function splitauthors(str) + local authors = lpegmatch(andsplitter,str) + for i=1,#authors do + local firstnames, vons, surnames, initials, juniors, words + local author = authors[i] + local split = lpegmatch(commasplitter,author) + local n = #split + if n == 1 then + --~ First von Last + words = lpegmatch(spacesplitter,author) + firstnames, vons, surnames = { }, { }, { } + local i, n = 1, #words + while i <= n do + local w = words[i] + if is_upper(w) then + firstnames[#firstnames+1], i = w, i + 1 + else + break + end + end + while i <= n do + local w = words[i] + if is_upper(w) then + break + else + vons[#vons+1], i = w, i + 1 + end + end + while i <= n do + surnames[#surnames+1], i = words[i], i + 1 + end + elseif n == 2 then + --~ von Last, First + words = lpegmatch(spacesplitter,split[2]) + surnames = lpegmatch(spacesplitter,split[1]) + firstnames, vons = { }, { } + local i, n = 1, #words + while i <= n do + local w = words[i] + if is_upper(w) then + firstnames[#firstnames+1], i = w, i + 1 + else + break + end + end + while i <= n do + vons[#vons+1], i = words[i], i + 1 + end + else + --~ von Last, Jr ,First + firstnames = lpegmatch(spacesplitter,split[1]) + juniors = lpegmatch(spacesplitter,split[2]) + surnames = lpegmatch(spacesplitter,split[3]) + if n > 3 then + -- error + end + end + if #surnames == 0 then + surnames[1] = firstnames[#firstnames] + firstnames[#firstnames] = nil + end + if firstnames then + initials = { } + for i=1,#firstnames do + initials[i] = utfchar(lpegmatch(firstcharacter,firstnames[i])) + end + end + authors[i] = { + original = author, + firstnames = firstnames, + vons = vons, + surnames = surnames, + initials = initials, + juniors = juniors, + } + end + authors.original = str + return authors +end + +local function the_initials(initials,symbol) + local t, symbol = { }, symbol or "." + for i=1,#initials do + t[i] = initials[i] .. symbol + end + return t +end + +-- authors + +bibtex.authors = bibtex.authors or { } + +local authors = bibtex.authors + +local defaultsettings = { + firstnamesep = " ", + vonsep = " ", + surnamesep = " ", + juniorsep = " ", + surnamejuniorsep = ", ", + juniorjuniorsep = ", ", + surnamefirstnamesep = ", ", + surnameinitialsep = ", ", + namesep = ", ", + lastnamesep = " and ", + finalnamesep = " and ", +} + +function authors.normal(author,settings) + local firstnames, vons, surnames, juniors = author.firstnames, author.vons, author.surnames, author.juniors + local result, settings = { }, settings or defaultsettings + if firstnames and #firstnames > 0 then + result[#result+1] = concat(firstnames," ") + result[#result+1] = settings.firstnamesep or defaultsettings.firstnamesep + end + if vons and #vons > 0 then + result[#result+1] = concat(vons," ") + result[#result+1] = settings.vonsep or defaultsettings.vonsep + end + if surnames then + result[#result+1] = concat(surnames," ") + end + if juniors and #juniors > 0 then + result[#result+1] = concat(juniors," ") + result[#result+1] = settings.surnamesep or defaultsettings.surnamesep + end + return concat(result) +end + +function authors.normalshort(author,settings) + local firstnames, vons, surnames, juniors = author.firstnames, author.vons, author.surnames, author.juniors + local result, settings = { }, settings or defaultsettings + if firstnames and #firstnames > 0 then + result[#result+1] = concat(firstnames," ") + result[#result+1] = settings.firstnamesep or defaultsettings.firstnamesep + end + if vons and #vons > 0 then + result[#result+1] = concat(vons," ") + result[#result+1] = settings.vonsep or defaultsettings.vonsep + end + if surnames then + result[#result+1] = concat(surnames," ") + end + if juniors and #juniors > 0 then + result[#result+1] = concat(juniors," ") + result[#result+1] = settings.surnamejuniorsep or defaultsettings.surnamejuniorsep + end + return concat(result) +end + +function authors.inverted(author,settings) + local firstnames, vons, surnames, juniors = author.firstnames, author.vons, author.surnames, author.juniors + local result, settings = { }, settings or defaultsettings + if vons and #vons > 0 then + result[#result+1] = concat(vons," ") + result[#result+1] = settings.vonsep or defaultsettings.vonsep + end + if surnames then + result[#result+1] = concat(surnames," ") + end + if juniors and #juniors > 0 then + result[#result+1] = settings.juniorjuniorsep or defaultsettings.juniorjuniorsep + result[#result+1] = concat(juniors," ") + end + if firstnames and #firstnames > 0 then + result[#result+1] = settings.surnamefirstnamesep or defaultsettings.surnamefirstnamesep + result[#result+1] = concat(firstnames," ") + end + return concat(result) +end + +function authors.invertedshort(author,settings) + local vons, surnames, initials, juniors = author.vons, author.surnames, author.initials, author.juniors + local result, settings = { }, settings or defaultsettings + if vons and #vons > 0 then + result[#result+1] = concat(vons," ") + result[#result+1] = settings.vonsep or defaultsettings.vonsep + end + if surnames then + result[#result+1] = concat(surnames," ") + end + if juniors and #juniors > 0 then + result[#result+1] = settings.juniorjuniorsep or defaultsettings.juniorjuniorsep + result[#result+1] = concat(juniors," ") + end + if initials and #initials > 0 then + result[#result+1] = settings.surnameinitialsep or defaultsettings.surnameinitialsep + result[#result+1] = concat(the_initials(initials)," ") + end + return concat(result) +end + +local lastconcatsize = 1 + +local function bibtexconcat(t,settings) + local namesep = settings.namesep or defaultsettings.namesep or ", " + local lastnamesep = settings.lastnamesep or defaultsettings.lastnamesep or namesep + local finalnamesep = settings.finalnamesep or defaultsettings.finalnamesep or lastnamesep + local lastconcatsize = #t + if lastconcatsize > 2 then + local s = { } + for i=1,lastconcatsize-2 do + s[i] = t[i] .. namesep + end + s[lastconcatsize-1], s[lastconcatsize] = t[lastconcatsize-1] .. finalnamesep, t[lastconcatsize] + return concat(s) + elseif lastconcatsize > 1 then + return concat(t,lastnamesep) + elseif lastconcatsize > 0 then + return t[1] + else + return "" + end +end + +function authors.concat(author,combiner,what,settings) + if type(combiner) == "string" then + combiner = authors[combiner or "normal"] or authors.normal + end + local split = splitauthors(author) + local setting = settings[what] + local etallimit, etaldisplay, etaltext = 1000, 1000, "" + if setting then + etallimit = settings.etallimit or 1000 + etaldisplay = settings.etaldisplay or etallimit + etalltext = settings.etaltext or "" + end + local max = #split + if max > etallimit and etaldisplay < max then + max = etaldisplay + end + for i=1,max do + split[i] = combiner(split[i],settings) + end + local result = bibtexconcat(split,settings) + if max < #split then + return result + else + return result .. etaltext + end +end + +function authors.short(author,year) + local result = { } + if author then + local authors = splitauthors(author) + for a=1,#authors do + local aa = authors[a] + local initials = aa.initials + for i=1,#initials do + result[#result+1] = initials[i] + end + local surnames = aa.surnames + for s=1,#surnames do + result[#result+1] = utfchar(lpegmatch(firstcharacter,surnames[s])) + end + end + end + if year then + result[#result+1] = year + end + return concat(result) +end + +-- We can consider creating a hashtable key -> entry but I wonder if +-- pays off. + +local function collectauthoryears(id,list) + list = aux.settings_to_hash(list) + id = lxml.get_id(id) + local found = { } + for e in xml.collected(id,"/bibtex/entry") do + if list[e.at.tag] then + local year = xmlfilter(e,"xml:///field[@name='year']/text()") + local author = xmlfilter(e,"xml:///field[@name='author']/text()") + if author and year then + local a = found[author] + if not a then + a = { } + found[author] = a + end + local y = a[year] + if not y then + y = { } + a[year] = y + end + y[#y+1] = e + end + end + end + -- found = { author = { year_1 = { e1, e2, e3 } } } + local done = { } + for author, years in next, found do + local yrs = { } + for year, entries in next, years do + if subyears then + -- -- add letters to all entries of an author and if so shouldn't + -- -- we tag all years of an author as soon as we do this? + -- if #entries > 1 then + -- for i=1,#years do + -- local entry = years[i] + -- -- years[i] = year .. string.char(i + string.byte("0") - 1) + -- end + -- end + else + yrs[#yrs+1] = year + end + end + done[author] = yrs + end + return done +end + +local method, settings = "normal", { } + +function authors.setsettings(s) + settings = s or settings +end + +if commands then + + local texsprint = tex and tex.sprint + local ctxcatcodes = tex and tex.ctxcatcodes + + local sessions = { } + + function commands.definebibtexsession(name) + sessions[name] = bibtex.new() + end + + function commands.preparebibtexsession(name,xmlname,options) + bibtex.toxml(sessions[name],options) + lxml.register(xmlname,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 } -- here we can keep more info + else + entries[entry] = true + end + end + + -- commands.bibtexconcat = bibtexconcat + + -- finalizers can be rather dumb as we have just text and no embedded xml + + function finalizers.bibtexconcat(collected,method,what) + if collected then + local author = collected[1].dt[1] or "" + if author ~= "" then + texsprint(ctxcatcodes,authors.concat(author,method,what,settings)) + end + end + end + + function finalizers.bibtexshort(collected) + if collected then + local c = collected[1] + local year = xmlfilter(c,"xml://field[@name='year']/text()") + local author = xmlfilter(c,"xml://field[@name='author']/text()") + texsprint(ctxcatcodes,authors.short(author,year)) + end + end + + -- experiment: + + --~ -- alternative approach: keep data at the tex end + + --~ local function xbibtexconcat(t,sep,finalsep,lastsep) + --~ local n = #t + --~ if n > 0 then + --~ context(t[1]) + --~ if n > 1 then + --~ if n > 2 then + --~ for i=2,n-1 do + --~ context.bibtexpublicationsparameter("sep") + --~ context(t[i]) + --~ end + --~ context.bibtexpublicationsparameter("finalsep") + --~ else + --~ context.bibtexpublicationsparameter("lastsep") + --~ end + --~ context(t[n]) + --~ end + --~ end + --~ end + + -- todo : sort + + -- todo: choose between bibtex or commands namespace + + function bibtex.authorref(id,list) + local result = collectauthoryears(id,list,method,what) + for author, years in next, result do + texsprint(ctxcatcodes,authors.concat(author,method,what,settings)) + end + end + + function bibtex.authoryearref(id,list) + local result = collectauthoryears(id,list,method,what) + for author, years in next, result do + texsprint(ctxcatcodes,authors.concat(author,method,what,settings)," (",concat(years,", "),")") + end + end + + function bibtex.authoryearsref(id,list) + local result = collectauthoryears(id,list,method,what) + for author, years in next, result do + texsprint(ctxcatcodes,"(",authors.concat(author,method,what,settings),", ",concat(years,", "),")") + end + end + + function bibtex.singular_or_plural(singular,plural) + if lastconcatsize and lastconcatsize > 1 then + texsprint(ctxcatcodes,plural) + else + texsprint(ctxcatcodes,singular) + end + end +end + + +--~ local function test(sample) +--~ local authors = splitauthors(sample) +--~ print(table.serialize(authors)) +--~ for i=1,#authors do +--~ local author = authors[i] +--~ print(normalauthor (author,settings)) +--~ print(normalshortauthor (author,settings)) +--~ print(invertedauthor (author,settings)) +--~ print(invertedshortauthor(author,settings)) +--~ end +--~ print(concatauthors(sample,settings,normalauthor)) +--~ print(concatauthors(sample,settings,normalshortauthor)) +--~ print(concatauthors(sample,settings,invertedauthor)) +--~ print(concatauthors(sample,settings,invertedshortauthor)) +--~ end + +--~ local sample_a = "Hagen, Hans and Hoekwater, Taco Whoever T. Ex. and Henkel Hut, Hartmut Harald von der" +--~ local sample_b = "Hans Hagen and Taco Whoever T. Ex. Hoekwater and Hartmut Harald von der Henkel Hut" + +--~ test(sample_a) +--~ test(sample_b) diff --git a/tex/context/base/bibl-bib.mkiv b/tex/context/base/bibl-bib.mkiv new file mode 100644 index 000000000..10abe5cb8 --- /dev/null +++ b/tex/context/base/bibl-bib.mkiv @@ -0,0 +1,962 @@ +%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 / Experimental BibTeX} + +\registerctxluafile{bibl-bib}{1.001} + +\unprotect + +% todo: et al limiters +% todo: split: citationvariant and publicationvariant + +%D This interface is under development. As I don't use \BIBTEX\ myself I need +%D some motivation to spend time on it, and an occasional question on the +%D list can be a reason. A few examples. As \BIBTEX\ databases can be poluted +%D by local commands, we need to catch: +%D +%D \startbuffer +%D \defbibtexcommand\MF {MF} +%D \defbibtexcommand\MP {MP} +%D \defbibtexcommand\TUB {TUGboat} +%D \defbibtexcommand\Mc {Mac} +%D \defbibtexcommand\sltt{\tt} +%D \defbibtexcommand\<#1>{\type{#1}} +%D \defbibtexcommand\acro#1{#1} +%D \stopbuffer +%D +%D \typebuffer +%D +%D Let's define a session and load a few databases. We convert to \UTF\ and +%D strip commands. +%D +%D \startbuffer +%D \definebibtexsession [somebibtex] +%D \registerbibtexfile [somebibtex] [tugboat.bib] +%D \registerbibtexfile [somebibtex] [komoedie.bib] +%D \preparebibtexsession [somebibtex] [convert,strip] +%D \stopbuffer +%D +%D \typebuffer +%D +%D This loads an mapping (work in progress): +%D +%D \startbuffer +%D \def\currentbibtexformat{apa} \input bxml-\currentbibtexformat.mkiv +%D \stopbuffer +%D +%D \typebuffer +%D +%D There are several ways to handle the \XML. It helps if you're a bit +%D familiar with \XML\ processing in \MKIV. +%D +%D Here we regular setups. Three elements are mapped but only one +%D is actually used and applied to root element \type {/bibtex}. +%D +%D \startbuffer +%D \startxmlsetups bibtex +%D \xmlregistereddocumentsetups{#1}{} +%D \xmlsetsetup{#1}{bibtex|entry|field}{bibtex:*} +%D \xmlmain{#1} +%D \stopxmlsetups +%D +%D \startxmlsetups bibtex:bibtex +%D \xmlfilter{#1}{ +%D /entry[@category='article'] +%D /field[@name='author' and (find(text(),'Hagen') or find(text(),'Hoekwater'))] +%D /../command(bibtex:format) +%D } +%D \stopxmlsetups +%D +%D \applytobibtexsession[somebibtex][bibtex] +%D \stopbuffer +%D +%D \typebuffer +%D +%D A simpler setup is given next. Here we just apply a setup to the root +%D element directly: +%D +%D \startbuffer +%D \startxmlsetups bibtex:list +%D \xmlfilter{#1}{/bibtex/entry/command(bibtex:format)} +%D \stopxmlsetups +%D +%D \applytobibtexsession[somebibtex][bibtex:list] +%D \stopbuffer +%D +%D \typebuffer +%D +%D A slightly more complex expression: +%D +%D \startbuffer +%D \startxmlsetups bibtex:filter +%D \xmlfilter{#1}{ +%D /bibtex +%D /entry[@category='article'] +%D /field[@name='author' and (find(text(),'Hagen') or find(text(),'Hoekwater'))] +%D /../command(bibtex:format) +%D } +%D \stopxmlsetups +%D +%D \applytobibtexsession[somebibtex][bibtex:filter] +%D \stopbuffer +%D +%D \typebuffer + +\newtoks \everydefinebibtexsession +\newtoks \everypreparebibtexsession +\newtoks \everysetupbibtexsession +\setfalse \tracebibtexformat + +\unexpanded\def\definebibtexsession {\dosingleargument\dodefinebibtexsession} +\def\preparebibtexsession {\dodoubleempty \dopreparebibtexsession} +\unexpanded\def\setupbibtexsession {\dodoubleargument\dosetupbibtexsession} + +\def\dodefinebibtexsession [#1]{\edef\currentbibtexsession{#1}% + \ctxlua{commands.definebibtexsession("#1")}% + \the\everydefinebibtexsession} + +\def\dopreparebibtexsession[#1][#2]{\edef\currentbibtexsession{#1}% + \ctxlua{commands.preparebibtexsession("#1","bibtex:#1","#2")}% + \the\everypreparebibtexsession} + +\def\dosetupbibtexsession [#1][#2]{\edef\currentbibtexsession{#1}% + \getparameters[\??pb#1][#2]% + \the\everysetupbibtexsession} + +\def\registerbibtexfile {\dodoubleargument\doregisterbibtexfile} +\def\registerbibtexentry {\dodoubleargument\doregisterbibtexentry} +\def\applytobibtexsession {\dodoubleargument\doapplytobibtexsession} + +\def\doregisterbibtexfile [#1][#2]{\ctxlua{commands.registerbibtexfile("#1","#2")}} +\def\doregisterbibtexentry [#1][#2]{\ctxlua{commands.registerbibtexentry("#1","#2")}} +\def\doapplytobibtexsession[#1][#2]{\xmlprocessregistered{bibtex:#1}{#2}{#2}} + +\unexpanded\def\bibtexcommand#1% + {\ifcsname\??pb:c:#1\endcsname \else + \fakebibtexcommand{#1}% + \fi + \csname\??pb:c:#1\endcsname} + +\def\fakebibtexcommand#1% + {\ifcsname#1\endcsname + \writestatus{bibtex}{unknown command: #1, using built-in context variant}% + \setugvalue{\??pb:c:#1}{\dosomebibtexcommand{#1}}% + \else + \writestatus{bibtex}{unknown command: #1}% + \setugvalue{\??pb:c:#1}{\dofakebibtexcommand{#1}}% + \fi} + +\let\dosomebibtexcommand \getvalue +\def\dofakebibtexcommand#1{{\tttf#1}} + +\def\defbibtexcommand#1% + {\setuvalue{\strippedcsname#1}} + +\def\bibxmldoifelse#1{\xmldoifelse\currentbibxmlnode{/field[@name='#1']}} +\def\bibxmldoif #1{\xmldoif \currentbibxmlnode{/field[@name='#1']}} +\def\bibxmldoifnot #1{\xmldoifnot \currentbibxmlnode{/field[@name='#1']}} +\def\bibxmlflush #1{\xmlcontext \currentbibxmlnode{/field[@name='#1']}} +\def\bibxmlsetup {\xmlsetup \currentbibxmlnode} % {#1} + +\def\currentbibtexformat{apa} % ho wto interface this, maybe split loading and key +\def\currentbibxmlnode {unset} +\def\currentbibxmltag {unset} + +\startxmlsetups bibtex + \xmlregistereddocumentsetups{#1}{} + \xmlsetsetup{#1}{bibtex|entry|field}{bibtex:*} + \xmlmain{#1} +\stopxmlsetups + +\startxmlsetups bibtex:format + \bibtexpublicationsparameter\c!before\relax % prevents lookahead + \edef\currentbibxmlnode {#1} + \edef\currentbibxmltag {\xmlatt{#1}{tag}} + \edef\currentbibxmlcategory{\xmlatt{#1}{category}} + \ifconditional\tracebibtexformat + \tracedbibxmlintro\currentbibxmltag + \tracedbibxmlintro\currentbibxmlcategory + \fi + \ignorespaces + \xmlcommand{#1}{.}{bibtex:\currentbibtexformat:\currentbibxmlcategory} + \removeunwantedspaces + \bibtexpublicationsparameter\c!after\relax % prevents lookahead +\stopxmlsetups + +\startxmlsetups bibtex:list + \xmlfilter{#1}{/bibtex/entry/command(bibtex:format)} +\stopxmlsetups + +\startxmlsetups bibtex:bibtex + \xmlfilter{#1}{/entry/command(bibtex:format)} +\stopxmlsetups + +% formatters + +\let\normalbibxmlflush\bibxmlflush + +\definecolor[bibtextracecolor:field] [darkred] +\definecolor[bibtextracecolor:crossref][darkblue] +\definecolor[bibtextracecolor:key] [darkgreen] + +\def\tracedbibxmlintro #1{{\tttf#1 -> }} +\def\tracedbibxmlflush #1{\color[bibtextracecolor:field] {\tttf[#1]}} +\def\tracedbibxmltexts #1{\color[bibtextracecolor:field] {\tttf<#1>}} +\def\tracedbibxmlcrossref#1{\color[bibtextracecolor:crossref]{\tttf#1}} +\def\tracedbibxmlkey #1{\color[bibtextracecolor:key] {\tttf#1}} + +\def\tracedbibxmltext + {\ifconditional\tracebibtexformat + \expandafter\tracedbibxmltexts % plural + \else + \expandafter\firstofoneargument + \fi} + +\def\bibxmlflush + {\ifconditional\tracebibtexformat + \expandafter\tracedbibxmlflush + \else + \expandafter\normalbibxmlflush + \fi} + +\startxmlsetups bibtex:format:crossref + \ifconditional\tracebibtexformat + \tracedbibxmlcrossref{\xmlfirst\currentbibxmlnode{/field[@name='crossref']/lower()}} + \else + \cite[\xmlfirst\currentbibxmlnode{/field[@name='crossref']/lower()}] + \fi +\stopxmlsetups + +\startxmlsetups bibtex:format:key + \ifconditional\tracebibtexformat + \tracedbibxmlkey{\normalbibxmlflush{key}} + \else + \bibxmlflush{key} + \fi +\stopxmlsetups + +\startxmlsetups bibtex:format:common:author + \ifconditional\tracebibtexformat + \bibxmlflush\currentbibtexvariant + \else + \xmlfilter{#1}{/field[@name='\currentbibtexvariant']/bibtexconcat('\currentbibtexvariant')} + \fi +\stopxmlsetups + +\startxmlsetups bibtex:format:author + \begingroup + \def\currentbibtexvariant{author} + \xmlsetup{#1}{bibtex:format:common:author} + \endgroup +\stopxmlsetups + +\startxmlsetups bibtex:format:artauthor + \begingroup + \def\currentbibtexvariant{artauthor} + \xmlsetup{#1}{bibtex:format:common:author} + \endgroup +\stopxmlsetups + +\startxmlsetups bibtex:format:editor + \begingroup + \def\currentbibtexvariant{editor} + \xmlsetup{#1}{bibtex:format:common:author} + \endgroup +\stopxmlsetups + +\startxmlsetups bibtex:format:doi +% \bibdoifelse{\@@pb@doi}{#1\expanded{\bibgotoDOI{\@@pb@thekey}{\@@pb@doi}}#2}{#3} + *doi* +\stopxmlsetups + + +\startxmlsetups bibtex:format:doi +% \bibdoifelse{\@@pb@biburl}{#1\expanded{\bibgotoURL{\@@pb@thekey}{\@@pb@biburl}}#2}{#3} + *url* +\stopxmlsetups + +\startxmlsetups bibtex:format:month +% {\bibdoifelse\@@pb@month +% {#1\doifnumberelse\@@pb@month +% {\doifconversiondefinedelse\@@pbmonthconversion +% {\convertnumber\@@pbmonthconversion\@@pb@month}{\@@pb@month}}% +% {\@@pb@month}#2}% +% {#3} + *month* +\stopxmlsetups + +% lists + +\def\bibtexlistprocessor + {\ctxlua{bibtex.hacks.add(structure.lists.uservalue("\currentlist",\currentlistindex,"bibref"),\currentlistindex)}} + +\appendtoks + \definelist[\currentbibtexsession]% + \setuplist[\currentbibtexsession][\c!state=\v!start,\c!width=]% + \installstructurelistprocessor{\currentbibtexsession:userdata}{\bibtexlistprocessor}% +\to \everydefinebibtexsession + +% \def\installbibtexsorter#1#2% +% {\setvalue{\??pb:\c!sort:#1}{#2}} + +% \installbibtexsorter\v!no {no} +% \installbibtexsorter\v!author {au} +% \installbibtexsorter\v!title {ti} +% \installbibtexsorter\v!short {ab} +% \installbibtexsorter\empty {no} +% \installbibtexsorter\s!default{no} + +% \setupbibtex +% [\c!sorttype=\v!cite, +% \c!sort=no] + +% \long\unexpanded\def\startpublication#1\stoppublication +% {\blank +% todo +% \blank} + +% \let\stoppublication\relax + +\unexpanded\def\bibtexspace {\removeunwantedspaces\space} +\unexpanded\def\bibtexperiod {\removeunwantedspaces.\space} +\unexpanded\def\bibtexcomma {\removeunwantedspaces,\space} +\unexpanded\def\bibtexlparent {\removeunwantedspaces\space(} +\unexpanded\def\bibtexrparent {\removeunwantedspaces)\space} +\unexpanded\def\bibtexlbracket{\removeunwantedspaces\space[} +\unexpanded\def\bibtexrbracket{\removeunwantedspaces]\space} + +% interfacing + +% todo : lang en language +% todo : directions + + +% variables + +\newcount\bibtexblock \bibtexblock\plusone + +\newtoks \everysetupbibtexpublications +\newtoks \everysetupbibtexcitations +\newcount\bibtexcounter + +\def\bibtexrefprefix{\number\bibtexblock:} + +\let\currentbibtexsession\s!default +\let\currentbibtexvariant\s!default + +% parameters: session+variant variant session shared + +\def\bibtexpublicationsparameter#1% + {\csname + \ifcsname\??pb\currentbibtexsession:\currentbibtexvariant#1\endcsname + \??pb\currentbibtexsession:\currentbibtexvariant#1% + \else\ifcsname\??pb:\currentbibtexvariant#1\endcsname + \??pb:\currentbibtexvariant#1% + \else\ifcsname\??pb\currentbibtexsession#1\endcsname + \??pb\currentbibtexsession#1% + \else\ifcsname\??pb#1\endcsname + \??pb#1% + \else + \s!empty + \fi\fi\fi\fi + \endcsname} + +\def\bibtexcitationparameter#1% + {\csname + \ifcsname\??pv\currentbibtexsession:\currentbibtexvariant#1\endcsname + \??pv\currentbibtexsession:\currentbibtexvariant#1% + \else\ifcsname\??pv:\currentbibtexvariant#1\endcsname + \??pv:\currentbibtexvariant#1% + \else\ifcsname\??pv\currentbibtexsession#1\endcsname + \??pv\currentbibtexsession#1% + \else\ifcsname\??pv#1\endcsname + \??pv#1% + \else + \s!empty + \fi\fi\fi\fi + \endcsname} + +% setup commands + +\unexpanded\def\setupbibtexpublications + {\let\currentpublicationclass\??pb + \let\everysetupbibtexwhatever\everysetupbibtexpublications + \dodoubleargument\dosetupbibtexwhatever} + +\unexpanded\def\setupbibtexcitations + {\let\currentpublicationclass\??pv + \let\everysetupbibtexwhatever\everysetupbibtexcitations + \dodoubleargument\dosetupbibtexwhatever} + +\unexpanded\def\setupbibtexpublicationvariants + {\let\currentpublicationclass\??pb + \let\everysetupbibtexwhatever\everysetupbibtexpublications + \dotripleargument\dosetupbibtexwhatevervariant} + +\unexpanded\def\setupbibtexcitationvariants + {\let\currentpublicationclass\??pv + \let\everysetupbibtexwhatever\everysetupbibtexcitations + \dotripleargument\dosetupbibtexwhatevervariant} + +\def\dosetupbibtexwhatever[#1][#2]% [sessionlist] [setup] + {\ifsecondargument + % sessions setups + \def\dobtxcommand##1{\getparameters[\currentpublicationclass##1][#2]}% + \processcommalist[#1]\dobtxcommand + \else + % setups + \getparameters[\currentpublicationclass][#1]% + \the\everysetupbibtexwhatever + \fi} + +\def\dosetupbibtexwhatevervariant[#1][#2][#3]% [sessionlist] [variantlist] [setup] + {\ifthirdargument + % sessions variants setups + \def\dobtxcommand##1% + {\def\dodobtxcommand####1{\getparameters[\currentpublicationclass##1:####1][#3]}% + \processcommalist[#2]\dodobtxcommand}% + \processcommalist[#1]\docbtxommand + \else\ifsecondargument + % variants setups + \def\dobtxcommand##1{\getparameters[\currentpublicationclass:##1][#2]}% + \processcommalist[#1]\dobtxcommand + \else + % setups + \getparameters[\currentpublicationclass][#1]% + \the\everysetupbibtexwhatever + \fi\fi} + +% some initializations + +\setupbibtexcitationvariants + [author,authoryear,authoryears] + [\c!namesep={, }] + +% loading alternatives (apa etc) + +\def\doloadbibtexpublicationalternative + {\ifproductionrun + \edef\bibtexpublicationsalternative{\@@pbalternative}% parent + \ifx\bibtexpublicationsalternative\empty \else + \processcommacommand[\bibtexpublicationsalternative]\dodoloadbibtexpublicationalternative + \let\@@pbalternative\empty + \fi + \fi} + +\def\dodoloadbibtexpublicationalternative#1% + {\doonlyonce{#1} + {\readsysfile{bxml-#1.mkiv} + {\showmessage\m!publications{6}{bxml-#1}} + {\showmessage\m!publications{1}{bxml-#1}}}} + +\appendtoks + \doloadbibtexpublicationalternative +\to \everysetupbibtexpublications + +\appendtoks + \doloadbibtexpublicationalternative +\to \everyjob + +% whatever, should be key + +\def\bibtexleftnumber#1{#1\hfill~} + +% testing + +% \showmessage\m!publications{5}{#1 is unknown}\secondoftwoarguments} + +\let\doifbibreferencefoundelse\secondofthreearguments + +% lists + +\newtoks\everysetupbibtexlistplacement + +% this will change as we need it too often .. we will use context.thebibtexnamesep + +\appendtoks + \ctxlua {bibtex.authors.setsettings { + namesep = \!!bs\bibtexpublicationsparameter\c!namesep\!!es, + lastnamesep = \!!bs\bibtexpublicationsparameter\c!lastnamesep\!!es, + finalnamesep = \!!bs\bibtexpublicationsparameter\c!finalnamesep\!!es, + firstnamesep = \!!bs\bibtexpublicationsparameter\c!firstnamesep\!!es, + juniorsep = \!!bs\bibtexpublicationsparameter\c!juniorsep\!!es, + vonsep = \!!bs\bibtexpublicationsparameter\c!vonsep\!!es, + surnamesep = \!!bs\bibtexpublicationsparameter\c!surnamesep\!!es, + namesep = \!!bs\bibtexpublicationsparameter\c!namesep\!!es, + lastnamesep = \!!bs\bibtexpublicationsparameter\c!lastnamesep\!!es, + finalnamesep = \!!bs\bibtexpublicationsparameter\c!finalnamesep\!!es, + author = { + etallimit = \!!bs\bibtexpublicationsparameter\c!authoretallimit\!!es, + etaldisplay = \!!bs\bibtexpublicationsparameter\c!authoretaldisplay\!!es, + etaltext = \!!bs\bibtexpublicationsparameter\c!authoretaltext\!!es, + }, + editor = { + etallimit = \!!bs\bibtexpublicationsparameter\c!editoretallimit\!!es, + etaldisplay = \!!bs\bibtexpublicationsparameter\c!editoretaldisplay\!!es, + etaltext = \!!bs\bibtexpublicationsparameter\c!editoretaltext\!!es, + }, + artauthor = { + etallimit = \!!bs\bibtexpublicationsparameter\c!artauthoretallimit\!!es, + etaldisplay = \!!bs\bibtexpublicationsparameter\c!artauthoretaldisplay\!!es, + etaltext = \!!bs\bibtexpublicationsparameter\c!artauthoretaltext\!!es, + }, + } }% +\to \everysetupbibtexlistplacement + +\def\completebibtexpublications{\dodoubleempty\docompletebibtexpublications} +\unexpanded\def\placebibtexpublications {\dodoubleempty\doplacebibtexpublications} + +\def\docompletebibtexpublications[#1][#2]% title might become obsolete, just headtext + {\begingroup + \edef\currentbibtexsession{#1}% + \let\currentlist\currentbibtexsession + \setuplist[\currentbibtexsession][\c!criterium=\v!previous,#2] + \doifelsenothing{\namedlistparameter\currentbibtexsession\c!title} + {\systemsuppliedchapter[\currentbibtexsession]{\headtext{\currentbibtexsession}}} + {\normalexpanded{\systemsuppliedchapter[\currentbibtexsession]{\namedlistparameter\currentbibtexsession\c!title}}}% + \dodoplacebibtexpublications} + +\def\doplacebibtexpublications[#1][#2]% + {\begingroup + \edef\currentbibtexsession{#1}% + \let\currentlist\currentbibtexsession + \setuplist[\currentbibtexsession][\c!criterium=\v!previous,#2]% + \dodoplacebibtexpublications} + +\def\dodoplacebibtexpublications + {\determinelistcharacteristics[\currentbibtexsession]% + \the\everysetupbibtexlistplacement + \forgetall + \typesetbibtexlist + \endgroup + \global\advance\bibtexblock\plusone} + +\setvalue{\??pb:\c!numbering:\v!short}#1% todo var s -> short tag + {\bibtexlistnumberbox{\bibtexpublicationsparameter\c!numbercommand{\bibtexgetshort\currentpublicationtag}}} + +\setvalue{\??pb:\c!numbering:\v!bib}#1% todo var n -> number + {\bibtexlistnumberbox{\bibtexpublicationsparameter\c!numbercommand{\bibtexgetnumber\currentpublicationtag}}} + +\setvalue{\??pb:\c!numbering:\s!unknown}#1% + {\bibtexlistnumberbox{\bibtexpublicationsparameter\c!numbercommand{#1}}} + +\def\@@pblimitednumber % name + {\csname\??pb:\c!numbering:% + \ifcsname\??pb:\c!numbering:\currentbibtexnumbering\endcsname + \currentbibtexnumbering + \else + \s!unknown + \fi + \endcsname} + +\appendtoks + \edef\currentbibtexnumbering{\bibtexpublicationsparameter\c!numbering}% + \ifx\currentbibtexnumbering\v!no + \setuplist[\currentbibtexsession][\c!numbercommand=,\c!symbol=\v!none,\c!textcommand=\outdented]% + \else + \setuplist[\currentbibtexsession][\c!numbercommand=\@@pblimitednumber]% + \fi +\to \everysetupbibtexlistplacement + +\newdimen\bibtexnumberwidth + +\def\bibtexlistnumberbox{\hbox \ifcase\bibtexnumberwidth\else to \bibtexnumberwidth\fi} + +\appendtoks + \doifelse{\bibtexpublicationsparameter\c!autohang}\v!yes + {\ifx\currentbibtexnumbering\v!short + \setbox\scratchbox\hbox{\bibtexpublicationsparameter\c!numbercommand{\bibtexpublicationsparameter\c!samplesize}}% + \else + \setbox\scratchbox\hbox{\bibtexpublicationsparameter\c!numbercommand{\ctxlua{tex.write(structure.lists.size())}}}% + \fi + \bibtexnumberwidth\wd\scratchbox + \setuplist[\currentbibtexsession][\c!distance=\zeropoint]} + {\doifelsenothing{\bibtexpublicationsparameter\c!width} + {\bibtexnumberwidth\zeropoint} + {\bibtexnumberwidth\bibtexpublicationsparameter\c!width}}% + \setuplist[\currentbibtexsession][\c!width=\bibtexnumberwidth]% +\to \everysetupbibtexlistplacement + +\appendtoks + \let\maybeyear\gobbleoneargument + \let\noopsort \gobbleoneargument +\to \everysetupbibtexlistplacement + +\appendtoks + \doifelse{\bibtexpublicationsparameter\c!maybeyear}\v!off + {\let\maybeyear\gobbleoneargument} + {\let\maybeyear\firstofoneargument}% +\to \everysetupbibtexlistplacement + +\appendtoks + \doifnot{\bibtexpublicationsparameter\c!option}\v!continue + {\global\bibtexcounter\zerocount}% +\to \everysetupbibtexlistplacement + +\appendtoks + \edef\currentbibtexcriterium{\namedlistparameter\currentbibtexsession\c!criterium}% +\to \everysetupbibtexlistplacement + +\def\typesetbibtexlist + {\dobeginoflist + \doif{\namedlistparameter\currentbibtexsession\c!criterium}\v!cite + {\setuplist[\currentbibtexsession][\c!criterium=\v!here]}% + \doifelse{\bibtexpublicationsparameter\c!method}\v!local + {\ctxlua{bibtex.hacks.reset(1)}}% function can take method + {\ctxlua{bibtex.hacks.reset(2)}}% + \placestructurelist + {\currentbibtexsession} + {\currentbibtexcriterium} + {\namedlistparameter\currentbibtexsession\c!number}% + \ctxlua{bibtex.hacks.flush("\bibtexpublicationsparameter\c!sorttype")}% + \doendoflist} + +\unexpanded\def\typesetbibtexpublication#1% + {\edef\currentbibtexsessiontag{#1}% + \ifx\currentbibtexsessiontag\empty + % can't really happen + \else\ifx\currentbibtexcriterium\v!all + \doplacepublicationindeed + \else + \ctxlua{bibtex.hacks.doifalreadyplaced("\currentbibtexsessiontag")} + \donothing + \dotypesetbibtexpublication + \fi\fi} + +\def\dotypesetbibtexpublication + {\doifbibreferencefoundelse\currentbibtexsessiontag + {\global\advance\bibtexcounter\plusone + \ctxlua{bibtex.hacks.registerplaced("\currentbibtexsessiontag")}% + \dodolistelement{\currentbibtexsession}{}{\number\bibtexcounter}{\thebibtexpublicationlistelement}{}{}} + {}} % invalid + +\def\thebibtexpublicationlistelement + {\strut + \expanded{\reference[\bibtexrefprefix\currentbibtexsessiontag]{\number\bibtexcounter}}% + \dotypesetabibtexpublication\currentbibtexsessiontag + \strut} + +\def\dotypesetabibtexpublication#1% + {\begingroup + \ignorespaces + \xmlfilter{bibtex:\currentbibtexsession}{/bibtex/entry[@tag='#1']/command(bibtex:format)}% + \removeunwantedspaces +% \ignorespaces +% \bibalternative{\bibgetvart{#1}}% +% \removeunwantedspaces + \endgroup} + +\def\doprocessbibtexentry#1{\typesetbibtexpublication{#1}} + +% citations + +\unexpanded\def\bibtexcitation[#1]% + {\edef\currentbibtexsession{#1}% + \strictdoifnextoptionalelse\dobibtexcitation\dobibtexref} + +\def\dobibtexref#1% + {\dodobibtexcitation[#1][]} + +\def\dobibtexcitation[#1]% + {\strictdoifnextoptionalelse{\dodobibtexcitation[#1]}{\dodobibtexcitation[#1][]}} + +\def\dodobibtexcitation[#1][#2]% + {\dontleavehmode + \begingroup + \doifelsenothing{#2}\secondargumentfalse\secondargumenttrue + \ifsecondargument + \dowhateverbibtexcitation{#1}{#2}% + \else + \donumberedbibtexcitation{#1}% + \fi + \endgroup} + +\def\dowhatevercitation#1#2% + {\processcommalist[#2]\dobibtexcitationindeed + \setupinteraction[\c!style=]% use flag instead + \doifassignmentelse{#1} + {\getparameters[\??pb\??pb][\c!alternative=,\c!extras=,#1]% + \edef\currentbibtexvariant{\@@pb@@pbalternative}% + \ifx\currentbibtexvariant\empty + \edef\currentbibtexvariant{\bibtexpublicationparameter\c!refcommand}% + \fi + \ifx\@@pb@@pbextras\empty + \setupcite[\currentbibtexvariant][#1]% + \else + \edef\@@pb@@pbextras{{\@@pb@@pbextras\ifdefined\@@pb@@pbright\@@pb@@pbright\else\bibtexpublicationparameter\c!right\fi}}% + \expanded{\setupcite[\currentbibtexvariant][#1,\c!right=\@@pb@@pbextras]}% + \fi}% + {\def\currentbibtexvariant{#1}}% + \getvalue{bibtex\currentbibtexvariant ref}[#2]} + +\def\donumberedbibtexcitation#1% + {\processcommalist[#1]\dobibtexcitationindeed + \setupinteraction[\c!style=]% + \edef\currentbibtexvariant{\bibtexcitationparameter\c!refcommand}% + \getvalue{bibtex\currentbibtexvariant ref}[#1]} + +\def\dobibtexcitationindeed#1% + {\iftrialtypesetting \else + \expanded{\writedatatolist[\currentbibtexsession][bibref=#1]}% + \fi} + +\def\nobibtexcitation[#1]% + {\processcommalist[#1]\dobibtexcitationindeed} + +\def\bibtexnumref[#1]% + {\dontleavehmode + \begingroup + \bibtexcitationparameter\v!left + \penalty\!!tenthousand + \ctxlua{bibtex.hacks.resolve("","\number\bibtexblock","#1")}% + \bibtexcitationparameter\v!right + \endgroup} + +\def\dowithbibtexnumrefconnector#1#2% + {\ifnum#1>\plusone + \ifnum#2>\plusone + \ifnum#2=#1\relax + \bibtexpublicationsparameter\c!lastpubsep + \else + \bibtexpublicationsparameter\c!pubsep + \fi + \fi + \fi} + +\def\dowithbibtexnumref#1#2#3#4#5% n, i, prefix block ref + {\dowithbibtexnumrefconnector{#1}{#2}% + \def\bibtexrefprefix{#4:}% + \inbiblink[#5]} + +\def\dowithbibtexnumrefrange#1#2#3#4#5#6#7% n, i, prefix block ref + {\dowithbibtexnumrefconnector{#1}{#2}% + \def\bibtexrefprefix{#4:}% + \inbiblink[#5]% + \endash + \def\bibtexrefprefix{#6:}% + \inbiblink[#7]} + +\def\nobibtexnumref#1% + {[#1]} + +% hm + +% \def\@@pbinumbercommand{\executeifdefined{\??pb:\c!numbercommand:\@@pbnumbering}\firstofoneargument} + +% \letvalue{\??pb:\c!numbercommand:\v!yes }\firstofoneargument +% \letvalue{\??pb:\c!numbercommand:\v!no }\gobbleoneargument +% \setvalue{\??pb:\c!numbercommand:\v!short}{\bibtexgetshort\currentpublicationtag\gobbleoneargument} +% \setvalue{\??pb:\c!numbercommand:\v!bib }{\bibtexgetnumber\currentpublicationtag\gobbleoneargument} + +% \def\bibalternative#1{\csname\??pv\@@currentalternative#1\endcsname} + +% basic setup + +% parent -> publicationlist +% +% \setuplist +% [\currentbibtexsession] +% [\c!samplesize={AA99}, +% \c!alternative=a, +% \c!interaction=, +% \c!pagenumber=\v!no, +% #1, +% \c!command=] + +% \setuppublicationlist +% [\c!title=, +% \c!command=\dospecialbibinsert, +% \c!maybeyear=\v!on] + +\setupbibtexpublications + [\c!monthconversion=, + \c!alternative=apa, + \c!method=\v!global, + \c!refcommand=num, + \c!numbercommand=\bibtexleftnumber] + +\setupbibtexcitations % command ? + [\c!refcommand=num] + +% helpers + +\def\doifbibtexinteractionelse + {\iflocation + \edef\temp{\bibtexcitationparameter\c!interaction}% + \ifx\temp\v!stop + \@EA@EA@EA\secondoftwoarguments + \else + \@EA@EA@EA\firstoftwoarguments + \fi + \else + \@EA\secondoftwoarguments + \fi} + +% variants + +% todo: lastsep here + +\newconditional\firstbibtexrefsep + +\def\bibtexresetrefsep + {\settrue\firstbibtexrefsep} + +\def\bibtexinsertrefsep + {\ifconditional\firstbibtexrefsep + \setfalse\firstbibtexrefsep + \else + \bibtexcitationparameter\c!pubsep + \fi} + +\def\inbibtexlink#1#2% + {\doifreferencefoundelse{\bibtexrefprefix#1} + {\goto{#2}[\bibtexrefprefix#1]} + {!#1!\unknownreference{#1}}} + +\def\dobibtexgotolink#1#2% + {\doifreferencefoundelse{\bibtexrefprefix#1} + {\goto{#2}[\bibtexrefprefix#1]} + {!#1!\unknownreference{#1}}} + +\def\dobibattexlink#1#2% + {\doifreferencefoundelse{\bibtexrefprefix#1} + {\at{#2}[\bibtexrefprefix#1]} + {!#1!\unknownreference{#1}}} + +\def\dobibtexurllink#1#2% + {\expanded{\useURL[bibtex:url:#1][#2]}% + \doifbibtexinteractionelse + {\goto{\url[bibtex:url:#1]}[url(bibtex:url:#1)]} + {\url[bibtex:url:#1]}} + +% todo: style, color + +\unexpanded\def\bibtexdataref {\dodoubleargument\dobibtexdataref} +\unexpanded\def\bibtextyperef {\dodoubleargument\dobibtextyperef} +\unexpanded\def\bibtexkeyref {\dodoubleargument\dobibtexkeyref} +\unexpanded\def\bibtexserialref {\dodoubleargument\dobibtexserialref} +\unexpanded\def\bibtexurlref {\dodoubleargument\dobibtexurlref} +\unexpanded\def\bibtexdoiref {\dodoubleargument\dobibtexdoiref} +\unexpanded\def\bibtexpageref {\dodoubleargument\dobibtexpageref} +\unexpanded\def\bibtexnoneref {\dodoubleargument\dobibtexnoneref} +\unexpanded\def\bibtexshortref {\dodoubleargument\dobibtexshortref} +\unexpanded\def\bibtexyearref {\dodoubleargument\dobibtexyearref} +\unexpanded\def\bibtexauthorref {\dodoubleargument\dobibtexauthorref} +\unexpanded\def\bibtexauthoryearref {\dodoubleargument\dobibtexauthoryearref} +\unexpanded\def\bibtexauthoryearsref{\dodoubleargument\dobibtexauthoryearsref} + +\def\dobibtexdataref {\doprocessbibtexref\dodobibtexdataref {ref}} % [#1][#2] +\def\dobibtextyperef {\doprocessbibtexref\dodobibtextyperef {type}} % [#1][#2] +\def\dobibtexkeyref {\doprocessbibtexref\dodobibtexkeyref {key}} % [#1][#2] +\def\dobibtexserialref {\doprocessbibtexref\dodobibtexserialref {serial}} % [#1][#2] +\def\dobibtexurlref {\doprocessbibtexref\dodobibtexurlref {url}} % [#1][#2] +\def\dobibtexdoiref {\doprocessbibtexref\dodobibtexdoiref {doi}} % [#1][#2] +\def\dobibtexpageref {\doprocessbibtexref\dodobibtexpageref {page}} % [#1][#2] +\def\dobibtexnoneref {\doprocessbibtexref\dodobibtexnoneref {none}} % [#1][#2] +\def\dobibtexshortref {\doprocessbibtexref\dodobibtexshortref {short}} % [#1][#2] +\def\dobibtexyearref {\doprocessbibtexref\dodobibtexyearref {year}} % [#1][#2] +\def\dobibtexauthorref {\doprocessbibtexref\dodobibtexauthorref {author}} % [#1][#2] +\def\dobibtexauthoryearref {\doprocessbibtexref\dodobibtexauthoryearref {authoryear}} % [#1][#2] +\def\dobibtexauthoryearsref{\doprocessbibtexref\dodobibtexauthoryearsref{authoryears}} % [#1][#2] + +\def\doprocessbibtexref#1#2[#3][#4]% + {\edef\currentbibtexsession{#3}% + \edef\currentbibtexvariant{#2}% + \def\dodoprocessbibtexref##1% + {% test for existence + \edef\currentbibtextag{##1}% + \bibtexinsertrefsep + #1{##1}}% + \bibtexresetrefsep + \bibtexcitationparameter\v!left + \processcommalist[#4]\dodoprocessbibtexref\relax + \bibtexcitationparameter\v!right} + +\def\dodobibtexdataref#1% + {\dotypesetabibtexpublication{#1}} + +\def\dodobibtextyperef#1% + {\edef\bibtexrefcontent{\xmlfilter{bibtex:\currentbibtexsession}{/bibtex/entry[@tag='#1']/attribute('category')}}% + \bibtexrefcontent} + +\def\dodobibtexkeyref#1% + {\edef\bibtexrefcontent{\xmlfilter{bibtex:\currentbibtexsession}{/bibtex/entry[@tag='key']/context()}}% + \dobibtexgotolink{#1}{\bibtexrefcontent}} + +\def\dodobibtexserialref#1% + {\edef\bibtexrefcontent{\xmlfilter{bibtex:\currentbibtexsession}{/bibtex/entry[@tag='#1']/match()}}% + \dobibtexgotolink{#1}{\bibtexrefcontent}} + +\def\dodobibtexurlref#1% + {\edef\bibtexrefcontent{\xmlfilter{bibtex:\currentbibtexsession}{/bibtex/entry[@tag='#1']/field[@name='url']/context()}}% + \dobibtexurllink{#1}{\bibtexrefcontent}} + +\def\dodobibtexdoiref#1% + {\edef\bibtexrefcontent{\xmlfilter{bibtex:\currentbibtexsession}{/bibtex/entry[@tag='#1']/field[@name='doi']/context()}}% + \dobibtexurllink{#1}{http://dx.doi.org/\bibtexrefcontent}} + +\def\dodobibtexpageref#1% + {\dobibtexatlink{#1}{}} % second argument can become 'page' + +\def\dodobibtexnoneref#1% + {} + +\def\dodobibtexshortref#1% + {\edef\bibtexrefcontent{\xmlfilter{bibtex:\currentbibtexsession}{/bibtex/entry[@tag='#1']/bibtexshort()}}% + \dobibtexgotolink{#1}{\bibtexrefcontent}} + +\def\dodobibtexyearref#1% + {\edef\bibtexrefcontent{\xmlfilter{bibtex:\currentbibtexsession}{/bibtex/entry[@tag='#1']/field[@name='year']/context()}}% + \bibtexrefcontent} + +% \def\bibmaybeinteractive#1#2% +% {\doifelsevalue{@@pv\@@currentalternative\c!compress} +% {\ifbibinteractionelse{\gotobiblink{#2}[#1]}{#2}} +% {#2}} + +% \def\bibauthornumref[#1]% +% {\getcommalistsize[#1]% +% \global\bibitemcounter\commalistsize +% \bibresetrefsep +% \processcommalist[#1]\dobibauthornumref } +% +% \def\dobibauthornumref#1% +% {\bibinsertrefsep +% \doifbibreferencefoundelse{#1} +% {\begingroup +% \bibgetvara{#1}% +% \bibalternative\c!inbetween +% \setuppublications[\c!refcommand=num]% +% \cite[#1]% +% \endgroup} +% {\unknownreference{#1}}} + +% compress years +% andtext namesep +% otherstext authoretallimit + +% we will use context.* instead at the lua end because it saves us passing settings + +% \def\thebibtexpubsep {\bibtexpublicationsparameter\c!pubsep} +% \def\thebibtexlastpubsep {\bibtexpublicationsparameter\c!lastpubsep} +% \def\thebibtexfinalpubseparator{\bibtexpublicationsparameter\c!lastpubsep} + +\def\dodobibtexauthorref #1{\ctxlua{bibtex.authorref ("bibtex:\currentbibtexsession","#1","normal","author")}} +\def\dodobibtexauthoryearref #1{\ctxlua{bibtex.authoryearref ("bibtex:\currentbibtexsession","#1","normal","author")}} +\def\dodobibtexauthoryearsref#1{\ctxlua{bibtex.authoryearsref("bibtex:\currentbibtexsession","#1","normal","author")}} + +\unexpanded\def\bibtexsingularplural#1#2{\ctxlua{bibtex.singular_or_plural(\!!bs#1\!!es,\!!bs#2\!!es)}} + +\protect \endinput + diff --git a/tex/context/base/bibl-tra.lua b/tex/context/base/bibl-tra.lua new file mode 100644 index 000000000..442231028 --- /dev/null +++ b/tex/context/base/bibl-tra.lua @@ -0,0 +1,194 @@ +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" +} + +bibtex = bibtex or { } +bibtex.hacks = bibtex.hacks or { } + +local match, gmatch, format, concat, sort = string.match, string.gmatch, string.format, table.concat, table.sort +local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes +local variables, constants = interfaces.variables, interfaces.constants + +local trace_bibtex = false trackers.register("publications.bibtex", function(v) trace_bibtex = v end) + +local hacks = bibtex.hacks + +local list, done, alldone, used, registered, ordered = { }, { }, { }, { }, { }, { } +local mode = 0 + +local template = string.striplong([[ + \citation{*} + \bibstyle{cont-%s} + \bibdata{%s} +]]) + +function hacks.process(settings) + local style = settings.style or "" + local database = settings.database or "" + local jobname = tex.jobname + if database ~= "" then + interfaces.showmessage("publications",3) + io.savedata(file.addsuffix(jobname,"aux"),format(template,style,database)) + if trace_bibtex then + logs.report("publications","processing bibtex file '%s'",jobname) + end + os.execute(format("bibtex %s",jobname)) + -- purge 'm + end +end + +function hacks.register(str) + if trace_bibtex then + logs.report("publications","registering bibtex entry '%s'",str) + end + registered[#registered+1] = str + ordered[str] = #registered +end + +function hacks.reset(m) + mode, list, done = m, { }, { } +end + +function hacks.add(str,listindex) + if not str or mode == 0 then + -- skip + elseif mode == 1 then + -- all locals but no duplicates + local sc = structure.sections.currentid() + if done[str] ~= sc then + done[str], alldone[str] = sc, true + list[#list+1] = { str, listindex } + end + elseif mode == 2 then + -- all locals but no preceding + local sc = structure.sections.currentid() + if not alldone[str] and done[str] ~= sc then + done[str], alldone[str] = sc, true + list[#list+1] = { str, listindex } + end + end +end + +local function compare(a,b) + local aa, bb = a[1], b[1] + if aa and bb then + return ordered[aa] < ordered[bb] + else + return true + end +end + +function hacks.flush(sortvariant) + if sortvariant == "" or sortvariant == variables.cite or sortvariant == "default" then + -- order is cite order i.e. same as list + else + sort(list,compare) + end + for i=1,#list do + context.doprocessbibtexentry(list[i][1]) + end +end + +function hacks.registerplaced(str) + used[str] = true +end + +function hacks.doifalreadyplaced(str) + commands.testcase(used[str]) +end + +-- we ask for :tag but when we can't find it we go back +-- to look for previous definitions, and when not found again +-- we look forward + +local function compare(a,b) + return a[3] < b[3] +end + +function hacks.resolve(prefix,block,reference) -- maybe already feed it split + local subset = jobreferences.collected[prefix or ""] or jobreferences.collected[""] + if subset then + local result, done = { }, { } + block = tonumber(block) + for rest in gmatch(reference,"([^,%s]+)") do + local blk, tag, found = block, nil, nil + if block then + tag = blk .. ":" .. rest + found = subset[tag] + if not found then + for i=block-1,1,-1 do + tag = i .. ":" .. rest + found = subset[tag] + if found then + blk = i + break + end + end + end + end + if not found then + blk = "*" + tag = blk .. ":" .. rest + found = subset[tag] + end + if found then + local current = found.entries and found.entries.text + if current and not done[current] then + result[#result+1] = { blk, rest, current } + done[current] = true + end + end + end + -- todo: ranges so the interface will change + sort(result,compare) + local first, last, firsti, lasti, firstr, lastr + local collected = { } + for i=1,#result do + local r = result[i] + local current = r[3] + if not first then + first, last, firsti, lasti, firstr, lastr = current, current, i, i, r, r + elseif current == last + 1 then + last, lasti, lastr = current, i, r + else + if last > first + 1 then + collected[#collected+1] = { firstr[1], firstr[2], lastr[1], lastr[2] } + else + collected[#collected+1] = { firstr[1], firstr[2] } + if last > first then + collected[#collected+1] = { lastr[1], lastr[2] } + end + end + first, last, firsti, lasti, firstr, lastr = current, current, i, i, r, r + end + end + if first then + if last > first + 1 then + collected[#collected+1] = { firstr[1], firstr[2], lastr[1], lastr[2] } + else + collected[#collected+1] = { firstr[1], firstr[2] } + if last > first then + collected[#collected+1] = { lastr[1], lastr[2] } + end + end + end + if #collected > 0 then + for i=1,#collected do + local c = collected[i] + if c[3] then + context.dowithbibtexnumrefrange(#collected,i,prefix,c[1],c[2],c[3],c[4]) + else + context.dowithbibtexnumref(#collected,i,prefix,c[1],c[2]) + end + end + else + context.nobibtexnumref("error 1") + end + else + context.nobibtexnumref("error 2") + end +end diff --git a/tex/context/base/bibl-tra.mkii b/tex/context/base/bibl-tra.mkii new file mode 100644 index 000000000..087781db9 --- /dev/null +++ b/tex/context/base/bibl-tra.mkii @@ -0,0 +1,1778 @@ +%D \module +%D [ file=bibl-tra, +%D version=2009.08.13, +%D title=\CONTEXT\ Publication Module, +%D subtitle=Publications, +%D author=Taco Hoekwater, +%D date=\currentdate, +%D copyright=Public Domain] +%C +%C Donated to the public domain. + +%D This used to be module \type {t-bib} but due to the number of differences +%D in handling structure between \MKII\ and \MKIV\ we now have \BIBTEX\ support +%D in the kernel. The only patches concerns some namespace issues. Also, +%D constants and variables are now predefined. When the \MKIV\ code is well +%D tested I might backport a couple of adaptions to this \MKII\ variant. + +\writestatus{loading}{ConTeXt Bibliography Support / BibTeX} + +\definefilesynonym[bib][obsolete] + +% here starts t-bib.tex + +%D The original was developed independantly by Taco Hoekwater while still working for Kluwer +%D Academic publishers (it still used the dutch interface then). Development continued after +%D he left Kluwer, and in Januari 2005, the then already internationalized file was merged +%D with the core distribution by Hans Hagen. The current version is once again by Taco. +%D +%D More documentation and additional resources can be found on the contextgarden: +%D \hyphenatedurl{http://wiki.contextgarden.net//Bibliography}. + +%D \subject{DONE (dd/mm/yyyy)} +%D +%D \startitemize +%D \item add author definition (and associated system variable) (26/05/2005) +%D \item add finalnamesep support for Oxford comma (17/09/2005) +%D \item add \type{\insert...} for: doi, eprint, howpublished (19/09/2005) +%D \item allow a defaulted \type{\setupcite} (19/11/2005) +%D \item renamed citation type 'number' to 'serial' (19/11/2005) +%D \item better definition of \type{\inverted...author} (19/11/2005) +%D \item don't reset [numbercommand] in \type {\setuppublication} by default (20/11/2005) +%D \item don't disable other \type {\setuppublication} keys if alternative is present (20/11/2005) +%D \item drop \type{\sanitizeaccents} (20/11/2005) +%D \item added \type{\nocite} and \type{\cite[none]} (21/11/2005) +%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 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) +%D \item Use \type{\readfile} inside \type{\usepublications} instead of \type{\readsysfile} (12/01/2006) +%D \item Use \type{\currentbibyear} and \type{\currentbibauthor} instead of \type{\YR} and \type{\AU} (05/02/2006) +%D \item Fix compressed version of authoryear style (05/02/2006) +%D \item Rename the clashing data fields \type{\url} and \type{\type} to \type{\biburl} and \type{\bibtype} (05/02/2006) +%D \item Added two french bibl files from Renaud Aubin (06/02/2006) +%D \item Five new bib class and eight extra bib fields, for IEEEtran (07/02/2006) +%D \item French keyword translation, provided by Renaud (08/02/2006) +%D \item fix underscores in undefined keys (22/02/2006) +%D \item Destroy interactivity in labels of the publication list (13/03/2006) +%D \item fix multi-cite list compression (11/4/2006) +%D \item fix \type{\getcitedata} (11/4/2006) +%D \item magic for chapter bibs (18-25/4/2006) +%D \item language setting (25/4/2006) +%D \item use \type{\hyphenatedurl} for \type{\inserturl} (25/4/2006) +%D \item Add \type{\docitation} to \type{\nocite}(26/4/2006) +%D \item patents can have numbers, added to bst files (26/4/2006) +%D \item \type{\docitation} needs a \type{\iftrialtypesetting} (27/4/2006) +%D \item \type{\filllocalpublist}'s loop is bound by definedness, not resolvedness (27/4/2006) +%D \item \type{\setuppublications[monthconversion=]} added (15/5/2006) +%D \item use \type{\undefinedreference} instead of bare question marks (15/5/2006) +%D \item add grouping around \type{\placepublications} commands (16/5/2006) +%D \item fix a bug in \type{\cite{}} (17/5/2006) +%D \item support \type{\cite[authornum]} (18/5/2006) +%D \item make \type{\cite} unexpandable (20/6/2006) +%D \item allow hyperlinks in author\&year combo's +%D (cite list compression has to be off) (20/6/2006) +%D \item fix duplicate labels for per-chapter style (20/6/2006) +%D \item allow \type{\setupcite[interaction=(start|stop)]} +%D \item fix the item number in the publication list with 'numbering=yes' (22/6/2006) +%D \item make the default criterium for \type{\placepublications} be \type{previous} (23/6/2006) +%D \item fix \type{\normalauthor} and \type{\normalshortauthor} spacing (29/6/2006) +%D \item do not typeset empty arguments to \type{\typesetapublication} (29/6/2006) +%D \item add \type{symbol=none} to \type{\setuplist} in unnumbered +%D mode to prevent typesetting of bare numbers (29/6/2006) +%D \item remove two incorrect spaces from bibl-num.tex (1/7/2006) +%D \item reset font styles within \type{\cite}, so that font switches +%D in \type{left} stay in effect (12/7/2006) +%D \item guard added against loading bbl files multiple times (13/7/2006) +%D \item fix \type{\cite[num]} with compression is on. (14/7/2006) +%D \item test \type{\iflocation} before deciding to use the +%D interactive version of cite (18/7/2006) +%D \item support \type{\setupcite[authoretallimit=1]} (18/7/2006) +%D \item support use of \type{\cite} within titles and captions by +%D saveguarding the list item extraction and reference placement +%D code (19/7/2006) +%D \item support \type{\setuppublicationlist[title=\chapter]} (4/8/2006) +%D \item use the expansion of \type{\headtext{pubs}} (4/8/2006) +%D \item hook added for repeated authors in publication list +%D \type{\setuppublicationlist[artauthorcommand=\mythreeargscommand]} +%D (4/8/2006) +%D \item make the bracketed arguments of \type{\artauthor}, \type{\author} +%D and \type{\editor} (bbl commands) optional (4/8/2006) +%D \item the constants \type{sorttype}, \type{compress} and +%D \type{autohang} have moved to the core (8/8/2006) +%D \item bibtex is now registered as a program to be run by texexec (8/8/2006) +%D \item fix a bug in \type{\setupcite[authoretallimit=1]} (9/8/2006) +%D \item fix a bug inside citations that prevented lastpubsep from ever being +%D used due to a volatile \type{\commalistsize} (25/8/2006). +%D \item added the possibility of \type{\placepublications[option=continue]} +%D (6/9/2006) +%D \item Mojca translated Master's Thesis to Masterarbeit (bibl-apa-de.tex) +%D (12/9/2006) +%D \item Added \type{\setuppublicationlist[maybeyear=off]} by request from +%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 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) +%D \item Patch for \type{\insertbiburl} and \type{\insertdoi} for Tobias Burnus (18/4/2007) +%D \item Added a missing \type{\relax} in \type{\dospecialbibinsert}, +%D that made the space before the {\it et al.} text disappear. (18/4/2007) +%D \item Attempt to fix percent signs in bbl files. As a side-effect, +%D this prohibits comments in \tex{startpublication} blocks! (17/4/2008) +%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 \item Remove a superfluous \type{\unprotect} in t-bib.mkiv (11/05/2009). +%D \item Patch of incollection in bibl-ams.tex from Xan (08/06/2009). +%D \item Patch of unpublished in bibl-ams.tex from Xan (22/07/2009). +%D \item Modified \type{\bibdogetupsometextprefix} so it works for undefined +%D language labels, from Hans (13/08/2009). +%D \item Removed some \MKIV\ hacks as well as some things that are in the +%D core like variables, constants and messages (HH:22/08/2009). +%D \item Added \type{bib} in front of \type {insert} macros and initialize +%D then later on (HH:22/08/2009). +%D \item Removed test for type {\currentlocationreference} plus associated +%D code (HH:22/08/2009). +%D \stopitemize +%D +%D \subject{WISHLIST} +%D +%D \startitemize +%D \item link back from publication list to citation +%D \item export \type {\citation{}} +%D \item support mlbibtex +%D \item don't load the whole lot, but filter entries instead +%D \stopitemize + +\unprotect + +%D Variables, constants and messages are removed as they are now in the +%D multilingual interface modules. + +\def\biblistname{pubs} % for compatibility + +%D how to load the references. There is some new stuff here +%D to support Idris' (incorrect :-)) use of projects + +% \let\preloadbiblist\relax +% +% \ifx\currentcomponent\v!text +% % single file +% \edef\temp{\the\everystarttext}% +% \ifx\temp\empty +% % post-starttext +% \def\preloadbiblist{\dousepublications\jobname }% +% \else +% % pre-starttext +% \appendtoks \dousepublications\jobname \to \everystarttext +% \fi +% % +% \else \ifx\currentcomponent\v!project +% % a project file, have to set up the partial products! +% \def\startproduct #1 % +% {\doateverystarttext +% \dousepublications{#1}% +% \donextlevel\v!product\currentproduct +% \doexecutefileonce\doexecutefileonce +% \donotexecutefile\doexecutefile#1\\}% +% % +% \else \ifx\currentcomponent\v!product +% % a product file +% \def\preloadbiblist{\dousepublications\jobname }% +% % +% \else +% % a component? not sure what to do +% \def\preloadbiblist{\dousepublications\jobname }% +% % +% \fi \fi \fi + +\def\preloadbiblist + {\globallet\preloadbiblist\relax + \dousepublications\jobname} + +\definelist[pubs] +\setuplist[pubs][\c!width=] + +%D \macros{bibdoif,bibdoifnot,bibdoifelse} +%D +%D Here are a few small helpers that are used a lot +%D in all the typesetting commands +%D (\type{\insert...}) we will encounter later. + +\long\def\bibdoifelse#1% + {\@EA\def\@EA\!!stringa\@EA{#1}% + \ifx\!!stringa\empty + \expandafter\secondoftwoarguments + \else + \expandafter\firstoftwoarguments + \fi} + +\long\def\bibdoifnot#1% + {\@EA\def\@EA\!!stringa\@EA{#1}% + \ifx\!!stringa\empty + \expandafter\firstofoneargument + \else + \expandafter\gobbleoneargument + \fi} + +\long\def\bibdoif#1% + {\@EA\def\@EA\!!stringa\@EA{#1}% + \ifx\!!stringa\empty + \expandafter\gobbleoneargument + \else + \expandafter\firstofoneargument + \fi} + +%D Bibtex settings separated out + +%D No point in writing the aux file if there is no database... + +\def\setupbibtex{\dosingleempty\dosetupbibtex} + +\def\dosetupbibtex[#1]% + {\let\@@pbdatabase\empty + \getparameters[\??pb][\c!sort=\s!default,#1]% + \expanded{\processaction[\@@pbsort]} + [ \v!no=>\def\bibstyle{cont-no}, + \v!author=>\def\bibstyle{cont-au}, + \v!title=>\def\bibstyle{cont-ti}, + \v!short=>\def\bibstyle{cont-ab}, + \s!default=>\def\bibstyle{cont-no}, + \s!unknown=>\def\bibstyle{\@@pbsort}]% + \ifx\@@pbdatabase\empty\else \writeauxfile \fi} + +\dosetupbibtex[bibtex=bibtex] + +%D \macros{writeauxfile} +%D +%D Unfortunately, \BIBTEX\ is not the best configurable program +%D around. The names of the commands it parses as well as the \type{.aux} +%D extension to the file name are both hardwired. +%D +%D This means \CONTEXT\ has to write a \LATEX-style auxiliary file, yuk! +%D The good news is that it can be rather short. We'll just ask +%D \BIBTEX\ to output the entire database(s) into the \type{bbl} file. +%D +%D The \type{\bibstyle} command controls how the \type{bbl} file will +%D be sorted. The possibilities are: +%D +%D \startitemize[packed] +%D \item by author (+year, title): cont-au.bst +%D \item by title (+author, year): cont-ti.bst +%D \item by short key as in abbrev.bst: cont-ab.bst +%D \item not sorted at all: cont-no.bst +%D \stopitemize + +\def\writeauxfile + {\doifmode{*\v!first} + {\openout \scratchwrite \jobname.aux + \write \scratchwrite {\string\citation{*}}% + \write \scratchwrite {\string\bibstyle{\bibstyle}}% + \write \scratchwrite {\string\bibdata{\@@pbdatabase}}% + \closeout\scratchwrite + \showmessage\m!publications{3}{}% + \expanded{\installprogram{\@@pbbibtex\space\jobname}}}} + +%D \macros{ifsortbycite,iftypesetall,ifautohang,ifbibcitecompress} +%D +%D The module needs some new \type{\if} statements. + +%D Default sort order of the reference list is by citation. + +\newif\ifsortbycite \sortbycitetrue + +%D By default, only referenced publications are typeset + +\newif\iftypesetall \typesetallfalse + +%D Hanging indentation of the publication list +%D will not adjust itself according to the width of the label. + +\newif\ifautohang \autohangfalse + +%D Cite lists are compressed, if possible. + +\newif\ifbibcitecompress \bibcitecompresstrue + +\def\setuppublications + {\dosingleargument\dosetuppublications} + +\def\bibleftnumber#1% + {#1\hfill~} + +\def\dosetuppublications[#1]% + {\getparameters + [\??pb] + [\c!alternative=,#1]% + \doifsomething\@@pbalternative + {\readsysfile + {bibl-\@@pbalternative.tex} + {\showmessage\m!publications{6}{bibl-\@@pbalternative}\let\@@pbalternative\empty} + {\showmessage\m!publications{1}{bibl-\@@pbalternative}\let\@@pbalternative\empty}}% + \getparameters + [\??pb] + [#1]% + \processaction + [\@@pbcriterium] + [ \v!all=>\typesetalltrue, + \s!unknown=>\typesetallfalse]% + \processaction + [\@@pbautohang] + [ \v!yes=>\autohangtrue, + \s!unknown=>\autohangfalse]% + \processaction + [\@@pbsorttype] + [ \v!cite=>\sortbycitetrue, + \v!bbl=>\sortbycitefalse, + \s!default=>\sortbycitetrue, + \s!unknown=>\sortbycitefalse]% + \processaction + [\@@pbnumbering] + [ \v!yes=>\let\@@pbinumbercommand\firstofoneargument, + \v!no=>\let\@@pbinumbercommand\gobbleoneargument, + \v!short=>\def\@@pbinumbercommand##1{\getvalue{pbds-\@@pbk}}, + \v!bib=>\def\@@pbinumbercommand##1{\getvalue{pbdn-\@@pbk}}, + \s!unknown=>\let\@@pbinumbercommand\firstofoneargument]% + \processaction + [\@@pbrefcommand] + [\s!default=>\edef\@@citedefault{\@@pbrefcommand}, + \s!unknown=>\edef\@@citedefault{\@@pbrefcommand}]} + +% initialize + +\def\@@pbrefcommand{num} +\def\@@pbnumbercommand{\bibleftnumber} + +%D \macros{usepublications} +%D +%D We need \type{\usereferences} so that it is possible to +%D refer to page and/or appearance number for publications +%D in the other document. + +\def\usepublications[#1]% + {\usereferences[#1]\processcommalist[#1]\dousepublications} + +\def\dousepublications#1% + {\doonlyonce + {#1.\f!bibextension} + {\readfile{#1.\f!bibextension} + {\showmessage\m!publications{4}{#1.\f!bibextension}} + {\showmessage\m!publications{2}{#1.\f!bibextension}}}} + +%D \macros{setuppublicationlist} +%D +%D This will be the first command in (\BIBTEX-generated) \type{bbl} +%D files. `samplesize' is a sample value (in case of \BIBTEX-generated +%D files, this will be the longest `short' key). `totalnumber' +%D is the total number of entries that will follow in this +%D file. + +%D Both values are only needed for the label calculation +%D if `autohang' is `true', so by default the command is +%D not even needed, and therefore I saw no need to give +%D it it's own system variable and it just re-uses \type{pb}. + +\def\setuppublicationlist + {\dosingleempty\dosetuppublicationlist} + +\def\dosetuppublicationlist[#1]% + {\getparameters[\??pv data][#1]% + \setuplist + [pubs] + [\c!samplesize={AA99},\c!totalnumber={99}, + \c!alternative=a,\c!interaction=,\c!pagenumber=\v!no,#1]} + +\def\setuppublicationlayout[#1]#2% + {\setvalue{\??pv data#1}{#2\unskip}} + +%D \macros{bibalternative} +%D +%D A nice little shorthand that will be used so we don't have to +%D key in the weird \type{\@@pv} parameter names all the time. + +\def\bibalternative#1% + {\getvalue{\??pv\@@currentalternative#1}} + +%D \macros{simplebibdef,bibcommandlist} +%D +%D \type{\simplebibdef} defines \type{bib@#1}, which in turn will +%D use one argument that is stored in \type{@@pb@#1}. +%D +%D \type{\simplebibdef} also defines \type{insert#1}, which can be +%D used in the argument of \type{\setuppublicationlayout} to fetch +%D one of the \type{@@pb@} data entries. \type{insert#1} then has +%D three arguments: \type{#1} are commands to be executed before the +%D data, \type{#2} are commands to be executed after the data, and +%D \type{#3} are commands to be executed if the data is not found. + +%D \type{\bibcommandlist} is the list of commands that is affected +%D by this approach. Later on, it will be used to do a series +%D of assignments from \type{#1} to \type{bib@#1}: e.g +%D \type{\title} becomes \type{\bib@title} when used within +%D a publication. + +\newtoks\initializebibdefinitions % we need to prevent clashes (HH) + +% \def\simplebibdef#1% hh: funny expansion ? +% {\@EA\long\@EA\def\csname bib@#1\endcsname##1% +% {\setvalue{\??pb @#1}{##1}% +% \ignorespaces}% +% \@EA\def\csname insert#1\endcsname##1##2##3% +% {\@EA\bibdoifelse +% \@EA{\csname @@pb@#1\endcsname}% +% {##1\csname @@pb@#1\endcsname##2}% +% {##3}% +% }} + +\def\simplebibdef#1% hh: funny expansion ? + {\@EA\long\@EA\def\csname bib@#1\endcsname##1% + {\setvalue{\??pb @#1}{##1}\ignorespaces}% + \expandafter \appendtoks + \expandafter\let\csname insert#1\expandafter\endcsname\csname bibinsert#1\endcsname + \to \initializebibdefinitions + \@EA\unexpanded\@EA\def\csname bibinsert#1\endcsname##1##2##3% + {\@EA\bibdoifelse\@EA{\csname\??pb @#1\endcsname}{##1\csname\??pb @#1\endcsname##2}{##3}}} + +\def\bibcommandlist + {abstract, annotate, arttitle, assignee, bibnumber, bibtype, biburl, chapter, city, + comment, country, day, dayfiled, doi, edition, eprint, howpublished, isbn, issn, + issue, journal, keyword, keywords, lastchecked, month, monthfiled, names, nationality, + note, notes, organization, pages, pubname, pubyear, revision, series, size, thekey, + title, volume, yearfiled} + +\processcommacommand[\bibcommandlist]\simplebibdef + +\def\bibinsertdoi#1#2#3% + {{\bibdoifelse{\@@pb@doi}% + {\edef\ascii{\@EA\detokenize\@EA{\@@pb@doi}}% + #1\expanded{\gotoDOI{\@@pb@thekey}{\ascii}}#2}{#3}}} + +\def\bibinsertbiburl#1#2#3% + {{\bibdoifelse{\@@pb@biburl}% + {\edef\ascii{\@EA\detokenize\@EA{\@@pb@biburl}}% + #1\expanded{\gotoURL{\@@pb@thekey}{\ascii}}#2}{#3}}} + +\def\bibinsertmonth#1#2#3% + {\bibdoifelse{\@@pb@month}% + {#1\doifnumberelse{\@@pb@month}% + {\doifconversiondefinedelse\@@pbmonthconversion + {\convertnumber\@@pbmonthconversion{\@@pb@month}}{\@@pb@month}}% + {\@@pb@month}#2}{#3}} + +\appendtoks + \let\inserturl \bibinsertbiburl % for backward compat. + \let\inserttype\bibinsertbibtype % for backward compat. +\to\initializebibdefinitions + +\def\newbibfield[#1]% + {\simplebibdef{#1}% + \edef\bibcommandlist{\bibcommandlist,#1}} + +%D \macros{bib@crossref} +%D +%D \type{\crossref} is used in database files to point to another +%D entry. Because of this special situation, it has to be defined +%D separately. Since this command will not be seen until at +%D \type{\placepublications}, it may force extra runs. The same is +%D true for \type{\cite} commands inside of publications. + +\def\bib@crossref#1% + {\setvalue{\??pb @crossref}{#1}\ignorespaces} + +\def\bibinsertcrossref#1#2#3% + {\bibdoifelse{\@@pb@crossref} + {#1\@EA\cite\@EA[\@@pb@crossref]#2} + {#3}} + +\appendtoks\let\insertcrossref\bibinsertcrossref\to\initializebibdefinitions + +%D \macros{complexbibdef,specialbibinsert} +%D +%D The commands \type{\artauthor}, \type{\author} and +%D \type{\editor} are more complex than the other commands. +%D Their argument lists have this form: +%D +%D \type{\author[junior]{firstnames}[inits]{von}{surname}} +%D +%D (bracketed stuff is optional) +%D +%D And not only that, but there also might be more than one of each of +%D these commands. This is why a special command is needed to insert +%D them, as well as one extra counter for each command. + +%D All of these \type{\@EA}'s and \type{\csnames} make this code +%D look far more complex than it really is. For example, the argument +%D \type{author} defines the macro \type{\bib@author} to do two +%D things: increment the counter \type{\author@num} (let's say to 2) +%D and next store it's arguments in the macro \type{\@@pb@author2}. +%D And it defines \type{\insertauthors} to expand into +%D \starttyping +%D \specialbibinsert{author}{\author@num}{}{}{} +%D \stoptyping + +\def\docomplexbibdef#1% + {\def\currentype{#1}% + \dosingleempty\dodocomplexbibdef} + +\def\dodocomplexbibdef[#1]#2% + {\def\firstarg{#1}\def\secondarg{#2}% + \dosingleempty\dododocomplexbibdef} + +\def\dododocomplexbibdef[#1]#2#3% + {\@EA\increment\csname \currentype @num\endcsname + \setevalue{\??pb @\currentype\csname \currentype @num\endcsname}% + {{\secondarg}{#2}{#3}{#1}{\firstarg}}\ignorespaces}% + +% \def\complexbibdef#1% +% {\@EA\newcounter\csname #1@num\endcsname +% \@EA\def\csname bib@#1\endcsname{\docomplexbibdef{#1}}% +% \@EA\def\csname insert#1s\endcsname##1##2##3% +% {\specialbibinsert{#1}{\csname #1@num\endcsname}{##1}{\unskip ##2}{##3}}} + +\def\complexbibdef#1% + {\@EA\newcounter\csname #1@num\endcsname + \@EA\def\csname bib@#1\endcsname{\docomplexbibdef{#1}}% + \expandafter \appendtoks + \expandafter\let\csname insert#1s\expandafter\endcsname\csname bibinsert#1s\endcsname + \to \initializebibdefinitions + \@EA\def\csname bibinsert#1s\endcsname##1##2##3{\specialbibinsert{#1}{\csname #1@num\endcsname}{##1}{\unskip ##2}{##3}}} + +\processcommalist[author,artauthor,editor]\complexbibdef + +%D Another level of indirection is needed to control the +%D typesetting of all of these arguments. + +%D Btw, there is a conflict between `author' and the predefined interface +%D variable `auteur'. The old version is overruled `auteur' is +%D overruled by the systemconstant definition at the top of this file! + +\newcount\etallimitcounter +\newcount\etaldisplaycounter +\newcount\todocounter + +\def\specialbibinsert#1#2#3#4#5% + {\bgroup + \ifnum#2>\zerocount + \etallimitcounter =0\bibalternative{#1etallimit}\relax + \etaldisplaycounter=0\bibalternative{#1etaldisplay}\relax + \ifnum #2>\etallimitcounter + \todocounter\etaldisplaycounter + % just in case ... + \ifnum\todocounter>\etallimitcounter + \todocounter\etallimitcounter + \fi + \else + \todocounter#2\relax + \fi + \ifnum\todocounter>\zerocount + % find the current author list + \let\templist\empty + \dorecurse{#2} + {\toks0=\@EA\@EA\@EA{\csname @@pb@#1\recurselevel\endcsname}% + \ifx\templist\empty \edef\templist{\the\toks0}% + \else \edef\templist{\templist,\the\toks0}\fi }% + \doifdefinedelse + {\??pv data#1\c!command} + {\doifemptyelsevalue + {\??pv data#1\c!command} + {#3\dospecialbibinsert{#1}{\todocounter}{\templist}#4}% + {#3\getvalue{\??pv data#1\c!command}{#1}{\todocounter}{\templist}#4}}% + {#3\dospecialbibinsert{#1}{\todocounter}{\templist}#4}% + \else + #5% + \fi + \else + #5% + \fi + \egroup} + +%D This macro does the hard work of inserting a list of people in the +%D output, with proper regard of all the inbetween strings that can +%D arise depending on length of the list of people. + +%D \#1 = type +%D \#2 = number of items to be typeset +%D \#3 = commacommand containing authors + +\def\dospecialbibinsert#1#2#3% + {\getcommacommandsize[#3]% + \scratchcounter 0 + \def\processauthoritem##1% + {\advance\scratchcounter1 + \ifnum \numexpr\scratchcounter-1\relax<#2\relax + \getvalue{\??pv data#1}##1% + \ifnum \scratchcounter=#2\relax + \ifnum\etallimitcounter<\commalistsize\relax \bibalternative{#1etaltext}\fi + \else \ifnum\numexpr\scratchcounter+1 = #2\relax + \ifnum \commalistsize > \plustwo \bibalternative\c!finalnamesep + \else \bibalternative\c!lastnamesep \fi + \else + \bibalternative\c!namesep + \fi \fi + \fi}% + \processcommacommand[#3]\processauthoritem } + +%D \macros{invertedauthor,normalauthor,invertedshortauthor,normalshortauthor} +%D +%D Just some commands that can be used in \type{\setuppublicationparameters} +%D If you want to write an extension to the styles, you might +%D as well define some of these commands yourself. +%D +%D The argument liust has been reordered here, and the meanings +%D are: +%D +%D {\obeylines\parskip0pt +%D \type{#1} firstnames +%D \type{#2} von +%D \type{#3} surname +%D \type{#4} inits +%D \type{#5} junior +%D } +%D + +\def\normalauthor#1#2#3#4#5% + {\bibdoif{#1}{#1\bibalternative\c!firstnamesep}% + \bibdoif{#2}{#2\bibalternative\c!vonsep}% + #3% + \bibdoif{#5}{\bibalternative\c!surnamesep#5\unskip}} + +\def\normalshortauthor#1#2#3#4#5% + {\bibdoif{#4}{#4\bibalternative\c!firstnamesep}% + \bibdoif{#2}{#2\bibalternative\c!vonsep}% + #3% + \bibdoif{#5}{\bibalternative\c!surnamesep#5\unskip}} + +\def\invertedauthor#1#2#3#4#5% + {\bibdoif{#2}{#2\bibalternative\c!vonsep}% + #3% + \bibdoif{#5}{\bibalternative\c!juniorsep #5}% + \bibdoif{#1}{\bibalternative\c!surnamesep #1\unskip}} + +\def\invertedshortauthor#1#2#3#4#5% + {\bibdoif{#2}{#2\bibalternative\c!vonsep}% + #3% + \bibdoif{#5}{\bibalternative\c!juniorsep #5}% + \bibdoif{#4}{\bibalternative\c!surnamesep #4\unskip}} + +%D \macros{clearbibitem,clearbibitemtwo,bibitemdefs} +%D +%D These are used in \type{\typesetapublication} to do +%D initializations and cleanups. + +\def\clearbibitem#1{\setvalue{\??pb @#1}{}}% + +\def\clearbibitemtwo#1% + {\letvalue{#1@num}\!!zerocount + \scratchcounter\plusone + \doloop + {\doifdefinedelse{\??pb @#1\the\scratchcounter} + {\letvalue{\??pb @#1\the\scratchcounter}\empty + \advance\scratchcounter\plusone}% + {\exitloop}}} + +\def\bibitemdefs#1% + {\@EA\let\@EA\tempa \csname bib@#1\endcsname + \@EA\let\csname #1\endcsname \tempa } + +%D \macros{startpublication} +%D +%D We are coming to the end of this module, to the macros that +%D do typesetting and read the \type{bbl} file. + +\newcounter\bibcounter + +%D Just a \type{\dosingleempty} is the most friendly +%D of doing this: there need not even be an argument +%D to \type{\startpublication}. Of course, then there +%D is no key either, and it had better be an +%D article (otherwise the layout will be all screwed up). +%D +%D Now prohibits comments, so % can be used for urls + +\def\startpublication + {\edef\bibmodsavedpercent{\the\catcode`\%}% + \catcode`\%=12 + \dosingleempty\dostartpublication} + +\def\stoppublication + {} % the \catcode of % is reset below + +%D Only specifying the key in the argument is also +%D legal. In storing this stuff into macros, some trickery with +%D token registers is needed to fix the expansion problems. Even so, +%D this appears to not always be 100\% safe, so people are +%D urgently advised to use \ETEX\ instead of traditional \TEX. +%D +%D In \ETEX, all expansion problems are conviniently solved by +%D the primitive \type{\protected}. To put that another way: +%D +%D It's not a bug in this module if it does not appear in \ETEX! + +\long\def\dostartpublication[#1]#2\stoppublication% + {\increment\bibcounter + \bgroup + \doifassignmentelse{#1}% + {\getparameters[\??pb][k=,t=article,n=,s=,a=,y=,o=,u=,#1]}% + {\getparameters[\??pb][k=#1,t=article,n=,s=,a=,y=,o=,u=]}% + \@EA\toks\@EA2\@EA{\@@pba}% + \@EA\toks\@EA4\@EA{\@@pbs}% + \toks0={\ignorespaces #2}% + \setxvalue{pbdk-\@@pbk}{\@@pbk} + \setxvalue{pbda-\@@pbk}{\the\toks2} + \setxvalue{pbdy-\@@pbk}{\@@pby} + \setxvalue{pbds-\@@pbk}{\the\toks4} + \setxvalue{pbdn-\@@pbk}{\@@pbn} + \setxvalue{pbdt-\@@pbk}{\@@pbt} + \setxvalue{pbdo-\@@pbk}{\@@pbo} + \setxvalue{pbdu-\@@pbk}{\@@pbu} + \setxvalue{pbdd-\@@pbk}{\the\toks0} + \xdef\allrefs{\allrefs,\@@pbk}% + \egroup + \catcode`\%=\bibmodsavedpercent\relax } + +% intialization of the order-list: + +\let\allrefs\empty + +%D The next macro is needed because the number command of the +%D publist sometimes needs to fetch something from the current +%D item (like the 'short' key). For this, the ID of the current +%D item is passed in the implict parameter \type{\@@pbk} + +\def\makepbkvalue#1{\def\@@pbk{#1}} + +\newif\ifinpublist + +% from Hans + +\def\ignoresectionconversion + {\let\@@sectionconversion\secondoftwoarguments} + +\let\normaldosetfilterlevel\dosetfilterlevel + +\def\patcheddosetfilterlevel#1#2% beware: this one is \let + {\bgroup + \ignoresectionconversion + \edef\askedlevel{#1}% + \edef\askedfilter{#2}% +% \message{ASKD: \meaning\askedlevel}% +% \message{PREV: \meaning\v!previous}% + \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\filllocalpublist% + {\doifdefinedelse{\alltoclevels} + {\let\dosetfilterlevel\patcheddosetfilterlevel + \dosettoclevel\??li{pubs}% + \let\dosetfilterlevel\normaldosetfilterlevel }% + {\dosettoclevel\??li{pubs}}% + \global\let\glocalpublist\empty + \doloop + {\doifdefinedelse + {\r!cross cite-\jobname-\recurselevel} + {\doifreferencefoundelse + {cite-\jobname-\recurselevel} + {\@EA\doifreglevelelse\@EA[\currentlocationreference] + {\@EA\doglobal\@EA\addtocommalist\@EA + {\currenttextreference}\glocalpublist}{}} + {}}% + {\exitloop}}% + \let\localpublist\glocalpublist} + +\def\typesetpubslist + {\dobeginoflist +% \the\initializebibdefinitions + \edef\askedlevel{\csname \??li pubs\c!criterium\endcsname}% + \ifx\askedlevel\v!all + \def\bibrefprefix{}% + \else % + \preparebibrefprefix + \fi + \ifsortbycite + \filllocalpublist + \iftypesetall + \let\localallrefs\allrefs + \processcommacommand[\localpublist]\typesetapublication + \def\removefromallrefs##1% + {\removefromcommalist{##1}\localallrefs }% + \processcommacommand[\localpublist]\removefromallrefs + \processcommacommand[\localallrefs]\typesetapublication + \else + \processcommacommand[\localpublist]\typesetapublication + \fi + \else + \iftypesetall + \processcommacommand[\allrefs]\typesetapublication + \else + % + \filllocalpublist + \processcommacommand[\allrefs]\maybetypesetapublication + \fi + \fi + \doendoflist} + +\newif\ifinpublist + +\def\maybetypesetapublication#1% + {\global\inpublistfalse + \def\test{#1}% + \def\runtest##1% + {\def\tempa{##1}\ifx \test\tempa \global\inpublisttrue \fi}% + \processcommacommand[\localpublist]\runtest + \ifinpublist \typesetapublication{#1}\fi} + +\def\initializepubslist + {\edef\@@pbnumbering{\@@pbnumbering}% + \ifautohang + \ifx\@@pbnumbering\v!short + \setbox\scratchbox\hbox{\@@pbnumbercommand{\getvalue{\??li pubs\c!samplesize}}}% + \else\iftypesetall + \setbox\scratchbox\hbox{\@@pbnumbercommand{\getvalue{\??li pubs\c!totalnumber}}}% + \else + \setbox\scratchbox\hbox{\@@pbnumbercommand{\numreferred}}% + \fi\fi + \edef\samplewidth{\the\wd\scratchbox}% + \setuplist[pubs][\c!width=\samplewidth,\c!distance=0pt]% + \ifx\@@pbnumbering\v!short + \def\@@pblimitednumber##1{\hbox to \samplewidth + {\@@pbnumbercommand{\getvalue{pbds-\@@pbk}}}}% + \else \ifx \@@pbnumbering\v!bib + \def\@@pblimitednumber##1{\hbox to \samplewidth + {\@@pbnumbercommand{\getvalue{pbdn-\@@pbk}}}}% + \else + \def\@@pblimitednumber##1{\hbox to \samplewidth{\@@pbnumbercommand{##1}}}% + \fi \fi + \else + \ifx\@@pbnumbering\v!short + \doifemptyelse + {\getvalue{\??li pubs\c!width}} + {\def\@@pblimitednumber##1{\hbox + {\@@pbnumbercommand{\getvalue{pbds-\@@pbk}}}}}% + {\def\@@pblimitednumber##1{\hbox to \getvalue{\??li pubs\c!width}% + {\@@pbnumbercommand{\getvalue{pbds-\@@pbk}}}}}% + \else \ifx \@@pbnumbering\v!bib + \doifemptyelse + {\getvalue{\??li pubs\c!width}} + {\def\@@pblimitednumber##1{\hbox + {\@@pbnumbercommand{\getvalue{pbdn-\@@pbk}}}}}% + {\def\@@pblimitednumber##1{\hbox to \getvalue{\??li pubs\c!width}% + {\@@pbnumbercommand{\getvalue{pbdn-\@@pbk}}}}}% + \else + \doifemptyelse + {\getvalue{\??li pubs\c!width}} + {\def\@@pblimitednumber##1{\hbox{\@@pbnumbercommand{##1}}}}% + {\def\@@pblimitednumber##1{\hbox to \getvalue{\??li pubs\c!width}{\@@pbnumbercommand{##1}}}}% + \fi + \fi + \fi + \ifx\@@pbnumbering\v!no + \setuplist[pubs][\c!numbercommand=,\c!symbol=\v!none,\c!textcommand=\outdented]% + \else + \setuplist[pubs][\c!numbercommand=\@@pblimitednumber]% + \fi + \doifelsevalue + {\??pv data\c!maybeyear}{\v!off}{\def\maybeyear##1{}}{\def\maybeyear##1{##1}}% + \forgetall} % bugfix 2005/03/18 + +\def\outdented#1% move to supp-box ? + {\hskip -\hangindent #1} + +%D The full list of publications + +\def\completepublications + {\dosingleempty\docompletepublications} + +\def\bibdogetupsometextprefix#1#2#3% + {\ifcsname#2#1#3\endcsname + \csname#2#1#3\endcsname + \else\ifcsname\??la#1\c!default\endcsname + \@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 + \fi\fi + \else + \expandafter\bibdogetupsometextprefix + \csname\??la#1\c!default\endcsname{#2}{#3}% + \fi + \else + \ifcsname#2#3\endcsname + \csname#2#3\endcsname + \else\ifcsname#2\s!en#3\endcsname + \csname#2\s!en#3\endcsname + \fi\fi + \fi\fi} + +\def\docompletepublications[#1]% + {\begingroup + \setuplist[pubs][\c!criterium=\v!previous,#1] + \begingroup + \let\handletextprefix\firstoftwoarguments + \edef\headtextpubs{\bibdogetupsometextprefix\headlanguage\c!title{pubs}}% + \doifdefinedelse + {\??pv data\v!title} + {\doifemptyelsevalue + {\??pv data\v!title} + {\expanded{\systemsuppliedtitle[pubs]{\headtextpubs}}}% + {\expanded{\getvalue{\??pv data\v!title}{\headtextpubs}}}% + }% + {\expanded{\systemsuppliedtitle[pubs]{\headtextpubs}}}% + \endgroup + \dodoplacepublications } + +%D And the portion with the entries only. + +\def\placepublications + {\dosingleempty\doplacepublications} + +\def\doplacepublications[#1]% + {%\getparameters[\??pv data][#1] + \begingroup + \setuplist[pubs][\c!criterium=\v!previous,#1]% + \dodoplacepublications }% + +\def\dodoplacepublications% + {\initializepubslist + \doifelsevalue + {\??li pubs\c!option}{\v!continue}% + {}% + {\global\let\bibcounter\!!zerocount }% + \inpublisttrue + \typesetpubslist + \inpublistfalse + \endgroup} + +%D \subsubject{What's in a publication} + +\unexpanded\def\typesetapublication#1% + {\doifsomething{#1} + {\doglobal\increment\bibcounter + \bgroup + \the\initializebibdefinitions + \makepbkvalue{#1}% + \ifgridsnapping + \snaptogrid\vbox{\dodolistelement{pubs}{}{\bibcounter}% + {\expanded{\reference[\bibrefprefix#1]{\bibcounter}}% + \strut \dotypesetapublication{#1}\strut }{}{}}% + \else + \dodolistelement{pubs}{}{\bibcounter}% + {\expanded{\reference[\bibrefprefix#1]{\bibcounter}}% + \strut \dotypesetapublication{#1}\strut }{}{}% + \fi + \egroup}} + +\def\dotypesetapublication#1% + {\bgroup + \def\@@currentalternative{data}% + \processcommacommand[\bibcommandlist,crossref]\clearbibitem + \processcommalist [artauthor,author,editor]\clearbibitemtwo + \processcommacommand[\bibcommandlist]\bibitemdefs + \processcommalist [artauthor,author,editor,crossref]\bibitemdefs + \let\biblanguage\empty + \getvalue{pbdd-#1}% + \ifcsname pbdt-#1\endcsname \bibalternative{\getvalue{pbdt-#1}}\fi + \egroup } + +%D An afterthought: + +\def\maybeyear#1{} + +%D An another: + +\def\noopsort#1{} + +%D This is the result of bibtex's `language' field. + +\def\setbiblanguage#1#2{\setvalue{\??pb @lang@#1}{#2}} + +\def\lang#1% + {\def\biblanguage{#1}% + \ifcsname \??pb @lang@#1\endcsname + \expanded{\language[\getvalue{\??pb @lang@#1}]}% + \fi \ignorespaces} + +%D \subject{Citations} +%D +%D \macros{cite,bibref} +%D +%D The indirection with \type{\dobibref} allows \LATEX\ style +%D \type{\cite} commands with a braced argument (these might appear +%D in included data from the \type{.bib} file). + +% \unexpanded\def\cite +% {\doifnextcharelse{[} +% {\dodocite} +% {\dobibref}} +% \def\dobibref#1% +% {\docite[#1][]} +% \def\dodocite[#1]% +% {\startstrictinspectnextcharacter +% \dodoubleempty\dododocite[#1]} +% \def\dododocite[#1][#2]{% +% \stopstrictinspectnextcharacter +% \docite[#1][#2]} + +\unexpanded\def\cite + {\strictdoifnextoptionalelse\dodocite\dobibref} + +\def\dobibref#1% + {\docite[#1][]} + +\def\dodocite[#1]% + {\strictdoifnextoptionalelse{\docite[#1]}{\docite[#1][]}} + +\def\docite[#1][#2]% + {\begingroup + \setupinteraction[\c!style=]% + \edef\temp{#2}% + \ifx\empty\temp \secondargumentfalse + \else \secondargumenttrue \fi + \ifsecondargument + \processcommalist[#2]\docitation + \doifassignmentelse + {#1}% + {\getparameters[LO][\c!alternative=,\c!extras=,#1]% + \edef\@@currentalternative{\LOalternative}% + \ifx\@@currentalternative\empty + \edef\@@currentalternative{\@@citedefault}% + \fi + \ifx\LOextras\empty + \setupcite[\@@currentalternative][#1]% + \else + \expandafter\ifx\csname LOright\endcsname \relax + \edef\LOextras{{\LOextras\bibalternative\c!right}}% + \else + \edef\LOextras{{\LOextras\LOright}}% + \fi + \expanded{\setupcite[\@@currentalternative][#1,\c!right=\LOextras]}% + \fi + }% + {\def\@@currentalternative{#1}}% + \expanded{% + \processaction[\csname @@pv\@@currentalternative \c!compress\endcsname]} + [ \v!yes=>\bibcitecompresstrue, + \v!no=>\bibcitecompressfalse, + \s!default=>\bibcitecompresstrue, + \s!unknown=>\bibcitecompresstrue]% + \getvalue{bib\@@currentalternative ref}[#2]% + \else + \processcommalist[#1]\docitation + \expanded{\processaction[\csname @@pv\@@citedefault \c!compress\endcsname]} + [ \v!yes=>\bibcitecompresstrue, + \v!no=>\bibcitecompressfalse, + \s!default=>\bibcitecompresstrue, + \s!unknown=>\bibcitecompresstrue]% + \edef\@@currentalternative{\@@citedefault}% + \getvalue{bib\@@citedefault ref}[#1]% + \fi + \endgroup} + +%D \macros{nocite} + +\def\nocite[#1]% + {\processcommalist[#1]\addthisref + \processcommalist[#1]\docitation } + +%D \macros{setupcite} + +\def\setupcite{\dodoubleempty\dosetupcite} + +\def\dosetupcite[#1][#2]% + {\ifsecondargument + \def\dodosetupcite##1{\getparameters[\??pv##1][#2]}% + \processcommalist[#1]\dodosetupcite + \else % default case + \getparameters[\??pv\@@citedefault][#1]% + \fi } + +%D Low-level stuff + +\def\getcitedata#1[#2]#3[#4]#5to#6% + {\bgroup + \addthisref{#4}% + \dofetchapublication{#4}% + \doifdefinedelse{@@pb@bib#2}% + {\xdef#6{\getvalue{@@pb@bib#2}}}% + {\xdef#6{\getvalue{@@pb@#2}}}% + \egroup} + +\def\dofetchapublication#1% + {\makepbkvalue{#1}% + \processcommacommand[\bibcommandlist,crossref]\clearbibitem + \processcommalist [artauthor,author,editor]\clearbibitemtwo + \processcommacommand[\bibcommandlist]\bibitemdefs + \processcommalist [artauthor,author,editor,crossref]\bibitemdefs + \getvalue{pbdd-#1}} + +%D This new version writes a reference out to the tui file for every +%D \type{\cite}. This will allow backlinking. +%D +%D Some special care is needed so that references are not added from +%D weird locations like in the TOC or within a \type{\setbox} command. + +\newcounter\citationnumber + +\def\docitation#1{% + \iftrialtypesetting \else + \ifdoinpututilities\else + \doglobal\increment\citationnumber + \expanded{\rawreference{}{cite-\jobname-\citationnumber}{#1}}% + \fi \fi } + +%D \macros{numreferred,doifreferredelse,addthisref,publist} +%D +%D The interesting command here is \type{\addthisref}, which maintains +%D the global list of references. +%D +%D \type{\numreferred} is needed to do automatic calculations on +%D the label width, and \type{\doifreferredelse} will be used +%D to implement \type{criterium=cite}. + +\newcounter\numreferred + +\long\def\doifreferredelse#1{\doifdefinedelse{pbr-#1}} + +\def\addthisref#1% + {\doifundefinedelse{pbr-#1} + {\setxvalue{pbr-#1}{\citationnumber}% + \doglobal\increment\numreferred + \ifx\publist\empty \gdef\publist{#1}\else\appended\gdef\publist{,#1}\fi} + {\setxvalue{pbr-#1}{\getvalue{pbr-#1},\citationnumber}}} + +\let\publist\empty + +%D \macros{doifbibreferencefoundelse} +%D +%D Some macros to fetch the information provided by +%D \type{\startpublication}. + +\def\doifbibreferencefoundelse#1% + {\preloadbiblist + \doifdefinedelse{pbdk-#1} + {\firstoftwoarguments} + {\showmessage\m!publications{5}{#1 is unknown}% + \secondoftwoarguments}} + +%D \macros{ixbibauthoryear,thebibauthors,thebibyears} +%D +%D If compression of \type{\cite}'s argument expansion is on, +%D the macros that deal with authors and years call this internal +%D command to do the actual typesetting. +%D +%D Two entries with same author but with different years may +%D be condensed into ``Author (year1,year2)''. This is about the +%D only optimization that makes sense for the (author,year) +%D style of citations (years within one author have to be unique +%D anyway so no need to test for that, and ``Author1, Author2 (year)'' +%D creates more confusion than it does good). +%D +%D In the code below, +%D the macro \type{\thebibauthors} holds the names of the alternative +%D author info fields for the current list. This is a commalist, +%D and \type{\thebibyears} holds the (collection of) year(s) that go with +%D this author (possibly as a nested commalist). +%D +%D There had better be an author for all cases, but there +%D does not have to be year info always. \type{\thebibyears} is +%D pre-initialized because this makes the insertion macros simpler. +%D +%D In `normal' \TeX, of course there are expansion problems again. + +\def\ixbibauthoryear#1#2#3#4% + {\bgroup + \gdef\ixlastcommand {#4}% + \gdef\ixsecondcommand{#3}% + \gdef\ixfirstcommand {#2}% + \glet\thebibauthors \empty + \glet\thebibyears \empty + \getcommalistsize[#1]% + \ifbibcitecompress + \dorecurse\commalistsize{\xdef\thebibyears{\thebibyears,}}% + \processcommalist[#1]\docompressbibauthoryear + \else + \processcommalist[#1]\donormalbibauthoryear + \fi + \egroup + \dobibauthoryear} + +%D \macros{dodobibauthoryear} +%D +%D This macro only has to make sure that the lists +%D \type{\thebibauthors} and \type{\thebibyears} are printed. + +\def\dobibauthoryear + {\scratchcounter\zerocount + \getcommacommandsize[\thebibauthors]% + \edef\authorcount{\commalistsize}% + \@EA\processcommalist\@EA[\thebibauthors]\dodobibauthoryear} + +\def\dodobibauthoryear#1% + {\advance\scratchcounter\plusone + \edef\wantednumber{\the\scratchcounter}% + \getfromcommacommand[\thebibyears][\wantednumber]% + \@EA\def\@EA\currentbibyear\@EA{\commalistelement}% + \setcurrentbibauthor{#1}% + \ifnum\scratchcounter=\plusone + \ixfirstcommand + \else\ifnum \scratchcounter=\authorcount\relax + \ixlastcommand + \else + \ixsecondcommand + \fi\fi} + +\def\setcurrentbibauthor#1% + {\getcommacommandsize[#1]% + \ifcase\commalistsize + % anonymous? + \def\currentbibauthor{}% + \or + \def\currentbibauthor{#1}% + \or + \expanded{\docurrentbibauthor#1}% + \else + \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. + +\def\docurrentbibauthor#1,#2% + {\doifemptyelse{#2} + {\def\currentbibauthor{#1\bibalternative{otherstext}}} + {\@EA + \ifx\csname \??pv\@@currentalternative authoretallimit\endcsname\relax + \edef\currentbibauthor{#1\bibalternative{andtext}#2}% + \else + \edef\currentbibauthor{#1% + \ifcase0\bibalternative{authoretallimit}\relax\or + \bibalternative{otherstext}\else\bibalternative{andtext}#2\fi}% + \fi}} + +%D This is not the one Hans made for me, because I need a global +%D edef, and the \type{\robustdoifinsetelse} doesn't listen to +%D \type{\doglobal } + +\def\robustaddtocommalist#1#2% {item} \cs + {\robustdoifinsetelse{#1}#2\resetglobal + {\dodoglobal\xdef#2{\ifx#2\empty\else#2,\fi#1}}} + +%D \macros{donormalbibauthoryear} +%D +%D Now we get to the macros that fill the two lists. +%D The `simple' one really is quite simple. + +\def\donormalbibauthoryear#1% + {\addthisref{#1}% + \def\myauthor{Xxxxxxxxxx}% + \def\myyear{0000}% + \doifbibreferencefoundelse{#1} + {\def\myauthor{{\getvalue{pbda-#1}}}% + \def\myyear {\getvalue{pbdy-#1}}}% + {}% + \@EA\doglobal\@EA\appendtocommalist\@EA{\myauthor}\thebibauthors + \@EA\doglobal\@EA\appendtocommalist\@EA{\myyear }\thebibyears} + +%D \macros{docompressbibauthoryear} +%D +%D So much for the easy parts. Nothing at all will be done if +%D the reference is not found or the reference does not contain +%D author data. No questions marks o.s.s. (to be fixed later) + +\def\docompressbibauthoryear#1% + {\addthisref{#1}% + \def\myauthor{Xxxxxxxxxx}% + \def\myyear {0000}% + \doifbibreferencefoundelse{#1} + {\xdef\myauthor{\csname pbda-#1\endcsname }% + \xdef\myyear {\csname pbdy-#1\endcsname }} + {}% + \ifx\myauthor\empty\else + \checkifmyauthoralreadyexists + \findmatchingyear + \fi} + +%D two temporary counters. One of these two can possibly be replaced +%D by \type{\scratchcounter}. + +\newcount\bibitemcounter +\newcount\bibitemwanted + +%D The first portion is simple enough: if this is the very first author +%D it is quite straightforward to add it. \type{\bibitemcounter} and +%D \type{\bibitemwanted} are needed later to insert the year +%D information in the correct item of \type{\thebibyears} + +\def\checkifmyauthoralreadyexists + {\doifemptyelsevalue{thebibauthors} + {\global\bibitemwanted \plusone + \global\bibitemcounter \plusone + \xdef\thebibauthors{{\myauthor}}} + {% the next weirdness is because according to \getcommalistsize, + % the length of \type{[{{},{}}]} is 2. + \@EA\getcommalistsize\@EA[\thebibauthors,]% + \global\bibitemcounter\commalistsize + \global\advance\bibitemcounter\minusone + \global\bibitemwanted \zerocount + \processcommacommand[\thebibauthors]\docomparemyauthor}} + +%D The outer \type{\ifnum} accomplishes the addition of +%D a new author to \type{\thebibauthors}. The messing about with +%D the two counters is again to make sure that \type{\thebibyears} +%D will be updated correctly.If the author {\it was} found, +%D the counters will stay at their present values and everything +%D will be setup properly to insert the year info. + +\def\docomparemyauthor#1% + {\global\advance\bibitemwanted \plusone + \def\mytempc{#1}% +% \message{authors: \myauthor <=>\mytempc \ifx\mytempc\myauthor :Y \else :N +% \meaning \myauthor, \meaning\mytempc\fi (\the\bibitemwanted = \the\bibitemcounter)}% + \ifx\mytempc\myauthor + \quitcommalist + \else + \ifnum\bibitemwanted = \bibitemcounter\relax + \global\advance\bibitemwanted \plusone + \global\bibitemcounter\bibitemwanted\relax + \@EA\doglobal\@EA\robustaddtocommalist\@EA{{\myauthor}}\thebibauthors + \fi + \fi} + +%D This macro should be clear now. + +\def\findmatchingyear + {\edef\wantednumber{\the\bibitemwanted}% + \getfromcommacommand[\thebibyears][\wantednumber]% + \ifx\commalistelement\empty + \edef\myyear{{\myyear}}% + \else + \edef\myyear{{\commalistelement, \myyear}}% + \fi + \edef\newcommalistelement{\myyear}% + \doglobal\replaceincommalist \thebibyears \wantednumber} + +%D \macros{preparebibrefprefix} +%D +%D The reference list only writes bare references when the criterium +%D is `all'. Otherwise, a prefix is added to make sure that pdfTeX +%D does not encounter duplicate named references. On the generation +%D side, this is not a big problem. \type{\preparebibrefprefix} +%D creates a suitable string to prepend if a prefix is needed. +%D +%D Because this macro is used within \type{\cite } that itself +%D can be used within lists like the table of contents, it needs +%D to save and restore \type{\savedalltoclevels} and +%D \type{\currentlevel} (\type{\dosetfilterlevel} needs to change +%D their values globally). + +\def\preparebibrefprefix + {\chardef\savedalltoclevels \alltoclevels + \let\savedcurrentlevel\currentlevel + \let\dosetfilterlevel\patcheddosetfilterlevel + \dosettoclevel\??li{pubs}% + \edef\bibrefprefix{\@@sectiontype\currentlevel\sectionseparator}% + \let\dosetfilterlevel\normaldosetfilterlevel + \global\let\currentlevel\savedcurrentlevel + \global\chardef\alltoclevels \savedalltoclevels } + +%D \macros{preparebibreflist} +%D +%D But this optional prefixing is a bit of a problem on the +%D other side. We would like to do \type{\goto{}[article-full]} +%D but can't do it like that, because the actual label may be +%D \type{1:2:0:3:4:article-full]} or so. The problem is solved +%D by building a commalist that looks like this: +%D \starttyping +%D \def\bibreflist% +%D {1:2:0:3:4:article-full, +%D 1:2:0:3:article-full, +%D 1:2:0:article-full, +%D 1:2:article-full, +%D 1:article-full, +%D article-full} +%D \stoptyping + +\def\preparebibreflist#1% + {\let\bibreflist\empty + \def\storeitem##1% + {\ifx\bibreflist\empty + \edef\prefix{##1\sectionseparator}% + \edef\bibreflist{\prefix#1,#1}% + \else + \edef\prefix{\prefix##1\sectionseparator}% + \edef\bibreflist{\prefix#1,\bibreflist}% + \fi}% + \expanded{\processseparatedlist[\bibrefprefix][\sectionseparator]}\storeitem } + +%D \macros{gotobiblink,inbiblink,atbiblink} +%D +%D The final task is looping over that list until a match is found. + +\newif\ifbibreffound + +\def\gotobiblink#1[#2]% + {\bgroup + \preparebibrefprefix + \preparebibreflist{#2}% + \global\bibreffoundfalse + \def\setuplink##1% + {\ifbibreffound\else + \doifreferencefoundelse + {##1} + {\global\bibreffoundtrue \goto{#1}[##1]}% + {}\fi}% + \processcommacommand[\bibreflist]\setuplink + \ifbibreffound \else \unknownreference{#2}\fi + \egroup } + +\def\atbiblink[#1]% + {\bgroup + \preparebibrefprefix + \preparebibreflist{#1}% + \global\bibreffoundfalse + \def\setuplink##1% + {\ifbibreffound\else + \doifreferencefoundelse + {##1} + {\global\bibreffoundtrue \at[##1]}% + {}\fi}% + \processcommacommand[\bibreflist]\setuplink + \ifbibreffound \else \unknownreference{#1}\fi + \egroup } + +\def\inbiblink[#1]% + {\bgroup + \preparebibrefprefix + \preparebibreflist{#1}% + \global\bibreffoundfalse + \def\setuplink##1% + {\ifbibreffound\else + \doifreferencefoundelse + {##1} + {\global\bibreffoundtrue \in[##1]}% + {}\fi}% + \processcommacommand[\bibreflist]\setuplink + \ifbibreffound \else \unknownreference{#1}\fi + \egroup } + +%D \macros{bibauthoryearref,bibauthoryearsref,bibauthorref,bibyearref} +%D +%D Now that all the hard work has been done, these are simple. +%D \type{\ixbibauthoryearref} stores the data in the macros +%D \type{\currentbibauthor} and \type{\currentbibyear}. + +\def\ifbibinteractionelse% + {\iflocation + \edef\test{\bibalternative\c!interaction}% + \ifx\test\v!stop + \@EA\@EA\@EA\secondoftwoarguments + \else + \@EA\@EA\@EA\firstoftwoarguments + \fi + \else + \@EA\secondoftwoarguments + \fi + } + +\def\bibmaybeinteractive#1#2% + {\ifbibcitecompress #2\else + \ifbibinteractionelse{\gotobiblink{#2}[#1]}{#2}\fi } + +\def\bibauthoryearref[#1]% + {\ixbibauthoryear{#1}% + {\bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween + \bibalternative\v!left{\currentbibyear}\bibalternative\v!right}} + {\bibalternative\c!pubsep + \bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween + \bibalternative\v!left {\currentbibyear}\bibalternative\v!right}} + {\bibalternative\c!lastpubsep + \bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween + \bibalternative\v!left {\currentbibyear}\bibalternative\v!right}}} + +\def\bibauthoryearsref[#1]% + {\bibalternative\v!left + \ixbibauthoryear{#1} + {\bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween{\currentbibyear}}} + {\bibalternative\c!pubsep + \bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween{\currentbibyear}}} + {\bibalternative\c!lastpubsep + \bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween{\currentbibyear}}}% + \bibalternative\v!right} + +\def\bibauthorref[#1]% + {\bibalternative\v!left + \ixbibauthoryear{#1}% + {\bibmaybeinteractive{#1}{{\currentbibauthor}}} + {\bibalternative\c!pubsep \bibmaybeinteractive{#1}{{\currentbibauthor}}} + {\bibalternative\c!lastpubsep\bibmaybeinteractive{#1}{{\currentbibauthor}}}% + \bibalternative\v!right} + +\def\bibyearref[#1]% + {\bibalternative\v!left + \ixbibauthoryear{#1}% + {\bibmaybeinteractive{#1}{{\currentbibyear}}} + {\bibalternative\c!pubsep \bibmaybeinteractive{#1}{{\currentbibyear}}} + {\bibalternative\c!lastpubsep\bibmaybeinteractive{#1}{{\currentbibyear}}}% + \bibalternative\v!right} + +%D ML problems: + +%D \macros{bibshortref,bibkeyref,bibpageref,bibtyperef,bibserialref} +%D +%D There is hardly any point in trying to compress these. The only +%D thing that needs to be done is making sure that +%D the separations are inserted correctly. And that is +%D what \type{\refsep} does. + +\newif\iffirstref + +\def\refsep{\iffirstref\firstreffalse\else\bibalternative\c!pubsep\fi} + +\def\bibshortref[#1]% + {\bibalternative\v!left + \firstreftrue\processcommalist[#1]\dobibshortref + \bibalternative\v!right} + +\def\dobibshortref#1% + {\addthisref{#1}\refsep + \doifbibreferencefoundelse{#1}{\gotobiblink{\getvalue{pbds-#1}}[#1]} + {\unknownreference{#1}}} + + +\def\bibserialref[#1]% + {\bibalternative\v!left + \firstreftrue\processcommalist[#1]\dobibserialref + \bibalternative\v!right} + +\def\dobibserialref#1% + {\addthisref{#1}\refsep + \doifbibreferencefoundelse{#1}{\gotobiblink{\getvalue{pbdn-#1}}[#1]} + {\unknownreference{#1}}} + +\def\bibkeyref[#1]% + {\bibalternative\v!left + \firstreftrue\processcommalist[#1]\dobibkeyref + \bibalternative\v!right} + +\def\dobibkeyref#1% + {\addthisref{#1}\refsep\gotobiblink{#1}[#1]} + +\def\gotoDOI#1#2% + {\ifbibinteractionelse + {\useURL[bibfooDoi#1][#2]% + \useURL[bibfoo#1][http://dx.doi.org/#2]% + \goto{\url[bibfooDoi#1]}[url(bibfoo#1)]} + {\hyphenatedurl{#2}}} + +\def\bibdoiref[#1]% + {\bibalternative\v!left + \firstreftrue\processcommalist[#1]\dobibdoiref + \bibalternative\v!right} + +\def\dobibdoiref#1% + {\addthisref{#1}\refsep + \doifbibreferencefoundelse{#1}{\expanded{\gotoDOI{#1}{\getvalue{pbdo-#1}}}} + {\unknownreference{#1}}} + +\def\biburlref[#1]% + {\bibalternative\v!left + \firstreftrue\processcommalist[#1]\dobiburlref + \bibalternative\v!right} + +\def\gotoURL#1#2% + {\ifbibinteractionelse + {\useURL[bibfoo#1][#2]\goto{\url[bibfoo#1]}[url(bibfoo#1)]} + {\hyphenatedurl{#2}}} + +\def\dobiburlref#1% + {\addthisref{#1}\refsep + \doifbibreferencefoundelse{#1}{\expanded{\gotoURL{#1}{\getvalue{pbdu-#1}}}} + {\unknownreference{#1}}} + +\def\bibtyperef[#1]% + {\bibalternative\v!left + \firstreftrue\processcommalist[#1]\dobibtyperef + \bibalternative\v!right} + +\def\dobibtyperef#1% + {\addthisref{#1}\refsep + \doifbibreferencefoundelse{#1}{\gotobiblink{\getvalue{pbdt-#1}}[#1]} + {\unknownreference{#1}}} + +\def\bibpageref[#1]% + {\bibalternative\v!left + \firstreftrue\processcommalist[#1]\dobibpageref + \bibalternative\v!right} + +\def\dobibpageref#1% + {\addthisref{#1}\refsep + \ifbibinteractionelse{\atbiblink[#1]}{{\referencingfalse\at[#1]}}} + +\def\bibdataref[#1]% + {\bibalternative\v!left + \firstreftrue\processcommalist[#1]\dobibdata + \bibalternative\v!right} + +\def\dobibdata#1% + {\addthisref{#1}\refsep + \doifbibreferencefoundelse{#1}{\dotypesetapublication{#1}} + {\unknownreference{#1}}} + +\let\bibnoneref\nocite + +%D \macros{bibnumref} +%D +%D It makes sense to try and compress the argument list of +%D \type{\bibnumref}. There are two things involved: the actual +%D compression, and a sort routine. The idea is to store the +%D found values in a new commalist called \type{\therefs}. + +%D But that is not too straight-forward, because \type{\in} is +%D not expandable, +%D so that the macro \type{\expandrefs} is needed. + +\def\expandrefs#1% + {\bgroup + \preparebibrefprefix + \preparebibreflist{#1}% + \global\bibreffoundfalse + \def\setuplink##1% + {\ifbibreffound\else + \doifreferencefoundelse + {##1} + {\global\bibreffoundtrue + \@EA\doglobal\@EA\addtocommalist\@EA{\reftypet}\therefs }% + {}\fi}% + \processcommacommand[\bibreflist]\setuplink + \ifbibreffound \else \showmessage\m!publications{5}{#1 unknown}% + \doglobal\addtocommalist{0}\therefs\fi + \egroup } + +%D But at least the actual sorting code is simple (note that sorting +%D a list with exactly one entry fails to return anything, which +%D is why the \type{\ifx} is needed). + +\def\bibnumref[#1]% + {\bibalternative\v!left + \penalty\!!tenthousand + \processcommalist[#1]\addthisref + \firstreftrue + \ifbibcitecompress + \glet\therefs\empty + \processcommalist[#1]\expandrefs + \sortcommacommand[\therefs]\donumericcompare + \ifx\empty\sortedcommalist\else + \let\therefs\sortedcommalist + \fi + \compresscommacommandnrs[\therefs]% + \processcommacommand[\compressedlist]\verysimplebibnumref + \else + \processcommalist[#1]\dosimplebibnumref + \fi + \bibalternative\v!right} + +\def\dosimplebibnumref #1% + {\refsep\ifbibinteractionelse + {\inbiblink[#1]}{{\referencingfalse\inbiblink[#1]}}} + +\def\verysimplebibnumref#1{\doverysimplebibnumref#1} + +\def\doverysimplebibnumref#1#2% + {\refsep + \ifcase#1\relax \unknownreference{#1}\else + \def\tempa{#2}\ifx\empty\tempa#1\else#1\bibalternative\c!inbetween#2\fi + \fi} + +%D By request from Sanjoy. This makes it easier to implement +%D \type{\citeasnoun}. + +\def\bibauthornumref[#1]% + {\getcommalistsize[#1]% + \global\bibitemcounter\commalistsize + \firstreftrue + \processcommalist[#1]\dobibauthornumref } + +\def\dobibauthornumref#1% + {\addthisref{#1}\refsep + \doifbibreferencefoundelse{#1} + {\getvalue{pbda-#1}% + \bibalternative\c!inbetween + \bibalternative\v!left + \ifbibinteractionelse{\inbiblink[#1]} + {{\referencingfalse\inbiblink[#1]}}% + \bibalternative\v!right} + {\unknownreference{#1}}} + +%D And some defaults are loaded from bibl-apa: + +\setuppublications + [\v!month\v!conversion=, + \c!alternative=apa] + +\appendtoks + \preloadbiblist +\to \everystarttext + +\protect \endinput diff --git a/tex/context/base/bibl-tra.mkiv b/tex/context/base/bibl-tra.mkiv new file mode 100644 index 000000000..519af0c6f --- /dev/null +++ b/tex/context/base/bibl-tra.mkiv @@ -0,0 +1,1552 @@ +%D \module +%D [ file=bibl-tra, +%D version=2009.08.22, +%D title=\CONTEXT\ Publication Module, +%D subtitle=Publications, +%D author=Taco Hoekwater, +%D date=\currentdate, +%D copyright=Public Domain] +%C +%C Donated to the public domain. + +%D This module has been adapted to \MKIV\ by Hans Hagen so if things go wrong, +%D he is to blame. The changes concern references and lists but teh rendering +%D itself is unchanged. Future versions might provide variants as we have plans +%D for an upgrade. +%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. +%D +%D A bit ongoing: make more local macros prefixed with bib, i.e. the bib +%D namespace is reserved. + +\writestatus{loading}{ConTeXt Bibliography Support / BibTeX} + +\definefilesynonym[bib][obsolete] + +\registerctxluafile{bibl-tra}{1.001} + +%D The original was developed independantly by Taco Hoekwater while still working for Kluwer +%D Academic publishers (it still used the dutch interface then). Development continued after +%D he left Kluwer, and in Januari 2005, the then already internationalized file was merged +%D with the core distribution by Hans Hagen. The current version is once again by Taco. +%D +%D More documentation and additional resources can be found on the contextgarden: +%D \hyphenatedurl{http://wiki.contextgarden.net//Bibliography}. + +%D \subject{DONE (dd/mm/yyyy)} +%D +%D \startitemize +%D \item add author definition (and associated system variable) (26/05/2005) +%D \item add finalnamesep support for Oxford comma (17/09/2005) +%D \item add \type{\insert...} for: doi, eprint, howpublished (19/09/2005) +%D \item allow a defaulted \type{\setupcite} (19/11/2005) +%D \item renamed citation type 'number' to 'serial' (19/11/2005) +%D \item better definition of \type{\inverted...author} (19/11/2005) +%D \item don't reset [numbercommand] in \type {\setuppublication} by default (20/11/2005) +%D \item don't disable other \type {\setuppublication} keys if alternative is present (20/11/2005) +%D \item drop \type{\sanitizeaccents} (20/11/2005) +%D \item added \type{\nocite} and \type{\cite[none]} (21/11/2005) +%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 M\"unster (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) +%D \item Use \type{\readfile} inside \type{\usepublications} instead of \type{\readsysfile} (12/01/2006) +%D \item Use \type{\currentbibyear} and \type{\currentbibauthor} instead of \type{\YR} and \type{\AU} (05/02/2006) +%D \item Fix compressed version of authoryear style (05/02/2006) +%D \item Rename the clashing data fields \type{\url} and \type{\type} to \type{\biburl} and \type{\bibtype} (05/02/2006) +%D \item Added two french bibl files from Renaud Aubin (06/02/2006) +%D \item Five new bib class and eight extra bib fields, for IEEEtran (07/02/2006) +%D \item French keyword translation, provided by Renaud (08/02/2006) +%D \item fix underscores in undefined keys (22/02/2006) +%D \item Destroy interactivity in labels of the publication list (13/03/2006) +%D \item fix multi-cite list compression (11/4/2006) +%D \item fix \type{\getcitedata} (11/4/2006) +%D \item magic for chapter bibs (18-25/4/2006) +%D \item language setting (25/4/2006) +%D \item use \type{\hyphenatedurl} for \type{\inserturl} (25/4/2006) +%D \item Add \type{\docitation} to \type{\nocite}(26/4/2006) +%D \item patents can have numbers, added to bst files (26/4/2006) +%D \item \type{\docitation} needs a \type{\iftrialtypesetting} (27/4/2006) +%D \item \type{\filllocalpublist}'s loop is bound by definedness, not resolvedness (27/4/2006) +%D \item \type{\setuppublications[monthconversion=]} added (15/5/2006) +%D \item use \type{\undefinedreference} instead of bare question marks (15/5/2006) +%D \item add grouping around \type{\placepublications} commands (16/5/2006) +%D \item fix a bug in \type{\cite{}} (17/5/2006) +%D \item support \type{\cite[authornum]} (18/5/2006) +%D \item make \type{\cite} unexpandable (20/6/2006) +%D \item allow hyperlinks in author\&year combo's +%D (cite list compression has to be off) (20/6/2006) +%D \item fix duplicate labels for per-chapter style (20/6/2006) +%D \item allow \type{\setupcite[interaction=(start|stop)]} +%D \item fix the item number in the publication list with 'numbering=yes' (22/6/2006) +%D \item make the default criterium for \type{\placepublications} be \type{previous} (23/6/2006) +%D \item fix \type{\normalauthor} and \type{\normalshortauthor} spacing (29/6/2006) +%D \item do not typeset empty arguments to \type{\typesetapublication} (29/6/2006) +%D \item add \type{symbol=none} to \type{\setuplist} in unnumbered +%D mode to prevent typesetting of bare numbers (29/6/2006) +%D \item remove two incorrect spaces from bibl-num.tex (1/7/2006) +%D \item reset font styles within \type{\cite}, so that font switches +%D in \type{left} stay in effect (12/7/2006) +%D \item guard added against loading bbl files multiple times (13/7/2006) +%D \item fix \type{\cite[num]} with compression is on. (14/7/2006) +%D \item test \type{\iflocation} before deciding to use the +%D interactive version of cite (18/7/2006) +%D \item support \type{\setupcite[authoretallimit=1]} (18/7/2006) +%D \item support use of \type{\cite} within titles and captions by +%D saveguarding the list item extraction and reference placement +%D code (19/7/2006) +%D \item support \type{\setuppublicationlist[title=\chapter]} (4/8/2006) +%D \item use the expansion of \type{\headtext{pubs}} (4/8/2006) +%D \item hook added for repeated authors in publication list +%D \type{\setuppublicationlist[artauthorcommand=\mythreeargscommand]} +%D (4/8/2006) +%D \item make the bracketed arguments of \type{\artauthor}, \type{\author} +%D and \type{\editor} (bbl commands) optional (4/8/2006) +%D \item the constants \type{sorttype}, \type{compress} and +%D \type{autohang} have moved to the core (8/8/2006) +%D \item bibtex is now registered as a program to be run by texexec (8/8/2006) +%D \item fix a bug in \type{\setupcite[authoretallimit=1]} (9/8/2006) +%D \item fix a bug inside citations that prevented lastpubsep from ever being +%D used due to a volatile \type{\commalistsize} (25/8/2006). +%D \item added the possibility of \type{\placepublications[option=continue]} +%D (6/9/2006) +%D \item Mojca translated Master's Thesis to Masterarbeit (bibl-apa-de.tex) +%D (12/9/2006) +%D \item Added \type{\setuppublicationlist[maybeyear=off]} by request from +%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 W\"achter) (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) +%D \item Patch for \type{\insertbiburl} and \type{\insertdoi} for Tobias Burnus (18/4/2007) +%D \item Added a missing \type{\relax} in \type{\dospecialbibinsert}, +%D that made the space before the {\it et al.} text disappear. (18/4/2007) +%D \item Attempt to fix percent signs in bbl files. As a side-effect, +%D this prohibits comments in \tex{startpublication} blocks! (17/4/2008) +%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 \item Remove a superfluous \type{\unprotect} in t-bib.mkiv (11/05/2009). +%D \item Patch of incollection in bibl-ams.tex from Xan (08/06/2009). +%D \item Patch of unpublished in bibl-ams.tex from Xan (22/07/2009). +%D \item Modified \type{\bibdogetupsometextprefix} so it works for undefined +%D language labels, from Hans (13/08/2009). +%D \item Adapt referencing and list insertion to \MKIV. Update some code +%D to the latest \CONTEXT. Change some names in order to avoid conflicts +%D with existing core names (like \type {\insertpages}). +%D \item All constants, variables, message etc.\ are now in the core. +%D \item Added key: \type {method} (when \type {global}, previous shown entries are +%D not shown again, when \type {local} they are repeated). +%D \stopitemize +%D +%D \subject{WISHLIST} +%D +%D \startitemize +%D \item link back from publication list to citation +%D \item export \type {\citation{}} +%D \item support mlbibtex +%D \item don't load the whole lot, but filter entries instead +%D \item 9 vs 10, 19 vs 20 ... prevent extra runs when only subtle changes in wd of reference +%D \stopitemize + +\unprotect + +\def\biblistname{pubs} % for compatibility + +\definelist + [pubs] + +\setuplist + [pubs] + [\c!state=\v!start, + \c!width=] + +\installstructurelistprocessor{pubs:userdata}% + {\ctxlua{bibtex.hacks.add(structure.lists.uservalue("\currentlist",\currentlistindex,"bibref"),\currentlistindex)}} + +\newcount\bibtexblock \bibtexblock\plusone + +%D \macros{bibdoif,bibdoifnot,bibdoifelse} +%D +%D Here are a few small helpers that are used a lot in all the typesetting commands +%D (\type{\bibinsert...}) we will encounter later. + +\long\def\bibdoifelse#1% + {\@EA\def\@EA\!!stringa\@EA{#1}% + \ifx\!!stringa\empty + \expandafter\secondoftwoarguments + \else + \expandafter\firstoftwoarguments + \fi} + +\long\def\bibdoifnot#1% + {\@EA\def\@EA\!!stringa\@EA{#1}% + \ifx\!!stringa\empty + \expandafter\firstofoneargument + \else + \expandafter\gobbleoneargument + \fi} + +\long\def\bibdoif#1% + {\@EA\def\@EA\!!stringa\@EA{#1}% + \ifx\!!stringa\empty + \expandafter\gobbleoneargument + \else + \expandafter\firstofoneargument + \fi} + +%D Unfortunately, \BIBTEX\ is not the best configurable program +%D around. The names of the commands it parses as well as the \type{.aux} +%D extension to the file name are both hardwired. +%D +%D This means \CONTEXT\ has to write a \LATEX-style auxiliary file, yuk! +%D The good news is that it can be rather short. We'll just ask +%D \BIBTEX\ to output the entire database(s) into the \type{bbl} file. +%D +%D The \type{\bibstyle} command controls how the \type{bbl} file will +%D be sorted. The possibilities are: +%D +%D \startitemize[packed] +%D \item by author (+year, title): cont-au.bst +%D \item by title (+author, year): cont-ti.bst +%D \item by short key as in abbrev.bst: cont-ab.bst +%D \item not sorted at all: cont-no.bst +%D \stopitemize + +\newtoks\everysetupbibtex + +\unexpanded\def\setupbibtex + {\dosingleempty\dosetupbibtex} + +\def\dosetupbibtex[#1]% + {\let\@@pbdatabase\empty + \getparameters[\??pb][#1]% + \the\everysetupbibtex} + +\def\installbibtexsorter#1#2% + {\setvalue{\??pb:\c!sort:#1}{#2}} + +\installbibtexsorter\v!no {no} +\installbibtexsorter\v!author {au} +\installbibtexsorter\v!title {ti} +\installbibtexsorter\v!short {ab} +\installbibtexsorter\empty {no} +\installbibtexsorter\s!default{no} + +\def\thebibtexsorter{\executeifdefined{\??pb:\c!sort:\@@pbsort}\@@pbsort} + +\appendtoks + \ifx\@@pbdatabase\empty\else + \doifmode{*\v!first}{\ctxlua{bibtex.hacks.process { style="\thebibtexsorter", database="\@@pbdatabase" }}}% + \fi +\to \everysetupbibtex + +\setupbibtex + [\c!sorttype=\v!cite, + \c!sort=no] + +%D \macros{iftypesetall,ifbibcitecompress} +%D +%D The module needs some new \type{\if} statements. + +\newtoks\everysetuppublications + +\unexpanded\def\setuppublications + {\dosingleargument\dosetuppublications} + +\def\dosetuppublications[#1]% + {\getparameters[\??pb][\c!alternative=,#1]% + \doifsomething\@@pbalternative + {\readsysfile{bibl-\@@pbalternative.tex} + {\showmessage\m!publications{6}{bibl-\@@pbalternative}} + {\showmessage\m!publications{1}{bibl-\@@pbalternative}}% + \let\@@pbalternative\empty}% + \let\setuppublicationlayout\normalsetuppublicationlayout % overloaded in bibl-num ... vadjust needs to be done with option + \getparameters[\??pb][#1]% as bibl-* can have set things back + \the\everysetuppublications + \ignorespaces} + +%D We can omit already shown references (\v!global) or use fresh +%D lists each time (\v!local). + +\chardef\bibtexoncemode\plusone % 0=disable, 1=local, 2=global + +\appendtoks + \doifelse\@@pbmethod\v!local + {\chardef\bibtexoncemode\plusone}% + {\chardef\bibtexoncemode\plustwo}% +\to \everysetuppublications + +%D Cite lists are compressed, if possible. This is set later on. + +\newif\ifbibcitecompress\bibcitecompresstrue + +% \appendtoks +% \processaction +% [\@@pbnumbering] +% [ \v!yes=>\let\@@pbinumbercommand\firstofoneargument, +% \v!no=>\let\@@pbinumbercommand\gobbleoneargument, +% \v!short=>\def\@@pbinumbercommand##1{\bibgetvars\currentpublicationkey}, +% \v!bib=>\def\@@pbinumbercommand##1{\bibgetvarn\currentpublicationkey}, +% \s!unknown=>\let\@@pbinumbercommand\firstofoneargument]% +% \to \everysetuppublications + +\def\@@pbinumbercommand{\executeifdefined{\??pb:\c!numbercommand:\@@pbnumbering}\firstofoneargument} + +\letvalue{\??pb:\c!numbercommand:\v!yes }\firstofoneargument +\letvalue{\??pb:\c!numbercommand:\v!no }\gobbleoneargument +\setvalue{\??pb:\c!numbercommand:\v!short}#1{\bibgetvars\currentpublicationkey} +\setvalue{\??pb:\c!numbercommand:\v!bib }#1{\bibgetvarn\currentpublicationkey} + +% to be tested +% +% \setvalue{\??pb:\c!numbercommand:\v!short}{\bibgetvars\currentpublicationkey\firstofoneargument} +% \setvalue{\??pb:\c!numbercommand:\v!bib }{\bibgetvarn\currentpublicationkey\firstofoneargument} + +\appendtoks + \processaction + [\@@pbrefcommand] + [\s!default=>\edef\@@citedefault{\@@pbrefcommand}, + \s!unknown=>\edef\@@citedefault{\@@pbrefcommand}]% +\to \everysetuppublications + +\def\bibleftnumber#1{#1\hfill~} + +%D \macros{usepublications} +%D +%D After discussing it with Thomas Schmitz it became clear that using external +%D references makes no sense as one needs to refer to it in special ways and +%D because similar numbers can be confusing. So, for the moment this is not +%D supported in \MKIV. (So no: see reference [3-5,9] in "some other document") + +\def\usepublications[#1]% + {\processcommalist[#1]\dousepublications} + +% \def\dousepublications#1% +% {\doonlyonce{#1.\f!bibextension} +% {\readfile{#1.\f!bibextension} +% {\showmessage\m!publications{4}{#1.\f!bibextension}} +% {\showmessage\m!publications{2}{#1.\f!bibextension}}}} + +\def\dousepublications#1% + {\doonlyonce{#1.\f!bibextension}{\dodousepublications{#1}}} + +\def\dodousepublications#1% + {\let\@@savedpar\par + \let\par\ignorespaces + \ifhmode\kern\zeropoint\fi + \readfile{#1.\f!bibextension} + {\showmessage\m!publications{4}{#1.\f!bibextension}} + {\showmessage\m!publications{2}{#1.\f!bibextension}}% + \ifhmode\removeunwantedspaces\fi + \let\par\@@savedpar} + +%D \macros{setuppublicationlist} +%D +%D This will be the first command in (\BIBTEX-generated) \type{bbl} +%D files. `samplesize' is a sample value (in case of \BIBTEX-generated +%D files, this will be the longest `short' key). `totalnumber' +%D is the total number of entries that will follow in this +%D file. +%D +%D Both values are only needed for the label calculation +%D if `autohang' is `true', so by default the command is +%D not even needed, and therefore I saw no need to give +%D it it's own system variable and it just re-uses \type{pb}. + +\def\publicationlistparameter#1{\csname\??pv:l:#1\endcsname} + +\unexpanded\def\setuppublicationlist + {\dosingleempty\dosetuppublicationlist} + +\def\dosetuppublicationlist[#1]% + {\getparameters[\??pv:l:][#1]% + \setuplist[pubs][\c!samplesize={AA99},\c!alternative=a,\c!interaction=,\c!pagenumber=\v!no,#1,\c!command=]} + +\unexpanded\def\setuppublicationlayout[#1]#2% + {\setvalue{\??pv:l:#1}{#2}} + +\let\normalsetuppublicationlayout\setuppublicationlayout + +\setuppublicationlist[\c!title=,\c!command=\dospecialbibinsert,\c!maybeyear=\v!on] + +%D \macros{bibalternative} +%D +%D A nice little shorthand that will be used so we don't have to +%D key in the weird \type{\@@pv} parameter names all the time. + +\def\bibalternative#1% + {\csname\??pv\@@currentalternative#1\endcsname} + +%D \macros{simplebibdef,bibcommandlist} +%D +%D \type{\simplebibdef} defines \type{bib@#1}, which in turn will +%D use one argument that is stored in \type{@@pb@#1}. +%D +%D \type{\simplebibdef} also defines \type{bibinsert#1}, which can be +%D used in the argument of \type{\setuppublicationlayout} to fetch +%D one of the \type{@@pb@} data entries. \type{bibinsert#1} then has +%D three arguments: \type{#1} are commands to be executed before the +%D data, \type{#2} are commands to be executed after the data, and +%D \type{#3} are commands to be executed if the data is not found. +%D +%D \type{\bibcommandlist} is the list of commands that is affected +%D by this approach. Later on, it will be used to do a series +%D of assignments from \type{#1} to \type{bib@#1}: e.g +%D \type{\title} becomes \type{\bib@title} when used within +%D a publication. + +\newtoks\initializebibdefinitions % we need to prevent clashes + +\def\simplebibdef#1% hh: funny expansion ? + {\@EA\long\@EA\def\csname bib@#1\endcsname##1% + {\setvalue{\??pb @#1}{##1}\ignorespaces}% + \expandafter \appendtoks + \expandafter\let\csname insert#1\expandafter\endcsname\csname bibinsert#1\endcsname + \to \initializebibdefinitions + \@EA\unexpanded\@EA\def\csname bibinsert#1\endcsname##1##2##3% + {\@EA\bibdoifelse\@EA{\csname\??pb @#1\endcsname}{##1\csname\??pb @#1\endcsname##2}{##3}}} + +\def\bibcommandlist + {abstract, annotate, arttitle, assignee, bibnumber, bibtype, biburl, chapter, city, + comment, country, day, dayfiled, doi, edition, eprint, howpublished, isbn, issn, + issue, journal, keyword, keywords, lastchecked, month, monthfiled, names, nationality, + note, notes, organization, pages, pubname, pubyear, revision, series, size, thekey, + title, volume, yearfiled} + +\processcommacommand[\bibcommandlist]\simplebibdef + +% \def\bibinsertdoi#1#2#3% +% {\begingroup +% \bibdoifelse{\@@pb@doi}% +% {\edef\ascii{\detokenize\expandafter{\@@pb@doi}}% probably not ok, to less expansion +% #1\expanded{\bibgotoDOI{\@@pb@thekey}{\ascii}}#2}{#3}% +% \endgroup} +% +% \def\bibinsertbiburl#1#2#3% +% {\begingroup +% \bibdoifelse{\@@pb@biburl}% +% {\edef\ascii{\detokenize\expandafter{\@@pb@biburl}}% probably not ok, to less expansion +% #1\expanded{\bibgotoURL{\@@pb@thekey}{\ascii}}#2}{#3}% +% \endgroup} + +\def\bibinsertdoi#1#2#3% let's see how this fails + {\bibdoifelse{\@@pb@doi}{#1\expanded{\bibgotoDOI{\@@pb@thekey}{\@@pb@doi}}#2}{#3}} + +\def\bibinsertbiburl#1#2#3% let's see how this fails + {\bibdoifelse{\@@pb@biburl}{#1\expanded{\bibgotoURL{\@@pb@thekey}{\@@pb@biburl}}#2}{#3}} + +\def\bibinsertmonth#1#2#3% + {\bibdoifelse\@@pb@month + {#1\doifnumberelse\@@pb@month + {\doifconversiondefinedelse\@@pbmonthconversion + {\convertnumber\@@pbmonthconversion\@@pb@month}{\@@pb@month}}% + {\@@pb@month}#2}% + {#3}} + +\appendtoks + \let\inserturl \bibinsertbiburl % for backward compat. + \let\inserttype\bibinsertbibtype % for backward compat. +\to\initializebibdefinitions + +\def\newbibfield[#1]% + {\simplebibdef{#1}% + \edef\bibcommandlist{\bibcommandlist,#1}} + +%D \macros{complexbibdef,specialbibinsert} +%D +%D The commands \type{\artauthor}, \type{\author} and +%D \type{\editor} are more complex than the other commands. +%D Their argument lists have this form: +%D +%D \type{\author[junior]{firstnames}[inits]{von}{surname}} +%D +%D (bracketed stuff is optional) +%D +%D And not only that, but there also might be more than one of each of +%D these commands. This is why a special command is needed to insert +%D them, as well as one extra counter for each command. + +% todo: instead of \getvalue{bla@num} in specs we should do +% \bibentrynum{bla} so that we can create a better namespace + +%D All of these \type{\@EA}'s and \type{\csnames} make this code +%D look far more complex than it really is. For example, the argument +%D \type{author} defines the macro \type{\bib@author} to do two +%D things: increment the counter \type{\author@num} (let's say to 2) +%D and next store it's arguments in the macro \type{\@@pb@author2}. +%D And it defines \type{\bibinsertauthors} to expand into +%D \starttyping +%D \specialbibinsert{author}{\author@num}{}{}{} +%D \stoptyping + +% \def\docomplexbibdef#1% +% {\def\currentype{#1}% +% \dosingleempty\dodocomplexbibdef} + +% \def\dodocomplexbibdef[#1]#2% +% {\def\firstarg{#1}\def\secondarg{#2}% +% \dosingleempty\dododocomplexbibdef} + +% \def\dododocomplexbibdef[#1]#2#3% +% {\@EA\increment\csname\currentype @num\endcsname +% \setevalue{\??pb @\currentype\csname \currentype @num\endcsname}% +% {{\secondarg}{#2}{#3}{#1}{\firstarg}}\ignorespaces} + +\def\docomplexbibdef#1% + {\dodoubleempty\dodocomplexbibdef[#1]} + +\def\dodocomplexbibdef[#1][#2]#3% + {\doquadrupleempty\dododocomplexbibdef[#1][#2][#3]} + +\def\dododocomplexbibdef[#1][#2][#3][#4]#5#6% + {\@EA\increment\csname#1@num\endcsname % todo: bib in name + \setevalue{\??pb @#1\csname#1@num\endcsname}{{#3}{#5}{#6}{#4}{#2}}\ignorespaces} + +\def\complexbibdef#1% + {\@EA\newcounter\csname #1@num\endcsname + \@EA\def\csname bib@#1\endcsname{\docomplexbibdef{#1}}% + \expandafter \appendtoks + \expandafter\let\csname insert#1s\expandafter\endcsname\csname bibinsert#1s\endcsname + \to \initializebibdefinitions + \@EA\def\csname bibinsert#1s\endcsname##1##2##3{\specialbibinsert{#1}{\csname #1@num\endcsname}{##1}{\unskip ##2}{##3}}} + +\processcommalist[author,artauthor,editor]\complexbibdef + +%D Another level of indirection is needed to control the +%D typesetting of all of these arguments. + +\newcount\etallimitcounter +\newcount\etaldisplaycounter +\newcount\todocounter + +\def\specialbibinsert#1#2#3#4#5% + {\bgroup + \ifnum#2>\zerocount + \etallimitcounter =0\bibalternative{#1etallimit}\relax + \etaldisplaycounter=0\bibalternative{#1etaldisplay}\relax + \ifnum #2>\etallimitcounter + \todocounter\etaldisplaycounter + % just in case ... + \ifnum\todocounter>\etallimitcounter + \todocounter\etallimitcounter + \fi + \else + \todocounter#2\relax + \fi + \ifnum\todocounter>\zerocount + % find the current author list + \let\templist\empty + \dorecurse{#2} + {\scratchtoks\@EA\@EA\@EA{\csname\??pb @#1\recurselevel\endcsname}% + \edef\templist{\ifx\templist\empty\else\templist,\fi\the\scratchtoks}}% + #3\publicationlistparameter\c!command{#1}{\todocounter}{\templist}#4\relax + \else + #5% + \fi + \else + #5% + \fi + \egroup} + +%D This macro does the hard work of inserting a list of people in the +%D output, with proper regard of all the inbetween strings that can +%D arise depending on length of the list of people. + +%D \#1 = type +%D \#2 = number of items to be typeset +%D \#3 = commacommand containing authors + +% \def\dospecialbibinsert#1#2#3% +% {\getcommacommandsize[#3]% +% \scratchcounter\zerocount +% \def\processauthoritem##1% +% {\advance\scratchcounter\plusone +% \ifnum\numexpr\scratchcounter-\plusone\relax<#2\relax +% \publicationlistparameter{#1}##1% +% \ifnum\scratchcounter=#2\relax +% \ifnum\etallimitcounter<\commalistsize\relax +% \bibalternative{#1etaltext}% +% \fi +% \else\ifnum\numexpr\scratchcounter+\plusone\relax=#2\relax +% \ifnum\commalistsize>\plustwo +% \bibalternative\c!finalnamesep +% \else +% \bibalternative\c!lastnamesep +% \fi +% \else +% \bibalternative\c!namesep +% \fi\fi +% \fi}% +% \processcommacommand[#3]\processauthoritem} + +\def\doprocessauthoritem#1#2#3% + {\advance\scratchcounter\plusone + \ifnum\numexpr\scratchcounter-\plusone\relax<#2\relax + \publicationlistparameter{#1}#3% + \ifnum\scratchcounter=#2\relax + \ifnum\etallimitcounter<\commalistsize\relax + \bibalternative{#1etaltext}% + \fi + \else\ifnum\numexpr\scratchcounter+\plusone\relax=#2\relax + \ifnum\commalistsize>\plustwo + \bibalternative\c!finalnamesep + \else + \bibalternative\c!lastnamesep + \fi + \else + \bibalternative\c!namesep + \fi\fi + \fi} + +\def\dospecialbibinsert#1#2#3% + {\getcommacommandsize[#3]% + \scratchcounter\zerocount + \processcommacommand[#3]{\doprocessauthoritem{#1}{#2}}} + +%D \macros{invertedauthor,normalauthor,invertedshortauthor,normalshortauthor} +%D +%D Just some commands that can be used in \type{\setuppublicationparameters} +%D If you want to write an extension to the styles, you might +%D as well define some of these commands yourself. +%D +%D The argument list has been reordered here, and the meanings +%D are: +%D +%D \startlines +%D \type{#1} firstnames +%D \type{#2} von +%D \type{#3} surname +%D \type{#4} inits +%D \type{#5} junior +%D \stoplines + +\def\normalauthor#1#2#3#4#5% + {\bibdoif{#1}{#1\bibalternative\c!firstnamesep}% + \bibdoif{#2}{#2\bibalternative\c!vonsep}% + #3% + \bibdoif{#5}{\bibalternative\c!surnamesep#5\unskip}} + +\def\normalshortauthor#1#2#3#4#5% + {\bibdoif{#4}{#4\bibalternative\c!firstnamesep}% + \bibdoif{#2}{#2\bibalternative\c!vonsep}% + #3% + \bibdoif{#5}{\bibalternative\c!surnamesep#5\unskip}} + +\def\invertedauthor#1#2#3#4#5% + {\bibdoif{#2}{#2\bibalternative\c!vonsep}% + #3% + \bibdoif{#5}{\bibalternative\c!juniorsep#5}% + \bibdoif{#1}{\bibalternative\c!surnamesep#1\unskip}} + +\def\invertedshortauthor#1#2#3#4#5% + {\bibdoif{#2}{#2\bibalternative\c!vonsep}% + #3% + \bibdoif{#5}{\bibalternative\c!juniorsep#5}% + \bibdoif{#4}{\bibalternative\c!surnamesep#4\unskip}} + +%D \macros{clearbibitem,clearbibitemtwo,bibitemdefs} +%D +%D These are used in \type{\typesetapublication} to do +%D initializations and cleanups. + +\def\clearbibitem#1{\setvalue{\??pb @#1}{}}% + +% \def\clearbibitemtwo#1% +% {\letvalue{#1@num}\!!zerocount +% \doloop +% {\doifdefinedelse{\??pb @#1\recurselevel} +% {\letvalue{\??pb @#1\recurselevel}\empty} % why not undefined? +% {\exitloop}}} + +% \def\clearbibitemtwo#1% +% {\letvalue{#1@num}\!!zerocount +% \doloop +% {\ifcsname\??pb @#1\recurselevel\endcsname +% \expandafter\let\csname\??pb @#1\recurselevel\undefined +% \else +% \exitloop +% \fi}} + +\def\clearbibitemtwo#1% is this reset really needed? after all we reset the counter and we are local + {%\dofastrecurse\plusone{\csname#1@num\endcsname}\plusone{\expandafter\let\csname\??pb @#1\recurselevel\undefined}% + \letvalue{#1@num}\!!zerocount} + +\def\bibitemdefs#1% + {\@EA\let\csname#1\expandafter\endcsname\csname bib@#1\endcsname} + +\def\presetbibvariables % make a fast resetter (toks) + {\processcommacommand[\bibcommandlist,crossref]\clearbibitem + \processcommalist [artauthor,author,editor]\clearbibitemtwo + \processcommacommand[\bibcommandlist]\bibitemdefs + \processcommalist [artauthor,author,editor,crossref]\bibitemdefs} + +%D \macros{startpublication} +%D +%D We are coming to the end of this module, to the macros that +%D do typesetting and read the \type{bbl} file. + +\newcount\bibtexcounter + +%D Just a \type{\dosingleempty} is the most friendly +%D of doing this: there need not even be an argument +%D to \type{\startpublication}. Of course, then there +%D is no key either, and it had better be an +%D article (otherwise the layout will be all screwed up). +%D +%D Only specifying the key in the argument is also +%D legal. In storing this stuff into macros, some trickery with +%D token registers is needed to fix the expansion problems. Even so, +%D this appears to not always be 100\% safe, so people are +%D urgently advised to use \ETEX\ instead of traditional \TEX. +%D +%D In \ETEX, all expansion problems are conveniently solved by +%D the primitive \type{\protected}. To put that another way: +%D +%D It's not a bug in this module if it does not appear in \ETEX! +%D +%D Now prohibits comments, so % can be used for urls + +\unexpanded\def\startpublication + {\begingroup + \catcode`\%=\othercatcode + \dosingleempty\dostartpublication} + +\let\stoppublication\relax + +% this is rather memory hungry; some day i will rewrite this so that +% we use the database instead + +%D \macros{doifbibreferencefoundelse} +%D +%D Some macros to fetch the information provided by +%D \type{\startpublication}. + +% we can consider a faster variant in the bbl file; we can also consider +% storing the keys in lua (and then do more in lua) and use calls to +% fetch the variables + +% hm, we can store at the lua end ... + +\long\def\dostartpublication[#1]#2\stoppublication + {\doifassignmentelse{#1}% + {\getparameters[\??pb][k=\s!unknown,t=article,n=,s=,a=,y=,o=,u=,#1]}% + {\getparameters[\??pb][k=#1,t=article,n=,s=,a=,y=,o=,u=]}% + \ctxlua{bibtex.hacks.register("\@@pbk")}% + \setxvalue{pbd:\@@pbk}##1{\noexpand\ifcase##1\noexpand\or + \@@pbk\noexpand\or + \@@pba\noexpand\or + \@@pby\noexpand\or + \@@pbs\noexpand\or + \@@pbn\noexpand\or + \@@pbt\noexpand\or + \@@pbo\noexpand\or + \@@pbu\noexpand\or + \normalunexpanded{#2}\noexpand\fi}% + \endgroup + \ignorespaces} + +\def\bibgetvark#1{\csname pbd:#1\endcsname\plusone } +\def\bibgetvara#1{\csname pbd:#1\endcsname\plustwo } +\def\bibgetvary#1{\csname pbd:#1\endcsname\plusthree} +\def\bibgetvars#1{\csname pbd:#1\endcsname\plusfour } +\def\bibgetvarn#1{\csname pbd:#1\endcsname\plusfive } +\def\bibgetvart#1{\csname pbd:#1\endcsname\plussix } +\def\bibgetvaro#1{\csname pbd:#1\endcsname\plusseven} +\def\bibgetvaru#1{\csname pbd:#1\endcsname\pluseight} +\def\bibgetvard#1{\csname pbd:#1\endcsname\plusnine } + +\def\doifbibreferencefoundelse#1% + {\preloadbiblist + \doifdefinedelse{pbd:#1} + \firstoftwoarguments + {\showmessage\m!publications{5}{#1 is unknown}\secondoftwoarguments}} + +%D \macros{bib@crossref} +%D +%D \type{\crossref} is used in database files to point to another +%D entry. Because of this special situation, it has to be defined +%D separately. Since this command will not be seen until at +%D \type{\placepublications}, it may force extra runs. The same is +%D true for \type{\cite} commands inside of publications. + +% used in bib self + +\def\bib@crossref#1% called via \csname \endcsname + {\setvalue{\??pb @crossref}{#1}\ignorespaces} + +\def\bibinsertcrossref#1#2#3% + {\bibdoifelse\@@pb@crossref{#1\cite[\@@pb@crossref]#2}{#3}} + +\appendtoks\let\insertcrossref\bibinsertcrossref\to\initializebibdefinitions + +%D The next macro is needed because the number command of the +%D publist sometimes needs to fetch something from the current +%D item (like the 'short' key). For this, the ID of the current +%D item is passed in the implict parameter \type{\currentpublicationkey} + +\def\doprocessbibtexentry#1{\typesetapublication{#1}} + +\def\typesetpubslist + {\dobeginoflist + % \the\initializebibdefinitions % COMMENTED + \edef\currentlist{pubs}% + \doif{\listparameter\c!criterium}\v!cite{\setuplist[pubs][\c!criterium=\v!here]}% + \ctxlua{bibtex.hacks.reset(\number\bibtexoncemode)}% + \placestructurelist{pubs}{\listparameter\c!criterium}{\listparameter\c!number}% + \ctxlua{bibtex.hacks.flush("\@@pbsorttype")}% + \doendoflist} + +\newif\ifinpublist + +\def\initializepubslist + {\def\currentlist{pubs}% + \edef\@@pbnumbering{\@@pbnumbering}% + \doifelse\@@pbautohang\v!yes + {\ifx\@@pbnumbering\v!short + \setbox\scratchbox\hbox{\@@pbnumbercommand{\listparameter\c!samplesize}}% + \else + \setbox\scratchbox\hbox{\@@pbnumbercommand{\ctxlua{tex.write(structure.lists.size())}}}% + \fi + \edef\publistnumberbox{\hbox to \the\wd\scratchbox}% + \expanded{\setuplist[pubs][\c!width=\the\wd\scratchbox,\c!distance=\zeropoint]}% + \ifx\@@pbnumbering\v!short + \def\@@pblimitednumber##1{\publistnumberbox{\@@pbnumbercommand{\bibgetvars\currentpublicationkey}}}% + \else\ifx\@@pbnumbering\v!bib + \def\@@pblimitednumber##1{\publistnumberbox{\@@pbnumbercommand{\bibgetvarn\currentpublicationkey}}}% + \else + \def\@@pblimitednumber##1{\publistnumberbox{\@@pbnumbercommand{##1}}}% + \fi\fi} + {\doifelsenothing{\listparameter\c!width} + {\let \publistnumberbox \hbox} + {\edef\publistnumberbox{\hbox to \listparameter\c!width}}% + \ifx\@@pbnumbering\v!short + \def\@@pblimitednumber##1{\publistnumberbox{\@@pbnumbercommand{\bibgetvars\currentpublicationkey}}}% + \else\ifx\@@pbnumbering\v!bib + \def\@@pblimitednumber##1{\publistnumberbox{\@@pbnumbercommand{\bibgetvarn\currentpublicationkey}}}% + \else + \def\@@pblimitednumber##1{\publistnumberbox{\@@pbnumbercommand{##1}}}% + \fi\fi}% + \ifx\@@pbnumbering\v!no + \setuplist[pubs][\c!numbercommand=,\c!symbol=\v!none,\c!textcommand=\outdented]% + \else + \setuplist[pubs][\c!numbercommand=\@@pblimitednumber]% + \fi + \doifelse{\publicationlistparameter\c!maybeyear}{\v!off}{\def\maybeyear##1{}}{\def\maybeyear##1{##1}}% + \forgetall} + +\def\outdented#1% move to supp-box ? + {\hskip-\hangindent#1\relax} + +%D The full list of publications + +\def\completepublications + {\dosingleempty\docompletepublications} + +\def\docompletepublications[#1]% + {\begingroup + \setuplist[pubs][\c!criterium=\v!previous,#1] + \doifelsenothing{\publicationlistparameter\c!title} + {\systemsuppliedchapter[pubs]{\headtext{pubs}}} + {\normalexpanded{\systemsuppliedchapter[pubs]{\publicationlistparameter\c!title}}}% + \dodoplacepublications} + +%D And the portion with the entries only. + +\def\bibrefprefix{\number\bibtexblock:} + +\unexpanded\def\placepublications + {\dosingleempty\doplacepublications} + +\def\doplacepublications[#1]% + {\begingroup + \setuplist[pubs][\c!criterium=\v!previous,#1]% + \dodoplacepublications} + +\def\dodoplacepublications + {\determinelistcharacteristics[pubs]% + \initializepubslist + \doifnot{\namedlistparameter{pubs}\c!option}\v!continue + {\global\bibtexcounter\zerocount}% + \inpublisttrue + \typesetpubslist + \inpublistfalse + \endgroup + \global\advance\bibtexblock\plusone} + +%D \subsubject{What's in a publication} + +\unexpanded\def\typesetapublication#1% + {\doifsomething{#1} + {\doifelse{\namedlistparameter{pubs}\c!criterium}\v!all + {\doplacepublicationindeed{#1}}% + {\ctxlua{bibtex.hacks.doifalreadyplaced("#1")} + {} + {\doplacepublicationindeed{#1}}}% + }} + +% for the moment we don't access the data directly but we will do that +% later when we get away from storing the data and only deal with +% references + +% we'll define proper handlers later + +\def\doplacepublicationindeed#1% + {\doifbibreferencefoundelse{#1} + {\global\advance\bibtexcounter\plusone + \def\currentpublicationkey{#1}% + \ctxlua{bibtex.hacks.registerplaced("#1")}% + \dodolistelement + {pubs}% + {}% + {\number\bibtexcounter}% + {\expanded{\reference[\bibrefprefix#1]{\number\bibtexcounter}}% + \strut\dotypesetapublication{#1}\strut}% + {}% + {}} + {}} % invalid + +\def\dotypesetapublication#1% + {\bgroup + \the\initializebibdefinitions % NEW + \def\@@currentalternative{:l:}% + \presetbibvariables + \let\biblanguage\empty + \ignorespaces + \bibgetvard{#1}% + \removeunwantedspaces + \ignorespaces + \bibalternative{\bibgetvart{#1}}% + \removeunwantedspaces + \egroup} + +%D An few afterthoughts: + +\let\maybeyear\gobbleoneargument +\let\noopsort \gobbleoneargument + +%D This is the result of bibtex's `language' field. + +\def\setbiblanguage#1#2{\setvalue{\??pb\s!language#1}{#2}} + +\def\lang#1% + {\edef\biblanguage{#1}% + \ifcsname\??pb\s!language#1\endcsname + \language[\getvalue{\??pb\s!language#1}]% + \fi + \ignorespaces} + +%D \subject{Citations} + +%D \macros{cite,bibref} +%D +%D The indirection with \type{\dobibref} allows \LATEX\ style +%D \type{\cite} commands with a braced argument (these might appear +%D in included data from the \type{.bib} file). + +% \unexpanded\def\cite +% {\doifnextoptionalelse\dodocite\dobibref} +% \def\dobibref#1% +% {\docite[#1][]} +% \def\dodocite[#1]% +% {\startstrictinspectnextcharacter +% \dodoubleempty\dododocite[#1]} +% \def\dododocite % [#1][#2] +% {\stopstrictinspectnextcharacter +% \docite} + +\unexpanded\def\cite + {\strictdoifnextoptionalelse\dodocite\dobibref} + +\def\dobibref#1% + {\docite[#1][]} + +\def\dodocite[#1]% + {\strictdoifnextoptionalelse{\docite[#1]}{\docite[#1][]}} + +\def\docite[#1][#2]% + {\begingroup + \doifelsenothing{#2}\secondargumentfalse\secondargumenttrue + \ifsecondargument + \dowhatevercite{#1}{#2}% + \else + \donumberedcite{#1}% + \fi + \endgroup} + +\def\dowhatevercite#1#2% + {\processcommalist[#2]\docitation + \setupinteraction[\c!style=]% + \doifassignmentelse + {#1}% + {\getparameters[LO][\c!alternative=,\c!extras=,#1]% + \edef\@@currentalternative{\LOalternative}% + \ifx\@@currentalternative\empty + \edef\@@currentalternative{\@@citedefault}% + \fi + \ifx\LOextras\empty + \setupcite[\@@currentalternative][#1]% + \else + \expandafter\ifx\csname LOright\endcsname \relax + \edef\LOextras{{\LOextras\bibalternative\c!right}}% + \else + \edef\LOextras{{\LOextras\LOright}}% + \fi + \expanded{\setupcite[\@@currentalternative][#1,\c!right=\LOextras]}% + \fi}% + {\def\@@currentalternative{#1}}% + \doifelsevalue{@@pv\@@currentalternative\c!compress}\v!no\bibcitecompressfalse\bibcitecompresstrue + \getvalue{bib\@@currentalternative ref}[#2]} + +\def\donumberedcite#1% + {\processcommalist[#1]\docitation + \setupinteraction[\c!style=]% + \edef\@@currentalternative{\@@citedefault}% + \doifelsevalue{@@pv\@@currentalternative\c!compress}\v!no\bibcitecompressfalse\bibcitecompresstrue + \getvalue{bib\@@citedefault ref}[#1]} + +%D \macros{nocite} + +\def\nocite[#1]% + {\processcommalist[#1]\docitation} + +%D \macros{setupcite} + +\unexpanded\def\setupcite{\dodoubleempty\dosetupcite} + +\def\dosetupcite[#1][#2]% + {\ifsecondargument + \def\dodosetupcite##1{\getparameters[\??pv##1][#2]}% + \processcommalist[#1]\dodosetupcite + \else % default case + \getparameters[\??pv\@@citedefault][#1]% + \fi} + +%D Low-level stuff + +\def\getcitedata#1[#2]#3[#4]#5to#6% + {\bgroup + \dofetchapublication{#4}% + \doifdefinedelse{\??pb @bib#2}% + {\xdef#6{\getvalue{\??pb @bib#2}}}% + {\xdef#6{\getvalue{\??pb @#2}}}% + \egroup} + +\def\dofetchapublication#1% + {\def\currentpublicationkey{#1}% + \presetbibvariables + \ignorespaces\bibgetvard{#1}} + +\def\docitation#1% + {\iftrialtypesetting \else + \expanded{\writedatatolist[pubs][bibref=#1]}% + \fi} + +\let\addthisref\gobbleoneargument % keep this for compatibility + +%D \macros{ixbibauthoryear,thebibauthors,thebibyears} +%D +%D If compression of \type{\cite}'s argument expansion is on, +%D the macros that deal with authors and years call this internal +%D command to do the actual typesetting. +%D +%D Two entries with same author but with different years may +%D be condensed into ``Author (year1,year2)''. This is about the +%D only optimization that makes sense for the (author,year) +%D style of citations (years within one author have to be unique +%D anyway so no need to test for that, and ``Author1, Author2 (year)'' +%D creates more confusion than it does good). +%D +%D In the code below, +%D the macro \type{\thebibauthors} holds the names of the alternative +%D author info fields for the current list. This is a commalist, +%D and \type{\thebibyears} holds the (collection of) year(s) that go with +%D this author (possibly as a nested commalist). +%D +%D There had better be an author for all cases, but there +%D does not have to be year info always. \type{\thebibyears} is +%D pre-initialized because this makes the insertion macros simpler. +%D +%D In `normal' \TeX, of course there are expansion problems again. + +\def\ixbibauthoryear#1#2#3#4% + {\bgroup + \gdef\ixlastcommand {#4}% + \gdef\ixsecondcommand{#3}% + \gdef\ixfirstcommand {#2}% + \glet\thebibauthors \empty + \glet\thebibyears \empty + \getcommalistsize[#1]% + \ifbibcitecompress + \dorecurse\commalistsize{\xdef\thebibyears{\thebibyears,}}% + \processcommalist[#1]\docompressbibauthoryear + \else + \processcommalist[#1]\donormalbibauthoryear + \fi + \egroup + \dobibauthoryear} + +%D \macros{dodobibauthoryear} +%D +%D This macro only has to make sure that the lists +%D \type{\thebibauthors} and \type{\thebibyears} are printed. + +\def\dobibauthoryear + {\scratchcounter\zerocount + \getcommacommandsize[\thebibauthors]% + \edef\authorcount{\commalistsize}% + \@EA\processcommalist\@EA[\thebibauthors]\dodobibauthoryear} + +\def\dodobibauthoryear#1% + {\advance\scratchcounter\plusone + \edef\wantednumber{\the\scratchcounter}% + \getfromcommacommand[\thebibyears][\wantednumber]% + \@EA\def\@EA\currentbibyear\@EA{\commalistelement}% + \setcurrentbibauthor{#1}% + \ifnum\scratchcounter=\plusone + \ixfirstcommand + \else\ifnum \scratchcounter=\authorcount\relax + \ixlastcommand + \else + \ixsecondcommand + \fi\fi} + +\def\setcurrentbibauthor#1% + {\getcommacommandsize[#1]% + \ifcase\commalistsize + % anonymous? + \let\currentbibauthor\empty + \or + \def\currentbibauthor{#1}% + \or + \expanded{\docurrentbibauthor#1}% + \else + \handlemultiplebibauthors{\commalistsize}{#1}% + \fi} + +\newcount\citescratchcounter + +\def\handlemultiplebibauthors#1#2% + {\citescratchcounter\zerocount + \let\currentbibauthor\empty + \def\bibprocessauthoritem##1% + {\advance\citescratchcounter\plusone + \ifnum \citescratchcounter=#1\relax + \edef\currentbibauthor{\currentbibauthor##1}% + \else\ifnum\numexpr\citescratchcounter+\plusone\relax=#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. + +\def\docurrentbibauthor#1,#2% + {\doifemptyelse{#2} + {\def\currentbibauthor{#1\bibalternative{otherstext}}} + {\@EA\ifx\csname\??pv\@@currentalternative authoretallimit\endcsname\relax + \edef\currentbibauthor{#1\bibalternative{andtext}#2}% + \else + \edef\currentbibauthor{#1% + \ifcase0\bibalternative{authoretallimit}\relax\or + \bibalternative{otherstext}\else\bibalternative{andtext}#2\fi}% + \fi}} + +%D This is not the one Hans made for me, because I need a global +%D edef, and the \type{\robustdoifinsetelse} doesn't listen to +%D \type{\doglobal } + +\def\robustaddtocommalist#1#2% {item} \cs + {\robustdoifinsetelse{#1}#2\resetglobal + {\dodoglobal\xdef#2{\ifx#2\empty\else#2,\fi#1}}} + +%D \macros{donormalbibauthoryear} +%D +%D Now we get to the macros that fill the two lists. +%D The `simple' one really is quite simple. + +\def\donormalbibauthoryear#1% + {\def\myauthor{Xxxxxxxxxx}% + \def\myyear{0000}% + \doifbibreferencefoundelse{#1} + {\def\myauthor{{\bibgetvara{#1}}}% + \def\myyear {\bibgetvary{#1}}}% + {}% + \@EA\doglobal\@EA\appendtocommalist\@EA{\myauthor}\thebibauthors + \@EA\doglobal\@EA\appendtocommalist\@EA{\myyear }\thebibyears} + +%D \macros{docompressbibauthoryear} +%D +%D So much for the easy parts. Nothing at all will be done if +%D the reference is not found or the reference does not contain +%D author data. No questions marks o.s.s. (to be fixed later) + +\def\docompressbibauthoryear#1% + {\def\myauthor{Xxxxxxxxxx}% + \def\myyear {0000}% + \doifbibreferencefoundelse{#1} + {\xdef\myauthor{\bibgetvara{#1}}% + \xdef\myyear {\bibgetvary{#1}}} + {}% + \ifx\myauthor\empty\else + \checkifmyauthoralreadyexists + \findmatchingyear + \fi} + +%D two temporary counters. One of these two can possibly be replaced +%D by \type{\scratchcounter}. + +\newcount\bibitemcounter +\newcount\bibitemwanted + +%D The first portion is simple enough: if this is the very first author +%D it is quite straightforward to add it. \type{\bibitemcounter} and +%D \type{\bibitemwanted} are needed later to insert the year +%D information in the correct item of \type{\thebibyears} + +\def\checkifmyauthoralreadyexists + {\doifemptyelsevalue{thebibauthors} + {\global\bibitemwanted \plusone + \global\bibitemcounter\plusone + \xdef\thebibauthors{{\myauthor}}} + {% the next weirdness is because according to \getcommalistsize, + % the length of \type{[{{},{}}]} is 2. + \@EA\getcommalistsize\@EA[\thebibauthors,]% + \global\bibitemcounter\numexpr\commalistsize+\minusone\relax + \global\bibitemwanted \zerocount + \processcommacommand[\thebibauthors]\docomparemyauthor}} + +%D The outer \type{\ifnum} accomplishes the addition of +%D a new author to \type{\thebibauthors}. The messing about with +%D the two counters is again to make sure that \type{\thebibyears} +%D will be updated correctly.If the author {\it was} found, +%D the counters will stay at their present values and everything +%D will be setup properly to insert the year info. + +\def\docomparemyauthor#1% + {\global\advance\bibitemwanted \plusone + \def\mytempc{#1}% + \ifx\mytempc\myauthor + \quitcommalist + \else\ifnum\bibitemwanted=\bibitemcounter\relax + \global\advance\bibitemwanted \plusone + \global\bibitemcounter\bibitemwanted\relax + \@EA\doglobal\@EA\robustaddtocommalist\@EA{{\myauthor}}\thebibauthors + \fi\fi} + +%D This macro should be clear now. + +\def\findmatchingyear + {\edef\wantednumber{\the\bibitemwanted}% + \getfromcommacommand[\thebibyears][\wantednumber]% + \ifx\commalistelement\empty + \edef\myyear{{\myyear}}% + \else + \edef\myyear{{\commalistelement,\myyear}}% + \fi + \edef\newcommalistelement{\myyear}% + \doglobal\replaceincommalist \thebibyears \wantednumber} + +%D \macros{gotobiblink,inbiblink,atbiblink} +%D +%D The final task is looping over that list until a match is found. + +\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}{\expanded{\goto{\currentreferencetext}}[\bibrefprefix#1]}{\unknownreference{#1}}} + +%D \macros{bibauthoryearref,bibauthoryearsref,bibauthorref,bibyearref} +%D +%D Now that all the hard work has been done, these are simple. +%D \type{\ixbibauthoryearref} stores the data in the macros +%D \type{\currentbibauthor} and \type{\currentbibyear}. + +\def\ifbibinteractionelse + {\iflocation + \edef\test{\bibalternative\c!interaction}% + \ifx\test\v!stop + \@EA\@EA\@EA\secondoftwoarguments + \else + \@EA\@EA\@EA\firstoftwoarguments + \fi + \else + \@EA\secondoftwoarguments + \fi} + +\def\ifbibinteractionelse + {\iflocation + \doifelse{\bibalternative\c!interaction}\v!stop + {\@EA\secondoftwoarguments} + {\@EA\firstoftwoarguments}% + \else + \@EA\secondoftwoarguments + \fi} + +\def\bibmaybeinteractive#1#2% + {\ifbibcitecompress + #2% + \else + \ifbibinteractionelse{\gotobiblink{#2}[#1]}{#2}% + \fi} + +\def\bibauthoryearref[#1]% + {\ixbibauthoryear{#1}% + {\bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween + \bibalternative\v!left{\currentbibyear}\bibalternative\v!right}} + {\bibalternative\c!pubsep + \bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween + \bibalternative\v!left {\currentbibyear}\bibalternative\v!right}} + {\bibalternative\c!lastpubsep + \bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween + \bibalternative\v!left {\currentbibyear}\bibalternative\v!right}}} + +\def\bibauthoryearsref[#1]% + {\bibalternative\v!left + \ixbibauthoryear{#1} + {\bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween{\currentbibyear}}} + {\bibalternative\c!pubsep + \bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween{\currentbibyear}}} + {\bibalternative\c!lastpubsep + \bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween{\currentbibyear}}}% + \bibalternative\v!right} + +\def\bibauthorref[#1]% + {\bibalternative\v!left + \ixbibauthoryear{#1}% + {\bibmaybeinteractive{#1}{{\currentbibauthor}}} + {\bibalternative\c!pubsep \bibmaybeinteractive{#1}{{\currentbibauthor}}} + {\bibalternative\c!lastpubsep\bibmaybeinteractive{#1}{{\currentbibauthor}}}% + \bibalternative\v!right} + +\def\bibyearref[#1]% + {\bibalternative\v!left + \ixbibauthoryear{#1}% + {\bibmaybeinteractive{#1}{{\currentbibyear}}} + {\bibalternative\c!pubsep \bibmaybeinteractive{#1}{{\currentbibyear}}} + {\bibalternative\c!lastpubsep\bibmaybeinteractive{#1}{{\currentbibyear}}}% + \bibalternative\v!right} + +%D \macros{bibshortref,bibkeyref,bibpageref,bibtyperef,bibserialref} +%D +%D There is hardly any point in trying to compress these. The only +%D thing that needs to be done is making sure that +%D the separations are inserted correctly. And that is +%D what \type{\bibinsertrefsep} does. + +\newconditional\firstbibrefsep + +\def\bibresetrefsep + {\settrue\firstbibrefsep} + +\def\bibinsertrefsep + {\ifconditional\firstbibrefsep + \setfalse\firstbibrefsep + \else + \bibalternative\c!pubsep + \fi} + +\def\bibshortref[#1]% + {\bibalternative\v!left + \bibresetrefsep\processcommalist[#1]\dobibshortref + \bibalternative\v!right} + +\def\dobibshortref#1% + {\bibinsertrefsep + \doifbibreferencefoundelse{#1} + {\gotobiblink{\bibgetvars{#1}}[#1]} + {\unknownreference{#1}}} + +\def\bibserialref[#1]% + {\bibalternative\v!left + \bibresetrefsep\processcommalist[#1]\dobibserialref + \bibalternative\v!right} + +\def\dobibserialref#1% + {\bibinsertrefsep + \doifbibreferencefoundelse{#1} + {\gotobiblink{\bibgetvarn{#1}}[#1]} + {\unknownreference{#1}}} + +\def\bibkeyref[#1]% + {\bibalternative\v!left + \bibresetrefsep\processcommalist[#1]\dobibkeyref + \bibalternative\v!right} + +\def\dobibkeyref#1% + {\bibinsertrefsep + \gotobiblink{#1}[#1]} + +\def\bibgotoDOI#1#2% + {\ifbibinteractionelse + {\useURL[bibfooDoi#1][#2]% + \useURL[bibfoo#1][http://dx.doi.org/#2]% + \goto{\url[bibfooDoi#1]}[url(bibfoo#1)]} + {\hyphenatedurl{#2}}} + +\def\bibdoiref[#1]% + {\bibalternative\v!left + \bibresetrefsep\processcommalist[#1]\dobibdoiref + \bibalternative\v!right} + +\def\dobibdoiref#1% + {\bibinsertrefsep + \doifbibreferencefoundelse{#1} + {\expanded{\bibgotoDOI{#1}{\bibgetvaro{#1}}}} + {\unknownreference{#1}}} + +\def\biburlref[#1]% + {\bibalternative\v!left + \bibresetrefsep\processcommalist[#1]\dobiburlref + \bibalternative\v!right} + +\def\bibgotoURL#1#2% + {\ifbibinteractionelse + {\useURL[bibfoo#1][#2]\goto{\url[bibfoo#1]}[url(bibfoo#1)]} + {\hyphenatedurl{#2}}} + +\def\dobiburlref#1% + {\bibinsertrefsep + \doifbibreferencefoundelse{#1} + {\expanded{\bibgotoURL{#1}{\bibgetvaru{#1}}}} + {\unknownreference{#1}}} + +\def\bibtyperef[#1]% + {\bibalternative\v!left + \bibresetrefsep\processcommalist[#1]\dobibtyperef + \bibalternative\v!right} + +\def\dobibtyperef#1% + {\bibinsertrefsep + \doifbibreferencefoundelse{#1} + {\gotobiblink{\bibgetvart{#1}}[#1]} + {\unknownreference{#1}}} + +\def\bibpageref[#1]% + {\bibalternative\v!left + \bibresetrefsep\processcommalist[#1]\dobibpageref + \bibalternative\v!right} + +\def\dobibpageref#1% + {\bibinsertrefsep + \ifbibinteractionelse + {\atbiblink[#1]} + {{\referencingfalse\at[#1]}}} + +\def\bibdataref[#1]% + {\bibalternative\v!left + \bibresetrefsep\processcommalist[#1]\dobibdata + \bibalternative\v!right} + +\def\dobibdata#1% + {\bibinsertrefsep + \doifbibreferencefoundelse{#1} + {\dotypesetapublication{#1}} + {\unknownreference{#1}}} + +\let\bibnoneref\nocite + +%D \macros{bibnumref} + +\def\bibnumref[#1]% + {\begingroup + \bibalternative\v!left + \penalty\!!tenthousand + \ctxlua{bibtex.hacks.resolve("","\number\bibtexblock","#1")}% + \bibalternative\v!right + \endgroup} + +\def\dowithbibtexnumrefconnector#1#2% + {\ifnum#1>\plusone + \ifnum#2>\plusone + \ifnum#2=#1\relax + \bibalternative{lastpubsep}% + \else + \bibalternative{pubsep}% + \fi + \fi + \fi} + +\def\dowithbibtexnumref#1#2#3#4#5% n, i, prefix block ref + {\dowithbibtexnumrefconnector{#1}{#2}% + \def\bibrefprefix{#4:}% + \inbiblink[#5]} + +\def\dowithbibtexnumrefrange#1#2#3#4#5#6#7% n, i, prefix block ref + {\dowithbibtexnumrefconnector{#1}{#2}% + \def\bibrefprefix{#4:}% + \inbiblink[#5]% + \endash + \def\bibrefprefix{#6:}% + \inbiblink[#7]} + +%D By request from Sanjoy. This makes it easier to implement +%D \type{\citeasnoun}. + +\def\bibauthornumref[#1]% + {\getcommalistsize[#1]% + \global\bibitemcounter\commalistsize + \bibresetrefsep + \processcommalist[#1]\dobibauthornumref } + +\def\dobibauthornumref#1% + {\bibinsertrefsep + \doifbibreferencefoundelse{#1} + {\begingroup + \bibgetvara{#1}% + \bibalternative\c!inbetween + \setuppublications[\c!refcommand=num]% + \cite[#1]% + \endgroup} + {\unknownreference{#1}}} + +%D And some defaults are loaded from bibl-apa: + +\def\c!monthconversion{monthconversion} % todo + +\setuppublications + [\c!monthconversion=, + \c!alternative=apa, + \c!method=\v!global, + \c!refcommand=num, + \c!numbercommand=\bibleftnumber] + +\def\preloadbiblist + {\globallet\preloadbiblist\relax + \dousepublications\jobname} + +% \appendtoks \preloadbiblist \to \everysetuppublications +% \appendtoks \preloadbiblist \to \everystarttext + +\protect \endinput diff --git a/tex/context/base/bibl-tst.lua b/tex/context/base/bibl-tst.lua new file mode 100644 index 000000000..5ff8f4570 --- /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") +print(bibtex.size,statistics.elapsedtime(bibtex)) +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/blob-ini.lua b/tex/context/base/blob-ini.lua new file mode 100644 index 000000000..0f7ccee26 --- /dev/null +++ b/tex/context/base/blob-ini.lua @@ -0,0 +1,165 @@ +if not modules then modules = { } end modules ['blob-ini'] = { + version = 1.001, + comment = "companion to blob-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- later we will consider an OO variant. + +-- This module is just a playground. Occasionally we need to typeset +-- at the lua and and this is one method. In principle we can construct +-- pages this way too which sometimes makes sense in dumb cases. Actually, +-- if one only needs this, one does not really need tex, okay maybe the +-- parbuilder but that one can be simplified as well then. + +-- set fonts, attributes +-- rest already done in packers etc +-- add local par whatsit (or wait till cleaned up) +-- collapse or new pars +-- interline spacing etc + +-- DON'T USE THESE FUNCTIONS AS THEY WILL CHANGE! + +local type = type + +local utfvalues = string.utfvalues +local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns + +local fontdata = fonts.identifiers + +local new_glyph_node = nodes.glyph +local new_glue_node = nodes.glyph + +local copy_node = node.copy +local copy_node_list = node.copy_list +local insert_node_after = node.insert_after +local flush_node_list = node.flush_list +local hpack_node_list = node.hpack +local vpack_node_list = node.vpack +local write_node = node.write + +local current_font = font.current + +blobs = blobs or { } + +local newline = lpegpatterns.newline +local space = lpegpatterns.spacer +local spacing = newline * space^0 +local content = (space^1)/" " + (1-spacing) + +local ctxtextcapture = lpeg.Ct ( ( + space^0 * ( + newline^2 * space^0 * lpeg.Cc("") + + newline * space^0 * lpeg.Cc(" ") + + lpeg.Cs(content^1) + ) +)^0) + +local function tonodes(str,fnt,attr) -- (str,template_glyph) + if not str or str == "" then + return + end + local head, tail, space, fnt, template = nil, nil, nil, nil, nil + if not fnt then + fnt = current_font() + elseif type(fnt) ~= "number" and fnt.id == "glyph" then + fnt, template = nil, fnt + -- else + -- already a number + end + for s in utfvalues(str) do + local n + if s == 32 then + if not space then + local parameters = fontdata[fnt].parameters + space = new_glue_node(parameters.space,parameters.space_stretch,parameters.space_shrink) + n = space + else + n = copy_node(space) + end + elseif template then + n = copy_node(template) + n.char = s + else + n = new_glyph_node(fnt,s) + end + if attr then -- normall false when template + n.attr = copy_node_list(attr) + end + if head then + insert_node_after(head,tail,n) + else + head = n + end + tail = n + end + return head, tail +end + +blobs.tonodes = tonodes + +function blobs.new() + return { + list = { }, + } +end + +function blobs.append(t,str) + local kind = type(str) + local dummy = nil + if kind == "string" then + local pars = lpegmatch(ctxtextcapture,str) + local list = t.list + for p=1,#pars do + local str = pars[p] + if #str == 0 then + list[#list+1 ] = { head = nil, tail = nil } + else + local l = list[#list] + if not l then + l = { head = nil, tail = nil } + list[#list+1 ] = l + end + local head, tail = tonodes(str,nil,nil) + if head then + if l.head then + l.tail.next = head + head.prev = l.tail + l.tail = tail + else + l.head, l.tail = head, tail + end + end + end + end + end +end + +function blobs.pack(t,how) + local list = t.list + for i=1,#list do + local pack = list[i].pack + if pack then + flush_node_list(node.pack) + end + if how == "vertical" then + -- we need to prepend a local par node + -- list[i].pack = node.vpack(list[i].head,"exactly") + logs.report("blobs","vpack not yet supported") + else + list[i].pack = hpack_node_list(list[i].head,"exactly") + end + end +end + +function blobs.write(t) + local list = t.list + for i=1,#list do + local pack = list[i].pack + if pack then + write_node(pack) + end + end +end diff --git a/tex/context/base/blob-ini.mkiv b/tex/context/base/blob-ini.mkiv new file mode 100644 index 000000000..7f63ec73d --- /dev/null +++ b/tex/context/base/blob-ini.mkiv @@ -0,0 +1,34 @@ +%D \module +%D [ file=blob-ini, +%D version=2010.04.06, +%D title=\CONTEXT\ \LUA\ Typesetting, +%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 Lua Typesetting / Initialization} + +%D This is a prelude to typesetting at the \LUA\ end. The code +%D is already quite old but will only get nice when we are further +%D down the road (close to version 1.00 of \LUATEX). Typesetting in +%D pure \LUA\ sometimes makes sense. + +\registerctxluafile{blob-ini}{1.001} + +\endinput + +% \starttext +% +% \startluacode +% local b = blobs.new() +% blobs.append(b,"Hello world.\n Here we are.\n\n And Again!") +% blobs.pack(b) +% blobs.write(b) +% \stopluacode +% +% \stoptext diff --git a/tex/context/base/buff-ini.lua b/tex/context/base/buff-ini.lua new file mode 100644 index 000000000..6b1af8f96 --- /dev/null +++ b/tex/context/base/buff-ini.lua @@ -0,0 +1,838 @@ +if not modules then modules = { } end modules ['buff-ini'] = { + version = 1.001, + comment = "companion to core-buf.mkiv", + 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 + +buffers = { } +buffers.data = { } +buffers.hooks = { } +buffers.flags = { } +buffers.commands = { } +buffers.visualizers = { } + +-- if needed we can make 'm local + +local trace_run = false trackers.register("buffers.run", function(v) trace_run = v end) +local trace_visualize = false trackers.register("buffers.visualize", function(v) trace_visualize = v end) + +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 type, next = type, next +local huge = math.huge +local byte, sub, find, char, gsub, rep, lower, format, gmatch, match = string.byte, string.sub, string.find, string.char, string.gsub, string.rep, string.lower, string.format, string.gmatch, string.match +local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues +local ctxcatcodes = tex.ctxcatcodes +local variables = interfaces.variables +local lpegmatch = lpeg.match + +local data, flags, hooks, visualizers = buffers.data, buffers.flags, buffers.hooks, buffers.visualizers + +visualizers.defaultname = variables.typing + +function buffers.raw(name) + return data[name] or { } +end + +function buffers.erase(name) + data[name] = nil +end + +function buffers.set(name, str) + data[name] = { str } -- CHECK THIS +end + +function buffers.append(name, str) + data[name] = (data[name] or "") .. str +end + + +buffers.flags.store_as_table = true + +-- to be sorted out: crlf + \ ; slow now + +local n = 0 + +function buffers.grab(name,begintag,endtag,bufferdata) + local dn = data[name] or "" + if dn == "" then + buffers.level = 0 + end + buffers.level = buffers.level + bufferdata:count("\\"..begintag) - bufferdata:count("\\"..endtag) + local more = buffers.level > 0 + if more then + dn = dn .. bufferdata .. endtag + buffers.level = buffers.level - 1 + else + if dn == "" then + dn = sub(bufferdata,1,#bufferdata-1) + else + dn = dn .. "\n" .. sub(bufferdata,1,#bufferdata-1) + end + dn = gsub(dn,"[\010\013]$","") + if flags.store_as_table then + dn = dn:splitlines() + end + end + data[name] = dn + cs.testcase(more) +end + +function buffers.exists(name) + return data[name] ~= nil +end + +function buffers.doifelsebuffer(name) + cs.testcase(data[name] ~= nil) +end + +flags.optimize_verbatim = true +flags.count_empty_lines = false + +local no_break_command = "\\doverbatimnobreak" +local do_break_command = "\\doverbatimgoodbreak" +local begin_of_line_command = "\\doverbatimbeginofline" +local end_of_line_command = "\\doverbatimendofline" +local empty_line_command = "\\doverbatimemptyline" + +local begin_of_display_command = "\\doverbatimbeginofdisplay" +local end_of_display_command = "\\doverbatimendofdisplay" +local begin_of_inline_command = "\\doverbatimbeginofinline" +local end_of_inline_command = "\\doverbatimendofinline" + +function buffers.verbatimbreak(n,m) + if flags.optimize_verbatim then + if n == 2 or n == m then + texsprint(no_break_command) + elseif n > 1 then + texsprint(do_break_command) + end + end +end + +function buffers.strip(lines,first,last) + local first, last = first or 1, last or #lines + for i=first,last do + local li = lines[i] + if #li == 0 or find(li,"^%s*$") then + first = first + 1 + else + break + end + end + for i=last,first,-1 do + local li = lines[i] + if #li == 0 or find(li,"^%s*$") then + last = last - 1 + else + break + end + end + return first, last, last - first + 1 +end + +function buffers.range(lines,first,last,range) -- 1,3 1,+3 fromhere,tothere + local first, last = first or 1, last or #lines + local what = aux.settings_to_array(range) + local r_first, r_last = what[1], what[2] + local f, l = tonumber(r_first), tonumber(r_last) + if r_first then + if f then + if f > first then + first = f + end + else + for i=first,last do + if find(lines[i],r_first) then + first, strip = i + 1 + break + end + end + end + end + if r_last then + if l then + if find(r_last,"^[%+]") then -- 1,+3 + l = first + l + end + if l < last then + last = l + end + else + for i=first,last do + if find(lines[i],r_last) then + last = i - 1 + break + end + end + end + end + return first, last +end + +function buffers.type(name,realign,range) + local lines = data[name] + local action = buffers.typeline + if lines then + if type(lines) == "string" then + lines = lines:splitlines() + data[name] = lines + end + if realign then + lines = buffers.realign(lines,realign) + end + local line, n = 0, 0 + local first, last, m = buffers.strip(lines) + if range then + first, last = buffers.range(lines,first,last,range) + first, last = buffers.strip(lines,first,last) + end + hooks.begin_of_display() + for i=first,last do + n, line = action(lines[i], n, m, line) + end + hooks.end_of_display() + end +end + +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 +end + +function buffers.loaddata(filename) -- this one might go away + local foundname = resolvers.findtexfile(filename) or "" + if foundname == "" then + foundname = resolvers.findtexfile(file.addsuffix(filename,'tex')) or "" + end + if foundname == "" then + return "" + else + return resolvers.loadtexfile(foundname) + end +end + +function buffers.typefile(name,realign,range) -- still somewhat messy, since name can be be suffixless + local str = buffers.loaddata(name) + if str and str~= "" then + local lines = str:splitlines() + if realign then + lines = buffers.realign(lines,realign) + end + local line, n, action = 0, 0, buffers.typeline + local first, last, m = buffers.strip(lines) + hooks.begin_of_display() + if range then + first, last = buffers.range(lines,first,last,range) + first, last = buffers.strip(lines,first,last) + end + for i=first,last do + n, line = action(lines[i], n, m, line) + end + hooks.end_of_display() + end +end + +function buffers.typeline(str,n,m,line) + n = n + 1 + buffers.verbatimbreak(n,m) + if find(str,"%S") then + line = line + 1 + hooks.begin_of_line(line) + hooks.flush_line(hooks.line(str)) + hooks.end_of_line() + else + if flags.count_empty_lines then + line = line + 1 + end + hooks.empty_line(line) + end + return n, line +end + +-- The optional prefix hack is there for the typesetbuffer feature and +-- in mkii we needed that (this hidden feature is used in a manual). + +local function prepared(name,list) -- list is optional + if not list or list == "" then + list = name + end + if not name or name == "" then + name = tex.jobname .. "-" .. list .. ".tmp" + end + local content = buffers.collect(list,nil) or "" + if content == "" then + content = "empty buffer" + end + return name, content +end + +local capsule = "\\starttext\n%s\n\\stoptext\n" +local command = "context %s" + +function buffers.save(name,list,encapsulate) -- list is optional + local name, content = prepared(name,list) + io.savedata(name, (encapsulate and format(capsule,content)) or content) +end + +function commands.savebuffer(list,name) -- name is optional + buffers.save(name,list) +end + +function buffers.run(name,list,encapsulate) + local name, content = prepared(name,list) + local data = io.loaddata(name) + content = (encapsulate and format(capsule,content)) or content + if data ~= content then + if trace_run then + commands.writestatus("buffers","changes in '%s', processing forced",name) + end + io.savedata(name,content) + os.execute(format(command,name)) + elseif trace_run then + commands.writestatus("buffers","no changes in '%s', not processed",name) + end +end + +local printer = (lpeg.patterns.textline/texprint)^0 + +function buffers.get(name) + local b = buffers.data[name] + if b then + if type(b) == "table" then + for i=1,#b do + texprint(b[i]) + end + else + lpegmatch(printer,b) + end + end +end + +local function content(name,separator) -- no print + local b = data[name] + if b then + if type(b) == "table" then + return concat(b,separator or "\n") + else + return b + end + else + return "" + end +end + +buffers.content = content + +function buffers.collect(names,separator) -- no print + -- maybe we should always store a buffer as table so + -- that we can pass it directly + if type(names) == "string" then + names = aux.settings_to_array(names) + end + local t = { } + for i=1,#names do + local c = content(names[i],separator) + if c ~= "" then + t[#t+1] = c + end + end + return concat(t,separator or "\r") -- "\n" is safer due to comments and such +end + +function buffers.feedback(names,separator) + -- don't change the texprint into texsprint as it fails on mp buffers + -- because (penddef) becomes penddef then + texprint(ctxcatcodes,string.splitlines(buffers.collect(names,separator))) +end + +local function tobyte(c) + return " [" .. utfbyte(c) .. "] " +end + +function buffers.inspect(name) + local b = data[name] + if b then + if type(b) == "table" then + for k=1,#b do + local v = b[k] + if v == "" then + texsprint(ctxcatcodes,"[crlf]\\par ") -- space ? + else + texsprint(ctxcatcodes,(gsub(v,"(.)",tobyte)),"\\par") + end + end + else + texsprint(ctxcatcodes,(gsub(b,"(.)",tobyte))) + end + end +end + +-- maybe just line(n,str) empty(n,str) + +visualizers.tablength = 7 +visualizers.enabletab = true -- false +visualizers.obeyspace = true + +function buffers.settablength(tablength) + visualizers.tablength = tablength and tonumber(tablength) or 7 +end + +visualizers.handlers = visualizers.handlers or { } + +local handlers = visualizers.handlers + +function buffers.newvisualizer(name) + name = lower(name) + local handler = { } + handlers[name] = handler + return handler +end + +function buffers.getvisualizer(name) + name = lower(name) + return handlers[name] or buffers.loadvisualizer(name) +end + +function buffers.loadvisualizer(name) + name = lower(name) + local hn = handlers[name] + if hn then + return hn + else + environment.loadluafile("pret-" .. name) + local hn = handlers[name] + if not hn then + -- hn = buffers.newvisualizer(name) + hn = handlers[visualizers.defaultname] + handlers[name] = hn + if trace_visualize then + logs.report("buffers","mapping '%s' visualizer onto '%s'",name,visualizers.defaultname) + end + elseif trace_visualize then + logs.report("buffers","loading '%s' visualizer",name) + end + return hn + end +end + +-- was "default", should be set at tex end (todo) + +local default = buffers.newvisualizer(visualizers.defaultname) + +--~ print(variables.typing) os.exit() + +-- will become cleaner + +local currentvisualizer, currenthandler + +function buffers.setvisualizer(str) + currentvisualizer = lower(str) + currenthandler = handlers[currentvisualizer] + if currenthandler then + -- if trace_visualize then + -- logs.report("buffers","enabling specific '%s' visualizer",currentvisualizer) + -- end + else + currentvisualizer = visualizers.defaultname + currenthandler = handlers.default + -- if trace_visualize then + -- logs.report("buffers","enabling default visualizer '%s'",currentvisualizer) + -- end + end + if currenthandler.reset then + currenthandler.reset() + end +end + +function buffers.resetvisualizer() + currentvisualizer = visualizers.defaultname + currenthandler = handlers.default + if currenthandler.reset then + currenthandler.reset() + end +end + +buffers.setvisualizer(visualizers.defaultname) + +function visualizers.reset() +end + +function buffers.doifelsevisualizer(str) + cs.testcase((str ~= "") and (handlers[lower(str)] ~= nil)) +end + +-- calling routines, don't change + +function hooks.begin_of_display() + (currenthandler.begin_of_display or default.begin_of_display)(currentvisualizer) +end + +function hooks.end_of_display() + (currenthandler.end_of_display or default.end_of_display)() +end + +function hooks.begin_of_inline() + (currenthandler.begin_of_inline or default.begin_of_inline)(currentvisualizer) +end + +function hooks.end_of_inline() + (currenthandler.end_of_inline or default.end_of_inline)() +end + +function hooks.flush_line(str,nesting) + local fl = currenthandler.flush_line + if fl then + str = gsub(str," *[\n\r]+ *"," ") ; -- semi colon needed + fl(str,nesting) + else + -- gsub done later + default.flush_line(str,nesting) + end +end + +function hooks.flush_inline(str,nesting) + hooks.begin_of_inline() + hooks.flush_line(str,nesting) + hooks.end_of_inline() +end + +function hooks.begin_of_line(n) + (currenthandler.begin_of_line or default.begin_of_line)(n) +end + +function hooks.end_of_line() + (currenthandler.end_of_line or default.end_of_line)() +end + +function hooks.empty_line() + (currenthandler.empty_line or default.empty_line)() +end + +function hooks.line(str) + if visualizers.enabletab then + str = string.tabtospace(str,visualizers.tablength) + else + str = gsub(str,"\t"," ") + end + return (currenthandler.line or default.line)(str) +end + +-- defaults + +function default.begin_of_display(currentvisualizer) + texsprint(ctxcatcodes,begin_of_display_command,"{",currentvisualizer,"}") +end + +function default.end_of_display() + texsprint(ctxcatcodes,end_of_display_command) +end + +function default.begin_of_inline(currentvisualizer) + texsprint(ctxcatcodes,begin_of_inline_command,"{",currentvisualizer,"}") +end + +function default.end_of_inline() + texsprint(ctxcatcodes,end_of_inline_command) +end + +function default.begin_of_line(n) + texsprint(ctxcatcodes, begin_of_line_command,"{",n,"}") +end + +function default.end_of_line() + texsprint(ctxcatcodes,end_of_line_command) +end + +function default.empty_line() + texsprint(ctxcatcodes,empty_line_command) +end + +function default.line(str) + return str +end + +function default.flush_line(str) + str = gsub(str," *[\n\r]+ *"," ") + if visualizers.obeyspace then + for c in utfcharacters(str) do + if c == " " then + texsprint(ctxcatcodes,"\\obs") + else + texwrite(c) + end + end + else + texwrite(str) + end +end + +-- not needed any more + +local function escaped_token(c) + if utffind(c,"^(%a%d)$") then + return c + elseif c == " " then + return "\\obs " + else + return "\\char" .. utfbyte(c) .. " " + end +end + +buffers.escaped_token = escaped_token + +function buffers.escaped(str) + -- use the utfcharacters loop + return (utfgsub(str,"(.)", escaped_token)) +end + +-- special one + +buffers.commands.nested = "\\switchslantedtype " + +-- todo : utf + faster, direct print and such. no \\char, vrb catcodes, see end + +function visualizers.flush_nested(str, enable) -- no utf, kind of obsolete mess + str = gsub(str," *[\n\r]+ *"," ") + local result, c, nested, i = "", "", 0, 1 + local commands = buffers.commands -- otherwise wrong commands + while i < #str do -- slow + c = sub(str,i,i+1) + if c == "<<" then + nested = nested + 1 + if enable then + result = result .. "{" .. commands.nested + else + result = result .. "{" + end + i = i + 2 + elseif c == ">>" then + if nested > 0 then + nested = nested - 1 + result = result .. "}" + end + i = i + 2 + else + c = sub(str,i,i) + if c == " " then + result = result .. "\\obs " + elseif find(c,"%a") then + result = result .. c + else + result = result .. "\\char" .. byte(c) .. " " + end + i = i + 1 + end + end + result = result .. "\\char" .. byte(sub(str,i,i)) .. " " .. rep("}",nested) + texsprint(ctxcatcodes,result) +end + +-- handy helpers +-- +-- \sop[color] switch_of_pretty +-- \bop[color] begin_of_pretty +-- \eop end_of_pretty +-- \obs obeyedspace +-- \char special characters + +buffers.currentcolors = { } + +function buffers.change_state(n, state) + if n then + if state ~= n then + if state > 0 then + texsprint(ctxcatcodes,"\\sop[",buffers.currentcolors[n],"]") + else + texsprint(ctxcatcodes,"\\bop[",buffers.currentcolors[n],"]") + end + return n + end + elseif state > 0 then + texsprint(ctxcatcodes,"\\eop") + return 0 + end + return state +end + +function buffers.finish_state(state) + if state > 0 then + texsprint(ctxcatcodes,"\\eop") + return 0 + else + return state + end +end + +buffers.open_nested = rep("\\char"..byte('<').." ",2) +buffers.close_nested = rep("\\char"..byte('>').." ",2) + +function buffers.replace_nested(result) + 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(ctxcatcodes,buffers.replace_nested(concat(result,""))) + else + texsprint(ctxcatcodes,concat(result,"")) + end +end + +-- new + +function buffers.realign(name,forced_n) -- no, auto, + local n, d + if type(name) == "string" then + d = data[name] + if type(d) == "string" then + d = d:splitlines() + end + else + d = name -- already a buffer + end + forced_n = (forced_n == variables.auto and huge) or tonumber(forced_n) + if forced_n then + for i=1, #d do + local spaces = find(d[i],"%S") + if not spaces then + -- empty line + elseif not n then + n = spaces + elseif spaces == 0 then + n = 0 + break + elseif n > spaces then + n = spaces + end + end + if n > 0 then + if n > forced_n then + n = forced_n + end + for i=1,#d do + d[i] = sub(d[i],n) + end + end + end + return d +end + +-- escapes: buffers.set_escape("tex","/BTEX","/ETEX") + +local function flush_escaped_line(str,pattern,flushline) + while true do + local a, b, c = match(str,pattern) + if a and a ~= "" then + flushline(a) + end + if b and b ~= "" then + texsprint(ctxcatcodes,"{",b,"}") + end + if c then + if c == "" then + break + else + str = c + end + else + flushline(str) + break + end + end +end + +function buffers.set_escape(name,pair) + if pair and pair ~= "" then + local visualizer = buffers.getvisualizer(name) + visualizer.normal_flush_line = visualizer.normal_flush_line or visualizer.flush_line + if pair == variables.no then + visualizer.flush_line = visualizer.normal_flush_line or visualizer.flush_line + if trace_visualize then + logs.report("buffers","resetting escape range for visualizer '%s'",name) + end + else + local start, stop + if pair == variables.yes then + start, stop = "/BTEX", "/ETEX" + else + pair = string.split(pair,",") + start, stop = string.esc(pair[1] or ""), string.esc(pair[2] or "") + end + if start ~= "" then + local pattern + if stop == "" then + pattern = "^(.-)" .. start .. "(.*)(.*)$" + else + pattern = "^(.-)" .. start .. "(.-)" .. stop .. "(.*)$" + end + function visualizer.flush_line(str) + flush_escaped_line(str,pattern,visualizer.normal_flush_line) + end + if trace_visualize then + logs.report("buffers","setting escape range for visualizer '%s' to %s -> %s",name,start,stop) + end + elseif trace_visualize then + logs.report("buffers","problematic escape specification '%s' for visualizer '%s'",pair,name) + end + end + end +end + +-- THIS WILL BECOME A FRAMEWORK: the problem with prety printing is that +-- we deal with snippets and therefore we need tolerant parsing + +--~ local type = type + +--~ visualizers = visualizers or { } + +--~ local function fallback(s) return s end + +--~ function visualizers.visualize(visualizer,kind,pattern) +--~ if type(visualizer) == "table" and type(kind) == "string" then +--~ kind = visualizer[kind] or visualizer.default or fallback +--~ else +--~ kind = fallback +--~ end +--~ return (lpeg.C(pattern))/kind +--~ end + +--~ local flusher = texio.write +--~ local format = string.format + +--~ local visualizer = { +--~ word = function(s) return flusher(format("\\bold{%s}",s)) end, +--~ number = function(s) return flusher(format("\\slanted{%s}",s)) end, +--~ default = function(s) return flusher(s) end, +--~ } + +--~ local word = lpeg.R("AZ","az")^1 +--~ local number = lpeg.R("09")^1 +--~ local any = lpeg.P(1) + +--~ local pattern = lpeg.P { "start", +--~ start = ( +--~ visualizers.visualize(visualizer,"word",word) + +--~ visualizers.visualize(visualizer,"number",number) + +--~ visualizers.visualize(visualizer,"default",any) +--~ )^1 +--~ } + +--~ str = [[test 123 test $oeps$]] + +--~ lpegmatch(pattern,str) diff --git a/tex/context/base/buff-ini.mkii b/tex/context/base/buff-ini.mkii new file mode 100644 index 000000000..fc147d090 --- /dev/null +++ b/tex/context/base/buff-ini.mkii @@ -0,0 +1,348 @@ +%D \module +%D [ file=buff-ini, % was core-buf % blocks are moved to core-blk +%D version=2000.01.05, +%D title=\CONTEXT\ Buffer 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 Buffer Macros / Buffers} + +\unprotect + +% Helpers: + +\chardef\buffernestmode\plusone % 0: not nested, 1: startbuffer nested, 2: all buffers nested + +\edefconvertedargument\emptybufferline{ } + +\ifx\tmpblocks\undefined \newwrite\tmpblocks \fi + +\newif\iftmpblockstarted + +\long\def\flushbufferline#1% + {\iftmpblockstarted + \ifsegmentatebuffer + \ifemptybufferline + \immediate\write\tmpblocks{\string\stopbufferparagraph }% + \immediate\write\tmpblocks{\string\startbufferparagraph}% + \else + \immediate\write\tmpblocks{#1}% + \fi + \else + \immediate\write\tmpblocks{#1}% + \fi + \else + \doifsomething{#1} + {\tmpblockstartedtrue + \immediate\write\tmpblocks{\string#1}}% + \fi} + +\long\def\processnextbufferlineA#1% + {\relax % checken waarom eerdere macro dit nodig heeft / supp-mps run + \defconvertedargument\next{#1 }% + \doifinstringelse{\delcharacter\letterpercent}{\delcharacter\next} + {\secondoftwoarguments} + {\doifincsnameelse\endofblock\next + {\ifnum\nestedbufferlevel=\zerocount + \expandafter\firstoftwoarguments + \else + \decrement\nestedbufferlevel\relax + \expandafter\secondoftwoarguments + \fi} + {\doifincsnameelse\beginofblock\next + {\increment\nestedbufferlevel\relax + \secondoftwoarguments} + {\secondoftwoarguments}}}} + +\long\def\processnextbufferlineB#1% #2#3% + {\defconvertedargument\next{#1 }% + \ifx\next\emptybufferline + \ifsegmentatebuffer \emptybufferlinetrue \fi + \expandafter\secondoftwoarguments% #3% + \else + \emptybufferlinefalse + \doifinstringelse\endofblock\next + {\expandafter\firstoftwoarguments }% #2} + {\expandafter\secondoftwoarguments}% #3}% + \fi} + +\bgroup +\obeylines +\long\gdef\copybufferline#1 + {\processnextbufferline{#1}\closebufferfile{\flushbufferline{#1}\copybufferline}} +\egroup + +\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}% + \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]}% + \unexpanded\setevalue{\e!get #1}{\noexpand\dogetbuffer [#1][def-\nofdefinedbuffers]}% + \unexpanded\setevalue{\e!type #1}{\noexpand\dotypebuffer [#1][def-\nofdefinedbuffers]}% + \getparameters[\??bu#1][#2]% + \fi} + +\def\definebuffer + {\dodoubleempty\dodefinebuffer} + +\unexpanded\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}} + +\unexpanded\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/buff-ini.mkiv b/tex/context/base/buff-ini.mkiv new file mode 100644 index 000000000..86b0fa3c5 --- /dev/null +++ b/tex/context/base/buff-ini.mkiv @@ -0,0 +1,355 @@ +%D \module +%D [ file=buff-ini, % was core-buf, % blocks are moved to core-blk +%D version=2000.01.05, +%D title=\CONTEXT\ Buffer 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 Buffer Macros / Buffers} + +\registerctxluafile{buff-ini}{1.001} + +% todo: +% +% \startluacode +% local locations = { } +% function document.set_number(name) +% locations[name] = { +% line = status.linenumber, +% file = status.filename +% } +% end +% function document.add_number(name) +% local b, l = buffers.raw(name), locations[name] +% if b and l then +% for i=1,#b do +% b[i] = string.gsub(b[i],"# line: ","# line: " .. l.line + 2) +% end +% end +% end +% \stopluacode +% +% \starttext +% +% \ctxlua{document.set_number("oeps")} +% \startbuffer[oeps] +% # line: +% +% test +% test +% \stopbuffer +% \ctxlua{document.add_number("oeps")} +% +% \typebuffer[oeps] +% +% \stoptext + +\ifdefined\doinitializeverbatim \else% temp hack + \def\doinitializeverbatim{\tttf} +\fi + +\unprotect + +\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}% + \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}}% + \normalexpanded{\noexpand\dodowithbuffer + {\currentbuffer} + {\bufferstart} + {\bufferstop} + {\donothing} + {\egroup + \noexpand\getvalue{\bufferstop}}}} + +\letvalue{\e!start\v!buffer}\dostartbuffer + +\let\endbuffer\undefined % to please the dep parser + +\def\dowithbuffer#1#2#3% name, startsequence, stopsequence, before, after + {\setbuffercapsules{#2}{#3}% + \normalexpanded{\noexpand\dodowithbuffer{#1}{\bufferstart}{\bufferstop}}} + +\long\def\dodowithbuffer#1#2#3#4#5% name, startsequence, stopsequence, before, after + {#4% + \bgroup + \setcatcodetable \vrbcatcodes + \catcode`\\=12 + \ctxlua{buffers.erase("#1")}% + \long\def\nododowithbuffer + {\egroup + #5}% + \long\def\dododowithbuffer##1#3% is detokenize needed? TEST + {\ctxlua + {buffers.grab("#1","#2","#3",\!!bs\detokenize{##1}\!!es)} + \dododowithbuffer + \nododowithbuffer}% + \dododowithbuffer} + +\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} + +\unexpanded\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 + \setuevalue{\e!start#1}{\noexpand\dostartbuffer[#1][def-\nofdefinedbuffers][\e!start#1][\e!stop#1]}% maybe also relax stop + \setuevalue{\e!get #1}{\noexpand\dogetbuffer [#1][def-\nofdefinedbuffers]}% + \setuevalue{\e!type #1}{\noexpand\dotypebuffer [#1][def-\nofdefinedbuffers]}% + \getparameters[\??bu#1][#2]% + \fi} + +\unexpanded\def\definebuffer + {\dodoubleempty\dodefinebuffer} + +\def\thebuffernumber#1% + {\csname\??bu#1\c!number\endcsname} + +\unexpanded\def\getbuffer + {\dodoubleempty\dogetbuffer} + +\def\dogetbuffer[#1][#2]% + {\ifsecondargument + \dodogetbuffer[#1][#2]% + \else + \dodogetbuffer[][#1]% + \fi} + +\def\dogetbufferasis{\ctxlua{buffers.get("\currentbuffer")}} + +\def\dodogetbuffer[#1][#2]% + {\getvalue{\??bu#1\c!before}% + \dobuffer{16}{#2}\dogetbufferasis + \getvalue{\??bu#1\c!after}} + +\unexpanded\def\typebuffer + {\dodoubleempty\dotypebuffer} + +\def\doprocessbufferverbatim + {\doinitializeverbatim + \ctxlua{buffers.type("\currentbuffer","\typingparameter\c!strip")}} + +\def\doprocessbufferlinesverbatim#1#2#3% + {#2% + % todo, set up numbers + \doinitializeverbatim + \ctxlua{buffers.type("\currentbuffer","\typingparameter\c!strip")} + #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} + +\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 + {\unexpanded\def\startbufferparagraph{\normalbufferparagraph{#1}}} + {\unexpanded\def\startbufferparagraph{\filterbufferparagraph{#1}{#2}}}% + \unexpanded\def\stopbufferparagraph{\dostopbufferparagraph{#1}}% + \def\next{\getparagraphedbuffer[#1]}% + \else + \dosetbufferoffset\empty + \unexpanded\def\startbufferparagraph{\filterbufferparagraph{}{#1}}% + \unexpanded\def\stopbufferparagraph{\dostopbufferparagraph{}}% + \def\next{\getparagraphedbuffer[]}% + \fi + \else + \dosetbufferoffset\empty + \unexpanded\def\startbufferparagraph{\normalbufferparagraph{}}% + \unexpanded\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 + \unexpanded\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: +% +% \startbuffer[x] +% x +% \stopbuffer +% +% \savebuffer[x][temp.log] + +\unexpanded\def\savebuffer{\dodoubleempty\dosavebuffer} + +\def\dosavebuffer[#1][#2]{\ctxlua{commands.savebuffer("#1","#2")}} + +\protect \endinput diff --git a/tex/context/base/buff-ver.mkii b/tex/context/base/buff-ver.mkii new file mode 100644 index 000000000..e7ad5474f --- /dev/null +++ b/tex/context/base/buff-ver.mkii @@ -0,0 +1,1340 @@ +%D \module +%D [ file=buff-ver, % was core-ver +%D version=2000.05.09, +%D title=\CONTEXT\ Buffer 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 Buffer Macros / Verbatim} + +\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}}% + \doifundefined{setuppretty\prettyidentifier type}% + {\startnointerference + \restorecatcodes % also needed when loading during \newpretty + \startreadingfile % restore < and > if needed + \lowercasestring verb-\prettyidentifier\to\filename + \readsysfile{\filename.mkii}\donothing\donothing + \stopreadingfile + \stopnointerference}% + \doifdefinedelse{setuppretty\prettyidentifier type}% + {\let\uncatcodecharacters\uncatcodeallcharacters % ugly, should be switch / todo + \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 +% +% \setupcolors[state=start] +% \setuptype[option=TEX] +% \setupcolors[textcolor=red] +% +% The options \type{before=\startsolutionbackground } and +% \type{after=\stopsolutionbackground} take care of putting a frame, +% which can +% +% {\blue The options \type{before=\startsolutionbackground } and +% \type{after=\stopsolutionbackground} take care of putting a frame, +% which} can + +\def\resumecoloraftergroup + {\localstartcolor[\s!black]% + \localstartcolor[\maintextcolor]% + \aftergroup\localstopcolor + \aftergroup\localstopcolor} + +% the rather messy \type command + +\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 + \let\currenttypingclass\??ty + \edef\currenttyping{#1}% + \catcode`\<=\@@other + \catcode`\>=\@@other + \futurelet\next\dodotype} + +\def\dodotypeA + {\initializetype + \initializetypegrouping + \verbatimfont + \verbatimcolor + \afterassignment\protectfirsttype\let\next=} + +\def\dodotypeB + {\initializetype + \setupnotypegrouping + \verbatimfont + \verbatimcolor + \let\next=} + +\def\dodotypeC<#1% + {\initializetype + \verbatimfont + \verbatimcolor + \if#1<% + \@EA\setupalternativetypegrouping + \else + \@EA#1% + \fi} + +\def\dodotypeD#1% + {\initializetype + \verbatimfont + \verbatimcolor + \catcode`#1=\@@endgroup} + +\def\dodotype + {\ifx\next\bgroup + \@EA\dodotypeA + \else\if\next<% + \doifelse{\typingparameter\c!option}\v!none + {\@EAEAEA\dodotypeB}{\@EAEAEA\dodotypeC}% + \else + \@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}. + +\chardef\recodeverbatimmode\zerocount % 0=nothing 1=rescan 2=autorescan + +% \appendtoks \chardef\recodeverbatimmode\plustwo \to \everytabulate +% \appendtoks \chardef\recodeverbatimmode\plustwo \to \everytable + +\def\dodotypeA + {\initializetype + \initializetypegrouping + \verbatimfont + \verbatimcolor + \ifcase\recodeverbatimmode + \@EA\dodotypeAA + \or + \@EA\dodotypeAB + \or + \ifnum\catcode`\{=\@@active + \@EAEAEA\dodotypeAB + \else + \@EAEAEA\dodotypeAA + \fi + \else + \@EA\dodotypeAA + \fi} + +\def\dodotypeAA + {\afterassignment\protectfirsttype\let\next=} + +\def\dodotypeAB + {\bgroup + \catcode`\}=\@@endgroup + \catcode`\{=\@@begingroup + \afterassignment\redotypeAB\global\globalscratchtoks} + +\def\redotypeAB + {\egroup + \expandafter\defconvertedargument\expandafter\ascii\expandafter{\the\globalscratchtoks}% == \edefconvertedargument\ascii{\the\globalscratchtoks}% + \ifx\scantokens\undefined\ascii\else\everyeof{\hskip-\spaceskip}\scantokens\expandafter{\ascii}\fi + \egroup} + +\bgroup +\catcode`\[=\@@begingroup +\catcode`\]=\@@endgroup +\catcode`\{=\@@active +\catcode`\}=\@@active +\gdef\initializetypegrouping + [\ifnum\catcode`\{=\@@active + \let\normalactivebgroup{% + \let\normalactiveegroup}% + \else + \catcode`\{=\@@active + \catcode`\}=\@@active + \let\normalactivebgroup\leftargument + \let\normalactiveegroup\rightargument + \fi + \def\activeleftargument + [\bgroup + \catcode`\}=\@@active + \let}\activerightargument + \normalactivebgroup]% + \def\activerightargument + [\normalactiveegroup + \egroup]% + \let{=\activeleftargument + % not \let}=\egroup, otherwise things go wrong in alignments (???) + \catcode`\}=\@@endgroup] +\egroup + +\bgroup +\catcode`\<=\@@active +\catcode`\>=\@@active +\gdef\setupalternativetypegrouping + {\catcode`\<=\@@active + \catcode`\>=\@@active + \def\doless + {\ifx<\next + \def\next + {\bgroup\switchslantedtype + \let\next=}% + \else + \let\next\lesscharacter + \fi + \next}% + \def\domore + {\ifx>\next + \def\next + {\egroup + \let\next=}% + \else + \let\next\morecharacter + \fi + \next}% + \def<{\futurelet\next\doless}% + \def>{\futurelet\next\domore}} +\egroup + +\def\setupnotypegrouping + {\catcode`\<=\@@begingroup + \catcode`\>=\@@endgroup} + +\def\doenterdoublelesstype + {\ifx\next\egroup + \lesscharacter\null\lesscharacter + \else + \bgroup\switchslantedtype + \let\doenterdoublemoretype\egroup + \fi} + +\def\doenterdoublemoretype + {\def\doenterdoubletype + {\ifx\next\egroup + \morecharacter\null\morecharacter + \fi}} + +\bgroup +\catcode`\<=\@@active +\catcode`\>=\@@active +\gdef\setupgroupedtype + {\catcode`\<=\@@active + \catcode`\>=\@@active + \def\doless + {\ifx<\next + \def\next + {\def\enterdoubletype{\futurelet\next\doenterdoublelesstype}% + \afterassignment\enterdoubletype + \let\next=}% + \else + \let\next\lesscharacter + \fi + \next}% + \def\domore + {\ifx>\next + \def\next + {\def\enterdoubletype{\futurelet\next\doenterdoublemoretype}% + \afterassignment\enterdoubletype + \let\next=}% + \else + \let\next\morecharacter + \fi + \next}% + \def<{\futurelet\next\doless}% + \def>{\futurelet\next\domore}} +\egroup + +%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 + {% \nohyphens % forgotten when no \par + \normallanguage\minusone % fails as the font redoes the language + \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\$\$}{\$\$}} + +\let\normaltexttex\tex +\let\normaltextarg\arg +\let\normaltextmat\mat +\let\normaltextdis\dis + +%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/buff-ver.mkiv b/tex/context/base/buff-ver.mkiv new file mode 100644 index 000000000..dacbdb7ac --- /dev/null +++ b/tex/context/base/buff-ver.mkiv @@ -0,0 +1,1193 @@ +%D \module +%D [ file=buff-ver, % was core-ver +%D version=2000.05.09, +%D title=\CONTEXT\ Buffer 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 Buffer Macros / Verbatim} + +%D We can optimize esp the initializations a bit. + +\unprotect + +\ifdefined\startlinenumbering\else \let\startlinenumbering \relax \fi +\ifdefined\stoplinenumbering \else \let\stoplinenumbering \relax \fi +\ifdefined\setuplinenumbering\else \unexpanded\def\setuplinenumbering[#1]{} \fi + +% D \macros +% D {iflinepar} +% D +% D A careful reader will see that \type{\linepar} is reset. +% D This boolean can be used to determine if the current line is +% D the first line in a pseudo paragraph and this boolean is set +% D after each empty line. The \type{\relax} can be used to +% D determine the end of the line when one implements a scanner +% D routine. +% +% will become obsolete + +\newif\iflinepar + +% \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} + +\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}} + +\unexpanded\def\setupprettiesintype#1% + {\uppercasestring#1\to\ascii + \edef\prettyidentifier{\executeifdefined{\??ty\??ty\ascii}{TEX}}% + \begingroup + % we can move this to lua + % \lowercasestring \f!prettyprefix\prettyidentifier\to\filename + % \doonlyonce\filename{\ctxloadluafile\filename\empty}% + \ctxlua{buffers.loadvisualizer("\ascii")}% + \endgroup} + +\unexpanded\def\setupprettytype + {\processingverbatimtrue % will move + \ctxlua{buffers.visualizers.reset()}} + +\def\setverbatimspaceskip + {\setbox\scratchbox\hbox{x}% + \spaceskip\wd\scratchbox + \xspaceskip\spaceskip} + +\let\obeycharacters\relax % tab mess can go + +\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:\empty }{\let\obeycharacters\relax} +\setvalue{\??tp:\c!option:\v!color }{\setupprettiesintype{\typingparameter\c!option}% + \let\obeycharacters\setupprettytype} +\setvalue{\??tp:\c!option:\v!normal }{\let\obeycharacters\setupgroupedtype} +\setvalue{\??tp:\c!option:\v!slanted }{\let\obeycharacters\setupslantedtype} +\setvalue{\??tp:\c!option:\s!unknown }{\setupprettiesintype{\typingparameter\c!option}% + \let\obeycharacters\setupprettytype} +%setvalue{\??tp:\c!option:\v!commands }{\def\obeycharacters{\setupcommandsintype}} + +\def\dosetverbatimfont + {\redoconvertfont\dosetfontattribute{\currenttypingclass\currenttyping}\c!style + \normalnoligatures\font} + +\unexpanded\def\setupcommonverbatim + {\let\prettyidentifier\s!default + % + \def\prettyidentifierfont{\typingparameter\c!icommand}% + \def\prettyvariablefont {\typingparameter\c!vcommand}% + \def\prettynaturalfont {\typingparameter\c!ccommand}% + % + \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}% + \setupverbatimcolor} + +\newtoks \everyinitializeverbatim + +\def\ignorebeginofpretty [#1]{} +\def\ignoreendofpretty {} + +\def\doverbatimbop{\bgroup\beginofpretty} +\def\doverbatimeop{\endofpretty\egroup} +\def\doverbatimsop{\endofpretty\egroup\bgroup\beginofpretty} + +\let\noverbatimbop\ignorebeginofpretty +\let\noverbatimeop\ignoreendofpretty +\let\noverbatimsop\ignorebeginofpretty + +\def\doinitializeverbatim % todo: combine all in one call is faster + {\ctxlua{buffers.visualizers.reset()}% + \doifelse{\typingparameter\c!space}\v!on + {\let\obs\fastcontrolspace}% + {\let\obs\specialobeyedspace}% + \edef\askedverbatimtab{\typingparameter\c!tab}% + \doifelse\askedverbatimtab\v!no + {\ctxlua{buffers.settablength(1)}} + {\doifnumberelse{\askedverbatimtab} + {\ctxlua{buffers.settablength(\askedverbatimtab)}} + {\ctxlua{buffers.settablength()}}}% + \ctxlua{buffers.doifelsevisualizer("\prettyidentifier")} + {\ctxlua{buffers.setvisualizer("\prettyidentifier")}% + \let\bop\doverbatimbop + \let\eop\doverbatimeop + \let\sop\doverbatimsop}% + {\ctxlua{buffers.setvisualizer("\v!typing")}% or resetdefaultvisualizer + \let\bop\noverbatimbop + \let\eop\noverbatimeop + \let\sop\noverbatimsop}% + \relax\the\everyinitializeverbatim\relax} + +\appendtoks + \resetfontfeature + \resetcharacterspacing +\to \everyinitializeverbatim + +% 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. + +%D \startbuffer +%D \setuptyping[TEX][escape=yes] +%D +%D \startTEX +%D /BTEX\em sometex/ETEX +%D /BTEX\em sometex/ETEX \after +%D \before /BTEX\em sometex/ETEX +%D \before /BTEX\em sometex/ETEX \after +%D \before /BTEX\em sometex/ETEX \inbetween /BTEX\em sometex/ETEX \after +%D \before \after +%D \stopTEX +%D \stopbuffer +%D +%D \typebuffer \start \getbuffer \stop +%D +%D \startbuffer +%D \setuptyping[TEX][escape={[[,]]}] +%D +%D \startTEX +%D [[\em sometex]] +%D [[\em sometex]] \after +%D \before [[\em sometex]] +%D \before [[\em sometex]] \after +%D \before [[\em sometex]] \inbetween [[\em sometex]] \after +%D \before \after +%D \stopTEX +%D \stopbuffer +%D +%D \typebuffer \start \getbuffer \stop +%D +%D \startbuffer +%D \setuptyping[TEX][escape=//] +%D +%D \startTEX +%D //\em sometex +%D \before //\em sometex +%D \stopTEX +%D +%D \typebuffer \start \getbuffer \stop + +\unexpanded\def\setupcommandsintype + {\ctxlua{buffers.set_escape("\currenttyping",\!!bs\typingparameter\c!escape\!!es)}} + +\appendtoks + \setupcommandsintype +\to \everyinitializeverbatim + +\unexpanded\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 + {\dontleavehmode \bgroup + % new, \strut enables leading space in \type { abc } at par start / begstrut + % else no hyphenation (replaced by \dontleavehmode which saves unboxing) + % \begstrut + \let\currenttypingclass\??ty + \edef\currenttyping{#1}% + \catcode`\<=\@@other + \catcode`\>=\@@other + \futurelet\next\dodotype} + +\def\dodotype + {\ifx\next\bgroup + \@EA\dodotypeA + \else + \@EA\dodotypeAD + \fi} + +\def\dodotypeAD + {\if\next<% + \doifelse{\typingparameter\c!option}\v!none{\@EA\dodotypeB}{\@EA\dodotypeC}% + \else + \@EA\dodotypeD + \fi} + +\def\dodotypeA + {\initializetype % probably too much + \verbatimcolor + \dosetverbatimfont + \setcatcodetable \typcatcodesa + \dodotypeAA} + +\def\dodotypeAA#1% + {\doinitializeverbatim + \def\obs{\obeyedspace}% + \ctxlua{buffers.hooks.flush_inline(\!!bs\detokenize{#1}\!!es)}% + \egroup} + +\def\dodotypeB#1% + {\initializetype + \verbatimcolor + \dosetverbatimfont + \setcatcodetable \typcatcodesb + \dodotypeBB} + +\def\dodotypeBB#1% + {\doinitializeverbatim + \ctxlua{buffers.visualizers.flush_nested(\!!bs\detokenize{#1}\!!es,false)}% + \egroup + \gobbleoneargument} % grab last > + +\def\dodotypeC#1% + {\initializetype + \verbatimcolor + \dosetverbatimfont + \setcatcodetable \typcatcodesb + \dodotypeCC} + +\def\dodotypeCC#1% + {\doinitializeverbatim + \ifx\obeycharacters\setupprettytype % temp hack, we need a proper signal + \ctxlua{buffers.hooks.flush_inline([\!!bs\detokenize{#1}\!!es,true)}% + \else + \def\obs{\obeyedspace}% + \ctxlua{buffers.visualizers.flush_nested(\!!bs\detokenize{#1}\!!es,true)}% + \fi + \egroup + \gobbleoneargument} % grab last > + +\def\dodotypeD#1% + {\initializetype + \verbatimcolor + \dosetverbatimfont + \setcatcodetable \typcatcodesa + \def\dodotypeDD##1#1{\dodotypeAA{##1}}% + \dodotypeDD} + +\def\dodotypeDD#1% + {\doinitializeverbatim + \ctxlua{buffers.hooks.flush_inline(\!!bs\detokenize{#1}\!!es,true)}% + \egroup + \gobbleoneargument} % grab last > + +%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 + %\dosetverbatimfont + %\setverbatimspaceskip + %\setupcopyverbatim % not needed + \setcatcodetable\vrbcatcodes} + +%D \macros +%D {setuptype} +%D +%D Some characteristics of \type{\type} can be set up by: + +\unexpanded\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\specialobeyedspace {\hskip\interwordspace\relax} % better than spaceskip +\def\specialcontrolspace{\hskip\zeropoint\hbox{\normalcontrolspace}\hskip\zeropoint\relax} + +\def\obeyhyphens + {\let\obeyedspace \specialobeyedspace + \let\controlspace\specialcontrolspace + \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 + \let\obeyedspace \specialobeyedspace + \let\controlspace\specialcontrolspace + \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 + \dosetverbatimfont + %\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\$\$}{\$\$}} + +\let\normaltexttex\tex +\let\normaltextarg\arg +\let\normaltextmat\mat +\let\normaltextdis\dis + +\def\astype + {\groupedcommand\dorawtype\relax} + +\def\dorawtype + {\let\currenttypingclass\??ty + \normalverbatimcolor % \verbatimcolor + \dosetverbatimfont} + +%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% + {\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}} + +\setvalue{\??tp:\c!blank:\v!standard}{\ctxparskip} +\setvalue{\??tp:\c!blank:\v!small }{\smallskipamount} +\setvalue{\??tp:\c!blank:\v!medium }{\medskipamount} +\setvalue{\??tp:\c!blank:\v!big }{\bigskipamount} +\setvalue{\??tp:\c!blank:\v!halfline}{.5\baselineskip} +\setvalue{\??tp:\c!blank:\v!line }{\baselineskip} +\setvalue{\??tp:\c!blank:\v!none }{\zeropoint} + +\def\doopenupverbatimlineindeed + {\getpagestatus + \ifrightpage + \hskip\typingparameter\c!oddmargin\relax + \else + \hskip\typingparameter\c!evenmargin\relax + \fi} + +\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 + \let\doopenupverbatimline\doopenupverbatimlineindeed + \else + \doadaptleftskip{\typingparameter\c!margin}% + \fi + % no symbolic blanks ! + \edef\!!stringa{\executeifdefined{\??bo\typingparameter\c!blank}{\typingparameter\c!blank}}% + \scratchskip\executeifdefined{\??tp:\c!blank:\!!stringa}\!!stringa\relax + \ifgridsnapping + % this will be adapted + \ifdim\scratchskip=.5\baselineskip\relax + \edef\verbatimbaselineskip{\the\scratchskip}% new + \else + \edef\verbatimbaselineskip{\the\baselineskip}% + \fi + \else + \edef\verbatimbaselineskip{\the\scratchskip}% + \fi +\doifsomething{\typingparameter\c!align}{\setupalign[\typingparameter\c!align]}% + \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. + +\newif\ifoptimizeverbatim \optimizeverbatimtrue + +\let \beginofverbatimlines \relax +\let \endofverbatimlines \relax + +\def\doverbatimnobreak + {\ifoptimizeverbatim\penalty500 \fi} + +\def\doverbatimgoodbreak + {\ifoptimizeverbatim\penalty\linepenalty\fi} + +% \def\doflushverbatimline +% {\expandafter\dodoverbatimline\expandafter{\savedverbatimline}} +% \def\doverbatimbeginofline#1% linenumber (optional provided by mkiv / todo) +% {\dontleavehmode +% \strut +% \the\everyline} +% \def\doverbatimendofline +% {\par} +% \def\doverbatimemptyline +% {\strut +% \par} +% \let\handleverbatimline=\relax + +% 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\dotypefileverbatim + {\doinitializeverbatim + \beginofverbatimlines + \ctxlua{buffers.typefile("\readfilename","\typingparameter\c!strip","\typingparameter\c!range")}% + \endofverbatimlines} + +\def\dotypefilelinesverbatim#1#2% + {#1\dotypefileverbatim#2} + +\unexpanded\def\dotypeblockverbatim#1#2% + {\dowithbuffer{_typing_}{#1}{#2} + {} + {\doinitializeverbatim + \beginofverbatimlines + \ctxlua{buffers.type("_typing_","\typingparameter\c!strip","\typingparameter\c!range")}% + \endofverbatimlines + \csname#2\endcsname}} + +\def\dododostarttyping[#1]% + {\typingparameter\c!before + \startpacked % includes \bgroup + \dosetuptypelinenumbering{#1}% + \initializetyping + \dosetverbatimfont + \startverbatimcolor + \normalexpanded{\dotypeblockverbatim{\e!start\currenttyping}{\e!stop\currenttyping}}} % was s!start + +\def\dostoptyping#1% hm, currenttyping + {\stopverbatimcolor + \stoppacked % includes \egroup + \typingparameter\c!after + \normalexpanded{\egroup\checknextindentation[\typingparameter\c!indentnext]}% + \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[start=continue] +%D ... +%D ... +%D \stopcode +%D +%D \startcode[start=10] +%D ... +%D \stopcode +%D \stoptyping + +%D Ranges: +%D +%D \starttyping +%D % label:start:one +%D +%D \def\MyMacro +%D {just an example} +%D +%D % label:stop:one +%D +%D \starttext +%D +%D % \typefile[file][range={3,6}]{whatever.tex} +%D +%D % \typefile[file][range={3,+2}]{whatever.tex} +%D +%D \typefile[file][range={label:start:one,label:stop:one}]{whatever.tex} +%D +%D \stoptext +%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} + +\unexpanded\def\setuptyping + {\dodoubleempty\dosetuptyping} + +%D \macros +%D {definetype} +%D +%D Specific inline verbatim commands can be defined with the +%D following command. + +\unexpanded\def\definetype + {\dodoubleempty\dodefinetype} + +\def\dodefinetype[#1][#2]% + {\setuvalue{#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. + +% TODO: parent etc ! + +\def\presettyping[#1][#2]% brrr also use parent here + {\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]} + +\unexpanded\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 \unexpanded\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\normalbeginofpretty [#1]{\startcolor[\prettypalet:#1]}% +\def\normalendofpretty {\stopcolor} +\def\normalstartverbatimcolor{\startcolor[\typingparameter\c!color]}% +\def\normalstopverbatimcolor {\stopcolor} +\def\normalverbatimcolor {\getvalue{\typingparameter\c!color}}% command ! + +\unexpanded\def\setupnormalprettyverbatim + {\edef\prettypalet{\prettyidentifier\prettypalet}% + \let\beginofpretty \normalbeginofpretty + \let\endofpretty \normalendofpretty + \let\startverbatimcolor\normalstartverbatimcolor + \let\stopverbatimcolor \normalstopverbatimcolor + \let\verbatimcolor \normalverbatimcolor} + +\unexpanded\def\setupignoreprettyverbatim + {\let\prettypalet \empty + \let\beginofpretty \ignorebeginofpretty + \let\endofpretty \ignoreendofpretty + \let\startverbatimcolor\normalstartverbatimcolor + \let\stopverbatimcolor \normalstopverbatimcolor + \let\verbatimcolor \normalverbatimcolor} + +\unexpanded\def\setupverbatimcolor + {\edef\prettypalet{\typingparameter\c!palet}% + \ifx\prettypalet\empty + \setupignoreprettyverbatim + \else + \setupnormalprettyverbatim + \fi} + +\let\beginofpretty \ignorebeginofpretty +\let\endofpretty \ignoreendofpretty +\let\prettypalet \empty +\let\startverbatimcolor\relax +\let\stopverbatimcolor \relax +\let\verbatimcolor \relax + +%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 + {%\ifcsname\currenttypingclass\currenttyping\c!start\endcsname \else + % \setuptyping[\currenttyping][\c!start=1,\c!stop=,\c!step=1,\c!continue=\v!no,\c!nlines=]% + %\fi + \doifassignmentelse{#1}{\setuptyping[\currenttyping][#1]}\donothing + \doifelse{\typingparameter\c!numbering}\v!file + {% kind of special: filters lines ! + \setuplinenumbering[\currenttyping][\c!method=\v!file]% + \donetrue} + {\doifelse{\typingparameter\c!numbering}\v!line + {\doifinset\v!continue{#1}{\setuptyping[\currenttyping][\c!continue=\v!yes]}% fails: \settypingparameter\c!continue{\v!yes} + \donetrue} + {\donefalse}}% + \ifdone + \edef\beginofverbatimlines{\noexpand\startlinenumbering + [\currenttyping]% + [\c!continue=\typingparameter\c!continue, + \c!method=\v!type, + \c!start=\typingparameter\c!start, + \c!stop=\typingparameter\c!stop, % ? + \c!step=\typingparameter\c!step]% + }% + \def\endofverbatimlines{\stoplinenumbering}% + \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 + \dosetverbatimfont + \startverbatimcolor + \scratchcounter + \ifcsname\currenttypingclass#3\v!global\c!start\endcsname + \numexpr\csname\currenttypingclass#3\v!global\c!start\endcsname+\plusone\relax + \else + \plusone + \fi + \setxvalue{\currenttypingclass#3\v!global\c!start}{\the\scratchcounter}% no direct setxvalue as it defines beforehand + \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 + {\def\readfilename{#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 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=, % yes | no | START,STOP BTEX,ETEX + \c!numbering=\v!no, + \c!lines=, + \c!range=, + \c!empty=, + \c!start=1, + \c!stop=, + \c!step=1, + \c!continue=, + \c!strip=\v!no, % auto or number + \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] + +%D Beware: only a few are currently (re)implemented in \MKIV. + +\definetyping[RAW] [\c!option=RAW] +\definetyping[MP] [\c!option=MP] % done +\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] % done +\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] % done + +\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] + +%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) + +% \let\beginverbatimline\relax +% \let\endverbatimline \relax + +% \appendtoks whatever\par\to\everyverbatimbeginofdisplay +% \appendtoks whatever\to\everyverbatimendofdisplay +% \appendtoks [\to\everyverbatimbeginofinline +% \appendtoks ]\to\everyverbatimendofinline + +\let\doopenupverbatimline\empty + +\newtoks\everyverbatimbeginofdisplay +\newtoks\everyverbatimendofdisplay +\newtoks\everyverbatimbeginofinline +\newtoks\everyverbatimendofinline + +\let\currentverbatimpretty\empty + +\def\doverbatimbeginofdisplay#1% + {\edef\currentverbatimpretty{#1}% + \the\everyverbatimbeginofdisplay} + +\def\doverbatimendofdisplay + {\the\everyverbatimendofdisplay} + +\def\doverbatimbeginofinline#1% + {\edef\currentverbatimpretty{#1}% + \the\everyverbatimbeginofinline} + +\def\doverbatimendofinline + {\the\everyverbatimendofinline} + +\def\doverbatimbeginofline#1% linenumber + {\bgroup % due to pretty status + \iflinepar\else\EveryPar{}\fi + \noindent % was wrong: \dontleavehmode + \xdef\dokeepverbatimlinedata % hm, still needed? + {\parindent \the\parindent + \hangindent\the\hangindent + \hangafter \the\hangafter + \leftskip \the\leftskip + \rightskip \the\rightskip}% + \egroup + \dokeepverbatimlinedata + \doopenupverbatimline + \the\everyline\strut + }%\beginverbatimline} + +\def\doverbatimendofline + {%\endverbatimline + \global\lineparfalse + \obeyedline\par} + +\def\doverbatimemptyline + {\strut + \par + \global\linepartrue} + +\protect \endinput diff --git a/tex/context/base/bxml-apa.mkiv b/tex/context/base/bxml-apa.mkiv new file mode 100644 index 000000000..5fc87e5ef --- /dev/null +++ b/tex/context/base/bxml-apa.mkiv @@ -0,0 +1,613 @@ +%D \module +%D [ file=bxml-apa, +%D version=2010.05.14, % based on bibl-apa.tex +%D title=APA bibliography style, +%D subtitle=Publications, +%D author={Taco Hoekwater \& Hans Hagen}, +%D date=\currentdate, +%D copyright={Hans Hagen \& Taco Hoekwater}] +%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 + +% helpers (todo) + +\let\maybeyear\firstofoneargument +\let\etalchar \firstofoneargument + +\setupbibtexcitationvariants + [author,year] + [\c!andtext={ and }, + \c!otherstext={ et al.}, + \c!pubsep={, }, + \c!lastpubsep={ and }, + \c!compress=\v!no, + \c!inbetween={ }, + \c!left={(}, + \c!right={)}] + +\setupbibtexcitationvariants + [authoryear] + [\c!andtext={ and }, + \c!otherstext={ et al.}, + \c!pubsep={, }, + \c!lastpubsep={ and }, + \c!compress=\v!yes, + \c!inbetween={ }, + \c!left={(}, + \c!right={)}] + +\setupbibtexcitationvariants + [authoryears] + [\c!andtext={ and }, + \c!otherstext={ et al.}, + \c!pubsep={, }, + \c!lastpubsep={ and }, + \c!compress=\v!yes, + \c!inbetween={, }, + \c!left={(}, + \c!right={)}] + +\setupbibtexcitationvariants + [key,serial,authornum,page,short,type,doi,url] + [\c!andtext={ and }, + \c!otherstext={ et al.}, + \c!pubsep={, }, + \c!lastpubsep={ and }, + \c!compress=\v!no, + \c!inbetween={ }, + \c!left={[}, + \c!right={]}] + +\setupbibtexcitationvariants + [num] + [\c!andtext={ and }, + \c!otherstext={ et al.}, + \c!pubsep={, }, + \c!lastpubsep={ and }, + \c!compress=\v!yes, + \c!inbetween={--}, + \c!left={[}, + \c!right={]}] + +\setupbibtexpublications + [\c!sorttype=, + \c!criterium=, + \c!refcommand=authoryears, + \c!numbering=\v!no, + \c!autohang=\v!no] + +\setupbibtexpublications + [\c!width=2em, % 24pt, + \c!artauthor=invertedshort, + \c!editor=invertedshort, + \c!author=invertedshort, + \c!namesep={, }, + \c!lastnamesep={ and }, + \c!finalnamesep={ and }, + \c!firstnamesep={, }, + \c!juniorsep={ }, + \c!vonsep={ }, + \c!surnamesep={, }, + \c!authoretallimit=5, + \c!editoretallimit=5, + \c!artauthoretallimit=5, + \c!authoretaldisplay=5, + \c!editoretaldisplay=5, + \c!artauthoretaldisplay=5, + \c!authoretaltext={ et al.}, + \c!editoretaltext={ et al.}, + \c!artauthoretaltext={ et al.}] + +% common + +\startxmlsetups bibtex:apa:common:wherefrom + \bibxmldoifelse {address} { + \getvariable{bibtex:temp}{left} + \bibxmldoifelse {country} { + \bibxmldoifelse {\getvariable{bibtex:temp}{label}} { + \bibxmlflush{address}\bibtexcomma\bibxmlflush{country}: \bibxmlflush{\getvariable{bibtex:temp}{label}} + } { + \bibxmlflush{address}\bibtexcomma\bibxmlflush{country} + } + } { + \bibxmldoifelse {\getvariable{bibtex:temp}{label}} { + \bibxmlflush{address}\bibtexcomma\bibxmlflush{\getvariable{bibtex:temp}{label}} + } { + \bibxmlflush{address} + } + } + \getvariable{bibtex:temp}{right} + } { + \bibxmldoifelse {country} { + \getvariable{bibtex:temp}{left} + \bibxmldoifelse {\getvariable{bibtex:temp}{label}} { + \bibxmlflush{country}: \bibxmlflush{\getvariable{bibtex:temp}{label}} + } { + \bibxmlflush{country} + } + \getvariable{bibtex:temp}{right} + } { + \bibxmldoifelse {\getvariable{bibtex:temp}{label}} { + \getvariable{bibtex:temp}{left} + \bibxmlflush{\getvariable{bibtex:temp}{label}} + \getvariable{bibtex:temp}{right} + } { + \getvariable{bibtex:temp}{otherwise} + } + } + } +\stopxmlsetups + +\startxmlsetups bibtex:apa:common:publisher + \setvariables[bibtex:temp][label=publisher,left=,right=,otherwise=]\relax + \bibxmlsetup{bibtex:apa:common:wherefrom} +\stopxmlsetups +\startxmlsetups bibtex:apa:common:organization + \setvariables[bibtex:temp][label=organization,left=,right=,otherwise=]\relax + \bibxmlsetup{bibtex:apa:common:wherefrom} +\stopxmlsetups +\startxmlsetups bibtex:apa:common:school + \setvariables[bibtex:temp][label=school,left=,right=,otherwise=]\relax + \bibxmlsetup{bibtex:apa:common:wherefrom} +\stopxmlsetups +\startxmlsetups bibtex:apa:common:institution + \setvariables[bibtex:temp][label=institution,left=,right=,otherwise=]\relax + \bibxmlsetup{bibtex:apa:common:wherefrom} +\stopxmlsetups + +\startxmlsetups bibtex:apa:common:school:subsentence + \setvariables[bibtex:temp][label=school,left=\bibtexcomma,right=\bibtexperiod,otherwise=\bibtexperiod]\relax + \bibxmlsetup{bibtex:apa:common:wherefrom} +\stopxmlsetups +\startxmlsetups bibtex:apa:common:institution:subsentence + \setvariables[bibtex:temp][label=institution,left=\bibtexcomma,right=\bibtexperiod,otherwise=\bibtexperiod]\relax + \bibxmlsetup{bibtex:apa:common:wherefrom} +\stopxmlsetups +\startxmlsetups bibtex:apa:common:publisher:sentence + \setvariables[bibtex:temp][label=publisher,left=\bibtexspace,right=\bibtexperiod,otherwise=]\relax + \bibxmlsetup{bibtex:apa:common:wherefrom} +\stopxmlsetups +\startxmlsetups bibtex:apa:common:organization:sentence + \setvariables[bibtex:temp][label=organization,left=\bibtexspace,right=\bibtexperiod,otherwise=]\relax + \bibxmlsetup{bibtex:apa:common:wherefrom} +\stopxmlsetups + +\startxmlsetups bibtex:apa:common:title-and-series + \bibxmldoif {title} { + \bibxmlflush{title} + \bibxmldoif {series} { + \bibtexlparent\bibxmlflush{series}\bibtexrparent + } + \bibtexperiod + } +\stopxmlsetups + +\startxmlsetups bibtex:apa:common:title-it-and-series + \bibxmldoif {title} { + \bgroup\it\bibxmlflush{title}\/\egroup + \bibxmldoif {series} { + \bibtexlparent\bibxmlflush{series}\bibtexrparent + } + \bibtexperiod + } +\stopxmlsetups + +\disablemode[bibtex:apa:edited-book] + +\startxmlsetups bibtex:apa:common:author-and-year + \bibxmldoif {author} { + \bibxmlsetup{bibtex:format:author} + } + \bibxmldoif {year} { + \bibtexlparent\bibxmlflush{year}\bibtexrparent + } + \bibtexperiod +\stopxmlsetups + +\startxmlsetups bibtex:apa:common:author-or-key-and-year + \bibxmldoifelse {author} { + \bibxmlsetup{bibtex:format:author} + } { + \bibxmldoif {key} { + \bibtexlbracket\bibxmlsetup{bibtex:format:key}\bibtexrbracket + } + } + \bibxmldoif {year} { + \bibtexlparent\bibxmlflush{year}\bibtexrparent + } + \bibtexperiod +\stopxmlsetups + +\startxmlsetups bibtex:apa:common:author-editors-crossref-year + \bibxmldoif {author} { + \bibxmlsetup{bibtex:format:author} + } { + \bibxmldoifelse {editor} { + \enablemode[bibtex:apa:edited-book] + \xmlsetup{#1}{bibtex:format:editor} + \bibtexcomma\bibtexsingularplural{editor}{editors} + } { + % weird period + \bibxmldoif {crossref} { + \bibtexlbracket\bibxmlsetup{bibtex:format:crossref}\bibtexrbracket\bibtexperiod + } + } + } + \bibxmldoif {year} { + \bibtexlparent\bibxmlflush{year}\bibtexrparent + } + \bibtexperiod +\stopxmlsetups + +\startxmlsetups bibtex:apa:common:editor-or-key-and-year + \bibxmldoifelse {editor} { + \enablemode[bibtex:apa:edited-book] + \xmlsetup{#1}{bibtex:format:editor} + \bibtexcomma\bibtexsingularplural{editor}{editors} + } { + \bibxmldoif {key} { + \bibtexlbracket\bibxmlsetup{bibtex:format:key}\bibtexrbracket + } + } + \bibtexspace + \bibxmldoif {year} { + \bibtexlparent\bibxmlflush{year}\bibtexrparent + } + \bibtexperiod +\stopxmlsetups + +\startxmlsetups bibtex:apa:common:note + \bibxmldoif {note} { + \bibtexspace\bibxmlflush{note}\bibtexperiod + } +\stopxmlsetups + +\startxmlsetups bibtex:apa:common:comment + \bibxmldoif {comment} { + \bibtexspace\bibxmlflush{comment}\bibtexperiod + } +\stopxmlsetups + +\startxmlsetups bibtex:apa:common:pages:p + \bibxmldoif {pages} { + \bibtexspace\bibxmlflush{pages}\bibtexspace p\bibtexperiod + } +\stopxmlsetups + +\startxmlsetups bibtex:apa:common:pages:pp + \bibxmldoif {pages} { + \bibtexspace\bibxmlflush{pages}\bibtexspace pp\bibtexperiod + } +\stopxmlsetups + +\startxmlsetups bibtex:apa:common:pages:pages + \bibxmldoif {pages} { + \bibtexcomma pages~\bibxmlflush{pages} + } +\stopxmlsetups + +\startxmlsetups bibtex:apa:common:edition:sentense + \bibxmldoif {edition} { + \bibtexspace\bibxmlflush{edition}\bibtexspace edition\bibtexperiod + } +\stopxmlsetups + +% check ewhen the next is used (no period) + +% \startxmlsetups bibtex:apa:common:edition +% \bibxmldoif {edition} { +% \bibtexspace\bibxmlflush{edition}\bibtexspace edition +% } +% \stopxmlsetups + +% we can share more, todo + +% specific + +\startxmlsetups bibtex:apa:article + \bibxmlsetup{bibtex:apa:common:author-or-key-and-year} + \bibxmldoif {title} { + \bibxmlflush{title}\bibtexperiod + } + \bibxmldoifelse {journal} { + \bgroup\it\bibxmlflush{journal}\/\egroup + } { + \bibxmldoif {crossref} { + In\bibtexspace\bibxmlflush{crossref} + } + } + \bibxmldoifelse {volume} { + \bibtexcomma\bgroup\it\bibxmlflush{volume}\/\egroup + \bibxmldoif {issue} { + \bibtexlparent\bibxmlflush{issue}\bibtexlparent + } + \bibxmldoif {pages} { + \bibtexcomma\bibxmlflush{pages} + } + \bibtexperiod + } { + \bibxmlsetup{bibtex:apa:common:pages:pp} + } + \bibxmlsetup{bibtex:apa:common:note} + \bibxmlsetup{bibtex:apa:common:comment} +\stopxmlsetups + +\startxmlsetups bibtex:apa:book + \bibxmlsetup{bibtex:apa:common:author-editors-crossref-year} + \bibxmldoif {title} { + \bgroup\it\bibxmlflush{title}\/\egroup + \doifmodeelse {bibtex:apa:edited-book} { + \bibxmldoifelse {volume} { + \bibtexspace Number\nonbreakablespace\bibxmlflush{volume} + \bibxmldoifelse {series} { + \bibtexspace in\nonbreakablespace\bibxmlflush{series}\bibtexperiod + } { + \bibxmldoifelse {crossref} { + \bibtexspace in\bibtexlbracket\bibxmlsetup{bibtex:format:crossref}\bibtexrbracket + } { + \bibtexperiod + } + } + } { + \bibxmldoif {series} { + \bibtexspace\bibxmlflush{series} + } + \bibtexperiod + } + } { + \bibxmldoifelse {crossref} { + \bibxmldoif {chapter} { + \bibtexcomma\bibxmlflush{chapter} + } + \bibxmlsetup{bibtex:apa:common:pages:pages} + \bibtexperiod + \bibxmldoif {volume} { + Volume\nonbreakablespace\bibxmlflush{volume}\bibtexspace of\nonbreakablespace + } + } { + \bibxmldoif {volume} { + \bibtexcomma volume\nonbreakablespace\bibxmlflush{volume} + \bibxmldoif {series} { + \bibtexspace of\nonbreakablespace\bgroup\it\bibxmlflush{series}\/\egroup + } + \bibxmldoif {chapter} { + \bibtexcomma\bibxmlflush{chapter} + } + \bibxmlsetup{bibtex:apa:common:pages:pages} + \bibtexperiod + } + } + } + } + \bibxmlsetup{bibtex:apa:common:edition:sentence} + \bibxmlsetup{bibtex:apa:common:publisher:sentence} + \bibxmlsetup{bibtex:apa:common:pages:p}% twice? + \bibxmlsetup{bibtex:apa:common:note} +\stopxmlsetups + +\startxmlsetups bibtex:apa:inbook + \bibxmlsetup{bibtex:apa:common:author-editors-crossref-year} + \bibxmldoifelse {title} { + \bgroup\it\bibxmlflush{title}\/\egroup + } { + \doifmodeelse {bibtex:apa:edited-book} { + \bibxmldoifelse {volume} { + \bibtexspace number\nonbreakablespace\bibxmlflush{volume} + \bibxmldoifelse {series} { + \bibtexspace in\nonbreakablespace\bibxmlflush{series}\bibtexperiod + } { + \bibxmldoifelse {crossref} { + \bibtexspace in\bibtexlbracket\bibxmlsetup{bibtex:format:crossref}\bibtexrbracket + } { + \bibtexperiod + } + } + } { + \bibxmldoif {series} { + \bibtexspace\bibxmlflush{series}\bibtexperiod + } + } + } { + \bibxmldoifelse {crossref} { + \bibxmldoif {chapter} { + \bibtexcomma\bibxmlflush{chapter} + } + \bibxmlsetup{bibtex:apa:common:pages:pages} + \bibxmldoif {volume} { + Volume\nonbreakablespace\bibxmlflush{volume}\bibtexspace of\nonbreakablespace + } + \bibxmldoif {crossref} { + \bibtexlbracket\bibxmlsetup{bibtex:format:crossref}\bibtexrbracket + } + } { + \bibxmldoif {volume} { + \bibtexcomma volume\nonbreakablespace\bibxmlflush{volume} + \bibxmldoif {series} { + \bibtexspace of\nonbreakablespace\bgroup\it\bibxmlflush{series}\/\egroup + } + \bibxmldoif {chapter} { + \bibtexcomma\bibxmlflush{chapter} + } + \bibxmlsetup{bibtex:apa:common:pages:pages} + \bibtexperiod + } + } + } + } + \bibtexspace + \bibxmlsetup{bibtex:apa:common:edition:sentence} + \bibxmlsetup{bibtex:apa:common:publisher} + \bibxmlsetup{bibtex:apa:common:note} +\stopxmlsetups + +\startxmlsetups bibtex:apa:booklet + \bibxmlsetup{bibtex:apa:common:author-or-key-and-year} + \bibxmlsetup{bibtex:apa:common:title-it-and-series} + \bibxmlsetup{bibtex:apa:common:edition:sentence} + \bibxmlsetup{bibtex:apa:common:publication:sentence} + \bibxmlsetup{bibtex:apa:common:pages:p} + \bibxmlsetup{bibtex:apa:common:note} +\stopxmlsetups + +\startxmlsetups bibtex:apa:manual + \bibxmlsetup{bibtex:apa:common:author-or-key-and-year} + \bibxmlsetup{bibtex:apa:common:title-it-and-series} + \bibxmlsetup{bibtex:apa:common:edition:sentence} + \bibxmlsetup{bibtex:apa:common:organization:sentence} + \bibxmlsetup{bibtex:apa:common:pages:p} + \bibxmlsetup{bibtex:apa:common:note} +\stopxmlsetups + +\startxmlsetups bibtex:apa:incollection + \bibxmlsetup{bibtex:apa:common:author-and-year} + \bibxmldoif {arttitle} { + \bibxmlflush{arttitle}\bibtexperiod + } + In\bibtexspace + \bibxmldoifelse {title} { + \bibxmlsetup{bibtex:format:editors}\bibtexcomma + \bgroup\it\bibxmlflush{title}\/\egroup + \bibxmldoif {series} { + \bibxmldoif {volume} { + \bibtexcomma number\bibtexspace\bibxmlflush{volume}\bibtexspace in + } + \bibtexspace\bibxmlflush{series} + } + \bibxmldoif {chapter} { + \bibtexcomma\bibxmlflush{chapter}\bibtexspace + } + \bibxmlsetup{bibtex:apa:common:pages:pages} + \bibxmldoif {edition} { + \bibtexspace\bibxmlflush{edition}\bibtexspace edition + } + \bibxmlsetup{bibtex:apa:common:publisher:sentence} + } { + \bibxmldoif {crossref} { + \bibtexlbracket\bibxmlsetup{bibtex:format:crossref}\bibtexrbracket + } + \bibxmldoif {chapter} { + \bibtexcomma\bibxmlflush{chapter} + } + \bibtexspace + \bibxmlsetup{bibtex:apa:common:pages:pages} + } + \bibxmlsetup{bibtex:apa:common:note} +\stopxmlsetups + +\startxmlsetups bibtex:apa:inproceedings + \bibxmlsetup{bibtex:apa:common:author-and-year} + \bibxmldoif {arttitle} { + \bibxmlflush{arttitle}\bibtexperiod + } + In\bibtexspace + \bibxmldoifelse {title} { + \bibxmldoif {editors} { + \bibxmlflush{bibtex:apa:format:editors} + \bibtexcomma\bibtexsingularplural{editor}{editors}\bibtexcomma + } + \bgroup\it\bibxmlflush{title}\/\egroup + \bibxmldoif {series} { + \bibxmldoif {volume} { + \bibtexcomma number~\bibxmlflush{volume} in + } + \bibtexspace + \bibxmlflush{series} + } + \bibxmldoif {chapter} { + \bibtexcomma\bibxmlflush{chapter}\bibtexspace + } + \bibxmlsetup{bibtex:apa:common:pages:pages} + \bibtexperiod + \bibxmlsetup{bibtex:apa:common:organization:sentence} + } { + \bibxmldoif {crossref} { + \bibtexlbracket\bibxmlsetup{bibtex:format:crossref}\bibtexrbracket + } + \bibxmldoif {chapter} { + \bibtexcomma\bibxmlflush{chapter}\bibtexspace + } + \bibxmlsetup{bibtex:apa:common:pages:pages} + \bibtexperiod + } + \bibxmlsetup{bibtex:apa:common:note} +\stopxmlsetups + +\startxmlsetups bibtex:apa:proceedings + \bibxmlsetup{bibtex:apa:common:editor-or-key-and-year} + \bibxmldoif {title} { + \bgroup\it\bibxmlflush{title}\/\egroup + \bibxmldoif {volume} { + \bibtexcomma number\bibtexspace\bibxmlflush{volume}\bibtexspace in\bibtexspace + } + \bibxmldoif {chapter} { + \bibtexcomma\bibxmlflush{chapter}\bibtexspace + } + \bibxmlsetup{bibtex:apa:common:pages:pages} + \bibtexperiod + \bibxmlsetup{bibtex:apa:common:organization:sentence} + } + \bibxmlsetup{bibtex:apa:common:note} +\stopxmlsetups + +\startxmlsetups bibtex:apa:common:thesis + \bibxmlsetup{bibtex:apa:common:author-and-year} + \bibxmlsetup{bibtex:apa:common:title-it-and-series} + \bibxmldoifelse {type} { + \bibxmlflush{type} + } { + \getvariable{bibtex:temp}{label} + } + \bibxmlsetup{bibtex:apa:common:school:subsentence} + \bibxmlsetup{bibtex:apa:common:pages:p} + \bibxmlsetup{bibtex:apa:common:note} +\stopxmlsetups + +\startxmlsetups bibtex:apa:mastersthesis + \setvariables[bibtex:temp][label=Master's thesis] + \bibxmlsetup{bibtex:apa:common:thesis} +\stopxmlsetups + +\startxmlsetups bibtex:apa:phdthesis + \setvariables[bibtex:temp][label=PhD thesis] + \bibxmlsetup{bibtex:apa:common:thesis} +\stopxmlsetups + +\startxmlsetups bibtex:apa:techreport + \bibxmlsetup{bibtex:apa:common:author-and-year} + \bibxmlsetup{bibtex:apa:common:title-and-series} + \bibxmldoifelse {type} { + \bibxmlflush{type} + \bibxmldoif {volume} { + \bibtexspace\bibxmlflush{volume} + } + } { + \bibtexspace Technical Report + } + \bibxmlsetup{bibtex:apa:common:institution:subsentence} + \bibxmlsetup{bibtex:apa:common:pages:p} + \bibxmlsetup{bibtex:apa:common:note} +\stopxmlsetups + +\startxmlsetups bibtex:apa:misc + \bibxmlsetup{bibtex:apa:common:author-and-year} + \bibxmlsetup{bibtex:apa:common:title-and-series} + \bibxmlsetup{bibtex:apa:common:publisher:sentence} + \bibxmlsetup{bibtex:apa:common:pages:p} + \bibxmlsetup{bibtex:apa:common:note} +\stopxmlsetups + +\startxmlsetups bibtex:apa:unpublished + \bibxmlsetup{bibtex:apa:common:author-and-year} + \bibxmlsetup{bibtex:apa:common:title-and-series} + \bibxmlsetup{bibtex:apa:common:pages:p} + \bibxmldoif {type} { + \bibtexlparent\bibxmlflush{type}\bibtexrparent + } + \bibxmlsetup{bibtex:apa:common:note} +\stopxmlsetups + +\protect \endinput diff --git a/tex/context/base/catc-act.tex b/tex/context/base/catc-act.tex new file mode 100644 index 000000000..bc24562d7 --- /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\activecatcode + \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\activehackcode\activecatcode + \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..21e7d0136 --- /dev/null +++ b/tex/context/base/catc-ctx.tex @@ -0,0 +1,250 @@ +%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. + +\ifdefined \ctxcatcodes \else \newcatcodetable \ctxcatcodes \fi +\ifdefined \mthcatcodes \else \newcatcodetable \mthcatcodes \fi % math, not used, too tricky +\ifdefined \xmlcatcodesn \else \newcatcodetable \xmlcatcodesn \fi % normal +\ifdefined \xmlcatcodese \else \newcatcodetable \xmlcatcodese \fi % entitle +\ifdefined \xmlcatcodesr \else \newcatcodetable \xmlcatcodesr \fi % reduce +\ifdefined \typcatcodesa \else \newcatcodetable \typcatcodesa \fi % { } +\ifdefined \typcatcodesb \else \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 % beware, in mkiv we use \notcatcodes + +\endinput + +% under consideration: +% +% \newcatcodetable\txtcatcodes +% +% \startcatcodetable \txtcatcodes +% \catcode`\^^I = 10 +% \catcode`\^^M = 5 +% \catcode`\^^L = 5 +% \catcode`\ = 10 +% \catcode`\\ = 0 +% \catcode`\{ = 1 +% \catcode`\} = 2 +% \stopcatcodetable +% +% \newcount\relaxedcatcodedepth +% +% \def\startrelaxedcatcodes +% {\global\chardef\relaxedcatcodeparent\catcodetable +% \global\advance\relaxedcatcodedepth\plusone +% \nonknuthmode\setcatcodetable\txtcatcodes} +% +% \def\stoprelaxedcatcodes +% {\ifcase\relaxedcatcodedepth +% % error +% \or +% \setcatcodetable\relaxedcatcodeparent +% \global\relaxedcatcodedepth\zerocount +% \else +% \global\advance\relaxedcatcodedepth\minusone +% \setcatcodetable\txtcatcodes +% \fi} +% +% \starttext +% +% \startrelaxedcatcodes +% \startcomment test \stopcomment +% test $ test 10% whatever|test \mathematics{x^2=1} +% \stoprelaxedcatcodes +% +% $x^2=1$ +% +% \stoptext diff --git a/tex/context/base/catc-def.tex b/tex/context/base/catc-def.tex new file mode 100644 index 000000000..e80cfe125 --- /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. + +\ifdefined\nilcatcodes \else \newcatcodetable \nilcatcodes \fi +\ifdefined\texcatcodes \else \newcatcodetable \texcatcodes \fi +\ifdefined\luacatcodes \else \newcatcodetable \luacatcodes \fi +\ifdefined\notcatcodes \else \newcatcodetable \notcatcodes \fi +\ifdefined\vrbcatcodes \else \newcatcodetable \vrbcatcodes \fi +\ifdefined\prtcatcodes \else \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..2749f403c --- /dev/null +++ b/tex/context/base/catc-ini.lua @@ -0,0 +1,33 @@ +if not modules then modules = { } end modules ['catc-ini'] = { + version = 1.001, + comment = "companion to catc-ini.mkiv", + 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 + local cnn = catcodes.names[number] + if cnn then + cnn[#cnn+1] = name + else + catcodes.names[number] = { name } + end + 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..dee15290a --- /dev/null +++ b/tex/context/base/catc-ini.mkii @@ -0,0 +1,249 @@ +%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 + +\chardef\escapecatcode = 0 +\chardef\begingroupcatcode = 1 +\chardef\endgroupcatcode = 2 +\chardef\mathshiftcatcode = 3 +\chardef\alignmentcatcode = 4 +\chardef\endoflinecatcode = 5 +\chardef\parametercatcode = 6 +\chardef\superscriptcatcode = 7 +\chardef\subscriptcatcode = 8 +\chardef\ignorecatcode = 9 +\chardef\spacecatcode = 10 +\chardef\lettercatcode = 11 +\chardef\othercatcode = 12 \chardef\other = 12 +\chardef\activecatcode = 13 \chardef\active = 13 +\chardef\commentcatcode = 14 + +\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=\lettercatcode \lettercatcode\else\othercatcode\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\activehackcode\activecatcode + \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 + \showcatcodenestingerror + \else + \expandafter\catcodetable\csname scct:\number\catcoderestorelevel\endcsname + \tracepopcatcodetable + \advance\catcoderestorelevel\minusone + \fi} + +\def\showcatcodenestingerror % can be overloaded + {\immediate\write16{}% + \immediate\write16{Fatal error: catcode push/pop mismatch. Fix this!}\wait\end + \immediate\write16{}} + +\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..269330a1b --- /dev/null +++ b/tex/context/base/catc-ini.mkiv @@ -0,0 +1,317 @@ +%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 + +\chardef\escapecatcode = 0 +\chardef\begingroupcatcode = 1 +\chardef\endgroupcatcode = 2 +\chardef\mathshiftcatcode = 3 +\chardef\alignmentcatcode = 4 +\chardef\endoflinecatcode = 5 +\chardef\parametercatcode = 6 +\chardef\superscriptcatcode = 7 +\chardef\subscriptcatcode = 8 +\chardef\ignorecatcode = 9 +\chardef\spacecatcode = 10 +\chardef\lettercatcode = 11 +\chardef\othercatcode = 12 \chardef\other = 12 +\chardef\activecatcode = 13 \chardef\active = 13 +\chardef\commentcatcode = 14 + +\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\chardef#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`\\ \othercatcode + \catcode`\^^M \othercatcode + \catcode`\ \othercatcode + \catcode`\% \othercatcode + \catcode127 \othercatcode} + +\long\normalprotected\def\startcatcodetable#1#2\stopcatcodetable + {\bgroup + \catcodetable\scratchcatcodes + \the\setdefaultcatcodes + #2% + \savecatcodetable#1\relax + \egroup} + +\newcatcodetable\dummycatcodes + +\long\normalprotected\def\startextendcatcodetable#1#2\stopextendcatcodetable + {\bgroup + \catcodetable#1\relax + \globaldefs\plusone + #2% + \globaldefs\zerocount + \egroup} + +% == +% +% \long\normalprotected\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. Do we still need this complex +%D mechanism? Future versions of \MKIV\ might only use +%D active characters for very special cases. + +\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}% + \reinstatecatcodecommandua % unexpanded + \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 (we could use \normalexpanded here) + {\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\normalprotected\expandafter\def\csname CCC:\number\cctcountera:\number\cctcounterb\endcsname{##1}}% + \reinstatecatcodecommandua % unexpanded + \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\activehackcode\activecatcode + \uppercase{\xdef~{\noexpand\catcodecommand{\number\cctcounterb}}}% + \egroup} + +\def\reinstatecatcodecommandua % can be used when a direct definition has been done + {\bgroup % and the selector has been lost + \uccode\activehackcode\cctcounterb + \catcode\uccode\activehackcode\activecatcode + \uppercase{\normalprotected\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\chardef\csname scct:\number\catcoderestorelevel\endcsname\currentcatcodetable} + +\def\popcatcodetable + {\ifcase\catcoderestorelevel + \showcatcodenestingerror + \else + \expandafter\catcodetable\csname scct:\number\catcoderestorelevel\endcsname + \tracepopcatcodetable + \advance\catcoderestorelevel\minusone + \fi} + +\def\showcatcodenestingerror % can be overloaded + {\immediate\write16{}% + \immediate\write16{Fatal error: catcode push/pop mismatch. Fix this!}\wait\end + \immediate\write16{}} + +\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 + +%D Only in \MKIV\ (to be used when crossing pages with changed catcodes +%D in the current vector): +%D +%D \starttyping +%D \normalprotected\def\startcrap +%D {\bgroup +%D \pushcatcodes +%D \whitespace +%D \obeylines +%D \activatespacehandler\v!yes +%D \strut} +%D +%D \normalprotected\def\stopcrap +%D {\popcatcodes +%D \egroup} +%D \stoptyping + +\newcount\catcodetablelevel + +\def\pushcatcodes + {\bgroup + \global\advance\catcodetablelevel\plusone + \ifcsname @@ccf:\number\catcodetablelevel\endcsname \else + \global\advance\cctdefcounter\plusone + \expandafter\global\expandafter\chardef\csname @@ccf:\number\catcodetablelevel\endcsname\cctdefcounter + \fi + \catcodetable\ctxcatcodes + \expandafter\savecatcodetable\csname @@ccf:\number\catcodetablelevel\endcsname + \egroup + \expandafter\catcodetable\csname @@ccf:\number\catcodetablelevel\endcsname} + +\def\popcatcodes + {\global\advance\catcodetablelevel\minusone} + +\endinput + diff --git a/tex/context/base/catc-sym.tex b/tex/context/base/catc-sym.tex new file mode 100644 index 000000000..067e192c8 --- /dev/null +++ b/tex/context/base/catc-sym.tex @@ -0,0 +1,187 @@ +%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. + +% we now have loaded syst-* so we have all @@catcode constants + +%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=\begingroupcatcode +\catcode`E=\endgroupcatcode +\catcode`.=\escapecatcode + +.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`\ =\spacecatcode + \catcode`\^^L=\ignorecatcode + \catcode`\^^M=\endoflinecatcode + \catcode`\^^?=\ignorecatcode} + +%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`\|=\activecatcode + \catcode`\~=\activecatcode + + \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 + +%D (Inspired by a discussion on the \CONTEXT\ mailing list) +%D +%D In \TEX\ each character can have one of 16 catcodes. This way the +%D backslash, dollar, ampersand, hash and some more characters get +%D their special meaning. If you want to process tokens under a +%D certain catcode regime, passing arguments can interfere badly. +%D +%D \startbuffer[a] +%D \def\whatever#1{[#1]} +%D \whatever{whatever \type {\whatever{you want}} $or$ not!} +%D \stopbuffer +%D +%D \typebuffer[a] +%D +%D Here we pass an argument to \type {\whatever} but part of that +%D argument is to be processed under a different catcode regime, i.e.\ +%D all characters that need to be typeset verbatim need to get +%D the catcode that makes it a letter. This is what we get when we typeset +%D the text verbatim: +%D +%D \starttyping +%D whatever \type {\whatever{you want}} $or$ not! +%D \stoptyping +%D +%D However, when passed to \type {\whatever} we get: +%D +%D \getbuffer[a] +%D +%D In \ETEX\ one can use \type {\scantokens} to circumvent this problem. +%D +%D \startbuffer[b] +%D \def\rescan#1{\scantokens{#1}} +%D \def\whatever#1{[\rescan{#1}]} +%D \whatever{whatever \type {\whatever{you want}} $or$ not!} +%D \stopbuffer +%D +%D \getbuffer[b] \typebuffer[b] +%D +%D This time the \type {\whatever} call gives: +%D +%D \getbuffer[b] +%D +%D In this example, two spaces have crept in. The first one, after the +%D macro name, is inserted by \TEX\ and cannot be avoided. The last space +%D is inserted by \type {\scantokens}, and is the consequence of the fact +%D that this macro mimics reading from a file. You can avoid the last +%D space by a slightly different definition: +%D +%D \startbuffer[c] +%D \def\rescan#1{\scantokens{#1\ignorespaces}} +%D \def\whatever#1{[\rescan{#1}]} +%D \whatever{whatever \type {\whatever{you want}} $or$ not!} +%D \stopbuffer +%D +%D \typebuffer[c] +%D +%D Unfortunately we still keep the first space, but at least it's better than +%D a failure: +%D +%D \getbuffer[c] + +\long\def\rescan#1{\scantokens{#1\ignorespaces}} +\long\def\rescanwithsetup#1#2{\begingroup\directsetup{#1}\scantokens{#2\ignorespaces}\endgroup} + +\ifx\scantextokens\undefined \else + \long\def\rescan#1{\scantextokens{#1}} + \long\def\rescanwithsetup#1#2{\begingroup\directsetup{#1}\scantextokens{#2}\endgroup} +\fi + +\endinput diff --git a/tex/context/base/char-act.mkiv b/tex/context/base/char-act.mkiv new file mode 100644 index 000000000..2dc7823f0 --- /dev/null +++ b/tex/context/base/char-act.mkiv @@ -0,0 +1,138 @@ +%D \module +%D [ file=char-act, +%D version=2006.12.05, +%D title=\CONTEXT\ Character Support, +%D subtitle=Active, +%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 / Active} + +\unprotect + +%D \macros +%D {processingverbatim} +%D +%D Typesetting a file in most cases results in more than one +%D page. Because we don't want problems with files that are +%D read in during the construction of the page, we set \type +%D {\ifprocessingverbatim}, so the output routine can adapt +%D its behavior. Originally we used \type {\scratchread}, but +%D because we want to support nesting, we decided to use a +%D separate input file. + +\newif\ifprocessingverbatim + +%D \macros +%D {obeyedspace, obeyedtab, obeyedline, obeyedpage} +%D +%D We have followed Knuth in naming macros that make \SPACE, +%D \NEWLINE\ and \NEWPAGE\ active and assigning them +%D \type{\obeysomething}, but first we set some default values. + +\def\obeyedspace {\ifprocessingverbatim\hbox{ }\else\space\fi} +\def\obeyedtab {\obeyedspace} +\def\obeyedline {\par} +\def\obeyedpage {\vfill\eject} + +%D \macros +%D {controlspace,setcontrolspaces} +%D +%D First we define \type{\obeyspaces}. When we want visible +%D spaces (control spaces) we only have to adapt the definition +%D of \type{\obeyedspace} to: + +\def\controlspace{\hbox{\char32}} % rather tex +\def\normalspace { } +\def\normalspaces{\catcode`\ =\@@space} + +\bgroup +\catcode`\ =\@@active +\gdef\obeyspaces{\catcode`\ =\@@active\def {\obeyedspace}} +\gdef\setcontrolspaces{\catcode`\ =\@@active\def {\controlspace}} +\egroup + +%D \macros +%D {obeytabs, obeylines, obeypages,ignoretabs, ignorelines, ignorepages} +%D +%D Next we take care of \NEWLINE\ and \NEWPAGE\ and because we +%D want to be able to typeset listings that contain \TAB, we +%D have to handle those too. Because we have to redefine the +%D \NEWPAGE\ character locally, we redefine the meaning of +%D this (often already) active character. + +\catcode`\^^L=\@@active \def^^L{\par} + +%D The following indirect definitions enable us to implement +%D all kind of \type{\obeyed} handlers. + +\bgroup + +\catcode`\^^I=\@@active +\catcode`\^^M=\@@active +\catcode`\^^L=\@@active + +\gdef\obeytabs {\catcode`\^^I=\@@active\def^^I{\obeyedtab}} +\gdef\obeylines {\catcode`\^^M=\@@active\def^^M{\obeyedline}} +\gdef\obeypages {\catcode`\^^L=\@@active\def^^L{\obeyedpage}} + +\gdef\ignoretabs {\catcode`\^^I=\@@active\def^^I{\obeyedspace}} +\gdef\ignorelines {\catcode`\^^M=\@@active\def^^M{\obeyedspace}} +\gdef\ignorepages {\catcode`\^^L=\@@ignore} % \@@active\def^^L{\obeyedline}} +\gdef\ignoreeofs {\catcode`\^^Z=\@@ignore} + +\egroup + +%D \macros +%D {naturaltextext} +%D +%D When one uses \ETEX, switching to normal \TEX\ is possible +%D too. We also introduce a switch that can be used in the +%D drivers and set in higher level shell macros. + +\def\naturaltextext#1\relax + {\bgroup + \def\ascii{#1}% + \setcatcodetable\ctxcatcodes + \prettynaturalfont{\scantextokens\expandafter{\ascii}\ifhmode\unskip\fi}% + \egroup} + +%D What-a-mess: + +% \def\normalspacecodes +% {\catcode`\^^I = 10 +% \catcode`\^^M = 5 +% \catcode`\^^L = 5 +% \catcode`\ = 10 +% \catcode`\^^Z = 9 } + +% \appendtoks +% \normalspacecodes +% \to \everybeforeoutput + +\endinput \protect + +% obsolete (old hack for idris) + +%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 diff --git a/tex/context/base/char-cmp.lua b/tex/context/base/char-cmp.lua new file mode 100644 index 000000000..c7deb7901 --- /dev/null +++ b/tex/context/base/char-cmp.lua @@ -0,0 +1,268 @@ +if not modules then modules = { } end modules ['char-cmp'] = { + version = 1.001, + comment = "companion to char-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local utf = unicode.utf8 +local unpack = unpack or table.unpack + +characters = characters or { } +characters.uncomposed = characters.uncomposed or { } + +--[[ldx-- +

The code defined here may move to the big character table.

+--ldx]]-- + +characters.basedigits = { + ['zero'] = 48, ['one'] = 49, + ['two'] = 50, ['three'] = 51, + ['four'] = 52, ['five'] = 53, + ['six'] = 54, ['seven'] = 55, + ['eight'] = 56, ['nine'] = 57 +} + +--[[ldx-- +

The next three tables can for instance be be used to enhance +kerning tables that lack kerning pairs for these special characters. +Of course they may come in handy elsewhere too

+--ldx]]-- + +-- we can use shcodes, but then we also need slcode and srcode +-- +-- AEligature +-- => slcode == ub('A') +-- => srcode == ub('E') +-- or +-- => shcode == { ub('A'), ub('E') } +-- => reduction = "AE" +-- +-- eacute +-- => shcode == ub('A') +-- or +-- => shcode == { ub('a') } +-- => reduction = "a" + +characters.uncomposed.left = { + AEligature = "A", aeligature = "a", + OEligature = "O", oeligature = "o", + IJligature = "I", ijligature = "i", + AE = "A", ae = "a", + OE = "O", oe = "o", + IJ = "I", ij = "i", + Ssharp = "S", ssharp = "s", +} + +characters.uncomposed.right = { + AEligature = "E", aeligature = "e", + OEligature = "E", oeligature = "e", + IJligature = "J", ijligature = "j", + AE = "E", ae = "e", + OE = "E", oe = "e", + IJ = "J", ij = "j", + Ssharp = "S", ssharp = "s", +} + +characters.uncomposed.both = { + Acircumflex = "A", acircumflex = "a", + Ccircumflex = "C", ccircumflex = "c", + Ecircumflex = "E", ecircumflex = "e", + Gcircumflex = "G", gcircumflex = "g", + Hcircumflex = "H", hcircumflex = "h", + Icircumflex = "I", icircumflex = "i", + Jcircumflex = "J", jcircumflex = "j", + Ocircumflex = "O", ocircumflex = "o", + Scircumflex = "S", scircumflex = "s", + Ucircumflex = "U", ucircumflex = "u", + Wcircumflex = "W", wcircumflex = "w", + Ycircumflex = "Y", ycircumflex = "y", + + Agrave = "A", agrave = "a", + Egrave = "E", egrave = "e", + Igrave = "I", igrave = "i", + Ograve = "O", ograve = "o", + Ugrave = "U", ugrave = "u", + Ygrave = "Y", ygrave = "y", + + Atilde = "A", atilde = "a", + Itilde = "I", itilde = "i", + Otilde = "O", otilde = "o", + Utilde = "U", utilde = "u", + Ntilde = "N", ntilde = "n", + + Adiaeresis = "A", adiaeresis = "a", Adieresis = "A", adieresis = "a", + Ediaeresis = "E", ediaeresis = "e", Edieresis = "E", edieresis = "e", + Idiaeresis = "I", idiaeresis = "i", Idieresis = "I", idieresis = "i", + Odiaeresis = "O", odiaeresis = "o", Odieresis = "O", odieresis = "o", + Udiaeresis = "U", udiaeresis = "u", Udieresis = "U", udieresis = "u", + Ydiaeresis = "Y", ydiaeresis = "y", Ydieresis = "Y", ydieresis = "y", + + Aacute = "A", aacute = "a", + Cacute = "C", cacute = "c", + Eacute = "E", eacute = "e", + Iacute = "I", iacute = "i", + Lacute = "L", lacute = "l", + Nacute = "N", nacute = "n", + Oacute = "O", oacute = "o", + Racute = "R", racute = "r", + Sacute = "S", sacute = "s", + Uacute = "U", uacute = "u", + Yacute = "Y", yacute = "y", + Zacute = "Z", zacute = "z", + + Dstroke = "D", dstroke = "d", + Hstroke = "H", hstroke = "h", + Tstroke = "T", tstroke = "t", + + Cdotaccent = "C", cdotaccent = "c", + Edotaccent = "E", edotaccent = "e", + Gdotaccent = "G", gdotaccent = "g", + Idotaccent = "I", idotaccent = "i", + Zdotaccent = "Z", zdotaccent = "z", + + Amacron = "A", amacron = "a", + Emacron = "E", emacron = "e", + Imacron = "I", imacron = "i", + Omacron = "O", omacron = "o", + Umacron = "U", umacron = "u", + + Ccedilla = "C", ccedilla = "c", + Kcedilla = "K", kcedilla = "k", + Lcedilla = "L", lcedilla = "l", + Ncedilla = "N", ncedilla = "n", + Rcedilla = "R", rcedilla = "r", + Scedilla = "S", scedilla = "s", + Tcedilla = "T", tcedilla = "t", + + Ohungarumlaut = "O", ohungarumlaut = "o", + Uhungarumlaut = "U", uhungarumlaut = "u", + + Aogonek = "A", aogonek = "a", + Eogonek = "E", eogonek = "e", + Iogonek = "I", iogonek = "i", + Uogonek = "U", uogonek = "u", + + Aring = "A", aring = "a", + Uring = "U", uring = "u", + + Abreve = "A", abreve = "a", + Ebreve = "E", ebreve = "e", + Gbreve = "G", gbreve = "g", + Ibreve = "I", ibreve = "i", + Obreve = "O", obreve = "o", + Ubreve = "U", ubreve = "u", + + Ccaron = "C", ccaron = "c", + Dcaron = "D", dcaron = "d", + Ecaron = "E", ecaron = "e", + Lcaron = "L", lcaron = "l", + Ncaron = "N", ncaron = "n", + Rcaron = "R", rcaron = "r", + Scaron = "S", scaron = "s", + Tcaron = "T", tcaron = "t", + Zcaron = "Z", zcaron = "z", + + dotlessI = "I", dotlessi = "i", + dotlessJ = "J", dotlessj = "j", + + AEligature = "AE", aeligature = "ae", AE = "AE", ae = "ae", + OEligature = "OE", oeligature = "oe", OE = "OE", oe = "oe", + IJligature = "IJ", ijligature = "ij", IJ = "IJ", ij = "ij", + + Lstroke = "L", lstroke = "l", Lslash = "L", lslash = "l", + Ostroke = "O", ostroke = "o", Oslash = "O", oslash = "o", + + Ssharp = "SS", ssharp = "ss", + + Aumlaut = "A", aumlaut = "a", + Eumlaut = "E", eumlaut = "e", + Iumlaut = "I", iumlaut = "i", + Oumlaut = "O", oumlaut = "o", + Uumlaut = "U", uumlaut = "u", + +} + +--[[ldx-- +

The following function is used in the indexing code, where +we need some sort of default fallback mapping.

+--ldx]]-- + +function characters.uncompose(n) -- n == string|number, returns string + local cdn + if type(n) == "string" then + cdn = characters.data[utf.byte(n)] + else + cdn = characters.data[n] + end + -- return characters.shape(n) + if cdn then + local shcode = cdn.shcode + if not shcode then + return characters.uncomposed.both[cdn.contextname] or n + elseif type(shcode) == "table" then + return utf.char(unpack(cdn.shcode)) + else + return utf.char(cdn.shcode) + end + end + return n +end + +--[[ldx-- +

Only characters with a code smaller than 128 make sense, +anything larger is encoding dependent. An interesting complication +is that a character can be in an encoding twice but is hashed +once.

+--ldx]]-- + +characters.ligatures = { + ['f'] = { + { 'f', 'ff' }, + { 'i', 'fi' }, + { 'l', 'fl' }, + }, + ['ff'] = { + { 'i', 'ffi' } + }, + ['fi'] = { + { 'i', 'fii' } + }, + ['fl'] = { + { 'i', 'fli' } + }, + ['s'] = { + { 't', 'st' } + }, + ['i'] = { + { 'j', 'ij' } + }, +} + +characters.texligatures = { + -- ['space'] = { + -- { 'L', 'Lslash' }, + -- { 'l', 'lslash' } + -- }, + -- ['question'] = { + -- { 'quoteleft', 'questiondown' } + -- }, + -- ['exclam'] = { + -- { 'quoteleft', 'exclamdown' } + -- }, + ['quoteleft'] = { + { 'quoteleft', 'quotedblleft' } + }, + ['quoteright'] = { + { 'quoteright', 'quotedblright' } + }, + ['hyphen'] = { + { 'hyphen', 'endash' } + }, + ['endash'] = { + { 'hyphen', 'emdash' } + } +} + +--~ U+2019: right single quotation mark / quoteright diff --git a/tex/context/base/char-def.lua b/tex/context/base/char-def.lua new file mode 100644 index 000000000..b7abee0fb --- /dev/null +++ b/tex/context/base/char-def.lua @@ -0,0 +1,141127 @@ +if not modules then modules = { } end modules ['char-def'] = { + version = 1.001, + comment = "companion to char-ini.mkiv", + 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={ + [0x0000]={ + category="cc", + description="NULL", + direction="bn", + linebreak="cm", + unicodeslot=0x0000, + }, + { + category="cc", + description="START OF HEADING", + direction="bn", + linebreak="cm", + unicodeslot=0x0001, + }, + { + category="cc", + description="START OF TEXT", + direction="bn", + linebreak="cm", + unicodeslot=0x0002, + }, + { + category="cc", + description="END OF TEXT", + direction="bn", + linebreak="cm", + unicodeslot=0x0003, + }, + { + category="cc", + description="END OF TRANSMISSION", + direction="bn", + linebreak="cm", + unicodeslot=0x0004, + }, + { + category="cc", + description="ENQUIRY", + direction="bn", + linebreak="cm", + unicodeslot=0x0005, + }, + { + category="cc", + description="ACKNOWLEDGE", + direction="bn", + linebreak="cm", + unicodeslot=0x0006, + }, + { + category="cc", + description="BELL", + direction="bn", + linebreak="cm", + unicodeslot=0x0007, + }, + { + category="cc", + description="BACKSPACE", + direction="bn", + linebreak="cm", + unicodeslot=0x0008, + }, + { + category="cc", + description="CHARACTER TABULATION", + direction="s", + linebreak="ba", + unicodeslot=0x0009, + }, + { + category="cc", + description="LINE FEED (LF)", + direction="b", + linebreak="lf", + unicodeslot=0x000A, + }, + { + category="cc", + description="LINE TABULATION", + direction="s", + linebreak="bk", + unicodeslot=0x000B, + }, + { + category="cc", + description="FORM FEED (FF)", + direction="ws", + linebreak="bk", + unicodeslot=0x000C, + }, + { + category="cc", + description="CARRIAGE RETURN (CR)", + direction="b", + linebreak="cr", + unicodeslot=0x000D, + }, + { + category="cc", + description="SHIFT OUT", + direction="bn", + linebreak="cm", + unicodeslot=0x000E, + }, + { + category="cc", + description="SHIFT IN", + direction="bn", + linebreak="cm", + unicodeslot=0x000F, + }, + { + category="cc", + description="DATA LINK ESCAPE", + direction="bn", + linebreak="cm", + unicodeslot=0x0010, + }, + { + category="cc", + description="DEVICE CONTROL ONE", + direction="bn", + linebreak="cm", + unicodeslot=0x0011, + }, + { + category="cc", + description="DEVICE CONTROL TWO", + direction="bn", + linebreak="cm", + unicodeslot=0x0012, + }, + { + category="cc", + description="DEVICE CONTROL THREE", + direction="bn", + linebreak="cm", + unicodeslot=0x0013, + }, + { + category="cc", + description="DEVICE CONTROL FOUR", + direction="bn", + linebreak="cm", + unicodeslot=0x0014, + }, + { + category="cc", + description="NEGATIVE ACKNOWLEDGE", + direction="bn", + linebreak="cm", + unicodeslot=0x0015, + }, + { + category="cc", + description="SYNCHRONOUS IDLE", + direction="bn", + linebreak="cm", + unicodeslot=0x0016, + }, + { + category="cc", + description="END OF TRANSMISSION BLOCK", + direction="bn", + linebreak="cm", + unicodeslot=0x0017, + }, + { + category="cc", + description="CANCEL", + direction="bn", + linebreak="cm", + unicodeslot=0x0018, + }, + { + category="cc", + description="END OF MEDIUM", + direction="bn", + linebreak="cm", + unicodeslot=0x0019, + }, + { + category="cc", + description="SUBSTITUTE", + direction="bn", + linebreak="cm", + unicodeslot=0x001A, + }, + { + category="cc", + description="ESCAPE", + direction="bn", + linebreak="cm", + unicodeslot=0x001B, + }, + { + category="cc", + description="INFORMATION SEPARATOR FOUR", + direction="b", + linebreak="cm", + unicodeslot=0x001C, + }, + { + category="cc", + description="INFORMATION SEPARATOR THREE", + direction="b", + linebreak="cm", + unicodeslot=0x001D, + }, + { + category="cc", + description="INFORMATION SEPARATOR TWO", + direction="b", + linebreak="cm", + unicodeslot=0x001E, + }, + { + category="cc", + description="INFORMATION SEPARATOR ONE", + direction="s", + linebreak="cm", + unicodeslot=0x001F, + }, + { + adobename="space", + category="zs", + cjkwd="na", + description="SPACE", + direction="ws", + linebreak="sp", + unicodeslot=0x0020, + }, + { + adobename="exclam", + category="po", + cjkwd="na", + description="EXCLAMATION MARK", + direction="on", + linebreak="ex", + mathclass="close", + unicodeslot=0x0021, + }, + { + adobename="quotedbl", + category="po", + cjkwd="na", + contextname="quotedbl", + description="QUOTATION MARK", + direction="on", + mathclass="default", + linebreak="qu", + unicodeslot=0x0022, + }, + { + adobename="numbersign", + category="po", + cjkwd="na", + description="NUMBER SIGN", + direction="et", + linebreak="al", + unicodeslot=0x0023, + }, + { + adobename="dollar", + category="sc", + cjkwd="na", + contextname="textdollar", + description="DOLLAR SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x0024, + }, + { + adobename="percent", + category="po", + cjkwd="na", + contextname="percent", + description="PERCENT SIGN", + direction="et", + linebreak="po", + unicodeslot=0x0025, + }, + { + adobename="ampersand", + category="po", + cjkwd="na", + description="AMPERSAND", + direction="on", + linebreak="al", + unicodeslot=0x0026, + }, + { + adobename="quotesingle", + category="po", + cjkwd="na", + contextname="quotesingle", + description="APOSTROPHE", + direction="on", + linebreak="qu", + mathclass="default", + unicodeslot=0x0027, + }, + { + adobename="parenleft", + category="ps", + cjkwd="na", + description="LEFT PARENTHESIS", + direction="on", + linebreak="op", + mathclass="open", + mathname="lparent", + mirror=0x0029, + unicodeslot=0x0028, + }, + { + adobename="parenright", + category="pe", + cjkwd="na", + description="RIGHT PARENTHESIS", + direction="on", + linebreak="cl", + mathclass="close", + mathname="rparent", + mirror=0x0028, + unicodeslot=0x0029, + }, + { + adobename="asterisk", + category="po", + cjkwd="na", + description="ASTERISK", + direction="on", + linebreak="al", + mathclass="binary", + mathname="ast", + unicodeslot=0x002A, + }, + { + adobename="plus", + category="sm", + cjkwd="na", + description="PLUS SIGN", + direction="es", + linebreak="pr", + mathclass="binary", + unicodeslot=0x002B, + }, + { + adobename="comma", + category="po", + cjkwd="na", + description="COMMA", + direction="cs", + linebreak="is", + mathclass="punctuation", + mathspec={ + { class="punctuation", name="textcomma" }, + { class="ord", name="mathcomma" }, + }, + unicodeslot=0x002C, + }, + { + adobename="hyphen", + category="pd", + cjkwd="na", + description="HYPHEN-MINUS", + direction="es", + linebreak="hy", + mathsymbol=0x2212, + unicodeslot=0x002D, + }, + { + adobename="period", + category="po", + cjkwd="na", + description="FULL STOP", + direction="cs", + linebreak="is", + 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", + mathsymbol=0x2044, + unicodeslot=0x002F, + }, + { + adobename="zero", + category="nd", + cjkwd="na", + description="DIGIT ZERO", + direction="en", + linebreak="nu", + mathclass="number", + unicodeslot=0x0030, + }, + { + adobename="one", + category="nd", + cjkwd="na", + description="DIGIT ONE", + direction="en", + linebreak="nu", + mathclass="number", + unicodeslot=0x0031, + }, + { + adobename="two", + category="nd", + cjkwd="na", + description="DIGIT TWO", + direction="en", + linebreak="nu", + mathclass="number", + unicodeslot=0x0032, + }, + { + adobename="three", + category="nd", + cjkwd="na", + description="DIGIT THREE", + direction="en", + linebreak="nu", + mathclass="number", + unicodeslot=0x0033, + }, + { + adobename="four", + category="nd", + cjkwd="na", + description="DIGIT FOUR", + direction="en", + linebreak="nu", + mathclass="number", + unicodeslot=0x0034, + }, + { + adobename="five", + category="nd", + cjkwd="na", + description="DIGIT FIVE", + direction="en", + linebreak="nu", + mathclass="number", + unicodeslot=0x0035, + }, + { + adobename="six", + category="nd", + cjkwd="na", + description="DIGIT SIX", + direction="en", + linebreak="nu", + mathclass="number", + unicodeslot=0x0036, + }, + { + adobename="seven", + category="nd", + cjkwd="na", + description="DIGIT SEVEN", + direction="en", + linebreak="nu", + mathclass="number", + unicodeslot=0x0037, + }, + { + adobename="eight", + category="nd", + cjkwd="na", + description="DIGIT EIGHT", + direction="en", + linebreak="nu", + mathclass="number", + unicodeslot=0x0038, + }, + { + adobename="nine", + category="nd", + cjkwd="na", + description="DIGIT NINE", + direction="en", + linebreak="nu", + mathclass="number", + unicodeslot=0x0039, + }, + { + adobename="colon", + category="po", + cjkwd="na", + description="COLON", + direction="cs", + linebreak="is", +--~ mathclass="punctuation", + mathclass="relation", +-- mathname="colon", + unicodeslot=0x003A, + }, + { + adobename="semicolon", + category="po", + cjkwd="na", + description="SEMICOLON", + direction="on", + linebreak="is", + mathclass="punctuation", + unicodeslot=0x003B, + }, + { + adobename="less", + category="sm", + cjkwd="na", + description="LESS-THAN SIGN", + direction="on", + linebreak="al", + mathclass="binary", + mathname="lt", + mirror=0x003E, + unicodeslot=0x003C, + }, + { + adobename="equal", + category="sm", + cjkwd="na", + description="EQUALS SIGN", + direction="on", + linebreak="al", +--~ mathclass="binary", + mathclass="relation", + mathname="eq", + unicodeslot=0x003D, + }, + { + adobename="greater", + category="sm", + cjkwd="na", + description="GREATER-THAN SIGN", + direction="on", + linebreak="al", + mathclass="binary", + mathname="gt", + mirror=0x003C, + unicodeslot=0x003E, + }, + { + adobename="question", + category="po", + cjkwd="na", + description="QUESTION MARK", + direction="on", + linebreak="ex", + mathclass="close", + unicodeslot=0x003F, + }, + { + adobename="at", + category="po", + cjkwd="na", + contextname="textat", + description="COMMERCIAL AT", + direction="on", + linebreak="al", + unicodeslot=0x0040, + }, + { + adobename="A", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER A", + direction="l", + lccode=0x0061, + linebreak="al", + mathclass="variable", + unicodeslot=0x0041, + }, + { + adobename="B", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER B", + direction="l", + lccode=0x0062, + linebreak="al", + mathclass="variable", + unicodeslot=0x0042, + }, + { + adobename="C", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER C", + direction="l", + lccode=0x0063, + linebreak="al", + mathclass="variable", + unicodeslot=0x0043, + }, + { + adobename="D", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER D", + direction="l", + lccode=0x0064, + linebreak="al", + mathclass="variable", + unicodeslot=0x0044, + }, + { + adobename="E", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER E", + direction="l", + lccode=0x0065, + linebreak="al", + mathclass="variable", + unicodeslot=0x0045, + }, + { + adobename="F", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER F", + direction="l", + lccode=0x0066, + linebreak="al", + mathclass="variable", + unicodeslot=0x0046, + }, + { + adobename="G", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER G", + direction="l", + lccode=0x0067, + linebreak="al", + mathclass="variable", + unicodeslot=0x0047, + }, + { + adobename="H", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER H", + direction="l", + lccode=0x0068, + linebreak="al", + mathclass="variable", + unicodeslot=0x0048, + }, + { + adobename="I", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER I", + direction="l", + lccode=0x0069, + linebreak="al", + mathclass="variable", + unicodeslot=0x0049, + }, + { + adobename="J", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER J", + direction="l", + lccode=0x006A, + linebreak="al", + mathclass="variable", + unicodeslot=0x004A, + }, + { + adobename="K", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER K", + direction="l", + lccode=0x006B, + linebreak="al", + mathclass="variable", + unicodeslot=0x004B, + }, + { + adobename="L", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER L", + direction="l", + lccode=0x006C, + linebreak="al", + mathclass="variable", + unicodeslot=0x004C, + }, + { + adobename="M", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER M", + direction="l", + lccode=0x006D, + linebreak="al", + mathclass="variable", + unicodeslot=0x004D, + }, + { + adobename="N", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER N", + direction="l", + lccode=0x006E, + linebreak="al", + mathclass="variable", + unicodeslot=0x004E, + }, + { + adobename="O", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER O", + direction="l", + lccode=0x006F, + linebreak="al", + mathclass="variable", + unicodeslot=0x004F, + }, + { + adobename="P", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER P", + direction="l", + lccode=0x0070, + linebreak="al", + mathclass="variable", + unicodeslot=0x0050, + }, + { + adobename="Q", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER Q", + direction="l", + lccode=0x0071, + linebreak="al", + mathclass="variable", + unicodeslot=0x0051, + }, + { + adobename="R", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER R", + direction="l", + lccode=0x0072, + linebreak="al", + mathclass="variable", + unicodeslot=0x0052, + }, + { + adobename="S", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER S", + direction="l", + lccode=0x0073, + linebreak="al", + mathclass="variable", + unicodeslot=0x0053, + }, + { + adobename="T", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER T", + direction="l", + lccode=0x0074, + linebreak="al", + mathclass="variable", + unicodeslot=0x0054, + }, + { + adobename="U", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER U", + direction="l", + lccode=0x0075, + linebreak="al", + mathclass="variable", + unicodeslot=0x0055, + }, + { + adobename="V", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER V", + direction="l", + lccode=0x0076, + linebreak="al", + mathclass="variable", + unicodeslot=0x0056, + }, + { + adobename="W", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER W", + direction="l", + lccode=0x0077, + linebreak="al", + mathclass="variable", + unicodeslot=0x0057, + }, + { + adobename="X", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER X", + direction="l", + lccode=0x0078, + linebreak="al", + mathclass="variable", + unicodeslot=0x0058, + }, + { + adobename="Y", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER Y", + direction="l", + lccode=0x0079, + linebreak="al", + mathclass="variable", + unicodeslot=0x0059, + }, + { + adobename="Z", + category="lu", + cjkwd="na", + description="LATIN CAPITAL LETTER Z", + direction="l", + lccode=0x007A, + linebreak="al", + mathclass="variable", + unicodeslot=0x005A, + }, + { + adobename="bracketleft", + category="ps", + cjkwd="na", + description="LEFT SQUARE BRACKET", + direction="on", + linebreak="op", + mathclass="open", + mathname="lbrack", + mirror=0x005D, + unicodeslot=0x005B, + }, + { + adobename="backslash", + category="po", + cjkwd="na", + contextname="textbackslash", + description="REVERSE SOLIDUS", + direction="on", + linebreak="pr", + mathclass="nothing", + mathname="backslash", + unicodeslot=0x005C, + }, + { + adobename="bracketright", + category="pe", + cjkwd="na", + description="RIGHT SQUARE BRACKET", + direction="on", + linebreak="cl", + mathclass="close", + mathname="rbrack", + mirror=0x005B, + unicodeslot=0x005D, + }, + { + adobename="asciicircum", + category="sk", + cjkwd="na", + contextname="textasciicircum", + description="CIRCUMFLEX ACCENT", + direction="on", + linebreak="al", + mathclass="accent", + unicodeslot=0x005E, + }, + { + adobename="underscore", + category="pc", + cjkwd="na", + contextname="textunderscore", + description="LOW LINE", + direction="on", + linebreak="al", + unicodeslot=0x005F, + }, + { + adobename="grave", + category="sk", + cjkwd="na", + contextname="textgrave", + description="GRAVE ACCENT", + mathclass="accent", + mathname="grave", + direction="on", + linebreak="al", + unicodeslot=0x0060, + }, + { + adobename="a", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER A", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x0041, + unicodeslot=0x0061, + }, + { + adobename="b", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER B", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x0042, + unicodeslot=0x0062, + }, + { + adobename="c", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER C", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x0043, + unicodeslot=0x0063, + }, + { + adobename="d", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER D", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x0044, + unicodeslot=0x0064, + }, + { + adobename="e", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER E", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x0045, + unicodeslot=0x0065, + }, + { + adobename="f", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER F", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x0046, + unicodeslot=0x0066, + }, + { + adobename="g", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER G", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x0047, + unicodeslot=0x0067, + }, + { + adobename="h", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER H", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x0048, + unicodeslot=0x0068, + }, + { + adobename="i", + category="ll", + cjkwd="na", + contextname="idotaccent", + description="LATIN SMALL LETTER I", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x0049, + unicodeslot=0x0069, + }, + { + adobename="j", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER J", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x004A, + unicodeslot=0x006A, + }, + { + adobename="k", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER K", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x004B, + unicodeslot=0x006B, + }, + { + adobename="l", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER L", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x004C, + unicodeslot=0x006C, + }, + { + adobename="m", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER M", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x004D, + unicodeslot=0x006D, + }, + { + adobename="n", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER N", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x004E, + unicodeslot=0x006E, + }, + { + adobename="o", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER O", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x004F, + unicodeslot=0x006F, + }, + { + adobename="p", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER P", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x0050, + unicodeslot=0x0070, + }, + { + adobename="q", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER Q", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x0051, + unicodeslot=0x0071, + }, + { + adobename="r", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER R", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x0052, + unicodeslot=0x0072, + }, + { + adobename="s", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER S", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x0053, + unicodeslot=0x0073, + }, + { + adobename="t", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER T", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x0054, + unicodeslot=0x0074, + }, + { + adobename="u", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER U", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x0055, + unicodeslot=0x0075, + }, + { + adobename="v", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER V", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x0056, + unicodeslot=0x0076, + }, + { + adobename="w", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER W", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x0057, + unicodeslot=0x0077, + }, + { + adobename="x", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER X", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x0058, + unicodeslot=0x0078, + }, + { + adobename="y", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER Y", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x0059, + unicodeslot=0x0079, + }, + { + adobename="z", + category="ll", + cjkwd="na", + description="LATIN SMALL LETTER Z", + direction="l", + linebreak="al", + mathclass="variable", + uccode=0x005A, + unicodeslot=0x007A, + }, + { + adobename="braceleft", + category="ps", + cjkwd="na", + contextname="textbraceleft", + description="LEFT CURLY BRACKET", + direction="on", + linebreak="op", + mathclass="open", + mathname="lbrace", -- was false + mirror=0x007D, + unicodeslot=0x007B, + }, + { + adobename="bar", + category="sm", + cjkwd="na", + contextname="textbar", + description="VERTICAL LINE", + direction="on", + linebreak="ba", + 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, + }, + { + adobename="braceright", + category="pe", + cjkwd="na", + contextname="textbraceright", + description="RIGHT CURLY BRACKET", + direction="on", + linebreak="cl", + mathclass="close", + mathname="rbrace", -- was false + mirror=0x007B, + unicodeslot=0x007D, + }, + { + adobename="asciitilde", + category="sm", + cjkwd="na", + contextname="textasciitilde", + description="TILDE", + direction="on", + linebreak="al", + unicodeslot=0x007E, + }, + { + category="cc", + description="DELETE", + direction="bn", + linebreak="cm", + unicodeslot=0x007F, + }, + { + category="cc", + description="NONE", + direction="bn", + linebreak="cm", + unicodeslot=0x0080, + }, + { + category="cc", + description="NONE", + direction="bn", + linebreak="cm", + unicodeslot=0x0081, + }, + { + category="cc", + description="BREAK PERMITTED HERE", + direction="bn", + linebreak="cm", + unicodeslot=0x0082, + }, + { + category="cc", + description="NO BREAK HERE", + direction="bn", + linebreak="cm", + unicodeslot=0x0083, + }, + { + category="cc", + description="NONE", + direction="bn", + linebreak="cm", + unicodeslot=0x0084, + }, + { + category="cc", + description="NEXT LINE (NEL)", + direction="b", + linebreak="nl", + unicodeslot=0x0085, + }, + { + category="cc", + description="START OF SELECTED AREA", + direction="bn", + linebreak="cm", + unicodeslot=0x0086, + }, + { + category="cc", + description="END OF SELECTED AREA", + direction="bn", + linebreak="cm", + unicodeslot=0x0087, + }, + { + category="cc", + description="CHARACTER TABULATION SET", + direction="bn", + linebreak="cm", + unicodeslot=0x0088, + }, + { + category="cc", + description="CHARACTER TABULATION WITH JUSTIFICATION", + direction="bn", + linebreak="cm", + unicodeslot=0x0089, + }, + { + category="cc", + description="LINE TABULATION SET", + direction="bn", + linebreak="cm", + unicodeslot=0x008A, + }, + { + category="cc", + description="PARTIAL LINE FORWARD", + direction="bn", + linebreak="cm", + unicodeslot=0x008B, + }, + { + category="cc", + description="PARTIAL LINE BACKWARD", + direction="bn", + linebreak="cm", + unicodeslot=0x008C, + }, + { + category="cc", + description="REVERSE LINE FEED", + direction="bn", + linebreak="cm", + unicodeslot=0x008D, + }, + { + category="cc", + description="SINGLE SHIFT TWO", + direction="bn", + linebreak="cm", + unicodeslot=0x008E, + }, + { + category="cc", + description="SINGLE SHIFT THREE", + direction="bn", + linebreak="cm", + unicodeslot=0x008F, + }, + { + category="cc", + description="DEVICE CONTROL STRING", + direction="bn", + linebreak="cm", + unicodeslot=0x0090, + }, + { + category="cc", + description="PRIVATE USE ONE", + direction="bn", + linebreak="cm", + unicodeslot=0x0091, + }, + { + category="cc", + description="PRIVATE USE TWO", + direction="bn", + linebreak="cm", + unicodeslot=0x0092, + }, + { + category="cc", + description="SET TRANSMIT STATE", + direction="bn", + linebreak="cm", + unicodeslot=0x0093, + }, + { + category="cc", + description="CANCEL CHARACTER", + direction="bn", + linebreak="cm", + unicodeslot=0x0094, + }, + { + category="cc", + description="MESSAGE WAITING", + direction="bn", + linebreak="cm", + unicodeslot=0x0095, + }, + { + category="cc", + description="START OF GUARDED AREA", + direction="bn", + linebreak="cm", + unicodeslot=0x0096, + }, + { + category="cc", + description="END OF GUARDED AREA", + direction="bn", + linebreak="cm", + unicodeslot=0x0097, + }, + { + category="cc", + description="START OF STRING", + direction="bn", + linebreak="cm", + unicodeslot=0x0098, + }, + { + category="cc", + description="NONE", + direction="bn", + linebreak="cm", + unicodeslot=0x0099, + }, + { + category="cc", + description="SINGLE CHARACTER INTRODUCER", + direction="bn", + linebreak="cm", + unicodeslot=0x009A, + }, + { + category="cc", + description="CONTROL SEQUENCE INTRODUCER", + direction="bn", + linebreak="cm", + unicodeslot=0x009B, + }, + { + category="cc", + description="STRING TERMINATOR", + direction="bn", + linebreak="cm", + unicodeslot=0x009C, + }, + { + category="cc", + description="OPERATING SYSTEM COMMAND", + direction="bn", + linebreak="cm", + unicodeslot=0x009D, + }, + { + category="cc", + description="PRIVACY MESSAGE", + direction="bn", + linebreak="cm", + unicodeslot=0x009E, + }, + { + category="cc", + description="APPLICATION PROGRAM COMMAND", + direction="bn", + linebreak="cm", + unicodeslot=0x009F, + }, + { + category="zs", + contextname="nobreakspace", + description="NO-BREAK SPACE", + direction="cs", + linebreak="gl", + specials={ "nobreak", 0x0020 }, + unicodeslot=0x00A0, + }, + { + adobename="exclamdown", + category="po", + cjkwd="a", + contextname="exclamdown", + description="INVERTED EXCLAMATION MARK", + direction="on", + linebreak="ai", + unicodeslot=0x00A1, + }, + { + adobename="cent", + category="sc", + cjkwd="na", + contextname="textcent", + description="CENT SIGN", + direction="et", + linebreak="po", + unicodeslot=0x00A2, + }, + { + adobename="sterling", + category="sc", + cjkwd="na", + contextname="textsterling", + description="POUND SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x00A3, + }, + { + adobename="currency", + category="sc", + cjkwd="a", + contextname="textcurrency", + description="CURRENCY SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x00A4, + }, + { + adobename="yen", + category="sc", + cjkwd="na", + contextname="textyen", + description="YEN SIGN", + direction="et", + linebreak="pr", + mathclass="nothing", + mathname="yen", + unicodeslot=0x00A5, + }, + { + adobename="brokenbar", + category="so", + cjkwd="na", + contextname="textbrokenbar", + description="BROKEN BAR", + direction="on", + linebreak="al", + unicodeslot=0x00A6, + }, + { + adobename="section", + category="so", + cjkwd="a", + contextname="sectionmark", + description="SECTION SIGN", + direction="on", + linebreak="ai", + mathclass="box", + mathname="S", + unicodeslot=0x00A7, + }, + { + adobename="dieresis", + category="sk", + cjkwd="a", + contextname="textdiaeresis", + description="DIAERESIS", + direction="on", + linebreak="ai", + mathclass="accent", + mathname="ddot", + specials={ "compat", 0x0020, 0x0308 }, + unicodeslot=0x00A8, + }, + { + adobename="copyright", + category="so", + contextname="copyright", + description="COPYRIGHT SIGN", + direction="on", + linebreak="al", + unicodeslot=0x00A9, + }, + { + adobename="ordfeminine", + category="ll", + cjkwd="a", + contextname="ordfeminine", + description="FEMININE ORDINAL INDICATOR", + direction="l", + linebreak="ai", + specials={ "super", 0x0061 }, + unicodeslot=0x00AA, + }, + { + adobename="guillemotleft", + category="pi", + contextname="leftguillemot", + description="LEFT-POINTING DOUBLE ANGLE QUOTATION MARK", + direction="on", + linebreak="qu", + mirror=0x00BB, + unicodeslot=0x00AB, + }, + { + adobename="logicalnot", + category="sm", + cjkwd="na", + contextname="textlognot", + description="NOT SIGN", + direction="on", + linebreak="al", + mathspec={ + { class="ord", name="lnot" }, + { class="ord", name="neg" }, + }, + unicodeslot=0x00AC, + }, + { + category="cf", + cjkwd="a", + contextname="softhyphen", + description="SOFT HYPHEN", + direction="bn", + linebreak="ba", + unicodeslot=0x00AD, + }, + { + adobename="registered", + category="so", + cjkwd="a", + contextname="registered", + description="REGISTERED SIGN", + direction="on", + linebreak="al", + unicodeslot=0x00AE, + }, + { + adobename="macron", + category="sk", + cjkwd="na", + contextname="textmacron", + description="MACRON", + direction="on", + linebreak="al", + mathclass="accent", + mathname="bar", + specials={ "compat", 0x0020, 0x0304 }, + unicodeslot=0x00AF, + }, + { + adobename="degree", + category="so", + cjkwd="a", + contextname="textdegree", + description="DEGREE SIGN", + direction="et", + linebreak="po", + unicodeslot=0x00B0, + }, + { + adobename="plusminus", + category="sm", + cjkwd="a", + contextname="textpm", + description="PLUS-MINUS SIGN", + direction="et", + linebreak="pr", + mathclass="binary", + mathname="pm", + unicodeslot=0x00B1, + }, + { + category="no", + cjkwd="a", + contextname="twosuperior", + description="SUPERSCRIPT TWO", + direction="en", + linebreak="ai", + specials={ "super", 0x0032 }, + unicodeslot=0x00B2, + }, + { + category="no", + cjkwd="a", + contextname="threesuperior", + description="SUPERSCRIPT THREE", + direction="en", + linebreak="ai", + specials={ "super", 0x0033 }, + unicodeslot=0x00B3, + }, + { + adobename="acute", + category="sk", + cjkwd="a", + contextname="textacute", + description="ACUTE ACCENT", + direction="on", + linebreak="bb", + mathclass="accent", + mathname="acute", + specials={ "compat", 0x0020, 0x0301 }, + unicodeslot=0x00B4, + }, + { + adobename="mu", + category="ll", + contextname="textmu", + description="MICRO SIGN", + direction="l", + linebreak="al", + specials={ "compat", 0x03BC }, + uccode=0x039C, + unicodeslot=0x00B5, + }, + { + adobename="paragraph", + category="so", + cjkwd="a", + contextname="paragraphmark", + description="PILCROW SIGN", + direction="on", + linebreak="ai", + mathclass="box", + mathname="P", + unicodeslot=0x00B6, + }, + { + adobename="periodcentered", + category="po", + cjkwd="a", + contextname="periodcentered", + description="MIDDLE DOT", + direction="on", + linebreak="ai", + mathclass="binary", + mathname="centerdot", + unicodeslot=0x00B7, + }, + { + adobename="cedilla", + category="sk", + cjkwd="a", + contextname="textcedilla", + description="CEDILLA", + direction="on", + linebreak="ai", + specials={ "compat", 0x0020, 0x0327 }, + unicodeslot=0x00B8, + }, + { + category="no", + cjkwd="a", + contextname="onesuperior", + description="SUPERSCRIPT ONE", + direction="en", + linebreak="ai", + specials={ "super", 0x0031 }, + unicodeslot=0x00B9, + }, + { + adobename="ordmasculine", + category="ll", + cjkwd="a", + contextname="ordmasculine", + description="MASCULINE ORDINAL INDICATOR", + direction="l", + linebreak="ai", + specials={ "super", 0x006F }, + unicodeslot=0x00BA, + }, + { + adobename="guillemotright", + category="pf", + contextname="rightguillemot", + description="RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK", + direction="on", + linebreak="qu", + mirror=0x00AB, + unicodeslot=0x00BB, + }, + { + adobename="onequarter", + category="no", + cjkwd="a", + contextname="onequarter", + description="VULGAR FRACTION ONE QUARTER", + direction="on", + linebreak="ai", + specials={ "fraction", 0x0031, 0x2044, 0x0034 }, + unicodeslot=0x00BC, + }, + { + adobename="onehalf", + category="no", + cjkwd="a", + contextname="onehalf", + description="VULGAR FRACTION ONE HALF", + direction="on", + linebreak="ai", + specials={ "fraction", 0x0031, 0x2044, 0x0032 }, + unicodeslot=0x00BD, + }, + { + adobename="threequarters", + category="no", + cjkwd="a", + contextname="threequarter", + description="VULGAR FRACTION THREE QUARTERS", + direction="on", + linebreak="ai", + specials={ "fraction", 0x0033, 0x2044, 0x0034 }, + unicodeslot=0x00BE, + }, + { + adobename="questiondown", + category="po", + cjkwd="a", + contextname="questiondown", + description="INVERTED QUESTION MARK", + direction="on", + linebreak="ai", + unicodeslot=0x00BF, + }, + { + adobename="Agrave", + category="lu", + contextname="Agrave", + description="LATIN CAPITAL LETTER A WITH GRAVE", + direction="l", + lccode=0x00E0, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x0041, 0x0300 }, + unicodeslot=0x00C0, + }, + { + adobename="Aacute", + category="lu", + contextname="Aacute", + description="LATIN CAPITAL LETTER A WITH ACUTE", + direction="l", + lccode=0x00E1, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x0041, 0x0301 }, + unicodeslot=0x00C1, + }, + { + adobename="Acircumflex", + category="lu", + contextname="Acircumflex", + description="LATIN CAPITAL LETTER A WITH CIRCUMFLEX", + direction="l", + lccode=0x00E2, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x0041, 0x0302 }, + unicodeslot=0x00C2, + }, + { + adobename="Atilde", + category="lu", + contextname="Atilde", + description="LATIN CAPITAL LETTER A WITH TILDE", + direction="l", + lccode=0x00E3, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x0041, 0x0303 }, + unicodeslot=0x00C3, + }, + { + adobename="Adieresis", + category="lu", + contextname="Adiaeresis", + description="LATIN CAPITAL LETTER A WITH DIAERESIS", + direction="l", + lccode=0x00E4, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x0041, 0x0308 }, + unicodeslot=0x00C4, + }, + { + adobename="Aring", + category="lu", + contextname="Aring", + description="LATIN CAPITAL LETTER A WITH RING ABOVE", + direction="l", + lccode=0x00E5, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x0041, 0x030A }, + unicodeslot=0x00C5, + }, + { + adobename="AE", + category="lu", + cjkwd="a", + contextname="AEligature", + description="LATIN CAPITAL LETTER AE", + direction="l", + lccode=0x00E6, + linebreak="al", + shcode={ 0x0041, 0x0045 }, + unicodeslot=0x00C6, + }, + { + adobename="Ccedilla", + category="lu", + contextname="Ccedilla", + description="LATIN CAPITAL LETTER C WITH CEDILLA", + direction="l", + lccode=0x00E7, + linebreak="al", + shcode=0x0043, + specials={ "char", 0x0043, 0x0327 }, + unicodeslot=0x00C7, + }, + { + adobename="Egrave", + category="lu", + contextname="Egrave", + description="LATIN CAPITAL LETTER E WITH GRAVE", + direction="l", + lccode=0x00E8, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x0045, 0x0300 }, + unicodeslot=0x00C8, + }, + { + adobename="Eacute", + category="lu", + contextname="Eacute", + description="LATIN CAPITAL LETTER E WITH ACUTE", + direction="l", + lccode=0x00E9, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x0045, 0x0301 }, + unicodeslot=0x00C9, + }, + { + adobename="Ecircumflex", + category="lu", + contextname="Ecircumflex", + description="LATIN CAPITAL LETTER E WITH CIRCUMFLEX", + direction="l", + lccode=0x00EA, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x0045, 0x0302 }, + unicodeslot=0x00CA, + }, + { + adobename="Edieresis", + category="lu", + contextname="Ediaeresis", + description="LATIN CAPITAL LETTER E WITH DIAERESIS", + direction="l", + lccode=0x00EB, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x0045, 0x0308 }, + unicodeslot=0x00CB, + }, + { + adobename="Igrave", + category="lu", + contextname="Igrave", + description="LATIN CAPITAL LETTER I WITH GRAVE", + direction="l", + lccode=0x00EC, + linebreak="al", + shcode=0x0049, + specials={ "char", 0x0049, 0x0300 }, + unicodeslot=0x00CC, + }, + { + adobename="Iacute", + category="lu", + contextname="Iacute", + description="LATIN CAPITAL LETTER I WITH ACUTE", + direction="l", + lccode=0x00ED, + linebreak="al", + shcode=0x0049, + specials={ "char", 0x0049, 0x0301 }, + unicodeslot=0x00CD, + }, + { + adobename="Icircumflex", + category="lu", + contextname="Icircumflex", + description="LATIN CAPITAL LETTER I WITH CIRCUMFLEX", + direction="l", + lccode=0x00EE, + linebreak="al", + shcode=0x0049, + specials={ "char", 0x0049, 0x0302 }, + unicodeslot=0x00CE, + }, + { + adobename="Idieresis", + category="lu", + contextname="Idiaeresis", + description="LATIN CAPITAL LETTER I WITH DIAERESIS", + direction="l", + lccode=0x00EF, + linebreak="al", + shcode=0x0049, + specials={ "char", 0x0049, 0x0308 }, + unicodeslot=0x00CF, + }, + { + adobename="Eth", + category="lu", + cjkwd="a", + contextname="Eth", + description="LATIN CAPITAL LETTER ETH", + direction="l", + lccode=0x00F0, + linebreak="al", + unicodeslot=0x00D0, + }, + { + adobename="Ntilde", + category="lu", + contextname="Ntilde", + description="LATIN CAPITAL LETTER N WITH TILDE", + direction="l", + lccode=0x00F1, + linebreak="al", + shcode=0x004E, + specials={ "char", 0x004E, 0x0303 }, + unicodeslot=0x00D1, + }, + { + adobename="Ograve", + category="lu", + contextname="Ograve", + description="LATIN CAPITAL LETTER O WITH GRAVE", + direction="l", + lccode=0x00F2, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x004F, 0x0300 }, + unicodeslot=0x00D2, + }, + { + adobename="Oacute", + category="lu", + contextname="Oacute", + description="LATIN CAPITAL LETTER O WITH ACUTE", + direction="l", + lccode=0x00F3, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x004F, 0x0301 }, + unicodeslot=0x00D3, + }, + { + adobename="Ocircumflex", + category="lu", + contextname="Ocircumflex", + description="LATIN CAPITAL LETTER O WITH CIRCUMFLEX", + direction="l", + lccode=0x00F4, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x004F, 0x0302 }, + unicodeslot=0x00D4, + }, + { + adobename="Otilde", + category="lu", + contextname="Otilde", + description="LATIN CAPITAL LETTER O WITH TILDE", + direction="l", + lccode=0x00F5, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x004F, 0x0303 }, + unicodeslot=0x00D5, + }, + { + adobename="Odieresis", + category="lu", + contextname="Odiaeresis", + description="LATIN CAPITAL LETTER O WITH DIAERESIS", + direction="l", + lccode=0x00F6, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x004F, 0x0308 }, + unicodeslot=0x00D6, + }, + { + adobename="multiply", + category="sm", + cjkwd="a", + contextname="textmultiply", + description="MULTIPLICATION SIGN", + direction="on", + linebreak="ai", + mathclass="binary", + mathname="times", + unicodeslot=0x00D7, + }, + { + adobename="Oslash", + category="lu", + cjkwd="a", + contextname="Ostroke", + description="LATIN CAPITAL LETTER O WITH STROKE", + direction="l", + lccode=0x00F8, + linebreak="al", + shcode=0x004F, + unicodeslot=0x00D8, + }, + { + adobename="Ugrave", + category="lu", + contextname="Ugrave", + description="LATIN CAPITAL LETTER U WITH GRAVE", + direction="l", + lccode=0x00F9, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x0055, 0x0300 }, + unicodeslot=0x00D9, + }, + { + adobename="Uacute", + category="lu", + contextname="Uacute", + description="LATIN CAPITAL LETTER U WITH ACUTE", + direction="l", + lccode=0x00FA, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x0055, 0x0301 }, + unicodeslot=0x00DA, + }, + { + adobename="Ucircumflex", + category="lu", + contextname="Ucircumflex", + description="LATIN CAPITAL LETTER U WITH CIRCUMFLEX", + direction="l", + lccode=0x00FB, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x0055, 0x0302 }, + unicodeslot=0x00DB, + }, + { + adobename="Udieresis", + category="lu", + contextname="Udiaeresis", + description="LATIN CAPITAL LETTER U WITH DIAERESIS", + direction="l", + lccode=0x00FC, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x0055, 0x0308 }, + unicodeslot=0x00DC, + }, + { + adobename="Yacute", + category="lu", + contextname="Yacute", + description="LATIN CAPITAL LETTER Y WITH ACUTE", + direction="l", + lccode=0x00FD, + linebreak="al", + shcode=0x0059, + specials={ "char", 0x0059, 0x0301 }, + unicodeslot=0x00DD, + }, + { + adobename="Thorn", + category="lu", + cjkwd="a", + contextname="Thorn", + description="LATIN CAPITAL LETTER THORN", + direction="l", + lccode=0x00FE, + linebreak="al", + unicodeslot=0x00DE, + }, + { + adobename="germandbls", + category="ll", + cjkwd="a", + contextname="ssharp", + description="LATIN SMALL LETTER SHARP S", + direction="l", + linebreak="al", + uccodes={ 0x0053, 0x0053 }, + unicodeslot=0x00DF, + }, + { + adobename="agrave", + category="ll", + cjkwd="a", + contextname="agrave", + description="LATIN SMALL LETTER A WITH GRAVE", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x0061, 0x0300 }, + uccode=0x00C0, + unicodeslot=0x00E0, + }, + { + adobename="aacute", + category="ll", + cjkwd="a", + contextname="aacute", + description="LATIN SMALL LETTER A WITH ACUTE", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x0061, 0x0301 }, + uccode=0x00C1, + unicodeslot=0x00E1, + }, + { + adobename="acircumflex", + category="ll", + contextname="acircumflex", + description="LATIN SMALL LETTER A WITH CIRCUMFLEX", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x0061, 0x0302 }, + uccode=0x00C2, + unicodeslot=0x00E2, + }, + { + adobename="atilde", + category="ll", + contextname="atilde", + description="LATIN SMALL LETTER A WITH TILDE", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x0061, 0x0303 }, + uccode=0x00C3, + unicodeslot=0x00E3, + }, + { + adobename="adieresis", + category="ll", + contextname="adiaeresis", + description="LATIN SMALL LETTER A WITH DIAERESIS", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x0061, 0x0308 }, + uccode=0x00C4, + unicodeslot=0x00E4, + }, + { + adobename="aring", + category="ll", + contextname="aring", + description="LATIN SMALL LETTER A WITH RING ABOVE", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x0061, 0x030A }, + uccode=0x00C5, + unicodeslot=0x00E5, + }, + { + adobename="ae", + category="ll", + cjkwd="a", + contextname="aeligature", + description="LATIN SMALL LETTER AE", + direction="l", + linebreak="al", + shcode={ 0x00E6, 0x00EA }, + uccode=0x00C6, + unicodeslot=0x00E6, + }, + { + adobename="ccedilla", + category="ll", + contextname="ccedilla", + description="LATIN SMALL LETTER C WITH CEDILLA", + direction="l", + linebreak="al", + shcode=0x0063, + specials={ "char", 0x0063, 0x0327 }, + uccode=0x00C7, + unicodeslot=0x00E7, + }, + { + adobename="egrave", + category="ll", + cjkwd="a", + contextname="egrave", + description="LATIN SMALL LETTER E WITH GRAVE", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x0065, 0x0300 }, + uccode=0x00C8, + unicodeslot=0x00E8, + }, + { + adobename="eacute", + category="ll", + cjkwd="a", + contextname="eacute", + description="LATIN SMALL LETTER E WITH ACUTE", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x0065, 0x0301 }, + uccode=0x00C9, + unicodeslot=0x00E9, + }, + { + adobename="ecircumflex", + category="ll", + cjkwd="a", + contextname="ecircumflex", + description="LATIN SMALL LETTER E WITH CIRCUMFLEX", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x0065, 0x0302 }, + uccode=0x00CA, + unicodeslot=0x00EA, + }, + { + adobename="edieresis", + category="ll", + contextname="ediaeresis", + description="LATIN SMALL LETTER E WITH DIAERESIS", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x0065, 0x0308 }, + uccode=0x00CB, + unicodeslot=0x00EB, + }, + { + adobename="igrave", + category="ll", + cjkwd="a", + contextname="igrave", + description="LATIN SMALL LETTER I WITH GRAVE", + direction="l", + linebreak="al", + shcode=0x0069, + specials={ "char", 0x0069, 0x0300 }, + uccode=0x00CC, + unicodeslot=0x00EC, + }, + { + adobename="iacute", + category="ll", + cjkwd="a", + contextname="iacute", + description="LATIN SMALL LETTER I WITH ACUTE", + direction="l", + linebreak="al", + shcode=0x0069, + specials={ "char", 0x0069, 0x0301 }, + uccode=0x00CD, + unicodeslot=0x00ED, + }, + { + adobename="icircumflex", + category="ll", + contextname="icircumflex", + description="LATIN SMALL LETTER I WITH CIRCUMFLEX", + direction="l", + linebreak="al", + shcode=0x0069, + specials={ "char", 0x0069, 0x0302 }, + uccode=0x00CE, + unicodeslot=0x00EE, + }, + { + adobename="idieresis", + category="ll", + contextname="idiaeresis", + description="LATIN SMALL LETTER I WITH DIAERESIS", + direction="l", + linebreak="al", + shcode=0x0069, + specials={ "char", 0x0069, 0x0308 }, + uccode=0x00CF, + unicodeslot=0x00EF, + }, + { + adobename="eth", + category="ll", + cjkwd="a", + --~ 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, + }, + { + adobename="ntilde", + category="ll", + contextname="ntilde", + description="LATIN SMALL LETTER N WITH TILDE", + direction="l", + linebreak="al", + shcode=0x006E, + specials={ "char", 0x006E, 0x0303 }, + uccode=0x00D1, + unicodeslot=0x00F1, + }, + { + adobename="ograve", + category="ll", + cjkwd="a", + contextname="ograve", + description="LATIN SMALL LETTER O WITH GRAVE", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x006F, 0x0300 }, + uccode=0x00D2, + unicodeslot=0x00F2, + }, + { + adobename="oacute", + category="ll", + cjkwd="a", + contextname="oacute", + description="LATIN SMALL LETTER O WITH ACUTE", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x006F, 0x0301 }, + uccode=0x00D3, + unicodeslot=0x00F3, + }, + { + adobename="ocircumflex", + category="ll", + contextname="ocircumflex", + description="LATIN SMALL LETTER O WITH CIRCUMFLEX", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x006F, 0x0302 }, + uccode=0x00D4, + unicodeslot=0x00F4, + }, + { + adobename="otilde", + category="ll", + contextname="otilde", + description="LATIN SMALL LETTER O WITH TILDE", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x006F, 0x0303 }, + uccode=0x00D5, + unicodeslot=0x00F5, + }, + { + adobename="odieresis", + category="ll", + contextname="odiaeresis", + description="LATIN SMALL LETTER O WITH DIAERESIS", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x006F, 0x0308 }, + uccode=0x00D6, + unicodeslot=0x00F6, + }, + { + adobename="divide", + category="sm", + cjkwd="a", + contextname="textdiv", + description="DIVISION SIGN", + direction="on", + linebreak="ai", + mathclass="binary", + mathname="div", + unicodeslot=0x00F7, + }, + { + adobename="oslash", + category="ll", + cjkwd="a", + contextname="ostroke", + description="LATIN SMALL LETTER O WITH STROKE", + direction="l", + linebreak="al", + shcode=0x006F, + uccode=0x00D8, + unicodeslot=0x00F8, + }, + { + adobename="ugrave", + category="ll", + cjkwd="a", + contextname="ugrave", + description="LATIN SMALL LETTER U WITH GRAVE", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x0075, 0x0300 }, + uccode=0x00D9, + unicodeslot=0x00F9, + }, + { + adobename="uacute", + category="ll", + cjkwd="a", + contextname="uacute", + description="LATIN SMALL LETTER U WITH ACUTE", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x0075, 0x0301 }, + uccode=0x00DA, + unicodeslot=0x00FA, + }, + { + adobename="ucircumflex", + category="ll", + contextname="ucircumflex", + description="LATIN SMALL LETTER U WITH CIRCUMFLEX", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x0075, 0x0302 }, + uccode=0x00DB, + unicodeslot=0x00FB, + }, + { + adobename="udieresis", + category="ll", + cjkwd="a", + contextname="udiaeresis", + description="LATIN SMALL LETTER U WITH DIAERESIS", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x0075, 0x0308 }, + uccode=0x00DC, + unicodeslot=0x00FC, + }, + { + adobename="yacute", + category="ll", + contextname="yacute", + description="LATIN SMALL LETTER Y WITH ACUTE", + direction="l", + linebreak="al", + shcode=0x0079, + specials={ "char", 0x0079, 0x0301 }, + uccode=0x00DD, + unicodeslot=0x00FD, + }, + { + adobename="thorn", + category="ll", + cjkwd="a", + contextname="thorn", + description="LATIN SMALL LETTER THORN", + direction="l", + linebreak="al", + uccode=0x00DE, + unicodeslot=0x00FE, + }, + { + adobename="ydieresis", + category="ll", + contextname="ydiaeresis", + description="LATIN SMALL LETTER Y WITH DIAERESIS", + direction="l", + linebreak="al", + shcode=0x0079, + specials={ "char", 0x0079, 0x0308 }, + uccode=0x0178, + unicodeslot=0x00FF, + }, + { + adobename="Amacron", + category="lu", + contextname="Amacron", + description="LATIN CAPITAL LETTER A WITH MACRON", + direction="l", + lccode=0x0101, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x0041, 0x0304 }, + unicodeslot=0x0100, + }, + { + adobename="amacron", + category="ll", + cjkwd="a", + contextname="amacron", + description="LATIN SMALL LETTER A WITH MACRON", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x0061, 0x0304 }, + uccode=0x0100, + unicodeslot=0x0101, + }, + { + adobename="Abreve", + category="lu", + contextname="Abreve", + description="LATIN CAPITAL LETTER A WITH BREVE", + direction="l", + lccode=0x0103, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x0041, 0x0306 }, + unicodeslot=0x0102, + }, + { + adobename="abreve", + category="ll", + contextname="abreve", + description="LATIN SMALL LETTER A WITH BREVE", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x0061, 0x0306 }, + uccode=0x0102, + unicodeslot=0x0103, + }, + { + adobename="Aogonek", + category="lu", + contextname="Aogonek", + description="LATIN CAPITAL LETTER A WITH OGONEK", + direction="l", + lccode=0x0105, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x0041, 0x0328 }, + unicodeslot=0x0104, + }, + { + adobename="aogonek", + category="ll", + contextname="aogonek", + description="LATIN SMALL LETTER A WITH OGONEK", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x0061, 0x0328 }, + uccode=0x0104, + unicodeslot=0x0105, + }, + { + adobename="Cacute", + category="lu", + contextname="Cacute", + description="LATIN CAPITAL LETTER C WITH ACUTE", + direction="l", + lccode=0x0107, + linebreak="al", + shcode=0x0043, + specials={ "char", 0x0043, 0x0301 }, + unicodeslot=0x0106, + }, + { + adobename="cacute", + category="ll", + contextname="cacute", + description="LATIN SMALL LETTER C WITH ACUTE", + direction="l", + linebreak="al", + shcode=0x0063, + specials={ "char", 0x0063, 0x0301 }, + uccode=0x0106, + unicodeslot=0x0107, + }, + { + adobename="Ccircumflex", + category="lu", + contextname="Ccircumflex", + description="LATIN CAPITAL LETTER C WITH CIRCUMFLEX", + direction="l", + lccode=0x0109, + linebreak="al", + shcode=0x0043, + specials={ "char", 0x0043, 0x0302 }, + unicodeslot=0x0108, + }, + { + adobename="ccircumflex", + category="ll", + contextname="ccircumflex", + description="LATIN SMALL LETTER C WITH CIRCUMFLEX", + direction="l", + linebreak="al", + shcode=0x0063, + specials={ "char", 0x0063, 0x0302 }, + uccode=0x0108, + unicodeslot=0x0109, + }, + { + adobename="Cdotaccent", + category="lu", + contextname="Cdotaccent", + description="LATIN CAPITAL LETTER C WITH DOT ABOVE", + direction="l", + lccode=0x010B, + linebreak="al", + shcode=0x0043, + specials={ "char", 0x0043, 0x0307 }, + unicodeslot=0x010A, + }, + { + adobename="cdotaccent", + category="ll", + contextname="cdotaccent", + description="LATIN SMALL LETTER C WITH DOT ABOVE", + direction="l", + linebreak="al", + shcode=0x0063, + specials={ "char", 0x0063, 0x0307 }, + uccode=0x010A, + unicodeslot=0x010B, + }, + { + adobename="Ccaron", + category="lu", + contextname="Ccaron", + description="LATIN CAPITAL LETTER C WITH CARON", + direction="l", + lccode=0x010D, + linebreak="al", + shcode=0x0043, + specials={ "char", 0x0043, 0x030C }, + unicodeslot=0x010C, + }, + { + adobename="ccaron", + category="ll", + contextname="ccaron", + description="LATIN SMALL LETTER C WITH CARON", + direction="l", + linebreak="al", + shcode=0x0063, + specials={ "char", 0x0063, 0x030C }, + uccode=0x010C, + unicodeslot=0x010D, + }, + { + adobename="Dcaron", + category="lu", + contextname="Dcaron", + description="LATIN CAPITAL LETTER D WITH CARON", + direction="l", + lccode=0x010F, + linebreak="al", + shcode=0x0044, + specials={ "char", 0x0044, 0x030C }, + unicodeslot=0x010E, + }, + { + adobename="dcaron", + category="ll", + contextname="dcaron", + description="LATIN SMALL LETTER D WITH CARON", + direction="l", + linebreak="al", + shcode=0x0064, + specials={ "char", 0x0064, 0x030C }, + uccode=0x010E, + unicodeslot=0x010F, + }, + { + adobename="Dcroat", + category="lu", + contextname="Dstroke", + description="LATIN CAPITAL LETTER D WITH STROKE", + direction="l", + lccode=0x0111, + linebreak="al", + shcode=0x0044, + unicodeslot=0x0110, + }, + { + adobename="dcroat", + category="ll", + cjkwd="a", + contextname="dstroke", + description="LATIN SMALL LETTER D WITH STROKE", + direction="l", + linebreak="al", + shcode=0x0064, + uccode=0x0110, + unicodeslot=0x0111, + }, + { + adobename="Emacron", + category="lu", + contextname="Emacron", + description="LATIN CAPITAL LETTER E WITH MACRON", + direction="l", + lccode=0x0113, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x0045, 0x0304 }, + unicodeslot=0x0112, + }, + { + adobename="emacron", + category="ll", + cjkwd="a", + contextname="emacron", + description="LATIN SMALL LETTER E WITH MACRON", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x0065, 0x0304 }, + uccode=0x0112, + unicodeslot=0x0113, + }, + { + adobename="Ebreve", + category="lu", + contextname="Ebreve", + description="LATIN CAPITAL LETTER E WITH BREVE", + direction="l", + lccode=0x0115, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x0045, 0x0306 }, + unicodeslot=0x0114, + }, + { + adobename="ebreve", + category="ll", + contextname="ebreve", + description="LATIN SMALL LETTER E WITH BREVE", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x0065, 0x0306 }, + uccode=0x0114, + unicodeslot=0x0115, + }, + { + adobename="Edotaccent", + category="lu", + contextname="Edotaccent", + description="LATIN CAPITAL LETTER E WITH DOT ABOVE", + direction="l", + lccode=0x0117, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x0045, 0x0307 }, + unicodeslot=0x0116, + }, + { + adobename="edotaccent", + category="ll", + contextname="edotaccent", + description="LATIN SMALL LETTER E WITH DOT ABOVE", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x0065, 0x0307 }, + uccode=0x0116, + unicodeslot=0x0117, + }, + { + adobename="Eogonek", + category="lu", + contextname="Eogonek", + description="LATIN CAPITAL LETTER E WITH OGONEK", + direction="l", + lccode=0x0119, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x0045, 0x0328 }, + unicodeslot=0x0118, + }, + { + adobename="eogonek", + category="ll", + contextname="eogonek", + description="LATIN SMALL LETTER E WITH OGONEK", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x0065, 0x0328 }, + uccode=0x0118, + unicodeslot=0x0119, + }, + { + adobename="Ecaron", + category="lu", + contextname="Ecaron", + description="LATIN CAPITAL LETTER E WITH CARON", + direction="l", + lccode=0x011B, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x0045, 0x030C }, + unicodeslot=0x011A, + }, + { + adobename="ecaron", + category="ll", + cjkwd="a", + contextname="ecaron", + description="LATIN SMALL LETTER E WITH CARON", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x0065, 0x030C }, + uccode=0x011A, + unicodeslot=0x011B, + }, + { + adobename="Gcircumflex", + category="lu", + contextname="Gcircumflex", + description="LATIN CAPITAL LETTER G WITH CIRCUMFLEX", + direction="l", + lccode=0x011D, + linebreak="al", + shcode=0x0047, + specials={ "char", 0x0047, 0x0302 }, + unicodeslot=0x011C, + }, + { + adobename="gcircumflex", + category="ll", + contextname="gcircumflex", + description="LATIN SMALL LETTER G WITH CIRCUMFLEX", + direction="l", + linebreak="al", + shcode=0x0067, + specials={ "char", 0x0067, 0x0302 }, + uccode=0x011C, + unicodeslot=0x011D, + }, + { + adobename="Gbreve", + category="lu", + contextname="Gbreve", + description="LATIN CAPITAL LETTER G WITH BREVE", + direction="l", + lccode=0x011F, + linebreak="al", + shcode=0x0047, + specials={ "char", 0x0047, 0x0306 }, + unicodeslot=0x011E, + }, + { + adobename="gbreve", + category="ll", + contextname="gbreve", + description="LATIN SMALL LETTER G WITH BREVE", + direction="l", + linebreak="al", + shcode=0x0067, + specials={ "char", 0x0067, 0x0306 }, + uccode=0x011E, + unicodeslot=0x011F, + }, + { + adobename="Gdotaccent", + category="lu", + contextname="Gdotaccent", + description="LATIN CAPITAL LETTER G WITH DOT ABOVE", + direction="l", + lccode=0x0121, + linebreak="al", + shcode=0x0047, + specials={ "char", 0x0047, 0x0307 }, + unicodeslot=0x0120, + }, + { + adobename="gdotaccent", + category="ll", + contextname="gdotaccent", + description="LATIN SMALL LETTER G WITH DOT ABOVE", + direction="l", + linebreak="al", + shcode=0x0067, + specials={ "char", 0x0067, 0x0307 }, + uccode=0x0120, + unicodeslot=0x0121, + }, + { + adobename="Gcommaaccent", + category="lu", + contextname="Gcommaaccent", + description="LATIN CAPITAL LETTER G WITH CEDILLA", + direction="l", + lccode=0x0123, + linebreak="al", + shcode=0x0047, + specials={ "char", 0x0047, 0x0327 }, + unicodeslot=0x0122, + }, + { + adobename="gcommaaccent", + category="ll", + contextname="gcommaaccent", + description="LATIN SMALL LETTER G WITH CEDILLA", + direction="l", + linebreak="al", + shcode=0x0067, + specials={ "char", 0x0067, 0x0327 }, + uccode=0x0122, + unicodeslot=0x0123, + }, + { + adobename="Hcircumflex", + category="lu", + contextname="Hcircumflex", + description="LATIN CAPITAL LETTER H WITH CIRCUMFLEX", + direction="l", + lccode=0x0125, + linebreak="al", + shcode=0x0048, + specials={ "char", 0x0048, 0x0302 }, + unicodeslot=0x0124, + }, + { + adobename="hcircumflex", + category="ll", + contextname="hcircumflex", + description="LATIN SMALL LETTER H WITH CIRCUMFLEX", + direction="l", + linebreak="al", + shcode=0x0068, + specials={ "char", 0x0068, 0x0302 }, + uccode=0x0124, + unicodeslot=0x0125, + }, + { + adobename="Hbar", + category="lu", + cjkwd="a", + contextname="Hstroke", + description="LATIN CAPITAL LETTER H WITH STROKE", + direction="l", + lccode=0x0127, + linebreak="al", + shcode=0x0048, + unicodeslot=0x0126, + }, + { + adobename="hbar", + category="ll", + cjkwd="a", + contextname="hstroke", + description="LATIN SMALL LETTER H WITH STROKE", + direction="l", + linebreak="al", + mathclass="ord", + mathname="hbar", + shcode=0x0068, + uccode=0x0126, + unicodeslot=0x0127, + }, + { + adobename="Itilde", + category="lu", + contextname="Itilde", + description="LATIN CAPITAL LETTER I WITH TILDE", + direction="l", + lccode=0x0129, + linebreak="al", + shcode=0x0049, + specials={ "char", 0x0049, 0x0303 }, + unicodeslot=0x0128, + }, + { + adobename="itilde", + category="ll", + contextname="itilde", + description="LATIN SMALL LETTER I WITH TILDE", + direction="l", + linebreak="al", + shcode=0x0069, + specials={ "char", 0x0069, 0x0303 }, + uccode=0x0128, + unicodeslot=0x0129, + }, + { + adobename="Imacron", + category="lu", + contextname="Imacron", + description="LATIN CAPITAL LETTER I WITH MACRON", + direction="l", + lccode=0x012B, + linebreak="al", + shcode=0x0049, + specials={ "char", 0x0049, 0x0304 }, + unicodeslot=0x012A, + }, + { + adobename="imacron", + category="ll", + cjkwd="a", + contextname="imacron", + description="LATIN SMALL LETTER I WITH MACRON", + direction="l", + linebreak="al", + shcode=0x0069, + specials={ "char", 0x0069, 0x0304 }, + uccode=0x012A, + unicodeslot=0x012B, + }, + { + adobename="Ibreve", + category="lu", + contextname="Ibreve", + description="LATIN CAPITAL LETTER I WITH BREVE", + direction="l", + lccode=0x012D, + linebreak="al", + shcode=0x0049, + specials={ "char", 0x0049, 0x0306 }, + unicodeslot=0x012C, + }, + { + adobename="ibreve", + category="ll", + contextname="ibreve", + description="LATIN SMALL LETTER I WITH BREVE", + direction="l", + linebreak="al", + shcode=0x0069, + specials={ "char", 0x0069, 0x0306 }, + uccode=0x012C, + unicodeslot=0x012D, + }, + { + adobename="Iogonek", + category="lu", + contextname="Iogonek", + description="LATIN CAPITAL LETTER I WITH OGONEK", + direction="l", + lccode=0x012F, + linebreak="al", + shcode=0x0049, + specials={ "char", 0x0049, 0x0328 }, + unicodeslot=0x012E, + }, + { + adobename="iogonek", + category="ll", + contextname="iogonek", + description="LATIN SMALL LETTER I WITH OGONEK", + direction="l", + linebreak="al", + shcode=0x0069, + specials={ "char", 0x0069, 0x0328 }, + uccode=0x012E, + unicodeslot=0x012F, + }, + { + adobename="Idotaccent", + category="lu", + contextname="Idotaccent", + description="LATIN CAPITAL LETTER I WITH DOT ABOVE", + direction="l", + lccode=0x0069, + linebreak="al", + shcode=0x0049, + specials={ "char", 0x0049, 0x0307 }, + unicodeslot=0x0130, + }, + { + adobename="dotlessi", + category="ll", + cjkwd="a", + contextname="dotlessi", + description="LATIN SMALL LETTER DOTLESS I", + direction="l", + linebreak="al", + uccode=0x0049, + unicodeslot=0x0131, + }, + { + adobename="IJ", + category="lu", + cjkwd="a", + contextname="IJligature", + description="LATIN CAPITAL LIGATURE IJ", + direction="l", + lccode=0x0133, + linebreak="al", + shcode={ 0x0049, 0x004A }, + specials={ "compat", 0x0049, 0x004A }, + unicodeslot=0x0132, + }, + { + adobename="ij", + category="ll", + cjkwd="a", + contextname="ijligature", + description="LATIN SMALL LIGATURE IJ", + direction="l", + linebreak="al", + shcode={ 0x0069, 0x006A }, + specials={ "compat", 0x0069, 0x006A }, + uccode=0x0132, + unicodeslot=0x0133, + }, + { + adobename="Jcircumflex", + category="lu", + contextname="Jcircumflex", + description="LATIN CAPITAL LETTER J WITH CIRCUMFLEX", + direction="l", + lccode=0x0135, + linebreak="al", + shcode=0x004A, + specials={ "char", 0x004A, 0x0302 }, + unicodeslot=0x0134, + }, + { + adobename="jcircumflex", + category="ll", + contextname="jcircumflex", + description="LATIN SMALL LETTER J WITH CIRCUMFLEX", + direction="l", + linebreak="al", + shcode=0x006A, + specials={ "char", 0x006A, 0x0302 }, + uccode=0x0134, + unicodeslot=0x0135, + }, + { + adobename="Kcommaaccent", + category="lu", + contextname="Kcommaaccent", + description="LATIN CAPITAL LETTER K WITH CEDILLA", + direction="l", + lccode=0x0137, + linebreak="al", + shcode=0x004B, + specials={ "char", 0x004B, 0x0327 }, + unicodeslot=0x0136, + }, + { + adobename="kcommaaccent", + category="ll", + contextname="kcommaaccent", + description="LATIN SMALL LETTER K WITH CEDILLA", + direction="l", + linebreak="al", + shcode=0x006B, + specials={ "char", 0x006B, 0x0327 }, + uccode=0x0136, + unicodeslot=0x0137, + }, + { + adobename="kgreenlandic", + category="ll", + cjkwd="a", + contextname="kkra", + description="LATIN SMALL LETTER KRA", + direction="l", + linebreak="al", + unicodeslot=0x0138, + }, + { + adobename="Lacute", + category="lu", + contextname="Lacute", + description="LATIN CAPITAL LETTER L WITH ACUTE", + direction="l", + lccode=0x013A, + linebreak="al", + shcode=0x004C, + specials={ "char", 0x004C, 0x0301 }, + unicodeslot=0x0139, + }, + { + adobename="lacute", + category="ll", + contextname="lacute", + description="LATIN SMALL LETTER L WITH ACUTE", + direction="l", + linebreak="al", + shcode=0x006C, + specials={ "char", 0x006C, 0x0301 }, + uccode=0x0139, + unicodeslot=0x013A, + }, + { + adobename="Lcommaaccent", + category="lu", + contextname="Lcommaaccent", + description="LATIN CAPITAL LETTER L WITH CEDILLA", + direction="l", + lccode=0x013C, + linebreak="al", + shcode=0x004C, + specials={ "char", 0x004C, 0x0327 }, + unicodeslot=0x013B, + }, + { + adobename="lcommaaccent", + category="ll", + contextname="lcommaaccent", + description="LATIN SMALL LETTER L WITH CEDILLA", + direction="l", + linebreak="al", + shcode=0x006C, + specials={ "char", 0x006C, 0x0327 }, + uccode=0x013B, + unicodeslot=0x013C, + }, + { + adobename="Lcaron", + category="lu", + contextname="Lcaron", + description="LATIN CAPITAL LETTER L WITH CARON", + direction="l", + lccode=0x013E, + linebreak="al", + shcode=0x004C, + specials={ "char", 0x004C, 0x030C }, + unicodeslot=0x013D, + }, + { + adobename="lcaron", + category="ll", + contextname="lcaron", + description="LATIN SMALL LETTER L WITH CARON", + direction="l", + linebreak="al", + shcode=0x006C, + specials={ "char", 0x006C, 0x030C }, + uccode=0x013D, + unicodeslot=0x013E, + }, + { + adobename="Ldot", + category="lu", + cjkwd="a", + contextname="Ldotmiddle", + description="LATIN CAPITAL LETTER L WITH MIDDLE DOT", + direction="l", + lccode=0x0140, + linebreak="al", + shcode=0x004C, + specials={ "compat", 0x004C, 0x00B7 }, + unicodeslot=0x013F, + }, + { + adobename="ldot", + category="ll", + cjkwd="a", + contextname="ldotmiddle", + description="LATIN SMALL LETTER L WITH MIDDLE DOT", + direction="l", + linebreak="al", + shcode=0x006C, + specials={ "compat", 0x006C, 0x00B7 }, + uccode=0x013F, + unicodeslot=0x0140, + }, + { + adobename="Lslash", + category="lu", + cjkwd="a", + contextname="Lstroke", + description="LATIN CAPITAL LETTER L WITH STROKE", + direction="l", + lccode=0x0142, + linebreak="al", + shcode=0x004C, + unicodeslot=0x0141, + }, + { + adobename="lslash", + category="ll", + cjkwd="a", + contextname="lstroke", + description="LATIN SMALL LETTER L WITH STROKE", + direction="l", + linebreak="al", + shcode=0x006C, + uccode=0x0141, + unicodeslot=0x0142, + }, + { + adobename="Nacute", + category="lu", + contextname="Nacute", + description="LATIN CAPITAL LETTER N WITH ACUTE", + direction="l", + lccode=0x0144, + linebreak="al", + shcode=0x004E, + specials={ "char", 0x004E, 0x0301 }, + unicodeslot=0x0143, + }, + { + adobename="nacute", + category="ll", + cjkwd="a", + contextname="nacute", + description="LATIN SMALL LETTER N WITH ACUTE", + direction="l", + linebreak="al", + shcode=0x006E, + specials={ "char", 0x006E, 0x0301 }, + uccode=0x0143, + unicodeslot=0x0144, + }, + { + adobename="Ncommaaccent", + category="lu", + contextname="Ncommaaccent", + description="LATIN CAPITAL LETTER N WITH CEDILLA", + direction="l", + lccode=0x0146, + linebreak="al", + shcode=0x004E, + specials={ "char", 0x004E, 0x0327 }, + unicodeslot=0x0145, + }, + { + adobename="ncommaaccent", + category="ll", + contextname="ncommaaccent", + description="LATIN SMALL LETTER N WITH CEDILLA", + direction="l", + linebreak="al", + shcode=0x006E, + specials={ "char", 0x006E, 0x0327 }, + uccode=0x0145, + unicodeslot=0x0146, + }, + { + adobename="Ncaron", + category="lu", + contextname="Ncaron", + description="LATIN CAPITAL LETTER N WITH CARON", + direction="l", + lccode=0x0148, + linebreak="al", + shcode=0x004E, + specials={ "char", 0x004E, 0x030C }, + unicodeslot=0x0147, + }, + { + adobename="ncaron", + category="ll", + cjkwd="a", + contextname="ncaron", + description="LATIN SMALL LETTER N WITH CARON", + direction="l", + linebreak="al", + shcode=0x006E, + specials={ "char", 0x006E, 0x030C }, + uccode=0x0147, + unicodeslot=0x0148, + }, + { + adobename="napostrophe", + category="ll", + cjkwd="a", + contextname="napostrophe", + description="LATIN SMALL LETTER N PRECEDED BY APOSTROPHE", + direction="l", + linebreak="al", + specials={ "compat", 0x02BC, 0x006E }, + unicodeslot=0x0149, + }, + { + adobename="Eng", + category="lu", + cjkwd="a", + contextname="Neng", + description="LATIN CAPITAL LETTER ENG", + direction="l", + lccode=0x014B, + linebreak="al", + unicodeslot=0x014A, + }, + { + adobename="eng", + category="ll", + cjkwd="a", + contextname="neng", + description="LATIN SMALL LETTER ENG", + direction="l", + linebreak="al", + uccode=0x014A, + unicodeslot=0x014B, + }, + { + adobename="Omacron", + category="lu", + contextname="Omacron", + description="LATIN CAPITAL LETTER O WITH MACRON", + direction="l", + lccode=0x014D, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x004F, 0x0304 }, + unicodeslot=0x014C, + }, + { + adobename="omacron", + category="ll", + cjkwd="a", + contextname="omacron", + description="LATIN SMALL LETTER O WITH MACRON", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x006F, 0x0304 }, + uccode=0x014C, + unicodeslot=0x014D, + }, + { + adobename="Obreve", + category="lu", + contextname="Obreve", + description="LATIN CAPITAL LETTER O WITH BREVE", + direction="l", + lccode=0x014F, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x004F, 0x0306 }, + unicodeslot=0x014E, + }, + { + adobename="obreve", + category="ll", + contextname="obreve", + description="LATIN SMALL LETTER O WITH BREVE", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x006F, 0x0306 }, + uccode=0x014E, + unicodeslot=0x014F, + }, + { + adobename="Ohungarumlaut", + category="lu", + contextname="Ohungarumlaut", + description="LATIN CAPITAL LETTER O WITH DOUBLE ACUTE", + direction="l", + lccode=0x0151, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x004F, 0x030B }, + unicodeslot=0x0150, + }, + { + adobename="ohungarumlaut", + category="ll", + contextname="ohungarumlaut", + description="LATIN SMALL LETTER O WITH DOUBLE ACUTE", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x006F, 0x030B }, + uccode=0x0150, + unicodeslot=0x0151, + }, + { + adobename="OE", + category="lu", + cjkwd="a", + contextname="OEligature", + description="LATIN CAPITAL LIGATURE OE", + direction="l", + lccode=0x0153, + linebreak="al", + shcode={ 0x004F, 0x0045 }, + unicodeslot=0x0152, + }, + { + adobename="oe", + category="ll", + cjkwd="a", + contextname="oeligature", + description="LATIN SMALL LIGATURE OE", + direction="l", + linebreak="al", + shcode={ 0x006F, 0x0065 }, + uccode=0x0152, + unicodeslot=0x0153, + }, + { + adobename="Racute", + category="lu", + contextname="Racute", + description="LATIN CAPITAL LETTER R WITH ACUTE", + direction="l", + lccode=0x0155, + linebreak="al", + shcode=0x0052, + specials={ "char", 0x0052, 0x0301 }, + unicodeslot=0x0154, + }, + { + adobename="racute", + category="ll", + contextname="racute", + description="LATIN SMALL LETTER R WITH ACUTE", + direction="l", + linebreak="al", + shcode=0x0072, + specials={ "char", 0x0072, 0x0301 }, + uccode=0x0154, + unicodeslot=0x0155, + }, + { + adobename="Rcommaaccent", + category="lu", + contextname="Rcommaaccent", + description="LATIN CAPITAL LETTER R WITH CEDILLA", + direction="l", + lccode=0x0157, + linebreak="al", + shcode=0x0052, + specials={ "char", 0x0052, 0x0327 }, + unicodeslot=0x0156, + }, + { + adobename="rcommaaccent", + category="ll", + contextname="rcommaaccent", + description="LATIN SMALL LETTER R WITH CEDILLA", + direction="l", + linebreak="al", + shcode=0x0072, + specials={ "char", 0x0072, 0x0327 }, + uccode=0x0156, + unicodeslot=0x0157, + }, + { + adobename="Rcaron", + category="lu", + contextname="Rcaron", + description="LATIN CAPITAL LETTER R WITH CARON", + direction="l", + lccode=0x0159, + linebreak="al", + shcode=0x0052, + specials={ "char", 0x0052, 0x030C }, + unicodeslot=0x0158, + }, + { + adobename="rcaron", + category="ll", + contextname="rcaron", + description="LATIN SMALL LETTER R WITH CARON", + direction="l", + linebreak="al", + shcode=0x0072, + specials={ "char", 0x0072, 0x030C }, + uccode=0x0158, + unicodeslot=0x0159, + }, + { + adobename="Sacute", + category="lu", + contextname="Sacute", + description="LATIN CAPITAL LETTER S WITH ACUTE", + direction="l", + lccode=0x015B, + linebreak="al", + shcode=0x0053, + specials={ "char", 0x0053, 0x0301 }, + unicodeslot=0x015A, + }, + { + adobename="sacute", + category="ll", + contextname="sacute", + description="LATIN SMALL LETTER S WITH ACUTE", + direction="l", + linebreak="al", + shcode=0x0073, + specials={ "char", 0x0073, 0x0301 }, + uccode=0x015A, + unicodeslot=0x015B, + }, + { + adobename="Scircumflex", + category="lu", + contextname="Scircumflex", + description="LATIN CAPITAL LETTER S WITH CIRCUMFLEX", + direction="l", + lccode=0x015D, + linebreak="al", + shcode=0x0053, + specials={ "char", 0x0053, 0x0302 }, + unicodeslot=0x015C, + }, + { + adobename="scircumflex", + category="ll", + contextname="scircumflex", + description="LATIN SMALL LETTER S WITH CIRCUMFLEX", + direction="l", + linebreak="al", + shcode=0x0073, + specials={ "char", 0x0073, 0x0302 }, + uccode=0x015C, + unicodeslot=0x015D, + }, + { + adobename="Scedilla", + category="lu", + contextname="Scedilla", + description="LATIN CAPITAL LETTER S WITH CEDILLA", + direction="l", + lccode=0x015F, + linebreak="al", + shcode=0x0053, + specials={ "char", 0x0053, 0x0327 }, + unicodeslot=0x015E, + }, + { + adobename="scedilla", + category="ll", + contextname="scedilla", + description="LATIN SMALL LETTER S WITH CEDILLA", + direction="l", + linebreak="al", + shcode=0x0073, + specials={ "char", 0x0073, 0x0327 }, + uccode=0x015E, + unicodeslot=0x015F, + }, + { + adobename="Scaron", + category="lu", + contextname="Scaron", + description="LATIN CAPITAL LETTER S WITH CARON", + direction="l", + lccode=0x0161, + linebreak="al", + shcode=0x0053, + specials={ "char", 0x0053, 0x030C }, + unicodeslot=0x0160, + }, + { + adobename="scaron", + category="ll", + contextname="scaron", + description="LATIN SMALL LETTER S WITH CARON", + direction="l", + linebreak="al", + shcode=0x0073, + specials={ "char", 0x0073, 0x030C }, + uccode=0x0160, + unicodeslot=0x0161, + }, + { + adobename="Tcommaaccent", + category="lu", + contextname="Tcedilla", + description="LATIN CAPITAL LETTER T WITH CEDILLA", + direction="l", + lccode=0x0163, + linebreak="al", + shcode=0x0054, + specials={ "char", 0x0054, 0x0327 }, + unicodeslot=0x0162, + }, + { + adobename="tcommaaccent", + category="ll", + contextname="tcedilla", + description="LATIN SMALL LETTER T WITH CEDILLA", + direction="l", + linebreak="al", + shcode=0x0074, + specials={ "char", 0x0074, 0x0327 }, + uccode=0x0162, + unicodeslot=0x0163, + }, + { + adobename="Tcaron", + category="lu", + contextname="Tcaron", + description="LATIN CAPITAL LETTER T WITH CARON", + direction="l", + lccode=0x0165, + linebreak="al", + shcode=0x0054, + specials={ "char", 0x0054, 0x030C }, + unicodeslot=0x0164, + }, + { + adobename="tcaron", + category="ll", + contextname="tcaron", + description="LATIN SMALL LETTER T WITH CARON", + direction="l", + linebreak="al", + shcode=0x0074, + specials={ "char", 0x0074, 0x030C }, + uccode=0x0164, + unicodeslot=0x0165, + }, + { + adobename="Tbar", + category="lu", + cjkwd="a", + contextname="Tstroke", + description="LATIN CAPITAL LETTER T WITH STROKE", + direction="l", + lccode=0x0167, + linebreak="al", + shcode=0x0054, + unicodeslot=0x0166, + }, + { + adobename="tbar", + category="ll", + cjkwd="a", + contextname="tstroke", + description="LATIN SMALL LETTER T WITH STROKE", + direction="l", + linebreak="al", + shcode=0x0074, + uccode=0x0166, + unicodeslot=0x0167, + }, + { + adobename="Utilde", + category="lu", + contextname="Utilde", + description="LATIN CAPITAL LETTER U WITH TILDE", + direction="l", + lccode=0x0169, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x0055, 0x0303 }, + unicodeslot=0x0168, + }, + { + adobename="utilde", + category="ll", + contextname="utilde", + description="LATIN SMALL LETTER U WITH TILDE", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x0075, 0x0303 }, + uccode=0x0168, + unicodeslot=0x0169, + }, + { + adobename="Umacron", + category="lu", + contextname="Umacron", + description="LATIN CAPITAL LETTER U WITH MACRON", + direction="l", + lccode=0x016B, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x0055, 0x0304 }, + unicodeslot=0x016A, + }, + { + adobename="umacron", + category="ll", + cjkwd="a", + contextname="umacron", + description="LATIN SMALL LETTER U WITH MACRON", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x0075, 0x0304 }, + uccode=0x016A, + unicodeslot=0x016B, + }, + { + adobename="Ubreve", + category="lu", + contextname="Ubreve", + description="LATIN CAPITAL LETTER U WITH BREVE", + direction="l", + lccode=0x016D, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x0055, 0x0306 }, + unicodeslot=0x016C, + }, + { + adobename="ubreve", + category="ll", + contextname="ubreve", + description="LATIN SMALL LETTER U WITH BREVE", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x0075, 0x0306 }, + uccode=0x016C, + unicodeslot=0x016D, + }, + { + adobename="Uring", + category="lu", + contextname="Uring", + description="LATIN CAPITAL LETTER U WITH RING ABOVE", + direction="l", + lccode=0x016F, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x0055, 0x030A }, + unicodeslot=0x016E, + }, + { + adobename="uring", + category="ll", + contextname="uring", + description="LATIN SMALL LETTER U WITH RING ABOVE", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x0075, 0x030A }, + uccode=0x016E, + unicodeslot=0x016F, + }, + { + adobename="Uhungarumlaut", + category="lu", + contextname="Uhungarumlaut", + description="LATIN CAPITAL LETTER U WITH DOUBLE ACUTE", + direction="l", + lccode=0x0171, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x0055, 0x030B }, + unicodeslot=0x0170, + }, + { + adobename="uhungarumlaut", + category="ll", + contextname="uhungarumlaut", + description="LATIN SMALL LETTER U WITH DOUBLE ACUTE", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x0075, 0x030B }, + uccode=0x0170, + unicodeslot=0x0171, + }, + { + adobename="Uogonek", + category="lu", + contextname="Uogonek", + description="LATIN CAPITAL LETTER U WITH OGONEK", + direction="l", + lccode=0x0173, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x0055, 0x0328 }, + unicodeslot=0x0172, + }, + { + adobename="uogonek", + category="ll", + contextname="uogonek", + description="LATIN SMALL LETTER U WITH OGONEK", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x0075, 0x0328 }, + uccode=0x0172, + unicodeslot=0x0173, + }, + { + adobename="Wcircumflex", + category="lu", + contextname="Wcircumflex", + description="LATIN CAPITAL LETTER W WITH CIRCUMFLEX", + direction="l", + lccode=0x0175, + linebreak="al", + shcode=0x0057, + specials={ "char", 0x0057, 0x0302 }, + unicodeslot=0x0174, + }, + { + adobename="wcircumflex", + category="ll", + contextname="wcircumflex", + description="LATIN SMALL LETTER W WITH CIRCUMFLEX", + direction="l", + linebreak="al", + shcode=0x0077, + specials={ "char", 0x0077, 0x0302 }, + uccode=0x0174, + unicodeslot=0x0175, + }, + { + adobename="Ycircumflex", + category="lu", + contextname="Ycircumflex", + description="LATIN CAPITAL LETTER Y WITH CIRCUMFLEX", + direction="l", + lccode=0x0177, + linebreak="al", + shcode=0x0059, + specials={ "char", 0x0059, 0x0302 }, + unicodeslot=0x0176, + }, + { + adobename="ycircumflex", + category="ll", + contextname="ycircumflex", + description="LATIN SMALL LETTER Y WITH CIRCUMFLEX", + direction="l", + linebreak="al", + shcode=0x0079, + specials={ "char", 0x0079, 0x0302 }, + uccode=0x0176, + unicodeslot=0x0177, + }, + { + adobename="Ydieresis", + category="lu", + contextname="Ydiaeresis", + description="LATIN CAPITAL LETTER Y WITH DIAERESIS", + direction="l", + lccode=0x00FF, + linebreak="al", + shcode=0x0059, + specials={ "char", 0x0059, 0x0308 }, + unicodeslot=0x0178, + }, + { + adobename="Zacute", + category="lu", + contextname="Zacute", + description="LATIN CAPITAL LETTER Z WITH ACUTE", + direction="l", + lccode=0x017A, + linebreak="al", + shcode=0x005A, + specials={ "char", 0x005A, 0x0301 }, + unicodeslot=0x0179, + }, + { + adobename="zacute", + category="ll", + contextname="zacute", + description="LATIN SMALL LETTER Z WITH ACUTE", + direction="l", + linebreak="al", + shcode=0x007A, + specials={ "char", 0x007A, 0x0301 }, + uccode=0x0179, + unicodeslot=0x017A, + }, + { + adobename="Zdotaccent", + category="lu", + contextname="Zdotaccent", + description="LATIN CAPITAL LETTER Z WITH DOT ABOVE", + direction="l", + lccode=0x017C, + linebreak="al", + shcode=0x005A, + specials={ "char", 0x005A, 0x0307 }, + unicodeslot=0x017B, + }, + { + adobename="zdotaccent", + category="ll", + contextname="zdotaccent", + description="LATIN SMALL LETTER Z WITH DOT ABOVE", + direction="l", + linebreak="al", + shcode=0x007A, + specials={ "char", 0x007A, 0x0307 }, + uccode=0x017B, + unicodeslot=0x017C, + }, + { + adobename="Zcaron", + category="lu", + contextname="Zcaron", + description="LATIN CAPITAL LETTER Z WITH CARON", + direction="l", + lccode=0x017E, + linebreak="al", + shcode=0x005A, + specials={ "char", 0x005A, 0x030C }, + unicodeslot=0x017D, + }, + { + adobename="zcaron", + category="ll", + contextname="zcaron", + description="LATIN SMALL LETTER Z WITH CARON", + direction="l", + linebreak="al", + shcode=0x007A, + specials={ "char", 0x007A, 0x030C }, + uccode=0x017D, + unicodeslot=0x017E, + }, + { + adobename="longs", + category="ll", + contextname="slong", + description="LATIN SMALL LETTER LONG S", + direction="l", + linebreak="al", + specials={ "compat", 0x0073 }, + uccode=0x0053, + unicodeslot=0x017F, + }, + { + category="ll", + contextname="bstroke", + description="LATIN SMALL LETTER B WITH STROKE", + direction="l", + linebreak="al", + shcode=0x0062, + uccode=0x0243, + unicodeslot=0x0180, + }, + { + category="lu", + contextname="Bhook", + description="LATIN CAPITAL LETTER B WITH HOOK", + direction="l", + lccode=0x0253, + linebreak="al", + shcode=0x0042, + unicodeslot=0x0181, + }, + { + category="lu", + description="LATIN CAPITAL LETTER B WITH TOPBAR", + direction="l", + lccode=0x0183, + linebreak="al", + shcode=0x0042, + unicodeslot=0x0182, + }, + { + category="ll", + description="LATIN SMALL LETTER B WITH TOPBAR", + direction="l", + linebreak="al", + shcode=0x0062, + uccode=0x0182, + unicodeslot=0x0183, + }, + { + category="lu", + description="LATIN CAPITAL LETTER TONE SIX", + direction="l", + lccode=0x0185, + linebreak="al", + unicodeslot=0x0184, + }, + { + category="ll", + description="LATIN SMALL LETTER TONE SIX", + direction="l", + linebreak="al", + uccode=0x0184, + unicodeslot=0x0185, + }, + { + category="lu", + description="LATIN CAPITAL LETTER OPEN O", + direction="l", + lccode=0x0254, + linebreak="al", + unicodeslot=0x0186, + }, + { + category="lu", + contextname="Chook", + description="LATIN CAPITAL LETTER C WITH HOOK", + direction="l", + lccode=0x0188, + linebreak="al", + shcode=0x0043, + unicodeslot=0x0187, + }, + { + category="ll", + contextname="chook", + description="LATIN SMALL LETTER C WITH HOOK", + direction="l", + linebreak="al", + shcode=0x0063, + uccode=0x0187, + unicodeslot=0x0188, + }, + { + category="lu", + contextname="Dafrican", + description="LATIN CAPITAL LETTER AFRICAN D", + direction="l", + lccode=0x0256, + linebreak="al", + unicodeslot=0x0189, + }, + { + category="lu", + contextname="Dhook", + description="LATIN CAPITAL LETTER D WITH HOOK", + direction="l", + lccode=0x0257, + linebreak="al", + shcode=0x0044, + unicodeslot=0x018A, + }, + { + category="lu", + description="LATIN CAPITAL LETTER D WITH TOPBAR", + direction="l", + lccode=0x018C, + linebreak="al", + shcode=0x0044, + unicodeslot=0x018B, + }, + { + category="ll", + description="LATIN SMALL LETTER D WITH TOPBAR", + direction="l", + linebreak="al", + shcode=0x0064, + uccode=0x018B, + unicodeslot=0x018C, + }, + { + category="ll", + description="LATIN SMALL LETTER TURNED DELTA", + direction="l", + linebreak="al", + unicodeslot=0x018D, + }, + { + category="lu", + description="LATIN CAPITAL LETTER REVERSED E", + direction="l", + lccode=0x01DD, + linebreak="al", + unicodeslot=0x018E, + }, + { + category="lu", + contextname="Schwa", + description="LATIN CAPITAL LETTER SCHWA", + direction="l", + lccode=0x0259, + linebreak="al", + unicodeslot=0x018F, + }, + { + category="lu", + description="LATIN CAPITAL LETTER OPEN E", + direction="l", + lccode=0x025B, + linebreak="al", + unicodeslot=0x0190, + }, + { + category="lu", + contextname="Fhook", + description="LATIN CAPITAL LETTER F WITH HOOK", + direction="l", + lccode=0x0192, + linebreak="al", + shcode=0x0046, + unicodeslot=0x0191, + }, + { + adobename="florin", + category="ll", + contextname="fhook", + description="LATIN SMALL LETTER F WITH HOOK", + direction="l", + linebreak="al", + shcode=0x0066, + uccode=0x0191, + unicodeslot=0x0192, + }, + { + category="lu", + contextname="Ghook", + description="LATIN CAPITAL LETTER G WITH HOOK", + direction="l", + lccode=0x0260, + linebreak="al", + shcode=0x0047, + unicodeslot=0x0193, + }, + { + category="lu", + description="LATIN CAPITAL LETTER GAMMA", + direction="l", + lccode=0x0263, + linebreak="al", + unicodeslot=0x0194, + }, + { + category="ll", + description="LATIN SMALL LETTER HV", + direction="l", + linebreak="al", + uccode=0x01F6, + unicodeslot=0x0195, + }, + { + category="lu", + description="LATIN CAPITAL LETTER IOTA", + direction="l", + lccode=0x0269, + linebreak="al", + unicodeslot=0x0196, + }, + { + category="lu", + contextname="Istroke", + description="LATIN CAPITAL LETTER I WITH STROKE", + direction="l", + lccode=0x0268, + linebreak="al", + shcode=0x0049, + unicodeslot=0x0197, + }, + { + category="lu", + contextname="Khook", + description="LATIN CAPITAL LETTER K WITH HOOK", + direction="l", + lccode=0x0199, + linebreak="al", + shcode=0x004B, + unicodeslot=0x0198, + }, + { + category="ll", + contextname="khook", + description="LATIN SMALL LETTER K WITH HOOK", + direction="l", + linebreak="al", + shcode=0x006B, + uccode=0x0198, + unicodeslot=0x0199, + }, + { + category="ll", + contextname="lbar", + description="LATIN SMALL LETTER L WITH BAR", + direction="l", + linebreak="al", + shcode=0x006C, + uccode=0x023D, + unicodeslot=0x019A, + }, + { + category="ll", + description="LATIN SMALL LETTER LAMBDA WITH STROKE", + direction="l", + linebreak="al", + unicodeslot=0x019B, + }, + { + category="lu", + description="LATIN CAPITAL LETTER TURNED M", + direction="l", + lccode=0x026F, + linebreak="al", + unicodeslot=0x019C, + }, + { + category="lu", + description="LATIN CAPITAL LETTER N WITH LEFT HOOK", + direction="l", + lccode=0x0272, + linebreak="al", + shcode=0x004E, + unicodeslot=0x019D, + }, + { + category="ll", + description="LATIN SMALL LETTER N WITH LONG RIGHT LEG", + direction="l", + linebreak="al", + shcode=0x006E, + uccode=0x0220, + unicodeslot=0x019E, + }, + { + category="lu", + description="LATIN CAPITAL LETTER O WITH MIDDLE TILDE", + direction="l", + lccode=0x0275, + linebreak="al", + shcode=0x004F, + unicodeslot=0x019F, + }, + { + adobename="Ohorn", + category="lu", + contextname="Ohorn", + description="LATIN CAPITAL LETTER O WITH HORN", + direction="l", + lccode=0x01A1, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x004F, 0x031B }, + unicodeslot=0x01A0, + }, + { + adobename="ohorn", + category="ll", + contextname="ohorn", + description="LATIN SMALL LETTER O WITH HORN", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x006F, 0x031B }, + uccode=0x01A0, + unicodeslot=0x01A1, + }, + { + category="lu", + description="LATIN CAPITAL LETTER OI", + direction="l", + lccode=0x01A3, + linebreak="al", + unicodeslot=0x01A2, + }, + { + category="ll", + description="LATIN SMALL LETTER OI", + direction="l", + linebreak="al", + uccode=0x01A2, + unicodeslot=0x01A3, + }, + { + category="lu", + contextname="Phook", + description="LATIN CAPITAL LETTER P WITH HOOK", + direction="l", + lccode=0x01A5, + linebreak="al", + shcode=0x0050, + unicodeslot=0x01A4, + }, + { + category="ll", + contextname="phook", + description="LATIN SMALL LETTER P WITH HOOK", + direction="l", + linebreak="al", + shcode=0x0070, + uccode=0x01A4, + unicodeslot=0x01A5, + }, + { + category="lu", + description="LATIN LETTER YR", + direction="l", + lccode=0x0280, + linebreak="al", + unicodeslot=0x01A6, + }, + { + category="lu", + description="LATIN CAPITAL LETTER TONE TWO", + direction="l", + lccode=0x01A8, + linebreak="al", + unicodeslot=0x01A7, + }, + { + category="ll", + description="LATIN SMALL LETTER TONE TWO", + direction="l", + linebreak="al", + uccode=0x01A7, + unicodeslot=0x01A8, + }, + { + category="lu", + description="LATIN CAPITAL LETTER ESH", + direction="l", + lccode=0x0283, + linebreak="al", + unicodeslot=0x01A9, + }, + { + category="ll", + description="LATIN LETTER REVERSED ESH LOOP", + direction="l", + linebreak="al", + unicodeslot=0x01AA, + }, + { + category="ll", + description="LATIN SMALL LETTER T WITH PALATAL HOOK", + direction="l", + linebreak="al", + shcode=0x0074, + unicodeslot=0x01AB, + }, + { + category="lu", + contextname="Thook", + description="LATIN CAPITAL LETTER T WITH HOOK", + direction="l", + lccode=0x01AD, + linebreak="al", + shcode=0x0054, + unicodeslot=0x01AC, + }, + { + category="ll", + contextname="thook", + description="LATIN SMALL LETTER T WITH HOOK", + direction="l", + linebreak="al", + shcode=0x0074, + uccode=0x01AC, + unicodeslot=0x01AD, + }, + { + category="lu", + description="LATIN CAPITAL LETTER T WITH RETROFLEX HOOK", + direction="l", + lccode=0x0288, + linebreak="al", + shcode=0x0054, + unicodeslot=0x01AE, + }, + { + adobename="Uhorn", + category="lu", + contextname="Uhorn", + description="LATIN CAPITAL LETTER U WITH HORN", + direction="l", + lccode=0x01B0, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x0055, 0x031B }, + unicodeslot=0x01AF, + }, + { + adobename="uhorn", + category="ll", + contextname="uhorn", + description="LATIN SMALL LETTER U WITH HORN", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x0075, 0x031B }, + uccode=0x01AF, + unicodeslot=0x01B0, + }, + { + category="lu", + description="LATIN CAPITAL LETTER UPSILON", + direction="l", + lccode=0x028A, + linebreak="al", + unicodeslot=0x01B1, + }, + { + category="lu", + contextname="Uhook", + description="LATIN CAPITAL LETTER V WITH HOOK", + direction="l", + lccode=0x028B, + linebreak="al", + shcode=0x0056, + unicodeslot=0x01B2, + }, + { + category="lu", + contextname="Yhook", + description="LATIN CAPITAL LETTER Y WITH HOOK", + direction="l", + lccode=0x01B4, + linebreak="al", + shcode=0x0059, + unicodeslot=0x01B3, + }, + { + category="ll", + contextname="yhook", + description="LATIN SMALL LETTER Y WITH HOOK", + direction="l", + linebreak="al", + shcode=0x0079, + uccode=0x01B3, + unicodeslot=0x01B4, + }, + { + category="lu", + contextname="Zstroke", + description="LATIN CAPITAL LETTER Z WITH STROKE", + direction="l", + lccode=0x01B6, + linebreak="al", + shcode=0x005A, + unicodeslot=0x01B5, + }, + { + category="ll", + contextname="zstroke", + description="LATIN SMALL LETTER Z WITH STROKE", + direction="l", + linebreak="al", + shcode=0x007A, + uccode=0x01B5, + unicodeslot=0x01B6, + }, + { + category="lu", + description="LATIN CAPITAL LETTER EZH", + direction="l", + lccode=0x0292, + linebreak="al", + unicodeslot=0x01B7, + }, + { + category="lu", + description="LATIN CAPITAL LETTER EZH REVERSED", + direction="l", + lccode=0x01B9, + linebreak="al", + unicodeslot=0x01B8, + }, + { + category="ll", + description="LATIN SMALL LETTER EZH REVERSED", + direction="l", + linebreak="al", + uccode=0x01B8, + unicodeslot=0x01B9, + }, + { + category="ll", + description="LATIN SMALL LETTER EZH WITH TAIL", + direction="l", + linebreak="al", + shcode=0x0292, + unicodeslot=0x01BA, + }, + { + category="lo", + description="LATIN LETTER TWO WITH STROKE", + direction="l", + linebreak="al", + unicodeslot=0x01BB, + }, + { + category="lu", + description="LATIN CAPITAL LETTER TONE FIVE", + direction="l", + lccode=0x01BD, + linebreak="al", + unicodeslot=0x01BC, + }, + { + category="ll", + description="LATIN SMALL LETTER TONE FIVE", + direction="l", + linebreak="al", + uccode=0x01BC, + unicodeslot=0x01BD, + }, + { + category="ll", + description="LATIN LETTER INVERTED GLOTTAL STOP WITH STROKE", + direction="l", + linebreak="al", + unicodeslot=0x01BE, + }, + { + category="ll", + description="LATIN LETTER WYNN", + direction="l", + linebreak="al", + uccode=0x01F7, + unicodeslot=0x01BF, + }, + { + category="lo", + description="LATIN LETTER DENTAL CLICK", + direction="l", + linebreak="al", + unicodeslot=0x01C0, + }, + { + category="lo", + description="LATIN LETTER LATERAL CLICK", + direction="l", + linebreak="al", + unicodeslot=0x01C1, + }, + { + category="lo", + description="LATIN LETTER ALVEOLAR CLICK", + direction="l", + linebreak="al", + unicodeslot=0x01C2, + }, + { + category="lo", + description="LATIN LETTER RETROFLEX CLICK", + direction="l", + linebreak="al", + unicodeslot=0x01C3, + }, + { + category="lu", + contextname="DZcaronligature", + description="LATIN CAPITAL LETTER DZ WITH CARON", + direction="l", + lccode=0x01C6, + linebreak="al", + shcode=0x01F1, + specials={ "compat", 0x0044, 0x017D }, + uccode=0x01C5, + unicodeslot=0x01C4, + }, + { + category="lt", + contextname="Dzcaronligature", + description="LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON", + direction="l", + lccode=0x01C6, + linebreak="al", + shcode=0x01F2, + specials={ "compat", 0x0044, 0x017E }, + uccode=0x01C4, + unicodeslot=0x01C5, + }, + { + category="ll", + contextname="dzcaronligature", + description="LATIN SMALL LETTER DZ WITH CARON", + direction="l", + linebreak="al", + shcode=0x01F3, + specials={ "compat", 0x0064, 0x017E }, + uccode=0x01C4, + unicodeslot=0x01C6, + }, + { + category="lu", + contextname="LJligature", + description="LATIN CAPITAL LETTER LJ", + direction="l", + lccode=0x01C9, + linebreak="al", + shcode={ 0x004C, 0x004A }, + specials={ "compat", 0x004C, 0x004A }, + uccode=0x01C8, + unicodeslot=0x01C7, + }, + { + category="lt", + contextname="Ljligature", + description="LATIN CAPITAL LETTER L WITH SMALL LETTER J", + direction="l", + lccode=0x01C9, + linebreak="al", + shcode={ 0x004C, 0x006A }, + specials={ "compat", 0x004C, 0x006A }, + uccode=0x01C7, + unicodeslot=0x01C8, + }, + { + category="ll", + contextname="ljligature", + description="LATIN SMALL LETTER LJ", + direction="l", + linebreak="al", + shcode={ 0x006C, 0x006A }, + specials={ "compat", 0x006C, 0x006A }, + uccode=0x01C7, + unicodeslot=0x01C9, + }, + { + category="lu", + contextname="NJligature", + description="LATIN CAPITAL LETTER NJ", + direction="l", + lccode=0x01CC, + linebreak="al", + shcode={ 0x004E, 0x004A }, + specials={ "compat", 0x004E, 0x004A }, + uccode=0x01CB, + unicodeslot=0x01CA, + }, + { + category="lt", + contextname="Njligature", + description="LATIN CAPITAL LETTER N WITH SMALL LETTER J", + direction="l", + lccode=0x01CC, + linebreak="al", + shcode=0x004E, + specials={ "compat", 0x004E, 0x006A }, + uccode=0x01CA, + unicodeslot=0x01CB, + }, + { + category="ll", + contextname="njligature", + description="LATIN SMALL LETTER NJ", + direction="l", + linebreak="al", + shcode={ 0x006E, 0x006A }, + specials={ "compat", 0x006E, 0x006A }, + uccode=0x01CA, + unicodeslot=0x01CC, + }, + { + category="lu", + contextname="Acaron", + description="LATIN CAPITAL LETTER A WITH CARON", + direction="l", + lccode=0x01CE, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x0041, 0x030C }, + unicodeslot=0x01CD, + }, + { + category="ll", + cjkwd="a", + contextname="acaron", + description="LATIN SMALL LETTER A WITH CARON", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x0061, 0x030C }, + uccode=0x01CD, + unicodeslot=0x01CE, + }, + { + category="lu", + contextname="Icaron", + description="LATIN CAPITAL LETTER I WITH CARON", + direction="l", + lccode=0x01D0, + linebreak="al", + shcode=0x0049, + specials={ "char", 0x0049, 0x030C }, + unicodeslot=0x01CF, + }, + { + category="ll", + cjkwd="a", + contextname="icaron", + description="LATIN SMALL LETTER I WITH CARON", + direction="l", + linebreak="al", + shcode=0x0069, + specials={ "char", 0x0069, 0x030C }, + uccode=0x01CF, + unicodeslot=0x01D0, + }, + { + category="lu", + contextname="Ocaron", + description="LATIN CAPITAL LETTER O WITH CARON", + direction="l", + lccode=0x01D2, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x004F, 0x030C }, + unicodeslot=0x01D1, + }, + { + category="ll", + cjkwd="a", + contextname="ocaron", + description="LATIN SMALL LETTER O WITH CARON", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x006F, 0x030C }, + uccode=0x01D1, + unicodeslot=0x01D2, + }, + { + category="lu", + contextname="Ucaron", + description="LATIN CAPITAL LETTER U WITH CARON", + direction="l", + lccode=0x01D4, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x0055, 0x030C }, + unicodeslot=0x01D3, + }, + { + category="ll", + cjkwd="a", + contextname="ucaron", + description="LATIN SMALL LETTER U WITH CARON", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x0075, 0x030C }, + uccode=0x01D3, + unicodeslot=0x01D4, + }, + { + category="lu", + contextname="Udiaeresismacron", + description="LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON", + direction="l", + lccode=0x01D6, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x00DC, 0x0304 }, + unicodeslot=0x01D5, + }, + { + category="ll", + cjkwd="a", + contextname="udiaeresismacron", + description="LATIN SMALL LETTER U WITH DIAERESIS AND MACRON", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x00FC, 0x0304 }, + uccode=0x01D5, + unicodeslot=0x01D6, + }, + { + category="lu", + contextname="Udiaeresisacute", + description="LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE", + direction="l", + lccode=0x01D8, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x00DC, 0x0301 }, + unicodeslot=0x01D7, + }, + { + category="ll", + cjkwd="a", + contextname="udiaeresisacute", + description="LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x00FC, 0x0301 }, + uccode=0x01D7, + unicodeslot=0x01D8, + }, + { + category="lu", + contextname="Udiaeresiscaron", + description="LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON", + direction="l", + lccode=0x01DA, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x00DC, 0x030C }, + unicodeslot=0x01D9, + }, + { + category="ll", + cjkwd="a", + contextname="udiaeresiscaron", + description="LATIN SMALL LETTER U WITH DIAERESIS AND CARON", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x00FC, 0x030C }, + uccode=0x01D9, + unicodeslot=0x01DA, + }, + { + category="lu", + contextname="Udiaeresisgrave", + description="LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE", + direction="l", + lccode=0x01DC, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x00DC, 0x0300 }, + unicodeslot=0x01DB, + }, + { + category="ll", + cjkwd="a", + contextname="udiaeresisgrave", + description="LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x00FC, 0x0300 }, + uccode=0x01DB, + unicodeslot=0x01DC, + }, + { + category="ll", + description="LATIN SMALL LETTER TURNED E", + direction="l", + linebreak="al", + uccode=0x018E, + unicodeslot=0x01DD, + }, + { + category="lu", + contextname="Adiaeresismacron", + description="LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON", + direction="l", + lccode=0x01DF, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x00C4, 0x0304 }, + unicodeslot=0x01DE, + }, + { + category="ll", + contextname="adiaeresismacron", + description="LATIN SMALL LETTER A WITH DIAERESIS AND MACRON", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x00E4, 0x0304 }, + uccode=0x01DE, + unicodeslot=0x01DF, + }, + { + category="lu", + contextname="Adotaccentmacron", + description="LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON", + direction="l", + lccode=0x01E1, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x0226, 0x0304 }, + unicodeslot=0x01E0, + }, + { + category="ll", + contextname="adotaccentmacron", + description="LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x0227, 0x0304 }, + uccode=0x01E0, + unicodeslot=0x01E1, + }, + { + category="lu", + contextname="AEmacron", + description="LATIN CAPITAL LETTER AE WITH MACRON", + direction="l", + lccode=0x01E3, + linebreak="al", + shcode=0x00C6, + specials={ "char", 0x00C6, 0x0304 }, + unicodeslot=0x01E2, + }, + { + category="ll", + contextname="aemacron", + description="LATIN SMALL LETTER AE WITH MACRON", + direction="l", + linebreak="al", + shcode=0x00E6, + specials={ "char", 0x00E6, 0x0304 }, + uccode=0x01E2, + unicodeslot=0x01E3, + }, + { + category="lu", + contextname="Gstroke", + description="LATIN CAPITAL LETTER G WITH STROKE", + direction="l", + lccode=0x01E5, + linebreak="al", + shcode=0x0047, + unicodeslot=0x01E4, + }, + { + category="ll", + contextname="gstroke", + description="LATIN SMALL LETTER G WITH STROKE", + direction="l", + linebreak="al", + shcode=0x0067, + uccode=0x01E4, + unicodeslot=0x01E5, + }, + { + adobename="Gcaron", + category="lu", + contextname="Gcaron", + description="LATIN CAPITAL LETTER G WITH CARON", + direction="l", + lccode=0x01E7, + linebreak="al", + shcode=0x0047, + specials={ "char", 0x0047, 0x030C }, + unicodeslot=0x01E6, + }, + { + adobename="gcaron", + category="ll", + contextname="gcaron", + description="LATIN SMALL LETTER G WITH CARON", + direction="l", + linebreak="al", + shcode=0x0067, + specials={ "char", 0x0067, 0x030C }, + uccode=0x01E6, + unicodeslot=0x01E7, + }, + { + category="lu", + contextname="Kcaron", + description="LATIN CAPITAL LETTER K WITH CARON", + direction="l", + lccode=0x01E9, + linebreak="al", + shcode=0x004B, + specials={ "char", 0x004B, 0x030C }, + unicodeslot=0x01E8, + }, + { + category="ll", + contextname="kcaron", + description="LATIN SMALL LETTER K WITH CARON", + direction="l", + linebreak="al", + shcode=0x006B, + specials={ "char", 0x006B, 0x030C }, + uccode=0x01E8, + unicodeslot=0x01E9, + }, + { + category="lu", + contextname="Oogonek", + description="LATIN CAPITAL LETTER O WITH OGONEK", + direction="l", + lccode=0x01EB, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x004F, 0x0328 }, + unicodeslot=0x01EA, + }, + { + category="ll", + contextname="oogonek", + description="LATIN SMALL LETTER O WITH OGONEK", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x006F, 0x0328 }, + uccode=0x01EA, + unicodeslot=0x01EB, + }, + { + category="lu", + contextname="Oogonekmacron", + description="LATIN CAPITAL LETTER O WITH OGONEK AND MACRON", + direction="l", + lccode=0x01ED, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x01EA, 0x0304 }, + unicodeslot=0x01EC, + }, + { + category="ll", + contextname="oogonekmacron", + description="LATIN SMALL LETTER O WITH OGONEK AND MACRON", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x01EB, 0x0304 }, + uccode=0x01EC, + unicodeslot=0x01ED, + }, + { + category="lu", + description="LATIN CAPITAL LETTER EZH WITH CARON", + direction="l", + lccode=0x01EF, + linebreak="al", + shcode=0x01B7, + specials={ "char", 0x01B7, 0x030C }, + unicodeslot=0x01EE, + }, + { + category="ll", + description="LATIN SMALL LETTER EZH WITH CARON", + direction="l", + linebreak="al", + shcode=0x0292, + specials={ "char", 0x0292, 0x030C }, + uccode=0x01EE, + unicodeslot=0x01EF, + }, + { + category="ll", + contextname="jcaron", + description="LATIN SMALL LETTER J WITH CARON", + direction="l", + linebreak="al", + shcode=0x006A, + specials={ "char", 0x006A, 0x030C }, + unicodeslot=0x01F0, + }, + { + category="lu", + contextname="DZligature", + description="LATIN CAPITAL LETTER DZ", + direction="l", + lccode=0x01F3, + linebreak="al", + specials={ "compat", 0x0044, 0x005A }, + uccode=0x01F2, + unicodeslot=0x01F1, + }, + { + category="lt", + contextname="Dzligature", + description="LATIN CAPITAL LETTER D WITH SMALL LETTER Z", + direction="l", + lccode=0x01F3, + linebreak="al", + shcode=0x0044, + specials={ "compat", 0x0044, 0x007A }, + uccode=0x01F1, + unicodeslot=0x01F2, + }, + { + category="ll", + contextname="dzligature", + description="LATIN SMALL LETTER DZ", + direction="l", + linebreak="al", + specials={ "compat", 0x0064, 0x007A }, + uccode=0x01F1, + unicodeslot=0x01F3, + }, + { + category="lu", + contextname="Gacute", + description="LATIN CAPITAL LETTER G WITH ACUTE", + direction="l", + lccode=0x01F5, + linebreak="al", + shcode=0x0047, + specials={ "char", 0x0047, 0x0301 }, + unicodeslot=0x01F4, + }, + { + category="ll", + contextname="gacute", + description="LATIN SMALL LETTER G WITH ACUTE", + direction="l", + linebreak="al", + shcode=0x0067, + specials={ "char", 0x0067, 0x0301 }, + uccode=0x01F4, + unicodeslot=0x01F5, + }, + { + category="lu", + description="LATIN CAPITAL LETTER HWAIR", + direction="l", + lccode=0x0195, + linebreak="al", + unicodeslot=0x01F6, + }, + { + category="lu", + description="LATIN CAPITAL LETTER WYNN", + direction="l", + lccode=0x01BF, + linebreak="al", + unicodeslot=0x01F7, + }, + { + category="lu", + contextname="Ngrave", + description="LATIN CAPITAL LETTER N WITH GRAVE", + direction="l", + lccode=0x01F9, + linebreak="al", + shcode=0x004E, + specials={ "char", 0x004E, 0x0300 }, + unicodeslot=0x01F8, + }, + { + category="ll", + contextname="ngrave", + description="LATIN SMALL LETTER N WITH GRAVE", + direction="l", + linebreak="al", + shcode=0x006E, + specials={ "char", 0x006E, 0x0300 }, + uccode=0x01F8, + unicodeslot=0x01F9, + }, + { + adobename="Aringacute", + category="lu", + contextname="Aringacute", + description="LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE", + direction="l", + lccode=0x01FB, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x00C5, 0x0301 }, + unicodeslot=0x01FA, + }, + { + adobename="aringacute", + category="ll", + contextname="aringacute", + description="LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x00E5, 0x0301 }, + uccode=0x01FA, + unicodeslot=0x01FB, + }, + { + adobename="AEacute", + category="lu", + contextname="AEacute", + description="LATIN CAPITAL LETTER AE WITH ACUTE", + direction="l", + lccode=0x01FD, + linebreak="al", + shcode=0x00C6, + specials={ "char", 0x00C6, 0x0301 }, + unicodeslot=0x01FC, + }, + { + adobename="aeacute", + category="ll", + contextname="aeacute", + description="LATIN SMALL LETTER AE WITH ACUTE", + direction="l", + linebreak="al", + shcode=0x00E6, + specials={ "char", 0x00E6, 0x0301 }, + uccode=0x01FC, + unicodeslot=0x01FD, + }, + { + adobename="Oslashacute", + category="lu", + contextname="Ostrokeacute", + description="LATIN CAPITAL LETTER O WITH STROKE AND ACUTE", + direction="l", + lccode=0x01FF, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x00D8, 0x0301 }, + unicodeslot=0x01FE, + }, + { + adobename="oslashacute", + category="ll", + contextname="ostrokeacute", + description="LATIN SMALL LETTER O WITH STROKE AND ACUTE", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x00F8, 0x0301 }, + uccode=0x01FE, + unicodeslot=0x01FF, + }, + { + category="lu", + contextname="Adoublegrave", + description="LATIN CAPITAL LETTER A WITH DOUBLE GRAVE", + direction="l", + lccode=0x0201, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x0041, 0x030F }, + unicodeslot=0x0200, + }, + { + category="ll", + contextname="adoublegrave", + description="LATIN SMALL LETTER A WITH DOUBLE GRAVE", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x0061, 0x030F }, + uccode=0x0200, + unicodeslot=0x0201, + }, + { + category="lu", + contextname="Ainvertedbreve", + description="LATIN CAPITAL LETTER A WITH INVERTED BREVE", + direction="l", + lccode=0x0203, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x0041, 0x0311 }, + unicodeslot=0x0202, + }, + { + category="ll", + contextname="ainvertedbreve", + description="LATIN SMALL LETTER A WITH INVERTED BREVE", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x0061, 0x0311 }, + uccode=0x0202, + unicodeslot=0x0203, + }, + { + category="lu", + contextname="Edoublegrave", + description="LATIN CAPITAL LETTER E WITH DOUBLE GRAVE", + direction="l", + lccode=0x0205, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x0045, 0x030F }, + unicodeslot=0x0204, + }, + { + category="ll", + contextname="edoublegrave", + description="LATIN SMALL LETTER E WITH DOUBLE GRAVE", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x0065, 0x030F }, + uccode=0x0204, + unicodeslot=0x0205, + }, + { + category="lu", + contextname="Einvertedbreve", + description="LATIN CAPITAL LETTER E WITH INVERTED BREVE", + direction="l", + lccode=0x0207, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x0045, 0x0311 }, + unicodeslot=0x0206, + }, + { + category="ll", + contextname="einvertedbreve", + description="LATIN SMALL LETTER E WITH INVERTED BREVE", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x0065, 0x0311 }, + uccode=0x0206, + unicodeslot=0x0207, + }, + { + category="lu", + contextname="Idoublegrave", + description="LATIN CAPITAL LETTER I WITH DOUBLE GRAVE", + direction="l", + lccode=0x0209, + linebreak="al", + shcode=0x0049, + specials={ "char", 0x0049, 0x030F }, + unicodeslot=0x0208, + }, + { + category="ll", + contextname="idoublegrave", + description="LATIN SMALL LETTER I WITH DOUBLE GRAVE", + direction="l", + linebreak="al", + shcode=0x0069, + specials={ "char", 0x0069, 0x030F }, + uccode=0x0208, + unicodeslot=0x0209, + }, + { + category="lu", + contextname="Iinvertedbreve", + description="LATIN CAPITAL LETTER I WITH INVERTED BREVE", + direction="l", + lccode=0x020B, + linebreak="al", + shcode=0x0049, + specials={ "char", 0x0049, 0x0311 }, + unicodeslot=0x020A, + }, + { + category="ll", + contextname="iinvertedbreve", + description="LATIN SMALL LETTER I WITH INVERTED BREVE", + direction="l", + linebreak="al", + shcode=0x0069, + specials={ "char", 0x0069, 0x0311 }, + uccode=0x020A, + unicodeslot=0x020B, + }, + { + category="lu", + contextname="Odoublegrave", + description="LATIN CAPITAL LETTER O WITH DOUBLE GRAVE", + direction="l", + lccode=0x020D, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x004F, 0x030F }, + unicodeslot=0x020C, + }, + { + category="ll", + contextname="odoublegrave", + description="LATIN SMALL LETTER O WITH DOUBLE GRAVE", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x006F, 0x030F }, + uccode=0x020C, + unicodeslot=0x020D, + }, + { + category="lu", + contextname="Oinvertedbreve", + description="LATIN CAPITAL LETTER O WITH INVERTED BREVE", + direction="l", + lccode=0x020F, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x004F, 0x0311 }, + unicodeslot=0x020E, + }, + { + category="ll", + contextname="oinvertedbreve", + description="LATIN SMALL LETTER O WITH INVERTED BREVE", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x006F, 0x0311 }, + uccode=0x020E, + unicodeslot=0x020F, + }, + { + category="lu", + contextname="Rdoublegrave", + description="LATIN CAPITAL LETTER R WITH DOUBLE GRAVE", + direction="l", + lccode=0x0211, + linebreak="al", + shcode=0x0052, + specials={ "char", 0x0052, 0x030F }, + unicodeslot=0x0210, + }, + { + category="ll", + contextname="rdoublegrave", + description="LATIN SMALL LETTER R WITH DOUBLE GRAVE", + direction="l", + linebreak="al", + shcode=0x0072, + specials={ "char", 0x0072, 0x030F }, + uccode=0x0210, + unicodeslot=0x0211, + }, + { + category="lu", + contextname="Rinvertedbreve", + description="LATIN CAPITAL LETTER R WITH INVERTED BREVE", + direction="l", + lccode=0x0213, + linebreak="al", + shcode=0x0052, + specials={ "char", 0x0052, 0x0311 }, + unicodeslot=0x0212, + }, + { + category="ll", + contextname="rinvertedbreve", + description="LATIN SMALL LETTER R WITH INVERTED BREVE", + direction="l", + linebreak="al", + shcode=0x0072, + specials={ "char", 0x0072, 0x0311 }, + uccode=0x0212, + unicodeslot=0x0213, + }, + { + category="lu", + contextname="Udoublegrave", + description="LATIN CAPITAL LETTER U WITH DOUBLE GRAVE", + direction="l", + lccode=0x0215, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x0055, 0x030F }, + unicodeslot=0x0214, + }, + { + category="ll", + contextname="udoublegrave", + description="LATIN SMALL LETTER U WITH DOUBLE GRAVE", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x0075, 0x030F }, + uccode=0x0214, + unicodeslot=0x0215, + }, + { + category="lu", + contextname="Uinvertedbreve", + description="LATIN CAPITAL LETTER U WITH INVERTED BREVE", + direction="l", + lccode=0x0217, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x0055, 0x0311 }, + unicodeslot=0x0216, + }, + { + category="ll", + contextname="uinvertedbreve", + description="LATIN SMALL LETTER U WITH INVERTED BREVE", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x0075, 0x0311 }, + uccode=0x0216, + unicodeslot=0x0217, + }, + { + adobename="Scommaaccent", + category="lu", + contextname="Scommaaccent", + description="LATIN CAPITAL LETTER S WITH COMMA BELOW", + direction="l", + lccode=0x0219, + linebreak="al", + shcode=0x0053, + specials={ "char", 0x0053, 0x0326 }, + unicodeslot=0x0218, + }, + { + adobename="scommaaccent", + category="ll", + contextname="scommaaccent", + description="LATIN SMALL LETTER S WITH COMMA BELOW", + direction="l", + linebreak="al", + shcode=0x0073, + specials={ "char", 0x0073, 0x0326 }, + uccode=0x0218, + unicodeslot=0x0219, + }, + { + category="lu", + contextname="Tcommaaccent", + description="LATIN CAPITAL LETTER T WITH COMMA BELOW", + direction="l", + lccode=0x021B, + linebreak="al", + shcode=0x0054, + specials={ "char", 0x0054, 0x0326 }, + unicodeslot=0x021A, + }, + { + category="ll", + contextname="tcommaaccent", + description="LATIN SMALL LETTER T WITH COMMA BELOW", + direction="l", + linebreak="al", + shcode=0x0074, + specials={ "char", 0x0074, 0x0326 }, + uccode=0x021A, + unicodeslot=0x021B, + }, + { + category="lu", + description="LATIN CAPITAL LETTER YOGH", + direction="l", + lccode=0x021D, + linebreak="al", + unicodeslot=0x021C, + }, + { + category="ll", + description="LATIN SMALL LETTER YOGH", + direction="l", + linebreak="al", + uccode=0x021C, + unicodeslot=0x021D, + }, + { + category="lu", + contextname="Hcaron", + description="LATIN CAPITAL LETTER H WITH CARON", + direction="l", + lccode=0x021F, + linebreak="al", + shcode=0x0048, + specials={ "char", 0x0048, 0x030C }, + unicodeslot=0x021E, + }, + { + category="ll", + contextname="hcaron", + description="LATIN SMALL LETTER H WITH CARON", + direction="l", + linebreak="al", + shcode=0x0068, + specials={ "char", 0x0068, 0x030C }, + uccode=0x021E, + unicodeslot=0x021F, + }, + { + category="lu", + description="LATIN CAPITAL LETTER N WITH LONG RIGHT LEG", + direction="l", + lccode=0x019E, + linebreak="al", + shcode=0x004E, + unicodeslot=0x0220, + }, + { + category="ll", + contextname="dcurl", + description="LATIN SMALL LETTER D WITH CURL", + direction="l", + linebreak="al", + shcode=0x0064, + unicodeslot=0x0221, + }, + { + category="lu", + description="LATIN CAPITAL LETTER OU", + direction="l", + lccode=0x0223, + linebreak="al", + unicodeslot=0x0222, + }, + { + category="ll", + description="LATIN SMALL LETTER OU", + direction="l", + linebreak="al", + uccode=0x0222, + unicodeslot=0x0223, + }, + { + category="lu", + contextname="Zhook", + description="LATIN CAPITAL LETTER Z WITH HOOK", + direction="l", + lccode=0x0225, + linebreak="al", + shcode=0x005A, + unicodeslot=0x0224, + }, + { + category="ll", + contextname="zhook", + description="LATIN SMALL LETTER Z WITH HOOK", + direction="l", + linebreak="al", + shcode=0x007A, + uccode=0x0224, + unicodeslot=0x0225, + }, + { + category="lu", + contextname="Adotaccent", + description="LATIN CAPITAL LETTER A WITH DOT ABOVE", + direction="l", + lccode=0x0227, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x0041, 0x0307 }, + unicodeslot=0x0226, + }, + { + category="ll", + contextname="adotaccent", + description="LATIN SMALL LETTER A WITH DOT ABOVE", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x0061, 0x0307 }, + uccode=0x0226, + unicodeslot=0x0227, + }, + { + category="lu", + contextname="Ecedilla", + description="LATIN CAPITAL LETTER E WITH CEDILLA", + direction="l", + lccode=0x0229, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x0045, 0x0327 }, + unicodeslot=0x0228, + }, + { + category="ll", + contextname="ecedilla", + description="LATIN SMALL LETTER E WITH CEDILLA", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x0065, 0x0327 }, + uccode=0x0228, + unicodeslot=0x0229, + }, + { + category="lu", + contextname="Odiaeresismacron", + description="LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON", + direction="l", + lccode=0x022B, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x00D6, 0x0304 }, + unicodeslot=0x022A, + }, + { + category="ll", + contextname="odiaeresismacron", + description="LATIN SMALL LETTER O WITH DIAERESIS AND MACRON", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x00F6, 0x0304 }, + uccode=0x022A, + unicodeslot=0x022B, + }, + { + category="lu", + contextname="Otildemacron", + description="LATIN CAPITAL LETTER O WITH TILDE AND MACRON", + direction="l", + lccode=0x022D, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x00D5, 0x0304 }, + unicodeslot=0x022C, + }, + { + category="ll", + contextname="otildemacron", + description="LATIN SMALL LETTER O WITH TILDE AND MACRON", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x00F5, 0x0304 }, + uccode=0x022C, + unicodeslot=0x022D, + }, + { + category="lu", + contextname="Odotaccent", + description="LATIN CAPITAL LETTER O WITH DOT ABOVE", + direction="l", + lccode=0x022F, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x004F, 0x0307 }, + unicodeslot=0x022E, + }, + { + category="ll", + contextname="odotaccent", + description="LATIN SMALL LETTER O WITH DOT ABOVE", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x006F, 0x0307 }, + uccode=0x022E, + unicodeslot=0x022F, + }, + { + category="lu", + contextname="Odotaccentmacron", + description="LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON", + direction="l", + lccode=0x0231, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x022E, 0x0304 }, + unicodeslot=0x0230, + }, + { + category="ll", + contextname="odotaccentmacron", + description="LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x022F, 0x0304 }, + uccode=0x0230, + unicodeslot=0x0231, + }, + { + category="lu", + contextname="Ymacron", + description="LATIN CAPITAL LETTER Y WITH MACRON", + direction="l", + lccode=0x0233, + linebreak="al", + shcode=0x0059, + specials={ "char", 0x0059, 0x0304 }, + unicodeslot=0x0232, + }, + { + category="ll", + contextname="ymacron", + description="LATIN SMALL LETTER Y WITH MACRON", + direction="l", + linebreak="al", + shcode=0x0079, + specials={ "char", 0x0079, 0x0304 }, + uccode=0x0232, + unicodeslot=0x0233, + }, + { + category="ll", + contextname="lcurl", + description="LATIN SMALL LETTER L WITH CURL", + direction="l", + linebreak="al", + shcode=0x006C, + unicodeslot=0x0234, + }, + { + category="ll", + contextname="ncurl", + description="LATIN SMALL LETTER N WITH CURL", + direction="l", + linebreak="al", + shcode=0x006E, + unicodeslot=0x0235, + }, + { + category="ll", + contextname="tcurl", + description="LATIN SMALL LETTER T WITH CURL", + direction="l", + linebreak="al", + shcode=0x0074, + unicodeslot=0x0236, + }, + { + category="ll", + contextname="dotlessj", + description="LATIN SMALL LETTER DOTLESS J", + direction="l", + linebreak="al", + unicodeslot=0x0237, + }, + { + category="ll", + description="LATIN SMALL LETTER DB DIGRAPH", + direction="l", + linebreak="al", + unicodeslot=0x0238, + }, + { + category="ll", + description="LATIN SMALL LETTER QP DIGRAPH", + direction="l", + linebreak="al", + unicodeslot=0x0239, + }, + { + category="lu", + contextname="Astroke", + description="LATIN CAPITAL LETTER A WITH STROKE", + direction="l", + lccode=0x2C65, + linebreak="al", + shcode=0x0041, + unicodeslot=0x023A, + }, + { + category="lu", + contextname="Cstroke", + description="LATIN CAPITAL LETTER C WITH STROKE", + direction="l", + lccode=0x023C, + linebreak="al", + shcode=0x0043, + unicodeslot=0x023B, + }, + { + category="ll", + contextname="cstroke", + description="LATIN SMALL LETTER C WITH STROKE", + direction="l", + linebreak="al", + shcode=0x0063, + uccode=0x023B, + unicodeslot=0x023C, + }, + { + category="lu", + contextname="Lbar", + description="LATIN CAPITAL LETTER L WITH BAR", + direction="l", + lccode=0x019A, + linebreak="al", + shcode=0x004C, + unicodeslot=0x023D, + }, + { + category="lu", + description="LATIN CAPITAL LETTER T WITH DIAGONAL STROKE", + direction="l", + lccode=0x2C66, + linebreak="al", + shcode=0x0054, + unicodeslot=0x023E, + }, + { + category="ll", + description="LATIN SMALL LETTER S WITH SWASH TAIL", + direction="l", + linebreak="al", + shcode=0x0073, + unicodeslot=0x023F, + }, + { + category="ll", + description="LATIN SMALL LETTER Z WITH SWASH TAIL", + direction="l", + linebreak="al", + shcode=0x007A, + unicodeslot=0x0240, + }, + { + category="lu", + description="LATIN CAPITAL LETTER GLOTTAL STOP", + direction="l", + lccode=0x0242, + linebreak="al", + unicodeslot=0x0241, + }, + { + category="ll", + description="LATIN SMALL LETTER GLOTTAL STOP", + direction="l", + linebreak="al", + uccode=0x0241, + unicodeslot=0x0242, + }, + { + category="lu", + description="LATIN CAPITAL LETTER B WITH STROKE", + direction="l", + lccode=0x0180, + linebreak="al", + shcode=0x0042, + unicodeslot=0x0243, + }, + { + category="lu", + description="LATIN CAPITAL LETTER U BAR", + direction="l", + lccode=0x0289, + linebreak="al", + unicodeslot=0x0244, + }, + { + category="lu", + description="LATIN CAPITAL LETTER TURNED V", + direction="l", + lccode=0x028C, + linebreak="al", + unicodeslot=0x0245, + }, + { + category="lu", + description="LATIN CAPITAL LETTER E WITH STROKE", + direction="l", + lccode=0x0247, + linebreak="al", + shcode=0x0045, + unicodeslot=0x0246, + }, + { + category="ll", + description="LATIN SMALL LETTER E WITH STROKE", + direction="l", + linebreak="al", + shcode=0x0065, + uccode=0x0246, + unicodeslot=0x0247, + }, + { + category="lu", + description="LATIN CAPITAL LETTER J WITH STROKE", + direction="l", + lccode=0x0249, + linebreak="al", + shcode=0x004A, + unicodeslot=0x0248, + }, + { + category="ll", + description="LATIN SMALL LETTER J WITH STROKE", + direction="l", + linebreak="al", + shcode=0x006A, + uccode=0x0248, + unicodeslot=0x0249, + }, + { + category="lu", + description="LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL", + direction="l", + lccode=0x024B, + linebreak="al", + unicodeslot=0x024A, + }, + { + category="ll", + description="LATIN SMALL LETTER Q WITH HOOK TAIL", + direction="l", + linebreak="al", + shcode=0x0071, + uccode=0x024A, + unicodeslot=0x024B, + }, + { + category="lu", + description="LATIN CAPITAL LETTER R WITH STROKE", + direction="l", + lccode=0x024D, + linebreak="al", + shcode=0x0052, + unicodeslot=0x024C, + }, + { + category="ll", + description="LATIN SMALL LETTER R WITH STROKE", + direction="l", + linebreak="al", + shcode=0x0072, + uccode=0x024C, + unicodeslot=0x024D, + }, + { + category="lu", + description="LATIN CAPITAL LETTER Y WITH STROKE", + direction="l", + lccode=0x024F, + linebreak="al", + shcode=0x0059, + unicodeslot=0x024E, + }, + { + category="ll", + description="LATIN SMALL LETTER Y WITH STROKE", + direction="l", + linebreak="al", + shcode=0x0079, + uccode=0x024E, + unicodeslot=0x024F, + }, + { + category="ll", + description="LATIN SMALL LETTER TURNED A", + direction="l", + linebreak="al", + unicodeslot=0x0250, + }, + { + category="ll", + cjkwd="a", + description="LATIN SMALL LETTER ALPHA", + direction="l", + linebreak="al", + unicodeslot=0x0251, + }, + { + category="ll", + description="LATIN SMALL LETTER TURNED ALPHA", + direction="l", + linebreak="al", + unicodeslot=0x0252, + }, + { + category="ll", + contextname="bhook", + description="LATIN SMALL LETTER B WITH HOOK", + direction="l", + linebreak="al", + shcode=0x0062, + uccode=0x0181, + unicodeslot=0x0253, + }, + { + category="ll", + description="LATIN SMALL LETTER OPEN O", + direction="l", + linebreak="al", + uccode=0x0186, + unicodeslot=0x0254, + }, + { + category="ll", + contextname="ccurl", + description="LATIN SMALL LETTER C WITH CURL", + direction="l", + linebreak="al", + shcode=0x0063, + unicodeslot=0x0255, + }, + { + category="ll", + contextname="dtail", + description="LATIN SMALL LETTER D WITH TAIL", + direction="l", + linebreak="al", + shcode=0x0064, + uccode=0x0189, + unicodeslot=0x0256, + }, + { + category="ll", + contextname="dhook", + description="LATIN SMALL LETTER D WITH HOOK", + direction="l", + linebreak="al", + shcode=0x0064, + uccode=0x018A, + unicodeslot=0x0257, + }, + { + category="ll", + description="LATIN SMALL LETTER REVERSED E", + direction="l", + linebreak="al", + unicodeslot=0x0258, + }, + { + category="ll", + contextname="schwa", + description="LATIN SMALL LETTER SCHWA", + direction="l", + linebreak="al", + uccode=0x018F, + unicodeslot=0x0259, + }, + { + category="ll", + contextname="schwahook", + description="LATIN SMALL LETTER SCHWA WITH HOOK", + direction="l", + linebreak="al", + shcode=0x0259, + unicodeslot=0x025A, + }, + { + category="ll", + description="LATIN SMALL LETTER OPEN E", + direction="l", + linebreak="al", + uccode=0x0190, + unicodeslot=0x025B, + }, + { + category="ll", + description="LATIN SMALL LETTER REVERSED OPEN E", + direction="l", + linebreak="al", + unicodeslot=0x025C, + }, + { + category="ll", + description="LATIN SMALL LETTER REVERSED OPEN E WITH HOOK", + direction="l", + linebreak="al", + unicodeslot=0x025D, + }, + { + category="ll", + description="LATIN SMALL LETTER CLOSED REVERSED OPEN E", + direction="l", + linebreak="al", + unicodeslot=0x025E, + }, + { + category="ll", + contextname="dotlessjstroke", + description="LATIN SMALL LETTER DOTLESS J WITH STROKE", + direction="l", + linebreak="al", + unicodeslot=0x025F, + }, + { + category="ll", + description="LATIN SMALL LETTER G WITH HOOK", + direction="l", + linebreak="al", + shcode=0x0067, + uccode=0x0193, + unicodeslot=0x0260, + }, + { + category="ll", + cjkwd="a", + description="LATIN SMALL LETTER SCRIPT G", + direction="l", + linebreak="al", + unicodeslot=0x0261, + }, + { + category="ll", + description="LATIN LETTER SMALL CAPITAL G", + direction="l", + linebreak="al", + unicodeslot=0x0262, + }, + { + category="ll", + description="LATIN SMALL LETTER GAMMA", + direction="l", + linebreak="al", + uccode=0x0194, + unicodeslot=0x0263, + }, + { + category="ll", + description="LATIN SMALL LETTER RAMS HORN", + direction="l", + linebreak="al", + unicodeslot=0x0264, + }, + { + category="ll", + description="LATIN SMALL LETTER TURNED H", + direction="l", + linebreak="al", + unicodeslot=0x0265, + }, + { + category="ll", + description="LATIN SMALL LETTER H WITH HOOK", + direction="l", + linebreak="al", + shcode=0x0068, + unicodeslot=0x0266, + }, + { + category="ll", + description="LATIN SMALL LETTER HENG WITH HOOK", + direction="l", + linebreak="al", + unicodeslot=0x0267, + }, + { + category="ll", + description="LATIN SMALL LETTER I WITH STROKE", + direction="l", + linebreak="al", + shcode=0x0069, + uccode=0x0197, + unicodeslot=0x0268, + }, + { + category="ll", + description="LATIN SMALL LETTER IOTA", + direction="l", + linebreak="al", + uccode=0x0196, + unicodeslot=0x0269, + }, + { + category="ll", + description="LATIN LETTER SMALL CAPITAL I", + direction="l", + linebreak="al", + unicodeslot=0x026A, + }, + { + category="ll", + description="LATIN SMALL LETTER L WITH MIDDLE TILDE", + direction="l", + linebreak="al", + shcode=0x006C, + uccode=0x2C62, + unicodeslot=0x026B, + }, + { + category="ll", + description="LATIN SMALL LETTER L WITH BELT", + direction="l", + linebreak="al", + shcode=0x006C, + unicodeslot=0x026C, + }, + { + category="ll", + description="LATIN SMALL LETTER L WITH RETROFLEX HOOK", + direction="l", + linebreak="al", + shcode=0x006C, + unicodeslot=0x026D, + }, + { + category="ll", + description="LATIN SMALL LETTER LEZH", + direction="l", + linebreak="al", + unicodeslot=0x026E, + }, + { + category="ll", + description="LATIN SMALL LETTER TURNED M", + direction="l", + linebreak="al", + uccode=0x019C, + unicodeslot=0x026F, + }, + { + category="ll", + description="LATIN SMALL LETTER TURNED M WITH LONG LEG", + direction="l", + linebreak="al", + unicodeslot=0x0270, + }, + { + category="ll", + description="LATIN SMALL LETTER M WITH HOOK", + direction="l", + linebreak="al", + shcode=0x006D, + unicodeslot=0x0271, + }, + { + category="ll", + description="LATIN SMALL LETTER N WITH LEFT HOOK", + direction="l", + linebreak="al", + shcode=0x006E, + uccode=0x019D, + unicodeslot=0x0272, + }, + { + category="ll", + description="LATIN SMALL LETTER N WITH RETROFLEX HOOK", + direction="l", + linebreak="al", + shcode=0x006E, + unicodeslot=0x0273, + }, + { + category="ll", + description="LATIN LETTER SMALL CAPITAL N", + direction="l", + linebreak="al", + unicodeslot=0x0274, + }, + { + category="ll", + description="LATIN SMALL LETTER BARRED O", + direction="l", + linebreak="al", + uccode=0x019F, + unicodeslot=0x0275, + }, + { + category="ll", + description="LATIN LETTER SMALL CAPITAL OE", + direction="l", + linebreak="al", + unicodeslot=0x0276, + }, + { + category="ll", + description="LATIN SMALL LETTER CLOSED OMEGA", + direction="l", + linebreak="al", + unicodeslot=0x0277, + }, + { + category="ll", + description="LATIN SMALL LETTER PHI", + direction="l", + linebreak="al", + unicodeslot=0x0278, + }, + { + category="ll", + description="LATIN SMALL LETTER TURNED R", + direction="l", + linebreak="al", + unicodeslot=0x0279, + }, + { + category="ll", + description="LATIN SMALL LETTER TURNED R WITH LONG LEG", + direction="l", + linebreak="al", + unicodeslot=0x027A, + }, + { + category="ll", + description="LATIN SMALL LETTER TURNED R WITH HOOK", + direction="l", + linebreak="al", + unicodeslot=0x027B, + }, + { + category="ll", + description="LATIN SMALL LETTER R WITH LONG LEG", + direction="l", + linebreak="al", + shcode=0x0072, + unicodeslot=0x027C, + }, + { + category="ll", + description="LATIN SMALL LETTER R WITH TAIL", + direction="l", + linebreak="al", + shcode=0x0072, + uccode=0x2C64, + unicodeslot=0x027D, + }, + { + category="ll", + description="LATIN SMALL LETTER R WITH FISHHOOK", + direction="l", + linebreak="al", + shcode=0x0072, + unicodeslot=0x027E, + }, + { + category="ll", + description="LATIN SMALL LETTER REVERSED R WITH FISHHOOK", + direction="l", + linebreak="al", + unicodeslot=0x027F, + }, + { + category="ll", + description="LATIN LETTER SMALL CAPITAL R", + direction="l", + linebreak="al", + uccode=0x01A6, + unicodeslot=0x0280, + }, + { + category="ll", + description="LATIN LETTER SMALL CAPITAL INVERTED R", + direction="l", + linebreak="al", + unicodeslot=0x0281, + }, + { + category="ll", + description="LATIN SMALL LETTER S WITH HOOK", + direction="l", + linebreak="al", + shcode=0x0073, + unicodeslot=0x0282, + }, + { + category="ll", + description="LATIN SMALL LETTER ESH", + direction="l", + linebreak="al", + uccode=0x01A9, + unicodeslot=0x0283, + }, + { + category="ll", + description="LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK", + direction="l", + linebreak="al", + unicodeslot=0x0284, + }, + { + category="ll", + description="LATIN SMALL LETTER SQUAT REVERSED ESH", + direction="l", + linebreak="al", + unicodeslot=0x0285, + }, + { + category="ll", + description="LATIN SMALL LETTER ESH WITH CURL", + direction="l", + linebreak="al", + shcode=0x0283, + unicodeslot=0x0286, + }, + { + category="ll", + description="LATIN SMALL LETTER TURNED T", + direction="l", + linebreak="al", + unicodeslot=0x0287, + }, + { + category="ll", + description="LATIN SMALL LETTER T WITH RETROFLEX HOOK", + direction="l", + linebreak="al", + shcode=0x0074, + uccode=0x01AE, + unicodeslot=0x0288, + }, + { + category="ll", + description="LATIN SMALL LETTER U BAR", + direction="l", + linebreak="al", + uccode=0x0244, + unicodeslot=0x0289, + }, + { + category="ll", + description="LATIN SMALL LETTER UPSILON", + direction="l", + linebreak="al", + uccode=0x01B1, + unicodeslot=0x028A, + }, + { + category="ll", + description="LATIN SMALL LETTER V WITH HOOK", + direction="l", + linebreak="al", + shcode=0x0076, + uccode=0x01B2, + unicodeslot=0x028B, + }, + { + category="ll", + description="LATIN SMALL LETTER TURNED V", + direction="l", + linebreak="al", + uccode=0x0245, + unicodeslot=0x028C, + }, + { + category="ll", + description="LATIN SMALL LETTER TURNED W", + direction="l", + linebreak="al", + unicodeslot=0x028D, + }, + { + category="ll", + description="LATIN SMALL LETTER TURNED Y", + direction="l", + linebreak="al", + unicodeslot=0x028E, + }, + { + category="ll", + description="LATIN LETTER SMALL CAPITAL Y", + direction="l", + linebreak="al", + unicodeslot=0x028F, + }, + { + category="ll", + description="LATIN SMALL LETTER Z WITH RETROFLEX HOOK", + direction="l", + linebreak="al", + shcode=0x007A, + unicodeslot=0x0290, + }, + { + category="ll", + description="LATIN SMALL LETTER Z WITH CURL", + direction="l", + linebreak="al", + shcode=0x007A, + unicodeslot=0x0291, + }, + { + category="ll", + description="LATIN SMALL LETTER EZH", + direction="l", + linebreak="al", + uccode=0x01B7, + unicodeslot=0x0292, + }, + { + category="ll", + description="LATIN SMALL LETTER EZH WITH CURL", + direction="l", + linebreak="al", + shcode=0x0292, + unicodeslot=0x0293, + }, + { + category="lo", + description="LATIN LETTER GLOTTAL STOP", + direction="l", + linebreak="al", + unicodeslot=0x0294, + }, + { + category="ll", + description="LATIN LETTER PHARYNGEAL VOICED FRICATIVE", + direction="l", + linebreak="al", + unicodeslot=0x0295, + }, + { + category="ll", + description="LATIN LETTER INVERTED GLOTTAL STOP", + direction="l", + linebreak="al", + unicodeslot=0x0296, + }, + { + category="ll", + description="LATIN LETTER STRETCHED C", + direction="l", + linebreak="al", + unicodeslot=0x0297, + }, + { + category="ll", + description="LATIN LETTER BILABIAL CLICK", + direction="l", + linebreak="al", + unicodeslot=0x0298, + }, + { + category="ll", + description="LATIN LETTER SMALL CAPITAL B", + direction="l", + linebreak="al", + unicodeslot=0x0299, + }, + { + category="ll", + description="LATIN SMALL LETTER CLOSED OPEN E", + direction="l", + linebreak="al", + unicodeslot=0x029A, + }, + { + category="ll", + description="LATIN LETTER SMALL CAPITAL G WITH HOOK", + direction="l", + linebreak="al", + unicodeslot=0x029B, + }, + { + category="ll", + description="LATIN LETTER SMALL CAPITAL H", + direction="l", + linebreak="al", + unicodeslot=0x029C, + }, + { + category="ll", + description="LATIN SMALL LETTER J WITH CROSSED-TAIL", + direction="l", + linebreak="al", + shcode=0x006A, + unicodeslot=0x029D, + }, + { + category="ll", + description="LATIN SMALL LETTER TURNED K", + direction="l", + linebreak="al", + unicodeslot=0x029E, + }, + { + category="ll", + description="LATIN LETTER SMALL CAPITAL L", + direction="l", + linebreak="al", + unicodeslot=0x029F, + }, + { + category="ll", + description="LATIN SMALL LETTER Q WITH HOOK", + direction="l", + linebreak="al", + shcode=0x0071, + unicodeslot=0x02A0, + }, + { + category="ll", + description="LATIN LETTER GLOTTAL STOP WITH STROKE", + direction="l", + linebreak="al", + unicodeslot=0x02A1, + }, + { + category="ll", + description="LATIN LETTER REVERSED GLOTTAL STOP WITH STROKE", + direction="l", + linebreak="al", + unicodeslot=0x02A2, + }, + { + category="ll", + description="LATIN SMALL LETTER DZ DIGRAPH", + direction="l", + linebreak="al", + unicodeslot=0x02A3, + }, + { + category="ll", + description="LATIN SMALL LETTER DEZH DIGRAPH", + direction="l", + linebreak="al", + unicodeslot=0x02A4, + }, + { + category="ll", + description="LATIN SMALL LETTER DZ DIGRAPH WITH CURL", + direction="l", + linebreak="al", + unicodeslot=0x02A5, + }, + { + category="ll", + description="LATIN SMALL LETTER TS DIGRAPH", + direction="l", + linebreak="al", + unicodeslot=0x02A6, + }, + { + category="ll", + description="LATIN SMALL LETTER TESH DIGRAPH", + direction="l", + linebreak="al", + unicodeslot=0x02A7, + }, + { + category="ll", + description="LATIN SMALL LETTER TC DIGRAPH WITH CURL", + direction="l", + linebreak="al", + unicodeslot=0x02A8, + }, + { + category="ll", + description="LATIN SMALL LETTER FENG DIGRAPH", + direction="l", + linebreak="al", + unicodeslot=0x02A9, + }, + { + category="ll", + description="LATIN SMALL LETTER LS DIGRAPH", + direction="l", + linebreak="al", + unicodeslot=0x02AA, + }, + { + category="ll", + description="LATIN SMALL LETTER LZ DIGRAPH", + direction="l", + linebreak="al", + unicodeslot=0x02AB, + }, + { + category="ll", + description="LATIN LETTER BILABIAL PERCUSSIVE", + direction="l", + linebreak="al", + unicodeslot=0x02AC, + }, + { + category="ll", + description="LATIN LETTER BIDENTAL PERCUSSIVE", + direction="l", + linebreak="al", + unicodeslot=0x02AD, + }, + { + category="ll", + description="LATIN SMALL LETTER TURNED H WITH FISHHOOK", + direction="l", + linebreak="al", + unicodeslot=0x02AE, + }, + { + category="ll", + description="LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL", + direction="l", + linebreak="al", + unicodeslot=0x02AF, + }, + { + category="lm", + description="MODIFIER LETTER SMALL H", + direction="l", + linebreak="al", + specials={ "super", 0x0068 }, + unicodeslot=0x02B0, + }, + { + category="lm", + description="MODIFIER LETTER SMALL H WITH HOOK", + direction="l", + linebreak="al", + specials={ "super", 0x0266 }, + unicodeslot=0x02B1, + }, + { + category="lm", + description="MODIFIER LETTER SMALL J", + direction="l", + linebreak="al", + specials={ "super", 0x006A }, + unicodeslot=0x02B2, + }, + { + category="lm", + description="MODIFIER LETTER SMALL R", + direction="l", + linebreak="al", + specials={ "super", 0x0072 }, + unicodeslot=0x02B3, + }, + { + category="lm", + description="MODIFIER LETTER SMALL TURNED R", + direction="l", + linebreak="al", + specials={ "super", 0x0279 }, + unicodeslot=0x02B4, + }, + { + category="lm", + description="MODIFIER LETTER SMALL TURNED R WITH HOOK", + direction="l", + linebreak="al", + specials={ "super", 0x027B }, + unicodeslot=0x02B5, + }, + { + category="lm", + description="MODIFIER LETTER SMALL CAPITAL INVERTED R", + direction="l", + linebreak="al", + specials={ "super", 0x0281 }, + unicodeslot=0x02B6, + }, + { + category="lm", + description="MODIFIER LETTER SMALL W", + direction="l", + linebreak="al", + specials={ "super", 0x0077 }, + unicodeslot=0x02B7, + }, + { + category="lm", + description="MODIFIER LETTER SMALL Y", + direction="l", + linebreak="al", + specials={ "super", 0x0079 }, + unicodeslot=0x02B8, + }, + { + category="lm", + description="MODIFIER LETTER PRIME", + direction="on", + linebreak="al", + unicodeslot=0x02B9, + }, + { + category="lm", + description="MODIFIER LETTER DOUBLE PRIME", + direction="on", + linebreak="al", + unicodeslot=0x02BA, + }, + { + category="lm", + description="MODIFIER LETTER TURNED COMMA", + direction="l", + linebreak="al", + unicodeslot=0x02BB, + }, + { + adobename="afii57929", + category="lm", + description="MODIFIER LETTER APOSTROPHE", + direction="l", + linebreak="al", + unicodeslot=0x02BC, + }, + { + adobename="afii64937", + category="lm", + description="MODIFIER LETTER REVERSED COMMA", + direction="l", + linebreak="al", + unicodeslot=0x02BD, + }, + { + category="lm", + description="MODIFIER LETTER RIGHT HALF RING", + direction="l", + linebreak="al", + unicodeslot=0x02BE, + }, + { + category="lm", + description="MODIFIER LETTER LEFT HALF RING", + direction="l", + linebreak="al", + unicodeslot=0x02BF, + }, + { + category="lm", + description="MODIFIER LETTER GLOTTAL STOP", + direction="l", + linebreak="al", + unicodeslot=0x02C0, + }, + { + category="lm", + description="MODIFIER LETTER REVERSED GLOTTAL STOP", + direction="l", + linebreak="al", + unicodeslot=0x02C1, + }, + { + category="sk", + description="MODIFIER LETTER LEFT ARROWHEAD", + direction="on", + linebreak="al", + unicodeslot=0x02C2, + }, + { + category="sk", + description="MODIFIER LETTER RIGHT ARROWHEAD", + direction="on", + linebreak="al", + unicodeslot=0x02C3, + }, + { + category="sk", + cjkwd="a", + description="MODIFIER LETTER UP ARROWHEAD", + direction="on", + linebreak="al", + unicodeslot=0x02C4, + }, + { + category="sk", + description="MODIFIER LETTER DOWN ARROWHEAD", + direction="on", + linebreak="al", + unicodeslot=0x02C5, + }, + { + adobename="circumflex", + category="lm", + contextname="textcircumflex", + description="MODIFIER LETTER CIRCUMFLEX ACCENT", + direction="on", + linebreak="al", + mathclass="accent", + mathname="hat", + specials={ "compat", 0x0020, 0x0302 }, + unicodeslot=0x02C6, + }, + { + adobename="caron", + category="lm", + cjkwd="a", + contextname="textcaron", + description="CARON", + direction="on", + linebreak="ai", + mathclass="accent", + mathname="check", + specials={ "compat", 0x0020, 0x030C }, + unicodeslot=0x02C7, + }, + { + category="lm", + description="MODIFIER LETTER VERTICAL LINE", + direction="on", + linebreak="bb", + unicodeslot=0x02C8, + }, + { + category="lm", + cjkwd="a", + description="MODIFIER LETTER MACRON", + direction="on", + linebreak="ai", + unicodeslot=0x02C9, + }, + { + category="lm", + cjkwd="a", + description="MODIFIER LETTER ACUTE ACCENT", + direction="on", + linebreak="ai", + unicodeslot=0x02CA, + }, + { + category="lm", + cjkwd="a", + description="MODIFIER LETTER GRAVE ACCENT", + direction="on", + linebreak="ai", + unicodeslot=0x02CB, + }, + { + category="lm", + description="MODIFIER LETTER LOW VERTICAL LINE", + direction="on", + linebreak="bb", + unicodeslot=0x02CC, + }, + { + category="lm", + cjkwd="a", + description="MODIFIER LETTER LOW MACRON", + direction="on", + linebreak="ai", + unicodeslot=0x02CD, + }, + { + category="lm", + description="MODIFIER LETTER LOW GRAVE ACCENT", + direction="on", + linebreak="al", + unicodeslot=0x02CE, + }, + { + category="lm", + description="MODIFIER LETTER LOW ACUTE ACCENT", + direction="on", + linebreak="al", + unicodeslot=0x02CF, + }, + { + category="lm", + cjkwd="a", + description="MODIFIER LETTER TRIANGULAR COLON", + direction="l", + linebreak="ai", + unicodeslot=0x02D0, + }, + { + category="lm", + description="MODIFIER LETTER HALF TRIANGULAR COLON", + direction="l", + linebreak="al", + unicodeslot=0x02D1, + }, + { + category="sk", + description="MODIFIER LETTER CENTRED RIGHT HALF RING", + direction="on", + linebreak="al", + unicodeslot=0x02D2, + }, + { + category="sk", + description="MODIFIER LETTER CENTRED LEFT HALF RING", + direction="on", + linebreak="al", + unicodeslot=0x02D3, + }, + { + category="sk", + description="MODIFIER LETTER UP TACK", + direction="on", + linebreak="al", + unicodeslot=0x02D4, + }, + { + category="sk", + description="MODIFIER LETTER DOWN TACK", + direction="on", + linebreak="al", + unicodeslot=0x02D5, + }, + { + category="sk", + description="MODIFIER LETTER PLUS SIGN", + direction="on", + linebreak="al", + unicodeslot=0x02D6, + }, + { + category="sk", + description="MODIFIER LETTER MINUS SIGN", + direction="on", + linebreak="al", + unicodeslot=0x02D7, + }, + { + adobename="breve", + category="sk", + cjkwd="a", + contextname="textbreve", + description="BREVE", + direction="on", + linebreak="ai", + mathclass="accent", + mathname="breve", + specials={ "compat", 0x0020, 0x0306 }, + unicodeslot=0x02D8, + }, + { + adobename="dotaccent", + category="sk", + cjkwd="a", + contextname="textdotaccent", + description="DOT ABOVE", + direction="on", + linebreak="ai", + mathclass="accent", + mathname="dot", + specials={ "compat", 0x0020, 0x0307 }, + unicodeslot=0x02D9, + }, + { + adobename="ring", + category="sk", + cjkwd="a", + contextname="textring", + description="RING ABOVE", + direction="on", + linebreak="ai", + mathclass="accent", + mathname="mathring", + specials={ "compat", 0x0020, 0x030A }, + unicodeslot=0x02DA, + }, + { + adobename="ogonek", + category="sk", + cjkwd="a", + contextname="textogonek", + description="OGONEK", + direction="on", + linebreak="ai", + specials={ "compat", 0x0020, 0x0328 }, + unicodeslot=0x02DB, + }, + { + adobename="tilde", + category="sk", + contextname="texttilde", + description="SMALL TILDE", + direction="on", + linebreak="al", + mathclass="accent", + mathname="tilde", + specials={ "compat", 0x0020, 0x0303 }, + unicodeslot=0x02DC, + }, + { + adobename="hungarumlaut", + category="sk", + cjkwd="a", + contextname="texthungarumlaut", + description="DOUBLE ACUTE ACCENT", + direction="on", + linebreak="ai", + specials={ "compat", 0x0020, 0x030B }, + unicodeslot=0x02DD, + }, + { + category="sk", + description="MODIFIER LETTER RHOTIC HOOK", + direction="on", + linebreak="al", + unicodeslot=0x02DE, + }, + { + category="sk", + cjkwd="a", + description="MODIFIER LETTER CROSS ACCENT", + direction="on", + linebreak="al", + unicodeslot=0x02DF, + }, + { + category="lm", + description="MODIFIER LETTER SMALL GAMMA", + direction="l", + linebreak="al", + specials={ "super", 0x0263 }, + unicodeslot=0x02E0, + }, + { + category="lm", + description="MODIFIER LETTER SMALL L", + direction="l", + linebreak="al", + specials={ "super", 0x006C }, + unicodeslot=0x02E1, + }, + { + category="lm", + description="MODIFIER LETTER SMALL S", + direction="l", + linebreak="al", + specials={ "super", 0x0073 }, + unicodeslot=0x02E2, + }, + { + category="lm", + description="MODIFIER LETTER SMALL X", + direction="l", + linebreak="al", + specials={ "super", 0x0078 }, + unicodeslot=0x02E3, + }, + { + category="lm", + description="MODIFIER LETTER SMALL REVERSED GLOTTAL STOP", + direction="l", + linebreak="al", + specials={ "super", 0x0295 }, + unicodeslot=0x02E4, + }, + { + category="sk", + description="MODIFIER LETTER EXTRA-HIGH TONE BAR", + direction="on", + linebreak="al", + unicodeslot=0x02E5, + }, + { + category="sk", + description="MODIFIER LETTER HIGH TONE BAR", + direction="on", + linebreak="al", + unicodeslot=0x02E6, + }, + { + category="sk", + description="MODIFIER LETTER MID TONE BAR", + direction="on", + linebreak="al", + unicodeslot=0x02E7, + }, + { + category="sk", + description="MODIFIER LETTER LOW TONE BAR", + direction="on", + linebreak="al", + unicodeslot=0x02E8, + }, + { + category="sk", + description="MODIFIER LETTER EXTRA-LOW TONE BAR", + direction="on", + linebreak="al", + unicodeslot=0x02E9, + }, + { + category="sk", + description="MODIFIER LETTER YIN DEPARTING TONE MARK", + direction="on", + linebreak="al", + unicodeslot=0x02EA, + }, + { + category="sk", + description="MODIFIER LETTER YANG DEPARTING TONE MARK", + direction="on", + linebreak="al", + unicodeslot=0x02EB, + }, + { + category="sk", + description="MODIFIER LETTER VOICING", + direction="on", + linebreak="al", + unicodeslot=0x02EC, + }, + { + category="sk", + description="MODIFIER LETTER UNASPIRATED", + direction="on", + linebreak="al", + unicodeslot=0x02ED, + }, + { + category="lm", + description="MODIFIER LETTER DOUBLE APOSTROPHE", + direction="l", + linebreak="al", + unicodeslot=0x02EE, + }, + { + category="sk", + description="MODIFIER LETTER LOW DOWN ARROWHEAD", + direction="on", + linebreak="al", + unicodeslot=0x02EF, + }, + { + category="sk", + description="MODIFIER LETTER LOW UP ARROWHEAD", + direction="on", + linebreak="al", + unicodeslot=0x02F0, + }, + { + category="sk", + description="MODIFIER LETTER LOW LEFT ARROWHEAD", + direction="on", + linebreak="al", + unicodeslot=0x02F1, + }, + { + category="sk", + description="MODIFIER LETTER LOW RIGHT ARROWHEAD", + direction="on", + linebreak="al", + unicodeslot=0x02F2, + }, + { + category="sk", + description="MODIFIER LETTER LOW RING", + direction="on", + linebreak="al", + unicodeslot=0x02F3, + }, + { + category="sk", + description="MODIFIER LETTER MIDDLE GRAVE ACCENT", + direction="on", + linebreak="al", + unicodeslot=0x02F4, + }, + { + category="sk", + description="MODIFIER LETTER MIDDLE DOUBLE GRAVE ACCENT", + direction="on", + linebreak="al", + unicodeslot=0x02F5, + }, + { + category="sk", + description="MODIFIER LETTER MIDDLE DOUBLE ACUTE ACCENT", + direction="on", + linebreak="al", + unicodeslot=0x02F6, + }, + { + category="sk", + description="MODIFIER LETTER LOW TILDE", + direction="on", + linebreak="al", + unicodeslot=0x02F7, + }, + { + category="sk", + description="MODIFIER LETTER RAISED COLON", + direction="on", + linebreak="al", + unicodeslot=0x02F8, + }, + { + category="sk", + description="MODIFIER LETTER BEGIN HIGH TONE", + direction="on", + linebreak="al", + unicodeslot=0x02F9, + }, + { + category="sk", + description="MODIFIER LETTER END HIGH TONE", + direction="on", + linebreak="al", + unicodeslot=0x02FA, + }, + { + category="sk", + description="MODIFIER LETTER BEGIN LOW TONE", + direction="on", + linebreak="al", + unicodeslot=0x02FB, + }, + { + category="sk", + description="MODIFIER LETTER END LOW TONE", + direction="on", + linebreak="al", + unicodeslot=0x02FC, + }, + { + category="sk", + description="MODIFIER LETTER SHELF", + direction="on", + linebreak="al", + unicodeslot=0x02FD, + }, + { + category="sk", + description="MODIFIER LETTER OPEN SHELF", + direction="on", + linebreak="al", + unicodeslot=0x02FE, + }, + { + category="sk", + description="MODIFIER LETTER LOW LEFT ARROW", + direction="on", + linebreak="al", + unicodeslot=0x02FF, + }, + { + adobename="gravecomb", + category="mn", + cjkwd="a", + description="COMBINING GRAVE ACCENT", + direction="nsm", + linebreak="cm", + unicodeslot=0x0300, + }, + { + adobename="acutecomb", + category="mn", + cjkwd="a", + description="COMBINING ACUTE ACCENT", + direction="nsm", + linebreak="cm", + unicodeslot=0x0301, + }, + { + category="mn", + cjkwd="a", + description="COMBINING CIRCUMFLEX ACCENT", + direction="nsm", + linebreak="cm", + mathstretch="h", + unicodeslot=0x0302, + }, + { + adobename="tildecomb", + category="mn", + cjkwd="a", + description="COMBINING TILDE", + direction="nsm", + linebreak="cm", + mathstretch="h", + unicodeslot=0x0303, + }, + { + category="mn", + cjkwd="a", + description="COMBINING MACRON", + direction="nsm", + linebreak="cm", + unicodeslot=0x0304, + }, + { + category="mn", + cjkwd="a", + description="COMBINING OVERLINE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0305, + }, + { + category="mn", + cjkwd="a", + description="COMBINING BREVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0306, + }, + { + category="mn", + cjkwd="a", + description="COMBINING DOT ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0307, + }, + { + category="mn", + cjkwd="a", + description="COMBINING DIAERESIS", + direction="nsm", + linebreak="cm", + unicodeslot=0x0308, + }, + { + adobename="hookabovecomb", + category="mn", + cjkwd="a", + description="COMBINING HOOK ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0309, + }, + { + category="mn", + cjkwd="a", + description="COMBINING RING ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x030A, + }, + { + category="mn", + cjkwd="a", + description="COMBINING DOUBLE ACUTE ACCENT", + direction="nsm", + linebreak="cm", + unicodeslot=0x030B, + }, + { + category="mn", + cjkwd="a", + description="COMBINING CARON", + direction="nsm", + linebreak="cm", + unicodeslot=0x030C, + }, + { + category="mn", + cjkwd="a", + description="COMBINING VERTICAL LINE ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x030D, + }, + { + category="mn", + cjkwd="a", + description="COMBINING DOUBLE VERTICAL LINE ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x030E, + }, + { + category="mn", + cjkwd="a", + description="COMBINING DOUBLE GRAVE ACCENT", + direction="nsm", + linebreak="cm", + unicodeslot=0x030F, + }, + { + category="mn", + cjkwd="a", + description="COMBINING CANDRABINDU", + direction="nsm", + linebreak="cm", + unicodeslot=0x0310, + }, + { + category="mn", + cjkwd="a", + description="COMBINING INVERTED BREVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0311, + }, + { + category="mn", + cjkwd="a", + description="COMBINING TURNED COMMA ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0312, + }, + { + category="mn", + cjkwd="a", + description="COMBINING COMMA ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0313, + }, + { + category="mn", + cjkwd="a", + description="COMBINING REVERSED COMMA ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0314, + }, + { + category="mn", + cjkwd="a", + description="COMBINING COMMA ABOVE RIGHT", + direction="nsm", + linebreak="cm", + unicodeslot=0x0315, + }, + { + category="mn", + cjkwd="a", + description="COMBINING GRAVE ACCENT BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0316, + }, + { + category="mn", + cjkwd="a", + description="COMBINING ACUTE ACCENT BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0317, + }, + { + category="mn", + cjkwd="a", + description="COMBINING LEFT TACK BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0318, + }, + { + category="mn", + cjkwd="a", + description="COMBINING RIGHT TACK BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0319, + }, + { + category="mn", + cjkwd="a", + description="COMBINING LEFT ANGLE ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x031A, + }, + { + category="mn", + cjkwd="a", + description="COMBINING HORN", + direction="nsm", + linebreak="cm", + unicodeslot=0x031B, + }, + { + category="mn", + cjkwd="a", + description="COMBINING LEFT HALF RING BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x031C, + }, + { + category="mn", + cjkwd="a", + description="COMBINING UP TACK BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x031D, + }, + { + category="mn", + cjkwd="a", + description="COMBINING DOWN TACK BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x031E, + }, + { + category="mn", + cjkwd="a", + description="COMBINING PLUS SIGN BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x031F, + }, + { + category="mn", + cjkwd="a", + description="COMBINING MINUS SIGN BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0320, + }, + { + category="mn", + cjkwd="a", + description="COMBINING PALATALIZED HOOK BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0321, + }, + { + category="mn", + cjkwd="a", + description="COMBINING RETROFLEX HOOK BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0322, + }, + { + adobename="dotbelowcomb", + category="mn", + cjkwd="a", + contextname="textbottomdot", + description="COMBINING DOT BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0323, + }, + { + category="mn", + cjkwd="a", + description="COMBINING DIAERESIS BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0324, + }, + { + category="mn", + cjkwd="a", + description="COMBINING RING BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0325, + }, + { + category="mn", + cjkwd="a", + contextname="textbottomcomma", + description="COMBINING COMMA BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0326, + }, + { + category="mn", + cjkwd="a", + description="COMBINING CEDILLA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0327, + }, + { + category="mn", + cjkwd="a", + description="COMBINING OGONEK", + direction="nsm", + linebreak="cm", + unicodeslot=0x0328, + }, + { + category="mn", + cjkwd="a", + description="COMBINING VERTICAL LINE BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0329, + }, + { + category="mn", + cjkwd="a", + description="COMBINING BRIDGE BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x032A, + }, + { + category="mn", + cjkwd="a", + description="COMBINING INVERTED DOUBLE ARCH BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x032B, + }, + { + category="mn", + cjkwd="a", + description="COMBINING CARON BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x032C, + }, + { + category="mn", + cjkwd="a", + description="COMBINING CIRCUMFLEX ACCENT BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x032D, + }, + { + category="mn", + cjkwd="a", + description="COMBINING BREVE BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x032E, + }, + { + category="mn", + cjkwd="a", + description="COMBINING INVERTED BREVE BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x032F, + }, + { + category="mn", + cjkwd="a", + description="COMBINING TILDE BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0330, + }, + { + category="mn", + cjkwd="a", + description="COMBINING MACRON BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0331, + }, + { + category="mn", + cjkwd="a", + description="COMBINING LOW LINE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0332, + }, + { + category="mn", + cjkwd="a", + description="COMBINING DOUBLE LOW LINE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0333, + }, + { + category="mn", + cjkwd="a", + description="COMBINING TILDE OVERLAY", + direction="nsm", + linebreak="cm", + unicodeslot=0x0334, + }, + { + category="mn", + cjkwd="a", + description="COMBINING SHORT STROKE OVERLAY", + direction="nsm", + linebreak="cm", + unicodeslot=0x0335, + }, + { + category="mn", + cjkwd="a", + description="COMBINING LONG STROKE OVERLAY", + direction="nsm", + linebreak="cm", + unicodeslot=0x0336, + }, + { + category="mn", + cjkwd="a", + description="COMBINING SHORT SOLIDUS OVERLAY", + direction="nsm", + linebreak="cm", + unicodeslot=0x0337, + }, + { + category="mn", + cjkwd="a", + description="COMBINING LONG SOLIDUS OVERLAY", + direction="nsm", + linebreak="cm", + mathclass="relation", + mathname="not", + unicodeslot=0x0338, + }, + { + category="mn", + cjkwd="a", + description="COMBINING RIGHT HALF RING BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0339, + }, + { + category="mn", + cjkwd="a", + description="COMBINING INVERTED BRIDGE BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x033A, + }, + { + category="mn", + cjkwd="a", + description="COMBINING SQUARE BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x033B, + }, + { + category="mn", + cjkwd="a", + description="COMBINING SEAGULL BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x033C, + }, + { + category="mn", + cjkwd="a", + description="COMBINING X ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x033D, + }, + { + category="mn", + cjkwd="a", + description="COMBINING VERTICAL TILDE", + direction="nsm", + linebreak="cm", + unicodeslot=0x033E, + }, + { + category="mn", + cjkwd="a", + description="COMBINING DOUBLE OVERLINE", + direction="nsm", + linebreak="cm", + unicodeslot=0x033F, + }, + { + category="mn", + cjkwd="a", + description="COMBINING GRAVE TONE MARK", + direction="nsm", + linebreak="cm", + specials={ "char", 0x0300 }, + unicodeslot=0x0340, + }, + { + category="mn", + cjkwd="a", + description="COMBINING ACUTE TONE MARK", + direction="nsm", + linebreak="cm", + specials={ "char", 0x0301 }, + unicodeslot=0x0341, + }, + { + category="mn", + cjkwd="a", + description="COMBINING GREEK PERISPOMENI", + direction="nsm", + linebreak="cm", + unicodeslot=0x0342, + }, + { + category="mn", + cjkwd="a", + description="COMBINING GREEK KORONIS", + direction="nsm", + linebreak="cm", + specials={ "char", 0x0313 }, + unicodeslot=0x0343, + }, + { + category="mn", + cjkwd="a", + description="COMBINING GREEK DIALYTIKA TONOS", + direction="nsm", + linebreak="cm", + specials={ "char", 0x0308, 0x0301 }, + unicodeslot=0x0344, + }, + { + category="mn", + cjkwd="a", + description="COMBINING GREEK YPOGEGRAMMENI", + direction="nsm", + linebreak="cm", + uccode=0x0399, + unicodeslot=0x0345, + }, + { + category="mn", + cjkwd="a", + description="COMBINING BRIDGE ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0346, + }, + { + category="mn", + cjkwd="a", + description="COMBINING EQUALS SIGN BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0347, + }, + { + category="mn", + cjkwd="a", + description="COMBINING DOUBLE VERTICAL LINE BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0348, + }, + { + category="mn", + cjkwd="a", + description="COMBINING LEFT ANGLE BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0349, + }, + { + category="mn", + cjkwd="a", + description="COMBINING NOT TILDE ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x034A, + }, + { + category="mn", + cjkwd="a", + description="COMBINING HOMOTHETIC ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x034B, + }, + { + category="mn", + cjkwd="a", + description="COMBINING ALMOST EQUAL TO ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x034C, + }, + { + category="mn", + cjkwd="a", + description="COMBINING LEFT RIGHT ARROW BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x034D, + }, + { + category="mn", + cjkwd="a", + description="COMBINING UPWARDS ARROW BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x034E, + }, + { + category="mn", + cjkwd="a", + description="COMBINING GRAPHEME JOINER", + direction="nsm", + linebreak="gl", + unicodeslot=0x034F, + }, + { + category="mn", + cjkwd="a", + description="COMBINING RIGHT ARROWHEAD ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0350, + }, + { + category="mn", + cjkwd="a", + description="COMBINING LEFT HALF RING ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0351, + }, + { + category="mn", + cjkwd="a", + description="COMBINING FERMATA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0352, + }, + { + category="mn", + cjkwd="a", + description="COMBINING X BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0353, + }, + { + category="mn", + cjkwd="a", + description="COMBINING LEFT ARROWHEAD BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0354, + }, + { + category="mn", + cjkwd="a", + description="COMBINING RIGHT ARROWHEAD BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0355, + }, + { + category="mn", + cjkwd="a", + description="COMBINING RIGHT ARROWHEAD AND UP ARROWHEAD BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0356, + }, + { + category="mn", + cjkwd="a", + description="COMBINING RIGHT HALF RING ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0357, + }, + { + category="mn", + cjkwd="a", + description="COMBINING DOT ABOVE RIGHT", + direction="nsm", + linebreak="cm", + unicodeslot=0x0358, + }, + { + category="mn", + cjkwd="a", + description="COMBINING ASTERISK BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0359, + }, + { + category="mn", + cjkwd="a", + description="COMBINING DOUBLE RING BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x035A, + }, + { + category="mn", + cjkwd="a", + description="COMBINING ZIGZAG ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x035B, + }, + { + category="mn", + cjkwd="a", + description="COMBINING DOUBLE BREVE BELOW", + direction="nsm", + linebreak="gl", + unicodeslot=0x035C, + }, + { + category="mn", + cjkwd="a", + description="COMBINING DOUBLE BREVE", + direction="nsm", + linebreak="gl", + unicodeslot=0x035D, + }, + { + category="mn", + cjkwd="a", + description="COMBINING DOUBLE MACRON", + direction="nsm", + linebreak="gl", + unicodeslot=0x035E, + }, + { + category="mn", + cjkwd="a", + description="COMBINING DOUBLE MACRON BELOW", + direction="nsm", + linebreak="gl", + unicodeslot=0x035F, + }, + { + category="mn", + cjkwd="a", + description="COMBINING DOUBLE TILDE", + direction="nsm", + linebreak="gl", + unicodeslot=0x0360, + }, + { + category="mn", + cjkwd="a", + description="COMBINING DOUBLE INVERTED BREVE", + direction="nsm", + linebreak="gl", + unicodeslot=0x0361, + }, + { + category="mn", + cjkwd="a", + description="COMBINING DOUBLE RIGHTWARDS ARROW BELOW", + direction="nsm", + linebreak="gl", + unicodeslot=0x0362, + }, + { + category="mn", + cjkwd="a", + description="COMBINING LATIN SMALL LETTER A", + direction="nsm", + linebreak="cm", + unicodeslot=0x0363, + }, + { + category="mn", + cjkwd="a", + description="COMBINING LATIN SMALL LETTER E", + direction="nsm", + linebreak="cm", + unicodeslot=0x0364, + }, + { + category="mn", + cjkwd="a", + description="COMBINING LATIN SMALL LETTER I", + direction="nsm", + linebreak="cm", + unicodeslot=0x0365, + }, + { + category="mn", + cjkwd="a", + description="COMBINING LATIN SMALL LETTER O", + direction="nsm", + linebreak="cm", + unicodeslot=0x0366, + }, + { + category="mn", + cjkwd="a", + description="COMBINING LATIN SMALL LETTER U", + direction="nsm", + linebreak="cm", + unicodeslot=0x0367, + }, + { + category="mn", + cjkwd="a", + description="COMBINING LATIN SMALL LETTER C", + direction="nsm", + linebreak="cm", + unicodeslot=0x0368, + }, + { + category="mn", + cjkwd="a", + description="COMBINING LATIN SMALL LETTER D", + direction="nsm", + linebreak="cm", + unicodeslot=0x0369, + }, + { + category="mn", + cjkwd="a", + description="COMBINING LATIN SMALL LETTER H", + direction="nsm", + linebreak="cm", + unicodeslot=0x036A, + }, + { + category="mn", + cjkwd="a", + description="COMBINING LATIN SMALL LETTER M", + direction="nsm", + linebreak="cm", + unicodeslot=0x036B, + }, + { + category="mn", + cjkwd="a", + description="COMBINING LATIN SMALL LETTER R", + direction="nsm", + linebreak="cm", + unicodeslot=0x036C, + }, + { + category="mn", + cjkwd="a", + description="COMBINING LATIN SMALL LETTER T", + direction="nsm", + linebreak="cm", + unicodeslot=0x036D, + }, + { + category="mn", + cjkwd="a", + description="COMBINING LATIN SMALL LETTER V", + direction="nsm", + linebreak="cm", + unicodeslot=0x036E, + }, + { + category="mn", + cjkwd="a", + description="COMBINING LATIN SMALL LETTER X", + direction="nsm", + linebreak="cm", + unicodeslot=0x036F, + }, + [0x0374]={ + category="sk", + description="GREEK NUMERAL SIGN", + direction="on", + linebreak="al", + specials={ "char", 0x02B9 }, + unicodeslot=0x0374, + }, + [0x0375]={ + category="sk", + description="GREEK LOWER NUMERAL SIGN", + direction="on", + linebreak="al", + unicodeslot=0x0375, + }, + [0x037A]={ + category="lm", + description="GREEK YPOGEGRAMMENI", + direction="l", + linebreak="al", + specials={ "compat", 0x0020, 0x0345 }, + unicodeslot=0x037A, + }, + [0x037B]={ + category="ll", + description="GREEK SMALL REVERSED LUNATE SIGMA SYMBOL", + direction="l", + linebreak="al", + uccode=0x03FD, + unicodeslot=0x037B, + }, + [0x037C]={ + category="ll", + description="GREEK SMALL DOTTED LUNATE SIGMA SYMBOL", + direction="l", + linebreak="al", + uccode=0x03FE, + unicodeslot=0x037C, + }, + [0x037D]={ + category="ll", + description="GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL", + direction="l", + linebreak="al", + uccode=0x03FF, + unicodeslot=0x037D, + }, + [0x037E]={ + category="po", + description="GREEK QUESTION MARK", + direction="on", + linebreak="is", + specials={ "char", 0x003B }, + unicodeslot=0x037E, + }, + [0x0384]={ + adobename="tonos", + category="sk", + contextname="greektonos", + description="GREEK TONOS", + direction="on", + linebreak="al", + specials={ "compat", 0x0020, 0x0301 }, + unicodeslot=0x0384, + }, + [0x0385]={ + adobename="dieresistonos", + category="sk", + contextname="greekdialytikatonos", + description="GREEK DIALYTIKA TONOS", + direction="on", + linebreak="al", + specials={ "char", 0x00A8, 0x0301 }, + unicodeslot=0x0385, + }, + [0x0386]={ + adobename="Alphatonos", + category="lu", + contextname="greekAlphatonos", + description="GREEK CAPITAL LETTER ALPHA WITH TONOS", + direction="l", + lccode=0x03AC, + linebreak="al", + shcode=0x0391, + specials={ "char", 0x0391, 0x0301 }, + unicodeslot=0x0386, + }, + [0x0387]={ + adobename="anoteleia", + category="po", + description="GREEK ANO TELEIA", + direction="on", + linebreak="al", + specials={ "char", 0x00B7 }, + unicodeslot=0x0387, + }, + [0x0388]={ + adobename="Epsilontonos", + category="lu", + contextname="greekEpsilontonos", + description="GREEK CAPITAL LETTER EPSILON WITH TONOS", + direction="l", + lccode=0x03AD, + linebreak="al", + shcode=0x0395, + specials={ "char", 0x0395, 0x0301 }, + unicodeslot=0x0388, + }, + [0x0389]={ + adobename="Etatonos", + category="lu", + contextname="greekEtatonos", + description="GREEK CAPITAL LETTER ETA WITH TONOS", + direction="l", + lccode=0x03AE, + linebreak="al", + shcode=0x0397, + specials={ "char", 0x0397, 0x0301 }, + unicodeslot=0x0389, + }, + [0x038A]={ + adobename="Iotatonos", + category="lu", + contextname="greekIotatonos", + description="GREEK CAPITAL LETTER IOTA WITH TONOS", + direction="l", + lccode=0x03AF, + linebreak="al", + shcode=0x0399, + specials={ "char", 0x0399, 0x0301 }, + unicodeslot=0x038A, + }, + [0x038C]={ + adobename="Omicrontonos", + category="lu", + contextname="greekOmicrontonos", + description="GREEK CAPITAL LETTER OMICRON WITH TONOS", + direction="l", + lccode=0x03CC, + linebreak="al", + shcode=0x039F, + specials={ "char", 0x039F, 0x0301 }, + unicodeslot=0x038C, + }, + [0x038E]={ + adobename="Upsilontonos", + category="lu", + contextname="greekUpsilontonos", + description="GREEK CAPITAL LETTER UPSILON WITH TONOS", + direction="l", + lccode=0x03CD, + linebreak="al", + shcode=0x03A5, + specials={ "char", 0x03A5, 0x0301 }, + unicodeslot=0x038E, + }, + [0x038F]={ + adobename="Omegatonos", + category="lu", + contextname="greekOmegatonos", + description="GREEK CAPITAL LETTER OMEGA WITH TONOS", + direction="l", + lccode=0x03CE, + linebreak="al", + shcode=0x03A9, + specials={ "char", 0x03A9, 0x0301 }, + unicodeslot=0x038F, + }, + [0x0390]={ + adobename="iotadieresistonos", + category="ll", + contextname="greekiotadialytikatonos", + description="GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS", + direction="l", + linebreak="al", + shcode=0x03B9, + specials={ "char", 0x03CA, 0x0301 }, + unicodeslot=0x0390, + }, + [0x0391]={ + adobename="Alpha", + category="lu", + cjkwd="a", + contextname="greekAlpha", + description="GREEK CAPITAL LETTER ALPHA", + direction="l", + lccode=0x03B1, + mathclass="variable", + mathname="Alpha", + linebreak="al", + unicodeslot=0x0391, + }, + [0x0392]={ + adobename="Beta", + category="lu", + cjkwd="a", + contextname="greekBeta", + description="GREEK CAPITAL LETTER BETA", + direction="l", + lccode=0x03B2, + mathclass="variable", + mathname="Beta", + linebreak="al", + unicodeslot=0x0392, + }, + [0x0393]={ + adobename="Gamma", + category="lu", + cjkwd="a", + contextname="greekGamma", + description="GREEK CAPITAL LETTER GAMMA", + direction="l", + mathclass="variable", + mathname="Gamma", + lccode=0x03B3, + linebreak="al", + unicodeslot=0x0393, + }, + [0x0394]={ + category="lu", + cjkwd="a", + contextname="greekDelta", + description="GREEK CAPITAL LETTER DELTA", + direction="l", + mathclass="variable", + mathname="Delta", + lccode=0x03B4, + linebreak="al", + unicodeslot=0x0394, + }, + [0x0395]={ + adobename="Epsilon", + category="lu", + cjkwd="a", + contextname="greekEpsilon", + description="GREEK CAPITAL LETTER EPSILON", + direction="l", + mathclass="variable", + mathname="Epsilon", + lccode=0x03B5, + linebreak="al", + unicodeslot=0x0395, + }, + [0x0396]={ + adobename="Zeta", + category="lu", + cjkwd="a", + contextname="greekZeta", + description="GREEK CAPITAL LETTER ZETA", + direction="l", + mathclass="variable", + mathname="Zeta", + lccode=0x03B6, + linebreak="al", + unicodeslot=0x0396, + }, + [0x0397]={ + adobename="Eta", + category="lu", + cjkwd="a", + contextname="greekEta", + description="GREEK CAPITAL LETTER ETA", + direction="l", + mathclass="variable", + mathname="Eta", + lccode=0x03B7, + linebreak="al", + unicodeslot=0x0397, + }, + [0x0398]={ + adobename="Theta", + category="lu", + cjkwd="a", + contextname="greekTheta", + description="GREEK CAPITAL LETTER THETA", + direction="l", + mathclass="variable", + mathname="Theta", + lccode=0x03B8, + linebreak="al", + unicodeslot=0x0398, + }, + [0x0399]={ + adobename="Iota", + category="lu", + cjkwd="a", + contextname="greekIota", + description="GREEK CAPITAL LETTER IOTA", + direction="l", + mathclass="variable", + mathname="Iota", + lccode=0x03B9, + linebreak="al", + unicodeslot=0x0399, + }, + [0x039A]={ + adobename="Kappa", + category="lu", + cjkwd="a", + contextname="greekKappa", + description="GREEK CAPITAL LETTER KAPPA", + direction="l", + mathclass="variable", + mathname="Kappa", + lccode=0x03BA, + linebreak="al", + unicodeslot=0x039A, + }, + [0x039B]={ + adobename="Lambda", + category="lu", + cjkwd="a", + contextname="greekLambda", + description="GREEK CAPITAL LETTER LAMDA", + direction="l", + mathclass="variable", + mathname="Lambda", + lccode=0x03BB, + linebreak="al", + unicodeslot=0x039B, + }, + [0x039C]={ + adobename="Mu", + category="lu", + cjkwd="a", + contextname="greekMu", + description="GREEK CAPITAL LETTER MU", + direction="l", + mathclass="variable", + mathname="Mu", + lccode=0x03BC, + linebreak="al", + unicodeslot=0x039C, + }, + [0x039D]={ + adobename="Nu", + category="lu", + cjkwd="a", + contextname="greekNu", + description="GREEK CAPITAL LETTER NU", + direction="l", + mathclass="variable", + mathname="Nu", + lccode=0x03BD, + linebreak="al", + unicodeslot=0x039D, + }, + [0x039E]={ + adobename="Xi", + category="lu", + cjkwd="a", + contextname="greekXi", + description="GREEK CAPITAL LETTER XI", + direction="l", + mathclass="variable", + mathname="Xi", + lccode=0x03BE, + linebreak="al", + unicodeslot=0x039E, + }, + [0x039F]={ + adobename="Omicron", + category="lu", + cjkwd="a", + contextname="greekOmicron", + description="GREEK CAPITAL LETTER OMICRON", + direction="l", + mathclass="variable", + mathname="Omicron", + lccode=0x03BF, + linebreak="al", + unicodeslot=0x039F, + }, + [0x03A0]={ + adobename="Pi", + category="lu", + cjkwd="a", + contextname="greekPi", + description="GREEK CAPITAL LETTER PI", + direction="l", + mathclass="variable", + mathname="Pi", + lccode=0x03C0, + linebreak="al", + unicodeslot=0x03A0, + }, + [0x03A1]={ + adobename="Rho", + category="lu", + cjkwd="a", + contextname="greekRho", + description="GREEK CAPITAL LETTER RHO", + direction="l", + mathclass="variable", + mathname="Rho", + lccode=0x03C1, + linebreak="al", + unicodeslot=0x03A1, + }, + [0x03A3]={ + adobename="Sigma", + category="lu", + cjkwd="a", + contextname="greekSigma", + description="GREEK CAPITAL LETTER SIGMA", + direction="l", + mathclass="variable", + mathname="Sigma", + lccode=0x03C3, + linebreak="al", + unicodeslot=0x03A3, + }, + [0x03A4]={ + adobename="Tau", + category="lu", + cjkwd="a", + contextname="greekTau", + description="GREEK CAPITAL LETTER TAU", + direction="l", + mathclass="variable", + mathname="Tau", + lccode=0x03C4, + linebreak="al", + unicodeslot=0x03A4, + }, + [0x03A5]={ + adobename="Upsilon", + category="lu", + cjkwd="a", + contextname="greekUpsilon", + description="GREEK CAPITAL LETTER UPSILON", + direction="l", + mathclass="variable", + mathname="Upsilon", + lccode=0x03C5, + linebreak="al", + unicodeslot=0x03A5, + }, + [0x03A6]={ + adobename="Phi", + category="lu", + cjkwd="a", + contextname="greekPhi", + description="GREEK CAPITAL LETTER PHI", + direction="l", + mathclass="variable", + mathname="Phi", + lccode=0x03C6, + linebreak="al", + unicodeslot=0x03A6, + }, + [0x03A7]={ + adobename="Chi", + category="lu", + cjkwd="a", + contextname="greekChi", + description="GREEK CAPITAL LETTER CHI", + direction="l", + mathclass="variable", + mathname="Chi", + lccode=0x03C7, + linebreak="al", + unicodeslot=0x03A7, + }, + [0x03A8]={ + adobename="Psi", + category="lu", + cjkwd="a", + contextname="greekPsi", + description="GREEK CAPITAL LETTER PSI", + direction="l", + mathclass="variable", + mathname="Psi", + lccode=0x03C8, + linebreak="al", + unicodeslot=0x03A8, + }, + [0x03A9]={ + category="lu", + cjkwd="a", + contextname="greekOmega", + description="GREEK CAPITAL LETTER OMEGA", + direction="l", + mathclass="variable", + mathname="Omega", + lccode=0x03C9, + linebreak="al", + unicodeslot=0x03A9, + }, + [0x03AA]={ + adobename="Iotadieresis", + category="lu", + contextname="greekIotadialytika", + description="GREEK CAPITAL LETTER IOTA WITH DIALYTIKA", + direction="l", + lccode=0x03CA, + linebreak="al", + shcode=0x0399, + specials={ "char", 0x0399, 0x0308 }, + unicodeslot=0x03AA, + }, + [0x03AB]={ + adobename="Upsilondieresis", + category="lu", + contextname="greekUpsilondialytika", + description="GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA", + direction="l", + lccode=0x03CB, + linebreak="al", + shcode=0x03A5, + specials={ "char", 0x03A5, 0x0308 }, + unicodeslot=0x03AB, + }, + [0x03AC]={ + adobename="alphatonos", + category="ll", + contextname="greekalphatonos", + description="GREEK SMALL LETTER ALPHA WITH TONOS", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x03B1, 0x0301 }, + uccode=0x0386, + unicodeslot=0x03AC, + }, + [0x03AD]={ + adobename="epsilontonos", + category="ll", + contextname="greekepsilontonos", + description="GREEK SMALL LETTER EPSILON WITH TONOS", + direction="l", + linebreak="al", + shcode=0x03B5, + specials={ "char", 0x03B5, 0x0301 }, + uccode=0x0388, + unicodeslot=0x03AD, + }, + [0x03AE]={ + adobename="etatonos", + category="ll", + contextname="greeketatonos", + description="GREEK SMALL LETTER ETA WITH TONOS", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x03B7, 0x0301 }, + uccode=0x0389, + unicodeslot=0x03AE, + }, + [0x03AF]={ + adobename="iotatonos", + category="ll", + contextname="greekiotatonos", + description="GREEK SMALL LETTER IOTA WITH TONOS", + direction="l", + linebreak="al", + shcode=0x03B9, + specials={ "char", 0x03B9, 0x0301 }, + uccode=0x038A, + unicodeslot=0x03AF, + }, + [0x03B0]={ + adobename="upsilondieresistonos", + category="ll", + contextname="greekupsilondialytikatonos", + description="GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS", + direction="l", + linebreak="al", + shcode=0x03C5, + specials={ "char", 0x03CB, 0x0301 }, + unicodeslot=0x03B0, + }, + [0x03B1]={ + adobename="alpha", + category="ll", + cjkwd="a", + contextname="greekalpha", + description="GREEK SMALL LETTER ALPHA", + direction="l", + linebreak="al", + mathclass="variable", + mathname="alpha", + uccode=0x0391, + unicodeslot=0x03B1, + }, + [0x03B2]={ + adobename="beta", + category="ll", + cjkwd="a", + contextname="greekbeta", + description="GREEK SMALL LETTER BETA", + direction="l", + linebreak="al", + mathclass="variable", + mathname="beta", + uccode=0x0392, + unicodeslot=0x03B2, + }, + [0x03B3]={ + adobename="gamma", + category="ll", + cjkwd="a", + contextname="greekgamma", + description="GREEK SMALL LETTER GAMMA", + direction="l", + linebreak="al", + mathclass="variable", + mathname="gamma", + uccode=0x0393, + unicodeslot=0x03B3, + }, + [0x03B4]={ + adobename="delta", + category="ll", + cjkwd="a", + contextname="greekdelta", + description="GREEK SMALL LETTER DELTA", + direction="l", + linebreak="al", + mathclass="variable", + mathname="delta", + uccode=0x0394, + unicodeslot=0x03B4, + }, + [0x03B5]={ + adobename="epsilon", + category="ll", + cjkwd="a", + contextname="greekepsilon", + description="GREEK SMALL LETTER EPSILON", + direction="l", + linebreak="al", + mathclass="variable", + mathname="varepsilon", + uccode=0x0395, + unicodeslot=0x03B5, + }, + [0x03B6]={ + adobename="zeta", + category="ll", + cjkwd="a", + contextname="greekzeta", + description="GREEK SMALL LETTER ZETA", + direction="l", + linebreak="al", + mathclass="variable", + mathname="zeta", + uccode=0x0396, + unicodeslot=0x03B6, + }, + [0x03B7]={ + adobename="eta", + category="ll", + cjkwd="a", + contextname="greeketa", + description="GREEK SMALL LETTER ETA", + direction="l", + linebreak="al", + mathclass="variable", + mathname="eta", + uccode=0x0397, + unicodeslot=0x03B7, + }, + [0x03B8]={ + adobename="theta", + category="ll", + cjkwd="a", + contextname="greektheta", + description="GREEK SMALL LETTER THETA", + direction="l", + linebreak="al", + mathclass="variable", + mathname="theta", + uccode=0x0398, + unicodeslot=0x03B8, + }, + [0x03B9]={ + adobename="iota", + category="ll", + cjkwd="a", + contextname="greekiota", + description="GREEK SMALL LETTER IOTA", + direction="l", + linebreak="al", + mathclass="variable", + mathname="iota", + uccode=0x0399, + unicodeslot=0x03B9, + }, + [0x03BA]={ + adobename="kappa", + category="ll", + cjkwd="a", + contextname="greekkappa", + description="GREEK SMALL LETTER KAPPA", + direction="l", + linebreak="al", + mathclass="variable", + mathname="kappa", + uccode=0x039A, + unicodeslot=0x03BA, + }, + [0x03BB]={ + adobename="lambda", + category="ll", + cjkwd="a", + contextname="greeklambda", + description="GREEK SMALL LETTER LAMDA", + direction="l", + linebreak="al", + mathclass="variable", + mathname="lambda", + uccode=0x039B, + unicodeslot=0x03BB, + }, + [0x03BC]={ + category="ll", + cjkwd="a", + contextname="greekmu", + description="GREEK SMALL LETTER MU", + direction="l", + linebreak="al", + mathclass="variable", + mathname="mu", + uccode=0x039C, + unicodeslot=0x03BC, + }, + [0x03BD]={ + adobename="nu", + category="ll", + cjkwd="a", + contextname="greeknu", + description="GREEK SMALL LETTER NU", + direction="l", + linebreak="al", + mathclass="variable", + mathname="nu", + uccode=0x039D, + unicodeslot=0x03BD, + }, + [0x03BE]={ + adobename="xi", + category="ll", + cjkwd="a", + contextname="greekxi", + description="GREEK SMALL LETTER XI", + direction="l", + linebreak="al", + mathclass="variable", + mathname="xi", + uccode=0x039E, + unicodeslot=0x03BE, + }, + [0x03BF]={ + adobename="omicron", + category="ll", + cjkwd="a", + contextname="greekomicron", + description="GREEK SMALL LETTER OMICRON", + direction="l", + linebreak="al", + mathclass="variable", + mathname="omicron", + uccode=0x039F, + unicodeslot=0x03BF, + }, + [0x03C0]={ + adobename="pi", + category="ll", + cjkwd="a", + contextname="greekpi", + description="GREEK SMALL LETTER PI", + direction="l", + linebreak="al", + mathclass="variable", + mathname="pi", + uccode=0x03A0, + unicodeslot=0x03C0, + }, + [0x03C1]={ + adobename="rho", + category="ll", + cjkwd="a", + contextname="greekrho", + description="GREEK SMALL LETTER RHO", + direction="l", + linebreak="al", + mathclass="variable", + mathname="rho", + uccode=0x03A1, + unicodeslot=0x03C1, + }, + [0x03C2]={ + adobename="sigma1", + category="ll", + contextname="greekfinalsigma", + description="GREEK SMALL LETTER FINAL SIGMA", + direction="l", + linebreak="al", + mathclass="variable", + mathname="varsigma", + uccode=0x03A3, + unicodeslot=0x03C2, + }, + [0x03C3]={ + adobename="sigma", + category="ll", + cjkwd="a", + contextname="greeksigma", + description="GREEK SMALL LETTER SIGMA", + direction="l", + linebreak="al", + mathclass="variable", + mathname="sigma", + uccode=0x03A3, + unicodeslot=0x03C3, + }, + [0x03C4]={ + adobename="tau", + category="ll", + cjkwd="a", + contextname="greektau", + description="GREEK SMALL LETTER TAU", + direction="l", + linebreak="al", + mathclass="variable", + mathname="tau", + uccode=0x03A4, + unicodeslot=0x03C4, + }, + [0x03C5]={ + adobename="upsilon", + category="ll", + cjkwd="a", + contextname="greekupsilon", + description="GREEK SMALL LETTER UPSILON", + direction="l", + linebreak="al", + mathclass="variable", + mathname="upsilon", + uccode=0x03A5, + unicodeslot=0x03C5, + }, + [0x03C6]={ + adobename="phi", + category="ll", + cjkwd="a", + contextname="greekphi", + description="GREEK SMALL LETTER PHI", + direction="l", + linebreak="al", + mathclass="variable", + mathname="varphi", + uccode=0x03A6, + unicodeslot=0x03C6, + }, + [0x03C7]={ + adobename="chi", + category="ll", + cjkwd="a", + contextname="greekchi", + description="GREEK SMALL LETTER CHI", + direction="l", + linebreak="al", + mathclass="variable", + mathname="chi", + uccode=0x03A7, + unicodeslot=0x03C7, + }, + [0x03C8]={ + adobename="psi", + category="ll", + cjkwd="a", + contextname="greekpsi", + description="GREEK SMALL LETTER PSI", + direction="l", + linebreak="al", + mathclass="variable", + mathname="psi", + uccode=0x03A8, + unicodeslot=0x03C8, + }, + [0x03C9]={ + adobename="omega", + category="ll", + cjkwd="a", + contextname="greekomega", + description="GREEK SMALL LETTER OMEGA", + direction="l", + linebreak="al", + mathclass="variable", + mathname="omega", + uccode=0x03A9, + unicodeslot=0x03C9, + }, + [0x03CA]={ + adobename="iotadieresis", + category="ll", + contextname="greekiotadialytika", + description="GREEK SMALL LETTER IOTA WITH DIALYTIKA", + direction="l", + linebreak="al", + shcode=0x03B9, + specials={ "char", 0x03B9, 0x0308 }, + uccode=0x03AA, + unicodeslot=0x03CA, + }, + [0x03CB]={ + adobename="upsilondieresis", + category="ll", + contextname="greekupsilondiaeresis", + description="GREEK SMALL LETTER UPSILON WITH DIALYTIKA", + direction="l", + linebreak="al", + shcode=0x03C5, + specials={ "char", 0x03C5, 0x0308 }, + uccode=0x03AB, + unicodeslot=0x03CB, + }, + [0x03CC]={ + adobename="omicrontonos", + category="ll", + contextname="greekomicrontonos", + description="GREEK SMALL LETTER OMICRON WITH TONOS", + direction="l", + linebreak="al", + shcode=0x03BF, + specials={ "char", 0x03BF, 0x0301 }, + uccode=0x038C, + unicodeslot=0x03CC, + }, + [0x03CD]={ + adobename="upsilontonos", + category="ll", + contextname="greekupsilontonos", + description="GREEK SMALL LETTER UPSILON WITH TONOS", + direction="l", + linebreak="al", + shcode=0x03C5, + specials={ "char", 0x03C5, 0x0301 }, + uccode=0x038E, + unicodeslot=0x03CD, + }, + [0x03CE]={ + adobename="omegatonos", + category="ll", + contextname="greekomegatonos", + description="GREEK SMALL LETTER OMEGA WITH TONOS", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x03C9, 0x0301 }, + uccode=0x038F, + unicodeslot=0x03CE, + }, + [0x03D0]={ + category="ll", + description="GREEK BETA SYMBOL", + direction="l", + linebreak="al", + specials={ "compat", 0x03B2 }, + uccode=0x0392, + unicodeslot=0x03D0, + }, + [0x03D1]={ + adobename="theta1", + category="ll", + contextname="greekthetaalt", + description="GREEK THETA SYMBOL", + direction="l", + linebreak="al", + mathclass="variable", + mathname="varTheta", + specials={ "compat", 0x03B8 }, + uccode=0x0398, + unicodeslot=0x03D1, + }, + [0x03D2]={ + adobename="Upsilon1", + category="lu", + description="GREEK UPSILON WITH HOOK SYMBOL", + direction="l", + linebreak="al", + specials={ "compat", 0x03A5 }, + unicodeslot=0x03D2, + }, + [0x03D3]={ + category="lu", + description="GREEK UPSILON WITH ACUTE AND HOOK SYMBOL", + direction="l", + linebreak="al", + specials={ "char", 0x03D2, 0x0301 }, + unicodeslot=0x03D3, + }, + [0x03D4]={ + category="lu", + description="GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL", + direction="l", + linebreak="al", + specials={ "char", 0x03D2, 0x0308 }, + unicodeslot=0x03D4, + }, + [0x03D5]={ + adobename="phi1", + category="ll", + contextname="greekphialt", + description="GREEK PHI SYMBOL", + direction="l", + linebreak="al", + specials={ "compat", 0x03C6 }, + mathclass="variable", + mathname="phi", + uccode=0x03A6, + unicodeslot=0x03D5, + }, + [0x03D6]={ + adobename="omega1", + category="ll", + contextname="greekpialt", + description="GREEK PI SYMBOL", + direction="l", + linebreak="al", + mathclass="variable", + mathname="varpi", + specials={ "compat", 0x03C0 }, + uccode=0x03A0, + unicodeslot=0x03D6, + }, + [0x03D7]={ + category="ll", + description="GREEK KAI SYMBOL", + direction="l", + linebreak="al", + unicodeslot=0x03D7, + }, + [0x03D8]={ + category="lu", + description="GREEK LETTER ARCHAIC KOPPA", + direction="l", + lccode=0x03D9, + linebreak="al", + unicodeslot=0x03D8, + }, + [0x03D9]={ + category="ll", + contextname="greekkoppa", + description="GREEK SMALL LETTER ARCHAIC KOPPA", + direction="l", + linebreak="al", + uccode=0x03D8, + unicodeslot=0x03D9, + }, + [0x03DA]={ + category="lu", + description="GREEK LETTER STIGMA", + direction="l", + lccode=0x03DB, + linebreak="al", + unicodeslot=0x03DA, + }, + [0x03DB]={ + category="ll", + contextname="greekstigma", + description="GREEK SMALL LETTER STIGMA", + direction="l", + linebreak="al", + uccode=0x03DA, + unicodeslot=0x03DB, + }, + [0x03DC]={ + category="lu", + description="GREEK LETTER DIGAMMA", + direction="l", + lccode=0x03DD, + linebreak="al", + mathclass="variable", + mathname="digamma", + unicodeslot=0x03DC, + }, + [0x03DD]={ + category="ll", + contextname="greekdigamma", + description="GREEK SMALL LETTER DIGAMMA", + direction="l", + linebreak="al", + uccode=0x03DC, + unicodeslot=0x03DD, + }, + [0x03DE]={ + category="lu", + description="GREEK LETTER KOPPA", + direction="l", + lccode=0x03DF, + linebreak="al", + unicodeslot=0x03DE, + }, + [0x03DF]={ + category="ll", + contextname="greeknumkoppa", + description="GREEK SMALL LETTER KOPPA", + direction="l", + linebreak="al", + uccode=0x03DE, + unicodeslot=0x03DF, + }, + [0x03E0]={ + category="lu", + description="GREEK LETTER SAMPI", + direction="l", + lccode=0x03E1, + linebreak="al", + unicodeslot=0x03E0, + }, + [0x03E1]={ + category="ll", + contextname="greeksampi", + description="GREEK SMALL LETTER SAMPI", + direction="l", + linebreak="al", + uccode=0x03E0, + unicodeslot=0x03E1, + }, + [0x03E2]={ + category="lu", + description="COPTIC CAPITAL LETTER SHEI", + direction="l", + lccode=0x03E3, + linebreak="al", + unicodeslot=0x03E2, + }, + [0x03E3]={ + category="ll", + description="COPTIC SMALL LETTER SHEI", + direction="l", + linebreak="al", + uccode=0x03E2, + unicodeslot=0x03E3, + }, + [0x03E4]={ + category="lu", + description="COPTIC CAPITAL LETTER FEI", + direction="l", + lccode=0x03E5, + linebreak="al", + unicodeslot=0x03E4, + }, + [0x03E5]={ + category="ll", + description="COPTIC SMALL LETTER FEI", + direction="l", + linebreak="al", + uccode=0x03E4, + unicodeslot=0x03E5, + }, + [0x03E6]={ + category="lu", + description="COPTIC CAPITAL LETTER KHEI", + direction="l", + lccode=0x03E7, + linebreak="al", + unicodeslot=0x03E6, + }, + [0x03E7]={ + category="ll", + description="COPTIC SMALL LETTER KHEI", + direction="l", + linebreak="al", + uccode=0x03E6, + unicodeslot=0x03E7, + }, + [0x03E8]={ + category="lu", + description="COPTIC CAPITAL LETTER HORI", + direction="l", + lccode=0x03E9, + linebreak="al", + unicodeslot=0x03E8, + }, + [0x03E9]={ + category="ll", + description="COPTIC SMALL LETTER HORI", + direction="l", + linebreak="al", + uccode=0x03E8, + unicodeslot=0x03E9, + }, + [0x03EA]={ + category="lu", + description="COPTIC CAPITAL LETTER GANGIA", + direction="l", + lccode=0x03EB, + linebreak="al", + unicodeslot=0x03EA, + }, + [0x03EB]={ + category="ll", + description="COPTIC SMALL LETTER GANGIA", + direction="l", + linebreak="al", + uccode=0x03EA, + unicodeslot=0x03EB, + }, + [0x03EC]={ + category="lu", + description="COPTIC CAPITAL LETTER SHIMA", + direction="l", + lccode=0x03ED, + linebreak="al", + unicodeslot=0x03EC, + }, + [0x03ED]={ + category="ll", + description="COPTIC SMALL LETTER SHIMA", + direction="l", + linebreak="al", + uccode=0x03EC, + unicodeslot=0x03ED, + }, + [0x03EE]={ + category="lu", + description="COPTIC CAPITAL LETTER DEI", + direction="l", + lccode=0x03EF, + linebreak="al", + unicodeslot=0x03EE, + }, + [0x03EF]={ + category="ll", + description="COPTIC SMALL LETTER DEI", + direction="l", + linebreak="al", + uccode=0x03EE, + unicodeslot=0x03EF, + }, + [0x03F0]={ + category="ll", + description="GREEK KAPPA SYMBOL", + direction="l", + linebreak="al", + specials={ "compat", 0x03BA }, + mathclass="ord", + mathname="varkappa", + uccode=0x039A, + unicodeslot=0x03F0, + }, + [0x03F1]={ + category="ll", + contextname="greekrhoalt", + description="GREEK RHO SYMBOL", + direction="l", + linebreak="al", + specials={ "compat", 0x03C1 }, + uccode=0x03A1, + unicodeslot=0x03F1, + }, + [0x03F2]={ + category="ll", + contextname="greeksigmalunate", + description="GREEK LUNATE SIGMA SYMBOL", + direction="l", + linebreak="al", + specials={ "compat", 0x03C2 }, + uccode=0x03F9, + unicodeslot=0x03F2, + }, + [0x03F3]={ + category="ll", + description="GREEK LETTER YOT", + direction="l", + linebreak="al", + unicodeslot=0x03F3, + }, + [0x03F4]={ + category="lu", + description="GREEK CAPITAL THETA SYMBOL", + direction="l", + lccode=0x03B8, + linebreak="al", + specials={ "compat", 0x0398 }, + unicodeslot=0x03F4, + }, + [0x03F5]={ + category="ll", + contextname="greekepsilonalt", + description="GREEK LUNATE EPSILON SYMBOL", + direction="l", + linebreak="al", + mathclass="variable", + mathname="epsilon", + specials={ "compat", 0x03B5 }, + uccode=0x0395, + unicodeslot=0x03F5, + }, + [0x03F6]={ + category="sm", + description="GREEK REVERSED LUNATE EPSILON SYMBOL", + direction="on", + linebreak="al", + mathclass="variable", + mathname="backepsilon", + unicodeslot=0x03F6, + }, + [0x03F7]={ + category="lu", + description="GREEK CAPITAL LETTER SHO", + direction="l", + lccode=0x03F8, + linebreak="al", + unicodeslot=0x03F7, + }, + [0x03F8]={ + category="ll", + description="GREEK SMALL LETTER SHO", + direction="l", + linebreak="al", + uccode=0x03F7, + unicodeslot=0x03F8, + }, + [0x03F9]={ + category="lu", + contextname="greekSigmalunate", + description="GREEK CAPITAL LUNATE SIGMA SYMBOL", + direction="l", + lccode=0x03F2, + linebreak="al", + specials={ "compat", 0x03A3 }, + unicodeslot=0x03F9, + }, + [0x03FA]={ + category="lu", + description="GREEK CAPITAL LETTER SAN", + direction="l", + lccode=0x03FB, + linebreak="al", + unicodeslot=0x03FA, + }, + [0x03FB]={ + category="ll", + description="GREEK SMALL LETTER SAN", + direction="l", + linebreak="al", + uccode=0x03FA, + unicodeslot=0x03FB, + }, + [0x03FC]={ + category="ll", + description="GREEK RHO WITH STROKE SYMBOL", + direction="l", + linebreak="al", + unicodeslot=0x03FC, + }, + [0x03FD]={ + category="lu", + description="GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL", + direction="l", + lccode=0x037B, + linebreak="al", + unicodeslot=0x03FD, + }, + [0x03FE]={ + category="lu", + description="GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL", + direction="l", + lccode=0x037C, + linebreak="al", + unicodeslot=0x03FE, + }, + [0x03FF]={ + category="lu", + description="GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL", + direction="l", + lccode=0x037D, + linebreak="al", + unicodeslot=0x03FF, + }, + [0x0400]={ + category="lu", + contextname="cyrillicEgrave", + description="CYRILLIC CAPITAL LETTER IE WITH GRAVE", + direction="l", + lccode=0x0450, + linebreak="al", + shcode=0x0415, + specials={ "char", 0x0415, 0x0300 }, + unicodeslot=0x0400, + }, + [0x0401]={ + adobename="afii10023", + category="lu", + cjkwd="a", + contextname="cyrillicYO", + description="CYRILLIC CAPITAL LETTER IO", + direction="l", + lccode=0x0451, + linebreak="al", + specials={ "char", 0x0415, 0x0308 }, + unicodeslot=0x0401, + }, + [0x0402]={ + adobename="afii10051", + category="lu", + contextname="cyrillicDJE", + description="CYRILLIC CAPITAL LETTER DJE", + direction="l", + lccode=0x0452, + linebreak="al", + unicodeslot=0x0402, + }, + [0x0403]={ + adobename="afii10052", + category="lu", + contextname="cyrillicGJE", + description="CYRILLIC CAPITAL LETTER GJE", + direction="l", + lccode=0x0453, + linebreak="al", + specials={ "char", 0x0413, 0x0301 }, + unicodeslot=0x0403, + }, + [0x0404]={ + adobename="afii10053", + category="lu", + contextname="cyrillicIE", + description="CYRILLIC CAPITAL LETTER UKRAINIAN IE", + direction="l", + lccode=0x0454, + linebreak="al", + unicodeslot=0x0404, + }, + [0x0405]={ + adobename="afii10054", + category="lu", + contextname="cyrillicDZE", + description="CYRILLIC CAPITAL LETTER DZE", + direction="l", + lccode=0x0455, + linebreak="al", + unicodeslot=0x0405, + }, + [0x0406]={ + adobename="afii10055", + category="lu", + contextname="cyrillicII", + description="CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I", + direction="l", + lccode=0x0456, + linebreak="al", + unicodeslot=0x0406, + }, + [0x0407]={ + adobename="afii10056", + category="lu", + contextname="cyrillicYI", + description="CYRILLIC CAPITAL LETTER YI", + direction="l", + lccode=0x0457, + linebreak="al", + specials={ "char", 0x0406, 0x0308 }, + unicodeslot=0x0407, + }, + [0x0408]={ + adobename="afii10057", + category="lu", + contextname="cyrillicJE", + description="CYRILLIC CAPITAL LETTER JE", + direction="l", + lccode=0x0458, + linebreak="al", + unicodeslot=0x0408, + }, + [0x0409]={ + adobename="afii10058", + category="lu", + contextname="cyrillicLJE", + description="CYRILLIC CAPITAL LETTER LJE", + direction="l", + lccode=0x0459, + linebreak="al", + unicodeslot=0x0409, + }, + [0x040A]={ + adobename="afii10059", + category="lu", + contextname="cyrillicNJE", + description="CYRILLIC CAPITAL LETTER NJE", + direction="l", + lccode=0x045A, + linebreak="al", + unicodeslot=0x040A, + }, + [0x040B]={ + adobename="afii10060", + category="lu", + contextname="cyrillicTSHE", + description="CYRILLIC CAPITAL LETTER TSHE", + direction="l", + lccode=0x045B, + linebreak="al", + unicodeslot=0x040B, + }, + [0x040C]={ + adobename="afii10061", + category="lu", + contextname="cyrillicKJE", + description="CYRILLIC CAPITAL LETTER KJE", + direction="l", + lccode=0x045C, + linebreak="al", + specials={ "char", 0x041A, 0x0301 }, + unicodeslot=0x040C, + }, + [0x040D]={ + category="lu", + contextname="cyrillicIgrave", + description="CYRILLIC CAPITAL LETTER I WITH GRAVE", + direction="l", + lccode=0x045D, + linebreak="al", + shcode=0x0418, + specials={ "char", 0x0418, 0x0300 }, + unicodeslot=0x040D, + }, + [0x040E]={ + adobename="afii10062", + category="lu", + contextname="cyrillicUSHRT", + description="CYRILLIC CAPITAL LETTER SHORT U", + direction="l", + lccode=0x045E, + linebreak="al", + specials={ "char", 0x0423, 0x0306 }, + unicodeslot=0x040E, + }, + [0x040F]={ + adobename="afii10145", + category="lu", + contextname="cyrillicDZHE", + description="CYRILLIC CAPITAL LETTER DZHE", + direction="l", + lccode=0x045F, + linebreak="al", + unicodeslot=0x040F, + }, + [0x0410]={ + adobename="afii10017", + category="lu", + cjkwd="a", + contextname="cyrillicA", + description="CYRILLIC CAPITAL LETTER A", + direction="l", + lccode=0x0430, + linebreak="al", + unicodeslot=0x0410, + }, + [0x0411]={ + adobename="afii10018", + category="lu", + cjkwd="a", + contextname="cyrillicB", + description="CYRILLIC CAPITAL LETTER BE", + direction="l", + lccode=0x0431, + linebreak="al", + unicodeslot=0x0411, + }, + [0x0412]={ + adobename="afii10019", + category="lu", + cjkwd="a", + contextname="cyrillicV", + description="CYRILLIC CAPITAL LETTER VE", + direction="l", + lccode=0x0432, + linebreak="al", + unicodeslot=0x0412, + }, + [0x0413]={ + adobename="afii10020", + category="lu", + cjkwd="a", + contextname="cyrillicG", + description="CYRILLIC CAPITAL LETTER GHE", + direction="l", + lccode=0x0433, + linebreak="al", + unicodeslot=0x0413, + }, + [0x0414]={ + adobename="afii10021", + category="lu", + cjkwd="a", + contextname="cyrillicD", + description="CYRILLIC CAPITAL LETTER DE", + direction="l", + lccode=0x0434, + linebreak="al", + unicodeslot=0x0414, + }, + [0x0415]={ + adobename="afii10022", + category="lu", + cjkwd="a", + contextname="cyrillicE", + description="CYRILLIC CAPITAL LETTER IE", + direction="l", + lccode=0x0435, + linebreak="al", + unicodeslot=0x0415, + }, + [0x0416]={ + adobename="afii10024", + category="lu", + cjkwd="a", + contextname="cyrillicZH", + description="CYRILLIC CAPITAL LETTER ZHE", + direction="l", + lccode=0x0436, + linebreak="al", + unicodeslot=0x0416, + }, + [0x0417]={ + adobename="afii10025", + category="lu", + cjkwd="a", + contextname="cyrillicZ", + description="CYRILLIC CAPITAL LETTER ZE", + direction="l", + lccode=0x0437, + linebreak="al", + unicodeslot=0x0417, + }, + [0x0418]={ + adobename="afii10026", + category="lu", + cjkwd="a", + contextname="cyrillicI", + description="CYRILLIC CAPITAL LETTER I", + direction="l", + lccode=0x0438, + linebreak="al", + unicodeslot=0x0418, + }, + [0x0419]={ + adobename="afii10027", + category="lu", + cjkwd="a", + contextname="cyrillicISHRT", + description="CYRILLIC CAPITAL LETTER SHORT I", + direction="l", + lccode=0x0439, + linebreak="al", + specials={ "char", 0x0418, 0x0306 }, + unicodeslot=0x0419, + }, + [0x041A]={ + adobename="afii10028", + category="lu", + cjkwd="a", + contextname="cyrillicK", + description="CYRILLIC CAPITAL LETTER KA", + direction="l", + lccode=0x043A, + linebreak="al", + unicodeslot=0x041A, + }, + [0x041B]={ + adobename="afii10029", + category="lu", + cjkwd="a", + contextname="cyrillicL", + description="CYRILLIC CAPITAL LETTER EL", + direction="l", + lccode=0x043B, + linebreak="al", + unicodeslot=0x041B, + }, + [0x041C]={ + adobename="afii10030", + category="lu", + cjkwd="a", + contextname="cyrillicM", + description="CYRILLIC CAPITAL LETTER EM", + direction="l", + lccode=0x043C, + linebreak="al", + unicodeslot=0x041C, + }, + [0x041D]={ + adobename="afii10031", + category="lu", + cjkwd="a", + contextname="cyrillicN", + description="CYRILLIC CAPITAL LETTER EN", + direction="l", + lccode=0x043D, + linebreak="al", + unicodeslot=0x041D, + }, + [0x041E]={ + adobename="afii10032", + category="lu", + cjkwd="a", + contextname="cyrillicO", + description="CYRILLIC CAPITAL LETTER O", + direction="l", + lccode=0x043E, + linebreak="al", + unicodeslot=0x041E, + }, + [0x041F]={ + adobename="afii10033", + category="lu", + cjkwd="a", + contextname="cyrillicP", + description="CYRILLIC CAPITAL LETTER PE", + direction="l", + lccode=0x043F, + linebreak="al", + unicodeslot=0x041F, + }, + [0x0420]={ + adobename="afii10034", + category="lu", + cjkwd="a", + contextname="cyrillicR", + description="CYRILLIC CAPITAL LETTER ER", + direction="l", + lccode=0x0440, + linebreak="al", + unicodeslot=0x0420, + }, + [0x0421]={ + adobename="afii10035", + category="lu", + cjkwd="a", + contextname="cyrillicS", + description="CYRILLIC CAPITAL LETTER ES", + direction="l", + lccode=0x0441, + linebreak="al", + unicodeslot=0x0421, + }, + [0x0422]={ + adobename="afii10036", + category="lu", + cjkwd="a", + contextname="cyrillicT", + description="CYRILLIC CAPITAL LETTER TE", + direction="l", + lccode=0x0442, + linebreak="al", + unicodeslot=0x0422, + }, + [0x0423]={ + adobename="afii10037", + category="lu", + cjkwd="a", + contextname="cyrillicU", + description="CYRILLIC CAPITAL LETTER U", + direction="l", + lccode=0x0443, + linebreak="al", + unicodeslot=0x0423, + }, + [0x0424]={ + adobename="afii10038", + category="lu", + cjkwd="a", + contextname="cyrillicF", + description="CYRILLIC CAPITAL LETTER EF", + direction="l", + lccode=0x0444, + linebreak="al", + unicodeslot=0x0424, + }, + [0x0425]={ + adobename="afii10039", + category="lu", + cjkwd="a", + contextname="cyrillicH", + description="CYRILLIC CAPITAL LETTER HA", + direction="l", + lccode=0x0445, + linebreak="al", + unicodeslot=0x0425, + }, + [0x0426]={ + adobename="afii10040", + category="lu", + cjkwd="a", + contextname="cyrillicC", + description="CYRILLIC CAPITAL LETTER TSE", + direction="l", + lccode=0x0446, + linebreak="al", + unicodeslot=0x0426, + }, + [0x0427]={ + adobename="afii10041", + category="lu", + cjkwd="a", + contextname="cyrillicCH", + description="CYRILLIC CAPITAL LETTER CHE", + direction="l", + lccode=0x0447, + linebreak="al", + unicodeslot=0x0427, + }, + [0x0428]={ + adobename="afii10042", + category="lu", + cjkwd="a", + contextname="cyrillicSH", + description="CYRILLIC CAPITAL LETTER SHA", + direction="l", + lccode=0x0448, + linebreak="al", + unicodeslot=0x0428, + }, + [0x0429]={ + adobename="afii10043", + category="lu", + cjkwd="a", + contextname="cyrillicSHCH", + description="CYRILLIC CAPITAL LETTER SHCHA", + direction="l", + lccode=0x0449, + linebreak="al", + unicodeslot=0x0429, + }, + [0x042A]={ + adobename="afii10044", + category="lu", + cjkwd="a", + contextname="cyrillicHRDSN", + description="CYRILLIC CAPITAL LETTER HARD SIGN", + direction="l", + lccode=0x044A, + linebreak="al", + unicodeslot=0x042A, + }, + [0x042B]={ + adobename="afii10045", + category="lu", + cjkwd="a", + contextname="cyrillicERY", + description="CYRILLIC CAPITAL LETTER YERU", + direction="l", + lccode=0x044B, + linebreak="al", + unicodeslot=0x042B, + }, + [0x042C]={ + adobename="afii10046", + category="lu", + cjkwd="a", + contextname="cyrillicSFTSN", + description="CYRILLIC CAPITAL LETTER SOFT SIGN", + direction="l", + lccode=0x044C, + linebreak="al", + unicodeslot=0x042C, + }, + [0x042D]={ + adobename="afii10047", + category="lu", + cjkwd="a", + contextname="cyrillicEREV", + description="CYRILLIC CAPITAL LETTER E", + direction="l", + lccode=0x044D, + linebreak="al", + unicodeslot=0x042D, + }, + [0x042E]={ + adobename="afii10048", + category="lu", + cjkwd="a", + contextname="cyrillicYU", + description="CYRILLIC CAPITAL LETTER YU", + direction="l", + lccode=0x044E, + linebreak="al", + unicodeslot=0x042E, + }, + [0x042F]={ + adobename="afii10049", + category="lu", + cjkwd="a", + contextname="cyrillicYA", + description="CYRILLIC CAPITAL LETTER YA", + direction="l", + lccode=0x044F, + linebreak="al", + unicodeslot=0x042F, + }, + [0x0430]={ + adobename="afii10065", + category="ll", + cjkwd="a", + contextname="cyrillica", + description="CYRILLIC SMALL LETTER A", + direction="l", + linebreak="al", + uccode=0x0410, + unicodeslot=0x0430, + }, + [0x0431]={ + adobename="afii10066", + category="ll", + cjkwd="a", + contextname="cyrillicb", + description="CYRILLIC SMALL LETTER BE", + direction="l", + linebreak="al", + uccode=0x0411, + unicodeslot=0x0431, + }, + [0x0432]={ + adobename="afii10067", + category="ll", + cjkwd="a", + contextname="cyrillicv", + description="CYRILLIC SMALL LETTER VE", + direction="l", + linebreak="al", + uccode=0x0412, + unicodeslot=0x0432, + }, + [0x0433]={ + adobename="afii10068", + category="ll", + cjkwd="a", + contextname="cyrillicg", + description="CYRILLIC SMALL LETTER GHE", + direction="l", + linebreak="al", + uccode=0x0413, + unicodeslot=0x0433, + }, + [0x0434]={ + adobename="afii10069", + category="ll", + cjkwd="a", + contextname="cyrillicd", + description="CYRILLIC SMALL LETTER DE", + direction="l", + linebreak="al", + uccode=0x0414, + unicodeslot=0x0434, + }, + [0x0435]={ + adobename="afii10070", + category="ll", + cjkwd="a", + contextname="cyrillice", + description="CYRILLIC SMALL LETTER IE", + direction="l", + linebreak="al", + uccode=0x0415, + unicodeslot=0x0435, + }, + [0x0436]={ + adobename="afii10072", + category="ll", + cjkwd="a", + contextname="cyrilliczh", + description="CYRILLIC SMALL LETTER ZHE", + direction="l", + linebreak="al", + uccode=0x0416, + unicodeslot=0x0436, + }, + [0x0437]={ + adobename="afii10073", + category="ll", + cjkwd="a", + contextname="cyrillicz", + description="CYRILLIC SMALL LETTER ZE", + direction="l", + linebreak="al", + uccode=0x0417, + unicodeslot=0x0437, + }, + [0x0438]={ + adobename="afii10074", + category="ll", + cjkwd="a", + contextname="cyrillici", + description="CYRILLIC SMALL LETTER I", + direction="l", + linebreak="al", + uccode=0x0418, + unicodeslot=0x0438, + }, + [0x0439]={ + adobename="afii10075", + category="ll", + cjkwd="a", + contextname="cyrillicishrt", + description="CYRILLIC SMALL LETTER SHORT I", + direction="l", + linebreak="al", + specials={ "char", 0x0438, 0x0306 }, + uccode=0x0419, + unicodeslot=0x0439, + }, + [0x043A]={ + adobename="afii10076", + category="ll", + cjkwd="a", + contextname="cyrillick", + description="CYRILLIC SMALL LETTER KA", + direction="l", + linebreak="al", + uccode=0x041A, + unicodeslot=0x043A, + }, + [0x043B]={ + adobename="afii10077", + category="ll", + cjkwd="a", + contextname="cyrillicl", + description="CYRILLIC SMALL LETTER EL", + direction="l", + linebreak="al", + uccode=0x041B, + unicodeslot=0x043B, + }, + [0x043C]={ + adobename="afii10078", + category="ll", + cjkwd="a", + contextname="cyrillicm", + description="CYRILLIC SMALL LETTER EM", + direction="l", + linebreak="al", + uccode=0x041C, + unicodeslot=0x043C, + }, + [0x043D]={ + adobename="afii10079", + category="ll", + cjkwd="a", + contextname="cyrillicn", + description="CYRILLIC SMALL LETTER EN", + direction="l", + linebreak="al", + uccode=0x041D, + unicodeslot=0x043D, + }, + [0x043E]={ + adobename="afii10080", + category="ll", + cjkwd="a", + contextname="cyrillico", + description="CYRILLIC SMALL LETTER O", + direction="l", + linebreak="al", + uccode=0x041E, + unicodeslot=0x043E, + }, + [0x043F]={ + adobename="afii10081", + category="ll", + cjkwd="a", + contextname="cyrillicp", + description="CYRILLIC SMALL LETTER PE", + direction="l", + linebreak="al", + uccode=0x041F, + unicodeslot=0x043F, + }, + [0x0440]={ + adobename="afii10082", + category="ll", + cjkwd="a", + contextname="cyrillicr", + description="CYRILLIC SMALL LETTER ER", + direction="l", + linebreak="al", + uccode=0x0420, + unicodeslot=0x0440, + }, + [0x0441]={ + adobename="afii10083", + category="ll", + cjkwd="a", + contextname="cyrillics", + description="CYRILLIC SMALL LETTER ES", + direction="l", + linebreak="al", + uccode=0x0421, + unicodeslot=0x0441, + }, + [0x0442]={ + adobename="afii10084", + category="ll", + cjkwd="a", + contextname="cyrillict", + description="CYRILLIC SMALL LETTER TE", + direction="l", + linebreak="al", + uccode=0x0422, + unicodeslot=0x0442, + }, + [0x0443]={ + adobename="afii10085", + category="ll", + cjkwd="a", + contextname="cyrillicu", + description="CYRILLIC SMALL LETTER U", + direction="l", + linebreak="al", + uccode=0x0423, + unicodeslot=0x0443, + }, + [0x0444]={ + adobename="afii10086", + category="ll", + cjkwd="a", + contextname="cyrillicf", + description="CYRILLIC SMALL LETTER EF", + direction="l", + linebreak="al", + uccode=0x0424, + unicodeslot=0x0444, + }, + [0x0445]={ + adobename="afii10087", + category="ll", + cjkwd="a", + contextname="cyrillich", + description="CYRILLIC SMALL LETTER HA", + direction="l", + linebreak="al", + uccode=0x0425, + unicodeslot=0x0445, + }, + [0x0446]={ + adobename="afii10088", + category="ll", + cjkwd="a", + contextname="cyrillicc", + description="CYRILLIC SMALL LETTER TSE", + direction="l", + linebreak="al", + uccode=0x0426, + unicodeslot=0x0446, + }, + [0x0447]={ + adobename="afii10089", + category="ll", + cjkwd="a", + contextname="cyrillicch", + description="CYRILLIC SMALL LETTER CHE", + direction="l", + linebreak="al", + uccode=0x0427, + unicodeslot=0x0447, + }, + [0x0448]={ + adobename="afii10090", + category="ll", + cjkwd="a", + contextname="cyrillicsh", + description="CYRILLIC SMALL LETTER SHA", + direction="l", + linebreak="al", + uccode=0x0428, + unicodeslot=0x0448, + }, + [0x0449]={ + adobename="afii10091", + category="ll", + cjkwd="a", + contextname="cyrillicshch", + description="CYRILLIC SMALL LETTER SHCHA", + direction="l", + linebreak="al", + uccode=0x0429, + unicodeslot=0x0449, + }, + [0x044A]={ + adobename="afii10092", + category="ll", + cjkwd="a", + contextname="cyrillichrdsn", + description="CYRILLIC SMALL LETTER HARD SIGN", + direction="l", + linebreak="al", + uccode=0x042A, + unicodeslot=0x044A, + }, + [0x044B]={ + adobename="afii10093", + category="ll", + cjkwd="a", + contextname="cyrillicery", + description="CYRILLIC SMALL LETTER YERU", + direction="l", + linebreak="al", + uccode=0x042B, + unicodeslot=0x044B, + }, + [0x044C]={ + adobename="afii10094", + category="ll", + cjkwd="a", + contextname="cyrillicsftsn", + description="CYRILLIC SMALL LETTER SOFT SIGN", + direction="l", + linebreak="al", + uccode=0x042C, + unicodeslot=0x044C, + }, + [0x044D]={ + adobename="afii10095", + category="ll", + cjkwd="a", + contextname="cyrillicerev", + description="CYRILLIC SMALL LETTER E", + direction="l", + linebreak="al", + uccode=0x042D, + unicodeslot=0x044D, + }, + [0x044E]={ + adobename="afii10096", + category="ll", + cjkwd="a", + contextname="cyrillicyu", + description="CYRILLIC SMALL LETTER YU", + direction="l", + linebreak="al", + uccode=0x042E, + unicodeslot=0x044E, + }, + [0x044F]={ + adobename="afii10097", + category="ll", + cjkwd="a", + contextname="cyrillicya", + description="CYRILLIC SMALL LETTER YA", + direction="l", + linebreak="al", + uccode=0x042F, + unicodeslot=0x044F, + }, + [0x0450]={ + category="ll", + contextname="cyrillicegrave", + description="CYRILLIC SMALL LETTER IE WITH GRAVE", + direction="l", + linebreak="al", + shcode=0x0435, + specials={ "char", 0x0435, 0x0300 }, + uccode=0x0400, + unicodeslot=0x0450, + }, + [0x0451]={ + adobename="afii10071", + category="ll", + cjkwd="a", + contextname="cyrillicyo", + description="CYRILLIC SMALL LETTER IO", + direction="l", + linebreak="al", + specials={ "char", 0x0435, 0x0308 }, + uccode=0x0401, + unicodeslot=0x0451, + }, + [0x0452]={ + adobename="afii10099", + category="ll", + contextname="cyrillicdje", + description="CYRILLIC SMALL LETTER DJE", + direction="l", + linebreak="al", + uccode=0x0402, + unicodeslot=0x0452, + }, + [0x0453]={ + adobename="afii10100", + category="ll", + contextname="cyrillicgje", + description="CYRILLIC SMALL LETTER GJE", + direction="l", + linebreak="al", + specials={ "char", 0x0433, 0x0301 }, + uccode=0x0403, + unicodeslot=0x0453, + }, + [0x0454]={ + adobename="afii10101", + category="ll", + contextname="cyrillicie", + description="CYRILLIC SMALL LETTER UKRAINIAN IE", + direction="l", + linebreak="al", + uccode=0x0404, + unicodeslot=0x0454, + }, + [0x0455]={ + adobename="afii10102", + category="ll", + contextname="cyrillicdze", + description="CYRILLIC SMALL LETTER DZE", + direction="l", + linebreak="al", + uccode=0x0405, + unicodeslot=0x0455, + }, + [0x0456]={ + adobename="afii10103", + category="ll", + contextname="cyrillicii", + description="CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I", + direction="l", + linebreak="al", + uccode=0x0406, + unicodeslot=0x0456, + }, + [0x0457]={ + adobename="afii10104", + category="ll", + contextname="cyrillicyi", + description="CYRILLIC SMALL LETTER YI", + direction="l", + linebreak="al", + specials={ "char", 0x0456, 0x0308 }, + uccode=0x0407, + unicodeslot=0x0457, + }, + [0x0458]={ + adobename="afii10105", + category="ll", + contextname="cyrillicje", + description="CYRILLIC SMALL LETTER JE", + direction="l", + linebreak="al", + uccode=0x0408, + unicodeslot=0x0458, + }, + [0x0459]={ + adobename="afii10106", + category="ll", + contextname="cyrilliclje", + description="CYRILLIC SMALL LETTER LJE", + direction="l", + linebreak="al", + uccode=0x0409, + unicodeslot=0x0459, + }, + [0x045A]={ + adobename="afii10107", + category="ll", + contextname="cyrillicnje", + description="CYRILLIC SMALL LETTER NJE", + direction="l", + linebreak="al", + uccode=0x040A, + unicodeslot=0x045A, + }, + [0x045B]={ + adobename="afii10108", + category="ll", + contextname="cyrillictshe", + description="CYRILLIC SMALL LETTER TSHE", + direction="l", + linebreak="al", + uccode=0x040B, + unicodeslot=0x045B, + }, + [0x045C]={ + adobename="afii10109", + category="ll", + contextname="cyrillickje", + description="CYRILLIC SMALL LETTER KJE", + direction="l", + linebreak="al", + specials={ "char", 0x043A, 0x0301 }, + uccode=0x040C, + unicodeslot=0x045C, + }, + [0x045D]={ + category="ll", + contextname="cyrillicigrave", + description="CYRILLIC SMALL LETTER I WITH GRAVE", + direction="l", + linebreak="al", + shcode=0x0438, + specials={ "char", 0x0438, 0x0300 }, + uccode=0x040D, + unicodeslot=0x045D, + }, + [0x045E]={ + adobename="afii10110", + category="ll", + contextname="cyrillicushrt", + description="CYRILLIC SMALL LETTER SHORT U", + direction="l", + linebreak="al", + specials={ "char", 0x0443, 0x0306 }, + uccode=0x040E, + unicodeslot=0x045E, + }, + [0x045F]={ + adobename="afii10193", + category="ll", + contextname="cyrillicdzhe", + description="CYRILLIC SMALL LETTER DZHE", + direction="l", + linebreak="al", + uccode=0x040F, + unicodeslot=0x045F, + }, + [0x0460]={ + category="lu", + contextname="cyrillicOMEGA", + description="CYRILLIC CAPITAL LETTER OMEGA", + direction="l", + lccode=0x0461, + linebreak="al", + unicodeslot=0x0460, + }, + [0x0461]={ + category="ll", + contextname="cyrillicomega", + description="CYRILLIC SMALL LETTER OMEGA", + direction="l", + linebreak="al", + uccode=0x0460, + unicodeslot=0x0461, + }, + [0x0462]={ + adobename="afii10146", + category="lu", + contextname="cyrillicYAT", + description="CYRILLIC CAPITAL LETTER YAT", + direction="l", + lccode=0x0463, + linebreak="al", + unicodeslot=0x0462, + }, + [0x0463]={ + adobename="afii10194", + category="ll", + contextname="cyrillicyat", + description="CYRILLIC SMALL LETTER YAT", + direction="l", + linebreak="al", + uccode=0x0462, + unicodeslot=0x0463, + }, + [0x0464]={ + category="lu", + contextname="cyrillicEiotified", + description="CYRILLIC CAPITAL LETTER IOTIFIED E", + direction="l", + lccode=0x0465, + linebreak="al", + unicodeslot=0x0464, + }, + [0x0465]={ + category="ll", + contextname="cyrilliceiotified", + description="CYRILLIC SMALL LETTER IOTIFIED E", + direction="l", + linebreak="al", + uccode=0x0464, + unicodeslot=0x0465, + }, + [0x0466]={ + category="lu", + contextname="cyrillicLITTLEYUS", + description="CYRILLIC CAPITAL LETTER LITTLE YUS", + direction="l", + lccode=0x0467, + linebreak="al", + unicodeslot=0x0466, + }, + [0x0467]={ + category="ll", + contextname="cyrilliclittleyus", + description="CYRILLIC SMALL LETTER LITTLE YUS", + direction="l", + linebreak="al", + uccode=0x0466, + unicodeslot=0x0467, + }, + [0x0468]={ + category="lu", + contextname="cyrillicLITTLEYUSiotified", + description="CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS", + direction="l", + lccode=0x0469, + linebreak="al", + unicodeslot=0x0468, + }, + [0x0469]={ + category="ll", + contextname="cyrilliclittleyusiotified", + description="CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS", + direction="l", + linebreak="al", + uccode=0x0468, + unicodeslot=0x0469, + }, + [0x046A]={ + category="lu", + contextname="cyrillicBIGYUS", + description="CYRILLIC CAPITAL LETTER BIG YUS", + direction="l", + lccode=0x046B, + linebreak="al", + unicodeslot=0x046A, + }, + [0x046B]={ + category="ll", + contextname="cyrillicbigyus", + description="CYRILLIC SMALL LETTER BIG YUS", + direction="l", + linebreak="al", + uccode=0x046A, + unicodeslot=0x046B, + }, + [0x046C]={ + category="lu", + contextname="cyrillicBIGYUSiotified", + description="CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS", + direction="l", + lccode=0x046D, + linebreak="al", + unicodeslot=0x046C, + }, + [0x046D]={ + category="ll", + contextname="cyrillicbigyusiotified", + description="CYRILLIC SMALL LETTER IOTIFIED BIG YUS", + direction="l", + linebreak="al", + uccode=0x046C, + unicodeslot=0x046D, + }, + [0x046E]={ + category="lu", + contextname="cyrillicKSI", + description="CYRILLIC CAPITAL LETTER KSI", + direction="l", + lccode=0x046F, + linebreak="al", + unicodeslot=0x046E, + }, + [0x046F]={ + category="ll", + contextname="cyrillicksi", + description="CYRILLIC SMALL LETTER KSI", + direction="l", + linebreak="al", + uccode=0x046E, + unicodeslot=0x046F, + }, + [0x0470]={ + category="lu", + contextname="cyrillicPSI", + description="CYRILLIC CAPITAL LETTER PSI", + direction="l", + lccode=0x0471, + linebreak="al", + unicodeslot=0x0470, + }, + [0x0471]={ + category="ll", + contextname="cyrillicpsi", + description="CYRILLIC SMALL LETTER PSI", + direction="l", + linebreak="al", + uccode=0x0470, + unicodeslot=0x0471, + }, + [0x0472]={ + adobename="afii10147", + category="lu", + contextname="cyrillicFITA", + description="CYRILLIC CAPITAL LETTER FITA", + direction="l", + lccode=0x0473, + linebreak="al", + unicodeslot=0x0472, + }, + [0x0473]={ + adobename="afii10195", + category="ll", + contextname="cyrillicfita", + description="CYRILLIC SMALL LETTER FITA", + direction="l", + linebreak="al", + uccode=0x0472, + unicodeslot=0x0473, + }, + [0x0474]={ + adobename="afii10148", + category="lu", + contextname="cyrillicIZHITSA", + description="CYRILLIC CAPITAL LETTER IZHITSA", + direction="l", + lccode=0x0475, + linebreak="al", + unicodeslot=0x0474, + }, + [0x0475]={ + adobename="afii10196", + category="ll", + contextname="cyrillicizhitsa", + description="CYRILLIC SMALL LETTER IZHITSA", + direction="l", + linebreak="al", + uccode=0x0474, + unicodeslot=0x0475, + }, + [0x0476]={ + category="lu", + contextname="cyrillicIZHITSAdoublegrave", + description="CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT", + direction="l", + lccode=0x0477, + linebreak="al", + shcode=0x0474, + specials={ "char", 0x0474, 0x030F }, + unicodeslot=0x0476, + }, + [0x0477]={ + category="ll", + contextname="cyrillicizhitsadoublegrave", + description="CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT", + direction="l", + linebreak="al", + shcode=0x0475, + specials={ "char", 0x0475, 0x030F }, + uccode=0x0476, + unicodeslot=0x0477, + }, + [0x0478]={ + category="lu", + contextname="cyrillicUK", + description="CYRILLIC CAPITAL LETTER UK", + direction="l", + lccode=0x0479, + linebreak="al", + unicodeslot=0x0478, + }, + [0x0479]={ + category="ll", + contextname="cyrillicuk", + description="CYRILLIC SMALL LETTER UK", + direction="l", + linebreak="al", + uccode=0x0478, + unicodeslot=0x0479, + }, + [0x047A]={ + category="lu", + contextname="cyrillicOMEGAround", + description="CYRILLIC CAPITAL LETTER ROUND OMEGA", + direction="l", + lccode=0x047B, + linebreak="al", + unicodeslot=0x047A, + }, + [0x047B]={ + category="ll", + contextname="cyrillicomegaround", + description="CYRILLIC SMALL LETTER ROUND OMEGA", + direction="l", + linebreak="al", + uccode=0x047A, + unicodeslot=0x047B, + }, + [0x047C]={ + category="lu", + contextname="cyrillicOMEGAtitlo", + description="CYRILLIC CAPITAL LETTER OMEGA WITH TITLO", + direction="l", + lccode=0x047D, + linebreak="al", + shcode=0x0460, + unicodeslot=0x047C, + }, + [0x047D]={ + category="ll", + contextname="cyrillicomegatitlo", + description="CYRILLIC SMALL LETTER OMEGA WITH TITLO", + direction="l", + linebreak="al", + shcode=0x0461, + uccode=0x047C, + unicodeslot=0x047D, + }, + [0x047E]={ + category="lu", + contextname="cyrillicOT", + description="CYRILLIC CAPITAL LETTER OT", + direction="l", + lccode=0x047F, + linebreak="al", + unicodeslot=0x047E, + }, + [0x047F]={ + category="ll", + contextname="cyrillicot", + description="CYRILLIC SMALL LETTER OT", + direction="l", + linebreak="al", + uccode=0x047E, + unicodeslot=0x047F, + }, + [0x0480]={ + category="lu", + contextname="cyrillicKOPPA", + description="CYRILLIC CAPITAL LETTER KOPPA", + direction="l", + lccode=0x0481, + linebreak="al", + unicodeslot=0x0480, + }, + [0x0481]={ + category="ll", + contextname="cyrillickoppa", + description="CYRILLIC SMALL LETTER KOPPA", + direction="l", + linebreak="al", + uccode=0x0480, + unicodeslot=0x0481, + }, + [0x0482]={ + category="so", + description="CYRILLIC THOUSANDS SIGN", + direction="l", + linebreak="al", + unicodeslot=0x0482, + }, + [0x0483]={ + category="mn", + contextname="cyrillicTITLO", + description="COMBINING CYRILLIC TITLO", + direction="nsm", + linebreak="cm", + unicodeslot=0x0483, + }, + [0x0484]={ + category="mn", + contextname="cyrillicPALATALIZATION", + description="COMBINING CYRILLIC PALATALIZATION", + direction="nsm", + linebreak="cm", + unicodeslot=0x0484, + }, + [0x0485]={ + category="mn", + contextname="cyrillicDASIAPNEUMATA", + description="COMBINING CYRILLIC DASIA PNEUMATA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0485, + }, + [0x0486]={ + category="mn", + contextname="cyrillicPSILIPNEUMATA", + description="COMBINING CYRILLIC PSILI PNEUMATA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0486, + }, + [0x0488]={ + category="me", + description="COMBINING CYRILLIC HUNDRED THOUSANDS SIGN", + direction="nsm", + linebreak="cm", + unicodeslot=0x0488, + }, + [0x0489]={ + category="me", + description="COMBINING CYRILLIC MILLIONS SIGN", + direction="nsm", + linebreak="cm", + unicodeslot=0x0489, + }, + [0x048A]={ + category="lu", + contextname="cyrillicISHRTtail", + description="CYRILLIC CAPITAL LETTER SHORT I WITH TAIL", + direction="l", + lccode=0x048B, + linebreak="al", + unicodeslot=0x048A, + }, + [0x048B]={ + category="ll", + contextname="cyrillicishrttail", + description="CYRILLIC SMALL LETTER SHORT I WITH TAIL", + direction="l", + linebreak="al", + uccode=0x048A, + unicodeslot=0x048B, + }, + [0x048C]={ + category="lu", + contextname="cyrillicSEMISOFT", + description="CYRILLIC CAPITAL LETTER SEMISOFT SIGN", + direction="l", + lccode=0x048D, + linebreak="al", + unicodeslot=0x048C, + }, + [0x048D]={ + category="ll", + contextname="cyrillicsemisoft", + description="CYRILLIC SMALL LETTER SEMISOFT SIGN", + direction="l", + linebreak="al", + uccode=0x048C, + unicodeslot=0x048D, + }, + [0x048E]={ + category="lu", + contextname="cyrillicERtick", + description="CYRILLIC CAPITAL LETTER ER WITH TICK", + direction="l", + lccode=0x048F, + linebreak="al", + shcode=0x0420, + unicodeslot=0x048E, + }, + [0x048F]={ + category="ll", + contextname="cyrillicertick", + description="CYRILLIC SMALL LETTER ER WITH TICK", + direction="l", + linebreak="al", + shcode=0x0440, + uccode=0x048E, + unicodeslot=0x048F, + }, + [0x0490]={ + adobename="afii10050", + category="lu", + contextname="cyrillicGHEupturn", + description="CYRILLIC CAPITAL LETTER GHE WITH UPTURN", + direction="l", + lccode=0x0491, + linebreak="al", + shcode=0x0413, + unicodeslot=0x0490, + }, + [0x0491]={ + adobename="afii10098", + category="ll", + contextname="cyrillicgheupturn", + description="CYRILLIC SMALL LETTER GHE WITH UPTURN", + direction="l", + linebreak="al", + shcode=0x0433, + uccode=0x0490, + unicodeslot=0x0491, + }, + [0x0492]={ + category="lu", + contextname="cyrillicGHEstroke", + description="CYRILLIC CAPITAL LETTER GHE WITH STROKE", + direction="l", + lccode=0x0493, + linebreak="al", + shcode=0x0413, + unicodeslot=0x0492, + }, + [0x0493]={ + category="ll", + contextname="cyrillicghestroke", + description="CYRILLIC SMALL LETTER GHE WITH STROKE", + direction="l", + linebreak="al", + shcode=0x0433, + uccode=0x0492, + unicodeslot=0x0493, + }, + [0x0494]={ + category="lu", + contextname="cyrillicGHEmidhook", + description="CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK", + direction="l", + lccode=0x0495, + linebreak="al", + shcode=0x0413, + unicodeslot=0x0494, + }, + [0x0495]={ + category="ll", + contextname="cyrillicghemidhook", + description="CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK", + direction="l", + linebreak="al", + shcode=0x0433, + uccode=0x0494, + unicodeslot=0x0495, + }, + [0x0496]={ + category="lu", + contextname="cyrillicZHEdescender", + description="CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER", + direction="l", + lccode=0x0497, + linebreak="al", + shcode=0x0416, + unicodeslot=0x0496, + }, + [0x0497]={ + category="ll", + contextname="cyrilliczhedescender", + description="CYRILLIC SMALL LETTER ZHE WITH DESCENDER", + direction="l", + linebreak="al", + shcode=0x0436, + uccode=0x0496, + unicodeslot=0x0497, + }, + [0x0498]={ + category="lu", + contextname="cyrillicZDSC", + description="CYRILLIC CAPITAL LETTER ZE WITH DESCENDER", + direction="l", + lccode=0x0499, + linebreak="al", + shcode=0x0417, + unicodeslot=0x0498, + }, + [0x0499]={ + category="ll", + contextname="cyrilliczdsc", + description="CYRILLIC SMALL LETTER ZE WITH DESCENDER", + direction="l", + linebreak="al", + shcode=0x0437, + uccode=0x0498, + unicodeslot=0x0499, + }, + [0x049A]={ + category="lu", + contextname="cyrillicKADC", + description="CYRILLIC CAPITAL LETTER KA WITH DESCENDER", + direction="l", + lccode=0x049B, + linebreak="al", + shcode=0x041A, + unicodeslot=0x049A, + }, + [0x049B]={ + category="ll", + contextname="cyrillickadc", + description="CYRILLIC SMALL LETTER KA WITH DESCENDER", + direction="l", + linebreak="al", + shcode=0x043A, + uccode=0x049A, + unicodeslot=0x049B, + }, + [0x049C]={ + category="lu", + contextname="cyrillicKAvertstroke", + description="CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE", + direction="l", + lccode=0x049D, + linebreak="al", + shcode=0x041A, + unicodeslot=0x049C, + }, + [0x049D]={ + category="ll", + contextname="cyrillickavertstroke", + description="CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE", + direction="l", + linebreak="al", + shcode=0x043A, + uccode=0x049C, + unicodeslot=0x049D, + }, + [0x049E]={ + category="lu", + contextname="cyrillicKAstroke", + description="CYRILLIC CAPITAL LETTER KA WITH STROKE", + direction="l", + lccode=0x049F, + linebreak="al", + shcode=0x041A, + unicodeslot=0x049E, + }, + [0x049F]={ + category="ll", + contextname="cyrillickastroke", + description="CYRILLIC SMALL LETTER KA WITH STROKE", + direction="l", + linebreak="al", + shcode=0x043A, + uccode=0x049E, + unicodeslot=0x049F, + }, + [0x04A0]={ + category="lu", + contextname="cyrillicKAbashkir", + description="CYRILLIC CAPITAL LETTER BASHKIR KA", + direction="l", + lccode=0x04A1, + linebreak="al", + unicodeslot=0x04A0, + }, + [0x04A1]={ + category="ll", + contextname="cyrillickabashkir", + description="CYRILLIC SMALL LETTER BASHKIR KA", + direction="l", + linebreak="al", + uccode=0x04A0, + unicodeslot=0x04A1, + }, + [0x04A2]={ + category="lu", + contextname="cyrillicENDC", + description="CYRILLIC CAPITAL LETTER EN WITH DESCENDER", + direction="l", + lccode=0x04A3, + linebreak="al", + shcode=0x041D, + unicodeslot=0x04A2, + }, + [0x04A3]={ + category="ll", + contextname="cyrillicendc", + description="CYRILLIC SMALL LETTER EN WITH DESCENDER", + direction="l", + linebreak="al", + shcode=0x043D, + uccode=0x04A2, + unicodeslot=0x04A3, + }, + [0x04A4]={ + category="lu", + contextname="cyrillicENGHE", + description="CYRILLIC CAPITAL LIGATURE EN GHE", + direction="l", + lccode=0x04A5, + linebreak="al", + unicodeslot=0x04A4, + }, + [0x04A5]={ + category="ll", + contextname="cyrillicenghe", + description="CYRILLIC SMALL LIGATURE EN GHE", + direction="l", + linebreak="al", + uccode=0x04A4, + unicodeslot=0x04A5, + }, + [0x04A6]={ + category="lu", + contextname="cyrillicPEmidhook", + description="CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK", + direction="l", + lccode=0x04A7, + linebreak="al", + shcode=0x041F, + unicodeslot=0x04A6, + }, + [0x04A7]={ + category="ll", + contextname="cyrillicpemidhook", + description="CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK", + direction="l", + linebreak="al", + shcode=0x043F, + uccode=0x04A6, + unicodeslot=0x04A7, + }, + [0x04A8]={ + category="lu", + contextname="cyrillicHA", + description="CYRILLIC CAPITAL LETTER ABKHASIAN HA", + direction="l", + lccode=0x04A9, + linebreak="al", + unicodeslot=0x04A8, + }, + [0x04A9]={ + category="ll", + contextname="cyrillicha", + description="CYRILLIC SMALL LETTER ABKHASIAN HA", + direction="l", + linebreak="al", + uccode=0x04A8, + unicodeslot=0x04A9, + }, + [0x04AA]={ + category="lu", + contextname="cyrillicSDSC", + description="CYRILLIC CAPITAL LETTER ES WITH DESCENDER", + direction="l", + lccode=0x04AB, + linebreak="al", + shcode=0x0421, + unicodeslot=0x04AA, + }, + [0x04AB]={ + category="ll", + contextname="cyrillicsdsc", + description="CYRILLIC SMALL LETTER ES WITH DESCENDER", + direction="l", + linebreak="al", + shcode=0x0441, + uccode=0x04AA, + unicodeslot=0x04AB, + }, + [0x04AC]={ + category="lu", + contextname="cyrillicTEDC", + description="CYRILLIC CAPITAL LETTER TE WITH DESCENDER", + direction="l", + lccode=0x04AD, + linebreak="al", + shcode=0x0422, + unicodeslot=0x04AC, + }, + [0x04AD]={ + category="ll", + contextname="cyrillictedc", + description="CYRILLIC SMALL LETTER TE WITH DESCENDER", + direction="l", + linebreak="al", + shcode=0x0442, + uccode=0x04AC, + unicodeslot=0x04AD, + }, + [0x04AE]={ + category="lu", + contextname="cyrillicYstr", + description="CYRILLIC CAPITAL LETTER STRAIGHT U", + direction="l", + lccode=0x04AF, + linebreak="al", + unicodeslot=0x04AE, + }, + [0x04AF]={ + category="ll", + contextname="cyrillicystr", + description="CYRILLIC SMALL LETTER STRAIGHT U", + direction="l", + linebreak="al", + uccode=0x04AE, + unicodeslot=0x04AF, + }, + [0x04B0]={ + category="lu", + contextname="cyrillicYstrstroke", + description="CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE", + direction="l", + lccode=0x04B1, + linebreak="al", + unicodeslot=0x04B0, + }, + [0x04B1]={ + category="ll", + contextname="cyrillicystrstroke", + description="CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE", + direction="l", + linebreak="al", + uccode=0x04B0, + unicodeslot=0x04B1, + }, + [0x04B2]={ + category="lu", + contextname="cyrillicHADC", + description="CYRILLIC CAPITAL LETTER HA WITH DESCENDER", + direction="l", + lccode=0x04B3, + linebreak="al", + shcode=0x0425, + unicodeslot=0x04B2, + }, + [0x04B3]={ + category="ll", + contextname="cyrillichadc", + description="CYRILLIC SMALL LETTER HA WITH DESCENDER", + direction="l", + linebreak="al", + shcode=0x0445, + uccode=0x04B2, + unicodeslot=0x04B3, + }, + [0x04B4]={ + category="lu", + contextname="cyrillicTETSE", + description="CYRILLIC CAPITAL LIGATURE TE TSE", + direction="l", + lccode=0x04B5, + linebreak="al", + unicodeslot=0x04B4, + }, + [0x04B5]={ + category="ll", + contextname="cyrillictetse", + description="CYRILLIC SMALL LIGATURE TE TSE", + direction="l", + linebreak="al", + uccode=0x04B4, + unicodeslot=0x04B5, + }, + [0x04B6]={ + category="lu", + contextname="cyrillicCHEDC", + description="CYRILLIC CAPITAL LETTER CHE WITH DESCENDER", + direction="l", + lccode=0x04B7, + linebreak="al", + shcode=0x0427, + unicodeslot=0x04B6, + }, + [0x04B7]={ + category="ll", + contextname="cyrillicchedc", + description="CYRILLIC SMALL LETTER CHE WITH DESCENDER", + direction="l", + linebreak="al", + shcode=0x0447, + uccode=0x04B6, + unicodeslot=0x04B7, + }, + [0x04B8]={ + category="lu", + contextname="cyrillicCHEvertstroke", + description="CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE", + direction="l", + lccode=0x04B9, + linebreak="al", + shcode=0x0427, + unicodeslot=0x04B8, + }, + [0x04B9]={ + category="ll", + contextname="cyrillicchevertstroke", + description="CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE", + direction="l", + linebreak="al", + shcode=0x0447, + uccode=0x04B8, + unicodeslot=0x04B9, + }, + [0x04BA]={ + category="lu", + contextname="cyrillicSHHA", + description="CYRILLIC CAPITAL LETTER SHHA", + direction="l", + lccode=0x04BB, + linebreak="al", + unicodeslot=0x04BA, + }, + [0x04BB]={ + category="ll", + contextname="cyrillicshha", + description="CYRILLIC SMALL LETTER SHHA", + direction="l", + linebreak="al", + uccode=0x04BA, + unicodeslot=0x04BB, + }, + [0x04BC]={ + category="lu", + contextname="cyrillicCHEabkhasian", + description="CYRILLIC CAPITAL LETTER ABKHASIAN CHE", + direction="l", + lccode=0x04BD, + linebreak="al", + unicodeslot=0x04BC, + }, + [0x04BD]={ + category="ll", + contextname="cyrilliccheabkhasian", + description="CYRILLIC SMALL LETTER ABKHASIAN CHE", + direction="l", + linebreak="al", + uccode=0x04BC, + unicodeslot=0x04BD, + }, + [0x04BE]={ + category="lu", + contextname="cyrillicCHEDCabkhasian", + description="CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER", + direction="l", + lccode=0x04BF, + linebreak="al", + unicodeslot=0x04BE, + }, + [0x04BF]={ + category="ll", + contextname="cyrillicchedcabkhasian", + description="CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER", + direction="l", + linebreak="al", + uccode=0x04BE, + unicodeslot=0x04BF, + }, + [0x04C0]={ + category="lu", + contextname="cyrillicPALOCHKA", + description="CYRILLIC LETTER PALOCHKA", + direction="l", + lccode=0x04CF, + linebreak="al", + unicodeslot=0x04C0, + }, + [0x04C1]={ + category="lu", + contextname="cyrillicZHEbreve", + description="CYRILLIC CAPITAL LETTER ZHE WITH BREVE", + direction="l", + lccode=0x04C2, + linebreak="al", + shcode=0x0416, + specials={ "char", 0x0416, 0x0306 }, + unicodeslot=0x04C1, + }, + [0x04C2]={ + category="ll", + contextname="cyrilliczhebreve", + description="CYRILLIC SMALL LETTER ZHE WITH BREVE", + direction="l", + linebreak="al", + shcode=0x0436, + specials={ "char", 0x0436, 0x0306 }, + uccode=0x04C1, + unicodeslot=0x04C2, + }, + [0x04C3]={ + category="lu", + contextname="cyrillicKAhook", + description="CYRILLIC CAPITAL LETTER KA WITH HOOK", + direction="l", + lccode=0x04C4, + linebreak="al", + shcode=0x041A, + unicodeslot=0x04C3, + }, + [0x04C4]={ + category="ll", + contextname="cyrillickahook", + description="CYRILLIC SMALL LETTER KA WITH HOOK", + direction="l", + linebreak="al", + shcode=0x043A, + uccode=0x04C3, + unicodeslot=0x04C4, + }, + [0x04C5]={ + category="lu", + contextname="cyrillicELtail", + description="CYRILLIC CAPITAL LETTER EL WITH TAIL", + direction="l", + lccode=0x04C6, + linebreak="al", + shcode=0x041B, + unicodeslot=0x04C5, + }, + [0x04C6]={ + category="ll", + contextname="cyrilliceltail", + description="CYRILLIC SMALL LETTER EL WITH TAIL", + direction="l", + linebreak="al", + shcode=0x043B, + uccode=0x04C5, + unicodeslot=0x04C6, + }, + [0x04C7]={ + category="lu", + contextname="cyrillicENhook", + description="CYRILLIC CAPITAL LETTER EN WITH HOOK", + direction="l", + lccode=0x04C8, + linebreak="al", + shcode=0x041D, + unicodeslot=0x04C7, + }, + [0x04C8]={ + category="ll", + contextname="cyrillicenhook", + description="CYRILLIC SMALL LETTER EN WITH HOOK", + direction="l", + linebreak="al", + shcode=0x043D, + uccode=0x04C7, + unicodeslot=0x04C8, + }, + [0x04C9]={ + category="lu", + contextname="cyrillicENtail", + description="CYRILLIC CAPITAL LETTER EN WITH TAIL", + direction="l", + lccode=0x04CA, + linebreak="al", + shcode=0x041D, + unicodeslot=0x04C9, + }, + [0x04CA]={ + category="ll", + contextname="cyrillicentail", + description="CYRILLIC SMALL LETTER EN WITH TAIL", + direction="l", + linebreak="al", + shcode=0x043D, + uccode=0x04C9, + unicodeslot=0x04CA, + }, + [0x04CB]={ + category="lu", + contextname="cyrillicCHEkhakassian", + description="CYRILLIC CAPITAL LETTER KHAKASSIAN CHE", + direction="l", + lccode=0x04CC, + linebreak="al", + unicodeslot=0x04CB, + }, + [0x04CC]={ + category="ll", + contextname="cyrillicchekhakassian", + description="CYRILLIC SMALL LETTER KHAKASSIAN CHE", + direction="l", + linebreak="al", + uccode=0x04CB, + unicodeslot=0x04CC, + }, + [0x04CD]={ + category="lu", + contextname="cyrillicEMtail", + description="CYRILLIC CAPITAL LETTER EM WITH TAIL", + direction="l", + lccode=0x04CE, + linebreak="al", + shcode=0x041C, + unicodeslot=0x04CD, + }, + [0x04CE]={ + category="ll", + contextname="cyrillicemtail", + description="CYRILLIC SMALL LETTER EM WITH TAIL", + direction="l", + linebreak="al", + shcode=0x043C, + uccode=0x04CD, + unicodeslot=0x04CE, + }, + [0x04CF]={ + category="ll", + description="CYRILLIC SMALL LETTER PALOCHKA", + direction="l", + linebreak="al", + uccode=0x04C0, + unicodeslot=0x04CF, + }, + [0x04D0]={ + category="lu", + contextname="cyrillicAbreve", + description="CYRILLIC CAPITAL LETTER A WITH BREVE", + direction="l", + lccode=0x04D1, + linebreak="al", + shcode=0x0410, + specials={ "char", 0x0410, 0x0306 }, + unicodeslot=0x04D0, + }, + [0x04D1]={ + category="ll", + contextname="cyrillicabreve", + description="CYRILLIC SMALL LETTER A WITH BREVE", + direction="l", + linebreak="al", + shcode=0x0430, + specials={ "char", 0x0430, 0x0306 }, + uccode=0x04D0, + unicodeslot=0x04D1, + }, + [0x04D2]={ + category="lu", + contextname="cyrillicAdiaeresis", + description="CYRILLIC CAPITAL LETTER A WITH DIAERESIS", + direction="l", + lccode=0x04D3, + linebreak="al", + shcode=0x0410, + specials={ "char", 0x0410, 0x0308 }, + unicodeslot=0x04D2, + }, + [0x04D3]={ + category="ll", + contextname="cyrillicadiaeresis", + description="CYRILLIC SMALL LETTER A WITH DIAERESIS", + direction="l", + linebreak="al", + shcode=0x0430, + specials={ "char", 0x0430, 0x0308 }, + uccode=0x04D2, + unicodeslot=0x04D3, + }, + [0x04D4]={ + category="lu", + contextname="cyrillicAE", + description="CYRILLIC CAPITAL LIGATURE A IE", + direction="l", + lccode=0x04D5, + linebreak="al", + unicodeslot=0x04D4, + }, + [0x04D5]={ + category="ll", + contextname="cyrillicae", + description="CYRILLIC SMALL LIGATURE A IE", + direction="l", + linebreak="al", + uccode=0x04D4, + unicodeslot=0x04D5, + }, + [0x04D6]={ + category="lu", + contextname="cyrillicEbreve", + description="CYRILLIC CAPITAL LETTER IE WITH BREVE", + direction="l", + lccode=0x04D7, + linebreak="al", + shcode=0x0415, + specials={ "char", 0x0415, 0x0306 }, + unicodeslot=0x04D6, + }, + [0x04D7]={ + category="ll", + contextname="cyrillicebreve", + description="CYRILLIC SMALL LETTER IE WITH BREVE", + direction="l", + linebreak="al", + shcode=0x0435, + specials={ "char", 0x0435, 0x0306 }, + uccode=0x04D6, + unicodeslot=0x04D7, + }, + [0x04D8]={ + category="lu", + contextname="cyrillicSCHWA", + description="CYRILLIC CAPITAL LETTER SCHWA", + direction="l", + lccode=0x04D9, + linebreak="al", + unicodeslot=0x04D8, + }, + [0x04D9]={ + adobename="afii10846", + category="ll", + contextname="cyrillicschwa", + description="CYRILLIC SMALL LETTER SCHWA", + direction="l", + linebreak="al", + uccode=0x04D8, + unicodeslot=0x04D9, + }, + [0x04DA]={ + category="lu", + contextname="cyrillicSCHWAdiaeresis", + description="CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS", + direction="l", + lccode=0x04DB, + linebreak="al", + shcode=0x04D8, + specials={ "char", 0x04D8, 0x0308 }, + unicodeslot=0x04DA, + }, + [0x04DB]={ + category="ll", + contextname="cyrillicschwadiaeresis", + description="CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS", + direction="l", + linebreak="al", + shcode=0x04D9, + specials={ "char", 0x04D9, 0x0308 }, + uccode=0x04DA, + unicodeslot=0x04DB, + }, + [0x04DC]={ + category="lu", + contextname="cyrillicZHEdiaeresis", + description="CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS", + direction="l", + lccode=0x04DD, + linebreak="al", + shcode=0x0416, + specials={ "char", 0x0416, 0x0308 }, + unicodeslot=0x04DC, + }, + [0x04DD]={ + category="ll", + contextname="cyrilliczhediaeresis", + description="CYRILLIC SMALL LETTER ZHE WITH DIAERESIS", + direction="l", + linebreak="al", + shcode=0x0436, + specials={ "char", 0x0436, 0x0308 }, + uccode=0x04DC, + unicodeslot=0x04DD, + }, + [0x04DE]={ + category="lu", + contextname="cyrillicZEdiaeresis", + description="CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS", + direction="l", + lccode=0x04DF, + linebreak="al", + shcode=0x0417, + specials={ "char", 0x0417, 0x0308 }, + unicodeslot=0x04DE, + }, + [0x04DF]={ + category="ll", + contextname="cyrilliczediaeresis", + description="CYRILLIC SMALL LETTER ZE WITH DIAERESIS", + direction="l", + linebreak="al", + shcode=0x0437, + specials={ "char", 0x0437, 0x0308 }, + uccode=0x04DE, + unicodeslot=0x04DF, + }, + [0x04E0]={ + category="lu", + contextname="cyrillicDZEabkhasian", + description="CYRILLIC CAPITAL LETTER ABKHASIAN DZE", + direction="l", + lccode=0x04E1, + linebreak="al", + unicodeslot=0x04E0, + }, + [0x04E1]={ + category="ll", + contextname="cyrillicdzeabkhasian", + description="CYRILLIC SMALL LETTER ABKHASIAN DZE", + direction="l", + linebreak="al", + uccode=0x04E0, + unicodeslot=0x04E1, + }, + [0x04E2]={ + category="lu", + contextname="cyrillicImacron", + description="CYRILLIC CAPITAL LETTER I WITH MACRON", + direction="l", + lccode=0x04E3, + linebreak="al", + shcode=0x0418, + specials={ "char", 0x0418, 0x0304 }, + unicodeslot=0x04E2, + }, + [0x04E3]={ + category="ll", + contextname="cyrillicimacron", + description="CYRILLIC SMALL LETTER I WITH MACRON", + direction="l", + linebreak="al", + shcode=0x0438, + specials={ "char", 0x0438, 0x0304 }, + uccode=0x04E2, + unicodeslot=0x04E3, + }, + [0x04E4]={ + category="lu", + contextname="cyrillicIdiaeresis", + description="CYRILLIC CAPITAL LETTER I WITH DIAERESIS", + direction="l", + lccode=0x04E5, + linebreak="al", + shcode=0x0418, + specials={ "char", 0x0418, 0x0308 }, + unicodeslot=0x04E4, + }, + [0x04E5]={ + category="ll", + contextname="cyrillicidiaeresis", + description="CYRILLIC SMALL LETTER I WITH DIAERESIS", + direction="l", + linebreak="al", + shcode=0x0438, + specials={ "char", 0x0438, 0x0308 }, + uccode=0x04E4, + unicodeslot=0x04E5, + }, + [0x04E6]={ + category="lu", + contextname="cyrillicOdiaeresis", + description="CYRILLIC CAPITAL LETTER O WITH DIAERESIS", + direction="l", + lccode=0x04E7, + linebreak="al", + shcode=0x041E, + specials={ "char", 0x041E, 0x0308 }, + unicodeslot=0x04E6, + }, + [0x04E7]={ + category="ll", + contextname="cyrillicodiaeresis", + description="CYRILLIC SMALL LETTER O WITH DIAERESIS", + direction="l", + linebreak="al", + shcode=0x043E, + specials={ "char", 0x043E, 0x0308 }, + uccode=0x04E6, + unicodeslot=0x04E7, + }, + [0x04E8]={ + category="lu", + contextname="cyrillicObarred", + description="CYRILLIC CAPITAL LETTER BARRED O", + direction="l", + lccode=0x04E9, + linebreak="al", + unicodeslot=0x04E8, + }, + [0x04E9]={ + category="ll", + contextname="cyrillicobarred", + description="CYRILLIC SMALL LETTER BARRED O", + direction="l", + linebreak="al", + uccode=0x04E8, + unicodeslot=0x04E9, + }, + [0x04EA]={ + category="lu", + contextname="cyrillicObarreddiaeresis", + description="CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS", + direction="l", + lccode=0x04EB, + linebreak="al", + specials={ "char", 0x04E8, 0x0308 }, + unicodeslot=0x04EA, + }, + [0x04EB]={ + category="ll", + contextname="cyrillicobarreddiaeresis", + description="CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS", + direction="l", + linebreak="al", + specials={ "char", 0x04E9, 0x0308 }, + uccode=0x04EA, + unicodeslot=0x04EB, + }, + [0x04EC]={ + category="lu", + contextname="cyrillicEdiaeresis", + description="CYRILLIC CAPITAL LETTER E WITH DIAERESIS", + direction="l", + lccode=0x04ED, + linebreak="al", + shcode=0x042D, + specials={ "char", 0x042D, 0x0308 }, + unicodeslot=0x04EC, + }, + [0x04ED]={ + category="ll", + contextname="cyrillicediaeresis", + description="CYRILLIC SMALL LETTER E WITH DIAERESIS", + direction="l", + linebreak="al", + shcode=0x044D, + specials={ "char", 0x044D, 0x0308 }, + uccode=0x04EC, + unicodeslot=0x04ED, + }, + [0x04EE]={ + category="lu", + contextname="cyrillicUmacron", + description="CYRILLIC CAPITAL LETTER U WITH MACRON", + direction="l", + lccode=0x04EF, + linebreak="al", + shcode=0x0423, + specials={ "char", 0x0423, 0x0304 }, + unicodeslot=0x04EE, + }, + [0x04EF]={ + category="ll", + contextname="cyrillicumacron", + description="CYRILLIC SMALL LETTER U WITH MACRON", + direction="l", + linebreak="al", + shcode=0x0443, + specials={ "char", 0x0443, 0x0304 }, + uccode=0x04EE, + unicodeslot=0x04EF, + }, + [0x04F0]={ + category="lu", + contextname="cyrillicUdiaeresis", + description="CYRILLIC CAPITAL LETTER U WITH DIAERESIS", + direction="l", + lccode=0x04F1, + linebreak="al", + shcode=0x0423, + specials={ "char", 0x0423, 0x0308 }, + unicodeslot=0x04F0, + }, + [0x04F1]={ + category="ll", + contextname="cyrillicudiaeresis", + description="CYRILLIC SMALL LETTER U WITH DIAERESIS", + direction="l", + linebreak="al", + shcode=0x0443, + specials={ "char", 0x0443, 0x0308 }, + uccode=0x04F0, + unicodeslot=0x04F1, + }, + [0x04F2]={ + category="lu", + contextname="cyrillicUdoubleacute", + description="CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE", + direction="l", + lccode=0x04F3, + linebreak="al", + shcode=0x0423, + specials={ "char", 0x0423, 0x030B }, + unicodeslot=0x04F2, + }, + [0x04F3]={ + category="ll", + contextname="cyrillicudoubleacute", + description="CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE", + direction="l", + linebreak="al", + shcode=0x0443, + specials={ "char", 0x0443, 0x030B }, + uccode=0x04F2, + unicodeslot=0x04F3, + }, + [0x04F4]={ + category="lu", + contextname="cyrillicCHEdiaeresis", + description="CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS", + direction="l", + lccode=0x04F5, + linebreak="al", + shcode=0x0427, + specials={ "char", 0x0427, 0x0308 }, + unicodeslot=0x04F4, + }, + [0x04F5]={ + category="ll", + contextname="cyrillicchediaeresis", + description="CYRILLIC SMALL LETTER CHE WITH DIAERESIS", + direction="l", + linebreak="al", + shcode=0x0447, + specials={ "char", 0x0447, 0x0308 }, + uccode=0x04F4, + unicodeslot=0x04F5, + }, + [0x04F6]={ + category="lu", + description="CYRILLIC CAPITAL LETTER GHE WITH DESCENDER", + direction="l", + lccode=0x04F7, + linebreak="al", + shcode=0x0413, + unicodeslot=0x04F6, + }, + [0x04F7]={ + category="ll", + description="CYRILLIC SMALL LETTER GHE WITH DESCENDER", + direction="l", + linebreak="al", + shcode=0x0433, + uccode=0x04F6, + unicodeslot=0x04F7, + }, + [0x04F8]={ + category="lu", + contextname="cyrillicYERUdiaeresis", + description="CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS", + direction="l", + lccode=0x04F9, + linebreak="al", + shcode=0x042B, + specials={ "char", 0x042B, 0x0308 }, + unicodeslot=0x04F8, + }, + [0x04F9]={ + category="ll", + contextname="cyrillicyerudiaeresis", + description="CYRILLIC SMALL LETTER YERU WITH DIAERESIS", + direction="l", + linebreak="al", + shcode=0x044B, + specials={ "char", 0x044B, 0x0308 }, + uccode=0x04F8, + unicodeslot=0x04F9, + }, + [0x04FA]={ + category="lu", + description="CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK", + direction="l", + lccode=0x04FB, + linebreak="al", + shcode=0x0413, + unicodeslot=0x04FA, + }, + [0x04FB]={ + category="ll", + description="CYRILLIC SMALL LETTER GHE WITH STROKE AND HOOK", + direction="l", + linebreak="al", + shcode=0x0433, + uccode=0x04FA, + unicodeslot=0x04FB, + }, + [0x04FC]={ + category="lu", + description="CYRILLIC CAPITAL LETTER HA WITH HOOK", + direction="l", + lccode=0x04FD, + linebreak="al", + shcode=0x0425, + unicodeslot=0x04FC, + }, + [0x04FD]={ + category="ll", + description="CYRILLIC SMALL LETTER HA WITH HOOK", + direction="l", + linebreak="al", + shcode=0x0445, + uccode=0x04FC, + unicodeslot=0x04FD, + }, + [0x04FE]={ + category="lu", + description="CYRILLIC CAPITAL LETTER HA WITH STROKE", + direction="l", + lccode=0x04FF, + linebreak="al", + shcode=0x0425, + unicodeslot=0x04FE, + }, + [0x04FF]={ + category="ll", + description="CYRILLIC SMALL LETTER HA WITH STROKE", + direction="l", + linebreak="al", + shcode=0x0445, + uccode=0x04FE, + unicodeslot=0x04FF, + }, + [0x0500]={ + category="lu", + description="CYRILLIC CAPITAL LETTER KOMI DE", + direction="l", + lccode=0x0501, + linebreak="al", + unicodeslot=0x0500, + }, + [0x0501]={ + category="ll", + description="CYRILLIC SMALL LETTER KOMI DE", + direction="l", + linebreak="al", + uccode=0x0500, + unicodeslot=0x0501, + }, + [0x0502]={ + category="lu", + description="CYRILLIC CAPITAL LETTER KOMI DJE", + direction="l", + lccode=0x0503, + linebreak="al", + unicodeslot=0x0502, + }, + [0x0503]={ + category="ll", + description="CYRILLIC SMALL LETTER KOMI DJE", + direction="l", + linebreak="al", + uccode=0x0502, + unicodeslot=0x0503, + }, + [0x0504]={ + category="lu", + description="CYRILLIC CAPITAL LETTER KOMI ZJE", + direction="l", + lccode=0x0505, + linebreak="al", + unicodeslot=0x0504, + }, + [0x0505]={ + category="ll", + description="CYRILLIC SMALL LETTER KOMI ZJE", + direction="l", + linebreak="al", + uccode=0x0504, + unicodeslot=0x0505, + }, + [0x0506]={ + category="lu", + description="CYRILLIC CAPITAL LETTER KOMI DZJE", + direction="l", + lccode=0x0507, + linebreak="al", + unicodeslot=0x0506, + }, + [0x0507]={ + category="ll", + description="CYRILLIC SMALL LETTER KOMI DZJE", + direction="l", + linebreak="al", + uccode=0x0506, + unicodeslot=0x0507, + }, + [0x0508]={ + category="lu", + description="CYRILLIC CAPITAL LETTER KOMI LJE", + direction="l", + lccode=0x0509, + linebreak="al", + unicodeslot=0x0508, + }, + [0x0509]={ + category="ll", + description="CYRILLIC SMALL LETTER KOMI LJE", + direction="l", + linebreak="al", + uccode=0x0508, + unicodeslot=0x0509, + }, + [0x050A]={ + category="lu", + description="CYRILLIC CAPITAL LETTER KOMI NJE", + direction="l", + lccode=0x050B, + linebreak="al", + unicodeslot=0x050A, + }, + [0x050B]={ + category="ll", + description="CYRILLIC SMALL LETTER KOMI NJE", + direction="l", + linebreak="al", + uccode=0x050A, + unicodeslot=0x050B, + }, + [0x050C]={ + category="lu", + description="CYRILLIC CAPITAL LETTER KOMI SJE", + direction="l", + lccode=0x050D, + linebreak="al", + unicodeslot=0x050C, + }, + [0x050D]={ + category="ll", + description="CYRILLIC SMALL LETTER KOMI SJE", + direction="l", + linebreak="al", + uccode=0x050C, + unicodeslot=0x050D, + }, + [0x050E]={ + category="lu", + description="CYRILLIC CAPITAL LETTER KOMI TJE", + direction="l", + lccode=0x050F, + linebreak="al", + unicodeslot=0x050E, + }, + [0x050F]={ + category="ll", + description="CYRILLIC SMALL LETTER KOMI TJE", + direction="l", + linebreak="al", + uccode=0x050E, + unicodeslot=0x050F, + }, + [0x0510]={ + category="lu", + description="CYRILLIC CAPITAL LETTER REVERSED ZE", + direction="l", + lccode=0x0511, + linebreak="al", + unicodeslot=0x0510, + }, + [0x0511]={ + category="ll", + description="CYRILLIC SMALL LETTER REVERSED ZE", + direction="l", + linebreak="al", + uccode=0x0510, + unicodeslot=0x0511, + }, + [0x0512]={ + category="lu", + description="CYRILLIC CAPITAL LETTER EL WITH HOOK", + direction="l", + lccode=0x0513, + linebreak="al", + shcode=0x041B, + unicodeslot=0x0512, + }, + [0x0513]={ + category="ll", + description="CYRILLIC SMALL LETTER EL WITH HOOK", + direction="l", + linebreak="al", + shcode=0x043B, + uccode=0x0512, + unicodeslot=0x0513, + }, + [0x0531]={ + category="lu", + description="ARMENIAN CAPITAL LETTER AYB", + direction="l", + lccode=0x0561, + linebreak="al", + unicodeslot=0x0531, + }, + [0x0532]={ + category="lu", + description="ARMENIAN CAPITAL LETTER BEN", + direction="l", + lccode=0x0562, + linebreak="al", + unicodeslot=0x0532, + }, + [0x0533]={ + category="lu", + description="ARMENIAN CAPITAL LETTER GIM", + direction="l", + lccode=0x0563, + linebreak="al", + unicodeslot=0x0533, + }, + [0x0534]={ + category="lu", + description="ARMENIAN CAPITAL LETTER DA", + direction="l", + lccode=0x0564, + linebreak="al", + unicodeslot=0x0534, + }, + [0x0535]={ + category="lu", + description="ARMENIAN CAPITAL LETTER ECH", + direction="l", + lccode=0x0565, + linebreak="al", + unicodeslot=0x0535, + }, + [0x0536]={ + category="lu", + description="ARMENIAN CAPITAL LETTER ZA", + direction="l", + lccode=0x0566, + linebreak="al", + unicodeslot=0x0536, + }, + [0x0537]={ + category="lu", + description="ARMENIAN CAPITAL LETTER EH", + direction="l", + lccode=0x0567, + linebreak="al", + unicodeslot=0x0537, + }, + [0x0538]={ + category="lu", + description="ARMENIAN CAPITAL LETTER ET", + direction="l", + lccode=0x0568, + linebreak="al", + unicodeslot=0x0538, + }, + [0x0539]={ + category="lu", + description="ARMENIAN CAPITAL LETTER TO", + direction="l", + lccode=0x0569, + linebreak="al", + unicodeslot=0x0539, + }, + [0x053A]={ + category="lu", + description="ARMENIAN CAPITAL LETTER ZHE", + direction="l", + lccode=0x056A, + linebreak="al", + unicodeslot=0x053A, + }, + [0x053B]={ + category="lu", + description="ARMENIAN CAPITAL LETTER INI", + direction="l", + lccode=0x056B, + linebreak="al", + unicodeslot=0x053B, + }, + [0x053C]={ + category="lu", + description="ARMENIAN CAPITAL LETTER LIWN", + direction="l", + lccode=0x056C, + linebreak="al", + unicodeslot=0x053C, + }, + [0x053D]={ + category="lu", + description="ARMENIAN CAPITAL LETTER XEH", + direction="l", + lccode=0x056D, + linebreak="al", + unicodeslot=0x053D, + }, + [0x053E]={ + category="lu", + description="ARMENIAN CAPITAL LETTER CA", + direction="l", + lccode=0x056E, + linebreak="al", + unicodeslot=0x053E, + }, + [0x053F]={ + category="lu", + description="ARMENIAN CAPITAL LETTER KEN", + direction="l", + lccode=0x056F, + linebreak="al", + unicodeslot=0x053F, + }, + [0x0540]={ + category="lu", + description="ARMENIAN CAPITAL LETTER HO", + direction="l", + lccode=0x0570, + linebreak="al", + unicodeslot=0x0540, + }, + [0x0541]={ + category="lu", + description="ARMENIAN CAPITAL LETTER JA", + direction="l", + lccode=0x0571, + linebreak="al", + unicodeslot=0x0541, + }, + [0x0542]={ + category="lu", + description="ARMENIAN CAPITAL LETTER GHAD", + direction="l", + lccode=0x0572, + linebreak="al", + unicodeslot=0x0542, + }, + [0x0543]={ + category="lu", + description="ARMENIAN CAPITAL LETTER CHEH", + direction="l", + lccode=0x0573, + linebreak="al", + unicodeslot=0x0543, + }, + [0x0544]={ + category="lu", + description="ARMENIAN CAPITAL LETTER MEN", + direction="l", + lccode=0x0574, + linebreak="al", + unicodeslot=0x0544, + }, + [0x0545]={ + category="lu", + description="ARMENIAN CAPITAL LETTER YI", + direction="l", + lccode=0x0575, + linebreak="al", + unicodeslot=0x0545, + }, + [0x0546]={ + category="lu", + description="ARMENIAN CAPITAL LETTER NOW", + direction="l", + lccode=0x0576, + linebreak="al", + unicodeslot=0x0546, + }, + [0x0547]={ + category="lu", + description="ARMENIAN CAPITAL LETTER SHA", + direction="l", + lccode=0x0577, + linebreak="al", + unicodeslot=0x0547, + }, + [0x0548]={ + category="lu", + description="ARMENIAN CAPITAL LETTER VO", + direction="l", + lccode=0x0578, + linebreak="al", + unicodeslot=0x0548, + }, + [0x0549]={ + category="lu", + description="ARMENIAN CAPITAL LETTER CHA", + direction="l", + lccode=0x0579, + linebreak="al", + unicodeslot=0x0549, + }, + [0x054A]={ + category="lu", + description="ARMENIAN CAPITAL LETTER PEH", + direction="l", + lccode=0x057A, + linebreak="al", + unicodeslot=0x054A, + }, + [0x054B]={ + category="lu", + description="ARMENIAN CAPITAL LETTER JHEH", + direction="l", + lccode=0x057B, + linebreak="al", + unicodeslot=0x054B, + }, + [0x054C]={ + category="lu", + description="ARMENIAN CAPITAL LETTER RA", + direction="l", + lccode=0x057C, + linebreak="al", + unicodeslot=0x054C, + }, + [0x054D]={ + category="lu", + description="ARMENIAN CAPITAL LETTER SEH", + direction="l", + lccode=0x057D, + linebreak="al", + unicodeslot=0x054D, + }, + [0x054E]={ + category="lu", + description="ARMENIAN CAPITAL LETTER VEW", + direction="l", + lccode=0x057E, + linebreak="al", + unicodeslot=0x054E, + }, + [0x054F]={ + category="lu", + description="ARMENIAN CAPITAL LETTER TIWN", + direction="l", + lccode=0x057F, + linebreak="al", + unicodeslot=0x054F, + }, + [0x0550]={ + category="lu", + description="ARMENIAN CAPITAL LETTER REH", + direction="l", + lccode=0x0580, + linebreak="al", + unicodeslot=0x0550, + }, + [0x0551]={ + category="lu", + description="ARMENIAN CAPITAL LETTER CO", + direction="l", + lccode=0x0581, + linebreak="al", + unicodeslot=0x0551, + }, + [0x0552]={ + category="lu", + description="ARMENIAN CAPITAL LETTER YIWN", + direction="l", + lccode=0x0582, + linebreak="al", + unicodeslot=0x0552, + }, + [0x0553]={ + category="lu", + description="ARMENIAN CAPITAL LETTER PIWR", + direction="l", + lccode=0x0583, + linebreak="al", + unicodeslot=0x0553, + }, + [0x0554]={ + category="lu", + description="ARMENIAN CAPITAL LETTER KEH", + direction="l", + lccode=0x0584, + linebreak="al", + unicodeslot=0x0554, + }, + [0x0555]={ + category="lu", + description="ARMENIAN CAPITAL LETTER OH", + direction="l", + lccode=0x0585, + linebreak="al", + unicodeslot=0x0555, + }, + [0x0556]={ + category="lu", + description="ARMENIAN CAPITAL LETTER FEH", + direction="l", + lccode=0x0586, + linebreak="al", + unicodeslot=0x0556, + }, + [0x0559]={ + category="lm", + description="ARMENIAN MODIFIER LETTER LEFT HALF RING", + direction="l", + linebreak="al", + unicodeslot=0x0559, + }, + [0x055A]={ + category="po", + description="ARMENIAN APOSTROPHE", + direction="l", + linebreak="al", + unicodeslot=0x055A, + }, + [0x055B]={ + category="po", + description="ARMENIAN EMPHASIS MARK", + direction="l", + linebreak="al", + unicodeslot=0x055B, + }, + [0x055C]={ + category="po", + description="ARMENIAN EXCLAMATION MARK", + direction="l", + linebreak="al", + unicodeslot=0x055C, + }, + [0x055D]={ + category="po", + description="ARMENIAN COMMA", + direction="l", + linebreak="al", + unicodeslot=0x055D, + }, + [0x055E]={ + category="po", + description="ARMENIAN QUESTION MARK", + direction="l", + linebreak="al", + unicodeslot=0x055E, + }, + [0x055F]={ + category="po", + description="ARMENIAN ABBREVIATION MARK", + direction="l", + linebreak="al", + unicodeslot=0x055F, + }, + [0x0561]={ + category="ll", + description="ARMENIAN SMALL LETTER AYB", + direction="l", + linebreak="al", + uccode=0x0531, + unicodeslot=0x0561, + }, + [0x0562]={ + category="ll", + description="ARMENIAN SMALL LETTER BEN", + direction="l", + linebreak="al", + uccode=0x0532, + unicodeslot=0x0562, + }, + [0x0563]={ + category="ll", + description="ARMENIAN SMALL LETTER GIM", + direction="l", + linebreak="al", + uccode=0x0533, + unicodeslot=0x0563, + }, + [0x0564]={ + category="ll", + description="ARMENIAN SMALL LETTER DA", + direction="l", + linebreak="al", + uccode=0x0534, + unicodeslot=0x0564, + }, + [0x0565]={ + category="ll", + description="ARMENIAN SMALL LETTER ECH", + direction="l", + linebreak="al", + uccode=0x0535, + unicodeslot=0x0565, + }, + [0x0566]={ + category="ll", + description="ARMENIAN SMALL LETTER ZA", + direction="l", + linebreak="al", + uccode=0x0536, + unicodeslot=0x0566, + }, + [0x0567]={ + category="ll", + description="ARMENIAN SMALL LETTER EH", + direction="l", + linebreak="al", + uccode=0x0537, + unicodeslot=0x0567, + }, + [0x0568]={ + category="ll", + description="ARMENIAN SMALL LETTER ET", + direction="l", + linebreak="al", + uccode=0x0538, + unicodeslot=0x0568, + }, + [0x0569]={ + category="ll", + description="ARMENIAN SMALL LETTER TO", + direction="l", + linebreak="al", + uccode=0x0539, + unicodeslot=0x0569, + }, + [0x056A]={ + category="ll", + description="ARMENIAN SMALL LETTER ZHE", + direction="l", + linebreak="al", + uccode=0x053A, + unicodeslot=0x056A, + }, + [0x056B]={ + category="ll", + description="ARMENIAN SMALL LETTER INI", + direction="l", + linebreak="al", + uccode=0x053B, + unicodeslot=0x056B, + }, + [0x056C]={ + category="ll", + description="ARMENIAN SMALL LETTER LIWN", + direction="l", + linebreak="al", + uccode=0x053C, + unicodeslot=0x056C, + }, + [0x056D]={ + category="ll", + description="ARMENIAN SMALL LETTER XEH", + direction="l", + linebreak="al", + uccode=0x053D, + unicodeslot=0x056D, + }, + [0x056E]={ + category="ll", + description="ARMENIAN SMALL LETTER CA", + direction="l", + linebreak="al", + uccode=0x053E, + unicodeslot=0x056E, + }, + [0x056F]={ + category="ll", + description="ARMENIAN SMALL LETTER KEN", + direction="l", + linebreak="al", + uccode=0x053F, + unicodeslot=0x056F, + }, + [0x0570]={ + category="ll", + description="ARMENIAN SMALL LETTER HO", + direction="l", + linebreak="al", + uccode=0x0540, + unicodeslot=0x0570, + }, + [0x0571]={ + category="ll", + description="ARMENIAN SMALL LETTER JA", + direction="l", + linebreak="al", + uccode=0x0541, + unicodeslot=0x0571, + }, + [0x0572]={ + category="ll", + description="ARMENIAN SMALL LETTER GHAD", + direction="l", + linebreak="al", + uccode=0x0542, + unicodeslot=0x0572, + }, + [0x0573]={ + category="ll", + description="ARMENIAN SMALL LETTER CHEH", + direction="l", + linebreak="al", + uccode=0x0543, + unicodeslot=0x0573, + }, + [0x0574]={ + category="ll", + description="ARMENIAN SMALL LETTER MEN", + direction="l", + linebreak="al", + uccode=0x0544, + unicodeslot=0x0574, + }, + [0x0575]={ + category="ll", + description="ARMENIAN SMALL LETTER YI", + direction="l", + linebreak="al", + uccode=0x0545, + unicodeslot=0x0575, + }, + [0x0576]={ + category="ll", + description="ARMENIAN SMALL LETTER NOW", + direction="l", + linebreak="al", + uccode=0x0546, + unicodeslot=0x0576, + }, + [0x0577]={ + category="ll", + description="ARMENIAN SMALL LETTER SHA", + direction="l", + linebreak="al", + uccode=0x0547, + unicodeslot=0x0577, + }, + [0x0578]={ + category="ll", + description="ARMENIAN SMALL LETTER VO", + direction="l", + linebreak="al", + uccode=0x0548, + unicodeslot=0x0578, + }, + [0x0579]={ + category="ll", + description="ARMENIAN SMALL LETTER CHA", + direction="l", + linebreak="al", + uccode=0x0549, + unicodeslot=0x0579, + }, + [0x057A]={ + category="ll", + description="ARMENIAN SMALL LETTER PEH", + direction="l", + linebreak="al", + uccode=0x054A, + unicodeslot=0x057A, + }, + [0x057B]={ + category="ll", + description="ARMENIAN SMALL LETTER JHEH", + direction="l", + linebreak="al", + uccode=0x054B, + unicodeslot=0x057B, + }, + [0x057C]={ + category="ll", + description="ARMENIAN SMALL LETTER RA", + direction="l", + linebreak="al", + uccode=0x054C, + unicodeslot=0x057C, + }, + [0x057D]={ + category="ll", + description="ARMENIAN SMALL LETTER SEH", + direction="l", + linebreak="al", + uccode=0x054D, + unicodeslot=0x057D, + }, + [0x057E]={ + category="ll", + description="ARMENIAN SMALL LETTER VEW", + direction="l", + linebreak="al", + uccode=0x054E, + unicodeslot=0x057E, + }, + [0x057F]={ + category="ll", + description="ARMENIAN SMALL LETTER TIWN", + direction="l", + linebreak="al", + uccode=0x054F, + unicodeslot=0x057F, + }, + [0x0580]={ + category="ll", + description="ARMENIAN SMALL LETTER REH", + direction="l", + linebreak="al", + uccode=0x0550, + unicodeslot=0x0580, + }, + [0x0581]={ + category="ll", + description="ARMENIAN SMALL LETTER CO", + direction="l", + linebreak="al", + uccode=0x0551, + unicodeslot=0x0581, + }, + [0x0582]={ + category="ll", + description="ARMENIAN SMALL LETTER YIWN", + direction="l", + linebreak="al", + uccode=0x0552, + unicodeslot=0x0582, + }, + [0x0583]={ + category="ll", + description="ARMENIAN SMALL LETTER PIWR", + direction="l", + linebreak="al", + uccode=0x0553, + unicodeslot=0x0583, + }, + [0x0584]={ + category="ll", + description="ARMENIAN SMALL LETTER KEH", + direction="l", + linebreak="al", + uccode=0x0554, + unicodeslot=0x0584, + }, + [0x0585]={ + category="ll", + description="ARMENIAN SMALL LETTER OH", + direction="l", + linebreak="al", + uccode=0x0555, + unicodeslot=0x0585, + }, + [0x0586]={ + category="ll", + description="ARMENIAN SMALL LETTER FEH", + direction="l", + linebreak="al", + uccode=0x0556, + unicodeslot=0x0586, + }, + [0x0587]={ + category="ll", + description="ARMENIAN SMALL LIGATURE ECH YIWN", + direction="l", + linebreak="al", + specials={ "compat", 0x0565, 0x0582 }, + unicodeslot=0x0587, + }, + [0x0589]={ + category="po", + description="ARMENIAN FULL STOP", + direction="l", + linebreak="is", + unicodeslot=0x0589, + }, + [0x058A]={ + category="pd", + description="ARMENIAN HYPHEN", + direction="on", + linebreak="ba", + unicodeslot=0x058A, + }, + [0x0591]={ + category="mn", + description="HEBREW ACCENT ETNAHTA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0591, + }, + [0x0592]={ + category="mn", + description="HEBREW ACCENT SEGOL", + direction="nsm", + linebreak="cm", + unicodeslot=0x0592, + }, + [0x0593]={ + category="mn", + description="HEBREW ACCENT SHALSHELET", + direction="nsm", + linebreak="cm", + unicodeslot=0x0593, + }, + [0x0594]={ + category="mn", + description="HEBREW ACCENT ZAQEF QATAN", + direction="nsm", + linebreak="cm", + unicodeslot=0x0594, + }, + [0x0595]={ + category="mn", + description="HEBREW ACCENT ZAQEF GADOL", + direction="nsm", + linebreak="cm", + unicodeslot=0x0595, + }, + [0x0596]={ + category="mn", + description="HEBREW ACCENT TIPEHA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0596, + }, + [0x0597]={ + category="mn", + description="HEBREW ACCENT REVIA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0597, + }, + [0x0598]={ + category="mn", + description="HEBREW ACCENT ZARQA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0598, + }, + [0x0599]={ + category="mn", + description="HEBREW ACCENT PASHTA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0599, + }, + [0x059A]={ + category="mn", + description="HEBREW ACCENT YETIV", + direction="nsm", + linebreak="cm", + unicodeslot=0x059A, + }, + [0x059B]={ + category="mn", + description="HEBREW ACCENT TEVIR", + direction="nsm", + linebreak="cm", + unicodeslot=0x059B, + }, + [0x059C]={ + category="mn", + description="HEBREW ACCENT GERESH", + direction="nsm", + linebreak="cm", + unicodeslot=0x059C, + }, + [0x059D]={ + category="mn", + description="HEBREW ACCENT GERESH MUQDAM", + direction="nsm", + linebreak="cm", + unicodeslot=0x059D, + }, + [0x059E]={ + category="mn", + description="HEBREW ACCENT GERSHAYIM", + direction="nsm", + linebreak="cm", + unicodeslot=0x059E, + }, + [0x059F]={ + category="mn", + description="HEBREW ACCENT QARNEY PARA", + direction="nsm", + linebreak="cm", + unicodeslot=0x059F, + }, + [0x05A0]={ + category="mn", + description="HEBREW ACCENT TELISHA GEDOLA", + direction="nsm", + linebreak="cm", + unicodeslot=0x05A0, + }, + [0x05A1]={ + category="mn", + description="HEBREW ACCENT PAZER", + direction="nsm", + linebreak="cm", + unicodeslot=0x05A1, + }, + [0x05A2]={ + category="mn", + description="HEBREW ACCENT ATNAH HAFUKH", + direction="nsm", + linebreak="cm", + unicodeslot=0x05A2, + }, + [0x05A3]={ + category="mn", + description="HEBREW ACCENT MUNAH", + direction="nsm", + linebreak="cm", + unicodeslot=0x05A3, + }, + [0x05A4]={ + category="mn", + description="HEBREW ACCENT MAHAPAKH", + direction="nsm", + linebreak="cm", + unicodeslot=0x05A4, + }, + [0x05A5]={ + category="mn", + description="HEBREW ACCENT MERKHA", + direction="nsm", + linebreak="cm", + unicodeslot=0x05A5, + }, + [0x05A6]={ + category="mn", + description="HEBREW ACCENT MERKHA KEFULA", + direction="nsm", + linebreak="cm", + unicodeslot=0x05A6, + }, + [0x05A7]={ + category="mn", + description="HEBREW ACCENT DARGA", + direction="nsm", + linebreak="cm", + unicodeslot=0x05A7, + }, + [0x05A8]={ + category="mn", + description="HEBREW ACCENT QADMA", + direction="nsm", + linebreak="cm", + unicodeslot=0x05A8, + }, + [0x05A9]={ + category="mn", + description="HEBREW ACCENT TELISHA QETANA", + direction="nsm", + linebreak="cm", + unicodeslot=0x05A9, + }, + [0x05AA]={ + category="mn", + description="HEBREW ACCENT YERAH BEN YOMO", + direction="nsm", + linebreak="cm", + unicodeslot=0x05AA, + }, + [0x05AB]={ + category="mn", + description="HEBREW ACCENT OLE", + direction="nsm", + linebreak="cm", + unicodeslot=0x05AB, + }, + [0x05AC]={ + category="mn", + description="HEBREW ACCENT ILUY", + direction="nsm", + linebreak="cm", + unicodeslot=0x05AC, + }, + [0x05AD]={ + category="mn", + description="HEBREW ACCENT DEHI", + direction="nsm", + linebreak="cm", + unicodeslot=0x05AD, + }, + [0x05AE]={ + category="mn", + description="HEBREW ACCENT ZINOR", + direction="nsm", + linebreak="cm", + unicodeslot=0x05AE, + }, + [0x05AF]={ + category="mn", + description="HEBREW MARK MASORA CIRCLE", + direction="nsm", + linebreak="cm", + unicodeslot=0x05AF, + }, + [0x05B0]={ + adobename="afii57799", + category="mn", + description="HEBREW POINT SHEVA", + direction="nsm", + linebreak="cm", + unicodeslot=0x05B0, + }, + [0x05B1]={ + adobename="afii57801", + category="mn", + description="HEBREW POINT HATAF SEGOL", + direction="nsm", + linebreak="cm", + unicodeslot=0x05B1, + }, + [0x05B2]={ + adobename="afii57800", + category="mn", + description="HEBREW POINT HATAF PATAH", + direction="nsm", + linebreak="cm", + unicodeslot=0x05B2, + }, + [0x05B3]={ + adobename="afii57802", + category="mn", + description="HEBREW POINT HATAF QAMATS", + direction="nsm", + linebreak="cm", + unicodeslot=0x05B3, + }, + [0x05B4]={ + adobename="afii57793", + category="mn", + description="HEBREW POINT HIRIQ", + direction="nsm", + linebreak="cm", + unicodeslot=0x05B4, + }, + [0x05B5]={ + adobename="afii57794", + category="mn", + description="HEBREW POINT TSERE", + direction="nsm", + linebreak="cm", + unicodeslot=0x05B5, + }, + [0x05B6]={ + adobename="afii57795", + category="mn", + description="HEBREW POINT SEGOL", + direction="nsm", + linebreak="cm", + unicodeslot=0x05B6, + }, + [0x05B7]={ + adobename="afii57798", + category="mn", + description="HEBREW POINT PATAH", + direction="nsm", + linebreak="cm", + unicodeslot=0x05B7, + }, + [0x05B8]={ + adobename="afii57797", + category="mn", + description="HEBREW POINT QAMATS", + direction="nsm", + linebreak="cm", + unicodeslot=0x05B8, + }, + [0x05B9]={ + adobename="afii57806", + category="mn", + description="HEBREW POINT HOLAM", + direction="nsm", + linebreak="cm", + unicodeslot=0x05B9, + }, + [0x05BA]={ + category="mn", + description="HEBREW POINT HOLAM HASER FOR VAV", + direction="nsm", + linebreak="cm", + unicodeslot=0x05BA, + }, + [0x05BB]={ + adobename="afii57796", + category="mn", + description="HEBREW POINT QUBUTS", + direction="nsm", + linebreak="cm", + unicodeslot=0x05BB, + }, + [0x05BC]={ + adobename="afii57807", + category="mn", + description="HEBREW POINT DAGESH OR MAPIQ", + direction="nsm", + linebreak="cm", + unicodeslot=0x05BC, + }, + [0x05BD]={ + adobename="afii57839", + category="mn", + description="HEBREW POINT METEG", + direction="nsm", + linebreak="cm", + unicodeslot=0x05BD, + }, + [0x05BE]={ + adobename="afii57645", + category="po", + description="HEBREW PUNCTUATION MAQAF", + direction="r", + linebreak="ba", + unicodeslot=0x05BE, + }, + [0x05BF]={ + adobename="afii57841", + category="mn", + description="HEBREW POINT RAFE", + direction="nsm", + linebreak="cm", + unicodeslot=0x05BF, + }, + [0x05C0]={ + adobename="afii57842", + category="po", + description="HEBREW PUNCTUATION PASEQ", + direction="r", + linebreak="al", + unicodeslot=0x05C0, + }, + [0x05C1]={ + adobename="afii57804", + category="mn", + description="HEBREW POINT SHIN DOT", + direction="nsm", + linebreak="cm", + unicodeslot=0x05C1, + }, + [0x05C2]={ + adobename="afii57803", + category="mn", + description="HEBREW POINT SIN DOT", + direction="nsm", + linebreak="cm", + unicodeslot=0x05C2, + }, + [0x05C3]={ + adobename="afii57658", + category="po", + description="HEBREW PUNCTUATION SOF PASUQ", + direction="r", + linebreak="al", + unicodeslot=0x05C3, + }, + [0x05C4]={ + category="mn", + description="HEBREW MARK UPPER DOT", + direction="nsm", + linebreak="cm", + unicodeslot=0x05C4, + }, + [0x05C5]={ + category="mn", + description="HEBREW MARK LOWER DOT", + direction="nsm", + linebreak="cm", + unicodeslot=0x05C5, + }, + [0x05C6]={ + category="po", + description="HEBREW PUNCTUATION NUN HAFUKHA", + direction="r", + linebreak="ex", + unicodeslot=0x05C6, + }, + [0x05C7]={ + category="mn", + description="HEBREW POINT QAMATS QATAN", + direction="nsm", + linebreak="cm", + unicodeslot=0x05C7, + }, + [0x05D0]={ + adobename="afii57664", + category="lo", + contextname="hebrewAlef", + description="HEBREW LETTER ALEF", + direction="r", + linebreak="al", + unicodeslot=0x05D0, + }, + [0x05D1]={ + adobename="afii57665", + category="lo", + contextname="hebrewBet", + description="HEBREW LETTER BET", + direction="r", + linebreak="al", + unicodeslot=0x05D1, + }, + [0x05D2]={ + adobename="afii57666", + category="lo", + contextname="hebrewGimel", + description="HEBREW LETTER GIMEL", + direction="r", + linebreak="al", + unicodeslot=0x05D2, + }, + [0x05D3]={ + adobename="afii57667", + category="lo", + contextname="hebrewDalet", + description="HEBREW LETTER DALET", + direction="r", + linebreak="al", + unicodeslot=0x05D3, + }, + [0x05D4]={ + adobename="afii57668", + category="lo", + contextname="hebrewHe", + description="HEBREW LETTER HE", + direction="r", + linebreak="al", + unicodeslot=0x05D4, + }, + [0x05D5]={ + adobename="afii57669", + category="lo", + contextname="hebrewVav", + description="HEBREW LETTER VAV", + direction="r", + linebreak="al", + unicodeslot=0x05D5, + }, + [0x05D6]={ + adobename="afii57670", + category="lo", + contextname="hebrewZayin", + description="HEBREW LETTER ZAYIN", + direction="r", + linebreak="al", + unicodeslot=0x05D6, + }, + [0x05D7]={ + adobename="afii57671", + category="lo", + contextname="hebrewHet", + description="HEBREW LETTER HET", + direction="r", + linebreak="al", + unicodeslot=0x05D7, + }, + [0x05D8]={ + adobename="afii57672", + category="lo", + contextname="hebrewTet", + description="HEBREW LETTER TET", + direction="r", + linebreak="al", + unicodeslot=0x05D8, + }, + [0x05D9]={ + adobename="afii57673", + category="lo", + contextname="hebrewYod", + description="HEBREW LETTER YOD", + direction="r", + linebreak="al", + unicodeslot=0x05D9, + }, + [0x05DA]={ + adobename="afii57674", + category="lo", + contextname="hebrewKaffinal", + description="HEBREW LETTER FINAL KAF", + direction="r", + linebreak="al", + unicodeslot=0x05DA, + }, + [0x05DB]={ + adobename="afii57675", + category="lo", + contextname="hebrewKaf", + description="HEBREW LETTER KAF", + direction="r", + linebreak="al", + unicodeslot=0x05DB, + }, + [0x05DC]={ + adobename="afii57676", + category="lo", + contextname="hebrewLamed", + description="HEBREW LETTER LAMED", + direction="r", + linebreak="al", + unicodeslot=0x05DC, + }, + [0x05DD]={ + adobename="afii57677", + category="lo", + contextname="hebrewMemfinal", + description="HEBREW LETTER FINAL MEM", + direction="r", + linebreak="al", + unicodeslot=0x05DD, + }, + [0x05DE]={ + adobename="afii57678", + category="lo", + contextname="hebrewMem", + description="HEBREW LETTER MEM", + direction="r", + linebreak="al", + unicodeslot=0x05DE, + }, + [0x05DF]={ + adobename="afii57679", + category="lo", + contextname="hebrewNunfinal", + description="HEBREW LETTER FINAL NUN", + direction="r", + linebreak="al", + unicodeslot=0x05DF, + }, + [0x05E0]={ + adobename="afii57680", + category="lo", + contextname="hebrewNun", + description="HEBREW LETTER NUN", + direction="r", + linebreak="al", + unicodeslot=0x05E0, + }, + [0x05E1]={ + adobename="afii57681", + category="lo", + contextname="hebrewSamekh", + description="HEBREW LETTER SAMEKH", + direction="r", + linebreak="al", + unicodeslot=0x05E1, + }, + [0x05E2]={ + adobename="afii57682", + category="lo", + contextname="hebrewAyin", + description="HEBREW LETTER AYIN", + direction="r", + linebreak="al", + unicodeslot=0x05E2, + }, + [0x05E3]={ + adobename="afii57683", + category="lo", + contextname="hebrewPefinal", + description="HEBREW LETTER FINAL PE", + direction="r", + linebreak="al", + unicodeslot=0x05E3, + }, + [0x05E4]={ + adobename="afii57684", + category="lo", + contextname="hebrewPe", + description="HEBREW LETTER PE", + direction="r", + linebreak="al", + unicodeslot=0x05E4, + }, + [0x05E5]={ + adobename="afii57685", + category="lo", + contextname="hebrewTsadifinal", + description="HEBREW LETTER FINAL TSADI", + direction="r", + linebreak="al", + unicodeslot=0x05E5, + }, + [0x05E6]={ + adobename="afii57686", + category="lo", + contextname="hebrewTsadi", + description="HEBREW LETTER TSADI", + direction="r", + linebreak="al", + unicodeslot=0x05E6, + }, + [0x05E7]={ + adobename="afii57687", + category="lo", + contextname="hebrewQof", + description="HEBREW LETTER QOF", + direction="r", + linebreak="al", + unicodeslot=0x05E7, + }, + [0x05E8]={ + adobename="afii57688", + category="lo", + contextname="hebrewResh", + description="HEBREW LETTER RESH", + direction="r", + linebreak="al", + unicodeslot=0x05E8, + }, + [0x05E9]={ + adobename="afii57689", + category="lo", + contextname="hebrewShin", + description="HEBREW LETTER SHIN", + direction="r", + linebreak="al", + unicodeslot=0x05E9, + }, + [0x05EA]={ + adobename="afii57690", + category="lo", + contextname="hebrewTav", + description="HEBREW LETTER TAV", + direction="r", + linebreak="al", + unicodeslot=0x05EA, + }, + [0x05F0]={ + adobename="afii57716", + category="lo", + description="HEBREW LIGATURE YIDDISH DOUBLE VAV", + direction="r", + linebreak="al", + unicodeslot=0x05F0, + }, + [0x05F1]={ + adobename="afii57717", + category="lo", + description="HEBREW LIGATURE YIDDISH VAV YOD", + direction="r", + linebreak="al", + unicodeslot=0x05F1, + }, + [0x05F2]={ + adobename="afii57718", + category="lo", + description="HEBREW LIGATURE YIDDISH DOUBLE YOD", + direction="r", + linebreak="al", + unicodeslot=0x05F2, + }, + [0x05F3]={ + category="po", + description="HEBREW PUNCTUATION GERESH", + direction="r", + linebreak="al", + unicodeslot=0x05F3, + }, + [0x05F4]={ + category="po", + description="HEBREW PUNCTUATION GERSHAYIM", + direction="r", + linebreak="al", + unicodeslot=0x05F4, + }, + [0x0600]={ + category="cf", + description="ARABIC NUMBER SIGN", + direction="an", + visible="yes", + linebreak="al", + unicodeslot=0x0600, + }, + [0x0601]={ + category="cf", + description="ARABIC SIGN SANAH", + direction="an", + visible="yes", + linebreak="al", + unicodeslot=0x0601, + }, + [0x0602]={ + category="cf", + description="ARABIC FOOTNOTE MARKER", + direction="an", + visible="yes", + linebreak="al", + unicodeslot=0x0602, + }, + [0x0603]={ + category="cf", + description="ARABIC SIGN SAFHA", + direction="an", + visible="yes", + linebreak="al", + unicodeslot=0x0603, + }, + [0x060B]={ + category="sc", + description="AFGHANI SIGN", + direction="al", + linebreak="po", + unicodeslot=0x060B, + }, + [0x060C]={ + adobename="afii57388", + category="po", + description="ARABIC COMMA", + direction="cs", + linebreak="ex", + unicodeslot=0x060C, + }, + [0x060D]={ + category="po", + description="ARABIC DATE SEPARATOR", + direction="al", + linebreak="is", + unicodeslot=0x060D, + }, + [0x060E]={ + category="so", + description="ARABIC POETIC VERSE SIGN", + direction="on", + linebreak="al", + unicodeslot=0x060E, + }, + [0x060F]={ + category="so", + description="ARABIC SIGN MISRA", + direction="on", + linebreak="al", + unicodeslot=0x060F, + }, + [0x0610]={ + category="mn", + description="ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM", + direction="nsm", + linebreak="cm", + unicodeslot=0x0610, + }, + [0x0611]={ + category="mn", + description="ARABIC SIGN ALAYHE ASSALLAM", + direction="nsm", + linebreak="cm", + unicodeslot=0x0611, + }, + [0x0612]={ + category="mn", + description="ARABIC SIGN RAHMATULLAH ALAYHE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0612, + }, + [0x0613]={ + category="mn", + description="ARABIC SIGN RADI ALLAHOU ANHU", + direction="nsm", + linebreak="cm", + unicodeslot=0x0613, + }, + [0x0614]={ + category="mn", + description="ARABIC SIGN TAKHALLUS", + direction="nsm", + linebreak="cm", + unicodeslot=0x0614, + }, + [0x0615]={ + category="mn", + description="ARABIC SMALL HIGH TAH", + direction="nsm", + linebreak="cm", + unicodeslot=0x0615, + }, + [0x061B]={ + adobename="afii57403", + category="po", + description="ARABIC SEMICOLON", + direction="al", + linebreak="ex", + unicodeslot=0x061B, + }, + [0x061E]={ + category="po", + description="ARABIC TRIPLE DOT PUNCTUATION MARK", + direction="al", + linebreak="ex", + unicodeslot=0x061E, + }, + [0x061F]={ + adobename="afii57407", + category="po", + description="ARABIC QUESTION MARK", + direction="al", + linebreak="ex", + unicodeslot=0x061F, + }, + [0x0621]={ + adobename="afii57409", + category="lo", + description="ARABIC LETTER HAMZA", + direction="al", + linebreak="al", + unicodeslot=0x0621, + }, + [0x0622]={ + adobename="afii57410", + category="lo", + description="ARABIC LETTER ALEF WITH MADDA ABOVE", + direction="al", + linebreak="al", + shcode=0x0627, + specials={ "char", 0x0627, 0x0653 }, + unicodeslot=0x0622, + }, + [0x0623]={ + adobename="afii57411", + category="lo", + description="ARABIC LETTER ALEF WITH HAMZA ABOVE", + direction="al", + linebreak="al", + shcode=0x0627, + specials={ "char", 0x0627, 0x0654 }, + unicodeslot=0x0623, + }, + [0x0624]={ + adobename="afii57412", + category="lo", + description="ARABIC LETTER WAW WITH HAMZA ABOVE", + direction="al", + linebreak="al", + shcode=0x0648, + specials={ "char", 0x0648, 0x0654 }, + unicodeslot=0x0624, + }, + [0x0625]={ + adobename="afii57413", + category="lo", + description="ARABIC LETTER ALEF WITH HAMZA BELOW", + direction="al", + linebreak="al", + shcode=0x0627, + specials={ "char", 0x0627, 0x0655 }, + unicodeslot=0x0625, + }, + [0x0626]={ + adobename="afii57414", + category="lo", + description="ARABIC LETTER YEH WITH HAMZA ABOVE", + direction="al", + linebreak="al", + shcode=0x064A, + specials={ "char", 0x064A, 0x0654 }, + unicodeslot=0x0626, + }, + [0x0627]={ + adobename="afii57415", + category="lo", + description="ARABIC LETTER ALEF", + direction="al", + linebreak="al", + unicodeslot=0x0627, + }, + [0x0628]={ + adobename="afii57416", + category="lo", + description="ARABIC LETTER BEH", + direction="al", + linebreak="al", + unicodeslot=0x0628, + }, + [0x0629]={ + adobename="afii57417", + category="lo", + description="ARABIC LETTER TEH MARBUTA", + direction="al", + linebreak="al", + unicodeslot=0x0629, + }, + [0x062A]={ + adobename="afii57418", + category="lo", + description="ARABIC LETTER TEH", + direction="al", + linebreak="al", + unicodeslot=0x062A, + }, + [0x062B]={ + adobename="afii57419", + category="lo", + description="ARABIC LETTER THEH", + direction="al", + linebreak="al", + unicodeslot=0x062B, + }, + [0x062C]={ + adobename="afii57420", + category="lo", + description="ARABIC LETTER JEEM", + direction="al", + linebreak="al", + unicodeslot=0x062C, + }, + [0x062D]={ + adobename="afii57421", + category="lo", + description="ARABIC LETTER HAH", + direction="al", + linebreak="al", + unicodeslot=0x062D, + }, + [0x062E]={ + adobename="afii57422", + category="lo", + description="ARABIC LETTER KHAH", + direction="al", + linebreak="al", + unicodeslot=0x062E, + }, + [0x062F]={ + adobename="afii57423", + category="lo", + description="ARABIC LETTER DAL", + direction="al", + linebreak="al", + unicodeslot=0x062F, + }, + [0x0630]={ + adobename="afii57424", + category="lo", + description="ARABIC LETTER THAL", + direction="al", + linebreak="al", + unicodeslot=0x0630, + }, + [0x0631]={ + adobename="afii57425", + category="lo", + description="ARABIC LETTER REH", + direction="al", + linebreak="al", + unicodeslot=0x0631, + }, + [0x0632]={ + adobename="afii57426", + category="lo", + description="ARABIC LETTER ZAIN", + direction="al", + linebreak="al", + unicodeslot=0x0632, + }, + [0x0633]={ + adobename="afii57427", + category="lo", + description="ARABIC LETTER SEEN", + direction="al", + linebreak="al", + unicodeslot=0x0633, + }, + [0x0634]={ + adobename="afii57428", + category="lo", + description="ARABIC LETTER SHEEN", + direction="al", + linebreak="al", + unicodeslot=0x0634, + }, + [0x0635]={ + adobename="afii57429", + category="lo", + description="ARABIC LETTER SAD", + direction="al", + linebreak="al", + unicodeslot=0x0635, + }, + [0x0636]={ + adobename="afii57430", + category="lo", + description="ARABIC LETTER DAD", + direction="al", + linebreak="al", + unicodeslot=0x0636, + }, + [0x0637]={ + adobename="afii57431", + category="lo", + description="ARABIC LETTER TAH", + direction="al", + linebreak="al", + unicodeslot=0x0637, + }, + [0x0638]={ + adobename="afii57432", + category="lo", + description="ARABIC LETTER ZAH", + direction="al", + linebreak="al", + unicodeslot=0x0638, + }, + [0x0639]={ + adobename="afii57433", + category="lo", + description="ARABIC LETTER AIN", + direction="al", + linebreak="al", + unicodeslot=0x0639, + }, + [0x063A]={ + adobename="afii57434", + category="lo", + description="ARABIC LETTER GHAIN", + direction="al", + linebreak="al", + unicodeslot=0x063A, + }, + [0x0640]={ + adobename="afii57440", + category="lm", + description="ARABIC TATWEEL", + direction="al", + linebreak="al", + unicodeslot=0x0640, + }, + [0x0641]={ + adobename="afii57441", + category="lo", + description="ARABIC LETTER FEH", + direction="al", + linebreak="al", + unicodeslot=0x0641, + }, + [0x0642]={ + adobename="afii57442", + category="lo", + description="ARABIC LETTER QAF", + direction="al", + linebreak="al", + unicodeslot=0x0642, + }, + [0x0643]={ + adobename="afii57443", + category="lo", + description="ARABIC LETTER KAF", + direction="al", + linebreak="al", + unicodeslot=0x0643, + }, + [0x0644]={ + adobename="afii57444", + category="lo", + description="ARABIC LETTER LAM", + direction="al", + linebreak="al", + unicodeslot=0x0644, + }, + [0x0645]={ + adobename="afii57445", + category="lo", + description="ARABIC LETTER MEEM", + direction="al", + linebreak="al", + unicodeslot=0x0645, + }, + [0x0646]={ + adobename="afii57446", + category="lo", + description="ARABIC LETTER NOON", + direction="al", + linebreak="al", + unicodeslot=0x0646, + }, + [0x0647]={ + adobename="afii57470", + category="lo", + description="ARABIC LETTER HEH", + direction="al", + linebreak="al", + unicodeslot=0x0647, + }, + [0x0648]={ + adobename="afii57448", + category="lo", + description="ARABIC LETTER WAW", + direction="al", + linebreak="al", + unicodeslot=0x0648, + }, + [0x0649]={ + adobename="afii57449", + category="lo", + description="ARABIC LETTER ALEF MAKSURA", + direction="al", + linebreak="al", + unicodeslot=0x0649, + }, + [0x064A]={ + adobename="afii57450", + category="lo", + description="ARABIC LETTER YEH", + direction="al", + linebreak="al", + unicodeslot=0x064A, + }, + [0x064B]={ + adobename="afii57451", + category="mn", + description="ARABIC FATHATAN", + direction="nsm", + linebreak="cm", + unicodeslot=0x064B, + }, + [0x064C]={ + adobename="afii57452", + category="mn", + description="ARABIC DAMMATAN", + direction="nsm", + linebreak="cm", + unicodeslot=0x064C, + }, + [0x064D]={ + adobename="afii57453", + category="mn", + description="ARABIC KASRATAN", + direction="nsm", + linebreak="cm", + unicodeslot=0x064D, + }, + [0x064E]={ + adobename="afii57454", + category="mn", + description="ARABIC FATHA", + direction="nsm", + linebreak="cm", + unicodeslot=0x064E, + }, + [0x064F]={ + adobename="afii57455", + category="mn", + description="ARABIC DAMMA", + direction="nsm", + linebreak="cm", + unicodeslot=0x064F, + }, + [0x0650]={ + adobename="afii57456", + category="mn", + description="ARABIC KASRA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0650, + }, + [0x0651]={ + adobename="afii57457", + category="mn", + description="ARABIC SHADDA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0651, + }, + [0x0652]={ + adobename="afii57458", + category="mn", + description="ARABIC SUKUN", + direction="nsm", + linebreak="cm", + unicodeslot=0x0652, + }, + [0x0653]={ + category="mn", + description="ARABIC MADDAH ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0653, + }, + [0x0654]={ + category="mn", + description="ARABIC HAMZA ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0654, + }, + [0x0655]={ + category="mn", + description="ARABIC HAMZA BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0655, + }, + [0x0656]={ + category="mn", + description="ARABIC SUBSCRIPT ALEF", + direction="nsm", + linebreak="cm", + unicodeslot=0x0656, + }, + [0x0657]={ + category="mn", + description="ARABIC INVERTED DAMMA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0657, + }, + [0x0658]={ + category="mn", + description="ARABIC MARK NOON GHUNNA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0658, + }, + [0x0659]={ + category="mn", + description="ARABIC ZWARAKAY", + direction="nsm", + linebreak="cm", + unicodeslot=0x0659, + }, + [0x065A]={ + category="mn", + description="ARABIC VOWEL SIGN SMALL V ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x065A, + }, + [0x065B]={ + category="mn", + description="ARABIC VOWEL SIGN INVERTED SMALL V ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x065B, + }, + [0x065C]={ + category="mn", + description="ARABIC VOWEL SIGN DOT BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x065C, + }, + [0x065D]={ + category="mn", + description="ARABIC REVERSED DAMMA", + direction="nsm", + linebreak="cm", + unicodeslot=0x065D, + }, + [0x065E]={ + category="mn", + description="ARABIC FATHA WITH TWO DOTS", + direction="nsm", + linebreak="cm", + unicodeslot=0x065E, + }, + [0x0660]={ + adobename="afii57392", + category="nd", + description="ARABIC-INDIC DIGIT ZERO", + direction="an", + linebreak="nu", + unicodeslot=0x0660, + }, + [0x0661]={ + adobename="afii57393", + category="nd", + description="ARABIC-INDIC DIGIT ONE", + direction="an", + linebreak="nu", + unicodeslot=0x0661, + }, + [0x0662]={ + adobename="afii57394", + category="nd", + description="ARABIC-INDIC DIGIT TWO", + direction="an", + linebreak="nu", + unicodeslot=0x0662, + }, + [0x0663]={ + adobename="afii57395", + category="nd", + description="ARABIC-INDIC DIGIT THREE", + direction="an", + linebreak="nu", + unicodeslot=0x0663, + }, + [0x0664]={ + adobename="afii57396", + category="nd", + description="ARABIC-INDIC DIGIT FOUR", + direction="an", + linebreak="nu", + unicodeslot=0x0664, + }, + [0x0665]={ + adobename="afii57397", + category="nd", + description="ARABIC-INDIC DIGIT FIVE", + direction="an", + linebreak="nu", + unicodeslot=0x0665, + }, + [0x0666]={ + adobename="afii57398", + category="nd", + description="ARABIC-INDIC DIGIT SIX", + direction="an", + linebreak="nu", + unicodeslot=0x0666, + }, + [0x0667]={ + adobename="afii57399", + category="nd", + description="ARABIC-INDIC DIGIT SEVEN", + direction="an", + linebreak="nu", + unicodeslot=0x0667, + }, + [0x0668]={ + adobename="afii57400", + category="nd", + description="ARABIC-INDIC DIGIT EIGHT", + direction="an", + linebreak="nu", + unicodeslot=0x0668, + }, + [0x0669]={ + adobename="afii57401", + category="nd", + description="ARABIC-INDIC DIGIT NINE", + direction="an", + linebreak="nu", + unicodeslot=0x0669, + }, + [0x066A]={ + adobename="afii57381", + category="po", + description="ARABIC PERCENT SIGN", + direction="et", + linebreak="ex", + unicodeslot=0x066A, + }, + [0x066B]={ + category="po", + description="ARABIC DECIMAL SEPARATOR", + direction="an", + linebreak="nu", + unicodeslot=0x066B, + }, + [0x066C]={ + category="po", + description="ARABIC THOUSANDS SEPARATOR", + direction="an", + linebreak="nu", + unicodeslot=0x066C, + }, + [0x066D]={ + adobename="afii63167", + category="po", + description="ARABIC FIVE POINTED STAR", + direction="al", + linebreak="al", + unicodeslot=0x066D, + }, + [0x066E]={ + category="lo", + description="ARABIC LETTER DOTLESS BEH", + direction="al", + linebreak="al", + unicodeslot=0x066E, + }, + [0x066F]={ + category="lo", + description="ARABIC LETTER DOTLESS QAF", + direction="al", + linebreak="al", + unicodeslot=0x066F, + }, + [0x0670]={ + category="mn", + description="ARABIC LETTER SUPERSCRIPT ALEF", + direction="nsm", + linebreak="cm", + unicodeslot=0x0670, + }, + [0x0671]={ + category="lo", + description="ARABIC LETTER ALEF WASLA", + direction="al", + linebreak="al", + unicodeslot=0x0671, + }, + [0x0672]={ + category="lo", + description="ARABIC LETTER ALEF WITH WAVY HAMZA ABOVE", + direction="al", + linebreak="al", + shcode=0x0627, + unicodeslot=0x0672, + }, + [0x0673]={ + category="lo", + description="ARABIC LETTER ALEF WITH WAVY HAMZA BELOW", + direction="al", + linebreak="al", + shcode=0x0627, + unicodeslot=0x0673, + }, + [0x0674]={ + category="lo", + description="ARABIC LETTER HIGH HAMZA", + direction="al", + linebreak="al", + unicodeslot=0x0674, + }, + [0x0675]={ + category="lo", + description="ARABIC LETTER HIGH HAMZA ALEF", + direction="al", + linebreak="al", + specials={ "compat", 0x0627, 0x0674 }, + unicodeslot=0x0675, + }, + [0x0676]={ + category="lo", + description="ARABIC LETTER HIGH HAMZA WAW", + direction="al", + linebreak="al", + specials={ "compat", 0x0648, 0x0674 }, + unicodeslot=0x0676, + }, + [0x0677]={ + category="lo", + description="ARABIC LETTER U WITH HAMZA ABOVE", + direction="al", + linebreak="al", + shcode=0x06C7, + specials={ "compat", 0x06C7, 0x0674 }, + unicodeslot=0x0677, + }, + [0x0678]={ + category="lo", + description="ARABIC LETTER HIGH HAMZA YEH", + direction="al", + linebreak="al", + specials={ "compat", 0x064A, 0x0674 }, + unicodeslot=0x0678, + }, + [0x0679]={ + adobename="afii57511", + category="lo", + description="ARABIC LETTER TTEH", + direction="al", + linebreak="al", + unicodeslot=0x0679, + }, + [0x067A]={ + category="lo", + description="ARABIC LETTER TTEHEH", + direction="al", + linebreak="al", + unicodeslot=0x067A, + }, + [0x067B]={ + category="lo", + description="ARABIC LETTER BEEH", + direction="al", + linebreak="al", + unicodeslot=0x067B, + }, + [0x067C]={ + category="lo", + description="ARABIC LETTER TEH WITH RING", + direction="al", + linebreak="al", + shcode=0x062A, + unicodeslot=0x067C, + }, + [0x067D]={ + category="lo", + description="ARABIC LETTER TEH WITH THREE DOTS ABOVE DOWNWARDS", + direction="al", + linebreak="al", + shcode=0x062A, + unicodeslot=0x067D, + }, + [0x067E]={ + adobename="afii57506", + category="lo", + description="ARABIC LETTER PEH", + direction="al", + linebreak="al", + unicodeslot=0x067E, + }, + [0x067F]={ + category="lo", + description="ARABIC LETTER TEHEH", + direction="al", + linebreak="al", + unicodeslot=0x067F, + }, + [0x0680]={ + category="lo", + description="ARABIC LETTER BEHEH", + direction="al", + linebreak="al", + unicodeslot=0x0680, + }, + [0x0681]={ + category="lo", + description="ARABIC LETTER HAH WITH HAMZA ABOVE", + direction="al", + linebreak="al", + shcode=0x062D, + unicodeslot=0x0681, + }, + [0x0682]={ + category="lo", + description="ARABIC LETTER HAH WITH TWO DOTS VERTICAL ABOVE", + direction="al", + linebreak="al", + shcode=0x062D, + unicodeslot=0x0682, + }, + [0x0683]={ + category="lo", + description="ARABIC LETTER NYEH", + direction="al", + linebreak="al", + unicodeslot=0x0683, + }, + [0x0684]={ + category="lo", + description="ARABIC LETTER DYEH", + direction="al", + linebreak="al", + unicodeslot=0x0684, + }, + [0x0685]={ + category="lo", + description="ARABIC LETTER HAH WITH THREE DOTS ABOVE", + direction="al", + linebreak="al", + shcode=0x062D, + unicodeslot=0x0685, + }, + [0x0686]={ + adobename="afii57507", + category="lo", + description="ARABIC LETTER TCHEH", + direction="al", + linebreak="al", + unicodeslot=0x0686, + }, + [0x0687]={ + category="lo", + description="ARABIC LETTER TCHEHEH", + direction="al", + linebreak="al", + unicodeslot=0x0687, + }, + [0x0688]={ + adobename="afii57512", + category="lo", + description="ARABIC LETTER DDAL", + direction="al", + linebreak="al", + unicodeslot=0x0688, + }, + [0x0689]={ + category="lo", + description="ARABIC LETTER DAL WITH RING", + direction="al", + linebreak="al", + shcode=0x062F, + unicodeslot=0x0689, + }, + [0x068A]={ + category="lo", + description="ARABIC LETTER DAL WITH DOT BELOW", + direction="al", + linebreak="al", + shcode=0x062F, + unicodeslot=0x068A, + }, + [0x068B]={ + category="lo", + description="ARABIC LETTER DAL WITH DOT BELOW AND SMALL TAH", + direction="al", + linebreak="al", + shcode=0x062F, + unicodeslot=0x068B, + }, + [0x068C]={ + category="lo", + description="ARABIC LETTER DAHAL", + direction="al", + linebreak="al", + unicodeslot=0x068C, + }, + [0x068D]={ + category="lo", + description="ARABIC LETTER DDAHAL", + direction="al", + linebreak="al", + unicodeslot=0x068D, + }, + [0x068E]={ + category="lo", + description="ARABIC LETTER DUL", + direction="al", + linebreak="al", + unicodeslot=0x068E, + }, + [0x068F]={ + category="lo", + description="ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARDS", + direction="al", + linebreak="al", + shcode=0x062F, + unicodeslot=0x068F, + }, + [0x0690]={ + category="lo", + description="ARABIC LETTER DAL WITH FOUR DOTS ABOVE", + direction="al", + linebreak="al", + shcode=0x062F, + unicodeslot=0x0690, + }, + [0x0691]={ + adobename="afii57513", + category="lo", + description="ARABIC LETTER RREH", + direction="al", + linebreak="al", + unicodeslot=0x0691, + }, + [0x0692]={ + category="lo", + description="ARABIC LETTER REH WITH SMALL V", + direction="al", + linebreak="al", + shcode=0x0631, + unicodeslot=0x0692, + }, + [0x0693]={ + category="lo", + description="ARABIC LETTER REH WITH RING", + direction="al", + linebreak="al", + shcode=0x0631, + unicodeslot=0x0693, + }, + [0x0694]={ + category="lo", + description="ARABIC LETTER REH WITH DOT BELOW", + direction="al", + linebreak="al", + shcode=0x0631, + unicodeslot=0x0694, + }, + [0x0695]={ + category="lo", + description="ARABIC LETTER REH WITH SMALL V BELOW", + direction="al", + linebreak="al", + shcode=0x0631, + unicodeslot=0x0695, + }, + [0x0696]={ + category="lo", + description="ARABIC LETTER REH WITH DOT BELOW AND DOT ABOVE", + direction="al", + linebreak="al", + shcode=0x0631, + unicodeslot=0x0696, + }, + [0x0697]={ + category="lo", + description="ARABIC LETTER REH WITH TWO DOTS ABOVE", + direction="al", + linebreak="al", + shcode=0x0631, + unicodeslot=0x0697, + }, + [0x0698]={ + adobename="afii57508", + category="lo", + description="ARABIC LETTER JEH", + direction="al", + linebreak="al", + unicodeslot=0x0698, + }, + [0x0699]={ + category="lo", + description="ARABIC LETTER REH WITH FOUR DOTS ABOVE", + direction="al", + linebreak="al", + shcode=0x0631, + unicodeslot=0x0699, + }, + [0x069A]={ + category="lo", + description="ARABIC LETTER SEEN WITH DOT BELOW AND DOT ABOVE", + direction="al", + linebreak="al", + shcode=0x0633, + unicodeslot=0x069A, + }, + [0x069B]={ + category="lo", + description="ARABIC LETTER SEEN WITH THREE DOTS BELOW", + direction="al", + linebreak="al", + shcode=0x0633, + unicodeslot=0x069B, + }, + [0x069C]={ + category="lo", + description="ARABIC LETTER SEEN WITH THREE DOTS BELOW AND THREE DOTS ABOVE", + direction="al", + linebreak="al", + shcode=0x0633, + unicodeslot=0x069C, + }, + [0x069D]={ + category="lo", + description="ARABIC LETTER SAD WITH TWO DOTS BELOW", + direction="al", + linebreak="al", + shcode=0x0635, + unicodeslot=0x069D, + }, + [0x069E]={ + category="lo", + description="ARABIC LETTER SAD WITH THREE DOTS ABOVE", + direction="al", + linebreak="al", + shcode=0x0635, + unicodeslot=0x069E, + }, + [0x069F]={ + category="lo", + description="ARABIC LETTER TAH WITH THREE DOTS ABOVE", + direction="al", + linebreak="al", + shcode=0x0637, + unicodeslot=0x069F, + }, + [0x06A0]={ + category="lo", + description="ARABIC LETTER AIN WITH THREE DOTS ABOVE", + direction="al", + linebreak="al", + shcode=0x0639, + unicodeslot=0x06A0, + }, + [0x06A1]={ + category="lo", + description="ARABIC LETTER DOTLESS FEH", + direction="al", + linebreak="al", + unicodeslot=0x06A1, + }, + [0x06A2]={ + category="lo", + description="ARABIC LETTER FEH WITH DOT MOVED BELOW", + direction="al", + linebreak="al", + shcode=0x0641, + unicodeslot=0x06A2, + }, + [0x06A3]={ + category="lo", + description="ARABIC LETTER FEH WITH DOT BELOW", + direction="al", + linebreak="al", + shcode=0x0641, + unicodeslot=0x06A3, + }, + [0x06A4]={ + adobename="afii57505", + category="lo", + description="ARABIC LETTER VEH", + direction="al", + linebreak="al", + unicodeslot=0x06A4, + }, + [0x06A5]={ + category="lo", + description="ARABIC LETTER FEH WITH THREE DOTS BELOW", + direction="al", + linebreak="al", + shcode=0x0641, + unicodeslot=0x06A5, + }, + [0x06A6]={ + category="lo", + description="ARABIC LETTER PEHEH", + direction="al", + linebreak="al", + unicodeslot=0x06A6, + }, + [0x06A7]={ + category="lo", + description="ARABIC LETTER QAF WITH DOT ABOVE", + direction="al", + linebreak="al", + shcode=0x0642, + unicodeslot=0x06A7, + }, + [0x06A8]={ + category="lo", + description="ARABIC LETTER QAF WITH THREE DOTS ABOVE", + direction="al", + linebreak="al", + shcode=0x0642, + unicodeslot=0x06A8, + }, + [0x06A9]={ + category="lo", + description="ARABIC LETTER KEHEH", + direction="al", + linebreak="al", + unicodeslot=0x06A9, + }, + [0x06AA]={ + category="lo", + description="ARABIC LETTER SWASH KAF", + direction="al", + linebreak="al", + unicodeslot=0x06AA, + }, + [0x06AB]={ + category="lo", + description="ARABIC LETTER KAF WITH RING", + direction="al", + linebreak="al", + shcode=0x0643, + unicodeslot=0x06AB, + }, + [0x06AC]={ + category="lo", + description="ARABIC LETTER KAF WITH DOT ABOVE", + direction="al", + linebreak="al", + shcode=0x0643, + unicodeslot=0x06AC, + }, + [0x06AD]={ + category="lo", + description="ARABIC LETTER NG", + direction="al", + linebreak="al", + unicodeslot=0x06AD, + }, + [0x06AE]={ + category="lo", + description="ARABIC LETTER KAF WITH THREE DOTS BELOW", + direction="al", + linebreak="al", + shcode=0x0643, + unicodeslot=0x06AE, + }, + [0x06AF]={ + adobename="afii57509", + category="lo", + description="ARABIC LETTER GAF", + direction="al", + linebreak="al", + unicodeslot=0x06AF, + }, + [0x06B0]={ + category="lo", + description="ARABIC LETTER GAF WITH RING", + direction="al", + linebreak="al", + shcode=0x06AF, + unicodeslot=0x06B0, + }, + [0x06B1]={ + category="lo", + description="ARABIC LETTER NGOEH", + direction="al", + linebreak="al", + unicodeslot=0x06B1, + }, + [0x06B2]={ + category="lo", + description="ARABIC LETTER GAF WITH TWO DOTS BELOW", + direction="al", + linebreak="al", + shcode=0x06AF, + unicodeslot=0x06B2, + }, + [0x06B3]={ + category="lo", + description="ARABIC LETTER GUEH", + direction="al", + linebreak="al", + unicodeslot=0x06B3, + }, + [0x06B4]={ + category="lo", + description="ARABIC LETTER GAF WITH THREE DOTS ABOVE", + direction="al", + linebreak="al", + shcode=0x06AF, + unicodeslot=0x06B4, + }, + [0x06B5]={ + category="lo", + description="ARABIC LETTER LAM WITH SMALL V", + direction="al", + linebreak="al", + shcode=0x0644, + unicodeslot=0x06B5, + }, + [0x06B6]={ + category="lo", + description="ARABIC LETTER LAM WITH DOT ABOVE", + direction="al", + linebreak="al", + shcode=0x0644, + unicodeslot=0x06B6, + }, + [0x06B7]={ + category="lo", + description="ARABIC LETTER LAM WITH THREE DOTS ABOVE", + direction="al", + linebreak="al", + shcode=0x0644, + unicodeslot=0x06B7, + }, + [0x06B8]={ + category="lo", + description="ARABIC LETTER LAM WITH THREE DOTS BELOW", + direction="al", + linebreak="al", + shcode=0x0644, + unicodeslot=0x06B8, + }, + [0x06B9]={ + category="lo", + description="ARABIC LETTER NOON WITH DOT BELOW", + direction="al", + linebreak="al", + shcode=0x0646, + unicodeslot=0x06B9, + }, + [0x06BA]={ + adobename="afii57514", + category="lo", + description="ARABIC LETTER NOON GHUNNA", + direction="al", + linebreak="al", + unicodeslot=0x06BA, + }, + [0x06BB]={ + category="lo", + description="ARABIC LETTER RNOON", + direction="al", + linebreak="al", + unicodeslot=0x06BB, + }, + [0x06BC]={ + category="lo", + description="ARABIC LETTER NOON WITH RING", + direction="al", + linebreak="al", + shcode=0x0646, + unicodeslot=0x06BC, + }, + [0x06BD]={ + category="lo", + description="ARABIC LETTER NOON WITH THREE DOTS ABOVE", + direction="al", + linebreak="al", + shcode=0x0646, + unicodeslot=0x06BD, + }, + [0x06BE]={ + category="lo", + description="ARABIC LETTER HEH DOACHASHMEE", + direction="al", + linebreak="al", + unicodeslot=0x06BE, + }, + [0x06BF]={ + category="lo", + description="ARABIC LETTER TCHEH WITH DOT ABOVE", + direction="al", + linebreak="al", + shcode=0x0686, + unicodeslot=0x06BF, + }, + [0x06C0]={ + category="lo", + description="ARABIC LETTER HEH WITH YEH ABOVE", + direction="al", + linebreak="al", + shcode=0x0647, + specials={ "char", 0x06D5, 0x0654 }, + unicodeslot=0x06C0, + }, + [0x06C1]={ + category="lo", + description="ARABIC LETTER HEH GOAL", + direction="al", + linebreak="al", + unicodeslot=0x06C1, + }, + [0x06C2]={ + category="lo", + description="ARABIC LETTER HEH GOAL WITH HAMZA ABOVE", + direction="al", + linebreak="al", + specials={ "char", 0x06C1, 0x0654 }, + unicodeslot=0x06C2, + }, + [0x06C3]={ + category="lo", + description="ARABIC LETTER TEH MARBUTA GOAL", + direction="al", + linebreak="al", + unicodeslot=0x06C3, + }, + [0x06C4]={ + category="lo", + description="ARABIC LETTER WAW WITH RING", + direction="al", + linebreak="al", + shcode=0x0648, + unicodeslot=0x06C4, + }, + [0x06C5]={ + category="lo", + description="ARABIC LETTER KIRGHIZ OE", + direction="al", + linebreak="al", + unicodeslot=0x06C5, + }, + [0x06C6]={ + category="lo", + description="ARABIC LETTER OE", + direction="al", + linebreak="al", + unicodeslot=0x06C6, + }, + [0x06C7]={ + category="lo", + description="ARABIC LETTER U", + direction="al", + linebreak="al", + unicodeslot=0x06C7, + }, + [0x06C8]={ + category="lo", + description="ARABIC LETTER YU", + direction="al", + linebreak="al", + unicodeslot=0x06C8, + }, + [0x06C9]={ + category="lo", + description="ARABIC LETTER KIRGHIZ YU", + direction="al", + linebreak="al", + unicodeslot=0x06C9, + }, + [0x06CA]={ + category="lo", + description="ARABIC LETTER WAW WITH TWO DOTS ABOVE", + direction="al", + linebreak="al", + shcode=0x0648, + unicodeslot=0x06CA, + }, + [0x06CB]={ + category="lo", + description="ARABIC LETTER VE", + direction="al", + linebreak="al", + unicodeslot=0x06CB, + }, + [0x06CC]={ + category="lo", + description="ARABIC LETTER FARSI YEH", + direction="al", + linebreak="al", + unicodeslot=0x06CC, + }, + [0x06CD]={ + category="lo", + description="ARABIC LETTER YEH WITH TAIL", + direction="al", + linebreak="al", + shcode=0x064A, + unicodeslot=0x06CD, + }, + [0x06CE]={ + category="lo", + description="ARABIC LETTER YEH WITH SMALL V", + direction="al", + linebreak="al", + shcode=0x064A, + unicodeslot=0x06CE, + }, + [0x06CF]={ + category="lo", + description="ARABIC LETTER WAW WITH DOT ABOVE", + direction="al", + linebreak="al", + shcode=0x0648, + unicodeslot=0x06CF, + }, + [0x06D0]={ + category="lo", + description="ARABIC LETTER E", + direction="al", + linebreak="al", + unicodeslot=0x06D0, + }, + [0x06D1]={ + category="lo", + description="ARABIC LETTER YEH WITH THREE DOTS BELOW", + direction="al", + linebreak="al", + shcode=0x064A, + unicodeslot=0x06D1, + }, + [0x06D2]={ + adobename="afii57519", + category="lo", + description="ARABIC LETTER YEH BARREE", + direction="al", + linebreak="al", + unicodeslot=0x06D2, + }, + [0x06D3]={ + category="lo", + description="ARABIC LETTER YEH BARREE WITH HAMZA ABOVE", + direction="al", + linebreak="al", + specials={ "char", 0x06D2, 0x0654 }, + unicodeslot=0x06D3, + }, + [0x06D4]={ + category="po", + description="ARABIC FULL STOP", + direction="al", + linebreak="ex", + unicodeslot=0x06D4, + }, + [0x06D5]={ + adobename="afii57534", + category="lo", + description="ARABIC LETTER AE", + direction="al", + linebreak="al", + unicodeslot=0x06D5, + }, + [0x06D6]={ + category="mn", + description="ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA", + direction="nsm", + linebreak="cm", + unicodeslot=0x06D6, + }, + [0x06D7]={ + category="mn", + description="ARABIC SMALL HIGH LIGATURE QAF WITH LAM WITH ALEF MAKSURA", + direction="nsm", + linebreak="cm", + unicodeslot=0x06D7, + }, + [0x06D8]={ + category="mn", + description="ARABIC SMALL HIGH MEEM INITIAL FORM", + direction="nsm", + linebreak="cm", + unicodeslot=0x06D8, + }, + [0x06D9]={ + category="mn", + description="ARABIC SMALL HIGH LAM ALEF", + direction="nsm", + linebreak="cm", + unicodeslot=0x06D9, + }, + [0x06DA]={ + category="mn", + description="ARABIC SMALL HIGH JEEM", + direction="nsm", + linebreak="cm", + unicodeslot=0x06DA, + }, + [0x06DB]={ + category="mn", + description="ARABIC SMALL HIGH THREE DOTS", + direction="nsm", + linebreak="cm", + unicodeslot=0x06DB, + }, + [0x06DC]={ + category="mn", + description="ARABIC SMALL HIGH SEEN", + direction="nsm", + linebreak="cm", + unicodeslot=0x06DC, + }, + [0x06DD]={ + category="cf", + description="ARABIC END OF AYAH", + direction="an", + visible="yes", + linebreak="al", + unicodeslot=0x06DD, + }, + [0x06DE]={ + category="me", + description="ARABIC START OF RUB EL HIZB", + direction="nsm", + linebreak="cm", + unicodeslot=0x06DE, + }, + [0x06DF]={ + category="mn", + description="ARABIC SMALL HIGH ROUNDED ZERO", + direction="nsm", + linebreak="cm", + unicodeslot=0x06DF, + }, + [0x06E0]={ + category="mn", + description="ARABIC SMALL HIGH UPRIGHT RECTANGULAR ZERO", + direction="nsm", + linebreak="cm", + unicodeslot=0x06E0, + }, + [0x06E1]={ + category="mn", + description="ARABIC SMALL HIGH DOTLESS HEAD OF KHAH", + direction="nsm", + linebreak="cm", + unicodeslot=0x06E1, + }, + [0x06E2]={ + category="mn", + description="ARABIC SMALL HIGH MEEM ISOLATED FORM", + direction="nsm", + linebreak="cm", + unicodeslot=0x06E2, + }, + [0x06E3]={ + category="mn", + description="ARABIC SMALL LOW SEEN", + direction="nsm", + linebreak="cm", + unicodeslot=0x06E3, + }, + [0x06E4]={ + category="mn", + description="ARABIC SMALL HIGH MADDA", + direction="nsm", + linebreak="cm", + unicodeslot=0x06E4, + }, + [0x06E5]={ + category="lm", + description="ARABIC SMALL WAW", + direction="al", + linebreak="al", + unicodeslot=0x06E5, + }, + [0x06E6]={ + category="lm", + description="ARABIC SMALL YEH", + direction="al", + linebreak="al", + unicodeslot=0x06E6, + }, + [0x06E7]={ + category="mn", + description="ARABIC SMALL HIGH YEH", + direction="nsm", + linebreak="cm", + unicodeslot=0x06E7, + }, + [0x06E8]={ + category="mn", + description="ARABIC SMALL HIGH NOON", + direction="nsm", + linebreak="cm", + unicodeslot=0x06E8, + }, + [0x06E9]={ + category="so", + description="ARABIC PLACE OF SAJDAH", + direction="on", + linebreak="al", + unicodeslot=0x06E9, + }, + [0x06EA]={ + category="mn", + description="ARABIC EMPTY CENTRE LOW STOP", + direction="nsm", + linebreak="cm", + unicodeslot=0x06EA, + }, + [0x06EB]={ + category="mn", + description="ARABIC EMPTY CENTRE HIGH STOP", + direction="nsm", + linebreak="cm", + unicodeslot=0x06EB, + }, + [0x06EC]={ + category="mn", + description="ARABIC ROUNDED HIGH STOP WITH FILLED CENTRE", + direction="nsm", + linebreak="cm", + unicodeslot=0x06EC, + }, + [0x06ED]={ + category="mn", + description="ARABIC SMALL LOW MEEM", + direction="nsm", + linebreak="cm", + unicodeslot=0x06ED, + }, + [0x06EE]={ + category="lo", + description="ARABIC LETTER DAL WITH INVERTED V", + direction="al", + linebreak="al", + shcode=0x062F, + unicodeslot=0x06EE, + }, + [0x06EF]={ + category="lo", + description="ARABIC LETTER REH WITH INVERTED V", + direction="al", + linebreak="al", + shcode=0x0631, + unicodeslot=0x06EF, + }, + [0x06F0]={ + category="nd", + description="EXTENDED ARABIC-INDIC DIGIT ZERO", + direction="en", + linebreak="nu", + unicodeslot=0x06F0, + }, + [0x06F1]={ + category="nd", + description="EXTENDED ARABIC-INDIC DIGIT ONE", + direction="en", + linebreak="nu", + unicodeslot=0x06F1, + }, + [0x06F2]={ + category="nd", + description="EXTENDED ARABIC-INDIC DIGIT TWO", + direction="en", + linebreak="nu", + unicodeslot=0x06F2, + }, + [0x06F3]={ + category="nd", + description="EXTENDED ARABIC-INDIC DIGIT THREE", + direction="en", + linebreak="nu", + unicodeslot=0x06F3, + }, + [0x06F4]={ + category="nd", + description="EXTENDED ARABIC-INDIC DIGIT FOUR", + direction="en", + linebreak="nu", + unicodeslot=0x06F4, + }, + [0x06F5]={ + category="nd", + description="EXTENDED ARABIC-INDIC DIGIT FIVE", + direction="en", + linebreak="nu", + unicodeslot=0x06F5, + }, + [0x06F6]={ + category="nd", + description="EXTENDED ARABIC-INDIC DIGIT SIX", + direction="en", + linebreak="nu", + unicodeslot=0x06F6, + }, + [0x06F7]={ + category="nd", + description="EXTENDED ARABIC-INDIC DIGIT SEVEN", + direction="en", + linebreak="nu", + unicodeslot=0x06F7, + }, + [0x06F8]={ + category="nd", + description="EXTENDED ARABIC-INDIC DIGIT EIGHT", + direction="en", + linebreak="nu", + unicodeslot=0x06F8, + }, + [0x06F9]={ + category="nd", + description="EXTENDED ARABIC-INDIC DIGIT NINE", + direction="en", + linebreak="nu", + unicodeslot=0x06F9, + }, + [0x06FA]={ + category="lo", + description="ARABIC LETTER SHEEN WITH DOT BELOW", + direction="al", + linebreak="al", + shcode=0x0634, + unicodeslot=0x06FA, + }, + [0x06FB]={ + category="lo", + description="ARABIC LETTER DAD WITH DOT BELOW", + direction="al", + linebreak="al", + shcode=0x0636, + unicodeslot=0x06FB, + }, + [0x06FC]={ + category="lo", + description="ARABIC LETTER GHAIN WITH DOT BELOW", + direction="al", + linebreak="al", + shcode=0x063A, + unicodeslot=0x06FC, + }, + [0x06FD]={ + category="so", + description="ARABIC SIGN SINDHI AMPERSAND", + direction="al", + linebreak="al", + unicodeslot=0x06FD, + }, + [0x06FE]={ + category="so", + description="ARABIC SIGN SINDHI POSTPOSITION MEN", + direction="al", + linebreak="al", + unicodeslot=0x06FE, + }, + [0x06FF]={ + category="lo", + description="ARABIC LETTER HEH WITH INVERTED V", + direction="al", + linebreak="al", + shcode=0x0647, + unicodeslot=0x06FF, + }, + [0x0700]={ + category="po", + description="SYRIAC END OF PARAGRAPH", + direction="al", + linebreak="al", + unicodeslot=0x0700, + }, + [0x0701]={ + category="po", + description="SYRIAC SUPRALINEAR FULL STOP", + direction="al", + linebreak="al", + unicodeslot=0x0701, + }, + [0x0702]={ + category="po", + description="SYRIAC SUBLINEAR FULL STOP", + direction="al", + linebreak="al", + unicodeslot=0x0702, + }, + [0x0703]={ + category="po", + description="SYRIAC SUPRALINEAR COLON", + direction="al", + linebreak="al", + unicodeslot=0x0703, + }, + [0x0704]={ + category="po", + description="SYRIAC SUBLINEAR COLON", + direction="al", + linebreak="al", + unicodeslot=0x0704, + }, + [0x0705]={ + category="po", + description="SYRIAC HORIZONTAL COLON", + direction="al", + linebreak="al", + unicodeslot=0x0705, + }, + [0x0706]={ + category="po", + description="SYRIAC COLON SKEWED LEFT", + direction="al", + linebreak="al", + unicodeslot=0x0706, + }, + [0x0707]={ + category="po", + description="SYRIAC COLON SKEWED RIGHT", + direction="al", + linebreak="al", + unicodeslot=0x0707, + }, + [0x0708]={ + category="po", + description="SYRIAC SUPRALINEAR COLON SKEWED LEFT", + direction="al", + linebreak="al", + unicodeslot=0x0708, + }, + [0x0709]={ + category="po", + description="SYRIAC SUBLINEAR COLON SKEWED RIGHT", + direction="al", + linebreak="al", + unicodeslot=0x0709, + }, + [0x070A]={ + category="po", + description="SYRIAC CONTRACTION", + direction="al", + linebreak="al", + unicodeslot=0x070A, + }, + [0x070B]={ + category="po", + description="SYRIAC HARKLEAN OBELUS", + direction="al", + linebreak="al", + unicodeslot=0x070B, + }, + [0x070C]={ + category="po", + description="SYRIAC HARKLEAN METOBELUS", + direction="al", + linebreak="al", + unicodeslot=0x070C, + }, + [0x070D]={ + category="po", + description="SYRIAC HARKLEAN ASTERISCUS", + direction="al", + linebreak="al", + unicodeslot=0x070D, + }, + [0x070F]={ + category="cf", + description="SYRIAC ABBREVIATION MARK", + direction="bn", + visible="yes", + linebreak="al", + unicodeslot=0x070F, + }, + [0x0710]={ + category="lo", + description="SYRIAC LETTER ALAPH", + direction="al", + linebreak="al", + unicodeslot=0x0710, + }, + [0x0711]={ + category="mn", + description="SYRIAC LETTER SUPERSCRIPT ALAPH", + direction="nsm", + linebreak="cm", + unicodeslot=0x0711, + }, + [0x0712]={ + category="lo", + description="SYRIAC LETTER BETH", + direction="al", + linebreak="al", + unicodeslot=0x0712, + }, + [0x0713]={ + category="lo", + description="SYRIAC LETTER GAMAL", + direction="al", + linebreak="al", + unicodeslot=0x0713, + }, + [0x0714]={ + category="lo", + description="SYRIAC LETTER GAMAL GARSHUNI", + direction="al", + linebreak="al", + unicodeslot=0x0714, + }, + [0x0715]={ + category="lo", + description="SYRIAC LETTER DALATH", + direction="al", + linebreak="al", + unicodeslot=0x0715, + }, + [0x0716]={ + category="lo", + description="SYRIAC LETTER DOTLESS DALATH RISH", + direction="al", + linebreak="al", + unicodeslot=0x0716, + }, + [0x0717]={ + category="lo", + description="SYRIAC LETTER HE", + direction="al", + linebreak="al", + unicodeslot=0x0717, + }, + [0x0718]={ + category="lo", + description="SYRIAC LETTER WAW", + direction="al", + linebreak="al", + unicodeslot=0x0718, + }, + [0x0719]={ + category="lo", + description="SYRIAC LETTER ZAIN", + direction="al", + linebreak="al", + unicodeslot=0x0719, + }, + [0x071A]={ + category="lo", + description="SYRIAC LETTER HETH", + direction="al", + linebreak="al", + unicodeslot=0x071A, + }, + [0x071B]={ + category="lo", + description="SYRIAC LETTER TETH", + direction="al", + linebreak="al", + unicodeslot=0x071B, + }, + [0x071C]={ + category="lo", + description="SYRIAC LETTER TETH GARSHUNI", + direction="al", + linebreak="al", + unicodeslot=0x071C, + }, + [0x071D]={ + category="lo", + description="SYRIAC LETTER YUDH", + direction="al", + linebreak="al", + unicodeslot=0x071D, + }, + [0x071E]={ + category="lo", + description="SYRIAC LETTER YUDH HE", + direction="al", + linebreak="al", + unicodeslot=0x071E, + }, + [0x071F]={ + category="lo", + description="SYRIAC LETTER KAPH", + direction="al", + linebreak="al", + unicodeslot=0x071F, + }, + [0x0720]={ + category="lo", + description="SYRIAC LETTER LAMADH", + direction="al", + linebreak="al", + unicodeslot=0x0720, + }, + [0x0721]={ + category="lo", + description="SYRIAC LETTER MIM", + direction="al", + linebreak="al", + unicodeslot=0x0721, + }, + [0x0722]={ + category="lo", + description="SYRIAC LETTER NUN", + direction="al", + linebreak="al", + unicodeslot=0x0722, + }, + [0x0723]={ + category="lo", + description="SYRIAC LETTER SEMKATH", + direction="al", + linebreak="al", + unicodeslot=0x0723, + }, + [0x0724]={ + category="lo", + description="SYRIAC LETTER FINAL SEMKATH", + direction="al", + linebreak="al", + unicodeslot=0x0724, + }, + [0x0725]={ + category="lo", + description="SYRIAC LETTER E", + direction="al", + linebreak="al", + unicodeslot=0x0725, + }, + [0x0726]={ + category="lo", + description="SYRIAC LETTER PE", + direction="al", + linebreak="al", + unicodeslot=0x0726, + }, + [0x0727]={ + category="lo", + description="SYRIAC LETTER REVERSED PE", + direction="al", + linebreak="al", + unicodeslot=0x0727, + }, + [0x0728]={ + category="lo", + description="SYRIAC LETTER SADHE", + direction="al", + linebreak="al", + unicodeslot=0x0728, + }, + [0x0729]={ + category="lo", + description="SYRIAC LETTER QAPH", + direction="al", + linebreak="al", + unicodeslot=0x0729, + }, + [0x072A]={ + category="lo", + description="SYRIAC LETTER RISH", + direction="al", + linebreak="al", + unicodeslot=0x072A, + }, + [0x072B]={ + category="lo", + description="SYRIAC LETTER SHIN", + direction="al", + linebreak="al", + unicodeslot=0x072B, + }, + [0x072C]={ + category="lo", + description="SYRIAC LETTER TAW", + direction="al", + linebreak="al", + unicodeslot=0x072C, + }, + [0x072D]={ + category="lo", + description="SYRIAC LETTER PERSIAN BHETH", + direction="al", + linebreak="al", + unicodeslot=0x072D, + }, + [0x072E]={ + category="lo", + description="SYRIAC LETTER PERSIAN GHAMAL", + direction="al", + linebreak="al", + unicodeslot=0x072E, + }, + [0x072F]={ + category="lo", + description="SYRIAC LETTER PERSIAN DHALATH", + direction="al", + linebreak="al", + unicodeslot=0x072F, + }, + [0x0730]={ + category="mn", + description="SYRIAC PTHAHA ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0730, + }, + [0x0731]={ + category="mn", + description="SYRIAC PTHAHA BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0731, + }, + [0x0732]={ + category="mn", + description="SYRIAC PTHAHA DOTTED", + direction="nsm", + linebreak="cm", + unicodeslot=0x0732, + }, + [0x0733]={ + category="mn", + description="SYRIAC ZQAPHA ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0733, + }, + [0x0734]={ + category="mn", + description="SYRIAC ZQAPHA BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0734, + }, + [0x0735]={ + category="mn", + description="SYRIAC ZQAPHA DOTTED", + direction="nsm", + linebreak="cm", + unicodeslot=0x0735, + }, + [0x0736]={ + category="mn", + description="SYRIAC RBASA ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0736, + }, + [0x0737]={ + category="mn", + description="SYRIAC RBASA BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0737, + }, + [0x0738]={ + category="mn", + description="SYRIAC DOTTED ZLAMA HORIZONTAL", + direction="nsm", + linebreak="cm", + unicodeslot=0x0738, + }, + [0x0739]={ + category="mn", + description="SYRIAC DOTTED ZLAMA ANGULAR", + direction="nsm", + linebreak="cm", + unicodeslot=0x0739, + }, + [0x073A]={ + category="mn", + description="SYRIAC HBASA ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x073A, + }, + [0x073B]={ + category="mn", + description="SYRIAC HBASA BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x073B, + }, + [0x073C]={ + category="mn", + description="SYRIAC HBASA-ESASA DOTTED", + direction="nsm", + linebreak="cm", + unicodeslot=0x073C, + }, + [0x073D]={ + category="mn", + description="SYRIAC ESASA ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x073D, + }, + [0x073E]={ + category="mn", + description="SYRIAC ESASA BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x073E, + }, + [0x073F]={ + category="mn", + description="SYRIAC RWAHA", + direction="nsm", + linebreak="cm", + unicodeslot=0x073F, + }, + [0x0740]={ + category="mn", + description="SYRIAC FEMININE DOT", + direction="nsm", + linebreak="cm", + unicodeslot=0x0740, + }, + [0x0741]={ + category="mn", + description="SYRIAC QUSHSHAYA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0741, + }, + [0x0742]={ + category="mn", + description="SYRIAC RUKKAKHA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0742, + }, + [0x0743]={ + category="mn", + description="SYRIAC TWO VERTICAL DOTS ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0743, + }, + [0x0744]={ + category="mn", + description="SYRIAC TWO VERTICAL DOTS BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0744, + }, + [0x0745]={ + category="mn", + description="SYRIAC THREE DOTS ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0745, + }, + [0x0746]={ + category="mn", + description="SYRIAC THREE DOTS BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0746, + }, + [0x0747]={ + category="mn", + description="SYRIAC OBLIQUE LINE ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0747, + }, + [0x0748]={ + category="mn", + description="SYRIAC OBLIQUE LINE BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x0748, + }, + [0x0749]={ + category="mn", + description="SYRIAC MUSIC", + direction="nsm", + linebreak="cm", + unicodeslot=0x0749, + }, + [0x074A]={ + category="mn", + description="SYRIAC BARREKH", + direction="nsm", + linebreak="cm", + unicodeslot=0x074A, + }, + [0x074D]={ + category="lo", + description="SYRIAC LETTER SOGDIAN ZHAIN", + direction="al", + linebreak="al", + unicodeslot=0x074D, + }, + [0x074E]={ + category="lo", + description="SYRIAC LETTER SOGDIAN KHAPH", + direction="al", + linebreak="al", + unicodeslot=0x074E, + }, + [0x074F]={ + category="lo", + description="SYRIAC LETTER SOGDIAN FE", + direction="al", + linebreak="al", + unicodeslot=0x074F, + }, + [0x0750]={ + category="lo", + description="ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW", + direction="al", + linebreak="al", + shcode=0x0628, + unicodeslot=0x0750, + }, + [0x0751]={ + category="lo", + description="ARABIC LETTER BEH WITH DOT BELOW AND THREE DOTS ABOVE", + direction="al", + linebreak="al", + shcode=0x0628, + unicodeslot=0x0751, + }, + [0x0752]={ + category="lo", + description="ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW", + direction="al", + linebreak="al", + shcode=0x0628, + unicodeslot=0x0752, + }, + [0x0753]={ + category="lo", + description="ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW AND TWO DOTS ABOVE", + direction="al", + linebreak="al", + shcode=0x0628, + unicodeslot=0x0753, + }, + [0x0754]={ + category="lo", + description="ARABIC LETTER BEH WITH TWO DOTS BELOW AND DOT ABOVE", + direction="al", + linebreak="al", + shcode=0x0628, + unicodeslot=0x0754, + }, + [0x0755]={ + category="lo", + description="ARABIC LETTER BEH WITH INVERTED SMALL V BELOW", + direction="al", + linebreak="al", + shcode=0x0628, + unicodeslot=0x0755, + }, + [0x0756]={ + category="lo", + description="ARABIC LETTER BEH WITH SMALL V", + direction="al", + linebreak="al", + shcode=0x0628, + unicodeslot=0x0756, + }, + [0x0757]={ + category="lo", + description="ARABIC LETTER HAH WITH TWO DOTS ABOVE", + direction="al", + linebreak="al", + shcode=0x062D, + unicodeslot=0x0757, + }, + [0x0758]={ + category="lo", + description="ARABIC LETTER HAH WITH THREE DOTS POINTING UPWARDS BELOW", + direction="al", + linebreak="al", + shcode=0x062D, + unicodeslot=0x0758, + }, + [0x0759]={ + category="lo", + description="ARABIC LETTER DAL WITH TWO DOTS VERTICALLY BELOW AND SMALL TAH", + direction="al", + linebreak="al", + shcode=0x062F, + unicodeslot=0x0759, + }, + [0x075A]={ + category="lo", + description="ARABIC LETTER DAL WITH INVERTED SMALL V BELOW", + direction="al", + linebreak="al", + shcode=0x062F, + unicodeslot=0x075A, + }, + [0x075B]={ + category="lo", + description="ARABIC LETTER REH WITH STROKE", + direction="al", + linebreak="al", + shcode=0x0631, + unicodeslot=0x075B, + }, + [0x075C]={ + category="lo", + description="ARABIC LETTER SEEN WITH FOUR DOTS ABOVE", + direction="al", + linebreak="al", + shcode=0x0633, + unicodeslot=0x075C, + }, + [0x075D]={ + category="lo", + description="ARABIC LETTER AIN WITH TWO DOTS ABOVE", + direction="al", + linebreak="al", + shcode=0x0639, + unicodeslot=0x075D, + }, + [0x075E]={ + category="lo", + description="ARABIC LETTER AIN WITH THREE DOTS POINTING DOWNWARDS ABOVE", + direction="al", + linebreak="al", + shcode=0x0639, + unicodeslot=0x075E, + }, + [0x075F]={ + category="lo", + description="ARABIC LETTER AIN WITH TWO DOTS VERTICALLY ABOVE", + direction="al", + linebreak="al", + shcode=0x0639, + unicodeslot=0x075F, + }, + [0x0760]={ + category="lo", + description="ARABIC LETTER FEH WITH TWO DOTS BELOW", + direction="al", + linebreak="al", + shcode=0x0641, + unicodeslot=0x0760, + }, + [0x0761]={ + category="lo", + description="ARABIC LETTER FEH WITH THREE DOTS POINTING UPWARDS BELOW", + direction="al", + linebreak="al", + shcode=0x0641, + unicodeslot=0x0761, + }, + [0x0762]={ + category="lo", + description="ARABIC LETTER KEHEH WITH DOT ABOVE", + direction="al", + linebreak="al", + shcode=0x06A9, + unicodeslot=0x0762, + }, + [0x0763]={ + category="lo", + description="ARABIC LETTER KEHEH WITH THREE DOTS ABOVE", + direction="al", + linebreak="al", + shcode=0x06A9, + unicodeslot=0x0763, + }, + [0x0764]={ + category="lo", + description="ARABIC LETTER KEHEH WITH THREE DOTS POINTING UPWARDS BELOW", + direction="al", + linebreak="al", + shcode=0x06A9, + unicodeslot=0x0764, + }, + [0x0765]={ + category="lo", + description="ARABIC LETTER MEEM WITH DOT ABOVE", + direction="al", + linebreak="al", + shcode=0x0645, + unicodeslot=0x0765, + }, + [0x0766]={ + category="lo", + description="ARABIC LETTER MEEM WITH DOT BELOW", + direction="al", + linebreak="al", + shcode=0x0645, + unicodeslot=0x0766, + }, + [0x0767]={ + category="lo", + description="ARABIC LETTER NOON WITH TWO DOTS BELOW", + direction="al", + linebreak="al", + shcode=0x0646, + unicodeslot=0x0767, + }, + [0x0768]={ + category="lo", + description="ARABIC LETTER NOON WITH SMALL TAH", + direction="al", + linebreak="al", + shcode=0x0646, + unicodeslot=0x0768, + }, + [0x0769]={ + category="lo", + description="ARABIC LETTER NOON WITH SMALL V", + direction="al", + linebreak="al", + shcode=0x0646, + unicodeslot=0x0769, + }, + [0x076A]={ + category="lo", + description="ARABIC LETTER LAM WITH BAR", + direction="al", + linebreak="al", + shcode=0x0644, + unicodeslot=0x076A, + }, + [0x076B]={ + category="lo", + description="ARABIC LETTER REH WITH TWO DOTS VERTICALLY ABOVE", + direction="al", + linebreak="al", + shcode=0x0631, + unicodeslot=0x076B, + }, + [0x076C]={ + category="lo", + description="ARABIC LETTER REH WITH HAMZA ABOVE", + direction="al", + linebreak="al", + shcode=0x0631, + unicodeslot=0x076C, + }, + [0x076D]={ + category="lo", + description="ARABIC LETTER SEEN WITH TWO DOTS VERTICALLY ABOVE", + direction="al", + linebreak="al", + shcode=0x0633, + unicodeslot=0x076D, + }, + [0x0780]={ + category="lo", + description="THAANA LETTER HAA", + direction="al", + linebreak="al", + unicodeslot=0x0780, + }, + [0x0781]={ + category="lo", + description="THAANA LETTER SHAVIYANI", + direction="al", + linebreak="al", + unicodeslot=0x0781, + }, + [0x0782]={ + category="lo", + description="THAANA LETTER NOONU", + direction="al", + linebreak="al", + unicodeslot=0x0782, + }, + [0x0783]={ + category="lo", + description="THAANA LETTER RAA", + direction="al", + linebreak="al", + unicodeslot=0x0783, + }, + [0x0784]={ + category="lo", + description="THAANA LETTER BAA", + direction="al", + linebreak="al", + unicodeslot=0x0784, + }, + [0x0785]={ + category="lo", + description="THAANA LETTER LHAVIYANI", + direction="al", + linebreak="al", + unicodeslot=0x0785, + }, + [0x0786]={ + category="lo", + description="THAANA LETTER KAAFU", + direction="al", + linebreak="al", + unicodeslot=0x0786, + }, + [0x0787]={ + category="lo", + description="THAANA LETTER ALIFU", + direction="al", + linebreak="al", + unicodeslot=0x0787, + }, + [0x0788]={ + category="lo", + description="THAANA LETTER VAAVU", + direction="al", + linebreak="al", + unicodeslot=0x0788, + }, + [0x0789]={ + category="lo", + description="THAANA LETTER MEEMU", + direction="al", + linebreak="al", + unicodeslot=0x0789, + }, + [0x078A]={ + category="lo", + description="THAANA LETTER FAAFU", + direction="al", + linebreak="al", + unicodeslot=0x078A, + }, + [0x078B]={ + category="lo", + description="THAANA LETTER DHAALU", + direction="al", + linebreak="al", + unicodeslot=0x078B, + }, + [0x078C]={ + category="lo", + description="THAANA LETTER THAA", + direction="al", + linebreak="al", + unicodeslot=0x078C, + }, + [0x078D]={ + category="lo", + description="THAANA LETTER LAAMU", + direction="al", + linebreak="al", + unicodeslot=0x078D, + }, + [0x078E]={ + category="lo", + description="THAANA LETTER GAAFU", + direction="al", + linebreak="al", + unicodeslot=0x078E, + }, + [0x078F]={ + category="lo", + description="THAANA LETTER GNAVIYANI", + direction="al", + linebreak="al", + unicodeslot=0x078F, + }, + [0x0790]={ + category="lo", + description="THAANA LETTER SEENU", + direction="al", + linebreak="al", + unicodeslot=0x0790, + }, + [0x0791]={ + category="lo", + description="THAANA LETTER DAVIYANI", + direction="al", + linebreak="al", + unicodeslot=0x0791, + }, + [0x0792]={ + category="lo", + description="THAANA LETTER ZAVIYANI", + direction="al", + linebreak="al", + unicodeslot=0x0792, + }, + [0x0793]={ + category="lo", + description="THAANA LETTER TAVIYANI", + direction="al", + linebreak="al", + unicodeslot=0x0793, + }, + [0x0794]={ + category="lo", + description="THAANA LETTER YAA", + direction="al", + linebreak="al", + unicodeslot=0x0794, + }, + [0x0795]={ + category="lo", + description="THAANA LETTER PAVIYANI", + direction="al", + linebreak="al", + unicodeslot=0x0795, + }, + [0x0796]={ + category="lo", + description="THAANA LETTER JAVIYANI", + direction="al", + linebreak="al", + unicodeslot=0x0796, + }, + [0x0797]={ + category="lo", + description="THAANA LETTER CHAVIYANI", + direction="al", + linebreak="al", + unicodeslot=0x0797, + }, + [0x0798]={ + category="lo", + description="THAANA LETTER TTAA", + direction="al", + linebreak="al", + unicodeslot=0x0798, + }, + [0x0799]={ + category="lo", + description="THAANA LETTER HHAA", + direction="al", + linebreak="al", + unicodeslot=0x0799, + }, + [0x079A]={ + category="lo", + description="THAANA LETTER KHAA", + direction="al", + linebreak="al", + unicodeslot=0x079A, + }, + [0x079B]={ + category="lo", + description="THAANA LETTER THAALU", + direction="al", + linebreak="al", + unicodeslot=0x079B, + }, + [0x079C]={ + category="lo", + description="THAANA LETTER ZAA", + direction="al", + linebreak="al", + unicodeslot=0x079C, + }, + [0x079D]={ + category="lo", + description="THAANA LETTER SHEENU", + direction="al", + linebreak="al", + unicodeslot=0x079D, + }, + [0x079E]={ + category="lo", + description="THAANA LETTER SAADHU", + direction="al", + linebreak="al", + unicodeslot=0x079E, + }, + [0x079F]={ + category="lo", + description="THAANA LETTER DAADHU", + direction="al", + linebreak="al", + unicodeslot=0x079F, + }, + [0x07A0]={ + category="lo", + description="THAANA LETTER TO", + direction="al", + linebreak="al", + unicodeslot=0x07A0, + }, + [0x07A1]={ + category="lo", + description="THAANA LETTER ZO", + direction="al", + linebreak="al", + unicodeslot=0x07A1, + }, + [0x07A2]={ + category="lo", + description="THAANA LETTER AINU", + direction="al", + linebreak="al", + unicodeslot=0x07A2, + }, + [0x07A3]={ + category="lo", + description="THAANA LETTER GHAINU", + direction="al", + linebreak="al", + unicodeslot=0x07A3, + }, + [0x07A4]={ + category="lo", + description="THAANA LETTER QAAFU", + direction="al", + linebreak="al", + unicodeslot=0x07A4, + }, + [0x07A5]={ + category="lo", + description="THAANA LETTER WAAVU", + direction="al", + linebreak="al", + unicodeslot=0x07A5, + }, + [0x07A6]={ + category="mn", + description="THAANA ABAFILI", + direction="nsm", + linebreak="cm", + unicodeslot=0x07A6, + }, + [0x07A7]={ + category="mn", + description="THAANA AABAAFILI", + direction="nsm", + linebreak="cm", + unicodeslot=0x07A7, + }, + [0x07A8]={ + category="mn", + description="THAANA IBIFILI", + direction="nsm", + linebreak="cm", + unicodeslot=0x07A8, + }, + [0x07A9]={ + category="mn", + description="THAANA EEBEEFILI", + direction="nsm", + linebreak="cm", + unicodeslot=0x07A9, + }, + [0x07AA]={ + category="mn", + description="THAANA UBUFILI", + direction="nsm", + linebreak="cm", + unicodeslot=0x07AA, + }, + [0x07AB]={ + category="mn", + description="THAANA OOBOOFILI", + direction="nsm", + linebreak="cm", + unicodeslot=0x07AB, + }, + [0x07AC]={ + category="mn", + description="THAANA EBEFILI", + direction="nsm", + linebreak="cm", + unicodeslot=0x07AC, + }, + [0x07AD]={ + category="mn", + description="THAANA EYBEYFILI", + direction="nsm", + linebreak="cm", + unicodeslot=0x07AD, + }, + [0x07AE]={ + category="mn", + description="THAANA OBOFILI", + direction="nsm", + linebreak="cm", + unicodeslot=0x07AE, + }, + [0x07AF]={ + category="mn", + description="THAANA OABOAFILI", + direction="nsm", + linebreak="cm", + unicodeslot=0x07AF, + }, + [0x07B0]={ + category="mn", + description="THAANA SUKUN", + direction="nsm", + linebreak="cm", + unicodeslot=0x07B0, + }, + [0x07B1]={ + category="lo", + description="THAANA LETTER NAA", + direction="al", + linebreak="al", + unicodeslot=0x07B1, + }, + [0x07C0]={ + category="nd", + description="NKO DIGIT ZERO", + direction="r", + linebreak="nu", + unicodeslot=0x07C0, + }, + [0x07C1]={ + category="nd", + description="NKO DIGIT ONE", + direction="r", + linebreak="nu", + unicodeslot=0x07C1, + }, + [0x07C2]={ + category="nd", + description="NKO DIGIT TWO", + direction="r", + linebreak="nu", + unicodeslot=0x07C2, + }, + [0x07C3]={ + category="nd", + description="NKO DIGIT THREE", + direction="r", + linebreak="nu", + unicodeslot=0x07C3, + }, + [0x07C4]={ + category="nd", + description="NKO DIGIT FOUR", + direction="r", + linebreak="nu", + unicodeslot=0x07C4, + }, + [0x07C5]={ + category="nd", + description="NKO DIGIT FIVE", + direction="r", + linebreak="nu", + unicodeslot=0x07C5, + }, + [0x07C6]={ + category="nd", + description="NKO DIGIT SIX", + direction="r", + linebreak="nu", + unicodeslot=0x07C6, + }, + [0x07C7]={ + category="nd", + description="NKO DIGIT SEVEN", + direction="r", + linebreak="nu", + unicodeslot=0x07C7, + }, + [0x07C8]={ + category="nd", + description="NKO DIGIT EIGHT", + direction="r", + linebreak="nu", + unicodeslot=0x07C8, + }, + [0x07C9]={ + category="nd", + description="NKO DIGIT NINE", + direction="r", + linebreak="nu", + unicodeslot=0x07C9, + }, + [0x07CA]={ + category="lo", + description="NKO LETTER A", + direction="r", + linebreak="al", + unicodeslot=0x07CA, + }, + [0x07CB]={ + category="lo", + description="NKO LETTER EE", + direction="r", + linebreak="al", + unicodeslot=0x07CB, + }, + [0x07CC]={ + category="lo", + description="NKO LETTER I", + direction="r", + linebreak="al", + unicodeslot=0x07CC, + }, + [0x07CD]={ + category="lo", + description="NKO LETTER E", + direction="r", + linebreak="al", + unicodeslot=0x07CD, + }, + [0x07CE]={ + category="lo", + description="NKO LETTER U", + direction="r", + linebreak="al", + unicodeslot=0x07CE, + }, + [0x07CF]={ + category="lo", + description="NKO LETTER OO", + direction="r", + linebreak="al", + unicodeslot=0x07CF, + }, + [0x07D0]={ + category="lo", + description="NKO LETTER O", + direction="r", + linebreak="al", + unicodeslot=0x07D0, + }, + [0x07D1]={ + category="lo", + description="NKO LETTER DAGBASINNA", + direction="r", + linebreak="al", + unicodeslot=0x07D1, + }, + [0x07D2]={ + category="lo", + description="NKO LETTER N", + direction="r", + linebreak="al", + unicodeslot=0x07D2, + }, + [0x07D3]={ + category="lo", + description="NKO LETTER BA", + direction="r", + linebreak="al", + unicodeslot=0x07D3, + }, + [0x07D4]={ + category="lo", + description="NKO LETTER PA", + direction="r", + linebreak="al", + unicodeslot=0x07D4, + }, + [0x07D5]={ + category="lo", + description="NKO LETTER TA", + direction="r", + linebreak="al", + unicodeslot=0x07D5, + }, + [0x07D6]={ + category="lo", + description="NKO LETTER JA", + direction="r", + linebreak="al", + unicodeslot=0x07D6, + }, + [0x07D7]={ + category="lo", + description="NKO LETTER CHA", + direction="r", + linebreak="al", + unicodeslot=0x07D7, + }, + [0x07D8]={ + category="lo", + description="NKO LETTER DA", + direction="r", + linebreak="al", + unicodeslot=0x07D8, + }, + [0x07D9]={ + category="lo", + description="NKO LETTER RA", + direction="r", + linebreak="al", + unicodeslot=0x07D9, + }, + [0x07DA]={ + category="lo", + description="NKO LETTER RRA", + direction="r", + linebreak="al", + unicodeslot=0x07DA, + }, + [0x07DB]={ + category="lo", + description="NKO LETTER SA", + direction="r", + linebreak="al", + unicodeslot=0x07DB, + }, + [0x07DC]={ + category="lo", + description="NKO LETTER GBA", + direction="r", + linebreak="al", + unicodeslot=0x07DC, + }, + [0x07DD]={ + category="lo", + description="NKO LETTER FA", + direction="r", + linebreak="al", + unicodeslot=0x07DD, + }, + [0x07DE]={ + category="lo", + description="NKO LETTER KA", + direction="r", + linebreak="al", + unicodeslot=0x07DE, + }, + [0x07DF]={ + category="lo", + description="NKO LETTER LA", + direction="r", + linebreak="al", + unicodeslot=0x07DF, + }, + [0x07E0]={ + category="lo", + description="NKO LETTER NA WOLOSO", + direction="r", + linebreak="al", + unicodeslot=0x07E0, + }, + [0x07E1]={ + category="lo", + description="NKO LETTER MA", + direction="r", + linebreak="al", + unicodeslot=0x07E1, + }, + [0x07E2]={ + category="lo", + description="NKO LETTER NYA", + direction="r", + linebreak="al", + unicodeslot=0x07E2, + }, + [0x07E3]={ + category="lo", + description="NKO LETTER NA", + direction="r", + linebreak="al", + unicodeslot=0x07E3, + }, + [0x07E4]={ + category="lo", + description="NKO LETTER HA", + direction="r", + linebreak="al", + unicodeslot=0x07E4, + }, + [0x07E5]={ + category="lo", + description="NKO LETTER WA", + direction="r", + linebreak="al", + unicodeslot=0x07E5, + }, + [0x07E6]={ + category="lo", + description="NKO LETTER YA", + direction="r", + linebreak="al", + unicodeslot=0x07E6, + }, + [0x07E7]={ + category="lo", + description="NKO LETTER NYA WOLOSO", + direction="r", + linebreak="al", + unicodeslot=0x07E7, + }, + [0x07E8]={ + category="lo", + description="NKO LETTER JONA JA", + direction="r", + linebreak="al", + unicodeslot=0x07E8, + }, + [0x07E9]={ + category="lo", + description="NKO LETTER JONA CHA", + direction="r", + linebreak="al", + unicodeslot=0x07E9, + }, + [0x07EA]={ + category="lo", + description="NKO LETTER JONA RA", + direction="r", + linebreak="al", + unicodeslot=0x07EA, + }, + [0x07EB]={ + category="mn", + description="NKO COMBINING SHORT HIGH TONE", + direction="nsm", + linebreak="cm", + unicodeslot=0x07EB, + }, + [0x07EC]={ + category="mn", + description="NKO COMBINING SHORT LOW TONE", + direction="nsm", + linebreak="cm", + unicodeslot=0x07EC, + }, + [0x07ED]={ + category="mn", + description="NKO COMBINING SHORT RISING TONE", + direction="nsm", + linebreak="cm", + unicodeslot=0x07ED, + }, + [0x07EE]={ + category="mn", + description="NKO COMBINING LONG DESCENDING TONE", + direction="nsm", + linebreak="cm", + unicodeslot=0x07EE, + }, + [0x07EF]={ + category="mn", + description="NKO COMBINING LONG HIGH TONE", + direction="nsm", + linebreak="cm", + unicodeslot=0x07EF, + }, + [0x07F0]={ + category="mn", + description="NKO COMBINING LONG LOW TONE", + direction="nsm", + linebreak="cm", + unicodeslot=0x07F0, + }, + [0x07F1]={ + category="mn", + description="NKO COMBINING LONG RISING TONE", + direction="nsm", + linebreak="cm", + unicodeslot=0x07F1, + }, + [0x07F2]={ + category="mn", + description="NKO COMBINING NASALIZATION MARK", + direction="nsm", + linebreak="cm", + unicodeslot=0x07F2, + }, + [0x07F3]={ + category="mn", + description="NKO COMBINING DOUBLE DOT ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x07F3, + }, + [0x07F4]={ + category="lm", + description="NKO HIGH TONE APOSTROPHE", + direction="r", + linebreak="al", + unicodeslot=0x07F4, + }, + [0x07F5]={ + category="lm", + description="NKO LOW TONE APOSTROPHE", + direction="r", + linebreak="al", + unicodeslot=0x07F5, + }, + [0x07F6]={ + category="so", + description="NKO SYMBOL OO DENNEN", + direction="on", + linebreak="al", + unicodeslot=0x07F6, + }, + [0x07F7]={ + category="po", + description="NKO SYMBOL GBAKURUNEN", + direction="on", + linebreak="al", + unicodeslot=0x07F7, + }, + [0x07F8]={ + category="po", + description="NKO COMMA", + direction="on", + linebreak="is", + unicodeslot=0x07F8, + }, + [0x07F9]={ + category="po", + description="NKO EXCLAMATION MARK", + direction="on", + linebreak="ex", + unicodeslot=0x07F9, + }, + [0x07FA]={ + category="lm", + description="NKO LAJANYALAN", + direction="r", + linebreak="al", + unicodeslot=0x07FA, + }, + [0x0901]={ + category="mn", + description="DEVANAGARI SIGN CANDRABINDU", + direction="nsm", + linebreak="cm", + unicodeslot=0x0901, + }, + [0x0902]={ + category="mn", + description="DEVANAGARI SIGN ANUSVARA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0902, + }, + [0x0903]={ + category="mc", + description="DEVANAGARI SIGN VISARGA", + direction="l", + linebreak="cm", + unicodeslot=0x0903, + }, + [0x0904]={ + category="lo", + description="DEVANAGARI LETTER SHORT A", + direction="l", + linebreak="al", + unicodeslot=0x0904, + }, + [0x0905]={ + category="lo", + description="DEVANAGARI LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x0905, + }, + [0x0906]={ + category="lo", + description="DEVANAGARI LETTER AA", + direction="l", + linebreak="al", + unicodeslot=0x0906, + }, + [0x0907]={ + category="lo", + description="DEVANAGARI LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x0907, + }, + [0x0908]={ + category="lo", + description="DEVANAGARI LETTER II", + direction="l", + linebreak="al", + unicodeslot=0x0908, + }, + [0x0909]={ + category="lo", + description="DEVANAGARI LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x0909, + }, + [0x090A]={ + category="lo", + description="DEVANAGARI LETTER UU", + direction="l", + linebreak="al", + unicodeslot=0x090A, + }, + [0x090B]={ + category="lo", + description="DEVANAGARI LETTER VOCALIC R", + direction="l", + linebreak="al", + unicodeslot=0x090B, + }, + [0x090C]={ + category="lo", + description="DEVANAGARI LETTER VOCALIC L", + direction="l", + linebreak="al", + unicodeslot=0x090C, + }, + [0x090D]={ + category="lo", + description="DEVANAGARI LETTER CANDRA E", + direction="l", + linebreak="al", + unicodeslot=0x090D, + }, + [0x090E]={ + category="lo", + description="DEVANAGARI LETTER SHORT E", + direction="l", + linebreak="al", + unicodeslot=0x090E, + }, + [0x090F]={ + category="lo", + description="DEVANAGARI LETTER E", + direction="l", + linebreak="al", + unicodeslot=0x090F, + }, + [0x0910]={ + category="lo", + description="DEVANAGARI LETTER AI", + direction="l", + linebreak="al", + unicodeslot=0x0910, + }, + [0x0911]={ + category="lo", + description="DEVANAGARI LETTER CANDRA O", + direction="l", + linebreak="al", + unicodeslot=0x0911, + }, + [0x0912]={ + category="lo", + description="DEVANAGARI LETTER SHORT O", + direction="l", + linebreak="al", + unicodeslot=0x0912, + }, + [0x0913]={ + category="lo", + description="DEVANAGARI LETTER O", + direction="l", + linebreak="al", + unicodeslot=0x0913, + }, + [0x0914]={ + category="lo", + description="DEVANAGARI LETTER AU", + direction="l", + linebreak="al", + unicodeslot=0x0914, + }, + [0x0915]={ + category="lo", + description="DEVANAGARI LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x0915, + }, + [0x0916]={ + category="lo", + description="DEVANAGARI LETTER KHA", + direction="l", + linebreak="al", + unicodeslot=0x0916, + }, + [0x0917]={ + category="lo", + description="DEVANAGARI LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x0917, + }, + [0x0918]={ + category="lo", + description="DEVANAGARI LETTER GHA", + direction="l", + linebreak="al", + unicodeslot=0x0918, + }, + [0x0919]={ + category="lo", + description="DEVANAGARI LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0x0919, + }, + [0x091A]={ + category="lo", + description="DEVANAGARI LETTER CA", + direction="l", + linebreak="al", + unicodeslot=0x091A, + }, + [0x091B]={ + category="lo", + description="DEVANAGARI LETTER CHA", + direction="l", + linebreak="al", + unicodeslot=0x091B, + }, + [0x091C]={ + category="lo", + description="DEVANAGARI LETTER JA", + direction="l", + linebreak="al", + unicodeslot=0x091C, + }, + [0x091D]={ + category="lo", + description="DEVANAGARI LETTER JHA", + direction="l", + linebreak="al", + unicodeslot=0x091D, + }, + [0x091E]={ + category="lo", + description="DEVANAGARI LETTER NYA", + direction="l", + linebreak="al", + unicodeslot=0x091E, + }, + [0x091F]={ + category="lo", + description="DEVANAGARI LETTER TTA", + direction="l", + linebreak="al", + unicodeslot=0x091F, + }, + [0x0920]={ + category="lo", + description="DEVANAGARI LETTER TTHA", + direction="l", + linebreak="al", + unicodeslot=0x0920, + }, + [0x0921]={ + category="lo", + description="DEVANAGARI LETTER DDA", + direction="l", + linebreak="al", + unicodeslot=0x0921, + }, + [0x0922]={ + category="lo", + description="DEVANAGARI LETTER DDHA", + direction="l", + linebreak="al", + unicodeslot=0x0922, + }, + [0x0923]={ + category="lo", + description="DEVANAGARI LETTER NNA", + direction="l", + linebreak="al", + unicodeslot=0x0923, + }, + [0x0924]={ + category="lo", + description="DEVANAGARI LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x0924, + }, + [0x0925]={ + category="lo", + description="DEVANAGARI LETTER THA", + direction="l", + linebreak="al", + unicodeslot=0x0925, + }, + [0x0926]={ + category="lo", + description="DEVANAGARI LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x0926, + }, + [0x0927]={ + category="lo", + description="DEVANAGARI LETTER DHA", + direction="l", + linebreak="al", + unicodeslot=0x0927, + }, + [0x0928]={ + category="lo", + description="DEVANAGARI LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x0928, + }, + [0x0929]={ + category="lo", + description="DEVANAGARI LETTER NNNA", + direction="l", + linebreak="al", + specials={ "char", 0x0928, 0x093C }, + unicodeslot=0x0929, + }, + [0x092A]={ + category="lo", + description="DEVANAGARI LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x092A, + }, + [0x092B]={ + category="lo", + description="DEVANAGARI LETTER PHA", + direction="l", + linebreak="al", + unicodeslot=0x092B, + }, + [0x092C]={ + category="lo", + description="DEVANAGARI LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x092C, + }, + [0x092D]={ + category="lo", + description="DEVANAGARI LETTER BHA", + direction="l", + linebreak="al", + unicodeslot=0x092D, + }, + [0x092E]={ + category="lo", + description="DEVANAGARI LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x092E, + }, + [0x092F]={ + category="lo", + description="DEVANAGARI LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x092F, + }, + [0x0930]={ + category="lo", + description="DEVANAGARI LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0x0930, + }, + [0x0931]={ + category="lo", + description="DEVANAGARI LETTER RRA", + direction="l", + linebreak="al", + specials={ "char", 0x0930, 0x093C }, + unicodeslot=0x0931, + }, + [0x0932]={ + category="lo", + description="DEVANAGARI LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x0932, + }, + [0x0933]={ + category="lo", + description="DEVANAGARI LETTER LLA", + direction="l", + linebreak="al", + unicodeslot=0x0933, + }, + [0x0934]={ + category="lo", + description="DEVANAGARI LETTER LLLA", + direction="l", + linebreak="al", + specials={ "char", 0x0933, 0x093C }, + unicodeslot=0x0934, + }, + [0x0935]={ + category="lo", + description="DEVANAGARI LETTER VA", + direction="l", + linebreak="al", + unicodeslot=0x0935, + }, + [0x0936]={ + category="lo", + description="DEVANAGARI LETTER SHA", + direction="l", + linebreak="al", + unicodeslot=0x0936, + }, + [0x0937]={ + category="lo", + description="DEVANAGARI LETTER SSA", + direction="l", + linebreak="al", + unicodeslot=0x0937, + }, + [0x0938]={ + category="lo", + description="DEVANAGARI LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x0938, + }, + [0x0939]={ + category="lo", + description="DEVANAGARI LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x0939, + }, + [0x093C]={ + category="mn", + description="DEVANAGARI SIGN NUKTA", + direction="nsm", + linebreak="cm", + unicodeslot=0x093C, + }, + [0x093D]={ + category="lo", + description="DEVANAGARI SIGN AVAGRAHA", + direction="l", + linebreak="al", + unicodeslot=0x093D, + }, + [0x093E]={ + category="mc", + description="DEVANAGARI VOWEL SIGN AA", + direction="l", + linebreak="cm", + unicodeslot=0x093E, + }, + [0x093F]={ + category="mc", + description="DEVANAGARI VOWEL SIGN I", + direction="l", + linebreak="cm", + unicodeslot=0x093F, + }, + [0x0940]={ + category="mc", + description="DEVANAGARI VOWEL SIGN II", + direction="l", + linebreak="cm", + unicodeslot=0x0940, + }, + [0x0941]={ + category="mn", + description="DEVANAGARI VOWEL SIGN U", + direction="nsm", + linebreak="cm", + unicodeslot=0x0941, + }, + [0x0942]={ + category="mn", + description="DEVANAGARI VOWEL SIGN UU", + direction="nsm", + linebreak="cm", + unicodeslot=0x0942, + }, + [0x0943]={ + category="mn", + description="DEVANAGARI VOWEL SIGN VOCALIC R", + direction="nsm", + linebreak="cm", + unicodeslot=0x0943, + }, + [0x0944]={ + category="mn", + description="DEVANAGARI VOWEL SIGN VOCALIC RR", + direction="nsm", + linebreak="cm", + unicodeslot=0x0944, + }, + [0x0945]={ + category="mn", + description="DEVANAGARI VOWEL SIGN CANDRA E", + direction="nsm", + linebreak="cm", + unicodeslot=0x0945, + }, + [0x0946]={ + category="mn", + description="DEVANAGARI VOWEL SIGN SHORT E", + direction="nsm", + linebreak="cm", + unicodeslot=0x0946, + }, + [0x0947]={ + category="mn", + description="DEVANAGARI VOWEL SIGN E", + direction="nsm", + linebreak="cm", + unicodeslot=0x0947, + }, + [0x0948]={ + category="mn", + description="DEVANAGARI VOWEL SIGN AI", + direction="nsm", + linebreak="cm", + unicodeslot=0x0948, + }, + [0x0949]={ + category="mc", + description="DEVANAGARI VOWEL SIGN CANDRA O", + direction="l", + linebreak="cm", + unicodeslot=0x0949, + }, + [0x094A]={ + category="mc", + description="DEVANAGARI VOWEL SIGN SHORT O", + direction="l", + linebreak="cm", + unicodeslot=0x094A, + }, + [0x094B]={ + category="mc", + description="DEVANAGARI VOWEL SIGN O", + direction="l", + linebreak="cm", + unicodeslot=0x094B, + }, + [0x094C]={ + category="mc", + description="DEVANAGARI VOWEL SIGN AU", + direction="l", + linebreak="cm", + unicodeslot=0x094C, + }, + [0x094D]={ + category="mn", + description="DEVANAGARI SIGN VIRAMA", + direction="nsm", + linebreak="cm", + unicodeslot=0x094D, + }, + [0x0950]={ + category="lo", + description="DEVANAGARI OM", + direction="l", + linebreak="al", + unicodeslot=0x0950, + }, + [0x0951]={ + category="mn", + description="DEVANAGARI STRESS SIGN UDATTA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0951, + }, + [0x0952]={ + category="mn", + description="DEVANAGARI STRESS SIGN ANUDATTA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0952, + }, + [0x0953]={ + category="mn", + description="DEVANAGARI GRAVE ACCENT", + direction="nsm", + linebreak="cm", + unicodeslot=0x0953, + }, + [0x0954]={ + category="mn", + description="DEVANAGARI ACUTE ACCENT", + direction="nsm", + linebreak="cm", + unicodeslot=0x0954, + }, + [0x0958]={ + category="lo", + description="DEVANAGARI LETTER QA", + direction="l", + linebreak="al", + specials={ "char", 0x0915, 0x093C }, + unicodeslot=0x0958, + }, + [0x0959]={ + category="lo", + description="DEVANAGARI LETTER KHHA", + direction="l", + linebreak="al", + specials={ "char", 0x0916, 0x093C }, + unicodeslot=0x0959, + }, + [0x095A]={ + category="lo", + description="DEVANAGARI LETTER GHHA", + direction="l", + linebreak="al", + specials={ "char", 0x0917, 0x093C }, + unicodeslot=0x095A, + }, + [0x095B]={ + category="lo", + description="DEVANAGARI LETTER ZA", + direction="l", + linebreak="al", + specials={ "char", 0x091C, 0x093C }, + unicodeslot=0x095B, + }, + [0x095C]={ + category="lo", + description="DEVANAGARI LETTER DDDHA", + direction="l", + linebreak="al", + specials={ "char", 0x0921, 0x093C }, + unicodeslot=0x095C, + }, + [0x095D]={ + category="lo", + description="DEVANAGARI LETTER RHA", + direction="l", + linebreak="al", + specials={ "char", 0x0922, 0x093C }, + unicodeslot=0x095D, + }, + [0x095E]={ + category="lo", + description="DEVANAGARI LETTER FA", + direction="l", + linebreak="al", + specials={ "char", 0x092B, 0x093C }, + unicodeslot=0x095E, + }, + [0x095F]={ + category="lo", + description="DEVANAGARI LETTER YYA", + direction="l", + linebreak="al", + specials={ "char", 0x092F, 0x093C }, + unicodeslot=0x095F, + }, + [0x0960]={ + category="lo", + description="DEVANAGARI LETTER VOCALIC RR", + direction="l", + linebreak="al", + unicodeslot=0x0960, + }, + [0x0961]={ + category="lo", + description="DEVANAGARI LETTER VOCALIC LL", + direction="l", + linebreak="al", + unicodeslot=0x0961, + }, + [0x0962]={ + category="mn", + description="DEVANAGARI VOWEL SIGN VOCALIC L", + direction="nsm", + linebreak="cm", + unicodeslot=0x0962, + }, + [0x0963]={ + category="mn", + description="DEVANAGARI VOWEL SIGN VOCALIC LL", + direction="nsm", + linebreak="cm", + unicodeslot=0x0963, + }, + [0x0964]={ + category="po", + description="DEVANAGARI DANDA", + direction="l", + linebreak="ba", + unicodeslot=0x0964, + }, + [0x0965]={ + category="po", + description="DEVANAGARI DOUBLE DANDA", + direction="l", + linebreak="ba", + unicodeslot=0x0965, + }, + [0x0966]={ + category="nd", + description="DEVANAGARI DIGIT ZERO", + direction="l", + linebreak="nu", + unicodeslot=0x0966, + }, + [0x0967]={ + category="nd", + description="DEVANAGARI DIGIT ONE", + direction="l", + linebreak="nu", + unicodeslot=0x0967, + }, + [0x0968]={ + category="nd", + description="DEVANAGARI DIGIT TWO", + direction="l", + linebreak="nu", + unicodeslot=0x0968, + }, + [0x0969]={ + category="nd", + description="DEVANAGARI DIGIT THREE", + direction="l", + linebreak="nu", + unicodeslot=0x0969, + }, + [0x096A]={ + category="nd", + description="DEVANAGARI DIGIT FOUR", + direction="l", + linebreak="nu", + unicodeslot=0x096A, + }, + [0x096B]={ + category="nd", + description="DEVANAGARI DIGIT FIVE", + direction="l", + linebreak="nu", + unicodeslot=0x096B, + }, + [0x096C]={ + category="nd", + description="DEVANAGARI DIGIT SIX", + direction="l", + linebreak="nu", + unicodeslot=0x096C, + }, + [0x096D]={ + category="nd", + description="DEVANAGARI DIGIT SEVEN", + direction="l", + linebreak="nu", + unicodeslot=0x096D, + }, + [0x096E]={ + category="nd", + description="DEVANAGARI DIGIT EIGHT", + direction="l", + linebreak="nu", + unicodeslot=0x096E, + }, + [0x096F]={ + category="nd", + description="DEVANAGARI DIGIT NINE", + direction="l", + linebreak="nu", + unicodeslot=0x096F, + }, + [0x0970]={ + category="po", + description="DEVANAGARI ABBREVIATION SIGN", + direction="l", + linebreak="al", + unicodeslot=0x0970, + }, + [0x097B]={ + category="lo", + description="DEVANAGARI LETTER GGA", + direction="l", + linebreak="al", + unicodeslot=0x097B, + }, + [0x097C]={ + category="lo", + description="DEVANAGARI LETTER JJA", + direction="l", + linebreak="al", + unicodeslot=0x097C, + }, + [0x097D]={ + category="lo", + description="DEVANAGARI LETTER GLOTTAL STOP", + direction="l", + linebreak="al", + unicodeslot=0x097D, + }, + [0x097E]={ + category="lo", + description="DEVANAGARI LETTER DDDA", + direction="l", + linebreak="al", + unicodeslot=0x097E, + }, + [0x097F]={ + category="lo", + description="DEVANAGARI LETTER BBA", + direction="l", + linebreak="al", + unicodeslot=0x097F, + }, + [0x0981]={ + category="mn", + description="BENGALI SIGN CANDRABINDU", + direction="nsm", + linebreak="cm", + unicodeslot=0x0981, + }, + [0x0982]={ + category="mc", + description="BENGALI SIGN ANUSVARA", + direction="l", + linebreak="cm", + unicodeslot=0x0982, + }, + [0x0983]={ + category="mc", + description="BENGALI SIGN VISARGA", + direction="l", + linebreak="cm", + unicodeslot=0x0983, + }, + [0x0985]={ + category="lo", + description="BENGALI LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x0985, + }, + [0x0986]={ + category="lo", + description="BENGALI LETTER AA", + direction="l", + linebreak="al", + unicodeslot=0x0986, + }, + [0x0987]={ + category="lo", + description="BENGALI LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x0987, + }, + [0x0988]={ + category="lo", + description="BENGALI LETTER II", + direction="l", + linebreak="al", + unicodeslot=0x0988, + }, + [0x0989]={ + category="lo", + description="BENGALI LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x0989, + }, + [0x098A]={ + category="lo", + description="BENGALI LETTER UU", + direction="l", + linebreak="al", + unicodeslot=0x098A, + }, + [0x098B]={ + category="lo", + description="BENGALI LETTER VOCALIC R", + direction="l", + linebreak="al", + unicodeslot=0x098B, + }, + [0x098C]={ + category="lo", + description="BENGALI LETTER VOCALIC L", + direction="l", + linebreak="al", + unicodeslot=0x098C, + }, + [0x098F]={ + category="lo", + description="BENGALI LETTER E", + direction="l", + linebreak="al", + unicodeslot=0x098F, + }, + [0x0990]={ + category="lo", + description="BENGALI LETTER AI", + direction="l", + linebreak="al", + unicodeslot=0x0990, + }, + [0x0993]={ + category="lo", + description="BENGALI LETTER O", + direction="l", + linebreak="al", + unicodeslot=0x0993, + }, + [0x0994]={ + category="lo", + description="BENGALI LETTER AU", + direction="l", + linebreak="al", + unicodeslot=0x0994, + }, + [0x0995]={ + category="lo", + description="BENGALI LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x0995, + }, + [0x0996]={ + category="lo", + description="BENGALI LETTER KHA", + direction="l", + linebreak="al", + unicodeslot=0x0996, + }, + [0x0997]={ + category="lo", + description="BENGALI LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x0997, + }, + [0x0998]={ + category="lo", + description="BENGALI LETTER GHA", + direction="l", + linebreak="al", + unicodeslot=0x0998, + }, + [0x0999]={ + category="lo", + description="BENGALI LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0x0999, + }, + [0x099A]={ + category="lo", + description="BENGALI LETTER CA", + direction="l", + linebreak="al", + unicodeslot=0x099A, + }, + [0x099B]={ + category="lo", + description="BENGALI LETTER CHA", + direction="l", + linebreak="al", + unicodeslot=0x099B, + }, + [0x099C]={ + category="lo", + description="BENGALI LETTER JA", + direction="l", + linebreak="al", + unicodeslot=0x099C, + }, + [0x099D]={ + category="lo", + description="BENGALI LETTER JHA", + direction="l", + linebreak="al", + unicodeslot=0x099D, + }, + [0x099E]={ + category="lo", + description="BENGALI LETTER NYA", + direction="l", + linebreak="al", + unicodeslot=0x099E, + }, + [0x099F]={ + category="lo", + description="BENGALI LETTER TTA", + direction="l", + linebreak="al", + unicodeslot=0x099F, + }, + [0x09A0]={ + category="lo", + description="BENGALI LETTER TTHA", + direction="l", + linebreak="al", + unicodeslot=0x09A0, + }, + [0x09A1]={ + category="lo", + description="BENGALI LETTER DDA", + direction="l", + linebreak="al", + unicodeslot=0x09A1, + }, + [0x09A2]={ + category="lo", + description="BENGALI LETTER DDHA", + direction="l", + linebreak="al", + unicodeslot=0x09A2, + }, + [0x09A3]={ + category="lo", + description="BENGALI LETTER NNA", + direction="l", + linebreak="al", + unicodeslot=0x09A3, + }, + [0x09A4]={ + category="lo", + description="BENGALI LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x09A4, + }, + [0x09A5]={ + category="lo", + description="BENGALI LETTER THA", + direction="l", + linebreak="al", + unicodeslot=0x09A5, + }, + [0x09A6]={ + category="lo", + description="BENGALI LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x09A6, + }, + [0x09A7]={ + category="lo", + description="BENGALI LETTER DHA", + direction="l", + linebreak="al", + unicodeslot=0x09A7, + }, + [0x09A8]={ + category="lo", + description="BENGALI LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x09A8, + }, + [0x09AA]={ + category="lo", + description="BENGALI LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x09AA, + }, + [0x09AB]={ + category="lo", + description="BENGALI LETTER PHA", + direction="l", + linebreak="al", + unicodeslot=0x09AB, + }, + [0x09AC]={ + category="lo", + description="BENGALI LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x09AC, + }, + [0x09AD]={ + category="lo", + description="BENGALI LETTER BHA", + direction="l", + linebreak="al", + unicodeslot=0x09AD, + }, + [0x09AE]={ + category="lo", + description="BENGALI LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x09AE, + }, + [0x09AF]={ + category="lo", + description="BENGALI LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x09AF, + }, + [0x09B0]={ + category="lo", + description="BENGALI LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0x09B0, + }, + [0x09B2]={ + category="lo", + description="BENGALI LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x09B2, + }, + [0x09B6]={ + category="lo", + description="BENGALI LETTER SHA", + direction="l", + linebreak="al", + unicodeslot=0x09B6, + }, + [0x09B7]={ + category="lo", + description="BENGALI LETTER SSA", + direction="l", + linebreak="al", + unicodeslot=0x09B7, + }, + [0x09B8]={ + category="lo", + description="BENGALI LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x09B8, + }, + [0x09B9]={ + category="lo", + description="BENGALI LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x09B9, + }, + [0x09BC]={ + category="mn", + description="BENGALI SIGN NUKTA", + direction="nsm", + linebreak="cm", + unicodeslot=0x09BC, + }, + [0x09BD]={ + category="lo", + description="BENGALI SIGN AVAGRAHA", + direction="l", + linebreak="al", + unicodeslot=0x09BD, + }, + [0x09BE]={ + category="mc", + description="BENGALI VOWEL SIGN AA", + direction="l", + linebreak="cm", + unicodeslot=0x09BE, + }, + [0x09BF]={ + category="mc", + description="BENGALI VOWEL SIGN I", + direction="l", + linebreak="cm", + unicodeslot=0x09BF, + }, + [0x09C0]={ + category="mc", + description="BENGALI VOWEL SIGN II", + direction="l", + linebreak="cm", + unicodeslot=0x09C0, + }, + [0x09C1]={ + category="mn", + description="BENGALI VOWEL SIGN U", + direction="nsm", + linebreak="cm", + unicodeslot=0x09C1, + }, + [0x09C2]={ + category="mn", + description="BENGALI VOWEL SIGN UU", + direction="nsm", + linebreak="cm", + unicodeslot=0x09C2, + }, + [0x09C3]={ + category="mn", + description="BENGALI VOWEL SIGN VOCALIC R", + direction="nsm", + linebreak="cm", + unicodeslot=0x09C3, + }, + [0x09C4]={ + category="mn", + description="BENGALI VOWEL SIGN VOCALIC RR", + direction="nsm", + linebreak="cm", + unicodeslot=0x09C4, + }, + [0x09C7]={ + category="mc", + description="BENGALI VOWEL SIGN E", + direction="l", + linebreak="cm", + unicodeslot=0x09C7, + }, + [0x09C8]={ + category="mc", + description="BENGALI VOWEL SIGN AI", + direction="l", + linebreak="cm", + unicodeslot=0x09C8, + }, + [0x09CB]={ + category="mc", + description="BENGALI VOWEL SIGN O", + direction="l", + linebreak="cm", + specials={ "char", 0x09C7, 0x09BE }, + unicodeslot=0x09CB, + }, + [0x09CC]={ + category="mc", + description="BENGALI VOWEL SIGN AU", + direction="l", + linebreak="cm", + specials={ "char", 0x09C7, 0x09D7 }, + unicodeslot=0x09CC, + }, + [0x09CD]={ + category="mn", + description="BENGALI SIGN VIRAMA", + direction="nsm", + linebreak="cm", + unicodeslot=0x09CD, + }, + [0x09CE]={ + category="lo", + description="BENGALI LETTER KHANDA TA", + direction="l", + linebreak="al", + unicodeslot=0x09CE, + }, + [0x09D7]={ + category="mc", + description="BENGALI AU LENGTH MARK", + direction="l", + linebreak="cm", + unicodeslot=0x09D7, + }, + [0x09DC]={ + category="lo", + description="BENGALI LETTER RRA", + direction="l", + linebreak="al", + specials={ "char", 0x09A1, 0x09BC }, + unicodeslot=0x09DC, + }, + [0x09DD]={ + category="lo", + description="BENGALI LETTER RHA", + direction="l", + linebreak="al", + specials={ "char", 0x09A2, 0x09BC }, + unicodeslot=0x09DD, + }, + [0x09DF]={ + category="lo", + description="BENGALI LETTER YYA", + direction="l", + linebreak="al", + specials={ "char", 0x09AF, 0x09BC }, + unicodeslot=0x09DF, + }, + [0x09E0]={ + category="lo", + description="BENGALI LETTER VOCALIC RR", + direction="l", + linebreak="al", + unicodeslot=0x09E0, + }, + [0x09E1]={ + category="lo", + description="BENGALI LETTER VOCALIC LL", + direction="l", + linebreak="al", + unicodeslot=0x09E1, + }, + [0x09E2]={ + category="mn", + description="BENGALI VOWEL SIGN VOCALIC L", + direction="nsm", + linebreak="cm", + unicodeslot=0x09E2, + }, + [0x09E3]={ + category="mn", + description="BENGALI VOWEL SIGN VOCALIC LL", + direction="nsm", + linebreak="cm", + unicodeslot=0x09E3, + }, + [0x09E6]={ + category="nd", + description="BENGALI DIGIT ZERO", + direction="l", + linebreak="nu", + unicodeslot=0x09E6, + }, + [0x09E7]={ + category="nd", + description="BENGALI DIGIT ONE", + direction="l", + linebreak="nu", + unicodeslot=0x09E7, + }, + [0x09E8]={ + category="nd", + description="BENGALI DIGIT TWO", + direction="l", + linebreak="nu", + unicodeslot=0x09E8, + }, + [0x09E9]={ + category="nd", + description="BENGALI DIGIT THREE", + direction="l", + linebreak="nu", + unicodeslot=0x09E9, + }, + [0x09EA]={ + category="nd", + description="BENGALI DIGIT FOUR", + direction="l", + linebreak="nu", + unicodeslot=0x09EA, + }, + [0x09EB]={ + category="nd", + description="BENGALI DIGIT FIVE", + direction="l", + linebreak="nu", + unicodeslot=0x09EB, + }, + [0x09EC]={ + category="nd", + description="BENGALI DIGIT SIX", + direction="l", + linebreak="nu", + unicodeslot=0x09EC, + }, + [0x09ED]={ + category="nd", + description="BENGALI DIGIT SEVEN", + direction="l", + linebreak="nu", + unicodeslot=0x09ED, + }, + [0x09EE]={ + category="nd", + description="BENGALI DIGIT EIGHT", + direction="l", + linebreak="nu", + unicodeslot=0x09EE, + }, + [0x09EF]={ + category="nd", + description="BENGALI DIGIT NINE", + direction="l", + linebreak="nu", + unicodeslot=0x09EF, + }, + [0x09F0]={ + category="lo", + description="BENGALI LETTER RA WITH MIDDLE DIAGONAL", + direction="l", + linebreak="al", + shcode=0x09B0, + unicodeslot=0x09F0, + }, + [0x09F1]={ + category="lo", + description="BENGALI LETTER RA WITH LOWER DIAGONAL", + direction="l", + linebreak="al", + shcode=0x09B0, + unicodeslot=0x09F1, + }, + [0x09F2]={ + category="sc", + description="BENGALI RUPEE MARK", + direction="et", + linebreak="pr", + unicodeslot=0x09F2, + }, + [0x09F3]={ + category="sc", + description="BENGALI RUPEE SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x09F3, + }, + [0x09F4]={ + category="no", + description="BENGALI CURRENCY NUMERATOR ONE", + direction="l", + linebreak="al", + unicodeslot=0x09F4, + }, + [0x09F5]={ + category="no", + description="BENGALI CURRENCY NUMERATOR TWO", + direction="l", + linebreak="al", + unicodeslot=0x09F5, + }, + [0x09F6]={ + category="no", + description="BENGALI CURRENCY NUMERATOR THREE", + direction="l", + linebreak="al", + unicodeslot=0x09F6, + }, + [0x09F7]={ + category="no", + description="BENGALI CURRENCY NUMERATOR FOUR", + direction="l", + linebreak="al", + unicodeslot=0x09F7, + }, + [0x09F8]={ + category="no", + description="BENGALI CURRENCY NUMERATOR ONE LESS THAN THE DENOMINATOR", + direction="l", + linebreak="al", + unicodeslot=0x09F8, + }, + [0x09F9]={ + category="no", + description="BENGALI CURRENCY DENOMINATOR SIXTEEN", + direction="l", + linebreak="al", + unicodeslot=0x09F9, + }, + [0x09FA]={ + category="so", + description="BENGALI ISSHAR", + direction="l", + linebreak="al", + unicodeslot=0x09FA, + }, + [0x0A01]={ + category="mn", + description="GURMUKHI SIGN ADAK BINDI", + direction="nsm", + linebreak="cm", + unicodeslot=0x0A01, + }, + [0x0A02]={ + category="mn", + description="GURMUKHI SIGN BINDI", + direction="nsm", + linebreak="cm", + unicodeslot=0x0A02, + }, + [0x0A03]={ + category="mc", + description="GURMUKHI SIGN VISARGA", + direction="l", + linebreak="cm", + unicodeslot=0x0A03, + }, + [0x0A05]={ + category="lo", + description="GURMUKHI LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x0A05, + }, + [0x0A06]={ + category="lo", + description="GURMUKHI LETTER AA", + direction="l", + linebreak="al", + unicodeslot=0x0A06, + }, + [0x0A07]={ + category="lo", + description="GURMUKHI LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x0A07, + }, + [0x0A08]={ + category="lo", + description="GURMUKHI LETTER II", + direction="l", + linebreak="al", + unicodeslot=0x0A08, + }, + [0x0A09]={ + category="lo", + description="GURMUKHI LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x0A09, + }, + [0x0A0A]={ + category="lo", + description="GURMUKHI LETTER UU", + direction="l", + linebreak="al", + unicodeslot=0x0A0A, + }, + [0x0A0F]={ + category="lo", + description="GURMUKHI LETTER EE", + direction="l", + linebreak="al", + unicodeslot=0x0A0F, + }, + [0x0A10]={ + category="lo", + description="GURMUKHI LETTER AI", + direction="l", + linebreak="al", + unicodeslot=0x0A10, + }, + [0x0A13]={ + category="lo", + description="GURMUKHI LETTER OO", + direction="l", + linebreak="al", + unicodeslot=0x0A13, + }, + [0x0A14]={ + category="lo", + description="GURMUKHI LETTER AU", + direction="l", + linebreak="al", + unicodeslot=0x0A14, + }, + [0x0A15]={ + category="lo", + description="GURMUKHI LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x0A15, + }, + [0x0A16]={ + category="lo", + description="GURMUKHI LETTER KHA", + direction="l", + linebreak="al", + unicodeslot=0x0A16, + }, + [0x0A17]={ + category="lo", + description="GURMUKHI LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x0A17, + }, + [0x0A18]={ + category="lo", + description="GURMUKHI LETTER GHA", + direction="l", + linebreak="al", + unicodeslot=0x0A18, + }, + [0x0A19]={ + category="lo", + description="GURMUKHI LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0x0A19, + }, + [0x0A1A]={ + category="lo", + description="GURMUKHI LETTER CA", + direction="l", + linebreak="al", + unicodeslot=0x0A1A, + }, + [0x0A1B]={ + category="lo", + description="GURMUKHI LETTER CHA", + direction="l", + linebreak="al", + unicodeslot=0x0A1B, + }, + [0x0A1C]={ + category="lo", + description="GURMUKHI LETTER JA", + direction="l", + linebreak="al", + unicodeslot=0x0A1C, + }, + [0x0A1D]={ + category="lo", + description="GURMUKHI LETTER JHA", + direction="l", + linebreak="al", + unicodeslot=0x0A1D, + }, + [0x0A1E]={ + category="lo", + description="GURMUKHI LETTER NYA", + direction="l", + linebreak="al", + unicodeslot=0x0A1E, + }, + [0x0A1F]={ + category="lo", + description="GURMUKHI LETTER TTA", + direction="l", + linebreak="al", + unicodeslot=0x0A1F, + }, + [0x0A20]={ + category="lo", + description="GURMUKHI LETTER TTHA", + direction="l", + linebreak="al", + unicodeslot=0x0A20, + }, + [0x0A21]={ + category="lo", + description="GURMUKHI LETTER DDA", + direction="l", + linebreak="al", + unicodeslot=0x0A21, + }, + [0x0A22]={ + category="lo", + description="GURMUKHI LETTER DDHA", + direction="l", + linebreak="al", + unicodeslot=0x0A22, + }, + [0x0A23]={ + category="lo", + description="GURMUKHI LETTER NNA", + direction="l", + linebreak="al", + unicodeslot=0x0A23, + }, + [0x0A24]={ + category="lo", + description="GURMUKHI LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x0A24, + }, + [0x0A25]={ + category="lo", + description="GURMUKHI LETTER THA", + direction="l", + linebreak="al", + unicodeslot=0x0A25, + }, + [0x0A26]={ + category="lo", + description="GURMUKHI LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x0A26, + }, + [0x0A27]={ + category="lo", + description="GURMUKHI LETTER DHA", + direction="l", + linebreak="al", + unicodeslot=0x0A27, + }, + [0x0A28]={ + category="lo", + description="GURMUKHI LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x0A28, + }, + [0x0A2A]={ + category="lo", + description="GURMUKHI LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x0A2A, + }, + [0x0A2B]={ + category="lo", + description="GURMUKHI LETTER PHA", + direction="l", + linebreak="al", + unicodeslot=0x0A2B, + }, + [0x0A2C]={ + category="lo", + description="GURMUKHI LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x0A2C, + }, + [0x0A2D]={ + category="lo", + description="GURMUKHI LETTER BHA", + direction="l", + linebreak="al", + unicodeslot=0x0A2D, + }, + [0x0A2E]={ + category="lo", + description="GURMUKHI LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x0A2E, + }, + [0x0A2F]={ + category="lo", + description="GURMUKHI LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x0A2F, + }, + [0x0A30]={ + category="lo", + description="GURMUKHI LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0x0A30, + }, + [0x0A32]={ + category="lo", + description="GURMUKHI LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x0A32, + }, + [0x0A33]={ + category="lo", + description="GURMUKHI LETTER LLA", + direction="l", + linebreak="al", + specials={ "char", 0x0A32, 0x0A3C }, + unicodeslot=0x0A33, + }, + [0x0A35]={ + category="lo", + description="GURMUKHI LETTER VA", + direction="l", + linebreak="al", + unicodeslot=0x0A35, + }, + [0x0A36]={ + category="lo", + description="GURMUKHI LETTER SHA", + direction="l", + linebreak="al", + specials={ "char", 0x0A38, 0x0A3C }, + unicodeslot=0x0A36, + }, + [0x0A38]={ + category="lo", + description="GURMUKHI LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x0A38, + }, + [0x0A39]={ + category="lo", + description="GURMUKHI LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x0A39, + }, + [0x0A3C]={ + category="mn", + description="GURMUKHI SIGN NUKTA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0A3C, + }, + [0x0A3E]={ + category="mc", + description="GURMUKHI VOWEL SIGN AA", + direction="l", + linebreak="cm", + unicodeslot=0x0A3E, + }, + [0x0A3F]={ + category="mc", + description="GURMUKHI VOWEL SIGN I", + direction="l", + linebreak="cm", + unicodeslot=0x0A3F, + }, + [0x0A40]={ + category="mc", + description="GURMUKHI VOWEL SIGN II", + direction="l", + linebreak="cm", + unicodeslot=0x0A40, + }, + [0x0A41]={ + category="mn", + description="GURMUKHI VOWEL SIGN U", + direction="nsm", + linebreak="cm", + unicodeslot=0x0A41, + }, + [0x0A42]={ + category="mn", + description="GURMUKHI VOWEL SIGN UU", + direction="nsm", + linebreak="cm", + unicodeslot=0x0A42, + }, + [0x0A47]={ + category="mn", + description="GURMUKHI VOWEL SIGN EE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0A47, + }, + [0x0A48]={ + category="mn", + description="GURMUKHI VOWEL SIGN AI", + direction="nsm", + linebreak="cm", + unicodeslot=0x0A48, + }, + [0x0A4B]={ + category="mn", + description="GURMUKHI VOWEL SIGN OO", + direction="nsm", + linebreak="cm", + unicodeslot=0x0A4B, + }, + [0x0A4C]={ + category="mn", + description="GURMUKHI VOWEL SIGN AU", + direction="nsm", + linebreak="cm", + unicodeslot=0x0A4C, + }, + [0x0A4D]={ + category="mn", + description="GURMUKHI SIGN VIRAMA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0A4D, + }, + [0x0A59]={ + category="lo", + description="GURMUKHI LETTER KHHA", + direction="l", + linebreak="al", + specials={ "char", 0x0A16, 0x0A3C }, + unicodeslot=0x0A59, + }, + [0x0A5A]={ + category="lo", + description="GURMUKHI LETTER GHHA", + direction="l", + linebreak="al", + specials={ "char", 0x0A17, 0x0A3C }, + unicodeslot=0x0A5A, + }, + [0x0A5B]={ + category="lo", + description="GURMUKHI LETTER ZA", + direction="l", + linebreak="al", + specials={ "char", 0x0A1C, 0x0A3C }, + unicodeslot=0x0A5B, + }, + [0x0A5C]={ + category="lo", + description="GURMUKHI LETTER RRA", + direction="l", + linebreak="al", + unicodeslot=0x0A5C, + }, + [0x0A5E]={ + category="lo", + description="GURMUKHI LETTER FA", + direction="l", + linebreak="al", + specials={ "char", 0x0A2B, 0x0A3C }, + unicodeslot=0x0A5E, + }, + [0x0A66]={ + category="nd", + description="GURMUKHI DIGIT ZERO", + direction="l", + linebreak="nu", + unicodeslot=0x0A66, + }, + [0x0A67]={ + category="nd", + description="GURMUKHI DIGIT ONE", + direction="l", + linebreak="nu", + unicodeslot=0x0A67, + }, + [0x0A68]={ + category="nd", + description="GURMUKHI DIGIT TWO", + direction="l", + linebreak="nu", + unicodeslot=0x0A68, + }, + [0x0A69]={ + category="nd", + description="GURMUKHI DIGIT THREE", + direction="l", + linebreak="nu", + unicodeslot=0x0A69, + }, + [0x0A6A]={ + category="nd", + description="GURMUKHI DIGIT FOUR", + direction="l", + linebreak="nu", + unicodeslot=0x0A6A, + }, + [0x0A6B]={ + category="nd", + description="GURMUKHI DIGIT FIVE", + direction="l", + linebreak="nu", + unicodeslot=0x0A6B, + }, + [0x0A6C]={ + category="nd", + description="GURMUKHI DIGIT SIX", + direction="l", + linebreak="nu", + unicodeslot=0x0A6C, + }, + [0x0A6D]={ + category="nd", + description="GURMUKHI DIGIT SEVEN", + direction="l", + linebreak="nu", + unicodeslot=0x0A6D, + }, + [0x0A6E]={ + category="nd", + description="GURMUKHI DIGIT EIGHT", + direction="l", + linebreak="nu", + unicodeslot=0x0A6E, + }, + [0x0A6F]={ + category="nd", + description="GURMUKHI DIGIT NINE", + direction="l", + linebreak="nu", + unicodeslot=0x0A6F, + }, + [0x0A70]={ + category="mn", + description="GURMUKHI TIPPI", + direction="nsm", + linebreak="cm", + unicodeslot=0x0A70, + }, + [0x0A71]={ + category="mn", + description="GURMUKHI ADDAK", + direction="nsm", + linebreak="cm", + unicodeslot=0x0A71, + }, + [0x0A72]={ + category="lo", + description="GURMUKHI IRI", + direction="l", + linebreak="al", + unicodeslot=0x0A72, + }, + [0x0A73]={ + category="lo", + description="GURMUKHI URA", + direction="l", + linebreak="al", + unicodeslot=0x0A73, + }, + [0x0A74]={ + category="lo", + description="GURMUKHI EK ONKAR", + direction="l", + linebreak="al", + unicodeslot=0x0A74, + }, + [0x0A81]={ + category="mn", + description="GUJARATI SIGN CANDRABINDU", + direction="nsm", + linebreak="cm", + unicodeslot=0x0A81, + }, + [0x0A82]={ + category="mn", + description="GUJARATI SIGN ANUSVARA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0A82, + }, + [0x0A83]={ + category="mc", + description="GUJARATI SIGN VISARGA", + direction="l", + linebreak="cm", + unicodeslot=0x0A83, + }, + [0x0A85]={ + category="lo", + description="GUJARATI LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x0A85, + }, + [0x0A86]={ + category="lo", + description="GUJARATI LETTER AA", + direction="l", + linebreak="al", + unicodeslot=0x0A86, + }, + [0x0A87]={ + category="lo", + description="GUJARATI LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x0A87, + }, + [0x0A88]={ + category="lo", + description="GUJARATI LETTER II", + direction="l", + linebreak="al", + unicodeslot=0x0A88, + }, + [0x0A89]={ + category="lo", + description="GUJARATI LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x0A89, + }, + [0x0A8A]={ + category="lo", + description="GUJARATI LETTER UU", + direction="l", + linebreak="al", + unicodeslot=0x0A8A, + }, + [0x0A8B]={ + category="lo", + description="GUJARATI LETTER VOCALIC R", + direction="l", + linebreak="al", + unicodeslot=0x0A8B, + }, + [0x0A8C]={ + category="lo", + description="GUJARATI LETTER VOCALIC L", + direction="l", + linebreak="al", + unicodeslot=0x0A8C, + }, + [0x0A8D]={ + category="lo", + description="GUJARATI VOWEL CANDRA E", + direction="l", + linebreak="al", + unicodeslot=0x0A8D, + }, + [0x0A8F]={ + category="lo", + description="GUJARATI LETTER E", + direction="l", + linebreak="al", + unicodeslot=0x0A8F, + }, + [0x0A90]={ + category="lo", + description="GUJARATI LETTER AI", + direction="l", + linebreak="al", + unicodeslot=0x0A90, + }, + [0x0A91]={ + category="lo", + description="GUJARATI VOWEL CANDRA O", + direction="l", + linebreak="al", + unicodeslot=0x0A91, + }, + [0x0A93]={ + category="lo", + description="GUJARATI LETTER O", + direction="l", + linebreak="al", + unicodeslot=0x0A93, + }, + [0x0A94]={ + category="lo", + description="GUJARATI LETTER AU", + direction="l", + linebreak="al", + unicodeslot=0x0A94, + }, + [0x0A95]={ + category="lo", + description="GUJARATI LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x0A95, + }, + [0x0A96]={ + category="lo", + description="GUJARATI LETTER KHA", + direction="l", + linebreak="al", + unicodeslot=0x0A96, + }, + [0x0A97]={ + category="lo", + description="GUJARATI LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x0A97, + }, + [0x0A98]={ + category="lo", + description="GUJARATI LETTER GHA", + direction="l", + linebreak="al", + unicodeslot=0x0A98, + }, + [0x0A99]={ + category="lo", + description="GUJARATI LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0x0A99, + }, + [0x0A9A]={ + category="lo", + description="GUJARATI LETTER CA", + direction="l", + linebreak="al", + unicodeslot=0x0A9A, + }, + [0x0A9B]={ + category="lo", + description="GUJARATI LETTER CHA", + direction="l", + linebreak="al", + unicodeslot=0x0A9B, + }, + [0x0A9C]={ + category="lo", + description="GUJARATI LETTER JA", + direction="l", + linebreak="al", + unicodeslot=0x0A9C, + }, + [0x0A9D]={ + category="lo", + description="GUJARATI LETTER JHA", + direction="l", + linebreak="al", + unicodeslot=0x0A9D, + }, + [0x0A9E]={ + category="lo", + description="GUJARATI LETTER NYA", + direction="l", + linebreak="al", + unicodeslot=0x0A9E, + }, + [0x0A9F]={ + category="lo", + description="GUJARATI LETTER TTA", + direction="l", + linebreak="al", + unicodeslot=0x0A9F, + }, + [0x0AA0]={ + category="lo", + description="GUJARATI LETTER TTHA", + direction="l", + linebreak="al", + unicodeslot=0x0AA0, + }, + [0x0AA1]={ + category="lo", + description="GUJARATI LETTER DDA", + direction="l", + linebreak="al", + unicodeslot=0x0AA1, + }, + [0x0AA2]={ + category="lo", + description="GUJARATI LETTER DDHA", + direction="l", + linebreak="al", + unicodeslot=0x0AA2, + }, + [0x0AA3]={ + category="lo", + description="GUJARATI LETTER NNA", + direction="l", + linebreak="al", + unicodeslot=0x0AA3, + }, + [0x0AA4]={ + category="lo", + description="GUJARATI LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x0AA4, + }, + [0x0AA5]={ + category="lo", + description="GUJARATI LETTER THA", + direction="l", + linebreak="al", + unicodeslot=0x0AA5, + }, + [0x0AA6]={ + category="lo", + description="GUJARATI LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x0AA6, + }, + [0x0AA7]={ + category="lo", + description="GUJARATI LETTER DHA", + direction="l", + linebreak="al", + unicodeslot=0x0AA7, + }, + [0x0AA8]={ + category="lo", + description="GUJARATI LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x0AA8, + }, + [0x0AAA]={ + category="lo", + description="GUJARATI LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x0AAA, + }, + [0x0AAB]={ + category="lo", + description="GUJARATI LETTER PHA", + direction="l", + linebreak="al", + unicodeslot=0x0AAB, + }, + [0x0AAC]={ + category="lo", + description="GUJARATI LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x0AAC, + }, + [0x0AAD]={ + category="lo", + description="GUJARATI LETTER BHA", + direction="l", + linebreak="al", + unicodeslot=0x0AAD, + }, + [0x0AAE]={ + category="lo", + description="GUJARATI LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x0AAE, + }, + [0x0AAF]={ + category="lo", + description="GUJARATI LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x0AAF, + }, + [0x0AB0]={ + category="lo", + description="GUJARATI LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0x0AB0, + }, + [0x0AB2]={ + category="lo", + description="GUJARATI LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x0AB2, + }, + [0x0AB3]={ + category="lo", + description="GUJARATI LETTER LLA", + direction="l", + linebreak="al", + unicodeslot=0x0AB3, + }, + [0x0AB5]={ + category="lo", + description="GUJARATI LETTER VA", + direction="l", + linebreak="al", + unicodeslot=0x0AB5, + }, + [0x0AB6]={ + category="lo", + description="GUJARATI LETTER SHA", + direction="l", + linebreak="al", + unicodeslot=0x0AB6, + }, + [0x0AB7]={ + category="lo", + description="GUJARATI LETTER SSA", + direction="l", + linebreak="al", + unicodeslot=0x0AB7, + }, + [0x0AB8]={ + category="lo", + description="GUJARATI LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x0AB8, + }, + [0x0AB9]={ + category="lo", + description="GUJARATI LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x0AB9, + }, + [0x0ABC]={ + category="mn", + description="GUJARATI SIGN NUKTA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0ABC, + }, + [0x0ABD]={ + category="lo", + description="GUJARATI SIGN AVAGRAHA", + direction="l", + linebreak="al", + unicodeslot=0x0ABD, + }, + [0x0ABE]={ + category="mc", + description="GUJARATI VOWEL SIGN AA", + direction="l", + linebreak="cm", + unicodeslot=0x0ABE, + }, + [0x0ABF]={ + category="mc", + description="GUJARATI VOWEL SIGN I", + direction="l", + linebreak="cm", + unicodeslot=0x0ABF, + }, + [0x0AC0]={ + category="mc", + description="GUJARATI VOWEL SIGN II", + direction="l", + linebreak="cm", + unicodeslot=0x0AC0, + }, + [0x0AC1]={ + category="mn", + description="GUJARATI VOWEL SIGN U", + direction="nsm", + linebreak="cm", + unicodeslot=0x0AC1, + }, + [0x0AC2]={ + category="mn", + description="GUJARATI VOWEL SIGN UU", + direction="nsm", + linebreak="cm", + unicodeslot=0x0AC2, + }, + [0x0AC3]={ + category="mn", + description="GUJARATI VOWEL SIGN VOCALIC R", + direction="nsm", + linebreak="cm", + unicodeslot=0x0AC3, + }, + [0x0AC4]={ + category="mn", + description="GUJARATI VOWEL SIGN VOCALIC RR", + direction="nsm", + linebreak="cm", + unicodeslot=0x0AC4, + }, + [0x0AC5]={ + category="mn", + description="GUJARATI VOWEL SIGN CANDRA E", + direction="nsm", + linebreak="cm", + unicodeslot=0x0AC5, + }, + [0x0AC7]={ + category="mn", + description="GUJARATI VOWEL SIGN E", + direction="nsm", + linebreak="cm", + unicodeslot=0x0AC7, + }, + [0x0AC8]={ + category="mn", + description="GUJARATI VOWEL SIGN AI", + direction="nsm", + linebreak="cm", + unicodeslot=0x0AC8, + }, + [0x0AC9]={ + category="mc", + description="GUJARATI VOWEL SIGN CANDRA O", + direction="l", + linebreak="cm", + unicodeslot=0x0AC9, + }, + [0x0ACB]={ + category="mc", + description="GUJARATI VOWEL SIGN O", + direction="l", + linebreak="cm", + unicodeslot=0x0ACB, + }, + [0x0ACC]={ + category="mc", + description="GUJARATI VOWEL SIGN AU", + direction="l", + linebreak="cm", + unicodeslot=0x0ACC, + }, + [0x0ACD]={ + category="mn", + description="GUJARATI SIGN VIRAMA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0ACD, + }, + [0x0AD0]={ + category="lo", + description="GUJARATI OM", + direction="l", + linebreak="al", + unicodeslot=0x0AD0, + }, + [0x0AE0]={ + category="lo", + description="GUJARATI LETTER VOCALIC RR", + direction="l", + linebreak="al", + unicodeslot=0x0AE0, + }, + [0x0AE1]={ + category="lo", + description="GUJARATI LETTER VOCALIC LL", + direction="l", + linebreak="al", + unicodeslot=0x0AE1, + }, + [0x0AE2]={ + category="mn", + description="GUJARATI VOWEL SIGN VOCALIC L", + direction="nsm", + linebreak="cm", + unicodeslot=0x0AE2, + }, + [0x0AE3]={ + category="mn", + description="GUJARATI VOWEL SIGN VOCALIC LL", + direction="nsm", + linebreak="cm", + unicodeslot=0x0AE3, + }, + [0x0AE6]={ + category="nd", + description="GUJARATI DIGIT ZERO", + direction="l", + linebreak="nu", + unicodeslot=0x0AE6, + }, + [0x0AE7]={ + category="nd", + description="GUJARATI DIGIT ONE", + direction="l", + linebreak="nu", + unicodeslot=0x0AE7, + }, + [0x0AE8]={ + category="nd", + description="GUJARATI DIGIT TWO", + direction="l", + linebreak="nu", + unicodeslot=0x0AE8, + }, + [0x0AE9]={ + category="nd", + description="GUJARATI DIGIT THREE", + direction="l", + linebreak="nu", + unicodeslot=0x0AE9, + }, + [0x0AEA]={ + category="nd", + description="GUJARATI DIGIT FOUR", + direction="l", + linebreak="nu", + unicodeslot=0x0AEA, + }, + [0x0AEB]={ + category="nd", + description="GUJARATI DIGIT FIVE", + direction="l", + linebreak="nu", + unicodeslot=0x0AEB, + }, + [0x0AEC]={ + category="nd", + description="GUJARATI DIGIT SIX", + direction="l", + linebreak="nu", + unicodeslot=0x0AEC, + }, + [0x0AED]={ + category="nd", + description="GUJARATI DIGIT SEVEN", + direction="l", + linebreak="nu", + unicodeslot=0x0AED, + }, + [0x0AEE]={ + category="nd", + description="GUJARATI DIGIT EIGHT", + direction="l", + linebreak="nu", + unicodeslot=0x0AEE, + }, + [0x0AEF]={ + category="nd", + description="GUJARATI DIGIT NINE", + direction="l", + linebreak="nu", + unicodeslot=0x0AEF, + }, + [0x0AF1]={ + category="sc", + description="GUJARATI RUPEE SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x0AF1, + }, + [0x0B01]={ + category="mn", + description="ORIYA SIGN CANDRABINDU", + direction="nsm", + linebreak="cm", + unicodeslot=0x0B01, + }, + [0x0B02]={ + category="mc", + description="ORIYA SIGN ANUSVARA", + direction="l", + linebreak="cm", + unicodeslot=0x0B02, + }, + [0x0B03]={ + category="mc", + description="ORIYA SIGN VISARGA", + direction="l", + linebreak="cm", + unicodeslot=0x0B03, + }, + [0x0B05]={ + category="lo", + description="ORIYA LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x0B05, + }, + [0x0B06]={ + category="lo", + description="ORIYA LETTER AA", + direction="l", + linebreak="al", + unicodeslot=0x0B06, + }, + [0x0B07]={ + category="lo", + description="ORIYA LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x0B07, + }, + [0x0B08]={ + category="lo", + description="ORIYA LETTER II", + direction="l", + linebreak="al", + unicodeslot=0x0B08, + }, + [0x0B09]={ + category="lo", + description="ORIYA LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x0B09, + }, + [0x0B0A]={ + category="lo", + description="ORIYA LETTER UU", + direction="l", + linebreak="al", + unicodeslot=0x0B0A, + }, + [0x0B0B]={ + category="lo", + description="ORIYA LETTER VOCALIC R", + direction="l", + linebreak="al", + unicodeslot=0x0B0B, + }, + [0x0B0C]={ + category="lo", + description="ORIYA LETTER VOCALIC L", + direction="l", + linebreak="al", + unicodeslot=0x0B0C, + }, + [0x0B0F]={ + category="lo", + description="ORIYA LETTER E", + direction="l", + linebreak="al", + unicodeslot=0x0B0F, + }, + [0x0B10]={ + category="lo", + description="ORIYA LETTER AI", + direction="l", + linebreak="al", + unicodeslot=0x0B10, + }, + [0x0B13]={ + category="lo", + description="ORIYA LETTER O", + direction="l", + linebreak="al", + unicodeslot=0x0B13, + }, + [0x0B14]={ + category="lo", + description="ORIYA LETTER AU", + direction="l", + linebreak="al", + unicodeslot=0x0B14, + }, + [0x0B15]={ + category="lo", + description="ORIYA LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x0B15, + }, + [0x0B16]={ + category="lo", + description="ORIYA LETTER KHA", + direction="l", + linebreak="al", + unicodeslot=0x0B16, + }, + [0x0B17]={ + category="lo", + description="ORIYA LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x0B17, + }, + [0x0B18]={ + category="lo", + description="ORIYA LETTER GHA", + direction="l", + linebreak="al", + unicodeslot=0x0B18, + }, + [0x0B19]={ + category="lo", + description="ORIYA LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0x0B19, + }, + [0x0B1A]={ + category="lo", + description="ORIYA LETTER CA", + direction="l", + linebreak="al", + unicodeslot=0x0B1A, + }, + [0x0B1B]={ + category="lo", + description="ORIYA LETTER CHA", + direction="l", + linebreak="al", + unicodeslot=0x0B1B, + }, + [0x0B1C]={ + category="lo", + description="ORIYA LETTER JA", + direction="l", + linebreak="al", + unicodeslot=0x0B1C, + }, + [0x0B1D]={ + category="lo", + description="ORIYA LETTER JHA", + direction="l", + linebreak="al", + unicodeslot=0x0B1D, + }, + [0x0B1E]={ + category="lo", + description="ORIYA LETTER NYA", + direction="l", + linebreak="al", + unicodeslot=0x0B1E, + }, + [0x0B1F]={ + category="lo", + description="ORIYA LETTER TTA", + direction="l", + linebreak="al", + unicodeslot=0x0B1F, + }, + [0x0B20]={ + category="lo", + description="ORIYA LETTER TTHA", + direction="l", + linebreak="al", + unicodeslot=0x0B20, + }, + [0x0B21]={ + category="lo", + description="ORIYA LETTER DDA", + direction="l", + linebreak="al", + unicodeslot=0x0B21, + }, + [0x0B22]={ + category="lo", + description="ORIYA LETTER DDHA", + direction="l", + linebreak="al", + unicodeslot=0x0B22, + }, + [0x0B23]={ + category="lo", + description="ORIYA LETTER NNA", + direction="l", + linebreak="al", + unicodeslot=0x0B23, + }, + [0x0B24]={ + category="lo", + description="ORIYA LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x0B24, + }, + [0x0B25]={ + category="lo", + description="ORIYA LETTER THA", + direction="l", + linebreak="al", + unicodeslot=0x0B25, + }, + [0x0B26]={ + category="lo", + description="ORIYA LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x0B26, + }, + [0x0B27]={ + category="lo", + description="ORIYA LETTER DHA", + direction="l", + linebreak="al", + unicodeslot=0x0B27, + }, + [0x0B28]={ + category="lo", + description="ORIYA LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x0B28, + }, + [0x0B2A]={ + category="lo", + description="ORIYA LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x0B2A, + }, + [0x0B2B]={ + category="lo", + description="ORIYA LETTER PHA", + direction="l", + linebreak="al", + unicodeslot=0x0B2B, + }, + [0x0B2C]={ + category="lo", + description="ORIYA LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x0B2C, + }, + [0x0B2D]={ + category="lo", + description="ORIYA LETTER BHA", + direction="l", + linebreak="al", + unicodeslot=0x0B2D, + }, + [0x0B2E]={ + category="lo", + description="ORIYA LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x0B2E, + }, + [0x0B2F]={ + category="lo", + description="ORIYA LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x0B2F, + }, + [0x0B30]={ + category="lo", + description="ORIYA LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0x0B30, + }, + [0x0B32]={ + category="lo", + description="ORIYA LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x0B32, + }, + [0x0B33]={ + category="lo", + description="ORIYA LETTER LLA", + direction="l", + linebreak="al", + unicodeslot=0x0B33, + }, + [0x0B35]={ + category="lo", + description="ORIYA LETTER VA", + direction="l", + linebreak="al", + unicodeslot=0x0B35, + }, + [0x0B36]={ + category="lo", + description="ORIYA LETTER SHA", + direction="l", + linebreak="al", + unicodeslot=0x0B36, + }, + [0x0B37]={ + category="lo", + description="ORIYA LETTER SSA", + direction="l", + linebreak="al", + unicodeslot=0x0B37, + }, + [0x0B38]={ + category="lo", + description="ORIYA LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x0B38, + }, + [0x0B39]={ + category="lo", + description="ORIYA LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x0B39, + }, + [0x0B3C]={ + category="mn", + description="ORIYA SIGN NUKTA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0B3C, + }, + [0x0B3D]={ + category="lo", + description="ORIYA SIGN AVAGRAHA", + direction="l", + linebreak="al", + unicodeslot=0x0B3D, + }, + [0x0B3E]={ + category="mc", + description="ORIYA VOWEL SIGN AA", + direction="l", + linebreak="cm", + unicodeslot=0x0B3E, + }, + [0x0B3F]={ + category="mn", + description="ORIYA VOWEL SIGN I", + direction="nsm", + linebreak="cm", + unicodeslot=0x0B3F, + }, + [0x0B40]={ + category="mc", + description="ORIYA VOWEL SIGN II", + direction="l", + linebreak="cm", + unicodeslot=0x0B40, + }, + [0x0B41]={ + category="mn", + description="ORIYA VOWEL SIGN U", + direction="nsm", + linebreak="cm", + unicodeslot=0x0B41, + }, + [0x0B42]={ + category="mn", + description="ORIYA VOWEL SIGN UU", + direction="nsm", + linebreak="cm", + unicodeslot=0x0B42, + }, + [0x0B43]={ + category="mn", + description="ORIYA VOWEL SIGN VOCALIC R", + direction="nsm", + linebreak="cm", + unicodeslot=0x0B43, + }, + [0x0B47]={ + category="mc", + description="ORIYA VOWEL SIGN E", + direction="l", + linebreak="cm", + unicodeslot=0x0B47, + }, + [0x0B48]={ + category="mc", + description="ORIYA VOWEL SIGN AI", + direction="l", + linebreak="cm", + specials={ "char", 0x0B47, 0x0B56 }, + unicodeslot=0x0B48, + }, + [0x0B4B]={ + category="mc", + description="ORIYA VOWEL SIGN O", + direction="l", + linebreak="cm", + specials={ "char", 0x0B47, 0x0B3E }, + unicodeslot=0x0B4B, + }, + [0x0B4C]={ + category="mc", + description="ORIYA VOWEL SIGN AU", + direction="l", + linebreak="cm", + specials={ "char", 0x0B47, 0x0B57 }, + unicodeslot=0x0B4C, + }, + [0x0B4D]={ + category="mn", + description="ORIYA SIGN VIRAMA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0B4D, + }, + [0x0B56]={ + category="mn", + description="ORIYA AI LENGTH MARK", + direction="nsm", + linebreak="cm", + unicodeslot=0x0B56, + }, + [0x0B57]={ + category="mc", + description="ORIYA AU LENGTH MARK", + direction="l", + linebreak="cm", + unicodeslot=0x0B57, + }, + [0x0B5C]={ + category="lo", + description="ORIYA LETTER RRA", + direction="l", + linebreak="al", + specials={ "char", 0x0B21, 0x0B3C }, + unicodeslot=0x0B5C, + }, + [0x0B5D]={ + category="lo", + description="ORIYA LETTER RHA", + direction="l", + linebreak="al", + specials={ "char", 0x0B22, 0x0B3C }, + unicodeslot=0x0B5D, + }, + [0x0B5F]={ + category="lo", + description="ORIYA LETTER YYA", + direction="l", + linebreak="al", + unicodeslot=0x0B5F, + }, + [0x0B60]={ + category="lo", + description="ORIYA LETTER VOCALIC RR", + direction="l", + linebreak="al", + unicodeslot=0x0B60, + }, + [0x0B61]={ + category="lo", + description="ORIYA LETTER VOCALIC LL", + direction="l", + linebreak="al", + unicodeslot=0x0B61, + }, + [0x0B66]={ + category="nd", + description="ORIYA DIGIT ZERO", + direction="l", + linebreak="nu", + unicodeslot=0x0B66, + }, + [0x0B67]={ + category="nd", + description="ORIYA DIGIT ONE", + direction="l", + linebreak="nu", + unicodeslot=0x0B67, + }, + [0x0B68]={ + category="nd", + description="ORIYA DIGIT TWO", + direction="l", + linebreak="nu", + unicodeslot=0x0B68, + }, + [0x0B69]={ + category="nd", + description="ORIYA DIGIT THREE", + direction="l", + linebreak="nu", + unicodeslot=0x0B69, + }, + [0x0B6A]={ + category="nd", + description="ORIYA DIGIT FOUR", + direction="l", + linebreak="nu", + unicodeslot=0x0B6A, + }, + [0x0B6B]={ + category="nd", + description="ORIYA DIGIT FIVE", + direction="l", + linebreak="nu", + unicodeslot=0x0B6B, + }, + [0x0B6C]={ + category="nd", + description="ORIYA DIGIT SIX", + direction="l", + linebreak="nu", + unicodeslot=0x0B6C, + }, + [0x0B6D]={ + category="nd", + description="ORIYA DIGIT SEVEN", + direction="l", + linebreak="nu", + unicodeslot=0x0B6D, + }, + [0x0B6E]={ + category="nd", + description="ORIYA DIGIT EIGHT", + direction="l", + linebreak="nu", + unicodeslot=0x0B6E, + }, + [0x0B6F]={ + category="nd", + description="ORIYA DIGIT NINE", + direction="l", + linebreak="nu", + unicodeslot=0x0B6F, + }, + [0x0B70]={ + category="so", + description="ORIYA ISSHAR", + direction="l", + linebreak="al", + unicodeslot=0x0B70, + }, + [0x0B71]={ + category="lo", + description="ORIYA LETTER WA", + direction="l", + linebreak="al", + unicodeslot=0x0B71, + }, + [0x0B82]={ + category="mn", + description="TAMIL SIGN ANUSVARA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0B82, + }, + [0x0B83]={ + category="lo", + description="TAMIL SIGN VISARGA", + direction="l", + linebreak="al", + unicodeslot=0x0B83, + }, + [0x0B85]={ + category="lo", + description="TAMIL LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x0B85, + }, + [0x0B86]={ + category="lo", + description="TAMIL LETTER AA", + direction="l", + linebreak="al", + unicodeslot=0x0B86, + }, + [0x0B87]={ + category="lo", + description="TAMIL LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x0B87, + }, + [0x0B88]={ + category="lo", + description="TAMIL LETTER II", + direction="l", + linebreak="al", + unicodeslot=0x0B88, + }, + [0x0B89]={ + category="lo", + description="TAMIL LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x0B89, + }, + [0x0B8A]={ + category="lo", + description="TAMIL LETTER UU", + direction="l", + linebreak="al", + unicodeslot=0x0B8A, + }, + [0x0B8E]={ + category="lo", + description="TAMIL LETTER E", + direction="l", + linebreak="al", + unicodeslot=0x0B8E, + }, + [0x0B8F]={ + category="lo", + description="TAMIL LETTER EE", + direction="l", + linebreak="al", + unicodeslot=0x0B8F, + }, + [0x0B90]={ + category="lo", + description="TAMIL LETTER AI", + direction="l", + linebreak="al", + unicodeslot=0x0B90, + }, + [0x0B92]={ + category="lo", + description="TAMIL LETTER O", + direction="l", + linebreak="al", + unicodeslot=0x0B92, + }, + [0x0B93]={ + category="lo", + description="TAMIL LETTER OO", + direction="l", + linebreak="al", + unicodeslot=0x0B93, + }, + [0x0B94]={ + category="lo", + description="TAMIL LETTER AU", + direction="l", + linebreak="al", + specials={ "char", 0x0B92, 0x0BD7 }, + unicodeslot=0x0B94, + }, + [0x0B95]={ + category="lo", + description="TAMIL LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x0B95, + }, + [0x0B99]={ + category="lo", + description="TAMIL LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0x0B99, + }, + [0x0B9A]={ + category="lo", + description="TAMIL LETTER CA", + direction="l", + linebreak="al", + unicodeslot=0x0B9A, + }, + [0x0B9C]={ + category="lo", + description="TAMIL LETTER JA", + direction="l", + linebreak="al", + unicodeslot=0x0B9C, + }, + [0x0B9E]={ + category="lo", + description="TAMIL LETTER NYA", + direction="l", + linebreak="al", + unicodeslot=0x0B9E, + }, + [0x0B9F]={ + category="lo", + description="TAMIL LETTER TTA", + direction="l", + linebreak="al", + unicodeslot=0x0B9F, + }, + [0x0BA3]={ + category="lo", + description="TAMIL LETTER NNA", + direction="l", + linebreak="al", + unicodeslot=0x0BA3, + }, + [0x0BA4]={ + category="lo", + description="TAMIL LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x0BA4, + }, + [0x0BA8]={ + category="lo", + description="TAMIL LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x0BA8, + }, + [0x0BA9]={ + category="lo", + description="TAMIL LETTER NNNA", + direction="l", + linebreak="al", + unicodeslot=0x0BA9, + }, + [0x0BAA]={ + category="lo", + description="TAMIL LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x0BAA, + }, + [0x0BAE]={ + category="lo", + description="TAMIL LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x0BAE, + }, + [0x0BAF]={ + category="lo", + description="TAMIL LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x0BAF, + }, + [0x0BB0]={ + category="lo", + description="TAMIL LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0x0BB0, + }, + [0x0BB1]={ + category="lo", + description="TAMIL LETTER RRA", + direction="l", + linebreak="al", + unicodeslot=0x0BB1, + }, + [0x0BB2]={ + category="lo", + description="TAMIL LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x0BB2, + }, + [0x0BB3]={ + category="lo", + description="TAMIL LETTER LLA", + direction="l", + linebreak="al", + unicodeslot=0x0BB3, + }, + [0x0BB4]={ + category="lo", + description="TAMIL LETTER LLLA", + direction="l", + linebreak="al", + unicodeslot=0x0BB4, + }, + [0x0BB5]={ + category="lo", + description="TAMIL LETTER VA", + direction="l", + linebreak="al", + unicodeslot=0x0BB5, + }, + [0x0BB6]={ + category="lo", + description="TAMIL LETTER SHA", + direction="l", + linebreak="al", + unicodeslot=0x0BB6, + }, + [0x0BB7]={ + category="lo", + description="TAMIL LETTER SSA", + direction="l", + linebreak="al", + unicodeslot=0x0BB7, + }, + [0x0BB8]={ + category="lo", + description="TAMIL LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x0BB8, + }, + [0x0BB9]={ + category="lo", + description="TAMIL LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x0BB9, + }, + [0x0BBE]={ + category="mc", + description="TAMIL VOWEL SIGN AA", + direction="l", + linebreak="cm", + unicodeslot=0x0BBE, + }, + [0x0BBF]={ + category="mc", + description="TAMIL VOWEL SIGN I", + direction="l", + linebreak="cm", + unicodeslot=0x0BBF, + }, + [0x0BC0]={ + category="mn", + description="TAMIL VOWEL SIGN II", + direction="nsm", + linebreak="cm", + unicodeslot=0x0BC0, + }, + [0x0BC1]={ + category="mc", + description="TAMIL VOWEL SIGN U", + direction="l", + linebreak="cm", + unicodeslot=0x0BC1, + }, + [0x0BC2]={ + category="mc", + description="TAMIL VOWEL SIGN UU", + direction="l", + linebreak="cm", + unicodeslot=0x0BC2, + }, + [0x0BC6]={ + category="mc", + description="TAMIL VOWEL SIGN E", + direction="l", + linebreak="cm", + unicodeslot=0x0BC6, + }, + [0x0BC7]={ + category="mc", + description="TAMIL VOWEL SIGN EE", + direction="l", + linebreak="cm", + unicodeslot=0x0BC7, + }, + [0x0BC8]={ + category="mc", + description="TAMIL VOWEL SIGN AI", + direction="l", + linebreak="cm", + unicodeslot=0x0BC8, + }, + [0x0BCA]={ + category="mc", + description="TAMIL VOWEL SIGN O", + direction="l", + linebreak="cm", + specials={ "char", 0x0BC6, 0x0BBE }, + unicodeslot=0x0BCA, + }, + [0x0BCB]={ + category="mc", + description="TAMIL VOWEL SIGN OO", + direction="l", + linebreak="cm", + specials={ "char", 0x0BC7, 0x0BBE }, + unicodeslot=0x0BCB, + }, + [0x0BCC]={ + category="mc", + description="TAMIL VOWEL SIGN AU", + direction="l", + linebreak="cm", + specials={ "char", 0x0BC6, 0x0BD7 }, + unicodeslot=0x0BCC, + }, + [0x0BCD]={ + category="mn", + description="TAMIL SIGN VIRAMA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0BCD, + }, + [0x0BD7]={ + category="mc", + description="TAMIL AU LENGTH MARK", + direction="l", + linebreak="cm", + unicodeslot=0x0BD7, + }, + [0x0BE6]={ + category="nd", + description="TAMIL DIGIT ZERO", + direction="l", + linebreak="nu", + unicodeslot=0x0BE6, + }, + [0x0BE7]={ + category="nd", + description="TAMIL DIGIT ONE", + direction="l", + linebreak="nu", + unicodeslot=0x0BE7, + }, + [0x0BE8]={ + category="nd", + description="TAMIL DIGIT TWO", + direction="l", + linebreak="nu", + unicodeslot=0x0BE8, + }, + [0x0BE9]={ + category="nd", + description="TAMIL DIGIT THREE", + direction="l", + linebreak="nu", + unicodeslot=0x0BE9, + }, + [0x0BEA]={ + category="nd", + description="TAMIL DIGIT FOUR", + direction="l", + linebreak="nu", + unicodeslot=0x0BEA, + }, + [0x0BEB]={ + category="nd", + description="TAMIL DIGIT FIVE", + direction="l", + linebreak="nu", + unicodeslot=0x0BEB, + }, + [0x0BEC]={ + category="nd", + description="TAMIL DIGIT SIX", + direction="l", + linebreak="nu", + unicodeslot=0x0BEC, + }, + [0x0BED]={ + category="nd", + description="TAMIL DIGIT SEVEN", + direction="l", + linebreak="nu", + unicodeslot=0x0BED, + }, + [0x0BEE]={ + category="nd", + description="TAMIL DIGIT EIGHT", + direction="l", + linebreak="nu", + unicodeslot=0x0BEE, + }, + [0x0BEF]={ + category="nd", + description="TAMIL DIGIT NINE", + direction="l", + linebreak="nu", + unicodeslot=0x0BEF, + }, + [0x0BF0]={ + category="no", + description="TAMIL NUMBER TEN", + direction="l", + linebreak="al", + unicodeslot=0x0BF0, + }, + [0x0BF1]={ + category="no", + description="TAMIL NUMBER ONE HUNDRED", + direction="l", + linebreak="al", + unicodeslot=0x0BF1, + }, + [0x0BF2]={ + category="no", + description="TAMIL NUMBER ONE THOUSAND", + direction="l", + linebreak="al", + unicodeslot=0x0BF2, + }, + [0x0BF3]={ + category="so", + description="TAMIL DAY SIGN", + direction="on", + linebreak="al", + unicodeslot=0x0BF3, + }, + [0x0BF4]={ + category="so", + description="TAMIL MONTH SIGN", + direction="on", + linebreak="al", + unicodeslot=0x0BF4, + }, + [0x0BF5]={ + category="so", + description="TAMIL YEAR SIGN", + direction="on", + linebreak="al", + unicodeslot=0x0BF5, + }, + [0x0BF6]={ + category="so", + description="TAMIL DEBIT SIGN", + direction="on", + linebreak="al", + unicodeslot=0x0BF6, + }, + [0x0BF7]={ + category="so", + description="TAMIL CREDIT SIGN", + direction="on", + linebreak="al", + unicodeslot=0x0BF7, + }, + [0x0BF8]={ + category="so", + description="TAMIL AS ABOVE SIGN", + direction="on", + linebreak="al", + unicodeslot=0x0BF8, + }, + [0x0BF9]={ + category="sc", + description="TAMIL RUPEE SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x0BF9, + }, + [0x0BFA]={ + category="so", + description="TAMIL NUMBER SIGN", + direction="on", + linebreak="al", + unicodeslot=0x0BFA, + }, + [0x0C01]={ + category="mc", + description="TELUGU SIGN CANDRABINDU", + direction="l", + linebreak="cm", + unicodeslot=0x0C01, + }, + [0x0C02]={ + category="mc", + description="TELUGU SIGN ANUSVARA", + direction="l", + linebreak="cm", + unicodeslot=0x0C02, + }, + [0x0C03]={ + category="mc", + description="TELUGU SIGN VISARGA", + direction="l", + linebreak="cm", + unicodeslot=0x0C03, + }, + [0x0C05]={ + category="lo", + description="TELUGU LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x0C05, + }, + [0x0C06]={ + category="lo", + description="TELUGU LETTER AA", + direction="l", + linebreak="al", + unicodeslot=0x0C06, + }, + [0x0C07]={ + category="lo", + description="TELUGU LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x0C07, + }, + [0x0C08]={ + category="lo", + description="TELUGU LETTER II", + direction="l", + linebreak="al", + unicodeslot=0x0C08, + }, + [0x0C09]={ + category="lo", + description="TELUGU LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x0C09, + }, + [0x0C0A]={ + category="lo", + description="TELUGU LETTER UU", + direction="l", + linebreak="al", + unicodeslot=0x0C0A, + }, + [0x0C0B]={ + category="lo", + description="TELUGU LETTER VOCALIC R", + direction="l", + linebreak="al", + unicodeslot=0x0C0B, + }, + [0x0C0C]={ + category="lo", + description="TELUGU LETTER VOCALIC L", + direction="l", + linebreak="al", + unicodeslot=0x0C0C, + }, + [0x0C0E]={ + category="lo", + description="TELUGU LETTER E", + direction="l", + linebreak="al", + unicodeslot=0x0C0E, + }, + [0x0C0F]={ + category="lo", + description="TELUGU LETTER EE", + direction="l", + linebreak="al", + unicodeslot=0x0C0F, + }, + [0x0C10]={ + category="lo", + description="TELUGU LETTER AI", + direction="l", + linebreak="al", + unicodeslot=0x0C10, + }, + [0x0C12]={ + category="lo", + description="TELUGU LETTER O", + direction="l", + linebreak="al", + unicodeslot=0x0C12, + }, + [0x0C13]={ + category="lo", + description="TELUGU LETTER OO", + direction="l", + linebreak="al", + unicodeslot=0x0C13, + }, + [0x0C14]={ + category="lo", + description="TELUGU LETTER AU", + direction="l", + linebreak="al", + unicodeslot=0x0C14, + }, + [0x0C15]={ + category="lo", + description="TELUGU LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x0C15, + }, + [0x0C16]={ + category="lo", + description="TELUGU LETTER KHA", + direction="l", + linebreak="al", + unicodeslot=0x0C16, + }, + [0x0C17]={ + category="lo", + description="TELUGU LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x0C17, + }, + [0x0C18]={ + category="lo", + description="TELUGU LETTER GHA", + direction="l", + linebreak="al", + unicodeslot=0x0C18, + }, + [0x0C19]={ + category="lo", + description="TELUGU LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0x0C19, + }, + [0x0C1A]={ + category="lo", + description="TELUGU LETTER CA", + direction="l", + linebreak="al", + unicodeslot=0x0C1A, + }, + [0x0C1B]={ + category="lo", + description="TELUGU LETTER CHA", + direction="l", + linebreak="al", + unicodeslot=0x0C1B, + }, + [0x0C1C]={ + category="lo", + description="TELUGU LETTER JA", + direction="l", + linebreak="al", + unicodeslot=0x0C1C, + }, + [0x0C1D]={ + category="lo", + description="TELUGU LETTER JHA", + direction="l", + linebreak="al", + unicodeslot=0x0C1D, + }, + [0x0C1E]={ + category="lo", + description="TELUGU LETTER NYA", + direction="l", + linebreak="al", + unicodeslot=0x0C1E, + }, + [0x0C1F]={ + category="lo", + description="TELUGU LETTER TTA", + direction="l", + linebreak="al", + unicodeslot=0x0C1F, + }, + [0x0C20]={ + category="lo", + description="TELUGU LETTER TTHA", + direction="l", + linebreak="al", + unicodeslot=0x0C20, + }, + [0x0C21]={ + category="lo", + description="TELUGU LETTER DDA", + direction="l", + linebreak="al", + unicodeslot=0x0C21, + }, + [0x0C22]={ + category="lo", + description="TELUGU LETTER DDHA", + direction="l", + linebreak="al", + unicodeslot=0x0C22, + }, + [0x0C23]={ + category="lo", + description="TELUGU LETTER NNA", + direction="l", + linebreak="al", + unicodeslot=0x0C23, + }, + [0x0C24]={ + category="lo", + description="TELUGU LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x0C24, + }, + [0x0C25]={ + category="lo", + description="TELUGU LETTER THA", + direction="l", + linebreak="al", + unicodeslot=0x0C25, + }, + [0x0C26]={ + category="lo", + description="TELUGU LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x0C26, + }, + [0x0C27]={ + category="lo", + description="TELUGU LETTER DHA", + direction="l", + linebreak="al", + unicodeslot=0x0C27, + }, + [0x0C28]={ + category="lo", + description="TELUGU LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x0C28, + }, + [0x0C2A]={ + category="lo", + description="TELUGU LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x0C2A, + }, + [0x0C2B]={ + category="lo", + description="TELUGU LETTER PHA", + direction="l", + linebreak="al", + unicodeslot=0x0C2B, + }, + [0x0C2C]={ + category="lo", + description="TELUGU LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x0C2C, + }, + [0x0C2D]={ + category="lo", + description="TELUGU LETTER BHA", + direction="l", + linebreak="al", + unicodeslot=0x0C2D, + }, + [0x0C2E]={ + category="lo", + description="TELUGU LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x0C2E, + }, + [0x0C2F]={ + category="lo", + description="TELUGU LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x0C2F, + }, + [0x0C30]={ + category="lo", + description="TELUGU LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0x0C30, + }, + [0x0C31]={ + category="lo", + description="TELUGU LETTER RRA", + direction="l", + linebreak="al", + unicodeslot=0x0C31, + }, + [0x0C32]={ + category="lo", + description="TELUGU LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x0C32, + }, + [0x0C33]={ + category="lo", + description="TELUGU LETTER LLA", + direction="l", + linebreak="al", + unicodeslot=0x0C33, + }, + [0x0C35]={ + category="lo", + description="TELUGU LETTER VA", + direction="l", + linebreak="al", + unicodeslot=0x0C35, + }, + [0x0C36]={ + category="lo", + description="TELUGU LETTER SHA", + direction="l", + linebreak="al", + unicodeslot=0x0C36, + }, + [0x0C37]={ + category="lo", + description="TELUGU LETTER SSA", + direction="l", + linebreak="al", + unicodeslot=0x0C37, + }, + [0x0C38]={ + category="lo", + description="TELUGU LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x0C38, + }, + [0x0C39]={ + category="lo", + description="TELUGU LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x0C39, + }, + [0x0C3E]={ + category="mn", + description="TELUGU VOWEL SIGN AA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0C3E, + }, + [0x0C3F]={ + category="mn", + description="TELUGU VOWEL SIGN I", + direction="nsm", + linebreak="cm", + unicodeslot=0x0C3F, + }, + [0x0C40]={ + category="mn", + description="TELUGU VOWEL SIGN II", + direction="nsm", + linebreak="cm", + unicodeslot=0x0C40, + }, + [0x0C41]={ + category="mc", + description="TELUGU VOWEL SIGN U", + direction="l", + linebreak="cm", + unicodeslot=0x0C41, + }, + [0x0C42]={ + category="mc", + description="TELUGU VOWEL SIGN UU", + direction="l", + linebreak="cm", + unicodeslot=0x0C42, + }, + [0x0C43]={ + category="mc", + description="TELUGU VOWEL SIGN VOCALIC R", + direction="l", + linebreak="cm", + unicodeslot=0x0C43, + }, + [0x0C44]={ + category="mc", + description="TELUGU VOWEL SIGN VOCALIC RR", + direction="l", + linebreak="cm", + unicodeslot=0x0C44, + }, + [0x0C46]={ + category="mn", + description="TELUGU VOWEL SIGN E", + direction="nsm", + linebreak="cm", + unicodeslot=0x0C46, + }, + [0x0C47]={ + category="mn", + description="TELUGU VOWEL SIGN EE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0C47, + }, + [0x0C48]={ + category="mn", + description="TELUGU VOWEL SIGN AI", + direction="nsm", + linebreak="cm", + specials={ "char", 0x0C46, 0x0C56 }, + unicodeslot=0x0C48, + }, + [0x0C4A]={ + category="mn", + description="TELUGU VOWEL SIGN O", + direction="nsm", + linebreak="cm", + unicodeslot=0x0C4A, + }, + [0x0C4B]={ + category="mn", + description="TELUGU VOWEL SIGN OO", + direction="nsm", + linebreak="cm", + unicodeslot=0x0C4B, + }, + [0x0C4C]={ + category="mn", + description="TELUGU VOWEL SIGN AU", + direction="nsm", + linebreak="cm", + unicodeslot=0x0C4C, + }, + [0x0C4D]={ + category="mn", + description="TELUGU SIGN VIRAMA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0C4D, + }, + [0x0C55]={ + category="mn", + description="TELUGU LENGTH MARK", + direction="nsm", + linebreak="cm", + unicodeslot=0x0C55, + }, + [0x0C56]={ + category="mn", + description="TELUGU AI LENGTH MARK", + direction="nsm", + linebreak="cm", + unicodeslot=0x0C56, + }, + [0x0C60]={ + category="lo", + description="TELUGU LETTER VOCALIC RR", + direction="l", + linebreak="al", + unicodeslot=0x0C60, + }, + [0x0C61]={ + category="lo", + description="TELUGU LETTER VOCALIC LL", + direction="l", + linebreak="al", + unicodeslot=0x0C61, + }, + [0x0C66]={ + category="nd", + description="TELUGU DIGIT ZERO", + direction="l", + linebreak="nu", + unicodeslot=0x0C66, + }, + [0x0C67]={ + category="nd", + description="TELUGU DIGIT ONE", + direction="l", + linebreak="nu", + unicodeslot=0x0C67, + }, + [0x0C68]={ + category="nd", + description="TELUGU DIGIT TWO", + direction="l", + linebreak="nu", + unicodeslot=0x0C68, + }, + [0x0C69]={ + category="nd", + description="TELUGU DIGIT THREE", + direction="l", + linebreak="nu", + unicodeslot=0x0C69, + }, + [0x0C6A]={ + category="nd", + description="TELUGU DIGIT FOUR", + direction="l", + linebreak="nu", + unicodeslot=0x0C6A, + }, + [0x0C6B]={ + category="nd", + description="TELUGU DIGIT FIVE", + direction="l", + linebreak="nu", + unicodeslot=0x0C6B, + }, + [0x0C6C]={ + category="nd", + description="TELUGU DIGIT SIX", + direction="l", + linebreak="nu", + unicodeslot=0x0C6C, + }, + [0x0C6D]={ + category="nd", + description="TELUGU DIGIT SEVEN", + direction="l", + linebreak="nu", + unicodeslot=0x0C6D, + }, + [0x0C6E]={ + category="nd", + description="TELUGU DIGIT EIGHT", + direction="l", + linebreak="nu", + unicodeslot=0x0C6E, + }, + [0x0C6F]={ + category="nd", + description="TELUGU DIGIT NINE", + direction="l", + linebreak="nu", + unicodeslot=0x0C6F, + }, + [0x0C82]={ + category="mc", + description="KANNADA SIGN ANUSVARA", + direction="l", + linebreak="cm", + unicodeslot=0x0C82, + }, + [0x0C83]={ + category="mc", + description="KANNADA SIGN VISARGA", + direction="l", + linebreak="cm", + unicodeslot=0x0C83, + }, + [0x0C85]={ + category="lo", + description="KANNADA LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x0C85, + }, + [0x0C86]={ + category="lo", + description="KANNADA LETTER AA", + direction="l", + linebreak="al", + unicodeslot=0x0C86, + }, + [0x0C87]={ + category="lo", + description="KANNADA LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x0C87, + }, + [0x0C88]={ + category="lo", + description="KANNADA LETTER II", + direction="l", + linebreak="al", + unicodeslot=0x0C88, + }, + [0x0C89]={ + category="lo", + description="KANNADA LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x0C89, + }, + [0x0C8A]={ + category="lo", + description="KANNADA LETTER UU", + direction="l", + linebreak="al", + unicodeslot=0x0C8A, + }, + [0x0C8B]={ + category="lo", + description="KANNADA LETTER VOCALIC R", + direction="l", + linebreak="al", + unicodeslot=0x0C8B, + }, + [0x0C8C]={ + category="lo", + description="KANNADA LETTER VOCALIC L", + direction="l", + linebreak="al", + unicodeslot=0x0C8C, + }, + [0x0C8E]={ + category="lo", + description="KANNADA LETTER E", + direction="l", + linebreak="al", + unicodeslot=0x0C8E, + }, + [0x0C8F]={ + category="lo", + description="KANNADA LETTER EE", + direction="l", + linebreak="al", + unicodeslot=0x0C8F, + }, + [0x0C90]={ + category="lo", + description="KANNADA LETTER AI", + direction="l", + linebreak="al", + unicodeslot=0x0C90, + }, + [0x0C92]={ + category="lo", + description="KANNADA LETTER O", + direction="l", + linebreak="al", + unicodeslot=0x0C92, + }, + [0x0C93]={ + category="lo", + description="KANNADA LETTER OO", + direction="l", + linebreak="al", + unicodeslot=0x0C93, + }, + [0x0C94]={ + category="lo", + description="KANNADA LETTER AU", + direction="l", + linebreak="al", + unicodeslot=0x0C94, + }, + [0x0C95]={ + category="lo", + description="KANNADA LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x0C95, + }, + [0x0C96]={ + category="lo", + description="KANNADA LETTER KHA", + direction="l", + linebreak="al", + unicodeslot=0x0C96, + }, + [0x0C97]={ + category="lo", + description="KANNADA LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x0C97, + }, + [0x0C98]={ + category="lo", + description="KANNADA LETTER GHA", + direction="l", + linebreak="al", + unicodeslot=0x0C98, + }, + [0x0C99]={ + category="lo", + description="KANNADA LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0x0C99, + }, + [0x0C9A]={ + category="lo", + description="KANNADA LETTER CA", + direction="l", + linebreak="al", + unicodeslot=0x0C9A, + }, + [0x0C9B]={ + category="lo", + description="KANNADA LETTER CHA", + direction="l", + linebreak="al", + unicodeslot=0x0C9B, + }, + [0x0C9C]={ + category="lo", + description="KANNADA LETTER JA", + direction="l", + linebreak="al", + unicodeslot=0x0C9C, + }, + [0x0C9D]={ + category="lo", + description="KANNADA LETTER JHA", + direction="l", + linebreak="al", + unicodeslot=0x0C9D, + }, + [0x0C9E]={ + category="lo", + description="KANNADA LETTER NYA", + direction="l", + linebreak="al", + unicodeslot=0x0C9E, + }, + [0x0C9F]={ + category="lo", + description="KANNADA LETTER TTA", + direction="l", + linebreak="al", + unicodeslot=0x0C9F, + }, + [0x0CA0]={ + category="lo", + description="KANNADA LETTER TTHA", + direction="l", + linebreak="al", + unicodeslot=0x0CA0, + }, + [0x0CA1]={ + category="lo", + description="KANNADA LETTER DDA", + direction="l", + linebreak="al", + unicodeslot=0x0CA1, + }, + [0x0CA2]={ + category="lo", + description="KANNADA LETTER DDHA", + direction="l", + linebreak="al", + unicodeslot=0x0CA2, + }, + [0x0CA3]={ + category="lo", + description="KANNADA LETTER NNA", + direction="l", + linebreak="al", + unicodeslot=0x0CA3, + }, + [0x0CA4]={ + category="lo", + description="KANNADA LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x0CA4, + }, + [0x0CA5]={ + category="lo", + description="KANNADA LETTER THA", + direction="l", + linebreak="al", + unicodeslot=0x0CA5, + }, + [0x0CA6]={ + category="lo", + description="KANNADA LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x0CA6, + }, + [0x0CA7]={ + category="lo", + description="KANNADA LETTER DHA", + direction="l", + linebreak="al", + unicodeslot=0x0CA7, + }, + [0x0CA8]={ + category="lo", + description="KANNADA LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x0CA8, + }, + [0x0CAA]={ + category="lo", + description="KANNADA LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x0CAA, + }, + [0x0CAB]={ + category="lo", + description="KANNADA LETTER PHA", + direction="l", + linebreak="al", + unicodeslot=0x0CAB, + }, + [0x0CAC]={ + category="lo", + description="KANNADA LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x0CAC, + }, + [0x0CAD]={ + category="lo", + description="KANNADA LETTER BHA", + direction="l", + linebreak="al", + unicodeslot=0x0CAD, + }, + [0x0CAE]={ + category="lo", + description="KANNADA LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x0CAE, + }, + [0x0CAF]={ + category="lo", + description="KANNADA LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x0CAF, + }, + [0x0CB0]={ + category="lo", + description="KANNADA LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0x0CB0, + }, + [0x0CB1]={ + category="lo", + description="KANNADA LETTER RRA", + direction="l", + linebreak="al", + unicodeslot=0x0CB1, + }, + [0x0CB2]={ + category="lo", + description="KANNADA LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x0CB2, + }, + [0x0CB3]={ + category="lo", + description="KANNADA LETTER LLA", + direction="l", + linebreak="al", + unicodeslot=0x0CB3, + }, + [0x0CB5]={ + category="lo", + description="KANNADA LETTER VA", + direction="l", + linebreak="al", + unicodeslot=0x0CB5, + }, + [0x0CB6]={ + category="lo", + description="KANNADA LETTER SHA", + direction="l", + linebreak="al", + unicodeslot=0x0CB6, + }, + [0x0CB7]={ + category="lo", + description="KANNADA LETTER SSA", + direction="l", + linebreak="al", + unicodeslot=0x0CB7, + }, + [0x0CB8]={ + category="lo", + description="KANNADA LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x0CB8, + }, + [0x0CB9]={ + category="lo", + description="KANNADA LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x0CB9, + }, + [0x0CBC]={ + category="mn", + description="KANNADA SIGN NUKTA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0CBC, + }, + [0x0CBD]={ + category="lo", + description="KANNADA SIGN AVAGRAHA", + direction="l", + linebreak="al", + unicodeslot=0x0CBD, + }, + [0x0CBE]={ + category="mc", + description="KANNADA VOWEL SIGN AA", + direction="l", + linebreak="cm", + unicodeslot=0x0CBE, + }, + [0x0CBF]={ + category="mn", + description="KANNADA VOWEL SIGN I", + direction="l", + linebreak="cm", + unicodeslot=0x0CBF, + }, + [0x0CC0]={ + category="mc", + description="KANNADA VOWEL SIGN II", + direction="l", + linebreak="cm", + specials={ "char", 0x0CBF, 0x0CD5 }, + unicodeslot=0x0CC0, + }, + [0x0CC1]={ + category="mc", + description="KANNADA VOWEL SIGN U", + direction="l", + linebreak="cm", + unicodeslot=0x0CC1, + }, + [0x0CC2]={ + category="mc", + description="KANNADA VOWEL SIGN UU", + direction="l", + linebreak="cm", + unicodeslot=0x0CC2, + }, + [0x0CC3]={ + category="mc", + description="KANNADA VOWEL SIGN VOCALIC R", + direction="l", + linebreak="cm", + unicodeslot=0x0CC3, + }, + [0x0CC4]={ + category="mc", + description="KANNADA VOWEL SIGN VOCALIC RR", + direction="l", + linebreak="cm", + unicodeslot=0x0CC4, + }, + [0x0CC6]={ + category="mn", + description="KANNADA VOWEL SIGN E", + direction="l", + linebreak="cm", + unicodeslot=0x0CC6, + }, + [0x0CC7]={ + category="mc", + description="KANNADA VOWEL SIGN EE", + direction="l", + linebreak="cm", + specials={ "char", 0x0CC6, 0x0CD5 }, + unicodeslot=0x0CC7, + }, + [0x0CC8]={ + category="mc", + description="KANNADA VOWEL SIGN AI", + direction="l", + linebreak="cm", + specials={ "char", 0x0CC6, 0x0CD6 }, + unicodeslot=0x0CC8, + }, + [0x0CCA]={ + category="mc", + description="KANNADA VOWEL SIGN O", + direction="l", + linebreak="cm", + specials={ "char", 0x0CC6, 0x0CC2 }, + unicodeslot=0x0CCA, + }, + [0x0CCB]={ + category="mc", + description="KANNADA VOWEL SIGN OO", + direction="l", + linebreak="cm", + specials={ "char", 0x0CCA, 0x0CD5 }, + unicodeslot=0x0CCB, + }, + [0x0CCC]={ + category="mn", + description="KANNADA VOWEL SIGN AU", + direction="nsm", + linebreak="cm", + unicodeslot=0x0CCC, + }, + [0x0CCD]={ + category="mn", + description="KANNADA SIGN VIRAMA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0CCD, + }, + [0x0CD5]={ + category="mc", + description="KANNADA LENGTH MARK", + direction="l", + linebreak="cm", + unicodeslot=0x0CD5, + }, + [0x0CD6]={ + category="mc", + description="KANNADA AI LENGTH MARK", + direction="l", + linebreak="cm", + unicodeslot=0x0CD6, + }, + [0x0CDE]={ + category="lo", + description="KANNADA LETTER FA", + direction="l", + linebreak="al", + unicodeslot=0x0CDE, + }, + [0x0CE0]={ + category="lo", + description="KANNADA LETTER VOCALIC RR", + direction="l", + linebreak="al", + unicodeslot=0x0CE0, + }, + [0x0CE1]={ + category="lo", + description="KANNADA LETTER VOCALIC LL", + direction="l", + linebreak="al", + unicodeslot=0x0CE1, + }, + [0x0CE2]={ + category="mn", + description="KANNADA VOWEL SIGN VOCALIC L", + direction="nsm", + linebreak="cm", + unicodeslot=0x0CE2, + }, + [0x0CE3]={ + category="mn", + description="KANNADA VOWEL SIGN VOCALIC LL", + direction="nsm", + linebreak="cm", + unicodeslot=0x0CE3, + }, + [0x0CE6]={ + category="nd", + description="KANNADA DIGIT ZERO", + direction="l", + linebreak="nu", + unicodeslot=0x0CE6, + }, + [0x0CE7]={ + category="nd", + description="KANNADA DIGIT ONE", + direction="l", + linebreak="nu", + unicodeslot=0x0CE7, + }, + [0x0CE8]={ + category="nd", + description="KANNADA DIGIT TWO", + direction="l", + linebreak="nu", + unicodeslot=0x0CE8, + }, + [0x0CE9]={ + category="nd", + description="KANNADA DIGIT THREE", + direction="l", + linebreak="nu", + unicodeslot=0x0CE9, + }, + [0x0CEA]={ + category="nd", + description="KANNADA DIGIT FOUR", + direction="l", + linebreak="nu", + unicodeslot=0x0CEA, + }, + [0x0CEB]={ + category="nd", + description="KANNADA DIGIT FIVE", + direction="l", + linebreak="nu", + unicodeslot=0x0CEB, + }, + [0x0CEC]={ + category="nd", + description="KANNADA DIGIT SIX", + direction="l", + linebreak="nu", + unicodeslot=0x0CEC, + }, + [0x0CED]={ + category="nd", + description="KANNADA DIGIT SEVEN", + direction="l", + linebreak="nu", + unicodeslot=0x0CED, + }, + [0x0CEE]={ + category="nd", + description="KANNADA DIGIT EIGHT", + direction="l", + linebreak="nu", + unicodeslot=0x0CEE, + }, + [0x0CEF]={ + category="nd", + description="KANNADA DIGIT NINE", + direction="l", + linebreak="nu", + unicodeslot=0x0CEF, + }, + [0x0CF1]={ + category="so", + description="KANNADA SIGN JIHVAMULIYA", + direction="on", + linebreak="al", + unicodeslot=0x0CF1, + }, + [0x0CF2]={ + category="so", + description="KANNADA SIGN UPADHMANIYA", + direction="on", + linebreak="al", + unicodeslot=0x0CF2, + }, + [0x0D02]={ + category="mc", + description="MALAYALAM SIGN ANUSVARA", + direction="l", + linebreak="cm", + unicodeslot=0x0D02, + }, + [0x0D03]={ + category="mc", + description="MALAYALAM SIGN VISARGA", + direction="l", + linebreak="cm", + unicodeslot=0x0D03, + }, + [0x0D05]={ + category="lo", + description="MALAYALAM LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x0D05, + }, + [0x0D06]={ + category="lo", + description="MALAYALAM LETTER AA", + direction="l", + linebreak="al", + unicodeslot=0x0D06, + }, + [0x0D07]={ + category="lo", + description="MALAYALAM LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x0D07, + }, + [0x0D08]={ + category="lo", + description="MALAYALAM LETTER II", + direction="l", + linebreak="al", + unicodeslot=0x0D08, + }, + [0x0D09]={ + category="lo", + description="MALAYALAM LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x0D09, + }, + [0x0D0A]={ + category="lo", + description="MALAYALAM LETTER UU", + direction="l", + linebreak="al", + unicodeslot=0x0D0A, + }, + [0x0D0B]={ + category="lo", + description="MALAYALAM LETTER VOCALIC R", + direction="l", + linebreak="al", + unicodeslot=0x0D0B, + }, + [0x0D0C]={ + category="lo", + description="MALAYALAM LETTER VOCALIC L", + direction="l", + linebreak="al", + unicodeslot=0x0D0C, + }, + [0x0D0E]={ + category="lo", + description="MALAYALAM LETTER E", + direction="l", + linebreak="al", + unicodeslot=0x0D0E, + }, + [0x0D0F]={ + category="lo", + description="MALAYALAM LETTER EE", + direction="l", + linebreak="al", + unicodeslot=0x0D0F, + }, + [0x0D10]={ + category="lo", + description="MALAYALAM LETTER AI", + direction="l", + linebreak="al", + unicodeslot=0x0D10, + }, + [0x0D12]={ + category="lo", + description="MALAYALAM LETTER O", + direction="l", + linebreak="al", + unicodeslot=0x0D12, + }, + [0x0D13]={ + category="lo", + description="MALAYALAM LETTER OO", + direction="l", + linebreak="al", + unicodeslot=0x0D13, + }, + [0x0D14]={ + category="lo", + description="MALAYALAM LETTER AU", + direction="l", + linebreak="al", + unicodeslot=0x0D14, + }, + [0x0D15]={ + category="lo", + description="MALAYALAM LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x0D15, + }, + [0x0D16]={ + category="lo", + description="MALAYALAM LETTER KHA", + direction="l", + linebreak="al", + unicodeslot=0x0D16, + }, + [0x0D17]={ + category="lo", + description="MALAYALAM LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x0D17, + }, + [0x0D18]={ + category="lo", + description="MALAYALAM LETTER GHA", + direction="l", + linebreak="al", + unicodeslot=0x0D18, + }, + [0x0D19]={ + category="lo", + description="MALAYALAM LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0x0D19, + }, + [0x0D1A]={ + category="lo", + description="MALAYALAM LETTER CA", + direction="l", + linebreak="al", + unicodeslot=0x0D1A, + }, + [0x0D1B]={ + category="lo", + description="MALAYALAM LETTER CHA", + direction="l", + linebreak="al", + unicodeslot=0x0D1B, + }, + [0x0D1C]={ + category="lo", + description="MALAYALAM LETTER JA", + direction="l", + linebreak="al", + unicodeslot=0x0D1C, + }, + [0x0D1D]={ + category="lo", + description="MALAYALAM LETTER JHA", + direction="l", + linebreak="al", + unicodeslot=0x0D1D, + }, + [0x0D1E]={ + category="lo", + description="MALAYALAM LETTER NYA", + direction="l", + linebreak="al", + unicodeslot=0x0D1E, + }, + [0x0D1F]={ + category="lo", + description="MALAYALAM LETTER TTA", + direction="l", + linebreak="al", + unicodeslot=0x0D1F, + }, + [0x0D20]={ + category="lo", + description="MALAYALAM LETTER TTHA", + direction="l", + linebreak="al", + unicodeslot=0x0D20, + }, + [0x0D21]={ + category="lo", + description="MALAYALAM LETTER DDA", + direction="l", + linebreak="al", + unicodeslot=0x0D21, + }, + [0x0D22]={ + category="lo", + description="MALAYALAM LETTER DDHA", + direction="l", + linebreak="al", + unicodeslot=0x0D22, + }, + [0x0D23]={ + category="lo", + description="MALAYALAM LETTER NNA", + direction="l", + linebreak="al", + unicodeslot=0x0D23, + }, + [0x0D24]={ + category="lo", + description="MALAYALAM LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x0D24, + }, + [0x0D25]={ + category="lo", + description="MALAYALAM LETTER THA", + direction="l", + linebreak="al", + unicodeslot=0x0D25, + }, + [0x0D26]={ + category="lo", + description="MALAYALAM LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x0D26, + }, + [0x0D27]={ + category="lo", + description="MALAYALAM LETTER DHA", + direction="l", + linebreak="al", + unicodeslot=0x0D27, + }, + [0x0D28]={ + category="lo", + description="MALAYALAM LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x0D28, + }, + [0x0D2A]={ + category="lo", + description="MALAYALAM LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x0D2A, + }, + [0x0D2B]={ + category="lo", + description="MALAYALAM LETTER PHA", + direction="l", + linebreak="al", + unicodeslot=0x0D2B, + }, + [0x0D2C]={ + category="lo", + description="MALAYALAM LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x0D2C, + }, + [0x0D2D]={ + category="lo", + description="MALAYALAM LETTER BHA", + direction="l", + linebreak="al", + unicodeslot=0x0D2D, + }, + [0x0D2E]={ + category="lo", + description="MALAYALAM LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x0D2E, + }, + [0x0D2F]={ + category="lo", + description="MALAYALAM LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x0D2F, + }, + [0x0D30]={ + category="lo", + description="MALAYALAM LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0x0D30, + }, + [0x0D31]={ + category="lo", + description="MALAYALAM LETTER RRA", + direction="l", + linebreak="al", + unicodeslot=0x0D31, + }, + [0x0D32]={ + category="lo", + description="MALAYALAM LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x0D32, + }, + [0x0D33]={ + category="lo", + description="MALAYALAM LETTER LLA", + direction="l", + linebreak="al", + unicodeslot=0x0D33, + }, + [0x0D34]={ + category="lo", + description="MALAYALAM LETTER LLLA", + direction="l", + linebreak="al", + unicodeslot=0x0D34, + }, + [0x0D35]={ + category="lo", + description="MALAYALAM LETTER VA", + direction="l", + linebreak="al", + unicodeslot=0x0D35, + }, + [0x0D36]={ + category="lo", + description="MALAYALAM LETTER SHA", + direction="l", + linebreak="al", + unicodeslot=0x0D36, + }, + [0x0D37]={ + category="lo", + description="MALAYALAM LETTER SSA", + direction="l", + linebreak="al", + unicodeslot=0x0D37, + }, + [0x0D38]={ + category="lo", + description="MALAYALAM LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x0D38, + }, + [0x0D39]={ + category="lo", + description="MALAYALAM LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x0D39, + }, + [0x0D3E]={ + category="mc", + description="MALAYALAM VOWEL SIGN AA", + direction="l", + linebreak="cm", + unicodeslot=0x0D3E, + }, + [0x0D3F]={ + category="mc", + description="MALAYALAM VOWEL SIGN I", + direction="l", + linebreak="cm", + unicodeslot=0x0D3F, + }, + [0x0D40]={ + category="mc", + description="MALAYALAM VOWEL SIGN II", + direction="l", + linebreak="cm", + unicodeslot=0x0D40, + }, + [0x0D41]={ + category="mn", + description="MALAYALAM VOWEL SIGN U", + direction="nsm", + linebreak="cm", + unicodeslot=0x0D41, + }, + [0x0D42]={ + category="mn", + description="MALAYALAM VOWEL SIGN UU", + direction="nsm", + linebreak="cm", + unicodeslot=0x0D42, + }, + [0x0D43]={ + category="mn", + description="MALAYALAM VOWEL SIGN VOCALIC R", + direction="nsm", + linebreak="cm", + unicodeslot=0x0D43, + }, + [0x0D46]={ + category="mc", + description="MALAYALAM VOWEL SIGN E", + direction="l", + linebreak="cm", + unicodeslot=0x0D46, + }, + [0x0D47]={ + category="mc", + description="MALAYALAM VOWEL SIGN EE", + direction="l", + linebreak="cm", + unicodeslot=0x0D47, + }, + [0x0D48]={ + category="mc", + description="MALAYALAM VOWEL SIGN AI", + direction="l", + linebreak="cm", + unicodeslot=0x0D48, + }, + [0x0D4A]={ + category="mc", + description="MALAYALAM VOWEL SIGN O", + direction="l", + linebreak="cm", + specials={ "char", 0x0D46, 0x0D3E }, + unicodeslot=0x0D4A, + }, + [0x0D4B]={ + category="mc", + description="MALAYALAM VOWEL SIGN OO", + direction="l", + linebreak="cm", + specials={ "char", 0x0D47, 0x0D3E }, + unicodeslot=0x0D4B, + }, + [0x0D4C]={ + category="mc", + description="MALAYALAM VOWEL SIGN AU", + direction="l", + linebreak="cm", + specials={ "char", 0x0D46, 0x0D57 }, + unicodeslot=0x0D4C, + }, + [0x0D4D]={ + category="mn", + description="MALAYALAM SIGN VIRAMA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0D4D, + }, + [0x0D57]={ + category="mc", + description="MALAYALAM AU LENGTH MARK", + direction="l", + linebreak="cm", + unicodeslot=0x0D57, + }, + [0x0D60]={ + category="lo", + description="MALAYALAM LETTER VOCALIC RR", + direction="l", + linebreak="al", + unicodeslot=0x0D60, + }, + [0x0D61]={ + category="lo", + description="MALAYALAM LETTER VOCALIC LL", + direction="l", + linebreak="al", + unicodeslot=0x0D61, + }, + [0x0D66]={ + category="nd", + description="MALAYALAM DIGIT ZERO", + direction="l", + linebreak="nu", + unicodeslot=0x0D66, + }, + [0x0D67]={ + category="nd", + description="MALAYALAM DIGIT ONE", + direction="l", + linebreak="nu", + unicodeslot=0x0D67, + }, + [0x0D68]={ + category="nd", + description="MALAYALAM DIGIT TWO", + direction="l", + linebreak="nu", + unicodeslot=0x0D68, + }, + [0x0D69]={ + category="nd", + description="MALAYALAM DIGIT THREE", + direction="l", + linebreak="nu", + unicodeslot=0x0D69, + }, + [0x0D6A]={ + category="nd", + description="MALAYALAM DIGIT FOUR", + direction="l", + linebreak="nu", + unicodeslot=0x0D6A, + }, + [0x0D6B]={ + category="nd", + description="MALAYALAM DIGIT FIVE", + direction="l", + linebreak="nu", + unicodeslot=0x0D6B, + }, + [0x0D6C]={ + category="nd", + description="MALAYALAM DIGIT SIX", + direction="l", + linebreak="nu", + unicodeslot=0x0D6C, + }, + [0x0D6D]={ + category="nd", + description="MALAYALAM DIGIT SEVEN", + direction="l", + linebreak="nu", + unicodeslot=0x0D6D, + }, + [0x0D6E]={ + category="nd", + description="MALAYALAM DIGIT EIGHT", + direction="l", + linebreak="nu", + unicodeslot=0x0D6E, + }, + [0x0D6F]={ + category="nd", + description="MALAYALAM DIGIT NINE", + direction="l", + linebreak="nu", + unicodeslot=0x0D6F, + }, + [0x0D82]={ + category="mc", + description="SINHALA SIGN ANUSVARAYA", + direction="l", + linebreak="cm", + unicodeslot=0x0D82, + }, + [0x0D83]={ + category="mc", + description="SINHALA SIGN VISARGAYA", + direction="l", + linebreak="cm", + unicodeslot=0x0D83, + }, + [0x0D85]={ + category="lo", + description="SINHALA LETTER AYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0D85, + }, + [0x0D86]={ + category="lo", + description="SINHALA LETTER AAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0D86, + }, + [0x0D87]={ + category="lo", + description="SINHALA LETTER AEYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0D87, + }, + [0x0D88]={ + category="lo", + description="SINHALA LETTER AEEYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0D88, + }, + [0x0D89]={ + category="lo", + description="SINHALA LETTER IYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0D89, + }, + [0x0D8A]={ + category="lo", + description="SINHALA LETTER IIYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0D8A, + }, + [0x0D8B]={ + category="lo", + description="SINHALA LETTER UYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0D8B, + }, + [0x0D8C]={ + category="lo", + description="SINHALA LETTER UUYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0D8C, + }, + [0x0D8D]={ + category="lo", + description="SINHALA LETTER IRUYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0D8D, + }, + [0x0D8E]={ + category="lo", + description="SINHALA LETTER IRUUYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0D8E, + }, + [0x0D8F]={ + category="lo", + description="SINHALA LETTER ILUYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0D8F, + }, + [0x0D90]={ + category="lo", + description="SINHALA LETTER ILUUYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0D90, + }, + [0x0D91]={ + category="lo", + description="SINHALA LETTER EYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0D91, + }, + [0x0D92]={ + category="lo", + description="SINHALA LETTER EEYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0D92, + }, + [0x0D93]={ + category="lo", + description="SINHALA LETTER AIYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0D93, + }, + [0x0D94]={ + category="lo", + description="SINHALA LETTER OYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0D94, + }, + [0x0D95]={ + category="lo", + description="SINHALA LETTER OOYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0D95, + }, + [0x0D96]={ + category="lo", + description="SINHALA LETTER AUYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0D96, + }, + [0x0D9A]={ + category="lo", + description="SINHALA LETTER ALPAPRAANA KAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0D9A, + }, + [0x0D9B]={ + category="lo", + description="SINHALA LETTER MAHAAPRAANA KAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0D9B, + }, + [0x0D9C]={ + category="lo", + description="SINHALA LETTER ALPAPRAANA GAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0D9C, + }, + [0x0D9D]={ + category="lo", + description="SINHALA LETTER MAHAAPRAANA GAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0D9D, + }, + [0x0D9E]={ + category="lo", + description="SINHALA LETTER KANTAJA NAASIKYAYA", + direction="l", + linebreak="al", + unicodeslot=0x0D9E, + }, + [0x0D9F]={ + category="lo", + description="SINHALA LETTER SANYAKA GAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0D9F, + }, + [0x0DA0]={ + category="lo", + description="SINHALA LETTER ALPAPRAANA CAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DA0, + }, + [0x0DA1]={ + category="lo", + description="SINHALA LETTER MAHAAPRAANA CAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DA1, + }, + [0x0DA2]={ + category="lo", + description="SINHALA LETTER ALPAPRAANA JAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DA2, + }, + [0x0DA3]={ + category="lo", + description="SINHALA LETTER MAHAAPRAANA JAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DA3, + }, + [0x0DA4]={ + category="lo", + description="SINHALA LETTER TAALUJA NAASIKYAYA", + direction="l", + linebreak="al", + unicodeslot=0x0DA4, + }, + [0x0DA5]={ + category="lo", + description="SINHALA LETTER TAALUJA SANYOOGA NAAKSIKYAYA", + direction="l", + linebreak="al", + unicodeslot=0x0DA5, + }, + [0x0DA6]={ + category="lo", + description="SINHALA LETTER SANYAKA JAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DA6, + }, + [0x0DA7]={ + category="lo", + description="SINHALA LETTER ALPAPRAANA TTAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DA7, + }, + [0x0DA8]={ + category="lo", + description="SINHALA LETTER MAHAAPRAANA TTAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DA8, + }, + [0x0DA9]={ + category="lo", + description="SINHALA LETTER ALPAPRAANA DDAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DA9, + }, + [0x0DAA]={ + category="lo", + description="SINHALA LETTER MAHAAPRAANA DDAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DAA, + }, + [0x0DAB]={ + category="lo", + description="SINHALA LETTER MUURDHAJA NAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DAB, + }, + [0x0DAC]={ + category="lo", + description="SINHALA LETTER SANYAKA DDAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DAC, + }, + [0x0DAD]={ + category="lo", + description="SINHALA LETTER ALPAPRAANA TAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DAD, + }, + [0x0DAE]={ + category="lo", + description="SINHALA LETTER MAHAAPRAANA TAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DAE, + }, + [0x0DAF]={ + category="lo", + description="SINHALA LETTER ALPAPRAANA DAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DAF, + }, + [0x0DB0]={ + category="lo", + description="SINHALA LETTER MAHAAPRAANA DAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DB0, + }, + [0x0DB1]={ + category="lo", + description="SINHALA LETTER DANTAJA NAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DB1, + }, + [0x0DB3]={ + category="lo", + description="SINHALA LETTER SANYAKA DAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DB3, + }, + [0x0DB4]={ + category="lo", + description="SINHALA LETTER ALPAPRAANA PAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DB4, + }, + [0x0DB5]={ + category="lo", + description="SINHALA LETTER MAHAAPRAANA PAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DB5, + }, + [0x0DB6]={ + category="lo", + description="SINHALA LETTER ALPAPRAANA BAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DB6, + }, + [0x0DB7]={ + category="lo", + description="SINHALA LETTER MAHAAPRAANA BAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DB7, + }, + [0x0DB8]={ + category="lo", + description="SINHALA LETTER MAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DB8, + }, + [0x0DB9]={ + category="lo", + description="SINHALA LETTER AMBA BAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DB9, + }, + [0x0DBA]={ + category="lo", + description="SINHALA LETTER YAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DBA, + }, + [0x0DBB]={ + category="lo", + description="SINHALA LETTER RAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DBB, + }, + [0x0DBD]={ + category="lo", + description="SINHALA LETTER DANTAJA LAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DBD, + }, + [0x0DC0]={ + category="lo", + description="SINHALA LETTER VAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DC0, + }, + [0x0DC1]={ + category="lo", + description="SINHALA LETTER TAALUJA SAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DC1, + }, + [0x0DC2]={ + category="lo", + description="SINHALA LETTER MUURDHAJA SAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DC2, + }, + [0x0DC3]={ + category="lo", + description="SINHALA LETTER DANTAJA SAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DC3, + }, + [0x0DC4]={ + category="lo", + description="SINHALA LETTER HAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DC4, + }, + [0x0DC5]={ + category="lo", + description="SINHALA LETTER MUURDHAJA LAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DC5, + }, + [0x0DC6]={ + category="lo", + description="SINHALA LETTER FAYANNA", + direction="l", + linebreak="al", + unicodeslot=0x0DC6, + }, + [0x0DCA]={ + category="mn", + description="SINHALA SIGN AL-LAKUNA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0DCA, + }, + [0x0DCF]={ + category="mc", + description="SINHALA VOWEL SIGN AELA-PILLA", + direction="l", + linebreak="cm", + unicodeslot=0x0DCF, + }, + [0x0DD0]={ + category="mc", + description="SINHALA VOWEL SIGN KETTI AEDA-PILLA", + direction="l", + linebreak="cm", + unicodeslot=0x0DD0, + }, + [0x0DD1]={ + category="mc", + description="SINHALA VOWEL SIGN DIGA AEDA-PILLA", + direction="l", + linebreak="cm", + unicodeslot=0x0DD1, + }, + [0x0DD2]={ + category="mn", + description="SINHALA VOWEL SIGN KETTI IS-PILLA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0DD2, + }, + [0x0DD3]={ + category="mn", + description="SINHALA VOWEL SIGN DIGA IS-PILLA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0DD3, + }, + [0x0DD4]={ + category="mn", + description="SINHALA VOWEL SIGN KETTI PAA-PILLA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0DD4, + }, + [0x0DD6]={ + category="mn", + description="SINHALA VOWEL SIGN DIGA PAA-PILLA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0DD6, + }, + [0x0DD8]={ + category="mc", + description="SINHALA VOWEL SIGN GAETTA-PILLA", + direction="l", + linebreak="cm", + unicodeslot=0x0DD8, + }, + [0x0DD9]={ + category="mc", + description="SINHALA VOWEL SIGN KOMBUVA", + direction="l", + linebreak="cm", + unicodeslot=0x0DD9, + }, + [0x0DDA]={ + category="mc", + description="SINHALA VOWEL SIGN DIGA KOMBUVA", + direction="l", + linebreak="cm", + specials={ "char", 0x0DD9, 0x0DCA }, + unicodeslot=0x0DDA, + }, + [0x0DDB]={ + category="mc", + description="SINHALA VOWEL SIGN KOMBU DEKA", + direction="l", + linebreak="cm", + unicodeslot=0x0DDB, + }, + [0x0DDC]={ + category="mc", + description="SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA", + direction="l", + linebreak="cm", + specials={ "char", 0x0DD9, 0x0DCF }, + unicodeslot=0x0DDC, + }, + [0x0DDD]={ + category="mc", + description="SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA", + direction="l", + linebreak="cm", + specials={ "char", 0x0DDC, 0x0DCA }, + unicodeslot=0x0DDD, + }, + [0x0DDE]={ + category="mc", + description="SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA", + direction="l", + linebreak="cm", + specials={ "char", 0x0DD9, 0x0DDF }, + unicodeslot=0x0DDE, + }, + [0x0DDF]={ + category="mc", + description="SINHALA VOWEL SIGN GAYANUKITTA", + direction="l", + linebreak="cm", + unicodeslot=0x0DDF, + }, + [0x0DF2]={ + category="mc", + description="SINHALA VOWEL SIGN DIGA GAETTA-PILLA", + direction="l", + linebreak="cm", + unicodeslot=0x0DF2, + }, + [0x0DF3]={ + category="mc", + description="SINHALA VOWEL SIGN DIGA GAYANUKITTA", + direction="l", + linebreak="cm", + unicodeslot=0x0DF3, + }, + [0x0DF4]={ + category="po", + description="SINHALA PUNCTUATION KUNDDALIYA", + direction="l", + linebreak="al", + unicodeslot=0x0DF4, + }, + [0x0E01]={ + category="lo", + description="THAI CHARACTER KO KAI", + direction="l", + linebreak="sa", + unicodeslot=0x0E01, + }, + [0x0E02]={ + category="lo", + description="THAI CHARACTER KHO KHAI", + direction="l", + linebreak="sa", + unicodeslot=0x0E02, + }, + [0x0E03]={ + category="lo", + description="THAI CHARACTER KHO KHUAT", + direction="l", + linebreak="sa", + unicodeslot=0x0E03, + }, + [0x0E04]={ + category="lo", + description="THAI CHARACTER KHO KHWAI", + direction="l", + linebreak="sa", + unicodeslot=0x0E04, + }, + [0x0E05]={ + category="lo", + description="THAI CHARACTER KHO KHON", + direction="l", + linebreak="sa", + unicodeslot=0x0E05, + }, + [0x0E06]={ + category="lo", + description="THAI CHARACTER KHO RAKHANG", + direction="l", + linebreak="sa", + unicodeslot=0x0E06, + }, + [0x0E07]={ + category="lo", + description="THAI CHARACTER NGO NGU", + direction="l", + linebreak="sa", + unicodeslot=0x0E07, + }, + [0x0E08]={ + category="lo", + description="THAI CHARACTER CHO CHAN", + direction="l", + linebreak="sa", + unicodeslot=0x0E08, + }, + [0x0E09]={ + category="lo", + description="THAI CHARACTER CHO CHING", + direction="l", + linebreak="sa", + unicodeslot=0x0E09, + }, + [0x0E0A]={ + category="lo", + description="THAI CHARACTER CHO CHANG", + direction="l", + linebreak="sa", + unicodeslot=0x0E0A, + }, + [0x0E0B]={ + category="lo", + description="THAI CHARACTER SO SO", + direction="l", + linebreak="sa", + unicodeslot=0x0E0B, + }, + [0x0E0C]={ + category="lo", + description="THAI CHARACTER CHO CHOE", + direction="l", + linebreak="sa", + unicodeslot=0x0E0C, + }, + [0x0E0D]={ + category="lo", + description="THAI CHARACTER YO YING", + direction="l", + linebreak="sa", + unicodeslot=0x0E0D, + }, + [0x0E0E]={ + category="lo", + description="THAI CHARACTER DO CHADA", + direction="l", + linebreak="sa", + unicodeslot=0x0E0E, + }, + [0x0E0F]={ + category="lo", + description="THAI CHARACTER TO PATAK", + direction="l", + linebreak="sa", + unicodeslot=0x0E0F, + }, + [0x0E10]={ + category="lo", + description="THAI CHARACTER THO THAN", + direction="l", + linebreak="sa", + unicodeslot=0x0E10, + }, + [0x0E11]={ + category="lo", + description="THAI CHARACTER THO NANGMONTHO", + direction="l", + linebreak="sa", + unicodeslot=0x0E11, + }, + [0x0E12]={ + category="lo", + description="THAI CHARACTER THO PHUTHAO", + direction="l", + linebreak="sa", + unicodeslot=0x0E12, + }, + [0x0E13]={ + category="lo", + description="THAI CHARACTER NO NEN", + direction="l", + linebreak="sa", + unicodeslot=0x0E13, + }, + [0x0E14]={ + category="lo", + description="THAI CHARACTER DO DEK", + direction="l", + linebreak="sa", + unicodeslot=0x0E14, + }, + [0x0E15]={ + category="lo", + description="THAI CHARACTER TO TAO", + direction="l", + linebreak="sa", + unicodeslot=0x0E15, + }, + [0x0E16]={ + category="lo", + description="THAI CHARACTER THO THUNG", + direction="l", + linebreak="sa", + unicodeslot=0x0E16, + }, + [0x0E17]={ + category="lo", + description="THAI CHARACTER THO THAHAN", + direction="l", + linebreak="sa", + unicodeslot=0x0E17, + }, + [0x0E18]={ + category="lo", + description="THAI CHARACTER THO THONG", + direction="l", + linebreak="sa", + unicodeslot=0x0E18, + }, + [0x0E19]={ + category="lo", + description="THAI CHARACTER NO NU", + direction="l", + linebreak="sa", + unicodeslot=0x0E19, + }, + [0x0E1A]={ + category="lo", + description="THAI CHARACTER BO BAIMAI", + direction="l", + linebreak="sa", + unicodeslot=0x0E1A, + }, + [0x0E1B]={ + category="lo", + description="THAI CHARACTER PO PLA", + direction="l", + linebreak="sa", + unicodeslot=0x0E1B, + }, + [0x0E1C]={ + category="lo", + description="THAI CHARACTER PHO PHUNG", + direction="l", + linebreak="sa", + unicodeslot=0x0E1C, + }, + [0x0E1D]={ + category="lo", + description="THAI CHARACTER FO FA", + direction="l", + linebreak="sa", + unicodeslot=0x0E1D, + }, + [0x0E1E]={ + category="lo", + description="THAI CHARACTER PHO PHAN", + direction="l", + linebreak="sa", + unicodeslot=0x0E1E, + }, + [0x0E1F]={ + category="lo", + description="THAI CHARACTER FO FAN", + direction="l", + linebreak="sa", + unicodeslot=0x0E1F, + }, + [0x0E20]={ + category="lo", + description="THAI CHARACTER PHO SAMPHAO", + direction="l", + linebreak="sa", + unicodeslot=0x0E20, + }, + [0x0E21]={ + category="lo", + description="THAI CHARACTER MO MA", + direction="l", + linebreak="sa", + unicodeslot=0x0E21, + }, + [0x0E22]={ + category="lo", + description="THAI CHARACTER YO YAK", + direction="l", + linebreak="sa", + unicodeslot=0x0E22, + }, + [0x0E23]={ + category="lo", + description="THAI CHARACTER RO RUA", + direction="l", + linebreak="sa", + unicodeslot=0x0E23, + }, + [0x0E24]={ + category="lo", + description="THAI CHARACTER RU", + direction="l", + linebreak="sa", + unicodeslot=0x0E24, + }, + [0x0E25]={ + category="lo", + description="THAI CHARACTER LO LING", + direction="l", + linebreak="sa", + unicodeslot=0x0E25, + }, + [0x0E26]={ + category="lo", + description="THAI CHARACTER LU", + direction="l", + linebreak="sa", + unicodeslot=0x0E26, + }, + [0x0E27]={ + category="lo", + description="THAI CHARACTER WO WAEN", + direction="l", + linebreak="sa", + unicodeslot=0x0E27, + }, + [0x0E28]={ + category="lo", + description="THAI CHARACTER SO SALA", + direction="l", + linebreak="sa", + unicodeslot=0x0E28, + }, + [0x0E29]={ + category="lo", + description="THAI CHARACTER SO RUSI", + direction="l", + linebreak="sa", + unicodeslot=0x0E29, + }, + [0x0E2A]={ + category="lo", + description="THAI CHARACTER SO SUA", + direction="l", + linebreak="sa", + unicodeslot=0x0E2A, + }, + [0x0E2B]={ + category="lo", + description="THAI CHARACTER HO HIP", + direction="l", + linebreak="sa", + unicodeslot=0x0E2B, + }, + [0x0E2C]={ + category="lo", + description="THAI CHARACTER LO CHULA", + direction="l", + linebreak="sa", + unicodeslot=0x0E2C, + }, + [0x0E2D]={ + category="lo", + description="THAI CHARACTER O ANG", + direction="l", + linebreak="sa", + unicodeslot=0x0E2D, + }, + [0x0E2E]={ + category="lo", + description="THAI CHARACTER HO NOKHUK", + direction="l", + linebreak="sa", + unicodeslot=0x0E2E, + }, + [0x0E2F]={ + category="lo", + description="THAI CHARACTER PAIYANNOI", + direction="l", + linebreak="sa", + unicodeslot=0x0E2F, + }, + [0x0E30]={ + category="lo", + description="THAI CHARACTER SARA A", + direction="l", + linebreak="sa", + unicodeslot=0x0E30, + }, + [0x0E31]={ + category="mn", + description="THAI CHARACTER MAI HAN-AKAT", + direction="nsm", + linebreak="sa", + unicodeslot=0x0E31, + }, + [0x0E32]={ + category="lo", + description="THAI CHARACTER SARA AA", + direction="l", + linebreak="sa", + unicodeslot=0x0E32, + }, + [0x0E33]={ + category="lo", + description="THAI CHARACTER SARA AM", + direction="l", + linebreak="sa", + specials={ "compat", 0x0E4D, 0x0E32 }, + unicodeslot=0x0E33, + }, + [0x0E34]={ + category="mn", + description="THAI CHARACTER SARA I", + direction="nsm", + linebreak="sa", + unicodeslot=0x0E34, + }, + [0x0E35]={ + category="mn", + description="THAI CHARACTER SARA II", + direction="nsm", + linebreak="sa", + unicodeslot=0x0E35, + }, + [0x0E36]={ + category="mn", + description="THAI CHARACTER SARA UE", + direction="nsm", + linebreak="sa", + unicodeslot=0x0E36, + }, + [0x0E37]={ + category="mn", + description="THAI CHARACTER SARA UEE", + direction="nsm", + linebreak="sa", + unicodeslot=0x0E37, + }, + [0x0E38]={ + category="mn", + description="THAI CHARACTER SARA U", + direction="nsm", + linebreak="sa", + unicodeslot=0x0E38, + }, + [0x0E39]={ + category="mn", + description="THAI CHARACTER SARA UU", + direction="nsm", + linebreak="sa", + unicodeslot=0x0E39, + }, + [0x0E3A]={ + category="mn", + description="THAI CHARACTER PHINTHU", + direction="nsm", + linebreak="sa", + unicodeslot=0x0E3A, + }, + [0x0E3F]={ + category="sc", + description="THAI CURRENCY SYMBOL BAHT", + direction="et", + linebreak="pr", + unicodeslot=0x0E3F, + }, + [0x0E40]={ + category="lo", + description="THAI CHARACTER SARA E", + direction="l", + linebreak="sa", + unicodeslot=0x0E40, + }, + [0x0E41]={ + category="lo", + description="THAI CHARACTER SARA AE", + direction="l", + linebreak="sa", + unicodeslot=0x0E41, + }, + [0x0E42]={ + category="lo", + description="THAI CHARACTER SARA O", + direction="l", + linebreak="sa", + unicodeslot=0x0E42, + }, + [0x0E43]={ + category="lo", + description="THAI CHARACTER SARA AI MAIMUAN", + direction="l", + linebreak="sa", + unicodeslot=0x0E43, + }, + [0x0E44]={ + category="lo", + description="THAI CHARACTER SARA AI MAIMALAI", + direction="l", + linebreak="sa", + unicodeslot=0x0E44, + }, + [0x0E45]={ + category="lo", + description="THAI CHARACTER LAKKHANGYAO", + direction="l", + linebreak="sa", + unicodeslot=0x0E45, + }, + [0x0E46]={ + category="lm", + description="THAI CHARACTER MAIYAMOK", + direction="l", + linebreak="sa", + unicodeslot=0x0E46, + }, + [0x0E47]={ + category="mn", + description="THAI CHARACTER MAITAIKHU", + direction="nsm", + linebreak="sa", + unicodeslot=0x0E47, + }, + [0x0E48]={ + category="mn", + description="THAI CHARACTER MAI EK", + direction="nsm", + linebreak="sa", + unicodeslot=0x0E48, + }, + [0x0E49]={ + category="mn", + description="THAI CHARACTER MAI THO", + direction="nsm", + linebreak="sa", + unicodeslot=0x0E49, + }, + [0x0E4A]={ + category="mn", + description="THAI CHARACTER MAI TRI", + direction="nsm", + linebreak="sa", + unicodeslot=0x0E4A, + }, + [0x0E4B]={ + category="mn", + description="THAI CHARACTER MAI CHATTAWA", + direction="nsm", + linebreak="sa", + unicodeslot=0x0E4B, + }, + [0x0E4C]={ + category="mn", + description="THAI CHARACTER THANTHAKHAT", + direction="nsm", + linebreak="sa", + unicodeslot=0x0E4C, + }, + [0x0E4D]={ + category="mn", + description="THAI CHARACTER NIKHAHIT", + direction="nsm", + linebreak="sa", + unicodeslot=0x0E4D, + }, + [0x0E4E]={ + category="mn", + description="THAI CHARACTER YAMAKKAN", + direction="nsm", + linebreak="sa", + unicodeslot=0x0E4E, + }, + [0x0E4F]={ + category="po", + description="THAI CHARACTER FONGMAN", + direction="l", + linebreak="al", + unicodeslot=0x0E4F, + }, + [0x0E50]={ + category="nd", + description="THAI DIGIT ZERO", + direction="l", + linebreak="nu", + unicodeslot=0x0E50, + }, + [0x0E51]={ + category="nd", + description="THAI DIGIT ONE", + direction="l", + linebreak="nu", + unicodeslot=0x0E51, + }, + [0x0E52]={ + category="nd", + description="THAI DIGIT TWO", + direction="l", + linebreak="nu", + unicodeslot=0x0E52, + }, + [0x0E53]={ + category="nd", + description="THAI DIGIT THREE", + direction="l", + linebreak="nu", + unicodeslot=0x0E53, + }, + [0x0E54]={ + category="nd", + description="THAI DIGIT FOUR", + direction="l", + linebreak="nu", + unicodeslot=0x0E54, + }, + [0x0E55]={ + category="nd", + description="THAI DIGIT FIVE", + direction="l", + linebreak="nu", + unicodeslot=0x0E55, + }, + [0x0E56]={ + category="nd", + description="THAI DIGIT SIX", + direction="l", + linebreak="nu", + unicodeslot=0x0E56, + }, + [0x0E57]={ + category="nd", + description="THAI DIGIT SEVEN", + direction="l", + linebreak="nu", + unicodeslot=0x0E57, + }, + [0x0E58]={ + category="nd", + description="THAI DIGIT EIGHT", + direction="l", + linebreak="nu", + unicodeslot=0x0E58, + }, + [0x0E59]={ + category="nd", + description="THAI DIGIT NINE", + direction="l", + linebreak="nu", + unicodeslot=0x0E59, + }, + [0x0E5A]={ + category="po", + description="THAI CHARACTER ANGKHANKHU", + direction="l", + linebreak="ba", + unicodeslot=0x0E5A, + }, + [0x0E5B]={ + category="po", + description="THAI CHARACTER KHOMUT", + direction="l", + linebreak="ba", + unicodeslot=0x0E5B, + }, + [0x0E81]={ + category="lo", + description="LAO LETTER KO", + direction="l", + linebreak="sa", + unicodeslot=0x0E81, + }, + [0x0E82]={ + category="lo", + description="LAO LETTER KHO SUNG", + direction="l", + linebreak="sa", + unicodeslot=0x0E82, + }, + [0x0E84]={ + category="lo", + description="LAO LETTER KHO TAM", + direction="l", + linebreak="sa", + unicodeslot=0x0E84, + }, + [0x0E87]={ + category="lo", + description="LAO LETTER NGO", + direction="l", + linebreak="sa", + unicodeslot=0x0E87, + }, + [0x0E88]={ + category="lo", + description="LAO LETTER CO", + direction="l", + linebreak="sa", + unicodeslot=0x0E88, + }, + [0x0E8A]={ + category="lo", + description="LAO LETTER SO TAM", + direction="l", + linebreak="sa", + unicodeslot=0x0E8A, + }, + [0x0E8D]={ + category="lo", + description="LAO LETTER NYO", + direction="l", + linebreak="sa", + unicodeslot=0x0E8D, + }, + [0x0E94]={ + category="lo", + description="LAO LETTER DO", + direction="l", + linebreak="sa", + unicodeslot=0x0E94, + }, + [0x0E95]={ + category="lo", + description="LAO LETTER TO", + direction="l", + linebreak="sa", + unicodeslot=0x0E95, + }, + [0x0E96]={ + category="lo", + description="LAO LETTER THO SUNG", + direction="l", + linebreak="sa", + unicodeslot=0x0E96, + }, + [0x0E97]={ + category="lo", + description="LAO LETTER THO TAM", + direction="l", + linebreak="sa", + unicodeslot=0x0E97, + }, + [0x0E99]={ + category="lo", + description="LAO LETTER NO", + direction="l", + linebreak="sa", + unicodeslot=0x0E99, + }, + [0x0E9A]={ + category="lo", + description="LAO LETTER BO", + direction="l", + linebreak="sa", + unicodeslot=0x0E9A, + }, + [0x0E9B]={ + category="lo", + description="LAO LETTER PO", + direction="l", + linebreak="sa", + unicodeslot=0x0E9B, + }, + [0x0E9C]={ + category="lo", + description="LAO LETTER PHO SUNG", + direction="l", + linebreak="sa", + unicodeslot=0x0E9C, + }, + [0x0E9D]={ + category="lo", + description="LAO LETTER FO TAM", + direction="l", + linebreak="sa", + unicodeslot=0x0E9D, + }, + [0x0E9E]={ + category="lo", + description="LAO LETTER PHO TAM", + direction="l", + linebreak="sa", + unicodeslot=0x0E9E, + }, + [0x0E9F]={ + category="lo", + description="LAO LETTER FO SUNG", + direction="l", + linebreak="sa", + unicodeslot=0x0E9F, + }, + [0x0EA1]={ + category="lo", + description="LAO LETTER MO", + direction="l", + linebreak="sa", + unicodeslot=0x0EA1, + }, + [0x0EA2]={ + category="lo", + description="LAO LETTER YO", + direction="l", + linebreak="sa", + unicodeslot=0x0EA2, + }, + [0x0EA3]={ + category="lo", + description="LAO LETTER LO LING", + direction="l", + linebreak="sa", + unicodeslot=0x0EA3, + }, + [0x0EA5]={ + category="lo", + description="LAO LETTER LO LOOT", + direction="l", + linebreak="sa", + unicodeslot=0x0EA5, + }, + [0x0EA7]={ + category="lo", + description="LAO LETTER WO", + direction="l", + linebreak="sa", + unicodeslot=0x0EA7, + }, + [0x0EAA]={ + category="lo", + description="LAO LETTER SO SUNG", + direction="l", + linebreak="sa", + unicodeslot=0x0EAA, + }, + [0x0EAB]={ + category="lo", + description="LAO LETTER HO SUNG", + direction="l", + linebreak="sa", + unicodeslot=0x0EAB, + }, + [0x0EAD]={ + category="lo", + description="LAO LETTER O", + direction="l", + linebreak="sa", + unicodeslot=0x0EAD, + }, + [0x0EAE]={ + category="lo", + description="LAO LETTER HO TAM", + direction="l", + linebreak="sa", + unicodeslot=0x0EAE, + }, + [0x0EAF]={ + category="lo", + description="LAO ELLIPSIS", + direction="l", + linebreak="sa", + unicodeslot=0x0EAF, + }, + [0x0EB0]={ + category="lo", + description="LAO VOWEL SIGN A", + direction="l", + linebreak="sa", + unicodeslot=0x0EB0, + }, + [0x0EB1]={ + category="mn", + description="LAO VOWEL SIGN MAI KAN", + direction="nsm", + linebreak="sa", + unicodeslot=0x0EB1, + }, + [0x0EB2]={ + category="lo", + description="LAO VOWEL SIGN AA", + direction="l", + linebreak="sa", + unicodeslot=0x0EB2, + }, + [0x0EB3]={ + category="lo", + description="LAO VOWEL SIGN AM", + direction="l", + linebreak="sa", + specials={ "compat", 0x0ECD, 0x0EB2 }, + unicodeslot=0x0EB3, + }, + [0x0EB4]={ + category="mn", + description="LAO VOWEL SIGN I", + direction="nsm", + linebreak="sa", + unicodeslot=0x0EB4, + }, + [0x0EB5]={ + category="mn", + description="LAO VOWEL SIGN II", + direction="nsm", + linebreak="sa", + unicodeslot=0x0EB5, + }, + [0x0EB6]={ + category="mn", + description="LAO VOWEL SIGN Y", + direction="nsm", + linebreak="sa", + unicodeslot=0x0EB6, + }, + [0x0EB7]={ + category="mn", + description="LAO VOWEL SIGN YY", + direction="nsm", + linebreak="sa", + unicodeslot=0x0EB7, + }, + [0x0EB8]={ + category="mn", + description="LAO VOWEL SIGN U", + direction="nsm", + linebreak="sa", + unicodeslot=0x0EB8, + }, + [0x0EB9]={ + category="mn", + description="LAO VOWEL SIGN UU", + direction="nsm", + linebreak="sa", + unicodeslot=0x0EB9, + }, + [0x0EBB]={ + category="mn", + description="LAO VOWEL SIGN MAI KON", + direction="nsm", + linebreak="sa", + unicodeslot=0x0EBB, + }, + [0x0EBC]={ + category="mn", + description="LAO SEMIVOWEL SIGN LO", + direction="nsm", + linebreak="sa", + unicodeslot=0x0EBC, + }, + [0x0EBD]={ + category="lo", + description="LAO SEMIVOWEL SIGN NYO", + direction="l", + linebreak="sa", + unicodeslot=0x0EBD, + }, + [0x0EC0]={ + category="lo", + description="LAO VOWEL SIGN E", + direction="l", + linebreak="sa", + unicodeslot=0x0EC0, + }, + [0x0EC1]={ + category="lo", + description="LAO VOWEL SIGN EI", + direction="l", + linebreak="sa", + unicodeslot=0x0EC1, + }, + [0x0EC2]={ + category="lo", + description="LAO VOWEL SIGN O", + direction="l", + linebreak="sa", + unicodeslot=0x0EC2, + }, + [0x0EC3]={ + category="lo", + description="LAO VOWEL SIGN AY", + direction="l", + linebreak="sa", + unicodeslot=0x0EC3, + }, + [0x0EC4]={ + category="lo", + description="LAO VOWEL SIGN AI", + direction="l", + linebreak="sa", + unicodeslot=0x0EC4, + }, + [0x0EC6]={ + category="lm", + description="LAO KO LA", + direction="l", + linebreak="sa", + unicodeslot=0x0EC6, + }, + [0x0EC8]={ + category="mn", + description="LAO TONE MAI EK", + direction="nsm", + linebreak="sa", + unicodeslot=0x0EC8, + }, + [0x0EC9]={ + category="mn", + description="LAO TONE MAI THO", + direction="nsm", + linebreak="sa", + unicodeslot=0x0EC9, + }, + [0x0ECA]={ + category="mn", + description="LAO TONE MAI TI", + direction="nsm", + linebreak="sa", + unicodeslot=0x0ECA, + }, + [0x0ECB]={ + category="mn", + description="LAO TONE MAI CATAWA", + direction="nsm", + linebreak="sa", + unicodeslot=0x0ECB, + }, + [0x0ECC]={ + category="mn", + description="LAO CANCELLATION MARK", + direction="nsm", + linebreak="sa", + unicodeslot=0x0ECC, + }, + [0x0ECD]={ + category="mn", + description="LAO NIGGAHITA", + direction="nsm", + linebreak="sa", + unicodeslot=0x0ECD, + }, + [0x0ED0]={ + category="nd", + description="LAO DIGIT ZERO", + direction="l", + linebreak="nu", + unicodeslot=0x0ED0, + }, + [0x0ED1]={ + category="nd", + description="LAO DIGIT ONE", + direction="l", + linebreak="nu", + unicodeslot=0x0ED1, + }, + [0x0ED2]={ + category="nd", + description="LAO DIGIT TWO", + direction="l", + linebreak="nu", + unicodeslot=0x0ED2, + }, + [0x0ED3]={ + category="nd", + description="LAO DIGIT THREE", + direction="l", + linebreak="nu", + unicodeslot=0x0ED3, + }, + [0x0ED4]={ + category="nd", + description="LAO DIGIT FOUR", + direction="l", + linebreak="nu", + unicodeslot=0x0ED4, + }, + [0x0ED5]={ + category="nd", + description="LAO DIGIT FIVE", + direction="l", + linebreak="nu", + unicodeslot=0x0ED5, + }, + [0x0ED6]={ + category="nd", + description="LAO DIGIT SIX", + direction="l", + linebreak="nu", + unicodeslot=0x0ED6, + }, + [0x0ED7]={ + category="nd", + description="LAO DIGIT SEVEN", + direction="l", + linebreak="nu", + unicodeslot=0x0ED7, + }, + [0x0ED8]={ + category="nd", + description="LAO DIGIT EIGHT", + direction="l", + linebreak="nu", + unicodeslot=0x0ED8, + }, + [0x0ED9]={ + category="nd", + description="LAO DIGIT NINE", + direction="l", + linebreak="nu", + unicodeslot=0x0ED9, + }, + [0x0EDC]={ + category="lo", + description="LAO HO NO", + direction="l", + linebreak="sa", + specials={ "compat", 0x0EAB, 0x0E99 }, + unicodeslot=0x0EDC, + }, + [0x0EDD]={ + category="lo", + description="LAO HO MO", + direction="l", + linebreak="sa", + specials={ "compat", 0x0EAB, 0x0EA1 }, + unicodeslot=0x0EDD, + }, + [0x0F00]={ + category="lo", + description="TIBETAN SYLLABLE OM", + direction="l", + linebreak="al", + unicodeslot=0x0F00, + }, + [0x0F01]={ + category="so", + description="TIBETAN MARK GTER YIG MGO TRUNCATED A", + direction="l", + linebreak="bb", + unicodeslot=0x0F01, + }, + [0x0F02]={ + category="so", + description="TIBETAN MARK GTER YIG MGO -UM RNAM BCAD MA", + direction="l", + linebreak="bb", + unicodeslot=0x0F02, + }, + [0x0F03]={ + category="so", + description="TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA", + direction="l", + linebreak="bb", + unicodeslot=0x0F03, + }, + [0x0F04]={ + category="po", + description="TIBETAN MARK INITIAL YIG MGO MDUN MA", + direction="l", + linebreak="bb", + unicodeslot=0x0F04, + }, + [0x0F05]={ + category="po", + description="TIBETAN MARK CLOSING YIG MGO SGAB MA", + direction="l", + linebreak="al", + unicodeslot=0x0F05, + }, + [0x0F06]={ + category="po", + description="TIBETAN MARK CARET YIG MGO PHUR SHAD MA", + direction="l", + linebreak="bb", + unicodeslot=0x0F06, + }, + [0x0F07]={ + category="po", + description="TIBETAN MARK YIG MGO TSHEG SHAD MA", + direction="l", + linebreak="bb", + unicodeslot=0x0F07, + }, + [0x0F08]={ + category="po", + description="TIBETAN MARK SBRUL SHAD", + direction="l", + linebreak="gl", + unicodeslot=0x0F08, + }, + [0x0F09]={ + category="po", + description="TIBETAN MARK BSKUR YIG MGO", + direction="l", + linebreak="bb", + unicodeslot=0x0F09, + }, + [0x0F0A]={ + category="po", + description="TIBETAN MARK BKA- SHOG YIG MGO", + direction="l", + linebreak="bb", + unicodeslot=0x0F0A, + }, + [0x0F0B]={ + category="po", + description="TIBETAN MARK INTERSYLLABIC TSHEG", + direction="l", + linebreak="ba", + unicodeslot=0x0F0B, + }, + [0x0F0C]={ + category="po", + description="TIBETAN MARK DELIMITER TSHEG BSTAR", + direction="l", + linebreak="gl", + specials={ "nobreak", 0x0F0B }, + unicodeslot=0x0F0C, + }, + [0x0F0D]={ + category="po", + description="TIBETAN MARK SHAD", + direction="l", + linebreak="ex", + unicodeslot=0x0F0D, + }, + [0x0F0E]={ + category="po", + description="TIBETAN MARK NYIS SHAD", + direction="l", + linebreak="ex", + unicodeslot=0x0F0E, + }, + [0x0F0F]={ + category="po", + description="TIBETAN MARK TSHEG SHAD", + direction="l", + linebreak="ex", + unicodeslot=0x0F0F, + }, + [0x0F10]={ + category="po", + description="TIBETAN MARK NYIS TSHEG SHAD", + direction="l", + linebreak="ex", + unicodeslot=0x0F10, + }, + [0x0F11]={ + category="po", + description="TIBETAN MARK RIN CHEN SPUNGS SHAD", + direction="l", + linebreak="ex", + unicodeslot=0x0F11, + }, + [0x0F12]={ + category="po", + description="TIBETAN MARK RGYA GRAM SHAD", + direction="l", + linebreak="gl", + unicodeslot=0x0F12, + }, + [0x0F13]={ + category="so", + description="TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN", + direction="l", + linebreak="al", + unicodeslot=0x0F13, + }, + [0x0F14]={ + category="so", + description="TIBETAN MARK GTER TSHEG", + direction="l", + linebreak="ex", + unicodeslot=0x0F14, + }, + [0x0F15]={ + category="so", + description="TIBETAN LOGOTYPE SIGN CHAD RTAGS", + direction="l", + linebreak="al", + unicodeslot=0x0F15, + }, + [0x0F16]={ + category="so", + description="TIBETAN LOGOTYPE SIGN LHAG RTAGS", + direction="l", + linebreak="al", + unicodeslot=0x0F16, + }, + [0x0F17]={ + category="so", + description="TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS", + direction="l", + linebreak="al", + unicodeslot=0x0F17, + }, + [0x0F18]={ + category="mn", + description="TIBETAN ASTROLOGICAL SIGN -KHYUD PA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F18, + }, + [0x0F19]={ + category="mn", + description="TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F19, + }, + [0x0F1A]={ + category="so", + description="TIBETAN SIGN RDEL DKAR GCIG", + direction="l", + linebreak="al", + unicodeslot=0x0F1A, + }, + [0x0F1B]={ + category="so", + description="TIBETAN SIGN RDEL DKAR GNYIS", + direction="l", + linebreak="al", + unicodeslot=0x0F1B, + }, + [0x0F1C]={ + category="so", + description="TIBETAN SIGN RDEL DKAR GSUM", + direction="l", + linebreak="al", + unicodeslot=0x0F1C, + }, + [0x0F1D]={ + category="so", + description="TIBETAN SIGN RDEL NAG GCIG", + direction="l", + linebreak="al", + unicodeslot=0x0F1D, + }, + [0x0F1E]={ + category="so", + description="TIBETAN SIGN RDEL NAG GNYIS", + direction="l", + linebreak="al", + unicodeslot=0x0F1E, + }, + [0x0F1F]={ + category="so", + description="TIBETAN SIGN RDEL DKAR RDEL NAG", + direction="l", + linebreak="al", + unicodeslot=0x0F1F, + }, + [0x0F20]={ + category="nd", + description="TIBETAN DIGIT ZERO", + direction="l", + linebreak="nu", + unicodeslot=0x0F20, + }, + [0x0F21]={ + category="nd", + description="TIBETAN DIGIT ONE", + direction="l", + linebreak="nu", + unicodeslot=0x0F21, + }, + [0x0F22]={ + category="nd", + description="TIBETAN DIGIT TWO", + direction="l", + linebreak="nu", + unicodeslot=0x0F22, + }, + [0x0F23]={ + category="nd", + description="TIBETAN DIGIT THREE", + direction="l", + linebreak="nu", + unicodeslot=0x0F23, + }, + [0x0F24]={ + category="nd", + description="TIBETAN DIGIT FOUR", + direction="l", + linebreak="nu", + unicodeslot=0x0F24, + }, + [0x0F25]={ + category="nd", + description="TIBETAN DIGIT FIVE", + direction="l", + linebreak="nu", + unicodeslot=0x0F25, + }, + [0x0F26]={ + category="nd", + description="TIBETAN DIGIT SIX", + direction="l", + linebreak="nu", + unicodeslot=0x0F26, + }, + [0x0F27]={ + category="nd", + description="TIBETAN DIGIT SEVEN", + direction="l", + linebreak="nu", + unicodeslot=0x0F27, + }, + [0x0F28]={ + category="nd", + description="TIBETAN DIGIT EIGHT", + direction="l", + linebreak="nu", + unicodeslot=0x0F28, + }, + [0x0F29]={ + category="nd", + description="TIBETAN DIGIT NINE", + direction="l", + linebreak="nu", + unicodeslot=0x0F29, + }, + [0x0F2A]={ + category="no", + description="TIBETAN DIGIT HALF ONE", + direction="l", + linebreak="al", + unicodeslot=0x0F2A, + }, + [0x0F2B]={ + category="no", + description="TIBETAN DIGIT HALF TWO", + direction="l", + linebreak="al", + unicodeslot=0x0F2B, + }, + [0x0F2C]={ + category="no", + description="TIBETAN DIGIT HALF THREE", + direction="l", + linebreak="al", + unicodeslot=0x0F2C, + }, + [0x0F2D]={ + category="no", + description="TIBETAN DIGIT HALF FOUR", + direction="l", + linebreak="al", + unicodeslot=0x0F2D, + }, + [0x0F2E]={ + category="no", + description="TIBETAN DIGIT HALF FIVE", + direction="l", + linebreak="al", + unicodeslot=0x0F2E, + }, + [0x0F2F]={ + category="no", + description="TIBETAN DIGIT HALF SIX", + direction="l", + linebreak="al", + unicodeslot=0x0F2F, + }, + [0x0F30]={ + category="no", + description="TIBETAN DIGIT HALF SEVEN", + direction="l", + linebreak="al", + unicodeslot=0x0F30, + }, + [0x0F31]={ + category="no", + description="TIBETAN DIGIT HALF EIGHT", + direction="l", + linebreak="al", + unicodeslot=0x0F31, + }, + [0x0F32]={ + category="no", + description="TIBETAN DIGIT HALF NINE", + direction="l", + linebreak="al", + unicodeslot=0x0F32, + }, + [0x0F33]={ + category="no", + description="TIBETAN DIGIT HALF ZERO", + direction="l", + linebreak="al", + unicodeslot=0x0F33, + }, + [0x0F34]={ + category="so", + description="TIBETAN MARK BSDUS RTAGS", + direction="l", + linebreak="ba", + unicodeslot=0x0F34, + }, + [0x0F35]={ + category="mn", + description="TIBETAN MARK NGAS BZUNG NYI ZLA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F35, + }, + [0x0F36]={ + category="so", + description="TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN", + direction="l", + linebreak="al", + unicodeslot=0x0F36, + }, + [0x0F37]={ + category="mn", + description="TIBETAN MARK NGAS BZUNG SGOR RTAGS", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F37, + }, + [0x0F38]={ + category="so", + description="TIBETAN MARK CHE MGO", + direction="l", + linebreak="al", + unicodeslot=0x0F38, + }, + [0x0F39]={ + category="mn", + description="TIBETAN MARK TSA -PHRU", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F39, + }, + [0x0F3A]={ + category="ps", + description="TIBETAN MARK GUG RTAGS GYON", + direction="on", + linebreak="op", + mirror=0x0F3B, + unicodeslot=0x0F3A, + }, + [0x0F3B]={ + category="pe", + description="TIBETAN MARK GUG RTAGS GYAS", + direction="on", + linebreak="cl", + mirror=0x0F3A, + unicodeslot=0x0F3B, + }, + [0x0F3C]={ + category="ps", + description="TIBETAN MARK ANG KHANG GYON", + direction="on", + linebreak="op", + mirror=0x0F3D, + unicodeslot=0x0F3C, + }, + [0x0F3D]={ + category="pe", + description="TIBETAN MARK ANG KHANG GYAS", + direction="on", + linebreak="cl", + mirror=0x0F3C, + unicodeslot=0x0F3D, + }, + [0x0F3E]={ + category="mc", + description="TIBETAN SIGN YAR TSHES", + direction="l", + linebreak="cm", + unicodeslot=0x0F3E, + }, + [0x0F3F]={ + category="mc", + description="TIBETAN SIGN MAR TSHES", + direction="l", + linebreak="cm", + unicodeslot=0x0F3F, + }, + [0x0F40]={ + category="lo", + description="TIBETAN LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x0F40, + }, + [0x0F41]={ + category="lo", + description="TIBETAN LETTER KHA", + direction="l", + linebreak="al", + unicodeslot=0x0F41, + }, + [0x0F42]={ + category="lo", + description="TIBETAN LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x0F42, + }, + [0x0F43]={ + category="lo", + description="TIBETAN LETTER GHA", + direction="l", + linebreak="al", + specials={ "char", 0x0F42, 0x0FB7 }, + unicodeslot=0x0F43, + }, + [0x0F44]={ + category="lo", + description="TIBETAN LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0x0F44, + }, + [0x0F45]={ + category="lo", + description="TIBETAN LETTER CA", + direction="l", + linebreak="al", + unicodeslot=0x0F45, + }, + [0x0F46]={ + category="lo", + description="TIBETAN LETTER CHA", + direction="l", + linebreak="al", + unicodeslot=0x0F46, + }, + [0x0F47]={ + category="lo", + description="TIBETAN LETTER JA", + direction="l", + linebreak="al", + unicodeslot=0x0F47, + }, + [0x0F49]={ + category="lo", + description="TIBETAN LETTER NYA", + direction="l", + linebreak="al", + unicodeslot=0x0F49, + }, + [0x0F4A]={ + category="lo", + description="TIBETAN LETTER TTA", + direction="l", + linebreak="al", + unicodeslot=0x0F4A, + }, + [0x0F4B]={ + category="lo", + description="TIBETAN LETTER TTHA", + direction="l", + linebreak="al", + unicodeslot=0x0F4B, + }, + [0x0F4C]={ + category="lo", + description="TIBETAN LETTER DDA", + direction="l", + linebreak="al", + unicodeslot=0x0F4C, + }, + [0x0F4D]={ + category="lo", + description="TIBETAN LETTER DDHA", + direction="l", + linebreak="al", + specials={ "char", 0x0F4C, 0x0FB7 }, + unicodeslot=0x0F4D, + }, + [0x0F4E]={ + category="lo", + description="TIBETAN LETTER NNA", + direction="l", + linebreak="al", + unicodeslot=0x0F4E, + }, + [0x0F4F]={ + category="lo", + description="TIBETAN LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x0F4F, + }, + [0x0F50]={ + category="lo", + description="TIBETAN LETTER THA", + direction="l", + linebreak="al", + unicodeslot=0x0F50, + }, + [0x0F51]={ + category="lo", + description="TIBETAN LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x0F51, + }, + [0x0F52]={ + category="lo", + description="TIBETAN LETTER DHA", + direction="l", + linebreak="al", + specials={ "char", 0x0F51, 0x0FB7 }, + unicodeslot=0x0F52, + }, + [0x0F53]={ + category="lo", + description="TIBETAN LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x0F53, + }, + [0x0F54]={ + category="lo", + description="TIBETAN LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x0F54, + }, + [0x0F55]={ + category="lo", + description="TIBETAN LETTER PHA", + direction="l", + linebreak="al", + unicodeslot=0x0F55, + }, + [0x0F56]={ + category="lo", + description="TIBETAN LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x0F56, + }, + [0x0F57]={ + category="lo", + description="TIBETAN LETTER BHA", + direction="l", + linebreak="al", + specials={ "char", 0x0F56, 0x0FB7 }, + unicodeslot=0x0F57, + }, + [0x0F58]={ + category="lo", + description="TIBETAN LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x0F58, + }, + [0x0F59]={ + category="lo", + description="TIBETAN LETTER TSA", + direction="l", + linebreak="al", + unicodeslot=0x0F59, + }, + [0x0F5A]={ + category="lo", + description="TIBETAN LETTER TSHA", + direction="l", + linebreak="al", + unicodeslot=0x0F5A, + }, + [0x0F5B]={ + category="lo", + description="TIBETAN LETTER DZA", + direction="l", + linebreak="al", + unicodeslot=0x0F5B, + }, + [0x0F5C]={ + category="lo", + description="TIBETAN LETTER DZHA", + direction="l", + linebreak="al", + specials={ "char", 0x0F5B, 0x0FB7 }, + unicodeslot=0x0F5C, + }, + [0x0F5D]={ + category="lo", + description="TIBETAN LETTER WA", + direction="l", + linebreak="al", + unicodeslot=0x0F5D, + }, + [0x0F5E]={ + category="lo", + description="TIBETAN LETTER ZHA", + direction="l", + linebreak="al", + unicodeslot=0x0F5E, + }, + [0x0F5F]={ + category="lo", + description="TIBETAN LETTER ZA", + direction="l", + linebreak="al", + unicodeslot=0x0F5F, + }, + [0x0F60]={ + category="lo", + description="TIBETAN LETTER -A", + direction="l", + linebreak="al", + unicodeslot=0x0F60, + }, + [0x0F61]={ + category="lo", + description="TIBETAN LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x0F61, + }, + [0x0F62]={ + category="lo", + description="TIBETAN LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0x0F62, + }, + [0x0F63]={ + category="lo", + description="TIBETAN LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x0F63, + }, + [0x0F64]={ + category="lo", + description="TIBETAN LETTER SHA", + direction="l", + linebreak="al", + unicodeslot=0x0F64, + }, + [0x0F65]={ + category="lo", + description="TIBETAN LETTER SSA", + direction="l", + linebreak="al", + unicodeslot=0x0F65, + }, + [0x0F66]={ + category="lo", + description="TIBETAN LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x0F66, + }, + [0x0F67]={ + category="lo", + description="TIBETAN LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x0F67, + }, + [0x0F68]={ + category="lo", + description="TIBETAN LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x0F68, + }, + [0x0F69]={ + category="lo", + description="TIBETAN LETTER KSSA", + direction="l", + linebreak="al", + specials={ "char", 0x0F40, 0x0FB5 }, + unicodeslot=0x0F69, + }, + [0x0F6A]={ + category="lo", + description="TIBETAN LETTER FIXED-FORM RA", + direction="l", + linebreak="al", + unicodeslot=0x0F6A, + }, + [0x0F71]={ + category="mn", + description="TIBETAN VOWEL SIGN AA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F71, + }, + [0x0F72]={ + category="mn", + description="TIBETAN VOWEL SIGN I", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F72, + }, + [0x0F73]={ + category="mn", + description="TIBETAN VOWEL SIGN II", + direction="nsm", + linebreak="cm", + specials={ "char", 0x0F71, 0x0F72 }, + unicodeslot=0x0F73, + }, + [0x0F74]={ + category="mn", + description="TIBETAN VOWEL SIGN U", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F74, + }, + [0x0F75]={ + category="mn", + description="TIBETAN VOWEL SIGN UU", + direction="nsm", + linebreak="cm", + specials={ "char", 0x0F71, 0x0F74 }, + unicodeslot=0x0F75, + }, + [0x0F76]={ + category="mn", + description="TIBETAN VOWEL SIGN VOCALIC R", + direction="nsm", + linebreak="cm", + specials={ "char", 0x0FB2, 0x0F80 }, + unicodeslot=0x0F76, + }, + [0x0F77]={ + category="mn", + description="TIBETAN VOWEL SIGN VOCALIC RR", + direction="nsm", + linebreak="cm", + specials={ "compat", 0x0FB2, 0x0F81 }, + unicodeslot=0x0F77, + }, + [0x0F78]={ + category="mn", + description="TIBETAN VOWEL SIGN VOCALIC L", + direction="nsm", + linebreak="cm", + specials={ "char", 0x0FB3, 0x0F80 }, + unicodeslot=0x0F78, + }, + [0x0F79]={ + category="mn", + description="TIBETAN VOWEL SIGN VOCALIC LL", + direction="nsm", + linebreak="cm", + specials={ "compat", 0x0FB3, 0x0F81 }, + unicodeslot=0x0F79, + }, + [0x0F7A]={ + category="mn", + description="TIBETAN VOWEL SIGN E", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F7A, + }, + [0x0F7B]={ + category="mn", + description="TIBETAN VOWEL SIGN EE", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F7B, + }, + [0x0F7C]={ + category="mn", + description="TIBETAN VOWEL SIGN O", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F7C, + }, + [0x0F7D]={ + category="mn", + description="TIBETAN VOWEL SIGN OO", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F7D, + }, + [0x0F7E]={ + category="mn", + description="TIBETAN SIGN RJES SU NGA RO", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F7E, + }, + [0x0F7F]={ + category="mc", + description="TIBETAN SIGN RNAM BCAD", + direction="l", + linebreak="ba", + unicodeslot=0x0F7F, + }, + [0x0F80]={ + category="mn", + description="TIBETAN VOWEL SIGN REVERSED I", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F80, + }, + [0x0F81]={ + category="mn", + description="TIBETAN VOWEL SIGN REVERSED II", + direction="nsm", + linebreak="cm", + specials={ "char", 0x0F71, 0x0F80 }, + unicodeslot=0x0F81, + }, + [0x0F82]={ + category="mn", + description="TIBETAN SIGN NYI ZLA NAA DA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F82, + }, + [0x0F83]={ + category="mn", + description="TIBETAN SIGN SNA LDAN", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F83, + }, + [0x0F84]={ + category="mn", + description="TIBETAN MARK HALANTA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F84, + }, + [0x0F85]={ + category="po", + description="TIBETAN MARK PALUTA", + direction="l", + linebreak="ba", + unicodeslot=0x0F85, + }, + [0x0F86]={ + category="mn", + description="TIBETAN SIGN LCI RTAGS", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F86, + }, + [0x0F87]={ + category="mn", + description="TIBETAN SIGN YANG RTAGS", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F87, + }, + [0x0F88]={ + category="lo", + description="TIBETAN SIGN LCE TSA CAN", + direction="l", + linebreak="al", + unicodeslot=0x0F88, + }, + [0x0F89]={ + category="lo", + description="TIBETAN SIGN MCHU CAN", + direction="l", + linebreak="al", + unicodeslot=0x0F89, + }, + [0x0F8A]={ + category="lo", + description="TIBETAN SIGN GRU CAN RGYINGS", + direction="l", + linebreak="al", + unicodeslot=0x0F8A, + }, + [0x0F8B]={ + category="lo", + description="TIBETAN SIGN GRU MED RGYINGS", + direction="l", + linebreak="al", + unicodeslot=0x0F8B, + }, + [0x0F90]={ + category="mn", + description="TIBETAN SUBJOINED LETTER KA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F90, + }, + [0x0F91]={ + category="mn", + description="TIBETAN SUBJOINED LETTER KHA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F91, + }, + [0x0F92]={ + category="mn", + description="TIBETAN SUBJOINED LETTER GA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F92, + }, + [0x0F93]={ + category="mn", + description="TIBETAN SUBJOINED LETTER GHA", + direction="nsm", + linebreak="cm", + specials={ "char", 0x0F92, 0x0FB7 }, + unicodeslot=0x0F93, + }, + [0x0F94]={ + category="mn", + description="TIBETAN SUBJOINED LETTER NGA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F94, + }, + [0x0F95]={ + category="mn", + description="TIBETAN SUBJOINED LETTER CA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F95, + }, + [0x0F96]={ + category="mn", + description="TIBETAN SUBJOINED LETTER CHA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F96, + }, + [0x0F97]={ + category="mn", + description="TIBETAN SUBJOINED LETTER JA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F97, + }, + [0x0F99]={ + category="mn", + description="TIBETAN SUBJOINED LETTER NYA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F99, + }, + [0x0F9A]={ + category="mn", + description="TIBETAN SUBJOINED LETTER TTA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F9A, + }, + [0x0F9B]={ + category="mn", + description="TIBETAN SUBJOINED LETTER TTHA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F9B, + }, + [0x0F9C]={ + category="mn", + description="TIBETAN SUBJOINED LETTER DDA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F9C, + }, + [0x0F9D]={ + category="mn", + description="TIBETAN SUBJOINED LETTER DDHA", + direction="nsm", + linebreak="cm", + specials={ "char", 0x0F9C, 0x0FB7 }, + unicodeslot=0x0F9D, + }, + [0x0F9E]={ + category="mn", + description="TIBETAN SUBJOINED LETTER NNA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F9E, + }, + [0x0F9F]={ + category="mn", + description="TIBETAN SUBJOINED LETTER TA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0F9F, + }, + [0x0FA0]={ + category="mn", + description="TIBETAN SUBJOINED LETTER THA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FA0, + }, + [0x0FA1]={ + category="mn", + description="TIBETAN SUBJOINED LETTER DA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FA1, + }, + [0x0FA2]={ + category="mn", + description="TIBETAN SUBJOINED LETTER DHA", + direction="nsm", + linebreak="cm", + specials={ "char", 0x0FA1, 0x0FB7 }, + unicodeslot=0x0FA2, + }, + [0x0FA3]={ + category="mn", + description="TIBETAN SUBJOINED LETTER NA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FA3, + }, + [0x0FA4]={ + category="mn", + description="TIBETAN SUBJOINED LETTER PA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FA4, + }, + [0x0FA5]={ + category="mn", + description="TIBETAN SUBJOINED LETTER PHA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FA5, + }, + [0x0FA6]={ + category="mn", + description="TIBETAN SUBJOINED LETTER BA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FA6, + }, + [0x0FA7]={ + category="mn", + description="TIBETAN SUBJOINED LETTER BHA", + direction="nsm", + linebreak="cm", + specials={ "char", 0x0FA6, 0x0FB7 }, + unicodeslot=0x0FA7, + }, + [0x0FA8]={ + category="mn", + description="TIBETAN SUBJOINED LETTER MA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FA8, + }, + [0x0FA9]={ + category="mn", + description="TIBETAN SUBJOINED LETTER TSA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FA9, + }, + [0x0FAA]={ + category="mn", + description="TIBETAN SUBJOINED LETTER TSHA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FAA, + }, + [0x0FAB]={ + category="mn", + description="TIBETAN SUBJOINED LETTER DZA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FAB, + }, + [0x0FAC]={ + category="mn", + description="TIBETAN SUBJOINED LETTER DZHA", + direction="nsm", + linebreak="cm", + specials={ "char", 0x0FAB, 0x0FB7 }, + unicodeslot=0x0FAC, + }, + [0x0FAD]={ + category="mn", + description="TIBETAN SUBJOINED LETTER WA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FAD, + }, + [0x0FAE]={ + category="mn", + description="TIBETAN SUBJOINED LETTER ZHA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FAE, + }, + [0x0FAF]={ + category="mn", + description="TIBETAN SUBJOINED LETTER ZA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FAF, + }, + [0x0FB0]={ + category="mn", + description="TIBETAN SUBJOINED LETTER -A", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FB0, + }, + [0x0FB1]={ + category="mn", + description="TIBETAN SUBJOINED LETTER YA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FB1, + }, + [0x0FB2]={ + category="mn", + description="TIBETAN SUBJOINED LETTER RA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FB2, + }, + [0x0FB3]={ + category="mn", + description="TIBETAN SUBJOINED LETTER LA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FB3, + }, + [0x0FB4]={ + category="mn", + description="TIBETAN SUBJOINED LETTER SHA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FB4, + }, + [0x0FB5]={ + category="mn", + description="TIBETAN SUBJOINED LETTER SSA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FB5, + }, + [0x0FB6]={ + category="mn", + description="TIBETAN SUBJOINED LETTER SA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FB6, + }, + [0x0FB7]={ + category="mn", + description="TIBETAN SUBJOINED LETTER HA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FB7, + }, + [0x0FB8]={ + category="mn", + description="TIBETAN SUBJOINED LETTER A", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FB8, + }, + [0x0FB9]={ + category="mn", + description="TIBETAN SUBJOINED LETTER KSSA", + direction="nsm", + linebreak="cm", + specials={ "char", 0x0F90, 0x0FB5 }, + unicodeslot=0x0FB9, + }, + [0x0FBA]={ + category="mn", + description="TIBETAN SUBJOINED LETTER FIXED-FORM WA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FBA, + }, + [0x0FBB]={ + category="mn", + description="TIBETAN SUBJOINED LETTER FIXED-FORM YA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FBB, + }, + [0x0FBC]={ + category="mn", + description="TIBETAN SUBJOINED LETTER FIXED-FORM RA", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FBC, + }, + [0x0FBE]={ + category="so", + description="TIBETAN KU RU KHA", + direction="l", + linebreak="ba", + unicodeslot=0x0FBE, + }, + [0x0FBF]={ + category="so", + description="TIBETAN KU RU KHA BZHI MIG CAN", + direction="l", + linebreak="ba", + unicodeslot=0x0FBF, + }, + [0x0FC0]={ + category="so", + description="TIBETAN CANTILLATION SIGN HEAVY BEAT", + direction="l", + linebreak="al", + unicodeslot=0x0FC0, + }, + [0x0FC1]={ + category="so", + description="TIBETAN CANTILLATION SIGN LIGHT BEAT", + direction="l", + linebreak="al", + unicodeslot=0x0FC1, + }, + [0x0FC2]={ + category="so", + description="TIBETAN CANTILLATION SIGN CANG TE-U", + direction="l", + linebreak="al", + unicodeslot=0x0FC2, + }, + [0x0FC3]={ + category="so", + description="TIBETAN CANTILLATION SIGN SBUB -CHAL", + direction="l", + linebreak="al", + unicodeslot=0x0FC3, + }, + [0x0FC4]={ + category="so", + description="TIBETAN SYMBOL DRIL BU", + direction="l", + linebreak="al", + unicodeslot=0x0FC4, + }, + [0x0FC5]={ + category="so", + description="TIBETAN SYMBOL RDO RJE", + direction="l", + linebreak="al", + unicodeslot=0x0FC5, + }, + [0x0FC6]={ + category="mn", + description="TIBETAN SYMBOL PADMA GDAN", + direction="nsm", + linebreak="cm", + unicodeslot=0x0FC6, + }, + [0x0FC7]={ + category="so", + description="TIBETAN SYMBOL RDO RJE RGYA GRAM", + direction="l", + linebreak="al", + unicodeslot=0x0FC7, + }, + [0x0FC8]={ + category="so", + description="TIBETAN SYMBOL PHUR PA", + direction="l", + linebreak="al", + unicodeslot=0x0FC8, + }, + [0x0FC9]={ + category="so", + description="TIBETAN SYMBOL NOR BU", + direction="l", + linebreak="al", + unicodeslot=0x0FC9, + }, + [0x0FCA]={ + category="so", + description="TIBETAN SYMBOL NOR BU NYIS -KHYIL", + direction="l", + linebreak="al", + unicodeslot=0x0FCA, + }, + [0x0FCB]={ + category="so", + description="TIBETAN SYMBOL NOR BU GSUM -KHYIL", + direction="l", + linebreak="al", + unicodeslot=0x0FCB, + }, + [0x0FCC]={ + category="so", + description="TIBETAN SYMBOL NOR BU BZHI -KHYIL", + direction="l", + linebreak="al", + unicodeslot=0x0FCC, + }, + [0x0FCF]={ + category="so", + description="TIBETAN SIGN RDEL NAG GSUM", + direction="l", + linebreak="al", + unicodeslot=0x0FCF, + }, + [0x0FD0]={ + category="po", + description="TIBETAN MARK BSKA- SHOG GI MGO RGYAN", + direction="l", + linebreak="bb", + unicodeslot=0x0FD0, + }, + [0x0FD1]={ + category="po", + description="TIBETAN MARK MNYAM YIG GI MGO RGYAN", + direction="l", + linebreak="bb", + unicodeslot=0x0FD1, + }, + [0x1000]={ + category="lo", + description="MYANMAR LETTER KA", + direction="l", + linebreak="sa", + unicodeslot=0x1000, + }, + [0x1001]={ + category="lo", + description="MYANMAR LETTER KHA", + direction="l", + linebreak="sa", + unicodeslot=0x1001, + }, + [0x1002]={ + category="lo", + description="MYANMAR LETTER GA", + direction="l", + linebreak="sa", + unicodeslot=0x1002, + }, + [0x1003]={ + category="lo", + description="MYANMAR LETTER GHA", + direction="l", + linebreak="sa", + unicodeslot=0x1003, + }, + [0x1004]={ + category="lo", + description="MYANMAR LETTER NGA", + direction="l", + linebreak="sa", + unicodeslot=0x1004, + }, + [0x1005]={ + category="lo", + description="MYANMAR LETTER CA", + direction="l", + linebreak="sa", + unicodeslot=0x1005, + }, + [0x1006]={ + category="lo", + description="MYANMAR LETTER CHA", + direction="l", + linebreak="sa", + unicodeslot=0x1006, + }, + [0x1007]={ + category="lo", + description="MYANMAR LETTER JA", + direction="l", + linebreak="sa", + unicodeslot=0x1007, + }, + [0x1008]={ + category="lo", + description="MYANMAR LETTER JHA", + direction="l", + linebreak="sa", + unicodeslot=0x1008, + }, + [0x1009]={ + category="lo", + description="MYANMAR LETTER NYA", + direction="l", + linebreak="sa", + unicodeslot=0x1009, + }, + [0x100A]={ + category="lo", + description="MYANMAR LETTER NNYA", + direction="l", + linebreak="sa", + unicodeslot=0x100A, + }, + [0x100B]={ + category="lo", + description="MYANMAR LETTER TTA", + direction="l", + linebreak="sa", + unicodeslot=0x100B, + }, + [0x100C]={ + category="lo", + description="MYANMAR LETTER TTHA", + direction="l", + linebreak="sa", + unicodeslot=0x100C, + }, + [0x100D]={ + category="lo", + description="MYANMAR LETTER DDA", + direction="l", + linebreak="sa", + unicodeslot=0x100D, + }, + [0x100E]={ + category="lo", + description="MYANMAR LETTER DDHA", + direction="l", + linebreak="sa", + unicodeslot=0x100E, + }, + [0x100F]={ + category="lo", + description="MYANMAR LETTER NNA", + direction="l", + linebreak="sa", + unicodeslot=0x100F, + }, + [0x1010]={ + category="lo", + description="MYANMAR LETTER TA", + direction="l", + linebreak="sa", + unicodeslot=0x1010, + }, + [0x1011]={ + category="lo", + description="MYANMAR LETTER THA", + direction="l", + linebreak="sa", + unicodeslot=0x1011, + }, + [0x1012]={ + category="lo", + description="MYANMAR LETTER DA", + direction="l", + linebreak="sa", + unicodeslot=0x1012, + }, + [0x1013]={ + category="lo", + description="MYANMAR LETTER DHA", + direction="l", + linebreak="sa", + unicodeslot=0x1013, + }, + [0x1014]={ + category="lo", + description="MYANMAR LETTER NA", + direction="l", + linebreak="sa", + unicodeslot=0x1014, + }, + [0x1015]={ + category="lo", + description="MYANMAR LETTER PA", + direction="l", + linebreak="sa", + unicodeslot=0x1015, + }, + [0x1016]={ + category="lo", + description="MYANMAR LETTER PHA", + direction="l", + linebreak="sa", + unicodeslot=0x1016, + }, + [0x1017]={ + category="lo", + description="MYANMAR LETTER BA", + direction="l", + linebreak="sa", + unicodeslot=0x1017, + }, + [0x1018]={ + category="lo", + description="MYANMAR LETTER BHA", + direction="l", + linebreak="sa", + unicodeslot=0x1018, + }, + [0x1019]={ + category="lo", + description="MYANMAR LETTER MA", + direction="l", + linebreak="sa", + unicodeslot=0x1019, + }, + [0x101A]={ + category="lo", + description="MYANMAR LETTER YA", + direction="l", + linebreak="sa", + unicodeslot=0x101A, + }, + [0x101B]={ + category="lo", + description="MYANMAR LETTER RA", + direction="l", + linebreak="sa", + unicodeslot=0x101B, + }, + [0x101C]={ + category="lo", + description="MYANMAR LETTER LA", + direction="l", + linebreak="sa", + unicodeslot=0x101C, + }, + [0x101D]={ + category="lo", + description="MYANMAR LETTER WA", + direction="l", + linebreak="sa", + unicodeslot=0x101D, + }, + [0x101E]={ + category="lo", + description="MYANMAR LETTER SA", + direction="l", + linebreak="sa", + unicodeslot=0x101E, + }, + [0x101F]={ + category="lo", + description="MYANMAR LETTER HA", + direction="l", + linebreak="sa", + unicodeslot=0x101F, + }, + [0x1020]={ + category="lo", + description="MYANMAR LETTER LLA", + direction="l", + linebreak="sa", + unicodeslot=0x1020, + }, + [0x1021]={ + category="lo", + description="MYANMAR LETTER A", + direction="l", + linebreak="sa", + unicodeslot=0x1021, + }, + [0x1023]={ + category="lo", + description="MYANMAR LETTER I", + direction="l", + linebreak="sa", + unicodeslot=0x1023, + }, + [0x1024]={ + category="lo", + description="MYANMAR LETTER II", + direction="l", + linebreak="sa", + unicodeslot=0x1024, + }, + [0x1025]={ + category="lo", + description="MYANMAR LETTER U", + direction="l", + linebreak="sa", + unicodeslot=0x1025, + }, + [0x1026]={ + category="lo", + description="MYANMAR LETTER UU", + direction="l", + linebreak="sa", + specials={ "char", 0x1025, 0x102E }, + unicodeslot=0x1026, + }, + [0x1027]={ + category="lo", + description="MYANMAR LETTER E", + direction="l", + linebreak="sa", + unicodeslot=0x1027, + }, + [0x1029]={ + category="lo", + description="MYANMAR LETTER O", + direction="l", + linebreak="sa", + unicodeslot=0x1029, + }, + [0x102A]={ + category="lo", + description="MYANMAR LETTER AU", + direction="l", + linebreak="sa", + unicodeslot=0x102A, + }, + [0x102C]={ + category="mc", + description="MYANMAR VOWEL SIGN AA", + direction="l", + linebreak="sa", + unicodeslot=0x102C, + }, + [0x102D]={ + category="mn", + description="MYANMAR VOWEL SIGN I", + direction="nsm", + linebreak="sa", + unicodeslot=0x102D, + }, + [0x102E]={ + category="mn", + description="MYANMAR VOWEL SIGN II", + direction="nsm", + linebreak="sa", + unicodeslot=0x102E, + }, + [0x102F]={ + category="mn", + description="MYANMAR VOWEL SIGN U", + direction="nsm", + linebreak="sa", + unicodeslot=0x102F, + }, + [0x1030]={ + category="mn", + description="MYANMAR VOWEL SIGN UU", + direction="nsm", + linebreak="sa", + unicodeslot=0x1030, + }, + [0x1031]={ + category="mc", + description="MYANMAR VOWEL SIGN E", + direction="l", + linebreak="sa", + unicodeslot=0x1031, + }, + [0x1032]={ + category="mn", + description="MYANMAR VOWEL SIGN AI", + direction="nsm", + linebreak="sa", + unicodeslot=0x1032, + }, + [0x1036]={ + category="mn", + description="MYANMAR SIGN ANUSVARA", + direction="nsm", + linebreak="sa", + unicodeslot=0x1036, + }, + [0x1037]={ + category="mn", + description="MYANMAR SIGN DOT BELOW", + direction="nsm", + linebreak="sa", + unicodeslot=0x1037, + }, + [0x1038]={ + category="mc", + description="MYANMAR SIGN VISARGA", + direction="l", + linebreak="sa", + unicodeslot=0x1038, + }, + [0x1039]={ + category="mn", + description="MYANMAR SIGN VIRAMA", + direction="nsm", + linebreak="sa", + unicodeslot=0x1039, + }, + [0x1040]={ + category="nd", + description="MYANMAR DIGIT ZERO", + direction="l", + linebreak="nu", + unicodeslot=0x1040, + }, + [0x1041]={ + category="nd", + description="MYANMAR DIGIT ONE", + direction="l", + linebreak="nu", + unicodeslot=0x1041, + }, + [0x1042]={ + category="nd", + description="MYANMAR DIGIT TWO", + direction="l", + linebreak="nu", + unicodeslot=0x1042, + }, + [0x1043]={ + category="nd", + description="MYANMAR DIGIT THREE", + direction="l", + linebreak="nu", + unicodeslot=0x1043, + }, + [0x1044]={ + category="nd", + description="MYANMAR DIGIT FOUR", + direction="l", + linebreak="nu", + unicodeslot=0x1044, + }, + [0x1045]={ + category="nd", + description="MYANMAR DIGIT FIVE", + direction="l", + linebreak="nu", + unicodeslot=0x1045, + }, + [0x1046]={ + category="nd", + description="MYANMAR DIGIT SIX", + direction="l", + linebreak="nu", + unicodeslot=0x1046, + }, + [0x1047]={ + category="nd", + description="MYANMAR DIGIT SEVEN", + direction="l", + linebreak="nu", + unicodeslot=0x1047, + }, + [0x1048]={ + category="nd", + description="MYANMAR DIGIT EIGHT", + direction="l", + linebreak="nu", + unicodeslot=0x1048, + }, + [0x1049]={ + category="nd", + description="MYANMAR DIGIT NINE", + direction="l", + linebreak="nu", + unicodeslot=0x1049, + }, + [0x104A]={ + category="po", + description="MYANMAR SIGN LITTLE SECTION", + direction="l", + linebreak="ba", + unicodeslot=0x104A, + }, + [0x104B]={ + category="po", + description="MYANMAR SIGN SECTION", + direction="l", + linebreak="ba", + unicodeslot=0x104B, + }, + [0x104C]={ + category="po", + description="MYANMAR SYMBOL LOCATIVE", + direction="l", + linebreak="al", + unicodeslot=0x104C, + }, + [0x104D]={ + category="po", + description="MYANMAR SYMBOL COMPLETED", + direction="l", + linebreak="al", + unicodeslot=0x104D, + }, + [0x104E]={ + category="po", + description="MYANMAR SYMBOL AFOREMENTIONED", + direction="l", + linebreak="al", + unicodeslot=0x104E, + }, + [0x104F]={ + category="po", + description="MYANMAR SYMBOL GENITIVE", + direction="l", + linebreak="al", + unicodeslot=0x104F, + }, + [0x1050]={ + category="lo", + description="MYANMAR LETTER SHA", + direction="l", + linebreak="sa", + unicodeslot=0x1050, + }, + [0x1051]={ + category="lo", + description="MYANMAR LETTER SSA", + direction="l", + linebreak="sa", + unicodeslot=0x1051, + }, + [0x1052]={ + category="lo", + description="MYANMAR LETTER VOCALIC R", + direction="l", + linebreak="sa", + unicodeslot=0x1052, + }, + [0x1053]={ + category="lo", + description="MYANMAR LETTER VOCALIC RR", + direction="l", + linebreak="sa", + unicodeslot=0x1053, + }, + [0x1054]={ + category="lo", + description="MYANMAR LETTER VOCALIC L", + direction="l", + linebreak="sa", + unicodeslot=0x1054, + }, + [0x1055]={ + category="lo", + description="MYANMAR LETTER VOCALIC LL", + direction="l", + linebreak="sa", + unicodeslot=0x1055, + }, + [0x1056]={ + category="mc", + description="MYANMAR VOWEL SIGN VOCALIC R", + direction="l", + linebreak="sa", + unicodeslot=0x1056, + }, + [0x1057]={ + category="mc", + description="MYANMAR VOWEL SIGN VOCALIC RR", + direction="l", + linebreak="sa", + unicodeslot=0x1057, + }, + [0x1058]={ + category="mn", + description="MYANMAR VOWEL SIGN VOCALIC L", + direction="nsm", + linebreak="sa", + unicodeslot=0x1058, + }, + [0x1059]={ + category="mn", + description="MYANMAR VOWEL SIGN VOCALIC LL", + direction="nsm", + linebreak="sa", + unicodeslot=0x1059, + }, + [0x10A0]={ + category="lu", + description="GEORGIAN CAPITAL LETTER AN", + direction="l", + lccode=0x2D00, + linebreak="al", + unicodeslot=0x10A0, + }, + [0x10A1]={ + category="lu", + description="GEORGIAN CAPITAL LETTER BAN", + direction="l", + lccode=0x2D01, + linebreak="al", + unicodeslot=0x10A1, + }, + [0x10A2]={ + category="lu", + description="GEORGIAN CAPITAL LETTER GAN", + direction="l", + lccode=0x2D02, + linebreak="al", + unicodeslot=0x10A2, + }, + [0x10A3]={ + category="lu", + description="GEORGIAN CAPITAL LETTER DON", + direction="l", + lccode=0x2D03, + linebreak="al", + unicodeslot=0x10A3, + }, + [0x10A4]={ + category="lu", + description="GEORGIAN CAPITAL LETTER EN", + direction="l", + lccode=0x2D04, + linebreak="al", + unicodeslot=0x10A4, + }, + [0x10A5]={ + category="lu", + description="GEORGIAN CAPITAL LETTER VIN", + direction="l", + lccode=0x2D05, + linebreak="al", + unicodeslot=0x10A5, + }, + [0x10A6]={ + category="lu", + description="GEORGIAN CAPITAL LETTER ZEN", + direction="l", + lccode=0x2D06, + linebreak="al", + unicodeslot=0x10A6, + }, + [0x10A7]={ + category="lu", + description="GEORGIAN CAPITAL LETTER TAN", + direction="l", + lccode=0x2D07, + linebreak="al", + unicodeslot=0x10A7, + }, + [0x10A8]={ + category="lu", + description="GEORGIAN CAPITAL LETTER IN", + direction="l", + lccode=0x2D08, + linebreak="al", + unicodeslot=0x10A8, + }, + [0x10A9]={ + category="lu", + description="GEORGIAN CAPITAL LETTER KAN", + direction="l", + lccode=0x2D09, + linebreak="al", + unicodeslot=0x10A9, + }, + [0x10AA]={ + category="lu", + description="GEORGIAN CAPITAL LETTER LAS", + direction="l", + lccode=0x2D0A, + linebreak="al", + unicodeslot=0x10AA, + }, + [0x10AB]={ + category="lu", + description="GEORGIAN CAPITAL LETTER MAN", + direction="l", + lccode=0x2D0B, + linebreak="al", + unicodeslot=0x10AB, + }, + [0x10AC]={ + category="lu", + description="GEORGIAN CAPITAL LETTER NAR", + direction="l", + lccode=0x2D0C, + linebreak="al", + unicodeslot=0x10AC, + }, + [0x10AD]={ + category="lu", + description="GEORGIAN CAPITAL LETTER ON", + direction="l", + lccode=0x2D0D, + linebreak="al", + unicodeslot=0x10AD, + }, + [0x10AE]={ + category="lu", + description="GEORGIAN CAPITAL LETTER PAR", + direction="l", + lccode=0x2D0E, + linebreak="al", + unicodeslot=0x10AE, + }, + [0x10AF]={ + category="lu", + description="GEORGIAN CAPITAL LETTER ZHAR", + direction="l", + lccode=0x2D0F, + linebreak="al", + unicodeslot=0x10AF, + }, + [0x10B0]={ + category="lu", + description="GEORGIAN CAPITAL LETTER RAE", + direction="l", + lccode=0x2D10, + linebreak="al", + unicodeslot=0x10B0, + }, + [0x10B1]={ + category="lu", + description="GEORGIAN CAPITAL LETTER SAN", + direction="l", + lccode=0x2D11, + linebreak="al", + unicodeslot=0x10B1, + }, + [0x10B2]={ + category="lu", + description="GEORGIAN CAPITAL LETTER TAR", + direction="l", + lccode=0x2D12, + linebreak="al", + unicodeslot=0x10B2, + }, + [0x10B3]={ + category="lu", + description="GEORGIAN CAPITAL LETTER UN", + direction="l", + lccode=0x2D13, + linebreak="al", + unicodeslot=0x10B3, + }, + [0x10B4]={ + category="lu", + description="GEORGIAN CAPITAL LETTER PHAR", + direction="l", + lccode=0x2D14, + linebreak="al", + unicodeslot=0x10B4, + }, + [0x10B5]={ + category="lu", + description="GEORGIAN CAPITAL LETTER KHAR", + direction="l", + lccode=0x2D15, + linebreak="al", + unicodeslot=0x10B5, + }, + [0x10B6]={ + category="lu", + description="GEORGIAN CAPITAL LETTER GHAN", + direction="l", + lccode=0x2D16, + linebreak="al", + unicodeslot=0x10B6, + }, + [0x10B7]={ + category="lu", + description="GEORGIAN CAPITAL LETTER QAR", + direction="l", + lccode=0x2D17, + linebreak="al", + unicodeslot=0x10B7, + }, + [0x10B8]={ + category="lu", + description="GEORGIAN CAPITAL LETTER SHIN", + direction="l", + lccode=0x2D18, + linebreak="al", + unicodeslot=0x10B8, + }, + [0x10B9]={ + category="lu", + description="GEORGIAN CAPITAL LETTER CHIN", + direction="l", + lccode=0x2D19, + linebreak="al", + unicodeslot=0x10B9, + }, + [0x10BA]={ + category="lu", + description="GEORGIAN CAPITAL LETTER CAN", + direction="l", + lccode=0x2D1A, + linebreak="al", + unicodeslot=0x10BA, + }, + [0x10BB]={ + category="lu", + description="GEORGIAN CAPITAL LETTER JIL", + direction="l", + lccode=0x2D1B, + linebreak="al", + unicodeslot=0x10BB, + }, + [0x10BC]={ + category="lu", + description="GEORGIAN CAPITAL LETTER CIL", + direction="l", + lccode=0x2D1C, + linebreak="al", + unicodeslot=0x10BC, + }, + [0x10BD]={ + category="lu", + description="GEORGIAN CAPITAL LETTER CHAR", + direction="l", + lccode=0x2D1D, + linebreak="al", + unicodeslot=0x10BD, + }, + [0x10BE]={ + category="lu", + description="GEORGIAN CAPITAL LETTER XAN", + direction="l", + lccode=0x2D1E, + linebreak="al", + unicodeslot=0x10BE, + }, + [0x10BF]={ + category="lu", + description="GEORGIAN CAPITAL LETTER JHAN", + direction="l", + lccode=0x2D1F, + linebreak="al", + unicodeslot=0x10BF, + }, + [0x10C0]={ + category="lu", + description="GEORGIAN CAPITAL LETTER HAE", + direction="l", + lccode=0x2D20, + linebreak="al", + unicodeslot=0x10C0, + }, + [0x10C1]={ + category="lu", + description="GEORGIAN CAPITAL LETTER HE", + direction="l", + lccode=0x2D21, + linebreak="al", + unicodeslot=0x10C1, + }, + [0x10C2]={ + category="lu", + description="GEORGIAN CAPITAL LETTER HIE", + direction="l", + lccode=0x2D22, + linebreak="al", + unicodeslot=0x10C2, + }, + [0x10C3]={ + category="lu", + description="GEORGIAN CAPITAL LETTER WE", + direction="l", + lccode=0x2D23, + linebreak="al", + unicodeslot=0x10C3, + }, + [0x10C4]={ + category="lu", + description="GEORGIAN CAPITAL LETTER HAR", + direction="l", + lccode=0x2D24, + linebreak="al", + unicodeslot=0x10C4, + }, + [0x10C5]={ + category="lu", + description="GEORGIAN CAPITAL LETTER HOE", + direction="l", + lccode=0x2D25, + linebreak="al", + unicodeslot=0x10C5, + }, + [0x10D0]={ + category="lo", + description="GEORGIAN LETTER AN", + direction="l", + linebreak="al", + unicodeslot=0x10D0, + }, + [0x10D1]={ + category="lo", + description="GEORGIAN LETTER BAN", + direction="l", + linebreak="al", + unicodeslot=0x10D1, + }, + [0x10D2]={ + category="lo", + description="GEORGIAN LETTER GAN", + direction="l", + linebreak="al", + unicodeslot=0x10D2, + }, + [0x10D3]={ + category="lo", + description="GEORGIAN LETTER DON", + direction="l", + linebreak="al", + unicodeslot=0x10D3, + }, + [0x10D4]={ + category="lo", + description="GEORGIAN LETTER EN", + direction="l", + linebreak="al", + unicodeslot=0x10D4, + }, + [0x10D5]={ + category="lo", + description="GEORGIAN LETTER VIN", + direction="l", + linebreak="al", + unicodeslot=0x10D5, + }, + [0x10D6]={ + category="lo", + description="GEORGIAN LETTER ZEN", + direction="l", + linebreak="al", + unicodeslot=0x10D6, + }, + [0x10D7]={ + category="lo", + description="GEORGIAN LETTER TAN", + direction="l", + linebreak="al", + unicodeslot=0x10D7, + }, + [0x10D8]={ + category="lo", + description="GEORGIAN LETTER IN", + direction="l", + linebreak="al", + unicodeslot=0x10D8, + }, + [0x10D9]={ + category="lo", + description="GEORGIAN LETTER KAN", + direction="l", + linebreak="al", + unicodeslot=0x10D9, + }, + [0x10DA]={ + category="lo", + description="GEORGIAN LETTER LAS", + direction="l", + linebreak="al", + unicodeslot=0x10DA, + }, + [0x10DB]={ + category="lo", + description="GEORGIAN LETTER MAN", + direction="l", + linebreak="al", + unicodeslot=0x10DB, + }, + [0x10DC]={ + category="lo", + description="GEORGIAN LETTER NAR", + direction="l", + linebreak="al", + unicodeslot=0x10DC, + }, + [0x10DD]={ + category="lo", + description="GEORGIAN LETTER ON", + direction="l", + linebreak="al", + unicodeslot=0x10DD, + }, + [0x10DE]={ + category="lo", + description="GEORGIAN LETTER PAR", + direction="l", + linebreak="al", + unicodeslot=0x10DE, + }, + [0x10DF]={ + category="lo", + description="GEORGIAN LETTER ZHAR", + direction="l", + linebreak="al", + unicodeslot=0x10DF, + }, + [0x10E0]={ + category="lo", + description="GEORGIAN LETTER RAE", + direction="l", + linebreak="al", + unicodeslot=0x10E0, + }, + [0x10E1]={ + category="lo", + description="GEORGIAN LETTER SAN", + direction="l", + linebreak="al", + unicodeslot=0x10E1, + }, + [0x10E2]={ + category="lo", + description="GEORGIAN LETTER TAR", + direction="l", + linebreak="al", + unicodeslot=0x10E2, + }, + [0x10E3]={ + category="lo", + description="GEORGIAN LETTER UN", + direction="l", + linebreak="al", + unicodeslot=0x10E3, + }, + [0x10E4]={ + category="lo", + description="GEORGIAN LETTER PHAR", + direction="l", + linebreak="al", + unicodeslot=0x10E4, + }, + [0x10E5]={ + category="lo", + description="GEORGIAN LETTER KHAR", + direction="l", + linebreak="al", + unicodeslot=0x10E5, + }, + [0x10E6]={ + category="lo", + description="GEORGIAN LETTER GHAN", + direction="l", + linebreak="al", + unicodeslot=0x10E6, + }, + [0x10E7]={ + category="lo", + description="GEORGIAN LETTER QAR", + direction="l", + linebreak="al", + unicodeslot=0x10E7, + }, + [0x10E8]={ + category="lo", + description="GEORGIAN LETTER SHIN", + direction="l", + linebreak="al", + unicodeslot=0x10E8, + }, + [0x10E9]={ + category="lo", + description="GEORGIAN LETTER CHIN", + direction="l", + linebreak="al", + unicodeslot=0x10E9, + }, + [0x10EA]={ + category="lo", + description="GEORGIAN LETTER CAN", + direction="l", + linebreak="al", + unicodeslot=0x10EA, + }, + [0x10EB]={ + category="lo", + description="GEORGIAN LETTER JIL", + direction="l", + linebreak="al", + unicodeslot=0x10EB, + }, + [0x10EC]={ + category="lo", + description="GEORGIAN LETTER CIL", + direction="l", + linebreak="al", + unicodeslot=0x10EC, + }, + [0x10ED]={ + category="lo", + description="GEORGIAN LETTER CHAR", + direction="l", + linebreak="al", + unicodeslot=0x10ED, + }, + [0x10EE]={ + category="lo", + description="GEORGIAN LETTER XAN", + direction="l", + linebreak="al", + unicodeslot=0x10EE, + }, + [0x10EF]={ + category="lo", + description="GEORGIAN LETTER JHAN", + direction="l", + linebreak="al", + unicodeslot=0x10EF, + }, + [0x10F0]={ + category="lo", + description="GEORGIAN LETTER HAE", + direction="l", + linebreak="al", + unicodeslot=0x10F0, + }, + [0x10F1]={ + category="lo", + description="GEORGIAN LETTER HE", + direction="l", + linebreak="al", + unicodeslot=0x10F1, + }, + [0x10F2]={ + category="lo", + description="GEORGIAN LETTER HIE", + direction="l", + linebreak="al", + unicodeslot=0x10F2, + }, + [0x10F3]={ + category="lo", + description="GEORGIAN LETTER WE", + direction="l", + linebreak="al", + unicodeslot=0x10F3, + }, + [0x10F4]={ + category="lo", + description="GEORGIAN LETTER HAR", + direction="l", + linebreak="al", + unicodeslot=0x10F4, + }, + [0x10F5]={ + category="lo", + description="GEORGIAN LETTER HOE", + direction="l", + linebreak="al", + unicodeslot=0x10F5, + }, + [0x10F6]={ + category="lo", + description="GEORGIAN LETTER FI", + direction="l", + linebreak="al", + unicodeslot=0x10F6, + }, + [0x10F7]={ + category="lo", + description="GEORGIAN LETTER YN", + direction="l", + linebreak="al", + unicodeslot=0x10F7, + }, + [0x10F8]={ + category="lo", + description="GEORGIAN LETTER ELIFI", + direction="l", + linebreak="al", + unicodeslot=0x10F8, + }, + [0x10F9]={ + category="lo", + description="GEORGIAN LETTER TURNED GAN", + direction="l", + linebreak="al", + unicodeslot=0x10F9, + }, + [0x10FA]={ + category="lo", + description="GEORGIAN LETTER AIN", + direction="l", + linebreak="al", + unicodeslot=0x10FA, + }, + [0x10FB]={ + category="po", + description="GEORGIAN PARAGRAPH SEPARATOR", + direction="l", + linebreak="al", + unicodeslot=0x10FB, + }, + [0x10FC]={ + category="lm", + description="MODIFIER LETTER GEORGIAN NAR", + direction="l", + linebreak="al", + specials={ "super", 0x10DC }, + unicodeslot=0x10FC, + }, + [0x1100]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG KIYEOK", + direction="l", + linebreak="jl", + unicodeslot=0x1100, + }, + [0x1101]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SSANGKIYEOK", + direction="l", + linebreak="jl", + unicodeslot=0x1101, + }, + [0x1102]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG NIEUN", + direction="l", + linebreak="jl", + unicodeslot=0x1102, + }, + [0x1103]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG TIKEUT", + direction="l", + linebreak="jl", + unicodeslot=0x1103, + }, + [0x1104]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SSANGTIKEUT", + direction="l", + linebreak="jl", + unicodeslot=0x1104, + }, + [0x1105]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG RIEUL", + direction="l", + linebreak="jl", + unicodeslot=0x1105, + }, + [0x1106]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG MIEUM", + direction="l", + linebreak="jl", + unicodeslot=0x1106, + }, + [0x1107]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG PIEUP", + direction="l", + linebreak="jl", + unicodeslot=0x1107, + }, + [0x1108]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SSANGPIEUP", + direction="l", + linebreak="jl", + unicodeslot=0x1108, + }, + [0x1109]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SIOS", + direction="l", + linebreak="jl", + unicodeslot=0x1109, + }, + [0x110A]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SSANGSIOS", + direction="l", + linebreak="jl", + unicodeslot=0x110A, + }, + [0x110B]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG IEUNG", + direction="l", + linebreak="jl", + unicodeslot=0x110B, + }, + [0x110C]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG CIEUC", + direction="l", + linebreak="jl", + unicodeslot=0x110C, + }, + [0x110D]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SSANGCIEUC", + direction="l", + linebreak="jl", + unicodeslot=0x110D, + }, + [0x110E]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG CHIEUCH", + direction="l", + linebreak="jl", + unicodeslot=0x110E, + }, + [0x110F]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG KHIEUKH", + direction="l", + linebreak="jl", + unicodeslot=0x110F, + }, + [0x1110]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG THIEUTH", + direction="l", + linebreak="jl", + unicodeslot=0x1110, + }, + [0x1111]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG PHIEUPH", + direction="l", + linebreak="jl", + unicodeslot=0x1111, + }, + [0x1112]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG HIEUH", + direction="l", + linebreak="jl", + unicodeslot=0x1112, + }, + [0x1113]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG NIEUN-KIYEOK", + direction="l", + linebreak="jl", + unicodeslot=0x1113, + }, + [0x1114]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SSANGNIEUN", + direction="l", + linebreak="jl", + unicodeslot=0x1114, + }, + [0x1115]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG NIEUN-TIKEUT", + direction="l", + linebreak="jl", + unicodeslot=0x1115, + }, + [0x1116]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG NIEUN-PIEUP", + direction="l", + linebreak="jl", + unicodeslot=0x1116, + }, + [0x1117]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG TIKEUT-KIYEOK", + direction="l", + linebreak="jl", + unicodeslot=0x1117, + }, + [0x1118]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG RIEUL-NIEUN", + direction="l", + linebreak="jl", + unicodeslot=0x1118, + }, + [0x1119]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SSANGRIEUL", + direction="l", + linebreak="jl", + unicodeslot=0x1119, + }, + [0x111A]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG RIEUL-HIEUH", + direction="l", + linebreak="jl", + unicodeslot=0x111A, + }, + [0x111B]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG KAPYEOUNRIEUL", + direction="l", + linebreak="jl", + unicodeslot=0x111B, + }, + [0x111C]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG MIEUM-PIEUP", + direction="l", + linebreak="jl", + unicodeslot=0x111C, + }, + [0x111D]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG KAPYEOUNMIEUM", + direction="l", + linebreak="jl", + unicodeslot=0x111D, + }, + [0x111E]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG PIEUP-KIYEOK", + direction="l", + linebreak="jl", + unicodeslot=0x111E, + }, + [0x111F]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG PIEUP-NIEUN", + direction="l", + linebreak="jl", + unicodeslot=0x111F, + }, + [0x1120]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG PIEUP-TIKEUT", + direction="l", + linebreak="jl", + unicodeslot=0x1120, + }, + [0x1121]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG PIEUP-SIOS", + direction="l", + linebreak="jl", + unicodeslot=0x1121, + }, + [0x1122]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG PIEUP-SIOS-KIYEOK", + direction="l", + linebreak="jl", + unicodeslot=0x1122, + }, + [0x1123]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG PIEUP-SIOS-TIKEUT", + direction="l", + linebreak="jl", + unicodeslot=0x1123, + }, + [0x1124]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG PIEUP-SIOS-PIEUP", + direction="l", + linebreak="jl", + unicodeslot=0x1124, + }, + [0x1125]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG PIEUP-SSANGSIOS", + direction="l", + linebreak="jl", + unicodeslot=0x1125, + }, + [0x1126]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG PIEUP-SIOS-CIEUC", + direction="l", + linebreak="jl", + unicodeslot=0x1126, + }, + [0x1127]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG PIEUP-CIEUC", + direction="l", + linebreak="jl", + unicodeslot=0x1127, + }, + [0x1128]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG PIEUP-CHIEUCH", + direction="l", + linebreak="jl", + unicodeslot=0x1128, + }, + [0x1129]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG PIEUP-THIEUTH", + direction="l", + linebreak="jl", + unicodeslot=0x1129, + }, + [0x112A]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG PIEUP-PHIEUPH", + direction="l", + linebreak="jl", + unicodeslot=0x112A, + }, + [0x112B]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG KAPYEOUNPIEUP", + direction="l", + linebreak="jl", + unicodeslot=0x112B, + }, + [0x112C]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG KAPYEOUNSSANGPIEUP", + direction="l", + linebreak="jl", + unicodeslot=0x112C, + }, + [0x112D]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SIOS-KIYEOK", + direction="l", + linebreak="jl", + unicodeslot=0x112D, + }, + [0x112E]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SIOS-NIEUN", + direction="l", + linebreak="jl", + unicodeslot=0x112E, + }, + [0x112F]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SIOS-TIKEUT", + direction="l", + linebreak="jl", + unicodeslot=0x112F, + }, + [0x1130]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SIOS-RIEUL", + direction="l", + linebreak="jl", + unicodeslot=0x1130, + }, + [0x1131]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SIOS-MIEUM", + direction="l", + linebreak="jl", + unicodeslot=0x1131, + }, + [0x1132]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SIOS-PIEUP", + direction="l", + linebreak="jl", + unicodeslot=0x1132, + }, + [0x1133]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SIOS-PIEUP-KIYEOK", + direction="l", + linebreak="jl", + unicodeslot=0x1133, + }, + [0x1134]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SIOS-SSANGSIOS", + direction="l", + linebreak="jl", + unicodeslot=0x1134, + }, + [0x1135]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SIOS-IEUNG", + direction="l", + linebreak="jl", + unicodeslot=0x1135, + }, + [0x1136]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SIOS-CIEUC", + direction="l", + linebreak="jl", + unicodeslot=0x1136, + }, + [0x1137]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SIOS-CHIEUCH", + direction="l", + linebreak="jl", + unicodeslot=0x1137, + }, + [0x1138]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SIOS-KHIEUKH", + direction="l", + linebreak="jl", + unicodeslot=0x1138, + }, + [0x1139]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SIOS-THIEUTH", + direction="l", + linebreak="jl", + unicodeslot=0x1139, + }, + [0x113A]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SIOS-PHIEUPH", + direction="l", + linebreak="jl", + unicodeslot=0x113A, + }, + [0x113B]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SIOS-HIEUH", + direction="l", + linebreak="jl", + unicodeslot=0x113B, + }, + [0x113C]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG CHITUEUMSIOS", + direction="l", + linebreak="jl", + unicodeslot=0x113C, + }, + [0x113D]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG CHITUEUMSSANGSIOS", + direction="l", + linebreak="jl", + unicodeslot=0x113D, + }, + [0x113E]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG CEONGCHIEUMSIOS", + direction="l", + linebreak="jl", + unicodeslot=0x113E, + }, + [0x113F]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG CEONGCHIEUMSSANGSIOS", + direction="l", + linebreak="jl", + unicodeslot=0x113F, + }, + [0x1140]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG PANSIOS", + direction="l", + linebreak="jl", + unicodeslot=0x1140, + }, + [0x1141]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG IEUNG-KIYEOK", + direction="l", + linebreak="jl", + unicodeslot=0x1141, + }, + [0x1142]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG IEUNG-TIKEUT", + direction="l", + linebreak="jl", + unicodeslot=0x1142, + }, + [0x1143]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG IEUNG-MIEUM", + direction="l", + linebreak="jl", + unicodeslot=0x1143, + }, + [0x1144]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG IEUNG-PIEUP", + direction="l", + linebreak="jl", + unicodeslot=0x1144, + }, + [0x1145]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG IEUNG-SIOS", + direction="l", + linebreak="jl", + unicodeslot=0x1145, + }, + [0x1146]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG IEUNG-PANSIOS", + direction="l", + linebreak="jl", + unicodeslot=0x1146, + }, + [0x1147]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SSANGIEUNG", + direction="l", + linebreak="jl", + unicodeslot=0x1147, + }, + [0x1148]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG IEUNG-CIEUC", + direction="l", + linebreak="jl", + unicodeslot=0x1148, + }, + [0x1149]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG IEUNG-CHIEUCH", + direction="l", + linebreak="jl", + unicodeslot=0x1149, + }, + [0x114A]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG IEUNG-THIEUTH", + direction="l", + linebreak="jl", + unicodeslot=0x114A, + }, + [0x114B]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG IEUNG-PHIEUPH", + direction="l", + linebreak="jl", + unicodeslot=0x114B, + }, + [0x114C]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG YESIEUNG", + direction="l", + linebreak="jl", + unicodeslot=0x114C, + }, + [0x114D]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG CIEUC-IEUNG", + direction="l", + linebreak="jl", + unicodeslot=0x114D, + }, + [0x114E]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG CHITUEUMCIEUC", + direction="l", + linebreak="jl", + unicodeslot=0x114E, + }, + [0x114F]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG CHITUEUMSSANGCIEUC", + direction="l", + linebreak="jl", + unicodeslot=0x114F, + }, + [0x1150]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG CEONGCHIEUMCIEUC", + direction="l", + linebreak="jl", + unicodeslot=0x1150, + }, + [0x1151]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG CEONGCHIEUMSSANGCIEUC", + direction="l", + linebreak="jl", + unicodeslot=0x1151, + }, + [0x1152]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG CHIEUCH-KHIEUKH", + direction="l", + linebreak="jl", + unicodeslot=0x1152, + }, + [0x1153]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG CHIEUCH-HIEUH", + direction="l", + linebreak="jl", + unicodeslot=0x1153, + }, + [0x1154]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG CHITUEUMCHIEUCH", + direction="l", + linebreak="jl", + unicodeslot=0x1154, + }, + [0x1155]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG CEONGCHIEUMCHIEUCH", + direction="l", + linebreak="jl", + unicodeslot=0x1155, + }, + [0x1156]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG PHIEUPH-PIEUP", + direction="l", + linebreak="jl", + unicodeslot=0x1156, + }, + [0x1157]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG KAPYEOUNPHIEUPH", + direction="l", + linebreak="jl", + unicodeslot=0x1157, + }, + [0x1158]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG SSANGHIEUH", + direction="l", + linebreak="jl", + unicodeslot=0x1158, + }, + [0x1159]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG YEORINHIEUH", + direction="l", + linebreak="jl", + unicodeslot=0x1159, + }, + [0x115F]={ + category="lo", + cjkwd="w", + description="HANGUL CHOSEONG FILLER", + direction="l", + linebreak="jl", + unicodeslot=0x115F, + }, + [0x1160]={ + category="lo", + description="HANGUL JUNGSEONG FILLER", + direction="l", + linebreak="jv", + unicodeslot=0x1160, + }, + [0x1161]={ + category="lo", + description="HANGUL JUNGSEONG A", + direction="l", + linebreak="jv", + unicodeslot=0x1161, + }, + [0x1162]={ + category="lo", + description="HANGUL JUNGSEONG AE", + direction="l", + linebreak="jv", + unicodeslot=0x1162, + }, + [0x1163]={ + category="lo", + description="HANGUL JUNGSEONG YA", + direction="l", + linebreak="jv", + unicodeslot=0x1163, + }, + [0x1164]={ + category="lo", + description="HANGUL JUNGSEONG YAE", + direction="l", + linebreak="jv", + unicodeslot=0x1164, + }, + [0x1165]={ + category="lo", + description="HANGUL JUNGSEONG EO", + direction="l", + linebreak="jv", + unicodeslot=0x1165, + }, + [0x1166]={ + category="lo", + description="HANGUL JUNGSEONG E", + direction="l", + linebreak="jv", + unicodeslot=0x1166, + }, + [0x1167]={ + category="lo", + description="HANGUL JUNGSEONG YEO", + direction="l", + linebreak="jv", + unicodeslot=0x1167, + }, + [0x1168]={ + category="lo", + description="HANGUL JUNGSEONG YE", + direction="l", + linebreak="jv", + unicodeslot=0x1168, + }, + [0x1169]={ + category="lo", + description="HANGUL JUNGSEONG O", + direction="l", + linebreak="jv", + unicodeslot=0x1169, + }, + [0x116A]={ + category="lo", + description="HANGUL JUNGSEONG WA", + direction="l", + linebreak="jv", + unicodeslot=0x116A, + }, + [0x116B]={ + category="lo", + description="HANGUL JUNGSEONG WAE", + direction="l", + linebreak="jv", + unicodeslot=0x116B, + }, + [0x116C]={ + category="lo", + description="HANGUL JUNGSEONG OE", + direction="l", + linebreak="jv", + unicodeslot=0x116C, + }, + [0x116D]={ + category="lo", + description="HANGUL JUNGSEONG YO", + direction="l", + linebreak="jv", + unicodeslot=0x116D, + }, + [0x116E]={ + category="lo", + description="HANGUL JUNGSEONG U", + direction="l", + linebreak="jv", + unicodeslot=0x116E, + }, + [0x116F]={ + category="lo", + description="HANGUL JUNGSEONG WEO", + direction="l", + linebreak="jv", + unicodeslot=0x116F, + }, + [0x1170]={ + category="lo", + description="HANGUL JUNGSEONG WE", + direction="l", + linebreak="jv", + unicodeslot=0x1170, + }, + [0x1171]={ + category="lo", + description="HANGUL JUNGSEONG WI", + direction="l", + linebreak="jv", + unicodeslot=0x1171, + }, + [0x1172]={ + category="lo", + description="HANGUL JUNGSEONG YU", + direction="l", + linebreak="jv", + unicodeslot=0x1172, + }, + [0x1173]={ + category="lo", + description="HANGUL JUNGSEONG EU", + direction="l", + linebreak="jv", + unicodeslot=0x1173, + }, + [0x1174]={ + category="lo", + description="HANGUL JUNGSEONG YI", + direction="l", + linebreak="jv", + unicodeslot=0x1174, + }, + [0x1175]={ + category="lo", + description="HANGUL JUNGSEONG I", + direction="l", + linebreak="jv", + unicodeslot=0x1175, + }, + [0x1176]={ + category="lo", + description="HANGUL JUNGSEONG A-O", + direction="l", + linebreak="jv", + unicodeslot=0x1176, + }, + [0x1177]={ + category="lo", + description="HANGUL JUNGSEONG A-U", + direction="l", + linebreak="jv", + unicodeslot=0x1177, + }, + [0x1178]={ + category="lo", + description="HANGUL JUNGSEONG YA-O", + direction="l", + linebreak="jv", + unicodeslot=0x1178, + }, + [0x1179]={ + category="lo", + description="HANGUL JUNGSEONG YA-YO", + direction="l", + linebreak="jv", + unicodeslot=0x1179, + }, + [0x117A]={ + category="lo", + description="HANGUL JUNGSEONG EO-O", + direction="l", + linebreak="jv", + unicodeslot=0x117A, + }, + [0x117B]={ + category="lo", + description="HANGUL JUNGSEONG EO-U", + direction="l", + linebreak="jv", + unicodeslot=0x117B, + }, + [0x117C]={ + category="lo", + description="HANGUL JUNGSEONG EO-EU", + direction="l", + linebreak="jv", + unicodeslot=0x117C, + }, + [0x117D]={ + category="lo", + description="HANGUL JUNGSEONG YEO-O", + direction="l", + linebreak="jv", + unicodeslot=0x117D, + }, + [0x117E]={ + category="lo", + description="HANGUL JUNGSEONG YEO-U", + direction="l", + linebreak="jv", + unicodeslot=0x117E, + }, + [0x117F]={ + category="lo", + description="HANGUL JUNGSEONG O-EO", + direction="l", + linebreak="jv", + unicodeslot=0x117F, + }, + [0x1180]={ + category="lo", + description="HANGUL JUNGSEONG O-E", + direction="l", + linebreak="jv", + unicodeslot=0x1180, + }, + [0x1181]={ + category="lo", + description="HANGUL JUNGSEONG O-YE", + direction="l", + linebreak="jv", + unicodeslot=0x1181, + }, + [0x1182]={ + category="lo", + description="HANGUL JUNGSEONG O-O", + direction="l", + linebreak="jv", + unicodeslot=0x1182, + }, + [0x1183]={ + category="lo", + description="HANGUL JUNGSEONG O-U", + direction="l", + linebreak="jv", + unicodeslot=0x1183, + }, + [0x1184]={ + category="lo", + description="HANGUL JUNGSEONG YO-YA", + direction="l", + linebreak="jv", + unicodeslot=0x1184, + }, + [0x1185]={ + category="lo", + description="HANGUL JUNGSEONG YO-YAE", + direction="l", + linebreak="jv", + unicodeslot=0x1185, + }, + [0x1186]={ + category="lo", + description="HANGUL JUNGSEONG YO-YEO", + direction="l", + linebreak="jv", + unicodeslot=0x1186, + }, + [0x1187]={ + category="lo", + description="HANGUL JUNGSEONG YO-O", + direction="l", + linebreak="jv", + unicodeslot=0x1187, + }, + [0x1188]={ + category="lo", + description="HANGUL JUNGSEONG YO-I", + direction="l", + linebreak="jv", + unicodeslot=0x1188, + }, + [0x1189]={ + category="lo", + description="HANGUL JUNGSEONG U-A", + direction="l", + linebreak="jv", + unicodeslot=0x1189, + }, + [0x118A]={ + category="lo", + description="HANGUL JUNGSEONG U-AE", + direction="l", + linebreak="jv", + unicodeslot=0x118A, + }, + [0x118B]={ + category="lo", + description="HANGUL JUNGSEONG U-EO-EU", + direction="l", + linebreak="jv", + unicodeslot=0x118B, + }, + [0x118C]={ + category="lo", + description="HANGUL JUNGSEONG U-YE", + direction="l", + linebreak="jv", + unicodeslot=0x118C, + }, + [0x118D]={ + category="lo", + description="HANGUL JUNGSEONG U-U", + direction="l", + linebreak="jv", + unicodeslot=0x118D, + }, + [0x118E]={ + category="lo", + description="HANGUL JUNGSEONG YU-A", + direction="l", + linebreak="jv", + unicodeslot=0x118E, + }, + [0x118F]={ + category="lo", + description="HANGUL JUNGSEONG YU-EO", + direction="l", + linebreak="jv", + unicodeslot=0x118F, + }, + [0x1190]={ + category="lo", + description="HANGUL JUNGSEONG YU-E", + direction="l", + linebreak="jv", + unicodeslot=0x1190, + }, + [0x1191]={ + category="lo", + description="HANGUL JUNGSEONG YU-YEO", + direction="l", + linebreak="jv", + unicodeslot=0x1191, + }, + [0x1192]={ + category="lo", + description="HANGUL JUNGSEONG YU-YE", + direction="l", + linebreak="jv", + unicodeslot=0x1192, + }, + [0x1193]={ + category="lo", + description="HANGUL JUNGSEONG YU-U", + direction="l", + linebreak="jv", + unicodeslot=0x1193, + }, + [0x1194]={ + category="lo", + description="HANGUL JUNGSEONG YU-I", + direction="l", + linebreak="jv", + unicodeslot=0x1194, + }, + [0x1195]={ + category="lo", + description="HANGUL JUNGSEONG EU-U", + direction="l", + linebreak="jv", + unicodeslot=0x1195, + }, + [0x1196]={ + category="lo", + description="HANGUL JUNGSEONG EU-EU", + direction="l", + linebreak="jv", + unicodeslot=0x1196, + }, + [0x1197]={ + category="lo", + description="HANGUL JUNGSEONG YI-U", + direction="l", + linebreak="jv", + unicodeslot=0x1197, + }, + [0x1198]={ + category="lo", + description="HANGUL JUNGSEONG I-A", + direction="l", + linebreak="jv", + unicodeslot=0x1198, + }, + [0x1199]={ + category="lo", + description="HANGUL JUNGSEONG I-YA", + direction="l", + linebreak="jv", + unicodeslot=0x1199, + }, + [0x119A]={ + category="lo", + description="HANGUL JUNGSEONG I-O", + direction="l", + linebreak="jv", + unicodeslot=0x119A, + }, + [0x119B]={ + category="lo", + description="HANGUL JUNGSEONG I-U", + direction="l", + linebreak="jv", + unicodeslot=0x119B, + }, + [0x119C]={ + category="lo", + description="HANGUL JUNGSEONG I-EU", + direction="l", + linebreak="jv", + unicodeslot=0x119C, + }, + [0x119D]={ + category="lo", + description="HANGUL JUNGSEONG I-ARAEA", + direction="l", + linebreak="jv", + unicodeslot=0x119D, + }, + [0x119E]={ + category="lo", + description="HANGUL JUNGSEONG ARAEA", + direction="l", + linebreak="jv", + unicodeslot=0x119E, + }, + [0x119F]={ + category="lo", + description="HANGUL JUNGSEONG ARAEA-EO", + direction="l", + linebreak="jv", + unicodeslot=0x119F, + }, + [0x11A0]={ + category="lo", + description="HANGUL JUNGSEONG ARAEA-U", + direction="l", + linebreak="jv", + unicodeslot=0x11A0, + }, + [0x11A1]={ + category="lo", + description="HANGUL JUNGSEONG ARAEA-I", + direction="l", + linebreak="jv", + unicodeslot=0x11A1, + }, + [0x11A2]={ + category="lo", + description="HANGUL JUNGSEONG SSANGARAEA", + direction="l", + linebreak="jv", + unicodeslot=0x11A2, + }, + [0x11A8]={ + category="lo", + description="HANGUL JONGSEONG KIYEOK", + direction="l", + linebreak="jt", + unicodeslot=0x11A8, + }, + [0x11A9]={ + category="lo", + description="HANGUL JONGSEONG SSANGKIYEOK", + direction="l", + linebreak="jt", + unicodeslot=0x11A9, + }, + [0x11AA]={ + category="lo", + description="HANGUL JONGSEONG KIYEOK-SIOS", + direction="l", + linebreak="jt", + unicodeslot=0x11AA, + }, + [0x11AB]={ + category="lo", + description="HANGUL JONGSEONG NIEUN", + direction="l", + linebreak="jt", + unicodeslot=0x11AB, + }, + [0x11AC]={ + category="lo", + description="HANGUL JONGSEONG NIEUN-CIEUC", + direction="l", + linebreak="jt", + unicodeslot=0x11AC, + }, + [0x11AD]={ + category="lo", + description="HANGUL JONGSEONG NIEUN-HIEUH", + direction="l", + linebreak="jt", + unicodeslot=0x11AD, + }, + [0x11AE]={ + category="lo", + description="HANGUL JONGSEONG TIKEUT", + direction="l", + linebreak="jt", + unicodeslot=0x11AE, + }, + [0x11AF]={ + category="lo", + description="HANGUL JONGSEONG RIEUL", + direction="l", + linebreak="jt", + unicodeslot=0x11AF, + }, + [0x11B0]={ + category="lo", + description="HANGUL JONGSEONG RIEUL-KIYEOK", + direction="l", + linebreak="jt", + unicodeslot=0x11B0, + }, + [0x11B1]={ + category="lo", + description="HANGUL JONGSEONG RIEUL-MIEUM", + direction="l", + linebreak="jt", + unicodeslot=0x11B1, + }, + [0x11B2]={ + category="lo", + description="HANGUL JONGSEONG RIEUL-PIEUP", + direction="l", + linebreak="jt", + unicodeslot=0x11B2, + }, + [0x11B3]={ + category="lo", + description="HANGUL JONGSEONG RIEUL-SIOS", + direction="l", + linebreak="jt", + unicodeslot=0x11B3, + }, + [0x11B4]={ + category="lo", + description="HANGUL JONGSEONG RIEUL-THIEUTH", + direction="l", + linebreak="jt", + unicodeslot=0x11B4, + }, + [0x11B5]={ + category="lo", + description="HANGUL JONGSEONG RIEUL-PHIEUPH", + direction="l", + linebreak="jt", + unicodeslot=0x11B5, + }, + [0x11B6]={ + category="lo", + description="HANGUL JONGSEONG RIEUL-HIEUH", + direction="l", + linebreak="jt", + unicodeslot=0x11B6, + }, + [0x11B7]={ + category="lo", + description="HANGUL JONGSEONG MIEUM", + direction="l", + linebreak="jt", + unicodeslot=0x11B7, + }, + [0x11B8]={ + category="lo", + description="HANGUL JONGSEONG PIEUP", + direction="l", + linebreak="jt", + unicodeslot=0x11B8, + }, + [0x11B9]={ + category="lo", + description="HANGUL JONGSEONG PIEUP-SIOS", + direction="l", + linebreak="jt", + unicodeslot=0x11B9, + }, + [0x11BA]={ + category="lo", + description="HANGUL JONGSEONG SIOS", + direction="l", + linebreak="jt", + unicodeslot=0x11BA, + }, + [0x11BB]={ + category="lo", + description="HANGUL JONGSEONG SSANGSIOS", + direction="l", + linebreak="jt", + unicodeslot=0x11BB, + }, + [0x11BC]={ + category="lo", + description="HANGUL JONGSEONG IEUNG", + direction="l", + linebreak="jt", + unicodeslot=0x11BC, + }, + [0x11BD]={ + category="lo", + description="HANGUL JONGSEONG CIEUC", + direction="l", + linebreak="jt", + unicodeslot=0x11BD, + }, + [0x11BE]={ + category="lo", + description="HANGUL JONGSEONG CHIEUCH", + direction="l", + linebreak="jt", + unicodeslot=0x11BE, + }, + [0x11BF]={ + category="lo", + description="HANGUL JONGSEONG KHIEUKH", + direction="l", + linebreak="jt", + unicodeslot=0x11BF, + }, + [0x11C0]={ + category="lo", + description="HANGUL JONGSEONG THIEUTH", + direction="l", + linebreak="jt", + unicodeslot=0x11C0, + }, + [0x11C1]={ + category="lo", + description="HANGUL JONGSEONG PHIEUPH", + direction="l", + linebreak="jt", + unicodeslot=0x11C1, + }, + [0x11C2]={ + category="lo", + description="HANGUL JONGSEONG HIEUH", + direction="l", + linebreak="jt", + unicodeslot=0x11C2, + }, + [0x11C3]={ + category="lo", + description="HANGUL JONGSEONG KIYEOK-RIEUL", + direction="l", + linebreak="jt", + unicodeslot=0x11C3, + }, + [0x11C4]={ + category="lo", + description="HANGUL JONGSEONG KIYEOK-SIOS-KIYEOK", + direction="l", + linebreak="jt", + unicodeslot=0x11C4, + }, + [0x11C5]={ + category="lo", + description="HANGUL JONGSEONG NIEUN-KIYEOK", + direction="l", + linebreak="jt", + unicodeslot=0x11C5, + }, + [0x11C6]={ + category="lo", + description="HANGUL JONGSEONG NIEUN-TIKEUT", + direction="l", + linebreak="jt", + unicodeslot=0x11C6, + }, + [0x11C7]={ + category="lo", + description="HANGUL JONGSEONG NIEUN-SIOS", + direction="l", + linebreak="jt", + unicodeslot=0x11C7, + }, + [0x11C8]={ + category="lo", + description="HANGUL JONGSEONG NIEUN-PANSIOS", + direction="l", + linebreak="jt", + unicodeslot=0x11C8, + }, + [0x11C9]={ + category="lo", + description="HANGUL JONGSEONG NIEUN-THIEUTH", + direction="l", + linebreak="jt", + unicodeslot=0x11C9, + }, + [0x11CA]={ + category="lo", + description="HANGUL JONGSEONG TIKEUT-KIYEOK", + direction="l", + linebreak="jt", + unicodeslot=0x11CA, + }, + [0x11CB]={ + category="lo", + description="HANGUL JONGSEONG TIKEUT-RIEUL", + direction="l", + linebreak="jt", + unicodeslot=0x11CB, + }, + [0x11CC]={ + category="lo", + description="HANGUL JONGSEONG RIEUL-KIYEOK-SIOS", + direction="l", + linebreak="jt", + unicodeslot=0x11CC, + }, + [0x11CD]={ + category="lo", + description="HANGUL JONGSEONG RIEUL-NIEUN", + direction="l", + linebreak="jt", + unicodeslot=0x11CD, + }, + [0x11CE]={ + category="lo", + description="HANGUL JONGSEONG RIEUL-TIKEUT", + direction="l", + linebreak="jt", + unicodeslot=0x11CE, + }, + [0x11CF]={ + category="lo", + description="HANGUL JONGSEONG RIEUL-TIKEUT-HIEUH", + direction="l", + linebreak="jt", + unicodeslot=0x11CF, + }, + [0x11D0]={ + category="lo", + description="HANGUL JONGSEONG SSANGRIEUL", + direction="l", + linebreak="jt", + unicodeslot=0x11D0, + }, + [0x11D1]={ + category="lo", + description="HANGUL JONGSEONG RIEUL-MIEUM-KIYEOK", + direction="l", + linebreak="jt", + unicodeslot=0x11D1, + }, + [0x11D2]={ + category="lo", + description="HANGUL JONGSEONG RIEUL-MIEUM-SIOS", + direction="l", + linebreak="jt", + unicodeslot=0x11D2, + }, + [0x11D3]={ + category="lo", + description="HANGUL JONGSEONG RIEUL-PIEUP-SIOS", + direction="l", + linebreak="jt", + unicodeslot=0x11D3, + }, + [0x11D4]={ + category="lo", + description="HANGUL JONGSEONG RIEUL-PIEUP-HIEUH", + direction="l", + linebreak="jt", + unicodeslot=0x11D4, + }, + [0x11D5]={ + category="lo", + description="HANGUL JONGSEONG RIEUL-KAPYEOUNPIEUP", + direction="l", + linebreak="jt", + unicodeslot=0x11D5, + }, + [0x11D6]={ + category="lo", + description="HANGUL JONGSEONG RIEUL-SSANGSIOS", + direction="l", + linebreak="jt", + unicodeslot=0x11D6, + }, + [0x11D7]={ + category="lo", + description="HANGUL JONGSEONG RIEUL-PANSIOS", + direction="l", + linebreak="jt", + unicodeslot=0x11D7, + }, + [0x11D8]={ + category="lo", + description="HANGUL JONGSEONG RIEUL-KHIEUKH", + direction="l", + linebreak="jt", + unicodeslot=0x11D8, + }, + [0x11D9]={ + category="lo", + description="HANGUL JONGSEONG RIEUL-YEORINHIEUH", + direction="l", + linebreak="jt", + unicodeslot=0x11D9, + }, + [0x11DA]={ + category="lo", + description="HANGUL JONGSEONG MIEUM-KIYEOK", + direction="l", + linebreak="jt", + unicodeslot=0x11DA, + }, + [0x11DB]={ + category="lo", + description="HANGUL JONGSEONG MIEUM-RIEUL", + direction="l", + linebreak="jt", + unicodeslot=0x11DB, + }, + [0x11DC]={ + category="lo", + description="HANGUL JONGSEONG MIEUM-PIEUP", + direction="l", + linebreak="jt", + unicodeslot=0x11DC, + }, + [0x11DD]={ + category="lo", + description="HANGUL JONGSEONG MIEUM-SIOS", + direction="l", + linebreak="jt", + unicodeslot=0x11DD, + }, + [0x11DE]={ + category="lo", + description="HANGUL JONGSEONG MIEUM-SSANGSIOS", + direction="l", + linebreak="jt", + unicodeslot=0x11DE, + }, + [0x11DF]={ + category="lo", + description="HANGUL JONGSEONG MIEUM-PANSIOS", + direction="l", + linebreak="jt", + unicodeslot=0x11DF, + }, + [0x11E0]={ + category="lo", + description="HANGUL JONGSEONG MIEUM-CHIEUCH", + direction="l", + linebreak="jt", + unicodeslot=0x11E0, + }, + [0x11E1]={ + category="lo", + description="HANGUL JONGSEONG MIEUM-HIEUH", + direction="l", + linebreak="jt", + unicodeslot=0x11E1, + }, + [0x11E2]={ + category="lo", + description="HANGUL JONGSEONG KAPYEOUNMIEUM", + direction="l", + linebreak="jt", + unicodeslot=0x11E2, + }, + [0x11E3]={ + category="lo", + description="HANGUL JONGSEONG PIEUP-RIEUL", + direction="l", + linebreak="jt", + unicodeslot=0x11E3, + }, + [0x11E4]={ + category="lo", + description="HANGUL JONGSEONG PIEUP-PHIEUPH", + direction="l", + linebreak="jt", + unicodeslot=0x11E4, + }, + [0x11E5]={ + category="lo", + description="HANGUL JONGSEONG PIEUP-HIEUH", + direction="l", + linebreak="jt", + unicodeslot=0x11E5, + }, + [0x11E6]={ + category="lo", + description="HANGUL JONGSEONG KAPYEOUNPIEUP", + direction="l", + linebreak="jt", + unicodeslot=0x11E6, + }, + [0x11E7]={ + category="lo", + description="HANGUL JONGSEONG SIOS-KIYEOK", + direction="l", + linebreak="jt", + unicodeslot=0x11E7, + }, + [0x11E8]={ + category="lo", + description="HANGUL JONGSEONG SIOS-TIKEUT", + direction="l", + linebreak="jt", + unicodeslot=0x11E8, + }, + [0x11E9]={ + category="lo", + description="HANGUL JONGSEONG SIOS-RIEUL", + direction="l", + linebreak="jt", + unicodeslot=0x11E9, + }, + [0x11EA]={ + category="lo", + description="HANGUL JONGSEONG SIOS-PIEUP", + direction="l", + linebreak="jt", + unicodeslot=0x11EA, + }, + [0x11EB]={ + category="lo", + description="HANGUL JONGSEONG PANSIOS", + direction="l", + linebreak="jt", + unicodeslot=0x11EB, + }, + [0x11EC]={ + category="lo", + description="HANGUL JONGSEONG IEUNG-KIYEOK", + direction="l", + linebreak="jt", + unicodeslot=0x11EC, + }, + [0x11ED]={ + category="lo", + description="HANGUL JONGSEONG IEUNG-SSANGKIYEOK", + direction="l", + linebreak="jt", + unicodeslot=0x11ED, + }, + [0x11EE]={ + category="lo", + description="HANGUL JONGSEONG SSANGIEUNG", + direction="l", + linebreak="jt", + unicodeslot=0x11EE, + }, + [0x11EF]={ + category="lo", + description="HANGUL JONGSEONG IEUNG-KHIEUKH", + direction="l", + linebreak="jt", + unicodeslot=0x11EF, + }, + [0x11F0]={ + category="lo", + description="HANGUL JONGSEONG YESIEUNG", + direction="l", + linebreak="jt", + unicodeslot=0x11F0, + }, + [0x11F1]={ + category="lo", + description="HANGUL JONGSEONG YESIEUNG-SIOS", + direction="l", + linebreak="jt", + unicodeslot=0x11F1, + }, + [0x11F2]={ + category="lo", + description="HANGUL JONGSEONG YESIEUNG-PANSIOS", + direction="l", + linebreak="jt", + unicodeslot=0x11F2, + }, + [0x11F3]={ + category="lo", + description="HANGUL JONGSEONG PHIEUPH-PIEUP", + direction="l", + linebreak="jt", + unicodeslot=0x11F3, + }, + [0x11F4]={ + category="lo", + description="HANGUL JONGSEONG KAPYEOUNPHIEUPH", + direction="l", + linebreak="jt", + unicodeslot=0x11F4, + }, + [0x11F5]={ + category="lo", + description="HANGUL JONGSEONG HIEUH-NIEUN", + direction="l", + linebreak="jt", + unicodeslot=0x11F5, + }, + [0x11F6]={ + category="lo", + description="HANGUL JONGSEONG HIEUH-RIEUL", + direction="l", + linebreak="jt", + unicodeslot=0x11F6, + }, + [0x11F7]={ + category="lo", + description="HANGUL JONGSEONG HIEUH-MIEUM", + direction="l", + linebreak="jt", + unicodeslot=0x11F7, + }, + [0x11F8]={ + category="lo", + description="HANGUL JONGSEONG HIEUH-PIEUP", + direction="l", + linebreak="jt", + unicodeslot=0x11F8, + }, + [0x11F9]={ + category="lo", + description="HANGUL JONGSEONG YEORINHIEUH", + direction="l", + linebreak="jt", + unicodeslot=0x11F9, + }, + [0x1200]={ + category="lo", + description="ETHIOPIC SYLLABLE HA", + direction="l", + linebreak="al", + unicodeslot=0x1200, + }, + [0x1201]={ + category="lo", + description="ETHIOPIC SYLLABLE HU", + direction="l", + linebreak="al", + unicodeslot=0x1201, + }, + [0x1202]={ + category="lo", + description="ETHIOPIC SYLLABLE HI", + direction="l", + linebreak="al", + unicodeslot=0x1202, + }, + [0x1203]={ + category="lo", + description="ETHIOPIC SYLLABLE HAA", + direction="l", + linebreak="al", + unicodeslot=0x1203, + }, + [0x1204]={ + category="lo", + description="ETHIOPIC SYLLABLE HEE", + direction="l", + linebreak="al", + unicodeslot=0x1204, + }, + [0x1205]={ + category="lo", + description="ETHIOPIC SYLLABLE HE", + direction="l", + linebreak="al", + unicodeslot=0x1205, + }, + [0x1206]={ + category="lo", + description="ETHIOPIC SYLLABLE HO", + direction="l", + linebreak="al", + unicodeslot=0x1206, + }, + [0x1207]={ + category="lo", + description="ETHIOPIC SYLLABLE HOA", + direction="l", + linebreak="al", + unicodeslot=0x1207, + }, + [0x1208]={ + category="lo", + description="ETHIOPIC SYLLABLE LA", + direction="l", + linebreak="al", + unicodeslot=0x1208, + }, + [0x1209]={ + category="lo", + description="ETHIOPIC SYLLABLE LU", + direction="l", + linebreak="al", + unicodeslot=0x1209, + }, + [0x120A]={ + category="lo", + description="ETHIOPIC SYLLABLE LI", + direction="l", + linebreak="al", + unicodeslot=0x120A, + }, + [0x120B]={ + category="lo", + description="ETHIOPIC SYLLABLE LAA", + direction="l", + linebreak="al", + unicodeslot=0x120B, + }, + [0x120C]={ + category="lo", + description="ETHIOPIC SYLLABLE LEE", + direction="l", + linebreak="al", + unicodeslot=0x120C, + }, + [0x120D]={ + category="lo", + description="ETHIOPIC SYLLABLE LE", + direction="l", + linebreak="al", + unicodeslot=0x120D, + }, + [0x120E]={ + category="lo", + description="ETHIOPIC SYLLABLE LO", + direction="l", + linebreak="al", + unicodeslot=0x120E, + }, + [0x120F]={ + category="lo", + description="ETHIOPIC SYLLABLE LWA", + direction="l", + linebreak="al", + unicodeslot=0x120F, + }, + [0x1210]={ + category="lo", + description="ETHIOPIC SYLLABLE HHA", + direction="l", + linebreak="al", + unicodeslot=0x1210, + }, + [0x1211]={ + category="lo", + description="ETHIOPIC SYLLABLE HHU", + direction="l", + linebreak="al", + unicodeslot=0x1211, + }, + [0x1212]={ + category="lo", + description="ETHIOPIC SYLLABLE HHI", + direction="l", + linebreak="al", + unicodeslot=0x1212, + }, + [0x1213]={ + category="lo", + description="ETHIOPIC SYLLABLE HHAA", + direction="l", + linebreak="al", + unicodeslot=0x1213, + }, + [0x1214]={ + category="lo", + description="ETHIOPIC SYLLABLE HHEE", + direction="l", + linebreak="al", + unicodeslot=0x1214, + }, + [0x1215]={ + category="lo", + description="ETHIOPIC SYLLABLE HHE", + direction="l", + linebreak="al", + unicodeslot=0x1215, + }, + [0x1216]={ + category="lo", + description="ETHIOPIC SYLLABLE HHO", + direction="l", + linebreak="al", + unicodeslot=0x1216, + }, + [0x1217]={ + category="lo", + description="ETHIOPIC SYLLABLE HHWA", + direction="l", + linebreak="al", + unicodeslot=0x1217, + }, + [0x1218]={ + category="lo", + description="ETHIOPIC SYLLABLE MA", + direction="l", + linebreak="al", + unicodeslot=0x1218, + }, + [0x1219]={ + category="lo", + description="ETHIOPIC SYLLABLE MU", + direction="l", + linebreak="al", + unicodeslot=0x1219, + }, + [0x121A]={ + category="lo", + description="ETHIOPIC SYLLABLE MI", + direction="l", + linebreak="al", + unicodeslot=0x121A, + }, + [0x121B]={ + category="lo", + description="ETHIOPIC SYLLABLE MAA", + direction="l", + linebreak="al", + unicodeslot=0x121B, + }, + [0x121C]={ + category="lo", + description="ETHIOPIC SYLLABLE MEE", + direction="l", + linebreak="al", + unicodeslot=0x121C, + }, + [0x121D]={ + category="lo", + description="ETHIOPIC SYLLABLE ME", + direction="l", + linebreak="al", + unicodeslot=0x121D, + }, + [0x121E]={ + category="lo", + description="ETHIOPIC SYLLABLE MO", + direction="l", + linebreak="al", + unicodeslot=0x121E, + }, + [0x121F]={ + category="lo", + description="ETHIOPIC SYLLABLE MWA", + direction="l", + linebreak="al", + unicodeslot=0x121F, + }, + [0x1220]={ + category="lo", + description="ETHIOPIC SYLLABLE SZA", + direction="l", + linebreak="al", + unicodeslot=0x1220, + }, + [0x1221]={ + category="lo", + description="ETHIOPIC SYLLABLE SZU", + direction="l", + linebreak="al", + unicodeslot=0x1221, + }, + [0x1222]={ + category="lo", + description="ETHIOPIC SYLLABLE SZI", + direction="l", + linebreak="al", + unicodeslot=0x1222, + }, + [0x1223]={ + category="lo", + description="ETHIOPIC SYLLABLE SZAA", + direction="l", + linebreak="al", + unicodeslot=0x1223, + }, + [0x1224]={ + category="lo", + description="ETHIOPIC SYLLABLE SZEE", + direction="l", + linebreak="al", + unicodeslot=0x1224, + }, + [0x1225]={ + category="lo", + description="ETHIOPIC SYLLABLE SZE", + direction="l", + linebreak="al", + unicodeslot=0x1225, + }, + [0x1226]={ + category="lo", + description="ETHIOPIC SYLLABLE SZO", + direction="l", + linebreak="al", + unicodeslot=0x1226, + }, + [0x1227]={ + category="lo", + description="ETHIOPIC SYLLABLE SZWA", + direction="l", + linebreak="al", + unicodeslot=0x1227, + }, + [0x1228]={ + category="lo", + description="ETHIOPIC SYLLABLE RA", + direction="l", + linebreak="al", + unicodeslot=0x1228, + }, + [0x1229]={ + category="lo", + description="ETHIOPIC SYLLABLE RU", + direction="l", + linebreak="al", + unicodeslot=0x1229, + }, + [0x122A]={ + category="lo", + description="ETHIOPIC SYLLABLE RI", + direction="l", + linebreak="al", + unicodeslot=0x122A, + }, + [0x122B]={ + category="lo", + description="ETHIOPIC SYLLABLE RAA", + direction="l", + linebreak="al", + unicodeslot=0x122B, + }, + [0x122C]={ + category="lo", + description="ETHIOPIC SYLLABLE REE", + direction="l", + linebreak="al", + unicodeslot=0x122C, + }, + [0x122D]={ + category="lo", + description="ETHIOPIC SYLLABLE RE", + direction="l", + linebreak="al", + unicodeslot=0x122D, + }, + [0x122E]={ + category="lo", + description="ETHIOPIC SYLLABLE RO", + direction="l", + linebreak="al", + unicodeslot=0x122E, + }, + [0x122F]={ + category="lo", + description="ETHIOPIC SYLLABLE RWA", + direction="l", + linebreak="al", + unicodeslot=0x122F, + }, + [0x1230]={ + category="lo", + description="ETHIOPIC SYLLABLE SA", + direction="l", + linebreak="al", + unicodeslot=0x1230, + }, + [0x1231]={ + category="lo", + description="ETHIOPIC SYLLABLE SU", + direction="l", + linebreak="al", + unicodeslot=0x1231, + }, + [0x1232]={ + category="lo", + description="ETHIOPIC SYLLABLE SI", + direction="l", + linebreak="al", + unicodeslot=0x1232, + }, + [0x1233]={ + category="lo", + description="ETHIOPIC SYLLABLE SAA", + direction="l", + linebreak="al", + unicodeslot=0x1233, + }, + [0x1234]={ + category="lo", + description="ETHIOPIC SYLLABLE SEE", + direction="l", + linebreak="al", + unicodeslot=0x1234, + }, + [0x1235]={ + category="lo", + description="ETHIOPIC SYLLABLE SE", + direction="l", + linebreak="al", + unicodeslot=0x1235, + }, + [0x1236]={ + category="lo", + description="ETHIOPIC SYLLABLE SO", + direction="l", + linebreak="al", + unicodeslot=0x1236, + }, + [0x1237]={ + category="lo", + description="ETHIOPIC SYLLABLE SWA", + direction="l", + linebreak="al", + unicodeslot=0x1237, + }, + [0x1238]={ + category="lo", + description="ETHIOPIC SYLLABLE SHA", + direction="l", + linebreak="al", + unicodeslot=0x1238, + }, + [0x1239]={ + category="lo", + description="ETHIOPIC SYLLABLE SHU", + direction="l", + linebreak="al", + unicodeslot=0x1239, + }, + [0x123A]={ + category="lo", + description="ETHIOPIC SYLLABLE SHI", + direction="l", + linebreak="al", + unicodeslot=0x123A, + }, + [0x123B]={ + category="lo", + description="ETHIOPIC SYLLABLE SHAA", + direction="l", + linebreak="al", + unicodeslot=0x123B, + }, + [0x123C]={ + category="lo", + description="ETHIOPIC SYLLABLE SHEE", + direction="l", + linebreak="al", + unicodeslot=0x123C, + }, + [0x123D]={ + category="lo", + description="ETHIOPIC SYLLABLE SHE", + direction="l", + linebreak="al", + unicodeslot=0x123D, + }, + [0x123E]={ + category="lo", + description="ETHIOPIC SYLLABLE SHO", + direction="l", + linebreak="al", + unicodeslot=0x123E, + }, + [0x123F]={ + category="lo", + description="ETHIOPIC SYLLABLE SHWA", + direction="l", + linebreak="al", + unicodeslot=0x123F, + }, + [0x1240]={ + category="lo", + description="ETHIOPIC SYLLABLE QA", + direction="l", + linebreak="al", + unicodeslot=0x1240, + }, + [0x1241]={ + category="lo", + description="ETHIOPIC SYLLABLE QU", + direction="l", + linebreak="al", + unicodeslot=0x1241, + }, + [0x1242]={ + category="lo", + description="ETHIOPIC SYLLABLE QI", + direction="l", + linebreak="al", + unicodeslot=0x1242, + }, + [0x1243]={ + category="lo", + description="ETHIOPIC SYLLABLE QAA", + direction="l", + linebreak="al", + unicodeslot=0x1243, + }, + [0x1244]={ + category="lo", + description="ETHIOPIC SYLLABLE QEE", + direction="l", + linebreak="al", + unicodeslot=0x1244, + }, + [0x1245]={ + category="lo", + description="ETHIOPIC SYLLABLE QE", + direction="l", + linebreak="al", + unicodeslot=0x1245, + }, + [0x1246]={ + category="lo", + description="ETHIOPIC SYLLABLE QO", + direction="l", + linebreak="al", + unicodeslot=0x1246, + }, + [0x1247]={ + category="lo", + description="ETHIOPIC SYLLABLE QOA", + direction="l", + linebreak="al", + unicodeslot=0x1247, + }, + [0x1248]={ + category="lo", + description="ETHIOPIC SYLLABLE QWA", + direction="l", + linebreak="al", + unicodeslot=0x1248, + }, + [0x124A]={ + category="lo", + description="ETHIOPIC SYLLABLE QWI", + direction="l", + linebreak="al", + unicodeslot=0x124A, + }, + [0x124B]={ + category="lo", + description="ETHIOPIC SYLLABLE QWAA", + direction="l", + linebreak="al", + unicodeslot=0x124B, + }, + [0x124C]={ + category="lo", + description="ETHIOPIC SYLLABLE QWEE", + direction="l", + linebreak="al", + unicodeslot=0x124C, + }, + [0x124D]={ + category="lo", + description="ETHIOPIC SYLLABLE QWE", + direction="l", + linebreak="al", + unicodeslot=0x124D, + }, + [0x1250]={ + category="lo", + description="ETHIOPIC SYLLABLE QHA", + direction="l", + linebreak="al", + unicodeslot=0x1250, + }, + [0x1251]={ + category="lo", + description="ETHIOPIC SYLLABLE QHU", + direction="l", + linebreak="al", + unicodeslot=0x1251, + }, + [0x1252]={ + category="lo", + description="ETHIOPIC SYLLABLE QHI", + direction="l", + linebreak="al", + unicodeslot=0x1252, + }, + [0x1253]={ + category="lo", + description="ETHIOPIC SYLLABLE QHAA", + direction="l", + linebreak="al", + unicodeslot=0x1253, + }, + [0x1254]={ + category="lo", + description="ETHIOPIC SYLLABLE QHEE", + direction="l", + linebreak="al", + unicodeslot=0x1254, + }, + [0x1255]={ + category="lo", + description="ETHIOPIC SYLLABLE QHE", + direction="l", + linebreak="al", + unicodeslot=0x1255, + }, + [0x1256]={ + category="lo", + description="ETHIOPIC SYLLABLE QHO", + direction="l", + linebreak="al", + unicodeslot=0x1256, + }, + [0x1258]={ + category="lo", + description="ETHIOPIC SYLLABLE QHWA", + direction="l", + linebreak="al", + unicodeslot=0x1258, + }, + [0x125A]={ + category="lo", + description="ETHIOPIC SYLLABLE QHWI", + direction="l", + linebreak="al", + unicodeslot=0x125A, + }, + [0x125B]={ + category="lo", + description="ETHIOPIC SYLLABLE QHWAA", + direction="l", + linebreak="al", + unicodeslot=0x125B, + }, + [0x125C]={ + category="lo", + description="ETHIOPIC SYLLABLE QHWEE", + direction="l", + linebreak="al", + unicodeslot=0x125C, + }, + [0x125D]={ + category="lo", + description="ETHIOPIC SYLLABLE QHWE", + direction="l", + linebreak="al", + unicodeslot=0x125D, + }, + [0x1260]={ + category="lo", + description="ETHIOPIC SYLLABLE BA", + direction="l", + linebreak="al", + unicodeslot=0x1260, + }, + [0x1261]={ + category="lo", + description="ETHIOPIC SYLLABLE BU", + direction="l", + linebreak="al", + unicodeslot=0x1261, + }, + [0x1262]={ + category="lo", + description="ETHIOPIC SYLLABLE BI", + direction="l", + linebreak="al", + unicodeslot=0x1262, + }, + [0x1263]={ + category="lo", + description="ETHIOPIC SYLLABLE BAA", + direction="l", + linebreak="al", + unicodeslot=0x1263, + }, + [0x1264]={ + category="lo", + description="ETHIOPIC SYLLABLE BEE", + direction="l", + linebreak="al", + unicodeslot=0x1264, + }, + [0x1265]={ + category="lo", + description="ETHIOPIC SYLLABLE BE", + direction="l", + linebreak="al", + unicodeslot=0x1265, + }, + [0x1266]={ + category="lo", + description="ETHIOPIC SYLLABLE BO", + direction="l", + linebreak="al", + unicodeslot=0x1266, + }, + [0x1267]={ + category="lo", + description="ETHIOPIC SYLLABLE BWA", + direction="l", + linebreak="al", + unicodeslot=0x1267, + }, + [0x1268]={ + category="lo", + description="ETHIOPIC SYLLABLE VA", + direction="l", + linebreak="al", + unicodeslot=0x1268, + }, + [0x1269]={ + category="lo", + description="ETHIOPIC SYLLABLE VU", + direction="l", + linebreak="al", + unicodeslot=0x1269, + }, + [0x126A]={ + category="lo", + description="ETHIOPIC SYLLABLE VI", + direction="l", + linebreak="al", + unicodeslot=0x126A, + }, + [0x126B]={ + category="lo", + description="ETHIOPIC SYLLABLE VAA", + direction="l", + linebreak="al", + unicodeslot=0x126B, + }, + [0x126C]={ + category="lo", + description="ETHIOPIC SYLLABLE VEE", + direction="l", + linebreak="al", + unicodeslot=0x126C, + }, + [0x126D]={ + category="lo", + description="ETHIOPIC SYLLABLE VE", + direction="l", + linebreak="al", + unicodeslot=0x126D, + }, + [0x126E]={ + category="lo", + description="ETHIOPIC SYLLABLE VO", + direction="l", + linebreak="al", + unicodeslot=0x126E, + }, + [0x126F]={ + category="lo", + description="ETHIOPIC SYLLABLE VWA", + direction="l", + linebreak="al", + unicodeslot=0x126F, + }, + [0x1270]={ + category="lo", + description="ETHIOPIC SYLLABLE TA", + direction="l", + linebreak="al", + unicodeslot=0x1270, + }, + [0x1271]={ + category="lo", + description="ETHIOPIC SYLLABLE TU", + direction="l", + linebreak="al", + unicodeslot=0x1271, + }, + [0x1272]={ + category="lo", + description="ETHIOPIC SYLLABLE TI", + direction="l", + linebreak="al", + unicodeslot=0x1272, + }, + [0x1273]={ + category="lo", + description="ETHIOPIC SYLLABLE TAA", + direction="l", + linebreak="al", + unicodeslot=0x1273, + }, + [0x1274]={ + category="lo", + description="ETHIOPIC SYLLABLE TEE", + direction="l", + linebreak="al", + unicodeslot=0x1274, + }, + [0x1275]={ + category="lo", + description="ETHIOPIC SYLLABLE TE", + direction="l", + linebreak="al", + unicodeslot=0x1275, + }, + [0x1276]={ + category="lo", + description="ETHIOPIC SYLLABLE TO", + direction="l", + linebreak="al", + unicodeslot=0x1276, + }, + [0x1277]={ + category="lo", + description="ETHIOPIC SYLLABLE TWA", + direction="l", + linebreak="al", + unicodeslot=0x1277, + }, + [0x1278]={ + category="lo", + description="ETHIOPIC SYLLABLE CA", + direction="l", + linebreak="al", + unicodeslot=0x1278, + }, + [0x1279]={ + category="lo", + description="ETHIOPIC SYLLABLE CU", + direction="l", + linebreak="al", + unicodeslot=0x1279, + }, + [0x127A]={ + category="lo", + description="ETHIOPIC SYLLABLE CI", + direction="l", + linebreak="al", + unicodeslot=0x127A, + }, + [0x127B]={ + category="lo", + description="ETHIOPIC SYLLABLE CAA", + direction="l", + linebreak="al", + unicodeslot=0x127B, + }, + [0x127C]={ + category="lo", + description="ETHIOPIC SYLLABLE CEE", + direction="l", + linebreak="al", + unicodeslot=0x127C, + }, + [0x127D]={ + category="lo", + description="ETHIOPIC SYLLABLE CE", + direction="l", + linebreak="al", + unicodeslot=0x127D, + }, + [0x127E]={ + category="lo", + description="ETHIOPIC SYLLABLE CO", + direction="l", + linebreak="al", + unicodeslot=0x127E, + }, + [0x127F]={ + category="lo", + description="ETHIOPIC SYLLABLE CWA", + direction="l", + linebreak="al", + unicodeslot=0x127F, + }, + [0x1280]={ + category="lo", + description="ETHIOPIC SYLLABLE XA", + direction="l", + linebreak="al", + unicodeslot=0x1280, + }, + [0x1281]={ + category="lo", + description="ETHIOPIC SYLLABLE XU", + direction="l", + linebreak="al", + unicodeslot=0x1281, + }, + [0x1282]={ + category="lo", + description="ETHIOPIC SYLLABLE XI", + direction="l", + linebreak="al", + unicodeslot=0x1282, + }, + [0x1283]={ + category="lo", + description="ETHIOPIC SYLLABLE XAA", + direction="l", + linebreak="al", + unicodeslot=0x1283, + }, + [0x1284]={ + category="lo", + description="ETHIOPIC SYLLABLE XEE", + direction="l", + linebreak="al", + unicodeslot=0x1284, + }, + [0x1285]={ + category="lo", + description="ETHIOPIC SYLLABLE XE", + direction="l", + linebreak="al", + unicodeslot=0x1285, + }, + [0x1286]={ + category="lo", + description="ETHIOPIC SYLLABLE XO", + direction="l", + linebreak="al", + unicodeslot=0x1286, + }, + [0x1287]={ + category="lo", + description="ETHIOPIC SYLLABLE XOA", + direction="l", + linebreak="al", + unicodeslot=0x1287, + }, + [0x1288]={ + category="lo", + description="ETHIOPIC SYLLABLE XWA", + direction="l", + linebreak="al", + unicodeslot=0x1288, + }, + [0x128A]={ + category="lo", + description="ETHIOPIC SYLLABLE XWI", + direction="l", + linebreak="al", + unicodeslot=0x128A, + }, + [0x128B]={ + category="lo", + description="ETHIOPIC SYLLABLE XWAA", + direction="l", + linebreak="al", + unicodeslot=0x128B, + }, + [0x128C]={ + category="lo", + description="ETHIOPIC SYLLABLE XWEE", + direction="l", + linebreak="al", + unicodeslot=0x128C, + }, + [0x128D]={ + category="lo", + description="ETHIOPIC SYLLABLE XWE", + direction="l", + linebreak="al", + unicodeslot=0x128D, + }, + [0x1290]={ + category="lo", + description="ETHIOPIC SYLLABLE NA", + direction="l", + linebreak="al", + unicodeslot=0x1290, + }, + [0x1291]={ + category="lo", + description="ETHIOPIC SYLLABLE NU", + direction="l", + linebreak="al", + unicodeslot=0x1291, + }, + [0x1292]={ + category="lo", + description="ETHIOPIC SYLLABLE NI", + direction="l", + linebreak="al", + unicodeslot=0x1292, + }, + [0x1293]={ + category="lo", + description="ETHIOPIC SYLLABLE NAA", + direction="l", + linebreak="al", + unicodeslot=0x1293, + }, + [0x1294]={ + category="lo", + description="ETHIOPIC SYLLABLE NEE", + direction="l", + linebreak="al", + unicodeslot=0x1294, + }, + [0x1295]={ + category="lo", + description="ETHIOPIC SYLLABLE NE", + direction="l", + linebreak="al", + unicodeslot=0x1295, + }, + [0x1296]={ + category="lo", + description="ETHIOPIC SYLLABLE NO", + direction="l", + linebreak="al", + unicodeslot=0x1296, + }, + [0x1297]={ + category="lo", + description="ETHIOPIC SYLLABLE NWA", + direction="l", + linebreak="al", + unicodeslot=0x1297, + }, + [0x1298]={ + category="lo", + description="ETHIOPIC SYLLABLE NYA", + direction="l", + linebreak="al", + unicodeslot=0x1298, + }, + [0x1299]={ + category="lo", + description="ETHIOPIC SYLLABLE NYU", + direction="l", + linebreak="al", + unicodeslot=0x1299, + }, + [0x129A]={ + category="lo", + description="ETHIOPIC SYLLABLE NYI", + direction="l", + linebreak="al", + unicodeslot=0x129A, + }, + [0x129B]={ + category="lo", + description="ETHIOPIC SYLLABLE NYAA", + direction="l", + linebreak="al", + unicodeslot=0x129B, + }, + [0x129C]={ + category="lo", + description="ETHIOPIC SYLLABLE NYEE", + direction="l", + linebreak="al", + unicodeslot=0x129C, + }, + [0x129D]={ + category="lo", + description="ETHIOPIC SYLLABLE NYE", + direction="l", + linebreak="al", + unicodeslot=0x129D, + }, + [0x129E]={ + category="lo", + description="ETHIOPIC SYLLABLE NYO", + direction="l", + linebreak="al", + unicodeslot=0x129E, + }, + [0x129F]={ + category="lo", + description="ETHIOPIC SYLLABLE NYWA", + direction="l", + linebreak="al", + unicodeslot=0x129F, + }, + [0x12A0]={ + category="lo", + description="ETHIOPIC SYLLABLE GLOTTAL A", + direction="l", + linebreak="al", + unicodeslot=0x12A0, + }, + [0x12A1]={ + category="lo", + description="ETHIOPIC SYLLABLE GLOTTAL U", + direction="l", + linebreak="al", + unicodeslot=0x12A1, + }, + [0x12A2]={ + category="lo", + description="ETHIOPIC SYLLABLE GLOTTAL I", + direction="l", + linebreak="al", + unicodeslot=0x12A2, + }, + [0x12A3]={ + category="lo", + description="ETHIOPIC SYLLABLE GLOTTAL AA", + direction="l", + linebreak="al", + unicodeslot=0x12A3, + }, + [0x12A4]={ + category="lo", + description="ETHIOPIC SYLLABLE GLOTTAL EE", + direction="l", + linebreak="al", + unicodeslot=0x12A4, + }, + [0x12A5]={ + category="lo", + description="ETHIOPIC SYLLABLE GLOTTAL E", + direction="l", + linebreak="al", + unicodeslot=0x12A5, + }, + [0x12A6]={ + category="lo", + description="ETHIOPIC SYLLABLE GLOTTAL O", + direction="l", + linebreak="al", + unicodeslot=0x12A6, + }, + [0x12A7]={ + category="lo", + description="ETHIOPIC SYLLABLE GLOTTAL WA", + direction="l", + linebreak="al", + unicodeslot=0x12A7, + }, + [0x12A8]={ + category="lo", + description="ETHIOPIC SYLLABLE KA", + direction="l", + linebreak="al", + unicodeslot=0x12A8, + }, + [0x12A9]={ + category="lo", + description="ETHIOPIC SYLLABLE KU", + direction="l", + linebreak="al", + unicodeslot=0x12A9, + }, + [0x12AA]={ + category="lo", + description="ETHIOPIC SYLLABLE KI", + direction="l", + linebreak="al", + unicodeslot=0x12AA, + }, + [0x12AB]={ + category="lo", + description="ETHIOPIC SYLLABLE KAA", + direction="l", + linebreak="al", + unicodeslot=0x12AB, + }, + [0x12AC]={ + category="lo", + description="ETHIOPIC SYLLABLE KEE", + direction="l", + linebreak="al", + unicodeslot=0x12AC, + }, + [0x12AD]={ + category="lo", + description="ETHIOPIC SYLLABLE KE", + direction="l", + linebreak="al", + unicodeslot=0x12AD, + }, + [0x12AE]={ + category="lo", + description="ETHIOPIC SYLLABLE KO", + direction="l", + linebreak="al", + unicodeslot=0x12AE, + }, + [0x12AF]={ + category="lo", + description="ETHIOPIC SYLLABLE KOA", + direction="l", + linebreak="al", + unicodeslot=0x12AF, + }, + [0x12B0]={ + category="lo", + description="ETHIOPIC SYLLABLE KWA", + direction="l", + linebreak="al", + unicodeslot=0x12B0, + }, + [0x12B2]={ + category="lo", + description="ETHIOPIC SYLLABLE KWI", + direction="l", + linebreak="al", + unicodeslot=0x12B2, + }, + [0x12B3]={ + category="lo", + description="ETHIOPIC SYLLABLE KWAA", + direction="l", + linebreak="al", + unicodeslot=0x12B3, + }, + [0x12B4]={ + category="lo", + description="ETHIOPIC SYLLABLE KWEE", + direction="l", + linebreak="al", + unicodeslot=0x12B4, + }, + [0x12B5]={ + category="lo", + description="ETHIOPIC SYLLABLE KWE", + direction="l", + linebreak="al", + unicodeslot=0x12B5, + }, + [0x12B8]={ + category="lo", + description="ETHIOPIC SYLLABLE KXA", + direction="l", + linebreak="al", + unicodeslot=0x12B8, + }, + [0x12B9]={ + category="lo", + description="ETHIOPIC SYLLABLE KXU", + direction="l", + linebreak="al", + unicodeslot=0x12B9, + }, + [0x12BA]={ + category="lo", + description="ETHIOPIC SYLLABLE KXI", + direction="l", + linebreak="al", + unicodeslot=0x12BA, + }, + [0x12BB]={ + category="lo", + description="ETHIOPIC SYLLABLE KXAA", + direction="l", + linebreak="al", + unicodeslot=0x12BB, + }, + [0x12BC]={ + category="lo", + description="ETHIOPIC SYLLABLE KXEE", + direction="l", + linebreak="al", + unicodeslot=0x12BC, + }, + [0x12BD]={ + category="lo", + description="ETHIOPIC SYLLABLE KXE", + direction="l", + linebreak="al", + unicodeslot=0x12BD, + }, + [0x12BE]={ + category="lo", + description="ETHIOPIC SYLLABLE KXO", + direction="l", + linebreak="al", + unicodeslot=0x12BE, + }, + [0x12C0]={ + category="lo", + description="ETHIOPIC SYLLABLE KXWA", + direction="l", + linebreak="al", + unicodeslot=0x12C0, + }, + [0x12C2]={ + category="lo", + description="ETHIOPIC SYLLABLE KXWI", + direction="l", + linebreak="al", + unicodeslot=0x12C2, + }, + [0x12C3]={ + category="lo", + description="ETHIOPIC SYLLABLE KXWAA", + direction="l", + linebreak="al", + unicodeslot=0x12C3, + }, + [0x12C4]={ + category="lo", + description="ETHIOPIC SYLLABLE KXWEE", + direction="l", + linebreak="al", + unicodeslot=0x12C4, + }, + [0x12C5]={ + category="lo", + description="ETHIOPIC SYLLABLE KXWE", + direction="l", + linebreak="al", + unicodeslot=0x12C5, + }, + [0x12C8]={ + category="lo", + description="ETHIOPIC SYLLABLE WA", + direction="l", + linebreak="al", + unicodeslot=0x12C8, + }, + [0x12C9]={ + category="lo", + description="ETHIOPIC SYLLABLE WU", + direction="l", + linebreak="al", + unicodeslot=0x12C9, + }, + [0x12CA]={ + category="lo", + description="ETHIOPIC SYLLABLE WI", + direction="l", + linebreak="al", + unicodeslot=0x12CA, + }, + [0x12CB]={ + category="lo", + description="ETHIOPIC SYLLABLE WAA", + direction="l", + linebreak="al", + unicodeslot=0x12CB, + }, + [0x12CC]={ + category="lo", + description="ETHIOPIC SYLLABLE WEE", + direction="l", + linebreak="al", + unicodeslot=0x12CC, + }, + [0x12CD]={ + category="lo", + description="ETHIOPIC SYLLABLE WE", + direction="l", + linebreak="al", + unicodeslot=0x12CD, + }, + [0x12CE]={ + category="lo", + description="ETHIOPIC SYLLABLE WO", + direction="l", + linebreak="al", + unicodeslot=0x12CE, + }, + [0x12CF]={ + category="lo", + description="ETHIOPIC SYLLABLE WOA", + direction="l", + linebreak="al", + unicodeslot=0x12CF, + }, + [0x12D0]={ + category="lo", + description="ETHIOPIC SYLLABLE PHARYNGEAL A", + direction="l", + linebreak="al", + unicodeslot=0x12D0, + }, + [0x12D1]={ + category="lo", + description="ETHIOPIC SYLLABLE PHARYNGEAL U", + direction="l", + linebreak="al", + unicodeslot=0x12D1, + }, + [0x12D2]={ + category="lo", + description="ETHIOPIC SYLLABLE PHARYNGEAL I", + direction="l", + linebreak="al", + unicodeslot=0x12D2, + }, + [0x12D3]={ + category="lo", + description="ETHIOPIC SYLLABLE PHARYNGEAL AA", + direction="l", + linebreak="al", + unicodeslot=0x12D3, + }, + [0x12D4]={ + category="lo", + description="ETHIOPIC SYLLABLE PHARYNGEAL EE", + direction="l", + linebreak="al", + unicodeslot=0x12D4, + }, + [0x12D5]={ + category="lo", + description="ETHIOPIC SYLLABLE PHARYNGEAL E", + direction="l", + linebreak="al", + unicodeslot=0x12D5, + }, + [0x12D6]={ + category="lo", + description="ETHIOPIC SYLLABLE PHARYNGEAL O", + direction="l", + linebreak="al", + unicodeslot=0x12D6, + }, + [0x12D8]={ + category="lo", + description="ETHIOPIC SYLLABLE ZA", + direction="l", + linebreak="al", + unicodeslot=0x12D8, + }, + [0x12D9]={ + category="lo", + description="ETHIOPIC SYLLABLE ZU", + direction="l", + linebreak="al", + unicodeslot=0x12D9, + }, + [0x12DA]={ + category="lo", + description="ETHIOPIC SYLLABLE ZI", + direction="l", + linebreak="al", + unicodeslot=0x12DA, + }, + [0x12DB]={ + category="lo", + description="ETHIOPIC SYLLABLE ZAA", + direction="l", + linebreak="al", + unicodeslot=0x12DB, + }, + [0x12DC]={ + category="lo", + description="ETHIOPIC SYLLABLE ZEE", + direction="l", + linebreak="al", + unicodeslot=0x12DC, + }, + [0x12DD]={ + category="lo", + description="ETHIOPIC SYLLABLE ZE", + direction="l", + linebreak="al", + unicodeslot=0x12DD, + }, + [0x12DE]={ + category="lo", + description="ETHIOPIC SYLLABLE ZO", + direction="l", + linebreak="al", + unicodeslot=0x12DE, + }, + [0x12DF]={ + category="lo", + description="ETHIOPIC SYLLABLE ZWA", + direction="l", + linebreak="al", + unicodeslot=0x12DF, + }, + [0x12E0]={ + category="lo", + description="ETHIOPIC SYLLABLE ZHA", + direction="l", + linebreak="al", + unicodeslot=0x12E0, + }, + [0x12E1]={ + category="lo", + description="ETHIOPIC SYLLABLE ZHU", + direction="l", + linebreak="al", + unicodeslot=0x12E1, + }, + [0x12E2]={ + category="lo", + description="ETHIOPIC SYLLABLE ZHI", + direction="l", + linebreak="al", + unicodeslot=0x12E2, + }, + [0x12E3]={ + category="lo", + description="ETHIOPIC SYLLABLE ZHAA", + direction="l", + linebreak="al", + unicodeslot=0x12E3, + }, + [0x12E4]={ + category="lo", + description="ETHIOPIC SYLLABLE ZHEE", + direction="l", + linebreak="al", + unicodeslot=0x12E4, + }, + [0x12E5]={ + category="lo", + description="ETHIOPIC SYLLABLE ZHE", + direction="l", + linebreak="al", + unicodeslot=0x12E5, + }, + [0x12E6]={ + category="lo", + description="ETHIOPIC SYLLABLE ZHO", + direction="l", + linebreak="al", + unicodeslot=0x12E6, + }, + [0x12E7]={ + category="lo", + description="ETHIOPIC SYLLABLE ZHWA", + direction="l", + linebreak="al", + unicodeslot=0x12E7, + }, + [0x12E8]={ + category="lo", + description="ETHIOPIC SYLLABLE YA", + direction="l", + linebreak="al", + unicodeslot=0x12E8, + }, + [0x12E9]={ + category="lo", + description="ETHIOPIC SYLLABLE YU", + direction="l", + linebreak="al", + unicodeslot=0x12E9, + }, + [0x12EA]={ + category="lo", + description="ETHIOPIC SYLLABLE YI", + direction="l", + linebreak="al", + unicodeslot=0x12EA, + }, + [0x12EB]={ + category="lo", + description="ETHIOPIC SYLLABLE YAA", + direction="l", + linebreak="al", + unicodeslot=0x12EB, + }, + [0x12EC]={ + category="lo", + description="ETHIOPIC SYLLABLE YEE", + direction="l", + linebreak="al", + unicodeslot=0x12EC, + }, + [0x12ED]={ + category="lo", + description="ETHIOPIC SYLLABLE YE", + direction="l", + linebreak="al", + unicodeslot=0x12ED, + }, + [0x12EE]={ + category="lo", + description="ETHIOPIC SYLLABLE YO", + direction="l", + linebreak="al", + unicodeslot=0x12EE, + }, + [0x12EF]={ + category="lo", + description="ETHIOPIC SYLLABLE YOA", + direction="l", + linebreak="al", + unicodeslot=0x12EF, + }, + [0x12F0]={ + category="lo", + description="ETHIOPIC SYLLABLE DA", + direction="l", + linebreak="al", + unicodeslot=0x12F0, + }, + [0x12F1]={ + category="lo", + description="ETHIOPIC SYLLABLE DU", + direction="l", + linebreak="al", + unicodeslot=0x12F1, + }, + [0x12F2]={ + category="lo", + description="ETHIOPIC SYLLABLE DI", + direction="l", + linebreak="al", + unicodeslot=0x12F2, + }, + [0x12F3]={ + category="lo", + description="ETHIOPIC SYLLABLE DAA", + direction="l", + linebreak="al", + unicodeslot=0x12F3, + }, + [0x12F4]={ + category="lo", + description="ETHIOPIC SYLLABLE DEE", + direction="l", + linebreak="al", + unicodeslot=0x12F4, + }, + [0x12F5]={ + category="lo", + description="ETHIOPIC SYLLABLE DE", + direction="l", + linebreak="al", + unicodeslot=0x12F5, + }, + [0x12F6]={ + category="lo", + description="ETHIOPIC SYLLABLE DO", + direction="l", + linebreak="al", + unicodeslot=0x12F6, + }, + [0x12F7]={ + category="lo", + description="ETHIOPIC SYLLABLE DWA", + direction="l", + linebreak="al", + unicodeslot=0x12F7, + }, + [0x12F8]={ + category="lo", + description="ETHIOPIC SYLLABLE DDA", + direction="l", + linebreak="al", + unicodeslot=0x12F8, + }, + [0x12F9]={ + category="lo", + description="ETHIOPIC SYLLABLE DDU", + direction="l", + linebreak="al", + unicodeslot=0x12F9, + }, + [0x12FA]={ + category="lo", + description="ETHIOPIC SYLLABLE DDI", + direction="l", + linebreak="al", + unicodeslot=0x12FA, + }, + [0x12FB]={ + category="lo", + description="ETHIOPIC SYLLABLE DDAA", + direction="l", + linebreak="al", + unicodeslot=0x12FB, + }, + [0x12FC]={ + category="lo", + description="ETHIOPIC SYLLABLE DDEE", + direction="l", + linebreak="al", + unicodeslot=0x12FC, + }, + [0x12FD]={ + category="lo", + description="ETHIOPIC SYLLABLE DDE", + direction="l", + linebreak="al", + unicodeslot=0x12FD, + }, + [0x12FE]={ + category="lo", + description="ETHIOPIC SYLLABLE DDO", + direction="l", + linebreak="al", + unicodeslot=0x12FE, + }, + [0x12FF]={ + category="lo", + description="ETHIOPIC SYLLABLE DDWA", + direction="l", + linebreak="al", + unicodeslot=0x12FF, + }, + [0x1300]={ + category="lo", + description="ETHIOPIC SYLLABLE JA", + direction="l", + linebreak="al", + unicodeslot=0x1300, + }, + [0x1301]={ + category="lo", + description="ETHIOPIC SYLLABLE JU", + direction="l", + linebreak="al", + unicodeslot=0x1301, + }, + [0x1302]={ + category="lo", + description="ETHIOPIC SYLLABLE JI", + direction="l", + linebreak="al", + unicodeslot=0x1302, + }, + [0x1303]={ + category="lo", + description="ETHIOPIC SYLLABLE JAA", + direction="l", + linebreak="al", + unicodeslot=0x1303, + }, + [0x1304]={ + category="lo", + description="ETHIOPIC SYLLABLE JEE", + direction="l", + linebreak="al", + unicodeslot=0x1304, + }, + [0x1305]={ + category="lo", + description="ETHIOPIC SYLLABLE JE", + direction="l", + linebreak="al", + unicodeslot=0x1305, + }, + [0x1306]={ + category="lo", + description="ETHIOPIC SYLLABLE JO", + direction="l", + linebreak="al", + unicodeslot=0x1306, + }, + [0x1307]={ + category="lo", + description="ETHIOPIC SYLLABLE JWA", + direction="l", + linebreak="al", + unicodeslot=0x1307, + }, + [0x1308]={ + category="lo", + description="ETHIOPIC SYLLABLE GA", + direction="l", + linebreak="al", + unicodeslot=0x1308, + }, + [0x1309]={ + category="lo", + description="ETHIOPIC SYLLABLE GU", + direction="l", + linebreak="al", + unicodeslot=0x1309, + }, + [0x130A]={ + category="lo", + description="ETHIOPIC SYLLABLE GI", + direction="l", + linebreak="al", + unicodeslot=0x130A, + }, + [0x130B]={ + category="lo", + description="ETHIOPIC SYLLABLE GAA", + direction="l", + linebreak="al", + unicodeslot=0x130B, + }, + [0x130C]={ + category="lo", + description="ETHIOPIC SYLLABLE GEE", + direction="l", + linebreak="al", + unicodeslot=0x130C, + }, + [0x130D]={ + category="lo", + description="ETHIOPIC SYLLABLE GE", + direction="l", + linebreak="al", + unicodeslot=0x130D, + }, + [0x130E]={ + category="lo", + description="ETHIOPIC SYLLABLE GO", + direction="l", + linebreak="al", + unicodeslot=0x130E, + }, + [0x130F]={ + category="lo", + description="ETHIOPIC SYLLABLE GOA", + direction="l", + linebreak="al", + unicodeslot=0x130F, + }, + [0x1310]={ + category="lo", + description="ETHIOPIC SYLLABLE GWA", + direction="l", + linebreak="al", + unicodeslot=0x1310, + }, + [0x1312]={ + category="lo", + description="ETHIOPIC SYLLABLE GWI", + direction="l", + linebreak="al", + unicodeslot=0x1312, + }, + [0x1313]={ + category="lo", + description="ETHIOPIC SYLLABLE GWAA", + direction="l", + linebreak="al", + unicodeslot=0x1313, + }, + [0x1314]={ + category="lo", + description="ETHIOPIC SYLLABLE GWEE", + direction="l", + linebreak="al", + unicodeslot=0x1314, + }, + [0x1315]={ + category="lo", + description="ETHIOPIC SYLLABLE GWE", + direction="l", + linebreak="al", + unicodeslot=0x1315, + }, + [0x1318]={ + category="lo", + description="ETHIOPIC SYLLABLE GGA", + direction="l", + linebreak="al", + unicodeslot=0x1318, + }, + [0x1319]={ + category="lo", + description="ETHIOPIC SYLLABLE GGU", + direction="l", + linebreak="al", + unicodeslot=0x1319, + }, + [0x131A]={ + category="lo", + description="ETHIOPIC SYLLABLE GGI", + direction="l", + linebreak="al", + unicodeslot=0x131A, + }, + [0x131B]={ + category="lo", + description="ETHIOPIC SYLLABLE GGAA", + direction="l", + linebreak="al", + unicodeslot=0x131B, + }, + [0x131C]={ + category="lo", + description="ETHIOPIC SYLLABLE GGEE", + direction="l", + linebreak="al", + unicodeslot=0x131C, + }, + [0x131D]={ + category="lo", + description="ETHIOPIC SYLLABLE GGE", + direction="l", + linebreak="al", + unicodeslot=0x131D, + }, + [0x131E]={ + category="lo", + description="ETHIOPIC SYLLABLE GGO", + direction="l", + linebreak="al", + unicodeslot=0x131E, + }, + [0x131F]={ + category="lo", + description="ETHIOPIC SYLLABLE GGWAA", + direction="l", + linebreak="al", + unicodeslot=0x131F, + }, + [0x1320]={ + category="lo", + description="ETHIOPIC SYLLABLE THA", + direction="l", + linebreak="al", + unicodeslot=0x1320, + }, + [0x1321]={ + category="lo", + description="ETHIOPIC SYLLABLE THU", + direction="l", + linebreak="al", + unicodeslot=0x1321, + }, + [0x1322]={ + category="lo", + description="ETHIOPIC SYLLABLE THI", + direction="l", + linebreak="al", + unicodeslot=0x1322, + }, + [0x1323]={ + category="lo", + description="ETHIOPIC SYLLABLE THAA", + direction="l", + linebreak="al", + unicodeslot=0x1323, + }, + [0x1324]={ + category="lo", + description="ETHIOPIC SYLLABLE THEE", + direction="l", + linebreak="al", + unicodeslot=0x1324, + }, + [0x1325]={ + category="lo", + description="ETHIOPIC SYLLABLE THE", + direction="l", + linebreak="al", + unicodeslot=0x1325, + }, + [0x1326]={ + category="lo", + description="ETHIOPIC SYLLABLE THO", + direction="l", + linebreak="al", + unicodeslot=0x1326, + }, + [0x1327]={ + category="lo", + description="ETHIOPIC SYLLABLE THWA", + direction="l", + linebreak="al", + unicodeslot=0x1327, + }, + [0x1328]={ + category="lo", + description="ETHIOPIC SYLLABLE CHA", + direction="l", + linebreak="al", + unicodeslot=0x1328, + }, + [0x1329]={ + category="lo", + description="ETHIOPIC SYLLABLE CHU", + direction="l", + linebreak="al", + unicodeslot=0x1329, + }, + [0x132A]={ + category="lo", + description="ETHIOPIC SYLLABLE CHI", + direction="l", + linebreak="al", + unicodeslot=0x132A, + }, + [0x132B]={ + category="lo", + description="ETHIOPIC SYLLABLE CHAA", + direction="l", + linebreak="al", + unicodeslot=0x132B, + }, + [0x132C]={ + category="lo", + description="ETHIOPIC SYLLABLE CHEE", + direction="l", + linebreak="al", + unicodeslot=0x132C, + }, + [0x132D]={ + category="lo", + description="ETHIOPIC SYLLABLE CHE", + direction="l", + linebreak="al", + unicodeslot=0x132D, + }, + [0x132E]={ + category="lo", + description="ETHIOPIC SYLLABLE CHO", + direction="l", + linebreak="al", + unicodeslot=0x132E, + }, + [0x132F]={ + category="lo", + description="ETHIOPIC SYLLABLE CHWA", + direction="l", + linebreak="al", + unicodeslot=0x132F, + }, + [0x1330]={ + category="lo", + description="ETHIOPIC SYLLABLE PHA", + direction="l", + linebreak="al", + unicodeslot=0x1330, + }, + [0x1331]={ + category="lo", + description="ETHIOPIC SYLLABLE PHU", + direction="l", + linebreak="al", + unicodeslot=0x1331, + }, + [0x1332]={ + category="lo", + description="ETHIOPIC SYLLABLE PHI", + direction="l", + linebreak="al", + unicodeslot=0x1332, + }, + [0x1333]={ + category="lo", + description="ETHIOPIC SYLLABLE PHAA", + direction="l", + linebreak="al", + unicodeslot=0x1333, + }, + [0x1334]={ + category="lo", + description="ETHIOPIC SYLLABLE PHEE", + direction="l", + linebreak="al", + unicodeslot=0x1334, + }, + [0x1335]={ + category="lo", + description="ETHIOPIC SYLLABLE PHE", + direction="l", + linebreak="al", + unicodeslot=0x1335, + }, + [0x1336]={ + category="lo", + description="ETHIOPIC SYLLABLE PHO", + direction="l", + linebreak="al", + unicodeslot=0x1336, + }, + [0x1337]={ + category="lo", + description="ETHIOPIC SYLLABLE PHWA", + direction="l", + linebreak="al", + unicodeslot=0x1337, + }, + [0x1338]={ + category="lo", + description="ETHIOPIC SYLLABLE TSA", + direction="l", + linebreak="al", + unicodeslot=0x1338, + }, + [0x1339]={ + category="lo", + description="ETHIOPIC SYLLABLE TSU", + direction="l", + linebreak="al", + unicodeslot=0x1339, + }, + [0x133A]={ + category="lo", + description="ETHIOPIC SYLLABLE TSI", + direction="l", + linebreak="al", + unicodeslot=0x133A, + }, + [0x133B]={ + category="lo", + description="ETHIOPIC SYLLABLE TSAA", + direction="l", + linebreak="al", + unicodeslot=0x133B, + }, + [0x133C]={ + category="lo", + description="ETHIOPIC SYLLABLE TSEE", + direction="l", + linebreak="al", + unicodeslot=0x133C, + }, + [0x133D]={ + category="lo", + description="ETHIOPIC SYLLABLE TSE", + direction="l", + linebreak="al", + unicodeslot=0x133D, + }, + [0x133E]={ + category="lo", + description="ETHIOPIC SYLLABLE TSO", + direction="l", + linebreak="al", + unicodeslot=0x133E, + }, + [0x133F]={ + category="lo", + description="ETHIOPIC SYLLABLE TSWA", + direction="l", + linebreak="al", + unicodeslot=0x133F, + }, + [0x1340]={ + category="lo", + description="ETHIOPIC SYLLABLE TZA", + direction="l", + linebreak="al", + unicodeslot=0x1340, + }, + [0x1341]={ + category="lo", + description="ETHIOPIC SYLLABLE TZU", + direction="l", + linebreak="al", + unicodeslot=0x1341, + }, + [0x1342]={ + category="lo", + description="ETHIOPIC SYLLABLE TZI", + direction="l", + linebreak="al", + unicodeslot=0x1342, + }, + [0x1343]={ + category="lo", + description="ETHIOPIC SYLLABLE TZAA", + direction="l", + linebreak="al", + unicodeslot=0x1343, + }, + [0x1344]={ + category="lo", + description="ETHIOPIC SYLLABLE TZEE", + direction="l", + linebreak="al", + unicodeslot=0x1344, + }, + [0x1345]={ + category="lo", + description="ETHIOPIC SYLLABLE TZE", + direction="l", + linebreak="al", + unicodeslot=0x1345, + }, + [0x1346]={ + category="lo", + description="ETHIOPIC SYLLABLE TZO", + direction="l", + linebreak="al", + unicodeslot=0x1346, + }, + [0x1347]={ + category="lo", + description="ETHIOPIC SYLLABLE TZOA", + direction="l", + linebreak="al", + unicodeslot=0x1347, + }, + [0x1348]={ + category="lo", + description="ETHIOPIC SYLLABLE FA", + direction="l", + linebreak="al", + unicodeslot=0x1348, + }, + [0x1349]={ + category="lo", + description="ETHIOPIC SYLLABLE FU", + direction="l", + linebreak="al", + unicodeslot=0x1349, + }, + [0x134A]={ + category="lo", + description="ETHIOPIC SYLLABLE FI", + direction="l", + linebreak="al", + unicodeslot=0x134A, + }, + [0x134B]={ + category="lo", + description="ETHIOPIC SYLLABLE FAA", + direction="l", + linebreak="al", + unicodeslot=0x134B, + }, + [0x134C]={ + category="lo", + description="ETHIOPIC SYLLABLE FEE", + direction="l", + linebreak="al", + unicodeslot=0x134C, + }, + [0x134D]={ + category="lo", + description="ETHIOPIC SYLLABLE FE", + direction="l", + linebreak="al", + unicodeslot=0x134D, + }, + [0x134E]={ + category="lo", + description="ETHIOPIC SYLLABLE FO", + direction="l", + linebreak="al", + unicodeslot=0x134E, + }, + [0x134F]={ + category="lo", + description="ETHIOPIC SYLLABLE FWA", + direction="l", + linebreak="al", + unicodeslot=0x134F, + }, + [0x1350]={ + category="lo", + description="ETHIOPIC SYLLABLE PA", + direction="l", + linebreak="al", + unicodeslot=0x1350, + }, + [0x1351]={ + category="lo", + description="ETHIOPIC SYLLABLE PU", + direction="l", + linebreak="al", + unicodeslot=0x1351, + }, + [0x1352]={ + category="lo", + description="ETHIOPIC SYLLABLE PI", + direction="l", + linebreak="al", + unicodeslot=0x1352, + }, + [0x1353]={ + category="lo", + description="ETHIOPIC SYLLABLE PAA", + direction="l", + linebreak="al", + unicodeslot=0x1353, + }, + [0x1354]={ + category="lo", + description="ETHIOPIC SYLLABLE PEE", + direction="l", + linebreak="al", + unicodeslot=0x1354, + }, + [0x1355]={ + category="lo", + description="ETHIOPIC SYLLABLE PE", + direction="l", + linebreak="al", + unicodeslot=0x1355, + }, + [0x1356]={ + category="lo", + description="ETHIOPIC SYLLABLE PO", + direction="l", + linebreak="al", + unicodeslot=0x1356, + }, + [0x1357]={ + category="lo", + description="ETHIOPIC SYLLABLE PWA", + direction="l", + linebreak="al", + unicodeslot=0x1357, + }, + [0x1358]={ + category="lo", + description="ETHIOPIC SYLLABLE RYA", + direction="l", + linebreak="al", + unicodeslot=0x1358, + }, + [0x1359]={ + category="lo", + description="ETHIOPIC SYLLABLE MYA", + direction="l", + linebreak="al", + unicodeslot=0x1359, + }, + [0x135A]={ + category="lo", + description="ETHIOPIC SYLLABLE FYA", + direction="l", + linebreak="al", + unicodeslot=0x135A, + }, + [0x135F]={ + category="mn", + description="ETHIOPIC COMBINING GEMINATION MARK", + direction="nsm", + linebreak="cm", + unicodeslot=0x135F, + }, + [0x1360]={ + category="so", + description="ETHIOPIC SECTION MARK", + direction="l", + linebreak="al", + unicodeslot=0x1360, + }, + [0x1361]={ + category="po", + description="ETHIOPIC WORDSPACE", + direction="l", + linebreak="ba", + unicodeslot=0x1361, + }, + [0x1362]={ + category="po", + description="ETHIOPIC FULL STOP", + direction="l", + linebreak="al", + unicodeslot=0x1362, + }, + [0x1363]={ + category="po", + description="ETHIOPIC COMMA", + direction="l", + linebreak="al", + unicodeslot=0x1363, + }, + [0x1364]={ + category="po", + description="ETHIOPIC SEMICOLON", + direction="l", + linebreak="al", + unicodeslot=0x1364, + }, + [0x1365]={ + category="po", + description="ETHIOPIC COLON", + direction="l", + linebreak="al", + unicodeslot=0x1365, + }, + [0x1366]={ + category="po", + description="ETHIOPIC PREFACE COLON", + direction="l", + linebreak="al", + unicodeslot=0x1366, + }, + [0x1367]={ + category="po", + description="ETHIOPIC QUESTION MARK", + direction="l", + linebreak="al", + unicodeslot=0x1367, + }, + [0x1368]={ + category="po", + description="ETHIOPIC PARAGRAPH SEPARATOR", + direction="l", + linebreak="al", + unicodeslot=0x1368, + }, + [0x1369]={ + category="no", + description="ETHIOPIC DIGIT ONE", + direction="l", + linebreak="al", + unicodeslot=0x1369, + }, + [0x136A]={ + category="no", + description="ETHIOPIC DIGIT TWO", + direction="l", + linebreak="al", + unicodeslot=0x136A, + }, + [0x136B]={ + category="no", + description="ETHIOPIC DIGIT THREE", + direction="l", + linebreak="al", + unicodeslot=0x136B, + }, + [0x136C]={ + category="no", + description="ETHIOPIC DIGIT FOUR", + direction="l", + linebreak="al", + unicodeslot=0x136C, + }, + [0x136D]={ + category="no", + description="ETHIOPIC DIGIT FIVE", + direction="l", + linebreak="al", + unicodeslot=0x136D, + }, + [0x136E]={ + category="no", + description="ETHIOPIC DIGIT SIX", + direction="l", + linebreak="al", + unicodeslot=0x136E, + }, + [0x136F]={ + category="no", + description="ETHIOPIC DIGIT SEVEN", + direction="l", + linebreak="al", + unicodeslot=0x136F, + }, + [0x1370]={ + category="no", + description="ETHIOPIC DIGIT EIGHT", + direction="l", + linebreak="al", + unicodeslot=0x1370, + }, + [0x1371]={ + category="no", + description="ETHIOPIC DIGIT NINE", + direction="l", + linebreak="al", + unicodeslot=0x1371, + }, + [0x1372]={ + category="no", + description="ETHIOPIC NUMBER TEN", + direction="l", + linebreak="al", + unicodeslot=0x1372, + }, + [0x1373]={ + category="no", + description="ETHIOPIC NUMBER TWENTY", + direction="l", + linebreak="al", + unicodeslot=0x1373, + }, + [0x1374]={ + category="no", + description="ETHIOPIC NUMBER THIRTY", + direction="l", + linebreak="al", + unicodeslot=0x1374, + }, + [0x1375]={ + category="no", + description="ETHIOPIC NUMBER FORTY", + direction="l", + linebreak="al", + unicodeslot=0x1375, + }, + [0x1376]={ + category="no", + description="ETHIOPIC NUMBER FIFTY", + direction="l", + linebreak="al", + unicodeslot=0x1376, + }, + [0x1377]={ + category="no", + description="ETHIOPIC NUMBER SIXTY", + direction="l", + linebreak="al", + unicodeslot=0x1377, + }, + [0x1378]={ + category="no", + description="ETHIOPIC NUMBER SEVENTY", + direction="l", + linebreak="al", + unicodeslot=0x1378, + }, + [0x1379]={ + category="no", + description="ETHIOPIC NUMBER EIGHTY", + direction="l", + linebreak="al", + unicodeslot=0x1379, + }, + [0x137A]={ + category="no", + description="ETHIOPIC NUMBER NINETY", + direction="l", + linebreak="al", + unicodeslot=0x137A, + }, + [0x137B]={ + category="no", + description="ETHIOPIC NUMBER HUNDRED", + direction="l", + linebreak="al", + unicodeslot=0x137B, + }, + [0x137C]={ + category="no", + description="ETHIOPIC NUMBER TEN THOUSAND", + direction="l", + linebreak="al", + unicodeslot=0x137C, + }, + [0x1380]={ + category="lo", + description="ETHIOPIC SYLLABLE SEBATBEIT MWA", + direction="l", + linebreak="al", + unicodeslot=0x1380, + }, + [0x1381]={ + category="lo", + description="ETHIOPIC SYLLABLE MWI", + direction="l", + linebreak="al", + unicodeslot=0x1381, + }, + [0x1382]={ + category="lo", + description="ETHIOPIC SYLLABLE MWEE", + direction="l", + linebreak="al", + unicodeslot=0x1382, + }, + [0x1383]={ + category="lo", + description="ETHIOPIC SYLLABLE MWE", + direction="l", + linebreak="al", + unicodeslot=0x1383, + }, + [0x1384]={ + category="lo", + description="ETHIOPIC SYLLABLE SEBATBEIT BWA", + direction="l", + linebreak="al", + unicodeslot=0x1384, + }, + [0x1385]={ + category="lo", + description="ETHIOPIC SYLLABLE BWI", + direction="l", + linebreak="al", + unicodeslot=0x1385, + }, + [0x1386]={ + category="lo", + description="ETHIOPIC SYLLABLE BWEE", + direction="l", + linebreak="al", + unicodeslot=0x1386, + }, + [0x1387]={ + category="lo", + description="ETHIOPIC SYLLABLE BWE", + direction="l", + linebreak="al", + unicodeslot=0x1387, + }, + [0x1388]={ + category="lo", + description="ETHIOPIC SYLLABLE SEBATBEIT FWA", + direction="l", + linebreak="al", + unicodeslot=0x1388, + }, + [0x1389]={ + category="lo", + description="ETHIOPIC SYLLABLE FWI", + direction="l", + linebreak="al", + unicodeslot=0x1389, + }, + [0x138A]={ + category="lo", + description="ETHIOPIC SYLLABLE FWEE", + direction="l", + linebreak="al", + unicodeslot=0x138A, + }, + [0x138B]={ + category="lo", + description="ETHIOPIC SYLLABLE FWE", + direction="l", + linebreak="al", + unicodeslot=0x138B, + }, + [0x138C]={ + category="lo", + description="ETHIOPIC SYLLABLE SEBATBEIT PWA", + direction="l", + linebreak="al", + unicodeslot=0x138C, + }, + [0x138D]={ + category="lo", + description="ETHIOPIC SYLLABLE PWI", + direction="l", + linebreak="al", + unicodeslot=0x138D, + }, + [0x138E]={ + category="lo", + description="ETHIOPIC SYLLABLE PWEE", + direction="l", + linebreak="al", + unicodeslot=0x138E, + }, + [0x138F]={ + category="lo", + description="ETHIOPIC SYLLABLE PWE", + direction="l", + linebreak="al", + unicodeslot=0x138F, + }, + [0x1390]={ + category="so", + description="ETHIOPIC TONAL MARK YIZET", + direction="on", + linebreak="al", + unicodeslot=0x1390, + }, + [0x1391]={ + category="so", + description="ETHIOPIC TONAL MARK DERET", + direction="on", + linebreak="al", + unicodeslot=0x1391, + }, + [0x1392]={ + category="so", + description="ETHIOPIC TONAL MARK RIKRIK", + direction="on", + linebreak="al", + unicodeslot=0x1392, + }, + [0x1393]={ + category="so", + description="ETHIOPIC TONAL MARK SHORT RIKRIK", + direction="on", + linebreak="al", + unicodeslot=0x1393, + }, + [0x1394]={ + category="so", + description="ETHIOPIC TONAL MARK DIFAT", + direction="on", + linebreak="al", + unicodeslot=0x1394, + }, + [0x1395]={ + category="so", + description="ETHIOPIC TONAL MARK KENAT", + direction="on", + linebreak="al", + unicodeslot=0x1395, + }, + [0x1396]={ + category="so", + description="ETHIOPIC TONAL MARK CHIRET", + direction="on", + linebreak="al", + unicodeslot=0x1396, + }, + [0x1397]={ + category="so", + description="ETHIOPIC TONAL MARK HIDET", + direction="on", + linebreak="al", + unicodeslot=0x1397, + }, + [0x1398]={ + category="so", + description="ETHIOPIC TONAL MARK DERET-HIDET", + direction="on", + linebreak="al", + unicodeslot=0x1398, + }, + [0x1399]={ + category="so", + description="ETHIOPIC TONAL MARK KURT", + direction="on", + linebreak="al", + unicodeslot=0x1399, + }, + [0x13A0]={ + category="lo", + description="CHEROKEE LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x13A0, + }, + [0x13A1]={ + category="lo", + description="CHEROKEE LETTER E", + direction="l", + linebreak="al", + unicodeslot=0x13A1, + }, + [0x13A2]={ + category="lo", + description="CHEROKEE LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x13A2, + }, + [0x13A3]={ + category="lo", + description="CHEROKEE LETTER O", + direction="l", + linebreak="al", + unicodeslot=0x13A3, + }, + [0x13A4]={ + category="lo", + description="CHEROKEE LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x13A4, + }, + [0x13A5]={ + category="lo", + description="CHEROKEE LETTER V", + direction="l", + linebreak="al", + unicodeslot=0x13A5, + }, + [0x13A6]={ + category="lo", + description="CHEROKEE LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x13A6, + }, + [0x13A7]={ + category="lo", + description="CHEROKEE LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x13A7, + }, + [0x13A8]={ + category="lo", + description="CHEROKEE LETTER GE", + direction="l", + linebreak="al", + unicodeslot=0x13A8, + }, + [0x13A9]={ + category="lo", + description="CHEROKEE LETTER GI", + direction="l", + linebreak="al", + unicodeslot=0x13A9, + }, + [0x13AA]={ + category="lo", + description="CHEROKEE LETTER GO", + direction="l", + linebreak="al", + unicodeslot=0x13AA, + }, + [0x13AB]={ + category="lo", + description="CHEROKEE LETTER GU", + direction="l", + linebreak="al", + unicodeslot=0x13AB, + }, + [0x13AC]={ + category="lo", + description="CHEROKEE LETTER GV", + direction="l", + linebreak="al", + unicodeslot=0x13AC, + }, + [0x13AD]={ + category="lo", + description="CHEROKEE LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x13AD, + }, + [0x13AE]={ + category="lo", + description="CHEROKEE LETTER HE", + direction="l", + linebreak="al", + unicodeslot=0x13AE, + }, + [0x13AF]={ + category="lo", + description="CHEROKEE LETTER HI", + direction="l", + linebreak="al", + unicodeslot=0x13AF, + }, + [0x13B0]={ + category="lo", + description="CHEROKEE LETTER HO", + direction="l", + linebreak="al", + unicodeslot=0x13B0, + }, + [0x13B1]={ + category="lo", + description="CHEROKEE LETTER HU", + direction="l", + linebreak="al", + unicodeslot=0x13B1, + }, + [0x13B2]={ + category="lo", + description="CHEROKEE LETTER HV", + direction="l", + linebreak="al", + unicodeslot=0x13B2, + }, + [0x13B3]={ + category="lo", + description="CHEROKEE LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x13B3, + }, + [0x13B4]={ + category="lo", + description="CHEROKEE LETTER LE", + direction="l", + linebreak="al", + unicodeslot=0x13B4, + }, + [0x13B5]={ + category="lo", + description="CHEROKEE LETTER LI", + direction="l", + linebreak="al", + unicodeslot=0x13B5, + }, + [0x13B6]={ + category="lo", + description="CHEROKEE LETTER LO", + direction="l", + linebreak="al", + unicodeslot=0x13B6, + }, + [0x13B7]={ + category="lo", + description="CHEROKEE LETTER LU", + direction="l", + linebreak="al", + unicodeslot=0x13B7, + }, + [0x13B8]={ + category="lo", + description="CHEROKEE LETTER LV", + direction="l", + linebreak="al", + unicodeslot=0x13B8, + }, + [0x13B9]={ + category="lo", + description="CHEROKEE LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x13B9, + }, + [0x13BA]={ + category="lo", + description="CHEROKEE LETTER ME", + direction="l", + linebreak="al", + unicodeslot=0x13BA, + }, + [0x13BB]={ + category="lo", + description="CHEROKEE LETTER MI", + direction="l", + linebreak="al", + unicodeslot=0x13BB, + }, + [0x13BC]={ + category="lo", + description="CHEROKEE LETTER MO", + direction="l", + linebreak="al", + unicodeslot=0x13BC, + }, + [0x13BD]={ + category="lo", + description="CHEROKEE LETTER MU", + direction="l", + linebreak="al", + unicodeslot=0x13BD, + }, + [0x13BE]={ + category="lo", + description="CHEROKEE LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x13BE, + }, + [0x13BF]={ + category="lo", + description="CHEROKEE LETTER HNA", + direction="l", + linebreak="al", + unicodeslot=0x13BF, + }, + [0x13C0]={ + category="lo", + description="CHEROKEE LETTER NAH", + direction="l", + linebreak="al", + unicodeslot=0x13C0, + }, + [0x13C1]={ + category="lo", + description="CHEROKEE LETTER NE", + direction="l", + linebreak="al", + unicodeslot=0x13C1, + }, + [0x13C2]={ + category="lo", + description="CHEROKEE LETTER NI", + direction="l", + linebreak="al", + unicodeslot=0x13C2, + }, + [0x13C3]={ + category="lo", + description="CHEROKEE LETTER NO", + direction="l", + linebreak="al", + unicodeslot=0x13C3, + }, + [0x13C4]={ + category="lo", + description="CHEROKEE LETTER NU", + direction="l", + linebreak="al", + unicodeslot=0x13C4, + }, + [0x13C5]={ + category="lo", + description="CHEROKEE LETTER NV", + direction="l", + linebreak="al", + unicodeslot=0x13C5, + }, + [0x13C6]={ + category="lo", + description="CHEROKEE LETTER QUA", + direction="l", + linebreak="al", + unicodeslot=0x13C6, + }, + [0x13C7]={ + category="lo", + description="CHEROKEE LETTER QUE", + direction="l", + linebreak="al", + unicodeslot=0x13C7, + }, + [0x13C8]={ + category="lo", + description="CHEROKEE LETTER QUI", + direction="l", + linebreak="al", + unicodeslot=0x13C8, + }, + [0x13C9]={ + category="lo", + description="CHEROKEE LETTER QUO", + direction="l", + linebreak="al", + unicodeslot=0x13C9, + }, + [0x13CA]={ + category="lo", + description="CHEROKEE LETTER QUU", + direction="l", + linebreak="al", + unicodeslot=0x13CA, + }, + [0x13CB]={ + category="lo", + description="CHEROKEE LETTER QUV", + direction="l", + linebreak="al", + unicodeslot=0x13CB, + }, + [0x13CC]={ + category="lo", + description="CHEROKEE LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x13CC, + }, + [0x13CD]={ + category="lo", + description="CHEROKEE LETTER S", + direction="l", + linebreak="al", + unicodeslot=0x13CD, + }, + [0x13CE]={ + category="lo", + description="CHEROKEE LETTER SE", + direction="l", + linebreak="al", + unicodeslot=0x13CE, + }, + [0x13CF]={ + category="lo", + description="CHEROKEE LETTER SI", + direction="l", + linebreak="al", + unicodeslot=0x13CF, + }, + [0x13D0]={ + category="lo", + description="CHEROKEE LETTER SO", + direction="l", + linebreak="al", + unicodeslot=0x13D0, + }, + [0x13D1]={ + category="lo", + description="CHEROKEE LETTER SU", + direction="l", + linebreak="al", + unicodeslot=0x13D1, + }, + [0x13D2]={ + category="lo", + description="CHEROKEE LETTER SV", + direction="l", + linebreak="al", + unicodeslot=0x13D2, + }, + [0x13D3]={ + category="lo", + description="CHEROKEE LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x13D3, + }, + [0x13D4]={ + category="lo", + description="CHEROKEE LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x13D4, + }, + [0x13D5]={ + category="lo", + description="CHEROKEE LETTER DE", + direction="l", + linebreak="al", + unicodeslot=0x13D5, + }, + [0x13D6]={ + category="lo", + description="CHEROKEE LETTER TE", + direction="l", + linebreak="al", + unicodeslot=0x13D6, + }, + [0x13D7]={ + category="lo", + description="CHEROKEE LETTER DI", + direction="l", + linebreak="al", + unicodeslot=0x13D7, + }, + [0x13D8]={ + category="lo", + description="CHEROKEE LETTER TI", + direction="l", + linebreak="al", + unicodeslot=0x13D8, + }, + [0x13D9]={ + category="lo", + description="CHEROKEE LETTER DO", + direction="l", + linebreak="al", + unicodeslot=0x13D9, + }, + [0x13DA]={ + category="lo", + description="CHEROKEE LETTER DU", + direction="l", + linebreak="al", + unicodeslot=0x13DA, + }, + [0x13DB]={ + category="lo", + description="CHEROKEE LETTER DV", + direction="l", + linebreak="al", + unicodeslot=0x13DB, + }, + [0x13DC]={ + category="lo", + description="CHEROKEE LETTER DLA", + direction="l", + linebreak="al", + unicodeslot=0x13DC, + }, + [0x13DD]={ + category="lo", + description="CHEROKEE LETTER TLA", + direction="l", + linebreak="al", + unicodeslot=0x13DD, + }, + [0x13DE]={ + category="lo", + description="CHEROKEE LETTER TLE", + direction="l", + linebreak="al", + unicodeslot=0x13DE, + }, + [0x13DF]={ + category="lo", + description="CHEROKEE LETTER TLI", + direction="l", + linebreak="al", + unicodeslot=0x13DF, + }, + [0x13E0]={ + category="lo", + description="CHEROKEE LETTER TLO", + direction="l", + linebreak="al", + unicodeslot=0x13E0, + }, + [0x13E1]={ + category="lo", + description="CHEROKEE LETTER TLU", + direction="l", + linebreak="al", + unicodeslot=0x13E1, + }, + [0x13E2]={ + category="lo", + description="CHEROKEE LETTER TLV", + direction="l", + linebreak="al", + unicodeslot=0x13E2, + }, + [0x13E3]={ + category="lo", + description="CHEROKEE LETTER TSA", + direction="l", + linebreak="al", + unicodeslot=0x13E3, + }, + [0x13E4]={ + category="lo", + description="CHEROKEE LETTER TSE", + direction="l", + linebreak="al", + unicodeslot=0x13E4, + }, + [0x13E5]={ + category="lo", + description="CHEROKEE LETTER TSI", + direction="l", + linebreak="al", + unicodeslot=0x13E5, + }, + [0x13E6]={ + category="lo", + description="CHEROKEE LETTER TSO", + direction="l", + linebreak="al", + unicodeslot=0x13E6, + }, + [0x13E7]={ + category="lo", + description="CHEROKEE LETTER TSU", + direction="l", + linebreak="al", + unicodeslot=0x13E7, + }, + [0x13E8]={ + category="lo", + description="CHEROKEE LETTER TSV", + direction="l", + linebreak="al", + unicodeslot=0x13E8, + }, + [0x13E9]={ + category="lo", + description="CHEROKEE LETTER WA", + direction="l", + linebreak="al", + unicodeslot=0x13E9, + }, + [0x13EA]={ + category="lo", + description="CHEROKEE LETTER WE", + direction="l", + linebreak="al", + unicodeslot=0x13EA, + }, + [0x13EB]={ + category="lo", + description="CHEROKEE LETTER WI", + direction="l", + linebreak="al", + unicodeslot=0x13EB, + }, + [0x13EC]={ + category="lo", + description="CHEROKEE LETTER WO", + direction="l", + linebreak="al", + unicodeslot=0x13EC, + }, + [0x13ED]={ + category="lo", + description="CHEROKEE LETTER WU", + direction="l", + linebreak="al", + unicodeslot=0x13ED, + }, + [0x13EE]={ + category="lo", + description="CHEROKEE LETTER WV", + direction="l", + linebreak="al", + unicodeslot=0x13EE, + }, + [0x13EF]={ + category="lo", + description="CHEROKEE LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x13EF, + }, + [0x13F0]={ + category="lo", + description="CHEROKEE LETTER YE", + direction="l", + linebreak="al", + unicodeslot=0x13F0, + }, + [0x13F1]={ + category="lo", + description="CHEROKEE LETTER YI", + direction="l", + linebreak="al", + unicodeslot=0x13F1, + }, + [0x13F2]={ + category="lo", + description="CHEROKEE LETTER YO", + direction="l", + linebreak="al", + unicodeslot=0x13F2, + }, + [0x13F3]={ + category="lo", + description="CHEROKEE LETTER YU", + direction="l", + linebreak="al", + unicodeslot=0x13F3, + }, + [0x13F4]={ + category="lo", + description="CHEROKEE LETTER YV", + direction="l", + linebreak="al", + unicodeslot=0x13F4, + }, + [0x1401]={ + category="lo", + description="CANADIAN SYLLABICS E", + direction="l", + linebreak="al", + unicodeslot=0x1401, + }, + [0x1402]={ + category="lo", + description="CANADIAN SYLLABICS AAI", + direction="l", + linebreak="al", + unicodeslot=0x1402, + }, + [0x1403]={ + category="lo", + description="CANADIAN SYLLABICS I", + direction="l", + linebreak="al", + unicodeslot=0x1403, + }, + [0x1404]={ + category="lo", + description="CANADIAN SYLLABICS II", + direction="l", + linebreak="al", + unicodeslot=0x1404, + }, + [0x1405]={ + category="lo", + description="CANADIAN SYLLABICS O", + direction="l", + linebreak="al", + unicodeslot=0x1405, + }, + [0x1406]={ + category="lo", + description="CANADIAN SYLLABICS OO", + direction="l", + linebreak="al", + unicodeslot=0x1406, + }, + [0x1407]={ + category="lo", + description="CANADIAN SYLLABICS Y-CREE OO", + direction="l", + linebreak="al", + unicodeslot=0x1407, + }, + [0x1408]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER EE", + direction="l", + linebreak="al", + unicodeslot=0x1408, + }, + [0x1409]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER I", + direction="l", + linebreak="al", + unicodeslot=0x1409, + }, + [0x140A]={ + category="lo", + description="CANADIAN SYLLABICS A", + direction="l", + linebreak="al", + unicodeslot=0x140A, + }, + [0x140B]={ + category="lo", + description="CANADIAN SYLLABICS AA", + direction="l", + linebreak="al", + unicodeslot=0x140B, + }, + [0x140C]={ + category="lo", + description="CANADIAN SYLLABICS WE", + direction="l", + linebreak="al", + unicodeslot=0x140C, + }, + [0x140D]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE WE", + direction="l", + linebreak="al", + unicodeslot=0x140D, + }, + [0x140E]={ + category="lo", + description="CANADIAN SYLLABICS WI", + direction="l", + linebreak="al", + unicodeslot=0x140E, + }, + [0x140F]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE WI", + direction="l", + linebreak="al", + unicodeslot=0x140F, + }, + [0x1410]={ + category="lo", + description="CANADIAN SYLLABICS WII", + direction="l", + linebreak="al", + unicodeslot=0x1410, + }, + [0x1411]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE WII", + direction="l", + linebreak="al", + unicodeslot=0x1411, + }, + [0x1412]={ + category="lo", + description="CANADIAN SYLLABICS WO", + direction="l", + linebreak="al", + unicodeslot=0x1412, + }, + [0x1413]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE WO", + direction="l", + linebreak="al", + unicodeslot=0x1413, + }, + [0x1414]={ + category="lo", + description="CANADIAN SYLLABICS WOO", + direction="l", + linebreak="al", + unicodeslot=0x1414, + }, + [0x1415]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE WOO", + direction="l", + linebreak="al", + unicodeslot=0x1415, + }, + [0x1416]={ + category="lo", + description="CANADIAN SYLLABICS NASKAPI WOO", + direction="l", + linebreak="al", + unicodeslot=0x1416, + }, + [0x1417]={ + category="lo", + description="CANADIAN SYLLABICS WA", + direction="l", + linebreak="al", + unicodeslot=0x1417, + }, + [0x1418]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE WA", + direction="l", + linebreak="al", + unicodeslot=0x1418, + }, + [0x1419]={ + category="lo", + description="CANADIAN SYLLABICS WAA", + direction="l", + linebreak="al", + unicodeslot=0x1419, + }, + [0x141A]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE WAA", + direction="l", + linebreak="al", + unicodeslot=0x141A, + }, + [0x141B]={ + category="lo", + description="CANADIAN SYLLABICS NASKAPI WAA", + direction="l", + linebreak="al", + unicodeslot=0x141B, + }, + [0x141C]={ + category="lo", + description="CANADIAN SYLLABICS AI", + direction="l", + linebreak="al", + unicodeslot=0x141C, + }, + [0x141D]={ + category="lo", + description="CANADIAN SYLLABICS Y-CREE W", + direction="l", + linebreak="al", + unicodeslot=0x141D, + }, + [0x141E]={ + category="lo", + description="CANADIAN SYLLABICS GLOTTAL STOP", + direction="l", + linebreak="al", + unicodeslot=0x141E, + }, + [0x141F]={ + category="lo", + description="CANADIAN SYLLABICS FINAL ACUTE", + direction="l", + linebreak="al", + unicodeslot=0x141F, + }, + [0x1420]={ + category="lo", + description="CANADIAN SYLLABICS FINAL GRAVE", + direction="l", + linebreak="al", + unicodeslot=0x1420, + }, + [0x1421]={ + category="lo", + description="CANADIAN SYLLABICS FINAL BOTTOM HALF RING", + direction="l", + linebreak="al", + unicodeslot=0x1421, + }, + [0x1422]={ + category="lo", + description="CANADIAN SYLLABICS FINAL TOP HALF RING", + direction="l", + linebreak="al", + unicodeslot=0x1422, + }, + [0x1423]={ + category="lo", + description="CANADIAN SYLLABICS FINAL RIGHT HALF RING", + direction="l", + linebreak="al", + unicodeslot=0x1423, + }, + [0x1424]={ + category="lo", + description="CANADIAN SYLLABICS FINAL RING", + direction="l", + linebreak="al", + unicodeslot=0x1424, + }, + [0x1425]={ + category="lo", + description="CANADIAN SYLLABICS FINAL DOUBLE ACUTE", + direction="l", + linebreak="al", + unicodeslot=0x1425, + }, + [0x1426]={ + category="lo", + description="CANADIAN SYLLABICS FINAL DOUBLE SHORT VERTICAL STROKES", + direction="l", + linebreak="al", + unicodeslot=0x1426, + }, + [0x1427]={ + category="lo", + description="CANADIAN SYLLABICS FINAL MIDDLE DOT", + direction="l", + linebreak="al", + unicodeslot=0x1427, + }, + [0x1428]={ + category="lo", + description="CANADIAN SYLLABICS FINAL SHORT HORIZONTAL STROKE", + direction="l", + linebreak="al", + unicodeslot=0x1428, + }, + [0x1429]={ + category="lo", + description="CANADIAN SYLLABICS FINAL PLUS", + direction="l", + linebreak="al", + unicodeslot=0x1429, + }, + [0x142A]={ + category="lo", + description="CANADIAN SYLLABICS FINAL DOWN TACK", + direction="l", + linebreak="al", + unicodeslot=0x142A, + }, + [0x142B]={ + category="lo", + description="CANADIAN SYLLABICS EN", + direction="l", + linebreak="al", + unicodeslot=0x142B, + }, + [0x142C]={ + category="lo", + description="CANADIAN SYLLABICS IN", + direction="l", + linebreak="al", + unicodeslot=0x142C, + }, + [0x142D]={ + category="lo", + description="CANADIAN SYLLABICS ON", + direction="l", + linebreak="al", + unicodeslot=0x142D, + }, + [0x142E]={ + category="lo", + description="CANADIAN SYLLABICS AN", + direction="l", + linebreak="al", + unicodeslot=0x142E, + }, + [0x142F]={ + category="lo", + description="CANADIAN SYLLABICS PE", + direction="l", + linebreak="al", + unicodeslot=0x142F, + }, + [0x1430]={ + category="lo", + description="CANADIAN SYLLABICS PAAI", + direction="l", + linebreak="al", + unicodeslot=0x1430, + }, + [0x1431]={ + category="lo", + description="CANADIAN SYLLABICS PI", + direction="l", + linebreak="al", + unicodeslot=0x1431, + }, + [0x1432]={ + category="lo", + description="CANADIAN SYLLABICS PII", + direction="l", + linebreak="al", + unicodeslot=0x1432, + }, + [0x1433]={ + category="lo", + description="CANADIAN SYLLABICS PO", + direction="l", + linebreak="al", + unicodeslot=0x1433, + }, + [0x1434]={ + category="lo", + description="CANADIAN SYLLABICS POO", + direction="l", + linebreak="al", + unicodeslot=0x1434, + }, + [0x1435]={ + category="lo", + description="CANADIAN SYLLABICS Y-CREE POO", + direction="l", + linebreak="al", + unicodeslot=0x1435, + }, + [0x1436]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER HEE", + direction="l", + linebreak="al", + unicodeslot=0x1436, + }, + [0x1437]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER HI", + direction="l", + linebreak="al", + unicodeslot=0x1437, + }, + [0x1438]={ + category="lo", + description="CANADIAN SYLLABICS PA", + direction="l", + linebreak="al", + unicodeslot=0x1438, + }, + [0x1439]={ + category="lo", + description="CANADIAN SYLLABICS PAA", + direction="l", + linebreak="al", + unicodeslot=0x1439, + }, + [0x143A]={ + category="lo", + description="CANADIAN SYLLABICS PWE", + direction="l", + linebreak="al", + unicodeslot=0x143A, + }, + [0x143B]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE PWE", + direction="l", + linebreak="al", + unicodeslot=0x143B, + }, + [0x143C]={ + category="lo", + description="CANADIAN SYLLABICS PWI", + direction="l", + linebreak="al", + unicodeslot=0x143C, + }, + [0x143D]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE PWI", + direction="l", + linebreak="al", + unicodeslot=0x143D, + }, + [0x143E]={ + category="lo", + description="CANADIAN SYLLABICS PWII", + direction="l", + linebreak="al", + unicodeslot=0x143E, + }, + [0x143F]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE PWII", + direction="l", + linebreak="al", + unicodeslot=0x143F, + }, + [0x1440]={ + category="lo", + description="CANADIAN SYLLABICS PWO", + direction="l", + linebreak="al", + unicodeslot=0x1440, + }, + [0x1441]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE PWO", + direction="l", + linebreak="al", + unicodeslot=0x1441, + }, + [0x1442]={ + category="lo", + description="CANADIAN SYLLABICS PWOO", + direction="l", + linebreak="al", + unicodeslot=0x1442, + }, + [0x1443]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE PWOO", + direction="l", + linebreak="al", + unicodeslot=0x1443, + }, + [0x1444]={ + category="lo", + description="CANADIAN SYLLABICS PWA", + direction="l", + linebreak="al", + unicodeslot=0x1444, + }, + [0x1445]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE PWA", + direction="l", + linebreak="al", + unicodeslot=0x1445, + }, + [0x1446]={ + category="lo", + description="CANADIAN SYLLABICS PWAA", + direction="l", + linebreak="al", + unicodeslot=0x1446, + }, + [0x1447]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE PWAA", + direction="l", + linebreak="al", + unicodeslot=0x1447, + }, + [0x1448]={ + category="lo", + description="CANADIAN SYLLABICS Y-CREE PWAA", + direction="l", + linebreak="al", + unicodeslot=0x1448, + }, + [0x1449]={ + category="lo", + description="CANADIAN SYLLABICS P", + direction="l", + linebreak="al", + unicodeslot=0x1449, + }, + [0x144A]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE P", + direction="l", + linebreak="al", + unicodeslot=0x144A, + }, + [0x144B]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER H", + direction="l", + linebreak="al", + unicodeslot=0x144B, + }, + [0x144C]={ + category="lo", + description="CANADIAN SYLLABICS TE", + direction="l", + linebreak="al", + unicodeslot=0x144C, + }, + [0x144D]={ + category="lo", + description="CANADIAN SYLLABICS TAAI", + direction="l", + linebreak="al", + unicodeslot=0x144D, + }, + [0x144E]={ + category="lo", + description="CANADIAN SYLLABICS TI", + direction="l", + linebreak="al", + unicodeslot=0x144E, + }, + [0x144F]={ + category="lo", + description="CANADIAN SYLLABICS TII", + direction="l", + linebreak="al", + unicodeslot=0x144F, + }, + [0x1450]={ + category="lo", + description="CANADIAN SYLLABICS TO", + direction="l", + linebreak="al", + unicodeslot=0x1450, + }, + [0x1451]={ + category="lo", + description="CANADIAN SYLLABICS TOO", + direction="l", + linebreak="al", + unicodeslot=0x1451, + }, + [0x1452]={ + category="lo", + description="CANADIAN SYLLABICS Y-CREE TOO", + direction="l", + linebreak="al", + unicodeslot=0x1452, + }, + [0x1453]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER DEE", + direction="l", + linebreak="al", + unicodeslot=0x1453, + }, + [0x1454]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER DI", + direction="l", + linebreak="al", + unicodeslot=0x1454, + }, + [0x1455]={ + category="lo", + description="CANADIAN SYLLABICS TA", + direction="l", + linebreak="al", + unicodeslot=0x1455, + }, + [0x1456]={ + category="lo", + description="CANADIAN SYLLABICS TAA", + direction="l", + linebreak="al", + unicodeslot=0x1456, + }, + [0x1457]={ + category="lo", + description="CANADIAN SYLLABICS TWE", + direction="l", + linebreak="al", + unicodeslot=0x1457, + }, + [0x1458]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE TWE", + direction="l", + linebreak="al", + unicodeslot=0x1458, + }, + [0x1459]={ + category="lo", + description="CANADIAN SYLLABICS TWI", + direction="l", + linebreak="al", + unicodeslot=0x1459, + }, + [0x145A]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE TWI", + direction="l", + linebreak="al", + unicodeslot=0x145A, + }, + [0x145B]={ + category="lo", + description="CANADIAN SYLLABICS TWII", + direction="l", + linebreak="al", + unicodeslot=0x145B, + }, + [0x145C]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE TWII", + direction="l", + linebreak="al", + unicodeslot=0x145C, + }, + [0x145D]={ + category="lo", + description="CANADIAN SYLLABICS TWO", + direction="l", + linebreak="al", + unicodeslot=0x145D, + }, + [0x145E]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE TWO", + direction="l", + linebreak="al", + unicodeslot=0x145E, + }, + [0x145F]={ + category="lo", + description="CANADIAN SYLLABICS TWOO", + direction="l", + linebreak="al", + unicodeslot=0x145F, + }, + [0x1460]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE TWOO", + direction="l", + linebreak="al", + unicodeslot=0x1460, + }, + [0x1461]={ + category="lo", + description="CANADIAN SYLLABICS TWA", + direction="l", + linebreak="al", + unicodeslot=0x1461, + }, + [0x1462]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE TWA", + direction="l", + linebreak="al", + unicodeslot=0x1462, + }, + [0x1463]={ + category="lo", + description="CANADIAN SYLLABICS TWAA", + direction="l", + linebreak="al", + unicodeslot=0x1463, + }, + [0x1464]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE TWAA", + direction="l", + linebreak="al", + unicodeslot=0x1464, + }, + [0x1465]={ + category="lo", + description="CANADIAN SYLLABICS NASKAPI TWAA", + direction="l", + linebreak="al", + unicodeslot=0x1465, + }, + [0x1466]={ + category="lo", + description="CANADIAN SYLLABICS T", + direction="l", + linebreak="al", + unicodeslot=0x1466, + }, + [0x1467]={ + category="lo", + description="CANADIAN SYLLABICS TTE", + direction="l", + linebreak="al", + unicodeslot=0x1467, + }, + [0x1468]={ + category="lo", + description="CANADIAN SYLLABICS TTI", + direction="l", + linebreak="al", + unicodeslot=0x1468, + }, + [0x1469]={ + category="lo", + description="CANADIAN SYLLABICS TTO", + direction="l", + linebreak="al", + unicodeslot=0x1469, + }, + [0x146A]={ + category="lo", + description="CANADIAN SYLLABICS TTA", + direction="l", + linebreak="al", + unicodeslot=0x146A, + }, + [0x146B]={ + category="lo", + description="CANADIAN SYLLABICS KE", + direction="l", + linebreak="al", + unicodeslot=0x146B, + }, + [0x146C]={ + category="lo", + description="CANADIAN SYLLABICS KAAI", + direction="l", + linebreak="al", + unicodeslot=0x146C, + }, + [0x146D]={ + category="lo", + description="CANADIAN SYLLABICS KI", + direction="l", + linebreak="al", + unicodeslot=0x146D, + }, + [0x146E]={ + category="lo", + description="CANADIAN SYLLABICS KII", + direction="l", + linebreak="al", + unicodeslot=0x146E, + }, + [0x146F]={ + category="lo", + description="CANADIAN SYLLABICS KO", + direction="l", + linebreak="al", + unicodeslot=0x146F, + }, + [0x1470]={ + category="lo", + description="CANADIAN SYLLABICS KOO", + direction="l", + linebreak="al", + unicodeslot=0x1470, + }, + [0x1471]={ + category="lo", + description="CANADIAN SYLLABICS Y-CREE KOO", + direction="l", + linebreak="al", + unicodeslot=0x1471, + }, + [0x1472]={ + category="lo", + description="CANADIAN SYLLABICS KA", + direction="l", + linebreak="al", + unicodeslot=0x1472, + }, + [0x1473]={ + category="lo", + description="CANADIAN SYLLABICS KAA", + direction="l", + linebreak="al", + unicodeslot=0x1473, + }, + [0x1474]={ + category="lo", + description="CANADIAN SYLLABICS KWE", + direction="l", + linebreak="al", + unicodeslot=0x1474, + }, + [0x1475]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE KWE", + direction="l", + linebreak="al", + unicodeslot=0x1475, + }, + [0x1476]={ + category="lo", + description="CANADIAN SYLLABICS KWI", + direction="l", + linebreak="al", + unicodeslot=0x1476, + }, + [0x1477]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE KWI", + direction="l", + linebreak="al", + unicodeslot=0x1477, + }, + [0x1478]={ + category="lo", + description="CANADIAN SYLLABICS KWII", + direction="l", + linebreak="al", + unicodeslot=0x1478, + }, + [0x1479]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE KWII", + direction="l", + linebreak="al", + unicodeslot=0x1479, + }, + [0x147A]={ + category="lo", + description="CANADIAN SYLLABICS KWO", + direction="l", + linebreak="al", + unicodeslot=0x147A, + }, + [0x147B]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE KWO", + direction="l", + linebreak="al", + unicodeslot=0x147B, + }, + [0x147C]={ + category="lo", + description="CANADIAN SYLLABICS KWOO", + direction="l", + linebreak="al", + unicodeslot=0x147C, + }, + [0x147D]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE KWOO", + direction="l", + linebreak="al", + unicodeslot=0x147D, + }, + [0x147E]={ + category="lo", + description="CANADIAN SYLLABICS KWA", + direction="l", + linebreak="al", + unicodeslot=0x147E, + }, + [0x147F]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE KWA", + direction="l", + linebreak="al", + unicodeslot=0x147F, + }, + [0x1480]={ + category="lo", + description="CANADIAN SYLLABICS KWAA", + direction="l", + linebreak="al", + unicodeslot=0x1480, + }, + [0x1481]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE KWAA", + direction="l", + linebreak="al", + unicodeslot=0x1481, + }, + [0x1482]={ + category="lo", + description="CANADIAN SYLLABICS NASKAPI KWAA", + direction="l", + linebreak="al", + unicodeslot=0x1482, + }, + [0x1483]={ + category="lo", + description="CANADIAN SYLLABICS K", + direction="l", + linebreak="al", + unicodeslot=0x1483, + }, + [0x1484]={ + category="lo", + description="CANADIAN SYLLABICS KW", + direction="l", + linebreak="al", + unicodeslot=0x1484, + }, + [0x1485]={ + category="lo", + description="CANADIAN SYLLABICS SOUTH-SLAVEY KEH", + direction="l", + linebreak="al", + unicodeslot=0x1485, + }, + [0x1486]={ + category="lo", + description="CANADIAN SYLLABICS SOUTH-SLAVEY KIH", + direction="l", + linebreak="al", + unicodeslot=0x1486, + }, + [0x1487]={ + category="lo", + description="CANADIAN SYLLABICS SOUTH-SLAVEY KOH", + direction="l", + linebreak="al", + unicodeslot=0x1487, + }, + [0x1488]={ + category="lo", + description="CANADIAN SYLLABICS SOUTH-SLAVEY KAH", + direction="l", + linebreak="al", + unicodeslot=0x1488, + }, + [0x1489]={ + category="lo", + description="CANADIAN SYLLABICS CE", + direction="l", + linebreak="al", + unicodeslot=0x1489, + }, + [0x148A]={ + category="lo", + description="CANADIAN SYLLABICS CAAI", + direction="l", + linebreak="al", + unicodeslot=0x148A, + }, + [0x148B]={ + category="lo", + description="CANADIAN SYLLABICS CI", + direction="l", + linebreak="al", + unicodeslot=0x148B, + }, + [0x148C]={ + category="lo", + description="CANADIAN SYLLABICS CII", + direction="l", + linebreak="al", + unicodeslot=0x148C, + }, + [0x148D]={ + category="lo", + description="CANADIAN SYLLABICS CO", + direction="l", + linebreak="al", + unicodeslot=0x148D, + }, + [0x148E]={ + category="lo", + description="CANADIAN SYLLABICS COO", + direction="l", + linebreak="al", + unicodeslot=0x148E, + }, + [0x148F]={ + category="lo", + description="CANADIAN SYLLABICS Y-CREE COO", + direction="l", + linebreak="al", + unicodeslot=0x148F, + }, + [0x1490]={ + category="lo", + description="CANADIAN SYLLABICS CA", + direction="l", + linebreak="al", + unicodeslot=0x1490, + }, + [0x1491]={ + category="lo", + description="CANADIAN SYLLABICS CAA", + direction="l", + linebreak="al", + unicodeslot=0x1491, + }, + [0x1492]={ + category="lo", + description="CANADIAN SYLLABICS CWE", + direction="l", + linebreak="al", + unicodeslot=0x1492, + }, + [0x1493]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE CWE", + direction="l", + linebreak="al", + unicodeslot=0x1493, + }, + [0x1494]={ + category="lo", + description="CANADIAN SYLLABICS CWI", + direction="l", + linebreak="al", + unicodeslot=0x1494, + }, + [0x1495]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE CWI", + direction="l", + linebreak="al", + unicodeslot=0x1495, + }, + [0x1496]={ + category="lo", + description="CANADIAN SYLLABICS CWII", + direction="l", + linebreak="al", + unicodeslot=0x1496, + }, + [0x1497]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE CWII", + direction="l", + linebreak="al", + unicodeslot=0x1497, + }, + [0x1498]={ + category="lo", + description="CANADIAN SYLLABICS CWO", + direction="l", + linebreak="al", + unicodeslot=0x1498, + }, + [0x1499]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE CWO", + direction="l", + linebreak="al", + unicodeslot=0x1499, + }, + [0x149A]={ + category="lo", + description="CANADIAN SYLLABICS CWOO", + direction="l", + linebreak="al", + unicodeslot=0x149A, + }, + [0x149B]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE CWOO", + direction="l", + linebreak="al", + unicodeslot=0x149B, + }, + [0x149C]={ + category="lo", + description="CANADIAN SYLLABICS CWA", + direction="l", + linebreak="al", + unicodeslot=0x149C, + }, + [0x149D]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE CWA", + direction="l", + linebreak="al", + unicodeslot=0x149D, + }, + [0x149E]={ + category="lo", + description="CANADIAN SYLLABICS CWAA", + direction="l", + linebreak="al", + unicodeslot=0x149E, + }, + [0x149F]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE CWAA", + direction="l", + linebreak="al", + unicodeslot=0x149F, + }, + [0x14A0]={ + category="lo", + description="CANADIAN SYLLABICS NASKAPI CWAA", + direction="l", + linebreak="al", + unicodeslot=0x14A0, + }, + [0x14A1]={ + category="lo", + description="CANADIAN SYLLABICS C", + direction="l", + linebreak="al", + unicodeslot=0x14A1, + }, + [0x14A2]={ + category="lo", + description="CANADIAN SYLLABICS SAYISI TH", + direction="l", + linebreak="al", + unicodeslot=0x14A2, + }, + [0x14A3]={ + category="lo", + description="CANADIAN SYLLABICS ME", + direction="l", + linebreak="al", + unicodeslot=0x14A3, + }, + [0x14A4]={ + category="lo", + description="CANADIAN SYLLABICS MAAI", + direction="l", + linebreak="al", + unicodeslot=0x14A4, + }, + [0x14A5]={ + category="lo", + description="CANADIAN SYLLABICS MI", + direction="l", + linebreak="al", + unicodeslot=0x14A5, + }, + [0x14A6]={ + category="lo", + description="CANADIAN SYLLABICS MII", + direction="l", + linebreak="al", + unicodeslot=0x14A6, + }, + [0x14A7]={ + category="lo", + description="CANADIAN SYLLABICS MO", + direction="l", + linebreak="al", + unicodeslot=0x14A7, + }, + [0x14A8]={ + category="lo", + description="CANADIAN SYLLABICS MOO", + direction="l", + linebreak="al", + unicodeslot=0x14A8, + }, + [0x14A9]={ + category="lo", + description="CANADIAN SYLLABICS Y-CREE MOO", + direction="l", + linebreak="al", + unicodeslot=0x14A9, + }, + [0x14AA]={ + category="lo", + description="CANADIAN SYLLABICS MA", + direction="l", + linebreak="al", + unicodeslot=0x14AA, + }, + [0x14AB]={ + category="lo", + description="CANADIAN SYLLABICS MAA", + direction="l", + linebreak="al", + unicodeslot=0x14AB, + }, + [0x14AC]={ + category="lo", + description="CANADIAN SYLLABICS MWE", + direction="l", + linebreak="al", + unicodeslot=0x14AC, + }, + [0x14AD]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE MWE", + direction="l", + linebreak="al", + unicodeslot=0x14AD, + }, + [0x14AE]={ + category="lo", + description="CANADIAN SYLLABICS MWI", + direction="l", + linebreak="al", + unicodeslot=0x14AE, + }, + [0x14AF]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE MWI", + direction="l", + linebreak="al", + unicodeslot=0x14AF, + }, + [0x14B0]={ + category="lo", + description="CANADIAN SYLLABICS MWII", + direction="l", + linebreak="al", + unicodeslot=0x14B0, + }, + [0x14B1]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE MWII", + direction="l", + linebreak="al", + unicodeslot=0x14B1, + }, + [0x14B2]={ + category="lo", + description="CANADIAN SYLLABICS MWO", + direction="l", + linebreak="al", + unicodeslot=0x14B2, + }, + [0x14B3]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE MWO", + direction="l", + linebreak="al", + unicodeslot=0x14B3, + }, + [0x14B4]={ + category="lo", + description="CANADIAN SYLLABICS MWOO", + direction="l", + linebreak="al", + unicodeslot=0x14B4, + }, + [0x14B5]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE MWOO", + direction="l", + linebreak="al", + unicodeslot=0x14B5, + }, + [0x14B6]={ + category="lo", + description="CANADIAN SYLLABICS MWA", + direction="l", + linebreak="al", + unicodeslot=0x14B6, + }, + [0x14B7]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE MWA", + direction="l", + linebreak="al", + unicodeslot=0x14B7, + }, + [0x14B8]={ + category="lo", + description="CANADIAN SYLLABICS MWAA", + direction="l", + linebreak="al", + unicodeslot=0x14B8, + }, + [0x14B9]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE MWAA", + direction="l", + linebreak="al", + unicodeslot=0x14B9, + }, + [0x14BA]={ + category="lo", + description="CANADIAN SYLLABICS NASKAPI MWAA", + direction="l", + linebreak="al", + unicodeslot=0x14BA, + }, + [0x14BB]={ + category="lo", + description="CANADIAN SYLLABICS M", + direction="l", + linebreak="al", + unicodeslot=0x14BB, + }, + [0x14BC]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE M", + direction="l", + linebreak="al", + unicodeslot=0x14BC, + }, + [0x14BD]={ + category="lo", + description="CANADIAN SYLLABICS MH", + direction="l", + linebreak="al", + unicodeslot=0x14BD, + }, + [0x14BE]={ + category="lo", + description="CANADIAN SYLLABICS ATHAPASCAN M", + direction="l", + linebreak="al", + unicodeslot=0x14BE, + }, + [0x14BF]={ + category="lo", + description="CANADIAN SYLLABICS SAYISI M", + direction="l", + linebreak="al", + unicodeslot=0x14BF, + }, + [0x14C0]={ + category="lo", + description="CANADIAN SYLLABICS NE", + direction="l", + linebreak="al", + unicodeslot=0x14C0, + }, + [0x14C1]={ + category="lo", + description="CANADIAN SYLLABICS NAAI", + direction="l", + linebreak="al", + unicodeslot=0x14C1, + }, + [0x14C2]={ + category="lo", + description="CANADIAN SYLLABICS NI", + direction="l", + linebreak="al", + unicodeslot=0x14C2, + }, + [0x14C3]={ + category="lo", + description="CANADIAN SYLLABICS NII", + direction="l", + linebreak="al", + unicodeslot=0x14C3, + }, + [0x14C4]={ + category="lo", + description="CANADIAN SYLLABICS NO", + direction="l", + linebreak="al", + unicodeslot=0x14C4, + }, + [0x14C5]={ + category="lo", + description="CANADIAN SYLLABICS NOO", + direction="l", + linebreak="al", + unicodeslot=0x14C5, + }, + [0x14C6]={ + category="lo", + description="CANADIAN SYLLABICS Y-CREE NOO", + direction="l", + linebreak="al", + unicodeslot=0x14C6, + }, + [0x14C7]={ + category="lo", + description="CANADIAN SYLLABICS NA", + direction="l", + linebreak="al", + unicodeslot=0x14C7, + }, + [0x14C8]={ + category="lo", + description="CANADIAN SYLLABICS NAA", + direction="l", + linebreak="al", + unicodeslot=0x14C8, + }, + [0x14C9]={ + category="lo", + description="CANADIAN SYLLABICS NWE", + direction="l", + linebreak="al", + unicodeslot=0x14C9, + }, + [0x14CA]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE NWE", + direction="l", + linebreak="al", + unicodeslot=0x14CA, + }, + [0x14CB]={ + category="lo", + description="CANADIAN SYLLABICS NWA", + direction="l", + linebreak="al", + unicodeslot=0x14CB, + }, + [0x14CC]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE NWA", + direction="l", + linebreak="al", + unicodeslot=0x14CC, + }, + [0x14CD]={ + category="lo", + description="CANADIAN SYLLABICS NWAA", + direction="l", + linebreak="al", + unicodeslot=0x14CD, + }, + [0x14CE]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE NWAA", + direction="l", + linebreak="al", + unicodeslot=0x14CE, + }, + [0x14CF]={ + category="lo", + description="CANADIAN SYLLABICS NASKAPI NWAA", + direction="l", + linebreak="al", + unicodeslot=0x14CF, + }, + [0x14D0]={ + category="lo", + description="CANADIAN SYLLABICS N", + direction="l", + linebreak="al", + unicodeslot=0x14D0, + }, + [0x14D1]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER NG", + direction="l", + linebreak="al", + unicodeslot=0x14D1, + }, + [0x14D2]={ + category="lo", + description="CANADIAN SYLLABICS NH", + direction="l", + linebreak="al", + unicodeslot=0x14D2, + }, + [0x14D3]={ + category="lo", + description="CANADIAN SYLLABICS LE", + direction="l", + linebreak="al", + unicodeslot=0x14D3, + }, + [0x14D4]={ + category="lo", + description="CANADIAN SYLLABICS LAAI", + direction="l", + linebreak="al", + unicodeslot=0x14D4, + }, + [0x14D5]={ + category="lo", + description="CANADIAN SYLLABICS LI", + direction="l", + linebreak="al", + unicodeslot=0x14D5, + }, + [0x14D6]={ + category="lo", + description="CANADIAN SYLLABICS LII", + direction="l", + linebreak="al", + unicodeslot=0x14D6, + }, + [0x14D7]={ + category="lo", + description="CANADIAN SYLLABICS LO", + direction="l", + linebreak="al", + unicodeslot=0x14D7, + }, + [0x14D8]={ + category="lo", + description="CANADIAN SYLLABICS LOO", + direction="l", + linebreak="al", + unicodeslot=0x14D8, + }, + [0x14D9]={ + category="lo", + description="CANADIAN SYLLABICS Y-CREE LOO", + direction="l", + linebreak="al", + unicodeslot=0x14D9, + }, + [0x14DA]={ + category="lo", + description="CANADIAN SYLLABICS LA", + direction="l", + linebreak="al", + unicodeslot=0x14DA, + }, + [0x14DB]={ + category="lo", + description="CANADIAN SYLLABICS LAA", + direction="l", + linebreak="al", + unicodeslot=0x14DB, + }, + [0x14DC]={ + category="lo", + description="CANADIAN SYLLABICS LWE", + direction="l", + linebreak="al", + unicodeslot=0x14DC, + }, + [0x14DD]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE LWE", + direction="l", + linebreak="al", + unicodeslot=0x14DD, + }, + [0x14DE]={ + category="lo", + description="CANADIAN SYLLABICS LWI", + direction="l", + linebreak="al", + unicodeslot=0x14DE, + }, + [0x14DF]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE LWI", + direction="l", + linebreak="al", + unicodeslot=0x14DF, + }, + [0x14E0]={ + category="lo", + description="CANADIAN SYLLABICS LWII", + direction="l", + linebreak="al", + unicodeslot=0x14E0, + }, + [0x14E1]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE LWII", + direction="l", + linebreak="al", + unicodeslot=0x14E1, + }, + [0x14E2]={ + category="lo", + description="CANADIAN SYLLABICS LWO", + direction="l", + linebreak="al", + unicodeslot=0x14E2, + }, + [0x14E3]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE LWO", + direction="l", + linebreak="al", + unicodeslot=0x14E3, + }, + [0x14E4]={ + category="lo", + description="CANADIAN SYLLABICS LWOO", + direction="l", + linebreak="al", + unicodeslot=0x14E4, + }, + [0x14E5]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE LWOO", + direction="l", + linebreak="al", + unicodeslot=0x14E5, + }, + [0x14E6]={ + category="lo", + description="CANADIAN SYLLABICS LWA", + direction="l", + linebreak="al", + unicodeslot=0x14E6, + }, + [0x14E7]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE LWA", + direction="l", + linebreak="al", + unicodeslot=0x14E7, + }, + [0x14E8]={ + category="lo", + description="CANADIAN SYLLABICS LWAA", + direction="l", + linebreak="al", + unicodeslot=0x14E8, + }, + [0x14E9]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE LWAA", + direction="l", + linebreak="al", + unicodeslot=0x14E9, + }, + [0x14EA]={ + category="lo", + description="CANADIAN SYLLABICS L", + direction="l", + linebreak="al", + unicodeslot=0x14EA, + }, + [0x14EB]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE L", + direction="l", + linebreak="al", + unicodeslot=0x14EB, + }, + [0x14EC]={ + category="lo", + description="CANADIAN SYLLABICS MEDIAL L", + direction="l", + linebreak="al", + unicodeslot=0x14EC, + }, + [0x14ED]={ + category="lo", + description="CANADIAN SYLLABICS SE", + direction="l", + linebreak="al", + unicodeslot=0x14ED, + }, + [0x14EE]={ + category="lo", + description="CANADIAN SYLLABICS SAAI", + direction="l", + linebreak="al", + unicodeslot=0x14EE, + }, + [0x14EF]={ + category="lo", + description="CANADIAN SYLLABICS SI", + direction="l", + linebreak="al", + unicodeslot=0x14EF, + }, + [0x14F0]={ + category="lo", + description="CANADIAN SYLLABICS SII", + direction="l", + linebreak="al", + unicodeslot=0x14F0, + }, + [0x14F1]={ + category="lo", + description="CANADIAN SYLLABICS SO", + direction="l", + linebreak="al", + unicodeslot=0x14F1, + }, + [0x14F2]={ + category="lo", + description="CANADIAN SYLLABICS SOO", + direction="l", + linebreak="al", + unicodeslot=0x14F2, + }, + [0x14F3]={ + category="lo", + description="CANADIAN SYLLABICS Y-CREE SOO", + direction="l", + linebreak="al", + unicodeslot=0x14F3, + }, + [0x14F4]={ + category="lo", + description="CANADIAN SYLLABICS SA", + direction="l", + linebreak="al", + unicodeslot=0x14F4, + }, + [0x14F5]={ + category="lo", + description="CANADIAN SYLLABICS SAA", + direction="l", + linebreak="al", + unicodeslot=0x14F5, + }, + [0x14F6]={ + category="lo", + description="CANADIAN SYLLABICS SWE", + direction="l", + linebreak="al", + unicodeslot=0x14F6, + }, + [0x14F7]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE SWE", + direction="l", + linebreak="al", + unicodeslot=0x14F7, + }, + [0x14F8]={ + category="lo", + description="CANADIAN SYLLABICS SWI", + direction="l", + linebreak="al", + unicodeslot=0x14F8, + }, + [0x14F9]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE SWI", + direction="l", + linebreak="al", + unicodeslot=0x14F9, + }, + [0x14FA]={ + category="lo", + description="CANADIAN SYLLABICS SWII", + direction="l", + linebreak="al", + unicodeslot=0x14FA, + }, + [0x14FB]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE SWII", + direction="l", + linebreak="al", + unicodeslot=0x14FB, + }, + [0x14FC]={ + category="lo", + description="CANADIAN SYLLABICS SWO", + direction="l", + linebreak="al", + unicodeslot=0x14FC, + }, + [0x14FD]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE SWO", + direction="l", + linebreak="al", + unicodeslot=0x14FD, + }, + [0x14FE]={ + category="lo", + description="CANADIAN SYLLABICS SWOO", + direction="l", + linebreak="al", + unicodeslot=0x14FE, + }, + [0x14FF]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE SWOO", + direction="l", + linebreak="al", + unicodeslot=0x14FF, + }, + [0x1500]={ + category="lo", + description="CANADIAN SYLLABICS SWA", + direction="l", + linebreak="al", + unicodeslot=0x1500, + }, + [0x1501]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE SWA", + direction="l", + linebreak="al", + unicodeslot=0x1501, + }, + [0x1502]={ + category="lo", + description="CANADIAN SYLLABICS SWAA", + direction="l", + linebreak="al", + unicodeslot=0x1502, + }, + [0x1503]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE SWAA", + direction="l", + linebreak="al", + unicodeslot=0x1503, + }, + [0x1504]={ + category="lo", + description="CANADIAN SYLLABICS NASKAPI SWAA", + direction="l", + linebreak="al", + unicodeslot=0x1504, + }, + [0x1505]={ + category="lo", + description="CANADIAN SYLLABICS S", + direction="l", + linebreak="al", + unicodeslot=0x1505, + }, + [0x1506]={ + category="lo", + description="CANADIAN SYLLABICS ATHAPASCAN S", + direction="l", + linebreak="al", + unicodeslot=0x1506, + }, + [0x1507]={ + category="lo", + description="CANADIAN SYLLABICS SW", + direction="l", + linebreak="al", + unicodeslot=0x1507, + }, + [0x1508]={ + category="lo", + description="CANADIAN SYLLABICS BLACKFOOT S", + direction="l", + linebreak="al", + unicodeslot=0x1508, + }, + [0x1509]={ + category="lo", + description="CANADIAN SYLLABICS MOOSE-CREE SK", + direction="l", + linebreak="al", + unicodeslot=0x1509, + }, + [0x150A]={ + category="lo", + description="CANADIAN SYLLABICS NASKAPI SKW", + direction="l", + linebreak="al", + unicodeslot=0x150A, + }, + [0x150B]={ + category="lo", + description="CANADIAN SYLLABICS NASKAPI S-W", + direction="l", + linebreak="al", + unicodeslot=0x150B, + }, + [0x150C]={ + category="lo", + description="CANADIAN SYLLABICS NASKAPI SPWA", + direction="l", + linebreak="al", + unicodeslot=0x150C, + }, + [0x150D]={ + category="lo", + description="CANADIAN SYLLABICS NASKAPI STWA", + direction="l", + linebreak="al", + unicodeslot=0x150D, + }, + [0x150E]={ + category="lo", + description="CANADIAN SYLLABICS NASKAPI SKWA", + direction="l", + linebreak="al", + unicodeslot=0x150E, + }, + [0x150F]={ + category="lo", + description="CANADIAN SYLLABICS NASKAPI SCWA", + direction="l", + linebreak="al", + unicodeslot=0x150F, + }, + [0x1510]={ + category="lo", + description="CANADIAN SYLLABICS SHE", + direction="l", + linebreak="al", + unicodeslot=0x1510, + }, + [0x1511]={ + category="lo", + description="CANADIAN SYLLABICS SHI", + direction="l", + linebreak="al", + unicodeslot=0x1511, + }, + [0x1512]={ + category="lo", + description="CANADIAN SYLLABICS SHII", + direction="l", + linebreak="al", + unicodeslot=0x1512, + }, + [0x1513]={ + category="lo", + description="CANADIAN SYLLABICS SHO", + direction="l", + linebreak="al", + unicodeslot=0x1513, + }, + [0x1514]={ + category="lo", + description="CANADIAN SYLLABICS SHOO", + direction="l", + linebreak="al", + unicodeslot=0x1514, + }, + [0x1515]={ + category="lo", + description="CANADIAN SYLLABICS SHA", + direction="l", + linebreak="al", + unicodeslot=0x1515, + }, + [0x1516]={ + category="lo", + description="CANADIAN SYLLABICS SHAA", + direction="l", + linebreak="al", + unicodeslot=0x1516, + }, + [0x1517]={ + category="lo", + description="CANADIAN SYLLABICS SHWE", + direction="l", + linebreak="al", + unicodeslot=0x1517, + }, + [0x1518]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE SHWE", + direction="l", + linebreak="al", + unicodeslot=0x1518, + }, + [0x1519]={ + category="lo", + description="CANADIAN SYLLABICS SHWI", + direction="l", + linebreak="al", + unicodeslot=0x1519, + }, + [0x151A]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE SHWI", + direction="l", + linebreak="al", + unicodeslot=0x151A, + }, + [0x151B]={ + category="lo", + description="CANADIAN SYLLABICS SHWII", + direction="l", + linebreak="al", + unicodeslot=0x151B, + }, + [0x151C]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE SHWII", + direction="l", + linebreak="al", + unicodeslot=0x151C, + }, + [0x151D]={ + category="lo", + description="CANADIAN SYLLABICS SHWO", + direction="l", + linebreak="al", + unicodeslot=0x151D, + }, + [0x151E]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE SHWO", + direction="l", + linebreak="al", + unicodeslot=0x151E, + }, + [0x151F]={ + category="lo", + description="CANADIAN SYLLABICS SHWOO", + direction="l", + linebreak="al", + unicodeslot=0x151F, + }, + [0x1520]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE SHWOO", + direction="l", + linebreak="al", + unicodeslot=0x1520, + }, + [0x1521]={ + category="lo", + description="CANADIAN SYLLABICS SHWA", + direction="l", + linebreak="al", + unicodeslot=0x1521, + }, + [0x1522]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE SHWA", + direction="l", + linebreak="al", + unicodeslot=0x1522, + }, + [0x1523]={ + category="lo", + description="CANADIAN SYLLABICS SHWAA", + direction="l", + linebreak="al", + unicodeslot=0x1523, + }, + [0x1524]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE SHWAA", + direction="l", + linebreak="al", + unicodeslot=0x1524, + }, + [0x1525]={ + category="lo", + description="CANADIAN SYLLABICS SH", + direction="l", + linebreak="al", + unicodeslot=0x1525, + }, + [0x1526]={ + category="lo", + description="CANADIAN SYLLABICS YE", + direction="l", + linebreak="al", + unicodeslot=0x1526, + }, + [0x1527]={ + category="lo", + description="CANADIAN SYLLABICS YAAI", + direction="l", + linebreak="al", + unicodeslot=0x1527, + }, + [0x1528]={ + category="lo", + description="CANADIAN SYLLABICS YI", + direction="l", + linebreak="al", + unicodeslot=0x1528, + }, + [0x1529]={ + category="lo", + description="CANADIAN SYLLABICS YII", + direction="l", + linebreak="al", + unicodeslot=0x1529, + }, + [0x152A]={ + category="lo", + description="CANADIAN SYLLABICS YO", + direction="l", + linebreak="al", + unicodeslot=0x152A, + }, + [0x152B]={ + category="lo", + description="CANADIAN SYLLABICS YOO", + direction="l", + linebreak="al", + unicodeslot=0x152B, + }, + [0x152C]={ + category="lo", + description="CANADIAN SYLLABICS Y-CREE YOO", + direction="l", + linebreak="al", + unicodeslot=0x152C, + }, + [0x152D]={ + category="lo", + description="CANADIAN SYLLABICS YA", + direction="l", + linebreak="al", + unicodeslot=0x152D, + }, + [0x152E]={ + category="lo", + description="CANADIAN SYLLABICS YAA", + direction="l", + linebreak="al", + unicodeslot=0x152E, + }, + [0x152F]={ + category="lo", + description="CANADIAN SYLLABICS YWE", + direction="l", + linebreak="al", + unicodeslot=0x152F, + }, + [0x1530]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE YWE", + direction="l", + linebreak="al", + unicodeslot=0x1530, + }, + [0x1531]={ + category="lo", + description="CANADIAN SYLLABICS YWI", + direction="l", + linebreak="al", + unicodeslot=0x1531, + }, + [0x1532]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE YWI", + direction="l", + linebreak="al", + unicodeslot=0x1532, + }, + [0x1533]={ + category="lo", + description="CANADIAN SYLLABICS YWII", + direction="l", + linebreak="al", + unicodeslot=0x1533, + }, + [0x1534]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE YWII", + direction="l", + linebreak="al", + unicodeslot=0x1534, + }, + [0x1535]={ + category="lo", + description="CANADIAN SYLLABICS YWO", + direction="l", + linebreak="al", + unicodeslot=0x1535, + }, + [0x1536]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE YWO", + direction="l", + linebreak="al", + unicodeslot=0x1536, + }, + [0x1537]={ + category="lo", + description="CANADIAN SYLLABICS YWOO", + direction="l", + linebreak="al", + unicodeslot=0x1537, + }, + [0x1538]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE YWOO", + direction="l", + linebreak="al", + unicodeslot=0x1538, + }, + [0x1539]={ + category="lo", + description="CANADIAN SYLLABICS YWA", + direction="l", + linebreak="al", + unicodeslot=0x1539, + }, + [0x153A]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE YWA", + direction="l", + linebreak="al", + unicodeslot=0x153A, + }, + [0x153B]={ + category="lo", + description="CANADIAN SYLLABICS YWAA", + direction="l", + linebreak="al", + unicodeslot=0x153B, + }, + [0x153C]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE YWAA", + direction="l", + linebreak="al", + unicodeslot=0x153C, + }, + [0x153D]={ + category="lo", + description="CANADIAN SYLLABICS NASKAPI YWAA", + direction="l", + linebreak="al", + unicodeslot=0x153D, + }, + [0x153E]={ + category="lo", + description="CANADIAN SYLLABICS Y", + direction="l", + linebreak="al", + unicodeslot=0x153E, + }, + [0x153F]={ + category="lo", + description="CANADIAN SYLLABICS BIBLE-CREE Y", + direction="l", + linebreak="al", + unicodeslot=0x153F, + }, + [0x1540]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE Y", + direction="l", + linebreak="al", + unicodeslot=0x1540, + }, + [0x1541]={ + category="lo", + description="CANADIAN SYLLABICS SAYISI YI", + direction="l", + linebreak="al", + unicodeslot=0x1541, + }, + [0x1542]={ + category="lo", + description="CANADIAN SYLLABICS RE", + direction="l", + linebreak="al", + unicodeslot=0x1542, + }, + [0x1543]={ + category="lo", + description="CANADIAN SYLLABICS R-CREE RE", + direction="l", + linebreak="al", + unicodeslot=0x1543, + }, + [0x1544]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE LE", + direction="l", + linebreak="al", + unicodeslot=0x1544, + }, + [0x1545]={ + category="lo", + description="CANADIAN SYLLABICS RAAI", + direction="l", + linebreak="al", + unicodeslot=0x1545, + }, + [0x1546]={ + category="lo", + description="CANADIAN SYLLABICS RI", + direction="l", + linebreak="al", + unicodeslot=0x1546, + }, + [0x1547]={ + category="lo", + description="CANADIAN SYLLABICS RII", + direction="l", + linebreak="al", + unicodeslot=0x1547, + }, + [0x1548]={ + category="lo", + description="CANADIAN SYLLABICS RO", + direction="l", + linebreak="al", + unicodeslot=0x1548, + }, + [0x1549]={ + category="lo", + description="CANADIAN SYLLABICS ROO", + direction="l", + linebreak="al", + unicodeslot=0x1549, + }, + [0x154A]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE LO", + direction="l", + linebreak="al", + unicodeslot=0x154A, + }, + [0x154B]={ + category="lo", + description="CANADIAN SYLLABICS RA", + direction="l", + linebreak="al", + unicodeslot=0x154B, + }, + [0x154C]={ + category="lo", + description="CANADIAN SYLLABICS RAA", + direction="l", + linebreak="al", + unicodeslot=0x154C, + }, + [0x154D]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE LA", + direction="l", + linebreak="al", + unicodeslot=0x154D, + }, + [0x154E]={ + category="lo", + description="CANADIAN SYLLABICS RWAA", + direction="l", + linebreak="al", + unicodeslot=0x154E, + }, + [0x154F]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE RWAA", + direction="l", + linebreak="al", + unicodeslot=0x154F, + }, + [0x1550]={ + category="lo", + description="CANADIAN SYLLABICS R", + direction="l", + linebreak="al", + unicodeslot=0x1550, + }, + [0x1551]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE R", + direction="l", + linebreak="al", + unicodeslot=0x1551, + }, + [0x1552]={ + category="lo", + description="CANADIAN SYLLABICS MEDIAL R", + direction="l", + linebreak="al", + unicodeslot=0x1552, + }, + [0x1553]={ + category="lo", + description="CANADIAN SYLLABICS FE", + direction="l", + linebreak="al", + unicodeslot=0x1553, + }, + [0x1554]={ + category="lo", + description="CANADIAN SYLLABICS FAAI", + direction="l", + linebreak="al", + unicodeslot=0x1554, + }, + [0x1555]={ + category="lo", + description="CANADIAN SYLLABICS FI", + direction="l", + linebreak="al", + unicodeslot=0x1555, + }, + [0x1556]={ + category="lo", + description="CANADIAN SYLLABICS FII", + direction="l", + linebreak="al", + unicodeslot=0x1556, + }, + [0x1557]={ + category="lo", + description="CANADIAN SYLLABICS FO", + direction="l", + linebreak="al", + unicodeslot=0x1557, + }, + [0x1558]={ + category="lo", + description="CANADIAN SYLLABICS FOO", + direction="l", + linebreak="al", + unicodeslot=0x1558, + }, + [0x1559]={ + category="lo", + description="CANADIAN SYLLABICS FA", + direction="l", + linebreak="al", + unicodeslot=0x1559, + }, + [0x155A]={ + category="lo", + description="CANADIAN SYLLABICS FAA", + direction="l", + linebreak="al", + unicodeslot=0x155A, + }, + [0x155B]={ + category="lo", + description="CANADIAN SYLLABICS FWAA", + direction="l", + linebreak="al", + unicodeslot=0x155B, + }, + [0x155C]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE FWAA", + direction="l", + linebreak="al", + unicodeslot=0x155C, + }, + [0x155D]={ + category="lo", + description="CANADIAN SYLLABICS F", + direction="l", + linebreak="al", + unicodeslot=0x155D, + }, + [0x155E]={ + category="lo", + description="CANADIAN SYLLABICS THE", + direction="l", + linebreak="al", + unicodeslot=0x155E, + }, + [0x155F]={ + category="lo", + description="CANADIAN SYLLABICS N-CREE THE", + direction="l", + linebreak="al", + unicodeslot=0x155F, + }, + [0x1560]={ + category="lo", + description="CANADIAN SYLLABICS THI", + direction="l", + linebreak="al", + unicodeslot=0x1560, + }, + [0x1561]={ + category="lo", + description="CANADIAN SYLLABICS N-CREE THI", + direction="l", + linebreak="al", + unicodeslot=0x1561, + }, + [0x1562]={ + category="lo", + description="CANADIAN SYLLABICS THII", + direction="l", + linebreak="al", + unicodeslot=0x1562, + }, + [0x1563]={ + category="lo", + description="CANADIAN SYLLABICS N-CREE THII", + direction="l", + linebreak="al", + unicodeslot=0x1563, + }, + [0x1564]={ + category="lo", + description="CANADIAN SYLLABICS THO", + direction="l", + linebreak="al", + unicodeslot=0x1564, + }, + [0x1565]={ + category="lo", + description="CANADIAN SYLLABICS THOO", + direction="l", + linebreak="al", + unicodeslot=0x1565, + }, + [0x1566]={ + category="lo", + description="CANADIAN SYLLABICS THA", + direction="l", + linebreak="al", + unicodeslot=0x1566, + }, + [0x1567]={ + category="lo", + description="CANADIAN SYLLABICS THAA", + direction="l", + linebreak="al", + unicodeslot=0x1567, + }, + [0x1568]={ + category="lo", + description="CANADIAN SYLLABICS THWAA", + direction="l", + linebreak="al", + unicodeslot=0x1568, + }, + [0x1569]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE THWAA", + direction="l", + linebreak="al", + unicodeslot=0x1569, + }, + [0x156A]={ + category="lo", + description="CANADIAN SYLLABICS TH", + direction="l", + linebreak="al", + unicodeslot=0x156A, + }, + [0x156B]={ + category="lo", + description="CANADIAN SYLLABICS TTHE", + direction="l", + linebreak="al", + unicodeslot=0x156B, + }, + [0x156C]={ + category="lo", + description="CANADIAN SYLLABICS TTHI", + direction="l", + linebreak="al", + unicodeslot=0x156C, + }, + [0x156D]={ + category="lo", + description="CANADIAN SYLLABICS TTHO", + direction="l", + linebreak="al", + unicodeslot=0x156D, + }, + [0x156E]={ + category="lo", + description="CANADIAN SYLLABICS TTHA", + direction="l", + linebreak="al", + unicodeslot=0x156E, + }, + [0x156F]={ + category="lo", + description="CANADIAN SYLLABICS TTH", + direction="l", + linebreak="al", + unicodeslot=0x156F, + }, + [0x1570]={ + category="lo", + description="CANADIAN SYLLABICS TYE", + direction="l", + linebreak="al", + unicodeslot=0x1570, + }, + [0x1571]={ + category="lo", + description="CANADIAN SYLLABICS TYI", + direction="l", + linebreak="al", + unicodeslot=0x1571, + }, + [0x1572]={ + category="lo", + description="CANADIAN SYLLABICS TYO", + direction="l", + linebreak="al", + unicodeslot=0x1572, + }, + [0x1573]={ + category="lo", + description="CANADIAN SYLLABICS TYA", + direction="l", + linebreak="al", + unicodeslot=0x1573, + }, + [0x1574]={ + category="lo", + description="CANADIAN SYLLABICS NUNAVIK HE", + direction="l", + linebreak="al", + unicodeslot=0x1574, + }, + [0x1575]={ + category="lo", + description="CANADIAN SYLLABICS NUNAVIK HI", + direction="l", + linebreak="al", + unicodeslot=0x1575, + }, + [0x1576]={ + category="lo", + description="CANADIAN SYLLABICS NUNAVIK HII", + direction="l", + linebreak="al", + unicodeslot=0x1576, + }, + [0x1577]={ + category="lo", + description="CANADIAN SYLLABICS NUNAVIK HO", + direction="l", + linebreak="al", + unicodeslot=0x1577, + }, + [0x1578]={ + category="lo", + description="CANADIAN SYLLABICS NUNAVIK HOO", + direction="l", + linebreak="al", + unicodeslot=0x1578, + }, + [0x1579]={ + category="lo", + description="CANADIAN SYLLABICS NUNAVIK HA", + direction="l", + linebreak="al", + unicodeslot=0x1579, + }, + [0x157A]={ + category="lo", + description="CANADIAN SYLLABICS NUNAVIK HAA", + direction="l", + linebreak="al", + unicodeslot=0x157A, + }, + [0x157B]={ + category="lo", + description="CANADIAN SYLLABICS NUNAVIK H", + direction="l", + linebreak="al", + unicodeslot=0x157B, + }, + [0x157C]={ + category="lo", + description="CANADIAN SYLLABICS NUNAVUT H", + direction="l", + linebreak="al", + unicodeslot=0x157C, + }, + [0x157D]={ + category="lo", + description="CANADIAN SYLLABICS HK", + direction="l", + linebreak="al", + unicodeslot=0x157D, + }, + [0x157E]={ + category="lo", + description="CANADIAN SYLLABICS QAAI", + direction="l", + linebreak="al", + unicodeslot=0x157E, + }, + [0x157F]={ + category="lo", + description="CANADIAN SYLLABICS QI", + direction="l", + linebreak="al", + unicodeslot=0x157F, + }, + [0x1580]={ + category="lo", + description="CANADIAN SYLLABICS QII", + direction="l", + linebreak="al", + unicodeslot=0x1580, + }, + [0x1581]={ + category="lo", + description="CANADIAN SYLLABICS QO", + direction="l", + linebreak="al", + unicodeslot=0x1581, + }, + [0x1582]={ + category="lo", + description="CANADIAN SYLLABICS QOO", + direction="l", + linebreak="al", + unicodeslot=0x1582, + }, + [0x1583]={ + category="lo", + description="CANADIAN SYLLABICS QA", + direction="l", + linebreak="al", + unicodeslot=0x1583, + }, + [0x1584]={ + category="lo", + description="CANADIAN SYLLABICS QAA", + direction="l", + linebreak="al", + unicodeslot=0x1584, + }, + [0x1585]={ + category="lo", + description="CANADIAN SYLLABICS Q", + direction="l", + linebreak="al", + unicodeslot=0x1585, + }, + [0x1586]={ + category="lo", + description="CANADIAN SYLLABICS TLHE", + direction="l", + linebreak="al", + unicodeslot=0x1586, + }, + [0x1587]={ + category="lo", + description="CANADIAN SYLLABICS TLHI", + direction="l", + linebreak="al", + unicodeslot=0x1587, + }, + [0x1588]={ + category="lo", + description="CANADIAN SYLLABICS TLHO", + direction="l", + linebreak="al", + unicodeslot=0x1588, + }, + [0x1589]={ + category="lo", + description="CANADIAN SYLLABICS TLHA", + direction="l", + linebreak="al", + unicodeslot=0x1589, + }, + [0x158A]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE RE", + direction="l", + linebreak="al", + unicodeslot=0x158A, + }, + [0x158B]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE RI", + direction="l", + linebreak="al", + unicodeslot=0x158B, + }, + [0x158C]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE RO", + direction="l", + linebreak="al", + unicodeslot=0x158C, + }, + [0x158D]={ + category="lo", + description="CANADIAN SYLLABICS WEST-CREE RA", + direction="l", + linebreak="al", + unicodeslot=0x158D, + }, + [0x158E]={ + category="lo", + description="CANADIAN SYLLABICS NGAAI", + direction="l", + linebreak="al", + unicodeslot=0x158E, + }, + [0x158F]={ + category="lo", + description="CANADIAN SYLLABICS NGI", + direction="l", + linebreak="al", + unicodeslot=0x158F, + }, + [0x1590]={ + category="lo", + description="CANADIAN SYLLABICS NGII", + direction="l", + linebreak="al", + unicodeslot=0x1590, + }, + [0x1591]={ + category="lo", + description="CANADIAN SYLLABICS NGO", + direction="l", + linebreak="al", + unicodeslot=0x1591, + }, + [0x1592]={ + category="lo", + description="CANADIAN SYLLABICS NGOO", + direction="l", + linebreak="al", + unicodeslot=0x1592, + }, + [0x1593]={ + category="lo", + description="CANADIAN SYLLABICS NGA", + direction="l", + linebreak="al", + unicodeslot=0x1593, + }, + [0x1594]={ + category="lo", + description="CANADIAN SYLLABICS NGAA", + direction="l", + linebreak="al", + unicodeslot=0x1594, + }, + [0x1595]={ + category="lo", + description="CANADIAN SYLLABICS NG", + direction="l", + linebreak="al", + unicodeslot=0x1595, + }, + [0x1596]={ + category="lo", + description="CANADIAN SYLLABICS NNG", + direction="l", + linebreak="al", + unicodeslot=0x1596, + }, + [0x1597]={ + category="lo", + description="CANADIAN SYLLABICS SAYISI SHE", + direction="l", + linebreak="al", + unicodeslot=0x1597, + }, + [0x1598]={ + category="lo", + description="CANADIAN SYLLABICS SAYISI SHI", + direction="l", + linebreak="al", + unicodeslot=0x1598, + }, + [0x1599]={ + category="lo", + description="CANADIAN SYLLABICS SAYISI SHO", + direction="l", + linebreak="al", + unicodeslot=0x1599, + }, + [0x159A]={ + category="lo", + description="CANADIAN SYLLABICS SAYISI SHA", + direction="l", + linebreak="al", + unicodeslot=0x159A, + }, + [0x159B]={ + category="lo", + description="CANADIAN SYLLABICS WOODS-CREE THE", + direction="l", + linebreak="al", + unicodeslot=0x159B, + }, + [0x159C]={ + category="lo", + description="CANADIAN SYLLABICS WOODS-CREE THI", + direction="l", + linebreak="al", + unicodeslot=0x159C, + }, + [0x159D]={ + category="lo", + description="CANADIAN SYLLABICS WOODS-CREE THO", + direction="l", + linebreak="al", + unicodeslot=0x159D, + }, + [0x159E]={ + category="lo", + description="CANADIAN SYLLABICS WOODS-CREE THA", + direction="l", + linebreak="al", + unicodeslot=0x159E, + }, + [0x159F]={ + category="lo", + description="CANADIAN SYLLABICS WOODS-CREE TH", + direction="l", + linebreak="al", + unicodeslot=0x159F, + }, + [0x15A0]={ + category="lo", + description="CANADIAN SYLLABICS LHI", + direction="l", + linebreak="al", + unicodeslot=0x15A0, + }, + [0x15A1]={ + category="lo", + description="CANADIAN SYLLABICS LHII", + direction="l", + linebreak="al", + unicodeslot=0x15A1, + }, + [0x15A2]={ + category="lo", + description="CANADIAN SYLLABICS LHO", + direction="l", + linebreak="al", + unicodeslot=0x15A2, + }, + [0x15A3]={ + category="lo", + description="CANADIAN SYLLABICS LHOO", + direction="l", + linebreak="al", + unicodeslot=0x15A3, + }, + [0x15A4]={ + category="lo", + description="CANADIAN SYLLABICS LHA", + direction="l", + linebreak="al", + unicodeslot=0x15A4, + }, + [0x15A5]={ + category="lo", + description="CANADIAN SYLLABICS LHAA", + direction="l", + linebreak="al", + unicodeslot=0x15A5, + }, + [0x15A6]={ + category="lo", + description="CANADIAN SYLLABICS LH", + direction="l", + linebreak="al", + unicodeslot=0x15A6, + }, + [0x15A7]={ + category="lo", + description="CANADIAN SYLLABICS TH-CREE THE", + direction="l", + linebreak="al", + unicodeslot=0x15A7, + }, + [0x15A8]={ + category="lo", + description="CANADIAN SYLLABICS TH-CREE THI", + direction="l", + linebreak="al", + unicodeslot=0x15A8, + }, + [0x15A9]={ + category="lo", + description="CANADIAN SYLLABICS TH-CREE THII", + direction="l", + linebreak="al", + unicodeslot=0x15A9, + }, + [0x15AA]={ + category="lo", + description="CANADIAN SYLLABICS TH-CREE THO", + direction="l", + linebreak="al", + unicodeslot=0x15AA, + }, + [0x15AB]={ + category="lo", + description="CANADIAN SYLLABICS TH-CREE THOO", + direction="l", + linebreak="al", + unicodeslot=0x15AB, + }, + [0x15AC]={ + category="lo", + description="CANADIAN SYLLABICS TH-CREE THA", + direction="l", + linebreak="al", + unicodeslot=0x15AC, + }, + [0x15AD]={ + category="lo", + description="CANADIAN SYLLABICS TH-CREE THAA", + direction="l", + linebreak="al", + unicodeslot=0x15AD, + }, + [0x15AE]={ + category="lo", + description="CANADIAN SYLLABICS TH-CREE TH", + direction="l", + linebreak="al", + unicodeslot=0x15AE, + }, + [0x15AF]={ + category="lo", + description="CANADIAN SYLLABICS AIVILIK B", + direction="l", + linebreak="al", + unicodeslot=0x15AF, + }, + [0x15B0]={ + category="lo", + description="CANADIAN SYLLABICS BLACKFOOT E", + direction="l", + linebreak="al", + unicodeslot=0x15B0, + }, + [0x15B1]={ + category="lo", + description="CANADIAN SYLLABICS BLACKFOOT I", + direction="l", + linebreak="al", + unicodeslot=0x15B1, + }, + [0x15B2]={ + category="lo", + description="CANADIAN SYLLABICS BLACKFOOT O", + direction="l", + linebreak="al", + unicodeslot=0x15B2, + }, + [0x15B3]={ + category="lo", + description="CANADIAN SYLLABICS BLACKFOOT A", + direction="l", + linebreak="al", + unicodeslot=0x15B3, + }, + [0x15B4]={ + category="lo", + description="CANADIAN SYLLABICS BLACKFOOT WE", + direction="l", + linebreak="al", + unicodeslot=0x15B4, + }, + [0x15B5]={ + category="lo", + description="CANADIAN SYLLABICS BLACKFOOT WI", + direction="l", + linebreak="al", + unicodeslot=0x15B5, + }, + [0x15B6]={ + category="lo", + description="CANADIAN SYLLABICS BLACKFOOT WO", + direction="l", + linebreak="al", + unicodeslot=0x15B6, + }, + [0x15B7]={ + category="lo", + description="CANADIAN SYLLABICS BLACKFOOT WA", + direction="l", + linebreak="al", + unicodeslot=0x15B7, + }, + [0x15B8]={ + category="lo", + description="CANADIAN SYLLABICS BLACKFOOT NE", + direction="l", + linebreak="al", + unicodeslot=0x15B8, + }, + [0x15B9]={ + category="lo", + description="CANADIAN SYLLABICS BLACKFOOT NI", + direction="l", + linebreak="al", + unicodeslot=0x15B9, + }, + [0x15BA]={ + category="lo", + description="CANADIAN SYLLABICS BLACKFOOT NO", + direction="l", + linebreak="al", + unicodeslot=0x15BA, + }, + [0x15BB]={ + category="lo", + description="CANADIAN SYLLABICS BLACKFOOT NA", + direction="l", + linebreak="al", + unicodeslot=0x15BB, + }, + [0x15BC]={ + category="lo", + description="CANADIAN SYLLABICS BLACKFOOT KE", + direction="l", + linebreak="al", + unicodeslot=0x15BC, + }, + [0x15BD]={ + category="lo", + description="CANADIAN SYLLABICS BLACKFOOT KI", + direction="l", + linebreak="al", + unicodeslot=0x15BD, + }, + [0x15BE]={ + category="lo", + description="CANADIAN SYLLABICS BLACKFOOT KO", + direction="l", + linebreak="al", + unicodeslot=0x15BE, + }, + [0x15BF]={ + category="lo", + description="CANADIAN SYLLABICS BLACKFOOT KA", + direction="l", + linebreak="al", + unicodeslot=0x15BF, + }, + [0x15C0]={ + category="lo", + description="CANADIAN SYLLABICS SAYISI HE", + direction="l", + linebreak="al", + unicodeslot=0x15C0, + }, + [0x15C1]={ + category="lo", + description="CANADIAN SYLLABICS SAYISI HI", + direction="l", + linebreak="al", + unicodeslot=0x15C1, + }, + [0x15C2]={ + category="lo", + description="CANADIAN SYLLABICS SAYISI HO", + direction="l", + linebreak="al", + unicodeslot=0x15C2, + }, + [0x15C3]={ + category="lo", + description="CANADIAN SYLLABICS SAYISI HA", + direction="l", + linebreak="al", + unicodeslot=0x15C3, + }, + [0x15C4]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER GHU", + direction="l", + linebreak="al", + unicodeslot=0x15C4, + }, + [0x15C5]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER GHO", + direction="l", + linebreak="al", + unicodeslot=0x15C5, + }, + [0x15C6]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER GHE", + direction="l", + linebreak="al", + unicodeslot=0x15C6, + }, + [0x15C7]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER GHEE", + direction="l", + linebreak="al", + unicodeslot=0x15C7, + }, + [0x15C8]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER GHI", + direction="l", + linebreak="al", + unicodeslot=0x15C8, + }, + [0x15C9]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER GHA", + direction="l", + linebreak="al", + unicodeslot=0x15C9, + }, + [0x15CA]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER RU", + direction="l", + linebreak="al", + unicodeslot=0x15CA, + }, + [0x15CB]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER RO", + direction="l", + linebreak="al", + unicodeslot=0x15CB, + }, + [0x15CC]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER RE", + direction="l", + linebreak="al", + unicodeslot=0x15CC, + }, + [0x15CD]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER REE", + direction="l", + linebreak="al", + unicodeslot=0x15CD, + }, + [0x15CE]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER RI", + direction="l", + linebreak="al", + unicodeslot=0x15CE, + }, + [0x15CF]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER RA", + direction="l", + linebreak="al", + unicodeslot=0x15CF, + }, + [0x15D0]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER WU", + direction="l", + linebreak="al", + unicodeslot=0x15D0, + }, + [0x15D1]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER WO", + direction="l", + linebreak="al", + unicodeslot=0x15D1, + }, + [0x15D2]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER WE", + direction="l", + linebreak="al", + unicodeslot=0x15D2, + }, + [0x15D3]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER WEE", + direction="l", + linebreak="al", + unicodeslot=0x15D3, + }, + [0x15D4]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER WI", + direction="l", + linebreak="al", + unicodeslot=0x15D4, + }, + [0x15D5]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER WA", + direction="l", + linebreak="al", + unicodeslot=0x15D5, + }, + [0x15D6]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER HWU", + direction="l", + linebreak="al", + unicodeslot=0x15D6, + }, + [0x15D7]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER HWO", + direction="l", + linebreak="al", + unicodeslot=0x15D7, + }, + [0x15D8]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER HWE", + direction="l", + linebreak="al", + unicodeslot=0x15D8, + }, + [0x15D9]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER HWEE", + direction="l", + linebreak="al", + unicodeslot=0x15D9, + }, + [0x15DA]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER HWI", + direction="l", + linebreak="al", + unicodeslot=0x15DA, + }, + [0x15DB]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER HWA", + direction="l", + linebreak="al", + unicodeslot=0x15DB, + }, + [0x15DC]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER THU", + direction="l", + linebreak="al", + unicodeslot=0x15DC, + }, + [0x15DD]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER THO", + direction="l", + linebreak="al", + unicodeslot=0x15DD, + }, + [0x15DE]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER THE", + direction="l", + linebreak="al", + unicodeslot=0x15DE, + }, + [0x15DF]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER THEE", + direction="l", + linebreak="al", + unicodeslot=0x15DF, + }, + [0x15E0]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER THI", + direction="l", + linebreak="al", + unicodeslot=0x15E0, + }, + [0x15E1]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER THA", + direction="l", + linebreak="al", + unicodeslot=0x15E1, + }, + [0x15E2]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TTU", + direction="l", + linebreak="al", + unicodeslot=0x15E2, + }, + [0x15E3]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TTO", + direction="l", + linebreak="al", + unicodeslot=0x15E3, + }, + [0x15E4]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TTE", + direction="l", + linebreak="al", + unicodeslot=0x15E4, + }, + [0x15E5]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TTEE", + direction="l", + linebreak="al", + unicodeslot=0x15E5, + }, + [0x15E6]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TTI", + direction="l", + linebreak="al", + unicodeslot=0x15E6, + }, + [0x15E7]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TTA", + direction="l", + linebreak="al", + unicodeslot=0x15E7, + }, + [0x15E8]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER PU", + direction="l", + linebreak="al", + unicodeslot=0x15E8, + }, + [0x15E9]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER PO", + direction="l", + linebreak="al", + unicodeslot=0x15E9, + }, + [0x15EA]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER PE", + direction="l", + linebreak="al", + unicodeslot=0x15EA, + }, + [0x15EB]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER PEE", + direction="l", + linebreak="al", + unicodeslot=0x15EB, + }, + [0x15EC]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER PI", + direction="l", + linebreak="al", + unicodeslot=0x15EC, + }, + [0x15ED]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER PA", + direction="l", + linebreak="al", + unicodeslot=0x15ED, + }, + [0x15EE]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER P", + direction="l", + linebreak="al", + unicodeslot=0x15EE, + }, + [0x15EF]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER GU", + direction="l", + linebreak="al", + unicodeslot=0x15EF, + }, + [0x15F0]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER GO", + direction="l", + linebreak="al", + unicodeslot=0x15F0, + }, + [0x15F1]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER GE", + direction="l", + linebreak="al", + unicodeslot=0x15F1, + }, + [0x15F2]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER GEE", + direction="l", + linebreak="al", + unicodeslot=0x15F2, + }, + [0x15F3]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER GI", + direction="l", + linebreak="al", + unicodeslot=0x15F3, + }, + [0x15F4]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER GA", + direction="l", + linebreak="al", + unicodeslot=0x15F4, + }, + [0x15F5]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER KHU", + direction="l", + linebreak="al", + unicodeslot=0x15F5, + }, + [0x15F6]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER KHO", + direction="l", + linebreak="al", + unicodeslot=0x15F6, + }, + [0x15F7]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER KHE", + direction="l", + linebreak="al", + unicodeslot=0x15F7, + }, + [0x15F8]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER KHEE", + direction="l", + linebreak="al", + unicodeslot=0x15F8, + }, + [0x15F9]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER KHI", + direction="l", + linebreak="al", + unicodeslot=0x15F9, + }, + [0x15FA]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER KHA", + direction="l", + linebreak="al", + unicodeslot=0x15FA, + }, + [0x15FB]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER KKU", + direction="l", + linebreak="al", + unicodeslot=0x15FB, + }, + [0x15FC]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER KKO", + direction="l", + linebreak="al", + unicodeslot=0x15FC, + }, + [0x15FD]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER KKE", + direction="l", + linebreak="al", + unicodeslot=0x15FD, + }, + [0x15FE]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER KKEE", + direction="l", + linebreak="al", + unicodeslot=0x15FE, + }, + [0x15FF]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER KKI", + direction="l", + linebreak="al", + unicodeslot=0x15FF, + }, + [0x1600]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER KKA", + direction="l", + linebreak="al", + unicodeslot=0x1600, + }, + [0x1601]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER KK", + direction="l", + linebreak="al", + unicodeslot=0x1601, + }, + [0x1602]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER NU", + direction="l", + linebreak="al", + unicodeslot=0x1602, + }, + [0x1603]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER NO", + direction="l", + linebreak="al", + unicodeslot=0x1603, + }, + [0x1604]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER NE", + direction="l", + linebreak="al", + unicodeslot=0x1604, + }, + [0x1605]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER NEE", + direction="l", + linebreak="al", + unicodeslot=0x1605, + }, + [0x1606]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER NI", + direction="l", + linebreak="al", + unicodeslot=0x1606, + }, + [0x1607]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER NA", + direction="l", + linebreak="al", + unicodeslot=0x1607, + }, + [0x1608]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER MU", + direction="l", + linebreak="al", + unicodeslot=0x1608, + }, + [0x1609]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER MO", + direction="l", + linebreak="al", + unicodeslot=0x1609, + }, + [0x160A]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER ME", + direction="l", + linebreak="al", + unicodeslot=0x160A, + }, + [0x160B]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER MEE", + direction="l", + linebreak="al", + unicodeslot=0x160B, + }, + [0x160C]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER MI", + direction="l", + linebreak="al", + unicodeslot=0x160C, + }, + [0x160D]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER MA", + direction="l", + linebreak="al", + unicodeslot=0x160D, + }, + [0x160E]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER YU", + direction="l", + linebreak="al", + unicodeslot=0x160E, + }, + [0x160F]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER YO", + direction="l", + linebreak="al", + unicodeslot=0x160F, + }, + [0x1610]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER YE", + direction="l", + linebreak="al", + unicodeslot=0x1610, + }, + [0x1611]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER YEE", + direction="l", + linebreak="al", + unicodeslot=0x1611, + }, + [0x1612]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER YI", + direction="l", + linebreak="al", + unicodeslot=0x1612, + }, + [0x1613]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER YA", + direction="l", + linebreak="al", + unicodeslot=0x1613, + }, + [0x1614]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER JU", + direction="l", + linebreak="al", + unicodeslot=0x1614, + }, + [0x1615]={ + category="lo", + description="CANADIAN SYLLABICS SAYISI JU", + direction="l", + linebreak="al", + unicodeslot=0x1615, + }, + [0x1616]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER JO", + direction="l", + linebreak="al", + unicodeslot=0x1616, + }, + [0x1617]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER JE", + direction="l", + linebreak="al", + unicodeslot=0x1617, + }, + [0x1618]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER JEE", + direction="l", + linebreak="al", + unicodeslot=0x1618, + }, + [0x1619]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER JI", + direction="l", + linebreak="al", + unicodeslot=0x1619, + }, + [0x161A]={ + category="lo", + description="CANADIAN SYLLABICS SAYISI JI", + direction="l", + linebreak="al", + unicodeslot=0x161A, + }, + [0x161B]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER JA", + direction="l", + linebreak="al", + unicodeslot=0x161B, + }, + [0x161C]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER JJU", + direction="l", + linebreak="al", + unicodeslot=0x161C, + }, + [0x161D]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER JJO", + direction="l", + linebreak="al", + unicodeslot=0x161D, + }, + [0x161E]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER JJE", + direction="l", + linebreak="al", + unicodeslot=0x161E, + }, + [0x161F]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER JJEE", + direction="l", + linebreak="al", + unicodeslot=0x161F, + }, + [0x1620]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER JJI", + direction="l", + linebreak="al", + unicodeslot=0x1620, + }, + [0x1621]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER JJA", + direction="l", + linebreak="al", + unicodeslot=0x1621, + }, + [0x1622]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER LU", + direction="l", + linebreak="al", + unicodeslot=0x1622, + }, + [0x1623]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER LO", + direction="l", + linebreak="al", + unicodeslot=0x1623, + }, + [0x1624]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER LE", + direction="l", + linebreak="al", + unicodeslot=0x1624, + }, + [0x1625]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER LEE", + direction="l", + linebreak="al", + unicodeslot=0x1625, + }, + [0x1626]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER LI", + direction="l", + linebreak="al", + unicodeslot=0x1626, + }, + [0x1627]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER LA", + direction="l", + linebreak="al", + unicodeslot=0x1627, + }, + [0x1628]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER DLU", + direction="l", + linebreak="al", + unicodeslot=0x1628, + }, + [0x1629]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER DLO", + direction="l", + linebreak="al", + unicodeslot=0x1629, + }, + [0x162A]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER DLE", + direction="l", + linebreak="al", + unicodeslot=0x162A, + }, + [0x162B]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER DLEE", + direction="l", + linebreak="al", + unicodeslot=0x162B, + }, + [0x162C]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER DLI", + direction="l", + linebreak="al", + unicodeslot=0x162C, + }, + [0x162D]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER DLA", + direction="l", + linebreak="al", + unicodeslot=0x162D, + }, + [0x162E]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER LHU", + direction="l", + linebreak="al", + unicodeslot=0x162E, + }, + [0x162F]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER LHO", + direction="l", + linebreak="al", + unicodeslot=0x162F, + }, + [0x1630]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER LHE", + direction="l", + linebreak="al", + unicodeslot=0x1630, + }, + [0x1631]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER LHEE", + direction="l", + linebreak="al", + unicodeslot=0x1631, + }, + [0x1632]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER LHI", + direction="l", + linebreak="al", + unicodeslot=0x1632, + }, + [0x1633]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER LHA", + direction="l", + linebreak="al", + unicodeslot=0x1633, + }, + [0x1634]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TLHU", + direction="l", + linebreak="al", + unicodeslot=0x1634, + }, + [0x1635]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TLHO", + direction="l", + linebreak="al", + unicodeslot=0x1635, + }, + [0x1636]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TLHE", + direction="l", + linebreak="al", + unicodeslot=0x1636, + }, + [0x1637]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TLHEE", + direction="l", + linebreak="al", + unicodeslot=0x1637, + }, + [0x1638]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TLHI", + direction="l", + linebreak="al", + unicodeslot=0x1638, + }, + [0x1639]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TLHA", + direction="l", + linebreak="al", + unicodeslot=0x1639, + }, + [0x163A]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TLU", + direction="l", + linebreak="al", + unicodeslot=0x163A, + }, + [0x163B]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TLO", + direction="l", + linebreak="al", + unicodeslot=0x163B, + }, + [0x163C]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TLE", + direction="l", + linebreak="al", + unicodeslot=0x163C, + }, + [0x163D]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TLEE", + direction="l", + linebreak="al", + unicodeslot=0x163D, + }, + [0x163E]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TLI", + direction="l", + linebreak="al", + unicodeslot=0x163E, + }, + [0x163F]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TLA", + direction="l", + linebreak="al", + unicodeslot=0x163F, + }, + [0x1640]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER ZU", + direction="l", + linebreak="al", + unicodeslot=0x1640, + }, + [0x1641]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER ZO", + direction="l", + linebreak="al", + unicodeslot=0x1641, + }, + [0x1642]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER ZE", + direction="l", + linebreak="al", + unicodeslot=0x1642, + }, + [0x1643]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER ZEE", + direction="l", + linebreak="al", + unicodeslot=0x1643, + }, + [0x1644]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER ZI", + direction="l", + linebreak="al", + unicodeslot=0x1644, + }, + [0x1645]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER ZA", + direction="l", + linebreak="al", + unicodeslot=0x1645, + }, + [0x1646]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER Z", + direction="l", + linebreak="al", + unicodeslot=0x1646, + }, + [0x1647]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER INITIAL Z", + direction="l", + linebreak="al", + unicodeslot=0x1647, + }, + [0x1648]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER DZU", + direction="l", + linebreak="al", + unicodeslot=0x1648, + }, + [0x1649]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER DZO", + direction="l", + linebreak="al", + unicodeslot=0x1649, + }, + [0x164A]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER DZE", + direction="l", + linebreak="al", + unicodeslot=0x164A, + }, + [0x164B]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER DZEE", + direction="l", + linebreak="al", + unicodeslot=0x164B, + }, + [0x164C]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER DZI", + direction="l", + linebreak="al", + unicodeslot=0x164C, + }, + [0x164D]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER DZA", + direction="l", + linebreak="al", + unicodeslot=0x164D, + }, + [0x164E]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER SU", + direction="l", + linebreak="al", + unicodeslot=0x164E, + }, + [0x164F]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER SO", + direction="l", + linebreak="al", + unicodeslot=0x164F, + }, + [0x1650]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER SE", + direction="l", + linebreak="al", + unicodeslot=0x1650, + }, + [0x1651]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER SEE", + direction="l", + linebreak="al", + unicodeslot=0x1651, + }, + [0x1652]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER SI", + direction="l", + linebreak="al", + unicodeslot=0x1652, + }, + [0x1653]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER SA", + direction="l", + linebreak="al", + unicodeslot=0x1653, + }, + [0x1654]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER SHU", + direction="l", + linebreak="al", + unicodeslot=0x1654, + }, + [0x1655]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER SHO", + direction="l", + linebreak="al", + unicodeslot=0x1655, + }, + [0x1656]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER SHE", + direction="l", + linebreak="al", + unicodeslot=0x1656, + }, + [0x1657]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER SHEE", + direction="l", + linebreak="al", + unicodeslot=0x1657, + }, + [0x1658]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER SHI", + direction="l", + linebreak="al", + unicodeslot=0x1658, + }, + [0x1659]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER SHA", + direction="l", + linebreak="al", + unicodeslot=0x1659, + }, + [0x165A]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER SH", + direction="l", + linebreak="al", + unicodeslot=0x165A, + }, + [0x165B]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TSU", + direction="l", + linebreak="al", + unicodeslot=0x165B, + }, + [0x165C]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TSO", + direction="l", + linebreak="al", + unicodeslot=0x165C, + }, + [0x165D]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TSE", + direction="l", + linebreak="al", + unicodeslot=0x165D, + }, + [0x165E]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TSEE", + direction="l", + linebreak="al", + unicodeslot=0x165E, + }, + [0x165F]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TSI", + direction="l", + linebreak="al", + unicodeslot=0x165F, + }, + [0x1660]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TSA", + direction="l", + linebreak="al", + unicodeslot=0x1660, + }, + [0x1661]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER CHU", + direction="l", + linebreak="al", + unicodeslot=0x1661, + }, + [0x1662]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER CHO", + direction="l", + linebreak="al", + unicodeslot=0x1662, + }, + [0x1663]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER CHE", + direction="l", + linebreak="al", + unicodeslot=0x1663, + }, + [0x1664]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER CHEE", + direction="l", + linebreak="al", + unicodeslot=0x1664, + }, + [0x1665]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER CHI", + direction="l", + linebreak="al", + unicodeslot=0x1665, + }, + [0x1666]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER CHA", + direction="l", + linebreak="al", + unicodeslot=0x1666, + }, + [0x1667]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TTSU", + direction="l", + linebreak="al", + unicodeslot=0x1667, + }, + [0x1668]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TTSO", + direction="l", + linebreak="al", + unicodeslot=0x1668, + }, + [0x1669]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TTSE", + direction="l", + linebreak="al", + unicodeslot=0x1669, + }, + [0x166A]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TTSEE", + direction="l", + linebreak="al", + unicodeslot=0x166A, + }, + [0x166B]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TTSI", + direction="l", + linebreak="al", + unicodeslot=0x166B, + }, + [0x166C]={ + category="lo", + description="CANADIAN SYLLABICS CARRIER TTSA", + direction="l", + linebreak="al", + unicodeslot=0x166C, + }, + [0x166D]={ + category="po", + description="CANADIAN SYLLABICS CHI SIGN", + direction="l", + linebreak="al", + unicodeslot=0x166D, + }, + [0x166E]={ + category="po", + description="CANADIAN SYLLABICS FULL STOP", + direction="l", + linebreak="al", + unicodeslot=0x166E, + }, + [0x166F]={ + category="lo", + description="CANADIAN SYLLABICS QAI", + direction="l", + linebreak="al", + unicodeslot=0x166F, + }, + [0x1670]={ + category="lo", + description="CANADIAN SYLLABICS NGAI", + direction="l", + linebreak="al", + unicodeslot=0x1670, + }, + [0x1671]={ + category="lo", + description="CANADIAN SYLLABICS NNGI", + direction="l", + linebreak="al", + unicodeslot=0x1671, + }, + [0x1672]={ + category="lo", + description="CANADIAN SYLLABICS NNGII", + direction="l", + linebreak="al", + unicodeslot=0x1672, + }, + [0x1673]={ + category="lo", + description="CANADIAN SYLLABICS NNGO", + direction="l", + linebreak="al", + unicodeslot=0x1673, + }, + [0x1674]={ + category="lo", + description="CANADIAN SYLLABICS NNGOO", + direction="l", + linebreak="al", + unicodeslot=0x1674, + }, + [0x1675]={ + category="lo", + description="CANADIAN SYLLABICS NNGA", + direction="l", + linebreak="al", + unicodeslot=0x1675, + }, + [0x1676]={ + category="lo", + description="CANADIAN SYLLABICS NNGAA", + direction="l", + linebreak="al", + unicodeslot=0x1676, + }, + [0x1680]={ + category="zs", + description="OGHAM SPACE MARK", + direction="ws", + linebreak="ba", + unicodeslot=0x1680, + }, + [0x1681]={ + category="lo", + description="OGHAM LETTER BEITH", + direction="l", + linebreak="al", + unicodeslot=0x1681, + }, + [0x1682]={ + category="lo", + description="OGHAM LETTER LUIS", + direction="l", + linebreak="al", + unicodeslot=0x1682, + }, + [0x1683]={ + category="lo", + description="OGHAM LETTER FEARN", + direction="l", + linebreak="al", + unicodeslot=0x1683, + }, + [0x1684]={ + category="lo", + description="OGHAM LETTER SAIL", + direction="l", + linebreak="al", + unicodeslot=0x1684, + }, + [0x1685]={ + category="lo", + description="OGHAM LETTER NION", + direction="l", + linebreak="al", + unicodeslot=0x1685, + }, + [0x1686]={ + category="lo", + description="OGHAM LETTER UATH", + direction="l", + linebreak="al", + unicodeslot=0x1686, + }, + [0x1687]={ + category="lo", + description="OGHAM LETTER DAIR", + direction="l", + linebreak="al", + unicodeslot=0x1687, + }, + [0x1688]={ + category="lo", + description="OGHAM LETTER TINNE", + direction="l", + linebreak="al", + unicodeslot=0x1688, + }, + [0x1689]={ + category="lo", + description="OGHAM LETTER COLL", + direction="l", + linebreak="al", + unicodeslot=0x1689, + }, + [0x168A]={ + category="lo", + description="OGHAM LETTER CEIRT", + direction="l", + linebreak="al", + unicodeslot=0x168A, + }, + [0x168B]={ + category="lo", + description="OGHAM LETTER MUIN", + direction="l", + linebreak="al", + unicodeslot=0x168B, + }, + [0x168C]={ + category="lo", + description="OGHAM LETTER GORT", + direction="l", + linebreak="al", + unicodeslot=0x168C, + }, + [0x168D]={ + category="lo", + description="OGHAM LETTER NGEADAL", + direction="l", + linebreak="al", + unicodeslot=0x168D, + }, + [0x168E]={ + category="lo", + description="OGHAM LETTER STRAIF", + direction="l", + linebreak="al", + unicodeslot=0x168E, + }, + [0x168F]={ + category="lo", + description="OGHAM LETTER RUIS", + direction="l", + linebreak="al", + unicodeslot=0x168F, + }, + [0x1690]={ + category="lo", + description="OGHAM LETTER AILM", + direction="l", + linebreak="al", + unicodeslot=0x1690, + }, + [0x1691]={ + category="lo", + description="OGHAM LETTER ONN", + direction="l", + linebreak="al", + unicodeslot=0x1691, + }, + [0x1692]={ + category="lo", + description="OGHAM LETTER UR", + direction="l", + linebreak="al", + unicodeslot=0x1692, + }, + [0x1693]={ + category="lo", + description="OGHAM LETTER EADHADH", + direction="l", + linebreak="al", + unicodeslot=0x1693, + }, + [0x1694]={ + category="lo", + description="OGHAM LETTER IODHADH", + direction="l", + linebreak="al", + unicodeslot=0x1694, + }, + [0x1695]={ + category="lo", + description="OGHAM LETTER EABHADH", + direction="l", + linebreak="al", + unicodeslot=0x1695, + }, + [0x1696]={ + category="lo", + description="OGHAM LETTER OR", + direction="l", + linebreak="al", + unicodeslot=0x1696, + }, + [0x1697]={ + category="lo", + description="OGHAM LETTER UILLEANN", + direction="l", + linebreak="al", + unicodeslot=0x1697, + }, + [0x1698]={ + category="lo", + description="OGHAM LETTER IFIN", + direction="l", + linebreak="al", + unicodeslot=0x1698, + }, + [0x1699]={ + category="lo", + description="OGHAM LETTER EAMHANCHOLL", + direction="l", + linebreak="al", + unicodeslot=0x1699, + }, + [0x169A]={ + category="lo", + description="OGHAM LETTER PEITH", + direction="l", + linebreak="al", + unicodeslot=0x169A, + }, + [0x169B]={ + category="ps", + description="OGHAM FEATHER MARK", + direction="on", + linebreak="op", + mirror=0x169C, + unicodeslot=0x169B, + }, + [0x169C]={ + category="pe", + description="OGHAM REVERSED FEATHER MARK", + direction="on", + linebreak="cl", + mirror=0x169B, + unicodeslot=0x169C, + }, + [0x16A0]={ + category="lo", + description="RUNIC LETTER FEHU FEOH FE F", + direction="l", + linebreak="al", + unicodeslot=0x16A0, + }, + [0x16A1]={ + category="lo", + description="RUNIC LETTER V", + direction="l", + linebreak="al", + unicodeslot=0x16A1, + }, + [0x16A2]={ + category="lo", + description="RUNIC LETTER URUZ UR U", + direction="l", + linebreak="al", + unicodeslot=0x16A2, + }, + [0x16A3]={ + category="lo", + description="RUNIC LETTER YR", + direction="l", + linebreak="al", + unicodeslot=0x16A3, + }, + [0x16A4]={ + category="lo", + description="RUNIC LETTER Y", + direction="l", + linebreak="al", + unicodeslot=0x16A4, + }, + [0x16A5]={ + category="lo", + description="RUNIC LETTER W", + direction="l", + linebreak="al", + unicodeslot=0x16A5, + }, + [0x16A6]={ + category="lo", + description="RUNIC LETTER THURISAZ THURS THORN", + direction="l", + linebreak="al", + unicodeslot=0x16A6, + }, + [0x16A7]={ + category="lo", + description="RUNIC LETTER ETH", + direction="l", + linebreak="al", + unicodeslot=0x16A7, + }, + [0x16A8]={ + category="lo", + description="RUNIC LETTER ANSUZ A", + direction="l", + linebreak="al", + unicodeslot=0x16A8, + }, + [0x16A9]={ + category="lo", + description="RUNIC LETTER OS O", + direction="l", + linebreak="al", + unicodeslot=0x16A9, + }, + [0x16AA]={ + category="lo", + description="RUNIC LETTER AC A", + direction="l", + linebreak="al", + unicodeslot=0x16AA, + }, + [0x16AB]={ + category="lo", + description="RUNIC LETTER AESC", + direction="l", + linebreak="al", + unicodeslot=0x16AB, + }, + [0x16AC]={ + category="lo", + description="RUNIC LETTER LONG-BRANCH-OSS O", + direction="l", + linebreak="al", + unicodeslot=0x16AC, + }, + [0x16AD]={ + category="lo", + description="RUNIC LETTER SHORT-TWIG-OSS O", + direction="l", + linebreak="al", + unicodeslot=0x16AD, + }, + [0x16AE]={ + category="lo", + description="RUNIC LETTER O", + direction="l", + linebreak="al", + unicodeslot=0x16AE, + }, + [0x16AF]={ + category="lo", + description="RUNIC LETTER OE", + direction="l", + linebreak="al", + unicodeslot=0x16AF, + }, + [0x16B0]={ + category="lo", + description="RUNIC LETTER ON", + direction="l", + linebreak="al", + unicodeslot=0x16B0, + }, + [0x16B1]={ + category="lo", + description="RUNIC LETTER RAIDO RAD REID R", + direction="l", + linebreak="al", + unicodeslot=0x16B1, + }, + [0x16B2]={ + category="lo", + description="RUNIC LETTER KAUNA", + direction="l", + linebreak="al", + unicodeslot=0x16B2, + }, + [0x16B3]={ + category="lo", + description="RUNIC LETTER CEN", + direction="l", + linebreak="al", + unicodeslot=0x16B3, + }, + [0x16B4]={ + category="lo", + description="RUNIC LETTER KAUN K", + direction="l", + linebreak="al", + unicodeslot=0x16B4, + }, + [0x16B5]={ + category="lo", + description="RUNIC LETTER G", + direction="l", + linebreak="al", + unicodeslot=0x16B5, + }, + [0x16B6]={ + category="lo", + description="RUNIC LETTER ENG", + direction="l", + linebreak="al", + unicodeslot=0x16B6, + }, + [0x16B7]={ + category="lo", + description="RUNIC LETTER GEBO GYFU G", + direction="l", + linebreak="al", + unicodeslot=0x16B7, + }, + [0x16B8]={ + category="lo", + description="RUNIC LETTER GAR", + direction="l", + linebreak="al", + unicodeslot=0x16B8, + }, + [0x16B9]={ + category="lo", + description="RUNIC LETTER WUNJO WYNN W", + direction="l", + linebreak="al", + unicodeslot=0x16B9, + }, + [0x16BA]={ + category="lo", + description="RUNIC LETTER HAGLAZ H", + direction="l", + linebreak="al", + unicodeslot=0x16BA, + }, + [0x16BB]={ + category="lo", + description="RUNIC LETTER HAEGL H", + direction="l", + linebreak="al", + unicodeslot=0x16BB, + }, + [0x16BC]={ + category="lo", + description="RUNIC LETTER LONG-BRANCH-HAGALL H", + direction="l", + linebreak="al", + unicodeslot=0x16BC, + }, + [0x16BD]={ + category="lo", + description="RUNIC LETTER SHORT-TWIG-HAGALL H", + direction="l", + linebreak="al", + unicodeslot=0x16BD, + }, + [0x16BE]={ + category="lo", + description="RUNIC LETTER NAUDIZ NYD NAUD N", + direction="l", + linebreak="al", + unicodeslot=0x16BE, + }, + [0x16BF]={ + category="lo", + description="RUNIC LETTER SHORT-TWIG-NAUD N", + direction="l", + linebreak="al", + unicodeslot=0x16BF, + }, + [0x16C0]={ + category="lo", + description="RUNIC LETTER DOTTED-N", + direction="l", + linebreak="al", + unicodeslot=0x16C0, + }, + [0x16C1]={ + category="lo", + description="RUNIC LETTER ISAZ IS ISS I", + direction="l", + linebreak="al", + unicodeslot=0x16C1, + }, + [0x16C2]={ + category="lo", + description="RUNIC LETTER E", + direction="l", + linebreak="al", + unicodeslot=0x16C2, + }, + [0x16C3]={ + category="lo", + description="RUNIC LETTER JERAN J", + direction="l", + linebreak="al", + unicodeslot=0x16C3, + }, + [0x16C4]={ + category="lo", + description="RUNIC LETTER GER", + direction="l", + linebreak="al", + unicodeslot=0x16C4, + }, + [0x16C5]={ + category="lo", + description="RUNIC LETTER LONG-BRANCH-AR AE", + direction="l", + linebreak="al", + unicodeslot=0x16C5, + }, + [0x16C6]={ + category="lo", + description="RUNIC LETTER SHORT-TWIG-AR A", + direction="l", + linebreak="al", + unicodeslot=0x16C6, + }, + [0x16C7]={ + category="lo", + description="RUNIC LETTER IWAZ EOH", + direction="l", + linebreak="al", + unicodeslot=0x16C7, + }, + [0x16C8]={ + category="lo", + description="RUNIC LETTER PERTHO PEORTH P", + direction="l", + linebreak="al", + unicodeslot=0x16C8, + }, + [0x16C9]={ + category="lo", + description="RUNIC LETTER ALGIZ EOLHX", + direction="l", + linebreak="al", + unicodeslot=0x16C9, + }, + [0x16CA]={ + category="lo", + description="RUNIC LETTER SOWILO S", + direction="l", + linebreak="al", + unicodeslot=0x16CA, + }, + [0x16CB]={ + category="lo", + description="RUNIC LETTER SIGEL LONG-BRANCH-SOL S", + direction="l", + linebreak="al", + unicodeslot=0x16CB, + }, + [0x16CC]={ + category="lo", + description="RUNIC LETTER SHORT-TWIG-SOL S", + direction="l", + linebreak="al", + unicodeslot=0x16CC, + }, + [0x16CD]={ + category="lo", + description="RUNIC LETTER C", + direction="l", + linebreak="al", + unicodeslot=0x16CD, + }, + [0x16CE]={ + category="lo", + description="RUNIC LETTER Z", + direction="l", + linebreak="al", + unicodeslot=0x16CE, + }, + [0x16CF]={ + category="lo", + description="RUNIC LETTER TIWAZ TIR TYR T", + direction="l", + linebreak="al", + unicodeslot=0x16CF, + }, + [0x16D0]={ + category="lo", + description="RUNIC LETTER SHORT-TWIG-TYR T", + direction="l", + linebreak="al", + unicodeslot=0x16D0, + }, + [0x16D1]={ + category="lo", + description="RUNIC LETTER D", + direction="l", + linebreak="al", + unicodeslot=0x16D1, + }, + [0x16D2]={ + category="lo", + description="RUNIC LETTER BERKANAN BEORC BJARKAN B", + direction="l", + linebreak="al", + unicodeslot=0x16D2, + }, + [0x16D3]={ + category="lo", + description="RUNIC LETTER SHORT-TWIG-BJARKAN B", + direction="l", + linebreak="al", + unicodeslot=0x16D3, + }, + [0x16D4]={ + category="lo", + description="RUNIC LETTER DOTTED-P", + direction="l", + linebreak="al", + unicodeslot=0x16D4, + }, + [0x16D5]={ + category="lo", + description="RUNIC LETTER OPEN-P", + direction="l", + linebreak="al", + unicodeslot=0x16D5, + }, + [0x16D6]={ + category="lo", + description="RUNIC LETTER EHWAZ EH E", + direction="l", + linebreak="al", + unicodeslot=0x16D6, + }, + [0x16D7]={ + category="lo", + description="RUNIC LETTER MANNAZ MAN M", + direction="l", + linebreak="al", + unicodeslot=0x16D7, + }, + [0x16D8]={ + category="lo", + description="RUNIC LETTER LONG-BRANCH-MADR M", + direction="l", + linebreak="al", + unicodeslot=0x16D8, + }, + [0x16D9]={ + category="lo", + description="RUNIC LETTER SHORT-TWIG-MADR M", + direction="l", + linebreak="al", + unicodeslot=0x16D9, + }, + [0x16DA]={ + category="lo", + description="RUNIC LETTER LAUKAZ LAGU LOGR L", + direction="l", + linebreak="al", + unicodeslot=0x16DA, + }, + [0x16DB]={ + category="lo", + description="RUNIC LETTER DOTTED-L", + direction="l", + linebreak="al", + unicodeslot=0x16DB, + }, + [0x16DC]={ + category="lo", + description="RUNIC LETTER INGWAZ", + direction="l", + linebreak="al", + unicodeslot=0x16DC, + }, + [0x16DD]={ + category="lo", + description="RUNIC LETTER ING", + direction="l", + linebreak="al", + unicodeslot=0x16DD, + }, + [0x16DE]={ + category="lo", + description="RUNIC LETTER DAGAZ DAEG D", + direction="l", + linebreak="al", + unicodeslot=0x16DE, + }, + [0x16DF]={ + category="lo", + description="RUNIC LETTER OTHALAN ETHEL O", + direction="l", + linebreak="al", + unicodeslot=0x16DF, + }, + [0x16E0]={ + category="lo", + description="RUNIC LETTER EAR", + direction="l", + linebreak="al", + unicodeslot=0x16E0, + }, + [0x16E1]={ + category="lo", + description="RUNIC LETTER IOR", + direction="l", + linebreak="al", + unicodeslot=0x16E1, + }, + [0x16E2]={ + category="lo", + description="RUNIC LETTER CWEORTH", + direction="l", + linebreak="al", + unicodeslot=0x16E2, + }, + [0x16E3]={ + category="lo", + description="RUNIC LETTER CALC", + direction="l", + linebreak="al", + unicodeslot=0x16E3, + }, + [0x16E4]={ + category="lo", + description="RUNIC LETTER CEALC", + direction="l", + linebreak="al", + unicodeslot=0x16E4, + }, + [0x16E5]={ + category="lo", + description="RUNIC LETTER STAN", + direction="l", + linebreak="al", + unicodeslot=0x16E5, + }, + [0x16E6]={ + category="lo", + description="RUNIC LETTER LONG-BRANCH-YR", + direction="l", + linebreak="al", + unicodeslot=0x16E6, + }, + [0x16E7]={ + category="lo", + description="RUNIC LETTER SHORT-TWIG-YR", + direction="l", + linebreak="al", + unicodeslot=0x16E7, + }, + [0x16E8]={ + category="lo", + description="RUNIC LETTER ICELANDIC-YR", + direction="l", + linebreak="al", + unicodeslot=0x16E8, + }, + [0x16E9]={ + category="lo", + description="RUNIC LETTER Q", + direction="l", + linebreak="al", + unicodeslot=0x16E9, + }, + [0x16EA]={ + category="lo", + description="RUNIC LETTER X", + direction="l", + linebreak="al", + unicodeslot=0x16EA, + }, + [0x16EB]={ + category="po", + description="RUNIC SINGLE PUNCTUATION", + direction="l", + linebreak="ba", + unicodeslot=0x16EB, + }, + [0x16EC]={ + category="po", + description="RUNIC MULTIPLE PUNCTUATION", + direction="l", + linebreak="ba", + unicodeslot=0x16EC, + }, + [0x16ED]={ + category="po", + description="RUNIC CROSS PUNCTUATION", + direction="l", + linebreak="ba", + unicodeslot=0x16ED, + }, + [0x16EE]={ + category="nl", + description="RUNIC ARLAUG SYMBOL", + direction="l", + linebreak="al", + unicodeslot=0x16EE, + }, + [0x16EF]={ + category="nl", + description="RUNIC TVIMADUR SYMBOL", + direction="l", + linebreak="al", + unicodeslot=0x16EF, + }, + [0x16F0]={ + category="nl", + description="RUNIC BELGTHOR SYMBOL", + direction="l", + linebreak="al", + unicodeslot=0x16F0, + }, + [0x1700]={ + category="lo", + description="TAGALOG LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x1700, + }, + [0x1701]={ + category="lo", + description="TAGALOG LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x1701, + }, + [0x1702]={ + category="lo", + description="TAGALOG LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x1702, + }, + [0x1703]={ + category="lo", + description="TAGALOG LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x1703, + }, + [0x1704]={ + category="lo", + description="TAGALOG LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x1704, + }, + [0x1705]={ + category="lo", + description="TAGALOG LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0x1705, + }, + [0x1706]={ + category="lo", + description="TAGALOG LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x1706, + }, + [0x1707]={ + category="lo", + description="TAGALOG LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x1707, + }, + [0x1708]={ + category="lo", + description="TAGALOG LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x1708, + }, + [0x1709]={ + category="lo", + description="TAGALOG LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x1709, + }, + [0x170A]={ + category="lo", + description="TAGALOG LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x170A, + }, + [0x170B]={ + category="lo", + description="TAGALOG LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x170B, + }, + [0x170C]={ + category="lo", + description="TAGALOG LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x170C, + }, + [0x170E]={ + category="lo", + description="TAGALOG LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x170E, + }, + [0x170F]={ + category="lo", + description="TAGALOG LETTER WA", + direction="l", + linebreak="al", + unicodeslot=0x170F, + }, + [0x1710]={ + category="lo", + description="TAGALOG LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x1710, + }, + [0x1711]={ + category="lo", + description="TAGALOG LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x1711, + }, + [0x1712]={ + category="mn", + description="TAGALOG VOWEL SIGN I", + direction="nsm", + linebreak="cm", + unicodeslot=0x1712, + }, + [0x1713]={ + category="mn", + description="TAGALOG VOWEL SIGN U", + direction="nsm", + linebreak="cm", + unicodeslot=0x1713, + }, + [0x1714]={ + category="mn", + description="TAGALOG SIGN VIRAMA", + direction="nsm", + linebreak="cm", + unicodeslot=0x1714, + }, + [0x1720]={ + category="lo", + description="HANUNOO LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x1720, + }, + [0x1721]={ + category="lo", + description="HANUNOO LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x1721, + }, + [0x1722]={ + category="lo", + description="HANUNOO LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x1722, + }, + [0x1723]={ + category="lo", + description="HANUNOO LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x1723, + }, + [0x1724]={ + category="lo", + description="HANUNOO LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x1724, + }, + [0x1725]={ + category="lo", + description="HANUNOO LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0x1725, + }, + [0x1726]={ + category="lo", + description="HANUNOO LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x1726, + }, + [0x1727]={ + category="lo", + description="HANUNOO LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x1727, + }, + [0x1728]={ + category="lo", + description="HANUNOO LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x1728, + }, + [0x1729]={ + category="lo", + description="HANUNOO LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x1729, + }, + [0x172A]={ + category="lo", + description="HANUNOO LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x172A, + }, + [0x172B]={ + category="lo", + description="HANUNOO LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x172B, + }, + [0x172C]={ + category="lo", + description="HANUNOO LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x172C, + }, + [0x172D]={ + category="lo", + description="HANUNOO LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0x172D, + }, + [0x172E]={ + category="lo", + description="HANUNOO LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x172E, + }, + [0x172F]={ + category="lo", + description="HANUNOO LETTER WA", + direction="l", + linebreak="al", + unicodeslot=0x172F, + }, + [0x1730]={ + category="lo", + description="HANUNOO LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x1730, + }, + [0x1731]={ + category="lo", + description="HANUNOO LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x1731, + }, + [0x1732]={ + category="mn", + description="HANUNOO VOWEL SIGN I", + direction="nsm", + linebreak="cm", + unicodeslot=0x1732, + }, + [0x1733]={ + category="mn", + description="HANUNOO VOWEL SIGN U", + direction="nsm", + linebreak="cm", + unicodeslot=0x1733, + }, + [0x1734]={ + category="mn", + description="HANUNOO SIGN PAMUDPOD", + direction="nsm", + linebreak="cm", + unicodeslot=0x1734, + }, + [0x1735]={ + category="po", + description="PHILIPPINE SINGLE PUNCTUATION", + direction="l", + linebreak="ba", + unicodeslot=0x1735, + }, + [0x1736]={ + category="po", + description="PHILIPPINE DOUBLE PUNCTUATION", + direction="l", + linebreak="ba", + unicodeslot=0x1736, + }, + [0x1740]={ + category="lo", + description="BUHID LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x1740, + }, + [0x1741]={ + category="lo", + description="BUHID LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x1741, + }, + [0x1742]={ + category="lo", + description="BUHID LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x1742, + }, + [0x1743]={ + category="lo", + description="BUHID LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x1743, + }, + [0x1744]={ + category="lo", + description="BUHID LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x1744, + }, + [0x1745]={ + category="lo", + description="BUHID LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0x1745, + }, + [0x1746]={ + category="lo", + description="BUHID LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x1746, + }, + [0x1747]={ + category="lo", + description="BUHID LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x1747, + }, + [0x1748]={ + category="lo", + description="BUHID LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x1748, + }, + [0x1749]={ + category="lo", + description="BUHID LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x1749, + }, + [0x174A]={ + category="lo", + description="BUHID LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x174A, + }, + [0x174B]={ + category="lo", + description="BUHID LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x174B, + }, + [0x174C]={ + category="lo", + description="BUHID LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x174C, + }, + [0x174D]={ + category="lo", + description="BUHID LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0x174D, + }, + [0x174E]={ + category="lo", + description="BUHID LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x174E, + }, + [0x174F]={ + category="lo", + description="BUHID LETTER WA", + direction="l", + linebreak="al", + unicodeslot=0x174F, + }, + [0x1750]={ + category="lo", + description="BUHID LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x1750, + }, + [0x1751]={ + category="lo", + description="BUHID LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x1751, + }, + [0x1752]={ + category="mn", + description="BUHID VOWEL SIGN I", + direction="nsm", + linebreak="cm", + unicodeslot=0x1752, + }, + [0x1753]={ + category="mn", + description="BUHID VOWEL SIGN U", + direction="nsm", + linebreak="cm", + unicodeslot=0x1753, + }, + [0x1760]={ + category="lo", + description="TAGBANWA LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x1760, + }, + [0x1761]={ + category="lo", + description="TAGBANWA LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x1761, + }, + [0x1762]={ + category="lo", + description="TAGBANWA LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x1762, + }, + [0x1763]={ + category="lo", + description="TAGBANWA LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x1763, + }, + [0x1764]={ + category="lo", + description="TAGBANWA LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x1764, + }, + [0x1765]={ + category="lo", + description="TAGBANWA LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0x1765, + }, + [0x1766]={ + category="lo", + description="TAGBANWA LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x1766, + }, + [0x1767]={ + category="lo", + description="TAGBANWA LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x1767, + }, + [0x1768]={ + category="lo", + description="TAGBANWA LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x1768, + }, + [0x1769]={ + category="lo", + description="TAGBANWA LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x1769, + }, + [0x176A]={ + category="lo", + description="TAGBANWA LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x176A, + }, + [0x176B]={ + category="lo", + description="TAGBANWA LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x176B, + }, + [0x176C]={ + category="lo", + description="TAGBANWA LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x176C, + }, + [0x176E]={ + category="lo", + description="TAGBANWA LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x176E, + }, + [0x176F]={ + category="lo", + description="TAGBANWA LETTER WA", + direction="l", + linebreak="al", + unicodeslot=0x176F, + }, + [0x1770]={ + category="lo", + description="TAGBANWA LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x1770, + }, + [0x1772]={ + category="mn", + description="TAGBANWA VOWEL SIGN I", + direction="nsm", + linebreak="cm", + unicodeslot=0x1772, + }, + [0x1773]={ + category="mn", + description="TAGBANWA VOWEL SIGN U", + direction="nsm", + linebreak="cm", + unicodeslot=0x1773, + }, + [0x1780]={ + category="lo", + description="KHMER LETTER KA", + direction="l", + linebreak="sa", + unicodeslot=0x1780, + }, + [0x1781]={ + category="lo", + description="KHMER LETTER KHA", + direction="l", + linebreak="sa", + unicodeslot=0x1781, + }, + [0x1782]={ + category="lo", + description="KHMER LETTER KO", + direction="l", + linebreak="sa", + unicodeslot=0x1782, + }, + [0x1783]={ + category="lo", + description="KHMER LETTER KHO", + direction="l", + linebreak="sa", + unicodeslot=0x1783, + }, + [0x1784]={ + category="lo", + description="KHMER LETTER NGO", + direction="l", + linebreak="sa", + unicodeslot=0x1784, + }, + [0x1785]={ + category="lo", + description="KHMER LETTER CA", + direction="l", + linebreak="sa", + unicodeslot=0x1785, + }, + [0x1786]={ + category="lo", + description="KHMER LETTER CHA", + direction="l", + linebreak="sa", + unicodeslot=0x1786, + }, + [0x1787]={ + category="lo", + description="KHMER LETTER CO", + direction="l", + linebreak="sa", + unicodeslot=0x1787, + }, + [0x1788]={ + category="lo", + description="KHMER LETTER CHO", + direction="l", + linebreak="sa", + unicodeslot=0x1788, + }, + [0x1789]={ + category="lo", + description="KHMER LETTER NYO", + direction="l", + linebreak="sa", + unicodeslot=0x1789, + }, + [0x178A]={ + category="lo", + description="KHMER LETTER DA", + direction="l", + linebreak="sa", + unicodeslot=0x178A, + }, + [0x178B]={ + category="lo", + description="KHMER LETTER TTHA", + direction="l", + linebreak="sa", + unicodeslot=0x178B, + }, + [0x178C]={ + category="lo", + description="KHMER LETTER DO", + direction="l", + linebreak="sa", + unicodeslot=0x178C, + }, + [0x178D]={ + category="lo", + description="KHMER LETTER TTHO", + direction="l", + linebreak="sa", + unicodeslot=0x178D, + }, + [0x178E]={ + category="lo", + description="KHMER LETTER NNO", + direction="l", + linebreak="sa", + unicodeslot=0x178E, + }, + [0x178F]={ + category="lo", + description="KHMER LETTER TA", + direction="l", + linebreak="sa", + unicodeslot=0x178F, + }, + [0x1790]={ + category="lo", + description="KHMER LETTER THA", + direction="l", + linebreak="sa", + unicodeslot=0x1790, + }, + [0x1791]={ + category="lo", + description="KHMER LETTER TO", + direction="l", + linebreak="sa", + unicodeslot=0x1791, + }, + [0x1792]={ + category="lo", + description="KHMER LETTER THO", + direction="l", + linebreak="sa", + unicodeslot=0x1792, + }, + [0x1793]={ + category="lo", + description="KHMER LETTER NO", + direction="l", + linebreak="sa", + unicodeslot=0x1793, + }, + [0x1794]={ + category="lo", + description="KHMER LETTER BA", + direction="l", + linebreak="sa", + unicodeslot=0x1794, + }, + [0x1795]={ + category="lo", + description="KHMER LETTER PHA", + direction="l", + linebreak="sa", + unicodeslot=0x1795, + }, + [0x1796]={ + category="lo", + description="KHMER LETTER PO", + direction="l", + linebreak="sa", + unicodeslot=0x1796, + }, + [0x1797]={ + category="lo", + description="KHMER LETTER PHO", + direction="l", + linebreak="sa", + unicodeslot=0x1797, + }, + [0x1798]={ + category="lo", + description="KHMER LETTER MO", + direction="l", + linebreak="sa", + unicodeslot=0x1798, + }, + [0x1799]={ + category="lo", + description="KHMER LETTER YO", + direction="l", + linebreak="sa", + unicodeslot=0x1799, + }, + [0x179A]={ + category="lo", + description="KHMER LETTER RO", + direction="l", + linebreak="sa", + unicodeslot=0x179A, + }, + [0x179B]={ + category="lo", + description="KHMER LETTER LO", + direction="l", + linebreak="sa", + unicodeslot=0x179B, + }, + [0x179C]={ + category="lo", + description="KHMER LETTER VO", + direction="l", + linebreak="sa", + unicodeslot=0x179C, + }, + [0x179D]={ + category="lo", + description="KHMER LETTER SHA", + direction="l", + linebreak="sa", + unicodeslot=0x179D, + }, + [0x179E]={ + category="lo", + description="KHMER LETTER SSO", + direction="l", + linebreak="sa", + unicodeslot=0x179E, + }, + [0x179F]={ + category="lo", + description="KHMER LETTER SA", + direction="l", + linebreak="sa", + unicodeslot=0x179F, + }, + [0x17A0]={ + category="lo", + description="KHMER LETTER HA", + direction="l", + linebreak="sa", + unicodeslot=0x17A0, + }, + [0x17A1]={ + category="lo", + description="KHMER LETTER LA", + direction="l", + linebreak="sa", + unicodeslot=0x17A1, + }, + [0x17A2]={ + category="lo", + description="KHMER LETTER QA", + direction="l", + linebreak="sa", + unicodeslot=0x17A2, + }, + [0x17A3]={ + category="lo", + description="KHMER INDEPENDENT VOWEL QAQ", + direction="l", + linebreak="sa", + unicodeslot=0x17A3, + }, + [0x17A4]={ + category="lo", + description="KHMER INDEPENDENT VOWEL QAA", + direction="l", + linebreak="sa", + unicodeslot=0x17A4, + }, + [0x17A5]={ + category="lo", + description="KHMER INDEPENDENT VOWEL QI", + direction="l", + linebreak="sa", + unicodeslot=0x17A5, + }, + [0x17A6]={ + category="lo", + description="KHMER INDEPENDENT VOWEL QII", + direction="l", + linebreak="sa", + unicodeslot=0x17A6, + }, + [0x17A7]={ + category="lo", + description="KHMER INDEPENDENT VOWEL QU", + direction="l", + linebreak="sa", + unicodeslot=0x17A7, + }, + [0x17A8]={ + category="lo", + description="KHMER INDEPENDENT VOWEL QUK", + direction="l", + linebreak="sa", + unicodeslot=0x17A8, + }, + [0x17A9]={ + category="lo", + description="KHMER INDEPENDENT VOWEL QUU", + direction="l", + linebreak="sa", + unicodeslot=0x17A9, + }, + [0x17AA]={ + category="lo", + description="KHMER INDEPENDENT VOWEL QUUV", + direction="l", + linebreak="sa", + unicodeslot=0x17AA, + }, + [0x17AB]={ + category="lo", + description="KHMER INDEPENDENT VOWEL RY", + direction="l", + linebreak="sa", + unicodeslot=0x17AB, + }, + [0x17AC]={ + category="lo", + description="KHMER INDEPENDENT VOWEL RYY", + direction="l", + linebreak="sa", + unicodeslot=0x17AC, + }, + [0x17AD]={ + category="lo", + description="KHMER INDEPENDENT VOWEL LY", + direction="l", + linebreak="sa", + unicodeslot=0x17AD, + }, + [0x17AE]={ + category="lo", + description="KHMER INDEPENDENT VOWEL LYY", + direction="l", + linebreak="sa", + unicodeslot=0x17AE, + }, + [0x17AF]={ + category="lo", + description="KHMER INDEPENDENT VOWEL QE", + direction="l", + linebreak="sa", + unicodeslot=0x17AF, + }, + [0x17B0]={ + category="lo", + description="KHMER INDEPENDENT VOWEL QAI", + direction="l", + linebreak="sa", + unicodeslot=0x17B0, + }, + [0x17B1]={ + category="lo", + description="KHMER INDEPENDENT VOWEL QOO TYPE ONE", + direction="l", + linebreak="sa", + unicodeslot=0x17B1, + }, + [0x17B2]={ + category="lo", + description="KHMER INDEPENDENT VOWEL QOO TYPE TWO", + direction="l", + linebreak="sa", + unicodeslot=0x17B2, + }, + [0x17B3]={ + category="lo", + description="KHMER INDEPENDENT VOWEL QAU", + direction="l", + linebreak="sa", + unicodeslot=0x17B3, + }, + [0x17B4]={ + category="cf", + description="KHMER VOWEL INHERENT AQ", + direction="l", + linebreak="sa", + unicodeslot=0x17B4, + }, + [0x17B5]={ + category="cf", + description="KHMER VOWEL INHERENT AA", + direction="l", + linebreak="sa", + unicodeslot=0x17B5, + }, + [0x17B6]={ + category="mc", + description="KHMER VOWEL SIGN AA", + direction="l", + linebreak="sa", + unicodeslot=0x17B6, + }, + [0x17B7]={ + category="mn", + description="KHMER VOWEL SIGN I", + direction="nsm", + linebreak="sa", + unicodeslot=0x17B7, + }, + [0x17B8]={ + category="mn", + description="KHMER VOWEL SIGN II", + direction="nsm", + linebreak="sa", + unicodeslot=0x17B8, + }, + [0x17B9]={ + category="mn", + description="KHMER VOWEL SIGN Y", + direction="nsm", + linebreak="sa", + unicodeslot=0x17B9, + }, + [0x17BA]={ + category="mn", + description="KHMER VOWEL SIGN YY", + direction="nsm", + linebreak="sa", + unicodeslot=0x17BA, + }, + [0x17BB]={ + category="mn", + description="KHMER VOWEL SIGN U", + direction="nsm", + linebreak="sa", + unicodeslot=0x17BB, + }, + [0x17BC]={ + category="mn", + description="KHMER VOWEL SIGN UU", + direction="nsm", + linebreak="sa", + unicodeslot=0x17BC, + }, + [0x17BD]={ + category="mn", + description="KHMER VOWEL SIGN UA", + direction="nsm", + linebreak="sa", + unicodeslot=0x17BD, + }, + [0x17BE]={ + category="mc", + description="KHMER VOWEL SIGN OE", + direction="l", + linebreak="sa", + unicodeslot=0x17BE, + }, + [0x17BF]={ + category="mc", + description="KHMER VOWEL SIGN YA", + direction="l", + linebreak="sa", + unicodeslot=0x17BF, + }, + [0x17C0]={ + category="mc", + description="KHMER VOWEL SIGN IE", + direction="l", + linebreak="sa", + unicodeslot=0x17C0, + }, + [0x17C1]={ + category="mc", + description="KHMER VOWEL SIGN E", + direction="l", + linebreak="sa", + unicodeslot=0x17C1, + }, + [0x17C2]={ + category="mc", + description="KHMER VOWEL SIGN AE", + direction="l", + linebreak="sa", + unicodeslot=0x17C2, + }, + [0x17C3]={ + category="mc", + description="KHMER VOWEL SIGN AI", + direction="l", + linebreak="sa", + unicodeslot=0x17C3, + }, + [0x17C4]={ + category="mc", + description="KHMER VOWEL SIGN OO", + direction="l", + linebreak="sa", + unicodeslot=0x17C4, + }, + [0x17C5]={ + category="mc", + description="KHMER VOWEL SIGN AU", + direction="l", + linebreak="sa", + unicodeslot=0x17C5, + }, + [0x17C6]={ + category="mn", + description="KHMER SIGN NIKAHIT", + direction="nsm", + linebreak="sa", + unicodeslot=0x17C6, + }, + [0x17C7]={ + category="mc", + description="KHMER SIGN REAHMUK", + direction="l", + linebreak="sa", + unicodeslot=0x17C7, + }, + [0x17C8]={ + category="mc", + description="KHMER SIGN YUUKALEAPINTU", + direction="l", + linebreak="sa", + unicodeslot=0x17C8, + }, + [0x17C9]={ + category="mn", + description="KHMER SIGN MUUSIKATOAN", + direction="nsm", + linebreak="sa", + unicodeslot=0x17C9, + }, + [0x17CA]={ + category="mn", + description="KHMER SIGN TRIISAP", + direction="nsm", + linebreak="sa", + unicodeslot=0x17CA, + }, + [0x17CB]={ + category="mn", + description="KHMER SIGN BANTOC", + direction="nsm", + linebreak="sa", + unicodeslot=0x17CB, + }, + [0x17CC]={ + category="mn", + description="KHMER SIGN ROBAT", + direction="nsm", + linebreak="sa", + unicodeslot=0x17CC, + }, + [0x17CD]={ + category="mn", + description="KHMER SIGN TOANDAKHIAT", + direction="nsm", + linebreak="sa", + unicodeslot=0x17CD, + }, + [0x17CE]={ + category="mn", + description="KHMER SIGN KAKABAT", + direction="nsm", + linebreak="sa", + unicodeslot=0x17CE, + }, + [0x17CF]={ + category="mn", + description="KHMER SIGN AHSDA", + direction="nsm", + linebreak="sa", + unicodeslot=0x17CF, + }, + [0x17D0]={ + category="mn", + description="KHMER SIGN SAMYOK SANNYA", + direction="nsm", + linebreak="sa", + unicodeslot=0x17D0, + }, + [0x17D1]={ + category="mn", + description="KHMER SIGN VIRIAM", + direction="nsm", + linebreak="sa", + unicodeslot=0x17D1, + }, + [0x17D2]={ + category="mn", + description="KHMER SIGN COENG", + direction="nsm", + linebreak="sa", + unicodeslot=0x17D2, + }, + [0x17D3]={ + category="mn", + description="KHMER SIGN BATHAMASAT", + direction="nsm", + linebreak="sa", + unicodeslot=0x17D3, + }, + [0x17D4]={ + category="po", + description="KHMER SIGN KHAN", + direction="l", + linebreak="ba", + unicodeslot=0x17D4, + }, + [0x17D5]={ + category="po", + description="KHMER SIGN BARIYOOSAN", + direction="l", + linebreak="ba", + unicodeslot=0x17D5, + }, + [0x17D6]={ + category="po", + description="KHMER SIGN CAMNUC PII KUUH", + direction="l", + linebreak="ns", + unicodeslot=0x17D6, + }, + [0x17D7]={ + category="lm", + description="KHMER SIGN LEK TOO", + direction="l", + linebreak="sa", + unicodeslot=0x17D7, + }, + [0x17D8]={ + category="po", + description="KHMER SIGN BEYYAL", + direction="l", + linebreak="ba", + unicodeslot=0x17D8, + }, + [0x17D9]={ + category="po", + description="KHMER SIGN PHNAEK MUAN", + direction="l", + linebreak="al", + unicodeslot=0x17D9, + }, + [0x17DA]={ + category="po", + description="KHMER SIGN KOOMUUT", + direction="l", + linebreak="ba", + unicodeslot=0x17DA, + }, + [0x17DB]={ + category="sc", + description="KHMER CURRENCY SYMBOL RIEL", + direction="et", + linebreak="pr", + unicodeslot=0x17DB, + }, + [0x17DC]={ + category="lo", + description="KHMER SIGN AVAKRAHASANYA", + direction="l", + linebreak="sa", + unicodeslot=0x17DC, + }, + [0x17DD]={ + category="mn", + description="KHMER SIGN ATTHACAN", + direction="nsm", + linebreak="sa", + unicodeslot=0x17DD, + }, + [0x17E0]={ + category="nd", + description="KHMER DIGIT ZERO", + direction="l", + linebreak="nu", + unicodeslot=0x17E0, + }, + [0x17E1]={ + category="nd", + description="KHMER DIGIT ONE", + direction="l", + linebreak="nu", + unicodeslot=0x17E1, + }, + [0x17E2]={ + category="nd", + description="KHMER DIGIT TWO", + direction="l", + linebreak="nu", + unicodeslot=0x17E2, + }, + [0x17E3]={ + category="nd", + description="KHMER DIGIT THREE", + direction="l", + linebreak="nu", + unicodeslot=0x17E3, + }, + [0x17E4]={ + category="nd", + description="KHMER DIGIT FOUR", + direction="l", + linebreak="nu", + unicodeslot=0x17E4, + }, + [0x17E5]={ + category="nd", + description="KHMER DIGIT FIVE", + direction="l", + linebreak="nu", + unicodeslot=0x17E5, + }, + [0x17E6]={ + category="nd", + description="KHMER DIGIT SIX", + direction="l", + linebreak="nu", + unicodeslot=0x17E6, + }, + [0x17E7]={ + category="nd", + description="KHMER DIGIT SEVEN", + direction="l", + linebreak="nu", + unicodeslot=0x17E7, + }, + [0x17E8]={ + category="nd", + description="KHMER DIGIT EIGHT", + direction="l", + linebreak="nu", + unicodeslot=0x17E8, + }, + [0x17E9]={ + category="nd", + description="KHMER DIGIT NINE", + direction="l", + linebreak="nu", + unicodeslot=0x17E9, + }, + [0x17F0]={ + category="no", + description="KHMER SYMBOL LEK ATTAK SON", + direction="on", + linebreak="al", + unicodeslot=0x17F0, + }, + [0x17F1]={ + category="no", + description="KHMER SYMBOL LEK ATTAK MUOY", + direction="on", + linebreak="al", + unicodeslot=0x17F1, + }, + [0x17F2]={ + category="no", + description="KHMER SYMBOL LEK ATTAK PII", + direction="on", + linebreak="al", + unicodeslot=0x17F2, + }, + [0x17F3]={ + category="no", + description="KHMER SYMBOL LEK ATTAK BEI", + direction="on", + linebreak="al", + unicodeslot=0x17F3, + }, + [0x17F4]={ + category="no", + description="KHMER SYMBOL LEK ATTAK BUON", + direction="on", + linebreak="al", + unicodeslot=0x17F4, + }, + [0x17F5]={ + category="no", + description="KHMER SYMBOL LEK ATTAK PRAM", + direction="on", + linebreak="al", + unicodeslot=0x17F5, + }, + [0x17F6]={ + category="no", + description="KHMER SYMBOL LEK ATTAK PRAM-MUOY", + direction="on", + linebreak="al", + unicodeslot=0x17F6, + }, + [0x17F7]={ + category="no", + description="KHMER SYMBOL LEK ATTAK PRAM-PII", + direction="on", + linebreak="al", + unicodeslot=0x17F7, + }, + [0x17F8]={ + category="no", + description="KHMER SYMBOL LEK ATTAK PRAM-BEI", + direction="on", + linebreak="al", + unicodeslot=0x17F8, + }, + [0x17F9]={ + category="no", + description="KHMER SYMBOL LEK ATTAK PRAM-BUON", + direction="on", + linebreak="al", + unicodeslot=0x17F9, + }, + [0x1800]={ + category="po", + description="MONGOLIAN BIRGA", + direction="on", + linebreak="al", + unicodeslot=0x1800, + }, + [0x1801]={ + category="po", + description="MONGOLIAN ELLIPSIS", + direction="on", + linebreak="al", + unicodeslot=0x1801, + }, + [0x1802]={ + category="po", + description="MONGOLIAN COMMA", + direction="on", + linebreak="ba", + unicodeslot=0x1802, + }, + [0x1803]={ + category="po", + description="MONGOLIAN FULL STOP", + direction="on", + linebreak="ba", + unicodeslot=0x1803, + }, + [0x1804]={ + category="po", + description="MONGOLIAN COLON", + direction="on", + linebreak="ba", + unicodeslot=0x1804, + }, + [0x1805]={ + category="po", + description="MONGOLIAN FOUR DOTS", + direction="on", + linebreak="ba", + unicodeslot=0x1805, + }, + [0x1806]={ + category="pd", + description="MONGOLIAN TODO SOFT HYPHEN", + direction="on", + linebreak="bb", + unicodeslot=0x1806, + }, + [0x1807]={ + category="po", + description="MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER", + direction="on", + linebreak="al", + unicodeslot=0x1807, + }, + [0x1808]={ + category="po", + description="MONGOLIAN MANCHU COMMA", + direction="on", + linebreak="ba", + unicodeslot=0x1808, + }, + [0x1809]={ + category="po", + description="MONGOLIAN MANCHU FULL STOP", + direction="on", + linebreak="ba", + unicodeslot=0x1809, + }, + [0x180A]={ + category="po", + description="MONGOLIAN NIRUGU", + direction="on", + linebreak="al", + unicodeslot=0x180A, + }, + [0x180B]={ + category="mn", + description="MONGOLIAN FREE VARIATION SELECTOR ONE", + direction="nsm", + linebreak="cm", + unicodeslot=0x180B, + }, + [0x180C]={ + category="mn", + description="MONGOLIAN FREE VARIATION SELECTOR TWO", + direction="nsm", + linebreak="cm", + unicodeslot=0x180C, + }, + [0x180D]={ + category="mn", + description="MONGOLIAN FREE VARIATION SELECTOR THREE", + direction="nsm", + linebreak="cm", + unicodeslot=0x180D, + }, + [0x180E]={ + category="zs", + description="MONGOLIAN VOWEL SEPARATOR", + direction="ws", + linebreak="gl", + unicodeslot=0x180E, + }, + [0x1810]={ + category="nd", + description="MONGOLIAN DIGIT ZERO", + direction="l", + linebreak="nu", + unicodeslot=0x1810, + }, + [0x1811]={ + category="nd", + description="MONGOLIAN DIGIT ONE", + direction="l", + linebreak="nu", + unicodeslot=0x1811, + }, + [0x1812]={ + category="nd", + description="MONGOLIAN DIGIT TWO", + direction="l", + linebreak="nu", + unicodeslot=0x1812, + }, + [0x1813]={ + category="nd", + description="MONGOLIAN DIGIT THREE", + direction="l", + linebreak="nu", + unicodeslot=0x1813, + }, + [0x1814]={ + category="nd", + description="MONGOLIAN DIGIT FOUR", + direction="l", + linebreak="nu", + unicodeslot=0x1814, + }, + [0x1815]={ + category="nd", + description="MONGOLIAN DIGIT FIVE", + direction="l", + linebreak="nu", + unicodeslot=0x1815, + }, + [0x1816]={ + category="nd", + description="MONGOLIAN DIGIT SIX", + direction="l", + linebreak="nu", + unicodeslot=0x1816, + }, + [0x1817]={ + category="nd", + description="MONGOLIAN DIGIT SEVEN", + direction="l", + linebreak="nu", + unicodeslot=0x1817, + }, + [0x1818]={ + category="nd", + description="MONGOLIAN DIGIT EIGHT", + direction="l", + linebreak="nu", + unicodeslot=0x1818, + }, + [0x1819]={ + category="nd", + description="MONGOLIAN DIGIT NINE", + direction="l", + linebreak="nu", + unicodeslot=0x1819, + }, + [0x1820]={ + category="lo", + description="MONGOLIAN LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x1820, + }, + [0x1821]={ + category="lo", + description="MONGOLIAN LETTER E", + direction="l", + linebreak="al", + unicodeslot=0x1821, + }, + [0x1822]={ + category="lo", + description="MONGOLIAN LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x1822, + }, + [0x1823]={ + category="lo", + description="MONGOLIAN LETTER O", + direction="l", + linebreak="al", + unicodeslot=0x1823, + }, + [0x1824]={ + category="lo", + description="MONGOLIAN LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x1824, + }, + [0x1825]={ + category="lo", + description="MONGOLIAN LETTER OE", + direction="l", + linebreak="al", + unicodeslot=0x1825, + }, + [0x1826]={ + category="lo", + description="MONGOLIAN LETTER UE", + direction="l", + linebreak="al", + unicodeslot=0x1826, + }, + [0x1827]={ + category="lo", + description="MONGOLIAN LETTER EE", + direction="l", + linebreak="al", + unicodeslot=0x1827, + }, + [0x1828]={ + category="lo", + description="MONGOLIAN LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x1828, + }, + [0x1829]={ + category="lo", + description="MONGOLIAN LETTER ANG", + direction="l", + linebreak="al", + unicodeslot=0x1829, + }, + [0x182A]={ + category="lo", + description="MONGOLIAN LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x182A, + }, + [0x182B]={ + category="lo", + description="MONGOLIAN LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x182B, + }, + [0x182C]={ + category="lo", + description="MONGOLIAN LETTER QA", + direction="l", + linebreak="al", + unicodeslot=0x182C, + }, + [0x182D]={ + category="lo", + description="MONGOLIAN LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x182D, + }, + [0x182E]={ + category="lo", + description="MONGOLIAN LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x182E, + }, + [0x182F]={ + category="lo", + description="MONGOLIAN LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x182F, + }, + [0x1830]={ + category="lo", + description="MONGOLIAN LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x1830, + }, + [0x1831]={ + category="lo", + description="MONGOLIAN LETTER SHA", + direction="l", + linebreak="al", + unicodeslot=0x1831, + }, + [0x1832]={ + category="lo", + description="MONGOLIAN LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x1832, + }, + [0x1833]={ + category="lo", + description="MONGOLIAN LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x1833, + }, + [0x1834]={ + category="lo", + description="MONGOLIAN LETTER CHA", + direction="l", + linebreak="al", + unicodeslot=0x1834, + }, + [0x1835]={ + category="lo", + description="MONGOLIAN LETTER JA", + direction="l", + linebreak="al", + unicodeslot=0x1835, + }, + [0x1836]={ + category="lo", + description="MONGOLIAN LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x1836, + }, + [0x1837]={ + category="lo", + description="MONGOLIAN LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0x1837, + }, + [0x1838]={ + category="lo", + description="MONGOLIAN LETTER WA", + direction="l", + linebreak="al", + unicodeslot=0x1838, + }, + [0x1839]={ + category="lo", + description="MONGOLIAN LETTER FA", + direction="l", + linebreak="al", + unicodeslot=0x1839, + }, + [0x183A]={ + category="lo", + description="MONGOLIAN LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x183A, + }, + [0x183B]={ + category="lo", + description="MONGOLIAN LETTER KHA", + direction="l", + linebreak="al", + unicodeslot=0x183B, + }, + [0x183C]={ + category="lo", + description="MONGOLIAN LETTER TSA", + direction="l", + linebreak="al", + unicodeslot=0x183C, + }, + [0x183D]={ + category="lo", + description="MONGOLIAN LETTER ZA", + direction="l", + linebreak="al", + unicodeslot=0x183D, + }, + [0x183E]={ + category="lo", + description="MONGOLIAN LETTER HAA", + direction="l", + linebreak="al", + unicodeslot=0x183E, + }, + [0x183F]={ + category="lo", + description="MONGOLIAN LETTER ZRA", + direction="l", + linebreak="al", + unicodeslot=0x183F, + }, + [0x1840]={ + category="lo", + description="MONGOLIAN LETTER LHA", + direction="l", + linebreak="al", + unicodeslot=0x1840, + }, + [0x1841]={ + category="lo", + description="MONGOLIAN LETTER ZHI", + direction="l", + linebreak="al", + unicodeslot=0x1841, + }, + [0x1842]={ + category="lo", + description="MONGOLIAN LETTER CHI", + direction="l", + linebreak="al", + unicodeslot=0x1842, + }, + [0x1843]={ + category="lm", + description="MONGOLIAN LETTER TODO LONG VOWEL SIGN", + direction="l", + linebreak="al", + unicodeslot=0x1843, + }, + [0x1844]={ + category="lo", + description="MONGOLIAN LETTER TODO E", + direction="l", + linebreak="al", + unicodeslot=0x1844, + }, + [0x1845]={ + category="lo", + description="MONGOLIAN LETTER TODO I", + direction="l", + linebreak="al", + unicodeslot=0x1845, + }, + [0x1846]={ + category="lo", + description="MONGOLIAN LETTER TODO O", + direction="l", + linebreak="al", + unicodeslot=0x1846, + }, + [0x1847]={ + category="lo", + description="MONGOLIAN LETTER TODO U", + direction="l", + linebreak="al", + unicodeslot=0x1847, + }, + [0x1848]={ + category="lo", + description="MONGOLIAN LETTER TODO OE", + direction="l", + linebreak="al", + unicodeslot=0x1848, + }, + [0x1849]={ + category="lo", + description="MONGOLIAN LETTER TODO UE", + direction="l", + linebreak="al", + unicodeslot=0x1849, + }, + [0x184A]={ + category="lo", + description="MONGOLIAN LETTER TODO ANG", + direction="l", + linebreak="al", + unicodeslot=0x184A, + }, + [0x184B]={ + category="lo", + description="MONGOLIAN LETTER TODO BA", + direction="l", + linebreak="al", + unicodeslot=0x184B, + }, + [0x184C]={ + category="lo", + description="MONGOLIAN LETTER TODO PA", + direction="l", + linebreak="al", + unicodeslot=0x184C, + }, + [0x184D]={ + category="lo", + description="MONGOLIAN LETTER TODO QA", + direction="l", + linebreak="al", + unicodeslot=0x184D, + }, + [0x184E]={ + category="lo", + description="MONGOLIAN LETTER TODO GA", + direction="l", + linebreak="al", + unicodeslot=0x184E, + }, + [0x184F]={ + category="lo", + description="MONGOLIAN LETTER TODO MA", + direction="l", + linebreak="al", + unicodeslot=0x184F, + }, + [0x1850]={ + category="lo", + description="MONGOLIAN LETTER TODO TA", + direction="l", + linebreak="al", + unicodeslot=0x1850, + }, + [0x1851]={ + category="lo", + description="MONGOLIAN LETTER TODO DA", + direction="l", + linebreak="al", + unicodeslot=0x1851, + }, + [0x1852]={ + category="lo", + description="MONGOLIAN LETTER TODO CHA", + direction="l", + linebreak="al", + unicodeslot=0x1852, + }, + [0x1853]={ + category="lo", + description="MONGOLIAN LETTER TODO JA", + direction="l", + linebreak="al", + unicodeslot=0x1853, + }, + [0x1854]={ + category="lo", + description="MONGOLIAN LETTER TODO TSA", + direction="l", + linebreak="al", + unicodeslot=0x1854, + }, + [0x1855]={ + category="lo", + description="MONGOLIAN LETTER TODO YA", + direction="l", + linebreak="al", + unicodeslot=0x1855, + }, + [0x1856]={ + category="lo", + description="MONGOLIAN LETTER TODO WA", + direction="l", + linebreak="al", + unicodeslot=0x1856, + }, + [0x1857]={ + category="lo", + description="MONGOLIAN LETTER TODO KA", + direction="l", + linebreak="al", + unicodeslot=0x1857, + }, + [0x1858]={ + category="lo", + description="MONGOLIAN LETTER TODO GAA", + direction="l", + linebreak="al", + unicodeslot=0x1858, + }, + [0x1859]={ + category="lo", + description="MONGOLIAN LETTER TODO HAA", + direction="l", + linebreak="al", + unicodeslot=0x1859, + }, + [0x185A]={ + category="lo", + description="MONGOLIAN LETTER TODO JIA", + direction="l", + linebreak="al", + unicodeslot=0x185A, + }, + [0x185B]={ + category="lo", + description="MONGOLIAN LETTER TODO NIA", + direction="l", + linebreak="al", + unicodeslot=0x185B, + }, + [0x185C]={ + category="lo", + description="MONGOLIAN LETTER TODO DZA", + direction="l", + linebreak="al", + unicodeslot=0x185C, + }, + [0x185D]={ + category="lo", + description="MONGOLIAN LETTER SIBE E", + direction="l", + linebreak="al", + unicodeslot=0x185D, + }, + [0x185E]={ + category="lo", + description="MONGOLIAN LETTER SIBE I", + direction="l", + linebreak="al", + unicodeslot=0x185E, + }, + [0x185F]={ + category="lo", + description="MONGOLIAN LETTER SIBE IY", + direction="l", + linebreak="al", + unicodeslot=0x185F, + }, + [0x1860]={ + category="lo", + description="MONGOLIAN LETTER SIBE UE", + direction="l", + linebreak="al", + unicodeslot=0x1860, + }, + [0x1861]={ + category="lo", + description="MONGOLIAN LETTER SIBE U", + direction="l", + linebreak="al", + unicodeslot=0x1861, + }, + [0x1862]={ + category="lo", + description="MONGOLIAN LETTER SIBE ANG", + direction="l", + linebreak="al", + unicodeslot=0x1862, + }, + [0x1863]={ + category="lo", + description="MONGOLIAN LETTER SIBE KA", + direction="l", + linebreak="al", + unicodeslot=0x1863, + }, + [0x1864]={ + category="lo", + description="MONGOLIAN LETTER SIBE GA", + direction="l", + linebreak="al", + unicodeslot=0x1864, + }, + [0x1865]={ + category="lo", + description="MONGOLIAN LETTER SIBE HA", + direction="l", + linebreak="al", + unicodeslot=0x1865, + }, + [0x1866]={ + category="lo", + description="MONGOLIAN LETTER SIBE PA", + direction="l", + linebreak="al", + unicodeslot=0x1866, + }, + [0x1867]={ + category="lo", + description="MONGOLIAN LETTER SIBE SHA", + direction="l", + linebreak="al", + unicodeslot=0x1867, + }, + [0x1868]={ + category="lo", + description="MONGOLIAN LETTER SIBE TA", + direction="l", + linebreak="al", + unicodeslot=0x1868, + }, + [0x1869]={ + category="lo", + description="MONGOLIAN LETTER SIBE DA", + direction="l", + linebreak="al", + unicodeslot=0x1869, + }, + [0x186A]={ + category="lo", + description="MONGOLIAN LETTER SIBE JA", + direction="l", + linebreak="al", + unicodeslot=0x186A, + }, + [0x186B]={ + category="lo", + description="MONGOLIAN LETTER SIBE FA", + direction="l", + linebreak="al", + unicodeslot=0x186B, + }, + [0x186C]={ + category="lo", + description="MONGOLIAN LETTER SIBE GAA", + direction="l", + linebreak="al", + unicodeslot=0x186C, + }, + [0x186D]={ + category="lo", + description="MONGOLIAN LETTER SIBE HAA", + direction="l", + linebreak="al", + unicodeslot=0x186D, + }, + [0x186E]={ + category="lo", + description="MONGOLIAN LETTER SIBE TSA", + direction="l", + linebreak="al", + unicodeslot=0x186E, + }, + [0x186F]={ + category="lo", + description="MONGOLIAN LETTER SIBE ZA", + direction="l", + linebreak="al", + unicodeslot=0x186F, + }, + [0x1870]={ + category="lo", + description="MONGOLIAN LETTER SIBE RAA", + direction="l", + linebreak="al", + unicodeslot=0x1870, + }, + [0x1871]={ + category="lo", + description="MONGOLIAN LETTER SIBE CHA", + direction="l", + linebreak="al", + unicodeslot=0x1871, + }, + [0x1872]={ + category="lo", + description="MONGOLIAN LETTER SIBE ZHA", + direction="l", + linebreak="al", + unicodeslot=0x1872, + }, + [0x1873]={ + category="lo", + description="MONGOLIAN LETTER MANCHU I", + direction="l", + linebreak="al", + unicodeslot=0x1873, + }, + [0x1874]={ + category="lo", + description="MONGOLIAN LETTER MANCHU KA", + direction="l", + linebreak="al", + unicodeslot=0x1874, + }, + [0x1875]={ + category="lo", + description="MONGOLIAN LETTER MANCHU RA", + direction="l", + linebreak="al", + unicodeslot=0x1875, + }, + [0x1876]={ + category="lo", + description="MONGOLIAN LETTER MANCHU FA", + direction="l", + linebreak="al", + unicodeslot=0x1876, + }, + [0x1877]={ + category="lo", + description="MONGOLIAN LETTER MANCHU ZHA", + direction="l", + linebreak="al", + unicodeslot=0x1877, + }, + [0x1880]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI ANUSVARA ONE", + direction="l", + linebreak="al", + unicodeslot=0x1880, + }, + [0x1881]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI VISARGA ONE", + direction="l", + linebreak="al", + unicodeslot=0x1881, + }, + [0x1882]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI DAMARU", + direction="l", + linebreak="al", + unicodeslot=0x1882, + }, + [0x1883]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI UBADAMA", + direction="l", + linebreak="al", + unicodeslot=0x1883, + }, + [0x1884]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI INVERTED UBADAMA", + direction="l", + linebreak="al", + unicodeslot=0x1884, + }, + [0x1885]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI BALUDA", + direction="l", + linebreak="al", + unicodeslot=0x1885, + }, + [0x1886]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI THREE BALUDA", + direction="l", + linebreak="al", + unicodeslot=0x1886, + }, + [0x1887]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI A", + direction="l", + linebreak="al", + unicodeslot=0x1887, + }, + [0x1888]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI I", + direction="l", + linebreak="al", + unicodeslot=0x1888, + }, + [0x1889]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI KA", + direction="l", + linebreak="al", + unicodeslot=0x1889, + }, + [0x188A]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI NGA", + direction="l", + linebreak="al", + unicodeslot=0x188A, + }, + [0x188B]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI CA", + direction="l", + linebreak="al", + unicodeslot=0x188B, + }, + [0x188C]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI TTA", + direction="l", + linebreak="al", + unicodeslot=0x188C, + }, + [0x188D]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI TTHA", + direction="l", + linebreak="al", + unicodeslot=0x188D, + }, + [0x188E]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI DDA", + direction="l", + linebreak="al", + unicodeslot=0x188E, + }, + [0x188F]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI NNA", + direction="l", + linebreak="al", + unicodeslot=0x188F, + }, + [0x1890]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI TA", + direction="l", + linebreak="al", + unicodeslot=0x1890, + }, + [0x1891]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI DA", + direction="l", + linebreak="al", + unicodeslot=0x1891, + }, + [0x1892]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI PA", + direction="l", + linebreak="al", + unicodeslot=0x1892, + }, + [0x1893]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI PHA", + direction="l", + linebreak="al", + unicodeslot=0x1893, + }, + [0x1894]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI SSA", + direction="l", + linebreak="al", + unicodeslot=0x1894, + }, + [0x1895]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI ZHA", + direction="l", + linebreak="al", + unicodeslot=0x1895, + }, + [0x1896]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI ZA", + direction="l", + linebreak="al", + unicodeslot=0x1896, + }, + [0x1897]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI AH", + direction="l", + linebreak="al", + unicodeslot=0x1897, + }, + [0x1898]={ + category="lo", + description="MONGOLIAN LETTER TODO ALI GALI TA", + direction="l", + linebreak="al", + unicodeslot=0x1898, + }, + [0x1899]={ + category="lo", + description="MONGOLIAN LETTER TODO ALI GALI ZHA", + direction="l", + linebreak="al", + unicodeslot=0x1899, + }, + [0x189A]={ + category="lo", + description="MONGOLIAN LETTER MANCHU ALI GALI GHA", + direction="l", + linebreak="al", + unicodeslot=0x189A, + }, + [0x189B]={ + category="lo", + description="MONGOLIAN LETTER MANCHU ALI GALI NGA", + direction="l", + linebreak="al", + unicodeslot=0x189B, + }, + [0x189C]={ + category="lo", + description="MONGOLIAN LETTER MANCHU ALI GALI CA", + direction="l", + linebreak="al", + unicodeslot=0x189C, + }, + [0x189D]={ + category="lo", + description="MONGOLIAN LETTER MANCHU ALI GALI JHA", + direction="l", + linebreak="al", + unicodeslot=0x189D, + }, + [0x189E]={ + category="lo", + description="MONGOLIAN LETTER MANCHU ALI GALI TTA", + direction="l", + linebreak="al", + unicodeslot=0x189E, + }, + [0x189F]={ + category="lo", + description="MONGOLIAN LETTER MANCHU ALI GALI DDHA", + direction="l", + linebreak="al", + unicodeslot=0x189F, + }, + [0x18A0]={ + category="lo", + description="MONGOLIAN LETTER MANCHU ALI GALI TA", + direction="l", + linebreak="al", + unicodeslot=0x18A0, + }, + [0x18A1]={ + category="lo", + description="MONGOLIAN LETTER MANCHU ALI GALI DHA", + direction="l", + linebreak="al", + unicodeslot=0x18A1, + }, + [0x18A2]={ + category="lo", + description="MONGOLIAN LETTER MANCHU ALI GALI SSA", + direction="l", + linebreak="al", + unicodeslot=0x18A2, + }, + [0x18A3]={ + category="lo", + description="MONGOLIAN LETTER MANCHU ALI GALI CYA", + direction="l", + linebreak="al", + unicodeslot=0x18A3, + }, + [0x18A4]={ + category="lo", + description="MONGOLIAN LETTER MANCHU ALI GALI ZHA", + direction="l", + linebreak="al", + unicodeslot=0x18A4, + }, + [0x18A5]={ + category="lo", + description="MONGOLIAN LETTER MANCHU ALI GALI ZA", + direction="l", + linebreak="al", + unicodeslot=0x18A5, + }, + [0x18A6]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI HALF U", + direction="l", + linebreak="al", + unicodeslot=0x18A6, + }, + [0x18A7]={ + category="lo", + description="MONGOLIAN LETTER ALI GALI HALF YA", + direction="l", + linebreak="al", + unicodeslot=0x18A7, + }, + [0x18A8]={ + category="lo", + description="MONGOLIAN LETTER MANCHU ALI GALI BHA", + direction="l", + linebreak="al", + unicodeslot=0x18A8, + }, + [0x18A9]={ + category="mn", + description="MONGOLIAN LETTER ALI GALI DAGALGA", + direction="nsm", + linebreak="cm", + unicodeslot=0x18A9, + }, + [0x1900]={ + category="lo", + description="LIMBU VOWEL-CARRIER LETTER", + direction="l", + linebreak="al", + unicodeslot=0x1900, + }, + [0x1901]={ + category="lo", + description="LIMBU LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x1901, + }, + [0x1902]={ + category="lo", + description="LIMBU LETTER KHA", + direction="l", + linebreak="al", + unicodeslot=0x1902, + }, + [0x1903]={ + category="lo", + description="LIMBU LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x1903, + }, + [0x1904]={ + category="lo", + description="LIMBU LETTER GHA", + direction="l", + linebreak="al", + unicodeslot=0x1904, + }, + [0x1905]={ + category="lo", + description="LIMBU LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0x1905, + }, + [0x1906]={ + category="lo", + description="LIMBU LETTER CA", + direction="l", + linebreak="al", + unicodeslot=0x1906, + }, + [0x1907]={ + category="lo", + description="LIMBU LETTER CHA", + direction="l", + linebreak="al", + unicodeslot=0x1907, + }, + [0x1908]={ + category="lo", + description="LIMBU LETTER JA", + direction="l", + linebreak="al", + unicodeslot=0x1908, + }, + [0x1909]={ + category="lo", + description="LIMBU LETTER JHA", + direction="l", + linebreak="al", + unicodeslot=0x1909, + }, + [0x190A]={ + category="lo", + description="LIMBU LETTER YAN", + direction="l", + linebreak="al", + unicodeslot=0x190A, + }, + [0x190B]={ + category="lo", + description="LIMBU LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x190B, + }, + [0x190C]={ + category="lo", + description="LIMBU LETTER THA", + direction="l", + linebreak="al", + unicodeslot=0x190C, + }, + [0x190D]={ + category="lo", + description="LIMBU LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x190D, + }, + [0x190E]={ + category="lo", + description="LIMBU LETTER DHA", + direction="l", + linebreak="al", + unicodeslot=0x190E, + }, + [0x190F]={ + category="lo", + description="LIMBU LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x190F, + }, + [0x1910]={ + category="lo", + description="LIMBU LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x1910, + }, + [0x1911]={ + category="lo", + description="LIMBU LETTER PHA", + direction="l", + linebreak="al", + unicodeslot=0x1911, + }, + [0x1912]={ + category="lo", + description="LIMBU LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x1912, + }, + [0x1913]={ + category="lo", + description="LIMBU LETTER BHA", + direction="l", + linebreak="al", + unicodeslot=0x1913, + }, + [0x1914]={ + category="lo", + description="LIMBU LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x1914, + }, + [0x1915]={ + category="lo", + description="LIMBU LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x1915, + }, + [0x1916]={ + category="lo", + description="LIMBU LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0x1916, + }, + [0x1917]={ + category="lo", + description="LIMBU LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x1917, + }, + [0x1918]={ + category="lo", + description="LIMBU LETTER WA", + direction="l", + linebreak="al", + unicodeslot=0x1918, + }, + [0x1919]={ + category="lo", + description="LIMBU LETTER SHA", + direction="l", + linebreak="al", + unicodeslot=0x1919, + }, + [0x191A]={ + category="lo", + description="LIMBU LETTER SSA", + direction="l", + linebreak="al", + unicodeslot=0x191A, + }, + [0x191B]={ + category="lo", + description="LIMBU LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x191B, + }, + [0x191C]={ + category="lo", + description="LIMBU LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x191C, + }, + [0x1920]={ + category="mn", + description="LIMBU VOWEL SIGN A", + direction="nsm", + linebreak="cm", + unicodeslot=0x1920, + }, + [0x1921]={ + category="mn", + description="LIMBU VOWEL SIGN I", + direction="nsm", + linebreak="cm", + unicodeslot=0x1921, + }, + [0x1922]={ + category="mn", + description="LIMBU VOWEL SIGN U", + direction="nsm", + linebreak="cm", + unicodeslot=0x1922, + }, + [0x1923]={ + category="mc", + description="LIMBU VOWEL SIGN EE", + direction="l", + linebreak="cm", + unicodeslot=0x1923, + }, + [0x1924]={ + category="mc", + description="LIMBU VOWEL SIGN AI", + direction="l", + linebreak="cm", + unicodeslot=0x1924, + }, + [0x1925]={ + category="mc", + description="LIMBU VOWEL SIGN OO", + direction="l", + linebreak="cm", + unicodeslot=0x1925, + }, + [0x1926]={ + category="mc", + description="LIMBU VOWEL SIGN AU", + direction="l", + linebreak="cm", + unicodeslot=0x1926, + }, + [0x1927]={ + category="mn", + description="LIMBU VOWEL SIGN E", + direction="nsm", + linebreak="cm", + unicodeslot=0x1927, + }, + [0x1928]={ + category="mn", + description="LIMBU VOWEL SIGN O", + direction="nsm", + linebreak="cm", + unicodeslot=0x1928, + }, + [0x1929]={ + category="mc", + description="LIMBU SUBJOINED LETTER YA", + direction="l", + linebreak="cm", + unicodeslot=0x1929, + }, + [0x192A]={ + category="mc", + description="LIMBU SUBJOINED LETTER RA", + direction="l", + linebreak="cm", + unicodeslot=0x192A, + }, + [0x192B]={ + category="mc", + description="LIMBU SUBJOINED LETTER WA", + direction="l", + linebreak="cm", + unicodeslot=0x192B, + }, + [0x1930]={ + category="mc", + description="LIMBU SMALL LETTER KA", + direction="l", + linebreak="cm", + unicodeslot=0x1930, + }, + [0x1931]={ + category="mc", + description="LIMBU SMALL LETTER NGA", + direction="l", + linebreak="cm", + unicodeslot=0x1931, + }, + [0x1932]={ + category="mn", + description="LIMBU SMALL LETTER ANUSVARA", + direction="nsm", + linebreak="cm", + unicodeslot=0x1932, + }, + [0x1933]={ + category="mc", + description="LIMBU SMALL LETTER TA", + direction="l", + linebreak="cm", + unicodeslot=0x1933, + }, + [0x1934]={ + category="mc", + description="LIMBU SMALL LETTER NA", + direction="l", + linebreak="cm", + unicodeslot=0x1934, + }, + [0x1935]={ + category="mc", + description="LIMBU SMALL LETTER PA", + direction="l", + linebreak="cm", + unicodeslot=0x1935, + }, + [0x1936]={ + category="mc", + description="LIMBU SMALL LETTER MA", + direction="l", + linebreak="cm", + unicodeslot=0x1936, + }, + [0x1937]={ + category="mc", + description="LIMBU SMALL LETTER RA", + direction="l", + linebreak="cm", + unicodeslot=0x1937, + }, + [0x1938]={ + category="mc", + description="LIMBU SMALL LETTER LA", + direction="l", + linebreak="cm", + unicodeslot=0x1938, + }, + [0x1939]={ + category="mn", + description="LIMBU SIGN MUKPHRENG", + direction="nsm", + linebreak="cm", + unicodeslot=0x1939, + }, + [0x193A]={ + category="mn", + description="LIMBU SIGN KEMPHRENG", + direction="nsm", + linebreak="cm", + unicodeslot=0x193A, + }, + [0x193B]={ + category="mn", + description="LIMBU SIGN SA-I", + direction="nsm", + linebreak="cm", + unicodeslot=0x193B, + }, + [0x1940]={ + category="so", + description="LIMBU SIGN LOO", + direction="on", + linebreak="al", + unicodeslot=0x1940, + }, + [0x1944]={ + category="po", + description="LIMBU EXCLAMATION MARK", + direction="on", + linebreak="ex", + unicodeslot=0x1944, + }, + [0x1945]={ + category="po", + description="LIMBU QUESTION MARK", + direction="on", + linebreak="ex", + unicodeslot=0x1945, + }, + [0x1946]={ + category="nd", + description="LIMBU DIGIT ZERO", + direction="l", + linebreak="nu", + unicodeslot=0x1946, + }, + [0x1947]={ + category="nd", + description="LIMBU DIGIT ONE", + direction="l", + linebreak="nu", + unicodeslot=0x1947, + }, + [0x1948]={ + category="nd", + description="LIMBU DIGIT TWO", + direction="l", + linebreak="nu", + unicodeslot=0x1948, + }, + [0x1949]={ + category="nd", + description="LIMBU DIGIT THREE", + direction="l", + linebreak="nu", + unicodeslot=0x1949, + }, + [0x194A]={ + category="nd", + description="LIMBU DIGIT FOUR", + direction="l", + linebreak="nu", + unicodeslot=0x194A, + }, + [0x194B]={ + category="nd", + description="LIMBU DIGIT FIVE", + direction="l", + linebreak="nu", + unicodeslot=0x194B, + }, + [0x194C]={ + category="nd", + description="LIMBU DIGIT SIX", + direction="l", + linebreak="nu", + unicodeslot=0x194C, + }, + [0x194D]={ + category="nd", + description="LIMBU DIGIT SEVEN", + direction="l", + linebreak="nu", + unicodeslot=0x194D, + }, + [0x194E]={ + category="nd", + description="LIMBU DIGIT EIGHT", + direction="l", + linebreak="nu", + unicodeslot=0x194E, + }, + [0x194F]={ + category="nd", + description="LIMBU DIGIT NINE", + direction="l", + linebreak="nu", + unicodeslot=0x194F, + }, + [0x1950]={ + category="lo", + description="TAI LE LETTER KA", + direction="l", + linebreak="sa", + unicodeslot=0x1950, + }, + [0x1951]={ + category="lo", + description="TAI LE LETTER XA", + direction="l", + linebreak="sa", + unicodeslot=0x1951, + }, + [0x1952]={ + category="lo", + description="TAI LE LETTER NGA", + direction="l", + linebreak="sa", + unicodeslot=0x1952, + }, + [0x1953]={ + category="lo", + description="TAI LE LETTER TSA", + direction="l", + linebreak="sa", + unicodeslot=0x1953, + }, + [0x1954]={ + category="lo", + description="TAI LE LETTER SA", + direction="l", + linebreak="sa", + unicodeslot=0x1954, + }, + [0x1955]={ + category="lo", + description="TAI LE LETTER YA", + direction="l", + linebreak="sa", + unicodeslot=0x1955, + }, + [0x1956]={ + category="lo", + description="TAI LE LETTER TA", + direction="l", + linebreak="sa", + unicodeslot=0x1956, + }, + [0x1957]={ + category="lo", + description="TAI LE LETTER THA", + direction="l", + linebreak="sa", + unicodeslot=0x1957, + }, + [0x1958]={ + category="lo", + description="TAI LE LETTER LA", + direction="l", + linebreak="sa", + unicodeslot=0x1958, + }, + [0x1959]={ + category="lo", + description="TAI LE LETTER PA", + direction="l", + linebreak="sa", + unicodeslot=0x1959, + }, + [0x195A]={ + category="lo", + description="TAI LE LETTER PHA", + direction="l", + linebreak="sa", + unicodeslot=0x195A, + }, + [0x195B]={ + category="lo", + description="TAI LE LETTER MA", + direction="l", + linebreak="sa", + unicodeslot=0x195B, + }, + [0x195C]={ + category="lo", + description="TAI LE LETTER FA", + direction="l", + linebreak="sa", + unicodeslot=0x195C, + }, + [0x195D]={ + category="lo", + description="TAI LE LETTER VA", + direction="l", + linebreak="sa", + unicodeslot=0x195D, + }, + [0x195E]={ + category="lo", + description="TAI LE LETTER HA", + direction="l", + linebreak="sa", + unicodeslot=0x195E, + }, + [0x195F]={ + category="lo", + description="TAI LE LETTER QA", + direction="l", + linebreak="sa", + unicodeslot=0x195F, + }, + [0x1960]={ + category="lo", + description="TAI LE LETTER KHA", + direction="l", + linebreak="sa", + unicodeslot=0x1960, + }, + [0x1961]={ + category="lo", + description="TAI LE LETTER TSHA", + direction="l", + linebreak="sa", + unicodeslot=0x1961, + }, + [0x1962]={ + category="lo", + description="TAI LE LETTER NA", + direction="l", + linebreak="sa", + unicodeslot=0x1962, + }, + [0x1963]={ + category="lo", + description="TAI LE LETTER A", + direction="l", + linebreak="sa", + unicodeslot=0x1963, + }, + [0x1964]={ + category="lo", + description="TAI LE LETTER I", + direction="l", + linebreak="sa", + unicodeslot=0x1964, + }, + [0x1965]={ + category="lo", + description="TAI LE LETTER EE", + direction="l", + linebreak="sa", + unicodeslot=0x1965, + }, + [0x1966]={ + category="lo", + description="TAI LE LETTER EH", + direction="l", + linebreak="sa", + unicodeslot=0x1966, + }, + [0x1967]={ + category="lo", + description="TAI LE LETTER U", + direction="l", + linebreak="sa", + unicodeslot=0x1967, + }, + [0x1968]={ + category="lo", + description="TAI LE LETTER OO", + direction="l", + linebreak="sa", + unicodeslot=0x1968, + }, + [0x1969]={ + category="lo", + description="TAI LE LETTER O", + direction="l", + linebreak="sa", + unicodeslot=0x1969, + }, + [0x196A]={ + category="lo", + description="TAI LE LETTER UE", + direction="l", + linebreak="sa", + unicodeslot=0x196A, + }, + [0x196B]={ + category="lo", + description="TAI LE LETTER E", + direction="l", + linebreak="sa", + unicodeslot=0x196B, + }, + [0x196C]={ + category="lo", + description="TAI LE LETTER AUE", + direction="l", + linebreak="sa", + unicodeslot=0x196C, + }, + [0x196D]={ + category="lo", + description="TAI LE LETTER AI", + direction="l", + linebreak="sa", + unicodeslot=0x196D, + }, + [0x1970]={ + category="lo", + description="TAI LE LETTER TONE-0x0002", + direction="l", + linebreak="sa", + unicodeslot=0x1970, + }, + [0x1971]={ + category="lo", + description="TAI LE LETTER TONE-0x0003", + direction="l", + linebreak="sa", + unicodeslot=0x1971, + }, + [0x1972]={ + category="lo", + description="TAI LE LETTER TONE-0x0004", + direction="l", + linebreak="sa", + unicodeslot=0x1972, + }, + [0x1973]={ + category="lo", + description="TAI LE LETTER TONE-0x0005", + direction="l", + linebreak="sa", + unicodeslot=0x1973, + }, + [0x1974]={ + category="lo", + description="TAI LE LETTER TONE-0x0006", + direction="l", + linebreak="sa", + unicodeslot=0x1974, + }, + [0x1980]={ + category="lo", + description="NEW TAI LUE LETTER HIGH QA", + direction="l", + linebreak="sa", + unicodeslot=0x1980, + }, + [0x1981]={ + category="lo", + description="NEW TAI LUE LETTER LOW QA", + direction="l", + linebreak="sa", + unicodeslot=0x1981, + }, + [0x1982]={ + category="lo", + description="NEW TAI LUE LETTER HIGH KA", + direction="l", + linebreak="sa", + unicodeslot=0x1982, + }, + [0x1983]={ + category="lo", + description="NEW TAI LUE LETTER HIGH XA", + direction="l", + linebreak="sa", + unicodeslot=0x1983, + }, + [0x1984]={ + category="lo", + description="NEW TAI LUE LETTER HIGH NGA", + direction="l", + linebreak="sa", + unicodeslot=0x1984, + }, + [0x1985]={ + category="lo", + description="NEW TAI LUE LETTER LOW KA", + direction="l", + linebreak="sa", + unicodeslot=0x1985, + }, + [0x1986]={ + category="lo", + description="NEW TAI LUE LETTER LOW XA", + direction="l", + linebreak="sa", + unicodeslot=0x1986, + }, + [0x1987]={ + category="lo", + description="NEW TAI LUE LETTER LOW NGA", + direction="l", + linebreak="sa", + unicodeslot=0x1987, + }, + [0x1988]={ + category="lo", + description="NEW TAI LUE LETTER HIGH TSA", + direction="l", + linebreak="sa", + unicodeslot=0x1988, + }, + [0x1989]={ + category="lo", + description="NEW TAI LUE LETTER HIGH SA", + direction="l", + linebreak="sa", + unicodeslot=0x1989, + }, + [0x198A]={ + category="lo", + description="NEW TAI LUE LETTER HIGH YA", + direction="l", + linebreak="sa", + unicodeslot=0x198A, + }, + [0x198B]={ + category="lo", + description="NEW TAI LUE LETTER LOW TSA", + direction="l", + linebreak="sa", + unicodeslot=0x198B, + }, + [0x198C]={ + category="lo", + description="NEW TAI LUE LETTER LOW SA", + direction="l", + linebreak="sa", + unicodeslot=0x198C, + }, + [0x198D]={ + category="lo", + description="NEW TAI LUE LETTER LOW YA", + direction="l", + linebreak="sa", + unicodeslot=0x198D, + }, + [0x198E]={ + category="lo", + description="NEW TAI LUE LETTER HIGH TA", + direction="l", + linebreak="sa", + unicodeslot=0x198E, + }, + [0x198F]={ + category="lo", + description="NEW TAI LUE LETTER HIGH THA", + direction="l", + linebreak="sa", + unicodeslot=0x198F, + }, + [0x1990]={ + category="lo", + description="NEW TAI LUE LETTER HIGH NA", + direction="l", + linebreak="sa", + unicodeslot=0x1990, + }, + [0x1991]={ + category="lo", + description="NEW TAI LUE LETTER LOW TA", + direction="l", + linebreak="sa", + unicodeslot=0x1991, + }, + [0x1992]={ + category="lo", + description="NEW TAI LUE LETTER LOW THA", + direction="l", + linebreak="sa", + unicodeslot=0x1992, + }, + [0x1993]={ + category="lo", + description="NEW TAI LUE LETTER LOW NA", + direction="l", + linebreak="sa", + unicodeslot=0x1993, + }, + [0x1994]={ + category="lo", + description="NEW TAI LUE LETTER HIGH PA", + direction="l", + linebreak="sa", + unicodeslot=0x1994, + }, + [0x1995]={ + category="lo", + description="NEW TAI LUE LETTER HIGH PHA", + direction="l", + linebreak="sa", + unicodeslot=0x1995, + }, + [0x1996]={ + category="lo", + description="NEW TAI LUE LETTER HIGH MA", + direction="l", + linebreak="sa", + unicodeslot=0x1996, + }, + [0x1997]={ + category="lo", + description="NEW TAI LUE LETTER LOW PA", + direction="l", + linebreak="sa", + unicodeslot=0x1997, + }, + [0x1998]={ + category="lo", + description="NEW TAI LUE LETTER LOW PHA", + direction="l", + linebreak="sa", + unicodeslot=0x1998, + }, + [0x1999]={ + category="lo", + description="NEW TAI LUE LETTER LOW MA", + direction="l", + linebreak="sa", + unicodeslot=0x1999, + }, + [0x199A]={ + category="lo", + description="NEW TAI LUE LETTER HIGH FA", + direction="l", + linebreak="sa", + unicodeslot=0x199A, + }, + [0x199B]={ + category="lo", + description="NEW TAI LUE LETTER HIGH VA", + direction="l", + linebreak="sa", + unicodeslot=0x199B, + }, + [0x199C]={ + category="lo", + description="NEW TAI LUE LETTER HIGH LA", + direction="l", + linebreak="sa", + unicodeslot=0x199C, + }, + [0x199D]={ + category="lo", + description="NEW TAI LUE LETTER LOW FA", + direction="l", + linebreak="sa", + unicodeslot=0x199D, + }, + [0x199E]={ + category="lo", + description="NEW TAI LUE LETTER LOW VA", + direction="l", + linebreak="sa", + unicodeslot=0x199E, + }, + [0x199F]={ + category="lo", + description="NEW TAI LUE LETTER LOW LA", + direction="l", + linebreak="sa", + unicodeslot=0x199F, + }, + [0x19A0]={ + category="lo", + description="NEW TAI LUE LETTER HIGH HA", + direction="l", + linebreak="sa", + unicodeslot=0x19A0, + }, + [0x19A1]={ + category="lo", + description="NEW TAI LUE LETTER HIGH DA", + direction="l", + linebreak="sa", + unicodeslot=0x19A1, + }, + [0x19A2]={ + category="lo", + description="NEW TAI LUE LETTER HIGH BA", + direction="l", + linebreak="sa", + unicodeslot=0x19A2, + }, + [0x19A3]={ + category="lo", + description="NEW TAI LUE LETTER LOW HA", + direction="l", + linebreak="sa", + unicodeslot=0x19A3, + }, + [0x19A4]={ + category="lo", + description="NEW TAI LUE LETTER LOW DA", + direction="l", + linebreak="sa", + unicodeslot=0x19A4, + }, + [0x19A5]={ + category="lo", + description="NEW TAI LUE LETTER LOW BA", + direction="l", + linebreak="sa", + unicodeslot=0x19A5, + }, + [0x19A6]={ + category="lo", + description="NEW TAI LUE LETTER HIGH KVA", + direction="l", + linebreak="sa", + unicodeslot=0x19A6, + }, + [0x19A7]={ + category="lo", + description="NEW TAI LUE LETTER HIGH XVA", + direction="l", + linebreak="sa", + unicodeslot=0x19A7, + }, + [0x19A8]={ + category="lo", + description="NEW TAI LUE LETTER LOW KVA", + direction="l", + linebreak="sa", + unicodeslot=0x19A8, + }, + [0x19A9]={ + category="lo", + description="NEW TAI LUE LETTER LOW XVA", + direction="l", + linebreak="sa", + unicodeslot=0x19A9, + }, + [0x19B0]={ + category="mc", + description="NEW TAI LUE VOWEL SIGN VOWEL SHORTENER", + direction="l", + linebreak="sa", + unicodeslot=0x19B0, + }, + [0x19B1]={ + category="mc", + description="NEW TAI LUE VOWEL SIGN AA", + direction="l", + linebreak="sa", + unicodeslot=0x19B1, + }, + [0x19B2]={ + category="mc", + description="NEW TAI LUE VOWEL SIGN II", + direction="l", + linebreak="sa", + unicodeslot=0x19B2, + }, + [0x19B3]={ + category="mc", + description="NEW TAI LUE VOWEL SIGN U", + direction="l", + linebreak="sa", + unicodeslot=0x19B3, + }, + [0x19B4]={ + category="mc", + description="NEW TAI LUE VOWEL SIGN UU", + direction="l", + linebreak="sa", + unicodeslot=0x19B4, + }, + [0x19B5]={ + category="mc", + description="NEW TAI LUE VOWEL SIGN E", + direction="l", + linebreak="sa", + unicodeslot=0x19B5, + }, + [0x19B6]={ + category="mc", + description="NEW TAI LUE VOWEL SIGN AE", + direction="l", + linebreak="sa", + unicodeslot=0x19B6, + }, + [0x19B7]={ + category="mc", + description="NEW TAI LUE VOWEL SIGN O", + direction="l", + linebreak="sa", + unicodeslot=0x19B7, + }, + [0x19B8]={ + category="mc", + description="NEW TAI LUE VOWEL SIGN OA", + direction="l", + linebreak="sa", + unicodeslot=0x19B8, + }, + [0x19B9]={ + category="mc", + description="NEW TAI LUE VOWEL SIGN UE", + direction="l", + linebreak="sa", + unicodeslot=0x19B9, + }, + [0x19BA]={ + category="mc", + description="NEW TAI LUE VOWEL SIGN AY", + direction="l", + linebreak="sa", + unicodeslot=0x19BA, + }, + [0x19BB]={ + category="mc", + description="NEW TAI LUE VOWEL SIGN AAY", + direction="l", + linebreak="sa", + unicodeslot=0x19BB, + }, + [0x19BC]={ + category="mc", + description="NEW TAI LUE VOWEL SIGN UY", + direction="l", + linebreak="sa", + unicodeslot=0x19BC, + }, + [0x19BD]={ + category="mc", + description="NEW TAI LUE VOWEL SIGN OY", + direction="l", + linebreak="sa", + unicodeslot=0x19BD, + }, + [0x19BE]={ + category="mc", + description="NEW TAI LUE VOWEL SIGN OAY", + direction="l", + linebreak="sa", + unicodeslot=0x19BE, + }, + [0x19BF]={ + category="mc", + description="NEW TAI LUE VOWEL SIGN UEY", + direction="l", + linebreak="sa", + unicodeslot=0x19BF, + }, + [0x19C0]={ + category="mc", + description="NEW TAI LUE VOWEL SIGN IY", + direction="l", + linebreak="sa", + unicodeslot=0x19C0, + }, + [0x19C1]={ + category="lo", + description="NEW TAI LUE LETTER FINAL V", + direction="l", + linebreak="sa", + unicodeslot=0x19C1, + }, + [0x19C2]={ + category="lo", + description="NEW TAI LUE LETTER FINAL NG", + direction="l", + linebreak="sa", + unicodeslot=0x19C2, + }, + [0x19C3]={ + category="lo", + description="NEW TAI LUE LETTER FINAL N", + direction="l", + linebreak="sa", + unicodeslot=0x19C3, + }, + [0x19C4]={ + category="lo", + description="NEW TAI LUE LETTER FINAL M", + direction="l", + linebreak="sa", + unicodeslot=0x19C4, + }, + [0x19C5]={ + category="lo", + description="NEW TAI LUE LETTER FINAL K", + direction="l", + linebreak="sa", + unicodeslot=0x19C5, + }, + [0x19C6]={ + category="lo", + description="NEW TAI LUE LETTER FINAL D", + direction="l", + linebreak="sa", + unicodeslot=0x19C6, + }, + [0x19C7]={ + category="lo", + description="NEW TAI LUE LETTER FINAL B", + direction="l", + linebreak="sa", + unicodeslot=0x19C7, + }, + [0x19C8]={ + category="mc", + description="NEW TAI LUE TONE MARK-0x0001", + direction="l", + linebreak="sa", + unicodeslot=0x19C8, + }, + [0x19C9]={ + category="mc", + description="NEW TAI LUE TONE MARK-0x0002", + direction="l", + linebreak="sa", + unicodeslot=0x19C9, + }, + [0x19D0]={ + category="nd", + description="NEW TAI LUE DIGIT ZERO", + direction="l", + linebreak="nu", + unicodeslot=0x19D0, + }, + [0x19D1]={ + category="nd", + description="NEW TAI LUE DIGIT ONE", + direction="l", + linebreak="nu", + unicodeslot=0x19D1, + }, + [0x19D2]={ + category="nd", + description="NEW TAI LUE DIGIT TWO", + direction="l", + linebreak="nu", + unicodeslot=0x19D2, + }, + [0x19D3]={ + category="nd", + description="NEW TAI LUE DIGIT THREE", + direction="l", + linebreak="nu", + unicodeslot=0x19D3, + }, + [0x19D4]={ + category="nd", + description="NEW TAI LUE DIGIT FOUR", + direction="l", + linebreak="nu", + unicodeslot=0x19D4, + }, + [0x19D5]={ + category="nd", + description="NEW TAI LUE DIGIT FIVE", + direction="l", + linebreak="nu", + unicodeslot=0x19D5, + }, + [0x19D6]={ + category="nd", + description="NEW TAI LUE DIGIT SIX", + direction="l", + linebreak="nu", + unicodeslot=0x19D6, + }, + [0x19D7]={ + category="nd", + description="NEW TAI LUE DIGIT SEVEN", + direction="l", + linebreak="nu", + unicodeslot=0x19D7, + }, + [0x19D8]={ + category="nd", + description="NEW TAI LUE DIGIT EIGHT", + direction="l", + linebreak="nu", + unicodeslot=0x19D8, + }, + [0x19D9]={ + category="nd", + description="NEW TAI LUE DIGIT NINE", + direction="l", + linebreak="nu", + unicodeslot=0x19D9, + }, + [0x19DE]={ + category="po", + description="NEW TAI LUE SIGN LAE", + direction="on", + linebreak="sa", + unicodeslot=0x19DE, + }, + [0x19DF]={ + category="po", + description="NEW TAI LUE SIGN LAEV", + direction="on", + linebreak="sa", + unicodeslot=0x19DF, + }, + [0x19E0]={ + category="so", + description="KHMER SYMBOL PATHAMASAT", + direction="on", + linebreak="al", + unicodeslot=0x19E0, + }, + [0x19E1]={ + category="so", + description="KHMER SYMBOL MUOY KOET", + direction="on", + linebreak="al", + unicodeslot=0x19E1, + }, + [0x19E2]={ + category="so", + description="KHMER SYMBOL PII KOET", + direction="on", + linebreak="al", + unicodeslot=0x19E2, + }, + [0x19E3]={ + category="so", + description="KHMER SYMBOL BEI KOET", + direction="on", + linebreak="al", + unicodeslot=0x19E3, + }, + [0x19E4]={ + category="so", + description="KHMER SYMBOL BUON KOET", + direction="on", + linebreak="al", + unicodeslot=0x19E4, + }, + [0x19E5]={ + category="so", + description="KHMER SYMBOL PRAM KOET", + direction="on", + linebreak="al", + unicodeslot=0x19E5, + }, + [0x19E6]={ + category="so", + description="KHMER SYMBOL PRAM-MUOY KOET", + direction="on", + linebreak="al", + unicodeslot=0x19E6, + }, + [0x19E7]={ + category="so", + description="KHMER SYMBOL PRAM-PII KOET", + direction="on", + linebreak="al", + unicodeslot=0x19E7, + }, + [0x19E8]={ + category="so", + description="KHMER SYMBOL PRAM-BEI KOET", + direction="on", + linebreak="al", + unicodeslot=0x19E8, + }, + [0x19E9]={ + category="so", + description="KHMER SYMBOL PRAM-BUON KOET", + direction="on", + linebreak="al", + unicodeslot=0x19E9, + }, + [0x19EA]={ + category="so", + description="KHMER SYMBOL DAP KOET", + direction="on", + linebreak="al", + unicodeslot=0x19EA, + }, + [0x19EB]={ + category="so", + description="KHMER SYMBOL DAP-MUOY KOET", + direction="on", + linebreak="al", + unicodeslot=0x19EB, + }, + [0x19EC]={ + category="so", + description="KHMER SYMBOL DAP-PII KOET", + direction="on", + linebreak="al", + unicodeslot=0x19EC, + }, + [0x19ED]={ + category="so", + description="KHMER SYMBOL DAP-BEI KOET", + direction="on", + linebreak="al", + unicodeslot=0x19ED, + }, + [0x19EE]={ + category="so", + description="KHMER SYMBOL DAP-BUON KOET", + direction="on", + linebreak="al", + unicodeslot=0x19EE, + }, + [0x19EF]={ + category="so", + description="KHMER SYMBOL DAP-PRAM KOET", + direction="on", + linebreak="al", + unicodeslot=0x19EF, + }, + [0x19F0]={ + category="so", + description="KHMER SYMBOL TUTEYASAT", + direction="on", + linebreak="al", + unicodeslot=0x19F0, + }, + [0x19F1]={ + category="so", + description="KHMER SYMBOL MUOY ROC", + direction="on", + linebreak="al", + unicodeslot=0x19F1, + }, + [0x19F2]={ + category="so", + description="KHMER SYMBOL PII ROC", + direction="on", + linebreak="al", + unicodeslot=0x19F2, + }, + [0x19F3]={ + category="so", + description="KHMER SYMBOL BEI ROC", + direction="on", + linebreak="al", + unicodeslot=0x19F3, + }, + [0x19F4]={ + category="so", + description="KHMER SYMBOL BUON ROC", + direction="on", + linebreak="al", + unicodeslot=0x19F4, + }, + [0x19F5]={ + category="so", + description="KHMER SYMBOL PRAM ROC", + direction="on", + linebreak="al", + unicodeslot=0x19F5, + }, + [0x19F6]={ + category="so", + description="KHMER SYMBOL PRAM-MUOY ROC", + direction="on", + linebreak="al", + unicodeslot=0x19F6, + }, + [0x19F7]={ + category="so", + description="KHMER SYMBOL PRAM-PII ROC", + direction="on", + linebreak="al", + unicodeslot=0x19F7, + }, + [0x19F8]={ + category="so", + description="KHMER SYMBOL PRAM-BEI ROC", + direction="on", + linebreak="al", + unicodeslot=0x19F8, + }, + [0x19F9]={ + category="so", + description="KHMER SYMBOL PRAM-BUON ROC", + direction="on", + linebreak="al", + unicodeslot=0x19F9, + }, + [0x19FA]={ + category="so", + description="KHMER SYMBOL DAP ROC", + direction="on", + linebreak="al", + unicodeslot=0x19FA, + }, + [0x19FB]={ + category="so", + description="KHMER SYMBOL DAP-MUOY ROC", + direction="on", + linebreak="al", + unicodeslot=0x19FB, + }, + [0x19FC]={ + category="so", + description="KHMER SYMBOL DAP-PII ROC", + direction="on", + linebreak="al", + unicodeslot=0x19FC, + }, + [0x19FD]={ + category="so", + description="KHMER SYMBOL DAP-BEI ROC", + direction="on", + linebreak="al", + unicodeslot=0x19FD, + }, + [0x19FE]={ + category="so", + description="KHMER SYMBOL DAP-BUON ROC", + direction="on", + linebreak="al", + unicodeslot=0x19FE, + }, + [0x19FF]={ + category="so", + description="KHMER SYMBOL DAP-PRAM ROC", + direction="on", + linebreak="al", + unicodeslot=0x19FF, + }, + [0x1A00]={ + category="lo", + description="BUGINESE LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x1A00, + }, + [0x1A01]={ + category="lo", + description="BUGINESE LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x1A01, + }, + [0x1A02]={ + category="lo", + description="BUGINESE LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0x1A02, + }, + [0x1A03]={ + category="lo", + description="BUGINESE LETTER NGKA", + direction="l", + linebreak="al", + unicodeslot=0x1A03, + }, + [0x1A04]={ + category="lo", + description="BUGINESE LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x1A04, + }, + [0x1A05]={ + category="lo", + description="BUGINESE LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x1A05, + }, + [0x1A06]={ + category="lo", + description="BUGINESE LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x1A06, + }, + [0x1A07]={ + category="lo", + description="BUGINESE LETTER MPA", + direction="l", + linebreak="al", + unicodeslot=0x1A07, + }, + [0x1A08]={ + category="lo", + description="BUGINESE LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x1A08, + }, + [0x1A09]={ + category="lo", + description="BUGINESE LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x1A09, + }, + [0x1A0A]={ + category="lo", + description="BUGINESE LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x1A0A, + }, + [0x1A0B]={ + category="lo", + description="BUGINESE LETTER NRA", + direction="l", + linebreak="al", + unicodeslot=0x1A0B, + }, + [0x1A0C]={ + category="lo", + description="BUGINESE LETTER CA", + direction="l", + linebreak="al", + unicodeslot=0x1A0C, + }, + [0x1A0D]={ + category="lo", + description="BUGINESE LETTER JA", + direction="l", + linebreak="al", + unicodeslot=0x1A0D, + }, + [0x1A0E]={ + category="lo", + description="BUGINESE LETTER NYA", + direction="l", + linebreak="al", + unicodeslot=0x1A0E, + }, + [0x1A0F]={ + category="lo", + description="BUGINESE LETTER NYCA", + direction="l", + linebreak="al", + unicodeslot=0x1A0F, + }, + [0x1A10]={ + category="lo", + description="BUGINESE LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x1A10, + }, + [0x1A11]={ + category="lo", + description="BUGINESE LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0x1A11, + }, + [0x1A12]={ + category="lo", + description="BUGINESE LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x1A12, + }, + [0x1A13]={ + category="lo", + description="BUGINESE LETTER VA", + direction="l", + linebreak="al", + unicodeslot=0x1A13, + }, + [0x1A14]={ + category="lo", + description="BUGINESE LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x1A14, + }, + [0x1A15]={ + category="lo", + description="BUGINESE LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x1A15, + }, + [0x1A16]={ + category="lo", + description="BUGINESE LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x1A16, + }, + [0x1A17]={ + category="mn", + description="BUGINESE VOWEL SIGN I", + direction="nsm", + linebreak="cm", + unicodeslot=0x1A17, + }, + [0x1A18]={ + category="mn", + description="BUGINESE VOWEL SIGN U", + direction="nsm", + linebreak="cm", + unicodeslot=0x1A18, + }, + [0x1A19]={ + category="mc", + description="BUGINESE VOWEL SIGN E", + direction="l", + linebreak="cm", + unicodeslot=0x1A19, + }, + [0x1A1A]={ + category="mc", + description="BUGINESE VOWEL SIGN O", + direction="l", + linebreak="cm", + unicodeslot=0x1A1A, + }, + [0x1A1B]={ + category="mc", + description="BUGINESE VOWEL SIGN AE", + direction="l", + linebreak="cm", + unicodeslot=0x1A1B, + }, + [0x1A1E]={ + category="po", + description="BUGINESE PALLAWA", + direction="l", + linebreak="ba", + unicodeslot=0x1A1E, + }, + [0x1A1F]={ + category="po", + description="BUGINESE END OF SECTION", + direction="l", + linebreak="al", + unicodeslot=0x1A1F, + }, + [0x1B00]={ + category="mn", + description="BALINESE SIGN ULU RICEM", + direction="nsm", + linebreak="cm", + unicodeslot=0x1B00, + }, + [0x1B01]={ + category="mn", + description="BALINESE SIGN ULU CANDRA", + direction="nsm", + linebreak="cm", + unicodeslot=0x1B01, + }, + [0x1B02]={ + category="mn", + description="BALINESE SIGN CECEK", + direction="nsm", + linebreak="cm", + unicodeslot=0x1B02, + }, + [0x1B03]={ + category="mn", + description="BALINESE SIGN SURANG", + direction="nsm", + linebreak="cm", + unicodeslot=0x1B03, + }, + [0x1B04]={ + category="mc", + description="BALINESE SIGN BISAH", + direction="l", + linebreak="cm", + unicodeslot=0x1B04, + }, + [0x1B05]={ + category="lo", + description="BALINESE LETTER AKARA", + direction="l", + linebreak="al", + unicodeslot=0x1B05, + }, + [0x1B06]={ + category="lo", + description="BALINESE LETTER AKARA TEDUNG", + direction="l", + linebreak="al", + specials={ "char", 0x1B05, 0x1B35 }, + unicodeslot=0x1B06, + }, + [0x1B07]={ + category="lo", + description="BALINESE LETTER IKARA", + direction="l", + linebreak="al", + unicodeslot=0x1B07, + }, + [0x1B08]={ + category="lo", + description="BALINESE LETTER IKARA TEDUNG", + direction="l", + linebreak="al", + specials={ "char", 0x1B07, 0x1B35 }, + unicodeslot=0x1B08, + }, + [0x1B09]={ + category="lo", + description="BALINESE LETTER UKARA", + direction="l", + linebreak="al", + unicodeslot=0x1B09, + }, + [0x1B0A]={ + category="lo", + description="BALINESE LETTER UKARA TEDUNG", + direction="l", + linebreak="al", + specials={ "char", 0x1B09, 0x1B35 }, + unicodeslot=0x1B0A, + }, + [0x1B0B]={ + category="lo", + description="BALINESE LETTER RA REPA", + direction="l", + linebreak="al", + unicodeslot=0x1B0B, + }, + [0x1B0C]={ + category="lo", + description="BALINESE LETTER RA REPA TEDUNG", + direction="l", + linebreak="al", + specials={ "char", 0x1B0B, 0x1B35 }, + unicodeslot=0x1B0C, + }, + [0x1B0D]={ + category="lo", + description="BALINESE LETTER LA LENGA", + direction="l", + linebreak="al", + unicodeslot=0x1B0D, + }, + [0x1B0E]={ + category="lo", + description="BALINESE LETTER LA LENGA TEDUNG", + direction="l", + linebreak="al", + specials={ "char", 0x1B0D, 0x1B35 }, + unicodeslot=0x1B0E, + }, + [0x1B0F]={ + category="lo", + description="BALINESE LETTER EKARA", + direction="l", + linebreak="al", + unicodeslot=0x1B0F, + }, + [0x1B10]={ + category="lo", + description="BALINESE LETTER AIKARA", + direction="l", + linebreak="al", + unicodeslot=0x1B10, + }, + [0x1B11]={ + category="lo", + description="BALINESE LETTER OKARA", + direction="l", + linebreak="al", + unicodeslot=0x1B11, + }, + [0x1B12]={ + category="lo", + description="BALINESE LETTER OKARA TEDUNG", + direction="l", + linebreak="al", + specials={ "char", 0x1B11, 0x1B35 }, + unicodeslot=0x1B12, + }, + [0x1B13]={ + category="lo", + description="BALINESE LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x1B13, + }, + [0x1B14]={ + category="lo", + description="BALINESE LETTER KA MAHAPRANA", + direction="l", + linebreak="al", + unicodeslot=0x1B14, + }, + [0x1B15]={ + category="lo", + description="BALINESE LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x1B15, + }, + [0x1B16]={ + category="lo", + description="BALINESE LETTER GA GORA", + direction="l", + linebreak="al", + unicodeslot=0x1B16, + }, + [0x1B17]={ + category="lo", + description="BALINESE LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0x1B17, + }, + [0x1B18]={ + category="lo", + description="BALINESE LETTER CA", + direction="l", + linebreak="al", + unicodeslot=0x1B18, + }, + [0x1B19]={ + category="lo", + description="BALINESE LETTER CA LACA", + direction="l", + linebreak="al", + unicodeslot=0x1B19, + }, + [0x1B1A]={ + category="lo", + description="BALINESE LETTER JA", + direction="l", + linebreak="al", + unicodeslot=0x1B1A, + }, + [0x1B1B]={ + category="lo", + description="BALINESE LETTER JA JERA", + direction="l", + linebreak="al", + unicodeslot=0x1B1B, + }, + [0x1B1C]={ + category="lo", + description="BALINESE LETTER NYA", + direction="l", + linebreak="al", + unicodeslot=0x1B1C, + }, + [0x1B1D]={ + category="lo", + description="BALINESE LETTER TA LATIK", + direction="l", + linebreak="al", + unicodeslot=0x1B1D, + }, + [0x1B1E]={ + category="lo", + description="BALINESE LETTER TA MURDA MAHAPRANA", + direction="l", + linebreak="al", + unicodeslot=0x1B1E, + }, + [0x1B1F]={ + category="lo", + description="BALINESE LETTER DA MURDA ALPAPRANA", + direction="l", + linebreak="al", + unicodeslot=0x1B1F, + }, + [0x1B20]={ + category="lo", + description="BALINESE LETTER DA MURDA MAHAPRANA", + direction="l", + linebreak="al", + unicodeslot=0x1B20, + }, + [0x1B21]={ + category="lo", + description="BALINESE LETTER NA RAMBAT", + direction="l", + linebreak="al", + unicodeslot=0x1B21, + }, + [0x1B22]={ + category="lo", + description="BALINESE LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x1B22, + }, + [0x1B23]={ + category="lo", + description="BALINESE LETTER TA TAWA", + direction="l", + linebreak="al", + unicodeslot=0x1B23, + }, + [0x1B24]={ + category="lo", + description="BALINESE LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x1B24, + }, + [0x1B25]={ + category="lo", + description="BALINESE LETTER DA MADU", + direction="l", + linebreak="al", + unicodeslot=0x1B25, + }, + [0x1B26]={ + category="lo", + description="BALINESE LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x1B26, + }, + [0x1B27]={ + category="lo", + description="BALINESE LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x1B27, + }, + [0x1B28]={ + category="lo", + description="BALINESE LETTER PA KAPAL", + direction="l", + linebreak="al", + unicodeslot=0x1B28, + }, + [0x1B29]={ + category="lo", + description="BALINESE LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x1B29, + }, + [0x1B2A]={ + category="lo", + description="BALINESE LETTER BA KEMBANG", + direction="l", + linebreak="al", + unicodeslot=0x1B2A, + }, + [0x1B2B]={ + category="lo", + description="BALINESE LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x1B2B, + }, + [0x1B2C]={ + category="lo", + description="BALINESE LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x1B2C, + }, + [0x1B2D]={ + category="lo", + description="BALINESE LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0x1B2D, + }, + [0x1B2E]={ + category="lo", + description="BALINESE LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x1B2E, + }, + [0x1B2F]={ + category="lo", + description="BALINESE LETTER WA", + direction="l", + linebreak="al", + unicodeslot=0x1B2F, + }, + [0x1B30]={ + category="lo", + description="BALINESE LETTER SA SAGA", + direction="l", + linebreak="al", + unicodeslot=0x1B30, + }, + [0x1B31]={ + category="lo", + description="BALINESE LETTER SA SAPA", + direction="l", + linebreak="al", + unicodeslot=0x1B31, + }, + [0x1B32]={ + category="lo", + description="BALINESE LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x1B32, + }, + [0x1B33]={ + category="lo", + description="BALINESE LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x1B33, + }, + [0x1B34]={ + category="mn", + description="BALINESE SIGN REREKAN", + direction="nsm", + linebreak="cm", + unicodeslot=0x1B34, + }, + [0x1B35]={ + category="mc", + description="BALINESE VOWEL SIGN TEDUNG", + direction="l", + linebreak="cm", + unicodeslot=0x1B35, + }, + [0x1B36]={ + category="mn", + description="BALINESE VOWEL SIGN ULU", + direction="nsm", + linebreak="cm", + unicodeslot=0x1B36, + }, + [0x1B37]={ + category="mn", + description="BALINESE VOWEL SIGN ULU SARI", + direction="nsm", + linebreak="cm", + unicodeslot=0x1B37, + }, + [0x1B38]={ + category="mn", + description="BALINESE VOWEL SIGN SUKU", + direction="nsm", + linebreak="cm", + unicodeslot=0x1B38, + }, + [0x1B39]={ + category="mn", + description="BALINESE VOWEL SIGN SUKU ILUT", + direction="nsm", + linebreak="cm", + unicodeslot=0x1B39, + }, + [0x1B3A]={ + category="mn", + description="BALINESE VOWEL SIGN RA REPA", + direction="nsm", + linebreak="cm", + unicodeslot=0x1B3A, + }, + [0x1B3B]={ + category="mc", + description="BALINESE VOWEL SIGN RA REPA TEDUNG", + direction="l", + linebreak="cm", + specials={ "char", 0x1B3A, 0x1B35 }, + unicodeslot=0x1B3B, + }, + [0x1B3C]={ + category="mn", + description="BALINESE VOWEL SIGN LA LENGA", + direction="nsm", + linebreak="cm", + unicodeslot=0x1B3C, + }, + [0x1B3D]={ + category="mc", + description="BALINESE VOWEL SIGN LA LENGA TEDUNG", + direction="l", + linebreak="cm", + specials={ "char", 0x1B3C, 0x1B35 }, + unicodeslot=0x1B3D, + }, + [0x1B3E]={ + category="mc", + description="BALINESE VOWEL SIGN TALING", + direction="l", + linebreak="cm", + unicodeslot=0x1B3E, + }, + [0x1B3F]={ + category="mc", + description="BALINESE VOWEL SIGN TALING REPA", + direction="l", + linebreak="cm", + unicodeslot=0x1B3F, + }, + [0x1B40]={ + category="mc", + description="BALINESE VOWEL SIGN TALING TEDUNG", + direction="l", + linebreak="cm", + specials={ "char", 0x1B3E, 0x1B35 }, + unicodeslot=0x1B40, + }, + [0x1B41]={ + category="mc", + description="BALINESE VOWEL SIGN TALING REPA TEDUNG", + direction="l", + linebreak="cm", + specials={ "char", 0x1B3F, 0x1B35 }, + unicodeslot=0x1B41, + }, + [0x1B42]={ + category="mn", + description="BALINESE VOWEL SIGN PEPET", + direction="nsm", + linebreak="cm", + unicodeslot=0x1B42, + }, + [0x1B43]={ + category="mc", + description="BALINESE VOWEL SIGN PEPET TEDUNG", + direction="l", + linebreak="cm", + specials={ "char", 0x1B42, 0x1B35 }, + unicodeslot=0x1B43, + }, + [0x1B44]={ + category="mc", + description="BALINESE ADEG ADEG", + direction="l", + linebreak="cm", + unicodeslot=0x1B44, + }, + [0x1B45]={ + category="lo", + description="BALINESE LETTER KAF SASAK", + direction="l", + linebreak="al", + unicodeslot=0x1B45, + }, + [0x1B46]={ + category="lo", + description="BALINESE LETTER KHOT SASAK", + direction="l", + linebreak="al", + unicodeslot=0x1B46, + }, + [0x1B47]={ + category="lo", + description="BALINESE LETTER TZIR SASAK", + direction="l", + linebreak="al", + unicodeslot=0x1B47, + }, + [0x1B48]={ + category="lo", + description="BALINESE LETTER EF SASAK", + direction="l", + linebreak="al", + unicodeslot=0x1B48, + }, + [0x1B49]={ + category="lo", + description="BALINESE LETTER VE SASAK", + direction="l", + linebreak="al", + unicodeslot=0x1B49, + }, + [0x1B4A]={ + category="lo", + description="BALINESE LETTER ZAL SASAK", + direction="l", + linebreak="al", + unicodeslot=0x1B4A, + }, + [0x1B4B]={ + category="lo", + description="BALINESE LETTER ASYURA SASAK", + direction="l", + linebreak="al", + unicodeslot=0x1B4B, + }, + [0x1B50]={ + category="nd", + description="BALINESE DIGIT ZERO", + direction="l", + linebreak="nu", + unicodeslot=0x1B50, + }, + [0x1B51]={ + category="nd", + description="BALINESE DIGIT ONE", + direction="l", + linebreak="nu", + unicodeslot=0x1B51, + }, + [0x1B52]={ + category="nd", + description="BALINESE DIGIT TWO", + direction="l", + linebreak="nu", + unicodeslot=0x1B52, + }, + [0x1B53]={ + category="nd", + description="BALINESE DIGIT THREE", + direction="l", + linebreak="nu", + unicodeslot=0x1B53, + }, + [0x1B54]={ + category="nd", + description="BALINESE DIGIT FOUR", + direction="l", + linebreak="nu", + unicodeslot=0x1B54, + }, + [0x1B55]={ + category="nd", + description="BALINESE DIGIT FIVE", + direction="l", + linebreak="nu", + unicodeslot=0x1B55, + }, + [0x1B56]={ + category="nd", + description="BALINESE DIGIT SIX", + direction="l", + linebreak="nu", + unicodeslot=0x1B56, + }, + [0x1B57]={ + category="nd", + description="BALINESE DIGIT SEVEN", + direction="l", + linebreak="nu", + unicodeslot=0x1B57, + }, + [0x1B58]={ + category="nd", + description="BALINESE DIGIT EIGHT", + direction="l", + linebreak="nu", + unicodeslot=0x1B58, + }, + [0x1B59]={ + category="nd", + description="BALINESE DIGIT NINE", + direction="l", + linebreak="nu", + unicodeslot=0x1B59, + }, + [0x1B5A]={ + category="po", + description="BALINESE PANTI", + direction="l", + linebreak="ba", + unicodeslot=0x1B5A, + }, + [0x1B5B]={ + category="po", + description="BALINESE PAMADA", + direction="l", + linebreak="ba", + unicodeslot=0x1B5B, + }, + [0x1B5C]={ + category="po", + description="BALINESE WINDU", + direction="l", + linebreak="ba", + unicodeslot=0x1B5C, + }, + [0x1B5D]={ + category="po", + description="BALINESE CARIK PAMUNGKAH", + direction="l", + linebreak="ba", + unicodeslot=0x1B5D, + }, + [0x1B5E]={ + category="po", + description="BALINESE CARIK SIKI", + direction="l", + linebreak="ba", + unicodeslot=0x1B5E, + }, + [0x1B5F]={ + category="po", + description="BALINESE CARIK PAREREN", + direction="l", + linebreak="ba", + unicodeslot=0x1B5F, + }, + [0x1B60]={ + category="po", + description="BALINESE PAMENENG", + direction="l", + linebreak="ba", + unicodeslot=0x1B60, + }, + [0x1B61]={ + category="so", + description="BALINESE MUSICAL SYMBOL DONG", + direction="l", + linebreak="al", + unicodeslot=0x1B61, + }, + [0x1B62]={ + category="so", + description="BALINESE MUSICAL SYMBOL DENG", + direction="l", + linebreak="al", + unicodeslot=0x1B62, + }, + [0x1B63]={ + category="so", + description="BALINESE MUSICAL SYMBOL DUNG", + direction="l", + linebreak="al", + unicodeslot=0x1B63, + }, + [0x1B64]={ + category="so", + description="BALINESE MUSICAL SYMBOL DANG", + direction="l", + linebreak="al", + unicodeslot=0x1B64, + }, + [0x1B65]={ + category="so", + description="BALINESE MUSICAL SYMBOL DANG SURANG", + direction="l", + linebreak="al", + unicodeslot=0x1B65, + }, + [0x1B66]={ + category="so", + description="BALINESE MUSICAL SYMBOL DING", + direction="l", + linebreak="al", + unicodeslot=0x1B66, + }, + [0x1B67]={ + category="so", + description="BALINESE MUSICAL SYMBOL DAENG", + direction="l", + linebreak="al", + unicodeslot=0x1B67, + }, + [0x1B68]={ + category="so", + description="BALINESE MUSICAL SYMBOL DEUNG", + direction="l", + linebreak="al", + unicodeslot=0x1B68, + }, + [0x1B69]={ + category="so", + description="BALINESE MUSICAL SYMBOL DAING", + direction="l", + linebreak="al", + unicodeslot=0x1B69, + }, + [0x1B6A]={ + category="so", + description="BALINESE MUSICAL SYMBOL DANG GEDE", + direction="l", + linebreak="al", + unicodeslot=0x1B6A, + }, + [0x1B6B]={ + category="mn", + description="BALINESE MUSICAL SYMBOL COMBINING TEGEH", + direction="nsm", + linebreak="cm", + unicodeslot=0x1B6B, + }, + [0x1B6C]={ + category="mn", + description="BALINESE MUSICAL SYMBOL COMBINING ENDEP", + direction="nsm", + linebreak="cm", + unicodeslot=0x1B6C, + }, + [0x1B6D]={ + category="mn", + description="BALINESE MUSICAL SYMBOL COMBINING KEMPUL", + direction="nsm", + linebreak="cm", + unicodeslot=0x1B6D, + }, + [0x1B6E]={ + category="mn", + description="BALINESE MUSICAL SYMBOL COMBINING KEMPLI", + direction="nsm", + linebreak="cm", + unicodeslot=0x1B6E, + }, + [0x1B6F]={ + category="mn", + description="BALINESE MUSICAL SYMBOL COMBINING JEGOGAN", + direction="nsm", + linebreak="cm", + unicodeslot=0x1B6F, + }, + [0x1B70]={ + category="mn", + description="BALINESE MUSICAL SYMBOL COMBINING KEMPUL WITH JEGOGAN", + direction="nsm", + linebreak="cm", + unicodeslot=0x1B70, + }, + [0x1B71]={ + category="mn", + description="BALINESE MUSICAL SYMBOL COMBINING KEMPLI WITH JEGOGAN", + direction="nsm", + linebreak="cm", + unicodeslot=0x1B71, + }, + [0x1B72]={ + category="mn", + description="BALINESE MUSICAL SYMBOL COMBINING BENDE", + direction="nsm", + linebreak="cm", + unicodeslot=0x1B72, + }, + [0x1B73]={ + category="mn", + description="BALINESE MUSICAL SYMBOL COMBINING GONG", + direction="nsm", + linebreak="cm", + unicodeslot=0x1B73, + }, + [0x1B74]={ + category="so", + description="BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG", + direction="l", + linebreak="al", + unicodeslot=0x1B74, + }, + [0x1B75]={ + category="so", + description="BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DAG", + direction="l", + linebreak="al", + unicodeslot=0x1B75, + }, + [0x1B76]={ + category="so", + description="BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TUK", + direction="l", + linebreak="al", + unicodeslot=0x1B76, + }, + [0x1B77]={ + category="so", + description="BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TAK", + direction="l", + linebreak="al", + unicodeslot=0x1B77, + }, + [0x1B78]={ + category="so", + description="BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PANG", + direction="l", + linebreak="al", + unicodeslot=0x1B78, + }, + [0x1B79]={ + category="so", + description="BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PUNG", + direction="l", + linebreak="al", + unicodeslot=0x1B79, + }, + [0x1B7A]={ + category="so", + description="BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLAK", + direction="l", + linebreak="al", + unicodeslot=0x1B7A, + }, + [0x1B7B]={ + category="so", + description="BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLUK", + direction="l", + linebreak="al", + unicodeslot=0x1B7B, + }, + [0x1B7C]={ + category="so", + description="BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING", + direction="l", + linebreak="al", + unicodeslot=0x1B7C, + }, + [0x1D00]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL A", + direction="l", + linebreak="al", + unicodeslot=0x1D00, + }, + [0x1D01]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL AE", + direction="l", + linebreak="al", + unicodeslot=0x1D01, + }, + [0x1D02]={ + category="ll", + description="LATIN SMALL LETTER TURNED AE", + direction="l", + linebreak="al", + unicodeslot=0x1D02, + }, + [0x1D03]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL BARRED B", + direction="l", + linebreak="al", + unicodeslot=0x1D03, + }, + [0x1D04]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL C", + direction="l", + linebreak="al", + unicodeslot=0x1D04, + }, + [0x1D05]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL D", + direction="l", + linebreak="al", + unicodeslot=0x1D05, + }, + [0x1D06]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL ETH", + direction="l", + linebreak="al", + unicodeslot=0x1D06, + }, + [0x1D07]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL E", + direction="l", + linebreak="al", + unicodeslot=0x1D07, + }, + [0x1D08]={ + category="ll", + description="LATIN SMALL LETTER TURNED OPEN E", + direction="l", + linebreak="al", + unicodeslot=0x1D08, + }, + [0x1D09]={ + category="ll", + description="LATIN SMALL LETTER TURNED I", + direction="l", + linebreak="al", + unicodeslot=0x1D09, + }, + [0x1D0A]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL J", + direction="l", + linebreak="al", + unicodeslot=0x1D0A, + }, + [0x1D0B]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL K", + direction="l", + linebreak="al", + unicodeslot=0x1D0B, + }, + [0x1D0C]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL L WITH STROKE", + direction="l", + linebreak="al", + unicodeslot=0x1D0C, + }, + [0x1D0D]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL M", + direction="l", + linebreak="al", + unicodeslot=0x1D0D, + }, + [0x1D0E]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL REVERSED N", + direction="l", + linebreak="al", + unicodeslot=0x1D0E, + }, + [0x1D0F]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL O", + direction="l", + linebreak="al", + unicodeslot=0x1D0F, + }, + [0x1D10]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL OPEN O", + direction="l", + linebreak="al", + unicodeslot=0x1D10, + }, + [0x1D11]={ + category="ll", + description="LATIN SMALL LETTER SIDEWAYS O", + direction="l", + linebreak="al", + unicodeslot=0x1D11, + }, + [0x1D12]={ + category="ll", + description="LATIN SMALL LETTER SIDEWAYS OPEN O", + direction="l", + linebreak="al", + unicodeslot=0x1D12, + }, + [0x1D13]={ + category="ll", + description="LATIN SMALL LETTER SIDEWAYS O WITH STROKE", + direction="l", + linebreak="al", + unicodeslot=0x1D13, + }, + [0x1D14]={ + category="ll", + description="LATIN SMALL LETTER TURNED OE", + direction="l", + linebreak="al", + unicodeslot=0x1D14, + }, + [0x1D15]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL OU", + direction="l", + linebreak="al", + unicodeslot=0x1D15, + }, + [0x1D16]={ + category="ll", + description="LATIN SMALL LETTER TOP HALF O", + direction="l", + linebreak="al", + unicodeslot=0x1D16, + }, + [0x1D17]={ + category="ll", + description="LATIN SMALL LETTER BOTTOM HALF O", + direction="l", + linebreak="al", + unicodeslot=0x1D17, + }, + [0x1D18]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL P", + direction="l", + linebreak="al", + unicodeslot=0x1D18, + }, + [0x1D19]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL REVERSED R", + direction="l", + linebreak="al", + unicodeslot=0x1D19, + }, + [0x1D1A]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL TURNED R", + direction="l", + linebreak="al", + unicodeslot=0x1D1A, + }, + [0x1D1B]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL T", + direction="l", + linebreak="al", + unicodeslot=0x1D1B, + }, + [0x1D1C]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL U", + direction="l", + linebreak="al", + unicodeslot=0x1D1C, + }, + [0x1D1D]={ + category="ll", + description="LATIN SMALL LETTER SIDEWAYS U", + direction="l", + linebreak="al", + unicodeslot=0x1D1D, + }, + [0x1D1E]={ + category="ll", + description="LATIN SMALL LETTER SIDEWAYS DIAERESIZED U", + direction="l", + linebreak="al", + unicodeslot=0x1D1E, + }, + [0x1D1F]={ + category="ll", + description="LATIN SMALL LETTER SIDEWAYS TURNED M", + direction="l", + linebreak="al", + unicodeslot=0x1D1F, + }, + [0x1D20]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL V", + direction="l", + linebreak="al", + unicodeslot=0x1D20, + }, + [0x1D21]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL W", + direction="l", + linebreak="al", + unicodeslot=0x1D21, + }, + [0x1D22]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL Z", + direction="l", + linebreak="al", + unicodeslot=0x1D22, + }, + [0x1D23]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL EZH", + direction="l", + linebreak="al", + unicodeslot=0x1D23, + }, + [0x1D24]={ + category="ll", + description="LATIN LETTER VOICED LARYNGEAL SPIRANT", + direction="l", + linebreak="al", + unicodeslot=0x1D24, + }, + [0x1D25]={ + category="ll", + description="LATIN LETTER AIN", + direction="l", + linebreak="al", + unicodeslot=0x1D25, + }, + [0x1D26]={ + category="ll", + description="GREEK LETTER SMALL CAPITAL GAMMA", + direction="l", + linebreak="al", + unicodeslot=0x1D26, + }, + [0x1D27]={ + category="ll", + description="GREEK LETTER SMALL CAPITAL LAMDA", + direction="l", + linebreak="al", + unicodeslot=0x1D27, + }, + [0x1D28]={ + category="ll", + description="GREEK LETTER SMALL CAPITAL PI", + direction="l", + linebreak="al", + unicodeslot=0x1D28, + }, + [0x1D29]={ + category="ll", + description="GREEK LETTER SMALL CAPITAL RHO", + direction="l", + linebreak="al", + unicodeslot=0x1D29, + }, + [0x1D2A]={ + category="ll", + description="GREEK LETTER SMALL CAPITAL PSI", + direction="l", + linebreak="al", + unicodeslot=0x1D2A, + }, + [0x1D2B]={ + category="ll", + description="CYRILLIC LETTER SMALL CAPITAL EL", + direction="l", + linebreak="al", + unicodeslot=0x1D2B, + }, + [0x1D2C]={ + category="lm", + description="MODIFIER LETTER CAPITAL A", + direction="l", + linebreak="al", + specials={ "super", 0x0041 }, + unicodeslot=0x1D2C, + }, + [0x1D2D]={ + category="lm", + description="MODIFIER LETTER CAPITAL AE", + direction="l", + linebreak="al", + specials={ "super", 0x00C6 }, + unicodeslot=0x1D2D, + }, + [0x1D2E]={ + category="lm", + description="MODIFIER LETTER CAPITAL B", + direction="l", + linebreak="al", + specials={ "super", 0x0042 }, + unicodeslot=0x1D2E, + }, + [0x1D2F]={ + category="lm", + description="MODIFIER LETTER CAPITAL BARRED B", + direction="l", + linebreak="al", + unicodeslot=0x1D2F, + }, + [0x1D30]={ + category="lm", + description="MODIFIER LETTER CAPITAL D", + direction="l", + linebreak="al", + specials={ "super", 0x0044 }, + unicodeslot=0x1D30, + }, + [0x1D31]={ + category="lm", + description="MODIFIER LETTER CAPITAL E", + direction="l", + linebreak="al", + specials={ "super", 0x0045 }, + unicodeslot=0x1D31, + }, + [0x1D32]={ + category="lm", + description="MODIFIER LETTER CAPITAL REVERSED E", + direction="l", + linebreak="al", + specials={ "super", 0x018E }, + unicodeslot=0x1D32, + }, + [0x1D33]={ + category="lm", + description="MODIFIER LETTER CAPITAL G", + direction="l", + linebreak="al", + specials={ "super", 0x0047 }, + unicodeslot=0x1D33, + }, + [0x1D34]={ + category="lm", + description="MODIFIER LETTER CAPITAL H", + direction="l", + linebreak="al", + specials={ "super", 0x0048 }, + unicodeslot=0x1D34, + }, + [0x1D35]={ + category="lm", + description="MODIFIER LETTER CAPITAL I", + direction="l", + linebreak="al", + specials={ "super", 0x0049 }, + unicodeslot=0x1D35, + }, + [0x1D36]={ + category="lm", + description="MODIFIER LETTER CAPITAL J", + direction="l", + linebreak="al", + specials={ "super", 0x004A }, + unicodeslot=0x1D36, + }, + [0x1D37]={ + category="lm", + description="MODIFIER LETTER CAPITAL K", + direction="l", + linebreak="al", + specials={ "super", 0x004B }, + unicodeslot=0x1D37, + }, + [0x1D38]={ + category="lm", + description="MODIFIER LETTER CAPITAL L", + direction="l", + linebreak="al", + specials={ "super", 0x004C }, + unicodeslot=0x1D38, + }, + [0x1D39]={ + category="lm", + description="MODIFIER LETTER CAPITAL M", + direction="l", + linebreak="al", + specials={ "super", 0x004D }, + unicodeslot=0x1D39, + }, + [0x1D3A]={ + category="lm", + description="MODIFIER LETTER CAPITAL N", + direction="l", + linebreak="al", + specials={ "super", 0x004E }, + unicodeslot=0x1D3A, + }, + [0x1D3B]={ + category="lm", + description="MODIFIER LETTER CAPITAL REVERSED N", + direction="l", + linebreak="al", + unicodeslot=0x1D3B, + }, + [0x1D3C]={ + category="lm", + description="MODIFIER LETTER CAPITAL O", + direction="l", + linebreak="al", + specials={ "super", 0x004F }, + unicodeslot=0x1D3C, + }, + [0x1D3D]={ + category="lm", + description="MODIFIER LETTER CAPITAL OU", + direction="l", + linebreak="al", + specials={ "super", 0x0222 }, + unicodeslot=0x1D3D, + }, + [0x1D3E]={ + category="lm", + description="MODIFIER LETTER CAPITAL P", + direction="l", + linebreak="al", + specials={ "super", 0x0050 }, + unicodeslot=0x1D3E, + }, + [0x1D3F]={ + category="lm", + description="MODIFIER LETTER CAPITAL R", + direction="l", + linebreak="al", + specials={ "super", 0x0052 }, + unicodeslot=0x1D3F, + }, + [0x1D40]={ + category="lm", + description="MODIFIER LETTER CAPITAL T", + direction="l", + linebreak="al", + specials={ "super", 0x0054 }, + unicodeslot=0x1D40, + }, + [0x1D41]={ + category="lm", + description="MODIFIER LETTER CAPITAL U", + direction="l", + linebreak="al", + specials={ "super", 0x0055 }, + unicodeslot=0x1D41, + }, + [0x1D42]={ + category="lm", + description="MODIFIER LETTER CAPITAL W", + direction="l", + linebreak="al", + specials={ "super", 0x0057 }, + unicodeslot=0x1D42, + }, + [0x1D43]={ + category="lm", + description="MODIFIER LETTER SMALL A", + direction="l", + linebreak="al", + specials={ "super", 0x0061 }, + unicodeslot=0x1D43, + }, + [0x1D44]={ + category="lm", + description="MODIFIER LETTER SMALL TURNED A", + direction="l", + linebreak="al", + specials={ "super", 0x0250 }, + unicodeslot=0x1D44, + }, + [0x1D45]={ + category="lm", + description="MODIFIER LETTER SMALL ALPHA", + direction="l", + linebreak="al", + specials={ "super", 0x0251 }, + unicodeslot=0x1D45, + }, + [0x1D46]={ + category="lm", + description="MODIFIER LETTER SMALL TURNED AE", + direction="l", + linebreak="al", + specials={ "super", 0x1D02 }, + unicodeslot=0x1D46, + }, + [0x1D47]={ + category="lm", + description="MODIFIER LETTER SMALL B", + direction="l", + linebreak="al", + specials={ "super", 0x0062 }, + unicodeslot=0x1D47, + }, + [0x1D48]={ + category="lm", + description="MODIFIER LETTER SMALL D", + direction="l", + linebreak="al", + specials={ "super", 0x0064 }, + unicodeslot=0x1D48, + }, + [0x1D49]={ + category="lm", + description="MODIFIER LETTER SMALL E", + direction="l", + linebreak="al", + specials={ "super", 0x0065 }, + unicodeslot=0x1D49, + }, + [0x1D4A]={ + category="lm", + description="MODIFIER LETTER SMALL SCHWA", + direction="l", + linebreak="al", + specials={ "super", 0x0259 }, + unicodeslot=0x1D4A, + }, + [0x1D4B]={ + category="lm", + description="MODIFIER LETTER SMALL OPEN E", + direction="l", + linebreak="al", + specials={ "super", 0x025B }, + unicodeslot=0x1D4B, + }, + [0x1D4C]={ + category="lm", + description="MODIFIER LETTER SMALL TURNED OPEN E", + direction="l", + linebreak="al", + specials={ "super", 0x025C }, + unicodeslot=0x1D4C, + }, + [0x1D4D]={ + category="lm", + description="MODIFIER LETTER SMALL G", + direction="l", + linebreak="al", + specials={ "super", 0x0067 }, + unicodeslot=0x1D4D, + }, + [0x1D4E]={ + category="lm", + description="MODIFIER LETTER SMALL TURNED I", + direction="l", + linebreak="al", + unicodeslot=0x1D4E, + }, + [0x1D4F]={ + category="lm", + description="MODIFIER LETTER SMALL K", + direction="l", + linebreak="al", + specials={ "super", 0x006B }, + unicodeslot=0x1D4F, + }, + [0x1D50]={ + category="lm", + description="MODIFIER LETTER SMALL M", + direction="l", + linebreak="al", + specials={ "super", 0x006D }, + unicodeslot=0x1D50, + }, + [0x1D51]={ + category="lm", + description="MODIFIER LETTER SMALL ENG", + direction="l", + linebreak="al", + specials={ "super", 0x014B }, + unicodeslot=0x1D51, + }, + [0x1D52]={ + category="lm", + description="MODIFIER LETTER SMALL O", + direction="l", + linebreak="al", + specials={ "super", 0x006F }, + unicodeslot=0x1D52, + }, + [0x1D53]={ + category="lm", + description="MODIFIER LETTER SMALL OPEN O", + direction="l", + linebreak="al", + specials={ "super", 0x0254 }, + unicodeslot=0x1D53, + }, + [0x1D54]={ + category="lm", + description="MODIFIER LETTER SMALL TOP HALF O", + direction="l", + linebreak="al", + specials={ "super", 0x1D16 }, + unicodeslot=0x1D54, + }, + [0x1D55]={ + category="lm", + description="MODIFIER LETTER SMALL BOTTOM HALF O", + direction="l", + linebreak="al", + specials={ "super", 0x1D17 }, + unicodeslot=0x1D55, + }, + [0x1D56]={ + category="lm", + description="MODIFIER LETTER SMALL P", + direction="l", + linebreak="al", + specials={ "super", 0x0070 }, + unicodeslot=0x1D56, + }, + [0x1D57]={ + category="lm", + description="MODIFIER LETTER SMALL T", + direction="l", + linebreak="al", + specials={ "super", 0x0074 }, + unicodeslot=0x1D57, + }, + [0x1D58]={ + category="lm", + description="MODIFIER LETTER SMALL U", + direction="l", + linebreak="al", + specials={ "super", 0x0075 }, + unicodeslot=0x1D58, + }, + [0x1D59]={ + category="lm", + description="MODIFIER LETTER SMALL SIDEWAYS U", + direction="l", + linebreak="al", + specials={ "super", 0x1D1D }, + unicodeslot=0x1D59, + }, + [0x1D5A]={ + category="lm", + description="MODIFIER LETTER SMALL TURNED M", + direction="l", + linebreak="al", + specials={ "super", 0x026F }, + unicodeslot=0x1D5A, + }, + [0x1D5B]={ + category="lm", + description="MODIFIER LETTER SMALL V", + direction="l", + linebreak="al", + specials={ "super", 0x0076 }, + unicodeslot=0x1D5B, + }, + [0x1D5C]={ + category="lm", + description="MODIFIER LETTER SMALL AIN", + direction="l", + linebreak="al", + specials={ "super", 0x1D25 }, + unicodeslot=0x1D5C, + }, + [0x1D5D]={ + category="lm", + description="MODIFIER LETTER SMALL BETA", + direction="l", + linebreak="al", + specials={ "super", 0x03B2 }, + unicodeslot=0x1D5D, + }, + [0x1D5E]={ + category="lm", + description="MODIFIER LETTER SMALL GREEK GAMMA", + direction="l", + linebreak="al", + specials={ "super", 0x03B3 }, + unicodeslot=0x1D5E, + }, + [0x1D5F]={ + category="lm", + description="MODIFIER LETTER SMALL DELTA", + direction="l", + linebreak="al", + specials={ "super", 0x03B4 }, + unicodeslot=0x1D5F, + }, + [0x1D60]={ + category="lm", + description="MODIFIER LETTER SMALL GREEK PHI", + direction="l", + linebreak="al", + specials={ "super", 0x03C6 }, + unicodeslot=0x1D60, + }, + [0x1D61]={ + category="lm", + description="MODIFIER LETTER SMALL CHI", + direction="l", + linebreak="al", + specials={ "super", 0x03C7 }, + unicodeslot=0x1D61, + }, + [0x1D62]={ + category="ll", + description="LATIN SUBSCRIPT SMALL LETTER I", + direction="l", + linebreak="al", + specials={ "sub", 0x0069 }, + unicodeslot=0x1D62, + }, + [0x1D63]={ + category="ll", + description="LATIN SUBSCRIPT SMALL LETTER R", + direction="l", + linebreak="al", + specials={ "sub", 0x0072 }, + unicodeslot=0x1D63, + }, + [0x1D64]={ + category="ll", + description="LATIN SUBSCRIPT SMALL LETTER U", + direction="l", + linebreak="al", + specials={ "sub", 0x0075 }, + unicodeslot=0x1D64, + }, + [0x1D65]={ + category="ll", + description="LATIN SUBSCRIPT SMALL LETTER V", + direction="l", + linebreak="al", + specials={ "sub", 0x0076 }, + unicodeslot=0x1D65, + }, + [0x1D66]={ + category="ll", + description="GREEK SUBSCRIPT SMALL LETTER BETA", + direction="l", + linebreak="al", + specials={ "sub", 0x03B2 }, + unicodeslot=0x1D66, + }, + [0x1D67]={ + category="ll", + description="GREEK SUBSCRIPT SMALL LETTER GAMMA", + direction="l", + linebreak="al", + specials={ "sub", 0x03B3 }, + unicodeslot=0x1D67, + }, + [0x1D68]={ + category="ll", + description="GREEK SUBSCRIPT SMALL LETTER RHO", + direction="l", + linebreak="al", + specials={ "sub", 0x03C1 }, + unicodeslot=0x1D68, + }, + [0x1D69]={ + category="ll", + description="GREEK SUBSCRIPT SMALL LETTER PHI", + direction="l", + linebreak="al", + specials={ "sub", 0x03C6 }, + unicodeslot=0x1D69, + }, + [0x1D6A]={ + category="ll", + description="GREEK SUBSCRIPT SMALL LETTER CHI", + direction="l", + linebreak="al", + specials={ "sub", 0x03C7 }, + unicodeslot=0x1D6A, + }, + [0x1D6B]={ + category="ll", + description="LATIN SMALL LETTER UE", + direction="l", + linebreak="al", + unicodeslot=0x1D6B, + }, + [0x1D6C]={ + category="ll", + description="LATIN SMALL LETTER B WITH MIDDLE TILDE", + direction="l", + linebreak="al", + shcode=0x0062, + unicodeslot=0x1D6C, + }, + [0x1D6D]={ + category="ll", + description="LATIN SMALL LETTER D WITH MIDDLE TILDE", + direction="l", + linebreak="al", + shcode=0x0064, + unicodeslot=0x1D6D, + }, + [0x1D6E]={ + category="ll", + description="LATIN SMALL LETTER F WITH MIDDLE TILDE", + direction="l", + linebreak="al", + shcode=0x0066, + unicodeslot=0x1D6E, + }, + [0x1D6F]={ + category="ll", + description="LATIN SMALL LETTER M WITH MIDDLE TILDE", + direction="l", + linebreak="al", + shcode=0x006D, + unicodeslot=0x1D6F, + }, + [0x1D70]={ + category="ll", + description="LATIN SMALL LETTER N WITH MIDDLE TILDE", + direction="l", + linebreak="al", + shcode=0x006E, + unicodeslot=0x1D70, + }, + [0x1D71]={ + category="ll", + description="LATIN SMALL LETTER P WITH MIDDLE TILDE", + direction="l", + linebreak="al", + shcode=0x0070, + unicodeslot=0x1D71, + }, + [0x1D72]={ + category="ll", + description="LATIN SMALL LETTER R WITH MIDDLE TILDE", + direction="l", + linebreak="al", + shcode=0x0072, + unicodeslot=0x1D72, + }, + [0x1D73]={ + category="ll", + description="LATIN SMALL LETTER R WITH FISHHOOK AND MIDDLE TILDE", + direction="l", + linebreak="al", + shcode=0x0072, + unicodeslot=0x1D73, + }, + [0x1D74]={ + category="ll", + description="LATIN SMALL LETTER S WITH MIDDLE TILDE", + direction="l", + linebreak="al", + shcode=0x0073, + unicodeslot=0x1D74, + }, + [0x1D75]={ + category="ll", + description="LATIN SMALL LETTER T WITH MIDDLE TILDE", + direction="l", + linebreak="al", + shcode=0x0074, + unicodeslot=0x1D75, + }, + [0x1D76]={ + category="ll", + description="LATIN SMALL LETTER Z WITH MIDDLE TILDE", + direction="l", + linebreak="al", + shcode=0x007A, + unicodeslot=0x1D76, + }, + [0x1D77]={ + category="ll", + description="LATIN SMALL LETTER TURNED G", + direction="l", + linebreak="al", + unicodeslot=0x1D77, + }, + [0x1D78]={ + category="lm", + description="MODIFIER LETTER CYRILLIC EN", + direction="l", + linebreak="al", + specials={ "super", 0x043D }, + unicodeslot=0x1D78, + }, + [0x1D79]={ + category="ll", + description="LATIN SMALL LETTER INSULAR G", + direction="l", + linebreak="al", + unicodeslot=0x1D79, + }, + [0x1D7A]={ + category="ll", + description="LATIN SMALL LETTER TH WITH STRIKETHROUGH", + direction="l", + linebreak="al", + unicodeslot=0x1D7A, + }, + [0x1D7B]={ + category="ll", + description="LATIN SMALL CAPITAL LETTER I WITH STROKE", + direction="l", + linebreak="al", + unicodeslot=0x1D7B, + }, + [0x1D7C]={ + category="ll", + description="LATIN SMALL LETTER IOTA WITH STROKE", + direction="l", + linebreak="al", + shcode=0x0269, + unicodeslot=0x1D7C, + }, + [0x1D7D]={ + category="ll", + description="LATIN SMALL LETTER P WITH STROKE", + direction="l", + linebreak="al", + shcode=0x0070, + uccode=0x2C63, + unicodeslot=0x1D7D, + }, + [0x1D7E]={ + category="ll", + description="LATIN SMALL CAPITAL LETTER U WITH STROKE", + direction="l", + linebreak="al", + unicodeslot=0x1D7E, + }, + [0x1D7F]={ + category="ll", + description="LATIN SMALL LETTER UPSILON WITH STROKE", + direction="l", + linebreak="al", + shcode=0x028A, + unicodeslot=0x1D7F, + }, + [0x1D80]={ + category="ll", + description="LATIN SMALL LETTER B WITH PALATAL HOOK", + direction="l", + linebreak="al", + shcode=0x0062, + unicodeslot=0x1D80, + }, + [0x1D81]={ + category="ll", + description="LATIN SMALL LETTER D WITH PALATAL HOOK", + direction="l", + linebreak="al", + shcode=0x0064, + unicodeslot=0x1D81, + }, + [0x1D82]={ + category="ll", + description="LATIN SMALL LETTER F WITH PALATAL HOOK", + direction="l", + linebreak="al", + shcode=0x0066, + unicodeslot=0x1D82, + }, + [0x1D83]={ + category="ll", + description="LATIN SMALL LETTER G WITH PALATAL HOOK", + direction="l", + linebreak="al", + shcode=0x0067, + unicodeslot=0x1D83, + }, + [0x1D84]={ + category="ll", + description="LATIN SMALL LETTER K WITH PALATAL HOOK", + direction="l", + linebreak="al", + shcode=0x006B, + unicodeslot=0x1D84, + }, + [0x1D85]={ + category="ll", + description="LATIN SMALL LETTER L WITH PALATAL HOOK", + direction="l", + linebreak="al", + shcode=0x006C, + unicodeslot=0x1D85, + }, + [0x1D86]={ + category="ll", + description="LATIN SMALL LETTER M WITH PALATAL HOOK", + direction="l", + linebreak="al", + shcode=0x006D, + unicodeslot=0x1D86, + }, + [0x1D87]={ + category="ll", + description="LATIN SMALL LETTER N WITH PALATAL HOOK", + direction="l", + linebreak="al", + shcode=0x006E, + unicodeslot=0x1D87, + }, + [0x1D88]={ + category="ll", + description="LATIN SMALL LETTER P WITH PALATAL HOOK", + direction="l", + linebreak="al", + shcode=0x0070, + unicodeslot=0x1D88, + }, + [0x1D89]={ + category="ll", + description="LATIN SMALL LETTER R WITH PALATAL HOOK", + direction="l", + linebreak="al", + shcode=0x0072, + unicodeslot=0x1D89, + }, + [0x1D8A]={ + category="ll", + description="LATIN SMALL LETTER S WITH PALATAL HOOK", + direction="l", + linebreak="al", + shcode=0x0073, + unicodeslot=0x1D8A, + }, + [0x1D8B]={ + category="ll", + description="LATIN SMALL LETTER ESH WITH PALATAL HOOK", + direction="l", + linebreak="al", + shcode=0x0283, + unicodeslot=0x1D8B, + }, + [0x1D8C]={ + category="ll", + description="LATIN SMALL LETTER V WITH PALATAL HOOK", + direction="l", + linebreak="al", + shcode=0x0076, + unicodeslot=0x1D8C, + }, + [0x1D8D]={ + category="ll", + description="LATIN SMALL LETTER X WITH PALATAL HOOK", + direction="l", + linebreak="al", + shcode=0x0078, + unicodeslot=0x1D8D, + }, + [0x1D8E]={ + category="ll", + description="LATIN SMALL LETTER Z WITH PALATAL HOOK", + direction="l", + linebreak="al", + shcode=0x007A, + unicodeslot=0x1D8E, + }, + [0x1D8F]={ + category="ll", + description="LATIN SMALL LETTER A WITH RETROFLEX HOOK", + direction="l", + linebreak="al", + shcode=0x0061, + unicodeslot=0x1D8F, + }, + [0x1D90]={ + category="ll", + description="LATIN SMALL LETTER ALPHA WITH RETROFLEX HOOK", + direction="l", + linebreak="al", + shcode=0x0251, + unicodeslot=0x1D90, + }, + [0x1D91]={ + category="ll", + description="LATIN SMALL LETTER D WITH HOOK AND TAIL", + direction="l", + linebreak="al", + shcode=0x0064, + unicodeslot=0x1D91, + }, + [0x1D92]={ + category="ll", + description="LATIN SMALL LETTER E WITH RETROFLEX HOOK", + direction="l", + linebreak="al", + shcode=0x0065, + unicodeslot=0x1D92, + }, + [0x1D93]={ + category="ll", + description="LATIN SMALL LETTER OPEN E WITH RETROFLEX HOOK", + direction="l", + linebreak="al", + unicodeslot=0x1D93, + }, + [0x1D94]={ + category="ll", + description="LATIN SMALL LETTER REVERSED OPEN E WITH RETROFLEX HOOK", + direction="l", + linebreak="al", + unicodeslot=0x1D94, + }, + [0x1D95]={ + category="ll", + description="LATIN SMALL LETTER SCHWA WITH RETROFLEX HOOK", + direction="l", + linebreak="al", + shcode=0x0259, + unicodeslot=0x1D95, + }, + [0x1D96]={ + category="ll", + description="LATIN SMALL LETTER I WITH RETROFLEX HOOK", + direction="l", + linebreak="al", + shcode=0x0069, + unicodeslot=0x1D96, + }, + [0x1D97]={ + category="ll", + description="LATIN SMALL LETTER OPEN O WITH RETROFLEX HOOK", + direction="l", + linebreak="al", + unicodeslot=0x1D97, + }, + [0x1D98]={ + category="ll", + description="LATIN SMALL LETTER ESH WITH RETROFLEX HOOK", + direction="l", + linebreak="al", + shcode=0x0283, + unicodeslot=0x1D98, + }, + [0x1D99]={ + category="ll", + description="LATIN SMALL LETTER U WITH RETROFLEX HOOK", + direction="l", + linebreak="al", + shcode=0x0075, + unicodeslot=0x1D99, + }, + [0x1D9A]={ + category="ll", + description="LATIN SMALL LETTER EZH WITH RETROFLEX HOOK", + direction="l", + linebreak="al", + shcode=0x0292, + unicodeslot=0x1D9A, + }, + [0x1D9B]={ + category="lm", + description="MODIFIER LETTER SMALL TURNED ALPHA", + direction="l", + linebreak="al", + specials={ "super", 0x0252 }, + unicodeslot=0x1D9B, + }, + [0x1D9C]={ + category="lm", + description="MODIFIER LETTER SMALL C", + direction="l", + linebreak="al", + specials={ "super", 0x0063 }, + unicodeslot=0x1D9C, + }, + [0x1D9D]={ + category="lm", + description="MODIFIER LETTER SMALL C WITH CURL", + direction="l", + linebreak="al", + specials={ "super", 0x0255 }, + unicodeslot=0x1D9D, + }, + [0x1D9E]={ + category="lm", + description="MODIFIER LETTER SMALL ETH", + direction="l", + linebreak="al", + specials={ "super", 0x00F0 }, + unicodeslot=0x1D9E, + }, + [0x1D9F]={ + category="lm", + description="MODIFIER LETTER SMALL REVERSED OPEN E", + direction="l", + linebreak="al", + specials={ "super", 0x025C }, + unicodeslot=0x1D9F, + }, + [0x1DA0]={ + category="lm", + description="MODIFIER LETTER SMALL F", + direction="l", + linebreak="al", + specials={ "super", 0x0066 }, + unicodeslot=0x1DA0, + }, + [0x1DA1]={ + category="lm", + description="MODIFIER LETTER SMALL DOTLESS J WITH STROKE", + direction="l", + linebreak="al", + specials={ "super", 0x025F }, + unicodeslot=0x1DA1, + }, + [0x1DA2]={ + category="lm", + description="MODIFIER LETTER SMALL SCRIPT G", + direction="l", + linebreak="al", + specials={ "super", 0x0261 }, + unicodeslot=0x1DA2, + }, + [0x1DA3]={ + category="lm", + description="MODIFIER LETTER SMALL TURNED H", + direction="l", + linebreak="al", + specials={ "super", 0x0265 }, + unicodeslot=0x1DA3, + }, + [0x1DA4]={ + category="lm", + description="MODIFIER LETTER SMALL I WITH STROKE", + direction="l", + linebreak="al", + specials={ "super", 0x0268 }, + unicodeslot=0x1DA4, + }, + [0x1DA5]={ + category="lm", + description="MODIFIER LETTER SMALL IOTA", + direction="l", + linebreak="al", + specials={ "super", 0x0269 }, + unicodeslot=0x1DA5, + }, + [0x1DA6]={ + category="lm", + description="MODIFIER LETTER SMALL CAPITAL I", + direction="l", + linebreak="al", + specials={ "super", 0x026A }, + unicodeslot=0x1DA6, + }, + [0x1DA7]={ + category="lm", + description="MODIFIER LETTER SMALL CAPITAL I WITH STROKE", + direction="l", + linebreak="al", + specials={ "super", 0x1D7B }, + unicodeslot=0x1DA7, + }, + [0x1DA8]={ + category="lm", + description="MODIFIER LETTER SMALL J WITH CROSSED-TAIL", + direction="l", + linebreak="al", + specials={ "super", 0x029D }, + unicodeslot=0x1DA8, + }, + [0x1DA9]={ + category="lm", + description="MODIFIER LETTER SMALL L WITH RETROFLEX HOOK", + direction="l", + linebreak="al", + specials={ "super", 0x026D }, + unicodeslot=0x1DA9, + }, + [0x1DAA]={ + category="lm", + description="MODIFIER LETTER SMALL L WITH PALATAL HOOK", + direction="l", + linebreak="al", + specials={ "super", 0x1D85 }, + unicodeslot=0x1DAA, + }, + [0x1DAB]={ + category="lm", + description="MODIFIER LETTER SMALL CAPITAL L", + direction="l", + linebreak="al", + specials={ "super", 0x029F }, + unicodeslot=0x1DAB, + }, + [0x1DAC]={ + category="lm", + description="MODIFIER LETTER SMALL M WITH HOOK", + direction="l", + linebreak="al", + specials={ "super", 0x0271 }, + unicodeslot=0x1DAC, + }, + [0x1DAD]={ + category="lm", + description="MODIFIER LETTER SMALL TURNED M WITH LONG LEG", + direction="l", + linebreak="al", + specials={ "super", 0x0270 }, + unicodeslot=0x1DAD, + }, + [0x1DAE]={ + category="lm", + description="MODIFIER LETTER SMALL N WITH LEFT HOOK", + direction="l", + linebreak="al", + specials={ "super", 0x0272 }, + unicodeslot=0x1DAE, + }, + [0x1DAF]={ + category="lm", + description="MODIFIER LETTER SMALL N WITH RETROFLEX HOOK", + direction="l", + linebreak="al", + specials={ "super", 0x0273 }, + unicodeslot=0x1DAF, + }, + [0x1DB0]={ + category="lm", + description="MODIFIER LETTER SMALL CAPITAL N", + direction="l", + linebreak="al", + specials={ "super", 0x0274 }, + unicodeslot=0x1DB0, + }, + [0x1DB1]={ + category="lm", + description="MODIFIER LETTER SMALL BARRED O", + direction="l", + linebreak="al", + specials={ "super", 0x0275 }, + unicodeslot=0x1DB1, + }, + [0x1DB2]={ + category="lm", + description="MODIFIER LETTER SMALL PHI", + direction="l", + linebreak="al", + specials={ "super", 0x0278 }, + unicodeslot=0x1DB2, + }, + [0x1DB3]={ + category="lm", + description="MODIFIER LETTER SMALL S WITH HOOK", + direction="l", + linebreak="al", + specials={ "super", 0x0282 }, + unicodeslot=0x1DB3, + }, + [0x1DB4]={ + category="lm", + description="MODIFIER LETTER SMALL ESH", + direction="l", + linebreak="al", + specials={ "super", 0x0283 }, + unicodeslot=0x1DB4, + }, + [0x1DB5]={ + category="lm", + description="MODIFIER LETTER SMALL T WITH PALATAL HOOK", + direction="l", + linebreak="al", + specials={ "super", 0x01AB }, + unicodeslot=0x1DB5, + }, + [0x1DB6]={ + category="lm", + description="MODIFIER LETTER SMALL U BAR", + direction="l", + linebreak="al", + specials={ "super", 0x0289 }, + unicodeslot=0x1DB6, + }, + [0x1DB7]={ + category="lm", + description="MODIFIER LETTER SMALL UPSILON", + direction="l", + linebreak="al", + specials={ "super", 0x028A }, + unicodeslot=0x1DB7, + }, + [0x1DB8]={ + category="lm", + description="MODIFIER LETTER SMALL CAPITAL U", + direction="l", + linebreak="al", + specials={ "super", 0x1D1C }, + unicodeslot=0x1DB8, + }, + [0x1DB9]={ + category="lm", + description="MODIFIER LETTER SMALL V WITH HOOK", + direction="l", + linebreak="al", + specials={ "super", 0x028B }, + unicodeslot=0x1DB9, + }, + [0x1DBA]={ + category="lm", + description="MODIFIER LETTER SMALL TURNED V", + direction="l", + linebreak="al", + specials={ "super", 0x028C }, + unicodeslot=0x1DBA, + }, + [0x1DBB]={ + category="lm", + description="MODIFIER LETTER SMALL Z", + direction="l", + linebreak="al", + specials={ "super", 0x007A }, + unicodeslot=0x1DBB, + }, + [0x1DBC]={ + category="lm", + description="MODIFIER LETTER SMALL Z WITH RETROFLEX HOOK", + direction="l", + linebreak="al", + specials={ "super", 0x0290 }, + unicodeslot=0x1DBC, + }, + [0x1DBD]={ + category="lm", + description="MODIFIER LETTER SMALL Z WITH CURL", + direction="l", + linebreak="al", + specials={ "super", 0x0291 }, + unicodeslot=0x1DBD, + }, + [0x1DBE]={ + category="lm", + description="MODIFIER LETTER SMALL EZH", + direction="l", + linebreak="al", + specials={ "super", 0x0292 }, + unicodeslot=0x1DBE, + }, + [0x1DBF]={ + category="lm", + description="MODIFIER LETTER SMALL THETA", + direction="l", + linebreak="al", + specials={ "super", 0x03B8 }, + unicodeslot=0x1DBF, + }, + [0x1DC0]={ + category="mn", + description="COMBINING DOTTED GRAVE ACCENT", + direction="nsm", + linebreak="cm", + unicodeslot=0x1DC0, + }, + [0x1DC1]={ + category="mn", + description="COMBINING DOTTED ACUTE ACCENT", + direction="nsm", + linebreak="cm", + unicodeslot=0x1DC1, + }, + [0x1DC2]={ + category="mn", + description="COMBINING SNAKE BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x1DC2, + }, + [0x1DC3]={ + category="mn", + description="COMBINING SUSPENSION MARK", + direction="nsm", + linebreak="cm", + unicodeslot=0x1DC3, + }, + [0x1DC4]={ + category="mn", + description="COMBINING MACRON-ACUTE", + direction="nsm", + linebreak="cm", + unicodeslot=0x1DC4, + }, + [0x1DC5]={ + category="mn", + description="COMBINING GRAVE-MACRON", + direction="nsm", + linebreak="cm", + unicodeslot=0x1DC5, + }, + [0x1DC6]={ + category="mn", + description="COMBINING MACRON-GRAVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x1DC6, + }, + [0x1DC7]={ + category="mn", + description="COMBINING ACUTE-MACRON", + direction="nsm", + linebreak="cm", + unicodeslot=0x1DC7, + }, + [0x1DC8]={ + category="mn", + description="COMBINING GRAVE-ACUTE-GRAVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x1DC8, + }, + [0x1DC9]={ + category="mn", + description="COMBINING ACUTE-GRAVE-ACUTE", + direction="nsm", + linebreak="cm", + unicodeslot=0x1DC9, + }, + [0x1DCA]={ + category="mn", + description="COMBINING LATIN SMALL LETTER R BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x1DCA, + }, + [0x1DFE]={ + category="mn", + description="COMBINING LEFT ARROWHEAD ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x1DFE, + }, + [0x1DFF]={ + category="mn", + description="COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x1DFF, + }, + [0x1E00]={ + category="lu", + description="LATIN CAPITAL LETTER A WITH RING BELOW", + direction="l", + lccode=0x1E01, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x0041, 0x0325 }, + unicodeslot=0x1E00, + }, + [0x1E01]={ + category="ll", + description="LATIN SMALL LETTER A WITH RING BELOW", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x0061, 0x0325 }, + uccode=0x1E00, + unicodeslot=0x1E01, + }, + [0x1E02]={ + category="lu", + description="LATIN CAPITAL LETTER B WITH DOT ABOVE", + direction="l", + lccode=0x1E03, + linebreak="al", + shcode=0x0042, + specials={ "char", 0x0042, 0x0307 }, + unicodeslot=0x1E02, + }, + [0x1E03]={ + category="ll", + description="LATIN SMALL LETTER B WITH DOT ABOVE", + direction="l", + linebreak="al", + shcode=0x0062, + specials={ "char", 0x0062, 0x0307 }, + uccode=0x1E02, + unicodeslot=0x1E03, + }, + [0x1E04]={ + category="lu", + description="LATIN CAPITAL LETTER B WITH DOT BELOW", + direction="l", + lccode=0x1E05, + linebreak="al", + shcode=0x0042, + specials={ "char", 0x0042, 0x0323 }, + unicodeslot=0x1E04, + }, + [0x1E05]={ + category="ll", + description="LATIN SMALL LETTER B WITH DOT BELOW", + direction="l", + linebreak="al", + shcode=0x0062, + specials={ "char", 0x0062, 0x0323 }, + uccode=0x1E04, + unicodeslot=0x1E05, + }, + [0x1E06]={ + category="lu", + description="LATIN CAPITAL LETTER B WITH LINE BELOW", + direction="l", + lccode=0x1E07, + linebreak="al", + shcode=0x0042, + specials={ "char", 0x0042, 0x0331 }, + unicodeslot=0x1E06, + }, + [0x1E07]={ + category="ll", + description="LATIN SMALL LETTER B WITH LINE BELOW", + direction="l", + linebreak="al", + shcode=0x0062, + specials={ "char", 0x0062, 0x0331 }, + uccode=0x1E06, + unicodeslot=0x1E07, + }, + [0x1E08]={ + category="lu", + description="LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE", + direction="l", + lccode=0x1E09, + linebreak="al", + shcode=0x0043, + specials={ "char", 0x00C7, 0x0301 }, + unicodeslot=0x1E08, + }, + [0x1E09]={ + category="ll", + description="LATIN SMALL LETTER C WITH CEDILLA AND ACUTE", + direction="l", + linebreak="al", + shcode=0x0063, + specials={ "char", 0x00E7, 0x0301 }, + uccode=0x1E08, + unicodeslot=0x1E09, + }, + [0x1E0A]={ + category="lu", + description="LATIN CAPITAL LETTER D WITH DOT ABOVE", + direction="l", + lccode=0x1E0B, + linebreak="al", + shcode=0x0044, + specials={ "char", 0x0044, 0x0307 }, + unicodeslot=0x1E0A, + }, + [0x1E0B]={ + category="ll", + description="LATIN SMALL LETTER D WITH DOT ABOVE", + direction="l", + linebreak="al", + shcode=0x0064, + specials={ "char", 0x0064, 0x0307 }, + uccode=0x1E0A, + unicodeslot=0x1E0B, + }, + [0x1E0C]={ + category="lu", + description="LATIN CAPITAL LETTER D WITH DOT BELOW", + direction="l", + lccode=0x1E0D, + linebreak="al", + shcode=0x0044, + specials={ "char", 0x0044, 0x0323 }, + unicodeslot=0x1E0C, + }, + [0x1E0D]={ + category="ll", + description="LATIN SMALL LETTER D WITH DOT BELOW", + direction="l", + linebreak="al", + shcode=0x0064, + specials={ "char", 0x0064, 0x0323 }, + uccode=0x1E0C, + unicodeslot=0x1E0D, + }, + [0x1E0E]={ + category="lu", + description="LATIN CAPITAL LETTER D WITH LINE BELOW", + direction="l", + lccode=0x1E0F, + linebreak="al", + shcode=0x0044, + specials={ "char", 0x0044, 0x0331 }, + unicodeslot=0x1E0E, + }, + [0x1E0F]={ + category="ll", + description="LATIN SMALL LETTER D WITH LINE BELOW", + direction="l", + linebreak="al", + shcode=0x0064, + specials={ "char", 0x0064, 0x0331 }, + uccode=0x1E0E, + unicodeslot=0x1E0F, + }, + [0x1E10]={ + category="lu", + description="LATIN CAPITAL LETTER D WITH CEDILLA", + direction="l", + lccode=0x1E11, + linebreak="al", + shcode=0x0044, + specials={ "char", 0x0044, 0x0327 }, + unicodeslot=0x1E10, + }, + [0x1E11]={ + category="ll", + description="LATIN SMALL LETTER D WITH CEDILLA", + direction="l", + linebreak="al", + shcode=0x0064, + specials={ "char", 0x0064, 0x0327 }, + uccode=0x1E10, + unicodeslot=0x1E11, + }, + [0x1E12]={ + category="lu", + description="LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW", + direction="l", + lccode=0x1E13, + linebreak="al", + shcode=0x0044, + specials={ "char", 0x0044, 0x032D }, + unicodeslot=0x1E12, + }, + [0x1E13]={ + category="ll", + description="LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW", + direction="l", + linebreak="al", + shcode=0x0064, + specials={ "char", 0x0064, 0x032D }, + uccode=0x1E12, + unicodeslot=0x1E13, + }, + [0x1E14]={ + category="lu", + description="LATIN CAPITAL LETTER E WITH MACRON AND GRAVE", + direction="l", + lccode=0x1E15, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x0112, 0x0300 }, + unicodeslot=0x1E14, + }, + [0x1E15]={ + category="ll", + description="LATIN SMALL LETTER E WITH MACRON AND GRAVE", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x0113, 0x0300 }, + uccode=0x1E14, + unicodeslot=0x1E15, + }, + [0x1E16]={ + category="lu", + description="LATIN CAPITAL LETTER E WITH MACRON AND ACUTE", + direction="l", + lccode=0x1E17, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x0112, 0x0301 }, + unicodeslot=0x1E16, + }, + [0x1E17]={ + category="ll", + description="LATIN SMALL LETTER E WITH MACRON AND ACUTE", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x0113, 0x0301 }, + uccode=0x1E16, + unicodeslot=0x1E17, + }, + [0x1E18]={ + category="lu", + description="LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW", + direction="l", + lccode=0x1E19, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x0045, 0x032D }, + unicodeslot=0x1E18, + }, + [0x1E19]={ + category="ll", + description="LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x0065, 0x032D }, + uccode=0x1E18, + unicodeslot=0x1E19, + }, + [0x1E1A]={ + category="lu", + description="LATIN CAPITAL LETTER E WITH TILDE BELOW", + direction="l", + lccode=0x1E1B, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x0045, 0x0330 }, + unicodeslot=0x1E1A, + }, + [0x1E1B]={ + category="ll", + description="LATIN SMALL LETTER E WITH TILDE BELOW", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x0065, 0x0330 }, + uccode=0x1E1A, + unicodeslot=0x1E1B, + }, + [0x1E1C]={ + category="lu", + description="LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE", + direction="l", + lccode=0x1E1D, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x0228, 0x0306 }, + unicodeslot=0x1E1C, + }, + [0x1E1D]={ + category="ll", + description="LATIN SMALL LETTER E WITH CEDILLA AND BREVE", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x0229, 0x0306 }, + uccode=0x1E1C, + unicodeslot=0x1E1D, + }, + [0x1E1E]={ + category="lu", + description="LATIN CAPITAL LETTER F WITH DOT ABOVE", + direction="l", + lccode=0x1E1F, + linebreak="al", + shcode=0x0046, + specials={ "char", 0x0046, 0x0307 }, + unicodeslot=0x1E1E, + }, + [0x1E1F]={ + category="ll", + description="LATIN SMALL LETTER F WITH DOT ABOVE", + direction="l", + linebreak="al", + shcode=0x0066, + specials={ "char", 0x0066, 0x0307 }, + uccode=0x1E1E, + unicodeslot=0x1E1F, + }, + [0x1E20]={ + category="lu", + description="LATIN CAPITAL LETTER G WITH MACRON", + direction="l", + lccode=0x1E21, + linebreak="al", + shcode=0x0047, + specials={ "char", 0x0047, 0x0304 }, + unicodeslot=0x1E20, + }, + [0x1E21]={ + category="ll", + description="LATIN SMALL LETTER G WITH MACRON", + direction="l", + linebreak="al", + shcode=0x0067, + specials={ "char", 0x0067, 0x0304 }, + uccode=0x1E20, + unicodeslot=0x1E21, + }, + [0x1E22]={ + category="lu", + description="LATIN CAPITAL LETTER H WITH DOT ABOVE", + direction="l", + lccode=0x1E23, + linebreak="al", + shcode=0x0048, + specials={ "char", 0x0048, 0x0307 }, + unicodeslot=0x1E22, + }, + [0x1E23]={ + category="ll", + description="LATIN SMALL LETTER H WITH DOT ABOVE", + direction="l", + linebreak="al", + shcode=0x0068, + specials={ "char", 0x0068, 0x0307 }, + uccode=0x1E22, + unicodeslot=0x1E23, + }, + [0x1E24]={ + category="lu", + description="LATIN CAPITAL LETTER H WITH DOT BELOW", + direction="l", + lccode=0x1E25, + linebreak="al", + shcode=0x0048, + specials={ "char", 0x0048, 0x0323 }, + unicodeslot=0x1E24, + }, + [0x1E25]={ + category="ll", + description="LATIN SMALL LETTER H WITH DOT BELOW", + direction="l", + linebreak="al", + shcode=0x0068, + specials={ "char", 0x0068, 0x0323 }, + uccode=0x1E24, + unicodeslot=0x1E25, + }, + [0x1E26]={ + category="lu", + description="LATIN CAPITAL LETTER H WITH DIAERESIS", + direction="l", + lccode=0x1E27, + linebreak="al", + shcode=0x0048, + specials={ "char", 0x0048, 0x0308 }, + unicodeslot=0x1E26, + }, + [0x1E27]={ + category="ll", + description="LATIN SMALL LETTER H WITH DIAERESIS", + direction="l", + linebreak="al", + shcode=0x0068, + specials={ "char", 0x0068, 0x0308 }, + uccode=0x1E26, + unicodeslot=0x1E27, + }, + [0x1E28]={ + category="lu", + description="LATIN CAPITAL LETTER H WITH CEDILLA", + direction="l", + lccode=0x1E29, + linebreak="al", + shcode=0x0048, + specials={ "char", 0x0048, 0x0327 }, + unicodeslot=0x1E28, + }, + [0x1E29]={ + category="ll", + description="LATIN SMALL LETTER H WITH CEDILLA", + direction="l", + linebreak="al", + shcode=0x0068, + specials={ "char", 0x0068, 0x0327 }, + uccode=0x1E28, + unicodeslot=0x1E29, + }, + [0x1E2A]={ + category="lu", + description="LATIN CAPITAL LETTER H WITH BREVE BELOW", + direction="l", + lccode=0x1E2B, + linebreak="al", + shcode=0x0048, + specials={ "char", 0x0048, 0x032E }, + unicodeslot=0x1E2A, + }, + [0x1E2B]={ + category="ll", + description="LATIN SMALL LETTER H WITH BREVE BELOW", + direction="l", + linebreak="al", + shcode=0x0068, + specials={ "char", 0x0068, 0x032E }, + uccode=0x1E2A, + unicodeslot=0x1E2B, + }, + [0x1E2C]={ + category="lu", + description="LATIN CAPITAL LETTER I WITH TILDE BELOW", + direction="l", + lccode=0x1E2D, + linebreak="al", + shcode=0x0049, + specials={ "char", 0x0049, 0x0330 }, + unicodeslot=0x1E2C, + }, + [0x1E2D]={ + category="ll", + description="LATIN SMALL LETTER I WITH TILDE BELOW", + direction="l", + linebreak="al", + shcode=0x0069, + specials={ "char", 0x0069, 0x0330 }, + uccode=0x1E2C, + unicodeslot=0x1E2D, + }, + [0x1E2E]={ + category="lu", + description="LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE", + direction="l", + lccode=0x1E2F, + linebreak="al", + shcode=0x0049, + specials={ "char", 0x00CF, 0x0301 }, + unicodeslot=0x1E2E, + }, + [0x1E2F]={ + category="ll", + description="LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE", + direction="l", + linebreak="al", + shcode=0x0069, + specials={ "char", 0x00EF, 0x0301 }, + uccode=0x1E2E, + unicodeslot=0x1E2F, + }, + [0x1E30]={ + category="lu", + description="LATIN CAPITAL LETTER K WITH ACUTE", + direction="l", + lccode=0x1E31, + linebreak="al", + shcode=0x004B, + specials={ "char", 0x004B, 0x0301 }, + unicodeslot=0x1E30, + }, + [0x1E31]={ + category="ll", + description="LATIN SMALL LETTER K WITH ACUTE", + direction="l", + linebreak="al", + shcode=0x006B, + specials={ "char", 0x006B, 0x0301 }, + uccode=0x1E30, + unicodeslot=0x1E31, + }, + [0x1E32]={ + category="lu", + description="LATIN CAPITAL LETTER K WITH DOT BELOW", + direction="l", + lccode=0x1E33, + linebreak="al", + shcode=0x004B, + specials={ "char", 0x004B, 0x0323 }, + unicodeslot=0x1E32, + }, + [0x1E33]={ + category="ll", + description="LATIN SMALL LETTER K WITH DOT BELOW", + direction="l", + linebreak="al", + shcode=0x006B, + specials={ "char", 0x006B, 0x0323 }, + uccode=0x1E32, + unicodeslot=0x1E33, + }, + [0x1E34]={ + category="lu", + description="LATIN CAPITAL LETTER K WITH LINE BELOW", + direction="l", + lccode=0x1E35, + linebreak="al", + shcode=0x004B, + specials={ "char", 0x004B, 0x0331 }, + unicodeslot=0x1E34, + }, + [0x1E35]={ + category="ll", + description="LATIN SMALL LETTER K WITH LINE BELOW", + direction="l", + linebreak="al", + shcode=0x006B, + specials={ "char", 0x006B, 0x0331 }, + uccode=0x1E34, + unicodeslot=0x1E35, + }, + [0x1E36]={ + category="lu", + description="LATIN CAPITAL LETTER L WITH DOT BELOW", + direction="l", + lccode=0x1E37, + linebreak="al", + shcode=0x004C, + specials={ "char", 0x004C, 0x0323 }, + unicodeslot=0x1E36, + }, + [0x1E37]={ + category="ll", + description="LATIN SMALL LETTER L WITH DOT BELOW", + direction="l", + linebreak="al", + shcode=0x006C, + specials={ "char", 0x006C, 0x0323 }, + uccode=0x1E36, + unicodeslot=0x1E37, + }, + [0x1E38]={ + category="lu", + description="LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON", + direction="l", + lccode=0x1E39, + linebreak="al", + shcode=0x004C, + specials={ "char", 0x1E36, 0x0304 }, + unicodeslot=0x1E38, + }, + [0x1E39]={ + category="ll", + description="LATIN SMALL LETTER L WITH DOT BELOW AND MACRON", + direction="l", + linebreak="al", + shcode=0x006C, + specials={ "char", 0x1E37, 0x0304 }, + uccode=0x1E38, + unicodeslot=0x1E39, + }, + [0x1E3A]={ + category="lu", + description="LATIN CAPITAL LETTER L WITH LINE BELOW", + direction="l", + lccode=0x1E3B, + linebreak="al", + shcode=0x004C, + specials={ "char", 0x004C, 0x0331 }, + unicodeslot=0x1E3A, + }, + [0x1E3B]={ + category="ll", + description="LATIN SMALL LETTER L WITH LINE BELOW", + direction="l", + linebreak="al", + shcode=0x006C, + specials={ "char", 0x006C, 0x0331 }, + uccode=0x1E3A, + unicodeslot=0x1E3B, + }, + [0x1E3C]={ + category="lu", + description="LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW", + direction="l", + lccode=0x1E3D, + linebreak="al", + shcode=0x004C, + specials={ "char", 0x004C, 0x032D }, + unicodeslot=0x1E3C, + }, + [0x1E3D]={ + category="ll", + description="LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW", + direction="l", + linebreak="al", + shcode=0x006C, + specials={ "char", 0x006C, 0x032D }, + uccode=0x1E3C, + unicodeslot=0x1E3D, + }, + [0x1E3E]={ + category="lu", + description="LATIN CAPITAL LETTER M WITH ACUTE", + direction="l", + lccode=0x1E3F, + linebreak="al", + shcode=0x004D, + specials={ "char", 0x004D, 0x0301 }, + unicodeslot=0x1E3E, + }, + [0x1E3F]={ + category="ll", + description="LATIN SMALL LETTER M WITH ACUTE", + direction="l", + linebreak="al", + shcode=0x006D, + specials={ "char", 0x006D, 0x0301 }, + uccode=0x1E3E, + unicodeslot=0x1E3F, + }, + [0x1E40]={ + category="lu", + description="LATIN CAPITAL LETTER M WITH DOT ABOVE", + direction="l", + lccode=0x1E41, + linebreak="al", + shcode=0x004D, + specials={ "char", 0x004D, 0x0307 }, + unicodeslot=0x1E40, + }, + [0x1E41]={ + category="ll", + description="LATIN SMALL LETTER M WITH DOT ABOVE", + direction="l", + linebreak="al", + shcode=0x006D, + specials={ "char", 0x006D, 0x0307 }, + uccode=0x1E40, + unicodeslot=0x1E41, + }, + [0x1E42]={ + category="lu", + description="LATIN CAPITAL LETTER M WITH DOT BELOW", + direction="l", + lccode=0x1E43, + linebreak="al", + shcode=0x004D, + specials={ "char", 0x004D, 0x0323 }, + unicodeslot=0x1E42, + }, + [0x1E43]={ + category="ll", + description="LATIN SMALL LETTER M WITH DOT BELOW", + direction="l", + linebreak="al", + shcode=0x006D, + specials={ "char", 0x006D, 0x0323 }, + uccode=0x1E42, + unicodeslot=0x1E43, + }, + [0x1E44]={ + category="lu", + description="LATIN CAPITAL LETTER N WITH DOT ABOVE", + direction="l", + lccode=0x1E45, + linebreak="al", + shcode=0x004E, + specials={ "char", 0x004E, 0x0307 }, + unicodeslot=0x1E44, + }, + [0x1E45]={ + category="ll", + description="LATIN SMALL LETTER N WITH DOT ABOVE", + direction="l", + linebreak="al", + shcode=0x006E, + specials={ "char", 0x006E, 0x0307 }, + uccode=0x1E44, + unicodeslot=0x1E45, + }, + [0x1E46]={ + category="lu", + description="LATIN CAPITAL LETTER N WITH DOT BELOW", + direction="l", + lccode=0x1E47, + linebreak="al", + shcode=0x004E, + specials={ "char", 0x004E, 0x0323 }, + unicodeslot=0x1E46, + }, + [0x1E47]={ + category="ll", + description="LATIN SMALL LETTER N WITH DOT BELOW", + direction="l", + linebreak="al", + shcode=0x006E, + specials={ "char", 0x006E, 0x0323 }, + uccode=0x1E46, + unicodeslot=0x1E47, + }, + [0x1E48]={ + category="lu", + description="LATIN CAPITAL LETTER N WITH LINE BELOW", + direction="l", + lccode=0x1E49, + linebreak="al", + shcode=0x004E, + specials={ "char", 0x004E, 0x0331 }, + unicodeslot=0x1E48, + }, + [0x1E49]={ + category="ll", + description="LATIN SMALL LETTER N WITH LINE BELOW", + direction="l", + linebreak="al", + shcode=0x006E, + specials={ "char", 0x006E, 0x0331 }, + uccode=0x1E48, + unicodeslot=0x1E49, + }, + [0x1E4A]={ + category="lu", + description="LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW", + direction="l", + lccode=0x1E4B, + linebreak="al", + shcode=0x004E, + specials={ "char", 0x004E, 0x032D }, + unicodeslot=0x1E4A, + }, + [0x1E4B]={ + category="ll", + description="LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW", + direction="l", + linebreak="al", + shcode=0x006E, + specials={ "char", 0x006E, 0x032D }, + uccode=0x1E4A, + unicodeslot=0x1E4B, + }, + [0x1E4C]={ + category="lu", + description="LATIN CAPITAL LETTER O WITH TILDE AND ACUTE", + direction="l", + lccode=0x1E4D, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x00D5, 0x0301 }, + unicodeslot=0x1E4C, + }, + [0x1E4D]={ + category="ll", + description="LATIN SMALL LETTER O WITH TILDE AND ACUTE", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x00F5, 0x0301 }, + uccode=0x1E4C, + unicodeslot=0x1E4D, + }, + [0x1E4E]={ + category="lu", + description="LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS", + direction="l", + lccode=0x1E4F, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x00D5, 0x0308 }, + unicodeslot=0x1E4E, + }, + [0x1E4F]={ + category="ll", + description="LATIN SMALL LETTER O WITH TILDE AND DIAERESIS", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x00F5, 0x0308 }, + uccode=0x1E4E, + unicodeslot=0x1E4F, + }, + [0x1E50]={ + category="lu", + description="LATIN CAPITAL LETTER O WITH MACRON AND GRAVE", + direction="l", + lccode=0x1E51, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x014C, 0x0300 }, + unicodeslot=0x1E50, + }, + [0x1E51]={ + category="ll", + description="LATIN SMALL LETTER O WITH MACRON AND GRAVE", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x014D, 0x0300 }, + uccode=0x1E50, + unicodeslot=0x1E51, + }, + [0x1E52]={ + category="lu", + description="LATIN CAPITAL LETTER O WITH MACRON AND ACUTE", + direction="l", + lccode=0x1E53, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x014C, 0x0301 }, + unicodeslot=0x1E52, + }, + [0x1E53]={ + category="ll", + description="LATIN SMALL LETTER O WITH MACRON AND ACUTE", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x014D, 0x0301 }, + uccode=0x1E52, + unicodeslot=0x1E53, + }, + [0x1E54]={ + category="lu", + description="LATIN CAPITAL LETTER P WITH ACUTE", + direction="l", + lccode=0x1E55, + linebreak="al", + shcode=0x0050, + specials={ "char", 0x0050, 0x0301 }, + unicodeslot=0x1E54, + }, + [0x1E55]={ + category="ll", + description="LATIN SMALL LETTER P WITH ACUTE", + direction="l", + linebreak="al", + shcode=0x0070, + specials={ "char", 0x0070, 0x0301 }, + uccode=0x1E54, + unicodeslot=0x1E55, + }, + [0x1E56]={ + category="lu", + description="LATIN CAPITAL LETTER P WITH DOT ABOVE", + direction="l", + lccode=0x1E57, + linebreak="al", + shcode=0x0050, + specials={ "char", 0x0050, 0x0307 }, + unicodeslot=0x1E56, + }, + [0x1E57]={ + category="ll", + description="LATIN SMALL LETTER P WITH DOT ABOVE", + direction="l", + linebreak="al", + shcode=0x0070, + specials={ "char", 0x0070, 0x0307 }, + uccode=0x1E56, + unicodeslot=0x1E57, + }, + [0x1E58]={ + category="lu", + description="LATIN CAPITAL LETTER R WITH DOT ABOVE", + direction="l", + lccode=0x1E59, + linebreak="al", + shcode=0x0052, + specials={ "char", 0x0052, 0x0307 }, + unicodeslot=0x1E58, + }, + [0x1E59]={ + category="ll", + description="LATIN SMALL LETTER R WITH DOT ABOVE", + direction="l", + linebreak="al", + shcode=0x0072, + specials={ "char", 0x0072, 0x0307 }, + uccode=0x1E58, + unicodeslot=0x1E59, + }, + [0x1E5A]={ + category="lu", + description="LATIN CAPITAL LETTER R WITH DOT BELOW", + direction="l", + lccode=0x1E5B, + linebreak="al", + shcode=0x0052, + specials={ "char", 0x0052, 0x0323 }, + unicodeslot=0x1E5A, + }, + [0x1E5B]={ + category="ll", + description="LATIN SMALL LETTER R WITH DOT BELOW", + direction="l", + linebreak="al", + shcode=0x0072, + specials={ "char", 0x0072, 0x0323 }, + uccode=0x1E5A, + unicodeslot=0x1E5B, + }, + [0x1E5C]={ + category="lu", + description="LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON", + direction="l", + lccode=0x1E5D, + linebreak="al", + shcode=0x0052, + specials={ "char", 0x1E5A, 0x0304 }, + unicodeslot=0x1E5C, + }, + [0x1E5D]={ + category="ll", + description="LATIN SMALL LETTER R WITH DOT BELOW AND MACRON", + direction="l", + linebreak="al", + shcode=0x0072, + specials={ "char", 0x1E5B, 0x0304 }, + uccode=0x1E5C, + unicodeslot=0x1E5D, + }, + [0x1E5E]={ + category="lu", + description="LATIN CAPITAL LETTER R WITH LINE BELOW", + direction="l", + lccode=0x1E5F, + linebreak="al", + shcode=0x0052, + specials={ "char", 0x0052, 0x0331 }, + unicodeslot=0x1E5E, + }, + [0x1E5F]={ + category="ll", + description="LATIN SMALL LETTER R WITH LINE BELOW", + direction="l", + linebreak="al", + shcode=0x0072, + specials={ "char", 0x0072, 0x0331 }, + uccode=0x1E5E, + unicodeslot=0x1E5F, + }, + [0x1E60]={ + category="lu", + description="LATIN CAPITAL LETTER S WITH DOT ABOVE", + direction="l", + lccode=0x1E61, + linebreak="al", + shcode=0x0053, + specials={ "char", 0x0053, 0x0307 }, + unicodeslot=0x1E60, + }, + [0x1E61]={ + category="ll", + description="LATIN SMALL LETTER S WITH DOT ABOVE", + direction="l", + linebreak="al", + shcode=0x0073, + specials={ "char", 0x0073, 0x0307 }, + uccode=0x1E60, + unicodeslot=0x1E61, + }, + [0x1E62]={ + category="lu", + description="LATIN CAPITAL LETTER S WITH DOT BELOW", + direction="l", + lccode=0x1E63, + linebreak="al", + shcode=0x0053, + specials={ "char", 0x0053, 0x0323 }, + unicodeslot=0x1E62, + }, + [0x1E63]={ + category="ll", + description="LATIN SMALL LETTER S WITH DOT BELOW", + direction="l", + linebreak="al", + shcode=0x0073, + specials={ "char", 0x0073, 0x0323 }, + uccode=0x1E62, + unicodeslot=0x1E63, + }, + [0x1E64]={ + category="lu", + description="LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE", + direction="l", + lccode=0x1E65, + linebreak="al", + shcode=0x0053, + specials={ "char", 0x015A, 0x0307 }, + unicodeslot=0x1E64, + }, + [0x1E65]={ + category="ll", + description="LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE", + direction="l", + linebreak="al", + shcode=0x0073, + specials={ "char", 0x015B, 0x0307 }, + uccode=0x1E64, + unicodeslot=0x1E65, + }, + [0x1E66]={ + category="lu", + description="LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE", + direction="l", + lccode=0x1E67, + linebreak="al", + shcode=0x0053, + specials={ "char", 0x0160, 0x0307 }, + unicodeslot=0x1E66, + }, + [0x1E67]={ + category="ll", + description="LATIN SMALL LETTER S WITH CARON AND DOT ABOVE", + direction="l", + linebreak="al", + shcode=0x0073, + specials={ "char", 0x0161, 0x0307 }, + uccode=0x1E66, + unicodeslot=0x1E67, + }, + [0x1E68]={ + category="lu", + description="LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE", + direction="l", + lccode=0x1E69, + linebreak="al", + shcode=0x0053, + specials={ "char", 0x1E62, 0x0307 }, + unicodeslot=0x1E68, + }, + [0x1E69]={ + category="ll", + description="LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE", + direction="l", + linebreak="al", + shcode=0x0073, + specials={ "char", 0x1E63, 0x0307 }, + uccode=0x1E68, + unicodeslot=0x1E69, + }, + [0x1E6A]={ + category="lu", + description="LATIN CAPITAL LETTER T WITH DOT ABOVE", + direction="l", + lccode=0x1E6B, + linebreak="al", + shcode=0x0054, + specials={ "char", 0x0054, 0x0307 }, + unicodeslot=0x1E6A, + }, + [0x1E6B]={ + category="ll", + description="LATIN SMALL LETTER T WITH DOT ABOVE", + direction="l", + linebreak="al", + shcode=0x0074, + specials={ "char", 0x0074, 0x0307 }, + uccode=0x1E6A, + unicodeslot=0x1E6B, + }, + [0x1E6C]={ + category="lu", + description="LATIN CAPITAL LETTER T WITH DOT BELOW", + direction="l", + lccode=0x1E6D, + linebreak="al", + shcode=0x0054, + specials={ "char", 0x0054, 0x0323 }, + unicodeslot=0x1E6C, + }, + [0x1E6D]={ + category="ll", + description="LATIN SMALL LETTER T WITH DOT BELOW", + direction="l", + linebreak="al", + shcode=0x0074, + specials={ "char", 0x0074, 0x0323 }, + uccode=0x1E6C, + unicodeslot=0x1E6D, + }, + [0x1E6E]={ + category="lu", + description="LATIN CAPITAL LETTER T WITH LINE BELOW", + direction="l", + lccode=0x1E6F, + linebreak="al", + shcode=0x0054, + specials={ "char", 0x0054, 0x0331 }, + unicodeslot=0x1E6E, + }, + [0x1E6F]={ + category="ll", + description="LATIN SMALL LETTER T WITH LINE BELOW", + direction="l", + linebreak="al", + shcode=0x0074, + specials={ "char", 0x0074, 0x0331 }, + uccode=0x1E6E, + unicodeslot=0x1E6F, + }, + [0x1E70]={ + category="lu", + description="LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW", + direction="l", + lccode=0x1E71, + linebreak="al", + shcode=0x0054, + specials={ "char", 0x0054, 0x032D }, + unicodeslot=0x1E70, + }, + [0x1E71]={ + category="ll", + description="LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW", + direction="l", + linebreak="al", + shcode=0x0074, + specials={ "char", 0x0074, 0x032D }, + uccode=0x1E70, + unicodeslot=0x1E71, + }, + [0x1E72]={ + category="lu", + description="LATIN CAPITAL LETTER U WITH DIAERESIS BELOW", + direction="l", + lccode=0x1E73, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x0055, 0x0324 }, + unicodeslot=0x1E72, + }, + [0x1E73]={ + category="ll", + description="LATIN SMALL LETTER U WITH DIAERESIS BELOW", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x0075, 0x0324 }, + uccode=0x1E72, + unicodeslot=0x1E73, + }, + [0x1E74]={ + category="lu", + description="LATIN CAPITAL LETTER U WITH TILDE BELOW", + direction="l", + lccode=0x1E75, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x0055, 0x0330 }, + unicodeslot=0x1E74, + }, + [0x1E75]={ + category="ll", + description="LATIN SMALL LETTER U WITH TILDE BELOW", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x0075, 0x0330 }, + uccode=0x1E74, + unicodeslot=0x1E75, + }, + [0x1E76]={ + category="lu", + description="LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW", + direction="l", + lccode=0x1E77, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x0055, 0x032D }, + unicodeslot=0x1E76, + }, + [0x1E77]={ + category="ll", + description="LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x0075, 0x032D }, + uccode=0x1E76, + unicodeslot=0x1E77, + }, + [0x1E78]={ + category="lu", + description="LATIN CAPITAL LETTER U WITH TILDE AND ACUTE", + direction="l", + lccode=0x1E79, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x0168, 0x0301 }, + unicodeslot=0x1E78, + }, + [0x1E79]={ + category="ll", + description="LATIN SMALL LETTER U WITH TILDE AND ACUTE", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x0169, 0x0301 }, + uccode=0x1E78, + unicodeslot=0x1E79, + }, + [0x1E7A]={ + category="lu", + description="LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS", + direction="l", + lccode=0x1E7B, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x016A, 0x0308 }, + unicodeslot=0x1E7A, + }, + [0x1E7B]={ + category="ll", + description="LATIN SMALL LETTER U WITH MACRON AND DIAERESIS", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x016B, 0x0308 }, + uccode=0x1E7A, + unicodeslot=0x1E7B, + }, + [0x1E7C]={ + category="lu", + description="LATIN CAPITAL LETTER V WITH TILDE", + direction="l", + lccode=0x1E7D, + linebreak="al", + shcode=0x0056, + specials={ "char", 0x0056, 0x0303 }, + unicodeslot=0x1E7C, + }, + [0x1E7D]={ + category="ll", + description="LATIN SMALL LETTER V WITH TILDE", + direction="l", + linebreak="al", + shcode=0x0076, + specials={ "char", 0x0076, 0x0303 }, + uccode=0x1E7C, + unicodeslot=0x1E7D, + }, + [0x1E7E]={ + category="lu", + description="LATIN CAPITAL LETTER V WITH DOT BELOW", + direction="l", + lccode=0x1E7F, + linebreak="al", + shcode=0x0056, + specials={ "char", 0x0056, 0x0323 }, + unicodeslot=0x1E7E, + }, + [0x1E7F]={ + category="ll", + description="LATIN SMALL LETTER V WITH DOT BELOW", + direction="l", + linebreak="al", + shcode=0x0076, + specials={ "char", 0x0076, 0x0323 }, + uccode=0x1E7E, + unicodeslot=0x1E7F, + }, + [0x1E80]={ + adobename="Wgrave", + category="lu", + description="LATIN CAPITAL LETTER W WITH GRAVE", + direction="l", + lccode=0x1E81, + linebreak="al", + shcode=0x0057, + specials={ "char", 0x0057, 0x0300 }, + unicodeslot=0x1E80, + }, + [0x1E81]={ + adobename="wgrave", + category="ll", + description="LATIN SMALL LETTER W WITH GRAVE", + direction="l", + linebreak="al", + shcode=0x0077, + specials={ "char", 0x0077, 0x0300 }, + uccode=0x1E80, + unicodeslot=0x1E81, + }, + [0x1E82]={ + adobename="Wacute", + category="lu", + description="LATIN CAPITAL LETTER W WITH ACUTE", + direction="l", + lccode=0x1E83, + linebreak="al", + shcode=0x0057, + specials={ "char", 0x0057, 0x0301 }, + unicodeslot=0x1E82, + }, + [0x1E83]={ + adobename="wacute", + category="ll", + description="LATIN SMALL LETTER W WITH ACUTE", + direction="l", + linebreak="al", + shcode=0x0077, + specials={ "char", 0x0077, 0x0301 }, + uccode=0x1E82, + unicodeslot=0x1E83, + }, + [0x1E84]={ + adobename="Wdieresis", + category="lu", + description="LATIN CAPITAL LETTER W WITH DIAERESIS", + direction="l", + lccode=0x1E85, + linebreak="al", + shcode=0x0057, + specials={ "char", 0x0057, 0x0308 }, + unicodeslot=0x1E84, + }, + [0x1E85]={ + adobename="wdieresis", + category="ll", + description="LATIN SMALL LETTER W WITH DIAERESIS", + direction="l", + linebreak="al", + shcode=0x0077, + specials={ "char", 0x0077, 0x0308 }, + uccode=0x1E84, + unicodeslot=0x1E85, + }, + [0x1E86]={ + category="lu", + description="LATIN CAPITAL LETTER W WITH DOT ABOVE", + direction="l", + lccode=0x1E87, + linebreak="al", + shcode=0x0057, + specials={ "char", 0x0057, 0x0307 }, + unicodeslot=0x1E86, + }, + [0x1E87]={ + category="ll", + description="LATIN SMALL LETTER W WITH DOT ABOVE", + direction="l", + linebreak="al", + shcode=0x0077, + specials={ "char", 0x0077, 0x0307 }, + uccode=0x1E86, + unicodeslot=0x1E87, + }, + [0x1E88]={ + category="lu", + description="LATIN CAPITAL LETTER W WITH DOT BELOW", + direction="l", + lccode=0x1E89, + linebreak="al", + shcode=0x0057, + specials={ "char", 0x0057, 0x0323 }, + unicodeslot=0x1E88, + }, + [0x1E89]={ + category="ll", + description="LATIN SMALL LETTER W WITH DOT BELOW", + direction="l", + linebreak="al", + shcode=0x0077, + specials={ "char", 0x0077, 0x0323 }, + uccode=0x1E88, + unicodeslot=0x1E89, + }, + [0x1E8A]={ + category="lu", + description="LATIN CAPITAL LETTER X WITH DOT ABOVE", + direction="l", + lccode=0x1E8B, + linebreak="al", + shcode=0x0058, + specials={ "char", 0x0058, 0x0307 }, + unicodeslot=0x1E8A, + }, + [0x1E8B]={ + category="ll", + description="LATIN SMALL LETTER X WITH DOT ABOVE", + direction="l", + linebreak="al", + shcode=0x0078, + specials={ "char", 0x0078, 0x0307 }, + uccode=0x1E8A, + unicodeslot=0x1E8B, + }, + [0x1E8C]={ + category="lu", + description="LATIN CAPITAL LETTER X WITH DIAERESIS", + direction="l", + lccode=0x1E8D, + linebreak="al", + shcode=0x0058, + specials={ "char", 0x0058, 0x0308 }, + unicodeslot=0x1E8C, + }, + [0x1E8D]={ + category="ll", + description="LATIN SMALL LETTER X WITH DIAERESIS", + direction="l", + linebreak="al", + shcode=0x0078, + specials={ "char", 0x0078, 0x0308 }, + uccode=0x1E8C, + unicodeslot=0x1E8D, + }, + [0x1E8E]={ + category="lu", + description="LATIN CAPITAL LETTER Y WITH DOT ABOVE", + direction="l", + lccode=0x1E8F, + linebreak="al", + shcode=0x0059, + specials={ "char", 0x0059, 0x0307 }, + unicodeslot=0x1E8E, + }, + [0x1E8F]={ + category="ll", + description="LATIN SMALL LETTER Y WITH DOT ABOVE", + direction="l", + linebreak="al", + shcode=0x0079, + specials={ "char", 0x0079, 0x0307 }, + uccode=0x1E8E, + unicodeslot=0x1E8F, + }, + [0x1E90]={ + category="lu", + description="LATIN CAPITAL LETTER Z WITH CIRCUMFLEX", + direction="l", + lccode=0x1E91, + linebreak="al", + shcode=0x005A, + specials={ "char", 0x005A, 0x0302 }, + unicodeslot=0x1E90, + }, + [0x1E91]={ + category="ll", + description="LATIN SMALL LETTER Z WITH CIRCUMFLEX", + direction="l", + linebreak="al", + shcode=0x007A, + specials={ "char", 0x007A, 0x0302 }, + uccode=0x1E90, + unicodeslot=0x1E91, + }, + [0x1E92]={ + category="lu", + description="LATIN CAPITAL LETTER Z WITH DOT BELOW", + direction="l", + lccode=0x1E93, + linebreak="al", + shcode=0x005A, + specials={ "char", 0x005A, 0x0323 }, + unicodeslot=0x1E92, + }, + [0x1E93]={ + category="ll", + description="LATIN SMALL LETTER Z WITH DOT BELOW", + direction="l", + linebreak="al", + shcode=0x007A, + specials={ "char", 0x007A, 0x0323 }, + uccode=0x1E92, + unicodeslot=0x1E93, + }, + [0x1E94]={ + category="lu", + description="LATIN CAPITAL LETTER Z WITH LINE BELOW", + direction="l", + lccode=0x1E95, + linebreak="al", + shcode=0x005A, + specials={ "char", 0x005A, 0x0331 }, + unicodeslot=0x1E94, + }, + [0x1E95]={ + category="ll", + description="LATIN SMALL LETTER Z WITH LINE BELOW", + direction="l", + linebreak="al", + shcode=0x007A, + specials={ "char", 0x007A, 0x0331 }, + uccode=0x1E94, + unicodeslot=0x1E95, + }, + [0x1E96]={ + category="ll", + description="LATIN SMALL LETTER H WITH LINE BELOW", + direction="l", + linebreak="al", + shcode=0x0068, + specials={ "char", 0x0068, 0x0331 }, + unicodeslot=0x1E96, + }, + [0x1E97]={ + category="ll", + description="LATIN SMALL LETTER T WITH DIAERESIS", + direction="l", + linebreak="al", + shcode=0x0074, + specials={ "char", 0x0074, 0x0308 }, + unicodeslot=0x1E97, + }, + [0x1E98]={ + category="ll", + description="LATIN SMALL LETTER W WITH RING ABOVE", + direction="l", + linebreak="al", + shcode=0x0077, + specials={ "char", 0x0077, 0x030A }, + unicodeslot=0x1E98, + }, + [0x1E99]={ + category="ll", + description="LATIN SMALL LETTER Y WITH RING ABOVE", + direction="l", + linebreak="al", + shcode=0x0079, + specials={ "char", 0x0079, 0x030A }, + unicodeslot=0x1E99, + }, + [0x1E9A]={ + category="ll", + description="LATIN SMALL LETTER A WITH RIGHT HALF RING", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "compat", 0x0061, 0x02BE }, + unicodeslot=0x1E9A, + }, + [0x1E9B]={ + category="ll", + description="LATIN SMALL LETTER LONG S WITH DOT ABOVE", + direction="l", + linebreak="al", + specials={ "char", 0x017F, 0x0307 }, + uccode=0x1E60, + unicodeslot=0x1E9B, + }, + [0x1EA0]={ + category="lu", + contextname="Adotbelow", + description="LATIN CAPITAL LETTER A WITH DOT BELOW", + direction="l", + lccode=0x1EA1, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x0041, 0x0323 }, + unicodeslot=0x1EA0, + }, + [0x1EA1]={ + category="ll", + contextname="adotbelow", + description="LATIN SMALL LETTER A WITH DOT BELOW", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x0061, 0x0323 }, + uccode=0x1EA0, + unicodeslot=0x1EA1, + }, + [0x1EA2]={ + category="lu", + contextname="Ahook", + description="LATIN CAPITAL LETTER A WITH HOOK ABOVE", + direction="l", + lccode=0x1EA3, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x0041, 0x0309 }, + unicodeslot=0x1EA2, + }, + [0x1EA3]={ + category="ll", + contextname="ahook", + description="LATIN SMALL LETTER A WITH HOOK ABOVE", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x0061, 0x0309 }, + uccode=0x1EA2, + unicodeslot=0x1EA3, + }, + [0x1EA4]={ + category="lu", + contextname="Acircumflexacute", + description="LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE", + direction="l", + lccode=0x1EA5, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x00C2, 0x0301 }, + unicodeslot=0x1EA4, + }, + [0x1EA5]={ + category="ll", + contextname="acircumflexacute", + description="LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x00E2, 0x0301 }, + uccode=0x1EA4, + unicodeslot=0x1EA5, + }, + [0x1EA6]={ + category="lu", + contextname="Acircumflexgrave", + description="LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE", + direction="l", + lccode=0x1EA7, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x00C2, 0x0300 }, + unicodeslot=0x1EA6, + }, + [0x1EA7]={ + category="ll", + contextname="acircumflexgrave", + description="LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x00E2, 0x0300 }, + uccode=0x1EA6, + unicodeslot=0x1EA7, + }, + [0x1EA8]={ + category="lu", + contextname="Acircumflexhook", + description="LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE", + direction="l", + lccode=0x1EA9, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x00C2, 0x0309 }, + unicodeslot=0x1EA8, + }, + [0x1EA9]={ + category="ll", + contextname="acircumflexhook", + description="LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x00E2, 0x0309 }, + uccode=0x1EA8, + unicodeslot=0x1EA9, + }, + [0x1EAA]={ + category="lu", + contextname="Acircumflextilde", + description="LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE", + direction="l", + lccode=0x1EAB, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x00C2, 0x0303 }, + unicodeslot=0x1EAA, + }, + [0x1EAB]={ + category="ll", + contextname="acircumflextilde", + description="LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x00E2, 0x0303 }, + uccode=0x1EAA, + unicodeslot=0x1EAB, + }, + [0x1EAC]={ + category="lu", + contextname="Acircumflexdotbelow", + description="LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW", + direction="l", + lccode=0x1EAD, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x1EA0, 0x0302 }, + unicodeslot=0x1EAC, + }, + [0x1EAD]={ + category="ll", + contextname="acircumflexdotbelow", + description="LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x1EA1, 0x0302 }, + uccode=0x1EAC, + unicodeslot=0x1EAD, + }, + [0x1EAE]={ + category="lu", + contextname="Abreveacute", + description="LATIN CAPITAL LETTER A WITH BREVE AND ACUTE", + direction="l", + lccode=0x1EAF, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x0102, 0x0301 }, + unicodeslot=0x1EAE, + }, + [0x1EAF]={ + category="ll", + contextname="abreveacute", + description="LATIN SMALL LETTER A WITH BREVE AND ACUTE", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x0103, 0x0301 }, + uccode=0x1EAE, + unicodeslot=0x1EAF, + }, + [0x1EB0]={ + category="lu", + contextname="Abrevegrave", + description="LATIN CAPITAL LETTER A WITH BREVE AND GRAVE", + direction="l", + lccode=0x1EB1, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x0102, 0x0300 }, + unicodeslot=0x1EB0, + }, + [0x1EB1]={ + category="ll", + contextname="abrevegrave", + description="LATIN SMALL LETTER A WITH BREVE AND GRAVE", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x0103, 0x0300 }, + uccode=0x1EB0, + unicodeslot=0x1EB1, + }, + [0x1EB2]={ + category="lu", + contextname="Abrevehook", + description="LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE", + direction="l", + lccode=0x1EB3, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x0102, 0x0309 }, + unicodeslot=0x1EB2, + }, + [0x1EB3]={ + category="ll", + contextname="abrevehook", + description="LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x0103, 0x0309 }, + uccode=0x1EB2, + unicodeslot=0x1EB3, + }, + [0x1EB4]={ + category="lu", + contextname="Abrevetilde", + description="LATIN CAPITAL LETTER A WITH BREVE AND TILDE", + direction="l", + lccode=0x1EB5, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x0102, 0x0303 }, + unicodeslot=0x1EB4, + }, + [0x1EB5]={ + category="ll", + contextname="abrevetilde", + description="LATIN SMALL LETTER A WITH BREVE AND TILDE", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x0103, 0x0303 }, + uccode=0x1EB4, + unicodeslot=0x1EB5, + }, + [0x1EB6]={ + category="lu", + contextname="Abrevedotbelow", + description="LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW", + direction="l", + lccode=0x1EB7, + linebreak="al", + shcode=0x0041, + specials={ "char", 0x1EA0, 0x0306 }, + unicodeslot=0x1EB6, + }, + [0x1EB7]={ + category="ll", + contextname="abrevedotbelow", + description="LATIN SMALL LETTER A WITH BREVE AND DOT BELOW", + direction="l", + linebreak="al", + shcode=0x0061, + specials={ "char", 0x1EA1, 0x0306 }, + uccode=0x1EB6, + unicodeslot=0x1EB7, + }, + [0x1EB8]={ + category="lu", + contextname="Edotbelow", + description="LATIN CAPITAL LETTER E WITH DOT BELOW", + direction="l", + lccode=0x1EB9, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x0045, 0x0323 }, + unicodeslot=0x1EB8, + }, + [0x1EB9]={ + category="ll", + contextname="edotbelow", + description="LATIN SMALL LETTER E WITH DOT BELOW", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x0065, 0x0323 }, + uccode=0x1EB8, + unicodeslot=0x1EB9, + }, + [0x1EBA]={ + category="lu", + contextname="Ehook", + description="LATIN CAPITAL LETTER E WITH HOOK ABOVE", + direction="l", + lccode=0x1EBB, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x0045, 0x0309 }, + unicodeslot=0x1EBA, + }, + [0x1EBB]={ + category="ll", + contextname="ehook", + description="LATIN SMALL LETTER E WITH HOOK ABOVE", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x0065, 0x0309 }, + uccode=0x1EBA, + unicodeslot=0x1EBB, + }, + [0x1EBC]={ + category="lu", + contextname="Etilde", + description="LATIN CAPITAL LETTER E WITH TILDE", + direction="l", + lccode=0x1EBD, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x0045, 0x0303 }, + unicodeslot=0x1EBC, + }, + [0x1EBD]={ + category="ll", + contextname="etilde", + description="LATIN SMALL LETTER E WITH TILDE", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x0065, 0x0303 }, + uccode=0x1EBC, + unicodeslot=0x1EBD, + }, + [0x1EBE]={ + category="lu", + contextname="Ecircumflexacute", + description="LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE", + direction="l", + lccode=0x1EBF, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x00CA, 0x0301 }, + unicodeslot=0x1EBE, + }, + [0x1EBF]={ + category="ll", + contextname="ecircumflexacute", + description="LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x00EA, 0x0301 }, + uccode=0x1EBE, + unicodeslot=0x1EBF, + }, + [0x1EC0]={ + category="lu", + contextname="Ecircumflexgrave", + description="LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE", + direction="l", + lccode=0x1EC1, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x00CA, 0x0300 }, + unicodeslot=0x1EC0, + }, + [0x1EC1]={ + category="ll", + contextname="ecircumflexgrave", + description="LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x00EA, 0x0300 }, + uccode=0x1EC0, + unicodeslot=0x1EC1, + }, + [0x1EC2]={ + category="lu", + contextname="Ecircumflexhook", + description="LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE", + direction="l", + lccode=0x1EC3, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x00CA, 0x0309 }, + unicodeslot=0x1EC2, + }, + [0x1EC3]={ + category="ll", + contextname="ecircumflexhook", + description="LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x00EA, 0x0309 }, + uccode=0x1EC2, + unicodeslot=0x1EC3, + }, + [0x1EC4]={ + category="lu", + contextname="Ecircumflextilde", + description="LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE", + direction="l", + lccode=0x1EC5, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x00CA, 0x0303 }, + unicodeslot=0x1EC4, + }, + [0x1EC5]={ + category="ll", + contextname="ecircumflextilde", + description="LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x00EA, 0x0303 }, + uccode=0x1EC4, + unicodeslot=0x1EC5, + }, + [0x1EC6]={ + category="lu", + contextname="Ecircumflexdotbelow", + description="LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW", + direction="l", + lccode=0x1EC7, + linebreak="al", + shcode=0x0045, + specials={ "char", 0x1EB8, 0x0302 }, + unicodeslot=0x1EC6, + }, + [0x1EC7]={ + category="ll", + contextname="ecircumflexdotbelow", + description="LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW", + direction="l", + linebreak="al", + shcode=0x0065, + specials={ "char", 0x1EB9, 0x0302 }, + uccode=0x1EC6, + unicodeslot=0x1EC7, + }, + [0x1EC8]={ + category="lu", + contextname="Ihook", + description="LATIN CAPITAL LETTER I WITH HOOK ABOVE", + direction="l", + lccode=0x1EC9, + linebreak="al", + shcode=0x0049, + specials={ "char", 0x0049, 0x0309 }, + unicodeslot=0x1EC8, + }, + [0x1EC9]={ + category="ll", + contextname="ihook", + description="LATIN SMALL LETTER I WITH HOOK ABOVE", + direction="l", + linebreak="al", + shcode=0x0069, + specials={ "char", 0x0069, 0x0309 }, + uccode=0x1EC8, + unicodeslot=0x1EC9, + }, + [0x1ECA]={ + category="lu", + contextname="Idotbelow", + description="LATIN CAPITAL LETTER I WITH DOT BELOW", + direction="l", + lccode=0x1ECB, + linebreak="al", + shcode=0x0049, + specials={ "char", 0x0049, 0x0323 }, + unicodeslot=0x1ECA, + }, + [0x1ECB]={ + category="ll", + contextname="idotbelow", + description="LATIN SMALL LETTER I WITH DOT BELOW", + direction="l", + linebreak="al", + shcode=0x0069, + specials={ "char", 0x0069, 0x0323 }, + uccode=0x1ECA, + unicodeslot=0x1ECB, + }, + [0x1ECC]={ + category="lu", + contextname="Odotbelow", + description="LATIN CAPITAL LETTER O WITH DOT BELOW", + direction="l", + lccode=0x1ECD, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x004F, 0x0323 }, + unicodeslot=0x1ECC, + }, + [0x1ECD]={ + category="ll", + contextname="odotbelow", + description="LATIN SMALL LETTER O WITH DOT BELOW", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x006F, 0x0323 }, + uccode=0x1ECC, + unicodeslot=0x1ECD, + }, + [0x1ECE]={ + category="lu", + contextname="Ohook", + description="LATIN CAPITAL LETTER O WITH HOOK ABOVE", + direction="l", + lccode=0x1ECF, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x004F, 0x0309 }, + unicodeslot=0x1ECE, + }, + [0x1ECF]={ + category="ll", + contextname="ohook", + description="LATIN SMALL LETTER O WITH HOOK ABOVE", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x006F, 0x0309 }, + uccode=0x1ECE, + unicodeslot=0x1ECF, + }, + [0x1ED0]={ + category="lu", + contextname="Ocircumflexacute", + description="LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE", + direction="l", + lccode=0x1ED1, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x00D4, 0x0301 }, + unicodeslot=0x1ED0, + }, + [0x1ED1]={ + category="ll", + contextname="ocircumflexacute", + description="LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x00F4, 0x0301 }, + uccode=0x1ED0, + unicodeslot=0x1ED1, + }, + [0x1ED2]={ + category="lu", + contextname="Ocircumflexgrave", + description="LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE", + direction="l", + lccode=0x1ED3, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x00D4, 0x0300 }, + unicodeslot=0x1ED2, + }, + [0x1ED3]={ + category="ll", + contextname="ocircumflexgrave", + description="LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x00F4, 0x0300 }, + uccode=0x1ED2, + unicodeslot=0x1ED3, + }, + [0x1ED4]={ + category="lu", + contextname="Ocircumflexhook", + description="LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE", + direction="l", + lccode=0x1ED5, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x00D4, 0x0309 }, + unicodeslot=0x1ED4, + }, + [0x1ED5]={ + category="ll", + contextname="ocircumflexhook", + description="LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x00F4, 0x0309 }, + uccode=0x1ED4, + unicodeslot=0x1ED5, + }, + [0x1ED6]={ + category="lu", + contextname="Ocircumflextilde", + description="LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE", + direction="l", + lccode=0x1ED7, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x00D4, 0x0303 }, + unicodeslot=0x1ED6, + }, + [0x1ED7]={ + category="ll", + contextname="ocircumflextilde", + description="LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x00F4, 0x0303 }, + uccode=0x1ED6, + unicodeslot=0x1ED7, + }, + [0x1ED8]={ + category="lu", + contextname="Ocircumflexdotbelow", + description="LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW", + direction="l", + lccode=0x1ED9, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x1ECC, 0x0302 }, + unicodeslot=0x1ED8, + }, + [0x1ED9]={ + category="ll", + contextname="ocircumflexdotbelow", + description="LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x1ECD, 0x0302 }, + uccode=0x1ED8, + unicodeslot=0x1ED9, + }, + [0x1EDA]={ + category="lu", + contextname="Ohornacute", + description="LATIN CAPITAL LETTER O WITH HORN AND ACUTE", + direction="l", + lccode=0x1EDB, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x01A0, 0x0301 }, + unicodeslot=0x1EDA, + }, + [0x1EDB]={ + category="ll", + contextname="ohornacute", + description="LATIN SMALL LETTER O WITH HORN AND ACUTE", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x01A1, 0x0301 }, + uccode=0x1EDA, + unicodeslot=0x1EDB, + }, + [0x1EDC]={ + category="lu", + contextname="Ohorngrave", + description="LATIN CAPITAL LETTER O WITH HORN AND GRAVE", + direction="l", + lccode=0x1EDD, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x01A0, 0x0300 }, + unicodeslot=0x1EDC, + }, + [0x1EDD]={ + category="ll", + contextname="ohorngrave", + description="LATIN SMALL LETTER O WITH HORN AND GRAVE", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x01A1, 0x0300 }, + uccode=0x1EDC, + unicodeslot=0x1EDD, + }, + [0x1EDE]={ + category="lu", + contextname="Ohornhook", + description="LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE", + direction="l", + lccode=0x1EDF, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x01A0, 0x0309 }, + unicodeslot=0x1EDE, + }, + [0x1EDF]={ + category="ll", + contextname="ohornhook", + description="LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x01A1, 0x0309 }, + uccode=0x1EDE, + unicodeslot=0x1EDF, + }, + [0x1EE0]={ + category="lu", + contextname="Ohorntilde", + description="LATIN CAPITAL LETTER O WITH HORN AND TILDE", + direction="l", + lccode=0x1EE1, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x01A0, 0x0303 }, + unicodeslot=0x1EE0, + }, + [0x1EE1]={ + category="ll", + contextname="ohorntilde", + description="LATIN SMALL LETTER O WITH HORN AND TILDE", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x01A1, 0x0303 }, + uccode=0x1EE0, + unicodeslot=0x1EE1, + }, + [0x1EE2]={ + category="lu", + contextname="Ohorndotbelow", + description="LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW", + direction="l", + lccode=0x1EE3, + linebreak="al", + shcode=0x004F, + specials={ "char", 0x01A0, 0x0323 }, + unicodeslot=0x1EE2, + }, + [0x1EE3]={ + category="ll", + contextname="ohorndotbelow", + description="LATIN SMALL LETTER O WITH HORN AND DOT BELOW", + direction="l", + linebreak="al", + shcode=0x006F, + specials={ "char", 0x01A1, 0x0323 }, + uccode=0x1EE2, + unicodeslot=0x1EE3, + }, + [0x1EE4]={ + category="lu", + contextname="Udotbelow", + description="LATIN CAPITAL LETTER U WITH DOT BELOW", + direction="l", + lccode=0x1EE5, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x0055, 0x0323 }, + unicodeslot=0x1EE4, + }, + [0x1EE5]={ + category="ll", + contextname="udotbelow", + description="LATIN SMALL LETTER U WITH DOT BELOW", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x0075, 0x0323 }, + uccode=0x1EE4, + unicodeslot=0x1EE5, + }, + [0x1EE6]={ + category="lu", + contextname="Uhook", + description="LATIN CAPITAL LETTER U WITH HOOK ABOVE", + direction="l", + lccode=0x1EE7, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x0055, 0x0309 }, + unicodeslot=0x1EE6, + }, + [0x1EE7]={ + category="ll", + contextname="uhook", + description="LATIN SMALL LETTER U WITH HOOK ABOVE", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x0075, 0x0309 }, + uccode=0x1EE6, + unicodeslot=0x1EE7, + }, + [0x1EE8]={ + category="lu", + contextname="Uhornacute", + description="LATIN CAPITAL LETTER U WITH HORN AND ACUTE", + direction="l", + lccode=0x1EE9, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x01AF, 0x0301 }, + unicodeslot=0x1EE8, + }, + [0x1EE9]={ + category="ll", + contextname="uhornacute", + description="LATIN SMALL LETTER U WITH HORN AND ACUTE", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x01B0, 0x0301 }, + uccode=0x1EE8, + unicodeslot=0x1EE9, + }, + [0x1EEA]={ + category="lu", + contextname="Uhorngrave", + description="LATIN CAPITAL LETTER U WITH HORN AND GRAVE", + direction="l", + lccode=0x1EEB, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x01AF, 0x0300 }, + unicodeslot=0x1EEA, + }, + [0x1EEB]={ + category="ll", + contextname="uhorngrave", + description="LATIN SMALL LETTER U WITH HORN AND GRAVE", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x01B0, 0x0300 }, + uccode=0x1EEA, + unicodeslot=0x1EEB, + }, + [0x1EEC]={ + category="lu", + contextname="Uhornhook", + description="LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE", + direction="l", + lccode=0x1EED, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x01AF, 0x0309 }, + unicodeslot=0x1EEC, + }, + [0x1EED]={ + category="ll", + contextname="uhornhook", + description="LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x01B0, 0x0309 }, + uccode=0x1EEC, + unicodeslot=0x1EED, + }, + [0x1EEE]={ + category="lu", + contextname="Uhorntilde", + description="LATIN CAPITAL LETTER U WITH HORN AND TILDE", + direction="l", + lccode=0x1EEF, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x01AF, 0x0303 }, + unicodeslot=0x1EEE, + }, + [0x1EEF]={ + category="ll", + contextname="uhorntilde", + description="LATIN SMALL LETTER U WITH HORN AND TILDE", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x01B0, 0x0303 }, + uccode=0x1EEE, + unicodeslot=0x1EEF, + }, + [0x1EF0]={ + category="lu", + contextname="Uhorndotbelow", + description="LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW", + direction="l", + lccode=0x1EF1, + linebreak="al", + shcode=0x0055, + specials={ "char", 0x01AF, 0x0323 }, + unicodeslot=0x1EF0, + }, + [0x1EF1]={ + category="ll", + contextname="uhorndotbelow", + description="LATIN SMALL LETTER U WITH HORN AND DOT BELOW", + direction="l", + linebreak="al", + shcode=0x0075, + specials={ "char", 0x01B0, 0x0323 }, + uccode=0x1EF0, + unicodeslot=0x1EF1, + }, + [0x1EF2]={ + adobename="Ygrave", + category="lu", + contextname="Ygrave", + description="LATIN CAPITAL LETTER Y WITH GRAVE", + direction="l", + lccode=0x1EF3, + linebreak="al", + shcode=0x0059, + specials={ "char", 0x0059, 0x0300 }, + unicodeslot=0x1EF2, + }, + [0x1EF3]={ + adobename="ygrave", + category="ll", + contextname="ygrave", + description="LATIN SMALL LETTER Y WITH GRAVE", + direction="l", + linebreak="al", + shcode=0x0079, + specials={ "char", 0x0079, 0x0300 }, + uccode=0x1EF2, + unicodeslot=0x1EF3, + }, + [0x1EF4]={ + category="lu", + contextname="Ydotbelow", + description="LATIN CAPITAL LETTER Y WITH DOT BELOW", + direction="l", + lccode=0x1EF5, + linebreak="al", + shcode=0x0059, + specials={ "char", 0x0059, 0x0323 }, + unicodeslot=0x1EF4, + }, + [0x1EF5]={ + category="ll", + contextname="ydotbelow", + description="LATIN SMALL LETTER Y WITH DOT BELOW", + direction="l", + linebreak="al", + shcode=0x0079, + specials={ "char", 0x0079, 0x0323 }, + uccode=0x1EF4, + unicodeslot=0x1EF5, + }, + [0x1EF6]={ + category="lu", + contextname="Yhook", + description="LATIN CAPITAL LETTER Y WITH HOOK ABOVE", + direction="l", + lccode=0x1EF7, + linebreak="al", + shcode=0x0059, + specials={ "char", 0x0059, 0x0309 }, + unicodeslot=0x1EF6, + }, + [0x1EF7]={ + category="ll", + contextname="yhook", + description="LATIN SMALL LETTER Y WITH HOOK ABOVE", + direction="l", + linebreak="al", + shcode=0x0079, + specials={ "char", 0x0079, 0x0309 }, + uccode=0x1EF6, + unicodeslot=0x1EF7, + }, + [0x1EF8]={ + category="lu", + contextname="Ytilde", + description="LATIN CAPITAL LETTER Y WITH TILDE", + direction="l", + lccode=0x1EF9, + linebreak="al", + shcode=0x0059, + specials={ "char", 0x0059, 0x0303 }, + unicodeslot=0x1EF8, + }, + [0x1EF9]={ + category="ll", + contextname="ytilde", + description="LATIN SMALL LETTER Y WITH TILDE", + direction="l", + linebreak="al", + shcode=0x0079, + specials={ "char", 0x0079, 0x0303 }, + uccode=0x1EF8, + unicodeslot=0x1EF9, + }, + [0x1F00]={ + category="ll", + contextname="greekalphapsili", + description="GREEK SMALL LETTER ALPHA WITH PSILI", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x03B1, 0x0313 }, + uccode=0x1F08, + unicodeslot=0x1F00, + }, + [0x1F01]={ + category="ll", + contextname="greekalphadasia", + description="GREEK SMALL LETTER ALPHA WITH DASIA", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x03B1, 0x0314 }, + uccode=0x1F09, + unicodeslot=0x1F01, + }, + [0x1F02]={ + category="ll", + contextname="greekalphapsilivaria", + description="GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x1F00, 0x0300 }, + uccode=0x1F0A, + unicodeslot=0x1F02, + }, + [0x1F03]={ + category="ll", + contextname="greekalphadasiavaria", + description="GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x1F01, 0x0300 }, + uccode=0x1F0B, + unicodeslot=0x1F03, + }, + [0x1F04]={ + category="ll", + contextname="greekalphapsilitonos", + description="GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x1F00, 0x0301 }, + uccode=0x1F0C, + unicodeslot=0x1F04, + }, + [0x1F05]={ + category="ll", + contextname="greekalphadasiatonos", + description="GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x1F01, 0x0301 }, + uccode=0x1F0D, + unicodeslot=0x1F05, + }, + [0x1F06]={ + category="ll", + contextname="greekalphapsiliperispomeni", + description="GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x1F00, 0x0342 }, + uccode=0x1F0E, + unicodeslot=0x1F06, + }, + [0x1F07]={ + category="ll", + contextname="greekalphadasiaperispomeni", + description="GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x1F01, 0x0342 }, + uccode=0x1F0F, + unicodeslot=0x1F07, + }, + [0x1F08]={ + category="lu", + contextname="greekAlphapsili", + description="GREEK CAPITAL LETTER ALPHA WITH PSILI", + direction="l", + lccode=0x1F00, + linebreak="al", + shcode=0x0391, + specials={ "char", 0x0391, 0x0313 }, + unicodeslot=0x1F08, + }, + [0x1F09]={ + category="lu", + contextname="greekAlphadasia", + description="GREEK CAPITAL LETTER ALPHA WITH DASIA", + direction="l", + lccode=0x1F01, + linebreak="al", + shcode=0x0391, + specials={ "char", 0x0391, 0x0314 }, + unicodeslot=0x1F09, + }, + [0x1F0A]={ + category="lu", + contextname="greekAlphapsilivaria", + description="GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA", + direction="l", + lccode=0x1F02, + linebreak="al", + shcode=0x0391, + specials={ "char", 0x1F08, 0x0300 }, + unicodeslot=0x1F0A, + }, + [0x1F0B]={ + category="lu", + contextname="greekAlphadasiavaria", + description="GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA", + direction="l", + lccode=0x1F03, + linebreak="al", + shcode=0x0391, + specials={ "char", 0x1F09, 0x0300 }, + unicodeslot=0x1F0B, + }, + [0x1F0C]={ + category="lu", + contextname="greekAlphapsilitonos", + description="GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA", + direction="l", + lccode=0x1F04, + linebreak="al", + shcode=0x0391, + specials={ "char", 0x1F08, 0x0301 }, + unicodeslot=0x1F0C, + }, + [0x1F0D]={ + category="lu", + contextname="greekAlphadasiatonos", + description="GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA", + direction="l", + lccode=0x1F05, + linebreak="al", + shcode=0x0391, + specials={ "char", 0x1F09, 0x0301 }, + unicodeslot=0x1F0D, + }, + [0x1F0E]={ + category="lu", + contextname="greekAlphapsiliperispomeni", + description="GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI", + direction="l", + lccode=0x1F06, + linebreak="al", + shcode=0x0391, + specials={ "char", 0x1F08, 0x0342 }, + unicodeslot=0x1F0E, + }, + [0x1F0F]={ + category="lu", + contextname="greekAlphadasiaperispomeni", + description="GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI", + direction="l", + lccode=0x1F07, + linebreak="al", + shcode=0x0391, + specials={ "char", 0x1F09, 0x0342 }, + unicodeslot=0x1F0F, + }, + [0x1F10]={ + category="ll", + contextname="greekepsilonpsili", + description="GREEK SMALL LETTER EPSILON WITH PSILI", + direction="l", + linebreak="al", + shcode=0x03B5, + specials={ "char", 0x03B5, 0x0313 }, + uccode=0x1F18, + unicodeslot=0x1F10, + }, + [0x1F11]={ + category="ll", + contextname="greekepsilondasia", + description="GREEK SMALL LETTER EPSILON WITH DASIA", + direction="l", + linebreak="al", + shcode=0x03B5, + specials={ "char", 0x03B5, 0x0314 }, + uccode=0x1F19, + unicodeslot=0x1F11, + }, + [0x1F12]={ + category="ll", + contextname="greekepsilonpsilivaria", + description="GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA", + direction="l", + linebreak="al", + shcode=0x03B5, + specials={ "char", 0x1F10, 0x0300 }, + uccode=0x1F1A, + unicodeslot=0x1F12, + }, + [0x1F13]={ + category="ll", + contextname="greekepsilondasiavaria", + description="GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA", + direction="l", + linebreak="al", + shcode=0x03B5, + specials={ "char", 0x1F11, 0x0300 }, + uccode=0x1F1B, + unicodeslot=0x1F13, + }, + [0x1F14]={ + category="ll", + contextname="greekepsilonpsilitonos", + description="GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA", + direction="l", + linebreak="al", + shcode=0x03B5, + specials={ "char", 0x1F10, 0x0301 }, + uccode=0x1F1C, + unicodeslot=0x1F14, + }, + [0x1F15]={ + category="ll", + contextname="greekepsilondasiatonos", + description="GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA", + direction="l", + linebreak="al", + shcode=0x03B5, + specials={ "char", 0x1F11, 0x0301 }, + uccode=0x1F1D, + unicodeslot=0x1F15, + }, + [0x1F18]={ + category="lu", + contextname="greekEpsilonpsili", + description="GREEK CAPITAL LETTER EPSILON WITH PSILI", + direction="l", + lccode=0x1F10, + linebreak="al", + shcode=0x0395, + specials={ "char", 0x0395, 0x0313 }, + unicodeslot=0x1F18, + }, + [0x1F19]={ + category="lu", + contextname="greekEpsilondasia", + description="GREEK CAPITAL LETTER EPSILON WITH DASIA", + direction="l", + lccode=0x1F11, + linebreak="al", + shcode=0x0395, + specials={ "char", 0x0395, 0x0314 }, + unicodeslot=0x1F19, + }, + [0x1F1A]={ + category="lu", + contextname="greekEpsilonpsilivaria", + description="GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA", + direction="l", + lccode=0x1F12, + linebreak="al", + shcode=0x0395, + specials={ "char", 0x1F18, 0x0300 }, + unicodeslot=0x1F1A, + }, + [0x1F1B]={ + category="lu", + contextname="greekEpsilondasiavaria", + description="GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA", + direction="l", + lccode=0x1F13, + linebreak="al", + shcode=0x0395, + specials={ "char", 0x1F19, 0x0300 }, + unicodeslot=0x1F1B, + }, + [0x1F1C]={ + category="lu", + contextname="greekEpsilonpsilitonos", + description="GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA", + direction="l", + lccode=0x1F14, + linebreak="al", + shcode=0x0395, + specials={ "char", 0x1F18, 0x0301 }, + unicodeslot=0x1F1C, + }, + [0x1F1D]={ + category="lu", + contextname="greekEpsilondasiatonos", + description="GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA", + direction="l", + lccode=0x1F15, + linebreak="al", + shcode=0x0395, + specials={ "char", 0x1F19, 0x0301 }, + unicodeslot=0x1F1D, + }, + [0x1F20]={ + category="ll", + contextname="greeketapsili", + description="GREEK SMALL LETTER ETA WITH PSILI", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x03B7, 0x0313 }, + uccode=0x1F28, + unicodeslot=0x1F20, + }, + [0x1F21]={ + category="ll", + contextname="greeketadasia", + description="GREEK SMALL LETTER ETA WITH DASIA", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x03B7, 0x0314 }, + uccode=0x1F29, + unicodeslot=0x1F21, + }, + [0x1F22]={ + category="ll", + contextname="greeketapsilivaria", + description="GREEK SMALL LETTER ETA WITH PSILI AND VARIA", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x1F20, 0x0300 }, + uccode=0x1F2A, + unicodeslot=0x1F22, + }, + [0x1F23]={ + category="ll", + contextname="greeketadasiavaria", + description="GREEK SMALL LETTER ETA WITH DASIA AND VARIA", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x1F21, 0x0300 }, + uccode=0x1F2B, + unicodeslot=0x1F23, + }, + [0x1F24]={ + category="ll", + contextname="greeketapsilitonos", + description="GREEK SMALL LETTER ETA WITH PSILI AND OXIA", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x1F20, 0x0301 }, + uccode=0x1F2C, + unicodeslot=0x1F24, + }, + [0x1F25]={ + category="ll", + contextname="greeketadasiatonos", + description="GREEK SMALL LETTER ETA WITH DASIA AND OXIA", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x1F21, 0x0301 }, + uccode=0x1F2D, + unicodeslot=0x1F25, + }, + [0x1F26]={ + category="ll", + contextname="greeketapsiliperispomeni", + description="GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x1F20, 0x0342 }, + uccode=0x1F2E, + unicodeslot=0x1F26, + }, + [0x1F27]={ + category="ll", + contextname="greeketadasiaperispomeni", + description="GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x1F21, 0x0342 }, + uccode=0x1F2F, + unicodeslot=0x1F27, + }, + [0x1F28]={ + category="lu", + contextname="greekEtapsili", + description="GREEK CAPITAL LETTER ETA WITH PSILI", + direction="l", + lccode=0x1F20, + linebreak="al", + shcode=0x0397, + specials={ "char", 0x0397, 0x0313 }, + unicodeslot=0x1F28, + }, + [0x1F29]={ + category="lu", + contextname="greekEtadasia", + description="GREEK CAPITAL LETTER ETA WITH DASIA", + direction="l", + lccode=0x1F21, + linebreak="al", + shcode=0x0397, + specials={ "char", 0x0397, 0x0314 }, + unicodeslot=0x1F29, + }, + [0x1F2A]={ + category="lu", + contextname="greekEtapsilivaria", + description="GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA", + direction="l", + lccode=0x1F22, + linebreak="al", + shcode=0x0397, + specials={ "char", 0x1F28, 0x0300 }, + unicodeslot=0x1F2A, + }, + [0x1F2B]={ + category="lu", + contextname="greekEtadasiavaria", + description="GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA", + direction="l", + lccode=0x1F23, + linebreak="al", + shcode=0x0397, + specials={ "char", 0x1F29, 0x0300 }, + unicodeslot=0x1F2B, + }, + [0x1F2C]={ + category="lu", + contextname="greekEtapsilitonos", + description="GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA", + direction="l", + lccode=0x1F24, + linebreak="al", + shcode=0x0397, + specials={ "char", 0x1F28, 0x0301 }, + unicodeslot=0x1F2C, + }, + [0x1F2D]={ + category="lu", + contextname="greekEtadasiatonos", + description="GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA", + direction="l", + lccode=0x1F25, + linebreak="al", + shcode=0x0397, + specials={ "char", 0x1F29, 0x0301 }, + unicodeslot=0x1F2D, + }, + [0x1F2E]={ + category="lu", + contextname="greekEtapsiliperispomeni", + description="GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI", + direction="l", + lccode=0x1F26, + linebreak="al", + shcode=0x0397, + specials={ "char", 0x1F28, 0x0342 }, + unicodeslot=0x1F2E, + }, + [0x1F2F]={ + category="lu", + contextname="greekEtadasiaperispomeni", + description="GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI", + direction="l", + lccode=0x1F27, + linebreak="al", + shcode=0x0397, + specials={ "char", 0x1F29, 0x0342 }, + unicodeslot=0x1F2F, + }, + [0x1F30]={ + category="ll", + contextname="greekiotapsili", + description="GREEK SMALL LETTER IOTA WITH PSILI", + direction="l", + linebreak="al", + shcode=0x03B9, + specials={ "char", 0x03B9, 0x0313 }, + uccode=0x1F38, + unicodeslot=0x1F30, + }, + [0x1F31]={ + category="ll", + contextname="greekiotadasia", + description="GREEK SMALL LETTER IOTA WITH DASIA", + direction="l", + linebreak="al", + shcode=0x03B9, + specials={ "char", 0x03B9, 0x0314 }, + uccode=0x1F39, + unicodeslot=0x1F31, + }, + [0x1F32]={ + category="ll", + contextname="greekiotapsilivaria", + description="GREEK SMALL LETTER IOTA WITH PSILI AND VARIA", + direction="l", + linebreak="al", + shcode=0x03B9, + specials={ "char", 0x1F30, 0x0300 }, + uccode=0x1F3A, + unicodeslot=0x1F32, + }, + [0x1F33]={ + category="ll", + contextname="greekiotadasiavaria", + description="GREEK SMALL LETTER IOTA WITH DASIA AND VARIA", + direction="l", + linebreak="al", + shcode=0x03B9, + specials={ "char", 0x1F31, 0x0300 }, + uccode=0x1F3B, + unicodeslot=0x1F33, + }, + [0x1F34]={ + category="ll", + contextname="greekiotapsilitonos", + description="GREEK SMALL LETTER IOTA WITH PSILI AND OXIA", + direction="l", + linebreak="al", + shcode=0x03B9, + specials={ "char", 0x1F30, 0x0301 }, + uccode=0x1F3C, + unicodeslot=0x1F34, + }, + [0x1F35]={ + category="ll", + contextname="greekiotadasiatonos", + description="GREEK SMALL LETTER IOTA WITH DASIA AND OXIA", + direction="l", + linebreak="al", + shcode=0x03B9, + specials={ "char", 0x1F31, 0x0301 }, + uccode=0x1F3D, + unicodeslot=0x1F35, + }, + [0x1F36]={ + category="ll", + contextname="greekiotapsiliperispomeni", + description="GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI", + direction="l", + linebreak="al", + shcode=0x03B9, + specials={ "char", 0x1F30, 0x0342 }, + uccode=0x1F3E, + unicodeslot=0x1F36, + }, + [0x1F37]={ + category="ll", + contextname="greekiotadasiaperispomeni", + description="GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI", + direction="l", + linebreak="al", + shcode=0x03B9, + specials={ "char", 0x1F31, 0x0342 }, + uccode=0x1F3F, + unicodeslot=0x1F37, + }, + [0x1F38]={ + category="lu", + contextname="greekIotapsili", + description="GREEK CAPITAL LETTER IOTA WITH PSILI", + direction="l", + lccode=0x1F30, + linebreak="al", + shcode=0x0399, + specials={ "char", 0x0399, 0x0313 }, + unicodeslot=0x1F38, + }, + [0x1F39]={ + category="lu", + contextname="greekIotadasia", + description="GREEK CAPITAL LETTER IOTA WITH DASIA", + direction="l", + lccode=0x1F31, + linebreak="al", + shcode=0x0399, + specials={ "char", 0x0399, 0x0314 }, + unicodeslot=0x1F39, + }, + [0x1F3A]={ + category="lu", + contextname="greekIotapsilivaria", + description="GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA", + direction="l", + lccode=0x1F32, + linebreak="al", + shcode=0x0399, + specials={ "char", 0x1F38, 0x0300 }, + unicodeslot=0x1F3A, + }, + [0x1F3B]={ + category="lu", + contextname="greekIotadasiavaria", + description="GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA", + direction="l", + lccode=0x1F33, + linebreak="al", + shcode=0x0399, + specials={ "char", 0x1F39, 0x0300 }, + unicodeslot=0x1F3B, + }, + [0x1F3C]={ + category="lu", + contextname="greekIotapsilitonos", + description="GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA", + direction="l", + lccode=0x1F34, + linebreak="al", + shcode=0x0399, + specials={ "char", 0x1F38, 0x0301 }, + unicodeslot=0x1F3C, + }, + [0x1F3D]={ + category="lu", + contextname="greekIotadasiatonos", + description="GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA", + direction="l", + lccode=0x1F35, + linebreak="al", + shcode=0x0399, + specials={ "char", 0x1F39, 0x0301 }, + unicodeslot=0x1F3D, + }, + [0x1F3E]={ + category="lu", + contextname="greekIotapsiliperispomeni", + description="GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI", + direction="l", + lccode=0x1F36, + linebreak="al", + shcode=0x0399, + specials={ "char", 0x1F38, 0x0342 }, + unicodeslot=0x1F3E, + }, + [0x1F3F]={ + category="lu", + contextname="greekIotadasiaperispomeni", + description="GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI", + direction="l", + lccode=0x1F37, + linebreak="al", + shcode=0x0399, + specials={ "char", 0x1F39, 0x0342 }, + unicodeslot=0x1F3F, + }, + [0x1F40]={ + category="ll", + contextname="greekomicronpsili", + description="GREEK SMALL LETTER OMICRON WITH PSILI", + direction="l", + linebreak="al", + shcode=0x03BF, + specials={ "char", 0x03BF, 0x0313 }, + uccode=0x1F48, + unicodeslot=0x1F40, + }, + [0x1F41]={ + category="ll", + contextname="greekomicrondasia", + description="GREEK SMALL LETTER OMICRON WITH DASIA", + direction="l", + linebreak="al", + shcode=0x03BF, + specials={ "char", 0x03BF, 0x0314 }, + uccode=0x1F49, + unicodeslot=0x1F41, + }, + [0x1F42]={ + category="ll", + contextname="greekomicronpsilivaria", + description="GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA", + direction="l", + linebreak="al", + shcode=0x03BF, + specials={ "char", 0x1F40, 0x0300 }, + uccode=0x1F4A, + unicodeslot=0x1F42, + }, + [0x1F43]={ + category="ll", + contextname="greekomicrondasiavaria", + description="GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA", + direction="l", + linebreak="al", + shcode=0x03BF, + specials={ "char", 0x1F41, 0x0300 }, + uccode=0x1F4B, + unicodeslot=0x1F43, + }, + [0x1F44]={ + category="ll", + contextname="greekomicronpsilitonos", + description="GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA", + direction="l", + linebreak="al", + shcode=0x03BF, + specials={ "char", 0x1F40, 0x0301 }, + uccode=0x1F4C, + unicodeslot=0x1F44, + }, + [0x1F45]={ + category="ll", + contextname="greekomicrondasiatonos", + description="GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA", + direction="l", + linebreak="al", + shcode=0x03BF, + specials={ "char", 0x1F41, 0x0301 }, + uccode=0x1F4D, + unicodeslot=0x1F45, + }, + [0x1F48]={ + category="lu", + contextname="greekOmicronpsili", + description="GREEK CAPITAL LETTER OMICRON WITH PSILI", + direction="l", + lccode=0x1F40, + linebreak="al", + shcode=0x039F, + specials={ "char", 0x039F, 0x0313 }, + unicodeslot=0x1F48, + }, + [0x1F49]={ + category="lu", + contextname="greekOmicrondasia", + description="GREEK CAPITAL LETTER OMICRON WITH DASIA", + direction="l", + lccode=0x1F41, + linebreak="al", + shcode=0x039F, + specials={ "char", 0x039F, 0x0314 }, + unicodeslot=0x1F49, + }, + [0x1F4A]={ + category="lu", + contextname="greekOmicronpsilivaria", + description="GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA", + direction="l", + lccode=0x1F42, + linebreak="al", + shcode=0x039F, + specials={ "char", 0x1F48, 0x0300 }, + unicodeslot=0x1F4A, + }, + [0x1F4B]={ + category="lu", + contextname="greekOmicrondasiavaria", + description="GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA", + direction="l", + lccode=0x1F43, + linebreak="al", + shcode=0x039F, + specials={ "char", 0x1F49, 0x0300 }, + unicodeslot=0x1F4B, + }, + [0x1F4C]={ + category="lu", + contextname="greekOmicronpsilitonos", + description="GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA", + direction="l", + lccode=0x1F44, + linebreak="al", + shcode=0x039F, + specials={ "char", 0x1F48, 0x0301 }, + unicodeslot=0x1F4C, + }, + [0x1F4D]={ + category="lu", + contextname="greekOmicrondasiatonos", + description="GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA", + direction="l", + lccode=0x1F45, + linebreak="al", + shcode=0x039F, + specials={ "char", 0x1F49, 0x0301 }, + unicodeslot=0x1F4D, + }, + [0x1F50]={ + category="ll", + contextname="greekupsilonpsili", + description="GREEK SMALL LETTER UPSILON WITH PSILI", + direction="l", + linebreak="al", + shcode=0x03C5, + specials={ "char", 0x03C5, 0x0313 }, + unicodeslot=0x1F50, + }, + [0x1F51]={ + category="ll", + contextname="greekupsilondasia", + description="GREEK SMALL LETTER UPSILON WITH DASIA", + direction="l", + linebreak="al", + shcode=0x03C5, + specials={ "char", 0x03C5, 0x0314 }, + uccode=0x1F59, + unicodeslot=0x1F51, + }, + [0x1F52]={ + category="ll", + contextname="greekupsilonpsilivaria", + description="GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA", + direction="l", + linebreak="al", + shcode=0x03C5, + specials={ "char", 0x1F50, 0x0300 }, + unicodeslot=0x1F52, + }, + [0x1F53]={ + category="ll", + contextname="greekupsilondasiavaria", + description="GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA", + direction="l", + linebreak="al", + shcode=0x03C5, + specials={ "char", 0x1F51, 0x0300 }, + uccode=0x1F5B, + unicodeslot=0x1F53, + }, + [0x1F54]={ + category="ll", + contextname="greekupsilonpsilitonos", + description="GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA", + direction="l", + linebreak="al", + shcode=0x03C5, + specials={ "char", 0x1F50, 0x0301 }, + unicodeslot=0x1F54, + }, + [0x1F55]={ + category="ll", + contextname="greekupsilondasiatonos", + description="GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA", + direction="l", + linebreak="al", + shcode=0x03C5, + specials={ "char", 0x1F51, 0x0301 }, + uccode=0x1F5D, + unicodeslot=0x1F55, + }, + [0x1F56]={ + category="ll", + contextname="greekupsilonpsiliperispomeni", + description="GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI", + direction="l", + linebreak="al", + shcode=0x03C5, + specials={ "char", 0x1F50, 0x0342 }, + unicodeslot=0x1F56, + }, + [0x1F57]={ + category="ll", + contextname="greekupsilondasiaperispomeni", + description="GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI", + direction="l", + linebreak="al", + shcode=0x03C5, + specials={ "char", 0x1F51, 0x0342 }, + uccode=0x1F5F, + unicodeslot=0x1F57, + }, + [0x1F59]={ + category="lu", + contextname="greekUpsilondasia", + description="GREEK CAPITAL LETTER UPSILON WITH DASIA", + direction="l", + lccode=0x1F51, + linebreak="al", + shcode=0x03A5, + specials={ "char", 0x03A5, 0x0314 }, + unicodeslot=0x1F59, + }, + [0x1F5B]={ + category="lu", + contextname="greekUpsilondasiavaria", + description="GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA", + direction="l", + lccode=0x1F53, + linebreak="al", + shcode=0x03A5, + specials={ "char", 0x1F59, 0x0300 }, + unicodeslot=0x1F5B, + }, + [0x1F5D]={ + category="lu", + contextname="greekUpsilondasiatonos", + description="GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA", + direction="l", + lccode=0x1F55, + linebreak="al", + shcode=0x03A5, + specials={ "char", 0x1F59, 0x0301 }, + unicodeslot=0x1F5D, + }, + [0x1F5F]={ + category="lu", + contextname="greekUpsilondasiaperispomeni", + description="GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI", + direction="l", + lccode=0x1F57, + linebreak="al", + shcode=0x03A5, + specials={ "char", 0x1F59, 0x0342 }, + unicodeslot=0x1F5F, + }, + [0x1F60]={ + category="ll", + contextname="greekomegapsili", + description="GREEK SMALL LETTER OMEGA WITH PSILI", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x03C9, 0x0313 }, + uccode=0x1F68, + unicodeslot=0x1F60, + }, + [0x1F61]={ + category="ll", + contextname="greekomegadasia", + description="GREEK SMALL LETTER OMEGA WITH DASIA", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x03C9, 0x0314 }, + uccode=0x1F69, + unicodeslot=0x1F61, + }, + [0x1F62]={ + category="ll", + contextname="greekomegapsilivaria", + description="GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x1F60, 0x0300 }, + uccode=0x1F6A, + unicodeslot=0x1F62, + }, + [0x1F63]={ + category="ll", + contextname="greekomegadasiavaria", + description="GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x1F61, 0x0300 }, + uccode=0x1F6B, + unicodeslot=0x1F63, + }, + [0x1F64]={ + category="ll", + contextname="greekomegapsilitonos", + description="GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x1F60, 0x0301 }, + uccode=0x1F6C, + unicodeslot=0x1F64, + }, + [0x1F65]={ + category="ll", + contextname="greekomegadasiatonos", + description="GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x1F61, 0x0301 }, + uccode=0x1F6D, + unicodeslot=0x1F65, + }, + [0x1F66]={ + category="ll", + contextname="greekomegapsiliperispomeni", + description="GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x1F60, 0x0342 }, + uccode=0x1F6E, + unicodeslot=0x1F66, + }, + [0x1F67]={ + category="ll", + contextname="greekomegadasiaperispomeni", + description="GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x1F61, 0x0342 }, + uccode=0x1F6F, + unicodeslot=0x1F67, + }, + [0x1F68]={ + category="lu", + contextname="greekOmegapsili", + description="GREEK CAPITAL LETTER OMEGA WITH PSILI", + direction="l", + lccode=0x1F60, + linebreak="al", + shcode=0x03A9, + specials={ "char", 0x03A9, 0x0313 }, + unicodeslot=0x1F68, + }, + [0x1F69]={ + category="lu", + contextname="greekOmegadasia", + description="GREEK CAPITAL LETTER OMEGA WITH DASIA", + direction="l", + lccode=0x1F61, + linebreak="al", + shcode=0x03A9, + specials={ "char", 0x03A9, 0x0314 }, + unicodeslot=0x1F69, + }, + [0x1F6A]={ + category="lu", + contextname="greekOmegapsilivaria", + description="GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA", + direction="l", + lccode=0x1F62, + linebreak="al", + shcode=0x03A9, + specials={ "char", 0x1F68, 0x0300 }, + unicodeslot=0x1F6A, + }, + [0x1F6B]={ + category="lu", + contextname="greekOmegadasiavaria", + description="GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA", + direction="l", + lccode=0x1F63, + linebreak="al", + shcode=0x03A9, + specials={ "char", 0x1F69, 0x0300 }, + unicodeslot=0x1F6B, + }, + [0x1F6C]={ + category="lu", + contextname="greekOmegapsilitonos", + description="GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA", + direction="l", + lccode=0x1F64, + linebreak="al", + shcode=0x03A9, + specials={ "char", 0x1F68, 0x0301 }, + unicodeslot=0x1F6C, + }, + [0x1F6D]={ + category="lu", + contextname="greekOmegadasiatonos", + description="GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA", + direction="l", + lccode=0x1F65, + linebreak="al", + shcode=0x03A9, + specials={ "char", 0x1F69, 0x0301 }, + unicodeslot=0x1F6D, + }, + [0x1F6E]={ + category="lu", + contextname="greekOmegapsiliperispomeni", + description="GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI", + direction="l", + lccode=0x1F66, + linebreak="al", + shcode=0x03A9, + specials={ "char", 0x1F68, 0x0342 }, + unicodeslot=0x1F6E, + }, + [0x1F6F]={ + category="lu", + contextname="greekOmegadasiaperispomeni", + description="GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI", + direction="l", + lccode=0x1F67, + linebreak="al", + shcode=0x03A9, + specials={ "char", 0x1F69, 0x0342 }, + unicodeslot=0x1F6F, + }, + [0x1F70]={ + category="ll", + contextname="greekalphavaria", + description="GREEK SMALL LETTER ALPHA WITH VARIA", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x03B1, 0x0300 }, + uccode=0x1FBA, + unicodeslot=0x1F70, + }, + [0x1F71]={ + category="ll", + contextname="greekalphaoxia", + description="GREEK SMALL LETTER ALPHA WITH OXIA", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x03AC }, + uccode=0x1FBB, + unicodeslot=0x1F71, + }, + [0x1F72]={ + category="ll", + contextname="greekepsilonvaria", + description="GREEK SMALL LETTER EPSILON WITH VARIA", + direction="l", + linebreak="al", + shcode=0x03B5, + specials={ "char", 0x03B5, 0x0300 }, + uccode=0x1FC8, + unicodeslot=0x1F72, + }, + [0x1F73]={ + category="ll", + contextname="greekepsilonoxia", + description="GREEK SMALL LETTER EPSILON WITH OXIA", + direction="l", + linebreak="al", + shcode=0x03B5, + specials={ "char", 0x03AD }, + uccode=0x1FC9, + unicodeslot=0x1F73, + }, + [0x1F74]={ + category="ll", + contextname="greeketavaria", + description="GREEK SMALL LETTER ETA WITH VARIA", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x03B7, 0x0300 }, + uccode=0x1FCA, + unicodeslot=0x1F74, + }, + [0x1F75]={ + category="ll", + contextname="greeketaoxia", + description="GREEK SMALL LETTER ETA WITH OXIA", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x03AE }, + uccode=0x1FCB, + unicodeslot=0x1F75, + }, + [0x1F76]={ + category="ll", + contextname="greekiotavaria", + description="GREEK SMALL LETTER IOTA WITH VARIA", + direction="l", + linebreak="al", + shcode=0x03B9, + specials={ "char", 0x03B9, 0x0300 }, + uccode=0x1FDA, + unicodeslot=0x1F76, + }, + [0x1F77]={ + category="ll", + contextname="greekiotaoxia", + description="GREEK SMALL LETTER IOTA WITH OXIA", + direction="l", + linebreak="al", + shcode=0x03B9, + specials={ "char", 0x03AF }, + uccode=0x1FDB, + unicodeslot=0x1F77, + }, + [0x1F78]={ + category="ll", + contextname="greekomicronvaria", + description="GREEK SMALL LETTER OMICRON WITH VARIA", + direction="l", + linebreak="al", + shcode=0x03BF, + specials={ "char", 0x03BF, 0x0300 }, + uccode=0x1FF8, + unicodeslot=0x1F78, + }, + [0x1F79]={ + category="ll", + contextname="greekomicronoxia", + description="GREEK SMALL LETTER OMICRON WITH OXIA", + direction="l", + linebreak="al", + shcode=0x03BF, + specials={ "char", 0x03CC }, + uccode=0x1FF9, + unicodeslot=0x1F79, + }, + [0x1F7A]={ + category="ll", + contextname="greekupsilonvaria", + description="GREEK SMALL LETTER UPSILON WITH VARIA", + direction="l", + linebreak="al", + shcode=0x03C5, + specials={ "char", 0x03C5, 0x0300 }, + uccode=0x1FEA, + unicodeslot=0x1F7A, + }, + [0x1F7B]={ + category="ll", + contextname="greekupsilonoxia", + description="GREEK SMALL LETTER UPSILON WITH OXIA", + direction="l", + linebreak="al", + shcode=0x03C5, + specials={ "char", 0x03CD }, + uccode=0x1FEB, + unicodeslot=0x1F7B, + }, + [0x1F7C]={ + category="ll", + contextname="greekomegavaria", + description="GREEK SMALL LETTER OMEGA WITH VARIA", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x03C9, 0x0300 }, + uccode=0x1FFA, + unicodeslot=0x1F7C, + }, + [0x1F7D]={ + category="ll", + contextname="greekomegaoxia", + description="GREEK SMALL LETTER OMEGA WITH OXIA", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x03CE }, + uccode=0x1FFB, + unicodeslot=0x1F7D, + }, + [0x1F80]={ + category="ll", + contextname="greekalphaiotasubpsili", + description="GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x1F00, 0x0345 }, + uccode=0x1F88, + unicodeslot=0x1F80, + }, + [0x1F81]={ + category="ll", + contextname="greekalphaiotasubdasia", + description="GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x1F01, 0x0345 }, + uccode=0x1F89, + unicodeslot=0x1F81, + }, + [0x1F82]={ + category="ll", + contextname="greekalphaiotasubpsilivaria", + description="GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x1F02, 0x0345 }, + uccode=0x1F8A, + unicodeslot=0x1F82, + }, + [0x1F83]={ + category="ll", + contextname="greekalphaiotasubdasiavaria", + description="GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x1F03, 0x0345 }, + uccode=0x1F8B, + unicodeslot=0x1F83, + }, + [0x1F84]={ + category="ll", + contextname="greekalphaiotasubpsilitonos", + description="GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x1F04, 0x0345 }, + uccode=0x1F8C, + unicodeslot=0x1F84, + }, + [0x1F85]={ + category="ll", + contextname="greekalphaiotasubdasiatonos", + description="GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x1F05, 0x0345 }, + uccode=0x1F8D, + unicodeslot=0x1F85, + }, + [0x1F86]={ + category="ll", + contextname="greekalphaiotasubpsiliperispomeni", + description="GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x1F06, 0x0345 }, + uccode=0x1F8E, + unicodeslot=0x1F86, + }, + [0x1F87]={ + category="ll", + contextname="greekalphaiotasubdasiaperispomeni", + description="GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x1F07, 0x0345 }, + uccode=0x1F8F, + unicodeslot=0x1F87, + }, + [0x1F88]={ + category="lt", + contextname="greekAlphaiotasubpsili", + description="GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI", + direction="l", + lccode=0x1F80, + linebreak="al", + shcode=0x0391, + specials={ "char", 0x1F08, 0x0345 }, + unicodeslot=0x1F88, + }, + [0x1F89]={ + category="lt", + contextname="greekAlphaiotasubdasia", + description="GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI", + direction="l", + lccode=0x1F81, + linebreak="al", + shcode=0x0391, + specials={ "char", 0x1F09, 0x0345 }, + unicodeslot=0x1F89, + }, + [0x1F8A]={ + category="lt", + contextname="greekAlphaiotasubpsilivaria", + description="GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI", + direction="l", + lccode=0x1F82, + linebreak="al", + shcode=0x0391, + specials={ "char", 0x1F0A, 0x0345 }, + unicodeslot=0x1F8A, + }, + [0x1F8B]={ + category="lt", + contextname="greekAlphaiotasubdasiavaria", + description="GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI", + direction="l", + lccode=0x1F83, + linebreak="al", + shcode=0x0391, + specials={ "char", 0x1F0B, 0x0345 }, + unicodeslot=0x1F8B, + }, + [0x1F8C]={ + category="lt", + contextname="greekAlphaiotasubpsilitonos", + description="GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI", + direction="l", + lccode=0x1F84, + linebreak="al", + shcode=0x0391, + specials={ "char", 0x1F0C, 0x0345 }, + unicodeslot=0x1F8C, + }, + [0x1F8D]={ + category="lt", + contextname="greekAlphaiotasubdasiatonos", + description="GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI", + direction="l", + lccode=0x1F85, + linebreak="al", + shcode=0x0391, + specials={ "char", 0x1F0D, 0x0345 }, + unicodeslot=0x1F8D, + }, + [0x1F8E]={ + category="lt", + contextname="greekAlphaiotasubpsiliperispomeni", + description="GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI", + direction="l", + lccode=0x1F86, + linebreak="al", + shcode=0x0391, + specials={ "char", 0x1F0E, 0x0345 }, + unicodeslot=0x1F8E, + }, + [0x1F8F]={ + category="lt", + contextname="greekAlphaiotasubdasiaperispomeni", + description="GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI", + direction="l", + lccode=0x1F87, + linebreak="al", + shcode=0x0391, + specials={ "char", 0x1F0F, 0x0345 }, + unicodeslot=0x1F8F, + }, + [0x1F90]={ + category="ll", + contextname="greeketaiotasubpsili", + description="GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x1F20, 0x0345 }, + uccode=0x1F98, + unicodeslot=0x1F90, + }, + [0x1F91]={ + category="ll", + contextname="greeketaiotasubdasia", + description="GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x1F21, 0x0345 }, + uccode=0x1F99, + unicodeslot=0x1F91, + }, + [0x1F92]={ + category="ll", + contextname="greeketaiotasubpsilivaria", + description="GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x1F22, 0x0345 }, + uccode=0x1F9A, + unicodeslot=0x1F92, + }, + [0x1F93]={ + category="ll", + contextname="greeketaiotasubdasiavaria", + description="GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x1F23, 0x0345 }, + uccode=0x1F9B, + unicodeslot=0x1F93, + }, + [0x1F94]={ + category="ll", + contextname="greeketaiotasubpsilitonos", + description="GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x1F24, 0x0345 }, + uccode=0x1F9C, + unicodeslot=0x1F94, + }, + [0x1F95]={ + category="ll", + contextname="greeketaiotasubdasiatonos", + description="GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x1F25, 0x0345 }, + uccode=0x1F9D, + unicodeslot=0x1F95, + }, + [0x1F96]={ + category="ll", + contextname="greeketaiotasubpsiliperispomeni", + description="GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x1F26, 0x0345 }, + uccode=0x1F9E, + unicodeslot=0x1F96, + }, + [0x1F97]={ + category="ll", + contextname="greeketaiotasubdasiaperispomeni", + description="GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x1F27, 0x0345 }, + uccode=0x1F9F, + unicodeslot=0x1F97, + }, + [0x1F98]={ + category="lt", + contextname="greekEtaiotasubpsili", + description="GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI", + direction="l", + lccode=0x1F90, + linebreak="al", + shcode=0x0397, + specials={ "char", 0x1F28, 0x0345 }, + unicodeslot=0x1F98, + }, + [0x1F99]={ + category="lt", + contextname="greekEtaiotasubdasia", + description="GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI", + direction="l", + lccode=0x1F91, + linebreak="al", + shcode=0x0397, + specials={ "char", 0x1F29, 0x0345 }, + unicodeslot=0x1F99, + }, + [0x1F9A]={ + category="lt", + contextname="greekEtaiotasubpsilivaria", + description="GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI", + direction="l", + lccode=0x1F92, + linebreak="al", + shcode=0x0397, + specials={ "char", 0x1F2A, 0x0345 }, + unicodeslot=0x1F9A, + }, + [0x1F9B]={ + category="lt", + contextname="greekEtaiotasubdasiavaria", + description="GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI", + direction="l", + lccode=0x1F93, + linebreak="al", + shcode=0x0397, + specials={ "char", 0x1F2B, 0x0345 }, + unicodeslot=0x1F9B, + }, + [0x1F9C]={ + category="lt", + contextname="greekEtaiotasubpsilitonos", + description="GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI", + direction="l", + lccode=0x1F94, + linebreak="al", + shcode=0x0397, + specials={ "char", 0x1F2C, 0x0345 }, + unicodeslot=0x1F9C, + }, + [0x1F9D]={ + category="lt", + contextname="greekEtaiotasubdasiatonos", + description="GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI", + direction="l", + lccode=0x1F95, + linebreak="al", + shcode=0x0397, + specials={ "char", 0x1F2D, 0x0345 }, + unicodeslot=0x1F9D, + }, + [0x1F9E]={ + category="lt", + contextname="greekEtaiotasubpsiliperispomeni", + description="GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI", + direction="l", + lccode=0x1F96, + linebreak="al", + shcode=0x0397, + specials={ "char", 0x1F2E, 0x0345 }, + unicodeslot=0x1F9E, + }, + [0x1F9F]={ + category="lt", + contextname="greekEtaiotasubdasiaperispomeni", + description="GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI", + direction="l", + lccode=0x1F97, + linebreak="al", + shcode=0x0397, + specials={ "char", 0x1F2F, 0x0345 }, + unicodeslot=0x1F9F, + }, + [0x1FA0]={ + category="ll", + contextname="greekomegaiotasubpsili", + description="GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x1F60, 0x0345 }, + uccode=0x1FA8, + unicodeslot=0x1FA0, + }, + [0x1FA1]={ + category="ll", + contextname="greekomegaiotasubdasia", + description="GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x1F61, 0x0345 }, + uccode=0x1FA9, + unicodeslot=0x1FA1, + }, + [0x1FA2]={ + category="ll", + contextname="greekomegaiotasubpsilivaria", + description="GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x1F62, 0x0345 }, + uccode=0x1FAA, + unicodeslot=0x1FA2, + }, + [0x1FA3]={ + category="ll", + contextname="greekomegaiotasubdasiavaria", + description="GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x1F63, 0x0345 }, + uccode=0x1FAB, + unicodeslot=0x1FA3, + }, + [0x1FA4]={ + category="ll", + contextname="greekomegaiotasubpsilitonos", + description="GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x1F64, 0x0345 }, + uccode=0x1FAC, + unicodeslot=0x1FA4, + }, + [0x1FA5]={ + category="ll", + contextname="greekomegaiotasubdasiatonos", + description="GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x1F65, 0x0345 }, + uccode=0x1FAD, + unicodeslot=0x1FA5, + }, + [0x1FA6]={ + category="ll", + contextname="greekomegaiotasubpsiliperispomeni", + description="GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x1F66, 0x0345 }, + uccode=0x1FAE, + unicodeslot=0x1FA6, + }, + [0x1FA7]={ + category="ll", + contextname="greekomegaiotasubdasiaperispomeni", + description="GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x1F67, 0x0345 }, + uccode=0x1FAF, + unicodeslot=0x1FA7, + }, + [0x1FA8]={ + category="lt", + contextname="greekOmegaiotasubpsili", + description="GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI", + direction="l", + lccode=0x1FA0, + linebreak="al", + shcode=0x03A9, + specials={ "char", 0x1F68, 0x0345 }, + unicodeslot=0x1FA8, + }, + [0x1FA9]={ + category="lt", + contextname="greekOmegaiotasubdasia", + description="GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI", + direction="l", + lccode=0x1FA1, + linebreak="al", + shcode=0x03A9, + specials={ "char", 0x1F69, 0x0345 }, + unicodeslot=0x1FA9, + }, + [0x1FAA]={ + category="lt", + contextname="greekOmegaiotasubpsilivaria", + description="GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI", + direction="l", + lccode=0x1FA2, + linebreak="al", + shcode=0x03A9, + specials={ "char", 0x1F6A, 0x0345 }, + unicodeslot=0x1FAA, + }, + [0x1FAB]={ + category="lt", + contextname="greekOmegaiotasubdasiavaria", + description="GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI", + direction="l", + lccode=0x1FA3, + linebreak="al", + shcode=0x03A9, + specials={ "char", 0x1F6B, 0x0345 }, + unicodeslot=0x1FAB, + }, + [0x1FAC]={ + category="lt", + contextname="greekOmegaiotasubpsilitonos", + description="GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI", + direction="l", + lccode=0x1FA4, + linebreak="al", + shcode=0x03A9, + specials={ "char", 0x1F6C, 0x0345 }, + unicodeslot=0x1FAC, + }, + [0x1FAD]={ + category="lt", + contextname="greekOmegaiotasubdasiatonos", + description="GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI", + direction="l", + lccode=0x1FA5, + linebreak="al", + shcode=0x03A9, + specials={ "char", 0x1F6D, 0x0345 }, + unicodeslot=0x1FAD, + }, + [0x1FAE]={ + category="lt", + contextname="greekOmegaiotasubpsiliperispomeni", + description="GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI", + direction="l", + lccode=0x1FA6, + linebreak="al", + shcode=0x03A9, + specials={ "char", 0x1F6E, 0x0345 }, + unicodeslot=0x1FAE, + }, + [0x1FAF]={ + category="lt", + contextname="greekOmegaiotasubdasiaperispomeni", + description="GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI", + direction="l", + lccode=0x1FA7, + linebreak="al", + shcode=0x03A9, + specials={ "char", 0x1F6F, 0x0345 }, + unicodeslot=0x1FAF, + }, + [0x1FB0]={ + category="ll", + contextname="greekalphavrachy", + description="GREEK SMALL LETTER ALPHA WITH VRACHY", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x03B1, 0x0306 }, + uccode=0x1FB8, + unicodeslot=0x1FB0, + }, + [0x1FB1]={ + category="ll", + contextname="greekalphamacron", + description="GREEK SMALL LETTER ALPHA WITH MACRON", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x03B1, 0x0304 }, + uccode=0x1FB9, + unicodeslot=0x1FB1, + }, + [0x1FB2]={ + category="ll", + contextname="greekalphaiotasubvaria", + description="GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x1F70, 0x0345 }, + unicodeslot=0x1FB2, + }, + [0x1FB3]={ + category="ll", + contextname="greekalphaiotasub", + description="GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x03B1, 0x0345 }, + uccode=0x1FBC, + unicodeslot=0x1FB3, + }, + [0x1FB4]={ + category="ll", + contextname="greekalphaiotasubtonos", + description="GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x03AC, 0x0345 }, + unicodeslot=0x1FB4, + }, + [0x1FB6]={ + category="ll", + contextname="greekalphaperispomeni", + description="GREEK SMALL LETTER ALPHA WITH PERISPOMENI", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x03B1, 0x0342 }, + unicodeslot=0x1FB6, + }, + [0x1FB7]={ + category="ll", + contextname="greekalphaiotasubperispomeni", + description="GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B1, + specials={ "char", 0x1FB6, 0x0345 }, + unicodeslot=0x1FB7, + }, + [0x1FB8]={ + category="lu", + contextname="greekAlphavrachy", + description="GREEK CAPITAL LETTER ALPHA WITH VRACHY", + direction="l", + lccode=0x1FB0, + linebreak="al", + shcode=0x0391, + specials={ "char", 0x0391, 0x0306 }, + unicodeslot=0x1FB8, + }, + [0x1FB9]={ + category="lu", + contextname="greekAlphamacron", + description="GREEK CAPITAL LETTER ALPHA WITH MACRON", + direction="l", + lccode=0x1FB1, + linebreak="al", + shcode=0x0391, + specials={ "char", 0x0391, 0x0304 }, + unicodeslot=0x1FB9, + }, + [0x1FBA]={ + category="lu", + contextname="greekAlphavaria", + description="GREEK CAPITAL LETTER ALPHA WITH VARIA", + direction="l", + lccode=0x1F70, + linebreak="al", + shcode=0x0391, + specials={ "char", 0x0391, 0x0300 }, + unicodeslot=0x1FBA, + }, + [0x1FBB]={ + category="lu", + contextname="greekAlphatonos", + description="GREEK CAPITAL LETTER ALPHA WITH OXIA", + direction="l", + lccode=0x1F71, + linebreak="al", + shcode=0x0391, + specials={ "char", 0x0386 }, + unicodeslot=0x1FBB, + }, + [0x1FBC]={ + category="lt", + contextname="greekAlphaiotasub", + description="GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI", + direction="l", + lccode=0x1FB3, + linebreak="al", + shcode=0x0391, + specials={ "char", 0x0391, 0x0345 }, + unicodeslot=0x1FBC, + }, + [0x1FBD]={ + category="sk", + contextname="greekCoronis", + description="GREEK KORONIS", + direction="on", + linebreak="al", + specials={ "compat", 0x0020, 0x0313 }, + unicodeslot=0x1FBD, + }, + [0x1FBE]={ + category="ll", + contextname="greekprosgegrammeni", + description="GREEK PROSGEGRAMMENI", + direction="l", + linebreak="al", + specials={ "char", 0x03B9 }, + uccode=0x0399, + unicodeslot=0x1FBE, + }, + [0x1FBF]={ + category="sk", + contextname="greekpsili", + description="GREEK PSILI", + direction="on", + linebreak="al", + specials={ "compat", 0x0020, 0x0313 }, + unicodeslot=0x1FBF, + }, + [0x1FC0]={ + category="sk", + contextname="greekperispomeni", + description="GREEK PERISPOMENI", + direction="on", + linebreak="al", + specials={ "compat", 0x0020, 0x0342 }, + unicodeslot=0x1FC0, + }, + [0x1FC1]={ + category="sk", + contextname="greekdialytikaperispomeni", + description="GREEK DIALYTIKA AND PERISPOMENI", + direction="on", + linebreak="al", + specials={ "char", 0x00A8, 0x0342 }, + unicodeslot=0x1FC1, + }, + [0x1FC2]={ + category="ll", + contextname="greeketaiotasubvaria", + description="GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x1F74, 0x0345 }, + unicodeslot=0x1FC2, + }, + [0x1FC3]={ + category="ll", + contextname="greeketaiotasub", + description="GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x03B7, 0x0345 }, + uccode=0x1FCC, + unicodeslot=0x1FC3, + }, + [0x1FC4]={ + category="ll", + contextname="greeketaiotasubtonos", + description="GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x03AE, 0x0345 }, + unicodeslot=0x1FC4, + }, + [0x1FC6]={ + category="ll", + contextname="greeketaperispomeni", + description="GREEK SMALL LETTER ETA WITH PERISPOMENI", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x03B7, 0x0342 }, + unicodeslot=0x1FC6, + }, + [0x1FC7]={ + category="ll", + contextname="greeketaiotasubperispomeni", + description="GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03B7, + specials={ "char", 0x1FC6, 0x0345 }, + unicodeslot=0x1FC7, + }, + [0x1FC8]={ + category="lu", + contextname="greekEpsilonvaria", + description="GREEK CAPITAL LETTER EPSILON WITH VARIA", + direction="l", + lccode=0x1F72, + linebreak="al", + shcode=0x0395, + specials={ "char", 0x0395, 0x0300 }, + unicodeslot=0x1FC8, + }, + [0x1FC9]={ + category="lu", + contextname="greekEpsilontonos", + description="GREEK CAPITAL LETTER EPSILON WITH OXIA", + direction="l", + lccode=0x1F73, + linebreak="al", + shcode=0x0395, + specials={ "char", 0x0388 }, + unicodeslot=0x1FC9, + }, + [0x1FCA]={ + category="lu", + contextname="greekEtavaria", + description="GREEK CAPITAL LETTER ETA WITH VARIA", + direction="l", + lccode=0x1F74, + linebreak="al", + shcode=0x0397, + specials={ "char", 0x0397, 0x0300 }, + unicodeslot=0x1FCA, + }, + [0x1FCB]={ + category="lu", + contextname="greekEtatonos", + description="GREEK CAPITAL LETTER ETA WITH OXIA", + direction="l", + lccode=0x1F75, + linebreak="al", + shcode=0x0397, + specials={ "char", 0x0389 }, + unicodeslot=0x1FCB, + }, + [0x1FCC]={ + category="lt", + contextname="greekEtaiotasub", + description="GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI", + direction="l", + lccode=0x1FC3, + linebreak="al", + shcode=0x0397, + specials={ "char", 0x0397, 0x0345 }, + unicodeslot=0x1FCC, + }, + [0x1FCD]={ + category="sk", + contextname="greekpsilivaria", + description="GREEK PSILI AND VARIA", + direction="on", + linebreak="al", + specials={ "char", 0x1FBF, 0x0300 }, + unicodeslot=0x1FCD, + }, + [0x1FCE]={ + category="sk", + contextname="greekpsilitonos", + description="GREEK PSILI AND OXIA", + direction="on", + linebreak="al", + specials={ "char", 0x1FBF, 0x0301 }, + unicodeslot=0x1FCE, + }, + [0x1FCF]={ + category="sk", + contextname="greekpsiliperispomeni", + description="GREEK PSILI AND PERISPOMENI", + direction="on", + linebreak="al", + specials={ "char", 0x1FBF, 0x0342 }, + unicodeslot=0x1FCF, + }, + [0x1FD0]={ + category="ll", + contextname="greekiotavrachy", + description="GREEK SMALL LETTER IOTA WITH VRACHY", + direction="l", + linebreak="al", + shcode=0x03B9, + specials={ "char", 0x03B9, 0x0306 }, + uccode=0x1FD8, + unicodeslot=0x1FD0, + }, + [0x1FD1]={ + category="ll", + contextname="greekiotamacron", + description="GREEK SMALL LETTER IOTA WITH MACRON", + direction="l", + linebreak="al", + shcode=0x03B9, + specials={ "char", 0x03B9, 0x0304 }, + uccode=0x1FD9, + unicodeslot=0x1FD1, + }, + [0x1FD2]={ + category="ll", + contextname="greekiotadialytikavaria", + description="GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA", + direction="l", + linebreak="al", + shcode=0x03B9, + specials={ "char", 0x03CA, 0x0300 }, + unicodeslot=0x1FD2, + }, + [0x1FD3]={ + category="ll", + contextname="greekiotadialytikatonos", + description="GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA", + direction="l", + linebreak="al", + shcode=0x03B9, + specials={ "char", 0x0390 }, + unicodeslot=0x1FD3, + }, + [0x1FD6]={ + category="ll", + contextname="greekiotaperispomeni", + description="GREEK SMALL LETTER IOTA WITH PERISPOMENI", + direction="l", + linebreak="al", + shcode=0x03B9, + specials={ "char", 0x03B9, 0x0342 }, + unicodeslot=0x1FD6, + }, + [0x1FD7]={ + category="ll", + contextname="greekiotadialytikaperispomeni", + description="GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI", + direction="l", + linebreak="al", + shcode=0x03B9, + specials={ "char", 0x03CA, 0x0342 }, + unicodeslot=0x1FD7, + }, + [0x1FD8]={ + category="lu", + contextname="greekIotavrachy", + description="GREEK CAPITAL LETTER IOTA WITH VRACHY", + direction="l", + lccode=0x1FD0, + linebreak="al", + shcode=0x0399, + specials={ "char", 0x0399, 0x0306 }, + unicodeslot=0x1FD8, + }, + [0x1FD9]={ + category="lu", + contextname="greekIotamacron", + description="GREEK CAPITAL LETTER IOTA WITH MACRON", + direction="l", + lccode=0x1FD1, + linebreak="al", + shcode=0x0399, + specials={ "char", 0x0399, 0x0304 }, + unicodeslot=0x1FD9, + }, + [0x1FDA]={ + category="lu", + contextname="greekIotavaria", + description="GREEK CAPITAL LETTER IOTA WITH VARIA", + direction="l", + lccode=0x1F76, + linebreak="al", + shcode=0x0399, + specials={ "char", 0x0399, 0x0300 }, + unicodeslot=0x1FDA, + }, + [0x1FDB]={ + category="lu", + contextname="greekIotatonos", + description="GREEK CAPITAL LETTER IOTA WITH OXIA", + direction="l", + lccode=0x1F77, + linebreak="al", + shcode=0x0399, + specials={ "char", 0x038A }, + unicodeslot=0x1FDB, + }, + [0x1FDD]={ + category="sk", + contextname="greekdasiavaria", + description="GREEK DASIA AND VARIA", + direction="on", + linebreak="al", + specials={ "char", 0x1FFE, 0x0300 }, + unicodeslot=0x1FDD, + }, + [0x1FDE]={ + category="sk", + contextname="greekdasiatonos", + description="GREEK DASIA AND OXIA", + direction="on", + linebreak="al", + specials={ "char", 0x1FFE, 0x0301 }, + unicodeslot=0x1FDE, + }, + [0x1FDF]={ + category="sk", + contextname="greekdasiaperispomeni", + description="GREEK DASIA AND PERISPOMENI", + direction="on", + linebreak="al", + specials={ "char", 0x1FFE, 0x0342 }, + unicodeslot=0x1FDF, + }, + [0x1FE0]={ + category="ll", + contextname="greekupsilonvrachy", + description="GREEK SMALL LETTER UPSILON WITH VRACHY", + direction="l", + linebreak="al", + shcode=0x03C5, + specials={ "char", 0x03C5, 0x0306 }, + uccode=0x1FE8, + unicodeslot=0x1FE0, + }, + [0x1FE1]={ + category="ll", + contextname="greekupsilonmacron", + description="GREEK SMALL LETTER UPSILON WITH MACRON", + direction="l", + linebreak="al", + shcode=0x03C5, + specials={ "char", 0x03C5, 0x0304 }, + uccode=0x1FE9, + unicodeslot=0x1FE1, + }, + [0x1FE2]={ + category="ll", + contextname="greekupsilondialytikavaria", + description="GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA", + direction="l", + linebreak="al", + shcode=0x03C5, + specials={ "char", 0x03CB, 0x0300 }, + unicodeslot=0x1FE2, + }, + [0x1FE3]={ + category="ll", + contextname="greekupsilondialytikatonos", + description="GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA", + direction="l", + linebreak="al", + shcode=0x03C5, + specials={ "char", 0x03B0 }, + unicodeslot=0x1FE3, + }, + [0x1FE4]={ + category="ll", + contextname="greekrhopsili", + description="GREEK SMALL LETTER RHO WITH PSILI", + direction="l", + linebreak="al", + shcode=0x03C1, + specials={ "char", 0x03C1, 0x0313 }, + unicodeslot=0x1FE4, + }, + [0x1FE5]={ + category="ll", + contextname="greekrhodasia", + description="GREEK SMALL LETTER RHO WITH DASIA", + direction="l", + linebreak="al", + shcode=0x03C1, + specials={ "char", 0x03C1, 0x0314 }, + uccode=0x1FEC, + unicodeslot=0x1FE5, + }, + [0x1FE6]={ + category="ll", + contextname="greekupsilonperispomeni", + description="GREEK SMALL LETTER UPSILON WITH PERISPOMENI", + direction="l", + linebreak="al", + shcode=0x03C5, + specials={ "char", 0x03C5, 0x0342 }, + unicodeslot=0x1FE6, + }, + [0x1FE7]={ + category="ll", + contextname="greekupsilondialytikaperispomeni", + description="GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI", + direction="l", + linebreak="al", + shcode=0x03C5, + specials={ "char", 0x03CB, 0x0342 }, + unicodeslot=0x1FE7, + }, + [0x1FE8]={ + category="lu", + contextname="greekUpsilonvrachy", + description="GREEK CAPITAL LETTER UPSILON WITH VRACHY", + direction="l", + lccode=0x1FE0, + linebreak="al", + shcode=0x03A5, + specials={ "char", 0x03A5, 0x0306 }, + unicodeslot=0x1FE8, + }, + [0x1FE9]={ + category="lu", + contextname="greekUpsilonmacron", + description="GREEK CAPITAL LETTER UPSILON WITH MACRON", + direction="l", + lccode=0x1FE1, + linebreak="al", + shcode=0x03A5, + specials={ "char", 0x03A5, 0x0304 }, + unicodeslot=0x1FE9, + }, + [0x1FEA]={ + category="lu", + contextname="greekUpsilonvaria", + description="GREEK CAPITAL LETTER UPSILON WITH VARIA", + direction="l", + lccode=0x1F7A, + linebreak="al", + shcode=0x03A5, + specials={ "char", 0x03A5, 0x0300 }, + unicodeslot=0x1FEA, + }, + [0x1FEB]={ + category="lu", + contextname="greekUpsilontonos", + description="GREEK CAPITAL LETTER UPSILON WITH OXIA", + direction="l", + lccode=0x1F7B, + linebreak="al", + shcode=0x03A5, + specials={ "char", 0x038E }, + unicodeslot=0x1FEB, + }, + [0x1FEC]={ + category="lu", + contextname="greekRhodasia", + description="GREEK CAPITAL LETTER RHO WITH DASIA", + direction="l", + lccode=0x1FE5, + linebreak="al", + shcode=0x03A1, + specials={ "char", 0x03A1, 0x0314 }, + unicodeslot=0x1FEC, + }, + [0x1FED]={ + category="sk", + contextname="greekdialytikavaria", + description="GREEK DIALYTIKA AND VARIA", + direction="on", + linebreak="al", + specials={ "char", 0x00A8, 0x0300 }, + unicodeslot=0x1FED, + }, + [0x1FEE]={ + category="sk", + contextname="greekdialytikatonos", + description="GREEK DIALYTIKA AND OXIA", + direction="on", + linebreak="al", + specials={ "char", 0x0385 }, + unicodeslot=0x1FEE, + }, + [0x1FEF]={ + category="sk", + contextname="greekvaria", + description="GREEK VARIA", + direction="on", + linebreak="al", + specials={ "char", 0x0060 }, + unicodeslot=0x1FEF, + }, + [0x1FF2]={ + category="ll", + contextname="greekomegaiotasubvaria", + description="GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x1F7C, 0x0345 }, + unicodeslot=0x1FF2, + }, + [0x1FF3]={ + category="ll", + contextname="greekomegaiotasub", + description="GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x03C9, 0x0345 }, + uccode=0x1FFC, + unicodeslot=0x1FF3, + }, + [0x1FF4]={ + category="ll", + contextname="greekomegaiotasubtonos", + description="GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x03CE, 0x0345 }, + unicodeslot=0x1FF4, + }, + [0x1FF6]={ + category="ll", + contextname="greekomegaperispomeni", + description="GREEK SMALL LETTER OMEGA WITH PERISPOMENI", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x03C9, 0x0342 }, + unicodeslot=0x1FF6, + }, + [0x1FF7]={ + category="ll", + contextname="greekomegaiotasubperispomeni", + description="GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI", + direction="l", + linebreak="al", + shcode=0x03C9, + specials={ "char", 0x1FF6, 0x0345 }, + unicodeslot=0x1FF7, + }, + [0x1FF8]={ + category="lu", + contextname="greekOmicronvaria", + description="GREEK CAPITAL LETTER OMICRON WITH VARIA", + direction="l", + lccode=0x1F78, + linebreak="al", + shcode=0x039F, + specials={ "char", 0x039F, 0x0300 }, + unicodeslot=0x1FF8, + }, + [0x1FF9]={ + category="lu", + contextname="greekOmicrontonos", + description="GREEK CAPITAL LETTER OMICRON WITH OXIA", + direction="l", + lccode=0x1F79, + linebreak="al", + shcode=0x039F, + specials={ "char", 0x038C }, + unicodeslot=0x1FF9, + }, + [0x1FFA]={ + category="lu", + contextname="greekOmegavaria", + description="GREEK CAPITAL LETTER OMEGA WITH VARIA", + direction="l", + lccode=0x1F7C, + linebreak="al", + shcode=0x03A9, + specials={ "char", 0x03A9, 0x0300 }, + unicodeslot=0x1FFA, + }, + [0x1FFB]={ + category="lu", + contextname="greekOmegatonos", + description="GREEK CAPITAL LETTER OMEGA WITH OXIA", + direction="l", + lccode=0x1F7D, + linebreak="al", + shcode=0x03A9, + specials={ "char", 0x038F }, + unicodeslot=0x1FFB, + }, + [0x1FFC]={ + category="lt", + contextname="greekOmegaiotasub", + description="GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI", + direction="l", + lccode=0x1FF3, + linebreak="al", + shcode=0x03A9, + specials={ "char", 0x03A9, 0x0345 }, + unicodeslot=0x1FFC, + }, + [0x1FFD]={ + category="sk", + contextname="greekoxia", + description="GREEK OXIA", + direction="on", + linebreak="al", + specials={ "char", 0x00B4 }, + unicodeslot=0x1FFD, + }, + [0x1FFE]={ + category="sk", + contextname="greekdasia", + description="GREEK DASIA", + direction="on", + linebreak="al", + specials={ "compat", 0x0020, 0x0314 }, + unicodeslot=0x1FFE, + }, + [0x2000]={ + category="zs", + description="EN QUAD", + direction="ws", + linebreak="ba", + specials={ "char", 0x2002 }, + unicodeslot=0x2000, + }, + [0x2001]={ + category="zs", + description="EM QUAD", + direction="ws", + linebreak="ba", + specials={ "char", 0x2003 }, + unicodeslot=0x2001, + }, + [0x2002]={ + category="zs", + contextname="enspace", + description="EN SPACE", + direction="ws", + linebreak="ba", + specials={ "compat", 0x0020 }, + unicodeslot=0x2002, + }, + [0x2003]={ + category="zs", + contextname="emspace", + description="EM SPACE", + direction="ws", + linebreak="ba", + specials={ "compat", 0x0020 }, + unicodeslot=0x2003, + }, + [0x2004]={ + category="zs", + contextname="threeperemspace", + description="THREE-PER-EM SPACE", + direction="ws", + linebreak="ba", + specials={ "compat", 0x0020 }, + unicodeslot=0x2004, + }, + [0x2005]={ + category="zs", + contextname="fourperemspace", + description="FOUR-PER-EM SPACE", + direction="ws", + linebreak="ba", + specials={ "compat", 0x0020 }, + unicodeslot=0x2005, + }, + [0x2006]={ + category="zs", + contextname="sixperemspace", + description="SIX-PER-EM SPACE", + direction="ws", + linebreak="ba", + specials={ "compat", 0x0020 }, + unicodeslot=0x2006, + }, + [0x2007]={ + category="zs", + contextname="figurespace", + description="FIGURE SPACE", + direction="ws", + linebreak="gl", + specials={ "nobreak", 0x0020 }, + unicodeslot=0x2007, + }, + [0x2008]={ + category="zs", + contextname="punctuationspace", + description="PUNCTUATION SPACE", + direction="ws", + linebreak="ba", + specials={ "compat", 0x0020 }, + unicodeslot=0x2008, + }, + [0x2009]={ + category="zs", + contextname="breakablethinspace", + description="THIN SPACE", + direction="ws", + linebreak="ba", + specials={ "compat", 0x0020 }, + unicodeslot=0x2009, + }, + [0x200A]={ + category="zs", + contextname="figurespace", + description="HAIR SPACE", + direction="ws", + linebreak="ba", + specials={ "compat", 0x0020 }, + unicodeslot=0x200A, + }, + [0x200B]={ + category="cf", + contextname="zerowidthspace", + description="ZERO WIDTH SPACE", + direction="bn", + linebreak="zw", + unicodeslot=0x200B, + }, + [0x200C]={ + adobename="afii61664", + category="cf", + contextname="zwnj", + description="ZERO WIDTH NON-JOINER", + direction="bn", + linebreak="cm", + unicodeslot=0x200C, + }, + [0x200D]={ + adobename="afii301", + category="cf", + contextname="zwj", + description="ZERO WIDTH JOINER", + direction="bn", + linebreak="cm", + unicodeslot=0x200D, + }, + [0x200E]={ + adobename="afii299", + category="cf", + description="LEFT-TO-RIGHT MARK", + direction="l", + linebreak="cm", + unicodeslot=0x200E, + }, + [0x200F]={ + adobename="afii300", + category="cf", + description="RIGHT-TO-LEFT MARK", + direction="r", + linebreak="cm", + unicodeslot=0x200F, + }, + [0x2010]={ + category="pd", + cjkwd="a", + description="HYPHEN", + direction="on", + linebreak="ba", + unicodeslot=0x2010, + }, + [0x2011]={ + category="pd", + description="NON-BREAKING HYPHEN", + direction="on", + linebreak="gl", + specials={ "nobreak", 0x2010 }, + unicodeslot=0x2011, + }, + [0x2012]={ + adobename="figuredash", + category="pd", + contextname="textminus", + description="FIGURE DASH", + direction="on", + linebreak="ba", + unicodeslot=0x2012, + }, + [0x2013]={ + adobename="endash", + category="pd", + cjkwd="a", + contextname="endash", + description="EN DASH", + direction="on", + linebreak="ba", + unicodeslot=0x2013, + }, + [0x2014]={ + adobename="emdash", + category="pd", + cjkwd="a", + contextname="emdash", + description="EM DASH", + direction="on", + linebreak="b2", + unicodeslot=0x2014, + }, + [0x2015]={ + adobename="afii208", + category="pd", + cjkwd="a", + contextname="texthorizontalbar", + description="HORIZONTAL BAR", + direction="on", + linebreak="ai", + unicodeslot=0x2015, + }, + [0x2016]={ + category="po", + cjkwd="a", + description="DOUBLE VERTICAL LINE", + direction="on", + linebreak="ai", + unicodeslot=0x2016, + }, + [0x2017]={ + adobename="underscoredbl", + category="po", + description="DOUBLE LOW LINE", + direction="on", + linebreak="al", + specials={ "compat", 0x0020, 0x0333 }, + unicodeslot=0x2017, + }, + [0x2018]={ + adobename="quoteleft", + category="pi", + cjkwd="a", + contextname="quoteleft", + description="LEFT SINGLE QUOTATION MARK", + direction="on", + linebreak="qu", + unicodeslot=0x2018, + }, + [0x2019]={ + adobename="quoteright", + category="pf", + cjkwd="a", + contextname="quoteright", + description="RIGHT SINGLE QUOTATION MARK", + direction="on", + linebreak="qu", + unicodeslot=0x2019, + }, + [0x201A]={ + adobename="quotesinglbase", + category="ps", + contextname="quotesinglebase", + description="SINGLE LOW-0x0009 QUOTATION MARK", + direction="on", + linebreak="op", + unicodeslot=0x201A, + }, + [0x201B]={ + adobename="quotereversed", + category="pi", + description="SINGLE HIGH-REVERSED-0x0009 QUOTATION MARK", + direction="on", + linebreak="qu", + unicodeslot=0x201B, + }, + [0x201C]={ + adobename="quotedblleft", + category="pi", + cjkwd="a", + contextname="quotedblleft", + description="LEFT DOUBLE QUOTATION MARK", + direction="on", + linebreak="qu", + unicodeslot=0x201C, + }, + [0x201D]={ + adobename="quotedblright", + category="pf", + cjkwd="a", + contextname="quotedblright", + description="RIGHT DOUBLE QUOTATION MARK", + direction="on", + linebreak="qu", + unicodeslot=0x201D, + }, + [0x201E]={ + adobename="quotedblbase", + category="ps", + contextname="quotedblbase", + description="DOUBLE LOW-0x0009 QUOTATION MARK", + direction="on", + linebreak="op", + unicodeslot=0x201E, + }, + [0x201F]={ + category="pi", + description="DOUBLE HIGH-REVERSED-0x0009 QUOTATION MARK", + direction="on", + linebreak="qu", + unicodeslot=0x201F, + }, + [0x2020]={ + adobename="dagger", + category="po", + cjkwd="a", + contextname="textdag", + description="DAGGER", + direction="on", + linebreak="ai", + mathspec={ + { class="binary", name="dagger" }, + { class="box", name="dag" }, + }, + unicodeslot=0x2020, + }, + [0x2021]={ + adobename="daggerdbl", + category="po", + cjkwd="a", + contextname="textddag", + description="DOUBLE DAGGER", + direction="on", + linebreak="ai", + mathspec={ + { class="binary", name="ddagger" }, + { class="box", name="ddag" }, + }, + unicodeslot=0x2021, + }, + [0x2022]={ + adobename="bullet", + category="po", + cjkwd="a", + contextname="textbullet", + description="BULLET", + direction="on", + linebreak="al", + mathclass="binary", + mathname="bullet", + unicodeslot=0x2022, + }, + [0x2023]={ + category="po", + description="TRIANGULAR BULLET", + direction="on", + linebreak="al", + unicodeslot=0x2023, + }, + [0x2024]={ + adobename="onedotenleader", + category="po", + cjkwd="a", + description="ONE DOT LEADER", + direction="on", + linebreak="in", + specials={ "compat", 0x002E }, + unicodeslot=0x2024, + }, + [0x2025]={ + adobename="twodotenleader", + category="po", + cjkwd="a", + description="TWO DOT LEADER", + direction="on", + linebreak="in", + specials={ "compat", 0x002E, 0x002E }, + unicodeslot=0x2025, + }, + [0x2026]={ + adobename="ellipsis", + category="po", + cjkwd="a", + contextname="textellipsis", + description="HORIZONTAL ELLIPSIS", + direction="on", + linebreak="in", + mathclass="inner", + mathname="ldots", + specials={ "compat", 0x002E, 0x002E, 0x002E }, + unicodeslot=0x2026, + }, + [0x2027]={ + category="po", + cjkwd="a", + description="HYPHENATION POINT", + direction="on", + linebreak="ba", + unicodeslot=0x2027, + }, + [0x2028]={ + category="zl", + description="LINE SEPARATOR", + direction="ws", + linebreak="bk", + unicodeslot=0x2028, + }, + [0x2029]={ + category="zp", + description="PARAGRAPH SEPARATOR", + direction="b", + linebreak="bk", + unicodeslot=0x2029, + }, + [0x202A]={ + category="cf", + description="LEFT-TO-RIGHT EMBEDDING", + direction="lre", + linebreak="cm", + unicodeslot=0x202A, + }, + [0x202B]={ + category="cf", + description="RIGHT-TO-LEFT EMBEDDING", + direction="rle", + linebreak="cm", + unicodeslot=0x202B, + }, + [0x202C]={ + adobename="afii61573", + category="cf", + description="POP DIRECTIONAL FORMATTING", + direction="pdf", + linebreak="cm", + unicodeslot=0x202C, + }, + [0x202D]={ + adobename="afii61574", + category="cf", + description="LEFT-TO-RIGHT OVERRIDE", + direction="lro", + linebreak="cm", + unicodeslot=0x202D, + }, + [0x202E]={ + adobename="afii61575", + category="cf", + description="RIGHT-TO-LEFT OVERRIDE", + direction="rlo", + linebreak="cm", + unicodeslot=0x202E, + }, + [0x202F]={ + category="zs", + contextname="narrownobreakspace", + description="NARROW NO-BREAK SPACE", + direction="cs", + linebreak="gl", + specials={ "nobreak", 0x0020 }, + unicodeslot=0x202F, + }, + [0x2030]={ + adobename="perthousand", + category="po", + cjkwd="a", + contextname="perthousand", + description="PER MILLE SIGN", + direction="et", + linebreak="po", + unicodeslot=0x2030, + }, + [0x2031]={ + category="po", + description="PER TEN THOUSAND SIGN", + direction="et", + linebreak="po", + unicodeslot=0x2031, + }, + [0x2032]={ + adobename="minute", + category="po", + cjkwd="a", + description="PRIME", + direction="et", + linebreak="po", + mathclass="nothing", + mathname="prime", + unicodeslot=0x2032, + }, + [0x2033]={ + adobename="second", + category="po", + cjkwd="a", + description="DOUBLE PRIME", + direction="et", + linebreak="po", + specials={ "compat", 0x2032, 0x2032 }, + unicodeslot=0x2033, + }, + [0x2034]={ + category="po", + description="TRIPLE PRIME", + direction="et", + linebreak="po", + specials={ "compat", 0x2032, 0x2032, 0x2032 }, + unicodeslot=0x2034, + }, + [0x2035]={ + category="po", + cjkwd="a", + description="REVERSED PRIME", + direction="on", + linebreak="po", + unicodeslot=0x2035, + }, + [0x2036]={ + category="po", + description="REVERSED DOUBLE PRIME", + direction="on", + linebreak="po", + specials={ "compat", 0x2035, 0x2035 }, + unicodeslot=0x2036, + }, + [0x2037]={ + category="po", + description="REVERSED TRIPLE PRIME", + direction="on", + linebreak="po", + specials={ "compat", 0x2035, 0x2035, 0x2035 }, + unicodeslot=0x2037, + }, + [0x2038]={ + category="po", + description="CARET", + direction="on", + linebreak="al", + unicodeslot=0x2038, + }, + [0x2039]={ + adobename="guilsinglleft", + category="pi", + contextname="guilsingleleft", + description="SINGLE LEFT-POINTING ANGLE QUOTATION MARK", + direction="on", + linebreak="qu", + mirror=0x203A, + unicodeslot=0x2039, + }, + [0x203A]={ + adobename="guilsinglright", + category="pf", + contextname="guilsingleright", + description="SINGLE RIGHT-POINTING ANGLE QUOTATION MARK", + direction="on", + linebreak="qu", + mirror=0x2039, + unicodeslot=0x203A, + }, + [0x203B]={ + category="po", + cjkwd="a", + description="REFERENCE MARK", + direction="on", + linebreak="ai", + unicodeslot=0x203B, + }, + [0x203C]={ + adobename="exclamdbl", + category="po", + description="DOUBLE EXCLAMATION MARK", + direction="on", + linebreak="ns", + specials={ "compat", 0x0021, 0x0021 }, + unicodeslot=0x203C, + }, + [0x203D]={ + category="po", + description="INTERROBANG", + direction="on", + linebreak="ns", + unicodeslot=0x203D, + }, + [0x203E]={ + category="po", + cjkwd="a", + description="OVERLINE", + direction="on", + linebreak="al", + specials={ "compat", 0x0020, 0x0305 }, + unicodeslot=0x203E, + }, + [0x203F]={ + category="pc", + description="UNDERTIE", + direction="on", + linebreak="al", + unicodeslot=0x203F, + }, + [0x2040]={ + category="pc", + description="CHARACTER TIE", + direction="on", + linebreak="al", + unicodeslot=0x2040, + }, + [0x2041]={ + category="po", + description="CARET INSERTION POINT", + direction="on", + linebreak="al", + unicodeslot=0x2041, + }, + [0x2042]={ + category="po", + description="ASTERISM", + direction="on", + linebreak="al", + unicodeslot=0x2042, + }, + [0x2043]={ + category="po", + description="HYPHEN BULLET", + direction="on", + linebreak="al", + unicodeslot=0x2043, + }, + [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]={ + category="ps", + description="LEFT SQUARE BRACKET WITH QUILL", + direction="on", + linebreak="op", + mirror=0x2046, + unicodeslot=0x2045, + }, + [0x2046]={ + category="pe", + description="RIGHT SQUARE BRACKET WITH QUILL", + direction="on", + linebreak="cl", + mirror=0x2045, + unicodeslot=0x2046, + }, + [0x2047]={ + category="po", + description="DOUBLE QUESTION MARK", + direction="on", + linebreak="ns", + specials={ "compat", 0x003F, 0x003F }, + unicodeslot=0x2047, + }, + [0x2048]={ + category="po", + description="QUESTION EXCLAMATION MARK", + direction="on", + linebreak="ns", + specials={ "compat", 0x003F, 0x0021 }, + unicodeslot=0x2048, + }, + [0x2049]={ + category="po", + description="EXCLAMATION QUESTION MARK", + direction="on", + linebreak="ns", + specials={ "compat", 0x0021, 0x003F }, + unicodeslot=0x2049, + }, + [0x204A]={ + category="po", + description="TIRONIAN SIGN ET", + direction="on", + linebreak="al", + unicodeslot=0x204A, + }, + [0x204B]={ + category="po", + description="REVERSED PILCROW SIGN", + direction="on", + linebreak="al", + unicodeslot=0x204B, + }, + [0x204C]={ + category="po", + description="BLACK LEFTWARDS BULLET", + direction="on", + linebreak="al", + unicodeslot=0x204C, + }, + [0x204D]={ + category="po", + description="BLACK RIGHTWARDS BULLET", + direction="on", + linebreak="al", + unicodeslot=0x204D, + }, + [0x204E]={ + category="po", + description="LOW ASTERISK", + direction="on", + linebreak="al", + unicodeslot=0x204E, + }, + [0x204F]={ + category="po", + description="REVERSED SEMICOLON", + direction="on", + linebreak="al", + unicodeslot=0x204F, + }, + [0x2050]={ + category="po", + description="CLOSE UP", + direction="on", + linebreak="al", + unicodeslot=0x2050, + }, + [0x2051]={ + category="po", + description="TWO ASTERISKS ALIGNED VERTICALLY", + direction="on", + linebreak="al", + unicodeslot=0x2051, + }, + [0x2052]={ + category="sm", + description="COMMERCIAL MINUS SIGN", + direction="on", + linebreak="al", + unicodeslot=0x2052, + }, + [0x2053]={ + category="po", + description="SWUNG DASH", + direction="on", + linebreak="al", + unicodeslot=0x2053, + }, + [0x2054]={ + category="pc", + description="INVERTED UNDERTIE", + direction="on", + linebreak="al", + unicodeslot=0x2054, + }, + [0x2055]={ + category="po", + description="FLOWER PUNCTUATION MARK", + direction="on", + linebreak="al", + unicodeslot=0x2055, + }, + [0x2056]={ + category="po", + description="THREE DOT PUNCTUATION", + direction="on", + linebreak="ba", + unicodeslot=0x2056, + }, + [0x2057]={ + category="po", + description="QUADRUPLE PRIME", + direction="on", + linebreak="al", + specials={ "compat", 0x2032, 0x2032, 0x2032, 0x2032 }, + unicodeslot=0x2057, + }, + [0x2058]={ + category="po", + description="FOUR DOT PUNCTUATION", + direction="on", + linebreak="ba", + unicodeslot=0x2058, + }, + [0x2059]={ + category="po", + description="FIVE DOT PUNCTUATION", + direction="on", + linebreak="ba", + unicodeslot=0x2059, + }, + [0x205A]={ + category="po", + description="TWO DOT PUNCTUATION", + direction="on", + linebreak="ba", + unicodeslot=0x205A, + }, + [0x205B]={ + category="po", + description="FOUR DOT MARK", + direction="on", + linebreak="ba", + unicodeslot=0x205B, + }, + [0x205C]={ + category="po", + description="DOTTED CROSS", + direction="on", + linebreak="al", + unicodeslot=0x205C, + }, + [0x205D]={ + category="po", + description="TRICOLON", + direction="on", + linebreak="ba", + unicodeslot=0x205D, + }, + [0x205E]={ + category="po", + description="VERTICAL FOUR DOTS", + direction="on", + linebreak="ba", + unicodeslot=0x205E, + }, + [0x205F]={ + category="zs", + contextname="medspace", + description="MEDIUM MATHEMATICAL SPACE", + direction="ws", + linebreak="ba", + specials={ "compat", 0x0020 }, + unicodeslot=0x205F, + }, + [0x2060]={ + category="cf", + description="WORD JOINER", + direction="bn", + linebreak="wj", + unicodeslot=0x2060, + }, + [0x2061]={ + category="cf", + comment="maybe: nulloperator", + contextname="relax", + description="FUNCTION APPLICATION", + direction="bn", + linebreak="al", + unicodeslot=0x2061, + }, + [0x2062]={ + category="cf", + description="INVISIBLE TIMES", + direction="bn", + linebreak="al", + unicodeslot=0x2062, + }, + [0x2063]={ + category="cf", + description="INVISIBLE SEPARATOR", + direction="bn", + linebreak="al", + unicodeslot=0x2063, + }, + [0x206A]={ + category="cf", + description="INHIBIT SYMMETRIC SWAPPING", + direction="bn", + linebreak="cm", + unicodeslot=0x206A, + }, + [0x206B]={ + category="cf", + description="ACTIVATE SYMMETRIC SWAPPING", + direction="bn", + linebreak="cm", + unicodeslot=0x206B, + }, + [0x206C]={ + category="cf", + description="INHIBIT ARABIC FORM SHAPING", + direction="bn", + linebreak="cm", + unicodeslot=0x206C, + }, + [0x206D]={ + category="cf", + description="ACTIVATE ARABIC FORM SHAPING", + direction="bn", + linebreak="cm", + unicodeslot=0x206D, + }, + [0x206E]={ + category="cf", + description="NATIONAL DIGIT SHAPES", + direction="bn", + linebreak="cm", + unicodeslot=0x206E, + }, + [0x206F]={ + category="cf", + description="NOMINAL DIGIT SHAPES", + direction="bn", + linebreak="cm", + unicodeslot=0x206F, + }, + [0x2070]={ + category="no", + description="SUPERSCRIPT ZERO", + direction="en", + linebreak="al", + specials={ "super", 0x0030 }, + unicodeslot=0x2070, + }, + [0x2071]={ + category="ll", + description="SUPERSCRIPT LATIN SMALL LETTER I", + direction="l", + linebreak="al", + specials={ "super", 0x0069 }, + unicodeslot=0x2071, + }, + [0x2074]={ + category="no", + cjkwd="a", + description="SUPERSCRIPT FOUR", + direction="en", + linebreak="ai", + specials={ "super", 0x0034 }, + unicodeslot=0x2074, + }, + [0x2075]={ + category="no", + description="SUPERSCRIPT FIVE", + direction="en", + linebreak="al", + specials={ "super", 0x0035 }, + unicodeslot=0x2075, + }, + [0x2076]={ + category="no", + description="SUPERSCRIPT SIX", + direction="en", + linebreak="al", + specials={ "super", 0x0036 }, + unicodeslot=0x2076, + }, + [0x2077]={ + category="no", + description="SUPERSCRIPT SEVEN", + direction="en", + linebreak="al", + specials={ "super", 0x0037 }, + unicodeslot=0x2077, + }, + [0x2078]={ + category="no", + description="SUPERSCRIPT EIGHT", + direction="en", + linebreak="al", + specials={ "super", 0x0038 }, + unicodeslot=0x2078, + }, + [0x2079]={ + category="no", + description="SUPERSCRIPT NINE", + direction="en", + linebreak="al", + specials={ "super", 0x0039 }, + unicodeslot=0x2079, + }, + [0x207A]={ + category="sm", + description="SUPERSCRIPT PLUS SIGN", + direction="es", + linebreak="al", + specials={ "super", 0x002B }, + unicodeslot=0x207A, + }, + [0x207B]={ + category="sm", + description="SUPERSCRIPT MINUS", + direction="es", + linebreak="al", + specials={ "super", 0x2212 }, + unicodeslot=0x207B, + }, + [0x207C]={ + category="sm", + description="SUPERSCRIPT EQUALS SIGN", + direction="on", + linebreak="al", + specials={ "super", 0x003D }, + unicodeslot=0x207C, + }, + [0x207D]={ + category="ps", + description="SUPERSCRIPT LEFT PARENTHESIS", + direction="on", + linebreak="op", + mirror=0x207E, + specials={ "super", 0x0028 }, + unicodeslot=0x207D, + }, + [0x207E]={ + category="pe", + description="SUPERSCRIPT RIGHT PARENTHESIS", + direction="on", + linebreak="cl", + mirror=0x207D, + specials={ "super", 0x0029 }, + unicodeslot=0x207E, + }, + [0x207F]={ + category="ll", + cjkwd="a", + description="SUPERSCRIPT LATIN SMALL LETTER N", + direction="l", + linebreak="ai", + specials={ "super", 0x006E }, + unicodeslot=0x207F, + }, + [0x2080]={ + category="no", + description="SUBSCRIPT ZERO", + direction="en", + linebreak="al", + specials={ "sub", 0x0030 }, + unicodeslot=0x2080, + }, + [0x2081]={ + category="no", + cjkwd="a", + description="SUBSCRIPT ONE", + direction="en", + linebreak="ai", + specials={ "sub", 0x0031 }, + unicodeslot=0x2081, + }, + [0x2082]={ + category="no", + cjkwd="a", + description="SUBSCRIPT TWO", + direction="en", + linebreak="ai", + specials={ "sub", 0x0032 }, + unicodeslot=0x2082, + }, + [0x2083]={ + category="no", + cjkwd="a", + description="SUBSCRIPT THREE", + direction="en", + linebreak="ai", + specials={ "sub", 0x0033 }, + unicodeslot=0x2083, + }, + [0x2084]={ + category="no", + cjkwd="a", + description="SUBSCRIPT FOUR", + direction="en", + linebreak="ai", + specials={ "sub", 0x0034 }, + unicodeslot=0x2084, + }, + [0x2085]={ + category="no", + description="SUBSCRIPT FIVE", + direction="en", + linebreak="al", + specials={ "sub", 0x0035 }, + unicodeslot=0x2085, + }, + [0x2086]={ + category="no", + description="SUBSCRIPT SIX", + direction="en", + linebreak="al", + specials={ "sub", 0x0036 }, + unicodeslot=0x2086, + }, + [0x2087]={ + category="no", + description="SUBSCRIPT SEVEN", + direction="en", + linebreak="al", + specials={ "sub", 0x0037 }, + unicodeslot=0x2087, + }, + [0x2088]={ + category="no", + description="SUBSCRIPT EIGHT", + direction="en", + linebreak="al", + specials={ "sub", 0x0038 }, + unicodeslot=0x2088, + }, + [0x2089]={ + category="no", + description="SUBSCRIPT NINE", + direction="en", + linebreak="al", + specials={ "sub", 0x0039 }, + unicodeslot=0x2089, + }, + [0x208A]={ + category="sm", + description="SUBSCRIPT PLUS SIGN", + direction="es", + linebreak="al", + specials={ "sub", 0x002B }, + unicodeslot=0x208A, + }, + [0x208B]={ + category="sm", + description="SUBSCRIPT MINUS", + direction="es", + linebreak="al", + specials={ "sub", 0x2212 }, + unicodeslot=0x208B, + }, + [0x208C]={ + category="sm", + description="SUBSCRIPT EQUALS SIGN", + direction="on", + linebreak="al", + specials={ "sub", 0x003D }, + unicodeslot=0x208C, + }, + [0x208D]={ + category="ps", + description="SUBSCRIPT LEFT PARENTHESIS", + direction="on", + linebreak="op", + mirror=0x208E, + specials={ "sub", 0x0028 }, + unicodeslot=0x208D, + }, + [0x208E]={ + category="pe", + description="SUBSCRIPT RIGHT PARENTHESIS", + direction="on", + linebreak="cl", + mirror=0x208D, + specials={ "sub", 0x0029 }, + unicodeslot=0x208E, + }, + [0x2090]={ + category="lm", + description="LATIN SUBSCRIPT SMALL LETTER A", + direction="l", + linebreak="al", + specials={ "sub", 0x0061 }, + unicodeslot=0x2090, + }, + [0x2091]={ + category="lm", + description="LATIN SUBSCRIPT SMALL LETTER E", + direction="l", + linebreak="al", + specials={ "sub", 0x0065 }, + unicodeslot=0x2091, + }, + [0x2092]={ + category="lm", + description="LATIN SUBSCRIPT SMALL LETTER O", + direction="l", + linebreak="al", + specials={ "sub", 0x006F }, + unicodeslot=0x2092, + }, + [0x2093]={ + category="lm", + description="LATIN SUBSCRIPT SMALL LETTER X", + direction="l", + linebreak="al", + specials={ "sub", 0x0078 }, + unicodeslot=0x2093, + }, + [0x2094]={ + category="lm", + description="LATIN SUBSCRIPT SMALL LETTER SCHWA", + direction="l", + linebreak="al", + specials={ "sub", 0x0259 }, + unicodeslot=0x2094, + }, + [0x20A0]={ + category="sc", + description="EURO-CURRENCY SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x20A0, + }, + [0x20A1]={ + adobename="colonmonetary", + category="sc", + description="COLON SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x20A1, + }, + [0x20A2]={ + category="sc", + description="CRUZEIRO SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x20A2, + }, + [0x20A3]={ + adobename="franc", + category="sc", + description="FRENCH FRANC SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x20A3, + }, + [0x20A4]={ + adobename="lira", + category="sc", + description="LIRA SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x20A4, + }, + [0x20A5]={ + category="sc", + description="MILL SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x20A5, + }, + [0x20A6]={ + category="sc", + description="NAIRA SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x20A6, + }, + [0x20A7]={ + adobename="peseta", + category="sc", + description="PESETA SIGN", + direction="et", + linebreak="po", + unicodeslot=0x20A7, + }, + [0x20A8]={ + category="sc", + description="RUPEE SIGN", + direction="et", + linebreak="pr", + specials={ "compat", 0x0052, 0x0073 }, + unicodeslot=0x20A8, + }, + [0x20A9]={ + category="sc", + cjkwd="h", + description="WON SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x20A9, + }, + [0x20AA]={ + adobename="afii57636", + category="sc", + description="NEW SHEQEL SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x20AA, + }, + [0x20AB]={ + adobename="dong", + category="sc", + contextname="textdong", + description="DONG SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x20AB, + }, + [0x20AC]={ + adobename="Euro", + category="sc", + cjkwd="a", + contextname="texteuro", + description="EURO SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x20AC, + }, + [0x20AD]={ + category="sc", + description="KIP SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x20AD, + }, + [0x20AE]={ + category="sc", + description="TUGRIK SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x20AE, + }, + [0x20AF]={ + category="sc", + description="DRACHMA SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x20AF, + }, + [0x20B0]={ + category="sc", + description="GERMAN PENNY SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x20B0, + }, + [0x20B1]={ + category="sc", + description="PESO SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x20B1, + }, + [0x20B2]={ + category="sc", + description="GUARANI SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x20B2, + }, + [0x20B3]={ + category="sc", + description="AUSTRAL SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x20B3, + }, + [0x20B4]={ + category="sc", + description="HRYVNIA SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x20B4, + }, + [0x20B5]={ + category="sc", + description="CEDI SIGN", + direction="et", + linebreak="pr", + unicodeslot=0x20B5, + }, + [0x20D0]={ + category="mn", + description="COMBINING LEFT HARPOON ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x20D0, + }, + [0x20D1]={ + category="mn", + description="COMBINING RIGHT HARPOON ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x20D1, + }, + [0x20D2]={ + category="mn", + description="COMBINING LONG VERTICAL LINE OVERLAY", + direction="nsm", + linebreak="cm", + unicodeslot=0x20D2, + }, + [0x20D3]={ + category="mn", + description="COMBINING SHORT VERTICAL LINE OVERLAY", + direction="nsm", + linebreak="cm", + unicodeslot=0x20D3, + }, + [0x20D4]={ + category="mn", + description="COMBINING ANTICLOCKWISE ARROW ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x20D4, + }, + [0x20D5]={ + category="mn", + description="COMBINING CLOCKWISE ARROW ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x20D5, + }, + [0x20D6]={ + category="mn", + description="COMBINING LEFT ARROW ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x20D6, + }, + [0x20D7]={ + category="mn", + description="COMBINING RIGHT ARROW ABOVE", + direction="nsm", + linebreak="cm", + mathclass="accent", + mathname="vec", + unicodeslot=0x20D7, + }, + [0x20D8]={ + category="mn", + description="COMBINING RING OVERLAY", + direction="nsm", + linebreak="cm", + unicodeslot=0x20D8, + }, + [0x20D9]={ + category="mn", + description="COMBINING CLOCKWISE RING OVERLAY", + direction="nsm", + linebreak="cm", + unicodeslot=0x20D9, + }, + [0x20DA]={ + category="mn", + description="COMBINING ANTICLOCKWISE RING OVERLAY", + direction="nsm", + linebreak="cm", + unicodeslot=0x20DA, + }, + [0x20DB]={ + category="mn", + description="COMBINING THREE DOTS ABOVE", + direction="nsm", + linebreak="cm", + mathclass="accent", + mathname="dddot", + unicodeslot=0x20DB, + }, + [0x20DC]={ + category="mn", + description="COMBINING FOUR DOTS ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x20DC, + }, + [0x20DD]={ + category="me", + description="COMBINING ENCLOSING CIRCLE", + direction="nsm", + linebreak="cm", + mathspec={ + { class="default",name="bigcircle" }, + { class="binary",name="bigcircle" }, + }, + unicodeslot=0x20DD, + }, + [0x20DE]={ + category="me", + description="COMBINING ENCLOSING SQUARE", + direction="nsm", + linebreak="cm", + mathclass="default", + mathname="bigsquare", + unicodeslot=0x20DE, + }, + [0x20DF]={ + category="me", + description="COMBINING ENCLOSING DIAMOND", + direction="nsm", + linebreak="cm", + mathclass="default", + mathname="bigdiamond", + unicodeslot=0x20DF, + }, + [0x20E0]={ + category="me", + description="COMBINING ENCLOSING CIRCLE BACKSLASH", + direction="nsm", + linebreak="cm", + unicodeslot=0x20E0, + }, + [0x20E1]={ + category="mn", + description="COMBINING LEFT RIGHT ARROW ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x20E1, + }, + [0x20E2]={ + category="me", + description="COMBINING ENCLOSING SCREEN", + direction="nsm", + linebreak="cm", + unicodeslot=0x20E2, + }, + [0x20E3]={ + category="me", + description="COMBINING ENCLOSING KEYCAP", + direction="nsm", + linebreak="cm", + unicodeslot=0x20E3, + }, + [0x20E4]={ + category="me", + description="COMBINING ENCLOSING UPWARD POINTING TRIANGLE", + direction="nsm", + linebreak="cm", + unicodeslot=0x20E4, + }, + [0x20E5]={ + category="mn", + description="COMBINING REVERSE SOLIDUS OVERLAY", + direction="nsm", + linebreak="cm", + unicodeslot=0x20E5, + }, + [0x20E6]={ + category="mn", + description="COMBINING DOUBLE VERTICAL STROKE OVERLAY", + direction="nsm", + linebreak="cm", + unicodeslot=0x20E6, + }, + [0x20E7]={ + category="mn", + description="COMBINING ANNUITY SYMBOL", + direction="nsm", + linebreak="cm", + unicodeslot=0x20E7, + }, + [0x20E8]={ + category="mn", + description="COMBINING TRIPLE UNDERDOT", + direction="nsm", + linebreak="cm", + unicodeslot=0x20E8, + }, + [0x20E9]={ + category="mn", + description="COMBINING WIDE BRIDGE ABOVE", + direction="nsm", + linebreak="cm", + mathclass="accent", + unicodeslot=0x20E9, + }, + [0x20EA]={ + category="mn", + description="COMBINING LEFTWARDS ARROW OVERLAY", + direction="nsm", + linebreak="cm", + unicodeslot=0x20EA, + }, + [0x20EB]={ + category="mn", + description="COMBINING LONG DOUBLE SOLIDUS OVERLAY", + direction="nsm", + linebreak="cm", + unicodeslot=0x20EB, + }, + [0x20EC]={ + category="mn", + description="COMBINING RIGHTWARDS HARPOON WITH BARB DOWNWARDS", + direction="nsm", + linebreak="cm", + unicodeslot=0x20EC, + }, + [0x20ED]={ + category="mn", + description="COMBINING LEFTWARDS HARPOON WITH BARB DOWNWARDS", + direction="nsm", + linebreak="cm", + unicodeslot=0x20ED, + }, + [0x20EE]={ + category="mn", + description="COMBINING LEFT ARROW BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x20EE, + }, + [0x20EF]={ + category="mn", + description="COMBINING RIGHT ARROW BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x20EF, + }, + [0x2100]={ + category="so", + description="ACCOUNT OF", + direction="on", + linebreak="al", + specials={ "compat", 0x0061, 0x002F, 0x0063 }, + unicodeslot=0x2100, + }, + [0x2101]={ + category="so", + description="ADDRESSED TO THE SUBJECT", + direction="on", + linebreak="al", + specials={ "compat", 0x0061, 0x002F, 0x0073 }, + unicodeslot=0x2101, + }, + [0x2102]={ + category="lu", + description="DOUBLE-STRUCK CAPITAL C", + direction="l", + linebreak="al", + mathclass="variable", + mathname="complexes", + specials={ "font", 0x0043 }, + unicodeslot=0x2102, + }, + [0x2103]={ + category="so", + cjkwd="a", + description="DEGREE CELSIUS", + contextname="textcelsius", + direction="on", + linebreak="po", + specials={ "compat", 0x00B0, 0x0043 }, + unicodeslot=0x2103, + }, + [0x2104]={ + category="so", + description="CENTRE LINE SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x2104, + }, + [0x2105]={ + adobename="afii61248", + category="so", + cjkwd="a", + description="CARE OF", + direction="on", + linebreak="ai", + specials={ "compat", 0x0063, 0x002F, 0x006F }, + unicodeslot=0x2105, + }, + [0x2106]={ + category="so", + description="CADA UNA", + direction="on", + linebreak="al", + specials={ "compat", 0x0063, 0x002F, 0x0075 }, + unicodeslot=0x2106, + }, + [0x2107]={ + category="lu", + description="EULER CONSTANT", + direction="l", + linebreak="al", + specials={ "compat", 0x0190 }, + unicodeslot=0x2107, + }, + [0x2108]={ + category="so", + description="SCRUPLE", + direction="on", + linebreak="al", + unicodeslot=0x2108, + }, + [0x2109]={ + category="so", + cjkwd="a", + description="DEGREE FAHRENHEIT", + direction="on", + linebreak="po", + specials={ "compat", 0x00B0, 0x0046 }, + unicodeslot=0x2109, + }, + [0x210A]={ + category="ll", + description="SCRIPT SMALL G", + direction="l", + linebreak="al", + specials={ "font", 0x0067 }, + unicodeslot=0x210A, + }, + [0x210B]={ + category="lu", + description="SCRIPT CAPITAL H", + direction="l", + linebreak="al", + specials={ "font", 0x0048 }, + unicodeslot=0x210B, + }, + [0x210C]={ + category="lu", + description="BLACK-LETTER CAPITAL H", + direction="l", + linebreak="al", + specials={ "font", 0x0048 }, + unicodeslot=0x210C, + }, + [0x210D]={ + category="lu", + description="DOUBLE-STRUCK CAPITAL H", + direction="l", + linebreak="al", + specials={ "font", 0x0048 }, + unicodeslot=0x210D, + }, + [0x210E]={ + category="ll", + description="PLANCK CONSTANT", + direction="l", + linebreak="al", + specials={ "font", 0x0068 }, + unicodeslot=0x210E, + }, + [0x210F]={ + category="ll", + description="PLANCK CONSTANT OVER TWO PI", + direction="l", + linebreak="al", + mathclass="variable", + mathname="hslash", + specials={ "font", 0x0127 }, + unicodeslot=0x210F, + }, + [0x2110]={ + category="lu", + description="SCRIPT CAPITAL I", + direction="l", + linebreak="al", + specials={ "font", 0x0049 }, + unicodeslot=0x2110, + }, + [0x2111]={ + adobename="Ifraktur", + category="lu", + description="BLACK-LETTER CAPITAL I", + direction="l", + linebreak="al", + mathclass="default", + mathname="Im", + specials={ "font", 0x0049 }, + unicodeslot=0x2111, + }, + [0x2112]={ + category="lu", + description="SCRIPT CAPITAL L", + direction="l", + linebreak="al", + specials={ "font", 0x004C }, + unicodeslot=0x2112, + }, + [0x2113]={ + adobename="afii61289", + category="ll", + cjkwd="a", + description="SCRIPT SMALL L", + direction="l", + linebreak="ai", + mathclass="default", + mathname="ell", + specials={ "font", 0x006C }, + unicodeslot=0x2113, + }, + [0x2114]={ + category="so", + description="L B BAR SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x2114, + }, + [0x2115]={ + category="lu", + description="DOUBLE-STRUCK CAPITAL N", + direction="l", + linebreak="al", + mathclass="variable", + mathname="naturalnumbers", + specials={ "font", 0x004E }, + unicodeslot=0x2115, + }, + [0x2116]={ + adobename="afii61352", + category="so", + cjkwd="a", + contextname="textnumero", + description="NUMERO SIGN", + direction="on", + linebreak="pr", + specials={ "compat", 0x004E, 0x006F }, + unicodeslot=0x2116, + }, + [0x2117]={ + category="so", + contextname="textcircledP", + description="SOUND RECORDING COPYRIGHT", + direction="on", + linebreak="al", + unicodeslot=0x2117, + }, + [0x2118]={ + adobename="weierstrass", + category="so", + description="SCRIPT CAPITAL P", + direction="on", + linebreak="al", + mathclass="default", + mathname="wp", + unicodeslot=0x2118, + }, + [0x2119]={ + category="lu", + description="DOUBLE-STRUCK CAPITAL P", + direction="l", + linebreak="al", + mathclass="variable", + mathname="primes", + specials={ "font", 0x0050 }, + unicodeslot=0x2119, + }, + [0x211A]={ + category="lu", + description="DOUBLE-STRUCK CAPITAL Q", + direction="l", + linebreak="al", + mathclass="variable", + mathname="rationals", + specials={ "font", 0x0051 }, + unicodeslot=0x211A, + }, + [0x211B]={ + category="lu", + description="SCRIPT CAPITAL R", + direction="l", + linebreak="al", + specials={ "font", 0x0052 }, + unicodeslot=0x211B, + }, + [0x211C]={ + adobename="Rfraktur", + category="lu", + description="BLACK-LETTER CAPITAL R", + direction="l", + linebreak="al", + mathclass="default", + mathname="Re", + specials={ "font", 0x0052 }, + unicodeslot=0x211C, + }, + [0x211D]={ + category="lu", + description="DOUBLE-STRUCK CAPITAL R", + direction="l", + linebreak="al", + mathclass="variable", + mathname="reals", + specials={ "font", 0x0052 }, + unicodeslot=0x211D, + }, + [0x211E]={ + adobename="prescription", + category="so", + description="PRESCRIPTION TAKE", + direction="on", + linebreak="al", + unicodeslot=0x211E, + }, + [0x211F]={ + category="so", + description="RESPONSE", + direction="on", + linebreak="al", + unicodeslot=0x211F, + }, + [0x2120]={ + category="so", + description="SERVICE MARK", + direction="on", + linebreak="al", + specials={ "super", 0x0053, 0x004D }, + unicodeslot=0x2120, + }, + [0x2121]={ + category="so", + cjkwd="a", + description="TELEPHONE SIGN", + direction="on", + linebreak="ai", + specials={ "compat", 0x0054, 0x0045, 0x004C }, + unicodeslot=0x2121, + }, + [0x2122]={ + adobename="trademark", + category="so", + cjkwd="a", + contextname="trademark", + description="TRADE MARK SIGN", + direction="on", + linebreak="ai", + specials={ "super", 0x0054, 0x004D }, + unicodeslot=0x2122, + }, + [0x2123]={ + category="so", + description="VERSICLE", + direction="on", + linebreak="al", + unicodeslot=0x2123, + }, + [0x2124]={ + category="lu", + description="DOUBLE-STRUCK CAPITAL Z", + direction="l", + linebreak="al", + mathclass="variable", + mathname="integers", + specials={ "font", 0x005A }, + unicodeslot=0x2124, + }, + [0x2125]={ + category="so", + contextname="textounce", + description="OUNCE SIGN", + direction="on", + linebreak="al", + unicodeslot=0x2125, + }, + [0x2126]={ + adobename="Omega", + category="lu", + cjkwd="a", + description="OHM SIGN", + contextname="textohm", + direction="l", + lccode=0x03C9, --AM: Not sure? + linebreak="al", + mathclass="variable", + 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", + mathname="mho", + unicodeslot=0x2127, + }, + [0x2128]={ + category="lu", + description="BLACK-LETTER CAPITAL Z", + direction="l", + linebreak="al", + specials={ "font", 0x005A }, + unicodeslot=0x2128, + }, + [0x2129]={ + category="so", + description="TURNED GREEK SMALL LETTER IOTA", + direction="on", + linebreak="al", + unicodeslot=0x2129, + }, + [0x212A]={ + category="lu", + description="KELVIN SIGN", + direction="l", + contextname="textkelvin", + lccode=0x006B, + linebreak="al", + specials={ "char", 0x004B }, + unicodeslot=0x212A, + }, + [0x212B]={ + category="lu", + cjkwd="a", + description="ANGSTROM SIGN", + direction="l", + contextname="textAngstrom", + lccode=0x00E5, + linebreak="ai", + mathclass="variable", + mathname="Angstrom", + specials={ "char", 0x00C5 }, + unicodeslot=0x212B, + }, + [0x212C]={ + category="lu", + description="SCRIPT CAPITAL B", + direction="l", + linebreak="al", + specials={ "font", 0x0042 }, + unicodeslot=0x212C, + }, + [0x212D]={ + category="lu", + description="BLACK-LETTER CAPITAL C", + direction="l", + linebreak="al", + specials={ "font", 0x0043 }, + unicodeslot=0x212D, + }, + [0x212E]={ + adobename="estimated", + category="so", + description="ESTIMATED SYMBOL", + direction="et", + linebreak="al", + unicodeslot=0x212E, + }, + [0x212F]={ + category="ll", + description="SCRIPT SMALL E", + direction="l", + linebreak="al", + specials={ "font", 0x0065 }, + unicodeslot=0x212F, + }, + [0x2130]={ + category="lu", + description="SCRIPT CAPITAL E", + direction="l", + linebreak="al", + specials={ "font", 0x0045 }, + unicodeslot=0x2130, + }, + [0x2131]={ + category="lu", + description="SCRIPT CAPITAL F", + direction="l", + linebreak="al", + specials={ "font", 0x0046 }, + unicodeslot=0x2131, + }, + [0x2132]={ + category="lu", + description="TURNED CAPITAL F", + direction="l", + lccode=0x214E, + linebreak="al", + mathclass="ord", + mathname="Finv", + unicodeslot=0x2132, + }, + [0x2133]={ + category="lu", + description="SCRIPT CAPITAL M", + direction="l", + linebreak="al", + specials={ "font", 0x004D }, + unicodeslot=0x2133, + }, + [0x2134]={ + category="ll", + description="SCRIPT SMALL O", + direction="l", + linebreak="al", + specials={ "font", 0x006F }, + unicodeslot=0x2134, + }, + [0x2135]={ + adobename="aleph", + category="lo", + description="ALEF SYMBOL", + direction="l", + linebreak="al", + mathclass="default", + mathname="aleph", + specials={ "compat", 0x05D0 }, + unicodeslot=0x2135, + }, + [0x2136]={ + category="lo", + description="BET SYMBOL", + direction="l", + linebreak="al", + mathclass="ord", + mathname="beth", + specials={ "compat", 0x05D1 }, + unicodeslot=0x2136, + }, + [0x2137]={ + category="lo", + description="GIMEL SYMBOL", + direction="l", + linebreak="al", + mathclass="ord", + mathname="gimel", + specials={ "compat", 0x05D2 }, + unicodeslot=0x2137, + }, + [0x2138]={ + category="lo", + description="DALET SYMBOL", + direction="l", + linebreak="al", + mathclass="ord", + mathname="daleth", + specials={ "compat", 0x05D3 }, + unicodeslot=0x2138, + }, + [0x2139]={ + category="ll", + description="INFORMATION SOURCE", + direction="l", + linebreak="al", + specials={ "font", 0x0069 }, + unicodeslot=0x2139, + }, + [0x213A]={ + category="so", + description="ROTATED CAPITAL Q", + direction="on", + linebreak="al", + unicodeslot=0x213A, + }, + [0x213B]={ + category="so", + description="FACSIMILE SIGN", + direction="on", + linebreak="al", + specials={ "compat", 0x0046, 0x0041, 0x0058 }, + unicodeslot=0x213B, + }, + [0x213C]={ + category="ll", + description="DOUBLE-STRUCK SMALL PI", + direction="l", + linebreak="al", + specials={ "font", 0x03C0 }, + unicodeslot=0x213C, + }, + [0x213D]={ + category="ll", + description="DOUBLE-STRUCK SMALL GAMMA", + direction="l", + linebreak="al", + specials={ "font", 0x03B3 }, + unicodeslot=0x213D, + }, + [0x213E]={ + category="lu", + description="DOUBLE-STRUCK CAPITAL GAMMA", + direction="l", + linebreak="al", + specials={ "font", 0x0393 }, + unicodeslot=0x213E, + }, + [0x213F]={ + category="lu", + description="DOUBLE-STRUCK CAPITAL PI", + direction="l", + linebreak="al", + specials={ "font", 0x03A0 }, + unicodeslot=0x213F, + }, + [0x2140]={ + category="sm", + description="DOUBLE-STRUCK N-ARY SUMMATION", + direction="on", + linebreak="al", + specials={ "font", 0x2211 }, + unicodeslot=0x2140, + }, + [0x2141]={ + category="sm", + description="TURNED SANS-SERIF CAPITAL G", + direction="on", + linebreak="al", + mathclass="ord", + mathname="Game", + unicodeslot=0x2141, + }, + [0x2142]={ + category="sm", + description="TURNED SANS-SERIF CAPITAL L", + direction="on", + linebreak="al", + unicodeslot=0x2142, + }, + [0x2143]={ + category="sm", + description="REVERSED SANS-SERIF CAPITAL L", + direction="on", + linebreak="al", + unicodeslot=0x2143, + }, + [0x2144]={ + category="sm", + description="TURNED SANS-SERIF CAPITAL Y", + direction="on", + linebreak="al", + unicodeslot=0x2144, + }, + [0x2145]={ + category="lu", + description="DOUBLE-STRUCK ITALIC CAPITAL D", + direction="l", + linebreak="al", + mathclass="nothing", + mathname="differentialD", + specials={ "font", 0x0044 }, + unicodeslot=0x2145, + }, + [0x2146]={ + category="ll", + description="DOUBLE-STRUCK ITALIC SMALL D", + direction="l", + linebreak="al", + mathclass="nothing", + mathname="differentiald", + specials={ "font", 0x0064 }, + unicodeslot=0x2146, + }, + [0x2147]={ + category="ll", + description="DOUBLE-STRUCK ITALIC SMALL E", + direction="l", + linebreak="al", + mathclass="nothing", + mathname="exponentiale", + specials={ "font", 0x0065 }, + unicodeslot=0x2147, + }, + [0x2148]={ + category="ll", + description="DOUBLE-STRUCK ITALIC SMALL I", + direction="l", + linebreak="al", + mathclass="nothing", + mathname="imaginaryi", + specials={ "font", 0x0069 }, + unicodeslot=0x2148, + }, + [0x2149]={ + category="ll", + description="DOUBLE-STRUCK ITALIC SMALL J", + direction="l", + linebreak="al", + mathclass="nothing", + mathname="imaginaryj", + specials={ "font", 0x006A }, + unicodeslot=0x2149, + }, + [0x214A]={ + category="so", + description="PROPERTY LINE", + direction="on", + linebreak="al", + unicodeslot=0x214A, + }, + [0x214B]={ + category="sm", + description="TURNED AMPERSAND", + direction="on", + linebreak="al", + unicodeslot=0x214B, + }, + [0x214C]={ + category="so", + description="PER SIGN", + direction="on", + linebreak="al", + unicodeslot=0x214C, + }, + [0x214D]={ + category="so", + description="AKTIESELSKAB", + direction="on", + linebreak="al", + unicodeslot=0x214D, + }, + [0x214E]={ + category="ll", + description="TURNED SMALL F", + direction="l", + linebreak="al", + uccode=0x2132, + unicodeslot=0x214E, + }, + [0x2153]={ + adobename="onethird", + category="no", + cjkwd="a", + contextname="onethird", + description="VULGAR FRACTION ONE THIRD", + direction="on", + linebreak="al", + specials={ "fraction", 0x0031, 0x2044, 0x0033 }, + unicodeslot=0x2153, + }, + [0x2154]={ + adobename="twothirds", + category="no", + cjkwd="a", + contextname="twothirds", + description="VULGAR FRACTION TWO THIRDS", + direction="on", + linebreak="ai", + specials={ "fraction", 0x0032, 0x2044, 0x0033 }, + unicodeslot=0x2154, + }, + [0x2155]={ + category="no", + contextname="onefifth", + description="VULGAR FRACTION ONE FIFTH", + direction="on", + linebreak="ai", + specials={ "fraction", 0x0031, 0x2044, 0x0035 }, + unicodeslot=0x2155, + }, + [0x2156]={ + category="no", + contextname="twofifths", + description="VULGAR FRACTION TWO FIFTHS", + direction="on", + linebreak="al", + specials={ "fraction", 0x0032, 0x2044, 0x0035 }, + unicodeslot=0x2156, + }, + [0x2157]={ + category="no", + contextname="threefifths", + description="VULGAR FRACTION THREE FIFTHS", + direction="on", + linebreak="al", + specials={ "fraction", 0x0033, 0x2044, 0x0035 }, + unicodeslot=0x2157, + }, + [0x2158]={ + category="no", + contextname="fourfifths", + description="VULGAR FRACTION FOUR FIFTHS", + direction="on", + linebreak="al", + specials={ "fraction", 0x0034, 0x2044, 0x0035 }, + unicodeslot=0x2158, + }, + [0x2159]={ + category="no", + contextname="onesixth", + description="VULGAR FRACTION ONE SIXTH", + direction="on", + linebreak="al", + specials={ "fraction", 0x0031, 0x2044, 0x0036 }, + unicodeslot=0x2159, + }, + [0x215A]={ + category="no", + contextname="fivesixths", + description="VULGAR FRACTION FIVE SIXTHS", + direction="on", + linebreak="al", + specials={ "fraction", 0x0035, 0x2044, 0x0036 }, + unicodeslot=0x215A, + }, + [0x215B]={ + adobename="oneeighth", + category="no", + cjkwd="a", + contextname="oneeighth", + description="VULGAR FRACTION ONE EIGHTH", + direction="on", + linebreak="ai", + specials={ "fraction", 0x0031, 0x2044, 0x0038 }, + unicodeslot=0x215B, + }, + [0x215C]={ + adobename="threeeighths", + category="no", + cjkwd="a", + contextname="threeeighths", + description="VULGAR FRACTION THREE EIGHTHS", + direction="on", + linebreak="al", + specials={ "fraction", 0x0033, 0x2044, 0x0038 }, + unicodeslot=0x215C, + }, + [0x215D]={ + adobename="fiveeighths", + category="no", + cjkwd="a", + contextname="fiveeighths", + description="VULGAR FRACTION FIVE EIGHTHS", + direction="on", + linebreak="al", + specials={ "fraction", 0x0035, 0x2044, 0x0038 }, + unicodeslot=0x215D, + }, + [0x215E]={ + adobename="seveneighths", + category="no", + cjkwd="a", + contextname="seveneighths", + description="VULGAR FRACTION SEVEN EIGHTHS", + direction="on", + linebreak="ai", + specials={ "fraction", 0x0037, 0x2044, 0x0038 }, + unicodeslot=0x215E, + }, + [0x215F]={ + category="no", + description="FRACTION NUMERATOR ONE", + direction="on", + linebreak="al", + specials={ "fraction", 0x0031, 0x2044 }, + unicodeslot=0x215F, + }, + [0x2160]={ + category="nl", + cjkwd="a", + contextname="romanI", + description="ROMAN NUMERAL ONE", + direction="l", + lccode=0x2170, + linebreak="ai", + specials={ "compat", 0x0049 }, + unicodeslot=0x2160, + }, + [0x2161]={ + category="nl", + cjkwd="a", + contextname="romanII", + description="ROMAN NUMERAL TWO", + direction="l", + lccode=0x2171, + linebreak="ai", + specials={ "compat", 0x0049, 0x0049 }, + unicodeslot=0x2161, + }, + [0x2162]={ + category="nl", + cjkwd="a", + contextname="romanIII", + description="ROMAN NUMERAL THREE", + direction="l", + lccode=0x2172, + linebreak="ai", + specials={ "compat", 0x0049, 0x0049, 0x0049 }, + unicodeslot=0x2162, + }, + [0x2163]={ + category="nl", + cjkwd="a", + contextname="romanIV", + description="ROMAN NUMERAL FOUR", + direction="l", + lccode=0x2173, + linebreak="ai", + specials={ "compat", 0x0049, 0x0056 }, + unicodeslot=0x2163, + }, + [0x2164]={ + category="nl", + cjkwd="a", + contextname="romanV", + description="ROMAN NUMERAL FIVE", + direction="l", + lccode=0x2174, + linebreak="ai", + specials={ "compat", 0x0056 }, + unicodeslot=0x2164, + }, + [0x2165]={ + category="nl", + cjkwd="a", + contextname="romanVI", + description="ROMAN NUMERAL SIX", + direction="l", + lccode=0x2175, + linebreak="ai", + specials={ "compat", 0x0056, 0x0049 }, + unicodeslot=0x2165, + }, + [0x2166]={ + category="nl", + cjkwd="a", + contextname="romanVII", + description="ROMAN NUMERAL SEVEN", + direction="l", + lccode=0x2176, + linebreak="ai", + specials={ "compat", 0x0056, 0x0049, 0x0049 }, + unicodeslot=0x2166, + }, + [0x2167]={ + category="nl", + cjkwd="a", + contextname="romanVIII", + description="ROMAN NUMERAL EIGHT", + direction="l", + lccode=0x2177, + linebreak="ai", + specials={ "compat", 0x0056, 0x0049, 0x0049, 0x0049 }, + unicodeslot=0x2167, + }, + [0x2168]={ + category="nl", + cjkwd="a", + contextname="romanIX", + description="ROMAN NUMERAL NINE", + direction="l", + lccode=0x2178, + linebreak="ai", + specials={ "compat", 0x0049, 0x0058 }, + unicodeslot=0x2168, + }, + [0x2169]={ + category="nl", + cjkwd="a", + contextname="romanX", + description="ROMAN NUMERAL TEN", + direction="l", + lccode=0x2179, + linebreak="ai", + specials={ "compat", 0x0058 }, + unicodeslot=0x2169, + }, + [0x216A]={ + category="nl", + cjkwd="a", + contextname="romanXI", + description="ROMAN NUMERAL ELEVEN", + direction="l", + lccode=0x217A, + linebreak="ai", + specials={ "compat", 0x0058, 0x0049 }, + unicodeslot=0x216A, + }, + [0x216B]={ + category="nl", + cjkwd="a", + contextname="romanXII", + description="ROMAN NUMERAL TWELVE", + direction="l", + lccode=0x217B, + linebreak="ai", + specials={ "compat", 0x0058, 0x0049, 0x0049 }, + unicodeslot=0x216B, + }, + [0x216C]={ + category="nl", + contextname="romanL", + description="ROMAN NUMERAL FIFTY", + direction="l", + lccode=0x217C, + linebreak="al", + specials={ "compat", 0x004C }, + unicodeslot=0x216C, + }, + [0x216D]={ + category="nl", + contextname="romanC", + description="ROMAN NUMERAL ONE HUNDRED", + direction="l", + lccode=0x217D, + linebreak="al", + specials={ "compat", 0x0043 }, + unicodeslot=0x216D, + }, + [0x216E]={ + category="nl", + contextname="romanD", + description="ROMAN NUMERAL FIVE HUNDRED", + direction="l", + lccode=0x217E, + linebreak="al", + specials={ "compat", 0x0044 }, + unicodeslot=0x216E, + }, + [0x216F]={ + category="nl", + contextname="romanM", + description="ROMAN NUMERAL ONE THOUSAND", + direction="l", + lccode=0x217F, + linebreak="al", + specials={ "compat", 0x004D }, + unicodeslot=0x216F, + }, + [0x2170]={ + category="nl", + cjkwd="a", + contextname="romani", + description="SMALL ROMAN NUMERAL ONE", + direction="l", + linebreak="ai", + specials={ "compat", 0x0069 }, + uccode=0x2160, + unicodeslot=0x2170, + }, + [0x2171]={ + category="nl", + cjkwd="a", + contextname="romanii", + description="SMALL ROMAN NUMERAL TWO", + direction="l", + linebreak="ai", + specials={ "compat", 0x0069, 0x0069 }, + uccode=0x2161, + unicodeslot=0x2171, + }, + [0x2172]={ + category="nl", + cjkwd="a", + contextname="romaniii", + description="SMALL ROMAN NUMERAL THREE", + direction="l", + linebreak="ai", + specials={ "compat", 0x0069, 0x0069, 0x0069 }, + uccode=0x2162, + unicodeslot=0x2172, + }, + [0x2173]={ + category="nl", + cjkwd="a", + contextname="romaniv", + description="SMALL ROMAN NUMERAL FOUR", + direction="l", + linebreak="ai", + specials={ "compat", 0x0069, 0x0076 }, + uccode=0x2163, + unicodeslot=0x2173, + }, + [0x2174]={ + category="nl", + cjkwd="a", + contextname="romanv", + description="SMALL ROMAN NUMERAL FIVE", + direction="l", + linebreak="ai", + specials={ "compat", 0x0076 }, + uccode=0x2164, + unicodeslot=0x2174, + }, + [0x2175]={ + category="nl", + cjkwd="a", + contextname="romanvi", + description="SMALL ROMAN NUMERAL SIX", + direction="l", + linebreak="ai", + specials={ "compat", 0x0076, 0x0069 }, + uccode=0x2165, + unicodeslot=0x2175, + }, + [0x2176]={ + category="nl", + cjkwd="a", + contextname="romanvii", + description="SMALL ROMAN NUMERAL SEVEN", + direction="l", + linebreak="ai", + specials={ "compat", 0x0076, 0x0069, 0x0069 }, + uccode=0x2166, + unicodeslot=0x2176, + }, + [0x2177]={ + category="nl", + cjkwd="a", + contextname="romanviii", + description="SMALL ROMAN NUMERAL EIGHT", + direction="l", + linebreak="ai", + specials={ "compat", 0x0076, 0x0069, 0x0069, 0x0069 }, + uccode=0x2167, + unicodeslot=0x2177, + }, + [0x2178]={ + category="nl", + cjkwd="a", + contextname="romanix", + description="SMALL ROMAN NUMERAL NINE", + direction="l", + linebreak="ai", + specials={ "compat", 0x0069, 0x0078 }, + uccode=0x2168, + unicodeslot=0x2178, + }, + [0x2179]={ + category="nl", + cjkwd="a", + contextname="romanx", + description="SMALL ROMAN NUMERAL TEN", + direction="l", + linebreak="ai", + specials={ "compat", 0x0078 }, + uccode=0x2169, + unicodeslot=0x2179, + }, + [0x217A]={ + category="nl", + contextname="romanxi", + description="SMALL ROMAN NUMERAL ELEVEN", + direction="l", + linebreak="al", + specials={ "compat", 0x0078, 0x0069 }, + uccode=0x216A, + unicodeslot=0x217A, + }, + [0x217B]={ + category="nl", + contextname="romanxii", + description="SMALL ROMAN NUMERAL TWELVE", + direction="l", + linebreak="al", + specials={ "compat", 0x0078, 0x0069, 0x0069 }, + uccode=0x216B, + unicodeslot=0x217B, + }, + [0x217C]={ + category="nl", + contextname="romanl", + description="SMALL ROMAN NUMERAL FIFTY", + direction="l", + linebreak="al", + specials={ "compat", 0x006C }, + uccode=0x216C, + unicodeslot=0x217C, + }, + [0x217D]={ + category="nl", + contextname="romanc", + description="SMALL ROMAN NUMERAL ONE HUNDRED", + direction="l", + linebreak="al", + specials={ "compat", 0x0063 }, + uccode=0x216D, + unicodeslot=0x217D, + }, + [0x217E]={ + category="nl", + contextname="romand", + description="SMALL ROMAN NUMERAL FIVE HUNDRED", + direction="l", + linebreak="al", + specials={ "compat", 0x0064 }, + uccode=0x216E, + unicodeslot=0x217E, + }, + [0x217F]={ + category="nl", + contextname="romanm", + description="SMALL ROMAN NUMERAL ONE THOUSAND", + direction="l", + linebreak="al", + specials={ "compat", 0x006D }, + uccode=0x216F, + unicodeslot=0x217F, + }, + [0x2180]={ + category="nl", + description="ROMAN NUMERAL ONE THOUSAND C D", + direction="l", + linebreak="al", + unicodeslot=0x2180, + }, + [0x2181]={ + category="nl", + description="ROMAN NUMERAL FIVE THOUSAND", + direction="l", + linebreak="al", + unicodeslot=0x2181, + }, + [0x2182]={ + category="nl", + description="ROMAN NUMERAL TEN THOUSAND", + direction="l", + linebreak="al", + unicodeslot=0x2182, + }, + [0x2183]={ + category="lu", + description="ROMAN NUMERAL REVERSED ONE HUNDRED", + direction="l", + lccode=0x2184, + linebreak="al", + unicodeslot=0x2183, + }, + [0x2184]={ + category="ll", + description="LATIN SMALL LETTER REVERSED C", + direction="l", + linebreak="al", + uccode=0x2183, + unicodeslot=0x2184, + }, + [0x2190]={ + adobename="arrowleft", + category="sm", + cjkwd="a", + description="LEFTWARDS ARROW", + direction="on", + linebreak="ai", + mathspec={ + { class="relation", name="leftarrow" }, + { class="relation", name="gets" }, + { class="under", name="underleftarrow" }, + { class="over", name="overleftarrow" }, + }, + mathstretch="h", + unicodeslot=0x2190, + }, + [0x2191]={ + adobename="arrowup", + category="sm", + cjkwd="a", + description="UPWARDS ARROW", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="uparrow", + unicodeslot=0x2191, + }, + [0x2192]={ + adobename="arrowright", + category="sm", + cjkwd="a", + description="RIGHTWARDS ARROW", + direction="on", + linebreak="ai", + mathspec={ + { class="relation",name="rightarrow" }, + { class="relation",name="to" }, + { class="under", name="underrightarrow" }, + { class="over", name="overrightarrow" }, + }, + mathstretch="h", + unicodeslot=0x2192, + }, + [0x2193]={ + adobename="arrowdown", + category="sm", + cjkwd="a", + description="DOWNWARDS ARROW", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="downarrow", + unicodeslot=0x2193, + }, + [0x2194]={ + adobename="arrowboth", + category="sm", + cjkwd="a", + description="LEFT RIGHT ARROW", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="leftrightarrow", + unicodeslot=0x2194, + }, + [0x2195]={ + adobename="arrowupdn", + category="so", + cjkwd="a", + description="UP DOWN ARROW", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="updownarrow", + unicodeslot=0x2195, + }, + [0x2196]={ + category="so", + cjkwd="a", + description="NORTH WEST ARROW", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="nwarrow", + unicodeslot=0x2196, + }, + [0x2197]={ + category="so", + cjkwd="a", + description="NORTH EAST ARROW", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="nearrow", + unicodeslot=0x2197, + }, + [0x2198]={ + category="so", + cjkwd="a", + description="SOUTH EAST ARROW", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="searrow", + unicodeslot=0x2198, + }, + [0x2199]={ + category="so", + cjkwd="a", + description="SOUTH WEST ARROW", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="swarrow", + unicodeslot=0x2199, + }, + [0x219A]={ + category="sm", + description="LEFTWARDS ARROW WITH STROKE", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nleftarrow", + specials={ "char", 0x2190, 0x0338 }, + unicodeslot=0x219A, + }, + [0x219B]={ + category="sm", + description="RIGHTWARDS ARROW WITH STROKE", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nrightarrow", + specials={ "char", 0x2192, 0x0338 }, + unicodeslot=0x219B, + }, + [0x219C]={ + category="so", + description="LEFTWARDS WAVE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x219C, + }, + [0x219D]={ + category="so", + description="RIGHTWARDS WAVE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x219D, + }, + [0x219E]={ + category="so", + description="LEFTWARDS TWO HEADED ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="twoheadleftarrow", + unicodeslot=0x219E, + }, + [0x219F]={ + category="so", + description="UPWARDS TWO HEADED ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="twoheadupleftarrow", + unicodeslot=0x219F, + }, + [0x21A0]={ + category="sm", + description="RIGHTWARDS TWO HEADED ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="twoheadrightarrow", + unicodeslot=0x21A0, + }, + [0x21A1]={ + category="so", + description="DOWNWARDS TWO HEADED ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="twoheaddownleftarrow", + unicodeslot=0x21A1, + }, + [0x21A2]={ + category="so", + description="LEFTWARDS ARROW WITH TAIL", + direction="on", + linebreak="al", + mathclass="relation", + mathname="leftarrowtail", + unicodeslot=0x21A2, + }, + [0x21A3]={ + category="sm", + description="RIGHTWARDS ARROW WITH TAIL", + direction="on", + linebreak="al", + mathclass="relation", + mathname="rightarrowtail", + unicodeslot=0x21A3, + }, + [0x21A4]={ + category="so", + description="LEFTWARDS ARROW FROM BAR", + direction="on", + linebreak="al", + unicodeslot=0x21A4, + }, + [0x21A5]={ + category="so", + description="UPWARDS ARROW FROM BAR", + direction="on", + linebreak="al", + unicodeslot=0x21A5, + }, + [0x21A6]={ + category="sm", + description="RIGHTWARDS ARROW FROM BAR", + direction="on", + linebreak="al", + fallback=[[\mapstochar\rightarrow]], + mathclass="relation", + mathname="mapsto", + unicodeslot=0x21A6, + }, + [0x21A7]={ + category="so", + description="DOWNWARDS ARROW FROM BAR", + direction="on", + linebreak="al", + unicodeslot=0x21A7, + }, + [0x21A8]={ + adobename="arrowupdnbse", + category="so", + description="UP DOWN ARROW WITH BASE", + direction="on", + linebreak="al", + unicodeslot=0x21A8, + }, + [0x21A9]={ + category="so", + description="LEFTWARDS ARROW WITH HOOK", + direction="on", + linebreak="al", + fallback=[[\leftarrow\joinrel\rhook]], + mathclass="relation", + mathname="hookleftarrow", + unicodeslot=0x21A9, + }, + [0x21AA]={ + category="so", + description="RIGHTWARDS ARROW WITH HOOK", + direction="on", + linebreak="al", + fallback=[[\lhook\joinrel\rightarrow]], + mathclass="relation", + mathname="hookrightarrow", + unicodeslot=0x21AA, + }, + [0x21AB]={ + category="so", + description="LEFTWARDS ARROW WITH LOOP", + direction="on", + linebreak="al", + mathclass="relation", + mathname="looparrowleft", + unicodeslot=0x21AB, + }, + [0x21AC]={ + category="so", + description="RIGHTWARDS ARROW WITH LOOP", + direction="on", + linebreak="al", + mathclass="relation", + mathname="looparrowright", + unicodeslot=0x21AC, + }, + [0x21AD]={ + category="so", + description="LEFT RIGHT WAVE ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="leftrightsquigarrow", + unicodeslot=0x21AD, + }, + [0x21AE]={ + category="sm", + description="LEFT RIGHT ARROW WITH STROKE", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nleftrightarrow", + specials={ "char", 0x2194, 0x0338 }, + unicodeslot=0x21AE, + }, + [0x21AF]={ + category="so", + description="DOWNWARDS ZIGZAG ARROW", + direction="on", + linebreak="al", + unicodeslot=0x21AF, + }, + [0x21B0]={ + category="so", + description="UPWARDS ARROW WITH TIP LEFTWARDS", + direction="on", + linebreak="al", + mathclass="relation", + mathname="Lsh", + unicodeslot=0x21B0, + }, + [0x21B1]={ + category="so", + description="UPWARDS ARROW WITH TIP RIGHTWARDS", + direction="on", + linebreak="al", + mathclass="relation", + mathname="Rsh", + unicodeslot=0x21B1, + }, + [0x21B2]={ + category="so", + description="DOWNWARDS ARROW WITH TIP LEFTWARDS", + direction="on", + linebreak="al", + mathclass="relation", + mathname="dlsh", -- from mathabx + unicodeslot=0x21B2, + }, + [0x21B3]={ + category="so", + description="DOWNWARDS ARROW WITH TIP RIGHTWARDS", + direction="on", + linebreak="al", + mathclass="relation", + mathname="drsh", -- from mathabx + unicodeslot=0x21B3, + }, + [0x21B4]={ + category="so", + description="RIGHTWARDS ARROW WITH CORNER DOWNWARDS", + direction="on", + linebreak="al", + unicodeslot=0x21B4, + }, + [0x21B5]={ + adobename="carriagereturn", + contextname="carriagereturn", + category="so", + description="DOWNWARDS ARROW WITH CORNER LEFTWARDS", + direction="on", + linebreak="al", + unicodeslot=0x21B5, + }, + [0x21B6]={ + category="so", + description="ANTICLOCKWISE TOP SEMICIRCLE ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="curvearrowleft", + unicodeslot=0x21B6, + }, + [0x21B7]={ + category="so", + description="CLOCKWISE TOP SEMICIRCLE ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="curvearrowright", + unicodeslot=0x21B7, + }, + [0x21B8]={ + category="so", + cjkwd="a", + description="NORTH WEST ARROW TO LONG BAR", + direction="on", + linebreak="al", + unicodeslot=0x21B8, + }, + [0x21B9]={ + category="so", + cjkwd="a", + description="LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR", + direction="on", + linebreak="al", + unicodeslot=0x21B9, + }, + [0x21BA]={ + category="so", + description="ANTICLOCKWISE OPEN CIRCLE ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="circlearrowright", + unicodeslot=0x21BA, + }, + [0x21BB]={ + category="so", + description="CLOCKWISE OPEN CIRCLE ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="circlearrowleft", + unicodeslot=0x21BB, + }, + [0x21BC]={ + category="so", + description="LEFTWARDS HARPOON WITH BARB UPWARDS", + direction="on", + linebreak="al", + mathclass="relation", + mathname="leftharpoonup", + unicodeslot=0x21BC, + }, + [0x21BD]={ + category="so", + description="LEFTWARDS HARPOON WITH BARB DOWNWARDS", + direction="on", + linebreak="al", + mathclass="relation", + mathname="leftharpoondown", + unicodeslot=0x21BD, + }, + [0x21BE]={ + category="so", + description="UPWARDS HARPOON WITH BARB RIGHTWARDS", + direction="on", + linebreak="al", + mathspec={ + { class="relation", name="upharpoonright" }, + { class="relation", name="restriction" }, + }, + unicodeslot=0x21BE, + }, + [0x21BF]={ + category="so", + description="UPWARDS HARPOON WITH BARB LEFTWARDS", + direction="on", + linebreak="al", + mathclass="relation", + mathname="upharpoonleft", + unicodeslot=0x21BF, + }, + [0x21C0]={ + category="so", + description="RIGHTWARDS HARPOON WITH BARB UPWARDS", + direction="on", + linebreak="al", + mathclass="relation", + mathname="rightharpoonup", + unicodeslot=0x21C0, + }, + [0x21C1]={ + category="so", + description="RIGHTWARDS HARPOON WITH BARB DOWNWARDS", + direction="on", + linebreak="al", + mathclass="relation", + mathname="rightharpoondown", + unicodeslot=0x21C1, + }, + [0x21C2]={ + category="so", + description="DOWNWARDS HARPOON WITH BARB RIGHTWARDS", + direction="on", + linebreak="al", + mathclass="relation", + mathname="downharpoonright", + unicodeslot=0x21C2, + }, + [0x21C3]={ + category="so", + description="DOWNWARDS HARPOON WITH BARB LEFTWARDS", + direction="on", + linebreak="al", + mathclass="relation", + mathname="downharpoonleft", + unicodeslot=0x21C3, + }, + [0x21C4]={ + category="so", + description="RIGHTWARDS ARROW OVER LEFTWARDS ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="rightleftarrows", + unicodeslot=0x21C4, + }, + [0x21C5]={ + category="so", + description="UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="updownarrows", + unicodeslot=0x21C5, + }, + [0x21C6]={ + category="so", + description="LEFTWARDS ARROW OVER RIGHTWARDS ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="leftrightarrows", + unicodeslot=0x21C6, + }, + [0x21C7]={ + category="so", + description="LEFTWARDS PAIRED ARROWS", + direction="on", + linebreak="al", + mathclass="relation", + mathname="leftleftarrows", + unicodeslot=0x21C7, + }, + [0x21C8]={ + category="so", + description="UPWARDS PAIRED ARROWS", + direction="on", + linebreak="al", + mathclass="relation", + mathname="upuparrows", + unicodeslot=0x21C8, + }, + [0x21C9]={ + category="so", + description="RIGHTWARDS PAIRED ARROWS", + direction="on", + linebreak="al", + mathclass="relation", + mathname="rightrightarrows", + unicodeslot=0x21C9, + }, + [0x21CA]={ + category="so", + description="DOWNWARDS PAIRED ARROWS", + direction="on", + linebreak="al", + mathclass="relation", + mathname="downdownarrows", + unicodeslot=0x21CA, + }, + [0x21CB]={ + category="so", + description="LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON", + direction="on", + linebreak="al", + mathclass="relation", + mathname="leftrightharpoons", + unicodeslot=0x21CB, + }, + [0x21CC]={ + category="so", + description="RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON", + direction="on", + linebreak="al", + mathclass="relation", + mathname="rightleftharpoons", + unicodeslot=0x21CC, + }, + [0x21CD]={ + category="so", + description="LEFTWARDS DOUBLE ARROW WITH STROKE", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nLeftarrow", + specials={ "char", 0x21D0, 0x0338 }, + unicodeslot=0x21CD, + }, + [0x21CE]={ + category="sm", + description="LEFT RIGHT DOUBLE ARROW WITH STROKE", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nLeftrightarrow", + specials={ "char", 0x21D4, 0x0338 }, + unicodeslot=0x21CE, + }, + [0x21CF]={ + category="sm", + description="RIGHTWARDS DOUBLE ARROW WITH STROKE", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nRightarrow", + specials={ "char", 0x21D2, 0x0338 }, + unicodeslot=0x21CF, + }, + [0x21D0]={ + adobename="arrowdblleft", + category="so", + description="LEFTWARDS DOUBLE ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="Leftarrow", + unicodeslot=0x21D0, + }, + [0x21D1]={ + adobename="arrowdblup", + category="so", + description="UPWARDS DOUBLE ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="Uparrow", + unicodeslot=0x21D1, + }, + [0x21D2]={ + adobename="arrowdblright", + category="sm", + cjkwd="a", + description="RIGHTWARDS DOUBLE ARROW", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="Rightarrow", + unicodeslot=0x21D2, + }, + [0x21D3]={ + adobename="arrowdbldown", + category="so", + description="DOWNWARDS DOUBLE ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="Downarrow", + unicodeslot=0x21D3, + }, + [0x21D4]={ + adobename="arrowdblboth", + category="sm", + cjkwd="a", + description="LEFT RIGHT DOUBLE ARROW", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="Leftrightarrow", + unicodeslot=0x21D4, + }, + [0x21D5]={ + category="so", + description="UP DOWN DOUBLE ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="Updownarrow", + unicodeslot=0x21D5, + }, + [0x21D6]={ + category="so", + description="NORTH WEST DOUBLE ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="Nwarrow", + unicodeslot=0x21D6, + }, + [0x21D7]={ + category="so", + description="NORTH EAST DOUBLE ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="Nearrow", + unicodeslot=0x21D7, + }, + [0x21D8]={ + category="so", + description="SOUTH EAST DOUBLE ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="Searrow", + unicodeslot=0x21D8, + }, + [0x21D9]={ + category="so", + description="SOUTH WEST DOUBLE ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="Swarrow", + unicodeslot=0x21D9, + }, + [0x21DA]={ + category="so", + description="LEFTWARDS TRIPLE ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="Lleftarrow", + unicodeslot=0x21DA, + }, + [0x21DB]={ + category="so", + description="RIGHTWARDS TRIPLE ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="Rrightarrow", + unicodeslot=0x21DB, + }, + [0x21DC]={ + category="so", + description="LEFTWARDS SQUIGGLE ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="leftsquigarrow", + unicodeslot=0x21DC, + }, + [0x21DD]={ + category="so", + description="RIGHTWARDS SQUIGGLE ARROW", + direction="on", + linebreak="al", + mathspec={ + { class="relation",name="rightsquigarrow" }, + { class="relation",name="leadsto" }, + }, + unicodeslot=0x21DD, + }, + [0x21DE]={ + category="so", + description="UPWARDS ARROW WITH DOUBLE STROKE", + direction="on", + linebreak="al", + unicodeslot=0x21DE, + }, + [0x21DF]={ + category="so", + description="DOWNWARDS ARROW WITH DOUBLE STROKE", + direction="on", + linebreak="al", + unicodeslot=0x21DF, + }, + [0x21E0]={ + category="so", + description="LEFTWARDS DASHED ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="dashleftarrow", + unicodeslot=0x21E0, + }, + [0x21E1]={ + category="so", + description="UPWARDS DASHED ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="dashuparrow", + unicodeslot=0x21E1, + }, + [0x21E2]={ + category="so", + description="RIGHTWARDS DASHED ARROW", + direction="on", + linebreak="al", + mathspec={ + { class="relation", name="dashrightarrow" } , + { class="relation", name="dasharrow" } , + }, + unicodeslot=0x21E2, + }, + [0x21E3]={ + category="so", + description="DOWNWARDS DASHED ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="dashdownarrow", + unicodeslot=0x21E3, + }, + [0x21E4]={ + category="so", + description="LEFTWARDS ARROW TO BAR", + direction="on", + linebreak="al", + unicodeslot=0x21E4, + }, + [0x21E5]={ + category="so", + description="RIGHTWARDS ARROW TO BAR", + direction="on", + linebreak="al", + unicodeslot=0x21E5, + }, + [0x21E6]={ + category="so", + description="LEFTWARDS WHITE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x21E6, + }, + [0x21E7]={ + category="so", + cjkwd="a", + description="UPWARDS WHITE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x21E7, + }, + [0x21E8]={ + category="so", + description="RIGHTWARDS WHITE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x21E8, + }, + [0x21E9]={ + category="so", + description="DOWNWARDS WHITE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x21E9, + }, + [0x21EA]={ + category="so", + description="UPWARDS WHITE ARROW FROM BAR", + direction="on", + linebreak="al", + unicodeslot=0x21EA, + }, + [0x21EB]={ + category="so", + description="UPWARDS WHITE ARROW ON PEDESTAL", + direction="on", + linebreak="al", + unicodeslot=0x21EB, + }, + [0x21EC]={ + category="so", + description="UPWARDS WHITE ARROW ON PEDESTAL WITH HORIZONTAL BAR", + direction="on", + linebreak="al", + unicodeslot=0x21EC, + }, + [0x21ED]={ + category="so", + description="UPWARDS WHITE ARROW ON PEDESTAL WITH VERTICAL BAR", + direction="on", + linebreak="al", + unicodeslot=0x21ED, + }, + [0x21EE]={ + category="so", + description="UPWARDS WHITE DOUBLE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x21EE, + }, + [0x21EF]={ + category="so", + description="UPWARDS WHITE DOUBLE ARROW ON PEDESTAL", + direction="on", + linebreak="al", + unicodeslot=0x21EF, + }, + [0x21F0]={ + category="so", + description="RIGHTWARDS WHITE ARROW FROM WALL", + direction="on", + linebreak="al", + unicodeslot=0x21F0, + }, + [0x21F1]={ + category="so", + description="NORTH WEST ARROW TO CORNER", + direction="on", + linebreak="al", + unicodeslot=0x21F1, + }, + [0x21F2]={ + category="so", + description="SOUTH EAST ARROW TO CORNER", + direction="on", + linebreak="al", + unicodeslot=0x21F2, + }, + [0x21F3]={ + category="so", + description="UP DOWN WHITE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x21F3, + }, + [0x21F4]={ + category="sm", + description="RIGHT ARROW WITH SMALL CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x21F4, + }, + [0x21F5]={ + category="sm", + description="DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x21F5, + }, + [0x21F6]={ + category="sm", + description="THREE RIGHTWARDS ARROWS", + direction="on", + linebreak="al", + unicodeslot=0x21F6, + }, + [0x21F7]={ + category="sm", + description="LEFTWARDS ARROW WITH VERTICAL STROKE", + direction="on", + linebreak="al", + unicodeslot=0x21F7, + }, + [0x21F8]={ + category="sm", + description="RIGHTWARDS ARROW WITH VERTICAL STROKE", + direction="on", + linebreak="al", + unicodeslot=0x21F8, + }, + [0x21F9]={ + category="sm", + description="LEFT RIGHT ARROW WITH VERTICAL STROKE", + direction="on", + linebreak="al", + unicodeslot=0x21F9, + }, + [0x21FA]={ + category="sm", + description="LEFTWARDS ARROW WITH DOUBLE VERTICAL STROKE", + direction="on", + linebreak="al", + unicodeslot=0x21FA, + }, + [0x21FB]={ + category="sm", + description="RIGHTWARDS ARROW WITH DOUBLE VERTICAL STROKE", + direction="on", + linebreak="al", + unicodeslot=0x21FB, + }, + [0x21FC]={ + category="sm", + description="LEFT RIGHT ARROW WITH DOUBLE VERTICAL STROKE", + direction="on", + linebreak="al", + unicodeslot=0x21FC, + }, + [0x21FD]={ + category="sm", + description="LEFTWARDS OPEN-HEADED ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="leftarrowtriangle", + unicodeslot=0x21FD, + }, + [0x21FE]={ + category="sm", + description="RIGHTWARDS OPEN-HEADED ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="rightarrowtriangle", + unicodeslot=0x21FE, + }, + [0x21FF]={ + category="sm", + description="LEFT RIGHT OPEN-HEADED ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="leftrightarrowtriangle", + unicodeslot=0x21FF, + }, + [0x2200]={ + adobename="universal", + category="sm", + cjkwd="a", + description="FOR ALL", + direction="on", + linebreak="ai", + mathclass="ord", + mathname="forall", + unicodeslot=0x2200, + }, + [0x2201]={ + category="sm", + description="COMPLEMENT", + direction="on", + linebreak="al", + mathclass="ord", + mathname="complement", + unicodeslot=0x2201, + }, + [0x2202]={ + adobename="partialdiff", + category="sm", + cjkwd="a", + description="PARTIAL DIFFERENTIAL", + direction="on", + linebreak="ai", + mathclass="default", + mathname="partial", + unicodeslot=0x2202, + }, + [0x2203]={ + adobename="existential", + category="sm", + cjkwd="a", + description="THERE EXISTS", + direction="on", + linebreak="ai", + mathclass="ord", + mathname="exists", + unicodeslot=0x2203, + }, + [0x2204]={ + category="sm", + description="THERE DOES NOT EXIST", + direction="on", + linebreak="al", + mathclass="ord", + mathname="nexists", + specials={ "char", 0x2203, 0x0338 }, + unicodeslot=0x2204, + }, + [0x2205]={ + adobename="emptyset", + category="sm", + description="EMPTY SET", + direction="on", + linebreak="al", + mathclass="default", + mathname="emptyset", + unicodeslot=0x2205, + }, + [0x2206]={ + adobename="Delta", + category="sm", + description="INCREMENT", + direction="on", + linebreak="al", + unicodeslot=0x2206, + }, + [0x2207]={ + adobename="gradient", + category="sm", + cjkwd="a", + description="NABLA", + direction="on", + linebreak="ai", + unicodeslot=0x2207, + }, + [0x2208]={ + adobename="element", + category="sm", + cjkwd="a", + description="ELEMENT OF", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="in", + mirror=0x220B, + unicodeslot=0x2208, + }, + [0x2209]={ + adobename="notelement", + category="sm", + description="NOT AN ELEMENT OF", + direction="on", + linebreak="al", + mirror=0x220C, + mathclass="relation", + mathname="nin", + specials={ "char", 0x2208, 0x0338 }, + unicodeslot=0x2209, + }, + [0x220A]={ + category="sm", + description="SMALL ELEMENT OF", + direction="on", + linebreak="al", + mirror=0x220D, + unicodeslot=0x220A, + }, + [0x220B]={ + adobename="suchthat", + category="sm", + cjkwd="a", + description="CONTAINS AS MEMBER", + direction="on", + linebreak="ai", + mathspec={ + { class="relation", name="ni" }, + { class="relation", name="owns" }, + }, + mirror=0x2208, + unicodeslot=0x220B, + }, + [0x220C]={ + category="sm", + description="DOES NOT CONTAIN AS MEMBER", + direction="on", + linebreak="al", + mirror=0x2209, + specials={ "char", 0x220B, 0x0338 }, + mathspec={ + { class="relation", name="nni" }, + { class="relation", name="nowns" }, + }, + unicodeslot=0x220C, + }, + [0x220D]={ + category="sm", + description="SMALL CONTAINS AS MEMBER", + direction="on", + linebreak="al", + mirror=0x220A, + unicodeslot=0x220D, + }, + [0x220E]={ + category="sm", + description="END OF PROOF", + direction="on", + linebreak="al", + unicodeslot=0x220E, + }, + [0x220F]={ + adobename="product", + category="sm", + cjkwd="a", + description="N-ARY PRODUCT", + direction="on", + linebreak="ai", + mathclass="limop", + mathname="prod", + unicodeslot=0x220F, + }, +[0x2210]={ + category="sm", + description="N-ARY COPRODUCT", + direction="on", + linebreak="al", + mathclass="limop", + mathname="coprod", + unicodeslot=0x2210, + }, + [0x2211]={ + adobename="summation", + category="sm", + cjkwd="a", + description="N-ARY SUMMATION", + direction="on", + linebreak="ai", + mathclass="limop", + mathname="sum", + unicodeslot=0x2211, + }, + [0x2212]={ + adobename="minus", + category="sm", + description="MINUS SIGN", + direction="es", + linebreak="pr", + mathclass="binary", + unicodeslot=0x2212, + }, + [0x2213]={ + category="sm", + description="MINUS-OR-PLUS SIGN", + direction="et", + linebreak="pr", + mathclass="binary", + mathname="mp", + unicodeslot=0x2213, + }, + [0x2214]={ + category="sm", + description="DOT PLUS", + direction="on", + linebreak="al", + mathclass="binary", + mathname="dotplus", + unicodeslot=0x2214, + }, + [0x2215]={ + category="sm", + cjkwd="a", + 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", + mathspec={ + { class="binary", name="setminus" }, + --~ { class="ord", name="diagdown" }, + }, + unicodeslot=0x2216, + }, + [0x2217]={ + adobename="asteriskmath", + category="sm", + description="ASTERISK OPERATOR", + direction="on", + linebreak="al", + mathclass="binary", + mathname="ast", + unicodeslot=0x2217, + }, + [0x2218]={ + category="sm", + description="RING OPERATOR", + direction="on", + linebreak="al", + mathclass="binary", + mathname="circ", + unicodeslot=0x2218, + }, + [0x2219]={ + category="sm", + description="BULLET OPERATOR", + direction="on", + linebreak="al", + mathclass="binary", + mathname="bullet", + unicodeslot=0x2219, + }, + [0x221A]={ + adobename="radical", + category="sm", + cjkwd="a", + description="SQUARE ROOT", + direction="on", + linebreak="ai", + mathclass="radical", + mathname="surd", + unicodeslot=0x221A, + }, + [0x221B]={ + category="sm", + description="CUBE ROOT", + direction="on", + linebreak="al", + unicodeslot=0x221B, + }, + [0x221C]={ + category="sm", + description="FOURTH ROOT", + direction="on", + linebreak="al", + unicodeslot=0x221C, + }, + [0x221D]={ + adobename="proportional", + category="sm", + cjkwd="a", + description="PROPORTIONAL TO", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="propto", + unicodeslot=0x221D, + }, + [0x221E]={ + adobename="infinity", + category="sm", + cjkwd="a", + description="INFINITY", + direction="on", + linebreak="ai", + mathclass="default", + mathname="infty", + unicodeslot=0x221E, + }, + [0x221F]={ + adobename="orthogonal", + category="sm", + cjkwd="a", + description="RIGHT ANGLE", + direction="on", + mathclass="ord", + mathname="rightangle", + linebreak="ai", + unicodeslot=0x221F, + }, + [0x2220]={ + adobename="angle", + category="sm", + cjkwd="a", + description="ANGLE", + direction="on", + linebreak="ai", + mathclass="ord", + mathname="angle", + unicodeslot=0x2220, + }, + [0x2221]={ + category="sm", + description="MEASURED ANGLE", + direction="on", + linebreak="al", + mathclass="ord", + mathname="measuredangle", + unicodeslot=0x2221, + }, + [0x2222]={ + category="sm", + description="SPHERICAL ANGLE", + direction="on", + linebreak="al", + mathclass="ord", + mathname="sphericalangle", + unicodeslot=0x2222, + }, + [0x2223]={ + category="sm", + cjkwd="a", + description="DIVIDES", + direction="on", + linebreak="ai", + mathclass="binary", + mathname="divides", + unicodeslot=0x2223, + }, + [0x2224]={ + category="sm", + description="DOES NOT DIVIDE", + direction="on", + linebreak="al", + specials={ "char", 0x2223, 0x0338 }, + mathspec={ + { class="binary", name="ndivides", }, + { class="relation", name="nmid", }, + }, + unicodeslot=0x2224, + }, + [0x2225]={ + category="sm", + cjkwd="a", + description="PARALLEL TO", + direction="on", + linebreak="ai", + mathspec={ + { class="relation", name="parallel" }, + { class="delimiter", name="Vert" }, + { class="nothing", name="Arrowvert" }, + { class="open", name="lVert" }, + { class="close", name="rVert" }, + }, + unicodeslot=0x2225, + }, + [0x2226]={ + category="sm", + description="NOT PARALLEL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nparallel", + specials={ "char", 0x2225, 0x0338 }, + unicodeslot=0x2226, + }, + [0x2227]={ + adobename="logicaland", + category="sm", + cjkwd="a", + description="LOGICAL AND", + direction="on", + linebreak="ai", + mathspec={ + { class="binary", name="wedge" }, + { class="binary", name="land" }, + }, + unicodeslot=0x2227, + }, + [0x2228]={ + adobename="logicalor", + category="sm", + cjkwd="a", + description="LOGICAL OR", + direction="on", + linebreak="ai", + mathspec={ + { class="bin",name="vee" }, + { class="bin",name="lor" }, + }, + unicodeslot=0x2228, + }, + [0x2229]={ + adobename="intersection", + category="sm", + cjkwd="a", + description="INTERSECTION", + direction="on", + linebreak="ai", + mathclass="binary", + mathname="cap", + unicodeslot=0x2229, + }, + [0x222A]={ + adobename="union", + category="sm", + cjkwd="a", + description="UNION", + direction="on", + linebreak="ai", + mathclass="binary", + mathname="cup", + unicodeslot=0x222A, + }, + [0x222B]={ + adobename="integral", + category="sm", + cjkwd="a", + description="INTEGRAL", + direction="on", + linebreak="ai", + mathspec={ + { class="nothing", name="intop" }, + { class="limop" , name="int" }, + }, + unicodeslot=0x222B, + }, + [0x222C]={ + category="sm", + cjkwd="a", + description="DOUBLE INTEGRAL", + direction="on", + linebreak="ai", + specials={ "compat", 0x222B, 0x222B }, + mathspec={ + { class="nothing", name="iintop" }, + { class="limop" , name="iint" }, + }, + unicodeslot=0x222C, + }, + [0x222D]={ + category="sm", + description="TRIPLE INTEGRAL", + direction="on", + linebreak="al", + specials={ "compat", 0x222B, 0x222B, 0x222B }, + mathspec={ + { class="nothing", name="iiintop" }, + { class="limop" , name="iiint" }, + }, + unicodeslot=0x222D, + }, + [0x222E]={ + category="sm", + cjkwd="a", + description="CONTOUR INTEGRAL", + direction="on", + linebreak="ai", + mathclass="limop", + mathname="oint", + unicodeslot=0x222E, + }, + [0x222F]={ + category="sm", + description="SURFACE INTEGRAL", + direction="on", + linebreak="al", + mathclass="limop", + mathname="oiint", + specials={ "compat", 0x222E, 0x222E }, + unicodeslot=0x222F, + }, + [0x2230]={ + category="sm", + description="VOLUME INTEGRAL", + direction="on", + linebreak="al", + mathclass="limop", + mathname="oiiint", + specials={ "compat", 0x222E, 0x222E, 0x222E }, + unicodeslot=0x2230, + }, + [0x2231]={ + category="sm", + description="CLOCKWISE INTEGRAL", + direction="on", + linebreak="al", + mathclass="limop", + mathname="intclockwise", + unicodeslot=0x2231, + }, + [0x2232]={ + category="sm", + description="CLOCKWISE CONTOUR INTEGRAL", + direction="on", + linebreak="al", + mathclass="limop", + mathname="ointclockwise", + unicodeslot=0x2232, + }, + [0x2233]={ + category="sm", + description="ANTICLOCKWISE CONTOUR INTEGRAL", + direction="on", + linebreak="al", + mathclass="limop", + mathname="ointctrclockwise", + unicodeslot=0x2233, + }, + [0x2234]={ + adobename="therefore", + category="sm", + cjkwd="a", + description="THEREFORE", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="therefore", + unicodeslot=0x2234, + }, + [0x2235]={ + category="sm", + cjkwd="a", + description="BECAUSE", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="because", + unicodeslot=0x2235, + }, + [0x2236]={ + category="sm", + cjkwd="a", + description="RATIO", + direction="on", + linebreak="ai", + mathclass="punctuation", + mathname="colon", + unicodeslot=0x2236, + }, + [0x2237]={ + category="sm", + cjkwd="a", + description="PROPORTION", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="squaredots", + unicodeslot=0x2237, + }, + [0x2238]={ + category="sm", + description="DOT MINUS", + direction="on", + linebreak="al", + mathclass="binary", + mathname="dotminus", + unicodeslot=0x2238, + }, + [0x2239]={ + category="sm", + description="EXCESS", + direction="on", + linebreak="al", + mathclass="relation", + mathname="minuscolon", + unicodeslot=0x2239, + }, + [0x223A]={ + category="sm", + description="GEOMETRIC PROPORTION", + direction="on", + linebreak="al", + unicodeslot=0x223A, + }, + [0x223B]={ + category="sm", + description="HOMOTHETIC", + direction="on", + linebreak="al", + unicodeslot=0x223B, + }, + [0x223C]={ + adobename="similar", + category="sm", + cjkwd="a", + description="TILDE OPERATOR", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="sim", + mirror=0x223D, + unicodeslot=0x223C, + }, + [0x223D]={ + category="sm", + cjkwd="a", + description="REVERSED TILDE", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="backsim", + mirror=0x223C, + unicodeslot=0x223D, + }, + [0x223E]={ + category="sm", + description="INVERTED LAZY S", + direction="on", + linebreak="al", + unicodeslot=0x223E, + }, + [0x223F]={ + category="sm", + description="SINE WAVE", + direction="on", + linebreak="al", + unicodeslot=0x223F, + }, + [0x2240]={ + category="sm", + description="WREATH PRODUCT", + direction="on", + linebreak="al", + mathclass="binary", + mathname="wr", + unicodeslot=0x2240, + }, + [0x2241]={ + category="sm", + description="NOT TILDE", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nsim", + specials={ "char", 0x223C, 0x0338 }, + unicodeslot=0x2241, + }, + [0x2242]={ + category="sm", + description="MINUS TILDE", + direction="on", + linebreak="al", + mathclass="relation", + mathname="eqsim", + unicodeslot=0x2242, + }, + [0x2243]={ + category="sm", + description="ASYMPTOTICALLY EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="simeq", + mirror=0x22CD, + unicodeslot=0x2243, + }, + [0x2244]={ + category="sm", + description="NOT ASYMPTOTICALLY EQUAL TO", + direction="on", + linebreak="al", + specials={ "char", 0x2243, 0x0338 }, + mathclass="relation", + mathname="nsimeq", + unicodeslot=0x2244, + }, + [0x2245]={ + adobename="congruent", + category="sm", + description="APPROXIMATELY EQUAL TO", + direction="on", + linebreak="al", + mathspec={ + { class="relation", name="approxEq"}, + { class="relation", name="cong"}, + }, + unicodeslot=0x2245, + }, + [0x2246]={ + category="sm", + description="APPROXIMATELY BUT NOT ACTUALLY EQUAL TO", + direction="on", + linebreak="al", + mathspec={ + { class="relation", name="napproxEq"}, + { class="relation", name="ncong"}, + }, + unicodeslot=0x2246, + }, + [0x2247]={ + category="sm", + description="NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="approxnEq", + specials={ "char", 0x2245, 0x0338 }, + unicodeslot=0x2247, + }, + [0x2248]={ + adobename="approxequal", + category="sm", + cjkwd="a", + description="ALMOST EQUAL TO", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="approx", + unicodeslot=0x2248, + }, + [0x2249]={ + category="sm", + description="NOT ALMOST EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="napprox", + specials={ "char", 0x2248, 0x0338 }, + unicodeslot=0x2249, + }, + [0x224A]={ + category="sm", + description="ALMOST EQUAL OR EQUAL TO", + direction="on", + mathclass="relation", + mathname="approxeq", + linebreak="al", + unicodeslot=0x224A, + }, + [0x224B]={ + category="sm", + description="TRIPLE TILDE", + direction="on", + linebreak="al", + unicodeslot=0x224B, + }, + [0x224C]={ + category="sm", + cjkwd="a", + description="ALL EQUAL TO", + direction="on", + linebreak="ai", + mathclass="relation", + unicodeslot=0x224C, + }, + [0x224D]={ + category="sm", + description="EQUIVALENT TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="asymp", + unicodeslot=0x224D, + }, + [0x224E]={ + category="sm", + description="GEOMETRICALLY EQUIVALENT TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="Bumpeq", + unicodeslot=0x224E, + }, + [0x224F]={ + category="sm", + description="DIFFERENCE BETWEEN", + direction="on", + linebreak="al", + unicodeslot=0x224F, + }, + [0x2250]={ + category="sm", + description="APPROACHES THE LIMIT", + direction="on", + linebreak="al", + unicodeslot=0x2250, + }, + [0x2251]={ + category="sm", + description="GEOMETRICALLY EQUAL TO", + direction="on", + linebreak="al", + mathspec={ + { class="relation", name="doteqdot" }, + { class="relation", name="Doteq" }, + }, + unicodeslot=0x2251, + }, + [0x2252]={ + category="sm", + cjkwd="a", + description="APPROXIMATELY EQUAL TO OR THE IMAGE OF", + direction="on", + linebreak="ai", + mirror=0x2253, + mathclass="relation", + mathname="fallingdotseq", + unicodeslot=0x2252, + }, + [0x2253]={ + category="sm", + description="IMAGE OF OR APPROXIMATELY EQUAL TO", + direction="on", + linebreak="al", + mirror=0x2252, + mathclass="relation", + mathname="risingdotseq", + unicodeslot=0x2253, + }, + [0x2254]={ + category="sm", + description="COLON EQUALS", + direction="on", + linebreak="al", + mirror=0x2255, + mathclass="relation", + mathname="colonequals", + unicodeslot=0x2254, + }, + [0x2255]={ + category="sm", + description="EQUALS COLON", + direction="on", + linebreak="al", + mirror=0x2254, + mathclass="relation", + mathname="equalscolon", + unicodeslot=0x2255, + }, + [0x2256]={ + category="sm", + description="RING IN EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="eqcirc", + unicodeslot=0x2256, + }, + [0x2257]={ + category="sm", + description="RING EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="circeq", + unicodeslot=0x2257, + }, + [0x2258]={ + category="sm", + description="CORRESPONDS TO", + direction="on", + linebreak="al", + unicodeslot=0x2258, + }, + [0x2259]={ + category="sm", + description="ESTIMATES", + direction="on", + fallback=[[\buildrel\wedge\over=]], + linebreak="al", + unicodeslot=0x2259, + mathclass="relation", + mathname="wedgeeq", + }, + [0x225A]={ + category="sm", + description="EQUIANGULAR TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="veeeq", + unicodeslot=0x225A, + }, + [0x225B]={ + category="sm", + description="STAR EQUALS", + direction="on", + linebreak="al", + mathclass="relation", + mathname="stareq", + unicodeslot=0x225B, + }, + [0x225C]={ + category="sm", + description="DELTA EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="triangleq", + unicodeslot=0x225C, + }, + [0x225D]={ + category="sm", + description="EQUAL TO BY DEFINITION", + direction="on", + linebreak="al", + mathclass="relation", + mathname="definedeq", + unicodeslot=0x225D, + }, + [0x225E]={ + category="sm", + description="MEASURED BY", + direction="on", + linebreak="al", + mathclass="relation", + mathname="measuredeq", + unicodeslot=0x225E, + }, + [0x225F]={ + category="sm", + description="QUESTIONED EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="questionedeq", + unicodeslot=0x225F, + }, + [0x2260]={ + adobename="notequal", + category="sm", + cjkwd="a", + description="NOT EQUAL TO", + direction="on", + linebreak="ai", + mathspec={ + { class="relation", name="neq" }, + { class="relation", name="ne" }, + }, + specials={ "char", 0x003D, 0x0338 }, + unicodeslot=0x2260, + }, + [0x2261]={ + adobename="equivalence", + category="sm", + cjkwd="a", + description="IDENTICAL TO", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="equiv", + unicodeslot=0x2261, + }, + [0x2262]={ + category="sm", + description="NOT IDENTICAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nequiv", + specials={ "char", 0x2261, 0x0338 }, + unicodeslot=0x2262, + }, + [0x2263]={ + category="sm", + description="STRICTLY EQUIVALENT TO", + direction="on", + linebreak="al", + unicodeslot=0x2263, + }, + [0x2264]={ + adobename="lessequal", + category="sm", + cjkwd="a", + description="LESS-THAN OR EQUAL TO", + direction="on", + linebreak="ai", + mathspec={ + { class="relation", name="leq" }, + { class="relation", name="le" }, + }, + mirror=0x2265, + unicodeslot=0x2264, + }, + [0x2265]={ + adobename="greaterequal", + category="sm", + cjkwd="a", + description="GREATER-THAN OR EQUAL TO", + direction="on", + linebreak="ai", + mathspec={ + { class="relation", name="geq" }, + { class="relation", name="ge" }, + }, + mirror=0x2264, + unicodeslot=0x2265, + }, + [0x2266]={ + category="sm", + cjkwd="a", + description="LESS-THAN OVER EQUAL TO", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="leqq", + mirror=0x2267, + unicodeslot=0x2266, + }, + [0x2267]={ + category="sm", + cjkwd="a", + description="GREATER-THAN OVER EQUAL TO", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="geqq", + mirror=0x2266, + unicodeslot=0x2267, + }, + [0x2268]={ + category="sm", + description="LESS-THAN BUT NOT EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="lneqq", + mirror=0x2269, + unicodeslot=0x2268, + }, + [0x2269]={ + category="sm", + description="GREATER-THAN BUT NOT EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="gneqq", + mirror=0x2268, + unicodeslot=0x2269, + }, + [0x226A]={ + category="sm", + cjkwd="a", + description="MUCH LESS-THAN", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="ll", + mirror=0x226B, + unicodeslot=0x226A, + }, + [0x226B]={ + category="sm", + cjkwd="a", + description="MUCH GREATER-THAN", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="gg", + mirror=0x226A, + unicodeslot=0x226B, + }, + [0x226C]={ + category="sm", + description="BETWEEN", + direction="on", + linebreak="al", + mathclass="relation", + mathname="between", + unicodeslot=0x226C, + }, + [0x226D]={ + category="sm", + description="NOT EQUIVALENT TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nasymp", + specials={ "char", 0x224D, 0x0338 }, + unicodeslot=0x226D, + }, + [0x226E]={ + category="sm", + cjkwd="a", + description="NOT LESS-THAN", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="nless", + mirror=0x226F, + specials={ "char", 0x003C, 0x0338 }, + unicodeslot=0x226E, + }, + [0x226F]={ + category="sm", + cjkwd="a", + description="NOT GREATER-THAN", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="ngtr", + mirror=0x226E, + specials={ "char", 0x003E, 0x0338 }, + unicodeslot=0x226F, + }, + [0x2270]={ + category="sm", + description="NEITHER LESS-THAN NOR EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nleq", + mirror=0x2271, + specials={ "char", 0x2264, 0x0338 }, + unicodeslot=0x2270, + }, + [0x2271]={ + category="sm", + description="NEITHER GREATER-THAN NOR EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="ngeq", + mirror=0x2270, + specials={ "char", 0x2265, 0x0338 }, + unicodeslot=0x2271, + }, + [0x2272]={ + category="sm", + description="LESS-THAN OR EQUIVALENT TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="lesssim", + mirror=0x2273, + unicodeslot=0x2272, + }, + [0x2273]={ + category="sm", + description="GREATER-THAN OR EQUIVALENT TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="gtrsim", + mirror=0x2272, + unicodeslot=0x2273, + }, + [0x2274]={ + category="sm", + description="NEITHER LESS-THAN NOR EQUIVALENT TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nlesssim", + mirror=0x2275, + specials={ "char", 0x2272, 0x0338 }, + unicodeslot=0x2274, + }, + [0x2275]={ + category="sm", + description="NEITHER GREATER-THAN NOR EQUIVALENT TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="ngtrsim", + mirror=0x2274, + specials={ "char", 0x2273, 0x0338 }, + unicodeslot=0x2275, + }, + [0x2276]={ + category="sm", + description="LESS-THAN OR GREATER-THAN", + direction="on", + linebreak="al", + mathclass="relation", + mathname="lessgtr", + mirror=0x2277, + unicodeslot=0x2276, + }, + [0x2277]={ + category="sm", + description="GREATER-THAN OR LESS-THAN", + direction="on", + linebreak="al", + mathclass="relation", + mathname="gtrless", + mirror=0x2276, + unicodeslot=0x2277, + }, + [0x2278]={ + category="sm", + description="NEITHER LESS-THAN NOR GREATER-THAN", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nlessgtr", + mirror=0x2279, + specials={ "char", 0x2276, 0x0338 }, + unicodeslot=0x2278, + }, + [0x2279]={ + category="sm", + description="NEITHER GREATER-THAN NOR LESS-THAN", + direction="on", + linebreak="al", + mathclass="relation", + mathname="ngtrless", + mirror=0x2278, + specials={ "char", 0x2277, 0x0338 }, + unicodeslot=0x2279, + }, + [0x227A]={ + category="sm", + description="PRECEDES", + direction="on", + linebreak="al", + mathclass="relation", + mathname="prec", + mirror=0x227B, + unicodeslot=0x227A, + }, + [0x227B]={ + category="sm", + description="SUCCEEDS", + direction="on", + linebreak="al", + mathclass="relation", + mathname="succ", + mirror=0x227A, + unicodeslot=0x227B, + }, + [0x227C]={ + category="sm", + description="PRECEDES OR EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="preccurlyeq", + mirror=0x227D, + unicodeslot=0x227C, + }, + [0x227D]={ + category="sm", + description="SUCCEEDS OR EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="succcurlyeq", + mirror=0x227C, + unicodeslot=0x227D, + }, + [0x227E]={ + category="sm", + description="PRECEDES OR EQUIVALENT TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="precsim", + mirror=0x227F, + unicodeslot=0x227E, + }, + [0x227F]={ + category="sm", + description="SUCCEEDS OR EQUIVALENT TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="succsim", + mirror=0x227E, + unicodeslot=0x227F, + }, + [0x2280]={ + category="sm", + description="DOES NOT PRECEDE", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nprec", + mirror=0x2281, + specials={ "char", 0x227A, 0x0338 }, + unicodeslot=0x2280, + }, + [0x2281]={ + category="sm", + description="DOES NOT SUCCEED", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nsucc", + mirror=0x2280, + specials={ "char", 0x227B, 0x0338 }, + unicodeslot=0x2281, + }, + [0x2282]={ + adobename="propersubset", + category="sm", + cjkwd="a", + description="SUBSET OF", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="subset", -- Subset + mirror=0x2283, + unicodeslot=0x2282, + }, + [0x2283]={ + adobename="propersuperset", + category="sm", + cjkwd="a", + description="SUPERSET OF", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="supset", + mirror=0x2282, + unicodeslot=0x2283, + }, + [0x2284]={ + adobename="notsubset", + category="sm", + description="NOT A SUBSET OF", + direction="on", + fallback=[[\not\subset]], + mathclass="relation", + mathname="nsubset", + linebreak="al", + mirror=0x2285, + specials={ "char", 0x2282, 0x0338 }, + unicodeslot=0x2284, + }, + [0x2285]={ + category="sm", + description="NOT A SUPERSET OF", + direction="on", + fallback=[[\not\supset]], + linebreak="al", + mathclass="relation", + mathname="nsupset", + mirror=0x2284, + specials={ "char", 0x2283, 0x0338 }, + unicodeslot=0x2285, + }, + [0x2286]={ + adobename="reflexsubset", + category="sm", + cjkwd="a", + description="SUBSET OF OR EQUAL TO", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="subseteq", + mirror=0x2287, + unicodeslot=0x2286, + }, + [0x2287]={ + adobename="reflexsuperset", + category="sm", + cjkwd="a", + description="SUPERSET OF OR EQUAL TO", + direction="on", + linebreak="ai", + mathclass="relation", + mathname="supseteq", + mirror=0x2286, + unicodeslot=0x2287, + }, + [0x2288]={ + category="sm", + description="NEITHER A SUBSET OF NOR EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nsubseteq", + mirror=0x2289, + specials={ "char", 0x2286, 0x0338 }, + unicodeslot=0x2288, + }, + [0x2289]={ + category="sm", + description="NEITHER A SUPERSET OF NOR EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nsupseteq", + mirror=0x2288, + specials={ "char", 0x2287, 0x0338 }, + unicodeslot=0x2289, + }, + [0x228A]={ + category="sm", + description="SUBSET OF WITH NOT EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="subsetneq", + mirror=0x228B, + unicodeslot=0x228A, + }, + [0x228B]={ + category="sm", + description="SUPERSET OF WITH NOT EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="supsetneq", + mirror=0x228A, + unicodeslot=0x228B, + }, + [0x228C]={ + category="sm", + description="MULTISET", + direction="on", + linebreak="al", + unicodeslot=0x228C, + }, + [0x228D]={ + category="sm", + description="MULTISET MULTIPLICATION", + direction="on", + linebreak="al", + unicodeslot=0x228D, + }, + [0x228E]={ + category="sm", + description="MULTISET UNION", + direction="on", + linebreak="al", + mathclass="binary", + mathname="uplus", + unicodeslot=0x228E, + }, + [0x228F]={ + category="sm", + description="SQUARE IMAGE OF", + direction="on", + linebreak="al", + mathclass="relation", + mathname="sqsubset", + mirror=0x2290, + unicodeslot=0x228F, + }, + [0x2290]={ + category="sm", + description="SQUARE ORIGINAL OF", + direction="on", + linebreak="al", + mathclass="relation", + mathname="sqsupset", + mirror=0x228F, + unicodeslot=0x2290, + }, + [0x2291]={ + category="sm", + description="SQUARE IMAGE OF OR EQUAL TO", + direction="on", + linebreak="al", + mathclass="binary", + mathname="sqsubseteq", + mirror=0x2292, + unicodeslot=0x2291, + }, + [0x2292]={ + category="sm", + description="SQUARE ORIGINAL OF OR EQUAL TO", + direction="on", + linebreak="al", + mathclass="binary", + mathname="sqsupseteq", + mirror=0x2291, + unicodeslot=0x2292, + }, + [0x2293]={ + category="sm", + description="SQUARE CAP", + direction="on", + linebreak="al", + mathclass="binary", + mathname="sqcap", + unicodeslot=0x2293, + }, + [0x2294]={ + category="sm", + description="SQUARE CUP", + direction="on", + linebreak="al", + mathclass="binary", + mathname="sqcup", + unicodeslot=0x2294, + }, + [0x2295]={ + adobename="circleplus", + category="sm", + cjkwd="a", + description="CIRCLED PLUS", + direction="on", + linebreak="ai", + mathclass="binary", + mathname="oplus", + unicodeslot=0x2295, + }, + [0x2296]={ + category="sm", + description="CIRCLED MINUS", + direction="on", + linebreak="al", + mathclass="binary", + mathname="ominus", + unicodeslot=0x2296, + }, + [0x2297]={ + adobename="circlemultiply", + category="sm", + description="CIRCLED TIMES", + direction="on", + linebreak="al", + mathclass="binary", + mathname="otimes", + unicodeslot=0x2297, + }, + [0x2298]={ + category="sm", + description="CIRCLED DIVISION SLASH", + direction="on", + linebreak="al", + mathclass="binary", + mathname="oslash", + mirror=0x29B8, + unicodeslot=0x2298, + }, + [0x2299]={ + category="sm", + cjkwd="a", + description="CIRCLED DOT OPERATOR", + direction="on", + linebreak="ai", + mathclass="binary", + mathname="odot", + unicodeslot=0x2299, + }, + [0x229A]={ + category="sm", + description="CIRCLED RING OPERATOR", + direction="on", + linebreak="al", + mathclass="binary", + mathname="circledcirc", + unicodeslot=0x229A, + }, + [0x229B]={ + category="sm", + description="CIRCLED ASTERISK OPERATOR", + direction="on", + linebreak="al", + mathclass="binary", + mathname="circledast", + unicodeslot=0x229B, + }, + [0x229C]={ + category="sm", + description="CIRCLED EQUALS", + direction="on", + linebreak="al", + mathclass="binary", + mathname="circledequals", + unicodeslot=0x229C, + }, + [0x229D]={ + category="sm", + description="CIRCLED DASH", + direction="on", + linebreak="al", + mathclass="binary", + mathname="circleddash", + unicodeslot=0x229D, + }, + [0x229E]={ + category="sm", + description="SQUARED PLUS", + direction="on", + linebreak="al", + mathclass="binary", + mathname="boxplus", + unicodeslot=0x229E, + }, + [0x229F]={ + category="sm", + description="SQUARED MINUS", + direction="on", + linebreak="al", + mathclass="binary", + mathname="boxminus", + unicodeslot=0x229F, + }, + [0x22A0]={ + category="sm", + description="SQUARED TIMES", + direction="on", + linebreak="al", + mathclass="binary", + mathname="boxtimes", + unicodeslot=0x22A0, + }, + [0x22A1]={ + category="sm", + description="SQUARED DOT OPERATOR", + direction="on", + linebreak="al", + mathclass="binary", + mathname="boxdot", + unicodeslot=0x22A1, + }, + [0x22A2]={ + category="sm", + description="RIGHT TACK", + direction="on", + linebreak="al", + mathclass="relation", + mathname="vdash", + mirror=0x22A3, + unicodeslot=0x22A2, + }, + [0x22A3]={ + category="sm", + description="LEFT TACK", + direction="on", + linebreak="al", + mathclass="relation", + mathname="dashv", + mirror=0x22A2, + unicodeslot=0x22A3, + }, + [0x22A4]={ + category="sm", + description="DOWN TACK", + direction="on", + linebreak="al", + mathclass="default", + mathname="top", + unicodeslot=0x22A4, + }, + [0x22A5]={ + adobename="perpendicular", + category="sm", + cjkwd="a", + description="UP TACK", + direction="on", + linebreak="ai", + mathspec={ + { class="default", name="bot" }, + { class="relation", name="perp" }, + }, + unicodeslot=0x22A5, + }, + [0x22A6]={ + category="sm", + description="ASSERTION", + direction="on", + linebreak="al", + mirror=0x2ADE, + unicodeslot=0x22A6, + }, + [0x22A7]={ + category="sm", + description="MODELS", + direction="on", + linebreak="al", + fallback=[[\mathrel|\joinrel=]], + mathclass="relation", + mathname="models", + unicodeslot=0x22A7, + }, + [0x22A8]={ + category="sm", + description="TRUE", + direction="on", + linebreak="al", + mirror=0x2AE4, + mathclass="relation", + mathname="vDash", + unicodeslot=0x22A8, + }, + [0x22A9]={ + category="sm", + description="FORCES", + direction="on", + linebreak="al", + mirror=0x2AE3, + mathclass="relation", + mathname="Vdash", + unicodeslot=0x22A9, + }, + [0x22AA]={ + category="sm", + description="TRIPLE VERTICAL BAR RIGHT TURNSTILE", + direction="on", + linebreak="al", + mathclass="relation", + mathname="Vvdash", + unicodeslot=0x22AA, + }, + [0x22AB]={ + category="sm", + description="DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE", + direction="on", + linebreak="al", + mirror=0x2AE5, + mathclass="relation", + mathname="VDash", + unicodeslot=0x22AB, + }, + [0x22AC]={ + category="sm", + description="DOES NOT PROVE", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nvdash", + specials={ "char", 0x22A2, 0x0338 }, + unicodeslot=0x22AC, + }, + [0x22AD]={ + category="sm", + description="NOT TRUE", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nvDash", + specials={ "char", 0x22A8, 0x0338 }, + unicodeslot=0x22AD, + }, + [0x22AE]={ + category="sm", + description="DOES NOT FORCE", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nVdash", + specials={ "char", 0x22A9, 0x0338 }, + unicodeslot=0x22AE, + }, + [0x22AF]={ + category="sm", + description="NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nVDash", + specials={ "char", 0x22AB, 0x0338 }, + unicodeslot=0x22AF, + }, + [0x22B0]={ + category="sm", + description="PRECEDES UNDER RELATION", + direction="on", + linebreak="al", + mirror=0x22B1, + unicodeslot=0x22B0, + }, + [0x22B1]={ + category="sm", + description="SUCCEEDS UNDER RELATION", + direction="on", + linebreak="al", + mirror=0x22B0, + unicodeslot=0x22B1, + }, + [0x22B2]={ + category="sm", + description="NORMAL SUBGROUP OF", + direction="on", + linebreak="al", + mathclass="bin", + mathname="triangleleft", + mirror=0x22B3, + unicodeslot=0x22B2, + }, + [0x22B3]={ + category="sm", + description="CONTAINS AS NORMAL SUBGROUP", + direction="on", + linebreak="al", + mathclass="bin", + mathname="triangleright", + mirror=0x22B2, + unicodeslot=0x22B3, + }, + [0x22B4]={ + category="sm", + description="NORMAL SUBGROUP OF OR EQUAL TO", + direction="on", + linebreak="al", + mirror=0x22B5, + unicodeslot=0x22B4, + }, + [0x22B5]={ + category="sm", + description="CONTAINS AS NORMAL SUBGROUP OR EQUAL TO", + direction="on", + linebreak="al", + mirror=0x22B4, + unicodeslot=0x22B5, + }, + [0x22B6]={ + category="sm", + description="ORIGINAL OF", + direction="on", + linebreak="al", + mirror=0x22B7, + unicodeslot=0x22B6, + }, + [0x22B7]={ + category="sm", + description="IMAGE OF", + direction="on", + linebreak="al", + mirror=0x22B6, + unicodeslot=0x22B7, + }, + [0x22B8]={ + category="sm", + description="MULTIMAP", + direction="on", + linebreak="al", + mathclass="relation", + mathname="multimap", + unicodeslot=0x22B8, + }, + [0x22B9]={ + category="sm", + description="HERMITIAN CONJUGATE MATRIX", + direction="on", + linebreak="al", + unicodeslot=0x22B9, + }, + [0x22BA]={ + category="sm", + description="INTERCALATE", + direction="on", + linebreak="al", + mathclass="binary", + mathname="intercal", + unicodeslot=0x22BA, + }, + [0x22BB]={ + category="sm", + description="XOR", + direction="on", + linebreak="al", + mathclass="binary", + mathname="veebar", + unicodeslot=0x22BB, + }, + [0x22BC]={ + category="sm", + description="NAND", + direction="on", + linebreak="al", + mathclass="binary", + mathname="barwedge", + unicodeslot=0x22BC, + }, + [0x22BD]={ + category="sm", + description="NOR", + direction="on", + linebreak="al", + unicodeslot=0x22BD, + }, + [0x22BE]={ + category="sm", + description="RIGHT ANGLE WITH ARC", + direction="on", + linebreak="al", + unicodeslot=0x22BE, + }, + [0x22BF]={ + category="sm", + cjkwd="a", + description="RIGHT TRIANGLE", + direction="on", + linebreak="ai", + unicodeslot=0x22BF, + }, + [0x22C0]={ + category="sm", + description="N-ARY LOGICAL AND", + direction="on", + linebreak="al", + mathclass="limop", + mathname="bigwedge", + unicodeslot=0x22C0, + }, + [0x22C1]={ + category="sm", + description="N-ARY LOGICAL OR", + direction="on", + linebreak="al", + mathclass="limop", + mathname="bigvee", + unicodeslot=0x22C1, + }, + [0x22C2]={ + category="sm", + description="N-ARY INTERSECTION", + direction="on", + linebreak="al", + mathclass="limop", + mathname="bigcap", + unicodeslot=0x22C2, + }, + [0x22C3]={ + category="sm", + description="N-ARY UNION", + direction="on", + linebreak="al", + mathclass="limop", + mathname="bigcup", + unicodeslot=0x22C3, + }, + [0x22C4]={ + category="sm", + description="DIAMOND OPERATOR", + direction="on", + linebreak="al", + mathclass="binary", + mathname="diamond", + unicodeslot=0x22C4, + }, + [0x22C5]={ + adobename="dotmath", + category="sm", + description="DOT OPERATOR", + direction="on", + linebreak="al", + mathspec={ + { class="binary", name="cdot" }, + { class="punctuation", name="cdotp" }, + }, + unicodeslot=0x22C5, + }, + [0x22C6]={ + category="sm", + description="STAR OPERATOR", + direction="on", + linebreak="al", + mathclass="binary", + mathname="star", + unicodeslot=0x22C6, + }, + [0x22C7]={ + category="sm", + description="DIVISION TIMES", + direction="on", + linebreak="al", + mathclass="binary", + mathname="divideontimes", + unicodeslot=0x22C7, + }, + [0x22C8]={ + category="sm", + 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]={ + category="sm", + description="LEFT NORMAL FACTOR SEMIDIRECT PRODUCT", + direction="on", + linebreak="al", + mathclass="binary", + mathname="ltimes", + mirror=0x22CA, + unicodeslot=0x22C9, + }, + [0x22CA]={ + category="sm", + description="RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT", + direction="on", + linebreak="al", + mathclass="binary", + mathname="rtimes", + mirror=0x22C9, + unicodeslot=0x22CA, + }, + [0x22CB]={ + category="sm", + description="LEFT SEMIDIRECT PRODUCT", + direction="on", + linebreak="al", + mathclass="binary", + mathname="leftthreetimes", + mirror=0x22CC, + unicodeslot=0x22CB, + }, + [0x22CC]={ + category="sm", + description="RIGHT SEMIDIRECT PRODUCT", + direction="on", + linebreak="al", + mathclass="binary", + mathname="rightthreetimes", + mirror=0x22CB, + unicodeslot=0x22CC, + }, + [0x22CD]={ + category="sm", + description="REVERSED TILDE EQUALS", + direction="on", + linebreak="al", + mirror=0x2243, + unicodeslot=0x22CD, + }, + [0x22CE]={ + category="sm", + description="CURLY LOGICAL OR", + direction="on", + linebreak="al", + mathclass="binary", + mathname="curlyvee", + unicodeslot=0x22CE, + }, + [0x22CF]={ + category="sm", + description="CURLY LOGICAL AND", + direction="on", + linebreak="al", + mathclass="binary", + mathname="curlywedge", + unicodeslot=0x22CF, + }, + [0x22D0]={ + category="sm", + description="DOUBLE SUBSET", + direction="on", + linebreak="al", + mathclass="relation", + mathname="Subset", + mirror=0x22D1, + unicodeslot=0x22D0, + }, + [0x22D1]={ + category="sm", + description="DOUBLE SUPERSET", + direction="on", + linebreak="al", + mathclass="relation", + mathname="Supset", + mirror=0x22D0, + unicodeslot=0x22D1, + }, + [0x22D2]={ + category="sm", + description="DOUBLE INTERSECTION", + direction="on", + linebreak="al", + mathspec={ + { class="binary", name="Cap" }, + { class="binary", name="doublecap"}, + }, + unicodeslot=0x22D2, + }, + [0x22D3]={ + category="sm", + description="DOUBLE UNION", + direction="on", + linebreak="al", + mathspec={ + { class="binary", name="Cup" }, + { class="binary", name="doublecup"}, + }, + unicodeslot=0x22D3, + }, + [0x22D4]={ + category="sm", + description="PITCHFORK", + direction="on", + linebreak="al", + mathclass="relation", + mathname="pitchfork", + unicodeslot=0x22D4, + }, + [0x22D5]={ + category="sm", + description="EQUAL AND PARALLEL TO", + direction="on", + linebreak="al", + unicodeslot=0x22D5, + }, + [0x22D6]={ + category="sm", + description="LESS-THAN WITH DOT", + direction="on", + linebreak="al", + mathclass="binary", + mathname="lessdot", + mirror=0x22D7, + unicodeslot=0x22D6, + }, + [0x22D7]={ + category="sm", + description="GREATER-THAN WITH DOT", + direction="on", + linebreak="al", + mathclass="binary", + mathname="gtrdot", + mirror=0x22D6, + unicodeslot=0x22D7, + }, + [0x22D8]={ + category="sm", + description="VERY MUCH LESS-THAN", + direction="on", + linebreak="al", + mathspec={ + { class="relation", name="lll"}, + { class="relation", name="llless"}, + }, + mirror=0x22D9, + unicodeslot=0x22D8, + }, + [0x22D9]={ + category="sm", + description="VERY MUCH GREATER-THAN", + direction="on", + linebreak="al", + mathspec={ + { class="relation", name="ggg"}, + { class="relation", name="gggtr"}, + }, + mirror=0x22D8, + unicodeslot=0x22D9, + }, + [0x22DA]={ + category="sm", + description="LESS-THAN EQUAL TO OR GREATER-THAN", + direction="on", + linebreak="al", + mirror=0x22DB, + mathclass="relation", + mathname="lesseqgtr", + unicodeslot=0x22DA, + }, + [0x22DB]={ + category="sm", + description="GREATER-THAN EQUAL TO OR LESS-THAN", + direction="on", + linebreak="al", + mirror=0x22DA, + mathclass="relation", + mathname="gtreqless", + unicodeslot=0x22DB, + }, + [0x22DC]={ + category="sm", + description="EQUAL TO OR LESS-THAN", + direction="on", + linebreak="al", + mathclass="relation", + mathname="eqless", + mirror=0x22DD, + unicodeslot=0x22DC, + }, + [0x22DD]={ + category="sm", + description="EQUAL TO OR GREATER-THAN", + direction="on", + linebreak="al", + mathclass="relation", + mathname="eqgtr", + mirror=0x22DC, + unicodeslot=0x22DD, + }, + [0x22DE]={ + category="sm", + description="EQUAL TO OR PRECEDES", + direction="on", + linebreak="al", + mirror=0x22DF, + mathclass="relation", + mathname="curlyeqprec", + unicodeslot=0x22DE, + }, + [0x22DF]={ + category="sm", + description="EQUAL TO OR SUCCEEDS", + direction="on", + linebreak="al", + mirror=0x22DE, + mathclass="relation", + mathname="curlyeqsucc", + unicodeslot=0x22DF, + }, + [0x22E0]={ + category="sm", + description="DOES NOT PRECEDE OR EQUAL", + direction="on", + linebreak="al", + mirror=0x22E1, + mathclass="relation", + mathname="npreccurlyeq", + specials={ "char", 0x227C, 0x0338 }, + unicodeslot=0x22E0, + }, + [0x22E1]={ + category="sm", + description="DOES NOT SUCCEED OR EQUAL", + direction="on", + linebreak="al", + mirror=0x22E0, + mathclass="relation", + mathname="nsucccurlyeq", + specials={ "char", 0x227D, 0x0338 }, + unicodeslot=0x22E1, + }, + [0x22E2]={ + category="sm", + description="NOT SQUARE IMAGE OF OR EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nsqsubseteq", + mirror=0x22E3, + specials={ "char", 0x2291, 0x0338 }, + unicodeslot=0x22E2, + }, + [0x22E3]={ + category="sm", + description="NOT SQUARE ORIGINAL OF OR EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nsqsupseteq", + mirror=0x22E2, + specials={ "char", 0x2292, 0x0338 }, + unicodeslot=0x22E3, + }, + [0x22E4]={ + category="sm", + description="SQUARE IMAGE OF OR NOT EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="sqsubsetneq", + mirror=0x22E5, + unicodeslot=0x22E4, + }, + [0x22E5]={ + category="sm", + description="SQUARE ORIGINAL OF OR NOT EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="sqsupsetneq", + mirror=0x22E4, + unicodeslot=0x22E5, + }, + [0x22E6]={ + category="sm", + description="LESS-THAN BUT NOT EQUIVALENT TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="lnsim", + mirror=0x22E7, + unicodeslot=0x22E6, + }, + [0x22E7]={ + category="sm", + description="GREATER-THAN BUT NOT EQUIVALENT TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="gnsim", + mirror=0x22E6, + unicodeslot=0x22E7, + }, + [0x22E8]={ + category="sm", + description="PRECEDES BUT NOT EQUIVALENT TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="precnsim", + mirror=0x22E9, + unicodeslot=0x22E8, + }, + [0x22E9]={ + category="sm", + description="SUCCEEDS BUT NOT EQUIVALENT TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="succnsim", + mirror=0x22E8, + unicodeslot=0x22E9, + }, + [0x22EA]={ + category="sm", + description="NOT NORMAL SUBGROUP OF", + direction="on", + linebreak="al", + mathclass="relation", + mathname="ntriangleright", + mirror=0x22EB, + specials={ "char", 0x22B2, 0x0338 }, + unicodeslot=0x22EA, + }, + [0x22EB]={ + category="sm", + description="DOES NOT CONTAIN AS NORMAL SUBGROUP", + direction="on", + linebreak="al", + mathclass="relation", + mathname="ntriangleleft", + mirror=0x22EA, + specials={ "char", 0x22B3, 0x0338 }, + unicodeslot=0x22EB, + }, + [0x22EC]={ + category="sm", + description="NOT NORMAL SUBGROUP OF OR EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="ntrianglelefteq", + mirror=0x22ED, + specials={ "char", 0x22B4, 0x0338 }, + unicodeslot=0x22EC, + }, + [0x22ED]={ + category="sm", + 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, + }, + [0x22EE]={ + category="sm", + description="VERTICAL ELLIPSIS", + direction="on", + linebreak="al", + mathclass="inner", + mathname="vdots", + unicodeslot=0x22EE, + }, + [0x22EF]={ + category="sm", + description="MIDLINE HORIZONTAL ELLIPSIS", + direction="on", + linebreak="al", + mathclass="inner", + mathname="cdots", + unicodeslot=0x22EF, + }, + [0x22F0]={ + category="sm", + description="UP RIGHT DIAGONAL ELLIPSIS", + direction="on", + linebreak="al", + mathclass="inner", + mathname="udots", + mirror=0x22F1, + unicodeslot=0x22F0, + }, + [0x22F1]={ + category="sm", + description="DOWN RIGHT DIAGONAL ELLIPSIS", + direction="on", + linebreak="al", + mathclass="inner", + mathname="ddots", + mirror=0x22F0, + unicodeslot=0x22F1, + }, + [0x22F2]={ + category="sm", + description="ELEMENT OF WITH LONG HORIZONTAL STROKE", + direction="on", + linebreak="al", + mirror=0x22FA, + unicodeslot=0x22F2, + }, + [0x22F3]={ + category="sm", + description="ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE", + direction="on", + linebreak="al", + mirror=0x22FB, + unicodeslot=0x22F3, + }, + [0x22F4]={ + category="sm", + description="SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE", + direction="on", + linebreak="al", + mirror=0x22FC, + unicodeslot=0x22F4, + }, + [0x22F5]={ + category="sm", + description="ELEMENT OF WITH DOT ABOVE", + direction="on", + linebreak="al", + unicodeslot=0x22F5, + }, + [0x22F6]={ + category="sm", + description="ELEMENT OF WITH OVERBAR", + direction="on", + linebreak="al", + mirror=0x22FD, + unicodeslot=0x22F6, + }, + [0x22F7]={ + category="sm", + description="SMALL ELEMENT OF WITH OVERBAR", + direction="on", + linebreak="al", + mirror=0x22FE, + unicodeslot=0x22F7, + }, + [0x22F8]={ + category="sm", + description="ELEMENT OF WITH UNDERBAR", + direction="on", + linebreak="al", + unicodeslot=0x22F8, + }, + [0x22F9]={ + category="sm", + description="ELEMENT OF WITH TWO HORIZONTAL STROKES", + direction="on", + linebreak="al", + unicodeslot=0x22F9, + }, + [0x22FA]={ + category="sm", + description="CONTAINS WITH LONG HORIZONTAL STROKE", + direction="on", + linebreak="al", + mirror=0x22F2, + unicodeslot=0x22FA, + }, + [0x22FB]={ + category="sm", + description="CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE", + direction="on", + linebreak="al", + mirror=0x22F3, + unicodeslot=0x22FB, + }, + [0x22FC]={ + category="sm", + description="SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE", + direction="on", + linebreak="al", + mirror=0x22F4, + unicodeslot=0x22FC, + }, + [0x22FD]={ + category="sm", + description="CONTAINS WITH OVERBAR", + direction="on", + linebreak="al", + mirror=0x22F6, + unicodeslot=0x22FD, + }, + [0x22FE]={ + category="sm", + description="SMALL CONTAINS WITH OVERBAR", + direction="on", + linebreak="al", + mirror=0x22F7, + unicodeslot=0x22FE, + }, + [0x22FF]={ + category="sm", + description="Z NOTATION BAG MEMBERSHIP", + direction="on", + linebreak="al", + unicodeslot=0x22FF, + }, + [0x2300]={ + category="so", + description="DIAMETER SIGN", + direction="on", + linebreak="al", + mathclass="ord", + mathname="varnothing", + unicodeslot=0x2300, + }, + [0x2301]={ + category="so", + description="ELECTRIC ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2301, + }, + [0x2302]={ + adobename="house", + category="so", + description="HOUSE", + direction="on", + linebreak="al", + unicodeslot=0x2302, + }, + [0x2303]={ + category="so", + description="UP ARROWHEAD", + direction="on", + linebreak="al", + unicodeslot=0x2303, + }, + [0x2304]={ + category="so", + description="DOWN ARROWHEAD", + direction="on", + linebreak="al", + unicodeslot=0x2304, + }, + [0x2305]={ + category="so", + description="PROJECTIVE", + direction="on", + linebreak="al", + unicodeslot=0x2305, + }, + [0x2306]={ + category="so", + description="PERSPECTIVE", + direction="on", + linebreak="al", + unicodeslot=0x2306, + }, + [0x2307]={ + category="so", + description="WAVY LINE", + direction="on", + linebreak="al", + unicodeslot=0x2307, + }, + [0x2308]={ + category="sm", + description="LEFT CEILING", + direction="on", + linebreak="al", + mathclass="open", + mathname="lceil", + mirror=0x2309, + unicodeslot=0x2308, + }, + [0x2309]={ + category="sm", + description="RIGHT CEILING", + direction="on", + linebreak="al", + mathclass="close", + mathname="rceil", + mirror=0x2308, + unicodeslot=0x2309, + }, + [0x230A]={ + category="sm", + description="LEFT FLOOR", + direction="on", + linebreak="al", + mathclass="open", + mathname="lfloor", + mirror=0x230B, + unicodeslot=0x230A, + }, + [0x230B]={ + category="sm", + description="RIGHT FLOOR", + direction="on", + linebreak="al", + mathclass="close", + mathname="rfloor", + mirror=0x230A, + unicodeslot=0x230B, + }, + [0x230C]={ + category="so", + description="BOTTOM RIGHT CROP", + direction="on", + linebreak="al", + unicodeslot=0x230C, + }, + [0x230D]={ + category="so", + description="BOTTOM LEFT CROP", + direction="on", + linebreak="al", + unicodeslot=0x230D, + }, + [0x230E]={ + category="so", + description="TOP RIGHT CROP", + direction="on", + linebreak="al", + unicodeslot=0x230E, + }, + [0x230F]={ + category="so", + description="TOP LEFT CROP", + direction="on", + linebreak="al", + unicodeslot=0x230F, + }, + [0x2310]={ + adobename="revlogicalnot", + category="so", + description="REVERSED NOT SIGN", + direction="on", + linebreak="al", + unicodeslot=0x2310, + }, + [0x2311]={ + category="so", + description="SQUARE LOZENGE", + direction="on", + linebreak="al", + unicodeslot=0x2311, + }, + [0x2312]={ + category="so", + cjkwd="a", + description="ARC", + direction="on", + linebreak="ai", + unicodeslot=0x2312, + }, + [0x2313]={ + category="so", + description="SEGMENT", + direction="on", + linebreak="al", + unicodeslot=0x2313, + }, + [0x2314]={ + category="so", + description="SECTOR", + direction="on", + linebreak="al", + unicodeslot=0x2314, + }, + [0x2315]={ + category="so", + description="TELEPHONE RECORDER", + direction="on", + linebreak="al", + unicodeslot=0x2315, + }, + [0x2316]={ + category="so", + description="POSITION INDICATOR", + direction="on", + linebreak="al", + unicodeslot=0x2316, + }, + [0x2317]={ + category="so", + description="VIEWDATA SQUARE", + direction="on", + linebreak="al", + unicodeslot=0x2317, + }, + [0x2318]={ + category="so", + description="PLACE OF INTEREST SIGN", + direction="on", + linebreak="al", + unicodeslot=0x2318, + }, + [0x2319]={ + category="so", + description="TURNED NOT SIGN", + direction="on", + linebreak="al", + unicodeslot=0x2319, + }, + [0x231A]={ + category="so", + description="WATCH", + direction="on", + linebreak="al", + unicodeslot=0x231A, + }, + [0x231B]={ + category="so", + description="HOURGLASS", + direction="on", + linebreak="al", + unicodeslot=0x231B, + }, + [0x231C]={ + category="so", + description="TOP LEFT CORNER", + direction="on", + linebreak="al", + mathclass="open", + mathname="ulcorner", + unicodeslot=0x231C, + }, + [0x231D]={ + category="so", + description="TOP RIGHT CORNER", + direction="on", + linebreak="al", + mathclass="close", + mathname="urcorner", + unicodeslot=0x231D, + }, + [0x231E]={ + category="so", + description="BOTTOM LEFT CORNER", + direction="on", + linebreak="al", + mathclass="open", + mathname="llcorner", + unicodeslot=0x231E, + }, + [0x231F]={ + category="so", + description="BOTTOM RIGHT CORNER", + direction="on", + linebreak="al", + mathclass="close", + mathname="lrcorner", + unicodeslot=0x231F, + }, + [0x2320]={ + adobename="integraltp", + category="sm", + description="TOP HALF INTEGRAL", + direction="on", + linebreak="al", + unicodeslot=0x2320, + }, + [0x2321]={ + adobename="integralbt", + category="sm", + description="BOTTOM HALF INTEGRAL", + direction="on", + linebreak="al", + unicodeslot=0x2321, + }, + [0x2322]={ + category="so", + description="FROWN", + direction="on", + linebreak="al", + mathclass="relation", + mathname="frown", + unicodeslot=0x2322, + }, + [0x2323]={ + category="so", + description="SMILE", + direction="on", + linebreak="al", + mathclass="relation", + mathname="smile", + unicodeslot=0x2323, + }, + [0x2324]={ + category="so", + description="UP ARROWHEAD BETWEEN TWO HORIZONTAL BARS", + direction="on", + linebreak="al", + unicodeslot=0x2324, + }, + [0x2325]={ + category="so", + description="OPTION KEY", + direction="on", + linebreak="al", + unicodeslot=0x2325, + }, + [0x2326]={ + category="so", + description="ERASE TO THE RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x2326, + }, + [0x2327]={ + category="so", + description="X IN A RECTANGLE BOX", + direction="on", + linebreak="al", + unicodeslot=0x2327, + }, + [0x2328]={ + category="so", + description="KEYBOARD", + direction="on", + linebreak="al", + unicodeslot=0x2328, + }, + [0x2329]={ + adobename="angleleft", + category="ps", + cjkwd="w", + description="LEFT-POINTING ANGLE BRACKET", + direction="on", + linebreak="op", + mirror=0x232A, + specials={ "char", 0x3008 }, + unicodeslot=0x2329, + }, + [0x232A]={ + adobename="angleright", + category="pe", + cjkwd="w", + description="RIGHT-POINTING ANGLE BRACKET", + direction="on", + linebreak="cl", + mirror=0x2329, + specials={ "char", 0x3009 }, + unicodeslot=0x232A, + }, + [0x232B]={ + category="so", + description="ERASE TO THE LEFT", + direction="on", + linebreak="al", + unicodeslot=0x232B, + }, + [0x232C]={ + category="so", + description="BENZENE RING", + direction="on", + linebreak="al", + unicodeslot=0x232C, + }, + [0x232D]={ + category="so", + description="CYLINDRICITY", + direction="on", + linebreak="al", + unicodeslot=0x232D, + }, + [0x232E]={ + category="so", + description="ALL AROUND-PROFILE", + direction="on", + linebreak="al", + unicodeslot=0x232E, + }, + [0x232F]={ + category="so", + description="SYMMETRY", + direction="on", + linebreak="al", + unicodeslot=0x232F, + }, + [0x2330]={ + category="so", + description="TOTAL RUNOUT", + direction="on", + linebreak="al", + unicodeslot=0x2330, + }, + [0x2331]={ + category="so", + description="DIMENSION ORIGIN", + direction="on", + linebreak="al", + unicodeslot=0x2331, + }, + [0x2332]={ + category="so", + description="CONICAL TAPER", + direction="on", + linebreak="al", + unicodeslot=0x2332, + }, + [0x2333]={ + category="so", + description="SLOPE", + direction="on", + linebreak="al", + unicodeslot=0x2333, + }, + [0x2334]={ + category="so", + description="COUNTERBORE", + direction="on", + linebreak="al", + unicodeslot=0x2334, + }, + [0x2335]={ + category="so", + description="COUNTERSINK", + direction="on", + linebreak="al", + unicodeslot=0x2335, + }, + [0x2336]={ + category="so", + description="APL FUNCTIONAL SYMBOL I-BEAM", + direction="l", + linebreak="al", + unicodeslot=0x2336, + }, + [0x2337]={ + category="so", + description="APL FUNCTIONAL SYMBOL SQUISH QUAD", + direction="l", + linebreak="al", + unicodeslot=0x2337, + }, + [0x2338]={ + category="so", + description="APL FUNCTIONAL SYMBOL QUAD EQUAL", + direction="l", + linebreak="al", + unicodeslot=0x2338, + }, + [0x2339]={ + category="so", + description="APL FUNCTIONAL SYMBOL QUAD DIVIDE", + direction="l", + linebreak="al", + unicodeslot=0x2339, + }, + [0x233A]={ + category="so", + description="APL FUNCTIONAL SYMBOL QUAD DIAMOND", + direction="l", + linebreak="al", + unicodeslot=0x233A, + }, + [0x233B]={ + category="so", + description="APL FUNCTIONAL SYMBOL QUAD JOT", + direction="l", + linebreak="al", + unicodeslot=0x233B, + }, + [0x233C]={ + category="so", + description="APL FUNCTIONAL SYMBOL QUAD CIRCLE", + direction="l", + linebreak="al", + unicodeslot=0x233C, + }, + [0x233D]={ + category="so", + description="APL FUNCTIONAL SYMBOL CIRCLE STILE", + direction="l", + linebreak="al", + unicodeslot=0x233D, + }, + [0x233E]={ + category="so", + description="APL FUNCTIONAL SYMBOL CIRCLE JOT", + direction="l", + linebreak="al", + unicodeslot=0x233E, + }, + [0x233F]={ + category="so", + description="APL FUNCTIONAL SYMBOL SLASH BAR", + direction="l", + linebreak="al", + unicodeslot=0x233F, + }, + [0x2340]={ + category="so", + description="APL FUNCTIONAL SYMBOL BACKSLASH BAR", + direction="l", + linebreak="al", + unicodeslot=0x2340, + }, + [0x2341]={ + category="so", + description="APL FUNCTIONAL SYMBOL QUAD SLASH", + direction="l", + linebreak="al", + unicodeslot=0x2341, + }, + [0x2342]={ + category="so", + description="APL FUNCTIONAL SYMBOL QUAD BACKSLASH", + direction="l", + linebreak="al", + unicodeslot=0x2342, + }, + [0x2343]={ + category="so", + description="APL FUNCTIONAL SYMBOL QUAD LESS-THAN", + direction="l", + linebreak="al", + unicodeslot=0x2343, + }, + [0x2344]={ + category="so", + description="APL FUNCTIONAL SYMBOL QUAD GREATER-THAN", + direction="l", + linebreak="al", + unicodeslot=0x2344, + }, + [0x2345]={ + category="so", + description="APL FUNCTIONAL SYMBOL LEFTWARDS VANE", + direction="l", + linebreak="al", + unicodeslot=0x2345, + }, + [0x2346]={ + category="so", + description="APL FUNCTIONAL SYMBOL RIGHTWARDS VANE", + direction="l", + linebreak="al", + unicodeslot=0x2346, + }, + [0x2347]={ + category="so", + description="APL FUNCTIONAL SYMBOL QUAD LEFTWARDS ARROW", + direction="l", + linebreak="al", + unicodeslot=0x2347, + }, + [0x2348]={ + category="so", + description="APL FUNCTIONAL SYMBOL QUAD RIGHTWARDS ARROW", + direction="l", + linebreak="al", + unicodeslot=0x2348, + }, + [0x2349]={ + category="so", + description="APL FUNCTIONAL SYMBOL CIRCLE BACKSLASH", + direction="l", + linebreak="al", + unicodeslot=0x2349, + }, + [0x234A]={ + category="so", + description="APL FUNCTIONAL SYMBOL DOWN TACK UNDERBAR", + direction="l", + linebreak="al", + unicodeslot=0x234A, + }, + [0x234B]={ + category="so", + description="APL FUNCTIONAL SYMBOL DELTA STILE", + direction="l", + linebreak="al", + unicodeslot=0x234B, + }, + [0x234C]={ + category="so", + description="APL FUNCTIONAL SYMBOL QUAD DOWN CARET", + direction="l", + linebreak="al", + unicodeslot=0x234C, + }, + [0x234D]={ + category="so", + description="APL FUNCTIONAL SYMBOL QUAD DELTA", + direction="l", + linebreak="al", + unicodeslot=0x234D, + }, + [0x234E]={ + category="so", + description="APL FUNCTIONAL SYMBOL DOWN TACK JOT", + direction="l", + linebreak="al", + unicodeslot=0x234E, + }, + [0x234F]={ + category="so", + description="APL FUNCTIONAL SYMBOL UPWARDS VANE", + direction="l", + linebreak="al", + unicodeslot=0x234F, + }, + [0x2350]={ + category="so", + description="APL FUNCTIONAL SYMBOL QUAD UPWARDS ARROW", + direction="l", + linebreak="al", + unicodeslot=0x2350, + }, + [0x2351]={ + category="so", + description="APL FUNCTIONAL SYMBOL UP TACK OVERBAR", + direction="l", + linebreak="al", + unicodeslot=0x2351, + }, + [0x2352]={ + category="so", + description="APL FUNCTIONAL SYMBOL DEL STILE", + direction="l", + linebreak="al", + unicodeslot=0x2352, + }, + [0x2353]={ + category="so", + description="APL FUNCTIONAL SYMBOL QUAD UP CARET", + direction="l", + linebreak="al", + unicodeslot=0x2353, + }, + [0x2354]={ + category="so", + description="APL FUNCTIONAL SYMBOL QUAD DEL", + direction="l", + linebreak="al", + unicodeslot=0x2354, + }, + [0x2355]={ + category="so", + description="APL FUNCTIONAL SYMBOL UP TACK JOT", + direction="l", + linebreak="al", + unicodeslot=0x2355, + }, + [0x2356]={ + category="so", + description="APL FUNCTIONAL SYMBOL DOWNWARDS VANE", + direction="l", + linebreak="al", + unicodeslot=0x2356, + }, + [0x2357]={ + category="so", + description="APL FUNCTIONAL SYMBOL QUAD DOWNWARDS ARROW", + direction="l", + linebreak="al", + unicodeslot=0x2357, + }, + [0x2358]={ + category="so", + description="APL FUNCTIONAL SYMBOL QUOTE UNDERBAR", + direction="l", + linebreak="al", + unicodeslot=0x2358, + }, + [0x2359]={ + category="so", + description="APL FUNCTIONAL SYMBOL DELTA UNDERBAR", + direction="l", + linebreak="al", + unicodeslot=0x2359, + }, + [0x235A]={ + category="so", + description="APL FUNCTIONAL SYMBOL DIAMOND UNDERBAR", + direction="l", + linebreak="al", + unicodeslot=0x235A, + }, + [0x235B]={ + category="so", + description="APL FUNCTIONAL SYMBOL JOT UNDERBAR", + direction="l", + linebreak="al", + unicodeslot=0x235B, + }, + [0x235C]={ + category="so", + description="APL FUNCTIONAL SYMBOL CIRCLE UNDERBAR", + direction="l", + linebreak="al", + unicodeslot=0x235C, + }, + [0x235D]={ + category="so", + description="APL FUNCTIONAL SYMBOL UP SHOE JOT", + direction="l", + linebreak="al", + unicodeslot=0x235D, + }, + [0x235E]={ + category="so", + description="APL FUNCTIONAL SYMBOL QUOTE QUAD", + direction="l", + linebreak="al", + unicodeslot=0x235E, + }, + [0x235F]={ + category="so", + description="APL FUNCTIONAL SYMBOL CIRCLE STAR", + direction="l", + linebreak="al", + unicodeslot=0x235F, + }, + [0x2360]={ + category="so", + description="APL FUNCTIONAL SYMBOL QUAD COLON", + direction="l", + linebreak="al", + unicodeslot=0x2360, + }, + [0x2361]={ + category="so", + description="APL FUNCTIONAL SYMBOL UP TACK DIAERESIS", + direction="l", + linebreak="al", + unicodeslot=0x2361, + }, + [0x2362]={ + category="so", + description="APL FUNCTIONAL SYMBOL DEL DIAERESIS", + direction="l", + linebreak="al", + unicodeslot=0x2362, + }, + [0x2363]={ + category="so", + description="APL FUNCTIONAL SYMBOL STAR DIAERESIS", + direction="l", + linebreak="al", + unicodeslot=0x2363, + }, + [0x2364]={ + category="so", + description="APL FUNCTIONAL SYMBOL JOT DIAERESIS", + direction="l", + linebreak="al", + unicodeslot=0x2364, + }, + [0x2365]={ + category="so", + description="APL FUNCTIONAL SYMBOL CIRCLE DIAERESIS", + direction="l", + linebreak="al", + unicodeslot=0x2365, + }, + [0x2366]={ + category="so", + description="APL FUNCTIONAL SYMBOL DOWN SHOE STILE", + direction="l", + linebreak="al", + unicodeslot=0x2366, + }, + [0x2367]={ + category="so", + description="APL FUNCTIONAL SYMBOL LEFT SHOE STILE", + direction="l", + linebreak="al", + unicodeslot=0x2367, + }, + [0x2368]={ + category="so", + description="APL FUNCTIONAL SYMBOL TILDE DIAERESIS", + direction="l", + linebreak="al", + unicodeslot=0x2368, + }, + [0x2369]={ + category="so", + description="APL FUNCTIONAL SYMBOL GREATER-THAN DIAERESIS", + direction="l", + linebreak="al", + unicodeslot=0x2369, + }, + [0x236A]={ + category="so", + description="APL FUNCTIONAL SYMBOL COMMA BAR", + direction="l", + linebreak="al", + unicodeslot=0x236A, + }, + [0x236B]={ + category="so", + description="APL FUNCTIONAL SYMBOL DEL TILDE", + direction="l", + linebreak="al", + unicodeslot=0x236B, + }, + [0x236C]={ + category="so", + description="APL FUNCTIONAL SYMBOL ZILDE", + direction="l", + linebreak="al", + unicodeslot=0x236C, + }, + [0x236D]={ + category="so", + description="APL FUNCTIONAL SYMBOL STILE TILDE", + direction="l", + linebreak="al", + unicodeslot=0x236D, + }, + [0x236E]={ + category="so", + description="APL FUNCTIONAL SYMBOL SEMICOLON UNDERBAR", + direction="l", + linebreak="al", + unicodeslot=0x236E, + }, + [0x236F]={ + category="so", + description="APL FUNCTIONAL SYMBOL QUAD NOT EQUAL", + direction="l", + linebreak="al", + unicodeslot=0x236F, + }, + [0x2370]={ + category="so", + description="APL FUNCTIONAL SYMBOL QUAD QUESTION", + direction="l", + linebreak="al", + unicodeslot=0x2370, + }, + [0x2371]={ + category="so", + description="APL FUNCTIONAL SYMBOL DOWN CARET TILDE", + direction="l", + linebreak="al", + unicodeslot=0x2371, + }, + [0x2372]={ + category="so", + description="APL FUNCTIONAL SYMBOL UP CARET TILDE", + direction="l", + linebreak="al", + unicodeslot=0x2372, + }, + [0x2373]={ + category="so", + description="APL FUNCTIONAL SYMBOL IOTA", + direction="l", + linebreak="al", + unicodeslot=0x2373, + }, + [0x2374]={ + category="so", + description="APL FUNCTIONAL SYMBOL RHO", + direction="l", + linebreak="al", + unicodeslot=0x2374, + }, + [0x2375]={ + category="so", + description="APL FUNCTIONAL SYMBOL OMEGA", + direction="l", + linebreak="al", + unicodeslot=0x2375, + }, + [0x2376]={ + category="so", + description="APL FUNCTIONAL SYMBOL ALPHA UNDERBAR", + direction="l", + linebreak="al", + unicodeslot=0x2376, + }, + [0x2377]={ + category="so", + description="APL FUNCTIONAL SYMBOL EPSILON UNDERBAR", + direction="l", + linebreak="al", + unicodeslot=0x2377, + }, + [0x2378]={ + category="so", + description="APL FUNCTIONAL SYMBOL IOTA UNDERBAR", + direction="l", + linebreak="al", + unicodeslot=0x2378, + }, + [0x2379]={ + category="so", + description="APL FUNCTIONAL SYMBOL OMEGA UNDERBAR", + direction="l", + linebreak="al", + unicodeslot=0x2379, + }, + [0x237A]={ + category="so", + description="APL FUNCTIONAL SYMBOL ALPHA", + direction="l", + linebreak="al", + unicodeslot=0x237A, + }, + [0x237B]={ + category="so", + description="NOT CHECK MARK", + direction="on", + linebreak="al", + unicodeslot=0x237B, + }, + [0x237C]={ + category="sm", + description="RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW", + direction="on", + linebreak="al", + unicodeslot=0x237C, + }, + [0x237D]={ + category="so", + description="SHOULDERED OPEN BOX", + direction="on", + linebreak="al", + unicodeslot=0x237D, + }, + [0x237E]={ + category="so", + description="BELL SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x237E, + }, + [0x237F]={ + category="so", + description="VERTICAL LINE WITH MIDDLE DOT", + direction="on", + linebreak="al", + unicodeslot=0x237F, + }, + [0x2380]={ + category="so", + description="INSERTION SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x2380, + }, + [0x2381]={ + category="so", + description="CONTINUOUS UNDERLINE SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x2381, + }, + [0x2382]={ + category="so", + description="DISCONTINUOUS UNDERLINE SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x2382, + }, + [0x2383]={ + category="so", + description="EMPHASIS SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x2383, + }, + [0x2384]={ + category="so", + description="COMPOSITION SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x2384, + }, + [0x2385]={ + category="so", + description="WHITE SQUARE WITH CENTRE VERTICAL LINE", + direction="on", + linebreak="al", + unicodeslot=0x2385, + }, + [0x2386]={ + category="so", + description="ENTER SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x2386, + }, + [0x2387]={ + category="so", + description="ALTERNATIVE KEY SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x2387, + }, + [0x2388]={ + category="so", + description="HELM SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x2388, + }, + [0x2389]={ + category="so", + description="CIRCLED HORIZONTAL BAR WITH NOTCH", + direction="on", + linebreak="al", + unicodeslot=0x2389, + }, + [0x238A]={ + category="so", + description="CIRCLED TRIANGLE DOWN", + direction="on", + linebreak="al", + unicodeslot=0x238A, + }, + [0x238B]={ + category="so", + description="BROKEN CIRCLE WITH NORTHWEST ARROW", + direction="on", + linebreak="al", + unicodeslot=0x238B, + }, + [0x238C]={ + category="so", + description="UNDO SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x238C, + }, + [0x238D]={ + category="so", + description="MONOSTABLE SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x238D, + }, + [0x238E]={ + category="so", + description="HYSTERESIS SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x238E, + }, + [0x238F]={ + category="so", + description="OPEN-CIRCUIT-OUTPUT H-TYPE SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x238F, + }, + [0x2390]={ + category="so", + description="OPEN-CIRCUIT-OUTPUT L-TYPE SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x2390, + }, + [0x2391]={ + category="so", + description="PASSIVE-PULL-DOWN-OUTPUT SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x2391, + }, + [0x2392]={ + category="so", + description="PASSIVE-PULL-UP-OUTPUT SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x2392, + }, + [0x2393]={ + category="so", + description="DIRECT CURRENT SYMBOL FORM TWO", + direction="on", + linebreak="al", + unicodeslot=0x2393, + }, + [0x2394]={ + category="so", + description="SOFTWARE-FUNCTION SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x2394, + }, + [0x2395]={ + category="so", + description="APL FUNCTIONAL SYMBOL QUAD", + direction="l", + linebreak="al", + unicodeslot=0x2395, + }, + [0x2396]={ + category="so", + description="DECIMAL SEPARATOR KEY SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x2396, + }, + [0x2397]={ + category="so", + description="PREVIOUS PAGE", + direction="on", + linebreak="al", + unicodeslot=0x2397, + }, + [0x2398]={ + category="so", + description="NEXT PAGE", + direction="on", + linebreak="al", + unicodeslot=0x2398, + }, + [0x2399]={ + category="so", + description="PRINT SCREEN SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x2399, + }, + [0x239A]={ + category="so", + description="CLEAR SCREEN SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x239A, + }, + [0x239B]={ + category="sm", + description="LEFT PARENTHESIS UPPER HOOK", + direction="on", + linebreak="al", + unicodeslot=0x239B, + }, + [0x239C]={ + category="sm", + description="LEFT PARENTHESIS EXTENSION", + direction="on", + linebreak="al", + unicodeslot=0x239C, + }, + [0x239D]={ + category="sm", + description="LEFT PARENTHESIS LOWER HOOK", + direction="on", + linebreak="al", + unicodeslot=0x239D, + }, + [0x239E]={ + category="sm", + description="RIGHT PARENTHESIS UPPER HOOK", + direction="on", + linebreak="al", + unicodeslot=0x239E, + }, + [0x239F]={ + category="sm", + description="RIGHT PARENTHESIS EXTENSION", + direction="on", + linebreak="al", + unicodeslot=0x239F, + }, + [0x23A0]={ + category="sm", + description="RIGHT PARENTHESIS LOWER HOOK", + direction="on", + linebreak="al", + unicodeslot=0x23A0, + }, + [0x23A1]={ + category="sm", + description="LEFT SQUARE BRACKET UPPER CORNER", + direction="on", + linebreak="al", + unicodeslot=0x23A1, + }, + [0x23A2]={ + category="sm", + description="LEFT SQUARE BRACKET EXTENSION", + direction="on", + linebreak="al", + unicodeslot=0x23A2, + }, + [0x23A3]={ + category="sm", + description="LEFT SQUARE BRACKET LOWER CORNER", + direction="on", + linebreak="al", + unicodeslot=0x23A3, + }, + [0x23A4]={ + category="sm", + description="RIGHT SQUARE BRACKET UPPER CORNER", + direction="on", + linebreak="al", + unicodeslot=0x23A4, + }, + [0x23A5]={ + category="sm", + description="RIGHT SQUARE BRACKET EXTENSION", + direction="on", + linebreak="al", + unicodeslot=0x23A5, + }, + [0x23A6]={ + category="sm", + description="RIGHT SQUARE BRACKET LOWER CORNER", + direction="on", + linebreak="al", + unicodeslot=0x23A6, + }, + [0x23A7]={ + category="sm", + description="LEFT CURLY BRACKET UPPER HOOK", + direction="on", + linebreak="al", + unicodeslot=0x23A7, + }, + [0x23A8]={ + category="sm", + description="LEFT CURLY BRACKET MIDDLE PIECE", + direction="on", + linebreak="al", + unicodeslot=0x23A8, + }, + [0x23A9]={ + category="sm", + description="LEFT CURLY BRACKET LOWER HOOK", + direction="on", + linebreak="al", + unicodeslot=0x23A9, + }, + [0x23AA]={ + category="sm", + description="CURLY BRACKET EXTENSION", + direction="on", + linebreak="al", + unicodeslot=0x23AA, + }, + [0x23AB]={ + category="sm", + description="RIGHT CURLY BRACKET UPPER HOOK", + direction="on", + linebreak="al", + unicodeslot=0x23AB, + }, + [0x23AC]={ + category="sm", + description="RIGHT CURLY BRACKET MIDDLE PIECE", + direction="on", + linebreak="al", + unicodeslot=0x23AC, + }, + [0x23AD]={ + category="sm", + description="RIGHT CURLY BRACKET LOWER HOOK", + direction="on", + linebreak="al", + unicodeslot=0x23AD, + }, + [0x23AE]={ + category="sm", + description="INTEGRAL EXTENSION", + direction="on", + linebreak="al", + unicodeslot=0x23AE, + }, + [0x23AF]={ + category="sm", + description="HORIZONTAL LINE EXTENSION", + direction="on", + linebreak="al", + unicodeslot=0x23AF, + }, + [0x23B0]={ + category="sm", + description="UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION", + direction="on", + linebreak="al", + mathclass="open", + mathname="lmoustache", + unicodeslot=0x23B0, + }, + [0x23B1]={ + category="sm", + description="UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION", + direction="on", + linebreak="al", + mathclass="close", + mathname="rmoustache", + unicodeslot=0x23B1, + }, + [0x23B2]={ + category="sm", + description="SUMMATION TOP", + direction="on", + linebreak="al", + unicodeslot=0x23B2, + }, + [0x23B3]={ + category="sm", + description="SUMMATION BOTTOM", + direction="on", + linebreak="al", + unicodeslot=0x23B3, + }, + [0x23B4]={ + category="so", + description="TOP SQUARE BRACKET", + direction="on", + linebreak="al", + unicodeslot=0x23B4, + }, + [0x23B5]={ + category="so", + description="BOTTOM SQUARE BRACKET", + direction="on", + linebreak="al", + unicodeslot=0x23B5, + }, + [0x23B6]={ + category="so", + description="BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET", + direction="on", + linebreak="al", + unicodeslot=0x23B6, + }, + [0x23B7]={ + category="so", + description="RADICAL SYMBOL BOTTOM", + direction="on", + linebreak="al", + unicodeslot=0x23B7, + }, + [0x23B8]={ + category="so", + description="LEFT VERTICAL BOX LINE", + direction="on", + linebreak="al", + unicodeslot=0x23B8, + }, + [0x23B9]={ + category="so", + description="RIGHT VERTICAL BOX LINE", + direction="on", + linebreak="al", + unicodeslot=0x23B9, + }, + [0x23BA]={ + category="so", + description="HORIZONTAL SCAN LINE-0x0001", + direction="on", + linebreak="al", + unicodeslot=0x23BA, + }, + [0x23BB]={ + category="so", + description="HORIZONTAL SCAN LINE-0x0003", + direction="on", + linebreak="al", + unicodeslot=0x23BB, + }, + [0x23BC]={ + category="so", + description="HORIZONTAL SCAN LINE-0x0007", + direction="on", + linebreak="al", + unicodeslot=0x23BC, + }, + [0x23BD]={ + category="so", + description="HORIZONTAL SCAN LINE-0x0009", + direction="on", + linebreak="al", + unicodeslot=0x23BD, + }, + [0x23BE]={ + category="so", + description="DENTISTRY SYMBOL LIGHT VERTICAL AND TOP RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x23BE, + }, + [0x23BF]={ + category="so", + description="DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x23BF, + }, + [0x23C0]={ + category="so", + description="DENTISTRY SYMBOL LIGHT VERTICAL WITH CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x23C0, + }, + [0x23C1]={ + category="so", + description="DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x23C1, + }, + [0x23C2]={ + category="so", + description="DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x23C2, + }, + [0x23C3]={ + category="so", + description="DENTISTRY SYMBOL LIGHT VERTICAL WITH TRIANGLE", + direction="on", + linebreak="al", + unicodeslot=0x23C3, + }, + [0x23C4]={ + category="so", + description="DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH TRIANGLE", + direction="on", + linebreak="al", + unicodeslot=0x23C4, + }, + [0x23C5]={ + category="so", + description="DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH TRIANGLE", + direction="on", + linebreak="al", + unicodeslot=0x23C5, + }, + [0x23C6]={ + category="so", + description="DENTISTRY SYMBOL LIGHT VERTICAL AND WAVE", + direction="on", + linebreak="al", + unicodeslot=0x23C6, + }, + [0x23C7]={ + category="so", + description="DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH WAVE", + direction="on", + linebreak="al", + unicodeslot=0x23C7, + }, + [0x23C8]={ + category="so", + description="DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH WAVE", + direction="on", + linebreak="al", + unicodeslot=0x23C8, + }, + [0x23C9]={ + category="so", + description="DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL", + direction="on", + linebreak="al", + unicodeslot=0x23C9, + }, + [0x23CA]={ + category="so", + description="DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL", + direction="on", + linebreak="al", + unicodeslot=0x23CA, + }, + [0x23CB]={ + category="so", + description="DENTISTRY SYMBOL LIGHT VERTICAL AND TOP LEFT", + direction="on", + linebreak="al", + unicodeslot=0x23CB, + }, + [0x23CC]={ + category="so", + description="DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM LEFT", + direction="on", + linebreak="al", + unicodeslot=0x23CC, + }, + [0x23CD]={ + category="so", + description="SQUARE FOOT", + direction="on", + linebreak="al", + unicodeslot=0x23CD, + }, + [0x23CE]={ + category="so", + description="RETURN SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x23CE, + }, + [0x23CF]={ + category="so", + description="EJECT SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x23CF, + }, + [0x23D0]={ + category="so", + description="VERTICAL LINE EXTENSION", + direction="on", + linebreak="al", + unicodeslot=0x23D0, + }, + [0x23D1]={ + category="so", + description="METRICAL BREVE", + direction="on", + linebreak="al", + unicodeslot=0x23D1, + }, + [0x23D2]={ + category="so", + description="METRICAL LONG OVER SHORT", + direction="on", + linebreak="al", + unicodeslot=0x23D2, + }, + [0x23D3]={ + category="so", + description="METRICAL SHORT OVER LONG", + direction="on", + linebreak="al", + unicodeslot=0x23D3, + }, + [0x23D4]={ + category="so", + description="METRICAL LONG OVER TWO SHORTS", + direction="on", + linebreak="al", + unicodeslot=0x23D4, + }, + [0x23D5]={ + category="so", + description="METRICAL TWO SHORTS OVER LONG", + direction="on", + linebreak="al", + unicodeslot=0x23D5, + }, + [0x23D6]={ + category="so", + description="METRICAL TWO SHORTS JOINED", + direction="on", + linebreak="al", + unicodeslot=0x23D6, + }, + [0x23D7]={ + category="so", + description="METRICAL TRISEME", + direction="on", + linebreak="al", + unicodeslot=0x23D7, + }, + [0x23D8]={ + category="so", + description="METRICAL TETRASEME", + direction="on", + linebreak="al", + unicodeslot=0x23D8, + }, + [0x23D9]={ + category="so", + description="METRICAL PENTASEME", + direction="on", + linebreak="al", + unicodeslot=0x23D9, + }, + [0x23DA]={ + category="so", + description="EARTH GROUND", + direction="on", + linebreak="al", + unicodeslot=0x23DA, + }, + [0x23DB]={ + category="so", + description="FUSE", + direction="on", + linebreak="al", + unicodeslot=0x23DB, + }, + [0x23DC]={ + category="sm", + description="TOP PARENTHESIS", + direction="on", + linebreak="al", + mathclass="topaccent", + mathname="overparent", + unicodeslot=0x23DC, + }, + [0x23DD]={ + category="sm", + description="BOTTOM PARENTHESIS", + direction="on", + linebreak="al", + mathclass="botaccent", + mathname="underparent", + unicodeslot=0x23DD, + }, + [0x23DE]={ + category="sm", + description="TOP CURLY BRACKET", + direction="on", + linebreak="al", + mathclass="topaccent", + mathname="overbrace", + unicodeslot=0x23DE, + }, + [0x23DF]={ + category="sm", + description="BOTTOM CURLY BRACKET", + direction="on", + linebreak="al", + mathclass="botaccent", + mathname="underbrace", + unicodeslot=0x23DF, + }, + [0x23E0]={ + category="sm", + description="TOP TORTOISE SHELL BRACKET", + direction="on", + linebreak="al", + mathclass="accent", + unicodeslot=0x23E0, + }, + [0x23E1]={ + category="sm", + description="BOTTOM TORTOISE SHELL BRACKET", + direction="on", + linebreak="al", + mathclass="accent", + unicodeslot=0x23E1, + }, + [0x23E2]={ + category="so", + description="WHITE TRAPEZIUM", + direction="on", + linebreak="al", + unicodeslot=0x23E2, + }, + [0x23E3]={ + category="so", + description="BENZENE RING WITH CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x23E3, + }, + [0x23E4]={ + category="so", + description="STRAIGHTNESS", + direction="on", + linebreak="al", + unicodeslot=0x23E4, + }, + [0x23E5]={ + category="so", + description="FLATNESS", + direction="on", + linebreak="al", + unicodeslot=0x23E5, + }, + [0x23E6]={ + category="so", + description="AC CURRENT", + direction="on", + linebreak="al", + unicodeslot=0x23E6, + }, + [0x23E7]={ + category="so", + description="ELECTRICAL INTERSECTION", + direction="on", + linebreak="al", + unicodeslot=0x23E7, + }, + [0x2400]={ + category="so", + description="SYMBOL FOR NULL", + direction="on", + linebreak="al", + unicodeslot=0x2400, + }, + [0x2401]={ + category="so", + description="SYMBOL FOR START OF HEADING", + direction="on", + linebreak="al", + unicodeslot=0x2401, + }, + [0x2402]={ + category="so", + description="SYMBOL FOR START OF TEXT", + direction="on", + linebreak="al", + unicodeslot=0x2402, + }, + [0x2403]={ + category="so", + description="SYMBOL FOR END OF TEXT", + direction="on", + linebreak="al", + unicodeslot=0x2403, + }, + [0x2404]={ + category="so", + description="SYMBOL FOR END OF TRANSMISSION", + direction="on", + linebreak="al", + unicodeslot=0x2404, + }, + [0x2405]={ + category="so", + description="SYMBOL FOR ENQUIRY", + direction="on", + linebreak="al", + unicodeslot=0x2405, + }, + [0x2406]={ + category="so", + description="SYMBOL FOR ACKNOWLEDGE", + direction="on", + linebreak="al", + unicodeslot=0x2406, + }, + [0x2407]={ + category="so", + description="SYMBOL FOR BELL", + direction="on", + linebreak="al", + unicodeslot=0x2407, + }, + [0x2408]={ + category="so", + description="SYMBOL FOR BACKSPACE", + direction="on", + linebreak="al", + unicodeslot=0x2408, + }, + [0x2409]={ + category="so", + description="SYMBOL FOR HORIZONTAL TABULATION", + direction="on", + linebreak="al", + unicodeslot=0x2409, + }, + [0x240A]={ + category="so", + description="SYMBOL FOR LINE FEED", + direction="on", + linebreak="al", + unicodeslot=0x240A, + }, + [0x240B]={ + category="so", + description="SYMBOL FOR VERTICAL TABULATION", + direction="on", + linebreak="al", + unicodeslot=0x240B, + }, + [0x240C]={ + category="so", + description="SYMBOL FOR FORM FEED", + direction="on", + linebreak="al", + unicodeslot=0x240C, + }, + [0x240D]={ + category="so", + description="SYMBOL FOR CARRIAGE RETURN", + direction="on", + linebreak="al", + unicodeslot=0x240D, + }, + [0x240E]={ + category="so", + description="SYMBOL FOR SHIFT OUT", + direction="on", + linebreak="al", + unicodeslot=0x240E, + }, + [0x240F]={ + category="so", + description="SYMBOL FOR SHIFT IN", + direction="on", + linebreak="al", + unicodeslot=0x240F, + }, + [0x2410]={ + category="so", + description="SYMBOL FOR DATA LINK ESCAPE", + direction="on", + linebreak="al", + unicodeslot=0x2410, + }, + [0x2411]={ + category="so", + description="SYMBOL FOR DEVICE CONTROL ONE", + direction="on", + linebreak="al", + unicodeslot=0x2411, + }, + [0x2412]={ + category="so", + description="SYMBOL FOR DEVICE CONTROL TWO", + direction="on", + linebreak="al", + unicodeslot=0x2412, + }, + [0x2413]={ + category="so", + description="SYMBOL FOR DEVICE CONTROL THREE", + direction="on", + linebreak="al", + unicodeslot=0x2413, + }, + [0x2414]={ + category="so", + description="SYMBOL FOR DEVICE CONTROL FOUR", + direction="on", + linebreak="al", + unicodeslot=0x2414, + }, + [0x2415]={ + category="so", + description="SYMBOL FOR NEGATIVE ACKNOWLEDGE", + direction="on", + linebreak="al", + unicodeslot=0x2415, + }, + [0x2416]={ + category="so", + description="SYMBOL FOR SYNCHRONOUS IDLE", + direction="on", + linebreak="al", + unicodeslot=0x2416, + }, + [0x2417]={ + category="so", + description="SYMBOL FOR END OF TRANSMISSION BLOCK", + direction="on", + linebreak="al", + unicodeslot=0x2417, + }, + [0x2418]={ + category="so", + description="SYMBOL FOR CANCEL", + direction="on", + linebreak="al", + unicodeslot=0x2418, + }, + [0x2419]={ + category="so", + description="SYMBOL FOR END OF MEDIUM", + direction="on", + linebreak="al", + unicodeslot=0x2419, + }, + [0x241A]={ + category="so", + description="SYMBOL FOR SUBSTITUTE", + direction="on", + linebreak="al", + unicodeslot=0x241A, + }, + [0x241B]={ + category="so", + description="SYMBOL FOR ESCAPE", + direction="on", + linebreak="al", + unicodeslot=0x241B, + }, + [0x241C]={ + category="so", + description="SYMBOL FOR FILE SEPARATOR", + direction="on", + linebreak="al", + unicodeslot=0x241C, + }, + [0x241D]={ + category="so", + description="SYMBOL FOR GROUP SEPARATOR", + direction="on", + linebreak="al", + unicodeslot=0x241D, + }, + [0x241E]={ + category="so", + description="SYMBOL FOR RECORD SEPARATOR", + direction="on", + linebreak="al", + unicodeslot=0x241E, + }, + [0x241F]={ + category="so", + description="SYMBOL FOR UNIT SEPARATOR", + direction="on", + linebreak="al", + unicodeslot=0x241F, + }, + [0x2420]={ + category="so", + description="SYMBOL FOR SPACE", + direction="on", + linebreak="al", + unicodeslot=0x2420, + }, + [0x2421]={ + category="so", + description="SYMBOL FOR DELETE", + direction="on", + linebreak="al", + unicodeslot=0x2421, + }, + [0x2422]={ + category="so", + description="BLANK SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x2422, + }, + [0x2423]={ + category="so", + description="OPEN BOX", + direction="on", + linebreak="al", + unicodeslot=0x2423, + }, + [0x2424]={ + category="so", + description="SYMBOL FOR NEWLINE", + direction="on", + linebreak="al", + unicodeslot=0x2424, + }, + [0x2425]={ + category="so", + description="SYMBOL FOR DELETE FORM TWO", + direction="on", + linebreak="al", + unicodeslot=0x2425, + }, + [0x2426]={ + category="so", + description="SYMBOL FOR SUBSTITUTE FORM TWO", + direction="on", + linebreak="al", + unicodeslot=0x2426, + }, + [0x2440]={ + category="so", + description="OCR HOOK", + direction="on", + linebreak="al", + unicodeslot=0x2440, + }, + [0x2441]={ + category="so", + description="OCR CHAIR", + direction="on", + linebreak="al", + unicodeslot=0x2441, + }, + [0x2442]={ + category="so", + description="OCR FORK", + direction="on", + linebreak="al", + unicodeslot=0x2442, + }, + [0x2443]={ + category="so", + description="OCR INVERTED FORK", + direction="on", + linebreak="al", + unicodeslot=0x2443, + }, + [0x2444]={ + category="so", + description="OCR BELT BUCKLE", + direction="on", + linebreak="al", + unicodeslot=0x2444, + }, + [0x2445]={ + category="so", + description="OCR BOW TIE", + direction="on", + linebreak="al", + unicodeslot=0x2445, + }, + [0x2446]={ + category="so", + description="OCR BRANCH BANK IDENTIFICATION", + direction="on", + linebreak="al", + unicodeslot=0x2446, + }, + [0x2447]={ + category="so", + description="OCR AMOUNT OF CHECK", + direction="on", + linebreak="al", + unicodeslot=0x2447, + }, + [0x2448]={ + category="so", + description="OCR DASH", + direction="on", + linebreak="al", + unicodeslot=0x2448, + }, + [0x2449]={ + category="so", + description="OCR CUSTOMER ACCOUNT NUMBER", + direction="on", + linebreak="al", + unicodeslot=0x2449, + }, + [0x244A]={ + category="so", + description="OCR DOUBLE BACKSLASH", + direction="on", + linebreak="al", + unicodeslot=0x244A, + }, + [0x2460]={ + category="no", + cjkwd="a", + description="CIRCLED DIGIT ONE", + direction="on", + linebreak="ai", + specials={ "circle", 0x0031 }, + unicodeslot=0x2460, + }, + [0x2461]={ + category="no", + cjkwd="a", + description="CIRCLED DIGIT TWO", + direction="on", + linebreak="ai", + specials={ "circle", 0x0032 }, + unicodeslot=0x2461, + }, + [0x2462]={ + category="no", + cjkwd="a", + description="CIRCLED DIGIT THREE", + direction="on", + linebreak="ai", + specials={ "circle", 0x0033 }, + unicodeslot=0x2462, + }, + [0x2463]={ + category="no", + cjkwd="a", + description="CIRCLED DIGIT FOUR", + direction="on", + linebreak="ai", + specials={ "circle", 0x0034 }, + unicodeslot=0x2463, + }, + [0x2464]={ + category="no", + cjkwd="a", + description="CIRCLED DIGIT FIVE", + direction="on", + linebreak="ai", + specials={ "circle", 0x0035 }, + unicodeslot=0x2464, + }, + [0x2465]={ + category="no", + cjkwd="a", + description="CIRCLED DIGIT SIX", + direction="on", + linebreak="ai", + specials={ "circle", 0x0036 }, + unicodeslot=0x2465, + }, + [0x2466]={ + category="no", + cjkwd="a", + description="CIRCLED DIGIT SEVEN", + direction="on", + linebreak="ai", + specials={ "circle", 0x0037 }, + unicodeslot=0x2466, + }, + [0x2467]={ + category="no", + cjkwd="a", + description="CIRCLED DIGIT EIGHT", + direction="on", + linebreak="ai", + specials={ "circle", 0x0038 }, + unicodeslot=0x2467, + }, + [0x2468]={ + category="no", + cjkwd="a", + description="CIRCLED DIGIT NINE", + direction="on", + linebreak="ai", + specials={ "circle", 0x0039 }, + unicodeslot=0x2468, + }, + [0x2469]={ + category="no", + cjkwd="a", + description="CIRCLED NUMBER TEN", + direction="on", + linebreak="ai", + specials={ "circle", 0x0031, 0x0030 }, + unicodeslot=0x2469, + }, + [0x246A]={ + category="no", + cjkwd="a", + description="CIRCLED NUMBER ELEVEN", + direction="on", + linebreak="ai", + specials={ "circle", 0x0031, 0x0031 }, + unicodeslot=0x246A, + }, + [0x246B]={ + category="no", + cjkwd="a", + description="CIRCLED NUMBER TWELVE", + direction="on", + linebreak="ai", + specials={ "circle", 0x0031, 0x0032 }, + unicodeslot=0x246B, + }, + [0x246C]={ + category="no", + cjkwd="a", + description="CIRCLED NUMBER THIRTEEN", + direction="on", + linebreak="ai", + specials={ "circle", 0x0031, 0x0033 }, + unicodeslot=0x246C, + }, + [0x246D]={ + category="no", + cjkwd="a", + description="CIRCLED NUMBER FOURTEEN", + direction="on", + linebreak="ai", + specials={ "circle", 0x0031, 0x0034 }, + unicodeslot=0x246D, + }, + [0x246E]={ + category="no", + cjkwd="a", + description="CIRCLED NUMBER FIFTEEN", + direction="on", + linebreak="ai", + specials={ "circle", 0x0031, 0x0035 }, + unicodeslot=0x246E, + }, + [0x246F]={ + category="no", + cjkwd="a", + description="CIRCLED NUMBER SIXTEEN", + direction="on", + linebreak="ai", + specials={ "circle", 0x0031, 0x0036 }, + unicodeslot=0x246F, + }, + [0x2470]={ + category="no", + cjkwd="a", + description="CIRCLED NUMBER SEVENTEEN", + direction="on", + linebreak="ai", + specials={ "circle", 0x0031, 0x0037 }, + unicodeslot=0x2470, + }, + [0x2471]={ + category="no", + cjkwd="a", + description="CIRCLED NUMBER EIGHTEEN", + direction="on", + linebreak="ai", + specials={ "circle", 0x0031, 0x0038 }, + unicodeslot=0x2471, + }, + [0x2472]={ + category="no", + cjkwd="a", + description="CIRCLED NUMBER NINETEEN", + direction="on", + linebreak="ai", + specials={ "circle", 0x0031, 0x0039 }, + unicodeslot=0x2472, + }, + [0x2473]={ + category="no", + cjkwd="a", + description="CIRCLED NUMBER TWENTY", + direction="on", + linebreak="ai", + specials={ "circle", 0x0032, 0x0030 }, + unicodeslot=0x2473, + }, + [0x2474]={ + category="no", + cjkwd="a", + description="PARENTHESIZED DIGIT ONE", + direction="on", + linebreak="ai", + specials={ "compat", 0x0028, 0x0031, 0x0029 }, + unicodeslot=0x2474, + }, + [0x2475]={ + category="no", + cjkwd="a", + description="PARENTHESIZED DIGIT TWO", + direction="on", + linebreak="ai", + specials={ "compat", 0x0028, 0x0032, 0x0029 }, + unicodeslot=0x2475, + }, + [0x2476]={ + category="no", + cjkwd="a", + description="PARENTHESIZED DIGIT THREE", + direction="on", + linebreak="ai", + specials={ "compat", 0x0028, 0x0033, 0x0029 }, + unicodeslot=0x2476, + }, + [0x2477]={ + category="no", + cjkwd="a", + description="PARENTHESIZED DIGIT FOUR", + direction="on", + linebreak="ai", + specials={ "compat", 0x0028, 0x0034, 0x0029 }, + unicodeslot=0x2477, + }, + [0x2478]={ + category="no", + cjkwd="a", + description="PARENTHESIZED DIGIT FIVE", + direction="on", + linebreak="ai", + specials={ "compat", 0x0028, 0x0035, 0x0029 }, + unicodeslot=0x2478, + }, + [0x2479]={ + category="no", + cjkwd="a", + description="PARENTHESIZED DIGIT SIX", + direction="on", + linebreak="ai", + specials={ "compat", 0x0028, 0x0036, 0x0029 }, + unicodeslot=0x2479, + }, + [0x247A]={ + category="no", + cjkwd="a", + description="PARENTHESIZED DIGIT SEVEN", + direction="on", + linebreak="ai", + specials={ "compat", 0x0028, 0x0037, 0x0029 }, + unicodeslot=0x247A, + }, + [0x247B]={ + category="no", + cjkwd="a", + description="PARENTHESIZED DIGIT EIGHT", + direction="on", + linebreak="ai", + specials={ "compat", 0x0028, 0x0038, 0x0029 }, + unicodeslot=0x247B, + }, + [0x247C]={ + category="no", + cjkwd="a", + description="PARENTHESIZED DIGIT NINE", + direction="on", + linebreak="ai", + specials={ "compat", 0x0028, 0x0039, 0x0029 }, + unicodeslot=0x247C, + }, + [0x247D]={ + category="no", + cjkwd="a", + description="PARENTHESIZED NUMBER TEN", + direction="on", + linebreak="ai", + specials={ "compat", 0x0028, 0x0031, 0x0030, 0x0029 }, + unicodeslot=0x247D, + }, + [0x247E]={ + category="no", + cjkwd="a", + description="PARENTHESIZED NUMBER ELEVEN", + direction="on", + linebreak="ai", + specials={ "compat", 0x0028, 0x0031, 0x0031, 0x0029 }, + unicodeslot=0x247E, + }, + [0x247F]={ + category="no", + cjkwd="a", + description="PARENTHESIZED NUMBER TWELVE", + direction="on", + linebreak="ai", + specials={ "compat", 0x0028, 0x0031, 0x0032, 0x0029 }, + unicodeslot=0x247F, + }, + [0x2480]={ + category="no", + cjkwd="a", + description="PARENTHESIZED NUMBER THIRTEEN", + direction="on", + linebreak="ai", + specials={ "compat", 0x0028, 0x0031, 0x0033, 0x0029 }, + unicodeslot=0x2480, + }, + [0x2481]={ + category="no", + cjkwd="a", + description="PARENTHESIZED NUMBER FOURTEEN", + direction="on", + linebreak="ai", + specials={ "compat", 0x0028, 0x0031, 0x0034, 0x0029 }, + unicodeslot=0x2481, + }, + [0x2482]={ + category="no", + cjkwd="a", + description="PARENTHESIZED NUMBER FIFTEEN", + direction="on", + linebreak="ai", + specials={ "compat", 0x0028, 0x0031, 0x0035, 0x0029 }, + unicodeslot=0x2482, + }, + [0x2483]={ + category="no", + cjkwd="a", + description="PARENTHESIZED NUMBER SIXTEEN", + direction="on", + linebreak="ai", + specials={ "compat", 0x0028, 0x0031, 0x0036, 0x0029 }, + unicodeslot=0x2483, + }, + [0x2484]={ + category="no", + cjkwd="a", + description="PARENTHESIZED NUMBER SEVENTEEN", + direction="on", + linebreak="ai", + specials={ "compat", 0x0028, 0x0031, 0x0037, 0x0029 }, + unicodeslot=0x2484, + }, + [0x2485]={ + category="no", + cjkwd="a", + description="PARENTHESIZED NUMBER EIGHTEEN", + direction="on", + linebreak="ai", + specials={ "compat", 0x0028, 0x0031, 0x0038, 0x0029 }, + unicodeslot=0x2485, + }, + [0x2486]={ + category="no", + cjkwd="a", + description="PARENTHESIZED NUMBER NINETEEN", + direction="on", + linebreak="ai", + specials={ "compat", 0x0028, 0x0031, 0x0039, 0x0029 }, + unicodeslot=0x2486, + }, + [0x2487]={ + category="no", + cjkwd="a", + description="PARENTHESIZED NUMBER TWENTY", + direction="on", + linebreak="ai", + specials={ "compat", 0x0028, 0x0032, 0x0030, 0x0029 }, + unicodeslot=0x2487, + }, + [0x2488]={ + category="no", + cjkwd="a", + description="DIGIT ONE FULL STOP", + direction="en", + linebreak="ai", + specials={ "compat", 0x0031, 0x002E }, + unicodeslot=0x2488, + }, + [0x2489]={ + category="no", + cjkwd="a", + description="DIGIT TWO FULL STOP", + direction="en", + linebreak="ai", + specials={ "compat", 0x0032, 0x002E }, + unicodeslot=0x2489, + }, + [0x248A]={ + category="no", + cjkwd="a", + description="DIGIT THREE FULL STOP", + direction="en", + linebreak="ai", + specials={ "compat", 0x0033, 0x002E }, + unicodeslot=0x248A, + }, + [0x248B]={ + category="no", + cjkwd="a", + description="DIGIT FOUR FULL STOP", + direction="en", + linebreak="ai", + specials={ "compat", 0x0034, 0x002E }, + unicodeslot=0x248B, + }, + [0x248C]={ + category="no", + cjkwd="a", + description="DIGIT FIVE FULL STOP", + direction="en", + linebreak="ai", + specials={ "compat", 0x0035, 0x002E }, + unicodeslot=0x248C, + }, + [0x248D]={ + category="no", + cjkwd="a", + description="DIGIT SIX FULL STOP", + direction="en", + linebreak="ai", + specials={ "compat", 0x0036, 0x002E }, + unicodeslot=0x248D, + }, + [0x248E]={ + category="no", + cjkwd="a", + description="DIGIT SEVEN FULL STOP", + direction="en", + linebreak="ai", + specials={ "compat", 0x0037, 0x002E }, + unicodeslot=0x248E, + }, + [0x248F]={ + category="no", + cjkwd="a", + description="DIGIT EIGHT FULL STOP", + direction="en", + linebreak="ai", + specials={ "compat", 0x0038, 0x002E }, + unicodeslot=0x248F, + }, + [0x2490]={ + category="no", + cjkwd="a", + description="DIGIT NINE FULL STOP", + direction="en", + linebreak="ai", + specials={ "compat", 0x0039, 0x002E }, + unicodeslot=0x2490, + }, + [0x2491]={ + category="no", + cjkwd="a", + description="NUMBER TEN FULL STOP", + direction="en", + linebreak="ai", + specials={ "compat", 0x0031, 0x0030, 0x002E }, + unicodeslot=0x2491, + }, + [0x2492]={ + category="no", + cjkwd="a", + description="NUMBER ELEVEN FULL STOP", + direction="en", + linebreak="ai", + specials={ "compat", 0x0031, 0x0031, 0x002E }, + unicodeslot=0x2492, + }, + [0x2493]={ + category="no", + cjkwd="a", + description="NUMBER TWELVE FULL STOP", + direction="en", + linebreak="ai", + specials={ "compat", 0x0031, 0x0032, 0x002E }, + unicodeslot=0x2493, + }, + [0x2494]={ + category="no", + cjkwd="a", + description="NUMBER THIRTEEN FULL STOP", + direction="en", + linebreak="ai", + specials={ "compat", 0x0031, 0x0033, 0x002E }, + unicodeslot=0x2494, + }, + [0x2495]={ + category="no", + cjkwd="a", + description="NUMBER FOURTEEN FULL STOP", + direction="en", + linebreak="ai", + specials={ "compat", 0x0031, 0x0034, 0x002E }, + unicodeslot=0x2495, + }, + [0x2496]={ + category="no", + cjkwd="a", + description="NUMBER FIFTEEN FULL STOP", + direction="en", + linebreak="ai", + specials={ "compat", 0x0031, 0x0035, 0x002E }, + unicodeslot=0x2496, + }, + [0x2497]={ + category="no", + cjkwd="a", + description="NUMBER SIXTEEN FULL STOP", + direction="en", + linebreak="ai", + specials={ "compat", 0x0031, 0x0036, 0x002E }, + unicodeslot=0x2497, + }, + [0x2498]={ + category="no", + cjkwd="a", + description="NUMBER SEVENTEEN FULL STOP", + direction="en", + linebreak="ai", + specials={ "compat", 0x0031, 0x0037, 0x002E }, + unicodeslot=0x2498, + }, + [0x2499]={ + category="no", + cjkwd="a", + description="NUMBER EIGHTEEN FULL STOP", + direction="en", + linebreak="ai", + specials={ "compat", 0x0031, 0x0038, 0x002E }, + unicodeslot=0x2499, + }, + [0x249A]={ + category="no", + cjkwd="a", + description="NUMBER NINETEEN FULL STOP", + direction="en", + linebreak="ai", + specials={ "compat", 0x0031, 0x0039, 0x002E }, + unicodeslot=0x249A, + }, + [0x249B]={ + category="no", + cjkwd="a", + description="NUMBER TWENTY FULL STOP", + direction="en", + linebreak="ai", + specials={ "compat", 0x0032, 0x0030, 0x002E }, + unicodeslot=0x249B, + }, + [0x249C]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER A", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x0061, 0x0029 }, + unicodeslot=0x249C, + }, + [0x249D]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER B", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x0062, 0x0029 }, + unicodeslot=0x249D, + }, + [0x249E]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER C", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x0063, 0x0029 }, + unicodeslot=0x249E, + }, + [0x249F]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER D", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x0064, 0x0029 }, + unicodeslot=0x249F, + }, + [0x24A0]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER E", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x0065, 0x0029 }, + unicodeslot=0x24A0, + }, + [0x24A1]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER F", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x0066, 0x0029 }, + unicodeslot=0x24A1, + }, + [0x24A2]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER G", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x0067, 0x0029 }, + unicodeslot=0x24A2, + }, + [0x24A3]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER H", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x0068, 0x0029 }, + unicodeslot=0x24A3, + }, + [0x24A4]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER I", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x0069, 0x0029 }, + unicodeslot=0x24A4, + }, + [0x24A5]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER J", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x006A, 0x0029 }, + unicodeslot=0x24A5, + }, + [0x24A6]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER K", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x006B, 0x0029 }, + unicodeslot=0x24A6, + }, + [0x24A7]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER L", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x006C, 0x0029 }, + unicodeslot=0x24A7, + }, + [0x24A8]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER M", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x006D, 0x0029 }, + unicodeslot=0x24A8, + }, + [0x24A9]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER N", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x006E, 0x0029 }, + unicodeslot=0x24A9, + }, + [0x24AA]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER O", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x006F, 0x0029 }, + unicodeslot=0x24AA, + }, + [0x24AB]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER P", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x0070, 0x0029 }, + unicodeslot=0x24AB, + }, + [0x24AC]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER Q", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x0071, 0x0029 }, + unicodeslot=0x24AC, + }, + [0x24AD]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER R", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x0072, 0x0029 }, + unicodeslot=0x24AD, + }, + [0x24AE]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER S", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x0073, 0x0029 }, + unicodeslot=0x24AE, + }, + [0x24AF]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER T", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x0074, 0x0029 }, + unicodeslot=0x24AF, + }, + [0x24B0]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER U", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x0075, 0x0029 }, + unicodeslot=0x24B0, + }, + [0x24B1]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER V", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x0076, 0x0029 }, + unicodeslot=0x24B1, + }, + [0x24B2]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER W", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x0077, 0x0029 }, + unicodeslot=0x24B2, + }, + [0x24B3]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER X", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x0078, 0x0029 }, + unicodeslot=0x24B3, + }, + [0x24B4]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER Y", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x0079, 0x0029 }, + unicodeslot=0x24B4, + }, + [0x24B5]={ + category="so", + cjkwd="a", + description="PARENTHESIZED LATIN SMALL LETTER Z", + direction="l", + linebreak="ai", + specials={ "compat", 0x0028, 0x007A, 0x0029 }, + unicodeslot=0x24B5, + }, + [0x24B6]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER A", + direction="l", + lccode=0x24D0, + linebreak="ai", + specials={ "circle", 0x0041 }, + unicodeslot=0x24B6, + }, + [0x24B7]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER B", + direction="l", + lccode=0x24D1, + linebreak="ai", + specials={ "circle", 0x0042 }, + unicodeslot=0x24B7, + }, + [0x24B8]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER C", + direction="l", + lccode=0x24D2, + linebreak="ai", + specials={ "circle", 0x0043 }, + unicodeslot=0x24B8, + }, + [0x24B9]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER D", + direction="l", + lccode=0x24D3, + linebreak="ai", + specials={ "circle", 0x0044 }, + unicodeslot=0x24B9, + }, + [0x24BA]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER E", + direction="l", + lccode=0x24D4, + linebreak="ai", + specials={ "circle", 0x0045 }, + unicodeslot=0x24BA, + }, + [0x24BB]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER F", + direction="l", + lccode=0x24D5, + linebreak="ai", + specials={ "circle", 0x0046 }, + unicodeslot=0x24BB, + }, + [0x24BC]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER G", + direction="l", + lccode=0x24D6, + linebreak="ai", + specials={ "circle", 0x0047 }, + unicodeslot=0x24BC, + }, + [0x24BD]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER H", + direction="l", + lccode=0x24D7, + linebreak="ai", + specials={ "circle", 0x0048 }, + unicodeslot=0x24BD, + }, + [0x24BE]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER I", + direction="l", + lccode=0x24D8, + linebreak="ai", + specials={ "circle", 0x0049 }, + unicodeslot=0x24BE, + }, + [0x24BF]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER J", + direction="l", + lccode=0x24D9, + linebreak="ai", + specials={ "circle", 0x004A }, + unicodeslot=0x24BF, + }, + [0x24C0]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER K", + direction="l", + lccode=0x24DA, + linebreak="ai", + specials={ "circle", 0x004B }, + unicodeslot=0x24C0, + }, + [0x24C1]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER L", + direction="l", + lccode=0x24DB, + linebreak="ai", + specials={ "circle", 0x004C }, + unicodeslot=0x24C1, + }, + [0x24C2]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER M", + direction="l", + lccode=0x24DC, + linebreak="ai", + specials={ "circle", 0x004D }, + unicodeslot=0x24C2, + }, + [0x24C3]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER N", + direction="l", + lccode=0x24DD, + linebreak="ai", + specials={ "circle", 0x004E }, + unicodeslot=0x24C3, + }, + [0x24C4]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER O", + direction="l", + lccode=0x24DE, + linebreak="ai", + specials={ "circle", 0x004F }, + unicodeslot=0x24C4, + }, + [0x24C5]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER P", + direction="l", + lccode=0x24DF, + linebreak="ai", + specials={ "circle", 0x0050 }, + unicodeslot=0x24C5, + }, + [0x24C6]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER Q", + direction="l", + lccode=0x24E0, + linebreak="ai", + specials={ "circle", 0x0051 }, + unicodeslot=0x24C6, + }, + [0x24C7]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER R", + direction="l", + lccode=0x24E1, + linebreak="ai", + mathclass="ord", + mathname="circledR", + specials={ "circle", 0x0052 }, + unicodeslot=0x24C7, + }, + [0x24C8]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER S", + direction="l", + lccode=0x24E2, + linebreak="ai", + mathclass="ord", + mathname="circledS", + specials={ "circle", 0x0053 }, + unicodeslot=0x24C8, + }, + [0x24C9]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER T", + direction="l", + lccode=0x24E3, + linebreak="ai", + specials={ "circle", 0x0054 }, + unicodeslot=0x24C9, + }, + [0x24CA]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER U", + direction="l", + lccode=0x24E4, + linebreak="ai", + specials={ "circle", 0x0055 }, + unicodeslot=0x24CA, + }, + [0x24CB]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER V", + direction="l", + lccode=0x24E5, + linebreak="ai", + specials={ "circle", 0x0056 }, + unicodeslot=0x24CB, + }, + [0x24CC]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER W", + direction="l", + lccode=0x24E6, + linebreak="ai", + specials={ "circle", 0x0057 }, + unicodeslot=0x24CC, + }, + [0x24CD]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER X", + direction="l", + lccode=0x24E7, + linebreak="ai", + specials={ "circle", 0x0058 }, + unicodeslot=0x24CD, + }, + [0x24CE]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER Y", + direction="l", + lccode=0x24E8, + linebreak="ai", + specials={ "circle", 0x0059 }, + unicodeslot=0x24CE, + }, + [0x24CF]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN CAPITAL LETTER Z", + direction="l", + lccode=0x24E9, + linebreak="ai", + specials={ "circle", 0x005A }, + unicodeslot=0x24CF, + }, + [0x24D0]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER A", + direction="l", + linebreak="ai", + specials={ "circle", 0x0061 }, + uccode=0x24B6, + unicodeslot=0x24D0, + }, + [0x24D1]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER B", + direction="l", + linebreak="ai", + specials={ "circle", 0x0062 }, + uccode=0x24B7, + unicodeslot=0x24D1, + }, + [0x24D2]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER C", + direction="l", + linebreak="ai", + specials={ "circle", 0x0063 }, + uccode=0x24B8, + unicodeslot=0x24D2, + }, + [0x24D3]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER D", + direction="l", + linebreak="ai", + specials={ "circle", 0x0064 }, + uccode=0x24B9, + unicodeslot=0x24D3, + }, + [0x24D4]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER E", + direction="l", + linebreak="ai", + specials={ "circle", 0x0065 }, + uccode=0x24BA, + unicodeslot=0x24D4, + }, + [0x24D5]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER F", + direction="l", + linebreak="ai", + specials={ "circle", 0x0066 }, + uccode=0x24BB, + unicodeslot=0x24D5, + }, + [0x24D6]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER G", + direction="l", + linebreak="ai", + specials={ "circle", 0x0067 }, + uccode=0x24BC, + unicodeslot=0x24D6, + }, + [0x24D7]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER H", + direction="l", + linebreak="ai", + specials={ "circle", 0x0068 }, + uccode=0x24BD, + unicodeslot=0x24D7, + }, + [0x24D8]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER I", + direction="l", + linebreak="ai", + specials={ "circle", 0x0069 }, + uccode=0x24BE, + unicodeslot=0x24D8, + }, + [0x24D9]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER J", + direction="l", + linebreak="ai", + specials={ "circle", 0x006A }, + uccode=0x24BF, + unicodeslot=0x24D9, + }, + [0x24DA]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER K", + direction="l", + linebreak="ai", + specials={ "circle", 0x006B }, + uccode=0x24C0, + unicodeslot=0x24DA, + }, + [0x24DB]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER L", + direction="l", + linebreak="ai", + specials={ "circle", 0x006C }, + uccode=0x24C1, + unicodeslot=0x24DB, + }, + [0x24DC]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER M", + direction="l", + linebreak="ai", + specials={ "circle", 0x006D }, + uccode=0x24C2, + unicodeslot=0x24DC, + }, + [0x24DD]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER N", + direction="l", + linebreak="ai", + specials={ "circle", 0x006E }, + uccode=0x24C3, + unicodeslot=0x24DD, + }, + [0x24DE]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER O", + direction="l", + linebreak="ai", + specials={ "circle", 0x006F }, + uccode=0x24C4, + unicodeslot=0x24DE, + }, + [0x24DF]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER P", + direction="l", + linebreak="ai", + specials={ "circle", 0x0070 }, + uccode=0x24C5, + unicodeslot=0x24DF, + }, + [0x24E0]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER Q", + direction="l", + linebreak="ai", + specials={ "circle", 0x0071 }, + uccode=0x24C6, + unicodeslot=0x24E0, + }, + [0x24E1]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER R", + direction="l", + linebreak="ai", + specials={ "circle", 0x0072 }, + uccode=0x24C7, + unicodeslot=0x24E1, + }, + [0x24E2]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER S", + direction="l", + linebreak="ai", + specials={ "circle", 0x0073 }, + uccode=0x24C8, + unicodeslot=0x24E2, + }, + [0x24E3]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER T", + direction="l", + linebreak="ai", + specials={ "circle", 0x0074 }, + uccode=0x24C9, + unicodeslot=0x24E3, + }, + [0x24E4]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER U", + direction="l", + linebreak="ai", + specials={ "circle", 0x0075 }, + uccode=0x24CA, + unicodeslot=0x24E4, + }, + [0x24E5]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER V", + direction="l", + linebreak="ai", + specials={ "circle", 0x0076 }, + uccode=0x24CB, + unicodeslot=0x24E5, + }, + [0x24E6]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER W", + direction="l", + linebreak="ai", + specials={ "circle", 0x0077 }, + uccode=0x24CC, + unicodeslot=0x24E6, + }, + [0x24E7]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER X", + direction="l", + linebreak="ai", + specials={ "circle", 0x0078 }, + uccode=0x24CD, + unicodeslot=0x24E7, + }, + [0x24E8]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER Y", + direction="l", + linebreak="ai", + specials={ "circle", 0x0079 }, + uccode=0x24CE, + unicodeslot=0x24E8, + }, + [0x24E9]={ + category="so", + cjkwd="a", + description="CIRCLED LATIN SMALL LETTER Z", + direction="l", + linebreak="ai", + specials={ "circle", 0x007A }, + uccode=0x24CF, + unicodeslot=0x24E9, + }, + [0x24EA]={ + category="no", + description="CIRCLED DIGIT ZERO", + direction="on", + linebreak="ai", + specials={ "circle", 0x0030 }, + unicodeslot=0x24EA, + }, + [0x24EB]={ + category="no", + cjkwd="a", + description="NEGATIVE CIRCLED NUMBER ELEVEN", + direction="on", + linebreak="ai", + unicodeslot=0x24EB, + }, + [0x24EC]={ + category="no", + cjkwd="a", + description="NEGATIVE CIRCLED NUMBER TWELVE", + direction="on", + linebreak="ai", + unicodeslot=0x24EC, + }, + [0x24ED]={ + category="no", + cjkwd="a", + description="NEGATIVE CIRCLED NUMBER THIRTEEN", + direction="on", + linebreak="ai", + unicodeslot=0x24ED, + }, + [0x24EE]={ + category="no", + cjkwd="a", + description="NEGATIVE CIRCLED NUMBER FOURTEEN", + direction="on", + linebreak="ai", + unicodeslot=0x24EE, + }, + [0x24EF]={ + category="no", + cjkwd="a", + description="NEGATIVE CIRCLED NUMBER FIFTEEN", + direction="on", + linebreak="ai", + unicodeslot=0x24EF, + }, + [0x24F0]={ + category="no", + cjkwd="a", + description="NEGATIVE CIRCLED NUMBER SIXTEEN", + direction="on", + linebreak="ai", + unicodeslot=0x24F0, + }, + [0x24F1]={ + category="no", + cjkwd="a", + description="NEGATIVE CIRCLED NUMBER SEVENTEEN", + direction="on", + linebreak="ai", + unicodeslot=0x24F1, + }, + [0x24F2]={ + category="no", + cjkwd="a", + description="NEGATIVE CIRCLED NUMBER EIGHTEEN", + direction="on", + linebreak="ai", + unicodeslot=0x24F2, + }, + [0x24F3]={ + category="no", + cjkwd="a", + description="NEGATIVE CIRCLED NUMBER NINETEEN", + direction="on", + linebreak="ai", + unicodeslot=0x24F3, + }, + [0x24F4]={ + category="no", + cjkwd="a", + description="NEGATIVE CIRCLED NUMBER TWENTY", + direction="on", + linebreak="ai", + unicodeslot=0x24F4, + }, + [0x24F5]={ + category="no", + cjkwd="a", + description="DOUBLE CIRCLED DIGIT ONE", + direction="on", + linebreak="ai", + unicodeslot=0x24F5, + }, + [0x24F6]={ + category="no", + cjkwd="a", + description="DOUBLE CIRCLED DIGIT TWO", + direction="on", + linebreak="ai", + unicodeslot=0x24F6, + }, + [0x24F7]={ + category="no", + cjkwd="a", + description="DOUBLE CIRCLED DIGIT THREE", + direction="on", + linebreak="ai", + unicodeslot=0x24F7, + }, + [0x24F8]={ + category="no", + cjkwd="a", + description="DOUBLE CIRCLED DIGIT FOUR", + direction="on", + linebreak="ai", + unicodeslot=0x24F8, + }, + [0x24F9]={ + category="no", + cjkwd="a", + description="DOUBLE CIRCLED DIGIT FIVE", + direction="on", + linebreak="ai", + unicodeslot=0x24F9, + }, + [0x24FA]={ + category="no", + cjkwd="a", + description="DOUBLE CIRCLED DIGIT SIX", + direction="on", + linebreak="ai", + unicodeslot=0x24FA, + }, + [0x24FB]={ + category="no", + cjkwd="a", + description="DOUBLE CIRCLED DIGIT SEVEN", + direction="on", + linebreak="ai", + unicodeslot=0x24FB, + }, + [0x24FC]={ + category="no", + cjkwd="a", + description="DOUBLE CIRCLED DIGIT EIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x24FC, + }, + [0x24FD]={ + category="no", + cjkwd="a", + description="DOUBLE CIRCLED DIGIT NINE", + direction="on", + linebreak="ai", + unicodeslot=0x24FD, + }, + [0x24FE]={ + category="no", + cjkwd="a", + description="DOUBLE CIRCLED NUMBER TEN", + direction="on", + linebreak="ai", + unicodeslot=0x24FE, + }, + [0x24FF]={ + category="no", + cjkwd="a", + description="NEGATIVE CIRCLED DIGIT ZERO", + direction="on", + linebreak="al", + unicodeslot=0x24FF, + }, + [0x2500]={ + adobename="SF100000", + category="so", + cjkwd="a", + description="BOX DRAWINGS LIGHT HORIZONTAL", + direction="on", + linebreak="ai", + unicodeslot=0x2500, + }, + [0x2501]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS HEAVY HORIZONTAL", + direction="on", + linebreak="ai", + unicodeslot=0x2501, + }, + [0x2502]={ + adobename="SF110000", + category="so", + cjkwd="a", + description="BOX DRAWINGS LIGHT VERTICAL", + direction="on", + linebreak="ai", + unicodeslot=0x2502, + }, + [0x2503]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS HEAVY VERTICAL", + direction="on", + linebreak="ai", + unicodeslot=0x2503, + }, + [0x2504]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL", + direction="on", + linebreak="ai", + unicodeslot=0x2504, + }, + [0x2505]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL", + direction="on", + linebreak="ai", + unicodeslot=0x2505, + }, + [0x2506]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL", + direction="on", + linebreak="ai", + unicodeslot=0x2506, + }, + [0x2507]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL", + direction="on", + linebreak="ai", + unicodeslot=0x2507, + }, + [0x2508]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL", + direction="on", + linebreak="ai", + unicodeslot=0x2508, + }, + [0x2509]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL", + direction="on", + linebreak="ai", + unicodeslot=0x2509, + }, + [0x250A]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL", + direction="on", + linebreak="ai", + unicodeslot=0x250A, + }, + [0x250B]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL", + direction="on", + linebreak="ai", + unicodeslot=0x250B, + }, + [0x250C]={ + adobename="SF10000", + category="so", + cjkwd="a", + description="BOX DRAWINGS LIGHT DOWN AND RIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x250C, + }, + [0x250D]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY", + direction="on", + linebreak="ai", + unicodeslot=0x250D, + }, + [0x250E]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x250E, + }, + [0x250F]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS HEAVY DOWN AND RIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x250F, + }, + [0x2510]={ + adobename="SF30000", + category="so", + cjkwd="a", + description="BOX DRAWINGS LIGHT DOWN AND LEFT", + direction="on", + linebreak="ai", + unicodeslot=0x2510, + }, + [0x2511]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY", + direction="on", + linebreak="ai", + unicodeslot=0x2511, + }, + [0x2512]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2512, + }, + [0x2513]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS HEAVY DOWN AND LEFT", + direction="on", + linebreak="ai", + unicodeslot=0x2513, + }, + [0x2514]={ + adobename="SF20000", + category="so", + cjkwd="a", + description="BOX DRAWINGS LIGHT UP AND RIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2514, + }, + [0x2515]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS UP LIGHT AND RIGHT HEAVY", + direction="on", + linebreak="ai", + unicodeslot=0x2515, + }, + [0x2516]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS UP HEAVY AND RIGHT LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2516, + }, + [0x2517]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS HEAVY UP AND RIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2517, + }, + [0x2518]={ + adobename="SF40000", + category="so", + cjkwd="a", + description="BOX DRAWINGS LIGHT UP AND LEFT", + direction="on", + linebreak="ai", + unicodeslot=0x2518, + }, + [0x2519]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS UP LIGHT AND LEFT HEAVY", + direction="on", + linebreak="ai", + unicodeslot=0x2519, + }, + [0x251A]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS UP HEAVY AND LEFT LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x251A, + }, + [0x251B]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS HEAVY UP AND LEFT", + direction="on", + linebreak="ai", + unicodeslot=0x251B, + }, + [0x251C]={ + adobename="SF80000", + category="so", + cjkwd="a", + description="BOX DRAWINGS LIGHT VERTICAL AND RIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x251C, + }, + [0x251D]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY", + direction="on", + linebreak="ai", + unicodeslot=0x251D, + }, + [0x251E]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x251E, + }, + [0x251F]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x251F, + }, + [0x2520]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2520, + }, + [0x2521]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY", + direction="on", + linebreak="ai", + unicodeslot=0x2521, + }, + [0x2522]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY", + direction="on", + linebreak="ai", + unicodeslot=0x2522, + }, + [0x2523]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS HEAVY VERTICAL AND RIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2523, + }, + [0x2524]={ + adobename="SF90000", + category="so", + cjkwd="a", + description="BOX DRAWINGS LIGHT VERTICAL AND LEFT", + direction="on", + linebreak="ai", + unicodeslot=0x2524, + }, + [0x2525]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY", + direction="on", + linebreak="ai", + unicodeslot=0x2525, + }, + [0x2526]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2526, + }, + [0x2527]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2527, + }, + [0x2528]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2528, + }, + [0x2529]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY", + direction="on", + linebreak="ai", + unicodeslot=0x2529, + }, + [0x252A]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY", + direction="on", + linebreak="ai", + unicodeslot=0x252A, + }, + [0x252B]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS HEAVY VERTICAL AND LEFT", + direction="on", + linebreak="ai", + unicodeslot=0x252B, + }, + [0x252C]={ + adobename="SF60000", + category="so", + cjkwd="a", + description="BOX DRAWINGS LIGHT DOWN AND HORIZONTAL", + direction="on", + linebreak="ai", + unicodeslot=0x252C, + }, + [0x252D]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x252D, + }, + [0x252E]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x252E, + }, + [0x252F]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY", + direction="on", + linebreak="ai", + unicodeslot=0x252F, + }, + [0x2530]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2530, + }, + [0x2531]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY", + direction="on", + linebreak="ai", + unicodeslot=0x2531, + }, + [0x2532]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY", + direction="on", + linebreak="ai", + unicodeslot=0x2532, + }, + [0x2533]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS HEAVY DOWN AND HORIZONTAL", + direction="on", + linebreak="ai", + unicodeslot=0x2533, + }, + [0x2534]={ + adobename="SF70000", + category="so", + cjkwd="a", + description="BOX DRAWINGS LIGHT UP AND HORIZONTAL", + direction="on", + linebreak="ai", + unicodeslot=0x2534, + }, + [0x2535]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2535, + }, + [0x2536]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2536, + }, + [0x2537]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY", + direction="on", + linebreak="ai", + unicodeslot=0x2537, + }, + [0x2538]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2538, + }, + [0x2539]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY", + direction="on", + linebreak="ai", + unicodeslot=0x2539, + }, + [0x253A]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY", + direction="on", + linebreak="ai", + unicodeslot=0x253A, + }, + [0x253B]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS HEAVY UP AND HORIZONTAL", + direction="on", + linebreak="ai", + unicodeslot=0x253B, + }, + [0x253C]={ + adobename="SF50000", + category="so", + cjkwd="a", + description="BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL", + direction="on", + linebreak="ai", + unicodeslot=0x253C, + }, + [0x253D]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x253D, + }, + [0x253E]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x253E, + }, + [0x253F]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY", + direction="on", + linebreak="ai", + unicodeslot=0x253F, + }, + [0x2540]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2540, + }, + [0x2541]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2541, + }, + [0x2542]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2542, + }, + [0x2543]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2543, + }, + [0x2544]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2544, + }, + [0x2545]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2545, + }, + [0x2546]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2546, + }, + [0x2547]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY", + direction="on", + linebreak="ai", + unicodeslot=0x2547, + }, + [0x2548]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY", + direction="on", + linebreak="ai", + unicodeslot=0x2548, + }, + [0x2549]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY", + direction="on", + linebreak="ai", + unicodeslot=0x2549, + }, + [0x254A]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY", + direction="on", + linebreak="ai", + unicodeslot=0x254A, + }, + [0x254B]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL", + direction="on", + linebreak="ai", + unicodeslot=0x254B, + }, + [0x254C]={ + category="so", + description="BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL", + direction="on", + linebreak="al", + unicodeslot=0x254C, + }, + [0x254D]={ + category="so", + description="BOX DRAWINGS HEAVY DOUBLE DASH HORIZONTAL", + direction="on", + linebreak="al", + unicodeslot=0x254D, + }, + [0x254E]={ + category="so", + description="BOX DRAWINGS LIGHT DOUBLE DASH VERTICAL", + direction="on", + linebreak="al", + unicodeslot=0x254E, + }, + [0x254F]={ + category="so", + description="BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL", + direction="on", + linebreak="al", + unicodeslot=0x254F, + }, + [0x2550]={ + adobename="SF430000", + category="so", + cjkwd="a", + description="BOX DRAWINGS DOUBLE HORIZONTAL", + direction="on", + linebreak="ai", + unicodeslot=0x2550, + }, + [0x2551]={ + adobename="SF240000", + category="so", + cjkwd="a", + description="BOX DRAWINGS DOUBLE VERTICAL", + direction="on", + linebreak="ai", + unicodeslot=0x2551, + }, + [0x2552]={ + adobename="SF510000", + category="so", + cjkwd="a", + description="BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE", + direction="on", + linebreak="ai", + unicodeslot=0x2552, + }, + [0x2553]={ + adobename="SF520000", + category="so", + cjkwd="a", + description="BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE", + direction="on", + linebreak="ai", + unicodeslot=0x2553, + }, + [0x2554]={ + adobename="SF390000", + category="so", + cjkwd="a", + description="BOX DRAWINGS DOUBLE DOWN AND RIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2554, + }, + [0x2555]={ + adobename="SF220000", + category="so", + cjkwd="a", + description="BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE", + direction="on", + linebreak="ai", + unicodeslot=0x2555, + }, + [0x2556]={ + adobename="SF210000", + category="so", + cjkwd="a", + description="BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE", + direction="on", + linebreak="ai", + unicodeslot=0x2556, + }, + [0x2557]={ + adobename="SF250000", + category="so", + cjkwd="a", + description="BOX DRAWINGS DOUBLE DOWN AND LEFT", + direction="on", + linebreak="ai", + unicodeslot=0x2557, + }, + [0x2558]={ + adobename="SF500000", + category="so", + cjkwd="a", + description="BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE", + direction="on", + linebreak="ai", + unicodeslot=0x2558, + }, + [0x2559]={ + adobename="SF490000", + category="so", + cjkwd="a", + description="BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE", + direction="on", + linebreak="ai", + unicodeslot=0x2559, + }, + [0x255A]={ + adobename="SF380000", + category="so", + cjkwd="a", + description="BOX DRAWINGS DOUBLE UP AND RIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x255A, + }, + [0x255B]={ + adobename="SF280000", + category="so", + cjkwd="a", + description="BOX DRAWINGS UP SINGLE AND LEFT DOUBLE", + direction="on", + linebreak="ai", + unicodeslot=0x255B, + }, + [0x255C]={ + adobename="SF270000", + category="so", + cjkwd="a", + description="BOX DRAWINGS UP DOUBLE AND LEFT SINGLE", + direction="on", + linebreak="ai", + unicodeslot=0x255C, + }, + [0x255D]={ + adobename="SF260000", + category="so", + cjkwd="a", + description="BOX DRAWINGS DOUBLE UP AND LEFT", + direction="on", + linebreak="ai", + unicodeslot=0x255D, + }, + [0x255E]={ + adobename="SF360000", + category="so", + cjkwd="a", + description="BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE", + direction="on", + linebreak="ai", + unicodeslot=0x255E, + }, + [0x255F]={ + adobename="SF370000", + category="so", + cjkwd="a", + description="BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE", + direction="on", + linebreak="ai", + unicodeslot=0x255F, + }, + [0x2560]={ + adobename="SF420000", + category="so", + cjkwd="a", + description="BOX DRAWINGS DOUBLE VERTICAL AND RIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2560, + }, + [0x2561]={ + adobename="SF190000", + category="so", + cjkwd="a", + description="BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE", + direction="on", + linebreak="ai", + unicodeslot=0x2561, + }, + [0x2562]={ + adobename="SF200000", + category="so", + cjkwd="a", + description="BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE", + direction="on", + linebreak="ai", + unicodeslot=0x2562, + }, + [0x2563]={ + adobename="SF230000", + category="so", + cjkwd="a", + description="BOX DRAWINGS DOUBLE VERTICAL AND LEFT", + direction="on", + linebreak="ai", + unicodeslot=0x2563, + }, + [0x2564]={ + adobename="SF470000", + category="so", + cjkwd="a", + description="BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE", + direction="on", + linebreak="ai", + unicodeslot=0x2564, + }, + [0x2565]={ + adobename="SF480000", + category="so", + cjkwd="a", + description="BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE", + direction="on", + linebreak="ai", + unicodeslot=0x2565, + }, + [0x2566]={ + adobename="SF410000", + category="so", + cjkwd="a", + description="BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL", + direction="on", + linebreak="ai", + unicodeslot=0x2566, + }, + [0x2567]={ + adobename="SF450000", + category="so", + cjkwd="a", + description="BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE", + direction="on", + linebreak="ai", + unicodeslot=0x2567, + }, + [0x2568]={ + adobename="SF460000", + category="so", + cjkwd="a", + description="BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE", + direction="on", + linebreak="ai", + unicodeslot=0x2568, + }, + [0x2569]={ + adobename="SF400000", + category="so", + cjkwd="a", + description="BOX DRAWINGS DOUBLE UP AND HORIZONTAL", + direction="on", + linebreak="ai", + unicodeslot=0x2569, + }, + [0x256A]={ + adobename="SF540000", + category="so", + cjkwd="a", + description="BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE", + direction="on", + linebreak="ai", + unicodeslot=0x256A, + }, + [0x256B]={ + adobename="SF530000", + category="so", + cjkwd="a", + description="BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE", + direction="on", + linebreak="ai", + unicodeslot=0x256B, + }, + [0x256C]={ + adobename="SF440000", + category="so", + cjkwd="a", + description="BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL", + direction="on", + linebreak="ai", + unicodeslot=0x256C, + }, + [0x256D]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS LIGHT ARC DOWN AND RIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x256D, + }, + [0x256E]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS LIGHT ARC DOWN AND LEFT", + direction="on", + linebreak="ai", + unicodeslot=0x256E, + }, + [0x256F]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS LIGHT ARC UP AND LEFT", + direction="on", + linebreak="ai", + unicodeslot=0x256F, + }, + [0x2570]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS LIGHT ARC UP AND RIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2570, + }, + [0x2571]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT", + direction="on", + linebreak="ai", + unicodeslot=0x2571, + }, + [0x2572]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2572, + }, + [0x2573]={ + category="so", + cjkwd="a", + description="BOX DRAWINGS LIGHT DIAGONAL CROSS", + direction="on", + linebreak="ai", + unicodeslot=0x2573, + }, + [0x2574]={ + category="so", + description="BOX DRAWINGS LIGHT LEFT", + direction="on", + linebreak="ai", + unicodeslot=0x2574, + }, + [0x2575]={ + category="so", + description="BOX DRAWINGS LIGHT UP", + direction="on", + linebreak="al", + unicodeslot=0x2575, + }, + [0x2576]={ + category="so", + description="BOX DRAWINGS LIGHT RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x2576, + }, + [0x2577]={ + category="so", + description="BOX DRAWINGS LIGHT DOWN", + direction="on", + linebreak="al", + unicodeslot=0x2577, + }, + [0x2578]={ + category="so", + description="BOX DRAWINGS HEAVY LEFT", + direction="on", + linebreak="al", + unicodeslot=0x2578, + }, + [0x2579]={ + category="so", + description="BOX DRAWINGS HEAVY UP", + direction="on", + linebreak="al", + unicodeslot=0x2579, + }, + [0x257A]={ + category="so", + description="BOX DRAWINGS HEAVY RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x257A, + }, + [0x257B]={ + category="so", + description="BOX DRAWINGS HEAVY DOWN", + direction="on", + linebreak="al", + unicodeslot=0x257B, + }, + [0x257C]={ + category="so", + description="BOX DRAWINGS LIGHT LEFT AND HEAVY RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x257C, + }, + [0x257D]={ + category="so", + description="BOX DRAWINGS LIGHT UP AND HEAVY DOWN", + direction="on", + linebreak="al", + unicodeslot=0x257D, + }, + [0x257E]={ + category="so", + description="BOX DRAWINGS HEAVY LEFT AND LIGHT RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x257E, + }, + [0x257F]={ + category="so", + description="BOX DRAWINGS HEAVY UP AND LIGHT DOWN", + direction="on", + linebreak="al", + unicodeslot=0x257F, + }, + [0x2580]={ + adobename="upblock", + category="so", + cjkwd="a", + description="UPPER HALF BLOCK", + direction="on", + linebreak="ai", + unicodeslot=0x2580, + }, + [0x2581]={ + category="so", + cjkwd="a", + description="LOWER ONE EIGHTH BLOCK", + direction="on", + linebreak="ai", + unicodeslot=0x2581, + }, + [0x2582]={ + category="so", + cjkwd="a", + description="LOWER ONE QUARTER BLOCK", + direction="on", + linebreak="ai", + unicodeslot=0x2582, + }, + [0x2583]={ + category="so", + cjkwd="a", + description="LOWER THREE EIGHTHS BLOCK", + direction="on", + linebreak="ai", + unicodeslot=0x2583, + }, + [0x2584]={ + adobename="dnblock", + category="so", + cjkwd="a", + description="LOWER HALF BLOCK", + direction="on", + linebreak="ai", + unicodeslot=0x2584, + }, + [0x2585]={ + category="so", + cjkwd="a", + description="LOWER FIVE EIGHTHS BLOCK", + direction="on", + linebreak="ai", + unicodeslot=0x2585, + }, + [0x2586]={ + category="so", + cjkwd="a", + description="LOWER THREE QUARTERS BLOCK", + direction="on", + linebreak="ai", + unicodeslot=0x2586, + }, + [0x2587]={ + category="so", + cjkwd="a", + description="LOWER SEVEN EIGHTHS BLOCK", + direction="on", + linebreak="ai", + unicodeslot=0x2587, + }, + [0x2588]={ + adobename="block", + category="so", + cjkwd="a", + description="FULL BLOCK", + direction="on", + linebreak="ai", + unicodeslot=0x2588, + }, + [0x2589]={ + category="so", + cjkwd="a", + description="LEFT SEVEN EIGHTHS BLOCK", + direction="on", + linebreak="ai", + unicodeslot=0x2589, + }, + [0x258A]={ + category="so", + cjkwd="a", + description="LEFT THREE QUARTERS BLOCK", + direction="on", + linebreak="ai", + unicodeslot=0x258A, + }, + [0x258B]={ + category="so", + cjkwd="a", + description="LEFT FIVE EIGHTHS BLOCK", + direction="on", + linebreak="ai", + unicodeslot=0x258B, + }, + [0x258C]={ + adobename="lfblock", + category="so", + cjkwd="a", + description="LEFT HALF BLOCK", + direction="on", + linebreak="ai", + unicodeslot=0x258C, + }, + [0x258D]={ + category="so", + cjkwd="a", + description="LEFT THREE EIGHTHS BLOCK", + direction="on", + linebreak="ai", + unicodeslot=0x258D, + }, + [0x258E]={ + category="so", + cjkwd="a", + description="LEFT ONE QUARTER BLOCK", + direction="on", + linebreak="ai", + unicodeslot=0x258E, + }, + [0x258F]={ + category="so", + cjkwd="a", + description="LEFT ONE EIGHTH BLOCK", + direction="on", + linebreak="ai", + unicodeslot=0x258F, + }, + [0x2590]={ + adobename="rtblock", + category="so", + description="RIGHT HALF BLOCK", + direction="on", + linebreak="al", + unicodeslot=0x2590, + }, + [0x2591]={ + adobename="ltshade", + category="so", + description="LIGHT SHADE", + direction="on", + linebreak="al", + unicodeslot=0x2591, + }, + [0x2592]={ + adobename="shade", + category="so", + cjkwd="a", + description="MEDIUM SHADE", + direction="on", + linebreak="ai", + unicodeslot=0x2592, + }, + [0x2593]={ + adobename="dkshade", + category="so", + cjkwd="a", + description="DARK SHADE", + direction="on", + linebreak="ai", + unicodeslot=0x2593, + }, + [0x2594]={ + category="so", + cjkwd="a", + description="UPPER ONE EIGHTH BLOCK", + direction="on", + linebreak="ai", + unicodeslot=0x2594, + }, + [0x2595]={ + category="so", + cjkwd="a", + description="RIGHT ONE EIGHTH BLOCK", + direction="on", + linebreak="ai", + unicodeslot=0x2595, + }, + [0x2596]={ + category="so", + description="QUADRANT LOWER LEFT", + direction="on", + linebreak="al", + unicodeslot=0x2596, + }, + [0x2597]={ + category="so", + description="QUADRANT LOWER RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x2597, + }, + [0x2598]={ + category="so", + description="QUADRANT UPPER LEFT", + direction="on", + linebreak="al", + unicodeslot=0x2598, + }, + [0x2599]={ + category="so", + description="QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x2599, + }, + [0x259A]={ + category="so", + description="QUADRANT UPPER LEFT AND LOWER RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x259A, + }, + [0x259B]={ + category="so", + description="QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT", + direction="on", + linebreak="al", + unicodeslot=0x259B, + }, + [0x259C]={ + category="so", + description="QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x259C, + }, + [0x259D]={ + category="so", + description="QUADRANT UPPER RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x259D, + }, + [0x259E]={ + category="so", + description="QUADRANT UPPER RIGHT AND LOWER LEFT", + direction="on", + linebreak="al", + unicodeslot=0x259E, + }, + [0x259F]={ + category="so", + description="QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x259F, + }, + [0x25A0]={ + adobename="filledbox", + category="so", + cjkwd="a", + description="BLACK SQUARE", + direction="on", + linebreak="ai", + unicodeslot=0x25A0, + }, + [0x25A1]={ + adobename="H22073", + category="so", + cjkwd="a", + description="WHITE SQUARE", + direction="on", + linebreak="ai", + mathspec={ + { class="ord", name="square" }, + { class="ord", name="Box" }, + }, + unicodeslot=0x25A1, + }, + [0x25A2]={ + category="so", + description="WHITE SQUARE WITH ROUNDED CORNERS", + direction="on", + linebreak="al", + mathclass="ord", + mathname="blacksquare", + unicodeslot=0x25A2, + }, + [0x25A3]={ + category="so", + cjkwd="a", + description="WHITE SQUARE CONTAINING BLACK SMALL SQUARE", + direction="on", + linebreak="ai", + unicodeslot=0x25A3, + }, + [0x25A4]={ + category="so", + cjkwd="a", + description="SQUARE WITH HORIZONTAL FILL", + direction="on", + linebreak="ai", + unicodeslot=0x25A4, + }, + [0x25A5]={ + category="so", + cjkwd="a", + description="SQUARE WITH VERTICAL FILL", + direction="on", + linebreak="ai", + unicodeslot=0x25A5, + }, + [0x25A6]={ + category="so", + cjkwd="a", + description="SQUARE WITH ORTHOGONAL CROSSHATCH FILL", + direction="on", + linebreak="ai", + unicodeslot=0x25A6, + }, + [0x25A7]={ + category="so", + cjkwd="a", + description="SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL", + direction="on", + linebreak="ai", + unicodeslot=0x25A7, + }, + [0x25A8]={ + category="so", + cjkwd="a", + description="SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL", + direction="on", + linebreak="ai", + unicodeslot=0x25A8, + }, + [0x25A9]={ + category="so", + cjkwd="a", + description="SQUARE WITH DIAGONAL CROSSHATCH FILL", + direction="on", + linebreak="ai", + unicodeslot=0x25A9, + }, + [0x25AA]={ + adobename="H18543", + category="so", + description="BLACK SMALL SQUARE", + direction="on", + linebreak="al", + unicodeslot=0x25AA, + }, + [0x25AB]={ + adobename="H18551", + category="so", + description="WHITE SMALL SQUARE", + direction="on", + linebreak="al", + unicodeslot=0x25AB, + }, + [0x25AC]={ + adobename="filledrect", + category="so", + description="BLACK RECTANGLE", + direction="on", + linebreak="al", + unicodeslot=0x25AC, + }, + [0x25AD]={ + category="so", + description="WHITE RECTANGLE", + direction="on", + linebreak="al", + unicodeslot=0x25AD, + }, + [0x25AE]={ + category="so", + description="BLACK VERTICAL RECTANGLE", + direction="on", + linebreak="al", + unicodeslot=0x25AE, + }, + [0x25AF]={ + category="so", + description="WHITE VERTICAL RECTANGLE", + direction="on", + linebreak="al", + unicodeslot=0x25AF, + }, + [0x25B0]={ + category="so", + description="BLACK PARALLELOGRAM", + direction="on", + linebreak="al", + unicodeslot=0x25B0, + }, + [0x25B1]={ + category="so", + description="WHITE PARALLELOGRAM", + direction="on", + linebreak="al", + unicodeslot=0x25B1, + }, + [0x25B2]={ + adobename="triagup", + category="so", + cjkwd="a", + description="BLACK UP-POINTING TRIANGLE", + direction="on", + linebreak="ai", + unicodeslot=0x25B2, + }, + [0x25B3]={ + category="so", + cjkwd="a", + description="WHITE UP-POINTING TRIANGLE", + direction="on", + linebreak="ai", + mathspec={ + { class="ord", name="triangle" }, + { class="binary", name="bigtriangleup" }, + }, + unicodeslot=0x25B3, + }, + [0x25B4]={ + category="so", + description="BLACK UP-POINTING SMALL TRIANGLE", + direction="on", + linebreak="al", + unicodeslot=0x25B4, + }, + [0x25B5]={ + category="so", + description="WHITE UP-POINTING SMALL TRIANGLE", + direction="on", + linebreak="al", + unicodeslot=0x25B5, + }, + [0x25B6]={ + category="so", + cjkwd="a", + description="BLACK RIGHT-POINTING TRIANGLE", + direction="on", + linebreak="ai", + mathclass="bin", + mathname="blacktriangleright", + unicodeslot=0x25B6, + }, + [0x25B7]={ + category="sm", + cjkwd="a", + description="WHITE RIGHT-POINTING TRIANGLE", + direction="on", + linebreak="ai", + unicodeslot=0x25B7, + }, + [0x25B8]={ + category="so", + description="BLACK RIGHT-POINTING SMALL TRIANGLE", + direction="on", + linebreak="al", + mathclass="bin", + mathname="blacktriangleleft", + unicodeslot=0x25B8, + }, + [0x25B9]={ + category="so", + description="WHITE RIGHT-POINTING SMALL TRIANGLE", + direction="on", + linebreak="al", + unicodeslot=0x25B9, + }, + [0x25BA]={ + adobename="triagrt", + category="so", + description="BLACK RIGHT-POINTING POINTER", + direction="on", + linebreak="al", + unicodeslot=0x25BA, + }, + [0x25BB]={ + category="so", + description="WHITE RIGHT-POINTING POINTER", + direction="on", + linebreak="al", + unicodeslot=0x25BB, + }, + [0x25BC]={ + adobename="triagdn", + category="so", + cjkwd="a", + description="BLACK DOWN-POINTING TRIANGLE", + direction="on", + linebreak="ai", + unicodeslot=0x25BC, + }, + [0x25BD]={ + category="so", + cjkwd="a", + description="WHITE DOWN-POINTING TRIANGLE", + direction="on", + linebreak="ai", + mathclass="binary", + mathname="bigtriangledown", + unicodeslot=0x25BD, + }, + [0x25BE]={ + category="so", + description="BLACK DOWN-POINTING SMALL TRIANGLE", + direction="on", + linebreak="al", + unicodeslot=0x25BE, + }, + [0x25BF]={ + category="so", + description="WHITE DOWN-POINTING SMALL TRIANGLE", + direction="on", + linebreak="al", + unicodeslot=0x25BF, + }, + [0x25C0]={ + category="so", + cjkwd="a", + description="BLACK LEFT-POINTING TRIANGLE", + direction="on", + linebreak="ai", + unicodeslot=0x25C0, + }, + [0x25C1]={ + category="sm", + cjkwd="a", + description="WHITE LEFT-POINTING TRIANGLE", + direction="on", + linebreak="ai", + unicodeslot=0x25C1, + }, + [0x25C2]={ + category="so", + description="BLACK LEFT-POINTING SMALL TRIANGLE", + direction="on", + linebreak="al", + unicodeslot=0x25C2, + }, + [0x25C3]={ + category="so", + description="WHITE LEFT-POINTING SMALL TRIANGLE", + direction="on", + linebreak="al", + unicodeslot=0x25C3, + }, + [0x25C4]={ + adobename="triaglf", + category="so", + description="BLACK LEFT-POINTING POINTER", + direction="on", + linebreak="al", + unicodeslot=0x25C4, + }, + [0x25C5]={ + category="so", + description="WHITE LEFT-POINTING POINTER", + direction="on", + linebreak="al", + unicodeslot=0x25C5, + }, + [0x25C6]={ + category="so", + cjkwd="a", + description="BLACK DIAMOND", + direction="on", + linebreak="ai", + unicodeslot=0x25C6, + }, + [0x25C7]={ + category="so", + cjkwd="a", + description="WHITE DIAMOND", + direction="on", + linebreak="ai", + unicodeslot=0x25C7, + }, + [0x25C8]={ + category="so", + cjkwd="a", + description="WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND", + direction="on", + linebreak="ai", + unicodeslot=0x25C8, + }, + [0x25C9]={ + category="so", + description="FISHEYE", + direction="on", + linebreak="al", + unicodeslot=0x25C9, + }, + [0x25CA]={ + adobename="lozenge", + category="so", + description="LOZENGE", + direction="on", + linebreak="al", + mathclass="ord", + mathname="lozenge", + unicodeslot=0x25CA, + }, + [0x25CB]={ + adobename="circle", + category="so", + cjkwd="a", + description="WHITE CIRCLE", + direction="on", + linebreak="ai", + unicodeslot=0x25CB, + }, + [0x25CC]={ + category="so", + description="DOTTED CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x25CC, + }, + [0x25CD]={ + category="so", + description="CIRCLE WITH VERTICAL FILL", + direction="on", + linebreak="al", + unicodeslot=0x25CD, + }, + [0x25CE]={ + category="so", + cjkwd="a", + description="BULLSEYE", + direction="on", + linebreak="ai", + unicodeslot=0x25CE, + }, + [0x25CF]={ + adobename="H18533", + category="so", + cjkwd="a", + description="BLACK CIRCLE", + direction="on", + linebreak="ai", + unicodeslot=0x25CF, + }, + [0x25D0]={ + category="so", + cjkwd="a", + description="CIRCLE WITH LEFT HALF BLACK", + direction="on", + linebreak="ai", + unicodeslot=0x25D0, + }, + [0x25D1]={ + category="so", + cjkwd="a", + description="CIRCLE WITH RIGHT HALF BLACK", + direction="on", + linebreak="ai", + unicodeslot=0x25D1, + }, + [0x25D2]={ + category="so", + description="CIRCLE WITH LOWER HALF BLACK", + direction="on", + linebreak="al", + unicodeslot=0x25D2, + }, + [0x25D3]={ + category="so", + description="CIRCLE WITH UPPER HALF BLACK", + direction="on", + linebreak="al", + unicodeslot=0x25D3, + }, + [0x25D4]={ + category="so", + description="CIRCLE WITH UPPER RIGHT QUADRANT BLACK", + direction="on", + linebreak="al", + unicodeslot=0x25D4, + }, + [0x25D5]={ + category="so", + description="CIRCLE WITH ALL BUT UPPER LEFT QUADRANT BLACK", + direction="on", + linebreak="al", + unicodeslot=0x25D5, + }, + [0x25D6]={ + category="so", + description="LEFT HALF BLACK CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x25D6, + }, + [0x25D7]={ + category="so", + description="RIGHT HALF BLACK CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x25D7, + }, + [0x25D8]={ + adobename="invbullet", + category="so", + description="INVERSE BULLET", + direction="on", + linebreak="al", + unicodeslot=0x25D8, + }, + [0x25D9]={ + adobename="invcircle", + category="so", + description="INVERSE WHITE CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x25D9, + }, + [0x25DA]={ + category="so", + description="UPPER HALF INVERSE WHITE CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x25DA, + }, + [0x25DB]={ + category="so", + description="LOWER HALF INVERSE WHITE CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x25DB, + }, + [0x25DC]={ + category="so", + description="UPPER LEFT QUADRANT CIRCULAR ARC", + direction="on", + linebreak="al", + unicodeslot=0x25DC, + }, + [0x25DD]={ + category="so", + description="UPPER RIGHT QUADRANT CIRCULAR ARC", + direction="on", + linebreak="al", + unicodeslot=0x25DD, + }, + [0x25DE]={ + category="so", + description="LOWER RIGHT QUADRANT CIRCULAR ARC", + direction="on", + linebreak="al", + unicodeslot=0x25DE, + }, + [0x25DF]={ + category="so", + description="LOWER LEFT QUADRANT CIRCULAR ARC", + direction="on", + linebreak="al", + unicodeslot=0x25DF, + }, + [0x25E0]={ + category="so", + description="UPPER HALF CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x25E0, + }, + [0x25E1]={ + category="so", + description="LOWER HALF CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x25E1, + }, + [0x25E2]={ + category="so", + cjkwd="a", + description="BLACK LOWER RIGHT TRIANGLE", + direction="on", + linebreak="ai", + unicodeslot=0x25E2, + }, + [0x25E3]={ + category="so", + cjkwd="a", + description="BLACK LOWER LEFT TRIANGLE", + direction="on", + linebreak="ai", + unicodeslot=0x25E3, + }, + [0x25E4]={ + category="so", + cjkwd="a", + description="BLACK UPPER LEFT TRIANGLE", + direction="on", + linebreak="ai", + unicodeslot=0x25E4, + }, + [0x25E5]={ + category="so", + cjkwd="a", + description="BLACK UPPER RIGHT TRIANGLE", + direction="on", + linebreak="ai", + unicodeslot=0x25E5, + }, + [0x25E6]={ + adobename="openbullet", + category="so", + description="WHITE BULLET", + direction="on", + linebreak="al", + unicodeslot=0x25E6, + }, + [0x25E7]={ + category="so", + description="SQUARE WITH LEFT HALF BLACK", + direction="on", + linebreak="al", + unicodeslot=0x25E7, + }, + [0x25E8]={ + category="so", + description="SQUARE WITH RIGHT HALF BLACK", + direction="on", + linebreak="al", + unicodeslot=0x25E8, + }, + [0x25E9]={ + category="so", + description="SQUARE WITH UPPER LEFT DIAGONAL HALF BLACK", + direction="on", + linebreak="al", + unicodeslot=0x25E9, + }, + [0x25EA]={ + category="so", + description="SQUARE WITH LOWER RIGHT DIAGONAL HALF BLACK", + direction="on", + linebreak="al", + unicodeslot=0x25EA, + }, + [0x25EB]={ + category="so", + description="WHITE SQUARE WITH VERTICAL BISECTING LINE", + direction="on", + linebreak="al", + unicodeslot=0x25EB, + }, + [0x25EC]={ + category="so", + description="WHITE UP-POINTING TRIANGLE WITH DOT", + direction="on", + linebreak="al", + unicodeslot=0x25EC, + }, + [0x25ED]={ + category="so", + description="UP-POINTING TRIANGLE WITH LEFT HALF BLACK", + direction="on", + linebreak="al", + unicodeslot=0x25ED, + }, + [0x25EE]={ + category="so", + description="UP-POINTING TRIANGLE WITH RIGHT HALF BLACK", + direction="on", + linebreak="al", + unicodeslot=0x25EE, + }, + [0x25EF]={ + category="so", + cjkwd="a", + description="LARGE CIRCLE", + direction="on", + linebreak="ai", + mathclass="binary", + mathname="bigcirc", + unicodeslot=0x25EF, + }, + [0x25F0]={ + category="so", + description="WHITE SQUARE WITH UPPER LEFT QUADRANT", + direction="on", + linebreak="al", + unicodeslot=0x25F0, + }, + [0x25F1]={ + category="so", + description="WHITE SQUARE WITH LOWER LEFT QUADRANT", + direction="on", + linebreak="al", + unicodeslot=0x25F1, + }, + [0x25F2]={ + category="so", + description="WHITE SQUARE WITH LOWER RIGHT QUADRANT", + direction="on", + linebreak="al", + unicodeslot=0x25F2, + }, + [0x25F3]={ + category="so", + description="WHITE SQUARE WITH UPPER RIGHT QUADRANT", + direction="on", + linebreak="al", + unicodeslot=0x25F3, + }, + [0x25F4]={ + category="so", + description="WHITE CIRCLE WITH UPPER LEFT QUADRANT", + direction="on", + linebreak="al", + unicodeslot=0x25F4, + }, + [0x25F5]={ + category="so", + description="WHITE CIRCLE WITH LOWER LEFT QUADRANT", + direction="on", + linebreak="al", + unicodeslot=0x25F5, + }, + [0x25F6]={ + category="so", + description="WHITE CIRCLE WITH LOWER RIGHT QUADRANT", + direction="on", + linebreak="al", + unicodeslot=0x25F6, + }, + [0x25F7]={ + category="so", + description="WHITE CIRCLE WITH UPPER RIGHT QUADRANT", + direction="on", + linebreak="al", + unicodeslot=0x25F7, + }, + [0x25F8]={ + category="sm", + description="UPPER LEFT TRIANGLE", + direction="on", + linebreak="al", + unicodeslot=0x25F8, + }, + [0x25F9]={ + category="sm", + description="UPPER RIGHT TRIANGLE", + direction="on", + linebreak="al", + unicodeslot=0x25F9, + }, + [0x25FA]={ + category="sm", + description="LOWER LEFT TRIANGLE", + direction="on", + linebreak="al", + unicodeslot=0x25FA, + }, + [0x25FB]={ + category="sm", + description="WHITE MEDIUM SQUARE", + direction="on", + linebreak="al", + unicodeslot=0x25FB, + }, + [0x25FC]={ + category="sm", + description="BLACK MEDIUM SQUARE", + direction="on", + linebreak="al", + unicodeslot=0x25FC, + }, + [0x25FD]={ + category="sm", + description="WHITE MEDIUM SMALL SQUARE", + direction="on", + linebreak="al", + unicodeslot=0x25FD, + }, + [0x25FE]={ + category="sm", + description="BLACK MEDIUM SMALL SQUARE", + direction="on", + linebreak="al", + unicodeslot=0x25FE, + }, + [0x25FF]={ + category="sm", + description="LOWER RIGHT TRIANGLE", + direction="on", + linebreak="al", + unicodeslot=0x25FF, + }, + [0x2600]={ + category="so", + description="BLACK SUN WITH RAYS", + direction="on", + linebreak="al", + unicodeslot=0x2600, + }, + [0x2601]={ + category="so", + description="CLOUD", + direction="on", + linebreak="al", + unicodeslot=0x2601, + }, + [0x2602]={ + category="so", + description="UMBRELLA", + direction="on", + linebreak="al", + unicodeslot=0x2602, + }, + [0x2603]={ + category="so", + description="SNOWMAN", + direction="on", + linebreak="al", + unicodeslot=0x2603, + }, + [0x2604]={ + category="so", + description="COMET", + direction="on", + linebreak="al", + unicodeslot=0x2604, + }, + [0x2605]={ + category="so", + cjkwd="a", + description="BLACK STAR", + direction="on", + linebreak="ai", + mathclass="ord", + mathname="bigstar", + unicodeslot=0x2605, + }, + [0x2606]={ + category="so", + cjkwd="a", + description="WHITE STAR", + direction="on", + linebreak="ai", + unicodeslot=0x2606, + }, + [0x2607]={ + category="so", + description="LIGHTNING", + direction="on", + linebreak="al", + unicodeslot=0x2607, + }, + [0x2608]={ + category="so", + description="THUNDERSTORM", + direction="on", + linebreak="al", + unicodeslot=0x2608, + }, + [0x2609]={ + category="so", + cjkwd="a", + description="SUN", + direction="on", + linebreak="ai", + unicodeslot=0x2609, + }, + [0x260A]={ + category="so", + description="ASCENDING NODE", + direction="on", + linebreak="al", + unicodeslot=0x260A, + }, + [0x260B]={ + category="so", + description="DESCENDING NODE", + direction="on", + linebreak="al", + unicodeslot=0x260B, + }, + [0x260C]={ + category="so", + description="CONJUNCTION", + direction="on", + linebreak="al", + unicodeslot=0x260C, + }, + [0x260D]={ + category="so", + description="OPPOSITION", + direction="on", + linebreak="al", + unicodeslot=0x260D, + }, + [0x260E]={ + category="so", + cjkwd="a", + description="BLACK TELEPHONE", + direction="on", + linebreak="ai", + unicodeslot=0x260E, + }, + [0x260F]={ + category="so", + cjkwd="a", + description="WHITE TELEPHONE", + direction="on", + linebreak="ai", + unicodeslot=0x260F, + }, + [0x2610]={ + category="so", + description="BALLOT BOX", + direction="on", + linebreak="al", + unicodeslot=0x2610, + }, + [0x2611]={ + category="so", + description="BALLOT BOX WITH CHECK", + direction="on", + linebreak="al", + unicodeslot=0x2611, + }, + [0x2612]={ + category="so", + description="BALLOT BOX WITH X", + direction="on", + linebreak="al", + unicodeslot=0x2612, + }, + [0x2613]={ + category="so", + description="SALTIRE", + direction="on", + linebreak="al", + unicodeslot=0x2613, + }, + [0x2614]={ + category="so", + cjkwd="a", + description="UMBRELLA WITH RAIN DROPS", + direction="on", + linebreak="ai", + unicodeslot=0x2614, + }, + [0x2615]={ + category="so", + cjkwd="a", + description="HOT BEVERAGE", + direction="on", + linebreak="ai", + unicodeslot=0x2615, + }, + [0x2616]={ + category="so", + description="WHITE SHOGI PIECE", + direction="on", + linebreak="ai", + unicodeslot=0x2616, + }, + [0x2617]={ + category="so", + description="BLACK SHOGI PIECE", + direction="on", + linebreak="ai", + unicodeslot=0x2617, + }, + [0x2618]={ + category="so", + description="SHAMROCK", + direction="on", + linebreak="al", + unicodeslot=0x2618, + }, + [0x2619]={ + category="so", + description="REVERSED ROTATED FLORAL HEART BULLET", + direction="on", + linebreak="al", + unicodeslot=0x2619, + }, + [0x261A]={ + category="so", + description="BLACK LEFT POINTING INDEX", + direction="on", + linebreak="al", + unicodeslot=0x261A, + }, + [0x261B]={ + category="so", + description="BLACK RIGHT POINTING INDEX", + direction="on", + linebreak="al", + unicodeslot=0x261B, + }, + [0x261C]={ + category="so", + cjkwd="a", + description="WHITE LEFT POINTING INDEX", + direction="on", + linebreak="ai", + unicodeslot=0x261C, + }, + [0x261D]={ + category="so", + description="WHITE UP POINTING INDEX", + direction="on", + linebreak="al", + unicodeslot=0x261D, + }, + [0x261E]={ + category="so", + cjkwd="a", + description="WHITE RIGHT POINTING INDEX", + direction="on", + linebreak="ai", + unicodeslot=0x261E, + }, + [0x261F]={ + category="so", + description="WHITE DOWN POINTING INDEX", + direction="on", + linebreak="al", + unicodeslot=0x261F, + }, + [0x2620]={ + category="so", + description="SKULL AND CROSSBONES", + direction="on", + linebreak="al", + unicodeslot=0x2620, + }, + [0x2621]={ + category="so", + description="CAUTION SIGN", + direction="on", + linebreak="al", + unicodeslot=0x2621, + }, + [0x2622]={ + category="so", + description="RADIOACTIVE SIGN", + direction="on", + linebreak="al", + unicodeslot=0x2622, + }, + [0x2623]={ + category="so", + description="BIOHAZARD SIGN", + direction="on", + linebreak="al", + unicodeslot=0x2623, + }, + [0x2624]={ + category="so", + description="CADUCEUS", + direction="on", + linebreak="al", + unicodeslot=0x2624, + }, + [0x2625]={ + category="so", + description="ANKH", + direction="on", + linebreak="al", + unicodeslot=0x2625, + }, + [0x2626]={ + category="so", + description="ORTHODOX CROSS", + direction="on", + linebreak="al", + unicodeslot=0x2626, + }, + [0x2627]={ + category="so", + description="CHI RHO", + direction="on", + linebreak="al", + unicodeslot=0x2627, + }, + [0x2628]={ + category="so", + description="CROSS OF LORRAINE", + direction="on", + linebreak="al", + unicodeslot=0x2628, + }, + [0x2629]={ + category="so", + description="CROSS OF JERUSALEM", + direction="on", + linebreak="al", + unicodeslot=0x2629, + }, + [0x262A]={ + category="so", + description="STAR AND CRESCENT", + direction="on", + linebreak="al", + unicodeslot=0x262A, + }, + [0x262B]={ + category="so", + description="FARSI SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x262B, + }, + [0x262C]={ + category="so", + description="ADI SHAKTI", + direction="on", + linebreak="al", + unicodeslot=0x262C, + }, + [0x262D]={ + category="so", + description="HAMMER AND SICKLE", + direction="on", + linebreak="al", + unicodeslot=0x262D, + }, + [0x262E]={ + category="so", + description="PEACE SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x262E, + }, + [0x262F]={ + category="so", + description="YIN YANG", + direction="on", + linebreak="al", + unicodeslot=0x262F, + }, + [0x2630]={ + category="so", + description="TRIGRAM FOR HEAVEN", + direction="on", + linebreak="al", + unicodeslot=0x2630, + }, + [0x2631]={ + category="so", + description="TRIGRAM FOR LAKE", + direction="on", + linebreak="al", + unicodeslot=0x2631, + }, + [0x2632]={ + category="so", + description="TRIGRAM FOR FIRE", + direction="on", + linebreak="al", + unicodeslot=0x2632, + }, + [0x2633]={ + category="so", + description="TRIGRAM FOR THUNDER", + direction="on", + linebreak="al", + unicodeslot=0x2633, + }, + [0x2634]={ + category="so", + description="TRIGRAM FOR WIND", + direction="on", + linebreak="al", + unicodeslot=0x2634, + }, + [0x2635]={ + category="so", + description="TRIGRAM FOR WATER", + direction="on", + linebreak="al", + unicodeslot=0x2635, + }, + [0x2636]={ + category="so", + description="TRIGRAM FOR MOUNTAIN", + direction="on", + linebreak="al", + unicodeslot=0x2636, + }, + [0x2637]={ + category="so", + description="TRIGRAM FOR EARTH", + direction="on", + linebreak="al", + unicodeslot=0x2637, + }, + [0x2638]={ + category="so", + description="WHEEL OF DHARMA", + direction="on", + linebreak="al", + unicodeslot=0x2638, + }, + [0x2639]={ + category="so", + description="WHITE FROWNING FACE", + direction="on", + linebreak="al", + unicodeslot=0x2639, + }, + [0x263A]={ + adobename="smileface", + category="so", + description="WHITE SMILING FACE", + direction="on", + linebreak="al", + unicodeslot=0x263A, + }, + [0x263B]={ + adobename="invsmileface", + category="so", + description="BLACK SMILING FACE", + direction="on", + linebreak="al", + unicodeslot=0x263B, + }, + [0x263C]={ + adobename="sun", + category="so", + description="WHITE SUN WITH RAYS", + direction="on", + linebreak="al", + unicodeslot=0x263C, + }, + [0x263D]={ + category="so", + description="FIRST QUARTER MOON", + direction="on", + linebreak="al", + unicodeslot=0x263D, + }, + [0x263E]={ + category="so", + description="LAST QUARTER MOON", + direction="on", + linebreak="al", + unicodeslot=0x263E, + }, + [0x263F]={ + category="so", + description="MERCURY", + direction="on", + linebreak="al", + unicodeslot=0x263F, + }, + [0x2640]={ + adobename="female", + category="so", + cjkwd="a", + description="FEMALE SIGN", + direction="on", + linebreak="ai", + unicodeslot=0x2640, + }, + [0x2641]={ + category="so", + description="EARTH", + direction="on", + linebreak="al", + unicodeslot=0x2641, + }, + [0x2642]={ + adobename="male", + category="so", + cjkwd="a", + description="MALE SIGN", + direction="on", + linebreak="ai", + unicodeslot=0x2642, + }, + [0x2643]={ + category="so", + description="JUPITER", + direction="on", + linebreak="al", + unicodeslot=0x2643, + }, + [0x2644]={ + category="so", + description="SATURN", + direction="on", + linebreak="al", + unicodeslot=0x2644, + }, + [0x2645]={ + category="so", + description="URANUS", + direction="on", + linebreak="al", + unicodeslot=0x2645, + }, + [0x2646]={ + category="so", + description="NEPTUNE", + direction="on", + linebreak="al", + unicodeslot=0x2646, + }, + [0x2647]={ + category="so", + description="PLUTO", + direction="on", + linebreak="al", + unicodeslot=0x2647, + }, + [0x2648]={ + category="so", + description="ARIES", + direction="on", + linebreak="al", + unicodeslot=0x2648, + }, + [0x2649]={ + category="so", + description="TAURUS", + direction="on", + linebreak="al", + unicodeslot=0x2649, + }, + [0x264A]={ + category="so", + description="GEMINI", + direction="on", + linebreak="al", + unicodeslot=0x264A, + }, + [0x264B]={ + category="so", + description="CANCER", + direction="on", + linebreak="al", + unicodeslot=0x264B, + }, + [0x264C]={ + category="so", + description="LEO", + direction="on", + linebreak="al", + unicodeslot=0x264C, + }, + [0x264D]={ + category="so", + description="VIRGO", + direction="on", + linebreak="al", + unicodeslot=0x264D, + }, + [0x264E]={ + category="so", + description="LIBRA", + direction="on", + linebreak="al", + unicodeslot=0x264E, + }, + [0x264F]={ + category="so", + description="SCORPIUS", + direction="on", + linebreak="al", + unicodeslot=0x264F, + }, + [0x2650]={ + category="so", + description="SAGITTARIUS", + direction="on", + linebreak="al", + unicodeslot=0x2650, + }, + [0x2651]={ + category="so", + description="CAPRICORN", + direction="on", + linebreak="al", + unicodeslot=0x2651, + }, + [0x2652]={ + category="so", + description="AQUARIUS", + direction="on", + linebreak="al", + unicodeslot=0x2652, + }, + [0x2653]={ + category="so", + description="PISCES", + direction="on", + linebreak="al", + unicodeslot=0x2653, + }, + [0x2654]={ + category="so", + description="WHITE CHESS KING", + direction="on", + linebreak="al", + unicodeslot=0x2654, + }, + [0x2655]={ + category="so", + description="WHITE CHESS QUEEN", + direction="on", + linebreak="al", + unicodeslot=0x2655, + }, + [0x2656]={ + category="so", + description="WHITE CHESS ROOK", + direction="on", + linebreak="al", + unicodeslot=0x2656, + }, + [0x2657]={ + category="so", + description="WHITE CHESS BISHOP", + direction="on", + linebreak="al", + unicodeslot=0x2657, + }, + [0x2658]={ + category="so", + description="WHITE CHESS KNIGHT", + direction="on", + linebreak="al", + unicodeslot=0x2658, + }, + [0x2659]={ + category="so", + description="WHITE CHESS PAWN", + direction="on", + linebreak="al", + unicodeslot=0x2659, + }, + [0x265A]={ + category="so", + description="BLACK CHESS KING", + direction="on", + linebreak="al", + unicodeslot=0x265A, + }, + [0x265B]={ + category="so", + description="BLACK CHESS QUEEN", + direction="on", + linebreak="al", + unicodeslot=0x265B, + }, + [0x265C]={ + category="so", + description="BLACK CHESS ROOK", + direction="on", + linebreak="al", + unicodeslot=0x265C, + }, + [0x265D]={ + category="so", + description="BLACK CHESS BISHOP", + direction="on", + linebreak="al", + unicodeslot=0x265D, + }, + [0x265E]={ + category="so", + description="BLACK CHESS KNIGHT", + direction="on", + linebreak="al", + unicodeslot=0x265E, + }, + [0x265F]={ + category="so", + description="BLACK CHESS PAWN", + direction="on", + linebreak="al", + unicodeslot=0x265F, + }, + [0x2660]={ + adobename="spade", + category="so", + cjkwd="a", + description="BLACK SPADE SUIT", + direction="on", + linebreak="ai", + mathclass="default", + mathname="spadesuit", + unicodeslot=0x2660, + }, + [0x2661]={ + category="so", + cjkwd="a", + description="WHITE HEART SUIT", + direction="on", + linebreak="ai", + mathclass="default", + mathname="heartsuit", + unicodeslot=0x2661, + }, + [0x2662]={ + category="so", + description="WHITE DIAMOND SUIT", + direction="on", + linebreak="al", + mathclass="default", + mathname="diamondsuit", + unicodeslot=0x2662, + }, + [0x2663]={ + adobename="club", + category="so", + cjkwd="a", + description="BLACK CLUB SUIT", + direction="on", + linebreak="ai", + mathclass="default", + mathname="clubsuit", + unicodeslot=0x2663, + }, + [0x2664]={ + category="so", + cjkwd="a", + description="WHITE SPADE SUIT", + direction="on", + linebreak="ai", + unicodeslot=0x2664, + }, + [0x2665]={ + adobename="heart", + category="so", + cjkwd="a", + description="BLACK HEART SUIT", + direction="on", + linebreak="ai", + unicodeslot=0x2665, + }, + [0x2666]={ + adobename="diamond", + category="so", + description="BLACK DIAMOND SUIT", + direction="on", + linebreak="al", + unicodeslot=0x2666, + }, + [0x2667]={ + category="so", + cjkwd="a", + description="WHITE CLUB SUIT", + direction="on", + linebreak="ai", + unicodeslot=0x2667, + }, + [0x2668]={ + category="so", + cjkwd="a", + description="HOT SPRINGS", + direction="on", + linebreak="ai", + unicodeslot=0x2668, + }, + [0x2669]={ + category="so", + cjkwd="a", + description="QUARTER NOTE", + direction="on", + linebreak="ai", + unicodeslot=0x2669, + }, + [0x266A]={ + adobename="musicalnote", + category="so", + cjkwd="a", + description="EIGHTH NOTE", + direction="on", + linebreak="ai", + unicodeslot=0x266A, + }, + [0x266B]={ + adobename="musicalnotedbl", + category="so", + description="BEAMED EIGHTH NOTES", + direction="on", + linebreak="al", + unicodeslot=0x266B, + }, + [0x266C]={ + category="so", + cjkwd="a", + description="BEAMED SIXTEENTH NOTES", + direction="on", + linebreak="ai", + unicodeslot=0x266C, + }, + [0x266D]={ + category="so", + cjkwd="a", + description="MUSIC FLAT SIGN", + direction="on", + linebreak="ai", + mathclass="default", + mathname="flat", + unicodeslot=0x266D, + }, + [0x266E]={ + category="so", + description="MUSIC NATURAL SIGN", + direction="on", + linebreak="al", + mathclass="default", + mathname="natural", + unicodeslot=0x266E, + }, + [0x266F]={ + category="sm", + cjkwd="a", + description="MUSIC SHARP SIGN", + direction="on", + linebreak="ai", + mathclass="default", + mathname="sharp", + unicodeslot=0x266F, + }, + [0x2670]={ + category="so", + description="WEST SYRIAC CROSS", + direction="on", + linebreak="al", + unicodeslot=0x2670, + }, + [0x2671]={ + category="so", + description="EAST SYRIAC CROSS", + direction="on", + linebreak="al", + unicodeslot=0x2671, + }, + [0x2672]={ + category="so", + description="UNIVERSAL RECYCLING SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x2672, + }, + [0x2673]={ + category="so", + description="RECYCLING SYMBOL FOR TYPE-0x0001 PLASTICS", + direction="on", + linebreak="al", + unicodeslot=0x2673, + }, + [0x2674]={ + category="so", + description="RECYCLING SYMBOL FOR TYPE-0x0002 PLASTICS", + direction="on", + linebreak="al", + unicodeslot=0x2674, + }, + [0x2675]={ + category="so", + description="RECYCLING SYMBOL FOR TYPE-0x0003 PLASTICS", + direction="on", + linebreak="al", + unicodeslot=0x2675, + }, + [0x2676]={ + category="so", + description="RECYCLING SYMBOL FOR TYPE-0x0004 PLASTICS", + direction="on", + linebreak="al", + unicodeslot=0x2676, + }, + [0x2677]={ + category="so", + description="RECYCLING SYMBOL FOR TYPE-0x0005 PLASTICS", + direction="on", + linebreak="al", + unicodeslot=0x2677, + }, + [0x2678]={ + category="so", + description="RECYCLING SYMBOL FOR TYPE-0x0006 PLASTICS", + direction="on", + linebreak="al", + unicodeslot=0x2678, + }, + [0x2679]={ + category="so", + description="RECYCLING SYMBOL FOR TYPE-0x0007 PLASTICS", + direction="on", + linebreak="al", + unicodeslot=0x2679, + }, + [0x267A]={ + category="so", + description="RECYCLING SYMBOL FOR GENERIC MATERIALS", + direction="on", + linebreak="al", + unicodeslot=0x267A, + }, + [0x267B]={ + category="so", + description="BLACK UNIVERSAL RECYCLING SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x267B, + }, + [0x267C]={ + category="so", + description="RECYCLED PAPER SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x267C, + }, + [0x267D]={ + category="so", + description="PARTIALLY-RECYCLED PAPER SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x267D, + }, + [0x267E]={ + category="so", + description="PERMANENT PAPER SIGN", + direction="on", + linebreak="al", + unicodeslot=0x267E, + }, + [0x267F]={ + category="so", + description="WHEELCHAIR SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x267F, + }, + [0x2680]={ + category="so", + description="DIE FACE-0x0001", + direction="on", + linebreak="al", + unicodeslot=0x2680, + }, + [0x2681]={ + category="so", + description="DIE FACE-0x0002", + direction="on", + linebreak="al", + unicodeslot=0x2681, + }, + [0x2682]={ + category="so", + description="DIE FACE-0x0003", + direction="on", + linebreak="al", + unicodeslot=0x2682, + }, + [0x2683]={ + category="so", + description="DIE FACE-0x0004", + direction="on", + linebreak="al", + unicodeslot=0x2683, + }, + [0x2684]={ + category="so", + description="DIE FACE-0x0005", + direction="on", + linebreak="al", + unicodeslot=0x2684, + }, + [0x2685]={ + category="so", + description="DIE FACE-0x0006", + direction="on", + linebreak="al", + unicodeslot=0x2685, + }, + [0x2686]={ + category="so", + description="WHITE CIRCLE WITH DOT RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x2686, + }, + [0x2687]={ + category="so", + description="WHITE CIRCLE WITH TWO DOTS", + direction="on", + linebreak="al", + unicodeslot=0x2687, + }, + [0x2688]={ + category="so", + description="BLACK CIRCLE WITH WHITE DOT RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x2688, + }, + [0x2689]={ + category="so", + description="BLACK CIRCLE WITH TWO WHITE DOTS", + direction="on", + linebreak="al", + unicodeslot=0x2689, + }, + [0x268A]={ + category="so", + description="MONOGRAM FOR YANG", + direction="on", + linebreak="al", + unicodeslot=0x268A, + }, + [0x268B]={ + category="so", + description="MONOGRAM FOR YIN", + direction="on", + linebreak="al", + unicodeslot=0x268B, + }, + [0x268C]={ + category="so", + description="DIGRAM FOR GREATER YANG", + direction="on", + linebreak="al", + unicodeslot=0x268C, + }, + [0x268D]={ + category="so", + description="DIGRAM FOR LESSER YIN", + direction="on", + linebreak="al", + unicodeslot=0x268D, + }, + [0x268E]={ + category="so", + description="DIGRAM FOR LESSER YANG", + direction="on", + linebreak="al", + unicodeslot=0x268E, + }, + [0x268F]={ + category="so", + description="DIGRAM FOR GREATER YIN", + direction="on", + linebreak="al", + unicodeslot=0x268F, + }, + [0x2690]={ + category="so", + description="WHITE FLAG", + direction="on", + linebreak="al", + unicodeslot=0x2690, + }, + [0x2691]={ + category="so", + description="BLACK FLAG", + direction="on", + linebreak="al", + unicodeslot=0x2691, + }, + [0x2692]={ + category="so", + description="HAMMER AND PICK", + direction="on", + linebreak="al", + unicodeslot=0x2692, + }, + [0x2693]={ + category="so", + description="ANCHOR", + direction="on", + linebreak="al", + unicodeslot=0x2693, + }, + [0x2694]={ + category="so", + description="CROSSED SWORDS", + direction="on", + linebreak="al", + unicodeslot=0x2694, + }, + [0x2695]={ + category="so", + description="STAFF OF AESCULAPIUS", + direction="on", + linebreak="al", + unicodeslot=0x2695, + }, + [0x2696]={ + category="so", + description="SCALES", + direction="on", + linebreak="al", + unicodeslot=0x2696, + }, + [0x2697]={ + category="so", + description="ALEMBIC", + direction="on", + linebreak="al", + unicodeslot=0x2697, + }, + [0x2698]={ + category="so", + description="FLOWER", + direction="on", + linebreak="al", + unicodeslot=0x2698, + }, + [0x2699]={ + category="so", + description="GEAR", + direction="on", + linebreak="al", + unicodeslot=0x2699, + }, + [0x269A]={ + category="so", + description="STAFF OF HERMES", + direction="on", + linebreak="al", + unicodeslot=0x269A, + }, + [0x269B]={ + category="so", + description="ATOM SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x269B, + }, + [0x269C]={ + category="so", + description="FLEUR-DE-LIS", + direction="on", + linebreak="al", + unicodeslot=0x269C, + }, + [0x26A0]={ + category="so", + description="WARNING SIGN", + direction="on", + linebreak="al", + unicodeslot=0x26A0, + }, + [0x26A1]={ + category="so", + description="HIGH VOLTAGE SIGN", + direction="on", + linebreak="al", + unicodeslot=0x26A1, + }, + [0x26A2]={ + category="so", + description="DOUBLED FEMALE SIGN", + direction="on", + linebreak="al", + unicodeslot=0x26A2, + }, + [0x26A3]={ + category="so", + description="DOUBLED MALE SIGN", + direction="on", + linebreak="al", + unicodeslot=0x26A3, + }, + [0x26A4]={ + category="so", + description="INTERLOCKED FEMALE AND MALE SIGN", + direction="on", + linebreak="al", + unicodeslot=0x26A4, + }, + [0x26A5]={ + category="so", + description="MALE AND FEMALE SIGN", + direction="on", + linebreak="al", + unicodeslot=0x26A5, + }, + [0x26A6]={ + category="so", + description="MALE WITH STROKE SIGN", + direction="on", + linebreak="al", + unicodeslot=0x26A6, + }, + [0x26A7]={ + category="so", + description="MALE WITH STROKE AND MALE AND FEMALE SIGN", + direction="on", + linebreak="al", + unicodeslot=0x26A7, + }, + [0x26A8]={ + category="so", + description="VERTICAL MALE WITH STROKE SIGN", + direction="on", + linebreak="al", + unicodeslot=0x26A8, + }, + [0x26A9]={ + category="so", + description="HORIZONTAL MALE WITH STROKE SIGN", + direction="on", + linebreak="al", + unicodeslot=0x26A9, + }, + [0x26AA]={ + category="so", + description="MEDIUM WHITE CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x26AA, + }, + [0x26AB]={ + category="so", + description="MEDIUM BLACK CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x26AB, + }, + [0x26AC]={ + category="so", + description="MEDIUM SMALL WHITE CIRCLE", + direction="l", + linebreak="al", + unicodeslot=0x26AC, + }, + [0x26AD]={ + category="so", + description="MARRIAGE SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x26AD, + }, + [0x26AE]={ + category="so", + description="DIVORCE SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x26AE, + }, + [0x26AF]={ + category="so", + description="UNMARRIED PARTNERSHIP SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x26AF, + }, + [0x26B0]={ + category="so", + description="COFFIN", + direction="on", + linebreak="al", + unicodeslot=0x26B0, + }, + [0x26B1]={ + category="so", + description="FUNERAL URN", + direction="on", + linebreak="al", + unicodeslot=0x26B1, + }, + [0x26B2]={ + category="so", + description="NEUTER", + direction="on", + linebreak="al", + unicodeslot=0x26B2, + }, + [0x2701]={ + category="so", + description="UPPER BLADE SCISSORS", + direction="on", + linebreak="al", + unicodeslot=0x2701, + }, + [0x2702]={ + category="so", + description="BLACK SCISSORS", + direction="on", + linebreak="al", + unicodeslot=0x2702, + }, + [0x2703]={ + category="so", + description="LOWER BLADE SCISSORS", + direction="on", + linebreak="al", + unicodeslot=0x2703, + }, + [0x2704]={ + category="so", + description="WHITE SCISSORS", + direction="on", + linebreak="al", + unicodeslot=0x2704, + }, + [0x2706]={ + category="so", + description="TELEPHONE LOCATION SIGN", + direction="on", + linebreak="al", + unicodeslot=0x2706, + }, + [0x2707]={ + category="so", + description="TAPE DRIVE", + direction="on", + linebreak="al", + unicodeslot=0x2707, + }, + [0x2708]={ + category="so", + description="AIRPLANE", + direction="on", + linebreak="al", + unicodeslot=0x2708, + }, + [0x2709]={ + category="so", + description="ENVELOPE", + direction="on", + linebreak="al", + unicodeslot=0x2709, + }, + [0x270C]={ + category="so", + description="VICTORY HAND", + direction="on", + linebreak="al", + unicodeslot=0x270C, + }, + [0x270D]={ + category="so", + description="WRITING HAND", + direction="on", + linebreak="al", + unicodeslot=0x270D, + }, + [0x270E]={ + category="so", + description="LOWER RIGHT PENCIL", + direction="on", + linebreak="al", + unicodeslot=0x270E, + }, + [0x270F]={ + category="so", + description="PENCIL", + direction="on", + linebreak="al", + unicodeslot=0x270F, + }, + [0x2710]={ + category="so", + description="UPPER RIGHT PENCIL", + direction="on", + linebreak="al", + unicodeslot=0x2710, + }, + [0x2711]={ + category="so", + description="WHITE NIB", + direction="on", + linebreak="al", + unicodeslot=0x2711, + }, + [0x2712]={ + category="so", + description="BLACK NIB", + direction="on", + linebreak="al", + unicodeslot=0x2712, + }, + [0x2713]={ + category="so", + description="CHECK MARK", + direction="on", + linebreak="al", + mathclass="nothing", + mathname="checkmark", + unicodeslot=0x2713, + }, + [0x2714]={ + category="so", + description="HEAVY CHECK MARK", + direction="on", + linebreak="al", + unicodeslot=0x2714, + }, + [0x2715]={ + category="so", + description="MULTIPLICATION X", + direction="on", + linebreak="al", + unicodeslot=0x2715, + }, + [0x2716]={ + category="so", + description="HEAVY MULTIPLICATION X", + direction="on", + linebreak="al", + unicodeslot=0x2716, + }, + [0x2717]={ + category="so", + description="BALLOT X", + direction="on", + linebreak="al", + unicodeslot=0x2717, + }, + [0x2718]={ + category="so", + description="HEAVY BALLOT X", + direction="on", + linebreak="al", + unicodeslot=0x2718, + }, + [0x2719]={ + category="so", + description="OUTLINED GREEK CROSS", + direction="on", + linebreak="al", + unicodeslot=0x2719, + }, + [0x271A]={ + category="so", + description="HEAVY GREEK CROSS", + direction="on", + linebreak="al", + unicodeslot=0x271A, + }, + [0x271B]={ + category="so", + description="OPEN CENTRE CROSS", + direction="on", + linebreak="al", + unicodeslot=0x271B, + }, + [0x271C]={ + category="so", + description="HEAVY OPEN CENTRE CROSS", + direction="on", + linebreak="al", + unicodeslot=0x271C, + }, + [0x271D]={ + category="so", + description="LATIN CROSS", + direction="on", + linebreak="al", + unicodeslot=0x271D, + }, + [0x271E]={ + category="so", + description="SHADOWED WHITE LATIN CROSS", + direction="on", + linebreak="al", + unicodeslot=0x271E, + }, + [0x271F]={ + category="so", + description="OUTLINED LATIN CROSS", + direction="on", + linebreak="al", + unicodeslot=0x271F, + }, + [0x2720]={ + category="so", + description="MALTESE CROSS", + direction="on", + linebreak="al", + mathclass="nothing", + mathname="maltese", + unicodeslot=0x2720, + }, + [0x2721]={ + category="so", + description="STAR OF DAVID", + direction="on", + linebreak="al", + unicodeslot=0x2721, + }, + [0x2722]={ + category="so", + description="FOUR TEARDROP-SPOKED ASTERISK", + direction="on", + linebreak="al", + unicodeslot=0x2722, + }, + [0x2723]={ + category="so", + description="FOUR BALLOON-SPOKED ASTERISK", + direction="on", + linebreak="al", + unicodeslot=0x2723, + }, + [0x2724]={ + category="so", + description="HEAVY FOUR BALLOON-SPOKED ASTERISK", + direction="on", + linebreak="al", + unicodeslot=0x2724, + }, + [0x2725]={ + category="so", + description="FOUR CLUB-SPOKED ASTERISK", + direction="on", + linebreak="al", + unicodeslot=0x2725, + }, + [0x2726]={ + category="so", + description="BLACK FOUR POINTED STAR", + direction="on", + linebreak="al", + unicodeslot=0x2726, + }, + [0x2727]={ + category="so", + description="WHITE FOUR POINTED STAR", + direction="on", + linebreak="al", + unicodeslot=0x2727, + }, + [0x2729]={ + category="so", + description="STRESS OUTLINED WHITE STAR", + direction="on", + linebreak="al", + unicodeslot=0x2729, + }, + [0x272A]={ + category="so", + description="CIRCLED WHITE STAR", + direction="on", + linebreak="al", + unicodeslot=0x272A, + }, + [0x272B]={ + category="so", + description="OPEN CENTRE BLACK STAR", + direction="on", + linebreak="al", + unicodeslot=0x272B, + }, + [0x272C]={ + category="so", + description="BLACK CENTRE WHITE STAR", + direction="on", + linebreak="al", + unicodeslot=0x272C, + }, + [0x272D]={ + category="so", + description="OUTLINED BLACK STAR", + direction="on", + linebreak="al", + unicodeslot=0x272D, + }, + [0x272E]={ + category="so", + description="HEAVY OUTLINED BLACK STAR", + direction="on", + linebreak="al", + unicodeslot=0x272E, + }, + [0x272F]={ + category="so", + description="PINWHEEL STAR", + direction="on", + linebreak="al", + unicodeslot=0x272F, + }, + [0x2730]={ + category="so", + description="SHADOWED WHITE STAR", + direction="on", + linebreak="al", + unicodeslot=0x2730, + }, + [0x2731]={ + category="so", + description="HEAVY ASTERISK", + direction="on", + linebreak="al", + unicodeslot=0x2731, + }, + [0x2732]={ + category="so", + description="OPEN CENTRE ASTERISK", + direction="on", + linebreak="al", + unicodeslot=0x2732, + }, + [0x2733]={ + category="so", + description="EIGHT SPOKED ASTERISK", + direction="on", + linebreak="al", + unicodeslot=0x2733, + }, + [0x2734]={ + category="so", + description="EIGHT POINTED BLACK STAR", + direction="on", + linebreak="al", + unicodeslot=0x2734, + }, + [0x2735]={ + category="so", + description="EIGHT POINTED PINWHEEL STAR", + direction="on", + linebreak="al", + unicodeslot=0x2735, + }, + [0x2736]={ + category="so", + description="SIX POINTED BLACK STAR", + direction="on", + linebreak="al", + unicodeslot=0x2736, + }, + [0x2737]={ + category="so", + description="EIGHT POINTED RECTILINEAR BLACK STAR", + direction="on", + linebreak="al", + unicodeslot=0x2737, + }, + [0x2738]={ + category="so", + description="HEAVY EIGHT POINTED RECTILINEAR BLACK STAR", + direction="on", + linebreak="al", + unicodeslot=0x2738, + }, + [0x2739]={ + category="so", + description="TWELVE POINTED BLACK STAR", + direction="on", + linebreak="al", + unicodeslot=0x2739, + }, + [0x273A]={ + category="so", + description="SIXTEEN POINTED ASTERISK", + direction="on", + linebreak="al", + unicodeslot=0x273A, + }, + [0x273B]={ + category="so", + description="TEARDROP-SPOKED ASTERISK", + direction="on", + linebreak="al", + unicodeslot=0x273B, + }, + [0x273C]={ + category="so", + description="OPEN CENTRE TEARDROP-SPOKED ASTERISK", + direction="on", + linebreak="al", + unicodeslot=0x273C, + }, + [0x273D]={ + category="so", + cjkwd="a", + description="HEAVY TEARDROP-SPOKED ASTERISK", + direction="on", + linebreak="al", + unicodeslot=0x273D, + }, + [0x273E]={ + category="so", + description="SIX PETALLED BLACK AND WHITE FLORETTE", + direction="on", + linebreak="al", + unicodeslot=0x273E, + }, + [0x273F]={ + category="so", + description="BLACK FLORETTE", + direction="on", + linebreak="al", + unicodeslot=0x273F, + }, + [0x2740]={ + category="so", + description="WHITE FLORETTE", + direction="on", + linebreak="al", + unicodeslot=0x2740, + }, + [0x2741]={ + category="so", + description="EIGHT PETALLED OUTLINED BLACK FLORETTE", + direction="on", + linebreak="al", + unicodeslot=0x2741, + }, + [0x2742]={ + category="so", + description="CIRCLED OPEN CENTRE EIGHT POINTED STAR", + direction="on", + linebreak="al", + unicodeslot=0x2742, + }, + [0x2743]={ + category="so", + description="HEAVY TEARDROP-SPOKED PINWHEEL ASTERISK", + direction="on", + linebreak="al", + unicodeslot=0x2743, + }, + [0x2744]={ + category="so", + description="SNOWFLAKE", + direction="on", + linebreak="al", + unicodeslot=0x2744, + }, + [0x2745]={ + category="so", + description="TIGHT TRIFOLIATE SNOWFLAKE", + direction="on", + linebreak="al", + unicodeslot=0x2745, + }, + [0x2746]={ + category="so", + description="HEAVY CHEVRON SNOWFLAKE", + direction="on", + linebreak="al", + unicodeslot=0x2746, + }, + [0x2747]={ + category="so", + description="SPARKLE", + direction="on", + linebreak="al", + unicodeslot=0x2747, + }, + [0x2748]={ + category="so", + description="HEAVY SPARKLE", + direction="on", + linebreak="al", + unicodeslot=0x2748, + }, + [0x2749]={ + category="so", + description="BALLOON-SPOKED ASTERISK", + direction="on", + linebreak="al", + unicodeslot=0x2749, + }, + [0x274A]={ + category="so", + description="EIGHT TEARDROP-SPOKED PROPELLER ASTERISK", + direction="on", + linebreak="al", + unicodeslot=0x274A, + }, + [0x274B]={ + category="so", + description="HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK", + direction="on", + linebreak="al", + unicodeslot=0x274B, + }, + [0x274D]={ + category="so", + description="SHADOWED WHITE CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x274D, + }, + [0x274F]={ + category="so", + description="LOWER RIGHT DROP-SHADOWED WHITE SQUARE", + direction="on", + linebreak="al", + unicodeslot=0x274F, + }, + [0x2750]={ + category="so", + description="UPPER RIGHT DROP-SHADOWED WHITE SQUARE", + direction="on", + linebreak="al", + unicodeslot=0x2750, + }, + [0x2751]={ + category="so", + description="LOWER RIGHT SHADOWED WHITE SQUARE", + direction="on", + linebreak="al", + unicodeslot=0x2751, + }, + [0x2752]={ + category="so", + description="UPPER RIGHT SHADOWED WHITE SQUARE", + direction="on", + linebreak="al", + unicodeslot=0x2752, + }, + [0x2756]={ + category="so", + description="BLACK DIAMOND MINUS WHITE X", + direction="on", + linebreak="al", + unicodeslot=0x2756, + }, + [0x2758]={ + category="so", + description="LIGHT VERTICAL BAR", + direction="on", + linebreak="al", + unicodeslot=0x2758, + }, + [0x2759]={ + category="so", + description="MEDIUM VERTICAL BAR", + direction="on", + linebreak="al", + unicodeslot=0x2759, + }, + [0x275A]={ + category="so", + description="HEAVY VERTICAL BAR", + direction="on", + linebreak="al", + unicodeslot=0x275A, + }, + [0x275B]={ + category="so", + description="HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT", + direction="on", + linebreak="qu", + unicodeslot=0x275B, + }, + [0x275C]={ + category="so", + description="HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT", + direction="on", + linebreak="qu", + unicodeslot=0x275C, + }, + [0x275D]={ + category="so", + description="HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT", + direction="on", + linebreak="qu", + unicodeslot=0x275D, + }, + [0x275E]={ + category="so", + description="HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT", + direction="on", + linebreak="qu", + unicodeslot=0x275E, + }, + [0x2761]={ + category="so", + description="CURVED STEM PARAGRAPH SIGN ORNAMENT", + direction="on", + linebreak="al", + unicodeslot=0x2761, + }, + [0x2762]={ + category="so", + description="HEAVY EXCLAMATION MARK ORNAMENT", + direction="on", + linebreak="ex", + unicodeslot=0x2762, + }, + [0x2763]={ + category="so", + description="HEAVY HEART EXCLAMATION MARK ORNAMENT", + direction="on", + linebreak="ex", + unicodeslot=0x2763, + }, + [0x2764]={ + category="so", + description="HEAVY BLACK HEART", + direction="on", + linebreak="al", + unicodeslot=0x2764, + }, + [0x2765]={ + category="so", + description="ROTATED HEAVY BLACK HEART BULLET", + direction="on", + linebreak="al", + unicodeslot=0x2765, + }, + [0x2766]={ + category="so", + description="FLORAL HEART", + direction="on", + linebreak="al", + unicodeslot=0x2766, + }, + [0x2767]={ + category="so", + description="ROTATED FLORAL HEART BULLET", + direction="on", + linebreak="al", + unicodeslot=0x2767, + }, + [0x2768]={ + category="ps", + description="MEDIUM LEFT PARENTHESIS ORNAMENT", + direction="on", + linebreak="op", + mirror=0x2769, + unicodeslot=0x2768, + }, + [0x2769]={ + category="pe", + description="MEDIUM RIGHT PARENTHESIS ORNAMENT", + direction="on", + linebreak="cl", + mirror=0x2768, + unicodeslot=0x2769, + }, + [0x276A]={ + category="ps", + description="MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT", + direction="on", + linebreak="op", + mirror=0x276B, + unicodeslot=0x276A, + }, + [0x276B]={ + category="pe", + description="MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT", + direction="on", + linebreak="cl", + mirror=0x276A, + unicodeslot=0x276B, + }, + [0x276C]={ + category="ps", + description="MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT", + direction="on", + linebreak="op", + mirror=0x276D, + unicodeslot=0x276C, + }, + [0x276D]={ + category="pe", + description="MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT", + direction="on", + linebreak="cl", + mirror=0x276C, + unicodeslot=0x276D, + }, + [0x276E]={ + category="ps", + description="HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT", + direction="on", + linebreak="op", + mirror=0x276F, + unicodeslot=0x276E, + }, + [0x276F]={ + category="pe", + description="HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT", + direction="on", + linebreak="cl", + mirror=0x276E, + unicodeslot=0x276F, + }, + [0x2770]={ + category="ps", + description="HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT", + direction="on", + linebreak="op", + mirror=0x2771, + unicodeslot=0x2770, + }, + [0x2771]={ + category="pe", + description="HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT", + direction="on", + linebreak="cl", + mirror=0x2770, + unicodeslot=0x2771, + }, + [0x2772]={ + category="ps", + description="LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT", + direction="on", + linebreak="op", + mirror=0x2773, + unicodeslot=0x2772, + }, + [0x2773]={ + category="pe", + description="LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT", + direction="on", + linebreak="cl", + mirror=0x2772, + unicodeslot=0x2773, + }, + [0x2774]={ + category="ps", + description="MEDIUM LEFT CURLY BRACKET ORNAMENT", + direction="on", + linebreak="op", + mirror=0x2775, + unicodeslot=0x2774, + }, + [0x2775]={ + category="pe", + description="MEDIUM RIGHT CURLY BRACKET ORNAMENT", + direction="on", + linebreak="cl", + mirror=0x2774, + unicodeslot=0x2775, + }, + [0x2776]={ + category="no", + cjkwd="a", + description="DINGBAT NEGATIVE CIRCLED DIGIT ONE", + direction="on", + linebreak="ai", + unicodeslot=0x2776, + }, + [0x2777]={ + category="no", + cjkwd="a", + description="DINGBAT NEGATIVE CIRCLED DIGIT TWO", + direction="on", + linebreak="ai", + unicodeslot=0x2777, + }, + [0x2778]={ + category="no", + cjkwd="a", + description="DINGBAT NEGATIVE CIRCLED DIGIT THREE", + direction="on", + linebreak="ai", + unicodeslot=0x2778, + }, + [0x2779]={ + category="no", + cjkwd="a", + description="DINGBAT NEGATIVE CIRCLED DIGIT FOUR", + direction="on", + linebreak="ai", + unicodeslot=0x2779, + }, + [0x277A]={ + category="no", + cjkwd="a", + description="DINGBAT NEGATIVE CIRCLED DIGIT FIVE", + direction="on", + linebreak="ai", + unicodeslot=0x277A, + }, + [0x277B]={ + category="no", + cjkwd="a", + description="DINGBAT NEGATIVE CIRCLED DIGIT SIX", + direction="on", + linebreak="ai", + unicodeslot=0x277B, + }, + [0x277C]={ + category="no", + cjkwd="a", + description="DINGBAT NEGATIVE CIRCLED DIGIT SEVEN", + direction="on", + linebreak="ai", + unicodeslot=0x277C, + }, + [0x277D]={ + category="no", + cjkwd="a", + description="DINGBAT NEGATIVE CIRCLED DIGIT EIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x277D, + }, + [0x277E]={ + category="no", + cjkwd="a", + description="DINGBAT NEGATIVE CIRCLED DIGIT NINE", + direction="on", + linebreak="ai", + unicodeslot=0x277E, + }, + [0x277F]={ + category="no", + cjkwd="a", + description="DINGBAT NEGATIVE CIRCLED NUMBER TEN", + direction="on", + linebreak="ai", + unicodeslot=0x277F, + }, + [0x2780]={ + category="no", + description="DINGBAT CIRCLED SANS-SERIF DIGIT ONE", + direction="on", + linebreak="ai", + unicodeslot=0x2780, + }, + [0x2781]={ + category="no", + description="DINGBAT CIRCLED SANS-SERIF DIGIT TWO", + direction="on", + linebreak="ai", + unicodeslot=0x2781, + }, + [0x2782]={ + category="no", + description="DINGBAT CIRCLED SANS-SERIF DIGIT THREE", + direction="on", + linebreak="ai", + unicodeslot=0x2782, + }, + [0x2783]={ + category="no", + description="DINGBAT CIRCLED SANS-SERIF DIGIT FOUR", + direction="on", + linebreak="ai", + unicodeslot=0x2783, + }, + [0x2784]={ + category="no", + description="DINGBAT CIRCLED SANS-SERIF DIGIT FIVE", + direction="on", + linebreak="ai", + unicodeslot=0x2784, + }, + [0x2785]={ + category="no", + description="DINGBAT CIRCLED SANS-SERIF DIGIT SIX", + direction="on", + linebreak="ai", + unicodeslot=0x2785, + }, + [0x2786]={ + category="no", + description="DINGBAT CIRCLED SANS-SERIF DIGIT SEVEN", + direction="on", + linebreak="ai", + unicodeslot=0x2786, + }, + [0x2787]={ + category="no", + description="DINGBAT CIRCLED SANS-SERIF DIGIT EIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2787, + }, + [0x2788]={ + category="no", + description="DINGBAT CIRCLED SANS-SERIF DIGIT NINE", + direction="on", + linebreak="ai", + unicodeslot=0x2788, + }, + [0x2789]={ + category="no", + description="DINGBAT CIRCLED SANS-SERIF NUMBER TEN", + direction="on", + linebreak="ai", + unicodeslot=0x2789, + }, + [0x278A]={ + category="no", + description="DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE", + direction="on", + linebreak="ai", + unicodeslot=0x278A, + }, + [0x278B]={ + category="no", + description="DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT TWO", + direction="on", + linebreak="ai", + unicodeslot=0x278B, + }, + [0x278C]={ + category="no", + description="DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT THREE", + direction="on", + linebreak="ai", + unicodeslot=0x278C, + }, + [0x278D]={ + category="no", + description="DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FOUR", + direction="on", + linebreak="ai", + unicodeslot=0x278D, + }, + [0x278E]={ + category="no", + description="DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FIVE", + direction="on", + linebreak="ai", + unicodeslot=0x278E, + }, + [0x278F]={ + category="no", + description="DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SIX", + direction="on", + linebreak="ai", + unicodeslot=0x278F, + }, + [0x2790]={ + category="no", + description="DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SEVEN", + direction="on", + linebreak="ai", + unicodeslot=0x2790, + }, + [0x2791]={ + category="no", + description="DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT EIGHT", + direction="on", + linebreak="ai", + unicodeslot=0x2791, + }, + [0x2792]={ + category="no", + description="DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE", + direction="on", + linebreak="ai", + unicodeslot=0x2792, + }, + [0x2793]={ + category="no", + description="DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN", + direction="on", + linebreak="ai", + unicodeslot=0x2793, + }, + [0x2794]={ + category="so", + description="HEAVY WIDE-HEADED RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2794, + }, + [0x2798]={ + category="so", + description="HEAVY SOUTH EAST ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2798, + }, + [0x2799]={ + category="so", + description="HEAVY RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2799, + }, + [0x279A]={ + category="so", + description="HEAVY NORTH EAST ARROW", + direction="on", + linebreak="al", + unicodeslot=0x279A, + }, + [0x279B]={ + category="so", + description="DRAFTING POINT RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x279B, + }, + [0x279C]={ + category="so", + description="HEAVY ROUND-TIPPED RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x279C, + }, + [0x279D]={ + category="so", + description="TRIANGLE-HEADED RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x279D, + }, + [0x279E]={ + category="so", + description="HEAVY TRIANGLE-HEADED RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x279E, + }, + [0x279F]={ + category="so", + description="DASHED TRIANGLE-HEADED RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x279F, + }, + [0x27A0]={ + category="so", + description="HEAVY DASHED TRIANGLE-HEADED RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27A0, + }, + [0x27A1]={ + category="so", + description="BLACK RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27A1, + }, + [0x27A2]={ + category="so", + description="THREE-D TOP-LIGHTED RIGHTWARDS ARROWHEAD", + direction="on", + linebreak="al", + unicodeslot=0x27A2, + }, + [0x27A3]={ + category="so", + description="THREE-D BOTTOM-LIGHTED RIGHTWARDS ARROWHEAD", + direction="on", + linebreak="al", + unicodeslot=0x27A3, + }, + [0x27A4]={ + category="so", + description="BLACK RIGHTWARDS ARROWHEAD", + direction="on", + linebreak="al", + unicodeslot=0x27A4, + }, + [0x27A5]={ + category="so", + description="HEAVY BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27A5, + }, + [0x27A6]={ + category="so", + description="HEAVY BLACK CURVED UPWARDS AND RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27A6, + }, + [0x27A7]={ + category="so", + description="SQUAT BLACK RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27A7, + }, + [0x27A8]={ + category="so", + description="HEAVY CONCAVE-POINTED BLACK RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27A8, + }, + [0x27A9]={ + category="so", + description="RIGHT-SHADED WHITE RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27A9, + }, + [0x27AA]={ + category="so", + description="LEFT-SHADED WHITE RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27AA, + }, + [0x27AB]={ + category="so", + description="BACK-TILTED SHADOWED WHITE RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27AB, + }, + [0x27AC]={ + category="so", + description="FRONT-TILTED SHADOWED WHITE RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27AC, + }, + [0x27AD]={ + category="so", + description="HEAVY LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27AD, + }, + [0x27AE]={ + category="so", + description="HEAVY UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27AE, + }, + [0x27AF]={ + category="so", + description="NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27AF, + }, + [0x27B1]={ + category="so", + description="NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27B1, + }, + [0x27B2]={ + category="so", + description="CIRCLED HEAVY WHITE RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27B2, + }, + [0x27B3]={ + category="so", + description="WHITE-FEATHERED RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27B3, + }, + [0x27B4]={ + category="so", + description="BLACK-FEATHERED SOUTH EAST ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27B4, + }, + [0x27B5]={ + category="so", + description="BLACK-FEATHERED RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27B5, + }, + [0x27B6]={ + category="so", + description="BLACK-FEATHERED NORTH EAST ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27B6, + }, + [0x27B7]={ + category="so", + description="HEAVY BLACK-FEATHERED SOUTH EAST ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27B7, + }, + [0x27B8]={ + category="so", + description="HEAVY BLACK-FEATHERED RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27B8, + }, + [0x27B9]={ + category="so", + description="HEAVY BLACK-FEATHERED NORTH EAST ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27B9, + }, + [0x27BA]={ + category="so", + description="TEARDROP-BARBED RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27BA, + }, + [0x27BB]={ + category="so", + description="HEAVY TEARDROP-SHANKED RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27BB, + }, + [0x27BC]={ + category="so", + description="WEDGE-TAILED RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27BC, + }, + [0x27BD]={ + category="so", + description="HEAVY WEDGE-TAILED RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27BD, + }, + [0x27BE]={ + category="so", + description="OPEN-OUTLINED RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27BE, + }, + [0x27C0]={ + category="sm", + description="THREE DIMENSIONAL ANGLE", + direction="on", + linebreak="al", + unicodeslot=0x27C0, + }, + [0x27C1]={ + category="sm", + description="WHITE TRIANGLE CONTAINING SMALL WHITE TRIANGLE", + direction="on", + linebreak="al", + unicodeslot=0x27C1, + }, + [0x27C2]={ + category="sm", + description="PERPENDICULAR", + direction="on", + linebreak="al", + unicodeslot=0x27C2, + }, + [0x27C3]={ + category="sm", + description="OPEN SUBSET", + direction="on", + linebreak="al", + mirror=0x27C4, + unicodeslot=0x27C3, + }, + [0x27C4]={ + category="sm", + description="OPEN SUPERSET", + direction="on", + linebreak="al", + mirror=0x27C3, + unicodeslot=0x27C4, + }, + [0x27C5]={ + category="ps", + description="LEFT S-SHAPED BAG DELIMITER", + direction="on", + linebreak="op", + mirror=0x27C6, + unicodeslot=0x27C5, + }, + [0x27C6]={ + category="pe", + description="RIGHT S-SHAPED BAG DELIMITER", + direction="on", + linebreak="cl", + mirror=0x27C5, + unicodeslot=0x27C6, + }, + [0x27C7]={ + category="sm", + description="OR WITH DOT INSIDE", + direction="on", + linebreak="al", + unicodeslot=0x27C7, + }, + [0x27C8]={ + category="sm", + description="REVERSE SOLIDUS PRECEDING SUBSET", + direction="on", + linebreak="al", + mirror=0x27C9, + unicodeslot=0x27C8, + }, + [0x27C9]={ + category="sm", + description="SUPERSET PRECEDING SOLIDUS", + direction="on", + linebreak="al", + mirror=0x27C8, + unicodeslot=0x27C9, + }, + [0x27CA]={ + category="sm", + description="VERTICAL BAR WITH HORIZONTAL STROKE", + direction="on", + linebreak="al", + unicodeslot=0x27CA, + }, + [0x27D0]={ + category="sm", + description="WHITE DIAMOND WITH CENTRED DOT", + direction="on", + linebreak="al", + unicodeslot=0x27D0, + }, + [0x27D1]={ + category="sm", + description="AND WITH DOT", + direction="on", + linebreak="al", + unicodeslot=0x27D1, + }, + [0x27D2]={ + category="sm", + description="ELEMENT OF OPENING UPWARDS", + direction="on", + linebreak="al", + unicodeslot=0x27D2, + }, + [0x27D3]={ + category="sm", + description="LOWER RIGHT CORNER WITH DOT", + direction="on", + linebreak="al", + unicodeslot=0x27D3, + }, + [0x27D4]={ + category="sm", + description="UPPER LEFT CORNER WITH DOT", + direction="on", + linebreak="al", + unicodeslot=0x27D4, + }, + [0x27D5]={ + category="sm", + description="LEFT OUTER JOIN", + direction="on", + linebreak="al", + mirror=0x27D6, + unicodeslot=0x27D5, + }, + [0x27D6]={ + category="sm", + description="RIGHT OUTER JOIN", + direction="on", + linebreak="al", + mirror=0x27D5, + unicodeslot=0x27D6, + }, + [0x27D7]={ + category="sm", + description="FULL OUTER JOIN", + direction="on", + linebreak="al", + unicodeslot=0x27D7, + }, + [0x27D8]={ + category="sm", + description="LARGE UP TACK", + direction="on", + linebreak="al", + unicodeslot=0x27D8, + }, + [0x27D9]={ + category="sm", + description="LARGE DOWN TACK", + direction="on", + linebreak="al", + unicodeslot=0x27D9, + }, + [0x27DA]={ + category="sm", + description="LEFT AND RIGHT DOUBLE TURNSTILE", + direction="on", + linebreak="al", + unicodeslot=0x27DA, + }, + [0x27DB]={ + category="sm", + description="LEFT AND RIGHT TACK", + direction="on", + linebreak="al", + unicodeslot=0x27DB, + }, + [0x27DC]={ + category="sm", + description="LEFT MULTIMAP", + direction="on", + linebreak="al", + unicodeslot=0x27DC, + }, + [0x27DD]={ + category="sm", + description="LONG RIGHT TACK", + direction="on", + linebreak="al", + mirror=0x27DE, + unicodeslot=0x27DD, + }, + [0x27DE]={ + category="sm", + description="LONG LEFT TACK", + direction="on", + linebreak="al", + mirror=0x27DD, + unicodeslot=0x27DE, + }, + [0x27DF]={ + category="sm", + description="UP TACK WITH CIRCLE ABOVE", + direction="on", + linebreak="al", + unicodeslot=0x27DF, + }, + [0x27E0]={ + category="sm", + description="LOZENGE DIVIDED BY HORIZONTAL RULE", + direction="on", + linebreak="al", + unicodeslot=0x27E0, + }, + [0x27E1]={ + category="sm", + description="WHITE CONCAVE-SIDED DIAMOND", + direction="on", + linebreak="al", + unicodeslot=0x27E1, + }, + [0x27E2]={ + category="sm", + description="WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK", + direction="on", + linebreak="al", + mirror=0x27E3, + unicodeslot=0x27E2, + }, + [0x27E3]={ + category="sm", + description="WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK", + direction="on", + linebreak="al", + mirror=0x27E2, + unicodeslot=0x27E3, + }, + [0x27E4]={ + category="sm", + description="WHITE SQUARE WITH LEFTWARDS TICK", + direction="on", + linebreak="al", + mirror=0x27E5, + unicodeslot=0x27E4, + }, + [0x27E5]={ + category="sm", + description="WHITE SQUARE WITH RIGHTWARDS TICK", + direction="on", + linebreak="al", + mirror=0x27E4, + unicodeslot=0x27E5, + }, + [0x27E6]={ + category="ps", + cjkwd="na", + description="MATHEMATICAL LEFT WHITE SQUARE BRACKET", + direction="on", + linebreak="op", + mathclass="open", + mathname="llbracket", + mirror=0x27E7, + unicodeslot=0x27E6, + }, + [0x27E7]={ + category="pe", + cjkwd="na", + description="MATHEMATICAL RIGHT WHITE SQUARE BRACKET", + direction="on", + linebreak="cl", + mathclass="close", + mathname="rrbracket", + mirror=0x27E6, + unicodeslot=0x27E7, + }, + [0x27E8]={ + category="ps", + cjkwd="na", + description="MATHEMATICAL LEFT ANGLE BRACKET", + direction="on", + linebreak="op", + mathclass="open", + mathname="langle", + mirror=0x27E9, + unicodeslot=0x27E8, + }, + [0x27E9]={ + category="pe", + cjkwd="na", + description="MATHEMATICAL RIGHT ANGLE BRACKET", + direction="on", + linebreak="cl", + mathclass="close", + mathname="rangle", + mirror=0x27E8, + unicodeslot=0x27E9, + }, + [0x27EA]={ + category="ps", + cjkwd="na", + description="MATHEMATICAL LEFT DOUBLE ANGLE BRACKET", + direction="on", + linebreak="op", + mathclass="open", + mathname="llangle", + mirror=0x27EB, + unicodeslot=0x27EA, + }, + [0x27EB]={ + category="pe", + cjkwd="na", + description="MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET", + direction="on", + linebreak="cl", + mathclass="close", + mathname="rrangle", + mirror=0x27EA, + unicodeslot=0x27EB, + }, + [0x27F0]={ + category="sm", + description="UPWARDS QUADRUPLE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27F0, + }, + [0x27F1]={ + category="sm", + description="DOWNWARDS QUADRUPLE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27F1, + }, + [0x27F2]={ + category="sm", + description="ANTICLOCKWISE GAPPED CIRCLE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27F2, + }, + [0x27F3]={ + category="sm", + description="CLOCKWISE GAPPED CIRCLE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x27F3, + }, + [0x27F4]={ + category="sm", + description="RIGHT ARROW WITH CIRCLED PLUS", + direction="on", + linebreak="al", + unicodeslot=0x27F4, + }, + [0x27F5]={ + category="sm", + description="LONG LEFTWARDS ARROW", + direction="on", + linebreak="al", + fallback=[[\leftarrow\joinrel\relbar]], + mathclass="relation", + mathname="longleftarrow", + unicodeslot=0x27F5, + }, + [0x27F6]={ + category="sm", + description="LONG RIGHTWARDS ARROW", + direction="on", + linebreak="al", + fallback=[[\relbar\joinrel\rightarrow]], + mathclass="relation", + mathname="longrightarrow", + unicodeslot=0x27F6, + }, + [0x27F7]={ + category="sm", + description="LONG LEFT RIGHT ARROW", + direction="on", + linebreak="al", + fallback=[[\leftarrow\joinrel\rightarrow]], + mathclass="relation", + mathname="longleftrightarrow", + unicodeslot=0x27F7, + }, + [0x27F8]={ + category="sm", + description="LONG LEFTWARDS DOUBLE ARROW", + direction="on", + linebreak="al", + fallback=[[\Leftarrow\joinrel\Relbar]], + mathclass="relation", + mathname="Longleftarrow", + unicodeslot=0x27F8, + }, + [0x27F9]={ + category="sm", + description="LONG RIGHTWARDS DOUBLE ARROW", + direction="on", + linebreak="al", + fallback=[[\Relbar\joinrel\Rightarrow]], + mathclass="relation", + mathname="Longrightarrow", + unicodeslot=0x27F9, + }, + [0x27FA]={ + category="sm", + description="LONG LEFT RIGHT DOUBLE ARROW", + direction="on", + linebreak="al", + fallback=[[\Leftarrow\joinrel\Rightarrow]], + mathclass="relation", + mathname="Longleftrightarrow", + unicodeslot=0x27FA, + }, + [0x27FB]={ + category="sm", + description="LONG LEFTWARDS ARROW FROM BAR", + direction="on", + linebreak="al", + fallback=[[\longleftarrow\mapstochar]], -- untested + mathclass="relation", + mathname="longmapsfrom", + unicodeslot=0x27FB, + }, + [0x27FC]={ + category="sm", + description="LONG RIGHTWARDS ARROW FROM BAR", + direction="on", + linebreak="al", + fallback=[[\mapstochar\longrightarrow]], + mathclass="relation", + mathname="longmapsto", + unicodeslot=0x27FC, + }, + [0x27FD]={ + category="sm", + description="LONG LEFTWARDS DOUBLE ARROW FROM BAR", + direction="on", + linebreak="al", + mathclass="relation", + mathname="Longmapsfrom", + unicodeslot=0x27FD, + }, + [0x27FE]={ + category="sm", + description="LONG RIGHTWARDS DOUBLE ARROW FROM BAR", + direction="on", + linebreak="al", + mathclass="relation", + mathname="Longmapsto", + unicodeslot=0x27FE, + }, + [0x27FF]={ + category="sm", + description="LONG RIGHTWARDS SQUIGGLE ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="longrightsquigarrow", + unicodeslot=0x27FF, + }, + [0x2800]={ + category="so", + description="BRAILLE PATTERN BLANK", + direction="l", + linebreak="al", + unicodeslot=0x2800, + }, + [0x2801]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0001", + direction="l", + linebreak="al", + unicodeslot=0x2801, + }, + [0x2802]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0002", + direction="l", + linebreak="al", + unicodeslot=0x2802, + }, + [0x2803]={ + category="so", + description="BRAILLE PATTERN DOTS-0x000C", + direction="l", + linebreak="al", + unicodeslot=0x2803, + }, + [0x2804]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0003", + direction="l", + linebreak="al", + unicodeslot=0x2804, + }, + [0x2805]={ + category="so", + description="BRAILLE PATTERN DOTS-0x000D", + direction="l", + linebreak="al", + unicodeslot=0x2805, + }, + [0x2806]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0017", + direction="l", + linebreak="al", + unicodeslot=0x2806, + }, + [0x2807]={ + category="so", + description="BRAILLE PATTERN DOTS-0x007B", + direction="l", + linebreak="al", + unicodeslot=0x2807, + }, + [0x2808]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0004", + direction="l", + linebreak="al", + unicodeslot=0x2808, + }, + [0x2809]={ + category="so", + description="BRAILLE PATTERN DOTS-0x000E", + direction="l", + linebreak="al", + unicodeslot=0x2809, + }, + [0x280A]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0018", + direction="l", + linebreak="al", + unicodeslot=0x280A, + }, + [0x280B]={ + category="so", + description="BRAILLE PATTERN DOTS-0x007C", + direction="l", + linebreak="al", + unicodeslot=0x280B, + }, + [0x280C]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0022", + direction="l", + linebreak="al", + unicodeslot=0x280C, + }, + [0x280D]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0086", + direction="l", + linebreak="al", + unicodeslot=0x280D, + }, + [0x280E]={ + category="so", + description="BRAILLE PATTERN DOTS-0x00EA", + direction="l", + linebreak="al", + unicodeslot=0x280E, + }, + [0x280F]={ + category="so", + description="BRAILLE PATTERN DOTS-0x04D2", + direction="l", + linebreak="al", + unicodeslot=0x280F, + }, + [0x2810]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0005", + direction="l", + linebreak="al", + unicodeslot=0x2810, + }, + [0x2811]={ + category="so", + description="BRAILLE PATTERN DOTS-0x000F", + direction="l", + linebreak="al", + unicodeslot=0x2811, + }, + [0x2812]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0019", + direction="l", + linebreak="al", + unicodeslot=0x2812, + }, + [0x2813]={ + category="so", + description="BRAILLE PATTERN DOTS-0x007D", + direction="l", + linebreak="al", + unicodeslot=0x2813, + }, + [0x2814]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0023", + direction="l", + linebreak="al", + unicodeslot=0x2814, + }, + [0x2815]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0087", + direction="l", + linebreak="al", + unicodeslot=0x2815, + }, + [0x2816]={ + category="so", + description="BRAILLE PATTERN DOTS-0x00EB", + direction="l", + linebreak="al", + unicodeslot=0x2816, + }, + [0x2817]={ + category="so", + description="BRAILLE PATTERN DOTS-0x04D3", + direction="l", + linebreak="al", + unicodeslot=0x2817, + }, + [0x2818]={ + category="so", + description="BRAILLE PATTERN DOTS-0x002D", + direction="l", + linebreak="al", + unicodeslot=0x2818, + }, + [0x2819]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0091", + direction="l", + linebreak="al", + unicodeslot=0x2819, + }, + [0x281A]={ + category="so", + description="BRAILLE PATTERN DOTS-0x00F5", + direction="l", + linebreak="al", + unicodeslot=0x281A, + }, + [0x281B]={ + category="so", + description="BRAILLE PATTERN DOTS-0x04DD", + direction="l", + linebreak="al", + unicodeslot=0x281B, + }, + [0x281C]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0159", + direction="l", + linebreak="al", + unicodeslot=0x281C, + }, + [0x281D]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0541", + direction="l", + linebreak="al", + unicodeslot=0x281D, + }, + [0x281E]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0929", + direction="l", + linebreak="al", + unicodeslot=0x281E, + }, + [0x281F]={ + category="so", + description="BRAILLE PATTERN DOTS-0x3039", + direction="l", + linebreak="al", + unicodeslot=0x281F, + }, + [0x2820]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0006", + direction="l", + linebreak="al", + unicodeslot=0x2820, + }, + [0x2821]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0010", + direction="l", + linebreak="al", + unicodeslot=0x2821, + }, + [0x2822]={ + category="so", + description="BRAILLE PATTERN DOTS-0x001A", + direction="l", + linebreak="al", + unicodeslot=0x2822, + }, + [0x2823]={ + category="so", + description="BRAILLE PATTERN DOTS-0x007E", + direction="l", + linebreak="al", + unicodeslot=0x2823, + }, + [0x2824]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0024", + direction="l", + linebreak="al", + unicodeslot=0x2824, + }, + [0x2825]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0088", + direction="l", + linebreak="al", + unicodeslot=0x2825, + }, + [0x2826]={ + category="so", + description="BRAILLE PATTERN DOTS-0x00EC", + direction="l", + linebreak="al", + unicodeslot=0x2826, + }, + [0x2827]={ + category="so", + description="BRAILLE PATTERN DOTS-0x04D4", + direction="l", + linebreak="al", + unicodeslot=0x2827, + }, + [0x2828]={ + category="so", + description="BRAILLE PATTERN DOTS-0x002E", + direction="l", + linebreak="al", + unicodeslot=0x2828, + }, + [0x2829]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0092", + direction="l", + linebreak="al", + unicodeslot=0x2829, + }, + [0x282A]={ + category="so", + description="BRAILLE PATTERN DOTS-0x00F6", + direction="l", + linebreak="al", + unicodeslot=0x282A, + }, + [0x282B]={ + category="so", + description="BRAILLE PATTERN DOTS-0x04DE", + direction="l", + linebreak="al", + unicodeslot=0x282B, + }, + [0x282C]={ + category="so", + description="BRAILLE PATTERN DOTS-0x015A", + direction="l", + linebreak="al", + unicodeslot=0x282C, + }, + [0x282D]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0542", + direction="l", + linebreak="al", + unicodeslot=0x282D, + }, + [0x282E]={ + category="so", + description="BRAILLE PATTERN DOTS-0x092A", + direction="l", + linebreak="al", + unicodeslot=0x282E, + }, + [0x282F]={ + category="so", + description="BRAILLE PATTERN DOTS-0x303A", + direction="l", + linebreak="al", + unicodeslot=0x282F, + }, + [0x2830]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0038", + direction="l", + linebreak="al", + unicodeslot=0x2830, + }, + [0x2831]={ + category="so", + description="BRAILLE PATTERN DOTS-0x009C", + direction="l", + linebreak="al", + unicodeslot=0x2831, + }, + [0x2832]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0100", + direction="l", + linebreak="al", + unicodeslot=0x2832, + }, + [0x2833]={ + category="so", + description="BRAILLE PATTERN DOTS-0x04E8", + direction="l", + linebreak="al", + unicodeslot=0x2833, + }, + [0x2834]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0164", + direction="l", + linebreak="al", + unicodeslot=0x2834, + }, + [0x2835]={ + category="so", + description="BRAILLE PATTERN DOTS-0x054C", + direction="l", + linebreak="al", + unicodeslot=0x2835, + }, + [0x2836]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0934", + direction="l", + linebreak="al", + unicodeslot=0x2836, + }, + [0x2837]={ + category="so", + description="BRAILLE PATTERN DOTS-0x3044", + direction="l", + linebreak="al", + unicodeslot=0x2837, + }, + [0x2838]={ + category="so", + description="BRAILLE PATTERN DOTS-0x01C8", + direction="l", + linebreak="al", + unicodeslot=0x2838, + }, + [0x2839]={ + category="so", + description="BRAILLE PATTERN DOTS-0x05B0", + direction="l", + linebreak="al", + unicodeslot=0x2839, + }, + [0x283A]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0998", + direction="l", + linebreak="al", + unicodeslot=0x283A, + }, + [0x283B]={ + category="so", + description="BRAILLE PATTERN DOTS-0x30A8", + direction="l", + linebreak="al", + unicodeslot=0x283B, + }, + [0x283C]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0D80", + direction="l", + linebreak="al", + unicodeslot=0x283C, + }, + [0x283D]={ + category="so", + description="BRAILLE PATTERN DOTS-0x3490", + direction="l", + linebreak="al", + unicodeslot=0x283D, + }, + [0x283E]={ + category="so", + description="BRAILLE PATTERN DOTS-0x5BA0", + direction="l", + linebreak="al", + unicodeslot=0x283E, + }, + [0x283F]={ + category="so", + description="BRAILLE PATTERN DOTS-0x1E240", + direction="l", + linebreak="al", + unicodeslot=0x283F, + }, + [0x2840]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0007", + direction="l", + linebreak="al", + unicodeslot=0x2840, + }, + [0x2841]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0011", + direction="l", + linebreak="al", + unicodeslot=0x2841, + }, + [0x2842]={ + category="so", + description="BRAILLE PATTERN DOTS-0x001B", + direction="l", + linebreak="al", + unicodeslot=0x2842, + }, + [0x2843]={ + category="so", + description="BRAILLE PATTERN DOTS-0x007F", + direction="l", + linebreak="al", + unicodeslot=0x2843, + }, + [0x2844]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0025", + direction="l", + linebreak="al", + unicodeslot=0x2844, + }, + [0x2845]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0089", + direction="l", + linebreak="al", + unicodeslot=0x2845, + }, + [0x2846]={ + category="so", + description="BRAILLE PATTERN DOTS-0x00ED", + direction="l", + linebreak="al", + unicodeslot=0x2846, + }, + [0x2847]={ + category="so", + description="BRAILLE PATTERN DOTS-0x04D5", + direction="l", + linebreak="al", + unicodeslot=0x2847, + }, + [0x2848]={ + category="so", + description="BRAILLE PATTERN DOTS-0x002F", + direction="l", + linebreak="al", + unicodeslot=0x2848, + }, + [0x2849]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0093", + direction="l", + linebreak="al", + unicodeslot=0x2849, + }, + [0x284A]={ + category="so", + description="BRAILLE PATTERN DOTS-0x00F7", + direction="l", + linebreak="al", + unicodeslot=0x284A, + }, + [0x284B]={ + category="so", + description="BRAILLE PATTERN DOTS-0x04DF", + direction="l", + linebreak="al", + unicodeslot=0x284B, + }, + [0x284C]={ + category="so", + description="BRAILLE PATTERN DOTS-0x015B", + direction="l", + linebreak="al", + unicodeslot=0x284C, + }, + [0x284D]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0543", + direction="l", + linebreak="al", + unicodeslot=0x284D, + }, + [0x284E]={ + category="so", + description="BRAILLE PATTERN DOTS-0x092B", + direction="l", + linebreak="al", + unicodeslot=0x284E, + }, + [0x284F]={ + category="so", + description="BRAILLE PATTERN DOTS-0x303B", + direction="l", + linebreak="al", + unicodeslot=0x284F, + }, + [0x2850]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0039", + direction="l", + linebreak="al", + unicodeslot=0x2850, + }, + [0x2851]={ + category="so", + description="BRAILLE PATTERN DOTS-0x009D", + direction="l", + linebreak="al", + unicodeslot=0x2851, + }, + [0x2852]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0101", + direction="l", + linebreak="al", + unicodeslot=0x2852, + }, + [0x2853]={ + category="so", + description="BRAILLE PATTERN DOTS-0x04E9", + direction="l", + linebreak="al", + unicodeslot=0x2853, + }, + [0x2854]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0165", + direction="l", + linebreak="al", + unicodeslot=0x2854, + }, + [0x2855]={ + category="so", + description="BRAILLE PATTERN DOTS-0x054D", + direction="l", + linebreak="al", + unicodeslot=0x2855, + }, + [0x2856]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0935", + direction="l", + linebreak="al", + unicodeslot=0x2856, + }, + [0x2857]={ + category="so", + description="BRAILLE PATTERN DOTS-0x3045", + direction="l", + linebreak="al", + unicodeslot=0x2857, + }, + [0x2858]={ + category="so", + description="BRAILLE PATTERN DOTS-0x01C9", + direction="l", + linebreak="al", + unicodeslot=0x2858, + }, + [0x2859]={ + category="so", + description="BRAILLE PATTERN DOTS-0x05B1", + direction="l", + linebreak="al", + unicodeslot=0x2859, + }, + [0x285A]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0999", + direction="l", + linebreak="al", + unicodeslot=0x285A, + }, + [0x285B]={ + category="so", + description="BRAILLE PATTERN DOTS-0x30A9", + direction="l", + linebreak="al", + unicodeslot=0x285B, + }, + [0x285C]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0D81", + direction="l", + linebreak="al", + unicodeslot=0x285C, + }, + [0x285D]={ + category="so", + description="BRAILLE PATTERN DOTS-0x3491", + direction="l", + linebreak="al", + unicodeslot=0x285D, + }, + [0x285E]={ + category="so", + description="BRAILLE PATTERN DOTS-0x5BA1", + direction="l", + linebreak="al", + unicodeslot=0x285E, + }, + [0x285F]={ + category="so", + description="BRAILLE PATTERN DOTS-0x1E241", + direction="l", + linebreak="al", + unicodeslot=0x285F, + }, + [0x2860]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0043", + direction="l", + linebreak="al", + unicodeslot=0x2860, + }, + [0x2861]={ + category="so", + description="BRAILLE PATTERN DOTS-0x00A7", + direction="l", + linebreak="al", + unicodeslot=0x2861, + }, + [0x2862]={ + category="so", + description="BRAILLE PATTERN DOTS-0x010B", + direction="l", + linebreak="al", + unicodeslot=0x2862, + }, + [0x2863]={ + category="so", + description="BRAILLE PATTERN DOTS-0x04F3", + direction="l", + linebreak="al", + unicodeslot=0x2863, + }, + [0x2864]={ + category="so", + description="BRAILLE PATTERN DOTS-0x016F", + direction="l", + linebreak="al", + unicodeslot=0x2864, + }, + [0x2865]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0557", + direction="l", + linebreak="al", + unicodeslot=0x2865, + }, + [0x2866]={ + category="so", + description="BRAILLE PATTERN DOTS-0x093F", + direction="l", + linebreak="al", + unicodeslot=0x2866, + }, + [0x2867]={ + category="so", + description="BRAILLE PATTERN DOTS-0x304F", + direction="l", + linebreak="al", + unicodeslot=0x2867, + }, + [0x2868]={ + category="so", + description="BRAILLE PATTERN DOTS-0x01D3", + direction="l", + linebreak="al", + unicodeslot=0x2868, + }, + [0x2869]={ + category="so", + description="BRAILLE PATTERN DOTS-0x05BB", + direction="l", + linebreak="al", + unicodeslot=0x2869, + }, + [0x286A]={ + category="so", + description="BRAILLE PATTERN DOTS-0x09A3", + direction="l", + linebreak="al", + unicodeslot=0x286A, + }, + [0x286B]={ + category="so", + description="BRAILLE PATTERN DOTS-0x30B3", + direction="l", + linebreak="al", + unicodeslot=0x286B, + }, + [0x286C]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0D8B", + direction="l", + linebreak="al", + unicodeslot=0x286C, + }, + [0x286D]={ + category="so", + description="BRAILLE PATTERN DOTS-0x349B", + direction="l", + linebreak="al", + unicodeslot=0x286D, + }, + [0x286E]={ + category="so", + description="BRAILLE PATTERN DOTS-0x5BAB", + direction="l", + linebreak="al", + unicodeslot=0x286E, + }, + [0x286F]={ + category="so", + description="BRAILLE PATTERN DOTS-0x1E24B", + direction="l", + linebreak="al", + unicodeslot=0x286F, + }, + [0x2870]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0237", + direction="l", + linebreak="al", + unicodeslot=0x2870, + }, + [0x2871]={ + category="so", + description="BRAILLE PATTERN DOTS-0x061F", + direction="l", + linebreak="al", + unicodeslot=0x2871, + }, + [0x2872]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0A07", + direction="l", + linebreak="al", + unicodeslot=0x2872, + }, + [0x2873]={ + category="so", + description="BRAILLE PATTERN DOTS-0x3117", + direction="l", + linebreak="al", + unicodeslot=0x2873, + }, + [0x2874]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0DEF", + direction="l", + linebreak="al", + unicodeslot=0x2874, + }, + [0x2875]={ + category="so", + description="BRAILLE PATTERN DOTS-0x34FF", + direction="l", + linebreak="al", + unicodeslot=0x2875, + }, + [0x2876]={ + category="so", + description="BRAILLE PATTERN DOTS-0x5C0F", + direction="l", + linebreak="al", + unicodeslot=0x2876, + }, + [0x2877]={ + category="so", + description="BRAILLE PATTERN DOTS-0x1E2AF", + direction="l", + linebreak="al", + unicodeslot=0x2877, + }, + [0x2878]={ + category="so", + description="BRAILLE PATTERN DOTS-0x11D7", + direction="l", + linebreak="al", + unicodeslot=0x2878, + }, + [0x2879]={ + category="so", + description="BRAILLE PATTERN DOTS-0x38E7", + direction="l", + linebreak="al", + unicodeslot=0x2879, + }, + [0x287A]={ + category="so", + description="BRAILLE PATTERN DOTS-0x5FF7", + direction="l", + linebreak="al", + unicodeslot=0x287A, + }, + [0x287B]={ + category="so", + description="BRAILLE PATTERN DOTS-0x1E697", + direction="l", + linebreak="al", + unicodeslot=0x287B, + }, + [0x287C]={ + category="so", + description="BRAILLE PATTERN DOTS-0x8707", + direction="l", + linebreak="al", + unicodeslot=0x287C, + }, + [0x287D]={ + category="so", + description="BRAILLE PATTERN DOTS-0x20DA7", + direction="l", + linebreak="al", + unicodeslot=0x287D, + }, + [0x287E]={ + category="so", + description="BRAILLE PATTERN DOTS-0x39447", + direction="l", + linebreak="al", + unicodeslot=0x287E, + }, + [0x287F]={ + category="so", + description="BRAILLE PATTERN DOTS-0x12D687", + direction="l", + linebreak="al", + unicodeslot=0x287F, + }, + [0x2880]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0008", + direction="l", + linebreak="al", + unicodeslot=0x2880, + }, + [0x2881]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0012", + direction="l", + linebreak="al", + unicodeslot=0x2881, + }, + [0x2882]={ + category="so", + description="BRAILLE PATTERN DOTS-0x001C", + direction="l", + linebreak="al", + unicodeslot=0x2882, + }, + [0x2883]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0080", + direction="l", + linebreak="al", + unicodeslot=0x2883, + }, + [0x2884]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0026", + direction="l", + linebreak="al", + unicodeslot=0x2884, + }, + [0x2885]={ + category="so", + description="BRAILLE PATTERN DOTS-0x008A", + direction="l", + linebreak="al", + unicodeslot=0x2885, + }, + [0x2886]={ + category="so", + description="BRAILLE PATTERN DOTS-0x00EE", + direction="l", + linebreak="al", + unicodeslot=0x2886, + }, + [0x2887]={ + category="so", + description="BRAILLE PATTERN DOTS-0x04D6", + direction="l", + linebreak="al", + unicodeslot=0x2887, + }, + [0x2888]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0030", + direction="l", + linebreak="al", + unicodeslot=0x2888, + }, + [0x2889]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0094", + direction="l", + linebreak="al", + unicodeslot=0x2889, + }, + [0x288A]={ + category="so", + description="BRAILLE PATTERN DOTS-0x00F8", + direction="l", + linebreak="al", + unicodeslot=0x288A, + }, + [0x288B]={ + category="so", + description="BRAILLE PATTERN DOTS-0x04E0", + direction="l", + linebreak="al", + unicodeslot=0x288B, + }, + [0x288C]={ + category="so", + description="BRAILLE PATTERN DOTS-0x015C", + direction="l", + linebreak="al", + unicodeslot=0x288C, + }, + [0x288D]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0544", + direction="l", + linebreak="al", + unicodeslot=0x288D, + }, + [0x288E]={ + category="so", + description="BRAILLE PATTERN DOTS-0x092C", + direction="l", + linebreak="al", + unicodeslot=0x288E, + }, + [0x288F]={ + category="so", + description="BRAILLE PATTERN DOTS-0x303C", + direction="l", + linebreak="al", + unicodeslot=0x288F, + }, + [0x2890]={ + category="so", + description="BRAILLE PATTERN DOTS-0x003A", + direction="l", + linebreak="al", + unicodeslot=0x2890, + }, + [0x2891]={ + category="so", + description="BRAILLE PATTERN DOTS-0x009E", + direction="l", + linebreak="al", + unicodeslot=0x2891, + }, + [0x2892]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0102", + direction="l", + linebreak="al", + unicodeslot=0x2892, + }, + [0x2893]={ + category="so", + description="BRAILLE PATTERN DOTS-0x04EA", + direction="l", + linebreak="al", + unicodeslot=0x2893, + }, + [0x2894]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0166", + direction="l", + linebreak="al", + unicodeslot=0x2894, + }, + [0x2895]={ + category="so", + description="BRAILLE PATTERN DOTS-0x054E", + direction="l", + linebreak="al", + unicodeslot=0x2895, + }, + [0x2896]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0936", + direction="l", + linebreak="al", + unicodeslot=0x2896, + }, + [0x2897]={ + category="so", + description="BRAILLE PATTERN DOTS-0x3046", + direction="l", + linebreak="al", + unicodeslot=0x2897, + }, + [0x2898]={ + category="so", + description="BRAILLE PATTERN DOTS-0x01CA", + direction="l", + linebreak="al", + unicodeslot=0x2898, + }, + [0x2899]={ + category="so", + description="BRAILLE PATTERN DOTS-0x05B2", + direction="l", + linebreak="al", + unicodeslot=0x2899, + }, + [0x289A]={ + category="so", + description="BRAILLE PATTERN DOTS-0x099A", + direction="l", + linebreak="al", + unicodeslot=0x289A, + }, + [0x289B]={ + category="so", + description="BRAILLE PATTERN DOTS-0x30AA", + direction="l", + linebreak="al", + unicodeslot=0x289B, + }, + [0x289C]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0D82", + direction="l", + linebreak="al", + unicodeslot=0x289C, + }, + [0x289D]={ + category="so", + description="BRAILLE PATTERN DOTS-0x3492", + direction="l", + linebreak="al", + unicodeslot=0x289D, + }, + [0x289E]={ + category="so", + description="BRAILLE PATTERN DOTS-0x5BA2", + direction="l", + linebreak="al", + unicodeslot=0x289E, + }, + [0x289F]={ + category="so", + description="BRAILLE PATTERN DOTS-0x1E242", + direction="l", + linebreak="al", + unicodeslot=0x289F, + }, + [0x28A0]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0044", + direction="l", + linebreak="al", + unicodeslot=0x28A0, + }, + [0x28A1]={ + category="so", + description="BRAILLE PATTERN DOTS-0x00A8", + direction="l", + linebreak="al", + unicodeslot=0x28A1, + }, + [0x28A2]={ + category="so", + description="BRAILLE PATTERN DOTS-0x010C", + direction="l", + linebreak="al", + unicodeslot=0x28A2, + }, + [0x28A3]={ + category="so", + description="BRAILLE PATTERN DOTS-0x04F4", + direction="l", + linebreak="al", + unicodeslot=0x28A3, + }, + [0x28A4]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0170", + direction="l", + linebreak="al", + unicodeslot=0x28A4, + }, + [0x28A5]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0558", + direction="l", + linebreak="al", + unicodeslot=0x28A5, + }, + [0x28A6]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0940", + direction="l", + linebreak="al", + unicodeslot=0x28A6, + }, + [0x28A7]={ + category="so", + description="BRAILLE PATTERN DOTS-0x3050", + direction="l", + linebreak="al", + unicodeslot=0x28A7, + }, + [0x28A8]={ + category="so", + description="BRAILLE PATTERN DOTS-0x01D4", + direction="l", + linebreak="al", + unicodeslot=0x28A8, + }, + [0x28A9]={ + category="so", + description="BRAILLE PATTERN DOTS-0x05BC", + direction="l", + linebreak="al", + unicodeslot=0x28A9, + }, + [0x28AA]={ + category="so", + description="BRAILLE PATTERN DOTS-0x09A4", + direction="l", + linebreak="al", + unicodeslot=0x28AA, + }, + [0x28AB]={ + category="so", + description="BRAILLE PATTERN DOTS-0x30B4", + direction="l", + linebreak="al", + unicodeslot=0x28AB, + }, + [0x28AC]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0D8C", + direction="l", + linebreak="al", + unicodeslot=0x28AC, + }, + [0x28AD]={ + category="so", + description="BRAILLE PATTERN DOTS-0x349C", + direction="l", + linebreak="al", + unicodeslot=0x28AD, + }, + [0x28AE]={ + category="so", + description="BRAILLE PATTERN DOTS-0x5BAC", + direction="l", + linebreak="al", + unicodeslot=0x28AE, + }, + [0x28AF]={ + category="so", + description="BRAILLE PATTERN DOTS-0x1E24C", + direction="l", + linebreak="al", + unicodeslot=0x28AF, + }, + [0x28B0]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0238", + direction="l", + linebreak="al", + unicodeslot=0x28B0, + }, + [0x28B1]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0620", + direction="l", + linebreak="al", + unicodeslot=0x28B1, + }, + [0x28B2]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0A08", + direction="l", + linebreak="al", + unicodeslot=0x28B2, + }, + [0x28B3]={ + category="so", + description="BRAILLE PATTERN DOTS-0x3118", + direction="l", + linebreak="al", + unicodeslot=0x28B3, + }, + [0x28B4]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0DF0", + direction="l", + linebreak="al", + unicodeslot=0x28B4, + }, + [0x28B5]={ + category="so", + description="BRAILLE PATTERN DOTS-0x3500", + direction="l", + linebreak="al", + unicodeslot=0x28B5, + }, + [0x28B6]={ + category="so", + description="BRAILLE PATTERN DOTS-0x5C10", + direction="l", + linebreak="al", + unicodeslot=0x28B6, + }, + [0x28B7]={ + category="so", + description="BRAILLE PATTERN DOTS-0x1E2B0", + direction="l", + linebreak="al", + unicodeslot=0x28B7, + }, + [0x28B8]={ + category="so", + description="BRAILLE PATTERN DOTS-0x11D8", + direction="l", + linebreak="al", + unicodeslot=0x28B8, + }, + [0x28B9]={ + category="so", + description="BRAILLE PATTERN DOTS-0x38E8", + direction="l", + linebreak="al", + unicodeslot=0x28B9, + }, + [0x28BA]={ + category="so", + description="BRAILLE PATTERN DOTS-0x5FF8", + direction="l", + linebreak="al", + unicodeslot=0x28BA, + }, + [0x28BB]={ + category="so", + description="BRAILLE PATTERN DOTS-0x1E698", + direction="l", + linebreak="al", + unicodeslot=0x28BB, + }, + [0x28BC]={ + category="so", + description="BRAILLE PATTERN DOTS-0x8708", + direction="l", + linebreak="al", + unicodeslot=0x28BC, + }, + [0x28BD]={ + category="so", + description="BRAILLE PATTERN DOTS-0x20DA8", + direction="l", + linebreak="al", + unicodeslot=0x28BD, + }, + [0x28BE]={ + category="so", + description="BRAILLE PATTERN DOTS-0x39448", + direction="l", + linebreak="al", + unicodeslot=0x28BE, + }, + [0x28BF]={ + category="so", + description="BRAILLE PATTERN DOTS-0x12D688", + direction="l", + linebreak="al", + unicodeslot=0x28BF, + }, + [0x28C0]={ + category="so", + description="BRAILLE PATTERN DOTS-0x004E", + direction="l", + linebreak="al", + unicodeslot=0x28C0, + }, + [0x28C1]={ + category="so", + description="BRAILLE PATTERN DOTS-0x00B2", + direction="l", + linebreak="al", + unicodeslot=0x28C1, + }, + [0x28C2]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0116", + direction="l", + linebreak="al", + unicodeslot=0x28C2, + }, + [0x28C3]={ + category="so", + description="BRAILLE PATTERN DOTS-0x04FE", + direction="l", + linebreak="al", + unicodeslot=0x28C3, + }, + [0x28C4]={ + category="so", + description="BRAILLE PATTERN DOTS-0x017A", + direction="l", + linebreak="al", + unicodeslot=0x28C4, + }, + [0x28C5]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0562", + direction="l", + linebreak="al", + unicodeslot=0x28C5, + }, + [0x28C6]={ + category="so", + description="BRAILLE PATTERN DOTS-0x094A", + direction="l", + linebreak="al", + unicodeslot=0x28C6, + }, + [0x28C7]={ + category="so", + description="BRAILLE PATTERN DOTS-0x305A", + direction="l", + linebreak="al", + unicodeslot=0x28C7, + }, + [0x28C8]={ + category="so", + description="BRAILLE PATTERN DOTS-0x01DE", + direction="l", + linebreak="al", + unicodeslot=0x28C8, + }, + [0x28C9]={ + category="so", + description="BRAILLE PATTERN DOTS-0x05C6", + direction="l", + linebreak="al", + unicodeslot=0x28C9, + }, + [0x28CA]={ + category="so", + description="BRAILLE PATTERN DOTS-0x09AE", + direction="l", + linebreak="al", + unicodeslot=0x28CA, + }, + [0x28CB]={ + category="so", + description="BRAILLE PATTERN DOTS-0x30BE", + direction="l", + linebreak="al", + unicodeslot=0x28CB, + }, + [0x28CC]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0D96", + direction="l", + linebreak="al", + unicodeslot=0x28CC, + }, + [0x28CD]={ + category="so", + description="BRAILLE PATTERN DOTS-0x34A6", + direction="l", + linebreak="al", + unicodeslot=0x28CD, + }, + [0x28CE]={ + category="so", + description="BRAILLE PATTERN DOTS-0x5BB6", + direction="l", + linebreak="al", + unicodeslot=0x28CE, + }, + [0x28CF]={ + category="so", + description="BRAILLE PATTERN DOTS-0x1E256", + direction="l", + linebreak="al", + unicodeslot=0x28CF, + }, + [0x28D0]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0242", + direction="l", + linebreak="al", + unicodeslot=0x28D0, + }, + [0x28D1]={ + category="so", + description="BRAILLE PATTERN DOTS-0x062A", + direction="l", + linebreak="al", + unicodeslot=0x28D1, + }, + [0x28D2]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0A12", + direction="l", + linebreak="al", + unicodeslot=0x28D2, + }, + [0x28D3]={ + category="so", + description="BRAILLE PATTERN DOTS-0x3122", + direction="l", + linebreak="al", + unicodeslot=0x28D3, + }, + [0x28D4]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0DFA", + direction="l", + linebreak="al", + unicodeslot=0x28D4, + }, + [0x28D5]={ + category="so", + description="BRAILLE PATTERN DOTS-0x350A", + direction="l", + linebreak="al", + unicodeslot=0x28D5, + }, + [0x28D6]={ + category="so", + description="BRAILLE PATTERN DOTS-0x5C1A", + direction="l", + linebreak="al", + unicodeslot=0x28D6, + }, + [0x28D7]={ + category="so", + description="BRAILLE PATTERN DOTS-0x1E2BA", + direction="l", + linebreak="al", + unicodeslot=0x28D7, + }, + [0x28D8]={ + category="so", + description="BRAILLE PATTERN DOTS-0x11E2", + direction="l", + linebreak="al", + unicodeslot=0x28D8, + }, + [0x28D9]={ + category="so", + description="BRAILLE PATTERN DOTS-0x38F2", + direction="l", + linebreak="al", + unicodeslot=0x28D9, + }, + [0x28DA]={ + category="so", + description="BRAILLE PATTERN DOTS-0x6002", + direction="l", + linebreak="al", + unicodeslot=0x28DA, + }, + [0x28DB]={ + category="so", + description="BRAILLE PATTERN DOTS-0x1E6A2", + direction="l", + linebreak="al", + unicodeslot=0x28DB, + }, + [0x28DC]={ + category="so", + description="BRAILLE PATTERN DOTS-0x8712", + direction="l", + linebreak="al", + unicodeslot=0x28DC, + }, + [0x28DD]={ + category="so", + description="BRAILLE PATTERN DOTS-0x20DB2", + direction="l", + linebreak="al", + unicodeslot=0x28DD, + }, + [0x28DE]={ + category="so", + description="BRAILLE PATTERN DOTS-0x39452", + direction="l", + linebreak="al", + unicodeslot=0x28DE, + }, + [0x28DF]={ + category="so", + description="BRAILLE PATTERN DOTS-0x12D692", + direction="l", + linebreak="al", + unicodeslot=0x28DF, + }, + [0x28E0]={ + category="so", + description="BRAILLE PATTERN DOTS-0x02A6", + direction="l", + linebreak="al", + unicodeslot=0x28E0, + }, + [0x28E1]={ + category="so", + description="BRAILLE PATTERN DOTS-0x068E", + direction="l", + linebreak="al", + unicodeslot=0x28E1, + }, + [0x28E2]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0A76", + direction="l", + linebreak="al", + unicodeslot=0x28E2, + }, + [0x28E3]={ + category="so", + description="BRAILLE PATTERN DOTS-0x3186", + direction="l", + linebreak="al", + unicodeslot=0x28E3, + }, + [0x28E4]={ + category="so", + description="BRAILLE PATTERN DOTS-0x0E5E", + direction="l", + linebreak="al", + unicodeslot=0x28E4, + }, + [0x28E5]={ + category="so", + description="BRAILLE PATTERN DOTS-0x356E", + direction="l", + linebreak="al", + unicodeslot=0x28E5, + }, + [0x28E6]={ + category="so", + description="BRAILLE PATTERN DOTS-0x5C7E", + direction="l", + linebreak="al", + unicodeslot=0x28E6, + }, + [0x28E7]={ + category="so", + description="BRAILLE PATTERN DOTS-0x1E31E", + direction="l", + linebreak="al", + unicodeslot=0x28E7, + }, + [0x28E8]={ + category="so", + description="BRAILLE PATTERN DOTS-0x1246", + direction="l", + linebreak="al", + unicodeslot=0x28E8, + }, + [0x28E9]={ + category="so", + description="BRAILLE PATTERN DOTS-0x3956", + direction="l", + linebreak="al", + unicodeslot=0x28E9, + }, + [0x28EA]={ + category="so", + description="BRAILLE PATTERN DOTS-0x6066", + direction="l", + linebreak="al", + unicodeslot=0x28EA, + }, + [0x28EB]={ + category="so", + description="BRAILLE PATTERN DOTS-0x1E706", + direction="l", + linebreak="al", + unicodeslot=0x28EB, + }, + [0x28EC]={ + category="so", + description="BRAILLE PATTERN DOTS-0x8776", + direction="l", + linebreak="al", + unicodeslot=0x28EC, + }, + [0x28ED]={ + category="so", + description="BRAILLE PATTERN DOTS-0x20E16", + direction="l", + linebreak="al", + unicodeslot=0x28ED, + }, + [0x28EE]={ + category="so", + description="BRAILLE PATTERN DOTS-0x394B6", + direction="l", + linebreak="al", + unicodeslot=0x28EE, + }, + [0x28EF]={ + category="so", + description="BRAILLE PATTERN DOTS-0x12D6F6", + direction="l", + linebreak="al", + unicodeslot=0x28EF, + }, + [0x28F0]={ + category="so", + description="BRAILLE PATTERN DOTS-0x162E", + direction="l", + linebreak="al", + unicodeslot=0x28F0, + }, + [0x28F1]={ + category="so", + description="BRAILLE PATTERN DOTS-0x3D3E", + direction="l", + linebreak="al", + unicodeslot=0x28F1, + }, + [0x28F2]={ + category="so", + description="BRAILLE PATTERN DOTS-0x644E", + direction="l", + linebreak="al", + unicodeslot=0x28F2, + }, + [0x28F3]={ + category="so", + description="BRAILLE PATTERN DOTS-0x1EAEE", + direction="l", + linebreak="al", + unicodeslot=0x28F3, + }, + [0x28F4]={ + category="so", + description="BRAILLE PATTERN DOTS-0x8B5E", + direction="l", + linebreak="al", + unicodeslot=0x28F4, + }, + [0x28F5]={ + category="so", + description="BRAILLE PATTERN DOTS-0x211FE", + direction="l", + linebreak="al", + unicodeslot=0x28F5, + }, + [0x28F6]={ + category="so", + description="BRAILLE PATTERN DOTS-0x3989E", + direction="l", + linebreak="al", + unicodeslot=0x28F6, + }, + [0x28F7]={ + category="so", + description="BRAILLE PATTERN DOTS-0x12DADE", + direction="l", + linebreak="al", + unicodeslot=0x28F7, + }, + [0x28F8]={ + category="so", + description="BRAILLE PATTERN DOTS-0xB26E", + direction="l", + linebreak="al", + unicodeslot=0x28F8, + }, + [0x28F9]={ + category="so", + description="BRAILLE PATTERN DOTS-0x2390E", + direction="l", + linebreak="al", + unicodeslot=0x28F9, + }, + [0x28FA]={ + category="so", + description="BRAILLE PATTERN DOTS-0x3BFAE", + direction="l", + linebreak="al", + unicodeslot=0x28FA, + }, + [0x28FB]={ + category="so", + description="BRAILLE PATTERN DOTS-0x1301EE", + direction="l", + linebreak="al", + unicodeslot=0x28FB, + }, + [0x28FC]={ + category="so", + description="BRAILLE PATTERN DOTS-0x5464E", + direction="l", + linebreak="al", + unicodeslot=0x28FC, + }, + [0x28FD]={ + category="so", + description="BRAILLE PATTERN DOTS-0x14888E", + direction="l", + linebreak="al", + unicodeslot=0x28FD, + }, + [0x28FE]={ + category="so", + description="BRAILLE PATTERN DOTS-0x23CACE", + direction="l", + linebreak="al", + unicodeslot=0x28FE, + }, + [0x28FF]={ + category="so", + description="BRAILLE PATTERN DOTS-0xBC614E", + direction="l", + linebreak="al", + unicodeslot=0x28FF, + }, + [0x2900]={ + category="sm", + description="RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE", + direction="on", + linebreak="al", + unicodeslot=0x2900, + }, + [0x2901]={ + category="sm", + description="RIGHTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE", + direction="on", + linebreak="al", + unicodeslot=0x2901, + }, + [0x2902]={ + category="sm", + description="LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE", + direction="on", + linebreak="al", + unicodeslot=0x2902, + }, + [0x2903]={ + category="sm", + description="RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE", + direction="on", + linebreak="al", + unicodeslot=0x2903, + }, + [0x2904]={ + category="sm", + description="LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE", + direction="on", + linebreak="al", + unicodeslot=0x2904, + }, + [0x2905]={ + category="sm", + description="RIGHTWARDS TWO-HEADED ARROW FROM BAR", + direction="on", + linebreak="al", + unicodeslot=0x2905, + }, + [0x2906]={ + category="sm", + description="LEFTWARDS DOUBLE ARROW FROM BAR", + direction="on", + linebreak="al", + mathclass="relation", + mathname="Mapsfrom", + unicodeslot=0x2906, + }, + [0x2907]={ + category="sm", + description="RIGHTWARDS DOUBLE ARROW FROM BAR", + direction="on", + linebreak="al", + mathclass="relation", + mathname="Mapsto", + unicodeslot=0x2907, + }, + [0x2908]={ + category="sm", + description="DOWNWARDS ARROW WITH HORIZONTAL STROKE", + direction="on", + linebreak="al", + unicodeslot=0x2908, + }, + [0x2909]={ + category="sm", + description="UPWARDS ARROW WITH HORIZONTAL STROKE", + direction="on", + linebreak="al", + unicodeslot=0x2909, + }, + [0x290A]={ + category="sm", + description="UPWARDS TRIPLE ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="Uuparrow", + unicodeslot=0x290A, + }, + [0x290B]={ + category="sm", + description="DOWNWARDS TRIPLE ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="Ddownarrow", + unicodeslot=0x290B, + }, + [0x290C]={ + category="sm", + description="LEFTWARDS DOUBLE DASH ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="dashedleftarrow", + unicodeslot=0x290C, + }, + [0x290D]={ + category="sm", + description="RIGHTWARDS DOUBLE DASH ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="dashedrightarrow", + unicodeslot=0x290D, + }, + [0x290E]={ + category="sm", + description="LEFTWARDS TRIPLE DASH ARROW", + direction="on", + linebreak="al", + unicodeslot=0x290E, + }, + [0x290F]={ + category="sm", + description="RIGHTWARDS TRIPLE DASH ARROW", + direction="on", + linebreak="al", + unicodeslot=0x290F, + }, + [0x2910]={ + category="sm", + description="RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2910, + }, + [0x2911]={ + category="sm", + description="RIGHTWARDS ARROW WITH DOTTED STEM", + direction="on", + linebreak="al", + mathclass="relation", + mathname="dottedrightarrow", + unicodeslot=0x2911, + }, + [0x2912]={ + category="sm", + description="UPWARDS ARROW TO BAR", + direction="on", + linebreak="al", + unicodeslot=0x2912, + }, + [0x2913]={ + category="sm", + description="DOWNWARDS ARROW TO BAR", + direction="on", + linebreak="al", + unicodeslot=0x2913, + }, + [0x2914]={ + category="sm", + description="RIGHTWARDS ARROW WITH TAIL WITH VERTICAL STROKE", + direction="on", + linebreak="al", + unicodeslot=0x2914, + }, + [0x2915]={ + category="sm", + description="RIGHTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE", + direction="on", + linebreak="al", + unicodeslot=0x2915, + }, + [0x2916]={ + category="sm", + description="RIGHTWARDS TWO-HEADED ARROW WITH TAIL", + direction="on", + linebreak="al", + mathclass="relation", + mathname="twoheadrightarrowtail", + unicodeslot=0x2916, + }, + [0x2917]={ + category="sm", + description="RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE", + direction="on", + linebreak="al", + mathclass="relation", + unicodeslot=0x2917, + }, + [0x2918]={ + category="sm", + description="RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE", + direction="on", + linebreak="al", + unicodeslot=0x2918, + }, + [0x2919]={ + category="sm", + description="LEFTWARDS ARROW-TAIL", + direction="on", + linebreak="al", + unicodeslot=0x2919, + }, + [0x291A]={ + category="sm", + description="RIGHTWARDS ARROW-TAIL", + direction="on", + linebreak="al", + unicodeslot=0x291A, + }, + [0x291B]={ + category="sm", + description="LEFTWARDS DOUBLE ARROW-TAIL", + direction="on", + linebreak="al", + unicodeslot=0x291B, + }, + [0x291C]={ + category="sm", + description="RIGHTWARDS DOUBLE ARROW-TAIL", + direction="on", + linebreak="al", + unicodeslot=0x291C, + }, + [0x291D]={ + category="sm", + description="LEFTWARDS ARROW TO BLACK DIAMOND", + direction="on", + linebreak="al", + unicodeslot=0x291D, + }, + [0x291E]={ + category="sm", + description="RIGHTWARDS ARROW TO BLACK DIAMOND", + direction="on", + linebreak="al", + unicodeslot=0x291E, + }, + [0x291F]={ + category="sm", + description="LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND", + direction="on", + linebreak="al", + unicodeslot=0x291F, + }, + [0x2920]={ + category="sm", + description="RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND", + direction="on", + linebreak="al", + unicodeslot=0x2920, + }, + [0x2921]={ + category="sm", + description="NORTH WEST AND SOUTH EAST ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="nwsearrow", + unicodeslot=0x2921, + }, + [0x2922]={ + category="sm", + description="NORTH EAST AND SOUTH WEST ARROW", + direction="on", + linebreak="al", + mathclass="relation", + mathname="neswarrow", + unicodeslot=0x2922, + }, + [0x2923]={ + category="sm", + description="NORTH WEST ARROW WITH HOOK", + direction="on", + linebreak="al", + mathclass="relation", + mathname="lhooknwarrow", + unicodeslot=0x2923, + }, + [0x2924]={ + category="sm", + description="NORTH EAST ARROW WITH HOOK", + direction="on", + linebreak="al", + mathclass="relation", + mathname="rhooknearrow", + unicodeslot=0x2924, + }, + [0x2925]={ + category="sm", + description="SOUTH EAST ARROW WITH HOOK", + direction="on", + linebreak="al", + mathclass="relation", + mathname="lhooksearrow", + unicodeslot=0x2925, + }, + [0x2926]={ + category="sm", + description="SOUTH WEST ARROW WITH HOOK", + direction="on", + linebreak="al", + mathclass="relation", + mathname="rhookswarrow", + unicodeslot=0x2926, + }, + [0x2927]={ + category="sm", + description="NORTH WEST ARROW AND NORTH EAST ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2927, + }, + [0x2928]={ + category="sm", + description="NORTH EAST ARROW AND SOUTH EAST ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2928, + }, + [0x2929]={ + category="sm", + description="SOUTH EAST ARROW AND SOUTH WEST ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2929, + }, + [0x292A]={ + category="sm", + description="SOUTH WEST ARROW AND NORTH WEST ARROW", + direction="on", + linebreak="al", + unicodeslot=0x292A, + }, + [0x292B]={ + category="sm", + description="RISING DIAGONAL CROSSING FALLING DIAGONAL", + direction="on", + linebreak="al", + unicodeslot=0x292B, + }, + [0x292C]={ + category="sm", + description="FALLING DIAGONAL CROSSING RISING DIAGONAL", + direction="on", + linebreak="al", + unicodeslot=0x292C, + }, + [0x292D]={ + category="sm", + description="SOUTH EAST ARROW CROSSING NORTH EAST ARROW", + direction="on", + linebreak="al", + unicodeslot=0x292D, + }, + [0x292E]={ + category="sm", + description="NORTH EAST ARROW CROSSING SOUTH EAST ARROW", + direction="on", + linebreak="al", + unicodeslot=0x292E, + }, + [0x292F]={ + category="sm", + description="FALLING DIAGONAL CROSSING NORTH EAST ARROW", + direction="on", + linebreak="al", + unicodeslot=0x292F, + }, + [0x2930]={ + category="sm", + description="RISING DIAGONAL CROSSING SOUTH EAST ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2930, + }, + [0x2931]={ + category="sm", + description="NORTH EAST ARROW CROSSING NORTH WEST ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2931, + }, + [0x2932]={ + category="sm", + description="NORTH WEST ARROW CROSSING NORTH EAST ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2932, + }, + [0x2933]={ + category="sm", + description="WAVE ARROW POINTING DIRECTLY RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x2933, + }, + [0x2934]={ + category="sm", + description="ARROW POINTING RIGHTWARDS THEN CURVING UPWARDS", + direction="on", + linebreak="al", + unicodeslot=0x2934, + }, + [0x2935]={ + category="sm", + description="ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS", + direction="on", + linebreak="al", + unicodeslot=0x2935, + }, + [0x2936]={ + category="sm", + description="ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS", + direction="on", + linebreak="al", + unicodeslot=0x2936, + }, + [0x2937]={ + category="sm", + description="ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS", + direction="on", + linebreak="al", + unicodeslot=0x2937, + }, + [0x2938]={ + category="sm", + description="RIGHT-SIDE ARC CLOCKWISE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2938, + }, + [0x2939]={ + category="sm", + description="LEFT-SIDE ARC ANTICLOCKWISE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2939, + }, + [0x293A]={ + category="sm", + description="TOP ARC ANTICLOCKWISE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x293A, + }, + [0x293B]={ + category="sm", + description="BOTTOM ARC ANTICLOCKWISE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x293B, + }, + [0x293C]={ + category="sm", + description="TOP ARC CLOCKWISE ARROW WITH MINUS", + direction="on", + linebreak="al", + unicodeslot=0x293C, + }, + [0x293D]={ + category="sm", + description="TOP ARC ANTICLOCKWISE ARROW WITH PLUS", + direction="on", + linebreak="al", + unicodeslot=0x293D, + }, + [0x293E]={ + category="sm", + description="LOWER RIGHT SEMICIRCULAR CLOCKWISE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x293E, + }, + [0x293F]={ + category="sm", + description="LOWER LEFT SEMICIRCULAR ANTICLOCKWISE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x293F, + }, + [0x2940]={ + category="sm", + description="ANTICLOCKWISE CLOSED CIRCLE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2940, + }, + [0x2941]={ + category="sm", + description="CLOCKWISE CLOSED CIRCLE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2941, + }, + [0x2942]={ + category="sm", + description="RIGHTWARDS ARROW ABOVE SHORT LEFTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2942, + }, + [0x2943]={ + category="sm", + description="LEFTWARDS ARROW ABOVE SHORT RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2943, + }, + [0x2944]={ + category="sm", + description="SHORT RIGHTWARDS ARROW ABOVE LEFTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2944, + }, + [0x2945]={ + category="sm", + description="RIGHTWARDS ARROW WITH PLUS BELOW", + direction="on", + linebreak="al", + unicodeslot=0x2945, + }, + [0x2946]={ + category="sm", + description="LEFTWARDS ARROW WITH PLUS BELOW", + direction="on", + linebreak="al", + unicodeslot=0x2946, + }, + [0x2947]={ + category="sm", + description="RIGHTWARDS ARROW THROUGH X", + direction="on", + linebreak="al", + unicodeslot=0x2947, + }, + [0x2948]={ + category="sm", + description="LEFT RIGHT ARROW THROUGH SMALL CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x2948, + }, + [0x2949]={ + category="sm", + description="UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x2949, + }, + [0x294A]={ + category="sm", + description="LEFT BARB UP RIGHT BARB DOWN HARPOON", + direction="on", + linebreak="al", + unicodeslot=0x294A, + }, + [0x294B]={ + category="sm", + description="LEFT BARB DOWN RIGHT BARB UP HARPOON", + direction="on", + linebreak="al", + unicodeslot=0x294B, + }, + [0x294C]={ + category="sm", + description="UP BARB RIGHT DOWN BARB LEFT HARPOON", + direction="on", + linebreak="al", + unicodeslot=0x294C, + }, + [0x294D]={ + category="sm", + description="UP BARB LEFT DOWN BARB RIGHT HARPOON", + direction="on", + linebreak="al", + unicodeslot=0x294D, + }, + [0x294E]={ + category="sm", + description="LEFT BARB UP RIGHT BARB UP HARPOON", + direction="on", + linebreak="al", + unicodeslot=0x294E, + }, + [0x294F]={ + category="sm", + description="UP BARB RIGHT DOWN BARB RIGHT HARPOON", + direction="on", + linebreak="al", + unicodeslot=0x294F, + }, + [0x2950]={ + category="sm", + description="LEFT BARB DOWN RIGHT BARB DOWN HARPOON", + direction="on", + linebreak="al", + unicodeslot=0x2950, + }, + [0x2951]={ + category="sm", + description="UP BARB LEFT DOWN BARB LEFT HARPOON", + direction="on", + linebreak="al", + unicodeslot=0x2951, + }, + [0x2952]={ + category="sm", + description="LEFTWARDS HARPOON WITH BARB UP TO BAR", + direction="on", + linebreak="al", + unicodeslot=0x2952, + }, + [0x2953]={ + category="sm", + description="RIGHTWARDS HARPOON WITH BARB UP TO BAR", + direction="on", + linebreak="al", + unicodeslot=0x2953, + }, + [0x2954]={ + category="sm", + description="UPWARDS HARPOON WITH BARB RIGHT TO BAR", + direction="on", + linebreak="al", + unicodeslot=0x2954, + }, + [0x2955]={ + category="sm", + description="DOWNWARDS HARPOON WITH BARB RIGHT TO BAR", + direction="on", + linebreak="al", + unicodeslot=0x2955, + }, + [0x2956]={ + category="sm", + description="LEFTWARDS HARPOON WITH BARB DOWN TO BAR", + direction="on", + linebreak="al", + unicodeslot=0x2956, + }, + [0x2957]={ + category="sm", + description="RIGHTWARDS HARPOON WITH BARB DOWN TO BAR", + direction="on", + linebreak="al", + unicodeslot=0x2957, + }, + [0x2958]={ + category="sm", + description="UPWARDS HARPOON WITH BARB LEFT TO BAR", + direction="on", + linebreak="al", + unicodeslot=0x2958, + }, + [0x2959]={ + category="sm", + description="DOWNWARDS HARPOON WITH BARB LEFT TO BAR", + direction="on", + linebreak="al", + unicodeslot=0x2959, + }, + [0x295A]={ + category="sm", + description="LEFTWARDS HARPOON WITH BARB UP FROM BAR", + direction="on", + linebreak="al", + unicodeslot=0x295A, + }, + [0x295B]={ + category="sm", + description="RIGHTWARDS HARPOON WITH BARB UP FROM BAR", + direction="on", + linebreak="al", + unicodeslot=0x295B, + }, + [0x295C]={ + category="sm", + description="UPWARDS HARPOON WITH BARB RIGHT FROM BAR", + direction="on", + linebreak="al", + unicodeslot=0x295C, + }, + [0x295D]={ + category="sm", + description="DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR", + direction="on", + linebreak="al", + unicodeslot=0x295D, + }, + [0x295E]={ + category="sm", + description="LEFTWARDS HARPOON WITH BARB DOWN FROM BAR", + direction="on", + linebreak="al", + unicodeslot=0x295E, + }, + [0x295F]={ + category="sm", + description="RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR", + direction="on", + linebreak="al", + unicodeslot=0x295F, + }, + [0x2960]={ + category="sm", + description="UPWARDS HARPOON WITH BARB LEFT FROM BAR", + direction="on", + linebreak="al", + unicodeslot=0x2960, + }, + [0x2961]={ + category="sm", + description="DOWNWARDS HARPOON WITH BARB LEFT FROM BAR", + direction="on", + linebreak="al", + unicodeslot=0x2961, + }, + [0x2962]={ + category="sm", + description="LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN", + direction="on", + linebreak="al", + unicodeslot=0x2962, + }, + [0x2963]={ + category="sm", + description="UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x2963, + }, + [0x2964]={ + category="sm", + description="RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN", + direction="on", + linebreak="al", + unicodeslot=0x2964, + }, + [0x2965]={ + category="sm", + description="DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x2965, + }, + [0x2966]={ + category="sm", + description="LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP", + direction="on", + linebreak="al", + unicodeslot=0x2966, + }, + [0x2967]={ + category="sm", + description="LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN", + direction="on", + linebreak="al", + unicodeslot=0x2967, + }, + [0x2968]={ + category="sm", + description="RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP", + direction="on", + linebreak="al", + unicodeslot=0x2968, + }, + [0x2969]={ + category="sm", + description="RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN", + direction="on", + linebreak="al", + unicodeslot=0x2969, + }, + [0x296A]={ + category="sm", + description="LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH", + direction="on", + linebreak="al", + unicodeslot=0x296A, + }, + [0x296B]={ + category="sm", + description="LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH", + direction="on", + linebreak="al", + unicodeslot=0x296B, + }, + [0x296C]={ + category="sm", + description="RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH", + direction="on", + linebreak="al", + unicodeslot=0x296C, + }, + [0x296D]={ + category="sm", + description="RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH", + direction="on", + linebreak="al", + unicodeslot=0x296D, + }, + [0x296E]={ + category="sm", + description="UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x296E, + }, + [0x296F]={ + category="sm", + description="DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x296F, + }, + [0x2970]={ + category="sm", + description="RIGHT DOUBLE ARROW WITH ROUNDED HEAD", + direction="on", + linebreak="al", + unicodeslot=0x2970, + }, + [0x2971]={ + category="sm", + description="EQUALS SIGN ABOVE RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2971, + }, + [0x2972]={ + category="sm", + description="TILDE OPERATOR ABOVE RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2972, + }, + [0x2973]={ + category="sm", + description="LEFTWARDS ARROW ABOVE TILDE OPERATOR", + direction="on", + linebreak="al", + unicodeslot=0x2973, + }, + [0x2974]={ + category="sm", + description="RIGHTWARDS ARROW ABOVE TILDE OPERATOR", + direction="on", + linebreak="al", + unicodeslot=0x2974, + }, + [0x2975]={ + category="sm", + description="RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO", + direction="on", + linebreak="al", + unicodeslot=0x2975, + }, + [0x2976]={ + category="sm", + description="LESS-THAN ABOVE LEFTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2976, + }, + [0x2977]={ + category="sm", + description="LEFTWARDS ARROW THROUGH LESS-THAN", + direction="on", + linebreak="al", + unicodeslot=0x2977, + }, + [0x2978]={ + category="sm", + description="GREATER-THAN ABOVE RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2978, + }, + [0x2979]={ + category="sm", + description="SUBSET ABOVE RIGHTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2979, + }, + [0x297A]={ + category="sm", + description="LEFTWARDS ARROW THROUGH SUBSET", + direction="on", + linebreak="al", + unicodeslot=0x297A, + }, + [0x297B]={ + category="sm", + description="SUPERSET ABOVE LEFTWARDS ARROW", + direction="on", + linebreak="al", + unicodeslot=0x297B, + }, + [0x297C]={ + category="sm", + description="LEFT FISH TAIL", + direction="on", + linebreak="al", + unicodeslot=0x297C, + }, + [0x297D]={ + category="sm", + description="RIGHT FISH TAIL", + direction="on", + linebreak="al", + unicodeslot=0x297D, + }, + [0x297E]={ + category="sm", + description="UP FISH TAIL", + direction="on", + linebreak="al", + unicodeslot=0x297E, + }, + [0x297F]={ + category="sm", + description="DOWN FISH TAIL", + direction="on", + linebreak="al", + unicodeslot=0x297F, + }, + [0x2980]={ + category="sm", + description="TRIPLE VERTICAL BAR DELIMITER", + direction="on", + linebreak="al", + unicodeslot=0x2980, + }, + [0x2981]={ + category="sm", + description="Z NOTATION SPOT", + direction="on", + linebreak="al", + unicodeslot=0x2981, + }, + [0x2982]={ + category="sm", + description="Z NOTATION TYPE COLON", + direction="on", + linebreak="al", + unicodeslot=0x2982, + }, + [0x2983]={ + category="ps", + description="LEFT WHITE CURLY BRACKET", + direction="on", + linebreak="op", + mirror=0x2984, + unicodeslot=0x2983, + }, + [0x2984]={ + category="pe", + description="RIGHT WHITE CURLY BRACKET", + direction="on", + linebreak="cl", + mirror=0x2983, + unicodeslot=0x2984, + }, + [0x2985]={ + category="ps", + cjkwd="na", + description="LEFT WHITE PARENTHESIS", + direction="on", + linebreak="op", + mirror=0x2986, + unicodeslot=0x2985, + }, + [0x2986]={ + category="pe", + cjkwd="na", + description="RIGHT WHITE PARENTHESIS", + direction="on", + linebreak="cl", + mirror=0x2985, + unicodeslot=0x2986, + }, + [0x2987]={ + category="ps", + description="Z NOTATION LEFT IMAGE BRACKET", + direction="on", + linebreak="op", + mirror=0x2988, + unicodeslot=0x2987, + }, + [0x2988]={ + category="pe", + description="Z NOTATION RIGHT IMAGE BRACKET", + direction="on", + linebreak="cl", + mirror=0x2987, + unicodeslot=0x2988, + }, + [0x2989]={ + category="ps", + description="Z NOTATION LEFT BINDING BRACKET", + direction="on", + linebreak="op", + mirror=0x298A, + unicodeslot=0x2989, + }, + [0x298A]={ + category="pe", + description="Z NOTATION RIGHT BINDING BRACKET", + direction="on", + linebreak="cl", + mirror=0x2989, + unicodeslot=0x298A, + }, + [0x298B]={ + category="ps", + description="LEFT SQUARE BRACKET WITH UNDERBAR", + direction="on", + linebreak="op", + mirror=0x298C, + unicodeslot=0x298B, + }, + [0x298C]={ + category="pe", + description="RIGHT SQUARE BRACKET WITH UNDERBAR", + direction="on", + linebreak="cl", + mirror=0x298B, + unicodeslot=0x298C, + }, + [0x298D]={ + category="ps", + description="LEFT SQUARE BRACKET WITH TICK IN TOP CORNER", + direction="on", + linebreak="op", + mirror=0x2990, + unicodeslot=0x298D, + }, + [0x298E]={ + category="pe", + description="RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER", + direction="on", + linebreak="cl", + mirror=0x298F, + unicodeslot=0x298E, + }, + [0x298F]={ + category="ps", + description="LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER", + direction="on", + linebreak="op", + mirror=0x298E, + unicodeslot=0x298F, + }, + [0x2990]={ + category="pe", + description="RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER", + direction="on", + linebreak="cl", + mirror=0x298D, + unicodeslot=0x2990, + }, + [0x2991]={ + category="ps", + description="LEFT ANGLE BRACKET WITH DOT", + direction="on", + linebreak="op", + mirror=0x2992, + unicodeslot=0x2991, + }, + [0x2992]={ + category="pe", + description="RIGHT ANGLE BRACKET WITH DOT", + direction="on", + linebreak="cl", + mirror=0x2991, + unicodeslot=0x2992, + }, + [0x2993]={ + category="ps", + description="LEFT ARC LESS-THAN BRACKET", + direction="on", + linebreak="op", + mirror=0x2994, + unicodeslot=0x2993, + }, + [0x2994]={ + category="pe", + description="RIGHT ARC GREATER-THAN BRACKET", + direction="on", + linebreak="cl", + mirror=0x2993, + unicodeslot=0x2994, + }, + [0x2995]={ + category="ps", + description="DOUBLE LEFT ARC GREATER-THAN BRACKET", + direction="on", + linebreak="op", + mirror=0x2996, + unicodeslot=0x2995, + }, + [0x2996]={ + category="pe", + description="DOUBLE RIGHT ARC LESS-THAN BRACKET", + direction="on", + linebreak="cl", + mirror=0x2995, + unicodeslot=0x2996, + }, + [0x2997]={ + category="ps", + description="LEFT BLACK TORTOISE SHELL BRACKET", + direction="on", + linebreak="op", + mirror=0x2998, + unicodeslot=0x2997, + }, + [0x2998]={ + category="pe", + description="RIGHT BLACK TORTOISE SHELL BRACKET", + direction="on", + linebreak="cl", + mirror=0x2997, + unicodeslot=0x2998, + }, + [0x2999]={ + category="sm", + description="DOTTED FENCE", + direction="on", + linebreak="al", + unicodeslot=0x2999, + }, + [0x299A]={ + category="sm", + description="VERTICAL ZIGZAG LINE", + direction="on", + linebreak="al", + unicodeslot=0x299A, + }, + [0x299B]={ + category="sm", + description="MEASURED ANGLE OPENING LEFT", + direction="on", + linebreak="al", + unicodeslot=0x299B, + }, + [0x299C]={ + category="sm", + description="RIGHT ANGLE VARIANT WITH SQUARE", + direction="on", + linebreak="al", + unicodeslot=0x299C, + }, + [0x299D]={ + category="sm", + description="MEASURED RIGHT ANGLE WITH DOT", + direction="on", + linebreak="al", + unicodeslot=0x299D, + }, + [0x299E]={ + category="sm", + description="ANGLE WITH S INSIDE", + direction="on", + linebreak="al", + unicodeslot=0x299E, + }, + [0x299F]={ + category="sm", + description="ACUTE ANGLE", + direction="on", + linebreak="al", + unicodeslot=0x299F, + }, + [0x29A0]={ + category="sm", + description="SPHERICAL ANGLE OPENING LEFT", + direction="on", + linebreak="al", + unicodeslot=0x29A0, + }, + [0x29A1]={ + category="sm", + description="SPHERICAL ANGLE OPENING UP", + direction="on", + linebreak="al", + unicodeslot=0x29A1, + }, + [0x29A2]={ + category="sm", + description="TURNED ANGLE", + direction="on", + linebreak="al", + unicodeslot=0x29A2, + }, + [0x29A3]={ + category="sm", + description="REVERSED ANGLE", + direction="on", + linebreak="al", + unicodeslot=0x29A3, + }, + [0x29A4]={ + category="sm", + description="ANGLE WITH UNDERBAR", + direction="on", + linebreak="al", + unicodeslot=0x29A4, + }, + [0x29A5]={ + category="sm", + description="REVERSED ANGLE WITH UNDERBAR", + direction="on", + linebreak="al", + unicodeslot=0x29A5, + }, + [0x29A6]={ + category="sm", + description="OBLIQUE ANGLE OPENING UP", + direction="on", + linebreak="al", + unicodeslot=0x29A6, + }, + [0x29A7]={ + category="sm", + description="OBLIQUE ANGLE OPENING DOWN", + direction="on", + linebreak="al", + unicodeslot=0x29A7, + }, + [0x29A8]={ + category="sm", + description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x29A8, + }, + [0x29A9]={ + category="sm", + description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT", + direction="on", + linebreak="al", + unicodeslot=0x29A9, + }, + [0x29AA]={ + category="sm", + description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x29AA, + }, + [0x29AB]={ + category="sm", + description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT", + direction="on", + linebreak="al", + unicodeslot=0x29AB, + }, + [0x29AC]={ + category="sm", + description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP", + direction="on", + linebreak="al", + unicodeslot=0x29AC, + }, + [0x29AD]={ + category="sm", + description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP", + direction="on", + linebreak="al", + unicodeslot=0x29AD, + }, + [0x29AE]={ + category="sm", + description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN", + direction="on", + linebreak="al", + unicodeslot=0x29AE, + }, + [0x29AF]={ + category="sm", + description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN", + direction="on", + linebreak="al", + unicodeslot=0x29AF, + }, + [0x29B0]={ + category="sm", + description="REVERSED EMPTY SET", + direction="on", + linebreak="al", + unicodeslot=0x29B0, + }, + [0x29B1]={ + category="sm", + description="EMPTY SET WITH OVERBAR", + direction="on", + linebreak="al", + unicodeslot=0x29B1, + }, + [0x29B2]={ + category="sm", + description="EMPTY SET WITH SMALL CIRCLE ABOVE", + direction="on", + linebreak="al", + unicodeslot=0x29B2, + }, + [0x29B3]={ + category="sm", + description="EMPTY SET WITH RIGHT ARROW ABOVE", + direction="on", + linebreak="al", + unicodeslot=0x29B3, + }, + [0x29B4]={ + category="sm", + description="EMPTY SET WITH LEFT ARROW ABOVE", + direction="on", + linebreak="al", + unicodeslot=0x29B4, + }, + [0x29B5]={ + category="sm", + description="CIRCLE WITH HORIZONTAL BAR", + direction="on", + linebreak="al", + unicodeslot=0x29B5, + }, + [0x29B6]={ + category="sm", + description="CIRCLED VERTICAL BAR", + direction="on", + linebreak="al", + unicodeslot=0x29B6, + }, + [0x29B7]={ + category="sm", + description="CIRCLED PARALLEL", + direction="on", + linebreak="al", + unicodeslot=0x29B7, + }, + [0x29B8]={ + category="sm", + description="CIRCLED REVERSE SOLIDUS", + direction="on", + linebreak="al", + mirror=0x2298, + unicodeslot=0x29B8, + }, + [0x29B9]={ + category="sm", + description="CIRCLED PERPENDICULAR", + direction="on", + linebreak="al", + unicodeslot=0x29B9, + }, + [0x29BA]={ + category="sm", + description="CIRCLE DIVIDED BY HORIZONTAL BAR AND TOP HALF DIVIDED BY VERTICAL BAR", + direction="on", + linebreak="al", + unicodeslot=0x29BA, + }, + [0x29BB]={ + category="sm", + description="CIRCLE WITH SUPERIMPOSED X", + direction="on", + linebreak="al", + unicodeslot=0x29BB, + }, + [0x29BC]={ + category="sm", + description="CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN", + direction="on", + linebreak="al", + unicodeslot=0x29BC, + }, + [0x29BD]={ + category="sm", + description="UP ARROW THROUGH CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x29BD, + }, + [0x29BE]={ + category="sm", + description="CIRCLED WHITE BULLET", + direction="on", + linebreak="al", + unicodeslot=0x29BE, + }, + [0x29BF]={ + category="sm", + description="CIRCLED BULLET", + direction="on", + linebreak="al", + unicodeslot=0x29BF, + }, + [0x29C0]={ + category="sm", + description="CIRCLED LESS-THAN", + direction="on", + linebreak="al", + mirror=0x29C1, + unicodeslot=0x29C0, + }, + [0x29C1]={ + category="sm", + description="CIRCLED GREATER-THAN", + direction="on", + linebreak="al", + mirror=0x29C0, + unicodeslot=0x29C1, + }, + [0x29C2]={ + category="sm", + description="CIRCLE WITH SMALL CIRCLE TO THE RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x29C2, + }, + [0x29C3]={ + category="sm", + description="CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT", + direction="on", + linebreak="al", + unicodeslot=0x29C3, + }, + [0x29C4]={ + category="sm", + description="SQUARED RISING DIAGONAL SLASH", + direction="on", + linebreak="al", + mirror=0x29C5, + unicodeslot=0x29C4, + }, + [0x29C5]={ + category="sm", + description="SQUARED FALLING DIAGONAL SLASH", + direction="on", + linebreak="al", + mirror=0x29C4, + unicodeslot=0x29C5, + }, + [0x29C6]={ + category="sm", + description="SQUARED ASTERISK", + direction="on", + linebreak="al", + unicodeslot=0x29C6, + }, + [0x29C7]={ + category="sm", + description="SQUARED SMALL CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x29C7, + }, + [0x29C8]={ + category="sm", + description="SQUARED SQUARE", + direction="on", + linebreak="al", + unicodeslot=0x29C8, + }, + [0x29C9]={ + category="sm", + description="TWO JOINED SQUARES", + direction="on", + linebreak="al", + unicodeslot=0x29C9, + }, + [0x29CA]={ + category="sm", + description="TRIANGLE WITH DOT ABOVE", + direction="on", + linebreak="al", + unicodeslot=0x29CA, + }, + [0x29CB]={ + category="sm", + description="TRIANGLE WITH UNDERBAR", + direction="on", + linebreak="al", + unicodeslot=0x29CB, + }, + [0x29CC]={ + category="sm", + description="S IN TRIANGLE", + direction="on", + linebreak="al", + unicodeslot=0x29CC, + }, + [0x29CD]={ + category="sm", + description="TRIANGLE WITH SERIFS AT BOTTOM", + direction="on", + linebreak="al", + unicodeslot=0x29CD, + }, + [0x29CE]={ + category="sm", + description="RIGHT TRIANGLE ABOVE LEFT TRIANGLE", + direction="on", + linebreak="al", + unicodeslot=0x29CE, + }, + [0x29CF]={ + category="sm", + description="LEFT TRIANGLE BESIDE VERTICAL BAR", + direction="on", + linebreak="al", + mirror=0x29D0, + unicodeslot=0x29CF, + }, + [0x29D0]={ + category="sm", + description="VERTICAL BAR BESIDE RIGHT TRIANGLE", + direction="on", + linebreak="al", + mirror=0x29CF, + unicodeslot=0x29D0, + }, + [0x29D1]={ + category="sm", + description="BOWTIE WITH LEFT HALF BLACK", + direction="on", + linebreak="al", + mirror=0x29D2, + unicodeslot=0x29D1, + }, + [0x29D2]={ + category="sm", + description="BOWTIE WITH RIGHT HALF BLACK", + direction="on", + linebreak="al", + mirror=0x29D1, + unicodeslot=0x29D2, + }, + [0x29D3]={ + category="sm", + description="BLACK BOWTIE", + direction="on", + linebreak="al", + unicodeslot=0x29D3, + }, + [0x29D4]={ + category="sm", + description="TIMES WITH LEFT HALF BLACK", + direction="on", + linebreak="al", + mirror=0x29D5, + unicodeslot=0x29D4, + }, + [0x29D5]={ + category="sm", + description="TIMES WITH RIGHT HALF BLACK", + direction="on", + linebreak="al", + mirror=0x29D4, + unicodeslot=0x29D5, + }, + [0x29D6]={ + category="sm", + description="WHITE HOURGLASS", + direction="on", + linebreak="al", + unicodeslot=0x29D6, + }, + [0x29D7]={ + category="sm", + description="BLACK HOURGLASS", + direction="on", + linebreak="al", + unicodeslot=0x29D7, + }, + [0x29D8]={ + category="ps", + description="LEFT WIGGLY FENCE", + direction="on", + linebreak="op", + mirror=0x29D9, + unicodeslot=0x29D8, + }, + [0x29D9]={ + category="pe", + description="RIGHT WIGGLY FENCE", + direction="on", + linebreak="cl", + mirror=0x29D8, + unicodeslot=0x29D9, + }, + [0x29DA]={ + category="ps", + description="LEFT DOUBLE WIGGLY FENCE", + direction="on", + linebreak="op", + mirror=0x29DB, + unicodeslot=0x29DA, + }, + [0x29DB]={ + category="pe", + description="RIGHT DOUBLE WIGGLY FENCE", + direction="on", + linebreak="cl", + mirror=0x29DA, + unicodeslot=0x29DB, + }, + [0x29DC]={ + category="sm", + description="INCOMPLETE INFINITY", + direction="on", + linebreak="al", + unicodeslot=0x29DC, + }, + [0x29DD]={ + category="sm", + description="TIE OVER INFINITY", + direction="on", + linebreak="al", + unicodeslot=0x29DD, + }, + [0x29DE]={ + category="sm", + description="INFINITY NEGATED WITH VERTICAL BAR", + direction="on", + linebreak="al", + unicodeslot=0x29DE, + }, + [0x29DF]={ + category="sm", + description="DOUBLE-ENDED MULTIMAP", + direction="on", + linebreak="al", + unicodeslot=0x29DF, + }, + [0x29E0]={ + category="sm", + description="SQUARE WITH CONTOURED OUTLINE", + direction="on", + linebreak="al", + unicodeslot=0x29E0, + }, + [0x29E1]={ + category="sm", + description="INCREASES AS", + direction="on", + linebreak="al", + unicodeslot=0x29E1, + }, + [0x29E2]={ + category="sm", + description="SHUFFLE PRODUCT", + direction="on", + linebreak="al", + unicodeslot=0x29E2, + }, + [0x29E3]={ + category="sm", + description="EQUALS SIGN AND SLANTED PARALLEL", + direction="on", + linebreak="al", + unicodeslot=0x29E3, + }, + [0x29E4]={ + category="sm", + description="EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE", + direction="on", + linebreak="al", + unicodeslot=0x29E4, + }, + [0x29E5]={ + category="sm", + description="IDENTICAL TO AND SLANTED PARALLEL", + direction="on", + linebreak="al", + unicodeslot=0x29E5, + }, + [0x29E6]={ + category="sm", + description="GLEICH STARK", + direction="on", + linebreak="al", + unicodeslot=0x29E6, + }, + [0x29E7]={ + category="sm", + description="THERMODYNAMIC", + direction="on", + linebreak="al", + unicodeslot=0x29E7, + }, + [0x29E8]={ + category="sm", + description="DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK", + direction="on", + linebreak="al", + unicodeslot=0x29E8, + }, + [0x29E9]={ + category="sm", + description="DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK", + direction="on", + linebreak="al", + unicodeslot=0x29E9, + }, + [0x29EA]={ + category="sm", + description="BLACK DIAMOND WITH DOWN ARROW", + direction="on", + linebreak="al", + unicodeslot=0x29EA, + }, + [0x29EB]={ + category="sm", + description="BLACK LOZENGE", + direction="on", + linebreak="al", + mathclass="ord", + mathname="blacklozenge", + unicodeslot=0x29EB, + }, + [0x29EC]={ + category="sm", + description="WHITE CIRCLE WITH DOWN ARROW", + direction="on", + linebreak="al", + unicodeslot=0x29EC, + }, + [0x29ED]={ + category="sm", + description="BLACK CIRCLE WITH DOWN ARROW", + direction="on", + linebreak="al", + unicodeslot=0x29ED, + }, + [0x29EE]={ + category="sm", + description="ERROR-BARRED WHITE SQUARE", + direction="on", + linebreak="al", + unicodeslot=0x29EE, + }, + [0x29EF]={ + category="sm", + description="ERROR-BARRED BLACK SQUARE", + direction="on", + linebreak="al", + unicodeslot=0x29EF, + }, + [0x29F0]={ + category="sm", + description="ERROR-BARRED WHITE DIAMOND", + direction="on", + linebreak="al", + unicodeslot=0x29F0, + }, + [0x29F1]={ + category="sm", + description="ERROR-BARRED BLACK DIAMOND", + direction="on", + linebreak="al", + unicodeslot=0x29F1, + }, + [0x29F2]={ + category="sm", + description="ERROR-BARRED WHITE CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x29F2, + }, + [0x29F3]={ + category="sm", + description="ERROR-BARRED BLACK CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x29F3, + }, + [0x29F4]={ + category="sm", + description="RULE-DELAYED", + direction="on", + linebreak="al", + unicodeslot=0x29F4, + }, + [0x29F5]={ + category="sm", + description="REVERSE SOLIDUS OPERATOR", + direction="on", + linebreak="al", + mirror=0x2215, + unicodeslot=0x29F5, + }, + [0x29F6]={ + category="sm", + description="SOLIDUS WITH OVERBAR", + direction="on", + linebreak="al", + unicodeslot=0x29F6, + }, + [0x29F7]={ + category="sm", + description="REVERSE SOLIDUS WITH HORIZONTAL STROKE", + direction="on", + linebreak="al", + unicodeslot=0x29F7, + }, + [0x29F8]={ + category="sm", + description="BIG SOLIDUS", + direction="on", + linebreak="al", + mirror=0x29F9, + unicodeslot=0x29F8, + }, + [0x29F9]={ + category="sm", + description="BIG REVERSE SOLIDUS", + direction="on", + linebreak="al", + mirror=0x29F8, + unicodeslot=0x29F9, + }, + [0x29FA]={ + category="sm", + description="DOUBLE PLUS", + direction="on", + linebreak="al", + unicodeslot=0x29FA, + }, + [0x29FB]={ + category="sm", + description="TRIPLE PLUS", + direction="on", + linebreak="al", + unicodeslot=0x29FB, + }, + [0x29FC]={ + category="ps", + description="LEFT-POINTING CURVED ANGLE BRACKET", + direction="on", + linebreak="op", + mirror=0x29FD, + unicodeslot=0x29FC, + }, + [0x29FD]={ + category="pe", + description="RIGHT-POINTING CURVED ANGLE BRACKET", + direction="on", + linebreak="cl", + mirror=0x29FC, + unicodeslot=0x29FD, + }, + [0x29FE]={ + category="sm", + description="TINY", + direction="on", + linebreak="al", + unicodeslot=0x29FE, + }, + [0x29FF]={ + category="sm", + description="MINY", + direction="on", + linebreak="al", + unicodeslot=0x29FF, + }, + [0x2A00]={ + category="sm", + description="N-ARY CIRCLED DOT OPERATOR", + direction="on", + linebreak="al", + unicodeslot=0x2A00, + }, + [0x2A01]={ + category="sm", + description="N-ARY CIRCLED PLUS OPERATOR", + direction="on", + linebreak="al", + mathclass="limop", + mathname="bigoplus", + unicodeslot=0x2A01, + }, + [0x2A02]={ + category="sm", + description="N-ARY CIRCLED TIMES OPERATOR", + direction="on", + linebreak="al", + mathclass="limop", + mathname="bigotimes", + unicodeslot=0x2A02, + }, + [0x2A03]={ + category="sm", + description="N-ARY UNION OPERATOR WITH DOT", + direction="on", + linebreak="al", + mathclass="limop", + mathname="bigodot", + unicodeslot=0x2A03, + }, + [0x2A04]={ + category="sm", + description="N-ARY UNION OPERATOR WITH PLUS", + direction="on", + linebreak="al", + mathclass="limop", + mathname="biguplus", + unicodeslot=0x2A04, + }, + [0x2A05]={ + category="sm", + description="N-ARY SQUARE INTERSECTION OPERATOR", + direction="on", + linebreak="al", + mathclass="limop", + mathname="bigsqcap", + unicodeslot=0x2A05, + }, + [0x2A06]={ + category="sm", + description="N-ARY SQUARE UNION OPERATOR", + direction="on", + linebreak="al", + mathclass="limop", + mathname="bigsqcup", + unicodeslot=0x2A06, + }, + [0x2A07]={ + category="sm", + description="TWO LOGICAL AND OPERATOR", + direction="on", + linebreak="al", + unicodeslot=0x2A07, + }, + [0x2A08]={ + category="sm", + description="TWO LOGICAL OR OPERATOR", + direction="on", + linebreak="al", + unicodeslot=0x2A08, + }, + [0x2A09]={ + category="sm", + description="N-ARY TIMES OPERATOR", + direction="on", + linebreak="al", + mathclass="limop", + mathname="bigtimes", + unicodeslot=0x2A09, + }, + [0x2A0A]={ + category="sm", + description="MODULO TWO SUM", + direction="on", + linebreak="al", + unicodeslot=0x2A0A, + }, + [0x2A0B]={ + category="sm", + description="SUMMATION WITH INTEGRAL", + direction="on", + linebreak="al", + unicodeslot=0x2A0B, + }, + [0x2A0C]={ + category="sm", + description="QUADRUPLE INTEGRAL OPERATOR", + direction="on", + linebreak="al", + specials={ "compat", 0x222B, 0x222B, 0x222B, 0x222B }, + unicodeslot=0x2A0C, + }, + [0x2A0D]={ + category="sm", + description="FINITE PART INTEGRAL", + direction="on", + linebreak="al", + unicodeslot=0x2A0D, + }, + [0x2A0E]={ + category="sm", + description="INTEGRAL WITH DOUBLE STROKE", + direction="on", + linebreak="al", + unicodeslot=0x2A0E, + }, + [0x2A0F]={ + category="sm", + description="INTEGRAL AVERAGE WITH SLASH", + direction="on", + linebreak="al", + unicodeslot=0x2A0F, + }, + [0x2A10]={ + category="sm", + description="CIRCULATION FUNCTION", + direction="on", + linebreak="al", + unicodeslot=0x2A10, + }, + [0x2A11]={ + category="sm", + description="ANTICLOCKWISE INTEGRATION", + direction="on", + linebreak="al", + unicodeslot=0x2A11, + }, + [0x2A12]={ + category="sm", + description="LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE", + direction="on", + linebreak="al", + unicodeslot=0x2A12, + }, + [0x2A13]={ + category="sm", + description="LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE", + direction="on", + linebreak="al", + unicodeslot=0x2A13, + }, + [0x2A14]={ + category="sm", + description="LINE INTEGRATION NOT INCLUDING THE POLE", + direction="on", + linebreak="al", + unicodeslot=0x2A14, + }, + [0x2A15]={ + category="sm", + description="INTEGRAL AROUND A POINT OPERATOR", + direction="on", + linebreak="al", + unicodeslot=0x2A15, + }, + [0x2A16]={ + category="sm", + description="QUATERNION INTEGRAL OPERATOR", + direction="on", + linebreak="al", + unicodeslot=0x2A16, + }, + [0x2A17]={ + category="sm", + description="INTEGRAL WITH LEFTWARDS ARROW WITH HOOK", + direction="on", + linebreak="al", + unicodeslot=0x2A17, + }, + [0x2A18]={ + category="sm", + description="INTEGRAL WITH TIMES SIGN", + direction="on", + linebreak="al", + unicodeslot=0x2A18, + }, + [0x2A19]={ + category="sm", + description="INTEGRAL WITH INTERSECTION", + direction="on", + linebreak="al", + unicodeslot=0x2A19, + }, + [0x2A1A]={ + category="sm", + description="INTEGRAL WITH UNION", + direction="on", + linebreak="al", + unicodeslot=0x2A1A, + }, + [0x2A1B]={ + category="sm", + description="INTEGRAL WITH OVERBAR", + direction="on", + linebreak="al", + unicodeslot=0x2A1B, + }, + [0x2A1C]={ + category="sm", + description="INTEGRAL WITH UNDERBAR", + direction="on", + linebreak="al", + unicodeslot=0x2A1C, + }, + [0x2A1D]={ + category="sm", + description="JOIN", + direction="on", + linebreak="al", + unicodeslot=0x2A1D, + }, + [0x2A1E]={ + category="sm", + description="LARGE LEFT TRIANGLE OPERATOR", + direction="on", + linebreak="al", + unicodeslot=0x2A1E, + }, + [0x2A1F]={ + category="sm", + description="Z NOTATION SCHEMA COMPOSITION", + direction="on", + linebreak="al", + unicodeslot=0x2A1F, + }, + [0x2A20]={ + category="sm", + description="Z NOTATION SCHEMA PIPING", + direction="on", + linebreak="al", + unicodeslot=0x2A20, + }, + [0x2A21]={ + category="sm", + description="Z NOTATION SCHEMA PROJECTION", + direction="on", + linebreak="al", + unicodeslot=0x2A21, + }, + [0x2A22]={ + category="sm", + description="PLUS SIGN WITH SMALL CIRCLE ABOVE", + direction="on", + linebreak="al", + unicodeslot=0x2A22, + }, + [0x2A23]={ + category="sm", + description="PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE", + direction="on", + linebreak="al", + unicodeslot=0x2A23, + }, + [0x2A24]={ + category="sm", + description="PLUS SIGN WITH TILDE ABOVE", + direction="on", + linebreak="al", + unicodeslot=0x2A24, + }, + [0x2A25]={ + category="sm", + description="PLUS SIGN WITH DOT BELOW", + direction="on", + linebreak="al", + unicodeslot=0x2A25, + }, + [0x2A26]={ + category="sm", + description="PLUS SIGN WITH TILDE BELOW", + direction="on", + linebreak="al", + unicodeslot=0x2A26, + }, + [0x2A27]={ + category="sm", + description="PLUS SIGN WITH SUBSCRIPT TWO", + direction="on", + linebreak="al", + unicodeslot=0x2A27, + }, + [0x2A28]={ + category="sm", + description="PLUS SIGN WITH BLACK TRIANGLE", + direction="on", + linebreak="al", + unicodeslot=0x2A28, + }, + [0x2A29]={ + category="sm", + description="MINUS SIGN WITH COMMA ABOVE", + direction="on", + linebreak="al", + unicodeslot=0x2A29, + }, + [0x2A2A]={ + category="sm", + description="MINUS SIGN WITH DOT BELOW", + direction="on", + linebreak="al", + unicodeslot=0x2A2A, + }, + [0x2A2B]={ + category="sm", + description="MINUS SIGN WITH FALLING DOTS", + direction="on", + linebreak="al", + mirror=0x2A2C, + unicodeslot=0x2A2B, + }, + [0x2A2C]={ + category="sm", + description="MINUS SIGN WITH RISING DOTS", + direction="on", + linebreak="al", + mirror=0x2A2B, + unicodeslot=0x2A2C, + }, + [0x2A2D]={ + category="sm", + description="PLUS SIGN IN LEFT HALF CIRCLE", + direction="on", + linebreak="al", + mirror=0x2A2E, + unicodeslot=0x2A2D, + }, + [0x2A2E]={ + category="sm", + description="PLUS SIGN IN RIGHT HALF CIRCLE", + direction="on", + linebreak="al", + mirror=0x2A2D, + unicodeslot=0x2A2E, + }, + [0x2A2F]={ + category="sm", + description="VECTOR OR CROSS PRODUCT", + direction="on", + linebreak="al", + unicodeslot=0x2A2F, + }, + [0x2A30]={ + category="sm", + description="MULTIPLICATION SIGN WITH DOT ABOVE", + direction="on", + linebreak="al", + unicodeslot=0x2A30, + }, + [0x2A31]={ + category="sm", + description="MULTIPLICATION SIGN WITH UNDERBAR", + direction="on", + linebreak="al", + unicodeslot=0x2A31, + }, + [0x2A32]={ + category="sm", + description="SEMIDIRECT PRODUCT WITH BOTTOM CLOSED", + direction="on", + linebreak="al", + unicodeslot=0x2A32, + }, + [0x2A33]={ + category="sm", + description="SMASH PRODUCT", + direction="on", + linebreak="al", + unicodeslot=0x2A33, + }, + [0x2A34]={ + category="sm", + description="MULTIPLICATION SIGN IN LEFT HALF CIRCLE", + direction="on", + linebreak="al", + mirror=0x2A35, + unicodeslot=0x2A34, + }, + [0x2A35]={ + category="sm", + description="MULTIPLICATION SIGN IN RIGHT HALF CIRCLE", + direction="on", + linebreak="al", + mirror=0x2A34, + unicodeslot=0x2A35, + }, + [0x2A36]={ + category="sm", + description="CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT", + direction="on", + linebreak="al", + unicodeslot=0x2A36, + }, + [0x2A37]={ + category="sm", + description="MULTIPLICATION SIGN IN DOUBLE CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x2A37, + }, + [0x2A38]={ + category="sm", + description="CIRCLED DIVISION SIGN", + direction="on", + linebreak="al", + unicodeslot=0x2A38, + }, + [0x2A39]={ + category="sm", + description="PLUS SIGN IN TRIANGLE", + direction="on", + linebreak="al", + unicodeslot=0x2A39, + }, + [0x2A3A]={ + category="sm", + description="MINUS SIGN IN TRIANGLE", + direction="on", + linebreak="al", + unicodeslot=0x2A3A, + }, + [0x2A3B]={ + category="sm", + description="MULTIPLICATION SIGN IN TRIANGLE", + direction="on", + linebreak="al", + unicodeslot=0x2A3B, + }, + [0x2A3C]={ + category="sm", + description="INTERIOR PRODUCT", + direction="on", + linebreak="al", + mirror=0x2A3D, + unicodeslot=0x2A3C, + }, + [0x2A3D]={ + category="sm", + description="RIGHTHAND INTERIOR PRODUCT", + direction="on", + linebreak="al", + mirror=0x2A3C, + unicodeslot=0x2A3D, + }, + [0x2A3E]={ + category="sm", + description="Z NOTATION RELATIONAL COMPOSITION", + direction="on", + linebreak="al", + unicodeslot=0x2A3E, + }, + [0x2A3F]={ + category="sm", + description="AMALGAMATION OR COPRODUCT", + direction="on", + linebreak="al", + mathclass="binary", + mathname="amalg", + unicodeslot=0x2A3F, + }, + [0x2A40]={ + category="sm", + description="INTERSECTION WITH DOT", + direction="on", + linebreak="al", + unicodeslot=0x2A40, + }, + [0x2A41]={ + category="sm", + description="UNION WITH MINUS SIGN", + direction="on", + linebreak="al", + unicodeslot=0x2A41, + }, + [0x2A42]={ + category="sm", + description="UNION WITH OVERBAR", + direction="on", + linebreak="al", + unicodeslot=0x2A42, + }, + [0x2A43]={ + category="sm", + description="INTERSECTION WITH OVERBAR", + direction="on", + linebreak="al", + unicodeslot=0x2A43, + }, + [0x2A44]={ + category="sm", + description="INTERSECTION WITH LOGICAL AND", + direction="on", + linebreak="al", + unicodeslot=0x2A44, + }, + [0x2A45]={ + category="sm", + description="UNION WITH LOGICAL OR", + direction="on", + linebreak="al", + unicodeslot=0x2A45, + }, + [0x2A46]={ + category="sm", + description="UNION ABOVE INTERSECTION", + direction="on", + linebreak="al", + unicodeslot=0x2A46, + }, + [0x2A47]={ + category="sm", + description="INTERSECTION ABOVE UNION", + direction="on", + linebreak="al", + unicodeslot=0x2A47, + }, + [0x2A48]={ + category="sm", + description="UNION ABOVE BAR ABOVE INTERSECTION", + direction="on", + linebreak="al", + unicodeslot=0x2A48, + }, + [0x2A49]={ + category="sm", + description="INTERSECTION ABOVE BAR ABOVE UNION", + direction="on", + linebreak="al", + unicodeslot=0x2A49, + }, + [0x2A4A]={ + category="sm", + description="UNION BESIDE AND JOINED WITH UNION", + direction="on", + linebreak="al", + unicodeslot=0x2A4A, + }, + [0x2A4B]={ + category="sm", + description="INTERSECTION BESIDE AND JOINED WITH INTERSECTION", + direction="on", + linebreak="al", + unicodeslot=0x2A4B, + }, + [0x2A4C]={ + category="sm", + description="CLOSED UNION WITH SERIFS", + direction="on", + linebreak="al", + unicodeslot=0x2A4C, + }, + [0x2A4D]={ + category="sm", + description="CLOSED INTERSECTION WITH SERIFS", + direction="on", + linebreak="al", + unicodeslot=0x2A4D, + }, + [0x2A4E]={ + category="sm", + description="DOUBLE SQUARE INTERSECTION", + direction="on", + linebreak="al", + unicodeslot=0x2A4E, + }, + [0x2A4F]={ + category="sm", + description="DOUBLE SQUARE UNION", + direction="on", + linebreak="al", + unicodeslot=0x2A4F, + }, + [0x2A50]={ + category="sm", + description="CLOSED UNION WITH SERIFS AND SMASH PRODUCT", + direction="on", + linebreak="al", + unicodeslot=0x2A50, + }, + [0x2A51]={ + category="sm", + description="LOGICAL AND WITH DOT ABOVE", + direction="on", + linebreak="al", + unicodeslot=0x2A51, + }, + [0x2A52]={ + category="sm", + description="LOGICAL OR WITH DOT ABOVE", + direction="on", + linebreak="al", + unicodeslot=0x2A52, + }, + [0x2A53]={ + category="sm", + description="DOUBLE LOGICAL AND", + direction="on", + linebreak="al", + unicodeslot=0x2A53, + }, + [0x2A54]={ + category="sm", + description="DOUBLE LOGICAL OR", + direction="on", + linebreak="al", + unicodeslot=0x2A54, + }, + [0x2A55]={ + category="sm", + description="TWO INTERSECTING LOGICAL AND", + direction="on", + linebreak="al", + unicodeslot=0x2A55, + }, + [0x2A56]={ + category="sm", + description="TWO INTERSECTING LOGICAL OR", + direction="on", + linebreak="al", + unicodeslot=0x2A56, + }, + [0x2A57]={ + category="sm", + description="SLOPING LARGE OR", + direction="on", + linebreak="al", + unicodeslot=0x2A57, + }, + [0x2A58]={ + category="sm", + description="SLOPING LARGE AND", + direction="on", + linebreak="al", + unicodeslot=0x2A58, + }, + [0x2A59]={ + category="sm", + description="LOGICAL OR OVERLAPPING LOGICAL AND", + direction="on", + linebreak="al", + unicodeslot=0x2A59, + }, + [0x2A5A]={ + category="sm", + description="LOGICAL AND WITH MIDDLE STEM", + direction="on", + linebreak="al", + unicodeslot=0x2A5A, + }, + [0x2A5B]={ + category="sm", + description="LOGICAL OR WITH MIDDLE STEM", + direction="on", + linebreak="al", + unicodeslot=0x2A5B, + }, + [0x2A5C]={ + category="sm", + description="LOGICAL AND WITH HORIZONTAL DASH", + direction="on", + linebreak="al", + unicodeslot=0x2A5C, + }, + [0x2A5D]={ + category="sm", + description="LOGICAL OR WITH HORIZONTAL DASH", + direction="on", + linebreak="al", + unicodeslot=0x2A5D, + }, + [0x2A5E]={ + category="sm", + description="LOGICAL AND WITH DOUBLE OVERBAR", + direction="on", + linebreak="al", + unicodeslot=0x2A5E, + }, + [0x2A5F]={ + category="sm", + description="LOGICAL AND WITH UNDERBAR", + direction="on", + linebreak="al", + unicodeslot=0x2A5F, + }, + [0x2A60]={ + category="sm", + description="LOGICAL AND WITH DOUBLE UNDERBAR", + direction="on", + linebreak="al", + unicodeslot=0x2A60, + }, + [0x2A61]={ + category="sm", + description="SMALL VEE WITH UNDERBAR", + direction="on", + linebreak="al", + unicodeslot=0x2A61, + }, + [0x2A62]={ + category="sm", + description="LOGICAL OR WITH DOUBLE OVERBAR", + direction="on", + linebreak="al", + unicodeslot=0x2A62, + }, + [0x2A63]={ + category="sm", + description="LOGICAL OR WITH DOUBLE UNDERBAR", + direction="on", + linebreak="al", + unicodeslot=0x2A63, + }, + [0x2A64]={ + category="sm", + description="Z NOTATION DOMAIN ANTIRESTRICTION", + direction="on", + linebreak="al", + mirror=0x2A65, + unicodeslot=0x2A64, + }, + [0x2A65]={ + category="sm", + description="Z NOTATION RANGE ANTIRESTRICTION", + direction="on", + linebreak="al", + mirror=0x2A64, + unicodeslot=0x2A65, + }, + [0x2A66]={ + category="sm", + description="EQUALS SIGN WITH DOT BELOW", + direction="on", + linebreak="al", + unicodeslot=0x2A66, + }, + [0x2A67]={ + category="sm", + description="IDENTICAL WITH DOT ABOVE", + direction="on", + linebreak="al", + unicodeslot=0x2A67, + }, + [0x2A68]={ + category="sm", + description="TRIPLE HORIZONTAL BAR WITH DOUBLE VERTICAL STROKE", + direction="on", + linebreak="al", + unicodeslot=0x2A68, + }, + [0x2A69]={ + category="sm", + description="TRIPLE HORIZONTAL BAR WITH TRIPLE VERTICAL STROKE", + direction="on", + linebreak="al", + unicodeslot=0x2A69, + }, + [0x2A6A]={ + category="sm", + description="TILDE OPERATOR WITH DOT ABOVE", + direction="on", + linebreak="al", + unicodeslot=0x2A6A, + }, + [0x2A6B]={ + category="sm", + description="TILDE OPERATOR WITH RISING DOTS", + direction="on", + linebreak="al", + unicodeslot=0x2A6B, + }, + [0x2A6C]={ + category="sm", + description="SIMILAR MINUS SIMILAR", + direction="on", + linebreak="al", + unicodeslot=0x2A6C, + }, + [0x2A6D]={ + category="sm", + description="CONGRUENT WITH DOT ABOVE", + direction="on", + linebreak="al", + unicodeslot=0x2A6D, + }, + [0x2A6E]={ + category="sm", + description="EQUALS WITH ASTERISK", + direction="on", + linebreak="al", + unicodeslot=0x2A6E, + }, + [0x2A6F]={ + category="sm", + description="ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT", + direction="on", + linebreak="al", + unicodeslot=0x2A6F, + }, + [0x2A70]={ + category="sm", + description="APPROXIMATELY EQUAL OR EQUAL TO", + direction="on", + linebreak="al", + unicodeslot=0x2A70, + }, + [0x2A71]={ + category="sm", + description="EQUALS SIGN ABOVE PLUS SIGN", + direction="on", + linebreak="al", + unicodeslot=0x2A71, + }, + [0x2A72]={ + category="sm", + description="PLUS SIGN ABOVE EQUALS SIGN", + direction="on", + linebreak="al", + unicodeslot=0x2A72, + }, + [0x2A73]={ + category="sm", + description="EQUALS SIGN ABOVE TILDE OPERATOR", + direction="on", + linebreak="al", + unicodeslot=0x2A73, + }, + [0x2A74]={ + category="sm", + description="DOUBLE COLON EQUAL", + direction="on", + linebreak="al", + specials={ "compat", 0x003A, 0x003A, 0x003D }, + unicodeslot=0x2A74, + }, + [0x2A75]={ + category="sm", + description="TWO CONSECUTIVE EQUALS SIGNS", + direction="on", + linebreak="al", + specials={ "compat", 0x003D, 0x003D }, + unicodeslot=0x2A75, + }, + [0x2A76]={ + category="sm", + description="THREE CONSECUTIVE EQUALS SIGNS", + direction="on", + linebreak="al", + specials={ "compat", 0x003D, 0x003D, 0x003D }, + unicodeslot=0x2A76, + }, + [0x2A77]={ + category="sm", + description="EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW", + direction="on", + linebreak="al", + unicodeslot=0x2A77, + }, + [0x2A78]={ + category="sm", + description="EQUIVALENT WITH FOUR DOTS ABOVE", + direction="on", + linebreak="al", + unicodeslot=0x2A78, + }, + [0x2A79]={ + category="sm", + description="LESS-THAN WITH CIRCLE INSIDE", + direction="on", + linebreak="al", + mirror=0x2A7A, + unicodeslot=0x2A79, + }, + [0x2A7A]={ + category="sm", + description="GREATER-THAN WITH CIRCLE INSIDE", + direction="on", + linebreak="al", + mirror=0x2A79, + unicodeslot=0x2A7A, + }, + [0x2A7B]={ + category="sm", + description="LESS-THAN WITH QUESTION MARK ABOVE", + direction="on", + linebreak="al", + unicodeslot=0x2A7B, + }, + [0x2A7C]={ + category="sm", + description="GREATER-THAN WITH QUESTION MARK ABOVE", + direction="on", + linebreak="al", + unicodeslot=0x2A7C, + }, + [0x2A7D]={ + category="sm", + description="LESS-THAN OR SLANTED EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="leqslant", + mirror=0x2A7E, + unicodeslot=0x2A7D, + }, + [0x2A7E]={ + category="sm", + description="GREATER-THAN OR SLANTED EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="geqslant", + mirror=0x2A7D, + unicodeslot=0x2A7E, + }, + [0x2A7F]={ + category="sm", + description="LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE", + direction="on", + linebreak="al", + mirror=0x2A80, + unicodeslot=0x2A7F, + }, + [0x2A80]={ + category="sm", + description="GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE", + direction="on", + linebreak="al", + mirror=0x2A7F, + unicodeslot=0x2A80, + }, + [0x2A81]={ + category="sm", + description="LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE", + direction="on", + linebreak="al", + mirror=0x2A82, + unicodeslot=0x2A81, + }, + [0x2A82]={ + category="sm", + description="GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE", + direction="on", + linebreak="al", + mirror=0x2A81, + unicodeslot=0x2A82, + }, + [0x2A83]={ + category="sm", + description="LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT", + direction="on", + linebreak="al", + mirror=0x2A84, + unicodeslot=0x2A83, + }, + [0x2A84]={ + category="sm", + description="GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT", + direction="on", + linebreak="al", + mirror=0x2A83, + unicodeslot=0x2A84, + }, + [0x2A85]={ + category="sm", + description="LESS-THAN OR APPROXIMATE", + direction="on", + linebreak="al", + mathclass="relation", + mathname="lessapprox", + unicodeslot=0x2A85, + }, + [0x2A86]={ + category="sm", + description="GREATER-THAN OR APPROXIMATE", + direction="on", + linebreak="al", + mathclass="relation", + mathname="gtrapprox", + unicodeslot=0x2A86, + }, + [0x2A87]={ + category="sm", + description="LESS-THAN AND SINGLE-LINE NOT EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="lneq", + unicodeslot=0x2A87, + }, + [0x2A88]={ + category="sm", + description="GREATER-THAN AND SINGLE-LINE NOT EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="rneq", + unicodeslot=0x2A88, + }, + [0x2A89]={ + category="sm", + description="LESS-THAN AND NOT APPROXIMATE", + direction="on", + linebreak="al", + mathclass="relation", + mathname="lnapprox", + unicodeslot=0x2A89, + }, + [0x2A8A]={ + category="sm", + description="GREATER-THAN AND NOT APPROXIMATE", + direction="on", + linebreak="al", + mathclass="relation", + mathname="gnapprox", + unicodeslot=0x2A8A, + }, + [0x2A8B]={ + category="sm", + description="LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN", + direction="on", + linebreak="al", + mathclass="relation", + mathname="lesseqqgtr", + mirror=0x2A8C, + unicodeslot=0x2A8B, + }, + [0x2A8C]={ + category="sm", + description="GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN", + direction="on", + linebreak="al", + mathclass="relation", + mathname="gtreqqless", + mirror=0x2A8B, + unicodeslot=0x2A8C, + }, + [0x2A8D]={ + category="sm", + description="LESS-THAN ABOVE SIMILAR OR EQUAL", + direction="on", + linebreak="al", + unicodeslot=0x2A8D, + }, + [0x2A8E]={ + category="sm", + description="GREATER-THAN ABOVE SIMILAR OR EQUAL", + direction="on", + linebreak="al", + unicodeslot=0x2A8E, + }, + [0x2A8F]={ + category="sm", + description="LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN", + direction="on", + linebreak="al", + unicodeslot=0x2A8F, + }, + [0x2A90]={ + category="sm", + description="GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN", + direction="on", + linebreak="al", + unicodeslot=0x2A90, + }, + [0x2A91]={ + category="sm", + description="LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL", + direction="on", + linebreak="al", + mirror=0x2A92, + unicodeslot=0x2A91, + }, + [0x2A92]={ + category="sm", + description="GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL", + direction="on", + linebreak="al", + mirror=0x2A91, + unicodeslot=0x2A92, + }, + [0x2A93]={ + category="sm", + description="LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL", + direction="on", + linebreak="al", + mirror=0x2A94, + unicodeslot=0x2A93, + }, + [0x2A94]={ + category="sm", + description="GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL", + direction="on", + linebreak="al", + mirror=0x2A93, + unicodeslot=0x2A94, + }, + [0x2A95]={ + category="sm", + description="SLANTED EQUAL TO OR LESS-THAN", + direction="on", + linebreak="al", + mathclass="relation", + mathname="eqslantless", + mirror=0x2A96, + unicodeslot=0x2A95, + }, + [0x2A96]={ + category="sm", + description="SLANTED EQUAL TO OR GREATER-THAN", + direction="on", + linebreak="al", + mathclass="relation", + mathname="eqslantgtr", + mirror=0x2A95, + unicodeslot=0x2A96, + }, + [0x2A97]={ + category="sm", + description="SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE", + direction="on", + linebreak="al", + mirror=0x2A98, + unicodeslot=0x2A97, + }, + [0x2A98]={ + category="sm", + description="SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE", + direction="on", + linebreak="al", + mirror=0x2A97, + unicodeslot=0x2A98, + }, + [0x2A99]={ + category="sm", + description="DOUBLE-LINE EQUAL TO OR LESS-THAN", + direction="on", + linebreak="al", + mirror=0x2A9A, + unicodeslot=0x2A99, + }, + [0x2A9A]={ + category="sm", + description="DOUBLE-LINE EQUAL TO OR GREATER-THAN", + direction="on", + linebreak="al", + mirror=0x2A99, + unicodeslot=0x2A9A, + }, + [0x2A9B]={ + category="sm", + description="DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN", + direction="on", + linebreak="al", + mirror=0x2A9C, + unicodeslot=0x2A9B, + }, + [0x2A9C]={ + category="sm", + description="DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN", + direction="on", + linebreak="al", + mirror=0x2A9B, + unicodeslot=0x2A9C, + }, + [0x2A9D]={ + category="sm", + description="SIMILAR OR LESS-THAN", + direction="on", + linebreak="al", + unicodeslot=0x2A9D, + }, + [0x2A9E]={ + category="sm", + description="SIMILAR OR GREATER-THAN", + direction="on", + linebreak="al", + unicodeslot=0x2A9E, + }, + [0x2A9F]={ + category="sm", + description="SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN", + direction="on", + linebreak="al", + unicodeslot=0x2A9F, + }, + [0x2AA0]={ + category="sm", + description="SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN", + direction="on", + linebreak="al", + unicodeslot=0x2AA0, + }, + [0x2AA1]={ + category="sm", + description="DOUBLE NESTED LESS-THAN", + direction="on", + linebreak="al", + mirror=0x2AA2, + unicodeslot=0x2AA1, + }, + [0x2AA2]={ + category="sm", + description="DOUBLE NESTED GREATER-THAN", + direction="on", + linebreak="al", + mirror=0x2AA1, + unicodeslot=0x2AA2, + }, + [0x2AA3]={ + category="sm", + description="DOUBLE NESTED LESS-THAN WITH UNDERBAR", + direction="on", + linebreak="al", + unicodeslot=0x2AA3, + }, + [0x2AA4]={ + category="sm", + description="GREATER-THAN OVERLAPPING LESS-THAN", + direction="on", + linebreak="al", + unicodeslot=0x2AA4, + }, + [0x2AA5]={ + category="sm", + description="GREATER-THAN BESIDE LESS-THAN", + direction="on", + linebreak="al", + unicodeslot=0x2AA5, + }, + [0x2AA6]={ + category="sm", + description="LESS-THAN CLOSED BY CURVE", + direction="on", + linebreak="al", + mirror=0x2AA7, + unicodeslot=0x2AA6, + }, + [0x2AA7]={ + category="sm", + description="GREATER-THAN CLOSED BY CURVE", + direction="on", + linebreak="al", + mirror=0x2AA6, + unicodeslot=0x2AA7, + }, + [0x2AA8]={ + category="sm", + description="LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL", + direction="on", + linebreak="al", + mirror=0x2AA9, + unicodeslot=0x2AA8, + }, + [0x2AA9]={ + category="sm", + description="GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL", + direction="on", + linebreak="al", + mirror=0x2AA8, + unicodeslot=0x2AA9, + }, + [0x2AAA]={ + category="sm", + description="SMALLER THAN", + direction="on", + linebreak="al", + mirror=0x2AAB, + unicodeslot=0x2AAA, + }, + [0x2AAB]={ + category="sm", + description="LARGER THAN", + direction="on", + linebreak="al", + mirror=0x2AAA, + unicodeslot=0x2AAB, + }, + [0x2AAC]={ + category="sm", + description="SMALLER THAN OR EQUAL TO", + direction="on", + linebreak="al", + mirror=0x2AAD, + unicodeslot=0x2AAC, + }, + [0x2AAD]={ + category="sm", + description="LARGER THAN OR EQUAL TO", + direction="on", + linebreak="al", + mirror=0x2AAC, + unicodeslot=0x2AAD, + }, + [0x2AAE]={ + category="sm", + description="EQUALS SIGN WITH BUMPY ABOVE", + direction="on", + linebreak="al", + unicodeslot=0x2AAE, + }, + [0x2AAF]={ + category="sm", + description="PRECEDES ABOVE SINGLE-LINE EQUALS SIGN", + direction="on", + linebreak="al", + mathclass="relation", + mathname="preceq", + mirror=0x2AB0, + unicodeslot=0x2AAF, + }, + [0x2AB0]={ + category="sm", + description="SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN", + direction="on", + linebreak="al", + mathclass="relation", + mathname="succeq", + mirror=0x2AAF, + unicodeslot=0x2AB0, + }, + [0x2AB1]={ + category="sm", + description="PRECEDES ABOVE SINGLE-LINE NOT EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="precneq", + unicodeslot=0x2AB1, + }, + [0x2AB2]={ + category="sm", + description="SUCCEEDS ABOVE SINGLE-LINE NOT EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="succneq", + unicodeslot=0x2AB2, + }, + [0x2AB3]={ + category="sm", + description="PRECEDES ABOVE EQUALS SIGN", + direction="on", + linebreak="al", + mathclass="relation", + mathname="preceqq", + mirror=0x2AB4, + unicodeslot=0x2AB3, + }, + [0x2AB4]={ + category="sm", + description="SUCCEEDS ABOVE EQUALS SIGN", + direction="on", + linebreak="al", + mathclass="relation", + mathname="succeqq", + mirror=0x2AB3, + unicodeslot=0x2AB4, + }, + [0x2AB5]={ + category="sm", + description="PRECEDES ABOVE NOT EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="precneqq", + unicodeslot=0x2AB5, + }, + [0x2AB6]={ + category="sm", + description="SUCCEEDS ABOVE NOT EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="succneqq", + unicodeslot=0x2AB6, + }, + [0x2AB7]={ + category="sm", + description="PRECEDES ABOVE ALMOST EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="precapprox", + unicodeslot=0x2AB7, + }, + [0x2AB8]={ + category="sm", + description="SUCCEEDS ABOVE ALMOST EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="succapprox", + unicodeslot=0x2AB8, + }, + [0x2AB9]={ + category="sm", + description="PRECEDES ABOVE NOT ALMOST EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="precnapprox", + unicodeslot=0x2AB9, + }, + [0x2ABA]={ + category="sm", + description="SUCCEEDS ABOVE NOT ALMOST EQUAL TO", + direction="on", + linebreak="al", + mathclass="relation", + mathname="succnapprox", + unicodeslot=0x2ABA, + }, + [0x2ABB]={ + category="sm", + description="DOUBLE PRECEDES", + direction="on", + linebreak="al", + mirror=0x2ABC, + unicodeslot=0x2ABB, + }, + [0x2ABC]={ + category="sm", + description="DOUBLE SUCCEEDS", + direction="on", + linebreak="al", + mirror=0x2ABB, + unicodeslot=0x2ABC, + }, + [0x2ABD]={ + category="sm", + description="SUBSET WITH DOT", + direction="on", + linebreak="al", + mirror=0x2ABE, + unicodeslot=0x2ABD, + }, + [0x2ABE]={ + category="sm", + description="SUPERSET WITH DOT", + direction="on", + linebreak="al", + mirror=0x2ABD, + unicodeslot=0x2ABE, + }, + [0x2ABF]={ + category="sm", + description="SUBSET WITH PLUS SIGN BELOW", + direction="on", + linebreak="al", + mirror=0x2AC0, + unicodeslot=0x2ABF, + }, + [0x2AC0]={ + category="sm", + description="SUPERSET WITH PLUS SIGN BELOW", + direction="on", + linebreak="al", + mirror=0x2ABF, + unicodeslot=0x2AC0, + }, + [0x2AC1]={ + category="sm", + description="SUBSET WITH MULTIPLICATION SIGN BELOW", + direction="on", + linebreak="al", + mirror=0x2AC2, + unicodeslot=0x2AC1, + }, + [0x2AC2]={ + category="sm", + description="SUPERSET WITH MULTIPLICATION SIGN BELOW", + direction="on", + linebreak="al", + mirror=0x2AC1, + unicodeslot=0x2AC2, + }, + [0x2AC3]={ + category="sm", + description="SUBSET OF OR EQUAL TO WITH DOT ABOVE", + direction="on", + linebreak="al", + mirror=0x2AC4, + unicodeslot=0x2AC3, + }, + [0x2AC4]={ + category="sm", + description="SUPERSET OF OR EQUAL TO WITH DOT ABOVE", + direction="on", + linebreak="al", + mirror=0x2AC3, + unicodeslot=0x2AC4, + }, + [0x2AC5]={ + category="sm", + description="SUBSET OF ABOVE EQUALS SIGN", + direction="on", + linebreak="al", + mathclass="relation", + mathname="subseteqq", + mirror=0x2AC6, + unicodeslot=0x2AC5, + }, + [0x2AC6]={ + category="sm", + description="SUPERSET OF ABOVE EQUALS SIGN", + direction="on", + linebreak="al", + mathclass="relation", + mathname="supseteqq", + mirror=0x2AC5, + unicodeslot=0x2AC6, + }, + [0x2AC7]={ + category="sm", + description="SUBSET OF ABOVE TILDE OPERATOR", + direction="on", + linebreak="al", + unicodeslot=0x2AC7, + }, + [0x2AC8]={ + category="sm", + description="SUPERSET OF ABOVE TILDE OPERATOR", + direction="on", + linebreak="al", + unicodeslot=0x2AC8, + }, + [0x2AC9]={ + category="sm", + description="SUBSET OF ABOVE ALMOST EQUAL TO", + direction="on", + linebreak="al", + unicodeslot=0x2AC9, + }, + [0x2ACA]={ + category="sm", + description="SUPERSET OF ABOVE ALMOST EQUAL TO", + direction="on", + linebreak="al", + unicodeslot=0x2ACA, + }, + [0x2ACB]={ + category="sm", + description="SUBSET OF ABOVE NOT EQUAL TO", + direction="on", + mathclass="relation", + mathname="subsetneqq", + linebreak="al", + unicodeslot=0x2ACB, + }, + [0x2ACC]={ + category="sm", + description="SUPERSET OF ABOVE NOT EQUAL TO", + direction="on", + mathclass="relation", + mathname="supsetneqq", + linebreak="al", + unicodeslot=0x2ACC, + }, + [0x2ACD]={ + category="sm", + description="SQUARE LEFT OPEN BOX OPERATOR", + direction="on", + linebreak="al", + mirror=0x2ACE, + unicodeslot=0x2ACD, + }, + [0x2ACE]={ + category="sm", + description="SQUARE RIGHT OPEN BOX OPERATOR", + direction="on", + linebreak="al", + mirror=0x2ACD, + unicodeslot=0x2ACE, + }, + [0x2ACF]={ + category="sm", + description="CLOSED SUBSET", + direction="on", + linebreak="al", + mirror=0x2AD0, + unicodeslot=0x2ACF, + }, + [0x2AD0]={ + category="sm", + description="CLOSED SUPERSET", + direction="on", + linebreak="al", + mirror=0x2ACF, + unicodeslot=0x2AD0, + }, + [0x2AD1]={ + category="sm", + description="CLOSED SUBSET OR EQUAL TO", + direction="on", + linebreak="al", + mirror=0x2AD2, + unicodeslot=0x2AD1, + }, + [0x2AD2]={ + category="sm", + description="CLOSED SUPERSET OR EQUAL TO", + direction="on", + linebreak="al", + mirror=0x2AD1, + unicodeslot=0x2AD2, + }, + [0x2AD3]={ + category="sm", + description="SUBSET ABOVE SUPERSET", + direction="on", + linebreak="al", + mirror=0x2AD4, + unicodeslot=0x2AD3, + }, + [0x2AD4]={ + category="sm", + description="SUPERSET ABOVE SUBSET", + direction="on", + linebreak="al", + mirror=0x2AD3, + unicodeslot=0x2AD4, + }, + [0x2AD5]={ + category="sm", + description="SUBSET ABOVE SUBSET", + direction="on", + linebreak="al", + mirror=0x2AD6, + unicodeslot=0x2AD5, + }, + [0x2AD6]={ + category="sm", + description="SUPERSET ABOVE SUPERSET", + direction="on", + linebreak="al", + mirror=0x2AD5, + unicodeslot=0x2AD6, + }, + [0x2AD7]={ + category="sm", + description="SUPERSET BESIDE SUBSET", + direction="on", + linebreak="al", + unicodeslot=0x2AD7, + }, + [0x2AD8]={ + category="sm", + description="SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET", + direction="on", + linebreak="al", + unicodeslot=0x2AD8, + }, + [0x2AD9]={ + category="sm", + description="ELEMENT OF OPENING DOWNWARDS", + direction="on", + linebreak="al", + unicodeslot=0x2AD9, + }, + [0x2ADA]={ + category="sm", + description="PITCHFORK WITH TEE TOP", + direction="on", + linebreak="al", + unicodeslot=0x2ADA, + }, + [0x2ADB]={ + category="sm", + description="TRANSVERSAL INTERSECTION", + direction="on", + linebreak="al", + unicodeslot=0x2ADB, + }, + [0x2ADC]={ + category="sm", + description="FORKING", + direction="on", + linebreak="al", + specials={ "char", 0x2ADD, 0x0338 }, + unicodeslot=0x2ADC, + }, + [0x2ADD]={ + category="sm", + description="NONFORKING", + direction="on", + linebreak="al", + unicodeslot=0x2ADD, + }, + [0x2ADE]={ + category="sm", + description="SHORT LEFT TACK", + direction="on", + linebreak="al", + mirror=0x22A6, + unicodeslot=0x2ADE, + }, + [0x2ADF]={ + category="sm", + description="SHORT DOWN TACK", + direction="on", + linebreak="al", + unicodeslot=0x2ADF, + }, + [0x2AE0]={ + category="sm", + description="SHORT UP TACK", + direction="on", + linebreak="al", + unicodeslot=0x2AE0, + }, + [0x2AE1]={ + category="sm", + description="PERPENDICULAR WITH S", + direction="on", + linebreak="al", + unicodeslot=0x2AE1, + }, + [0x2AE2]={ + category="sm", + description="VERTICAL BAR TRIPLE RIGHT TURNSTILE", + direction="on", + linebreak="al", + unicodeslot=0x2AE2, + }, + [0x2AE3]={ + category="sm", + description="DOUBLE VERTICAL BAR LEFT TURNSTILE", + direction="on", + linebreak="al", + mirror=0x22A9, + unicodeslot=0x2AE3, + }, + [0x2AE4]={ + category="sm", + description="VERTICAL BAR DOUBLE LEFT TURNSTILE", + direction="on", + linebreak="al", + mirror=0x22A8, + unicodeslot=0x2AE4, + }, + [0x2AE5]={ + category="sm", + description="DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE", + direction="on", + linebreak="al", + mirror=0x22AB, + unicodeslot=0x2AE5, + }, + [0x2AE6]={ + category="sm", + description="LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL", + direction="on", + linebreak="al", + unicodeslot=0x2AE6, + }, + [0x2AE7]={ + category="sm", + description="SHORT DOWN TACK WITH OVERBAR", + direction="on", + linebreak="al", + unicodeslot=0x2AE7, + }, + [0x2AE8]={ + category="sm", + description="SHORT UP TACK WITH UNDERBAR", + direction="on", + linebreak="al", + unicodeslot=0x2AE8, + }, + [0x2AE9]={ + category="sm", + description="SHORT UP TACK ABOVE SHORT DOWN TACK", + direction="on", + linebreak="al", + unicodeslot=0x2AE9, + }, + [0x2AEA]={ + category="sm", + description="DOUBLE DOWN TACK", + direction="on", + linebreak="al", + unicodeslot=0x2AEA, + }, + [0x2AEB]={ + category="sm", + description="DOUBLE UP TACK", + direction="on", + linebreak="al", + unicodeslot=0x2AEB, + }, + [0x2AEC]={ + category="sm", + description="DOUBLE STROKE NOT SIGN", + direction="on", + linebreak="al", + mirror=0x2AED, + unicodeslot=0x2AEC, + }, + [0x2AED]={ + category="sm", + description="REVERSED DOUBLE STROKE NOT SIGN", + direction="on", + linebreak="al", + mirror=0x2AEC, + unicodeslot=0x2AED, + }, + [0x2AEE]={ + category="sm", + description="DOES NOT DIVIDE WITH REVERSED NEGATION SLASH", + direction="on", + linebreak="al", + unicodeslot=0x2AEE, + }, + [0x2AEF]={ + category="sm", + description="VERTICAL LINE WITH CIRCLE ABOVE", + direction="on", + linebreak="al", + unicodeslot=0x2AEF, + }, + [0x2AF0]={ + category="sm", + description="VERTICAL LINE WITH CIRCLE BELOW", + direction="on", + linebreak="al", + unicodeslot=0x2AF0, + }, + [0x2AF1]={ + category="sm", + description="DOWN TACK WITH CIRCLE BELOW", + direction="on", + linebreak="al", + unicodeslot=0x2AF1, + }, + [0x2AF2]={ + category="sm", + description="PARALLEL WITH HORIZONTAL STROKE", + direction="on", + linebreak="al", + unicodeslot=0x2AF2, + }, + [0x2AF3]={ + category="sm", + description="PARALLEL WITH TILDE OPERATOR", + direction="on", + linebreak="al", + unicodeslot=0x2AF3, + }, + [0x2AF4]={ + category="sm", + description="TRIPLE VERTICAL BAR BINARY RELATION", + direction="on", + linebreak="al", + unicodeslot=0x2AF4, + }, + [0x2AF5]={ + category="sm", + description="TRIPLE VERTICAL BAR WITH HORIZONTAL STROKE", + direction="on", + linebreak="al", + unicodeslot=0x2AF5, + }, + [0x2AF6]={ + category="sm", + description="TRIPLE COLON OPERATOR", + direction="on", + linebreak="al", + unicodeslot=0x2AF6, + }, + [0x2AF7]={ + category="sm", + description="TRIPLE NESTED LESS-THAN", + direction="on", + linebreak="al", + mirror=0x2AF8, + unicodeslot=0x2AF7, + }, + [0x2AF8]={ + category="sm", + description="TRIPLE NESTED GREATER-THAN", + direction="on", + linebreak="al", + mirror=0x2AF7, + unicodeslot=0x2AF8, + }, + [0x2AF9]={ + category="sm", + description="DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO", + direction="on", + linebreak="al", + mirror=0x2AFA, + unicodeslot=0x2AF9, + }, + [0x2AFA]={ + category="sm", + description="DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO", + direction="on", + linebreak="al", + mirror=0x2AF9, + unicodeslot=0x2AFA, + }, + [0x2AFB]={ + category="sm", + description="TRIPLE SOLIDUS BINARY RELATION", + direction="on", + linebreak="al", + unicodeslot=0x2AFB, + }, + [0x2AFC]={ + category="sm", + description="LARGE TRIPLE VERTICAL BAR OPERATOR", + direction="on", + linebreak="al", + unicodeslot=0x2AFC, + }, + [0x2AFD]={ + category="sm", + description="DOUBLE SOLIDUS OPERATOR", + direction="on", + linebreak="al", + unicodeslot=0x2AFD, + }, + [0x2AFE]={ + category="sm", + description="WHITE VERTICAL BAR", + direction="on", + linebreak="al", + unicodeslot=0x2AFE, + }, + [0x2AFF]={ + category="sm", + description="N-ARY WHITE VERTICAL BAR", + direction="on", + linebreak="al", + unicodeslot=0x2AFF, + }, + [0x2B00]={ + category="so", + description="NORTH EAST WHITE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2B00, + }, + [0x2B01]={ + category="so", + description="NORTH WEST WHITE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2B01, + }, + [0x2B02]={ + category="so", + description="SOUTH EAST WHITE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2B02, + }, + [0x2B03]={ + category="so", + description="SOUTH WEST WHITE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2B03, + }, + [0x2B04]={ + category="so", + description="LEFT RIGHT WHITE ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2B04, + }, + [0x2B05]={ + category="so", + description="LEFTWARDS BLACK ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2B05, + }, + [0x2B06]={ + category="so", + description="UPWARDS BLACK ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2B06, + }, + [0x2B07]={ + category="so", + description="DOWNWARDS BLACK ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2B07, + }, + [0x2B08]={ + category="so", + description="NORTH EAST BLACK ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2B08, + }, + [0x2B09]={ + category="so", + description="NORTH WEST BLACK ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2B09, + }, + [0x2B0A]={ + category="so", + description="SOUTH EAST BLACK ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2B0A, + }, + [0x2B0B]={ + category="so", + description="SOUTH WEST BLACK ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2B0B, + }, + [0x2B0C]={ + category="so", + description="LEFT RIGHT BLACK ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2B0C, + }, + [0x2B0D]={ + category="so", + description="UP DOWN BLACK ARROW", + direction="on", + linebreak="al", + unicodeslot=0x2B0D, + }, + [0x2B0E]={ + category="so", + description="RIGHTWARDS ARROW WITH TIP DOWNWARDS", + direction="on", + linebreak="al", + unicodeslot=0x2B0E, + }, + [0x2B0F]={ + category="so", + description="RIGHTWARDS ARROW WITH TIP UPWARDS", + direction="on", + linebreak="al", + unicodeslot=0x2B0F, + }, + [0x2B10]={ + category="so", + description="LEFTWARDS ARROW WITH TIP DOWNWARDS", + direction="on", + linebreak="al", + unicodeslot=0x2B10, + }, + [0x2B11]={ + category="so", + description="LEFTWARDS ARROW WITH TIP UPWARDS", + direction="on", + linebreak="al", + unicodeslot=0x2B11, + }, + [0x2B12]={ + category="so", + description="SQUARE WITH TOP HALF BLACK", + direction="on", + linebreak="al", + unicodeslot=0x2B12, + }, + [0x2B13]={ + category="so", + description="SQUARE WITH BOTTOM HALF BLACK", + direction="on", + linebreak="al", + unicodeslot=0x2B13, + }, + [0x2B14]={ + category="so", + description="SQUARE WITH UPPER RIGHT DIAGONAL HALF BLACK", + direction="on", + linebreak="al", + unicodeslot=0x2B14, + }, + [0x2B15]={ + category="so", + description="SQUARE WITH LOWER LEFT DIAGONAL HALF BLACK", + direction="on", + linebreak="al", + unicodeslot=0x2B15, + }, + [0x2B16]={ + category="so", + description="DIAMOND WITH LEFT HALF BLACK", + direction="on", + linebreak="al", + unicodeslot=0x2B16, + }, + [0x2B17]={ + category="so", + description="DIAMOND WITH RIGHT HALF BLACK", + direction="on", + linebreak="al", + unicodeslot=0x2B17, + }, + [0x2B18]={ + category="so", + description="DIAMOND WITH TOP HALF BLACK", + direction="on", + linebreak="al", + unicodeslot=0x2B18, + }, + [0x2B19]={ + category="so", + description="DIAMOND WITH BOTTOM HALF BLACK", + direction="on", + linebreak="al", + unicodeslot=0x2B19, + }, + [0x2B1A]={ + category="so", + description="DOTTED SQUARE", + direction="on", + linebreak="al", + unicodeslot=0x2B1A, + }, + [0x2B20]={ + category="so", + description="WHITE PENTAGON", + direction="on", + linebreak="al", + unicodeslot=0x2B20, + }, + [0x2B21]={ + category="so", + description="WHITE HEXAGON", + direction="on", + linebreak="al", + unicodeslot=0x2B21, + }, + [0x2B22]={ + category="so", + description="BLACK HEXAGON", + direction="on", + linebreak="al", + unicodeslot=0x2B22, + }, + [0x2B23]={ + category="so", + description="HORIZONTAL BLACK HEXAGON", + direction="on", + linebreak="al", + unicodeslot=0x2B23, + }, + [0x2C00]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER AZU", + direction="l", + lccode=0x2C30, + linebreak="al", + unicodeslot=0x2C00, + }, + [0x2C01]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER BUKY", + direction="l", + lccode=0x2C31, + linebreak="al", + unicodeslot=0x2C01, + }, + [0x2C02]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER VEDE", + direction="l", + lccode=0x2C32, + linebreak="al", + unicodeslot=0x2C02, + }, + [0x2C03]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER GLAGOLI", + direction="l", + lccode=0x2C33, + linebreak="al", + unicodeslot=0x2C03, + }, + [0x2C04]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER DOBRO", + direction="l", + lccode=0x2C34, + linebreak="al", + unicodeslot=0x2C04, + }, + [0x2C05]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER YESTU", + direction="l", + lccode=0x2C35, + linebreak="al", + unicodeslot=0x2C05, + }, + [0x2C06]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER ZHIVETE", + direction="l", + lccode=0x2C36, + linebreak="al", + unicodeslot=0x2C06, + }, + [0x2C07]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER DZELO", + direction="l", + lccode=0x2C37, + linebreak="al", + unicodeslot=0x2C07, + }, + [0x2C08]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER ZEMLJA", + direction="l", + lccode=0x2C38, + linebreak="al", + unicodeslot=0x2C08, + }, + [0x2C09]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER IZHE", + direction="l", + lccode=0x2C39, + linebreak="al", + unicodeslot=0x2C09, + }, + [0x2C0A]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER INITIAL IZHE", + direction="l", + lccode=0x2C3A, + linebreak="al", + unicodeslot=0x2C0A, + }, + [0x2C0B]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER I", + direction="l", + lccode=0x2C3B, + linebreak="al", + unicodeslot=0x2C0B, + }, + [0x2C0C]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER DJERVI", + direction="l", + lccode=0x2C3C, + linebreak="al", + unicodeslot=0x2C0C, + }, + [0x2C0D]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER KAKO", + direction="l", + lccode=0x2C3D, + linebreak="al", + unicodeslot=0x2C0D, + }, + [0x2C0E]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER LJUDIJE", + direction="l", + lccode=0x2C3E, + linebreak="al", + unicodeslot=0x2C0E, + }, + [0x2C0F]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER MYSLITE", + direction="l", + lccode=0x2C3F, + linebreak="al", + unicodeslot=0x2C0F, + }, + [0x2C10]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER NASHI", + direction="l", + lccode=0x2C40, + linebreak="al", + unicodeslot=0x2C10, + }, + [0x2C11]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER ONU", + direction="l", + lccode=0x2C41, + linebreak="al", + unicodeslot=0x2C11, + }, + [0x2C12]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER POKOJI", + direction="l", + lccode=0x2C42, + linebreak="al", + unicodeslot=0x2C12, + }, + [0x2C13]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER RITSI", + direction="l", + lccode=0x2C43, + linebreak="al", + unicodeslot=0x2C13, + }, + [0x2C14]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER SLOVO", + direction="l", + lccode=0x2C44, + linebreak="al", + unicodeslot=0x2C14, + }, + [0x2C15]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER TVRIDO", + direction="l", + lccode=0x2C45, + linebreak="al", + unicodeslot=0x2C15, + }, + [0x2C16]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER UKU", + direction="l", + lccode=0x2C46, + linebreak="al", + unicodeslot=0x2C16, + }, + [0x2C17]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER FRITU", + direction="l", + lccode=0x2C47, + linebreak="al", + unicodeslot=0x2C17, + }, + [0x2C18]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER HERU", + direction="l", + lccode=0x2C48, + linebreak="al", + unicodeslot=0x2C18, + }, + [0x2C19]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER OTU", + direction="l", + lccode=0x2C49, + linebreak="al", + unicodeslot=0x2C19, + }, + [0x2C1A]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER PE", + direction="l", + lccode=0x2C4A, + linebreak="al", + unicodeslot=0x2C1A, + }, + [0x2C1B]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER SHTA", + direction="l", + lccode=0x2C4B, + linebreak="al", + unicodeslot=0x2C1B, + }, + [0x2C1C]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER TSI", + direction="l", + lccode=0x2C4C, + linebreak="al", + unicodeslot=0x2C1C, + }, + [0x2C1D]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER CHRIVI", + direction="l", + lccode=0x2C4D, + linebreak="al", + unicodeslot=0x2C1D, + }, + [0x2C1E]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER SHA", + direction="l", + lccode=0x2C4E, + linebreak="al", + unicodeslot=0x2C1E, + }, + [0x2C1F]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER YERU", + direction="l", + lccode=0x2C4F, + linebreak="al", + unicodeslot=0x2C1F, + }, + [0x2C20]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER YERI", + direction="l", + lccode=0x2C50, + linebreak="al", + unicodeslot=0x2C20, + }, + [0x2C21]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER YATI", + direction="l", + lccode=0x2C51, + linebreak="al", + unicodeslot=0x2C21, + }, + [0x2C22]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER SPIDERY HA", + direction="l", + lccode=0x2C52, + linebreak="al", + unicodeslot=0x2C22, + }, + [0x2C23]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER YU", + direction="l", + lccode=0x2C53, + linebreak="al", + unicodeslot=0x2C23, + }, + [0x2C24]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER SMALL YUS", + direction="l", + lccode=0x2C54, + linebreak="al", + unicodeslot=0x2C24, + }, + [0x2C25]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL", + direction="l", + lccode=0x2C55, + linebreak="al", + unicodeslot=0x2C25, + }, + [0x2C26]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER YO", + direction="l", + lccode=0x2C56, + linebreak="al", + unicodeslot=0x2C26, + }, + [0x2C27]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS", + direction="l", + lccode=0x2C57, + linebreak="al", + unicodeslot=0x2C27, + }, + [0x2C28]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER BIG YUS", + direction="l", + lccode=0x2C58, + linebreak="al", + unicodeslot=0x2C28, + }, + [0x2C29]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS", + direction="l", + lccode=0x2C59, + linebreak="al", + unicodeslot=0x2C29, + }, + [0x2C2A]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER FITA", + direction="l", + lccode=0x2C5A, + linebreak="al", + unicodeslot=0x2C2A, + }, + [0x2C2B]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER IZHITSA", + direction="l", + lccode=0x2C5B, + linebreak="al", + unicodeslot=0x2C2B, + }, + [0x2C2C]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER SHTAPIC", + direction="l", + lccode=0x2C5C, + linebreak="al", + unicodeslot=0x2C2C, + }, + [0x2C2D]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER TROKUTASTI A", + direction="l", + lccode=0x2C5D, + linebreak="al", + unicodeslot=0x2C2D, + }, + [0x2C2E]={ + category="lu", + description="GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE", + direction="l", + lccode=0x2C5E, + linebreak="al", + unicodeslot=0x2C2E, + }, + [0x2C30]={ + category="ll", + description="GLAGOLITIC SMALL LETTER AZU", + direction="l", + linebreak="al", + uccode=0x2C00, + unicodeslot=0x2C30, + }, + [0x2C31]={ + category="ll", + description="GLAGOLITIC SMALL LETTER BUKY", + direction="l", + linebreak="al", + uccode=0x2C01, + unicodeslot=0x2C31, + }, + [0x2C32]={ + category="ll", + description="GLAGOLITIC SMALL LETTER VEDE", + direction="l", + linebreak="al", + uccode=0x2C02, + unicodeslot=0x2C32, + }, + [0x2C33]={ + category="ll", + description="GLAGOLITIC SMALL LETTER GLAGOLI", + direction="l", + linebreak="al", + uccode=0x2C03, + unicodeslot=0x2C33, + }, + [0x2C34]={ + category="ll", + description="GLAGOLITIC SMALL LETTER DOBRO", + direction="l", + linebreak="al", + uccode=0x2C04, + unicodeslot=0x2C34, + }, + [0x2C35]={ + category="ll", + description="GLAGOLITIC SMALL LETTER YESTU", + direction="l", + linebreak="al", + uccode=0x2C05, + unicodeslot=0x2C35, + }, + [0x2C36]={ + category="ll", + description="GLAGOLITIC SMALL LETTER ZHIVETE", + direction="l", + linebreak="al", + uccode=0x2C06, + unicodeslot=0x2C36, + }, + [0x2C37]={ + category="ll", + description="GLAGOLITIC SMALL LETTER DZELO", + direction="l", + linebreak="al", + uccode=0x2C07, + unicodeslot=0x2C37, + }, + [0x2C38]={ + category="ll", + description="GLAGOLITIC SMALL LETTER ZEMLJA", + direction="l", + linebreak="al", + uccode=0x2C08, + unicodeslot=0x2C38, + }, + [0x2C39]={ + category="ll", + description="GLAGOLITIC SMALL LETTER IZHE", + direction="l", + linebreak="al", + uccode=0x2C09, + unicodeslot=0x2C39, + }, + [0x2C3A]={ + category="ll", + description="GLAGOLITIC SMALL LETTER INITIAL IZHE", + direction="l", + linebreak="al", + uccode=0x2C0A, + unicodeslot=0x2C3A, + }, + [0x2C3B]={ + category="ll", + description="GLAGOLITIC SMALL LETTER I", + direction="l", + linebreak="al", + uccode=0x2C0B, + unicodeslot=0x2C3B, + }, + [0x2C3C]={ + category="ll", + description="GLAGOLITIC SMALL LETTER DJERVI", + direction="l", + linebreak="al", + uccode=0x2C0C, + unicodeslot=0x2C3C, + }, + [0x2C3D]={ + category="ll", + description="GLAGOLITIC SMALL LETTER KAKO", + direction="l", + linebreak="al", + uccode=0x2C0D, + unicodeslot=0x2C3D, + }, + [0x2C3E]={ + category="ll", + description="GLAGOLITIC SMALL LETTER LJUDIJE", + direction="l", + linebreak="al", + uccode=0x2C0E, + unicodeslot=0x2C3E, + }, + [0x2C3F]={ + category="ll", + description="GLAGOLITIC SMALL LETTER MYSLITE", + direction="l", + linebreak="al", + uccode=0x2C0F, + unicodeslot=0x2C3F, + }, + [0x2C40]={ + category="ll", + description="GLAGOLITIC SMALL LETTER NASHI", + direction="l", + linebreak="al", + uccode=0x2C10, + unicodeslot=0x2C40, + }, + [0x2C41]={ + category="ll", + description="GLAGOLITIC SMALL LETTER ONU", + direction="l", + linebreak="al", + uccode=0x2C11, + unicodeslot=0x2C41, + }, + [0x2C42]={ + category="ll", + description="GLAGOLITIC SMALL LETTER POKOJI", + direction="l", + linebreak="al", + uccode=0x2C12, + unicodeslot=0x2C42, + }, + [0x2C43]={ + category="ll", + description="GLAGOLITIC SMALL LETTER RITSI", + direction="l", + linebreak="al", + uccode=0x2C13, + unicodeslot=0x2C43, + }, + [0x2C44]={ + category="ll", + description="GLAGOLITIC SMALL LETTER SLOVO", + direction="l", + linebreak="al", + uccode=0x2C14, + unicodeslot=0x2C44, + }, + [0x2C45]={ + category="ll", + description="GLAGOLITIC SMALL LETTER TVRIDO", + direction="l", + linebreak="al", + uccode=0x2C15, + unicodeslot=0x2C45, + }, + [0x2C46]={ + category="ll", + description="GLAGOLITIC SMALL LETTER UKU", + direction="l", + linebreak="al", + uccode=0x2C16, + unicodeslot=0x2C46, + }, + [0x2C47]={ + category="ll", + description="GLAGOLITIC SMALL LETTER FRITU", + direction="l", + linebreak="al", + uccode=0x2C17, + unicodeslot=0x2C47, + }, + [0x2C48]={ + category="ll", + description="GLAGOLITIC SMALL LETTER HERU", + direction="l", + linebreak="al", + uccode=0x2C18, + unicodeslot=0x2C48, + }, + [0x2C49]={ + category="ll", + description="GLAGOLITIC SMALL LETTER OTU", + direction="l", + linebreak="al", + uccode=0x2C19, + unicodeslot=0x2C49, + }, + [0x2C4A]={ + category="ll", + description="GLAGOLITIC SMALL LETTER PE", + direction="l", + linebreak="al", + uccode=0x2C1A, + unicodeslot=0x2C4A, + }, + [0x2C4B]={ + category="ll", + description="GLAGOLITIC SMALL LETTER SHTA", + direction="l", + linebreak="al", + uccode=0x2C1B, + unicodeslot=0x2C4B, + }, + [0x2C4C]={ + category="ll", + description="GLAGOLITIC SMALL LETTER TSI", + direction="l", + linebreak="al", + uccode=0x2C1C, + unicodeslot=0x2C4C, + }, + [0x2C4D]={ + category="ll", + description="GLAGOLITIC SMALL LETTER CHRIVI", + direction="l", + linebreak="al", + uccode=0x2C1D, + unicodeslot=0x2C4D, + }, + [0x2C4E]={ + category="ll", + description="GLAGOLITIC SMALL LETTER SHA", + direction="l", + linebreak="al", + uccode=0x2C1E, + unicodeslot=0x2C4E, + }, + [0x2C4F]={ + category="ll", + description="GLAGOLITIC SMALL LETTER YERU", + direction="l", + linebreak="al", + uccode=0x2C1F, + unicodeslot=0x2C4F, + }, + [0x2C50]={ + category="ll", + description="GLAGOLITIC SMALL LETTER YERI", + direction="l", + linebreak="al", + uccode=0x2C20, + unicodeslot=0x2C50, + }, + [0x2C51]={ + category="ll", + description="GLAGOLITIC SMALL LETTER YATI", + direction="l", + linebreak="al", + uccode=0x2C21, + unicodeslot=0x2C51, + }, + [0x2C52]={ + category="ll", + description="GLAGOLITIC SMALL LETTER SPIDERY HA", + direction="l", + linebreak="al", + uccode=0x2C22, + unicodeslot=0x2C52, + }, + [0x2C53]={ + category="ll", + description="GLAGOLITIC SMALL LETTER YU", + direction="l", + linebreak="al", + uccode=0x2C23, + unicodeslot=0x2C53, + }, + [0x2C54]={ + category="ll", + description="GLAGOLITIC SMALL LETTER SMALL YUS", + direction="l", + linebreak="al", + uccode=0x2C24, + unicodeslot=0x2C54, + }, + [0x2C55]={ + category="ll", + description="GLAGOLITIC SMALL LETTER SMALL YUS WITH TAIL", + direction="l", + linebreak="al", + uccode=0x2C25, + unicodeslot=0x2C55, + }, + [0x2C56]={ + category="ll", + description="GLAGOLITIC SMALL LETTER YO", + direction="l", + linebreak="al", + uccode=0x2C26, + unicodeslot=0x2C56, + }, + [0x2C57]={ + category="ll", + description="GLAGOLITIC SMALL LETTER IOTATED SMALL YUS", + direction="l", + linebreak="al", + uccode=0x2C27, + unicodeslot=0x2C57, + }, + [0x2C58]={ + category="ll", + description="GLAGOLITIC SMALL LETTER BIG YUS", + direction="l", + linebreak="al", + uccode=0x2C28, + unicodeslot=0x2C58, + }, + [0x2C59]={ + category="ll", + description="GLAGOLITIC SMALL LETTER IOTATED BIG YUS", + direction="l", + linebreak="al", + uccode=0x2C29, + unicodeslot=0x2C59, + }, + [0x2C5A]={ + category="ll", + description="GLAGOLITIC SMALL LETTER FITA", + direction="l", + linebreak="al", + uccode=0x2C2A, + unicodeslot=0x2C5A, + }, + [0x2C5B]={ + category="ll", + description="GLAGOLITIC SMALL LETTER IZHITSA", + direction="l", + linebreak="al", + uccode=0x2C2B, + unicodeslot=0x2C5B, + }, + [0x2C5C]={ + category="ll", + description="GLAGOLITIC SMALL LETTER SHTAPIC", + direction="l", + linebreak="al", + uccode=0x2C2C, + unicodeslot=0x2C5C, + }, + [0x2C5D]={ + category="ll", + description="GLAGOLITIC SMALL LETTER TROKUTASTI A", + direction="l", + linebreak="al", + uccode=0x2C2D, + unicodeslot=0x2C5D, + }, + [0x2C5E]={ + category="ll", + description="GLAGOLITIC SMALL LETTER LATINATE MYSLITE", + direction="l", + linebreak="al", + uccode=0x2C2E, + unicodeslot=0x2C5E, + }, + [0x2C60]={ + category="lu", + description="LATIN CAPITAL LETTER L WITH DOUBLE BAR", + direction="l", + lccode=0x2C61, + linebreak="al", + shcode=0x004C, + unicodeslot=0x2C60, + }, + [0x2C61]={ + category="ll", + description="LATIN SMALL LETTER L WITH DOUBLE BAR", + direction="l", + linebreak="al", + shcode=0x006C, + uccode=0x2C60, + unicodeslot=0x2C61, + }, + [0x2C62]={ + category="lu", + description="LATIN CAPITAL LETTER L WITH MIDDLE TILDE", + direction="l", + lccode=0x026B, + linebreak="al", + shcode=0x004C, + unicodeslot=0x2C62, + }, + [0x2C63]={ + category="lu", + description="LATIN CAPITAL LETTER P WITH STROKE", + direction="l", + lccode=0x1D7D, + linebreak="al", + shcode=0x0050, + unicodeslot=0x2C63, + }, + [0x2C64]={ + category="lu", + description="LATIN CAPITAL LETTER R WITH TAIL", + direction="l", + lccode=0x027D, + linebreak="al", + shcode=0x0052, + unicodeslot=0x2C64, + }, + [0x2C65]={ + category="ll", + description="LATIN SMALL LETTER A WITH STROKE", + direction="l", + linebreak="al", + shcode=0x0061, + uccode=0x023A, + unicodeslot=0x2C65, + }, + [0x2C66]={ + category="ll", + description="LATIN SMALL LETTER T WITH DIAGONAL STROKE", + direction="l", + linebreak="al", + shcode=0x0074, + uccode=0x023E, + unicodeslot=0x2C66, + }, + [0x2C67]={ + category="lu", + description="LATIN CAPITAL LETTER H WITH DESCENDER", + direction="l", + lccode=0x2C68, + linebreak="al", + shcode=0x0048, + unicodeslot=0x2C67, + }, + [0x2C68]={ + category="ll", + description="LATIN SMALL LETTER H WITH DESCENDER", + direction="l", + linebreak="al", + shcode=0x0068, + uccode=0x2C67, + unicodeslot=0x2C68, + }, + [0x2C69]={ + category="lu", + description="LATIN CAPITAL LETTER K WITH DESCENDER", + direction="l", + lccode=0x2C6A, + linebreak="al", + shcode=0x004B, + unicodeslot=0x2C69, + }, + [0x2C6A]={ + category="ll", + description="LATIN SMALL LETTER K WITH DESCENDER", + direction="l", + linebreak="al", + shcode=0x006B, + uccode=0x2C69, + unicodeslot=0x2C6A, + }, + [0x2C6B]={ + category="lu", + description="LATIN CAPITAL LETTER Z WITH DESCENDER", + direction="l", + lccode=0x2C6C, + linebreak="al", + shcode=0x005A, + unicodeslot=0x2C6B, + }, + [0x2C6C]={ + category="ll", + description="LATIN SMALL LETTER Z WITH DESCENDER", + direction="l", + linebreak="al", + shcode=0x007A, + uccode=0x2C6B, + unicodeslot=0x2C6C, + }, + [0x2C74]={ + category="ll", + description="LATIN SMALL LETTER V WITH CURL", + direction="l", + linebreak="al", + shcode=0x0076, + unicodeslot=0x2C74, + }, + [0x2C75]={ + category="lu", + description="LATIN CAPITAL LETTER HALF H", + direction="l", + lccode=0x2C76, + linebreak="al", + unicodeslot=0x2C75, + }, + [0x2C76]={ + category="ll", + description="LATIN SMALL LETTER HALF H", + direction="l", + linebreak="al", + uccode=0x2C75, + unicodeslot=0x2C76, + }, + [0x2C77]={ + category="ll", + description="LATIN SMALL LETTER TAILLESS PHI", + direction="l", + linebreak="al", + unicodeslot=0x2C77, + }, + [0x2C80]={ + category="lu", + description="COPTIC CAPITAL LETTER ALFA", + direction="l", + lccode=0x2C81, + linebreak="al", + unicodeslot=0x2C80, + }, + [0x2C81]={ + category="ll", + description="COPTIC SMALL LETTER ALFA", + direction="l", + linebreak="al", + uccode=0x2C80, + unicodeslot=0x2C81, + }, + [0x2C82]={ + category="lu", + description="COPTIC CAPITAL LETTER VIDA", + direction="l", + lccode=0x2C83, + linebreak="al", + unicodeslot=0x2C82, + }, + [0x2C83]={ + category="ll", + description="COPTIC SMALL LETTER VIDA", + direction="l", + linebreak="al", + uccode=0x2C82, + unicodeslot=0x2C83, + }, + [0x2C84]={ + category="lu", + description="COPTIC CAPITAL LETTER GAMMA", + direction="l", + lccode=0x2C85, + linebreak="al", + unicodeslot=0x2C84, + }, + [0x2C85]={ + category="ll", + description="COPTIC SMALL LETTER GAMMA", + direction="l", + linebreak="al", + uccode=0x2C84, + unicodeslot=0x2C85, + }, + [0x2C86]={ + category="lu", + description="COPTIC CAPITAL LETTER DALDA", + direction="l", + lccode=0x2C87, + linebreak="al", + unicodeslot=0x2C86, + }, + [0x2C87]={ + category="ll", + description="COPTIC SMALL LETTER DALDA", + direction="l", + linebreak="al", + uccode=0x2C86, + unicodeslot=0x2C87, + }, + [0x2C88]={ + category="lu", + description="COPTIC CAPITAL LETTER EIE", + direction="l", + lccode=0x2C89, + linebreak="al", + unicodeslot=0x2C88, + }, + [0x2C89]={ + category="ll", + description="COPTIC SMALL LETTER EIE", + direction="l", + linebreak="al", + uccode=0x2C88, + unicodeslot=0x2C89, + }, + [0x2C8A]={ + category="lu", + description="COPTIC CAPITAL LETTER SOU", + direction="l", + lccode=0x2C8B, + linebreak="al", + unicodeslot=0x2C8A, + }, + [0x2C8B]={ + category="ll", + description="COPTIC SMALL LETTER SOU", + direction="l", + linebreak="al", + uccode=0x2C8A, + unicodeslot=0x2C8B, + }, + [0x2C8C]={ + category="lu", + description="COPTIC CAPITAL LETTER ZATA", + direction="l", + lccode=0x2C8D, + linebreak="al", + unicodeslot=0x2C8C, + }, + [0x2C8D]={ + category="ll", + description="COPTIC SMALL LETTER ZATA", + direction="l", + linebreak="al", + uccode=0x2C8C, + unicodeslot=0x2C8D, + }, + [0x2C8E]={ + category="lu", + description="COPTIC CAPITAL LETTER HATE", + direction="l", + lccode=0x2C8F, + linebreak="al", + unicodeslot=0x2C8E, + }, + [0x2C8F]={ + category="ll", + description="COPTIC SMALL LETTER HATE", + direction="l", + linebreak="al", + uccode=0x2C8E, + unicodeslot=0x2C8F, + }, + [0x2C90]={ + category="lu", + description="COPTIC CAPITAL LETTER THETHE", + direction="l", + lccode=0x2C91, + linebreak="al", + unicodeslot=0x2C90, + }, + [0x2C91]={ + category="ll", + description="COPTIC SMALL LETTER THETHE", + direction="l", + linebreak="al", + uccode=0x2C90, + unicodeslot=0x2C91, + }, + [0x2C92]={ + category="lu", + description="COPTIC CAPITAL LETTER IAUDA", + direction="l", + lccode=0x2C93, + linebreak="al", + unicodeslot=0x2C92, + }, + [0x2C93]={ + category="ll", + description="COPTIC SMALL LETTER IAUDA", + direction="l", + linebreak="al", + uccode=0x2C92, + unicodeslot=0x2C93, + }, + [0x2C94]={ + category="lu", + description="COPTIC CAPITAL LETTER KAPA", + direction="l", + lccode=0x2C95, + linebreak="al", + unicodeslot=0x2C94, + }, + [0x2C95]={ + category="ll", + description="COPTIC SMALL LETTER KAPA", + direction="l", + linebreak="al", + uccode=0x2C94, + unicodeslot=0x2C95, + }, + [0x2C96]={ + category="lu", + description="COPTIC CAPITAL LETTER LAULA", + direction="l", + lccode=0x2C97, + linebreak="al", + unicodeslot=0x2C96, + }, + [0x2C97]={ + category="ll", + description="COPTIC SMALL LETTER LAULA", + direction="l", + linebreak="al", + uccode=0x2C96, + unicodeslot=0x2C97, + }, + [0x2C98]={ + category="lu", + description="COPTIC CAPITAL LETTER MI", + direction="l", + lccode=0x2C99, + linebreak="al", + unicodeslot=0x2C98, + }, + [0x2C99]={ + category="ll", + description="COPTIC SMALL LETTER MI", + direction="l", + linebreak="al", + uccode=0x2C98, + unicodeslot=0x2C99, + }, + [0x2C9A]={ + category="lu", + description="COPTIC CAPITAL LETTER NI", + direction="l", + lccode=0x2C9B, + linebreak="al", + unicodeslot=0x2C9A, + }, + [0x2C9B]={ + category="ll", + description="COPTIC SMALL LETTER NI", + direction="l", + linebreak="al", + uccode=0x2C9A, + unicodeslot=0x2C9B, + }, + [0x2C9C]={ + category="lu", + description="COPTIC CAPITAL LETTER KSI", + direction="l", + lccode=0x2C9D, + linebreak="al", + unicodeslot=0x2C9C, + }, + [0x2C9D]={ + category="ll", + description="COPTIC SMALL LETTER KSI", + direction="l", + linebreak="al", + uccode=0x2C9C, + unicodeslot=0x2C9D, + }, + [0x2C9E]={ + category="lu", + description="COPTIC CAPITAL LETTER O", + direction="l", + lccode=0x2C9F, + linebreak="al", + unicodeslot=0x2C9E, + }, + [0x2C9F]={ + category="ll", + description="COPTIC SMALL LETTER O", + direction="l", + linebreak="al", + uccode=0x2C9E, + unicodeslot=0x2C9F, + }, + [0x2CA0]={ + category="lu", + description="COPTIC CAPITAL LETTER PI", + direction="l", + lccode=0x2CA1, + linebreak="al", + unicodeslot=0x2CA0, + }, + [0x2CA1]={ + category="ll", + description="COPTIC SMALL LETTER PI", + direction="l", + linebreak="al", + uccode=0x2CA0, + unicodeslot=0x2CA1, + }, + [0x2CA2]={ + category="lu", + description="COPTIC CAPITAL LETTER RO", + direction="l", + lccode=0x2CA3, + linebreak="al", + unicodeslot=0x2CA2, + }, + [0x2CA3]={ + category="ll", + description="COPTIC SMALL LETTER RO", + direction="l", + linebreak="al", + uccode=0x2CA2, + unicodeslot=0x2CA3, + }, + [0x2CA4]={ + category="lu", + description="COPTIC CAPITAL LETTER SIMA", + direction="l", + lccode=0x2CA5, + linebreak="al", + unicodeslot=0x2CA4, + }, + [0x2CA5]={ + category="ll", + description="COPTIC SMALL LETTER SIMA", + direction="l", + linebreak="al", + uccode=0x2CA4, + unicodeslot=0x2CA5, + }, + [0x2CA6]={ + category="lu", + description="COPTIC CAPITAL LETTER TAU", + direction="l", + lccode=0x2CA7, + linebreak="al", + unicodeslot=0x2CA6, + }, + [0x2CA7]={ + category="ll", + description="COPTIC SMALL LETTER TAU", + direction="l", + linebreak="al", + uccode=0x2CA6, + unicodeslot=0x2CA7, + }, + [0x2CA8]={ + category="lu", + description="COPTIC CAPITAL LETTER UA", + direction="l", + lccode=0x2CA9, + linebreak="al", + unicodeslot=0x2CA8, + }, + [0x2CA9]={ + category="ll", + description="COPTIC SMALL LETTER UA", + direction="l", + linebreak="al", + uccode=0x2CA8, + unicodeslot=0x2CA9, + }, + [0x2CAA]={ + category="lu", + description="COPTIC CAPITAL LETTER FI", + direction="l", + lccode=0x2CAB, + linebreak="al", + unicodeslot=0x2CAA, + }, + [0x2CAB]={ + category="ll", + description="COPTIC SMALL LETTER FI", + direction="l", + linebreak="al", + uccode=0x2CAA, + unicodeslot=0x2CAB, + }, + [0x2CAC]={ + category="lu", + description="COPTIC CAPITAL LETTER KHI", + direction="l", + lccode=0x2CAD, + linebreak="al", + unicodeslot=0x2CAC, + }, + [0x2CAD]={ + category="ll", + description="COPTIC SMALL LETTER KHI", + direction="l", + linebreak="al", + uccode=0x2CAC, + unicodeslot=0x2CAD, + }, + [0x2CAE]={ + category="lu", + description="COPTIC CAPITAL LETTER PSI", + direction="l", + lccode=0x2CAF, + linebreak="al", + unicodeslot=0x2CAE, + }, + [0x2CAF]={ + category="ll", + description="COPTIC SMALL LETTER PSI", + direction="l", + linebreak="al", + uccode=0x2CAE, + unicodeslot=0x2CAF, + }, + [0x2CB0]={ + category="lu", + description="COPTIC CAPITAL LETTER OOU", + direction="l", + lccode=0x2CB1, + linebreak="al", + unicodeslot=0x2CB0, + }, + [0x2CB1]={ + category="ll", + description="COPTIC SMALL LETTER OOU", + direction="l", + linebreak="al", + uccode=0x2CB0, + unicodeslot=0x2CB1, + }, + [0x2CB2]={ + category="lu", + description="COPTIC CAPITAL LETTER DIALECT-P ALEF", + direction="l", + lccode=0x2CB3, + linebreak="al", + unicodeslot=0x2CB2, + }, + [0x2CB3]={ + category="ll", + description="COPTIC SMALL LETTER DIALECT-P ALEF", + direction="l", + linebreak="al", + uccode=0x2CB2, + unicodeslot=0x2CB3, + }, + [0x2CB4]={ + category="lu", + description="COPTIC CAPITAL LETTER OLD COPTIC AIN", + direction="l", + lccode=0x2CB5, + linebreak="al", + unicodeslot=0x2CB4, + }, + [0x2CB5]={ + category="ll", + description="COPTIC SMALL LETTER OLD COPTIC AIN", + direction="l", + linebreak="al", + uccode=0x2CB4, + unicodeslot=0x2CB5, + }, + [0x2CB6]={ + category="lu", + description="COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE", + direction="l", + lccode=0x2CB7, + linebreak="al", + unicodeslot=0x2CB6, + }, + [0x2CB7]={ + category="ll", + description="COPTIC SMALL LETTER CRYPTOGRAMMIC EIE", + direction="l", + linebreak="al", + uccode=0x2CB6, + unicodeslot=0x2CB7, + }, + [0x2CB8]={ + category="lu", + description="COPTIC CAPITAL LETTER DIALECT-P KAPA", + direction="l", + lccode=0x2CB9, + linebreak="al", + unicodeslot=0x2CB8, + }, + [0x2CB9]={ + category="ll", + description="COPTIC SMALL LETTER DIALECT-P KAPA", + direction="l", + linebreak="al", + uccode=0x2CB8, + unicodeslot=0x2CB9, + }, + [0x2CBA]={ + category="lu", + description="COPTIC CAPITAL LETTER DIALECT-P NI", + direction="l", + lccode=0x2CBB, + linebreak="al", + unicodeslot=0x2CBA, + }, + [0x2CBB]={ + category="ll", + description="COPTIC SMALL LETTER DIALECT-P NI", + direction="l", + linebreak="al", + uccode=0x2CBA, + unicodeslot=0x2CBB, + }, + [0x2CBC]={ + category="lu", + description="COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI", + direction="l", + lccode=0x2CBD, + linebreak="al", + unicodeslot=0x2CBC, + }, + [0x2CBD]={ + category="ll", + description="COPTIC SMALL LETTER CRYPTOGRAMMIC NI", + direction="l", + linebreak="al", + uccode=0x2CBC, + unicodeslot=0x2CBD, + }, + [0x2CBE]={ + category="lu", + description="COPTIC CAPITAL LETTER OLD COPTIC OOU", + direction="l", + lccode=0x2CBF, + linebreak="al", + unicodeslot=0x2CBE, + }, + [0x2CBF]={ + category="ll", + description="COPTIC SMALL LETTER OLD COPTIC OOU", + direction="l", + linebreak="al", + uccode=0x2CBE, + unicodeslot=0x2CBF, + }, + [0x2CC0]={ + category="lu", + description="COPTIC CAPITAL LETTER SAMPI", + direction="l", + lccode=0x2CC1, + linebreak="al", + unicodeslot=0x2CC0, + }, + [0x2CC1]={ + category="ll", + description="COPTIC SMALL LETTER SAMPI", + direction="l", + linebreak="al", + uccode=0x2CC0, + unicodeslot=0x2CC1, + }, + [0x2CC2]={ + category="lu", + description="COPTIC CAPITAL LETTER CROSSED SHEI", + direction="l", + lccode=0x2CC3, + linebreak="al", + unicodeslot=0x2CC2, + }, + [0x2CC3]={ + category="ll", + description="COPTIC SMALL LETTER CROSSED SHEI", + direction="l", + linebreak="al", + uccode=0x2CC2, + unicodeslot=0x2CC3, + }, + [0x2CC4]={ + category="lu", + description="COPTIC CAPITAL LETTER OLD COPTIC SHEI", + direction="l", + lccode=0x2CC5, + linebreak="al", + unicodeslot=0x2CC4, + }, + [0x2CC5]={ + category="ll", + description="COPTIC SMALL LETTER OLD COPTIC SHEI", + direction="l", + linebreak="al", + uccode=0x2CC4, + unicodeslot=0x2CC5, + }, + [0x2CC6]={ + category="lu", + description="COPTIC CAPITAL LETTER OLD COPTIC ESH", + direction="l", + lccode=0x2CC7, + linebreak="al", + unicodeslot=0x2CC6, + }, + [0x2CC7]={ + category="ll", + description="COPTIC SMALL LETTER OLD COPTIC ESH", + direction="l", + linebreak="al", + uccode=0x2CC6, + unicodeslot=0x2CC7, + }, + [0x2CC8]={ + category="lu", + description="COPTIC CAPITAL LETTER AKHMIMIC KHEI", + direction="l", + lccode=0x2CC9, + linebreak="al", + unicodeslot=0x2CC8, + }, + [0x2CC9]={ + category="ll", + description="COPTIC SMALL LETTER AKHMIMIC KHEI", + direction="l", + linebreak="al", + uccode=0x2CC8, + unicodeslot=0x2CC9, + }, + [0x2CCA]={ + category="lu", + description="COPTIC CAPITAL LETTER DIALECT-P HORI", + direction="l", + lccode=0x2CCB, + linebreak="al", + unicodeslot=0x2CCA, + }, + [0x2CCB]={ + category="ll", + description="COPTIC SMALL LETTER DIALECT-P HORI", + direction="l", + linebreak="al", + uccode=0x2CCA, + unicodeslot=0x2CCB, + }, + [0x2CCC]={ + category="lu", + description="COPTIC CAPITAL LETTER OLD COPTIC HORI", + direction="l", + lccode=0x2CCD, + linebreak="al", + unicodeslot=0x2CCC, + }, + [0x2CCD]={ + category="ll", + description="COPTIC SMALL LETTER OLD COPTIC HORI", + direction="l", + linebreak="al", + uccode=0x2CCC, + unicodeslot=0x2CCD, + }, + [0x2CCE]={ + category="lu", + description="COPTIC CAPITAL LETTER OLD COPTIC HA", + direction="l", + lccode=0x2CCF, + linebreak="al", + unicodeslot=0x2CCE, + }, + [0x2CCF]={ + category="ll", + description="COPTIC SMALL LETTER OLD COPTIC HA", + direction="l", + linebreak="al", + uccode=0x2CCE, + unicodeslot=0x2CCF, + }, + [0x2CD0]={ + category="lu", + description="COPTIC CAPITAL LETTER L-SHAPED HA", + direction="l", + lccode=0x2CD1, + linebreak="al", + unicodeslot=0x2CD0, + }, + [0x2CD1]={ + category="ll", + description="COPTIC SMALL LETTER L-SHAPED HA", + direction="l", + linebreak="al", + uccode=0x2CD0, + unicodeslot=0x2CD1, + }, + [0x2CD2]={ + category="lu", + description="COPTIC CAPITAL LETTER OLD COPTIC HEI", + direction="l", + lccode=0x2CD3, + linebreak="al", + unicodeslot=0x2CD2, + }, + [0x2CD3]={ + category="ll", + description="COPTIC SMALL LETTER OLD COPTIC HEI", + direction="l", + linebreak="al", + uccode=0x2CD2, + unicodeslot=0x2CD3, + }, + [0x2CD4]={ + category="lu", + description="COPTIC CAPITAL LETTER OLD COPTIC HAT", + direction="l", + lccode=0x2CD5, + linebreak="al", + unicodeslot=0x2CD4, + }, + [0x2CD5]={ + category="ll", + description="COPTIC SMALL LETTER OLD COPTIC HAT", + direction="l", + linebreak="al", + uccode=0x2CD4, + unicodeslot=0x2CD5, + }, + [0x2CD6]={ + category="lu", + description="COPTIC CAPITAL LETTER OLD COPTIC GANGIA", + direction="l", + lccode=0x2CD7, + linebreak="al", + unicodeslot=0x2CD6, + }, + [0x2CD7]={ + category="ll", + description="COPTIC SMALL LETTER OLD COPTIC GANGIA", + direction="l", + linebreak="al", + uccode=0x2CD6, + unicodeslot=0x2CD7, + }, + [0x2CD8]={ + category="lu", + description="COPTIC CAPITAL LETTER OLD COPTIC DJA", + direction="l", + lccode=0x2CD9, + linebreak="al", + unicodeslot=0x2CD8, + }, + [0x2CD9]={ + category="ll", + description="COPTIC SMALL LETTER OLD COPTIC DJA", + direction="l", + linebreak="al", + uccode=0x2CD8, + unicodeslot=0x2CD9, + }, + [0x2CDA]={ + category="lu", + description="COPTIC CAPITAL LETTER OLD COPTIC SHIMA", + direction="l", + lccode=0x2CDB, + linebreak="al", + unicodeslot=0x2CDA, + }, + [0x2CDB]={ + category="ll", + description="COPTIC SMALL LETTER OLD COPTIC SHIMA", + direction="l", + linebreak="al", + uccode=0x2CDA, + unicodeslot=0x2CDB, + }, + [0x2CDC]={ + category="lu", + description="COPTIC CAPITAL LETTER OLD NUBIAN SHIMA", + direction="l", + lccode=0x2CDD, + linebreak="al", + unicodeslot=0x2CDC, + }, + [0x2CDD]={ + category="ll", + description="COPTIC SMALL LETTER OLD NUBIAN SHIMA", + direction="l", + linebreak="al", + uccode=0x2CDC, + unicodeslot=0x2CDD, + }, + [0x2CDE]={ + category="lu", + description="COPTIC CAPITAL LETTER OLD NUBIAN NGI", + direction="l", + lccode=0x2CDF, + linebreak="al", + unicodeslot=0x2CDE, + }, + [0x2CDF]={ + category="ll", + description="COPTIC SMALL LETTER OLD NUBIAN NGI", + direction="l", + linebreak="al", + uccode=0x2CDE, + unicodeslot=0x2CDF, + }, + [0x2CE0]={ + category="lu", + description="COPTIC CAPITAL LETTER OLD NUBIAN NYI", + direction="l", + lccode=0x2CE1, + linebreak="al", + unicodeslot=0x2CE0, + }, + [0x2CE1]={ + category="ll", + description="COPTIC SMALL LETTER OLD NUBIAN NYI", + direction="l", + linebreak="al", + uccode=0x2CE0, + unicodeslot=0x2CE1, + }, + [0x2CE2]={ + category="lu", + description="COPTIC CAPITAL LETTER OLD NUBIAN WAU", + direction="l", + lccode=0x2CE3, + linebreak="al", + unicodeslot=0x2CE2, + }, + [0x2CE3]={ + category="ll", + description="COPTIC SMALL LETTER OLD NUBIAN WAU", + direction="l", + linebreak="al", + uccode=0x2CE2, + unicodeslot=0x2CE3, + }, + [0x2CE4]={ + category="ll", + description="COPTIC SYMBOL KAI", + direction="l", + linebreak="al", + unicodeslot=0x2CE4, + }, + [0x2CE5]={ + category="so", + description="COPTIC SYMBOL MI RO", + direction="on", + linebreak="al", + unicodeslot=0x2CE5, + }, + [0x2CE6]={ + category="so", + description="COPTIC SYMBOL PI RO", + direction="on", + linebreak="al", + unicodeslot=0x2CE6, + }, + [0x2CE7]={ + category="so", + description="COPTIC SYMBOL STAUROS", + direction="on", + linebreak="al", + unicodeslot=0x2CE7, + }, + [0x2CE8]={ + category="so", + description="COPTIC SYMBOL TAU RO", + direction="on", + linebreak="al", + unicodeslot=0x2CE8, + }, + [0x2CE9]={ + category="so", + description="COPTIC SYMBOL KHI RO", + direction="on", + linebreak="al", + unicodeslot=0x2CE9, + }, + [0x2CEA]={ + category="so", + description="COPTIC SYMBOL SHIMA SIMA", + direction="on", + linebreak="al", + unicodeslot=0x2CEA, + }, + [0x2CF9]={ + category="po", + description="COPTIC OLD NUBIAN FULL STOP", + direction="on", + linebreak="ba", + unicodeslot=0x2CF9, + }, + [0x2CFA]={ + category="po", + description="COPTIC OLD NUBIAN DIRECT QUESTION MARK", + direction="on", + linebreak="ba", + unicodeslot=0x2CFA, + }, + [0x2CFB]={ + category="po", + description="COPTIC OLD NUBIAN INDIRECT QUESTION MARK", + direction="on", + linebreak="ba", + unicodeslot=0x2CFB, + }, + [0x2CFC]={ + category="po", + description="COPTIC OLD NUBIAN VERSE DIVIDER", + direction="on", + linebreak="ba", + unicodeslot=0x2CFC, + }, + [0x2CFD]={ + category="no", + description="COPTIC FRACTION ONE HALF", + direction="on", + linebreak="al", + unicodeslot=0x2CFD, + }, + [0x2CFE]={ + category="po", + description="COPTIC FULL STOP", + direction="on", + linebreak="ba", + unicodeslot=0x2CFE, + }, + [0x2CFF]={ + category="po", + description="COPTIC MORPHOLOGICAL DIVIDER", + direction="on", + linebreak="ba", + unicodeslot=0x2CFF, + }, + [0x2D00]={ + category="ll", + description="GEORGIAN SMALL LETTER AN", + direction="l", + linebreak="al", + uccode=0x10A0, + unicodeslot=0x2D00, + }, + [0x2D01]={ + category="ll", + description="GEORGIAN SMALL LETTER BAN", + direction="l", + linebreak="al", + uccode=0x10A1, + unicodeslot=0x2D01, + }, + [0x2D02]={ + category="ll", + description="GEORGIAN SMALL LETTER GAN", + direction="l", + linebreak="al", + uccode=0x10A2, + unicodeslot=0x2D02, + }, + [0x2D03]={ + category="ll", + description="GEORGIAN SMALL LETTER DON", + direction="l", + linebreak="al", + uccode=0x10A3, + unicodeslot=0x2D03, + }, + [0x2D04]={ + category="ll", + description="GEORGIAN SMALL LETTER EN", + direction="l", + linebreak="al", + uccode=0x10A4, + unicodeslot=0x2D04, + }, + [0x2D05]={ + category="ll", + description="GEORGIAN SMALL LETTER VIN", + direction="l", + linebreak="al", + uccode=0x10A5, + unicodeslot=0x2D05, + }, + [0x2D06]={ + category="ll", + description="GEORGIAN SMALL LETTER ZEN", + direction="l", + linebreak="al", + uccode=0x10A6, + unicodeslot=0x2D06, + }, + [0x2D07]={ + category="ll", + description="GEORGIAN SMALL LETTER TAN", + direction="l", + linebreak="al", + uccode=0x10A7, + unicodeslot=0x2D07, + }, + [0x2D08]={ + category="ll", + description="GEORGIAN SMALL LETTER IN", + direction="l", + linebreak="al", + uccode=0x10A8, + unicodeslot=0x2D08, + }, + [0x2D09]={ + category="ll", + description="GEORGIAN SMALL LETTER KAN", + direction="l", + linebreak="al", + uccode=0x10A9, + unicodeslot=0x2D09, + }, + [0x2D0A]={ + category="ll", + description="GEORGIAN SMALL LETTER LAS", + direction="l", + linebreak="al", + uccode=0x10AA, + unicodeslot=0x2D0A, + }, + [0x2D0B]={ + category="ll", + description="GEORGIAN SMALL LETTER MAN", + direction="l", + linebreak="al", + uccode=0x10AB, + unicodeslot=0x2D0B, + }, + [0x2D0C]={ + category="ll", + description="GEORGIAN SMALL LETTER NAR", + direction="l", + linebreak="al", + uccode=0x10AC, + unicodeslot=0x2D0C, + }, + [0x2D0D]={ + category="ll", + description="GEORGIAN SMALL LETTER ON", + direction="l", + linebreak="al", + uccode=0x10AD, + unicodeslot=0x2D0D, + }, + [0x2D0E]={ + category="ll", + description="GEORGIAN SMALL LETTER PAR", + direction="l", + linebreak="al", + uccode=0x10AE, + unicodeslot=0x2D0E, + }, + [0x2D0F]={ + category="ll", + description="GEORGIAN SMALL LETTER ZHAR", + direction="l", + linebreak="al", + uccode=0x10AF, + unicodeslot=0x2D0F, + }, + [0x2D10]={ + category="ll", + description="GEORGIAN SMALL LETTER RAE", + direction="l", + linebreak="al", + uccode=0x10B0, + unicodeslot=0x2D10, + }, + [0x2D11]={ + category="ll", + description="GEORGIAN SMALL LETTER SAN", + direction="l", + linebreak="al", + uccode=0x10B1, + unicodeslot=0x2D11, + }, + [0x2D12]={ + category="ll", + description="GEORGIAN SMALL LETTER TAR", + direction="l", + linebreak="al", + uccode=0x10B2, + unicodeslot=0x2D12, + }, + [0x2D13]={ + category="ll", + description="GEORGIAN SMALL LETTER UN", + direction="l", + linebreak="al", + uccode=0x10B3, + unicodeslot=0x2D13, + }, + [0x2D14]={ + category="ll", + description="GEORGIAN SMALL LETTER PHAR", + direction="l", + linebreak="al", + uccode=0x10B4, + unicodeslot=0x2D14, + }, + [0x2D15]={ + category="ll", + description="GEORGIAN SMALL LETTER KHAR", + direction="l", + linebreak="al", + uccode=0x10B5, + unicodeslot=0x2D15, + }, + [0x2D16]={ + category="ll", + description="GEORGIAN SMALL LETTER GHAN", + direction="l", + linebreak="al", + uccode=0x10B6, + unicodeslot=0x2D16, + }, + [0x2D17]={ + category="ll", + description="GEORGIAN SMALL LETTER QAR", + direction="l", + linebreak="al", + uccode=0x10B7, + unicodeslot=0x2D17, + }, + [0x2D18]={ + category="ll", + description="GEORGIAN SMALL LETTER SHIN", + direction="l", + linebreak="al", + uccode=0x10B8, + unicodeslot=0x2D18, + }, + [0x2D19]={ + category="ll", + description="GEORGIAN SMALL LETTER CHIN", + direction="l", + linebreak="al", + uccode=0x10B9, + unicodeslot=0x2D19, + }, + [0x2D1A]={ + category="ll", + description="GEORGIAN SMALL LETTER CAN", + direction="l", + linebreak="al", + uccode=0x10BA, + unicodeslot=0x2D1A, + }, + [0x2D1B]={ + category="ll", + description="GEORGIAN SMALL LETTER JIL", + direction="l", + linebreak="al", + uccode=0x10BB, + unicodeslot=0x2D1B, + }, + [0x2D1C]={ + category="ll", + description="GEORGIAN SMALL LETTER CIL", + direction="l", + linebreak="al", + uccode=0x10BC, + unicodeslot=0x2D1C, + }, + [0x2D1D]={ + category="ll", + description="GEORGIAN SMALL LETTER CHAR", + direction="l", + linebreak="al", + uccode=0x10BD, + unicodeslot=0x2D1D, + }, + [0x2D1E]={ + category="ll", + description="GEORGIAN SMALL LETTER XAN", + direction="l", + linebreak="al", + uccode=0x10BE, + unicodeslot=0x2D1E, + }, + [0x2D1F]={ + category="ll", + description="GEORGIAN SMALL LETTER JHAN", + direction="l", + linebreak="al", + uccode=0x10BF, + unicodeslot=0x2D1F, + }, + [0x2D20]={ + category="ll", + description="GEORGIAN SMALL LETTER HAE", + direction="l", + linebreak="al", + uccode=0x10C0, + unicodeslot=0x2D20, + }, + [0x2D21]={ + category="ll", + description="GEORGIAN SMALL LETTER HE", + direction="l", + linebreak="al", + uccode=0x10C1, + unicodeslot=0x2D21, + }, + [0x2D22]={ + category="ll", + description="GEORGIAN SMALL LETTER HIE", + direction="l", + linebreak="al", + uccode=0x10C2, + unicodeslot=0x2D22, + }, + [0x2D23]={ + category="ll", + description="GEORGIAN SMALL LETTER WE", + direction="l", + linebreak="al", + uccode=0x10C3, + unicodeslot=0x2D23, + }, + [0x2D24]={ + category="ll", + description="GEORGIAN SMALL LETTER HAR", + direction="l", + linebreak="al", + uccode=0x10C4, + unicodeslot=0x2D24, + }, + [0x2D25]={ + category="ll", + description="GEORGIAN SMALL LETTER HOE", + direction="l", + linebreak="al", + uccode=0x10C5, + unicodeslot=0x2D25, + }, + [0x2D30]={ + category="lo", + description="TIFINAGH LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x2D30, + }, + [0x2D31]={ + category="lo", + description="TIFINAGH LETTER YAB", + direction="l", + linebreak="al", + unicodeslot=0x2D31, + }, + [0x2D32]={ + category="lo", + description="TIFINAGH LETTER YABH", + direction="l", + linebreak="al", + unicodeslot=0x2D32, + }, + [0x2D33]={ + category="lo", + description="TIFINAGH LETTER YAG", + direction="l", + linebreak="al", + unicodeslot=0x2D33, + }, + [0x2D34]={ + category="lo", + description="TIFINAGH LETTER YAGHH", + direction="l", + linebreak="al", + unicodeslot=0x2D34, + }, + [0x2D35]={ + category="lo", + description="TIFINAGH LETTER BERBER ACADEMY YAJ", + direction="l", + linebreak="al", + unicodeslot=0x2D35, + }, + [0x2D36]={ + category="lo", + description="TIFINAGH LETTER YAJ", + direction="l", + linebreak="al", + unicodeslot=0x2D36, + }, + [0x2D37]={ + category="lo", + description="TIFINAGH LETTER YAD", + direction="l", + linebreak="al", + unicodeslot=0x2D37, + }, + [0x2D38]={ + category="lo", + description="TIFINAGH LETTER YADH", + direction="l", + linebreak="al", + unicodeslot=0x2D38, + }, + [0x2D39]={ + category="lo", + description="TIFINAGH LETTER YADD", + direction="l", + linebreak="al", + unicodeslot=0x2D39, + }, + [0x2D3A]={ + category="lo", + description="TIFINAGH LETTER YADDH", + direction="l", + linebreak="al", + unicodeslot=0x2D3A, + }, + [0x2D3B]={ + category="lo", + description="TIFINAGH LETTER YEY", + direction="l", + linebreak="al", + unicodeslot=0x2D3B, + }, + [0x2D3C]={ + category="lo", + description="TIFINAGH LETTER YAF", + direction="l", + linebreak="al", + unicodeslot=0x2D3C, + }, + [0x2D3D]={ + category="lo", + description="TIFINAGH LETTER YAK", + direction="l", + linebreak="al", + unicodeslot=0x2D3D, + }, + [0x2D3E]={ + category="lo", + description="TIFINAGH LETTER TUAREG YAK", + direction="l", + linebreak="al", + unicodeslot=0x2D3E, + }, + [0x2D3F]={ + category="lo", + description="TIFINAGH LETTER YAKHH", + direction="l", + linebreak="al", + unicodeslot=0x2D3F, + }, + [0x2D40]={ + category="lo", + description="TIFINAGH LETTER YAH", + direction="l", + linebreak="al", + unicodeslot=0x2D40, + }, + [0x2D41]={ + category="lo", + description="TIFINAGH LETTER BERBER ACADEMY YAH", + direction="l", + linebreak="al", + unicodeslot=0x2D41, + }, + [0x2D42]={ + category="lo", + description="TIFINAGH LETTER TUAREG YAH", + direction="l", + linebreak="al", + unicodeslot=0x2D42, + }, + [0x2D43]={ + category="lo", + description="TIFINAGH LETTER YAHH", + direction="l", + linebreak="al", + unicodeslot=0x2D43, + }, + [0x2D44]={ + category="lo", + description="TIFINAGH LETTER YAA", + direction="l", + linebreak="al", + unicodeslot=0x2D44, + }, + [0x2D45]={ + category="lo", + description="TIFINAGH LETTER YAKH", + direction="l", + linebreak="al", + unicodeslot=0x2D45, + }, + [0x2D46]={ + category="lo", + description="TIFINAGH LETTER TUAREG YAKH", + direction="l", + linebreak="al", + unicodeslot=0x2D46, + }, + [0x2D47]={ + category="lo", + description="TIFINAGH LETTER YAQ", + direction="l", + linebreak="al", + unicodeslot=0x2D47, + }, + [0x2D48]={ + category="lo", + description="TIFINAGH LETTER TUAREG YAQ", + direction="l", + linebreak="al", + unicodeslot=0x2D48, + }, + [0x2D49]={ + category="lo", + description="TIFINAGH LETTER YI", + direction="l", + linebreak="al", + unicodeslot=0x2D49, + }, + [0x2D4A]={ + category="lo", + description="TIFINAGH LETTER YAZH", + direction="l", + linebreak="al", + unicodeslot=0x2D4A, + }, + [0x2D4B]={ + category="lo", + description="TIFINAGH LETTER AHAGGAR YAZH", + direction="l", + linebreak="al", + unicodeslot=0x2D4B, + }, + [0x2D4C]={ + category="lo", + description="TIFINAGH LETTER TUAREG YAZH", + direction="l", + linebreak="al", + unicodeslot=0x2D4C, + }, + [0x2D4D]={ + category="lo", + description="TIFINAGH LETTER YAL", + direction="l", + linebreak="al", + unicodeslot=0x2D4D, + }, + [0x2D4E]={ + category="lo", + description="TIFINAGH LETTER YAM", + direction="l", + linebreak="al", + unicodeslot=0x2D4E, + }, + [0x2D4F]={ + category="lo", + description="TIFINAGH LETTER YAN", + direction="l", + linebreak="al", + unicodeslot=0x2D4F, + }, + [0x2D50]={ + category="lo", + description="TIFINAGH LETTER TUAREG YAGN", + direction="l", + linebreak="al", + unicodeslot=0x2D50, + }, + [0x2D51]={ + category="lo", + description="TIFINAGH LETTER TUAREG YANG", + direction="l", + linebreak="al", + unicodeslot=0x2D51, + }, + [0x2D52]={ + category="lo", + description="TIFINAGH LETTER YAP", + direction="l", + linebreak="al", + unicodeslot=0x2D52, + }, + [0x2D53]={ + category="lo", + description="TIFINAGH LETTER YU", + direction="l", + linebreak="al", + unicodeslot=0x2D53, + }, + [0x2D54]={ + category="lo", + description="TIFINAGH LETTER YAR", + direction="l", + linebreak="al", + unicodeslot=0x2D54, + }, + [0x2D55]={ + category="lo", + description="TIFINAGH LETTER YARR", + direction="l", + linebreak="al", + unicodeslot=0x2D55, + }, + [0x2D56]={ + category="lo", + description="TIFINAGH LETTER YAGH", + direction="l", + linebreak="al", + unicodeslot=0x2D56, + }, + [0x2D57]={ + category="lo", + description="TIFINAGH LETTER TUAREG YAGH", + direction="l", + linebreak="al", + unicodeslot=0x2D57, + }, + [0x2D58]={ + category="lo", + description="TIFINAGH LETTER AYER YAGH", + direction="l", + linebreak="al", + unicodeslot=0x2D58, + }, + [0x2D59]={ + category="lo", + description="TIFINAGH LETTER YAS", + direction="l", + linebreak="al", + unicodeslot=0x2D59, + }, + [0x2D5A]={ + category="lo", + description="TIFINAGH LETTER YASS", + direction="l", + linebreak="al", + unicodeslot=0x2D5A, + }, + [0x2D5B]={ + category="lo", + description="TIFINAGH LETTER YASH", + direction="l", + linebreak="al", + unicodeslot=0x2D5B, + }, + [0x2D5C]={ + category="lo", + description="TIFINAGH LETTER YAT", + direction="l", + linebreak="al", + unicodeslot=0x2D5C, + }, + [0x2D5D]={ + category="lo", + description="TIFINAGH LETTER YATH", + direction="l", + linebreak="al", + unicodeslot=0x2D5D, + }, + [0x2D5E]={ + category="lo", + description="TIFINAGH LETTER YACH", + direction="l", + linebreak="al", + unicodeslot=0x2D5E, + }, + [0x2D5F]={ + category="lo", + description="TIFINAGH LETTER YATT", + direction="l", + linebreak="al", + unicodeslot=0x2D5F, + }, + [0x2D60]={ + category="lo", + description="TIFINAGH LETTER YAV", + direction="l", + linebreak="al", + unicodeslot=0x2D60, + }, + [0x2D61]={ + category="lo", + description="TIFINAGH LETTER YAW", + direction="l", + linebreak="al", + unicodeslot=0x2D61, + }, + [0x2D62]={ + category="lo", + description="TIFINAGH LETTER YAY", + direction="l", + linebreak="al", + unicodeslot=0x2D62, + }, + [0x2D63]={ + category="lo", + description="TIFINAGH LETTER YAZ", + direction="l", + linebreak="al", + unicodeslot=0x2D63, + }, + [0x2D64]={ + category="lo", + description="TIFINAGH LETTER TAWELLEMET YAZ", + direction="l", + linebreak="al", + unicodeslot=0x2D64, + }, + [0x2D65]={ + category="lo", + description="TIFINAGH LETTER YAZZ", + direction="l", + linebreak="al", + unicodeslot=0x2D65, + }, + [0x2D6F]={ + category="lm", + description="TIFINAGH MODIFIER LETTER LABIALIZATION MARK", + direction="l", + linebreak="al", + specials={ "super", 0x2D61 }, + unicodeslot=0x2D6F, + }, + [0x2D80]={ + category="lo", + description="ETHIOPIC SYLLABLE LOA", + direction="l", + linebreak="al", + unicodeslot=0x2D80, + }, + [0x2D81]={ + category="lo", + description="ETHIOPIC SYLLABLE MOA", + direction="l", + linebreak="al", + unicodeslot=0x2D81, + }, + [0x2D82]={ + category="lo", + description="ETHIOPIC SYLLABLE ROA", + direction="l", + linebreak="al", + unicodeslot=0x2D82, + }, + [0x2D83]={ + category="lo", + description="ETHIOPIC SYLLABLE SOA", + direction="l", + linebreak="al", + unicodeslot=0x2D83, + }, + [0x2D84]={ + category="lo", + description="ETHIOPIC SYLLABLE SHOA", + direction="l", + linebreak="al", + unicodeslot=0x2D84, + }, + [0x2D85]={ + category="lo", + description="ETHIOPIC SYLLABLE BOA", + direction="l", + linebreak="al", + unicodeslot=0x2D85, + }, + [0x2D86]={ + category="lo", + description="ETHIOPIC SYLLABLE TOA", + direction="l", + linebreak="al", + unicodeslot=0x2D86, + }, + [0x2D87]={ + category="lo", + description="ETHIOPIC SYLLABLE COA", + direction="l", + linebreak="al", + unicodeslot=0x2D87, + }, + [0x2D88]={ + category="lo", + description="ETHIOPIC SYLLABLE NOA", + direction="l", + linebreak="al", + unicodeslot=0x2D88, + }, + [0x2D89]={ + category="lo", + description="ETHIOPIC SYLLABLE NYOA", + direction="l", + linebreak="al", + unicodeslot=0x2D89, + }, + [0x2D8A]={ + category="lo", + description="ETHIOPIC SYLLABLE GLOTTAL OA", + direction="l", + linebreak="al", + unicodeslot=0x2D8A, + }, + [0x2D8B]={ + category="lo", + description="ETHIOPIC SYLLABLE ZOA", + direction="l", + linebreak="al", + unicodeslot=0x2D8B, + }, + [0x2D8C]={ + category="lo", + description="ETHIOPIC SYLLABLE DOA", + direction="l", + linebreak="al", + unicodeslot=0x2D8C, + }, + [0x2D8D]={ + category="lo", + description="ETHIOPIC SYLLABLE DDOA", + direction="l", + linebreak="al", + unicodeslot=0x2D8D, + }, + [0x2D8E]={ + category="lo", + description="ETHIOPIC SYLLABLE JOA", + direction="l", + linebreak="al", + unicodeslot=0x2D8E, + }, + [0x2D8F]={ + category="lo", + description="ETHIOPIC SYLLABLE THOA", + direction="l", + linebreak="al", + unicodeslot=0x2D8F, + }, + [0x2D90]={ + category="lo", + description="ETHIOPIC SYLLABLE CHOA", + direction="l", + linebreak="al", + unicodeslot=0x2D90, + }, + [0x2D91]={ + category="lo", + description="ETHIOPIC SYLLABLE PHOA", + direction="l", + linebreak="al", + unicodeslot=0x2D91, + }, + [0x2D92]={ + category="lo", + description="ETHIOPIC SYLLABLE POA", + direction="l", + linebreak="al", + unicodeslot=0x2D92, + }, + [0x2D93]={ + category="lo", + description="ETHIOPIC SYLLABLE GGWA", + direction="l", + linebreak="al", + unicodeslot=0x2D93, + }, + [0x2D94]={ + category="lo", + description="ETHIOPIC SYLLABLE GGWI", + direction="l", + linebreak="al", + unicodeslot=0x2D94, + }, + [0x2D95]={ + category="lo", + description="ETHIOPIC SYLLABLE GGWEE", + direction="l", + linebreak="al", + unicodeslot=0x2D95, + }, + [0x2D96]={ + category="lo", + description="ETHIOPIC SYLLABLE GGWE", + direction="l", + linebreak="al", + unicodeslot=0x2D96, + }, + [0x2DA0]={ + category="lo", + description="ETHIOPIC SYLLABLE SSA", + direction="l", + linebreak="al", + unicodeslot=0x2DA0, + }, + [0x2DA1]={ + category="lo", + description="ETHIOPIC SYLLABLE SSU", + direction="l", + linebreak="al", + unicodeslot=0x2DA1, + }, + [0x2DA2]={ + category="lo", + description="ETHIOPIC SYLLABLE SSI", + direction="l", + linebreak="al", + unicodeslot=0x2DA2, + }, + [0x2DA3]={ + category="lo", + description="ETHIOPIC SYLLABLE SSAA", + direction="l", + linebreak="al", + unicodeslot=0x2DA3, + }, + [0x2DA4]={ + category="lo", + description="ETHIOPIC SYLLABLE SSEE", + direction="l", + linebreak="al", + unicodeslot=0x2DA4, + }, + [0x2DA5]={ + category="lo", + description="ETHIOPIC SYLLABLE SSE", + direction="l", + linebreak="al", + unicodeslot=0x2DA5, + }, + [0x2DA6]={ + category="lo", + description="ETHIOPIC SYLLABLE SSO", + direction="l", + linebreak="al", + unicodeslot=0x2DA6, + }, + [0x2DA8]={ + category="lo", + description="ETHIOPIC SYLLABLE CCA", + direction="l", + linebreak="al", + unicodeslot=0x2DA8, + }, + [0x2DA9]={ + category="lo", + description="ETHIOPIC SYLLABLE CCU", + direction="l", + linebreak="al", + unicodeslot=0x2DA9, + }, + [0x2DAA]={ + category="lo", + description="ETHIOPIC SYLLABLE CCI", + direction="l", + linebreak="al", + unicodeslot=0x2DAA, + }, + [0x2DAB]={ + category="lo", + description="ETHIOPIC SYLLABLE CCAA", + direction="l", + linebreak="al", + unicodeslot=0x2DAB, + }, + [0x2DAC]={ + category="lo", + description="ETHIOPIC SYLLABLE CCEE", + direction="l", + linebreak="al", + unicodeslot=0x2DAC, + }, + [0x2DAD]={ + category="lo", + description="ETHIOPIC SYLLABLE CCE", + direction="l", + linebreak="al", + unicodeslot=0x2DAD, + }, + [0x2DAE]={ + category="lo", + description="ETHIOPIC SYLLABLE CCO", + direction="l", + linebreak="al", + unicodeslot=0x2DAE, + }, + [0x2DB0]={ + category="lo", + description="ETHIOPIC SYLLABLE ZZA", + direction="l", + linebreak="al", + unicodeslot=0x2DB0, + }, + [0x2DB1]={ + category="lo", + description="ETHIOPIC SYLLABLE ZZU", + direction="l", + linebreak="al", + unicodeslot=0x2DB1, + }, + [0x2DB2]={ + category="lo", + description="ETHIOPIC SYLLABLE ZZI", + direction="l", + linebreak="al", + unicodeslot=0x2DB2, + }, + [0x2DB3]={ + category="lo", + description="ETHIOPIC SYLLABLE ZZAA", + direction="l", + linebreak="al", + unicodeslot=0x2DB3, + }, + [0x2DB4]={ + category="lo", + description="ETHIOPIC SYLLABLE ZZEE", + direction="l", + linebreak="al", + unicodeslot=0x2DB4, + }, + [0x2DB5]={ + category="lo", + description="ETHIOPIC SYLLABLE ZZE", + direction="l", + linebreak="al", + unicodeslot=0x2DB5, + }, + [0x2DB6]={ + category="lo", + description="ETHIOPIC SYLLABLE ZZO", + direction="l", + linebreak="al", + unicodeslot=0x2DB6, + }, + [0x2DB8]={ + category="lo", + description="ETHIOPIC SYLLABLE CCHA", + direction="l", + linebreak="al", + unicodeslot=0x2DB8, + }, + [0x2DB9]={ + category="lo", + description="ETHIOPIC SYLLABLE CCHU", + direction="l", + linebreak="al", + unicodeslot=0x2DB9, + }, + [0x2DBA]={ + category="lo", + description="ETHIOPIC SYLLABLE CCHI", + direction="l", + linebreak="al", + unicodeslot=0x2DBA, + }, + [0x2DBB]={ + category="lo", + description="ETHIOPIC SYLLABLE CCHAA", + direction="l", + linebreak="al", + unicodeslot=0x2DBB, + }, + [0x2DBC]={ + category="lo", + description="ETHIOPIC SYLLABLE CCHEE", + direction="l", + linebreak="al", + unicodeslot=0x2DBC, + }, + [0x2DBD]={ + category="lo", + description="ETHIOPIC SYLLABLE CCHE", + direction="l", + linebreak="al", + unicodeslot=0x2DBD, + }, + [0x2DBE]={ + category="lo", + description="ETHIOPIC SYLLABLE CCHO", + direction="l", + linebreak="al", + unicodeslot=0x2DBE, + }, + [0x2DC0]={ + category="lo", + description="ETHIOPIC SYLLABLE QYA", + direction="l", + linebreak="al", + unicodeslot=0x2DC0, + }, + [0x2DC1]={ + category="lo", + description="ETHIOPIC SYLLABLE QYU", + direction="l", + linebreak="al", + unicodeslot=0x2DC1, + }, + [0x2DC2]={ + category="lo", + description="ETHIOPIC SYLLABLE QYI", + direction="l", + linebreak="al", + unicodeslot=0x2DC2, + }, + [0x2DC3]={ + category="lo", + description="ETHIOPIC SYLLABLE QYAA", + direction="l", + linebreak="al", + unicodeslot=0x2DC3, + }, + [0x2DC4]={ + category="lo", + description="ETHIOPIC SYLLABLE QYEE", + direction="l", + linebreak="al", + unicodeslot=0x2DC4, + }, + [0x2DC5]={ + category="lo", + description="ETHIOPIC SYLLABLE QYE", + direction="l", + linebreak="al", + unicodeslot=0x2DC5, + }, + [0x2DC6]={ + category="lo", + description="ETHIOPIC SYLLABLE QYO", + direction="l", + linebreak="al", + unicodeslot=0x2DC6, + }, + [0x2DC8]={ + category="lo", + description="ETHIOPIC SYLLABLE KYA", + direction="l", + linebreak="al", + unicodeslot=0x2DC8, + }, + [0x2DC9]={ + category="lo", + description="ETHIOPIC SYLLABLE KYU", + direction="l", + linebreak="al", + unicodeslot=0x2DC9, + }, + [0x2DCA]={ + category="lo", + description="ETHIOPIC SYLLABLE KYI", + direction="l", + linebreak="al", + unicodeslot=0x2DCA, + }, + [0x2DCB]={ + category="lo", + description="ETHIOPIC SYLLABLE KYAA", + direction="l", + linebreak="al", + unicodeslot=0x2DCB, + }, + [0x2DCC]={ + category="lo", + description="ETHIOPIC SYLLABLE KYEE", + direction="l", + linebreak="al", + unicodeslot=0x2DCC, + }, + [0x2DCD]={ + category="lo", + description="ETHIOPIC SYLLABLE KYE", + direction="l", + linebreak="al", + unicodeslot=0x2DCD, + }, + [0x2DCE]={ + category="lo", + description="ETHIOPIC SYLLABLE KYO", + direction="l", + linebreak="al", + unicodeslot=0x2DCE, + }, + [0x2DD0]={ + category="lo", + description="ETHIOPIC SYLLABLE XYA", + direction="l", + linebreak="al", + unicodeslot=0x2DD0, + }, + [0x2DD1]={ + category="lo", + description="ETHIOPIC SYLLABLE XYU", + direction="l", + linebreak="al", + unicodeslot=0x2DD1, + }, + [0x2DD2]={ + category="lo", + description="ETHIOPIC SYLLABLE XYI", + direction="l", + linebreak="al", + unicodeslot=0x2DD2, + }, + [0x2DD3]={ + category="lo", + description="ETHIOPIC SYLLABLE XYAA", + direction="l", + linebreak="al", + unicodeslot=0x2DD3, + }, + [0x2DD4]={ + category="lo", + description="ETHIOPIC SYLLABLE XYEE", + direction="l", + linebreak="al", + unicodeslot=0x2DD4, + }, + [0x2DD5]={ + category="lo", + description="ETHIOPIC SYLLABLE XYE", + direction="l", + linebreak="al", + unicodeslot=0x2DD5, + }, + [0x2DD6]={ + category="lo", + description="ETHIOPIC SYLLABLE XYO", + direction="l", + linebreak="al", + unicodeslot=0x2DD6, + }, + [0x2DD8]={ + category="lo", + description="ETHIOPIC SYLLABLE GYA", + direction="l", + linebreak="al", + unicodeslot=0x2DD8, + }, + [0x2DD9]={ + category="lo", + description="ETHIOPIC SYLLABLE GYU", + direction="l", + linebreak="al", + unicodeslot=0x2DD9, + }, + [0x2DDA]={ + category="lo", + description="ETHIOPIC SYLLABLE GYI", + direction="l", + linebreak="al", + unicodeslot=0x2DDA, + }, + [0x2DDB]={ + category="lo", + description="ETHIOPIC SYLLABLE GYAA", + direction="l", + linebreak="al", + unicodeslot=0x2DDB, + }, + [0x2DDC]={ + category="lo", + description="ETHIOPIC SYLLABLE GYEE", + direction="l", + linebreak="al", + unicodeslot=0x2DDC, + }, + [0x2DDD]={ + category="lo", + description="ETHIOPIC SYLLABLE GYE", + direction="l", + linebreak="al", + unicodeslot=0x2DDD, + }, + [0x2DDE]={ + category="lo", + description="ETHIOPIC SYLLABLE GYO", + direction="l", + linebreak="al", + unicodeslot=0x2DDE, + }, + [0x2E00]={ + category="po", + description="RIGHT ANGLE SUBSTITUTION MARKER", + direction="on", + linebreak="qu", + unicodeslot=0x2E00, + }, + [0x2E01]={ + category="po", + description="RIGHT ANGLE DOTTED SUBSTITUTION MARKER", + direction="on", + linebreak="qu", + unicodeslot=0x2E01, + }, + [0x2E02]={ + category="pi", + description="LEFT SUBSTITUTION BRACKET", + direction="on", + linebreak="qu", + mirror=0x2E03, + unicodeslot=0x2E02, + }, + [0x2E03]={ + category="pf", + description="RIGHT SUBSTITUTION BRACKET", + direction="on", + linebreak="qu", + mirror=0x2E02, + unicodeslot=0x2E03, + }, + [0x2E04]={ + category="pi", + description="LEFT DOTTED SUBSTITUTION BRACKET", + direction="on", + linebreak="qu", + mirror=0x2E05, + unicodeslot=0x2E04, + }, + [0x2E05]={ + category="pf", + description="RIGHT DOTTED SUBSTITUTION BRACKET", + direction="on", + linebreak="qu", + mirror=0x2E04, + unicodeslot=0x2E05, + }, + [0x2E06]={ + category="po", + description="RAISED INTERPOLATION MARKER", + direction="on", + linebreak="qu", + unicodeslot=0x2E06, + }, + [0x2E07]={ + category="po", + description="RAISED DOTTED INTERPOLATION MARKER", + direction="on", + linebreak="qu", + unicodeslot=0x2E07, + }, + [0x2E08]={ + category="po", + description="DOTTED TRANSPOSITION MARKER", + direction="on", + linebreak="qu", + unicodeslot=0x2E08, + }, + [0x2E09]={ + category="pi", + description="LEFT TRANSPOSITION BRACKET", + direction="on", + linebreak="qu", + mirror=0x2E0A, + unicodeslot=0x2E09, + }, + [0x2E0A]={ + category="pf", + description="RIGHT TRANSPOSITION BRACKET", + direction="on", + linebreak="qu", + mirror=0x2E09, + unicodeslot=0x2E0A, + }, + [0x2E0B]={ + category="po", + description="RAISED SQUARE", + direction="on", + linebreak="qu", + unicodeslot=0x2E0B, + }, + [0x2E0C]={ + category="pi", + description="LEFT RAISED OMISSION BRACKET", + direction="on", + linebreak="qu", + mirror=0x2E0D, + unicodeslot=0x2E0C, + }, + [0x2E0D]={ + category="pf", + description="RIGHT RAISED OMISSION BRACKET", + direction="on", + linebreak="qu", + mirror=0x2E0C, + unicodeslot=0x2E0D, + }, + [0x2E0E]={ + category="po", + description="EDITORIAL CORONIS", + direction="on", + linebreak="ba", + unicodeslot=0x2E0E, + }, + [0x2E0F]={ + category="po", + description="PARAGRAPHOS", + direction="on", + linebreak="ba", + unicodeslot=0x2E0F, + }, + [0x2E10]={ + category="po", + description="FORKED PARAGRAPHOS", + direction="on", + linebreak="ba", + unicodeslot=0x2E10, + }, + [0x2E11]={ + category="po", + description="REVERSED FORKED PARAGRAPHOS", + direction="on", + linebreak="ba", + unicodeslot=0x2E11, + }, + [0x2E12]={ + category="po", + description="HYPODIASTOLE", + direction="on", + linebreak="ba", + unicodeslot=0x2E12, + }, + [0x2E13]={ + category="po", + description="DOTTED OBELOS", + direction="on", + linebreak="ba", + unicodeslot=0x2E13, + }, + [0x2E14]={ + category="po", + description="DOWNWARDS ANCORA", + direction="on", + linebreak="ba", + unicodeslot=0x2E14, + }, + [0x2E15]={ + category="po", + description="UPWARDS ANCORA", + direction="on", + linebreak="ba", + unicodeslot=0x2E15, + }, + [0x2E16]={ + category="po", + description="DOTTED RIGHT-POINTING ANGLE", + direction="on", + linebreak="al", + unicodeslot=0x2E16, + }, + [0x2E17]={ + category="pd", + description="DOUBLE OBLIQUE HYPHEN", + direction="on", + linebreak="ba", + unicodeslot=0x2E17, + }, + [0x2E1C]={ + category="pi", + description="LEFT LOW PARAPHRASE BRACKET", + direction="on", + linebreak="qu", + mirror=0x2E1D, + unicodeslot=0x2E1C, + }, + [0x2E1D]={ + category="pf", + description="RIGHT LOW PARAPHRASE BRACKET", + direction="on", + linebreak="qu", + mirror=0x2E1C, + unicodeslot=0x2E1D, + }, + [0x2E80]={ + category="so", + cjkwd="w", + description="CJK RADICAL REPEAT", + direction="on", + linebreak="id", + unicodeslot=0x2E80, + }, + [0x2E81]={ + category="so", + cjkwd="w", + description="CJK RADICAL CLIFF", + direction="on", + linebreak="id", + unicodeslot=0x2E81, + }, + [0x2E82]={ + category="so", + cjkwd="w", + description="CJK RADICAL SECOND ONE", + direction="on", + linebreak="id", + unicodeslot=0x2E82, + }, + [0x2E83]={ + category="so", + cjkwd="w", + description="CJK RADICAL SECOND TWO", + direction="on", + linebreak="id", + unicodeslot=0x2E83, + }, + [0x2E84]={ + category="so", + cjkwd="w", + description="CJK RADICAL SECOND THREE", + direction="on", + linebreak="id", + unicodeslot=0x2E84, + }, + [0x2E85]={ + category="so", + cjkwd="w", + description="CJK RADICAL PERSON", + direction="on", + linebreak="id", + unicodeslot=0x2E85, + }, + [0x2E86]={ + category="so", + cjkwd="w", + description="CJK RADICAL BOX", + direction="on", + linebreak="id", + unicodeslot=0x2E86, + }, + [0x2E87]={ + category="so", + cjkwd="w", + description="CJK RADICAL TABLE", + direction="on", + linebreak="id", + unicodeslot=0x2E87, + }, + [0x2E88]={ + category="so", + cjkwd="w", + description="CJK RADICAL KNIFE ONE", + direction="on", + linebreak="id", + unicodeslot=0x2E88, + }, + [0x2E89]={ + category="so", + cjkwd="w", + description="CJK RADICAL KNIFE TWO", + direction="on", + linebreak="id", + unicodeslot=0x2E89, + }, + [0x2E8A]={ + category="so", + cjkwd="w", + description="CJK RADICAL DIVINATION", + direction="on", + linebreak="id", + unicodeslot=0x2E8A, + }, + [0x2E8B]={ + category="so", + cjkwd="w", + description="CJK RADICAL SEAL", + direction="on", + linebreak="id", + unicodeslot=0x2E8B, + }, + [0x2E8C]={ + category="so", + cjkwd="w", + description="CJK RADICAL SMALL ONE", + direction="on", + linebreak="id", + unicodeslot=0x2E8C, + }, + [0x2E8D]={ + category="so", + cjkwd="w", + description="CJK RADICAL SMALL TWO", + direction="on", + linebreak="id", + unicodeslot=0x2E8D, + }, + [0x2E8E]={ + category="so", + cjkwd="w", + description="CJK RADICAL LAME ONE", + direction="on", + linebreak="id", + unicodeslot=0x2E8E, + }, + [0x2E8F]={ + category="so", + cjkwd="w", + description="CJK RADICAL LAME TWO", + direction="on", + linebreak="id", + unicodeslot=0x2E8F, + }, + [0x2E90]={ + category="so", + cjkwd="w", + description="CJK RADICAL LAME THREE", + direction="on", + linebreak="id", + unicodeslot=0x2E90, + }, + [0x2E91]={ + category="so", + cjkwd="w", + description="CJK RADICAL LAME FOUR", + direction="on", + linebreak="id", + unicodeslot=0x2E91, + }, + [0x2E92]={ + category="so", + cjkwd="w", + description="CJK RADICAL SNAKE", + direction="on", + linebreak="id", + unicodeslot=0x2E92, + }, + [0x2E93]={ + category="so", + cjkwd="w", + description="CJK RADICAL THREAD", + direction="on", + linebreak="id", + unicodeslot=0x2E93, + }, + [0x2E94]={ + category="so", + cjkwd="w", + description="CJK RADICAL SNOUT ONE", + direction="on", + linebreak="id", + unicodeslot=0x2E94, + }, + [0x2E95]={ + category="so", + cjkwd="w", + description="CJK RADICAL SNOUT TWO", + direction="on", + linebreak="id", + unicodeslot=0x2E95, + }, + [0x2E96]={ + category="so", + cjkwd="w", + description="CJK RADICAL HEART ONE", + direction="on", + linebreak="id", + unicodeslot=0x2E96, + }, + [0x2E97]={ + category="so", + cjkwd="w", + description="CJK RADICAL HEART TWO", + direction="on", + linebreak="id", + unicodeslot=0x2E97, + }, + [0x2E98]={ + category="so", + cjkwd="w", + description="CJK RADICAL HAND", + direction="on", + linebreak="id", + unicodeslot=0x2E98, + }, + [0x2E99]={ + category="so", + cjkwd="w", + description="CJK RADICAL RAP", + direction="on", + linebreak="id", + unicodeslot=0x2E99, + }, + [0x2E9B]={ + category="so", + cjkwd="w", + description="CJK RADICAL CHOKE", + direction="on", + linebreak="id", + unicodeslot=0x2E9B, + }, + [0x2E9C]={ + category="so", + cjkwd="w", + description="CJK RADICAL SUN", + direction="on", + linebreak="id", + unicodeslot=0x2E9C, + }, + [0x2E9D]={ + category="so", + cjkwd="w", + description="CJK RADICAL MOON", + direction="on", + linebreak="id", + unicodeslot=0x2E9D, + }, + [0x2E9E]={ + category="so", + cjkwd="w", + description="CJK RADICAL DEATH", + direction="on", + linebreak="id", + unicodeslot=0x2E9E, + }, + [0x2E9F]={ + category="so", + cjkwd="w", + description="CJK RADICAL MOTHER", + direction="on", + linebreak="id", + specials={ "compat", 0x6BCD }, + unicodeslot=0x2E9F, + }, + [0x2EA0]={ + category="so", + cjkwd="w", + description="CJK RADICAL CIVILIAN", + direction="on", + linebreak="id", + unicodeslot=0x2EA0, + }, + [0x2EA1]={ + category="so", + cjkwd="w", + description="CJK RADICAL WATER ONE", + direction="on", + linebreak="id", + unicodeslot=0x2EA1, + }, + [0x2EA2]={ + category="so", + cjkwd="w", + description="CJK RADICAL WATER TWO", + direction="on", + linebreak="id", + unicodeslot=0x2EA2, + }, + [0x2EA3]={ + category="so", + cjkwd="w", + description="CJK RADICAL FIRE", + direction="on", + linebreak="id", + unicodeslot=0x2EA3, + }, + [0x2EA4]={ + category="so", + cjkwd="w", + description="CJK RADICAL PAW ONE", + direction="on", + linebreak="id", + unicodeslot=0x2EA4, + }, + [0x2EA5]={ + category="so", + cjkwd="w", + description="CJK RADICAL PAW TWO", + direction="on", + linebreak="id", + unicodeslot=0x2EA5, + }, + [0x2EA6]={ + category="so", + cjkwd="w", + description="CJK RADICAL SIMPLIFIED HALF TREE TRUNK", + direction="on", + linebreak="id", + unicodeslot=0x2EA6, + }, + [0x2EA7]={ + category="so", + cjkwd="w", + description="CJK RADICAL COW", + direction="on", + linebreak="id", + unicodeslot=0x2EA7, + }, + [0x2EA8]={ + category="so", + cjkwd="w", + description="CJK RADICAL DOG", + direction="on", + linebreak="id", + unicodeslot=0x2EA8, + }, + [0x2EA9]={ + category="so", + cjkwd="w", + description="CJK RADICAL JADE", + direction="on", + linebreak="id", + unicodeslot=0x2EA9, + }, + [0x2EAA]={ + category="so", + cjkwd="w", + description="CJK RADICAL BOLT OF CLOTH", + direction="on", + linebreak="id", + unicodeslot=0x2EAA, + }, + [0x2EAB]={ + category="so", + cjkwd="w", + description="CJK RADICAL EYE", + direction="on", + linebreak="id", + unicodeslot=0x2EAB, + }, + [0x2EAC]={ + category="so", + cjkwd="w", + description="CJK RADICAL SPIRIT ONE", + direction="on", + linebreak="id", + unicodeslot=0x2EAC, + }, + [0x2EAD]={ + category="so", + cjkwd="w", + description="CJK RADICAL SPIRIT TWO", + direction="on", + linebreak="id", + unicodeslot=0x2EAD, + }, + [0x2EAE]={ + category="so", + cjkwd="w", + description="CJK RADICAL BAMBOO", + direction="on", + linebreak="id", + unicodeslot=0x2EAE, + }, + [0x2EAF]={ + category="so", + cjkwd="w", + description="CJK RADICAL SILK", + direction="on", + linebreak="id", + unicodeslot=0x2EAF, + }, + [0x2EB0]={ + category="so", + cjkwd="w", + description="CJK RADICAL C-SIMPLIFIED SILK", + direction="on", + linebreak="id", + unicodeslot=0x2EB0, + }, + [0x2EB1]={ + category="so", + cjkwd="w", + description="CJK RADICAL NET ONE", + direction="on", + linebreak="id", + unicodeslot=0x2EB1, + }, + [0x2EB2]={ + category="so", + cjkwd="w", + description="CJK RADICAL NET TWO", + direction="on", + linebreak="id", + unicodeslot=0x2EB2, + }, + [0x2EB3]={ + category="so", + cjkwd="w", + description="CJK RADICAL NET THREE", + direction="on", + linebreak="id", + unicodeslot=0x2EB3, + }, + [0x2EB4]={ + category="so", + cjkwd="w", + description="CJK RADICAL NET FOUR", + direction="on", + linebreak="id", + unicodeslot=0x2EB4, + }, + [0x2EB5]={ + category="so", + cjkwd="w", + description="CJK RADICAL MESH", + direction="on", + linebreak="id", + unicodeslot=0x2EB5, + }, + [0x2EB6]={ + category="so", + cjkwd="w", + description="CJK RADICAL SHEEP", + direction="on", + linebreak="id", + unicodeslot=0x2EB6, + }, + [0x2EB7]={ + category="so", + cjkwd="w", + description="CJK RADICAL RAM", + direction="on", + linebreak="id", + unicodeslot=0x2EB7, + }, + [0x2EB8]={ + category="so", + cjkwd="w", + description="CJK RADICAL EWE", + direction="on", + linebreak="id", + unicodeslot=0x2EB8, + }, + [0x2EB9]={ + category="so", + cjkwd="w", + description="CJK RADICAL OLD", + direction="on", + linebreak="id", + unicodeslot=0x2EB9, + }, + [0x2EBA]={ + category="so", + cjkwd="w", + description="CJK RADICAL BRUSH ONE", + direction="on", + linebreak="id", + unicodeslot=0x2EBA, + }, + [0x2EBB]={ + category="so", + cjkwd="w", + description="CJK RADICAL BRUSH TWO", + direction="on", + linebreak="id", + unicodeslot=0x2EBB, + }, + [0x2EBC]={ + category="so", + cjkwd="w", + description="CJK RADICAL MEAT", + direction="on", + linebreak="id", + unicodeslot=0x2EBC, + }, + [0x2EBD]={ + category="so", + cjkwd="w", + description="CJK RADICAL MORTAR", + direction="on", + linebreak="id", + unicodeslot=0x2EBD, + }, + [0x2EBE]={ + category="so", + cjkwd="w", + description="CJK RADICAL GRASS ONE", + direction="on", + linebreak="id", + unicodeslot=0x2EBE, + }, + [0x2EBF]={ + category="so", + cjkwd="w", + description="CJK RADICAL GRASS TWO", + direction="on", + linebreak="id", + unicodeslot=0x2EBF, + }, + [0x2EC0]={ + category="so", + cjkwd="w", + description="CJK RADICAL GRASS THREE", + direction="on", + linebreak="id", + unicodeslot=0x2EC0, + }, + [0x2EC1]={ + category="so", + cjkwd="w", + description="CJK RADICAL TIGER", + direction="on", + linebreak="id", + unicodeslot=0x2EC1, + }, + [0x2EC2]={ + category="so", + cjkwd="w", + description="CJK RADICAL CLOTHES", + direction="on", + linebreak="id", + unicodeslot=0x2EC2, + }, + [0x2EC3]={ + category="so", + cjkwd="w", + description="CJK RADICAL WEST ONE", + direction="on", + linebreak="id", + unicodeslot=0x2EC3, + }, + [0x2EC4]={ + category="so", + cjkwd="w", + description="CJK RADICAL WEST TWO", + direction="on", + linebreak="id", + unicodeslot=0x2EC4, + }, + [0x2EC5]={ + category="so", + cjkwd="w", + description="CJK RADICAL C-SIMPLIFIED SEE", + direction="on", + linebreak="id", + unicodeslot=0x2EC5, + }, + [0x2EC6]={ + category="so", + cjkwd="w", + description="CJK RADICAL SIMPLIFIED HORN", + direction="on", + linebreak="id", + unicodeslot=0x2EC6, + }, + [0x2EC7]={ + category="so", + cjkwd="w", + description="CJK RADICAL HORN", + direction="on", + linebreak="id", + unicodeslot=0x2EC7, + }, + [0x2EC8]={ + category="so", + cjkwd="w", + description="CJK RADICAL C-SIMPLIFIED SPEECH", + direction="on", + linebreak="id", + unicodeslot=0x2EC8, + }, + [0x2EC9]={ + category="so", + cjkwd="w", + description="CJK RADICAL C-SIMPLIFIED SHELL", + direction="on", + linebreak="id", + unicodeslot=0x2EC9, + }, + [0x2ECA]={ + category="so", + cjkwd="w", + description="CJK RADICAL FOOT", + direction="on", + linebreak="id", + unicodeslot=0x2ECA, + }, + [0x2ECB]={ + category="so", + cjkwd="w", + description="CJK RADICAL C-SIMPLIFIED CART", + direction="on", + linebreak="id", + unicodeslot=0x2ECB, + }, + [0x2ECC]={ + category="so", + cjkwd="w", + description="CJK RADICAL SIMPLIFIED WALK", + direction="on", + linebreak="id", + unicodeslot=0x2ECC, + }, + [0x2ECD]={ + category="so", + cjkwd="w", + description="CJK RADICAL WALK ONE", + direction="on", + linebreak="id", + unicodeslot=0x2ECD, + }, + [0x2ECE]={ + category="so", + cjkwd="w", + description="CJK RADICAL WALK TWO", + direction="on", + linebreak="id", + unicodeslot=0x2ECE, + }, + [0x2ECF]={ + category="so", + cjkwd="w", + description="CJK RADICAL CITY", + direction="on", + linebreak="id", + unicodeslot=0x2ECF, + }, + [0x2ED0]={ + category="so", + cjkwd="w", + description="CJK RADICAL C-SIMPLIFIED GOLD", + direction="on", + linebreak="id", + unicodeslot=0x2ED0, + }, + [0x2ED1]={ + category="so", + cjkwd="w", + description="CJK RADICAL LONG ONE", + direction="on", + linebreak="id", + unicodeslot=0x2ED1, + }, + [0x2ED2]={ + category="so", + cjkwd="w", + description="CJK RADICAL LONG TWO", + direction="on", + linebreak="id", + unicodeslot=0x2ED2, + }, + [0x2ED3]={ + category="so", + cjkwd="w", + description="CJK RADICAL C-SIMPLIFIED LONG", + direction="on", + linebreak="id", + unicodeslot=0x2ED3, + }, + [0x2ED4]={ + category="so", + cjkwd="w", + description="CJK RADICAL C-SIMPLIFIED GATE", + direction="on", + linebreak="id", + unicodeslot=0x2ED4, + }, + [0x2ED5]={ + category="so", + cjkwd="w", + description="CJK RADICAL MOUND ONE", + direction="on", + linebreak="id", + unicodeslot=0x2ED5, + }, + [0x2ED6]={ + category="so", + cjkwd="w", + description="CJK RADICAL MOUND TWO", + direction="on", + linebreak="id", + unicodeslot=0x2ED6, + }, + [0x2ED7]={ + category="so", + cjkwd="w", + description="CJK RADICAL RAIN", + direction="on", + linebreak="id", + unicodeslot=0x2ED7, + }, + [0x2ED8]={ + category="so", + cjkwd="w", + description="CJK RADICAL BLUE", + direction="on", + linebreak="id", + unicodeslot=0x2ED8, + }, + [0x2ED9]={ + category="so", + cjkwd="w", + description="CJK RADICAL C-SIMPLIFIED TANNED LEATHER", + direction="on", + linebreak="id", + unicodeslot=0x2ED9, + }, + [0x2EDA]={ + category="so", + cjkwd="w", + description="CJK RADICAL C-SIMPLIFIED LEAF", + direction="on", + linebreak="id", + unicodeslot=0x2EDA, + }, + [0x2EDB]={ + category="so", + cjkwd="w", + description="CJK RADICAL C-SIMPLIFIED WIND", + direction="on", + linebreak="id", + unicodeslot=0x2EDB, + }, + [0x2EDC]={ + category="so", + cjkwd="w", + description="CJK RADICAL C-SIMPLIFIED FLY", + direction="on", + linebreak="id", + unicodeslot=0x2EDC, + }, + [0x2EDD]={ + category="so", + cjkwd="w", + description="CJK RADICAL EAT ONE", + direction="on", + linebreak="id", + unicodeslot=0x2EDD, + }, + [0x2EDE]={ + category="so", + cjkwd="w", + description="CJK RADICAL EAT TWO", + direction="on", + linebreak="id", + unicodeslot=0x2EDE, + }, + [0x2EDF]={ + category="so", + cjkwd="w", + description="CJK RADICAL EAT THREE", + direction="on", + linebreak="id", + unicodeslot=0x2EDF, + }, + [0x2EE0]={ + category="so", + cjkwd="w", + description="CJK RADICAL C-SIMPLIFIED EAT", + direction="on", + linebreak="id", + unicodeslot=0x2EE0, + }, + [0x2EE1]={ + category="so", + cjkwd="w", + description="CJK RADICAL HEAD", + direction="on", + linebreak="id", + unicodeslot=0x2EE1, + }, + [0x2EE2]={ + category="so", + cjkwd="w", + description="CJK RADICAL C-SIMPLIFIED HORSE", + direction="on", + linebreak="id", + unicodeslot=0x2EE2, + }, + [0x2EE3]={ + category="so", + cjkwd="w", + description="CJK RADICAL BONE", + direction="on", + linebreak="id", + unicodeslot=0x2EE3, + }, + [0x2EE4]={ + category="so", + cjkwd="w", + description="CJK RADICAL GHOST", + direction="on", + linebreak="id", + unicodeslot=0x2EE4, + }, + [0x2EE5]={ + category="so", + cjkwd="w", + description="CJK RADICAL C-SIMPLIFIED FISH", + direction="on", + linebreak="id", + unicodeslot=0x2EE5, + }, + [0x2EE6]={ + category="so", + cjkwd="w", + description="CJK RADICAL C-SIMPLIFIED BIRD", + direction="on", + linebreak="id", + unicodeslot=0x2EE6, + }, + [0x2EE7]={ + category="so", + cjkwd="w", + description="CJK RADICAL C-SIMPLIFIED SALT", + direction="on", + linebreak="id", + unicodeslot=0x2EE7, + }, + [0x2EE8]={ + category="so", + cjkwd="w", + description="CJK RADICAL SIMPLIFIED WHEAT", + direction="on", + linebreak="id", + unicodeslot=0x2EE8, + }, + [0x2EE9]={ + category="so", + cjkwd="w", + description="CJK RADICAL SIMPLIFIED YELLOW", + direction="on", + linebreak="id", + unicodeslot=0x2EE9, + }, + [0x2EEA]={ + category="so", + cjkwd="w", + description="CJK RADICAL C-SIMPLIFIED FROG", + direction="on", + linebreak="id", + unicodeslot=0x2EEA, + }, + [0x2EEB]={ + category="so", + cjkwd="w", + description="CJK RADICAL J-SIMPLIFIED EVEN", + direction="on", + linebreak="id", + unicodeslot=0x2EEB, + }, + [0x2EEC]={ + category="so", + cjkwd="w", + description="CJK RADICAL C-SIMPLIFIED EVEN", + direction="on", + linebreak="id", + unicodeslot=0x2EEC, + }, + [0x2EED]={ + category="so", + cjkwd="w", + description="CJK RADICAL J-SIMPLIFIED TOOTH", + direction="on", + linebreak="id", + unicodeslot=0x2EED, + }, + [0x2EEE]={ + category="so", + cjkwd="w", + description="CJK RADICAL C-SIMPLIFIED TOOTH", + direction="on", + linebreak="id", + unicodeslot=0x2EEE, + }, + [0x2EEF]={ + category="so", + cjkwd="w", + description="CJK RADICAL J-SIMPLIFIED DRAGON", + direction="on", + linebreak="id", + unicodeslot=0x2EEF, + }, + [0x2EF0]={ + category="so", + cjkwd="w", + description="CJK RADICAL C-SIMPLIFIED DRAGON", + direction="on", + linebreak="id", + unicodeslot=0x2EF0, + }, + [0x2EF1]={ + category="so", + cjkwd="w", + description="CJK RADICAL TURTLE", + direction="on", + linebreak="id", + unicodeslot=0x2EF1, + }, + [0x2EF2]={ + category="so", + cjkwd="w", + description="CJK RADICAL J-SIMPLIFIED TURTLE", + direction="on", + linebreak="id", + unicodeslot=0x2EF2, + }, + [0x2EF3]={ + category="so", + cjkwd="w", + description="CJK RADICAL C-SIMPLIFIED TURTLE", + direction="on", + linebreak="id", + specials={ "compat", 0x9F9F }, + unicodeslot=0x2EF3, + }, + [0x2F00]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL ONE", + direction="on", + linebreak="id", + specials={ "compat", 0x4E00 }, + unicodeslot=0x2F00, + }, + [0x2F01]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL LINE", + direction="on", + linebreak="id", + specials={ "compat", 0x4E28 }, + unicodeslot=0x2F01, + }, + [0x2F02]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL DOT", + direction="on", + linebreak="id", + specials={ "compat", 0x4E36 }, + unicodeslot=0x2F02, + }, + [0x2F03]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SLASH", + direction="on", + linebreak="id", + specials={ "compat", 0x4E3F }, + unicodeslot=0x2F03, + }, + [0x2F04]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SECOND", + direction="on", + linebreak="id", + specials={ "compat", 0x4E59 }, + unicodeslot=0x2F04, + }, + [0x2F05]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL HOOK", + direction="on", + linebreak="id", + specials={ "compat", 0x4E85 }, + unicodeslot=0x2F05, + }, + [0x2F06]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL TWO", + direction="on", + linebreak="id", + specials={ "compat", 0x4E8C }, + unicodeslot=0x2F06, + }, + [0x2F07]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL LID", + direction="on", + linebreak="id", + specials={ "compat", 0x4EA0 }, + unicodeslot=0x2F07, + }, + [0x2F08]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL MAN", + direction="on", + linebreak="id", + specials={ "compat", 0x4EBA }, + unicodeslot=0x2F08, + }, + [0x2F09]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL LEGS", + direction="on", + linebreak="id", + specials={ "compat", 0x513F }, + unicodeslot=0x2F09, + }, + [0x2F0A]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL ENTER", + direction="on", + linebreak="id", + specials={ "compat", 0x5165 }, + unicodeslot=0x2F0A, + }, + [0x2F0B]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL EIGHT", + direction="on", + linebreak="id", + specials={ "compat", 0x516B }, + unicodeslot=0x2F0B, + }, + [0x2F0C]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL DOWN BOX", + direction="on", + linebreak="id", + specials={ "compat", 0x5182 }, + unicodeslot=0x2F0C, + }, + [0x2F0D]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL COVER", + direction="on", + linebreak="id", + specials={ "compat", 0x5196 }, + unicodeslot=0x2F0D, + }, + [0x2F0E]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL ICE", + direction="on", + linebreak="id", + specials={ "compat", 0x51AB }, + unicodeslot=0x2F0E, + }, + [0x2F0F]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL TABLE", + direction="on", + linebreak="id", + specials={ "compat", 0x51E0 }, + unicodeslot=0x2F0F, + }, + [0x2F10]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL OPEN BOX", + direction="on", + linebreak="id", + specials={ "compat", 0x51F5 }, + unicodeslot=0x2F10, + }, + [0x2F11]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL KNIFE", + direction="on", + linebreak="id", + specials={ "compat", 0x5200 }, + unicodeslot=0x2F11, + }, + [0x2F12]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL POWER", + direction="on", + linebreak="id", + specials={ "compat", 0x529B }, + unicodeslot=0x2F12, + }, + [0x2F13]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL WRAP", + direction="on", + linebreak="id", + specials={ "compat", 0x52F9 }, + unicodeslot=0x2F13, + }, + [0x2F14]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SPOON", + direction="on", + linebreak="id", + specials={ "compat", 0x5315 }, + unicodeslot=0x2F14, + }, + [0x2F15]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL RIGHT OPEN BOX", + direction="on", + linebreak="id", + specials={ "compat", 0x531A }, + unicodeslot=0x2F15, + }, + [0x2F16]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL HIDING ENCLOSURE", + direction="on", + linebreak="id", + specials={ "compat", 0x5338 }, + unicodeslot=0x2F16, + }, + [0x2F17]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL TEN", + direction="on", + linebreak="id", + specials={ "compat", 0x5341 }, + unicodeslot=0x2F17, + }, + [0x2F18]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL DIVINATION", + direction="on", + linebreak="id", + specials={ "compat", 0x535C }, + unicodeslot=0x2F18, + }, + [0x2F19]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SEAL", + direction="on", + linebreak="id", + specials={ "compat", 0x5369 }, + unicodeslot=0x2F19, + }, + [0x2F1A]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL CLIFF", + direction="on", + linebreak="id", + specials={ "compat", 0x5382 }, + unicodeslot=0x2F1A, + }, + [0x2F1B]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL PRIVATE", + direction="on", + linebreak="id", + specials={ "compat", 0x53B6 }, + unicodeslot=0x2F1B, + }, + [0x2F1C]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL AGAIN", + direction="on", + linebreak="id", + specials={ "compat", 0x53C8 }, + unicodeslot=0x2F1C, + }, + [0x2F1D]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL MOUTH", + direction="on", + linebreak="id", + specials={ "compat", 0x53E3 }, + unicodeslot=0x2F1D, + }, + [0x2F1E]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL ENCLOSURE", + direction="on", + linebreak="id", + specials={ "compat", 0x56D7 }, + unicodeslot=0x2F1E, + }, + [0x2F1F]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL EARTH", + direction="on", + linebreak="id", + specials={ "compat", 0x571F }, + unicodeslot=0x2F1F, + }, + [0x2F20]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SCHOLAR", + direction="on", + linebreak="id", + specials={ "compat", 0x58EB }, + unicodeslot=0x2F20, + }, + [0x2F21]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL GO", + direction="on", + linebreak="id", + specials={ "compat", 0x5902 }, + unicodeslot=0x2F21, + }, + [0x2F22]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL GO SLOWLY", + direction="on", + linebreak="id", + specials={ "compat", 0x590A }, + unicodeslot=0x2F22, + }, + [0x2F23]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL EVENING", + direction="on", + linebreak="id", + specials={ "compat", 0x5915 }, + unicodeslot=0x2F23, + }, + [0x2F24]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL BIG", + direction="on", + linebreak="id", + specials={ "compat", 0x5927 }, + unicodeslot=0x2F24, + }, + [0x2F25]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL WOMAN", + direction="on", + linebreak="id", + specials={ "compat", 0x5973 }, + unicodeslot=0x2F25, + }, + [0x2F26]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL CHILD", + direction="on", + linebreak="id", + specials={ "compat", 0x5B50 }, + unicodeslot=0x2F26, + }, + [0x2F27]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL ROOF", + direction="on", + linebreak="id", + specials={ "compat", 0x5B80 }, + unicodeslot=0x2F27, + }, + [0x2F28]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL INCH", + direction="on", + linebreak="id", + specials={ "compat", 0x5BF8 }, + unicodeslot=0x2F28, + }, + [0x2F29]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SMALL", + direction="on", + linebreak="id", + specials={ "compat", 0x5C0F }, + unicodeslot=0x2F29, + }, + [0x2F2A]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL LAME", + direction="on", + linebreak="id", + specials={ "compat", 0x5C22 }, + unicodeslot=0x2F2A, + }, + [0x2F2B]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL CORPSE", + direction="on", + linebreak="id", + specials={ "compat", 0x5C38 }, + unicodeslot=0x2F2B, + }, + [0x2F2C]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SPROUT", + direction="on", + linebreak="id", + specials={ "compat", 0x5C6E }, + unicodeslot=0x2F2C, + }, + [0x2F2D]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL MOUNTAIN", + direction="on", + linebreak="id", + specials={ "compat", 0x5C71 }, + unicodeslot=0x2F2D, + }, + [0x2F2E]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL RIVER", + direction="on", + linebreak="id", + specials={ "compat", 0x5DDB }, + unicodeslot=0x2F2E, + }, + [0x2F2F]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL WORK", + direction="on", + linebreak="id", + specials={ "compat", 0x5DE5 }, + unicodeslot=0x2F2F, + }, + [0x2F30]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL ONESELF", + direction="on", + linebreak="id", + specials={ "compat", 0x5DF1 }, + unicodeslot=0x2F30, + }, + [0x2F31]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL TURBAN", + direction="on", + linebreak="id", + specials={ "compat", 0x5DFE }, + unicodeslot=0x2F31, + }, + [0x2F32]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL DRY", + direction="on", + linebreak="id", + specials={ "compat", 0x5E72 }, + unicodeslot=0x2F32, + }, + [0x2F33]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SHORT THREAD", + direction="on", + linebreak="id", + specials={ "compat", 0x5E7A }, + unicodeslot=0x2F33, + }, + [0x2F34]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL DOTTED CLIFF", + direction="on", + linebreak="id", + specials={ "compat", 0x5E7F }, + unicodeslot=0x2F34, + }, + [0x2F35]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL LONG STRIDE", + direction="on", + linebreak="id", + specials={ "compat", 0x5EF4 }, + unicodeslot=0x2F35, + }, + [0x2F36]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL TWO HANDS", + direction="on", + linebreak="id", + specials={ "compat", 0x5EFE }, + unicodeslot=0x2F36, + }, + [0x2F37]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SHOOT", + direction="on", + linebreak="id", + specials={ "compat", 0x5F0B }, + unicodeslot=0x2F37, + }, + [0x2F38]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL BOW", + direction="on", + linebreak="id", + specials={ "compat", 0x5F13 }, + unicodeslot=0x2F38, + }, + [0x2F39]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SNOUT", + direction="on", + linebreak="id", + specials={ "compat", 0x5F50 }, + unicodeslot=0x2F39, + }, + [0x2F3A]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL BRISTLE", + direction="on", + linebreak="id", + specials={ "compat", 0x5F61 }, + unicodeslot=0x2F3A, + }, + [0x2F3B]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL STEP", + direction="on", + linebreak="id", + specials={ "compat", 0x5F73 }, + unicodeslot=0x2F3B, + }, + [0x2F3C]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL HEART", + direction="on", + linebreak="id", + specials={ "compat", 0x5FC3 }, + unicodeslot=0x2F3C, + }, + [0x2F3D]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL HALBERD", + direction="on", + linebreak="id", + specials={ "compat", 0x6208 }, + unicodeslot=0x2F3D, + }, + [0x2F3E]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL DOOR", + direction="on", + linebreak="id", + specials={ "compat", 0x6236 }, + unicodeslot=0x2F3E, + }, + [0x2F3F]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL HAND", + direction="on", + linebreak="id", + specials={ "compat", 0x624B }, + unicodeslot=0x2F3F, + }, + [0x2F40]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL BRANCH", + direction="on", + linebreak="id", + specials={ "compat", 0x652F }, + unicodeslot=0x2F40, + }, + [0x2F41]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL RAP", + direction="on", + linebreak="id", + specials={ "compat", 0x6534 }, + unicodeslot=0x2F41, + }, + [0x2F42]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SCRIPT", + direction="on", + linebreak="id", + specials={ "compat", 0x6587 }, + unicodeslot=0x2F42, + }, + [0x2F43]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL DIPPER", + direction="on", + linebreak="id", + specials={ "compat", 0x6597 }, + unicodeslot=0x2F43, + }, + [0x2F44]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL AXE", + direction="on", + linebreak="id", + specials={ "compat", 0x65A4 }, + unicodeslot=0x2F44, + }, + [0x2F45]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SQUARE", + direction="on", + linebreak="id", + specials={ "compat", 0x65B9 }, + unicodeslot=0x2F45, + }, + [0x2F46]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL NOT", + direction="on", + linebreak="id", + specials={ "compat", 0x65E0 }, + unicodeslot=0x2F46, + }, + [0x2F47]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SUN", + direction="on", + linebreak="id", + specials={ "compat", 0x65E5 }, + unicodeslot=0x2F47, + }, + [0x2F48]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SAY", + direction="on", + linebreak="id", + specials={ "compat", 0x66F0 }, + unicodeslot=0x2F48, + }, + [0x2F49]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL MOON", + direction="on", + linebreak="id", + specials={ "compat", 0x6708 }, + unicodeslot=0x2F49, + }, + [0x2F4A]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL TREE", + direction="on", + linebreak="id", + specials={ "compat", 0x6728 }, + unicodeslot=0x2F4A, + }, + [0x2F4B]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL LACK", + direction="on", + linebreak="id", + specials={ "compat", 0x6B20 }, + unicodeslot=0x2F4B, + }, + [0x2F4C]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL STOP", + direction="on", + linebreak="id", + specials={ "compat", 0x6B62 }, + unicodeslot=0x2F4C, + }, + [0x2F4D]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL DEATH", + direction="on", + linebreak="id", + specials={ "compat", 0x6B79 }, + unicodeslot=0x2F4D, + }, + [0x2F4E]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL WEAPON", + direction="on", + linebreak="id", + specials={ "compat", 0x6BB3 }, + unicodeslot=0x2F4E, + }, + [0x2F4F]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL DO NOT", + direction="on", + linebreak="id", + specials={ "compat", 0x6BCB }, + unicodeslot=0x2F4F, + }, + [0x2F50]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL COMPARE", + direction="on", + linebreak="id", + specials={ "compat", 0x6BD4 }, + unicodeslot=0x2F50, + }, + [0x2F51]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL FUR", + direction="on", + linebreak="id", + specials={ "compat", 0x6BDB }, + unicodeslot=0x2F51, + }, + [0x2F52]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL CLAN", + direction="on", + linebreak="id", + specials={ "compat", 0x6C0F }, + unicodeslot=0x2F52, + }, + [0x2F53]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL STEAM", + direction="on", + linebreak="id", + specials={ "compat", 0x6C14 }, + unicodeslot=0x2F53, + }, + [0x2F54]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL WATER", + direction="on", + linebreak="id", + specials={ "compat", 0x6C34 }, + unicodeslot=0x2F54, + }, + [0x2F55]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL FIRE", + direction="on", + linebreak="id", + specials={ "compat", 0x706B }, + unicodeslot=0x2F55, + }, + [0x2F56]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL CLAW", + direction="on", + linebreak="id", + specials={ "compat", 0x722A }, + unicodeslot=0x2F56, + }, + [0x2F57]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL FATHER", + direction="on", + linebreak="id", + specials={ "compat", 0x7236 }, + unicodeslot=0x2F57, + }, + [0x2F58]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL DOUBLE X", + direction="on", + linebreak="id", + specials={ "compat", 0x723B }, + unicodeslot=0x2F58, + }, + [0x2F59]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL HALF TREE TRUNK", + direction="on", + linebreak="id", + specials={ "compat", 0x723F }, + unicodeslot=0x2F59, + }, + [0x2F5A]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SLICE", + direction="on", + linebreak="id", + specials={ "compat", 0x7247 }, + unicodeslot=0x2F5A, + }, + [0x2F5B]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL FANG", + direction="on", + linebreak="id", + specials={ "compat", 0x7259 }, + unicodeslot=0x2F5B, + }, + [0x2F5C]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL COW", + direction="on", + linebreak="id", + specials={ "compat", 0x725B }, + unicodeslot=0x2F5C, + }, + [0x2F5D]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL DOG", + direction="on", + linebreak="id", + specials={ "compat", 0x72AC }, + unicodeslot=0x2F5D, + }, + [0x2F5E]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL PROFOUND", + direction="on", + linebreak="id", + specials={ "compat", 0x7384 }, + unicodeslot=0x2F5E, + }, + [0x2F5F]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL JADE", + direction="on", + linebreak="id", + specials={ "compat", 0x7389 }, + unicodeslot=0x2F5F, + }, + [0x2F60]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL MELON", + direction="on", + linebreak="id", + specials={ "compat", 0x74DC }, + unicodeslot=0x2F60, + }, + [0x2F61]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL TILE", + direction="on", + linebreak="id", + specials={ "compat", 0x74E6 }, + unicodeslot=0x2F61, + }, + [0x2F62]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SWEET", + direction="on", + linebreak="id", + specials={ "compat", 0x7518 }, + unicodeslot=0x2F62, + }, + [0x2F63]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL LIFE", + direction="on", + linebreak="id", + specials={ "compat", 0x751F }, + unicodeslot=0x2F63, + }, + [0x2F64]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL USE", + direction="on", + linebreak="id", + specials={ "compat", 0x7528 }, + unicodeslot=0x2F64, + }, + [0x2F65]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL FIELD", + direction="on", + linebreak="id", + specials={ "compat", 0x7530 }, + unicodeslot=0x2F65, + }, + [0x2F66]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL BOLT OF CLOTH", + direction="on", + linebreak="id", + specials={ "compat", 0x758B }, + unicodeslot=0x2F66, + }, + [0x2F67]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SICKNESS", + direction="on", + linebreak="id", + specials={ "compat", 0x7592 }, + unicodeslot=0x2F67, + }, + [0x2F68]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL DOTTED TENT", + direction="on", + linebreak="id", + specials={ "compat", 0x7676 }, + unicodeslot=0x2F68, + }, + [0x2F69]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL WHITE", + direction="on", + linebreak="id", + specials={ "compat", 0x767D }, + unicodeslot=0x2F69, + }, + [0x2F6A]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SKIN", + direction="on", + linebreak="id", + specials={ "compat", 0x76AE }, + unicodeslot=0x2F6A, + }, + [0x2F6B]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL DISH", + direction="on", + linebreak="id", + specials={ "compat", 0x76BF }, + unicodeslot=0x2F6B, + }, + [0x2F6C]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL EYE", + direction="on", + linebreak="id", + specials={ "compat", 0x76EE }, + unicodeslot=0x2F6C, + }, + [0x2F6D]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SPEAR", + direction="on", + linebreak="id", + specials={ "compat", 0x77DB }, + unicodeslot=0x2F6D, + }, + [0x2F6E]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL ARROW", + direction="on", + linebreak="id", + specials={ "compat", 0x77E2 }, + unicodeslot=0x2F6E, + }, + [0x2F6F]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL STONE", + direction="on", + linebreak="id", + specials={ "compat", 0x77F3 }, + unicodeslot=0x2F6F, + }, + [0x2F70]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SPIRIT", + direction="on", + linebreak="id", + specials={ "compat", 0x793A }, + unicodeslot=0x2F70, + }, + [0x2F71]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL TRACK", + direction="on", + linebreak="id", + specials={ "compat", 0x79B8 }, + unicodeslot=0x2F71, + }, + [0x2F72]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL GRAIN", + direction="on", + linebreak="id", + specials={ "compat", 0x79BE }, + unicodeslot=0x2F72, + }, + [0x2F73]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL CAVE", + direction="on", + linebreak="id", + specials={ "compat", 0x7A74 }, + unicodeslot=0x2F73, + }, + [0x2F74]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL STAND", + direction="on", + linebreak="id", + specials={ "compat", 0x7ACB }, + unicodeslot=0x2F74, + }, + [0x2F75]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL BAMBOO", + direction="on", + linebreak="id", + specials={ "compat", 0x7AF9 }, + unicodeslot=0x2F75, + }, + [0x2F76]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL RICE", + direction="on", + linebreak="id", + specials={ "compat", 0x7C73 }, + unicodeslot=0x2F76, + }, + [0x2F77]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SILK", + direction="on", + linebreak="id", + specials={ "compat", 0x7CF8 }, + unicodeslot=0x2F77, + }, + [0x2F78]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL JAR", + direction="on", + linebreak="id", + specials={ "compat", 0x7F36 }, + unicodeslot=0x2F78, + }, + [0x2F79]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL NET", + direction="on", + linebreak="id", + specials={ "compat", 0x7F51 }, + unicodeslot=0x2F79, + }, + [0x2F7A]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SHEEP", + direction="on", + linebreak="id", + specials={ "compat", 0x7F8A }, + unicodeslot=0x2F7A, + }, + [0x2F7B]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL FEATHER", + direction="on", + linebreak="id", + specials={ "compat", 0x7FBD }, + unicodeslot=0x2F7B, + }, + [0x2F7C]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL OLD", + direction="on", + linebreak="id", + specials={ "compat", 0x8001 }, + unicodeslot=0x2F7C, + }, + [0x2F7D]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL AND", + direction="on", + linebreak="id", + specials={ "compat", 0x800C }, + unicodeslot=0x2F7D, + }, + [0x2F7E]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL PLOW", + direction="on", + linebreak="id", + specials={ "compat", 0x8012 }, + unicodeslot=0x2F7E, + }, + [0x2F7F]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL EAR", + direction="on", + linebreak="id", + specials={ "compat", 0x8033 }, + unicodeslot=0x2F7F, + }, + [0x2F80]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL BRUSH", + direction="on", + linebreak="id", + specials={ "compat", 0x807F }, + unicodeslot=0x2F80, + }, + [0x2F81]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL MEAT", + direction="on", + linebreak="id", + specials={ "compat", 0x8089 }, + unicodeslot=0x2F81, + }, + [0x2F82]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL MINISTER", + direction="on", + linebreak="id", + specials={ "compat", 0x81E3 }, + unicodeslot=0x2F82, + }, + [0x2F83]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SELF", + direction="on", + linebreak="id", + specials={ "compat", 0x81EA }, + unicodeslot=0x2F83, + }, + [0x2F84]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL ARRIVE", + direction="on", + linebreak="id", + specials={ "compat", 0x81F3 }, + unicodeslot=0x2F84, + }, + [0x2F85]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL MORTAR", + direction="on", + linebreak="id", + specials={ "compat", 0x81FC }, + unicodeslot=0x2F85, + }, + [0x2F86]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL TONGUE", + direction="on", + linebreak="id", + specials={ "compat", 0x820C }, + unicodeslot=0x2F86, + }, + [0x2F87]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL OPPOSE", + direction="on", + linebreak="id", + specials={ "compat", 0x821B }, + unicodeslot=0x2F87, + }, + [0x2F88]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL BOAT", + direction="on", + linebreak="id", + specials={ "compat", 0x821F }, + unicodeslot=0x2F88, + }, + [0x2F89]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL STOPPING", + direction="on", + linebreak="id", + specials={ "compat", 0x826E }, + unicodeslot=0x2F89, + }, + [0x2F8A]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL COLOR", + direction="on", + linebreak="id", + specials={ "compat", 0x8272 }, + unicodeslot=0x2F8A, + }, + [0x2F8B]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL GRASS", + direction="on", + linebreak="id", + specials={ "compat", 0x8278 }, + unicodeslot=0x2F8B, + }, + [0x2F8C]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL TIGER", + direction="on", + linebreak="id", + specials={ "compat", 0x864D }, + unicodeslot=0x2F8C, + }, + [0x2F8D]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL INSECT", + direction="on", + linebreak="id", + specials={ "compat", 0x866B }, + unicodeslot=0x2F8D, + }, + [0x2F8E]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL BLOOD", + direction="on", + linebreak="id", + specials={ "compat", 0x8840 }, + unicodeslot=0x2F8E, + }, + [0x2F8F]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL WALK ENCLOSURE", + direction="on", + linebreak="id", + specials={ "compat", 0x884C }, + unicodeslot=0x2F8F, + }, + [0x2F90]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL CLOTHES", + direction="on", + linebreak="id", + specials={ "compat", 0x8863 }, + unicodeslot=0x2F90, + }, + [0x2F91]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL WEST", + direction="on", + linebreak="id", + specials={ "compat", 0x897E }, + unicodeslot=0x2F91, + }, + [0x2F92]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SEE", + direction="on", + linebreak="id", + specials={ "compat", 0x898B }, + unicodeslot=0x2F92, + }, + [0x2F93]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL HORN", + direction="on", + linebreak="id", + specials={ "compat", 0x89D2 }, + unicodeslot=0x2F93, + }, + [0x2F94]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SPEECH", + direction="on", + linebreak="id", + specials={ "compat", 0x8A00 }, + unicodeslot=0x2F94, + }, + [0x2F95]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL VALLEY", + direction="on", + linebreak="id", + specials={ "compat", 0x8C37 }, + unicodeslot=0x2F95, + }, + [0x2F96]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL BEAN", + direction="on", + linebreak="id", + specials={ "compat", 0x8C46 }, + unicodeslot=0x2F96, + }, + [0x2F97]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL PIG", + direction="on", + linebreak="id", + specials={ "compat", 0x8C55 }, + unicodeslot=0x2F97, + }, + [0x2F98]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL BADGER", + direction="on", + linebreak="id", + specials={ "compat", 0x8C78 }, + unicodeslot=0x2F98, + }, + [0x2F99]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SHELL", + direction="on", + linebreak="id", + specials={ "compat", 0x8C9D }, + unicodeslot=0x2F99, + }, + [0x2F9A]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL RED", + direction="on", + linebreak="id", + specials={ "compat", 0x8D64 }, + unicodeslot=0x2F9A, + }, + [0x2F9B]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL RUN", + direction="on", + linebreak="id", + specials={ "compat", 0x8D70 }, + unicodeslot=0x2F9B, + }, + [0x2F9C]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL FOOT", + direction="on", + linebreak="id", + specials={ "compat", 0x8DB3 }, + unicodeslot=0x2F9C, + }, + [0x2F9D]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL BODY", + direction="on", + linebreak="id", + specials={ "compat", 0x8EAB }, + unicodeslot=0x2F9D, + }, + [0x2F9E]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL CART", + direction="on", + linebreak="id", + specials={ "compat", 0x8ECA }, + unicodeslot=0x2F9E, + }, + [0x2F9F]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL BITTER", + direction="on", + linebreak="id", + specials={ "compat", 0x8F9B }, + unicodeslot=0x2F9F, + }, + [0x2FA0]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL MORNING", + direction="on", + linebreak="id", + specials={ "compat", 0x8FB0 }, + unicodeslot=0x2FA0, + }, + [0x2FA1]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL WALK", + direction="on", + linebreak="id", + specials={ "compat", 0x8FB5 }, + unicodeslot=0x2FA1, + }, + [0x2FA2]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL CITY", + direction="on", + linebreak="id", + specials={ "compat", 0x9091 }, + unicodeslot=0x2FA2, + }, + [0x2FA3]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL WINE", + direction="on", + linebreak="id", + specials={ "compat", 0x9149 }, + unicodeslot=0x2FA3, + }, + [0x2FA4]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL DISTINGUISH", + direction="on", + linebreak="id", + specials={ "compat", 0x91C6 }, + unicodeslot=0x2FA4, + }, + [0x2FA5]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL VILLAGE", + direction="on", + linebreak="id", + specials={ "compat", 0x91CC }, + unicodeslot=0x2FA5, + }, + [0x2FA6]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL GOLD", + direction="on", + linebreak="id", + specials={ "compat", 0x91D1 }, + unicodeslot=0x2FA6, + }, + [0x2FA7]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL LONG", + direction="on", + linebreak="id", + specials={ "compat", 0x9577 }, + unicodeslot=0x2FA7, + }, + [0x2FA8]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL GATE", + direction="on", + linebreak="id", + specials={ "compat", 0x9580 }, + unicodeslot=0x2FA8, + }, + [0x2FA9]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL MOUND", + direction="on", + linebreak="id", + specials={ "compat", 0x961C }, + unicodeslot=0x2FA9, + }, + [0x2FAA]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SLAVE", + direction="on", + linebreak="id", + specials={ "compat", 0x96B6 }, + unicodeslot=0x2FAA, + }, + [0x2FAB]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SHORT TAILED BIRD", + direction="on", + linebreak="id", + specials={ "compat", 0x96B9 }, + unicodeslot=0x2FAB, + }, + [0x2FAC]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL RAIN", + direction="on", + linebreak="id", + specials={ "compat", 0x96E8 }, + unicodeslot=0x2FAC, + }, + [0x2FAD]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL BLUE", + direction="on", + linebreak="id", + specials={ "compat", 0x9751 }, + unicodeslot=0x2FAD, + }, + [0x2FAE]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL WRONG", + direction="on", + linebreak="id", + specials={ "compat", 0x975E }, + unicodeslot=0x2FAE, + }, + [0x2FAF]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL FACE", + direction="on", + linebreak="id", + specials={ "compat", 0x9762 }, + unicodeslot=0x2FAF, + }, + [0x2FB0]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL LEATHER", + direction="on", + linebreak="id", + specials={ "compat", 0x9769 }, + unicodeslot=0x2FB0, + }, + [0x2FB1]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL TANNED LEATHER", + direction="on", + linebreak="id", + specials={ "compat", 0x97CB }, + unicodeslot=0x2FB1, + }, + [0x2FB2]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL LEEK", + direction="on", + linebreak="id", + specials={ "compat", 0x97ED }, + unicodeslot=0x2FB2, + }, + [0x2FB3]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SOUND", + direction="on", + linebreak="id", + specials={ "compat", 0x97F3 }, + unicodeslot=0x2FB3, + }, + [0x2FB4]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL LEAF", + direction="on", + linebreak="id", + specials={ "compat", 0x9801 }, + unicodeslot=0x2FB4, + }, + [0x2FB5]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL WIND", + direction="on", + linebreak="id", + specials={ "compat", 0x98A8 }, + unicodeslot=0x2FB5, + }, + [0x2FB6]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL FLY", + direction="on", + linebreak="id", + specials={ "compat", 0x98DB }, + unicodeslot=0x2FB6, + }, + [0x2FB7]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL EAT", + direction="on", + linebreak="id", + specials={ "compat", 0x98DF }, + unicodeslot=0x2FB7, + }, + [0x2FB8]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL HEAD", + direction="on", + linebreak="id", + specials={ "compat", 0x9996 }, + unicodeslot=0x2FB8, + }, + [0x2FB9]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL FRAGRANT", + direction="on", + linebreak="id", + specials={ "compat", 0x9999 }, + unicodeslot=0x2FB9, + }, + [0x2FBA]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL HORSE", + direction="on", + linebreak="id", + specials={ "compat", 0x99AC }, + unicodeslot=0x2FBA, + }, + [0x2FBB]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL BONE", + direction="on", + linebreak="id", + specials={ "compat", 0x9AA8 }, + unicodeslot=0x2FBB, + }, + [0x2FBC]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL TALL", + direction="on", + linebreak="id", + specials={ "compat", 0x9AD8 }, + unicodeslot=0x2FBC, + }, + [0x2FBD]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL HAIR", + direction="on", + linebreak="id", + specials={ "compat", 0x9ADF }, + unicodeslot=0x2FBD, + }, + [0x2FBE]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL FIGHT", + direction="on", + linebreak="id", + specials={ "compat", 0x9B25 }, + unicodeslot=0x2FBE, + }, + [0x2FBF]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SACRIFICIAL WINE", + direction="on", + linebreak="id", + specials={ "compat", 0x9B2F }, + unicodeslot=0x2FBF, + }, + [0x2FC0]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL CAULDRON", + direction="on", + linebreak="id", + specials={ "compat", 0x9B32 }, + unicodeslot=0x2FC0, + }, + [0x2FC1]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL GHOST", + direction="on", + linebreak="id", + specials={ "compat", 0x9B3C }, + unicodeslot=0x2FC1, + }, + [0x2FC2]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL FISH", + direction="on", + linebreak="id", + specials={ "compat", 0x9B5A }, + unicodeslot=0x2FC2, + }, + [0x2FC3]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL BIRD", + direction="on", + linebreak="id", + specials={ "compat", 0x9CE5 }, + unicodeslot=0x2FC3, + }, + [0x2FC4]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL SALT", + direction="on", + linebreak="id", + specials={ "compat", 0x9E75 }, + unicodeslot=0x2FC4, + }, + [0x2FC5]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL DEER", + direction="on", + linebreak="id", + specials={ "compat", 0x9E7F }, + unicodeslot=0x2FC5, + }, + [0x2FC6]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL WHEAT", + direction="on", + linebreak="id", + specials={ "compat", 0x9EA5 }, + unicodeslot=0x2FC6, + }, + [0x2FC7]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL HEMP", + direction="on", + linebreak="id", + specials={ "compat", 0x9EBB }, + unicodeslot=0x2FC7, + }, + [0x2FC8]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL YELLOW", + direction="on", + linebreak="id", + specials={ "compat", 0x9EC3 }, + unicodeslot=0x2FC8, + }, + [0x2FC9]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL MILLET", + direction="on", + linebreak="id", + specials={ "compat", 0x9ECD }, + unicodeslot=0x2FC9, + }, + [0x2FCA]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL BLACK", + direction="on", + linebreak="id", + specials={ "compat", 0x9ED1 }, + unicodeslot=0x2FCA, + }, + [0x2FCB]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL EMBROIDERY", + direction="on", + linebreak="id", + specials={ "compat", 0x9EF9 }, + unicodeslot=0x2FCB, + }, + [0x2FCC]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL FROG", + direction="on", + linebreak="id", + specials={ "compat", 0x9EFD }, + unicodeslot=0x2FCC, + }, + [0x2FCD]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL TRIPOD", + direction="on", + linebreak="id", + specials={ "compat", 0x9F0E }, + unicodeslot=0x2FCD, + }, + [0x2FCE]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL DRUM", + direction="on", + linebreak="id", + specials={ "compat", 0x9F13 }, + unicodeslot=0x2FCE, + }, + [0x2FCF]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL RAT", + direction="on", + linebreak="id", + specials={ "compat", 0x9F20 }, + unicodeslot=0x2FCF, + }, + [0x2FD0]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL NOSE", + direction="on", + linebreak="id", + specials={ "compat", 0x9F3B }, + unicodeslot=0x2FD0, + }, + [0x2FD1]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL EVEN", + direction="on", + linebreak="id", + specials={ "compat", 0x9F4A }, + unicodeslot=0x2FD1, + }, + [0x2FD2]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL TOOTH", + direction="on", + linebreak="id", + specials={ "compat", 0x9F52 }, + unicodeslot=0x2FD2, + }, + [0x2FD3]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL DRAGON", + direction="on", + linebreak="id", + specials={ "compat", 0x9F8D }, + unicodeslot=0x2FD3, + }, + [0x2FD4]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL TURTLE", + direction="on", + linebreak="id", + specials={ "compat", 0x9F9C }, + unicodeslot=0x2FD4, + }, + [0x2FD5]={ + category="so", + cjkwd="w", + description="KANGXI RADICAL FLUTE", + direction="on", + linebreak="id", + specials={ "compat", 0x9FA0 }, + unicodeslot=0x2FD5, + }, + [0x2FF0]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT", + direction="on", + linebreak="id", + unicodeslot=0x2FF0, + }, + [0x2FF1]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO BELOW", + direction="on", + linebreak="id", + unicodeslot=0x2FF1, + }, + [0x2FF2]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO MIDDLE AND RIGHT", + direction="on", + linebreak="id", + unicodeslot=0x2FF2, + }, + [0x2FF3]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO MIDDLE AND BELOW", + direction="on", + linebreak="id", + unicodeslot=0x2FF3, + }, + [0x2FF4]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC DESCRIPTION CHARACTER FULL SURROUND", + direction="on", + linebreak="id", + unicodeslot=0x2FF4, + }, + [0x2FF5]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM ABOVE", + direction="on", + linebreak="id", + unicodeslot=0x2FF5, + }, + [0x2FF6]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM BELOW", + direction="on", + linebreak="id", + unicodeslot=0x2FF6, + }, + [0x2FF7]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LEFT", + direction="on", + linebreak="id", + unicodeslot=0x2FF7, + }, + [0x2FF8]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER LEFT", + direction="on", + linebreak="id", + unicodeslot=0x2FF8, + }, + [0x2FF9]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER RIGHT", + direction="on", + linebreak="id", + unicodeslot=0x2FF9, + }, + [0x2FFA]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LOWER LEFT", + direction="on", + linebreak="id", + unicodeslot=0x2FFA, + }, + [0x2FFB]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID", + direction="on", + linebreak="id", + unicodeslot=0x2FFB, + }, + [0x3000]={ + category="zs", + cjkwd="f", + contextname="ideographicspace", + description="IDEOGRAPHIC SPACE", + direction="ws", + linebreak="id", + specials={ "wide", 0x0020 }, + unicodeslot=0x3000, + }, + [0x3001]={ + category="po", + cjkwd="w", + description="IDEOGRAPHIC COMMA", + direction="on", + linebreak="cl", + unicodeslot=0x3001, + }, + [0x3002]={ + category="po", + cjkwd="w", + description="IDEOGRAPHIC FULL STOP", + direction="on", + linebreak="cl", + unicodeslot=0x3002, + }, + [0x3003]={ + category="po", + cjkwd="w", + description="DITTO MARK", + direction="on", + linebreak="id", + unicodeslot=0x3003, + }, + [0x3004]={ + category="so", + cjkwd="w", + description="JAPANESE INDUSTRIAL STANDARD SYMBOL", + direction="on", + linebreak="id", + unicodeslot=0x3004, + }, + [0x3005]={ + category="lm", + cjkwd="w", + description="IDEOGRAPHIC ITERATION MARK", + direction="l", + linebreak="ns", + unicodeslot=0x3005, + }, + [0x3006]={ + category="lo", + cjkwd="w", + description="IDEOGRAPHIC CLOSING MARK", + direction="l", + linebreak="id", + unicodeslot=0x3006, + }, + [0x3007]={ + category="nl", + cjkwd="w", + description="IDEOGRAPHIC NUMBER ZERO", + direction="l", + linebreak="id", + unicodeslot=0x3007, + }, + [0x3008]={ + category="ps", + cjkwd="w", + description="LEFT ANGLE BRACKET", + direction="on", + linebreak="op", + mirror=0x3009, + unicodeslot=0x3008, + }, + [0x3009]={ + category="pe", + cjkwd="w", + description="RIGHT ANGLE BRACKET", + direction="on", + linebreak="cl", + mirror=0x3008, + unicodeslot=0x3009, + }, + [0x300A]={ + category="ps", + cjkwd="w", + description="LEFT DOUBLE ANGLE BRACKET", + direction="on", + linebreak="op", + mirror=0x300B, + unicodeslot=0x300A, + }, + [0x300B]={ + category="pe", + cjkwd="w", + description="RIGHT DOUBLE ANGLE BRACKET", + direction="on", + linebreak="cl", + mirror=0x300A, + unicodeslot=0x300B, + }, + [0x300C]={ + category="ps", + cjkwd="w", + description="LEFT CORNER BRACKET", + direction="on", + linebreak="op", + mirror=0x300D, + unicodeslot=0x300C, + }, + [0x300D]={ + category="pe", + cjkwd="w", + description="RIGHT CORNER BRACKET", + direction="on", + linebreak="cl", + mirror=0x300C, + unicodeslot=0x300D, + }, + [0x300E]={ + category="ps", + cjkwd="w", + description="LEFT WHITE CORNER BRACKET", + direction="on", + linebreak="op", + mirror=0x300F, + unicodeslot=0x300E, + }, + [0x300F]={ + category="pe", + cjkwd="w", + description="RIGHT WHITE CORNER BRACKET", + direction="on", + linebreak="cl", + mirror=0x300E, + unicodeslot=0x300F, + }, + [0x3010]={ + category="ps", + cjkwd="w", + description="LEFT BLACK LENTICULAR BRACKET", + direction="on", + linebreak="op", + mirror=0x3011, + unicodeslot=0x3010, + }, + [0x3011]={ + category="pe", + cjkwd="w", + description="RIGHT BLACK LENTICULAR BRACKET", + direction="on", + linebreak="cl", + mirror=0x3010, + unicodeslot=0x3011, + }, + [0x3012]={ + category="so", + cjkwd="w", + description="POSTAL MARK", + direction="on", + linebreak="id", + unicodeslot=0x3012, + }, + [0x3013]={ + category="so", + cjkwd="w", + description="GETA MARK", + direction="on", + linebreak="id", + unicodeslot=0x3013, + }, + [0x3014]={ + category="ps", + cjkwd="w", + description="LEFT TORTOISE SHELL BRACKET", + direction="on", + linebreak="op", + mirror=0x3015, + mathclass="open", + mathname="lgroup", + unicodeslot=0x3014, + }, + [0x3015]={ + category="pe", + cjkwd="w", + description="RIGHT TORTOISE SHELL BRACKET", + direction="on", + linebreak="cl", + mirror=0x3014, + mathclass="close", + mathname="rgroup", + unicodeslot=0x3015, + }, + [0x3016]={ + category="ps", + cjkwd="w", + description="LEFT WHITE LENTICULAR BRACKET", + direction="on", + linebreak="op", + mirror=0x3017, + unicodeslot=0x3016, + }, + [0x3017]={ + category="pe", + cjkwd="w", + description="RIGHT WHITE LENTICULAR BRACKET", + direction="on", + linebreak="cl", + mirror=0x3016, + unicodeslot=0x3017, + }, + [0x3018]={ + category="ps", + cjkwd="w", + description="LEFT WHITE TORTOISE SHELL BRACKET", + direction="on", + linebreak="op", + mirror=0x3019, + unicodeslot=0x3018, + }, + [0x3019]={ + category="pe", + cjkwd="w", + description="RIGHT WHITE TORTOISE SHELL BRACKET", + direction="on", + linebreak="cl", + mirror=0x3018, + unicodeslot=0x3019, + }, + [0x301A]={ + category="ps", + cjkwd="w", + description="LEFT WHITE SQUARE BRACKET", + direction="on", + linebreak="op", + mirror=0x301B, + unicodeslot=0x301A, + }, + [0x301B]={ + category="pe", + cjkwd="w", + description="RIGHT WHITE SQUARE BRACKET", + direction="on", + linebreak="cl", + mirror=0x301A, + unicodeslot=0x301B, + }, + [0x301C]={ + category="pd", + cjkwd="w", + description="WAVE DASH", + direction="on", + linebreak="ns", + unicodeslot=0x301C, + }, + [0x301D]={ + category="ps", + cjkwd="w", + description="REVERSED DOUBLE PRIME QUOTATION MARK", + direction="on", + linebreak="op", + unicodeslot=0x301D, + }, + [0x301E]={ + category="pe", + cjkwd="w", + description="DOUBLE PRIME QUOTATION MARK", + direction="on", + linebreak="cl", + unicodeslot=0x301E, + }, + [0x301F]={ + category="pe", + cjkwd="w", + description="LOW DOUBLE PRIME QUOTATION MARK", + direction="on", + linebreak="cl", + unicodeslot=0x301F, + }, + [0x3020]={ + category="so", + cjkwd="w", + description="POSTAL MARK FACE", + direction="on", + linebreak="id", + unicodeslot=0x3020, + }, + [0x3021]={ + category="nl", + cjkwd="w", + description="HANGZHOU NUMERAL ONE", + direction="l", + linebreak="id", + unicodeslot=0x3021, + }, + [0x3022]={ + category="nl", + cjkwd="w", + description="HANGZHOU NUMERAL TWO", + direction="l", + linebreak="id", + unicodeslot=0x3022, + }, + [0x3023]={ + category="nl", + cjkwd="w", + description="HANGZHOU NUMERAL THREE", + direction="l", + linebreak="id", + unicodeslot=0x3023, + }, + [0x3024]={ + category="nl", + cjkwd="w", + description="HANGZHOU NUMERAL FOUR", + direction="l", + linebreak="id", + unicodeslot=0x3024, + }, + [0x3025]={ + category="nl", + cjkwd="w", + description="HANGZHOU NUMERAL FIVE", + direction="l", + linebreak="id", + unicodeslot=0x3025, + }, + [0x3026]={ + category="nl", + cjkwd="w", + description="HANGZHOU NUMERAL SIX", + direction="l", + linebreak="id", + unicodeslot=0x3026, + }, + [0x3027]={ + category="nl", + cjkwd="w", + description="HANGZHOU NUMERAL SEVEN", + direction="l", + linebreak="id", + unicodeslot=0x3027, + }, + [0x3028]={ + category="nl", + cjkwd="w", + description="HANGZHOU NUMERAL EIGHT", + direction="l", + linebreak="id", + unicodeslot=0x3028, + }, + [0x3029]={ + category="nl", + cjkwd="w", + description="HANGZHOU NUMERAL NINE", + direction="l", + linebreak="id", + unicodeslot=0x3029, + }, + [0x302A]={ + category="mn", + cjkwd="w", + description="IDEOGRAPHIC LEVEL TONE MARK", + direction="nsm", + linebreak="cm", + unicodeslot=0x302A, + }, + [0x302B]={ + category="mn", + cjkwd="w", + description="IDEOGRAPHIC RISING TONE MARK", + direction="nsm", + linebreak="cm", + unicodeslot=0x302B, + }, + [0x302C]={ + category="mn", + cjkwd="w", + description="IDEOGRAPHIC DEPARTING TONE MARK", + direction="nsm", + linebreak="cm", + unicodeslot=0x302C, + }, + [0x302D]={ + category="mn", + cjkwd="w", + description="IDEOGRAPHIC ENTERING TONE MARK", + direction="nsm", + linebreak="cm", + unicodeslot=0x302D, + }, + [0x302E]={ + category="mn", + cjkwd="w", + description="HANGUL SINGLE DOT TONE MARK", + direction="nsm", + linebreak="cm", + unicodeslot=0x302E, + }, + [0x302F]={ + category="mn", + cjkwd="w", + description="HANGUL DOUBLE DOT TONE MARK", + direction="nsm", + linebreak="cm", + unicodeslot=0x302F, + }, + [0x3030]={ + category="pd", + cjkwd="w", + description="WAVY DASH", + direction="on", + linebreak="id", + unicodeslot=0x3030, + }, + [0x3031]={ + category="lm", + cjkwd="w", + description="VERTICAL KANA REPEAT MARK", + direction="l", + linebreak="id", + unicodeslot=0x3031, + }, + [0x3032]={ + category="lm", + cjkwd="w", + description="VERTICAL KANA REPEAT WITH VOICED SOUND MARK", + direction="l", + linebreak="id", + unicodeslot=0x3032, + }, + [0x3033]={ + category="lm", + cjkwd="w", + description="VERTICAL KANA REPEAT MARK UPPER HALF", + direction="l", + linebreak="id", + unicodeslot=0x3033, + }, + [0x3034]={ + category="lm", + cjkwd="w", + description="VERTICAL KANA REPEAT WITH VOICED SOUND MARK UPPER HALF", + direction="l", + linebreak="id", + unicodeslot=0x3034, + }, + [0x3035]={ + category="lm", + cjkwd="w", + description="VERTICAL KANA REPEAT MARK LOWER HALF", + direction="l", + linebreak="id", + unicodeslot=0x3035, + }, + [0x3036]={ + category="so", + cjkwd="w", + description="CIRCLED POSTAL MARK", + direction="on", + linebreak="id", + specials={ "compat", 0x3012 }, + unicodeslot=0x3036, + }, + [0x3037]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL", + direction="on", + linebreak="id", + unicodeslot=0x3037, + }, + [0x3038]={ + category="nl", + cjkwd="w", + description="HANGZHOU NUMERAL TEN", + direction="l", + linebreak="id", + specials={ "compat", 0x5341 }, + unicodeslot=0x3038, + }, + [0x3039]={ + category="nl", + cjkwd="w", + description="HANGZHOU NUMERAL TWENTY", + direction="l", + linebreak="id", + specials={ "compat", 0x5344 }, + unicodeslot=0x3039, + }, + [0x303A]={ + category="nl", + cjkwd="w", + description="HANGZHOU NUMERAL THIRTY", + direction="l", + linebreak="id", + specials={ "compat", 0x5345 }, + unicodeslot=0x303A, + }, + [0x303B]={ + category="lm", + cjkwd="w", + description="VERTICAL IDEOGRAPHIC ITERATION MARK", + direction="l", + linebreak="ns", + unicodeslot=0x303B, + }, + [0x303C]={ + category="lo", + cjkwd="w", + description="MASU MARK", + direction="l", + linebreak="ns", + unicodeslot=0x303C, + }, + [0x303D]={ + category="po", + cjkwd="w", + description="PART ALTERNATION MARK", + direction="on", + linebreak="id", + unicodeslot=0x303D, + }, + [0x303E]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC VARIATION INDICATOR", + direction="on", + linebreak="id", + unicodeslot=0x303E, + }, + [0x303F]={ + category="so", + contextname="ideographichalffillspace", + description="IDEOGRAPHIC HALF FILL SPACE", + direction="on", + linebreak="id", + unicodeslot=0x303F, + }, + [0x3041]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER SMALL A", + direction="l", + linebreak="ns", + unicodeslot=0x3041, + }, + [0x3042]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER A", + direction="l", + linebreak="id", + unicodeslot=0x3042, + }, + [0x3043]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER SMALL I", + direction="l", + linebreak="ns", + unicodeslot=0x3043, + }, + [0x3044]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER I", + direction="l", + linebreak="id", + unicodeslot=0x3044, + }, + [0x3045]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER SMALL U", + direction="l", + linebreak="ns", + unicodeslot=0x3045, + }, + [0x3046]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER U", + direction="l", + linebreak="id", + unicodeslot=0x3046, + }, + [0x3047]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER SMALL E", + direction="l", + linebreak="ns", + unicodeslot=0x3047, + }, + [0x3048]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER E", + direction="l", + linebreak="id", + unicodeslot=0x3048, + }, + [0x3049]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER SMALL O", + direction="l", + linebreak="ns", + unicodeslot=0x3049, + }, + [0x304A]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER O", + direction="l", + linebreak="id", + unicodeslot=0x304A, + }, + [0x304B]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER KA", + direction="l", + linebreak="id", + unicodeslot=0x304B, + }, + [0x304C]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER GA", + direction="l", + linebreak="id", + specials={ "char", 0x304B, 0x3099 }, + unicodeslot=0x304C, + }, + [0x304D]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER KI", + direction="l", + linebreak="id", + unicodeslot=0x304D, + }, + [0x304E]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER GI", + direction="l", + linebreak="id", + specials={ "char", 0x304D, 0x3099 }, + unicodeslot=0x304E, + }, + [0x304F]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER KU", + direction="l", + linebreak="id", + unicodeslot=0x304F, + }, + [0x3050]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER GU", + direction="l", + linebreak="id", + specials={ "char", 0x304F, 0x3099 }, + unicodeslot=0x3050, + }, + [0x3051]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER KE", + direction="l", + linebreak="id", + unicodeslot=0x3051, + }, + [0x3052]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER GE", + direction="l", + linebreak="id", + specials={ "char", 0x3051, 0x3099 }, + unicodeslot=0x3052, + }, + [0x3053]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER KO", + direction="l", + linebreak="id", + unicodeslot=0x3053, + }, + [0x3054]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER GO", + direction="l", + linebreak="id", + specials={ "char", 0x3053, 0x3099 }, + unicodeslot=0x3054, + }, + [0x3055]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER SA", + direction="l", + linebreak="id", + unicodeslot=0x3055, + }, + [0x3056]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER ZA", + direction="l", + linebreak="id", + specials={ "char", 0x3055, 0x3099 }, + unicodeslot=0x3056, + }, + [0x3057]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER SI", + direction="l", + linebreak="id", + unicodeslot=0x3057, + }, + [0x3058]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER ZI", + direction="l", + linebreak="id", + specials={ "char", 0x3057, 0x3099 }, + unicodeslot=0x3058, + }, + [0x3059]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER SU", + direction="l", + linebreak="id", + unicodeslot=0x3059, + }, + [0x305A]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER ZU", + direction="l", + linebreak="id", + specials={ "char", 0x3059, 0x3099 }, + unicodeslot=0x305A, + }, + [0x305B]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER SE", + direction="l", + linebreak="id", + unicodeslot=0x305B, + }, + [0x305C]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER ZE", + direction="l", + linebreak="id", + specials={ "char", 0x305B, 0x3099 }, + unicodeslot=0x305C, + }, + [0x305D]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER SO", + direction="l", + linebreak="id", + unicodeslot=0x305D, + }, + [0x305E]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER ZO", + direction="l", + linebreak="id", + specials={ "char", 0x305D, 0x3099 }, + unicodeslot=0x305E, + }, + [0x305F]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER TA", + direction="l", + linebreak="id", + unicodeslot=0x305F, + }, + [0x3060]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER DA", + direction="l", + linebreak="id", + specials={ "char", 0x305F, 0x3099 }, + unicodeslot=0x3060, + }, + [0x3061]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER TI", + direction="l", + linebreak="id", + unicodeslot=0x3061, + }, + [0x3062]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER DI", + direction="l", + linebreak="id", + specials={ "char", 0x3061, 0x3099 }, + unicodeslot=0x3062, + }, + [0x3063]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER SMALL TU", + direction="l", + linebreak="ns", + unicodeslot=0x3063, + }, + [0x3064]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER TU", + direction="l", + linebreak="id", + unicodeslot=0x3064, + }, + [0x3065]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER DU", + direction="l", + linebreak="id", + specials={ "char", 0x3064, 0x3099 }, + unicodeslot=0x3065, + }, + [0x3066]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER TE", + direction="l", + linebreak="id", + unicodeslot=0x3066, + }, + [0x3067]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER DE", + direction="l", + linebreak="id", + specials={ "char", 0x3066, 0x3099 }, + unicodeslot=0x3067, + }, + [0x3068]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER TO", + direction="l", + linebreak="id", + unicodeslot=0x3068, + }, + [0x3069]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER DO", + direction="l", + linebreak="id", + specials={ "char", 0x3068, 0x3099 }, + unicodeslot=0x3069, + }, + [0x306A]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER NA", + direction="l", + linebreak="id", + unicodeslot=0x306A, + }, + [0x306B]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER NI", + direction="l", + linebreak="id", + unicodeslot=0x306B, + }, + [0x306C]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER NU", + direction="l", + linebreak="id", + unicodeslot=0x306C, + }, + [0x306D]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER NE", + direction="l", + linebreak="id", + unicodeslot=0x306D, + }, + [0x306E]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER NO", + direction="l", + linebreak="id", + unicodeslot=0x306E, + }, + [0x306F]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER HA", + direction="l", + linebreak="id", + unicodeslot=0x306F, + }, + [0x3070]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER BA", + direction="l", + linebreak="id", + specials={ "char", 0x306F, 0x3099 }, + unicodeslot=0x3070, + }, + [0x3071]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER PA", + direction="l", + linebreak="id", + specials={ "char", 0x306F, 0x309A }, + unicodeslot=0x3071, + }, + [0x3072]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER HI", + direction="l", + linebreak="id", + unicodeslot=0x3072, + }, + [0x3073]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER BI", + direction="l", + linebreak="id", + specials={ "char", 0x3072, 0x3099 }, + unicodeslot=0x3073, + }, + [0x3074]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER PI", + direction="l", + linebreak="id", + specials={ "char", 0x3072, 0x309A }, + unicodeslot=0x3074, + }, + [0x3075]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER HU", + direction="l", + linebreak="id", + unicodeslot=0x3075, + }, + [0x3076]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER BU", + direction="l", + linebreak="id", + specials={ "char", 0x3075, 0x3099 }, + unicodeslot=0x3076, + }, + [0x3077]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER PU", + direction="l", + linebreak="id", + specials={ "char", 0x3075, 0x309A }, + unicodeslot=0x3077, + }, + [0x3078]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER HE", + direction="l", + linebreak="id", + unicodeslot=0x3078, + }, + [0x3079]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER BE", + direction="l", + linebreak="id", + specials={ "char", 0x3078, 0x3099 }, + unicodeslot=0x3079, + }, + [0x307A]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER PE", + direction="l", + linebreak="id", + specials={ "char", 0x3078, 0x309A }, + unicodeslot=0x307A, + }, + [0x307B]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER HO", + direction="l", + linebreak="id", + unicodeslot=0x307B, + }, + [0x307C]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER BO", + direction="l", + linebreak="id", + specials={ "char", 0x307B, 0x3099 }, + unicodeslot=0x307C, + }, + [0x307D]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER PO", + direction="l", + linebreak="id", + specials={ "char", 0x307B, 0x309A }, + unicodeslot=0x307D, + }, + [0x307E]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER MA", + direction="l", + linebreak="id", + unicodeslot=0x307E, + }, + [0x307F]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER MI", + direction="l", + linebreak="id", + unicodeslot=0x307F, + }, + [0x3080]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER MU", + direction="l", + linebreak="id", + unicodeslot=0x3080, + }, + [0x3081]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER ME", + direction="l", + linebreak="id", + unicodeslot=0x3081, + }, + [0x3082]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER MO", + direction="l", + linebreak="id", + unicodeslot=0x3082, + }, + [0x3083]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER SMALL YA", + direction="l", + linebreak="ns", + unicodeslot=0x3083, + }, + [0x3084]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER YA", + direction="l", + linebreak="id", + unicodeslot=0x3084, + }, + [0x3085]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER SMALL YU", + direction="l", + linebreak="ns", + unicodeslot=0x3085, + }, + [0x3086]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER YU", + direction="l", + linebreak="id", + unicodeslot=0x3086, + }, + [0x3087]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER SMALL YO", + direction="l", + linebreak="ns", + unicodeslot=0x3087, + }, + [0x3088]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER YO", + direction="l", + linebreak="id", + unicodeslot=0x3088, + }, + [0x3089]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER RA", + direction="l", + linebreak="id", + unicodeslot=0x3089, + }, + [0x308A]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER RI", + direction="l", + linebreak="id", + unicodeslot=0x308A, + }, + [0x308B]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER RU", + direction="l", + linebreak="id", + unicodeslot=0x308B, + }, + [0x308C]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER RE", + direction="l", + linebreak="id", + unicodeslot=0x308C, + }, + [0x308D]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER RO", + direction="l", + linebreak="id", + unicodeslot=0x308D, + }, + [0x308E]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER SMALL WA", + direction="l", + linebreak="ns", + unicodeslot=0x308E, + }, + [0x308F]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER WA", + direction="l", + linebreak="id", + unicodeslot=0x308F, + }, + [0x3090]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER WI", + direction="l", + linebreak="id", + unicodeslot=0x3090, + }, + [0x3091]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER WE", + direction="l", + linebreak="id", + unicodeslot=0x3091, + }, + [0x3092]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER WO", + direction="l", + linebreak="id", + unicodeslot=0x3092, + }, + [0x3093]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER N", + direction="l", + linebreak="id", + unicodeslot=0x3093, + }, + [0x3094]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER VU", + direction="l", + linebreak="id", + specials={ "char", 0x3046, 0x3099 }, + unicodeslot=0x3094, + }, + [0x3095]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER SMALL KA", + direction="l", + linebreak="ns", + unicodeslot=0x3095, + }, + [0x3096]={ + category="lo", + cjkwd="w", + description="HIRAGANA LETTER SMALL KE", + direction="l", + linebreak="ns", + unicodeslot=0x3096, + }, + [0x3099]={ + category="mn", + cjkwd="w", + description="COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK", + direction="nsm", + linebreak="cm", + unicodeslot=0x3099, + }, + [0x309A]={ + category="mn", + cjkwd="w", + description="COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK", + direction="nsm", + linebreak="cm", + unicodeslot=0x309A, + }, + [0x309B]={ + category="sk", + cjkwd="w", + description="KATAKANA-HIRAGANA VOICED SOUND MARK", + direction="on", + linebreak="ns", + specials={ "compat", 0x0020, 0x3099 }, + unicodeslot=0x309B, + }, + [0x309C]={ + category="sk", + cjkwd="w", + description="KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK", + direction="on", + linebreak="ns", + specials={ "compat", 0x0020, 0x309A }, + unicodeslot=0x309C, + }, + [0x309D]={ + category="lm", + cjkwd="w", + description="HIRAGANA ITERATION MARK", + direction="l", + linebreak="ns", + unicodeslot=0x309D, + }, + [0x309E]={ + category="lm", + cjkwd="w", + description="HIRAGANA VOICED ITERATION MARK", + direction="l", + linebreak="ns", + specials={ "char", 0x309D, 0x3099 }, + unicodeslot=0x309E, + }, + [0x309F]={ + category="lo", + cjkwd="w", + description="HIRAGANA DIGRAPH YORI", + direction="l", + linebreak="id", + specials={ "vertical", 0x3088, 0x308A }, + unicodeslot=0x309F, + }, + [0x30A0]={ + category="pd", + cjkwd="w", + description="KATAKANA-HIRAGANA DOUBLE HYPHEN", + direction="on", + linebreak="ns", + unicodeslot=0x30A0, + }, + [0x30A1]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL A", + direction="l", + linebreak="ns", + unicodeslot=0x30A1, + }, + [0x30A2]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER A", + direction="l", + linebreak="id", + unicodeslot=0x30A2, + }, + [0x30A3]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL I", + direction="l", + linebreak="ns", + unicodeslot=0x30A3, + }, + [0x30A4]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER I", + direction="l", + linebreak="id", + unicodeslot=0x30A4, + }, + [0x30A5]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL U", + direction="l", + linebreak="ns", + unicodeslot=0x30A5, + }, + [0x30A6]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER U", + direction="l", + linebreak="id", + unicodeslot=0x30A6, + }, + [0x30A7]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL E", + direction="l", + linebreak="ns", + unicodeslot=0x30A7, + }, + [0x30A8]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER E", + direction="l", + linebreak="id", + unicodeslot=0x30A8, + }, + [0x30A9]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL O", + direction="l", + linebreak="ns", + unicodeslot=0x30A9, + }, + [0x30AA]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER O", + direction="l", + linebreak="id", + unicodeslot=0x30AA, + }, + [0x30AB]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER KA", + direction="l", + linebreak="id", + unicodeslot=0x30AB, + }, + [0x30AC]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER GA", + direction="l", + linebreak="id", + specials={ "char", 0x30AB, 0x3099 }, + unicodeslot=0x30AC, + }, + [0x30AD]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER KI", + direction="l", + linebreak="id", + unicodeslot=0x30AD, + }, + [0x30AE]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER GI", + direction="l", + linebreak="id", + specials={ "char", 0x30AD, 0x3099 }, + unicodeslot=0x30AE, + }, + [0x30AF]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER KU", + direction="l", + linebreak="id", + unicodeslot=0x30AF, + }, + [0x30B0]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER GU", + direction="l", + linebreak="id", + specials={ "char", 0x30AF, 0x3099 }, + unicodeslot=0x30B0, + }, + [0x30B1]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER KE", + direction="l", + linebreak="id", + unicodeslot=0x30B1, + }, + [0x30B2]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER GE", + direction="l", + linebreak="id", + specials={ "char", 0x30B1, 0x3099 }, + unicodeslot=0x30B2, + }, + [0x30B3]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER KO", + direction="l", + linebreak="id", + unicodeslot=0x30B3, + }, + [0x30B4]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER GO", + direction="l", + linebreak="id", + specials={ "char", 0x30B3, 0x3099 }, + unicodeslot=0x30B4, + }, + [0x30B5]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SA", + direction="l", + linebreak="id", + unicodeslot=0x30B5, + }, + [0x30B6]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER ZA", + direction="l", + linebreak="id", + specials={ "char", 0x30B5, 0x3099 }, + unicodeslot=0x30B6, + }, + [0x30B7]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SI", + direction="l", + linebreak="id", + unicodeslot=0x30B7, + }, + [0x30B8]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER ZI", + direction="l", + linebreak="id", + specials={ "char", 0x30B7, 0x3099 }, + unicodeslot=0x30B8, + }, + [0x30B9]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SU", + direction="l", + linebreak="id", + unicodeslot=0x30B9, + }, + [0x30BA]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER ZU", + direction="l", + linebreak="id", + specials={ "char", 0x30B9, 0x3099 }, + unicodeslot=0x30BA, + }, + [0x30BB]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SE", + direction="l", + linebreak="id", + unicodeslot=0x30BB, + }, + [0x30BC]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER ZE", + direction="l", + linebreak="id", + specials={ "char", 0x30BB, 0x3099 }, + unicodeslot=0x30BC, + }, + [0x30BD]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SO", + direction="l", + linebreak="id", + unicodeslot=0x30BD, + }, + [0x30BE]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER ZO", + direction="l", + linebreak="id", + specials={ "char", 0x30BD, 0x3099 }, + unicodeslot=0x30BE, + }, + [0x30BF]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER TA", + direction="l", + linebreak="id", + unicodeslot=0x30BF, + }, + [0x30C0]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER DA", + direction="l", + linebreak="id", + specials={ "char", 0x30BF, 0x3099 }, + unicodeslot=0x30C0, + }, + [0x30C1]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER TI", + direction="l", + linebreak="id", + unicodeslot=0x30C1, + }, + [0x30C2]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER DI", + direction="l", + linebreak="id", + specials={ "char", 0x30C1, 0x3099 }, + unicodeslot=0x30C2, + }, + [0x30C3]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL TU", + direction="l", + linebreak="ns", + unicodeslot=0x30C3, + }, + [0x30C4]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER TU", + direction="l", + linebreak="id", + unicodeslot=0x30C4, + }, + [0x30C5]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER DU", + direction="l", + linebreak="id", + specials={ "char", 0x30C4, 0x3099 }, + unicodeslot=0x30C5, + }, + [0x30C6]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER TE", + direction="l", + linebreak="id", + unicodeslot=0x30C6, + }, + [0x30C7]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER DE", + direction="l", + linebreak="id", + specials={ "char", 0x30C6, 0x3099 }, + unicodeslot=0x30C7, + }, + [0x30C8]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER TO", + direction="l", + linebreak="id", + unicodeslot=0x30C8, + }, + [0x30C9]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER DO", + direction="l", + linebreak="id", + specials={ "char", 0x30C8, 0x3099 }, + unicodeslot=0x30C9, + }, + [0x30CA]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER NA", + direction="l", + linebreak="id", + unicodeslot=0x30CA, + }, + [0x30CB]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER NI", + direction="l", + linebreak="id", + unicodeslot=0x30CB, + }, + [0x30CC]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER NU", + direction="l", + linebreak="id", + unicodeslot=0x30CC, + }, + [0x30CD]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER NE", + direction="l", + linebreak="id", + unicodeslot=0x30CD, + }, + [0x30CE]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER NO", + direction="l", + linebreak="id", + unicodeslot=0x30CE, + }, + [0x30CF]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER HA", + direction="l", + linebreak="id", + unicodeslot=0x30CF, + }, + [0x30D0]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER BA", + direction="l", + linebreak="id", + specials={ "char", 0x30CF, 0x3099 }, + unicodeslot=0x30D0, + }, + [0x30D1]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER PA", + direction="l", + linebreak="id", + specials={ "char", 0x30CF, 0x309A }, + unicodeslot=0x30D1, + }, + [0x30D2]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER HI", + direction="l", + linebreak="id", + unicodeslot=0x30D2, + }, + [0x30D3]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER BI", + direction="l", + linebreak="id", + specials={ "char", 0x30D2, 0x3099 }, + unicodeslot=0x30D3, + }, + [0x30D4]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER PI", + direction="l", + linebreak="id", + specials={ "char", 0x30D2, 0x309A }, + unicodeslot=0x30D4, + }, + [0x30D5]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER HU", + direction="l", + linebreak="id", + unicodeslot=0x30D5, + }, + [0x30D6]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER BU", + direction="l", + linebreak="id", + specials={ "char", 0x30D5, 0x3099 }, + unicodeslot=0x30D6, + }, + [0x30D7]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER PU", + direction="l", + linebreak="id", + specials={ "char", 0x30D5, 0x309A }, + unicodeslot=0x30D7, + }, + [0x30D8]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER HE", + direction="l", + linebreak="id", + unicodeslot=0x30D8, + }, + [0x30D9]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER BE", + direction="l", + linebreak="id", + specials={ "char", 0x30D8, 0x3099 }, + unicodeslot=0x30D9, + }, + [0x30DA]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER PE", + direction="l", + linebreak="id", + specials={ "char", 0x30D8, 0x309A }, + unicodeslot=0x30DA, + }, + [0x30DB]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER HO", + direction="l", + linebreak="id", + unicodeslot=0x30DB, + }, + [0x30DC]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER BO", + direction="l", + linebreak="id", + specials={ "char", 0x30DB, 0x3099 }, + unicodeslot=0x30DC, + }, + [0x30DD]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER PO", + direction="l", + linebreak="id", + specials={ "char", 0x30DB, 0x309A }, + unicodeslot=0x30DD, + }, + [0x30DE]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER MA", + direction="l", + linebreak="id", + unicodeslot=0x30DE, + }, + [0x30DF]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER MI", + direction="l", + linebreak="id", + unicodeslot=0x30DF, + }, + [0x30E0]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER MU", + direction="l", + linebreak="id", + unicodeslot=0x30E0, + }, + [0x30E1]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER ME", + direction="l", + linebreak="id", + unicodeslot=0x30E1, + }, + [0x30E2]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER MO", + direction="l", + linebreak="id", + unicodeslot=0x30E2, + }, + [0x30E3]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL YA", + direction="l", + linebreak="ns", + unicodeslot=0x30E3, + }, + [0x30E4]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER YA", + direction="l", + linebreak="id", + unicodeslot=0x30E4, + }, + [0x30E5]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL YU", + direction="l", + linebreak="ns", + unicodeslot=0x30E5, + }, + [0x30E6]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER YU", + direction="l", + linebreak="id", + unicodeslot=0x30E6, + }, + [0x30E7]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL YO", + direction="l", + linebreak="ns", + unicodeslot=0x30E7, + }, + [0x30E8]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER YO", + direction="l", + linebreak="id", + unicodeslot=0x30E8, + }, + [0x30E9]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER RA", + direction="l", + linebreak="id", + unicodeslot=0x30E9, + }, + [0x30EA]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER RI", + direction="l", + linebreak="id", + unicodeslot=0x30EA, + }, + [0x30EB]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER RU", + direction="l", + linebreak="id", + unicodeslot=0x30EB, + }, + [0x30EC]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER RE", + direction="l", + linebreak="id", + unicodeslot=0x30EC, + }, + [0x30ED]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER RO", + direction="l", + linebreak="id", + unicodeslot=0x30ED, + }, + [0x30EE]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL WA", + direction="l", + linebreak="ns", + unicodeslot=0x30EE, + }, + [0x30EF]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER WA", + direction="l", + linebreak="id", + unicodeslot=0x30EF, + }, + [0x30F0]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER WI", + direction="l", + linebreak="id", + unicodeslot=0x30F0, + }, + [0x30F1]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER WE", + direction="l", + linebreak="id", + unicodeslot=0x30F1, + }, + [0x30F2]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER WO", + direction="l", + linebreak="id", + unicodeslot=0x30F2, + }, + [0x30F3]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER N", + direction="l", + linebreak="id", + unicodeslot=0x30F3, + }, + [0x30F4]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER VU", + direction="l", + linebreak="id", + specials={ "char", 0x30A6, 0x3099 }, + unicodeslot=0x30F4, + }, + [0x30F5]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL KA", + direction="l", + linebreak="ns", + unicodeslot=0x30F5, + }, + [0x30F6]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL KE", + direction="l", + linebreak="ns", + unicodeslot=0x30F6, + }, + [0x30F7]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER VA", + direction="l", + linebreak="id", + specials={ "char", 0x30EF, 0x3099 }, + unicodeslot=0x30F7, + }, + [0x30F8]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER VI", + direction="l", + linebreak="id", + specials={ "char", 0x30F0, 0x3099 }, + unicodeslot=0x30F8, + }, + [0x30F9]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER VE", + direction="l", + linebreak="id", + specials={ "char", 0x30F1, 0x3099 }, + unicodeslot=0x30F9, + }, + [0x30FA]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER VO", + direction="l", + linebreak="id", + specials={ "char", 0x30F2, 0x3099 }, + unicodeslot=0x30FA, + }, + [0x30FB]={ + category="po", + cjkwd="w", + description="KATAKANA MIDDLE DOT", + direction="on", + linebreak="ns", + unicodeslot=0x30FB, + }, + [0x30FC]={ + category="lm", + cjkwd="w", + description="KATAKANA-HIRAGANA PROLONGED SOUND MARK", + direction="l", + linebreak="ns", + unicodeslot=0x30FC, + }, + [0x30FD]={ + category="lm", + cjkwd="w", + description="KATAKANA ITERATION MARK", + direction="l", + linebreak="ns", + unicodeslot=0x30FD, + }, + [0x30FE]={ + category="lm", + cjkwd="w", + description="KATAKANA VOICED ITERATION MARK", + direction="l", + linebreak="ns", + specials={ "char", 0x30FD, 0x3099 }, + unicodeslot=0x30FE, + }, + [0x30FF]={ + category="lo", + cjkwd="w", + description="KATAKANA DIGRAPH KOTO", + direction="l", + linebreak="id", + specials={ "vertical", 0x30B3, 0x30C8 }, + unicodeslot=0x30FF, + }, + [0x3105]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER B", + direction="l", + linebreak="id", + unicodeslot=0x3105, + }, + [0x3106]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER P", + direction="l", + linebreak="id", + unicodeslot=0x3106, + }, + [0x3107]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER M", + direction="l", + linebreak="id", + unicodeslot=0x3107, + }, + [0x3108]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER F", + direction="l", + linebreak="id", + unicodeslot=0x3108, + }, + [0x3109]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER D", + direction="l", + linebreak="id", + unicodeslot=0x3109, + }, + [0x310A]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER T", + direction="l", + linebreak="id", + unicodeslot=0x310A, + }, + [0x310B]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER N", + direction="l", + linebreak="id", + unicodeslot=0x310B, + }, + [0x310C]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER L", + direction="l", + linebreak="id", + unicodeslot=0x310C, + }, + [0x310D]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER G", + direction="l", + linebreak="id", + unicodeslot=0x310D, + }, + [0x310E]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER K", + direction="l", + linebreak="id", + unicodeslot=0x310E, + }, + [0x310F]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER H", + direction="l", + linebreak="id", + unicodeslot=0x310F, + }, + [0x3110]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER J", + direction="l", + linebreak="id", + unicodeslot=0x3110, + }, + [0x3111]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER Q", + direction="l", + linebreak="id", + unicodeslot=0x3111, + }, + [0x3112]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER X", + direction="l", + linebreak="id", + unicodeslot=0x3112, + }, + [0x3113]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER ZH", + direction="l", + linebreak="id", + unicodeslot=0x3113, + }, + [0x3114]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER CH", + direction="l", + linebreak="id", + unicodeslot=0x3114, + }, + [0x3115]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER SH", + direction="l", + linebreak="id", + unicodeslot=0x3115, + }, + [0x3116]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER R", + direction="l", + linebreak="id", + unicodeslot=0x3116, + }, + [0x3117]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER Z", + direction="l", + linebreak="id", + unicodeslot=0x3117, + }, + [0x3118]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER C", + direction="l", + linebreak="id", + unicodeslot=0x3118, + }, + [0x3119]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER S", + direction="l", + linebreak="id", + unicodeslot=0x3119, + }, + [0x311A]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER A", + direction="l", + linebreak="id", + unicodeslot=0x311A, + }, + [0x311B]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER O", + direction="l", + linebreak="id", + unicodeslot=0x311B, + }, + [0x311C]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER E", + direction="l", + linebreak="id", + unicodeslot=0x311C, + }, + [0x311D]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER EH", + direction="l", + linebreak="id", + unicodeslot=0x311D, + }, + [0x311E]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER AI", + direction="l", + linebreak="id", + unicodeslot=0x311E, + }, + [0x311F]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER EI", + direction="l", + linebreak="id", + unicodeslot=0x311F, + }, + [0x3120]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER AU", + direction="l", + linebreak="id", + unicodeslot=0x3120, + }, + [0x3121]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER OU", + direction="l", + linebreak="id", + unicodeslot=0x3121, + }, + [0x3122]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER AN", + direction="l", + linebreak="id", + unicodeslot=0x3122, + }, + [0x3123]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER EN", + direction="l", + linebreak="id", + unicodeslot=0x3123, + }, + [0x3124]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER ANG", + direction="l", + linebreak="id", + unicodeslot=0x3124, + }, + [0x3125]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER ENG", + direction="l", + linebreak="id", + unicodeslot=0x3125, + }, + [0x3126]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER ER", + direction="l", + linebreak="id", + unicodeslot=0x3126, + }, + [0x3127]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER I", + direction="l", + linebreak="id", + unicodeslot=0x3127, + }, + [0x3128]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER U", + direction="l", + linebreak="id", + unicodeslot=0x3128, + }, + [0x3129]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER IU", + direction="l", + linebreak="id", + unicodeslot=0x3129, + }, + [0x312A]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER V", + direction="l", + linebreak="id", + unicodeslot=0x312A, + }, + [0x312B]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER NG", + direction="l", + linebreak="id", + unicodeslot=0x312B, + }, + [0x312C]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER GN", + direction="l", + linebreak="id", + unicodeslot=0x312C, + }, + [0x3131]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER KIYEOK", + direction="l", + linebreak="id", + specials={ "compat", 0x1100 }, + unicodeslot=0x3131, + }, + [0x3132]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER SSANGKIYEOK", + direction="l", + linebreak="id", + specials={ "compat", 0x1101 }, + unicodeslot=0x3132, + }, + [0x3133]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER KIYEOK-SIOS", + direction="l", + linebreak="id", + specials={ "compat", 0x11AA }, + unicodeslot=0x3133, + }, + [0x3134]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER NIEUN", + direction="l", + linebreak="id", + specials={ "compat", 0x1102 }, + unicodeslot=0x3134, + }, + [0x3135]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER NIEUN-CIEUC", + direction="l", + linebreak="id", + specials={ "compat", 0x11AC }, + unicodeslot=0x3135, + }, + [0x3136]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER NIEUN-HIEUH", + direction="l", + linebreak="id", + specials={ "compat", 0x11AD }, + unicodeslot=0x3136, + }, + [0x3137]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER TIKEUT", + direction="l", + linebreak="id", + specials={ "compat", 0x1103 }, + unicodeslot=0x3137, + }, + [0x3138]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER SSANGTIKEUT", + direction="l", + linebreak="id", + specials={ "compat", 0x1104 }, + unicodeslot=0x3138, + }, + [0x3139]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER RIEUL", + direction="l", + linebreak="id", + specials={ "compat", 0x1105 }, + unicodeslot=0x3139, + }, + [0x313A]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER RIEUL-KIYEOK", + direction="l", + linebreak="id", + specials={ "compat", 0x11B0 }, + unicodeslot=0x313A, + }, + [0x313B]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER RIEUL-MIEUM", + direction="l", + linebreak="id", + specials={ "compat", 0x11B1 }, + unicodeslot=0x313B, + }, + [0x313C]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER RIEUL-PIEUP", + direction="l", + linebreak="id", + specials={ "compat", 0x11B2 }, + unicodeslot=0x313C, + }, + [0x313D]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER RIEUL-SIOS", + direction="l", + linebreak="id", + specials={ "compat", 0x11B3 }, + unicodeslot=0x313D, + }, + [0x313E]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER RIEUL-THIEUTH", + direction="l", + linebreak="id", + specials={ "compat", 0x11B4 }, + unicodeslot=0x313E, + }, + [0x313F]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER RIEUL-PHIEUPH", + direction="l", + linebreak="id", + specials={ "compat", 0x11B5 }, + unicodeslot=0x313F, + }, + [0x3140]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER RIEUL-HIEUH", + direction="l", + linebreak="id", + specials={ "compat", 0x111A }, + unicodeslot=0x3140, + }, + [0x3141]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER MIEUM", + direction="l", + linebreak="id", + specials={ "compat", 0x1106 }, + unicodeslot=0x3141, + }, + [0x3142]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER PIEUP", + direction="l", + linebreak="id", + specials={ "compat", 0x1107 }, + unicodeslot=0x3142, + }, + [0x3143]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER SSANGPIEUP", + direction="l", + linebreak="id", + specials={ "compat", 0x1108 }, + unicodeslot=0x3143, + }, + [0x3144]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER PIEUP-SIOS", + direction="l", + linebreak="id", + specials={ "compat", 0x1121 }, + unicodeslot=0x3144, + }, + [0x3145]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER SIOS", + direction="l", + linebreak="id", + specials={ "compat", 0x1109 }, + unicodeslot=0x3145, + }, + [0x3146]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER SSANGSIOS", + direction="l", + linebreak="id", + specials={ "compat", 0x110A }, + unicodeslot=0x3146, + }, + [0x3147]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER IEUNG", + direction="l", + linebreak="id", + specials={ "compat", 0x110B }, + unicodeslot=0x3147, + }, + [0x3148]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER CIEUC", + direction="l", + linebreak="id", + specials={ "compat", 0x110C }, + unicodeslot=0x3148, + }, + [0x3149]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER SSANGCIEUC", + direction="l", + linebreak="id", + specials={ "compat", 0x110D }, + unicodeslot=0x3149, + }, + [0x314A]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER CHIEUCH", + direction="l", + linebreak="id", + specials={ "compat", 0x110E }, + unicodeslot=0x314A, + }, + [0x314B]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER KHIEUKH", + direction="l", + linebreak="id", + specials={ "compat", 0x110F }, + unicodeslot=0x314B, + }, + [0x314C]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER THIEUTH", + direction="l", + linebreak="id", + specials={ "compat", 0x1110 }, + unicodeslot=0x314C, + }, + [0x314D]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER PHIEUPH", + direction="l", + linebreak="id", + specials={ "compat", 0x1111 }, + unicodeslot=0x314D, + }, + [0x314E]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER HIEUH", + direction="l", + linebreak="id", + specials={ "compat", 0x1112 }, + unicodeslot=0x314E, + }, + [0x314F]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER A", + direction="l", + linebreak="id", + specials={ "compat", 0x1161 }, + unicodeslot=0x314F, + }, + [0x3150]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER AE", + direction="l", + linebreak="id", + specials={ "compat", 0x1162 }, + unicodeslot=0x3150, + }, + [0x3151]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER YA", + direction="l", + linebreak="id", + specials={ "compat", 0x1163 }, + unicodeslot=0x3151, + }, + [0x3152]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER YAE", + direction="l", + linebreak="id", + specials={ "compat", 0x1164 }, + unicodeslot=0x3152, + }, + [0x3153]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER EO", + direction="l", + linebreak="id", + specials={ "compat", 0x1165 }, + unicodeslot=0x3153, + }, + [0x3154]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER E", + direction="l", + linebreak="id", + specials={ "compat", 0x1166 }, + unicodeslot=0x3154, + }, + [0x3155]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER YEO", + direction="l", + linebreak="id", + specials={ "compat", 0x1167 }, + unicodeslot=0x3155, + }, + [0x3156]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER YE", + direction="l", + linebreak="id", + specials={ "compat", 0x1168 }, + unicodeslot=0x3156, + }, + [0x3157]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER O", + direction="l", + linebreak="id", + specials={ "compat", 0x1169 }, + unicodeslot=0x3157, + }, + [0x3158]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER WA", + direction="l", + linebreak="id", + specials={ "compat", 0x116A }, + unicodeslot=0x3158, + }, + [0x3159]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER WAE", + direction="l", + linebreak="id", + specials={ "compat", 0x116B }, + unicodeslot=0x3159, + }, + [0x315A]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER OE", + direction="l", + linebreak="id", + specials={ "compat", 0x116C }, + unicodeslot=0x315A, + }, + [0x315B]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER YO", + direction="l", + linebreak="id", + specials={ "compat", 0x116D }, + unicodeslot=0x315B, + }, + [0x315C]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER U", + direction="l", + linebreak="id", + specials={ "compat", 0x116E }, + unicodeslot=0x315C, + }, + [0x315D]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER WEO", + direction="l", + linebreak="id", + specials={ "compat", 0x116F }, + unicodeslot=0x315D, + }, + [0x315E]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER WE", + direction="l", + linebreak="id", + specials={ "compat", 0x1170 }, + unicodeslot=0x315E, + }, + [0x315F]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER WI", + direction="l", + linebreak="id", + specials={ "compat", 0x1171 }, + unicodeslot=0x315F, + }, + [0x3160]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER YU", + direction="l", + linebreak="id", + specials={ "compat", 0x1172 }, + unicodeslot=0x3160, + }, + [0x3161]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER EU", + direction="l", + linebreak="id", + specials={ "compat", 0x1173 }, + unicodeslot=0x3161, + }, + [0x3162]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER YI", + direction="l", + linebreak="id", + specials={ "compat", 0x1174 }, + unicodeslot=0x3162, + }, + [0x3163]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER I", + direction="l", + linebreak="id", + specials={ "compat", 0x1175 }, + unicodeslot=0x3163, + }, + [0x3164]={ + category="lo", + cjkwd="w", + description="HANGUL FILLER", + direction="l", + linebreak="id", + specials={ "compat", 0x1160 }, + unicodeslot=0x3164, + }, + [0x3165]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER SSANGNIEUN", + direction="l", + linebreak="id", + specials={ "compat", 0x1114 }, + unicodeslot=0x3165, + }, + [0x3166]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER NIEUN-TIKEUT", + direction="l", + linebreak="id", + specials={ "compat", 0x1115 }, + unicodeslot=0x3166, + }, + [0x3167]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER NIEUN-SIOS", + direction="l", + linebreak="id", + specials={ "compat", 0x11C7 }, + unicodeslot=0x3167, + }, + [0x3168]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER NIEUN-PANSIOS", + direction="l", + linebreak="id", + specials={ "compat", 0x11C8 }, + unicodeslot=0x3168, + }, + [0x3169]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER RIEUL-KIYEOK-SIOS", + direction="l", + linebreak="id", + specials={ "compat", 0x11CC }, + unicodeslot=0x3169, + }, + [0x316A]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER RIEUL-TIKEUT", + direction="l", + linebreak="id", + specials={ "compat", 0x11CE }, + unicodeslot=0x316A, + }, + [0x316B]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER RIEUL-PIEUP-SIOS", + direction="l", + linebreak="id", + specials={ "compat", 0x11D3 }, + unicodeslot=0x316B, + }, + [0x316C]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER RIEUL-PANSIOS", + direction="l", + linebreak="id", + specials={ "compat", 0x11D7 }, + unicodeslot=0x316C, + }, + [0x316D]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER RIEUL-YEORINHIEUH", + direction="l", + linebreak="id", + specials={ "compat", 0x11D9 }, + unicodeslot=0x316D, + }, + [0x316E]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER MIEUM-PIEUP", + direction="l", + linebreak="id", + specials={ "compat", 0x111C }, + unicodeslot=0x316E, + }, + [0x316F]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER MIEUM-SIOS", + direction="l", + linebreak="id", + specials={ "compat", 0x11DD }, + unicodeslot=0x316F, + }, + [0x3170]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER MIEUM-PANSIOS", + direction="l", + linebreak="id", + specials={ "compat", 0x11DF }, + unicodeslot=0x3170, + }, + [0x3171]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER KAPYEOUNMIEUM", + direction="l", + linebreak="id", + specials={ "compat", 0x111D }, + unicodeslot=0x3171, + }, + [0x3172]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER PIEUP-KIYEOK", + direction="l", + linebreak="id", + specials={ "compat", 0x111E }, + unicodeslot=0x3172, + }, + [0x3173]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER PIEUP-TIKEUT", + direction="l", + linebreak="id", + specials={ "compat", 0x1120 }, + unicodeslot=0x3173, + }, + [0x3174]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER PIEUP-SIOS-KIYEOK", + direction="l", + linebreak="id", + specials={ "compat", 0x1122 }, + unicodeslot=0x3174, + }, + [0x3175]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER PIEUP-SIOS-TIKEUT", + direction="l", + linebreak="id", + specials={ "compat", 0x1123 }, + unicodeslot=0x3175, + }, + [0x3176]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER PIEUP-CIEUC", + direction="l", + linebreak="id", + specials={ "compat", 0x1127 }, + unicodeslot=0x3176, + }, + [0x3177]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER PIEUP-THIEUTH", + direction="l", + linebreak="id", + specials={ "compat", 0x1129 }, + unicodeslot=0x3177, + }, + [0x3178]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER KAPYEOUNPIEUP", + direction="l", + linebreak="id", + specials={ "compat", 0x112B }, + unicodeslot=0x3178, + }, + [0x3179]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER KAPYEOUNSSANGPIEUP", + direction="l", + linebreak="id", + specials={ "compat", 0x112C }, + unicodeslot=0x3179, + }, + [0x317A]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER SIOS-KIYEOK", + direction="l", + linebreak="id", + specials={ "compat", 0x112D }, + unicodeslot=0x317A, + }, + [0x317B]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER SIOS-NIEUN", + direction="l", + linebreak="id", + specials={ "compat", 0x112E }, + unicodeslot=0x317B, + }, + [0x317C]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER SIOS-TIKEUT", + direction="l", + linebreak="id", + specials={ "compat", 0x112F }, + unicodeslot=0x317C, + }, + [0x317D]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER SIOS-PIEUP", + direction="l", + linebreak="id", + specials={ "compat", 0x1132 }, + unicodeslot=0x317D, + }, + [0x317E]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER SIOS-CIEUC", + direction="l", + linebreak="id", + specials={ "compat", 0x1136 }, + unicodeslot=0x317E, + }, + [0x317F]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER PANSIOS", + direction="l", + linebreak="id", + specials={ "compat", 0x1140 }, + unicodeslot=0x317F, + }, + [0x3180]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER SSANGIEUNG", + direction="l", + linebreak="id", + specials={ "compat", 0x1147 }, + unicodeslot=0x3180, + }, + [0x3181]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER YESIEUNG", + direction="l", + linebreak="id", + specials={ "compat", 0x114C }, + unicodeslot=0x3181, + }, + [0x3182]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER YESIEUNG-SIOS", + direction="l", + linebreak="id", + specials={ "compat", 0x11F1 }, + unicodeslot=0x3182, + }, + [0x3183]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER YESIEUNG-PANSIOS", + direction="l", + linebreak="id", + specials={ "compat", 0x11F2 }, + unicodeslot=0x3183, + }, + [0x3184]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER KAPYEOUNPHIEUPH", + direction="l", + linebreak="id", + specials={ "compat", 0x1157 }, + unicodeslot=0x3184, + }, + [0x3185]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER SSANGHIEUH", + direction="l", + linebreak="id", + specials={ "compat", 0x1158 }, + unicodeslot=0x3185, + }, + [0x3186]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER YEORINHIEUH", + direction="l", + linebreak="id", + specials={ "compat", 0x1159 }, + unicodeslot=0x3186, + }, + [0x3187]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER YO-YA", + direction="l", + linebreak="id", + specials={ "compat", 0x1184 }, + unicodeslot=0x3187, + }, + [0x3188]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER YO-YAE", + direction="l", + linebreak="id", + specials={ "compat", 0x1185 }, + unicodeslot=0x3188, + }, + [0x3189]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER YO-I", + direction="l", + linebreak="id", + specials={ "compat", 0x1188 }, + unicodeslot=0x3189, + }, + [0x318A]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER YU-YEO", + direction="l", + linebreak="id", + specials={ "compat", 0x1191 }, + unicodeslot=0x318A, + }, + [0x318B]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER YU-YE", + direction="l", + linebreak="id", + specials={ "compat", 0x1192 }, + unicodeslot=0x318B, + }, + [0x318C]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER YU-I", + direction="l", + linebreak="id", + specials={ "compat", 0x1194 }, + unicodeslot=0x318C, + }, + [0x318D]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER ARAEA", + direction="l", + linebreak="id", + specials={ "compat", 0x119E }, + unicodeslot=0x318D, + }, + [0x318E]={ + category="lo", + cjkwd="w", + description="HANGUL LETTER ARAEAE", + direction="l", + linebreak="id", + specials={ "compat", 0x11A1 }, + unicodeslot=0x318E, + }, + [0x3190]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC ANNOTATION LINKING MARK", + direction="l", + linebreak="id", + unicodeslot=0x3190, + }, + [0x3191]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC ANNOTATION REVERSE MARK", + direction="l", + linebreak="id", + unicodeslot=0x3191, + }, + [0x3192]={ + category="no", + cjkwd="w", + description="IDEOGRAPHIC ANNOTATION ONE MARK", + direction="l", + linebreak="id", + specials={ "super", 0x4E00 }, + unicodeslot=0x3192, + }, + [0x3193]={ + category="no", + cjkwd="w", + description="IDEOGRAPHIC ANNOTATION TWO MARK", + direction="l", + linebreak="id", + specials={ "super", 0x4E8C }, + unicodeslot=0x3193, + }, + [0x3194]={ + category="no", + cjkwd="w", + description="IDEOGRAPHIC ANNOTATION THREE MARK", + direction="l", + linebreak="id", + specials={ "super", 0x4E09 }, + unicodeslot=0x3194, + }, + [0x3195]={ + category="no", + cjkwd="w", + description="IDEOGRAPHIC ANNOTATION FOUR MARK", + direction="l", + linebreak="id", + specials={ "super", 0x56DB }, + unicodeslot=0x3195, + }, + [0x3196]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC ANNOTATION TOP MARK", + direction="l", + linebreak="id", + specials={ "super", 0x4E0A }, + unicodeslot=0x3196, + }, + [0x3197]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC ANNOTATION MIDDLE MARK", + direction="l", + linebreak="id", + specials={ "super", 0x4E2D }, + unicodeslot=0x3197, + }, + [0x3198]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC ANNOTATION BOTTOM MARK", + direction="l", + linebreak="id", + specials={ "super", 0x4E0B }, + unicodeslot=0x3198, + }, + [0x3199]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC ANNOTATION FIRST MARK", + direction="l", + linebreak="id", + specials={ "super", 0x7532 }, + unicodeslot=0x3199, + }, + [0x319A]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC ANNOTATION SECOND MARK", + direction="l", + linebreak="id", + specials={ "super", 0x4E59 }, + unicodeslot=0x319A, + }, + [0x319B]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC ANNOTATION THIRD MARK", + direction="l", + linebreak="id", + specials={ "super", 0x4E19 }, + unicodeslot=0x319B, + }, + [0x319C]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC ANNOTATION FOURTH MARK", + direction="l", + linebreak="id", + specials={ "super", 0x4E01 }, + unicodeslot=0x319C, + }, + [0x319D]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC ANNOTATION HEAVEN MARK", + direction="l", + linebreak="id", + specials={ "super", 0x5929 }, + unicodeslot=0x319D, + }, + [0x319E]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC ANNOTATION EARTH MARK", + direction="l", + linebreak="id", + specials={ "super", 0x5730 }, + unicodeslot=0x319E, + }, + [0x319F]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC ANNOTATION MAN MARK", + direction="l", + linebreak="id", + specials={ "super", 0x4EBA }, + unicodeslot=0x319F, + }, + [0x31A0]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER BU", + direction="l", + linebreak="id", + unicodeslot=0x31A0, + }, + [0x31A1]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER ZI", + direction="l", + linebreak="id", + unicodeslot=0x31A1, + }, + [0x31A2]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER JI", + direction="l", + linebreak="id", + unicodeslot=0x31A2, + }, + [0x31A3]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER GU", + direction="l", + linebreak="id", + unicodeslot=0x31A3, + }, + [0x31A4]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER EE", + direction="l", + linebreak="id", + unicodeslot=0x31A4, + }, + [0x31A5]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER ENN", + direction="l", + linebreak="id", + unicodeslot=0x31A5, + }, + [0x31A6]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER OO", + direction="l", + linebreak="id", + unicodeslot=0x31A6, + }, + [0x31A7]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER ONN", + direction="l", + linebreak="id", + unicodeslot=0x31A7, + }, + [0x31A8]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER IR", + direction="l", + linebreak="id", + unicodeslot=0x31A8, + }, + [0x31A9]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER ANN", + direction="l", + linebreak="id", + unicodeslot=0x31A9, + }, + [0x31AA]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER INN", + direction="l", + linebreak="id", + unicodeslot=0x31AA, + }, + [0x31AB]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER UNN", + direction="l", + linebreak="id", + unicodeslot=0x31AB, + }, + [0x31AC]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER IM", + direction="l", + linebreak="id", + unicodeslot=0x31AC, + }, + [0x31AD]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER NGG", + direction="l", + linebreak="id", + unicodeslot=0x31AD, + }, + [0x31AE]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER AINN", + direction="l", + linebreak="id", + unicodeslot=0x31AE, + }, + [0x31AF]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER AUNN", + direction="l", + linebreak="id", + unicodeslot=0x31AF, + }, + [0x31B0]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER AM", + direction="l", + linebreak="id", + unicodeslot=0x31B0, + }, + [0x31B1]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER OM", + direction="l", + linebreak="id", + unicodeslot=0x31B1, + }, + [0x31B2]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER ONG", + direction="l", + linebreak="id", + unicodeslot=0x31B2, + }, + [0x31B3]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER INNN", + direction="l", + linebreak="id", + unicodeslot=0x31B3, + }, + [0x31B4]={ + category="lo", + cjkwd="w", + description="BOPOMOFO FINAL LETTER P", + direction="l", + linebreak="id", + unicodeslot=0x31B4, + }, + [0x31B5]={ + category="lo", + cjkwd="w", + description="BOPOMOFO FINAL LETTER T", + direction="l", + linebreak="id", + unicodeslot=0x31B5, + }, + [0x31B6]={ + category="lo", + cjkwd="w", + description="BOPOMOFO FINAL LETTER K", + direction="l", + linebreak="id", + unicodeslot=0x31B6, + }, + [0x31B7]={ + category="lo", + cjkwd="w", + description="BOPOMOFO FINAL LETTER H", + direction="l", + linebreak="id", + unicodeslot=0x31B7, + }, + [0x31C0]={ + category="so", + cjkwd="w", + description="CJK STROKE T", + direction="on", + linebreak="id", + unicodeslot=0x31C0, + }, + [0x31C1]={ + category="so", + cjkwd="w", + description="CJK STROKE WG", + direction="on", + linebreak="id", + unicodeslot=0x31C1, + }, + [0x31C2]={ + category="so", + cjkwd="w", + description="CJK STROKE XG", + direction="on", + linebreak="id", + unicodeslot=0x31C2, + }, + [0x31C3]={ + category="so", + cjkwd="w", + description="CJK STROKE BXG", + direction="on", + linebreak="id", + unicodeslot=0x31C3, + }, + [0x31C4]={ + category="so", + cjkwd="w", + description="CJK STROKE SW", + direction="on", + linebreak="id", + unicodeslot=0x31C4, + }, + [0x31C5]={ + category="so", + cjkwd="w", + description="CJK STROKE HZZ", + direction="on", + linebreak="id", + unicodeslot=0x31C5, + }, + [0x31C6]={ + category="so", + cjkwd="w", + description="CJK STROKE HZG", + direction="on", + linebreak="id", + unicodeslot=0x31C6, + }, + [0x31C7]={ + category="so", + cjkwd="w", + description="CJK STROKE HP", + direction="on", + linebreak="id", + unicodeslot=0x31C7, + }, + [0x31C8]={ + category="so", + cjkwd="w", + description="CJK STROKE HZWG", + direction="on", + linebreak="id", + unicodeslot=0x31C8, + }, + [0x31C9]={ + category="so", + cjkwd="w", + description="CJK STROKE SZWG", + direction="on", + linebreak="id", + unicodeslot=0x31C9, + }, + [0x31CA]={ + category="so", + cjkwd="w", + description="CJK STROKE HZT", + direction="on", + linebreak="id", + unicodeslot=0x31CA, + }, + [0x31CB]={ + category="so", + cjkwd="w", + description="CJK STROKE HZZP", + direction="on", + linebreak="id", + unicodeslot=0x31CB, + }, + [0x31CC]={ + category="so", + cjkwd="w", + description="CJK STROKE HPWG", + direction="on", + linebreak="id", + unicodeslot=0x31CC, + }, + [0x31CD]={ + category="so", + cjkwd="w", + description="CJK STROKE HZW", + direction="on", + linebreak="id", + unicodeslot=0x31CD, + }, + [0x31CE]={ + category="so", + cjkwd="w", + description="CJK STROKE HZZZ", + direction="on", + linebreak="id", + unicodeslot=0x31CE, + }, + [0x31CF]={ + category="so", + cjkwd="w", + description="CJK STROKE N", + direction="on", + linebreak="id", + unicodeslot=0x31CF, + }, + [0x31F0]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL KU", + direction="l", + linebreak="ns", + unicodeslot=0x31F0, + }, + [0x31F1]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL SI", + direction="l", + linebreak="ns", + unicodeslot=0x31F1, + }, + [0x31F2]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL SU", + direction="l", + linebreak="ns", + unicodeslot=0x31F2, + }, + [0x31F3]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL TO", + direction="l", + linebreak="ns", + unicodeslot=0x31F3, + }, + [0x31F4]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL NU", + direction="l", + linebreak="ns", + unicodeslot=0x31F4, + }, + [0x31F5]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL HA", + direction="l", + linebreak="ns", + unicodeslot=0x31F5, + }, + [0x31F6]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL HI", + direction="l", + linebreak="ns", + unicodeslot=0x31F6, + }, + [0x31F7]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL HU", + direction="l", + linebreak="ns", + unicodeslot=0x31F7, + }, + [0x31F8]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL HE", + direction="l", + linebreak="ns", + unicodeslot=0x31F8, + }, + [0x31F9]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL HO", + direction="l", + linebreak="ns", + unicodeslot=0x31F9, + }, + [0x31FA]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL MU", + direction="l", + linebreak="ns", + unicodeslot=0x31FA, + }, + [0x31FB]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL RA", + direction="l", + linebreak="ns", + unicodeslot=0x31FB, + }, + [0x31FC]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL RI", + direction="l", + linebreak="ns", + unicodeslot=0x31FC, + }, + [0x31FD]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL RU", + direction="l", + linebreak="ns", + unicodeslot=0x31FD, + }, + [0x31FE]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL RE", + direction="l", + linebreak="ns", + unicodeslot=0x31FE, + }, + [0x31FF]={ + category="lo", + cjkwd="w", + description="KATAKANA LETTER SMALL RO", + direction="l", + linebreak="ns", + unicodeslot=0x31FF, + }, + [0x3200]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL KIYEOK", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x1100, 0x0029 }, + unicodeslot=0x3200, + }, + [0x3201]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL NIEUN", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x1102, 0x0029 }, + unicodeslot=0x3201, + }, + [0x3202]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL TIKEUT", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x1103, 0x0029 }, + unicodeslot=0x3202, + }, + [0x3203]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL RIEUL", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x1105, 0x0029 }, + unicodeslot=0x3203, + }, + [0x3204]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL MIEUM", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x1106, 0x0029 }, + unicodeslot=0x3204, + }, + [0x3205]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL PIEUP", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x1107, 0x0029 }, + unicodeslot=0x3205, + }, + [0x3206]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL SIOS", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x1109, 0x0029 }, + unicodeslot=0x3206, + }, + [0x3207]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL IEUNG", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x110B, 0x0029 }, + unicodeslot=0x3207, + }, + [0x3208]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL CIEUC", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x110C, 0x0029 }, + unicodeslot=0x3208, + }, + [0x3209]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL CHIEUCH", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x110E, 0x0029 }, + unicodeslot=0x3209, + }, + [0x320A]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL KHIEUKH", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x110F, 0x0029 }, + unicodeslot=0x320A, + }, + [0x320B]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL THIEUTH", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x1110, 0x0029 }, + unicodeslot=0x320B, + }, + [0x320C]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL PHIEUPH", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x1111, 0x0029 }, + unicodeslot=0x320C, + }, + [0x320D]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL HIEUH", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x1112, 0x0029 }, + unicodeslot=0x320D, + }, + [0x320E]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL KIYEOK A", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x1100, 0x1161, 0x0029 }, + unicodeslot=0x320E, + }, + [0x320F]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL NIEUN A", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x1102, 0x1161, 0x0029 }, + unicodeslot=0x320F, + }, + [0x3210]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL TIKEUT A", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x1103, 0x1161, 0x0029 }, + unicodeslot=0x3210, + }, + [0x3211]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL RIEUL A", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x1105, 0x1161, 0x0029 }, + unicodeslot=0x3211, + }, + [0x3212]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL MIEUM A", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x1106, 0x1161, 0x0029 }, + unicodeslot=0x3212, + }, + [0x3213]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL PIEUP A", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x1107, 0x1161, 0x0029 }, + unicodeslot=0x3213, + }, + [0x3214]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL SIOS A", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x1109, 0x1161, 0x0029 }, + unicodeslot=0x3214, + }, + [0x3215]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL IEUNG A", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x110B, 0x1161, 0x0029 }, + unicodeslot=0x3215, + }, + [0x3216]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL CIEUC A", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x110C, 0x1161, 0x0029 }, + unicodeslot=0x3216, + }, + [0x3217]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL CHIEUCH A", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x110E, 0x1161, 0x0029 }, + unicodeslot=0x3217, + }, + [0x3218]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL KHIEUKH A", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x110F, 0x1161, 0x0029 }, + unicodeslot=0x3218, + }, + [0x3219]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL THIEUTH A", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x1110, 0x1161, 0x0029 }, + unicodeslot=0x3219, + }, + [0x321A]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL PHIEUPH A", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x1111, 0x1161, 0x0029 }, + unicodeslot=0x321A, + }, + [0x321B]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL HIEUH A", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x1112, 0x1161, 0x0029 }, + unicodeslot=0x321B, + }, + [0x321C]={ + category="so", + cjkwd="w", + description="PARENTHESIZED HANGUL CIEUC U", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x110C, 0x116E, 0x0029 }, + unicodeslot=0x321C, + }, + [0x321D]={ + category="so", + cjkwd="w", + description="PARENTHESIZED KOREAN CHARACTER OJEON", + direction="on", + linebreak="id", + specials={ "compat", 0x0028, 0x110B, 0x1169, 0x110C, 0x1165, 0x11AB, 0x0029 }, + unicodeslot=0x321D, + }, + [0x321E]={ + category="so", + cjkwd="w", + description="PARENTHESIZED KOREAN CHARACTER O HU", + direction="on", + linebreak="id", + specials={ "compat", 0x0028, 0x110B, 0x1169, 0x1112, 0x116E, 0x0029 }, + unicodeslot=0x321E, + }, + [0x3220]={ + category="no", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH ONE", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x4E00, 0x0029 }, + unicodeslot=0x3220, + }, + [0x3221]={ + category="no", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH TWO", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x4E8C, 0x0029 }, + unicodeslot=0x3221, + }, + [0x3222]={ + category="no", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH THREE", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x4E09, 0x0029 }, + unicodeslot=0x3222, + }, + [0x3223]={ + category="no", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH FOUR", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x56DB, 0x0029 }, + unicodeslot=0x3223, + }, + [0x3224]={ + category="no", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH FIVE", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x4E94, 0x0029 }, + unicodeslot=0x3224, + }, + [0x3225]={ + category="no", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH SIX", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x516D, 0x0029 }, + unicodeslot=0x3225, + }, + [0x3226]={ + category="no", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH SEVEN", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x4E03, 0x0029 }, + unicodeslot=0x3226, + }, + [0x3227]={ + category="no", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH EIGHT", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x516B, 0x0029 }, + unicodeslot=0x3227, + }, + [0x3228]={ + category="no", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH NINE", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x4E5D, 0x0029 }, + unicodeslot=0x3228, + }, + [0x3229]={ + category="no", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH TEN", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x5341, 0x0029 }, + unicodeslot=0x3229, + }, + [0x322A]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH MOON", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x6708, 0x0029 }, + unicodeslot=0x322A, + }, + [0x322B]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH FIRE", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x706B, 0x0029 }, + unicodeslot=0x322B, + }, + [0x322C]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH WATER", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x6C34, 0x0029 }, + unicodeslot=0x322C, + }, + [0x322D]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH WOOD", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x6728, 0x0029 }, + unicodeslot=0x322D, + }, + [0x322E]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH METAL", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x91D1, 0x0029 }, + unicodeslot=0x322E, + }, + [0x322F]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH EARTH", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x571F, 0x0029 }, + unicodeslot=0x322F, + }, + [0x3230]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH SUN", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x65E5, 0x0029 }, + unicodeslot=0x3230, + }, + [0x3231]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH STOCK", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x682A, 0x0029 }, + unicodeslot=0x3231, + }, + [0x3232]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH HAVE", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x6709, 0x0029 }, + unicodeslot=0x3232, + }, + [0x3233]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH SOCIETY", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x793E, 0x0029 }, + unicodeslot=0x3233, + }, + [0x3234]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH NAME", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x540D, 0x0029 }, + unicodeslot=0x3234, + }, + [0x3235]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH SPECIAL", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x7279, 0x0029 }, + unicodeslot=0x3235, + }, + [0x3236]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH FINANCIAL", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x8CA1, 0x0029 }, + unicodeslot=0x3236, + }, + [0x3237]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH CONGRATULATION", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x795D, 0x0029 }, + unicodeslot=0x3237, + }, + [0x3238]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH LABOR", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x52B4, 0x0029 }, + unicodeslot=0x3238, + }, + [0x3239]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH REPRESENT", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x4EE3, 0x0029 }, + unicodeslot=0x3239, + }, + [0x323A]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH CALL", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x547C, 0x0029 }, + unicodeslot=0x323A, + }, + [0x323B]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH STUDY", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x5B66, 0x0029 }, + unicodeslot=0x323B, + }, + [0x323C]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH SUPERVISE", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x76E3, 0x0029 }, + unicodeslot=0x323C, + }, + [0x323D]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH ENTERPRISE", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x4F01, 0x0029 }, + unicodeslot=0x323D, + }, + [0x323E]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH RESOURCE", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x8CC7, 0x0029 }, + unicodeslot=0x323E, + }, + [0x323F]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH ALLIANCE", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x5354, 0x0029 }, + unicodeslot=0x323F, + }, + [0x3240]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH FESTIVAL", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x796D, 0x0029 }, + unicodeslot=0x3240, + }, + [0x3241]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH REST", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x4F11, 0x0029 }, + unicodeslot=0x3241, + }, + [0x3242]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH SELF", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x81EA, 0x0029 }, + unicodeslot=0x3242, + }, + [0x3243]={ + category="so", + cjkwd="w", + description="PARENTHESIZED IDEOGRAPH REACH", + direction="l", + linebreak="id", + specials={ "compat", 0x0028, 0x81F3, 0x0029 }, + unicodeslot=0x3243, + }, + [0x3250]={ + category="so", + cjkwd="w", + description="PARTNERSHIP SIGN", + direction="on", + linebreak="id", + specials={ "square", 0x0050, 0x0054, 0x0045 }, + unicodeslot=0x3250, + }, + [0x3251]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER TWENTY ONE", + direction="on", + linebreak="id", + specials={ "circle", 0x0032, 0x0031 }, + unicodeslot=0x3251, + }, + [0x3252]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER TWENTY TWO", + direction="on", + linebreak="id", + specials={ "circle", 0x0032, 0x0032 }, + unicodeslot=0x3252, + }, + [0x3253]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER TWENTY THREE", + direction="on", + linebreak="id", + specials={ "circle", 0x0032, 0x0033 }, + unicodeslot=0x3253, + }, + [0x3254]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER TWENTY FOUR", + direction="on", + linebreak="id", + specials={ "circle", 0x0032, 0x0034 }, + unicodeslot=0x3254, + }, + [0x3255]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER TWENTY FIVE", + direction="on", + linebreak="id", + specials={ "circle", 0x0032, 0x0035 }, + unicodeslot=0x3255, + }, + [0x3256]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER TWENTY SIX", + direction="on", + linebreak="id", + specials={ "circle", 0x0032, 0x0036 }, + unicodeslot=0x3256, + }, + [0x3257]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER TWENTY SEVEN", + direction="on", + linebreak="id", + specials={ "circle", 0x0032, 0x0037 }, + unicodeslot=0x3257, + }, + [0x3258]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER TWENTY EIGHT", + direction="on", + linebreak="id", + specials={ "circle", 0x0032, 0x0038 }, + unicodeslot=0x3258, + }, + [0x3259]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER TWENTY NINE", + direction="on", + linebreak="id", + specials={ "circle", 0x0032, 0x0039 }, + unicodeslot=0x3259, + }, + [0x325A]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER THIRTY", + direction="on", + linebreak="id", + specials={ "circle", 0x0033, 0x0030 }, + unicodeslot=0x325A, + }, + [0x325B]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER THIRTY ONE", + direction="on", + linebreak="id", + specials={ "circle", 0x0033, 0x0031 }, + unicodeslot=0x325B, + }, + [0x325C]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER THIRTY TWO", + direction="on", + linebreak="id", + specials={ "circle", 0x0033, 0x0032 }, + unicodeslot=0x325C, + }, + [0x325D]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER THIRTY THREE", + direction="on", + linebreak="id", + specials={ "circle", 0x0033, 0x0033 }, + unicodeslot=0x325D, + }, + [0x325E]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER THIRTY FOUR", + direction="on", + linebreak="id", + specials={ "circle", 0x0033, 0x0034 }, + unicodeslot=0x325E, + }, + [0x325F]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER THIRTY FIVE", + direction="on", + linebreak="id", + specials={ "circle", 0x0033, 0x0035 }, + unicodeslot=0x325F, + }, + [0x3260]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL KIYEOK", + direction="l", + linebreak="id", + specials={ "circle", 0x1100 }, + unicodeslot=0x3260, + }, + [0x3261]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL NIEUN", + direction="l", + linebreak="id", + specials={ "circle", 0x1102 }, + unicodeslot=0x3261, + }, + [0x3262]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL TIKEUT", + direction="l", + linebreak="id", + specials={ "circle", 0x1103 }, + unicodeslot=0x3262, + }, + [0x3263]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL RIEUL", + direction="l", + linebreak="id", + specials={ "circle", 0x1105 }, + unicodeslot=0x3263, + }, + [0x3264]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL MIEUM", + direction="l", + linebreak="id", + specials={ "circle", 0x1106 }, + unicodeslot=0x3264, + }, + [0x3265]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL PIEUP", + direction="l", + linebreak="id", + specials={ "circle", 0x1107 }, + unicodeslot=0x3265, + }, + [0x3266]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL SIOS", + direction="l", + linebreak="id", + specials={ "circle", 0x1109 }, + unicodeslot=0x3266, + }, + [0x3267]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL IEUNG", + direction="l", + linebreak="id", + specials={ "circle", 0x110B }, + unicodeslot=0x3267, + }, + [0x3268]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL CIEUC", + direction="l", + linebreak="id", + specials={ "circle", 0x110C }, + unicodeslot=0x3268, + }, + [0x3269]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL CHIEUCH", + direction="l", + linebreak="id", + specials={ "circle", 0x110E }, + unicodeslot=0x3269, + }, + [0x326A]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL KHIEUKH", + direction="l", + linebreak="id", + specials={ "circle", 0x110F }, + unicodeslot=0x326A, + }, + [0x326B]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL THIEUTH", + direction="l", + linebreak="id", + specials={ "circle", 0x1110 }, + unicodeslot=0x326B, + }, + [0x326C]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL PHIEUPH", + direction="l", + linebreak="id", + specials={ "circle", 0x1111 }, + unicodeslot=0x326C, + }, + [0x326D]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL HIEUH", + direction="l", + linebreak="id", + specials={ "circle", 0x1112 }, + unicodeslot=0x326D, + }, + [0x326E]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL KIYEOK A", + direction="l", + linebreak="id", + specials={ "circle", 0x1100, 0x1161 }, + unicodeslot=0x326E, + }, + [0x326F]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL NIEUN A", + direction="l", + linebreak="id", + specials={ "circle", 0x1102, 0x1161 }, + unicodeslot=0x326F, + }, + [0x3270]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL TIKEUT A", + direction="l", + linebreak="id", + specials={ "circle", 0x1103, 0x1161 }, + unicodeslot=0x3270, + }, + [0x3271]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL RIEUL A", + direction="l", + linebreak="id", + specials={ "circle", 0x1105, 0x1161 }, + unicodeslot=0x3271, + }, + [0x3272]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL MIEUM A", + direction="l", + linebreak="id", + specials={ "circle", 0x1106, 0x1161 }, + unicodeslot=0x3272, + }, + [0x3273]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL PIEUP A", + direction="l", + linebreak="id", + specials={ "circle", 0x1107, 0x1161 }, + unicodeslot=0x3273, + }, + [0x3274]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL SIOS A", + direction="l", + linebreak="id", + specials={ "circle", 0x1109, 0x1161 }, + unicodeslot=0x3274, + }, + [0x3275]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL IEUNG A", + direction="l", + linebreak="id", + specials={ "circle", 0x110B, 0x1161 }, + unicodeslot=0x3275, + }, + [0x3276]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL CIEUC A", + direction="l", + linebreak="id", + specials={ "circle", 0x110C, 0x1161 }, + unicodeslot=0x3276, + }, + [0x3277]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL CHIEUCH A", + direction="l", + linebreak="id", + specials={ "circle", 0x110E, 0x1161 }, + unicodeslot=0x3277, + }, + [0x3278]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL KHIEUKH A", + direction="l", + linebreak="id", + specials={ "circle", 0x110F, 0x1161 }, + unicodeslot=0x3278, + }, + [0x3279]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL THIEUTH A", + direction="l", + linebreak="id", + specials={ "circle", 0x1110, 0x1161 }, + unicodeslot=0x3279, + }, + [0x327A]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL PHIEUPH A", + direction="l", + linebreak="id", + specials={ "circle", 0x1111, 0x1161 }, + unicodeslot=0x327A, + }, + [0x327B]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL HIEUH A", + direction="l", + linebreak="id", + specials={ "circle", 0x1112, 0x1161 }, + unicodeslot=0x327B, + }, + [0x327C]={ + category="so", + cjkwd="w", + description="CIRCLED KOREAN CHARACTER CHAMKO", + direction="on", + linebreak="id", + specials={ "circle", 0x110E, 0x1161, 0x11B7, 0x1100, 0x1169 }, + unicodeslot=0x327C, + }, + [0x327D]={ + category="so", + cjkwd="w", + description="CIRCLED KOREAN CHARACTER JUEUI", + direction="on", + linebreak="id", + specials={ "circle", 0x110C, 0x116E, 0x110B, 0x1174 }, + unicodeslot=0x327D, + }, + [0x327E]={ + category="so", + cjkwd="w", + description="CIRCLED HANGUL IEUNG U", + direction="on", + linebreak="id", + specials={ "circle", 0x110B, 0x116E }, + unicodeslot=0x327E, + }, + [0x327F]={ + category="so", + cjkwd="w", + description="KOREAN STANDARD SYMBOL", + direction="l", + linebreak="id", + unicodeslot=0x327F, + }, + [0x3280]={ + category="no", + cjkwd="w", + description="CIRCLED IDEOGRAPH ONE", + direction="l", + linebreak="id", + specials={ "circle", 0x4E00 }, + unicodeslot=0x3280, + }, + [0x3281]={ + category="no", + cjkwd="w", + description="CIRCLED IDEOGRAPH TWO", + direction="l", + linebreak="id", + specials={ "circle", 0x4E8C }, + unicodeslot=0x3281, + }, + [0x3282]={ + category="no", + cjkwd="w", + description="CIRCLED IDEOGRAPH THREE", + direction="l", + linebreak="id", + specials={ "circle", 0x4E09 }, + unicodeslot=0x3282, + }, + [0x3283]={ + category="no", + cjkwd="w", + description="CIRCLED IDEOGRAPH FOUR", + direction="l", + linebreak="id", + specials={ "circle", 0x56DB }, + unicodeslot=0x3283, + }, + [0x3284]={ + category="no", + cjkwd="w", + description="CIRCLED IDEOGRAPH FIVE", + direction="l", + linebreak="id", + specials={ "circle", 0x4E94 }, + unicodeslot=0x3284, + }, + [0x3285]={ + category="no", + cjkwd="w", + description="CIRCLED IDEOGRAPH SIX", + direction="l", + linebreak="id", + specials={ "circle", 0x516D }, + unicodeslot=0x3285, + }, + [0x3286]={ + category="no", + cjkwd="w", + description="CIRCLED IDEOGRAPH SEVEN", + direction="l", + linebreak="id", + specials={ "circle", 0x4E03 }, + unicodeslot=0x3286, + }, + [0x3287]={ + category="no", + cjkwd="w", + description="CIRCLED IDEOGRAPH EIGHT", + direction="l", + linebreak="id", + specials={ "circle", 0x516B }, + unicodeslot=0x3287, + }, + [0x3288]={ + category="no", + cjkwd="w", + description="CIRCLED IDEOGRAPH NINE", + direction="l", + linebreak="id", + specials={ "circle", 0x4E5D }, + unicodeslot=0x3288, + }, + [0x3289]={ + category="no", + cjkwd="w", + description="CIRCLED IDEOGRAPH TEN", + direction="l", + linebreak="id", + specials={ "circle", 0x5341 }, + unicodeslot=0x3289, + }, + [0x328A]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH MOON", + direction="l", + linebreak="id", + specials={ "circle", 0x6708 }, + unicodeslot=0x328A, + }, + [0x328B]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH FIRE", + direction="l", + linebreak="id", + specials={ "circle", 0x706B }, + unicodeslot=0x328B, + }, + [0x328C]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH WATER", + direction="l", + linebreak="id", + specials={ "circle", 0x6C34 }, + unicodeslot=0x328C, + }, + [0x328D]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH WOOD", + direction="l", + linebreak="id", + specials={ "circle", 0x6728 }, + unicodeslot=0x328D, + }, + [0x328E]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH METAL", + direction="l", + linebreak="id", + specials={ "circle", 0x91D1 }, + unicodeslot=0x328E, + }, + [0x328F]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH EARTH", + direction="l", + linebreak="id", + specials={ "circle", 0x571F }, + unicodeslot=0x328F, + }, + [0x3290]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH SUN", + direction="l", + linebreak="id", + specials={ "circle", 0x65E5 }, + unicodeslot=0x3290, + }, + [0x3291]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH STOCK", + direction="l", + linebreak="id", + specials={ "circle", 0x682A }, + unicodeslot=0x3291, + }, + [0x3292]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH HAVE", + direction="l", + linebreak="id", + specials={ "circle", 0x6709 }, + unicodeslot=0x3292, + }, + [0x3293]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH SOCIETY", + direction="l", + linebreak="id", + specials={ "circle", 0x793E }, + unicodeslot=0x3293, + }, + [0x3294]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH NAME", + direction="l", + linebreak="id", + specials={ "circle", 0x540D }, + unicodeslot=0x3294, + }, + [0x3295]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH SPECIAL", + direction="l", + linebreak="id", + specials={ "circle", 0x7279 }, + unicodeslot=0x3295, + }, + [0x3296]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH FINANCIAL", + direction="l", + linebreak="id", + specials={ "circle", 0x8CA1 }, + unicodeslot=0x3296, + }, + [0x3297]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH CONGRATULATION", + direction="l", + linebreak="id", + specials={ "circle", 0x795D }, + unicodeslot=0x3297, + }, + [0x3298]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH LABOR", + direction="l", + linebreak="id", + specials={ "circle", 0x52B4 }, + unicodeslot=0x3298, + }, + [0x3299]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH SECRET", + direction="l", + linebreak="id", + specials={ "circle", 0x79D8 }, + unicodeslot=0x3299, + }, + [0x329A]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH MALE", + direction="l", + linebreak="id", + specials={ "circle", 0x7537 }, + unicodeslot=0x329A, + }, + [0x329B]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH FEMALE", + direction="l", + linebreak="id", + specials={ "circle", 0x5973 }, + unicodeslot=0x329B, + }, + [0x329C]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH SUITABLE", + direction="l", + linebreak="id", + specials={ "circle", 0x9069 }, + unicodeslot=0x329C, + }, + [0x329D]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH EXCELLENT", + direction="l", + linebreak="id", + specials={ "circle", 0x512A }, + unicodeslot=0x329D, + }, + [0x329E]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH PRINT", + direction="l", + linebreak="id", + specials={ "circle", 0x5370 }, + unicodeslot=0x329E, + }, + [0x329F]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH ATTENTION", + direction="l", + linebreak="id", + specials={ "circle", 0x6CE8 }, + unicodeslot=0x329F, + }, + [0x32A0]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH ITEM", + direction="l", + linebreak="id", + specials={ "circle", 0x9805 }, + unicodeslot=0x32A0, + }, + [0x32A1]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH REST", + direction="l", + linebreak="id", + specials={ "circle", 0x4F11 }, + unicodeslot=0x32A1, + }, + [0x32A2]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH COPY", + direction="l", + linebreak="id", + specials={ "circle", 0x5199 }, + unicodeslot=0x32A2, + }, + [0x32A3]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH CORRECT", + direction="l", + linebreak="id", + specials={ "circle", 0x6B63 }, + unicodeslot=0x32A3, + }, + [0x32A4]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH HIGH", + direction="l", + linebreak="id", + specials={ "circle", 0x4E0A }, + unicodeslot=0x32A4, + }, + [0x32A5]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH CENTRE", + direction="l", + linebreak="id", + specials={ "circle", 0x4E2D }, + unicodeslot=0x32A5, + }, + [0x32A6]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH LOW", + direction="l", + linebreak="id", + specials={ "circle", 0x4E0B }, + unicodeslot=0x32A6, + }, + [0x32A7]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH LEFT", + direction="l", + linebreak="id", + specials={ "circle", 0x5DE6 }, + unicodeslot=0x32A7, + }, + [0x32A8]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH RIGHT", + direction="l", + linebreak="id", + specials={ "circle", 0x53F3 }, + unicodeslot=0x32A8, + }, + [0x32A9]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH MEDICINE", + direction="l", + linebreak="id", + specials={ "circle", 0x533B }, + unicodeslot=0x32A9, + }, + [0x32AA]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH RELIGION", + direction="l", + linebreak="id", + specials={ "circle", 0x5B97 }, + unicodeslot=0x32AA, + }, + [0x32AB]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH STUDY", + direction="l", + linebreak="id", + specials={ "circle", 0x5B66 }, + unicodeslot=0x32AB, + }, + [0x32AC]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH SUPERVISE", + direction="l", + linebreak="id", + specials={ "circle", 0x76E3 }, + unicodeslot=0x32AC, + }, + [0x32AD]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH ENTERPRISE", + direction="l", + linebreak="id", + specials={ "circle", 0x4F01 }, + unicodeslot=0x32AD, + }, + [0x32AE]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH RESOURCE", + direction="l", + linebreak="id", + specials={ "circle", 0x8CC7 }, + unicodeslot=0x32AE, + }, + [0x32AF]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH ALLIANCE", + direction="l", + linebreak="id", + specials={ "circle", 0x5354 }, + unicodeslot=0x32AF, + }, + [0x32B0]={ + category="so", + cjkwd="w", + description="CIRCLED IDEOGRAPH NIGHT", + direction="l", + linebreak="id", + specials={ "circle", 0x591C }, + unicodeslot=0x32B0, + }, + [0x32B1]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER THIRTY SIX", + direction="on", + linebreak="id", + specials={ "circle", 0x0033, 0x0036 }, + unicodeslot=0x32B1, + }, + [0x32B2]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER THIRTY SEVEN", + direction="on", + linebreak="id", + specials={ "circle", 0x0033, 0x0037 }, + unicodeslot=0x32B2, + }, + [0x32B3]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER THIRTY EIGHT", + direction="on", + linebreak="id", + specials={ "circle", 0x0033, 0x0038 }, + unicodeslot=0x32B3, + }, + [0x32B4]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER THIRTY NINE", + direction="on", + linebreak="id", + specials={ "circle", 0x0033, 0x0039 }, + unicodeslot=0x32B4, + }, + [0x32B5]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER FORTY", + direction="on", + linebreak="id", + specials={ "circle", 0x0034, 0x0030 }, + unicodeslot=0x32B5, + }, + [0x32B6]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER FORTY ONE", + direction="on", + linebreak="id", + specials={ "circle", 0x0034, 0x0031 }, + unicodeslot=0x32B6, + }, + [0x32B7]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER FORTY TWO", + direction="on", + linebreak="id", + specials={ "circle", 0x0034, 0x0032 }, + unicodeslot=0x32B7, + }, + [0x32B8]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER FORTY THREE", + direction="on", + linebreak="id", + specials={ "circle", 0x0034, 0x0033 }, + unicodeslot=0x32B8, + }, + [0x32B9]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER FORTY FOUR", + direction="on", + linebreak="id", + specials={ "circle", 0x0034, 0x0034 }, + unicodeslot=0x32B9, + }, + [0x32BA]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER FORTY FIVE", + direction="on", + linebreak="id", + specials={ "circle", 0x0034, 0x0035 }, + unicodeslot=0x32BA, + }, + [0x32BB]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER FORTY SIX", + direction="on", + linebreak="id", + specials={ "circle", 0x0034, 0x0036 }, + unicodeslot=0x32BB, + }, + [0x32BC]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER FORTY SEVEN", + direction="on", + linebreak="id", + specials={ "circle", 0x0034, 0x0037 }, + unicodeslot=0x32BC, + }, + [0x32BD]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER FORTY EIGHT", + direction="on", + linebreak="id", + specials={ "circle", 0x0034, 0x0038 }, + unicodeslot=0x32BD, + }, + [0x32BE]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER FORTY NINE", + direction="on", + linebreak="id", + specials={ "circle", 0x0034, 0x0039 }, + unicodeslot=0x32BE, + }, + [0x32BF]={ + category="no", + cjkwd="w", + description="CIRCLED NUMBER FIFTY", + direction="on", + linebreak="id", + specials={ "circle", 0x0035, 0x0030 }, + unicodeslot=0x32BF, + }, + [0x32C0]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x6708 }, + unicodeslot=0x32C0, + }, + [0x32C1]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR FEBRUARY", + direction="l", + linebreak="id", + specials={ "compat", 0x0032, 0x6708 }, + unicodeslot=0x32C1, + }, + [0x32C2]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR MARCH", + direction="l", + linebreak="id", + specials={ "compat", 0x0033, 0x6708 }, + unicodeslot=0x32C2, + }, + [0x32C3]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR APRIL", + direction="l", + linebreak="id", + specials={ "compat", 0x0034, 0x6708 }, + unicodeslot=0x32C3, + }, + [0x32C4]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR MAY", + direction="l", + linebreak="id", + specials={ "compat", 0x0035, 0x6708 }, + unicodeslot=0x32C4, + }, + [0x32C5]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR JUNE", + direction="l", + linebreak="id", + specials={ "compat", 0x0036, 0x6708 }, + unicodeslot=0x32C5, + }, + [0x32C6]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR JULY", + direction="l", + linebreak="id", + specials={ "compat", 0x0037, 0x6708 }, + unicodeslot=0x32C6, + }, + [0x32C7]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR AUGUST", + direction="l", + linebreak="id", + specials={ "compat", 0x0038, 0x6708 }, + unicodeslot=0x32C7, + }, + [0x32C8]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR SEPTEMBER", + direction="l", + linebreak="id", + specials={ "compat", 0x0039, 0x6708 }, + unicodeslot=0x32C8, + }, + [0x32C9]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR OCTOBER", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x0030, 0x6708 }, + unicodeslot=0x32C9, + }, + [0x32CA]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR NOVEMBER", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x0031, 0x6708 }, + unicodeslot=0x32CA, + }, + [0x32CB]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DECEMBER", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x0032, 0x6708 }, + unicodeslot=0x32CB, + }, + [0x32CC]={ + category="so", + cjkwd="w", + description="SQUARE HG", + direction="on", + linebreak="id", + specials={ "square", 0x0048, 0x0067 }, + unicodeslot=0x32CC, + }, + [0x32CD]={ + category="so", + cjkwd="w", + description="SQUARE ERG", + direction="on", + linebreak="id", + specials={ "square", 0x0065, 0x0072, 0x0067 }, + unicodeslot=0x32CD, + }, + [0x32CE]={ + category="so", + cjkwd="w", + description="SQUARE EV", + direction="on", + linebreak="id", + specials={ "square", 0x0065, 0x0056 }, + unicodeslot=0x32CE, + }, + [0x32CF]={ + category="so", + cjkwd="w", + description="LIMITED LIABILITY SIGN", + direction="on", + linebreak="id", + specials={ "square", 0x004C, 0x0054, 0x0044 }, + unicodeslot=0x32CF, + }, + [0x32D0]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA A", + direction="l", + linebreak="id", + specials={ "circle", 0x30A2 }, + unicodeslot=0x32D0, + }, + [0x32D1]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA I", + direction="l", + linebreak="id", + specials={ "circle", 0x30A4 }, + unicodeslot=0x32D1, + }, + [0x32D2]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA U", + direction="l", + linebreak="id", + specials={ "circle", 0x30A6 }, + unicodeslot=0x32D2, + }, + [0x32D3]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA E", + direction="l", + linebreak="id", + specials={ "circle", 0x30A8 }, + unicodeslot=0x32D3, + }, + [0x32D4]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA O", + direction="l", + linebreak="id", + specials={ "circle", 0x30AA }, + unicodeslot=0x32D4, + }, + [0x32D5]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA KA", + direction="l", + linebreak="id", + specials={ "circle", 0x30AB }, + unicodeslot=0x32D5, + }, + [0x32D6]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA KI", + direction="l", + linebreak="id", + specials={ "circle", 0x30AD }, + unicodeslot=0x32D6, + }, + [0x32D7]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA KU", + direction="l", + linebreak="id", + specials={ "circle", 0x30AF }, + unicodeslot=0x32D7, + }, + [0x32D8]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA KE", + direction="l", + linebreak="id", + specials={ "circle", 0x30B1 }, + unicodeslot=0x32D8, + }, + [0x32D9]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA KO", + direction="l", + linebreak="id", + specials={ "circle", 0x30B3 }, + unicodeslot=0x32D9, + }, + [0x32DA]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA SA", + direction="l", + linebreak="id", + specials={ "circle", 0x30B5 }, + unicodeslot=0x32DA, + }, + [0x32DB]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA SI", + direction="l", + linebreak="id", + specials={ "circle", 0x30B7 }, + unicodeslot=0x32DB, + }, + [0x32DC]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA SU", + direction="l", + linebreak="id", + specials={ "circle", 0x30B9 }, + unicodeslot=0x32DC, + }, + [0x32DD]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA SE", + direction="l", + linebreak="id", + specials={ "circle", 0x30BB }, + unicodeslot=0x32DD, + }, + [0x32DE]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA SO", + direction="l", + linebreak="id", + specials={ "circle", 0x30BD }, + unicodeslot=0x32DE, + }, + [0x32DF]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA TA", + direction="l", + linebreak="id", + specials={ "circle", 0x30BF }, + unicodeslot=0x32DF, + }, + [0x32E0]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA TI", + direction="l", + linebreak="id", + specials={ "circle", 0x30C1 }, + unicodeslot=0x32E0, + }, + [0x32E1]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA TU", + direction="l", + linebreak="id", + specials={ "circle", 0x30C4 }, + unicodeslot=0x32E1, + }, + [0x32E2]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA TE", + direction="l", + linebreak="id", + specials={ "circle", 0x30C6 }, + unicodeslot=0x32E2, + }, + [0x32E3]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA TO", + direction="l", + linebreak="id", + specials={ "circle", 0x30C8 }, + unicodeslot=0x32E3, + }, + [0x32E4]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA NA", + direction="l", + linebreak="id", + specials={ "circle", 0x30CA }, + unicodeslot=0x32E4, + }, + [0x32E5]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA NI", + direction="l", + linebreak="id", + specials={ "circle", 0x30CB }, + unicodeslot=0x32E5, + }, + [0x32E6]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA NU", + direction="l", + linebreak="id", + specials={ "circle", 0x30CC }, + unicodeslot=0x32E6, + }, + [0x32E7]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA NE", + direction="l", + linebreak="id", + specials={ "circle", 0x30CD }, + unicodeslot=0x32E7, + }, + [0x32E8]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA NO", + direction="l", + linebreak="id", + specials={ "circle", 0x30CE }, + unicodeslot=0x32E8, + }, + [0x32E9]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA HA", + direction="l", + linebreak="id", + specials={ "circle", 0x30CF }, + unicodeslot=0x32E9, + }, + [0x32EA]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA HI", + direction="l", + linebreak="id", + specials={ "circle", 0x30D2 }, + unicodeslot=0x32EA, + }, + [0x32EB]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA HU", + direction="l", + linebreak="id", + specials={ "circle", 0x30D5 }, + unicodeslot=0x32EB, + }, + [0x32EC]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA HE", + direction="l", + linebreak="id", + specials={ "circle", 0x30D8 }, + unicodeslot=0x32EC, + }, + [0x32ED]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA HO", + direction="l", + linebreak="id", + specials={ "circle", 0x30DB }, + unicodeslot=0x32ED, + }, + [0x32EE]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA MA", + direction="l", + linebreak="id", + specials={ "circle", 0x30DE }, + unicodeslot=0x32EE, + }, + [0x32EF]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA MI", + direction="l", + linebreak="id", + specials={ "circle", 0x30DF }, + unicodeslot=0x32EF, + }, + [0x32F0]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA MU", + direction="l", + linebreak="id", + specials={ "circle", 0x30E0 }, + unicodeslot=0x32F0, + }, + [0x32F1]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA ME", + direction="l", + linebreak="id", + specials={ "circle", 0x30E1 }, + unicodeslot=0x32F1, + }, + [0x32F2]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA MO", + direction="l", + linebreak="id", + specials={ "circle", 0x30E2 }, + unicodeslot=0x32F2, + }, + [0x32F3]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA YA", + direction="l", + linebreak="id", + specials={ "circle", 0x30E4 }, + unicodeslot=0x32F3, + }, + [0x32F4]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA YU", + direction="l", + linebreak="id", + specials={ "circle", 0x30E6 }, + unicodeslot=0x32F4, + }, + [0x32F5]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA YO", + direction="l", + linebreak="id", + specials={ "circle", 0x30E8 }, + unicodeslot=0x32F5, + }, + [0x32F6]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA RA", + direction="l", + linebreak="id", + specials={ "circle", 0x30E9 }, + unicodeslot=0x32F6, + }, + [0x32F7]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA RI", + direction="l", + linebreak="id", + specials={ "circle", 0x30EA }, + unicodeslot=0x32F7, + }, + [0x32F8]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA RU", + direction="l", + linebreak="id", + specials={ "circle", 0x30EB }, + unicodeslot=0x32F8, + }, + [0x32F9]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA RE", + direction="l", + linebreak="id", + specials={ "circle", 0x30EC }, + unicodeslot=0x32F9, + }, + [0x32FA]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA RO", + direction="l", + linebreak="id", + specials={ "circle", 0x30ED }, + unicodeslot=0x32FA, + }, + [0x32FB]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA WA", + direction="l", + linebreak="id", + specials={ "circle", 0x30EF }, + unicodeslot=0x32FB, + }, + [0x32FC]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA WI", + direction="l", + linebreak="id", + specials={ "circle", 0x30F0 }, + unicodeslot=0x32FC, + }, + [0x32FD]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA WE", + direction="l", + linebreak="id", + specials={ "circle", 0x30F1 }, + unicodeslot=0x32FD, + }, + [0x32FE]={ + category="so", + cjkwd="w", + description="CIRCLED KATAKANA WO", + direction="l", + linebreak="id", + specials={ "circle", 0x30F2 }, + unicodeslot=0x32FE, + }, + [0x3300]={ + category="so", + cjkwd="w", + description="SQUARE APAATO", + direction="l", + linebreak="id", + specials={ "square", 0x30A2, 0x30D1, 0x30FC, 0x30C8 }, + unicodeslot=0x3300, + }, + [0x3301]={ + category="so", + cjkwd="w", + description="SQUARE ARUHUA", + direction="l", + linebreak="id", + specials={ "square", 0x30A2, 0x30EB, 0x30D5, 0x30A1 }, + unicodeslot=0x3301, + }, + [0x3302]={ + category="so", + cjkwd="w", + description="SQUARE ANPEA", + direction="l", + linebreak="id", + specials={ "square", 0x30A2, 0x30F3, 0x30DA, 0x30A2 }, + unicodeslot=0x3302, + }, + [0x3303]={ + category="so", + cjkwd="w", + description="SQUARE AARU", + direction="l", + linebreak="id", + specials={ "square", 0x30A2, 0x30FC, 0x30EB }, + unicodeslot=0x3303, + }, + [0x3304]={ + category="so", + cjkwd="w", + description="SQUARE ININGU", + direction="l", + linebreak="id", + specials={ "square", 0x30A4, 0x30CB, 0x30F3, 0x30B0 }, + unicodeslot=0x3304, + }, + [0x3305]={ + category="so", + cjkwd="w", + description="SQUARE INTI", + direction="l", + linebreak="id", + specials={ "square", 0x30A4, 0x30F3, 0x30C1 }, + unicodeslot=0x3305, + }, + [0x3306]={ + category="so", + cjkwd="w", + description="SQUARE UON", + direction="l", + linebreak="id", + specials={ "square", 0x30A6, 0x30A9, 0x30F3 }, + unicodeslot=0x3306, + }, + [0x3307]={ + category="so", + cjkwd="w", + description="SQUARE ESUKUUDO", + direction="l", + linebreak="id", + specials={ "square", 0x30A8, 0x30B9, 0x30AF, 0x30FC, 0x30C9 }, + unicodeslot=0x3307, + }, + [0x3308]={ + category="so", + cjkwd="w", + description="SQUARE EEKAA", + direction="l", + linebreak="id", + specials={ "square", 0x30A8, 0x30FC, 0x30AB, 0x30FC }, + unicodeslot=0x3308, + }, + [0x3309]={ + category="so", + cjkwd="w", + description="SQUARE ONSU", + direction="l", + linebreak="id", + specials={ "square", 0x30AA, 0x30F3, 0x30B9 }, + unicodeslot=0x3309, + }, + [0x330A]={ + category="so", + cjkwd="w", + description="SQUARE OOMU", + direction="l", + linebreak="id", + specials={ "square", 0x30AA, 0x30FC, 0x30E0 }, + unicodeslot=0x330A, + }, + [0x330B]={ + category="so", + cjkwd="w", + description="SQUARE KAIRI", + direction="l", + linebreak="id", + specials={ "square", 0x30AB, 0x30A4, 0x30EA }, + unicodeslot=0x330B, + }, + [0x330C]={ + category="so", + cjkwd="w", + description="SQUARE KARATTO", + direction="l", + linebreak="id", + specials={ "square", 0x30AB, 0x30E9, 0x30C3, 0x30C8 }, + unicodeslot=0x330C, + }, + [0x330D]={ + category="so", + cjkwd="w", + description="SQUARE KARORII", + direction="l", + linebreak="id", + specials={ "square", 0x30AB, 0x30ED, 0x30EA, 0x30FC }, + unicodeslot=0x330D, + }, + [0x330E]={ + category="so", + cjkwd="w", + description="SQUARE GARON", + direction="l", + linebreak="id", + specials={ "square", 0x30AC, 0x30ED, 0x30F3 }, + unicodeslot=0x330E, + }, + [0x330F]={ + category="so", + cjkwd="w", + description="SQUARE GANMA", + direction="l", + linebreak="id", + specials={ "square", 0x30AC, 0x30F3, 0x30DE }, + unicodeslot=0x330F, + }, + [0x3310]={ + category="so", + cjkwd="w", + description="SQUARE GIGA", + direction="l", + linebreak="id", + specials={ "square", 0x30AE, 0x30AC }, + unicodeslot=0x3310, + }, + [0x3311]={ + category="so", + cjkwd="w", + description="SQUARE GINII", + direction="l", + linebreak="id", + specials={ "square", 0x30AE, 0x30CB, 0x30FC }, + unicodeslot=0x3311, + }, + [0x3312]={ + category="so", + cjkwd="w", + description="SQUARE KYURII", + direction="l", + linebreak="id", + specials={ "square", 0x30AD, 0x30E5, 0x30EA, 0x30FC }, + unicodeslot=0x3312, + }, + [0x3313]={ + category="so", + cjkwd="w", + description="SQUARE GIRUDAA", + direction="l", + linebreak="id", + specials={ "square", 0x30AE, 0x30EB, 0x30C0, 0x30FC }, + unicodeslot=0x3313, + }, + [0x3314]={ + category="so", + cjkwd="w", + description="SQUARE KIRO", + direction="l", + linebreak="id", + specials={ "square", 0x30AD, 0x30ED }, + unicodeslot=0x3314, + }, + [0x3315]={ + category="so", + cjkwd="w", + description="SQUARE KIROGURAMU", + direction="l", + linebreak="id", + specials={ "square", 0x30AD, 0x30ED, 0x30B0, 0x30E9, 0x30E0 }, + unicodeslot=0x3315, + }, + [0x3316]={ + category="so", + cjkwd="w", + description="SQUARE KIROMEETORU", + direction="l", + linebreak="id", + specials={ "square", 0x30AD, 0x30ED, 0x30E1, 0x30FC, 0x30C8, 0x30EB }, + unicodeslot=0x3316, + }, + [0x3317]={ + category="so", + cjkwd="w", + description="SQUARE KIROWATTO", + direction="l", + linebreak="id", + specials={ "square", 0x30AD, 0x30ED, 0x30EF, 0x30C3, 0x30C8 }, + unicodeslot=0x3317, + }, + [0x3318]={ + category="so", + cjkwd="w", + description="SQUARE GURAMU", + direction="l", + linebreak="id", + specials={ "square", 0x30B0, 0x30E9, 0x30E0 }, + unicodeslot=0x3318, + }, + [0x3319]={ + category="so", + cjkwd="w", + description="SQUARE GURAMUTON", + direction="l", + linebreak="id", + specials={ "square", 0x30B0, 0x30E9, 0x30E0, 0x30C8, 0x30F3 }, + unicodeslot=0x3319, + }, + [0x331A]={ + category="so", + cjkwd="w", + description="SQUARE KURUZEIRO", + direction="l", + linebreak="id", + specials={ "square", 0x30AF, 0x30EB, 0x30BC, 0x30A4, 0x30ED }, + unicodeslot=0x331A, + }, + [0x331B]={ + category="so", + cjkwd="w", + description="SQUARE KUROONE", + direction="l", + linebreak="id", + specials={ "square", 0x30AF, 0x30ED, 0x30FC, 0x30CD }, + unicodeslot=0x331B, + }, + [0x331C]={ + category="so", + cjkwd="w", + description="SQUARE KEESU", + direction="l", + linebreak="id", + specials={ "square", 0x30B1, 0x30FC, 0x30B9 }, + unicodeslot=0x331C, + }, + [0x331D]={ + category="so", + cjkwd="w", + description="SQUARE KORUNA", + direction="l", + linebreak="id", + specials={ "square", 0x30B3, 0x30EB, 0x30CA }, + unicodeslot=0x331D, + }, + [0x331E]={ + category="so", + cjkwd="w", + description="SQUARE KOOPO", + direction="l", + linebreak="id", + specials={ "square", 0x30B3, 0x30FC, 0x30DD }, + unicodeslot=0x331E, + }, + [0x331F]={ + category="so", + cjkwd="w", + description="SQUARE SAIKURU", + direction="l", + linebreak="id", + specials={ "square", 0x30B5, 0x30A4, 0x30AF, 0x30EB }, + unicodeslot=0x331F, + }, + [0x3320]={ + category="so", + cjkwd="w", + description="SQUARE SANTIIMU", + direction="l", + linebreak="id", + specials={ "square", 0x30B5, 0x30F3, 0x30C1, 0x30FC, 0x30E0 }, + unicodeslot=0x3320, + }, + [0x3321]={ + category="so", + cjkwd="w", + description="SQUARE SIRINGU", + direction="l", + linebreak="id", + specials={ "square", 0x30B7, 0x30EA, 0x30F3, 0x30B0 }, + unicodeslot=0x3321, + }, + [0x3322]={ + category="so", + cjkwd="w", + description="SQUARE SENTI", + direction="l", + linebreak="id", + specials={ "square", 0x30BB, 0x30F3, 0x30C1 }, + unicodeslot=0x3322, + }, + [0x3323]={ + category="so", + cjkwd="w", + description="SQUARE SENTO", + direction="l", + linebreak="id", + specials={ "square", 0x30BB, 0x30F3, 0x30C8 }, + unicodeslot=0x3323, + }, + [0x3324]={ + category="so", + cjkwd="w", + description="SQUARE DAASU", + direction="l", + linebreak="id", + specials={ "square", 0x30C0, 0x30FC, 0x30B9 }, + unicodeslot=0x3324, + }, + [0x3325]={ + category="so", + cjkwd="w", + description="SQUARE DESI", + direction="l", + linebreak="id", + specials={ "square", 0x30C7, 0x30B7 }, + unicodeslot=0x3325, + }, + [0x3326]={ + category="so", + cjkwd="w", + description="SQUARE DORU", + direction="l", + linebreak="id", + specials={ "square", 0x30C9, 0x30EB }, + unicodeslot=0x3326, + }, + [0x3327]={ + category="so", + cjkwd="w", + description="SQUARE TON", + direction="l", + linebreak="id", + specials={ "square", 0x30C8, 0x30F3 }, + unicodeslot=0x3327, + }, + [0x3328]={ + category="so", + cjkwd="w", + description="SQUARE NANO", + direction="l", + linebreak="id", + specials={ "square", 0x30CA, 0x30CE }, + unicodeslot=0x3328, + }, + [0x3329]={ + category="so", + cjkwd="w", + description="SQUARE NOTTO", + direction="l", + linebreak="id", + specials={ "square", 0x30CE, 0x30C3, 0x30C8 }, + unicodeslot=0x3329, + }, + [0x332A]={ + category="so", + cjkwd="w", + description="SQUARE HAITU", + direction="l", + linebreak="id", + specials={ "square", 0x30CF, 0x30A4, 0x30C4 }, + unicodeslot=0x332A, + }, + [0x332B]={ + category="so", + cjkwd="w", + description="SQUARE PAASENTO", + direction="l", + linebreak="id", + specials={ "square", 0x30D1, 0x30FC, 0x30BB, 0x30F3, 0x30C8 }, + unicodeslot=0x332B, + }, + [0x332C]={ + category="so", + cjkwd="w", + description="SQUARE PAATU", + direction="l", + linebreak="id", + specials={ "square", 0x30D1, 0x30FC, 0x30C4 }, + unicodeslot=0x332C, + }, + [0x332D]={ + category="so", + cjkwd="w", + description="SQUARE BAARERU", + direction="l", + linebreak="id", + specials={ "square", 0x30D0, 0x30FC, 0x30EC, 0x30EB }, + unicodeslot=0x332D, + }, + [0x332E]={ + category="so", + cjkwd="w", + description="SQUARE PIASUTORU", + direction="l", + linebreak="id", + specials={ "square", 0x30D4, 0x30A2, 0x30B9, 0x30C8, 0x30EB }, + unicodeslot=0x332E, + }, + [0x332F]={ + category="so", + cjkwd="w", + description="SQUARE PIKURU", + direction="l", + linebreak="id", + specials={ "square", 0x30D4, 0x30AF, 0x30EB }, + unicodeslot=0x332F, + }, + [0x3330]={ + category="so", + cjkwd="w", + description="SQUARE PIKO", + direction="l", + linebreak="id", + specials={ "square", 0x30D4, 0x30B3 }, + unicodeslot=0x3330, + }, + [0x3331]={ + category="so", + cjkwd="w", + description="SQUARE BIRU", + direction="l", + linebreak="id", + specials={ "square", 0x30D3, 0x30EB }, + unicodeslot=0x3331, + }, + [0x3332]={ + category="so", + cjkwd="w", + description="SQUARE HUARADDO", + direction="l", + linebreak="id", + specials={ "square", 0x30D5, 0x30A1, 0x30E9, 0x30C3, 0x30C9 }, + unicodeslot=0x3332, + }, + [0x3333]={ + category="so", + cjkwd="w", + description="SQUARE HUIITO", + direction="l", + linebreak="id", + specials={ "square", 0x30D5, 0x30A3, 0x30FC, 0x30C8 }, + unicodeslot=0x3333, + }, + [0x3334]={ + category="so", + cjkwd="w", + description="SQUARE BUSSYERU", + direction="l", + linebreak="id", + specials={ "square", 0x30D6, 0x30C3, 0x30B7, 0x30A7, 0x30EB }, + unicodeslot=0x3334, + }, + [0x3335]={ + category="so", + cjkwd="w", + description="SQUARE HURAN", + direction="l", + linebreak="id", + specials={ "square", 0x30D5, 0x30E9, 0x30F3 }, + unicodeslot=0x3335, + }, + [0x3336]={ + category="so", + cjkwd="w", + description="SQUARE HEKUTAARU", + direction="l", + linebreak="id", + specials={ "square", 0x30D8, 0x30AF, 0x30BF, 0x30FC, 0x30EB }, + unicodeslot=0x3336, + }, + [0x3337]={ + category="so", + cjkwd="w", + description="SQUARE PESO", + direction="l", + linebreak="id", + specials={ "square", 0x30DA, 0x30BD }, + unicodeslot=0x3337, + }, + [0x3338]={ + category="so", + cjkwd="w", + description="SQUARE PENIHI", + direction="l", + linebreak="id", + specials={ "square", 0x30DA, 0x30CB, 0x30D2 }, + unicodeslot=0x3338, + }, + [0x3339]={ + category="so", + cjkwd="w", + description="SQUARE HERUTU", + direction="l", + linebreak="id", + specials={ "square", 0x30D8, 0x30EB, 0x30C4 }, + unicodeslot=0x3339, + }, + [0x333A]={ + category="so", + cjkwd="w", + description="SQUARE PENSU", + direction="l", + linebreak="id", + specials={ "square", 0x30DA, 0x30F3, 0x30B9 }, + unicodeslot=0x333A, + }, + [0x333B]={ + category="so", + cjkwd="w", + description="SQUARE PEEZI", + direction="l", + linebreak="id", + specials={ "square", 0x30DA, 0x30FC, 0x30B8 }, + unicodeslot=0x333B, + }, + [0x333C]={ + category="so", + cjkwd="w", + description="SQUARE BEETA", + direction="l", + linebreak="id", + specials={ "square", 0x30D9, 0x30FC, 0x30BF }, + unicodeslot=0x333C, + }, + [0x333D]={ + category="so", + cjkwd="w", + description="SQUARE POINTO", + direction="l", + linebreak="id", + specials={ "square", 0x30DD, 0x30A4, 0x30F3, 0x30C8 }, + unicodeslot=0x333D, + }, + [0x333E]={ + category="so", + cjkwd="w", + description="SQUARE BORUTO", + direction="l", + linebreak="id", + specials={ "square", 0x30DC, 0x30EB, 0x30C8 }, + unicodeslot=0x333E, + }, + [0x333F]={ + category="so", + cjkwd="w", + description="SQUARE HON", + direction="l", + linebreak="id", + specials={ "square", 0x30DB, 0x30F3 }, + unicodeslot=0x333F, + }, + [0x3340]={ + category="so", + cjkwd="w", + description="SQUARE PONDO", + direction="l", + linebreak="id", + specials={ "square", 0x30DD, 0x30F3, 0x30C9 }, + unicodeslot=0x3340, + }, + [0x3341]={ + category="so", + cjkwd="w", + description="SQUARE HOORU", + direction="l", + linebreak="id", + specials={ "square", 0x30DB, 0x30FC, 0x30EB }, + unicodeslot=0x3341, + }, + [0x3342]={ + category="so", + cjkwd="w", + description="SQUARE HOON", + direction="l", + linebreak="id", + specials={ "square", 0x30DB, 0x30FC, 0x30F3 }, + unicodeslot=0x3342, + }, + [0x3343]={ + category="so", + cjkwd="w", + description="SQUARE MAIKURO", + direction="l", + linebreak="id", + specials={ "square", 0x30DE, 0x30A4, 0x30AF, 0x30ED }, + unicodeslot=0x3343, + }, + [0x3344]={ + category="so", + cjkwd="w", + description="SQUARE MAIRU", + direction="l", + linebreak="id", + specials={ "square", 0x30DE, 0x30A4, 0x30EB }, + unicodeslot=0x3344, + }, + [0x3345]={ + category="so", + cjkwd="w", + description="SQUARE MAHHA", + direction="l", + linebreak="id", + specials={ "square", 0x30DE, 0x30C3, 0x30CF }, + unicodeslot=0x3345, + }, + [0x3346]={ + category="so", + cjkwd="w", + description="SQUARE MARUKU", + direction="l", + linebreak="id", + specials={ "square", 0x30DE, 0x30EB, 0x30AF }, + unicodeslot=0x3346, + }, + [0x3347]={ + category="so", + cjkwd="w", + description="SQUARE MANSYON", + direction="l", + linebreak="id", + specials={ "square", 0x30DE, 0x30F3, 0x30B7, 0x30E7, 0x30F3 }, + unicodeslot=0x3347, + }, + [0x3348]={ + category="so", + cjkwd="w", + description="SQUARE MIKURON", + direction="l", + linebreak="id", + specials={ "square", 0x30DF, 0x30AF, 0x30ED, 0x30F3 }, + unicodeslot=0x3348, + }, + [0x3349]={ + category="so", + cjkwd="w", + description="SQUARE MIRI", + direction="l", + linebreak="id", + specials={ "square", 0x30DF, 0x30EA }, + unicodeslot=0x3349, + }, + [0x334A]={ + category="so", + cjkwd="w", + description="SQUARE MIRIBAARU", + direction="l", + linebreak="id", + specials={ "square", 0x30DF, 0x30EA, 0x30D0, 0x30FC, 0x30EB }, + unicodeslot=0x334A, + }, + [0x334B]={ + category="so", + cjkwd="w", + description="SQUARE MEGA", + direction="l", + linebreak="id", + specials={ "square", 0x30E1, 0x30AC }, + unicodeslot=0x334B, + }, + [0x334C]={ + category="so", + cjkwd="w", + description="SQUARE MEGATON", + direction="l", + linebreak="id", + specials={ "square", 0x30E1, 0x30AC, 0x30C8, 0x30F3 }, + unicodeslot=0x334C, + }, + [0x334D]={ + category="so", + cjkwd="w", + description="SQUARE MEETORU", + direction="l", + linebreak="id", + specials={ "square", 0x30E1, 0x30FC, 0x30C8, 0x30EB }, + unicodeslot=0x334D, + }, + [0x334E]={ + category="so", + cjkwd="w", + description="SQUARE YAADO", + direction="l", + linebreak="id", + specials={ "square", 0x30E4, 0x30FC, 0x30C9 }, + unicodeslot=0x334E, + }, + [0x334F]={ + category="so", + cjkwd="w", + description="SQUARE YAARU", + direction="l", + linebreak="id", + specials={ "square", 0x30E4, 0x30FC, 0x30EB }, + unicodeslot=0x334F, + }, + [0x3350]={ + category="so", + cjkwd="w", + description="SQUARE YUAN", + direction="l", + linebreak="id", + specials={ "square", 0x30E6, 0x30A2, 0x30F3 }, + unicodeslot=0x3350, + }, + [0x3351]={ + category="so", + cjkwd="w", + description="SQUARE RITTORU", + direction="l", + linebreak="id", + specials={ "square", 0x30EA, 0x30C3, 0x30C8, 0x30EB }, + unicodeslot=0x3351, + }, + [0x3352]={ + category="so", + cjkwd="w", + description="SQUARE RIRA", + direction="l", + linebreak="id", + specials={ "square", 0x30EA, 0x30E9 }, + unicodeslot=0x3352, + }, + [0x3353]={ + category="so", + cjkwd="w", + description="SQUARE RUPII", + direction="l", + linebreak="id", + specials={ "square", 0x30EB, 0x30D4, 0x30FC }, + unicodeslot=0x3353, + }, + [0x3354]={ + category="so", + cjkwd="w", + description="SQUARE RUUBURU", + direction="l", + linebreak="id", + specials={ "square", 0x30EB, 0x30FC, 0x30D6, 0x30EB }, + unicodeslot=0x3354, + }, + [0x3355]={ + category="so", + cjkwd="w", + description="SQUARE REMU", + direction="l", + linebreak="id", + specials={ "square", 0x30EC, 0x30E0 }, + unicodeslot=0x3355, + }, + [0x3356]={ + category="so", + cjkwd="w", + description="SQUARE RENTOGEN", + direction="l", + linebreak="id", + specials={ "square", 0x30EC, 0x30F3, 0x30C8, 0x30B2, 0x30F3 }, + unicodeslot=0x3356, + }, + [0x3357]={ + category="so", + cjkwd="w", + description="SQUARE WATTO", + direction="l", + linebreak="id", + specials={ "square", 0x30EF, 0x30C3, 0x30C8 }, + unicodeslot=0x3357, + }, + [0x3358]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ZERO", + direction="l", + linebreak="id", + specials={ "compat", 0x0030, 0x70B9 }, + unicodeslot=0x3358, + }, + [0x3359]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ONE", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x70B9 }, + unicodeslot=0x3359, + }, + [0x335A]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWO", + direction="l", + linebreak="id", + specials={ "compat", 0x0032, 0x70B9 }, + unicodeslot=0x335A, + }, + [0x335B]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THREE", + direction="l", + linebreak="id", + specials={ "compat", 0x0033, 0x70B9 }, + unicodeslot=0x335B, + }, + [0x335C]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOUR", + direction="l", + linebreak="id", + specials={ "compat", 0x0034, 0x70B9 }, + unicodeslot=0x335C, + }, + [0x335D]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIVE", + direction="l", + linebreak="id", + specials={ "compat", 0x0035, 0x70B9 }, + unicodeslot=0x335D, + }, + [0x335E]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIX", + direction="l", + linebreak="id", + specials={ "compat", 0x0036, 0x70B9 }, + unicodeslot=0x335E, + }, + [0x335F]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVEN", + direction="l", + linebreak="id", + specials={ "compat", 0x0037, 0x70B9 }, + unicodeslot=0x335F, + }, + [0x3360]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHT", + direction="l", + linebreak="id", + specials={ "compat", 0x0038, 0x70B9 }, + unicodeslot=0x3360, + }, + [0x3361]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINE", + direction="l", + linebreak="id", + specials={ "compat", 0x0039, 0x70B9 }, + unicodeslot=0x3361, + }, + [0x3362]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TEN", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x0030, 0x70B9 }, + unicodeslot=0x3362, + }, + [0x3363]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ELEVEN", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x0031, 0x70B9 }, + unicodeslot=0x3363, + }, + [0x3364]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWELVE", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x0032, 0x70B9 }, + unicodeslot=0x3364, + }, + [0x3365]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THIRTEEN", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x0033, 0x70B9 }, + unicodeslot=0x3365, + }, + [0x3366]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOURTEEN", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x0034, 0x70B9 }, + unicodeslot=0x3366, + }, + [0x3367]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIFTEEN", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x0035, 0x70B9 }, + unicodeslot=0x3367, + }, + [0x3368]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIXTEEN", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x0036, 0x70B9 }, + unicodeslot=0x3368, + }, + [0x3369]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVENTEEN", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x0037, 0x70B9 }, + unicodeslot=0x3369, + }, + [0x336A]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHTEEN", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x0038, 0x70B9 }, + unicodeslot=0x336A, + }, + [0x336B]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINETEEN", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x0039, 0x70B9 }, + unicodeslot=0x336B, + }, + [0x336C]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY", + direction="l", + linebreak="id", + specials={ "compat", 0x0032, 0x0030, 0x70B9 }, + unicodeslot=0x336C, + }, + [0x336D]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-ONE", + direction="l", + linebreak="id", + specials={ "compat", 0x0032, 0x0031, 0x70B9 }, + unicodeslot=0x336D, + }, + [0x336E]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-TWO", + direction="l", + linebreak="id", + specials={ "compat", 0x0032, 0x0032, 0x70B9 }, + unicodeslot=0x336E, + }, + [0x336F]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-THREE", + direction="l", + linebreak="id", + specials={ "compat", 0x0032, 0x0033, 0x70B9 }, + unicodeslot=0x336F, + }, + [0x3370]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-FOUR", + direction="l", + linebreak="id", + specials={ "compat", 0x0032, 0x0034, 0x70B9 }, + unicodeslot=0x3370, + }, + [0x3371]={ + category="so", + cjkwd="w", + description="SQUARE HPA", + direction="l", + linebreak="id", + specials={ "square", 0x0068, 0x0050, 0x0061 }, + unicodeslot=0x3371, + }, + [0x3372]={ + category="so", + cjkwd="w", + description="SQUARE DA", + direction="l", + linebreak="id", + specials={ "square", 0x0064, 0x0061 }, + unicodeslot=0x3372, + }, + [0x3373]={ + category="so", + cjkwd="w", + description="SQUARE AU", + direction="l", + linebreak="id", + specials={ "square", 0x0041, 0x0055 }, + unicodeslot=0x3373, + }, + [0x3374]={ + category="so", + cjkwd="w", + description="SQUARE BAR", + direction="l", + linebreak="id", + specials={ "square", 0x0062, 0x0061, 0x0072 }, + unicodeslot=0x3374, + }, + [0x3375]={ + category="so", + cjkwd="w", + description="SQUARE OV", + direction="l", + linebreak="id", + specials={ "square", 0x006F, 0x0056 }, + unicodeslot=0x3375, + }, + [0x3376]={ + category="so", + cjkwd="w", + description="SQUARE PC", + direction="l", + linebreak="id", + specials={ "square", 0x0070, 0x0063 }, + unicodeslot=0x3376, + }, + [0x3377]={ + category="so", + cjkwd="w", + description="SQUARE DM", + direction="on", + linebreak="id", + specials={ "square", 0x0064, 0x006D }, + unicodeslot=0x3377, + }, + [0x3378]={ + category="so", + cjkwd="w", + description="SQUARE DM SQUARED", + direction="on", + linebreak="id", + specials={ "square", 0x0064, 0x006D, 0x00B2 }, + unicodeslot=0x3378, + }, + [0x3379]={ + category="so", + cjkwd="w", + description="SQUARE DM CUBED", + direction="on", + linebreak="id", + specials={ "square", 0x0064, 0x006D, 0x00B3 }, + unicodeslot=0x3379, + }, + [0x337A]={ + category="so", + cjkwd="w", + description="SQUARE IU", + direction="on", + linebreak="id", + specials={ "square", 0x0049, 0x0055 }, + unicodeslot=0x337A, + }, + [0x337B]={ + category="so", + cjkwd="w", + description="SQUARE ERA NAME HEISEI", + direction="l", + linebreak="id", + specials={ "square", 0x5E73, 0x6210 }, + unicodeslot=0x337B, + }, + [0x337C]={ + category="so", + cjkwd="w", + description="SQUARE ERA NAME SYOUWA", + direction="l", + linebreak="id", + specials={ "square", 0x662D, 0x548C }, + unicodeslot=0x337C, + }, + [0x337D]={ + category="so", + cjkwd="w", + description="SQUARE ERA NAME TAISYOU", + direction="l", + linebreak="id", + specials={ "square", 0x5927, 0x6B63 }, + unicodeslot=0x337D, + }, + [0x337E]={ + category="so", + cjkwd="w", + description="SQUARE ERA NAME MEIZI", + direction="l", + linebreak="id", + specials={ "square", 0x660E, 0x6CBB }, + unicodeslot=0x337E, + }, + [0x337F]={ + category="so", + cjkwd="w", + description="SQUARE CORPORATION", + direction="l", + linebreak="id", + specials={ "square", 0x682A, 0x5F0F, 0x4F1A, 0x793E }, + unicodeslot=0x337F, + }, + [0x3380]={ + category="so", + cjkwd="w", + description="SQUARE PA AMPS", + direction="l", + linebreak="id", + specials={ "square", 0x0070, 0x0041 }, + unicodeslot=0x3380, + }, + [0x3381]={ + category="so", + cjkwd="w", + description="SQUARE NA", + direction="l", + linebreak="id", + specials={ "square", 0x006E, 0x0041 }, + unicodeslot=0x3381, + }, + [0x3382]={ + category="so", + cjkwd="w", + description="SQUARE MU A", + direction="l", + linebreak="id", + specials={ "square", 0x03BC, 0x0041 }, + unicodeslot=0x3382, + }, + [0x3383]={ + category="so", + cjkwd="w", + description="SQUARE MA", + direction="l", + linebreak="id", + specials={ "square", 0x006D, 0x0041 }, + unicodeslot=0x3383, + }, + [0x3384]={ + category="so", + cjkwd="w", + description="SQUARE KA", + direction="l", + linebreak="id", + specials={ "square", 0x006B, 0x0041 }, + unicodeslot=0x3384, + }, + [0x3385]={ + category="so", + cjkwd="w", + description="SQUARE KB", + direction="l", + linebreak="id", + specials={ "square", 0x004B, 0x0042 }, + unicodeslot=0x3385, + }, + [0x3386]={ + category="so", + cjkwd="w", + description="SQUARE MB", + direction="l", + linebreak="id", + specials={ "square", 0x004D, 0x0042 }, + unicodeslot=0x3386, + }, + [0x3387]={ + category="so", + cjkwd="w", + description="SQUARE GB", + direction="l", + linebreak="id", + specials={ "square", 0x0047, 0x0042 }, + unicodeslot=0x3387, + }, + [0x3388]={ + category="so", + cjkwd="w", + description="SQUARE CAL", + direction="l", + linebreak="id", + specials={ "square", 0x0063, 0x0061, 0x006C }, + unicodeslot=0x3388, + }, + [0x3389]={ + category="so", + cjkwd="w", + description="SQUARE KCAL", + direction="l", + linebreak="id", + specials={ "square", 0x006B, 0x0063, 0x0061, 0x006C }, + unicodeslot=0x3389, + }, + [0x338A]={ + category="so", + cjkwd="w", + description="SQUARE PF", + direction="l", + linebreak="id", + specials={ "square", 0x0070, 0x0046 }, + unicodeslot=0x338A, + }, + [0x338B]={ + category="so", + cjkwd="w", + description="SQUARE NF", + direction="l", + linebreak="id", + specials={ "square", 0x006E, 0x0046 }, + unicodeslot=0x338B, + }, + [0x338C]={ + category="so", + cjkwd="w", + description="SQUARE MU F", + direction="l", + linebreak="id", + specials={ "square", 0x03BC, 0x0046 }, + unicodeslot=0x338C, + }, + [0x338D]={ + category="so", + cjkwd="w", + description="SQUARE MU G", + direction="l", + linebreak="id", + specials={ "square", 0x03BC, 0x0067 }, + unicodeslot=0x338D, + }, + [0x338E]={ + category="so", + cjkwd="w", + description="SQUARE MG", + direction="l", + linebreak="id", + specials={ "square", 0x006D, 0x0067 }, + unicodeslot=0x338E, + }, + [0x338F]={ + category="so", + cjkwd="w", + description="SQUARE KG", + direction="l", + linebreak="id", + specials={ "square", 0x006B, 0x0067 }, + unicodeslot=0x338F, + }, + [0x3390]={ + category="so", + cjkwd="w", + description="SQUARE HZ", + direction="l", + linebreak="id", + specials={ "square", 0x0048, 0x007A }, + unicodeslot=0x3390, + }, + [0x3391]={ + category="so", + cjkwd="w", + description="SQUARE KHZ", + direction="l", + linebreak="id", + specials={ "square", 0x006B, 0x0048, 0x007A }, + unicodeslot=0x3391, + }, + [0x3392]={ + category="so", + cjkwd="w", + description="SQUARE MHZ", + direction="l", + linebreak="id", + specials={ "square", 0x004D, 0x0048, 0x007A }, + unicodeslot=0x3392, + }, + [0x3393]={ + category="so", + cjkwd="w", + description="SQUARE GHZ", + direction="l", + linebreak="id", + specials={ "square", 0x0047, 0x0048, 0x007A }, + unicodeslot=0x3393, + }, + [0x3394]={ + category="so", + cjkwd="w", + description="SQUARE THZ", + direction="l", + linebreak="id", + specials={ "square", 0x0054, 0x0048, 0x007A }, + unicodeslot=0x3394, + }, + [0x3395]={ + category="so", + cjkwd="w", + description="SQUARE MU L", + direction="l", + linebreak="id", + specials={ "square", 0x03BC, 0x2113 }, + unicodeslot=0x3395, + }, + [0x3396]={ + category="so", + cjkwd="w", + description="SQUARE ML", + direction="l", + linebreak="id", + specials={ "square", 0x006D, 0x2113 }, + unicodeslot=0x3396, + }, + [0x3397]={ + category="so", + cjkwd="w", + description="SQUARE DL", + direction="l", + linebreak="id", + specials={ "square", 0x0064, 0x2113 }, + unicodeslot=0x3397, + }, + [0x3398]={ + category="so", + cjkwd="w", + description="SQUARE KL", + direction="l", + linebreak="id", + specials={ "square", 0x006B, 0x2113 }, + unicodeslot=0x3398, + }, + [0x3399]={ + category="so", + cjkwd="w", + description="SQUARE FM", + direction="l", + linebreak="id", + specials={ "square", 0x0066, 0x006D }, + unicodeslot=0x3399, + }, + [0x339A]={ + category="so", + cjkwd="w", + description="SQUARE NM", + direction="l", + linebreak="id", + specials={ "square", 0x006E, 0x006D }, + unicodeslot=0x339A, + }, + [0x339B]={ + category="so", + cjkwd="w", + description="SQUARE MU M", + direction="l", + linebreak="id", + specials={ "square", 0x03BC, 0x006D }, + unicodeslot=0x339B, + }, + [0x339C]={ + category="so", + cjkwd="w", + description="SQUARE MM", + direction="l", + linebreak="id", + specials={ "square", 0x006D, 0x006D }, + unicodeslot=0x339C, + }, + [0x339D]={ + category="so", + cjkwd="w", + description="SQUARE CM", + direction="l", + linebreak="id", + specials={ "square", 0x0063, 0x006D }, + unicodeslot=0x339D, + }, + [0x339E]={ + category="so", + cjkwd="w", + description="SQUARE KM", + direction="l", + linebreak="id", + specials={ "square", 0x006B, 0x006D }, + unicodeslot=0x339E, + }, + [0x339F]={ + category="so", + cjkwd="w", + description="SQUARE MM SQUARED", + direction="l", + linebreak="id", + specials={ "square", 0x006D, 0x006D, 0x00B2 }, + unicodeslot=0x339F, + }, + [0x33A0]={ + category="so", + cjkwd="w", + description="SQUARE CM SQUARED", + direction="l", + linebreak="id", + specials={ "square", 0x0063, 0x006D, 0x00B2 }, + unicodeslot=0x33A0, + }, + [0x33A1]={ + category="so", + cjkwd="w", + description="SQUARE M SQUARED", + direction="l", + linebreak="id", + specials={ "square", 0x006D, 0x00B2 }, + unicodeslot=0x33A1, + }, + [0x33A2]={ + category="so", + cjkwd="w", + description="SQUARE KM SQUARED", + direction="l", + linebreak="id", + specials={ "square", 0x006B, 0x006D, 0x00B2 }, + unicodeslot=0x33A2, + }, + [0x33A3]={ + category="so", + cjkwd="w", + description="SQUARE MM CUBED", + direction="l", + linebreak="id", + specials={ "square", 0x006D, 0x006D, 0x00B3 }, + unicodeslot=0x33A3, + }, + [0x33A4]={ + category="so", + cjkwd="w", + description="SQUARE CM CUBED", + direction="l", + linebreak="id", + specials={ "square", 0x0063, 0x006D, 0x00B3 }, + unicodeslot=0x33A4, + }, + [0x33A5]={ + category="so", + cjkwd="w", + description="SQUARE M CUBED", + direction="l", + linebreak="id", + specials={ "square", 0x006D, 0x00B3 }, + unicodeslot=0x33A5, + }, + [0x33A6]={ + category="so", + cjkwd="w", + description="SQUARE KM CUBED", + direction="l", + linebreak="id", + specials={ "square", 0x006B, 0x006D, 0x00B3 }, + unicodeslot=0x33A6, + }, + [0x33A7]={ + category="so", + cjkwd="w", + description="SQUARE M OVER S", + direction="l", + linebreak="id", + specials={ "square", 0x006D, 0x2215, 0x0073 }, + unicodeslot=0x33A7, + }, + [0x33A8]={ + category="so", + cjkwd="w", + description="SQUARE M OVER S SQUARED", + direction="l", + linebreak="id", + specials={ "square", 0x006D, 0x2215, 0x0073, 0x00B2 }, + unicodeslot=0x33A8, + }, + [0x33A9]={ + category="so", + cjkwd="w", + description="SQUARE PA", + direction="l", + linebreak="id", + specials={ "square", 0x0050, 0x0061 }, + unicodeslot=0x33A9, + }, + [0x33AA]={ + category="so", + cjkwd="w", + description="SQUARE KPA", + direction="l", + linebreak="id", + specials={ "square", 0x006B, 0x0050, 0x0061 }, + unicodeslot=0x33AA, + }, + [0x33AB]={ + category="so", + cjkwd="w", + description="SQUARE MPA", + direction="l", + linebreak="id", + specials={ "square", 0x004D, 0x0050, 0x0061 }, + unicodeslot=0x33AB, + }, + [0x33AC]={ + category="so", + cjkwd="w", + description="SQUARE GPA", + direction="l", + linebreak="id", + specials={ "square", 0x0047, 0x0050, 0x0061 }, + unicodeslot=0x33AC, + }, + [0x33AD]={ + category="so", + cjkwd="w", + description="SQUARE RAD", + direction="l", + linebreak="id", + specials={ "square", 0x0072, 0x0061, 0x0064 }, + unicodeslot=0x33AD, + }, + [0x33AE]={ + category="so", + cjkwd="w", + description="SQUARE RAD OVER S", + direction="l", + linebreak="id", + specials={ "square", 0x0072, 0x0061, 0x0064, 0x2215, 0x0073 }, + unicodeslot=0x33AE, + }, + [0x33AF]={ + category="so", + cjkwd="w", + description="SQUARE RAD OVER S SQUARED", + direction="l", + linebreak="id", + specials={ "square", 0x0072, 0x0061, 0x0064, 0x2215, 0x0073, 0x00B2 }, + unicodeslot=0x33AF, + }, + [0x33B0]={ + category="so", + cjkwd="w", + description="SQUARE PS", + direction="l", + linebreak="id", + specials={ "square", 0x0070, 0x0073 }, + unicodeslot=0x33B0, + }, + [0x33B1]={ + category="so", + cjkwd="w", + description="SQUARE NS", + direction="l", + linebreak="id", + specials={ "square", 0x006E, 0x0073 }, + unicodeslot=0x33B1, + }, + [0x33B2]={ + category="so", + cjkwd="w", + description="SQUARE MU S", + direction="l", + linebreak="id", + specials={ "square", 0x03BC, 0x0073 }, + unicodeslot=0x33B2, + }, + [0x33B3]={ + category="so", + cjkwd="w", + description="SQUARE MS", + direction="l", + linebreak="id", + specials={ "square", 0x006D, 0x0073 }, + unicodeslot=0x33B3, + }, + [0x33B4]={ + category="so", + cjkwd="w", + description="SQUARE PV", + direction="l", + linebreak="id", + specials={ "square", 0x0070, 0x0056 }, + unicodeslot=0x33B4, + }, + [0x33B5]={ + category="so", + cjkwd="w", + description="SQUARE NV", + direction="l", + linebreak="id", + specials={ "square", 0x006E, 0x0056 }, + unicodeslot=0x33B5, + }, + [0x33B6]={ + category="so", + cjkwd="w", + description="SQUARE MU V", + direction="l", + linebreak="id", + specials={ "square", 0x03BC, 0x0056 }, + unicodeslot=0x33B6, + }, + [0x33B7]={ + category="so", + cjkwd="w", + description="SQUARE MV", + direction="l", + linebreak="id", + specials={ "square", 0x006D, 0x0056 }, + unicodeslot=0x33B7, + }, + [0x33B8]={ + category="so", + cjkwd="w", + description="SQUARE KV", + direction="l", + linebreak="id", + specials={ "square", 0x006B, 0x0056 }, + unicodeslot=0x33B8, + }, + [0x33B9]={ + category="so", + cjkwd="w", + description="SQUARE MV MEGA", + direction="l", + linebreak="id", + specials={ "square", 0x004D, 0x0056 }, + unicodeslot=0x33B9, + }, + [0x33BA]={ + category="so", + cjkwd="w", + description="SQUARE PW", + direction="l", + linebreak="id", + specials={ "square", 0x0070, 0x0057 }, + unicodeslot=0x33BA, + }, + [0x33BB]={ + category="so", + cjkwd="w", + description="SQUARE NW", + direction="l", + linebreak="id", + specials={ "square", 0x006E, 0x0057 }, + unicodeslot=0x33BB, + }, + [0x33BC]={ + category="so", + cjkwd="w", + description="SQUARE MU W", + direction="l", + linebreak="id", + specials={ "square", 0x03BC, 0x0057 }, + unicodeslot=0x33BC, + }, + [0x33BD]={ + category="so", + cjkwd="w", + description="SQUARE MW", + direction="l", + linebreak="id", + specials={ "square", 0x006D, 0x0057 }, + unicodeslot=0x33BD, + }, + [0x33BE]={ + category="so", + cjkwd="w", + description="SQUARE KW", + direction="l", + linebreak="id", + specials={ "square", 0x006B, 0x0057 }, + unicodeslot=0x33BE, + }, + [0x33BF]={ + category="so", + cjkwd="w", + description="SQUARE MW MEGA", + direction="l", + linebreak="id", + specials={ "square", 0x004D, 0x0057 }, + unicodeslot=0x33BF, + }, + [0x33C0]={ + category="so", + cjkwd="w", + description="SQUARE K OHM", + direction="l", + linebreak="id", + specials={ "square", 0x006B, 0x03A9 }, + unicodeslot=0x33C0, + }, + [0x33C1]={ + category="so", + cjkwd="w", + description="SQUARE M OHM", + direction="l", + linebreak="id", + specials={ "square", 0x004D, 0x03A9 }, + unicodeslot=0x33C1, + }, + [0x33C2]={ + category="so", + cjkwd="w", + description="SQUARE AM", + direction="l", + linebreak="id", + specials={ "square", 0x0061, 0x002E, 0x006D, 0x002E }, + unicodeslot=0x33C2, + }, + [0x33C3]={ + category="so", + cjkwd="w", + description="SQUARE BQ", + direction="l", + linebreak="id", + specials={ "square", 0x0042, 0x0071 }, + unicodeslot=0x33C3, + }, + [0x33C4]={ + category="so", + cjkwd="w", + description="SQUARE CC", + direction="l", + linebreak="id", + specials={ "square", 0x0063, 0x0063 }, + unicodeslot=0x33C4, + }, + [0x33C5]={ + category="so", + cjkwd="w", + description="SQUARE CD", + direction="l", + linebreak="id", + specials={ "square", 0x0063, 0x0064 }, + unicodeslot=0x33C5, + }, + [0x33C6]={ + category="so", + cjkwd="w", + description="SQUARE C OVER KG", + direction="l", + linebreak="id", + specials={ "square", 0x0043, 0x2215, 0x006B, 0x0067 }, + unicodeslot=0x33C6, + }, + [0x33C7]={ + category="so", + cjkwd="w", + description="SQUARE CO", + direction="l", + linebreak="id", + specials={ "square", 0x0043, 0x006F, 0x002E }, + unicodeslot=0x33C7, + }, + [0x33C8]={ + category="so", + cjkwd="w", + description="SQUARE DB", + direction="l", + linebreak="id", + specials={ "square", 0x0064, 0x0042 }, + unicodeslot=0x33C8, + }, + [0x33C9]={ + category="so", + cjkwd="w", + description="SQUARE GY", + direction="l", + linebreak="id", + specials={ "square", 0x0047, 0x0079 }, + unicodeslot=0x33C9, + }, + [0x33CA]={ + category="so", + cjkwd="w", + description="SQUARE HA", + direction="l", + linebreak="id", + specials={ "square", 0x0068, 0x0061 }, + unicodeslot=0x33CA, + }, + [0x33CB]={ + category="so", + cjkwd="w", + description="SQUARE HP", + direction="l", + linebreak="id", + specials={ "square", 0x0048, 0x0050 }, + unicodeslot=0x33CB, + }, + [0x33CC]={ + category="so", + cjkwd="w", + description="SQUARE IN", + direction="l", + linebreak="id", + specials={ "square", 0x0069, 0x006E }, + unicodeslot=0x33CC, + }, + [0x33CD]={ + category="so", + cjkwd="w", + description="SQUARE KK", + direction="l", + linebreak="id", + specials={ "square", 0x004B, 0x004B }, + unicodeslot=0x33CD, + }, + [0x33CE]={ + category="so", + cjkwd="w", + description="SQUARE KM CAPITAL", + direction="l", + linebreak="id", + specials={ "square", 0x004B, 0x004D }, + unicodeslot=0x33CE, + }, + [0x33CF]={ + category="so", + cjkwd="w", + description="SQUARE KT", + direction="l", + linebreak="id", + specials={ "square", 0x006B, 0x0074 }, + unicodeslot=0x33CF, + }, + [0x33D0]={ + category="so", + cjkwd="w", + description="SQUARE LM", + direction="l", + linebreak="id", + specials={ "square", 0x006C, 0x006D }, + unicodeslot=0x33D0, + }, + [0x33D1]={ + category="so", + cjkwd="w", + description="SQUARE LN", + direction="l", + linebreak="id", + specials={ "square", 0x006C, 0x006E }, + unicodeslot=0x33D1, + }, + [0x33D2]={ + category="so", + cjkwd="w", + description="SQUARE LOG", + direction="l", + linebreak="id", + specials={ "square", 0x006C, 0x006F, 0x0067 }, + unicodeslot=0x33D2, + }, + [0x33D3]={ + category="so", + cjkwd="w", + description="SQUARE LX", + direction="l", + linebreak="id", + specials={ "square", 0x006C, 0x0078 }, + unicodeslot=0x33D3, + }, + [0x33D4]={ + category="so", + cjkwd="w", + description="SQUARE MB SMALL", + direction="l", + linebreak="id", + specials={ "square", 0x006D, 0x0062 }, + unicodeslot=0x33D4, + }, + [0x33D5]={ + category="so", + cjkwd="w", + description="SQUARE MIL", + direction="l", + linebreak="id", + specials={ "square", 0x006D, 0x0069, 0x006C }, + unicodeslot=0x33D5, + }, + [0x33D6]={ + category="so", + cjkwd="w", + description="SQUARE MOL", + direction="l", + linebreak="id", + specials={ "square", 0x006D, 0x006F, 0x006C }, + unicodeslot=0x33D6, + }, + [0x33D7]={ + category="so", + cjkwd="w", + description="SQUARE PH", + direction="l", + linebreak="id", + specials={ "square", 0x0050, 0x0048 }, + unicodeslot=0x33D7, + }, + [0x33D8]={ + category="so", + cjkwd="w", + description="SQUARE PM", + direction="l", + linebreak="id", + specials={ "square", 0x0070, 0x002E, 0x006D, 0x002E }, + unicodeslot=0x33D8, + }, + [0x33D9]={ + category="so", + cjkwd="w", + description="SQUARE PPM", + direction="l", + linebreak="id", + specials={ "square", 0x0050, 0x0050, 0x004D }, + unicodeslot=0x33D9, + }, + [0x33DA]={ + category="so", + cjkwd="w", + description="SQUARE PR", + direction="l", + linebreak="id", + specials={ "square", 0x0050, 0x0052 }, + unicodeslot=0x33DA, + }, + [0x33DB]={ + category="so", + cjkwd="w", + description="SQUARE SR", + direction="l", + linebreak="id", + specials={ "square", 0x0073, 0x0072 }, + unicodeslot=0x33DB, + }, + [0x33DC]={ + category="so", + cjkwd="w", + description="SQUARE SV", + direction="l", + linebreak="id", + specials={ "square", 0x0053, 0x0076 }, + unicodeslot=0x33DC, + }, + [0x33DD]={ + category="so", + cjkwd="w", + description="SQUARE WB", + direction="l", + linebreak="id", + specials={ "square", 0x0057, 0x0062 }, + unicodeslot=0x33DD, + }, + [0x33DE]={ + category="so", + cjkwd="w", + description="SQUARE V OVER M", + direction="on", + linebreak="id", + specials={ "square", 0x0056, 0x2215, 0x006D }, + unicodeslot=0x33DE, + }, + [0x33DF]={ + category="so", + cjkwd="w", + description="SQUARE A OVER M", + direction="on", + linebreak="id", + specials={ "square", 0x0041, 0x2215, 0x006D }, + unicodeslot=0x33DF, + }, + [0x33E0]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ONE", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x65E5 }, + unicodeslot=0x33E0, + }, + [0x33E1]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWO", + direction="l", + linebreak="id", + specials={ "compat", 0x0032, 0x65E5 }, + unicodeslot=0x33E1, + }, + [0x33E2]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THREE", + direction="l", + linebreak="id", + specials={ "compat", 0x0033, 0x65E5 }, + unicodeslot=0x33E2, + }, + [0x33E3]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOUR", + direction="l", + linebreak="id", + specials={ "compat", 0x0034, 0x65E5 }, + unicodeslot=0x33E3, + }, + [0x33E4]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIVE", + direction="l", + linebreak="id", + specials={ "compat", 0x0035, 0x65E5 }, + unicodeslot=0x33E4, + }, + [0x33E5]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIX", + direction="l", + linebreak="id", + specials={ "compat", 0x0036, 0x65E5 }, + unicodeslot=0x33E5, + }, + [0x33E6]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVEN", + direction="l", + linebreak="id", + specials={ "compat", 0x0037, 0x65E5 }, + unicodeslot=0x33E6, + }, + [0x33E7]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHT", + direction="l", + linebreak="id", + specials={ "compat", 0x0038, 0x65E5 }, + unicodeslot=0x33E7, + }, + [0x33E8]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINE", + direction="l", + linebreak="id", + specials={ "compat", 0x0039, 0x65E5 }, + unicodeslot=0x33E8, + }, + [0x33E9]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TEN", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x0030, 0x65E5 }, + unicodeslot=0x33E9, + }, + [0x33EA]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ELEVEN", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x0031, 0x65E5 }, + unicodeslot=0x33EA, + }, + [0x33EB]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWELVE", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x0032, 0x65E5 }, + unicodeslot=0x33EB, + }, + [0x33EC]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTEEN", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x0033, 0x65E5 }, + unicodeslot=0x33EC, + }, + [0x33ED]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOURTEEN", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x0034, 0x65E5 }, + unicodeslot=0x33ED, + }, + [0x33EE]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIFTEEN", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x0035, 0x65E5 }, + unicodeslot=0x33EE, + }, + [0x33EF]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIXTEEN", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x0036, 0x65E5 }, + unicodeslot=0x33EF, + }, + [0x33F0]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVENTEEN", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x0037, 0x65E5 }, + unicodeslot=0x33F0, + }, + [0x33F1]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHTEEN", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x0038, 0x65E5 }, + unicodeslot=0x33F1, + }, + [0x33F2]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINETEEN", + direction="l", + linebreak="id", + specials={ "compat", 0x0031, 0x0039, 0x65E5 }, + unicodeslot=0x33F2, + }, + [0x33F3]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY", + direction="l", + linebreak="id", + specials={ "compat", 0x0032, 0x0030, 0x65E5 }, + unicodeslot=0x33F3, + }, + [0x33F4]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-ONE", + direction="l", + linebreak="id", + specials={ "compat", 0x0032, 0x0031, 0x65E5 }, + unicodeslot=0x33F4, + }, + [0x33F5]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-TWO", + direction="l", + linebreak="id", + specials={ "compat", 0x0032, 0x0032, 0x65E5 }, + unicodeslot=0x33F5, + }, + [0x33F6]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-THREE", + direction="l", + linebreak="id", + specials={ "compat", 0x0032, 0x0033, 0x65E5 }, + unicodeslot=0x33F6, + }, + [0x33F7]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FOUR", + direction="l", + linebreak="id", + specials={ "compat", 0x0032, 0x0034, 0x65E5 }, + unicodeslot=0x33F7, + }, + [0x33F8]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FIVE", + direction="l", + linebreak="id", + specials={ "compat", 0x0032, 0x0035, 0x65E5 }, + unicodeslot=0x33F8, + }, + [0x33F9]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SIX", + direction="l", + linebreak="id", + specials={ "compat", 0x0032, 0x0036, 0x65E5 }, + unicodeslot=0x33F9, + }, + [0x33FA]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SEVEN", + direction="l", + linebreak="id", + specials={ "compat", 0x0032, 0x0037, 0x65E5 }, + unicodeslot=0x33FA, + }, + [0x33FB]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-EIGHT", + direction="l", + linebreak="id", + specials={ "compat", 0x0032, 0x0038, 0x65E5 }, + unicodeslot=0x33FB, + }, + [0x33FC]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-NINE", + direction="l", + linebreak="id", + specials={ "compat", 0x0032, 0x0039, 0x65E5 }, + unicodeslot=0x33FC, + }, + [0x33FD]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY", + direction="l", + linebreak="id", + specials={ "compat", 0x0033, 0x0030, 0x65E5 }, + unicodeslot=0x33FD, + }, + [0x33FE]={ + category="so", + cjkwd="w", + description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY-ONE", + direction="l", + linebreak="id", + specials={ "compat", 0x0033, 0x0031, 0x65E5 }, + unicodeslot=0x33FE, + }, + [0x33FF]={ + category="so", + cjkwd="w", + description="SQUARE GAL", + direction="on", + linebreak="id", + specials={ "square", 0x0067, 0x0061, 0x006C }, + unicodeslot=0x33FF, + }, + [0x3400]={ + category="lo", + cjkwd="w", + description="", + direction="l", + linebreak="id", + unicodeslot=0x3400, + range= 0x4DB5, + }, + [0x4DC0]={ + category="so", + description="HEXAGRAM FOR THE CREATIVE HEAVEN", + direction="on", + linebreak="al", + unicodeslot=0x4DC0, + }, + [0x4DC1]={ + category="so", + description="HEXAGRAM FOR THE RECEPTIVE EARTH", + direction="on", + linebreak="al", + unicodeslot=0x4DC1, + }, + [0x4DC2]={ + category="so", + description="HEXAGRAM FOR DIFFICULTY AT THE BEGINNING", + direction="on", + linebreak="al", + unicodeslot=0x4DC2, + }, + [0x4DC3]={ + category="so", + description="HEXAGRAM FOR YOUTHFUL FOLLY", + direction="on", + linebreak="al", + unicodeslot=0x4DC3, + }, + [0x4DC4]={ + category="so", + description="HEXAGRAM FOR WAITING", + direction="on", + linebreak="al", + unicodeslot=0x4DC4, + }, + [0x4DC5]={ + category="so", + description="HEXAGRAM FOR CONFLICT", + direction="on", + linebreak="al", + unicodeslot=0x4DC5, + }, + [0x4DC6]={ + category="so", + description="HEXAGRAM FOR THE ARMY", + direction="on", + linebreak="al", + unicodeslot=0x4DC6, + }, + [0x4DC7]={ + category="so", + description="HEXAGRAM FOR HOLDING TOGETHER", + direction="on", + linebreak="al", + unicodeslot=0x4DC7, + }, + [0x4DC8]={ + category="so", + description="HEXAGRAM FOR SMALL TAMING", + direction="on", + linebreak="al", + unicodeslot=0x4DC8, + }, + [0x4DC9]={ + category="so", + description="HEXAGRAM FOR TREADING", + direction="on", + linebreak="al", + unicodeslot=0x4DC9, + }, + [0x4DCA]={ + category="so", + description="HEXAGRAM FOR PEACE", + direction="on", + linebreak="al", + unicodeslot=0x4DCA, + }, + [0x4DCB]={ + category="so", + description="HEXAGRAM FOR STANDSTILL", + direction="on", + linebreak="al", + unicodeslot=0x4DCB, + }, + [0x4DCC]={ + category="so", + description="HEXAGRAM FOR FELLOWSHIP", + direction="on", + linebreak="al", + unicodeslot=0x4DCC, + }, + [0x4DCD]={ + category="so", + description="HEXAGRAM FOR GREAT POSSESSION", + direction="on", + linebreak="al", + unicodeslot=0x4DCD, + }, + [0x4DCE]={ + category="so", + description="HEXAGRAM FOR MODESTY", + direction="on", + linebreak="al", + unicodeslot=0x4DCE, + }, + [0x4DCF]={ + category="so", + description="HEXAGRAM FOR ENTHUSIASM", + direction="on", + linebreak="al", + unicodeslot=0x4DCF, + }, + [0x4DD0]={ + category="so", + description="HEXAGRAM FOR FOLLOWING", + direction="on", + linebreak="al", + unicodeslot=0x4DD0, + }, + [0x4DD1]={ + category="so", + description="HEXAGRAM FOR WORK ON THE DECAYED", + direction="on", + linebreak="al", + unicodeslot=0x4DD1, + }, + [0x4DD2]={ + category="so", + description="HEXAGRAM FOR APPROACH", + direction="on", + linebreak="al", + unicodeslot=0x4DD2, + }, + [0x4DD3]={ + category="so", + description="HEXAGRAM FOR CONTEMPLATION", + direction="on", + linebreak="al", + unicodeslot=0x4DD3, + }, + [0x4DD4]={ + category="so", + description="HEXAGRAM FOR BITING THROUGH", + direction="on", + linebreak="al", + unicodeslot=0x4DD4, + }, + [0x4DD5]={ + category="so", + description="HEXAGRAM FOR GRACE", + direction="on", + linebreak="al", + unicodeslot=0x4DD5, + }, + [0x4DD6]={ + category="so", + description="HEXAGRAM FOR SPLITTING APART", + direction="on", + linebreak="al", + unicodeslot=0x4DD6, + }, + [0x4DD7]={ + category="so", + description="HEXAGRAM FOR RETURN", + direction="on", + linebreak="al", + unicodeslot=0x4DD7, + }, + [0x4DD8]={ + category="so", + description="HEXAGRAM FOR INNOCENCE", + direction="on", + linebreak="al", + unicodeslot=0x4DD8, + }, + [0x4DD9]={ + category="so", + description="HEXAGRAM FOR GREAT TAMING", + direction="on", + linebreak="al", + unicodeslot=0x4DD9, + }, + [0x4DDA]={ + category="so", + description="HEXAGRAM FOR MOUTH CORNERS", + direction="on", + linebreak="al", + unicodeslot=0x4DDA, + }, + [0x4DDB]={ + category="so", + description="HEXAGRAM FOR GREAT PREPONDERANCE", + direction="on", + linebreak="al", + unicodeslot=0x4DDB, + }, + [0x4DDC]={ + category="so", + description="HEXAGRAM FOR THE ABYSMAL WATER", + direction="on", + linebreak="al", + unicodeslot=0x4DDC, + }, + [0x4DDD]={ + category="so", + description="HEXAGRAM FOR THE CLINGING FIRE", + direction="on", + linebreak="al", + unicodeslot=0x4DDD, + }, + [0x4DDE]={ + category="so", + description="HEXAGRAM FOR INFLUENCE", + direction="on", + linebreak="al", + unicodeslot=0x4DDE, + }, + [0x4DDF]={ + category="so", + description="HEXAGRAM FOR DURATION", + direction="on", + linebreak="al", + unicodeslot=0x4DDF, + }, + [0x4DE0]={ + category="so", + description="HEXAGRAM FOR RETREAT", + direction="on", + linebreak="al", + unicodeslot=0x4DE0, + }, + [0x4DE1]={ + category="so", + description="HEXAGRAM FOR GREAT POWER", + direction="on", + linebreak="al", + unicodeslot=0x4DE1, + }, + [0x4DE2]={ + category="so", + description="HEXAGRAM FOR PROGRESS", + direction="on", + linebreak="al", + unicodeslot=0x4DE2, + }, + [0x4DE3]={ + category="so", + description="HEXAGRAM FOR DARKENING OF THE LIGHT", + direction="on", + linebreak="al", + unicodeslot=0x4DE3, + }, + [0x4DE4]={ + category="so", + description="HEXAGRAM FOR THE FAMILY", + direction="on", + linebreak="al", + unicodeslot=0x4DE4, + }, + [0x4DE5]={ + category="so", + description="HEXAGRAM FOR OPPOSITION", + direction="on", + linebreak="al", + unicodeslot=0x4DE5, + }, + [0x4DE6]={ + category="so", + description="HEXAGRAM FOR OBSTRUCTION", + direction="on", + linebreak="al", + unicodeslot=0x4DE6, + }, + [0x4DE7]={ + category="so", + description="HEXAGRAM FOR DELIVERANCE", + direction="on", + linebreak="al", + unicodeslot=0x4DE7, + }, + [0x4DE8]={ + category="so", + description="HEXAGRAM FOR DECREASE", + direction="on", + linebreak="al", + unicodeslot=0x4DE8, + }, + [0x4DE9]={ + category="so", + description="HEXAGRAM FOR INCREASE", + direction="on", + linebreak="al", + unicodeslot=0x4DE9, + }, + [0x4DEA]={ + category="so", + description="HEXAGRAM FOR BREAKTHROUGH", + direction="on", + linebreak="al", + unicodeslot=0x4DEA, + }, + [0x4DEB]={ + category="so", + description="HEXAGRAM FOR COMING TO MEET", + direction="on", + linebreak="al", + unicodeslot=0x4DEB, + }, + [0x4DEC]={ + category="so", + description="HEXAGRAM FOR GATHERING TOGETHER", + direction="on", + linebreak="al", + unicodeslot=0x4DEC, + }, + [0x4DED]={ + category="so", + description="HEXAGRAM FOR PUSHING UPWARD", + direction="on", + linebreak="al", + unicodeslot=0x4DED, + }, + [0x4DEE]={ + category="so", + description="HEXAGRAM FOR OPPRESSION", + direction="on", + linebreak="al", + unicodeslot=0x4DEE, + }, + [0x4DEF]={ + category="so", + description="HEXAGRAM FOR THE WELL", + direction="on", + linebreak="al", + unicodeslot=0x4DEF, + }, + [0x4DF0]={ + category="so", + description="HEXAGRAM FOR REVOLUTION", + direction="on", + linebreak="al", + unicodeslot=0x4DF0, + }, + [0x4DF1]={ + category="so", + description="HEXAGRAM FOR THE CAULDRON", + direction="on", + linebreak="al", + unicodeslot=0x4DF1, + }, + [0x4DF2]={ + category="so", + description="HEXAGRAM FOR THE AROUSING THUNDER", + direction="on", + linebreak="al", + unicodeslot=0x4DF2, + }, + [0x4DF3]={ + category="so", + description="HEXAGRAM FOR THE KEEPING STILL MOUNTAIN", + direction="on", + linebreak="al", + unicodeslot=0x4DF3, + }, + [0x4DF4]={ + category="so", + description="HEXAGRAM FOR DEVELOPMENT", + direction="on", + linebreak="al", + unicodeslot=0x4DF4, + }, + [0x4DF5]={ + category="so", + description="HEXAGRAM FOR THE MARRYING MAIDEN", + direction="on", + linebreak="al", + unicodeslot=0x4DF5, + }, + [0x4DF6]={ + category="so", + description="HEXAGRAM FOR ABUNDANCE", + direction="on", + linebreak="al", + unicodeslot=0x4DF6, + }, + [0x4DF7]={ + category="so", + description="HEXAGRAM FOR THE WANDERER", + direction="on", + linebreak="al", + unicodeslot=0x4DF7, + }, + [0x4DF8]={ + category="so", + description="HEXAGRAM FOR THE GENTLE WIND", + direction="on", + linebreak="al", + unicodeslot=0x4DF8, + }, + [0x4DF9]={ + category="so", + description="HEXAGRAM FOR THE JOYOUS LAKE", + direction="on", + linebreak="al", + unicodeslot=0x4DF9, + }, + [0x4DFA]={ + category="so", + description="HEXAGRAM FOR DISPERSION", + direction="on", + linebreak="al", + unicodeslot=0x4DFA, + }, + [0x4DFB]={ + category="so", + description="HEXAGRAM FOR LIMITATION", + direction="on", + linebreak="al", + unicodeslot=0x4DFB, + }, + [0x4DFC]={ + category="so", + description="HEXAGRAM FOR INNER TRUTH", + direction="on", + linebreak="al", + unicodeslot=0x4DFC, + }, + [0x4DFD]={ + category="so", + description="HEXAGRAM FOR SMALL PREPONDERANCE", + direction="on", + linebreak="al", + unicodeslot=0x4DFD, + }, + [0x4DFE]={ + category="so", + description="HEXAGRAM FOR AFTER COMPLETION", + direction="on", + linebreak="al", + unicodeslot=0x4DFE, + }, + [0x4DFF]={ + category="so", + description="HEXAGRAM FOR BEFORE COMPLETION", + direction="on", + linebreak="al", + unicodeslot=0x4DFF, + }, + [0x4E00]={ + category="lo", + cjkwd="w", + description="", + direction="l", + linebreak="id", + unicodeslot=0x4E00, + range=0x9FBB, + }, + [0xA000]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE IT", + direction="l", + linebreak="id", + unicodeslot=0xA000, + }, + [0xA001]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE IX", + direction="l", + linebreak="id", + unicodeslot=0xA001, + }, + [0xA002]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE I", + direction="l", + linebreak="id", + unicodeslot=0xA002, + }, + [0xA003]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE IP", + direction="l", + linebreak="id", + unicodeslot=0xA003, + }, + [0xA004]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE IET", + direction="l", + linebreak="id", + unicodeslot=0xA004, + }, + [0xA005]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE IEX", + direction="l", + linebreak="id", + unicodeslot=0xA005, + }, + [0xA006]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE IE", + direction="l", + linebreak="id", + unicodeslot=0xA006, + }, + [0xA007]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE IEP", + direction="l", + linebreak="id", + unicodeslot=0xA007, + }, + [0xA008]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE AT", + direction="l", + linebreak="id", + unicodeslot=0xA008, + }, + [0xA009]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE AX", + direction="l", + linebreak="id", + unicodeslot=0xA009, + }, + [0xA00A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE A", + direction="l", + linebreak="id", + unicodeslot=0xA00A, + }, + [0xA00B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE AP", + direction="l", + linebreak="id", + unicodeslot=0xA00B, + }, + [0xA00C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE UOX", + direction="l", + linebreak="id", + unicodeslot=0xA00C, + }, + [0xA00D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE UO", + direction="l", + linebreak="id", + unicodeslot=0xA00D, + }, + [0xA00E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE UOP", + direction="l", + linebreak="id", + unicodeslot=0xA00E, + }, + [0xA00F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE OT", + direction="l", + linebreak="id", + unicodeslot=0xA00F, + }, + [0xA010]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE OX", + direction="l", + linebreak="id", + unicodeslot=0xA010, + }, + [0xA011]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE O", + direction="l", + linebreak="id", + unicodeslot=0xA011, + }, + [0xA012]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE OP", + direction="l", + linebreak="id", + unicodeslot=0xA012, + }, + [0xA013]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE EX", + direction="l", + linebreak="id", + unicodeslot=0xA013, + }, + [0xA014]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE E", + direction="l", + linebreak="id", + unicodeslot=0xA014, + }, + [0xA015]={ + category="lm", + cjkwd="w", + description="YI SYLLABLE WU", + direction="l", + linebreak="ns", + unicodeslot=0xA015, + }, + [0xA016]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BIT", + direction="l", + linebreak="id", + unicodeslot=0xA016, + }, + [0xA017]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BIX", + direction="l", + linebreak="id", + unicodeslot=0xA017, + }, + [0xA018]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BI", + direction="l", + linebreak="id", + unicodeslot=0xA018, + }, + [0xA019]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BIP", + direction="l", + linebreak="id", + unicodeslot=0xA019, + }, + [0xA01A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BIET", + direction="l", + linebreak="id", + unicodeslot=0xA01A, + }, + [0xA01B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BIEX", + direction="l", + linebreak="id", + unicodeslot=0xA01B, + }, + [0xA01C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BIE", + direction="l", + linebreak="id", + unicodeslot=0xA01C, + }, + [0xA01D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BIEP", + direction="l", + linebreak="id", + unicodeslot=0xA01D, + }, + [0xA01E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BAT", + direction="l", + linebreak="id", + unicodeslot=0xA01E, + }, + [0xA01F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BAX", + direction="l", + linebreak="id", + unicodeslot=0xA01F, + }, + [0xA020]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BA", + direction="l", + linebreak="id", + unicodeslot=0xA020, + }, + [0xA021]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BAP", + direction="l", + linebreak="id", + unicodeslot=0xA021, + }, + [0xA022]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BUOX", + direction="l", + linebreak="id", + unicodeslot=0xA022, + }, + [0xA023]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BUO", + direction="l", + linebreak="id", + unicodeslot=0xA023, + }, + [0xA024]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BUOP", + direction="l", + linebreak="id", + unicodeslot=0xA024, + }, + [0xA025]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BOT", + direction="l", + linebreak="id", + unicodeslot=0xA025, + }, + [0xA026]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BOX", + direction="l", + linebreak="id", + unicodeslot=0xA026, + }, + [0xA027]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BO", + direction="l", + linebreak="id", + unicodeslot=0xA027, + }, + [0xA028]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BOP", + direction="l", + linebreak="id", + unicodeslot=0xA028, + }, + [0xA029]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BEX", + direction="l", + linebreak="id", + unicodeslot=0xA029, + }, + [0xA02A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BE", + direction="l", + linebreak="id", + unicodeslot=0xA02A, + }, + [0xA02B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BEP", + direction="l", + linebreak="id", + unicodeslot=0xA02B, + }, + [0xA02C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BUT", + direction="l", + linebreak="id", + unicodeslot=0xA02C, + }, + [0xA02D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BUX", + direction="l", + linebreak="id", + unicodeslot=0xA02D, + }, + [0xA02E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BU", + direction="l", + linebreak="id", + unicodeslot=0xA02E, + }, + [0xA02F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BUP", + direction="l", + linebreak="id", + unicodeslot=0xA02F, + }, + [0xA030]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BURX", + direction="l", + linebreak="id", + unicodeslot=0xA030, + }, + [0xA031]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BUR", + direction="l", + linebreak="id", + unicodeslot=0xA031, + }, + [0xA032]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BYT", + direction="l", + linebreak="id", + unicodeslot=0xA032, + }, + [0xA033]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BYX", + direction="l", + linebreak="id", + unicodeslot=0xA033, + }, + [0xA034]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BY", + direction="l", + linebreak="id", + unicodeslot=0xA034, + }, + [0xA035]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BYP", + direction="l", + linebreak="id", + unicodeslot=0xA035, + }, + [0xA036]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BYRX", + direction="l", + linebreak="id", + unicodeslot=0xA036, + }, + [0xA037]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BYR", + direction="l", + linebreak="id", + unicodeslot=0xA037, + }, + [0xA038]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PIT", + direction="l", + linebreak="id", + unicodeslot=0xA038, + }, + [0xA039]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PIX", + direction="l", + linebreak="id", + unicodeslot=0xA039, + }, + [0xA03A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PI", + direction="l", + linebreak="id", + unicodeslot=0xA03A, + }, + [0xA03B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PIP", + direction="l", + linebreak="id", + unicodeslot=0xA03B, + }, + [0xA03C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PIEX", + direction="l", + linebreak="id", + unicodeslot=0xA03C, + }, + [0xA03D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PIE", + direction="l", + linebreak="id", + unicodeslot=0xA03D, + }, + [0xA03E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PIEP", + direction="l", + linebreak="id", + unicodeslot=0xA03E, + }, + [0xA03F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PAT", + direction="l", + linebreak="id", + unicodeslot=0xA03F, + }, + [0xA040]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PAX", + direction="l", + linebreak="id", + unicodeslot=0xA040, + }, + [0xA041]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PA", + direction="l", + linebreak="id", + unicodeslot=0xA041, + }, + [0xA042]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PAP", + direction="l", + linebreak="id", + unicodeslot=0xA042, + }, + [0xA043]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PUOX", + direction="l", + linebreak="id", + unicodeslot=0xA043, + }, + [0xA044]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PUO", + direction="l", + linebreak="id", + unicodeslot=0xA044, + }, + [0xA045]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PUOP", + direction="l", + linebreak="id", + unicodeslot=0xA045, + }, + [0xA046]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE POT", + direction="l", + linebreak="id", + unicodeslot=0xA046, + }, + [0xA047]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE POX", + direction="l", + linebreak="id", + unicodeslot=0xA047, + }, + [0xA048]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PO", + direction="l", + linebreak="id", + unicodeslot=0xA048, + }, + [0xA049]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE POP", + direction="l", + linebreak="id", + unicodeslot=0xA049, + }, + [0xA04A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PUT", + direction="l", + linebreak="id", + unicodeslot=0xA04A, + }, + [0xA04B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PUX", + direction="l", + linebreak="id", + unicodeslot=0xA04B, + }, + [0xA04C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PU", + direction="l", + linebreak="id", + unicodeslot=0xA04C, + }, + [0xA04D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PUP", + direction="l", + linebreak="id", + unicodeslot=0xA04D, + }, + [0xA04E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PURX", + direction="l", + linebreak="id", + unicodeslot=0xA04E, + }, + [0xA04F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PUR", + direction="l", + linebreak="id", + unicodeslot=0xA04F, + }, + [0xA050]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PYT", + direction="l", + linebreak="id", + unicodeslot=0xA050, + }, + [0xA051]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PYX", + direction="l", + linebreak="id", + unicodeslot=0xA051, + }, + [0xA052]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PY", + direction="l", + linebreak="id", + unicodeslot=0xA052, + }, + [0xA053]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PYP", + direction="l", + linebreak="id", + unicodeslot=0xA053, + }, + [0xA054]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PYRX", + direction="l", + linebreak="id", + unicodeslot=0xA054, + }, + [0xA055]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE PYR", + direction="l", + linebreak="id", + unicodeslot=0xA055, + }, + [0xA056]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBIT", + direction="l", + linebreak="id", + unicodeslot=0xA056, + }, + [0xA057]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBIX", + direction="l", + linebreak="id", + unicodeslot=0xA057, + }, + [0xA058]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBI", + direction="l", + linebreak="id", + unicodeslot=0xA058, + }, + [0xA059]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBIP", + direction="l", + linebreak="id", + unicodeslot=0xA059, + }, + [0xA05A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBIET", + direction="l", + linebreak="id", + unicodeslot=0xA05A, + }, + [0xA05B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBIEX", + direction="l", + linebreak="id", + unicodeslot=0xA05B, + }, + [0xA05C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBIE", + direction="l", + linebreak="id", + unicodeslot=0xA05C, + }, + [0xA05D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBIEP", + direction="l", + linebreak="id", + unicodeslot=0xA05D, + }, + [0xA05E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBAT", + direction="l", + linebreak="id", + unicodeslot=0xA05E, + }, + [0xA05F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBAX", + direction="l", + linebreak="id", + unicodeslot=0xA05F, + }, + [0xA060]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBA", + direction="l", + linebreak="id", + unicodeslot=0xA060, + }, + [0xA061]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBAP", + direction="l", + linebreak="id", + unicodeslot=0xA061, + }, + [0xA062]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBUOX", + direction="l", + linebreak="id", + unicodeslot=0xA062, + }, + [0xA063]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBUO", + direction="l", + linebreak="id", + unicodeslot=0xA063, + }, + [0xA064]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBUOP", + direction="l", + linebreak="id", + unicodeslot=0xA064, + }, + [0xA065]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBOT", + direction="l", + linebreak="id", + unicodeslot=0xA065, + }, + [0xA066]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBOX", + direction="l", + linebreak="id", + unicodeslot=0xA066, + }, + [0xA067]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBO", + direction="l", + linebreak="id", + unicodeslot=0xA067, + }, + [0xA068]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBOP", + direction="l", + linebreak="id", + unicodeslot=0xA068, + }, + [0xA069]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBEX", + direction="l", + linebreak="id", + unicodeslot=0xA069, + }, + [0xA06A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBE", + direction="l", + linebreak="id", + unicodeslot=0xA06A, + }, + [0xA06B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBEP", + direction="l", + linebreak="id", + unicodeslot=0xA06B, + }, + [0xA06C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBUT", + direction="l", + linebreak="id", + unicodeslot=0xA06C, + }, + [0xA06D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBUX", + direction="l", + linebreak="id", + unicodeslot=0xA06D, + }, + [0xA06E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBU", + direction="l", + linebreak="id", + unicodeslot=0xA06E, + }, + [0xA06F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBUP", + direction="l", + linebreak="id", + unicodeslot=0xA06F, + }, + [0xA070]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBURX", + direction="l", + linebreak="id", + unicodeslot=0xA070, + }, + [0xA071]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBUR", + direction="l", + linebreak="id", + unicodeslot=0xA071, + }, + [0xA072]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBYT", + direction="l", + linebreak="id", + unicodeslot=0xA072, + }, + [0xA073]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBYX", + direction="l", + linebreak="id", + unicodeslot=0xA073, + }, + [0xA074]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBY", + direction="l", + linebreak="id", + unicodeslot=0xA074, + }, + [0xA075]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE BBYP", + direction="l", + linebreak="id", + unicodeslot=0xA075, + }, + [0xA076]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBIT", + direction="l", + linebreak="id", + unicodeslot=0xA076, + }, + [0xA077]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBIX", + direction="l", + linebreak="id", + unicodeslot=0xA077, + }, + [0xA078]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBI", + direction="l", + linebreak="id", + unicodeslot=0xA078, + }, + [0xA079]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBIP", + direction="l", + linebreak="id", + unicodeslot=0xA079, + }, + [0xA07A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBIEX", + direction="l", + linebreak="id", + unicodeslot=0xA07A, + }, + [0xA07B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBIE", + direction="l", + linebreak="id", + unicodeslot=0xA07B, + }, + [0xA07C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBIEP", + direction="l", + linebreak="id", + unicodeslot=0xA07C, + }, + [0xA07D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBAT", + direction="l", + linebreak="id", + unicodeslot=0xA07D, + }, + [0xA07E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBAX", + direction="l", + linebreak="id", + unicodeslot=0xA07E, + }, + [0xA07F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBA", + direction="l", + linebreak="id", + unicodeslot=0xA07F, + }, + [0xA080]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBAP", + direction="l", + linebreak="id", + unicodeslot=0xA080, + }, + [0xA081]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBOT", + direction="l", + linebreak="id", + unicodeslot=0xA081, + }, + [0xA082]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBOX", + direction="l", + linebreak="id", + unicodeslot=0xA082, + }, + [0xA083]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBO", + direction="l", + linebreak="id", + unicodeslot=0xA083, + }, + [0xA084]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBOP", + direction="l", + linebreak="id", + unicodeslot=0xA084, + }, + [0xA085]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBUT", + direction="l", + linebreak="id", + unicodeslot=0xA085, + }, + [0xA086]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBUX", + direction="l", + linebreak="id", + unicodeslot=0xA086, + }, + [0xA087]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBU", + direction="l", + linebreak="id", + unicodeslot=0xA087, + }, + [0xA088]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBUP", + direction="l", + linebreak="id", + unicodeslot=0xA088, + }, + [0xA089]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBURX", + direction="l", + linebreak="id", + unicodeslot=0xA089, + }, + [0xA08A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBUR", + direction="l", + linebreak="id", + unicodeslot=0xA08A, + }, + [0xA08B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBYT", + direction="l", + linebreak="id", + unicodeslot=0xA08B, + }, + [0xA08C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBYX", + direction="l", + linebreak="id", + unicodeslot=0xA08C, + }, + [0xA08D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBY", + direction="l", + linebreak="id", + unicodeslot=0xA08D, + }, + [0xA08E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBYP", + direction="l", + linebreak="id", + unicodeslot=0xA08E, + }, + [0xA08F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBYRX", + direction="l", + linebreak="id", + unicodeslot=0xA08F, + }, + [0xA090]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NBYR", + direction="l", + linebreak="id", + unicodeslot=0xA090, + }, + [0xA091]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMIT", + direction="l", + linebreak="id", + unicodeslot=0xA091, + }, + [0xA092]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMIX", + direction="l", + linebreak="id", + unicodeslot=0xA092, + }, + [0xA093]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMI", + direction="l", + linebreak="id", + unicodeslot=0xA093, + }, + [0xA094]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMIP", + direction="l", + linebreak="id", + unicodeslot=0xA094, + }, + [0xA095]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMIEX", + direction="l", + linebreak="id", + unicodeslot=0xA095, + }, + [0xA096]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMIE", + direction="l", + linebreak="id", + unicodeslot=0xA096, + }, + [0xA097]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMIEP", + direction="l", + linebreak="id", + unicodeslot=0xA097, + }, + [0xA098]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMAT", + direction="l", + linebreak="id", + unicodeslot=0xA098, + }, + [0xA099]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMAX", + direction="l", + linebreak="id", + unicodeslot=0xA099, + }, + [0xA09A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMA", + direction="l", + linebreak="id", + unicodeslot=0xA09A, + }, + [0xA09B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMAP", + direction="l", + linebreak="id", + unicodeslot=0xA09B, + }, + [0xA09C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMUOX", + direction="l", + linebreak="id", + unicodeslot=0xA09C, + }, + [0xA09D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMUO", + direction="l", + linebreak="id", + unicodeslot=0xA09D, + }, + [0xA09E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMUOP", + direction="l", + linebreak="id", + unicodeslot=0xA09E, + }, + [0xA09F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMOT", + direction="l", + linebreak="id", + unicodeslot=0xA09F, + }, + [0xA0A0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMOX", + direction="l", + linebreak="id", + unicodeslot=0xA0A0, + }, + [0xA0A1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMO", + direction="l", + linebreak="id", + unicodeslot=0xA0A1, + }, + [0xA0A2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMOP", + direction="l", + linebreak="id", + unicodeslot=0xA0A2, + }, + [0xA0A3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMUT", + direction="l", + linebreak="id", + unicodeslot=0xA0A3, + }, + [0xA0A4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMUX", + direction="l", + linebreak="id", + unicodeslot=0xA0A4, + }, + [0xA0A5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMU", + direction="l", + linebreak="id", + unicodeslot=0xA0A5, + }, + [0xA0A6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMUP", + direction="l", + linebreak="id", + unicodeslot=0xA0A6, + }, + [0xA0A7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMURX", + direction="l", + linebreak="id", + unicodeslot=0xA0A7, + }, + [0xA0A8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMUR", + direction="l", + linebreak="id", + unicodeslot=0xA0A8, + }, + [0xA0A9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMYX", + direction="l", + linebreak="id", + unicodeslot=0xA0A9, + }, + [0xA0AA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMY", + direction="l", + linebreak="id", + unicodeslot=0xA0AA, + }, + [0xA0AB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMYP", + direction="l", + linebreak="id", + unicodeslot=0xA0AB, + }, + [0xA0AC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMYRX", + direction="l", + linebreak="id", + unicodeslot=0xA0AC, + }, + [0xA0AD]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HMYR", + direction="l", + linebreak="id", + unicodeslot=0xA0AD, + }, + [0xA0AE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MIT", + direction="l", + linebreak="id", + unicodeslot=0xA0AE, + }, + [0xA0AF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MIX", + direction="l", + linebreak="id", + unicodeslot=0xA0AF, + }, + [0xA0B0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MI", + direction="l", + linebreak="id", + unicodeslot=0xA0B0, + }, + [0xA0B1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MIP", + direction="l", + linebreak="id", + unicodeslot=0xA0B1, + }, + [0xA0B2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MIEX", + direction="l", + linebreak="id", + unicodeslot=0xA0B2, + }, + [0xA0B3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MIE", + direction="l", + linebreak="id", + unicodeslot=0xA0B3, + }, + [0xA0B4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MIEP", + direction="l", + linebreak="id", + unicodeslot=0xA0B4, + }, + [0xA0B5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MAT", + direction="l", + linebreak="id", + unicodeslot=0xA0B5, + }, + [0xA0B6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MAX", + direction="l", + linebreak="id", + unicodeslot=0xA0B6, + }, + [0xA0B7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MA", + direction="l", + linebreak="id", + unicodeslot=0xA0B7, + }, + [0xA0B8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MAP", + direction="l", + linebreak="id", + unicodeslot=0xA0B8, + }, + [0xA0B9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MUOT", + direction="l", + linebreak="id", + unicodeslot=0xA0B9, + }, + [0xA0BA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MUOX", + direction="l", + linebreak="id", + unicodeslot=0xA0BA, + }, + [0xA0BB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MUO", + direction="l", + linebreak="id", + unicodeslot=0xA0BB, + }, + [0xA0BC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MUOP", + direction="l", + linebreak="id", + unicodeslot=0xA0BC, + }, + [0xA0BD]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MOT", + direction="l", + linebreak="id", + unicodeslot=0xA0BD, + }, + [0xA0BE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MOX", + direction="l", + linebreak="id", + unicodeslot=0xA0BE, + }, + [0xA0BF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MO", + direction="l", + linebreak="id", + unicodeslot=0xA0BF, + }, + [0xA0C0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MOP", + direction="l", + linebreak="id", + unicodeslot=0xA0C0, + }, + [0xA0C1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MEX", + direction="l", + linebreak="id", + unicodeslot=0xA0C1, + }, + [0xA0C2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ME", + direction="l", + linebreak="id", + unicodeslot=0xA0C2, + }, + [0xA0C3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MUT", + direction="l", + linebreak="id", + unicodeslot=0xA0C3, + }, + [0xA0C4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MUX", + direction="l", + linebreak="id", + unicodeslot=0xA0C4, + }, + [0xA0C5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MU", + direction="l", + linebreak="id", + unicodeslot=0xA0C5, + }, + [0xA0C6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MUP", + direction="l", + linebreak="id", + unicodeslot=0xA0C6, + }, + [0xA0C7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MURX", + direction="l", + linebreak="id", + unicodeslot=0xA0C7, + }, + [0xA0C8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MUR", + direction="l", + linebreak="id", + unicodeslot=0xA0C8, + }, + [0xA0C9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MYT", + direction="l", + linebreak="id", + unicodeslot=0xA0C9, + }, + [0xA0CA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MYX", + direction="l", + linebreak="id", + unicodeslot=0xA0CA, + }, + [0xA0CB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MY", + direction="l", + linebreak="id", + unicodeslot=0xA0CB, + }, + [0xA0CC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MYP", + direction="l", + linebreak="id", + unicodeslot=0xA0CC, + }, + [0xA0CD]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE FIT", + direction="l", + linebreak="id", + unicodeslot=0xA0CD, + }, + [0xA0CE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE FIX", + direction="l", + linebreak="id", + unicodeslot=0xA0CE, + }, + [0xA0CF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE FI", + direction="l", + linebreak="id", + unicodeslot=0xA0CF, + }, + [0xA0D0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE FIP", + direction="l", + linebreak="id", + unicodeslot=0xA0D0, + }, + [0xA0D1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE FAT", + direction="l", + linebreak="id", + unicodeslot=0xA0D1, + }, + [0xA0D2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE FAX", + direction="l", + linebreak="id", + unicodeslot=0xA0D2, + }, + [0xA0D3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE FA", + direction="l", + linebreak="id", + unicodeslot=0xA0D3, + }, + [0xA0D4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE FAP", + direction="l", + linebreak="id", + unicodeslot=0xA0D4, + }, + [0xA0D5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE FOX", + direction="l", + linebreak="id", + unicodeslot=0xA0D5, + }, + [0xA0D6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE FO", + direction="l", + linebreak="id", + unicodeslot=0xA0D6, + }, + [0xA0D7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE FOP", + direction="l", + linebreak="id", + unicodeslot=0xA0D7, + }, + [0xA0D8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE FUT", + direction="l", + linebreak="id", + unicodeslot=0xA0D8, + }, + [0xA0D9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE FUX", + direction="l", + linebreak="id", + unicodeslot=0xA0D9, + }, + [0xA0DA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE FU", + direction="l", + linebreak="id", + unicodeslot=0xA0DA, + }, + [0xA0DB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE FUP", + direction="l", + linebreak="id", + unicodeslot=0xA0DB, + }, + [0xA0DC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE FURX", + direction="l", + linebreak="id", + unicodeslot=0xA0DC, + }, + [0xA0DD]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE FUR", + direction="l", + linebreak="id", + unicodeslot=0xA0DD, + }, + [0xA0DE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE FYT", + direction="l", + linebreak="id", + unicodeslot=0xA0DE, + }, + [0xA0DF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE FYX", + direction="l", + linebreak="id", + unicodeslot=0xA0DF, + }, + [0xA0E0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE FY", + direction="l", + linebreak="id", + unicodeslot=0xA0E0, + }, + [0xA0E1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE FYP", + direction="l", + linebreak="id", + unicodeslot=0xA0E1, + }, + [0xA0E2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VIT", + direction="l", + linebreak="id", + unicodeslot=0xA0E2, + }, + [0xA0E3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VIX", + direction="l", + linebreak="id", + unicodeslot=0xA0E3, + }, + [0xA0E4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VI", + direction="l", + linebreak="id", + unicodeslot=0xA0E4, + }, + [0xA0E5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VIP", + direction="l", + linebreak="id", + unicodeslot=0xA0E5, + }, + [0xA0E6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VIET", + direction="l", + linebreak="id", + unicodeslot=0xA0E6, + }, + [0xA0E7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VIEX", + direction="l", + linebreak="id", + unicodeslot=0xA0E7, + }, + [0xA0E8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VIE", + direction="l", + linebreak="id", + unicodeslot=0xA0E8, + }, + [0xA0E9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VIEP", + direction="l", + linebreak="id", + unicodeslot=0xA0E9, + }, + [0xA0EA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VAT", + direction="l", + linebreak="id", + unicodeslot=0xA0EA, + }, + [0xA0EB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VAX", + direction="l", + linebreak="id", + unicodeslot=0xA0EB, + }, + [0xA0EC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VA", + direction="l", + linebreak="id", + unicodeslot=0xA0EC, + }, + [0xA0ED]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VAP", + direction="l", + linebreak="id", + unicodeslot=0xA0ED, + }, + [0xA0EE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VOT", + direction="l", + linebreak="id", + unicodeslot=0xA0EE, + }, + [0xA0EF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VOX", + direction="l", + linebreak="id", + unicodeslot=0xA0EF, + }, + [0xA0F0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VO", + direction="l", + linebreak="id", + unicodeslot=0xA0F0, + }, + [0xA0F1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VOP", + direction="l", + linebreak="id", + unicodeslot=0xA0F1, + }, + [0xA0F2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VEX", + direction="l", + linebreak="id", + unicodeslot=0xA0F2, + }, + [0xA0F3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VEP", + direction="l", + linebreak="id", + unicodeslot=0xA0F3, + }, + [0xA0F4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VUT", + direction="l", + linebreak="id", + unicodeslot=0xA0F4, + }, + [0xA0F5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VUX", + direction="l", + linebreak="id", + unicodeslot=0xA0F5, + }, + [0xA0F6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VU", + direction="l", + linebreak="id", + unicodeslot=0xA0F6, + }, + [0xA0F7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VUP", + direction="l", + linebreak="id", + unicodeslot=0xA0F7, + }, + [0xA0F8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VURX", + direction="l", + linebreak="id", + unicodeslot=0xA0F8, + }, + [0xA0F9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VUR", + direction="l", + linebreak="id", + unicodeslot=0xA0F9, + }, + [0xA0FA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VYT", + direction="l", + linebreak="id", + unicodeslot=0xA0FA, + }, + [0xA0FB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VYX", + direction="l", + linebreak="id", + unicodeslot=0xA0FB, + }, + [0xA0FC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VY", + direction="l", + linebreak="id", + unicodeslot=0xA0FC, + }, + [0xA0FD]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VYP", + direction="l", + linebreak="id", + unicodeslot=0xA0FD, + }, + [0xA0FE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VYRX", + direction="l", + linebreak="id", + unicodeslot=0xA0FE, + }, + [0xA0FF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE VYR", + direction="l", + linebreak="id", + unicodeslot=0xA0FF, + }, + [0xA100]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DIT", + direction="l", + linebreak="id", + unicodeslot=0xA100, + }, + [0xA101]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DIX", + direction="l", + linebreak="id", + unicodeslot=0xA101, + }, + [0xA102]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DI", + direction="l", + linebreak="id", + unicodeslot=0xA102, + }, + [0xA103]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DIP", + direction="l", + linebreak="id", + unicodeslot=0xA103, + }, + [0xA104]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DIEX", + direction="l", + linebreak="id", + unicodeslot=0xA104, + }, + [0xA105]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DIE", + direction="l", + linebreak="id", + unicodeslot=0xA105, + }, + [0xA106]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DIEP", + direction="l", + linebreak="id", + unicodeslot=0xA106, + }, + [0xA107]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DAT", + direction="l", + linebreak="id", + unicodeslot=0xA107, + }, + [0xA108]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DAX", + direction="l", + linebreak="id", + unicodeslot=0xA108, + }, + [0xA109]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DA", + direction="l", + linebreak="id", + unicodeslot=0xA109, + }, + [0xA10A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DAP", + direction="l", + linebreak="id", + unicodeslot=0xA10A, + }, + [0xA10B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DUOX", + direction="l", + linebreak="id", + unicodeslot=0xA10B, + }, + [0xA10C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DUO", + direction="l", + linebreak="id", + unicodeslot=0xA10C, + }, + [0xA10D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DOT", + direction="l", + linebreak="id", + unicodeslot=0xA10D, + }, + [0xA10E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DOX", + direction="l", + linebreak="id", + unicodeslot=0xA10E, + }, + [0xA10F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DO", + direction="l", + linebreak="id", + unicodeslot=0xA10F, + }, + [0xA110]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DOP", + direction="l", + linebreak="id", + unicodeslot=0xA110, + }, + [0xA111]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DEX", + direction="l", + linebreak="id", + unicodeslot=0xA111, + }, + [0xA112]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DE", + direction="l", + linebreak="id", + unicodeslot=0xA112, + }, + [0xA113]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DEP", + direction="l", + linebreak="id", + unicodeslot=0xA113, + }, + [0xA114]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DUT", + direction="l", + linebreak="id", + unicodeslot=0xA114, + }, + [0xA115]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DUX", + direction="l", + linebreak="id", + unicodeslot=0xA115, + }, + [0xA116]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DU", + direction="l", + linebreak="id", + unicodeslot=0xA116, + }, + [0xA117]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DUP", + direction="l", + linebreak="id", + unicodeslot=0xA117, + }, + [0xA118]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DURX", + direction="l", + linebreak="id", + unicodeslot=0xA118, + }, + [0xA119]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DUR", + direction="l", + linebreak="id", + unicodeslot=0xA119, + }, + [0xA11A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TIT", + direction="l", + linebreak="id", + unicodeslot=0xA11A, + }, + [0xA11B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TIX", + direction="l", + linebreak="id", + unicodeslot=0xA11B, + }, + [0xA11C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TI", + direction="l", + linebreak="id", + unicodeslot=0xA11C, + }, + [0xA11D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TIP", + direction="l", + linebreak="id", + unicodeslot=0xA11D, + }, + [0xA11E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TIEX", + direction="l", + linebreak="id", + unicodeslot=0xA11E, + }, + [0xA11F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TIE", + direction="l", + linebreak="id", + unicodeslot=0xA11F, + }, + [0xA120]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TIEP", + direction="l", + linebreak="id", + unicodeslot=0xA120, + }, + [0xA121]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TAT", + direction="l", + linebreak="id", + unicodeslot=0xA121, + }, + [0xA122]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TAX", + direction="l", + linebreak="id", + unicodeslot=0xA122, + }, + [0xA123]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TA", + direction="l", + linebreak="id", + unicodeslot=0xA123, + }, + [0xA124]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TAP", + direction="l", + linebreak="id", + unicodeslot=0xA124, + }, + [0xA125]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TUOT", + direction="l", + linebreak="id", + unicodeslot=0xA125, + }, + [0xA126]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TUOX", + direction="l", + linebreak="id", + unicodeslot=0xA126, + }, + [0xA127]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TUO", + direction="l", + linebreak="id", + unicodeslot=0xA127, + }, + [0xA128]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TUOP", + direction="l", + linebreak="id", + unicodeslot=0xA128, + }, + [0xA129]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TOT", + direction="l", + linebreak="id", + unicodeslot=0xA129, + }, + [0xA12A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TOX", + direction="l", + linebreak="id", + unicodeslot=0xA12A, + }, + [0xA12B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TO", + direction="l", + linebreak="id", + unicodeslot=0xA12B, + }, + [0xA12C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TOP", + direction="l", + linebreak="id", + unicodeslot=0xA12C, + }, + [0xA12D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TEX", + direction="l", + linebreak="id", + unicodeslot=0xA12D, + }, + [0xA12E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TE", + direction="l", + linebreak="id", + unicodeslot=0xA12E, + }, + [0xA12F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TEP", + direction="l", + linebreak="id", + unicodeslot=0xA12F, + }, + [0xA130]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TUT", + direction="l", + linebreak="id", + unicodeslot=0xA130, + }, + [0xA131]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TUX", + direction="l", + linebreak="id", + unicodeslot=0xA131, + }, + [0xA132]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TU", + direction="l", + linebreak="id", + unicodeslot=0xA132, + }, + [0xA133]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TUP", + direction="l", + linebreak="id", + unicodeslot=0xA133, + }, + [0xA134]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TURX", + direction="l", + linebreak="id", + unicodeslot=0xA134, + }, + [0xA135]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE TUR", + direction="l", + linebreak="id", + unicodeslot=0xA135, + }, + [0xA136]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDIT", + direction="l", + linebreak="id", + unicodeslot=0xA136, + }, + [0xA137]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDIX", + direction="l", + linebreak="id", + unicodeslot=0xA137, + }, + [0xA138]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDI", + direction="l", + linebreak="id", + unicodeslot=0xA138, + }, + [0xA139]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDIP", + direction="l", + linebreak="id", + unicodeslot=0xA139, + }, + [0xA13A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDIEX", + direction="l", + linebreak="id", + unicodeslot=0xA13A, + }, + [0xA13B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDIE", + direction="l", + linebreak="id", + unicodeslot=0xA13B, + }, + [0xA13C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDIEP", + direction="l", + linebreak="id", + unicodeslot=0xA13C, + }, + [0xA13D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDAT", + direction="l", + linebreak="id", + unicodeslot=0xA13D, + }, + [0xA13E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDAX", + direction="l", + linebreak="id", + unicodeslot=0xA13E, + }, + [0xA13F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDA", + direction="l", + linebreak="id", + unicodeslot=0xA13F, + }, + [0xA140]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDAP", + direction="l", + linebreak="id", + unicodeslot=0xA140, + }, + [0xA141]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDUOX", + direction="l", + linebreak="id", + unicodeslot=0xA141, + }, + [0xA142]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDUO", + direction="l", + linebreak="id", + unicodeslot=0xA142, + }, + [0xA143]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDUOP", + direction="l", + linebreak="id", + unicodeslot=0xA143, + }, + [0xA144]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDOT", + direction="l", + linebreak="id", + unicodeslot=0xA144, + }, + [0xA145]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDOX", + direction="l", + linebreak="id", + unicodeslot=0xA145, + }, + [0xA146]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDO", + direction="l", + linebreak="id", + unicodeslot=0xA146, + }, + [0xA147]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDOP", + direction="l", + linebreak="id", + unicodeslot=0xA147, + }, + [0xA148]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDEX", + direction="l", + linebreak="id", + unicodeslot=0xA148, + }, + [0xA149]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDE", + direction="l", + linebreak="id", + unicodeslot=0xA149, + }, + [0xA14A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDEP", + direction="l", + linebreak="id", + unicodeslot=0xA14A, + }, + [0xA14B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDUT", + direction="l", + linebreak="id", + unicodeslot=0xA14B, + }, + [0xA14C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDUX", + direction="l", + linebreak="id", + unicodeslot=0xA14C, + }, + [0xA14D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDU", + direction="l", + linebreak="id", + unicodeslot=0xA14D, + }, + [0xA14E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDUP", + direction="l", + linebreak="id", + unicodeslot=0xA14E, + }, + [0xA14F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDURX", + direction="l", + linebreak="id", + unicodeslot=0xA14F, + }, + [0xA150]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE DDUR", + direction="l", + linebreak="id", + unicodeslot=0xA150, + }, + [0xA151]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NDIT", + direction="l", + linebreak="id", + unicodeslot=0xA151, + }, + [0xA152]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NDIX", + direction="l", + linebreak="id", + unicodeslot=0xA152, + }, + [0xA153]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NDI", + direction="l", + linebreak="id", + unicodeslot=0xA153, + }, + [0xA154]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NDIP", + direction="l", + linebreak="id", + unicodeslot=0xA154, + }, + [0xA155]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NDIEX", + direction="l", + linebreak="id", + unicodeslot=0xA155, + }, + [0xA156]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NDIE", + direction="l", + linebreak="id", + unicodeslot=0xA156, + }, + [0xA157]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NDAT", + direction="l", + linebreak="id", + unicodeslot=0xA157, + }, + [0xA158]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NDAX", + direction="l", + linebreak="id", + unicodeslot=0xA158, + }, + [0xA159]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NDA", + direction="l", + linebreak="id", + unicodeslot=0xA159, + }, + [0xA15A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NDAP", + direction="l", + linebreak="id", + unicodeslot=0xA15A, + }, + [0xA15B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NDOT", + direction="l", + linebreak="id", + unicodeslot=0xA15B, + }, + [0xA15C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NDOX", + direction="l", + linebreak="id", + unicodeslot=0xA15C, + }, + [0xA15D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NDO", + direction="l", + linebreak="id", + unicodeslot=0xA15D, + }, + [0xA15E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NDOP", + direction="l", + linebreak="id", + unicodeslot=0xA15E, + }, + [0xA15F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NDEX", + direction="l", + linebreak="id", + unicodeslot=0xA15F, + }, + [0xA160]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NDE", + direction="l", + linebreak="id", + unicodeslot=0xA160, + }, + [0xA161]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NDEP", + direction="l", + linebreak="id", + unicodeslot=0xA161, + }, + [0xA162]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NDUT", + direction="l", + linebreak="id", + unicodeslot=0xA162, + }, + [0xA163]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NDUX", + direction="l", + linebreak="id", + unicodeslot=0xA163, + }, + [0xA164]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NDU", + direction="l", + linebreak="id", + unicodeslot=0xA164, + }, + [0xA165]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NDUP", + direction="l", + linebreak="id", + unicodeslot=0xA165, + }, + [0xA166]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NDURX", + direction="l", + linebreak="id", + unicodeslot=0xA166, + }, + [0xA167]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NDUR", + direction="l", + linebreak="id", + unicodeslot=0xA167, + }, + [0xA168]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HNIT", + direction="l", + linebreak="id", + unicodeslot=0xA168, + }, + [0xA169]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HNIX", + direction="l", + linebreak="id", + unicodeslot=0xA169, + }, + [0xA16A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HNI", + direction="l", + linebreak="id", + unicodeslot=0xA16A, + }, + [0xA16B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HNIP", + direction="l", + linebreak="id", + unicodeslot=0xA16B, + }, + [0xA16C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HNIET", + direction="l", + linebreak="id", + unicodeslot=0xA16C, + }, + [0xA16D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HNIEX", + direction="l", + linebreak="id", + unicodeslot=0xA16D, + }, + [0xA16E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HNIE", + direction="l", + linebreak="id", + unicodeslot=0xA16E, + }, + [0xA16F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HNIEP", + direction="l", + linebreak="id", + unicodeslot=0xA16F, + }, + [0xA170]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HNAT", + direction="l", + linebreak="id", + unicodeslot=0xA170, + }, + [0xA171]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HNAX", + direction="l", + linebreak="id", + unicodeslot=0xA171, + }, + [0xA172]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HNA", + direction="l", + linebreak="id", + unicodeslot=0xA172, + }, + [0xA173]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HNAP", + direction="l", + linebreak="id", + unicodeslot=0xA173, + }, + [0xA174]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HNUOX", + direction="l", + linebreak="id", + unicodeslot=0xA174, + }, + [0xA175]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HNUO", + direction="l", + linebreak="id", + unicodeslot=0xA175, + }, + [0xA176]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HNOT", + direction="l", + linebreak="id", + unicodeslot=0xA176, + }, + [0xA177]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HNOX", + direction="l", + linebreak="id", + unicodeslot=0xA177, + }, + [0xA178]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HNOP", + direction="l", + linebreak="id", + unicodeslot=0xA178, + }, + [0xA179]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HNEX", + direction="l", + linebreak="id", + unicodeslot=0xA179, + }, + [0xA17A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HNE", + direction="l", + linebreak="id", + unicodeslot=0xA17A, + }, + [0xA17B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HNEP", + direction="l", + linebreak="id", + unicodeslot=0xA17B, + }, + [0xA17C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HNUT", + direction="l", + linebreak="id", + unicodeslot=0xA17C, + }, + [0xA17D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NIT", + direction="l", + linebreak="id", + unicodeslot=0xA17D, + }, + [0xA17E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NIX", + direction="l", + linebreak="id", + unicodeslot=0xA17E, + }, + [0xA17F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NI", + direction="l", + linebreak="id", + unicodeslot=0xA17F, + }, + [0xA180]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NIP", + direction="l", + linebreak="id", + unicodeslot=0xA180, + }, + [0xA181]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NIEX", + direction="l", + linebreak="id", + unicodeslot=0xA181, + }, + [0xA182]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NIE", + direction="l", + linebreak="id", + unicodeslot=0xA182, + }, + [0xA183]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NIEP", + direction="l", + linebreak="id", + unicodeslot=0xA183, + }, + [0xA184]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NAX", + direction="l", + linebreak="id", + unicodeslot=0xA184, + }, + [0xA185]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NA", + direction="l", + linebreak="id", + unicodeslot=0xA185, + }, + [0xA186]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NAP", + direction="l", + linebreak="id", + unicodeslot=0xA186, + }, + [0xA187]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NUOX", + direction="l", + linebreak="id", + unicodeslot=0xA187, + }, + [0xA188]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NUO", + direction="l", + linebreak="id", + unicodeslot=0xA188, + }, + [0xA189]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NUOP", + direction="l", + linebreak="id", + unicodeslot=0xA189, + }, + [0xA18A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NOT", + direction="l", + linebreak="id", + unicodeslot=0xA18A, + }, + [0xA18B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NOX", + direction="l", + linebreak="id", + unicodeslot=0xA18B, + }, + [0xA18C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NO", + direction="l", + linebreak="id", + unicodeslot=0xA18C, + }, + [0xA18D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NOP", + direction="l", + linebreak="id", + unicodeslot=0xA18D, + }, + [0xA18E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NEX", + direction="l", + linebreak="id", + unicodeslot=0xA18E, + }, + [0xA18F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NE", + direction="l", + linebreak="id", + unicodeslot=0xA18F, + }, + [0xA190]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NEP", + direction="l", + linebreak="id", + unicodeslot=0xA190, + }, + [0xA191]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NUT", + direction="l", + linebreak="id", + unicodeslot=0xA191, + }, + [0xA192]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NUX", + direction="l", + linebreak="id", + unicodeslot=0xA192, + }, + [0xA193]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NU", + direction="l", + linebreak="id", + unicodeslot=0xA193, + }, + [0xA194]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NUP", + direction="l", + linebreak="id", + unicodeslot=0xA194, + }, + [0xA195]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NURX", + direction="l", + linebreak="id", + unicodeslot=0xA195, + }, + [0xA196]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NUR", + direction="l", + linebreak="id", + unicodeslot=0xA196, + }, + [0xA197]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLIT", + direction="l", + linebreak="id", + unicodeslot=0xA197, + }, + [0xA198]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLIX", + direction="l", + linebreak="id", + unicodeslot=0xA198, + }, + [0xA199]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLI", + direction="l", + linebreak="id", + unicodeslot=0xA199, + }, + [0xA19A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLIP", + direction="l", + linebreak="id", + unicodeslot=0xA19A, + }, + [0xA19B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLIEX", + direction="l", + linebreak="id", + unicodeslot=0xA19B, + }, + [0xA19C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLIE", + direction="l", + linebreak="id", + unicodeslot=0xA19C, + }, + [0xA19D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLIEP", + direction="l", + linebreak="id", + unicodeslot=0xA19D, + }, + [0xA19E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLAT", + direction="l", + linebreak="id", + unicodeslot=0xA19E, + }, + [0xA19F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLAX", + direction="l", + linebreak="id", + unicodeslot=0xA19F, + }, + [0xA1A0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLA", + direction="l", + linebreak="id", + unicodeslot=0xA1A0, + }, + [0xA1A1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLAP", + direction="l", + linebreak="id", + unicodeslot=0xA1A1, + }, + [0xA1A2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLUOX", + direction="l", + linebreak="id", + unicodeslot=0xA1A2, + }, + [0xA1A3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLUO", + direction="l", + linebreak="id", + unicodeslot=0xA1A3, + }, + [0xA1A4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLUOP", + direction="l", + linebreak="id", + unicodeslot=0xA1A4, + }, + [0xA1A5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLOX", + direction="l", + linebreak="id", + unicodeslot=0xA1A5, + }, + [0xA1A6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLO", + direction="l", + linebreak="id", + unicodeslot=0xA1A6, + }, + [0xA1A7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLOP", + direction="l", + linebreak="id", + unicodeslot=0xA1A7, + }, + [0xA1A8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLEX", + direction="l", + linebreak="id", + unicodeslot=0xA1A8, + }, + [0xA1A9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLE", + direction="l", + linebreak="id", + unicodeslot=0xA1A9, + }, + [0xA1AA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLEP", + direction="l", + linebreak="id", + unicodeslot=0xA1AA, + }, + [0xA1AB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLUT", + direction="l", + linebreak="id", + unicodeslot=0xA1AB, + }, + [0xA1AC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLUX", + direction="l", + linebreak="id", + unicodeslot=0xA1AC, + }, + [0xA1AD]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLU", + direction="l", + linebreak="id", + unicodeslot=0xA1AD, + }, + [0xA1AE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLUP", + direction="l", + linebreak="id", + unicodeslot=0xA1AE, + }, + [0xA1AF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLURX", + direction="l", + linebreak="id", + unicodeslot=0xA1AF, + }, + [0xA1B0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLUR", + direction="l", + linebreak="id", + unicodeslot=0xA1B0, + }, + [0xA1B1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLYT", + direction="l", + linebreak="id", + unicodeslot=0xA1B1, + }, + [0xA1B2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLYX", + direction="l", + linebreak="id", + unicodeslot=0xA1B2, + }, + [0xA1B3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLY", + direction="l", + linebreak="id", + unicodeslot=0xA1B3, + }, + [0xA1B4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLYP", + direction="l", + linebreak="id", + unicodeslot=0xA1B4, + }, + [0xA1B5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLYRX", + direction="l", + linebreak="id", + unicodeslot=0xA1B5, + }, + [0xA1B6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HLYR", + direction="l", + linebreak="id", + unicodeslot=0xA1B6, + }, + [0xA1B7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LIT", + direction="l", + linebreak="id", + unicodeslot=0xA1B7, + }, + [0xA1B8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LIX", + direction="l", + linebreak="id", + unicodeslot=0xA1B8, + }, + [0xA1B9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LI", + direction="l", + linebreak="id", + unicodeslot=0xA1B9, + }, + [0xA1BA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LIP", + direction="l", + linebreak="id", + unicodeslot=0xA1BA, + }, + [0xA1BB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LIET", + direction="l", + linebreak="id", + unicodeslot=0xA1BB, + }, + [0xA1BC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LIEX", + direction="l", + linebreak="id", + unicodeslot=0xA1BC, + }, + [0xA1BD]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LIE", + direction="l", + linebreak="id", + unicodeslot=0xA1BD, + }, + [0xA1BE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LIEP", + direction="l", + linebreak="id", + unicodeslot=0xA1BE, + }, + [0xA1BF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LAT", + direction="l", + linebreak="id", + unicodeslot=0xA1BF, + }, + [0xA1C0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LAX", + direction="l", + linebreak="id", + unicodeslot=0xA1C0, + }, + [0xA1C1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LA", + direction="l", + linebreak="id", + unicodeslot=0xA1C1, + }, + [0xA1C2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LAP", + direction="l", + linebreak="id", + unicodeslot=0xA1C2, + }, + [0xA1C3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LUOT", + direction="l", + linebreak="id", + unicodeslot=0xA1C3, + }, + [0xA1C4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LUOX", + direction="l", + linebreak="id", + unicodeslot=0xA1C4, + }, + [0xA1C5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LUO", + direction="l", + linebreak="id", + unicodeslot=0xA1C5, + }, + [0xA1C6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LUOP", + direction="l", + linebreak="id", + unicodeslot=0xA1C6, + }, + [0xA1C7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LOT", + direction="l", + linebreak="id", + unicodeslot=0xA1C7, + }, + [0xA1C8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LOX", + direction="l", + linebreak="id", + unicodeslot=0xA1C8, + }, + [0xA1C9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LO", + direction="l", + linebreak="id", + unicodeslot=0xA1C9, + }, + [0xA1CA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LOP", + direction="l", + linebreak="id", + unicodeslot=0xA1CA, + }, + [0xA1CB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LEX", + direction="l", + linebreak="id", + unicodeslot=0xA1CB, + }, + [0xA1CC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LE", + direction="l", + linebreak="id", + unicodeslot=0xA1CC, + }, + [0xA1CD]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LEP", + direction="l", + linebreak="id", + unicodeslot=0xA1CD, + }, + [0xA1CE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LUT", + direction="l", + linebreak="id", + unicodeslot=0xA1CE, + }, + [0xA1CF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LUX", + direction="l", + linebreak="id", + unicodeslot=0xA1CF, + }, + [0xA1D0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LU", + direction="l", + linebreak="id", + unicodeslot=0xA1D0, + }, + [0xA1D1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LUP", + direction="l", + linebreak="id", + unicodeslot=0xA1D1, + }, + [0xA1D2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LURX", + direction="l", + linebreak="id", + unicodeslot=0xA1D2, + }, + [0xA1D3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LUR", + direction="l", + linebreak="id", + unicodeslot=0xA1D3, + }, + [0xA1D4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LYT", + direction="l", + linebreak="id", + unicodeslot=0xA1D4, + }, + [0xA1D5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LYX", + direction="l", + linebreak="id", + unicodeslot=0xA1D5, + }, + [0xA1D6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LY", + direction="l", + linebreak="id", + unicodeslot=0xA1D6, + }, + [0xA1D7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LYP", + direction="l", + linebreak="id", + unicodeslot=0xA1D7, + }, + [0xA1D8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LYRX", + direction="l", + linebreak="id", + unicodeslot=0xA1D8, + }, + [0xA1D9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE LYR", + direction="l", + linebreak="id", + unicodeslot=0xA1D9, + }, + [0xA1DA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GIT", + direction="l", + linebreak="id", + unicodeslot=0xA1DA, + }, + [0xA1DB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GIX", + direction="l", + linebreak="id", + unicodeslot=0xA1DB, + }, + [0xA1DC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GI", + direction="l", + linebreak="id", + unicodeslot=0xA1DC, + }, + [0xA1DD]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GIP", + direction="l", + linebreak="id", + unicodeslot=0xA1DD, + }, + [0xA1DE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GIET", + direction="l", + linebreak="id", + unicodeslot=0xA1DE, + }, + [0xA1DF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GIEX", + direction="l", + linebreak="id", + unicodeslot=0xA1DF, + }, + [0xA1E0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GIE", + direction="l", + linebreak="id", + unicodeslot=0xA1E0, + }, + [0xA1E1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GIEP", + direction="l", + linebreak="id", + unicodeslot=0xA1E1, + }, + [0xA1E2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GAT", + direction="l", + linebreak="id", + unicodeslot=0xA1E2, + }, + [0xA1E3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GAX", + direction="l", + linebreak="id", + unicodeslot=0xA1E3, + }, + [0xA1E4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GA", + direction="l", + linebreak="id", + unicodeslot=0xA1E4, + }, + [0xA1E5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GAP", + direction="l", + linebreak="id", + unicodeslot=0xA1E5, + }, + [0xA1E6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GUOT", + direction="l", + linebreak="id", + unicodeslot=0xA1E6, + }, + [0xA1E7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GUOX", + direction="l", + linebreak="id", + unicodeslot=0xA1E7, + }, + [0xA1E8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GUO", + direction="l", + linebreak="id", + unicodeslot=0xA1E8, + }, + [0xA1E9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GUOP", + direction="l", + linebreak="id", + unicodeslot=0xA1E9, + }, + [0xA1EA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GOT", + direction="l", + linebreak="id", + unicodeslot=0xA1EA, + }, + [0xA1EB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GOX", + direction="l", + linebreak="id", + unicodeslot=0xA1EB, + }, + [0xA1EC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GO", + direction="l", + linebreak="id", + unicodeslot=0xA1EC, + }, + [0xA1ED]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GOP", + direction="l", + linebreak="id", + unicodeslot=0xA1ED, + }, + [0xA1EE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GET", + direction="l", + linebreak="id", + unicodeslot=0xA1EE, + }, + [0xA1EF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GEX", + direction="l", + linebreak="id", + unicodeslot=0xA1EF, + }, + [0xA1F0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GE", + direction="l", + linebreak="id", + unicodeslot=0xA1F0, + }, + [0xA1F1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GEP", + direction="l", + linebreak="id", + unicodeslot=0xA1F1, + }, + [0xA1F2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GUT", + direction="l", + linebreak="id", + unicodeslot=0xA1F2, + }, + [0xA1F3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GUX", + direction="l", + linebreak="id", + unicodeslot=0xA1F3, + }, + [0xA1F4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GU", + direction="l", + linebreak="id", + unicodeslot=0xA1F4, + }, + [0xA1F5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GUP", + direction="l", + linebreak="id", + unicodeslot=0xA1F5, + }, + [0xA1F6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GURX", + direction="l", + linebreak="id", + unicodeslot=0xA1F6, + }, + [0xA1F7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GUR", + direction="l", + linebreak="id", + unicodeslot=0xA1F7, + }, + [0xA1F8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KIT", + direction="l", + linebreak="id", + unicodeslot=0xA1F8, + }, + [0xA1F9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KIX", + direction="l", + linebreak="id", + unicodeslot=0xA1F9, + }, + [0xA1FA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KI", + direction="l", + linebreak="id", + unicodeslot=0xA1FA, + }, + [0xA1FB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KIP", + direction="l", + linebreak="id", + unicodeslot=0xA1FB, + }, + [0xA1FC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KIEX", + direction="l", + linebreak="id", + unicodeslot=0xA1FC, + }, + [0xA1FD]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KIE", + direction="l", + linebreak="id", + unicodeslot=0xA1FD, + }, + [0xA1FE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KIEP", + direction="l", + linebreak="id", + unicodeslot=0xA1FE, + }, + [0xA1FF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KAT", + direction="l", + linebreak="id", + unicodeslot=0xA1FF, + }, + [0xA200]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KAX", + direction="l", + linebreak="id", + unicodeslot=0xA200, + }, + [0xA201]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KA", + direction="l", + linebreak="id", + unicodeslot=0xA201, + }, + [0xA202]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KAP", + direction="l", + linebreak="id", + unicodeslot=0xA202, + }, + [0xA203]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KUOX", + direction="l", + linebreak="id", + unicodeslot=0xA203, + }, + [0xA204]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KUO", + direction="l", + linebreak="id", + unicodeslot=0xA204, + }, + [0xA205]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KUOP", + direction="l", + linebreak="id", + unicodeslot=0xA205, + }, + [0xA206]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KOT", + direction="l", + linebreak="id", + unicodeslot=0xA206, + }, + [0xA207]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KOX", + direction="l", + linebreak="id", + unicodeslot=0xA207, + }, + [0xA208]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KO", + direction="l", + linebreak="id", + unicodeslot=0xA208, + }, + [0xA209]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KOP", + direction="l", + linebreak="id", + unicodeslot=0xA209, + }, + [0xA20A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KET", + direction="l", + linebreak="id", + unicodeslot=0xA20A, + }, + [0xA20B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KEX", + direction="l", + linebreak="id", + unicodeslot=0xA20B, + }, + [0xA20C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KE", + direction="l", + linebreak="id", + unicodeslot=0xA20C, + }, + [0xA20D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KEP", + direction="l", + linebreak="id", + unicodeslot=0xA20D, + }, + [0xA20E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KUT", + direction="l", + linebreak="id", + unicodeslot=0xA20E, + }, + [0xA20F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KUX", + direction="l", + linebreak="id", + unicodeslot=0xA20F, + }, + [0xA210]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KU", + direction="l", + linebreak="id", + unicodeslot=0xA210, + }, + [0xA211]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KUP", + direction="l", + linebreak="id", + unicodeslot=0xA211, + }, + [0xA212]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KURX", + direction="l", + linebreak="id", + unicodeslot=0xA212, + }, + [0xA213]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE KUR", + direction="l", + linebreak="id", + unicodeslot=0xA213, + }, + [0xA214]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGIT", + direction="l", + linebreak="id", + unicodeslot=0xA214, + }, + [0xA215]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGIX", + direction="l", + linebreak="id", + unicodeslot=0xA215, + }, + [0xA216]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGI", + direction="l", + linebreak="id", + unicodeslot=0xA216, + }, + [0xA217]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGIEX", + direction="l", + linebreak="id", + unicodeslot=0xA217, + }, + [0xA218]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGIE", + direction="l", + linebreak="id", + unicodeslot=0xA218, + }, + [0xA219]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGIEP", + direction="l", + linebreak="id", + unicodeslot=0xA219, + }, + [0xA21A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGAT", + direction="l", + linebreak="id", + unicodeslot=0xA21A, + }, + [0xA21B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGAX", + direction="l", + linebreak="id", + unicodeslot=0xA21B, + }, + [0xA21C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGA", + direction="l", + linebreak="id", + unicodeslot=0xA21C, + }, + [0xA21D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGAP", + direction="l", + linebreak="id", + unicodeslot=0xA21D, + }, + [0xA21E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGUOT", + direction="l", + linebreak="id", + unicodeslot=0xA21E, + }, + [0xA21F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGUOX", + direction="l", + linebreak="id", + unicodeslot=0xA21F, + }, + [0xA220]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGUO", + direction="l", + linebreak="id", + unicodeslot=0xA220, + }, + [0xA221]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGUOP", + direction="l", + linebreak="id", + unicodeslot=0xA221, + }, + [0xA222]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGOT", + direction="l", + linebreak="id", + unicodeslot=0xA222, + }, + [0xA223]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGOX", + direction="l", + linebreak="id", + unicodeslot=0xA223, + }, + [0xA224]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGO", + direction="l", + linebreak="id", + unicodeslot=0xA224, + }, + [0xA225]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGOP", + direction="l", + linebreak="id", + unicodeslot=0xA225, + }, + [0xA226]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGET", + direction="l", + linebreak="id", + unicodeslot=0xA226, + }, + [0xA227]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGEX", + direction="l", + linebreak="id", + unicodeslot=0xA227, + }, + [0xA228]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGE", + direction="l", + linebreak="id", + unicodeslot=0xA228, + }, + [0xA229]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGEP", + direction="l", + linebreak="id", + unicodeslot=0xA229, + }, + [0xA22A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGUT", + direction="l", + linebreak="id", + unicodeslot=0xA22A, + }, + [0xA22B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGUX", + direction="l", + linebreak="id", + unicodeslot=0xA22B, + }, + [0xA22C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGU", + direction="l", + linebreak="id", + unicodeslot=0xA22C, + }, + [0xA22D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGUP", + direction="l", + linebreak="id", + unicodeslot=0xA22D, + }, + [0xA22E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGURX", + direction="l", + linebreak="id", + unicodeslot=0xA22E, + }, + [0xA22F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE GGUR", + direction="l", + linebreak="id", + unicodeslot=0xA22F, + }, + [0xA230]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MGIEX", + direction="l", + linebreak="id", + unicodeslot=0xA230, + }, + [0xA231]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MGIE", + direction="l", + linebreak="id", + unicodeslot=0xA231, + }, + [0xA232]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MGAT", + direction="l", + linebreak="id", + unicodeslot=0xA232, + }, + [0xA233]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MGAX", + direction="l", + linebreak="id", + unicodeslot=0xA233, + }, + [0xA234]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MGA", + direction="l", + linebreak="id", + unicodeslot=0xA234, + }, + [0xA235]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MGAP", + direction="l", + linebreak="id", + unicodeslot=0xA235, + }, + [0xA236]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MGUOX", + direction="l", + linebreak="id", + unicodeslot=0xA236, + }, + [0xA237]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MGUO", + direction="l", + linebreak="id", + unicodeslot=0xA237, + }, + [0xA238]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MGUOP", + direction="l", + linebreak="id", + unicodeslot=0xA238, + }, + [0xA239]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MGOT", + direction="l", + linebreak="id", + unicodeslot=0xA239, + }, + [0xA23A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MGOX", + direction="l", + linebreak="id", + unicodeslot=0xA23A, + }, + [0xA23B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MGO", + direction="l", + linebreak="id", + unicodeslot=0xA23B, + }, + [0xA23C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MGOP", + direction="l", + linebreak="id", + unicodeslot=0xA23C, + }, + [0xA23D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MGEX", + direction="l", + linebreak="id", + unicodeslot=0xA23D, + }, + [0xA23E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MGE", + direction="l", + linebreak="id", + unicodeslot=0xA23E, + }, + [0xA23F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MGEP", + direction="l", + linebreak="id", + unicodeslot=0xA23F, + }, + [0xA240]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MGUT", + direction="l", + linebreak="id", + unicodeslot=0xA240, + }, + [0xA241]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MGUX", + direction="l", + linebreak="id", + unicodeslot=0xA241, + }, + [0xA242]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MGU", + direction="l", + linebreak="id", + unicodeslot=0xA242, + }, + [0xA243]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MGUP", + direction="l", + linebreak="id", + unicodeslot=0xA243, + }, + [0xA244]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MGURX", + direction="l", + linebreak="id", + unicodeslot=0xA244, + }, + [0xA245]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE MGUR", + direction="l", + linebreak="id", + unicodeslot=0xA245, + }, + [0xA246]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HXIT", + direction="l", + linebreak="id", + unicodeslot=0xA246, + }, + [0xA247]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HXIX", + direction="l", + linebreak="id", + unicodeslot=0xA247, + }, + [0xA248]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HXI", + direction="l", + linebreak="id", + unicodeslot=0xA248, + }, + [0xA249]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HXIP", + direction="l", + linebreak="id", + unicodeslot=0xA249, + }, + [0xA24A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HXIET", + direction="l", + linebreak="id", + unicodeslot=0xA24A, + }, + [0xA24B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HXIEX", + direction="l", + linebreak="id", + unicodeslot=0xA24B, + }, + [0xA24C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HXIE", + direction="l", + linebreak="id", + unicodeslot=0xA24C, + }, + [0xA24D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HXIEP", + direction="l", + linebreak="id", + unicodeslot=0xA24D, + }, + [0xA24E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HXAT", + direction="l", + linebreak="id", + unicodeslot=0xA24E, + }, + [0xA24F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HXAX", + direction="l", + linebreak="id", + unicodeslot=0xA24F, + }, + [0xA250]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HXA", + direction="l", + linebreak="id", + unicodeslot=0xA250, + }, + [0xA251]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HXAP", + direction="l", + linebreak="id", + unicodeslot=0xA251, + }, + [0xA252]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HXUOT", + direction="l", + linebreak="id", + unicodeslot=0xA252, + }, + [0xA253]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HXUOX", + direction="l", + linebreak="id", + unicodeslot=0xA253, + }, + [0xA254]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HXUO", + direction="l", + linebreak="id", + unicodeslot=0xA254, + }, + [0xA255]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HXUOP", + direction="l", + linebreak="id", + unicodeslot=0xA255, + }, + [0xA256]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HXOT", + direction="l", + linebreak="id", + unicodeslot=0xA256, + }, + [0xA257]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HXOX", + direction="l", + linebreak="id", + unicodeslot=0xA257, + }, + [0xA258]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HXO", + direction="l", + linebreak="id", + unicodeslot=0xA258, + }, + [0xA259]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HXOP", + direction="l", + linebreak="id", + unicodeslot=0xA259, + }, + [0xA25A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HXEX", + direction="l", + linebreak="id", + unicodeslot=0xA25A, + }, + [0xA25B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HXE", + direction="l", + linebreak="id", + unicodeslot=0xA25B, + }, + [0xA25C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HXEP", + direction="l", + linebreak="id", + unicodeslot=0xA25C, + }, + [0xA25D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NGIEX", + direction="l", + linebreak="id", + unicodeslot=0xA25D, + }, + [0xA25E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NGIE", + direction="l", + linebreak="id", + unicodeslot=0xA25E, + }, + [0xA25F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NGIEP", + direction="l", + linebreak="id", + unicodeslot=0xA25F, + }, + [0xA260]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NGAT", + direction="l", + linebreak="id", + unicodeslot=0xA260, + }, + [0xA261]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NGAX", + direction="l", + linebreak="id", + unicodeslot=0xA261, + }, + [0xA262]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NGA", + direction="l", + linebreak="id", + unicodeslot=0xA262, + }, + [0xA263]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NGAP", + direction="l", + linebreak="id", + unicodeslot=0xA263, + }, + [0xA264]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NGUOT", + direction="l", + linebreak="id", + unicodeslot=0xA264, + }, + [0xA265]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NGUOX", + direction="l", + linebreak="id", + unicodeslot=0xA265, + }, + [0xA266]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NGUO", + direction="l", + linebreak="id", + unicodeslot=0xA266, + }, + [0xA267]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NGOT", + direction="l", + linebreak="id", + unicodeslot=0xA267, + }, + [0xA268]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NGOX", + direction="l", + linebreak="id", + unicodeslot=0xA268, + }, + [0xA269]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NGO", + direction="l", + linebreak="id", + unicodeslot=0xA269, + }, + [0xA26A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NGOP", + direction="l", + linebreak="id", + unicodeslot=0xA26A, + }, + [0xA26B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NGEX", + direction="l", + linebreak="id", + unicodeslot=0xA26B, + }, + [0xA26C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NGE", + direction="l", + linebreak="id", + unicodeslot=0xA26C, + }, + [0xA26D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NGEP", + direction="l", + linebreak="id", + unicodeslot=0xA26D, + }, + [0xA26E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HIT", + direction="l", + linebreak="id", + unicodeslot=0xA26E, + }, + [0xA26F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HIEX", + direction="l", + linebreak="id", + unicodeslot=0xA26F, + }, + [0xA270]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HIE", + direction="l", + linebreak="id", + unicodeslot=0xA270, + }, + [0xA271]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HAT", + direction="l", + linebreak="id", + unicodeslot=0xA271, + }, + [0xA272]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HAX", + direction="l", + linebreak="id", + unicodeslot=0xA272, + }, + [0xA273]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HA", + direction="l", + linebreak="id", + unicodeslot=0xA273, + }, + [0xA274]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HAP", + direction="l", + linebreak="id", + unicodeslot=0xA274, + }, + [0xA275]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HUOT", + direction="l", + linebreak="id", + unicodeslot=0xA275, + }, + [0xA276]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HUOX", + direction="l", + linebreak="id", + unicodeslot=0xA276, + }, + [0xA277]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HUO", + direction="l", + linebreak="id", + unicodeslot=0xA277, + }, + [0xA278]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HUOP", + direction="l", + linebreak="id", + unicodeslot=0xA278, + }, + [0xA279]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HOT", + direction="l", + linebreak="id", + unicodeslot=0xA279, + }, + [0xA27A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HOX", + direction="l", + linebreak="id", + unicodeslot=0xA27A, + }, + [0xA27B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HO", + direction="l", + linebreak="id", + unicodeslot=0xA27B, + }, + [0xA27C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HOP", + direction="l", + linebreak="id", + unicodeslot=0xA27C, + }, + [0xA27D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HEX", + direction="l", + linebreak="id", + unicodeslot=0xA27D, + }, + [0xA27E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HE", + direction="l", + linebreak="id", + unicodeslot=0xA27E, + }, + [0xA27F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE HEP", + direction="l", + linebreak="id", + unicodeslot=0xA27F, + }, + [0xA280]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE WAT", + direction="l", + linebreak="id", + unicodeslot=0xA280, + }, + [0xA281]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE WAX", + direction="l", + linebreak="id", + unicodeslot=0xA281, + }, + [0xA282]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE WA", + direction="l", + linebreak="id", + unicodeslot=0xA282, + }, + [0xA283]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE WAP", + direction="l", + linebreak="id", + unicodeslot=0xA283, + }, + [0xA284]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE WUOX", + direction="l", + linebreak="id", + unicodeslot=0xA284, + }, + [0xA285]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE WUO", + direction="l", + linebreak="id", + unicodeslot=0xA285, + }, + [0xA286]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE WUOP", + direction="l", + linebreak="id", + unicodeslot=0xA286, + }, + [0xA287]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE WOX", + direction="l", + linebreak="id", + unicodeslot=0xA287, + }, + [0xA288]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE WO", + direction="l", + linebreak="id", + unicodeslot=0xA288, + }, + [0xA289]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE WOP", + direction="l", + linebreak="id", + unicodeslot=0xA289, + }, + [0xA28A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE WEX", + direction="l", + linebreak="id", + unicodeslot=0xA28A, + }, + [0xA28B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE WE", + direction="l", + linebreak="id", + unicodeslot=0xA28B, + }, + [0xA28C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE WEP", + direction="l", + linebreak="id", + unicodeslot=0xA28C, + }, + [0xA28D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZIT", + direction="l", + linebreak="id", + unicodeslot=0xA28D, + }, + [0xA28E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZIX", + direction="l", + linebreak="id", + unicodeslot=0xA28E, + }, + [0xA28F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZI", + direction="l", + linebreak="id", + unicodeslot=0xA28F, + }, + [0xA290]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZIP", + direction="l", + linebreak="id", + unicodeslot=0xA290, + }, + [0xA291]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZIEX", + direction="l", + linebreak="id", + unicodeslot=0xA291, + }, + [0xA292]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZIE", + direction="l", + linebreak="id", + unicodeslot=0xA292, + }, + [0xA293]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZIEP", + direction="l", + linebreak="id", + unicodeslot=0xA293, + }, + [0xA294]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZAT", + direction="l", + linebreak="id", + unicodeslot=0xA294, + }, + [0xA295]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZAX", + direction="l", + linebreak="id", + unicodeslot=0xA295, + }, + [0xA296]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZA", + direction="l", + linebreak="id", + unicodeslot=0xA296, + }, + [0xA297]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZAP", + direction="l", + linebreak="id", + unicodeslot=0xA297, + }, + [0xA298]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZUOX", + direction="l", + linebreak="id", + unicodeslot=0xA298, + }, + [0xA299]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZUO", + direction="l", + linebreak="id", + unicodeslot=0xA299, + }, + [0xA29A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZUOP", + direction="l", + linebreak="id", + unicodeslot=0xA29A, + }, + [0xA29B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZOT", + direction="l", + linebreak="id", + unicodeslot=0xA29B, + }, + [0xA29C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZOX", + direction="l", + linebreak="id", + unicodeslot=0xA29C, + }, + [0xA29D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZO", + direction="l", + linebreak="id", + unicodeslot=0xA29D, + }, + [0xA29E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZOP", + direction="l", + linebreak="id", + unicodeslot=0xA29E, + }, + [0xA29F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZEX", + direction="l", + linebreak="id", + unicodeslot=0xA29F, + }, + [0xA2A0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZE", + direction="l", + linebreak="id", + unicodeslot=0xA2A0, + }, + [0xA2A1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZEP", + direction="l", + linebreak="id", + unicodeslot=0xA2A1, + }, + [0xA2A2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZUT", + direction="l", + linebreak="id", + unicodeslot=0xA2A2, + }, + [0xA2A3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZUX", + direction="l", + linebreak="id", + unicodeslot=0xA2A3, + }, + [0xA2A4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZU", + direction="l", + linebreak="id", + unicodeslot=0xA2A4, + }, + [0xA2A5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZUP", + direction="l", + linebreak="id", + unicodeslot=0xA2A5, + }, + [0xA2A6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZURX", + direction="l", + linebreak="id", + unicodeslot=0xA2A6, + }, + [0xA2A7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZUR", + direction="l", + linebreak="id", + unicodeslot=0xA2A7, + }, + [0xA2A8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZYT", + direction="l", + linebreak="id", + unicodeslot=0xA2A8, + }, + [0xA2A9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZYX", + direction="l", + linebreak="id", + unicodeslot=0xA2A9, + }, + [0xA2AA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZY", + direction="l", + linebreak="id", + unicodeslot=0xA2AA, + }, + [0xA2AB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZYP", + direction="l", + linebreak="id", + unicodeslot=0xA2AB, + }, + [0xA2AC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZYRX", + direction="l", + linebreak="id", + unicodeslot=0xA2AC, + }, + [0xA2AD]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZYR", + direction="l", + linebreak="id", + unicodeslot=0xA2AD, + }, + [0xA2AE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CIT", + direction="l", + linebreak="id", + unicodeslot=0xA2AE, + }, + [0xA2AF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CIX", + direction="l", + linebreak="id", + unicodeslot=0xA2AF, + }, + [0xA2B0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CI", + direction="l", + linebreak="id", + unicodeslot=0xA2B0, + }, + [0xA2B1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CIP", + direction="l", + linebreak="id", + unicodeslot=0xA2B1, + }, + [0xA2B2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CIET", + direction="l", + linebreak="id", + unicodeslot=0xA2B2, + }, + [0xA2B3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CIEX", + direction="l", + linebreak="id", + unicodeslot=0xA2B3, + }, + [0xA2B4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CIE", + direction="l", + linebreak="id", + unicodeslot=0xA2B4, + }, + [0xA2B5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CIEP", + direction="l", + linebreak="id", + unicodeslot=0xA2B5, + }, + [0xA2B6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CAT", + direction="l", + linebreak="id", + unicodeslot=0xA2B6, + }, + [0xA2B7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CAX", + direction="l", + linebreak="id", + unicodeslot=0xA2B7, + }, + [0xA2B8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CA", + direction="l", + linebreak="id", + unicodeslot=0xA2B8, + }, + [0xA2B9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CAP", + direction="l", + linebreak="id", + unicodeslot=0xA2B9, + }, + [0xA2BA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CUOX", + direction="l", + linebreak="id", + unicodeslot=0xA2BA, + }, + [0xA2BB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CUO", + direction="l", + linebreak="id", + unicodeslot=0xA2BB, + }, + [0xA2BC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CUOP", + direction="l", + linebreak="id", + unicodeslot=0xA2BC, + }, + [0xA2BD]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE COT", + direction="l", + linebreak="id", + unicodeslot=0xA2BD, + }, + [0xA2BE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE COX", + direction="l", + linebreak="id", + unicodeslot=0xA2BE, + }, + [0xA2BF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CO", + direction="l", + linebreak="id", + unicodeslot=0xA2BF, + }, + [0xA2C0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE COP", + direction="l", + linebreak="id", + unicodeslot=0xA2C0, + }, + [0xA2C1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CEX", + direction="l", + linebreak="id", + unicodeslot=0xA2C1, + }, + [0xA2C2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CE", + direction="l", + linebreak="id", + unicodeslot=0xA2C2, + }, + [0xA2C3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CEP", + direction="l", + linebreak="id", + unicodeslot=0xA2C3, + }, + [0xA2C4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CUT", + direction="l", + linebreak="id", + unicodeslot=0xA2C4, + }, + [0xA2C5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CUX", + direction="l", + linebreak="id", + unicodeslot=0xA2C5, + }, + [0xA2C6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CU", + direction="l", + linebreak="id", + unicodeslot=0xA2C6, + }, + [0xA2C7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CUP", + direction="l", + linebreak="id", + unicodeslot=0xA2C7, + }, + [0xA2C8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CURX", + direction="l", + linebreak="id", + unicodeslot=0xA2C8, + }, + [0xA2C9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CUR", + direction="l", + linebreak="id", + unicodeslot=0xA2C9, + }, + [0xA2CA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CYT", + direction="l", + linebreak="id", + unicodeslot=0xA2CA, + }, + [0xA2CB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CYX", + direction="l", + linebreak="id", + unicodeslot=0xA2CB, + }, + [0xA2CC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CY", + direction="l", + linebreak="id", + unicodeslot=0xA2CC, + }, + [0xA2CD]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CYP", + direction="l", + linebreak="id", + unicodeslot=0xA2CD, + }, + [0xA2CE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CYRX", + direction="l", + linebreak="id", + unicodeslot=0xA2CE, + }, + [0xA2CF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CYR", + direction="l", + linebreak="id", + unicodeslot=0xA2CF, + }, + [0xA2D0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZIT", + direction="l", + linebreak="id", + unicodeslot=0xA2D0, + }, + [0xA2D1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZIX", + direction="l", + linebreak="id", + unicodeslot=0xA2D1, + }, + [0xA2D2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZI", + direction="l", + linebreak="id", + unicodeslot=0xA2D2, + }, + [0xA2D3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZIP", + direction="l", + linebreak="id", + unicodeslot=0xA2D3, + }, + [0xA2D4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZIET", + direction="l", + linebreak="id", + unicodeslot=0xA2D4, + }, + [0xA2D5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZIEX", + direction="l", + linebreak="id", + unicodeslot=0xA2D5, + }, + [0xA2D6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZIE", + direction="l", + linebreak="id", + unicodeslot=0xA2D6, + }, + [0xA2D7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZIEP", + direction="l", + linebreak="id", + unicodeslot=0xA2D7, + }, + [0xA2D8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZAT", + direction="l", + linebreak="id", + unicodeslot=0xA2D8, + }, + [0xA2D9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZAX", + direction="l", + linebreak="id", + unicodeslot=0xA2D9, + }, + [0xA2DA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZA", + direction="l", + linebreak="id", + unicodeslot=0xA2DA, + }, + [0xA2DB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZAP", + direction="l", + linebreak="id", + unicodeslot=0xA2DB, + }, + [0xA2DC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZOX", + direction="l", + linebreak="id", + unicodeslot=0xA2DC, + }, + [0xA2DD]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZO", + direction="l", + linebreak="id", + unicodeslot=0xA2DD, + }, + [0xA2DE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZOP", + direction="l", + linebreak="id", + unicodeslot=0xA2DE, + }, + [0xA2DF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZEX", + direction="l", + linebreak="id", + unicodeslot=0xA2DF, + }, + [0xA2E0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZE", + direction="l", + linebreak="id", + unicodeslot=0xA2E0, + }, + [0xA2E1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZEP", + direction="l", + linebreak="id", + unicodeslot=0xA2E1, + }, + [0xA2E2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZUX", + direction="l", + linebreak="id", + unicodeslot=0xA2E2, + }, + [0xA2E3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZU", + direction="l", + linebreak="id", + unicodeslot=0xA2E3, + }, + [0xA2E4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZUP", + direction="l", + linebreak="id", + unicodeslot=0xA2E4, + }, + [0xA2E5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZURX", + direction="l", + linebreak="id", + unicodeslot=0xA2E5, + }, + [0xA2E6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZUR", + direction="l", + linebreak="id", + unicodeslot=0xA2E6, + }, + [0xA2E7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZYT", + direction="l", + linebreak="id", + unicodeslot=0xA2E7, + }, + [0xA2E8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZYX", + direction="l", + linebreak="id", + unicodeslot=0xA2E8, + }, + [0xA2E9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZY", + direction="l", + linebreak="id", + unicodeslot=0xA2E9, + }, + [0xA2EA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZYP", + direction="l", + linebreak="id", + unicodeslot=0xA2EA, + }, + [0xA2EB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZYRX", + direction="l", + linebreak="id", + unicodeslot=0xA2EB, + }, + [0xA2EC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZZYR", + direction="l", + linebreak="id", + unicodeslot=0xA2EC, + }, + [0xA2ED]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZIT", + direction="l", + linebreak="id", + unicodeslot=0xA2ED, + }, + [0xA2EE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZIX", + direction="l", + linebreak="id", + unicodeslot=0xA2EE, + }, + [0xA2EF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZI", + direction="l", + linebreak="id", + unicodeslot=0xA2EF, + }, + [0xA2F0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZIP", + direction="l", + linebreak="id", + unicodeslot=0xA2F0, + }, + [0xA2F1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZIEX", + direction="l", + linebreak="id", + unicodeslot=0xA2F1, + }, + [0xA2F2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZIE", + direction="l", + linebreak="id", + unicodeslot=0xA2F2, + }, + [0xA2F3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZIEP", + direction="l", + linebreak="id", + unicodeslot=0xA2F3, + }, + [0xA2F4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZAT", + direction="l", + linebreak="id", + unicodeslot=0xA2F4, + }, + [0xA2F5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZAX", + direction="l", + linebreak="id", + unicodeslot=0xA2F5, + }, + [0xA2F6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZA", + direction="l", + linebreak="id", + unicodeslot=0xA2F6, + }, + [0xA2F7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZAP", + direction="l", + linebreak="id", + unicodeslot=0xA2F7, + }, + [0xA2F8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZUOX", + direction="l", + linebreak="id", + unicodeslot=0xA2F8, + }, + [0xA2F9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZUO", + direction="l", + linebreak="id", + unicodeslot=0xA2F9, + }, + [0xA2FA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZOX", + direction="l", + linebreak="id", + unicodeslot=0xA2FA, + }, + [0xA2FB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZOP", + direction="l", + linebreak="id", + unicodeslot=0xA2FB, + }, + [0xA2FC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZEX", + direction="l", + linebreak="id", + unicodeslot=0xA2FC, + }, + [0xA2FD]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZE", + direction="l", + linebreak="id", + unicodeslot=0xA2FD, + }, + [0xA2FE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZUX", + direction="l", + linebreak="id", + unicodeslot=0xA2FE, + }, + [0xA2FF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZU", + direction="l", + linebreak="id", + unicodeslot=0xA2FF, + }, + [0xA300]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZUP", + direction="l", + linebreak="id", + unicodeslot=0xA300, + }, + [0xA301]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZURX", + direction="l", + linebreak="id", + unicodeslot=0xA301, + }, + [0xA302]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZUR", + direction="l", + linebreak="id", + unicodeslot=0xA302, + }, + [0xA303]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZYT", + direction="l", + linebreak="id", + unicodeslot=0xA303, + }, + [0xA304]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZYX", + direction="l", + linebreak="id", + unicodeslot=0xA304, + }, + [0xA305]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZY", + direction="l", + linebreak="id", + unicodeslot=0xA305, + }, + [0xA306]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZYP", + direction="l", + linebreak="id", + unicodeslot=0xA306, + }, + [0xA307]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZYRX", + direction="l", + linebreak="id", + unicodeslot=0xA307, + }, + [0xA308]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NZYR", + direction="l", + linebreak="id", + unicodeslot=0xA308, + }, + [0xA309]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SIT", + direction="l", + linebreak="id", + unicodeslot=0xA309, + }, + [0xA30A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SIX", + direction="l", + linebreak="id", + unicodeslot=0xA30A, + }, + [0xA30B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SI", + direction="l", + linebreak="id", + unicodeslot=0xA30B, + }, + [0xA30C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SIP", + direction="l", + linebreak="id", + unicodeslot=0xA30C, + }, + [0xA30D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SIEX", + direction="l", + linebreak="id", + unicodeslot=0xA30D, + }, + [0xA30E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SIE", + direction="l", + linebreak="id", + unicodeslot=0xA30E, + }, + [0xA30F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SIEP", + direction="l", + linebreak="id", + unicodeslot=0xA30F, + }, + [0xA310]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SAT", + direction="l", + linebreak="id", + unicodeslot=0xA310, + }, + [0xA311]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SAX", + direction="l", + linebreak="id", + unicodeslot=0xA311, + }, + [0xA312]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SA", + direction="l", + linebreak="id", + unicodeslot=0xA312, + }, + [0xA313]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SAP", + direction="l", + linebreak="id", + unicodeslot=0xA313, + }, + [0xA314]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SUOX", + direction="l", + linebreak="id", + unicodeslot=0xA314, + }, + [0xA315]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SUO", + direction="l", + linebreak="id", + unicodeslot=0xA315, + }, + [0xA316]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SUOP", + direction="l", + linebreak="id", + unicodeslot=0xA316, + }, + [0xA317]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SOT", + direction="l", + linebreak="id", + unicodeslot=0xA317, + }, + [0xA318]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SOX", + direction="l", + linebreak="id", + unicodeslot=0xA318, + }, + [0xA319]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SO", + direction="l", + linebreak="id", + unicodeslot=0xA319, + }, + [0xA31A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SOP", + direction="l", + linebreak="id", + unicodeslot=0xA31A, + }, + [0xA31B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SEX", + direction="l", + linebreak="id", + unicodeslot=0xA31B, + }, + [0xA31C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SE", + direction="l", + linebreak="id", + unicodeslot=0xA31C, + }, + [0xA31D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SEP", + direction="l", + linebreak="id", + unicodeslot=0xA31D, + }, + [0xA31E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SUT", + direction="l", + linebreak="id", + unicodeslot=0xA31E, + }, + [0xA31F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SUX", + direction="l", + linebreak="id", + unicodeslot=0xA31F, + }, + [0xA320]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SU", + direction="l", + linebreak="id", + unicodeslot=0xA320, + }, + [0xA321]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SUP", + direction="l", + linebreak="id", + unicodeslot=0xA321, + }, + [0xA322]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SURX", + direction="l", + linebreak="id", + unicodeslot=0xA322, + }, + [0xA323]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SUR", + direction="l", + linebreak="id", + unicodeslot=0xA323, + }, + [0xA324]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SYT", + direction="l", + linebreak="id", + unicodeslot=0xA324, + }, + [0xA325]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SYX", + direction="l", + linebreak="id", + unicodeslot=0xA325, + }, + [0xA326]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SY", + direction="l", + linebreak="id", + unicodeslot=0xA326, + }, + [0xA327]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SYP", + direction="l", + linebreak="id", + unicodeslot=0xA327, + }, + [0xA328]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SYRX", + direction="l", + linebreak="id", + unicodeslot=0xA328, + }, + [0xA329]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SYR", + direction="l", + linebreak="id", + unicodeslot=0xA329, + }, + [0xA32A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSIT", + direction="l", + linebreak="id", + unicodeslot=0xA32A, + }, + [0xA32B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSIX", + direction="l", + linebreak="id", + unicodeslot=0xA32B, + }, + [0xA32C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSI", + direction="l", + linebreak="id", + unicodeslot=0xA32C, + }, + [0xA32D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSIP", + direction="l", + linebreak="id", + unicodeslot=0xA32D, + }, + [0xA32E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSIEX", + direction="l", + linebreak="id", + unicodeslot=0xA32E, + }, + [0xA32F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSIE", + direction="l", + linebreak="id", + unicodeslot=0xA32F, + }, + [0xA330]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSIEP", + direction="l", + linebreak="id", + unicodeslot=0xA330, + }, + [0xA331]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSAT", + direction="l", + linebreak="id", + unicodeslot=0xA331, + }, + [0xA332]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSAX", + direction="l", + linebreak="id", + unicodeslot=0xA332, + }, + [0xA333]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSA", + direction="l", + linebreak="id", + unicodeslot=0xA333, + }, + [0xA334]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSAP", + direction="l", + linebreak="id", + unicodeslot=0xA334, + }, + [0xA335]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSOT", + direction="l", + linebreak="id", + unicodeslot=0xA335, + }, + [0xA336]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSOX", + direction="l", + linebreak="id", + unicodeslot=0xA336, + }, + [0xA337]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSO", + direction="l", + linebreak="id", + unicodeslot=0xA337, + }, + [0xA338]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSOP", + direction="l", + linebreak="id", + unicodeslot=0xA338, + }, + [0xA339]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSEX", + direction="l", + linebreak="id", + unicodeslot=0xA339, + }, + [0xA33A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSE", + direction="l", + linebreak="id", + unicodeslot=0xA33A, + }, + [0xA33B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSEP", + direction="l", + linebreak="id", + unicodeslot=0xA33B, + }, + [0xA33C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSUT", + direction="l", + linebreak="id", + unicodeslot=0xA33C, + }, + [0xA33D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSUX", + direction="l", + linebreak="id", + unicodeslot=0xA33D, + }, + [0xA33E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSU", + direction="l", + linebreak="id", + unicodeslot=0xA33E, + }, + [0xA33F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSUP", + direction="l", + linebreak="id", + unicodeslot=0xA33F, + }, + [0xA340]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSYT", + direction="l", + linebreak="id", + unicodeslot=0xA340, + }, + [0xA341]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSYX", + direction="l", + linebreak="id", + unicodeslot=0xA341, + }, + [0xA342]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSY", + direction="l", + linebreak="id", + unicodeslot=0xA342, + }, + [0xA343]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSYP", + direction="l", + linebreak="id", + unicodeslot=0xA343, + }, + [0xA344]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSYRX", + direction="l", + linebreak="id", + unicodeslot=0xA344, + }, + [0xA345]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SSYR", + direction="l", + linebreak="id", + unicodeslot=0xA345, + }, + [0xA346]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHAT", + direction="l", + linebreak="id", + unicodeslot=0xA346, + }, + [0xA347]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHAX", + direction="l", + linebreak="id", + unicodeslot=0xA347, + }, + [0xA348]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHA", + direction="l", + linebreak="id", + unicodeslot=0xA348, + }, + [0xA349]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHAP", + direction="l", + linebreak="id", + unicodeslot=0xA349, + }, + [0xA34A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHUOX", + direction="l", + linebreak="id", + unicodeslot=0xA34A, + }, + [0xA34B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHUO", + direction="l", + linebreak="id", + unicodeslot=0xA34B, + }, + [0xA34C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHUOP", + direction="l", + linebreak="id", + unicodeslot=0xA34C, + }, + [0xA34D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHOT", + direction="l", + linebreak="id", + unicodeslot=0xA34D, + }, + [0xA34E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHOX", + direction="l", + linebreak="id", + unicodeslot=0xA34E, + }, + [0xA34F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHO", + direction="l", + linebreak="id", + unicodeslot=0xA34F, + }, + [0xA350]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHOP", + direction="l", + linebreak="id", + unicodeslot=0xA350, + }, + [0xA351]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHET", + direction="l", + linebreak="id", + unicodeslot=0xA351, + }, + [0xA352]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHEX", + direction="l", + linebreak="id", + unicodeslot=0xA352, + }, + [0xA353]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHE", + direction="l", + linebreak="id", + unicodeslot=0xA353, + }, + [0xA354]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHEP", + direction="l", + linebreak="id", + unicodeslot=0xA354, + }, + [0xA355]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHUT", + direction="l", + linebreak="id", + unicodeslot=0xA355, + }, + [0xA356]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHUX", + direction="l", + linebreak="id", + unicodeslot=0xA356, + }, + [0xA357]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHU", + direction="l", + linebreak="id", + unicodeslot=0xA357, + }, + [0xA358]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHUP", + direction="l", + linebreak="id", + unicodeslot=0xA358, + }, + [0xA359]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHURX", + direction="l", + linebreak="id", + unicodeslot=0xA359, + }, + [0xA35A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHUR", + direction="l", + linebreak="id", + unicodeslot=0xA35A, + }, + [0xA35B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHYT", + direction="l", + linebreak="id", + unicodeslot=0xA35B, + }, + [0xA35C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHYX", + direction="l", + linebreak="id", + unicodeslot=0xA35C, + }, + [0xA35D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHY", + direction="l", + linebreak="id", + unicodeslot=0xA35D, + }, + [0xA35E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHYP", + direction="l", + linebreak="id", + unicodeslot=0xA35E, + }, + [0xA35F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHYRX", + direction="l", + linebreak="id", + unicodeslot=0xA35F, + }, + [0xA360]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ZHYR", + direction="l", + linebreak="id", + unicodeslot=0xA360, + }, + [0xA361]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHAT", + direction="l", + linebreak="id", + unicodeslot=0xA361, + }, + [0xA362]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHAX", + direction="l", + linebreak="id", + unicodeslot=0xA362, + }, + [0xA363]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHA", + direction="l", + linebreak="id", + unicodeslot=0xA363, + }, + [0xA364]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHAP", + direction="l", + linebreak="id", + unicodeslot=0xA364, + }, + [0xA365]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHUOT", + direction="l", + linebreak="id", + unicodeslot=0xA365, + }, + [0xA366]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHUOX", + direction="l", + linebreak="id", + unicodeslot=0xA366, + }, + [0xA367]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHUO", + direction="l", + linebreak="id", + unicodeslot=0xA367, + }, + [0xA368]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHUOP", + direction="l", + linebreak="id", + unicodeslot=0xA368, + }, + [0xA369]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHOT", + direction="l", + linebreak="id", + unicodeslot=0xA369, + }, + [0xA36A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHOX", + direction="l", + linebreak="id", + unicodeslot=0xA36A, + }, + [0xA36B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHO", + direction="l", + linebreak="id", + unicodeslot=0xA36B, + }, + [0xA36C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHOP", + direction="l", + linebreak="id", + unicodeslot=0xA36C, + }, + [0xA36D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHET", + direction="l", + linebreak="id", + unicodeslot=0xA36D, + }, + [0xA36E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHEX", + direction="l", + linebreak="id", + unicodeslot=0xA36E, + }, + [0xA36F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHE", + direction="l", + linebreak="id", + unicodeslot=0xA36F, + }, + [0xA370]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHEP", + direction="l", + linebreak="id", + unicodeslot=0xA370, + }, + [0xA371]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHUX", + direction="l", + linebreak="id", + unicodeslot=0xA371, + }, + [0xA372]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHU", + direction="l", + linebreak="id", + unicodeslot=0xA372, + }, + [0xA373]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHUP", + direction="l", + linebreak="id", + unicodeslot=0xA373, + }, + [0xA374]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHURX", + direction="l", + linebreak="id", + unicodeslot=0xA374, + }, + [0xA375]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHUR", + direction="l", + linebreak="id", + unicodeslot=0xA375, + }, + [0xA376]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHYT", + direction="l", + linebreak="id", + unicodeslot=0xA376, + }, + [0xA377]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHYX", + direction="l", + linebreak="id", + unicodeslot=0xA377, + }, + [0xA378]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHY", + direction="l", + linebreak="id", + unicodeslot=0xA378, + }, + [0xA379]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHYP", + direction="l", + linebreak="id", + unicodeslot=0xA379, + }, + [0xA37A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHYRX", + direction="l", + linebreak="id", + unicodeslot=0xA37A, + }, + [0xA37B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE CHYR", + direction="l", + linebreak="id", + unicodeslot=0xA37B, + }, + [0xA37C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RRAX", + direction="l", + linebreak="id", + unicodeslot=0xA37C, + }, + [0xA37D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RRA", + direction="l", + linebreak="id", + unicodeslot=0xA37D, + }, + [0xA37E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RRUOX", + direction="l", + linebreak="id", + unicodeslot=0xA37E, + }, + [0xA37F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RRUO", + direction="l", + linebreak="id", + unicodeslot=0xA37F, + }, + [0xA380]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RROT", + direction="l", + linebreak="id", + unicodeslot=0xA380, + }, + [0xA381]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RROX", + direction="l", + linebreak="id", + unicodeslot=0xA381, + }, + [0xA382]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RRO", + direction="l", + linebreak="id", + unicodeslot=0xA382, + }, + [0xA383]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RROP", + direction="l", + linebreak="id", + unicodeslot=0xA383, + }, + [0xA384]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RRET", + direction="l", + linebreak="id", + unicodeslot=0xA384, + }, + [0xA385]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RREX", + direction="l", + linebreak="id", + unicodeslot=0xA385, + }, + [0xA386]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RRE", + direction="l", + linebreak="id", + unicodeslot=0xA386, + }, + [0xA387]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RREP", + direction="l", + linebreak="id", + unicodeslot=0xA387, + }, + [0xA388]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RRUT", + direction="l", + linebreak="id", + unicodeslot=0xA388, + }, + [0xA389]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RRUX", + direction="l", + linebreak="id", + unicodeslot=0xA389, + }, + [0xA38A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RRU", + direction="l", + linebreak="id", + unicodeslot=0xA38A, + }, + [0xA38B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RRUP", + direction="l", + linebreak="id", + unicodeslot=0xA38B, + }, + [0xA38C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RRURX", + direction="l", + linebreak="id", + unicodeslot=0xA38C, + }, + [0xA38D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RRUR", + direction="l", + linebreak="id", + unicodeslot=0xA38D, + }, + [0xA38E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RRYT", + direction="l", + linebreak="id", + unicodeslot=0xA38E, + }, + [0xA38F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RRYX", + direction="l", + linebreak="id", + unicodeslot=0xA38F, + }, + [0xA390]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RRY", + direction="l", + linebreak="id", + unicodeslot=0xA390, + }, + [0xA391]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RRYP", + direction="l", + linebreak="id", + unicodeslot=0xA391, + }, + [0xA392]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RRYRX", + direction="l", + linebreak="id", + unicodeslot=0xA392, + }, + [0xA393]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RRYR", + direction="l", + linebreak="id", + unicodeslot=0xA393, + }, + [0xA394]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NRAT", + direction="l", + linebreak="id", + unicodeslot=0xA394, + }, + [0xA395]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NRAX", + direction="l", + linebreak="id", + unicodeslot=0xA395, + }, + [0xA396]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NRA", + direction="l", + linebreak="id", + unicodeslot=0xA396, + }, + [0xA397]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NRAP", + direction="l", + linebreak="id", + unicodeslot=0xA397, + }, + [0xA398]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NROX", + direction="l", + linebreak="id", + unicodeslot=0xA398, + }, + [0xA399]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NRO", + direction="l", + linebreak="id", + unicodeslot=0xA399, + }, + [0xA39A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NROP", + direction="l", + linebreak="id", + unicodeslot=0xA39A, + }, + [0xA39B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NRET", + direction="l", + linebreak="id", + unicodeslot=0xA39B, + }, + [0xA39C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NREX", + direction="l", + linebreak="id", + unicodeslot=0xA39C, + }, + [0xA39D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NRE", + direction="l", + linebreak="id", + unicodeslot=0xA39D, + }, + [0xA39E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NREP", + direction="l", + linebreak="id", + unicodeslot=0xA39E, + }, + [0xA39F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NRUT", + direction="l", + linebreak="id", + unicodeslot=0xA39F, + }, + [0xA3A0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NRUX", + direction="l", + linebreak="id", + unicodeslot=0xA3A0, + }, + [0xA3A1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NRU", + direction="l", + linebreak="id", + unicodeslot=0xA3A1, + }, + [0xA3A2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NRUP", + direction="l", + linebreak="id", + unicodeslot=0xA3A2, + }, + [0xA3A3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NRURX", + direction="l", + linebreak="id", + unicodeslot=0xA3A3, + }, + [0xA3A4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NRUR", + direction="l", + linebreak="id", + unicodeslot=0xA3A4, + }, + [0xA3A5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NRYT", + direction="l", + linebreak="id", + unicodeslot=0xA3A5, + }, + [0xA3A6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NRYX", + direction="l", + linebreak="id", + unicodeslot=0xA3A6, + }, + [0xA3A7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NRY", + direction="l", + linebreak="id", + unicodeslot=0xA3A7, + }, + [0xA3A8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NRYP", + direction="l", + linebreak="id", + unicodeslot=0xA3A8, + }, + [0xA3A9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NRYRX", + direction="l", + linebreak="id", + unicodeslot=0xA3A9, + }, + [0xA3AA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NRYR", + direction="l", + linebreak="id", + unicodeslot=0xA3AA, + }, + [0xA3AB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHAT", + direction="l", + linebreak="id", + unicodeslot=0xA3AB, + }, + [0xA3AC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHAX", + direction="l", + linebreak="id", + unicodeslot=0xA3AC, + }, + [0xA3AD]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHA", + direction="l", + linebreak="id", + unicodeslot=0xA3AD, + }, + [0xA3AE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHAP", + direction="l", + linebreak="id", + unicodeslot=0xA3AE, + }, + [0xA3AF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHUOX", + direction="l", + linebreak="id", + unicodeslot=0xA3AF, + }, + [0xA3B0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHUO", + direction="l", + linebreak="id", + unicodeslot=0xA3B0, + }, + [0xA3B1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHUOP", + direction="l", + linebreak="id", + unicodeslot=0xA3B1, + }, + [0xA3B2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHOT", + direction="l", + linebreak="id", + unicodeslot=0xA3B2, + }, + [0xA3B3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHOX", + direction="l", + linebreak="id", + unicodeslot=0xA3B3, + }, + [0xA3B4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHO", + direction="l", + linebreak="id", + unicodeslot=0xA3B4, + }, + [0xA3B5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHOP", + direction="l", + linebreak="id", + unicodeslot=0xA3B5, + }, + [0xA3B6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHET", + direction="l", + linebreak="id", + unicodeslot=0xA3B6, + }, + [0xA3B7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHEX", + direction="l", + linebreak="id", + unicodeslot=0xA3B7, + }, + [0xA3B8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHE", + direction="l", + linebreak="id", + unicodeslot=0xA3B8, + }, + [0xA3B9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHEP", + direction="l", + linebreak="id", + unicodeslot=0xA3B9, + }, + [0xA3BA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHUT", + direction="l", + linebreak="id", + unicodeslot=0xA3BA, + }, + [0xA3BB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHUX", + direction="l", + linebreak="id", + unicodeslot=0xA3BB, + }, + [0xA3BC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHU", + direction="l", + linebreak="id", + unicodeslot=0xA3BC, + }, + [0xA3BD]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHUP", + direction="l", + linebreak="id", + unicodeslot=0xA3BD, + }, + [0xA3BE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHURX", + direction="l", + linebreak="id", + unicodeslot=0xA3BE, + }, + [0xA3BF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHUR", + direction="l", + linebreak="id", + unicodeslot=0xA3BF, + }, + [0xA3C0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHYT", + direction="l", + linebreak="id", + unicodeslot=0xA3C0, + }, + [0xA3C1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHYX", + direction="l", + linebreak="id", + unicodeslot=0xA3C1, + }, + [0xA3C2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHY", + direction="l", + linebreak="id", + unicodeslot=0xA3C2, + }, + [0xA3C3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHYP", + direction="l", + linebreak="id", + unicodeslot=0xA3C3, + }, + [0xA3C4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHYRX", + direction="l", + linebreak="id", + unicodeslot=0xA3C4, + }, + [0xA3C5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE SHYR", + direction="l", + linebreak="id", + unicodeslot=0xA3C5, + }, + [0xA3C6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RAT", + direction="l", + linebreak="id", + unicodeslot=0xA3C6, + }, + [0xA3C7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RAX", + direction="l", + linebreak="id", + unicodeslot=0xA3C7, + }, + [0xA3C8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RA", + direction="l", + linebreak="id", + unicodeslot=0xA3C8, + }, + [0xA3C9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RAP", + direction="l", + linebreak="id", + unicodeslot=0xA3C9, + }, + [0xA3CA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RUOX", + direction="l", + linebreak="id", + unicodeslot=0xA3CA, + }, + [0xA3CB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RUO", + direction="l", + linebreak="id", + unicodeslot=0xA3CB, + }, + [0xA3CC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RUOP", + direction="l", + linebreak="id", + unicodeslot=0xA3CC, + }, + [0xA3CD]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ROT", + direction="l", + linebreak="id", + unicodeslot=0xA3CD, + }, + [0xA3CE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ROX", + direction="l", + linebreak="id", + unicodeslot=0xA3CE, + }, + [0xA3CF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RO", + direction="l", + linebreak="id", + unicodeslot=0xA3CF, + }, + [0xA3D0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE ROP", + direction="l", + linebreak="id", + unicodeslot=0xA3D0, + }, + [0xA3D1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE REX", + direction="l", + linebreak="id", + unicodeslot=0xA3D1, + }, + [0xA3D2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RE", + direction="l", + linebreak="id", + unicodeslot=0xA3D2, + }, + [0xA3D3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE REP", + direction="l", + linebreak="id", + unicodeslot=0xA3D3, + }, + [0xA3D4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RUT", + direction="l", + linebreak="id", + unicodeslot=0xA3D4, + }, + [0xA3D5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RUX", + direction="l", + linebreak="id", + unicodeslot=0xA3D5, + }, + [0xA3D6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RU", + direction="l", + linebreak="id", + unicodeslot=0xA3D6, + }, + [0xA3D7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RUP", + direction="l", + linebreak="id", + unicodeslot=0xA3D7, + }, + [0xA3D8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RURX", + direction="l", + linebreak="id", + unicodeslot=0xA3D8, + }, + [0xA3D9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RUR", + direction="l", + linebreak="id", + unicodeslot=0xA3D9, + }, + [0xA3DA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RYT", + direction="l", + linebreak="id", + unicodeslot=0xA3DA, + }, + [0xA3DB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RYX", + direction="l", + linebreak="id", + unicodeslot=0xA3DB, + }, + [0xA3DC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RY", + direction="l", + linebreak="id", + unicodeslot=0xA3DC, + }, + [0xA3DD]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RYP", + direction="l", + linebreak="id", + unicodeslot=0xA3DD, + }, + [0xA3DE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RYRX", + direction="l", + linebreak="id", + unicodeslot=0xA3DE, + }, + [0xA3DF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE RYR", + direction="l", + linebreak="id", + unicodeslot=0xA3DF, + }, + [0xA3E0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JIT", + direction="l", + linebreak="id", + unicodeslot=0xA3E0, + }, + [0xA3E1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JIX", + direction="l", + linebreak="id", + unicodeslot=0xA3E1, + }, + [0xA3E2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JI", + direction="l", + linebreak="id", + unicodeslot=0xA3E2, + }, + [0xA3E3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JIP", + direction="l", + linebreak="id", + unicodeslot=0xA3E3, + }, + [0xA3E4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JIET", + direction="l", + linebreak="id", + unicodeslot=0xA3E4, + }, + [0xA3E5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JIEX", + direction="l", + linebreak="id", + unicodeslot=0xA3E5, + }, + [0xA3E6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JIE", + direction="l", + linebreak="id", + unicodeslot=0xA3E6, + }, + [0xA3E7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JIEP", + direction="l", + linebreak="id", + unicodeslot=0xA3E7, + }, + [0xA3E8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JUOT", + direction="l", + linebreak="id", + unicodeslot=0xA3E8, + }, + [0xA3E9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JUOX", + direction="l", + linebreak="id", + unicodeslot=0xA3E9, + }, + [0xA3EA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JUO", + direction="l", + linebreak="id", + unicodeslot=0xA3EA, + }, + [0xA3EB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JUOP", + direction="l", + linebreak="id", + unicodeslot=0xA3EB, + }, + [0xA3EC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JOT", + direction="l", + linebreak="id", + unicodeslot=0xA3EC, + }, + [0xA3ED]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JOX", + direction="l", + linebreak="id", + unicodeslot=0xA3ED, + }, + [0xA3EE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JO", + direction="l", + linebreak="id", + unicodeslot=0xA3EE, + }, + [0xA3EF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JOP", + direction="l", + linebreak="id", + unicodeslot=0xA3EF, + }, + [0xA3F0]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JUT", + direction="l", + linebreak="id", + unicodeslot=0xA3F0, + }, + [0xA3F1]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JUX", + direction="l", + linebreak="id", + unicodeslot=0xA3F1, + }, + [0xA3F2]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JU", + direction="l", + linebreak="id", + unicodeslot=0xA3F2, + }, + [0xA3F3]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JUP", + direction="l", + linebreak="id", + unicodeslot=0xA3F3, + }, + [0xA3F4]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JURX", + direction="l", + linebreak="id", + unicodeslot=0xA3F4, + }, + [0xA3F5]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JUR", + direction="l", + linebreak="id", + unicodeslot=0xA3F5, + }, + [0xA3F6]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JYT", + direction="l", + linebreak="id", + unicodeslot=0xA3F6, + }, + [0xA3F7]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JYX", + direction="l", + linebreak="id", + unicodeslot=0xA3F7, + }, + [0xA3F8]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JY", + direction="l", + linebreak="id", + unicodeslot=0xA3F8, + }, + [0xA3F9]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JYP", + direction="l", + linebreak="id", + unicodeslot=0xA3F9, + }, + [0xA3FA]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JYRX", + direction="l", + linebreak="id", + unicodeslot=0xA3FA, + }, + [0xA3FB]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JYR", + direction="l", + linebreak="id", + unicodeslot=0xA3FB, + }, + [0xA3FC]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QIT", + direction="l", + linebreak="id", + unicodeslot=0xA3FC, + }, + [0xA3FD]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QIX", + direction="l", + linebreak="id", + unicodeslot=0xA3FD, + }, + [0xA3FE]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QI", + direction="l", + linebreak="id", + unicodeslot=0xA3FE, + }, + [0xA3FF]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QIP", + direction="l", + linebreak="id", + unicodeslot=0xA3FF, + }, + [0xA400]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QIET", + direction="l", + linebreak="id", + unicodeslot=0xA400, + }, + [0xA401]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QIEX", + direction="l", + linebreak="id", + unicodeslot=0xA401, + }, + [0xA402]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QIE", + direction="l", + linebreak="id", + unicodeslot=0xA402, + }, + [0xA403]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QIEP", + direction="l", + linebreak="id", + unicodeslot=0xA403, + }, + [0xA404]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QUOT", + direction="l", + linebreak="id", + unicodeslot=0xA404, + }, + [0xA405]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QUOX", + direction="l", + linebreak="id", + unicodeslot=0xA405, + }, + [0xA406]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QUO", + direction="l", + linebreak="id", + unicodeslot=0xA406, + }, + [0xA407]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QUOP", + direction="l", + linebreak="id", + unicodeslot=0xA407, + }, + [0xA408]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QOT", + direction="l", + linebreak="id", + unicodeslot=0xA408, + }, + [0xA409]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QOX", + direction="l", + linebreak="id", + unicodeslot=0xA409, + }, + [0xA40A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QO", + direction="l", + linebreak="id", + unicodeslot=0xA40A, + }, + [0xA40B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QOP", + direction="l", + linebreak="id", + unicodeslot=0xA40B, + }, + [0xA40C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QUT", + direction="l", + linebreak="id", + unicodeslot=0xA40C, + }, + [0xA40D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QUX", + direction="l", + linebreak="id", + unicodeslot=0xA40D, + }, + [0xA40E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QU", + direction="l", + linebreak="id", + unicodeslot=0xA40E, + }, + [0xA40F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QUP", + direction="l", + linebreak="id", + unicodeslot=0xA40F, + }, + [0xA410]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QURX", + direction="l", + linebreak="id", + unicodeslot=0xA410, + }, + [0xA411]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QUR", + direction="l", + linebreak="id", + unicodeslot=0xA411, + }, + [0xA412]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QYT", + direction="l", + linebreak="id", + unicodeslot=0xA412, + }, + [0xA413]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QYX", + direction="l", + linebreak="id", + unicodeslot=0xA413, + }, + [0xA414]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QY", + direction="l", + linebreak="id", + unicodeslot=0xA414, + }, + [0xA415]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QYP", + direction="l", + linebreak="id", + unicodeslot=0xA415, + }, + [0xA416]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QYRX", + direction="l", + linebreak="id", + unicodeslot=0xA416, + }, + [0xA417]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE QYR", + direction="l", + linebreak="id", + unicodeslot=0xA417, + }, + [0xA418]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJIT", + direction="l", + linebreak="id", + unicodeslot=0xA418, + }, + [0xA419]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJIX", + direction="l", + linebreak="id", + unicodeslot=0xA419, + }, + [0xA41A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJI", + direction="l", + linebreak="id", + unicodeslot=0xA41A, + }, + [0xA41B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJIP", + direction="l", + linebreak="id", + unicodeslot=0xA41B, + }, + [0xA41C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJIET", + direction="l", + linebreak="id", + unicodeslot=0xA41C, + }, + [0xA41D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJIEX", + direction="l", + linebreak="id", + unicodeslot=0xA41D, + }, + [0xA41E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJIE", + direction="l", + linebreak="id", + unicodeslot=0xA41E, + }, + [0xA41F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJIEP", + direction="l", + linebreak="id", + unicodeslot=0xA41F, + }, + [0xA420]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJUOX", + direction="l", + linebreak="id", + unicodeslot=0xA420, + }, + [0xA421]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJUO", + direction="l", + linebreak="id", + unicodeslot=0xA421, + }, + [0xA422]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJUOP", + direction="l", + linebreak="id", + unicodeslot=0xA422, + }, + [0xA423]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJOT", + direction="l", + linebreak="id", + unicodeslot=0xA423, + }, + [0xA424]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJOX", + direction="l", + linebreak="id", + unicodeslot=0xA424, + }, + [0xA425]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJO", + direction="l", + linebreak="id", + unicodeslot=0xA425, + }, + [0xA426]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJOP", + direction="l", + linebreak="id", + unicodeslot=0xA426, + }, + [0xA427]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJUT", + direction="l", + linebreak="id", + unicodeslot=0xA427, + }, + [0xA428]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJUX", + direction="l", + linebreak="id", + unicodeslot=0xA428, + }, + [0xA429]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJU", + direction="l", + linebreak="id", + unicodeslot=0xA429, + }, + [0xA42A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJUP", + direction="l", + linebreak="id", + unicodeslot=0xA42A, + }, + [0xA42B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJURX", + direction="l", + linebreak="id", + unicodeslot=0xA42B, + }, + [0xA42C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJUR", + direction="l", + linebreak="id", + unicodeslot=0xA42C, + }, + [0xA42D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJYT", + direction="l", + linebreak="id", + unicodeslot=0xA42D, + }, + [0xA42E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJYX", + direction="l", + linebreak="id", + unicodeslot=0xA42E, + }, + [0xA42F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJY", + direction="l", + linebreak="id", + unicodeslot=0xA42F, + }, + [0xA430]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE JJYP", + direction="l", + linebreak="id", + unicodeslot=0xA430, + }, + [0xA431]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJIT", + direction="l", + linebreak="id", + unicodeslot=0xA431, + }, + [0xA432]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJIX", + direction="l", + linebreak="id", + unicodeslot=0xA432, + }, + [0xA433]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJI", + direction="l", + linebreak="id", + unicodeslot=0xA433, + }, + [0xA434]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJIP", + direction="l", + linebreak="id", + unicodeslot=0xA434, + }, + [0xA435]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJIET", + direction="l", + linebreak="id", + unicodeslot=0xA435, + }, + [0xA436]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJIEX", + direction="l", + linebreak="id", + unicodeslot=0xA436, + }, + [0xA437]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJIE", + direction="l", + linebreak="id", + unicodeslot=0xA437, + }, + [0xA438]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJIEP", + direction="l", + linebreak="id", + unicodeslot=0xA438, + }, + [0xA439]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJUOX", + direction="l", + linebreak="id", + unicodeslot=0xA439, + }, + [0xA43A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJUO", + direction="l", + linebreak="id", + unicodeslot=0xA43A, + }, + [0xA43B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJOT", + direction="l", + linebreak="id", + unicodeslot=0xA43B, + }, + [0xA43C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJOX", + direction="l", + linebreak="id", + unicodeslot=0xA43C, + }, + [0xA43D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJO", + direction="l", + linebreak="id", + unicodeslot=0xA43D, + }, + [0xA43E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJOP", + direction="l", + linebreak="id", + unicodeslot=0xA43E, + }, + [0xA43F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJUX", + direction="l", + linebreak="id", + unicodeslot=0xA43F, + }, + [0xA440]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJU", + direction="l", + linebreak="id", + unicodeslot=0xA440, + }, + [0xA441]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJUP", + direction="l", + linebreak="id", + unicodeslot=0xA441, + }, + [0xA442]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJURX", + direction="l", + linebreak="id", + unicodeslot=0xA442, + }, + [0xA443]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJUR", + direction="l", + linebreak="id", + unicodeslot=0xA443, + }, + [0xA444]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJYT", + direction="l", + linebreak="id", + unicodeslot=0xA444, + }, + [0xA445]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJYX", + direction="l", + linebreak="id", + unicodeslot=0xA445, + }, + [0xA446]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJY", + direction="l", + linebreak="id", + unicodeslot=0xA446, + }, + [0xA447]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJYP", + direction="l", + linebreak="id", + unicodeslot=0xA447, + }, + [0xA448]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJYRX", + direction="l", + linebreak="id", + unicodeslot=0xA448, + }, + [0xA449]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NJYR", + direction="l", + linebreak="id", + unicodeslot=0xA449, + }, + [0xA44A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NYIT", + direction="l", + linebreak="id", + unicodeslot=0xA44A, + }, + [0xA44B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NYIX", + direction="l", + linebreak="id", + unicodeslot=0xA44B, + }, + [0xA44C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NYI", + direction="l", + linebreak="id", + unicodeslot=0xA44C, + }, + [0xA44D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NYIP", + direction="l", + linebreak="id", + unicodeslot=0xA44D, + }, + [0xA44E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NYIET", + direction="l", + linebreak="id", + unicodeslot=0xA44E, + }, + [0xA44F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NYIEX", + direction="l", + linebreak="id", + unicodeslot=0xA44F, + }, + [0xA450]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NYIE", + direction="l", + linebreak="id", + unicodeslot=0xA450, + }, + [0xA451]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NYIEP", + direction="l", + linebreak="id", + unicodeslot=0xA451, + }, + [0xA452]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NYUOX", + direction="l", + linebreak="id", + unicodeslot=0xA452, + }, + [0xA453]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NYUO", + direction="l", + linebreak="id", + unicodeslot=0xA453, + }, + [0xA454]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NYUOP", + direction="l", + linebreak="id", + unicodeslot=0xA454, + }, + [0xA455]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NYOT", + direction="l", + linebreak="id", + unicodeslot=0xA455, + }, + [0xA456]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NYOX", + direction="l", + linebreak="id", + unicodeslot=0xA456, + }, + [0xA457]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NYO", + direction="l", + linebreak="id", + unicodeslot=0xA457, + }, + [0xA458]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NYOP", + direction="l", + linebreak="id", + unicodeslot=0xA458, + }, + [0xA459]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NYUT", + direction="l", + linebreak="id", + unicodeslot=0xA459, + }, + [0xA45A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NYUX", + direction="l", + linebreak="id", + unicodeslot=0xA45A, + }, + [0xA45B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NYU", + direction="l", + linebreak="id", + unicodeslot=0xA45B, + }, + [0xA45C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE NYUP", + direction="l", + linebreak="id", + unicodeslot=0xA45C, + }, + [0xA45D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE XIT", + direction="l", + linebreak="id", + unicodeslot=0xA45D, + }, + [0xA45E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE XIX", + direction="l", + linebreak="id", + unicodeslot=0xA45E, + }, + [0xA45F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE XI", + direction="l", + linebreak="id", + unicodeslot=0xA45F, + }, + [0xA460]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE XIP", + direction="l", + linebreak="id", + unicodeslot=0xA460, + }, + [0xA461]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE XIET", + direction="l", + linebreak="id", + unicodeslot=0xA461, + }, + [0xA462]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE XIEX", + direction="l", + linebreak="id", + unicodeslot=0xA462, + }, + [0xA463]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE XIE", + direction="l", + linebreak="id", + unicodeslot=0xA463, + }, + [0xA464]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE XIEP", + direction="l", + linebreak="id", + unicodeslot=0xA464, + }, + [0xA465]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE XUOX", + direction="l", + linebreak="id", + unicodeslot=0xA465, + }, + [0xA466]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE XUO", + direction="l", + linebreak="id", + unicodeslot=0xA466, + }, + [0xA467]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE XOT", + direction="l", + linebreak="id", + unicodeslot=0xA467, + }, + [0xA468]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE XOX", + direction="l", + linebreak="id", + unicodeslot=0xA468, + }, + [0xA469]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE XO", + direction="l", + linebreak="id", + unicodeslot=0xA469, + }, + [0xA46A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE XOP", + direction="l", + linebreak="id", + unicodeslot=0xA46A, + }, + [0xA46B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE XYT", + direction="l", + linebreak="id", + unicodeslot=0xA46B, + }, + [0xA46C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE XYX", + direction="l", + linebreak="id", + unicodeslot=0xA46C, + }, + [0xA46D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE XY", + direction="l", + linebreak="id", + unicodeslot=0xA46D, + }, + [0xA46E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE XYP", + direction="l", + linebreak="id", + unicodeslot=0xA46E, + }, + [0xA46F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE XYRX", + direction="l", + linebreak="id", + unicodeslot=0xA46F, + }, + [0xA470]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE XYR", + direction="l", + linebreak="id", + unicodeslot=0xA470, + }, + [0xA471]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YIT", + direction="l", + linebreak="id", + unicodeslot=0xA471, + }, + [0xA472]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YIX", + direction="l", + linebreak="id", + unicodeslot=0xA472, + }, + [0xA473]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YI", + direction="l", + linebreak="id", + unicodeslot=0xA473, + }, + [0xA474]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YIP", + direction="l", + linebreak="id", + unicodeslot=0xA474, + }, + [0xA475]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YIET", + direction="l", + linebreak="id", + unicodeslot=0xA475, + }, + [0xA476]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YIEX", + direction="l", + linebreak="id", + unicodeslot=0xA476, + }, + [0xA477]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YIE", + direction="l", + linebreak="id", + unicodeslot=0xA477, + }, + [0xA478]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YIEP", + direction="l", + linebreak="id", + unicodeslot=0xA478, + }, + [0xA479]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YUOT", + direction="l", + linebreak="id", + unicodeslot=0xA479, + }, + [0xA47A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YUOX", + direction="l", + linebreak="id", + unicodeslot=0xA47A, + }, + [0xA47B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YUO", + direction="l", + linebreak="id", + unicodeslot=0xA47B, + }, + [0xA47C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YUOP", + direction="l", + linebreak="id", + unicodeslot=0xA47C, + }, + [0xA47D]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YOT", + direction="l", + linebreak="id", + unicodeslot=0xA47D, + }, + [0xA47E]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YOX", + direction="l", + linebreak="id", + unicodeslot=0xA47E, + }, + [0xA47F]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YO", + direction="l", + linebreak="id", + unicodeslot=0xA47F, + }, + [0xA480]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YOP", + direction="l", + linebreak="id", + unicodeslot=0xA480, + }, + [0xA481]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YUT", + direction="l", + linebreak="id", + unicodeslot=0xA481, + }, + [0xA482]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YUX", + direction="l", + linebreak="id", + unicodeslot=0xA482, + }, + [0xA483]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YU", + direction="l", + linebreak="id", + unicodeslot=0xA483, + }, + [0xA484]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YUP", + direction="l", + linebreak="id", + unicodeslot=0xA484, + }, + [0xA485]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YURX", + direction="l", + linebreak="id", + unicodeslot=0xA485, + }, + [0xA486]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YUR", + direction="l", + linebreak="id", + unicodeslot=0xA486, + }, + [0xA487]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YYT", + direction="l", + linebreak="id", + unicodeslot=0xA487, + }, + [0xA488]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YYX", + direction="l", + linebreak="id", + unicodeslot=0xA488, + }, + [0xA489]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YY", + direction="l", + linebreak="id", + unicodeslot=0xA489, + }, + [0xA48A]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YYP", + direction="l", + linebreak="id", + unicodeslot=0xA48A, + }, + [0xA48B]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YYRX", + direction="l", + linebreak="id", + unicodeslot=0xA48B, + }, + [0xA48C]={ + category="lo", + cjkwd="w", + description="YI SYLLABLE YYR", + direction="l", + linebreak="id", + unicodeslot=0xA48C, + }, + [0xA490]={ + category="so", + cjkwd="w", + description="YI RADICAL QOT", + direction="on", + linebreak="id", + unicodeslot=0xA490, + }, + [0xA491]={ + category="so", + cjkwd="w", + description="YI RADICAL LI", + direction="on", + linebreak="id", + unicodeslot=0xA491, + }, + [0xA492]={ + category="so", + cjkwd="w", + description="YI RADICAL KIT", + direction="on", + linebreak="id", + unicodeslot=0xA492, + }, + [0xA493]={ + category="so", + cjkwd="w", + description="YI RADICAL NYIP", + direction="on", + linebreak="id", + unicodeslot=0xA493, + }, + [0xA494]={ + category="so", + cjkwd="w", + description="YI RADICAL CYP", + direction="on", + linebreak="id", + unicodeslot=0xA494, + }, + [0xA495]={ + category="so", + cjkwd="w", + description="YI RADICAL SSI", + direction="on", + linebreak="id", + unicodeslot=0xA495, + }, + [0xA496]={ + category="so", + cjkwd="w", + description="YI RADICAL GGOP", + direction="on", + linebreak="id", + unicodeslot=0xA496, + }, + [0xA497]={ + category="so", + cjkwd="w", + description="YI RADICAL GEP", + direction="on", + linebreak="id", + unicodeslot=0xA497, + }, + [0xA498]={ + category="so", + cjkwd="w", + description="YI RADICAL MI", + direction="on", + linebreak="id", + unicodeslot=0xA498, + }, + [0xA499]={ + category="so", + cjkwd="w", + description="YI RADICAL HXIT", + direction="on", + linebreak="id", + unicodeslot=0xA499, + }, + [0xA49A]={ + category="so", + cjkwd="w", + description="YI RADICAL LYR", + direction="on", + linebreak="id", + unicodeslot=0xA49A, + }, + [0xA49B]={ + category="so", + cjkwd="w", + description="YI RADICAL BBUT", + direction="on", + linebreak="id", + unicodeslot=0xA49B, + }, + [0xA49C]={ + category="so", + cjkwd="w", + description="YI RADICAL MOP", + direction="on", + linebreak="id", + unicodeslot=0xA49C, + }, + [0xA49D]={ + category="so", + cjkwd="w", + description="YI RADICAL YO", + direction="on", + linebreak="id", + unicodeslot=0xA49D, + }, + [0xA49E]={ + category="so", + cjkwd="w", + description="YI RADICAL PUT", + direction="on", + linebreak="id", + unicodeslot=0xA49E, + }, + [0xA49F]={ + category="so", + cjkwd="w", + description="YI RADICAL HXUO", + direction="on", + linebreak="id", + unicodeslot=0xA49F, + }, + [0xA4A0]={ + category="so", + cjkwd="w", + description="YI RADICAL TAT", + direction="on", + linebreak="id", + unicodeslot=0xA4A0, + }, + [0xA4A1]={ + category="so", + cjkwd="w", + description="YI RADICAL GA", + direction="on", + linebreak="id", + unicodeslot=0xA4A1, + }, + [0xA4A2]={ + category="so", + cjkwd="w", + description="YI RADICAL ZUP", + direction="on", + linebreak="id", + unicodeslot=0xA4A2, + }, + [0xA4A3]={ + category="so", + cjkwd="w", + description="YI RADICAL CYT", + direction="on", + linebreak="id", + unicodeslot=0xA4A3, + }, + [0xA4A4]={ + category="so", + cjkwd="w", + description="YI RADICAL DDUR", + direction="on", + linebreak="id", + unicodeslot=0xA4A4, + }, + [0xA4A5]={ + category="so", + cjkwd="w", + description="YI RADICAL BUR", + direction="on", + linebreak="id", + unicodeslot=0xA4A5, + }, + [0xA4A6]={ + category="so", + cjkwd="w", + description="YI RADICAL GGUO", + direction="on", + linebreak="id", + unicodeslot=0xA4A6, + }, + [0xA4A7]={ + category="so", + cjkwd="w", + description="YI RADICAL NYOP", + direction="on", + linebreak="id", + unicodeslot=0xA4A7, + }, + [0xA4A8]={ + category="so", + cjkwd="w", + description="YI RADICAL TU", + direction="on", + linebreak="id", + unicodeslot=0xA4A8, + }, + [0xA4A9]={ + category="so", + cjkwd="w", + description="YI RADICAL OP", + direction="on", + linebreak="id", + unicodeslot=0xA4A9, + }, + [0xA4AA]={ + category="so", + cjkwd="w", + description="YI RADICAL JJUT", + direction="on", + linebreak="id", + unicodeslot=0xA4AA, + }, + [0xA4AB]={ + category="so", + cjkwd="w", + description="YI RADICAL ZOT", + direction="on", + linebreak="id", + unicodeslot=0xA4AB, + }, + [0xA4AC]={ + category="so", + cjkwd="w", + description="YI RADICAL PYT", + direction="on", + linebreak="id", + unicodeslot=0xA4AC, + }, + [0xA4AD]={ + category="so", + cjkwd="w", + description="YI RADICAL HMO", + direction="on", + linebreak="id", + unicodeslot=0xA4AD, + }, + [0xA4AE]={ + category="so", + cjkwd="w", + description="YI RADICAL YIT", + direction="on", + linebreak="id", + unicodeslot=0xA4AE, + }, + [0xA4AF]={ + category="so", + cjkwd="w", + description="YI RADICAL VUR", + direction="on", + linebreak="id", + unicodeslot=0xA4AF, + }, + [0xA4B0]={ + category="so", + cjkwd="w", + description="YI RADICAL SHY", + direction="on", + linebreak="id", + unicodeslot=0xA4B0, + }, + [0xA4B1]={ + category="so", + cjkwd="w", + description="YI RADICAL VEP", + direction="on", + linebreak="id", + unicodeslot=0xA4B1, + }, + [0xA4B2]={ + category="so", + cjkwd="w", + description="YI RADICAL ZA", + direction="on", + linebreak="id", + unicodeslot=0xA4B2, + }, + [0xA4B3]={ + category="so", + cjkwd="w", + description="YI RADICAL JO", + direction="on", + linebreak="id", + unicodeslot=0xA4B3, + }, + [0xA4B4]={ + category="so", + cjkwd="w", + description="YI RADICAL NZUP", + direction="on", + linebreak="id", + unicodeslot=0xA4B4, + }, + [0xA4B5]={ + category="so", + cjkwd="w", + description="YI RADICAL JJY", + direction="on", + linebreak="id", + unicodeslot=0xA4B5, + }, + [0xA4B6]={ + category="so", + cjkwd="w", + description="YI RADICAL GOT", + direction="on", + linebreak="id", + unicodeslot=0xA4B6, + }, + [0xA4B7]={ + category="so", + cjkwd="w", + description="YI RADICAL JJIE", + direction="on", + linebreak="id", + unicodeslot=0xA4B7, + }, + [0xA4B8]={ + category="so", + cjkwd="w", + description="YI RADICAL WO", + direction="on", + linebreak="id", + unicodeslot=0xA4B8, + }, + [0xA4B9]={ + category="so", + cjkwd="w", + description="YI RADICAL DU", + direction="on", + linebreak="id", + unicodeslot=0xA4B9, + }, + [0xA4BA]={ + category="so", + cjkwd="w", + description="YI RADICAL SHUR", + direction="on", + linebreak="id", + unicodeslot=0xA4BA, + }, + [0xA4BB]={ + category="so", + cjkwd="w", + description="YI RADICAL LIE", + direction="on", + linebreak="id", + unicodeslot=0xA4BB, + }, + [0xA4BC]={ + category="so", + cjkwd="w", + description="YI RADICAL CY", + direction="on", + linebreak="id", + unicodeslot=0xA4BC, + }, + [0xA4BD]={ + category="so", + cjkwd="w", + description="YI RADICAL CUOP", + direction="on", + linebreak="id", + unicodeslot=0xA4BD, + }, + [0xA4BE]={ + category="so", + cjkwd="w", + description="YI RADICAL CIP", + direction="on", + linebreak="id", + unicodeslot=0xA4BE, + }, + [0xA4BF]={ + category="so", + cjkwd="w", + description="YI RADICAL HXOP", + direction="on", + linebreak="id", + unicodeslot=0xA4BF, + }, + [0xA4C0]={ + category="so", + cjkwd="w", + description="YI RADICAL SHAT", + direction="on", + linebreak="id", + unicodeslot=0xA4C0, + }, + [0xA4C1]={ + category="so", + cjkwd="w", + description="YI RADICAL ZUR", + direction="on", + linebreak="id", + unicodeslot=0xA4C1, + }, + [0xA4C2]={ + category="so", + cjkwd="w", + description="YI RADICAL SHOP", + direction="on", + linebreak="id", + unicodeslot=0xA4C2, + }, + [0xA4C3]={ + category="so", + cjkwd="w", + description="YI RADICAL CHE", + direction="on", + linebreak="id", + unicodeslot=0xA4C3, + }, + [0xA4C4]={ + category="so", + cjkwd="w", + description="YI RADICAL ZZIET", + direction="on", + linebreak="id", + unicodeslot=0xA4C4, + }, + [0xA4C5]={ + category="so", + cjkwd="w", + description="YI RADICAL NBIE", + direction="on", + linebreak="id", + unicodeslot=0xA4C5, + }, + [0xA4C6]={ + category="so", + cjkwd="w", + description="YI RADICAL KE", + direction="on", + linebreak="id", + unicodeslot=0xA4C6, + }, + [0xA700]={ + category="sk", + description="MODIFIER LETTER CHINESE TONE YIN PING", + direction="on", + linebreak="al", + unicodeslot=0xA700, + }, + [0xA701]={ + category="sk", + description="MODIFIER LETTER CHINESE TONE YANG PING", + direction="on", + linebreak="al", + unicodeslot=0xA701, + }, + [0xA702]={ + category="sk", + description="MODIFIER LETTER CHINESE TONE YIN SHANG", + direction="on", + linebreak="al", + unicodeslot=0xA702, + }, + [0xA703]={ + category="sk", + description="MODIFIER LETTER CHINESE TONE YANG SHANG", + direction="on", + linebreak="al", + unicodeslot=0xA703, + }, + [0xA704]={ + category="sk", + description="MODIFIER LETTER CHINESE TONE YIN QU", + direction="on", + linebreak="al", + unicodeslot=0xA704, + }, + [0xA705]={ + category="sk", + description="MODIFIER LETTER CHINESE TONE YANG QU", + direction="on", + linebreak="al", + unicodeslot=0xA705, + }, + [0xA706]={ + category="sk", + description="MODIFIER LETTER CHINESE TONE YIN RU", + direction="on", + linebreak="al", + unicodeslot=0xA706, + }, + [0xA707]={ + category="sk", + description="MODIFIER LETTER CHINESE TONE YANG RU", + direction="on", + linebreak="al", + unicodeslot=0xA707, + }, + [0xA708]={ + category="sk", + description="MODIFIER LETTER EXTRA-HIGH DOTTED TONE BAR", + direction="on", + linebreak="al", + unicodeslot=0xA708, + }, + [0xA709]={ + category="sk", + description="MODIFIER LETTER HIGH DOTTED TONE BAR", + direction="on", + linebreak="al", + unicodeslot=0xA709, + }, + [0xA70A]={ + category="sk", + description="MODIFIER LETTER MID DOTTED TONE BAR", + direction="on", + linebreak="al", + unicodeslot=0xA70A, + }, + [0xA70B]={ + category="sk", + description="MODIFIER LETTER LOW DOTTED TONE BAR", + direction="on", + linebreak="al", + unicodeslot=0xA70B, + }, + [0xA70C]={ + category="sk", + description="MODIFIER LETTER EXTRA-LOW DOTTED TONE BAR", + direction="on", + linebreak="al", + unicodeslot=0xA70C, + }, + [0xA70D]={ + category="sk", + description="MODIFIER LETTER EXTRA-HIGH DOTTED LEFT-STEM TONE BAR", + direction="on", + linebreak="al", + unicodeslot=0xA70D, + }, + [0xA70E]={ + category="sk", + description="MODIFIER LETTER HIGH DOTTED LEFT-STEM TONE BAR", + direction="on", + linebreak="al", + unicodeslot=0xA70E, + }, + [0xA70F]={ + category="sk", + description="MODIFIER LETTER MID DOTTED LEFT-STEM TONE BAR", + direction="on", + linebreak="al", + unicodeslot=0xA70F, + }, + [0xA710]={ + category="sk", + description="MODIFIER LETTER LOW DOTTED LEFT-STEM TONE BAR", + direction="on", + linebreak="al", + unicodeslot=0xA710, + }, + [0xA711]={ + category="sk", + description="MODIFIER LETTER EXTRA-LOW DOTTED LEFT-STEM TONE BAR", + direction="on", + linebreak="al", + unicodeslot=0xA711, + }, + [0xA712]={ + category="sk", + description="MODIFIER LETTER EXTRA-HIGH LEFT-STEM TONE BAR", + direction="on", + linebreak="al", + unicodeslot=0xA712, + }, + [0xA713]={ + category="sk", + description="MODIFIER LETTER HIGH LEFT-STEM TONE BAR", + direction="on", + linebreak="al", + unicodeslot=0xA713, + }, + [0xA714]={ + category="sk", + description="MODIFIER LETTER MID LEFT-STEM TONE BAR", + direction="on", + linebreak="al", + unicodeslot=0xA714, + }, + [0xA715]={ + category="sk", + description="MODIFIER LETTER LOW LEFT-STEM TONE BAR", + direction="on", + linebreak="al", + unicodeslot=0xA715, + }, + [0xA716]={ + category="sk", + description="MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR", + direction="on", + linebreak="al", + unicodeslot=0xA716, + }, + [0xA717]={ + category="lm", + description="MODIFIER LETTER DOT VERTICAL BAR", + direction="on", + linebreak="al", + unicodeslot=0xA717, + }, + [0xA718]={ + category="lm", + description="MODIFIER LETTER DOT SLASH", + direction="on", + linebreak="al", + unicodeslot=0xA718, + }, + [0xA719]={ + category="lm", + description="MODIFIER LETTER DOT HORIZONTAL BAR", + direction="on", + linebreak="al", + unicodeslot=0xA719, + }, + [0xA71A]={ + category="lm", + description="MODIFIER LETTER LOWER RIGHT CORNER ANGLE", + direction="on", + linebreak="al", + unicodeslot=0xA71A, + }, + [0xA720]={ + category="sk", + description="MODIFIER LETTER STRESS AND HIGH TONE", + direction="on", + linebreak="al", + unicodeslot=0xA720, + }, + [0xA721]={ + category="sk", + description="MODIFIER LETTER STRESS AND LOW TONE", + direction="on", + linebreak="al", + unicodeslot=0xA721, + }, + [0xA800]={ + category="lo", + description="SYLOTI NAGRI LETTER A", + direction="l", + linebreak="al", + unicodeslot=0xA800, + }, + [0xA801]={ + category="lo", + description="SYLOTI NAGRI LETTER I", + direction="l", + linebreak="al", + unicodeslot=0xA801, + }, + [0xA802]={ + category="mc", + description="SYLOTI NAGRI SIGN DVISVARA", + direction="nsm", + linebreak="cm", + unicodeslot=0xA802, + }, + [0xA803]={ + category="lo", + description="SYLOTI NAGRI LETTER U", + direction="l", + linebreak="al", + unicodeslot=0xA803, + }, + [0xA804]={ + category="lo", + description="SYLOTI NAGRI LETTER E", + direction="l", + linebreak="al", + unicodeslot=0xA804, + }, + [0xA805]={ + category="lo", + description="SYLOTI NAGRI LETTER O", + direction="l", + linebreak="al", + unicodeslot=0xA805, + }, + [0xA806]={ + category="mn", + description="SYLOTI NAGRI SIGN HASANTA", + direction="nsm", + linebreak="cm", + unicodeslot=0xA806, + }, + [0xA807]={ + category="lo", + description="SYLOTI NAGRI LETTER KO", + direction="l", + linebreak="al", + unicodeslot=0xA807, + }, + [0xA808]={ + category="lo", + description="SYLOTI NAGRI LETTER KHO", + direction="l", + linebreak="al", + unicodeslot=0xA808, + }, + [0xA809]={ + category="lo", + description="SYLOTI NAGRI LETTER GO", + direction="l", + linebreak="al", + unicodeslot=0xA809, + }, + [0xA80A]={ + category="lo", + description="SYLOTI NAGRI LETTER GHO", + direction="l", + linebreak="al", + unicodeslot=0xA80A, + }, + [0xA80B]={ + category="mn", + description="SYLOTI NAGRI SIGN ANUSVARA", + direction="nsm", + linebreak="cm", + unicodeslot=0xA80B, + }, + [0xA80C]={ + category="lo", + description="SYLOTI NAGRI LETTER CO", + direction="l", + linebreak="al", + unicodeslot=0xA80C, + }, + [0xA80D]={ + category="lo", + description="SYLOTI NAGRI LETTER CHO", + direction="l", + linebreak="al", + unicodeslot=0xA80D, + }, + [0xA80E]={ + category="lo", + description="SYLOTI NAGRI LETTER JO", + direction="l", + linebreak="al", + unicodeslot=0xA80E, + }, + [0xA80F]={ + category="lo", + description="SYLOTI NAGRI LETTER JHO", + direction="l", + linebreak="al", + unicodeslot=0xA80F, + }, + [0xA810]={ + category="lo", + description="SYLOTI NAGRI LETTER TTO", + direction="l", + linebreak="al", + unicodeslot=0xA810, + }, + [0xA811]={ + category="lo", + description="SYLOTI NAGRI LETTER TTHO", + direction="l", + linebreak="al", + unicodeslot=0xA811, + }, + [0xA812]={ + category="lo", + description="SYLOTI NAGRI LETTER DDO", + direction="l", + linebreak="al", + unicodeslot=0xA812, + }, + [0xA813]={ + category="lo", + description="SYLOTI NAGRI LETTER DDHO", + direction="l", + linebreak="al", + unicodeslot=0xA813, + }, + [0xA814]={ + category="lo", + description="SYLOTI NAGRI LETTER TO", + direction="l", + linebreak="al", + unicodeslot=0xA814, + }, + [0xA815]={ + category="lo", + description="SYLOTI NAGRI LETTER THO", + direction="l", + linebreak="al", + unicodeslot=0xA815, + }, + [0xA816]={ + category="lo", + description="SYLOTI NAGRI LETTER DO", + direction="l", + linebreak="al", + unicodeslot=0xA816, + }, + [0xA817]={ + category="lo", + description="SYLOTI NAGRI LETTER DHO", + direction="l", + linebreak="al", + unicodeslot=0xA817, + }, + [0xA818]={ + category="lo", + description="SYLOTI NAGRI LETTER NO", + direction="l", + linebreak="al", + unicodeslot=0xA818, + }, + [0xA819]={ + category="lo", + description="SYLOTI NAGRI LETTER PO", + direction="l", + linebreak="al", + unicodeslot=0xA819, + }, + [0xA81A]={ + category="lo", + description="SYLOTI NAGRI LETTER PHO", + direction="l", + linebreak="al", + unicodeslot=0xA81A, + }, + [0xA81B]={ + category="lo", + description="SYLOTI NAGRI LETTER BO", + direction="l", + linebreak="al", + unicodeslot=0xA81B, + }, + [0xA81C]={ + category="lo", + description="SYLOTI NAGRI LETTER BHO", + direction="l", + linebreak="al", + unicodeslot=0xA81C, + }, + [0xA81D]={ + category="lo", + description="SYLOTI NAGRI LETTER MO", + direction="l", + linebreak="al", + unicodeslot=0xA81D, + }, + [0xA81E]={ + category="lo", + description="SYLOTI NAGRI LETTER RO", + direction="l", + linebreak="al", + unicodeslot=0xA81E, + }, + [0xA81F]={ + category="lo", + description="SYLOTI NAGRI LETTER LO", + direction="l", + linebreak="al", + unicodeslot=0xA81F, + }, + [0xA820]={ + category="lo", + description="SYLOTI NAGRI LETTER RRO", + direction="l", + linebreak="al", + unicodeslot=0xA820, + }, + [0xA821]={ + category="lo", + description="SYLOTI NAGRI LETTER SO", + direction="l", + linebreak="al", + unicodeslot=0xA821, + }, + [0xA822]={ + category="lo", + description="SYLOTI NAGRI LETTER HO", + direction="l", + linebreak="al", + unicodeslot=0xA822, + }, + [0xA823]={ + category="mc", + description="SYLOTI NAGRI VOWEL SIGN A", + direction="l", + linebreak="cm", + unicodeslot=0xA823, + }, + [0xA824]={ + category="mc", + description="SYLOTI NAGRI VOWEL SIGN I", + direction="l", + linebreak="cm", + unicodeslot=0xA824, + }, + [0xA825]={ + category="mn", + description="SYLOTI NAGRI VOWEL SIGN U", + direction="nsm", + linebreak="cm", + unicodeslot=0xA825, + }, + [0xA826]={ + category="mn", + description="SYLOTI NAGRI VOWEL SIGN E", + direction="nsm", + linebreak="cm", + unicodeslot=0xA826, + }, + [0xA827]={ + category="mc", + description="SYLOTI NAGRI VOWEL SIGN OO", + direction="l", + linebreak="cm", + unicodeslot=0xA827, + }, + [0xA828]={ + category="so", + description="SYLOTI NAGRI POETRY MARK-0x0001", + direction="on", + linebreak="al", + unicodeslot=0xA828, + }, + [0xA829]={ + category="so", + description="SYLOTI NAGRI POETRY MARK-0x0002", + direction="on", + linebreak="al", + unicodeslot=0xA829, + }, + [0xA82A]={ + category="so", + description="SYLOTI NAGRI POETRY MARK-0x0003", + direction="on", + linebreak="al", + unicodeslot=0xA82A, + }, + [0xA82B]={ + category="so", + description="SYLOTI NAGRI POETRY MARK-0x0004", + direction="on", + linebreak="al", + unicodeslot=0xA82B, + }, + [0xA840]={ + category="lo", + description="PHAGS-PA LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0xA840, + }, + [0xA841]={ + category="lo", + description="PHAGS-PA LETTER KHA", + direction="l", + linebreak="al", + unicodeslot=0xA841, + }, + [0xA842]={ + category="lo", + description="PHAGS-PA LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0xA842, + }, + [0xA843]={ + category="lo", + description="PHAGS-PA LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0xA843, + }, + [0xA844]={ + category="lo", + description="PHAGS-PA LETTER CA", + direction="l", + linebreak="al", + unicodeslot=0xA844, + }, + [0xA845]={ + category="lo", + description="PHAGS-PA LETTER CHA", + direction="l", + linebreak="al", + unicodeslot=0xA845, + }, + [0xA846]={ + category="lo", + description="PHAGS-PA LETTER JA", + direction="l", + linebreak="al", + unicodeslot=0xA846, + }, + [0xA847]={ + category="lo", + description="PHAGS-PA LETTER NYA", + direction="l", + linebreak="al", + unicodeslot=0xA847, + }, + [0xA848]={ + category="lo", + description="PHAGS-PA LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0xA848, + }, + [0xA849]={ + category="lo", + description="PHAGS-PA LETTER THA", + direction="l", + linebreak="al", + unicodeslot=0xA849, + }, + [0xA84A]={ + category="lo", + description="PHAGS-PA LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0xA84A, + }, + [0xA84B]={ + category="lo", + description="PHAGS-PA LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0xA84B, + }, + [0xA84C]={ + category="lo", + description="PHAGS-PA LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0xA84C, + }, + [0xA84D]={ + category="lo", + description="PHAGS-PA LETTER PHA", + direction="l", + linebreak="al", + unicodeslot=0xA84D, + }, + [0xA84E]={ + category="lo", + description="PHAGS-PA LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0xA84E, + }, + [0xA84F]={ + category="lo", + description="PHAGS-PA LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0xA84F, + }, + [0xA850]={ + category="lo", + description="PHAGS-PA LETTER TSA", + direction="l", + linebreak="al", + unicodeslot=0xA850, + }, + [0xA851]={ + category="lo", + description="PHAGS-PA LETTER TSHA", + direction="l", + linebreak="al", + unicodeslot=0xA851, + }, + [0xA852]={ + category="lo", + description="PHAGS-PA LETTER DZA", + direction="l", + linebreak="al", + unicodeslot=0xA852, + }, + [0xA853]={ + category="lo", + description="PHAGS-PA LETTER WA", + direction="l", + linebreak="al", + unicodeslot=0xA853, + }, + [0xA854]={ + category="lo", + description="PHAGS-PA LETTER ZHA", + direction="l", + linebreak="al", + unicodeslot=0xA854, + }, + [0xA855]={ + category="lo", + description="PHAGS-PA LETTER ZA", + direction="l", + linebreak="al", + unicodeslot=0xA855, + }, + [0xA856]={ + category="lo", + description="PHAGS-PA LETTER SMALL A", + direction="l", + linebreak="al", + unicodeslot=0xA856, + }, + [0xA857]={ + category="lo", + description="PHAGS-PA LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0xA857, + }, + [0xA858]={ + category="lo", + description="PHAGS-PA LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0xA858, + }, + [0xA859]={ + category="lo", + description="PHAGS-PA LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0xA859, + }, + [0xA85A]={ + category="lo", + description="PHAGS-PA LETTER SHA", + direction="l", + linebreak="al", + unicodeslot=0xA85A, + }, + [0xA85B]={ + category="lo", + description="PHAGS-PA LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0xA85B, + }, + [0xA85C]={ + category="lo", + description="PHAGS-PA LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0xA85C, + }, + [0xA85D]={ + category="lo", + description="PHAGS-PA LETTER A", + direction="l", + linebreak="al", + unicodeslot=0xA85D, + }, + [0xA85E]={ + category="lo", + description="PHAGS-PA LETTER I", + direction="l", + linebreak="al", + unicodeslot=0xA85E, + }, + [0xA85F]={ + category="lo", + description="PHAGS-PA LETTER U", + direction="l", + linebreak="al", + unicodeslot=0xA85F, + }, + [0xA860]={ + category="lo", + description="PHAGS-PA LETTER E", + direction="l", + linebreak="al", + unicodeslot=0xA860, + }, + [0xA861]={ + category="lo", + description="PHAGS-PA LETTER O", + direction="l", + linebreak="al", + unicodeslot=0xA861, + }, + [0xA862]={ + category="lo", + description="PHAGS-PA LETTER QA", + direction="l", + linebreak="al", + unicodeslot=0xA862, + }, + [0xA863]={ + category="lo", + description="PHAGS-PA LETTER XA", + direction="l", + linebreak="al", + unicodeslot=0xA863, + }, + [0xA864]={ + category="lo", + description="PHAGS-PA LETTER FA", + direction="l", + linebreak="al", + unicodeslot=0xA864, + }, + [0xA865]={ + category="lo", + description="PHAGS-PA LETTER GGA", + direction="l", + linebreak="al", + unicodeslot=0xA865, + }, + [0xA866]={ + category="lo", + description="PHAGS-PA LETTER EE", + direction="l", + linebreak="al", + unicodeslot=0xA866, + }, + [0xA867]={ + category="lo", + description="PHAGS-PA SUBJOINED LETTER WA", + direction="l", + linebreak="al", + unicodeslot=0xA867, + }, + [0xA868]={ + category="lo", + description="PHAGS-PA SUBJOINED LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0xA868, + }, + [0xA869]={ + category="lo", + description="PHAGS-PA LETTER TTA", + direction="l", + linebreak="al", + unicodeslot=0xA869, + }, + [0xA86A]={ + category="lo", + description="PHAGS-PA LETTER TTHA", + direction="l", + linebreak="al", + unicodeslot=0xA86A, + }, + [0xA86B]={ + category="lo", + description="PHAGS-PA LETTER DDA", + direction="l", + linebreak="al", + unicodeslot=0xA86B, + }, + [0xA86C]={ + category="lo", + description="PHAGS-PA LETTER NNA", + direction="l", + linebreak="al", + unicodeslot=0xA86C, + }, + [0xA86D]={ + category="lo", + description="PHAGS-PA LETTER ALTERNATE YA", + direction="l", + linebreak="al", + unicodeslot=0xA86D, + }, + [0xA86E]={ + category="lo", + description="PHAGS-PA LETTER VOICELESS SHA", + direction="l", + linebreak="al", + unicodeslot=0xA86E, + }, + [0xA86F]={ + category="lo", + description="PHAGS-PA LETTER VOICED HA", + direction="l", + linebreak="al", + unicodeslot=0xA86F, + }, + [0xA870]={ + category="lo", + description="PHAGS-PA LETTER ASPIRATED FA", + direction="l", + linebreak="al", + unicodeslot=0xA870, + }, + [0xA871]={ + category="lo", + description="PHAGS-PA SUBJOINED LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0xA871, + }, + [0xA872]={ + category="lo", + description="PHAGS-PA SUPERFIXED LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0xA872, + }, + [0xA873]={ + category="lo", + description="PHAGS-PA LETTER CANDRABINDU", + direction="l", + linebreak="al", + unicodeslot=0xA873, + }, + [0xA874]={ + category="po", + description="PHAGS-PA SINGLE HEAD MARK", + direction="on", + linebreak="bb", + unicodeslot=0xA874, + }, + [0xA875]={ + category="po", + description="PHAGS-PA DOUBLE HEAD MARK", + direction="on", + linebreak="bb", + unicodeslot=0xA875, + }, + [0xA876]={ + category="po", + description="PHAGS-PA MARK SHAD", + direction="on", + linebreak="ex", + unicodeslot=0xA876, + }, + [0xA877]={ + category="po", + description="PHAGS-PA MARK DOUBLE SHAD", + direction="on", + linebreak="ex", + unicodeslot=0xA877, + }, + [0xAC00]={ + category="lo", + cjkwd="w", + description="", + direction="l", + linebreak="h2", + unicodeslot=0xAC00, + range=0xD7A3, + }, + [0xD800]={ + category="cs", + description="", + direction="l", + linebreak="sg", + unicodeslot=0xD800, + }, + [0xDB7F]={ + category="cs", + description="", + direction="l", + linebreak="sg", + unicodeslot=0xDB7F, + }, + [0xDB80]={ + category="cs", + description="", + direction="l", + linebreak="sg", + unicodeslot=0xDB80, + }, + [0xDBFF]={ + category="cs", + description="", + direction="l", + linebreak="sg", + unicodeslot=0xDBFF, + }, + [0xDC00]={ + category="cs", + description="", + direction="l", + linebreak="sg", + unicodeslot=0xDC00, + }, + [0xDFFF]={ + category="cs", + description="", + direction="l", + linebreak="sg", + unicodeslot=0xDFFF, + }, + [0xE000]={ + category="co", + cjkwd="a", + description="", + direction="l", + unicodeslot=0xE000, + }, + [0xF8FF]={ + category="co", + cjkwd="a", + description="", + direction="l", + unicodeslot=0xF8FF, + }, + [0xF900]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0384", + direction="l", + linebreak="id", + specials={ "char", 0x8C48 }, + unicodeslot=0xF900, + }, + [0xF901]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0385", + direction="l", + linebreak="id", + specials={ "char", 0x66F4 }, + unicodeslot=0xF901, + }, + [0xF902]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0386", + direction="l", + linebreak="id", + specials={ "char", 0x8ECA }, + unicodeslot=0xF902, + }, + [0xF903]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0387", + direction="l", + linebreak="id", + specials={ "char", 0x8CC8 }, + unicodeslot=0xF903, + }, + [0xF904]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0388", + direction="l", + linebreak="id", + specials={ "char", 0x6ED1 }, + unicodeslot=0xF904, + }, + [0xF905]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0389", + direction="l", + linebreak="id", + specials={ "char", 0x4E32 }, + unicodeslot=0xF905, + }, + [0xF906]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x038A", + direction="l", + linebreak="id", + specials={ "char", 0x53E5 }, + unicodeslot=0xF906, + }, + [0xF907]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x038B", + direction="l", + linebreak="id", + specials={ "char", 0x9F9C }, + unicodeslot=0xF907, + }, + [0xF908]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x038C", + direction="l", + linebreak="id", + specials={ "char", 0x9F9C }, + unicodeslot=0xF908, + }, + [0xF909]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x038D", + direction="l", + linebreak="id", + specials={ "char", 0x5951 }, + unicodeslot=0xF909, + }, + [0xF90A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005AA", + direction="l", + linebreak="id", + specials={ "char", 0x91D1 }, + unicodeslot=0xF90A, + }, + [0xF90B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005AB", + direction="l", + linebreak="id", + specials={ "char", 0x5587 }, + unicodeslot=0xF90B, + }, + [0xF90C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005AC", + direction="l", + linebreak="id", + specials={ "char", 0x5948 }, + unicodeslot=0xF90C, + }, + [0xF90D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005AD", + direction="l", + linebreak="id", + specials={ "char", 0x61F6 }, + unicodeslot=0xF90D, + }, + [0xF90E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005AE", + direction="l", + linebreak="id", + specials={ "char", 0x7669 }, + unicodeslot=0xF90E, + }, + [0xF90F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005AF", + direction="l", + linebreak="id", + specials={ "char", 0x7F85 }, + unicodeslot=0xF90F, + }, + [0xF910]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x038E", + direction="l", + linebreak="id", + specials={ "char", 0x863F }, + unicodeslot=0xF910, + }, + [0xF911]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x038F", + direction="l", + linebreak="id", + specials={ "char", 0x87BA }, + unicodeslot=0xF911, + }, + [0xF912]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0390", + direction="l", + linebreak="id", + specials={ "char", 0x88F8 }, + unicodeslot=0xF912, + }, + [0xF913]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0391", + direction="l", + linebreak="id", + specials={ "char", 0x908F }, + unicodeslot=0xF913, + }, + [0xF914]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0392", + direction="l", + linebreak="id", + specials={ "char", 0x6A02 }, + unicodeslot=0xF914, + }, + [0xF915]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0393", + direction="l", + linebreak="id", + specials={ "char", 0x6D1B }, + unicodeslot=0xF915, + }, + [0xF916]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0394", + direction="l", + linebreak="id", + specials={ "char", 0x70D9 }, + unicodeslot=0xF916, + }, + [0xF917]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0395", + direction="l", + linebreak="id", + specials={ "char", 0x73DE }, + unicodeslot=0xF917, + }, + [0xF918]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0396", + direction="l", + linebreak="id", + specials={ "char", 0x843D }, + unicodeslot=0xF918, + }, + [0xF919]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0397", + direction="l", + linebreak="id", + specials={ "char", 0x916A }, + unicodeslot=0xF919, + }, + [0xF91A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005BA", + direction="l", + linebreak="id", + specials={ "char", 0x99F1 }, + unicodeslot=0xF91A, + }, + [0xF91B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005BB", + direction="l", + linebreak="id", + specials={ "char", 0x4E82 }, + unicodeslot=0xF91B, + }, + [0xF91C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005BC", + direction="l", + linebreak="id", + specials={ "char", 0x5375 }, + unicodeslot=0xF91C, + }, + [0xF91D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005BD", + direction="l", + linebreak="id", + specials={ "char", 0x6B04 }, + unicodeslot=0xF91D, + }, + [0xF91E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005BE", + direction="l", + linebreak="id", + specials={ "char", 0x721B }, + unicodeslot=0xF91E, + }, + [0xF91F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005BF", + direction="l", + linebreak="id", + specials={ "char", 0x862D }, + unicodeslot=0xF91F, + }, + [0xF920]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0398", + direction="l", + linebreak="id", + specials={ "char", 0x9E1E }, + unicodeslot=0xF920, + }, + [0xF921]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0399", + direction="l", + linebreak="id", + specials={ "char", 0x5D50 }, + unicodeslot=0xF921, + }, + [0xF922]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x039A", + direction="l", + linebreak="id", + specials={ "char", 0x6FEB }, + unicodeslot=0xF922, + }, + [0xF923]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x039B", + direction="l", + linebreak="id", + specials={ "char", 0x85CD }, + unicodeslot=0xF923, + }, + [0xF924]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x039C", + direction="l", + linebreak="id", + specials={ "char", 0x8964 }, + unicodeslot=0xF924, + }, + [0xF925]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x039D", + direction="l", + linebreak="id", + specials={ "char", 0x62C9 }, + unicodeslot=0xF925, + }, + [0xF926]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x039E", + direction="l", + linebreak="id", + specials={ "char", 0x81D8 }, + unicodeslot=0xF926, + }, + [0xF927]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x039F", + direction="l", + linebreak="id", + specials={ "char", 0x881F }, + unicodeslot=0xF927, + }, + [0xF928]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03A0", + direction="l", + linebreak="id", + specials={ "char", 0x5ECA }, + unicodeslot=0xF928, + }, + [0xF929]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03A1", + direction="l", + linebreak="id", + specials={ "char", 0x6717 }, + unicodeslot=0xF929, + }, + [0xF92A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005CA", + direction="l", + linebreak="id", + specials={ "char", 0x6D6A }, + unicodeslot=0xF92A, + }, + [0xF92B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005CB", + direction="l", + linebreak="id", + specials={ "char", 0x72FC }, + unicodeslot=0xF92B, + }, + [0xF92C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005CC", + direction="l", + linebreak="id", + specials={ "char", 0x90CE }, + unicodeslot=0xF92C, + }, + [0xF92D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005CD", + direction="l", + linebreak="id", + specials={ "char", 0x4F86 }, + unicodeslot=0xF92D, + }, + [0xF92E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005CE", + direction="l", + linebreak="id", + specials={ "char", 0x51B7 }, + unicodeslot=0xF92E, + }, + [0xF92F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005CF", + direction="l", + linebreak="id", + specials={ "char", 0x52DE }, + unicodeslot=0xF92F, + }, + [0xF930]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03A2", + direction="l", + linebreak="id", + specials={ "char", 0x64C4 }, + unicodeslot=0xF930, + }, + [0xF931]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03A3", + direction="l", + linebreak="id", + specials={ "char", 0x6AD3 }, + unicodeslot=0xF931, + }, + [0xF932]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03A4", + direction="l", + linebreak="id", + specials={ "char", 0x7210 }, + unicodeslot=0xF932, + }, + [0xF933]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03A5", + direction="l", + linebreak="id", + specials={ "char", 0x76E7 }, + unicodeslot=0xF933, + }, + [0xF934]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03A6", + direction="l", + linebreak="id", + specials={ "char", 0x8001 }, + unicodeslot=0xF934, + }, + [0xF935]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03A7", + direction="l", + linebreak="id", + specials={ "char", 0x8606 }, + unicodeslot=0xF935, + }, + [0xF936]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03A8", + direction="l", + linebreak="id", + specials={ "char", 0x865C }, + unicodeslot=0xF936, + }, + [0xF937]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03A9", + direction="l", + linebreak="id", + specials={ "char", 0x8DEF }, + unicodeslot=0xF937, + }, + [0xF938]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03AA", + direction="l", + linebreak="id", + specials={ "char", 0x9732 }, + unicodeslot=0xF938, + }, + [0xF939]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03AB", + direction="l", + linebreak="id", + specials={ "char", 0x9B6F }, + unicodeslot=0xF939, + }, + [0xF93A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005DA", + direction="l", + linebreak="id", + specials={ "char", 0x9DFA }, + unicodeslot=0xF93A, + }, + [0xF93B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005DB", + direction="l", + linebreak="id", + specials={ "char", 0x788C }, + unicodeslot=0xF93B, + }, + [0xF93C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005DC", + direction="l", + linebreak="id", + specials={ "char", 0x797F }, + unicodeslot=0xF93C, + }, + [0xF93D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005DD", + direction="l", + linebreak="id", + specials={ "char", 0x7DA0 }, + unicodeslot=0xF93D, + }, + [0xF93E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005DE", + direction="l", + linebreak="id", + specials={ "char", 0x83C9 }, + unicodeslot=0xF93E, + }, + [0xF93F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005DF", + direction="l", + linebreak="id", + specials={ "char", 0x9304 }, + unicodeslot=0xF93F, + }, + [0xF940]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03AC", + direction="l", + linebreak="id", + specials={ "char", 0x9E7F }, + unicodeslot=0xF940, + }, + [0xF941]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03AD", + direction="l", + linebreak="id", + specials={ "char", 0x8AD6 }, + unicodeslot=0xF941, + }, + [0xF942]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03AE", + direction="l", + linebreak="id", + specials={ "char", 0x58DF }, + unicodeslot=0xF942, + }, + [0xF943]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03AF", + direction="l", + linebreak="id", + specials={ "char", 0x5F04 }, + unicodeslot=0xF943, + }, + [0xF944]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03B0", + direction="l", + linebreak="id", + specials={ "char", 0x7C60 }, + unicodeslot=0xF944, + }, + [0xF945]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03B1", + direction="l", + linebreak="id", + specials={ "char", 0x807E }, + unicodeslot=0xF945, + }, + [0xF946]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03B2", + direction="l", + linebreak="id", + specials={ "char", 0x7262 }, + unicodeslot=0xF946, + }, + [0xF947]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03B3", + direction="l", + linebreak="id", + specials={ "char", 0x78CA }, + unicodeslot=0xF947, + }, + [0xF948]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03B4", + direction="l", + linebreak="id", + specials={ "char", 0x8CC2 }, + unicodeslot=0xF948, + }, + [0xF949]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03B5", + direction="l", + linebreak="id", + specials={ "char", 0x96F7 }, + unicodeslot=0xF949, + }, + [0xF94A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005EA", + direction="l", + linebreak="id", + specials={ "char", 0x58D8 }, + unicodeslot=0xF94A, + }, + [0xF94B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005EB", + direction="l", + linebreak="id", + specials={ "char", 0x5C62 }, + unicodeslot=0xF94B, + }, + [0xF94C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005EC", + direction="l", + linebreak="id", + specials={ "char", 0x6A13 }, + unicodeslot=0xF94C, + }, + [0xF94D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005ED", + direction="l", + linebreak="id", + specials={ "char", 0x6DDA }, + unicodeslot=0xF94D, + }, + [0xF94E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005EE", + direction="l", + linebreak="id", + specials={ "char", 0x6F0F }, + unicodeslot=0xF94E, + }, + [0xF94F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005EF", + direction="l", + linebreak="id", + specials={ "char", 0x7D2F }, + unicodeslot=0xF94F, + }, + [0xF950]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03B6", + direction="l", + linebreak="id", + specials={ "char", 0x7E37 }, + unicodeslot=0xF950, + }, + [0xF951]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03B7", + direction="l", + linebreak="id", + specials={ "char", 0x964B }, + unicodeslot=0xF951, + }, + [0xF952]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03B8", + direction="l", + linebreak="id", + specials={ "char", 0x52D2 }, + unicodeslot=0xF952, + }, + [0xF953]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03B9", + direction="l", + linebreak="id", + specials={ "char", 0x808B }, + unicodeslot=0xF953, + }, + [0xF954]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03BA", + direction="l", + linebreak="id", + specials={ "char", 0x51DC }, + unicodeslot=0xF954, + }, + [0xF955]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03BB", + direction="l", + linebreak="id", + specials={ "char", 0x51CC }, + unicodeslot=0xF955, + }, + [0xF956]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03BC", + direction="l", + linebreak="id", + specials={ "char", 0x7A1C }, + unicodeslot=0xF956, + }, + [0xF957]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03BD", + direction="l", + linebreak="id", + specials={ "char", 0x7DBE }, + unicodeslot=0xF957, + }, + [0xF958]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03BE", + direction="l", + linebreak="id", + specials={ "char", 0x83F1 }, + unicodeslot=0xF958, + }, + [0xF959]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03BF", + direction="l", + linebreak="id", + specials={ "char", 0x9675 }, + unicodeslot=0xF959, + }, + [0xF95A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005FA", + direction="l", + linebreak="id", + specials={ "char", 0x8B80 }, + unicodeslot=0xF95A, + }, + [0xF95B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005FB", + direction="l", + linebreak="id", + specials={ "char", 0x62CF }, + unicodeslot=0xF95B, + }, + [0xF95C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005FC", + direction="l", + linebreak="id", + specials={ "char", 0x6A02 }, + unicodeslot=0xF95C, + }, + [0xF95D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005FD", + direction="l", + linebreak="id", + specials={ "char", 0x8AFE }, + unicodeslot=0xF95D, + }, + [0xF95E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005FE", + direction="l", + linebreak="id", + specials={ "char", 0x4E39 }, + unicodeslot=0xF95E, + }, + [0xF95F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x005FF", + direction="l", + linebreak="id", + specials={ "char", 0x5BE7 }, + unicodeslot=0xF95F, + }, + [0xF960]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03C0", + direction="l", + linebreak="id", + specials={ "char", 0x6012 }, + unicodeslot=0xF960, + }, + [0xF961]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03C1", + direction="l", + linebreak="id", + specials={ "char", 0x7387 }, + unicodeslot=0xF961, + }, + [0xF962]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03C2", + direction="l", + linebreak="id", + specials={ "char", 0x7570 }, + unicodeslot=0xF962, + }, + [0xF963]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03C3", + direction="l", + linebreak="id", + specials={ "char", 0x5317 }, + unicodeslot=0xF963, + }, + [0xF964]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03C4", + direction="l", + linebreak="id", + specials={ "char", 0x78FB }, + unicodeslot=0xF964, + }, + [0xF965]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03C5", + direction="l", + linebreak="id", + specials={ "char", 0x4FBF }, + unicodeslot=0xF965, + }, + [0xF966]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03C6", + direction="l", + linebreak="id", + specials={ "char", 0x5FA9 }, + unicodeslot=0xF966, + }, + [0xF967]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03C7", + direction="l", + linebreak="id", + specials={ "char", 0x4E0D }, + unicodeslot=0xF967, + }, + [0xF968]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03C8", + direction="l", + linebreak="id", + specials={ "char", 0x6CCC }, + unicodeslot=0xF968, + }, + [0xF969]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03C9", + direction="l", + linebreak="id", + specials={ "char", 0x6578 }, + unicodeslot=0xF969, + }, + [0xF96A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0060A", + direction="l", + linebreak="id", + specials={ "char", 0x7D22 }, + unicodeslot=0xF96A, + }, + [0xF96B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0060B", + direction="l", + linebreak="id", + specials={ "char", 0x53C3 }, + unicodeslot=0xF96B, + }, + [0xF96C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0060C", + direction="l", + linebreak="id", + specials={ "char", 0x585E }, + unicodeslot=0xF96C, + }, + [0xF96D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0060D", + direction="l", + linebreak="id", + specials={ "char", 0x7701 }, + unicodeslot=0xF96D, + }, + [0xF96E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0060E", + direction="l", + linebreak="id", + specials={ "char", 0x8449 }, + unicodeslot=0xF96E, + }, + [0xF96F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0060F", + direction="l", + linebreak="id", + specials={ "char", 0x8AAA }, + unicodeslot=0xF96F, + }, + [0xF970]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03CA", + direction="l", + linebreak="id", + specials={ "char", 0x6BBA }, + unicodeslot=0xF970, + }, + [0xF971]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03CB", + direction="l", + linebreak="id", + specials={ "char", 0x8FB0 }, + unicodeslot=0xF971, + }, + [0xF972]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03CC", + direction="l", + linebreak="id", + specials={ "char", 0x6C88 }, + unicodeslot=0xF972, + }, + [0xF973]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03CD", + direction="l", + linebreak="id", + specials={ "char", 0x62FE }, + unicodeslot=0xF973, + }, + [0xF974]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03CE", + direction="l", + linebreak="id", + specials={ "char", 0x82E5 }, + unicodeslot=0xF974, + }, + [0xF975]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03CF", + direction="l", + linebreak="id", + specials={ "char", 0x63A0 }, + unicodeslot=0xF975, + }, + [0xF976]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03D0", + direction="l", + linebreak="id", + specials={ "char", 0x7565 }, + unicodeslot=0xF976, + }, + [0xF977]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03D1", + direction="l", + linebreak="id", + specials={ "char", 0x4EAE }, + unicodeslot=0xF977, + }, + [0xF978]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03D2", + direction="l", + linebreak="id", + specials={ "char", 0x5169 }, + unicodeslot=0xF978, + }, + [0xF979]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03D3", + direction="l", + linebreak="id", + specials={ "char", 0x51C9 }, + unicodeslot=0xF979, + }, + [0xF97A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0061A", + direction="l", + linebreak="id", + specials={ "char", 0x6881 }, + unicodeslot=0xF97A, + }, + [0xF97B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0061B", + direction="l", + linebreak="id", + specials={ "char", 0x7CE7 }, + unicodeslot=0xF97B, + }, + [0xF97C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0061C", + direction="l", + linebreak="id", + specials={ "char", 0x826F }, + unicodeslot=0xF97C, + }, + [0xF97D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0061D", + direction="l", + linebreak="id", + specials={ "char", 0x8AD2 }, + unicodeslot=0xF97D, + }, + [0xF97E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0061E", + direction="l", + linebreak="id", + specials={ "char", 0x91CF }, + unicodeslot=0xF97E, + }, + [0xF97F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0061F", + direction="l", + linebreak="id", + specials={ "char", 0x52F5 }, + unicodeslot=0xF97F, + }, + [0xF980]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03D4", + direction="l", + linebreak="id", + specials={ "char", 0x5442 }, + unicodeslot=0xF980, + }, + [0xF981]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03D5", + direction="l", + linebreak="id", + specials={ "char", 0x5973 }, + unicodeslot=0xF981, + }, + [0xF982]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03D6", + direction="l", + linebreak="id", + specials={ "char", 0x5EEC }, + unicodeslot=0xF982, + }, + [0xF983]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03D7", + direction="l", + linebreak="id", + specials={ "char", 0x65C5 }, + unicodeslot=0xF983, + }, + [0xF984]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03D8", + direction="l", + linebreak="id", + specials={ "char", 0x6FFE }, + unicodeslot=0xF984, + }, + [0xF985]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03D9", + direction="l", + linebreak="id", + specials={ "char", 0x792A }, + unicodeslot=0xF985, + }, + [0xF986]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03DA", + direction="l", + linebreak="id", + specials={ "char", 0x95AD }, + unicodeslot=0xF986, + }, + [0xF987]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03DB", + direction="l", + linebreak="id", + specials={ "char", 0x9A6A }, + unicodeslot=0xF987, + }, + [0xF988]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03DC", + direction="l", + linebreak="id", + specials={ "char", 0x9E97 }, + unicodeslot=0xF988, + }, + [0xF989]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03DD", + direction="l", + linebreak="id", + specials={ "char", 0x9ECE }, + unicodeslot=0xF989, + }, + [0xF98A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0062A", + direction="l", + linebreak="id", + specials={ "char", 0x529B }, + unicodeslot=0xF98A, + }, + [0xF98B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0062B", + direction="l", + linebreak="id", + specials={ "char", 0x66C6 }, + unicodeslot=0xF98B, + }, + [0xF98C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0062C", + direction="l", + linebreak="id", + specials={ "char", 0x6B77 }, + unicodeslot=0xF98C, + }, + [0xF98D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0062D", + direction="l", + linebreak="id", + specials={ "char", 0x8F62 }, + unicodeslot=0xF98D, + }, + [0xF98E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0062E", + direction="l", + linebreak="id", + specials={ "char", 0x5E74 }, + unicodeslot=0xF98E, + }, + [0xF98F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0062F", + direction="l", + linebreak="id", + specials={ "char", 0x6190 }, + unicodeslot=0xF98F, + }, + [0xF990]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03DE", + direction="l", + linebreak="id", + specials={ "char", 0x6200 }, + unicodeslot=0xF990, + }, + [0xF991]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03DF", + direction="l", + linebreak="id", + specials={ "char", 0x649A }, + unicodeslot=0xF991, + }, + [0xF992]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03E0", + direction="l", + linebreak="id", + specials={ "char", 0x6F23 }, + unicodeslot=0xF992, + }, + [0xF993]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03E1", + direction="l", + linebreak="id", + specials={ "char", 0x7149 }, + unicodeslot=0xF993, + }, + [0xF994]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03E2", + direction="l", + linebreak="id", + specials={ "char", 0x7489 }, + unicodeslot=0xF994, + }, + [0xF995]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03E3", + direction="l", + linebreak="id", + specials={ "char", 0x79CA }, + unicodeslot=0xF995, + }, + [0xF996]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03E4", + direction="l", + linebreak="id", + specials={ "char", 0x7DF4 }, + unicodeslot=0xF996, + }, + [0xF997]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03E5", + direction="l", + linebreak="id", + specials={ "char", 0x806F }, + unicodeslot=0xF997, + }, + [0xF998]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03E6", + direction="l", + linebreak="id", + specials={ "char", 0x8F26 }, + unicodeslot=0xF998, + }, + [0xF999]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x03E7", + direction="l", + linebreak="id", + specials={ "char", 0x84EE }, + unicodeslot=0xF999, + }, + [0xF99A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0063A", + direction="l", + linebreak="id", + specials={ "char", 0x9023 }, + unicodeslot=0xF99A, + }, + [0xF99B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0063B", + direction="l", + linebreak="id", + specials={ "char", 0x934A }, + unicodeslot=0xF99B, + }, + [0xF99C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0063C", + direction="l", + linebreak="id", + specials={ "char", 0x5217 }, + unicodeslot=0xF99C, + }, + [0xF99D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0063D", + direction="l", + linebreak="id", + specials={ "char", 0x52A3 }, + unicodeslot=0xF99D, + }, + [0xF99E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0063E", + direction="l", + linebreak="id", + specials={ "char", 0x54BD }, + unicodeslot=0xF99E, + }, + [0xF99F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0063F", + direction="l", + linebreak="id", + specials={ "char", 0x70C8 }, + unicodeslot=0xF99F, + }, + [0xF9A0]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009A0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x88C2 }, + unicodeslot=0xF9A0, + }, + [0xF9A1]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009A0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x8AAA }, + unicodeslot=0xF9A1, + }, + [0xF9A2]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009A0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x5EC9 }, + unicodeslot=0xF9A2, + }, + [0xF9A3]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009A0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x5FF5 }, + unicodeslot=0xF9A3, + }, + [0xF9A4]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009A0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x637B }, + unicodeslot=0xF9A4, + }, + [0xF9A5]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009A0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x6BAE }, + unicodeslot=0xF9A5, + }, + [0xF9A6]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009A0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x7C3E }, + unicodeslot=0xF9A6, + }, + [0xF9A7]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009A0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x7375 }, + unicodeslot=0xF9A7, + }, + [0xF9A8]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009A0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x4EE4 }, + unicodeslot=0xF9A8, + }, + [0xF9A9]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009A0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x56F9 }, + unicodeslot=0xF9A9, + }, + [0xF9AA]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009AA", + direction="l", + linebreak="id", + specials={ "char", 0x5BE7 }, + unicodeslot=0xF9AA, + }, + [0xF9AB]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009AB", + direction="l", + linebreak="id", + specials={ "char", 0x5DBA }, + unicodeslot=0xF9AB, + }, + [0xF9AC]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009AC", + direction="l", + linebreak="id", + specials={ "char", 0x601C }, + unicodeslot=0xF9AC, + }, + [0xF9AD]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009AD", + direction="l", + linebreak="id", + specials={ "char", 0x73B2 }, + unicodeslot=0xF9AD, + }, + [0xF9AE]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009AE", + direction="l", + linebreak="id", + specials={ "char", 0x7469 }, + unicodeslot=0xF9AE, + }, + [0xF9AF]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009AF", + direction="l", + linebreak="id", + specials={ "char", 0x7F9A }, + unicodeslot=0xF9AF, + }, + [0xF9B0]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009B0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x8046 }, + unicodeslot=0xF9B0, + }, + [0xF9B1]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009B0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x9234 }, + unicodeslot=0xF9B1, + }, + [0xF9B2]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009B0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x96F6 }, + unicodeslot=0xF9B2, + }, + [0xF9B3]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009B0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x9748 }, + unicodeslot=0xF9B3, + }, + [0xF9B4]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009B0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x9818 }, + unicodeslot=0xF9B4, + }, + [0xF9B5]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009B0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x4F8B }, + unicodeslot=0xF9B5, + }, + [0xF9B6]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009B0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x79AE }, + unicodeslot=0xF9B6, + }, + [0xF9B7]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009B0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x91B4 }, + unicodeslot=0xF9B7, + }, + [0xF9B8]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009B0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x96B8 }, + unicodeslot=0xF9B8, + }, + [0xF9B9]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009B0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x60E1 }, + unicodeslot=0xF9B9, + }, + [0xF9BA]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009BA", + direction="l", + linebreak="id", + specials={ "char", 0x4E86 }, + unicodeslot=0xF9BA, + }, + [0xF9BB]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009BB", + direction="l", + linebreak="id", + specials={ "char", 0x50DA }, + unicodeslot=0xF9BB, + }, + [0xF9BC]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009BC", + direction="l", + linebreak="id", + specials={ "char", 0x5BEE }, + unicodeslot=0xF9BC, + }, + [0xF9BD]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009BD", + direction="l", + linebreak="id", + specials={ "char", 0x5C3F }, + unicodeslot=0xF9BD, + }, + [0xF9BE]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009BE", + direction="l", + linebreak="id", + specials={ "char", 0x6599 }, + unicodeslot=0xF9BE, + }, + [0xF9BF]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009BF", + direction="l", + linebreak="id", + specials={ "char", 0x6A02 }, + unicodeslot=0xF9BF, + }, + [0xF9C0]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009C0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x71CE }, + unicodeslot=0xF9C0, + }, + [0xF9C1]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009C0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x7642 }, + unicodeslot=0xF9C1, + }, + [0xF9C2]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009C0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x84FC }, + unicodeslot=0xF9C2, + }, + [0xF9C3]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009C0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x907C }, + unicodeslot=0xF9C3, + }, + [0xF9C4]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009C0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x9F8D }, + unicodeslot=0xF9C4, + }, + [0xF9C5]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009C0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x6688 }, + unicodeslot=0xF9C5, + }, + [0xF9C6]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009C0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x962E }, + unicodeslot=0xF9C6, + }, + [0xF9C7]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009C0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x5289 }, + unicodeslot=0xF9C7, + }, + [0xF9C8]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009C0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x677B }, + unicodeslot=0xF9C8, + }, + [0xF9C9]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009C0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x67F3 }, + unicodeslot=0xF9C9, + }, + [0xF9CA]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009CA", + direction="l", + linebreak="id", + specials={ "char", 0x6D41 }, + unicodeslot=0xF9CA, + }, + [0xF9CB]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009CB", + direction="l", + linebreak="id", + specials={ "char", 0x6E9C }, + unicodeslot=0xF9CB, + }, + [0xF9CC]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009CC", + direction="l", + linebreak="id", + specials={ "char", 0x7409 }, + unicodeslot=0xF9CC, + }, + [0xF9CD]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009CD", + direction="l", + linebreak="id", + specials={ "char", 0x7559 }, + unicodeslot=0xF9CD, + }, + [0xF9CE]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009CE", + direction="l", + linebreak="id", + specials={ "char", 0x786B }, + unicodeslot=0xF9CE, + }, + [0xF9CF]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009CF", + direction="l", + linebreak="id", + specials={ "char", 0x7D10 }, + unicodeslot=0xF9CF, + }, + [0xF9D0]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009D0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x985E }, + unicodeslot=0xF9D0, + }, + [0xF9D1]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009D0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x516D }, + unicodeslot=0xF9D1, + }, + [0xF9D2]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009D0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x622E }, + unicodeslot=0xF9D2, + }, + [0xF9D3]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009D0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x9678 }, + unicodeslot=0xF9D3, + }, + [0xF9D4]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009D0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x502B }, + unicodeslot=0xF9D4, + }, + [0xF9D5]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009D0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x5D19 }, + unicodeslot=0xF9D5, + }, + [0xF9D6]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009D0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x6DEA }, + unicodeslot=0xF9D6, + }, + [0xF9D7]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009D0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x8F2A }, + unicodeslot=0xF9D7, + }, + [0xF9D8]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009D0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x5F8B }, + unicodeslot=0xF9D8, + }, + [0xF9D9]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009D0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x6144 }, + unicodeslot=0xF9D9, + }, + [0xF9DA]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009DA", + direction="l", + linebreak="id", + specials={ "char", 0x6817 }, + unicodeslot=0xF9DA, + }, + [0xF9DB]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009DB", + direction="l", + linebreak="id", + specials={ "char", 0x7387 }, + unicodeslot=0xF9DB, + }, + [0xF9DC]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009DC", + direction="l", + linebreak="id", + specials={ "char", 0x9686 }, + unicodeslot=0xF9DC, + }, + [0xF9DD]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009DD", + direction="l", + linebreak="id", + specials={ "char", 0x5229 }, + unicodeslot=0xF9DD, + }, + [0xF9DE]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009DE", + direction="l", + linebreak="id", + specials={ "char", 0x540F }, + unicodeslot=0xF9DE, + }, + [0xF9DF]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009DF", + direction="l", + linebreak="id", + specials={ "char", 0x5C65 }, + unicodeslot=0xF9DF, + }, + [0xF9E0]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009E0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x6613 }, + unicodeslot=0xF9E0, + }, + [0xF9E1]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009E0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x674E }, + unicodeslot=0xF9E1, + }, + [0xF9E2]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009E0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x68A8 }, + unicodeslot=0xF9E2, + }, + [0xF9E3]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009E0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x6CE5 }, + unicodeslot=0xF9E3, + }, + [0xF9E4]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009E0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x7406 }, + unicodeslot=0xF9E4, + }, + [0xF9E5]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009E0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x75E2 }, + unicodeslot=0xF9E5, + }, + [0xF9E6]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009E0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x7F79 }, + unicodeslot=0xF9E6, + }, + [0xF9E7]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009E0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x88CF }, + unicodeslot=0xF9E7, + }, + [0xF9E8]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009E0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x88E1 }, + unicodeslot=0xF9E8, + }, + [0xF9E9]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009E0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x91CC }, + unicodeslot=0xF9E9, + }, + [0xF9EA]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009EA", + direction="l", + linebreak="id", + specials={ "char", 0x96E2 }, + unicodeslot=0xF9EA, + }, + [0xF9EB]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009EB", + direction="l", + linebreak="id", + specials={ "char", 0x533F }, + unicodeslot=0xF9EB, + }, + [0xF9EC]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009EC", + direction="l", + linebreak="id", + specials={ "char", 0x6EBA }, + unicodeslot=0xF9EC, + }, + [0xF9ED]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009ED", + direction="l", + linebreak="id", + specials={ "char", 0x541D }, + unicodeslot=0xF9ED, + }, + [0xF9EE]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009EE", + direction="l", + linebreak="id", + specials={ "char", 0x71D0 }, + unicodeslot=0xF9EE, + }, + [0xF9EF]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009EF", + direction="l", + linebreak="id", + specials={ "char", 0x7498 }, + unicodeslot=0xF9EF, + }, + [0xF9F0]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009F0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x85FA }, + unicodeslot=0xF9F0, + }, + [0xF9F1]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009F0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x96A3 }, + unicodeslot=0xF9F1, + }, + [0xF9F2]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009F0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x9C57 }, + unicodeslot=0xF9F2, + }, + [0xF9F3]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009F0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x9E9F }, + unicodeslot=0xF9F3, + }, + [0xF9F4]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009F0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x6797 }, + unicodeslot=0xF9F4, + }, + [0xF9F5]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009F0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x6DCB }, + unicodeslot=0xF9F5, + }, + [0xF9F6]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009F0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x81E8 }, + unicodeslot=0xF9F6, + }, + [0xF9F7]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009F0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x7ACB }, + unicodeslot=0xF9F7, + }, + [0xF9F8]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009F0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x7B20 }, + unicodeslot=0xF9F8, + }, + [0xF9F9]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009F0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x7C92 }, + unicodeslot=0xF9F9, + }, + [0xF9FA]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009FA", + direction="l", + linebreak="id", + specials={ "char", 0x72C0 }, + unicodeslot=0xF9FA, + }, + [0xF9FB]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009FB", + direction="l", + linebreak="id", + specials={ "char", 0x7099 }, + unicodeslot=0xF9FB, + }, + [0xF9FC]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009FC", + direction="l", + linebreak="id", + specials={ "char", 0x8B58 }, + unicodeslot=0xF9FC, + }, + [0xF9FD]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009FD", + direction="l", + linebreak="id", + specials={ "char", 0x4EC0 }, + unicodeslot=0xF9FD, + }, + [0xF9FE]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009FE", + direction="l", + linebreak="id", + specials={ "char", 0x8336 }, + unicodeslot=0xF9FE, + }, + [0xF9FF]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-F0x0009FF", + direction="l", + linebreak="id", + specials={ "char", 0x523A }, + unicodeslot=0xF9FF, + }, + [0xFA00]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x5207 }, + unicodeslot=0xFA00, + }, + [0xFA01]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x5EA6 }, + unicodeslot=0xFA01, + }, + [0xFA02]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x62D3 }, + unicodeslot=0xFA02, + }, + [0xFA03]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x7CD6 }, + unicodeslot=0xFA03, + }, + [0xFA04]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x5B85 }, + unicodeslot=0xFA04, + }, + [0xFA05]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x6D1E }, + unicodeslot=0xFA05, + }, + [0xFA06]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x66B4 }, + unicodeslot=0xFA06, + }, + [0xFA07]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x8F3B }, + unicodeslot=0xFA07, + }, + [0xFA08]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x884C }, + unicodeslot=0xFA08, + }, + [0xFA09]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x964D }, + unicodeslot=0xFA09, + }, + [0xFA0A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0000A", + direction="l", + linebreak="id", + specials={ "char", 0x898B }, + unicodeslot=0xFA0A, + }, + [0xFA0B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0000B", + direction="l", + linebreak="id", + specials={ "char", 0x5ED3 }, + unicodeslot=0xFA0B, + }, + [0xFA0C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0000C", + direction="l", + linebreak="id", + specials={ "char", 0x5140 }, + unicodeslot=0xFA0C, + }, + [0xFA0D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0000D", + direction="l", + linebreak="id", + specials={ "char", 0x55C0 }, + unicodeslot=0xFA0D, + }, + [0xFA0E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0000E", + direction="l", + linebreak="id", + unicodeslot=0xFA0E, + }, + [0xFA0F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0000F", + direction="l", + linebreak="id", + unicodeslot=0xFA0F, + }, + [0xFA10]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x000A", + direction="l", + linebreak="id", + specials={ "char", 0x585A }, + unicodeslot=0xFA10, + }, + [0xFA11]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x000B", + direction="l", + linebreak="id", + unicodeslot=0xFA11, + }, + [0xFA12]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x000C", + direction="l", + linebreak="id", + specials={ "char", 0x6674 }, + unicodeslot=0xFA12, + }, + [0xFA13]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x000D", + direction="l", + linebreak="id", + unicodeslot=0xFA13, + }, + [0xFA14]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x000E", + direction="l", + linebreak="id", + unicodeslot=0xFA14, + }, + [0xFA15]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x000F", + direction="l", + linebreak="id", + specials={ "char", 0x51DE }, + unicodeslot=0xFA15, + }, + [0xFA16]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0010", + direction="l", + linebreak="id", + specials={ "char", 0x732A }, + unicodeslot=0xFA16, + }, + [0xFA17]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0011", + direction="l", + linebreak="id", + specials={ "char", 0x76CA }, + unicodeslot=0xFA17, + }, + [0xFA18]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0012", + direction="l", + linebreak="id", + specials={ "char", 0x793C }, + unicodeslot=0xFA18, + }, + [0xFA19]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0013", + direction="l", + linebreak="id", + specials={ "char", 0x795E }, + unicodeslot=0xFA19, + }, + [0xFA1A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0001A", + direction="l", + linebreak="id", + specials={ "char", 0x7965 }, + unicodeslot=0xFA1A, + }, + [0xFA1B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0001B", + direction="l", + linebreak="id", + specials={ "char", 0x798F }, + unicodeslot=0xFA1B, + }, + [0xFA1C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0001C", + direction="l", + linebreak="id", + specials={ "char", 0x9756 }, + unicodeslot=0xFA1C, + }, + [0xFA1D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0001D", + direction="l", + linebreak="id", + specials={ "char", 0x7CBE }, + unicodeslot=0xFA1D, + }, + [0xFA1E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0001E", + direction="l", + linebreak="id", + specials={ "char", 0x7FBD }, + unicodeslot=0xFA1E, + }, + [0xFA1F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0001F", + direction="l", + linebreak="id", + unicodeslot=0xFA1F, + }, + [0xFA20]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0014", + direction="l", + linebreak="id", + specials={ "char", 0x8612 }, + unicodeslot=0xFA20, + }, + [0xFA21]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0015", + direction="l", + linebreak="id", + unicodeslot=0xFA21, + }, + [0xFA22]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0016", + direction="l", + linebreak="id", + specials={ "char", 0x8AF8 }, + unicodeslot=0xFA22, + }, + [0xFA23]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0017", + direction="l", + linebreak="id", + unicodeslot=0xFA23, + }, + [0xFA24]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0018", + direction="l", + linebreak="id", + unicodeslot=0xFA24, + }, + [0xFA25]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0019", + direction="l", + linebreak="id", + specials={ "char", 0x9038 }, + unicodeslot=0xFA25, + }, + [0xFA26]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x001A", + direction="l", + linebreak="id", + specials={ "char", 0x90FD }, + unicodeslot=0xFA26, + }, + [0xFA27]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x001B", + direction="l", + linebreak="id", + unicodeslot=0xFA27, + }, + [0xFA28]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x001C", + direction="l", + linebreak="id", + unicodeslot=0xFA28, + }, + [0xFA29]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x001D", + direction="l", + linebreak="id", + unicodeslot=0xFA29, + }, + [0xFA2A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0002A", + direction="l", + linebreak="id", + specials={ "char", 0x98EF }, + unicodeslot=0xFA2A, + }, + [0xFA2B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0002B", + direction="l", + linebreak="id", + specials={ "char", 0x98FC }, + unicodeslot=0xFA2B, + }, + [0xFA2C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0002C", + direction="l", + linebreak="id", + specials={ "char", 0x9928 }, + unicodeslot=0xFA2C, + }, + [0xFA2D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0002D", + direction="l", + linebreak="id", + specials={ "char", 0x9DB4 }, + unicodeslot=0xFA2D, + }, + [0xFA30]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x001E", + direction="l", + linebreak="id", + specials={ "char", 0x4FAE }, + unicodeslot=0xFA30, + }, + [0xFA31]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x001F", + direction="l", + linebreak="id", + specials={ "char", 0x50E7 }, + unicodeslot=0xFA31, + }, + [0xFA32]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0020", + direction="l", + linebreak="id", + specials={ "char", 0x514D }, + unicodeslot=0xFA32, + }, + [0xFA33]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0021", + direction="l", + linebreak="id", + specials={ "char", 0x52C9 }, + unicodeslot=0xFA33, + }, + [0xFA34]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0022", + direction="l", + linebreak="id", + specials={ "char", 0x52E4 }, + unicodeslot=0xFA34, + }, + [0xFA35]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0023", + direction="l", + linebreak="id", + specials={ "char", 0x5351 }, + unicodeslot=0xFA35, + }, + [0xFA36]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0024", + direction="l", + linebreak="id", + specials={ "char", 0x559D }, + unicodeslot=0xFA36, + }, + [0xFA37]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0025", + direction="l", + linebreak="id", + specials={ "char", 0x5606 }, + unicodeslot=0xFA37, + }, + [0xFA38]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0026", + direction="l", + linebreak="id", + specials={ "char", 0x5668 }, + unicodeslot=0xFA38, + }, + [0xFA39]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0027", + direction="l", + linebreak="id", + specials={ "char", 0x5840 }, + unicodeslot=0xFA39, + }, + [0xFA3A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0003A", + direction="l", + linebreak="id", + specials={ "char", 0x58A8 }, + unicodeslot=0xFA3A, + }, + [0xFA3B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0003B", + direction="l", + linebreak="id", + specials={ "char", 0x5C64 }, + unicodeslot=0xFA3B, + }, + [0xFA3C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0003C", + direction="l", + linebreak="id", + specials={ "char", 0x5C6E }, + unicodeslot=0xFA3C, + }, + [0xFA3D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0003D", + direction="l", + linebreak="id", + specials={ "char", 0x6094 }, + unicodeslot=0xFA3D, + }, + [0xFA3E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0003E", + direction="l", + linebreak="id", + specials={ "char", 0x6168 }, + unicodeslot=0xFA3E, + }, + [0xFA3F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0003F", + direction="l", + linebreak="id", + specials={ "char", 0x618E }, + unicodeslot=0xFA3F, + }, + [0xFA40]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0028", + direction="l", + linebreak="id", + specials={ "char", 0x61F2 }, + unicodeslot=0xFA40, + }, + [0xFA41]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0029", + direction="l", + linebreak="id", + specials={ "char", 0x654F }, + unicodeslot=0xFA41, + }, + [0xFA42]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x002A", + direction="l", + linebreak="id", + specials={ "char", 0x65E2 }, + unicodeslot=0xFA42, + }, + [0xFA43]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x002B", + direction="l", + linebreak="id", + specials={ "char", 0x6691 }, + unicodeslot=0xFA43, + }, + [0xFA44]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x002C", + direction="l", + linebreak="id", + specials={ "char", 0x6885 }, + unicodeslot=0xFA44, + }, + [0xFA45]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x002D", + direction="l", + linebreak="id", + specials={ "char", 0x6D77 }, + unicodeslot=0xFA45, + }, + [0xFA46]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x002E", + direction="l", + linebreak="id", + specials={ "char", 0x6E1A }, + unicodeslot=0xFA46, + }, + [0xFA47]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x002F", + direction="l", + linebreak="id", + specials={ "char", 0x6F22 }, + unicodeslot=0xFA47, + }, + [0xFA48]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0030", + direction="l", + linebreak="id", + specials={ "char", 0x716E }, + unicodeslot=0xFA48, + }, + [0xFA49]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0031", + direction="l", + linebreak="id", + specials={ "char", 0x722B }, + unicodeslot=0xFA49, + }, + [0xFA4A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0004A", + direction="l", + linebreak="id", + specials={ "char", 0x7422 }, + unicodeslot=0xFA4A, + }, + [0xFA4B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0004B", + direction="l", + linebreak="id", + specials={ "char", 0x7891 }, + unicodeslot=0xFA4B, + }, + [0xFA4C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0004C", + direction="l", + linebreak="id", + specials={ "char", 0x793E }, + unicodeslot=0xFA4C, + }, + [0xFA4D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0004D", + direction="l", + linebreak="id", + specials={ "char", 0x7949 }, + unicodeslot=0xFA4D, + }, + [0xFA4E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0004E", + direction="l", + linebreak="id", + specials={ "char", 0x7948 }, + unicodeslot=0xFA4E, + }, + [0xFA4F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0004F", + direction="l", + linebreak="id", + specials={ "char", 0x7950 }, + unicodeslot=0xFA4F, + }, + [0xFA50]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0032", + direction="l", + linebreak="id", + specials={ "char", 0x7956 }, + unicodeslot=0xFA50, + }, + [0xFA51]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0033", + direction="l", + linebreak="id", + specials={ "char", 0x795D }, + unicodeslot=0xFA51, + }, + [0xFA52]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0034", + direction="l", + linebreak="id", + specials={ "char", 0x798D }, + unicodeslot=0xFA52, + }, + [0xFA53]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0035", + direction="l", + linebreak="id", + specials={ "char", 0x798E }, + unicodeslot=0xFA53, + }, + [0xFA54]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0036", + direction="l", + linebreak="id", + specials={ "char", 0x7A40 }, + unicodeslot=0xFA54, + }, + [0xFA55]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0037", + direction="l", + linebreak="id", + specials={ "char", 0x7A81 }, + unicodeslot=0xFA55, + }, + [0xFA56]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0038", + direction="l", + linebreak="id", + specials={ "char", 0x7BC0 }, + unicodeslot=0xFA56, + }, + [0xFA57]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0039", + direction="l", + linebreak="id", + specials={ "char", 0x7DF4 }, + unicodeslot=0xFA57, + }, + [0xFA58]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x003A", + direction="l", + linebreak="id", + specials={ "char", 0x7E09 }, + unicodeslot=0xFA58, + }, + [0xFA59]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x003B", + direction="l", + linebreak="id", + specials={ "char", 0x7E41 }, + unicodeslot=0xFA59, + }, + [0xFA5A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0005A", + direction="l", + linebreak="id", + specials={ "char", 0x7F72 }, + unicodeslot=0xFA5A, + }, + [0xFA5B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0005B", + direction="l", + linebreak="id", + specials={ "char", 0x8005 }, + unicodeslot=0xFA5B, + }, + [0xFA5C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0005C", + direction="l", + linebreak="id", + specials={ "char", 0x81ED }, + unicodeslot=0xFA5C, + }, + [0xFA5D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0005D", + direction="l", + linebreak="id", + specials={ "char", 0x8279 }, + unicodeslot=0xFA5D, + }, + [0xFA5E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0005E", + direction="l", + linebreak="id", + specials={ "char", 0x8279 }, + unicodeslot=0xFA5E, + }, + [0xFA5F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0005F", + direction="l", + linebreak="id", + specials={ "char", 0x8457 }, + unicodeslot=0xFA5F, + }, + [0xFA60]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x003C", + direction="l", + linebreak="id", + specials={ "char", 0x8910 }, + unicodeslot=0xFA60, + }, + [0xFA61]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x003D", + direction="l", + linebreak="id", + specials={ "char", 0x8996 }, + unicodeslot=0xFA61, + }, + [0xFA62]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x003E", + direction="l", + linebreak="id", + specials={ "char", 0x8B01 }, + unicodeslot=0xFA62, + }, + [0xFA63]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x003F", + direction="l", + linebreak="id", + specials={ "char", 0x8B39 }, + unicodeslot=0xFA63, + }, + [0xFA64]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0040", + direction="l", + linebreak="id", + specials={ "char", 0x8CD3 }, + unicodeslot=0xFA64, + }, + [0xFA65]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0041", + direction="l", + linebreak="id", + specials={ "char", 0x8D08 }, + unicodeslot=0xFA65, + }, + [0xFA66]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0042", + direction="l", + linebreak="id", + specials={ "char", 0x8FB6 }, + unicodeslot=0xFA66, + }, + [0xFA67]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0043", + direction="l", + linebreak="id", + specials={ "char", 0x9038 }, + unicodeslot=0xFA67, + }, + [0xFA68]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0044", + direction="l", + linebreak="id", + specials={ "char", 0x96E3 }, + unicodeslot=0xFA68, + }, + [0xFA69]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0045", + direction="l", + linebreak="id", + specials={ "char", 0x97FF }, + unicodeslot=0xFA69, + }, + [0xFA6A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0006A", + direction="l", + linebreak="id", + specials={ "char", 0x983B }, + unicodeslot=0xFA6A, + }, + [0xFA70]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0046", + direction="l", + linebreak="id", + specials={ "char", 0x4E26 }, + unicodeslot=0xFA70, + }, + [0xFA71]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0047", + direction="l", + linebreak="id", + specials={ "char", 0x51B5 }, + unicodeslot=0xFA71, + }, + [0xFA72]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0048", + direction="l", + linebreak="id", + specials={ "char", 0x5168 }, + unicodeslot=0xFA72, + }, + [0xFA73]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0049", + direction="l", + linebreak="id", + specials={ "char", 0x4F80 }, + unicodeslot=0xFA73, + }, + [0xFA74]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x004A", + direction="l", + linebreak="id", + specials={ "char", 0x5145 }, + unicodeslot=0xFA74, + }, + [0xFA75]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x004B", + direction="l", + linebreak="id", + specials={ "char", 0x5180 }, + unicodeslot=0xFA75, + }, + [0xFA76]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x004C", + direction="l", + linebreak="id", + specials={ "char", 0x52C7 }, + unicodeslot=0xFA76, + }, + [0xFA77]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x004D", + direction="l", + linebreak="id", + specials={ "char", 0x52FA }, + unicodeslot=0xFA77, + }, + [0xFA78]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x004E", + direction="l", + linebreak="id", + specials={ "char", 0x559D }, + unicodeslot=0xFA78, + }, + [0xFA79]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x004F", + direction="l", + linebreak="id", + specials={ "char", 0x5555 }, + unicodeslot=0xFA79, + }, + [0xFA7A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0007A", + direction="l", + linebreak="id", + specials={ "char", 0x5599 }, + unicodeslot=0xFA7A, + }, + [0xFA7B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0007B", + direction="l", + linebreak="id", + specials={ "char", 0x55E2 }, + unicodeslot=0xFA7B, + }, + [0xFA7C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0007C", + direction="l", + linebreak="id", + specials={ "char", 0x585A }, + unicodeslot=0xFA7C, + }, + [0xFA7D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0007D", + direction="l", + linebreak="id", + specials={ "char", 0x58B3 }, + unicodeslot=0xFA7D, + }, + [0xFA7E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0007E", + direction="l", + linebreak="id", + specials={ "char", 0x5944 }, + unicodeslot=0xFA7E, + }, + [0xFA7F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0007F", + direction="l", + linebreak="id", + specials={ "char", 0x5954 }, + unicodeslot=0xFA7F, + }, + [0xFA80]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0050", + direction="l", + linebreak="id", + specials={ "char", 0x5A62 }, + unicodeslot=0xFA80, + }, + [0xFA81]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0051", + direction="l", + linebreak="id", + specials={ "char", 0x5B28 }, + unicodeslot=0xFA81, + }, + [0xFA82]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0052", + direction="l", + linebreak="id", + specials={ "char", 0x5ED2 }, + unicodeslot=0xFA82, + }, + [0xFA83]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0053", + direction="l", + linebreak="id", + specials={ "char", 0x5ED9 }, + unicodeslot=0xFA83, + }, + [0xFA84]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0054", + direction="l", + linebreak="id", + specials={ "char", 0x5F69 }, + unicodeslot=0xFA84, + }, + [0xFA85]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0055", + direction="l", + linebreak="id", + specials={ "char", 0x5FAD }, + unicodeslot=0xFA85, + }, + [0xFA86]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0056", + direction="l", + linebreak="id", + specials={ "char", 0x60D8 }, + unicodeslot=0xFA86, + }, + [0xFA87]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0057", + direction="l", + linebreak="id", + specials={ "char", 0x614E }, + unicodeslot=0xFA87, + }, + [0xFA88]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0058", + direction="l", + linebreak="id", + specials={ "char", 0x6108 }, + unicodeslot=0xFA88, + }, + [0xFA89]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0059", + direction="l", + linebreak="id", + specials={ "char", 0x618E }, + unicodeslot=0xFA89, + }, + [0xFA8A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0008A", + direction="l", + linebreak="id", + specials={ "char", 0x6160 }, + unicodeslot=0xFA8A, + }, + [0xFA8B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0008B", + direction="l", + linebreak="id", + specials={ "char", 0x61F2 }, + unicodeslot=0xFA8B, + }, + [0xFA8C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0008C", + direction="l", + linebreak="id", + specials={ "char", 0x6234 }, + unicodeslot=0xFA8C, + }, + [0xFA8D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0008D", + direction="l", + linebreak="id", + specials={ "char", 0x63C4 }, + unicodeslot=0xFA8D, + }, + [0xFA8E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0008E", + direction="l", + linebreak="id", + specials={ "char", 0x641C }, + unicodeslot=0xFA8E, + }, + [0xFA8F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0008F", + direction="l", + linebreak="id", + specials={ "char", 0x6452 }, + unicodeslot=0xFA8F, + }, + [0xFA90]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x005A", + direction="l", + linebreak="id", + specials={ "char", 0x6556 }, + unicodeslot=0xFA90, + }, + [0xFA91]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x005B", + direction="l", + linebreak="id", + specials={ "char", 0x6674 }, + unicodeslot=0xFA91, + }, + [0xFA92]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x005C", + direction="l", + linebreak="id", + specials={ "char", 0x6717 }, + unicodeslot=0xFA92, + }, + [0xFA93]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x005D", + direction="l", + linebreak="id", + specials={ "char", 0x671B }, + unicodeslot=0xFA93, + }, + [0xFA94]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x005E", + direction="l", + linebreak="id", + specials={ "char", 0x6756 }, + unicodeslot=0xFA94, + }, + [0xFA95]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x005F", + direction="l", + linebreak="id", + specials={ "char", 0x6B79 }, + unicodeslot=0xFA95, + }, + [0xFA96]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0060", + direction="l", + linebreak="id", + specials={ "char", 0x6BBA }, + unicodeslot=0xFA96, + }, + [0xFA97]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0061", + direction="l", + linebreak="id", + specials={ "char", 0x6D41 }, + unicodeslot=0xFA97, + }, + [0xFA98]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0062", + direction="l", + linebreak="id", + specials={ "char", 0x6EDB }, + unicodeslot=0xFA98, + }, + [0xFA99]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0063", + direction="l", + linebreak="id", + specials={ "char", 0x6ECB }, + unicodeslot=0xFA99, + }, + [0xFA9A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0009A", + direction="l", + linebreak="id", + specials={ "char", 0x6F22 }, + unicodeslot=0xFA9A, + }, + [0xFA9B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0009B", + direction="l", + linebreak="id", + specials={ "char", 0x701E }, + unicodeslot=0xFA9B, + }, + [0xFA9C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0009C", + direction="l", + linebreak="id", + specials={ "char", 0x716E }, + unicodeslot=0xFA9C, + }, + [0xFA9D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0009D", + direction="l", + linebreak="id", + specials={ "char", 0x77A7 }, + unicodeslot=0xFA9D, + }, + [0xFA9E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0009E", + direction="l", + linebreak="id", + specials={ "char", 0x7235 }, + unicodeslot=0xFA9E, + }, + [0xFA9F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FA0x0009F", + direction="l", + linebreak="id", + specials={ "char", 0x72AF }, + unicodeslot=0xFA9F, + }, + [0xFAA0]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAA0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x732A }, + unicodeslot=0xFAA0, + }, + [0xFAA1]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAA0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x7471 }, + unicodeslot=0xFAA1, + }, + [0xFAA2]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAA0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x7506 }, + unicodeslot=0xFAA2, + }, + [0xFAA3]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAA0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x753B }, + unicodeslot=0xFAA3, + }, + [0xFAA4]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAA0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x761D }, + unicodeslot=0xFAA4, + }, + [0xFAA5]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAA0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x761F }, + unicodeslot=0xFAA5, + }, + [0xFAA6]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAA0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x76CA }, + unicodeslot=0xFAA6, + }, + [0xFAA7]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAA0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x76DB }, + unicodeslot=0xFAA7, + }, + [0xFAA8]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAA0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x76F4 }, + unicodeslot=0xFAA8, + }, + [0xFAA9]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAA0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x774A }, + unicodeslot=0xFAA9, + }, + [0xFAAA]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAAA", + direction="l", + linebreak="id", + specials={ "char", 0x7740 }, + unicodeslot=0xFAAA, + }, + [0xFAAB]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAAB", + direction="l", + linebreak="id", + specials={ "char", 0x78CC }, + unicodeslot=0xFAAB, + }, + [0xFAAC]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAAC", + direction="l", + linebreak="id", + specials={ "char", 0x7AB1 }, + unicodeslot=0xFAAC, + }, + [0xFAAD]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAAD", + direction="l", + linebreak="id", + specials={ "char", 0x7BC0 }, + unicodeslot=0xFAAD, + }, + [0xFAAE]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAAE", + direction="l", + linebreak="id", + specials={ "char", 0x7C7B }, + unicodeslot=0xFAAE, + }, + [0xFAAF]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAAF", + direction="l", + linebreak="id", + specials={ "char", 0x7D5B }, + unicodeslot=0xFAAF, + }, + [0xFAB0]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAB0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x7DF4 }, + unicodeslot=0xFAB0, + }, + [0xFAB1]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAB0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x7F3E }, + unicodeslot=0xFAB1, + }, + [0xFAB2]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAB0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x8005 }, + unicodeslot=0xFAB2, + }, + [0xFAB3]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAB0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x8352 }, + unicodeslot=0xFAB3, + }, + [0xFAB4]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAB0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x83EF }, + unicodeslot=0xFAB4, + }, + [0xFAB5]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAB0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x8779 }, + unicodeslot=0xFAB5, + }, + [0xFAB6]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAB0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x8941 }, + unicodeslot=0xFAB6, + }, + [0xFAB7]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAB0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x8986 }, + unicodeslot=0xFAB7, + }, + [0xFAB8]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAB0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x8996 }, + unicodeslot=0xFAB8, + }, + [0xFAB9]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAB0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x8ABF }, + unicodeslot=0xFAB9, + }, + [0xFABA]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FABA", + direction="l", + linebreak="id", + specials={ "char", 0x8AF8 }, + unicodeslot=0xFABA, + }, + [0xFABB]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FABB", + direction="l", + linebreak="id", + specials={ "char", 0x8ACB }, + unicodeslot=0xFABB, + }, + [0xFABC]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FABC", + direction="l", + linebreak="id", + specials={ "char", 0x8B01 }, + unicodeslot=0xFABC, + }, + [0xFABD]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FABD", + direction="l", + linebreak="id", + specials={ "char", 0x8AFE }, + unicodeslot=0xFABD, + }, + [0xFABE]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FABE", + direction="l", + linebreak="id", + specials={ "char", 0x8AED }, + unicodeslot=0xFABE, + }, + [0xFABF]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FABF", + direction="l", + linebreak="id", + specials={ "char", 0x8B39 }, + unicodeslot=0xFABF, + }, + [0xFAC0]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAC0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x8B8A }, + unicodeslot=0xFAC0, + }, + [0xFAC1]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAC0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x8D08 }, + unicodeslot=0xFAC1, + }, + [0xFAC2]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAC0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x8F38 }, + unicodeslot=0xFAC2, + }, + [0xFAC3]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAC0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x9072 }, + unicodeslot=0xFAC3, + }, + [0xFAC4]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAC0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x9199 }, + unicodeslot=0xFAC4, + }, + [0xFAC5]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAC0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x9276 }, + unicodeslot=0xFAC5, + }, + [0xFAC6]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAC0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x967C }, + unicodeslot=0xFAC6, + }, + [0xFAC7]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAC0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x96E3 }, + unicodeslot=0xFAC7, + }, + [0xFAC8]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAC0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x9756 }, + unicodeslot=0xFAC8, + }, + [0xFAC9]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAC0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x97DB }, + unicodeslot=0xFAC9, + }, + [0xFACA]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FACA", + direction="l", + linebreak="id", + specials={ "char", 0x97FF }, + unicodeslot=0xFACA, + }, + [0xFACB]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FACB", + direction="l", + linebreak="id", + specials={ "char", 0x980B }, + unicodeslot=0xFACB, + }, + [0xFACC]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FACC", + direction="l", + linebreak="id", + specials={ "char", 0x983B }, + unicodeslot=0xFACC, + }, + [0xFACD]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FACD", + direction="l", + linebreak="id", + specials={ "char", 0x9B12 }, + unicodeslot=0xFACD, + }, + [0xFACE]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FACE", + direction="l", + linebreak="id", + specials={ "char", 0x9F9C }, + unicodeslot=0xFACE, + }, + [0xFACF]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FACF", + direction="l", + linebreak="id", + specials={ "char", 0x2284A }, + unicodeslot=0xFACF, + }, + [0xFAD0]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAD0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x22844 }, + unicodeslot=0xFAD0, + }, + [0xFAD1]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAD0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x233D5 }, + unicodeslot=0xFAD1, + }, + [0xFAD2]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAD0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x3B9D }, + unicodeslot=0xFAD2, + }, + [0xFAD3]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAD0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x4018 }, + unicodeslot=0xFAD3, + }, + [0xFAD4]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAD0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x4039 }, + unicodeslot=0xFAD4, + }, + [0xFAD5]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAD0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x25249 }, + unicodeslot=0xFAD5, + }, + [0xFAD6]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAD0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x25CD0 }, + unicodeslot=0xFAD6, + }, + [0xFAD7]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAD0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x27ED3 }, + unicodeslot=0xFAD7, + }, + [0xFAD8]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAD0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x9F43 }, + unicodeslot=0xFAD8, + }, + [0xFAD9]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-FAD0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x9F8E }, + unicodeslot=0xFAD9, + }, + [0xFB00]={ + category="ll", + contextname="ffligature", + description="LATIN SMALL LIGATURE FF", + direction="l", + linebreak="al", + specials={ "compat", 0x0066, 0x0066 }, + unicodeslot=0xFB00, + }, + [0xFB01]={ + category="ll", + contextname="filigature", + description="LATIN SMALL LIGATURE FI", + direction="l", + linebreak="al", + shcode={ 0x0066, 0x0069 }, + specials={ "compat", 0x0066, 0x0069 }, + unicodeslot=0xFB01, + }, + [0xFB02]={ + category="ll", + contextname="flligature", + description="LATIN SMALL LIGATURE FL", + direction="l", + linebreak="al", + shcode={ 0x0066, 0x006C }, + specials={ "compat", 0x0066, 0x006C }, + unicodeslot=0xFB02, + }, + [0xFB03]={ + category="ll", + contextname="ffiligature", + description="LATIN SMALL LIGATURE FFI", + direction="l", + linebreak="al", + shcode={ 0x0066, 0x0069 }, + specials={ "compat", 0x0066, 0x0066, 0x0069 }, + unicodeslot=0xFB03, + }, + [0xFB04]={ + category="ll", + contextname="fflligature", + description="LATIN SMALL LIGATURE FFL", + direction="l", + linebreak="al", + shcode={ 0x0066, 0x006C }, + specials={ "compat", 0x0066, 0x0066, 0x006C }, + unicodeslot=0xFB04, + }, + [0xFB05]={ + category="ll", + description="LATIN SMALL LIGATURE LONG S T", + direction="l", + linebreak="al", + specials={ "compat", 0x017F, 0x0074 }, + unicodeslot=0xFB05, + }, + [0xFB06]={ + category="ll", + contextname="stligature", + description="LATIN SMALL LIGATURE ST", + direction="l", + linebreak="al", + shcode={ 0x0073, 0x0074 }, + specials={ "compat", 0x0073, 0x0074 }, + unicodeslot=0xFB06, + }, + [0xFB13]={ + category="ll", + description="ARMENIAN SMALL LIGATURE MEN NOW", + direction="l", + linebreak="al", + specials={ "compat", 0x0574, 0x0576 }, + unicodeslot=0xFB13, + }, + [0xFB14]={ + category="ll", + description="ARMENIAN SMALL LIGATURE MEN ECH", + direction="l", + linebreak="al", + specials={ "compat", 0x0574, 0x0565 }, + unicodeslot=0xFB14, + }, + [0xFB15]={ + category="ll", + description="ARMENIAN SMALL LIGATURE MEN INI", + direction="l", + linebreak="al", + specials={ "compat", 0x0574, 0x056B }, + unicodeslot=0xFB15, + }, + [0xFB16]={ + category="ll", + description="ARMENIAN SMALL LIGATURE VEW NOW", + direction="l", + linebreak="al", + specials={ "compat", 0x057E, 0x0576 }, + unicodeslot=0xFB16, + }, + [0xFB17]={ + category="ll", + description="ARMENIAN SMALL LIGATURE MEN XEH", + direction="l", + linebreak="al", + specials={ "compat", 0x0574, 0x056D }, + unicodeslot=0xFB17, + }, + [0xFB1D]={ + category="lo", + description="HEBREW LETTER YOD WITH HIRIQ", + direction="r", + linebreak="al", + shcode=0x05D9, + specials={ "char", 0x05D9, 0x05B4 }, + unicodeslot=0xFB1D, + }, + [0xFB1E]={ + category="mn", + description="HEBREW POINT JUDEO-SPANISH VARIKA", + direction="nsm", + linebreak="cm", + unicodeslot=0xFB1E, + }, + [0xFB1F]={ + category="lo", + description="HEBREW LIGATURE YIDDISH YOD YOD PATAH", + direction="r", + linebreak="al", + specials={ "char", 0x05F2, 0x05B7 }, + unicodeslot=0xFB1F, + }, + [0xFB20]={ + category="lo", + description="HEBREW LETTER ALTERNATIVE AYIN", + direction="r", + linebreak="al", + specials={ "font", 0x05E2 }, + unicodeslot=0xFB20, + }, + [0xFB21]={ + category="lo", + description="HEBREW LETTER WIDE ALEF", + direction="r", + linebreak="al", + specials={ "font", 0x05D0 }, + unicodeslot=0xFB21, + }, + [0xFB22]={ + category="lo", + description="HEBREW LETTER WIDE DALET", + direction="r", + linebreak="al", + specials={ "font", 0x05D3 }, + unicodeslot=0xFB22, + }, + [0xFB23]={ + category="lo", + description="HEBREW LETTER WIDE HE", + direction="r", + linebreak="al", + specials={ "font", 0x05D4 }, + unicodeslot=0xFB23, + }, + [0xFB24]={ + category="lo", + description="HEBREW LETTER WIDE KAF", + direction="r", + linebreak="al", + specials={ "font", 0x05DB }, + unicodeslot=0xFB24, + }, + [0xFB25]={ + category="lo", + description="HEBREW LETTER WIDE LAMED", + direction="r", + linebreak="al", + specials={ "font", 0x05DC }, + unicodeslot=0xFB25, + }, + [0xFB26]={ + category="lo", + description="HEBREW LETTER WIDE FINAL MEM", + direction="r", + linebreak="al", + specials={ "font", 0x05DD }, + unicodeslot=0xFB26, + }, + [0xFB27]={ + category="lo", + description="HEBREW LETTER WIDE RESH", + direction="r", + linebreak="al", + specials={ "font", 0x05E8 }, + unicodeslot=0xFB27, + }, + [0xFB28]={ + category="lo", + description="HEBREW LETTER WIDE TAV", + direction="r", + linebreak="al", + specials={ "font", 0x05EA }, + unicodeslot=0xFB28, + }, + [0xFB29]={ + category="sm", + description="HEBREW LETTER ALTERNATIVE PLUS SIGN", + direction="es", + linebreak="al", + specials={ "font", 0x002B }, + unicodeslot=0xFB29, + }, + [0xFB2A]={ + category="lo", + description="HEBREW LETTER SHIN WITH SHIN DOT", + direction="r", + linebreak="al", + shcode=0x05E9, + specials={ "char", 0x05E9, 0x05C1 }, + unicodeslot=0xFB2A, + }, + [0xFB2B]={ + category="lo", + description="HEBREW LETTER SHIN WITH SIN DOT", + direction="r", + linebreak="al", + shcode=0x05E9, + specials={ "char", 0x05E9, 0x05C2 }, + unicodeslot=0xFB2B, + }, + [0xFB2C]={ + category="lo", + description="HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT", + direction="r", + linebreak="al", + shcode=0x05E9, + specials={ "char", 0xFB49, 0x05C1 }, + unicodeslot=0xFB2C, + }, + [0xFB2D]={ + category="lo", + description="HEBREW LETTER SHIN WITH DAGESH AND SIN DOT", + direction="r", + linebreak="al", + shcode=0x05E9, + specials={ "char", 0xFB49, 0x05C2 }, + unicodeslot=0xFB2D, + }, + [0xFB2E]={ + category="lo", + description="HEBREW LETTER ALEF WITH PATAH", + direction="r", + linebreak="al", + shcode=0x05D0, + specials={ "char", 0x05D0, 0x05B7 }, + unicodeslot=0xFB2E, + }, + [0xFB2F]={ + category="lo", + description="HEBREW LETTER ALEF WITH QAMATS", + direction="r", + linebreak="al", + shcode=0x05D0, + specials={ "char", 0x05D0, 0x05B8 }, + unicodeslot=0xFB2F, + }, + [0xFB30]={ + category="lo", + description="HEBREW LETTER ALEF WITH MAPIQ", + direction="r", + linebreak="al", + shcode=0x05D0, + specials={ "char", 0x05D0, 0x05BC }, + unicodeslot=0xFB30, + }, + [0xFB31]={ + category="lo", + description="HEBREW LETTER BET WITH DAGESH", + direction="r", + linebreak="al", + shcode=0x05D1, + specials={ "char", 0x05D1, 0x05BC }, + unicodeslot=0xFB31, + }, + [0xFB32]={ + category="lo", + description="HEBREW LETTER GIMEL WITH DAGESH", + direction="r", + linebreak="al", + shcode=0x05D2, + specials={ "char", 0x05D2, 0x05BC }, + unicodeslot=0xFB32, + }, + [0xFB33]={ + category="lo", + description="HEBREW LETTER DALET WITH DAGESH", + direction="r", + linebreak="al", + shcode=0x05D3, + specials={ "char", 0x05D3, 0x05BC }, + unicodeslot=0xFB33, + }, + [0xFB34]={ + category="lo", + description="HEBREW LETTER HE WITH MAPIQ", + direction="r", + linebreak="al", + shcode=0x05D4, + specials={ "char", 0x05D4, 0x05BC }, + unicodeslot=0xFB34, + }, + [0xFB35]={ + category="lo", + description="HEBREW LETTER VAV WITH DAGESH", + direction="r", + linebreak="al", + shcode=0x05D5, + specials={ "char", 0x05D5, 0x05BC }, + unicodeslot=0xFB35, + }, + [0xFB36]={ + category="lo", + description="HEBREW LETTER ZAYIN WITH DAGESH", + direction="r", + linebreak="al", + shcode=0x05D6, + specials={ "char", 0x05D6, 0x05BC }, + unicodeslot=0xFB36, + }, + [0xFB38]={ + category="lo", + description="HEBREW LETTER TET WITH DAGESH", + direction="r", + linebreak="al", + shcode=0x05D8, + specials={ "char", 0x05D8, 0x05BC }, + unicodeslot=0xFB38, + }, + [0xFB39]={ + category="lo", + description="HEBREW LETTER YOD WITH DAGESH", + direction="r", + linebreak="al", + shcode=0x05D9, + specials={ "char", 0x05D9, 0x05BC }, + unicodeslot=0xFB39, + }, + [0xFB3A]={ + category="lo", + description="HEBREW LETTER FINAL KAF WITH DAGESH", + direction="r", + linebreak="al", + specials={ "char", 0x05DA, 0x05BC }, + unicodeslot=0xFB3A, + }, + [0xFB3B]={ + category="lo", + description="HEBREW LETTER KAF WITH DAGESH", + direction="r", + linebreak="al", + shcode=0x05DB, + specials={ "char", 0x05DB, 0x05BC }, + unicodeslot=0xFB3B, + }, + [0xFB3C]={ + category="lo", + description="HEBREW LETTER LAMED WITH DAGESH", + direction="r", + linebreak="al", + shcode=0x05DC, + specials={ "char", 0x05DC, 0x05BC }, + unicodeslot=0xFB3C, + }, + [0xFB3E]={ + category="lo", + description="HEBREW LETTER MEM WITH DAGESH", + direction="r", + linebreak="al", + shcode=0x05DE, + specials={ "char", 0x05DE, 0x05BC }, + unicodeslot=0xFB3E, + }, + [0xFB40]={ + category="lo", + description="HEBREW LETTER NUN WITH DAGESH", + direction="r", + linebreak="al", + shcode=0x05E0, + specials={ "char", 0x05E0, 0x05BC }, + unicodeslot=0xFB40, + }, + [0xFB41]={ + category="lo", + description="HEBREW LETTER SAMEKH WITH DAGESH", + direction="r", + linebreak="al", + shcode=0x05E1, + specials={ "char", 0x05E1, 0x05BC }, + unicodeslot=0xFB41, + }, + [0xFB43]={ + category="lo", + description="HEBREW LETTER FINAL PE WITH DAGESH", + direction="r", + linebreak="al", + specials={ "char", 0x05E3, 0x05BC }, + unicodeslot=0xFB43, + }, + [0xFB44]={ + category="lo", + description="HEBREW LETTER PE WITH DAGESH", + direction="r", + linebreak="al", + shcode=0x05E4, + specials={ "char", 0x05E4, 0x05BC }, + unicodeslot=0xFB44, + }, + [0xFB46]={ + category="lo", + description="HEBREW LETTER TSADI WITH DAGESH", + direction="r", + linebreak="al", + shcode=0x05E6, + specials={ "char", 0x05E6, 0x05BC }, + unicodeslot=0xFB46, + }, + [0xFB47]={ + category="lo", + description="HEBREW LETTER QOF WITH DAGESH", + direction="r", + linebreak="al", + shcode=0x05E7, + specials={ "char", 0x05E7, 0x05BC }, + unicodeslot=0xFB47, + }, + [0xFB48]={ + category="lo", + description="HEBREW LETTER RESH WITH DAGESH", + direction="r", + linebreak="al", + shcode=0x05E8, + specials={ "char", 0x05E8, 0x05BC }, + unicodeslot=0xFB48, + }, + [0xFB49]={ + category="lo", + description="HEBREW LETTER SHIN WITH DAGESH", + direction="r", + linebreak="al", + shcode=0x05E9, + specials={ "char", 0x05E9, 0x05BC }, + unicodeslot=0xFB49, + }, + [0xFB4A]={ + category="lo", + description="HEBREW LETTER TAV WITH DAGESH", + direction="r", + linebreak="al", + shcode=0x05EA, + specials={ "char", 0x05EA, 0x05BC }, + unicodeslot=0xFB4A, + }, + [0xFB4B]={ + category="lo", + description="HEBREW LETTER VAV WITH HOLAM", + direction="r", + linebreak="al", + shcode=0x05D5, + specials={ "char", 0x05D5, 0x05B9 }, + unicodeslot=0xFB4B, + }, + [0xFB4C]={ + category="lo", + description="HEBREW LETTER BET WITH RAFE", + direction="r", + linebreak="al", + shcode=0x05D1, + specials={ "char", 0x05D1, 0x05BF }, + unicodeslot=0xFB4C, + }, + [0xFB4D]={ + category="lo", + description="HEBREW LETTER KAF WITH RAFE", + direction="r", + linebreak="al", + shcode=0x05DB, + specials={ "char", 0x05DB, 0x05BF }, + unicodeslot=0xFB4D, + }, + [0xFB4E]={ + category="lo", + description="HEBREW LETTER PE WITH RAFE", + direction="r", + linebreak="al", + shcode=0x05E4, + specials={ "char", 0x05E4, 0x05BF }, + unicodeslot=0xFB4E, + }, + [0xFB4F]={ + category="lo", + description="HEBREW LIGATURE ALEF LAMED", + direction="r", + linebreak="al", + specials={ "compat", 0x05D0, 0x05DC }, + unicodeslot=0xFB4F, + }, + [0xFB50]={ + category="lo", + description="ARABIC LETTER ALEF WASLA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0671 }, + unicodeslot=0xFB50, + }, + [0xFB51]={ + category="lo", + description="ARABIC LETTER ALEF WASLA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0671 }, + unicodeslot=0xFB51, + }, + [0xFB52]={ + category="lo", + description="ARABIC LETTER BEEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x067B }, + unicodeslot=0xFB52, + }, + [0xFB53]={ + category="lo", + description="ARABIC LETTER BEEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x067B }, + unicodeslot=0xFB53, + }, + [0xFB54]={ + category="lo", + description="ARABIC LETTER BEEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x067B }, + unicodeslot=0xFB54, + }, + [0xFB55]={ + category="lo", + description="ARABIC LETTER BEEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x067B }, + unicodeslot=0xFB55, + }, + [0xFB56]={ + category="lo", + description="ARABIC LETTER PEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x067E }, + unicodeslot=0xFB56, + }, + [0xFB57]={ + category="lo", + description="ARABIC LETTER PEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x067E }, + unicodeslot=0xFB57, + }, + [0xFB58]={ + category="lo", + description="ARABIC LETTER PEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x067E }, + unicodeslot=0xFB58, + }, + [0xFB59]={ + category="lo", + description="ARABIC LETTER PEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x067E }, + unicodeslot=0xFB59, + }, + [0xFB5A]={ + category="lo", + description="ARABIC LETTER BEHEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0680 }, + unicodeslot=0xFB5A, + }, + [0xFB5B]={ + category="lo", + description="ARABIC LETTER BEHEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0680 }, + unicodeslot=0xFB5B, + }, + [0xFB5C]={ + category="lo", + description="ARABIC LETTER BEHEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0680 }, + unicodeslot=0xFB5C, + }, + [0xFB5D]={ + category="lo", + description="ARABIC LETTER BEHEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0680 }, + unicodeslot=0xFB5D, + }, + [0xFB5E]={ + category="lo", + description="ARABIC LETTER TTEHEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x067A }, + unicodeslot=0xFB5E, + }, + [0xFB5F]={ + category="lo", + description="ARABIC LETTER TTEHEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x067A }, + unicodeslot=0xFB5F, + }, + [0xFB60]={ + category="lo", + description="ARABIC LETTER TTEHEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x067A }, + unicodeslot=0xFB60, + }, + [0xFB61]={ + category="lo", + description="ARABIC LETTER TTEHEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x067A }, + unicodeslot=0xFB61, + }, + [0xFB62]={ + category="lo", + description="ARABIC LETTER TEHEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x067F }, + unicodeslot=0xFB62, + }, + [0xFB63]={ + category="lo", + description="ARABIC LETTER TEHEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x067F }, + unicodeslot=0xFB63, + }, + [0xFB64]={ + category="lo", + description="ARABIC LETTER TEHEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x067F }, + unicodeslot=0xFB64, + }, + [0xFB65]={ + category="lo", + description="ARABIC LETTER TEHEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x067F }, + unicodeslot=0xFB65, + }, + [0xFB66]={ + category="lo", + description="ARABIC LETTER TTEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0679 }, + unicodeslot=0xFB66, + }, + [0xFB67]={ + category="lo", + description="ARABIC LETTER TTEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0679 }, + unicodeslot=0xFB67, + }, + [0xFB68]={ + category="lo", + description="ARABIC LETTER TTEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0679 }, + unicodeslot=0xFB68, + }, + [0xFB69]={ + category="lo", + description="ARABIC LETTER TTEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0679 }, + unicodeslot=0xFB69, + }, + [0xFB6A]={ + category="lo", + description="ARABIC LETTER VEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x06A4 }, + unicodeslot=0xFB6A, + }, + [0xFB6B]={ + category="lo", + description="ARABIC LETTER VEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x06A4 }, + unicodeslot=0xFB6B, + }, + [0xFB6C]={ + category="lo", + description="ARABIC LETTER VEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x06A4 }, + unicodeslot=0xFB6C, + }, + [0xFB6D]={ + category="lo", + description="ARABIC LETTER VEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x06A4 }, + unicodeslot=0xFB6D, + }, + [0xFB6E]={ + category="lo", + description="ARABIC LETTER PEHEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x06A6 }, + unicodeslot=0xFB6E, + }, + [0xFB6F]={ + category="lo", + description="ARABIC LETTER PEHEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x06A6 }, + unicodeslot=0xFB6F, + }, + [0xFB70]={ + category="lo", + description="ARABIC LETTER PEHEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x06A6 }, + unicodeslot=0xFB70, + }, + [0xFB71]={ + category="lo", + description="ARABIC LETTER PEHEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x06A6 }, + unicodeslot=0xFB71, + }, + [0xFB72]={ + category="lo", + description="ARABIC LETTER DYEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0684 }, + unicodeslot=0xFB72, + }, + [0xFB73]={ + category="lo", + description="ARABIC LETTER DYEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0684 }, + unicodeslot=0xFB73, + }, + [0xFB74]={ + category="lo", + description="ARABIC LETTER DYEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0684 }, + unicodeslot=0xFB74, + }, + [0xFB75]={ + category="lo", + description="ARABIC LETTER DYEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0684 }, + unicodeslot=0xFB75, + }, + [0xFB76]={ + category="lo", + description="ARABIC LETTER NYEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0683 }, + unicodeslot=0xFB76, + }, + [0xFB77]={ + category="lo", + description="ARABIC LETTER NYEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0683 }, + unicodeslot=0xFB77, + }, + [0xFB78]={ + category="lo", + description="ARABIC LETTER NYEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0683 }, + unicodeslot=0xFB78, + }, + [0xFB79]={ + category="lo", + description="ARABIC LETTER NYEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0683 }, + unicodeslot=0xFB79, + }, + [0xFB7A]={ + category="lo", + description="ARABIC LETTER TCHEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0686 }, + unicodeslot=0xFB7A, + }, + [0xFB7B]={ + category="lo", + description="ARABIC LETTER TCHEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0686 }, + unicodeslot=0xFB7B, + }, + [0xFB7C]={ + category="lo", + description="ARABIC LETTER TCHEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0686 }, + unicodeslot=0xFB7C, + }, + [0xFB7D]={ + category="lo", + description="ARABIC LETTER TCHEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0686 }, + unicodeslot=0xFB7D, + }, + [0xFB7E]={ + category="lo", + description="ARABIC LETTER TCHEHEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0687 }, + unicodeslot=0xFB7E, + }, + [0xFB7F]={ + category="lo", + description="ARABIC LETTER TCHEHEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0687 }, + unicodeslot=0xFB7F, + }, + [0xFB80]={ + category="lo", + description="ARABIC LETTER TCHEHEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0687 }, + unicodeslot=0xFB80, + }, + [0xFB81]={ + category="lo", + description="ARABIC LETTER TCHEHEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0687 }, + unicodeslot=0xFB81, + }, + [0xFB82]={ + category="lo", + description="ARABIC LETTER DDAHAL ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x068D }, + unicodeslot=0xFB82, + }, + [0xFB83]={ + category="lo", + description="ARABIC LETTER DDAHAL FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x068D }, + unicodeslot=0xFB83, + }, + [0xFB84]={ + category="lo", + description="ARABIC LETTER DAHAL ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x068C }, + unicodeslot=0xFB84, + }, + [0xFB85]={ + category="lo", + description="ARABIC LETTER DAHAL FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x068C }, + unicodeslot=0xFB85, + }, + [0xFB86]={ + category="lo", + description="ARABIC LETTER DUL ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x068E }, + unicodeslot=0xFB86, + }, + [0xFB87]={ + category="lo", + description="ARABIC LETTER DUL FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x068E }, + unicodeslot=0xFB87, + }, + [0xFB88]={ + category="lo", + description="ARABIC LETTER DDAL ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0688 }, + unicodeslot=0xFB88, + }, + [0xFB89]={ + category="lo", + description="ARABIC LETTER DDAL FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0688 }, + unicodeslot=0xFB89, + }, + [0xFB8A]={ + category="lo", + description="ARABIC LETTER JEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0698 }, + unicodeslot=0xFB8A, + }, + [0xFB8B]={ + category="lo", + description="ARABIC LETTER JEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0698 }, + unicodeslot=0xFB8B, + }, + [0xFB8C]={ + category="lo", + description="ARABIC LETTER RREH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0691 }, + unicodeslot=0xFB8C, + }, + [0xFB8D]={ + category="lo", + description="ARABIC LETTER RREH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0691 }, + unicodeslot=0xFB8D, + }, + [0xFB8E]={ + category="lo", + description="ARABIC LETTER KEHEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x06A9 }, + unicodeslot=0xFB8E, + }, + [0xFB8F]={ + category="lo", + description="ARABIC LETTER KEHEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x06A9 }, + unicodeslot=0xFB8F, + }, + [0xFB90]={ + category="lo", + description="ARABIC LETTER KEHEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x06A9 }, + unicodeslot=0xFB90, + }, + [0xFB91]={ + category="lo", + description="ARABIC LETTER KEHEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x06A9 }, + unicodeslot=0xFB91, + }, + [0xFB92]={ + category="lo", + description="ARABIC LETTER GAF ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x06AF }, + unicodeslot=0xFB92, + }, + [0xFB93]={ + category="lo", + description="ARABIC LETTER GAF FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x06AF }, + unicodeslot=0xFB93, + }, + [0xFB94]={ + category="lo", + description="ARABIC LETTER GAF INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x06AF }, + unicodeslot=0xFB94, + }, + [0xFB95]={ + category="lo", + description="ARABIC LETTER GAF MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x06AF }, + unicodeslot=0xFB95, + }, + [0xFB96]={ + category="lo", + description="ARABIC LETTER GUEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x06B3 }, + unicodeslot=0xFB96, + }, + [0xFB97]={ + category="lo", + description="ARABIC LETTER GUEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x06B3 }, + unicodeslot=0xFB97, + }, + [0xFB98]={ + category="lo", + description="ARABIC LETTER GUEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x06B3 }, + unicodeslot=0xFB98, + }, + [0xFB99]={ + category="lo", + description="ARABIC LETTER GUEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x06B3 }, + unicodeslot=0xFB99, + }, + [0xFB9A]={ + category="lo", + description="ARABIC LETTER NGOEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x06B1 }, + unicodeslot=0xFB9A, + }, + [0xFB9B]={ + category="lo", + description="ARABIC LETTER NGOEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x06B1 }, + unicodeslot=0xFB9B, + }, + [0xFB9C]={ + category="lo", + description="ARABIC LETTER NGOEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x06B1 }, + unicodeslot=0xFB9C, + }, + [0xFB9D]={ + category="lo", + description="ARABIC LETTER NGOEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x06B1 }, + unicodeslot=0xFB9D, + }, + [0xFB9E]={ + category="lo", + description="ARABIC LETTER NOON GHUNNA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x06BA }, + unicodeslot=0xFB9E, + }, + [0xFB9F]={ + category="lo", + description="ARABIC LETTER NOON GHUNNA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x06BA }, + unicodeslot=0xFB9F, + }, + [0xFBA0]={ + category="lo", + description="ARABIC LETTER RNOON ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x06BB }, + unicodeslot=0xFBA0, + }, + [0xFBA1]={ + category="lo", + description="ARABIC LETTER RNOON FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x06BB }, + unicodeslot=0xFBA1, + }, + [0xFBA2]={ + category="lo", + description="ARABIC LETTER RNOON INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x06BB }, + unicodeslot=0xFBA2, + }, + [0xFBA3]={ + category="lo", + description="ARABIC LETTER RNOON MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x06BB }, + unicodeslot=0xFBA3, + }, + [0xFBA4]={ + category="lo", + description="ARABIC LETTER HEH WITH YEH ABOVE ISOLATED FORM", + direction="al", + linebreak="al", + shcode=0x0647, + specials={ "isolated", 0x06C0 }, + unicodeslot=0xFBA4, + }, + [0xFBA5]={ + category="lo", + description="ARABIC LETTER HEH WITH YEH ABOVE FINAL FORM", + direction="al", + linebreak="al", + shcode=0x0647, + specials={ "final", 0x06C0 }, + unicodeslot=0xFBA5, + }, + [0xFBA6]={ + category="lo", + description="ARABIC LETTER HEH GOAL ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x06C1 }, + unicodeslot=0xFBA6, + }, + [0xFBA7]={ + category="lo", + description="ARABIC LETTER HEH GOAL FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x06C1 }, + unicodeslot=0xFBA7, + }, + [0xFBA8]={ + category="lo", + description="ARABIC LETTER HEH GOAL INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x06C1 }, + unicodeslot=0xFBA8, + }, + [0xFBA9]={ + category="lo", + description="ARABIC LETTER HEH GOAL MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x06C1 }, + unicodeslot=0xFBA9, + }, + [0xFBAA]={ + category="lo", + description="ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x06BE }, + unicodeslot=0xFBAA, + }, + [0xFBAB]={ + category="lo", + description="ARABIC LETTER HEH DOACHASHMEE FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x06BE }, + unicodeslot=0xFBAB, + }, + [0xFBAC]={ + category="lo", + description="ARABIC LETTER HEH DOACHASHMEE INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x06BE }, + unicodeslot=0xFBAC, + }, + [0xFBAD]={ + category="lo", + description="ARABIC LETTER HEH DOACHASHMEE MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x06BE }, + unicodeslot=0xFBAD, + }, + [0xFBAE]={ + category="lo", + description="ARABIC LETTER YEH BARREE ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x06D2 }, + unicodeslot=0xFBAE, + }, + [0xFBAF]={ + category="lo", + description="ARABIC LETTER YEH BARREE FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x06D2 }, + unicodeslot=0xFBAF, + }, + [0xFBB0]={ + category="lo", + description="ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x06D3 }, + unicodeslot=0xFBB0, + }, + [0xFBB1]={ + category="lo", + description="ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x06D3 }, + unicodeslot=0xFBB1, + }, + [0xFBD3]={ + category="lo", + description="ARABIC LETTER NG ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x06AD }, + unicodeslot=0xFBD3, + }, + [0xFBD4]={ + category="lo", + description="ARABIC LETTER NG FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x06AD }, + unicodeslot=0xFBD4, + }, + [0xFBD5]={ + category="lo", + description="ARABIC LETTER NG INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x06AD }, + unicodeslot=0xFBD5, + }, + [0xFBD6]={ + category="lo", + description="ARABIC LETTER NG MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x06AD }, + unicodeslot=0xFBD6, + }, + [0xFBD7]={ + category="lo", + description="ARABIC LETTER U ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x06C7 }, + unicodeslot=0xFBD7, + }, + [0xFBD8]={ + category="lo", + description="ARABIC LETTER U FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x06C7 }, + unicodeslot=0xFBD8, + }, + [0xFBD9]={ + category="lo", + description="ARABIC LETTER OE ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x06C6 }, + unicodeslot=0xFBD9, + }, + [0xFBDA]={ + category="lo", + description="ARABIC LETTER OE FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x06C6 }, + unicodeslot=0xFBDA, + }, + [0xFBDB]={ + category="lo", + description="ARABIC LETTER YU ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x06C8 }, + unicodeslot=0xFBDB, + }, + [0xFBDC]={ + category="lo", + description="ARABIC LETTER YU FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x06C8 }, + unicodeslot=0xFBDC, + }, + [0xFBDD]={ + category="lo", + description="ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM", + direction="al", + linebreak="al", + shcode=0x06C7, + specials={ "isolated", 0x0677 }, + unicodeslot=0xFBDD, + }, + [0xFBDE]={ + category="lo", + description="ARABIC LETTER VE ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x06CB }, + unicodeslot=0xFBDE, + }, + [0xFBDF]={ + category="lo", + description="ARABIC LETTER VE FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x06CB }, + unicodeslot=0xFBDF, + }, + [0xFBE0]={ + category="lo", + description="ARABIC LETTER KIRGHIZ OE ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x06C5 }, + unicodeslot=0xFBE0, + }, + [0xFBE1]={ + category="lo", + description="ARABIC LETTER KIRGHIZ OE FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x06C5 }, + unicodeslot=0xFBE1, + }, + [0xFBE2]={ + category="lo", + description="ARABIC LETTER KIRGHIZ YU ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x06C9 }, + unicodeslot=0xFBE2, + }, + [0xFBE3]={ + category="lo", + description="ARABIC LETTER KIRGHIZ YU FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x06C9 }, + unicodeslot=0xFBE3, + }, + [0xFBE4]={ + category="lo", + description="ARABIC LETTER E ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x06D0 }, + unicodeslot=0xFBE4, + }, + [0xFBE5]={ + category="lo", + description="ARABIC LETTER E FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x06D0 }, + unicodeslot=0xFBE5, + }, + [0xFBE6]={ + category="lo", + description="ARABIC LETTER E INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x06D0 }, + unicodeslot=0xFBE6, + }, + [0xFBE7]={ + category="lo", + description="ARABIC LETTER E MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x06D0 }, + unicodeslot=0xFBE7, + }, + [0xFBE8]={ + category="lo", + description="ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0649 }, + unicodeslot=0xFBE8, + }, + [0xFBE9]={ + category="lo", + description="ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0649 }, + unicodeslot=0xFBE9, + }, + [0xFBEA]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0626, 0x0627 }, + unicodeslot=0xFBEA, + }, + [0xFBEB]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0626, 0x0627 }, + unicodeslot=0xFBEB, + }, + [0xFBEC]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0626, 0x06D5 }, + unicodeslot=0xFBEC, + }, + [0xFBED]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0626, 0x06D5 }, + unicodeslot=0xFBED, + }, + [0xFBEE]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0626, 0x0648 }, + unicodeslot=0xFBEE, + }, + [0xFBEF]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0626, 0x0648 }, + unicodeslot=0xFBEF, + }, + [0xFBF0]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0626, 0x06C7 }, + unicodeslot=0xFBF0, + }, + [0xFBF1]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0626, 0x06C7 }, + unicodeslot=0xFBF1, + }, + [0xFBF2]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0626, 0x06C6 }, + unicodeslot=0xFBF2, + }, + [0xFBF3]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0626, 0x06C6 }, + unicodeslot=0xFBF3, + }, + [0xFBF4]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0626, 0x06C8 }, + unicodeslot=0xFBF4, + }, + [0xFBF5]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0626, 0x06C8 }, + unicodeslot=0xFBF5, + }, + [0xFBF6]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0626, 0x06D0 }, + unicodeslot=0xFBF6, + }, + [0xFBF7]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0626, 0x06D0 }, + unicodeslot=0xFBF7, + }, + [0xFBF8]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0626, 0x06D0 }, + unicodeslot=0xFBF8, + }, + [0xFBF9]={ + category="lo", + description="ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0626, 0x0649 }, + unicodeslot=0xFBF9, + }, + [0xFBFA]={ + category="lo", + description="ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0626, 0x0649 }, + unicodeslot=0xFBFA, + }, + [0xFBFB]={ + category="lo", + description="ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0626, 0x0649 }, + unicodeslot=0xFBFB, + }, + [0xFBFC]={ + category="lo", + description="ARABIC LETTER FARSI YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x06CC }, + unicodeslot=0xFBFC, + }, + [0xFBFD]={ + category="lo", + description="ARABIC LETTER FARSI YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x06CC }, + unicodeslot=0xFBFD, + }, + [0xFBFE]={ + category="lo", + description="ARABIC LETTER FARSI YEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x06CC }, + unicodeslot=0xFBFE, + }, + [0xFBFF]={ + category="lo", + description="ARABIC LETTER FARSI YEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x06CC }, + unicodeslot=0xFBFF, + }, + [0xFC00]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0626, 0x062C }, + unicodeslot=0xFC00, + }, + [0xFC01]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0626, 0x062D }, + unicodeslot=0xFC01, + }, + [0xFC02]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0626, 0x0645 }, + unicodeslot=0xFC02, + }, + [0xFC03]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0626, 0x0649 }, + unicodeslot=0xFC03, + }, + [0xFC04]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0626, 0x064A }, + unicodeslot=0xFC04, + }, + [0xFC05]={ + category="lo", + description="ARABIC LIGATURE BEH WITH JEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0628, 0x062C }, + unicodeslot=0xFC05, + }, + [0xFC06]={ + category="lo", + description="ARABIC LIGATURE BEH WITH HAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0628, 0x062D }, + unicodeslot=0xFC06, + }, + [0xFC07]={ + category="lo", + description="ARABIC LIGATURE BEH WITH KHAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0628, 0x062E }, + unicodeslot=0xFC07, + }, + [0xFC08]={ + category="lo", + description="ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0628, 0x0645 }, + unicodeslot=0xFC08, + }, + [0xFC09]={ + category="lo", + description="ARABIC LIGATURE BEH WITH ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0628, 0x0649 }, + unicodeslot=0xFC09, + }, + [0xFC0A]={ + category="lo", + description="ARABIC LIGATURE BEH WITH YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0628, 0x064A }, + unicodeslot=0xFC0A, + }, + [0xFC0B]={ + category="lo", + description="ARABIC LIGATURE TEH WITH JEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062A, 0x062C }, + unicodeslot=0xFC0B, + }, + [0xFC0C]={ + category="lo", + description="ARABIC LIGATURE TEH WITH HAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062A, 0x062D }, + unicodeslot=0xFC0C, + }, + [0xFC0D]={ + category="lo", + description="ARABIC LIGATURE TEH WITH KHAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062A, 0x062E }, + unicodeslot=0xFC0D, + }, + [0xFC0E]={ + category="lo", + description="ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062A, 0x0645 }, + unicodeslot=0xFC0E, + }, + [0xFC0F]={ + category="lo", + description="ARABIC LIGATURE TEH WITH ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062A, 0x0649 }, + unicodeslot=0xFC0F, + }, + [0xFC10]={ + category="lo", + description="ARABIC LIGATURE TEH WITH YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062A, 0x064A }, + unicodeslot=0xFC10, + }, + [0xFC11]={ + category="lo", + description="ARABIC LIGATURE THEH WITH JEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062B, 0x062C }, + unicodeslot=0xFC11, + }, + [0xFC12]={ + category="lo", + description="ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062B, 0x0645 }, + unicodeslot=0xFC12, + }, + [0xFC13]={ + category="lo", + description="ARABIC LIGATURE THEH WITH ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062B, 0x0649 }, + unicodeslot=0xFC13, + }, + [0xFC14]={ + category="lo", + description="ARABIC LIGATURE THEH WITH YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062B, 0x064A }, + unicodeslot=0xFC14, + }, + [0xFC15]={ + category="lo", + description="ARABIC LIGATURE JEEM WITH HAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062C, 0x062D }, + unicodeslot=0xFC15, + }, + [0xFC16]={ + category="lo", + description="ARABIC LIGATURE JEEM WITH MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062C, 0x0645 }, + unicodeslot=0xFC16, + }, + [0xFC17]={ + category="lo", + description="ARABIC LIGATURE HAH WITH JEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062D, 0x062C }, + unicodeslot=0xFC17, + }, + [0xFC18]={ + category="lo", + description="ARABIC LIGATURE HAH WITH MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062D, 0x0645 }, + unicodeslot=0xFC18, + }, + [0xFC19]={ + category="lo", + description="ARABIC LIGATURE KHAH WITH JEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062E, 0x062C }, + unicodeslot=0xFC19, + }, + [0xFC1A]={ + category="lo", + description="ARABIC LIGATURE KHAH WITH HAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062E, 0x062D }, + unicodeslot=0xFC1A, + }, + [0xFC1B]={ + category="lo", + description="ARABIC LIGATURE KHAH WITH MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062E, 0x0645 }, + unicodeslot=0xFC1B, + }, + [0xFC1C]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH JEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0633, 0x062C }, + unicodeslot=0xFC1C, + }, + [0xFC1D]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH HAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0633, 0x062D }, + unicodeslot=0xFC1D, + }, + [0xFC1E]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH KHAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0633, 0x062E }, + unicodeslot=0xFC1E, + }, + [0xFC1F]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0633, 0x0645 }, + unicodeslot=0xFC1F, + }, + [0xFC20]={ + category="lo", + description="ARABIC LIGATURE SAD WITH HAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0635, 0x062D }, + unicodeslot=0xFC20, + }, + [0xFC21]={ + category="lo", + description="ARABIC LIGATURE SAD WITH MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0635, 0x0645 }, + unicodeslot=0xFC21, + }, + [0xFC22]={ + category="lo", + description="ARABIC LIGATURE DAD WITH JEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0636, 0x062C }, + unicodeslot=0xFC22, + }, + [0xFC23]={ + category="lo", + description="ARABIC LIGATURE DAD WITH HAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0636, 0x062D }, + unicodeslot=0xFC23, + }, + [0xFC24]={ + category="lo", + description="ARABIC LIGATURE DAD WITH KHAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0636, 0x062E }, + unicodeslot=0xFC24, + }, + [0xFC25]={ + category="lo", + description="ARABIC LIGATURE DAD WITH MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0636, 0x0645 }, + unicodeslot=0xFC25, + }, + [0xFC26]={ + category="lo", + description="ARABIC LIGATURE TAH WITH HAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0637, 0x062D }, + unicodeslot=0xFC26, + }, + [0xFC27]={ + category="lo", + description="ARABIC LIGATURE TAH WITH MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0637, 0x0645 }, + unicodeslot=0xFC27, + }, + [0xFC28]={ + category="lo", + description="ARABIC LIGATURE ZAH WITH MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0638, 0x0645 }, + unicodeslot=0xFC28, + }, + [0xFC29]={ + category="lo", + description="ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0639, 0x062C }, + unicodeslot=0xFC29, + }, + [0xFC2A]={ + category="lo", + description="ARABIC LIGATURE AIN WITH MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0639, 0x0645 }, + unicodeslot=0xFC2A, + }, + [0xFC2B]={ + category="lo", + description="ARABIC LIGATURE GHAIN WITH JEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x063A, 0x062C }, + unicodeslot=0xFC2B, + }, + [0xFC2C]={ + category="lo", + description="ARABIC LIGATURE GHAIN WITH MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x063A, 0x0645 }, + unicodeslot=0xFC2C, + }, + [0xFC2D]={ + category="lo", + description="ARABIC LIGATURE FEH WITH JEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0641, 0x062C }, + unicodeslot=0xFC2D, + }, + [0xFC2E]={ + category="lo", + description="ARABIC LIGATURE FEH WITH HAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0641, 0x062D }, + unicodeslot=0xFC2E, + }, + [0xFC2F]={ + category="lo", + description="ARABIC LIGATURE FEH WITH KHAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0641, 0x062E }, + unicodeslot=0xFC2F, + }, + [0xFC30]={ + category="lo", + description="ARABIC LIGATURE FEH WITH MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0641, 0x0645 }, + unicodeslot=0xFC30, + }, + [0xFC31]={ + category="lo", + description="ARABIC LIGATURE FEH WITH ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0641, 0x0649 }, + unicodeslot=0xFC31, + }, + [0xFC32]={ + category="lo", + description="ARABIC LIGATURE FEH WITH YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0641, 0x064A }, + unicodeslot=0xFC32, + }, + [0xFC33]={ + category="lo", + description="ARABIC LIGATURE QAF WITH HAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0642, 0x062D }, + unicodeslot=0xFC33, + }, + [0xFC34]={ + category="lo", + description="ARABIC LIGATURE QAF WITH MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0642, 0x0645 }, + unicodeslot=0xFC34, + }, + [0xFC35]={ + category="lo", + description="ARABIC LIGATURE QAF WITH ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0642, 0x0649 }, + unicodeslot=0xFC35, + }, + [0xFC36]={ + category="lo", + description="ARABIC LIGATURE QAF WITH YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0642, 0x064A }, + unicodeslot=0xFC36, + }, + [0xFC37]={ + category="lo", + description="ARABIC LIGATURE KAF WITH ALEF ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0643, 0x0627 }, + unicodeslot=0xFC37, + }, + [0xFC38]={ + category="lo", + description="ARABIC LIGATURE KAF WITH JEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0643, 0x062C }, + unicodeslot=0xFC38, + }, + [0xFC39]={ + category="lo", + description="ARABIC LIGATURE KAF WITH HAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0643, 0x062D }, + unicodeslot=0xFC39, + }, + [0xFC3A]={ + category="lo", + description="ARABIC LIGATURE KAF WITH KHAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0643, 0x062E }, + unicodeslot=0xFC3A, + }, + [0xFC3B]={ + category="lo", + description="ARABIC LIGATURE KAF WITH LAM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0643, 0x0644 }, + unicodeslot=0xFC3B, + }, + [0xFC3C]={ + category="lo", + description="ARABIC LIGATURE KAF WITH MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0643, 0x0645 }, + unicodeslot=0xFC3C, + }, + [0xFC3D]={ + category="lo", + description="ARABIC LIGATURE KAF WITH ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0643, 0x0649 }, + unicodeslot=0xFC3D, + }, + [0xFC3E]={ + category="lo", + description="ARABIC LIGATURE KAF WITH YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0643, 0x064A }, + unicodeslot=0xFC3E, + }, + [0xFC3F]={ + category="lo", + description="ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0644, 0x062C }, + unicodeslot=0xFC3F, + }, + [0xFC40]={ + category="lo", + description="ARABIC LIGATURE LAM WITH HAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0644, 0x062D }, + unicodeslot=0xFC40, + }, + [0xFC41]={ + category="lo", + description="ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0644, 0x062E }, + unicodeslot=0xFC41, + }, + [0xFC42]={ + category="lo", + description="ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0644, 0x0645 }, + unicodeslot=0xFC42, + }, + [0xFC43]={ + category="lo", + description="ARABIC LIGATURE LAM WITH ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0644, 0x0649 }, + unicodeslot=0xFC43, + }, + [0xFC44]={ + category="lo", + description="ARABIC LIGATURE LAM WITH YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0644, 0x064A }, + unicodeslot=0xFC44, + }, + [0xFC45]={ + category="lo", + description="ARABIC LIGATURE MEEM WITH JEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0645, 0x062C }, + unicodeslot=0xFC45, + }, + [0xFC46]={ + category="lo", + description="ARABIC LIGATURE MEEM WITH HAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0645, 0x062D }, + unicodeslot=0xFC46, + }, + [0xFC47]={ + category="lo", + description="ARABIC LIGATURE MEEM WITH KHAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0645, 0x062E }, + unicodeslot=0xFC47, + }, + [0xFC48]={ + category="lo", + description="ARABIC LIGATURE MEEM WITH MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0645, 0x0645 }, + unicodeslot=0xFC48, + }, + [0xFC49]={ + category="lo", + description="ARABIC LIGATURE MEEM WITH ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0645, 0x0649 }, + unicodeslot=0xFC49, + }, + [0xFC4A]={ + category="lo", + description="ARABIC LIGATURE MEEM WITH YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0645, 0x064A }, + unicodeslot=0xFC4A, + }, + [0xFC4B]={ + category="lo", + description="ARABIC LIGATURE NOON WITH JEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0646, 0x062C }, + unicodeslot=0xFC4B, + }, + [0xFC4C]={ + category="lo", + description="ARABIC LIGATURE NOON WITH HAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0646, 0x062D }, + unicodeslot=0xFC4C, + }, + [0xFC4D]={ + category="lo", + description="ARABIC LIGATURE NOON WITH KHAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0646, 0x062E }, + unicodeslot=0xFC4D, + }, + [0xFC4E]={ + category="lo", + description="ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0646, 0x0645 }, + unicodeslot=0xFC4E, + }, + [0xFC4F]={ + category="lo", + description="ARABIC LIGATURE NOON WITH ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0646, 0x0649 }, + unicodeslot=0xFC4F, + }, + [0xFC50]={ + category="lo", + description="ARABIC LIGATURE NOON WITH YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0646, 0x064A }, + unicodeslot=0xFC50, + }, + [0xFC51]={ + category="lo", + description="ARABIC LIGATURE HEH WITH JEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0647, 0x062C }, + unicodeslot=0xFC51, + }, + [0xFC52]={ + category="lo", + description="ARABIC LIGATURE HEH WITH MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0647, 0x0645 }, + unicodeslot=0xFC52, + }, + [0xFC53]={ + category="lo", + description="ARABIC LIGATURE HEH WITH ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0647, 0x0649 }, + unicodeslot=0xFC53, + }, + [0xFC54]={ + category="lo", + description="ARABIC LIGATURE HEH WITH YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0647, 0x064A }, + unicodeslot=0xFC54, + }, + [0xFC55]={ + category="lo", + description="ARABIC LIGATURE YEH WITH JEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x064A, 0x062C }, + unicodeslot=0xFC55, + }, + [0xFC56]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x064A, 0x062D }, + unicodeslot=0xFC56, + }, + [0xFC57]={ + category="lo", + description="ARABIC LIGATURE YEH WITH KHAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x064A, 0x062E }, + unicodeslot=0xFC57, + }, + [0xFC58]={ + category="lo", + description="ARABIC LIGATURE YEH WITH MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x064A, 0x0645 }, + unicodeslot=0xFC58, + }, + [0xFC59]={ + category="lo", + description="ARABIC LIGATURE YEH WITH ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x064A, 0x0649 }, + unicodeslot=0xFC59, + }, + [0xFC5A]={ + category="lo", + description="ARABIC LIGATURE YEH WITH YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x064A, 0x064A }, + unicodeslot=0xFC5A, + }, + [0xFC5B]={ + category="lo", + description="ARABIC LIGATURE THAL WITH SUPERSCRIPT ALEF ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0630, 0x0670 }, + unicodeslot=0xFC5B, + }, + [0xFC5C]={ + category="lo", + description="ARABIC LIGATURE REH WITH SUPERSCRIPT ALEF ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0631, 0x0670 }, + unicodeslot=0xFC5C, + }, + [0xFC5D]={ + category="lo", + description="ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0649, 0x0670 }, + unicodeslot=0xFC5D, + }, + [0xFC5E]={ + category="lo", + description="ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0020, 0x064C, 0x0651 }, + unicodeslot=0xFC5E, + }, + [0xFC5F]={ + category="lo", + description="ARABIC LIGATURE SHADDA WITH KASRATAN ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0020, 0x064D, 0x0651 }, + unicodeslot=0xFC5F, + }, + [0xFC60]={ + category="lo", + description="ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0020, 0x064E, 0x0651 }, + unicodeslot=0xFC60, + }, + [0xFC61]={ + category="lo", + description="ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0020, 0x064F, 0x0651 }, + unicodeslot=0xFC61, + }, + [0xFC62]={ + category="lo", + description="ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0020, 0x0650, 0x0651 }, + unicodeslot=0xFC62, + }, + [0xFC63]={ + category="lo", + description="ARABIC LIGATURE SHADDA WITH SUPERSCRIPT ALEF ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0020, 0x0651, 0x0670 }, + unicodeslot=0xFC63, + }, + [0xFC64]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH REH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0626, 0x0631 }, + unicodeslot=0xFC64, + }, + [0xFC65]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ZAIN FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0626, 0x0632 }, + unicodeslot=0xFC65, + }, + [0xFC66]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0626, 0x0645 }, + unicodeslot=0xFC66, + }, + [0xFC67]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH NOON FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0626, 0x0646 }, + unicodeslot=0xFC67, + }, + [0xFC68]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0626, 0x0649 }, + unicodeslot=0xFC68, + }, + [0xFC69]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0626, 0x064A }, + unicodeslot=0xFC69, + }, + [0xFC6A]={ + category="lo", + description="ARABIC LIGATURE BEH WITH REH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0628, 0x0631 }, + unicodeslot=0xFC6A, + }, + [0xFC6B]={ + category="lo", + description="ARABIC LIGATURE BEH WITH ZAIN FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0628, 0x0632 }, + unicodeslot=0xFC6B, + }, + [0xFC6C]={ + category="lo", + description="ARABIC LIGATURE BEH WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0628, 0x0645 }, + unicodeslot=0xFC6C, + }, + [0xFC6D]={ + category="lo", + description="ARABIC LIGATURE BEH WITH NOON FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0628, 0x0646 }, + unicodeslot=0xFC6D, + }, + [0xFC6E]={ + category="lo", + description="ARABIC LIGATURE BEH WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0628, 0x0649 }, + unicodeslot=0xFC6E, + }, + [0xFC6F]={ + category="lo", + description="ARABIC LIGATURE BEH WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0628, 0x064A }, + unicodeslot=0xFC6F, + }, + [0xFC70]={ + category="lo", + description="ARABIC LIGATURE TEH WITH REH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062A, 0x0631 }, + unicodeslot=0xFC70, + }, + [0xFC71]={ + category="lo", + description="ARABIC LIGATURE TEH WITH ZAIN FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062A, 0x0632 }, + unicodeslot=0xFC71, + }, + [0xFC72]={ + category="lo", + description="ARABIC LIGATURE TEH WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062A, 0x0645 }, + unicodeslot=0xFC72, + }, + [0xFC73]={ + category="lo", + description="ARABIC LIGATURE TEH WITH NOON FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062A, 0x0646 }, + unicodeslot=0xFC73, + }, + [0xFC74]={ + category="lo", + description="ARABIC LIGATURE TEH WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062A, 0x0649 }, + unicodeslot=0xFC74, + }, + [0xFC75]={ + category="lo", + description="ARABIC LIGATURE TEH WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062A, 0x064A }, + unicodeslot=0xFC75, + }, + [0xFC76]={ + category="lo", + description="ARABIC LIGATURE THEH WITH REH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062B, 0x0631 }, + unicodeslot=0xFC76, + }, + [0xFC77]={ + category="lo", + description="ARABIC LIGATURE THEH WITH ZAIN FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062B, 0x0632 }, + unicodeslot=0xFC77, + }, + [0xFC78]={ + category="lo", + description="ARABIC LIGATURE THEH WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062B, 0x0645 }, + unicodeslot=0xFC78, + }, + [0xFC79]={ + category="lo", + description="ARABIC LIGATURE THEH WITH NOON FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062B, 0x0646 }, + unicodeslot=0xFC79, + }, + [0xFC7A]={ + category="lo", + description="ARABIC LIGATURE THEH WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062B, 0x0649 }, + unicodeslot=0xFC7A, + }, + [0xFC7B]={ + category="lo", + description="ARABIC LIGATURE THEH WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062B, 0x064A }, + unicodeslot=0xFC7B, + }, + [0xFC7C]={ + category="lo", + description="ARABIC LIGATURE FEH WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0641, 0x0649 }, + unicodeslot=0xFC7C, + }, + [0xFC7D]={ + category="lo", + description="ARABIC LIGATURE FEH WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0641, 0x064A }, + unicodeslot=0xFC7D, + }, + [0xFC7E]={ + category="lo", + description="ARABIC LIGATURE QAF WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0642, 0x0649 }, + unicodeslot=0xFC7E, + }, + [0xFC7F]={ + category="lo", + description="ARABIC LIGATURE QAF WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0642, 0x064A }, + unicodeslot=0xFC7F, + }, + [0xFC80]={ + category="lo", + description="ARABIC LIGATURE KAF WITH ALEF FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0643, 0x0627 }, + unicodeslot=0xFC80, + }, + [0xFC81]={ + category="lo", + description="ARABIC LIGATURE KAF WITH LAM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0643, 0x0644 }, + unicodeslot=0xFC81, + }, + [0xFC82]={ + category="lo", + description="ARABIC LIGATURE KAF WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0643, 0x0645 }, + unicodeslot=0xFC82, + }, + [0xFC83]={ + category="lo", + description="ARABIC LIGATURE KAF WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0643, 0x0649 }, + unicodeslot=0xFC83, + }, + [0xFC84]={ + category="lo", + description="ARABIC LIGATURE KAF WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0643, 0x064A }, + unicodeslot=0xFC84, + }, + [0xFC85]={ + category="lo", + description="ARABIC LIGATURE LAM WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0644, 0x0645 }, + unicodeslot=0xFC85, + }, + [0xFC86]={ + category="lo", + description="ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0644, 0x0649 }, + unicodeslot=0xFC86, + }, + [0xFC87]={ + category="lo", + description="ARABIC LIGATURE LAM WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0644, 0x064A }, + unicodeslot=0xFC87, + }, + [0xFC88]={ + category="lo", + description="ARABIC LIGATURE MEEM WITH ALEF FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0645, 0x0627 }, + unicodeslot=0xFC88, + }, + [0xFC89]={ + category="lo", + description="ARABIC LIGATURE MEEM WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0645, 0x0645 }, + unicodeslot=0xFC89, + }, + [0xFC8A]={ + category="lo", + description="ARABIC LIGATURE NOON WITH REH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0646, 0x0631 }, + unicodeslot=0xFC8A, + }, + [0xFC8B]={ + category="lo", + description="ARABIC LIGATURE NOON WITH ZAIN FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0646, 0x0632 }, + unicodeslot=0xFC8B, + }, + [0xFC8C]={ + category="lo", + description="ARABIC LIGATURE NOON WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0646, 0x0645 }, + unicodeslot=0xFC8C, + }, + [0xFC8D]={ + category="lo", + description="ARABIC LIGATURE NOON WITH NOON FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0646, 0x0646 }, + unicodeslot=0xFC8D, + }, + [0xFC8E]={ + category="lo", + description="ARABIC LIGATURE NOON WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0646, 0x0649 }, + unicodeslot=0xFC8E, + }, + [0xFC8F]={ + category="lo", + description="ARABIC LIGATURE NOON WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0646, 0x064A }, + unicodeslot=0xFC8F, + }, + [0xFC90]={ + category="lo", + description="ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0649, 0x0670 }, + unicodeslot=0xFC90, + }, + [0xFC91]={ + category="lo", + description="ARABIC LIGATURE YEH WITH REH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x064A, 0x0631 }, + unicodeslot=0xFC91, + }, + [0xFC92]={ + category="lo", + description="ARABIC LIGATURE YEH WITH ZAIN FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x064A, 0x0632 }, + unicodeslot=0xFC92, + }, + [0xFC93]={ + category="lo", + description="ARABIC LIGATURE YEH WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x064A, 0x0645 }, + unicodeslot=0xFC93, + }, + [0xFC94]={ + category="lo", + description="ARABIC LIGATURE YEH WITH NOON FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x064A, 0x0646 }, + unicodeslot=0xFC94, + }, + [0xFC95]={ + category="lo", + description="ARABIC LIGATURE YEH WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x064A, 0x0649 }, + unicodeslot=0xFC95, + }, + [0xFC96]={ + category="lo", + description="ARABIC LIGATURE YEH WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x064A, 0x064A }, + unicodeslot=0xFC96, + }, + [0xFC97]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0626, 0x062C }, + unicodeslot=0xFC97, + }, + [0xFC98]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0626, 0x062D }, + unicodeslot=0xFC98, + }, + [0xFC99]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH KHAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0626, 0x062E }, + unicodeslot=0xFC99, + }, + [0xFC9A]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0626, 0x0645 }, + unicodeslot=0xFC9A, + }, + [0xFC9B]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0626, 0x0647 }, + unicodeslot=0xFC9B, + }, + [0xFC9C]={ + category="lo", + description="ARABIC LIGATURE BEH WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0628, 0x062C }, + unicodeslot=0xFC9C, + }, + [0xFC9D]={ + category="lo", + description="ARABIC LIGATURE BEH WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0628, 0x062D }, + unicodeslot=0xFC9D, + }, + [0xFC9E]={ + category="lo", + description="ARABIC LIGATURE BEH WITH KHAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0628, 0x062E }, + unicodeslot=0xFC9E, + }, + [0xFC9F]={ + category="lo", + description="ARABIC LIGATURE BEH WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0628, 0x0645 }, + unicodeslot=0xFC9F, + }, + [0xFCA0]={ + category="lo", + description="ARABIC LIGATURE BEH WITH HEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0628, 0x0647 }, + unicodeslot=0xFCA0, + }, + [0xFCA1]={ + category="lo", + description="ARABIC LIGATURE TEH WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062A, 0x062C }, + unicodeslot=0xFCA1, + }, + [0xFCA2]={ + category="lo", + description="ARABIC LIGATURE TEH WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062A, 0x062D }, + unicodeslot=0xFCA2, + }, + [0xFCA3]={ + category="lo", + description="ARABIC LIGATURE TEH WITH KHAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062A, 0x062E }, + unicodeslot=0xFCA3, + }, + [0xFCA4]={ + category="lo", + description="ARABIC LIGATURE TEH WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062A, 0x0645 }, + unicodeslot=0xFCA4, + }, + [0xFCA5]={ + category="lo", + description="ARABIC LIGATURE TEH WITH HEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062A, 0x0647 }, + unicodeslot=0xFCA5, + }, + [0xFCA6]={ + category="lo", + description="ARABIC LIGATURE THEH WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062B, 0x0645 }, + unicodeslot=0xFCA6, + }, + [0xFCA7]={ + category="lo", + description="ARABIC LIGATURE JEEM WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062C, 0x062D }, + unicodeslot=0xFCA7, + }, + [0xFCA8]={ + category="lo", + description="ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062C, 0x0645 }, + unicodeslot=0xFCA8, + }, + [0xFCA9]={ + category="lo", + description="ARABIC LIGATURE HAH WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062D, 0x062C }, + unicodeslot=0xFCA9, + }, + [0xFCAA]={ + category="lo", + description="ARABIC LIGATURE HAH WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062D, 0x0645 }, + unicodeslot=0xFCAA, + }, + [0xFCAB]={ + category="lo", + description="ARABIC LIGATURE KHAH WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062E, 0x062C }, + unicodeslot=0xFCAB, + }, + [0xFCAC]={ + category="lo", + description="ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062E, 0x0645 }, + unicodeslot=0xFCAC, + }, + [0xFCAD]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0633, 0x062C }, + unicodeslot=0xFCAD, + }, + [0xFCAE]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0633, 0x062D }, + unicodeslot=0xFCAE, + }, + [0xFCAF]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH KHAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0633, 0x062E }, + unicodeslot=0xFCAF, + }, + [0xFCB0]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0633, 0x0645 }, + unicodeslot=0xFCB0, + }, + [0xFCB1]={ + category="lo", + description="ARABIC LIGATURE SAD WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0635, 0x062D }, + unicodeslot=0xFCB1, + }, + [0xFCB2]={ + category="lo", + description="ARABIC LIGATURE SAD WITH KHAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0635, 0x062E }, + unicodeslot=0xFCB2, + }, + [0xFCB3]={ + category="lo", + description="ARABIC LIGATURE SAD WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0635, 0x0645 }, + unicodeslot=0xFCB3, + }, + [0xFCB4]={ + category="lo", + description="ARABIC LIGATURE DAD WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0636, 0x062C }, + unicodeslot=0xFCB4, + }, + [0xFCB5]={ + category="lo", + description="ARABIC LIGATURE DAD WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0636, 0x062D }, + unicodeslot=0xFCB5, + }, + [0xFCB6]={ + category="lo", + description="ARABIC LIGATURE DAD WITH KHAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0636, 0x062E }, + unicodeslot=0xFCB6, + }, + [0xFCB7]={ + category="lo", + description="ARABIC LIGATURE DAD WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0636, 0x0645 }, + unicodeslot=0xFCB7, + }, + [0xFCB8]={ + category="lo", + description="ARABIC LIGATURE TAH WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0637, 0x062D }, + unicodeslot=0xFCB8, + }, + [0xFCB9]={ + category="lo", + description="ARABIC LIGATURE ZAH WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0638, 0x0645 }, + unicodeslot=0xFCB9, + }, + [0xFCBA]={ + category="lo", + description="ARABIC LIGATURE AIN WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0639, 0x062C }, + unicodeslot=0xFCBA, + }, + [0xFCBB]={ + category="lo", + description="ARABIC LIGATURE AIN WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0639, 0x0645 }, + unicodeslot=0xFCBB, + }, + [0xFCBC]={ + category="lo", + description="ARABIC LIGATURE GHAIN WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x063A, 0x062C }, + unicodeslot=0xFCBC, + }, + [0xFCBD]={ + category="lo", + description="ARABIC LIGATURE GHAIN WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x063A, 0x0645 }, + unicodeslot=0xFCBD, + }, + [0xFCBE]={ + category="lo", + description="ARABIC LIGATURE FEH WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0641, 0x062C }, + unicodeslot=0xFCBE, + }, + [0xFCBF]={ + category="lo", + description="ARABIC LIGATURE FEH WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0641, 0x062D }, + unicodeslot=0xFCBF, + }, + [0xFCC0]={ + category="lo", + description="ARABIC LIGATURE FEH WITH KHAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0641, 0x062E }, + unicodeslot=0xFCC0, + }, + [0xFCC1]={ + category="lo", + description="ARABIC LIGATURE FEH WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0641, 0x0645 }, + unicodeslot=0xFCC1, + }, + [0xFCC2]={ + category="lo", + description="ARABIC LIGATURE QAF WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0642, 0x062D }, + unicodeslot=0xFCC2, + }, + [0xFCC3]={ + category="lo", + description="ARABIC LIGATURE QAF WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0642, 0x0645 }, + unicodeslot=0xFCC3, + }, + [0xFCC4]={ + category="lo", + description="ARABIC LIGATURE KAF WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0643, 0x062C }, + unicodeslot=0xFCC4, + }, + [0xFCC5]={ + category="lo", + description="ARABIC LIGATURE KAF WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0643, 0x062D }, + unicodeslot=0xFCC5, + }, + [0xFCC6]={ + category="lo", + description="ARABIC LIGATURE KAF WITH KHAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0643, 0x062E }, + unicodeslot=0xFCC6, + }, + [0xFCC7]={ + category="lo", + description="ARABIC LIGATURE KAF WITH LAM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0643, 0x0644 }, + unicodeslot=0xFCC7, + }, + [0xFCC8]={ + category="lo", + description="ARABIC LIGATURE KAF WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0643, 0x0645 }, + unicodeslot=0xFCC8, + }, + [0xFCC9]={ + category="lo", + description="ARABIC LIGATURE LAM WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0644, 0x062C }, + unicodeslot=0xFCC9, + }, + [0xFCCA]={ + category="lo", + description="ARABIC LIGATURE LAM WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0644, 0x062D }, + unicodeslot=0xFCCA, + }, + [0xFCCB]={ + category="lo", + description="ARABIC LIGATURE LAM WITH KHAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0644, 0x062E }, + unicodeslot=0xFCCB, + }, + [0xFCCC]={ + category="lo", + description="ARABIC LIGATURE LAM WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0644, 0x0645 }, + unicodeslot=0xFCCC, + }, + [0xFCCD]={ + category="lo", + description="ARABIC LIGATURE LAM WITH HEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0644, 0x0647 }, + unicodeslot=0xFCCD, + }, + [0xFCCE]={ + category="lo", + description="ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0645, 0x062C }, + unicodeslot=0xFCCE, + }, + [0xFCCF]={ + category="lo", + description="ARABIC LIGATURE MEEM WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0645, 0x062D }, + unicodeslot=0xFCCF, + }, + [0xFCD0]={ + category="lo", + description="ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0645, 0x062E }, + unicodeslot=0xFCD0, + }, + [0xFCD1]={ + category="lo", + description="ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0645, 0x0645 }, + unicodeslot=0xFCD1, + }, + [0xFCD2]={ + category="lo", + description="ARABIC LIGATURE NOON WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0646, 0x062C }, + unicodeslot=0xFCD2, + }, + [0xFCD3]={ + category="lo", + description="ARABIC LIGATURE NOON WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0646, 0x062D }, + unicodeslot=0xFCD3, + }, + [0xFCD4]={ + category="lo", + description="ARABIC LIGATURE NOON WITH KHAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0646, 0x062E }, + unicodeslot=0xFCD4, + }, + [0xFCD5]={ + category="lo", + description="ARABIC LIGATURE NOON WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0646, 0x0645 }, + unicodeslot=0xFCD5, + }, + [0xFCD6]={ + category="lo", + description="ARABIC LIGATURE NOON WITH HEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0646, 0x0647 }, + unicodeslot=0xFCD6, + }, + [0xFCD7]={ + category="lo", + description="ARABIC LIGATURE HEH WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0647, 0x062C }, + unicodeslot=0xFCD7, + }, + [0xFCD8]={ + category="lo", + description="ARABIC LIGATURE HEH WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0647, 0x0645 }, + unicodeslot=0xFCD8, + }, + [0xFCD9]={ + category="lo", + description="ARABIC LIGATURE HEH WITH SUPERSCRIPT ALEF INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0647, 0x0670 }, + unicodeslot=0xFCD9, + }, + [0xFCDA]={ + category="lo", + description="ARABIC LIGATURE YEH WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x064A, 0x062C }, + unicodeslot=0xFCDA, + }, + [0xFCDB]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x064A, 0x062D }, + unicodeslot=0xFCDB, + }, + [0xFCDC]={ + category="lo", + description="ARABIC LIGATURE YEH WITH KHAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x064A, 0x062E }, + unicodeslot=0xFCDC, + }, + [0xFCDD]={ + category="lo", + description="ARABIC LIGATURE YEH WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x064A, 0x0645 }, + unicodeslot=0xFCDD, + }, + [0xFCDE]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x064A, 0x0647 }, + unicodeslot=0xFCDE, + }, + [0xFCDF]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0626, 0x0645 }, + unicodeslot=0xFCDF, + }, + [0xFCE0]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0626, 0x0647 }, + unicodeslot=0xFCE0, + }, + [0xFCE1]={ + category="lo", + description="ARABIC LIGATURE BEH WITH MEEM MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0628, 0x0645 }, + unicodeslot=0xFCE1, + }, + [0xFCE2]={ + category="lo", + description="ARABIC LIGATURE BEH WITH HEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0628, 0x0647 }, + unicodeslot=0xFCE2, + }, + [0xFCE3]={ + category="lo", + description="ARABIC LIGATURE TEH WITH MEEM MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x062A, 0x0645 }, + unicodeslot=0xFCE3, + }, + [0xFCE4]={ + category="lo", + description="ARABIC LIGATURE TEH WITH HEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x062A, 0x0647 }, + unicodeslot=0xFCE4, + }, + [0xFCE5]={ + category="lo", + description="ARABIC LIGATURE THEH WITH MEEM MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x062B, 0x0645 }, + unicodeslot=0xFCE5, + }, + [0xFCE6]={ + category="lo", + description="ARABIC LIGATURE THEH WITH HEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x062B, 0x0647 }, + unicodeslot=0xFCE6, + }, + [0xFCE7]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH MEEM MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0633, 0x0645 }, + unicodeslot=0xFCE7, + }, + [0xFCE8]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH HEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0633, 0x0647 }, + unicodeslot=0xFCE8, + }, + [0xFCE9]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH MEEM MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0634, 0x0645 }, + unicodeslot=0xFCE9, + }, + [0xFCEA]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH HEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0634, 0x0647 }, + unicodeslot=0xFCEA, + }, + [0xFCEB]={ + category="lo", + description="ARABIC LIGATURE KAF WITH LAM MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0643, 0x0644 }, + unicodeslot=0xFCEB, + }, + [0xFCEC]={ + category="lo", + description="ARABIC LIGATURE KAF WITH MEEM MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0643, 0x0645 }, + unicodeslot=0xFCEC, + }, + [0xFCED]={ + category="lo", + description="ARABIC LIGATURE LAM WITH MEEM MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0644, 0x0645 }, + unicodeslot=0xFCED, + }, + [0xFCEE]={ + category="lo", + description="ARABIC LIGATURE NOON WITH MEEM MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0646, 0x0645 }, + unicodeslot=0xFCEE, + }, + [0xFCEF]={ + category="lo", + description="ARABIC LIGATURE NOON WITH HEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0646, 0x0647 }, + unicodeslot=0xFCEF, + }, + [0xFCF0]={ + category="lo", + description="ARABIC LIGATURE YEH WITH MEEM MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x064A, 0x0645 }, + unicodeslot=0xFCF0, + }, + [0xFCF1]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x064A, 0x0647 }, + unicodeslot=0xFCF1, + }, + [0xFCF2]={ + category="lo", + description="ARABIC LIGATURE SHADDA WITH FATHA MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0640, 0x064E, 0x0651 }, + unicodeslot=0xFCF2, + }, + [0xFCF3]={ + category="lo", + description="ARABIC LIGATURE SHADDA WITH DAMMA MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0640, 0x064F, 0x0651 }, + unicodeslot=0xFCF3, + }, + [0xFCF4]={ + category="lo", + description="ARABIC LIGATURE SHADDA WITH KASRA MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0640, 0x0650, 0x0651 }, + unicodeslot=0xFCF4, + }, + [0xFCF5]={ + category="lo", + description="ARABIC LIGATURE TAH WITH ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0637, 0x0649 }, + unicodeslot=0xFCF5, + }, + [0xFCF6]={ + category="lo", + description="ARABIC LIGATURE TAH WITH YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0637, 0x064A }, + unicodeslot=0xFCF6, + }, + [0xFCF7]={ + category="lo", + description="ARABIC LIGATURE AIN WITH ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0639, 0x0649 }, + unicodeslot=0xFCF7, + }, + [0xFCF8]={ + category="lo", + description="ARABIC LIGATURE AIN WITH YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0639, 0x064A }, + unicodeslot=0xFCF8, + }, + [0xFCF9]={ + category="lo", + description="ARABIC LIGATURE GHAIN WITH ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x063A, 0x0649 }, + unicodeslot=0xFCF9, + }, + [0xFCFA]={ + category="lo", + description="ARABIC LIGATURE GHAIN WITH YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x063A, 0x064A }, + unicodeslot=0xFCFA, + }, + [0xFCFB]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0633, 0x0649 }, + unicodeslot=0xFCFB, + }, + [0xFCFC]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0633, 0x064A }, + unicodeslot=0xFCFC, + }, + [0xFCFD]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0634, 0x0649 }, + unicodeslot=0xFCFD, + }, + [0xFCFE]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0634, 0x064A }, + unicodeslot=0xFCFE, + }, + [0xFCFF]={ + category="lo", + description="ARABIC LIGATURE HAH WITH ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062D, 0x0649 }, + unicodeslot=0xFCFF, + }, + [0xFD00]={ + category="lo", + description="ARABIC LIGATURE HAH WITH YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062D, 0x064A }, + unicodeslot=0xFD00, + }, + [0xFD01]={ + category="lo", + description="ARABIC LIGATURE JEEM WITH ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062C, 0x0649 }, + unicodeslot=0xFD01, + }, + [0xFD02]={ + category="lo", + description="ARABIC LIGATURE JEEM WITH YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062C, 0x064A }, + unicodeslot=0xFD02, + }, + [0xFD03]={ + category="lo", + description="ARABIC LIGATURE KHAH WITH ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062E, 0x0649 }, + unicodeslot=0xFD03, + }, + [0xFD04]={ + category="lo", + description="ARABIC LIGATURE KHAH WITH YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062E, 0x064A }, + unicodeslot=0xFD04, + }, + [0xFD05]={ + category="lo", + description="ARABIC LIGATURE SAD WITH ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0635, 0x0649 }, + unicodeslot=0xFD05, + }, + [0xFD06]={ + category="lo", + description="ARABIC LIGATURE SAD WITH YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0635, 0x064A }, + unicodeslot=0xFD06, + }, + [0xFD07]={ + category="lo", + description="ARABIC LIGATURE DAD WITH ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0636, 0x0649 }, + unicodeslot=0xFD07, + }, + [0xFD08]={ + category="lo", + description="ARABIC LIGATURE DAD WITH YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0636, 0x064A }, + unicodeslot=0xFD08, + }, + [0xFD09]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH JEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0634, 0x062C }, + unicodeslot=0xFD09, + }, + [0xFD0A]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH HAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0634, 0x062D }, + unicodeslot=0xFD0A, + }, + [0xFD0B]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH KHAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0634, 0x062E }, + unicodeslot=0xFD0B, + }, + [0xFD0C]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0634, 0x0645 }, + unicodeslot=0xFD0C, + }, + [0xFD0D]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH REH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0634, 0x0631 }, + unicodeslot=0xFD0D, + }, + [0xFD0E]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH REH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0633, 0x0631 }, + unicodeslot=0xFD0E, + }, + [0xFD0F]={ + category="lo", + description="ARABIC LIGATURE SAD WITH REH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0635, 0x0631 }, + unicodeslot=0xFD0F, + }, + [0xFD10]={ + category="lo", + description="ARABIC LIGATURE DAD WITH REH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0636, 0x0631 }, + unicodeslot=0xFD10, + }, + [0xFD11]={ + category="lo", + description="ARABIC LIGATURE TAH WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0637, 0x0649 }, + unicodeslot=0xFD11, + }, + [0xFD12]={ + category="lo", + description="ARABIC LIGATURE TAH WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0637, 0x064A }, + unicodeslot=0xFD12, + }, + [0xFD13]={ + category="lo", + description="ARABIC LIGATURE AIN WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0639, 0x0649 }, + unicodeslot=0xFD13, + }, + [0xFD14]={ + category="lo", + description="ARABIC LIGATURE AIN WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0639, 0x064A }, + unicodeslot=0xFD14, + }, + [0xFD15]={ + category="lo", + description="ARABIC LIGATURE GHAIN WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x063A, 0x0649 }, + unicodeslot=0xFD15, + }, + [0xFD16]={ + category="lo", + description="ARABIC LIGATURE GHAIN WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x063A, 0x064A }, + unicodeslot=0xFD16, + }, + [0xFD17]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0633, 0x0649 }, + unicodeslot=0xFD17, + }, + [0xFD18]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0633, 0x064A }, + unicodeslot=0xFD18, + }, + [0xFD19]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0634, 0x0649 }, + unicodeslot=0xFD19, + }, + [0xFD1A]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0634, 0x064A }, + unicodeslot=0xFD1A, + }, + [0xFD1B]={ + category="lo", + description="ARABIC LIGATURE HAH WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062D, 0x0649 }, + unicodeslot=0xFD1B, + }, + [0xFD1C]={ + category="lo", + description="ARABIC LIGATURE HAH WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062D, 0x064A }, + unicodeslot=0xFD1C, + }, + [0xFD1D]={ + category="lo", + description="ARABIC LIGATURE JEEM WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062C, 0x0649 }, + unicodeslot=0xFD1D, + }, + [0xFD1E]={ + category="lo", + description="ARABIC LIGATURE JEEM WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062C, 0x064A }, + unicodeslot=0xFD1E, + }, + [0xFD1F]={ + category="lo", + description="ARABIC LIGATURE KHAH WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062E, 0x0649 }, + unicodeslot=0xFD1F, + }, + [0xFD20]={ + category="lo", + description="ARABIC LIGATURE KHAH WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062E, 0x064A }, + unicodeslot=0xFD20, + }, + [0xFD21]={ + category="lo", + description="ARABIC LIGATURE SAD WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0635, 0x0649 }, + unicodeslot=0xFD21, + }, + [0xFD22]={ + category="lo", + description="ARABIC LIGATURE SAD WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0635, 0x064A }, + unicodeslot=0xFD22, + }, + [0xFD23]={ + category="lo", + description="ARABIC LIGATURE DAD WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0636, 0x0649 }, + unicodeslot=0xFD23, + }, + [0xFD24]={ + category="lo", + description="ARABIC LIGATURE DAD WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0636, 0x064A }, + unicodeslot=0xFD24, + }, + [0xFD25]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH JEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0634, 0x062C }, + unicodeslot=0xFD25, + }, + [0xFD26]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH HAH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0634, 0x062D }, + unicodeslot=0xFD26, + }, + [0xFD27]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH KHAH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0634, 0x062E }, + unicodeslot=0xFD27, + }, + [0xFD28]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0634, 0x0645 }, + unicodeslot=0xFD28, + }, + [0xFD29]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH REH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0634, 0x0631 }, + unicodeslot=0xFD29, + }, + [0xFD2A]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH REH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0633, 0x0631 }, + unicodeslot=0xFD2A, + }, + [0xFD2B]={ + category="lo", + description="ARABIC LIGATURE SAD WITH REH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0635, 0x0631 }, + unicodeslot=0xFD2B, + }, + [0xFD2C]={ + category="lo", + description="ARABIC LIGATURE DAD WITH REH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0636, 0x0631 }, + unicodeslot=0xFD2C, + }, + [0xFD2D]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0634, 0x062C }, + unicodeslot=0xFD2D, + }, + [0xFD2E]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0634, 0x062D }, + unicodeslot=0xFD2E, + }, + [0xFD2F]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH KHAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0634, 0x062E }, + unicodeslot=0xFD2F, + }, + [0xFD30]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0634, 0x0645 }, + unicodeslot=0xFD30, + }, + [0xFD31]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH HEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0633, 0x0647 }, + unicodeslot=0xFD31, + }, + [0xFD32]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH HEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0634, 0x0647 }, + unicodeslot=0xFD32, + }, + [0xFD33]={ + category="lo", + description="ARABIC LIGATURE TAH WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0637, 0x0645 }, + unicodeslot=0xFD33, + }, + [0xFD34]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH JEEM MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0633, 0x062C }, + unicodeslot=0xFD34, + }, + [0xFD35]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH HAH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0633, 0x062D }, + unicodeslot=0xFD35, + }, + [0xFD36]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH KHAH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0633, 0x062E }, + unicodeslot=0xFD36, + }, + [0xFD37]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH JEEM MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0634, 0x062C }, + unicodeslot=0xFD37, + }, + [0xFD38]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH HAH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0634, 0x062D }, + unicodeslot=0xFD38, + }, + [0xFD39]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH KHAH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0634, 0x062E }, + unicodeslot=0xFD39, + }, + [0xFD3A]={ + category="lo", + description="ARABIC LIGATURE TAH WITH MEEM MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0637, 0x0645 }, + unicodeslot=0xFD3A, + }, + [0xFD3B]={ + category="lo", + description="ARABIC LIGATURE ZAH WITH MEEM MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0638, 0x0645 }, + unicodeslot=0xFD3B, + }, + [0xFD3C]={ + category="lo", + description="ARABIC LIGATURE ALEF WITH FATHATAN FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0627, 0x064B }, + unicodeslot=0xFD3C, + }, + [0xFD3D]={ + category="lo", + description="ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0627, 0x064B }, + unicodeslot=0xFD3D, + }, + [0xFD3E]={ + category="ps", + description="ORNATE LEFT PARENTHESIS", + direction="on", + linebreak="op", + unicodeslot=0xFD3E, + }, + [0xFD3F]={ + category="pe", + description="ORNATE RIGHT PARENTHESIS", + direction="on", + linebreak="cl", + unicodeslot=0xFD3F, + }, + [0xFD50]={ + category="lo", + description="ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062A, 0x062C, 0x0645 }, + unicodeslot=0xFD50, + }, + [0xFD51]={ + category="lo", + description="ARABIC LIGATURE TEH WITH HAH WITH JEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062A, 0x062D, 0x062C }, + unicodeslot=0xFD51, + }, + [0xFD52]={ + category="lo", + description="ARABIC LIGATURE TEH WITH HAH WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062A, 0x062D, 0x062C }, + unicodeslot=0xFD52, + }, + [0xFD53]={ + category="lo", + description="ARABIC LIGATURE TEH WITH HAH WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062A, 0x062D, 0x0645 }, + unicodeslot=0xFD53, + }, + [0xFD54]={ + category="lo", + description="ARABIC LIGATURE TEH WITH KHAH WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062A, 0x062E, 0x0645 }, + unicodeslot=0xFD54, + }, + [0xFD55]={ + category="lo", + description="ARABIC LIGATURE TEH WITH MEEM WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062A, 0x0645, 0x062C }, + unicodeslot=0xFD55, + }, + [0xFD56]={ + category="lo", + description="ARABIC LIGATURE TEH WITH MEEM WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062A, 0x0645, 0x062D }, + unicodeslot=0xFD56, + }, + [0xFD57]={ + category="lo", + description="ARABIC LIGATURE TEH WITH MEEM WITH KHAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062A, 0x0645, 0x062E }, + unicodeslot=0xFD57, + }, + [0xFD58]={ + category="lo", + description="ARABIC LIGATURE JEEM WITH MEEM WITH HAH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062C, 0x0645, 0x062D }, + unicodeslot=0xFD58, + }, + [0xFD59]={ + category="lo", + description="ARABIC LIGATURE JEEM WITH MEEM WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062C, 0x0645, 0x062D }, + unicodeslot=0xFD59, + }, + [0xFD5A]={ + category="lo", + description="ARABIC LIGATURE HAH WITH MEEM WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062D, 0x0645, 0x064A }, + unicodeslot=0xFD5A, + }, + [0xFD5B]={ + category="lo", + description="ARABIC LIGATURE HAH WITH MEEM WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062D, 0x0645, 0x0649 }, + unicodeslot=0xFD5B, + }, + [0xFD5C]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH HAH WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0633, 0x062D, 0x062C }, + unicodeslot=0xFD5C, + }, + [0xFD5D]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH JEEM WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0633, 0x062C, 0x062D }, + unicodeslot=0xFD5D, + }, + [0xFD5E]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH JEEM WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0633, 0x062C, 0x0649 }, + unicodeslot=0xFD5E, + }, + [0xFD5F]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH MEEM WITH HAH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0633, 0x0645, 0x062D }, + unicodeslot=0xFD5F, + }, + [0xFD60]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH MEEM WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0633, 0x0645, 0x062D }, + unicodeslot=0xFD60, + }, + [0xFD61]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH MEEM WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0633, 0x0645, 0x062C }, + unicodeslot=0xFD61, + }, + [0xFD62]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH MEEM WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0633, 0x0645, 0x0645 }, + unicodeslot=0xFD62, + }, + [0xFD63]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH MEEM WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0633, 0x0645, 0x0645 }, + unicodeslot=0xFD63, + }, + [0xFD64]={ + category="lo", + description="ARABIC LIGATURE SAD WITH HAH WITH HAH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0635, 0x062D, 0x062D }, + unicodeslot=0xFD64, + }, + [0xFD65]={ + category="lo", + description="ARABIC LIGATURE SAD WITH HAH WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0635, 0x062D, 0x062D }, + unicodeslot=0xFD65, + }, + [0xFD66]={ + category="lo", + description="ARABIC LIGATURE SAD WITH MEEM WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0635, 0x0645, 0x0645 }, + unicodeslot=0xFD66, + }, + [0xFD67]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH HAH WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0634, 0x062D, 0x0645 }, + unicodeslot=0xFD67, + }, + [0xFD68]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH HAH WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0634, 0x062D, 0x0645 }, + unicodeslot=0xFD68, + }, + [0xFD69]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH JEEM WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0634, 0x062C, 0x064A }, + unicodeslot=0xFD69, + }, + [0xFD6A]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0634, 0x0645, 0x062E }, + unicodeslot=0xFD6A, + }, + [0xFD6B]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0634, 0x0645, 0x062E }, + unicodeslot=0xFD6B, + }, + [0xFD6C]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0634, 0x0645, 0x0645 }, + unicodeslot=0xFD6C, + }, + [0xFD6D]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0634, 0x0645, 0x0645 }, + unicodeslot=0xFD6D, + }, + [0xFD6E]={ + category="lo", + description="ARABIC LIGATURE DAD WITH HAH WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0636, 0x062D, 0x0649 }, + unicodeslot=0xFD6E, + }, + [0xFD6F]={ + category="lo", + description="ARABIC LIGATURE DAD WITH KHAH WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0636, 0x062E, 0x0645 }, + unicodeslot=0xFD6F, + }, + [0xFD70]={ + category="lo", + description="ARABIC LIGATURE DAD WITH KHAH WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0636, 0x062E, 0x0645 }, + unicodeslot=0xFD70, + }, + [0xFD71]={ + category="lo", + description="ARABIC LIGATURE TAH WITH MEEM WITH HAH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0637, 0x0645, 0x062D }, + unicodeslot=0xFD71, + }, + [0xFD72]={ + category="lo", + description="ARABIC LIGATURE TAH WITH MEEM WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0637, 0x0645, 0x062D }, + unicodeslot=0xFD72, + }, + [0xFD73]={ + category="lo", + description="ARABIC LIGATURE TAH WITH MEEM WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0637, 0x0645, 0x0645 }, + unicodeslot=0xFD73, + }, + [0xFD74]={ + category="lo", + description="ARABIC LIGATURE TAH WITH MEEM WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0637, 0x0645, 0x064A }, + unicodeslot=0xFD74, + }, + [0xFD75]={ + category="lo", + description="ARABIC LIGATURE AIN WITH JEEM WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0639, 0x062C, 0x0645 }, + unicodeslot=0xFD75, + }, + [0xFD76]={ + category="lo", + description="ARABIC LIGATURE AIN WITH MEEM WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0639, 0x0645, 0x0645 }, + unicodeslot=0xFD76, + }, + [0xFD77]={ + category="lo", + description="ARABIC LIGATURE AIN WITH MEEM WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0639, 0x0645, 0x0645 }, + unicodeslot=0xFD77, + }, + [0xFD78]={ + category="lo", + description="ARABIC LIGATURE AIN WITH MEEM WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0639, 0x0645, 0x0649 }, + unicodeslot=0xFD78, + }, + [0xFD79]={ + category="lo", + description="ARABIC LIGATURE GHAIN WITH MEEM WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x063A, 0x0645, 0x0645 }, + unicodeslot=0xFD79, + }, + [0xFD7A]={ + category="lo", + description="ARABIC LIGATURE GHAIN WITH MEEM WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x063A, 0x0645, 0x064A }, + unicodeslot=0xFD7A, + }, + [0xFD7B]={ + category="lo", + description="ARABIC LIGATURE GHAIN WITH MEEM WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x063A, 0x0645, 0x0649 }, + unicodeslot=0xFD7B, + }, + [0xFD7C]={ + category="lo", + description="ARABIC LIGATURE FEH WITH KHAH WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0641, 0x062E, 0x0645 }, + unicodeslot=0xFD7C, + }, + [0xFD7D]={ + category="lo", + description="ARABIC LIGATURE FEH WITH KHAH WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0641, 0x062E, 0x0645 }, + unicodeslot=0xFD7D, + }, + [0xFD7E]={ + category="lo", + description="ARABIC LIGATURE QAF WITH MEEM WITH HAH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0642, 0x0645, 0x062D }, + unicodeslot=0xFD7E, + }, + [0xFD7F]={ + category="lo", + description="ARABIC LIGATURE QAF WITH MEEM WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0642, 0x0645, 0x0645 }, + unicodeslot=0xFD7F, + }, + [0xFD80]={ + category="lo", + description="ARABIC LIGATURE LAM WITH HAH WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0644, 0x062D, 0x0645 }, + unicodeslot=0xFD80, + }, + [0xFD81]={ + category="lo", + description="ARABIC LIGATURE LAM WITH HAH WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0644, 0x062D, 0x064A }, + unicodeslot=0xFD81, + }, + [0xFD82]={ + category="lo", + description="ARABIC LIGATURE LAM WITH HAH WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0644, 0x062D, 0x0649 }, + unicodeslot=0xFD82, + }, + [0xFD83]={ + category="lo", + description="ARABIC LIGATURE LAM WITH JEEM WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0644, 0x062C, 0x062C }, + unicodeslot=0xFD83, + }, + [0xFD84]={ + category="lo", + description="ARABIC LIGATURE LAM WITH JEEM WITH JEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0644, 0x062C, 0x062C }, + unicodeslot=0xFD84, + }, + [0xFD85]={ + category="lo", + description="ARABIC LIGATURE LAM WITH KHAH WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0644, 0x062E, 0x0645 }, + unicodeslot=0xFD85, + }, + [0xFD86]={ + category="lo", + description="ARABIC LIGATURE LAM WITH KHAH WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0644, 0x062E, 0x0645 }, + unicodeslot=0xFD86, + }, + [0xFD87]={ + category="lo", + description="ARABIC LIGATURE LAM WITH MEEM WITH HAH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0644, 0x0645, 0x062D }, + unicodeslot=0xFD87, + }, + [0xFD88]={ + category="lo", + description="ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0644, 0x0645, 0x062D }, + unicodeslot=0xFD88, + }, + [0xFD89]={ + category="lo", + description="ARABIC LIGATURE MEEM WITH HAH WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0645, 0x062D, 0x062C }, + unicodeslot=0xFD89, + }, + [0xFD8A]={ + category="lo", + description="ARABIC LIGATURE MEEM WITH HAH WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0645, 0x062D, 0x0645 }, + unicodeslot=0xFD8A, + }, + [0xFD8B]={ + category="lo", + description="ARABIC LIGATURE MEEM WITH HAH WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0645, 0x062D, 0x064A }, + unicodeslot=0xFD8B, + }, + [0xFD8C]={ + category="lo", + description="ARABIC LIGATURE MEEM WITH JEEM WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0645, 0x062C, 0x062D }, + unicodeslot=0xFD8C, + }, + [0xFD8D]={ + category="lo", + description="ARABIC LIGATURE MEEM WITH JEEM WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0645, 0x062C, 0x0645 }, + unicodeslot=0xFD8D, + }, + [0xFD8E]={ + category="lo", + description="ARABIC LIGATURE MEEM WITH KHAH WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0645, 0x062E, 0x062C }, + unicodeslot=0xFD8E, + }, + [0xFD8F]={ + category="lo", + description="ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0645, 0x062E, 0x0645 }, + unicodeslot=0xFD8F, + }, + [0xFD92]={ + category="lo", + description="ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0645, 0x062C, 0x062E }, + unicodeslot=0xFD92, + }, + [0xFD93]={ + category="lo", + description="ARABIC LIGATURE HEH WITH MEEM WITH JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0647, 0x0645, 0x062C }, + unicodeslot=0xFD93, + }, + [0xFD94]={ + category="lo", + description="ARABIC LIGATURE HEH WITH MEEM WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0647, 0x0645, 0x0645 }, + unicodeslot=0xFD94, + }, + [0xFD95]={ + category="lo", + description="ARABIC LIGATURE NOON WITH HAH WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0646, 0x062D, 0x0645 }, + unicodeslot=0xFD95, + }, + [0xFD96]={ + category="lo", + description="ARABIC LIGATURE NOON WITH HAH WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0646, 0x062D, 0x0649 }, + unicodeslot=0xFD96, + }, + [0xFD97]={ + category="lo", + description="ARABIC LIGATURE NOON WITH JEEM WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0646, 0x062C, 0x0645 }, + unicodeslot=0xFD97, + }, + [0xFD98]={ + category="lo", + description="ARABIC LIGATURE NOON WITH JEEM WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0646, 0x062C, 0x0645 }, + unicodeslot=0xFD98, + }, + [0xFD99]={ + category="lo", + description="ARABIC LIGATURE NOON WITH JEEM WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0646, 0x062C, 0x0649 }, + unicodeslot=0xFD99, + }, + [0xFD9A]={ + category="lo", + description="ARABIC LIGATURE NOON WITH MEEM WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0646, 0x0645, 0x064A }, + unicodeslot=0xFD9A, + }, + [0xFD9B]={ + category="lo", + description="ARABIC LIGATURE NOON WITH MEEM WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0646, 0x0645, 0x0649 }, + unicodeslot=0xFD9B, + }, + [0xFD9C]={ + category="lo", + description="ARABIC LIGATURE YEH WITH MEEM WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x064A, 0x0645, 0x0645 }, + unicodeslot=0xFD9C, + }, + [0xFD9D]={ + category="lo", + description="ARABIC LIGATURE YEH WITH MEEM WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x064A, 0x0645, 0x0645 }, + unicodeslot=0xFD9D, + }, + [0xFD9E]={ + category="lo", + description="ARABIC LIGATURE BEH WITH KHAH WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0628, 0x062E, 0x064A }, + unicodeslot=0xFD9E, + }, + [0xFD9F]={ + category="lo", + description="ARABIC LIGATURE TEH WITH JEEM WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062A, 0x062C, 0x064A }, + unicodeslot=0xFD9F, + }, + [0xFDA0]={ + category="lo", + description="ARABIC LIGATURE TEH WITH JEEM WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062A, 0x062C, 0x0649 }, + unicodeslot=0xFDA0, + }, + [0xFDA1]={ + category="lo", + description="ARABIC LIGATURE TEH WITH KHAH WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062A, 0x062E, 0x064A }, + unicodeslot=0xFDA1, + }, + [0xFDA2]={ + category="lo", + description="ARABIC LIGATURE TEH WITH KHAH WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062A, 0x062E, 0x0649 }, + unicodeslot=0xFDA2, + }, + [0xFDA3]={ + category="lo", + description="ARABIC LIGATURE TEH WITH MEEM WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062A, 0x0645, 0x064A }, + unicodeslot=0xFDA3, + }, + [0xFDA4]={ + category="lo", + description="ARABIC LIGATURE TEH WITH MEEM WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062A, 0x0645, 0x0649 }, + unicodeslot=0xFDA4, + }, + [0xFDA5]={ + category="lo", + description="ARABIC LIGATURE JEEM WITH MEEM WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062C, 0x0645, 0x064A }, + unicodeslot=0xFDA5, + }, + [0xFDA6]={ + category="lo", + description="ARABIC LIGATURE JEEM WITH HAH WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062C, 0x062D, 0x0649 }, + unicodeslot=0xFDA6, + }, + [0xFDA7]={ + category="lo", + description="ARABIC LIGATURE JEEM WITH MEEM WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062C, 0x0645, 0x0649 }, + unicodeslot=0xFDA7, + }, + [0xFDA8]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH KHAH WITH ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0633, 0x062E, 0x0649 }, + unicodeslot=0xFDA8, + }, + [0xFDA9]={ + category="lo", + description="ARABIC LIGATURE SAD WITH HAH WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0635, 0x062D, 0x064A }, + unicodeslot=0xFDA9, + }, + [0xFDAA]={ + category="lo", + description="ARABIC LIGATURE SHEEN WITH HAH WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0634, 0x062D, 0x064A }, + unicodeslot=0xFDAA, + }, + [0xFDAB]={ + category="lo", + description="ARABIC LIGATURE DAD WITH HAH WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0636, 0x062D, 0x064A }, + unicodeslot=0xFDAB, + }, + [0xFDAC]={ + category="lo", + description="ARABIC LIGATURE LAM WITH JEEM WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0644, 0x062C, 0x064A }, + unicodeslot=0xFDAC, + }, + [0xFDAD]={ + category="lo", + description="ARABIC LIGATURE LAM WITH MEEM WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0644, 0x0645, 0x064A }, + unicodeslot=0xFDAD, + }, + [0xFDAE]={ + category="lo", + description="ARABIC LIGATURE YEH WITH HAH WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x064A, 0x062D, 0x064A }, + unicodeslot=0xFDAE, + }, + [0xFDAF]={ + category="lo", + description="ARABIC LIGATURE YEH WITH JEEM WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x064A, 0x062C, 0x064A }, + unicodeslot=0xFDAF, + }, + [0xFDB0]={ + category="lo", + description="ARABIC LIGATURE YEH WITH MEEM WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x064A, 0x0645, 0x064A }, + unicodeslot=0xFDB0, + }, + [0xFDB1]={ + category="lo", + description="ARABIC LIGATURE MEEM WITH MEEM WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0645, 0x0645, 0x064A }, + unicodeslot=0xFDB1, + }, + [0xFDB2]={ + category="lo", + description="ARABIC LIGATURE QAF WITH MEEM WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0642, 0x0645, 0x064A }, + unicodeslot=0xFDB2, + }, + [0xFDB3]={ + category="lo", + description="ARABIC LIGATURE NOON WITH HAH WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0646, 0x062D, 0x064A }, + unicodeslot=0xFDB3, + }, + [0xFDB4]={ + category="lo", + description="ARABIC LIGATURE QAF WITH MEEM WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0642, 0x0645, 0x062D }, + unicodeslot=0xFDB4, + }, + [0xFDB5]={ + category="lo", + description="ARABIC LIGATURE LAM WITH HAH WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0644, 0x062D, 0x0645 }, + unicodeslot=0xFDB5, + }, + [0xFDB6]={ + category="lo", + description="ARABIC LIGATURE AIN WITH MEEM WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0639, 0x0645, 0x064A }, + unicodeslot=0xFDB6, + }, + [0xFDB7]={ + category="lo", + description="ARABIC LIGATURE KAF WITH MEEM WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0643, 0x0645, 0x064A }, + unicodeslot=0xFDB7, + }, + [0xFDB8]={ + category="lo", + description="ARABIC LIGATURE NOON WITH JEEM WITH HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0646, 0x062C, 0x062D }, + unicodeslot=0xFDB8, + }, + [0xFDB9]={ + category="lo", + description="ARABIC LIGATURE MEEM WITH KHAH WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0645, 0x062E, 0x064A }, + unicodeslot=0xFDB9, + }, + [0xFDBA]={ + category="lo", + description="ARABIC LIGATURE LAM WITH JEEM WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0644, 0x062C, 0x0645 }, + unicodeslot=0xFDBA, + }, + [0xFDBB]={ + category="lo", + description="ARABIC LIGATURE KAF WITH MEEM WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0643, 0x0645, 0x0645 }, + unicodeslot=0xFDBB, + }, + [0xFDBC]={ + category="lo", + description="ARABIC LIGATURE LAM WITH JEEM WITH MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0644, 0x062C, 0x0645 }, + unicodeslot=0xFDBC, + }, + [0xFDBD]={ + category="lo", + description="ARABIC LIGATURE NOON WITH JEEM WITH HAH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0646, 0x062C, 0x062D }, + unicodeslot=0xFDBD, + }, + [0xFDBE]={ + category="lo", + description="ARABIC LIGATURE JEEM WITH HAH WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062C, 0x062D, 0x064A }, + unicodeslot=0xFDBE, + }, + [0xFDBF]={ + category="lo", + description="ARABIC LIGATURE HAH WITH JEEM WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062D, 0x062C, 0x064A }, + unicodeslot=0xFDBF, + }, + [0xFDC0]={ + category="lo", + description="ARABIC LIGATURE MEEM WITH JEEM WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0645, 0x062C, 0x064A }, + unicodeslot=0xFDC0, + }, + [0xFDC1]={ + category="lo", + description="ARABIC LIGATURE FEH WITH MEEM WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0641, 0x0645, 0x064A }, + unicodeslot=0xFDC1, + }, + [0xFDC2]={ + category="lo", + description="ARABIC LIGATURE BEH WITH HAH WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0628, 0x062D, 0x064A }, + unicodeslot=0xFDC2, + }, + [0xFDC3]={ + category="lo", + description="ARABIC LIGATURE KAF WITH MEEM WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0643, 0x0645, 0x0645 }, + unicodeslot=0xFDC3, + }, + [0xFDC4]={ + category="lo", + description="ARABIC LIGATURE AIN WITH JEEM WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0639, 0x062C, 0x0645 }, + unicodeslot=0xFDC4, + }, + [0xFDC5]={ + category="lo", + description="ARABIC LIGATURE SAD WITH MEEM WITH MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0635, 0x0645, 0x0645 }, + unicodeslot=0xFDC5, + }, + [0xFDC6]={ + category="lo", + description="ARABIC LIGATURE SEEN WITH KHAH WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0633, 0x062E, 0x064A }, + unicodeslot=0xFDC6, + }, + [0xFDC7]={ + category="lo", + description="ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0646, 0x062C, 0x064A }, + unicodeslot=0xFDC7, + }, + [0xFDF0]={ + category="lo", + description="ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0635, 0x0644, 0x06D2 }, + unicodeslot=0xFDF0, + }, + [0xFDF1]={ + category="lo", + description="ARABIC LIGATURE QALA USED AS KORANIC STOP SIGN ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0642, 0x0644, 0x06D2 }, + unicodeslot=0xFDF1, + }, + [0xFDF2]={ + category="lo", + description="ARABIC LIGATURE ALLAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0627, 0x0644, 0x0644, 0x0647 }, + unicodeslot=0xFDF2, + }, + [0xFDF3]={ + category="lo", + description="ARABIC LIGATURE AKBAR ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0627, 0x0643, 0x0628, 0x0631 }, + unicodeslot=0xFDF3, + }, + [0xFDF4]={ + category="lo", + description="ARABIC LIGATURE MOHAMMAD ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0645, 0x062D, 0x0645, 0x062F }, + unicodeslot=0xFDF4, + }, + [0xFDF5]={ + category="lo", + description="ARABIC LIGATURE SALAM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0635, 0x0644, 0x0639, 0x0645 }, + unicodeslot=0xFDF5, + }, + [0xFDF6]={ + category="lo", + description="ARABIC LIGATURE RASOUL ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0631, 0x0633, 0x0648, 0x0644 }, + unicodeslot=0xFDF6, + }, + [0xFDF7]={ + category="lo", + description="ARABIC LIGATURE ALAYHE ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0639, 0x0644, 0x064A, 0x0647 }, + unicodeslot=0xFDF7, + }, + [0xFDF8]={ + category="lo", + description="ARABIC LIGATURE WASALLAM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0648, 0x0633, 0x0644, 0x0645 }, + unicodeslot=0xFDF8, + }, + [0xFDF9]={ + category="lo", + description="ARABIC LIGATURE SALLA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0635, 0x0644, 0x0649 }, + unicodeslot=0xFDF9, + }, + [0xFDFA]={ + category="lo", + description="ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0635, 0x0644, 0x0649, 0x0020, 0x0627, 0x0644, 0x0644, 0x0647, 0x0020, 0x0639, 0x0644, 0x064A, 0x0647, 0x0020, 0x0648, 0x0633, 0x0644, 0x0645 }, + unicodeslot=0xFDFA, + }, + [0xFDFB]={ + category="lo", + description="ARABIC LIGATURE JALLAJALALOUHOU", + direction="al", + linebreak="al", + specials={ "isolated", 0x062C, 0x0644, 0x0020, 0x062C, 0x0644, 0x0627, 0x0644, 0x0647 }, + unicodeslot=0xFDFB, + }, + [0xFDFC]={ + category="sc", + description="RIAL SIGN", + direction="al", + linebreak="po", + specials={ "isolated", 0x0631, 0x06CC, 0x0627, 0x0644 }, + unicodeslot=0xFDFC, + }, + [0xFDFD]={ + category="so", + description="ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM", + direction="on", + linebreak="al", + unicodeslot=0xFDFD, + }, + [0xFE00]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0001", + direction="nsm", + linebreak="cm", + unicodeslot=0xFE00, + }, + [0xFE01]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0002", + direction="nsm", + linebreak="cm", + unicodeslot=0xFE01, + }, + [0xFE02]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0003", + direction="nsm", + linebreak="cm", + unicodeslot=0xFE02, + }, + [0xFE03]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0004", + direction="nsm", + linebreak="cm", + unicodeslot=0xFE03, + }, + [0xFE04]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0005", + direction="nsm", + linebreak="cm", + unicodeslot=0xFE04, + }, + [0xFE05]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0006", + direction="nsm", + linebreak="cm", + unicodeslot=0xFE05, + }, + [0xFE06]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0007", + direction="nsm", + linebreak="cm", + unicodeslot=0xFE06, + }, + [0xFE07]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0008", + direction="nsm", + linebreak="cm", + unicodeslot=0xFE07, + }, + [0xFE08]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0009", + direction="nsm", + linebreak="cm", + unicodeslot=0xFE08, + }, + [0xFE09]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x000A", + direction="nsm", + linebreak="cm", + unicodeslot=0xFE09, + }, + [0xFE0A]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x000B", + direction="nsm", + linebreak="cm", + unicodeslot=0xFE0A, + }, + [0xFE0B]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x000C", + direction="nsm", + linebreak="cm", + unicodeslot=0xFE0B, + }, + [0xFE0C]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x000D", + direction="nsm", + linebreak="cm", + unicodeslot=0xFE0C, + }, + [0xFE0D]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x000E", + direction="nsm", + linebreak="cm", + unicodeslot=0xFE0D, + }, + [0xFE0E]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x000F", + direction="nsm", + linebreak="cm", + unicodeslot=0xFE0E, + }, + [0xFE0F]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0010", + direction="nsm", + linebreak="cm", + unicodeslot=0xFE0F, + }, + [0xFE10]={ + category="po", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL COMMA", + direction="on", + linebreak="is", + specials={ "vertical", 0x002C }, + unicodeslot=0xFE10, + }, + [0xFE11]={ + category="po", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC COMMA", + direction="on", + linebreak="cl", + specials={ "vertical", 0x3001 }, + unicodeslot=0xFE11, + }, + [0xFE12]={ + category="po", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC FULL STOP", + direction="on", + linebreak="cl", + specials={ "vertical", 0x3002 }, + unicodeslot=0xFE12, + }, + [0xFE13]={ + category="po", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL COLON", + direction="on", + linebreak="is", + specials={ "vertical", 0x003A }, + unicodeslot=0xFE13, + }, + [0xFE14]={ + category="po", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL SEMICOLON", + direction="on", + linebreak="is", + specials={ "vertical", 0x003B }, + unicodeslot=0xFE14, + }, + [0xFE15]={ + category="po", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL EXCLAMATION MARK", + direction="on", + linebreak="ex", + specials={ "vertical", 0x0021 }, + unicodeslot=0xFE15, + }, + [0xFE16]={ + category="po", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL QUESTION MARK", + direction="on", + linebreak="ex", + specials={ "vertical", 0x003F }, + unicodeslot=0xFE16, + }, + [0xFE17]={ + category="ps", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET", + direction="on", + linebreak="op", + specials={ "vertical", 0x3016 }, + unicodeslot=0xFE17, + }, + [0xFE18]={ + category="pe", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET", + direction="on", + linebreak="cl", + specials={ "vertical", 0x3017 }, + unicodeslot=0xFE18, + }, + [0xFE19]={ + category="po", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS", + direction="on", + linebreak="in", + specials={ "vertical", 0x2026 }, + unicodeslot=0xFE19, + }, + [0xFE20]={ + category="mn", + description="COMBINING LIGATURE LEFT HALF", + direction="nsm", + linebreak="cm", + unicodeslot=0xFE20, + }, + [0xFE21]={ + category="mn", + description="COMBINING LIGATURE RIGHT HALF", + direction="nsm", + linebreak="cm", + unicodeslot=0xFE21, + }, + [0xFE22]={ + category="mn", + description="COMBINING DOUBLE TILDE LEFT HALF", + direction="nsm", + linebreak="cm", + unicodeslot=0xFE22, + }, + [0xFE23]={ + category="mn", + description="COMBINING DOUBLE TILDE RIGHT HALF", + direction="nsm", + linebreak="cm", + unicodeslot=0xFE23, + }, + [0xFE30]={ + category="po", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL TWO DOT LEADER", + direction="on", + linebreak="id", + specials={ "vertical", 0x2025 }, + unicodeslot=0xFE30, + }, + [0xFE31]={ + category="pd", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL EM DASH", + direction="on", + linebreak="id", + specials={ "vertical", 0x2014 }, + unicodeslot=0xFE31, + }, + [0xFE32]={ + category="pd", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL EN DASH", + direction="on", + linebreak="id", + specials={ "vertical", 0x2013 }, + unicodeslot=0xFE32, + }, + [0xFE33]={ + category="pc", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL LOW LINE", + direction="on", + linebreak="id", + specials={ "vertical", 0x005F }, + unicodeslot=0xFE33, + }, + [0xFE34]={ + category="pc", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL WAVY LOW LINE", + direction="on", + linebreak="id", + specials={ "vertical", 0x005F }, + unicodeslot=0xFE34, + }, + [0xFE35]={ + category="ps", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS", + direction="on", + linebreak="op", + specials={ "vertical", 0x0028 }, + unicodeslot=0xFE35, + }, + [0xFE36]={ + category="pe", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS", + direction="on", + linebreak="cl", + specials={ "vertical", 0x0029 }, + unicodeslot=0xFE36, + }, + [0xFE37]={ + category="ps", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET", + direction="on", + linebreak="op", + mathfiller="downbracefill", -- funny, chinese, no math, wrong but for the moment we need it for buggy mathml + specials={ "vertical", 0x007B }, + unicodeslot=0xFE37, + }, + [0xFE38]={ + category="pe", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET", + direction="on", + linebreak="cl", + mathfiller="upbracefill", -- funny, chinese, no math, wrong but for the moment we need it for buggy mathml + specials={ "vertical", 0x007D }, + unicodeslot=0xFE38, + }, + [0xFE39]={ + category="ps", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET", + direction="on", + linebreak="op", + specials={ "vertical", 0x3014 }, + unicodeslot=0xFE39, + }, + [0xFE3A]={ + category="pe", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET", + direction="on", + linebreak="cl", + specials={ "vertical", 0x3015 }, + unicodeslot=0xFE3A, + }, + [0xFE3B]={ + category="ps", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET", + direction="on", + linebreak="op", + specials={ "vertical", 0x3010 }, + unicodeslot=0xFE3B, + }, + [0xFE3C]={ + category="pe", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET", + direction="on", + linebreak="cl", + specials={ "vertical", 0x3011 }, + unicodeslot=0xFE3C, + }, + [0xFE3D]={ + category="ps", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET", + direction="on", + linebreak="op", + specials={ "vertical", 0x300A }, + unicodeslot=0xFE3D, + }, + [0xFE3E]={ + category="pe", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET", + direction="on", + linebreak="cl", + specials={ "vertical", 0x300B }, + unicodeslot=0xFE3E, + }, + [0xFE3F]={ + category="ps", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET", + direction="on", + linebreak="op", + specials={ "vertical", 0x3008 }, + unicodeslot=0xFE3F, + }, + [0xFE40]={ + category="pe", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET", + direction="on", + linebreak="cl", + specials={ "vertical", 0x3009 }, + unicodeslot=0xFE40, + }, + [0xFE41]={ + category="ps", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET", + direction="on", + linebreak="op", + specials={ "vertical", 0x300C }, + unicodeslot=0xFE41, + }, + [0xFE42]={ + category="pe", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET", + direction="on", + linebreak="cl", + specials={ "vertical", 0x300D }, + unicodeslot=0xFE42, + }, + [0xFE43]={ + category="ps", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET", + direction="on", + linebreak="op", + specials={ "vertical", 0x300E }, + unicodeslot=0xFE43, + }, + [0xFE44]={ + category="pe", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET", + direction="on", + linebreak="cl", + specials={ "vertical", 0x300F }, + unicodeslot=0xFE44, + }, + [0xFE45]={ + category="po", + cjkwd="w", + description="SESAME DOT", + direction="on", + linebreak="id", + unicodeslot=0xFE45, + }, + [0xFE46]={ + category="po", + cjkwd="w", + description="WHITE SESAME DOT", + direction="on", + linebreak="id", + unicodeslot=0xFE46, + }, + [0xFE47]={ + category="ps", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET", + direction="on", + linebreak="op", + specials={ "vertical", 0x005B }, + unicodeslot=0xFE47, + }, + [0xFE48]={ + category="pe", + cjkwd="w", + description="PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET", + direction="on", + linebreak="cl", + specials={ "vertical", 0x005D }, + unicodeslot=0xFE48, + }, + [0xFE49]={ + category="po", + cjkwd="w", + description="DASHED OVERLINE", + direction="on", + linebreak="id", + specials={ "compat", 0x203E }, + unicodeslot=0xFE49, + }, + [0xFE4A]={ + category="po", + cjkwd="w", + description="CENTRELINE OVERLINE", + direction="on", + linebreak="id", + specials={ "compat", 0x203E }, + unicodeslot=0xFE4A, + }, + [0xFE4B]={ + category="po", + cjkwd="w", + description="WAVY OVERLINE", + direction="on", + linebreak="id", + specials={ "compat", 0x203E }, + unicodeslot=0xFE4B, + }, + [0xFE4C]={ + category="po", + cjkwd="w", + description="DOUBLE WAVY OVERLINE", + direction="on", + linebreak="id", + specials={ "compat", 0x203E }, + unicodeslot=0xFE4C, + }, + [0xFE4D]={ + category="pc", + cjkwd="w", + description="DASHED LOW LINE", + direction="on", + linebreak="id", + specials={ "compat", 0x005F }, + unicodeslot=0xFE4D, + }, + [0xFE4E]={ + category="pc", + cjkwd="w", + description="CENTRELINE LOW LINE", + direction="on", + linebreak="id", + specials={ "compat", 0x005F }, + unicodeslot=0xFE4E, + }, + [0xFE4F]={ + category="pc", + cjkwd="w", + description="WAVY LOW LINE", + direction="on", + linebreak="id", + specials={ "compat", 0x005F }, + unicodeslot=0xFE4F, + }, + [0xFE50]={ + category="po", + cjkwd="w", + description="SMALL COMMA", + direction="cs", + linebreak="cl", + specials={ "small", 0x002C }, + unicodeslot=0xFE50, + }, + [0xFE51]={ + category="po", + cjkwd="w", + description="SMALL IDEOGRAPHIC COMMA", + direction="on", + linebreak="id", + specials={ "small", 0x3001 }, + unicodeslot=0xFE51, + }, + [0xFE52]={ + category="po", + cjkwd="w", + description="SMALL FULL STOP", + direction="cs", + linebreak="cl", + specials={ "small", 0x002E }, + unicodeslot=0xFE52, + }, + [0xFE54]={ + category="po", + cjkwd="w", + description="SMALL SEMICOLON", + direction="on", + linebreak="ns", + specials={ "small", 0x003B }, + unicodeslot=0xFE54, + }, + [0xFE55]={ + category="po", + cjkwd="w", + description="SMALL COLON", + direction="cs", + linebreak="ns", + specials={ "small", 0x003A }, + unicodeslot=0xFE55, + }, + [0xFE56]={ + category="po", + cjkwd="w", + description="SMALL QUESTION MARK", + direction="on", + linebreak="ex", + specials={ "small", 0x003F }, + unicodeslot=0xFE56, + }, + [0xFE57]={ + category="po", + cjkwd="w", + description="SMALL EXCLAMATION MARK", + direction="on", + linebreak="ex", + specials={ "small", 0x0021 }, + unicodeslot=0xFE57, + }, + [0xFE58]={ + category="pd", + cjkwd="w", + description="SMALL EM DASH", + direction="on", + linebreak="id", + specials={ "small", 0x2014 }, + unicodeslot=0xFE58, + }, + [0xFE59]={ + category="ps", + cjkwd="w", + description="SMALL LEFT PARENTHESIS", + direction="on", + linebreak="op", + mirror=0xFE5A, + specials={ "small", 0x0028 }, + unicodeslot=0xFE59, + }, + [0xFE5A]={ + category="pe", + cjkwd="w", + description="SMALL RIGHT PARENTHESIS", + direction="on", + linebreak="cl", + mirror=0xFE59, + specials={ "small", 0x0029 }, + unicodeslot=0xFE5A, + }, + [0xFE5B]={ + category="ps", + cjkwd="w", + description="SMALL LEFT CURLY BRACKET", + direction="on", + linebreak="op", + mirror=0xFE5C, + specials={ "small", 0x007B }, + unicodeslot=0xFE5B, + }, + [0xFE5C]={ + category="pe", + cjkwd="w", + description="SMALL RIGHT CURLY BRACKET", + direction="on", + linebreak="cl", + mirror=0xFE5B, + specials={ "small", 0x007D }, + unicodeslot=0xFE5C, + }, + [0xFE5D]={ + category="ps", + cjkwd="w", + description="SMALL LEFT TORTOISE SHELL BRACKET", + direction="on", + linebreak="op", + mirror=0xFE5E, + specials={ "small", 0x3014 }, + unicodeslot=0xFE5D, + }, + [0xFE5E]={ + category="pe", + cjkwd="w", + description="SMALL RIGHT TORTOISE SHELL BRACKET", + direction="on", + linebreak="cl", + mirror=0xFE5D, + specials={ "small", 0x3015 }, + unicodeslot=0xFE5E, + }, + [0xFE5F]={ + category="po", + cjkwd="w", + description="SMALL NUMBER SIGN", + direction="et", + linebreak="id", + specials={ "small", 0x0023 }, + unicodeslot=0xFE5F, + }, + [0xFE60]={ + category="po", + cjkwd="w", + description="SMALL AMPERSAND", + direction="on", + linebreak="id", + specials={ "small", 0x0026 }, + unicodeslot=0xFE60, + }, + [0xFE61]={ + category="po", + cjkwd="w", + description="SMALL ASTERISK", + direction="on", + linebreak="id", + specials={ "small", 0x002A }, + unicodeslot=0xFE61, + }, + [0xFE62]={ + category="sm", + cjkwd="w", + description="SMALL PLUS SIGN", + direction="es", + linebreak="id", + specials={ "small", 0x002B }, + unicodeslot=0xFE62, + }, + [0xFE63]={ + category="pd", + cjkwd="w", + description="SMALL HYPHEN-MINUS", + direction="es", + linebreak="id", + specials={ "small", 0x002D }, + unicodeslot=0xFE63, + }, + [0xFE64]={ + category="sm", + cjkwd="w", + description="SMALL LESS-THAN SIGN", + direction="on", + linebreak="id", + mirror=0xFE65, + specials={ "small", 0x003C }, + unicodeslot=0xFE64, + }, + [0xFE65]={ + category="sm", + cjkwd="w", + description="SMALL GREATER-THAN SIGN", + direction="on", + linebreak="id", + mirror=0xFE64, + specials={ "small", 0x003E }, + unicodeslot=0xFE65, + }, + [0xFE66]={ + category="sm", + cjkwd="w", + description="SMALL EQUALS SIGN", + direction="on", + linebreak="id", + specials={ "small", 0x003D }, + unicodeslot=0xFE66, + }, + [0xFE68]={ + category="po", + cjkwd="w", + description="SMALL REVERSE SOLIDUS", + direction="on", + linebreak="id", + specials={ "small", 0x005C }, + unicodeslot=0xFE68, + }, + [0xFE69]={ + category="sc", + cjkwd="w", + description="SMALL DOLLAR SIGN", + direction="et", + linebreak="pr", + specials={ "small", 0x0024 }, + unicodeslot=0xFE69, + }, + [0xFE6A]={ + category="po", + cjkwd="w", + description="SMALL PERCENT SIGN", + direction="et", + linebreak="po", + specials={ "small", 0x0025 }, + unicodeslot=0xFE6A, + }, + [0xFE6B]={ + category="po", + cjkwd="w", + description="SMALL COMMERCIAL AT", + direction="on", + linebreak="id", + specials={ "small", 0x0040 }, + unicodeslot=0xFE6B, + }, + [0xFE70]={ + category="lo", + description="ARABIC FATHATAN ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0020, 0x064B }, + unicodeslot=0xFE70, + }, + [0xFE71]={ + category="lo", + description="ARABIC TATWEEL WITH FATHATAN ABOVE", + direction="al", + linebreak="al", + specials={ "medial", 0x0640, 0x064B }, + unicodeslot=0xFE71, + }, + [0xFE72]={ + category="lo", + description="ARABIC DAMMATAN ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0020, 0x064C }, + unicodeslot=0xFE72, + }, + [0xFE73]={ + category="lo", + description="ARABIC TAIL FRAGMENT", + direction="al", + linebreak="al", + unicodeslot=0xFE73, + }, + [0xFE74]={ + category="lo", + description="ARABIC KASRATAN ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0020, 0x064D }, + unicodeslot=0xFE74, + }, + [0xFE76]={ + category="lo", + description="ARABIC FATHA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0020, 0x064E }, + unicodeslot=0xFE76, + }, + [0xFE77]={ + category="lo", + description="ARABIC FATHA MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0640, 0x064E }, + unicodeslot=0xFE77, + }, + [0xFE78]={ + category="lo", + description="ARABIC DAMMA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0020, 0x064F }, + unicodeslot=0xFE78, + }, + [0xFE79]={ + category="lo", + description="ARABIC DAMMA MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0640, 0x064F }, + unicodeslot=0xFE79, + }, + [0xFE7A]={ + category="lo", + description="ARABIC KASRA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0020, 0x0650 }, + unicodeslot=0xFE7A, + }, + [0xFE7B]={ + category="lo", + description="ARABIC KASRA MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0640, 0x0650 }, + unicodeslot=0xFE7B, + }, + [0xFE7C]={ + category="lo", + description="ARABIC SHADDA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0020, 0x0651 }, + unicodeslot=0xFE7C, + }, + [0xFE7D]={ + category="lo", + description="ARABIC SHADDA MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0640, 0x0651 }, + unicodeslot=0xFE7D, + }, + [0xFE7E]={ + category="lo", + description="ARABIC SUKUN ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0020, 0x0652 }, + unicodeslot=0xFE7E, + }, + [0xFE7F]={ + category="lo", + description="ARABIC SUKUN MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0640, 0x0652 }, + unicodeslot=0xFE7F, + }, + [0xFE80]={ + category="lo", + description="ARABIC LETTER HAMZA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0621 }, + unicodeslot=0xFE80, + }, + [0xFE81]={ + category="lo", + description="ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM", + direction="al", + linebreak="al", + shcode=0x0627, + specials={ "isolated", 0x0622 }, + unicodeslot=0xFE81, + }, + [0xFE82]={ + category="lo", + description="ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM", + direction="al", + linebreak="al", + shcode=0x0627, + specials={ "final", 0x0622 }, + unicodeslot=0xFE82, + }, + [0xFE83]={ + category="lo", + description="ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM", + direction="al", + linebreak="al", + shcode=0x0627, + specials={ "isolated", 0x0623 }, + unicodeslot=0xFE83, + }, + [0xFE84]={ + category="lo", + description="ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM", + direction="al", + linebreak="al", + shcode=0x0627, + specials={ "final", 0x0623 }, + unicodeslot=0xFE84, + }, + [0xFE85]={ + category="lo", + description="ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM", + direction="al", + linebreak="al", + shcode=0x0648, + specials={ "isolated", 0x0624 }, + unicodeslot=0xFE85, + }, + [0xFE86]={ + category="lo", + description="ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM", + direction="al", + linebreak="al", + shcode=0x0648, + specials={ "final", 0x0624 }, + unicodeslot=0xFE86, + }, + [0xFE87]={ + category="lo", + description="ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM", + direction="al", + linebreak="al", + shcode=0x0627, + specials={ "isolated", 0x0625 }, + unicodeslot=0xFE87, + }, + [0xFE88]={ + category="lo", + description="ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM", + direction="al", + linebreak="al", + shcode=0x0627, + specials={ "final", 0x0625 }, + unicodeslot=0xFE88, + }, + [0xFE89]={ + category="lo", + description="ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM", + direction="al", + linebreak="al", + shcode=0x064A, + specials={ "isolated", 0x0626 }, + unicodeslot=0xFE89, + }, + [0xFE8A]={ + category="lo", + description="ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM", + direction="al", + linebreak="al", + shcode=0x064A, + specials={ "final", 0x0626 }, + unicodeslot=0xFE8A, + }, + [0xFE8B]={ + category="lo", + description="ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM", + direction="al", + linebreak="al", + shcode=0x064A, + specials={ "initial", 0x0626 }, + unicodeslot=0xFE8B, + }, + [0xFE8C]={ + category="lo", + description="ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM", + direction="al", + linebreak="al", + shcode=0x064A, + specials={ "medial", 0x0626 }, + unicodeslot=0xFE8C, + }, + [0xFE8D]={ + category="lo", + description="ARABIC LETTER ALEF ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0627 }, + unicodeslot=0xFE8D, + }, + [0xFE8E]={ + category="lo", + description="ARABIC LETTER ALEF FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0627 }, + unicodeslot=0xFE8E, + }, + [0xFE8F]={ + category="lo", + description="ARABIC LETTER BEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0628 }, + unicodeslot=0xFE8F, + }, + [0xFE90]={ + category="lo", + description="ARABIC LETTER BEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0628 }, + unicodeslot=0xFE90, + }, + [0xFE91]={ + category="lo", + description="ARABIC LETTER BEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0628 }, + unicodeslot=0xFE91, + }, + [0xFE92]={ + category="lo", + description="ARABIC LETTER BEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0628 }, + unicodeslot=0xFE92, + }, + [0xFE93]={ + category="lo", + description="ARABIC LETTER TEH MARBUTA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0629 }, + unicodeslot=0xFE93, + }, + [0xFE94]={ + category="lo", + description="ARABIC LETTER TEH MARBUTA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0629 }, + unicodeslot=0xFE94, + }, + [0xFE95]={ + category="lo", + description="ARABIC LETTER TEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062A }, + unicodeslot=0xFE95, + }, + [0xFE96]={ + category="lo", + description="ARABIC LETTER TEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062A }, + unicodeslot=0xFE96, + }, + [0xFE97]={ + category="lo", + description="ARABIC LETTER TEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062A }, + unicodeslot=0xFE97, + }, + [0xFE98]={ + category="lo", + description="ARABIC LETTER TEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x062A }, + unicodeslot=0xFE98, + }, + [0xFE99]={ + category="lo", + description="ARABIC LETTER THEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062B }, + unicodeslot=0xFE99, + }, + [0xFE9A]={ + category="lo", + description="ARABIC LETTER THEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062B }, + unicodeslot=0xFE9A, + }, + [0xFE9B]={ + category="lo", + description="ARABIC LETTER THEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062B }, + unicodeslot=0xFE9B, + }, + [0xFE9C]={ + category="lo", + description="ARABIC LETTER THEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x062B }, + unicodeslot=0xFE9C, + }, + [0xFE9D]={ + category="lo", + description="ARABIC LETTER JEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062C }, + unicodeslot=0xFE9D, + }, + [0xFE9E]={ + category="lo", + description="ARABIC LETTER JEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062C }, + unicodeslot=0xFE9E, + }, + [0xFE9F]={ + category="lo", + description="ARABIC LETTER JEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062C }, + unicodeslot=0xFE9F, + }, + [0xFEA0]={ + category="lo", + description="ARABIC LETTER JEEM MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x062C }, + unicodeslot=0xFEA0, + }, + [0xFEA1]={ + category="lo", + description="ARABIC LETTER HAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062D }, + unicodeslot=0xFEA1, + }, + [0xFEA2]={ + category="lo", + description="ARABIC LETTER HAH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062D }, + unicodeslot=0xFEA2, + }, + [0xFEA3]={ + category="lo", + description="ARABIC LETTER HAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062D }, + unicodeslot=0xFEA3, + }, + [0xFEA4]={ + category="lo", + description="ARABIC LETTER HAH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x062D }, + unicodeslot=0xFEA4, + }, + [0xFEA5]={ + category="lo", + description="ARABIC LETTER KHAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062E }, + unicodeslot=0xFEA5, + }, + [0xFEA6]={ + category="lo", + description="ARABIC LETTER KHAH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062E }, + unicodeslot=0xFEA6, + }, + [0xFEA7]={ + category="lo", + description="ARABIC LETTER KHAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x062E }, + unicodeslot=0xFEA7, + }, + [0xFEA8]={ + category="lo", + description="ARABIC LETTER KHAH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x062E }, + unicodeslot=0xFEA8, + }, + [0xFEA9]={ + category="lo", + description="ARABIC LETTER DAL ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x062F }, + unicodeslot=0xFEA9, + }, + [0xFEAA]={ + category="lo", + description="ARABIC LETTER DAL FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x062F }, + unicodeslot=0xFEAA, + }, + [0xFEAB]={ + category="lo", + description="ARABIC LETTER THAL ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0630 }, + unicodeslot=0xFEAB, + }, + [0xFEAC]={ + category="lo", + description="ARABIC LETTER THAL FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0630 }, + unicodeslot=0xFEAC, + }, + [0xFEAD]={ + category="lo", + description="ARABIC LETTER REH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0631 }, + unicodeslot=0xFEAD, + }, + [0xFEAE]={ + category="lo", + description="ARABIC LETTER REH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0631 }, + unicodeslot=0xFEAE, + }, + [0xFEAF]={ + category="lo", + description="ARABIC LETTER ZAIN ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0632 }, + unicodeslot=0xFEAF, + }, + [0xFEB0]={ + category="lo", + description="ARABIC LETTER ZAIN FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0632 }, + unicodeslot=0xFEB0, + }, + [0xFEB1]={ + category="lo", + description="ARABIC LETTER SEEN ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0633 }, + unicodeslot=0xFEB1, + }, + [0xFEB2]={ + category="lo", + description="ARABIC LETTER SEEN FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0633 }, + unicodeslot=0xFEB2, + }, + [0xFEB3]={ + category="lo", + description="ARABIC LETTER SEEN INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0633 }, + unicodeslot=0xFEB3, + }, + [0xFEB4]={ + category="lo", + description="ARABIC LETTER SEEN MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0633 }, + unicodeslot=0xFEB4, + }, + [0xFEB5]={ + category="lo", + description="ARABIC LETTER SHEEN ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0634 }, + unicodeslot=0xFEB5, + }, + [0xFEB6]={ + category="lo", + description="ARABIC LETTER SHEEN FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0634 }, + unicodeslot=0xFEB6, + }, + [0xFEB7]={ + category="lo", + description="ARABIC LETTER SHEEN INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0634 }, + unicodeslot=0xFEB7, + }, + [0xFEB8]={ + category="lo", + description="ARABIC LETTER SHEEN MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0634 }, + unicodeslot=0xFEB8, + }, + [0xFEB9]={ + category="lo", + description="ARABIC LETTER SAD ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0635 }, + unicodeslot=0xFEB9, + }, + [0xFEBA]={ + category="lo", + description="ARABIC LETTER SAD FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0635 }, + unicodeslot=0xFEBA, + }, + [0xFEBB]={ + category="lo", + description="ARABIC LETTER SAD INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0635 }, + unicodeslot=0xFEBB, + }, + [0xFEBC]={ + category="lo", + description="ARABIC LETTER SAD MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0635 }, + unicodeslot=0xFEBC, + }, + [0xFEBD]={ + category="lo", + description="ARABIC LETTER DAD ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0636 }, + unicodeslot=0xFEBD, + }, + [0xFEBE]={ + category="lo", + description="ARABIC LETTER DAD FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0636 }, + unicodeslot=0xFEBE, + }, + [0xFEBF]={ + category="lo", + description="ARABIC LETTER DAD INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0636 }, + unicodeslot=0xFEBF, + }, + [0xFEC0]={ + category="lo", + description="ARABIC LETTER DAD MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0636 }, + unicodeslot=0xFEC0, + }, + [0xFEC1]={ + category="lo", + description="ARABIC LETTER TAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0637 }, + unicodeslot=0xFEC1, + }, + [0xFEC2]={ + category="lo", + description="ARABIC LETTER TAH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0637 }, + unicodeslot=0xFEC2, + }, + [0xFEC3]={ + category="lo", + description="ARABIC LETTER TAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0637 }, + unicodeslot=0xFEC3, + }, + [0xFEC4]={ + category="lo", + description="ARABIC LETTER TAH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0637 }, + unicodeslot=0xFEC4, + }, + [0xFEC5]={ + category="lo", + description="ARABIC LETTER ZAH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0638 }, + unicodeslot=0xFEC5, + }, + [0xFEC6]={ + category="lo", + description="ARABIC LETTER ZAH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0638 }, + unicodeslot=0xFEC6, + }, + [0xFEC7]={ + category="lo", + description="ARABIC LETTER ZAH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0638 }, + unicodeslot=0xFEC7, + }, + [0xFEC8]={ + category="lo", + description="ARABIC LETTER ZAH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0638 }, + unicodeslot=0xFEC8, + }, + [0xFEC9]={ + category="lo", + description="ARABIC LETTER AIN ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0639 }, + unicodeslot=0xFEC9, + }, + [0xFECA]={ + category="lo", + description="ARABIC LETTER AIN FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0639 }, + unicodeslot=0xFECA, + }, + [0xFECB]={ + category="lo", + description="ARABIC LETTER AIN INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0639 }, + unicodeslot=0xFECB, + }, + [0xFECC]={ + category="lo", + description="ARABIC LETTER AIN MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0639 }, + unicodeslot=0xFECC, + }, + [0xFECD]={ + category="lo", + description="ARABIC LETTER GHAIN ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x063A }, + unicodeslot=0xFECD, + }, + [0xFECE]={ + category="lo", + description="ARABIC LETTER GHAIN FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x063A }, + unicodeslot=0xFECE, + }, + [0xFECF]={ + category="lo", + description="ARABIC LETTER GHAIN INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x063A }, + unicodeslot=0xFECF, + }, + [0xFED0]={ + category="lo", + description="ARABIC LETTER GHAIN MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x063A }, + unicodeslot=0xFED0, + }, + [0xFED1]={ + category="lo", + description="ARABIC LETTER FEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0641 }, + unicodeslot=0xFED1, + }, + [0xFED2]={ + category="lo", + description="ARABIC LETTER FEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0641 }, + unicodeslot=0xFED2, + }, + [0xFED3]={ + category="lo", + description="ARABIC LETTER FEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0641 }, + unicodeslot=0xFED3, + }, + [0xFED4]={ + category="lo", + description="ARABIC LETTER FEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0641 }, + unicodeslot=0xFED4, + }, + [0xFED5]={ + category="lo", + description="ARABIC LETTER QAF ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0642 }, + unicodeslot=0xFED5, + }, + [0xFED6]={ + category="lo", + description="ARABIC LETTER QAF FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0642 }, + unicodeslot=0xFED6, + }, + [0xFED7]={ + category="lo", + description="ARABIC LETTER QAF INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0642 }, + unicodeslot=0xFED7, + }, + [0xFED8]={ + category="lo", + description="ARABIC LETTER QAF MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0642 }, + unicodeslot=0xFED8, + }, + [0xFED9]={ + category="lo", + description="ARABIC LETTER KAF ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0643 }, + unicodeslot=0xFED9, + }, + [0xFEDA]={ + category="lo", + description="ARABIC LETTER KAF FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0643 }, + unicodeslot=0xFEDA, + }, + [0xFEDB]={ + category="lo", + description="ARABIC LETTER KAF INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0643 }, + unicodeslot=0xFEDB, + }, + [0xFEDC]={ + category="lo", + description="ARABIC LETTER KAF MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0643 }, + unicodeslot=0xFEDC, + }, + [0xFEDD]={ + category="lo", + description="ARABIC LETTER LAM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0644 }, + unicodeslot=0xFEDD, + }, + [0xFEDE]={ + category="lo", + description="ARABIC LETTER LAM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0644 }, + unicodeslot=0xFEDE, + }, + [0xFEDF]={ + category="lo", + description="ARABIC LETTER LAM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0644 }, + unicodeslot=0xFEDF, + }, + [0xFEE0]={ + category="lo", + description="ARABIC LETTER LAM MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0644 }, + unicodeslot=0xFEE0, + }, + [0xFEE1]={ + category="lo", + description="ARABIC LETTER MEEM ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0645 }, + unicodeslot=0xFEE1, + }, + [0xFEE2]={ + category="lo", + description="ARABIC LETTER MEEM FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0645 }, + unicodeslot=0xFEE2, + }, + [0xFEE3]={ + category="lo", + description="ARABIC LETTER MEEM INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0645 }, + unicodeslot=0xFEE3, + }, + [0xFEE4]={ + category="lo", + description="ARABIC LETTER MEEM MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0645 }, + unicodeslot=0xFEE4, + }, + [0xFEE5]={ + category="lo", + description="ARABIC LETTER NOON ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0646 }, + unicodeslot=0xFEE5, + }, + [0xFEE6]={ + category="lo", + description="ARABIC LETTER NOON FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0646 }, + unicodeslot=0xFEE6, + }, + [0xFEE7]={ + category="lo", + description="ARABIC LETTER NOON INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0646 }, + unicodeslot=0xFEE7, + }, + [0xFEE8]={ + category="lo", + description="ARABIC LETTER NOON MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0646 }, + unicodeslot=0xFEE8, + }, + [0xFEE9]={ + category="lo", + description="ARABIC LETTER HEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0647 }, + unicodeslot=0xFEE9, + }, + [0xFEEA]={ + category="lo", + description="ARABIC LETTER HEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0647 }, + unicodeslot=0xFEEA, + }, + [0xFEEB]={ + category="lo", + description="ARABIC LETTER HEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x0647 }, + unicodeslot=0xFEEB, + }, + [0xFEEC]={ + category="lo", + description="ARABIC LETTER HEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x0647 }, + unicodeslot=0xFEEC, + }, + [0xFEED]={ + category="lo", + description="ARABIC LETTER WAW ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0648 }, + unicodeslot=0xFEED, + }, + [0xFEEE]={ + category="lo", + description="ARABIC LETTER WAW FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0648 }, + unicodeslot=0xFEEE, + }, + [0xFEEF]={ + category="lo", + description="ARABIC LETTER ALEF MAKSURA ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0649 }, + unicodeslot=0xFEEF, + }, + [0xFEF0]={ + category="lo", + description="ARABIC LETTER ALEF MAKSURA FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0649 }, + unicodeslot=0xFEF0, + }, + [0xFEF1]={ + category="lo", + description="ARABIC LETTER YEH ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x064A }, + unicodeslot=0xFEF1, + }, + [0xFEF2]={ + category="lo", + description="ARABIC LETTER YEH FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x064A }, + unicodeslot=0xFEF2, + }, + [0xFEF3]={ + category="lo", + description="ARABIC LETTER YEH INITIAL FORM", + direction="al", + linebreak="al", + specials={ "initial", 0x064A }, + unicodeslot=0xFEF3, + }, + [0xFEF4]={ + category="lo", + description="ARABIC LETTER YEH MEDIAL FORM", + direction="al", + linebreak="al", + specials={ "medial", 0x064A }, + unicodeslot=0xFEF4, + }, + [0xFEF5]={ + category="lo", + description="ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0644, 0x0622 }, + unicodeslot=0xFEF5, + }, + [0xFEF6]={ + category="lo", + description="ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0644, 0x0622 }, + unicodeslot=0xFEF6, + }, + [0xFEF7]={ + category="lo", + description="ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0644, 0x0623 }, + unicodeslot=0xFEF7, + }, + [0xFEF8]={ + category="lo", + description="ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0644, 0x0623 }, + unicodeslot=0xFEF8, + }, + [0xFEF9]={ + category="lo", + description="ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0644, 0x0625 }, + unicodeslot=0xFEF9, + }, + [0xFEFA]={ + category="lo", + description="ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0644, 0x0625 }, + unicodeslot=0xFEFA, + }, + [0xFEFB]={ + category="lo", + description="ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM", + direction="al", + linebreak="al", + specials={ "isolated", 0x0644, 0x0627 }, + unicodeslot=0xFEFB, + }, + [0xFEFC]={ + category="lo", + description="ARABIC LIGATURE LAM WITH ALEF FINAL FORM", + direction="al", + linebreak="al", + specials={ "final", 0x0644, 0x0627 }, + unicodeslot=0xFEFC, + }, + [0xFEFF]={ + category="cf", + contextname="zerowidthnobreakspace", + description="ZERO WIDTH NO-BREAK SPACE", + direction="bn", + linebreak="wj", + unicodeslot=0xFEFF, + }, + [0xFF01]={ + category="po", + cjkwd="f", + description="FULLWIDTH EXCLAMATION MARK", + direction="on", + linebreak="ex", + specials={ "wide", 0x0021 }, + unicodeslot=0xFF01, + }, + [0xFF02]={ + category="po", + cjkwd="f", + description="FULLWIDTH QUOTATION MARK", + direction="on", + linebreak="id", + specials={ "wide", 0x0022 }, + unicodeslot=0xFF02, + }, + [0xFF03]={ + category="po", + cjkwd="f", + description="FULLWIDTH NUMBER SIGN", + direction="et", + linebreak="id", + specials={ "wide", 0x0023 }, + unicodeslot=0xFF03, + }, + [0xFF04]={ + category="sc", + cjkwd="f", + description="FULLWIDTH DOLLAR SIGN", + direction="et", + linebreak="pr", + specials={ "wide", 0x0024 }, + unicodeslot=0xFF04, + }, + [0xFF05]={ + category="po", + cjkwd="f", + description="FULLWIDTH PERCENT SIGN", + direction="et", + linebreak="po", + specials={ "wide", 0x0025 }, + unicodeslot=0xFF05, + }, + [0xFF06]={ + category="po", + cjkwd="f", + description="FULLWIDTH AMPERSAND", + direction="on", + linebreak="id", + specials={ "wide", 0x0026 }, + unicodeslot=0xFF06, + }, + [0xFF07]={ + category="po", + cjkwd="f", + description="FULLWIDTH APOSTROPHE", + direction="on", + linebreak="id", + specials={ "wide", 0x0027 }, + unicodeslot=0xFF07, + }, + [0xFF08]={ + category="ps", + cjkwd="f", + description="FULLWIDTH LEFT PARENTHESIS", + direction="on", + linebreak="op", + mirror=0xFF09, + specials={ "wide", 0x0028 }, + unicodeslot=0xFF08, + }, + [0xFF09]={ + category="pe", + cjkwd="f", + description="FULLWIDTH RIGHT PARENTHESIS", + direction="on", + linebreak="cl", + mirror=0xFF08, + specials={ "wide", 0x0029 }, + unicodeslot=0xFF09, + }, + [0xFF0A]={ + category="po", + cjkwd="f", + description="FULLWIDTH ASTERISK", + direction="on", + linebreak="id", + specials={ "wide", 0x002A }, + unicodeslot=0xFF0A, + }, + [0xFF0B]={ + category="sm", + cjkwd="f", + description="FULLWIDTH PLUS SIGN", + direction="es", + linebreak="id", + specials={ "wide", 0x002B }, + unicodeslot=0xFF0B, + }, + [0xFF0C]={ + category="po", + cjkwd="f", + description="FULLWIDTH COMMA", + direction="cs", + linebreak="cl", + specials={ "wide", 0x002C }, + unicodeslot=0xFF0C, + }, + [0xFF0D]={ + category="pd", + cjkwd="f", + description="FULLWIDTH HYPHEN-MINUS", + direction="es", + linebreak="id", + specials={ "wide", 0x002D }, + unicodeslot=0xFF0D, + }, + [0xFF0E]={ + category="po", + cjkwd="f", + description="FULLWIDTH FULL STOP", + direction="cs", + linebreak="cl", + specials={ "wide", 0x002E }, + unicodeslot=0xFF0E, + }, + [0xFF0F]={ + category="po", + cjkwd="f", + description="FULLWIDTH SOLIDUS", + direction="cs", + linebreak="id", + specials={ "wide", 0x002F }, + unicodeslot=0xFF0F, + }, + [0xFF10]={ + category="nd", + cjkwd="f", + description="FULLWIDTH DIGIT ZERO", + direction="en", + linebreak="id", + specials={ "wide", 0x0030 }, + unicodeslot=0xFF10, + }, + [0xFF11]={ + category="nd", + cjkwd="f", + description="FULLWIDTH DIGIT ONE", + direction="en", + linebreak="id", + specials={ "wide", 0x0031 }, + unicodeslot=0xFF11, + }, + [0xFF12]={ + category="nd", + cjkwd="f", + description="FULLWIDTH DIGIT TWO", + direction="en", + linebreak="id", + specials={ "wide", 0x0032 }, + unicodeslot=0xFF12, + }, + [0xFF13]={ + category="nd", + cjkwd="f", + description="FULLWIDTH DIGIT THREE", + direction="en", + linebreak="id", + specials={ "wide", 0x0033 }, + unicodeslot=0xFF13, + }, + [0xFF14]={ + category="nd", + cjkwd="f", + description="FULLWIDTH DIGIT FOUR", + direction="en", + linebreak="id", + specials={ "wide", 0x0034 }, + unicodeslot=0xFF14, + }, + [0xFF15]={ + category="nd", + cjkwd="f", + description="FULLWIDTH DIGIT FIVE", + direction="en", + linebreak="id", + specials={ "wide", 0x0035 }, + unicodeslot=0xFF15, + }, + [0xFF16]={ + category="nd", + cjkwd="f", + description="FULLWIDTH DIGIT SIX", + direction="en", + linebreak="id", + specials={ "wide", 0x0036 }, + unicodeslot=0xFF16, + }, + [0xFF17]={ + category="nd", + cjkwd="f", + description="FULLWIDTH DIGIT SEVEN", + direction="en", + linebreak="id", + specials={ "wide", 0x0037 }, + unicodeslot=0xFF17, + }, + [0xFF18]={ + category="nd", + cjkwd="f", + description="FULLWIDTH DIGIT EIGHT", + direction="en", + linebreak="id", + specials={ "wide", 0x0038 }, + unicodeslot=0xFF18, + }, + [0xFF19]={ + category="nd", + cjkwd="f", + description="FULLWIDTH DIGIT NINE", + direction="en", + linebreak="id", + specials={ "wide", 0x0039 }, + unicodeslot=0xFF19, + }, + [0xFF1A]={ + category="po", + cjkwd="f", + description="FULLWIDTH COLON", + direction="cs", + linebreak="ns", + specials={ "wide", 0x003A }, + unicodeslot=0xFF1A, + }, + [0xFF1B]={ + category="po", + cjkwd="f", + description="FULLWIDTH SEMICOLON", + direction="on", + linebreak="ns", + specials={ "wide", 0x003B }, + unicodeslot=0xFF1B, + }, + [0xFF1C]={ + category="sm", + cjkwd="f", + description="FULLWIDTH LESS-THAN SIGN", + direction="on", + linebreak="id", + mirror=0xFF1E, + specials={ "wide", 0x003C }, + unicodeslot=0xFF1C, + }, + [0xFF1D]={ + category="sm", + cjkwd="f", + description="FULLWIDTH EQUALS SIGN", + direction="on", + linebreak="id", + specials={ "wide", 0x003D }, + unicodeslot=0xFF1D, + }, + [0xFF1E]={ + category="sm", + cjkwd="f", + description="FULLWIDTH GREATER-THAN SIGN", + direction="on", + linebreak="id", + mirror=0xFF1C, + specials={ "wide", 0x003E }, + unicodeslot=0xFF1E, + }, + [0xFF1F]={ + category="po", + cjkwd="f", + description="FULLWIDTH QUESTION MARK", + direction="on", + linebreak="ex", + specials={ "wide", 0x003F }, + unicodeslot=0xFF1F, + }, + [0xFF20]={ + category="po", + cjkwd="f", + description="FULLWIDTH COMMERCIAL AT", + direction="on", + linebreak="id", + specials={ "wide", 0x0040 }, + unicodeslot=0xFF20, + }, + [0xFF21]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER A", + direction="l", + lccode=0xFF41, + linebreak="id", + specials={ "wide", 0x0041 }, + unicodeslot=0xFF21, + }, + [0xFF22]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER B", + direction="l", + lccode=0xFF42, + linebreak="id", + specials={ "wide", 0x0042 }, + unicodeslot=0xFF22, + }, + [0xFF23]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER C", + direction="l", + lccode=0xFF43, + linebreak="id", + specials={ "wide", 0x0043 }, + unicodeslot=0xFF23, + }, + [0xFF24]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER D", + direction="l", + lccode=0xFF44, + linebreak="id", + specials={ "wide", 0x0044 }, + unicodeslot=0xFF24, + }, + [0xFF25]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER E", + direction="l", + lccode=0xFF45, + linebreak="id", + specials={ "wide", 0x0045 }, + unicodeslot=0xFF25, + }, + [0xFF26]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER F", + direction="l", + lccode=0xFF46, + linebreak="id", + specials={ "wide", 0x0046 }, + unicodeslot=0xFF26, + }, + [0xFF27]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER G", + direction="l", + lccode=0xFF47, + linebreak="id", + specials={ "wide", 0x0047 }, + unicodeslot=0xFF27, + }, + [0xFF28]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER H", + direction="l", + lccode=0xFF48, + linebreak="id", + specials={ "wide", 0x0048 }, + unicodeslot=0xFF28, + }, + [0xFF29]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER I", + direction="l", + lccode=0xFF49, + linebreak="id", + specials={ "wide", 0x0049 }, + unicodeslot=0xFF29, + }, + [0xFF2A]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER J", + direction="l", + lccode=0xFF4A, + linebreak="id", + specials={ "wide", 0x004A }, + unicodeslot=0xFF2A, + }, + [0xFF2B]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER K", + direction="l", + lccode=0xFF4B, + linebreak="id", + specials={ "wide", 0x004B }, + unicodeslot=0xFF2B, + }, + [0xFF2C]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER L", + direction="l", + lccode=0xFF4C, + linebreak="id", + specials={ "wide", 0x004C }, + unicodeslot=0xFF2C, + }, + [0xFF2D]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER M", + direction="l", + lccode=0xFF4D, + linebreak="id", + specials={ "wide", 0x004D }, + unicodeslot=0xFF2D, + }, + [0xFF2E]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER N", + direction="l", + lccode=0xFF4E, + linebreak="id", + specials={ "wide", 0x004E }, + unicodeslot=0xFF2E, + }, + [0xFF2F]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER O", + direction="l", + lccode=0xFF4F, + linebreak="id", + specials={ "wide", 0x004F }, + unicodeslot=0xFF2F, + }, + [0xFF30]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER P", + direction="l", + lccode=0xFF50, + linebreak="id", + specials={ "wide", 0x0050 }, + unicodeslot=0xFF30, + }, + [0xFF31]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER Q", + direction="l", + lccode=0xFF51, + linebreak="id", + specials={ "wide", 0x0051 }, + unicodeslot=0xFF31, + }, + [0xFF32]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER R", + direction="l", + lccode=0xFF52, + linebreak="id", + specials={ "wide", 0x0052 }, + unicodeslot=0xFF32, + }, + [0xFF33]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER S", + direction="l", + lccode=0xFF53, + linebreak="id", + specials={ "wide", 0x0053 }, + unicodeslot=0xFF33, + }, + [0xFF34]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER T", + direction="l", + lccode=0xFF54, + linebreak="id", + specials={ "wide", 0x0054 }, + unicodeslot=0xFF34, + }, + [0xFF35]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER U", + direction="l", + lccode=0xFF55, + linebreak="id", + specials={ "wide", 0x0055 }, + unicodeslot=0xFF35, + }, + [0xFF36]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER V", + direction="l", + lccode=0xFF56, + linebreak="id", + specials={ "wide", 0x0056 }, + unicodeslot=0xFF36, + }, + [0xFF37]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER W", + direction="l", + lccode=0xFF57, + linebreak="id", + specials={ "wide", 0x0057 }, + unicodeslot=0xFF37, + }, + [0xFF38]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER X", + direction="l", + lccode=0xFF58, + linebreak="id", + specials={ "wide", 0x0058 }, + unicodeslot=0xFF38, + }, + [0xFF39]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER Y", + direction="l", + lccode=0xFF59, + linebreak="id", + specials={ "wide", 0x0059 }, + unicodeslot=0xFF39, + }, + [0xFF3A]={ + category="lu", + cjkwd="f", + description="FULLWIDTH LATIN CAPITAL LETTER Z", + direction="l", + lccode=0xFF5A, + linebreak="id", + specials={ "wide", 0x005A }, + unicodeslot=0xFF3A, + }, + [0xFF3B]={ + category="ps", + cjkwd="f", + description="FULLWIDTH LEFT SQUARE BRACKET", + direction="on", + linebreak="op", + mirror=0xFF3D, + specials={ "wide", 0x005B }, + unicodeslot=0xFF3B, + }, + [0xFF3C]={ + category="po", + cjkwd="f", + description="FULLWIDTH REVERSE SOLIDUS", + direction="on", + linebreak="id", + specials={ "wide", 0x005C }, + unicodeslot=0xFF3C, + }, + [0xFF3D]={ + category="pe", + cjkwd="f", + description="FULLWIDTH RIGHT SQUARE BRACKET", + direction="on", + linebreak="cl", + mirror=0xFF3B, + specials={ "wide", 0x005D }, + unicodeslot=0xFF3D, + }, + [0xFF3E]={ + category="sk", + cjkwd="f", + description="FULLWIDTH CIRCUMFLEX ACCENT", + direction="on", + linebreak="id", + specials={ "wide", 0x005E }, + unicodeslot=0xFF3E, + }, + [0xFF3F]={ + category="pc", + cjkwd="f", + description="FULLWIDTH LOW LINE", + direction="on", + linebreak="id", + specials={ "wide", 0x005F }, + unicodeslot=0xFF3F, + }, + [0xFF40]={ + category="sk", + cjkwd="f", + description="FULLWIDTH GRAVE ACCENT", + direction="on", + linebreak="id", + specials={ "wide", 0x0060 }, + unicodeslot=0xFF40, + }, + [0xFF41]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER A", + direction="l", + linebreak="id", + specials={ "wide", 0x0061 }, + uccode=0xFF21, + unicodeslot=0xFF41, + }, + [0xFF42]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER B", + direction="l", + linebreak="id", + specials={ "wide", 0x0062 }, + uccode=0xFF22, + unicodeslot=0xFF42, + }, + [0xFF43]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER C", + direction="l", + linebreak="id", + specials={ "wide", 0x0063 }, + uccode=0xFF23, + unicodeslot=0xFF43, + }, + [0xFF44]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER D", + direction="l", + linebreak="id", + specials={ "wide", 0x0064 }, + uccode=0xFF24, + unicodeslot=0xFF44, + }, + [0xFF45]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER E", + direction="l", + linebreak="id", + specials={ "wide", 0x0065 }, + uccode=0xFF25, + unicodeslot=0xFF45, + }, + [0xFF46]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER F", + direction="l", + linebreak="id", + specials={ "wide", 0x0066 }, + uccode=0xFF26, + unicodeslot=0xFF46, + }, + [0xFF47]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER G", + direction="l", + linebreak="id", + specials={ "wide", 0x0067 }, + uccode=0xFF27, + unicodeslot=0xFF47, + }, + [0xFF48]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER H", + direction="l", + linebreak="id", + specials={ "wide", 0x0068 }, + uccode=0xFF28, + unicodeslot=0xFF48, + }, + [0xFF49]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER I", + direction="l", + linebreak="id", + specials={ "wide", 0x0069 }, + uccode=0xFF29, + unicodeslot=0xFF49, + }, + [0xFF4A]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER J", + direction="l", + linebreak="id", + specials={ "wide", 0x006A }, + uccode=0xFF2A, + unicodeslot=0xFF4A, + }, + [0xFF4B]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER K", + direction="l", + linebreak="id", + specials={ "wide", 0x006B }, + uccode=0xFF2B, + unicodeslot=0xFF4B, + }, + [0xFF4C]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER L", + direction="l", + linebreak="id", + specials={ "wide", 0x006C }, + uccode=0xFF2C, + unicodeslot=0xFF4C, + }, + [0xFF4D]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER M", + direction="l", + linebreak="id", + specials={ "wide", 0x006D }, + uccode=0xFF2D, + unicodeslot=0xFF4D, + }, + [0xFF4E]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER N", + direction="l", + linebreak="id", + specials={ "wide", 0x006E }, + uccode=0xFF2E, + unicodeslot=0xFF4E, + }, + [0xFF4F]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER O", + direction="l", + linebreak="id", + specials={ "wide", 0x006F }, + uccode=0xFF2F, + unicodeslot=0xFF4F, + }, + [0xFF50]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER P", + direction="l", + linebreak="id", + specials={ "wide", 0x0070 }, + uccode=0xFF30, + unicodeslot=0xFF50, + }, + [0xFF51]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER Q", + direction="l", + linebreak="id", + specials={ "wide", 0x0071 }, + uccode=0xFF31, + unicodeslot=0xFF51, + }, + [0xFF52]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER R", + direction="l", + linebreak="id", + specials={ "wide", 0x0072 }, + uccode=0xFF32, + unicodeslot=0xFF52, + }, + [0xFF53]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER S", + direction="l", + linebreak="id", + specials={ "wide", 0x0073 }, + uccode=0xFF33, + unicodeslot=0xFF53, + }, + [0xFF54]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER T", + direction="l", + linebreak="id", + specials={ "wide", 0x0074 }, + uccode=0xFF34, + unicodeslot=0xFF54, + }, + [0xFF55]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER U", + direction="l", + linebreak="id", + specials={ "wide", 0x0075 }, + uccode=0xFF35, + unicodeslot=0xFF55, + }, + [0xFF56]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER V", + direction="l", + linebreak="id", + specials={ "wide", 0x0076 }, + uccode=0xFF36, + unicodeslot=0xFF56, + }, + [0xFF57]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER W", + direction="l", + linebreak="id", + specials={ "wide", 0x0077 }, + uccode=0xFF37, + unicodeslot=0xFF57, + }, + [0xFF58]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER X", + direction="l", + linebreak="id", + specials={ "wide", 0x0078 }, + uccode=0xFF38, + unicodeslot=0xFF58, + }, + [0xFF59]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER Y", + direction="l", + linebreak="id", + specials={ "wide", 0x0079 }, + uccode=0xFF39, + unicodeslot=0xFF59, + }, + [0xFF5A]={ + category="ll", + cjkwd="f", + description="FULLWIDTH LATIN SMALL LETTER Z", + direction="l", + linebreak="id", + specials={ "wide", 0x007A }, + uccode=0xFF3A, + unicodeslot=0xFF5A, + }, + [0xFF5B]={ + category="ps", + cjkwd="f", + description="FULLWIDTH LEFT CURLY BRACKET", + direction="on", + linebreak="op", + mirror=0xFF5D, + specials={ "wide", 0x007B }, + unicodeslot=0xFF5B, + }, + [0xFF5C]={ + category="sm", + cjkwd="f", + description="FULLWIDTH VERTICAL LINE", + direction="on", + linebreak="id", + specials={ "wide", 0x007C }, + unicodeslot=0xFF5C, + }, + [0xFF5D]={ + category="pe", + cjkwd="f", + description="FULLWIDTH RIGHT CURLY BRACKET", + direction="on", + linebreak="cl", + mirror=0xFF5B, + specials={ "wide", 0x007D }, + unicodeslot=0xFF5D, + }, + [0xFF5E]={ + category="sm", + cjkwd="f", + description="FULLWIDTH TILDE", + direction="on", + linebreak="id", + specials={ "wide", 0x007E }, + unicodeslot=0xFF5E, + }, + [0xFF5F]={ + category="ps", + cjkwd="f", + description="FULLWIDTH LEFT WHITE PARENTHESIS", + direction="on", + linebreak="op", + mirror=0xFF60, + specials={ "wide", 0x2985 }, + unicodeslot=0xFF5F, + }, + [0xFF60]={ + category="pe", + cjkwd="f", + description="FULLWIDTH RIGHT WHITE PARENTHESIS", + direction="on", + linebreak="cl", + mirror=0xFF5F, + specials={ "wide", 0x2986 }, + unicodeslot=0xFF60, + }, + [0xFF61]={ + category="po", + cjkwd="h", + description="HALFWIDTH IDEOGRAPHIC FULL STOP", + direction="on", + linebreak="cl", + specials={ "narrow", 0x3002 }, + unicodeslot=0xFF61, + }, + [0xFF62]={ + category="ps", + cjkwd="h", + description="HALFWIDTH LEFT CORNER BRACKET", + direction="on", + linebreak="op", + mirror=0xFF63, + specials={ "narrow", 0x300C }, + unicodeslot=0xFF62, + }, + [0xFF63]={ + category="pe", + cjkwd="h", + description="HALFWIDTH RIGHT CORNER BRACKET", + direction="on", + linebreak="cl", + mirror=0xFF62, + specials={ "narrow", 0x300D }, + unicodeslot=0xFF63, + }, + [0xFF64]={ + category="po", + cjkwd="h", + description="HALFWIDTH IDEOGRAPHIC COMMA", + direction="on", + linebreak="cl", + specials={ "narrow", 0x3001 }, + unicodeslot=0xFF64, + }, + [0xFF65]={ + category="po", + cjkwd="h", + description="HALFWIDTH KATAKANA MIDDLE DOT", + direction="on", + linebreak="ns", + specials={ "narrow", 0x30FB }, + unicodeslot=0xFF65, + }, + [0xFF66]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER WO", + direction="l", + linebreak="al", + specials={ "narrow", 0x30F2 }, + unicodeslot=0xFF66, + }, + [0xFF67]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER SMALL A", + direction="l", + linebreak="ns", + specials={ "narrow", 0x30A1 }, + unicodeslot=0xFF67, + }, + [0xFF68]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER SMALL I", + direction="l", + linebreak="ns", + specials={ "narrow", 0x30A3 }, + unicodeslot=0xFF68, + }, + [0xFF69]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER SMALL U", + direction="l", + linebreak="ns", + specials={ "narrow", 0x30A5 }, + unicodeslot=0xFF69, + }, + [0xFF6A]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER SMALL E", + direction="l", + linebreak="ns", + specials={ "narrow", 0x30A7 }, + unicodeslot=0xFF6A, + }, + [0xFF6B]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER SMALL O", + direction="l", + linebreak="ns", + specials={ "narrow", 0x30A9 }, + unicodeslot=0xFF6B, + }, + [0xFF6C]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER SMALL YA", + direction="l", + linebreak="ns", + specials={ "narrow", 0x30E3 }, + unicodeslot=0xFF6C, + }, + [0xFF6D]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER SMALL YU", + direction="l", + linebreak="ns", + specials={ "narrow", 0x30E5 }, + unicodeslot=0xFF6D, + }, + [0xFF6E]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER SMALL YO", + direction="l", + linebreak="ns", + specials={ "narrow", 0x30E7 }, + unicodeslot=0xFF6E, + }, + [0xFF6F]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER SMALL TU", + direction="l", + linebreak="ns", + specials={ "narrow", 0x30C3 }, + unicodeslot=0xFF6F, + }, + [0xFF70]={ + category="lm", + cjkwd="h", + description="HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK", + direction="l", + linebreak="ns", + specials={ "narrow", 0x30FC }, + unicodeslot=0xFF70, + }, + [0xFF71]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER A", + direction="l", + linebreak="al", + specials={ "narrow", 0x30A2 }, + unicodeslot=0xFF71, + }, + [0xFF72]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER I", + direction="l", + linebreak="al", + specials={ "narrow", 0x30A4 }, + unicodeslot=0xFF72, + }, + [0xFF73]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER U", + direction="l", + linebreak="al", + specials={ "narrow", 0x30A6 }, + unicodeslot=0xFF73, + }, + [0xFF74]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER E", + direction="l", + linebreak="al", + specials={ "narrow", 0x30A8 }, + unicodeslot=0xFF74, + }, + [0xFF75]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER O", + direction="l", + linebreak="al", + specials={ "narrow", 0x30AA }, + unicodeslot=0xFF75, + }, + [0xFF76]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER KA", + direction="l", + linebreak="al", + specials={ "narrow", 0x30AB }, + unicodeslot=0xFF76, + }, + [0xFF77]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER KI", + direction="l", + linebreak="al", + specials={ "narrow", 0x30AD }, + unicodeslot=0xFF77, + }, + [0xFF78]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER KU", + direction="l", + linebreak="al", + specials={ "narrow", 0x30AF }, + unicodeslot=0xFF78, + }, + [0xFF79]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER KE", + direction="l", + linebreak="al", + specials={ "narrow", 0x30B1 }, + unicodeslot=0xFF79, + }, + [0xFF7A]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER KO", + direction="l", + linebreak="al", + specials={ "narrow", 0x30B3 }, + unicodeslot=0xFF7A, + }, + [0xFF7B]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER SA", + direction="l", + linebreak="al", + specials={ "narrow", 0x30B5 }, + unicodeslot=0xFF7B, + }, + [0xFF7C]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER SI", + direction="l", + linebreak="al", + specials={ "narrow", 0x30B7 }, + unicodeslot=0xFF7C, + }, + [0xFF7D]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER SU", + direction="l", + linebreak="al", + specials={ "narrow", 0x30B9 }, + unicodeslot=0xFF7D, + }, + [0xFF7E]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER SE", + direction="l", + linebreak="al", + specials={ "narrow", 0x30BB }, + unicodeslot=0xFF7E, + }, + [0xFF7F]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER SO", + direction="l", + linebreak="al", + specials={ "narrow", 0x30BD }, + unicodeslot=0xFF7F, + }, + [0xFF80]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER TA", + direction="l", + linebreak="al", + specials={ "narrow", 0x30BF }, + unicodeslot=0xFF80, + }, + [0xFF81]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER TI", + direction="l", + linebreak="al", + specials={ "narrow", 0x30C1 }, + unicodeslot=0xFF81, + }, + [0xFF82]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER TU", + direction="l", + linebreak="al", + specials={ "narrow", 0x30C4 }, + unicodeslot=0xFF82, + }, + [0xFF83]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER TE", + direction="l", + linebreak="al", + specials={ "narrow", 0x30C6 }, + unicodeslot=0xFF83, + }, + [0xFF84]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER TO", + direction="l", + linebreak="al", + specials={ "narrow", 0x30C8 }, + unicodeslot=0xFF84, + }, + [0xFF85]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER NA", + direction="l", + linebreak="al", + specials={ "narrow", 0x30CA }, + unicodeslot=0xFF85, + }, + [0xFF86]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER NI", + direction="l", + linebreak="al", + specials={ "narrow", 0x30CB }, + unicodeslot=0xFF86, + }, + [0xFF87]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER NU", + direction="l", + linebreak="al", + specials={ "narrow", 0x30CC }, + unicodeslot=0xFF87, + }, + [0xFF88]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER NE", + direction="l", + linebreak="al", + specials={ "narrow", 0x30CD }, + unicodeslot=0xFF88, + }, + [0xFF89]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER NO", + direction="l", + linebreak="al", + specials={ "narrow", 0x30CE }, + unicodeslot=0xFF89, + }, + [0xFF8A]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER HA", + direction="l", + linebreak="al", + specials={ "narrow", 0x30CF }, + unicodeslot=0xFF8A, + }, + [0xFF8B]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER HI", + direction="l", + linebreak="al", + specials={ "narrow", 0x30D2 }, + unicodeslot=0xFF8B, + }, + [0xFF8C]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER HU", + direction="l", + linebreak="al", + specials={ "narrow", 0x30D5 }, + unicodeslot=0xFF8C, + }, + [0xFF8D]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER HE", + direction="l", + linebreak="al", + specials={ "narrow", 0x30D8 }, + unicodeslot=0xFF8D, + }, + [0xFF8E]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER HO", + direction="l", + linebreak="al", + specials={ "narrow", 0x30DB }, + unicodeslot=0xFF8E, + }, + [0xFF8F]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER MA", + direction="l", + linebreak="al", + specials={ "narrow", 0x30DE }, + unicodeslot=0xFF8F, + }, + [0xFF90]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER MI", + direction="l", + linebreak="al", + specials={ "narrow", 0x30DF }, + unicodeslot=0xFF90, + }, + [0xFF91]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER MU", + direction="l", + linebreak="al", + specials={ "narrow", 0x30E0 }, + unicodeslot=0xFF91, + }, + [0xFF92]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER ME", + direction="l", + linebreak="al", + specials={ "narrow", 0x30E1 }, + unicodeslot=0xFF92, + }, + [0xFF93]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER MO", + direction="l", + linebreak="al", + specials={ "narrow", 0x30E2 }, + unicodeslot=0xFF93, + }, + [0xFF94]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER YA", + direction="l", + linebreak="al", + specials={ "narrow", 0x30E4 }, + unicodeslot=0xFF94, + }, + [0xFF95]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER YU", + direction="l", + linebreak="al", + specials={ "narrow", 0x30E6 }, + unicodeslot=0xFF95, + }, + [0xFF96]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER YO", + direction="l", + linebreak="al", + specials={ "narrow", 0x30E8 }, + unicodeslot=0xFF96, + }, + [0xFF97]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER RA", + direction="l", + linebreak="al", + specials={ "narrow", 0x30E9 }, + unicodeslot=0xFF97, + }, + [0xFF98]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER RI", + direction="l", + linebreak="al", + specials={ "narrow", 0x30EA }, + unicodeslot=0xFF98, + }, + [0xFF99]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER RU", + direction="l", + linebreak="al", + specials={ "narrow", 0x30EB }, + unicodeslot=0xFF99, + }, + [0xFF9A]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER RE", + direction="l", + linebreak="al", + specials={ "narrow", 0x30EC }, + unicodeslot=0xFF9A, + }, + [0xFF9B]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER RO", + direction="l", + linebreak="al", + specials={ "narrow", 0x30ED }, + unicodeslot=0xFF9B, + }, + [0xFF9C]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER WA", + direction="l", + linebreak="al", + specials={ "narrow", 0x30EF }, + unicodeslot=0xFF9C, + }, + [0xFF9D]={ + category="lo", + cjkwd="h", + description="HALFWIDTH KATAKANA LETTER N", + direction="l", + linebreak="al", + specials={ "narrow", 0x30F3 }, + unicodeslot=0xFF9D, + }, + [0xFF9E]={ + category="lm", + cjkwd="h", + description="HALFWIDTH KATAKANA VOICED SOUND MARK", + direction="l", + linebreak="ns", + specials={ "narrow", 0x3099 }, + unicodeslot=0xFF9E, + }, + [0xFF9F]={ + category="lm", + cjkwd="h", + description="HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK", + direction="l", + linebreak="ns", + specials={ "narrow", 0x309A }, + unicodeslot=0xFF9F, + }, + [0xFFA0]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL FILLER", + direction="l", + linebreak="al", + specials={ "narrow", 0x3164 }, + unicodeslot=0xFFA0, + }, + [0xFFA1]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER KIYEOK", + direction="l", + linebreak="al", + specials={ "narrow", 0x3131 }, + unicodeslot=0xFFA1, + }, + [0xFFA2]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER SSANGKIYEOK", + direction="l", + linebreak="al", + specials={ "narrow", 0x3132 }, + unicodeslot=0xFFA2, + }, + [0xFFA3]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER KIYEOK-SIOS", + direction="l", + linebreak="al", + specials={ "narrow", 0x3133 }, + unicodeslot=0xFFA3, + }, + [0xFFA4]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER NIEUN", + direction="l", + linebreak="al", + specials={ "narrow", 0x3134 }, + unicodeslot=0xFFA4, + }, + [0xFFA5]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER NIEUN-CIEUC", + direction="l", + linebreak="al", + specials={ "narrow", 0x3135 }, + unicodeslot=0xFFA5, + }, + [0xFFA6]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER NIEUN-HIEUH", + direction="l", + linebreak="al", + specials={ "narrow", 0x3136 }, + unicodeslot=0xFFA6, + }, + [0xFFA7]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER TIKEUT", + direction="l", + linebreak="al", + specials={ "narrow", 0x3137 }, + unicodeslot=0xFFA7, + }, + [0xFFA8]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER SSANGTIKEUT", + direction="l", + linebreak="al", + specials={ "narrow", 0x3138 }, + unicodeslot=0xFFA8, + }, + [0xFFA9]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER RIEUL", + direction="l", + linebreak="al", + specials={ "narrow", 0x3139 }, + unicodeslot=0xFFA9, + }, + [0xFFAA]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER RIEUL-KIYEOK", + direction="l", + linebreak="al", + specials={ "narrow", 0x313A }, + unicodeslot=0xFFAA, + }, + [0xFFAB]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER RIEUL-MIEUM", + direction="l", + linebreak="al", + specials={ "narrow", 0x313B }, + unicodeslot=0xFFAB, + }, + [0xFFAC]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER RIEUL-PIEUP", + direction="l", + linebreak="al", + specials={ "narrow", 0x313C }, + unicodeslot=0xFFAC, + }, + [0xFFAD]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER RIEUL-SIOS", + direction="l", + linebreak="al", + specials={ "narrow", 0x313D }, + unicodeslot=0xFFAD, + }, + [0xFFAE]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER RIEUL-THIEUTH", + direction="l", + linebreak="al", + specials={ "narrow", 0x313E }, + unicodeslot=0xFFAE, + }, + [0xFFAF]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER RIEUL-PHIEUPH", + direction="l", + linebreak="al", + specials={ "narrow", 0x313F }, + unicodeslot=0xFFAF, + }, + [0xFFB0]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER RIEUL-HIEUH", + direction="l", + linebreak="al", + specials={ "narrow", 0x3140 }, + unicodeslot=0xFFB0, + }, + [0xFFB1]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER MIEUM", + direction="l", + linebreak="al", + specials={ "narrow", 0x3141 }, + unicodeslot=0xFFB1, + }, + [0xFFB2]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER PIEUP", + direction="l", + linebreak="al", + specials={ "narrow", 0x3142 }, + unicodeslot=0xFFB2, + }, + [0xFFB3]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER SSANGPIEUP", + direction="l", + linebreak="al", + specials={ "narrow", 0x3143 }, + unicodeslot=0xFFB3, + }, + [0xFFB4]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER PIEUP-SIOS", + direction="l", + linebreak="al", + specials={ "narrow", 0x3144 }, + unicodeslot=0xFFB4, + }, + [0xFFB5]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER SIOS", + direction="l", + linebreak="al", + specials={ "narrow", 0x3145 }, + unicodeslot=0xFFB5, + }, + [0xFFB6]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER SSANGSIOS", + direction="l", + linebreak="al", + specials={ "narrow", 0x3146 }, + unicodeslot=0xFFB6, + }, + [0xFFB7]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER IEUNG", + direction="l", + linebreak="al", + specials={ "narrow", 0x3147 }, + unicodeslot=0xFFB7, + }, + [0xFFB8]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER CIEUC", + direction="l", + linebreak="al", + specials={ "narrow", 0x3148 }, + unicodeslot=0xFFB8, + }, + [0xFFB9]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER SSANGCIEUC", + direction="l", + linebreak="al", + specials={ "narrow", 0x3149 }, + unicodeslot=0xFFB9, + }, + [0xFFBA]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER CHIEUCH", + direction="l", + linebreak="al", + specials={ "narrow", 0x314A }, + unicodeslot=0xFFBA, + }, + [0xFFBB]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER KHIEUKH", + direction="l", + linebreak="al", + specials={ "narrow", 0x314B }, + unicodeslot=0xFFBB, + }, + [0xFFBC]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER THIEUTH", + direction="l", + linebreak="al", + specials={ "narrow", 0x314C }, + unicodeslot=0xFFBC, + }, + [0xFFBD]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER PHIEUPH", + direction="l", + linebreak="al", + specials={ "narrow", 0x314D }, + unicodeslot=0xFFBD, + }, + [0xFFBE]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER HIEUH", + direction="l", + linebreak="al", + specials={ "narrow", 0x314E }, + unicodeslot=0xFFBE, + }, + [0xFFC2]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER A", + direction="l", + linebreak="al", + specials={ "narrow", 0x314F }, + unicodeslot=0xFFC2, + }, + [0xFFC3]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER AE", + direction="l", + linebreak="al", + specials={ "narrow", 0x3150 }, + unicodeslot=0xFFC3, + }, + [0xFFC4]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER YA", + direction="l", + linebreak="al", + specials={ "narrow", 0x3151 }, + unicodeslot=0xFFC4, + }, + [0xFFC5]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER YAE", + direction="l", + linebreak="al", + specials={ "narrow", 0x3152 }, + unicodeslot=0xFFC5, + }, + [0xFFC6]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER EO", + direction="l", + linebreak="al", + specials={ "narrow", 0x3153 }, + unicodeslot=0xFFC6, + }, + [0xFFC7]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER E", + direction="l", + linebreak="al", + specials={ "narrow", 0x3154 }, + unicodeslot=0xFFC7, + }, + [0xFFCA]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER YEO", + direction="l", + linebreak="al", + specials={ "narrow", 0x3155 }, + unicodeslot=0xFFCA, + }, + [0xFFCB]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER YE", + direction="l", + linebreak="al", + specials={ "narrow", 0x3156 }, + unicodeslot=0xFFCB, + }, + [0xFFCC]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER O", + direction="l", + linebreak="al", + specials={ "narrow", 0x3157 }, + unicodeslot=0xFFCC, + }, + [0xFFCD]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER WA", + direction="l", + linebreak="al", + specials={ "narrow", 0x3158 }, + unicodeslot=0xFFCD, + }, + [0xFFCE]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER WAE", + direction="l", + linebreak="al", + specials={ "narrow", 0x3159 }, + unicodeslot=0xFFCE, + }, + [0xFFCF]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER OE", + direction="l", + linebreak="al", + specials={ "narrow", 0x315A }, + unicodeslot=0xFFCF, + }, + [0xFFD2]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER YO", + direction="l", + linebreak="al", + specials={ "narrow", 0x315B }, + unicodeslot=0xFFD2, + }, + [0xFFD3]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER U", + direction="l", + linebreak="al", + specials={ "narrow", 0x315C }, + unicodeslot=0xFFD3, + }, + [0xFFD4]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER WEO", + direction="l", + linebreak="al", + specials={ "narrow", 0x315D }, + unicodeslot=0xFFD4, + }, + [0xFFD5]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER WE", + direction="l", + linebreak="al", + specials={ "narrow", 0x315E }, + unicodeslot=0xFFD5, + }, + [0xFFD6]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER WI", + direction="l", + linebreak="al", + specials={ "narrow", 0x315F }, + unicodeslot=0xFFD6, + }, + [0xFFD7]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER YU", + direction="l", + linebreak="al", + specials={ "narrow", 0x3160 }, + unicodeslot=0xFFD7, + }, + [0xFFDA]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER EU", + direction="l", + linebreak="al", + specials={ "narrow", 0x3161 }, + unicodeslot=0xFFDA, + }, + [0xFFDB]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER YI", + direction="l", + linebreak="al", + specials={ "narrow", 0x3162 }, + unicodeslot=0xFFDB, + }, + [0xFFDC]={ + category="lo", + cjkwd="h", + description="HALFWIDTH HANGUL LETTER I", + direction="l", + linebreak="al", + specials={ "narrow", 0x3163 }, + unicodeslot=0xFFDC, + }, + [0xFFE0]={ + category="sc", + cjkwd="f", + description="FULLWIDTH CENT SIGN", + direction="et", + linebreak="po", + specials={ "wide", 0x00A2 }, + unicodeslot=0xFFE0, + }, + [0xFFE1]={ + category="sc", + cjkwd="f", + description="FULLWIDTH POUND SIGN", + direction="et", + linebreak="pr", + specials={ "wide", 0x00A3 }, + unicodeslot=0xFFE1, + }, + [0xFFE2]={ + category="sm", + cjkwd="f", + description="FULLWIDTH NOT SIGN", + direction="on", + linebreak="id", + specials={ "wide", 0x00AC }, + unicodeslot=0xFFE2, + }, + [0xFFE3]={ + category="sk", + cjkwd="f", + description="FULLWIDTH MACRON", + direction="on", + linebreak="id", + specials={ "wide", 0x00AF }, + unicodeslot=0xFFE3, + }, + [0xFFE4]={ + category="so", + cjkwd="f", + description="FULLWIDTH BROKEN BAR", + direction="on", + linebreak="id", + specials={ "wide", 0x00A6 }, + unicodeslot=0xFFE4, + }, + [0xFFE5]={ + category="sc", + cjkwd="f", + description="FULLWIDTH YEN SIGN", + direction="et", + linebreak="pr", + specials={ "wide", 0x00A5 }, + unicodeslot=0xFFE5, + }, + [0xFFE6]={ + category="sc", + cjkwd="f", + description="FULLWIDTH WON SIGN", + direction="et", + linebreak="pr", + specials={ "wide", 0x20A9 }, + unicodeslot=0xFFE6, + }, + [0xFFE8]={ + category="so", + cjkwd="h", + description="HALFWIDTH FORMS LIGHT VERTICAL", + direction="on", + linebreak="al", + specials={ "narrow", 0x2502 }, + unicodeslot=0xFFE8, + }, + [0xFFE9]={ + category="sm", + cjkwd="h", + description="HALFWIDTH LEFTWARDS ARROW", + direction="on", + linebreak="al", + specials={ "narrow", 0x2190 }, + unicodeslot=0xFFE9, + }, + [0xFFEA]={ + category="sm", + cjkwd="h", + description="HALFWIDTH UPWARDS ARROW", + direction="on", + linebreak="al", + specials={ "narrow", 0x2191 }, + unicodeslot=0xFFEA, + }, + [0xFFEB]={ + category="sm", + cjkwd="h", + description="HALFWIDTH RIGHTWARDS ARROW", + direction="on", + linebreak="al", + specials={ "narrow", 0x2192 }, + unicodeslot=0xFFEB, + }, + [0xFFEC]={ + category="sm", + cjkwd="h", + description="HALFWIDTH DOWNWARDS ARROW", + direction="on", + linebreak="al", + specials={ "narrow", 0x2193 }, + unicodeslot=0xFFEC, + }, + [0xFFED]={ + category="so", + cjkwd="h", + description="HALFWIDTH BLACK SQUARE", + direction="on", + linebreak="al", + specials={ "narrow", 0x25A0 }, + unicodeslot=0xFFED, + }, + [0xFFEE]={ + category="so", + cjkwd="h", + description="HALFWIDTH WHITE CIRCLE", + direction="on", + linebreak="al", + specials={ "narrow", 0x25CB }, + unicodeslot=0xFFEE, + }, + [0xFFF9]={ + category="cf", + description="INTERLINEAR ANNOTATION ANCHOR", + direction="on", + visible="yes", + linebreak="cm", + unicodeslot=0xFFF9, + }, + [0xFFFA]={ + category="cf", + description="INTERLINEAR ANNOTATION SEPARATOR", + direction="on", + visible="yes", + linebreak="cm", + unicodeslot=0xFFFA, + }, + [0xFFFB]={ + category="cf", + description="INTERLINEAR ANNOTATION TERMINATOR", + direction="on", + visible="yes", + linebreak="cm", + unicodeslot=0xFFFB, + }, + [0xFFFC]={ + category="so", + description="OBJECT REPLACEMENT CHARACTER", + direction="on", + linebreak="cb", + unicodeslot=0xFFFC, + }, + [0xFFFD]={ + category="so", + cjkwd="a", + description="REPLACEMENT CHARACTER", + direction="on", + linebreak="ai", + unicodeslot=0xFFFD, + }, + [0x10000]={ + category="lo", + description="LINEAR B SYLLABLE B0x0008 A", + direction="l", + linebreak="al", + unicodeslot=0x10000, + }, + [0x10001]={ + category="lo", + description="LINEAR B SYLLABLE B0x0026 E", + direction="l", + linebreak="al", + unicodeslot=0x10001, + }, + [0x10002]={ + category="lo", + description="LINEAR B SYLLABLE B0x001C I", + direction="l", + linebreak="al", + unicodeslot=0x10002, + }, + [0x10003]={ + category="lo", + description="LINEAR B SYLLABLE B0x003D O", + direction="l", + linebreak="al", + unicodeslot=0x10003, + }, + [0x10004]={ + category="lo", + description="LINEAR B SYLLABLE B0x000A U", + direction="l", + linebreak="al", + unicodeslot=0x10004, + }, + [0x10005]={ + category="lo", + description="LINEAR B SYLLABLE B0x0001 DA", + direction="l", + linebreak="al", + unicodeslot=0x10005, + }, + [0x10006]={ + category="lo", + description="LINEAR B SYLLABLE B0x002D DE", + direction="l", + linebreak="al", + unicodeslot=0x10006, + }, + [0x10007]={ + category="lo", + description="LINEAR B SYLLABLE B0x0007 DI", + direction="l", + linebreak="al", + unicodeslot=0x10007, + }, + [0x10008]={ + category="lo", + description="LINEAR B SYLLABLE B0x000E DO", + direction="l", + linebreak="al", + unicodeslot=0x10008, + }, + [0x10009]={ + category="lo", + description="LINEAR B SYLLABLE B0x0033 DU", + direction="l", + linebreak="al", + unicodeslot=0x10009, + }, + [0x1000A]={ + category="lo", + description="LINEAR B SYLLABLE B0x0039 JA", + direction="l", + linebreak="al", + unicodeslot=0x1000A, + }, + [0x1000B]={ + category="lo", + description="LINEAR B SYLLABLE B0x002E JE", + direction="l", + linebreak="al", + unicodeslot=0x1000B, + }, + [0x1000D]={ + category="lo", + description="LINEAR B SYLLABLE B0x0024 JO", + direction="l", + linebreak="al", + unicodeslot=0x1000D, + }, + [0x1000E]={ + category="lo", + description="LINEAR B SYLLABLE B0x0041 JU", + direction="l", + linebreak="al", + unicodeslot=0x1000E, + }, + [0x1000F]={ + category="lo", + description="LINEAR B SYLLABLE B0x004D KA", + direction="l", + linebreak="al", + unicodeslot=0x1000F, + }, + [0x10010]={ + category="lo", + description="LINEAR B SYLLABLE B0x002C KE", + direction="l", + linebreak="al", + unicodeslot=0x10010, + }, + [0x10011]={ + category="lo", + description="LINEAR B SYLLABLE B0x0043 KI", + direction="l", + linebreak="al", + unicodeslot=0x10011, + }, + [0x10012]={ + category="lo", + description="LINEAR B SYLLABLE B0x0046 KO", + direction="l", + linebreak="al", + unicodeslot=0x10012, + }, + [0x10013]={ + category="lo", + description="LINEAR B SYLLABLE B0x0051 KU", + direction="l", + linebreak="al", + unicodeslot=0x10013, + }, + [0x10014]={ + category="lo", + description="LINEAR B SYLLABLE B0x0050 MA", + direction="l", + linebreak="al", + unicodeslot=0x10014, + }, + [0x10015]={ + category="lo", + description="LINEAR B SYLLABLE B0x000D ME", + direction="l", + linebreak="al", + unicodeslot=0x10015, + }, + [0x10016]={ + category="lo", + description="LINEAR B SYLLABLE B0x0049 MI", + direction="l", + linebreak="al", + unicodeslot=0x10016, + }, + [0x10017]={ + category="lo", + description="LINEAR B SYLLABLE B0x000F MO", + direction="l", + linebreak="al", + unicodeslot=0x10017, + }, + [0x10018]={ + category="lo", + description="LINEAR B SYLLABLE B0x0017 MU", + direction="l", + linebreak="al", + unicodeslot=0x10018, + }, + [0x10019]={ + category="lo", + description="LINEAR B SYLLABLE B0x0006 NA", + direction="l", + linebreak="al", + unicodeslot=0x10019, + }, + [0x1001A]={ + category="lo", + description="LINEAR B SYLLABLE B0x0018 NE", + direction="l", + linebreak="al", + unicodeslot=0x1001A, + }, + [0x1001B]={ + category="lo", + description="LINEAR B SYLLABLE B0x001E NI", + direction="l", + linebreak="al", + unicodeslot=0x1001B, + }, + [0x1001C]={ + category="lo", + description="LINEAR B SYLLABLE B0x0034 NO", + direction="l", + linebreak="al", + unicodeslot=0x1001C, + }, + [0x1001D]={ + category="lo", + description="LINEAR B SYLLABLE B0x0037 NU", + direction="l", + linebreak="al", + unicodeslot=0x1001D, + }, + [0x1001E]={ + category="lo", + description="LINEAR B SYLLABLE B0x0003 PA", + direction="l", + linebreak="al", + unicodeslot=0x1001E, + }, + [0x1001F]={ + category="lo", + description="LINEAR B SYLLABLE B0x0048 PE", + direction="l", + linebreak="al", + unicodeslot=0x1001F, + }, + [0x10020]={ + category="lo", + description="LINEAR B SYLLABLE B0x0027 PI", + direction="l", + linebreak="al", + unicodeslot=0x10020, + }, + [0x10021]={ + category="lo", + description="LINEAR B SYLLABLE B0x000B PO", + direction="l", + linebreak="al", + unicodeslot=0x10021, + }, + [0x10022]={ + category="lo", + description="LINEAR B SYLLABLE B0x0032 PU", + direction="l", + linebreak="al", + unicodeslot=0x10022, + }, + [0x10023]={ + category="lo", + description="LINEAR B SYLLABLE B0x0010 QA", + direction="l", + linebreak="al", + unicodeslot=0x10023, + }, + [0x10024]={ + category="lo", + description="LINEAR B SYLLABLE B0x004E QE", + direction="l", + linebreak="al", + unicodeslot=0x10024, + }, + [0x10025]={ + category="lo", + description="LINEAR B SYLLABLE B0x0015 QI", + direction="l", + linebreak="al", + unicodeslot=0x10025, + }, + [0x10026]={ + category="lo", + description="LINEAR B SYLLABLE B0x0020 QO", + direction="l", + linebreak="al", + unicodeslot=0x10026, + }, + [0x10028]={ + category="lo", + description="LINEAR B SYLLABLE B0x003C RA", + direction="l", + linebreak="al", + unicodeslot=0x10028, + }, + [0x10029]={ + category="lo", + description="LINEAR B SYLLABLE B0x001B RE", + direction="l", + linebreak="al", + unicodeslot=0x10029, + }, + [0x1002A]={ + category="lo", + description="LINEAR B SYLLABLE B0x0035 RI", + direction="l", + linebreak="al", + unicodeslot=0x1002A, + }, + [0x1002B]={ + category="lo", + description="LINEAR B SYLLABLE B0x0002 RO", + direction="l", + linebreak="al", + unicodeslot=0x1002B, + }, + [0x1002C]={ + category="lo", + description="LINEAR B SYLLABLE B0x001A RU", + direction="l", + linebreak="al", + unicodeslot=0x1002C, + }, + [0x1002D]={ + category="lo", + description="LINEAR B SYLLABLE B0x001F SA", + direction="l", + linebreak="al", + unicodeslot=0x1002D, + }, + [0x1002E]={ + category="lo", + description="LINEAR B SYLLABLE B0x0009 SE", + direction="l", + linebreak="al", + unicodeslot=0x1002E, + }, + [0x1002F]={ + category="lo", + description="LINEAR B SYLLABLE B0x0029 SI", + direction="l", + linebreak="al", + unicodeslot=0x1002F, + }, + [0x10030]={ + category="lo", + description="LINEAR B SYLLABLE B0x000C SO", + direction="l", + linebreak="al", + unicodeslot=0x10030, + }, + [0x10031]={ + category="lo", + description="LINEAR B SYLLABLE B0x003A SU", + direction="l", + linebreak="al", + unicodeslot=0x10031, + }, + [0x10032]={ + category="lo", + description="LINEAR B SYLLABLE B0x003B TA", + direction="l", + linebreak="al", + unicodeslot=0x10032, + }, + [0x10033]={ + category="lo", + description="LINEAR B SYLLABLE B0x0004 TE", + direction="l", + linebreak="al", + unicodeslot=0x10033, + }, + [0x10034]={ + category="lo", + description="LINEAR B SYLLABLE B0x0025 TI", + direction="l", + linebreak="al", + unicodeslot=0x10034, + }, + [0x10035]={ + category="lo", + description="LINEAR B SYLLABLE B0x0005 TO", + direction="l", + linebreak="al", + unicodeslot=0x10035, + }, + [0x10036]={ + category="lo", + description="LINEAR B SYLLABLE B0x0045 TU", + direction="l", + linebreak="al", + unicodeslot=0x10036, + }, + [0x10037]={ + category="lo", + description="LINEAR B SYLLABLE B0x0036 WA", + direction="l", + linebreak="al", + unicodeslot=0x10037, + }, + [0x10038]={ + category="lo", + description="LINEAR B SYLLABLE B0x004B WE", + direction="l", + linebreak="al", + unicodeslot=0x10038, + }, + [0x10039]={ + category="lo", + description="LINEAR B SYLLABLE B0x0028 WI", + direction="l", + linebreak="al", + unicodeslot=0x10039, + }, + [0x1003A]={ + category="lo", + description="LINEAR B SYLLABLE B0x002A WO", + direction="l", + linebreak="al", + unicodeslot=0x1003A, + }, + [0x1003C]={ + category="lo", + description="LINEAR B SYLLABLE B0x0011 ZA", + direction="l", + linebreak="al", + unicodeslot=0x1003C, + }, + [0x1003D]={ + category="lo", + description="LINEAR B SYLLABLE B0x004A ZE", + direction="l", + linebreak="al", + unicodeslot=0x1003D, + }, + [0x1003F]={ + category="lo", + description="LINEAR B SYLLABLE B0x0014 ZO", + direction="l", + linebreak="al", + unicodeslot=0x1003F, + }, + [0x10040]={ + category="lo", + description="LINEAR B SYLLABLE B0x0019 A0x0002", + direction="l", + linebreak="al", + unicodeslot=0x10040, + }, + [0x10041]={ + category="lo", + description="LINEAR B SYLLABLE B0x002B A0x0003", + direction="l", + linebreak="al", + unicodeslot=0x10041, + }, + [0x10042]={ + category="lo", + description="LINEAR B SYLLABLE B0x0055 AU", + direction="l", + linebreak="al", + unicodeslot=0x10042, + }, + [0x10043]={ + category="lo", + description="LINEAR B SYLLABLE B0x0047 DWE", + direction="l", + linebreak="al", + unicodeslot=0x10043, + }, + [0x10044]={ + category="lo", + description="LINEAR B SYLLABLE B0x005A DWO", + direction="l", + linebreak="al", + unicodeslot=0x10044, + }, + [0x10045]={ + category="lo", + description="LINEAR B SYLLABLE B0x0030 NWA", + direction="l", + linebreak="al", + unicodeslot=0x10045, + }, + [0x10046]={ + category="lo", + description="LINEAR B SYLLABLE B0x001D PU0x0002", + direction="l", + linebreak="al", + unicodeslot=0x10046, + }, + [0x10047]={ + category="lo", + description="LINEAR B SYLLABLE B0x003E PTE", + direction="l", + linebreak="al", + unicodeslot=0x10047, + }, + [0x10048]={ + category="lo", + description="LINEAR B SYLLABLE B0x004C RA0x0002", + direction="l", + linebreak="al", + unicodeslot=0x10048, + }, + [0x10049]={ + category="lo", + description="LINEAR B SYLLABLE B0x0021 RA0x0003", + direction="l", + linebreak="al", + unicodeslot=0x10049, + }, + [0x1004A]={ + category="lo", + description="LINEAR B SYLLABLE B0x0044 RO0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1004A, + }, + [0x1004B]={ + category="lo", + description="LINEAR B SYLLABLE B0x0042 TA0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1004B, + }, + [0x1004C]={ + category="lo", + description="LINEAR B SYLLABLE B0x0057 TWE", + direction="l", + linebreak="al", + unicodeslot=0x1004C, + }, + [0x1004D]={ + category="lo", + description="LINEAR B SYLLABLE B0x005B TWO", + direction="l", + linebreak="al", + unicodeslot=0x1004D, + }, + [0x10050]={ + category="lo", + description="LINEAR B SYMBOL B0x0012", + direction="l", + linebreak="al", + unicodeslot=0x10050, + }, + [0x10051]={ + category="lo", + description="LINEAR B SYMBOL B0x0013", + direction="l", + linebreak="al", + unicodeslot=0x10051, + }, + [0x10052]={ + category="lo", + description="LINEAR B SYMBOL B0x0016", + direction="l", + linebreak="al", + unicodeslot=0x10052, + }, + [0x10053]={ + category="lo", + description="LINEAR B SYMBOL B0x0022", + direction="l", + linebreak="al", + unicodeslot=0x10053, + }, + [0x10054]={ + category="lo", + description="LINEAR B SYMBOL B0x002F", + direction="l", + linebreak="al", + unicodeslot=0x10054, + }, + [0x10055]={ + category="lo", + description="LINEAR B SYMBOL B0x0031", + direction="l", + linebreak="al", + unicodeslot=0x10055, + }, + [0x10056]={ + category="lo", + description="LINEAR B SYMBOL B0x0038", + direction="l", + linebreak="al", + unicodeslot=0x10056, + }, + [0x10057]={ + category="lo", + description="LINEAR B SYMBOL B0x003F", + direction="l", + linebreak="al", + unicodeslot=0x10057, + }, + [0x10058]={ + category="lo", + description="LINEAR B SYMBOL B0x0040", + direction="l", + linebreak="al", + unicodeslot=0x10058, + }, + [0x10059]={ + category="lo", + description="LINEAR B SYMBOL B0x004F", + direction="l", + linebreak="al", + unicodeslot=0x10059, + }, + [0x1005A]={ + category="lo", + description="LINEAR B SYMBOL B0x0052", + direction="l", + linebreak="al", + unicodeslot=0x1005A, + }, + [0x1005B]={ + category="lo", + description="LINEAR B SYMBOL B0x0053", + direction="l", + linebreak="al", + unicodeslot=0x1005B, + }, + [0x1005C]={ + category="lo", + description="LINEAR B SYMBOL B0x0056", + direction="l", + linebreak="al", + unicodeslot=0x1005C, + }, + [0x1005D]={ + category="lo", + description="LINEAR B SYMBOL B0x0059", + direction="l", + linebreak="al", + unicodeslot=0x1005D, + }, + [0x10080]={ + category="lo", + description="LINEAR B IDEOGRAM B0x0064 MAN", + direction="l", + linebreak="al", + unicodeslot=0x10080, + }, + [0x10081]={ + category="lo", + description="LINEAR B IDEOGRAM B0x0066 WOMAN", + direction="l", + linebreak="al", + unicodeslot=0x10081, + }, + [0x10082]={ + category="lo", + description="LINEAR B IDEOGRAM B0x0068 DEER", + direction="l", + linebreak="al", + unicodeslot=0x10082, + }, + [0x10083]={ + category="lo", + description="LINEAR B IDEOGRAM B0x0069 EQUID", + direction="l", + linebreak="al", + unicodeslot=0x10083, + }, + [0x10084]={ + category="lo", + description="LINEAR B IDEOGRAM B0x0069F MARE", + direction="l", + linebreak="al", + unicodeslot=0x10084, + }, + [0x10085]={ + category="lo", + description="LINEAR B IDEOGRAM B0x0069M STALLION", + direction="l", + linebreak="al", + unicodeslot=0x10085, + }, + [0x10086]={ + category="lo", + description="LINEAR B IDEOGRAM B0x006AF EWE", + direction="l", + linebreak="al", + unicodeslot=0x10086, + }, + [0x10087]={ + category="lo", + description="LINEAR B IDEOGRAM B0x006AM RAM", + direction="l", + linebreak="al", + unicodeslot=0x10087, + }, + [0x10088]={ + category="lo", + description="LINEAR B IDEOGRAM B0x006BF SHE-GOAT", + direction="l", + linebreak="al", + unicodeslot=0x10088, + }, + [0x10089]={ + category="lo", + description="LINEAR B IDEOGRAM B0x006BM HE-GOAT", + direction="l", + linebreak="al", + unicodeslot=0x10089, + }, + [0x1008A]={ + category="lo", + description="LINEAR B IDEOGRAM B0x006CF SOW", + direction="l", + linebreak="al", + unicodeslot=0x1008A, + }, + [0x1008B]={ + category="lo", + description="LINEAR B IDEOGRAM B0x006CM BOAR", + direction="l", + linebreak="al", + unicodeslot=0x1008B, + }, + [0x1008C]={ + category="lo", + description="LINEAR B IDEOGRAM B0x006DF COW", + direction="l", + linebreak="al", + unicodeslot=0x1008C, + }, + [0x1008D]={ + category="lo", + description="LINEAR B IDEOGRAM B0x006DM BULL", + direction="l", + linebreak="al", + unicodeslot=0x1008D, + }, + [0x1008E]={ + category="lo", + description="LINEAR B IDEOGRAM B0x0078 WHEAT", + direction="l", + linebreak="al", + unicodeslot=0x1008E, + }, + [0x1008F]={ + category="lo", + description="LINEAR B IDEOGRAM B0x0079 BARLEY", + direction="l", + linebreak="al", + unicodeslot=0x1008F, + }, + [0x10090]={ + category="lo", + description="LINEAR B IDEOGRAM B0x007A OLIVE", + direction="l", + linebreak="al", + unicodeslot=0x10090, + }, + [0x10091]={ + category="lo", + description="LINEAR B IDEOGRAM B0x007B SPICE", + direction="l", + linebreak="al", + unicodeslot=0x10091, + }, + [0x10092]={ + category="lo", + description="LINEAR B IDEOGRAM B0x007D CYPERUS", + direction="l", + linebreak="al", + unicodeslot=0x10092, + }, + [0x10093]={ + category="lo", + description="LINEAR B MONOGRAM B0x007F KAPO", + direction="l", + linebreak="al", + unicodeslot=0x10093, + }, + [0x10094]={ + category="lo", + description="LINEAR B MONOGRAM B0x0080 KANAKO", + direction="l", + linebreak="al", + unicodeslot=0x10094, + }, + [0x10095]={ + category="lo", + description="LINEAR B IDEOGRAM B0x0082 OIL", + direction="l", + linebreak="al", + unicodeslot=0x10095, + }, + [0x10096]={ + category="lo", + description="LINEAR B IDEOGRAM B0x0083 WINE", + direction="l", + linebreak="al", + unicodeslot=0x10096, + }, + [0x10097]={ + category="lo", + description="LINEAR B IDEOGRAM B0x0084", + direction="l", + linebreak="al", + unicodeslot=0x10097, + }, + [0x10098]={ + category="lo", + description="LINEAR B MONOGRAM B0x0085 AREPA", + direction="l", + linebreak="al", + unicodeslot=0x10098, + }, + [0x10099]={ + category="lo", + description="LINEAR B MONOGRAM B0x0087 MERI", + direction="l", + linebreak="al", + unicodeslot=0x10099, + }, + [0x1009A]={ + category="lo", + description="LINEAR B IDEOGRAM B0x008C BRONZE", + direction="l", + linebreak="al", + unicodeslot=0x1009A, + }, + [0x1009B]={ + category="lo", + description="LINEAR B IDEOGRAM B0x008D GOLD", + direction="l", + linebreak="al", + unicodeslot=0x1009B, + }, + [0x1009C]={ + category="lo", + description="LINEAR B IDEOGRAM B0x008E", + direction="l", + linebreak="al", + unicodeslot=0x1009C, + }, + [0x1009D]={ + category="lo", + description="LINEAR B IDEOGRAM B0x0091 WOOL", + direction="l", + linebreak="al", + unicodeslot=0x1009D, + }, + [0x1009E]={ + category="lo", + description="LINEAR B IDEOGRAM B0x0092", + direction="l", + linebreak="al", + unicodeslot=0x1009E, + }, + [0x1009F]={ + category="lo", + description="LINEAR B IDEOGRAM B0x0096", + direction="l", + linebreak="al", + unicodeslot=0x1009F, + }, + [0x100A0]={ + category="lo", + description="LINEAR B IDEOGRAM B0x0097 HORN", + direction="l", + linebreak="al", + unicodeslot=0x100A0, + }, + [0x100A1]={ + category="lo", + description="LINEAR B IDEOGRAM B0x0098", + direction="l", + linebreak="al", + unicodeslot=0x100A1, + }, + [0x100A2]={ + category="lo", + description="LINEAR B IDEOGRAM B0x0099", + direction="l", + linebreak="al", + unicodeslot=0x100A2, + }, + [0x100A3]={ + category="lo", + description="LINEAR B IDEOGRAM B0x009A", + direction="l", + linebreak="al", + unicodeslot=0x100A3, + }, + [0x100A4]={ + category="lo", + description="LINEAR B MONOGRAM B0x009C TURO0x0002", + direction="l", + linebreak="al", + unicodeslot=0x100A4, + }, + [0x100A5]={ + category="lo", + description="LINEAR B IDEOGRAM B0x009D", + direction="l", + linebreak="al", + unicodeslot=0x100A5, + }, + [0x100A6]={ + category="lo", + description="LINEAR B IDEOGRAM B0x009E", + direction="l", + linebreak="al", + unicodeslot=0x100A6, + }, + [0x100A7]={ + category="lo", + description="LINEAR B IDEOGRAM B0x009F CLOTH", + direction="l", + linebreak="al", + unicodeslot=0x100A7, + }, + [0x100A8]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00A0", + direction="l", + linebreak="al", + unicodeslot=0x100A8, + }, + [0x100A9]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00A1", + direction="l", + linebreak="al", + unicodeslot=0x100A9, + }, + [0x100AA]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00A2 GARMENT", + direction="l", + linebreak="al", + unicodeslot=0x100AA, + }, + [0x100AB]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00A3 ARMOUR", + direction="l", + linebreak="al", + unicodeslot=0x100AB, + }, + [0x100AC]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00A4", + direction="l", + linebreak="al", + unicodeslot=0x100AC, + }, + [0x100AD]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00A5", + direction="l", + linebreak="al", + unicodeslot=0x100AD, + }, + [0x100AE]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00A6", + direction="l", + linebreak="al", + unicodeslot=0x100AE, + }, + [0x100AF]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00A7", + direction="l", + linebreak="al", + unicodeslot=0x100AF, + }, + [0x100B0]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00A8", + direction="l", + linebreak="al", + unicodeslot=0x100B0, + }, + [0x100B1]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00A9", + direction="l", + linebreak="al", + unicodeslot=0x100B1, + }, + [0x100B2]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00AA", + direction="l", + linebreak="al", + unicodeslot=0x100B2, + }, + [0x100B3]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00AB", + direction="l", + linebreak="al", + unicodeslot=0x100B3, + }, + [0x100B4]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00AC", + direction="l", + linebreak="al", + unicodeslot=0x100B4, + }, + [0x100B5]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00AD MONTH", + direction="l", + linebreak="al", + unicodeslot=0x100B5, + }, + [0x100B6]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00AE", + direction="l", + linebreak="al", + unicodeslot=0x100B6, + }, + [0x100B7]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00B0 TREE", + direction="l", + linebreak="al", + unicodeslot=0x100B7, + }, + [0x100B8]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00B1", + direction="l", + linebreak="al", + unicodeslot=0x100B8, + }, + [0x100B9]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00B2", + direction="l", + linebreak="al", + unicodeslot=0x100B9, + }, + [0x100BA]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00B3", + direction="l", + linebreak="al", + unicodeslot=0x100BA, + }, + [0x100BB]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00B4", + direction="l", + linebreak="al", + unicodeslot=0x100BB, + }, + [0x100BC]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00B5", + direction="l", + linebreak="al", + unicodeslot=0x100BC, + }, + [0x100BD]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00B6", + direction="l", + linebreak="al", + unicodeslot=0x100BD, + }, + [0x100BE]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00B7", + direction="l", + linebreak="al", + unicodeslot=0x100BE, + }, + [0x100BF]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00B8", + direction="l", + linebreak="al", + unicodeslot=0x100BF, + }, + [0x100C0]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00B9", + direction="l", + linebreak="al", + unicodeslot=0x100C0, + }, + [0x100C1]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00BD", + direction="l", + linebreak="al", + unicodeslot=0x100C1, + }, + [0x100C2]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00BE", + direction="l", + linebreak="al", + unicodeslot=0x100C2, + }, + [0x100C3]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00BF HELMET", + direction="l", + linebreak="al", + unicodeslot=0x100C3, + }, + [0x100C4]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00DC FOOTSTOOL", + direction="l", + linebreak="al", + unicodeslot=0x100C4, + }, + [0x100C5]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00E1 BATHTUB", + direction="l", + linebreak="al", + unicodeslot=0x100C5, + }, + [0x100C6]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00E6 SPEAR", + direction="l", + linebreak="al", + unicodeslot=0x100C6, + }, + [0x100C7]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00E7 ARROW", + direction="l", + linebreak="al", + unicodeslot=0x100C7, + }, + [0x100C8]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00E8", + direction="l", + linebreak="al", + unicodeslot=0x100C8, + }, + [0x100C9]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00E9 SWORD", + direction="l", + linebreak="al", + unicodeslot=0x100C9, + }, + [0x100CA]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00EA", + direction="l", + linebreak="al", + unicodeslot=0x100CA, + }, + [0x100CB]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00EC", + direction="l", + linebreak="al", + unicodeslot=0x100CB, + }, + [0x100CC]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00F0 WHEELED CHARIOT", + direction="l", + linebreak="al", + unicodeslot=0x100CC, + }, + [0x100CD]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00F1 CHARIOT", + direction="l", + linebreak="al", + unicodeslot=0x100CD, + }, + [0x100CE]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00F2 CHARIOT FRAME", + direction="l", + linebreak="al", + unicodeslot=0x100CE, + }, + [0x100CF]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00F3 WHEEL", + direction="l", + linebreak="al", + unicodeslot=0x100CF, + }, + [0x100D0]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00F5", + direction="l", + linebreak="al", + unicodeslot=0x100D0, + }, + [0x100D1]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00F6", + direction="l", + linebreak="al", + unicodeslot=0x100D1, + }, + [0x100D2]={ + category="lo", + description="LINEAR B MONOGRAM B0x00F7 DIPTE", + direction="l", + linebreak="al", + unicodeslot=0x100D2, + }, + [0x100D3]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00F8", + direction="l", + linebreak="al", + unicodeslot=0x100D3, + }, + [0x100D4]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00F9", + direction="l", + linebreak="al", + unicodeslot=0x100D4, + }, + [0x100D5]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00FB", + direction="l", + linebreak="al", + unicodeslot=0x100D5, + }, + [0x100D6]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00FC", + direction="l", + linebreak="al", + unicodeslot=0x100D6, + }, + [0x100D7]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00FD", + direction="l", + linebreak="al", + unicodeslot=0x100D7, + }, + [0x100D8]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00FE DART", + direction="l", + linebreak="al", + unicodeslot=0x100D8, + }, + [0x100D9]={ + category="lo", + description="LINEAR B IDEOGRAM B0x00FF", + direction="l", + linebreak="al", + unicodeslot=0x100D9, + }, + [0x100DA]={ + category="lo", + description="LINEAR B IDEOGRAM B0x0100", + direction="l", + linebreak="al", + unicodeslot=0x100DA, + }, + [0x100DB]={ + category="lo", + description="LINEAR B IDEOGRAM B0x0101", + direction="l", + linebreak="al", + unicodeslot=0x100DB, + }, + [0x100DC]={ + category="lo", + description="LINEAR B IDEOGRAM B0x0102", + direction="l", + linebreak="al", + unicodeslot=0x100DC, + }, + [0x100DD]={ + category="lo", + description="LINEAR B IDEOGRAM B0x0103", + direction="l", + linebreak="al", + unicodeslot=0x100DD, + }, + [0x100DE]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x009B", + direction="l", + linebreak="al", + unicodeslot=0x100DE, + }, + [0x100DF]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00C8", + direction="l", + linebreak="al", + unicodeslot=0x100DF, + }, + [0x100E0]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00C9", + direction="l", + linebreak="al", + unicodeslot=0x100E0, + }, + [0x100E1]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00CA", + direction="l", + linebreak="al", + unicodeslot=0x100E1, + }, + [0x100E2]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00CB", + direction="l", + linebreak="al", + unicodeslot=0x100E2, + }, + [0x100E3]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00CC", + direction="l", + linebreak="al", + unicodeslot=0x100E3, + }, + [0x100E4]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00CD", + direction="l", + linebreak="al", + unicodeslot=0x100E4, + }, + [0x100E5]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00CE", + direction="l", + linebreak="al", + unicodeslot=0x100E5, + }, + [0x100E6]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00CF", + direction="l", + linebreak="al", + unicodeslot=0x100E6, + }, + [0x100E7]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00D0", + direction="l", + linebreak="al", + unicodeslot=0x100E7, + }, + [0x100E8]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00D1", + direction="l", + linebreak="al", + unicodeslot=0x100E8, + }, + [0x100E9]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00D2", + direction="l", + linebreak="al", + unicodeslot=0x100E9, + }, + [0x100EA]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00D3", + direction="l", + linebreak="al", + unicodeslot=0x100EA, + }, + [0x100EB]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00D4", + direction="l", + linebreak="al", + unicodeslot=0x100EB, + }, + [0x100EC]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00D5", + direction="l", + linebreak="al", + unicodeslot=0x100EC, + }, + [0x100ED]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00D6", + direction="l", + linebreak="al", + unicodeslot=0x100ED, + }, + [0x100EE]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00D7", + direction="l", + linebreak="al", + unicodeslot=0x100EE, + }, + [0x100EF]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00D8", + direction="l", + linebreak="al", + unicodeslot=0x100EF, + }, + [0x100F0]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00D9", + direction="l", + linebreak="al", + unicodeslot=0x100F0, + }, + [0x100F1]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00DA", + direction="l", + linebreak="al", + unicodeslot=0x100F1, + }, + [0x100F2]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00DB", + direction="l", + linebreak="al", + unicodeslot=0x100F2, + }, + [0x100F3]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00DD", + direction="l", + linebreak="al", + unicodeslot=0x100F3, + }, + [0x100F4]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00DE", + direction="l", + linebreak="al", + unicodeslot=0x100F4, + }, + [0x100F5]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00E2", + direction="l", + linebreak="al", + unicodeslot=0x100F5, + }, + [0x100F6]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00E3", + direction="l", + linebreak="al", + unicodeslot=0x100F6, + }, + [0x100F7]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00E4", + direction="l", + linebreak="al", + unicodeslot=0x100F7, + }, + [0x100F8]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00E5", + direction="l", + linebreak="al", + unicodeslot=0x100F8, + }, + [0x100F9]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x00FA", + direction="l", + linebreak="al", + unicodeslot=0x100F9, + }, + [0x100FA]={ + category="lo", + description="LINEAR B IDEOGRAM VESSEL B0x0131", + direction="l", + linebreak="al", + unicodeslot=0x100FA, + }, + [0x10100]={ + category="po", + description="AEGEAN WORD SEPARATOR LINE", + direction="l", + linebreak="ba", + unicodeslot=0x10100, + }, + [0x10101]={ + category="po", + description="AEGEAN WORD SEPARATOR DOT", + direction="on", + linebreak="ba", + unicodeslot=0x10101, + }, + [0x10102]={ + category="so", + description="AEGEAN CHECK MARK", + direction="l", + linebreak="ba", + unicodeslot=0x10102, + }, + [0x10107]={ + category="no", + description="AEGEAN NUMBER ONE", + direction="l", + linebreak="al", + unicodeslot=0x10107, + }, + [0x10108]={ + category="no", + description="AEGEAN NUMBER TWO", + direction="l", + linebreak="al", + unicodeslot=0x10108, + }, + [0x10109]={ + category="no", + description="AEGEAN NUMBER THREE", + direction="l", + linebreak="al", + unicodeslot=0x10109, + }, + [0x1010A]={ + category="no", + description="AEGEAN NUMBER FOUR", + direction="l", + linebreak="al", + unicodeslot=0x1010A, + }, + [0x1010B]={ + category="no", + description="AEGEAN NUMBER FIVE", + direction="l", + linebreak="al", + unicodeslot=0x1010B, + }, + [0x1010C]={ + category="no", + description="AEGEAN NUMBER SIX", + direction="l", + linebreak="al", + unicodeslot=0x1010C, + }, + [0x1010D]={ + category="no", + description="AEGEAN NUMBER SEVEN", + direction="l", + linebreak="al", + unicodeslot=0x1010D, + }, + [0x1010E]={ + category="no", + description="AEGEAN NUMBER EIGHT", + direction="l", + linebreak="al", + unicodeslot=0x1010E, + }, + [0x1010F]={ + category="no", + description="AEGEAN NUMBER NINE", + direction="l", + linebreak="al", + unicodeslot=0x1010F, + }, + [0x10110]={ + category="no", + description="AEGEAN NUMBER TEN", + direction="l", + linebreak="al", + unicodeslot=0x10110, + }, + [0x10111]={ + category="no", + description="AEGEAN NUMBER TWENTY", + direction="l", + linebreak="al", + unicodeslot=0x10111, + }, + [0x10112]={ + category="no", + description="AEGEAN NUMBER THIRTY", + direction="l", + linebreak="al", + unicodeslot=0x10112, + }, + [0x10113]={ + category="no", + description="AEGEAN NUMBER FORTY", + direction="l", + linebreak="al", + unicodeslot=0x10113, + }, + [0x10114]={ + category="no", + description="AEGEAN NUMBER FIFTY", + direction="l", + linebreak="al", + unicodeslot=0x10114, + }, + [0x10115]={ + category="no", + description="AEGEAN NUMBER SIXTY", + direction="l", + linebreak="al", + unicodeslot=0x10115, + }, + [0x10116]={ + category="no", + description="AEGEAN NUMBER SEVENTY", + direction="l", + linebreak="al", + unicodeslot=0x10116, + }, + [0x10117]={ + category="no", + description="AEGEAN NUMBER EIGHTY", + direction="l", + linebreak="al", + unicodeslot=0x10117, + }, + [0x10118]={ + category="no", + description="AEGEAN NUMBER NINETY", + direction="l", + linebreak="al", + unicodeslot=0x10118, + }, + [0x10119]={ + category="no", + description="AEGEAN NUMBER ONE HUNDRED", + direction="l", + linebreak="al", + unicodeslot=0x10119, + }, + [0x1011A]={ + category="no", + description="AEGEAN NUMBER TWO HUNDRED", + direction="l", + linebreak="al", + unicodeslot=0x1011A, + }, + [0x1011B]={ + category="no", + description="AEGEAN NUMBER THREE HUNDRED", + direction="l", + linebreak="al", + unicodeslot=0x1011B, + }, + [0x1011C]={ + category="no", + description="AEGEAN NUMBER FOUR HUNDRED", + direction="l", + linebreak="al", + unicodeslot=0x1011C, + }, + [0x1011D]={ + category="no", + description="AEGEAN NUMBER FIVE HUNDRED", + direction="l", + linebreak="al", + unicodeslot=0x1011D, + }, + [0x1011E]={ + category="no", + description="AEGEAN NUMBER SIX HUNDRED", + direction="l", + linebreak="al", + unicodeslot=0x1011E, + }, + [0x1011F]={ + category="no", + description="AEGEAN NUMBER SEVEN HUNDRED", + direction="l", + linebreak="al", + unicodeslot=0x1011F, + }, + [0x10120]={ + category="no", + description="AEGEAN NUMBER EIGHT HUNDRED", + direction="l", + linebreak="al", + unicodeslot=0x10120, + }, + [0x10121]={ + category="no", + description="AEGEAN NUMBER NINE HUNDRED", + direction="l", + linebreak="al", + unicodeslot=0x10121, + }, + [0x10122]={ + category="no", + description="AEGEAN NUMBER ONE THOUSAND", + direction="l", + linebreak="al", + unicodeslot=0x10122, + }, + [0x10123]={ + category="no", + description="AEGEAN NUMBER TWO THOUSAND", + direction="l", + linebreak="al", + unicodeslot=0x10123, + }, + [0x10124]={ + category="no", + description="AEGEAN NUMBER THREE THOUSAND", + direction="l", + linebreak="al", + unicodeslot=0x10124, + }, + [0x10125]={ + category="no", + description="AEGEAN NUMBER FOUR THOUSAND", + direction="l", + linebreak="al", + unicodeslot=0x10125, + }, + [0x10126]={ + category="no", + description="AEGEAN NUMBER FIVE THOUSAND", + direction="l", + linebreak="al", + unicodeslot=0x10126, + }, + [0x10127]={ + category="no", + description="AEGEAN NUMBER SIX THOUSAND", + direction="l", + linebreak="al", + unicodeslot=0x10127, + }, + [0x10128]={ + category="no", + description="AEGEAN NUMBER SEVEN THOUSAND", + direction="l", + linebreak="al", + unicodeslot=0x10128, + }, + [0x10129]={ + category="no", + description="AEGEAN NUMBER EIGHT THOUSAND", + direction="l", + linebreak="al", + unicodeslot=0x10129, + }, + [0x1012A]={ + category="no", + description="AEGEAN NUMBER NINE THOUSAND", + direction="l", + linebreak="al", + unicodeslot=0x1012A, + }, + [0x1012B]={ + category="no", + description="AEGEAN NUMBER TEN THOUSAND", + direction="l", + linebreak="al", + unicodeslot=0x1012B, + }, + [0x1012C]={ + category="no", + description="AEGEAN NUMBER TWENTY THOUSAND", + direction="l", + linebreak="al", + unicodeslot=0x1012C, + }, + [0x1012D]={ + category="no", + description="AEGEAN NUMBER THIRTY THOUSAND", + direction="l", + linebreak="al", + unicodeslot=0x1012D, + }, + [0x1012E]={ + category="no", + description="AEGEAN NUMBER FORTY THOUSAND", + direction="l", + linebreak="al", + unicodeslot=0x1012E, + }, + [0x1012F]={ + category="no", + description="AEGEAN NUMBER FIFTY THOUSAND", + direction="l", + linebreak="al", + unicodeslot=0x1012F, + }, + [0x10130]={ + category="no", + description="AEGEAN NUMBER SIXTY THOUSAND", + direction="l", + linebreak="al", + unicodeslot=0x10130, + }, + [0x10131]={ + category="no", + description="AEGEAN NUMBER SEVENTY THOUSAND", + direction="l", + linebreak="al", + unicodeslot=0x10131, + }, + [0x10132]={ + category="no", + description="AEGEAN NUMBER EIGHTY THOUSAND", + direction="l", + linebreak="al", + unicodeslot=0x10132, + }, + [0x10133]={ + category="no", + description="AEGEAN NUMBER NINETY THOUSAND", + direction="l", + linebreak="al", + unicodeslot=0x10133, + }, + [0x10137]={ + category="so", + description="AEGEAN WEIGHT BASE UNIT", + direction="l", + linebreak="al", + unicodeslot=0x10137, + }, + [0x10138]={ + category="so", + description="AEGEAN WEIGHT FIRST SUBUNIT", + direction="l", + linebreak="al", + unicodeslot=0x10138, + }, + [0x10139]={ + category="so", + description="AEGEAN WEIGHT SECOND SUBUNIT", + direction="l", + linebreak="al", + unicodeslot=0x10139, + }, + [0x1013A]={ + category="so", + description="AEGEAN WEIGHT THIRD SUBUNIT", + direction="l", + linebreak="al", + unicodeslot=0x1013A, + }, + [0x1013B]={ + category="so", + description="AEGEAN WEIGHT FOURTH SUBUNIT", + direction="l", + linebreak="al", + unicodeslot=0x1013B, + }, + [0x1013C]={ + category="so", + description="AEGEAN DRY MEASURE FIRST SUBUNIT", + direction="l", + linebreak="al", + unicodeslot=0x1013C, + }, + [0x1013D]={ + category="so", + description="AEGEAN LIQUID MEASURE FIRST SUBUNIT", + direction="l", + linebreak="al", + unicodeslot=0x1013D, + }, + [0x1013E]={ + category="so", + description="AEGEAN MEASURE SECOND SUBUNIT", + direction="l", + linebreak="al", + unicodeslot=0x1013E, + }, + [0x1013F]={ + category="so", + description="AEGEAN MEASURE THIRD SUBUNIT", + direction="l", + linebreak="al", + unicodeslot=0x1013F, + }, + [0x10140]={ + category="nl", + description="GREEK ACROPHONIC ATTIC ONE QUARTER", + direction="on", + linebreak="al", + unicodeslot=0x10140, + }, + [0x10141]={ + category="nl", + description="GREEK ACROPHONIC ATTIC ONE HALF", + direction="on", + linebreak="al", + unicodeslot=0x10141, + }, + [0x10142]={ + category="nl", + description="GREEK ACROPHONIC ATTIC ONE DRACHMA", + direction="on", + linebreak="al", + unicodeslot=0x10142, + }, + [0x10143]={ + category="nl", + description="GREEK ACROPHONIC ATTIC FIVE", + direction="on", + linebreak="al", + unicodeslot=0x10143, + }, + [0x10144]={ + category="nl", + description="GREEK ACROPHONIC ATTIC FIFTY", + direction="on", + linebreak="al", + unicodeslot=0x10144, + }, + [0x10145]={ + category="nl", + description="GREEK ACROPHONIC ATTIC FIVE HUNDRED", + direction="on", + linebreak="al", + unicodeslot=0x10145, + }, + [0x10146]={ + category="nl", + description="GREEK ACROPHONIC ATTIC FIVE THOUSAND", + direction="on", + linebreak="al", + unicodeslot=0x10146, + }, + [0x10147]={ + category="nl", + description="GREEK ACROPHONIC ATTIC FIFTY THOUSAND", + direction="on", + linebreak="al", + unicodeslot=0x10147, + }, + [0x10148]={ + category="nl", + description="GREEK ACROPHONIC ATTIC FIVE TALENTS", + direction="on", + linebreak="al", + unicodeslot=0x10148, + }, + [0x10149]={ + category="nl", + description="GREEK ACROPHONIC ATTIC TEN TALENTS", + direction="on", + linebreak="al", + unicodeslot=0x10149, + }, + [0x1014A]={ + category="nl", + description="GREEK ACROPHONIC ATTIC FIFTY TALENTS", + direction="on", + linebreak="al", + unicodeslot=0x1014A, + }, + [0x1014B]={ + category="nl", + description="GREEK ACROPHONIC ATTIC ONE HUNDRED TALENTS", + direction="on", + linebreak="al", + unicodeslot=0x1014B, + }, + [0x1014C]={ + category="nl", + description="GREEK ACROPHONIC ATTIC FIVE HUNDRED TALENTS", + direction="on", + linebreak="al", + unicodeslot=0x1014C, + }, + [0x1014D]={ + category="nl", + description="GREEK ACROPHONIC ATTIC ONE THOUSAND TALENTS", + direction="on", + linebreak="al", + unicodeslot=0x1014D, + }, + [0x1014E]={ + category="nl", + description="GREEK ACROPHONIC ATTIC FIVE THOUSAND TALENTS", + direction="on", + linebreak="al", + unicodeslot=0x1014E, + }, + [0x1014F]={ + category="nl", + description="GREEK ACROPHONIC ATTIC FIVE STATERS", + direction="on", + linebreak="al", + unicodeslot=0x1014F, + }, + [0x10150]={ + category="nl", + description="GREEK ACROPHONIC ATTIC TEN STATERS", + direction="on", + linebreak="al", + unicodeslot=0x10150, + }, + [0x10151]={ + category="nl", + description="GREEK ACROPHONIC ATTIC FIFTY STATERS", + direction="on", + linebreak="al", + unicodeslot=0x10151, + }, + [0x10152]={ + category="nl", + description="GREEK ACROPHONIC ATTIC ONE HUNDRED STATERS", + direction="on", + linebreak="al", + unicodeslot=0x10152, + }, + [0x10153]={ + category="nl", + description="GREEK ACROPHONIC ATTIC FIVE HUNDRED STATERS", + direction="on", + linebreak="al", + unicodeslot=0x10153, + }, + [0x10154]={ + category="nl", + description="GREEK ACROPHONIC ATTIC ONE THOUSAND STATERS", + direction="on", + linebreak="al", + unicodeslot=0x10154, + }, + [0x10155]={ + category="nl", + description="GREEK ACROPHONIC ATTIC TEN THOUSAND STATERS", + direction="on", + linebreak="al", + unicodeslot=0x10155, + }, + [0x10156]={ + category="nl", + description="GREEK ACROPHONIC ATTIC FIFTY THOUSAND STATERS", + direction="on", + linebreak="al", + unicodeslot=0x10156, + }, + [0x10157]={ + category="nl", + description="GREEK ACROPHONIC ATTIC TEN MNAS", + direction="on", + linebreak="al", + unicodeslot=0x10157, + }, + [0x10158]={ + category="nl", + description="GREEK ACROPHONIC HERAEUM ONE PLETHRON", + direction="on", + linebreak="al", + unicodeslot=0x10158, + }, + [0x10159]={ + category="nl", + description="GREEK ACROPHONIC THESPIAN ONE", + direction="on", + linebreak="al", + unicodeslot=0x10159, + }, + [0x1015A]={ + category="nl", + description="GREEK ACROPHONIC HERMIONIAN ONE", + direction="on", + linebreak="al", + unicodeslot=0x1015A, + }, + [0x1015B]={ + category="nl", + description="GREEK ACROPHONIC EPIDAUREAN TWO", + direction="on", + linebreak="al", + unicodeslot=0x1015B, + }, + [0x1015C]={ + category="nl", + description="GREEK ACROPHONIC THESPIAN TWO", + direction="on", + linebreak="al", + unicodeslot=0x1015C, + }, + [0x1015D]={ + category="nl", + description="GREEK ACROPHONIC CYRENAIC TWO DRACHMAS", + direction="on", + linebreak="al", + unicodeslot=0x1015D, + }, + [0x1015E]={ + category="nl", + description="GREEK ACROPHONIC EPIDAUREAN TWO DRACHMAS", + direction="on", + linebreak="al", + unicodeslot=0x1015E, + }, + [0x1015F]={ + category="nl", + description="GREEK ACROPHONIC TROEZENIAN FIVE", + direction="on", + linebreak="al", + unicodeslot=0x1015F, + }, + [0x10160]={ + category="nl", + description="GREEK ACROPHONIC TROEZENIAN TEN", + direction="on", + linebreak="al", + unicodeslot=0x10160, + }, + [0x10161]={ + category="nl", + description="GREEK ACROPHONIC TROEZENIAN TEN ALTERNATE FORM", + direction="on", + linebreak="al", + unicodeslot=0x10161, + }, + [0x10162]={ + category="nl", + description="GREEK ACROPHONIC HERMIONIAN TEN", + direction="on", + linebreak="al", + unicodeslot=0x10162, + }, + [0x10163]={ + category="nl", + description="GREEK ACROPHONIC MESSENIAN TEN", + direction="on", + linebreak="al", + unicodeslot=0x10163, + }, + [0x10164]={ + category="nl", + description="GREEK ACROPHONIC THESPIAN TEN", + direction="on", + linebreak="al", + unicodeslot=0x10164, + }, + [0x10165]={ + category="nl", + description="GREEK ACROPHONIC THESPIAN THIRTY", + direction="on", + linebreak="al", + unicodeslot=0x10165, + }, + [0x10166]={ + category="nl", + description="GREEK ACROPHONIC TROEZENIAN FIFTY", + direction="on", + linebreak="al", + unicodeslot=0x10166, + }, + [0x10167]={ + category="nl", + description="GREEK ACROPHONIC TROEZENIAN FIFTY ALTERNATE FORM", + direction="on", + linebreak="al", + unicodeslot=0x10167, + }, + [0x10168]={ + category="nl", + description="GREEK ACROPHONIC HERMIONIAN FIFTY", + direction="on", + linebreak="al", + unicodeslot=0x10168, + }, + [0x10169]={ + category="nl", + description="GREEK ACROPHONIC THESPIAN FIFTY", + direction="on", + linebreak="al", + unicodeslot=0x10169, + }, + [0x1016A]={ + category="nl", + description="GREEK ACROPHONIC THESPIAN ONE HUNDRED", + direction="on", + linebreak="al", + unicodeslot=0x1016A, + }, + [0x1016B]={ + category="nl", + description="GREEK ACROPHONIC THESPIAN THREE HUNDRED", + direction="on", + linebreak="al", + unicodeslot=0x1016B, + }, + [0x1016C]={ + category="nl", + description="GREEK ACROPHONIC EPIDAUREAN FIVE HUNDRED", + direction="on", + linebreak="al", + unicodeslot=0x1016C, + }, + [0x1016D]={ + category="nl", + description="GREEK ACROPHONIC TROEZENIAN FIVE HUNDRED", + direction="on", + linebreak="al", + unicodeslot=0x1016D, + }, + [0x1016E]={ + category="nl", + description="GREEK ACROPHONIC THESPIAN FIVE HUNDRED", + direction="on", + linebreak="al", + unicodeslot=0x1016E, + }, + [0x1016F]={ + category="nl", + description="GREEK ACROPHONIC CARYSTIAN FIVE HUNDRED", + direction="on", + linebreak="al", + unicodeslot=0x1016F, + }, + [0x10170]={ + category="nl", + description="GREEK ACROPHONIC NAXIAN FIVE HUNDRED", + direction="on", + linebreak="al", + unicodeslot=0x10170, + }, + [0x10171]={ + category="nl", + description="GREEK ACROPHONIC THESPIAN ONE THOUSAND", + direction="on", + linebreak="al", + unicodeslot=0x10171, + }, + [0x10172]={ + category="nl", + description="GREEK ACROPHONIC THESPIAN FIVE THOUSAND", + direction="on", + linebreak="al", + unicodeslot=0x10172, + }, + [0x10173]={ + category="nl", + description="GREEK ACROPHONIC DELPHIC FIVE MNAS", + direction="on", + linebreak="al", + unicodeslot=0x10173, + }, + [0x10174]={ + category="nl", + description="GREEK ACROPHONIC STRATIAN FIFTY MNAS", + direction="on", + linebreak="al", + unicodeslot=0x10174, + }, + [0x10175]={ + category="no", + description="GREEK ONE HALF SIGN", + direction="on", + linebreak="al", + unicodeslot=0x10175, + }, + [0x10176]={ + category="no", + description="GREEK ONE HALF SIGN ALTERNATE FORM", + direction="on", + linebreak="al", + unicodeslot=0x10176, + }, + [0x10177]={ + category="no", + description="GREEK TWO THIRDS SIGN", + direction="on", + linebreak="al", + unicodeslot=0x10177, + }, + [0x10178]={ + category="no", + description="GREEK THREE QUARTERS SIGN", + direction="on", + linebreak="al", + unicodeslot=0x10178, + }, + [0x10179]={ + category="so", + description="GREEK YEAR SIGN", + direction="on", + linebreak="al", + unicodeslot=0x10179, + }, + [0x1017A]={ + category="so", + description="GREEK TALENT SIGN", + direction="on", + linebreak="al", + unicodeslot=0x1017A, + }, + [0x1017B]={ + category="so", + description="GREEK DRACHMA SIGN", + direction="on", + linebreak="al", + unicodeslot=0x1017B, + }, + [0x1017C]={ + category="so", + description="GREEK OBOL SIGN", + direction="on", + linebreak="al", + unicodeslot=0x1017C, + }, + [0x1017D]={ + category="so", + description="GREEK TWO OBOLS SIGN", + direction="on", + linebreak="al", + unicodeslot=0x1017D, + }, + [0x1017E]={ + category="so", + description="GREEK THREE OBOLS SIGN", + direction="on", + linebreak="al", + unicodeslot=0x1017E, + }, + [0x1017F]={ + category="so", + description="GREEK FOUR OBOLS SIGN", + direction="on", + linebreak="al", + unicodeslot=0x1017F, + }, + [0x10180]={ + category="so", + description="GREEK FIVE OBOLS SIGN", + direction="on", + linebreak="al", + unicodeslot=0x10180, + }, + [0x10181]={ + category="so", + description="GREEK METRETES SIGN", + direction="on", + linebreak="al", + unicodeslot=0x10181, + }, + [0x10182]={ + category="so", + description="GREEK KYATHOS BASE SIGN", + direction="on", + linebreak="al", + unicodeslot=0x10182, + }, + [0x10183]={ + category="so", + description="GREEK LITRA SIGN", + direction="on", + linebreak="al", + unicodeslot=0x10183, + }, + [0x10184]={ + category="so", + description="GREEK OUNKIA SIGN", + direction="on", + linebreak="al", + unicodeslot=0x10184, + }, + [0x10185]={ + category="so", + description="GREEK XESTES SIGN", + direction="on", + linebreak="al", + unicodeslot=0x10185, + }, + [0x10186]={ + category="so", + description="GREEK ARTABE SIGN", + direction="on", + linebreak="al", + unicodeslot=0x10186, + }, + [0x10187]={ + category="so", + description="GREEK AROURA SIGN", + direction="on", + linebreak="al", + unicodeslot=0x10187, + }, + [0x10188]={ + category="so", + description="GREEK GRAMMA SIGN", + direction="on", + linebreak="al", + unicodeslot=0x10188, + }, + [0x10189]={ + category="so", + description="GREEK TRYBLION BASE SIGN", + direction="on", + linebreak="al", + unicodeslot=0x10189, + }, + [0x1018A]={ + category="no", + description="GREEK ZERO SIGN", + direction="on", + linebreak="al", + unicodeslot=0x1018A, + }, + [0x10300]={ + category="lo", + description="OLD ITALIC LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x10300, + }, + [0x10301]={ + category="lo", + description="OLD ITALIC LETTER BE", + direction="l", + linebreak="al", + unicodeslot=0x10301, + }, + [0x10302]={ + category="lo", + description="OLD ITALIC LETTER KE", + direction="l", + linebreak="al", + unicodeslot=0x10302, + }, + [0x10303]={ + category="lo", + description="OLD ITALIC LETTER DE", + direction="l", + linebreak="al", + unicodeslot=0x10303, + }, + [0x10304]={ + category="lo", + description="OLD ITALIC LETTER E", + direction="l", + linebreak="al", + unicodeslot=0x10304, + }, + [0x10305]={ + category="lo", + description="OLD ITALIC LETTER VE", + direction="l", + linebreak="al", + unicodeslot=0x10305, + }, + [0x10306]={ + category="lo", + description="OLD ITALIC LETTER ZE", + direction="l", + linebreak="al", + unicodeslot=0x10306, + }, + [0x10307]={ + category="lo", + description="OLD ITALIC LETTER HE", + direction="l", + linebreak="al", + unicodeslot=0x10307, + }, + [0x10308]={ + category="lo", + description="OLD ITALIC LETTER THE", + direction="l", + linebreak="al", + unicodeslot=0x10308, + }, + [0x10309]={ + category="lo", + description="OLD ITALIC LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x10309, + }, + [0x1030A]={ + category="lo", + description="OLD ITALIC LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x1030A, + }, + [0x1030B]={ + category="lo", + description="OLD ITALIC LETTER EL", + direction="l", + linebreak="al", + unicodeslot=0x1030B, + }, + [0x1030C]={ + category="lo", + description="OLD ITALIC LETTER EM", + direction="l", + linebreak="al", + unicodeslot=0x1030C, + }, + [0x1030D]={ + category="lo", + description="OLD ITALIC LETTER EN", + direction="l", + linebreak="al", + unicodeslot=0x1030D, + }, + [0x1030E]={ + category="lo", + description="OLD ITALIC LETTER ESH", + direction="l", + linebreak="al", + unicodeslot=0x1030E, + }, + [0x1030F]={ + category="lo", + description="OLD ITALIC LETTER O", + direction="l", + linebreak="al", + unicodeslot=0x1030F, + }, + [0x10310]={ + category="lo", + description="OLD ITALIC LETTER PE", + direction="l", + linebreak="al", + unicodeslot=0x10310, + }, + [0x10311]={ + category="lo", + description="OLD ITALIC LETTER SHE", + direction="l", + linebreak="al", + unicodeslot=0x10311, + }, + [0x10312]={ + category="lo", + description="OLD ITALIC LETTER KU", + direction="l", + linebreak="al", + unicodeslot=0x10312, + }, + [0x10313]={ + category="lo", + description="OLD ITALIC LETTER ER", + direction="l", + linebreak="al", + unicodeslot=0x10313, + }, + [0x10314]={ + category="lo", + description="OLD ITALIC LETTER ES", + direction="l", + linebreak="al", + unicodeslot=0x10314, + }, + [0x10315]={ + category="lo", + description="OLD ITALIC LETTER TE", + direction="l", + linebreak="al", + unicodeslot=0x10315, + }, + [0x10316]={ + category="lo", + description="OLD ITALIC LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x10316, + }, + [0x10317]={ + category="lo", + description="OLD ITALIC LETTER EKS", + direction="l", + linebreak="al", + unicodeslot=0x10317, + }, + [0x10318]={ + category="lo", + description="OLD ITALIC LETTER PHE", + direction="l", + linebreak="al", + unicodeslot=0x10318, + }, + [0x10319]={ + category="lo", + description="OLD ITALIC LETTER KHE", + direction="l", + linebreak="al", + unicodeslot=0x10319, + }, + [0x1031A]={ + category="lo", + description="OLD ITALIC LETTER EF", + direction="l", + linebreak="al", + unicodeslot=0x1031A, + }, + [0x1031B]={ + category="lo", + description="OLD ITALIC LETTER ERS", + direction="l", + linebreak="al", + unicodeslot=0x1031B, + }, + [0x1031C]={ + category="lo", + description="OLD ITALIC LETTER CHE", + direction="l", + linebreak="al", + unicodeslot=0x1031C, + }, + [0x1031D]={ + category="lo", + description="OLD ITALIC LETTER II", + direction="l", + linebreak="al", + unicodeslot=0x1031D, + }, + [0x1031E]={ + category="lo", + description="OLD ITALIC LETTER UU", + direction="l", + linebreak="al", + unicodeslot=0x1031E, + }, + [0x10320]={ + category="no", + description="OLD ITALIC NUMERAL ONE", + direction="l", + linebreak="al", + unicodeslot=0x10320, + }, + [0x10321]={ + category="no", + description="OLD ITALIC NUMERAL FIVE", + direction="l", + linebreak="al", + unicodeslot=0x10321, + }, + [0x10322]={ + category="no", + description="OLD ITALIC NUMERAL TEN", + direction="l", + linebreak="al", + unicodeslot=0x10322, + }, + [0x10323]={ + category="no", + description="OLD ITALIC NUMERAL FIFTY", + direction="l", + linebreak="al", + unicodeslot=0x10323, + }, + [0x10330]={ + category="lo", + description="GOTHIC LETTER AHSA", + direction="l", + linebreak="al", + unicodeslot=0x10330, + }, + [0x10331]={ + category="lo", + description="GOTHIC LETTER BAIRKAN", + direction="l", + linebreak="al", + unicodeslot=0x10331, + }, + [0x10332]={ + category="lo", + description="GOTHIC LETTER GIBA", + direction="l", + linebreak="al", + unicodeslot=0x10332, + }, + [0x10333]={ + category="lo", + description="GOTHIC LETTER DAGS", + direction="l", + linebreak="al", + unicodeslot=0x10333, + }, + [0x10334]={ + category="lo", + description="GOTHIC LETTER AIHVUS", + direction="l", + linebreak="al", + unicodeslot=0x10334, + }, + [0x10335]={ + category="lo", + description="GOTHIC LETTER QAIRTHRA", + direction="l", + linebreak="al", + unicodeslot=0x10335, + }, + [0x10336]={ + category="lo", + description="GOTHIC LETTER IUJA", + direction="l", + linebreak="al", + unicodeslot=0x10336, + }, + [0x10337]={ + category="lo", + description="GOTHIC LETTER HAGL", + direction="l", + linebreak="al", + unicodeslot=0x10337, + }, + [0x10338]={ + category="lo", + description="GOTHIC LETTER THIUTH", + direction="l", + linebreak="al", + unicodeslot=0x10338, + }, + [0x10339]={ + category="lo", + description="GOTHIC LETTER EIS", + direction="l", + linebreak="al", + unicodeslot=0x10339, + }, + [0x1033A]={ + category="lo", + description="GOTHIC LETTER KUSMA", + direction="l", + linebreak="al", + unicodeslot=0x1033A, + }, + [0x1033B]={ + category="lo", + description="GOTHIC LETTER LAGUS", + direction="l", + linebreak="al", + unicodeslot=0x1033B, + }, + [0x1033C]={ + category="lo", + description="GOTHIC LETTER MANNA", + direction="l", + linebreak="al", + unicodeslot=0x1033C, + }, + [0x1033D]={ + category="lo", + description="GOTHIC LETTER NAUTHS", + direction="l", + linebreak="al", + unicodeslot=0x1033D, + }, + [0x1033E]={ + category="lo", + description="GOTHIC LETTER JER", + direction="l", + linebreak="al", + unicodeslot=0x1033E, + }, + [0x1033F]={ + category="lo", + description="GOTHIC LETTER URUS", + direction="l", + linebreak="al", + unicodeslot=0x1033F, + }, + [0x10340]={ + category="lo", + description="GOTHIC LETTER PAIRTHRA", + direction="l", + linebreak="al", + unicodeslot=0x10340, + }, + [0x10341]={ + category="nl", + description="GOTHIC LETTER NINETY", + direction="l", + linebreak="al", + unicodeslot=0x10341, + }, + [0x10342]={ + category="lo", + description="GOTHIC LETTER RAIDA", + direction="l", + linebreak="al", + unicodeslot=0x10342, + }, + [0x10343]={ + category="lo", + description="GOTHIC LETTER SAUIL", + direction="l", + linebreak="al", + unicodeslot=0x10343, + }, + [0x10344]={ + category="lo", + description="GOTHIC LETTER TEIWS", + direction="l", + linebreak="al", + unicodeslot=0x10344, + }, + [0x10345]={ + category="lo", + description="GOTHIC LETTER WINJA", + direction="l", + linebreak="al", + unicodeslot=0x10345, + }, + [0x10346]={ + category="lo", + description="GOTHIC LETTER FAIHU", + direction="l", + linebreak="al", + unicodeslot=0x10346, + }, + [0x10347]={ + category="lo", + description="GOTHIC LETTER IGGWS", + direction="l", + linebreak="al", + unicodeslot=0x10347, + }, + [0x10348]={ + category="lo", + description="GOTHIC LETTER HWAIR", + direction="l", + linebreak="al", + unicodeslot=0x10348, + }, + [0x10349]={ + category="lo", + description="GOTHIC LETTER OTHAL", + direction="l", + linebreak="al", + unicodeslot=0x10349, + }, + [0x1034A]={ + category="nl", + description="GOTHIC LETTER NINE HUNDRED", + direction="l", + linebreak="al", + unicodeslot=0x1034A, + }, + [0x10380]={ + category="lo", + description="UGARITIC LETTER ALPA", + direction="l", + linebreak="al", + unicodeslot=0x10380, + }, + [0x10381]={ + category="lo", + description="UGARITIC LETTER BETA", + direction="l", + linebreak="al", + unicodeslot=0x10381, + }, + [0x10382]={ + category="lo", + description="UGARITIC LETTER GAMLA", + direction="l", + linebreak="al", + unicodeslot=0x10382, + }, + [0x10383]={ + category="lo", + description="UGARITIC LETTER KHA", + direction="l", + linebreak="al", + unicodeslot=0x10383, + }, + [0x10384]={ + category="lo", + description="UGARITIC LETTER DELTA", + direction="l", + linebreak="al", + unicodeslot=0x10384, + }, + [0x10385]={ + category="lo", + description="UGARITIC LETTER HO", + direction="l", + linebreak="al", + unicodeslot=0x10385, + }, + [0x10386]={ + category="lo", + description="UGARITIC LETTER WO", + direction="l", + linebreak="al", + unicodeslot=0x10386, + }, + [0x10387]={ + category="lo", + description="UGARITIC LETTER ZETA", + direction="l", + linebreak="al", + unicodeslot=0x10387, + }, + [0x10388]={ + category="lo", + description="UGARITIC LETTER HOTA", + direction="l", + linebreak="al", + unicodeslot=0x10388, + }, + [0x10389]={ + category="lo", + description="UGARITIC LETTER TET", + direction="l", + linebreak="al", + unicodeslot=0x10389, + }, + [0x1038A]={ + category="lo", + description="UGARITIC LETTER YOD", + direction="l", + linebreak="al", + unicodeslot=0x1038A, + }, + [0x1038B]={ + category="lo", + description="UGARITIC LETTER KAF", + direction="l", + linebreak="al", + unicodeslot=0x1038B, + }, + [0x1038C]={ + category="lo", + description="UGARITIC LETTER SHIN", + direction="l", + linebreak="al", + unicodeslot=0x1038C, + }, + [0x1038D]={ + category="lo", + description="UGARITIC LETTER LAMDA", + direction="l", + linebreak="al", + unicodeslot=0x1038D, + }, + [0x1038E]={ + category="lo", + description="UGARITIC LETTER MEM", + direction="l", + linebreak="al", + unicodeslot=0x1038E, + }, + [0x1038F]={ + category="lo", + description="UGARITIC LETTER DHAL", + direction="l", + linebreak="al", + unicodeslot=0x1038F, + }, + [0x10390]={ + category="lo", + description="UGARITIC LETTER NUN", + direction="l", + linebreak="al", + unicodeslot=0x10390, + }, + [0x10391]={ + category="lo", + description="UGARITIC LETTER ZU", + direction="l", + linebreak="al", + unicodeslot=0x10391, + }, + [0x10392]={ + category="lo", + description="UGARITIC LETTER SAMKA", + direction="l", + linebreak="al", + unicodeslot=0x10392, + }, + [0x10393]={ + category="lo", + description="UGARITIC LETTER AIN", + direction="l", + linebreak="al", + unicodeslot=0x10393, + }, + [0x10394]={ + category="lo", + description="UGARITIC LETTER PU", + direction="l", + linebreak="al", + unicodeslot=0x10394, + }, + [0x10395]={ + category="lo", + description="UGARITIC LETTER SADE", + direction="l", + linebreak="al", + unicodeslot=0x10395, + }, + [0x10396]={ + category="lo", + description="UGARITIC LETTER QOPA", + direction="l", + linebreak="al", + unicodeslot=0x10396, + }, + [0x10397]={ + category="lo", + description="UGARITIC LETTER RASHA", + direction="l", + linebreak="al", + unicodeslot=0x10397, + }, + [0x10398]={ + category="lo", + description="UGARITIC LETTER THANNA", + direction="l", + linebreak="al", + unicodeslot=0x10398, + }, + [0x10399]={ + category="lo", + description="UGARITIC LETTER GHAIN", + direction="l", + linebreak="al", + unicodeslot=0x10399, + }, + [0x1039A]={ + category="lo", + description="UGARITIC LETTER TO", + direction="l", + linebreak="al", + unicodeslot=0x1039A, + }, + [0x1039B]={ + category="lo", + description="UGARITIC LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x1039B, + }, + [0x1039C]={ + category="lo", + description="UGARITIC LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x1039C, + }, + [0x1039D]={ + category="lo", + description="UGARITIC LETTER SSU", + direction="l", + linebreak="al", + unicodeslot=0x1039D, + }, + [0x1039F]={ + category="po", + description="UGARITIC WORD DIVIDER", + direction="l", + linebreak="ba", + unicodeslot=0x1039F, + }, + [0x103A0]={ + category="lo", + description="OLD PERSIAN SIGN A", + direction="l", + linebreak="al", + unicodeslot=0x103A0, + }, + [0x103A1]={ + category="lo", + description="OLD PERSIAN SIGN I", + direction="l", + linebreak="al", + unicodeslot=0x103A1, + }, + [0x103A2]={ + category="lo", + description="OLD PERSIAN SIGN U", + direction="l", + linebreak="al", + unicodeslot=0x103A2, + }, + [0x103A3]={ + category="lo", + description="OLD PERSIAN SIGN KA", + direction="l", + linebreak="al", + unicodeslot=0x103A3, + }, + [0x103A4]={ + category="lo", + description="OLD PERSIAN SIGN KU", + direction="l", + linebreak="al", + unicodeslot=0x103A4, + }, + [0x103A5]={ + category="lo", + description="OLD PERSIAN SIGN GA", + direction="l", + linebreak="al", + unicodeslot=0x103A5, + }, + [0x103A6]={ + category="lo", + description="OLD PERSIAN SIGN GU", + direction="l", + linebreak="al", + unicodeslot=0x103A6, + }, + [0x103A7]={ + category="lo", + description="OLD PERSIAN SIGN XA", + direction="l", + linebreak="al", + unicodeslot=0x103A7, + }, + [0x103A8]={ + category="lo", + description="OLD PERSIAN SIGN CA", + direction="l", + linebreak="al", + unicodeslot=0x103A8, + }, + [0x103A9]={ + category="lo", + description="OLD PERSIAN SIGN JA", + direction="l", + linebreak="al", + unicodeslot=0x103A9, + }, + [0x103AA]={ + category="lo", + description="OLD PERSIAN SIGN JI", + direction="l", + linebreak="al", + unicodeslot=0x103AA, + }, + [0x103AB]={ + category="lo", + description="OLD PERSIAN SIGN TA", + direction="l", + linebreak="al", + unicodeslot=0x103AB, + }, + [0x103AC]={ + category="lo", + description="OLD PERSIAN SIGN TU", + direction="l", + linebreak="al", + unicodeslot=0x103AC, + }, + [0x103AD]={ + category="lo", + description="OLD PERSIAN SIGN DA", + direction="l", + linebreak="al", + unicodeslot=0x103AD, + }, + [0x103AE]={ + category="lo", + description="OLD PERSIAN SIGN DI", + direction="l", + linebreak="al", + unicodeslot=0x103AE, + }, + [0x103AF]={ + category="lo", + description="OLD PERSIAN SIGN DU", + direction="l", + linebreak="al", + unicodeslot=0x103AF, + }, + [0x103B0]={ + category="lo", + description="OLD PERSIAN SIGN THA", + direction="l", + linebreak="al", + unicodeslot=0x103B0, + }, + [0x103B1]={ + category="lo", + description="OLD PERSIAN SIGN PA", + direction="l", + linebreak="al", + unicodeslot=0x103B1, + }, + [0x103B2]={ + category="lo", + description="OLD PERSIAN SIGN BA", + direction="l", + linebreak="al", + unicodeslot=0x103B2, + }, + [0x103B3]={ + category="lo", + description="OLD PERSIAN SIGN FA", + direction="l", + linebreak="al", + unicodeslot=0x103B3, + }, + [0x103B4]={ + category="lo", + description="OLD PERSIAN SIGN NA", + direction="l", + linebreak="al", + unicodeslot=0x103B4, + }, + [0x103B5]={ + category="lo", + description="OLD PERSIAN SIGN NU", + direction="l", + linebreak="al", + unicodeslot=0x103B5, + }, + [0x103B6]={ + category="lo", + description="OLD PERSIAN SIGN MA", + direction="l", + linebreak="al", + unicodeslot=0x103B6, + }, + [0x103B7]={ + category="lo", + description="OLD PERSIAN SIGN MI", + direction="l", + linebreak="al", + unicodeslot=0x103B7, + }, + [0x103B8]={ + category="lo", + description="OLD PERSIAN SIGN MU", + direction="l", + linebreak="al", + unicodeslot=0x103B8, + }, + [0x103B9]={ + category="lo", + description="OLD PERSIAN SIGN YA", + direction="l", + linebreak="al", + unicodeslot=0x103B9, + }, + [0x103BA]={ + category="lo", + description="OLD PERSIAN SIGN VA", + direction="l", + linebreak="al", + unicodeslot=0x103BA, + }, + [0x103BB]={ + category="lo", + description="OLD PERSIAN SIGN VI", + direction="l", + linebreak="al", + unicodeslot=0x103BB, + }, + [0x103BC]={ + category="lo", + description="OLD PERSIAN SIGN RA", + direction="l", + linebreak="al", + unicodeslot=0x103BC, + }, + [0x103BD]={ + category="lo", + description="OLD PERSIAN SIGN RU", + direction="l", + linebreak="al", + unicodeslot=0x103BD, + }, + [0x103BE]={ + category="lo", + description="OLD PERSIAN SIGN LA", + direction="l", + linebreak="al", + unicodeslot=0x103BE, + }, + [0x103BF]={ + category="lo", + description="OLD PERSIAN SIGN SA", + direction="l", + linebreak="al", + unicodeslot=0x103BF, + }, + [0x103C0]={ + category="lo", + description="OLD PERSIAN SIGN ZA", + direction="l", + linebreak="al", + unicodeslot=0x103C0, + }, + [0x103C1]={ + category="lo", + description="OLD PERSIAN SIGN SHA", + direction="l", + linebreak="al", + unicodeslot=0x103C1, + }, + [0x103C2]={ + category="lo", + description="OLD PERSIAN SIGN SSA", + direction="l", + linebreak="al", + unicodeslot=0x103C2, + }, + [0x103C3]={ + category="lo", + description="OLD PERSIAN SIGN HA", + direction="l", + linebreak="al", + unicodeslot=0x103C3, + }, + [0x103C8]={ + category="lo", + description="OLD PERSIAN SIGN AURAMAZDAA", + direction="l", + linebreak="al", + unicodeslot=0x103C8, + }, + [0x103C9]={ + category="lo", + description="OLD PERSIAN SIGN AURAMAZDAA-0x0002", + direction="l", + linebreak="al", + unicodeslot=0x103C9, + }, + [0x103CA]={ + category="lo", + description="OLD PERSIAN SIGN AURAMAZDAAHA", + direction="l", + linebreak="al", + unicodeslot=0x103CA, + }, + [0x103CB]={ + category="lo", + description="OLD PERSIAN SIGN XSHAAYATHIYA", + direction="l", + linebreak="al", + unicodeslot=0x103CB, + }, + [0x103CC]={ + category="lo", + description="OLD PERSIAN SIGN DAHYAAUSH", + direction="l", + linebreak="al", + unicodeslot=0x103CC, + }, + [0x103CD]={ + category="lo", + description="OLD PERSIAN SIGN DAHYAAUSH-0x0002", + direction="l", + linebreak="al", + unicodeslot=0x103CD, + }, + [0x103CE]={ + category="lo", + description="OLD PERSIAN SIGN BAGA", + direction="l", + linebreak="al", + unicodeslot=0x103CE, + }, + [0x103CF]={ + category="lo", + description="OLD PERSIAN SIGN BUUMISH", + direction="l", + linebreak="al", + unicodeslot=0x103CF, + }, + [0x103D0]={ + category="po", + description="OLD PERSIAN WORD DIVIDER", + direction="l", + linebreak="ba", + unicodeslot=0x103D0, + }, + [0x103D1]={ + category="nl", + description="OLD PERSIAN NUMBER ONE", + direction="l", + linebreak="al", + unicodeslot=0x103D1, + }, + [0x103D2]={ + category="nl", + description="OLD PERSIAN NUMBER TWO", + direction="l", + linebreak="al", + unicodeslot=0x103D2, + }, + [0x103D3]={ + category="nl", + description="OLD PERSIAN NUMBER TEN", + direction="l", + linebreak="al", + unicodeslot=0x103D3, + }, + [0x103D4]={ + category="nl", + description="OLD PERSIAN NUMBER TWENTY", + direction="l", + linebreak="al", + unicodeslot=0x103D4, + }, + [0x103D5]={ + category="nl", + description="OLD PERSIAN NUMBER HUNDRED", + direction="l", + linebreak="al", + unicodeslot=0x103D5, + }, + [0x10400]={ + category="lu", + description="DESERET CAPITAL LETTER LONG I", + direction="l", + lccode=0x10428, + linebreak="al", + unicodeslot=0x10400, + }, + [0x10401]={ + category="lu", + description="DESERET CAPITAL LETTER LONG E", + direction="l", + lccode=0x10429, + linebreak="al", + unicodeslot=0x10401, + }, + [0x10402]={ + category="lu", + description="DESERET CAPITAL LETTER LONG A", + direction="l", + lccode=0x1042A, + linebreak="al", + unicodeslot=0x10402, + }, + [0x10403]={ + category="lu", + description="DESERET CAPITAL LETTER LONG AH", + direction="l", + lccode=0x1042B, + linebreak="al", + unicodeslot=0x10403, + }, + [0x10404]={ + category="lu", + description="DESERET CAPITAL LETTER LONG O", + direction="l", + lccode=0x1042C, + linebreak="al", + unicodeslot=0x10404, + }, + [0x10405]={ + category="lu", + description="DESERET CAPITAL LETTER LONG OO", + direction="l", + lccode=0x1042D, + linebreak="al", + unicodeslot=0x10405, + }, + [0x10406]={ + category="lu", + description="DESERET CAPITAL LETTER SHORT I", + direction="l", + lccode=0x1042E, + linebreak="al", + unicodeslot=0x10406, + }, + [0x10407]={ + category="lu", + description="DESERET CAPITAL LETTER SHORT E", + direction="l", + lccode=0x1042F, + linebreak="al", + unicodeslot=0x10407, + }, + [0x10408]={ + category="lu", + description="DESERET CAPITAL LETTER SHORT A", + direction="l", + lccode=0x10430, + linebreak="al", + unicodeslot=0x10408, + }, + [0x10409]={ + category="lu", + description="DESERET CAPITAL LETTER SHORT AH", + direction="l", + lccode=0x10431, + linebreak="al", + unicodeslot=0x10409, + }, + [0x1040A]={ + category="lu", + description="DESERET CAPITAL LETTER SHORT O", + direction="l", + lccode=0x10432, + linebreak="al", + unicodeslot=0x1040A, + }, + [0x1040B]={ + category="lu", + description="DESERET CAPITAL LETTER SHORT OO", + direction="l", + lccode=0x10433, + linebreak="al", + unicodeslot=0x1040B, + }, + [0x1040C]={ + category="lu", + description="DESERET CAPITAL LETTER AY", + direction="l", + lccode=0x10434, + linebreak="al", + unicodeslot=0x1040C, + }, + [0x1040D]={ + category="lu", + description="DESERET CAPITAL LETTER OW", + direction="l", + lccode=0x10435, + linebreak="al", + unicodeslot=0x1040D, + }, + [0x1040E]={ + category="lu", + description="DESERET CAPITAL LETTER WU", + direction="l", + lccode=0x10436, + linebreak="al", + unicodeslot=0x1040E, + }, + [0x1040F]={ + category="lu", + description="DESERET CAPITAL LETTER YEE", + direction="l", + lccode=0x10437, + linebreak="al", + unicodeslot=0x1040F, + }, + [0x10410]={ + category="lu", + description="DESERET CAPITAL LETTER H", + direction="l", + lccode=0x10438, + linebreak="al", + unicodeslot=0x10410, + }, + [0x10411]={ + category="lu", + description="DESERET CAPITAL LETTER PEE", + direction="l", + lccode=0x10439, + linebreak="al", + unicodeslot=0x10411, + }, + [0x10412]={ + category="lu", + description="DESERET CAPITAL LETTER BEE", + direction="l", + lccode=0x1043A, + linebreak="al", + unicodeslot=0x10412, + }, + [0x10413]={ + category="lu", + description="DESERET CAPITAL LETTER TEE", + direction="l", + lccode=0x1043B, + linebreak="al", + unicodeslot=0x10413, + }, + [0x10414]={ + category="lu", + description="DESERET CAPITAL LETTER DEE", + direction="l", + lccode=0x1043C, + linebreak="al", + unicodeslot=0x10414, + }, + [0x10415]={ + category="lu", + description="DESERET CAPITAL LETTER CHEE", + direction="l", + lccode=0x1043D, + linebreak="al", + unicodeslot=0x10415, + }, + [0x10416]={ + category="lu", + description="DESERET CAPITAL LETTER JEE", + direction="l", + lccode=0x1043E, + linebreak="al", + unicodeslot=0x10416, + }, + [0x10417]={ + category="lu", + description="DESERET CAPITAL LETTER KAY", + direction="l", + lccode=0x1043F, + linebreak="al", + unicodeslot=0x10417, + }, + [0x10418]={ + category="lu", + description="DESERET CAPITAL LETTER GAY", + direction="l", + lccode=0x10440, + linebreak="al", + unicodeslot=0x10418, + }, + [0x10419]={ + category="lu", + description="DESERET CAPITAL LETTER EF", + direction="l", + lccode=0x10441, + linebreak="al", + unicodeslot=0x10419, + }, + [0x1041A]={ + category="lu", + description="DESERET CAPITAL LETTER VEE", + direction="l", + lccode=0x10442, + linebreak="al", + unicodeslot=0x1041A, + }, + [0x1041B]={ + category="lu", + description="DESERET CAPITAL LETTER ETH", + direction="l", + lccode=0x10443, + linebreak="al", + unicodeslot=0x1041B, + }, + [0x1041C]={ + category="lu", + description="DESERET CAPITAL LETTER THEE", + direction="l", + lccode=0x10444, + linebreak="al", + unicodeslot=0x1041C, + }, + [0x1041D]={ + category="lu", + description="DESERET CAPITAL LETTER ES", + direction="l", + lccode=0x10445, + linebreak="al", + unicodeslot=0x1041D, + }, + [0x1041E]={ + category="lu", + description="DESERET CAPITAL LETTER ZEE", + direction="l", + lccode=0x10446, + linebreak="al", + unicodeslot=0x1041E, + }, + [0x1041F]={ + category="lu", + description="DESERET CAPITAL LETTER ESH", + direction="l", + lccode=0x10447, + linebreak="al", + unicodeslot=0x1041F, + }, + [0x10420]={ + category="lu", + description="DESERET CAPITAL LETTER ZHEE", + direction="l", + lccode=0x10448, + linebreak="al", + unicodeslot=0x10420, + }, + [0x10421]={ + category="lu", + description="DESERET CAPITAL LETTER ER", + direction="l", + lccode=0x10449, + linebreak="al", + unicodeslot=0x10421, + }, + [0x10422]={ + category="lu", + description="DESERET CAPITAL LETTER EL", + direction="l", + lccode=0x1044A, + linebreak="al", + unicodeslot=0x10422, + }, + [0x10423]={ + category="lu", + description="DESERET CAPITAL LETTER EM", + direction="l", + lccode=0x1044B, + linebreak="al", + unicodeslot=0x10423, + }, + [0x10424]={ + category="lu", + description="DESERET CAPITAL LETTER EN", + direction="l", + lccode=0x1044C, + linebreak="al", + unicodeslot=0x10424, + }, + [0x10425]={ + category="lu", + description="DESERET CAPITAL LETTER ENG", + direction="l", + lccode=0x1044D, + linebreak="al", + unicodeslot=0x10425, + }, + [0x10426]={ + category="lu", + description="DESERET CAPITAL LETTER OI", + direction="l", + lccode=0x1044E, + linebreak="al", + unicodeslot=0x10426, + }, + [0x10427]={ + category="lu", + description="DESERET CAPITAL LETTER EW", + direction="l", + lccode=0x1044F, + linebreak="al", + unicodeslot=0x10427, + }, + [0x10428]={ + category="ll", + description="DESERET SMALL LETTER LONG I", + direction="l", + linebreak="al", + uccode=0x10400, + unicodeslot=0x10428, + }, + [0x10429]={ + category="ll", + description="DESERET SMALL LETTER LONG E", + direction="l", + linebreak="al", + uccode=0x10401, + unicodeslot=0x10429, + }, + [0x1042A]={ + category="ll", + description="DESERET SMALL LETTER LONG A", + direction="l", + linebreak="al", + uccode=0x10402, + unicodeslot=0x1042A, + }, + [0x1042B]={ + category="ll", + description="DESERET SMALL LETTER LONG AH", + direction="l", + linebreak="al", + uccode=0x10403, + unicodeslot=0x1042B, + }, + [0x1042C]={ + category="ll", + description="DESERET SMALL LETTER LONG O", + direction="l", + linebreak="al", + uccode=0x10404, + unicodeslot=0x1042C, + }, + [0x1042D]={ + category="ll", + description="DESERET SMALL LETTER LONG OO", + direction="l", + linebreak="al", + uccode=0x10405, + unicodeslot=0x1042D, + }, + [0x1042E]={ + category="ll", + description="DESERET SMALL LETTER SHORT I", + direction="l", + linebreak="al", + uccode=0x10406, + unicodeslot=0x1042E, + }, + [0x1042F]={ + category="ll", + description="DESERET SMALL LETTER SHORT E", + direction="l", + linebreak="al", + uccode=0x10407, + unicodeslot=0x1042F, + }, + [0x10430]={ + category="ll", + description="DESERET SMALL LETTER SHORT A", + direction="l", + linebreak="al", + uccode=0x10408, + unicodeslot=0x10430, + }, + [0x10431]={ + category="ll", + description="DESERET SMALL LETTER SHORT AH", + direction="l", + linebreak="al", + uccode=0x10409, + unicodeslot=0x10431, + }, + [0x10432]={ + category="ll", + description="DESERET SMALL LETTER SHORT O", + direction="l", + linebreak="al", + uccode=0x1040A, + unicodeslot=0x10432, + }, + [0x10433]={ + category="ll", + description="DESERET SMALL LETTER SHORT OO", + direction="l", + linebreak="al", + uccode=0x1040B, + unicodeslot=0x10433, + }, + [0x10434]={ + category="ll", + description="DESERET SMALL LETTER AY", + direction="l", + linebreak="al", + uccode=0x1040C, + unicodeslot=0x10434, + }, + [0x10435]={ + category="ll", + description="DESERET SMALL LETTER OW", + direction="l", + linebreak="al", + uccode=0x1040D, + unicodeslot=0x10435, + }, + [0x10436]={ + category="ll", + description="DESERET SMALL LETTER WU", + direction="l", + linebreak="al", + uccode=0x1040E, + unicodeslot=0x10436, + }, + [0x10437]={ + category="ll", + description="DESERET SMALL LETTER YEE", + direction="l", + linebreak="al", + uccode=0x1040F, + unicodeslot=0x10437, + }, + [0x10438]={ + category="ll", + description="DESERET SMALL LETTER H", + direction="l", + linebreak="al", + uccode=0x10410, + unicodeslot=0x10438, + }, + [0x10439]={ + category="ll", + description="DESERET SMALL LETTER PEE", + direction="l", + linebreak="al", + uccode=0x10411, + unicodeslot=0x10439, + }, + [0x1043A]={ + category="ll", + description="DESERET SMALL LETTER BEE", + direction="l", + linebreak="al", + uccode=0x10412, + unicodeslot=0x1043A, + }, + [0x1043B]={ + category="ll", + description="DESERET SMALL LETTER TEE", + direction="l", + linebreak="al", + uccode=0x10413, + unicodeslot=0x1043B, + }, + [0x1043C]={ + category="ll", + description="DESERET SMALL LETTER DEE", + direction="l", + linebreak="al", + uccode=0x10414, + unicodeslot=0x1043C, + }, + [0x1043D]={ + category="ll", + description="DESERET SMALL LETTER CHEE", + direction="l", + linebreak="al", + uccode=0x10415, + unicodeslot=0x1043D, + }, + [0x1043E]={ + category="ll", + description="DESERET SMALL LETTER JEE", + direction="l", + linebreak="al", + uccode=0x10416, + unicodeslot=0x1043E, + }, + [0x1043F]={ + category="ll", + description="DESERET SMALL LETTER KAY", + direction="l", + linebreak="al", + uccode=0x10417, + unicodeslot=0x1043F, + }, + [0x10440]={ + category="ll", + description="DESERET SMALL LETTER GAY", + direction="l", + linebreak="al", + uccode=0x10418, + unicodeslot=0x10440, + }, + [0x10441]={ + category="ll", + description="DESERET SMALL LETTER EF", + direction="l", + linebreak="al", + uccode=0x10419, + unicodeslot=0x10441, + }, + [0x10442]={ + category="ll", + description="DESERET SMALL LETTER VEE", + direction="l", + linebreak="al", + uccode=0x1041A, + unicodeslot=0x10442, + }, + [0x10443]={ + category="ll", + description="DESERET SMALL LETTER ETH", + direction="l", + linebreak="al", + uccode=0x1041B, + unicodeslot=0x10443, + }, + [0x10444]={ + category="ll", + description="DESERET SMALL LETTER THEE", + direction="l", + linebreak="al", + uccode=0x1041C, + unicodeslot=0x10444, + }, + [0x10445]={ + category="ll", + description="DESERET SMALL LETTER ES", + direction="l", + linebreak="al", + uccode=0x1041D, + unicodeslot=0x10445, + }, + [0x10446]={ + category="ll", + description="DESERET SMALL LETTER ZEE", + direction="l", + linebreak="al", + uccode=0x1041E, + unicodeslot=0x10446, + }, + [0x10447]={ + category="ll", + description="DESERET SMALL LETTER ESH", + direction="l", + linebreak="al", + uccode=0x1041F, + unicodeslot=0x10447, + }, + [0x10448]={ + category="ll", + description="DESERET SMALL LETTER ZHEE", + direction="l", + linebreak="al", + uccode=0x10420, + unicodeslot=0x10448, + }, + [0x10449]={ + category="ll", + description="DESERET SMALL LETTER ER", + direction="l", + linebreak="al", + uccode=0x10421, + unicodeslot=0x10449, + }, + [0x1044A]={ + category="ll", + description="DESERET SMALL LETTER EL", + direction="l", + linebreak="al", + uccode=0x10422, + unicodeslot=0x1044A, + }, + [0x1044B]={ + category="ll", + description="DESERET SMALL LETTER EM", + direction="l", + linebreak="al", + uccode=0x10423, + unicodeslot=0x1044B, + }, + [0x1044C]={ + category="ll", + description="DESERET SMALL LETTER EN", + direction="l", + linebreak="al", + uccode=0x10424, + unicodeslot=0x1044C, + }, + [0x1044D]={ + category="ll", + description="DESERET SMALL LETTER ENG", + direction="l", + linebreak="al", + uccode=0x10425, + unicodeslot=0x1044D, + }, + [0x1044E]={ + category="ll", + description="DESERET SMALL LETTER OI", + direction="l", + linebreak="al", + uccode=0x10426, + unicodeslot=0x1044E, + }, + [0x1044F]={ + category="ll", + description="DESERET SMALL LETTER EW", + direction="l", + linebreak="al", + uccode=0x10427, + unicodeslot=0x1044F, + }, + [0x10450]={ + category="lo", + description="SHAVIAN LETTER PEEP", + direction="l", + linebreak="al", + unicodeslot=0x10450, + }, + [0x10451]={ + category="lo", + description="SHAVIAN LETTER TOT", + direction="l", + linebreak="al", + unicodeslot=0x10451, + }, + [0x10452]={ + category="lo", + description="SHAVIAN LETTER KICK", + direction="l", + linebreak="al", + unicodeslot=0x10452, + }, + [0x10453]={ + category="lo", + description="SHAVIAN LETTER FEE", + direction="l", + linebreak="al", + unicodeslot=0x10453, + }, + [0x10454]={ + category="lo", + description="SHAVIAN LETTER THIGH", + direction="l", + linebreak="al", + unicodeslot=0x10454, + }, + [0x10455]={ + category="lo", + description="SHAVIAN LETTER SO", + direction="l", + linebreak="al", + unicodeslot=0x10455, + }, + [0x10456]={ + category="lo", + description="SHAVIAN LETTER SURE", + direction="l", + linebreak="al", + unicodeslot=0x10456, + }, + [0x10457]={ + category="lo", + description="SHAVIAN LETTER CHURCH", + direction="l", + linebreak="al", + unicodeslot=0x10457, + }, + [0x10458]={ + category="lo", + description="SHAVIAN LETTER YEA", + direction="l", + linebreak="al", + unicodeslot=0x10458, + }, + [0x10459]={ + category="lo", + description="SHAVIAN LETTER HUNG", + direction="l", + linebreak="al", + unicodeslot=0x10459, + }, + [0x1045A]={ + category="lo", + description="SHAVIAN LETTER BIB", + direction="l", + linebreak="al", + unicodeslot=0x1045A, + }, + [0x1045B]={ + category="lo", + description="SHAVIAN LETTER DEAD", + direction="l", + linebreak="al", + unicodeslot=0x1045B, + }, + [0x1045C]={ + category="lo", + description="SHAVIAN LETTER GAG", + direction="l", + linebreak="al", + unicodeslot=0x1045C, + }, + [0x1045D]={ + category="lo", + description="SHAVIAN LETTER VOW", + direction="l", + linebreak="al", + unicodeslot=0x1045D, + }, + [0x1045E]={ + category="lo", + description="SHAVIAN LETTER THEY", + direction="l", + linebreak="al", + unicodeslot=0x1045E, + }, + [0x1045F]={ + category="lo", + description="SHAVIAN LETTER ZOO", + direction="l", + linebreak="al", + unicodeslot=0x1045F, + }, + [0x10460]={ + category="lo", + description="SHAVIAN LETTER MEASURE", + direction="l", + linebreak="al", + unicodeslot=0x10460, + }, + [0x10461]={ + category="lo", + description="SHAVIAN LETTER JUDGE", + direction="l", + linebreak="al", + unicodeslot=0x10461, + }, + [0x10462]={ + category="lo", + description="SHAVIAN LETTER WOE", + direction="l", + linebreak="al", + unicodeslot=0x10462, + }, + [0x10463]={ + category="lo", + description="SHAVIAN LETTER HA-HA", + direction="l", + linebreak="al", + unicodeslot=0x10463, + }, + [0x10464]={ + category="lo", + description="SHAVIAN LETTER LOLL", + direction="l", + linebreak="al", + unicodeslot=0x10464, + }, + [0x10465]={ + category="lo", + description="SHAVIAN LETTER MIME", + direction="l", + linebreak="al", + unicodeslot=0x10465, + }, + [0x10466]={ + category="lo", + description="SHAVIAN LETTER IF", + direction="l", + linebreak="al", + unicodeslot=0x10466, + }, + [0x10467]={ + category="lo", + description="SHAVIAN LETTER EGG", + direction="l", + linebreak="al", + unicodeslot=0x10467, + }, + [0x10468]={ + category="lo", + description="SHAVIAN LETTER ASH", + direction="l", + linebreak="al", + unicodeslot=0x10468, + }, + [0x10469]={ + category="lo", + description="SHAVIAN LETTER ADO", + direction="l", + linebreak="al", + unicodeslot=0x10469, + }, + [0x1046A]={ + category="lo", + description="SHAVIAN LETTER ON", + direction="l", + linebreak="al", + unicodeslot=0x1046A, + }, + [0x1046B]={ + category="lo", + description="SHAVIAN LETTER WOOL", + direction="l", + linebreak="al", + unicodeslot=0x1046B, + }, + [0x1046C]={ + category="lo", + description="SHAVIAN LETTER OUT", + direction="l", + linebreak="al", + unicodeslot=0x1046C, + }, + [0x1046D]={ + category="lo", + description="SHAVIAN LETTER AH", + direction="l", + linebreak="al", + unicodeslot=0x1046D, + }, + [0x1046E]={ + category="lo", + description="SHAVIAN LETTER ROAR", + direction="l", + linebreak="al", + unicodeslot=0x1046E, + }, + [0x1046F]={ + category="lo", + description="SHAVIAN LETTER NUN", + direction="l", + linebreak="al", + unicodeslot=0x1046F, + }, + [0x10470]={ + category="lo", + description="SHAVIAN LETTER EAT", + direction="l", + linebreak="al", + unicodeslot=0x10470, + }, + [0x10471]={ + category="lo", + description="SHAVIAN LETTER AGE", + direction="l", + linebreak="al", + unicodeslot=0x10471, + }, + [0x10472]={ + category="lo", + description="SHAVIAN LETTER ICE", + direction="l", + linebreak="al", + unicodeslot=0x10472, + }, + [0x10473]={ + category="lo", + description="SHAVIAN LETTER UP", + direction="l", + linebreak="al", + unicodeslot=0x10473, + }, + [0x10474]={ + category="lo", + description="SHAVIAN LETTER OAK", + direction="l", + linebreak="al", + unicodeslot=0x10474, + }, + [0x10475]={ + category="lo", + description="SHAVIAN LETTER OOZE", + direction="l", + linebreak="al", + unicodeslot=0x10475, + }, + [0x10476]={ + category="lo", + description="SHAVIAN LETTER OIL", + direction="l", + linebreak="al", + unicodeslot=0x10476, + }, + [0x10477]={ + category="lo", + description="SHAVIAN LETTER AWE", + direction="l", + linebreak="al", + unicodeslot=0x10477, + }, + [0x10478]={ + category="lo", + description="SHAVIAN LETTER ARE", + direction="l", + linebreak="al", + unicodeslot=0x10478, + }, + [0x10479]={ + category="lo", + description="SHAVIAN LETTER OR", + direction="l", + linebreak="al", + unicodeslot=0x10479, + }, + [0x1047A]={ + category="lo", + description="SHAVIAN LETTER AIR", + direction="l", + linebreak="al", + unicodeslot=0x1047A, + }, + [0x1047B]={ + category="lo", + description="SHAVIAN LETTER ERR", + direction="l", + linebreak="al", + unicodeslot=0x1047B, + }, + [0x1047C]={ + category="lo", + description="SHAVIAN LETTER ARRAY", + direction="l", + linebreak="al", + unicodeslot=0x1047C, + }, + [0x1047D]={ + category="lo", + description="SHAVIAN LETTER EAR", + direction="l", + linebreak="al", + unicodeslot=0x1047D, + }, + [0x1047E]={ + category="lo", + description="SHAVIAN LETTER IAN", + direction="l", + linebreak="al", + unicodeslot=0x1047E, + }, + [0x1047F]={ + category="lo", + description="SHAVIAN LETTER YEW", + direction="l", + linebreak="al", + unicodeslot=0x1047F, + }, + [0x10480]={ + category="lo", + description="OSMANYA LETTER ALEF", + direction="l", + linebreak="al", + unicodeslot=0x10480, + }, + [0x10481]={ + category="lo", + description="OSMANYA LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x10481, + }, + [0x10482]={ + category="lo", + description="OSMANYA LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x10482, + }, + [0x10483]={ + category="lo", + description="OSMANYA LETTER JA", + direction="l", + linebreak="al", + unicodeslot=0x10483, + }, + [0x10484]={ + category="lo", + description="OSMANYA LETTER XA", + direction="l", + linebreak="al", + unicodeslot=0x10484, + }, + [0x10485]={ + category="lo", + description="OSMANYA LETTER KHA", + direction="l", + linebreak="al", + unicodeslot=0x10485, + }, + [0x10486]={ + category="lo", + description="OSMANYA LETTER DEEL", + direction="l", + linebreak="al", + unicodeslot=0x10486, + }, + [0x10487]={ + category="lo", + description="OSMANYA LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0x10487, + }, + [0x10488]={ + category="lo", + description="OSMANYA LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x10488, + }, + [0x10489]={ + category="lo", + description="OSMANYA LETTER SHIIN", + direction="l", + linebreak="al", + unicodeslot=0x10489, + }, + [0x1048A]={ + category="lo", + description="OSMANYA LETTER DHA", + direction="l", + linebreak="al", + unicodeslot=0x1048A, + }, + [0x1048B]={ + category="lo", + description="OSMANYA LETTER CAYN", + direction="l", + linebreak="al", + unicodeslot=0x1048B, + }, + [0x1048C]={ + category="lo", + description="OSMANYA LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x1048C, + }, + [0x1048D]={ + category="lo", + description="OSMANYA LETTER FA", + direction="l", + linebreak="al", + unicodeslot=0x1048D, + }, + [0x1048E]={ + category="lo", + description="OSMANYA LETTER QAAF", + direction="l", + linebreak="al", + unicodeslot=0x1048E, + }, + [0x1048F]={ + category="lo", + description="OSMANYA LETTER KAAF", + direction="l", + linebreak="al", + unicodeslot=0x1048F, + }, + [0x10490]={ + category="lo", + description="OSMANYA LETTER LAAN", + direction="l", + linebreak="al", + unicodeslot=0x10490, + }, + [0x10491]={ + category="lo", + description="OSMANYA LETTER MIIN", + direction="l", + linebreak="al", + unicodeslot=0x10491, + }, + [0x10492]={ + category="lo", + description="OSMANYA LETTER NUUN", + direction="l", + linebreak="al", + unicodeslot=0x10492, + }, + [0x10493]={ + category="lo", + description="OSMANYA LETTER WAW", + direction="l", + linebreak="al", + unicodeslot=0x10493, + }, + [0x10494]={ + category="lo", + description="OSMANYA LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x10494, + }, + [0x10495]={ + category="lo", + description="OSMANYA LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x10495, + }, + [0x10496]={ + category="lo", + description="OSMANYA LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x10496, + }, + [0x10497]={ + category="lo", + description="OSMANYA LETTER E", + direction="l", + linebreak="al", + unicodeslot=0x10497, + }, + [0x10498]={ + category="lo", + description="OSMANYA LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x10498, + }, + [0x10499]={ + category="lo", + description="OSMANYA LETTER O", + direction="l", + linebreak="al", + unicodeslot=0x10499, + }, + [0x1049A]={ + category="lo", + description="OSMANYA LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x1049A, + }, + [0x1049B]={ + category="lo", + description="OSMANYA LETTER AA", + direction="l", + linebreak="al", + unicodeslot=0x1049B, + }, + [0x1049C]={ + category="lo", + description="OSMANYA LETTER EE", + direction="l", + linebreak="al", + unicodeslot=0x1049C, + }, + [0x1049D]={ + category="lo", + description="OSMANYA LETTER OO", + direction="l", + linebreak="al", + unicodeslot=0x1049D, + }, + [0x104A0]={ + category="nd", + description="OSMANYA DIGIT ZERO", + direction="l", + linebreak="nu", + unicodeslot=0x104A0, + }, + [0x104A1]={ + category="nd", + description="OSMANYA DIGIT ONE", + direction="l", + linebreak="nu", + unicodeslot=0x104A1, + }, + [0x104A2]={ + category="nd", + description="OSMANYA DIGIT TWO", + direction="l", + linebreak="nu", + unicodeslot=0x104A2, + }, + [0x104A3]={ + category="nd", + description="OSMANYA DIGIT THREE", + direction="l", + linebreak="nu", + unicodeslot=0x104A3, + }, + [0x104A4]={ + category="nd", + description="OSMANYA DIGIT FOUR", + direction="l", + linebreak="nu", + unicodeslot=0x104A4, + }, + [0x104A5]={ + category="nd", + description="OSMANYA DIGIT FIVE", + direction="l", + linebreak="nu", + unicodeslot=0x104A5, + }, + [0x104A6]={ + category="nd", + description="OSMANYA DIGIT SIX", + direction="l", + linebreak="nu", + unicodeslot=0x104A6, + }, + [0x104A7]={ + category="nd", + description="OSMANYA DIGIT SEVEN", + direction="l", + linebreak="nu", + unicodeslot=0x104A7, + }, + [0x104A8]={ + category="nd", + description="OSMANYA DIGIT EIGHT", + direction="l", + linebreak="nu", + unicodeslot=0x104A8, + }, + [0x104A9]={ + category="nd", + description="OSMANYA DIGIT NINE", + direction="l", + linebreak="nu", + unicodeslot=0x104A9, + }, + [0x10800]={ + category="lo", + description="CYPRIOT SYLLABLE A", + direction="r", + linebreak="al", + unicodeslot=0x10800, + }, + [0x10801]={ + category="lo", + description="CYPRIOT SYLLABLE E", + direction="r", + linebreak="al", + unicodeslot=0x10801, + }, + [0x10802]={ + category="lo", + description="CYPRIOT SYLLABLE I", + direction="r", + linebreak="al", + unicodeslot=0x10802, + }, + [0x10803]={ + category="lo", + description="CYPRIOT SYLLABLE O", + direction="r", + linebreak="al", + unicodeslot=0x10803, + }, + [0x10804]={ + category="lo", + description="CYPRIOT SYLLABLE U", + direction="r", + linebreak="al", + unicodeslot=0x10804, + }, + [0x10805]={ + category="lo", + description="CYPRIOT SYLLABLE JA", + direction="r", + linebreak="al", + unicodeslot=0x10805, + }, + [0x10808]={ + category="lo", + description="CYPRIOT SYLLABLE JO", + direction="r", + linebreak="al", + unicodeslot=0x10808, + }, + [0x1080A]={ + category="lo", + description="CYPRIOT SYLLABLE KA", + direction="r", + linebreak="al", + unicodeslot=0x1080A, + }, + [0x1080B]={ + category="lo", + description="CYPRIOT SYLLABLE KE", + direction="r", + linebreak="al", + unicodeslot=0x1080B, + }, + [0x1080C]={ + category="lo", + description="CYPRIOT SYLLABLE KI", + direction="r", + linebreak="al", + unicodeslot=0x1080C, + }, + [0x1080D]={ + category="lo", + description="CYPRIOT SYLLABLE KO", + direction="r", + linebreak="al", + unicodeslot=0x1080D, + }, + [0x1080E]={ + category="lo", + description="CYPRIOT SYLLABLE KU", + direction="r", + linebreak="al", + unicodeslot=0x1080E, + }, + [0x1080F]={ + category="lo", + description="CYPRIOT SYLLABLE LA", + direction="r", + linebreak="al", + unicodeslot=0x1080F, + }, + [0x10810]={ + category="lo", + description="CYPRIOT SYLLABLE LE", + direction="r", + linebreak="al", + unicodeslot=0x10810, + }, + [0x10811]={ + category="lo", + description="CYPRIOT SYLLABLE LI", + direction="r", + linebreak="al", + unicodeslot=0x10811, + }, + [0x10812]={ + category="lo", + description="CYPRIOT SYLLABLE LO", + direction="r", + linebreak="al", + unicodeslot=0x10812, + }, + [0x10813]={ + category="lo", + description="CYPRIOT SYLLABLE LU", + direction="r", + linebreak="al", + unicodeslot=0x10813, + }, + [0x10814]={ + category="lo", + description="CYPRIOT SYLLABLE MA", + direction="r", + linebreak="al", + unicodeslot=0x10814, + }, + [0x10815]={ + category="lo", + description="CYPRIOT SYLLABLE ME", + direction="r", + linebreak="al", + unicodeslot=0x10815, + }, + [0x10816]={ + category="lo", + description="CYPRIOT SYLLABLE MI", + direction="r", + linebreak="al", + unicodeslot=0x10816, + }, + [0x10817]={ + category="lo", + description="CYPRIOT SYLLABLE MO", + direction="r", + linebreak="al", + unicodeslot=0x10817, + }, + [0x10818]={ + category="lo", + description="CYPRIOT SYLLABLE MU", + direction="r", + linebreak="al", + unicodeslot=0x10818, + }, + [0x10819]={ + category="lo", + description="CYPRIOT SYLLABLE NA", + direction="r", + linebreak="al", + unicodeslot=0x10819, + }, + [0x1081A]={ + category="lo", + description="CYPRIOT SYLLABLE NE", + direction="r", + linebreak="al", + unicodeslot=0x1081A, + }, + [0x1081B]={ + category="lo", + description="CYPRIOT SYLLABLE NI", + direction="r", + linebreak="al", + unicodeslot=0x1081B, + }, + [0x1081C]={ + category="lo", + description="CYPRIOT SYLLABLE NO", + direction="r", + linebreak="al", + unicodeslot=0x1081C, + }, + [0x1081D]={ + category="lo", + description="CYPRIOT SYLLABLE NU", + direction="r", + linebreak="al", + unicodeslot=0x1081D, + }, + [0x1081E]={ + category="lo", + description="CYPRIOT SYLLABLE PA", + direction="r", + linebreak="al", + unicodeslot=0x1081E, + }, + [0x1081F]={ + category="lo", + description="CYPRIOT SYLLABLE PE", + direction="r", + linebreak="al", + unicodeslot=0x1081F, + }, + [0x10820]={ + category="lo", + description="CYPRIOT SYLLABLE PI", + direction="r", + linebreak="al", + unicodeslot=0x10820, + }, + [0x10821]={ + category="lo", + description="CYPRIOT SYLLABLE PO", + direction="r", + linebreak="al", + unicodeslot=0x10821, + }, + [0x10822]={ + category="lo", + description="CYPRIOT SYLLABLE PU", + direction="r", + linebreak="al", + unicodeslot=0x10822, + }, + [0x10823]={ + category="lo", + description="CYPRIOT SYLLABLE RA", + direction="r", + linebreak="al", + unicodeslot=0x10823, + }, + [0x10824]={ + category="lo", + description="CYPRIOT SYLLABLE RE", + direction="r", + linebreak="al", + unicodeslot=0x10824, + }, + [0x10825]={ + category="lo", + description="CYPRIOT SYLLABLE RI", + direction="r", + linebreak="al", + unicodeslot=0x10825, + }, + [0x10826]={ + category="lo", + description="CYPRIOT SYLLABLE RO", + direction="r", + linebreak="al", + unicodeslot=0x10826, + }, + [0x10827]={ + category="lo", + description="CYPRIOT SYLLABLE RU", + direction="r", + linebreak="al", + unicodeslot=0x10827, + }, + [0x10828]={ + category="lo", + description="CYPRIOT SYLLABLE SA", + direction="r", + linebreak="al", + unicodeslot=0x10828, + }, + [0x10829]={ + category="lo", + description="CYPRIOT SYLLABLE SE", + direction="r", + linebreak="al", + unicodeslot=0x10829, + }, + [0x1082A]={ + category="lo", + description="CYPRIOT SYLLABLE SI", + direction="r", + linebreak="al", + unicodeslot=0x1082A, + }, + [0x1082B]={ + category="lo", + description="CYPRIOT SYLLABLE SO", + direction="r", + linebreak="al", + unicodeslot=0x1082B, + }, + [0x1082C]={ + category="lo", + description="CYPRIOT SYLLABLE SU", + direction="r", + linebreak="al", + unicodeslot=0x1082C, + }, + [0x1082D]={ + category="lo", + description="CYPRIOT SYLLABLE TA", + direction="r", + linebreak="al", + unicodeslot=0x1082D, + }, + [0x1082E]={ + category="lo", + description="CYPRIOT SYLLABLE TE", + direction="r", + linebreak="al", + unicodeslot=0x1082E, + }, + [0x1082F]={ + category="lo", + description="CYPRIOT SYLLABLE TI", + direction="r", + linebreak="al", + unicodeslot=0x1082F, + }, + [0x10830]={ + category="lo", + description="CYPRIOT SYLLABLE TO", + direction="r", + linebreak="al", + unicodeslot=0x10830, + }, + [0x10831]={ + category="lo", + description="CYPRIOT SYLLABLE TU", + direction="r", + linebreak="al", + unicodeslot=0x10831, + }, + [0x10832]={ + category="lo", + description="CYPRIOT SYLLABLE WA", + direction="r", + linebreak="al", + unicodeslot=0x10832, + }, + [0x10833]={ + category="lo", + description="CYPRIOT SYLLABLE WE", + direction="r", + linebreak="al", + unicodeslot=0x10833, + }, + [0x10834]={ + category="lo", + description="CYPRIOT SYLLABLE WI", + direction="r", + linebreak="al", + unicodeslot=0x10834, + }, + [0x10835]={ + category="lo", + description="CYPRIOT SYLLABLE WO", + direction="r", + linebreak="al", + unicodeslot=0x10835, + }, + [0x10837]={ + category="lo", + description="CYPRIOT SYLLABLE XA", + direction="r", + linebreak="al", + unicodeslot=0x10837, + }, + [0x10838]={ + category="lo", + description="CYPRIOT SYLLABLE XE", + direction="r", + linebreak="al", + unicodeslot=0x10838, + }, + [0x1083C]={ + category="lo", + description="CYPRIOT SYLLABLE ZA", + direction="r", + linebreak="al", + unicodeslot=0x1083C, + }, + [0x1083F]={ + category="lo", + description="CYPRIOT SYLLABLE ZO", + direction="r", + linebreak="al", + unicodeslot=0x1083F, + }, + [0x10900]={ + category="lo", + description="PHOENICIAN LETTER ALF", + direction="r", + linebreak="al", + unicodeslot=0x10900, + }, + [0x10901]={ + category="lo", + description="PHOENICIAN LETTER BET", + direction="r", + linebreak="al", + unicodeslot=0x10901, + }, + [0x10902]={ + category="lo", + description="PHOENICIAN LETTER GAML", + direction="r", + linebreak="al", + unicodeslot=0x10902, + }, + [0x10903]={ + category="lo", + description="PHOENICIAN LETTER DELT", + direction="r", + linebreak="al", + unicodeslot=0x10903, + }, + [0x10904]={ + category="lo", + description="PHOENICIAN LETTER HE", + direction="r", + linebreak="al", + unicodeslot=0x10904, + }, + [0x10905]={ + category="lo", + description="PHOENICIAN LETTER WAU", + direction="r", + linebreak="al", + unicodeslot=0x10905, + }, + [0x10906]={ + category="lo", + description="PHOENICIAN LETTER ZAI", + direction="r", + linebreak="al", + unicodeslot=0x10906, + }, + [0x10907]={ + category="lo", + description="PHOENICIAN LETTER HET", + direction="r", + linebreak="al", + unicodeslot=0x10907, + }, + [0x10908]={ + category="lo", + description="PHOENICIAN LETTER TET", + direction="r", + linebreak="al", + unicodeslot=0x10908, + }, + [0x10909]={ + category="lo", + description="PHOENICIAN LETTER YOD", + direction="r", + linebreak="al", + unicodeslot=0x10909, + }, + [0x1090A]={ + category="lo", + description="PHOENICIAN LETTER KAF", + direction="r", + linebreak="al", + unicodeslot=0x1090A, + }, + [0x1090B]={ + category="lo", + description="PHOENICIAN LETTER LAMD", + direction="r", + linebreak="al", + unicodeslot=0x1090B, + }, + [0x1090C]={ + category="lo", + description="PHOENICIAN LETTER MEM", + direction="r", + linebreak="al", + unicodeslot=0x1090C, + }, + [0x1090D]={ + category="lo", + description="PHOENICIAN LETTER NUN", + direction="r", + linebreak="al", + unicodeslot=0x1090D, + }, + [0x1090E]={ + category="lo", + description="PHOENICIAN LETTER SEMK", + direction="r", + linebreak="al", + unicodeslot=0x1090E, + }, + [0x1090F]={ + category="lo", + description="PHOENICIAN LETTER AIN", + direction="r", + linebreak="al", + unicodeslot=0x1090F, + }, + [0x10910]={ + category="lo", + description="PHOENICIAN LETTER PE", + direction="r", + linebreak="al", + unicodeslot=0x10910, + }, + [0x10911]={ + category="lo", + description="PHOENICIAN LETTER SADE", + direction="r", + linebreak="al", + unicodeslot=0x10911, + }, + [0x10912]={ + category="lo", + description="PHOENICIAN LETTER QOF", + direction="r", + linebreak="al", + unicodeslot=0x10912, + }, + [0x10913]={ + category="lo", + description="PHOENICIAN LETTER ROSH", + direction="r", + linebreak="al", + unicodeslot=0x10913, + }, + [0x10914]={ + category="lo", + description="PHOENICIAN LETTER SHIN", + direction="r", + linebreak="al", + unicodeslot=0x10914, + }, + [0x10915]={ + category="lo", + description="PHOENICIAN LETTER TAU", + direction="r", + linebreak="al", + unicodeslot=0x10915, + }, + [0x10916]={ + category="no", + description="PHOENICIAN NUMBER ONE", + direction="r", + linebreak="al", + unicodeslot=0x10916, + }, + [0x10917]={ + category="no", + description="PHOENICIAN NUMBER TEN", + direction="r", + linebreak="al", + unicodeslot=0x10917, + }, + [0x10918]={ + category="no", + description="PHOENICIAN NUMBER TWENTY", + direction="r", + linebreak="al", + unicodeslot=0x10918, + }, + [0x10919]={ + category="no", + description="PHOENICIAN NUMBER ONE HUNDRED", + direction="r", + linebreak="al", + unicodeslot=0x10919, + }, + [0x1091F]={ + category="po", + description="PHOENICIAN WORD SEPARATOR", + direction="on", + linebreak="ba", + unicodeslot=0x1091F, + }, + [0x10A00]={ + category="lo", + description="KHAROSHTHI LETTER A", + direction="r", + linebreak="al", + unicodeslot=0x10A00, + }, + [0x10A01]={ + category="mn", + description="KHAROSHTHI VOWEL SIGN I", + direction="nsm", + linebreak="cm", + unicodeslot=0x10A01, + }, + [0x10A02]={ + category="mn", + description="KHAROSHTHI VOWEL SIGN U", + direction="nsm", + linebreak="cm", + unicodeslot=0x10A02, + }, + [0x10A03]={ + category="mn", + description="KHAROSHTHI VOWEL SIGN VOCALIC R", + direction="nsm", + linebreak="cm", + unicodeslot=0x10A03, + }, + [0x10A05]={ + category="mn", + description="KHAROSHTHI VOWEL SIGN E", + direction="nsm", + linebreak="cm", + unicodeslot=0x10A05, + }, + [0x10A06]={ + category="mn", + description="KHAROSHTHI VOWEL SIGN O", + direction="nsm", + linebreak="cm", + unicodeslot=0x10A06, + }, + [0x10A0C]={ + category="mn", + description="KHAROSHTHI VOWEL LENGTH MARK", + direction="nsm", + linebreak="cm", + unicodeslot=0x10A0C, + }, + [0x10A0D]={ + category="mn", + description="KHAROSHTHI SIGN DOUBLE RING BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x10A0D, + }, + [0x10A0E]={ + category="mn", + description="KHAROSHTHI SIGN ANUSVARA", + direction="nsm", + linebreak="cm", + unicodeslot=0x10A0E, + }, + [0x10A0F]={ + category="mn", + description="KHAROSHTHI SIGN VISARGA", + direction="nsm", + linebreak="cm", + unicodeslot=0x10A0F, + }, + [0x10A10]={ + category="lo", + description="KHAROSHTHI LETTER KA", + direction="r", + linebreak="al", + unicodeslot=0x10A10, + }, + [0x10A11]={ + category="lo", + description="KHAROSHTHI LETTER KHA", + direction="r", + linebreak="al", + unicodeslot=0x10A11, + }, + [0x10A12]={ + category="lo", + description="KHAROSHTHI LETTER GA", + direction="r", + linebreak="al", + unicodeslot=0x10A12, + }, + [0x10A13]={ + category="lo", + description="KHAROSHTHI LETTER GHA", + direction="r", + linebreak="al", + unicodeslot=0x10A13, + }, + [0x10A15]={ + category="lo", + description="KHAROSHTHI LETTER CA", + direction="r", + linebreak="al", + unicodeslot=0x10A15, + }, + [0x10A16]={ + category="lo", + description="KHAROSHTHI LETTER CHA", + direction="r", + linebreak="al", + unicodeslot=0x10A16, + }, + [0x10A17]={ + category="lo", + description="KHAROSHTHI LETTER JA", + direction="r", + linebreak="al", + unicodeslot=0x10A17, + }, + [0x10A19]={ + category="lo", + description="KHAROSHTHI LETTER NYA", + direction="r", + linebreak="al", + unicodeslot=0x10A19, + }, + [0x10A1A]={ + category="lo", + description="KHAROSHTHI LETTER TTA", + direction="r", + linebreak="al", + unicodeslot=0x10A1A, + }, + [0x10A1B]={ + category="lo", + description="KHAROSHTHI LETTER TTHA", + direction="r", + linebreak="al", + unicodeslot=0x10A1B, + }, + [0x10A1C]={ + category="lo", + description="KHAROSHTHI LETTER DDA", + direction="r", + linebreak="al", + unicodeslot=0x10A1C, + }, + [0x10A1D]={ + category="lo", + description="KHAROSHTHI LETTER DDHA", + direction="r", + linebreak="al", + unicodeslot=0x10A1D, + }, + [0x10A1E]={ + category="lo", + description="KHAROSHTHI LETTER NNA", + direction="r", + linebreak="al", + unicodeslot=0x10A1E, + }, + [0x10A1F]={ + category="lo", + description="KHAROSHTHI LETTER TA", + direction="r", + linebreak="al", + unicodeslot=0x10A1F, + }, + [0x10A20]={ + category="lo", + description="KHAROSHTHI LETTER THA", + direction="r", + linebreak="al", + unicodeslot=0x10A20, + }, + [0x10A21]={ + category="lo", + description="KHAROSHTHI LETTER DA", + direction="r", + linebreak="al", + unicodeslot=0x10A21, + }, + [0x10A22]={ + category="lo", + description="KHAROSHTHI LETTER DHA", + direction="r", + linebreak="al", + unicodeslot=0x10A22, + }, + [0x10A23]={ + category="lo", + description="KHAROSHTHI LETTER NA", + direction="r", + linebreak="al", + unicodeslot=0x10A23, + }, + [0x10A24]={ + category="lo", + description="KHAROSHTHI LETTER PA", + direction="r", + linebreak="al", + unicodeslot=0x10A24, + }, + [0x10A25]={ + category="lo", + description="KHAROSHTHI LETTER PHA", + direction="r", + linebreak="al", + unicodeslot=0x10A25, + }, + [0x10A26]={ + category="lo", + description="KHAROSHTHI LETTER BA", + direction="r", + linebreak="al", + unicodeslot=0x10A26, + }, + [0x10A27]={ + category="lo", + description="KHAROSHTHI LETTER BHA", + direction="r", + linebreak="al", + unicodeslot=0x10A27, + }, + [0x10A28]={ + category="lo", + description="KHAROSHTHI LETTER MA", + direction="r", + linebreak="al", + unicodeslot=0x10A28, + }, + [0x10A29]={ + category="lo", + description="KHAROSHTHI LETTER YA", + direction="r", + linebreak="al", + unicodeslot=0x10A29, + }, + [0x10A2A]={ + category="lo", + description="KHAROSHTHI LETTER RA", + direction="r", + linebreak="al", + unicodeslot=0x10A2A, + }, + [0x10A2B]={ + category="lo", + description="KHAROSHTHI LETTER LA", + direction="r", + linebreak="al", + unicodeslot=0x10A2B, + }, + [0x10A2C]={ + category="lo", + description="KHAROSHTHI LETTER VA", + direction="r", + linebreak="al", + unicodeslot=0x10A2C, + }, + [0x10A2D]={ + category="lo", + description="KHAROSHTHI LETTER SHA", + direction="r", + linebreak="al", + unicodeslot=0x10A2D, + }, + [0x10A2E]={ + category="lo", + description="KHAROSHTHI LETTER SSA", + direction="r", + linebreak="al", + unicodeslot=0x10A2E, + }, + [0x10A2F]={ + category="lo", + description="KHAROSHTHI LETTER SA", + direction="r", + linebreak="al", + unicodeslot=0x10A2F, + }, + [0x10A30]={ + category="lo", + description="KHAROSHTHI LETTER ZA", + direction="r", + linebreak="al", + unicodeslot=0x10A30, + }, + [0x10A31]={ + category="lo", + description="KHAROSHTHI LETTER HA", + direction="r", + linebreak="al", + unicodeslot=0x10A31, + }, + [0x10A32]={ + category="lo", + description="KHAROSHTHI LETTER KKA", + direction="r", + linebreak="al", + unicodeslot=0x10A32, + }, + [0x10A33]={ + category="lo", + description="KHAROSHTHI LETTER TTTHA", + direction="r", + linebreak="al", + unicodeslot=0x10A33, + }, + [0x10A38]={ + category="mn", + description="KHAROSHTHI SIGN BAR ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x10A38, + }, + [0x10A39]={ + category="mn", + description="KHAROSHTHI SIGN CAUDA", + direction="nsm", + linebreak="cm", + unicodeslot=0x10A39, + }, + [0x10A3A]={ + category="mn", + description="KHAROSHTHI SIGN DOT BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x10A3A, + }, + [0x10A3F]={ + category="mn", + description="KHAROSHTHI VIRAMA", + direction="nsm", + linebreak="cm", + unicodeslot=0x10A3F, + }, + [0x10A40]={ + category="no", + description="KHAROSHTHI DIGIT ONE", + direction="r", + linebreak="al", + unicodeslot=0x10A40, + }, + [0x10A41]={ + category="no", + description="KHAROSHTHI DIGIT TWO", + direction="r", + linebreak="al", + unicodeslot=0x10A41, + }, + [0x10A42]={ + category="no", + description="KHAROSHTHI DIGIT THREE", + direction="r", + linebreak="al", + unicodeslot=0x10A42, + }, + [0x10A43]={ + category="no", + description="KHAROSHTHI DIGIT FOUR", + direction="r", + linebreak="al", + unicodeslot=0x10A43, + }, + [0x10A44]={ + category="no", + description="KHAROSHTHI NUMBER TEN", + direction="r", + linebreak="al", + unicodeslot=0x10A44, + }, + [0x10A45]={ + category="no", + description="KHAROSHTHI NUMBER TWENTY", + direction="r", + linebreak="al", + unicodeslot=0x10A45, + }, + [0x10A46]={ + category="no", + description="KHAROSHTHI NUMBER ONE HUNDRED", + direction="r", + linebreak="al", + unicodeslot=0x10A46, + }, + [0x10A47]={ + category="no", + description="KHAROSHTHI NUMBER ONE THOUSAND", + direction="r", + linebreak="al", + unicodeslot=0x10A47, + }, + [0x10A50]={ + category="po", + description="KHAROSHTHI PUNCTUATION DOT", + direction="r", + linebreak="ba", + unicodeslot=0x10A50, + }, + [0x10A51]={ + category="po", + description="KHAROSHTHI PUNCTUATION SMALL CIRCLE", + direction="r", + linebreak="ba", + unicodeslot=0x10A51, + }, + [0x10A52]={ + category="po", + description="KHAROSHTHI PUNCTUATION CIRCLE", + direction="r", + linebreak="ba", + unicodeslot=0x10A52, + }, + [0x10A53]={ + category="po", + description="KHAROSHTHI PUNCTUATION CRESCENT BAR", + direction="r", + linebreak="ba", + unicodeslot=0x10A53, + }, + [0x10A54]={ + category="po", + description="KHAROSHTHI PUNCTUATION MANGALAM", + direction="r", + linebreak="ba", + unicodeslot=0x10A54, + }, + [0x10A55]={ + category="po", + description="KHAROSHTHI PUNCTUATION LOTUS", + direction="r", + linebreak="ba", + unicodeslot=0x10A55, + }, + [0x10A56]={ + category="po", + description="KHAROSHTHI PUNCTUATION DANDA", + direction="r", + linebreak="ba", + unicodeslot=0x10A56, + }, + [0x10A57]={ + category="po", + description="KHAROSHTHI PUNCTUATION DOUBLE DANDA", + direction="r", + linebreak="ba", + unicodeslot=0x10A57, + }, + [0x10A58]={ + category="po", + description="KHAROSHTHI PUNCTUATION LINES", + direction="r", + linebreak="al", + unicodeslot=0x10A58, + }, + [0x12000]={ + category="lo", + description="CUNEIFORM SIGN A", + direction="l", + linebreak="al", + unicodeslot=0x12000, + }, + [0x12001]={ + category="lo", + description="CUNEIFORM SIGN A TIMES A", + direction="l", + linebreak="al", + unicodeslot=0x12001, + }, + [0x12002]={ + category="lo", + description="CUNEIFORM SIGN A TIMES BAD", + direction="l", + linebreak="al", + unicodeslot=0x12002, + }, + [0x12003]={ + category="lo", + description="CUNEIFORM SIGN A TIMES GAN0x0002 TENU", + direction="l", + linebreak="al", + unicodeslot=0x12003, + }, + [0x12004]={ + category="lo", + description="CUNEIFORM SIGN A TIMES HA", + direction="l", + linebreak="al", + unicodeslot=0x12004, + }, + [0x12005]={ + category="lo", + description="CUNEIFORM SIGN A TIMES IGI", + direction="l", + linebreak="al", + unicodeslot=0x12005, + }, + [0x12006]={ + category="lo", + description="CUNEIFORM SIGN A TIMES LAGAR GUNU", + direction="l", + linebreak="al", + unicodeslot=0x12006, + }, + [0x12007]={ + category="lo", + description="CUNEIFORM SIGN A TIMES MUSH", + direction="l", + linebreak="al", + unicodeslot=0x12007, + }, + [0x12008]={ + category="lo", + description="CUNEIFORM SIGN A TIMES SAG", + direction="l", + linebreak="al", + unicodeslot=0x12008, + }, + [0x12009]={ + category="lo", + description="CUNEIFORM SIGN A0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12009, + }, + [0x1200A]={ + category="lo", + description="CUNEIFORM SIGN AB", + direction="l", + linebreak="al", + unicodeslot=0x1200A, + }, + [0x1200B]={ + category="lo", + description="CUNEIFORM SIGN AB TIMES ASH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1200B, + }, + [0x1200C]={ + category="lo", + description="CUNEIFORM SIGN AB TIMES DUN0x0003 GUNU", + direction="l", + linebreak="al", + unicodeslot=0x1200C, + }, + [0x1200D]={ + category="lo", + description="CUNEIFORM SIGN AB TIMES GAL", + direction="l", + linebreak="al", + unicodeslot=0x1200D, + }, + [0x1200E]={ + category="lo", + description="CUNEIFORM SIGN AB TIMES GAN0x0002 TENU", + direction="l", + linebreak="al", + unicodeslot=0x1200E, + }, + [0x1200F]={ + category="lo", + description="CUNEIFORM SIGN AB TIMES HA", + direction="l", + linebreak="al", + unicodeslot=0x1200F, + }, + [0x12010]={ + category="lo", + description="CUNEIFORM SIGN AB TIMES IGI GUNU", + direction="l", + linebreak="al", + unicodeslot=0x12010, + }, + [0x12011]={ + category="lo", + description="CUNEIFORM SIGN AB TIMES IMIN", + direction="l", + linebreak="al", + unicodeslot=0x12011, + }, + [0x12012]={ + category="lo", + description="CUNEIFORM SIGN AB TIMES LAGAB", + direction="l", + linebreak="al", + unicodeslot=0x12012, + }, + [0x12013]={ + category="lo", + description="CUNEIFORM SIGN AB TIMES SHESH", + direction="l", + linebreak="al", + unicodeslot=0x12013, + }, + [0x12014]={ + category="lo", + description="CUNEIFORM SIGN AB TIMES U PLUS U PLUS U", + direction="l", + linebreak="al", + unicodeslot=0x12014, + }, + [0x12015]={ + category="lo", + description="CUNEIFORM SIGN AB GUNU", + direction="l", + linebreak="al", + unicodeslot=0x12015, + }, + [0x12016]={ + category="lo", + description="CUNEIFORM SIGN AB0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12016, + }, + [0x12017]={ + category="lo", + description="CUNEIFORM SIGN AB0x0002 TIMES BALAG", + direction="l", + linebreak="al", + unicodeslot=0x12017, + }, + [0x12018]={ + category="lo", + description="CUNEIFORM SIGN AB0x0002 TIMES GAN0x0002 TENU", + direction="l", + linebreak="al", + unicodeslot=0x12018, + }, + [0x12019]={ + category="lo", + description="CUNEIFORM SIGN AB0x0002 TIMES ME PLUS EN", + direction="l", + linebreak="al", + unicodeslot=0x12019, + }, + [0x1201A]={ + category="lo", + description="CUNEIFORM SIGN AB0x0002 TIMES SHA0x0003", + direction="l", + linebreak="al", + unicodeslot=0x1201A, + }, + [0x1201B]={ + category="lo", + description="CUNEIFORM SIGN AB0x0002 TIMES TAK0x0004", + direction="l", + linebreak="al", + unicodeslot=0x1201B, + }, + [0x1201C]={ + category="lo", + description="CUNEIFORM SIGN AD", + direction="l", + linebreak="al", + unicodeslot=0x1201C, + }, + [0x1201D]={ + category="lo", + description="CUNEIFORM SIGN AK", + direction="l", + linebreak="al", + unicodeslot=0x1201D, + }, + [0x1201E]={ + category="lo", + description="CUNEIFORM SIGN AK TIMES ERIN0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1201E, + }, + [0x1201F]={ + category="lo", + description="CUNEIFORM SIGN AK TIMES SHITA PLUS GISH", + direction="l", + linebreak="al", + unicodeslot=0x1201F, + }, + [0x12020]={ + category="lo", + description="CUNEIFORM SIGN AL", + direction="l", + linebreak="al", + unicodeslot=0x12020, + }, + [0x12021]={ + category="lo", + description="CUNEIFORM SIGN AL TIMES AL", + direction="l", + linebreak="al", + unicodeslot=0x12021, + }, + [0x12022]={ + category="lo", + description="CUNEIFORM SIGN AL TIMES DIM0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12022, + }, + [0x12023]={ + category="lo", + description="CUNEIFORM SIGN AL TIMES GISH", + direction="l", + linebreak="al", + unicodeslot=0x12023, + }, + [0x12024]={ + category="lo", + description="CUNEIFORM SIGN AL TIMES HA", + direction="l", + linebreak="al", + unicodeslot=0x12024, + }, + [0x12025]={ + category="lo", + description="CUNEIFORM SIGN AL TIMES KAD0x0003", + direction="l", + linebreak="al", + unicodeslot=0x12025, + }, + [0x12026]={ + category="lo", + description="CUNEIFORM SIGN AL TIMES KI", + direction="l", + linebreak="al", + unicodeslot=0x12026, + }, + [0x12027]={ + category="lo", + description="CUNEIFORM SIGN AL TIMES SHE", + direction="l", + linebreak="al", + unicodeslot=0x12027, + }, + [0x12028]={ + category="lo", + description="CUNEIFORM SIGN AL TIMES USH", + direction="l", + linebreak="al", + unicodeslot=0x12028, + }, + [0x12029]={ + category="lo", + description="CUNEIFORM SIGN ALAN", + direction="l", + linebreak="al", + unicodeslot=0x12029, + }, + [0x1202A]={ + category="lo", + description="CUNEIFORM SIGN ALEPH", + direction="l", + linebreak="al", + unicodeslot=0x1202A, + }, + [0x1202B]={ + category="lo", + description="CUNEIFORM SIGN AMAR", + direction="l", + linebreak="al", + unicodeslot=0x1202B, + }, + [0x1202C]={ + category="lo", + description="CUNEIFORM SIGN AMAR TIMES SHE", + direction="l", + linebreak="al", + unicodeslot=0x1202C, + }, + [0x1202D]={ + category="lo", + description="CUNEIFORM SIGN AN", + direction="l", + linebreak="al", + unicodeslot=0x1202D, + }, + [0x1202E]={ + category="lo", + description="CUNEIFORM SIGN AN OVER AN", + direction="l", + linebreak="al", + unicodeslot=0x1202E, + }, + [0x1202F]={ + category="lo", + description="CUNEIFORM SIGN AN THREE TIMES", + direction="l", + linebreak="al", + unicodeslot=0x1202F, + }, + [0x12030]={ + category="lo", + description="CUNEIFORM SIGN AN PLUS NAGA OPPOSING AN PLUS NAGA", + direction="l", + linebreak="al", + unicodeslot=0x12030, + }, + [0x12031]={ + category="lo", + description="CUNEIFORM SIGN AN PLUS NAGA SQUARED", + direction="l", + linebreak="al", + unicodeslot=0x12031, + }, + [0x12032]={ + category="lo", + description="CUNEIFORM SIGN ANSHE", + direction="l", + linebreak="al", + unicodeslot=0x12032, + }, + [0x12033]={ + category="lo", + description="CUNEIFORM SIGN APIN", + direction="l", + linebreak="al", + unicodeslot=0x12033, + }, + [0x12034]={ + category="lo", + description="CUNEIFORM SIGN ARAD", + direction="l", + linebreak="al", + unicodeslot=0x12034, + }, + [0x12035]={ + category="lo", + description="CUNEIFORM SIGN ARAD TIMES KUR", + direction="l", + linebreak="al", + mathclass="ord", + mathname="backprime", + unicodeslot=0x12035, + }, + [0x12036]={ + category="lo", + description="CUNEIFORM SIGN ARKAB", + direction="l", + linebreak="al", + unicodeslot=0x12036, + }, + [0x12037]={ + category="lo", + description="CUNEIFORM SIGN ASAL0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12037, + }, + [0x12038]={ + category="lo", + description="CUNEIFORM SIGN ASH", + direction="l", + linebreak="al", + unicodeslot=0x12038, + }, + [0x12039]={ + category="lo", + description="CUNEIFORM SIGN ASH ZIDA TENU", + direction="l", + linebreak="al", + unicodeslot=0x12039, + }, + [0x1203A]={ + category="lo", + description="CUNEIFORM SIGN ASH KABA TENU", + direction="l", + linebreak="al", + unicodeslot=0x1203A, + }, + [0x1203B]={ + category="lo", + description="CUNEIFORM SIGN ASH OVER ASH TUG0x0002 OVER TUG0x0002 TUG0x0002 OVER TUG0x0002 PAP", + direction="l", + linebreak="al", + unicodeslot=0x1203B, + }, + [0x1203C]={ + category="lo", + description="CUNEIFORM SIGN ASH OVER ASH OVER ASH", + direction="l", + linebreak="al", + unicodeslot=0x1203C, + }, + [0x1203D]={ + category="lo", + description="CUNEIFORM SIGN ASH OVER ASH OVER ASH CROSSING ASH OVER ASH OVER ASH", + direction="l", + linebreak="al", + unicodeslot=0x1203D, + }, + [0x1203E]={ + category="lo", + description="CUNEIFORM SIGN ASH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1203E, + }, + [0x1203F]={ + category="lo", + description="CUNEIFORM SIGN ASHGAB", + direction="l", + linebreak="al", + unicodeslot=0x1203F, + }, + [0x12040]={ + category="lo", + description="CUNEIFORM SIGN BA", + direction="l", + linebreak="al", + unicodeslot=0x12040, + }, + [0x12041]={ + category="lo", + description="CUNEIFORM SIGN BAD", + direction="l", + linebreak="al", + unicodeslot=0x12041, + }, + [0x12042]={ + category="lo", + description="CUNEIFORM SIGN BAG0x0003", + direction="l", + linebreak="al", + unicodeslot=0x12042, + }, + [0x12043]={ + category="lo", + description="CUNEIFORM SIGN BAHAR0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12043, + }, + [0x12044]={ + category="lo", + description="CUNEIFORM SIGN BAL", + direction="l", + linebreak="al", + unicodeslot=0x12044, + }, + [0x12045]={ + category="lo", + description="CUNEIFORM SIGN BAL OVER BAL", + direction="l", + linebreak="al", + unicodeslot=0x12045, + }, + [0x12046]={ + category="lo", + description="CUNEIFORM SIGN BALAG", + direction="l", + linebreak="al", + unicodeslot=0x12046, + }, + [0x12047]={ + category="lo", + description="CUNEIFORM SIGN BAR", + direction="l", + linebreak="al", + unicodeslot=0x12047, + }, + [0x12048]={ + category="lo", + description="CUNEIFORM SIGN BARA0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12048, + }, + [0x12049]={ + category="lo", + description="CUNEIFORM SIGN BI", + direction="l", + linebreak="al", + unicodeslot=0x12049, + }, + [0x1204A]={ + category="lo", + description="CUNEIFORM SIGN BI TIMES A", + direction="l", + linebreak="al", + unicodeslot=0x1204A, + }, + [0x1204B]={ + category="lo", + description="CUNEIFORM SIGN BI TIMES GAR", + direction="l", + linebreak="al", + unicodeslot=0x1204B, + }, + [0x1204C]={ + category="lo", + description="CUNEIFORM SIGN BI TIMES IGI GUNU", + direction="l", + linebreak="al", + unicodeslot=0x1204C, + }, + [0x1204D]={ + category="lo", + description="CUNEIFORM SIGN BU", + direction="l", + linebreak="al", + unicodeslot=0x1204D, + }, + [0x1204E]={ + category="lo", + description="CUNEIFORM SIGN BU OVER BU AB", + direction="l", + linebreak="al", + unicodeslot=0x1204E, + }, + [0x1204F]={ + category="lo", + description="CUNEIFORM SIGN BU OVER BU UN", + direction="l", + linebreak="al", + unicodeslot=0x1204F, + }, + [0x12050]={ + category="lo", + description="CUNEIFORM SIGN BU CROSSING BU", + direction="l", + linebreak="al", + unicodeslot=0x12050, + }, + [0x12051]={ + category="lo", + description="CUNEIFORM SIGN BULUG", + direction="l", + linebreak="al", + unicodeslot=0x12051, + }, + [0x12052]={ + category="lo", + description="CUNEIFORM SIGN BULUG OVER BULUG", + direction="l", + linebreak="al", + unicodeslot=0x12052, + }, + [0x12053]={ + category="lo", + description="CUNEIFORM SIGN BUR", + direction="l", + linebreak="al", + unicodeslot=0x12053, + }, + [0x12054]={ + category="lo", + description="CUNEIFORM SIGN BUR0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12054, + }, + [0x12055]={ + category="lo", + description="CUNEIFORM SIGN DA", + direction="l", + linebreak="al", + unicodeslot=0x12055, + }, + [0x12056]={ + category="lo", + description="CUNEIFORM SIGN DAG", + direction="l", + linebreak="al", + unicodeslot=0x12056, + }, + [0x12057]={ + category="lo", + description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES A PLUS MASH", + direction="l", + linebreak="al", + unicodeslot=0x12057, + }, + [0x12058]={ + category="lo", + description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES AMAR", + direction="l", + linebreak="al", + unicodeslot=0x12058, + }, + [0x12059]={ + category="lo", + description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES BALAG", + direction="l", + linebreak="al", + unicodeslot=0x12059, + }, + [0x1205A]={ + category="lo", + description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES BI", + direction="l", + linebreak="al", + unicodeslot=0x1205A, + }, + [0x1205B]={ + category="lo", + description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES GA", + direction="l", + linebreak="al", + unicodeslot=0x1205B, + }, + [0x1205C]={ + category="lo", + description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES GA PLUS MASH", + direction="l", + linebreak="al", + unicodeslot=0x1205C, + }, + [0x1205D]={ + category="lo", + description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES GI", + direction="l", + linebreak="al", + unicodeslot=0x1205D, + }, + [0x1205E]={ + category="lo", + description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES GIR0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1205E, + }, + [0x1205F]={ + category="lo", + description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES GUD", + direction="l", + linebreak="al", + unicodeslot=0x1205F, + }, + [0x12060]={ + category="lo", + description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES HA", + direction="l", + linebreak="al", + unicodeslot=0x12060, + }, + [0x12061]={ + category="lo", + description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES IR", + direction="l", + linebreak="al", + unicodeslot=0x12061, + }, + [0x12062]={ + category="lo", + description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES IR PLUS LU", + direction="l", + linebreak="al", + unicodeslot=0x12062, + }, + [0x12063]={ + category="lo", + description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES KAK", + direction="l", + linebreak="al", + unicodeslot=0x12063, + }, + [0x12064]={ + category="lo", + description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES LA", + direction="l", + linebreak="al", + unicodeslot=0x12064, + }, + [0x12065]={ + category="lo", + description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES LU", + direction="l", + linebreak="al", + unicodeslot=0x12065, + }, + [0x12066]={ + category="lo", + description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES LU PLUS MASH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12066, + }, + [0x12067]={ + category="lo", + description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES LUM", + direction="l", + linebreak="al", + unicodeslot=0x12067, + }, + [0x12068]={ + category="lo", + description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES NE", + direction="l", + linebreak="al", + unicodeslot=0x12068, + }, + [0x12069]={ + category="lo", + description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES PAP PLUS PAP", + direction="l", + linebreak="al", + unicodeslot=0x12069, + }, + [0x1206A]={ + category="lo", + description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES SI", + direction="l", + linebreak="al", + unicodeslot=0x1206A, + }, + [0x1206B]={ + category="lo", + description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES TAK0x0004", + direction="l", + linebreak="al", + unicodeslot=0x1206B, + }, + [0x1206C]={ + category="lo", + description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES U0x0002 PLUS GIR0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1206C, + }, + [0x1206D]={ + category="lo", + description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES USH", + direction="l", + linebreak="al", + unicodeslot=0x1206D, + }, + [0x1206E]={ + category="lo", + description="CUNEIFORM SIGN DAM", + direction="l", + linebreak="al", + unicodeslot=0x1206E, + }, + [0x1206F]={ + category="lo", + description="CUNEIFORM SIGN DAR", + direction="l", + linebreak="al", + unicodeslot=0x1206F, + }, + [0x12070]={ + category="lo", + description="CUNEIFORM SIGN DARA0x0003", + direction="l", + linebreak="al", + unicodeslot=0x12070, + }, + [0x12071]={ + category="lo", + description="CUNEIFORM SIGN DARA0x0004", + direction="l", + linebreak="al", + unicodeslot=0x12071, + }, + [0x12072]={ + category="lo", + description="CUNEIFORM SIGN DI", + direction="l", + linebreak="al", + unicodeslot=0x12072, + }, + [0x12073]={ + category="lo", + description="CUNEIFORM SIGN DIB", + direction="l", + linebreak="al", + unicodeslot=0x12073, + }, + [0x12074]={ + category="lo", + description="CUNEIFORM SIGN DIM", + direction="l", + linebreak="al", + unicodeslot=0x12074, + }, + [0x12075]={ + category="lo", + description="CUNEIFORM SIGN DIM TIMES SHE", + direction="l", + linebreak="al", + unicodeslot=0x12075, + }, + [0x12076]={ + category="lo", + description="CUNEIFORM SIGN DIM0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12076, + }, + [0x12077]={ + category="lo", + description="CUNEIFORM SIGN DIN", + direction="l", + linebreak="al", + unicodeslot=0x12077, + }, + [0x12078]={ + category="lo", + description="CUNEIFORM SIGN DIN KASKAL U GUNU DISH", + direction="l", + linebreak="al", + unicodeslot=0x12078, + }, + [0x12079]={ + category="lo", + description="CUNEIFORM SIGN DISH", + direction="l", + linebreak="al", + unicodeslot=0x12079, + }, + [0x1207A]={ + category="lo", + description="CUNEIFORM SIGN DU", + direction="l", + linebreak="al", + unicodeslot=0x1207A, + }, + [0x1207B]={ + category="lo", + description="CUNEIFORM SIGN DU OVER DU", + direction="l", + linebreak="al", + unicodeslot=0x1207B, + }, + [0x1207C]={ + category="lo", + description="CUNEIFORM SIGN DU GUNU", + direction="l", + linebreak="al", + unicodeslot=0x1207C, + }, + [0x1207D]={ + category="lo", + description="CUNEIFORM SIGN DU SHESHIG", + direction="l", + linebreak="al", + unicodeslot=0x1207D, + }, + [0x1207E]={ + category="lo", + description="CUNEIFORM SIGN DUB", + direction="l", + linebreak="al", + unicodeslot=0x1207E, + }, + [0x1207F]={ + category="lo", + description="CUNEIFORM SIGN DUB TIMES ESH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1207F, + }, + [0x12080]={ + category="lo", + description="CUNEIFORM SIGN DUB0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12080, + }, + [0x12081]={ + category="lo", + description="CUNEIFORM SIGN DUG", + direction="l", + linebreak="al", + unicodeslot=0x12081, + }, + [0x12082]={ + category="lo", + description="CUNEIFORM SIGN DUGUD", + direction="l", + linebreak="al", + unicodeslot=0x12082, + }, + [0x12083]={ + category="lo", + description="CUNEIFORM SIGN DUH", + direction="l", + linebreak="al", + unicodeslot=0x12083, + }, + [0x12084]={ + category="lo", + description="CUNEIFORM SIGN DUN", + direction="l", + linebreak="al", + unicodeslot=0x12084, + }, + [0x12085]={ + category="lo", + description="CUNEIFORM SIGN DUN0x0003", + direction="l", + linebreak="al", + unicodeslot=0x12085, + }, + [0x12086]={ + category="lo", + description="CUNEIFORM SIGN DUN0x0003 GUNU", + direction="l", + linebreak="al", + unicodeslot=0x12086, + }, + [0x12087]={ + category="lo", + description="CUNEIFORM SIGN DUN0x0003 GUNU GUNU", + direction="l", + linebreak="al", + unicodeslot=0x12087, + }, + [0x12088]={ + category="lo", + description="CUNEIFORM SIGN DUN0x0004", + direction="l", + linebreak="al", + unicodeslot=0x12088, + }, + [0x12089]={ + category="lo", + description="CUNEIFORM SIGN DUR0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12089, + }, + [0x1208A]={ + category="lo", + description="CUNEIFORM SIGN E", + direction="l", + linebreak="al", + unicodeslot=0x1208A, + }, + [0x1208B]={ + category="lo", + description="CUNEIFORM SIGN E TIMES PAP", + direction="l", + linebreak="al", + unicodeslot=0x1208B, + }, + [0x1208C]={ + category="lo", + description="CUNEIFORM SIGN E OVER E NUN OVER NUN", + direction="l", + linebreak="al", + unicodeslot=0x1208C, + }, + [0x1208D]={ + category="lo", + description="CUNEIFORM SIGN E0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1208D, + }, + [0x1208E]={ + category="lo", + description="CUNEIFORM SIGN E0x0002 TIMES A PLUS HA PLUS DA", + direction="l", + linebreak="al", + unicodeslot=0x1208E, + }, + [0x1208F]={ + category="lo", + description="CUNEIFORM SIGN E0x0002 TIMES GAR", + direction="l", + linebreak="al", + unicodeslot=0x1208F, + }, + [0x12090]={ + category="lo", + description="CUNEIFORM SIGN E0x0002 TIMES MI", + direction="l", + linebreak="al", + unicodeslot=0x12090, + }, + [0x12091]={ + category="lo", + description="CUNEIFORM SIGN E0x0002 TIMES SAL", + direction="l", + linebreak="al", + unicodeslot=0x12091, + }, + [0x12092]={ + category="lo", + description="CUNEIFORM SIGN E0x0002 TIMES SHE", + direction="l", + linebreak="al", + unicodeslot=0x12092, + }, + [0x12093]={ + category="lo", + description="CUNEIFORM SIGN E0x0002 TIMES U", + direction="l", + linebreak="al", + unicodeslot=0x12093, + }, + [0x12094]={ + category="lo", + description="CUNEIFORM SIGN EDIN", + direction="l", + linebreak="al", + unicodeslot=0x12094, + }, + [0x12095]={ + category="lo", + description="CUNEIFORM SIGN EGIR", + direction="l", + linebreak="al", + unicodeslot=0x12095, + }, + [0x12096]={ + category="lo", + description="CUNEIFORM SIGN EL", + direction="l", + linebreak="al", + unicodeslot=0x12096, + }, + [0x12097]={ + category="lo", + description="CUNEIFORM SIGN EN", + direction="l", + linebreak="al", + unicodeslot=0x12097, + }, + [0x12098]={ + category="lo", + description="CUNEIFORM SIGN EN TIMES GAN0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12098, + }, + [0x12099]={ + category="lo", + description="CUNEIFORM SIGN EN TIMES GAN0x0002 TENU", + direction="l", + linebreak="al", + unicodeslot=0x12099, + }, + [0x1209A]={ + category="lo", + description="CUNEIFORM SIGN EN TIMES ME", + direction="l", + linebreak="al", + unicodeslot=0x1209A, + }, + [0x1209B]={ + category="lo", + description="CUNEIFORM SIGN EN CROSSING EN", + direction="l", + linebreak="al", + unicodeslot=0x1209B, + }, + [0x1209C]={ + category="lo", + description="CUNEIFORM SIGN EN OPPOSING EN", + direction="l", + linebreak="al", + unicodeslot=0x1209C, + }, + [0x1209D]={ + category="lo", + description="CUNEIFORM SIGN EN SQUARED", + direction="l", + linebreak="al", + unicodeslot=0x1209D, + }, + [0x1209E]={ + category="lo", + description="CUNEIFORM SIGN EREN", + direction="l", + linebreak="al", + unicodeslot=0x1209E, + }, + [0x1209F]={ + category="lo", + description="CUNEIFORM SIGN ERIN0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1209F, + }, + [0x120A0]={ + category="lo", + description="CUNEIFORM SIGN ESH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x120A0, + }, + [0x120A1]={ + category="lo", + description="CUNEIFORM SIGN EZEN", + direction="l", + linebreak="al", + unicodeslot=0x120A1, + }, + [0x120A2]={ + category="lo", + description="CUNEIFORM SIGN EZEN TIMES A", + direction="l", + linebreak="al", + unicodeslot=0x120A2, + }, + [0x120A3]={ + category="lo", + description="CUNEIFORM SIGN EZEN TIMES A PLUS LAL", + direction="l", + linebreak="al", + unicodeslot=0x120A3, + }, + [0x120A4]={ + category="lo", + description="CUNEIFORM SIGN EZEN TIMES A PLUS LAL TIMES LAL", + direction="l", + linebreak="al", + unicodeslot=0x120A4, + }, + [0x120A5]={ + category="lo", + description="CUNEIFORM SIGN EZEN TIMES AN", + direction="l", + linebreak="al", + unicodeslot=0x120A5, + }, + [0x120A6]={ + category="lo", + description="CUNEIFORM SIGN EZEN TIMES BAD", + direction="l", + linebreak="al", + unicodeslot=0x120A6, + }, + [0x120A7]={ + category="lo", + description="CUNEIFORM SIGN EZEN TIMES DUN0x0003 GUNU", + direction="l", + linebreak="al", + unicodeslot=0x120A7, + }, + [0x120A8]={ + category="lo", + description="CUNEIFORM SIGN EZEN TIMES DUN0x0003 GUNU GUNU", + direction="l", + linebreak="al", + unicodeslot=0x120A8, + }, + [0x120A9]={ + category="lo", + description="CUNEIFORM SIGN EZEN TIMES HA", + direction="l", + linebreak="al", + unicodeslot=0x120A9, + }, + [0x120AA]={ + category="lo", + description="CUNEIFORM SIGN EZEN TIMES HA GUNU", + direction="l", + linebreak="al", + unicodeslot=0x120AA, + }, + [0x120AB]={ + category="lo", + description="CUNEIFORM SIGN EZEN TIMES IGI GUNU", + direction="l", + linebreak="al", + unicodeslot=0x120AB, + }, + [0x120AC]={ + category="lo", + description="CUNEIFORM SIGN EZEN TIMES KASKAL", + direction="l", + linebreak="al", + unicodeslot=0x120AC, + }, + [0x120AD]={ + category="lo", + description="CUNEIFORM SIGN EZEN TIMES KASKAL SQUARED", + direction="l", + linebreak="al", + unicodeslot=0x120AD, + }, + [0x120AE]={ + category="lo", + description="CUNEIFORM SIGN EZEN TIMES KU0x0003", + direction="l", + linebreak="al", + unicodeslot=0x120AE, + }, + [0x120AF]={ + category="lo", + description="CUNEIFORM SIGN EZEN TIMES LA", + direction="l", + linebreak="al", + unicodeslot=0x120AF, + }, + [0x120B0]={ + category="lo", + description="CUNEIFORM SIGN EZEN TIMES LAL TIMES LAL", + direction="l", + linebreak="al", + unicodeslot=0x120B0, + }, + [0x120B1]={ + category="lo", + description="CUNEIFORM SIGN EZEN TIMES LI", + direction="l", + linebreak="al", + unicodeslot=0x120B1, + }, + [0x120B2]={ + category="lo", + description="CUNEIFORM SIGN EZEN TIMES LU", + direction="l", + linebreak="al", + unicodeslot=0x120B2, + }, + [0x120B3]={ + category="lo", + description="CUNEIFORM SIGN EZEN TIMES U0x0002", + direction="l", + linebreak="al", + unicodeslot=0x120B3, + }, + [0x120B4]={ + category="lo", + description="CUNEIFORM SIGN EZEN TIMES UD", + direction="l", + linebreak="al", + unicodeslot=0x120B4, + }, + [0x120B5]={ + category="lo", + description="CUNEIFORM SIGN GA", + direction="l", + linebreak="al", + unicodeslot=0x120B5, + }, + [0x120B6]={ + category="lo", + description="CUNEIFORM SIGN GA GUNU", + direction="l", + linebreak="al", + unicodeslot=0x120B6, + }, + [0x120B7]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002", + direction="l", + linebreak="al", + unicodeslot=0x120B7, + }, + [0x120B8]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES A PLUS DA PLUS HA", + direction="l", + linebreak="al", + unicodeslot=0x120B8, + }, + [0x120B9]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES A PLUS HA", + direction="l", + linebreak="al", + unicodeslot=0x120B9, + }, + [0x120BA]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES A PLUS IGI", + direction="l", + linebreak="al", + unicodeslot=0x120BA, + }, + [0x120BB]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES AB0x0002 TENU PLUS TAB", + direction="l", + linebreak="al", + unicodeslot=0x120BB, + }, + [0x120BC]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES AN", + direction="l", + linebreak="al", + unicodeslot=0x120BC, + }, + [0x120BD]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES ASH", + direction="l", + linebreak="al", + unicodeslot=0x120BD, + }, + [0x120BE]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES ASH0x0002 PLUS GAL", + direction="l", + linebreak="al", + unicodeslot=0x120BE, + }, + [0x120BF]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES BAD", + direction="l", + linebreak="al", + unicodeslot=0x120BF, + }, + [0x120C0]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES BAR PLUS RA", + direction="l", + linebreak="al", + unicodeslot=0x120C0, + }, + [0x120C1]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES BUR", + direction="l", + linebreak="al", + unicodeslot=0x120C1, + }, + [0x120C2]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES BUR PLUS RA", + direction="l", + linebreak="al", + unicodeslot=0x120C2, + }, + [0x120C3]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES DA", + direction="l", + linebreak="al", + unicodeslot=0x120C3, + }, + [0x120C4]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES DI", + direction="l", + linebreak="al", + unicodeslot=0x120C4, + }, + [0x120C5]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES DIM TIMES SHE", + direction="l", + linebreak="al", + unicodeslot=0x120C5, + }, + [0x120C6]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES DUB", + direction="l", + linebreak="al", + unicodeslot=0x120C6, + }, + [0x120C7]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES EL", + direction="l", + linebreak="al", + unicodeslot=0x120C7, + }, + [0x120C8]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES EL PLUS LA", + direction="l", + linebreak="al", + unicodeslot=0x120C8, + }, + [0x120C9]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES EN", + direction="l", + linebreak="al", + unicodeslot=0x120C9, + }, + [0x120CA]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES EN TIMES GAN0x0002 TENU", + direction="l", + linebreak="al", + unicodeslot=0x120CA, + }, + [0x120CB]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES GAN0x0002 TENU", + direction="l", + linebreak="al", + unicodeslot=0x120CB, + }, + [0x120CC]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES GAR", + direction="l", + linebreak="al", + unicodeslot=0x120CC, + }, + [0x120CD]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES GI", + direction="l", + linebreak="al", + unicodeslot=0x120CD, + }, + [0x120CE]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES GI0x0004", + direction="l", + linebreak="al", + unicodeslot=0x120CE, + }, + [0x120CF]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES GI0x0004 PLUS A", + direction="l", + linebreak="al", + unicodeslot=0x120CF, + }, + [0x120D0]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES GIR0x0002 PLUS SU", + direction="l", + linebreak="al", + unicodeslot=0x120D0, + }, + [0x120D1]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES HA PLUS LU PLUS ESH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x120D1, + }, + [0x120D2]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES HAL", + direction="l", + linebreak="al", + unicodeslot=0x120D2, + }, + [0x120D3]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES HAL PLUS LA", + direction="l", + linebreak="al", + unicodeslot=0x120D3, + }, + [0x120D4]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES HI PLUS LI", + direction="l", + linebreak="al", + unicodeslot=0x120D4, + }, + [0x120D5]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES HUB0x0002", + direction="l", + linebreak="al", + unicodeslot=0x120D5, + }, + [0x120D6]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES IGI GUNU", + direction="l", + linebreak="al", + unicodeslot=0x120D6, + }, + [0x120D7]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES ISH PLUS HU PLUS ASH", + direction="l", + linebreak="al", + unicodeslot=0x120D7, + }, + [0x120D8]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES KAK", + direction="l", + linebreak="al", + unicodeslot=0x120D8, + }, + [0x120D9]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES KASKAL", + direction="l", + linebreak="al", + unicodeslot=0x120D9, + }, + [0x120DA]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES KID", + direction="l", + linebreak="al", + unicodeslot=0x120DA, + }, + [0x120DB]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES KID PLUS LAL", + direction="l", + linebreak="al", + unicodeslot=0x120DB, + }, + [0x120DC]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES KU0x0003 PLUS AN", + direction="l", + linebreak="al", + unicodeslot=0x120DC, + }, + [0x120DD]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES LA", + direction="l", + linebreak="al", + unicodeslot=0x120DD, + }, + [0x120DE]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES ME PLUS EN", + direction="l", + linebreak="al", + unicodeslot=0x120DE, + }, + [0x120DF]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES MI", + direction="l", + linebreak="al", + unicodeslot=0x120DF, + }, + [0x120E0]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES NUN", + direction="l", + linebreak="al", + unicodeslot=0x120E0, + }, + [0x120E1]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES NUN OVER NUN", + direction="l", + linebreak="al", + unicodeslot=0x120E1, + }, + [0x120E2]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES PA", + direction="l", + linebreak="al", + unicodeslot=0x120E2, + }, + [0x120E3]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES SAL", + direction="l", + linebreak="al", + unicodeslot=0x120E3, + }, + [0x120E4]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES SAR", + direction="l", + linebreak="al", + unicodeslot=0x120E4, + }, + [0x120E5]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES SHE", + direction="l", + linebreak="al", + unicodeslot=0x120E5, + }, + [0x120E6]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES SHE PLUS TUR", + direction="l", + linebreak="al", + unicodeslot=0x120E6, + }, + [0x120E7]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES SHID", + direction="l", + linebreak="al", + unicodeslot=0x120E7, + }, + [0x120E8]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES SUM", + direction="l", + linebreak="al", + unicodeslot=0x120E8, + }, + [0x120E9]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES TAK0x0004", + direction="l", + linebreak="al", + unicodeslot=0x120E9, + }, + [0x120EA]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES U", + direction="l", + linebreak="al", + unicodeslot=0x120EA, + }, + [0x120EB]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES UD", + direction="l", + linebreak="al", + unicodeslot=0x120EB, + }, + [0x120EC]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 TIMES UD PLUS DU", + direction="l", + linebreak="al", + unicodeslot=0x120EC, + }, + [0x120ED]={ + category="lo", + description="CUNEIFORM SIGN GA0x0002 OVER GA0x0002", + direction="l", + linebreak="al", + unicodeslot=0x120ED, + }, + [0x120EE]={ + category="lo", + description="CUNEIFORM SIGN GABA", + direction="l", + linebreak="al", + unicodeslot=0x120EE, + }, + [0x120EF]={ + category="lo", + description="CUNEIFORM SIGN GABA CROSSING GABA", + direction="l", + linebreak="al", + unicodeslot=0x120EF, + }, + [0x120F0]={ + category="lo", + description="CUNEIFORM SIGN GAD", + direction="l", + linebreak="al", + unicodeslot=0x120F0, + }, + [0x120F1]={ + category="lo", + description="CUNEIFORM SIGN GAD OVER GAD GAR OVER GAR", + direction="l", + linebreak="al", + unicodeslot=0x120F1, + }, + [0x120F2]={ + category="lo", + description="CUNEIFORM SIGN GAL", + direction="l", + linebreak="al", + unicodeslot=0x120F2, + }, + [0x120F3]={ + category="lo", + description="CUNEIFORM SIGN GAL GAD OVER GAD GAR OVER GAR", + direction="l", + linebreak="al", + unicodeslot=0x120F3, + }, + [0x120F4]={ + category="lo", + description="CUNEIFORM SIGN GALAM", + direction="l", + linebreak="al", + unicodeslot=0x120F4, + }, + [0x120F5]={ + category="lo", + description="CUNEIFORM SIGN GAM", + direction="l", + linebreak="al", + unicodeslot=0x120F5, + }, + [0x120F6]={ + category="lo", + description="CUNEIFORM SIGN GAN", + direction="l", + linebreak="al", + unicodeslot=0x120F6, + }, + [0x120F7]={ + category="lo", + description="CUNEIFORM SIGN GAN0x0002", + direction="l", + linebreak="al", + unicodeslot=0x120F7, + }, + [0x120F8]={ + category="lo", + description="CUNEIFORM SIGN GAN0x0002 TENU", + direction="l", + linebreak="al", + unicodeslot=0x120F8, + }, + [0x120F9]={ + category="lo", + description="CUNEIFORM SIGN GAN0x0002 OVER GAN0x0002", + direction="l", + linebreak="al", + unicodeslot=0x120F9, + }, + [0x120FA]={ + category="lo", + description="CUNEIFORM SIGN GAN0x0002 CROSSING GAN0x0002", + direction="l", + linebreak="al", + unicodeslot=0x120FA, + }, + [0x120FB]={ + category="lo", + description="CUNEIFORM SIGN GAR", + direction="l", + linebreak="al", + unicodeslot=0x120FB, + }, + [0x120FC]={ + category="lo", + description="CUNEIFORM SIGN GAR0x0003", + direction="l", + linebreak="al", + unicodeslot=0x120FC, + }, + [0x120FD]={ + category="lo", + description="CUNEIFORM SIGN GASHAN", + direction="l", + linebreak="al", + unicodeslot=0x120FD, + }, + [0x120FE]={ + category="lo", + description="CUNEIFORM SIGN GESHTIN", + direction="l", + linebreak="al", + unicodeslot=0x120FE, + }, + [0x120FF]={ + category="lo", + description="CUNEIFORM SIGN GESHTIN TIMES KUR", + direction="l", + linebreak="al", + unicodeslot=0x120FF, + }, + [0x12100]={ + category="lo", + description="CUNEIFORM SIGN GI", + direction="l", + linebreak="al", + unicodeslot=0x12100, + }, + [0x12101]={ + category="lo", + description="CUNEIFORM SIGN GI TIMES E", + direction="l", + linebreak="al", + unicodeslot=0x12101, + }, + [0x12102]={ + category="lo", + description="CUNEIFORM SIGN GI TIMES U", + direction="l", + linebreak="al", + unicodeslot=0x12102, + }, + [0x12103]={ + category="lo", + description="CUNEIFORM SIGN GI CROSSING GI", + direction="l", + linebreak="al", + unicodeslot=0x12103, + }, + [0x12104]={ + category="lo", + description="CUNEIFORM SIGN GI0x0004", + direction="l", + linebreak="al", + unicodeslot=0x12104, + }, + [0x12105]={ + category="lo", + description="CUNEIFORM SIGN GI0x0004 OVER GI0x0004", + direction="l", + linebreak="al", + unicodeslot=0x12105, + }, + [0x12106]={ + category="lo", + description="CUNEIFORM SIGN GI0x0004 CROSSING GI0x0004", + direction="l", + linebreak="al", + unicodeslot=0x12106, + }, + [0x12107]={ + category="lo", + description="CUNEIFORM SIGN GIDIM", + direction="l", + linebreak="al", + unicodeslot=0x12107, + }, + [0x12108]={ + category="lo", + description="CUNEIFORM SIGN GIR0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12108, + }, + [0x12109]={ + category="lo", + description="CUNEIFORM SIGN GIR0x0002 GUNU", + direction="l", + linebreak="al", + unicodeslot=0x12109, + }, + [0x1210A]={ + category="lo", + description="CUNEIFORM SIGN GIR0x0003", + direction="l", + linebreak="al", + unicodeslot=0x1210A, + }, + [0x1210B]={ + category="lo", + description="CUNEIFORM SIGN GIR0x0003 TIMES A PLUS IGI", + direction="l", + linebreak="al", + unicodeslot=0x1210B, + }, + [0x1210C]={ + category="lo", + description="CUNEIFORM SIGN GIR0x0003 TIMES GAN0x0002 TENU", + direction="l", + linebreak="al", + unicodeslot=0x1210C, + }, + [0x1210D]={ + category="lo", + description="CUNEIFORM SIGN GIR0x0003 TIMES IGI", + direction="l", + linebreak="al", + unicodeslot=0x1210D, + }, + [0x1210E]={ + category="lo", + description="CUNEIFORM SIGN GIR0x0003 TIMES LU PLUS IGI", + direction="l", + linebreak="al", + unicodeslot=0x1210E, + }, + [0x1210F]={ + category="lo", + description="CUNEIFORM SIGN GIR0x0003 TIMES PA", + direction="l", + linebreak="al", + unicodeslot=0x1210F, + }, + [0x12110]={ + category="lo", + description="CUNEIFORM SIGN GISAL", + direction="l", + linebreak="al", + unicodeslot=0x12110, + }, + [0x12111]={ + category="lo", + description="CUNEIFORM SIGN GISH", + direction="l", + linebreak="al", + unicodeslot=0x12111, + }, + [0x12112]={ + category="lo", + description="CUNEIFORM SIGN GISH CROSSING GISH", + direction="l", + linebreak="al", + unicodeslot=0x12112, + }, + [0x12113]={ + category="lo", + description="CUNEIFORM SIGN GISH TIMES BAD", + direction="l", + linebreak="al", + unicodeslot=0x12113, + }, + [0x12114]={ + category="lo", + description="CUNEIFORM SIGN GISH TIMES TAK0x0004", + direction="l", + linebreak="al", + unicodeslot=0x12114, + }, + [0x12115]={ + category="lo", + description="CUNEIFORM SIGN GISH TENU", + direction="l", + linebreak="al", + unicodeslot=0x12115, + }, + [0x12116]={ + category="lo", + description="CUNEIFORM SIGN GU", + direction="l", + linebreak="al", + unicodeslot=0x12116, + }, + [0x12117]={ + category="lo", + description="CUNEIFORM SIGN GU CROSSING GU", + direction="l", + linebreak="al", + unicodeslot=0x12117, + }, + [0x12118]={ + category="lo", + description="CUNEIFORM SIGN GU0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12118, + }, + [0x12119]={ + category="lo", + description="CUNEIFORM SIGN GU0x0002 TIMES KAK", + direction="l", + linebreak="al", + unicodeslot=0x12119, + }, + [0x1211A]={ + category="lo", + description="CUNEIFORM SIGN GU0x0002 TIMES KAK TIMES IGI GUNU", + direction="l", + linebreak="al", + unicodeslot=0x1211A, + }, + [0x1211B]={ + category="lo", + description="CUNEIFORM SIGN GU0x0002 TIMES NUN", + direction="l", + linebreak="al", + unicodeslot=0x1211B, + }, + [0x1211C]={ + category="lo", + description="CUNEIFORM SIGN GU0x0002 TIMES SAL PLUS TUG0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1211C, + }, + [0x1211D]={ + category="lo", + description="CUNEIFORM SIGN GU0x0002 GUNU", + direction="l", + linebreak="al", + unicodeslot=0x1211D, + }, + [0x1211E]={ + category="lo", + description="CUNEIFORM SIGN GUD", + direction="l", + linebreak="al", + unicodeslot=0x1211E, + }, + [0x1211F]={ + category="lo", + description="CUNEIFORM SIGN GUD TIMES A PLUS KUR", + direction="l", + linebreak="al", + unicodeslot=0x1211F, + }, + [0x12120]={ + category="lo", + description="CUNEIFORM SIGN GUD TIMES KUR", + direction="l", + linebreak="al", + unicodeslot=0x12120, + }, + [0x12121]={ + category="lo", + description="CUNEIFORM SIGN GUD OVER GUD LUGAL", + direction="l", + linebreak="al", + unicodeslot=0x12121, + }, + [0x12122]={ + category="lo", + description="CUNEIFORM SIGN GUL", + direction="l", + linebreak="al", + unicodeslot=0x12122, + }, + [0x12123]={ + category="lo", + description="CUNEIFORM SIGN GUM", + direction="l", + linebreak="al", + unicodeslot=0x12123, + }, + [0x12124]={ + category="lo", + description="CUNEIFORM SIGN GUM TIMES SHE", + direction="l", + linebreak="al", + unicodeslot=0x12124, + }, + [0x12125]={ + category="lo", + description="CUNEIFORM SIGN GUR", + direction="l", + linebreak="al", + unicodeslot=0x12125, + }, + [0x12126]={ + category="lo", + description="CUNEIFORM SIGN GUR0x0007", + direction="l", + linebreak="al", + unicodeslot=0x12126, + }, + [0x12127]={ + category="lo", + description="CUNEIFORM SIGN GURUN", + direction="l", + linebreak="al", + unicodeslot=0x12127, + }, + [0x12128]={ + category="lo", + description="CUNEIFORM SIGN GURUSH", + direction="l", + linebreak="al", + unicodeslot=0x12128, + }, + [0x12129]={ + category="lo", + description="CUNEIFORM SIGN HA", + direction="l", + linebreak="al", + unicodeslot=0x12129, + }, + [0x1212A]={ + category="lo", + description="CUNEIFORM SIGN HA TENU", + direction="l", + linebreak="al", + unicodeslot=0x1212A, + }, + [0x1212B]={ + category="lo", + description="CUNEIFORM SIGN HA GUNU", + direction="l", + linebreak="al", + unicodeslot=0x1212B, + }, + [0x1212C]={ + category="lo", + description="CUNEIFORM SIGN HAL", + direction="l", + linebreak="al", + unicodeslot=0x1212C, + }, + [0x1212D]={ + category="lo", + description="CUNEIFORM SIGN HI", + direction="l", + linebreak="al", + unicodeslot=0x1212D, + }, + [0x1212E]={ + category="lo", + description="CUNEIFORM SIGN HI TIMES ASH", + direction="l", + linebreak="al", + unicodeslot=0x1212E, + }, + [0x1212F]={ + category="lo", + description="CUNEIFORM SIGN HI TIMES ASH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1212F, + }, + [0x12130]={ + category="lo", + description="CUNEIFORM SIGN HI TIMES BAD", + direction="l", + linebreak="al", + unicodeslot=0x12130, + }, + [0x12131]={ + category="lo", + description="CUNEIFORM SIGN HI TIMES DISH", + direction="l", + linebreak="al", + unicodeslot=0x12131, + }, + [0x12132]={ + category="lo", + description="CUNEIFORM SIGN HI TIMES GAD", + direction="l", + linebreak="al", + unicodeslot=0x12132, + }, + [0x12133]={ + category="lo", + description="CUNEIFORM SIGN HI TIMES KIN", + direction="l", + linebreak="al", + unicodeslot=0x12133, + }, + [0x12134]={ + category="lo", + description="CUNEIFORM SIGN HI TIMES NUN", + direction="l", + linebreak="al", + unicodeslot=0x12134, + }, + [0x12135]={ + category="lo", + description="CUNEIFORM SIGN HI TIMES SHE", + direction="l", + linebreak="al", + unicodeslot=0x12135, + }, + [0x12136]={ + category="lo", + description="CUNEIFORM SIGN HI TIMES U", + direction="l", + linebreak="al", + unicodeslot=0x12136, + }, + [0x12137]={ + category="lo", + description="CUNEIFORM SIGN HU", + direction="l", + linebreak="al", + unicodeslot=0x12137, + }, + [0x12138]={ + category="lo", + description="CUNEIFORM SIGN HUB0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12138, + }, + [0x12139]={ + category="lo", + description="CUNEIFORM SIGN HUB0x0002 TIMES AN", + direction="l", + linebreak="al", + unicodeslot=0x12139, + }, + [0x1213A]={ + category="lo", + description="CUNEIFORM SIGN HUB0x0002 TIMES HAL", + direction="l", + linebreak="al", + unicodeslot=0x1213A, + }, + [0x1213B]={ + category="lo", + description="CUNEIFORM SIGN HUB0x0002 TIMES KASKAL", + direction="l", + linebreak="al", + unicodeslot=0x1213B, + }, + [0x1213C]={ + category="lo", + description="CUNEIFORM SIGN HUB0x0002 TIMES LISH", + direction="l", + linebreak="al", + unicodeslot=0x1213C, + }, + [0x1213D]={ + category="lo", + description="CUNEIFORM SIGN HUB0x0002 TIMES UD", + direction="l", + linebreak="al", + unicodeslot=0x1213D, + }, + [0x1213E]={ + category="lo", + description="CUNEIFORM SIGN HUL0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1213E, + }, + [0x1213F]={ + category="lo", + description="CUNEIFORM SIGN I", + direction="l", + linebreak="al", + unicodeslot=0x1213F, + }, + [0x12140]={ + category="lo", + description="CUNEIFORM SIGN I A", + direction="l", + linebreak="al", + unicodeslot=0x12140, + }, + [0x12141]={ + category="lo", + description="CUNEIFORM SIGN IB", + direction="l", + linebreak="al", + unicodeslot=0x12141, + }, + [0x12142]={ + category="lo", + description="CUNEIFORM SIGN IDIM", + direction="l", + linebreak="al", + unicodeslot=0x12142, + }, + [0x12143]={ + category="lo", + description="CUNEIFORM SIGN IDIM OVER IDIM BUR", + direction="l", + linebreak="al", + unicodeslot=0x12143, + }, + [0x12144]={ + category="lo", + description="CUNEIFORM SIGN IDIM OVER IDIM SQUARED", + direction="l", + linebreak="al", + unicodeslot=0x12144, + }, + [0x12145]={ + category="lo", + description="CUNEIFORM SIGN IG", + direction="l", + linebreak="al", + unicodeslot=0x12145, + }, + [0x12146]={ + category="lo", + description="CUNEIFORM SIGN IGI", + direction="l", + linebreak="al", + unicodeslot=0x12146, + }, + [0x12147]={ + category="lo", + description="CUNEIFORM SIGN IGI DIB", + direction="l", + linebreak="al", + unicodeslot=0x12147, + }, + [0x12148]={ + category="lo", + description="CUNEIFORM SIGN IGI RI", + direction="l", + linebreak="al", + unicodeslot=0x12148, + }, + [0x12149]={ + category="lo", + description="CUNEIFORM SIGN IGI OVER IGI SHIR OVER SHIR UD OVER UD", + direction="l", + linebreak="al", + unicodeslot=0x12149, + }, + [0x1214A]={ + category="lo", + description="CUNEIFORM SIGN IGI GUNU", + direction="l", + linebreak="al", + unicodeslot=0x1214A, + }, + [0x1214B]={ + category="lo", + description="CUNEIFORM SIGN IL", + direction="l", + linebreak="al", + unicodeslot=0x1214B, + }, + [0x1214C]={ + category="lo", + description="CUNEIFORM SIGN IL TIMES GAN0x0002 TENU", + direction="l", + linebreak="al", + unicodeslot=0x1214C, + }, + [0x1214D]={ + category="lo", + description="CUNEIFORM SIGN IL0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1214D, + }, + [0x1214E]={ + category="lo", + description="CUNEIFORM SIGN IM", + direction="l", + linebreak="al", + unicodeslot=0x1214E, + }, + [0x1214F]={ + category="lo", + description="CUNEIFORM SIGN IM TIMES TAK0x0004", + direction="l", + linebreak="al", + unicodeslot=0x1214F, + }, + [0x12150]={ + category="lo", + description="CUNEIFORM SIGN IM CROSSING IM", + direction="l", + linebreak="al", + unicodeslot=0x12150, + }, + [0x12151]={ + category="lo", + description="CUNEIFORM SIGN IM OPPOSING IM", + direction="l", + linebreak="al", + unicodeslot=0x12151, + }, + [0x12152]={ + category="lo", + description="CUNEIFORM SIGN IM SQUARED", + direction="l", + linebreak="al", + unicodeslot=0x12152, + }, + [0x12153]={ + category="lo", + description="CUNEIFORM SIGN IMIN", + direction="l", + linebreak="al", + unicodeslot=0x12153, + }, + [0x12154]={ + category="lo", + description="CUNEIFORM SIGN IN", + direction="l", + linebreak="al", + unicodeslot=0x12154, + }, + [0x12155]={ + category="lo", + description="CUNEIFORM SIGN IR", + direction="l", + linebreak="al", + unicodeslot=0x12155, + }, + [0x12156]={ + category="lo", + description="CUNEIFORM SIGN ISH", + direction="l", + linebreak="al", + unicodeslot=0x12156, + }, + [0x12157]={ + category="lo", + description="CUNEIFORM SIGN KA", + direction="l", + linebreak="al", + unicodeslot=0x12157, + }, + [0x12158]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES A", + direction="l", + linebreak="al", + unicodeslot=0x12158, + }, + [0x12159]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES AD", + direction="l", + linebreak="al", + unicodeslot=0x12159, + }, + [0x1215A]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES AD PLUS KU0x0003", + direction="l", + linebreak="al", + unicodeslot=0x1215A, + }, + [0x1215B]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES ASH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1215B, + }, + [0x1215C]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES BAD", + direction="l", + linebreak="al", + unicodeslot=0x1215C, + }, + [0x1215D]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES BALAG", + direction="l", + linebreak="al", + unicodeslot=0x1215D, + }, + [0x1215E]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES BAR", + direction="l", + linebreak="al", + unicodeslot=0x1215E, + }, + [0x1215F]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES BI", + direction="l", + linebreak="al", + unicodeslot=0x1215F, + }, + [0x12160]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES ERIN0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12160, + }, + [0x12161]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES ESH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12161, + }, + [0x12162]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES GA", + direction="l", + linebreak="al", + unicodeslot=0x12162, + }, + [0x12163]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES GAL", + direction="l", + linebreak="al", + unicodeslot=0x12163, + }, + [0x12164]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES GAN0x0002 TENU", + direction="l", + linebreak="al", + unicodeslot=0x12164, + }, + [0x12165]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES GAR", + direction="l", + linebreak="al", + unicodeslot=0x12165, + }, + [0x12166]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES GAR PLUS SHA0x0003 PLUS A", + direction="l", + linebreak="al", + unicodeslot=0x12166, + }, + [0x12167]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES GI", + direction="l", + linebreak="al", + unicodeslot=0x12167, + }, + [0x12168]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES GIR0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12168, + }, + [0x12169]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES GISH PLUS SAR", + direction="l", + linebreak="al", + unicodeslot=0x12169, + }, + [0x1216A]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES GISH CROSSING GISH", + direction="l", + linebreak="al", + unicodeslot=0x1216A, + }, + [0x1216B]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES GU", + direction="l", + linebreak="al", + unicodeslot=0x1216B, + }, + [0x1216C]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES GUR0x0007", + direction="l", + linebreak="al", + unicodeslot=0x1216C, + }, + [0x1216D]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES IGI", + direction="l", + linebreak="al", + unicodeslot=0x1216D, + }, + [0x1216E]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES IM", + direction="l", + linebreak="al", + unicodeslot=0x1216E, + }, + [0x1216F]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES KAK", + direction="l", + linebreak="al", + unicodeslot=0x1216F, + }, + [0x12170]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES KI", + direction="l", + linebreak="al", + unicodeslot=0x12170, + }, + [0x12171]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES KID", + direction="l", + linebreak="al", + unicodeslot=0x12171, + }, + [0x12172]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES LI", + direction="l", + linebreak="al", + unicodeslot=0x12172, + }, + [0x12173]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES LU", + direction="l", + linebreak="al", + unicodeslot=0x12173, + }, + [0x12174]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES ME", + direction="l", + linebreak="al", + unicodeslot=0x12174, + }, + [0x12175]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES ME PLUS DU", + direction="l", + linebreak="al", + unicodeslot=0x12175, + }, + [0x12176]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES ME PLUS GI", + direction="l", + linebreak="al", + unicodeslot=0x12176, + }, + [0x12177]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES ME PLUS TE", + direction="l", + linebreak="al", + unicodeslot=0x12177, + }, + [0x12178]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES MI", + direction="l", + linebreak="al", + unicodeslot=0x12178, + }, + [0x12179]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES MI PLUS NUNUZ", + direction="l", + linebreak="al", + unicodeslot=0x12179, + }, + [0x1217A]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES NE", + direction="l", + linebreak="al", + unicodeslot=0x1217A, + }, + [0x1217B]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES NUN", + direction="l", + linebreak="al", + unicodeslot=0x1217B, + }, + [0x1217C]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES PI", + direction="l", + linebreak="al", + unicodeslot=0x1217C, + }, + [0x1217D]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES RU", + direction="l", + linebreak="al", + unicodeslot=0x1217D, + }, + [0x1217E]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES SA", + direction="l", + linebreak="al", + unicodeslot=0x1217E, + }, + [0x1217F]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES SAR", + direction="l", + linebreak="al", + unicodeslot=0x1217F, + }, + [0x12180]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES SHA", + direction="l", + linebreak="al", + unicodeslot=0x12180, + }, + [0x12181]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES SHE", + direction="l", + linebreak="al", + unicodeslot=0x12181, + }, + [0x12182]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES SHID", + direction="l", + linebreak="al", + unicodeslot=0x12182, + }, + [0x12183]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES SHU", + direction="l", + linebreak="al", + unicodeslot=0x12183, + }, + [0x12184]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES SIG", + direction="l", + linebreak="al", + unicodeslot=0x12184, + }, + [0x12185]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES SUHUR", + direction="l", + linebreak="al", + unicodeslot=0x12185, + }, + [0x12186]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES TAR", + direction="l", + linebreak="al", + unicodeslot=0x12186, + }, + [0x12187]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES U", + direction="l", + linebreak="al", + unicodeslot=0x12187, + }, + [0x12188]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES U0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12188, + }, + [0x12189]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES UD", + direction="l", + linebreak="al", + unicodeslot=0x12189, + }, + [0x1218A]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES UMUM TIMES PA", + direction="l", + linebreak="al", + unicodeslot=0x1218A, + }, + [0x1218B]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES USH", + direction="l", + linebreak="al", + unicodeslot=0x1218B, + }, + [0x1218C]={ + category="lo", + description="CUNEIFORM SIGN KA TIMES ZI", + direction="l", + linebreak="al", + unicodeslot=0x1218C, + }, + [0x1218D]={ + category="lo", + description="CUNEIFORM SIGN KA0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1218D, + }, + [0x1218E]={ + category="lo", + description="CUNEIFORM SIGN KA0x0002 CROSSING KA0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1218E, + }, + [0x1218F]={ + category="lo", + description="CUNEIFORM SIGN KAB", + direction="l", + linebreak="al", + unicodeslot=0x1218F, + }, + [0x12190]={ + category="lo", + description="CUNEIFORM SIGN KAD0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12190, + }, + [0x12191]={ + category="lo", + description="CUNEIFORM SIGN KAD0x0003", + direction="l", + linebreak="al", + unicodeslot=0x12191, + }, + [0x12192]={ + category="lo", + description="CUNEIFORM SIGN KAD0x0004", + direction="l", + linebreak="al", + unicodeslot=0x12192, + }, + [0x12193]={ + category="lo", + description="CUNEIFORM SIGN KAD0x0005", + direction="l", + linebreak="al", + unicodeslot=0x12193, + }, + [0x12194]={ + category="lo", + description="CUNEIFORM SIGN KAD0x0005 OVER KAD0x0005", + direction="l", + linebreak="al", + unicodeslot=0x12194, + }, + [0x12195]={ + category="lo", + description="CUNEIFORM SIGN KAK", + direction="l", + linebreak="al", + unicodeslot=0x12195, + }, + [0x12196]={ + category="lo", + description="CUNEIFORM SIGN KAK TIMES IGI GUNU", + direction="l", + linebreak="al", + unicodeslot=0x12196, + }, + [0x12197]={ + category="lo", + description="CUNEIFORM SIGN KAL", + direction="l", + linebreak="al", + unicodeslot=0x12197, + }, + [0x12198]={ + category="lo", + description="CUNEIFORM SIGN KAL TIMES BAD", + direction="l", + linebreak="al", + unicodeslot=0x12198, + }, + [0x12199]={ + category="lo", + description="CUNEIFORM SIGN KAL CROSSING KAL", + direction="l", + linebreak="al", + unicodeslot=0x12199, + }, + [0x1219A]={ + category="lo", + description="CUNEIFORM SIGN KAM0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1219A, + }, + [0x1219B]={ + category="lo", + description="CUNEIFORM SIGN KAM0x0004", + direction="l", + linebreak="al", + unicodeslot=0x1219B, + }, + [0x1219C]={ + category="lo", + description="CUNEIFORM SIGN KASKAL", + direction="l", + linebreak="al", + unicodeslot=0x1219C, + }, + [0x1219D]={ + category="lo", + description="CUNEIFORM SIGN KASKAL LAGAB TIMES U OVER LAGAB TIMES U", + direction="l", + linebreak="al", + unicodeslot=0x1219D, + }, + [0x1219E]={ + category="lo", + description="CUNEIFORM SIGN KASKAL OVER KASKAL LAGAB TIMES U OVER LAGAB TIMES U", + direction="l", + linebreak="al", + unicodeslot=0x1219E, + }, + [0x1219F]={ + category="lo", + description="CUNEIFORM SIGN KESH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1219F, + }, + [0x121A0]={ + category="lo", + description="CUNEIFORM SIGN KI", + direction="l", + linebreak="al", + unicodeslot=0x121A0, + }, + [0x121A1]={ + category="lo", + description="CUNEIFORM SIGN KI TIMES BAD", + direction="l", + linebreak="al", + unicodeslot=0x121A1, + }, + [0x121A2]={ + category="lo", + description="CUNEIFORM SIGN KI TIMES U", + direction="l", + linebreak="al", + unicodeslot=0x121A2, + }, + [0x121A3]={ + category="lo", + description="CUNEIFORM SIGN KI TIMES UD", + direction="l", + linebreak="al", + unicodeslot=0x121A3, + }, + [0x121A4]={ + category="lo", + description="CUNEIFORM SIGN KID", + direction="l", + linebreak="al", + unicodeslot=0x121A4, + }, + [0x121A5]={ + category="lo", + description="CUNEIFORM SIGN KIN", + direction="l", + linebreak="al", + unicodeslot=0x121A5, + }, + [0x121A6]={ + category="lo", + description="CUNEIFORM SIGN KISAL", + direction="l", + linebreak="al", + unicodeslot=0x121A6, + }, + [0x121A7]={ + category="lo", + description="CUNEIFORM SIGN KISH", + direction="l", + linebreak="al", + unicodeslot=0x121A7, + }, + [0x121A8]={ + category="lo", + description="CUNEIFORM SIGN KISIM0x0005", + direction="l", + linebreak="al", + unicodeslot=0x121A8, + }, + [0x121A9]={ + category="lo", + description="CUNEIFORM SIGN KISIM0x0005 OVER KISIM0x0005", + direction="l", + linebreak="al", + unicodeslot=0x121A9, + }, + [0x121AA]={ + category="lo", + description="CUNEIFORM SIGN KU", + direction="l", + linebreak="al", + unicodeslot=0x121AA, + }, + [0x121AB]={ + category="lo", + description="CUNEIFORM SIGN KU OVER HI TIMES ASH0x0002 KU OVER HI TIMES ASH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x121AB, + }, + [0x121AC]={ + category="lo", + description="CUNEIFORM SIGN KU0x0003", + direction="l", + linebreak="al", + unicodeslot=0x121AC, + }, + [0x121AD]={ + category="lo", + description="CUNEIFORM SIGN KU0x0004", + direction="l", + linebreak="al", + unicodeslot=0x121AD, + }, + [0x121AE]={ + category="lo", + description="CUNEIFORM SIGN KU0x0004 VARIANT FORM", + direction="l", + linebreak="al", + unicodeslot=0x121AE, + }, + [0x121AF]={ + category="lo", + description="CUNEIFORM SIGN KU0x0007", + direction="l", + linebreak="al", + unicodeslot=0x121AF, + }, + [0x121B0]={ + category="lo", + description="CUNEIFORM SIGN KUL", + direction="l", + linebreak="al", + unicodeslot=0x121B0, + }, + [0x121B1]={ + category="lo", + description="CUNEIFORM SIGN KUL GUNU", + direction="l", + linebreak="al", + unicodeslot=0x121B1, + }, + [0x121B2]={ + category="lo", + description="CUNEIFORM SIGN KUN", + direction="l", + linebreak="al", + unicodeslot=0x121B2, + }, + [0x121B3]={ + category="lo", + description="CUNEIFORM SIGN KUR", + direction="l", + linebreak="al", + unicodeslot=0x121B3, + }, + [0x121B4]={ + category="lo", + description="CUNEIFORM SIGN KUR OPPOSING KUR", + direction="l", + linebreak="al", + unicodeslot=0x121B4, + }, + [0x121B5]={ + category="lo", + description="CUNEIFORM SIGN KUSHU0x0002", + direction="l", + linebreak="al", + unicodeslot=0x121B5, + }, + [0x121B6]={ + category="lo", + description="CUNEIFORM SIGN KWU0x013E", + direction="l", + linebreak="al", + unicodeslot=0x121B6, + }, + [0x121B7]={ + category="lo", + description="CUNEIFORM SIGN LA", + direction="l", + linebreak="al", + unicodeslot=0x121B7, + }, + [0x121B8]={ + category="lo", + description="CUNEIFORM SIGN LAGAB", + direction="l", + linebreak="al", + unicodeslot=0x121B8, + }, + [0x121B9]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES A", + direction="l", + linebreak="al", + unicodeslot=0x121B9, + }, + [0x121BA]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES A PLUS DA PLUS HA", + direction="l", + linebreak="al", + unicodeslot=0x121BA, + }, + [0x121BB]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES A PLUS GAR", + direction="l", + linebreak="al", + unicodeslot=0x121BB, + }, + [0x121BC]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES A PLUS LAL", + direction="l", + linebreak="al", + unicodeslot=0x121BC, + }, + [0x121BD]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES AL", + direction="l", + linebreak="al", + unicodeslot=0x121BD, + }, + [0x121BE]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES AN", + direction="l", + linebreak="al", + unicodeslot=0x121BE, + }, + [0x121BF]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES ASH ZIDA TENU", + direction="l", + linebreak="al", + unicodeslot=0x121BF, + }, + [0x121C0]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES BAD", + direction="l", + linebreak="al", + unicodeslot=0x121C0, + }, + [0x121C1]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES BI", + direction="l", + linebreak="al", + unicodeslot=0x121C1, + }, + [0x121C2]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES DAR", + direction="l", + linebreak="al", + unicodeslot=0x121C2, + }, + [0x121C3]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES EN", + direction="l", + linebreak="al", + unicodeslot=0x121C3, + }, + [0x121C4]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES GA", + direction="l", + linebreak="al", + unicodeslot=0x121C4, + }, + [0x121C5]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES GAR", + direction="l", + linebreak="al", + unicodeslot=0x121C5, + }, + [0x121C6]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES GUD", + direction="l", + linebreak="al", + unicodeslot=0x121C6, + }, + [0x121C7]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES GUD PLUS GUD", + direction="l", + linebreak="al", + unicodeslot=0x121C7, + }, + [0x121C8]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES HA", + direction="l", + linebreak="al", + unicodeslot=0x121C8, + }, + [0x121C9]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES HAL", + direction="l", + linebreak="al", + unicodeslot=0x121C9, + }, + [0x121CA]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES HI TIMES NUN", + direction="l", + linebreak="al", + unicodeslot=0x121CA, + }, + [0x121CB]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES IGI GUNU", + direction="l", + linebreak="al", + unicodeslot=0x121CB, + }, + [0x121CC]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES IM", + direction="l", + linebreak="al", + unicodeslot=0x121CC, + }, + [0x121CD]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES IM PLUS HA", + direction="l", + linebreak="al", + unicodeslot=0x121CD, + }, + [0x121CE]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES IM PLUS LU", + direction="l", + linebreak="al", + unicodeslot=0x121CE, + }, + [0x121CF]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES KI", + direction="l", + linebreak="al", + unicodeslot=0x121CF, + }, + [0x121D0]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES KIN", + direction="l", + linebreak="al", + unicodeslot=0x121D0, + }, + [0x121D1]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES KU0x0003", + direction="l", + linebreak="al", + unicodeslot=0x121D1, + }, + [0x121D2]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES KUL", + direction="l", + linebreak="al", + unicodeslot=0x121D2, + }, + [0x121D3]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES KUL PLUS HI PLUS A", + direction="l", + linebreak="al", + unicodeslot=0x121D3, + }, + [0x121D4]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES LAGAB", + direction="l", + linebreak="al", + unicodeslot=0x121D4, + }, + [0x121D5]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES LISH", + direction="l", + linebreak="al", + unicodeslot=0x121D5, + }, + [0x121D6]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES LU", + direction="l", + linebreak="al", + unicodeslot=0x121D6, + }, + [0x121D7]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES LUL", + direction="l", + linebreak="al", + unicodeslot=0x121D7, + }, + [0x121D8]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES ME", + direction="l", + linebreak="al", + unicodeslot=0x121D8, + }, + [0x121D9]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES ME PLUS EN", + direction="l", + linebreak="al", + unicodeslot=0x121D9, + }, + [0x121DA]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES MUSH", + direction="l", + linebreak="al", + unicodeslot=0x121DA, + }, + [0x121DB]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES NE", + direction="l", + linebreak="al", + unicodeslot=0x121DB, + }, + [0x121DC]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES SHE PLUS SUM", + direction="l", + linebreak="al", + unicodeslot=0x121DC, + }, + [0x121DD]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES SHITA PLUS GISH PLUS ERIN0x0002", + direction="l", + linebreak="al", + unicodeslot=0x121DD, + }, + [0x121DE]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES SHITA PLUS GISH TENU", + direction="l", + linebreak="al", + unicodeslot=0x121DE, + }, + [0x121DF]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES SHU0x0002", + direction="l", + linebreak="al", + unicodeslot=0x121DF, + }, + [0x121E0]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES SHU0x0002 PLUS SHU0x0002", + direction="l", + linebreak="al", + unicodeslot=0x121E0, + }, + [0x121E1]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES SUM", + direction="l", + linebreak="al", + unicodeslot=0x121E1, + }, + [0x121E2]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES TAG", + direction="l", + linebreak="al", + unicodeslot=0x121E2, + }, + [0x121E3]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES TAK0x0004", + direction="l", + linebreak="al", + unicodeslot=0x121E3, + }, + [0x121E4]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES TE PLUS A PLUS SU PLUS NA", + direction="l", + linebreak="al", + unicodeslot=0x121E4, + }, + [0x121E5]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES U", + direction="l", + linebreak="al", + unicodeslot=0x121E5, + }, + [0x121E6]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES U PLUS A", + direction="l", + linebreak="al", + unicodeslot=0x121E6, + }, + [0x121E7]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES U PLUS U PLUS U", + direction="l", + linebreak="al", + unicodeslot=0x121E7, + }, + [0x121E8]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES U0x0002 PLUS ASH", + direction="l", + linebreak="al", + unicodeslot=0x121E8, + }, + [0x121E9]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES UD", + direction="l", + linebreak="al", + unicodeslot=0x121E9, + }, + [0x121EA]={ + category="lo", + description="CUNEIFORM SIGN LAGAB TIMES USH", + direction="l", + linebreak="al", + unicodeslot=0x121EA, + }, + [0x121EB]={ + category="lo", + description="CUNEIFORM SIGN LAGAB SQUARED", + direction="l", + linebreak="al", + unicodeslot=0x121EB, + }, + [0x121EC]={ + category="lo", + description="CUNEIFORM SIGN LAGAR", + direction="l", + linebreak="al", + unicodeslot=0x121EC, + }, + [0x121ED]={ + category="lo", + description="CUNEIFORM SIGN LAGAR TIMES SHE", + direction="l", + linebreak="al", + unicodeslot=0x121ED, + }, + [0x121EE]={ + category="lo", + description="CUNEIFORM SIGN LAGAR TIMES SHE PLUS SUM", + direction="l", + linebreak="al", + unicodeslot=0x121EE, + }, + [0x121EF]={ + category="lo", + description="CUNEIFORM SIGN LAGAR GUNU", + direction="l", + linebreak="al", + unicodeslot=0x121EF, + }, + [0x121F0]={ + category="lo", + description="CUNEIFORM SIGN LAGAR GUNU OVER LAGAR GUNU SHE", + direction="l", + linebreak="al", + unicodeslot=0x121F0, + }, + [0x121F1]={ + category="lo", + description="CUNEIFORM SIGN LAHSHU", + direction="l", + linebreak="al", + unicodeslot=0x121F1, + }, + [0x121F2]={ + category="lo", + description="CUNEIFORM SIGN LAL", + direction="l", + linebreak="al", + unicodeslot=0x121F2, + }, + [0x121F3]={ + category="lo", + description="CUNEIFORM SIGN LAL TIMES LAL", + direction="l", + linebreak="al", + unicodeslot=0x121F3, + }, + [0x121F4]={ + category="lo", + description="CUNEIFORM SIGN LAM", + direction="l", + linebreak="al", + unicodeslot=0x121F4, + }, + [0x121F5]={ + category="lo", + description="CUNEIFORM SIGN LAM TIMES KUR", + direction="l", + linebreak="al", + unicodeslot=0x121F5, + }, + [0x121F6]={ + category="lo", + description="CUNEIFORM SIGN LAM TIMES KUR PLUS RU", + direction="l", + linebreak="al", + unicodeslot=0x121F6, + }, + [0x121F7]={ + category="lo", + description="CUNEIFORM SIGN LI", + direction="l", + linebreak="al", + unicodeslot=0x121F7, + }, + [0x121F8]={ + category="lo", + description="CUNEIFORM SIGN LIL", + direction="l", + linebreak="al", + unicodeslot=0x121F8, + }, + [0x121F9]={ + category="lo", + description="CUNEIFORM SIGN LIMMU0x0002", + direction="l", + linebreak="al", + unicodeslot=0x121F9, + }, + [0x121FA]={ + category="lo", + description="CUNEIFORM SIGN LISH", + direction="l", + linebreak="al", + unicodeslot=0x121FA, + }, + [0x121FB]={ + category="lo", + description="CUNEIFORM SIGN LU", + direction="l", + linebreak="al", + unicodeslot=0x121FB, + }, + [0x121FC]={ + category="lo", + description="CUNEIFORM SIGN LU TIMES BAD", + direction="l", + linebreak="al", + unicodeslot=0x121FC, + }, + [0x121FD]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002", + direction="l", + linebreak="al", + unicodeslot=0x121FD, + }, + [0x121FE]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 TIMES AL", + direction="l", + linebreak="al", + unicodeslot=0x121FE, + }, + [0x121FF]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 TIMES BAD", + direction="l", + linebreak="al", + unicodeslot=0x121FF, + }, + [0x12200]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 TIMES ESH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12200, + }, + [0x12201]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 TIMES ESH0x0002 TENU", + direction="l", + linebreak="al", + unicodeslot=0x12201, + }, + [0x12202]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 TIMES GAN0x0002 TENU", + direction="l", + linebreak="al", + unicodeslot=0x12202, + }, + [0x12203]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 TIMES HI TIMES BAD", + direction="l", + linebreak="al", + unicodeslot=0x12203, + }, + [0x12204]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 TIMES IM", + direction="l", + linebreak="al", + unicodeslot=0x12204, + }, + [0x12205]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 TIMES KAD0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12205, + }, + [0x12206]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 TIMES KAD0x0003", + direction="l", + linebreak="al", + unicodeslot=0x12206, + }, + [0x12207]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 TIMES KAD0x0003 PLUS ASH", + direction="l", + linebreak="al", + unicodeslot=0x12207, + }, + [0x12208]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 TIMES KI", + direction="l", + linebreak="al", + unicodeslot=0x12208, + }, + [0x12209]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 TIMES LA PLUS ASH", + direction="l", + linebreak="al", + unicodeslot=0x12209, + }, + [0x1220A]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 TIMES LAGAB", + direction="l", + linebreak="al", + unicodeslot=0x1220A, + }, + [0x1220B]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 TIMES ME PLUS EN", + direction="l", + linebreak="al", + unicodeslot=0x1220B, + }, + [0x1220C]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 TIMES NE", + direction="l", + linebreak="al", + unicodeslot=0x1220C, + }, + [0x1220D]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 TIMES NU", + direction="l", + linebreak="al", + unicodeslot=0x1220D, + }, + [0x1220E]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 TIMES SI PLUS ASH", + direction="l", + linebreak="al", + unicodeslot=0x1220E, + }, + [0x1220F]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 TIMES SIK0x0002 PLUS BU", + direction="l", + linebreak="al", + unicodeslot=0x1220F, + }, + [0x12210]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 TIMES TUG0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12210, + }, + [0x12211]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 TENU", + direction="l", + linebreak="al", + unicodeslot=0x12211, + }, + [0x12212]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 CROSSING LU0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12212, + }, + [0x12213]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 OPPOSING LU0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12213, + }, + [0x12214]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 SQUARED", + direction="l", + linebreak="al", + unicodeslot=0x12214, + }, + [0x12215]={ + category="lo", + description="CUNEIFORM SIGN LU0x0002 SHESHIG", + direction="l", + linebreak="al", + unicodeslot=0x12215, + }, + [0x12216]={ + category="lo", + description="CUNEIFORM SIGN LU0x0003", + direction="l", + linebreak="al", + unicodeslot=0x12216, + }, + [0x12217]={ + category="lo", + description="CUNEIFORM SIGN LUGAL", + direction="l", + linebreak="al", + unicodeslot=0x12217, + }, + [0x12218]={ + category="lo", + description="CUNEIFORM SIGN LUGAL OVER LUGAL", + direction="l", + linebreak="al", + unicodeslot=0x12218, + }, + [0x12219]={ + category="lo", + description="CUNEIFORM SIGN LUGAL OPPOSING LUGAL", + direction="l", + linebreak="al", + unicodeslot=0x12219, + }, + [0x1221A]={ + category="lo", + description="CUNEIFORM SIGN LUGAL SHESHIG", + direction="l", + linebreak="al", + unicodeslot=0x1221A, + }, + [0x1221B]={ + category="lo", + description="CUNEIFORM SIGN LUH", + direction="l", + linebreak="al", + unicodeslot=0x1221B, + }, + [0x1221C]={ + category="lo", + description="CUNEIFORM SIGN LUL", + direction="l", + linebreak="al", + unicodeslot=0x1221C, + }, + [0x1221D]={ + category="lo", + description="CUNEIFORM SIGN LUM", + direction="l", + linebreak="al", + unicodeslot=0x1221D, + }, + [0x1221E]={ + category="lo", + description="CUNEIFORM SIGN LUM OVER LUM", + direction="l", + linebreak="al", + unicodeslot=0x1221E, + }, + [0x1221F]={ + category="lo", + description="CUNEIFORM SIGN LUM OVER LUM GAR OVER GAR", + direction="l", + linebreak="al", + unicodeslot=0x1221F, + }, + [0x12220]={ + category="lo", + description="CUNEIFORM SIGN MA", + direction="l", + linebreak="al", + unicodeslot=0x12220, + }, + [0x12221]={ + category="lo", + description="CUNEIFORM SIGN MA TIMES TAK0x0004", + direction="l", + linebreak="al", + unicodeslot=0x12221, + }, + [0x12222]={ + category="lo", + description="CUNEIFORM SIGN MA GUNU", + direction="l", + linebreak="al", + unicodeslot=0x12222, + }, + [0x12223]={ + category="lo", + description="CUNEIFORM SIGN MA0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12223, + }, + [0x12224]={ + category="lo", + description="CUNEIFORM SIGN MAH", + direction="l", + linebreak="al", + unicodeslot=0x12224, + }, + [0x12225]={ + category="lo", + description="CUNEIFORM SIGN MAR", + direction="l", + linebreak="al", + unicodeslot=0x12225, + }, + [0x12226]={ + category="lo", + description="CUNEIFORM SIGN MASH", + direction="l", + linebreak="al", + unicodeslot=0x12226, + }, + [0x12227]={ + category="lo", + description="CUNEIFORM SIGN MASH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12227, + }, + [0x12228]={ + category="lo", + description="CUNEIFORM SIGN ME", + direction="l", + linebreak="al", + unicodeslot=0x12228, + }, + [0x12229]={ + category="lo", + description="CUNEIFORM SIGN MES", + direction="l", + linebreak="al", + unicodeslot=0x12229, + }, + [0x1222A]={ + category="lo", + description="CUNEIFORM SIGN MI", + direction="l", + linebreak="al", + unicodeslot=0x1222A, + }, + [0x1222B]={ + category="lo", + description="CUNEIFORM SIGN MIN", + direction="l", + linebreak="al", + unicodeslot=0x1222B, + }, + [0x1222C]={ + category="lo", + description="CUNEIFORM SIGN MU", + direction="l", + linebreak="al", + unicodeslot=0x1222C, + }, + [0x1222D]={ + category="lo", + description="CUNEIFORM SIGN MU OVER MU", + direction="l", + linebreak="al", + unicodeslot=0x1222D, + }, + [0x1222E]={ + category="lo", + description="CUNEIFORM SIGN MUG", + direction="l", + linebreak="al", + unicodeslot=0x1222E, + }, + [0x1222F]={ + category="lo", + description="CUNEIFORM SIGN MUG GUNU", + direction="l", + linebreak="al", + unicodeslot=0x1222F, + }, + [0x12230]={ + category="lo", + description="CUNEIFORM SIGN MUNSUB", + direction="l", + linebreak="al", + unicodeslot=0x12230, + }, + [0x12231]={ + category="lo", + description="CUNEIFORM SIGN MURGU0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12231, + }, + [0x12232]={ + category="lo", + description="CUNEIFORM SIGN MUSH", + direction="l", + linebreak="al", + unicodeslot=0x12232, + }, + [0x12233]={ + category="lo", + description="CUNEIFORM SIGN MUSH TIMES A", + direction="l", + linebreak="al", + unicodeslot=0x12233, + }, + [0x12234]={ + category="lo", + description="CUNEIFORM SIGN MUSH TIMES KUR", + direction="l", + linebreak="al", + unicodeslot=0x12234, + }, + [0x12235]={ + category="lo", + description="CUNEIFORM SIGN MUSH TIMES ZA", + direction="l", + linebreak="al", + unicodeslot=0x12235, + }, + [0x12236]={ + category="lo", + description="CUNEIFORM SIGN MUSH OVER MUSH", + direction="l", + linebreak="al", + unicodeslot=0x12236, + }, + [0x12237]={ + category="lo", + description="CUNEIFORM SIGN MUSH OVER MUSH TIMES A PLUS NA", + direction="l", + linebreak="al", + unicodeslot=0x12237, + }, + [0x12238]={ + category="lo", + description="CUNEIFORM SIGN MUSH CROSSING MUSH", + direction="l", + linebreak="al", + unicodeslot=0x12238, + }, + [0x12239]={ + category="lo", + description="CUNEIFORM SIGN MUSH0x0003", + direction="l", + linebreak="al", + unicodeslot=0x12239, + }, + [0x1223A]={ + category="lo", + description="CUNEIFORM SIGN MUSH0x0003 TIMES A", + direction="l", + linebreak="al", + unicodeslot=0x1223A, + }, + [0x1223B]={ + category="lo", + description="CUNEIFORM SIGN MUSH0x0003 TIMES A PLUS DI", + direction="l", + linebreak="al", + unicodeslot=0x1223B, + }, + [0x1223C]={ + category="lo", + description="CUNEIFORM SIGN MUSH0x0003 TIMES DI", + direction="l", + linebreak="al", + unicodeslot=0x1223C, + }, + [0x1223D]={ + category="lo", + description="CUNEIFORM SIGN MUSH0x0003 GUNU", + direction="l", + linebreak="al", + unicodeslot=0x1223D, + }, + [0x1223E]={ + category="lo", + description="CUNEIFORM SIGN NA", + direction="l", + linebreak="al", + unicodeslot=0x1223E, + }, + [0x1223F]={ + category="lo", + description="CUNEIFORM SIGN NA0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1223F, + }, + [0x12240]={ + category="lo", + description="CUNEIFORM SIGN NAGA", + direction="l", + linebreak="al", + unicodeslot=0x12240, + }, + [0x12241]={ + category="lo", + description="CUNEIFORM SIGN NAGA INVERTED", + direction="l", + linebreak="al", + unicodeslot=0x12241, + }, + [0x12242]={ + category="lo", + description="CUNEIFORM SIGN NAGA TIMES SHU TENU", + direction="l", + linebreak="al", + unicodeslot=0x12242, + }, + [0x12243]={ + category="lo", + description="CUNEIFORM SIGN NAGA OPPOSING NAGA", + direction="l", + linebreak="al", + unicodeslot=0x12243, + }, + [0x12244]={ + category="lo", + description="CUNEIFORM SIGN NAGAR", + direction="l", + linebreak="al", + unicodeslot=0x12244, + }, + [0x12245]={ + category="lo", + description="CUNEIFORM SIGN NAM NUTILLU", + direction="l", + linebreak="al", + unicodeslot=0x12245, + }, + [0x12246]={ + category="lo", + description="CUNEIFORM SIGN NAM", + direction="l", + linebreak="al", + unicodeslot=0x12246, + }, + [0x12247]={ + category="lo", + description="CUNEIFORM SIGN NAM0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12247, + }, + [0x12248]={ + category="lo", + description="CUNEIFORM SIGN NE", + direction="l", + linebreak="al", + unicodeslot=0x12248, + }, + [0x12249]={ + category="lo", + description="CUNEIFORM SIGN NE TIMES A", + direction="l", + linebreak="al", + unicodeslot=0x12249, + }, + [0x1224A]={ + category="lo", + description="CUNEIFORM SIGN NE TIMES UD", + direction="l", + linebreak="al", + unicodeslot=0x1224A, + }, + [0x1224B]={ + category="lo", + description="CUNEIFORM SIGN NE SHESHIG", + direction="l", + linebreak="al", + unicodeslot=0x1224B, + }, + [0x1224C]={ + category="lo", + description="CUNEIFORM SIGN NI", + direction="l", + linebreak="al", + unicodeslot=0x1224C, + }, + [0x1224D]={ + category="lo", + description="CUNEIFORM SIGN NI TIMES E", + direction="l", + linebreak="al", + unicodeslot=0x1224D, + }, + [0x1224E]={ + category="lo", + description="CUNEIFORM SIGN NI0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1224E, + }, + [0x1224F]={ + category="lo", + description="CUNEIFORM SIGN NIM", + direction="l", + linebreak="al", + unicodeslot=0x1224F, + }, + [0x12250]={ + category="lo", + description="CUNEIFORM SIGN NIM TIMES GAN0x0002 TENU", + direction="l", + linebreak="al", + unicodeslot=0x12250, + }, + [0x12251]={ + category="lo", + description="CUNEIFORM SIGN NIM TIMES GAR PLUS GAN0x0002 TENU", + direction="l", + linebreak="al", + unicodeslot=0x12251, + }, + [0x12252]={ + category="lo", + description="CUNEIFORM SIGN NINDA0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12252, + }, + [0x12253]={ + category="lo", + description="CUNEIFORM SIGN NINDA0x0002 TIMES AN", + direction="l", + linebreak="al", + unicodeslot=0x12253, + }, + [0x12254]={ + category="lo", + description="CUNEIFORM SIGN NINDA0x0002 TIMES ASH", + direction="l", + linebreak="al", + unicodeslot=0x12254, + }, + [0x12255]={ + category="lo", + description="CUNEIFORM SIGN NINDA0x0002 TIMES ASH PLUS ASH", + direction="l", + linebreak="al", + unicodeslot=0x12255, + }, + [0x12256]={ + category="lo", + description="CUNEIFORM SIGN NINDA0x0002 TIMES GUD", + direction="l", + linebreak="al", + unicodeslot=0x12256, + }, + [0x12257]={ + category="lo", + description="CUNEIFORM SIGN NINDA0x0002 TIMES ME PLUS GAN0x0002 TENU", + direction="l", + linebreak="al", + unicodeslot=0x12257, + }, + [0x12258]={ + category="lo", + description="CUNEIFORM SIGN NINDA0x0002 TIMES NE", + direction="l", + linebreak="al", + unicodeslot=0x12258, + }, + [0x12259]={ + category="lo", + description="CUNEIFORM SIGN NINDA0x0002 TIMES NUN", + direction="l", + linebreak="al", + unicodeslot=0x12259, + }, + [0x1225A]={ + category="lo", + description="CUNEIFORM SIGN NINDA0x0002 TIMES SHE", + direction="l", + linebreak="al", + unicodeslot=0x1225A, + }, + [0x1225B]={ + category="lo", + description="CUNEIFORM SIGN NINDA0x0002 TIMES SHE PLUS A AN", + direction="l", + linebreak="al", + unicodeslot=0x1225B, + }, + [0x1225C]={ + category="lo", + description="CUNEIFORM SIGN NINDA0x0002 TIMES SHE PLUS ASH", + direction="l", + linebreak="al", + unicodeslot=0x1225C, + }, + [0x1225D]={ + category="lo", + description="CUNEIFORM SIGN NINDA0x0002 TIMES SHE PLUS ASH PLUS ASH", + direction="l", + linebreak="al", + unicodeslot=0x1225D, + }, + [0x1225E]={ + category="lo", + description="CUNEIFORM SIGN NINDA0x0002 TIMES U0x0002 PLUS ASH", + direction="l", + linebreak="al", + unicodeslot=0x1225E, + }, + [0x1225F]={ + category="lo", + description="CUNEIFORM SIGN NINDA0x0002 TIMES USH", + direction="l", + linebreak="al", + unicodeslot=0x1225F, + }, + [0x12260]={ + category="lo", + description="CUNEIFORM SIGN NISAG", + direction="l", + linebreak="al", + unicodeslot=0x12260, + }, + [0x12261]={ + category="lo", + description="CUNEIFORM SIGN NU", + direction="l", + linebreak="al", + unicodeslot=0x12261, + }, + [0x12262]={ + category="lo", + description="CUNEIFORM SIGN NU0x000B", + direction="l", + linebreak="al", + unicodeslot=0x12262, + }, + [0x12263]={ + category="lo", + description="CUNEIFORM SIGN NUN", + direction="l", + linebreak="al", + unicodeslot=0x12263, + }, + [0x12264]={ + category="lo", + description="CUNEIFORM SIGN NUN LAGAR TIMES GAR", + direction="l", + linebreak="al", + unicodeslot=0x12264, + }, + [0x12265]={ + category="lo", + description="CUNEIFORM SIGN NUN LAGAR TIMES MASH", + direction="l", + linebreak="al", + unicodeslot=0x12265, + }, + [0x12266]={ + category="lo", + description="CUNEIFORM SIGN NUN LAGAR TIMES SAL", + direction="l", + linebreak="al", + unicodeslot=0x12266, + }, + [0x12267]={ + category="lo", + description="CUNEIFORM SIGN NUN LAGAR TIMES SAL OVER NUN LAGAR TIMES SAL", + direction="l", + linebreak="al", + unicodeslot=0x12267, + }, + [0x12268]={ + category="lo", + description="CUNEIFORM SIGN NUN LAGAR TIMES USH", + direction="l", + linebreak="al", + unicodeslot=0x12268, + }, + [0x12269]={ + category="lo", + description="CUNEIFORM SIGN NUN TENU", + direction="l", + linebreak="al", + unicodeslot=0x12269, + }, + [0x1226A]={ + category="lo", + description="CUNEIFORM SIGN NUN OVER NUN", + direction="l", + linebreak="al", + unicodeslot=0x1226A, + }, + [0x1226B]={ + category="lo", + description="CUNEIFORM SIGN NUN CROSSING NUN", + direction="l", + linebreak="al", + unicodeslot=0x1226B, + }, + [0x1226C]={ + category="lo", + description="CUNEIFORM SIGN NUN CROSSING NUN LAGAR OVER LAGAR", + direction="l", + linebreak="al", + unicodeslot=0x1226C, + }, + [0x1226D]={ + category="lo", + description="CUNEIFORM SIGN NUNUZ", + direction="l", + linebreak="al", + unicodeslot=0x1226D, + }, + [0x1226E]={ + category="lo", + description="CUNEIFORM SIGN NUNUZ AB0x0002 TIMES ASHGAB", + direction="l", + linebreak="al", + unicodeslot=0x1226E, + }, + [0x1226F]={ + category="lo", + description="CUNEIFORM SIGN NUNUZ AB0x0002 TIMES BI", + direction="l", + linebreak="al", + unicodeslot=0x1226F, + }, + [0x12270]={ + category="lo", + description="CUNEIFORM SIGN NUNUZ AB0x0002 TIMES DUG", + direction="l", + linebreak="al", + unicodeslot=0x12270, + }, + [0x12271]={ + category="lo", + description="CUNEIFORM SIGN NUNUZ AB0x0002 TIMES GUD", + direction="l", + linebreak="al", + unicodeslot=0x12271, + }, + [0x12272]={ + category="lo", + description="CUNEIFORM SIGN NUNUZ AB0x0002 TIMES IGI GUNU", + direction="l", + linebreak="al", + unicodeslot=0x12272, + }, + [0x12273]={ + category="lo", + description="CUNEIFORM SIGN NUNUZ AB0x0002 TIMES KAD0x0003", + direction="l", + linebreak="al", + unicodeslot=0x12273, + }, + [0x12274]={ + category="lo", + description="CUNEIFORM SIGN NUNUZ AB0x0002 TIMES LA", + direction="l", + linebreak="al", + unicodeslot=0x12274, + }, + [0x12275]={ + category="lo", + description="CUNEIFORM SIGN NUNUZ AB0x0002 TIMES NE", + direction="l", + linebreak="al", + unicodeslot=0x12275, + }, + [0x12276]={ + category="lo", + description="CUNEIFORM SIGN NUNUZ AB0x0002 TIMES SILA0x0003", + direction="l", + linebreak="al", + unicodeslot=0x12276, + }, + [0x12277]={ + category="lo", + description="CUNEIFORM SIGN NUNUZ AB0x0002 TIMES U0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12277, + }, + [0x12278]={ + category="lo", + description="CUNEIFORM SIGN NUNUZ KISIM0x0005 TIMES BI", + direction="l", + linebreak="al", + unicodeslot=0x12278, + }, + [0x12279]={ + category="lo", + description="CUNEIFORM SIGN NUNUZ KISIM0x0005 TIMES BI U", + direction="l", + linebreak="al", + unicodeslot=0x12279, + }, + [0x1227A]={ + category="lo", + description="CUNEIFORM SIGN PA", + direction="l", + linebreak="al", + unicodeslot=0x1227A, + }, + [0x1227B]={ + category="lo", + description="CUNEIFORM SIGN PAD", + direction="l", + linebreak="al", + unicodeslot=0x1227B, + }, + [0x1227C]={ + category="lo", + description="CUNEIFORM SIGN PAN", + direction="l", + linebreak="al", + unicodeslot=0x1227C, + }, + [0x1227D]={ + category="lo", + description="CUNEIFORM SIGN PAP", + direction="l", + linebreak="al", + unicodeslot=0x1227D, + }, + [0x1227E]={ + category="lo", + description="CUNEIFORM SIGN PESH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1227E, + }, + [0x1227F]={ + category="lo", + description="CUNEIFORM SIGN PI", + direction="l", + linebreak="al", + unicodeslot=0x1227F, + }, + [0x12280]={ + category="lo", + description="CUNEIFORM SIGN PI TIMES A", + direction="l", + linebreak="al", + unicodeslot=0x12280, + }, + [0x12281]={ + category="lo", + description="CUNEIFORM SIGN PI TIMES AB", + direction="l", + linebreak="al", + unicodeslot=0x12281, + }, + [0x12282]={ + category="lo", + description="CUNEIFORM SIGN PI TIMES BI", + direction="l", + linebreak="al", + unicodeslot=0x12282, + }, + [0x12283]={ + category="lo", + description="CUNEIFORM SIGN PI TIMES BU", + direction="l", + linebreak="al", + unicodeslot=0x12283, + }, + [0x12284]={ + category="lo", + description="CUNEIFORM SIGN PI TIMES E", + direction="l", + linebreak="al", + unicodeslot=0x12284, + }, + [0x12285]={ + category="lo", + description="CUNEIFORM SIGN PI TIMES I", + direction="l", + linebreak="al", + unicodeslot=0x12285, + }, + [0x12286]={ + category="lo", + description="CUNEIFORM SIGN PI TIMES IB", + direction="l", + linebreak="al", + unicodeslot=0x12286, + }, + [0x12287]={ + category="lo", + description="CUNEIFORM SIGN PI TIMES U", + direction="l", + linebreak="al", + unicodeslot=0x12287, + }, + [0x12288]={ + category="lo", + description="CUNEIFORM SIGN PI TIMES U0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12288, + }, + [0x12289]={ + category="lo", + description="CUNEIFORM SIGN PI CROSSING PI", + direction="l", + linebreak="al", + unicodeslot=0x12289, + }, + [0x1228A]={ + category="lo", + description="CUNEIFORM SIGN PIRIG", + direction="l", + linebreak="al", + unicodeslot=0x1228A, + }, + [0x1228B]={ + category="lo", + description="CUNEIFORM SIGN PIRIG TIMES KAL", + direction="l", + linebreak="al", + unicodeslot=0x1228B, + }, + [0x1228C]={ + category="lo", + description="CUNEIFORM SIGN PIRIG TIMES UD", + direction="l", + linebreak="al", + unicodeslot=0x1228C, + }, + [0x1228D]={ + category="lo", + description="CUNEIFORM SIGN PIRIG TIMES ZA", + direction="l", + linebreak="al", + unicodeslot=0x1228D, + }, + [0x1228E]={ + category="lo", + description="CUNEIFORM SIGN PIRIG OPPOSING PIRIG", + direction="l", + linebreak="al", + unicodeslot=0x1228E, + }, + [0x1228F]={ + category="lo", + description="CUNEIFORM SIGN RA", + direction="l", + linebreak="al", + unicodeslot=0x1228F, + }, + [0x12290]={ + category="lo", + description="CUNEIFORM SIGN RAB", + direction="l", + linebreak="al", + unicodeslot=0x12290, + }, + [0x12291]={ + category="lo", + description="CUNEIFORM SIGN RI", + direction="l", + linebreak="al", + unicodeslot=0x12291, + }, + [0x12292]={ + category="lo", + description="CUNEIFORM SIGN RU", + direction="l", + linebreak="al", + unicodeslot=0x12292, + }, + [0x12293]={ + category="lo", + description="CUNEIFORM SIGN SA", + direction="l", + linebreak="al", + unicodeslot=0x12293, + }, + [0x12294]={ + category="lo", + description="CUNEIFORM SIGN SAG NUTILLU", + direction="l", + linebreak="al", + unicodeslot=0x12294, + }, + [0x12295]={ + category="lo", + description="CUNEIFORM SIGN SAG", + direction="l", + linebreak="al", + unicodeslot=0x12295, + }, + [0x12296]={ + category="lo", + description="CUNEIFORM SIGN SAG TIMES A", + direction="l", + linebreak="al", + unicodeslot=0x12296, + }, + [0x12297]={ + category="lo", + description="CUNEIFORM SIGN SAG TIMES DU", + direction="l", + linebreak="al", + unicodeslot=0x12297, + }, + [0x12298]={ + category="lo", + description="CUNEIFORM SIGN SAG TIMES DUB", + direction="l", + linebreak="al", + unicodeslot=0x12298, + }, + [0x12299]={ + category="lo", + description="CUNEIFORM SIGN SAG TIMES HA", + direction="l", + linebreak="al", + unicodeslot=0x12299, + }, + [0x1229A]={ + category="lo", + description="CUNEIFORM SIGN SAG TIMES KAK", + direction="l", + linebreak="al", + unicodeslot=0x1229A, + }, + [0x1229B]={ + category="lo", + description="CUNEIFORM SIGN SAG TIMES KUR", + direction="l", + linebreak="al", + unicodeslot=0x1229B, + }, + [0x1229C]={ + category="lo", + description="CUNEIFORM SIGN SAG TIMES LUM", + direction="l", + linebreak="al", + unicodeslot=0x1229C, + }, + [0x1229D]={ + category="lo", + description="CUNEIFORM SIGN SAG TIMES MI", + direction="l", + linebreak="al", + unicodeslot=0x1229D, + }, + [0x1229E]={ + category="lo", + description="CUNEIFORM SIGN SAG TIMES NUN", + direction="l", + linebreak="al", + unicodeslot=0x1229E, + }, + [0x1229F]={ + category="lo", + description="CUNEIFORM SIGN SAG TIMES SAL", + direction="l", + linebreak="al", + unicodeslot=0x1229F, + }, + [0x122A0]={ + category="lo", + description="CUNEIFORM SIGN SAG TIMES SHID", + direction="l", + linebreak="al", + unicodeslot=0x122A0, + }, + [0x122A1]={ + category="lo", + description="CUNEIFORM SIGN SAG TIMES TAB", + direction="l", + linebreak="al", + unicodeslot=0x122A1, + }, + [0x122A2]={ + category="lo", + description="CUNEIFORM SIGN SAG TIMES U0x0002", + direction="l", + linebreak="al", + unicodeslot=0x122A2, + }, + [0x122A3]={ + category="lo", + description="CUNEIFORM SIGN SAG TIMES UB", + direction="l", + linebreak="al", + unicodeslot=0x122A3, + }, + [0x122A4]={ + category="lo", + description="CUNEIFORM SIGN SAG TIMES UM", + direction="l", + linebreak="al", + unicodeslot=0x122A4, + }, + [0x122A5]={ + category="lo", + description="CUNEIFORM SIGN SAG TIMES UR", + direction="l", + linebreak="al", + unicodeslot=0x122A5, + }, + [0x122A6]={ + category="lo", + description="CUNEIFORM SIGN SAG TIMES USH", + direction="l", + linebreak="al", + unicodeslot=0x122A6, + }, + [0x122A7]={ + category="lo", + description="CUNEIFORM SIGN SAG OVER SAG", + direction="l", + linebreak="al", + unicodeslot=0x122A7, + }, + [0x122A8]={ + category="lo", + description="CUNEIFORM SIGN SAG GUNU", + direction="l", + linebreak="al", + unicodeslot=0x122A8, + }, + [0x122A9]={ + category="lo", + description="CUNEIFORM SIGN SAL", + direction="l", + linebreak="al", + unicodeslot=0x122A9, + }, + [0x122AA]={ + category="lo", + description="CUNEIFORM SIGN SAL LAGAB TIMES ASH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x122AA, + }, + [0x122AB]={ + category="lo", + description="CUNEIFORM SIGN SANGA0x0002", + direction="l", + linebreak="al", + unicodeslot=0x122AB, + }, + [0x122AC]={ + category="lo", + description="CUNEIFORM SIGN SAR", + direction="l", + linebreak="al", + unicodeslot=0x122AC, + }, + [0x122AD]={ + category="lo", + description="CUNEIFORM SIGN SHA", + direction="l", + linebreak="al", + unicodeslot=0x122AD, + }, + [0x122AE]={ + category="lo", + description="CUNEIFORM SIGN SHA0x0003", + direction="l", + linebreak="al", + unicodeslot=0x122AE, + }, + [0x122AF]={ + category="lo", + description="CUNEIFORM SIGN SHA0x0003 TIMES A", + direction="l", + linebreak="al", + unicodeslot=0x122AF, + }, + [0x122B0]={ + category="lo", + description="CUNEIFORM SIGN SHA0x0003 TIMES BAD", + direction="l", + linebreak="al", + unicodeslot=0x122B0, + }, + [0x122B1]={ + category="lo", + description="CUNEIFORM SIGN SHA0x0003 TIMES GISH", + direction="l", + linebreak="al", + unicodeslot=0x122B1, + }, + [0x122B2]={ + category="lo", + description="CUNEIFORM SIGN SHA0x0003 TIMES NE", + direction="l", + linebreak="al", + unicodeslot=0x122B2, + }, + [0x122B3]={ + category="lo", + description="CUNEIFORM SIGN SHA0x0003 TIMES SHU0x0002", + direction="l", + linebreak="al", + unicodeslot=0x122B3, + }, + [0x122B4]={ + category="lo", + description="CUNEIFORM SIGN SHA0x0003 TIMES TUR", + direction="l", + linebreak="al", + unicodeslot=0x122B4, + }, + [0x122B5]={ + category="lo", + description="CUNEIFORM SIGN SHA0x0003 TIMES U", + direction="l", + linebreak="al", + unicodeslot=0x122B5, + }, + [0x122B6]={ + category="lo", + description="CUNEIFORM SIGN SHA0x0003 TIMES U PLUS A", + direction="l", + linebreak="al", + unicodeslot=0x122B6, + }, + [0x122B7]={ + category="lo", + description="CUNEIFORM SIGN SHA0x0006", + direction="l", + linebreak="al", + unicodeslot=0x122B7, + }, + [0x122B8]={ + category="lo", + description="CUNEIFORM SIGN SHAB0x0006", + direction="l", + linebreak="al", + unicodeslot=0x122B8, + }, + [0x122B9]={ + category="lo", + description="CUNEIFORM SIGN SHAR0x0002", + direction="l", + linebreak="al", + unicodeslot=0x122B9, + }, + [0x122BA]={ + category="lo", + description="CUNEIFORM SIGN SHE", + direction="l", + linebreak="al", + unicodeslot=0x122BA, + }, + [0x122BB]={ + category="lo", + description="CUNEIFORM SIGN SHE HU", + direction="l", + linebreak="al", + unicodeslot=0x122BB, + }, + [0x122BC]={ + category="lo", + description="CUNEIFORM SIGN SHE OVER SHE GAD OVER GAD GAR OVER GAR", + direction="l", + linebreak="al", + unicodeslot=0x122BC, + }, + [0x122BD]={ + category="lo", + description="CUNEIFORM SIGN SHE OVER SHE TAB OVER TAB GAR OVER GAR", + direction="l", + linebreak="al", + unicodeslot=0x122BD, + }, + [0x122BE]={ + category="lo", + description="CUNEIFORM SIGN SHEG0x0009", + direction="l", + linebreak="al", + unicodeslot=0x122BE, + }, + [0x122BF]={ + category="lo", + description="CUNEIFORM SIGN SHEN", + direction="l", + linebreak="al", + unicodeslot=0x122BF, + }, + [0x122C0]={ + category="lo", + description="CUNEIFORM SIGN SHESH", + direction="l", + linebreak="al", + unicodeslot=0x122C0, + }, + [0x122C1]={ + category="lo", + description="CUNEIFORM SIGN SHESH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x122C1, + }, + [0x122C2]={ + category="lo", + description="CUNEIFORM SIGN SHESHLAM", + direction="l", + linebreak="al", + unicodeslot=0x122C2, + }, + [0x122C3]={ + category="lo", + description="CUNEIFORM SIGN SHID", + direction="l", + linebreak="al", + unicodeslot=0x122C3, + }, + [0x122C4]={ + category="lo", + description="CUNEIFORM SIGN SHID TIMES A", + direction="l", + linebreak="al", + unicodeslot=0x122C4, + }, + [0x122C5]={ + category="lo", + description="CUNEIFORM SIGN SHID TIMES IM", + direction="l", + linebreak="al", + unicodeslot=0x122C5, + }, + [0x122C6]={ + category="lo", + description="CUNEIFORM SIGN SHIM", + direction="l", + linebreak="al", + unicodeslot=0x122C6, + }, + [0x122C7]={ + category="lo", + description="CUNEIFORM SIGN SHIM TIMES A", + direction="l", + linebreak="al", + unicodeslot=0x122C7, + }, + [0x122C8]={ + category="lo", + description="CUNEIFORM SIGN SHIM TIMES BAL", + direction="l", + linebreak="al", + unicodeslot=0x122C8, + }, + [0x122C9]={ + category="lo", + description="CUNEIFORM SIGN SHIM TIMES BULUG", + direction="l", + linebreak="al", + unicodeslot=0x122C9, + }, + [0x122CA]={ + category="lo", + description="CUNEIFORM SIGN SHIM TIMES DIN", + direction="l", + linebreak="al", + unicodeslot=0x122CA, + }, + [0x122CB]={ + category="lo", + description="CUNEIFORM SIGN SHIM TIMES GAR", + direction="l", + linebreak="al", + unicodeslot=0x122CB, + }, + [0x122CC]={ + category="lo", + description="CUNEIFORM SIGN SHIM TIMES IGI", + direction="l", + linebreak="al", + unicodeslot=0x122CC, + }, + [0x122CD]={ + category="lo", + description="CUNEIFORM SIGN SHIM TIMES IGI GUNU", + direction="l", + linebreak="al", + unicodeslot=0x122CD, + }, + [0x122CE]={ + category="lo", + description="CUNEIFORM SIGN SHIM TIMES KUSHU0x0002", + direction="l", + linebreak="al", + unicodeslot=0x122CE, + }, + [0x122CF]={ + category="lo", + description="CUNEIFORM SIGN SHIM TIMES LUL", + direction="l", + linebreak="al", + unicodeslot=0x122CF, + }, + [0x122D0]={ + category="lo", + description="CUNEIFORM SIGN SHIM TIMES MUG", + direction="l", + linebreak="al", + unicodeslot=0x122D0, + }, + [0x122D1]={ + category="lo", + description="CUNEIFORM SIGN SHIM TIMES SAL", + direction="l", + linebreak="al", + unicodeslot=0x122D1, + }, + [0x122D2]={ + category="lo", + description="CUNEIFORM SIGN SHINIG", + direction="l", + linebreak="al", + unicodeslot=0x122D2, + }, + [0x122D3]={ + category="lo", + description="CUNEIFORM SIGN SHIR", + direction="l", + linebreak="al", + unicodeslot=0x122D3, + }, + [0x122D4]={ + category="lo", + description="CUNEIFORM SIGN SHIR TENU", + direction="l", + linebreak="al", + unicodeslot=0x122D4, + }, + [0x122D5]={ + category="lo", + description="CUNEIFORM SIGN SHIR OVER SHIR BUR OVER BUR", + direction="l", + linebreak="al", + unicodeslot=0x122D5, + }, + [0x122D6]={ + category="lo", + description="CUNEIFORM SIGN SHITA", + direction="l", + linebreak="al", + unicodeslot=0x122D6, + }, + [0x122D7]={ + category="lo", + description="CUNEIFORM SIGN SHU", + direction="l", + linebreak="al", + unicodeslot=0x122D7, + }, + [0x122D8]={ + category="lo", + description="CUNEIFORM SIGN SHU OVER INVERTED SHU", + direction="l", + linebreak="al", + unicodeslot=0x122D8, + }, + [0x122D9]={ + category="lo", + description="CUNEIFORM SIGN SHU0x0002", + direction="l", + linebreak="al", + unicodeslot=0x122D9, + }, + [0x122DA]={ + category="lo", + description="CUNEIFORM SIGN SHUBUR", + direction="l", + linebreak="al", + unicodeslot=0x122DA, + }, + [0x122DB]={ + category="lo", + description="CUNEIFORM SIGN SI", + direction="l", + linebreak="al", + unicodeslot=0x122DB, + }, + [0x122DC]={ + category="lo", + description="CUNEIFORM SIGN SI GUNU", + direction="l", + linebreak="al", + unicodeslot=0x122DC, + }, + [0x122DD]={ + category="lo", + description="CUNEIFORM SIGN SIG", + direction="l", + linebreak="al", + unicodeslot=0x122DD, + }, + [0x122DE]={ + category="lo", + description="CUNEIFORM SIGN SIG0x0004", + direction="l", + linebreak="al", + unicodeslot=0x122DE, + }, + [0x122DF]={ + category="lo", + description="CUNEIFORM SIGN SIG0x0004 OVER SIG0x0004 SHU0x0002", + direction="l", + linebreak="al", + unicodeslot=0x122DF, + }, + [0x122E0]={ + category="lo", + description="CUNEIFORM SIGN SIK0x0002", + direction="l", + linebreak="al", + unicodeslot=0x122E0, + }, + [0x122E1]={ + category="lo", + description="CUNEIFORM SIGN SILA0x0003", + direction="l", + linebreak="al", + unicodeslot=0x122E1, + }, + [0x122E2]={ + category="lo", + description="CUNEIFORM SIGN SU", + direction="l", + linebreak="al", + unicodeslot=0x122E2, + }, + [0x122E3]={ + category="lo", + description="CUNEIFORM SIGN SU OVER SU", + direction="l", + linebreak="al", + unicodeslot=0x122E3, + }, + [0x122E4]={ + category="lo", + description="CUNEIFORM SIGN SUD", + direction="l", + linebreak="al", + unicodeslot=0x122E4, + }, + [0x122E5]={ + category="lo", + description="CUNEIFORM SIGN SUD0x0002", + direction="l", + linebreak="al", + unicodeslot=0x122E5, + }, + [0x122E6]={ + category="lo", + description="CUNEIFORM SIGN SUHUR", + direction="l", + linebreak="al", + unicodeslot=0x122E6, + }, + [0x122E7]={ + category="lo", + description="CUNEIFORM SIGN SUM", + direction="l", + linebreak="al", + unicodeslot=0x122E7, + }, + [0x122E8]={ + category="lo", + description="CUNEIFORM SIGN SUMASH", + direction="l", + linebreak="al", + unicodeslot=0x122E8, + }, + [0x122E9]={ + category="lo", + description="CUNEIFORM SIGN SUR", + direction="l", + linebreak="al", + unicodeslot=0x122E9, + }, + [0x122EA]={ + category="lo", + description="CUNEIFORM SIGN SUR0x0009", + direction="l", + linebreak="al", + unicodeslot=0x122EA, + }, + [0x122EB]={ + category="lo", + description="CUNEIFORM SIGN TA", + direction="l", + linebreak="al", + unicodeslot=0x122EB, + }, + [0x122EC]={ + category="lo", + description="CUNEIFORM SIGN TA ASTERISK", + direction="l", + linebreak="al", + unicodeslot=0x122EC, + }, + [0x122ED]={ + category="lo", + description="CUNEIFORM SIGN TA TIMES HI", + direction="l", + linebreak="al", + unicodeslot=0x122ED, + }, + [0x122EE]={ + category="lo", + description="CUNEIFORM SIGN TA TIMES MI", + direction="l", + linebreak="al", + unicodeslot=0x122EE, + }, + [0x122EF]={ + category="lo", + description="CUNEIFORM SIGN TA GUNU", + direction="l", + linebreak="al", + unicodeslot=0x122EF, + }, + [0x122F0]={ + category="lo", + description="CUNEIFORM SIGN TAB", + direction="l", + linebreak="al", + unicodeslot=0x122F0, + }, + [0x122F1]={ + category="lo", + description="CUNEIFORM SIGN TAB OVER TAB NI OVER NI DISH OVER DISH", + direction="l", + linebreak="al", + unicodeslot=0x122F1, + }, + [0x122F2]={ + category="lo", + description="CUNEIFORM SIGN TAB SQUARED", + direction="l", + linebreak="al", + unicodeslot=0x122F2, + }, + [0x122F3]={ + category="lo", + description="CUNEIFORM SIGN TAG", + direction="l", + linebreak="al", + unicodeslot=0x122F3, + }, + [0x122F4]={ + category="lo", + description="CUNEIFORM SIGN TAG TIMES BI", + direction="l", + linebreak="al", + unicodeslot=0x122F4, + }, + [0x122F5]={ + category="lo", + description="CUNEIFORM SIGN TAG TIMES GUD", + direction="l", + linebreak="al", + unicodeslot=0x122F5, + }, + [0x122F6]={ + category="lo", + description="CUNEIFORM SIGN TAG TIMES SHE", + direction="l", + linebreak="al", + unicodeslot=0x122F6, + }, + [0x122F7]={ + category="lo", + description="CUNEIFORM SIGN TAG TIMES SHU", + direction="l", + linebreak="al", + unicodeslot=0x122F7, + }, + [0x122F8]={ + category="lo", + description="CUNEIFORM SIGN TAG TIMES TUG0x0002", + direction="l", + linebreak="al", + unicodeslot=0x122F8, + }, + [0x122F9]={ + category="lo", + description="CUNEIFORM SIGN TAG TIMES UD", + direction="l", + linebreak="al", + unicodeslot=0x122F9, + }, + [0x122FA]={ + category="lo", + description="CUNEIFORM SIGN TAK0x0004", + direction="l", + linebreak="al", + unicodeslot=0x122FA, + }, + [0x122FB]={ + category="lo", + description="CUNEIFORM SIGN TAR", + direction="l", + linebreak="al", + unicodeslot=0x122FB, + }, + [0x122FC]={ + category="lo", + description="CUNEIFORM SIGN TE", + direction="l", + linebreak="al", + unicodeslot=0x122FC, + }, + [0x122FD]={ + category="lo", + description="CUNEIFORM SIGN TE GUNU", + direction="l", + linebreak="al", + unicodeslot=0x122FD, + }, + [0x122FE]={ + category="lo", + description="CUNEIFORM SIGN TI", + direction="l", + linebreak="al", + unicodeslot=0x122FE, + }, + [0x122FF]={ + category="lo", + description="CUNEIFORM SIGN TI TENU", + direction="l", + linebreak="al", + unicodeslot=0x122FF, + }, + [0x12300]={ + category="lo", + description="CUNEIFORM SIGN TIL", + direction="l", + linebreak="al", + unicodeslot=0x12300, + }, + [0x12301]={ + category="lo", + description="CUNEIFORM SIGN TIR", + direction="l", + linebreak="al", + unicodeslot=0x12301, + }, + [0x12302]={ + category="lo", + description="CUNEIFORM SIGN TIR TIMES TAK0x0004", + direction="l", + linebreak="al", + unicodeslot=0x12302, + }, + [0x12303]={ + category="lo", + description="CUNEIFORM SIGN TIR OVER TIR", + direction="l", + linebreak="al", + unicodeslot=0x12303, + }, + [0x12304]={ + category="lo", + description="CUNEIFORM SIGN TIR OVER TIR GAD OVER GAD GAR OVER GAR", + direction="l", + linebreak="al", + unicodeslot=0x12304, + }, + [0x12305]={ + category="lo", + description="CUNEIFORM SIGN TU", + direction="l", + linebreak="al", + unicodeslot=0x12305, + }, + [0x12306]={ + category="lo", + description="CUNEIFORM SIGN TUG0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12306, + }, + [0x12307]={ + category="lo", + description="CUNEIFORM SIGN TUK", + direction="l", + linebreak="al", + unicodeslot=0x12307, + }, + [0x12308]={ + category="lo", + description="CUNEIFORM SIGN TUM", + direction="l", + linebreak="al", + unicodeslot=0x12308, + }, + [0x12309]={ + category="lo", + description="CUNEIFORM SIGN TUR", + direction="l", + linebreak="al", + unicodeslot=0x12309, + }, + [0x1230A]={ + category="lo", + description="CUNEIFORM SIGN TUR OVER TUR ZA OVER ZA", + direction="l", + linebreak="al", + unicodeslot=0x1230A, + }, + [0x1230B]={ + category="lo", + description="CUNEIFORM SIGN U", + direction="l", + linebreak="al", + unicodeslot=0x1230B, + }, + [0x1230C]={ + category="lo", + description="CUNEIFORM SIGN U GUD", + direction="l", + linebreak="al", + unicodeslot=0x1230C, + }, + [0x1230D]={ + category="lo", + description="CUNEIFORM SIGN U U U", + direction="l", + linebreak="al", + unicodeslot=0x1230D, + }, + [0x1230E]={ + category="lo", + description="CUNEIFORM SIGN U OVER U PA OVER PA GAR OVER GAR", + direction="l", + linebreak="al", + unicodeslot=0x1230E, + }, + [0x1230F]={ + category="lo", + description="CUNEIFORM SIGN U OVER U SUR OVER SUR", + direction="l", + linebreak="al", + unicodeslot=0x1230F, + }, + [0x12310]={ + category="lo", + description="CUNEIFORM SIGN U OVER U U REVERSED OVER U REVERSED", + direction="l", + linebreak="al", + unicodeslot=0x12310, + }, + [0x12311]={ + category="lo", + description="CUNEIFORM SIGN U0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12311, + }, + [0x12312]={ + category="lo", + description="CUNEIFORM SIGN UB", + direction="l", + linebreak="al", + unicodeslot=0x12312, + }, + [0x12313]={ + category="lo", + description="CUNEIFORM SIGN UD", + direction="l", + linebreak="al", + unicodeslot=0x12313, + }, + [0x12314]={ + category="lo", + description="CUNEIFORM SIGN UD KUSHU0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12314, + }, + [0x12315]={ + category="lo", + description="CUNEIFORM SIGN UD TIMES BAD", + direction="l", + linebreak="al", + unicodeslot=0x12315, + }, + [0x12316]={ + category="lo", + description="CUNEIFORM SIGN UD TIMES MI", + direction="l", + linebreak="al", + unicodeslot=0x12316, + }, + [0x12317]={ + category="lo", + description="CUNEIFORM SIGN UD TIMES U PLUS U PLUS U", + direction="l", + linebreak="al", + unicodeslot=0x12317, + }, + [0x12318]={ + category="lo", + description="CUNEIFORM SIGN UD TIMES U PLUS U PLUS U GUNU", + direction="l", + linebreak="al", + unicodeslot=0x12318, + }, + [0x12319]={ + category="lo", + description="CUNEIFORM SIGN UD GUNU", + direction="l", + linebreak="al", + unicodeslot=0x12319, + }, + [0x1231A]={ + category="lo", + description="CUNEIFORM SIGN UD SHESHIG", + direction="l", + linebreak="al", + unicodeslot=0x1231A, + }, + [0x1231B]={ + category="lo", + description="CUNEIFORM SIGN UD SHESHIG TIMES BAD", + direction="l", + linebreak="al", + unicodeslot=0x1231B, + }, + [0x1231C]={ + category="lo", + description="CUNEIFORM SIGN UDUG", + direction="l", + linebreak="al", + unicodeslot=0x1231C, + }, + [0x1231D]={ + category="lo", + description="CUNEIFORM SIGN UM", + direction="l", + linebreak="al", + unicodeslot=0x1231D, + }, + [0x1231E]={ + category="lo", + description="CUNEIFORM SIGN UM TIMES LAGAB", + direction="l", + linebreak="al", + unicodeslot=0x1231E, + }, + [0x1231F]={ + category="lo", + description="CUNEIFORM SIGN UM TIMES ME PLUS DA", + direction="l", + linebreak="al", + unicodeslot=0x1231F, + }, + [0x12320]={ + category="lo", + description="CUNEIFORM SIGN UM TIMES SHA0x0003", + direction="l", + linebreak="al", + unicodeslot=0x12320, + }, + [0x12321]={ + category="lo", + description="CUNEIFORM SIGN UM TIMES U", + direction="l", + linebreak="al", + unicodeslot=0x12321, + }, + [0x12322]={ + category="lo", + description="CUNEIFORM SIGN UMBIN", + direction="l", + linebreak="al", + unicodeslot=0x12322, + }, + [0x12323]={ + category="lo", + description="CUNEIFORM SIGN UMUM", + direction="l", + linebreak="al", + unicodeslot=0x12323, + }, + [0x12324]={ + category="lo", + description="CUNEIFORM SIGN UMUM TIMES KASKAL", + direction="l", + linebreak="al", + unicodeslot=0x12324, + }, + [0x12325]={ + category="lo", + description="CUNEIFORM SIGN UMUM TIMES PA", + direction="l", + linebreak="al", + unicodeslot=0x12325, + }, + [0x12326]={ + category="lo", + description="CUNEIFORM SIGN UN", + direction="l", + linebreak="al", + unicodeslot=0x12326, + }, + [0x12327]={ + category="lo", + description="CUNEIFORM SIGN UN GUNU", + direction="l", + linebreak="al", + unicodeslot=0x12327, + }, + [0x12328]={ + category="lo", + description="CUNEIFORM SIGN UR", + direction="l", + linebreak="al", + unicodeslot=0x12328, + }, + [0x12329]={ + category="lo", + description="CUNEIFORM SIGN UR CROSSING UR", + direction="l", + linebreak="al", + unicodeslot=0x12329, + }, + [0x1232A]={ + category="lo", + description="CUNEIFORM SIGN UR SHESHIG", + direction="l", + linebreak="al", + unicodeslot=0x1232A, + }, + [0x1232B]={ + category="lo", + description="CUNEIFORM SIGN UR0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1232B, + }, + [0x1232C]={ + category="lo", + description="CUNEIFORM SIGN UR0x0002 TIMES A PLUS HA", + direction="l", + linebreak="al", + unicodeslot=0x1232C, + }, + [0x1232D]={ + category="lo", + description="CUNEIFORM SIGN UR0x0002 TIMES A PLUS NA", + direction="l", + linebreak="al", + unicodeslot=0x1232D, + }, + [0x1232E]={ + category="lo", + description="CUNEIFORM SIGN UR0x0002 TIMES AL", + direction="l", + linebreak="al", + unicodeslot=0x1232E, + }, + [0x1232F]={ + category="lo", + description="CUNEIFORM SIGN UR0x0002 TIMES HA", + direction="l", + linebreak="al", + unicodeslot=0x1232F, + }, + [0x12330]={ + category="lo", + description="CUNEIFORM SIGN UR0x0002 TIMES NUN", + direction="l", + linebreak="al", + unicodeslot=0x12330, + }, + [0x12331]={ + category="lo", + description="CUNEIFORM SIGN UR0x0002 TIMES U0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12331, + }, + [0x12332]={ + category="lo", + description="CUNEIFORM SIGN UR0x0002 TIMES U0x0002 PLUS ASH", + direction="l", + linebreak="al", + unicodeslot=0x12332, + }, + [0x12333]={ + category="lo", + description="CUNEIFORM SIGN UR0x0002 TIMES U0x0002 PLUS BI", + direction="l", + linebreak="al", + unicodeslot=0x12333, + }, + [0x12334]={ + category="lo", + description="CUNEIFORM SIGN UR0x0004", + direction="l", + linebreak="al", + unicodeslot=0x12334, + }, + [0x12335]={ + category="lo", + description="CUNEIFORM SIGN URI", + direction="l", + linebreak="al", + unicodeslot=0x12335, + }, + [0x12336]={ + category="lo", + description="CUNEIFORM SIGN URI0x0003", + direction="l", + linebreak="al", + unicodeslot=0x12336, + }, + [0x12337]={ + category="lo", + description="CUNEIFORM SIGN URU", + direction="l", + linebreak="al", + unicodeslot=0x12337, + }, + [0x12338]={ + category="lo", + description="CUNEIFORM SIGN URU TIMES A", + direction="l", + linebreak="al", + unicodeslot=0x12338, + }, + [0x12339]={ + category="lo", + description="CUNEIFORM SIGN URU TIMES ASHGAB", + direction="l", + linebreak="al", + unicodeslot=0x12339, + }, + [0x1233A]={ + category="lo", + description="CUNEIFORM SIGN URU TIMES BAR", + direction="l", + linebreak="al", + unicodeslot=0x1233A, + }, + [0x1233B]={ + category="lo", + description="CUNEIFORM SIGN URU TIMES DUN", + direction="l", + linebreak="al", + unicodeslot=0x1233B, + }, + [0x1233C]={ + category="lo", + description="CUNEIFORM SIGN URU TIMES GA", + direction="l", + linebreak="al", + unicodeslot=0x1233C, + }, + [0x1233D]={ + category="lo", + description="CUNEIFORM SIGN URU TIMES GAL", + direction="l", + linebreak="al", + unicodeslot=0x1233D, + }, + [0x1233E]={ + category="lo", + description="CUNEIFORM SIGN URU TIMES GAN0x0002 TENU", + direction="l", + linebreak="al", + unicodeslot=0x1233E, + }, + [0x1233F]={ + category="lo", + description="CUNEIFORM SIGN URU TIMES GAR", + direction="l", + linebreak="al", + unicodeslot=0x1233F, + }, + [0x12340]={ + category="lo", + description="CUNEIFORM SIGN URU TIMES GU", + direction="l", + linebreak="al", + unicodeslot=0x12340, + }, + [0x12341]={ + category="lo", + description="CUNEIFORM SIGN URU TIMES HA", + direction="l", + linebreak="al", + unicodeslot=0x12341, + }, + [0x12342]={ + category="lo", + description="CUNEIFORM SIGN URU TIMES IGI", + direction="l", + linebreak="al", + unicodeslot=0x12342, + }, + [0x12343]={ + category="lo", + description="CUNEIFORM SIGN URU TIMES IM", + direction="l", + linebreak="al", + unicodeslot=0x12343, + }, + [0x12344]={ + category="lo", + description="CUNEIFORM SIGN URU TIMES ISH", + direction="l", + linebreak="al", + unicodeslot=0x12344, + }, + [0x12345]={ + category="lo", + description="CUNEIFORM SIGN URU TIMES KI", + direction="l", + linebreak="al", + unicodeslot=0x12345, + }, + [0x12346]={ + category="lo", + description="CUNEIFORM SIGN URU TIMES LUM", + direction="l", + linebreak="al", + unicodeslot=0x12346, + }, + [0x12347]={ + category="lo", + description="CUNEIFORM SIGN URU TIMES MIN", + direction="l", + linebreak="al", + unicodeslot=0x12347, + }, + [0x12348]={ + category="lo", + description="CUNEIFORM SIGN URU TIMES PA", + direction="l", + linebreak="al", + unicodeslot=0x12348, + }, + [0x12349]={ + category="lo", + description="CUNEIFORM SIGN URU TIMES SHE", + direction="l", + linebreak="al", + unicodeslot=0x12349, + }, + [0x1234A]={ + category="lo", + description="CUNEIFORM SIGN URU TIMES SIG0x0004", + direction="l", + linebreak="al", + unicodeslot=0x1234A, + }, + [0x1234B]={ + category="lo", + description="CUNEIFORM SIGN URU TIMES TU", + direction="l", + linebreak="al", + unicodeslot=0x1234B, + }, + [0x1234C]={ + category="lo", + description="CUNEIFORM SIGN URU TIMES U PLUS GUD", + direction="l", + linebreak="al", + unicodeslot=0x1234C, + }, + [0x1234D]={ + category="lo", + description="CUNEIFORM SIGN URU TIMES UD", + direction="l", + linebreak="al", + unicodeslot=0x1234D, + }, + [0x1234E]={ + category="lo", + description="CUNEIFORM SIGN URU TIMES URUDA", + direction="l", + linebreak="al", + unicodeslot=0x1234E, + }, + [0x1234F]={ + category="lo", + description="CUNEIFORM SIGN URUDA", + direction="l", + linebreak="al", + unicodeslot=0x1234F, + }, + [0x12350]={ + category="lo", + description="CUNEIFORM SIGN URUDA TIMES U", + direction="l", + linebreak="al", + unicodeslot=0x12350, + }, + [0x12351]={ + category="lo", + description="CUNEIFORM SIGN USH", + direction="l", + linebreak="al", + unicodeslot=0x12351, + }, + [0x12352]={ + category="lo", + description="CUNEIFORM SIGN USH TIMES A", + direction="l", + linebreak="al", + unicodeslot=0x12352, + }, + [0x12353]={ + category="lo", + description="CUNEIFORM SIGN USH TIMES KU", + direction="l", + linebreak="al", + unicodeslot=0x12353, + }, + [0x12354]={ + category="lo", + description="CUNEIFORM SIGN USH TIMES KUR", + direction="l", + linebreak="al", + unicodeslot=0x12354, + }, + [0x12355]={ + category="lo", + description="CUNEIFORM SIGN USH TIMES TAK0x0004", + direction="l", + linebreak="al", + unicodeslot=0x12355, + }, + [0x12356]={ + category="lo", + description="CUNEIFORM SIGN USHX", + direction="l", + linebreak="al", + unicodeslot=0x12356, + }, + [0x12357]={ + category="lo", + description="CUNEIFORM SIGN USH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12357, + }, + [0x12358]={ + category="lo", + description="CUNEIFORM SIGN USHUMX", + direction="l", + linebreak="al", + unicodeslot=0x12358, + }, + [0x12359]={ + category="lo", + description="CUNEIFORM SIGN UTUKI", + direction="l", + linebreak="al", + unicodeslot=0x12359, + }, + [0x1235A]={ + category="lo", + description="CUNEIFORM SIGN UZ0x0003", + direction="l", + linebreak="al", + unicodeslot=0x1235A, + }, + [0x1235B]={ + category="lo", + description="CUNEIFORM SIGN UZ0x0003 TIMES KASKAL", + direction="l", + linebreak="al", + unicodeslot=0x1235B, + }, + [0x1235C]={ + category="lo", + description="CUNEIFORM SIGN UZU", + direction="l", + linebreak="al", + unicodeslot=0x1235C, + }, + [0x1235D]={ + category="lo", + description="CUNEIFORM SIGN ZA", + direction="l", + linebreak="al", + unicodeslot=0x1235D, + }, + [0x1235E]={ + category="lo", + description="CUNEIFORM SIGN ZA TENU", + direction="l", + linebreak="al", + unicodeslot=0x1235E, + }, + [0x1235F]={ + category="lo", + description="CUNEIFORM SIGN ZA SQUARED TIMES KUR", + direction="l", + linebreak="al", + unicodeslot=0x1235F, + }, + [0x12360]={ + category="lo", + description="CUNEIFORM SIGN ZAG", + direction="l", + linebreak="al", + unicodeslot=0x12360, + }, + [0x12361]={ + category="lo", + description="CUNEIFORM SIGN ZAMX", + direction="l", + linebreak="al", + unicodeslot=0x12361, + }, + [0x12362]={ + category="lo", + description="CUNEIFORM SIGN ZE0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12362, + }, + [0x12363]={ + category="lo", + description="CUNEIFORM SIGN ZI", + direction="l", + linebreak="al", + unicodeslot=0x12363, + }, + [0x12364]={ + category="lo", + description="CUNEIFORM SIGN ZI OVER ZI", + direction="l", + linebreak="al", + unicodeslot=0x12364, + }, + [0x12365]={ + category="lo", + description="CUNEIFORM SIGN ZI0x0003", + direction="l", + linebreak="al", + unicodeslot=0x12365, + }, + [0x12366]={ + category="lo", + description="CUNEIFORM SIGN ZIB", + direction="l", + linebreak="al", + unicodeslot=0x12366, + }, + [0x12367]={ + category="lo", + description="CUNEIFORM SIGN ZIB KABA TENU", + direction="l", + linebreak="al", + unicodeslot=0x12367, + }, + [0x12368]={ + category="lo", + description="CUNEIFORM SIGN ZIG", + direction="l", + linebreak="al", + unicodeslot=0x12368, + }, + [0x12369]={ + category="lo", + description="CUNEIFORM SIGN ZIZ0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12369, + }, + [0x1236A]={ + category="lo", + description="CUNEIFORM SIGN ZU", + direction="l", + linebreak="al", + unicodeslot=0x1236A, + }, + [0x1236B]={ + category="lo", + description="CUNEIFORM SIGN ZU0x0005", + direction="l", + linebreak="al", + unicodeslot=0x1236B, + }, + [0x1236C]={ + category="lo", + description="CUNEIFORM SIGN ZU0x0005 TIMES A", + direction="l", + linebreak="al", + unicodeslot=0x1236C, + }, + [0x1236D]={ + category="lo", + description="CUNEIFORM SIGN ZUBUR", + direction="l", + linebreak="al", + unicodeslot=0x1236D, + }, + [0x1236E]={ + category="lo", + description="CUNEIFORM SIGN ZUM", + direction="l", + linebreak="al", + unicodeslot=0x1236E, + }, + [0x12400]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN TWO ASH", + direction="l", + linebreak="al", + unicodeslot=0x12400, + }, + [0x12401]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN THREE ASH", + direction="l", + linebreak="al", + unicodeslot=0x12401, + }, + [0x12402]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FOUR ASH", + direction="l", + linebreak="al", + unicodeslot=0x12402, + }, + [0x12403]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FIVE ASH", + direction="l", + linebreak="al", + unicodeslot=0x12403, + }, + [0x12404]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN SIX ASH", + direction="l", + linebreak="al", + unicodeslot=0x12404, + }, + [0x12405]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN SEVEN ASH", + direction="l", + linebreak="al", + unicodeslot=0x12405, + }, + [0x12406]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN EIGHT ASH", + direction="l", + linebreak="al", + unicodeslot=0x12406, + }, + [0x12407]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN NINE ASH", + direction="l", + linebreak="al", + unicodeslot=0x12407, + }, + [0x12408]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN THREE DISH", + direction="l", + linebreak="al", + unicodeslot=0x12408, + }, + [0x12409]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FOUR DISH", + direction="l", + linebreak="al", + unicodeslot=0x12409, + }, + [0x1240A]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FIVE DISH", + direction="l", + linebreak="al", + unicodeslot=0x1240A, + }, + [0x1240B]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN SIX DISH", + direction="l", + linebreak="al", + unicodeslot=0x1240B, + }, + [0x1240C]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN SEVEN DISH", + direction="l", + linebreak="al", + unicodeslot=0x1240C, + }, + [0x1240D]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN EIGHT DISH", + direction="l", + linebreak="al", + unicodeslot=0x1240D, + }, + [0x1240E]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN NINE DISH", + direction="l", + linebreak="al", + unicodeslot=0x1240E, + }, + [0x1240F]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FOUR U", + direction="l", + linebreak="al", + unicodeslot=0x1240F, + }, + [0x12410]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FIVE U", + direction="l", + linebreak="al", + unicodeslot=0x12410, + }, + [0x12411]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN SIX U", + direction="l", + linebreak="al", + unicodeslot=0x12411, + }, + [0x12412]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN SEVEN U", + direction="l", + linebreak="al", + unicodeslot=0x12412, + }, + [0x12413]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN EIGHT U", + direction="l", + linebreak="al", + unicodeslot=0x12413, + }, + [0x12414]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN NINE U", + direction="l", + linebreak="al", + unicodeslot=0x12414, + }, + [0x12415]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN ONE GESH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12415, + }, + [0x12416]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN TWO GESH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12416, + }, + [0x12417]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN THREE GESH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12417, + }, + [0x12418]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FOUR GESH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12418, + }, + [0x12419]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FIVE GESH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12419, + }, + [0x1241A]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN SIX GESH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1241A, + }, + [0x1241B]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN SEVEN GESH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1241B, + }, + [0x1241C]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN EIGHT GESH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1241C, + }, + [0x1241D]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN NINE GESH0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1241D, + }, + [0x1241E]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN ONE GESHU", + direction="l", + linebreak="al", + unicodeslot=0x1241E, + }, + [0x1241F]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN TWO GESHU", + direction="l", + linebreak="al", + unicodeslot=0x1241F, + }, + [0x12420]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN THREE GESHU", + direction="l", + linebreak="al", + unicodeslot=0x12420, + }, + [0x12421]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FOUR GESHU", + direction="l", + linebreak="al", + unicodeslot=0x12421, + }, + [0x12422]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FIVE GESHU", + direction="l", + linebreak="al", + unicodeslot=0x12422, + }, + [0x12423]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN TWO SHAR0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12423, + }, + [0x12424]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN THREE SHAR0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12424, + }, + [0x12425]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN THREE SHAR0x0002 VARIANT FORM", + direction="l", + linebreak="al", + unicodeslot=0x12425, + }, + [0x12426]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FOUR SHAR0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12426, + }, + [0x12427]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FIVE SHAR0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12427, + }, + [0x12428]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN SIX SHAR0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12428, + }, + [0x12429]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN SEVEN SHAR0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12429, + }, + [0x1242A]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN EIGHT SHAR0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1242A, + }, + [0x1242B]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN NINE SHAR0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1242B, + }, + [0x1242C]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN ONE SHARU", + direction="l", + linebreak="al", + unicodeslot=0x1242C, + }, + [0x1242D]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN TWO SHARU", + direction="l", + linebreak="al", + unicodeslot=0x1242D, + }, + [0x1242E]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN THREE SHARU", + direction="l", + linebreak="al", + unicodeslot=0x1242E, + }, + [0x1242F]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN THREE SHARU VARIANT FORM", + direction="l", + linebreak="al", + unicodeslot=0x1242F, + }, + [0x12430]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FOUR SHARU", + direction="l", + linebreak="al", + unicodeslot=0x12430, + }, + [0x12431]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FIVE SHARU", + direction="l", + linebreak="al", + unicodeslot=0x12431, + }, + [0x12432]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN SHAR0x0002 TIMES GAL PLUS DISH", + direction="l", + linebreak="al", + unicodeslot=0x12432, + }, + [0x12433]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN SHAR0x0002 TIMES GAL PLUS MIN", + direction="l", + linebreak="al", + unicodeslot=0x12433, + }, + [0x12434]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN ONE BURU", + direction="l", + linebreak="al", + unicodeslot=0x12434, + }, + [0x12435]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN TWO BURU", + direction="l", + linebreak="al", + unicodeslot=0x12435, + }, + [0x12436]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN THREE BURU", + direction="l", + linebreak="al", + unicodeslot=0x12436, + }, + [0x12437]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN THREE BURU VARIANT FORM", + direction="l", + linebreak="al", + unicodeslot=0x12437, + }, + [0x12438]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FOUR BURU", + direction="l", + linebreak="al", + unicodeslot=0x12438, + }, + [0x12439]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FIVE BURU", + direction="l", + linebreak="al", + unicodeslot=0x12439, + }, + [0x1243A]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN THREE VARIANT FORM ESH0x0010", + direction="l", + linebreak="al", + unicodeslot=0x1243A, + }, + [0x1243B]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN THREE VARIANT FORM ESH0x0015", + direction="l", + linebreak="al", + unicodeslot=0x1243B, + }, + [0x1243C]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU", + direction="l", + linebreak="al", + unicodeslot=0x1243C, + }, + [0x1243D]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU0x0004", + direction="l", + linebreak="al", + unicodeslot=0x1243D, + }, + [0x1243E]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU A", + direction="l", + linebreak="al", + unicodeslot=0x1243E, + }, + [0x1243F]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU B", + direction="l", + linebreak="al", + unicodeslot=0x1243F, + }, + [0x12440]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN SIX VARIANT FORM ASH0x0009", + direction="l", + linebreak="al", + unicodeslot=0x12440, + }, + [0x12441]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN0x0003", + direction="l", + linebreak="al", + unicodeslot=0x12441, + }, + [0x12442]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN A", + direction="l", + linebreak="al", + unicodeslot=0x12442, + }, + [0x12443]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN B", + direction="l", + linebreak="al", + unicodeslot=0x12443, + }, + [0x12444]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN EIGHT VARIANT FORM USSU", + direction="l", + linebreak="al", + unicodeslot=0x12444, + }, + [0x12445]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN EIGHT VARIANT FORM USSU0x0003", + direction="l", + linebreak="al", + unicodeslot=0x12445, + }, + [0x12446]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU", + direction="l", + linebreak="al", + unicodeslot=0x12446, + }, + [0x12447]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU0x0003", + direction="l", + linebreak="al", + unicodeslot=0x12447, + }, + [0x12448]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU0x0004", + direction="l", + linebreak="al", + unicodeslot=0x12448, + }, + [0x12449]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU A", + direction="l", + linebreak="al", + unicodeslot=0x12449, + }, + [0x1244A]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN TWO ASH TENU", + direction="l", + linebreak="al", + unicodeslot=0x1244A, + }, + [0x1244B]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN THREE ASH TENU", + direction="l", + linebreak="al", + unicodeslot=0x1244B, + }, + [0x1244C]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FOUR ASH TENU", + direction="l", + linebreak="al", + unicodeslot=0x1244C, + }, + [0x1244D]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FIVE ASH TENU", + direction="l", + linebreak="al", + unicodeslot=0x1244D, + }, + [0x1244E]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN SIX ASH TENU", + direction="l", + linebreak="al", + unicodeslot=0x1244E, + }, + [0x1244F]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN ONE BAN0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1244F, + }, + [0x12450]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN TWO BAN0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12450, + }, + [0x12451]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN THREE BAN0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12451, + }, + [0x12452]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FOUR BAN0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12452, + }, + [0x12453]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FOUR BAN0x0002 VARIANT FORM", + direction="l", + linebreak="al", + unicodeslot=0x12453, + }, + [0x12454]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FIVE BAN0x0002", + direction="l", + linebreak="al", + unicodeslot=0x12454, + }, + [0x12455]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FIVE BAN0x0002 VARIANT FORM", + direction="l", + linebreak="al", + unicodeslot=0x12455, + }, + [0x12456]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN NIGIDAMIN", + direction="l", + linebreak="al", + unicodeslot=0x12456, + }, + [0x12457]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN NIGIDAESH", + direction="l", + linebreak="al", + unicodeslot=0x12457, + }, + [0x12458]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN ONE ESHE0x0003", + direction="l", + linebreak="al", + unicodeslot=0x12458, + }, + [0x12459]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN TWO ESHE0x0003", + direction="l", + linebreak="al", + unicodeslot=0x12459, + }, + [0x1245A]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN ONE THIRD DISH", + direction="l", + linebreak="al", + unicodeslot=0x1245A, + }, + [0x1245B]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN TWO THIRDS DISH", + direction="l", + linebreak="al", + unicodeslot=0x1245B, + }, + [0x1245C]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN FIVE SIXTHS DISH", + direction="l", + linebreak="al", + unicodeslot=0x1245C, + }, + [0x1245D]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN ONE THIRD VARIANT FORM A", + direction="l", + linebreak="al", + unicodeslot=0x1245D, + }, + [0x1245E]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN TWO THIRDS VARIANT FORM A", + direction="l", + linebreak="al", + unicodeslot=0x1245E, + }, + [0x1245F]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN ONE EIGHTH ASH", + direction="l", + linebreak="al", + unicodeslot=0x1245F, + }, + [0x12460]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN ONE QUARTER ASH", + direction="l", + linebreak="al", + unicodeslot=0x12460, + }, + [0x12461]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE SIXTH", + direction="l", + linebreak="al", + unicodeslot=0x12461, + }, + [0x12462]={ + category="nl", + description="CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE QUARTER", + direction="l", + linebreak="al", + unicodeslot=0x12462, + }, + [0x12470]={ + category="po", + description="CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER", + direction="l", + linebreak="ba", + unicodeslot=0x12470, + }, + [0x12471]={ + category="po", + description="CUNEIFORM PUNCTUATION SIGN VERTICAL COLON", + direction="l", + linebreak="ba", + unicodeslot=0x12471, + }, + [0x12472]={ + category="po", + description="CUNEIFORM PUNCTUATION SIGN DIAGONAL COLON", + direction="l", + linebreak="ba", + unicodeslot=0x12472, + }, + [0x12473]={ + category="po", + description="CUNEIFORM PUNCTUATION SIGN DIAGONAL TRICOLON", + direction="l", + linebreak="ba", + unicodeslot=0x12473, + }, + [0x1D000]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL PSILI", + direction="l", + linebreak="al", + unicodeslot=0x1D000, + }, + [0x1D001]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL DASEIA", + direction="l", + linebreak="al", + unicodeslot=0x1D001, + }, + [0x1D002]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL PERISPOMENI", + direction="l", + linebreak="al", + unicodeslot=0x1D002, + }, + [0x1D003]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL OXEIA EKFONITIKON", + direction="l", + linebreak="al", + unicodeslot=0x1D003, + }, + [0x1D004]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL OXEIA DIPLI", + direction="l", + linebreak="al", + unicodeslot=0x1D004, + }, + [0x1D005]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL VAREIA EKFONITIKON", + direction="l", + linebreak="al", + unicodeslot=0x1D005, + }, + [0x1D006]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL VAREIA DIPLI", + direction="l", + linebreak="al", + unicodeslot=0x1D006, + }, + [0x1D007]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KATHISTI", + direction="l", + linebreak="al", + unicodeslot=0x1D007, + }, + [0x1D008]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL SYRMATIKI", + direction="l", + linebreak="al", + unicodeslot=0x1D008, + }, + [0x1D009]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL PARAKLITIKI", + direction="l", + linebreak="al", + unicodeslot=0x1D009, + }, + [0x1D00A]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL YPOKRISIS", + direction="l", + linebreak="al", + unicodeslot=0x1D00A, + }, + [0x1D00B]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL YPOKRISIS DIPLI", + direction="l", + linebreak="al", + unicodeslot=0x1D00B, + }, + [0x1D00C]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KREMASTI", + direction="l", + linebreak="al", + unicodeslot=0x1D00C, + }, + [0x1D00D]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL APESO EKFONITIKON", + direction="l", + linebreak="al", + unicodeslot=0x1D00D, + }, + [0x1D00E]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL EXO EKFONITIKON", + direction="l", + linebreak="al", + unicodeslot=0x1D00E, + }, + [0x1D00F]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL TELEIA", + direction="l", + linebreak="al", + unicodeslot=0x1D00F, + }, + [0x1D010]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KENTIMATA", + direction="l", + linebreak="al", + unicodeslot=0x1D010, + }, + [0x1D011]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL APOSTROFOS", + direction="l", + linebreak="al", + unicodeslot=0x1D011, + }, + [0x1D012]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL APOSTROFOS DIPLI", + direction="l", + linebreak="al", + unicodeslot=0x1D012, + }, + [0x1D013]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL SYNEVMA", + direction="l", + linebreak="al", + unicodeslot=0x1D013, + }, + [0x1D014]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL THITA", + direction="l", + linebreak="al", + unicodeslot=0x1D014, + }, + [0x1D015]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL OLIGON ARCHAION", + direction="l", + linebreak="al", + unicodeslot=0x1D015, + }, + [0x1D016]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL GORGON ARCHAION", + direction="l", + linebreak="al", + unicodeslot=0x1D016, + }, + [0x1D017]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL PSILON", + direction="l", + linebreak="al", + unicodeslot=0x1D017, + }, + [0x1D018]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL CHAMILON", + direction="l", + linebreak="al", + unicodeslot=0x1D018, + }, + [0x1D019]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL VATHY", + direction="l", + linebreak="al", + unicodeslot=0x1D019, + }, + [0x1D01A]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL ISON ARCHAION", + direction="l", + linebreak="al", + unicodeslot=0x1D01A, + }, + [0x1D01B]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KENTIMA ARCHAION", + direction="l", + linebreak="al", + unicodeslot=0x1D01B, + }, + [0x1D01C]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KENTIMATA ARCHAION", + direction="l", + linebreak="al", + unicodeslot=0x1D01C, + }, + [0x1D01D]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL SAXIMATA", + direction="l", + linebreak="al", + unicodeslot=0x1D01D, + }, + [0x1D01E]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL PARICHON", + direction="l", + linebreak="al", + unicodeslot=0x1D01E, + }, + [0x1D01F]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL STAVROS APODEXIA", + direction="l", + linebreak="al", + unicodeslot=0x1D01F, + }, + [0x1D020]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL OXEIAI ARCHAION", + direction="l", + linebreak="al", + unicodeslot=0x1D020, + }, + [0x1D021]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL VAREIAI ARCHAION", + direction="l", + linebreak="al", + unicodeslot=0x1D021, + }, + [0x1D022]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL APODERMA ARCHAION", + direction="l", + linebreak="al", + unicodeslot=0x1D022, + }, + [0x1D023]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL APOTHEMA", + direction="l", + linebreak="al", + unicodeslot=0x1D023, + }, + [0x1D024]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KLASMA", + direction="l", + linebreak="al", + unicodeslot=0x1D024, + }, + [0x1D025]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL REVMA", + direction="l", + linebreak="al", + unicodeslot=0x1D025, + }, + [0x1D026]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL PIASMA ARCHAION", + direction="l", + linebreak="al", + unicodeslot=0x1D026, + }, + [0x1D027]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL TINAGMA", + direction="l", + linebreak="al", + unicodeslot=0x1D027, + }, + [0x1D028]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL ANATRICHISMA", + direction="l", + linebreak="al", + unicodeslot=0x1D028, + }, + [0x1D029]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL SEISMA", + direction="l", + linebreak="al", + unicodeslot=0x1D029, + }, + [0x1D02A]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL SYNAGMA ARCHAION", + direction="l", + linebreak="al", + unicodeslot=0x1D02A, + }, + [0x1D02B]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL SYNAGMA META STAVROU", + direction="l", + linebreak="al", + unicodeslot=0x1D02B, + }, + [0x1D02C]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL OYRANISMA ARCHAION", + direction="l", + linebreak="al", + unicodeslot=0x1D02C, + }, + [0x1D02D]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL THEMA", + direction="l", + linebreak="al", + unicodeslot=0x1D02D, + }, + [0x1D02E]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL LEMOI", + direction="l", + linebreak="al", + unicodeslot=0x1D02E, + }, + [0x1D02F]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL DYO", + direction="l", + linebreak="al", + unicodeslot=0x1D02F, + }, + [0x1D030]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL TRIA", + direction="l", + linebreak="al", + unicodeslot=0x1D030, + }, + [0x1D031]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL TESSERA", + direction="l", + linebreak="al", + unicodeslot=0x1D031, + }, + [0x1D032]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KRATIMATA", + direction="l", + linebreak="al", + unicodeslot=0x1D032, + }, + [0x1D033]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL APESO EXO NEO", + direction="l", + linebreak="al", + unicodeslot=0x1D033, + }, + [0x1D034]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION", + direction="l", + linebreak="al", + unicodeslot=0x1D034, + }, + [0x1D035]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL IMIFTHORA", + direction="l", + linebreak="al", + unicodeslot=0x1D035, + }, + [0x1D036]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL TROMIKON ARCHAION", + direction="l", + linebreak="al", + unicodeslot=0x1D036, + }, + [0x1D037]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KATAVA TROMIKON", + direction="l", + linebreak="al", + unicodeslot=0x1D037, + }, + [0x1D038]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL PELASTON", + direction="l", + linebreak="al", + unicodeslot=0x1D038, + }, + [0x1D039]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL PSIFISTON", + direction="l", + linebreak="al", + unicodeslot=0x1D039, + }, + [0x1D03A]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KONTEVMA", + direction="l", + linebreak="al", + unicodeslot=0x1D03A, + }, + [0x1D03B]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL CHOREVMA ARCHAION", + direction="l", + linebreak="al", + unicodeslot=0x1D03B, + }, + [0x1D03C]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL RAPISMA", + direction="l", + linebreak="al", + unicodeslot=0x1D03C, + }, + [0x1D03D]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL PARAKALESMA ARCHAION", + direction="l", + linebreak="al", + unicodeslot=0x1D03D, + }, + [0x1D03E]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL PARAKLITIKI ARCHAION", + direction="l", + linebreak="al", + unicodeslot=0x1D03E, + }, + [0x1D03F]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL ICHADIN", + direction="l", + linebreak="al", + unicodeslot=0x1D03F, + }, + [0x1D040]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL NANA", + direction="l", + linebreak="al", + unicodeslot=0x1D040, + }, + [0x1D041]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL PETASMA", + direction="l", + linebreak="al", + unicodeslot=0x1D041, + }, + [0x1D042]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KONTEVMA ALLO", + direction="l", + linebreak="al", + unicodeslot=0x1D042, + }, + [0x1D043]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL TROMIKON ALLO", + direction="l", + linebreak="al", + unicodeslot=0x1D043, + }, + [0x1D044]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL STRAGGISMATA", + direction="l", + linebreak="al", + unicodeslot=0x1D044, + }, + [0x1D045]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL GRONTHISMATA", + direction="l", + linebreak="al", + unicodeslot=0x1D045, + }, + [0x1D046]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL ISON NEO", + direction="l", + linebreak="al", + unicodeslot=0x1D046, + }, + [0x1D047]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL OLIGON NEO", + direction="l", + linebreak="al", + unicodeslot=0x1D047, + }, + [0x1D048]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL OXEIA NEO", + direction="l", + linebreak="al", + unicodeslot=0x1D048, + }, + [0x1D049]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL PETASTI", + direction="l", + linebreak="al", + unicodeslot=0x1D049, + }, + [0x1D04A]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KOUFISMA", + direction="l", + linebreak="al", + unicodeslot=0x1D04A, + }, + [0x1D04B]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL PETASTOKOUFISMA", + direction="l", + linebreak="al", + unicodeslot=0x1D04B, + }, + [0x1D04C]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KRATIMOKOUFISMA", + direction="l", + linebreak="al", + unicodeslot=0x1D04C, + }, + [0x1D04D]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL PELASTON NEO", + direction="l", + linebreak="al", + unicodeslot=0x1D04D, + }, + [0x1D04E]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KENTIMATA NEO ANO", + direction="l", + linebreak="al", + unicodeslot=0x1D04E, + }, + [0x1D04F]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KENTIMA NEO ANO", + direction="l", + linebreak="al", + unicodeslot=0x1D04F, + }, + [0x1D050]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL YPSILI", + direction="l", + linebreak="al", + unicodeslot=0x1D050, + }, + [0x1D051]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL APOSTROFOS NEO", + direction="l", + linebreak="al", + unicodeslot=0x1D051, + }, + [0x1D052]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL APOSTROFOI SYNDESMOS NEO", + direction="l", + linebreak="al", + unicodeslot=0x1D052, + }, + [0x1D053]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL YPORROI", + direction="l", + linebreak="al", + unicodeslot=0x1D053, + }, + [0x1D054]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KRATIMOYPORROON", + direction="l", + linebreak="al", + unicodeslot=0x1D054, + }, + [0x1D055]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL ELAFRON", + direction="l", + linebreak="al", + unicodeslot=0x1D055, + }, + [0x1D056]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL CHAMILI", + direction="l", + linebreak="al", + unicodeslot=0x1D056, + }, + [0x1D057]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL MIKRON ISON", + direction="l", + linebreak="al", + unicodeslot=0x1D057, + }, + [0x1D058]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL VAREIA NEO", + direction="l", + linebreak="al", + unicodeslot=0x1D058, + }, + [0x1D059]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL PIASMA NEO", + direction="l", + linebreak="al", + unicodeslot=0x1D059, + }, + [0x1D05A]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL PSIFISTON NEO", + direction="l", + linebreak="al", + unicodeslot=0x1D05A, + }, + [0x1D05B]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL OMALON", + direction="l", + linebreak="al", + unicodeslot=0x1D05B, + }, + [0x1D05C]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL ANTIKENOMA", + direction="l", + linebreak="al", + unicodeslot=0x1D05C, + }, + [0x1D05D]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL LYGISMA", + direction="l", + linebreak="al", + unicodeslot=0x1D05D, + }, + [0x1D05E]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL PARAKLITIKI NEO", + direction="l", + linebreak="al", + unicodeslot=0x1D05E, + }, + [0x1D05F]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL PARAKALESMA NEO", + direction="l", + linebreak="al", + unicodeslot=0x1D05F, + }, + [0x1D060]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL ETERON PARAKALESMA", + direction="l", + linebreak="al", + unicodeslot=0x1D060, + }, + [0x1D061]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KYLISMA", + direction="l", + linebreak="al", + unicodeslot=0x1D061, + }, + [0x1D062]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL ANTIKENOKYLISMA", + direction="l", + linebreak="al", + unicodeslot=0x1D062, + }, + [0x1D063]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL TROMIKON NEO", + direction="l", + linebreak="al", + unicodeslot=0x1D063, + }, + [0x1D064]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL EKSTREPTON", + direction="l", + linebreak="al", + unicodeslot=0x1D064, + }, + [0x1D065]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL SYNAGMA NEO", + direction="l", + linebreak="al", + unicodeslot=0x1D065, + }, + [0x1D066]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL SYRMA", + direction="l", + linebreak="al", + unicodeslot=0x1D066, + }, + [0x1D067]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL CHOREVMA NEO", + direction="l", + linebreak="al", + unicodeslot=0x1D067, + }, + [0x1D068]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL EPEGERMA", + direction="l", + linebreak="al", + unicodeslot=0x1D068, + }, + [0x1D069]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL SEISMA NEO", + direction="l", + linebreak="al", + unicodeslot=0x1D069, + }, + [0x1D06A]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL XIRON KLASMA", + direction="l", + linebreak="al", + unicodeslot=0x1D06A, + }, + [0x1D06B]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL TROMIKOPSIFISTON", + direction="l", + linebreak="al", + unicodeslot=0x1D06B, + }, + [0x1D06C]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL PSIFISTOLYGISMA", + direction="l", + linebreak="al", + unicodeslot=0x1D06C, + }, + [0x1D06D]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL TROMIKOLYGISMA", + direction="l", + linebreak="al", + unicodeslot=0x1D06D, + }, + [0x1D06E]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL TROMIKOPARAKALESMA", + direction="l", + linebreak="al", + unicodeslot=0x1D06E, + }, + [0x1D06F]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL PSIFISTOPARAKALESMA", + direction="l", + linebreak="al", + unicodeslot=0x1D06F, + }, + [0x1D070]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL TROMIKOSYNAGMA", + direction="l", + linebreak="al", + unicodeslot=0x1D070, + }, + [0x1D071]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL PSIFISTOSYNAGMA", + direction="l", + linebreak="al", + unicodeslot=0x1D071, + }, + [0x1D072]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL GORGOSYNTHETON", + direction="l", + linebreak="al", + unicodeslot=0x1D072, + }, + [0x1D073]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL ARGOSYNTHETON", + direction="l", + linebreak="al", + unicodeslot=0x1D073, + }, + [0x1D074]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL ETERON ARGOSYNTHETON", + direction="l", + linebreak="al", + unicodeslot=0x1D074, + }, + [0x1D075]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL OYRANISMA NEO", + direction="l", + linebreak="al", + unicodeslot=0x1D075, + }, + [0x1D076]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL THEMATISMOS ESO", + direction="l", + linebreak="al", + unicodeslot=0x1D076, + }, + [0x1D077]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL THEMATISMOS EXO", + direction="l", + linebreak="al", + unicodeslot=0x1D077, + }, + [0x1D078]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL THEMA APLOUN", + direction="l", + linebreak="al", + unicodeslot=0x1D078, + }, + [0x1D079]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL THES KAI APOTHES", + direction="l", + linebreak="al", + unicodeslot=0x1D079, + }, + [0x1D07A]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KATAVASMA", + direction="l", + linebreak="al", + unicodeslot=0x1D07A, + }, + [0x1D07B]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL ENDOFONON", + direction="l", + linebreak="al", + unicodeslot=0x1D07B, + }, + [0x1D07C]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL YFEN KATO", + direction="l", + linebreak="al", + unicodeslot=0x1D07C, + }, + [0x1D07D]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL YFEN ANO", + direction="l", + linebreak="al", + unicodeslot=0x1D07D, + }, + [0x1D07E]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL STAVROS", + direction="l", + linebreak="al", + unicodeslot=0x1D07E, + }, + [0x1D07F]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KLASMA ANO", + direction="l", + linebreak="al", + unicodeslot=0x1D07F, + }, + [0x1D080]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL DIPLI ARCHAION", + direction="l", + linebreak="al", + unicodeslot=0x1D080, + }, + [0x1D081]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KRATIMA ARCHAION", + direction="l", + linebreak="al", + unicodeslot=0x1D081, + }, + [0x1D082]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KRATIMA ALLO", + direction="l", + linebreak="al", + unicodeslot=0x1D082, + }, + [0x1D083]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KRATIMA NEO", + direction="l", + linebreak="al", + unicodeslot=0x1D083, + }, + [0x1D084]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL APODERMA NEO", + direction="l", + linebreak="al", + unicodeslot=0x1D084, + }, + [0x1D085]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL APLI", + direction="l", + linebreak="al", + unicodeslot=0x1D085, + }, + [0x1D086]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL DIPLI", + direction="l", + linebreak="al", + unicodeslot=0x1D086, + }, + [0x1D087]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL TRIPLI", + direction="l", + linebreak="al", + unicodeslot=0x1D087, + }, + [0x1D088]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL TETRAPLI", + direction="l", + linebreak="al", + unicodeslot=0x1D088, + }, + [0x1D089]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KORONIS", + direction="l", + linebreak="al", + unicodeslot=0x1D089, + }, + [0x1D08A]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL LEIMMA ENOS CHRONOU", + direction="l", + linebreak="al", + unicodeslot=0x1D08A, + }, + [0x1D08B]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL LEIMMA DYO CHRONON", + direction="l", + linebreak="al", + unicodeslot=0x1D08B, + }, + [0x1D08C]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL LEIMMA TRION CHRONON", + direction="l", + linebreak="al", + unicodeslot=0x1D08C, + }, + [0x1D08D]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL LEIMMA TESSARON CHRONON", + direction="l", + linebreak="al", + unicodeslot=0x1D08D, + }, + [0x1D08E]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL LEIMMA IMISEOS CHRONOU", + direction="l", + linebreak="al", + unicodeslot=0x1D08E, + }, + [0x1D08F]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL GORGON NEO ANO", + direction="l", + linebreak="al", + unicodeslot=0x1D08F, + }, + [0x1D090]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON ARISTERA", + direction="l", + linebreak="al", + unicodeslot=0x1D090, + }, + [0x1D091]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON DEXIA", + direction="l", + linebreak="al", + unicodeslot=0x1D091, + }, + [0x1D092]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL DIGORGON", + direction="l", + linebreak="al", + unicodeslot=0x1D092, + }, + [0x1D093]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA KATO", + direction="l", + linebreak="al", + unicodeslot=0x1D093, + }, + [0x1D094]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA ANO", + direction="l", + linebreak="al", + unicodeslot=0x1D094, + }, + [0x1D095]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON DEXIA", + direction="l", + linebreak="al", + unicodeslot=0x1D095, + }, + [0x1D096]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL TRIGORGON", + direction="l", + linebreak="al", + unicodeslot=0x1D096, + }, + [0x1D097]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL ARGON", + direction="l", + linebreak="al", + unicodeslot=0x1D097, + }, + [0x1D098]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL IMIDIARGON", + direction="l", + linebreak="al", + unicodeslot=0x1D098, + }, + [0x1D099]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL DIARGON", + direction="l", + linebreak="al", + unicodeslot=0x1D099, + }, + [0x1D09A]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL AGOGI POLI ARGI", + direction="l", + linebreak="al", + unicodeslot=0x1D09A, + }, + [0x1D09B]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL AGOGI ARGOTERI", + direction="l", + linebreak="al", + unicodeslot=0x1D09B, + }, + [0x1D09C]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL AGOGI ARGI", + direction="l", + linebreak="al", + unicodeslot=0x1D09C, + }, + [0x1D09D]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL AGOGI METRIA", + direction="l", + linebreak="al", + unicodeslot=0x1D09D, + }, + [0x1D09E]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL AGOGI MESI", + direction="l", + linebreak="al", + unicodeslot=0x1D09E, + }, + [0x1D09F]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL AGOGI GORGI", + direction="l", + linebreak="al", + unicodeslot=0x1D09F, + }, + [0x1D0A0]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL AGOGI GORGOTERI", + direction="l", + linebreak="al", + unicodeslot=0x1D0A0, + }, + [0x1D0A1]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL AGOGI POLI GORGI", + direction="l", + linebreak="al", + unicodeslot=0x1D0A1, + }, + [0x1D0A2]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOS ICHOS", + direction="l", + linebreak="al", + unicodeslot=0x1D0A2, + }, + [0x1D0A3]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI PROTOS ICHOS", + direction="l", + linebreak="al", + unicodeslot=0x1D0A3, + }, + [0x1D0A4]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL MARTYRIA DEYTEROS ICHOS", + direction="l", + linebreak="al", + unicodeslot=0x1D0A4, + }, + [0x1D0A5]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI DEYTEROS ICHOS", + direction="l", + linebreak="al", + unicodeslot=0x1D0A5, + }, + [0x1D0A6]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL MARTYRIA TRITOS ICHOS", + direction="l", + linebreak="al", + unicodeslot=0x1D0A6, + }, + [0x1D0A7]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL MARTYRIA TRIFONIAS", + direction="l", + linebreak="al", + unicodeslot=0x1D0A7, + }, + [0x1D0A8]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS ICHOS", + direction="l", + linebreak="al", + unicodeslot=0x1D0A8, + }, + [0x1D0A9]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS LEGETOS ICHOS", + direction="l", + linebreak="al", + unicodeslot=0x1D0A9, + }, + [0x1D0AA]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL MARTYRIA LEGETOS ICHOS", + direction="l", + linebreak="al", + unicodeslot=0x1D0AA, + }, + [0x1D0AB]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS ICHOS", + direction="l", + linebreak="al", + unicodeslot=0x1D0AB, + }, + [0x1D0AC]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL ISAKIA TELOUS ICHIMATOS", + direction="l", + linebreak="al", + unicodeslot=0x1D0AC, + }, + [0x1D0AD]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL APOSTROFOI TELOUS ICHIMATOS", + direction="l", + linebreak="al", + unicodeslot=0x1D0AD, + }, + [0x1D0AE]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL FANEROSIS TETRAFONIAS", + direction="l", + linebreak="al", + unicodeslot=0x1D0AE, + }, + [0x1D0AF]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL FANEROSIS MONOFONIAS", + direction="l", + linebreak="al", + unicodeslot=0x1D0AF, + }, + [0x1D0B0]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL FANEROSIS DIFONIAS", + direction="l", + linebreak="al", + unicodeslot=0x1D0B0, + }, + [0x1D0B1]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL MARTYRIA VARYS ICHOS", + direction="l", + linebreak="al", + unicodeslot=0x1D0B1, + }, + [0x1D0B2]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOVARYS ICHOS", + direction="l", + linebreak="al", + unicodeslot=0x1D0B2, + }, + [0x1D0B3]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS TETARTOS ICHOS", + direction="l", + linebreak="al", + unicodeslot=0x1D0B3, + }, + [0x1D0B4]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL GORTHMIKON N APLOUN", + direction="l", + linebreak="al", + unicodeslot=0x1D0B4, + }, + [0x1D0B5]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL GORTHMIKON N DIPLOUN", + direction="l", + linebreak="al", + unicodeslot=0x1D0B5, + }, + [0x1D0B6]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL ENARXIS KAI FTHORA VOU", + direction="l", + linebreak="al", + unicodeslot=0x1D0B6, + }, + [0x1D0B7]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL IMIFONON", + direction="l", + linebreak="al", + unicodeslot=0x1D0B7, + }, + [0x1D0B8]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL IMIFTHORON", + direction="l", + linebreak="al", + unicodeslot=0x1D0B8, + }, + [0x1D0B9]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION DEYTEROU ICHOU", + direction="l", + linebreak="al", + unicodeslot=0x1D0B9, + }, + [0x1D0BA]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI PA", + direction="l", + linebreak="al", + unicodeslot=0x1D0BA, + }, + [0x1D0BB]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NANA", + direction="l", + linebreak="al", + unicodeslot=0x1D0BB, + }, + [0x1D0BC]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL FTHORA NAOS ICHOS", + direction="l", + linebreak="al", + unicodeslot=0x1D0BC, + }, + [0x1D0BD]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI DI", + direction="l", + linebreak="al", + unicodeslot=0x1D0BD, + }, + [0x1D0BE]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON DIATONON DI", + direction="l", + linebreak="al", + unicodeslot=0x1D0BE, + }, + [0x1D0BF]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI KE", + direction="l", + linebreak="al", + unicodeslot=0x1D0BF, + }, + [0x1D0C0]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI ZO", + direction="l", + linebreak="al", + unicodeslot=0x1D0C0, + }, + [0x1D0C1]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI KATO", + direction="l", + linebreak="al", + unicodeslot=0x1D0C1, + }, + [0x1D0C2]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI ANO", + direction="l", + linebreak="al", + unicodeslot=0x1D0C2, + }, + [0x1D0C3]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA DIFONIAS", + direction="l", + linebreak="al", + unicodeslot=0x1D0C3, + }, + [0x1D0C4]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA MONOFONIAS", + direction="l", + linebreak="al", + unicodeslot=0x1D0C4, + }, + [0x1D0C5]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL FHTORA SKLIRON CHROMA VASIS", + direction="l", + linebreak="al", + unicodeslot=0x1D0C5, + }, + [0x1D0C6]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON CHROMA SYNAFI", + direction="l", + linebreak="al", + unicodeslot=0x1D0C6, + }, + [0x1D0C7]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL FTHORA NENANO", + direction="l", + linebreak="al", + unicodeslot=0x1D0C7, + }, + [0x1D0C8]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL CHROA ZYGOS", + direction="l", + linebreak="al", + unicodeslot=0x1D0C8, + }, + [0x1D0C9]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL CHROA KLITON", + direction="l", + linebreak="al", + unicodeslot=0x1D0C9, + }, + [0x1D0CA]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL CHROA SPATHI", + direction="l", + linebreak="al", + unicodeslot=0x1D0CA, + }, + [0x1D0CB]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL FTHORA I YFESIS TETARTIMORION", + direction="l", + linebreak="al", + unicodeslot=0x1D0CB, + }, + [0x1D0CC]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL FTHORA ENARMONIOS ANTIFONIA", + direction="l", + linebreak="al", + unicodeslot=0x1D0CC, + }, + [0x1D0CD]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL YFESIS TRITIMORION", + direction="l", + linebreak="al", + unicodeslot=0x1D0CD, + }, + [0x1D0CE]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL DIESIS TRITIMORION", + direction="l", + linebreak="al", + unicodeslot=0x1D0CE, + }, + [0x1D0CF]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL DIESIS TETARTIMORION", + direction="l", + linebreak="al", + unicodeslot=0x1D0CF, + }, + [0x1D0D0]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL DIESIS APLI DYO DODEKATA", + direction="l", + linebreak="al", + unicodeslot=0x1D0D0, + }, + [0x1D0D1]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL DIESIS MONOGRAMMOS TESSERA DODEKATA", + direction="l", + linebreak="al", + unicodeslot=0x1D0D1, + }, + [0x1D0D2]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL DIESIS DIGRAMMOS EX DODEKATA", + direction="l", + linebreak="al", + unicodeslot=0x1D0D2, + }, + [0x1D0D3]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL DIESIS TRIGRAMMOS OKTO DODEKATA", + direction="l", + linebreak="al", + unicodeslot=0x1D0D3, + }, + [0x1D0D4]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL YFESIS APLI DYO DODEKATA", + direction="l", + linebreak="al", + unicodeslot=0x1D0D4, + }, + [0x1D0D5]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL YFESIS MONOGRAMMOS TESSERA DODEKATA", + direction="l", + linebreak="al", + unicodeslot=0x1D0D5, + }, + [0x1D0D6]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL YFESIS DIGRAMMOS EX DODEKATA", + direction="l", + linebreak="al", + unicodeslot=0x1D0D6, + }, + [0x1D0D7]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL YFESIS TRIGRAMMOS OKTO DODEKATA", + direction="l", + linebreak="al", + unicodeslot=0x1D0D7, + }, + [0x1D0D8]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL GENIKI DIESIS", + direction="l", + linebreak="al", + unicodeslot=0x1D0D8, + }, + [0x1D0D9]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL GENIKI YFESIS", + direction="l", + linebreak="al", + unicodeslot=0x1D0D9, + }, + [0x1D0DA]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MIKRI", + direction="l", + linebreak="al", + unicodeslot=0x1D0DA, + }, + [0x1D0DB]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MEGALI", + direction="l", + linebreak="al", + unicodeslot=0x1D0DB, + }, + [0x1D0DC]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL DIASTOLI DIPLI", + direction="l", + linebreak="al", + unicodeslot=0x1D0DC, + }, + [0x1D0DD]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL DIASTOLI THESEOS", + direction="l", + linebreak="al", + unicodeslot=0x1D0DD, + }, + [0x1D0DE]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS", + direction="l", + linebreak="al", + unicodeslot=0x1D0DE, + }, + [0x1D0DF]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS DISIMOU", + direction="l", + linebreak="al", + unicodeslot=0x1D0DF, + }, + [0x1D0E0]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TRISIMOU", + direction="l", + linebreak="al", + unicodeslot=0x1D0E0, + }, + [0x1D0E1]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TETRASIMOU", + direction="l", + linebreak="al", + unicodeslot=0x1D0E1, + }, + [0x1D0E2]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS", + direction="l", + linebreak="al", + unicodeslot=0x1D0E2, + }, + [0x1D0E3]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS DISIMOU", + direction="l", + linebreak="al", + unicodeslot=0x1D0E3, + }, + [0x1D0E4]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TRISIMOU", + direction="l", + linebreak="al", + unicodeslot=0x1D0E4, + }, + [0x1D0E5]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TETRASIMOU", + direction="l", + linebreak="al", + unicodeslot=0x1D0E5, + }, + [0x1D0E6]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL DIGRAMMA GG", + direction="l", + linebreak="al", + unicodeslot=0x1D0E6, + }, + [0x1D0E7]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL DIFTOGGOS OU", + direction="l", + linebreak="al", + unicodeslot=0x1D0E7, + }, + [0x1D0E8]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL STIGMA", + direction="l", + linebreak="al", + unicodeslot=0x1D0E8, + }, + [0x1D0E9]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL ARKTIKO PA", + direction="l", + linebreak="al", + unicodeslot=0x1D0E9, + }, + [0x1D0EA]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL ARKTIKO VOU", + direction="l", + linebreak="al", + unicodeslot=0x1D0EA, + }, + [0x1D0EB]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL ARKTIKO GA", + direction="l", + linebreak="al", + unicodeslot=0x1D0EB, + }, + [0x1D0EC]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL ARKTIKO DI", + direction="l", + linebreak="al", + unicodeslot=0x1D0EC, + }, + [0x1D0ED]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL ARKTIKO KE", + direction="l", + linebreak="al", + unicodeslot=0x1D0ED, + }, + [0x1D0EE]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL ARKTIKO ZO", + direction="l", + linebreak="al", + unicodeslot=0x1D0EE, + }, + [0x1D0EF]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL ARKTIKO NI", + direction="l", + linebreak="al", + unicodeslot=0x1D0EF, + }, + [0x1D0F0]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KENTIMATA NEO MESO", + direction="l", + linebreak="al", + unicodeslot=0x1D0F0, + }, + [0x1D0F1]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KENTIMA NEO MESO", + direction="l", + linebreak="al", + unicodeslot=0x1D0F1, + }, + [0x1D0F2]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KENTIMATA NEO KATO", + direction="l", + linebreak="al", + unicodeslot=0x1D0F2, + }, + [0x1D0F3]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KENTIMA NEO KATO", + direction="l", + linebreak="al", + unicodeslot=0x1D0F3, + }, + [0x1D0F4]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL KLASMA KATO", + direction="l", + linebreak="al", + unicodeslot=0x1D0F4, + }, + [0x1D0F5]={ + category="so", + description="BYZANTINE MUSICAL SYMBOL GORGON NEO KATO", + direction="l", + linebreak="al", + unicodeslot=0x1D0F5, + }, + [0x1D100]={ + category="so", + description="MUSICAL SYMBOL SINGLE BARLINE", + direction="l", + linebreak="al", + unicodeslot=0x1D100, + }, + [0x1D101]={ + category="so", + description="MUSICAL SYMBOL DOUBLE BARLINE", + direction="l", + linebreak="al", + unicodeslot=0x1D101, + }, + [0x1D102]={ + category="so", + description="MUSICAL SYMBOL FINAL BARLINE", + direction="l", + linebreak="al", + unicodeslot=0x1D102, + }, + [0x1D103]={ + category="so", + description="MUSICAL SYMBOL REVERSE FINAL BARLINE", + direction="l", + linebreak="al", + unicodeslot=0x1D103, + }, + [0x1D104]={ + category="so", + description="MUSICAL SYMBOL DASHED BARLINE", + direction="l", + linebreak="al", + unicodeslot=0x1D104, + }, + [0x1D105]={ + category="so", + description="MUSICAL SYMBOL SHORT BARLINE", + direction="l", + linebreak="al", + unicodeslot=0x1D105, + }, + [0x1D106]={ + category="so", + description="MUSICAL SYMBOL LEFT REPEAT SIGN", + direction="l", + linebreak="al", + unicodeslot=0x1D106, + }, + [0x1D107]={ + category="so", + description="MUSICAL SYMBOL RIGHT REPEAT SIGN", + direction="l", + linebreak="al", + unicodeslot=0x1D107, + }, + [0x1D108]={ + category="so", + description="MUSICAL SYMBOL REPEAT DOTS", + direction="l", + linebreak="al", + unicodeslot=0x1D108, + }, + [0x1D109]={ + category="so", + description="MUSICAL SYMBOL DAL SEGNO", + direction="l", + linebreak="al", + unicodeslot=0x1D109, + }, + [0x1D10A]={ + category="so", + description="MUSICAL SYMBOL DA CAPO", + direction="l", + linebreak="al", + unicodeslot=0x1D10A, + }, + [0x1D10B]={ + category="so", + description="MUSICAL SYMBOL SEGNO", + direction="l", + linebreak="al", + unicodeslot=0x1D10B, + }, + [0x1D10C]={ + category="so", + description="MUSICAL SYMBOL CODA", + direction="l", + linebreak="al", + unicodeslot=0x1D10C, + }, + [0x1D10D]={ + category="so", + description="MUSICAL SYMBOL REPEATED FIGURE-0x0001", + direction="l", + linebreak="al", + unicodeslot=0x1D10D, + }, + [0x1D10E]={ + category="so", + description="MUSICAL SYMBOL REPEATED FIGURE-0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1D10E, + }, + [0x1D10F]={ + category="so", + description="MUSICAL SYMBOL REPEATED FIGURE-0x0003", + direction="l", + linebreak="al", + unicodeslot=0x1D10F, + }, + [0x1D110]={ + category="so", + description="MUSICAL SYMBOL FERMATA", + direction="l", + linebreak="al", + unicodeslot=0x1D110, + }, + [0x1D111]={ + category="so", + description="MUSICAL SYMBOL FERMATA BELOW", + direction="l", + linebreak="al", + unicodeslot=0x1D111, + }, + [0x1D112]={ + category="so", + description="MUSICAL SYMBOL BREATH MARK", + direction="l", + linebreak="al", + unicodeslot=0x1D112, + }, + [0x1D113]={ + category="so", + description="MUSICAL SYMBOL CAESURA", + direction="l", + linebreak="al", + unicodeslot=0x1D113, + }, + [0x1D114]={ + category="so", + description="MUSICAL SYMBOL BRACE", + direction="l", + linebreak="al", + unicodeslot=0x1D114, + }, + [0x1D115]={ + category="so", + description="MUSICAL SYMBOL BRACKET", + direction="l", + linebreak="al", + unicodeslot=0x1D115, + }, + [0x1D116]={ + category="so", + description="MUSICAL SYMBOL ONE-LINE STAFF", + direction="l", + linebreak="al", + unicodeslot=0x1D116, + }, + [0x1D117]={ + category="so", + description="MUSICAL SYMBOL TWO-LINE STAFF", + direction="l", + linebreak="al", + unicodeslot=0x1D117, + }, + [0x1D118]={ + category="so", + description="MUSICAL SYMBOL THREE-LINE STAFF", + direction="l", + linebreak="al", + unicodeslot=0x1D118, + }, + [0x1D119]={ + category="so", + description="MUSICAL SYMBOL FOUR-LINE STAFF", + direction="l", + linebreak="al", + unicodeslot=0x1D119, + }, + [0x1D11A]={ + category="so", + description="MUSICAL SYMBOL FIVE-LINE STAFF", + direction="l", + linebreak="al", + unicodeslot=0x1D11A, + }, + [0x1D11B]={ + category="so", + description="MUSICAL SYMBOL SIX-LINE STAFF", + direction="l", + linebreak="al", + unicodeslot=0x1D11B, + }, + [0x1D11C]={ + category="so", + description="MUSICAL SYMBOL SIX-STRING FRETBOARD", + direction="l", + linebreak="al", + unicodeslot=0x1D11C, + }, + [0x1D11D]={ + category="so", + description="MUSICAL SYMBOL FOUR-STRING FRETBOARD", + direction="l", + linebreak="al", + unicodeslot=0x1D11D, + }, + [0x1D11E]={ + category="so", + description="MUSICAL SYMBOL G CLEF", + direction="l", + linebreak="al", + unicodeslot=0x1D11E, + }, + [0x1D11F]={ + category="so", + description="MUSICAL SYMBOL G CLEF OTTAVA ALTA", + direction="l", + linebreak="al", + unicodeslot=0x1D11F, + }, + [0x1D120]={ + category="so", + description="MUSICAL SYMBOL G CLEF OTTAVA BASSA", + direction="l", + linebreak="al", + unicodeslot=0x1D120, + }, + [0x1D121]={ + category="so", + description="MUSICAL SYMBOL C CLEF", + direction="l", + linebreak="al", + unicodeslot=0x1D121, + }, + [0x1D122]={ + category="so", + description="MUSICAL SYMBOL F CLEF", + direction="l", + linebreak="al", + unicodeslot=0x1D122, + }, + [0x1D123]={ + category="so", + description="MUSICAL SYMBOL F CLEF OTTAVA ALTA", + direction="l", + linebreak="al", + unicodeslot=0x1D123, + }, + [0x1D124]={ + category="so", + description="MUSICAL SYMBOL F CLEF OTTAVA BASSA", + direction="l", + linebreak="al", + unicodeslot=0x1D124, + }, + [0x1D125]={ + category="so", + description="MUSICAL SYMBOL DRUM CLEF-0x0001", + direction="l", + linebreak="al", + unicodeslot=0x1D125, + }, + [0x1D126]={ + category="so", + description="MUSICAL SYMBOL DRUM CLEF-0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1D126, + }, + [0x1D12A]={ + category="so", + description="MUSICAL SYMBOL DOUBLE SHARP", + direction="l", + linebreak="al", + unicodeslot=0x1D12A, + }, + [0x1D12B]={ + category="so", + description="MUSICAL SYMBOL DOUBLE FLAT", + direction="l", + linebreak="al", + unicodeslot=0x1D12B, + }, + [0x1D12C]={ + category="so", + description="MUSICAL SYMBOL FLAT UP", + direction="l", + linebreak="al", + unicodeslot=0x1D12C, + }, + [0x1D12D]={ + category="so", + description="MUSICAL SYMBOL FLAT DOWN", + direction="l", + linebreak="al", + unicodeslot=0x1D12D, + }, + [0x1D12E]={ + category="so", + description="MUSICAL SYMBOL NATURAL UP", + direction="l", + linebreak="al", + unicodeslot=0x1D12E, + }, + [0x1D12F]={ + category="so", + description="MUSICAL SYMBOL NATURAL DOWN", + direction="l", + linebreak="al", + unicodeslot=0x1D12F, + }, + [0x1D130]={ + category="so", + description="MUSICAL SYMBOL SHARP UP", + direction="l", + linebreak="al", + unicodeslot=0x1D130, + }, + [0x1D131]={ + category="so", + description="MUSICAL SYMBOL SHARP DOWN", + direction="l", + linebreak="al", + unicodeslot=0x1D131, + }, + [0x1D132]={ + category="so", + description="MUSICAL SYMBOL QUARTER TONE SHARP", + direction="l", + linebreak="al", + unicodeslot=0x1D132, + }, + [0x1D133]={ + category="so", + description="MUSICAL SYMBOL QUARTER TONE FLAT", + direction="l", + linebreak="al", + unicodeslot=0x1D133, + }, + [0x1D134]={ + category="so", + description="MUSICAL SYMBOL COMMON TIME", + direction="l", + linebreak="al", + unicodeslot=0x1D134, + }, + [0x1D135]={ + category="so", + description="MUSICAL SYMBOL CUT TIME", + direction="l", + linebreak="al", + unicodeslot=0x1D135, + }, + [0x1D136]={ + category="so", + description="MUSICAL SYMBOL OTTAVA ALTA", + direction="l", + linebreak="al", + unicodeslot=0x1D136, + }, + [0x1D137]={ + category="so", + description="MUSICAL SYMBOL OTTAVA BASSA", + direction="l", + linebreak="al", + unicodeslot=0x1D137, + }, + [0x1D138]={ + category="so", + description="MUSICAL SYMBOL QUINDICESIMA ALTA", + direction="l", + linebreak="al", + unicodeslot=0x1D138, + }, + [0x1D139]={ + category="so", + description="MUSICAL SYMBOL QUINDICESIMA BASSA", + direction="l", + linebreak="al", + unicodeslot=0x1D139, + }, + [0x1D13A]={ + category="so", + description="MUSICAL SYMBOL MULTI REST", + direction="l", + linebreak="al", + unicodeslot=0x1D13A, + }, + [0x1D13B]={ + category="so", + description="MUSICAL SYMBOL WHOLE REST", + direction="l", + linebreak="al", + unicodeslot=0x1D13B, + }, + [0x1D13C]={ + category="so", + description="MUSICAL SYMBOL HALF REST", + direction="l", + linebreak="al", + unicodeslot=0x1D13C, + }, + [0x1D13D]={ + category="so", + description="MUSICAL SYMBOL QUARTER REST", + direction="l", + linebreak="al", + unicodeslot=0x1D13D, + }, + [0x1D13E]={ + category="so", + description="MUSICAL SYMBOL EIGHTH REST", + direction="l", + linebreak="al", + unicodeslot=0x1D13E, + }, + [0x1D13F]={ + category="so", + description="MUSICAL SYMBOL SIXTEENTH REST", + direction="l", + linebreak="al", + unicodeslot=0x1D13F, + }, + [0x1D140]={ + category="so", + description="MUSICAL SYMBOL THIRTY-SECOND REST", + direction="l", + linebreak="al", + unicodeslot=0x1D140, + }, + [0x1D141]={ + category="so", + description="MUSICAL SYMBOL SIXTY-FOURTH REST", + direction="l", + linebreak="al", + unicodeslot=0x1D141, + }, + [0x1D142]={ + category="so", + description="MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH REST", + direction="l", + linebreak="al", + unicodeslot=0x1D142, + }, + [0x1D143]={ + category="so", + description="MUSICAL SYMBOL X NOTEHEAD", + direction="l", + linebreak="al", + unicodeslot=0x1D143, + }, + [0x1D144]={ + category="so", + description="MUSICAL SYMBOL PLUS NOTEHEAD", + direction="l", + linebreak="al", + unicodeslot=0x1D144, + }, + [0x1D145]={ + category="so", + description="MUSICAL SYMBOL CIRCLE X NOTEHEAD", + direction="l", + linebreak="al", + unicodeslot=0x1D145, + }, + [0x1D146]={ + category="so", + description="MUSICAL SYMBOL SQUARE NOTEHEAD WHITE", + direction="l", + linebreak="al", + unicodeslot=0x1D146, + }, + [0x1D147]={ + category="so", + description="MUSICAL SYMBOL SQUARE NOTEHEAD BLACK", + direction="l", + linebreak="al", + unicodeslot=0x1D147, + }, + [0x1D148]={ + category="so", + description="MUSICAL SYMBOL TRIANGLE NOTEHEAD UP WHITE", + direction="l", + linebreak="al", + unicodeslot=0x1D148, + }, + [0x1D149]={ + category="so", + description="MUSICAL SYMBOL TRIANGLE NOTEHEAD UP BLACK", + direction="l", + linebreak="al", + unicodeslot=0x1D149, + }, + [0x1D14A]={ + category="so", + description="MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT WHITE", + direction="l", + linebreak="al", + unicodeslot=0x1D14A, + }, + [0x1D14B]={ + category="so", + description="MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT BLACK", + direction="l", + linebreak="al", + unicodeslot=0x1D14B, + }, + [0x1D14C]={ + category="so", + description="MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT WHITE", + direction="l", + linebreak="al", + unicodeslot=0x1D14C, + }, + [0x1D14D]={ + category="so", + description="MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT BLACK", + direction="l", + linebreak="al", + unicodeslot=0x1D14D, + }, + [0x1D14E]={ + category="so", + description="MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN WHITE", + direction="l", + linebreak="al", + unicodeslot=0x1D14E, + }, + [0x1D14F]={ + category="so", + description="MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN BLACK", + direction="l", + linebreak="al", + unicodeslot=0x1D14F, + }, + [0x1D150]={ + category="so", + description="MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT WHITE", + direction="l", + linebreak="al", + unicodeslot=0x1D150, + }, + [0x1D151]={ + category="so", + description="MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT BLACK", + direction="l", + linebreak="al", + unicodeslot=0x1D151, + }, + [0x1D152]={ + category="so", + description="MUSICAL SYMBOL MOON NOTEHEAD WHITE", + direction="l", + linebreak="al", + unicodeslot=0x1D152, + }, + [0x1D153]={ + category="so", + description="MUSICAL SYMBOL MOON NOTEHEAD BLACK", + direction="l", + linebreak="al", + unicodeslot=0x1D153, + }, + [0x1D154]={ + category="so", + description="MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN WHITE", + direction="l", + linebreak="al", + unicodeslot=0x1D154, + }, + [0x1D155]={ + category="so", + description="MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN BLACK", + direction="l", + linebreak="al", + unicodeslot=0x1D155, + }, + [0x1D156]={ + category="so", + description="MUSICAL SYMBOL PARENTHESIS NOTEHEAD", + direction="l", + linebreak="al", + unicodeslot=0x1D156, + }, + [0x1D157]={ + category="so", + description="MUSICAL SYMBOL VOID NOTEHEAD", + direction="l", + linebreak="al", + unicodeslot=0x1D157, + }, + [0x1D158]={ + category="so", + description="MUSICAL SYMBOL NOTEHEAD BLACK", + direction="l", + linebreak="al", + unicodeslot=0x1D158, + }, + [0x1D159]={ + category="so", + description="MUSICAL SYMBOL NULL NOTEHEAD", + direction="l", + linebreak="al", + unicodeslot=0x1D159, + }, + [0x1D15A]={ + category="so", + description="MUSICAL SYMBOL CLUSTER NOTEHEAD WHITE", + direction="l", + linebreak="al", + unicodeslot=0x1D15A, + }, + [0x1D15B]={ + category="so", + description="MUSICAL SYMBOL CLUSTER NOTEHEAD BLACK", + direction="l", + linebreak="al", + unicodeslot=0x1D15B, + }, + [0x1D15C]={ + category="so", + description="MUSICAL SYMBOL BREVE", + direction="l", + linebreak="al", + unicodeslot=0x1D15C, + }, + [0x1D15D]={ + category="so", + description="MUSICAL SYMBOL WHOLE NOTE", + direction="l", + linebreak="al", + unicodeslot=0x1D15D, + }, + [0x1D15E]={ + category="so", + description="MUSICAL SYMBOL HALF NOTE", + direction="l", + linebreak="al", + specials={ "char", 0x1D157, 0x1D165 }, + unicodeslot=0x1D15E, + }, + [0x1D15F]={ + category="so", + description="MUSICAL SYMBOL QUARTER NOTE", + direction="l", + linebreak="al", + specials={ "char", 0x1D158, 0x1D165 }, + unicodeslot=0x1D15F, + }, + [0x1D160]={ + category="so", + description="MUSICAL SYMBOL EIGHTH NOTE", + direction="l", + linebreak="al", + specials={ "char", 0x1D15F, 0x1D16E }, + unicodeslot=0x1D160, + }, + [0x1D161]={ + category="so", + description="MUSICAL SYMBOL SIXTEENTH NOTE", + direction="l", + linebreak="al", + specials={ "char", 0x1D15F, 0x1D16F }, + unicodeslot=0x1D161, + }, + [0x1D162]={ + category="so", + description="MUSICAL SYMBOL THIRTY-SECOND NOTE", + direction="l", + linebreak="al", + specials={ "char", 0x1D15F, 0x1D170 }, + unicodeslot=0x1D162, + }, + [0x1D163]={ + category="so", + description="MUSICAL SYMBOL SIXTY-FOURTH NOTE", + direction="l", + linebreak="al", + specials={ "char", 0x1D15F, 0x1D171 }, + unicodeslot=0x1D163, + }, + [0x1D164]={ + category="so", + description="MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE", + direction="l", + linebreak="al", + specials={ "char", 0x1D15F, 0x1D172 }, + unicodeslot=0x1D164, + }, + [0x1D165]={ + category="mc", + description="MUSICAL SYMBOL COMBINING STEM", + direction="l", + linebreak="cm", + unicodeslot=0x1D165, + }, + [0x1D166]={ + category="mc", + description="MUSICAL SYMBOL COMBINING SPRECHGESANG STEM", + direction="l", + linebreak="cm", + unicodeslot=0x1D166, + }, + [0x1D167]={ + category="mn", + description="MUSICAL SYMBOL COMBINING TREMOLO-0x0001", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D167, + }, + [0x1D168]={ + category="mn", + description="MUSICAL SYMBOL COMBINING TREMOLO-0x0002", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D168, + }, + [0x1D169]={ + category="mn", + description="MUSICAL SYMBOL COMBINING TREMOLO-0x0003", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D169, + }, + [0x1D16A]={ + category="so", + description="MUSICAL SYMBOL FINGERED TREMOLO-0x0001", + direction="l", + linebreak="al", + unicodeslot=0x1D16A, + }, + [0x1D16B]={ + category="so", + description="MUSICAL SYMBOL FINGERED TREMOLO-0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1D16B, + }, + [0x1D16C]={ + category="so", + description="MUSICAL SYMBOL FINGERED TREMOLO-0x0003", + direction="l", + linebreak="al", + unicodeslot=0x1D16C, + }, + [0x1D16D]={ + category="mc", + description="MUSICAL SYMBOL COMBINING AUGMENTATION DOT", + direction="l", + linebreak="cm", + unicodeslot=0x1D16D, + }, + [0x1D16E]={ + category="mc", + description="MUSICAL SYMBOL COMBINING FLAG-0x0001", + direction="l", + linebreak="cm", + unicodeslot=0x1D16E, + }, + [0x1D16F]={ + category="mc", + description="MUSICAL SYMBOL COMBINING FLAG-0x0002", + direction="l", + linebreak="cm", + unicodeslot=0x1D16F, + }, + [0x1D170]={ + category="mc", + description="MUSICAL SYMBOL COMBINING FLAG-0x0003", + direction="l", + linebreak="cm", + unicodeslot=0x1D170, + }, + [0x1D171]={ + category="mc", + description="MUSICAL SYMBOL COMBINING FLAG-0x0004", + direction="l", + linebreak="cm", + unicodeslot=0x1D171, + }, + [0x1D172]={ + category="mc", + description="MUSICAL SYMBOL COMBINING FLAG-0x0005", + direction="l", + linebreak="cm", + unicodeslot=0x1D172, + }, + [0x1D173]={ + category="cf", + description="MUSICAL SYMBOL BEGIN BEAM", + direction="bn", + linebreak="cm", + unicodeslot=0x1D173, + }, + [0x1D174]={ + category="cf", + description="MUSICAL SYMBOL END BEAM", + direction="bn", + linebreak="cm", + unicodeslot=0x1D174, + }, + [0x1D175]={ + category="cf", + description="MUSICAL SYMBOL BEGIN TIE", + direction="bn", + linebreak="cm", + unicodeslot=0x1D175, + }, + [0x1D176]={ + category="cf", + description="MUSICAL SYMBOL END TIE", + direction="bn", + linebreak="cm", + unicodeslot=0x1D176, + }, + [0x1D177]={ + category="cf", + description="MUSICAL SYMBOL BEGIN SLUR", + direction="bn", + linebreak="cm", + unicodeslot=0x1D177, + }, + [0x1D178]={ + category="cf", + description="MUSICAL SYMBOL END SLUR", + direction="bn", + linebreak="cm", + unicodeslot=0x1D178, + }, + [0x1D179]={ + category="cf", + description="MUSICAL SYMBOL BEGIN PHRASE", + direction="bn", + linebreak="cm", + unicodeslot=0x1D179, + }, + [0x1D17A]={ + category="cf", + description="MUSICAL SYMBOL END PHRASE", + direction="bn", + linebreak="cm", + unicodeslot=0x1D17A, + }, + [0x1D17B]={ + category="mn", + description="MUSICAL SYMBOL COMBINING ACCENT", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D17B, + }, + [0x1D17C]={ + category="mn", + description="MUSICAL SYMBOL COMBINING STACCATO", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D17C, + }, + [0x1D17D]={ + category="mn", + description="MUSICAL SYMBOL COMBINING TENUTO", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D17D, + }, + [0x1D17E]={ + category="mn", + description="MUSICAL SYMBOL COMBINING STACCATISSIMO", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D17E, + }, + [0x1D17F]={ + category="mn", + description="MUSICAL SYMBOL COMBINING MARCATO", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D17F, + }, + [0x1D180]={ + category="mn", + description="MUSICAL SYMBOL COMBINING MARCATO-STACCATO", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D180, + }, + [0x1D181]={ + category="mn", + description="MUSICAL SYMBOL COMBINING ACCENT-STACCATO", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D181, + }, + [0x1D182]={ + category="mn", + description="MUSICAL SYMBOL COMBINING LOURE", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D182, + }, + [0x1D183]={ + category="so", + description="MUSICAL SYMBOL ARPEGGIATO UP", + direction="l", + linebreak="al", + unicodeslot=0x1D183, + }, + [0x1D184]={ + category="so", + description="MUSICAL SYMBOL ARPEGGIATO DOWN", + direction="l", + linebreak="al", + unicodeslot=0x1D184, + }, + [0x1D185]={ + category="mn", + description="MUSICAL SYMBOL COMBINING DOIT", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D185, + }, + [0x1D186]={ + category="mn", + description="MUSICAL SYMBOL COMBINING RIP", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D186, + }, + [0x1D187]={ + category="mn", + description="MUSICAL SYMBOL COMBINING FLIP", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D187, + }, + [0x1D188]={ + category="mn", + description="MUSICAL SYMBOL COMBINING SMEAR", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D188, + }, + [0x1D189]={ + category="mn", + description="MUSICAL SYMBOL COMBINING BEND", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D189, + }, + [0x1D18A]={ + category="mn", + description="MUSICAL SYMBOL COMBINING DOUBLE TONGUE", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D18A, + }, + [0x1D18B]={ + category="mn", + description="MUSICAL SYMBOL COMBINING TRIPLE TONGUE", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D18B, + }, + [0x1D18C]={ + category="so", + description="MUSICAL SYMBOL RINFORZANDO", + direction="l", + linebreak="al", + unicodeslot=0x1D18C, + }, + [0x1D18D]={ + category="so", + description="MUSICAL SYMBOL SUBITO", + direction="l", + linebreak="al", + unicodeslot=0x1D18D, + }, + [0x1D18E]={ + category="so", + description="MUSICAL SYMBOL Z", + direction="l", + linebreak="al", + unicodeslot=0x1D18E, + }, + [0x1D18F]={ + category="so", + description="MUSICAL SYMBOL PIANO", + direction="l", + linebreak="al", + unicodeslot=0x1D18F, + }, + [0x1D190]={ + category="so", + description="MUSICAL SYMBOL MEZZO", + direction="l", + linebreak="al", + unicodeslot=0x1D190, + }, + [0x1D191]={ + category="so", + description="MUSICAL SYMBOL FORTE", + direction="l", + linebreak="al", + unicodeslot=0x1D191, + }, + [0x1D192]={ + category="so", + description="MUSICAL SYMBOL CRESCENDO", + direction="l", + linebreak="al", + unicodeslot=0x1D192, + }, + [0x1D193]={ + category="so", + description="MUSICAL SYMBOL DECRESCENDO", + direction="l", + linebreak="al", + unicodeslot=0x1D193, + }, + [0x1D194]={ + category="so", + description="MUSICAL SYMBOL GRACE NOTE SLASH", + direction="l", + linebreak="al", + unicodeslot=0x1D194, + }, + [0x1D195]={ + category="so", + description="MUSICAL SYMBOL GRACE NOTE NO SLASH", + direction="l", + linebreak="al", + unicodeslot=0x1D195, + }, + [0x1D196]={ + category="so", + description="MUSICAL SYMBOL TR", + direction="l", + linebreak="al", + unicodeslot=0x1D196, + }, + [0x1D197]={ + category="so", + description="MUSICAL SYMBOL TURN", + direction="l", + linebreak="al", + unicodeslot=0x1D197, + }, + [0x1D198]={ + category="so", + description="MUSICAL SYMBOL INVERTED TURN", + direction="l", + linebreak="al", + unicodeslot=0x1D198, + }, + [0x1D199]={ + category="so", + description="MUSICAL SYMBOL TURN SLASH", + direction="l", + linebreak="al", + unicodeslot=0x1D199, + }, + [0x1D19A]={ + category="so", + description="MUSICAL SYMBOL TURN UP", + direction="l", + linebreak="al", + unicodeslot=0x1D19A, + }, + [0x1D19B]={ + category="so", + description="MUSICAL SYMBOL ORNAMENT STROKE-0x0001", + direction="l", + linebreak="al", + unicodeslot=0x1D19B, + }, + [0x1D19C]={ + category="so", + description="MUSICAL SYMBOL ORNAMENT STROKE-0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1D19C, + }, + [0x1D19D]={ + category="so", + description="MUSICAL SYMBOL ORNAMENT STROKE-0x0003", + direction="l", + linebreak="al", + unicodeslot=0x1D19D, + }, + [0x1D19E]={ + category="so", + description="MUSICAL SYMBOL ORNAMENT STROKE-0x0004", + direction="l", + linebreak="al", + unicodeslot=0x1D19E, + }, + [0x1D19F]={ + category="so", + description="MUSICAL SYMBOL ORNAMENT STROKE-0x0005", + direction="l", + linebreak="al", + unicodeslot=0x1D19F, + }, + [0x1D1A0]={ + category="so", + description="MUSICAL SYMBOL ORNAMENT STROKE-0x0006", + direction="l", + linebreak="al", + unicodeslot=0x1D1A0, + }, + [0x1D1A1]={ + category="so", + description="MUSICAL SYMBOL ORNAMENT STROKE-0x0007", + direction="l", + linebreak="al", + unicodeslot=0x1D1A1, + }, + [0x1D1A2]={ + category="so", + description="MUSICAL SYMBOL ORNAMENT STROKE-0x0008", + direction="l", + linebreak="al", + unicodeslot=0x1D1A2, + }, + [0x1D1A3]={ + category="so", + description="MUSICAL SYMBOL ORNAMENT STROKE-0x0009", + direction="l", + linebreak="al", + unicodeslot=0x1D1A3, + }, + [0x1D1A4]={ + category="so", + description="MUSICAL SYMBOL ORNAMENT STROKE-0x000A", + direction="l", + linebreak="al", + unicodeslot=0x1D1A4, + }, + [0x1D1A5]={ + category="so", + description="MUSICAL SYMBOL ORNAMENT STROKE-0x000B", + direction="l", + linebreak="al", + unicodeslot=0x1D1A5, + }, + [0x1D1A6]={ + category="so", + description="MUSICAL SYMBOL HAUPTSTIMME", + direction="l", + linebreak="al", + unicodeslot=0x1D1A6, + }, + [0x1D1A7]={ + category="so", + description="MUSICAL SYMBOL NEBENSTIMME", + direction="l", + linebreak="al", + unicodeslot=0x1D1A7, + }, + [0x1D1A8]={ + category="so", + description="MUSICAL SYMBOL END OF STIMME", + direction="l", + linebreak="al", + unicodeslot=0x1D1A8, + }, + [0x1D1A9]={ + category="so", + description="MUSICAL SYMBOL DEGREE SLASH", + direction="l", + linebreak="al", + unicodeslot=0x1D1A9, + }, + [0x1D1AA]={ + category="mn", + description="MUSICAL SYMBOL COMBINING DOWN BOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D1AA, + }, + [0x1D1AB]={ + category="mn", + description="MUSICAL SYMBOL COMBINING UP BOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D1AB, + }, + [0x1D1AC]={ + category="mn", + description="MUSICAL SYMBOL COMBINING HARMONIC", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D1AC, + }, + [0x1D1AD]={ + category="mn", + description="MUSICAL SYMBOL COMBINING SNAP PIZZICATO", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D1AD, + }, + [0x1D1AE]={ + category="so", + description="MUSICAL SYMBOL PEDAL MARK", + direction="l", + linebreak="al", + unicodeslot=0x1D1AE, + }, + [0x1D1AF]={ + category="so", + description="MUSICAL SYMBOL PEDAL UP MARK", + direction="l", + linebreak="al", + unicodeslot=0x1D1AF, + }, + [0x1D1B0]={ + category="so", + description="MUSICAL SYMBOL HALF PEDAL MARK", + direction="l", + linebreak="al", + unicodeslot=0x1D1B0, + }, + [0x1D1B1]={ + category="so", + description="MUSICAL SYMBOL GLISSANDO UP", + direction="l", + linebreak="al", + unicodeslot=0x1D1B1, + }, + [0x1D1B2]={ + category="so", + description="MUSICAL SYMBOL GLISSANDO DOWN", + direction="l", + linebreak="al", + unicodeslot=0x1D1B2, + }, + [0x1D1B3]={ + category="so", + description="MUSICAL SYMBOL WITH FINGERNAILS", + direction="l", + linebreak="al", + unicodeslot=0x1D1B3, + }, + [0x1D1B4]={ + category="so", + description="MUSICAL SYMBOL DAMP", + direction="l", + linebreak="al", + unicodeslot=0x1D1B4, + }, + [0x1D1B5]={ + category="so", + description="MUSICAL SYMBOL DAMP ALL", + direction="l", + linebreak="al", + unicodeslot=0x1D1B5, + }, + [0x1D1B6]={ + category="so", + description="MUSICAL SYMBOL MAXIMA", + direction="l", + linebreak="al", + unicodeslot=0x1D1B6, + }, + [0x1D1B7]={ + category="so", + description="MUSICAL SYMBOL LONGA", + direction="l", + linebreak="al", + unicodeslot=0x1D1B7, + }, + [0x1D1B8]={ + category="so", + description="MUSICAL SYMBOL BREVIS", + direction="l", + linebreak="al", + unicodeslot=0x1D1B8, + }, + [0x1D1B9]={ + category="so", + description="MUSICAL SYMBOL SEMIBREVIS WHITE", + direction="l", + linebreak="al", + unicodeslot=0x1D1B9, + }, + [0x1D1BA]={ + category="so", + description="MUSICAL SYMBOL SEMIBREVIS BLACK", + direction="l", + linebreak="al", + unicodeslot=0x1D1BA, + }, + [0x1D1BB]={ + category="so", + description="MUSICAL SYMBOL MINIMA", + direction="l", + linebreak="al", + specials={ "char", 0x1D1B9, 0x1D165 }, + unicodeslot=0x1D1BB, + }, + [0x1D1BC]={ + category="so", + description="MUSICAL SYMBOL MINIMA BLACK", + direction="l", + linebreak="al", + specials={ "char", 0x1D1BA, 0x1D165 }, + unicodeslot=0x1D1BC, + }, + [0x1D1BD]={ + category="so", + description="MUSICAL SYMBOL SEMIMINIMA WHITE", + direction="l", + linebreak="al", + specials={ "char", 0x1D1BB, 0x1D16E }, + unicodeslot=0x1D1BD, + }, + [0x1D1BE]={ + category="so", + description="MUSICAL SYMBOL SEMIMINIMA BLACK", + direction="l", + linebreak="al", + specials={ "char", 0x1D1BC, 0x1D16E }, + unicodeslot=0x1D1BE, + }, + [0x1D1BF]={ + category="so", + description="MUSICAL SYMBOL FUSA WHITE", + direction="l", + linebreak="al", + specials={ "char", 0x1D1BB, 0x1D16F }, + unicodeslot=0x1D1BF, + }, + [0x1D1C0]={ + category="so", + description="MUSICAL SYMBOL FUSA BLACK", + direction="l", + linebreak="al", + specials={ "char", 0x1D1BC, 0x1D16F }, + unicodeslot=0x1D1C0, + }, + [0x1D1C1]={ + category="so", + description="MUSICAL SYMBOL LONGA PERFECTA REST", + direction="l", + linebreak="al", + unicodeslot=0x1D1C1, + }, + [0x1D1C2]={ + category="so", + description="MUSICAL SYMBOL LONGA IMPERFECTA REST", + direction="l", + linebreak="al", + unicodeslot=0x1D1C2, + }, + [0x1D1C3]={ + category="so", + description="MUSICAL SYMBOL BREVIS REST", + direction="l", + linebreak="al", + unicodeslot=0x1D1C3, + }, + [0x1D1C4]={ + category="so", + description="MUSICAL SYMBOL SEMIBREVIS REST", + direction="l", + linebreak="al", + unicodeslot=0x1D1C4, + }, + [0x1D1C5]={ + category="so", + description="MUSICAL SYMBOL MINIMA REST", + direction="l", + linebreak="al", + unicodeslot=0x1D1C5, + }, + [0x1D1C6]={ + category="so", + description="MUSICAL SYMBOL SEMIMINIMA REST", + direction="l", + linebreak="al", + unicodeslot=0x1D1C6, + }, + [0x1D1C7]={ + category="so", + description="MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA", + direction="l", + linebreak="al", + unicodeslot=0x1D1C7, + }, + [0x1D1C8]={ + category="so", + description="MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE IMPERFECTA", + direction="l", + linebreak="al", + unicodeslot=0x1D1C8, + }, + [0x1D1C9]={ + category="so", + description="MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA DIMINUTION-0x0001", + direction="l", + linebreak="al", + unicodeslot=0x1D1C9, + }, + [0x1D1CA]={ + category="so", + description="MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE PERFECTA", + direction="l", + linebreak="al", + unicodeslot=0x1D1CA, + }, + [0x1D1CB]={ + category="so", + description="MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA", + direction="l", + linebreak="al", + unicodeslot=0x1D1CB, + }, + [0x1D1CC]={ + category="so", + description="MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-0x0001", + direction="l", + linebreak="al", + unicodeslot=0x1D1CC, + }, + [0x1D1CD]={ + category="so", + description="MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-0x0002", + direction="l", + linebreak="al", + unicodeslot=0x1D1CD, + }, + [0x1D1CE]={ + category="so", + description="MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-0x0003", + direction="l", + linebreak="al", + unicodeslot=0x1D1CE, + }, + [0x1D1CF]={ + category="so", + description="MUSICAL SYMBOL CROIX", + direction="l", + linebreak="al", + unicodeslot=0x1D1CF, + }, + [0x1D1D0]={ + category="so", + description="MUSICAL SYMBOL GREGORIAN C CLEF", + direction="l", + linebreak="al", + unicodeslot=0x1D1D0, + }, + [0x1D1D1]={ + category="so", + description="MUSICAL SYMBOL GREGORIAN F CLEF", + direction="l", + linebreak="al", + unicodeslot=0x1D1D1, + }, + [0x1D1D2]={ + category="so", + description="MUSICAL SYMBOL SQUARE B", + direction="l", + linebreak="al", + unicodeslot=0x1D1D2, + }, + [0x1D1D3]={ + category="so", + description="MUSICAL SYMBOL VIRGA", + direction="l", + linebreak="al", + unicodeslot=0x1D1D3, + }, + [0x1D1D4]={ + category="so", + description="MUSICAL SYMBOL PODATUS", + direction="l", + linebreak="al", + unicodeslot=0x1D1D4, + }, + [0x1D1D5]={ + category="so", + description="MUSICAL SYMBOL CLIVIS", + direction="l", + linebreak="al", + unicodeslot=0x1D1D5, + }, + [0x1D1D6]={ + category="so", + description="MUSICAL SYMBOL SCANDICUS", + direction="l", + linebreak="al", + unicodeslot=0x1D1D6, + }, + [0x1D1D7]={ + category="so", + description="MUSICAL SYMBOL CLIMACUS", + direction="l", + linebreak="al", + unicodeslot=0x1D1D7, + }, + [0x1D1D8]={ + category="so", + description="MUSICAL SYMBOL TORCULUS", + direction="l", + linebreak="al", + unicodeslot=0x1D1D8, + }, + [0x1D1D9]={ + category="so", + description="MUSICAL SYMBOL PORRECTUS", + direction="l", + linebreak="al", + unicodeslot=0x1D1D9, + }, + [0x1D1DA]={ + category="so", + description="MUSICAL SYMBOL PORRECTUS FLEXUS", + direction="l", + linebreak="al", + unicodeslot=0x1D1DA, + }, + [0x1D1DB]={ + category="so", + description="MUSICAL SYMBOL SCANDICUS FLEXUS", + direction="l", + linebreak="al", + unicodeslot=0x1D1DB, + }, + [0x1D1DC]={ + category="so", + description="MUSICAL SYMBOL TORCULUS RESUPINUS", + direction="l", + linebreak="al", + unicodeslot=0x1D1DC, + }, + [0x1D1DD]={ + category="so", + description="MUSICAL SYMBOL PES SUBPUNCTIS", + direction="l", + linebreak="al", + unicodeslot=0x1D1DD, + }, + [0x1D200]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x0001", + direction="on", + linebreak="al", + unicodeslot=0x1D200, + }, + [0x1D201]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x0002", + direction="on", + linebreak="al", + unicodeslot=0x1D201, + }, + [0x1D202]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x0003", + direction="on", + linebreak="al", + unicodeslot=0x1D202, + }, + [0x1D203]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x0004", + direction="on", + linebreak="al", + unicodeslot=0x1D203, + }, + [0x1D204]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x0005", + direction="on", + linebreak="al", + unicodeslot=0x1D204, + }, + [0x1D205]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x0006", + direction="on", + linebreak="al", + unicodeslot=0x1D205, + }, + [0x1D206]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x0007", + direction="on", + linebreak="al", + unicodeslot=0x1D206, + }, + [0x1D207]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x0008", + direction="on", + linebreak="al", + unicodeslot=0x1D207, + }, + [0x1D208]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x0009", + direction="on", + linebreak="al", + unicodeslot=0x1D208, + }, + [0x1D209]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x000A", + direction="on", + linebreak="al", + unicodeslot=0x1D209, + }, + [0x1D20A]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x000B", + direction="on", + linebreak="al", + unicodeslot=0x1D20A, + }, + [0x1D20B]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x000C", + direction="on", + linebreak="al", + unicodeslot=0x1D20B, + }, + [0x1D20C]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x000D", + direction="on", + linebreak="al", + unicodeslot=0x1D20C, + }, + [0x1D20D]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x000E", + direction="on", + linebreak="al", + unicodeslot=0x1D20D, + }, + [0x1D20E]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x000F", + direction="on", + linebreak="al", + unicodeslot=0x1D20E, + }, + [0x1D20F]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x0010", + direction="on", + linebreak="al", + unicodeslot=0x1D20F, + }, + [0x1D210]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x0011", + direction="on", + linebreak="al", + unicodeslot=0x1D210, + }, + [0x1D211]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x0012", + direction="on", + linebreak="al", + unicodeslot=0x1D211, + }, + [0x1D212]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x0013", + direction="on", + linebreak="al", + unicodeslot=0x1D212, + }, + [0x1D213]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x0014", + direction="on", + linebreak="al", + unicodeslot=0x1D213, + }, + [0x1D214]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x0015", + direction="on", + linebreak="al", + unicodeslot=0x1D214, + }, + [0x1D215]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x0016", + direction="on", + linebreak="al", + unicodeslot=0x1D215, + }, + [0x1D216]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x0017", + direction="on", + linebreak="al", + unicodeslot=0x1D216, + }, + [0x1D217]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x0018", + direction="on", + linebreak="al", + unicodeslot=0x1D217, + }, + [0x1D218]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x0032", + direction="on", + linebreak="al", + unicodeslot=0x1D218, + }, + [0x1D219]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x0033", + direction="on", + linebreak="al", + unicodeslot=0x1D219, + }, + [0x1D21A]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x0034", + direction="on", + linebreak="al", + unicodeslot=0x1D21A, + }, + [0x1D21B]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x0035", + direction="on", + linebreak="al", + unicodeslot=0x1D21B, + }, + [0x1D21C]={ + category="so", + description="GREEK VOCAL NOTATION SYMBOL-0x0036", + direction="on", + linebreak="al", + unicodeslot=0x1D21C, + }, + [0x1D21D]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0001", + direction="on", + linebreak="al", + unicodeslot=0x1D21D, + }, + [0x1D21E]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0002", + direction="on", + linebreak="al", + unicodeslot=0x1D21E, + }, + [0x1D21F]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0004", + direction="on", + linebreak="al", + unicodeslot=0x1D21F, + }, + [0x1D220]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0005", + direction="on", + linebreak="al", + unicodeslot=0x1D220, + }, + [0x1D221]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0007", + direction="on", + linebreak="al", + unicodeslot=0x1D221, + }, + [0x1D222]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0008", + direction="on", + linebreak="al", + unicodeslot=0x1D222, + }, + [0x1D223]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x000B", + direction="on", + linebreak="al", + unicodeslot=0x1D223, + }, + [0x1D224]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x000C", + direction="on", + linebreak="al", + unicodeslot=0x1D224, + }, + [0x1D225]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x000D", + direction="on", + linebreak="al", + unicodeslot=0x1D225, + }, + [0x1D226]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x000E", + direction="on", + linebreak="al", + unicodeslot=0x1D226, + }, + [0x1D227]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0011", + direction="on", + linebreak="al", + unicodeslot=0x1D227, + }, + [0x1D228]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0012", + direction="on", + linebreak="al", + unicodeslot=0x1D228, + }, + [0x1D229]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0013", + direction="on", + linebreak="al", + unicodeslot=0x1D229, + }, + [0x1D22A]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0017", + direction="on", + linebreak="al", + unicodeslot=0x1D22A, + }, + [0x1D22B]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0018", + direction="on", + linebreak="al", + unicodeslot=0x1D22B, + }, + [0x1D22C]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0019", + direction="on", + linebreak="al", + unicodeslot=0x1D22C, + }, + [0x1D22D]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x001A", + direction="on", + linebreak="al", + unicodeslot=0x1D22D, + }, + [0x1D22E]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x001B", + direction="on", + linebreak="al", + unicodeslot=0x1D22E, + }, + [0x1D22F]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x001D", + direction="on", + linebreak="al", + unicodeslot=0x1D22F, + }, + [0x1D230]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x001E", + direction="on", + linebreak="al", + unicodeslot=0x1D230, + }, + [0x1D231]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0020", + direction="on", + linebreak="al", + unicodeslot=0x1D231, + }, + [0x1D232]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0024", + direction="on", + linebreak="al", + unicodeslot=0x1D232, + }, + [0x1D233]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0025", + direction="on", + linebreak="al", + unicodeslot=0x1D233, + }, + [0x1D234]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0026", + direction="on", + linebreak="al", + unicodeslot=0x1D234, + }, + [0x1D235]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0027", + direction="on", + linebreak="al", + unicodeslot=0x1D235, + }, + [0x1D236]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0028", + direction="on", + linebreak="al", + unicodeslot=0x1D236, + }, + [0x1D237]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x002A", + direction="on", + linebreak="al", + unicodeslot=0x1D237, + }, + [0x1D238]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x002B", + direction="on", + linebreak="al", + unicodeslot=0x1D238, + }, + [0x1D239]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x002D", + direction="on", + linebreak="al", + unicodeslot=0x1D239, + }, + [0x1D23A]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x002F", + direction="on", + linebreak="al", + unicodeslot=0x1D23A, + }, + [0x1D23B]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0030", + direction="on", + linebreak="al", + unicodeslot=0x1D23B, + }, + [0x1D23C]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0031", + direction="on", + linebreak="al", + unicodeslot=0x1D23C, + }, + [0x1D23D]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0032", + direction="on", + linebreak="al", + unicodeslot=0x1D23D, + }, + [0x1D23E]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0033", + direction="on", + linebreak="al", + unicodeslot=0x1D23E, + }, + [0x1D23F]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0034", + direction="on", + linebreak="al", + unicodeslot=0x1D23F, + }, + [0x1D240]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0035", + direction="on", + linebreak="al", + unicodeslot=0x1D240, + }, + [0x1D241]={ + category="so", + description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0036", + direction="on", + linebreak="al", + unicodeslot=0x1D241, + }, + [0x1D242]={ + category="mn", + description="COMBINING GREEK MUSICAL TRISEME", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D242, + }, + [0x1D243]={ + category="mn", + description="COMBINING GREEK MUSICAL TETRASEME", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D243, + }, + [0x1D244]={ + category="mn", + description="COMBINING GREEK MUSICAL PENTASEME", + direction="nsm", + linebreak="cm", + unicodeslot=0x1D244, + }, + [0x1D245]={ + category="so", + description="GREEK MUSICAL LEIMMA", + direction="on", + linebreak="al", + unicodeslot=0x1D245, + }, + [0x1D300]={ + category="so", + description="MONOGRAM FOR EARTH", + direction="on", + linebreak="al", + unicodeslot=0x1D300, + }, + [0x1D301]={ + category="so", + description="DIGRAM FOR HEAVENLY EARTH", + direction="on", + linebreak="al", + unicodeslot=0x1D301, + }, + [0x1D302]={ + category="so", + description="DIGRAM FOR HUMAN EARTH", + direction="on", + linebreak="al", + unicodeslot=0x1D302, + }, + [0x1D303]={ + category="so", + description="DIGRAM FOR EARTHLY HEAVEN", + direction="on", + linebreak="al", + unicodeslot=0x1D303, + }, + [0x1D304]={ + category="so", + description="DIGRAM FOR EARTHLY HUMAN", + direction="on", + linebreak="al", + unicodeslot=0x1D304, + }, + [0x1D305]={ + category="so", + description="DIGRAM FOR EARTH", + direction="on", + linebreak="al", + unicodeslot=0x1D305, + }, + [0x1D306]={ + category="so", + description="TETRAGRAM FOR CENTRE", + direction="on", + linebreak="al", + unicodeslot=0x1D306, + }, + [0x1D307]={ + category="so", + description="TETRAGRAM FOR FULL CIRCLE", + direction="on", + linebreak="al", + unicodeslot=0x1D307, + }, + [0x1D308]={ + category="so", + description="TETRAGRAM FOR MIRED", + direction="on", + linebreak="al", + unicodeslot=0x1D308, + }, + [0x1D309]={ + category="so", + description="TETRAGRAM FOR BARRIER", + direction="on", + linebreak="al", + unicodeslot=0x1D309, + }, + [0x1D30A]={ + category="so", + description="TETRAGRAM FOR KEEPING SMALL", + direction="on", + linebreak="al", + unicodeslot=0x1D30A, + }, + [0x1D30B]={ + category="so", + description="TETRAGRAM FOR CONTRARIETY", + direction="on", + linebreak="al", + unicodeslot=0x1D30B, + }, + [0x1D30C]={ + category="so", + description="TETRAGRAM FOR ASCENT", + direction="on", + linebreak="al", + unicodeslot=0x1D30C, + }, + [0x1D30D]={ + category="so", + description="TETRAGRAM FOR OPPOSITION", + direction="on", + linebreak="al", + unicodeslot=0x1D30D, + }, + [0x1D30E]={ + category="so", + description="TETRAGRAM FOR BRANCHING OUT", + direction="on", + linebreak="al", + unicodeslot=0x1D30E, + }, + [0x1D30F]={ + category="so", + description="TETRAGRAM FOR DEFECTIVENESS OR DISTORTION", + direction="on", + linebreak="al", + unicodeslot=0x1D30F, + }, + [0x1D310]={ + category="so", + description="TETRAGRAM FOR DIVERGENCE", + direction="on", + linebreak="al", + unicodeslot=0x1D310, + }, + [0x1D311]={ + category="so", + description="TETRAGRAM FOR YOUTHFULNESS", + direction="on", + linebreak="al", + unicodeslot=0x1D311, + }, + [0x1D312]={ + category="so", + description="TETRAGRAM FOR INCREASE", + direction="on", + linebreak="al", + unicodeslot=0x1D312, + }, + [0x1D313]={ + category="so", + description="TETRAGRAM FOR PENETRATION", + direction="on", + linebreak="al", + unicodeslot=0x1D313, + }, + [0x1D314]={ + category="so", + description="TETRAGRAM FOR REACH", + direction="on", + linebreak="al", + unicodeslot=0x1D314, + }, + [0x1D315]={ + category="so", + description="TETRAGRAM FOR CONTACT", + direction="on", + linebreak="al", + unicodeslot=0x1D315, + }, + [0x1D316]={ + category="so", + description="TETRAGRAM FOR HOLDING BACK", + direction="on", + linebreak="al", + unicodeslot=0x1D316, + }, + [0x1D317]={ + category="so", + description="TETRAGRAM FOR WAITING", + direction="on", + linebreak="al", + unicodeslot=0x1D317, + }, + [0x1D318]={ + category="so", + description="TETRAGRAM FOR FOLLOWING", + direction="on", + linebreak="al", + unicodeslot=0x1D318, + }, + [0x1D319]={ + category="so", + description="TETRAGRAM FOR ADVANCE", + direction="on", + linebreak="al", + unicodeslot=0x1D319, + }, + [0x1D31A]={ + category="so", + description="TETRAGRAM FOR RELEASE", + direction="on", + linebreak="al", + unicodeslot=0x1D31A, + }, + [0x1D31B]={ + category="so", + description="TETRAGRAM FOR RESISTANCE", + direction="on", + linebreak="al", + unicodeslot=0x1D31B, + }, + [0x1D31C]={ + category="so", + description="TETRAGRAM FOR EASE", + direction="on", + linebreak="al", + unicodeslot=0x1D31C, + }, + [0x1D31D]={ + category="so", + description="TETRAGRAM FOR JOY", + direction="on", + linebreak="al", + unicodeslot=0x1D31D, + }, + [0x1D31E]={ + category="so", + description="TETRAGRAM FOR CONTENTION", + direction="on", + linebreak="al", + unicodeslot=0x1D31E, + }, + [0x1D31F]={ + category="so", + description="TETRAGRAM FOR ENDEAVOUR", + direction="on", + linebreak="al", + unicodeslot=0x1D31F, + }, + [0x1D320]={ + category="so", + description="TETRAGRAM FOR DUTIES", + direction="on", + linebreak="al", + unicodeslot=0x1D320, + }, + [0x1D321]={ + category="so", + description="TETRAGRAM FOR CHANGE", + direction="on", + linebreak="al", + unicodeslot=0x1D321, + }, + [0x1D322]={ + category="so", + description="TETRAGRAM FOR DECISIVENESS", + direction="on", + linebreak="al", + unicodeslot=0x1D322, + }, + [0x1D323]={ + category="so", + description="TETRAGRAM FOR BOLD RESOLUTION", + direction="on", + linebreak="al", + unicodeslot=0x1D323, + }, + [0x1D324]={ + category="so", + description="TETRAGRAM FOR PACKING", + direction="on", + linebreak="al", + unicodeslot=0x1D324, + }, + [0x1D325]={ + category="so", + description="TETRAGRAM FOR LEGION", + direction="on", + linebreak="al", + unicodeslot=0x1D325, + }, + [0x1D326]={ + category="so", + description="TETRAGRAM FOR CLOSENESS", + direction="on", + linebreak="al", + unicodeslot=0x1D326, + }, + [0x1D327]={ + category="so", + description="TETRAGRAM FOR KINSHIP", + direction="on", + linebreak="al", + unicodeslot=0x1D327, + }, + [0x1D328]={ + category="so", + description="TETRAGRAM FOR GATHERING", + direction="on", + linebreak="al", + unicodeslot=0x1D328, + }, + [0x1D329]={ + category="so", + description="TETRAGRAM FOR STRENGTH", + direction="on", + linebreak="al", + unicodeslot=0x1D329, + }, + [0x1D32A]={ + category="so", + description="TETRAGRAM FOR PURITY", + direction="on", + linebreak="al", + unicodeslot=0x1D32A, + }, + [0x1D32B]={ + category="so", + description="TETRAGRAM FOR FULLNESS", + direction="on", + linebreak="al", + unicodeslot=0x1D32B, + }, + [0x1D32C]={ + category="so", + description="TETRAGRAM FOR RESIDENCE", + direction="on", + linebreak="al", + unicodeslot=0x1D32C, + }, + [0x1D32D]={ + category="so", + description="TETRAGRAM FOR LAW OR MODEL", + direction="on", + linebreak="al", + unicodeslot=0x1D32D, + }, + [0x1D32E]={ + category="so", + description="TETRAGRAM FOR RESPONSE", + direction="on", + linebreak="al", + unicodeslot=0x1D32E, + }, + [0x1D32F]={ + category="so", + description="TETRAGRAM FOR GOING TO MEET", + direction="on", + linebreak="al", + unicodeslot=0x1D32F, + }, + [0x1D330]={ + category="so", + description="TETRAGRAM FOR ENCOUNTERS", + direction="on", + linebreak="al", + unicodeslot=0x1D330, + }, + [0x1D331]={ + category="so", + description="TETRAGRAM FOR STOVE", + direction="on", + linebreak="al", + unicodeslot=0x1D331, + }, + [0x1D332]={ + category="so", + description="TETRAGRAM FOR GREATNESS", + direction="on", + linebreak="al", + unicodeslot=0x1D332, + }, + [0x1D333]={ + category="so", + description="TETRAGRAM FOR ENLARGEMENT", + direction="on", + linebreak="al", + unicodeslot=0x1D333, + }, + [0x1D334]={ + category="so", + description="TETRAGRAM FOR PATTERN", + direction="on", + linebreak="al", + unicodeslot=0x1D334, + }, + [0x1D335]={ + category="so", + description="TETRAGRAM FOR RITUAL", + direction="on", + linebreak="al", + unicodeslot=0x1D335, + }, + [0x1D336]={ + category="so", + description="TETRAGRAM FOR FLIGHT", + direction="on", + linebreak="al", + unicodeslot=0x1D336, + }, + [0x1D337]={ + category="so", + description="TETRAGRAM FOR VASTNESS OR WASTING", + direction="on", + linebreak="al", + unicodeslot=0x1D337, + }, + [0x1D338]={ + category="so", + description="TETRAGRAM FOR CONSTANCY", + direction="on", + linebreak="al", + unicodeslot=0x1D338, + }, + [0x1D339]={ + category="so", + description="TETRAGRAM FOR MEASURE", + direction="on", + linebreak="al", + unicodeslot=0x1D339, + }, + [0x1D33A]={ + category="so", + description="TETRAGRAM FOR ETERNITY", + direction="on", + linebreak="al", + unicodeslot=0x1D33A, + }, + [0x1D33B]={ + category="so", + description="TETRAGRAM FOR UNITY", + direction="on", + linebreak="al", + unicodeslot=0x1D33B, + }, + [0x1D33C]={ + category="so", + description="TETRAGRAM FOR DIMINISHMENT", + direction="on", + linebreak="al", + unicodeslot=0x1D33C, + }, + [0x1D33D]={ + category="so", + description="TETRAGRAM FOR CLOSED MOUTH", + direction="on", + linebreak="al", + unicodeslot=0x1D33D, + }, + [0x1D33E]={ + category="so", + description="TETRAGRAM FOR GUARDEDNESS", + direction="on", + linebreak="al", + unicodeslot=0x1D33E, + }, + [0x1D33F]={ + category="so", + description="TETRAGRAM FOR GATHERING IN", + direction="on", + linebreak="al", + unicodeslot=0x1D33F, + }, + [0x1D340]={ + category="so", + description="TETRAGRAM FOR MASSING", + direction="on", + linebreak="al", + unicodeslot=0x1D340, + }, + [0x1D341]={ + category="so", + description="TETRAGRAM FOR ACCUMULATION", + direction="on", + linebreak="al", + unicodeslot=0x1D341, + }, + [0x1D342]={ + category="so", + description="TETRAGRAM FOR EMBELLISHMENT", + direction="on", + linebreak="al", + unicodeslot=0x1D342, + }, + [0x1D343]={ + category="so", + description="TETRAGRAM FOR DOUBT", + direction="on", + linebreak="al", + unicodeslot=0x1D343, + }, + [0x1D344]={ + category="so", + description="TETRAGRAM FOR WATCH", + direction="on", + linebreak="al", + unicodeslot=0x1D344, + }, + [0x1D345]={ + category="so", + description="TETRAGRAM FOR SINKING", + direction="on", + linebreak="al", + unicodeslot=0x1D345, + }, + [0x1D346]={ + category="so", + description="TETRAGRAM FOR INNER", + direction="on", + linebreak="al", + unicodeslot=0x1D346, + }, + [0x1D347]={ + category="so", + description="TETRAGRAM FOR DEPARTURE", + direction="on", + linebreak="al", + unicodeslot=0x1D347, + }, + [0x1D348]={ + category="so", + description="TETRAGRAM FOR DARKENING", + direction="on", + linebreak="al", + unicodeslot=0x1D348, + }, + [0x1D349]={ + category="so", + description="TETRAGRAM FOR DIMMING", + direction="on", + linebreak="al", + unicodeslot=0x1D349, + }, + [0x1D34A]={ + category="so", + description="TETRAGRAM FOR EXHAUSTION", + direction="on", + linebreak="al", + unicodeslot=0x1D34A, + }, + [0x1D34B]={ + category="so", + description="TETRAGRAM FOR SEVERANCE", + direction="on", + linebreak="al", + unicodeslot=0x1D34B, + }, + [0x1D34C]={ + category="so", + description="TETRAGRAM FOR STOPPAGE", + direction="on", + linebreak="al", + unicodeslot=0x1D34C, + }, + [0x1D34D]={ + category="so", + description="TETRAGRAM FOR HARDNESS", + direction="on", + linebreak="al", + unicodeslot=0x1D34D, + }, + [0x1D34E]={ + category="so", + description="TETRAGRAM FOR COMPLETION", + direction="on", + linebreak="al", + unicodeslot=0x1D34E, + }, + [0x1D34F]={ + category="so", + description="TETRAGRAM FOR CLOSURE", + direction="on", + linebreak="al", + unicodeslot=0x1D34F, + }, + [0x1D350]={ + category="so", + description="TETRAGRAM FOR FAILURE", + direction="on", + linebreak="al", + unicodeslot=0x1D350, + }, + [0x1D351]={ + category="so", + description="TETRAGRAM FOR AGGRAVATION", + direction="on", + linebreak="al", + unicodeslot=0x1D351, + }, + [0x1D352]={ + category="so", + description="TETRAGRAM FOR COMPLIANCE", + direction="on", + linebreak="al", + unicodeslot=0x1D352, + }, + [0x1D353]={ + category="so", + description="TETRAGRAM FOR ON THE VERGE", + direction="on", + linebreak="al", + unicodeslot=0x1D353, + }, + [0x1D354]={ + category="so", + description="TETRAGRAM FOR DIFFICULTIES", + direction="on", + linebreak="al", + unicodeslot=0x1D354, + }, + [0x1D355]={ + category="so", + description="TETRAGRAM FOR LABOURING", + direction="on", + linebreak="al", + unicodeslot=0x1D355, + }, + [0x1D356]={ + category="so", + description="TETRAGRAM FOR FOSTERING", + direction="on", + linebreak="al", + unicodeslot=0x1D356, + }, + [0x1D360]={ + category="no", + description="COUNTING ROD UNIT DIGIT ONE", + direction="l", + linebreak="al", + unicodeslot=0x1D360, + }, + [0x1D361]={ + category="no", + description="COUNTING ROD UNIT DIGIT TWO", + direction="l", + linebreak="al", + unicodeslot=0x1D361, + }, + [0x1D362]={ + category="no", + description="COUNTING ROD UNIT DIGIT THREE", + direction="l", + linebreak="al", + unicodeslot=0x1D362, + }, + [0x1D363]={ + category="no", + description="COUNTING ROD UNIT DIGIT FOUR", + direction="l", + linebreak="al", + unicodeslot=0x1D363, + }, + [0x1D364]={ + category="no", + description="COUNTING ROD UNIT DIGIT FIVE", + direction="l", + linebreak="al", + unicodeslot=0x1D364, + }, + [0x1D365]={ + category="no", + description="COUNTING ROD UNIT DIGIT SIX", + direction="l", + linebreak="al", + unicodeslot=0x1D365, + }, + [0x1D366]={ + category="no", + description="COUNTING ROD UNIT DIGIT SEVEN", + direction="l", + linebreak="al", + unicodeslot=0x1D366, + }, + [0x1D367]={ + category="no", + description="COUNTING ROD UNIT DIGIT EIGHT", + direction="l", + linebreak="al", + unicodeslot=0x1D367, + }, + [0x1D368]={ + category="no", + description="COUNTING ROD UNIT DIGIT NINE", + direction="l", + linebreak="al", + unicodeslot=0x1D368, + }, + [0x1D369]={ + category="no", + description="COUNTING ROD TENS DIGIT ONE", + direction="l", + linebreak="al", + unicodeslot=0x1D369, + }, + [0x1D36A]={ + category="no", + description="COUNTING ROD TENS DIGIT TWO", + direction="l", + linebreak="al", + unicodeslot=0x1D36A, + }, + [0x1D36B]={ + category="no", + description="COUNTING ROD TENS DIGIT THREE", + direction="l", + linebreak="al", + unicodeslot=0x1D36B, + }, + [0x1D36C]={ + category="no", + description="COUNTING ROD TENS DIGIT FOUR", + direction="l", + linebreak="al", + unicodeslot=0x1D36C, + }, + [0x1D36D]={ + category="no", + description="COUNTING ROD TENS DIGIT FIVE", + direction="l", + linebreak="al", + unicodeslot=0x1D36D, + }, + [0x1D36E]={ + category="no", + description="COUNTING ROD TENS DIGIT SIX", + direction="l", + linebreak="al", + unicodeslot=0x1D36E, + }, + [0x1D36F]={ + category="no", + description="COUNTING ROD TENS DIGIT SEVEN", + direction="l", + linebreak="al", + unicodeslot=0x1D36F, + }, + [0x1D370]={ + category="no", + description="COUNTING ROD TENS DIGIT EIGHT", + direction="l", + linebreak="al", + unicodeslot=0x1D370, + }, + [0x1D371]={ + category="no", + description="COUNTING ROD TENS DIGIT NINE", + direction="l", + linebreak="al", + unicodeslot=0x1D371, + }, + [0x1D400]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL A", + direction="l", + linebreak="al", + specials={ "font", 0x0041 }, + unicodeslot=0x1D400, + }, + [0x1D401]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL B", + direction="l", + linebreak="al", + specials={ "font", 0x0042 }, + unicodeslot=0x1D401, + }, + [0x1D402]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL C", + direction="l", + linebreak="al", + specials={ "font", 0x0043 }, + unicodeslot=0x1D402, + }, + [0x1D403]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL D", + direction="l", + linebreak="al", + specials={ "font", 0x0044 }, + unicodeslot=0x1D403, + }, + [0x1D404]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL E", + direction="l", + linebreak="al", + specials={ "font", 0x0045 }, + unicodeslot=0x1D404, + }, + [0x1D405]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL F", + direction="l", + linebreak="al", + specials={ "font", 0x0046 }, + unicodeslot=0x1D405, + }, + [0x1D406]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL G", + direction="l", + linebreak="al", + specials={ "font", 0x0047 }, + unicodeslot=0x1D406, + }, + [0x1D407]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL H", + direction="l", + linebreak="al", + specials={ "font", 0x0048 }, + unicodeslot=0x1D407, + }, + [0x1D408]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL I", + direction="l", + linebreak="al", + specials={ "font", 0x0049 }, + unicodeslot=0x1D408, + }, + [0x1D409]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL J", + direction="l", + linebreak="al", + specials={ "font", 0x004A }, + unicodeslot=0x1D409, + }, + [0x1D40A]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL K", + direction="l", + linebreak="al", + specials={ "font", 0x004B }, + unicodeslot=0x1D40A, + }, + [0x1D40B]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL L", + direction="l", + linebreak="al", + specials={ "font", 0x004C }, + unicodeslot=0x1D40B, + }, + [0x1D40C]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL M", + direction="l", + linebreak="al", + specials={ "font", 0x004D }, + unicodeslot=0x1D40C, + }, + [0x1D40D]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL N", + direction="l", + linebreak="al", + specials={ "font", 0x004E }, + unicodeslot=0x1D40D, + }, + [0x1D40E]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL O", + direction="l", + linebreak="al", + specials={ "font", 0x004F }, + unicodeslot=0x1D40E, + }, + [0x1D40F]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL P", + direction="l", + linebreak="al", + specials={ "font", 0x0050 }, + unicodeslot=0x1D40F, + }, + [0x1D410]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0051 }, + unicodeslot=0x1D410, + }, + [0x1D411]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL R", + direction="l", + linebreak="al", + specials={ "font", 0x0052 }, + unicodeslot=0x1D411, + }, + [0x1D412]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL S", + direction="l", + linebreak="al", + specials={ "font", 0x0053 }, + unicodeslot=0x1D412, + }, + [0x1D413]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL T", + direction="l", + linebreak="al", + specials={ "font", 0x0054 }, + unicodeslot=0x1D413, + }, + [0x1D414]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL U", + direction="l", + linebreak="al", + specials={ "font", 0x0055 }, + unicodeslot=0x1D414, + }, + [0x1D415]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL V", + direction="l", + linebreak="al", + specials={ "font", 0x0056 }, + unicodeslot=0x1D415, + }, + [0x1D416]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL W", + direction="l", + linebreak="al", + specials={ "font", 0x0057 }, + unicodeslot=0x1D416, + }, + [0x1D417]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL X", + direction="l", + linebreak="al", + specials={ "font", 0x0058 }, + unicodeslot=0x1D417, + }, + [0x1D418]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0059 }, + unicodeslot=0x1D418, + }, + [0x1D419]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL Z", + direction="l", + linebreak="al", + specials={ "font", 0x005A }, + unicodeslot=0x1D419, + }, + [0x1D41A]={ + category="ll", + description="MATHEMATICAL BOLD SMALL A", + direction="l", + linebreak="al", + specials={ "font", 0x0061 }, + unicodeslot=0x1D41A, + }, + [0x1D41B]={ + category="ll", + description="MATHEMATICAL BOLD SMALL B", + direction="l", + linebreak="al", + specials={ "font", 0x0062 }, + unicodeslot=0x1D41B, + }, + [0x1D41C]={ + category="ll", + description="MATHEMATICAL BOLD SMALL C", + direction="l", + linebreak="al", + specials={ "font", 0x0063 }, + unicodeslot=0x1D41C, + }, + [0x1D41D]={ + category="ll", + description="MATHEMATICAL BOLD SMALL D", + direction="l", + linebreak="al", + specials={ "font", 0x0064 }, + unicodeslot=0x1D41D, + }, + [0x1D41E]={ + category="ll", + description="MATHEMATICAL BOLD SMALL E", + direction="l", + linebreak="al", + specials={ "font", 0x0065 }, + unicodeslot=0x1D41E, + }, + [0x1D41F]={ + category="ll", + description="MATHEMATICAL BOLD SMALL F", + direction="l", + linebreak="al", + specials={ "font", 0x0066 }, + unicodeslot=0x1D41F, + }, + [0x1D420]={ + category="ll", + description="MATHEMATICAL BOLD SMALL G", + direction="l", + linebreak="al", + specials={ "font", 0x0067 }, + unicodeslot=0x1D420, + }, + [0x1D421]={ + category="ll", + description="MATHEMATICAL BOLD SMALL H", + direction="l", + linebreak="al", + specials={ "font", 0x0068 }, + unicodeslot=0x1D421, + }, + [0x1D422]={ + category="ll", + description="MATHEMATICAL BOLD SMALL I", + direction="l", + linebreak="al", + specials={ "font", 0x0069 }, + unicodeslot=0x1D422, + }, + [0x1D423]={ + category="ll", + description="MATHEMATICAL BOLD SMALL J", + direction="l", + linebreak="al", + specials={ "font", 0x006A }, + unicodeslot=0x1D423, + }, + [0x1D424]={ + category="ll", + description="MATHEMATICAL BOLD SMALL K", + direction="l", + linebreak="al", + specials={ "font", 0x006B }, + unicodeslot=0x1D424, + }, + [0x1D425]={ + category="ll", + description="MATHEMATICAL BOLD SMALL L", + direction="l", + linebreak="al", + specials={ "font", 0x006C }, + unicodeslot=0x1D425, + }, + [0x1D426]={ + category="ll", + description="MATHEMATICAL BOLD SMALL M", + direction="l", + linebreak="al", + specials={ "font", 0x006D }, + unicodeslot=0x1D426, + }, + [0x1D427]={ + category="ll", + description="MATHEMATICAL BOLD SMALL N", + direction="l", + linebreak="al", + specials={ "font", 0x006E }, + unicodeslot=0x1D427, + }, + [0x1D428]={ + category="ll", + description="MATHEMATICAL BOLD SMALL O", + direction="l", + linebreak="al", + specials={ "font", 0x006F }, + unicodeslot=0x1D428, + }, + [0x1D429]={ + category="ll", + description="MATHEMATICAL BOLD SMALL P", + direction="l", + linebreak="al", + specials={ "font", 0x0070 }, + unicodeslot=0x1D429, + }, + [0x1D42A]={ + category="ll", + description="MATHEMATICAL BOLD SMALL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0071 }, + unicodeslot=0x1D42A, + }, + [0x1D42B]={ + category="ll", + description="MATHEMATICAL BOLD SMALL R", + direction="l", + linebreak="al", + specials={ "font", 0x0072 }, + unicodeslot=0x1D42B, + }, + [0x1D42C]={ + category="ll", + description="MATHEMATICAL BOLD SMALL S", + direction="l", + linebreak="al", + specials={ "font", 0x0073 }, + unicodeslot=0x1D42C, + }, + [0x1D42D]={ + category="ll", + description="MATHEMATICAL BOLD SMALL T", + direction="l", + linebreak="al", + specials={ "font", 0x0074 }, + unicodeslot=0x1D42D, + }, + [0x1D42E]={ + category="ll", + description="MATHEMATICAL BOLD SMALL U", + direction="l", + linebreak="al", + specials={ "font", 0x0075 }, + unicodeslot=0x1D42E, + }, + [0x1D42F]={ + category="ll", + description="MATHEMATICAL BOLD SMALL V", + direction="l", + linebreak="al", + specials={ "font", 0x0076 }, + unicodeslot=0x1D42F, + }, + [0x1D430]={ + category="ll", + description="MATHEMATICAL BOLD SMALL W", + direction="l", + linebreak="al", + specials={ "font", 0x0077 }, + unicodeslot=0x1D430, + }, + [0x1D431]={ + category="ll", + description="MATHEMATICAL BOLD SMALL X", + direction="l", + linebreak="al", + specials={ "font", 0x0078 }, + unicodeslot=0x1D431, + }, + [0x1D432]={ + category="ll", + description="MATHEMATICAL BOLD SMALL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0079 }, + unicodeslot=0x1D432, + }, + [0x1D433]={ + category="ll", + description="MATHEMATICAL BOLD SMALL Z", + direction="l", + linebreak="al", + specials={ "font", 0x007A }, + unicodeslot=0x1D433, + }, + [0x1D434]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL A", + direction="l", + linebreak="al", + specials={ "font", 0x0041 }, + unicodeslot=0x1D434, + }, + [0x1D435]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL B", + direction="l", + linebreak="al", + specials={ "font", 0x0042 }, + unicodeslot=0x1D435, + }, + [0x1D436]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL C", + direction="l", + linebreak="al", + specials={ "font", 0x0043 }, + unicodeslot=0x1D436, + }, + [0x1D437]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL D", + direction="l", + linebreak="al", + specials={ "font", 0x0044 }, + unicodeslot=0x1D437, + }, + [0x1D438]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL E", + direction="l", + linebreak="al", + specials={ "font", 0x0045 }, + unicodeslot=0x1D438, + }, + [0x1D439]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL F", + direction="l", + linebreak="al", + specials={ "font", 0x0046 }, + unicodeslot=0x1D439, + }, + [0x1D43A]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL G", + direction="l", + linebreak="al", + specials={ "font", 0x0047 }, + unicodeslot=0x1D43A, + }, + [0x1D43B]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL H", + direction="l", + linebreak="al", + specials={ "font", 0x0048 }, + unicodeslot=0x1D43B, + }, + [0x1D43C]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL I", + direction="l", + linebreak="al", + specials={ "font", 0x0049 }, + unicodeslot=0x1D43C, + }, + [0x1D43D]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL J", + direction="l", + linebreak="al", + specials={ "font", 0x004A }, + unicodeslot=0x1D43D, + }, + [0x1D43E]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL K", + direction="l", + linebreak="al", + specials={ "font", 0x004B }, + unicodeslot=0x1D43E, + }, + [0x1D43F]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL L", + direction="l", + linebreak="al", + specials={ "font", 0x004C }, + unicodeslot=0x1D43F, + }, + [0x1D440]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL M", + direction="l", + linebreak="al", + specials={ "font", 0x004D }, + unicodeslot=0x1D440, + }, + [0x1D441]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL N", + direction="l", + linebreak="al", + specials={ "font", 0x004E }, + unicodeslot=0x1D441, + }, + [0x1D442]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL O", + direction="l", + linebreak="al", + specials={ "font", 0x004F }, + unicodeslot=0x1D442, + }, + [0x1D443]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL P", + direction="l", + linebreak="al", + specials={ "font", 0x0050 }, + unicodeslot=0x1D443, + }, + [0x1D444]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0051 }, + unicodeslot=0x1D444, + }, + [0x1D445]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL R", + direction="l", + linebreak="al", + specials={ "font", 0x0052 }, + unicodeslot=0x1D445, + }, + [0x1D446]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL S", + direction="l", + linebreak="al", + specials={ "font", 0x0053 }, + unicodeslot=0x1D446, + }, + [0x1D447]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL T", + direction="l", + linebreak="al", + specials={ "font", 0x0054 }, + unicodeslot=0x1D447, + }, + [0x1D448]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL U", + direction="l", + linebreak="al", + specials={ "font", 0x0055 }, + unicodeslot=0x1D448, + }, + [0x1D449]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL V", + direction="l", + linebreak="al", +--mathclass="variable", + specials={ "font", 0x0056 }, + unicodeslot=0x1D449, + }, + [0x1D44A]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL W", + direction="l", + linebreak="al", + specials={ "font", 0x0057 }, + unicodeslot=0x1D44A, + }, + [0x1D44B]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL X", + direction="l", + linebreak="al", + specials={ "font", 0x0058 }, + unicodeslot=0x1D44B, + }, + [0x1D44C]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0059 }, + unicodeslot=0x1D44C, + }, + [0x1D44D]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL Z", + direction="l", + linebreak="al", + specials={ "font", 0x005A }, + unicodeslot=0x1D44D, + }, + [0x1D44E]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL A", + direction="l", + linebreak="al", + specials={ "font", 0x0061 }, + unicodeslot=0x1D44E, + }, + [0x1D44F]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL B", + direction="l", + linebreak="al", + specials={ "font", 0x0062 }, + unicodeslot=0x1D44F, + }, + [0x1D450]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL C", + direction="l", + linebreak="al", + specials={ "font", 0x0063 }, + unicodeslot=0x1D450, + }, + [0x1D451]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL D", + direction="l", + linebreak="al", + specials={ "font", 0x0064 }, + unicodeslot=0x1D451, + }, + [0x1D452]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL E", + direction="l", + linebreak="al", + specials={ "font", 0x0065 }, + unicodeslot=0x1D452, + }, + [0x1D453]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL F", + direction="l", + linebreak="al", + specials={ "font", 0x0066 }, + unicodeslot=0x1D453, + }, + [0x1D454]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL G", + direction="l", + linebreak="al", + specials={ "font", 0x0067 }, + unicodeslot=0x1D454, + }, + [0x1D456]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL I", + direction="l", + linebreak="al", + specials={ "font", 0x0069 }, + unicodeslot=0x1D456, + }, + [0x1D457]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL J", + direction="l", + linebreak="al", + specials={ "font", 0x006A }, + unicodeslot=0x1D457, + }, + [0x1D458]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL K", + direction="l", + linebreak="al", + specials={ "font", 0x006B }, + unicodeslot=0x1D458, + }, + [0x1D459]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL L", + direction="l", + linebreak="al", + specials={ "font", 0x006C }, + unicodeslot=0x1D459, + }, + [0x1D45A]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL M", + direction="l", + linebreak="al", + specials={ "font", 0x006D }, + unicodeslot=0x1D45A, + }, + [0x1D45B]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL N", + direction="l", + linebreak="al", + specials={ "font", 0x006E }, + unicodeslot=0x1D45B, + }, + [0x1D45C]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL O", + direction="l", + linebreak="al", + specials={ "font", 0x006F }, + unicodeslot=0x1D45C, + }, + [0x1D45D]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL P", + direction="l", + linebreak="al", + specials={ "font", 0x0070 }, + unicodeslot=0x1D45D, + }, + [0x1D45E]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0071 }, + unicodeslot=0x1D45E, + }, + [0x1D45F]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL R", + direction="l", + linebreak="al", + specials={ "font", 0x0072 }, + unicodeslot=0x1D45F, + }, + [0x1D460]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL S", + direction="l", + linebreak="al", + specials={ "font", 0x0073 }, + unicodeslot=0x1D460, + }, + [0x1D461]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL T", + direction="l", + linebreak="al", + specials={ "font", 0x0074 }, + unicodeslot=0x1D461, + }, + [0x1D462]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL U", + direction="l", + linebreak="al", + specials={ "font", 0x0075 }, + unicodeslot=0x1D462, + }, + [0x1D463]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL V", + direction="l", + linebreak="al", + specials={ "font", 0x0076 }, + unicodeslot=0x1D463, + }, + [0x1D464]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL W", + direction="l", + linebreak="al", + specials={ "font", 0x0077 }, + unicodeslot=0x1D464, + }, + [0x1D465]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL X", + direction="l", + linebreak="al", + specials={ "font", 0x0078 }, + unicodeslot=0x1D465, + }, + [0x1D466]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0079 }, + unicodeslot=0x1D466, + }, + [0x1D467]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL Z", + direction="l", + linebreak="al", + specials={ "font", 0x007A }, + unicodeslot=0x1D467, + }, + [0x1D468]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL A", + direction="l", + linebreak="al", + specials={ "font", 0x0041 }, + unicodeslot=0x1D468, + }, + [0x1D469]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL B", + direction="l", + linebreak="al", + specials={ "font", 0x0042 }, + unicodeslot=0x1D469, + }, + [0x1D46A]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL C", + direction="l", + linebreak="al", + specials={ "font", 0x0043 }, + unicodeslot=0x1D46A, + }, + [0x1D46B]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL D", + direction="l", + linebreak="al", + specials={ "font", 0x0044 }, + unicodeslot=0x1D46B, + }, + [0x1D46C]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL E", + direction="l", + linebreak="al", + specials={ "font", 0x0045 }, + unicodeslot=0x1D46C, + }, + [0x1D46D]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL F", + direction="l", + linebreak="al", + specials={ "font", 0x0046 }, + unicodeslot=0x1D46D, + }, + [0x1D46E]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL G", + direction="l", + linebreak="al", + specials={ "font", 0x0047 }, + unicodeslot=0x1D46E, + }, + [0x1D46F]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL H", + direction="l", + linebreak="al", + specials={ "font", 0x0048 }, + unicodeslot=0x1D46F, + }, + [0x1D470]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL I", + direction="l", + linebreak="al", + specials={ "font", 0x0049 }, + unicodeslot=0x1D470, + }, + [0x1D471]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL J", + direction="l", + linebreak="al", + specials={ "font", 0x004A }, + unicodeslot=0x1D471, + }, + [0x1D472]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL K", + direction="l", + linebreak="al", + specials={ "font", 0x004B }, + unicodeslot=0x1D472, + }, + [0x1D473]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL L", + direction="l", + linebreak="al", + specials={ "font", 0x004C }, + unicodeslot=0x1D473, + }, + [0x1D474]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL M", + direction="l", + linebreak="al", + specials={ "font", 0x004D }, + unicodeslot=0x1D474, + }, + [0x1D475]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL N", + direction="l", + linebreak="al", + specials={ "font", 0x004E }, + unicodeslot=0x1D475, + }, + [0x1D476]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL O", + direction="l", + linebreak="al", + specials={ "font", 0x004F }, + unicodeslot=0x1D476, + }, + [0x1D477]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL P", + direction="l", + linebreak="al", + specials={ "font", 0x0050 }, + unicodeslot=0x1D477, + }, + [0x1D478]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0051 }, + unicodeslot=0x1D478, + }, + [0x1D479]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL R", + direction="l", + linebreak="al", + specials={ "font", 0x0052 }, + unicodeslot=0x1D479, + }, + [0x1D47A]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL S", + direction="l", + linebreak="al", + specials={ "font", 0x0053 }, + unicodeslot=0x1D47A, + }, + [0x1D47B]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL T", + direction="l", + linebreak="al", + specials={ "font", 0x0054 }, + unicodeslot=0x1D47B, + }, + [0x1D47C]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL U", + direction="l", + linebreak="al", + specials={ "font", 0x0055 }, + unicodeslot=0x1D47C, + }, + [0x1D47D]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL V", + direction="l", + linebreak="al", + specials={ "font", 0x0056 }, + unicodeslot=0x1D47D, + }, + [0x1D47E]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL W", + direction="l", + linebreak="al", + specials={ "font", 0x0057 }, + unicodeslot=0x1D47E, + }, + [0x1D47F]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL X", + direction="l", + linebreak="al", + specials={ "font", 0x0058 }, + unicodeslot=0x1D47F, + }, + [0x1D480]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0059 }, + unicodeslot=0x1D480, + }, + [0x1D481]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL Z", + direction="l", + linebreak="al", + specials={ "font", 0x005A }, + unicodeslot=0x1D481, + }, + [0x1D482]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL A", + direction="l", + linebreak="al", + specials={ "font", 0x0061 }, + unicodeslot=0x1D482, + }, + [0x1D483]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL B", + direction="l", + linebreak="al", + specials={ "font", 0x0062 }, + unicodeslot=0x1D483, + }, + [0x1D484]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL C", + direction="l", + linebreak="al", + specials={ "font", 0x0063 }, + unicodeslot=0x1D484, + }, + [0x1D485]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL D", + direction="l", + linebreak="al", + specials={ "font", 0x0064 }, + unicodeslot=0x1D485, + }, + [0x1D486]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL E", + direction="l", + linebreak="al", + specials={ "font", 0x0065 }, + unicodeslot=0x1D486, + }, + [0x1D487]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL F", + direction="l", + linebreak="al", + specials={ "font", 0x0066 }, + unicodeslot=0x1D487, + }, + [0x1D488]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL G", + direction="l", + linebreak="al", + specials={ "font", 0x0067 }, + unicodeslot=0x1D488, + }, + [0x1D489]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL H", + direction="l", + linebreak="al", + specials={ "font", 0x0068 }, + unicodeslot=0x1D489, + }, + [0x1D48A]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL I", + direction="l", + linebreak="al", + specials={ "font", 0x0069 }, + unicodeslot=0x1D48A, + }, + [0x1D48B]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL J", + direction="l", + linebreak="al", + specials={ "font", 0x006A }, + unicodeslot=0x1D48B, + }, + [0x1D48C]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL K", + direction="l", + linebreak="al", + specials={ "font", 0x006B }, + unicodeslot=0x1D48C, + }, + [0x1D48D]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL L", + direction="l", + linebreak="al", + specials={ "font", 0x006C }, + unicodeslot=0x1D48D, + }, + [0x1D48E]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL M", + direction="l", + linebreak="al", + specials={ "font", 0x006D }, + unicodeslot=0x1D48E, + }, + [0x1D48F]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL N", + direction="l", + linebreak="al", + specials={ "font", 0x006E }, + unicodeslot=0x1D48F, + }, + [0x1D490]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL O", + direction="l", + linebreak="al", + specials={ "font", 0x006F }, + unicodeslot=0x1D490, + }, + [0x1D491]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL P", + direction="l", + linebreak="al", + specials={ "font", 0x0070 }, + unicodeslot=0x1D491, + }, + [0x1D492]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0071 }, + unicodeslot=0x1D492, + }, + [0x1D493]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL R", + direction="l", + linebreak="al", + specials={ "font", 0x0072 }, + unicodeslot=0x1D493, + }, + [0x1D494]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL S", + direction="l", + linebreak="al", + specials={ "font", 0x0073 }, + unicodeslot=0x1D494, + }, + [0x1D495]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL T", + direction="l", + linebreak="al", + specials={ "font", 0x0074 }, + unicodeslot=0x1D495, + }, + [0x1D496]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL U", + direction="l", + linebreak="al", + specials={ "font", 0x0075 }, + unicodeslot=0x1D496, + }, + [0x1D497]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL V", + direction="l", + linebreak="al", + specials={ "font", 0x0076 }, + unicodeslot=0x1D497, + }, + [0x1D498]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL W", + direction="l", + linebreak="al", + specials={ "font", 0x0077 }, + unicodeslot=0x1D498, + }, + [0x1D499]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL X", + direction="l", + linebreak="al", + specials={ "font", 0x0078 }, + unicodeslot=0x1D499, + }, + [0x1D49A]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0079 }, + unicodeslot=0x1D49A, + }, + [0x1D49B]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL Z", + direction="l", + linebreak="al", + specials={ "font", 0x007A }, + unicodeslot=0x1D49B, + }, + [0x1D49C]={ + category="lu", + description="MATHEMATICAL SCRIPT CAPITAL A", + direction="l", + linebreak="al", + specials={ "font", 0x0041 }, + unicodeslot=0x1D49C, + }, + [0x1D49E]={ + category="lu", + description="MATHEMATICAL SCRIPT CAPITAL C", + direction="l", + linebreak="al", + specials={ "font", 0x0043 }, + unicodeslot=0x1D49E, + }, + [0x1D49F]={ + category="lu", + description="MATHEMATICAL SCRIPT CAPITAL D", + direction="l", + linebreak="al", + specials={ "font", 0x0044 }, + unicodeslot=0x1D49F, + }, + [0x1D4A2]={ + category="lu", + description="MATHEMATICAL SCRIPT CAPITAL G", + direction="l", + linebreak="al", + specials={ "font", 0x0047 }, + unicodeslot=0x1D4A2, + }, + [0x1D4A5]={ + category="lu", + description="MATHEMATICAL SCRIPT CAPITAL J", + direction="l", + linebreak="al", + specials={ "font", 0x004A }, + unicodeslot=0x1D4A5, + }, + [0x1D4A6]={ + category="lu", + description="MATHEMATICAL SCRIPT CAPITAL K", + direction="l", + linebreak="al", + specials={ "font", 0x004B }, + unicodeslot=0x1D4A6, + }, + [0x1D4A9]={ + category="lu", + description="MATHEMATICAL SCRIPT CAPITAL N", + direction="l", + linebreak="al", + specials={ "font", 0x004E }, + unicodeslot=0x1D4A9, + }, + [0x1D4AA]={ + category="lu", + description="MATHEMATICAL SCRIPT CAPITAL O", + direction="l", + linebreak="al", + specials={ "font", 0x004F }, + unicodeslot=0x1D4AA, + }, + [0x1D4AB]={ + category="lu", + description="MATHEMATICAL SCRIPT CAPITAL P", + direction="l", + linebreak="al", + specials={ "font", 0x0050 }, + unicodeslot=0x1D4AB, + }, + [0x1D4AC]={ + category="lu", + description="MATHEMATICAL SCRIPT CAPITAL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0051 }, + unicodeslot=0x1D4AC, + }, + [0x1D4AE]={ + category="lu", + description="MATHEMATICAL SCRIPT CAPITAL S", + direction="l", + linebreak="al", + specials={ "font", 0x0053 }, + unicodeslot=0x1D4AE, + }, + [0x1D4AF]={ + category="lu", + description="MATHEMATICAL SCRIPT CAPITAL T", + direction="l", + linebreak="al", + specials={ "font", 0x0054 }, + unicodeslot=0x1D4AF, + }, + [0x1D4B0]={ + category="lu", + description="MATHEMATICAL SCRIPT CAPITAL U", + direction="l", + linebreak="al", + specials={ "font", 0x0055 }, + unicodeslot=0x1D4B0, + }, + [0x1D4B1]={ + category="lu", + description="MATHEMATICAL SCRIPT CAPITAL V", + direction="l", + linebreak="al", + specials={ "font", 0x0056 }, + unicodeslot=0x1D4B1, + }, + [0x1D4B2]={ + category="lu", + description="MATHEMATICAL SCRIPT CAPITAL W", + direction="l", + linebreak="al", + specials={ "font", 0x0057 }, + unicodeslot=0x1D4B2, + }, + [0x1D4B3]={ + category="lu", + description="MATHEMATICAL SCRIPT CAPITAL X", + direction="l", + linebreak="al", + specials={ "font", 0x0058 }, + unicodeslot=0x1D4B3, + }, + [0x1D4B4]={ + category="lu", + description="MATHEMATICAL SCRIPT CAPITAL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0059 }, + unicodeslot=0x1D4B4, + }, + [0x1D4B5]={ + category="lu", + description="MATHEMATICAL SCRIPT CAPITAL Z", + direction="l", + linebreak="al", + specials={ "font", 0x005A }, + unicodeslot=0x1D4B5, + }, + [0x1D4B6]={ + category="ll", + description="MATHEMATICAL SCRIPT SMALL A", + direction="l", + linebreak="al", + specials={ "font", 0x0061 }, + unicodeslot=0x1D4B6, + }, + [0x1D4B7]={ + category="ll", + description="MATHEMATICAL SCRIPT SMALL B", + direction="l", + linebreak="al", + specials={ "font", 0x0062 }, + unicodeslot=0x1D4B7, + }, + [0x1D4B8]={ + category="ll", + description="MATHEMATICAL SCRIPT SMALL C", + direction="l", + linebreak="al", + specials={ "font", 0x0063 }, + unicodeslot=0x1D4B8, + }, + [0x1D4B9]={ + category="ll", + description="MATHEMATICAL SCRIPT SMALL D", + direction="l", + linebreak="al", + specials={ "font", 0x0064 }, + unicodeslot=0x1D4B9, + }, + [0x1D4BB]={ + category="ll", + description="MATHEMATICAL SCRIPT SMALL F", + direction="l", + linebreak="al", + specials={ "font", 0x0066 }, + unicodeslot=0x1D4BB, + }, + [0x1D4BD]={ + category="ll", + description="MATHEMATICAL SCRIPT SMALL H", + direction="l", + linebreak="al", + specials={ "font", 0x0068 }, + unicodeslot=0x1D4BD, + }, + [0x1D4BE]={ + category="ll", + description="MATHEMATICAL SCRIPT SMALL I", + direction="l", + linebreak="al", + specials={ "font", 0x0069 }, + unicodeslot=0x1D4BE, + }, + [0x1D4BF]={ + category="ll", + description="MATHEMATICAL SCRIPT SMALL J", + direction="l", + linebreak="al", + specials={ "font", 0x006A }, + unicodeslot=0x1D4BF, + }, + [0x1D4C0]={ + category="ll", + description="MATHEMATICAL SCRIPT SMALL K", + direction="l", + linebreak="al", + specials={ "font", 0x006B }, + unicodeslot=0x1D4C0, + }, + [0x1D4C1]={ + category="ll", + description="MATHEMATICAL SCRIPT SMALL L", + direction="l", + linebreak="al", + specials={ "font", 0x006C }, + unicodeslot=0x1D4C1, + }, + [0x1D4C2]={ + category="ll", + description="MATHEMATICAL SCRIPT SMALL M", + direction="l", + linebreak="al", + specials={ "font", 0x006D }, + unicodeslot=0x1D4C2, + }, + [0x1D4C3]={ + category="ll", + description="MATHEMATICAL SCRIPT SMALL N", + direction="l", + linebreak="al", + specials={ "font", 0x006E }, + unicodeslot=0x1D4C3, + }, + [0x1D4C5]={ + category="ll", + description="MATHEMATICAL SCRIPT SMALL P", + direction="l", + linebreak="al", + specials={ "font", 0x0070 }, + unicodeslot=0x1D4C5, + }, + [0x1D4C6]={ + category="ll", + description="MATHEMATICAL SCRIPT SMALL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0071 }, + unicodeslot=0x1D4C6, + }, + [0x1D4C7]={ + category="ll", + description="MATHEMATICAL SCRIPT SMALL R", + direction="l", + linebreak="al", + specials={ "font", 0x0072 }, + unicodeslot=0x1D4C7, + }, + [0x1D4C8]={ + category="ll", + description="MATHEMATICAL SCRIPT SMALL S", + direction="l", + linebreak="al", + specials={ "font", 0x0073 }, + unicodeslot=0x1D4C8, + }, + [0x1D4C9]={ + category="ll", + description="MATHEMATICAL SCRIPT SMALL T", + direction="l", + linebreak="al", + specials={ "font", 0x0074 }, + unicodeslot=0x1D4C9, + }, + [0x1D4CA]={ + category="ll", + description="MATHEMATICAL SCRIPT SMALL U", + direction="l", + linebreak="al", + specials={ "font", 0x0075 }, + unicodeslot=0x1D4CA, + }, + [0x1D4CB]={ + category="ll", + description="MATHEMATICAL SCRIPT SMALL V", + direction="l", + linebreak="al", + specials={ "font", 0x0076 }, + unicodeslot=0x1D4CB, + }, + [0x1D4CC]={ + category="ll", + description="MATHEMATICAL SCRIPT SMALL W", + direction="l", + linebreak="al", + specials={ "font", 0x0077 }, + unicodeslot=0x1D4CC, + }, + [0x1D4CD]={ + category="ll", + description="MATHEMATICAL SCRIPT SMALL X", + direction="l", + linebreak="al", + specials={ "font", 0x0078 }, + unicodeslot=0x1D4CD, + }, + [0x1D4CE]={ + category="ll", + description="MATHEMATICAL SCRIPT SMALL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0079 }, + unicodeslot=0x1D4CE, + }, + [0x1D4CF]={ + category="ll", + description="MATHEMATICAL SCRIPT SMALL Z", + direction="l", + linebreak="al", + specials={ "font", 0x007A }, + unicodeslot=0x1D4CF, + }, + [0x1D4D0]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL A", + direction="l", + linebreak="al", + specials={ "font", 0x0041 }, + unicodeslot=0x1D4D0, + }, + [0x1D4D1]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL B", + direction="l", + linebreak="al", + specials={ "font", 0x0042 }, + unicodeslot=0x1D4D1, + }, + [0x1D4D2]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL C", + direction="l", + linebreak="al", + specials={ "font", 0x0043 }, + unicodeslot=0x1D4D2, + }, + [0x1D4D3]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL D", + direction="l", + linebreak="al", + specials={ "font", 0x0044 }, + unicodeslot=0x1D4D3, + }, + [0x1D4D4]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL E", + direction="l", + linebreak="al", + specials={ "font", 0x0045 }, + unicodeslot=0x1D4D4, + }, + [0x1D4D5]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL F", + direction="l", + linebreak="al", + specials={ "font", 0x0046 }, + unicodeslot=0x1D4D5, + }, + [0x1D4D6]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL G", + direction="l", + linebreak="al", + specials={ "font", 0x0047 }, + unicodeslot=0x1D4D6, + }, + [0x1D4D7]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL H", + direction="l", + linebreak="al", + specials={ "font", 0x0048 }, + unicodeslot=0x1D4D7, + }, + [0x1D4D8]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL I", + direction="l", + linebreak="al", + specials={ "font", 0x0049 }, + unicodeslot=0x1D4D8, + }, + [0x1D4D9]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL J", + direction="l", + linebreak="al", + specials={ "font", 0x004A }, + unicodeslot=0x1D4D9, + }, + [0x1D4DA]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL K", + direction="l", + linebreak="al", + specials={ "font", 0x004B }, + unicodeslot=0x1D4DA, + }, + [0x1D4DB]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL L", + direction="l", + linebreak="al", + specials={ "font", 0x004C }, + unicodeslot=0x1D4DB, + }, + [0x1D4DC]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL M", + direction="l", + linebreak="al", + specials={ "font", 0x004D }, + unicodeslot=0x1D4DC, + }, + [0x1D4DD]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL N", + direction="l", + linebreak="al", + specials={ "font", 0x004E }, + unicodeslot=0x1D4DD, + }, + [0x1D4DE]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL O", + direction="l", + linebreak="al", + specials={ "font", 0x004F }, + unicodeslot=0x1D4DE, + }, + [0x1D4DF]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL P", + direction="l", + linebreak="al", + specials={ "font", 0x0050 }, + unicodeslot=0x1D4DF, + }, + [0x1D4E0]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0051 }, + unicodeslot=0x1D4E0, + }, + [0x1D4E1]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL R", + direction="l", + linebreak="al", + specials={ "font", 0x0052 }, + unicodeslot=0x1D4E1, + }, + [0x1D4E2]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL S", + direction="l", + linebreak="al", + specials={ "font", 0x0053 }, + unicodeslot=0x1D4E2, + }, + [0x1D4E3]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL T", + direction="l", + linebreak="al", + specials={ "font", 0x0054 }, + unicodeslot=0x1D4E3, + }, + [0x1D4E4]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL U", + direction="l", + linebreak="al", + specials={ "font", 0x0055 }, + unicodeslot=0x1D4E4, + }, + [0x1D4E5]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL V", + direction="l", + linebreak="al", + specials={ "font", 0x0056 }, + unicodeslot=0x1D4E5, + }, + [0x1D4E6]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL W", + direction="l", + linebreak="al", + specials={ "font", 0x0057 }, + unicodeslot=0x1D4E6, + }, + [0x1D4E7]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL X", + direction="l", + linebreak="al", + specials={ "font", 0x0058 }, + unicodeslot=0x1D4E7, + }, + [0x1D4E8]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0059 }, + unicodeslot=0x1D4E8, + }, + [0x1D4E9]={ + category="lu", + description="MATHEMATICAL BOLD SCRIPT CAPITAL Z", + direction="l", + linebreak="al", + specials={ "font", 0x005A }, + unicodeslot=0x1D4E9, + }, + [0x1D4EA]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL A", + direction="l", + linebreak="al", + specials={ "font", 0x0061 }, + unicodeslot=0x1D4EA, + }, + [0x1D4EB]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL B", + direction="l", + linebreak="al", + specials={ "font", 0x0062 }, + unicodeslot=0x1D4EB, + }, + [0x1D4EC]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL C", + direction="l", + linebreak="al", + specials={ "font", 0x0063 }, + unicodeslot=0x1D4EC, + }, + [0x1D4ED]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL D", + direction="l", + linebreak="al", + specials={ "font", 0x0064 }, + unicodeslot=0x1D4ED, + }, + [0x1D4EE]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL E", + direction="l", + linebreak="al", + specials={ "font", 0x0065 }, + unicodeslot=0x1D4EE, + }, + [0x1D4EF]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL F", + direction="l", + linebreak="al", + specials={ "font", 0x0066 }, + unicodeslot=0x1D4EF, + }, + [0x1D4F0]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL G", + direction="l", + linebreak="al", + specials={ "font", 0x0067 }, + unicodeslot=0x1D4F0, + }, + [0x1D4F1]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL H", + direction="l", + linebreak="al", + specials={ "font", 0x0068 }, + unicodeslot=0x1D4F1, + }, + [0x1D4F2]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL I", + direction="l", + linebreak="al", + specials={ "font", 0x0069 }, + unicodeslot=0x1D4F2, + }, + [0x1D4F3]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL J", + direction="l", + linebreak="al", + specials={ "font", 0x006A }, + unicodeslot=0x1D4F3, + }, + [0x1D4F4]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL K", + direction="l", + linebreak="al", + specials={ "font", 0x006B }, + unicodeslot=0x1D4F4, + }, + [0x1D4F5]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL L", + direction="l", + linebreak="al", + specials={ "font", 0x006C }, + unicodeslot=0x1D4F5, + }, + [0x1D4F6]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL M", + direction="l", + linebreak="al", + specials={ "font", 0x006D }, + unicodeslot=0x1D4F6, + }, + [0x1D4F7]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL N", + direction="l", + linebreak="al", + specials={ "font", 0x006E }, + unicodeslot=0x1D4F7, + }, + [0x1D4F8]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL O", + direction="l", + linebreak="al", + specials={ "font", 0x006F }, + unicodeslot=0x1D4F8, + }, + [0x1D4F9]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL P", + direction="l", + linebreak="al", + specials={ "font", 0x0070 }, + unicodeslot=0x1D4F9, + }, + [0x1D4FA]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0071 }, + unicodeslot=0x1D4FA, + }, + [0x1D4FB]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL R", + direction="l", + linebreak="al", + specials={ "font", 0x0072 }, + unicodeslot=0x1D4FB, + }, + [0x1D4FC]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL S", + direction="l", + linebreak="al", + specials={ "font", 0x0073 }, + unicodeslot=0x1D4FC, + }, + [0x1D4FD]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL T", + direction="l", + linebreak="al", + specials={ "font", 0x0074 }, + unicodeslot=0x1D4FD, + }, + [0x1D4FE]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL U", + direction="l", + linebreak="al", + specials={ "font", 0x0075 }, + unicodeslot=0x1D4FE, + }, + [0x1D4FF]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL V", + direction="l", + linebreak="al", + specials={ "font", 0x0076 }, + unicodeslot=0x1D4FF, + }, + [0x1D500]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL W", + direction="l", + linebreak="al", + specials={ "font", 0x0077 }, + unicodeslot=0x1D500, + }, + [0x1D501]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL X", + direction="l", + linebreak="al", + specials={ "font", 0x0078 }, + unicodeslot=0x1D501, + }, + [0x1D502]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0079 }, + unicodeslot=0x1D502, + }, + [0x1D503]={ + category="ll", + description="MATHEMATICAL BOLD SCRIPT SMALL Z", + direction="l", + linebreak="al", + specials={ "font", 0x007A }, + unicodeslot=0x1D503, + }, + [0x1D504]={ + category="lu", + description="MATHEMATICAL FRAKTUR CAPITAL A", + direction="l", + linebreak="al", + specials={ "font", 0x0041 }, + unicodeslot=0x1D504, + }, + [0x1D505]={ + category="lu", + description="MATHEMATICAL FRAKTUR CAPITAL B", + direction="l", + linebreak="al", + specials={ "font", 0x0042 }, + unicodeslot=0x1D505, + }, + [0x1D507]={ + category="lu", + description="MATHEMATICAL FRAKTUR CAPITAL D", + direction="l", + linebreak="al", + specials={ "font", 0x0044 }, + unicodeslot=0x1D507, + }, + [0x1D508]={ + category="lu", + description="MATHEMATICAL FRAKTUR CAPITAL E", + direction="l", + linebreak="al", + specials={ "font", 0x0045 }, + unicodeslot=0x1D508, + }, + [0x1D509]={ + category="lu", + description="MATHEMATICAL FRAKTUR CAPITAL F", + direction="l", + linebreak="al", + specials={ "font", 0x0046 }, + unicodeslot=0x1D509, + }, + [0x1D50A]={ + category="lu", + description="MATHEMATICAL FRAKTUR CAPITAL G", + direction="l", + linebreak="al", + specials={ "font", 0x0047 }, + unicodeslot=0x1D50A, + }, + [0x1D50D]={ + category="lu", + description="MATHEMATICAL FRAKTUR CAPITAL J", + direction="l", + linebreak="al", + specials={ "font", 0x004A }, + unicodeslot=0x1D50D, + }, + [0x1D50E]={ + category="lu", + description="MATHEMATICAL FRAKTUR CAPITAL K", + direction="l", + linebreak="al", + specials={ "font", 0x004B }, + unicodeslot=0x1D50E, + }, + [0x1D50F]={ + category="lu", + description="MATHEMATICAL FRAKTUR CAPITAL L", + direction="l", + linebreak="al", + specials={ "font", 0x004C }, + unicodeslot=0x1D50F, + }, + [0x1D510]={ + category="lu", + description="MATHEMATICAL FRAKTUR CAPITAL M", + direction="l", + linebreak="al", + specials={ "font", 0x004D }, + unicodeslot=0x1D510, + }, + [0x1D511]={ + category="lu", + description="MATHEMATICAL FRAKTUR CAPITAL N", + direction="l", + linebreak="al", + specials={ "font", 0x004E }, + unicodeslot=0x1D511, + }, + [0x1D512]={ + category="lu", + description="MATHEMATICAL FRAKTUR CAPITAL O", + direction="l", + linebreak="al", + specials={ "font", 0x004F }, + unicodeslot=0x1D512, + }, + [0x1D513]={ + category="lu", + description="MATHEMATICAL FRAKTUR CAPITAL P", + direction="l", + linebreak="al", + specials={ "font", 0x0050 }, + unicodeslot=0x1D513, + }, + [0x1D514]={ + category="lu", + description="MATHEMATICAL FRAKTUR CAPITAL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0051 }, + unicodeslot=0x1D514, + }, + [0x1D516]={ + category="lu", + description="MATHEMATICAL FRAKTUR CAPITAL S", + direction="l", + linebreak="al", + specials={ "font", 0x0053 }, + unicodeslot=0x1D516, + }, + [0x1D517]={ + category="lu", + description="MATHEMATICAL FRAKTUR CAPITAL T", + direction="l", + linebreak="al", + specials={ "font", 0x0054 }, + unicodeslot=0x1D517, + }, + [0x1D518]={ + category="lu", + description="MATHEMATICAL FRAKTUR CAPITAL U", + direction="l", + linebreak="al", + specials={ "font", 0x0055 }, + unicodeslot=0x1D518, + }, + [0x1D519]={ + category="lu", + description="MATHEMATICAL FRAKTUR CAPITAL V", + direction="l", + linebreak="al", + specials={ "font", 0x0056 }, + unicodeslot=0x1D519, + }, + [0x1D51A]={ + category="lu", + description="MATHEMATICAL FRAKTUR CAPITAL W", + direction="l", + linebreak="al", + specials={ "font", 0x0057 }, + unicodeslot=0x1D51A, + }, + [0x1D51B]={ + category="lu", + description="MATHEMATICAL FRAKTUR CAPITAL X", + direction="l", + linebreak="al", + specials={ "font", 0x0058 }, + unicodeslot=0x1D51B, + }, + [0x1D51C]={ + category="lu", + description="MATHEMATICAL FRAKTUR CAPITAL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0059 }, + unicodeslot=0x1D51C, + }, + [0x1D51E]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL A", + direction="l", + linebreak="al", + specials={ "font", 0x0061 }, + unicodeslot=0x1D51E, + }, + [0x1D51F]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL B", + direction="l", + linebreak="al", + specials={ "font", 0x0062 }, + unicodeslot=0x1D51F, + }, + [0x1D520]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL C", + direction="l", + linebreak="al", + specials={ "font", 0x0063 }, + unicodeslot=0x1D520, + }, + [0x1D521]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL D", + direction="l", + linebreak="al", + specials={ "font", 0x0064 }, + unicodeslot=0x1D521, + }, + [0x1D522]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL E", + direction="l", + linebreak="al", + specials={ "font", 0x0065 }, + unicodeslot=0x1D522, + }, + [0x1D523]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL F", + direction="l", + linebreak="al", + specials={ "font", 0x0066 }, + unicodeslot=0x1D523, + }, + [0x1D524]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL G", + direction="l", + linebreak="al", + specials={ "font", 0x0067 }, + unicodeslot=0x1D524, + }, + [0x1D525]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL H", + direction="l", + linebreak="al", + specials={ "font", 0x0068 }, + unicodeslot=0x1D525, + }, + [0x1D526]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL I", + direction="l", + linebreak="al", + specials={ "font", 0x0069 }, + unicodeslot=0x1D526, + }, + [0x1D527]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL J", + direction="l", + linebreak="al", + specials={ "font", 0x006A }, + unicodeslot=0x1D527, + }, + [0x1D528]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL K", + direction="l", + linebreak="al", + specials={ "font", 0x006B }, + unicodeslot=0x1D528, + }, + [0x1D529]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL L", + direction="l", + linebreak="al", + specials={ "font", 0x006C }, + unicodeslot=0x1D529, + }, + [0x1D52A]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL M", + direction="l", + linebreak="al", + specials={ "font", 0x006D }, + unicodeslot=0x1D52A, + }, + [0x1D52B]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL N", + direction="l", + linebreak="al", + specials={ "font", 0x006E }, + unicodeslot=0x1D52B, + }, + [0x1D52C]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL O", + direction="l", + linebreak="al", + specials={ "font", 0x006F }, + unicodeslot=0x1D52C, + }, + [0x1D52D]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL P", + direction="l", + linebreak="al", + specials={ "font", 0x0070 }, + unicodeslot=0x1D52D, + }, + [0x1D52E]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0071 }, + unicodeslot=0x1D52E, + }, + [0x1D52F]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL R", + direction="l", + linebreak="al", + specials={ "font", 0x0072 }, + unicodeslot=0x1D52F, + }, + [0x1D530]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL S", + direction="l", + linebreak="al", + specials={ "font", 0x0073 }, + unicodeslot=0x1D530, + }, + [0x1D531]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL T", + direction="l", + linebreak="al", + specials={ "font", 0x0074 }, + unicodeslot=0x1D531, + }, + [0x1D532]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL U", + direction="l", + linebreak="al", + specials={ "font", 0x0075 }, + unicodeslot=0x1D532, + }, + [0x1D533]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL V", + direction="l", + linebreak="al", + specials={ "font", 0x0076 }, + unicodeslot=0x1D533, + }, + [0x1D534]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL W", + direction="l", + linebreak="al", + specials={ "font", 0x0077 }, + unicodeslot=0x1D534, + }, + [0x1D535]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL X", + direction="l", + linebreak="al", + specials={ "font", 0x0078 }, + unicodeslot=0x1D535, + }, + [0x1D536]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0079 }, + unicodeslot=0x1D536, + }, + [0x1D537]={ + category="ll", + description="MATHEMATICAL FRAKTUR SMALL Z", + direction="l", + linebreak="al", + specials={ "font", 0x007A }, + unicodeslot=0x1D537, + }, + [0x1D538]={ + category="lu", + description="MATHEMATICAL DOUBLE-STRUCK CAPITAL A", + direction="l", + linebreak="al", + specials={ "font", 0x0041 }, + unicodeslot=0x1D538, + }, + [0x1D539]={ + category="lu", + description="MATHEMATICAL DOUBLE-STRUCK CAPITAL B", + direction="l", + linebreak="al", + specials={ "font", 0x0042 }, + unicodeslot=0x1D539, + }, + [0x1D53B]={ + category="lu", + description="MATHEMATICAL DOUBLE-STRUCK CAPITAL D", + direction="l", + linebreak="al", + specials={ "font", 0x0044 }, + unicodeslot=0x1D53B, + }, + [0x1D53C]={ + category="lu", + description="MATHEMATICAL DOUBLE-STRUCK CAPITAL E", + direction="l", + linebreak="al", + specials={ "font", 0x0045 }, + unicodeslot=0x1D53C, + }, + [0x1D53D]={ + category="lu", + description="MATHEMATICAL DOUBLE-STRUCK CAPITAL F", + direction="l", + linebreak="al", + specials={ "font", 0x0046 }, + unicodeslot=0x1D53D, + }, + [0x1D53E]={ + category="lu", + description="MATHEMATICAL DOUBLE-STRUCK CAPITAL G", + direction="l", + linebreak="al", + specials={ "font", 0x0047 }, + unicodeslot=0x1D53E, + }, + [0x1D540]={ + category="lu", + description="MATHEMATICAL DOUBLE-STRUCK CAPITAL I", + direction="l", + linebreak="al", + specials={ "font", 0x0049 }, + unicodeslot=0x1D540, + }, + [0x1D541]={ + category="lu", + description="MATHEMATICAL DOUBLE-STRUCK CAPITAL J", + direction="l", + linebreak="al", + specials={ "font", 0x004A }, + unicodeslot=0x1D541, + }, + [0x1D542]={ + category="lu", + description="MATHEMATICAL DOUBLE-STRUCK CAPITAL K", + direction="l", + linebreak="al", + specials={ "font", 0x004B }, + unicodeslot=0x1D542, + }, + [0x1D543]={ + category="lu", + description="MATHEMATICAL DOUBLE-STRUCK CAPITAL L", + direction="l", + linebreak="al", + specials={ "font", 0x004C }, + unicodeslot=0x1D543, + }, + [0x1D544]={ + category="lu", + description="MATHEMATICAL DOUBLE-STRUCK CAPITAL M", + direction="l", + linebreak="al", + specials={ "font", 0x004D }, + unicodeslot=0x1D544, + }, + [0x1D546]={ + category="lu", + description="MATHEMATICAL DOUBLE-STRUCK CAPITAL O", + direction="l", + linebreak="al", + specials={ "font", 0x004F }, + unicodeslot=0x1D546, + }, + [0x1D54A]={ + category="lu", + description="MATHEMATICAL DOUBLE-STRUCK CAPITAL S", + direction="l", + linebreak="al", + specials={ "font", 0x0053 }, + unicodeslot=0x1D54A, + }, + [0x1D54B]={ + category="lu", + description="MATHEMATICAL DOUBLE-STRUCK CAPITAL T", + direction="l", + linebreak="al", + specials={ "font", 0x0054 }, + unicodeslot=0x1D54B, + }, + [0x1D54C]={ + category="lu", + description="MATHEMATICAL DOUBLE-STRUCK CAPITAL U", + direction="l", + linebreak="al", + specials={ "font", 0x0055 }, + unicodeslot=0x1D54C, + }, + [0x1D54D]={ + category="lu", + description="MATHEMATICAL DOUBLE-STRUCK CAPITAL V", + direction="l", + linebreak="al", + specials={ "font", 0x0056 }, + unicodeslot=0x1D54D, + }, + [0x1D54E]={ + category="lu", + description="MATHEMATICAL DOUBLE-STRUCK CAPITAL W", + direction="l", + linebreak="al", + specials={ "font", 0x0057 }, + unicodeslot=0x1D54E, + }, + [0x1D54F]={ + category="lu", + description="MATHEMATICAL DOUBLE-STRUCK CAPITAL X", + direction="l", + linebreak="al", + specials={ "font", 0x0058 }, + unicodeslot=0x1D54F, + }, + [0x1D550]={ + category="lu", + description="MATHEMATICAL DOUBLE-STRUCK CAPITAL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0059 }, + unicodeslot=0x1D550, + }, + [0x1D552]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL A", + direction="l", + linebreak="al", + specials={ "font", 0x0061 }, + unicodeslot=0x1D552, + }, + [0x1D553]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL B", + direction="l", + linebreak="al", + specials={ "font", 0x0062 }, + unicodeslot=0x1D553, + }, + [0x1D554]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL C", + direction="l", + linebreak="al", + specials={ "font", 0x0063 }, + unicodeslot=0x1D554, + }, + [0x1D555]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL D", + direction="l", + linebreak="al", + specials={ "font", 0x0064 }, + unicodeslot=0x1D555, + }, + [0x1D556]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL E", + direction="l", + linebreak="al", + specials={ "font", 0x0065 }, + unicodeslot=0x1D556, + }, + [0x1D557]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL F", + direction="l", + linebreak="al", + specials={ "font", 0x0066 }, + unicodeslot=0x1D557, + }, + [0x1D558]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL G", + direction="l", + linebreak="al", + specials={ "font", 0x0067 }, + unicodeslot=0x1D558, + }, + [0x1D559]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL H", + direction="l", + linebreak="al", + specials={ "font", 0x0068 }, + unicodeslot=0x1D559, + }, + [0x1D55A]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL I", + direction="l", + linebreak="al", + specials={ "font", 0x0069 }, + unicodeslot=0x1D55A, + }, + [0x1D55B]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL J", + direction="l", + linebreak="al", + specials={ "font", 0x006A }, + unicodeslot=0x1D55B, + }, + [0x1D55C]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL K", + direction="l", + linebreak="al", + specials={ "font", 0x006B }, + unicodeslot=0x1D55C, + }, + [0x1D55D]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL L", + direction="l", + linebreak="al", + specials={ "font", 0x006C }, + unicodeslot=0x1D55D, + }, + [0x1D55E]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL M", + direction="l", + linebreak="al", + specials={ "font", 0x006D }, + unicodeslot=0x1D55E, + }, + [0x1D55F]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL N", + direction="l", + linebreak="al", + specials={ "font", 0x006E }, + unicodeslot=0x1D55F, + }, + [0x1D560]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL O", + direction="l", + linebreak="al", + specials={ "font", 0x006F }, + unicodeslot=0x1D560, + }, + [0x1D561]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL P", + direction="l", + linebreak="al", + specials={ "font", 0x0070 }, + unicodeslot=0x1D561, + }, + [0x1D562]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0071 }, + unicodeslot=0x1D562, + }, + [0x1D563]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL R", + direction="l", + linebreak="al", + specials={ "font", 0x0072 }, + unicodeslot=0x1D563, + }, + [0x1D564]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL S", + direction="l", + linebreak="al", + specials={ "font", 0x0073 }, + unicodeslot=0x1D564, + }, + [0x1D565]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL T", + direction="l", + linebreak="al", + specials={ "font", 0x0074 }, + unicodeslot=0x1D565, + }, + [0x1D566]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL U", + direction="l", + linebreak="al", + specials={ "font", 0x0075 }, + unicodeslot=0x1D566, + }, + [0x1D567]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL V", + direction="l", + linebreak="al", + specials={ "font", 0x0076 }, + unicodeslot=0x1D567, + }, + [0x1D568]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL W", + direction="l", + linebreak="al", + specials={ "font", 0x0077 }, + unicodeslot=0x1D568, + }, + [0x1D569]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL X", + direction="l", + linebreak="al", + specials={ "font", 0x0078 }, + unicodeslot=0x1D569, + }, + [0x1D56A]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0079 }, + unicodeslot=0x1D56A, + }, + [0x1D56B]={ + category="ll", + description="MATHEMATICAL DOUBLE-STRUCK SMALL Z", + direction="l", + linebreak="al", + specials={ "font", 0x007A }, + unicodeslot=0x1D56B, + }, + [0x1D56C]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL A", + direction="l", + linebreak="al", + specials={ "font", 0x0041 }, + unicodeslot=0x1D56C, + }, + [0x1D56D]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL B", + direction="l", + linebreak="al", + specials={ "font", 0x0042 }, + unicodeslot=0x1D56D, + }, + [0x1D56E]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL C", + direction="l", + linebreak="al", + specials={ "font", 0x0043 }, + unicodeslot=0x1D56E, + }, + [0x1D56F]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL D", + direction="l", + linebreak="al", + specials={ "font", 0x0044 }, + unicodeslot=0x1D56F, + }, + [0x1D570]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL E", + direction="l", + linebreak="al", + specials={ "font", 0x0045 }, + unicodeslot=0x1D570, + }, + [0x1D571]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL F", + direction="l", + linebreak="al", + specials={ "font", 0x0046 }, + unicodeslot=0x1D571, + }, + [0x1D572]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL G", + direction="l", + linebreak="al", + specials={ "font", 0x0047 }, + unicodeslot=0x1D572, + }, + [0x1D573]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL H", + direction="l", + linebreak="al", + specials={ "font", 0x0048 }, + unicodeslot=0x1D573, + }, + [0x1D574]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL I", + direction="l", + linebreak="al", + specials={ "font", 0x0049 }, + unicodeslot=0x1D574, + }, + [0x1D575]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL J", + direction="l", + linebreak="al", + specials={ "font", 0x004A }, + unicodeslot=0x1D575, + }, + [0x1D576]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL K", + direction="l", + linebreak="al", + specials={ "font", 0x004B }, + unicodeslot=0x1D576, + }, + [0x1D577]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL L", + direction="l", + linebreak="al", + specials={ "font", 0x004C }, + unicodeslot=0x1D577, + }, + [0x1D578]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL M", + direction="l", + linebreak="al", + specials={ "font", 0x004D }, + unicodeslot=0x1D578, + }, + [0x1D579]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL N", + direction="l", + linebreak="al", + specials={ "font", 0x004E }, + unicodeslot=0x1D579, + }, + [0x1D57A]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL O", + direction="l", + linebreak="al", + specials={ "font", 0x004F }, + unicodeslot=0x1D57A, + }, + [0x1D57B]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL P", + direction="l", + linebreak="al", + specials={ "font", 0x0050 }, + unicodeslot=0x1D57B, + }, + [0x1D57C]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0051 }, + unicodeslot=0x1D57C, + }, + [0x1D57D]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL R", + direction="l", + linebreak="al", + specials={ "font", 0x0052 }, + unicodeslot=0x1D57D, + }, + [0x1D57E]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL S", + direction="l", + linebreak="al", + specials={ "font", 0x0053 }, + unicodeslot=0x1D57E, + }, + [0x1D57F]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL T", + direction="l", + linebreak="al", + specials={ "font", 0x0054 }, + unicodeslot=0x1D57F, + }, + [0x1D580]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL U", + direction="l", + linebreak="al", + specials={ "font", 0x0055 }, + unicodeslot=0x1D580, + }, + [0x1D581]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL V", + direction="l", + linebreak="al", + specials={ "font", 0x0056 }, + unicodeslot=0x1D581, + }, + [0x1D582]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL W", + direction="l", + linebreak="al", + specials={ "font", 0x0057 }, + unicodeslot=0x1D582, + }, + [0x1D583]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL X", + direction="l", + linebreak="al", + specials={ "font", 0x0058 }, + unicodeslot=0x1D583, + }, + [0x1D584]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0059 }, + unicodeslot=0x1D584, + }, + [0x1D585]={ + category="lu", + description="MATHEMATICAL BOLD FRAKTUR CAPITAL Z", + direction="l", + linebreak="al", + specials={ "font", 0x005A }, + unicodeslot=0x1D585, + }, + [0x1D586]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL A", + direction="l", + linebreak="al", + specials={ "font", 0x0061 }, + unicodeslot=0x1D586, + }, + [0x1D587]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL B", + direction="l", + linebreak="al", + specials={ "font", 0x0062 }, + unicodeslot=0x1D587, + }, + [0x1D588]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL C", + direction="l", + linebreak="al", + specials={ "font", 0x0063 }, + unicodeslot=0x1D588, + }, + [0x1D589]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL D", + direction="l", + linebreak="al", + specials={ "font", 0x0064 }, + unicodeslot=0x1D589, + }, + [0x1D58A]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL E", + direction="l", + linebreak="al", + specials={ "font", 0x0065 }, + unicodeslot=0x1D58A, + }, + [0x1D58B]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL F", + direction="l", + linebreak="al", + specials={ "font", 0x0066 }, + unicodeslot=0x1D58B, + }, + [0x1D58C]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL G", + direction="l", + linebreak="al", + specials={ "font", 0x0067 }, + unicodeslot=0x1D58C, + }, + [0x1D58D]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL H", + direction="l", + linebreak="al", + specials={ "font", 0x0068 }, + unicodeslot=0x1D58D, + }, + [0x1D58E]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL I", + direction="l", + linebreak="al", + specials={ "font", 0x0069 }, + unicodeslot=0x1D58E, + }, + [0x1D58F]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL J", + direction="l", + linebreak="al", + specials={ "font", 0x006A }, + unicodeslot=0x1D58F, + }, + [0x1D590]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL K", + direction="l", + linebreak="al", + specials={ "font", 0x006B }, + unicodeslot=0x1D590, + }, + [0x1D591]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL L", + direction="l", + linebreak="al", + specials={ "font", 0x006C }, + unicodeslot=0x1D591, + }, + [0x1D592]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL M", + direction="l", + linebreak="al", + specials={ "font", 0x006D }, + unicodeslot=0x1D592, + }, + [0x1D593]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL N", + direction="l", + linebreak="al", + specials={ "font", 0x006E }, + unicodeslot=0x1D593, + }, + [0x1D594]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL O", + direction="l", + linebreak="al", + specials={ "font", 0x006F }, + unicodeslot=0x1D594, + }, + [0x1D595]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL P", + direction="l", + linebreak="al", + specials={ "font", 0x0070 }, + unicodeslot=0x1D595, + }, + [0x1D596]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0071 }, + unicodeslot=0x1D596, + }, + [0x1D597]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL R", + direction="l", + linebreak="al", + specials={ "font", 0x0072 }, + unicodeslot=0x1D597, + }, + [0x1D598]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL S", + direction="l", + linebreak="al", + specials={ "font", 0x0073 }, + unicodeslot=0x1D598, + }, + [0x1D599]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL T", + direction="l", + linebreak="al", + specials={ "font", 0x0074 }, + unicodeslot=0x1D599, + }, + [0x1D59A]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL U", + direction="l", + linebreak="al", + specials={ "font", 0x0075 }, + unicodeslot=0x1D59A, + }, + [0x1D59B]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL V", + direction="l", + linebreak="al", + specials={ "font", 0x0076 }, + unicodeslot=0x1D59B, + }, + [0x1D59C]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL W", + direction="l", + linebreak="al", + specials={ "font", 0x0077 }, + unicodeslot=0x1D59C, + }, + [0x1D59D]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL X", + direction="l", + linebreak="al", + specials={ "font", 0x0078 }, + unicodeslot=0x1D59D, + }, + [0x1D59E]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0079 }, + unicodeslot=0x1D59E, + }, + [0x1D59F]={ + category="ll", + description="MATHEMATICAL BOLD FRAKTUR SMALL Z", + direction="l", + linebreak="al", + specials={ "font", 0x007A }, + unicodeslot=0x1D59F, + }, + [0x1D5A0]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL A", + direction="l", + linebreak="al", + specials={ "font", 0x0041 }, + unicodeslot=0x1D5A0, + }, + [0x1D5A1]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL B", + direction="l", + linebreak="al", + specials={ "font", 0x0042 }, + unicodeslot=0x1D5A1, + }, + [0x1D5A2]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL C", + direction="l", + linebreak="al", + specials={ "font", 0x0043 }, + unicodeslot=0x1D5A2, + }, + [0x1D5A3]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL D", + direction="l", + linebreak="al", + specials={ "font", 0x0044 }, + unicodeslot=0x1D5A3, + }, + [0x1D5A4]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL E", + direction="l", + linebreak="al", + specials={ "font", 0x0045 }, + unicodeslot=0x1D5A4, + }, + [0x1D5A5]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL F", + direction="l", + linebreak="al", + specials={ "font", 0x0046 }, + unicodeslot=0x1D5A5, + }, + [0x1D5A6]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL G", + direction="l", + linebreak="al", + specials={ "font", 0x0047 }, + unicodeslot=0x1D5A6, + }, + [0x1D5A7]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL H", + direction="l", + linebreak="al", + specials={ "font", 0x0048 }, + unicodeslot=0x1D5A7, + }, + [0x1D5A8]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL I", + direction="l", + linebreak="al", + specials={ "font", 0x0049 }, + unicodeslot=0x1D5A8, + }, + [0x1D5A9]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL J", + direction="l", + linebreak="al", + specials={ "font", 0x004A }, + unicodeslot=0x1D5A9, + }, + [0x1D5AA]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL K", + direction="l", + linebreak="al", + specials={ "font", 0x004B }, + unicodeslot=0x1D5AA, + }, + [0x1D5AB]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL L", + direction="l", + linebreak="al", + specials={ "font", 0x004C }, + unicodeslot=0x1D5AB, + }, + [0x1D5AC]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL M", + direction="l", + linebreak="al", + specials={ "font", 0x004D }, + unicodeslot=0x1D5AC, + }, + [0x1D5AD]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL N", + direction="l", + linebreak="al", + specials={ "font", 0x004E }, + unicodeslot=0x1D5AD, + }, + [0x1D5AE]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL O", + direction="l", + linebreak="al", + specials={ "font", 0x004F }, + unicodeslot=0x1D5AE, + }, + [0x1D5AF]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL P", + direction="l", + linebreak="al", + specials={ "font", 0x0050 }, + unicodeslot=0x1D5AF, + }, + [0x1D5B0]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0051 }, + unicodeslot=0x1D5B0, + }, + [0x1D5B1]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL R", + direction="l", + linebreak="al", + specials={ "font", 0x0052 }, + unicodeslot=0x1D5B1, + }, + [0x1D5B2]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL S", + direction="l", + linebreak="al", + specials={ "font", 0x0053 }, + unicodeslot=0x1D5B2, + }, + [0x1D5B3]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL T", + direction="l", + linebreak="al", + specials={ "font", 0x0054 }, + unicodeslot=0x1D5B3, + }, + [0x1D5B4]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL U", + direction="l", + linebreak="al", + specials={ "font", 0x0055 }, + unicodeslot=0x1D5B4, + }, + [0x1D5B5]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL V", + direction="l", + linebreak="al", + specials={ "font", 0x0056 }, + unicodeslot=0x1D5B5, + }, + [0x1D5B6]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL W", + direction="l", + linebreak="al", + specials={ "font", 0x0057 }, + unicodeslot=0x1D5B6, + }, + [0x1D5B7]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL X", + direction="l", + linebreak="al", + specials={ "font", 0x0058 }, + unicodeslot=0x1D5B7, + }, + [0x1D5B8]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0059 }, + unicodeslot=0x1D5B8, + }, + [0x1D5B9]={ + category="lu", + description="MATHEMATICAL SANS-SERIF CAPITAL Z", + direction="l", + linebreak="al", + specials={ "font", 0x005A }, + unicodeslot=0x1D5B9, + }, + [0x1D5BA]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL A", + direction="l", + linebreak="al", + specials={ "font", 0x0061 }, + unicodeslot=0x1D5BA, + }, + [0x1D5BB]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL B", + direction="l", + linebreak="al", + specials={ "font", 0x0062 }, + unicodeslot=0x1D5BB, + }, + [0x1D5BC]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL C", + direction="l", + linebreak="al", + specials={ "font", 0x0063 }, + unicodeslot=0x1D5BC, + }, + [0x1D5BD]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL D", + direction="l", + linebreak="al", + specials={ "font", 0x0064 }, + unicodeslot=0x1D5BD, + }, + [0x1D5BE]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL E", + direction="l", + linebreak="al", + specials={ "font", 0x0065 }, + unicodeslot=0x1D5BE, + }, + [0x1D5BF]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL F", + direction="l", + linebreak="al", + specials={ "font", 0x0066 }, + unicodeslot=0x1D5BF, + }, + [0x1D5C0]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL G", + direction="l", + linebreak="al", + specials={ "font", 0x0067 }, + unicodeslot=0x1D5C0, + }, + [0x1D5C1]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL H", + direction="l", + linebreak="al", + specials={ "font", 0x0068 }, + unicodeslot=0x1D5C1, + }, + [0x1D5C2]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL I", + direction="l", + linebreak="al", + specials={ "font", 0x0069 }, + unicodeslot=0x1D5C2, + }, + [0x1D5C3]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL J", + direction="l", + linebreak="al", + specials={ "font", 0x006A }, + unicodeslot=0x1D5C3, + }, + [0x1D5C4]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL K", + direction="l", + linebreak="al", + specials={ "font", 0x006B }, + unicodeslot=0x1D5C4, + }, + [0x1D5C5]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL L", + direction="l", + linebreak="al", + specials={ "font", 0x006C }, + unicodeslot=0x1D5C5, + }, + [0x1D5C6]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL M", + direction="l", + linebreak="al", + specials={ "font", 0x006D }, + unicodeslot=0x1D5C6, + }, + [0x1D5C7]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL N", + direction="l", + linebreak="al", + specials={ "font", 0x006E }, + unicodeslot=0x1D5C7, + }, + [0x1D5C8]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL O", + direction="l", + linebreak="al", + specials={ "font", 0x006F }, + unicodeslot=0x1D5C8, + }, + [0x1D5C9]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL P", + direction="l", + linebreak="al", + specials={ "font", 0x0070 }, + unicodeslot=0x1D5C9, + }, + [0x1D5CA]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0071 }, + unicodeslot=0x1D5CA, + }, + [0x1D5CB]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL R", + direction="l", + linebreak="al", + specials={ "font", 0x0072 }, + unicodeslot=0x1D5CB, + }, + [0x1D5CC]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL S", + direction="l", + linebreak="al", + specials={ "font", 0x0073 }, + unicodeslot=0x1D5CC, + }, + [0x1D5CD]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL T", + direction="l", + linebreak="al", + specials={ "font", 0x0074 }, + unicodeslot=0x1D5CD, + }, + [0x1D5CE]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL U", + direction="l", + linebreak="al", + specials={ "font", 0x0075 }, + unicodeslot=0x1D5CE, + }, + [0x1D5CF]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL V", + direction="l", + linebreak="al", + specials={ "font", 0x0076 }, + unicodeslot=0x1D5CF, + }, + [0x1D5D0]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL W", + direction="l", + linebreak="al", + specials={ "font", 0x0077 }, + unicodeslot=0x1D5D0, + }, + [0x1D5D1]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL X", + direction="l", + linebreak="al", + specials={ "font", 0x0078 }, + unicodeslot=0x1D5D1, + }, + [0x1D5D2]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0079 }, + unicodeslot=0x1D5D2, + }, + [0x1D5D3]={ + category="ll", + description="MATHEMATICAL SANS-SERIF SMALL Z", + direction="l", + linebreak="al", + specials={ "font", 0x007A }, + unicodeslot=0x1D5D3, + }, + [0x1D5D4]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL A", + direction="l", + linebreak="al", + specials={ "font", 0x0041 }, + unicodeslot=0x1D5D4, + }, + [0x1D5D5]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL B", + direction="l", + linebreak="al", + specials={ "font", 0x0042 }, + unicodeslot=0x1D5D5, + }, + [0x1D5D6]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL C", + direction="l", + linebreak="al", + specials={ "font", 0x0043 }, + unicodeslot=0x1D5D6, + }, + [0x1D5D7]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL D", + direction="l", + linebreak="al", + specials={ "font", 0x0044 }, + unicodeslot=0x1D5D7, + }, + [0x1D5D8]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL E", + direction="l", + linebreak="al", + specials={ "font", 0x0045 }, + unicodeslot=0x1D5D8, + }, + [0x1D5D9]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL F", + direction="l", + linebreak="al", + specials={ "font", 0x0046 }, + unicodeslot=0x1D5D9, + }, + [0x1D5DA]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL G", + direction="l", + linebreak="al", + specials={ "font", 0x0047 }, + unicodeslot=0x1D5DA, + }, + [0x1D5DB]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL H", + direction="l", + linebreak="al", + specials={ "font", 0x0048 }, + unicodeslot=0x1D5DB, + }, + [0x1D5DC]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL I", + direction="l", + linebreak="al", + specials={ "font", 0x0049 }, + unicodeslot=0x1D5DC, + }, + [0x1D5DD]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL J", + direction="l", + linebreak="al", + specials={ "font", 0x004A }, + unicodeslot=0x1D5DD, + }, + [0x1D5DE]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL K", + direction="l", + linebreak="al", + specials={ "font", 0x004B }, + unicodeslot=0x1D5DE, + }, + [0x1D5DF]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL L", + direction="l", + linebreak="al", + specials={ "font", 0x004C }, + unicodeslot=0x1D5DF, + }, + [0x1D5E0]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL M", + direction="l", + linebreak="al", + specials={ "font", 0x004D }, + unicodeslot=0x1D5E0, + }, + [0x1D5E1]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL N", + direction="l", + linebreak="al", + specials={ "font", 0x004E }, + unicodeslot=0x1D5E1, + }, + [0x1D5E2]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL O", + direction="l", + linebreak="al", + specials={ "font", 0x004F }, + unicodeslot=0x1D5E2, + }, + [0x1D5E3]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL P", + direction="l", + linebreak="al", + specials={ "font", 0x0050 }, + unicodeslot=0x1D5E3, + }, + [0x1D5E4]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0051 }, + unicodeslot=0x1D5E4, + }, + [0x1D5E5]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL R", + direction="l", + linebreak="al", + specials={ "font", 0x0052 }, + unicodeslot=0x1D5E5, + }, + [0x1D5E6]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL S", + direction="l", + linebreak="al", + specials={ "font", 0x0053 }, + unicodeslot=0x1D5E6, + }, + [0x1D5E7]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL T", + direction="l", + linebreak="al", + specials={ "font", 0x0054 }, + unicodeslot=0x1D5E7, + }, + [0x1D5E8]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL U", + direction="l", + linebreak="al", + specials={ "font", 0x0055 }, + unicodeslot=0x1D5E8, + }, + [0x1D5E9]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL V", + direction="l", + linebreak="al", + specials={ "font", 0x0056 }, + unicodeslot=0x1D5E9, + }, + [0x1D5EA]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL W", + direction="l", + linebreak="al", + specials={ "font", 0x0057 }, + unicodeslot=0x1D5EA, + }, + [0x1D5EB]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL X", + direction="l", + linebreak="al", + specials={ "font", 0x0058 }, + unicodeslot=0x1D5EB, + }, + [0x1D5EC]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0059 }, + unicodeslot=0x1D5EC, + }, + [0x1D5ED]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL Z", + direction="l", + linebreak="al", + specials={ "font", 0x005A }, + unicodeslot=0x1D5ED, + }, + [0x1D5EE]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL A", + direction="l", + linebreak="al", + specials={ "font", 0x0061 }, + unicodeslot=0x1D5EE, + }, + [0x1D5EF]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL B", + direction="l", + linebreak="al", + specials={ "font", 0x0062 }, + unicodeslot=0x1D5EF, + }, + [0x1D5F0]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL C", + direction="l", + linebreak="al", + specials={ "font", 0x0063 }, + unicodeslot=0x1D5F0, + }, + [0x1D5F1]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL D", + direction="l", + linebreak="al", + specials={ "font", 0x0064 }, + unicodeslot=0x1D5F1, + }, + [0x1D5F2]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL E", + direction="l", + linebreak="al", + specials={ "font", 0x0065 }, + unicodeslot=0x1D5F2, + }, + [0x1D5F3]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL F", + direction="l", + linebreak="al", + specials={ "font", 0x0066 }, + unicodeslot=0x1D5F3, + }, + [0x1D5F4]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL G", + direction="l", + linebreak="al", + specials={ "font", 0x0067 }, + unicodeslot=0x1D5F4, + }, + [0x1D5F5]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL H", + direction="l", + linebreak="al", + specials={ "font", 0x0068 }, + unicodeslot=0x1D5F5, + }, + [0x1D5F6]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL I", + direction="l", + linebreak="al", + specials={ "font", 0x0069 }, + unicodeslot=0x1D5F6, + }, + [0x1D5F7]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL J", + direction="l", + linebreak="al", + specials={ "font", 0x006A }, + unicodeslot=0x1D5F7, + }, + [0x1D5F8]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL K", + direction="l", + linebreak="al", + specials={ "font", 0x006B }, + unicodeslot=0x1D5F8, + }, + [0x1D5F9]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL L", + direction="l", + linebreak="al", + specials={ "font", 0x006C }, + unicodeslot=0x1D5F9, + }, + [0x1D5FA]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL M", + direction="l", + linebreak="al", + specials={ "font", 0x006D }, + unicodeslot=0x1D5FA, + }, + [0x1D5FB]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL N", + direction="l", + linebreak="al", + specials={ "font", 0x006E }, + unicodeslot=0x1D5FB, + }, + [0x1D5FC]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL O", + direction="l", + linebreak="al", + specials={ "font", 0x006F }, + unicodeslot=0x1D5FC, + }, + [0x1D5FD]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL P", + direction="l", + linebreak="al", + specials={ "font", 0x0070 }, + unicodeslot=0x1D5FD, + }, + [0x1D5FE]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0071 }, + unicodeslot=0x1D5FE, + }, + [0x1D5FF]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL R", + direction="l", + linebreak="al", + specials={ "font", 0x0072 }, + unicodeslot=0x1D5FF, + }, + [0x1D600]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL S", + direction="l", + linebreak="al", + specials={ "font", 0x0073 }, + unicodeslot=0x1D600, + }, + [0x1D601]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL T", + direction="l", + linebreak="al", + specials={ "font", 0x0074 }, + unicodeslot=0x1D601, + }, + [0x1D602]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL U", + direction="l", + linebreak="al", + specials={ "font", 0x0075 }, + unicodeslot=0x1D602, + }, + [0x1D603]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL V", + direction="l", + linebreak="al", + specials={ "font", 0x0076 }, + unicodeslot=0x1D603, + }, + [0x1D604]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL W", + direction="l", + linebreak="al", + specials={ "font", 0x0077 }, + unicodeslot=0x1D604, + }, + [0x1D605]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL X", + direction="l", + linebreak="al", + specials={ "font", 0x0078 }, + unicodeslot=0x1D605, + }, + [0x1D606]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0079 }, + unicodeslot=0x1D606, + }, + [0x1D607]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL Z", + direction="l", + linebreak="al", + specials={ "font", 0x007A }, + unicodeslot=0x1D607, + }, + [0x1D608]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL A", + direction="l", + linebreak="al", + specials={ "font", 0x0041 }, + unicodeslot=0x1D608, + }, + [0x1D609]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL B", + direction="l", + linebreak="al", + specials={ "font", 0x0042 }, + unicodeslot=0x1D609, + }, + [0x1D60A]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL C", + direction="l", + linebreak="al", + specials={ "font", 0x0043 }, + unicodeslot=0x1D60A, + }, + [0x1D60B]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL D", + direction="l", + linebreak="al", + specials={ "font", 0x0044 }, + unicodeslot=0x1D60B, + }, + [0x1D60C]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL E", + direction="l", + linebreak="al", + specials={ "font", 0x0045 }, + unicodeslot=0x1D60C, + }, + [0x1D60D]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL F", + direction="l", + linebreak="al", + specials={ "font", 0x0046 }, + unicodeslot=0x1D60D, + }, + [0x1D60E]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL G", + direction="l", + linebreak="al", + specials={ "font", 0x0047 }, + unicodeslot=0x1D60E, + }, + [0x1D60F]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL H", + direction="l", + linebreak="al", + specials={ "font", 0x0048 }, + unicodeslot=0x1D60F, + }, + [0x1D610]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL I", + direction="l", + linebreak="al", + specials={ "font", 0x0049 }, + unicodeslot=0x1D610, + }, + [0x1D611]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL J", + direction="l", + linebreak="al", + specials={ "font", 0x004A }, + unicodeslot=0x1D611, + }, + [0x1D612]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL K", + direction="l", + linebreak="al", + specials={ "font", 0x004B }, + unicodeslot=0x1D612, + }, + [0x1D613]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL L", + direction="l", + linebreak="al", + specials={ "font", 0x004C }, + unicodeslot=0x1D613, + }, + [0x1D614]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL M", + direction="l", + linebreak="al", + specials={ "font", 0x004D }, + unicodeslot=0x1D614, + }, + [0x1D615]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL N", + direction="l", + linebreak="al", + specials={ "font", 0x004E }, + unicodeslot=0x1D615, + }, + [0x1D616]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL O", + direction="l", + linebreak="al", + specials={ "font", 0x004F }, + unicodeslot=0x1D616, + }, + [0x1D617]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL P", + direction="l", + linebreak="al", + specials={ "font", 0x0050 }, + unicodeslot=0x1D617, + }, + [0x1D618]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0051 }, + unicodeslot=0x1D618, + }, + [0x1D619]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL R", + direction="l", + linebreak="al", + specials={ "font", 0x0052 }, + unicodeslot=0x1D619, + }, + [0x1D61A]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL S", + direction="l", + linebreak="al", + specials={ "font", 0x0053 }, + unicodeslot=0x1D61A, + }, + [0x1D61B]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL T", + direction="l", + linebreak="al", + specials={ "font", 0x0054 }, + unicodeslot=0x1D61B, + }, + [0x1D61C]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL U", + direction="l", + linebreak="al", + specials={ "font", 0x0055 }, + unicodeslot=0x1D61C, + }, + [0x1D61D]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL V", + direction="l", + linebreak="al", + specials={ "font", 0x0056 }, + unicodeslot=0x1D61D, + }, + [0x1D61E]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL W", + direction="l", + linebreak="al", + specials={ "font", 0x0057 }, + unicodeslot=0x1D61E, + }, + [0x1D61F]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL X", + direction="l", + linebreak="al", + specials={ "font", 0x0058 }, + unicodeslot=0x1D61F, + }, + [0x1D620]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0059 }, + unicodeslot=0x1D620, + }, + [0x1D621]={ + category="lu", + description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z", + direction="l", + linebreak="al", + specials={ "font", 0x005A }, + unicodeslot=0x1D621, + }, + [0x1D622]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL A", + direction="l", + linebreak="al", + specials={ "font", 0x0061 }, + unicodeslot=0x1D622, + }, + [0x1D623]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL B", + direction="l", + linebreak="al", + specials={ "font", 0x0062 }, + unicodeslot=0x1D623, + }, + [0x1D624]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL C", + direction="l", + linebreak="al", + specials={ "font", 0x0063 }, + unicodeslot=0x1D624, + }, + [0x1D625]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL D", + direction="l", + linebreak="al", + specials={ "font", 0x0064 }, + unicodeslot=0x1D625, + }, + [0x1D626]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL E", + direction="l", + linebreak="al", + specials={ "font", 0x0065 }, + unicodeslot=0x1D626, + }, + [0x1D627]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL F", + direction="l", + linebreak="al", + specials={ "font", 0x0066 }, + unicodeslot=0x1D627, + }, + [0x1D628]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL G", + direction="l", + linebreak="al", + specials={ "font", 0x0067 }, + unicodeslot=0x1D628, + }, + [0x1D629]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL H", + direction="l", + linebreak="al", + specials={ "font", 0x0068 }, + unicodeslot=0x1D629, + }, + [0x1D62A]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL I", + direction="l", + linebreak="al", + specials={ "font", 0x0069 }, + unicodeslot=0x1D62A, + }, + [0x1D62B]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL J", + direction="l", + linebreak="al", + specials={ "font", 0x006A }, + unicodeslot=0x1D62B, + }, + [0x1D62C]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL K", + direction="l", + linebreak="al", + specials={ "font", 0x006B }, + unicodeslot=0x1D62C, + }, + [0x1D62D]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL L", + direction="l", + linebreak="al", + specials={ "font", 0x006C }, + unicodeslot=0x1D62D, + }, + [0x1D62E]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL M", + direction="l", + linebreak="al", + specials={ "font", 0x006D }, + unicodeslot=0x1D62E, + }, + [0x1D62F]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL N", + direction="l", + linebreak="al", + specials={ "font", 0x006E }, + unicodeslot=0x1D62F, + }, + [0x1D630]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL O", + direction="l", + linebreak="al", + specials={ "font", 0x006F }, + unicodeslot=0x1D630, + }, + [0x1D631]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL P", + direction="l", + linebreak="al", + specials={ "font", 0x0070 }, + unicodeslot=0x1D631, + }, + [0x1D632]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0071 }, + unicodeslot=0x1D632, + }, + [0x1D633]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL R", + direction="l", + linebreak="al", + specials={ "font", 0x0072 }, + unicodeslot=0x1D633, + }, + [0x1D634]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL S", + direction="l", + linebreak="al", + specials={ "font", 0x0073 }, + unicodeslot=0x1D634, + }, + [0x1D635]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL T", + direction="l", + linebreak="al", + specials={ "font", 0x0074 }, + unicodeslot=0x1D635, + }, + [0x1D636]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL U", + direction="l", + linebreak="al", + specials={ "font", 0x0075 }, + unicodeslot=0x1D636, + }, + [0x1D637]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL V", + direction="l", + linebreak="al", + specials={ "font", 0x0076 }, + unicodeslot=0x1D637, + }, + [0x1D638]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL W", + direction="l", + linebreak="al", + specials={ "font", 0x0077 }, + unicodeslot=0x1D638, + }, + [0x1D639]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL X", + direction="l", + linebreak="al", + specials={ "font", 0x0078 }, + unicodeslot=0x1D639, + }, + [0x1D63A]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0079 }, + unicodeslot=0x1D63A, + }, + [0x1D63B]={ + category="ll", + description="MATHEMATICAL SANS-SERIF ITALIC SMALL Z", + direction="l", + linebreak="al", + specials={ "font", 0x007A }, + unicodeslot=0x1D63B, + }, + [0x1D63C]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A", + direction="l", + linebreak="al", + specials={ "font", 0x0041 }, + unicodeslot=0x1D63C, + }, + [0x1D63D]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL B", + direction="l", + linebreak="al", + specials={ "font", 0x0042 }, + unicodeslot=0x1D63D, + }, + [0x1D63E]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL C", + direction="l", + linebreak="al", + specials={ "font", 0x0043 }, + unicodeslot=0x1D63E, + }, + [0x1D63F]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL D", + direction="l", + linebreak="al", + specials={ "font", 0x0044 }, + unicodeslot=0x1D63F, + }, + [0x1D640]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL E", + direction="l", + linebreak="al", + specials={ "font", 0x0045 }, + unicodeslot=0x1D640, + }, + [0x1D641]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL F", + direction="l", + linebreak="al", + specials={ "font", 0x0046 }, + unicodeslot=0x1D641, + }, + [0x1D642]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL G", + direction="l", + linebreak="al", + specials={ "font", 0x0047 }, + unicodeslot=0x1D642, + }, + [0x1D643]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL H", + direction="l", + linebreak="al", + specials={ "font", 0x0048 }, + unicodeslot=0x1D643, + }, + [0x1D644]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL I", + direction="l", + linebreak="al", + specials={ "font", 0x0049 }, + unicodeslot=0x1D644, + }, + [0x1D645]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL J", + direction="l", + linebreak="al", + specials={ "font", 0x004A }, + unicodeslot=0x1D645, + }, + [0x1D646]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL K", + direction="l", + linebreak="al", + specials={ "font", 0x004B }, + unicodeslot=0x1D646, + }, + [0x1D647]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL L", + direction="l", + linebreak="al", + specials={ "font", 0x004C }, + unicodeslot=0x1D647, + }, + [0x1D648]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL M", + direction="l", + linebreak="al", + specials={ "font", 0x004D }, + unicodeslot=0x1D648, + }, + [0x1D649]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL N", + direction="l", + linebreak="al", + specials={ "font", 0x004E }, + unicodeslot=0x1D649, + }, + [0x1D64A]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL O", + direction="l", + linebreak="al", + specials={ "font", 0x004F }, + unicodeslot=0x1D64A, + }, + [0x1D64B]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL P", + direction="l", + linebreak="al", + specials={ "font", 0x0050 }, + unicodeslot=0x1D64B, + }, + [0x1D64C]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0051 }, + unicodeslot=0x1D64C, + }, + [0x1D64D]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL R", + direction="l", + linebreak="al", + specials={ "font", 0x0052 }, + unicodeslot=0x1D64D, + }, + [0x1D64E]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL S", + direction="l", + linebreak="al", + specials={ "font", 0x0053 }, + unicodeslot=0x1D64E, + }, + [0x1D64F]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL T", + direction="l", + linebreak="al", + specials={ "font", 0x0054 }, + unicodeslot=0x1D64F, + }, + [0x1D650]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL U", + direction="l", + linebreak="al", + specials={ "font", 0x0055 }, + unicodeslot=0x1D650, + }, + [0x1D651]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL V", + direction="l", + linebreak="al", + specials={ "font", 0x0056 }, + unicodeslot=0x1D651, + }, + [0x1D652]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL W", + direction="l", + linebreak="al", + specials={ "font", 0x0057 }, + unicodeslot=0x1D652, + }, + [0x1D653]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL X", + direction="l", + linebreak="al", + specials={ "font", 0x0058 }, + unicodeslot=0x1D653, + }, + [0x1D654]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0059 }, + unicodeslot=0x1D654, + }, + [0x1D655]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z", + direction="l", + linebreak="al", + specials={ "font", 0x005A }, + unicodeslot=0x1D655, + }, + [0x1D656]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A", + direction="l", + linebreak="al", + specials={ "font", 0x0061 }, + unicodeslot=0x1D656, + }, + [0x1D657]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL B", + direction="l", + linebreak="al", + specials={ "font", 0x0062 }, + unicodeslot=0x1D657, + }, + [0x1D658]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL C", + direction="l", + linebreak="al", + specials={ "font", 0x0063 }, + unicodeslot=0x1D658, + }, + [0x1D659]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL D", + direction="l", + linebreak="al", + specials={ "font", 0x0064 }, + unicodeslot=0x1D659, + }, + [0x1D65A]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL E", + direction="l", + linebreak="al", + specials={ "font", 0x0065 }, + unicodeslot=0x1D65A, + }, + [0x1D65B]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL F", + direction="l", + linebreak="al", + specials={ "font", 0x0066 }, + unicodeslot=0x1D65B, + }, + [0x1D65C]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL G", + direction="l", + linebreak="al", + specials={ "font", 0x0067 }, + unicodeslot=0x1D65C, + }, + [0x1D65D]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL H", + direction="l", + linebreak="al", + specials={ "font", 0x0068 }, + unicodeslot=0x1D65D, + }, + [0x1D65E]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL I", + direction="l", + linebreak="al", + specials={ "font", 0x0069 }, + unicodeslot=0x1D65E, + }, + [0x1D65F]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL J", + direction="l", + linebreak="al", + specials={ "font", 0x006A }, + unicodeslot=0x1D65F, + }, + [0x1D660]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL K", + direction="l", + linebreak="al", + specials={ "font", 0x006B }, + unicodeslot=0x1D660, + }, + [0x1D661]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL L", + direction="l", + linebreak="al", + specials={ "font", 0x006C }, + unicodeslot=0x1D661, + }, + [0x1D662]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL M", + direction="l", + linebreak="al", + specials={ "font", 0x006D }, + unicodeslot=0x1D662, + }, + [0x1D663]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL N", + direction="l", + linebreak="al", + specials={ "font", 0x006E }, + unicodeslot=0x1D663, + }, + [0x1D664]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL O", + direction="l", + linebreak="al", + specials={ "font", 0x006F }, + unicodeslot=0x1D664, + }, + [0x1D665]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL P", + direction="l", + linebreak="al", + specials={ "font", 0x0070 }, + unicodeslot=0x1D665, + }, + [0x1D666]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0071 }, + unicodeslot=0x1D666, + }, + [0x1D667]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL R", + direction="l", + linebreak="al", + specials={ "font", 0x0072 }, + unicodeslot=0x1D667, + }, + [0x1D668]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL S", + direction="l", + linebreak="al", + specials={ "font", 0x0073 }, + unicodeslot=0x1D668, + }, + [0x1D669]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL T", + direction="l", + linebreak="al", + specials={ "font", 0x0074 }, + unicodeslot=0x1D669, + }, + [0x1D66A]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL U", + direction="l", + linebreak="al", + specials={ "font", 0x0075 }, + unicodeslot=0x1D66A, + }, + [0x1D66B]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL V", + direction="l", + linebreak="al", + specials={ "font", 0x0076 }, + unicodeslot=0x1D66B, + }, + [0x1D66C]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL W", + direction="l", + linebreak="al", + specials={ "font", 0x0077 }, + unicodeslot=0x1D66C, + }, + [0x1D66D]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL X", + direction="l", + linebreak="al", + specials={ "font", 0x0078 }, + unicodeslot=0x1D66D, + }, + [0x1D66E]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0079 }, + unicodeslot=0x1D66E, + }, + [0x1D66F]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z", + direction="l", + linebreak="al", + specials={ "font", 0x007A }, + unicodeslot=0x1D66F, + }, + [0x1D670]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL A", + direction="l", + linebreak="al", + specials={ "font", 0x0041 }, + unicodeslot=0x1D670, + }, + [0x1D671]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL B", + direction="l", + linebreak="al", + specials={ "font", 0x0042 }, + unicodeslot=0x1D671, + }, + [0x1D672]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL C", + direction="l", + linebreak="al", + specials={ "font", 0x0043 }, + unicodeslot=0x1D672, + }, + [0x1D673]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL D", + direction="l", + linebreak="al", + specials={ "font", 0x0044 }, + unicodeslot=0x1D673, + }, + [0x1D674]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL E", + direction="l", + linebreak="al", + specials={ "font", 0x0045 }, + unicodeslot=0x1D674, + }, + [0x1D675]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL F", + direction="l", + linebreak="al", + specials={ "font", 0x0046 }, + unicodeslot=0x1D675, + }, + [0x1D676]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL G", + direction="l", + linebreak="al", + specials={ "font", 0x0047 }, + unicodeslot=0x1D676, + }, + [0x1D677]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL H", + direction="l", + linebreak="al", + specials={ "font", 0x0048 }, + unicodeslot=0x1D677, + }, + [0x1D678]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL I", + direction="l", + linebreak="al", + specials={ "font", 0x0049 }, + unicodeslot=0x1D678, + }, + [0x1D679]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL J", + direction="l", + linebreak="al", + specials={ "font", 0x004A }, + unicodeslot=0x1D679, + }, + [0x1D67A]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL K", + direction="l", + linebreak="al", + specials={ "font", 0x004B }, + unicodeslot=0x1D67A, + }, + [0x1D67B]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL L", + direction="l", + linebreak="al", + specials={ "font", 0x004C }, + unicodeslot=0x1D67B, + }, + [0x1D67C]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL M", + direction="l", + linebreak="al", + specials={ "font", 0x004D }, + unicodeslot=0x1D67C, + }, + [0x1D67D]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL N", + direction="l", + linebreak="al", + specials={ "font", 0x004E }, + unicodeslot=0x1D67D, + }, + [0x1D67E]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL O", + direction="l", + linebreak="al", + specials={ "font", 0x004F }, + unicodeslot=0x1D67E, + }, + [0x1D67F]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL P", + direction="l", + linebreak="al", + specials={ "font", 0x0050 }, + unicodeslot=0x1D67F, + }, + [0x1D680]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0051 }, + unicodeslot=0x1D680, + }, + [0x1D681]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL R", + direction="l", + linebreak="al", + specials={ "font", 0x0052 }, + unicodeslot=0x1D681, + }, + [0x1D682]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL S", + direction="l", + linebreak="al", + specials={ "font", 0x0053 }, + unicodeslot=0x1D682, + }, + [0x1D683]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL T", + direction="l", + linebreak="al", + specials={ "font", 0x0054 }, + unicodeslot=0x1D683, + }, + [0x1D684]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL U", + direction="l", + linebreak="al", + specials={ "font", 0x0055 }, + unicodeslot=0x1D684, + }, + [0x1D685]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL V", + direction="l", + linebreak="al", + specials={ "font", 0x0056 }, + unicodeslot=0x1D685, + }, + [0x1D686]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL W", + direction="l", + linebreak="al", + specials={ "font", 0x0057 }, + unicodeslot=0x1D686, + }, + [0x1D687]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL X", + direction="l", + linebreak="al", + specials={ "font", 0x0058 }, + unicodeslot=0x1D687, + }, + [0x1D688]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0059 }, + unicodeslot=0x1D688, + }, + [0x1D689]={ + category="lu", + description="MATHEMATICAL MONOSPACE CAPITAL Z", + direction="l", + linebreak="al", + specials={ "font", 0x005A }, + unicodeslot=0x1D689, + }, + [0x1D68A]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL A", + direction="l", + linebreak="al", + specials={ "font", 0x0061 }, + unicodeslot=0x1D68A, + }, + [0x1D68B]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL B", + direction="l", + linebreak="al", + specials={ "font", 0x0062 }, + unicodeslot=0x1D68B, + }, + [0x1D68C]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL C", + direction="l", + linebreak="al", + specials={ "font", 0x0063 }, + unicodeslot=0x1D68C, + }, + [0x1D68D]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL D", + direction="l", + linebreak="al", + specials={ "font", 0x0064 }, + unicodeslot=0x1D68D, + }, + [0x1D68E]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL E", + direction="l", + linebreak="al", + specials={ "font", 0x0065 }, + unicodeslot=0x1D68E, + }, + [0x1D68F]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL F", + direction="l", + linebreak="al", + specials={ "font", 0x0066 }, + unicodeslot=0x1D68F, + }, + [0x1D690]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL G", + direction="l", + linebreak="al", + specials={ "font", 0x0067 }, + unicodeslot=0x1D690, + }, + [0x1D691]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL H", + direction="l", + linebreak="al", + specials={ "font", 0x0068 }, + unicodeslot=0x1D691, + }, + [0x1D692]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL I", + direction="l", + linebreak="al", + specials={ "font", 0x0069 }, + unicodeslot=0x1D692, + }, + [0x1D693]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL J", + direction="l", + linebreak="al", + specials={ "font", 0x006A }, + unicodeslot=0x1D693, + }, + [0x1D694]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL K", + direction="l", + linebreak="al", + specials={ "font", 0x006B }, + unicodeslot=0x1D694, + }, + [0x1D695]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL L", + direction="l", + linebreak="al", + specials={ "font", 0x006C }, + unicodeslot=0x1D695, + }, + [0x1D696]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL M", + direction="l", + linebreak="al", + specials={ "font", 0x006D }, + unicodeslot=0x1D696, + }, + [0x1D697]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL N", + direction="l", + linebreak="al", + specials={ "font", 0x006E }, + unicodeslot=0x1D697, + }, + [0x1D698]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL O", + direction="l", + linebreak="al", + specials={ "font", 0x006F }, + unicodeslot=0x1D698, + }, + [0x1D699]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL P", + direction="l", + linebreak="al", + specials={ "font", 0x0070 }, + unicodeslot=0x1D699, + }, + [0x1D69A]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL Q", + direction="l", + linebreak="al", + specials={ "font", 0x0071 }, + unicodeslot=0x1D69A, + }, + [0x1D69B]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL R", + direction="l", + linebreak="al", + specials={ "font", 0x0072 }, + unicodeslot=0x1D69B, + }, + [0x1D69C]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL S", + direction="l", + linebreak="al", + specials={ "font", 0x0073 }, + unicodeslot=0x1D69C, + }, + [0x1D69D]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL T", + direction="l", + linebreak="al", + specials={ "font", 0x0074 }, + unicodeslot=0x1D69D, + }, + [0x1D69E]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL U", + direction="l", + linebreak="al", + specials={ "font", 0x0075 }, + unicodeslot=0x1D69E, + }, + [0x1D69F]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL V", + direction="l", + linebreak="al", + specials={ "font", 0x0076 }, + unicodeslot=0x1D69F, + }, + [0x1D6A0]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL W", + direction="l", + linebreak="al", + specials={ "font", 0x0077 }, + unicodeslot=0x1D6A0, + }, + [0x1D6A1]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL X", + direction="l", + linebreak="al", + specials={ "font", 0x0078 }, + unicodeslot=0x1D6A1, + }, + [0x1D6A2]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL Y", + direction="l", + linebreak="al", + specials={ "font", 0x0079 }, + unicodeslot=0x1D6A2, + }, + [0x1D6A3]={ + category="ll", + description="MATHEMATICAL MONOSPACE SMALL Z", + direction="l", + linebreak="al", + specials={ "font", 0x007A }, + unicodeslot=0x1D6A3, + }, + [0x1D6A4]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL DOTLESS I", + direction="l", + linebreak="al", + mathclass="default", + mathname="imath", + specials={ "font", 0x0131 }, + unicodeslot=0x1D6A4, + }, + [0x1D6A5]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL DOTLESS J", + direction="l", + linebreak="al", + mathclass="default", + mathname="jmath", + specials={ "font", 0x0237 }, + unicodeslot=0x1D6A5, + }, + [0x1D6A8]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL ALPHA", + direction="l", + linebreak="al", + specials={ "font", 0x0391 }, + unicodeslot=0x1D6A8, + }, + [0x1D6A9]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL BETA", + direction="l", + linebreak="al", + specials={ "font", 0x0392 }, + unicodeslot=0x1D6A9, + }, + [0x1D6AA]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL GAMMA", + direction="l", + linebreak="al", + specials={ "font", 0x0393 }, + unicodeslot=0x1D6AA, + }, + [0x1D6AB]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL DELTA", + direction="l", + linebreak="al", + specials={ "font", 0x0394 }, + unicodeslot=0x1D6AB, + }, + [0x1D6AC]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL EPSILON", + direction="l", + linebreak="al", + specials={ "font", 0x0395 }, + unicodeslot=0x1D6AC, + }, + [0x1D6AD]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL ZETA", + direction="l", + linebreak="al", + specials={ "font", 0x0396 }, + unicodeslot=0x1D6AD, + }, + [0x1D6AE]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL ETA", + direction="l", + linebreak="al", + specials={ "font", 0x0397 }, + unicodeslot=0x1D6AE, + }, + [0x1D6AF]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL THETA", + direction="l", + linebreak="al", + specials={ "font", 0x0398 }, + unicodeslot=0x1D6AF, + }, + [0x1D6B0]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL IOTA", + direction="l", + linebreak="al", + specials={ "font", 0x0399 }, + unicodeslot=0x1D6B0, + }, + [0x1D6B1]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL KAPPA", + direction="l", + linebreak="al", + specials={ "font", 0x039A }, + unicodeslot=0x1D6B1, + }, + [0x1D6B2]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL LAMDA", + direction="l", + linebreak="al", + specials={ "font", 0x039B }, + unicodeslot=0x1D6B2, + }, + [0x1D6B3]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL MU", + direction="l", + linebreak="al", + specials={ "font", 0x039C }, + unicodeslot=0x1D6B3, + }, + [0x1D6B4]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL NU", + direction="l", + linebreak="al", + specials={ "font", 0x039D }, + unicodeslot=0x1D6B4, + }, + [0x1D6B5]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL XI", + direction="l", + linebreak="al", + specials={ "font", 0x039E }, + unicodeslot=0x1D6B5, + }, + [0x1D6B6]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL OMICRON", + direction="l", + linebreak="al", + specials={ "font", 0x039F }, + unicodeslot=0x1D6B6, + }, + [0x1D6B7]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL PI", + direction="l", + linebreak="al", + specials={ "font", 0x03A0 }, + unicodeslot=0x1D6B7, + }, + [0x1D6B8]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL RHO", + direction="l", + linebreak="al", + specials={ "font", 0x03A1 }, + unicodeslot=0x1D6B8, + }, + [0x1D6B9]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL THETA SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03F4 }, + unicodeslot=0x1D6B9, + }, + [0x1D6BA]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL SIGMA", + direction="l", + linebreak="al", + specials={ "font", 0x03A3 }, + unicodeslot=0x1D6BA, + }, + [0x1D6BB]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL TAU", + direction="l", + linebreak="al", + specials={ "font", 0x03A4 }, + unicodeslot=0x1D6BB, + }, + [0x1D6BC]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL UPSILON", + direction="l", + linebreak="al", + specials={ "font", 0x03A5 }, + unicodeslot=0x1D6BC, + }, + [0x1D6BD]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL PHI", + direction="l", + linebreak="al", + specials={ "font", 0x03A6 }, + unicodeslot=0x1D6BD, + }, + [0x1D6BE]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL CHI", + direction="l", + linebreak="al", + specials={ "font", 0x03A7 }, + unicodeslot=0x1D6BE, + }, + [0x1D6BF]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL PSI", + direction="l", + linebreak="al", + specials={ "font", 0x03A8 }, + unicodeslot=0x1D6BF, + }, + [0x1D6C0]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL OMEGA", + direction="l", + linebreak="al", + specials={ "font", 0x03A9 }, + unicodeslot=0x1D6C0, + }, + [0x1D6C1]={ + category="sm", + description="MATHEMATICAL BOLD NABLA", + direction="l", + linebreak="al", + specials={ "font", 0x2207 }, + unicodeslot=0x1D6C1, + }, + [0x1D6C2]={ + category="ll", + description="MATHEMATICAL BOLD SMALL ALPHA", + direction="l", + linebreak="al", + specials={ "font", 0x03B1 }, + unicodeslot=0x1D6C2, + }, + [0x1D6C3]={ + category="ll", + description="MATHEMATICAL BOLD SMALL BETA", + direction="l", + linebreak="al", + specials={ "font", 0x03B2 }, + unicodeslot=0x1D6C3, + }, + [0x1D6C4]={ + category="ll", + description="MATHEMATICAL BOLD SMALL GAMMA", + direction="l", + linebreak="al", + specials={ "font", 0x03B3 }, + unicodeslot=0x1D6C4, + }, + [0x1D6C5]={ + category="ll", + description="MATHEMATICAL BOLD SMALL DELTA", + direction="l", + linebreak="al", + specials={ "font", 0x03B4 }, + unicodeslot=0x1D6C5, + }, + [0x1D6C6]={ + category="ll", + description="MATHEMATICAL BOLD SMALL EPSILON", + direction="l", + linebreak="al", + specials={ "font", 0x03B5 }, + unicodeslot=0x1D6C6, + }, + [0x1D6C7]={ + category="ll", + description="MATHEMATICAL BOLD SMALL ZETA", + direction="l", + linebreak="al", + specials={ "font", 0x03B6 }, + unicodeslot=0x1D6C7, + }, + [0x1D6C8]={ + category="ll", + description="MATHEMATICAL BOLD SMALL ETA", + direction="l", + linebreak="al", + specials={ "font", 0x03B7 }, + unicodeslot=0x1D6C8, + }, + [0x1D6C9]={ + category="ll", + description="MATHEMATICAL BOLD SMALL THETA", + direction="l", + linebreak="al", + specials={ "font", 0x03B8 }, + unicodeslot=0x1D6C9, + }, + [0x1D6CA]={ + category="ll", + description="MATHEMATICAL BOLD SMALL IOTA", + direction="l", + linebreak="al", + specials={ "font", 0x03B9 }, + unicodeslot=0x1D6CA, + }, + [0x1D6CB]={ + category="ll", + description="MATHEMATICAL BOLD SMALL KAPPA", + direction="l", + linebreak="al", + specials={ "font", 0x03BA }, + unicodeslot=0x1D6CB, + }, + [0x1D6CC]={ + category="ll", + description="MATHEMATICAL BOLD SMALL LAMDA", + direction="l", + linebreak="al", + specials={ "font", 0x03BB }, + unicodeslot=0x1D6CC, + }, + [0x1D6CD]={ + category="ll", + description="MATHEMATICAL BOLD SMALL MU", + direction="l", + linebreak="al", + specials={ "font", 0x03BC }, + unicodeslot=0x1D6CD, + }, + [0x1D6CE]={ + category="ll", + description="MATHEMATICAL BOLD SMALL NU", + direction="l", + linebreak="al", + specials={ "font", 0x03BD }, + unicodeslot=0x1D6CE, + }, + [0x1D6CF]={ + category="ll", + description="MATHEMATICAL BOLD SMALL XI", + direction="l", + linebreak="al", + specials={ "font", 0x03BE }, + unicodeslot=0x1D6CF, + }, + [0x1D6D0]={ + category="ll", + description="MATHEMATICAL BOLD SMALL OMICRON", + direction="l", + linebreak="al", + specials={ "font", 0x03BF }, + unicodeslot=0x1D6D0, + }, + [0x1D6D1]={ + category="ll", + description="MATHEMATICAL BOLD SMALL PI", + direction="l", + linebreak="al", + specials={ "font", 0x03C0 }, + unicodeslot=0x1D6D1, + }, + [0x1D6D2]={ + category="ll", + description="MATHEMATICAL BOLD SMALL RHO", + direction="l", + linebreak="al", + specials={ "font", 0x03C1 }, + unicodeslot=0x1D6D2, + }, + [0x1D6D3]={ + category="ll", + description="MATHEMATICAL BOLD SMALL FINAL SIGMA", + direction="l", + linebreak="al", + specials={ "font", 0x03C2 }, + unicodeslot=0x1D6D3, + }, + [0x1D6D4]={ + category="ll", + description="MATHEMATICAL BOLD SMALL SIGMA", + direction="l", + linebreak="al", + specials={ "font", 0x03C3 }, + unicodeslot=0x1D6D4, + }, + [0x1D6D5]={ + category="ll", + description="MATHEMATICAL BOLD SMALL TAU", + direction="l", + linebreak="al", + specials={ "font", 0x03C4 }, + unicodeslot=0x1D6D5, + }, + [0x1D6D6]={ + category="ll", + description="MATHEMATICAL BOLD SMALL UPSILON", + direction="l", + linebreak="al", + specials={ "font", 0x03C5 }, + unicodeslot=0x1D6D6, + }, + [0x1D6D7]={ + category="ll", + description="MATHEMATICAL BOLD SMALL PHI", + direction="l", + linebreak="al", + specials={ "font", 0x03C6 }, + unicodeslot=0x1D6D7, + }, + [0x1D6D8]={ + category="ll", + description="MATHEMATICAL BOLD SMALL CHI", + direction="l", + linebreak="al", + specials={ "font", 0x03C7 }, + unicodeslot=0x1D6D8, + }, + [0x1D6D9]={ + category="ll", + description="MATHEMATICAL BOLD SMALL PSI", + direction="l", + linebreak="al", + specials={ "font", 0x03C8 }, + unicodeslot=0x1D6D9, + }, + [0x1D6DA]={ + category="ll", + description="MATHEMATICAL BOLD SMALL OMEGA", + direction="l", + linebreak="al", + specials={ "font", 0x03C9 }, + unicodeslot=0x1D6DA, + }, + [0x1D6DB]={ + category="sm", + description="MATHEMATICAL BOLD PARTIAL DIFFERENTIAL", + direction="l", + linebreak="al", + specials={ "font", 0x2202 }, + unicodeslot=0x1D6DB, + }, + [0x1D6DC]={ + category="ll", + description="MATHEMATICAL BOLD EPSILON SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03F5 }, + unicodeslot=0x1D6DC, + }, + [0x1D6DD]={ + category="ll", + description="MATHEMATICAL BOLD THETA SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03D1 }, + unicodeslot=0x1D6DD, + }, + [0x1D6DE]={ + category="ll", + description="MATHEMATICAL BOLD KAPPA SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03F0 }, + unicodeslot=0x1D6DE, + }, + [0x1D6DF]={ + category="ll", + description="MATHEMATICAL BOLD PHI SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03D5 }, + unicodeslot=0x1D6DF, + }, + [0x1D6E0]={ + category="ll", + description="MATHEMATICAL BOLD RHO SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03F1 }, + unicodeslot=0x1D6E0, + }, + [0x1D6E1]={ + category="ll", + description="MATHEMATICAL BOLD PI SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03D6 }, + unicodeslot=0x1D6E1, + }, + [0x1D6E2]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL ALPHA", + direction="l", + linebreak="al", + specials={ "font", 0x0391 }, + unicodeslot=0x1D6E2, + }, + [0x1D6E3]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL BETA", + direction="l", + linebreak="al", + specials={ "font", 0x0392 }, + unicodeslot=0x1D6E3, + }, + [0x1D6E4]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL GAMMA", + direction="l", + linebreak="al", + specials={ "font", 0x0393 }, + unicodeslot=0x1D6E4, + }, + [0x1D6E5]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL DELTA", + direction="l", + linebreak="al", + specials={ "font", 0x0394 }, + unicodeslot=0x1D6E5, + }, + [0x1D6E6]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL EPSILON", + direction="l", + linebreak="al", + specials={ "font", 0x0395 }, + unicodeslot=0x1D6E6, + }, + [0x1D6E7]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL ZETA", + direction="l", + linebreak="al", + specials={ "font", 0x0396 }, + unicodeslot=0x1D6E7, + }, + [0x1D6E8]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL ETA", + direction="l", + linebreak="al", + specials={ "font", 0x0397 }, + unicodeslot=0x1D6E8, + }, + [0x1D6E9]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL THETA", + direction="l", + linebreak="al", + specials={ "font", 0x0398 }, + unicodeslot=0x1D6E9, + }, + [0x1D6EA]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL IOTA", + direction="l", + linebreak="al", + specials={ "font", 0x0399 }, + unicodeslot=0x1D6EA, + }, + [0x1D6EB]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL KAPPA", + direction="l", + linebreak="al", + specials={ "font", 0x039A }, + unicodeslot=0x1D6EB, + }, + [0x1D6EC]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL LAMDA", + direction="l", + linebreak="al", + specials={ "font", 0x039B }, + unicodeslot=0x1D6EC, + }, + [0x1D6ED]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL MU", + direction="l", + linebreak="al", + specials={ "font", 0x039C }, + unicodeslot=0x1D6ED, + }, + [0x1D6EE]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL NU", + direction="l", + linebreak="al", + specials={ "font", 0x039D }, + unicodeslot=0x1D6EE, + }, + [0x1D6EF]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL XI", + direction="l", + linebreak="al", + specials={ "font", 0x039E }, + unicodeslot=0x1D6EF, + }, + [0x1D6F0]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL OMICRON", + direction="l", + linebreak="al", + specials={ "font", 0x039F }, + unicodeslot=0x1D6F0, + }, + [0x1D6F1]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL PI", + direction="l", + linebreak="al", + specials={ "font", 0x03A0 }, + unicodeslot=0x1D6F1, + }, + [0x1D6F2]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL RHO", + direction="l", + linebreak="al", + specials={ "font", 0x03A1 }, + unicodeslot=0x1D6F2, + }, + [0x1D6F3]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL THETA SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03F4 }, + unicodeslot=0x1D6F3, + }, + [0x1D6F4]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL SIGMA", + direction="l", + linebreak="al", + specials={ "font", 0x03A3 }, + unicodeslot=0x1D6F4, + }, + [0x1D6F5]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL TAU", + direction="l", + linebreak="al", + specials={ "font", 0x03A4 }, + unicodeslot=0x1D6F5, + }, + [0x1D6F6]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL UPSILON", + direction="l", + linebreak="al", + specials={ "font", 0x03A5 }, + unicodeslot=0x1D6F6, + }, + [0x1D6F7]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL PHI", + direction="l", + linebreak="al", + specials={ "font", 0x03A6 }, + unicodeslot=0x1D6F7, + }, + [0x1D6F8]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL CHI", + direction="l", + linebreak="al", + specials={ "font", 0x03A7 }, + unicodeslot=0x1D6F8, + }, + [0x1D6F9]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL PSI", + direction="l", + linebreak="al", + specials={ "font", 0x03A8 }, + unicodeslot=0x1D6F9, + }, + [0x1D6FA]={ + category="lu", + description="MATHEMATICAL ITALIC CAPITAL OMEGA", + direction="l", + linebreak="al", + specials={ "font", 0x03A9 }, + unicodeslot=0x1D6FA, + }, + [0x1D6FB]={ + category="sm", + description="MATHEMATICAL ITALIC NABLA", + direction="l", + linebreak="al", + mathclass="default", + mathname="nabla", + specials={ "font", 0x2207 }, + unicodeslot=0x1D6FB, + }, + [0x1D6FC]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL ALPHA", + direction="l", + linebreak="al", + specials={ "font", 0x03B1 }, + unicodeslot=0x1D6FC, + }, + [0x1D6FD]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL BETA", + direction="l", + linebreak="al", + specials={ "font", 0x03B2 }, + unicodeslot=0x1D6FD, + }, + [0x1D6FE]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL GAMMA", + direction="l", + linebreak="al", + specials={ "font", 0x03B3 }, + unicodeslot=0x1D6FE, + }, + [0x1D6FF]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL DELTA", + direction="l", + linebreak="al", + specials={ "font", 0x03B4 }, + unicodeslot=0x1D6FF, + }, + [0x1D700]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL EPSILON", + direction="l", + linebreak="al", + specials={ "font", 0x03B5 }, + unicodeslot=0x1D700, + }, + [0x1D701]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL ZETA", + direction="l", + linebreak="al", + specials={ "font", 0x03B6 }, + unicodeslot=0x1D701, + }, + [0x1D702]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL ETA", + direction="l", + linebreak="al", + specials={ "font", 0x03B7 }, + unicodeslot=0x1D702, + }, + [0x1D703]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL THETA", + direction="l", + linebreak="al", + specials={ "font", 0x03B8 }, + unicodeslot=0x1D703, + }, + [0x1D704]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL IOTA", + direction="l", + linebreak="al", + specials={ "font", 0x03B9 }, + unicodeslot=0x1D704, + }, + [0x1D705]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL KAPPA", + direction="l", + linebreak="al", + specials={ "font", 0x03BA }, + unicodeslot=0x1D705, + }, + [0x1D706]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL LAMDA", + direction="l", + linebreak="al", + specials={ "font", 0x03BB }, + unicodeslot=0x1D706, + }, + [0x1D707]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL MU", + direction="l", + linebreak="al", + specials={ "font", 0x03BC }, + unicodeslot=0x1D707, + }, + [0x1D708]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL NU", + direction="l", + linebreak="al", + specials={ "font", 0x03BD }, + unicodeslot=0x1D708, + }, + [0x1D709]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL XI", + direction="l", + linebreak="al", + specials={ "font", 0x03BE }, + unicodeslot=0x1D709, + }, + [0x1D70A]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL OMICRON", + direction="l", + linebreak="al", + specials={ "font", 0x03BF }, + unicodeslot=0x1D70A, + }, + [0x1D70B]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL PI", + direction="l", + linebreak="al", + specials={ "font", 0x03C0 }, + unicodeslot=0x1D70B, + }, + [0x1D70C]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL RHO", + direction="l", + linebreak="al", + specials={ "font", 0x03C1 }, + unicodeslot=0x1D70C, + }, + [0x1D70D]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL FINAL SIGMA", + direction="l", + linebreak="al", + specials={ "font", 0x03C2 }, + unicodeslot=0x1D70D, + }, + [0x1D70E]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL SIGMA", + direction="l", + linebreak="al", + specials={ "font", 0x03C3 }, + unicodeslot=0x1D70E, + }, + [0x1D70F]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL TAU", + direction="l", + linebreak="al", + specials={ "font", 0x03C4 }, + unicodeslot=0x1D70F, + }, + [0x1D710]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL UPSILON", + direction="l", + linebreak="al", + specials={ "font", 0x03C5 }, + unicodeslot=0x1D710, + }, + [0x1D711]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL PHI", + direction="l", + linebreak="al", + specials={ "font", 0x03C6 }, + unicodeslot=0x1D711, + }, + [0x1D712]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL CHI", + direction="l", + linebreak="al", + specials={ "font", 0x03C7 }, + unicodeslot=0x1D712, + }, + [0x1D713]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL PSI", + direction="l", + linebreak="al", + specials={ "font", 0x03C8 }, + unicodeslot=0x1D713, + }, + [0x1D714]={ + category="ll", + description="MATHEMATICAL ITALIC SMALL OMEGA", + direction="l", + linebreak="al", + specials={ "font", 0x03C9 }, + unicodeslot=0x1D714, + }, + [0x1D715]={ + category="sm", + description="MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL", + direction="l", + linebreak="al", + specials={ "font", 0x2202 }, + unicodeslot=0x1D715, + }, + [0x1D716]={ + category="ll", + description="MATHEMATICAL ITALIC EPSILON SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03F5 }, + unicodeslot=0x1D716, + }, + [0x1D717]={ + category="ll", + description="MATHEMATICAL ITALIC THETA SYMBOL", + direction="l", + linebreak="al", + mathclass="default", + mathname="vartheta", + specials={ "font", 0x03D1 }, + unicodeslot=0x1D717, + }, + [0x1D718]={ + category="ll", + description="MATHEMATICAL ITALIC KAPPA SYMBOL", + direction="l", + linebreak="al", + mathclass="default", + mathname="varkappa", + specials={ "font", 0x03F0 }, + unicodeslot=0x1D718, + }, + [0x1D719]={ + category="ll", + description="MATHEMATICAL ITALIC PHI SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03D5 }, + unicodeslot=0x1D719, + }, + [0x1D71A]={ + category="ll", + description="MATHEMATICAL ITALIC RHO SYMBOL", + direction="l", + linebreak="al", + mathclass="variable", + mathname="varrho", + specials={ "font", 0x03F1 }, + unicodeslot=0x1D71A, + }, + [0x1D71B]={ + category="ll", + description="MATHEMATICAL ITALIC PI SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03D6 }, + unicodeslot=0x1D71B, + }, + [0x1D71C]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL ALPHA", + direction="l", + linebreak="al", + specials={ "font", 0x0391 }, + unicodeslot=0x1D71C, + }, + [0x1D71D]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL BETA", + direction="l", + linebreak="al", + specials={ "font", 0x0392 }, + unicodeslot=0x1D71D, + }, + [0x1D71E]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL GAMMA", + direction="l", + linebreak="al", + specials={ "font", 0x0393 }, + unicodeslot=0x1D71E, + }, + [0x1D71F]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL DELTA", + direction="l", + linebreak="al", + specials={ "font", 0x0394 }, + unicodeslot=0x1D71F, + }, + [0x1D720]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL EPSILON", + direction="l", + linebreak="al", + specials={ "font", 0x0395 }, + unicodeslot=0x1D720, + }, + [0x1D721]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL ZETA", + direction="l", + linebreak="al", + specials={ "font", 0x0396 }, + unicodeslot=0x1D721, + }, + [0x1D722]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL ETA", + direction="l", + linebreak="al", + specials={ "font", 0x0397 }, + unicodeslot=0x1D722, + }, + [0x1D723]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL THETA", + direction="l", + linebreak="al", + specials={ "font", 0x0398 }, + unicodeslot=0x1D723, + }, + [0x1D724]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL IOTA", + direction="l", + linebreak="al", + specials={ "font", 0x0399 }, + unicodeslot=0x1D724, + }, + [0x1D725]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL KAPPA", + direction="l", + linebreak="al", + specials={ "font", 0x039A }, + unicodeslot=0x1D725, + }, + [0x1D726]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL LAMDA", + direction="l", + linebreak="al", + specials={ "font", 0x039B }, + unicodeslot=0x1D726, + }, + [0x1D727]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL MU", + direction="l", + linebreak="al", + specials={ "font", 0x039C }, + unicodeslot=0x1D727, + }, + [0x1D728]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL NU", + direction="l", + linebreak="al", + specials={ "font", 0x039D }, + unicodeslot=0x1D728, + }, + [0x1D729]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL XI", + direction="l", + linebreak="al", + specials={ "font", 0x039E }, + unicodeslot=0x1D729, + }, + [0x1D72A]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL OMICRON", + direction="l", + linebreak="al", + specials={ "font", 0x039F }, + unicodeslot=0x1D72A, + }, + [0x1D72B]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL PI", + direction="l", + linebreak="al", + specials={ "font", 0x03A0 }, + unicodeslot=0x1D72B, + }, + [0x1D72C]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL RHO", + direction="l", + linebreak="al", + specials={ "font", 0x03A1 }, + unicodeslot=0x1D72C, + }, + [0x1D72D]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL THETA SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03F4 }, + unicodeslot=0x1D72D, + }, + [0x1D72E]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL SIGMA", + direction="l", + linebreak="al", + specials={ "font", 0x03A3 }, + unicodeslot=0x1D72E, + }, + [0x1D72F]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL TAU", + direction="l", + linebreak="al", + specials={ "font", 0x03A4 }, + unicodeslot=0x1D72F, + }, + [0x1D730]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL UPSILON", + direction="l", + linebreak="al", + specials={ "font", 0x03A5 }, + unicodeslot=0x1D730, + }, + [0x1D731]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL PHI", + direction="l", + linebreak="al", + specials={ "font", 0x03A6 }, + unicodeslot=0x1D731, + }, + [0x1D732]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL CHI", + direction="l", + linebreak="al", + specials={ "font", 0x03A7 }, + unicodeslot=0x1D732, + }, + [0x1D733]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL PSI", + direction="l", + linebreak="al", + specials={ "font", 0x03A8 }, + unicodeslot=0x1D733, + }, + [0x1D734]={ + category="lu", + description="MATHEMATICAL BOLD ITALIC CAPITAL OMEGA", + direction="l", + linebreak="al", + specials={ "font", 0x03A9 }, + unicodeslot=0x1D734, + }, + [0x1D735]={ + category="sm", + description="MATHEMATICAL BOLD ITALIC NABLA", + direction="l", + linebreak="al", + specials={ "font", 0x2207 }, + unicodeslot=0x1D735, + }, + [0x1D736]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL ALPHA", + direction="l", + linebreak="al", + specials={ "font", 0x03B1 }, + unicodeslot=0x1D736, + }, + [0x1D737]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL BETA", + direction="l", + linebreak="al", + specials={ "font", 0x03B2 }, + unicodeslot=0x1D737, + }, + [0x1D738]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL GAMMA", + direction="l", + linebreak="al", + specials={ "font", 0x03B3 }, + unicodeslot=0x1D738, + }, + [0x1D739]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL DELTA", + direction="l", + linebreak="al", + specials={ "font", 0x03B4 }, + unicodeslot=0x1D739, + }, + [0x1D73A]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL EPSILON", + direction="l", + linebreak="al", + specials={ "font", 0x03B5 }, + unicodeslot=0x1D73A, + }, + [0x1D73B]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL ZETA", + direction="l", + linebreak="al", + specials={ "font", 0x03B6 }, + unicodeslot=0x1D73B, + }, + [0x1D73C]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL ETA", + direction="l", + linebreak="al", + specials={ "font", 0x03B7 }, + unicodeslot=0x1D73C, + }, + [0x1D73D]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL THETA", + direction="l", + linebreak="al", + specials={ "font", 0x03B8 }, + unicodeslot=0x1D73D, + }, + [0x1D73E]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL IOTA", + direction="l", + linebreak="al", + specials={ "font", 0x03B9 }, + unicodeslot=0x1D73E, + }, + [0x1D73F]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL KAPPA", + direction="l", + linebreak="al", + specials={ "font", 0x03BA }, + unicodeslot=0x1D73F, + }, + [0x1D740]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL LAMDA", + direction="l", + linebreak="al", + specials={ "font", 0x03BB }, + unicodeslot=0x1D740, + }, + [0x1D741]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL MU", + direction="l", + linebreak="al", + specials={ "font", 0x03BC }, + unicodeslot=0x1D741, + }, + [0x1D742]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL NU", + direction="l", + linebreak="al", + specials={ "font", 0x03BD }, + unicodeslot=0x1D742, + }, + [0x1D743]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL XI", + direction="l", + linebreak="al", + specials={ "font", 0x03BE }, + unicodeslot=0x1D743, + }, + [0x1D744]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL OMICRON", + direction="l", + linebreak="al", + specials={ "font", 0x03BF }, + unicodeslot=0x1D744, + }, + [0x1D745]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL PI", + direction="l", + linebreak="al", + specials={ "font", 0x03C0 }, + unicodeslot=0x1D745, + }, + [0x1D746]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL RHO", + direction="l", + linebreak="al", + specials={ "font", 0x03C1 }, + unicodeslot=0x1D746, + }, + [0x1D747]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL FINAL SIGMA", + direction="l", + linebreak="al", + specials={ "font", 0x03C2 }, + unicodeslot=0x1D747, + }, + [0x1D748]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL SIGMA", + direction="l", + linebreak="al", + specials={ "font", 0x03C3 }, + unicodeslot=0x1D748, + }, + [0x1D749]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL TAU", + direction="l", + linebreak="al", + specials={ "font", 0x03C4 }, + unicodeslot=0x1D749, + }, + [0x1D74A]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL UPSILON", + direction="l", + linebreak="al", + specials={ "font", 0x03C5 }, + unicodeslot=0x1D74A, + }, + [0x1D74B]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL PHI", + direction="l", + linebreak="al", + specials={ "font", 0x03C6 }, + unicodeslot=0x1D74B, + }, + [0x1D74C]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL CHI", + direction="l", + linebreak="al", + specials={ "font", 0x03C7 }, + unicodeslot=0x1D74C, + }, + [0x1D74D]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL PSI", + direction="l", + linebreak="al", + specials={ "font", 0x03C8 }, + unicodeslot=0x1D74D, + }, + [0x1D74E]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC SMALL OMEGA", + direction="l", + linebreak="al", + specials={ "font", 0x03C9 }, + unicodeslot=0x1D74E, + }, + [0x1D74F]={ + category="sm", + description="MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL", + direction="l", + linebreak="al", + specials={ "font", 0x2202 }, + unicodeslot=0x1D74F, + }, + [0x1D750]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC EPSILON SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03F5 }, + unicodeslot=0x1D750, + }, + [0x1D751]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC THETA SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03D1 }, + unicodeslot=0x1D751, + }, + [0x1D752]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC KAPPA SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03F0 }, + unicodeslot=0x1D752, + }, + [0x1D753]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC PHI SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03D5 }, + unicodeslot=0x1D753, + }, + [0x1D754]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC RHO SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03F1 }, + unicodeslot=0x1D754, + }, + [0x1D755]={ + category="ll", + description="MATHEMATICAL BOLD ITALIC PI SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03D6 }, + unicodeslot=0x1D755, + }, + [0x1D756]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA", + direction="l", + linebreak="al", + specials={ "font", 0x0391 }, + unicodeslot=0x1D756, + }, + [0x1D757]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL BETA", + direction="l", + linebreak="al", + specials={ "font", 0x0392 }, + unicodeslot=0x1D757, + }, + [0x1D758]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL GAMMA", + direction="l", + linebreak="al", + specials={ "font", 0x0393 }, + unicodeslot=0x1D758, + }, + [0x1D759]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL DELTA", + direction="l", + linebreak="al", + specials={ "font", 0x0394 }, + unicodeslot=0x1D759, + }, + [0x1D75A]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL EPSILON", + direction="l", + linebreak="al", + specials={ "font", 0x0395 }, + unicodeslot=0x1D75A, + }, + [0x1D75B]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL ZETA", + direction="l", + linebreak="al", + specials={ "font", 0x0396 }, + unicodeslot=0x1D75B, + }, + [0x1D75C]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL ETA", + direction="l", + linebreak="al", + specials={ "font", 0x0397 }, + unicodeslot=0x1D75C, + }, + [0x1D75D]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA", + direction="l", + linebreak="al", + specials={ "font", 0x0398 }, + unicodeslot=0x1D75D, + }, + [0x1D75E]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL IOTA", + direction="l", + linebreak="al", + specials={ "font", 0x0399 }, + unicodeslot=0x1D75E, + }, + [0x1D75F]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL KAPPA", + direction="l", + linebreak="al", + specials={ "font", 0x039A }, + unicodeslot=0x1D75F, + }, + [0x1D760]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL LAMDA", + direction="l", + linebreak="al", + specials={ "font", 0x039B }, + unicodeslot=0x1D760, + }, + [0x1D761]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL MU", + direction="l", + linebreak="al", + specials={ "font", 0x039C }, + unicodeslot=0x1D761, + }, + [0x1D762]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL NU", + direction="l", + linebreak="al", + specials={ "font", 0x039D }, + unicodeslot=0x1D762, + }, + [0x1D763]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL XI", + direction="l", + linebreak="al", + specials={ "font", 0x039E }, + unicodeslot=0x1D763, + }, + [0x1D764]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL OMICRON", + direction="l", + linebreak="al", + specials={ "font", 0x039F }, + unicodeslot=0x1D764, + }, + [0x1D765]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL PI", + direction="l", + linebreak="al", + specials={ "font", 0x03A0 }, + unicodeslot=0x1D765, + }, + [0x1D766]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL RHO", + direction="l", + linebreak="al", + specials={ "font", 0x03A1 }, + unicodeslot=0x1D766, + }, + [0x1D767]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03F4 }, + unicodeslot=0x1D767, + }, + [0x1D768]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL SIGMA", + direction="l", + linebreak="al", + specials={ "font", 0x03A3 }, + unicodeslot=0x1D768, + }, + [0x1D769]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL TAU", + direction="l", + linebreak="al", + specials={ "font", 0x03A4 }, + unicodeslot=0x1D769, + }, + [0x1D76A]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL UPSILON", + direction="l", + linebreak="al", + specials={ "font", 0x03A5 }, + unicodeslot=0x1D76A, + }, + [0x1D76B]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL PHI", + direction="l", + linebreak="al", + specials={ "font", 0x03A6 }, + unicodeslot=0x1D76B, + }, + [0x1D76C]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL CHI", + direction="l", + linebreak="al", + specials={ "font", 0x03A7 }, + unicodeslot=0x1D76C, + }, + [0x1D76D]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL PSI", + direction="l", + linebreak="al", + specials={ "font", 0x03A8 }, + unicodeslot=0x1D76D, + }, + [0x1D76E]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA", + direction="l", + linebreak="al", + specials={ "font", 0x03A9 }, + unicodeslot=0x1D76E, + }, + [0x1D76F]={ + category="sm", + description="MATHEMATICAL SANS-SERIF BOLD NABLA", + direction="l", + linebreak="al", + specials={ "font", 0x2207 }, + unicodeslot=0x1D76F, + }, + [0x1D770]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA", + direction="l", + linebreak="al", + specials={ "font", 0x03B1 }, + unicodeslot=0x1D770, + }, + [0x1D771]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL BETA", + direction="l", + linebreak="al", + specials={ "font", 0x03B2 }, + unicodeslot=0x1D771, + }, + [0x1D772]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL GAMMA", + direction="l", + linebreak="al", + specials={ "font", 0x03B3 }, + unicodeslot=0x1D772, + }, + [0x1D773]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL DELTA", + direction="l", + linebreak="al", + specials={ "font", 0x03B4 }, + unicodeslot=0x1D773, + }, + [0x1D774]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL EPSILON", + direction="l", + linebreak="al", + specials={ "font", 0x03B5 }, + unicodeslot=0x1D774, + }, + [0x1D775]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL ZETA", + direction="l", + linebreak="al", + specials={ "font", 0x03B6 }, + unicodeslot=0x1D775, + }, + [0x1D776]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL ETA", + direction="l", + linebreak="al", + specials={ "font", 0x03B7 }, + unicodeslot=0x1D776, + }, + [0x1D777]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL THETA", + direction="l", + linebreak="al", + specials={ "font", 0x03B8 }, + unicodeslot=0x1D777, + }, + [0x1D778]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL IOTA", + direction="l", + linebreak="al", + specials={ "font", 0x03B9 }, + unicodeslot=0x1D778, + }, + [0x1D779]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL KAPPA", + direction="l", + linebreak="al", + specials={ "font", 0x03BA }, + unicodeslot=0x1D779, + }, + [0x1D77A]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL LAMDA", + direction="l", + linebreak="al", + specials={ "font", 0x03BB }, + unicodeslot=0x1D77A, + }, + [0x1D77B]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL MU", + direction="l", + linebreak="al", + specials={ "font", 0x03BC }, + unicodeslot=0x1D77B, + }, + [0x1D77C]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL NU", + direction="l", + linebreak="al", + specials={ "font", 0x03BD }, + unicodeslot=0x1D77C, + }, + [0x1D77D]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL XI", + direction="l", + linebreak="al", + specials={ "font", 0x03BE }, + unicodeslot=0x1D77D, + }, + [0x1D77E]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL OMICRON", + direction="l", + linebreak="al", + specials={ "font", 0x03BF }, + unicodeslot=0x1D77E, + }, + [0x1D77F]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL PI", + direction="l", + linebreak="al", + specials={ "font", 0x03C0 }, + unicodeslot=0x1D77F, + }, + [0x1D780]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL RHO", + direction="l", + linebreak="al", + specials={ "font", 0x03C1 }, + unicodeslot=0x1D780, + }, + [0x1D781]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL FINAL SIGMA", + direction="l", + linebreak="al", + specials={ "font", 0x03C2 }, + unicodeslot=0x1D781, + }, + [0x1D782]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL SIGMA", + direction="l", + linebreak="al", + specials={ "font", 0x03C3 }, + unicodeslot=0x1D782, + }, + [0x1D783]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL TAU", + direction="l", + linebreak="al", + specials={ "font", 0x03C4 }, + unicodeslot=0x1D783, + }, + [0x1D784]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL UPSILON", + direction="l", + linebreak="al", + specials={ "font", 0x03C5 }, + unicodeslot=0x1D784, + }, + [0x1D785]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL PHI", + direction="l", + linebreak="al", + specials={ "font", 0x03C6 }, + unicodeslot=0x1D785, + }, + [0x1D786]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL CHI", + direction="l", + linebreak="al", + specials={ "font", 0x03C7 }, + unicodeslot=0x1D786, + }, + [0x1D787]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL PSI", + direction="l", + linebreak="al", + specials={ "font", 0x03C8 }, + unicodeslot=0x1D787, + }, + [0x1D788]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA", + direction="l", + linebreak="al", + specials={ "font", 0x03C9 }, + unicodeslot=0x1D788, + }, + [0x1D789]={ + category="sm", + description="MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL", + direction="l", + linebreak="al", + specials={ "font", 0x2202 }, + unicodeslot=0x1D789, + }, + [0x1D78A]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03F5 }, + unicodeslot=0x1D78A, + }, + [0x1D78B]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD THETA SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03D1 }, + unicodeslot=0x1D78B, + }, + [0x1D78C]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD KAPPA SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03F0 }, + unicodeslot=0x1D78C, + }, + [0x1D78D]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD PHI SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03D5 }, + unicodeslot=0x1D78D, + }, + [0x1D78E]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD RHO SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03F1 }, + unicodeslot=0x1D78E, + }, + [0x1D78F]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD PI SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03D6 }, + unicodeslot=0x1D78F, + }, + [0x1D790]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA", + direction="l", + linebreak="al", + specials={ "font", 0x0391 }, + unicodeslot=0x1D790, + }, + [0x1D791]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL BETA", + direction="l", + linebreak="al", + specials={ "font", 0x0392 }, + unicodeslot=0x1D791, + }, + [0x1D792]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL GAMMA", + direction="l", + linebreak="al", + specials={ "font", 0x0393 }, + unicodeslot=0x1D792, + }, + [0x1D793]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL DELTA", + direction="l", + linebreak="al", + specials={ "font", 0x0394 }, + unicodeslot=0x1D793, + }, + [0x1D794]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL EPSILON", + direction="l", + linebreak="al", + specials={ "font", 0x0395 }, + unicodeslot=0x1D794, + }, + [0x1D795]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ZETA", + direction="l", + linebreak="al", + specials={ "font", 0x0396 }, + unicodeslot=0x1D795, + }, + [0x1D796]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ETA", + direction="l", + linebreak="al", + specials={ "font", 0x0397 }, + unicodeslot=0x1D796, + }, + [0x1D797]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA", + direction="l", + linebreak="al", + specials={ "font", 0x0398 }, + unicodeslot=0x1D797, + }, + [0x1D798]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL IOTA", + direction="l", + linebreak="al", + specials={ "font", 0x0399 }, + unicodeslot=0x1D798, + }, + [0x1D799]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL KAPPA", + direction="l", + linebreak="al", + specials={ "font", 0x039A }, + unicodeslot=0x1D799, + }, + [0x1D79A]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL LAMDA", + direction="l", + linebreak="al", + specials={ "font", 0x039B }, + unicodeslot=0x1D79A, + }, + [0x1D79B]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL MU", + direction="l", + linebreak="al", + specials={ "font", 0x039C }, + unicodeslot=0x1D79B, + }, + [0x1D79C]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL NU", + direction="l", + linebreak="al", + specials={ "font", 0x039D }, + unicodeslot=0x1D79C, + }, + [0x1D79D]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL XI", + direction="l", + linebreak="al", + specials={ "font", 0x039E }, + unicodeslot=0x1D79D, + }, + [0x1D79E]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMICRON", + direction="l", + linebreak="al", + specials={ "font", 0x039F }, + unicodeslot=0x1D79E, + }, + [0x1D79F]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PI", + direction="l", + linebreak="al", + specials={ "font", 0x03A0 }, + unicodeslot=0x1D79F, + }, + [0x1D7A0]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL RHO", + direction="l", + linebreak="al", + specials={ "font", 0x03A1 }, + unicodeslot=0x1D7A0, + }, + [0x1D7A1]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03F4 }, + unicodeslot=0x1D7A1, + }, + [0x1D7A2]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL SIGMA", + direction="l", + linebreak="al", + specials={ "font", 0x03A3 }, + unicodeslot=0x1D7A2, + }, + [0x1D7A3]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL TAU", + direction="l", + linebreak="al", + specials={ "font", 0x03A4 }, + unicodeslot=0x1D7A3, + }, + [0x1D7A4]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL UPSILON", + direction="l", + linebreak="al", + specials={ "font", 0x03A5 }, + unicodeslot=0x1D7A4, + }, + [0x1D7A5]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PHI", + direction="l", + linebreak="al", + specials={ "font", 0x03A6 }, + unicodeslot=0x1D7A5, + }, + [0x1D7A6]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL CHI", + direction="l", + linebreak="al", + specials={ "font", 0x03A7 }, + unicodeslot=0x1D7A6, + }, + [0x1D7A7]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PSI", + direction="l", + linebreak="al", + specials={ "font", 0x03A8 }, + unicodeslot=0x1D7A7, + }, + [0x1D7A8]={ + category="lu", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA", + direction="l", + linebreak="al", + specials={ "font", 0x03A9 }, + unicodeslot=0x1D7A8, + }, + [0x1D7A9]={ + category="sm", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA", + direction="l", + linebreak="al", + specials={ "font", 0x2207 }, + unicodeslot=0x1D7A9, + }, + [0x1D7AA]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA", + direction="l", + linebreak="al", + specials={ "font", 0x03B1 }, + unicodeslot=0x1D7AA, + }, + [0x1D7AB]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL BETA", + direction="l", + linebreak="al", + specials={ "font", 0x03B2 }, + unicodeslot=0x1D7AB, + }, + [0x1D7AC]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL GAMMA", + direction="l", + linebreak="al", + specials={ "font", 0x03B3 }, + unicodeslot=0x1D7AC, + }, + [0x1D7AD]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL DELTA", + direction="l", + linebreak="al", + specials={ "font", 0x03B4 }, + unicodeslot=0x1D7AD, + }, + [0x1D7AE]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL EPSILON", + direction="l", + linebreak="al", + specials={ "font", 0x03B5 }, + unicodeslot=0x1D7AE, + }, + [0x1D7AF]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ZETA", + direction="l", + linebreak="al", + specials={ "font", 0x03B6 }, + unicodeslot=0x1D7AF, + }, + [0x1D7B0]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ETA", + direction="l", + linebreak="al", + specials={ "font", 0x03B7 }, + unicodeslot=0x1D7B0, + }, + [0x1D7B1]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL THETA", + direction="l", + linebreak="al", + specials={ "font", 0x03B8 }, + unicodeslot=0x1D7B1, + }, + [0x1D7B2]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL IOTA", + direction="l", + linebreak="al", + specials={ "font", 0x03B9 }, + unicodeslot=0x1D7B2, + }, + [0x1D7B3]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL KAPPA", + direction="l", + linebreak="al", + specials={ "font", 0x03BA }, + unicodeslot=0x1D7B3, + }, + [0x1D7B4]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL LAMDA", + direction="l", + linebreak="al", + specials={ "font", 0x03BB }, + unicodeslot=0x1D7B4, + }, + [0x1D7B5]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL MU", + direction="l", + linebreak="al", + specials={ "font", 0x03BC }, + unicodeslot=0x1D7B5, + }, + [0x1D7B6]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL NU", + direction="l", + linebreak="al", + specials={ "font", 0x03BD }, + unicodeslot=0x1D7B6, + }, + [0x1D7B7]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL XI", + direction="l", + linebreak="al", + specials={ "font", 0x03BE }, + unicodeslot=0x1D7B7, + }, + [0x1D7B8]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMICRON", + direction="l", + linebreak="al", + specials={ "font", 0x03BF }, + unicodeslot=0x1D7B8, + }, + [0x1D7B9]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PI", + direction="l", + linebreak="al", + specials={ "font", 0x03C0 }, + unicodeslot=0x1D7B9, + }, + [0x1D7BA]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL RHO", + direction="l", + linebreak="al", + specials={ "font", 0x03C1 }, + unicodeslot=0x1D7BA, + }, + [0x1D7BB]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL FINAL SIGMA", + direction="l", + linebreak="al", + specials={ "font", 0x03C2 }, + unicodeslot=0x1D7BB, + }, + [0x1D7BC]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL SIGMA", + direction="l", + linebreak="al", + specials={ "font", 0x03C3 }, + unicodeslot=0x1D7BC, + }, + [0x1D7BD]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL TAU", + direction="l", + linebreak="al", + specials={ "font", 0x03C4 }, + unicodeslot=0x1D7BD, + }, + [0x1D7BE]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL UPSILON", + direction="l", + linebreak="al", + specials={ "font", 0x03C5 }, + unicodeslot=0x1D7BE, + }, + [0x1D7BF]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PHI", + direction="l", + linebreak="al", + specials={ "font", 0x03C6 }, + unicodeslot=0x1D7BF, + }, + [0x1D7C0]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL CHI", + direction="l", + linebreak="al", + specials={ "font", 0x03C7 }, + unicodeslot=0x1D7C0, + }, + [0x1D7C1]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PSI", + direction="l", + linebreak="al", + specials={ "font", 0x03C8 }, + unicodeslot=0x1D7C1, + }, + [0x1D7C2]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA", + direction="l", + linebreak="al", + specials={ "font", 0x03C9 }, + unicodeslot=0x1D7C2, + }, + [0x1D7C3]={ + category="sm", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL", + direction="l", + linebreak="al", + specials={ "font", 0x2202 }, + unicodeslot=0x1D7C3, + }, + [0x1D7C4]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03F5 }, + unicodeslot=0x1D7C4, + }, + [0x1D7C5]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC THETA SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03D1 }, + unicodeslot=0x1D7C5, + }, + [0x1D7C6]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC KAPPA SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03F0 }, + unicodeslot=0x1D7C6, + }, + [0x1D7C7]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC PHI SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03D5 }, + unicodeslot=0x1D7C7, + }, + [0x1D7C8]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC RHO SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03F1 }, + unicodeslot=0x1D7C8, + }, + [0x1D7C9]={ + category="ll", + description="MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL", + direction="l", + linebreak="al", + specials={ "font", 0x03D6 }, + unicodeslot=0x1D7C9, + }, + [0x1D7CA]={ + category="lu", + description="MATHEMATICAL BOLD CAPITAL DIGAMMA", + direction="l", + linebreak="al", + specials={ "font", 0x03DC }, + unicodeslot=0x1D7CA, + }, + [0x1D7CB]={ + category="ll", + description="MATHEMATICAL BOLD SMALL DIGAMMA", + direction="l", + linebreak="al", + specials={ "font", 0x03DD }, + unicodeslot=0x1D7CB, + }, + [0x1D7CE]={ + category="nd", + description="MATHEMATICAL BOLD DIGIT ZERO", + direction="en", + linebreak="nu", + specials={ "font", 0x0030 }, + unicodeslot=0x1D7CE, + }, + [0x1D7CF]={ + category="nd", + description="MATHEMATICAL BOLD DIGIT ONE", + direction="en", + linebreak="nu", + specials={ "font", 0x0031 }, + unicodeslot=0x1D7CF, + }, + [0x1D7D0]={ + category="nd", + description="MATHEMATICAL BOLD DIGIT TWO", + direction="en", + linebreak="nu", + specials={ "font", 0x0032 }, + unicodeslot=0x1D7D0, + }, + [0x1D7D1]={ + category="nd", + description="MATHEMATICAL BOLD DIGIT THREE", + direction="en", + linebreak="nu", + specials={ "font", 0x0033 }, + unicodeslot=0x1D7D1, + }, + [0x1D7D2]={ + category="nd", + description="MATHEMATICAL BOLD DIGIT FOUR", + direction="en", + linebreak="nu", + specials={ "font", 0x0034 }, + unicodeslot=0x1D7D2, + }, + [0x1D7D3]={ + category="nd", + description="MATHEMATICAL BOLD DIGIT FIVE", + direction="en", + linebreak="nu", + specials={ "font", 0x0035 }, + unicodeslot=0x1D7D3, + }, + [0x1D7D4]={ + category="nd", + description="MATHEMATICAL BOLD DIGIT SIX", + direction="en", + linebreak="nu", + specials={ "font", 0x0036 }, + unicodeslot=0x1D7D4, + }, + [0x1D7D5]={ + category="nd", + description="MATHEMATICAL BOLD DIGIT SEVEN", + direction="en", + linebreak="nu", + specials={ "font", 0x0037 }, + unicodeslot=0x1D7D5, + }, + [0x1D7D6]={ + category="nd", + description="MATHEMATICAL BOLD DIGIT EIGHT", + direction="en", + linebreak="nu", + specials={ "font", 0x0038 }, + unicodeslot=0x1D7D6, + }, + [0x1D7D7]={ + category="nd", + description="MATHEMATICAL BOLD DIGIT NINE", + direction="en", + linebreak="nu", + specials={ "font", 0x0039 }, + unicodeslot=0x1D7D7, + }, + [0x1D7D8]={ + category="nd", + description="MATHEMATICAL DOUBLE-STRUCK DIGIT ZERO", + direction="en", + linebreak="nu", + specials={ "font", 0x0030 }, + unicodeslot=0x1D7D8, + }, + [0x1D7D9]={ + category="nd", + description="MATHEMATICAL DOUBLE-STRUCK DIGIT ONE", + direction="en", + linebreak="nu", + specials={ "font", 0x0031 }, + unicodeslot=0x1D7D9, + }, + [0x1D7DA]={ + category="nd", + description="MATHEMATICAL DOUBLE-STRUCK DIGIT TWO", + direction="en", + linebreak="nu", + specials={ "font", 0x0032 }, + unicodeslot=0x1D7DA, + }, + [0x1D7DB]={ + category="nd", + description="MATHEMATICAL DOUBLE-STRUCK DIGIT THREE", + direction="en", + linebreak="nu", + specials={ "font", 0x0033 }, + unicodeslot=0x1D7DB, + }, + [0x1D7DC]={ + category="nd", + description="MATHEMATICAL DOUBLE-STRUCK DIGIT FOUR", + direction="en", + linebreak="nu", + specials={ "font", 0x0034 }, + unicodeslot=0x1D7DC, + }, + [0x1D7DD]={ + category="nd", + description="MATHEMATICAL DOUBLE-STRUCK DIGIT FIVE", + direction="en", + linebreak="nu", + specials={ "font", 0x0035 }, + unicodeslot=0x1D7DD, + }, + [0x1D7DE]={ + category="nd", + description="MATHEMATICAL DOUBLE-STRUCK DIGIT SIX", + direction="en", + linebreak="nu", + specials={ "font", 0x0036 }, + unicodeslot=0x1D7DE, + }, + [0x1D7DF]={ + category="nd", + description="MATHEMATICAL DOUBLE-STRUCK DIGIT SEVEN", + direction="en", + linebreak="nu", + specials={ "font", 0x0037 }, + unicodeslot=0x1D7DF, + }, + [0x1D7E0]={ + category="nd", + description="MATHEMATICAL DOUBLE-STRUCK DIGIT EIGHT", + direction="en", + linebreak="nu", + specials={ "font", 0x0038 }, + unicodeslot=0x1D7E0, + }, + [0x1D7E1]={ + category="nd", + description="MATHEMATICAL DOUBLE-STRUCK DIGIT NINE", + direction="en", + linebreak="nu", + specials={ "font", 0x0039 }, + unicodeslot=0x1D7E1, + }, + [0x1D7E2]={ + category="nd", + description="MATHEMATICAL SANS-SERIF DIGIT ZERO", + direction="en", + linebreak="nu", + specials={ "font", 0x0030 }, + unicodeslot=0x1D7E2, + }, + [0x1D7E3]={ + category="nd", + description="MATHEMATICAL SANS-SERIF DIGIT ONE", + direction="en", + linebreak="nu", + specials={ "font", 0x0031 }, + unicodeslot=0x1D7E3, + }, + [0x1D7E4]={ + category="nd", + description="MATHEMATICAL SANS-SERIF DIGIT TWO", + direction="en", + linebreak="nu", + specials={ "font", 0x0032 }, + unicodeslot=0x1D7E4, + }, + [0x1D7E5]={ + category="nd", + description="MATHEMATICAL SANS-SERIF DIGIT THREE", + direction="en", + linebreak="nu", + specials={ "font", 0x0033 }, + unicodeslot=0x1D7E5, + }, + [0x1D7E6]={ + category="nd", + description="MATHEMATICAL SANS-SERIF DIGIT FOUR", + direction="en", + linebreak="nu", + specials={ "font", 0x0034 }, + unicodeslot=0x1D7E6, + }, + [0x1D7E7]={ + category="nd", + description="MATHEMATICAL SANS-SERIF DIGIT FIVE", + direction="en", + linebreak="nu", + specials={ "font", 0x0035 }, + unicodeslot=0x1D7E7, + }, + [0x1D7E8]={ + category="nd", + description="MATHEMATICAL SANS-SERIF DIGIT SIX", + direction="en", + linebreak="nu", + specials={ "font", 0x0036 }, + unicodeslot=0x1D7E8, + }, + [0x1D7E9]={ + category="nd", + description="MATHEMATICAL SANS-SERIF DIGIT SEVEN", + direction="en", + linebreak="nu", + specials={ "font", 0x0037 }, + unicodeslot=0x1D7E9, + }, + [0x1D7EA]={ + category="nd", + description="MATHEMATICAL SANS-SERIF DIGIT EIGHT", + direction="en", + linebreak="nu", + specials={ "font", 0x0038 }, + unicodeslot=0x1D7EA, + }, + [0x1D7EB]={ + category="nd", + description="MATHEMATICAL SANS-SERIF DIGIT NINE", + direction="en", + linebreak="nu", + specials={ "font", 0x0039 }, + unicodeslot=0x1D7EB, + }, + [0x1D7EC]={ + category="nd", + description="MATHEMATICAL SANS-SERIF BOLD DIGIT ZERO", + direction="en", + linebreak="nu", + specials={ "font", 0x0030 }, + unicodeslot=0x1D7EC, + }, + [0x1D7ED]={ + category="nd", + description="MATHEMATICAL SANS-SERIF BOLD DIGIT ONE", + direction="en", + linebreak="nu", + specials={ "font", 0x0031 }, + unicodeslot=0x1D7ED, + }, + [0x1D7EE]={ + category="nd", + description="MATHEMATICAL SANS-SERIF BOLD DIGIT TWO", + direction="en", + linebreak="nu", + specials={ "font", 0x0032 }, + unicodeslot=0x1D7EE, + }, + [0x1D7EF]={ + category="nd", + description="MATHEMATICAL SANS-SERIF BOLD DIGIT THREE", + direction="en", + linebreak="nu", + specials={ "font", 0x0033 }, + unicodeslot=0x1D7EF, + }, + [0x1D7F0]={ + category="nd", + description="MATHEMATICAL SANS-SERIF BOLD DIGIT FOUR", + direction="en", + linebreak="nu", + specials={ "font", 0x0034 }, + unicodeslot=0x1D7F0, + }, + [0x1D7F1]={ + category="nd", + description="MATHEMATICAL SANS-SERIF BOLD DIGIT FIVE", + direction="en", + linebreak="nu", + specials={ "font", 0x0035 }, + unicodeslot=0x1D7F1, + }, + [0x1D7F2]={ + category="nd", + description="MATHEMATICAL SANS-SERIF BOLD DIGIT SIX", + direction="en", + linebreak="nu", + specials={ "font", 0x0036 }, + unicodeslot=0x1D7F2, + }, + [0x1D7F3]={ + category="nd", + description="MATHEMATICAL SANS-SERIF BOLD DIGIT SEVEN", + direction="en", + linebreak="nu", + specials={ "font", 0x0037 }, + unicodeslot=0x1D7F3, + }, + [0x1D7F4]={ + category="nd", + description="MATHEMATICAL SANS-SERIF BOLD DIGIT EIGHT", + direction="en", + linebreak="nu", + specials={ "font", 0x0038 }, + unicodeslot=0x1D7F4, + }, + [0x1D7F5]={ + category="nd", + description="MATHEMATICAL SANS-SERIF BOLD DIGIT NINE", + direction="en", + linebreak="nu", + specials={ "font", 0x0039 }, + unicodeslot=0x1D7F5, + }, + [0x1D7F6]={ + category="nd", + description="MATHEMATICAL MONOSPACE DIGIT ZERO", + direction="en", + linebreak="nu", + specials={ "font", 0x0030 }, + unicodeslot=0x1D7F6, + }, + [0x1D7F7]={ + category="nd", + description="MATHEMATICAL MONOSPACE DIGIT ONE", + direction="en", + linebreak="nu", + specials={ "font", 0x0031 }, + unicodeslot=0x1D7F7, + }, + [0x1D7F8]={ + category="nd", + description="MATHEMATICAL MONOSPACE DIGIT TWO", + direction="en", + linebreak="nu", + specials={ "font", 0x0032 }, + unicodeslot=0x1D7F8, + }, + [0x1D7F9]={ + category="nd", + description="MATHEMATICAL MONOSPACE DIGIT THREE", + direction="en", + linebreak="nu", + specials={ "font", 0x0033 }, + unicodeslot=0x1D7F9, + }, + [0x1D7FA]={ + category="nd", + description="MATHEMATICAL MONOSPACE DIGIT FOUR", + direction="en", + linebreak="nu", + specials={ "font", 0x0034 }, + unicodeslot=0x1D7FA, + }, + [0x1D7FB]={ + category="nd", + description="MATHEMATICAL MONOSPACE DIGIT FIVE", + direction="en", + linebreak="nu", + specials={ "font", 0x0035 }, + unicodeslot=0x1D7FB, + }, + [0x1D7FC]={ + category="nd", + description="MATHEMATICAL MONOSPACE DIGIT SIX", + direction="en", + linebreak="nu", + specials={ "font", 0x0036 }, + unicodeslot=0x1D7FC, + }, + [0x1D7FD]={ + category="nd", + description="MATHEMATICAL MONOSPACE DIGIT SEVEN", + direction="en", + linebreak="nu", + specials={ "font", 0x0037 }, + unicodeslot=0x1D7FD, + }, + [0x1D7FE]={ + category="nd", + description="MATHEMATICAL MONOSPACE DIGIT EIGHT", + direction="en", + linebreak="nu", + specials={ "font", 0x0038 }, + unicodeslot=0x1D7FE, + }, + [0x1D7FF]={ + category="nd", + description="MATHEMATICAL MONOSPACE DIGIT NINE", + direction="en", + linebreak="nu", + specials={ "font", 0x0039 }, + unicodeslot=0x1D7FF, + }, + [0x20000]={ + category="lo", + cjkwd="w", + description="", + direction="l", + linebreak="id", + unicodeslot=0x20000, + range=0x2A6D6, + }, + [0x2F800]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0320", + direction="l", + linebreak="id", + specials={ "char", 0x4E3D }, + unicodeslot=0x2F800, + }, + [0x2F801]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0321", + direction="l", + linebreak="id", + specials={ "char", 0x4E38 }, + unicodeslot=0x2F801, + }, + [0x2F802]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0322", + direction="l", + linebreak="id", + specials={ "char", 0x4E41 }, + unicodeslot=0x2F802, + }, + [0x2F803]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0323", + direction="l", + linebreak="id", + specials={ "char", 0x20122 }, + unicodeslot=0x2F803, + }, + [0x2F804]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0324", + direction="l", + linebreak="id", + specials={ "char", 0x4F60 }, + unicodeslot=0x2F804, + }, + [0x2F805]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0325", + direction="l", + linebreak="id", + specials={ "char", 0x4FAE }, + unicodeslot=0x2F805, + }, + [0x2F806]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0326", + direction="l", + linebreak="id", + specials={ "char", 0x4FBB }, + unicodeslot=0x2F806, + }, + [0x2F807]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0327", + direction="l", + linebreak="id", + specials={ "char", 0x5002 }, + unicodeslot=0x2F807, + }, + [0x2F808]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0328", + direction="l", + linebreak="id", + specials={ "char", 0x507A }, + unicodeslot=0x2F808, + }, + [0x2F809]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0329", + direction="l", + linebreak="id", + specials={ "char", 0x5099 }, + unicodeslot=0x2F809, + }, + [0x2F80A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0050A", + direction="l", + linebreak="id", + specials={ "char", 0x50E7 }, + unicodeslot=0x2F80A, + }, + [0x2F80B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0050B", + direction="l", + linebreak="id", + specials={ "char", 0x50CF }, + unicodeslot=0x2F80B, + }, + [0x2F80C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0050C", + direction="l", + linebreak="id", + specials={ "char", 0x349E }, + unicodeslot=0x2F80C, + }, + [0x2F80D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0050D", + direction="l", + linebreak="id", + specials={ "char", 0x2063A }, + unicodeslot=0x2F80D, + }, + [0x2F80E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0050E", + direction="l", + linebreak="id", + specials={ "char", 0x514D }, + unicodeslot=0x2F80E, + }, + [0x2F80F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0050F", + direction="l", + linebreak="id", + specials={ "char", 0x5154 }, + unicodeslot=0x2F80F, + }, + [0x2F810]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x032A", + direction="l", + linebreak="id", + specials={ "char", 0x5164 }, + unicodeslot=0x2F810, + }, + [0x2F811]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x032B", + direction="l", + linebreak="id", + specials={ "char", 0x5177 }, + unicodeslot=0x2F811, + }, + [0x2F812]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x032C", + direction="l", + linebreak="id", + specials={ "char", 0x2051C }, + unicodeslot=0x2F812, + }, + [0x2F813]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x032D", + direction="l", + linebreak="id", + specials={ "char", 0x34B9 }, + unicodeslot=0x2F813, + }, + [0x2F814]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x032E", + direction="l", + linebreak="id", + specials={ "char", 0x5167 }, + unicodeslot=0x2F814, + }, + [0x2F815]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x032F", + direction="l", + linebreak="id", + specials={ "char", 0x518D }, + unicodeslot=0x2F815, + }, + [0x2F816]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0330", + direction="l", + linebreak="id", + specials={ "char", 0x2054B }, + unicodeslot=0x2F816, + }, + [0x2F817]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0331", + direction="l", + linebreak="id", + specials={ "char", 0x5197 }, + unicodeslot=0x2F817, + }, + [0x2F818]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0332", + direction="l", + linebreak="id", + specials={ "char", 0x51A4 }, + unicodeslot=0x2F818, + }, + [0x2F819]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0333", + direction="l", + linebreak="id", + specials={ "char", 0x4ECC }, + unicodeslot=0x2F819, + }, + [0x2F81A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0051A", + direction="l", + linebreak="id", + specials={ "char", 0x51AC }, + unicodeslot=0x2F81A, + }, + [0x2F81B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0051B", + direction="l", + linebreak="id", + specials={ "char", 0x51B5 }, + unicodeslot=0x2F81B, + }, + [0x2F81C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0051C", + direction="l", + linebreak="id", + specials={ "char", 0x291DF }, + unicodeslot=0x2F81C, + }, + [0x2F81D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0051D", + direction="l", + linebreak="id", + specials={ "char", 0x51F5 }, + unicodeslot=0x2F81D, + }, + [0x2F81E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0051E", + direction="l", + linebreak="id", + specials={ "char", 0x5203 }, + unicodeslot=0x2F81E, + }, + [0x2F81F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0051F", + direction="l", + linebreak="id", + specials={ "char", 0x34DF }, + unicodeslot=0x2F81F, + }, + [0x2F820]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0334", + direction="l", + linebreak="id", + specials={ "char", 0x523B }, + unicodeslot=0x2F820, + }, + [0x2F821]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0335", + direction="l", + linebreak="id", + specials={ "char", 0x5246 }, + unicodeslot=0x2F821, + }, + [0x2F822]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0336", + direction="l", + linebreak="id", + specials={ "char", 0x5272 }, + unicodeslot=0x2F822, + }, + [0x2F823]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0337", + direction="l", + linebreak="id", + specials={ "char", 0x5277 }, + unicodeslot=0x2F823, + }, + [0x2F824]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0338", + direction="l", + linebreak="id", + specials={ "char", 0x3515 }, + unicodeslot=0x2F824, + }, + [0x2F825]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0339", + direction="l", + linebreak="id", + specials={ "char", 0x52C7 }, + unicodeslot=0x2F825, + }, + [0x2F826]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x033A", + direction="l", + linebreak="id", + specials={ "char", 0x52C9 }, + unicodeslot=0x2F826, + }, + [0x2F827]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x033B", + direction="l", + linebreak="id", + specials={ "char", 0x52E4 }, + unicodeslot=0x2F827, + }, + [0x2F828]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x033C", + direction="l", + linebreak="id", + specials={ "char", 0x52FA }, + unicodeslot=0x2F828, + }, + [0x2F829]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x033D", + direction="l", + linebreak="id", + specials={ "char", 0x5305 }, + unicodeslot=0x2F829, + }, + [0x2F82A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0052A", + direction="l", + linebreak="id", + specials={ "char", 0x5306 }, + unicodeslot=0x2F82A, + }, + [0x2F82B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0052B", + direction="l", + linebreak="id", + specials={ "char", 0x5317 }, + unicodeslot=0x2F82B, + }, + [0x2F82C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0052C", + direction="l", + linebreak="id", + specials={ "char", 0x5349 }, + unicodeslot=0x2F82C, + }, + [0x2F82D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0052D", + direction="l", + linebreak="id", + specials={ "char", 0x5351 }, + unicodeslot=0x2F82D, + }, + [0x2F82E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0052E", + direction="l", + linebreak="id", + specials={ "char", 0x535A }, + unicodeslot=0x2F82E, + }, + [0x2F82F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0052F", + direction="l", + linebreak="id", + specials={ "char", 0x5373 }, + unicodeslot=0x2F82F, + }, + [0x2F830]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x033E", + direction="l", + linebreak="id", + specials={ "char", 0x537D }, + unicodeslot=0x2F830, + }, + [0x2F831]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x033F", + direction="l", + linebreak="id", + specials={ "char", 0x537F }, + unicodeslot=0x2F831, + }, + [0x2F832]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0340", + direction="l", + linebreak="id", + specials={ "char", 0x537F }, + unicodeslot=0x2F832, + }, + [0x2F833]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0341", + direction="l", + linebreak="id", + specials={ "char", 0x537F }, + unicodeslot=0x2F833, + }, + [0x2F834]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0342", + direction="l", + linebreak="id", + specials={ "char", 0x20A2C }, + unicodeslot=0x2F834, + }, + [0x2F835]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0343", + direction="l", + linebreak="id", + specials={ "char", 0x7070 }, + unicodeslot=0x2F835, + }, + [0x2F836]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0344", + direction="l", + linebreak="id", + specials={ "char", 0x53CA }, + unicodeslot=0x2F836, + }, + [0x2F837]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0345", + direction="l", + linebreak="id", + specials={ "char", 0x53DF }, + unicodeslot=0x2F837, + }, + [0x2F838]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0346", + direction="l", + linebreak="id", + specials={ "char", 0x20B63 }, + unicodeslot=0x2F838, + }, + [0x2F839]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0347", + direction="l", + linebreak="id", + specials={ "char", 0x53EB }, + unicodeslot=0x2F839, + }, + [0x2F83A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0053A", + direction="l", + linebreak="id", + specials={ "char", 0x53F1 }, + unicodeslot=0x2F83A, + }, + [0x2F83B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0053B", + direction="l", + linebreak="id", + specials={ "char", 0x5406 }, + unicodeslot=0x2F83B, + }, + [0x2F83C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0053C", + direction="l", + linebreak="id", + specials={ "char", 0x549E }, + unicodeslot=0x2F83C, + }, + [0x2F83D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0053D", + direction="l", + linebreak="id", + specials={ "char", 0x5438 }, + unicodeslot=0x2F83D, + }, + [0x2F83E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0053E", + direction="l", + linebreak="id", + specials={ "char", 0x5448 }, + unicodeslot=0x2F83E, + }, + [0x2F83F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0053F", + direction="l", + linebreak="id", + specials={ "char", 0x5468 }, + unicodeslot=0x2F83F, + }, + [0x2F840]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0348", + direction="l", + linebreak="id", + specials={ "char", 0x54A2 }, + unicodeslot=0x2F840, + }, + [0x2F841]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0349", + direction="l", + linebreak="id", + specials={ "char", 0x54F6 }, + unicodeslot=0x2F841, + }, + [0x2F842]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x034A", + direction="l", + linebreak="id", + specials={ "char", 0x5510 }, + unicodeslot=0x2F842, + }, + [0x2F843]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x034B", + direction="l", + linebreak="id", + specials={ "char", 0x5553 }, + unicodeslot=0x2F843, + }, + [0x2F844]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x034C", + direction="l", + linebreak="id", + specials={ "char", 0x5563 }, + unicodeslot=0x2F844, + }, + [0x2F845]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x034D", + direction="l", + linebreak="id", + specials={ "char", 0x5584 }, + unicodeslot=0x2F845, + }, + [0x2F846]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x034E", + direction="l", + linebreak="id", + specials={ "char", 0x5584 }, + unicodeslot=0x2F846, + }, + [0x2F847]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x034F", + direction="l", + linebreak="id", + specials={ "char", 0x5599 }, + unicodeslot=0x2F847, + }, + [0x2F848]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0350", + direction="l", + linebreak="id", + specials={ "char", 0x55AB }, + unicodeslot=0x2F848, + }, + [0x2F849]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0351", + direction="l", + linebreak="id", + specials={ "char", 0x55B3 }, + unicodeslot=0x2F849, + }, + [0x2F84A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0054A", + direction="l", + linebreak="id", + specials={ "char", 0x55C2 }, + unicodeslot=0x2F84A, + }, + [0x2F84B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0054B", + direction="l", + linebreak="id", + specials={ "char", 0x5716 }, + unicodeslot=0x2F84B, + }, + [0x2F84C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0054C", + direction="l", + linebreak="id", + specials={ "char", 0x5606 }, + unicodeslot=0x2F84C, + }, + [0x2F84D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0054D", + direction="l", + linebreak="id", + specials={ "char", 0x5717 }, + unicodeslot=0x2F84D, + }, + [0x2F84E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0054E", + direction="l", + linebreak="id", + specials={ "char", 0x5651 }, + unicodeslot=0x2F84E, + }, + [0x2F84F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0054F", + direction="l", + linebreak="id", + specials={ "char", 0x5674 }, + unicodeslot=0x2F84F, + }, + [0x2F850]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0352", + direction="l", + linebreak="id", + specials={ "char", 0x5207 }, + unicodeslot=0x2F850, + }, + [0x2F851]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0353", + direction="l", + linebreak="id", + specials={ "char", 0x58EE }, + unicodeslot=0x2F851, + }, + [0x2F852]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0354", + direction="l", + linebreak="id", + specials={ "char", 0x57CE }, + unicodeslot=0x2F852, + }, + [0x2F853]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0355", + direction="l", + linebreak="id", + specials={ "char", 0x57F4 }, + unicodeslot=0x2F853, + }, + [0x2F854]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0356", + direction="l", + linebreak="id", + specials={ "char", 0x580D }, + unicodeslot=0x2F854, + }, + [0x2F855]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0357", + direction="l", + linebreak="id", + specials={ "char", 0x578B }, + unicodeslot=0x2F855, + }, + [0x2F856]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0358", + direction="l", + linebreak="id", + specials={ "char", 0x5832 }, + unicodeslot=0x2F856, + }, + [0x2F857]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0359", + direction="l", + linebreak="id", + specials={ "char", 0x5831 }, + unicodeslot=0x2F857, + }, + [0x2F858]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x035A", + direction="l", + linebreak="id", + specials={ "char", 0x58AC }, + unicodeslot=0x2F858, + }, + [0x2F859]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x035B", + direction="l", + linebreak="id", + specials={ "char", 0x214E4 }, + unicodeslot=0x2F859, + }, + [0x2F85A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0055A", + direction="l", + linebreak="id", + specials={ "char", 0x58F2 }, + unicodeslot=0x2F85A, + }, + [0x2F85B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0055B", + direction="l", + linebreak="id", + specials={ "char", 0x58F7 }, + unicodeslot=0x2F85B, + }, + [0x2F85C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0055C", + direction="l", + linebreak="id", + specials={ "char", 0x5906 }, + unicodeslot=0x2F85C, + }, + [0x2F85D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0055D", + direction="l", + linebreak="id", + specials={ "char", 0x591A }, + unicodeslot=0x2F85D, + }, + [0x2F85E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0055E", + direction="l", + linebreak="id", + specials={ "char", 0x5922 }, + unicodeslot=0x2F85E, + }, + [0x2F85F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0055F", + direction="l", + linebreak="id", + specials={ "char", 0x5962 }, + unicodeslot=0x2F85F, + }, + [0x2F860]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x035C", + direction="l", + linebreak="id", + specials={ "char", 0x216A8 }, + unicodeslot=0x2F860, + }, + [0x2F861]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x035D", + direction="l", + linebreak="id", + specials={ "char", 0x216EA }, + unicodeslot=0x2F861, + }, + [0x2F862]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x035E", + direction="l", + linebreak="id", + specials={ "char", 0x59EC }, + unicodeslot=0x2F862, + }, + [0x2F863]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x035F", + direction="l", + linebreak="id", + specials={ "char", 0x5A1B }, + unicodeslot=0x2F863, + }, + [0x2F864]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0360", + direction="l", + linebreak="id", + specials={ "char", 0x5A27 }, + unicodeslot=0x2F864, + }, + [0x2F865]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0361", + direction="l", + linebreak="id", + specials={ "char", 0x59D8 }, + unicodeslot=0x2F865, + }, + [0x2F866]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0362", + direction="l", + linebreak="id", + specials={ "char", 0x5A66 }, + unicodeslot=0x2F866, + }, + [0x2F867]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0363", + direction="l", + linebreak="id", + specials={ "char", 0x36EE }, + unicodeslot=0x2F867, + }, + [0x2F868]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0364", + direction="l", + linebreak="id", + specials={ "char", 0x36FC }, + unicodeslot=0x2F868, + }, + [0x2F869]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0365", + direction="l", + linebreak="id", + specials={ "char", 0x5B08 }, + unicodeslot=0x2F869, + }, + [0x2F86A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0056A", + direction="l", + linebreak="id", + specials={ "char", 0x5B3E }, + unicodeslot=0x2F86A, + }, + [0x2F86B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0056B", + direction="l", + linebreak="id", + specials={ "char", 0x5B3E }, + unicodeslot=0x2F86B, + }, + [0x2F86C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0056C", + direction="l", + linebreak="id", + specials={ "char", 0x219C8 }, + unicodeslot=0x2F86C, + }, + [0x2F86D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0056D", + direction="l", + linebreak="id", + specials={ "char", 0x5BC3 }, + unicodeslot=0x2F86D, + }, + [0x2F86E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0056E", + direction="l", + linebreak="id", + specials={ "char", 0x5BD8 }, + unicodeslot=0x2F86E, + }, + [0x2F86F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0056F", + direction="l", + linebreak="id", + specials={ "char", 0x5BE7 }, + unicodeslot=0x2F86F, + }, + [0x2F870]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0366", + direction="l", + linebreak="id", + specials={ "char", 0x5BF3 }, + unicodeslot=0x2F870, + }, + [0x2F871]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0367", + direction="l", + linebreak="id", + specials={ "char", 0x21B18 }, + unicodeslot=0x2F871, + }, + [0x2F872]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0368", + direction="l", + linebreak="id", + specials={ "char", 0x5BFF }, + unicodeslot=0x2F872, + }, + [0x2F873]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0369", + direction="l", + linebreak="id", + specials={ "char", 0x5C06 }, + unicodeslot=0x2F873, + }, + [0x2F874]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x036A", + direction="l", + linebreak="id", + specials={ "char", 0x5F53 }, + unicodeslot=0x2F874, + }, + [0x2F875]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x036B", + direction="l", + linebreak="id", + specials={ "char", 0x5C22 }, + unicodeslot=0x2F875, + }, + [0x2F876]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x036C", + direction="l", + linebreak="id", + specials={ "char", 0x3781 }, + unicodeslot=0x2F876, + }, + [0x2F877]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x036D", + direction="l", + linebreak="id", + specials={ "char", 0x5C60 }, + unicodeslot=0x2F877, + }, + [0x2F878]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x036E", + direction="l", + linebreak="id", + specials={ "char", 0x5C6E }, + unicodeslot=0x2F878, + }, + [0x2F879]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x036F", + direction="l", + linebreak="id", + specials={ "char", 0x5CC0 }, + unicodeslot=0x2F879, + }, + [0x2F87A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0057A", + direction="l", + linebreak="id", + specials={ "char", 0x5C8D }, + unicodeslot=0x2F87A, + }, + [0x2F87B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0057B", + direction="l", + linebreak="id", + specials={ "char", 0x21DE4 }, + unicodeslot=0x2F87B, + }, + [0x2F87C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0057C", + direction="l", + linebreak="id", + specials={ "char", 0x5D43 }, + unicodeslot=0x2F87C, + }, + [0x2F87D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0057D", + direction="l", + linebreak="id", + specials={ "char", 0x21DE6 }, + unicodeslot=0x2F87D, + }, + [0x2F87E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0057E", + direction="l", + linebreak="id", + specials={ "char", 0x5D6E }, + unicodeslot=0x2F87E, + }, + [0x2F87F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0057F", + direction="l", + linebreak="id", + specials={ "char", 0x5D6B }, + unicodeslot=0x2F87F, + }, + [0x2F880]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0370", + direction="l", + linebreak="id", + specials={ "char", 0x5D7C }, + unicodeslot=0x2F880, + }, + [0x2F881]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0371", + direction="l", + linebreak="id", + specials={ "char", 0x5DE1 }, + unicodeslot=0x2F881, + }, + [0x2F882]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0372", + direction="l", + linebreak="id", + specials={ "char", 0x5DE2 }, + unicodeslot=0x2F882, + }, + [0x2F883]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0373", + direction="l", + linebreak="id", + specials={ "char", 0x382F }, + unicodeslot=0x2F883, + }, + [0x2F884]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0374", + direction="l", + linebreak="id", + specials={ "char", 0x5DFD }, + unicodeslot=0x2F884, + }, + [0x2F885]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0375", + direction="l", + linebreak="id", + specials={ "char", 0x5E28 }, + unicodeslot=0x2F885, + }, + [0x2F886]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0376", + direction="l", + linebreak="id", + specials={ "char", 0x5E3D }, + unicodeslot=0x2F886, + }, + [0x2F887]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0377", + direction="l", + linebreak="id", + specials={ "char", 0x5E69 }, + unicodeslot=0x2F887, + }, + [0x2F888]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0378", + direction="l", + linebreak="id", + specials={ "char", 0x3862 }, + unicodeslot=0x2F888, + }, + [0x2F889]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0379", + direction="l", + linebreak="id", + specials={ "char", 0x22183 }, + unicodeslot=0x2F889, + }, + [0x2F88A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0058A", + direction="l", + linebreak="id", + specials={ "char", 0x387C }, + unicodeslot=0x2F88A, + }, + [0x2F88B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0058B", + direction="l", + linebreak="id", + specials={ "char", 0x5EB0 }, + unicodeslot=0x2F88B, + }, + [0x2F88C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0058C", + direction="l", + linebreak="id", + specials={ "char", 0x5EB3 }, + unicodeslot=0x2F88C, + }, + [0x2F88D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0058D", + direction="l", + linebreak="id", + specials={ "char", 0x5EB6 }, + unicodeslot=0x2F88D, + }, + [0x2F88E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0058E", + direction="l", + linebreak="id", + specials={ "char", 0x5ECA }, + unicodeslot=0x2F88E, + }, + [0x2F88F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0058F", + direction="l", + linebreak="id", + specials={ "char", 0x2A392 }, + unicodeslot=0x2F88F, + }, + [0x2F890]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x037A", + direction="l", + linebreak="id", + specials={ "char", 0x5EFE }, + unicodeslot=0x2F890, + }, + [0x2F891]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x037B", + direction="l", + linebreak="id", + specials={ "char", 0x22331 }, + unicodeslot=0x2F891, + }, + [0x2F892]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x037C", + direction="l", + linebreak="id", + specials={ "char", 0x22331 }, + unicodeslot=0x2F892, + }, + [0x2F893]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x037D", + direction="l", + linebreak="id", + specials={ "char", 0x8201 }, + unicodeslot=0x2F893, + }, + [0x2F894]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x037E", + direction="l", + linebreak="id", + specials={ "char", 0x5F22 }, + unicodeslot=0x2F894, + }, + [0x2F895]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x037F", + direction="l", + linebreak="id", + specials={ "char", 0x5F22 }, + unicodeslot=0x2F895, + }, + [0x2F896]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0380", + direction="l", + linebreak="id", + specials={ "char", 0x38C7 }, + unicodeslot=0x2F896, + }, + [0x2F897]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0381", + direction="l", + linebreak="id", + specials={ "char", 0x232B8 }, + unicodeslot=0x2F897, + }, + [0x2F898]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0382", + direction="l", + linebreak="id", + specials={ "char", 0x261DA }, + unicodeslot=0x2F898, + }, + [0x2F899]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0383", + direction="l", + linebreak="id", + specials={ "char", 0x5F62 }, + unicodeslot=0x2F899, + }, + [0x2F89A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0059A", + direction="l", + linebreak="id", + specials={ "char", 0x5F6B }, + unicodeslot=0x2F89A, + }, + [0x2F89B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0059B", + direction="l", + linebreak="id", + specials={ "char", 0x38E3 }, + unicodeslot=0x2F89B, + }, + [0x2F89C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0059C", + direction="l", + linebreak="id", + specials={ "char", 0x5F9A }, + unicodeslot=0x2F89C, + }, + [0x2F89D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0059D", + direction="l", + linebreak="id", + specials={ "char", 0x5FCD }, + unicodeslot=0x2F89D, + }, + [0x2F89E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0059E", + direction="l", + linebreak="id", + specials={ "char", 0x5FD7 }, + unicodeslot=0x2F89E, + }, + [0x2F89F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0059F", + direction="l", + linebreak="id", + specials={ "char", 0x5FF9 }, + unicodeslot=0x2F89F, + }, + [0x2F8A0]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008A0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x6081 }, + unicodeslot=0x2F8A0, + }, + [0x2F8A1]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008A0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x393A }, + unicodeslot=0x2F8A1, + }, + [0x2F8A2]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008A0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x391C }, + unicodeslot=0x2F8A2, + }, + [0x2F8A3]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008A0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x6094 }, + unicodeslot=0x2F8A3, + }, + [0x2F8A4]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008A0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x226D4 }, + unicodeslot=0x2F8A4, + }, + [0x2F8A5]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008A0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x60C7 }, + unicodeslot=0x2F8A5, + }, + [0x2F8A6]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008A0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x6148 }, + unicodeslot=0x2F8A6, + }, + [0x2F8A7]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008A0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x614C }, + unicodeslot=0x2F8A7, + }, + [0x2F8A8]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008A0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x614E }, + unicodeslot=0x2F8A8, + }, + [0x2F8A9]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008A0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x614C }, + unicodeslot=0x2F8A9, + }, + [0x2F8AA]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008AA", + direction="l", + linebreak="id", + specials={ "char", 0x617A }, + unicodeslot=0x2F8AA, + }, + [0x2F8AB]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008AB", + direction="l", + linebreak="id", + specials={ "char", 0x618E }, + unicodeslot=0x2F8AB, + }, + [0x2F8AC]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008AC", + direction="l", + linebreak="id", + specials={ "char", 0x61B2 }, + unicodeslot=0x2F8AC, + }, + [0x2F8AD]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008AD", + direction="l", + linebreak="id", + specials={ "char", 0x61A4 }, + unicodeslot=0x2F8AD, + }, + [0x2F8AE]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008AE", + direction="l", + linebreak="id", + specials={ "char", 0x61AF }, + unicodeslot=0x2F8AE, + }, + [0x2F8AF]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008AF", + direction="l", + linebreak="id", + specials={ "char", 0x61DE }, + unicodeslot=0x2F8AF, + }, + [0x2F8B0]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008B0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x61F2 }, + unicodeslot=0x2F8B0, + }, + [0x2F8B1]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008B0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x61F6 }, + unicodeslot=0x2F8B1, + }, + [0x2F8B2]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008B0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x6210 }, + unicodeslot=0x2F8B2, + }, + [0x2F8B3]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008B0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x621B }, + unicodeslot=0x2F8B3, + }, + [0x2F8B4]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008B0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x625D }, + unicodeslot=0x2F8B4, + }, + [0x2F8B5]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008B0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x62B1 }, + unicodeslot=0x2F8B5, + }, + [0x2F8B6]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008B0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x62D4 }, + unicodeslot=0x2F8B6, + }, + [0x2F8B7]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008B0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x6350 }, + unicodeslot=0x2F8B7, + }, + [0x2F8B8]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008B0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x22B0C }, + unicodeslot=0x2F8B8, + }, + [0x2F8B9]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008B0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x633D }, + unicodeslot=0x2F8B9, + }, + [0x2F8BA]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008BA", + direction="l", + linebreak="id", + specials={ "char", 0x62FC }, + unicodeslot=0x2F8BA, + }, + [0x2F8BB]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008BB", + direction="l", + linebreak="id", + specials={ "char", 0x6368 }, + unicodeslot=0x2F8BB, + }, + [0x2F8BC]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008BC", + direction="l", + linebreak="id", + specials={ "char", 0x6383 }, + unicodeslot=0x2F8BC, + }, + [0x2F8BD]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008BD", + direction="l", + linebreak="id", + specials={ "char", 0x63E4 }, + unicodeslot=0x2F8BD, + }, + [0x2F8BE]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008BE", + direction="l", + linebreak="id", + specials={ "char", 0x22BF1 }, + unicodeslot=0x2F8BE, + }, + [0x2F8BF]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008BF", + direction="l", + linebreak="id", + specials={ "char", 0x6422 }, + unicodeslot=0x2F8BF, + }, + [0x2F8C0]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008C0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x63C5 }, + unicodeslot=0x2F8C0, + }, + [0x2F8C1]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008C0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x63A9 }, + unicodeslot=0x2F8C1, + }, + [0x2F8C2]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008C0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x3A2E }, + unicodeslot=0x2F8C2, + }, + [0x2F8C3]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008C0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x6469 }, + unicodeslot=0x2F8C3, + }, + [0x2F8C4]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008C0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x647E }, + unicodeslot=0x2F8C4, + }, + [0x2F8C5]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008C0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x649D }, + unicodeslot=0x2F8C5, + }, + [0x2F8C6]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008C0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x6477 }, + unicodeslot=0x2F8C6, + }, + [0x2F8C7]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008C0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x3A6C }, + unicodeslot=0x2F8C7, + }, + [0x2F8C8]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008C0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x654F }, + unicodeslot=0x2F8C8, + }, + [0x2F8C9]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008C0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x656C }, + unicodeslot=0x2F8C9, + }, + [0x2F8CA]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008CA", + direction="l", + linebreak="id", + specials={ "char", 0x2300A }, + unicodeslot=0x2F8CA, + }, + [0x2F8CB]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008CB", + direction="l", + linebreak="id", + specials={ "char", 0x65E3 }, + unicodeslot=0x2F8CB, + }, + [0x2F8CC]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008CC", + direction="l", + linebreak="id", + specials={ "char", 0x66F8 }, + unicodeslot=0x2F8CC, + }, + [0x2F8CD]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008CD", + direction="l", + linebreak="id", + specials={ "char", 0x6649 }, + unicodeslot=0x2F8CD, + }, + [0x2F8CE]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008CE", + direction="l", + linebreak="id", + specials={ "char", 0x3B19 }, + unicodeslot=0x2F8CE, + }, + [0x2F8CF]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008CF", + direction="l", + linebreak="id", + specials={ "char", 0x6691 }, + unicodeslot=0x2F8CF, + }, + [0x2F8D0]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008D0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x3B08 }, + unicodeslot=0x2F8D0, + }, + [0x2F8D1]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008D0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x3AE4 }, + unicodeslot=0x2F8D1, + }, + [0x2F8D2]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008D0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x5192 }, + unicodeslot=0x2F8D2, + }, + [0x2F8D3]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008D0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x5195 }, + unicodeslot=0x2F8D3, + }, + [0x2F8D4]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008D0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x6700 }, + unicodeslot=0x2F8D4, + }, + [0x2F8D5]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008D0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x669C }, + unicodeslot=0x2F8D5, + }, + [0x2F8D6]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008D0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x80AD }, + unicodeslot=0x2F8D6, + }, + [0x2F8D7]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008D0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x43D9 }, + unicodeslot=0x2F8D7, + }, + [0x2F8D8]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008D0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x6717 }, + unicodeslot=0x2F8D8, + }, + [0x2F8D9]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008D0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x671B }, + unicodeslot=0x2F8D9, + }, + [0x2F8DA]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008DA", + direction="l", + linebreak="id", + specials={ "char", 0x6721 }, + unicodeslot=0x2F8DA, + }, + [0x2F8DB]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008DB", + direction="l", + linebreak="id", + specials={ "char", 0x675E }, + unicodeslot=0x2F8DB, + }, + [0x2F8DC]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008DC", + direction="l", + linebreak="id", + specials={ "char", 0x6753 }, + unicodeslot=0x2F8DC, + }, + [0x2F8DD]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008DD", + direction="l", + linebreak="id", + specials={ "char", 0x233C3 }, + unicodeslot=0x2F8DD, + }, + [0x2F8DE]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008DE", + direction="l", + linebreak="id", + specials={ "char", 0x3B49 }, + unicodeslot=0x2F8DE, + }, + [0x2F8DF]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008DF", + direction="l", + linebreak="id", + specials={ "char", 0x67FA }, + unicodeslot=0x2F8DF, + }, + [0x2F8E0]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008E0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x6785 }, + unicodeslot=0x2F8E0, + }, + [0x2F8E1]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008E0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x6852 }, + unicodeslot=0x2F8E1, + }, + [0x2F8E2]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008E0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x6885 }, + unicodeslot=0x2F8E2, + }, + [0x2F8E3]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008E0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x2346D }, + unicodeslot=0x2F8E3, + }, + [0x2F8E4]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008E0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x688E }, + unicodeslot=0x2F8E4, + }, + [0x2F8E5]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008E0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x681F }, + unicodeslot=0x2F8E5, + }, + [0x2F8E6]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008E0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x6914 }, + unicodeslot=0x2F8E6, + }, + [0x2F8E7]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008E0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x3B9D }, + unicodeslot=0x2F8E7, + }, + [0x2F8E8]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008E0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x6942 }, + unicodeslot=0x2F8E8, + }, + [0x2F8E9]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008E0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x69A3 }, + unicodeslot=0x2F8E9, + }, + [0x2F8EA]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008EA", + direction="l", + linebreak="id", + specials={ "char", 0x69EA }, + unicodeslot=0x2F8EA, + }, + [0x2F8EB]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008EB", + direction="l", + linebreak="id", + specials={ "char", 0x6AA8 }, + unicodeslot=0x2F8EB, + }, + [0x2F8EC]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008EC", + direction="l", + linebreak="id", + specials={ "char", 0x236A3 }, + unicodeslot=0x2F8EC, + }, + [0x2F8ED]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008ED", + direction="l", + linebreak="id", + specials={ "char", 0x6ADB }, + unicodeslot=0x2F8ED, + }, + [0x2F8EE]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008EE", + direction="l", + linebreak="id", + specials={ "char", 0x3C18 }, + unicodeslot=0x2F8EE, + }, + [0x2F8EF]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008EF", + direction="l", + linebreak="id", + specials={ "char", 0x6B21 }, + unicodeslot=0x2F8EF, + }, + [0x2F8F0]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008F0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x238A7 }, + unicodeslot=0x2F8F0, + }, + [0x2F8F1]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008F0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x6B54 }, + unicodeslot=0x2F8F1, + }, + [0x2F8F2]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008F0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x3C4E }, + unicodeslot=0x2F8F2, + }, + [0x2F8F3]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008F0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x6B72 }, + unicodeslot=0x2F8F3, + }, + [0x2F8F4]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008F0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x6B9F }, + unicodeslot=0x2F8F4, + }, + [0x2F8F5]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008F0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x6BBA }, + unicodeslot=0x2F8F5, + }, + [0x2F8F6]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008F0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x6BBB }, + unicodeslot=0x2F8F6, + }, + [0x2F8F7]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008F0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x23A8D }, + unicodeslot=0x2F8F7, + }, + [0x2F8F8]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008F0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x21D0B }, + unicodeslot=0x2F8F8, + }, + [0x2F8F9]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008F0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x23AFA }, + unicodeslot=0x2F8F9, + }, + [0x2F8FA]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008FA", + direction="l", + linebreak="id", + specials={ "char", 0x6C4E }, + unicodeslot=0x2F8FA, + }, + [0x2F8FB]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008FB", + direction="l", + linebreak="id", + specials={ "char", 0x23CBC }, + unicodeslot=0x2F8FB, + }, + [0x2F8FC]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008FC", + direction="l", + linebreak="id", + specials={ "char", 0x6CBF }, + unicodeslot=0x2F8FC, + }, + [0x2F8FD]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008FD", + direction="l", + linebreak="id", + specials={ "char", 0x6CCD }, + unicodeslot=0x2F8FD, + }, + [0x2F8FE]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008FE", + direction="l", + linebreak="id", + specials={ "char", 0x6C67 }, + unicodeslot=0x2F8FE, + }, + [0x2F8FF]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008FF", + direction="l", + linebreak="id", + specials={ "char", 0x6D16 }, + unicodeslot=0x2F8FF, + }, + [0x2F900]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0384", + direction="l", + linebreak="id", + specials={ "char", 0x6D3E }, + unicodeslot=0x2F900, + }, + [0x2F901]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0385", + direction="l", + linebreak="id", + specials={ "char", 0x6D77 }, + unicodeslot=0x2F901, + }, + [0x2F902]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0386", + direction="l", + linebreak="id", + specials={ "char", 0x6D41 }, + unicodeslot=0x2F902, + }, + [0x2F903]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0387", + direction="l", + linebreak="id", + specials={ "char", 0x6D69 }, + unicodeslot=0x2F903, + }, + [0x2F904]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0388", + direction="l", + linebreak="id", + specials={ "char", 0x6D78 }, + unicodeslot=0x2F904, + }, + [0x2F905]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0389", + direction="l", + linebreak="id", + specials={ "char", 0x6D85 }, + unicodeslot=0x2F905, + }, + [0x2F906]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x038A", + direction="l", + linebreak="id", + specials={ "char", 0x23D1E }, + unicodeslot=0x2F906, + }, + [0x2F907]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x038B", + direction="l", + linebreak="id", + specials={ "char", 0x6D34 }, + unicodeslot=0x2F907, + }, + [0x2F908]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x038C", + direction="l", + linebreak="id", + specials={ "char", 0x6E2F }, + unicodeslot=0x2F908, + }, + [0x2F909]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x038D", + direction="l", + linebreak="id", + specials={ "char", 0x6E6E }, + unicodeslot=0x2F909, + }, + [0x2F90A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005AA", + direction="l", + linebreak="id", + specials={ "char", 0x3D33 }, + unicodeslot=0x2F90A, + }, + [0x2F90B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005AB", + direction="l", + linebreak="id", + specials={ "char", 0x6ECB }, + unicodeslot=0x2F90B, + }, + [0x2F90C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005AC", + direction="l", + linebreak="id", + specials={ "char", 0x6EC7 }, + unicodeslot=0x2F90C, + }, + [0x2F90D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005AD", + direction="l", + linebreak="id", + specials={ "char", 0x23ED1 }, + unicodeslot=0x2F90D, + }, + [0x2F90E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005AE", + direction="l", + linebreak="id", + specials={ "char", 0x6DF9 }, + unicodeslot=0x2F90E, + }, + [0x2F90F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005AF", + direction="l", + linebreak="id", + specials={ "char", 0x6F6E }, + unicodeslot=0x2F90F, + }, + [0x2F910]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x038E", + direction="l", + linebreak="id", + specials={ "char", 0x23F5E }, + unicodeslot=0x2F910, + }, + [0x2F911]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x038F", + direction="l", + linebreak="id", + specials={ "char", 0x23F8E }, + unicodeslot=0x2F911, + }, + [0x2F912]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0390", + direction="l", + linebreak="id", + specials={ "char", 0x6FC6 }, + unicodeslot=0x2F912, + }, + [0x2F913]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0391", + direction="l", + linebreak="id", + specials={ "char", 0x7039 }, + unicodeslot=0x2F913, + }, + [0x2F914]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0392", + direction="l", + linebreak="id", + specials={ "char", 0x701E }, + unicodeslot=0x2F914, + }, + [0x2F915]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0393", + direction="l", + linebreak="id", + specials={ "char", 0x701B }, + unicodeslot=0x2F915, + }, + [0x2F916]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0394", + direction="l", + linebreak="id", + specials={ "char", 0x3D96 }, + unicodeslot=0x2F916, + }, + [0x2F917]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0395", + direction="l", + linebreak="id", + specials={ "char", 0x704A }, + unicodeslot=0x2F917, + }, + [0x2F918]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0396", + direction="l", + linebreak="id", + specials={ "char", 0x707D }, + unicodeslot=0x2F918, + }, + [0x2F919]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0397", + direction="l", + linebreak="id", + specials={ "char", 0x7077 }, + unicodeslot=0x2F919, + }, + [0x2F91A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005BA", + direction="l", + linebreak="id", + specials={ "char", 0x70AD }, + unicodeslot=0x2F91A, + }, + [0x2F91B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005BB", + direction="l", + linebreak="id", + specials={ "char", 0x20525 }, + unicodeslot=0x2F91B, + }, + [0x2F91C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005BC", + direction="l", + linebreak="id", + specials={ "char", 0x7145 }, + unicodeslot=0x2F91C, + }, + [0x2F91D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005BD", + direction="l", + linebreak="id", + specials={ "char", 0x24263 }, + unicodeslot=0x2F91D, + }, + [0x2F91E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005BE", + direction="l", + linebreak="id", + specials={ "char", 0x719C }, + unicodeslot=0x2F91E, + }, + [0x2F91F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005BF", + direction="l", + linebreak="id", + specials={ "char", 0x243AB }, + unicodeslot=0x2F91F, + }, + [0x2F920]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0398", + direction="l", + linebreak="id", + specials={ "char", 0x7228 }, + unicodeslot=0x2F920, + }, + [0x2F921]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0399", + direction="l", + linebreak="id", + specials={ "char", 0x7235 }, + unicodeslot=0x2F921, + }, + [0x2F922]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x039A", + direction="l", + linebreak="id", + specials={ "char", 0x7250 }, + unicodeslot=0x2F922, + }, + [0x2F923]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x039B", + direction="l", + linebreak="id", + specials={ "char", 0x24608 }, + unicodeslot=0x2F923, + }, + [0x2F924]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x039C", + direction="l", + linebreak="id", + specials={ "char", 0x7280 }, + unicodeslot=0x2F924, + }, + [0x2F925]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x039D", + direction="l", + linebreak="id", + specials={ "char", 0x7295 }, + unicodeslot=0x2F925, + }, + [0x2F926]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x039E", + direction="l", + linebreak="id", + specials={ "char", 0x24735 }, + unicodeslot=0x2F926, + }, + [0x2F927]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x039F", + direction="l", + linebreak="id", + specials={ "char", 0x24814 }, + unicodeslot=0x2F927, + }, + [0x2F928]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03A0", + direction="l", + linebreak="id", + specials={ "char", 0x737A }, + unicodeslot=0x2F928, + }, + [0x2F929]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03A1", + direction="l", + linebreak="id", + specials={ "char", 0x738B }, + unicodeslot=0x2F929, + }, + [0x2F92A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005CA", + direction="l", + linebreak="id", + specials={ "char", 0x3EAC }, + unicodeslot=0x2F92A, + }, + [0x2F92B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005CB", + direction="l", + linebreak="id", + specials={ "char", 0x73A5 }, + unicodeslot=0x2F92B, + }, + [0x2F92C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005CC", + direction="l", + linebreak="id", + specials={ "char", 0x3EB8 }, + unicodeslot=0x2F92C, + }, + [0x2F92D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005CD", + direction="l", + linebreak="id", + specials={ "char", 0x3EB8 }, + unicodeslot=0x2F92D, + }, + [0x2F92E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005CE", + direction="l", + linebreak="id", + specials={ "char", 0x7447 }, + unicodeslot=0x2F92E, + }, + [0x2F92F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005CF", + direction="l", + linebreak="id", + specials={ "char", 0x745C }, + unicodeslot=0x2F92F, + }, + [0x2F930]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03A2", + direction="l", + linebreak="id", + specials={ "char", 0x7471 }, + unicodeslot=0x2F930, + }, + [0x2F931]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03A3", + direction="l", + linebreak="id", + specials={ "char", 0x7485 }, + unicodeslot=0x2F931, + }, + [0x2F932]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03A4", + direction="l", + linebreak="id", + specials={ "char", 0x74CA }, + unicodeslot=0x2F932, + }, + [0x2F933]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03A5", + direction="l", + linebreak="id", + specials={ "char", 0x3F1B }, + unicodeslot=0x2F933, + }, + [0x2F934]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03A6", + direction="l", + linebreak="id", + specials={ "char", 0x7524 }, + unicodeslot=0x2F934, + }, + [0x2F935]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03A7", + direction="l", + linebreak="id", + specials={ "char", 0x24C36 }, + unicodeslot=0x2F935, + }, + [0x2F936]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03A8", + direction="l", + linebreak="id", + specials={ "char", 0x753E }, + unicodeslot=0x2F936, + }, + [0x2F937]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03A9", + direction="l", + linebreak="id", + specials={ "char", 0x24C92 }, + unicodeslot=0x2F937, + }, + [0x2F938]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03AA", + direction="l", + linebreak="id", + specials={ "char", 0x7570 }, + unicodeslot=0x2F938, + }, + [0x2F939]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03AB", + direction="l", + linebreak="id", + specials={ "char", 0x2219F }, + unicodeslot=0x2F939, + }, + [0x2F93A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005DA", + direction="l", + linebreak="id", + specials={ "char", 0x7610 }, + unicodeslot=0x2F93A, + }, + [0x2F93B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005DB", + direction="l", + linebreak="id", + specials={ "char", 0x24FA1 }, + unicodeslot=0x2F93B, + }, + [0x2F93C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005DC", + direction="l", + linebreak="id", + specials={ "char", 0x24FB8 }, + unicodeslot=0x2F93C, + }, + [0x2F93D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005DD", + direction="l", + linebreak="id", + specials={ "char", 0x25044 }, + unicodeslot=0x2F93D, + }, + [0x2F93E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005DE", + direction="l", + linebreak="id", + specials={ "char", 0x3FFC }, + unicodeslot=0x2F93E, + }, + [0x2F93F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005DF", + direction="l", + linebreak="id", + specials={ "char", 0x4008 }, + unicodeslot=0x2F93F, + }, + [0x2F940]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03AC", + direction="l", + linebreak="id", + specials={ "char", 0x76F4 }, + unicodeslot=0x2F940, + }, + [0x2F941]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03AD", + direction="l", + linebreak="id", + specials={ "char", 0x250F3 }, + unicodeslot=0x2F941, + }, + [0x2F942]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03AE", + direction="l", + linebreak="id", + specials={ "char", 0x250F2 }, + unicodeslot=0x2F942, + }, + [0x2F943]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03AF", + direction="l", + linebreak="id", + specials={ "char", 0x25119 }, + unicodeslot=0x2F943, + }, + [0x2F944]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03B0", + direction="l", + linebreak="id", + specials={ "char", 0x25133 }, + unicodeslot=0x2F944, + }, + [0x2F945]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03B1", + direction="l", + linebreak="id", + specials={ "char", 0x771E }, + unicodeslot=0x2F945, + }, + [0x2F946]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03B2", + direction="l", + linebreak="id", + specials={ "char", 0x771F }, + unicodeslot=0x2F946, + }, + [0x2F947]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03B3", + direction="l", + linebreak="id", + specials={ "char", 0x771F }, + unicodeslot=0x2F947, + }, + [0x2F948]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03B4", + direction="l", + linebreak="id", + specials={ "char", 0x774A }, + unicodeslot=0x2F948, + }, + [0x2F949]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03B5", + direction="l", + linebreak="id", + specials={ "char", 0x4039 }, + unicodeslot=0x2F949, + }, + [0x2F94A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005EA", + direction="l", + linebreak="id", + specials={ "char", 0x778B }, + unicodeslot=0x2F94A, + }, + [0x2F94B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005EB", + direction="l", + linebreak="id", + specials={ "char", 0x4046 }, + unicodeslot=0x2F94B, + }, + [0x2F94C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005EC", + direction="l", + linebreak="id", + specials={ "char", 0x4096 }, + unicodeslot=0x2F94C, + }, + [0x2F94D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005ED", + direction="l", + linebreak="id", + specials={ "char", 0x2541D }, + unicodeslot=0x2F94D, + }, + [0x2F94E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005EE", + direction="l", + linebreak="id", + specials={ "char", 0x784E }, + unicodeslot=0x2F94E, + }, + [0x2F94F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005EF", + direction="l", + linebreak="id", + specials={ "char", 0x788C }, + unicodeslot=0x2F94F, + }, + [0x2F950]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03B6", + direction="l", + linebreak="id", + specials={ "char", 0x78CC }, + unicodeslot=0x2F950, + }, + [0x2F951]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03B7", + direction="l", + linebreak="id", + specials={ "char", 0x40E3 }, + unicodeslot=0x2F951, + }, + [0x2F952]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03B8", + direction="l", + linebreak="id", + specials={ "char", 0x25626 }, + unicodeslot=0x2F952, + }, + [0x2F953]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03B9", + direction="l", + linebreak="id", + specials={ "char", 0x7956 }, + unicodeslot=0x2F953, + }, + [0x2F954]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03BA", + direction="l", + linebreak="id", + specials={ "char", 0x2569A }, + unicodeslot=0x2F954, + }, + [0x2F955]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03BB", + direction="l", + linebreak="id", + specials={ "char", 0x256C5 }, + unicodeslot=0x2F955, + }, + [0x2F956]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03BC", + direction="l", + linebreak="id", + specials={ "char", 0x798F }, + unicodeslot=0x2F956, + }, + [0x2F957]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03BD", + direction="l", + linebreak="id", + specials={ "char", 0x79EB }, + unicodeslot=0x2F957, + }, + [0x2F958]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03BE", + direction="l", + linebreak="id", + specials={ "char", 0x412F }, + unicodeslot=0x2F958, + }, + [0x2F959]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03BF", + direction="l", + linebreak="id", + specials={ "char", 0x7A40 }, + unicodeslot=0x2F959, + }, + [0x2F95A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005FA", + direction="l", + linebreak="id", + specials={ "char", 0x7A4A }, + unicodeslot=0x2F95A, + }, + [0x2F95B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005FB", + direction="l", + linebreak="id", + specials={ "char", 0x7A4F }, + unicodeslot=0x2F95B, + }, + [0x2F95C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005FC", + direction="l", + linebreak="id", + specials={ "char", 0x2597C }, + unicodeslot=0x2F95C, + }, + [0x2F95D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005FD", + direction="l", + linebreak="id", + specials={ "char", 0x25AA7 }, + unicodeslot=0x2F95D, + }, + [0x2F95E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005FE", + direction="l", + linebreak="id", + specials={ "char", 0x25AA7 }, + unicodeslot=0x2F95E, + }, + [0x2F95F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005FF", + direction="l", + linebreak="id", + specials={ "char", 0x7AEE }, + unicodeslot=0x2F95F, + }, + [0x2F960]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03C0", + direction="l", + linebreak="id", + specials={ "char", 0x4202 }, + unicodeslot=0x2F960, + }, + [0x2F961]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03C1", + direction="l", + linebreak="id", + specials={ "char", 0x25BAB }, + unicodeslot=0x2F961, + }, + [0x2F962]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03C2", + direction="l", + linebreak="id", + specials={ "char", 0x7BC6 }, + unicodeslot=0x2F962, + }, + [0x2F963]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03C3", + direction="l", + linebreak="id", + specials={ "char", 0x7BC9 }, + unicodeslot=0x2F963, + }, + [0x2F964]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03C4", + direction="l", + linebreak="id", + specials={ "char", 0x4227 }, + unicodeslot=0x2F964, + }, + [0x2F965]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03C5", + direction="l", + linebreak="id", + specials={ "char", 0x25C80 }, + unicodeslot=0x2F965, + }, + [0x2F966]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03C6", + direction="l", + linebreak="id", + specials={ "char", 0x7CD2 }, + unicodeslot=0x2F966, + }, + [0x2F967]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03C7", + direction="l", + linebreak="id", + specials={ "char", 0x42A0 }, + unicodeslot=0x2F967, + }, + [0x2F968]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03C8", + direction="l", + linebreak="id", + specials={ "char", 0x7CE8 }, + unicodeslot=0x2F968, + }, + [0x2F969]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03C9", + direction="l", + linebreak="id", + specials={ "char", 0x7CE3 }, + unicodeslot=0x2F969, + }, + [0x2F96A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0060A", + direction="l", + linebreak="id", + specials={ "char", 0x7D00 }, + unicodeslot=0x2F96A, + }, + [0x2F96B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0060B", + direction="l", + linebreak="id", + specials={ "char", 0x25F86 }, + unicodeslot=0x2F96B, + }, + [0x2F96C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0060C", + direction="l", + linebreak="id", + specials={ "char", 0x7D63 }, + unicodeslot=0x2F96C, + }, + [0x2F96D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0060D", + direction="l", + linebreak="id", + specials={ "char", 0x4301 }, + unicodeslot=0x2F96D, + }, + [0x2F96E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0060E", + direction="l", + linebreak="id", + specials={ "char", 0x7DC7 }, + unicodeslot=0x2F96E, + }, + [0x2F96F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0060F", + direction="l", + linebreak="id", + specials={ "char", 0x7E02 }, + unicodeslot=0x2F96F, + }, + [0x2F970]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03CA", + direction="l", + linebreak="id", + specials={ "char", 0x7E45 }, + unicodeslot=0x2F970, + }, + [0x2F971]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03CB", + direction="l", + linebreak="id", + specials={ "char", 0x4334 }, + unicodeslot=0x2F971, + }, + [0x2F972]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03CC", + direction="l", + linebreak="id", + specials={ "char", 0x26228 }, + unicodeslot=0x2F972, + }, + [0x2F973]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03CD", + direction="l", + linebreak="id", + specials={ "char", 0x26247 }, + unicodeslot=0x2F973, + }, + [0x2F974]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03CE", + direction="l", + linebreak="id", + specials={ "char", 0x4359 }, + unicodeslot=0x2F974, + }, + [0x2F975]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03CF", + direction="l", + linebreak="id", + specials={ "char", 0x262D9 }, + unicodeslot=0x2F975, + }, + [0x2F976]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03D0", + direction="l", + linebreak="id", + specials={ "char", 0x7F7A }, + unicodeslot=0x2F976, + }, + [0x2F977]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03D1", + direction="l", + linebreak="id", + specials={ "char", 0x2633E }, + unicodeslot=0x2F977, + }, + [0x2F978]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03D2", + direction="l", + linebreak="id", + specials={ "char", 0x7F95 }, + unicodeslot=0x2F978, + }, + [0x2F979]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03D3", + direction="l", + linebreak="id", + specials={ "char", 0x7FFA }, + unicodeslot=0x2F979, + }, + [0x2F97A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0061A", + direction="l", + linebreak="id", + specials={ "char", 0x8005 }, + unicodeslot=0x2F97A, + }, + [0x2F97B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0061B", + direction="l", + linebreak="id", + specials={ "char", 0x264DA }, + unicodeslot=0x2F97B, + }, + [0x2F97C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0061C", + direction="l", + linebreak="id", + specials={ "char", 0x26523 }, + unicodeslot=0x2F97C, + }, + [0x2F97D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0061D", + direction="l", + linebreak="id", + specials={ "char", 0x8060 }, + unicodeslot=0x2F97D, + }, + [0x2F97E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0061E", + direction="l", + linebreak="id", + specials={ "char", 0x265A8 }, + unicodeslot=0x2F97E, + }, + [0x2F97F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0061F", + direction="l", + linebreak="id", + specials={ "char", 0x8070 }, + unicodeslot=0x2F97F, + }, + [0x2F980]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03D4", + direction="l", + linebreak="id", + specials={ "char", 0x2335F }, + unicodeslot=0x2F980, + }, + [0x2F981]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03D5", + direction="l", + linebreak="id", + specials={ "char", 0x43D5 }, + unicodeslot=0x2F981, + }, + [0x2F982]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03D6", + direction="l", + linebreak="id", + specials={ "char", 0x80B2 }, + unicodeslot=0x2F982, + }, + [0x2F983]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03D7", + direction="l", + linebreak="id", + specials={ "char", 0x8103 }, + unicodeslot=0x2F983, + }, + [0x2F984]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03D8", + direction="l", + linebreak="id", + specials={ "char", 0x440B }, + unicodeslot=0x2F984, + }, + [0x2F985]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03D9", + direction="l", + linebreak="id", + specials={ "char", 0x813E }, + unicodeslot=0x2F985, + }, + [0x2F986]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03DA", + direction="l", + linebreak="id", + specials={ "char", 0x5AB5 }, + unicodeslot=0x2F986, + }, + [0x2F987]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03DB", + direction="l", + linebreak="id", + specials={ "char", 0x267A7 }, + unicodeslot=0x2F987, + }, + [0x2F988]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03DC", + direction="l", + linebreak="id", + specials={ "char", 0x267B5 }, + unicodeslot=0x2F988, + }, + [0x2F989]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03DD", + direction="l", + linebreak="id", + specials={ "char", 0x23393 }, + unicodeslot=0x2F989, + }, + [0x2F98A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0062A", + direction="l", + linebreak="id", + specials={ "char", 0x2339C }, + unicodeslot=0x2F98A, + }, + [0x2F98B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0062B", + direction="l", + linebreak="id", + specials={ "char", 0x8201 }, + unicodeslot=0x2F98B, + }, + [0x2F98C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0062C", + direction="l", + linebreak="id", + specials={ "char", 0x8204 }, + unicodeslot=0x2F98C, + }, + [0x2F98D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0062D", + direction="l", + linebreak="id", + specials={ "char", 0x8F9E }, + unicodeslot=0x2F98D, + }, + [0x2F98E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0062E", + direction="l", + linebreak="id", + specials={ "char", 0x446B }, + unicodeslot=0x2F98E, + }, + [0x2F98F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0062F", + direction="l", + linebreak="id", + specials={ "char", 0x8291 }, + unicodeslot=0x2F98F, + }, + [0x2F990]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03DE", + direction="l", + linebreak="id", + specials={ "char", 0x828B }, + unicodeslot=0x2F990, + }, + [0x2F991]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03DF", + direction="l", + linebreak="id", + specials={ "char", 0x829D }, + unicodeslot=0x2F991, + }, + [0x2F992]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03E0", + direction="l", + linebreak="id", + specials={ "char", 0x52B3 }, + unicodeslot=0x2F992, + }, + [0x2F993]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03E1", + direction="l", + linebreak="id", + specials={ "char", 0x82B1 }, + unicodeslot=0x2F993, + }, + [0x2F994]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03E2", + direction="l", + linebreak="id", + specials={ "char", 0x82B3 }, + unicodeslot=0x2F994, + }, + [0x2F995]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03E3", + direction="l", + linebreak="id", + specials={ "char", 0x82BD }, + unicodeslot=0x2F995, + }, + [0x2F996]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03E4", + direction="l", + linebreak="id", + specials={ "char", 0x82E6 }, + unicodeslot=0x2F996, + }, + [0x2F997]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03E5", + direction="l", + linebreak="id", + specials={ "char", 0x26B3C }, + unicodeslot=0x2F997, + }, + [0x2F998]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03E6", + direction="l", + linebreak="id", + specials={ "char", 0x82E5 }, + unicodeslot=0x2F998, + }, + [0x2F999]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03E7", + direction="l", + linebreak="id", + specials={ "char", 0x831D }, + unicodeslot=0x2F999, + }, + [0x2F99A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0063A", + direction="l", + linebreak="id", + specials={ "char", 0x8363 }, + unicodeslot=0x2F99A, + }, + [0x2F99B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0063B", + direction="l", + linebreak="id", + specials={ "char", 0x83AD }, + unicodeslot=0x2F99B, + }, + [0x2F99C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0063C", + direction="l", + linebreak="id", + specials={ "char", 0x8323 }, + unicodeslot=0x2F99C, + }, + [0x2F99D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0063D", + direction="l", + linebreak="id", + specials={ "char", 0x83BD }, + unicodeslot=0x2F99D, + }, + [0x2F99E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0063E", + direction="l", + linebreak="id", + specials={ "char", 0x83E7 }, + unicodeslot=0x2F99E, + }, + [0x2F99F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0063F", + direction="l", + linebreak="id", + specials={ "char", 0x8457 }, + unicodeslot=0x2F99F, + }, + [0x2F9A0]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009A0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x8353 }, + unicodeslot=0x2F9A0, + }, + [0x2F9A1]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009A0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x83CA }, + unicodeslot=0x2F9A1, + }, + [0x2F9A2]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009A0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x83CC }, + unicodeslot=0x2F9A2, + }, + [0x2F9A3]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009A0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x83DC }, + unicodeslot=0x2F9A3, + }, + [0x2F9A4]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009A0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x26C36 }, + unicodeslot=0x2F9A4, + }, + [0x2F9A5]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009A0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x26D6B }, + unicodeslot=0x2F9A5, + }, + [0x2F9A6]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009A0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x26CD5 }, + unicodeslot=0x2F9A6, + }, + [0x2F9A7]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009A0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x452B }, + unicodeslot=0x2F9A7, + }, + [0x2F9A8]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009A0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x84F1 }, + unicodeslot=0x2F9A8, + }, + [0x2F9A9]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009A0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x84F3 }, + unicodeslot=0x2F9A9, + }, + [0x2F9AA]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009AA", + direction="l", + linebreak="id", + specials={ "char", 0x8516 }, + unicodeslot=0x2F9AA, + }, + [0x2F9AB]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009AB", + direction="l", + linebreak="id", + specials={ "char", 0x273CA }, + unicodeslot=0x2F9AB, + }, + [0x2F9AC]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009AC", + direction="l", + linebreak="id", + specials={ "char", 0x8564 }, + unicodeslot=0x2F9AC, + }, + [0x2F9AD]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009AD", + direction="l", + linebreak="id", + specials={ "char", 0x26F2C }, + unicodeslot=0x2F9AD, + }, + [0x2F9AE]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009AE", + direction="l", + linebreak="id", + specials={ "char", 0x455D }, + unicodeslot=0x2F9AE, + }, + [0x2F9AF]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009AF", + direction="l", + linebreak="id", + specials={ "char", 0x4561 }, + unicodeslot=0x2F9AF, + }, + [0x2F9B0]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009B0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x26FB1 }, + unicodeslot=0x2F9B0, + }, + [0x2F9B1]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009B0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x270D2 }, + unicodeslot=0x2F9B1, + }, + [0x2F9B2]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009B0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x456B }, + unicodeslot=0x2F9B2, + }, + [0x2F9B3]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009B0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x8650 }, + unicodeslot=0x2F9B3, + }, + [0x2F9B4]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009B0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x865C }, + unicodeslot=0x2F9B4, + }, + [0x2F9B5]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009B0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x8667 }, + unicodeslot=0x2F9B5, + }, + [0x2F9B6]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009B0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x8669 }, + unicodeslot=0x2F9B6, + }, + [0x2F9B7]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009B0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x86A9 }, + unicodeslot=0x2F9B7, + }, + [0x2F9B8]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009B0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x8688 }, + unicodeslot=0x2F9B8, + }, + [0x2F9B9]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009B0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x870E }, + unicodeslot=0x2F9B9, + }, + [0x2F9BA]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009BA", + direction="l", + linebreak="id", + specials={ "char", 0x86E2 }, + unicodeslot=0x2F9BA, + }, + [0x2F9BB]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009BB", + direction="l", + linebreak="id", + specials={ "char", 0x8779 }, + unicodeslot=0x2F9BB, + }, + [0x2F9BC]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009BC", + direction="l", + linebreak="id", + specials={ "char", 0x8728 }, + unicodeslot=0x2F9BC, + }, + [0x2F9BD]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009BD", + direction="l", + linebreak="id", + specials={ "char", 0x876B }, + unicodeslot=0x2F9BD, + }, + [0x2F9BE]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009BE", + direction="l", + linebreak="id", + specials={ "char", 0x8786 }, + unicodeslot=0x2F9BE, + }, + [0x2F9BF]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009BF", + direction="l", + linebreak="id", + specials={ "char", 0x45D7 }, + unicodeslot=0x2F9BF, + }, + [0x2F9C0]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009C0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x87E1 }, + unicodeslot=0x2F9C0, + }, + [0x2F9C1]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009C0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x8801 }, + unicodeslot=0x2F9C1, + }, + [0x2F9C2]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009C0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x45F9 }, + unicodeslot=0x2F9C2, + }, + [0x2F9C3]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009C0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x8860 }, + unicodeslot=0x2F9C3, + }, + [0x2F9C4]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009C0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x8863 }, + unicodeslot=0x2F9C4, + }, + [0x2F9C5]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009C0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x27667 }, + unicodeslot=0x2F9C5, + }, + [0x2F9C6]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009C0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x88D7 }, + unicodeslot=0x2F9C6, + }, + [0x2F9C7]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009C0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x88DE }, + unicodeslot=0x2F9C7, + }, + [0x2F9C8]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009C0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x4635 }, + unicodeslot=0x2F9C8, + }, + [0x2F9C9]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009C0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x88FA }, + unicodeslot=0x2F9C9, + }, + [0x2F9CA]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009CA", + direction="l", + linebreak="id", + specials={ "char", 0x34BB }, + unicodeslot=0x2F9CA, + }, + [0x2F9CB]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009CB", + direction="l", + linebreak="id", + specials={ "char", 0x278AE }, + unicodeslot=0x2F9CB, + }, + [0x2F9CC]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009CC", + direction="l", + linebreak="id", + specials={ "char", 0x27966 }, + unicodeslot=0x2F9CC, + }, + [0x2F9CD]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009CD", + direction="l", + linebreak="id", + specials={ "char", 0x46BE }, + unicodeslot=0x2F9CD, + }, + [0x2F9CE]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009CE", + direction="l", + linebreak="id", + specials={ "char", 0x46C7 }, + unicodeslot=0x2F9CE, + }, + [0x2F9CF]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009CF", + direction="l", + linebreak="id", + specials={ "char", 0x8AA0 }, + unicodeslot=0x2F9CF, + }, + [0x2F9D0]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009D0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x8AED }, + unicodeslot=0x2F9D0, + }, + [0x2F9D1]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009D0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x8B8A }, + unicodeslot=0x2F9D1, + }, + [0x2F9D2]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009D0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x8C55 }, + unicodeslot=0x2F9D2, + }, + [0x2F9D3]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009D0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x27CA8 }, + unicodeslot=0x2F9D3, + }, + [0x2F9D4]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009D0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x8CAB }, + unicodeslot=0x2F9D4, + }, + [0x2F9D5]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009D0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x8CC1 }, + unicodeslot=0x2F9D5, + }, + [0x2F9D6]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009D0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x8D1B }, + unicodeslot=0x2F9D6, + }, + [0x2F9D7]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009D0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x8D77 }, + unicodeslot=0x2F9D7, + }, + [0x2F9D8]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009D0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x27F2F }, + unicodeslot=0x2F9D8, + }, + [0x2F9D9]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009D0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x20804 }, + unicodeslot=0x2F9D9, + }, + [0x2F9DA]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009DA", + direction="l", + linebreak="id", + specials={ "char", 0x8DCB }, + unicodeslot=0x2F9DA, + }, + [0x2F9DB]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009DB", + direction="l", + linebreak="id", + specials={ "char", 0x8DBC }, + unicodeslot=0x2F9DB, + }, + [0x2F9DC]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009DC", + direction="l", + linebreak="id", + specials={ "char", 0x8DF0 }, + unicodeslot=0x2F9DC, + }, + [0x2F9DD]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009DD", + direction="l", + linebreak="id", + specials={ "char", 0x208DE }, + unicodeslot=0x2F9DD, + }, + [0x2F9DE]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009DE", + direction="l", + linebreak="id", + specials={ "char", 0x8ED4 }, + unicodeslot=0x2F9DE, + }, + [0x2F9DF]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009DF", + direction="l", + linebreak="id", + specials={ "char", 0x8F38 }, + unicodeslot=0x2F9DF, + }, + [0x2F9E0]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009E0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x285D2 }, + unicodeslot=0x2F9E0, + }, + [0x2F9E1]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009E0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x285ED }, + unicodeslot=0x2F9E1, + }, + [0x2F9E2]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009E0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x9094 }, + unicodeslot=0x2F9E2, + }, + [0x2F9E3]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009E0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x90F1 }, + unicodeslot=0x2F9E3, + }, + [0x2F9E4]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009E0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x9111 }, + unicodeslot=0x2F9E4, + }, + [0x2F9E5]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009E0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x2872E }, + unicodeslot=0x2F9E5, + }, + [0x2F9E6]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009E0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x911B }, + unicodeslot=0x2F9E6, + }, + [0x2F9E7]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009E0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x9238 }, + unicodeslot=0x2F9E7, + }, + [0x2F9E8]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009E0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x92D7 }, + unicodeslot=0x2F9E8, + }, + [0x2F9E9]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009E0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x92D8 }, + unicodeslot=0x2F9E9, + }, + [0x2F9EA]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009EA", + direction="l", + linebreak="id", + specials={ "char", 0x927C }, + unicodeslot=0x2F9EA, + }, + [0x2F9EB]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009EB", + direction="l", + linebreak="id", + specials={ "char", 0x93F9 }, + unicodeslot=0x2F9EB, + }, + [0x2F9EC]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009EC", + direction="l", + linebreak="id", + specials={ "char", 0x9415 }, + unicodeslot=0x2F9EC, + }, + [0x2F9ED]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009ED", + direction="l", + linebreak="id", + specials={ "char", 0x28BFA }, + unicodeslot=0x2F9ED, + }, + [0x2F9EE]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009EE", + direction="l", + linebreak="id", + specials={ "char", 0x958B }, + unicodeslot=0x2F9EE, + }, + [0x2F9EF]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009EF", + direction="l", + linebreak="id", + specials={ "char", 0x4995 }, + unicodeslot=0x2F9EF, + }, + [0x2F9F0]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009F0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x95B7 }, + unicodeslot=0x2F9F0, + }, + [0x2F9F1]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009F0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x28D77 }, + unicodeslot=0x2F9F1, + }, + [0x2F9F2]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009F0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x49E6 }, + unicodeslot=0x2F9F2, + }, + [0x2F9F3]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009F0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x96C3 }, + unicodeslot=0x2F9F3, + }, + [0x2F9F4]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009F0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x5DB2 }, + unicodeslot=0x2F9F4, + }, + [0x2F9F5]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009F0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x9723 }, + unicodeslot=0x2F9F5, + }, + [0x2F9F6]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009F0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x29145 }, + unicodeslot=0x2F9F6, + }, + [0x2F9F7]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009F0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x2921A }, + unicodeslot=0x2F9F7, + }, + [0x2F9F8]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009F0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x4A6E }, + unicodeslot=0x2F9F8, + }, + [0x2F9F9]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009F0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x4A76 }, + unicodeslot=0x2F9F9, + }, + [0x2F9FA]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009FA", + direction="l", + linebreak="id", + specials={ "char", 0x97E0 }, + unicodeslot=0x2F9FA, + }, + [0x2F9FB]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009FB", + direction="l", + linebreak="id", + specials={ "char", 0x2940A }, + unicodeslot=0x2F9FB, + }, + [0x2F9FC]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009FC", + direction="l", + linebreak="id", + specials={ "char", 0x4AB2 }, + unicodeslot=0x2F9FC, + }, + [0x2F9FD]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009FD", + direction="l", + linebreak="id", + specials={ "char", 0x29496 }, + unicodeslot=0x2F9FD, + }, + [0x2F9FE]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009FE", + direction="l", + linebreak="id", + specials={ "char", 0x980B }, + unicodeslot=0x2F9FE, + }, + [0x2F9FF]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009FF", + direction="l", + linebreak="id", + specials={ "char", 0x980B }, + unicodeslot=0x2F9FF, + }, + [0x2FA00]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0000", + direction="l", + linebreak="id", + specials={ "char", 0x9829 }, + unicodeslot=0x2FA00, + }, + [0x2FA01]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0001", + direction="l", + linebreak="id", + specials={ "char", 0x295B6 }, + unicodeslot=0x2FA01, + }, + [0x2FA02]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0002", + direction="l", + linebreak="id", + specials={ "char", 0x98E2 }, + unicodeslot=0x2FA02, + }, + [0x2FA03]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0003", + direction="l", + linebreak="id", + specials={ "char", 0x4B33 }, + unicodeslot=0x2FA03, + }, + [0x2FA04]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0004", + direction="l", + linebreak="id", + specials={ "char", 0x9929 }, + unicodeslot=0x2FA04, + }, + [0x2FA05]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0005", + direction="l", + linebreak="id", + specials={ "char", 0x99A7 }, + unicodeslot=0x2FA05, + }, + [0x2FA06]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0006", + direction="l", + linebreak="id", + specials={ "char", 0x99C2 }, + unicodeslot=0x2FA06, + }, + [0x2FA07]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0007", + direction="l", + linebreak="id", + specials={ "char", 0x99FE }, + unicodeslot=0x2FA07, + }, + [0x2FA08]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0008", + direction="l", + linebreak="id", + specials={ "char", 0x4BCE }, + unicodeslot=0x2FA08, + }, + [0x2FA09]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0009", + direction="l", + linebreak="id", + specials={ "char", 0x29B30 }, + unicodeslot=0x2FA09, + }, + [0x2FA0A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0000A", + direction="l", + linebreak="id", + specials={ "char", 0x9B12 }, + unicodeslot=0x2FA0A, + }, + [0x2FA0B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0000B", + direction="l", + linebreak="id", + specials={ "char", 0x9C40 }, + unicodeslot=0x2FA0B, + }, + [0x2FA0C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0000C", + direction="l", + linebreak="id", + specials={ "char", 0x9CFD }, + unicodeslot=0x2FA0C, + }, + [0x2FA0D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0000D", + direction="l", + linebreak="id", + specials={ "char", 0x4CCE }, + unicodeslot=0x2FA0D, + }, + [0x2FA0E]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0000E", + direction="l", + linebreak="id", + specials={ "char", 0x4CED }, + unicodeslot=0x2FA0E, + }, + [0x2FA0F]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0000F", + direction="l", + linebreak="id", + specials={ "char", 0x9D67 }, + unicodeslot=0x2FA0F, + }, + [0x2FA10]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x000A", + direction="l", + linebreak="id", + specials={ "char", 0x2A0CE }, + unicodeslot=0x2FA10, + }, + [0x2FA11]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x000B", + direction="l", + linebreak="id", + specials={ "char", 0x4CF8 }, + unicodeslot=0x2FA11, + }, + [0x2FA12]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x000C", + direction="l", + linebreak="id", + specials={ "char", 0x2A105 }, + unicodeslot=0x2FA12, + }, + [0x2FA13]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x000D", + direction="l", + linebreak="id", + specials={ "char", 0x2A20E }, + unicodeslot=0x2FA13, + }, + [0x2FA14]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x000E", + direction="l", + linebreak="id", + specials={ "char", 0x2A291 }, + unicodeslot=0x2FA14, + }, + [0x2FA15]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x000F", + direction="l", + linebreak="id", + specials={ "char", 0x9EBB }, + unicodeslot=0x2FA15, + }, + [0x2FA16]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0010", + direction="l", + linebreak="id", + specials={ "char", 0x4D56 }, + unicodeslot=0x2FA16, + }, + [0x2FA17]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0011", + direction="l", + linebreak="id", + specials={ "char", 0x9EF9 }, + unicodeslot=0x2FA17, + }, + [0x2FA18]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0012", + direction="l", + linebreak="id", + specials={ "char", 0x9EFE }, + unicodeslot=0x2FA18, + }, + [0x2FA19]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0013", + direction="l", + linebreak="id", + specials={ "char", 0x9F05 }, + unicodeslot=0x2FA19, + }, + [0x2FA1A]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0001A", + direction="l", + linebreak="id", + specials={ "char", 0x9F0F }, + unicodeslot=0x2FA1A, + }, + [0x2FA1B]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0001B", + direction="l", + linebreak="id", + specials={ "char", 0x9F16 }, + unicodeslot=0x2FA1B, + }, + [0x2FA1C]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0001C", + direction="l", + linebreak="id", + specials={ "char", 0x9F3B }, + unicodeslot=0x2FA1C, + }, + [0x2FA1D]={ + category="lo", + cjkwd="w", + description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0001D", + direction="l", + linebreak="id", + specials={ "char", 0x2A600 }, + unicodeslot=0x2FA1D, + }, + [0xE0001]={ + category="cf", + description="LANGUAGE TAG", + direction="bn", + linebreak="cm", + unicodeslot=0xE0001, + }, + [0xE0020]={ + category="cf", + description="TAG SPACE", + direction="bn", + linebreak="cm", + unicodeslot=0xE0020, + }, + [0xE0021]={ + category="cf", + description="TAG EXCLAMATION MARK", + direction="bn", + linebreak="cm", + unicodeslot=0xE0021, + }, + [0xE0022]={ + category="cf", + description="TAG QUOTATION MARK", + direction="bn", + linebreak="cm", + unicodeslot=0xE0022, + }, + [0xE0023]={ + category="cf", + description="TAG NUMBER SIGN", + direction="bn", + linebreak="cm", + unicodeslot=0xE0023, + }, + [0xE0024]={ + category="cf", + description="TAG DOLLAR SIGN", + direction="bn", + linebreak="cm", + unicodeslot=0xE0024, + }, + [0xE0025]={ + category="cf", + description="TAG PERCENT SIGN", + direction="bn", + linebreak="cm", + unicodeslot=0xE0025, + }, + [0xE0026]={ + category="cf", + description="TAG AMPERSAND", + direction="bn", + linebreak="cm", + unicodeslot=0xE0026, + }, + [0xE0027]={ + category="cf", + description="TAG APOSTROPHE", + direction="bn", + linebreak="cm", + unicodeslot=0xE0027, + }, + [0xE0028]={ + category="cf", + description="TAG LEFT PARENTHESIS", + direction="bn", + linebreak="cm", + unicodeslot=0xE0028, + }, + [0xE0029]={ + category="cf", + description="TAG RIGHT PARENTHESIS", + direction="bn", + linebreak="cm", + unicodeslot=0xE0029, + }, + [0xE002A]={ + category="cf", + description="TAG ASTERISK", + direction="bn", + linebreak="cm", + unicodeslot=0xE002A, + }, + [0xE002B]={ + category="cf", + description="TAG PLUS SIGN", + direction="bn", + linebreak="cm", + unicodeslot=0xE002B, + }, + [0xE002C]={ + category="cf", + description="TAG COMMA", + direction="bn", + linebreak="cm", + unicodeslot=0xE002C, + }, + [0xE002D]={ + category="cf", + description="TAG HYPHEN-MINUS", + direction="bn", + linebreak="cm", + unicodeslot=0xE002D, + }, + [0xE002E]={ + category="cf", + description="TAG FULL STOP", + direction="bn", + linebreak="cm", + unicodeslot=0xE002E, + }, + [0xE002F]={ + category="cf", + description="TAG SOLIDUS", + direction="bn", + linebreak="cm", + unicodeslot=0xE002F, + }, + [0xE0030]={ + category="cf", + description="TAG DIGIT ZERO", + direction="bn", + linebreak="cm", + unicodeslot=0xE0030, + }, + [0xE0031]={ + category="cf", + description="TAG DIGIT ONE", + direction="bn", + linebreak="cm", + unicodeslot=0xE0031, + }, + [0xE0032]={ + category="cf", + description="TAG DIGIT TWO", + direction="bn", + linebreak="cm", + unicodeslot=0xE0032, + }, + [0xE0033]={ + category="cf", + description="TAG DIGIT THREE", + direction="bn", + linebreak="cm", + unicodeslot=0xE0033, + }, + [0xE0034]={ + category="cf", + description="TAG DIGIT FOUR", + direction="bn", + linebreak="cm", + unicodeslot=0xE0034, + }, + [0xE0035]={ + category="cf", + description="TAG DIGIT FIVE", + direction="bn", + linebreak="cm", + unicodeslot=0xE0035, + }, + [0xE0036]={ + category="cf", + description="TAG DIGIT SIX", + direction="bn", + linebreak="cm", + unicodeslot=0xE0036, + }, + [0xE0037]={ + category="cf", + description="TAG DIGIT SEVEN", + direction="bn", + linebreak="cm", + unicodeslot=0xE0037, + }, + [0xE0038]={ + category="cf", + description="TAG DIGIT EIGHT", + direction="bn", + linebreak="cm", + unicodeslot=0xE0038, + }, + [0xE0039]={ + category="cf", + description="TAG DIGIT NINE", + direction="bn", + linebreak="cm", + unicodeslot=0xE0039, + }, + [0xE003A]={ + category="cf", + description="TAG COLON", + direction="bn", + linebreak="cm", + unicodeslot=0xE003A, + }, + [0xE003B]={ + category="cf", + description="TAG SEMICOLON", + direction="bn", + linebreak="cm", + unicodeslot=0xE003B, + }, + [0xE003C]={ + category="cf", + description="TAG LESS-THAN SIGN", + direction="bn", + linebreak="cm", + unicodeslot=0xE003C, + }, + [0xE003D]={ + category="cf", + description="TAG EQUALS SIGN", + direction="bn", + linebreak="cm", + unicodeslot=0xE003D, + }, + [0xE003E]={ + category="cf", + description="TAG GREATER-THAN SIGN", + direction="bn", + linebreak="cm", + unicodeslot=0xE003E, + }, + [0xE003F]={ + category="cf", + description="TAG QUESTION MARK", + direction="bn", + linebreak="cm", + unicodeslot=0xE003F, + }, + [0xE0040]={ + category="cf", + description="TAG COMMERCIAL AT", + direction="bn", + linebreak="cm", + unicodeslot=0xE0040, + }, + [0xE0041]={ + category="cf", + description="TAG LATIN CAPITAL LETTER A", + direction="bn", + linebreak="cm", + unicodeslot=0xE0041, + }, + [0xE0042]={ + category="cf", + description="TAG LATIN CAPITAL LETTER B", + direction="bn", + linebreak="cm", + unicodeslot=0xE0042, + }, + [0xE0043]={ + category="cf", + description="TAG LATIN CAPITAL LETTER C", + direction="bn", + linebreak="cm", + unicodeslot=0xE0043, + }, + [0xE0044]={ + category="cf", + description="TAG LATIN CAPITAL LETTER D", + direction="bn", + linebreak="cm", + unicodeslot=0xE0044, + }, + [0xE0045]={ + category="cf", + description="TAG LATIN CAPITAL LETTER E", + direction="bn", + linebreak="cm", + unicodeslot=0xE0045, + }, + [0xE0046]={ + category="cf", + description="TAG LATIN CAPITAL LETTER F", + direction="bn", + linebreak="cm", + unicodeslot=0xE0046, + }, + [0xE0047]={ + category="cf", + description="TAG LATIN CAPITAL LETTER G", + direction="bn", + linebreak="cm", + unicodeslot=0xE0047, + }, + [0xE0048]={ + category="cf", + description="TAG LATIN CAPITAL LETTER H", + direction="bn", + linebreak="cm", + unicodeslot=0xE0048, + }, + [0xE0049]={ + category="cf", + description="TAG LATIN CAPITAL LETTER I", + direction="bn", + linebreak="cm", + unicodeslot=0xE0049, + }, + [0xE004A]={ + category="cf", + description="TAG LATIN CAPITAL LETTER J", + direction="bn", + linebreak="cm", + unicodeslot=0xE004A, + }, + [0xE004B]={ + category="cf", + description="TAG LATIN CAPITAL LETTER K", + direction="bn", + linebreak="cm", + unicodeslot=0xE004B, + }, + [0xE004C]={ + category="cf", + description="TAG LATIN CAPITAL LETTER L", + direction="bn", + linebreak="cm", + unicodeslot=0xE004C, + }, + [0xE004D]={ + category="cf", + description="TAG LATIN CAPITAL LETTER M", + direction="bn", + linebreak="cm", + unicodeslot=0xE004D, + }, + [0xE004E]={ + category="cf", + description="TAG LATIN CAPITAL LETTER N", + direction="bn", + linebreak="cm", + unicodeslot=0xE004E, + }, + [0xE004F]={ + category="cf", + description="TAG LATIN CAPITAL LETTER O", + direction="bn", + linebreak="cm", + unicodeslot=0xE004F, + }, + [0xE0050]={ + category="cf", + description="TAG LATIN CAPITAL LETTER P", + direction="bn", + linebreak="cm", + unicodeslot=0xE0050, + }, + [0xE0051]={ + category="cf", + description="TAG LATIN CAPITAL LETTER Q", + direction="bn", + linebreak="cm", + unicodeslot=0xE0051, + }, + [0xE0052]={ + category="cf", + description="TAG LATIN CAPITAL LETTER R", + direction="bn", + linebreak="cm", + unicodeslot=0xE0052, + }, + [0xE0053]={ + category="cf", + description="TAG LATIN CAPITAL LETTER S", + direction="bn", + linebreak="cm", + unicodeslot=0xE0053, + }, + [0xE0054]={ + category="cf", + description="TAG LATIN CAPITAL LETTER T", + direction="bn", + linebreak="cm", + unicodeslot=0xE0054, + }, + [0xE0055]={ + category="cf", + description="TAG LATIN CAPITAL LETTER U", + direction="bn", + linebreak="cm", + unicodeslot=0xE0055, + }, + [0xE0056]={ + category="cf", + description="TAG LATIN CAPITAL LETTER V", + direction="bn", + linebreak="cm", + unicodeslot=0xE0056, + }, + [0xE0057]={ + category="cf", + description="TAG LATIN CAPITAL LETTER W", + direction="bn", + linebreak="cm", + unicodeslot=0xE0057, + }, + [0xE0058]={ + category="cf", + description="TAG LATIN CAPITAL LETTER X", + direction="bn", + linebreak="cm", + unicodeslot=0xE0058, + }, + [0xE0059]={ + category="cf", + description="TAG LATIN CAPITAL LETTER Y", + direction="bn", + linebreak="cm", + unicodeslot=0xE0059, + }, + [0xE005A]={ + category="cf", + description="TAG LATIN CAPITAL LETTER Z", + direction="bn", + linebreak="cm", + unicodeslot=0xE005A, + }, + [0xE005B]={ + category="cf", + description="TAG LEFT SQUARE BRACKET", + direction="bn", + linebreak="cm", + unicodeslot=0xE005B, + }, + [0xE005C]={ + category="cf", + description="TAG REVERSE SOLIDUS", + direction="bn", + linebreak="cm", + unicodeslot=0xE005C, + }, + [0xE005D]={ + category="cf", + description="TAG RIGHT SQUARE BRACKET", + direction="bn", + linebreak="cm", + unicodeslot=0xE005D, + }, + [0xE005E]={ + category="cf", + description="TAG CIRCUMFLEX ACCENT", + direction="bn", + linebreak="cm", + unicodeslot=0xE005E, + }, + [0xE005F]={ + category="cf", + description="TAG LOW LINE", + direction="bn", + linebreak="cm", + unicodeslot=0xE005F, + }, + [0xE0060]={ + category="cf", + description="TAG GRAVE ACCENT", + direction="bn", + linebreak="cm", + unicodeslot=0xE0060, + }, + [0xE0061]={ + category="cf", + description="TAG LATIN SMALL LETTER A", + direction="bn", + linebreak="cm", + unicodeslot=0xE0061, + }, + [0xE0062]={ + category="cf", + description="TAG LATIN SMALL LETTER B", + direction="bn", + linebreak="cm", + unicodeslot=0xE0062, + }, + [0xE0063]={ + category="cf", + description="TAG LATIN SMALL LETTER C", + direction="bn", + linebreak="cm", + unicodeslot=0xE0063, + }, + [0xE0064]={ + category="cf", + description="TAG LATIN SMALL LETTER D", + direction="bn", + linebreak="cm", + unicodeslot=0xE0064, + }, + [0xE0065]={ + category="cf", + description="TAG LATIN SMALL LETTER E", + direction="bn", + linebreak="cm", + unicodeslot=0xE0065, + }, + [0xE0066]={ + category="cf", + description="TAG LATIN SMALL LETTER F", + direction="bn", + linebreak="cm", + unicodeslot=0xE0066, + }, + [0xE0067]={ + category="cf", + description="TAG LATIN SMALL LETTER G", + direction="bn", + linebreak="cm", + unicodeslot=0xE0067, + }, + [0xE0068]={ + category="cf", + description="TAG LATIN SMALL LETTER H", + direction="bn", + linebreak="cm", + unicodeslot=0xE0068, + }, + [0xE0069]={ + category="cf", + description="TAG LATIN SMALL LETTER I", + direction="bn", + linebreak="cm", + unicodeslot=0xE0069, + }, + [0xE006A]={ + category="cf", + description="TAG LATIN SMALL LETTER J", + direction="bn", + linebreak="cm", + unicodeslot=0xE006A, + }, + [0xE006B]={ + category="cf", + description="TAG LATIN SMALL LETTER K", + direction="bn", + linebreak="cm", + unicodeslot=0xE006B, + }, + [0xE006C]={ + category="cf", + description="TAG LATIN SMALL LETTER L", + direction="bn", + linebreak="cm", + unicodeslot=0xE006C, + }, + [0xE006D]={ + category="cf", + description="TAG LATIN SMALL LETTER M", + direction="bn", + linebreak="cm", + unicodeslot=0xE006D, + }, + [0xE006E]={ + category="cf", + description="TAG LATIN SMALL LETTER N", + direction="bn", + linebreak="cm", + unicodeslot=0xE006E, + }, + [0xE006F]={ + category="cf", + description="TAG LATIN SMALL LETTER O", + direction="bn", + linebreak="cm", + unicodeslot=0xE006F, + }, + [0xE0070]={ + category="cf", + description="TAG LATIN SMALL LETTER P", + direction="bn", + linebreak="cm", + unicodeslot=0xE0070, + }, + [0xE0071]={ + category="cf", + description="TAG LATIN SMALL LETTER Q", + direction="bn", + linebreak="cm", + unicodeslot=0xE0071, + }, + [0xE0072]={ + category="cf", + description="TAG LATIN SMALL LETTER R", + direction="bn", + linebreak="cm", + unicodeslot=0xE0072, + }, + [0xE0073]={ + category="cf", + description="TAG LATIN SMALL LETTER S", + direction="bn", + linebreak="cm", + unicodeslot=0xE0073, + }, + [0xE0074]={ + category="cf", + description="TAG LATIN SMALL LETTER T", + direction="bn", + linebreak="cm", + unicodeslot=0xE0074, + }, + [0xE0075]={ + category="cf", + description="TAG LATIN SMALL LETTER U", + direction="bn", + linebreak="cm", + unicodeslot=0xE0075, + }, + [0xE0076]={ + category="cf", + description="TAG LATIN SMALL LETTER V", + direction="bn", + linebreak="cm", + unicodeslot=0xE0076, + }, + [0xE0077]={ + category="cf", + description="TAG LATIN SMALL LETTER W", + direction="bn", + linebreak="cm", + unicodeslot=0xE0077, + }, + [0xE0078]={ + category="cf", + description="TAG LATIN SMALL LETTER X", + direction="bn", + linebreak="cm", + unicodeslot=0xE0078, + }, + [0xE0079]={ + category="cf", + description="TAG LATIN SMALL LETTER Y", + direction="bn", + linebreak="cm", + unicodeslot=0xE0079, + }, + [0xE007A]={ + category="cf", + description="TAG LATIN SMALL LETTER Z", + direction="bn", + linebreak="cm", + unicodeslot=0xE007A, + }, + [0xE007B]={ + category="cf", + description="TAG LEFT CURLY BRACKET", + direction="bn", + linebreak="cm", + unicodeslot=0xE007B, + }, + [0xE007C]={ + category="cf", + description="TAG VERTICAL LINE", + direction="bn", + linebreak="cm", + unicodeslot=0xE007C, + }, + [0xE007D]={ + category="cf", + description="TAG RIGHT CURLY BRACKET", + direction="bn", + linebreak="cm", + unicodeslot=0xE007D, + }, + [0xE007E]={ + category="cf", + description="TAG TILDE", + direction="bn", + linebreak="cm", + unicodeslot=0xE007E, + }, + [0xE007F]={ + category="cf", + description="CANCEL TAG", + direction="bn", + linebreak="cm", + unicodeslot=0xE007F, + }, + [0xE0100]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0011", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0100, + }, + [0xE0101]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0012", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0101, + }, + [0xE0102]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0013", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0102, + }, + [0xE0103]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0014", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0103, + }, + [0xE0104]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0015", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0104, + }, + [0xE0105]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0016", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0105, + }, + [0xE0106]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0017", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0106, + }, + [0xE0107]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0018", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0107, + }, + [0xE0108]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0019", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0108, + }, + [0xE0109]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x001A", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0109, + }, + [0xE010A]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x001B", + direction="nsm", + linebreak="cm", + unicodeslot=0xE010A, + }, + [0xE010B]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x001C", + direction="nsm", + linebreak="cm", + unicodeslot=0xE010B, + }, + [0xE010C]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x001D", + direction="nsm", + linebreak="cm", + unicodeslot=0xE010C, + }, + [0xE010D]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x001E", + direction="nsm", + linebreak="cm", + unicodeslot=0xE010D, + }, + [0xE010E]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x001F", + direction="nsm", + linebreak="cm", + unicodeslot=0xE010E, + }, + [0xE010F]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0020", + direction="nsm", + linebreak="cm", + unicodeslot=0xE010F, + }, + [0xE0110]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0021", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0110, + }, + [0xE0111]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0022", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0111, + }, + [0xE0112]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0023", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0112, + }, + [0xE0113]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0024", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0113, + }, + [0xE0114]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0025", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0114, + }, + [0xE0115]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0026", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0115, + }, + [0xE0116]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0027", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0116, + }, + [0xE0117]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0028", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0117, + }, + [0xE0118]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0029", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0118, + }, + [0xE0119]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x002A", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0119, + }, + [0xE011A]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x002B", + direction="nsm", + linebreak="cm", + unicodeslot=0xE011A, + }, + [0xE011B]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x002C", + direction="nsm", + linebreak="cm", + unicodeslot=0xE011B, + }, + [0xE011C]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x002D", + direction="nsm", + linebreak="cm", + unicodeslot=0xE011C, + }, + [0xE011D]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x002E", + direction="nsm", + linebreak="cm", + unicodeslot=0xE011D, + }, + [0xE011E]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x002F", + direction="nsm", + linebreak="cm", + unicodeslot=0xE011E, + }, + [0xE011F]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0030", + direction="nsm", + linebreak="cm", + unicodeslot=0xE011F, + }, + [0xE0120]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0031", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0120, + }, + [0xE0121]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0032", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0121, + }, + [0xE0122]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0033", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0122, + }, + [0xE0123]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0034", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0123, + }, + [0xE0124]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0035", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0124, + }, + [0xE0125]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0036", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0125, + }, + [0xE0126]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0037", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0126, + }, + [0xE0127]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0038", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0127, + }, + [0xE0128]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0039", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0128, + }, + [0xE0129]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x003A", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0129, + }, + [0xE012A]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x003B", + direction="nsm", + linebreak="cm", + unicodeslot=0xE012A, + }, + [0xE012B]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x003C", + direction="nsm", + linebreak="cm", + unicodeslot=0xE012B, + }, + [0xE012C]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x003D", + direction="nsm", + linebreak="cm", + unicodeslot=0xE012C, + }, + [0xE012D]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x003E", + direction="nsm", + linebreak="cm", + unicodeslot=0xE012D, + }, + [0xE012E]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x003F", + direction="nsm", + linebreak="cm", + unicodeslot=0xE012E, + }, + [0xE012F]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0040", + direction="nsm", + linebreak="cm", + unicodeslot=0xE012F, + }, + [0xE0130]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0041", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0130, + }, + [0xE0131]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0042", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0131, + }, + [0xE0132]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0043", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0132, + }, + [0xE0133]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0044", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0133, + }, + [0xE0134]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0045", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0134, + }, + [0xE0135]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0046", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0135, + }, + [0xE0136]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0047", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0136, + }, + [0xE0137]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0048", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0137, + }, + [0xE0138]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0049", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0138, + }, + [0xE0139]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x004A", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0139, + }, + [0xE013A]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x004B", + direction="nsm", + linebreak="cm", + unicodeslot=0xE013A, + }, + [0xE013B]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x004C", + direction="nsm", + linebreak="cm", + unicodeslot=0xE013B, + }, + [0xE013C]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x004D", + direction="nsm", + linebreak="cm", + unicodeslot=0xE013C, + }, + [0xE013D]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x004E", + direction="nsm", + linebreak="cm", + unicodeslot=0xE013D, + }, + [0xE013E]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x004F", + direction="nsm", + linebreak="cm", + unicodeslot=0xE013E, + }, + [0xE013F]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0050", + direction="nsm", + linebreak="cm", + unicodeslot=0xE013F, + }, + [0xE0140]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0051", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0140, + }, + [0xE0141]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0052", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0141, + }, + [0xE0142]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0053", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0142, + }, + [0xE0143]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0054", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0143, + }, + [0xE0144]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0055", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0144, + }, + [0xE0145]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0056", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0145, + }, + [0xE0146]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0057", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0146, + }, + [0xE0147]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0058", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0147, + }, + [0xE0148]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0059", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0148, + }, + [0xE0149]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x005A", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0149, + }, + [0xE014A]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x005B", + direction="nsm", + linebreak="cm", + unicodeslot=0xE014A, + }, + [0xE014B]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x005C", + direction="nsm", + linebreak="cm", + unicodeslot=0xE014B, + }, + [0xE014C]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x005D", + direction="nsm", + linebreak="cm", + unicodeslot=0xE014C, + }, + [0xE014D]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x005E", + direction="nsm", + linebreak="cm", + unicodeslot=0xE014D, + }, + [0xE014E]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x005F", + direction="nsm", + linebreak="cm", + unicodeslot=0xE014E, + }, + [0xE014F]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0060", + direction="nsm", + linebreak="cm", + unicodeslot=0xE014F, + }, + [0xE0150]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0061", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0150, + }, + [0xE0151]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0062", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0151, + }, + [0xE0152]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0063", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0152, + }, + [0xE0153]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0064", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0153, + }, + [0xE0154]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0065", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0154, + }, + [0xE0155]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0066", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0155, + }, + [0xE0156]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0067", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0156, + }, + [0xE0157]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0068", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0157, + }, + [0xE0158]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0069", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0158, + }, + [0xE0159]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x006A", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0159, + }, + [0xE015A]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x006B", + direction="nsm", + linebreak="cm", + unicodeslot=0xE015A, + }, + [0xE015B]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x006C", + direction="nsm", + linebreak="cm", + unicodeslot=0xE015B, + }, + [0xE015C]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x006D", + direction="nsm", + linebreak="cm", + unicodeslot=0xE015C, + }, + [0xE015D]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x006E", + direction="nsm", + linebreak="cm", + unicodeslot=0xE015D, + }, + [0xE015E]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x006F", + direction="nsm", + linebreak="cm", + unicodeslot=0xE015E, + }, + [0xE015F]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0070", + direction="nsm", + linebreak="cm", + unicodeslot=0xE015F, + }, + [0xE0160]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0071", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0160, + }, + [0xE0161]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0072", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0161, + }, + [0xE0162]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0073", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0162, + }, + [0xE0163]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0074", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0163, + }, + [0xE0164]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0075", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0164, + }, + [0xE0165]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0076", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0165, + }, + [0xE0166]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0077", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0166, + }, + [0xE0167]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0078", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0167, + }, + [0xE0168]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0079", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0168, + }, + [0xE0169]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x007A", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0169, + }, + [0xE016A]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x007B", + direction="nsm", + linebreak="cm", + unicodeslot=0xE016A, + }, + [0xE016B]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x007C", + direction="nsm", + linebreak="cm", + unicodeslot=0xE016B, + }, + [0xE016C]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x007D", + direction="nsm", + linebreak="cm", + unicodeslot=0xE016C, + }, + [0xE016D]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x007E", + direction="nsm", + linebreak="cm", + unicodeslot=0xE016D, + }, + [0xE016E]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x007F", + direction="nsm", + linebreak="cm", + unicodeslot=0xE016E, + }, + [0xE016F]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0080", + direction="nsm", + linebreak="cm", + unicodeslot=0xE016F, + }, + [0xE0170]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0081", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0170, + }, + [0xE0171]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0082", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0171, + }, + [0xE0172]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0083", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0172, + }, + [0xE0173]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0084", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0173, + }, + [0xE0174]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0085", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0174, + }, + [0xE0175]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0086", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0175, + }, + [0xE0176]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0087", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0176, + }, + [0xE0177]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0088", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0177, + }, + [0xE0178]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0089", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0178, + }, + [0xE0179]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x008A", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0179, + }, + [0xE017A]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x008B", + direction="nsm", + linebreak="cm", + unicodeslot=0xE017A, + }, + [0xE017B]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x008C", + direction="nsm", + linebreak="cm", + unicodeslot=0xE017B, + }, + [0xE017C]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x008D", + direction="nsm", + linebreak="cm", + unicodeslot=0xE017C, + }, + [0xE017D]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x008E", + direction="nsm", + linebreak="cm", + unicodeslot=0xE017D, + }, + [0xE017E]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x008F", + direction="nsm", + linebreak="cm", + unicodeslot=0xE017E, + }, + [0xE017F]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0090", + direction="nsm", + linebreak="cm", + unicodeslot=0xE017F, + }, + [0xE0180]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0091", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0180, + }, + [0xE0181]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0092", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0181, + }, + [0xE0182]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0093", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0182, + }, + [0xE0183]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0094", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0183, + }, + [0xE0184]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0095", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0184, + }, + [0xE0185]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0096", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0185, + }, + [0xE0186]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0097", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0186, + }, + [0xE0187]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0098", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0187, + }, + [0xE0188]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0099", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0188, + }, + [0xE0189]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x009A", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0189, + }, + [0xE018A]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x009B", + direction="nsm", + linebreak="cm", + unicodeslot=0xE018A, + }, + [0xE018B]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x009C", + direction="nsm", + linebreak="cm", + unicodeslot=0xE018B, + }, + [0xE018C]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x009D", + direction="nsm", + linebreak="cm", + unicodeslot=0xE018C, + }, + [0xE018D]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x009E", + direction="nsm", + linebreak="cm", + unicodeslot=0xE018D, + }, + [0xE018E]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x009F", + direction="nsm", + linebreak="cm", + unicodeslot=0xE018E, + }, + [0xE018F]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00A0", + direction="nsm", + linebreak="cm", + unicodeslot=0xE018F, + }, + [0xE0190]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00A1", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0190, + }, + [0xE0191]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00A2", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0191, + }, + [0xE0192]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00A3", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0192, + }, + [0xE0193]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00A4", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0193, + }, + [0xE0194]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00A5", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0194, + }, + [0xE0195]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00A6", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0195, + }, + [0xE0196]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00A7", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0196, + }, + [0xE0197]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00A8", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0197, + }, + [0xE0198]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00A9", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0198, + }, + [0xE0199]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00AA", + direction="nsm", + linebreak="cm", + unicodeslot=0xE0199, + }, + [0xE019A]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00AB", + direction="nsm", + linebreak="cm", + unicodeslot=0xE019A, + }, + [0xE019B]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00AC", + direction="nsm", + linebreak="cm", + unicodeslot=0xE019B, + }, + [0xE019C]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00AD", + direction="nsm", + linebreak="cm", + unicodeslot=0xE019C, + }, + [0xE019D]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00AE", + direction="nsm", + linebreak="cm", + unicodeslot=0xE019D, + }, + [0xE019E]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00AF", + direction="nsm", + linebreak="cm", + unicodeslot=0xE019E, + }, + [0xE019F]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00B0", + direction="nsm", + linebreak="cm", + unicodeslot=0xE019F, + }, + [0xE01A0]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00B1", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01A0, + }, + [0xE01A1]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00B2", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01A1, + }, + [0xE01A2]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00B3", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01A2, + }, + [0xE01A3]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00B4", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01A3, + }, + [0xE01A4]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00B5", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01A4, + }, + [0xE01A5]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00B6", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01A5, + }, + [0xE01A6]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00B7", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01A6, + }, + [0xE01A7]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00B8", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01A7, + }, + [0xE01A8]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00B9", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01A8, + }, + [0xE01A9]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00BA", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01A9, + }, + [0xE01AA]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00BB", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01AA, + }, + [0xE01AB]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00BC", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01AB, + }, + [0xE01AC]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00BD", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01AC, + }, + [0xE01AD]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00BE", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01AD, + }, + [0xE01AE]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00BF", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01AE, + }, + [0xE01AF]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00C0", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01AF, + }, + [0xE01B0]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00C1", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01B0, + }, + [0xE01B1]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00C2", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01B1, + }, + [0xE01B2]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00C3", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01B2, + }, + [0xE01B3]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00C4", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01B3, + }, + [0xE01B4]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00C5", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01B4, + }, + [0xE01B5]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00C6", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01B5, + }, + [0xE01B6]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00C7", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01B6, + }, + [0xE01B7]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00C8", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01B7, + }, + [0xE01B8]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00C9", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01B8, + }, + [0xE01B9]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00CA", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01B9, + }, + [0xE01BA]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00CB", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01BA, + }, + [0xE01BB]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00CC", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01BB, + }, + [0xE01BC]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00CD", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01BC, + }, + [0xE01BD]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00CE", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01BD, + }, + [0xE01BE]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00CF", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01BE, + }, + [0xE01BF]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00D0", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01BF, + }, + [0xE01C0]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00D1", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01C0, + }, + [0xE01C1]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00D2", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01C1, + }, + [0xE01C2]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00D3", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01C2, + }, + [0xE01C3]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00D4", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01C3, + }, + [0xE01C4]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00D5", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01C4, + }, + [0xE01C5]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00D6", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01C5, + }, + [0xE01C6]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00D7", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01C6, + }, + [0xE01C7]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00D8", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01C7, + }, + [0xE01C8]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00D9", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01C8, + }, + [0xE01C9]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00DA", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01C9, + }, + [0xE01CA]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00DB", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01CA, + }, + [0xE01CB]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00DC", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01CB, + }, + [0xE01CC]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00DD", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01CC, + }, + [0xE01CD]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00DE", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01CD, + }, + [0xE01CE]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00DF", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01CE, + }, + [0xE01CF]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00E0", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01CF, + }, + [0xE01D0]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00E1", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01D0, + }, + [0xE01D1]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00E2", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01D1, + }, + [0xE01D2]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00E3", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01D2, + }, + [0xE01D3]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00E4", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01D3, + }, + [0xE01D4]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00E5", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01D4, + }, + [0xE01D5]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00E6", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01D5, + }, + [0xE01D6]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00E7", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01D6, + }, + [0xE01D7]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00E8", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01D7, + }, + [0xE01D8]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00E9", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01D8, + }, + [0xE01D9]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00EA", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01D9, + }, + [0xE01DA]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00EB", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01DA, + }, + [0xE01DB]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00EC", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01DB, + }, + [0xE01DC]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00ED", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01DC, + }, + [0xE01DD]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00EE", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01DD, + }, + [0xE01DE]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00EF", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01DE, + }, + [0xE01DF]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00F0", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01DF, + }, + [0xE01E0]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00F1", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01E0, + }, + [0xE01E1]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00F2", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01E1, + }, + [0xE01E2]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00F3", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01E2, + }, + [0xE01E3]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00F4", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01E3, + }, + [0xE01E4]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00F5", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01E4, + }, + [0xE01E5]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00F6", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01E5, + }, + [0xE01E6]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00F7", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01E6, + }, + [0xE01E7]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00F8", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01E7, + }, + [0xE01E8]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00F9", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01E8, + }, + [0xE01E9]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00FA", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01E9, + }, + [0xE01EA]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00FB", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01EA, + }, + [0xE01EB]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00FC", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01EB, + }, + [0xE01EC]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00FD", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01EC, + }, + [0xE01ED]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00FE", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01ED, + }, + [0xE01EE]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x00FF", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01EE, + }, + [0xE01EF]={ + category="mn", + cjkwd="a", + description="VARIATION SELECTOR-0x0100", + direction="nsm", + linebreak="cm", + unicodeslot=0xE01EF, + }, +--~ [0xF0000]={ +--~ category="co", +--~ cjkwd="a", +--~ description="", +--~ direction="l", +--~ unicodeslot=0xF0000, +--~ }, +--~ [0xFFFFD]={ +--~ category="co", +--~ cjkwd="a", +--~ description="", +--~ direction="l", +--~ unicodeslot=0xFFFFD, +--~ }, +--~ [0x100000]={ +--~ category="co", +--~ cjkwd="a", +--~ description="", +--~ direction="l", +--~ unicodeslot=0x100000, +--~ }, +--~ [0x10FFFD]={ +--~ category="co", +--~ cjkwd="a", +--~ description="", +--~ direction="l", +--~ unicodeslot=0x10FFFD, +--~ }, +} diff --git a/tex/context/base/char-enc.lua b/tex/context/base/char-enc.lua new file mode 100644 index 000000000..45f404ee9 --- /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.mkiv", + 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.mkiv b/tex/context/base/char-enc.mkiv new file mode 100644 index 000000000..9fe9a363b --- /dev/null +++ b/tex/context/base/char-enc.mkiv @@ -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 new file mode 100644 index 000000000..5c4a40bad --- /dev/null +++ b/tex/context/base/char-ini.lua @@ -0,0 +1,698 @@ +if not modules then modules = { } end modules ['char-ini'] = { + version = 1.001, + comment = "companion to char-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +tex = tex or { } +xml = xml or { } + +local utf = unicode.utf8 + +local utfchar, utfbyte, utfvalues = utf.char, utf.byte, string.utfvalues +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 { } + +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"] = { 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 = lower(name) + tag = gsub(name,"[^a-z]", "") + local range = characters.blocks[tag] + if range then + return range[1], range[2], range[3] + end + 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 + return start, stop, nil + end + end + local slot = tonumber(name,16) or tonumber(name) + return slot, slot, nil +end + +characters.categories = { + lu = "Letter Uppercase", + ll = "Letter Lowercase", + lt = "Letter Titlecase", + lm = "Letter Modifier", + lo = "Letter Other", + mn = "Mark Nonspacing", + mc = "Mark Spacing Combining", + me = "Mark Enclosing", + nd = "Number Decimal Digit", + nl = "Number Letter", + no = "Number Other", + pc = "Punctuation Connector", + pd = "Punctuation Dash", + ps = "Punctuation Open", + pe = "Punctuation Close", + pi = "Punctuation Initial Quote", + pf = "Punctuation Final Quote", + po = "Punctuation Other", + sm = "Symbol Math", + sc = "Symbol Currency", + sk = "Symbol Modifier", + so = "Symbol Other", + zs = "Separator Space", + zl = "Separator Line", + zp = "Separator Paragraph", + cc = "Other Control", + cf = "Other Format", + cs = "Other Surrogate", + co = "Other Private Use", + cn = "Other Not Assigned", +} + +--~ special : cf (softhyphen) zs (emspace) +--~ 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 { + "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 { + "cf","zs" +} + +-- linebreak: todo: hash +-- +-- normative : BK CR LF CM SG GL CB SP ZW NL WJ JL JV JT H2 H3 +-- informative : XX OP CL QU NS EX SY IS PR PO NU AL ID IN HY BB BA SA AI B2 + +-- east asian width: +-- +-- N A H W F Na + +characters.bidi = { + l = "Left-to-Right", + lre = "Left-to-Right Embedding", + lro = "Left-to-Right Override", + r = "Right-to-Left", + al = "Right-to-Left Arabic", + rle = "Right-to-Left Embedding", + rlo = "Right-to-Left Override", + pdf = "Pop Directional Format", + en = "European Number", + es = "European Number Separator", + et = "European Number Terminator", + an = "Arabic Number", + cs = "Common Number Separator", + nsm = "Non-Spacing Mark", + bn = "Boundary Neutral", + b = "Paragraph Separator", + s = "Segment Separator", + ws = "Whitespace", + on = "Other Neutrals", +} + +local _empty_table_ = { __index = function(t,k) return "" end } + +function table.set_empty_metatable(t) + setmetatable(t,_empty_table_) +end + +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]]-- + +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 + fallbacks[s] = k + end + directions[k] = v.direction + end + +end + +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]]-- + +--[[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(ctxcatcodes,format("\\catcode%s=13\\unexpanded\\def %s{\\%s}",n,utfchar(n),name)) +end + +function tex.uprint(n) + texsprint(ctxcatcodes,utfchar(n)) +end + +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 next, data do + -- we can use a macro instead of direct settings + local fallback = chr.fallback + if fallback then + -- texprint(format("{\\catcode %s=13\\unexpanded\\gdef %s{\\checkedchar{%s}{%s}}}",u,utfchar(u),u,fallback)) + texsprint("{\\catcode",u,"=13\\unexpanded\\gdef ",utfchar(u),"{\\checkedchar{",u,"}{",fallback,"}}}") -- no texprint + 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 + -- texprint(ctxcatcodes, "\\chardef\\"..contextname,"=",u) + texprint(ctxcatcodes,format("\\chardef\\%s=%s",contextname,u)) + else + -- texprint(ctxcatcodes, "\\let\\"..contextname,"=",utfchar(u)) + texprint(ctxcatcodes,format("\\let\\%s=%s",contextname,utfchar(u))) + if is_letter[category] then + lettered[#lettered+1] = "\\c"..u.."\\l" + end + end + elseif is_command[category] then + -- this might change: contextcommand ipv contextname + -- texprint(format("{\\catcode %s=13\\unexpanded\\gdef %s{\\%s}}",u,utfchar(u),contextname)) + texsprint("{\\catcode",u,"=13\\unexpanded\\gdef ",utfchar(u),"{\\"..contextname,"}}") -- no texprint + activated[#activated+1] = "\\c"..u.."\\a" + 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 + -- 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 + if tobeactivated then + activated = concat(activated) + for a=1,#tobeactivated do + texsprint(ctxcatcodes,format(template_a,tobeactivated[a],activated)) + end + end +end + +function characters.charcode(box) + local b = tex.box[box] + local l = b.list + texsprint((l and l.id == node.id('glyph') and l.char) or 0) +end + +--[[ldx-- +

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

+--ldx]]-- + +-- we need a function ... + +function characters.setcodes() + 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(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 + +--[[ldx-- +

Next comes a whole series of helper methods. These are (will be) part +of the official .

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

This converts a string (if given) into a number.

+--ldx]]-- + +function characters.number(n) + if type(n) == "string" then return tonumber(n,16) else return n end +end + +--[[ldx-- +

Checking for valid characters.

+--ldx]]-- + +function characters.is_valid(s) + return s or "" +end + +function characters.checked(s, default) + return s or default +end + +characters.valid = characters.is_valid + +--[[ldx-- +

+--ldx]]-- +-- set a table entry; index is number (can be different from unicodeslot) + +function characters.set(n, c) + data[characters.number(n)] = c +end + +--[[ldx-- +

Get a table entry happens by number. Keep in mind that the unicodeslot +can be different (not likely).

+--ldx]]-- + +function characters.get(n) + return data[characters.number(n)] +end + +--[[ldx-- +

A couple of convenience methods. Beware, these are not that fast due +to the checking.

+--ldx]]-- + +function characters.hexindex(n) + return format("%04X", characters.valid(data[characters.number(n)].unicodeslot)) +end + +function characters.contextname(n) + return characters.valid(data[characters.number(n)].contextname) +end + +function characters.adobename(n) + return characters.valid(data[characters.number(n)].adobename) +end + +function characters.description(n) + return characters.valid(data[characters.number(n)].description) +end + +function characters.category(n) + return characters.valid(data[characters.number(n)].category) +end + +--[[ldx-- +

Requesting lower and uppercase codes:

+--ldx]]-- + +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 = data[n] + if c and c.contextname then + texsprint(texcatcodes, "\\"..c.contextname) + else + texsprint(utfchar(n)) + end +end + +function characters.shape(n) + local shcode = data[n].shcode + if not shcode then + return n, nil + elseif type(shcode) == "table" then + return shcode[1], shcode[#shcode] + else + return shcode, nil + end +end + +--[[ldx-- +

Categories play an important role, so here are some checkers.

+--ldx]]-- + +function characters.is_of_category(token,category) + if type(token) == "string" then + return data[utfbyte(token)].category == category + else + return data[token].category == category + end +end + +function characters.i_is_of_category(i,category) -- by index (number) + local cd = data[i] + return cd and cd.category == category +end + +function characters.n_is_of_category(n,category) -- by name (string) + local cd = data[utfbyte(n)] + return cd and cd.category == category +end + +-- xml support (moved) + +function characters.remapentity(chr,slot) + texsprint(format("{\\catcode%s=13\\xdef%s{\\string%s}}",slot,utfchar(slot),chr)) +end + +characters.active_offset = 0x10000 -- there will be remapped in that byte range + +-- xml.entities = xml.entities or { } +-- +-- storage.register("xml/entities",xml.entities,"xml.entities") -- this will move to lxml +-- +-- function characters.setmkiventities() +-- local entities = xml.entities +-- entities.lt = "<" +-- entities.amp = "&" +-- entities.gt = ">" +-- end +-- +-- function characters.setmkiientities() +-- local entities = xml.entities +-- entities.lt = utfchar(characters.active_offset + utfbyte("<")) +-- entities.amp = utfchar(characters.active_offset + utfbyte("&")) +-- entities.gt = utfchar(characters.active_offset + utfbyte(">")) +-- end + +-- some day we will make a table + +function characters.lower(str) + local new = { } + for u in utfvalues(str) do + new[#new+1] = utfchar(data[u].lccode or u) + end + return concat(new) +end + +function characters.upper(str) + local new = { } + for u in utfvalues(str) do + new[#new+1] = utfchar(data[u].uccode or u) + end + return concat(new) +end + +-- -- some day we might go this route, but it does not really save that much +-- -- so not now (we can generate a lot using mtx-unicode that operates on the +-- -- database) +-- +-- -- category cjkwd direction linebreak +-- +-- -- adobename comment contextcommand contextname description fallback lccode +-- -- mathclass mathfiller mathname mathspec mathstretch mathsymbol mirror +-- -- range shcode specials uccode uccodes unicodeslot +-- +-- local data = { +-- ['one']={ +-- common = { +-- category="cc", +-- direction="bn", +-- linebreak="cm", +-- }, +-- vector = { +-- [0x0000] = { +-- description="NULL", +-- group='one', +-- unicodeslot=0x0000, +-- }, +-- { +-- description="START OF HEADING", +-- group='one', +-- unicodeslot=0x0001, +-- }, +-- } +-- } +-- } +-- +-- local chardata, groupdata = { }, { } +-- +-- for group, gdata in next, data do +-- local common, vector = { __index = gdata.common }, gdata.vector +-- for character, cdata in next, vector do +-- chardata[character] = cdata +-- setmetatable(cdata,common) +-- end +-- groupdata[group] = gdata +-- end + +--~ characters.data, characters.groups = chardata, groupdata diff --git a/tex/context/base/char-ini.mkiv b/tex/context/base/char-ini.mkiv new file mode 100644 index 000000000..0d5e16bb0 --- /dev/null +++ b/tex/context/base/char-ini.mkiv @@ -0,0 +1,76 @@ +%D \module +%D [ file=char-ini, +%D version=2006.08.20, +%D title=\CONTEXT\ Character Support, +%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 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-map}{1.001} % maybe we will load this someplace else +\registerctxluafile{char-tex}{1.001} + +\unprotect + +% \def\checkedchar#1% #2% +% {\relax\iffontchar\font#1 \expandafter\firstoftwoarguments\else\expandafter\secondoftwoarguments\fi{\char#1}} +% +% impossible in math mode so there always fallback (till we have gyre): + +\def\utfchar #1{\ctxlua{tex.uprint(\number#1)}} +\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}} + +%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). It is on the agenda +%D to do this with \type {tex.lccode} cum suis once they're available. + +\def\setcclcuc#1#2#3{\global\catcode#1=\@@letter\global\lccode#1=#2\global\uccode#1=#3\relax} +\def\setcclcucself#1{\global\catcode#1=\@@letter\global\lccode#1=#1\global\uccode#1=#1\relax } + +\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 +%D to a double quote but it should be ^^19 since the original is in ec encoding). + +% \setcclcuc "201C "201C "201C +% \setcclcuc "201D "201D "201D + +\ctxlua { + characters.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, + } + ) + catcodes.register("xmlcatcodes",\number\xmlcatcodes) +} + +\protect \endinput diff --git a/tex/context/base/char-map.lua b/tex/context/base/char-map.lua new file mode 100644 index 000000000..3f8cc3b3d --- /dev/null +++ b/tex/context/base/char-map.lua @@ -0,0 +1,1069 @@ +if not modules then modules = { } end modules ['char-map'] = { + version = 1.001, + comment = "companion to char-ini.mkiv", + author = "Hans Hagen & Arthur Reutenauer", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +characters = characters or { } + +characters.casemap={ + [0x0049]={ + ["az"]={ + ["not_before_dot"]={ + ["lower"]={ 0x0131 }, + ["title"]={ 0x0049 }, + ["upper"]={ 0x0049 }, + }, + }, + ["lt"]={ + ["more_above"]={ + ["lower"]={ 0x0069, 0x0307 }, + ["title"]={ 0x0049 }, + ["upper"]={ 0x0049 }, + }, + }, + ["tr"]={ + ["not_before_dot"]={ + ["lower"]={ 0x0131 }, + ["title"]={ 0x0049 }, + ["upper"]={ 0x0049 }, + }, + }, + }, + [0x004A]={ + ["lt"]={ + ["more_above"]={ + ["lower"]={ 0x006A, 0x0307 }, + ["title"]={ 0x004A }, + ["upper"]={ 0x004A }, + }, + }, + }, + [0x0069]={ + ["az"]={ + ["all"]={ + ["lower"]={ 0x0069 }, + ["title"]={ 0x0130 }, + ["upper"]={ 0x0130 }, + }, + }, + ["tr"]={ + ["all"]={ + ["lower"]={ 0x0069 }, + ["title"]={ 0x0130 }, + ["upper"]={ 0x0130 }, + }, + }, + }, + [0x00CC]={ + ["lt"]={ + ["all"]={ + ["lower"]={ 0x0069, 0x0307, 0x0300 }, + ["title"]={ 0x00CC }, + ["upper"]={ 0x00CC }, + }, + }, + }, + [0x00CD]={ + ["lt"]={ + ["all"]={ + ["lower"]={ 0x0069, 0x0307, 0x0301 }, + ["title"]={ 0x00CD }, + ["upper"]={ 0x00CD }, + }, + }, + }, + [0x00DF]={ + [""]={ + ["all"]={ + ["lower"]={ 0x00DF }, + ["title"]={ 0x0053, 0x0073 }, + ["upper"]={ 0x0053, 0x0053 }, + }, + }, + }, + [0x0128]={ + ["lt"]={ + ["all"]={ + ["lower"]={ 0x0069, 0x0307, 0x0303 }, + ["title"]={ 0x0128 }, + ["upper"]={ 0x0128 }, + }, + }, + }, + [0x012E]={ + ["lt"]={ + ["more_above"]={ + ["lower"]={ 0x012F, 0x0307 }, + ["title"]={ 0x012E }, + ["upper"]={ 0x012E }, + }, + }, + }, + [0x0130]={ + [""]={ + ["all"]={ + ["lower"]={ 0x0069, 0x0307 }, + ["title"]={ 0x0130 }, + ["upper"]={ 0x0130 }, + }, + }, + ["az"]={ + ["all"]={ + ["lower"]={ 0x0069 }, + ["title"]={ 0x0130 }, + ["upper"]={ 0x0130 }, + }, + }, + ["tr"]={ + ["all"]={ + ["lower"]={ 0x0069 }, + ["title"]={ 0x0130 }, + ["upper"]={ 0x0130 }, + }, + }, + }, + [0x0149]={ + [""]={ + ["all"]={ + ["lower"]={ 0x0149 }, + ["title"]={ 0x02BC, 0x004E }, + ["upper"]={ 0x02BC, 0x004E }, + }, + }, + }, + [0x01F0]={ + [""]={ + ["all"]={ + ["lower"]={ 0x01F0 }, + ["title"]={ 0x004A, 0x030C }, + ["upper"]={ 0x004A, 0x030C }, + }, + }, + }, + [0x0307]={ + ["az"]={ + ["after_i"]={ + ["lower"]={}, + ["title"]={ 0x0307 }, + ["upper"]={ 0x0307 }, + }, + }, + ["lt"]={ + ["after_soft_dotted"]={ + ["lower"]={ 0x0307 }, + ["title"]={}, + ["upper"]={}, + }, + }, + ["tr"]={ + ["after_i"]={ + ["lower"]={}, + ["title"]={ 0x0307 }, + ["upper"]={ 0x0307 }, + }, + }, + }, + [0x0390]={ + [""]={ + ["all"]={ + ["lower"]={ 0x0390 }, + ["title"]={ 0x0399, 0x0308, 0x0301 }, + ["upper"]={ 0x0399, 0x0308, 0x0301 }, + }, + }, + }, + [0x03A3]={ + ["final_sigma"]={ + ["all"]={ + ["lower"]={ 0x03C2 }, + ["title"]={ 0x03A3 }, + ["upper"]={ 0x03A3 }, + }, + }, + }, + [0x03B0]={ + [""]={ + ["all"]={ + ["lower"]={ 0x03B0 }, + ["title"]={ 0x03A5, 0x0308, 0x0301 }, + ["upper"]={ 0x03A5, 0x0308, 0x0301 }, + }, + }, + }, + [0x0587]={ + [""]={ + ["all"]={ + ["lower"]={ 0x0587 }, + ["title"]={ 0x0535, 0x0582 }, + ["upper"]={ 0x0535, 0x0552 }, + }, + }, + }, + [0x1E96]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1E96 }, + ["title"]={ 0x0048, 0x0331 }, + ["upper"]={ 0x0048, 0x0331 }, + }, + }, + }, + [0x1E97]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1E97 }, + ["title"]={ 0x0054, 0x0308 }, + ["upper"]={ 0x0054, 0x0308 }, + }, + }, + }, + [0x1E98]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1E98 }, + ["title"]={ 0x0057, 0x030A }, + ["upper"]={ 0x0057, 0x030A }, + }, + }, + }, + [0x1E99]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1E99 }, + ["title"]={ 0x0059, 0x030A }, + ["upper"]={ 0x0059, 0x030A }, + }, + }, + }, + [0x1E9A]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1E9A }, + ["title"]={ 0x0041, 0x02BE }, + ["upper"]={ 0x0041, 0x02BE }, + }, + }, + }, + [0x1F50]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F50 }, + ["title"]={ 0x03A5, 0x0313 }, + ["upper"]={ 0x03A5, 0x0313 }, + }, + }, + }, + [0x1F52]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F52 }, + ["title"]={ 0x03A5, 0x0313, 0x0300 }, + ["upper"]={ 0x03A5, 0x0313, 0x0300 }, + }, + }, + }, + [0x1F54]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F54 }, + ["title"]={ 0x03A5, 0x0313, 0x0301 }, + ["upper"]={ 0x03A5, 0x0313, 0x0301 }, + }, + }, + }, + [0x1F56]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F56 }, + ["title"]={ 0x03A5, 0x0313, 0x0342 }, + ["upper"]={ 0x03A5, 0x0313, 0x0342 }, + }, + }, + }, + [0x1F80]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F80 }, + ["title"]={ 0x1F88 }, + ["upper"]={ 0x1F08, 0x0399 }, + }, + }, + }, + [0x1F81]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F81 }, + ["title"]={ 0x1F89 }, + ["upper"]={ 0x1F09, 0x0399 }, + }, + }, + }, + [0x1F82]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F82 }, + ["title"]={ 0x1F8A }, + ["upper"]={ 0x1F0A, 0x0399 }, + }, + }, + }, + [0x1F83]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F83 }, + ["title"]={ 0x1F8B }, + ["upper"]={ 0x1F0B, 0x0399 }, + }, + }, + }, + [0x1F84]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F84 }, + ["title"]={ 0x1F8C }, + ["upper"]={ 0x1F0C, 0x0399 }, + }, + }, + }, + [0x1F85]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F85 }, + ["title"]={ 0x1F8D }, + ["upper"]={ 0x1F0D, 0x0399 }, + }, + }, + }, + [0x1F86]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F86 }, + ["title"]={ 0x1F8E }, + ["upper"]={ 0x1F0E, 0x0399 }, + }, + }, + }, + [0x1F87]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F87 }, + ["title"]={ 0x1F8F }, + ["upper"]={ 0x1F0F, 0x0399 }, + }, + }, + }, + [0x1F88]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F80 }, + ["title"]={ 0x1F88 }, + ["upper"]={ 0x1F08, 0x0399 }, + }, + }, + }, + [0x1F89]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F81 }, + ["title"]={ 0x1F89 }, + ["upper"]={ 0x1F09, 0x0399 }, + }, + }, + }, + [0x1F8A]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F82 }, + ["title"]={ 0x1F8A }, + ["upper"]={ 0x1F0A, 0x0399 }, + }, + }, + }, + [0x1F8B]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F83 }, + ["title"]={ 0x1F8B }, + ["upper"]={ 0x1F0B, 0x0399 }, + }, + }, + }, + [0x1F8C]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F84 }, + ["title"]={ 0x1F8C }, + ["upper"]={ 0x1F0C, 0x0399 }, + }, + }, + }, + [0x1F8D]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F85 }, + ["title"]={ 0x1F8D }, + ["upper"]={ 0x1F0D, 0x0399 }, + }, + }, + }, + [0x1F8E]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F86 }, + ["title"]={ 0x1F8E }, + ["upper"]={ 0x1F0E, 0x0399 }, + }, + }, + }, + [0x1F8F]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F87 }, + ["title"]={ 0x1F8F }, + ["upper"]={ 0x1F0F, 0x0399 }, + }, + }, + }, + [0x1F90]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F90 }, + ["title"]={ 0x1F98 }, + ["upper"]={ 0x1F28, 0x0399 }, + }, + }, + }, + [0x1F91]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F91 }, + ["title"]={ 0x1F99 }, + ["upper"]={ 0x1F29, 0x0399 }, + }, + }, + }, + [0x1F92]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F92 }, + ["title"]={ 0x1F9A }, + ["upper"]={ 0x1F2A, 0x0399 }, + }, + }, + }, + [0x1F93]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F93 }, + ["title"]={ 0x1F9B }, + ["upper"]={ 0x1F2B, 0x0399 }, + }, + }, + }, + [0x1F94]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F94 }, + ["title"]={ 0x1F9C }, + ["upper"]={ 0x1F2C, 0x0399 }, + }, + }, + }, + [0x1F95]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F95 }, + ["title"]={ 0x1F9D }, + ["upper"]={ 0x1F2D, 0x0399 }, + }, + }, + }, + [0x1F96]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F96 }, + ["title"]={ 0x1F9E }, + ["upper"]={ 0x1F2E, 0x0399 }, + }, + }, + }, + [0x1F97]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F97 }, + ["title"]={ 0x1F9F }, + ["upper"]={ 0x1F2F, 0x0399 }, + }, + }, + }, + [0x1F98]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F90 }, + ["title"]={ 0x1F98 }, + ["upper"]={ 0x1F28, 0x0399 }, + }, + }, + }, + [0x1F99]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F91 }, + ["title"]={ 0x1F99 }, + ["upper"]={ 0x1F29, 0x0399 }, + }, + }, + }, + [0x1F9A]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F92 }, + ["title"]={ 0x1F9A }, + ["upper"]={ 0x1F2A, 0x0399 }, + }, + }, + }, + [0x1F9B]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F93 }, + ["title"]={ 0x1F9B }, + ["upper"]={ 0x1F2B, 0x0399 }, + }, + }, + }, + [0x1F9C]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F94 }, + ["title"]={ 0x1F9C }, + ["upper"]={ 0x1F2C, 0x0399 }, + }, + }, + }, + [0x1F9D]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F95 }, + ["title"]={ 0x1F9D }, + ["upper"]={ 0x1F2D, 0x0399 }, + }, + }, + }, + [0x1F9E]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F96 }, + ["title"]={ 0x1F9E }, + ["upper"]={ 0x1F2E, 0x0399 }, + }, + }, + }, + [0x1F9F]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1F97 }, + ["title"]={ 0x1F9F }, + ["upper"]={ 0x1F2F, 0x0399 }, + }, + }, + }, + [0x1FA0]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FA0 }, + ["title"]={ 0x1FA8 }, + ["upper"]={ 0x1F68, 0x0399 }, + }, + }, + }, + [0x1FA1]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FA1 }, + ["title"]={ 0x1FA9 }, + ["upper"]={ 0x1F69, 0x0399 }, + }, + }, + }, + [0x1FA2]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FA2 }, + ["title"]={ 0x1FAA }, + ["upper"]={ 0x1F6A, 0x0399 }, + }, + }, + }, + [0x1FA3]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FA3 }, + ["title"]={ 0x1FAB }, + ["upper"]={ 0x1F6B, 0x0399 }, + }, + }, + }, + [0x1FA4]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FA4 }, + ["title"]={ 0x1FAC }, + ["upper"]={ 0x1F6C, 0x0399 }, + }, + }, + }, + [0x1FA5]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FA5 }, + ["title"]={ 0x1FAD }, + ["upper"]={ 0x1F6D, 0x0399 }, + }, + }, + }, + [0x1FA6]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FA6 }, + ["title"]={ 0x1FAE }, + ["upper"]={ 0x1F6E, 0x0399 }, + }, + }, + }, + [0x1FA7]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FA7 }, + ["title"]={ 0x1FAF }, + ["upper"]={ 0x1F6F, 0x0399 }, + }, + }, + }, + [0x1FA8]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FA0 }, + ["title"]={ 0x1FA8 }, + ["upper"]={ 0x1F68, 0x0399 }, + }, + }, + }, + [0x1FA9]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FA1 }, + ["title"]={ 0x1FA9 }, + ["upper"]={ 0x1F69, 0x0399 }, + }, + }, + }, + [0x1FAA]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FA2 }, + ["title"]={ 0x1FAA }, + ["upper"]={ 0x1F6A, 0x0399 }, + }, + }, + }, + [0x1FAB]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FA3 }, + ["title"]={ 0x1FAB }, + ["upper"]={ 0x1F6B, 0x0399 }, + }, + }, + }, + [0x1FAC]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FA4 }, + ["title"]={ 0x1FAC }, + ["upper"]={ 0x1F6C, 0x0399 }, + }, + }, + }, + [0x1FAD]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FA5 }, + ["title"]={ 0x1FAD }, + ["upper"]={ 0x1F6D, 0x0399 }, + }, + }, + }, + [0x1FAE]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FA6 }, + ["title"]={ 0x1FAE }, + ["upper"]={ 0x1F6E, 0x0399 }, + }, + }, + }, + [0x1FAF]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FA7 }, + ["title"]={ 0x1FAF }, + ["upper"]={ 0x1F6F, 0x0399 }, + }, + }, + }, + [0x1FB2]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FB2 }, + ["title"]={ 0x1FBA, 0x0345 }, + ["upper"]={ 0x1FBA, 0x0399 }, + }, + }, + }, + [0x1FB3]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FB3 }, + ["title"]={ 0x1FBC }, + ["upper"]={ 0x0391, 0x0399 }, + }, + }, + }, + [0x1FB4]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FB4 }, + ["title"]={ 0x0386, 0x0345 }, + ["upper"]={ 0x0386, 0x0399 }, + }, + }, + }, + [0x1FB6]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FB6 }, + ["title"]={ 0x0391, 0x0342 }, + ["upper"]={ 0x0391, 0x0342 }, + }, + }, + }, + [0x1FB7]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FB7 }, + ["title"]={ 0x0391, 0x0342, 0x0345 }, + ["upper"]={ 0x0391, 0x0342, 0x0399 }, + }, + }, + }, + [0x1FBC]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FB3 }, + ["title"]={ 0x1FBC }, + ["upper"]={ 0x0391, 0x0399 }, + }, + }, + }, + [0x1FC2]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FC2 }, + ["title"]={ 0x1FCA, 0x0345 }, + ["upper"]={ 0x1FCA, 0x0399 }, + }, + }, + }, + [0x1FC3]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FC3 }, + ["title"]={ 0x1FCC }, + ["upper"]={ 0x0397, 0x0399 }, + }, + }, + }, + [0x1FC4]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FC4 }, + ["title"]={ 0x0389, 0x0345 }, + ["upper"]={ 0x0389, 0x0399 }, + }, + }, + }, + [0x1FC6]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FC6 }, + ["title"]={ 0x0397, 0x0342 }, + ["upper"]={ 0x0397, 0x0342 }, + }, + }, + }, + [0x1FC7]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FC7 }, + ["title"]={ 0x0397, 0x0342, 0x0345 }, + ["upper"]={ 0x0397, 0x0342, 0x0399 }, + }, + }, + }, + [0x1FCC]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FC3 }, + ["title"]={ 0x1FCC }, + ["upper"]={ 0x0397, 0x0399 }, + }, + }, + }, + [0x1FD2]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FD2 }, + ["title"]={ 0x0399, 0x0308, 0x0300 }, + ["upper"]={ 0x0399, 0x0308, 0x0300 }, + }, + }, + }, + [0x1FD3]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FD3 }, + ["title"]={ 0x0399, 0x0308, 0x0301 }, + ["upper"]={ 0x0399, 0x0308, 0x0301 }, + }, + }, + }, + [0x1FD6]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FD6 }, + ["title"]={ 0x0399, 0x0342 }, + ["upper"]={ 0x0399, 0x0342 }, + }, + }, + }, + [0x1FD7]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FD7 }, + ["title"]={ 0x0399, 0x0308, 0x0342 }, + ["upper"]={ 0x0399, 0x0308, 0x0342 }, + }, + }, + }, + [0x1FE2]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FE2 }, + ["title"]={ 0x03A5, 0x0308, 0x0300 }, + ["upper"]={ 0x03A5, 0x0308, 0x0300 }, + }, + }, + }, + [0x1FE3]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FE3 }, + ["title"]={ 0x03A5, 0x0308, 0x0301 }, + ["upper"]={ 0x03A5, 0x0308, 0x0301 }, + }, + }, + }, + [0x1FE4]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FE4 }, + ["title"]={ 0x03A1, 0x0313 }, + ["upper"]={ 0x03A1, 0x0313 }, + }, + }, + }, + [0x1FE6]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FE6 }, + ["title"]={ 0x03A5, 0x0342 }, + ["upper"]={ 0x03A5, 0x0342 }, + }, + }, + }, + [0x1FE7]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FE7 }, + ["title"]={ 0x03A5, 0x0308, 0x0342 }, + ["upper"]={ 0x03A5, 0x0308, 0x0342 }, + }, + }, + }, + [0x1FF2]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FF2 }, + ["title"]={ 0x1FFA, 0x0345 }, + ["upper"]={ 0x1FFA, 0x0399 }, + }, + }, + }, + [0x1FF3]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FF3 }, + ["title"]={ 0x1FFC }, + ["upper"]={ 0x03A9, 0x0399 }, + }, + }, + }, + [0x1FF4]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FF4 }, + ["title"]={ 0x038F, 0x0345 }, + ["upper"]={ 0x038F, 0x0399 }, + }, + }, + }, + [0x1FF6]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FF6 }, + ["title"]={ 0x03A9, 0x0342 }, + ["upper"]={ 0x03A9, 0x0342 }, + }, + }, + }, + [0x1FF7]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FF7 }, + ["title"]={ 0x03A9, 0x0342, 0x0345 }, + ["upper"]={ 0x03A9, 0x0342, 0x0399 }, + }, + }, + }, + [0x1FFC]={ + [""]={ + ["all"]={ + ["lower"]={ 0x1FF3 }, + ["title"]={ 0x1FFC }, + ["upper"]={ 0x03A9, 0x0399 }, + }, + }, + }, + [0xFB00]={ + [""]={ + ["all"]={ + ["lower"]={ 0xFB00 }, + ["title"]={ 0x0046, 0x0066 }, + ["upper"]={ 0x0046, 0x0046 }, + }, + }, + }, + [0xFB01]={ + [""]={ + ["all"]={ + ["lower"]={ 0xFB01 }, + ["title"]={ 0x0046, 0x0069 }, + ["upper"]={ 0x0046, 0x0049 }, + }, + }, + }, + [0xFB02]={ + [""]={ + ["all"]={ + ["lower"]={ 0xFB02 }, + ["title"]={ 0x0046, 0x006C }, + ["upper"]={ 0x0046, 0x004C }, + }, + }, + }, + [0xFB03]={ + [""]={ + ["all"]={ + ["lower"]={ 0xFB03 }, + ["title"]={ 0x0046, 0x0066, 0x0069 }, + ["upper"]={ 0x0046, 0x0046, 0x0049 }, + }, + }, + }, + [0xFB04]={ + [""]={ + ["all"]={ + ["lower"]={ 0xFB04 }, + ["title"]={ 0x0046, 0x0066, 0x006C }, + ["upper"]={ 0x0046, 0x0046, 0x004C }, + }, + }, + }, + [0xFB05]={ + [""]={ + ["all"]={ + ["lower"]={ 0xFB05 }, + ["title"]={ 0x0053, 0x0074 }, + ["upper"]={ 0x0053, 0x0054 }, + }, + }, + }, + [0xFB06]={ + [""]={ + ["all"]={ + ["lower"]={ 0xFB06 }, + ["title"]={ 0x0053, 0x0074 }, + ["upper"]={ 0x0053, 0x0054 }, + }, + }, + }, + [0xFB13]={ + [""]={ + ["all"]={ + ["lower"]={ 0xFB13 }, + ["title"]={ 0x0544, 0x0576 }, + ["upper"]={ 0x0544, 0x0546 }, + }, + }, + }, + [0xFB14]={ + [""]={ + ["all"]={ + ["lower"]={ 0xFB14 }, + ["title"]={ 0x0544, 0x0565 }, + ["upper"]={ 0x0544, 0x0535 }, + }, + }, + }, + [0xFB15]={ + [""]={ + ["all"]={ + ["lower"]={ 0xFB15 }, + ["title"]={ 0x0544, 0x056B }, + ["upper"]={ 0x0544, 0x053B }, + }, + }, + }, + [0xFB16]={ + [""]={ + ["all"]={ + ["lower"]={ 0xFB16 }, + ["title"]={ 0x054E, 0x0576 }, + ["upper"]={ 0x054E, 0x0546 }, + }, + }, + }, + [0xFB17]={ + [""]={ + ["all"]={ + ["lower"]={ 0xFB17 }, + ["title"]={ 0x0544, 0x056D }, + ["upper"]={ 0x0544, 0x053D }, + }, + }, + }, +} diff --git a/tex/context/base/char-tex.lua b/tex/context/base/char-tex.lua new file mode 100644 index 000000000..ed9a244d7 --- /dev/null +++ b/tex/context/base/char-tex.lua @@ -0,0 +1,89 @@ +if not modules then modules = { } end modules ['char-tex'] = { + version = 1.001, + comment = "companion to char-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +characters = characters or { } +characters.tex = characters.tex or { } + +local find = string.find + +local accent_map = { + ['~'] = "̃" , -- ̃ Ẽ + ['"'] = "̈" , -- ̈ Ë + ["`"] = "̀" , -- ̀ È + ["'"] = "́" , -- ́ É + ["^"] = "̂" , -- ̂ Ê + -- ̄ Ē + -- ̆ Ĕ + -- ̇ Ė + -- ̉ Ẻ + -- ̌ Ě + -- ̏ Ȅ + -- ̑ Ȇ + -- ̣ Ẹ + -- ̧ Ȩ + -- ̨ Ę + -- ̭ Ḙ + -- ̰ Ḛ +} + +local accents = table.concat(table.keys(accent_map)) + +local function remap_accents(a,c,braced) + local m = accent_map[a] + if m then + return c .. m + elseif braced then + return "\\" .. a .. "{" .. c .. "}" + else + return "\\" .. a .. c + end +end + +local command_map = { + ["i"] = "ı" +} + +local function remap_commands(c) + local m = command_map[c] + if m then + return m + else + return "\\" .. c + end +end + +local P, C, R, S, Cs, Cc = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cs, lpeg.Cc +local U, lpegmatch = lpeg.patterns.utf8, lpeg.match + +local accents = (P('\\') * C(S(accents)) * (P("{") * C(U) * P("}" * Cc(true)) + C(U) * Cc(false))) / remap_accents +local commands = (P('\\') * C(R("az","AZ")^1)) / remap_commands + +local convert_accents = Cs((accents + P(1))^0) +local convert_commands = Cs((commands + P(1))^0) + +local no_l = P("{") / "" +local no_r = P("}") / "" + +local convert_accents_strip = Cs((no_l * accents * no_r + accents + P(1))^0) +local convert_commands_strip = Cs((no_l * commands * no_r + commands + P(1))^0) + +function characters.tex.toutf(str,strip) + if find(str,"\\") then -- we can start at teh found position + if strip then + str = lpegmatch(convert_commands_strip,str) + str = lpegmatch(convert_accents_strip,str) + else + str = lpegmatch(convert_commands,str) + str = lpegmatch(convert_accents,str) + end + end + return str +end + +--~ print(characters.tex.toutf([[\"{e}]]),true) +--~ print(characters.tex.toutf([[{\"{e}}]],true)) diff --git a/tex/context/base/char-utf.lua b/tex/context/base/char-utf.lua new file mode 100644 index 000000000..6dd85fdc8 --- /dev/null +++ b/tex/context/base/char-utf.lua @@ -0,0 +1,273 @@ +if not modules then modules = { } end modules ['char-utf'] = { + version = 1.001, + comment = "companion to char-utf.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--[[ldx-- +

When a sequence of characters enters the application, it may +be neccessary to collapse subsequences into their composed variant.

+ +

This module implements methods for collapsing and expanding +sequences. We also provide means to deal with characters that are +special to as well as 8-bit characters that need to end up +in special kinds of output (for instance ).

+ +

We implement these manipulations as filters. One can run multiple filters +over a string.

+--ldx]]-- + +local utf = unicode.utf8 +local concat, gmatch = table.concat, string.gmatch +local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues + +local ctxcatcodes = tex.ctxcatcodes + +characters = characters or { } +characters.graphemes = characters.graphemes or { } +characters.filters = characters.filters or { } +characters.filters.utf = characters.filters.utf or { } + +characters.filters.utf.initialized = false +characters.filters.utf.collapsing = true +characters.filters.utf.expanding = true + +local graphemes = characters.graphemes +local utffilters = characters.filters.utf +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.

+--ldx]]-- + +function utffilters.initialize() + if utffilters.collapsing and not utffilters.initialized then + 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 + local first, second = utfchar(vs[2]), utfchar(vs[3]) + local cgf = graphemes[first] + if not cgf then + cgf = { } + graphemes[first] = cgf + end + cgf[second] = utfchar(k) + end + end + utffilters.initialized = true + end +end + +-- utffilters.add_grapheme(utfchar(318),'l','\string~') +-- utffilters.add_grapheme('c','a','b') + +function utffilters.add_grapheme(result,first,second) + local r, f, s = tonumber(result), tonumber(first), tonumber(second) + if r then result = utfchar(r) end + if f then first = utfchar(f) end + if s then second = utfchar(s) end + if not graphemes[first] then + graphemes[first] = { [second] = result } + else + graphemes[first][second] = result + end +end + +function utffilters.collapse(str) -- old one + if utffilters.collapsing and str and #str > 1 then + if not utffilters.initialized then -- saves a call + utffilters.initialize() + end + local tokens, first, done = { }, false, false + for second in utfcharacters(str) do + local cgf = graphemes[first] + if cgf and cgf[second] then + first, done = cgf[second], true + elseif first then + tokens[#tokens+1] = first + first = second + else + first = second + end + end + if done then + tokens[#tokens+1] = first + return concat(tokens) + end + end + return str +end + +--[[ldx-- +

In order to deal with 8-bit output, we need to find a way to +go from to 8-bit. This is handled in the + engine itself.

+ +

This leaves us problems with characters that are specific to + like {}, $ and alike.

+ +

We can remap some chars that tex input files are sensitive for to +a private area (while writing to a utility file) and revert then +to their original slot when we read in such a file. Instead of +reverting, we can (when we resolve characters to glyphs) map them +to their right glyph there.

+ +

For this purpose we can use the private planes 0x0F0000 and +0x100000.

+--ldx]]-- + +utffilters.private = { + high = { }, + low = { }, + escapes = { }, +} + +local low = utffilters.private.low +local high = utffilters.private.high +local escapes = utffilters.private.escapes +local special = "~#$%^&_{}\\|" + +function utffilters.private.set(ch) + local cb + if type(ch) == "number" then + cb, ch = ch, utfchar(ch) + else + cb = utfbyte(ch) + end + if cb < 256 then + low[ch] = utfchar(0x0F0000 + cb) + high[utfchar(0x0F0000 + cb)] = ch + escapes[ch] = "\\" .. ch + end +end + +function utffilters.private.replace(str) return utfgsub(str,"(.)", low ) end +function utffilters.private.revert(str) return utfgsub(str,"(.)", high ) end +function utffilters.private.escape(str) return utfgsub(str,"(.)", escapes) end + +local set = utffilters.private.set + +for ch in gmatch(special,".") do set(ch) end + +--[[ldx-- +

We get a more efficient variant of this when we integrate +replacements in collapser. This more or less renders the previous +private code redundant. The following code is equivalent but the +first snippet uses the relocated dollars.

+ + +[󰀤x󰀤] [$x$] + +--ldx]]-- + +local cr = utffilters.private.high -- kan via een lpeg +local cf = utffilters + +--[[ldx-- +

The next variant has lazy token collecting, on a 140 page mk.tex this saves +about .25 seconds, which is understandable because we have no graphmes and +not collecting tokens is not only faster but also saves garbage collecting. +

+--ldx]]-- + +-- lpeg variant is not faster + +function utffilters.collapse(str) -- not really tested (we could preallocate a table) + if cf.collapsing and str then + if #str > 1 then + if not cf.initialized then -- saves a call + cf.initialize() + end + local tokens, first, done, n = { }, false, false, 0 + for second in utfcharacters(str) do + if done then + local crs = cr[second] + if crs then + if first then + tokens[#tokens+1] = first + end + first = crs + else + local cgf = graphemes[first] + if cgf and cgf[second] then + first = cgf[second] + elseif first then + tokens[#tokens+1] = first + first = second + else + first = second + end + end + else + local crs = cr[second] + if crs then + for s in utfcharacters(str) do + if n == 1 then + break + else + tokens[#tokens+1], n = s, n - 1 + end + end + if first then + tokens[#tokens+1] = first + end + first, done = crs, true + else + local cgf = graphemes[first] + if cgf and cgf[second] then + for s in utfcharacters(str) do + if n == 1 then + break + else + tokens[#tokens+1], n = s, n -1 + end + end + first, done = cgf[second], true + else + first, n = second, n + 1 + end + end + end + end + if done then + tokens[#tokens+1] = first + return concat(tokens) -- seldom called + end + elseif #str > 0 then + return cr[str] or str + end + end + return str +end + +--[[ldx-- +

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

+--ldx]]-- + +commands = commands or { } + +function commands.uchar(first,second) + tex.sprint(ctxcatcodes,utfchar(first*256+second)) +end + +--[[ldx-- +

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

+--ldx]]-- + +function utf.split(str) + local t = { } + for snippet in utfcharacters(str) do + t[#t+1] = snippet + end + return t +end + +function utf.each(str,fnc) + for snippet in utfcharacters(str) do + fnc(snippet) + end +end diff --git a/tex/context/base/char-utf.mkiv b/tex/context/base/char-utf.mkiv new file mode 100644 index 000000000..16b4029d8 --- /dev/null +++ b/tex/context/base/char-utf.mkiv @@ -0,0 +1,47 @@ +%D \module +%D [ file=char-utf, +%D version=2006.12.05, +%D title=\CONTEXT\ Character Support, +%D subtitle=Unicode UTF, +%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 / 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 +%D sequences). Writing the code was a relaxed experience, not in the +%D last place because it was accompanied by listening to those nice +%D Vienna Teng cd's (who decided that making music was more fun than +%D programming, but then, she may not know \TEX\ and \LUA). + +\unprotect + +\registerctxluafile{char-utf}{1.001} + +%D We enable collapsing (combining characters) by default, but +%D since the source files are rather simple, we postpone the +%D initialization till runtime. + +\appendtoks + \ctxlua { + characters.filters.utf.collapsing = true + resolvers.install_text_filter('utf',characters.filters.utf.collapse) + }% +\to \everyjob + +%D The next one influences input parsing. +%D +%D \starttyping +%D \definecomposedutf 318 108 126 % lcaron +%D \stoptyping + +\unexpanded\def\definecomposedutf#1 #2 #3 % + {\ctxlua{characters.filters.utf.add_grapheme("#1","#2","#3")}} + +\protect diff --git a/tex/context/base/chem-ini.lua b/tex/context/base/chem-ini.lua new file mode 100644 index 000000000..908749092 --- /dev/null +++ b/tex/context/base/chem-ini.lua @@ -0,0 +1,75 @@ +if not modules then modules = { } end modules ['chem-ini'] = { + version = 1.001, + comment = "companion to chem-ini.mkiv", + 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 lpegmatch = lpeg.match + +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 lpegmatch(parser,str) +end + +function commands.molecule(str) + if trace_molecules then + local rep = lpegmatch(parser,str) + logs.report("chemistry", "molecule %s => %s",str,rep) + texsprint(ctxcatcodes,rep) + else + texsprint(ctxcatcodes,lpegmatch(parser,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..5184fe1a7 --- /dev/null +++ b/tex/context/base/chem-ini.mkiv @@ -0,0 +1,47 @@ +%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)}} + +%D For old times sake: + +\def\chem#1#2#3% + {\dontleavehmode\begingroup#1\lohi{#2}{#3}\endgroup} + +\protect \endinput + + diff --git a/tex/context/base/chem-str.lua b/tex/context/base/chem-str.lua new file mode 100644 index 000000000..ad4cc6c1b --- /dev/null +++ b/tex/context/base/chem-str.lua @@ -0,0 +1,490 @@ +if not modules then modules = { } end modules ['chem-str'] = { + version = 1.001, + comment = "companion to chem-str.mkiv", + 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 lpegmatch = lpeg.match + +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", bd = "line", bw = "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[lower(name)] = nil +end + +function chemicals.define(name,spec,text) + name = lower(name) + 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 lpegmatch(chemicals.moleculeparser,...) + +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 = lpegmatch(pattern,"RZ1357") + +--~ print(lpegmatch(pattern,"RZ=x")) 1 RZ false false false x +--~ print(lpegmatch(pattern,"RZ1=x")) 1 RZ 1 false false x +--~ print(lpegmatch(pattern,"RZ1..3=x")) 1 RZ 1 3 false x +--~ print(lpegmatch(pattern,"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 = lpegmatch(pattern,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..1e17218c8 --- /dev/null +++ b/tex/context/base/chem-str.mkiv @@ -0,0 +1,529 @@ +%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 + +\unexpanded\def\setupchemical + {\dosingleempty\dosetupchemical} + +\def\dosetupchemical + {\getparameters[\??cm]} + +\let\setupchemicals\setupchemical + +\unexpanded\def\setupchemicalframed + {\dosingleempty\dosetupchemicalframed} + +\def\dosetupchemicalframed + {\getparameters[\??cm:\c!frame]} + +\def\chemicalparameter#1{\csname\??cm#1\endcsname} + +\unexpanded\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} + +\unexpanded\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 + +\def\dochemicaltext#1% + {\mathematics{\dosetchemicaltext\strut\ifcase\currentxfontsize\or\scriptstyle\or\scriptscriptstyle\fi#1}} + +\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 + +\unexpanded\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 } + +\unexpanded\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-ema.tex b/tex/context/base/colo-ema.tex new file mode 100644 index 000000000..e5e90b235 --- /dev/null +++ b/tex/context/base/colo-ema.tex @@ -0,0 +1,590 @@ +%D \module +%D [ file=colo-ema, +%D version=2003.03.20, +%D title=\CONTEXT\ Color Macros, +%D subtitle=Emacs Colors, +%D author=Peter Rolf, +%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. + +% author : Peter Rolf +% last change : 17 march 2003 +% origin : /emacs/etc/rgb.txt +% +% USAGE: +% +% - select emacs menu: Edit -> Text Properties -> Display +% Colors, if you don't know what I'm talking about +% - copy this file to your /texmf/tex/context/user directory +% and add "\input colo-emacs" to your tex-file +% +% IMPORTANT NOTES: +% +% - all color names are written as ONE word in lowercase +% letters (no redundancy as in rgb.txt) so if you want to +% use the color "Light Sky Blue"/"light sky blue" it's new +% name is lightskyblue +% - the grayX values [X=0..100] can only be used with \color +% [grayX] +% - use it at your own risk :) +% +% HINT: +% +% I only include this file (\showcolor [ema]) until I've +% found the colors I want. Copy and paste the color +% definitions to a seperate file, to decrease compilation +% time (540 color definitions). + +\definecolor [snow] [r=1,g=.980392,b=.980392] +\definecolor [ghostwhite] [r=.972549,g=.972549,b=1] +\definecolor [whitesmoke] [s=.960784] +\definecolor [gainsboro] [s=.862745] +\definecolor [floralwhite] [r=1,g=.980392,b=.941176] +\definecolor [oldlace] [r=.992157,g=.960784,b=.901961] +\definecolor [linen] [r=.980392,g=.941176,b=.901961] +\definecolor [antiquewhite] [r=.980392,g=.921569,b=.843137] +\definecolor [papayawhip] [r=1,g=.937255,b=.835294] +\definecolor [blanchedalmond] [r=1,g=.921569,b=.803922] +\definecolor [bisque] [r=1,g=.894118,b=.768627] +\definecolor [peachpuff] [r=1,g=.854902,b=.72549] +\definecolor [navajowhite] [r=1,g=.870588,b=.678431] +\definecolor [moccasin] [r=1,g=.894118,b=.709804] +\definecolor [cornsilk] [r=1,g=.972549,b=.862745] +\definecolor [ivory] [r=1,g=1,b=.941176] +\definecolor [lemonchiffon] [r=1,g=.980392,b=.803922] +\definecolor [seashell] [r=1,g=.960784,b=.933333] +\definecolor [honeydew] [r=.941176,g=1,b=.941176] +\definecolor [mintcream] [r=.960784,g=1,b=.980392] +\definecolor [azure] [r=.941176,g=1,b=1] +\definecolor [aliceblue] [r=.941176,g=.972549,b=1] +\definecolor [lavender] [r=.901961,g=.901961,b=.980392] +\definecolor [lavenderblush] [r=1,g=.941176,b=.960784] +\definecolor [mistyrose] [r=1,g=.894118,b=.882353] +%definecolor[white] [s=1] +%definecolor[black] [s=0] +\definecolor [darkslategray] [r=.184314,g=.309804,b=.309804] +\definecolor [dimgray] [s=.411765] +\definecolor [slategray] [r=.439216,g=.501961,b=.564706] +\definecolor [lightslategray] [r=.466667,g=.533333,b=.6] +\definecolor [gray] [s=.745098] +\definecolor [lightgray] [s=.827451] +\definecolor [midnightblue] [r=.098039,g=.098039,b=.439216] +\definecolor [navy] [b=.501961] +\definecolor [navyblue] [navy] +\definecolor [cornflowerblue] [r=.392157,g=.584314,b=.929412] +\definecolor [darkslateblue] [r=.282353,g=.239216,b=.545098] +\definecolor [slateblue] [r=.415686,g=.352941,b=.803922] +\definecolor [mediumslateblue] [r=.482353,g=.407843,b=.933333] +\definecolor [lightslateblue] [r=.517647,g=.439216,b=1] +\definecolor [mediumblue] [b=.803922] +\definecolor [royalblue] [r=.254902,g=.411765,b=.882353] +%definecolor[blue] [b=1] +\definecolor [dodgerblue] [r=.117647,g=.564706,b=1] +\definecolor [deepskyblue] [g=.74902,b=1] +\definecolor [skyblue] [r=.529412,g=.807843,b=.921569] +\definecolor [lightskyblue] [r=.529412,g=.807843,b=.980392] +\definecolor [steelblue] [r=.27451,g=.509804,b=.705882] +\definecolor [lightsteelblue] [r=.690196,g=.768627,b=.870588] +\definecolor [lightblue] [r=.678431,g=.847059,b=.901961] +\definecolor [powderblue] [r=.690196,g=.878431,b=.901961] +\definecolor [paleturquoise] [r=.686275,g=.933333,b=.933333] +\definecolor [darkturquoise] [g=.807843,b=.819608] +\definecolor [mediumturquoise] [r=.282353,g=.819608,b=.8] +\definecolor [turquoise] [r=.25098,g=.878431,b=.815686] +%definecolor[cyan] [g=1,b=1] +\definecolor [lightcyan] [r=.878431,g=1,b=1] +\definecolor [cadetblue] [r=.372549,g=.619608,b=.627451] +\definecolor [mediumaquamarine] [r=.4,g=.803922,b=.666667] +\definecolor [aquamarine] [r=.498039,g=1,b=.831373] +\definecolor [darkgreen] [g=.392157] +\definecolor [darkolivegreen] [r=.333333,g=.419608,b=.184314] +\definecolor [darkseagreen] [r=.560784,g=.737255,b=.560784] +\definecolor [seagreen] [r=.180392,g=.545098,b=.341176] +\definecolor [mediumseagreen] [r=.235294,g=.701961,b=.443137] +\definecolor [lightseagreen] [r=.12549,g=.698039,b=.666667] +\definecolor [palegreen] [r=.596078,g=.984314,b=.596078] +\definecolor [springgreen] [g=1,b=.498039] +\definecolor [lawngreen] [r=.486275,g=.988235] +%definecolor[green] [g=1] +\definecolor [chartreuse] [r=.498039,g=1] +\definecolor [mediumspringgreen] [g=.980392,b=.603922] +\definecolor [greenyellow] [r=.678431,g=1,b=.184314] +\definecolor [limegreen] [r=.196078,g=.803922,b=.196078] +\definecolor [yellowgreen] [r=.603922,g=.803922,b=.196078] +\definecolor [forestgreen] [r=.133333,g=.545098,b=.133333] +\definecolor [olivedrab] [r=.419608,g=.556863,b=.137255] +\definecolor [darkkhaki] [r=.741176,g=.717647,b=.419608] +\definecolor [khaki] [r=.941176,g=.901961,b=.54902] +\definecolor [palegoldenrod] [r=.933333,g=.909804,b=.666667] +\definecolor [lightgoldenrodyellow] [r=.980392,g=.980392,b=.823529] +\definecolor [lightyellow] [r=1,g=1,b=.878431] +%definecolor[yellow] [r=1,g=1] +\definecolor [gold] [r=1,g=.843137] +\definecolor [lightgoldenrod] [r=.933333,g=.866667,b=.509804] +\definecolor [goldenrod] [r=.854902,g=.647059,b=.12549] +\definecolor [darkgoldenrod] [r=.721569,g=.52549,b=.043137] +\definecolor [rosybrown] [r=.737255,g=.560784,b=.560784] +\definecolor [indianred] [r=.803922,g=.360784,b=.360784] +\definecolor [saddlebrown] [r=.545098,g=.270588,b=.07451] +\definecolor [sienna] [r=.627451,g=.321569,b=.176471] +\definecolor [peru] [r=.803922,g=.521569,b=.247059] +\definecolor [burlywood] [r=.870588,g=.721569,b=.529412] +\definecolor [beige] [r=.960784,g=.960784,b=.862745] +\definecolor [wheat] [r=.960784,g=.870588,b=.701961] +\definecolor [sandybrown] [r=.956863,g=.643137,b=.376471] +\definecolor [tan] [r=.823529,g=.705882,b=.54902] +\definecolor [chocolate] [r=.823529,g=.411765,b=.117647] +\definecolor [firebrick] [r=.698039,g=.133333,b=.133333] +\definecolor [brown] [r=.647059,g=.164706,b=.164706] +\definecolor [darksalmon] [r=.913725,g=.588235,b=.478431] +\definecolor [salmon] [r=.980392,g=.501961,b=.447059] +\definecolor [lightsalmon] [r=1,g=.627451,b=.478431] +\definecolor [orange] [r=1,g=.647059] +\definecolor [darkorange] [r=1,g=.54902] +\definecolor [coral] [r=1,g=.498039,b=.313725] +\definecolor [lightcoral] [r=.941176,g=.501961,b=.501961] +\definecolor [tomato] [r=1,g=.388235,b=.278431] +\definecolor [orangered] [r=1,g=.270588] +%definecolor[red] [r=1] +\definecolor [hotpink] [r=1,g=.411765,b=.705882] +\definecolor [deeppink] [r=1,g=.078431,b=.576471] +\definecolor [pink] [r=1,g=.752941,b=.796078] +\definecolor [lightpink] [r=1,g=.713725,b=.756863] +\definecolor [palevioletred] [r=.858824,g=.439216,b=.576471] +\definecolor [maroon] [r=.690196,g=.188235,b=.376471] +\definecolor [mediumvioletred] [r=.780392,g=.082353,b=.521569] +\definecolor [violetred] [r=.815686,g=.12549,b=.564706] +%definecolor[magenta] [r=1,b=1] +\definecolor [violet] [r=.933333,g=.509804,b=.933333] +\definecolor [plum] [r=.866667,g=.627451,b=.866667] +\definecolor [orchid] [r=.854902,g=.439216,b=.839216] +\definecolor [mediumorchid] [r=.729412,g=.333333,b=.827451] +\definecolor [darkorchid] [r=.6,g=.196078,b=.8] +\definecolor [darkviolet] [r=.580392,b=.827451] +\definecolor [blueviolet] [r=.541176,g=.168627,b=.886275] +\definecolor [purple] [r=.627451,g=.12549,b=.941176] +\definecolor [mediumpurple] [r=.576471,g=.439216,b=.858824] +\definecolor [thistle] [r=.847059,g=.74902,b=.847059] +\definecolor [snow1] [r=1,g=.980392,b=.980392] +\definecolor [snow2] [r=.933333,g=.913725,b=.913725] +\definecolor [snow3] [r=.803922,g=.788235,b=.788235] +\definecolor [snow4] [r=.545098,g=.537255,b=.537255] +\definecolor [seashell1] [r=1,g=.960784,b=.933333] +\definecolor [seashell2] [r=.933333,g=.898039,b=.870588] +\definecolor [seashell3] [r=.803922,g=.772549,b=.74902] +\definecolor [seashell4] [r=.545098,g=.52549,b=.509804] +\definecolor [antiquewhite1] [r=1,g=.937255,b=.858824] +\definecolor [antiquewhite2] [r=.933333,g=.87451,b=.8] +\definecolor [antiquewhite3] [r=.803922,g=.752941,b=.690196] +\definecolor [antiquewhite4] [r=.545098,g=.513725,b=.470588] +\definecolor [bisque1] [r=1,g=.894118,b=.768627] +\definecolor [bisque2] [r=.933333,g=.835294,b=.717647] +\definecolor [bisque3] [r=.803922,g=.717647,b=.619608] +\definecolor [bisque4] [r=.545098,g=.490196,b=.419608] +\definecolor [peachpuff1] [r=1,g=.854902,b=.72549] +\definecolor [peachpuff2] [r=.933333,g=.796078,b=.678431] +\definecolor [peachpuff3] [r=.803922,g=.686275,b=.584314] +\definecolor [peachpuff4] [r=.545098,g=.466667,b=.396078] +\definecolor [navajowhite1] [r=1,g=.870588,b=.678431] +\definecolor [navajowhite2] [r=.933333,g=.811765,b=.631373] +\definecolor [navajowhite3] [r=.803922,g=.701961,b=.545098] +\definecolor [navajowhite4] [r=.545098,g=.47451,b=.368627] +\definecolor [lemonchiffon1] [r=1,g=.980392,b=.803922] +\definecolor [lemonchiffon2] [r=.933333,g=.913725,b=.74902] +\definecolor [lemonchiffon3] [r=.803922,g=.788235,b=.647059] +\definecolor [lemonchiffon4] [r=.545098,g=.537255,b=.439216] +\definecolor [cornsilk1] [r=1,g=.972549,b=.862745] +\definecolor [cornsilk2] [r=.933333,g=.909804,b=.803922] +\definecolor [cornsilk3] [r=.803922,g=.784314,b=.694118] +\definecolor [cornsilk4] [r=.545098,g=.533333,b=.470588] +\definecolor [ivory1] [r=1,g=1,b=.941176] +\definecolor [ivory2] [r=.933333,g=.933333,b=.878431] +\definecolor [ivory3] [r=.803922,g=.803922,b=.756863] +\definecolor [ivory4] [r=.545098,g=.545098,b=.513725] +\definecolor [honeydew1] [r=.941176,g=1,b=.941176] +\definecolor [honeydew2] [r=.878431,g=.933333,b=.878431] +\definecolor [honeydew3] [r=.756863,g=.803922,b=.756863] +\definecolor [honeydew4] [r=.513725,g=.545098,b=.513725] +\definecolor [lavenderblush1] [r=1,g=.941176,b=.960784] +\definecolor [lavenderblush2] [r=.933333,g=.878431,b=.898039] +\definecolor [lavenderblush3] [r=.803922,g=.756863,b=.772549] +\definecolor [lavenderblush4] [r=.545098,g=.513725,b=.52549] +\definecolor [mistyrose1] [r=1,g=.894118,b=.882353] +\definecolor [mistyrose2] [r=.933333,g=.835294,b=.823529] +\definecolor [mistyrose3] [r=.803922,g=.717647,b=.709804] +\definecolor [mistyrose4] [r=.545098,g=.490196,b=.482353] +\definecolor [azure1] [r=.941176,g=1,b=1] +\definecolor [azure2] [r=.878431,g=.933333,b=.933333] +\definecolor [azure3] [r=.756863,g=.803922,b=.803922] +\definecolor [azure4] [r=.513725,g=.545098,b=.545098] +\definecolor [slateblue1] [r=.513725,g=.435294,b=1] +\definecolor [slateblue2] [r=.478431,g=.403922,b=.933333] +\definecolor [slateblue3] [r=.411765,g=.34902,b=.803922] +\definecolor [slateblue4] [r=.278431,g=.235294,b=.545098] +\definecolor [royalblue1] [r=.282353,g=.462745,b=1] +\definecolor [royalblue2] [r=.262745,g=.431373,b=.933333] +\definecolor [royalblue3] [r=.227451,g=.372549,b=.803922] +\definecolor [royalblue4] [r=.152941,g=.25098,b=.545098] +\definecolor [blue1] [blue] +\definecolor [blue2] [b=.933333] +\definecolor [blue3] [b=.803922] +\definecolor [blue4] [b=.545098] +\definecolor [dodgerblue1] [r=.117647,g=.564706,b=1] +\definecolor [dodgerblue2] [r=.109804,g=.52549,b=.933333] +\definecolor [dodgerblue3] [r=.094118,g=.454902,b=.803922] +\definecolor [dodgerblue4] [r=.062745,g=.305882,b=.545098] +\definecolor [steelblue1] [r=.388235,g=.721569,b=1] +\definecolor [steelblue2] [r=.360784,g=.67451,b=.933333] +\definecolor [steelblue3] [r=.309804,g=.580392,b=.803922] +\definecolor [steelblue4] [r=.211765,g=.392157,b=.545098] +\definecolor [deepskyblue1] [g=.74902,b=1] +\definecolor [deepskyblue2] [g=.698039,b=.933333] +\definecolor [deepskyblue3] [g=.603922,b=.803922] +\definecolor [deepskyblue4] [g=.407843,b=.545098] +\definecolor [skyblue1] [r=.529412,g=.807843,b=1] +\definecolor [skyblue2] [r=.494118,g=.752941,b=.933333] +\definecolor [skyblue3] [r=.423529,g=.65098,b=.803922] +\definecolor [skyblue4] [r=.290196,g=.439216,b=.545098] +\definecolor [lightskyblue1] [r=.690196,g=.886275,b=1] +\definecolor [lightskyblue2] [r=.643137,g=.827451,b=.933333] +\definecolor [lightskyblue3] [r=.552941,g=.713725,b=.803922] +\definecolor [lightskyblue4] [r=.376471,g=.482353,b=.545098] +\definecolor [slategray1] [r=.776471,g=.886275,b=1] +\definecolor [slategray2] [r=.72549,g=.827451,b=.933333] +\definecolor [slategray3] [r=.623529,g=.713725,b=.803922] +\definecolor [slategray4] [r=.423529,g=.482353,b=.545098] +\definecolor [lightsteelblue1] [r=.792157,g=.882353,b=1] +\definecolor [lightsteelblue2] [r=.737255,g=.823529,b=.933333] +\definecolor [lightsteelblue3] [r=.635294,g=.709804,b=.803922] +\definecolor [lightsteelblue4] [r=.431373,g=.482353,b=.545098] +\definecolor [lightblue1] [r=.74902,g=.937255,b=1] +\definecolor [lightblue2] [r=.698039,g=.87451,b=.933333] +\definecolor [lightblue3] [r=.603922,g=.752941,b=.803922] +\definecolor [lightblue4] [r=.407843,g=.513725,b=.545098] +\definecolor [lightcyan1] [r=.878431,g=1,b=1] +\definecolor [lightcyan2] [r=.819608,g=.933333,b=.933333] +\definecolor [lightcyan3] [r=.705882,g=.803922,b=.803922] +\definecolor [lightcyan4] [r=.478431,g=.545098,b=.545098] +\definecolor [paleturquoise1] [r=.733333,g=1,b=1] +\definecolor [paleturquoise2] [r=.682353,g=.933333,b=.933333] +\definecolor [paleturquoise3] [r=.588235,g=.803922,b=.803922] +\definecolor [paleturquoise4] [r=.4,g=.545098,b=.545098] +\definecolor [cadetblue1] [r=.596078,g=.960784,b=1] +\definecolor [cadetblue2] [r=.556863,g=.898039,b=.933333] +\definecolor [cadetblue3] [r=.478431,g=.772549,b=.803922] +\definecolor [cadetblue4] [r=.32549,g=.52549,b=.545098] +\definecolor [turquoise1] [g=.960784,b=1] +\definecolor [turquoise2] [g=.898039,b=.933333] +\definecolor [turquoise3] [g=.772549,b=.803922] +\definecolor [turquoise4] [g=.52549,b=.545098] +\definecolor [cyan1] [cyan] +\definecolor [cyan2] [g=.933333,b=.933333] +\definecolor [cyan3] [g=.803922,b=.803922] +\definecolor [cyan4] [g=.545098,b=.545098] +\definecolor [darkslategray1] [r=.592157,g=1,b=1] +\definecolor [darkslategray2] [r=.552941,g=.933333,b=.933333] +\definecolor [darkslategray3] [r=.47451,g=.803922,b=.803922] +\definecolor [darkslategray4] [r=.321569,g=.545098,b=.545098] +\definecolor [aquamarine1] [r=.498039,g=1,b=.831373] +\definecolor [aquamarine2] [r=.462745,g=.933333,b=.776471] +\definecolor [aquamarine3] [r=.4,g=.803922,b=.666667] +\definecolor [aquamarine4] [r=.270588,g=.545098,b=.454902] +\definecolor [darkseagreen1] [r=.756863,g=1,b=.756863] +\definecolor [darkseagreen2] [r=.705882,g=.933333,b=.705882] +\definecolor [darkseagreen3] [r=.607843,g=.803922,b=.607843] +\definecolor [darkseagreen4] [r=.411765,g=.545098,b=.411765] +\definecolor [seagreen1] [r=.329412,g=1,b=.623529] +\definecolor [seagreen2] [r=.305882,g=.933333,b=.580392] +\definecolor [seagreen3] [r=.262745,g=.803922,b=.501961] +\definecolor [seagreen4] [r=.180392,g=.545098,b=.341176] +\definecolor [palegreen1] [r=.603922,g=1,b=.603922] +\definecolor [palegreen2] [r=.564706,g=.933333,b=.564706] +\definecolor [palegreen3] [r=.486275,g=.803922,b=.486275] +\definecolor [palegreen4] [r=.329412,g=.545098,b=.329412] +\definecolor [springgreen1] [g=1,b=.498039] +\definecolor [springgreen2] [g=.933333,b=.462745] +\definecolor [springgreen3] [g=.803922,b=.4] +\definecolor [springgreen4] [g=.545098,b=.270588] +\definecolor [green1] [green] +\definecolor [green2] [g=.933333] +\definecolor [green3] [g=.803922] +\definecolor [green4] [g=.545098] +\definecolor [chartreuse1] [r=.498039,g=1] +\definecolor [chartreuse2] [r=.462745,g=.933333] +\definecolor [chartreuse3] [r=.4,g=.803922] +\definecolor [chartreuse4] [r=.270588,g=.545098] +\definecolor [olivedrab1] [r=.752941,g=1,b=.243137] +\definecolor [olivedrab2] [r=.701961,g=.933333,b=.227451] +\definecolor [olivedrab3] [r=.603922,g=.803922,b=.196078] +\definecolor [olivedrab4] [r=.411765,g=.545098,b=.133333] +\definecolor [darkolivegreen1] [r=.792157,g=1,b=.439216] +\definecolor [darkolivegreen2] [r=.737255,g=.933333,b=.407843] +\definecolor [darkolivegreen3] [r=.635294,g=.803922,b=.352941] +\definecolor [darkolivegreen4] [r=.431373,g=.545098,b=.239216] +\definecolor [khaki1] [r=1,g=.964706,b=.560784] +\definecolor [khaki2] [r=.933333,g=.901961,b=.521569] +\definecolor [khaki3] [r=.803922,g=.776471,b=.45098] +\definecolor [khaki4] [r=.545098,g=.52549,b=.305882] +\definecolor [lightgoldenrod1] [r=1,g=.92549,b=.545098] +\definecolor [lightgoldenrod2] [r=.933333,g=.862745,b=.509804] +\definecolor [lightgoldenrod3] [r=.803922,g=.745098,b=.439216] +\definecolor [lightgoldenrod4] [r=.545098,g=.505882,b=.298039] +\definecolor [lightyellow1] [r=1,g=1,b=.878431] +\definecolor [lightyellow2] [r=.933333,g=.933333,b=.819608] +\definecolor [lightyellow3] [r=.803922,g=.803922,b=.705882] +\definecolor [lightyellow4] [r=.545098,g=.545098,b=.478431] +\definecolor [yellow1] [yellow] +\definecolor [yellow2] [r=.933333,g=.933333] +\definecolor [yellow3] [r=.803922,g=.803922] +\definecolor [yellow4] [r=.545098,g=.545098] +\definecolor [gold1] [r=1,g=.843137] +\definecolor [gold2] [r=.933333,g=.788235] +\definecolor [gold3] [r=.803922,g=.678431] +\definecolor [gold4] [r=.545098,g=.458824] +\definecolor [goldenrod1] [r=1,g=.756863,b=.145098] +\definecolor [goldenrod2] [r=.933333,g=.705882,b=.133333] +\definecolor [goldenrod3] [r=.803922,g=.607843,b=.113725] +\definecolor [goldenrod4] [r=.545098,g=.411765,b=.078431] +\definecolor [darkgoldenrod1] [r=1,g=.72549,b=.058824] +\definecolor [darkgoldenrod2] [r=.933333,g=.678431,b=.054902] +\definecolor [darkgoldenrod3] [r=.803922,g=.584314,b=.047059] +\definecolor [darkgoldenrod4] [r=.545098,g=.396078,b=.031373] +\definecolor [rosybrown1] [r=1,g=.756863,b=.756863] +\definecolor [rosybrown2] [r=.933333,g=.705882,b=.705882] +\definecolor [rosybrown3] [r=.803922,g=.607843,b=.607843] +\definecolor [rosybrown4] [r=.545098,g=.411765,b=.411765] +\definecolor [indianred1] [r=1,g=.415686,b=.415686] +\definecolor [indianred2] [r=.933333,g=.388235,b=.388235] +\definecolor [indianred3] [r=.803922,g=.333333,b=.333333] +\definecolor [indianred4] [r=.545098,g=.227451,b=.227451] +\definecolor [sienna1] [r=1,g=.509804,b=.278431] +\definecolor [sienna2] [r=.933333,g=.47451,b=.258824] +\definecolor [sienna3] [r=.803922,g=.407843,b=.223529] +\definecolor [sienna4] [r=.545098,g=.278431,b=.14902] +\definecolor [burlywood1] [r=1,g=.827451,b=.607843] +\definecolor [burlywood2] [r=.933333,g=.772549,b=.568627] +\definecolor [burlywood3] [r=.803922,g=.666667,b=.490196] +\definecolor [burlywood4] [r=.545098,g=.45098,b=.333333] +\definecolor [wheat1] [r=1,g=.905882,b=.729412] +\definecolor [wheat2] [r=.933333,g=.847059,b=.682353] +\definecolor [wheat3] [r=.803922,g=.729412,b=.588235] +\definecolor [wheat4] [r=.545098,g=.494118,b=.4] +\definecolor [tan1] [r=1,g=.647059,b=.309804] +\definecolor [tan2] [r=.933333,g=.603922,b=.286275] +\definecolor [tan3] [r=.803922,g=.521569,b=.247059] +\definecolor [tan4] [r=.545098,g=.352941,b=.168627] +\definecolor [chocolate1] [r=1,g=.498039,b=.141176] +\definecolor [chocolate2] [r=.933333,g=.462745,b=.129412] +\definecolor [chocolate3] [r=.803922,g=.4,b=.113725] +\definecolor [chocolate4] [r=.545098,g=.270588,b=.07451] +\definecolor [firebrick1] [r=1,g=.188235,b=.188235] +\definecolor [firebrick2] [r=.933333,g=.172549,b=.172549] +\definecolor [firebrick3] [r=.803922,g=.14902,b=.14902] +\definecolor [firebrick4] [r=.545098,g=.101961,b=.101961] +\definecolor [brown1] [r=1,g=.25098,b=.25098] +\definecolor [brown2] [r=.933333,g=.231373,b=.231373] +\definecolor [brown3] [r=.803922,g=.2,b=.2] +\definecolor [brown4] [r=.545098,g=.137255,b=.137255] +\definecolor [salmon1] [r=1,g=.54902,b=.411765] +\definecolor [salmon2] [r=.933333,g=.509804,b=.384314] +\definecolor [salmon3] [r=.803922,g=.439216,b=.329412] +\definecolor [salmon4] [r=.545098,g=.298039,b=.223529] +\definecolor [lightsalmon1] [r=1,g=.627451,b=.478431] +\definecolor [lightsalmon2] [r=.933333,g=.584314,b=.447059] +\definecolor [lightsalmon3] [r=.803922,g=.505882,b=.384314] +\definecolor [lightsalmon4] [r=.545098,g=.341176,b=.258824] +\definecolor [orange1] [r=1,g=.647059] +\definecolor [orange2] [r=.933333,g=.603922] +\definecolor [orange3] [r=.803922,g=.521569] +\definecolor [orange4] [r=.545098,g=.352941] +\definecolor [darkorange1] [r=1,g=.498039] +\definecolor [darkorange2] [r=.933333,g=.462745] +\definecolor [darkorange3] [r=.803922,g=.4] +\definecolor [darkorange4] [r=.545098,g=.270588] +\definecolor [coral1] [r=1,g=.447059,b=.337255] +\definecolor [coral2] [r=.933333,g=.415686,b=.313725] +\definecolor [coral3] [r=.803922,g=.356863,b=.270588] +\definecolor [coral4] [r=.545098,g=.243137,b=.184314] +\definecolor [tomato1] [r=1,g=.388235,b=.278431] +\definecolor [tomato2] [r=.933333,g=.360784,b=.258824] +\definecolor [tomato3] [r=.803922,g=.309804,b=.223529] +\definecolor [tomato4] [r=.545098,g=.211765,b=.14902] +\definecolor [orangered1] [r=1,g=.270588] +\definecolor [orangered2] [r=.933333,g=.25098] +\definecolor [orangered3] [r=.803922,g=.215686] +\definecolor [orangered4] [r=.545098,g=.145098] +\definecolor [red1] [red] +\definecolor [red2] [r=.933333] +\definecolor [red3] [r=.803922] +\definecolor [red4] [r=.545098] +\definecolor [deeppink1] [r=1,g=.078431,b=.576471] +\definecolor [deeppink2] [r=.933333,g=.070588,b=.537255] +\definecolor [deeppink3] [r=.803922,g=.062745,b=.462745] +\definecolor [deeppink4] [r=.545098,g=.039216,b=.313725] +\definecolor [hotpink1] [r=1,g=.431373,b=.705882] +\definecolor [hotpink2] [r=.933333,g=.415686,b=.654902] +\definecolor [hotpink3] [r=.803922,g=.376471,b=.564706] +\definecolor [hotpink4] [r=.545098,g=.227451,b=.384314] +\definecolor [pink1] [r=1,g=.709804,b=.772549] +\definecolor [pink2] [r=.933333,g=.662745,b=.721569] +\definecolor [pink3] [r=.803922,g=.568627,b=.619608] +\definecolor [pink4] [r=.545098,g=.388235,b=.423529] +\definecolor [lightpink1] [r=1,g=.682353,b=.72549] +\definecolor [lightpink2] [r=.933333,g=.635294,b=.678431] +\definecolor [lightpink3] [r=.803922,g=.54902,b=.584314] +\definecolor [lightpink4] [r=.545098,g=.372549,b=.396078] +\definecolor [palevioletred1] [r=1,g=.509804,b=.670588] +\definecolor [palevioletred2] [r=.933333,g=.47451,b=.623529] +\definecolor [palevioletred3] [r=.803922,g=.407843,b=.537255] +\definecolor [palevioletred4] [r=.545098,g=.278431,b=.364706] +\definecolor [maroon1] [r=1,g=.203922,b=.701961] +\definecolor [maroon2] [r=.933333,g=.188235,b=.654902] +\definecolor [maroon3] [r=.803922,g=.160784,b=.564706] +\definecolor [maroon4] [r=.545098,g=.109804,b=.384314] +\definecolor [violetred1] [r=1,g=.243137,b=.588235] +\definecolor [violetred2] [r=.933333,g=.227451,b=.54902] +\definecolor [violetred3] [r=.803922,g=.196078,b=.470588] +\definecolor [violetred4] [r=.545098,g=.133333,b=.321569] +\definecolor [magenta1] [magenta] +\definecolor [magenta2] [r=.933333,b=.933333] +\definecolor [magenta3] [r=.803922,b=.803922] +\definecolor [magenta4] [r=.545098,b=.545098] +\definecolor [orchid1] [r=1,g=.513725,b=.980392] +\definecolor [orchid2] [r=.933333,g=.478431,b=.913725] +\definecolor [orchid3] [r=.803922,g=.411765,b=.788235] +\definecolor [orchid4] [r=.545098,g=.278431,b=.537255] +\definecolor [plum1] [r=1,g=.733333,b=1] +\definecolor [plum2] [r=.933333,g=.682353,b=.933333] +\definecolor [plum3] [r=.803922,g=.588235,b=.803922] +\definecolor [plum4] [r=.545098,g=.4,b=.545098] +\definecolor [mediumorchid1] [r=.878431,g=.4,b=1] +\definecolor [mediumorchid2] [r=.819608,g=.372549,b=.933333] +\definecolor [mediumorchid3] [r=.705882,g=.321569,b=.803922] +\definecolor [mediumorchid4] [r=.478431,g=.215686,b=.545098] +\definecolor [darkorchid1] [r=.74902,g=.243137,b=1] +\definecolor [darkorchid2] [r=.698039,g=.227451,b=.933333] +\definecolor [darkorchid3] [r=.603922,g=.196078,b=.803922] +\definecolor [darkorchid4] [r=.407843,g=.133333,b=.545098] +\definecolor [purple1] [r=.607843,g=.188235,b=1] +\definecolor [purple2] [r=.568627,g=.172549,b=.933333] +\definecolor [purple3] [r=.490196,g=.14902,b=.803922] +\definecolor [purple4] [r=.333333,g=.101961,b=.545098] +\definecolor [mediumpurple1] [r=.670588,g=.509804,b=1] +\definecolor [mediumpurple2] [r=.623529,g=.47451,b=.933333] +\definecolor [mediumpurple3] [r=.537255,g=.407843,b=.803922] +\definecolor [mediumpurple4] [r=.364706,g=.278431,b=.545098] +\definecolor [thistle1] [r=1,g=.882353,b=1] +\definecolor [thistle2] [r=.933333,g=.823529,b=.933333] +\definecolor [thistle3] [r=.803922,g=.709804,b=.803922] +\definecolor [thistle4] [r=.545098,g=.482353,b=.545098] +\definecolor [gray0] [black] +\definecolor [gray1] [s=.01] +\definecolor [gray2] [s=.02] +\definecolor [gray3] [s=.03] +\definecolor [gray4] [s=.04] +\definecolor [gray5] [s=.05] +\definecolor [gray6] [s=.06] +\definecolor [gray7] [s=.07] +\definecolor [gray8] [s=.08] +\definecolor [gray9] [s=.09] +\definecolor [gray10] [s=.1] +\definecolor [gray11] [s=.11] +\definecolor [gray12] [s=.12] +\definecolor [gray13] [s=.13] +\definecolor [gray14] [s=.14] +\definecolor [gray15] [s=.15] +\definecolor [gray16] [s=.16] +\definecolor [gray17] [s=.17] +\definecolor [gray18] [s=.18] +\definecolor [gray19] [s=.19] +\definecolor [gray20] [s=.2] +\definecolor [gray21] [s=.21] +\definecolor [gray22] [s=.22] +\definecolor [gray23] [s=.23] +\definecolor [gray24] [s=.24] +\definecolor [gray25] [s=.25] +\definecolor [gray26] [s=.26] +\definecolor [gray27] [s=.27] +\definecolor [gray28] [s=.28] +\definecolor [gray29] [s=.29] +\definecolor [gray30] [s=.3] +\definecolor [gray31] [s=.31] +\definecolor [gray32] [s=.32] +\definecolor [gray33] [s=.33] +\definecolor [gray34] [s=.34] +\definecolor [gray35] [s=.35] +\definecolor [gray36] [s=.36] +\definecolor [gray37] [s=.37] +\definecolor [gray38] [s=.38] +\definecolor [gray39] [s=.39] +\definecolor [gray40] [s=.4] +\definecolor [gray41] [s=.41] +\definecolor [gray42] [s=.42] +\definecolor [gray43] [s=.43] +\definecolor [gray44] [s=.44] +\definecolor [gray45] [s=.45] +\definecolor [gray46] [s=.46] +\definecolor [gray47] [s=.47] +\definecolor [gray48] [s=.48] +\definecolor [gray49] [s=.49] +\definecolor [gray50] [s=.5] +\definecolor [gray51] [s=.51] +\definecolor [gray52] [s=.52] +\definecolor [gray53] [s=.53] +\definecolor [gray54] [s=.54] +\definecolor [gray55] [s=.55] +\definecolor [gray56] [s=.56] +\definecolor [gray57] [s=.57] +\definecolor [gray58] [s=.58] +\definecolor [gray59] [s=.59] +\definecolor [gray60] [s=.6] +\definecolor [gray61] [s=.61] +\definecolor [gray62] [s=.62] +\definecolor [gray63] [s=.63] +\definecolor [gray64] [s=.64] +\definecolor [gray65] [s=.65] +\definecolor [gray66] [s=.66] +\definecolor [gray67] [s=.67] +\definecolor [gray68] [s=.68] +\definecolor [gray69] [s=.69] +\definecolor [gray70] [s=.7] +\definecolor [gray71] [s=.71] +\definecolor [gray72] [s=.72] +\definecolor [gray73] [s=.73] +\definecolor [gray74] [s=.74] +\definecolor [gray75] [s=.75] +\definecolor [gray76] [s=.76] +\definecolor [gray77] [s=.77] +\definecolor [gray78] [s=.78] +\definecolor [gray79] [s=.79] +\definecolor [gray80] [s=.8] +\definecolor [gray81] [s=.81] +\definecolor [gray82] [s=.82] +\definecolor [gray83] [s=.83] +\definecolor [gray84] [s=.84] +\definecolor [gray85] [s=.85] +\definecolor [gray86] [s=.86] +\definecolor [gray87] [s=.87] +\definecolor [gray88] [s=.88] +\definecolor [gray89] [s=.89] +\definecolor [gray90] [s=.9] +\definecolor [gray91] [s=.91] +\definecolor [gray92] [s=.92] +\definecolor [gray93] [s=.93] +\definecolor [gray94] [s=.94] +\definecolor [gray95] [s=.95] +\definecolor [gray96] [s=.96] +\definecolor [gray97] [s=.97] +\definecolor [gray98] [s=.98] +\definecolor [gray99] [s=.99] +\definecolor [gray100] [white] +\definecolor [darkgray] [s=.662745] +\definecolor [darkblue] [b=.545098] +\definecolor [darkcyan] [g=.545098,b=.545098] +\definecolor [darkmagenta] [r=.545098,b=.545098] +\definecolor [darkred] [r=.545098] +\definecolor [lightgreen] [r=.564706,g=.933333,b=.564706] diff --git a/tex/context/base/colo-ext.mkii b/tex/context/base/colo-ext.mkii new file mode 100644 index 000000000..473c010e0 --- /dev/null +++ b/tex/context/base/colo-ext.mkii @@ -0,0 +1,59 @@ +%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!intent=\v!none] + +\def\starttextoverprint + {\doifelse\@@clintent\v!overprint + {\glet\stoptextoverprint \dostopoverprint + \glet\starttextoverprint\dostartoverprint + \dostartoverprint} + {\glet\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..b17608f59 --- /dev/null +++ b/tex/context/base/colo-ext.mkiv @@ -0,0 +1,103 @@ +%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 + {\startnegativeproperty % might change + \startcolor[white]\vrule\!!height\ht#1\!!depth\dp#1\!!width\wd#1\stopcolor + \hskip-\wd#1% + \box#1% + \stopnegativeproperty}} + +%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. + +\unexpanded\def\startcolorintent[#1]% + {\pushattribute\colorintentattribute + \dotriggercolorintent{#1}} + +\unexpanded\def\stopcolorintent + {\popattribute\colorintentattribute} + +\unexpanded\def\startoverprint{\startcolorintent[\v!overprint]} +\unexpanded\def\stopoverprint {\stopcolorintent} + +\unexpanded\def\startknockout {\startcolorintent[\v!knockout ]} +\unexpanded\def\stopknockout {\stopcolorintent} + +\let\starttextcolorintent\relax +\let\stoptextcolorintent \relax + +\setupcolors + [\c!overprint=\v!no] + +\appendtoks + \dosettextcolorintent +\to \everysetupcolors + +\def\dosettextcolorintent + {\doifnot\@@clintent\v!none + {\xdef\starttextcolorintent{\noexpand\dotriggercolorintent{\@@clintent}}% + \glet\dosettextcolorintent\relax + \dotriggercolorintent\@@clintent}} + +\appendtoks \starttextcolorintent \to \everystarttextproperties +\appendtoks \stoptextcolorintent \to \everystoptextproperties + +\setupcolors[\c!intent=\v!none] + +% A goodie that replaces the startMPcolor hackery +% +% \definecolor[red-t] [r=1,t=0.5,a=1] +% \definecolor[green-t][g=1,t=0.5,a=1] +% \defineintermediatecolor[mycolora][0.5,red,green] +% \defineintermediatecolor[mycolorb][0.5,red-t,green-t] +% \starttext +% test {\mycolora OEPS} test +% test {\mycolorb OEPS} test +% \stoptext + +\unexpanded\def\defineintermediatecolor + {\dotripleempty\dodefineintermediatecolor} + +\def\dodefineintermediatecolor[#1][#2][#3]% \dotripleempty adds {} inside [] + {\dododefineintermediatecolor[#1][#2][#3]} + +\def\dododefineintermediatecolor[#1][#2,#3,#4][#5]% + {\ifconditional\collectcolorsinlist\collectcolorinlist{#1}\fi + \ctxlua{colors.defineintermediatecolor("#1","#2", + \thecolorattribute{#3},\thecolorattribute{#4}, + \thetransparencyattribute{#3},\thetransparencyattribute{#4}, + "#5",false,\iffreezecolors true\else false\fi)}% not global + \dodefinecolorcommand\setvalue{#1}} + +\protect \endinput diff --git a/tex/context/base/colo-hex.mkii b/tex/context/base/colo-hex.mkii new file mode 100644 index 000000000..db67f1841 --- /dev/null +++ b/tex/context/base/colo-hex.mkii @@ -0,0 +1,125 @@ +%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. + +\ifdefined \hexcolorprefix + \expandafter \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 + +% \definecolor[rgbtestcolor] [r=0.87843,g=0.87451,b=0.89020] % RGB(224,223,227) +% \definecolor[hextestcolor] [h=E0DFE3] +% +% \startMPpage +% path p ; % example by Peter Rolf +% p := unitsquare xyscaled(5cm,5cm) ; +% fill (point 0 of p -- point 1 of p -- point 2 of p --cycle) withcolor \MPcolor{rgbtestcolor} ; % bottom right part of the square +% fill (point 0 of p -- point 3 of p -- point 2 of p --cycle) withcolor \MPcolor{hextestcolor} ; % top left part +% \stopMPpage + +\newdimen\hexcolorfraction \hexcolorfraction=\dimexpr1pt/255\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\relax + \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\dimexpr255\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..f661b2445 --- /dev/null +++ b/tex/context/base/colo-hex.mkiv @@ -0,0 +1,28 @@ +%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 This is built in. + +% \definecolor[rgbtestcolor] [r=0.87843,g=0.87451,b=0.89020] % RGB(224,223,227) +% \definecolor[hextestcolor] [\letterhash E0DFE3] % or [h=E0DFE3] +% +% \startMPpage +% path p ; % example by Peter Rolf +% p := unitsquare xyscaled(5cm,5cm) ; +% fill (point 0 of p -- point 1 of p -- point 2 of p --cycle) withcolor \MPcolor{rgbtestcolor} ; % bottom right part of the square +% fill (point 0 of p -- point 3 of p -- point 2 of p --cycle) withcolor \MPcolor{hextestcolor} ; % top left part +% \stopMPpage + +\def\checkhexcolor[#1]{\doifcolorelse{#1}\donothing{\definecolor[#1][x=#1]}} % is this ok? + +\endinput diff --git a/tex/context/base/colo-hex.tex b/tex/context/base/colo-hex.tex new file mode 100644 index 000000000..7d223c131 --- /dev/null +++ b/tex/context/base/colo-hex.tex @@ -0,0 +1,3 @@ +% this is just a stub + +\loadmarkfile{colo-hex} diff --git a/tex/context/base/colo-ini.lua b/tex/context/base/colo-ini.lua new file mode 100644 index 000000000..342d6110d --- /dev/null +++ b/tex/context/base/colo-ini.lua @@ -0,0 +1,480 @@ +if not modules then modules = { } end modules ['colo-ini'] = { + version = 1.000, + comment = "companion to colo-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local type = type +local concat = table.concat +local format, gmatch, gsub, lower, match, find = string.format, string.gmatch, string.gsub, string.lower, string.match, string.find +local texsprint = tex.sprint +local ctxcatcodes = tex.ctxcatcodes + +local trace_define = false trackers.register("colors.define",function(v) trace_define = v end) + +local settings_to_hash_strict = aux.settings_to_hash_strict + +colors = colors or { } +transparencies = transparencies or { } + +local registrations = backends.registrations + +local a_color = attributes.private('color') +local a_transparency = attributes.private('transparency') +local a_colorspace = attributes.private('colormodel') +local a_background = attributes.private('background') + +local register_color = colors.register +local attributes_list = attributes.list + +local function definecolor(name, ca, global) + if ca and ca > 0 then + if global then + if trace_define then + commands.writestatus("color","define global color '%s' with attribute: %s",name,ca) + end + context.colordefagc(name,ca) + else + if trace_define then + commands.writestatus("color","define local color '%s' with attribute: %s",name,ca) + end + context.colordefalc(name,ca) + end + else + if global then + context.colordefrgc(name) + else + context.colordefrlc(name) + end + end +end + +local function inheritcolor(name, ca, global) + if ca and ca ~= "" then + if global then + if trace_define then + commands.writestatus("color","inherit global color '%s' with attribute: %s",name,ca) + end + context.colordeffgc(name,ca) + else + if trace_define then + commands.writestatus("color","inherit local color '%s' with attribute: %s",name,ca) + end + context.colordefflc(name,ca) + end + else + if global then + context.colordefrgc(name) + else + context.colordefrlc(name) + end + end +end + +local function definetransparent(name, ta, global) + if ta and ta > 0 then + if global then + if trace_define then + commands.writestatus("color","define global transparency '%s' with attribute: %s",name,ta) + end + context.colordefagt(name,ta) + else + if trace_define then + commands.writestatus("color","define local transparency '%s' with attribute: %s",name,ta) + end + context.colordefalt(name,ta) + end + else + if global then + context.colordefrgt(name) + else + context.colordefrlt(name) + end + end +end + +local function inherittransparent(name, ta, global) + if ta and ta ~= "" then + if global then + if trace_define then + commands.writestatus("color","inherit global transparency '%s' with attribute: %s",name,ta) + end + context.colordeffgt(name,ta) + else + if trace_define then + commands.writestatus("color","inherit local transparency '%s' with attribute: %s",name,ta) + end + context.colordefflt(name,ta) + end + else + if global then + context.colordefrgt(name) + else + context.colordefrlt(name) + end + end +end + +local transparent = { + none = 0, + normal = 1, + multiply = 2, + screen = 3, + overlay = 4, + softlight = 5, + hardlight = 6, + colordodge = 7, + colorburn = 8, + darken = 9, + lighten = 10, + difference = 11, + exclusion = 12, +} + +-- By coupling we are downward compatible. When we decouple we need to do more tricky +-- housekeeping (e.g. persist color independent transparencies when color bound ones +-- are nil.) + +colors.couple = true + +function colors.definetransparency(name,n) + transparent[name] = n +end + +local registered = { } + +local function do_registerspotcolor(parent,name,parentnumber,e,f,d,p) + if not registered[parentnumber] then + local v = colors.values[parentnumber] + if v then + local kind = colors.default -- else problems with shading etc + if kind == 1 then kind = v[1] end + if e and e ~= "" then + registrations.spotcolorname(parent,e) -- before registration of the color + end + if kind == 2 then -- name noffractions names p's r g b + registrations.grayspotcolor(parent,f,d,p,v[2]) + elseif kind == 3 then + registrations.rgbspotcolor (parent,f,d,p,v[3],v[4],v[5]) + elseif kind == 4 then + registrations.cmykspotcolor(parent,f,d,p,v[6],v[7],v[8],v[9]) + end + end + registered[parentnumber] = true + end +end + +local function do_registermultitonecolor(parent,name,parentnumber,e,f,d,p) -- same as spot but different template + if not registered[parentnumber] then + local v = colors.values[parentnumber] + if v then + local kind = colors.default -- else problems with shading etc + if kind == 1 then kind = v[1] end + if kind == 2 then + registrations.grayindexcolor(parent,f,d,p,v[2]) + elseif kind == 3 then + registrations.rgbindexcolor (parent,f,d,p,v[3],v[4],v[5]) + elseif kind == 4 then + registrations.cmykindexcolor(parent,f,d,p,v[6],v[7],v[8],v[9]) + end + end + registered[parentnumber] = true + end +end + +function colors.definesimplegray(name,s) + return register_color(name,'gray',s) -- we still need to get rid of 'color' +end + +function colors.defineprocesscolor(name,str,global,freeze) -- still inconsistent color vs transparent + local x = match(str,"^#(.+)$") -- for old times sake (if we need to feed from xml or so) + if x then + local r, g, b = match(x .. "000000","(..)(..)(..)") -- watch the 255 + definecolor(name, register_color(name,'rgb',(tonumber(r,16) or 0)/255,(tonumber(g,16) or 0)/255,(tonumber(b,16) or 0)/255), global) + else + local settings = settings_to_hash_strict(str) + if settings then + local r, g, b = settings.r, settings.g, settings.b + if r or g or b then + definecolor(name, register_color(name,'rgb', tonumber(r) or 0, tonumber(g) or 0, tonumber(b) or 0), global) + else + local c, m, y, k = settings.c, settings.m, settings.y, settings.k + if c or m or y or b then + definecolor(name, register_color(name,'cmyk',tonumber(c) or 0, tonumber(m) or 0, tonumber(y) or 0, tonumber(k) or 0), global) + else + local h, s, v = settings.h, settings.s, settings.v + if v then + r, g, b = colors.hsvtorgb(tonumber(h) or 0, tonumber(s) or 1, tonumber(v) or 1) -- maybe later native + definecolor(name, register_color(name,'rgb',r,g,b), global) + else + local x = settings.x or h + if x then + r, g, b = match(x .. "000000","(..)(..)(..)") -- watch the 255 + definecolor(name, register_color(name,'rgb',(tonumber(r,16) or 0)/255,(tonumber(g,16) or 0)/255,(tonumber(b,16) or 0)/255), global) + else + definecolor(name, register_color(name,'gray',tonumber(s) or 0), global) + end + end + end + end + local a, t = settings.a, settings.t + if a and t then + definetransparent(name, transparencies.register(name,transparent[a] or tonumber(a) or 1,tonumber(t) or 1), global) + elseif colors.couple then + -- definetransparent(name, transparencies.register(nil, 1, 1), global) -- can be sped up + definetransparent(name, 0, global) -- can be sped up + end + elseif freeze then + local ca = attributes_list[a_color] [str] + local ta = attributes_list[a_transparency][str] + if ca then + definecolor(name, ca, global) + end + if ta then + definetransparent(name, ta, global) + end + else + inheritcolor(name, str, global) + 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[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 +end + +function colors.isblack(ca) -- maybe commands + local cv = ca > 0 and colors.value(ca) + return (cv and cv[2] == 0) or false +end + +function colors.definespotcolor(name,parent,str,global) + if parent == "" or find(parent,"=") then + colors.registerspotcolor(name, parent) + elseif name ~= parent then + local cp = attributes_list[a_color][parent] + if cp then + local t = settings_to_hash_strict(str) + if t then + local tp = tonumber(t.p) or 1 + do_registerspotcolor(parent, name, cp, t.e, 1, "", tp) -- p not really needed, only diagnostics + if name and name ~= "" then + definecolor(name, register_color(name,'spot', parent, 1, "", tp), true) + local ta, tt = t.a, t.t + if ta and tt then + definetransparent(name, transparencies.register(name,transparent[ta] or tonumber(ta) or 1,tonumber(tt) or 1), global) + elseif colors.couple then + --~ definetransparent(name, transparencies.register(nil, 1, 1), global) -- can be sped up + definetransparent(name, 0, global) -- can be sped up + end + end + end + end + end +end + +function colors.registerspotcolor(parent, str) + local cp = attributes_list[a_color][parent] + if cp then + local e = "" + if str then + local t = settings_to_hash_strict(str) + e = (t and t.e) or "" + end + do_registerspotcolor(parent, "dummy", cp, e, 1, "", 1) -- p not really needed, only diagnostics + end +end + +function colors.definemultitonecolor(name,multispec,colorspec,selfspec) + local dd, pp, nn = { }, { }, { } + for k,v in gmatch(multispec,"(%a+)=([^%,]*)") do + dd[#dd+1] = k + pp[#pp+1] = v + nn[#nn+1] = k + nn[#nn+1] = format("%1.3g",tonumber(v) or 0) -- 0 can't happen + end +--~ v = tonumber(v) * p + local nof = #dd + if nof > 0 then + dd, pp, nn = concat(dd,','), concat(pp,','), concat(nn,'_') + local parent = gsub(lower(nn),"[^%d%a%.]+","_") + colors.defineprocesscolor(parent,colorspec..","..selfspec,true,true) + local cp = attributes_list[a_color][parent] + if cp then + do_registerspotcolor(parent, name, cp, "", nof, dd, pp) + do_registermultitonecolor(parent, name, cp, "", nof, dd, pp) + definecolor(name, register_color(name, 'spot', parent, nof, dd, pp), true) + local t = settings_to_hash_strict(selfspec) + if t and t.a and t.t then + definetransparent(name, transparencies.register(name,transparent[t.a] or tonumber(t.a) or 1,tonumber(t.t) or 1), global) + elseif colors.couple then + -- definetransparent(name, transparencies.register(nil, 1, 1), global) -- can be sped up + definetransparent(name, 0, global) -- can be sped up + end + end + end +end + +function colors.mp(model,ca,ta,default) + local cv = colors.value(ca) -- faster when direct colors.values[ca] + if cv then + local tv = transparencies.value(ta) + if model == 1 then + model = cv[1] + end + if tv then + if model == 2 then + return format("transparent(%s,%s,(%s,%s,%s))",tv[1],tv[2],cv[3],cv[4],cv[5]) + elseif model == 3 then + return format("transparent(%s,%s,(%s,%s,%s))",tv[1],tv[2],cv[3],cv[4],cv[5]) + elseif model == 4 then + return format("transparent(%s,%s,cmyk(%s,%s,%s,%s))",tv[1],tv[2],cv[6],cv[7],cv[8],cv[9]) + else + return format("transparent(%s,%s,multitonecolor(\"%s\",%s,\"%s\",\"%s\"))",tv[1],tv[2],cv[10],cv[11],cv[12],cv[13]) + end + else + if model == 2 then + return format("(%s,%s,%s)",cv[3],cv[4],cv[5]) + elseif model == 3 then + return format("(%s,%s,%s)",cv[3],cv[4],cv[5]) + elseif model == 4 then + return format("cmyk(%s,%s,%s,%s)",cv[6],cv[7],cv[8],cv[9]) + else + return format("multitonecolor(\"%s\",%s,\"%s\",\"%s\")",cv[10],cv[11],cv[12],cv[13]) + end + end + else + default = default or 0 -- rgb ! + return format("(%s,%s,%s)",default,default,default) + end +end + +function colors.formatcolor(ca,separator) + local cv = colors.value(ca) + if cv then + local c, f, t, model = { }, 13, 13, cv[1] + if model == 2 then + f, t = 2, 2 + elseif model == 3 then + f, t = 3, 5 + elseif model == 4 then + 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 format("%0.3f",0) + end +end + +function colors.formatgray(ca,separator) + local cv = colors.value(ca) + return format("%0.3f",(cv and cv[2]) or 0) +end + +function colors.colorcomponents(ca) -- return list + local cv = colors.value(ca) + if cv then + local model = cv[1] + if model == 2 then + return format("s=%1.3f",cv[2]) + elseif model == 3 then + return format("r=%1.3f g=%1.3f b=%1.3f",cv[3],cv[4],cv[5]) + elseif model == 4 then + return format("c=%1.3f m=%1.3f y=%1.3f k=%1.3f",cv[6],cv[7],cv[8],cv[9]) + elseif type(cv[13]) == "string" then + return format("p=%s",cv[13]) + else + return format("p=%1.3f",cv[13]) + end + else + return "" + end +end + +function colors.transparencycomponents(ta) + local tv = transparencies.value(ta) + if tv then + return format("a=%1.3f t=%1.3f",tv[1],tv[2]) + else + return "" + end +end + +function colors.spotcolorname(ca,default) + local cv, v = colors.value(ca), "unknown" + if cv and cv[1] == 5 then + v = cv[10] + end + return tostring(v) +end + +function colors.spotcolorparent(ca,default) + local cv, v = colors.value(ca), "unknown" + if cv and cv[1] == 5 then + v = cv[12] + if v == "" then + v = cv[10] + end + end + return tostring(v) +end + +function colors.spotcolorvalue(ca,default) + local cv, v = colors.value(ca), 0 + if cv and cv[1] == 5 then + v = cv[13] + end + return tostring(v) +end + +-- experiment (a bit of a hack, as we need to get the attribute number) + +local min = math.min + +-- a[b,c] -> b+a*(c-b) + +local function f(one,two,i,fraction) + local o, t = one[i], two[i] + local otf = o + fraction * (t - o) + if otf > 1 then + otf = 1 + end + return otf +end + +function colors.defineintermediatecolor(name,fraction,c_one,c_two,a_one,a_two,specs,global,freeze) + fraction = tonumber(fraction) or 1 + local one, two = colors.value(c_one), colors.value(c_two) + if one and two then + local csone, cstwo = one[1], two[1] + if csone == cstwo then + -- actually we can set all 8 values at once here but this is cleaner as we avoid + -- problems with weighted gray conversions and work with original values + local ca + if csone == 2 then + ca = register_color(name,'gray',f(one,two,2,fraction)) + elseif csone == 3 then + ca = register_color(name,'rgb',f(one,two,3,fraction),f(one,two,4,fraction),f(one,two,5,fraction)) + elseif csone == 4 then + ca = register_color(name,'cmyk',f(one,two,6,fraction),f(one,two,7,fraction),f(one,two,8,fraction),f(one,two,9,fraction)) + else + ca = register_color(name,'gray',f(one,two,2,fraction)) + end + definecolor(name,ca,global,freeze) + end + end + local one, two = transparencies.value(a_one), transparencies.value(a_two) + local t = settings_to_hash_strict(specs) + local ta = tonumber((t and t.a) or (one and one[1]) or (two and two[1])) + local tt = tonumber((t and t.t) or (one and two and f(one,two,2,fraction))) + if ta and tt then +--~ print(ta,tt) + definetransparent(name,transparencies.register(name,ta,tt),global) + end +end diff --git a/tex/context/base/colo-ini.mkii b/tex/context/base/colo-ini.mkii new file mode 100644 index 000000000..2d2a7bdaa --- /dev/null +++ b/tex/context/base/colo-ini.mkii @@ -0,0 +1,2776 @@ +%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. + +\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 +%D however be accomplished by using specials. This also means +%D that this support depends on the \DVI\ driver used. At the +%D moment this module was written, still no decent standard on +%D color specials has been agreed upon. We therefore decided to +%D implement a mechanism that is as independant as possible of +%D drivers. +%D +%D Color support shares with fonts that is must be implemented +%D in a way that permits processing of individual \DVI\ pages. +%D Furthermore it should honour grouping. The first condition +%D forces us to use a scheme that keeps track of colors at +%D page boundaries. This can be done by means of \TEX's +%D marking mechanism (\type{\mark}). +%D +%D When building pages, \TEX\ periodically looks at the +%D accumulated typeset contents and breaks the page when +%D suitable. At that moment, control is transfered to the +%D output routine. This routine takes care of building the +%D pagebody and for instance adds headers and footers. The page +%D can be broken in the middle of some colored text, but +%D headers and footers are often in black upon white or +%D background. If colors are applied there, they definitely +%D are used local, which means that they don't cross page +%D borders. +%D +%D Boxes are handled as a whole, which means that when we +%D apply colors inside a box, those colors don't cross page +%D boundaries, unless of course boxes are split or unboxed. +%D Especially in interactive texts, colors are often used in +%D such a local way: in boxes (buttons and navigational tools) +%D or in the pagebody (backgrounds). +%D +%D So we can distinguish local colors, that don't cross +%D pages from global colors, of which we can end many pages +%D later. The color macros will treat both types in a different +%D way, thus gaining some speed. +%D +%D This module also deals with gray scales. Because similar +%D colors can end up in the same gray scale when printed in +%D black and white, we also implement a palet system that deals +%D with these matters. Because of fundamental differences +%D between color and gray scale printing, in \CONTEXT\ we also +%D differ between these. For historic reasons |<|we first +%D implemented gray scales using patterns of tiny periods|>| +%D and therefore called them {\em rasters}. So don't be +%D surprised if this term shows up. + +%D \macros +%D {definecolor} +%D +%D We will enable users to specify colors in \cap{RGB} and +%D \cap{CMYK} color spaces or gray scales using +%D +%D \showsetup{definecolor} +%D +%D For example: +%D +%D \starttyping +%D \definecolor [SomeKindOfRed] [r=.8,g=.05,b=.05] +%D \stoptyping +%D +%D Such color specifications are saved in a macro in the +%D following way: +%D +%D \starttyping +%D \setvalue{\??cr name}{R:r:g:b} +%D \setvalue{\??cr name}{C:c:m:y:k} +%D \setvalue{\??cr name}{S:s} +%D \stoptyping +%D +%D Gray scales are specified with the \type{s} parameter, +%D where the \type {s} is derived from {\em screen}. +%D +%D Starting with \PDF\ 1.4 (2001) \CONTEXT\ supports +%D transparent colors. The transparency factor is represented +%D by a \type {t} and the transparency method by an \type {a} +%D (alternative). Later we will implement more control +%D (probably by symbolic methods. So, currently the data is +%D stored as follows: +%D +%D \starttyping +%D \setvalue{\??cr name}{R:r:g:b:a:t} +%D \setvalue{\??cr name}{C:c:m:y:k:a:t} +%D \setvalue{\??cr name}{S:s:a:t} +%D \stoptyping + +% r g b : rbg +% c m y k : cmyk +% s : gray +% p n d f : spot +% h : hexadecimal +% t a : transparency +% e : equivalent (spotcolors) + +\def\@@cl@@z{0} +\def\@@cl@@o{1} + +\def\@@resetcolorparameters + {\let\@@cl@@r\@@cl@@z \let\@@cl@@g\@@cl@@z \let\@@cl@@b\@@cl@@z + \let\@@cl@@c\@@cl@@z \let\@@cl@@m\@@cl@@z \let\@@cl@@y\@@cl@@z \let\@@cl@@k\@@cl@@z + \let\@@cl@@s\@@cl@@z + \let\@@cl@@p\@@cl@@o \let\@@cl@@n\empty \let\@@cl@@d\empty \let\@@cl@@f\@@cl@@o + \let\@@cl@@h\empty + \let\@@cl@@e\empty + \let\@@cl@@t\@@cl@@z \let\@@cl@@a\@@cl@@z} + +\@@resetcolorparameters + +\def\@@cl@@A{\@@cl@@a} % a hook for symbolic conversion, see below + +%D Handling a few nested \type{\cs}'s is no problem (\type +%D {\@EA\@EAEAEA\@EA}) but we need a full expansion, so I +%D tried one of the fully expandable primitives using a sort +%D of delimited thing. I tried \type {\number} first, but this +%D does not work, but \type {\romannumeral} does. Actually, +%D \type{\romannumeral0} returns nothing, so it's a perfect +%D candidate for this kind of hackery. This reminds me that I +%D have to look into David Kastrup's Euro\TeX\ 2002 article +%D because he is using \type {\romannumeral} for loops +%D (repetitive \quote {m} stuff). + +% \def\x{\y}\def\y{\z}\def\z{0:1:1:1} +% +% \def\bla #1:#2:#3\end{} +% +% \@EA\bla\romannumeral\x\end + +\def\colorXpattern{0S:\@@cl@@z:\@@cl@@z:\@@cl@@z} +\def\colorZpattern{0S:\@@cl@@z:\@@cl@@A:\@@cl@@t} +\def\colorSpattern{0S:\@@cl@@s:\@@cl@@A:\@@cl@@t} +\def\colorCpattern{0C:\@@cl@@c:\@@cl@@m:\@@cl@@y:\@@cl@@k:\@@cl@@A:\@@cl@@t} +\def\colorRpattern{0R:\@@cl@@r:\@@cl@@g:\@@cl@@b:\@@cl@@A:\@@cl@@t} + +%def\colorPpattern{0P:\@@cl@@n:\@@cl@@p:\@@cl@@A:\@@cl@@t} + +\def\colorPpattern{0P:\@@cl@@n:\@@cl@@f:\@@cl@@d:\@@cl@@p:\@@cl@@A:\@@cl@@t} + +%D The extra 0 catches empty colors specs (needed for the +%D \type {\MPcolor} and \type {\PDFcolor} conversion (\type +%D {\@@cr} equals \type {\relax}!). + +\def\handlecolorwith#1{\@EA#1\romannumeral0} + +%D Next comes the main definition macro. + +\def\dodefinecolor {\dododefinecolor\relax \setvalue \setevalue1} +\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 + {\ifconditional\collectcolorsinlist\collectcolorinlist{#5}\fi + \doifassignmentelse{#6} + {\@@resetcolorparameters + \getparameters[\??cl @@][#6]% + \ifx\@@cl@@h\empty + \doifelse{\@@cl@@r\@@cl@@g\@@cl@@b}{\@@cl@@z\@@cl@@z\@@cl@@z} + {\doifelse{\@@cl@@c\@@cl@@m\@@cl@@y\@@cl@@k}{\@@cl@@z\@@cl@@z\@@cl@@z\@@cl@@z} + {\doifelse\@@cl@@s\@@cl@@z + {\showmessage\m!colors8{{[#6]},#5}% + #3{\??cr#5}{\colorZpattern}} + {#3{\??cr#5}{\colorSpattern}}} + {#3{\??cr#5}{\colorCpattern}}} + {#3{\??cr#5}{\colorRpattern}}% + \else + \setxvalue{\??cr#5}{\colorHpattern}% + \fi + % new: e=external spot color name + \ifx\@@cl@@e\empty \else + \doregisterspotcolorname{#5}\@@cl@@e + \fi} + {\doifelsenothing\currentpalet + \donefalse + {\doifdefinedelse{\??cr\currentpalet#6}\donetrue\donefalse}% + \ifdone + \doifnot{#5}{#6} + {#2{\??cr#5}{\paletcolorspec{#6}}}% + \else + \doifdefinedelse{\??cr#6} + {\doifelse{#5}{#6} + {% this way we can freeze \definecolor[somecolor][somecolor] + % and still prevent cyclic definitions + \iffreezecolors#3{\??cr#5}{\csname\??cr#6\endcsname}\fi} + {\iffreezecolors\@EA#3\else\@EA#2\fi{\??cr#5}{\csname\??cr#6\endcsname}}} + {\showmessage\m!colors3{#5 (def)}}% + \fi}% + \ifcase#4\or + \unexpanded#2{#5}{\switchtocolor[#5]}% \unexpanded toegevoegd + \fi} + +\def\paletcolorspec#1% + {\csname\??cr\currentpalet#1\endcsname} + +%D Hex color support is not enabled by default. You need to say \type +%D {\setupcolor [hex]} to get this working. + +\ifx\colorHpattern\undefined \let\colorHpattern\colorZpattern \fi + +%D New and experimental. + +\def\dodefinespotcolor[#1][#2][#3]% todo: always global + {\doifnot{#1}{#2} + {\@@resetcolorparameters + \ifconditional\collectcolorsinlist\collectcolorinlist{#1}\fi + \edef\@@cl@@n{#2}% + \getparameters[\??cl @@][#3]% + \doifnothing\@@cl@@p{\let\@@cl@@p\!!plusone}% + \ifx\@@cl@@e\empty \else + \doregisterspotcolorname{#2}\@@cl@@e + \fi + \doglobal\addtocommalist{#2}\allspotcolors + \setxvalue{\??cr#1}{\colorPpattern}% was \setevalue + \setgvalue{#1}{\switchtocolor[#1]}}} % was \setvalue + +\def\registerusedspotcolors + {\ifx\allspotcolors\empty \else + \bgroup + \let\usedspotcolors\empty + \def\docommand##1% + {\doifdefined{\??cs##1}{\addtocommalist{##1}\usedspotcolors}}% + \processcommacommand[\allspotcolors]\docommand + \savecurrentvalue\usedspotcolors\usedspotcolors + \egroup + \fi} + +\def\registerusedcolorchannels + {\bgroup + \doifdefinedelse{\??cs c} + {\def\usedcolorchannels{c,m,y,k}}% + {\let\usedcolorchannels\empty}% + \doifdefined{\??cs r} + {\addtocommalist{r,g,b}\usedcolorchannels}% + \doifdefined{\??cs s} + {\ExpandBothAfter\doifnotinset{k}\usedcolorchannels + {\addtocommalist{s}\usedcolorchannels}}% + \savecurrentvalue\usedcolorchannels\usedcolorchannels + \egroup} + +\prependtoks + \registerusedspotcolors + \registerusedcolorchannels +\to \everylastshipout + +\def\registerusedspotcolor#1% + {\global\@EA\chardef\csname\??cs#1\endcsname\zerocount} + +%D On top of spotcolors, we define multitone colors. You'd better know +%D what you're doing because invalid definitions will lead to invalid +%D documents (i.e.\ resources). + +% \definecolor [darkblue] [c=.5,m=.5] +% \definecolor [darkyellow] [y=.5] +% +% \definemultitonecolor [whatever] [darkblue=.5,darkyellow=.5] [c=.25,m=.25,y=.25] [a=1,t=.5] +% \definemultitonecolor [another] [darkblue=.5,darkyellow=.5] [c=.25,m=.25,y=.25] + +\def\dodefinemultitonecolor[#1][#2][#3][#4]% + {\let\@@cl@@cl@@D\empty % n's + \let\@@cl@@cl@@P\empty % p's + \let\@@cl@@cl@@N\empty % name + \scratchcounter\zerocount + \processcommacommand[#2]\dododefinemultitonecolor + \bgroup + \lccode`\.=`\_% + \lccode`\,=`\_% + \lccode`\:=`\_% + \lccode`\;=`\_% + \lccode`\+=`\_% + \lccode`\-=`\_% + \lccode`\*=`\_% + \lccode`\/=`\_% +% \lccode`\_=`\_% + % not needed, other attribute in driver: + % + % \@@resetcolorparameters + % \getparameters[#4]% + % \ifx\@@cl@@t\@@cl@@z\else + % \edef\@@cl@@cl@@N{\@@cl@@cl@@N_\@@cl@@t_\@@cl@@a}% + % \fi + \lowercase\@EA{\@EA\xdef\@EA\@@cleancolor\@EA{\@@cl@@cl@@N}}% + \egroup + \setxvalue{\??cl\@@cleancolor\s!check}{\noexpand\docheckmultitonecolor{\@@cl@@cl@@D}}% + \expanded{\defineglobalcolor[\@@cleancolor][#3,#4]}% + \expanded{\definespotcolor[#1][\@@cleancolor][#4,f=\the\scratchcounter,p={\@@cl@@cl@@P},d={\@@cl@@cl@@D}]}} + +\def\docheckmultitonecolor#1% + {\flushatshipout + {\let\checkmultitonecolor\gobbleoneargument + \def\docommand##1{\hbox{\definecolor[\s!dummy-100][##1][p=1]\color[\s!dummy-100]}}% + \processcommalist[#1]\docommand}} + +\def\checkmultitonecolor#1% + {\csname\??cl#1\s!check\endcsname\letgvalue{\??cl#1\s!check}\relax} + +\def\dodefinespotcolor[#1][#2][#3]% todo: always global (REDEFINED) + {\doifnot{#1}{#2} + {\@@resetcolorparameters + \ifconditional\collectcolorsinlist\collectcolorinlist{#1}\fi + \edef\@@cl@@n{#2}% + \getparameters[\??cl @@][#3]% + \doifnothing \@@cl@@p{\let\@@cl@@p\!!plusone}% + \doifsomething\@@cl@@e{\doregisterspotcolorname{#2}\@@cl@@e}% + \doglobal\addtocommalist{#2}\allspotcolors + \setxvalue{\??cr#1}{\colorPpattern}% was \setevalue + \setgvalue{#1}{\switchtocolor[#1]}}}% was \setvalue + +\def\dododefinemultitonecolor#1% + {\advance\scratchcounter\plusone + \splitstring#1\at=\to\!!stringa\and\!!stringb + \ifx\@@cl@@cl@@D\empty + \let\@@cl@@cl@@D\!!stringa + \let\@@cl@@cl@@P\!!stringb + \normalizecolor\!!stringb + \edef\@@cl@@cl@@N{\!!stringa_\!!stringb}% + \else + \edef\@@cl@@cl@@D{\@@cl@@cl@@D,\!!stringa}% + \edef\@@cl@@cl@@P{\@@cl@@cl@@P,\!!stringb}% + \normalizecolor\!!stringb + \edef\@@cl@@cl@@N{\@@cl@@cl@@N_\!!stringa_\!!stringb}% + \fi} + +% \def\dododefinemultitonecolor#1% a/b safe +% {\advance\scratchcounter\plusone +% \splitstring#1\at=\to\@@cl@@one\and\@@cl@@two +% \ifx\@@cl@@cl@@D\empty +% \let\@@cl@@cl@@D\@@cl@@one +% \let\@@cl@@cl@@P\@@cl@@two +% \normalizecolor\@@cl@@two +% \edef\@@cl@@cl@@N{\@@cl@@one_\@@cl@@two}% +% \else +% \edef\@@cl@@cl@@D{\@@cl@@cl@@D,\@@cl@@one}% +% \edef\@@cl@@cl@@P{\@@cl@@cl@@P,\@@cl@@two}% +% \normalizecolor\@@cl@@two +% \edef\@@cl@@cl@@N{\@@cl@@cl@@N_\@@cl@@one_\@@cl@@two}% +% \fi} + +%D The names of colors are stored in a comma separated list +%D only for the purpose of showing them with \type {\showcolor}. +%D +%D \startbuffer +%D \definecolor [SomeKindOfRed] [r=.8,g=.05,b=.05] +%D \stopbuffer +%D +%D \typebuffer +%D \getbuffer +%D +%D This color shows up as \color [SomeKindOfRed] {some kind +%D of red}. +%D +%D \starttyping +%D \setupcolors[state=start] +%D +%D \definecolor[mygreen][green] +%D \definecolor[green][g=.5] +%D +%D \startcolor[mygreen]test\stopcolor +%D +%D \setupcolors[expansion=no] +%D +%D \definecolor[mygreen][green] +%D \definecolor[green][g=.5] +%D +%D \startcolor[mygreen]test\stopcolor +%D \stoptyping + +%D \macros +%D {startcolormode,stopcolormode,permitcolormode} +%D +%D We use \type{\stopcolormode} to reset the color in +%D whatever color space and do so by calling the corresponding +%D special. Both commands can be used for fast color +%D switching, like in colored verbatim, + +\newif\ifpermitcolormode \permitcolormodetrue + +\def\dowithcolor#1#2% #1=\action #2=color + {\ifincolor\ifpermitcolormode + \ifcsname\??cr\currentpalet#2\endcsname + \handlecolorwith#1\csname\??cr\currentpalet#2\endcsname\od + \else\ifcsname\??cr#2\endcsname + \handlecolorwith#1\csname\??cr#2\endcsname\od + \fi\fi + \fi\fi} + +\def\startcolormode % includes \ifincolor\ifpermitcolormode + {%\dostoptransparency % needed for: {test \trans test \notrans test} + \conditionalstoptransparency + \dowithcolor\execcolorRCSP} + +\def\stopcolormode + {\ifincolor\ifpermitcolormode + \supportedstoptransparency + \dostopcolormode + \fi\fi} + +\def\restorecolormode + {\ifincolor\ifpermitcolormode + \supportedstoptransparency + \dostopcolormode + \ifx\maintextcolor\empty \else + \startcolormode\maintextcolor + \fi + \fi\fi} + +%D Color modes are entered using the next set of commands. +%D The \type{\stop} alternatives are implemented in a way +%D that permits non||grouped use. +%D +%D The, for this module redundant, check if we are in color +%D mode is needed when we use these macros in other modules. + +\def\execcolorRCSP#1:% + {\csname execcolor#1\endcsname} + +\def\execcolorR + {\iffilterspotcolor + \@EA\noexeccolorR + \else + \@EA\doexeccolorR + \fi} + +\def\execcolorC + {\iffilterspotcolor + \@EA\noexeccolorC + \else + \@EA\doexeccolorC + \fi} + +\def\execcolorS + {\iffilterspotcolor + \@EA\noexeccolorS + \else + \@EA\doexeccolorS + \fi} + +\def\execcolorP + {\iffilterspotcolor + \@EA\doexeccolorPP + \else\ifcase\currentcolorchannel + \@EAEAEA\doexeccolorP + \else + \@EAEAEA\noexeccolorP + \fi\fi} + +\def\doexeccolorR#1:#2:#3:% + {\edef\@@cl@@r{#1}\edef\@@cl@@g{#2}\edef\@@cl@@b{#3}% + \ifpreferGRAY\ifx\@@cl@@r\@@cr@@g\ifx\@@cl@@r\@@cl@@b + \GRAYpreferedtrue + \fi\fi\fi + \ifincolor\else\RGBsupportedfalse\CMYKsupportedfalse\fi + \ifGRAYprefered + \registercolorchannel\c!s + \let\@@cl@@s\@@cl@@r + \normalizeGRAY + \doexeccolorgray + \else\ifRGBsupported + \registercolorchannel\c!r + \normalizeRGB + \doexeccolorrgb + \else\ifCMYKsupported + \registercolorchannel\c!c + \convertRGBtoCMYK\@@cl@@r\@@cl@@g\@@cl@@b + \normalizeCMYK + \doexeccolorcmyk + \else + \registercolorchannel\c!s + \convertRGBtoGRAY\@@cl@@r\@@cl@@g\@@cl@@b + \normalizeGRAY + \doexeccolorgray + \fi\fi\fi + \exectransparency} + +\def\doexeccolorC#1:#2:#3:#4:% + {\edef\@@cl@@c{#1}\edef\@@cl@@m{#2}\edef\@@cl@@y{#3}\edef\@@cl@@k{#4}% + \ifpreferGRAY\ifx\@@cl@@k\@@cl@@z\ifx\@@cl@@c\@@cr@@m\ifx\@@cl@@c\@@cl@@y + \GRAYpreferedtrue + \fi\fi\fi\fi + \ifincolor\else\RGBsupportedfalse\CMYKsupportedfalse\fi + \ifGRAYprefered + \registercolorchannel\c!s + \let\@@cl@@s\@@cl@@c + \normalizeGRAY + \doexeccolorgray + \else\ifCMYKsupported + \registercolorchannel\c!c + \ifreduceCMYK + \convertCMYKtoCMY\@@cl@@c\@@cl@@m\@@cl@@y\@@cl@@k + \fi + \normalizeCMYK + \doexeccolorcmyk + \else\ifRGBsupported + \registercolorchannel\c!r + \convertCMYKtoRGB\@@cl@@c\@@cl@@m\@@cl@@y\@@cl@@k + \normalizeRGB + \doexeccolorrgb + \else + \registercolorchannel\c!s + \convertCMYKtoGRAY\@@cl@@c\@@cl@@m\@@cl@@y\@@cl@@k + \normalizeGRAY + \doexeccolorgray + \fi\fi\fi + \exectransparency} + +\def\doexeccolorS#1:% + {\edef\@@cl@@s{#1}% + \registercolorchannel\c!s + \normalizeGRAY + \doexeccolorgray + \exectransparency} + +% \def\doexeccolorP#1:#2:% +% {\edef\@@cl@@n{#1}% +% \edef\@@cl@@p{#2}% +% \registerusedspotcolor\@@cl@@n +% \ifSPOTsupported +% \dowithcolor\registerspotcolor\@@cl@@n +% \dostartspotcolormode\@@cl@@n\@@cl@@p +% \else +% \doingspotcolortrue +% \let\spotcolorfactor\@@cl@@p +% \factorizecolortrue % using counter and array +% \dowithcolor\execcolorRCSP\@@cl@@n +% \factorizecolorfalse +% \let\spotcolorfactor\@@cl@@o +% \doingspotcolorfalse +% \fi +% \exectransparency} + +\def\doexeccolorP#1:#2:#3:#4:% + {\edef\@@cl@@n{#1}% name + \edef\@@cl@@f{#2}% fractions + \edef\@@cl@@d{#3}% definitions + \edef\@@cl@@p{#4}% + \ifx\@@cl@@d\empty + \let\@@cl@@d\@@cl@@n + \fi + \registerusedspotcolor\@@cl@@n + \ifSPOTsupported + \checkmultitonecolor\@@cl@@n + \dowithcolor\registerspotcolor\@@cl@@n + \dostartspotcolormode\@@cl@@n\@@cl@@p + \else + \doingspotcolortrue + \normalizespotcolor\@@cl@@p + \let\spotcolorfactor\@@cl@@p + \factorizecolortrue % using counter and array + \dowithcolor\execcolorRCSP\@@cl@@n + \factorizecolorfalse + \let\spotcolorfactor\@@cl@@o + \doingspotcolorfalse + \fi + \exectransparency} + +\def\doexeccolorPindex#1:#2:#3:#4:% + {\edef\@@cl@@n{#1}% + \edef\@@cl@@f{#2}% + \edef\@@cl@@d{#3}% + \edef\@@cl@@p{#4}% + \ifx\@@cl@@d\empty + \let\@@cl@@d\@@cl@@n + \fi + \ifSPOTsupported + \checkmultitonecolor\@@cl@@n + \dowithcolor\registerindexcolor\@@cl@@n + \fi + \noexectransparency} + +\def\doexeccolorPP#1:#2:% + {\edef\@@cl@@n{#1}% + \edef\@@cl@@p{#2}% + \registerusedspotcolor\@@cl@@n + \ifx\@@cl@@n\currentspotcolor + \normalizeSPOT + \dostartgraycolormode\@@cl@@p % was spotcolormode + \else + \dovidecolor\@@cl@@p\@@cl@@o + \fi + \exectransparency} + +\def\doexeccolorrgb + {\ifcase\currentcolorchannel + \dostartrgbcolormode\@@cl@@r\@@cl@@g\@@cl@@b + \or \or \or \or + \or \dostartgraycolormode\@@cl@@r + \or \dostartgraycolormode\@@cl@@g + \or \dostartgraycolormode\@@cl@@b + \fi} + +\def\doexeccolorcmyk + {\ifcase\currentcolorchannel + \dostartcmykcolormode\@@cl@@c\@@cl@@m\@@cl@@y\@@cl@@k + \or \negatecolorcomponent\@@cl@@c\dostartgraycolormode\@@cl@@c + \or \negatecolorcomponent\@@cl@@m\dostartgraycolormode\@@cl@@m + \or \negatecolorcomponent\@@cl@@y\dostartgraycolormode\@@cl@@y + \or \negatecolorcomponent\@@cl@@k\dostartgraycolormode\@@cl@@k + \fi} + +\def\doexeccolorgray + {\ifcase\currentcolorchannel + \dostartgraycolormode\@@cl@@s + \or \or \or + \or \dostartgraycolormode\@@cl@@s + \or \or \or + \or \dostartgraycolormode\@@cl@@s + \fi} + +%D When filtering colors, we need to either erase +%D the background, or ignore the foreground. + +% \newif\ifhidesplitcolor \hidesplitcolortrue +% +% \def\noexeccolor#1\od +% {\dostartgraycolormode\@@cl@@o} +% +% \let\noexeccolorS\noexeccolor +% \let\noexeccolorP\noexeccolor + +%D Well, here comes some real trickery. When we have the 100\% +%D spot color or black color, we don't want to erase the +%D background. So, instead we hide the content by giving it +%D zero transparency. + +% todo : #1#2#3 met #2 > of < and #3 een threshold + +\def\dohidecolor#1#2% + {\ifhidesplitcolor + \ifx#1#2% + \dostartgraycolormode\@@cl@@o + \else + \doregisternonecolor + \dostartnonecolormode + \fi + \else + \dostartgraycolormode\@@cl@@o + \fi} + +\def\dovidecolor#1#2% + {\ifhidesplitcolor + \ifx#1#2% + \doregisternonecolor + \dostartnonecolormode + \else + \dostartgraycolormode\@@cl@@o + \fi + \else + \dostartgraycolormode\@@cl@@o + \fi} + +% \def\fullytransparentcolor % fails on floats +% {\dostartgraycolormode\@@cl@@o % better than z +% %\global\@EA\chardef\csname\@@currenttransparent\endcsname\plusone +% %\global\intransparenttrue +% \dostarttransparency10} + +\def\noexeccolorR#1:#2:#3:#4\od + {\edef\@@cl@@r{#1}\edef\@@cl@@g{#2}\edef\@@cl@@b{#3}% + \dohidecolor\@@cl@@s\@@cl@@o} + +\def\noexeccolorC#1:#2:#3:#4:#5\od + {\edef\@@cl@@c{#1}\edef\@@cl@@m{#2}\edef\@@cl@@y{#3}\edef\@@cl@@k{#4}% + \dohidecolor\@@cl@@s\@@cl@@o} + +\def\noexeccolorS#1:#2\od + {\edef\@@cl@@s{#1}% + \dohidecolor\@@cl@@s\@@cl@@o} + +\def\noexeccolorP#1:#2:#3:#4:#5\od + {\edef\@@cl@@p{#4}% + \dohidecolor\@@cl@@p\@@cl@@z} + +%D For the sake of postprocessing (i.e.\ color separation) +%D we can normalize colors, which comes down to giving equal +%D values an equal accuracy and format. This feature is +%D turned off by default due to a speed penalty. This macro +%D also handles spot color percentages. + +\newif\iffactorizecolor +\newif\ifnormalizecolor + +\def\spotcolorfactor{1} + +% \def\normalizecolor#1% +% {\colordimen#1\thousandpoint +% \colordimen\spotcolorfactor\colordimen +% \colorcount\colordimen +% \advance\colorcount \medcard +% \divide\colorcount \maxcard +% \edef#1{\realcolorvalue\colorcount}} + +\def\normalizecolor#1% + {\colorcount\numexpr(\dimexpr\spotcolorfactor\dimexpr#1\thousandpoint\relax\relax+\medcard)/\maxcard\relax + \edef#1{\realcolorvalue\colorcount}} + +% \def\normalizespotcolor#1% +% {\colordimen-#1\thousandpoint +% \advance\colordimen\thousandpoint +% \colorcount\colordimen +% \advance\colorcount \medcard +% \divide\colorcount \maxcard +% \edef#1{\realcolorvalue\colorcount}} + +\def\normalizespotcolor#1% + {\colorcount\numexpr(\dimexpr\thousandpoint-#1\thousandpoint\relax+\medcard)/\maxcard\relax + \edef#1{\realcolorvalue\colorcount}} + +\def\donormalizeRGB + {\normalizecolor\@@cl@@r + \normalizecolor\@@cl@@g + \normalizecolor\@@cl@@b} + +\def\normalizeRGB + {\ifnormalizecolor + \donormalizeRGB + \else\iffactorizecolor + \donormalizeRGB + \fi\fi} + +\def\donormalizeCMYK + {\normalizecolor\@@cl@@c + \normalizecolor\@@cl@@m + \normalizecolor\@@cl@@y + \normalizecolor\@@cl@@k} + +\def\normalizeCMYK + {\ifnormalizecolor + \donormalizeCMYK + \else\iffactorizecolor + \donormalizeCMYK + \fi\fi} + +\def\donormalizeGRAY + {\normalizecolor\@@cl@@s} + +\def\normalizeGRAY + {\ifnormalizecolor + \donormalizeGRAY + \else\iffactorizecolor + \donormalizeGRAY + \fi\fi} + +\def\normalizeSPOT + {\normalizespotcolor\@@cl@@p} + +%D We need to register spot colors (i.e.\ resources need to +%D be created. + +\def\registerspotcolor#1:% + {\ifcsname\??cl:\c!p:\@@cl@@n\endcsname + \@EA\dontregisterspotcolor + \else + \letgvalue{\??cl:\c!p:\@@cl@@n}\empty + %\@EA\@EA\csname registerspotcolor#1\endcsname + \csname registerspotcolor#1\@EA\endcsname + \fi} + +% todo: convert to rgb if needed, will will do this in mkiv + +\def\dontregisterspotcolor #1\od{} +\def\registerspotcolorR #1:#2:#3:#4\od{\doregisterrgbspotcolor \@@cl@@n\@@cl@@f\@@cl@@d\@@cl@@p{#1}{#2}{#3}} +\def\registerspotcolorC#1:#2:#3:#4:#5\od{\doregistercmykspotcolor\@@cl@@n\@@cl@@f\@@cl@@d\@@cl@@p{#1}{#2}{#3}{#4}} +\def\registerspotcolorS #1:#2\od{\doregistergrayspotcolor\@@cl@@n\@@cl@@f\@@cl@@d\@@cl@@p{#1}} +\def\registerspotcolorP #1:#2:#3\od{\doregistergrayspotcolor\@@cl@@n\@@cl@@f\@@cl@@d\@@cl@@p{#2}} + +%D Experimental feature: + +% \definecolor [darkblue] [c=1,m=.38,y=0,k=.64] % pantone pms 2965 uncoated m +% \definecolor [darkyellow] [c=0,m=.28,y=1,k=.06] % pantone pms 124 uncoated m +% +% \definecolor [darkblue-50] [darkblue] [p=.5] +% \definecolor [darkyellow-50] [darkyellow] [p=.5] +% \definecolor [darkblue-80] [darkblue] [p=.8] +% \definecolor [darkyellow-80] [darkyellow] [p=.8] +% +% \definecolor [darkblue,darkyellow] [r=.8] +% \definecolor [darkdull-5030] [darkblue,darkyellow] [p={.5,.3}] +% +% \setupcolors[state=start] +% +% \blackrule[width=4cm,height=3cm,color=darkblue-50] +% \blackrule[width=4cm,height=3cm,color=darkblue-80] +% \blackrule[width=4cm,height=3cm,color=darkyellow-50] +% \blackrule[width=4cm,height=3cm,color=darkyellow-80] +% \blackrule[width=4cm,height=3cm,color=darkdull-5030] + +%D Experimental too (special purpose code). + +\def\registerindexcolor#1:% + {\ifcsname\??cl:i:\@@cl@@n\endcsname + \@EA\dontregisterindexcolor + \else + \letgvalue{\??cl:i:\@@cl@@n}\empty % signal + \showmessage\m!colors{12}\@@cl@@n + \@EA\@EA\csname registerindexcolor#1\endcsname + \fi} + +\let\dontregisterindexcolor\dontregisterspotcolor + +\def\registerindexcolorR #1:#2:#3:#4\od{\doregisterrgbindexcolor \@@cl@@n\@@cl@@f\@@cl@@d\@@cl@@p{#1}{#2}{#3}} +\def\registerindexcolorC#1:#2:#3:#4:#5\od{\doregistercmykindexcolor\@@cl@@n\@@cl@@f\@@cl@@d\@@cl@@p{#1}{#2}{#3}{#4}} +\def\registerindexcolorS #1:#2\od{\doregistergrayindexcolor\@@cl@@n\@@cl@@f\@@cl@@d\@@cl@@p{#1}} +\def\registerindexcolorP #1:#2:#3\od{\doregistergrayindexcolor\@@cl@@n\@@cl@@f\@@cl@@d\@@cl@@p{#2}} + +\def\predefinecolor[#1]% + {\bgroup + \flushatshipout{\hbox{\localcolortrue\color[#1]{}}}% real ones + \egroup} + +\def\predefineindexcolor[#1]% + {\bgroup + \flushatshipout{\hbox{\localcolortrue\color[#1]{}}}% real ones + \let\doexeccolorP\doexeccolorPindex + \flushatshipout{\hbox{\localcolortrue\color[#1]{}}}% index one + \egroup} + +% \def\checkpredefinedcolor[#1]% +% {\ifcase\internalspotcolorsize{#1}\relax +% \@EA\predefinecolor\or\@EA\predefinecolor\else\@EA\predefineindexcolor +% \fi[#1]} + +\let\checkpredefinedcolor\predefineindexcolor % we need an index in order to negate bitmaps + +%D Transparency is handled similar for all three color modes. We +%D can turn transparency off with the following switch: + +\newif\iftransparencysupported \transparencysupportedtrue % only mkii + +\def\exectransparency + {\iftransparencysupported + \expandafter\doexectransparency + \else + \expandafter\noexectransparency + \fi} + +\def\doexectransparency#1:#2\od + {\ifcase#1\space + \global\intransparentfalse + \else + \global\intransparentfalse + %\dostarttransparency{#1}{#2}% + \supportedstarttransparency{#1}{#2}% + \global\intransparenttrue + \fi} + +\def\noexectransparency#1\od + {} + +%D Experimental: minimize transparency resets. + +\newif\ifintransparent +\newif\ifoptimizetransparency \optimizetransparencytrue % under test + +\let\supportedstoptransparency\relax + +\def\conditionalstoptransparency + {\ifoptimizetransparency + \ifintransparent + \global\intransparentfalse + \supportedstoptransparency + \fi + \else + \supportedstoptransparency + \fi} + +\def\supportedstarttransparency + {\iftransparencysupported + \globallet\supportedstoptransparency\dostoptransparency + \expandafter\dostarttransparency + \else + \expandafter\gobbletwoarguments + \fi} + +%D We now use the \type {\@@cl@@A} hook to implement +%D symbolic names. These are converted into numbers +%D at definition time (which saves runtime). + +\def\dodefinetransparency[#1][#2]% + {\@EA\chardef\csname\??cl-#1\endcsname#2\relax} + +\def\transparencynumber#1% + {\number\executeifdefined{\??cl-#1}{#1}} + +%D Now we hook 'm into the patterns: + +\def\@@cl@@A{\transparencynumber\@@cl@@a} + +%D The next macro can be used to return to the (normal) +%D page color. This macro is used in the same way as +%D \type {\color}. + +\def\startregistercolor[#1]% + {\permitcolormodefalse\startcolor[#1]\permitcolormodetrue} + +\def\stopregistercolor + {\permitcolormodefalse\stopcolor\permitcolormodetrue} + +\def\starttextcolor[#1]% + {\doifsomething{#1} + {\bgroup + \def\stoptextcolor % also goes ok with \page after + {\let\maintextcolor\empty % this one because the top of + \stopregistercolor % page sets the color right (side + \egroup}% % effect) + \def\starttextcolor[##1]% + {\bgroup + % \@@themaintextcolor==##1 is catched in \definecolor + \definecolor[\@@themaintextcolor][##1]% + \let\stoptextcolor\egroup}% + \startregistercolor[\@@themaintextcolor]% + \definecolor[\@@themaintextcolor][#1]% + \let\maintextcolor\@@themaintextcolor}} + +\let\stoptextcolor\relax + +%D The following hook permits proper support at the text +%D level. This definition actually belongs in another +%D module. (May need a different \MKIV\ implementation.) + +% \ifx\initializemaintextcolor\undefined + + \let\@@clprevcolor\empty + + \def\initializemaintextcolor + {% saveguard for setting text color to empty after + % it has been set + \doifnothing\@@cltextcolor + {\ifx\@@clprevcolor\empty\else + \let\@@cltextcolor\defaulttextcolor + \fi}% + \doifelsenothing\@@cltextcolor + {\let\maintextcolor\empty} + {\edef\@@clprevcolor{\@@cltextcolor}% + \let\maintextcolor\@@themaintextcolor + \doifelsenothing\@@cltextcolor % another saveguard + {\definecolor[\@@themaintextcolor][\defaulttextcolor]}% + {\definecolor[\@@themaintextcolor][\@@cltextcolor]}% + \doinitializemaintextcolor}} + + \def\doinitializemaintextcolor + {\appendtoks\starttextcolor[\@@themaintextcolor]\to\everystarttext + \appendtoks\stoptextcolor \to\everystoptext + \let\doinitializemaintextcolor\relax} + +% \fi + +\def\localstarttextcolor + {\ifx\maintextcolor\empty + \startcolormode\defaulttextcolor + \else + \startcolormode\maintextcolor + \fi} + +% \def\localstoptextcolor +% {\stopcolormode} +% +% better: + +\def\localstoptextcolor + {\restorecolormode} + +\def\restoretextcolor + {\ifx\maintextcolor\empty + \expandafter\dorestoretextcolor + \else + % obey main text color + \fi} + +\def\dorestoretextcolor + {\color[\defaulttextcolor]} + +%D We use some reserved names for local color components. +%D Consistent use of these scratch variables saves us +%D unneccessary hash entries. +%D +%D \starttyping +%D \@@cl@@r \@@cl@@g \@@cl@@b +%D \@@cl@@c \@@cl@@m \@@cl@@y \@@cl@@k +%D \@@cl@@s +%D \stoptyping +%D +%D We implement several conversion routines. +%D +%D \starttyping +%D \convertRGBtoCMYK {r} {g} {b} +%D \convertRGBtoGRAY {r} {g} {b} +%D \convertCMYKtoRGB {c} {m} {y} {k} +%D \convertCMYKtoGRAY {c} {m} {y} {k} +%D \convertCMYKtoCMY {c} {m} {y} {k} +%D \stoptyping +%D +%D The relation between \cap{Gray}, \cap{RGB} and \cap{CMYK} +%D is: +%D +%D \placeformula[-] +%D \startformula +%D G = .30r + .59g + .11b +%D = 1.0 - \min(1.0,\ .30c + .59m + .11y + k) +%D \stopformula +%D +%D When converting from \cap{CMYK} to \cap{RGB} we use the +%D formula: +%D +%D \placeformula[-] +%D \startformula +%D \eqalign +%D {r &= 1.0 - \min(1.0,\ c+k) \cr +%D g &= 1.0 - \min(1.0,\ m+k) \cr +%D b &= 1.0 - \min(1.0,\ y+k)} +%D \stopformula +%D +%D In the conversion routine the color components are calculated +%D in three digits precision. + +\def\realcolorvalue#1% + {\ifnum#1>\zerocount % important, first encountered in --modu supp-mpe + \ifnum#1<\plusten 0.00\the#1\else + \ifnum#1<\plushundred 0.0\the#1\else + \ifnum#1<\plusthousand 0.\the#1\else + 1\fi\fi\fi + \else 0\fi} + +% \def\doconvertCMYKtoRGB#1\k#2\to#3% +% {\ifdim#2\points>#1\points% >= problem, repaired 2/12/2002 +% \let#3\@@cl@@z % k >= color +% \else +% \colordimen\onepoint +% \advance\colordimen -#1\points +% \advance\colordimen -#2\points +% \multiply\colordimen \plusthousand +% \colorcount\colordimen +% \advance\colorcount \medcard +% \divide\colorcount \maxcard +% \edef#3{\realcolorvalue\colorcount}% +% \fi} + +\def\doconvertCMYKtoRGB#1\k#2\to#3% + {\colorcount\numexpr(\dimexpr\plusthousand\dimexpr\onepoint-#1\points-#2\points\relax\relax+\medcard)/\maxcard\relax + \ifnum\colorcount>\zeropoint + \edef#3{\realcolorvalue\colorcount}% + \else + \let#3\@@cl@@z + \fi} + +\def\convertCMYKtoRGB#1#2#3#4% + {\doconvertCMYKtoRGB#1\k#4\to\@@cl@@r + \doconvertCMYKtoRGB#2\k#4\to\@@cl@@g + \doconvertCMYKtoRGB#3\k#4\to\@@cl@@b} + +% \def\doconvertRGBtoCMYK#1\to#2% +% {\colordimen#1\points +% \multiply\colordimen \plusthousand +% \colorcount\colordimen +% \advance\colorcount \medcard +% \divide\colorcount \maxcard +% \colorcount-\colorcount +% \advance\colorcount \plusthousand +% \edef#2{\realcolorvalue\colorcount}} + +\def\doconvertRGBtoCMYK#1\to#2% + {\colorcount\numexpr\plusthousand-(\dimexpr\plusthousand\dimexpr#1\points\relax\relax+\medcard)/\maxcard\relax + \edef#2{\realcolorvalue\colorcount}} + +\def\convertRGBtoCMYK#1#2#3% + {\doconvertRGBtoCMYK#1\to\@@cl@@c + \doconvertRGBtoCMYK#2\to\@@cl@@m + \doconvertRGBtoCMYK#3\to\@@cl@@y + \let\@@cl@@k\@@cl@@z} + +%D The following switch is mainly meant for (hidden) +%D documentation purposes. + +\def\nGRAYfactor{333.333} +\def\rGRAYfactor{\ifweightGRAY300\else\nGRAYfactor\fi} +\def\gGRAYfactor{\ifweightGRAY590\else\nGRAYfactor\fi} +\def\bGRAYfactor{\ifweightGRAY110\else\nGRAYfactor\fi} + +% \def\convertRGBtoGRAY#1#2#3% +% {\colordimen#1\points +% \colordimen\rGRAYfactor\colordimen +% \colorcount\colordimen +% \colordimen#2\points +% \colordimen\gGRAYfactor\colordimen +% \advance\colorcount \colordimen +% \colordimen#3\points +% \colordimen\bGRAYfactor\colordimen +% \advance\colorcount \colordimen +% \advance\colorcount \medcard +% \divide\colorcount \maxcard +% \edef\@@cl@@s{\realcolorvalue\colorcount}} + +\def\convertRGBtoGRAY#1#2#3% + {\colorcount\numexpr + (\dimexpr\rGRAYfactor\dimexpr#1\points\relax\relax+ + \dimexpr\gGRAYfactor\dimexpr#2\points\relax\relax+ + \dimexpr\bGRAYfactor\dimexpr#3\points\relax\relax+ + \medcard)/\maxcard + \relax + \edef\@@cl@@s{\realcolorvalue\colorcount}} + +\def\convertCMYKtoGRAY#1#2#3#4% + {\convertCMYKtoRGB{#1}{#2}{#3}{#4}% + \convertRGBtoGRAY\@@cl@@r\@@cl@@g\@@cl@@b} + +% \def\doconvertCMYKtoCMY#1\k#2\to#3% +% {\colordimen#1\points +% \advance\colordimen #2\points\relax +% \ifdim\colordimen>\onepoint +% \colordimen\onepoint +% %\else +% % \colordimen\colordimen +% \fi +% \multiply\colordimen \plusthousand +% \colorcount\colordimen +% \advance\colorcount \medcard +% \divide\colorcount \maxcard +% \edef#3{\realcolorvalue\colorcount}} + +\def\doconvertCMYKtoCMY#1\k#2\to#3% + {\colorcount\numexpr(\dimexpr\plusthousand\dimexpr#1\points+#2\points\relax\relax+\medcard)/\maxcard\relax + \ifnum\colorcount>\plusthousand + \let#3\@@cl@@o + \else + \edef#3{\realcolorvalue\colorcount}% + \fi} + +\def\convertCMYKtoCMY#1#2#3#4% + {\doconvertCMYKtoCMY#1\k#4\to\@@cl@@c + \doconvertCMYKtoCMY#2\k#4\to\@@cl@@m + \doconvertCMYKtoCMY#3\k#4\to\@@cl@@y + \let\@@cl@@k\@@cl@@z} + +%D Before we present the color macros, we first define the +%D setup command. This command takes care of setting up the +%D booleans that control local and global behavior (more on +%D that later) and conversion to other color spaces. + +\let\currentspotcolor \empty +\let\previousspotcolor\empty + +%D The tests depend on the use of constants. If we use the \MKIV\ +%D method we can share more. + +\def\doifcolorelse#1% + {\ifcsname\??cr\ifcsname\??cr\currentpalet#1\endcsname\currentpalet\fi#1\endcsname + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +\def\doifcolor#1% + {\ifcsname\??cr\ifcsname\??cr\currentpalet#1\endcsname\currentpalet\fi#1\endcsname + \expandafter\firstofoneargument + \else + \expandafter\gobbleoneargument + \fi} + +%D There are a couple of different color switching macros, +%D the local ones can be used to speed up things (only in \MKII). + +\def\localstartcolor + {\ifincolor + \localcolortrue + \expandafter\doglobalstartcolor + \else + \expandafter\noglobalstartcolor + \fi} + +\def\localstopcolor + {\ifincolor + \doglobalstopcolor + \else + \noglobalstopcolor + \fi} + +\unexpanded\def\startcolor + {\ifincolor + \expandafter\doglobalstartcolor + \else + \expandafter\noglobalstartcolor + \fi} + +\unexpanded\def\stopcolor + {\ifincolor + \doglobalstopcolor + \else + \noglobalstopcolor + \fi} + +%D This macros call the global color switching ones. Starting +%D a global, i.e. a possible page boundary crossing, color +%D mode also sets a \type{\mark} in \TEX's internal list. + +\newcount\colorlevel + +\letvalue{\??cl0C}\empty % saved color +\letvalue{\??cl0S}\empty % stop command + +%D We keep a positive color stack for foreground colors, and +%D a negative one for backgrounds. Not that brilliant a +%D solution, but it suits. The signs are swapped when the +%D page ornaments are typeset. + +\let\@@colorplus \plusone +\let\@@colorminus\minusone + +\def\@@currentcolorname {\??cl\the\colorlevel C} +\def\@@currentcolorstop {\??cl\the\colorlevel S} +%def\@@currenttransparent{\??cl\the\colorlevel T} + +\letvalue{\??cl*\s!black}\s!black + +\def\currentcolorname + {\csname + \ifcsname\@@currentcolorname\endcsname + \expandafter\ifx\csname\@@currentcolorname\endcsname\empty + \??cl*\s!black + \else + \@@currentcolorname + \fi + \else + \??cl*\s!black + \fi + \endcsname} + +\def\outercolorname + {\ifcsname\@@currentcolorname\endcsname + \expandafter\ifx\csname\@@currentcolorname\endcsname\empty + \s!black + \else + currentcolor% + \fi + \else + \s!black + \fi} + +% not the following, because we need a different tag in order to trick the stack +% +% \def\outercolorname{\executeifdefined\@@currentcolorname\s!black} +% +% \def\startcurrentcolor{\expanded{\startcolor[\s!black]\noexpand\startcolor[\outercolorname]}} +% \def\stopcurrentcolor {\stopcolor\stopcolor} +% +% test case: +% +% \setupcolors[state=start,textcolor=red] +% \starttext +% red +% \color[green]{green +% \startMPcode +% label(\sometxt{green\color[blue]{blue}green}, origin) withcolor red; +% draw fullcircle scaled 1cm xscaled 2; +% \stopMPcode +% green} +% red +% \stoptext + +\def\dodoglobalstartcolor + {\global\@EA\let\@EA\@@currentcolor\csname\@@currentcolorname\endcsname + \global\advance\colorlevel \@@colorplus + \global\@EA\let\csname\@@currentcolorname\endcsname\@@askedcolor + %\debuggerinfo\m!colors + % {start \@@askedcolor\space at level \the\colorlevel}% + \ifx\@@askedcolor\empty + \global\@EA\let\csname\@@currentcolorname\endcsname\@@currentcolor + \global\@EA\let\csname\@@currentcolorstop\endcsname\donoglobalstopcolor + \else\ifx\@@askedcolor\@@currentcolor + \global\@EA\let\csname\@@currentcolorstop\endcsname\donoglobalstopcolor + \else + \doifcolorelse\@@askedcolor + {%\docolormark\@@askedcolor + \ifpermitcolormode\docolormark\@@askedcolor\fi + \global\@EA\let\csname\@@currentcolorstop\endcsname\dodoglobalstopcolor + \startcolormode\@@askedcolor} + {\global\@EA\let\csname\@@currentcolorstop\endcsname\donoglobalstopcolor + \showmessage\m!colors3\@@askedcolor\empty}% + \fi\fi} + +\def\doglobalstartcolor[#1]% + {\edef\@@askedcolor{#1}% + \ifcase\colorlevel\relax + \ifx\@@askedcolor\empty + \global\@EA\let\csname\@@currentcolorstop\endcsname\empty + \else + \dodoglobalstartcolor + \fi + \else + \dodoglobalstartcolor + \fi + \ignorespaces} + +\def\noglobalstartcolor[#1]% + {} + +\def\dodoglobalstopcolor + {\ifcase\colorlevel \else + \donoglobalstopcolor + \global\@EA\let\@EA\@@previouscolor\csname\@@currentcolorname\endcsname + \ifcase\colorlevel\relax + \ifpermitcolormode + \docolormark\empty + \conditionalstoptransparency + \dostopcolormode + \fi + \else % let's do a bit redundant testing here + \docolormark\@@previouscolor + \ifx\@@previouscolor\empty + \ifpermitcolormode + \conditionalstoptransparency + \dostopcolormode + \fi + \else + \doifcolorelse\@@previouscolor + {\ifx\@@currentcolor\@@previouscolor\else + % alternatively we could let \startcolormode handle this + \ifpermitcolormode + \conditionalstoptransparency % really needed + % more safe but less efficient: \dostopcolormode + \fi + \startcolormode\@@previouscolor + \fi} + {\ifpermitcolormode + \conditionalstoptransparency + \dostopcolormode + \fi}% + \fi + \fi + \fi} + +\def\donoglobalstopcolor + {\ifcase\colorlevel \else + \global\@EA\let\@EA\@@currentcolor\csname\@@currentcolorname\endcsname + %\debuggerinfo{\m!colors} + % {stop \@@currentcolor\normalspace at level \the\colorlevel}% + \global\advance\colorlevel \@@colorminus + \fi} + +\def\doglobalstopcolor + {\csname\@@currentcolorstop\endcsname} + +\let\noglobalstopcolor\relax + +\let\faststartcolor\doglobalstartcolor +\let\faststopcolor \doglobalstopcolor + +%D We don't use grouping and save each stop alternative. This +%D permits be especially useful in for instance local color +%D support in verbatim. Using \type{\bgroup}||\type{\egroup} +%D pairs could interfere with calling commands + +%D This color mechanism takes care of nested colors, like in: +%D +%D \startbuffer +%D \color[green]{groen \color[green]{groen \color[red]{rood}} groen} +%D \color[green]{groen \color[]{groen \color[red]{rood}} groen} +%D \color[green]{groen \color[red]{rood \color[red]{rood}} groen} +%D \color[green]{groen \color[green]{groen \color[]{groen}} groen} +%D \color[green]{groen \color[red]{rood} groen} +%D \color[green]{groen \color[]{groen} groen} +%D \color[]{zwart \color[red]{rood} zwart} +%D \color[]{zwart} +%D \stopbuffer +%D +%D \typebuffer +%D +%D or +%D +%D \startvoorbeeld +%D \startlines +%D \getbuffer +%D \stoplines +%D \stopvoorbeeld +%D +%D Crossing page boundaries is of course also handled. +%D Undefined or empty color specifications are treated as +%D efficient as possible. +%D +%D \startbuffer +%D \startcolor[green] +%D [green] \input tufte [green] \par +%D \startcolor[] +%D [green] \input knuth [green] \par +%D \startcolor[red] +%D [red] \input tufte [red] \par +%D \startcolor[yellow] +%D [yellow] \input knuth [yellow] \par +%D \stopcolor +%D [red] \input tufte [red] \par +%D \stopcolor +%D [green] \input knuth [green] \par +%D \stopcolor +%D [green] \input tufte [green] \par +%D \stopcolor +%D \stopbuffer +%D +%D \startpacked +%D \getbuffer +%D \stoppacked +%D +%D These quotes are typeset by saying: +%D +%D \typebuffer + +%D We already mentioned that colors interfere with building +%D the pagebody. This means that when the page is composed, +%D the colors temporary have to be reset. After the page is +%D shipped out, we have to revive the current color. +%D +%D We use \type{\mark}s to keep track of colors across page +%D boundaries. Unfortunately standard \TEX\ supports only one mark, +%D and using this one for color support only would be a waste. +%D We therefore use an adapted version of J.~Fox's multiple mark +%D mechanism as (re|)|implemented in \module{supp-mrk}. + +\doifdefinedelse{rawnewmark} + {\rawnewmark\colormark} + {\let\colormark\gobbleoneargument} + +%D Using this mark mechanism with lots of colors has one +%D major drawback: \TEX's memory tends to overflow when +%D very colorful text is stored in a global box. Even worse is that +%D the processing time grows considerably. We therefore support +%D local as well as global color switching. +%D +%D Of the next macros, \type {\popcolor} is to be used after +%D the actual \type {\shipout} and \type {\startcolorpage} and +%D \type {\stopcolorpage} are called when entering and leaving +%D the \type {\pagebody} builder. In case of emergencies +%D \type {\pushcolor} can be used to undo the current color, +%D for instance when insertions are appended to the page. +%D +%D Out of efficiency we only use marks when needed. The next +%D macro tries to find out if indeed a mark should be set. +%D This macro uses the boolean \type {\ifinpagebody}, which can +%D be defined and set in the module that handles the pagebody. + +\def\docolormark#1% + {\iflocalcolor \else \ifinpagebody \else \ifinframed \else + \dodocolormark{#1}% + \fi \fi \fi} + +\let\lastcolormark=\empty + +\def\dodocolormark#1% + {\edef\newcolormark{#1}% + \ifx\newcolormark\lastcolormark\else + \global\let\lastcolormark\newcolormark + \@EA\rawsetmark\@EA\colormark\@EA{\lastcolormark}% + \fi} + +%D \macros +%D {pushcolor, popcolor} +%D +%D Pushing the current state in the output routine simply comes +%D to resetting the color to black, while popping restores the +%D color state to that of before the break. + +\def\topofpagecolor{\rawgetbotmark\colormark} % see postponing + +\def\pushcolor + {\stopcolormode} + +\def\popcolor + {\doifsomething{\rawgetbotmark\colormark} + {%\debuggerinfo\m!colors{popping \getbotmark\colormark}% + \startcolormode{\rawgetbotmark\colormark}}} + +\def\popsplitcolor + {\getsplitmarks\colormark % hier wel + \doifsomething{\rawgetsplitbotmark\colormark} + {%\debuggerinfo\m!colors{split popping \getsplitbotmark\colormark}% + \startcolormode{\rawgetsplitbotmark\colormark}}} + +\appendtoks\pushcolor \to\everypushproperties +\appendtoks\popcolor \to\everypopproperties +\appendtoks\popsplitcolor\to\everypopsplitproperties + +% Private macro: only needed in test cases (like multiple +% seperations in one file); no user command! + +\def\resynccolor + {\ifcase\pagetotal % \ifdim\pagetotal=\zeropoint + \popcolor + \else\ifx\@@currentcolor\empty + \ifx\maintextcolor\empty\else + \startcolormode\maintextcolor + \fi + \else + \startcolormode\@@currentcolor + \fi\fi} + +% weird stuff + +\def\pushpostponedpagecolor + {\edef\savedtopofpagecolor{\topofpagecolor}% + \doifsomething\savedtopofpagecolor\restorecolormode} % \stopcolormode + +\def\poppostponedpagecolor + {\doifsomething\savedtopofpagecolor\startcolormode\savedtopofpagecolor} + +%D \macros +%D {startcolorpage, stopcolorpage} +%D +%D Local use can be forced with the next two macros. Nesting +%D is still supported but colors are no longer marked. +%D +%D The next implementation makes (simple) color separation more +%D easy. It also supports nested colors in page backgrounds +%D and texts. + +\def\startcolorpage + {\bgroup + \let\@@colorplus \minusone + \let\@@colorminus\plusone + \let\docolormark\gobbleoneargument + \edef\savedcolorlevel{\the\colorlevel}% + \global\colorlevel\zerocount % before \localstartcolor of + \ifx\maintextcolor\empty % course, ugly bug removed + \localstartcolor[\defaulttextcolor]% + \else + \localstartcolor[\maintextcolor]% + \fi} + +\def\stopcolorpage + {\localstopcolor + \global\colorlevel\savedcolorlevel + \egroup} + +\appendtoks \startcolorpage\to\everystarttextproperties +\prependtoks\stopcolorpage \to\everystoptextproperties + +%D We want color support to be similar to font support and +%D therefore implement \type{\color} using grouping. +%D +%D When \type {\somecolor} is issued, we can savely assume +%D grouping. Using \type {\groupedcommand} here (i.e.\ the +%D definition of \type {\color}) is unsafe because in +%D interferes with for instance switching attributes. + +\unexpanded\def\color[#1]% + {\groupedcommand{\startcolor[#1]}\stopcolor} + +%D This implementation enables use of defined colors like: +%D +%D \starttyping +%D Look at the {\brightgreen bright} side of life and get +%D yourself no \red{red} head! +%D \stoptyping + +%D Also wrong, test in combinations: \type{...{}{\red test}} +%D +%D \def\switchtocolor[#1]% +%D {\startcolor[#1]\aftergroup\stopcolor} + +\def\switchtocolor[#1]% grouping is realy needed, else migration + {\bgroup\startcolor[#1]\aftergroup\stopcolor\aftergroup\egroup} + +\unexpanded\def\color[#1]% + {\groupedcommand{\startcolor[#1]}\stopcolor} + +\unexpanded\def\graycolor[#1]% not \gray because this is a color + {\groupedcommand{\RGBsupportedfalse\CMYKsupportedfalse\SPOTsupportedfalse\startcolor[#1]}\stopcolor} + +\unexpanded\def\colored[#1]% + {\groupedcommand{\definecolor[@colored@][#1]\startcolor[@colored@]}\stopcolor} + +%D We can speed the following macros a bit up, but this +%D hardly pays off; they are only used in the manual. + +\def\realcolorformat#1% + {\ifnum#1<\plusten 0.00\the#1\else + \ifnum#1<\plushundred 0.0\the#1\else + \ifnum#1<\plusthousand 0.\the#1\else + 1.000\fi\fi\fi} + +\def\dodoformatcolor#1% + {\colordimen#1\points\relax + \ifdim\colordimen>\onepoint + \colordimen\onepoint + \fi + \multiply\colordimen \plusthousand + \colorcount\colordimen + \advance\colorcount \medcard + \divide\colorcount \maxcard \relax + \realcolorformat\colorcount} + +\def\doformatcolorR#1:#2:#3:#4:#5\od + {\dodoformatcolor{#1}\colorformatseparator + \dodoformatcolor{#2}\colorformatseparator + \dodoformatcolor{#3}} + +\def\doformatcolorC#1:#2:#3:#4:#5:#6\od + {\dodoformatcolor{#1}\colorformatseparator + \dodoformatcolor{#2}\colorformatseparator + \dodoformatcolor{#3}\colorformatseparator + \dodoformatcolor{#4}} + +\def\doformatcolorS#1:#2:#3\od + {\dodoformatcolor{#1}} + +\def\doformatcolorP#1:#2:#3:#4:#5:#6\od + {#1\colorformatseparator + \dodoformatcolor{#2}\colorformatseparator + \dodoformatcolor{#3}\colorformatseparator + \dodoformatcolor{#4}\colorformatseparator} + +\def\doformatcolor#1:% + {\csname doformatcolor#1\endcsname} + +\def\colorvalue + {\dowithcolor\doformatcolor} + +\def\doformatgrayR#1:#2:#3:#4:#5\od + {\convertRGBtoGRAY{#1}{#2}{#3}% + \dodoformatcolor\@@cl@@s} + +\def\doformatgrayC#1:#2:#3:#4:#5:#6\od + {\convertCMYKtoGRAY{#1}{#2}{#3}{#4}% + \dodoformatcolor\@@cl@@s} + +\def\doformatgrayS#1:#2:#3\od + {\dodoformatcolor{#1}} + +% \def\doformatgrayP#1:#2:#3:#4:#5:#6\od +% {\convertSPOTtoGRAY{#1}{#2}{#3}{#4}% +% \dodoformatcolor\@@cl@@s} + +\def\doformatgrayP#1:#2:#3:#4:#5:#6\od + {todo} + +\def\doformatgray#1:% + {\csname doformatgray#1\endcsname} + +\def\grayvalue + {\dowithcolor\doformatgray} + +%D \macros +%D {localstartraster,localstopraster, +%D startraster,stopraster} +%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. +%D +%D \starttyping +%D \def\localstartraster[#1]% +%D {\doifelsenothing{#1} +%D {\dostartgraymode\@@rsscreen} +%D {\dostartgraymode{#1}}} +%D +%D \def\localstopraster +%D {\dostopgraymode} +%D +%D \let\startraster\localstartraster +%D \let\stopraster \localstopraster +%D \stoptyping +%D +%D The next alternative is slower, since it works on top of the +%D color (stack) mechanism, but it does provide nesting. + +\def\dosetrastercolor#1% + {\edef\@@cl@@s{#1}% + \ifx\@@cl@@s\empty + \let\@@cl@@s\@@rsscreen + \fi + \let\@@cl@@t\@@cl@@z % else we get rogue + \let\@@cl@@a\@@cl@@z % transpancies + \setevalue{\??cr\??rs}{\colorSpattern}} + +% beware, don't add extra grouping, else color in tables +% fails + +\def\localstartraster[#1]% + {\ifincolor\dosetrastercolor{#1}\localstartcolor[\??rs]\fi} + +\def\startraster[#1]% + {\ifincolor\dosetrastercolor{#1}\startcolor[\??rs]\fi} + +\def\localstopraster{\ifincolor\localstopcolor\fi} +\def\stopraster {\ifincolor\stopcolor\fi} + +\def\raster[#1]{\groupedcommand{\startraster[#1]}{\stopraster}} + +%D Palets use an auxiliary macro: + +\def\dodefinepaletcolor#1#2#3% + {\doifassignmentelse{#3} + {% == \definepalet[test][xx={y=.4}] + \definecolor[\??pa#1:#2][#3]% + \iffreezecolors\@EA\setevalue\else\@EA\setvalue\fi{\??cr#1:#2}{\csname\??cr\??pa#1:#2\endcsname}} + {% == \definepalet[test][xx=green] + \doifdefinedelse{\??cr#3} + {\iffreezecolors\@EA\setevalue\else\@EA\setvalue\fi{\??cr#1:#2}{\csname\??cr#3\endcsname}} + {\letvalue{\??cr#1:#2}\colorXpattern}}} + +%D \MP\ related conversions: + +\def\scaledMPcolor#1#2% + {\ifMPgraphics + \handlecolorwith\doMPcolor + \csname\??cr + \ifcsname\??cr\currentpalet#2\endcsname\currentpalet\fi + #2\endcsname + :::::::\end#1\end + \else + #2% + \fi} + +\def\MPcolor{\scaledMPcolor1} + +%D Before we had transparency available, the following +%D conversion macro was available: +%D +%D \starttyping +%D \def\doMPcolor#1:#2:#3:#4:#5:#6:#7:#8\end +%D {\if #1R(#2,#3,#4)% +%D \else\if#1C\ifMPcmykcolors cmyk(#2,#3,#4,#5)\else(1-#2-#5,1-#3-#5,1-#4-#5)\fi +%D \else\if#1S(#2,#2,#2)% +%D \else (0,0,0)% +%D \fi\fi\fi} +%D \stoptyping +%D +%D In order to be useful, this macro is to be fully +%D expandabele. + +\def\doMPcolor#1:% #1 can be \relax ! ! ! i.e. an empty color + {\csname MPc\@EA\ifx\csname MPc\string#1\endcsname\relax B\else#1\fi\endcsname} + +\def\MPcR{\doMPrgb} +\def\MPcC{\ifMPcmykcolors\@EA\doMPcmykY\else\@EA\doMPcmykN\fi} +\def\MPcS{\doMPgray} +\def\MPcP{\ifMPspotcolors\@EA\doMPspotY\else\@EA\doMPspotN\fi} +\def\MPcB{\doMPblack} + +\def\transparentMP {transparent} +\def\cmykMP {scaledcmyk} +\def\cmykASrgbMP {scaledcmykasrgb} % not really needed any more +\def\rgbMP {scaledrgb} +\def\grayMP {scaledgray} +\def\spotMP {spotcolor} + +\def\doMPtransparent#1#2:#3:#4\end + {\ifcase#2\space(#1)\else\transparentMP(#2,#3,(#1))\fi} + +\def\doMPgray#1:#2\end#3\end + {\doMPtransparent{\grayMP(#1,#3)}#2\end} + +\def\doMPrgb#1:#2:#3:#4\end#5\end + {\doMPtransparent{\rgbMP(#1,#2,#3,#5)}#4\end} + +\def\doMPcmykY#1:#2:#3:#4:#5\end#6\end + {\doMPtransparent{\cmykMP(#1,#2,#3,#4,#6)}#5\end} + +\def\doMPcmykN#1:#2:#3:#4:#5\end#6\end + {\doMPtransparent{\cmykASrgbMP(#1,#2,#3,#4,#6)}#5\end} + +\def\doMPspotY#1:#2:#3:#4:#5\end#6\end % best make #3 same as #1 when empty + {\doMPtransparent{multitonecolor("#1",#2,"#3","#4")}#5\end} + +\def\doMPspotN#1:#2:#3:#4:#5\end#6\end + {\scaledMPcolor{#4}{#1}} + +\def\doMPblack#1\end#2\end + {\unknownMPcolor} + +\def\unknownMPcolor + {(0,0,0)} + +\let\processMP\spotMP % for some time, will become obsolete, brrr + +%D \PDF\ related conversions: + +\def\PDFcolor #1{\handlecolorwith\doPDFcolor \csname\??cr#1\endcsname:::::::\end} +\def\PDFcolorvalue#1{\handlecolorwith\doPDFcolorvalue\csname\??cr#1\endcsname:::::::\end} +\def\FDFcolor #1{\handlecolorwith\doFDFcolor \csname\??cr#1\endcsname:::::::\end} + +\def\doPDFcolor#1:#2:#3:#4:#5:#6:#7:#8\end + {\if #1R#2 #3 #4 rg% + \else\if#1C#2 #3 #4 #5 k% + \else\if#1S#2 g% + \else\if#1P#5 g% + \else 0 g% + \fi\fi\fi\fi} + +\def\doPDFcolorvalue#1:#2:#3:#4:#5:#6:#7:#8\end + {\if #1R#2 #3 #4% + \else\if#1C#2 #3 #4 #5% + \else\if#1S#2% + \else\if#1P#5% + \else 0% + \fi\fi\fi\fi} + +\def\doFDFcolor#1:#2:#3:#4:#5:#6:#7:#8\end + {[\if #1R#2 #3 #4% + \else\if#1C#2 #3 #4 #5% + \else\if#1S#2% + \else\if#1P#5% + \else 0% + \fi\fi\fi\fi]} + +\def\internalspotcolorname#1{\handlecolorwith\dointernalspotcolorname\csname\??cr#1\endcsname:::::::\end} +\def\internalspotcolorsize#1{\handlecolorwith\dointernalspotcolorsize\csname\??cr#1\endcsname:::::::\end} + +\def\dointernalspotcolorname#1:#2:#3:#4:#5:#6:#7:#8\end{\if#1P\ifcase0#3 #1\else#2\fi\else#1\fi} +\def\dointernalspotcolorsize#1:#2:#3:#4:#5:#6:#7:#8\end{\if#1P\ifcase0#3 0\else#3\fi\else 0\fi} + +%D Slow but ok \unknown + +\def\colorcomponents#1% might be broken + {\startnointerference + \localcolortrue + \globallet\thecolorcomponents\empty + \def\doexeccolorR ##1:##2:##3:##4:##5\od{\gdef\thecolorcomponents{r=\twodigitrounding{##1} g=\twodigitrounding{##2} b=\twodigitrounding{##3}}}% + \def\doexeccolorC##1:##2:##3:##4:##5:##6\od{\gdef\thecolorcomponents{c=\twodigitrounding{##1} m=\twodigitrounding{##2} y=\twodigitrounding{##3} k=\twodigitrounding{##4}}}% + \def\doexeccolorS ##1:##2:##3\od{\gdef\thecolorcomponents{s=\twodigitrounding{##1}}}% + \def\doexeccolorP##1:##2:##3:##4:##5:##6\od{\gdef\thecolorcomponents{p=\twodigitrounding{##4} n=##1}}% + \let\doexeccolorPindex\doexeccolorP + \backgroundline[#1]{}% + \stopnointerference + \thecolorcomponents} + +\def\transparencycomponents#1% + {\startnointerference + \localcolortrue + \globallet\thetransparencycomponents\empty + \def\doexeccolorR ##1:##2:##3:##4:##5\od{\gdef\thetransparencycomponents{a=\twodigitrounding{##4} t=\twodigitrounding{##5}}}% + \def\doexeccolorC##1:##2:##3:##4:##5:##6\od{\gdef\thetransparencycomponents{a=\twodigitrounding{##5} t=\twodigitrounding{##6}}}% + \def\doexeccolorS ##1:##2:##3\od{\gdef\thetransparencycomponents{a=\twodigitrounding{##2} t=\twodigitrounding{##3}}}% + \def\doexeccolorP##1:##2:##3:##4:##5:##6\od{\gdef\thetransparencycomponents{a=\twodigitrounding{##5} t=\twodigitrounding{##6}}}% + \let\doexeccolorPindex\doexeccolorP + \backgroundline[#1]{}% + \stopnointerference + \thetransparencycomponents} + +%D \macros +%D {everyshapebox} +%D +%D A terrible hack, needed because we cannot have marks in +%D shape boxes. + +\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 new file mode 100644 index 000000000..1bceb5aa7 --- /dev/null +++ b/tex/context/base/colo-ini.mkiv @@ -0,0 +1,1091 @@ +%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. + +\registerctxluafile{colo-ini}{1.000} +\registerctxluafile{lpdf-col}{1.000} + +\unprotect + +%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). + +\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\ifconvertGRAY \convertGRAYtrue +\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 + +\let\colorlist \empty +\let\currentspotcolor \empty +\let\allspotcolors \empty +\let\usedspotcolors \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 + +\unexpanded\def\definecolor {\dodoubleargument\dodefinecolor} +\unexpanded\def\defineglobalcolor {\dodoubleargument\dodefineglobalcolor} +\unexpanded\def\definenamedcolor {\dodoubleargument\dodefinenamedcolor} +\unexpanded\def\definespotcolor {\dotripleargument\dodefinespotcolor} +\unexpanded\def\definemultitonecolor{\doquadrupleempty\dodefinemultitonecolor} + +%D \macros +%D {startcolor,stopcolor, +%D faststartcolor,faststopcolor, +%D startraster,stopraster,raster, +%D color,graycolor} +%D +%D The local and global and raster commands are here just +%D for compatibility with \MKII. +%D +%D \showsetup{startcolor} +%D +%D \macros +%D {color,graycolor} +%D +%D This leaves the simple color command: +%D +%D \showsetup{color} +%D \showsetup{graycolor} +%D +%D This leaves the simple color command: +%D +%D \showsetup{color} +%D \showsetup{graycolor} + + \def\switchtocolor [#1]{\getvalue{#1}} +\unexpanded\def\color [#1]{\groupedcommand{\doactivatecolor{#1}}{}} +\unexpanded\def\startcolor [#1]{\begingroup\doactivatecolor{#1}} +\unexpanded\def\stopcolor {\endgroup} +\unexpanded\def\graycolor [#1]{\groupedcommand{\dosetcolormodel{gray}\getvalue{#1}}{}} +\unexpanded\def\colored [#1]{\groupedcommand{\definecolor[@colored@][#1]\doactivatecolor{@colored@}}{}} +\unexpanded\def\fastcolored [#1]#2{\begingroup\dodefinefastcolor[@colored@][#1]\doactivatecolor{@colored@}#2\endgroup} + \def\predefinecolor [#1]{\flushatshipout{\hbox{\color[#1]{}}}} + \def\predefineindexcolor[#1]{\flushatshipout{\hbox{\color[#1]{}}}} + \unexpanded\def\startcolorpage {\startcolor[\ifx\maintextcolor\empty\defaulttextcolor\else\maintextcolor\fi]} + \unexpanded\def\stopcolorpage {\stopcolor} + \unexpanded\def\startraster [#1]{\dosetrastercolor{#1}} + \unexpanded\def\stopraster {} + \def\raster [#1]{\groupedcommand{\dosetrastercolor{#1}}{}} + \def\faststartcolor [#1]{\doactivatecolor{#1}} + \def\faststopcolor {} +\unexpanded\def\dosetcolorattribute#1#2{\ifcsname#1#2\endcsname\doactivatecolor{\csname#1#2\endcsname}\fi} + +\let\grey\graycolor + +%D Stacking: + +% \colormodelattribute \colorattribute \transparencyattribute + +\newcount\currentcolornesting + +\unexpanded\def\pushcolor[#1]% + {\global\advance\currentcolornesting\plusone + \expandafter\edef\csname\??cl:s:\number\currentcolornesting\endcsname + {\attribute\colormodelattribute \the\attribute\colormodelattribute + \attribute\colorattribute \the\attribute\colorattribute + \attribute\transparencyattribute\the\attribute\transparencyattribute + \space}% stack + \doactivatecolor{#1}} + +\unexpanded\def\popcolor + {\csname\??cl:s:\number\currentcolornesting\endcsname + \global\advance\currentcolornesting\minusone} + +%D \macros +%D {startcurrentcolor,stopcurrentcolor} + +\unexpanded\def\startcurrentcolor{\startcolor[\outercolorname]} +\unexpanded\def\stopcurrentcolor {\stopcolor} + +%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 + +\unexpanded\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 + {\showcolormessage\m!colors4\colorstyle} + {\showcolormessage\m!colors5\colorstyle}% + \stopreadingfile} + +\let\usecolors\setupcolor + +% check: \startcolormode + +%D \macros +%D {definetransparency} +%D +%D This command numbers to names: + +\unexpanded\def\definetransparency + {\dodoubleargument\dodefinetransparency} + +\unexpanded\def\setupcolors + {\dosingleargument\dosetupcolors} + +\let\showcolormessage\gobblethreearguments + +\newtoks\everysetupcolors + +\def\dosetupcolors[#1]% some no longer make sense in MkIV + {\getparameters[\??cl][#1]% + \doifelse\@@clspot\v!yes + \SPOTsupportedtrue + \SPOTsupportedfalse + \doifelse\@@clreduction\v!yes + \reduceCMYKtrue + \reduceCMYKfalse + \doifelse\@@clexpansion\v!yes + \freezecolorstrue + \freezecolorsfalse + \doifelse\@@clfactor\v!no + \weightGRAYfalse + \weightGRAYtrue + \doifelse\@@clrgb\v!no + {\ifRGBsupported \showcolormessage\m!colors {9}\v!rgb \RGBsupportedfalse \fi} + {\ifRGBsupported \else\showcolormessage\m!colors{10}\v!rgb \RGBsupportedtrue \fi}% + \doifelse\@@clcmyk\v!no + {\ifCMYKsupported \showcolormessage\m!colors {9}\v!cmyk \CMYKsupportedfalse\fi} + {\ifCMYKsupported\else\showcolormessage\m!colors{10}\v!cmyk \CMYKsupportedtrue \fi}% + \doifelse\@@clmpcmyk\v!no + {\ifMPcmykcolors \showcolormessage\m!colors {9}{\v!mp\v!cmyk}\MPcmykcolorsfalse \fi} + {\ifMPcmykcolors \else\showcolormessage\m!colors{10}{\v!mp\v!cmyk}\MPcmykcolorstrue \fi}% + \doifelse\@@clmpspot\v!no + {\ifMPspotcolors \showcolormessage\m!colors {9}{\v!mp\v!spot}\MPspotcolorsfalse \fi} + {\ifMPspotcolors \else\showcolormessage\m!colors{10}{\v!mp\v!spot}\MPspotcolorstrue \fi}% + \preferGRAYfalse + \convertGRAYtrue + \processaction + [\@@clconversion] + [ \v!yes=>\preferGRAYtrue, + \v!no=>\convertGRAYfalse, + \v!never=>\convertGRAYfalse, + \v!always=>\preferGRAYtrue\RGBsupportedfalse\CMYKsupportedfalse]% + \ifRGBsupported + \converttoGRAYfalse + \forcegrayMPcolorsfalse + \else\ifCMYKsupported + \converttoGRAYfalse + \forcegrayMPcolorsfalse + \convertMPcolorstrue + \ifreduceCMYK + \reduceMPcolorstrue + \fi + \else + \ifconverttoGRAY\else\showcolormessage\m!colors{11}\empty\fi + \converttoGRAYtrue + \forcegrayMPcolorstrue + \convertMPcolorsfalse + \reduceMPcolorsfalse + \fi\fi + \doifelse\@@clstate\v!stop + {\incolorfalse\forcegrayMPcolorstrue}% + {\ifincolor\else\showcolormessage\m!colors1\colorstyle\fi\incolortrue\let\@@clstate\v!start}% + \dosetupcolormodel + \the\everysetupcolors} + +%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. + +\unexpanded\def\definepalet + {\dodoubleargument\dodefinepalet} + +\def\dodefinepalet[#1][#2]% + {\doifassignmentelse{#2} + {%\showcolormessage\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]}}}} + +\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 + +\unexpanded\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 + \showcolormessage\m!colors7\currentpalet + \let\currentpalet\empty + \fi\fi + \initializemaintextcolor} + +%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. + +\unexpanded\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 + {\ifcsname\??cr#2:\recurselevel\endcsname + \setevalue{\??cr#1:\recurselevel}{\csname\??cr#2:\recurselevel\endcsname}% + \else + \exitloop + \fi}}% + \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 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 In \MKIV\ we don't support color separation as we might now assume +%D that printing houses have the right programs to do it themselves. +%D The \MKII\ color separator was implemented as part of a project +%D that needed. If it's ever needed in \MKIV\ i'll do it in the +%D backend. + +\let\doifseparatingcolorselse\secondoftwoarguments +\let\doifcolorchannelelse \secondofthreearguments +\let\resetcolorseparation \relax +\let\colorchannelprefix \empty +\let\colorchannelsuffix \empty + +%D We now define the low level macros: + +% todo: palets in definecolor +% todo: {\red xx} vs \red{xx} + +% check: registerusedspotcolors +% check: \currentcolorname +% check: \outercolorname +% check: \startcolormode + +% \def\mptexcolor#1{"\dogetattributeid\s!color \somecolorattribute{#1} A"} +% +% \startMPpage +% fill fullcircle scaled 10cm ; +% fill fullcircle scaled 5cm withprescript \mptexcolor{red} withpostscript \mptexcolor{black} ; +% fill fullcircle scaled 3cm ; +% draw btex test etex withprescript \mptexcolor{blue} ; +% \stopMPpage + +\ifx\currentcolormodel\undefined \newcount\currentcolormodel \fi + +% \def\setcolormodel#1% +% {\showcolormessage\m!colors1{#1}% +% \dosetcolormodel{#1}} + +\def\dosetcolormodel#1% no message + {\currentcolormodel\ctxlua{tex.print(colors.setmodel('#1',\ifweightGRAY true\else false\fi))}% + \attribute\colormodelattribute\currentcolormodel} + +\dosetcolormodel{all} + + +\def\dosetupcolormodel + {\ifincolor + \ifRGBsupported + \ifCMYKsupported + \dosetcolormodel{all}% + \else + \dosetcolormodel{rgb}% + \fi + \else + \ifCMYKsupported + \dosetcolormodel{cmyk}% + \else + \ifconvertGRAY + \dosetcolormodel{gray}% + \else + \dosetcolormodel{none}% + \fi + \fi + \fi + \else + \ifconvertGRAY + \dosetcolormodel{gray}% + \else + \dosetcolormodel{none}% + \fi + \fi} + +\appendtoks + \dosetupcolormodel +\to \everyjob + +% Currently in mkiv transparency is implemented independent of color. This costs +% a bit more processing time but gives the possibility to apply transparency +% independently in the future. Is this useful? If not we may as well combine them +% again in the future. By coupling we are downward compatible. When we decouple we +% need to do more tricky housekeeping (e.g. persist color independent transparencies +% when color bound ones are nil. + +% Since we couple definitions, we could stick to one test. Todo. Same for mpcolor. + +\letvalue{(cs:-}\empty +\letvalue{(ts:-}\empty + +\def\doactivatecolor#1% : in currentpalet, maybe not, ugly + {\def\currentcolorname{#1}% + \ifcsname(cs:\currentpalet#1)\endcsname + \csname(cs:\currentpalet#1)\endcsname + \csname(ts:\currentpalet#1)\endcsname + \else\ifcsname(cs:#1)\endcsname + \csname(cs:#1)\endcsname + \csname(ts:#1)\endcsname + \fi\fi} + +\let\normaldoactivatecolor\doactivatecolor + +% if it becomes a bottleneck we can set up a more complex system with one shared +% attribute for colorspace, color and transparency + +\def\doactivatecolor + {\ifproductionrun + \ctxlua{colors.enable() transparencies.enable()}% not that efficient but at least robust + \let\doactivatecolor\normaldoactivatecolor + \expandafter\doactivatecolor + \else + \expandafter\normaldoactivatecolor + \fi} + +\def\deactivatecolor + {\let\currentcolorname\s!black + \attribute\colorattribute\attributeunsetvalue + \attribute\transparencyattribute\attributeunsetvalue} + +\def\dodefinecolorcommand#1#2% + {\unexpanded#1{#2}{\doactivatecolor{#2}}} + +\let\colorlist\empty % not really used, only for colo-run +\setfalse\collectcolorsinlist +\def\collectcolorinlist#1{\doglobal\addtocommalist{#1}\colorlist} + +\def\doregistercolor#1#2{\ctxlua{colors.defineprocesscolor("#1","#2",false,\iffreezecolors true\else false\fi)}} + +\def\dodefinecolor[#1][#2]% + {\ifconditional\collectcolorsinlist\collectcolorinlist{#1}\fi + \ctxlua{colors.defineprocesscolor("#1","#2",false,\iffreezecolors true\else false\fi)}% + \dodefinecolorcommand\setvalue{#1}} + +\def\dodefineglobalcolor[#1][#2]% + {\ifconditional\collectcolorsinlist\collectcolorinlist{#1}\fi + \ctxlua{colors.defineprocesscolor("#1","#2",true,\iffreezecolors true\else false\fi)}% + \dodefinecolorcommand\setgvalue{#1}} + +\def\dodefinenamedcolor[#1][#2]% + {\ifconditional\collectcolorsinlist\collectcolorinlist{#1}\fi + \ctxlua{colors.defineprocesscolor("#1","#2",false,\iffreezecolors true\else false\fi)}% + \dodefinecolorcommand\setvalue{#1}} + +\def\dodefinespotcolor[#1][#2][#3]% + {\ifconditional\collectcolorsinlist\collectcolorinlist{#1}\fi + \ctxlua{colors.definespotcolor("#1","#2","#3",true)}% + \dodefinecolorcommand\setxvalue{#1}} + +\def\dodefinemultitonecolor[#1][#2][#3][#4]% + {\ctxlua{colors.definemultitonecolor("#1","#2","#3","#4",true)}% + \dodefinecolorcommand\setxvalue{#1}} + +\def\dodefinetransparency[#1][#2]% + {\ctxlua{colors.definetransparency("#1",#2)}} + +\def\dosetrastercolor#1% slow, we need a fast one + {\edef\@@rastervalue{#1}% + \ifx\@@rastervalue\empty + \let\@@rastervalue\@@rsscreen + \fi + \attribute\colorattribute\ctxlua{tex.sprint(colors.definesimplegray("_raster_",\@@rastervalue))}\relax} + +\def\dodefinefastcolor[#1][#2]% still not fast but ok + {\ctxlua{colors.defineprocesscolor("#1","#2",false,\iffreezecolors true\else false\fi)}% + \dodefinecolorcommand\setvalue{#1}} + +%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. + +\def\doifcolorelse#1% + {\ifcsname(ca:\currentpalet#1)\endcsname + \@EA\firstoftwoarguments + \else\ifcsname(ca:#1)\endcsname + \@EAEAEA\firstoftwoarguments + \else + \@EAEAEA\secondoftwoarguments + \fi\fi} + +\def\doifcolor#1% + {\ifcsname(ca:\currentpalet#1)\endcsname + \@EA\firstofoneargument + \else\ifcsname(ca:#1)\endcsname + \@EAEAEA\firstofoneargument + \else + \@EAEAEA\gobbleoneargument + \fi\fi} + +%D \macros +%D {colored} +%D +%D A bit like \type {\definedfont}: + +\unexpanded\def\colored[#1]% + {\ctxlua{colors.defineprocesscolor("@colored@","#1",false,false)}% + \groupedcommand{\doactivatecolor{@colored@}}{}} + +%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. +%D +%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 + +% can be cleaned up + +\let\maintextcolor \empty +\def\defaulttextcolor {black} +\def\@@themaintextcolor{themaintextcolor} + +\appendtoks + \deactivatecolor + \ifx\maintextcolor\empty\else\doactivatecolor\maintextcolor\fi +\to \everybeforeoutput + +\def\registermaintextcolor{\ctxlua{colors.main = \thecolorattribute\maintextcolor}} + +\unexpanded\def\starttextcolor[#1]% + {\doifsomething{#1} + {\definecolor[\@@themaintextcolor][#1]% + \let\maintextcolor\@@themaintextcolor + \doactivatecolor\maintextcolor + \registermaintextcolor}} + +\let\stoptextcolor\relax + +\def\initializemaintextcolor + {\doifelsenothing\@@cltextcolor + {\definecolor[\@@themaintextcolor][\defaulttextcolor]} + {\definecolor[\@@themaintextcolor][\@@cltextcolor]}% + \let\maintextcolor\@@themaintextcolor + \doactivatecolor\maintextcolor + \registermaintextcolor} + +\appendtoks \initializemaintextcolor \to \everyjob +\appendtoks \initializemaintextcolor \to \everysetupcolors + +\def\dodefinepaletcolor#1#2#3% + {\doifassignmentelse{#3}% \definepalet[test][xx={y=.4}] + {\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}} + {\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} + +\def\doinheritca#1{\csname(ca:\ifcsname(ca:\currentpalet#1)\endcsname\currentpalet#1\else\ifcsname(ca:#1)\endcsname#1\fi\fi)\endcsname} +\def\doinheritcs#1{\csname(cs:\ifcsname(cs:\currentpalet#1)\endcsname\currentpalet#1\else\ifcsname(cs:#1)\endcsname#1\fi\fi)\endcsname} +\def\doinheritta#1{\csname(ta:\ifcsname(ta:\currentpalet#1)\endcsname\currentpalet#1\else\ifcsname(ta:#1)\endcsname#1\fi\fi)\endcsname} +\def\doinheritts#1{\csname(ts:\ifcsname(ts:\currentpalet#1)\endcsname\currentpalet#1\else\ifcsname(ts:#1)\endcsname#1\fi\fi)\endcsname} + +%D Low level defs: + +\def\colordefalc#1#2{\setevalue{(ca:#1)}{#2}\setvalue {(cs:#1)}{\attribute\colorattribute #2 }} +\def\colordefagc#1#2{\setxvalue{(ca:#1)}{#2}\setvalue {(cs:#1)}{\attribute\colorattribute #2 }} +\def\colordefalt#1#2{\setevalue{(ta:#1)}{#2}\setvalue {(ts:#1)}{\attribute\transparencyattribute#2 }} +\def\colordefagt#1#2{\setxvalue{(ta:#1)}{#2}\setgvalue{(ts:#1)}{\attribute\transparencyattribute#2 }} + +\def\colordefflc#1#2{\setvalue {(ca:#1)}{\doinheritca{#2}}\setvalue {(cs:#1)}{\doinheritcs{#2}}} +\def\colordeffgc#1#2{\setgvalue{(ca:#1)}{\doinheritca{#2}}\setvalue {(cs:#1)}{\doinheritcs{#2}}} +\def\colordefflt#1#2{\setvalue {(ta:#1)}{\doinheritta{#2}}\setvalue {(ts:#1)}{\doinheritts{#2}}} +\def\colordeffgt#1#2{\setgvalue{(ta:#1)}{\doinheritta{#2}}\setgvalue{(ts:#1)}{\doinheritts{#2}}} + +\def\colordefrlc #1{\localundefine {(ca:#1)}\localundefine {(cs:#1)}} +\def\colordefrgc #1{\globalundefine{(ca:#1)}\globalundefine{(cs:#1)}} +\def\colordefrlt #1{\localundefine {(ta:#1)}\localundefine {(ts:#1)}} +\def\colordefrgt #1{\globalundefine{(ta:#1)}\globalundefine{(ts:#1)}} + +%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{ } + +\def\MPcolor#1{\ctxlua{tex.sprint(colors.mp(\number\currentcolormodel,\number\doinheritca{#1},\number\doinheritta{#1}))}} + +\let\currentcolorname\s!black % todo +\let\outercolorname \s!black % todo + +\def\thecolorattribute #1{\number\csname(ca:\ifcsname(ca:\currentpalet#1)\endcsname\currentpalet#1\else\ifcsname(ca:#1)\endcsname#1\fi\fi)\endcsname} +\def\thetransparencyattribute#1{\number\csname(ta:\ifcsname(ta:\currentpalet#1)\endcsname\currentpalet#1\else\ifcsname(ta:#1)\endcsname#1\fi\fi)\endcsname} + +\def\internalspotcolorname #1{\ctxlua{tex.sprint(colors.spotcolorname (\thecolorattribute{#1}))}} +\def\internalspotcolorparent#1{\ctxlua{tex.sprint(colors.spotcolorparent(\thecolorattribute{#1}))}} +\def\internalspotcolorsize #1{\ctxlua{tex.sprint(colors.spotcolorvalue (\thecolorattribute{#1}))}} + +\def\colorcomponents #1{\ctxlua{tex.sprint(colors.colorcomponents (\thecolorattribute {#1}))}} +\def\transparencycomponents#1{\ctxlua{tex.sprint(colors.transparencycomponents(\thetransparencyattribute{#1}))}} + +\def\colorvalue#1{\ctxlua{tex.sprint(colors.formatcolor(\thecolorattribute{#1},"\colorformatseparator"))}} +\def\grayvalue #1{\ctxlua{tex.sprint(colors.formatgray (\thecolorattribute{#1},"\colorformatseparator"))}} + +\def\doifblackelse #1{\ctxlua{commands.doifelse(colors.isblack(\thecolorattribute{#1}))}} +\def\doifdrawingblackelse {\ctxlua{commands.doifelse(colors.isblack(tex.attribute[attributes.numbers['color']]))}} + +%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} + +% \normal added else fails in metafun manual (leaders do a hard scan) + +\unexpanded\def\forcecolorhack{\leaders\hrule\normalhskip\zeropoint} + +%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, % will be enabled later on + \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, % obsolete + \c!factor=\v!yes, + \c!criterium=\v!all] % obsolete + +\appendtoks + \setupcolors[\c!state=\v!start]% later direct +\to \everyjob + +\appendtoks + \let\showcolormessage\showmessage +\to \everyjob + +\setupcolor + [\v!rgb] + +\protect \endinput diff --git a/tex/context/base/colo-rgb.tex b/tex/context/base/colo-rgb.tex new file mode 100644 index 000000000..038e0ab0b --- /dev/null +++ b/tex/context/base/colo-rgb.tex @@ -0,0 +1,530 @@ +%D \module +%D [ file=colo-rgb, +%D version=1995.01.01, +%D title=\CONTEXT\ Color Macros, +%D subtitle=RGB, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Just to give users a start we define some colors. While +%D switching fonts is as international as can be, thanks to the +%D mnemonics, naming colors is very interface dependant. To +%D support international setups, we define both english and +%D interface dependant colors. We use the color inheritance +%D mechanisms to implement the interface dependant ones. + +%D First we define some simple primary \cap{RGB} and \cap{CMYK} +%D colors. All colors are defined in \cap{RGB} color space. + +\definecolor [red] [r=1, g=0, b=0] +\definecolor [green] [r=0, g=1, b=0] +\definecolor [blue] [r=0, g=0, b=1] + +\definecolor [cyan] [r=0, g=1, b=1] +\definecolor [magenta] [r=1, g=0, b=1] +\definecolor [yellow] [r=1, g=1, b=0] + +\definecolor [white] [s=1] % [r=1, g=1, b=1] +\definecolor [black] [s=0] +\definecolor [gray] [s=.9] + +\definecolor [darkred] [r=.8, g=0, b=0] +\definecolor [middlered] [r=.9, g=0, b=0] +\definecolor [lightred] [r=1, g=0, b=0] + +\definecolor [darkgreen] [r=0, g=.6, b=0] +\definecolor [middlegreen] [r=0, g=.8, b=0] +\definecolor [lightgreen] [r=0, g=1, b=0] + +\definecolor [darkblue] [r=0, g=0, b=.8] +\definecolor [middleblue] [r=0, g=0, b=.9] +\definecolor [lightblue] [r=0, g=0, b=1] + +\definecolor [darkcyan] [r=.6, g=.8, b=.8] +\definecolor [middlecyan] [r=0, g=.8, b=.8] + +\definecolor [darkmagenta] [r=.8, g=.6, b=.8] +\definecolor [middlemagenta] [r=1, g=0, b=.6] + +\definecolor [darkyellow] [r=.8, g=.8, b=.6] +\definecolor [middleyellow] [r=1, g=1, b=.2] + +\definecolor [darkgray] [s=.5] +\definecolor [middlegray] [s=.7] +\definecolor [lightgray] [s=.9] + +%D These colors are mapped to interface dependant colornames. + +\startinterface dutch + + \definecolor [rood] [red] + \definecolor [groen] [green] + \definecolor [blauw] [blue] + + \definecolor [cyaan] [cyan] + \definecolor [magenta] [magenta] + \definecolor [geel] [yellow] + + \definecolor [wit] [white] + \definecolor [grijs] [gray] + \definecolor [zwart] [black] + + \definecolor [donkerrood] [darkred] + \definecolor [middelrood] [middlered] + \definecolor [lichtrood] [lightred] + + \definecolor [donkergroen] [darkgreen] + \definecolor [middelgroen] [middlegreen] + \definecolor [lichtgroen] [lightgreen] + + \definecolor [donkerblauw] [darkblue] + \definecolor [middelblauw] [middleblue] + \definecolor [lichtblauw] [lightblue] + + \definecolor [donkercyaan] [darkcyan] + \definecolor [middelcyaan] [middlecyan] + + \definecolor [donkermagenta] [darkmagenta] + \definecolor [middelmagenta] [middlemagenta] + + \definecolor [donkergeel] [darkyellow] + \definecolor [middelgeel] [middleyellow] + + \definecolor [donkergrijs] [darkgray] + \definecolor [middengrijs] [middlegray] + \definecolor [lichtgrijs] [lightgray] + +\stopinterface + +\startinterface german + + \definecolor [rot] [red] + \definecolor [gruen] [green] + \definecolor [blau] [blue] + + \definecolor [cyan] [cyan] + \definecolor [magenta] [magenta] + \definecolor [gelb] [yellow] + + \definecolor [weiss] [white] + \definecolor [grau] [gray] + \definecolor [schwarz] [black] + + \definecolor [dunkelrot] [darkred] + \definecolor [mittelrot] [middlered] + \definecolor [hellrot] [lightred] + + \definecolor [dunkelgruen] [darkgreen] + \definecolor [mittelgruen] [middlegreen] + \definecolor [hellgruen] [lightgreen] + + \definecolor [dunkelblau] [darkblue] + \definecolor [mittelblau] [middleblue] + \definecolor [hellblau] [lightblue] + + \definecolor [dunkelcyan] [darkcyan] + \definecolor [mittelcyan] [middlecyan] + + \definecolor [dunkelmagenta] [darkmagenta] + \definecolor [mittelmagenta] [middlemagenta] + + \definecolor [dunkelgelb] [darkyellow] + \definecolor [mittelgelb] [middleyellow] + + \definecolor [dunkelgrau] [darkgray] + \definecolor [mittelgrau] [middlegray] + \definecolor [hellgrau] [lightgray] + +\stopinterface + +\startinterface czech + + \definecolor [cervena] [red] + \definecolor [zelena] [green] + \definecolor [modra] [blue] + + \definecolor [azurova] [cyan] + \definecolor [fialova] [magenta] + \definecolor [zluta] [yellow] + + \definecolor [bila] [white] + \definecolor [cerna] [black] + + \definecolor [tmavecervena] [darkred] + \definecolor [strednecervena] [middlered] + \definecolor [svetlecervena] [lightred] + + \definecolor [tmavezelena] [darkgreen] + \definecolor [strednezelena] [middlegreen] + \definecolor [svetlezelena] [lightgreen] + + \definecolor [tmavemodra] [darkblue] + \definecolor [strednemodra] [middleblue] + \definecolor [svetlemodra] [lightblue] + + \definecolor [tmaveazurova] [darkcyan] + \definecolor [stredneazurova] [middlecyan] + + \definecolor [tmavefialova] [darkmagenta] + \definecolor [strednefialova] [middlemagenta] + + \definecolor [tmavezluta] [darkyellow] + \definecolor [strednezluta] [middleyellow] + + \definecolor [tmaveseda] [darkgray] + \definecolor [stredneseda] [middlegray] + \definecolor [svetleseda] [lightgray] + +\stopinterface + +\startinterface italian + + \definecolor [rosso] [red] + \definecolor [verde] [green] + \definecolor [blu] [blue] + + \definecolor [azzurro] [cyan] + \definecolor [turchino] [cyan] + \definecolor [ciano] [cyan] + \definecolor [cremisi] [magenta] + \definecolor [giallo] [yellow] + + \definecolor [bianco] [white] + \definecolor [grigio] [gray] + \definecolor [nero] [black] + + \definecolor [rossoscuro] [darkred] + \definecolor [rossomedio] [middlered] + \definecolor [rossochiaro] [lightred] + + \definecolor [verdescuro] [darkgreen] + \definecolor [verdemedio] [middlegreen] + \definecolor [verdechiaro] [lightgreen] + + \definecolor [bluscuro] [darkblue] + \definecolor [blumedio] [middleblue] + \definecolor [bluchiaro] [lightblue] + + \definecolor [azzurroscuro] [darkcyan] + \definecolor [azzurrochiaro] [middlecyan] + + \definecolor [cremisiscuro] [darkmagenta] + \definecolor [cremisichiaro] [middlemagenta] + + + \definecolor [gialloscuro] [darkyellow] + \definecolor [giallomedio] [middleyellow] + + \definecolor [grigioscuro] [darkgray] + \definecolor [grigiomedio] [middlegray] + \definecolor [grigiochiaro] [lightgray] + +\stopinterface + +\startinterface romanian + + \definecolor [rosu] [red] + \definecolor [verde] [green] + \definecolor [albastru] [blue] + + \definecolor [cian] [cyan] + \definecolor [magenta] [magenta] + \definecolor [galben] [yellow] + + \definecolor [alb] [white] + \definecolor [gri] [gray] + \definecolor [negru] [black] + + \definecolor [rosuinchis] [darkred] + \definecolor [rosumediu] [middlered] + \definecolor [rosudeschis] [lightred] + + \definecolor [verdeinchis] [darkgreen] + \definecolor [verdemediu] [middlegreen] + \definecolor [verdedeschis] [lightgreen] + + \definecolor [albastruinchis] [darkblue] + \definecolor [albastrumediu] [middleblue] + \definecolor [albastrudeschis] [lightblue] + + \definecolor [cianinchis] [darkcyan] + \definecolor [cianmediu] [middlecyan] + + \definecolor [magentainchis] [darkmagenta] + \definecolor [magentamediu] [middlemagenta] + + \definecolor [galbeninchis] [darkyellow] + \definecolor [galbenmediu] [middleyellow] + + \definecolor [griinchis] [darkgray] + \definecolor [grimediu] [middlegray] + \definecolor [grideschis] [lightgray] + +\stopinterface + +%D Like colors, we first define the english colorgroups. These +%D colorgroups are tuned for distinctive gray scale printing. + +% todo : more efficient and real gray + +\definecolorgroup + [gray] + [0.95:0.95:0.95, + 0.90:0.90:0.90, + 0.80:0.80:0.80, + 0.70:0.70:0.70, + 0.60:0.60:0.60, + 0.50:0.50:0.50, + 0.40:0.40:0.40, + 0.30:0.30:0.30, + 0.20:0.20:0.20, + 0.10:0.10:0.10, + 0.00:0.00:0.00] + +\definecolorgroup + [red] + [1.00:0.90:0.90, + 1.00:0.80:0.80, + 1.00:0.70:0.70, + 1.00:0.55:0.55, + 1.00:0.40:0.40, + 1.00:0.25:0.25, + 1.00:0.15:0.15, + 0.90:0.00:0.00] + +\definecolorgroup + [green] + [0.90:1.00:0.90, + 0.70:1.00:0.70, + 0.50:1.00:0.50, + 0.30:1.00:0.30, + 0.15:0.90:0.15, + 0.00:0.80:0.00, + 0.00:0.65:0.00, + 0.00:0.50:0.00] + +\definecolorgroup + [blue] + [0.90:0.95:1.00, + 0.80:0.90:1.00, + 0.55:0.85:1.00, + 0.30:0.80:1.00, + 0.15:0.75:1.00, + 0.00:0.70:1.00, + 0.00:0.55:1.00, + 0.00:0.40:1.00] + +\definecolorgroup + [cyan] + [0.80:1.00:1.00, + 0.60:1.00:1.00, + 0.30:1.00:1.00, + 0.00:0.95:0.95, + 0.00:0.85:0.85, + 0.00:0.75:0.75, + 0.00:0.60:0.60, + 0.00:0.50:0.50] + +\definecolorgroup + [magenta] + [1.00:0.90:1.00, + 1.00:0.80:1.00, + 1.00:0.65:1.00, + 1.00:0.50:1.00, + 1.00:0.35:1.00, + 1.00:0.15:1.00, + 0.90:0.05:0.90, + 0.80:0.00:0.80] + +\definecolorgroup + [yellow] + [1.00:1.00:0.70, + 1.00:1.00:0.00, + 1.00:0.85:0.05, + 1.00:0.70:0.00, + 1.00:0.55:0.00, + 0.95:0.40:0.00, + 0.80:0.30:0.00, + 0.60:0.30:0.00] + +\definecolorgroup + [red*] + [1.00:0.95:0.95, + 1.00:0.90:0.90, + 1.00:0.80:0.80, + 1.00:0.70:0.70, + 1.00:0.60:0.60, + 1.00:0.50:0.50, + 1.00:0.40:0.40, + 1.00:0.30:0.30] + +\definecolorgroup + [green*] + [0.95:1.00:0.95, + 0.90:1.00:0.90, + 0.80:1.00:0.80, + 0.70:1.00:0.70, + 0.60:1.00:0.60, + 0.50:1.00:0.50, + 0.40:1.00:0.40, + 0.30:1.00:0.30] + +\definecolorgroup + [blue*] + [0.95:0.95:1.00, + 0.90:0.90:1.00, + 0.80:0.80:1.00, + 0.70:0.70:1.00, + 0.60:0.60:1.00, + 0.50:0.50:1.00, + 0.40:0.40:1.00, + 0.30:0.30:1.00] + +\definecolorgroup + [yellow*] + [1.00:1.00:0.10, + 1.00:1.00:0.00, + 0.90:0.90:0.00, + 0.80:0.80:0.00, + 0.70:0.70:0.00, + 0.60:0.60:0.00, + 0.50:0.50:0.00, + 0.40:0.40:0.00] + +%D For the sake of implementing interface dependant color +%D groups we support colorgroup duplication. + +\startinterface dutch + \definecolorgroup [grijs] [gray] + \definecolorgroup [rood] [red] + \definecolorgroup [groen] [green] + \definecolorgroup [blauw] [blue] + \definecolorgroup [cyaan] [cyan] + \definecolorgroup [magenta] [magenta] + \definecolorgroup [geel] [yellow] + \definecolorgroup [rood*] [red*] + \definecolorgroup [groen*] [green*] + \definecolorgroup [blauw*] [blue*] + \definecolorgroup [geel*] [yellow*] +\stopinterface + +\startinterface german + \definecolorgroup [grau] [gray] + \definecolorgroup [rot] [red] + \definecolorgroup [gruen] [green] + \definecolorgroup [blau] [blue] + \definecolorgroup [cyan] [cyan] + \definecolorgroup [magenta] [magenta] + \definecolorgroup [gelb] [yellow] + \definecolorgroup [rot*] [red*] + \definecolorgroup [gruen*] [green*] + \definecolorgroup [blau*] [blue*] + \definecolorgroup [gelb*] [yellow*] +\stopinterface + +\startinterface czech + \definecolorgroup [seda] [gray] + \definecolorgroup [cervena] [red] + \definecolorgroup [zelena] [green] + \definecolorgroup [modra] [blue] + \definecolorgroup [azurova] [cyan] + \definecolorgroup [fialova] [magenta] + \definecolorgroup [zluta] [yellow] + \definecolorgroup [cervena*] [red*] + \definecolorgroup [zelena*] [green*] + \definecolorgroup [modra*] [blue*] + \definecolorgroup [zluta*] [yellow*] +\stopinterface + +\startinterface italian + \definecolorgroup [grigio] [gray] + \definecolorgroup [rosso] [red] + \definecolorgroup [verde] [green] + \definecolorgroup [blu] [blue] + \definecolorgroup [ciano] [cyan] + \definecolorgroup [azzurro] [cyan] + \definecolorgroup [turchino][cyan] + \definecolorgroup [magenta] [magenta] + \definecolorgroup [cremisi] [magenta] + \definecolorgroup [giallo] [yellow] + \definecolorgroup [rosso*] [red*] + \definecolorgroup [verde*] [green*] + \definecolorgroup [blu*] [blue*] + \definecolorgroup [giallo*] [yellow*] +\stopinterface + +%D The next set of color palets is quite language independant. +%D These palets are meant as examples. + +\definepalet + [alfa] + [ top=red:7, + bottom=green:6, + up=blue:5, + down=cyan:4, + strange=magenta:3, + charm=yellow:2] + +\definepalet + [beta] + [ top=red:7, + bottom=green:5, + up=blue:3, + down=cyan:6, + strange=magenta:2, + charm=yellow:1] + +\definepalet + [gamma] + [ top=red:2, + bottom=green:5, + up=blue:3, + down=cyan:6, + strange=magenta:7, + charm=yellow:4] + +\definepalet + [delta] + [ top=yellow*:5, + bottom=yellow*:3, + up=yellow*:2, + down=magenta:6, + strange=blue:4, + charm=blue:1] + +\definepalet + [epsilon] + [ top=cyan:7, + bottom=cyan:5, + up=blue:3, + down=yellow:6, + strange=yellow:4, + charm=yellow:2] + +\definepalet + [zeta] + [ top=red:6, + bottom=green:5, + up=blue:7, + down=cyan:4, + strange=magenta:3, + charm=yellow:2] + +%D The next four colors are used for typesetting verbatim \TEX\ +%D in color. + +\definecolor [texcolorone] [middlered] +\definecolor [texcolortwo] [middlegreen] +\definecolor [texcolorthree] [middleblue] +\definecolor [texcolorfour] [darkyellow] + +%D Bonus (needed for FO test): + +\definecolor [orange] [r=1,g=.5] + +\endinput diff --git a/tex/context/base/colo-run.tex b/tex/context/base/colo-run.tex new file mode 100644 index 000000000..d94ea9801 --- /dev/null +++ b/tex/context/base/colo-run.tex @@ -0,0 +1,257 @@ +%D \module +%D [ file=colo-run, +%D version=1997.04.01, +%D title=\CONTEXT\ Color Macros, +%D subtitle=Runtime loaded commands, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 + +% temp hack (not do be documented) + +% \gdef\doformatcolorP#1:#2:#3:#4:#5:#6\od % was undefined in colo-ini +% {#1\colorformatseparator +% \dodoformatcolor{#2}\colorformatseparator +% \dodoformatcolor{#3}\colorformatseparator +% \dodoformatcolor{#4}\colorformatseparator} + +% \gdef\doformatgrayP#1:#2:#3:#4:#5:#6\od +% {todo} + +% so far + +\gdef\showpalet + {\dodoubleargument\doshowpalet} + +\gdef\doshowpalet[#1][#2]% + {\doifdefined{\??pa#1} + {\doifinsetelse\v!vertical{#2} + {\showverticalpalet[#1][#2]} + {\showhorizontalpalet[#1][#2]}}} + +\gdef\showverticalpalet[#1][#2]% + {\localvbox + {\offinterlineskip + \setuppalet[#1] + \def\rule + {\vrule\!!width3em\!!height\strutht\!!depth\strutdp} + \tabskip\zeropoint + \def\doshowpalet##1% + {\doifinsetelse\v!number{#2}{##1\hskip.5em}{}& + \color[##1]{\rule}\graycolor[##1]{\rule}& + \doifinset\v!value{#2}{\hskip.5em\colorvalue{##1}}\crcr} + \halign + {\hss##&\hss##\hss&##\cr + &\doifinset{\v!name}{#2}{\strut#1}&\cr% + \processpalet[#1]\doshowpalet\crcr}}} + +\gdef\showhorizontalpalet[#1][#2]% + {\localvbox + {\offinterlineskip + \setuppalet[#1] + \tabskip\zeropoint + \!!widtha\zeropoint + \doifinset\v!number{#2} + {\def\doshowpalet##1% + {\setbox0\hbox{##1}% + \ifdim\!!widtha<\wd0\!!widtha\wd0\fi}% + \processpalet[#1]\doshowpalet}% + \advance\!!widtha 1em + \ifdim\!!widtha<5em + \!!widtha5em + \fi + \halign + {##&&\hbox to \!!widtha{\hss##\hss}\cr + \doifinset\v!number{#2} + {\def\doshowpalet##1{&\strut##1}% + \processpalet[#1]\doshowpalet}\cr + \doifinset\v!name{#2}{#1\hskip.5em}% + \def\doshowpalet##1% + {&\strut\color[##1]{\vrule\!!width\!!widtha\!!height\strutht\!!depth\zeropoint}}% + \processpalet[#1]\doshowpalet\crcr + \noalign{\vskip-\strutdepth}% + \def\doshowpalet##1% + {&\graycolor[##1]{\vrule\!!width\!!widtha\!!height\zeropoint\!!depth\strutdp}}% + \processpalet[#1]\doshowpalet\crcr + \doifinset\v!value{#2} + {\def\doshowpalet##1% + {&\vbox + {\hsize\!!widtha + \vskip.25ex + \everypar{\strut} + \veryraggedcenter + \let\colorformatseparator=\endgraf + \colorvalue{##1}}}% + \processpalet[#1]\doshowpalet}% + \crcr}}} + +\gdef\processpalet[#1]% + {\expanded{\globalprocesscommalist[\getvalue{\??pa#1}]}} + +\gdef\showcolorgroup + {\dodoubleargument\doshowcolorgroup} + +\gdef\doshowcolorgroup[#1][#2]% + {\doifcolor{#1:1} + {\doifinsetelse\v!vertical{#2} + {\showverticalcolorgroup[#1][#2]} + {\showhorizontalcolorgroup[#1][#2]}}} + +\gdef\showhorizontalcolorgroup[#1][#2]% + {\localvbox + {\offinterlineskip + \setuppalet + \tabskip\zeropoint + \def\rule + {\vrule\!!width4em\!!height\strutht\!!depth\strutdp} + \def\colorformatseparator{\strut\cr} + \def\dodoshowgroup##1% + {\halign + {\hss####\hss\cr + \doifinset\v!number{#2}{\strut##1}\cr + \color[#1:##1]{\vrule\!!width4em\!!height\strutht\!!depth\zeropoint}\cr + \graycolor[#1:##1]{\vrule\!!width4em\!!height\zeropoint\!!depth\strutdp}\cr + \doifinset\v!value{#2}{\colorvalue{#1:##1}\strut}\crcr}} + \def\doshowgroup##1% + {\doifcolor{#1:##1} + {\vbox{\dodoshowgroup{##1}}}}% + \hbox + {\doifinset\v!name{#2} + {\strut + \doifinsetelse\v!value{#2} + {\raise3\lineheight\hbox{#1\hskip.5em}} + {#1}% + \hskip.5em}% + \doshowgroup1\doshowgroup2\doshowgroup3\doshowgroup4% + \doshowgroup5\doshowgroup6\doshowgroup7\doshowgroup8}}} + +\gdef\showverticalcolorgroup[#1][#2]% + {\localvbox + {\offinterlineskip + \setuppalet + \tabskip\zeropoint + \def\rule + {\vrule\!!width2.5em\!!height\strutht\!!depth\strutdp}% + \def\doshowgroup##1% + {\doifcolor{#1:##1} + {\doifinset\v!number{#2}{##1\hskip.5em}& + \color[#1:##1]{\rule}\graycolor[#1:##1]{\rule}& + \doifinset\v!value{#2}{\hskip.5em\colorvalue{#1:##1}}\crcr}}% + \halign + {\hss##&\hss##\hss&##\hss\cr + &\doifinset\v!name{#2}{\strut#1}&\crcr + \doshowgroup1\doshowgroup2\doshowgroup3\doshowgroup4% + \doshowgroup5\doshowgroup6\doshowgroup7\doshowgroup8}}} + +\gdef\showcolor + {\dosingleempty\doshowcolor} + +\gdef\doshowcolor[#1]% + {\bgroup + \iffirstargument + \let\colorlist\empty % not really used, only for colo-run + \let\colorstyle\empty + \settrue\collectcolorsinlist + \setupcolor[#1]% + \fi + \def\rule + {\vrule\!!width4em\!!height\strutht\!!depth\strutdp}% + \def\docommand##1% + {\NC\graycolor[##1]{\rule}\NC\color[##1]{\rule}\NC\grayvalue{##1}\NC\colorvalue{##1}\NC##1\NC\NR}% + \starttabulate[|l|l|l|l|l|l|l|] + \expanded{\globalprocesscommalist[\colorlist]}\docommand + \stoptabulate + \egroup} + +\gdef\comparepalet + {\dosingleargument\docomparepalet} + +\gdef\docomparepalet[#1]% + {\doifdefined{\??pa#1} + {\hbox + {\dodocomparepalet\color[#1]% + \quad + \dodocomparepalet\graycolor[#1]}}} + +\gdef\dodocomparepalet#1[#2]% + {\localvbox + {\offinterlineskip + \setuppalet[#2] + \getcommacommandsize[\getvalue{\??pa#2}] + \!!widtha2em\relax + \hsize\commalistsize\!!widtha + \def\rule% + {\vrule\!!width.5\!!widtha\!!height2.25ex\!!depth-.75ex} + \def\dododocomparepalet##1% + {\hbox + {\setbox0\hbox + {#1[##1]{\vrule\!!width\hsize\!!height3ex}}% + \wd0\zeropoint + \box0 + \hbox to \hsize + {\def\dododocomparepalet####1% + {\hbox to \!!widtha + {\hss#1[####1]{\rule}\hss}}% + \processcommacommand[\getvalue{\??pa#2}]\dododocomparepalet}} + \endgraf} + \processcommacommand[\getvalue{\??pa#2}]\dododocomparepalet}} + +\gdef\comparecolorgroup + {\dosingleargument\docomparecolorgroup} + +\gdef\docomparecolorgroup[#1]% + {\doifcolor{#1:1} + {\hbox + {\dodocomparecolorgroup\color[#1]% + \quad + \dodocomparecolorgroup\graycolor[#1]}}} + +\gdef\dodocomparecolorgroup#1[#2]% + {\localvbox + {\!!counta\zerocount + \dorecurse{15} + {\doifcolor{#2:\recurselevel}{\advance\!!counta\plusone}} + \!!widtha2em\relax + \hsize\!!counta\!!widtha + \def\rule + {\vrule\!!width.5\!!widtha\!!height2.25ex\!!depth-.75ex} + \def\dododocomparecolorgroup##1% + {\hbox to \hsize + {\setbox0\hbox + {#1[#2:##1]{\vrule\!!width\hsize\!!height3ex}}% + \wd0\zeropoint + \box0 + \hbox to \hsize + {\hss\dorecurse\!!counta{#1[#2:\recurselevel]{\rule}\hss}}} + \endgraf} + \dorecurse\!!counta{\dododocomparecolorgroup\recurselevel}}} + +\gdef\dogetcolorcomponents#1% + {\doifelsenothing{#1} + {\appendtoks + \TB + \to \scratchtoks} + {\appendtoks + \NC\showcolorbar[#1]\NC#1\NC\transparencycomponents{#1}\NC\colorcomponents{#1}\NC \NR + \to \scratchtoks}} + +\gdef\showcolorbar[#1]% + {\backgroundline[#1]{\strut\enspace\color[white]{white}\enspace\color[black]{black}\enspace}} + +\gdef\showcolorcomponents[#1]% + {\begingroup + \scratchtoks{\TB}% + \processcommacommand[#1]\dogetcolorcomponents + \starttabulate[|lT|lT|lT|lT|] + \NC color \NC name \NC transparency \NC specification \NC\NR + \the\scratchtoks + \stoptabulate + \endgroup} + +\protect \endinput diff --git a/tex/context/base/colo-x11.tex b/tex/context/base/colo-x11.tex new file mode 100644 index 000000000..45d3aac62 --- /dev/null +++ b/tex/context/base/colo-x11.tex @@ -0,0 +1,677 @@ +%D \module +%D [ file=colo-x11, +%D version=2009.11.13, +%D title=\CONTEXT\ Color Macros, +%D subtitle=X11, +%D author=Alan Braslau] +%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 Standard X11 rgb colors (from \type {/usr/share/X11/rgb.txt}): + +\doifnotmode{mkiv} { + \input colo-hex.mkii +} + +\definecolor [snow] [h=fffafa] +\definecolor [ghostwhite] [h=f8f8ff] +\definecolor [whitesmoke] [s=0.96] +\definecolor [gainsboro] [s=0.86] +\definecolor [floralwhite] [h=fffaf0] +\definecolor [oldlace] [h=fdf5e6] +\definecolor [linen] [h=faf0e6] +\definecolor [antiquewhite] [h=faebd7] +\definecolor [papayawhip] [h=ffefd5] +\definecolor [blanchedalmond] [h=ffebcd] +\definecolor [bisque] [h=ffe4c4] +\definecolor [peachpuff] [h=ffdab9] +\definecolor [navajowhite] [h=ffdead] +\definecolor [moccasin] [h=ffe4b5] +\definecolor [cornsilk] [h=fff8dc] +\definecolor [ivory] [h=fffff0] +\definecolor [lemonchiffon] [h=fffacd] +\definecolor [seashell] [h=fff5ee] +\definecolor [honeydew] [h=f0fff0] +\definecolor [mintcream] [h=f5fffa] +\definecolor [azure] [h=f0ffff] +\definecolor [aliceblue] [h=f0f8ff] +\definecolor [lavender] [h=e6e6fa] +\definecolor [lavenderblush] [h=fff0f5] +\definecolor [mistyrose] [h=ffe4e1] +\definecolor [white] [s=1] +\definecolor [black] [s=0] +\definecolor [darkslategray] [h=2f4f4f] +\definecolor [darkslategrey] [darkslategray] +\definecolor [dimgray] [s=0.41] +\definecolor [dimgrey] [dimgray] +\definecolor [slategray] [h=708090] +\definecolor [slategrey] [slategray] +\definecolor [lightslategray] [h=778899] +\definecolor [lightslategrey] [lightslategray] +\definecolor [gray] [s=0.75] +\definecolor [grey] [gray] +\definecolor [lightgrey] [s=0.83] +\definecolor [lightgray] [lightgrey] +\definecolor [midnightblue] [h=191970] +\definecolor [navy] [h=000080] +\definecolor [navyblue] [navy] +\definecolor [cornflowerblue] [h=6495ed] +\definecolor [darkslateblue] [h=483d8b] +\definecolor [slateblue] [h=6a5acd] +\definecolor [mediumslateblue] [h=7b68ee] +\definecolor [lightslateblue] [h=8470ff] +\definecolor [mediumblue] [h=0000cd] +\definecolor [royalblue] [h=4169e1] +\definecolor [blue] [h=0000ff] +\definecolor [dodgerblue] [h=1e90ff] +\definecolor [deepskyblue] [h=00bfff] +\definecolor [skyblue] [h=87ceeb] +\definecolor [lightskyblue] [h=87cefa] +\definecolor [steelblue] [h=4682b4] +\definecolor [lightsteelblue] [h=b0c4de] +\definecolor [lightblue] [h=add8e6] +\definecolor [powderblue] [h=b0e0e6] +\definecolor [paleturquoise] [h=afeeee] +\definecolor [darkturquoise] [h=00ced1] +\definecolor [mediumturquoise] [h=48d1cc] +\definecolor [turquoise] [h=40e0d0] +\definecolor [cyan] [h=00ffff] +\definecolor [lightcyan] [h=e0ffff] +\definecolor [cadetblue] [h=5f9ea0] +\definecolor [mediumaquamarine] [h=66cdaa] +\definecolor [aquamarine] [h=7fffd4] +\definecolor [darkgreen] [h=006400] +\definecolor [darkolivegreen] [h=556b2f] +\definecolor [darkseagreen] [h=8fbc8f] +\definecolor [seagreen] [h=2e8b57] +\definecolor [mediumseagreen] [h=3cb371] +\definecolor [lightseagreen] [h=20b2aa] +\definecolor [palegreen] [h=98fb98] +\definecolor [springgreen] [h=00ff7f] +\definecolor [lawngreen] [h=7cfc00] +\definecolor [green] [h=00ff00] +\definecolor [chartreuse] [h=7fff00] +\definecolor [mediumspringgreen] [h=00fa9a] +\definecolor [greenyellow] [h=adff2f] +\definecolor [limegreen] [h=32cd32] +\definecolor [yellowgreen] [h=9acd32] +\definecolor [forestgreen] [h=228b22] +\definecolor [olivedrab] [h=6b8e23] +\definecolor [darkkhaki] [h=bdb76b] +\definecolor [khaki] [h=f0e68c] +\definecolor [palegoldenrod] [h=eee8aa] +\definecolor [lightgoldenrodyellow] [h=fafad2] +\definecolor [lightyellow] [h=ffffe0] +\definecolor [yellow] [h=ffff00] +\definecolor [gold] [h=ffd700] +\definecolor [lightgoldenrod] [h=eedd82] +\definecolor [goldenrod] [h=daa520] +\definecolor [darkgoldenrod] [h=b8860b] +\definecolor [rosybrown] [h=bc8f8f] +\definecolor [indianred] [h=cd5c5c] +\definecolor [saddlebrown] [h=8b4513] +\definecolor [sienna] [h=a0522d] +\definecolor [peru] [h=cd853f] +\definecolor [burlywood] [h=deb887] +\definecolor [beige] [h=f5f5dc] +\definecolor [wheat] [h=f5deb3] +\definecolor [sandybrown] [h=f4a460] +\definecolor [tan] [h=d2b48c] +\definecolor [chocolate] [h=d2691e] +\definecolor [firebrick] [h=b22222] +\definecolor [brown] [h=a52a2a] +\definecolor [darksalmon] [h=e9967a] +\definecolor [salmon] [h=fa8072] +\definecolor [lightsalmon] [h=ffa07a] +\definecolor [orange] [h=ffa500] +\definecolor [darkorange] [h=ff8c00] +\definecolor [coral] [h=ff7f50] +\definecolor [lightcoral] [h=f08080] +\definecolor [tomato] [h=ff6347] +\definecolor [orangered] [h=ff4500] +\definecolor [red] [h=ff0000] +\definecolor [hotpink] [h=ff69b4] +\definecolor [deeppink] [h=ff1493] +\definecolor [pink] [h=ffc0cb] +\definecolor [lightpink] [h=ffb6c1] +\definecolor [palevioletred] [h=db7093] +\definecolor [maroon] [h=b03060] +\definecolor [mediumvioletred] [h=c71585] +\definecolor [violetred] [h=d02090] +\definecolor [magenta] [h=ff00ff] +\definecolor [violet] [h=ee82ee] +\definecolor [plum] [h=dda0dd] +\definecolor [orchid] [h=da70d6] +\definecolor [mediumorchid] [h=ba55d3] +\definecolor [darkorchid] [h=9932cc] +\definecolor [darkviolet] [h=9400d3] +\definecolor [blueviolet] [h=8a2be2] +\definecolor [purple] [h=a020f0] +\definecolor [mediumpurple] [h=9370db] +\definecolor [thistle] [h=d8bfd8] +\definecolor [snow1] [h=fffafa] +\definecolor [snow2] [h=eee9e9] +\definecolor [snow3] [h=cdc9c9] +\definecolor [snow4] [h=8b8989] +\definecolor [seashell1] [h=fff5ee] +\definecolor [seashell2] [h=eee5de] +\definecolor [seashell3] [h=cdc5bf] +\definecolor [seashell4] [h=8b8682] +\definecolor [antiquewhite1] [h=ffefdb] +\definecolor [antiquewhite2] [h=eedfcc] +\definecolor [antiquewhite3] [h=cdc0b0] +\definecolor [antiquewhite4] [h=8b8378] +\definecolor [bisque1] [h=ffe4c4] +\definecolor [bisque2] [h=eed5b7] +\definecolor [bisque3] [h=cdb79e] +\definecolor [bisque4] [h=8b7d6b] +\definecolor [peachpuff1] [h=ffdab9] +\definecolor [peachpuff2] [h=eecbad] +\definecolor [peachpuff3] [h=cdaf95] +\definecolor [peachpuff4] [h=8b7765] +\definecolor [navajowhite1] [h=ffdead] +\definecolor [navajowhite2] [h=eecfa1] +\definecolor [navajowhite3] [h=cdb38b] +\definecolor [navajowhite4] [h=8b795e] +\definecolor [lemonchiffon1] [h=fffacd] +\definecolor [lemonchiffon2] [h=eee9bf] +\definecolor [lemonchiffon3] [h=cdc9a5] +\definecolor [lemonchiffon4] [h=8b8970] +\definecolor [cornsilk1] [h=fff8dc] +\definecolor [cornsilk2] [h=eee8cd] +\definecolor [cornsilk3] [h=cdc8b1] +\definecolor [cornsilk4] [h=8b8878] +\definecolor [ivory1] [h=fffff0] +\definecolor [ivory2] [h=eeeee0] +\definecolor [ivory3] [h=cdcdc1] +\definecolor [ivory4] [h=8b8b83] +\definecolor [honeydew1] [h=f0fff0] +\definecolor [honeydew2] [h=e0eee0] +\definecolor [honeydew3] [h=c1cdc1] +\definecolor [honeydew4] [h=838b83] +\definecolor [lavenderblush1] [h=fff0f5] +\definecolor [lavenderblush2] [h=eee0e5] +\definecolor [lavenderblush3] [h=cdc1c5] +\definecolor [lavenderblush4] [h=8b8386] +\definecolor [mistyrose1] [h=ffe4e1] +\definecolor [mistyrose2] [h=eed5d2] +\definecolor [mistyrose3] [h=cdb7b5] +\definecolor [mistyrose4] [h=8b7d7b] +\definecolor [azure1] [h=f0ffff] +\definecolor [azure2] [h=e0eeee] +\definecolor [azure3] [h=c1cdcd] +\definecolor [azure4] [h=838b8b] +\definecolor [slateblue1] [h=836fff] +\definecolor [slateblue2] [h=7a67ee] +\definecolor [slateblue3] [h=6959cd] +\definecolor [slateblue4] [h=473c8b] +\definecolor [royalblue1] [h=4876ff] +\definecolor [royalblue2] [h=436eee] +\definecolor [royalblue3] [h=3a5fcd] +\definecolor [royalblue4] [h=27408b] +\definecolor [blue1] [h=0000ff] +\definecolor [blue2] [h=0000ee] +\definecolor [blue3] [h=0000cd] +\definecolor [blue4] [h=00008b] +\definecolor [dodgerblue1] [h=1e90ff] +\definecolor [dodgerblue2] [h=1c86ee] +\definecolor [dodgerblue3] [h=1874cd] +\definecolor [dodgerblue4] [h=104e8b] +\definecolor [steelblue1] [h=63b8ff] +\definecolor [steelblue2] [h=5cacee] +\definecolor [steelblue3] [h=4f94cd] +\definecolor [steelblue4] [h=36648b] +\definecolor [deepskyblue1] [h=00bfff] +\definecolor [deepskyblue2] [h=00b2ee] +\definecolor [deepskyblue3] [h=009acd] +\definecolor [deepskyblue4] [h=00688b] +\definecolor [skyblue1] [h=87ceff] +\definecolor [skyblue2] [h=7ec0ee] +\definecolor [skyblue3] [h=6ca6cd] +\definecolor [skyblue4] [h=4a708b] +\definecolor [lightskyblue1] [h=b0e2ff] +\definecolor [lightskyblue2] [h=a4d3ee] +\definecolor [lightskyblue3] [h=8db6cd] +\definecolor [lightskyblue4] [h=607b8b] +\definecolor [slategray1] [h=c6e2ff] +\definecolor [slategray2] [h=b9d3ee] +\definecolor [slategray3] [h=9fb6cd] +\definecolor [slategray4] [h=6c7b8b] +\definecolor [lightsteelblue1] [h=cae1ff] +\definecolor [lightsteelblue2] [h=bcd2ee] +\definecolor [lightsteelblue3] [h=a2b5cd] +\definecolor [lightsteelblue4] [h=6e7b8b] +\definecolor [lightblue1] [h=bfefff] +\definecolor [lightblue2] [h=b2dfee] +\definecolor [lightblue3] [h=9ac0cd] +\definecolor [lightblue4] [h=68838b] +\definecolor [lightcyan1] [h=e0ffff] +\definecolor [lightcyan2] [h=d1eeee] +\definecolor [lightcyan3] [h=b4cdcd] +\definecolor [lightcyan4] [h=7a8b8b] +\definecolor [paleturquoise1] [h=bbffff] +\definecolor [paleturquoise2] [h=aeeeee] +\definecolor [paleturquoise3] [h=96cdcd] +\definecolor [paleturquoise4] [h=668b8b] +\definecolor [cadetblue1] [h=98f5ff] +\definecolor [cadetblue2] [h=8ee5ee] +\definecolor [cadetblue3] [h=7ac5cd] +\definecolor [cadetblue4] [h=53868b] +\definecolor [turquoise1] [h=00f5ff] +\definecolor [turquoise2] [h=00e5ee] +\definecolor [turquoise3] [h=00c5cd] +\definecolor [turquoise4] [h=00868b] +\definecolor [cyan1] [h=00ffff] +\definecolor [cyan2] [h=00eeee] +\definecolor [cyan3] [h=00cdcd] +\definecolor [cyan4] [h=008b8b] +\definecolor [darkslategray1] [h=97ffff] +\definecolor [darkslategray2] [h=8deeee] +\definecolor [darkslategray3] [h=79cdcd] +\definecolor [darkslategray4] [h=528b8b] +\definecolor [aquamarine1] [h=7fffd4] +\definecolor [aquamarine2] [h=76eec6] +\definecolor [aquamarine3] [h=66cdaa] +\definecolor [aquamarine4] [h=458b74] +\definecolor [darkseagreen1] [h=c1ffc1] +\definecolor [darkseagreen2] [h=b4eeb4] +\definecolor [darkseagreen3] [h=9bcd9b] +\definecolor [darkseagreen4] [h=698b69] +\definecolor [seagreen1] [h=54ff9f] +\definecolor [seagreen2] [h=4eee94] +\definecolor [seagreen3] [h=43cd80] +\definecolor [seagreen4] [h=2e8b57] +\definecolor [palegreen1] [h=9aff9a] +\definecolor [palegreen2] [h=90ee90] +\definecolor [palegreen3] [h=7ccd7c] +\definecolor [palegreen4] [h=548b54] +\definecolor [springgreen1] [h=00ff7f] +\definecolor [springgreen2] [h=00ee76] +\definecolor [springgreen3] [h=00cd66] +\definecolor [springgreen4] [h=008b45] +\definecolor [green1] [h=00ff00] +\definecolor [green2] [h=00ee00] +\definecolor [green3] [h=00cd00] +\definecolor [green4] [h=008b00] +\definecolor [chartreuse1] [h=7fff00] +\definecolor [chartreuse2] [h=76ee00] +\definecolor [chartreuse3] [h=66cd00] +\definecolor [chartreuse4] [h=458b00] +\definecolor [olivedrab1] [h=c0ff3e] +\definecolor [olivedrab2] [h=b3ee3a] +\definecolor [olivedrab3] [h=9acd32] +\definecolor [olivedrab4] [h=698b22] +\definecolor [darkolivegreen1] [h=caff70] +\definecolor [darkolivegreen2] [h=bcee68] +\definecolor [darkolivegreen3] [h=a2cd5a] +\definecolor [darkolivegreen4] [h=6e8b3d] +\definecolor [khaki1] [h=fff68f] +\definecolor [khaki2] [h=eee685] +\definecolor [khaki3] [h=cdc673] +\definecolor [khaki4] [h=8b864e] +\definecolor [lightgoldenrod1] [h=ffec8b] +\definecolor [lightgoldenrod2] [h=eedc82] +\definecolor [lightgoldenrod3] [h=cdbe70] +\definecolor [lightgoldenrod4] [h=8b814c] +\definecolor [lightyellow1] [h=ffffe0] +\definecolor [lightyellow2] [h=eeeed1] +\definecolor [lightyellow3] [h=cdcdb4] +\definecolor [lightyellow4] [h=8b8b7a] +\definecolor [yellow1] [h=ffff00] +\definecolor [yellow2] [h=eeee00] +\definecolor [yellow3] [h=cdcd00] +\definecolor [yellow4] [h=8b8b00] +\definecolor [gold1] [h=ffd700] +\definecolor [gold2] [h=eec900] +\definecolor [gold3] [h=cdad00] +\definecolor [gold4] [h=8b7500] +\definecolor [goldenrod1] [h=ffc125] +\definecolor [goldenrod2] [h=eeb422] +\definecolor [goldenrod3] [h=cd9b1d] +\definecolor [goldenrod4] [h=8b6914] +\definecolor [darkgoldenrod1] [h=ffb90f] +\definecolor [darkgoldenrod2] [h=eead0e] +\definecolor [darkgoldenrod3] [h=cd950c] +\definecolor [darkgoldenrod4] [h=8b6508] +\definecolor [rosybrown1] [h=ffc1c1] +\definecolor [rosybrown2] [h=eeb4b4] +\definecolor [rosybrown3] [h=cd9b9b] +\definecolor [rosybrown4] [h=8b6969] +\definecolor [indianred1] [h=ff6a6a] +\definecolor [indianred2] [h=ee6363] +\definecolor [indianred3] [h=cd5555] +\definecolor [indianred4] [h=8b3a3a] +\definecolor [sienna1] [h=ff8247] +\definecolor [sienna2] [h=ee7942] +\definecolor [sienna3] [h=cd6839] +\definecolor [sienna4] [h=8b4726] +\definecolor [burlywood1] [h=ffd39b] +\definecolor [burlywood2] [h=eec591] +\definecolor [burlywood3] [h=cdaa7d] +\definecolor [burlywood4] [h=8b7355] +\definecolor [wheat1] [h=ffe7ba] +\definecolor [wheat2] [h=eed8ae] +\definecolor [wheat3] [h=cdba96] +\definecolor [wheat4] [h=8b7e66] +\definecolor [tan1] [h=ffa54f] +\definecolor [tan2] [h=ee9a49] +\definecolor [tan3] [h=cd853f] +\definecolor [tan4] [h=8b5a2b] +\definecolor [chocolate1] [h=ff7f24] +\definecolor [chocolate2] [h=ee7621] +\definecolor [chocolate3] [h=cd661d] +\definecolor [chocolate4] [h=8b4513] +\definecolor [firebrick1] [h=ff3030] +\definecolor [firebrick2] [h=ee2c2c] +\definecolor [firebrick3] [h=cd2626] +\definecolor [firebrick4] [h=8b1a1a] +\definecolor [brown1] [h=ff4040] +\definecolor [brown2] [h=ee3b3b] +\definecolor [brown3] [h=cd3333] +\definecolor [brown4] [h=8b2323] +\definecolor [salmon1] [h=ff8c69] +\definecolor [salmon2] [h=ee8262] +\definecolor [salmon3] [h=cd7054] +\definecolor [salmon4] [h=8b4c39] +\definecolor [lightsalmon1] [h=ffa07a] +\definecolor [lightsalmon2] [h=ee9572] +\definecolor [lightsalmon3] [h=cd8162] +\definecolor [lightsalmon4] [h=8b5742] +\definecolor [orange1] [h=ffa500] +\definecolor [orange2] [h=ee9a00] +\definecolor [orange3] [h=cd8500] +\definecolor [orange4] [h=8b5a00] +\definecolor [darkorange1] [h=ff7f00] +\definecolor [darkorange2] [h=ee7600] +\definecolor [darkorange3] [h=cd6600] +\definecolor [darkorange4] [h=8b4500] +\definecolor [coral1] [h=ff7256] +\definecolor [coral2] [h=ee6a50] +\definecolor [coral3] [h=cd5b45] +\definecolor [coral4] [h=8b3e2f] +\definecolor [tomato1] [h=ff6347] +\definecolor [tomato2] [h=ee5c42] +\definecolor [tomato3] [h=cd4f39] +\definecolor [tomato4] [h=8b3626] +\definecolor [orangered1] [h=ff4500] +\definecolor [orangered2] [h=ee4000] +\definecolor [orangered3] [h=cd3700] +\definecolor [orangered4] [h=8b2500] +\definecolor [red1] [h=ff0000] +\definecolor [red2] [h=ee0000] +\definecolor [red3] [h=cd0000] +\definecolor [red4] [h=8b0000] +\definecolor [debianred] [h=d70751] +\definecolor [deeppink1] [h=ff1493] +\definecolor [deeppink2] [h=ee1289] +\definecolor [deeppink3] [h=cd1076] +\definecolor [deeppink4] [h=8b0a50] +\definecolor [hotpink1] [h=ff6eb4] +\definecolor [hotpink2] [h=ee6aa7] +\definecolor [hotpink3] [h=cd6090] +\definecolor [hotpink4] [h=8b3a62] +\definecolor [pink1] [h=ffb5c5] +\definecolor [pink2] [h=eea9b8] +\definecolor [pink3] [h=cd919e] +\definecolor [pink4] [h=8b636c] +\definecolor [lightpink1] [h=ffaeb9] +\definecolor [lightpink2] [h=eea2ad] +\definecolor [lightpink3] [h=cd8c95] +\definecolor [lightpink4] [h=8b5f65] +\definecolor [palevioletred1] [h=ff82ab] +\definecolor [palevioletred2] [h=ee799f] +\definecolor [palevioletred3] [h=cd6889] +\definecolor [palevioletred4] [h=8b475d] +\definecolor [maroon1] [h=ff34b3] +\definecolor [maroon2] [h=ee30a7] +\definecolor [maroon3] [h=cd2990] +\definecolor [maroon4] [h=8b1c62] +\definecolor [violetred1] [h=ff3e96] +\definecolor [violetred2] [h=ee3a8c] +\definecolor [violetred3] [h=cd3278] +\definecolor [violetred4] [h=8b2252] +\definecolor [magenta1] [h=ff00ff] +\definecolor [magenta2] [h=ee00ee] +\definecolor [magenta3] [h=cd00cd] +\definecolor [magenta4] [h=8b008b] +\definecolor [orchid1] [h=ff83fa] +\definecolor [orchid2] [h=ee7ae9] +\definecolor [orchid3] [h=cd69c9] +\definecolor [orchid4] [h=8b4789] +\definecolor [plum1] [h=ffbbff] +\definecolor [plum2] [h=eeaeee] +\definecolor [plum3] [h=cd96cd] +\definecolor [plum4] [h=8b668b] +\definecolor [mediumorchid1] [h=e066ff] +\definecolor [mediumorchid2] [h=d15fee] +\definecolor [mediumorchid3] [h=b452cd] +\definecolor [mediumorchid4] [h=7a378b] +\definecolor [darkorchid1] [h=bf3eff] +\definecolor [darkorchid2] [h=b23aee] +\definecolor [darkorchid3] [h=9a32cd] +\definecolor [darkorchid4] [h=68228b] +\definecolor [purple1] [h=9b30ff] +\definecolor [purple2] [h=912cee] +\definecolor [purple3] [h=7d26cd] +\definecolor [purple4] [h=551a8b] +\definecolor [mediumpurple1] [h=ab82ff] +\definecolor [mediumpurple2] [h=9f79ee] +\definecolor [mediumpurple3] [h=8968cd] +\definecolor [mediumpurple4] [h=5d478b] +\definecolor [thistle1] [h=ffe1ff] +\definecolor [thistle2] [h=eed2ee] +\definecolor [thistle3] [h=cdb5cd] +\definecolor [thistle4] [h=8b7b8b] +\definecolor [gray0] [s=0.00] +\definecolor [grey0] [gray0] +\definecolor [gray1] [s=0.01] +\definecolor [grey1] [gray1] +\definecolor [gray2] [s=0.02] +\definecolor [grey2] [gray2] +\definecolor [gray3] [s=0.03] +\definecolor [grey3] [gray3] +\definecolor [gray4] [s=0.04] +\definecolor [grey4] [gray4] +\definecolor [gray5] [s=0.05] +\definecolor [grey5] [gray5] +\definecolor [gray6] [s=0.06] +\definecolor [grey6] [gray6] +\definecolor [gray7] [s=0.07] +\definecolor [grey7] [gray7] +\definecolor [gray8] [s=0.08] +\definecolor [grey8] [gray8] +\definecolor [gray9] [s=0.09] +\definecolor [grey9] [gray9] +\definecolor [gray10] [s=0.10] +\definecolor [grey10] [gray10] +\definecolor [gray11] [s=0.11] +\definecolor [grey11] [gray11] +\definecolor [gray12] [s=0.12] +\definecolor [grey12] [gray12] +\definecolor [gray13] [s=0.13] +\definecolor [grey13] [gray13] +\definecolor [gray14] [s=0.14] +\definecolor [grey14] [gray14] +\definecolor [gray15] [s=0.15] +\definecolor [grey15] [gray15] +\definecolor [gray16] [s=0.16] +\definecolor [grey16] [gray16] +\definecolor [gray17] [s=0.17] +\definecolor [grey17] [gray17] +\definecolor [gray18] [s=0.18] +\definecolor [grey18] [gray18] +\definecolor [gray19] [s=0.19] +\definecolor [grey19] [gray19] +\definecolor [gray20] [s=0.20] +\definecolor [grey20] [gray20] +\definecolor [gray21] [s=0.21] +\definecolor [grey21] [gray21] +\definecolor [gray22] [s=0.22] +\definecolor [grey22] [gray22] +\definecolor [gray23] [s=0.23] +\definecolor [grey23] [gray23] +\definecolor [gray24] [s=0.24] +\definecolor [grey24] [gray24] +\definecolor [gray25] [s=0.25] +\definecolor [grey25] [gray25] +\definecolor [gray26] [s=0.26] +\definecolor [grey26] [gray26] +\definecolor [gray27] [s=0.27] +\definecolor [grey27] [gray27] +\definecolor [gray28] [s=0.28] +\definecolor [grey28] [gray28] +\definecolor [gray29] [s=0.29] +\definecolor [grey29] [gray29] +\definecolor [gray30] [s=0.30] +\definecolor [grey30] [gray30] +\definecolor [gray31] [s=0.31] +\definecolor [grey31] [gray31] +\definecolor [gray32] [s=0.32] +\definecolor [grey32] [gray32] +\definecolor [gray33] [s=0.33] +\definecolor [grey33] [gray33] +\definecolor [gray34] [s=0.34] +\definecolor [grey34] [gray34] +\definecolor [gray35] [s=0.35] +\definecolor [grey35] [gray35] +\definecolor [gray36] [s=0.36] +\definecolor [grey36] [gray36] +\definecolor [gray37] [s=0.37] +\definecolor [grey37] [gray37] +\definecolor [gray38] [s=0.38] +\definecolor [grey38] [gray38] +\definecolor [gray39] [s=0.39] +\definecolor [grey39] [gray39] +\definecolor [gray40] [s=0.40] +\definecolor [grey40] [gray40] +\definecolor [gray41] [s=0.41] +\definecolor [grey41] [gray41] +\definecolor [gray42] [s=0.42] +\definecolor [grey42] [gray42] +\definecolor [gray43] [s=0.43] +\definecolor [grey43] [gray43] +\definecolor [gray44] [s=0.44] +\definecolor [grey44] [gray44] +\definecolor [gray45] [s=0.45] +\definecolor [grey45] [gray45] +\definecolor [gray46] [s=0.46] +\definecolor [grey46] [gray46] +\definecolor [gray47] [s=0.47] +\definecolor [grey47] [gray47] +\definecolor [gray48] [s=0.48] +\definecolor [grey48] [gray48] +\definecolor [gray49] [s=0.49] +\definecolor [grey49] [gray49] +\definecolor [gray50] [s=0.50] +\definecolor [grey50] [gray50] +\definecolor [gray51] [s=0.51] +\definecolor [grey51] [gray51] +\definecolor [gray52] [s=0.52] +\definecolor [grey52] [gray52] +\definecolor [gray53] [s=0.53] +\definecolor [grey53] [gray53] +\definecolor [gray54] [s=0.54] +\definecolor [grey54] [gray54] +\definecolor [gray55] [s=0.55] +\definecolor [grey55] [gray55] +\definecolor [gray56] [s=0.56] +\definecolor [grey56] [gray56] +\definecolor [gray57] [s=0.57] +\definecolor [grey57] [gray57] +\definecolor [gray58] [s=0.58] +\definecolor [grey58] [gray58] +\definecolor [gray59] [s=0.59] +\definecolor [grey59] [gray59] +\definecolor [gray60] [s=0.60] +\definecolor [grey60] [gray60] +\definecolor [gray61] [s=0.61] +\definecolor [grey61] [gray61] +\definecolor [gray62] [s=0.62] +\definecolor [grey62] [gray62] +\definecolor [gray63] [s=0.63] +\definecolor [grey63] [gray63] +\definecolor [gray64] [s=0.64] +\definecolor [grey64] [gray64] +\definecolor [gray65] [s=0.65] +\definecolor [grey65] [gray65] +\definecolor [gray66] [s=0.66] +\definecolor [grey66] [gray66] +\definecolor [gray67] [s=0.67] +\definecolor [grey67] [gray67] +\definecolor [gray68] [s=0.68] +\definecolor [grey68] [gray68] +\definecolor [gray69] [s=0.69] +\definecolor [grey69] [gray69] +\definecolor [gray70] [s=0.70] +\definecolor [grey70] [gray70] +\definecolor [gray71] [s=0.71] +\definecolor [grey71] [gray71] +\definecolor [gray72] [s=0.72] +\definecolor [grey72] [gray72] +\definecolor [gray73] [s=0.73] +\definecolor [grey73] [gray73] +\definecolor [gray74] [s=0.74] +\definecolor [grey74] [gray74] +\definecolor [gray75] [s=0.75] +\definecolor [grey75] [gray75] +\definecolor [gray76] [s=0.76] +\definecolor [grey76] [gray76] +\definecolor [gray77] [s=0.77] +\definecolor [grey77] [gray77] +\definecolor [gray78] [s=0.78] +\definecolor [grey78] [gray78] +\definecolor [gray79] [s=0.79] +\definecolor [grey79] [gray79] +\definecolor [gray80] [s=0.80] +\definecolor [grey80] [gray80] +\definecolor [gray81] [s=0.81] +\definecolor [grey81] [gray81] +\definecolor [gray82] [s=0.82] +\definecolor [grey82] [gray82] +\definecolor [gray83] [s=0.83] +\definecolor [grey83] [gray83] +\definecolor [gray84] [s=0.84] +\definecolor [grey84] [gray84] +\definecolor [gray85] [s=0.85] +\definecolor [grey85] [gray85] +\definecolor [gray86] [s=0.86] +\definecolor [grey86] [gray86] +\definecolor [gray87] [s=0.87] +\definecolor [grey87] [gray87] +\definecolor [gray88] [s=0.88] +\definecolor [grey88] [gray88] +\definecolor [gray89] [s=0.89] +\definecolor [grey89] [gray89] +\definecolor [gray90] [s=0.90] +\definecolor [grey90] [gray90] +\definecolor [gray91] [s=0.91] +\definecolor [grey91] [gray91] +\definecolor [gray92] [s=0.92] +\definecolor [grey92] [gray92] +\definecolor [gray93] [s=0.93] +\definecolor [grey93] [gray93] +\definecolor [gray94] [s=0.94] +\definecolor [grey94] [gray94] +\definecolor [gray95] [s=0.95] +\definecolor [grey95] [gray95] +\definecolor [gray96] [s=0.96] +\definecolor [grey96] [gray96] +\definecolor [gray97] [s=0.97] +\definecolor [grey97] [gray97] +\definecolor [gray98] [s=0.98] +\definecolor [grey98] [gray98] +\definecolor [gray99] [s=0.99] +\definecolor [grey99] [gray99] +\definecolor [gray100] [s=1.00] +\definecolor [grey100] [gray100] +\definecolor [darkgrey] [s=0.66] +\definecolor [darkgray] [darkgrey] +\definecolor [darkblue] [h=00008b] +\definecolor [darkcyan] [h=008b8b] +\definecolor [darkmagenta] [h=8b008b] +\definecolor [darkred] [h=8b0000] +\definecolor [lightgreen] [h=90ee90] + +\endinput diff --git a/tex/context/base/colo-xwi.tex b/tex/context/base/colo-xwi.tex new file mode 100644 index 000000000..81e09d871 --- /dev/null +++ b/tex/context/base/colo-xwi.tex @@ -0,0 +1,142 @@ +%D \module +%D [ file=colo-xwi, +%D version=1995.01.01, +%D title=\CONTEXT\ Color Macros, +%D subtitle=X Windows, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D I've forgotten where I got these definitions from, but maybe +%D they can be of use. + +\definecolor [aliceblue] [r=0.94,g=0.97,b=1.00] +\definecolor [antiquewhite] [r=0.98,g=0.92,b=0.84] +\definecolor [aquamarine] [r=0.50,g=1.00,b=0.83] +\definecolor [azure] [r=0.94,g=1.00,b=1.00] +\definecolor [beige] [r=0.96,g=0.96,b=0.86] +\definecolor [bisque] [r=1.00,g=0.89,b=0.77] +\definecolor [black] [s=0] % [r=0.00,g=0.00,b=0.00] +\definecolor [blanchedalmond] [r=1.00,g=0.92,b=0.80] +\definecolor [blue] [r=0.00,g=0.00,b=1.00] +\definecolor [blueviolet] [r=0.54,g=0.17,b=0.89] +\definecolor [brown] [r=0.65,g=0.16,b=0.16] +\definecolor [burlywood] [r=0.87,g=0.72,b=0.53] +\definecolor [cadetblue] [r=0.37,g=0.62,b=0.63] +\definecolor [chartreuse] [r=0.50,g=1.00,b=0.00] +\definecolor [chocolate] [r=0.82,g=0.41,b=0.12] +\definecolor [coral] [r=1.00,g=0.50,b=0.31] +\definecolor [cornflowerblue] [r=0.39,g=0.58,b=0.93] +\definecolor [cornsilk] [r=1.00,g=0.97,b=0.86] +\definecolor [cyan] [r=0.00,g=1.00,b=1.00] +\definecolor [darkgoldenrod] [r=0.72,g=0.53,b=0.04] +\definecolor [darkgreen] [r=0.00,g=0.39,b=0.00] +\definecolor [darkkhaki] [r=0.74,g=0.72,b=0.42] +\definecolor [darkolivegreen] [r=0.33,g=0.42,b=0.18] +\definecolor [darkorange] [r=1.00,g=0.55,b=0.00] +\definecolor [darkorchid] [r=0.60,g=0.20,b=0.80] +\definecolor [darksalmon] [r=0.91,g=0.59,b=0.48] +\definecolor [darkseagreen] [r=0.56,g=0.74,b=0.56] +\definecolor [darkslateblue] [r=0.28,g=0.24,b=0.55] +\definecolor [darkturquoise] [r=0.00,g=0.81,b=0.82] +\definecolor [darkviolet] [r=0.58,g=0.00,b=0.83] +\definecolor [deeppink] [r=1.00,g=0.08,b=0.58] +\definecolor [deepskyblue] [r=0.00,g=0.75,b=1.00] +\definecolor [dodgerblue] [r=0.12,g=0.56,b=1.00] +\definecolor [firebrick] [r=0.70,g=0.13,b=0.13] +\definecolor [floralwhite] [r=1.00,g=0.98,b=0.94] +\definecolor [forestgreen] [r=0.13,g=0.55,b=0.13] +\definecolor [gainsboro] [r=0.86,g=0.86,b=0.86] +\definecolor [ghostwhite] [r=0.97,g=0.97,b=1.00] +\definecolor [gold] [r=1.00,g=0.84,b=0.00] +\definecolor [goldenrod] [r=0.85,g=0.65,b=0.13] +\definecolor [green] [r=0.00,g=1.00,b=0.00] +\definecolor [greenyellow] [r=0.68,g=1.00,b=0.18] +\definecolor [honeydew] [r=0.94,g=1.00,b=0.94] +\definecolor [hotpink] [r=1.00,g=0.41,b=0.71] +\definecolor [indianred] [r=0.80,g=0.36,b=0.36] +\definecolor [ivory] [r=1.00,g=1.00,b=0.94] +\definecolor [khaki] [r=0.94,g=0.90,b=0.55] +\definecolor [lavender] [r=0.90,g=0.90,b=0.98] +\definecolor [lavenderblush] [r=1.00,g=0.94,b=0.96] +\definecolor [lawngreen] [r=0.49,g=0.99,b=0.00] +\definecolor [lemonchiffon] [r=1.00,g=0.98,b=0.80] +\definecolor [lightblue] [r=0.68,g=0.85,b=0.90] +\definecolor [lightcoral] [r=0.94,g=0.50,b=0.50] +\definecolor [lightcyan] [r=0.88,g=1.00,b=1.00] +\definecolor [lightgoldenrod] [r=0.93,g=0.87,b=0.51] +\definecolor [lightgoldenrodyellow] [r=0.98,g=0.98,b=0.82] +\definecolor [lightpink] [r=1.00,g=0.71,b=0.76] +\definecolor [lightsalmon] [r=1.00,g=0.63,b=0.48] +\definecolor [lightseagreen] [r=0.13,g=0.70,b=0.67] +\definecolor [lightskyblue] [r=0.53,g=0.81,b=0.98] +\definecolor [lightslateblue] [r=0.52,g=0.44,b=1.00] +\definecolor [lightsteelblue] [r=0.69,g=0.77,b=0.87] +\definecolor [lightyellow] [r=1.00,g=1.00,b=0.88] +\definecolor [limegreen] [r=0.20,g=0.80,b=0.20] +\definecolor [linen] [r=0.98,g=0.94,b=0.90] +\definecolor [magenta] [r=1.00,g=0.00,b=1.00] +\definecolor [maroon] [r=0.69,g=0.19,b=0.38] +\definecolor [mediumaquamarine] [r=0.40,g=0.80,b=0.67] +\definecolor [mediumblue] [r=0.00,g=0.00,b=0.80] +\definecolor [mediumorchid] [r=0.73,g=0.33,b=0.83] +\definecolor [mediumpurple] [r=0.58,g=0.44,b=0.86] +\definecolor [mediumseagreen] [r=0.24,g=0.70,b=0.44] +\definecolor [mediumslateblue] [r=0.48,g=0.41,b=0.93] +\definecolor [mediumspringgreen] [r=0.00,g=0.98,b=0.60] +\definecolor [mediumturquoise] [r=0.28,g=0.82,b=0.80] +\definecolor [mediumvioletred] [r=0.78,g=0.08,b=0.52] +\definecolor [midnightblue] [r=0.10,g=0.10,b=0.44] +\definecolor [mintcream] [r=0.96,g=1.00,b=0.98] +\definecolor [mistyrose] [r=1.00,g=0.89,b=0.88] +\definecolor [moccasin] [r=1.00,g=0.89,b=0.71] +\definecolor [navajowhite] [r=1.00,g=0.87,b=0.68] +\definecolor [navy] [r=0.00,g=0.00,b=0.50] +\definecolor [navyblue] [r=0.00,g=0.00,b=0.50] +\definecolor [oldlace] [r=0.99,g=0.96,b=0.90] +\definecolor [olivedrab] [r=0.42,g=0.56,b=0.14] +\definecolor [orange] [r=1.00,g=0.65,b=0.00] +\definecolor [orangered] [r=1.00,g=0.27,b=0.00] +\definecolor [orchid] [r=0.85,g=0.44,b=0.84] +\definecolor [palegoldenrod] [r=0.93,g=0.91,b=0.67] +\definecolor [palegreen] [r=0.60,g=0.98,b=0.60] +\definecolor [paleturquoise] [r=0.69,g=0.93,b=0.93] +\definecolor [palevioletred] [r=0.86,g=0.44,b=0.58] +\definecolor [papayawhip] [r=1.00,g=0.94,b=0.84] +\definecolor [peachpuff] [r=1.00,g=0.85,b=0.73] +\definecolor [peru] [r=0.80,g=0.52,b=0.25] +\definecolor [pink] [r=1.00,g=0.75,b=0.80] +\definecolor [plum] [r=0.87,g=0.63,b=0.87] +\definecolor [powderblue] [r=0.69,g=0.88,b=0.90] +\definecolor [purple] [r=0.63,g=0.13,b=0.94] +\definecolor [red ] [r=1.00,g=0.00,b=0.00] +\definecolor [rosybrown] [r=0.74,g=0.56,b=0.56] +\definecolor [royalblue] [r=0.25,g=0.41,b=0.88] +\definecolor [saddlebrown] [r=0.55,g=0.27,b=0.07] +\definecolor [salmon] [r=0.98,g=0.50,b=0.45] +\definecolor [sandybrown] [r=0.96,g=0.64,b=0.38] +\definecolor [seagreen] [r=0.18,g=0.55,b=0.34] +\definecolor [seashell] [r=1.00,g=0.96,b=0.93] +\definecolor [sienna] [r=0.63,g=0.32,b=0.18] +\definecolor [skyblue] [r=0.53,g=0.81,b=0.92] +\definecolor [slateblue] [r=0.42,g=0.35,b=0.80] +\definecolor [snow] [r=1.00,g=0.98,b=0.98] +\definecolor [springgreen] [r=0.00,g=1.00,b=0.50] +\definecolor [steelblue] [r=0.27,g=0.51,b=0.71] +\definecolor [tan ] [r=0.82,g=0.71,b=0.55] +\definecolor [thistle] [r=0.85,g=0.75,b=0.85] +\definecolor [tomato] [r=1.00,g=0.39,b=0.28] +\definecolor [turquoise] [r=0.25,g=0.88,b=0.82] +\definecolor [violet] [r=0.93,g=0.51,b=0.93] +\definecolor [violetred] [r=0.82,g=0.13,b=0.56] +\definecolor [wheat] [r=0.96,g=0.87,b=0.70] +\definecolor [white] [r=1.00,g=1.00,b=1.00] +\definecolor [whitesmoke] [s=0.96] % [r=0.96,g=0.96,b=0.96] +\definecolor [yellow] [r=1.00,g=1.00,b=0.00] +\definecolor [yellowgreen] [r=0.60,g=0.80,b=0.20] + +\endinput diff --git a/tex/context/base/cont-cs.tex b/tex/context/base/cont-cs.tex new file mode 100644 index 000000000..f878920aa --- /dev/null +++ b/tex/context/base/cont-cs.tex @@ -0,0 +1,39 @@ +%D \module +%D [ file=cont-cs, +%D version=1998.12.02, +%D title=\CONTEXT, +%D subtitle=\CONTEXT\ Czech Format 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. + +\catcode`\{=1 \catcode`\}=2 \def\defaultinterface{czech} + +\input context.tex + +\unprotect + +\setupcurrentlanguage[\s!cs] + +\loaduserspecifications + +\installlanguage [\s!en] [\c!state=\v!start] +\installlanguage [\s!de] [\c!state=\v!start] +\installlanguage [\s!sk] [\c!state=\v!start] +\installlanguage [\s!cs] [\c!state=\v!start] + +\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 new file mode 100644 index 000000000..460ca7eca --- /dev/null +++ b/tex/context/base/cont-de.tex @@ -0,0 +1,44 @@ +%D \module +%D [ file=cont-de, +%D version=1997.08.19, +%D title=\CONTEXT, +%D subtitle=\CONTEXT\ German Format 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. + +\catcode`\{=1 \catcode`\}=2 \def\defaultinterface{german} + +\input context.tex + +\unprotect + +\setupcurrentlanguage[\s!de] + +\loaduserspecifications + +\installlanguage [\s!us] [\c!state=\v!start] +\installlanguage [\s!gb] [\c!state=\v!start] +\installlanguage [\s!de] [\c!state=\v!start] +\installlanguage [\s!fr] [\c!state=\v!start] +\installlanguage [\s!es] [\c!state=\v!start] +\installlanguage [\s!nl] [\c!state=\v!start] +\installlanguage [\s!it] [\c!state=\v!start] + +\installlanguage [deo] [\c!state=\v!start] + +\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 new file mode 100644 index 000000000..e2b09ecbe --- /dev/null +++ b/tex/context/base/cont-en.tex @@ -0,0 +1,46 @@ +%D \module +%D [ file=cont-en, +%D version=1997.08.19, +%D title=\CONTEXT, +%D subtitle=\CONTEXT\ English Format 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. + +\catcode`\{=1 \catcode`\}=2 \def\defaultinterface{english} + +\input context.tex + +\unprotect + +\setupcurrentlanguage[\s!en] + +\loaduserspecifications + +% Do we need more defaults? or maybe all languages? + +\installlanguage [\s!us] [\c!state=\v!start] +\installlanguage [\s!gb] [\c!state=\v!start] +\installlanguage [\s!de] [\c!state=\v!start] +\installlanguage [\s!fr] [\c!state=\v!start] +\installlanguage [\s!es] [\c!state=\v!start] +\installlanguage [\s!pt] [\c!state=\v!start] +\installlanguage [\s!it] [\c!state=\v!start] +\installlanguage [\s!nl] [\c!state=\v!start] +\installlanguage [\s!cs] [\c!state=\v!start] +\installlanguage [\s!sk] [\c!state=\v!start] +\installlanguage [\s!pl] [\c!state=\v!start] + +\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-err.tex b/tex/context/base/cont-err.tex new file mode 100644 index 000000000..f01ce87aa --- /dev/null +++ b/tex/context/base/cont-err.tex @@ -0,0 +1,18 @@ +%D \module +%D [ file=cont-err, +%D version=2003.08.12, +%D title=\CONTEXT\ System Files, +%D subtitle=Just A warning, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\unprotect + +\writestatus\m!systems{no file 'cont-sys.tex', using 'cont-sys.rme' instead} + +\protect \endinput diff --git a/tex/context/base/cont-fil.tex b/tex/context/base/cont-fil.tex new file mode 100644 index 000000000..b295872ca --- /dev/null +++ b/tex/context/base/cont-fil.tex @@ -0,0 +1,124 @@ +%D \module +%D [ file=cont-fil, +%D version=1997.11.15, +%D title=\CONTEXT\ Miscellaneous Macros, +%D subtitle=File Synonyms, +%D author=J. Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 File Synonyms} + +\definefilesynonym [chemie] [chemic] +\definefilesynonym [chemics] [chemic] + +\definefilesynonym [unit] [units] +\definefilesynonym [eenheid] [units] +\definefilesynonym [einheit] [units] + +\definefilesynonym [pstric] [pstricks] +\definefilesynonym [pstrick] [pstricks] + +\definefilesynonym [finance] [financ] + +\definefilesynonym [con-01] [contml] % will go away + +%definefilesynonym [sch-base] [sch-00] +%definefilesynonym [sch-make] [sch-01] + +\definefilesynonym [dir-make] [dir-01] +\definefilesynonym [dir-identify] [dir-05] + +\definefilesynonym [xml-format] [xml-01] +\definefilesynonym [xml-pretty] [xml-02] +\definefilesynonym [xml-analyze] [xml-11] + +\definefilesynonym [int-load] [set-11] +\definefilesynonym [int-make] [set-12] + +\definefilesynonym [fig-base] [fig-00] +\definefilesynonym [fig-make] [fig-01] +\definefilesynonym [fig-fake] [fig-02] +\definefilesynonym [fig-missing] [fig-06] + +\definefilesynonym [exi-interface] [exi-21] + +\definefilesynonym [res-make] [res-01] +\definefilesynonym [res-base] [res-04] +\definefilesynonym [res-crop] [res-07] +\definefilesynonym [res-trace] [res-08] +\definefilesynonym [res-log] [res-09] +\definefilesynonym [res-identify] [res-12] + +\definefilesynonym [med-show] [res-50] + +\definefilesynonym [pre-general] [pre-00] + +\definefilesynonym [pre-original] [pre-01] +\definefilesynonym [pre-green] [pre-02] +\definefilesynonym [pre-funny] [pre-03] +\definefilesynonym [pre-colorful] [pre-04] +\definefilesynonym [pre-fuzzy] [pre-05] +\definefilesynonym [pre-polish] [pre-06] +\definefilesynonym [pre-spider] [pre-07] +\definefilesynonym [pre-wonder] [pre-08] +\definefilesynonym [pre-windows] [pre-09] +\definefilesynonym [pre-grow] [pre-10] +\definefilesynonym [pre-stack] [pre-11] +\definefilesynonym [pre-arrows] [pre-12] +\definefilesynonym [pre-writing] [pre-13] +\definefilesynonym [pre-split] [pre-14] +\definefilesynonym [pre-balls] [pre-15] +\definefilesynonym [pre-knot] [pre-16] +\definefilesynonym [pre-weird] [pre-17] +\definefilesynonym [pre-shade] [pre-18] +\definefilesynonym [pre-organic] [pre-19] +\definefilesynonym [pre-speckle] [pre-20] +\definefilesynonym [pre-zoom] [pre-21] +\definefilesynonym [pre-cycle] [pre-22] +\definefilesynonym [pre-super] [pre-23] + +%definefilesynonym [pre-more] [pre-24] +%definefilesynonym [pre-more] [pre-25] + +\definefilesynonym [pre-more] [pre-26] + +%definefilesynonym [pre-more] [pre-27] +%definefilesynonym [pre-more] [pre-28] +%definefilesynonym [pre-more] [pre-29] +%definefilesynonym [pre-more] [pre-30] + +\definefilesynonym [pre-stepwise] [pre-60] +\definefilesynonym [pre-stepper] [pre-61] + +\definefilesynonym [pre-punk] [pre-70] +\definefilesynonym [pre-random] [pre-71] + +\definefilesynonym [abr-pseudocaps] [abr-01] +\definefilesynonym [abr-smallcaps] [abr-02] + +\definefilesynonym [chinese] [chi-00] +\definefilesynonym [japanese] [jap-00] + +%definefilesynonym [chi-simplified] [chi-01] +%definefilesynonym [chi-traditional] [chi-02] + +\definefilesynonym [greek] [grk-00] + +\definefilesynonym [unic-chi] [unic-cjk] +\definefilesynonym [unic-jap] [unic-cjk] + +%definefilesynonym [practexjournal] [ptj-01] +\definefilesynonym [pracjourn] [ptj-01] + +\definefilesynonym [maps] [map-10] +\definefilesynonym [map-se] [map-10] % for some time + +\definefilesynonym [mml] [mathml] +\definefilesynonym [cml] [chemml] + +\endinput diff --git a/tex/context/base/cont-fr.tex b/tex/context/base/cont-fr.tex new file mode 100644 index 000000000..d812b28f9 --- /dev/null +++ b/tex/context/base/cont-fr.tex @@ -0,0 +1,42 @@ +%D \module +%D [ file=cont-de, +%D version=1997.08.19, +%D title=\CONTEXT, +%D subtitle=\CONTEXT\ French Format 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. + +\catcode`\{=1 \catcode`\}=2 \def\defaultinterface{french} + +\input context.tex + +\unprotect + +\setupcurrentlanguage[\s!fr] + +\loaduserspecifications + +\installlanguage [\s!us] [\c!state=\v!start] +\installlanguage [\s!gb] [\c!state=\v!start] +\installlanguage [\s!de] [\c!state=\v!start] +\installlanguage [\s!fr] [\c!state=\v!start] +\installlanguage [\s!es] [\c!state=\v!start] +\installlanguage [\s!nl] [\c!state=\v!start] +\installlanguage [\s!it] [\c!state=\v!start] + +\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 new file mode 100644 index 000000000..99d297425 --- /dev/null +++ b/tex/context/base/cont-gb.tex @@ -0,0 +1,42 @@ +%D \module +%D [ file=cont-uk, +%D version=1997.08.19, +%D title=\CONTEXT, +%D subtitle=\CONTEXT\ English Format 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. + +\catcode`\{=1 \catcode`\}=2 \def\defaultinterface{english} + +\input context.tex + +\unprotect + +\setupcurrentlanguage[\s!gb] + +\loaduserspecifications + +\installlanguage [\s!us] [\c!state=\v!start] +\installlanguage [\s!gb] [\c!state=\v!start] +\installlanguage [\s!de] [\c!state=\v!start] +\installlanguage [\s!fr] [\c!state=\v!start] +\installlanguage [\s!es] [\c!state=\v!start] +\installlanguage [\s!nl] [\c!state=\v!start] +\installlanguage [\s!it] [\c!state=\v!start] + +\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 new file mode 100644 index 000000000..2141e3bc9 --- /dev/null +++ b/tex/context/base/cont-it.tex @@ -0,0 +1,41 @@ +%D \module +%D [ file=cont-it, +%D version=1997.08.19, +%D title=\CONTEXT, +%D subtitle=\CONTEXT\ Italian Format 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. + +\catcode`\{=1 \catcode`\}=2 \def\defaultinterface{italian} + +\input context.tex + +\unprotect + +\setupcurrentlanguage[\s!it] + +\loaduserspecifications + +\installlanguage [\s!us] [\c!state=\v!start] +\installlanguage [\s!gb] [\c!state=\v!start] +\installlanguage [\s!de] [\c!state=\v!start] +\installlanguage [\s!fr] [\c!state=\v!start] +\installlanguage [\s!es] [\c!state=\v!start] +\installlanguage [\s!it] [\c!state=\v!start] + +\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 new file mode 100644 index 000000000..9bfec2999 --- /dev/null +++ b/tex/context/base/cont-log.tex @@ -0,0 +1,359 @@ +%D \module +%D [ file=cont-log, +%D version=1995.10.10, +%D title=\CONTEXT\ Miscellaneous Macros, +%D subtitle=\TEX\ Logos, +%D author=J. Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 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, +%D authors of macro packages adapted this raising and lowering +%D style. In this module we define some of those logos. +%D Watch the \type{cmr} detection hack. + +\unprotect + +\defconvertedargument\someCMRfont{cmr} % hm, we now have lm + +% \def\doifCMRfontelse#1#2% +% {\doifinstringelse{\someCMRfont}{\fontname\font} +% {\def\next{#1}} +% {\def\next{#2}}% +% \next} + +\def\doifCMRfontelse + {\doifinstringelse\someCMRfont{\fontname\font}} + +\unexpanded\def\CMRkern + {\doifCMRfontelse\kern{\scratchdimen=}} + +% \def\TeX +% {T% +% \kern-.1667em\lower.5ex\hbox{E}% +% \kern-.125emX} + +\def\Mkern#1% + {{\setbox\scratchbox\hbox{M}\kern#1\wd\scratchbox}} + +\unexpanded\def\TeX + {T% + \Mkern{-.1667}\lower.5ex\hbox{E}% + \Mkern{-.125}X} + +\unexpanded\def\ConTeXt + {C% + \CMRkern-.0333emo% + \CMRkern-.0333emn% +% \CMRkern-.1667em\TeX% + \CMRkern-.0667em\TeX% + \CMRkern-.0333emt} + +\unexpanded\def\PPCHTeX + {ppch\TeX} + +\unexpanded\def\PRAGMA + {Pragma ADE} + +%\def\LaTeX +% {L% +% \kern-.30em\raise.3ex\hbox{\txx A}% +% \kern-.18em\TeX} + +\unexpanded\def\LaTeX % requested by erik frambach + {{\setbox\scratchbox\hbox{L}% + \scratchdimen\ht\scratchbox + \setbox\scratchbox\hbox{\txx A}% + L\kern-.55\wd\scratchbox + \raise\scratchdimen\hbox{\lower\ht\scratchbox\copy\scratchbox}% + \kern-.2\wd\scratchbox\TeX}} + +\unexpanded\def\TaBlE + {T% + \kern-.27em\lower.5ex\hbox{A}% + \kern-.18emB% + \kern-.1em\lower.5ex\hbox{L}% + \kern-.075emE} + +\unexpanded\def\PiCTeX + {P% + \kern-.12em\lower.5ex\hbox{I}% + \kern-.075em C% + \kern-.11em\TeX} + +\def\AMSswitch#1% + {$\cal\ifdim\bodyfontsize>1.1em\scriptstyle\fi#1$} + +\unexpanded\def\AmSTeX + {\AMSswitch A% + \kern-.1667em\lower.5ex\hbox{\AMSswitch M}% + \kern-.125em\AMSswitch S% + -\TeX} + +\unexpanded\def\LamSTeX + {L% + \kern-.4em\raise.3ex\hbox{\AMSswitch A}% + \kern-.25em\lower.4ex\hbox{\AMSswitch M}% + \kern-.1em{\AMSswitch S}% + -\TeX} + +\unexpanded\def\AmSLaTeX + {\AMSswitch A% + \kern-.1667em\lower.5ex\hbox{\AMSswitch M}% + \kern-.125em\AMSswitch S% + -\LaTeX} + +%D Alternative \CONTEXT\ logo, first Idris S.~Hamid's version: +%D +%D \def\Context +%D {{\sc C\kern -.0667emo\kern -.0667emn\kern -.0549emt\kern +%D -.1667em\lower.5ex\hbox {e}\kern -.125emx\kern -.0549emt}} +%D +%D I changed this into one that adapts itself: + +\unexpanded\def\Context + {{C\kern -.0667em\getscaledglyph{.8}\empty{O\kern -.0667emN\kern + -.0549emT\doifitalicelse{\kern-.1em}{\kern-.1667em}\lower.5ex\hbox + {E}\doifitalicelse\empty{\kern-.11em}X\kern-.055emT}}} + +%D The \METAFONT\ and \METAPOST\ logos adapt themselves to the +%D current fontsize, an ugly but usefull hack. + +% rather hard coded +% +% \loadmapfile[original-base.map] % \loadmapfile[original-vogel-symbol] +% +% \unexpanded\def\setMFPfont +% {\font\logofont=logo% +% \ifnum\fam=\bffam\c!bf\else +% \ifnum\fam=\slfam\c!sl\else +% \ifnum\fam=\itfam\c!sl\else +% \ifnum\fam=\bsfam\c!bf\else +% \ifnum\fam=\bifam\c!bf\else +% \fi\fi\fi\fi\fi +% 10 at \currentfontscale\bodyfontsize +% \logofont} +% +% or: +% +% \definefontsynonym [MetaLogo] [logo10] +% \definefontsynonym [MetaLogoBold] [logobf10] +% \definefontsynonym [MetaLogoSlanted] [logosl10] +% \definefontsynonym [MetaLogoItalic] [logosl10] +% \definefontsynonym [MetaLogoBoldSlanted] [logobf10] +% \definefontsynonym [MetaLogoBoldtalic] [logobf10] +% +% \loadmapfile[original-base.map] % \loadmapfile[original-vogel-symbol] +% +% \def\setMFPfont{\symbolicfont{MetaLogo}} + +\let\logofont\nullfont + +\loadmapfile[original-base.map] + +\unexpanded\def\setMFPfont% more sensitive for low level changes + {\font\logofont=logo% + \ifx\fontalternative\c!bf\else + \ifx\fontalternative\c!it\else + \ifx\fontalternative\c!sl\else + \ifx\fontalternative\c!bi\else + \ifx\fontalternative\c!bs\else + \fi\fi\fi\fi\fi + 10 at \currentfontscale\bodyfontsize + \logofont} + +%\unexpanded\def\MetaFont% +% {\hbox{\setMFPfont METAFONT}} +% +%\unexpanded\def\MetaPost% +% {\hbox{\setMFPfont METAPOST}} + +\def\MetaHyphen% there is no hyphenchar in this font + {\discretionary{\vrule\!!height.33em\!!depth-.27em\!!width.33em}{}{}} + +\unexpanded\def\MetaFont + {{\setMFPfont META\MetaHyphen FONT}} + +\unexpanded\def\MetaPost + {{\setMFPfont META\MetaHyphen POST}} + +\unexpanded\def\MetaFun + {MetaFun} + +%D \macros +%D {TEX, METAFONT, METAPOST, METAFUN, +%D PICTEX, TABLE, +%D CONTEXT, PPCHTEX, +%D AMSTEX, LATEX, LAMSTEX} +%D +%D We define the funny written ones as well as th eless +%D error prone upper case names (in \CONTEXT\ we tend to +%D write all user defined commands, like abbreviations, in +%D uppercase.) + +\unexpanded\def\METAFONT {\MetaFont} +\unexpanded\def\METAPOST {\MetaPost} +\unexpanded\def\PPCHTEX {\PPCHTeX} +\unexpanded\def\CONTEXT {\ConTeXt} +\unexpanded\def\METAFUN {\MetaFun} + +\unexpanded\def\TEX {\TeX} +\unexpanded\def\LATEX {\LaTeX} +\unexpanded\def\PICTEX {\PiCTeX} +\unexpanded\def\TABLE {\TaBlE} +\unexpanded\def\AMSTEX {\AmSTeX} +\unexpanded\def\LAMSTEX {\LamSTeX} +\unexpanded\def\INRSTEX {inrs\TeX} + +%D And this is how they show up: \TeX, \MetaFont, \MetaPost, +%D \PiCTeX, \TaBlE, \ConTeXt, \PPCHTeX, \AmSTeX, \LaTeX, +%D \LamSTeX. + +% \def\TEXEDIT {\TeX edit} +% \def\TEXFORM {\TeX form} +% \def\TEXADRES {\TeX adres} +% \def\TEXSPELL {\TeX spell} +% \def\TEXUTIL {\TeX util} +% \def\TEXEXEC {\TeX exec} + +%D Some placeholders: + +\unexpanded\def\eTeX {\mathematics{\varepsilon}-\TeX} +\unexpanded\def\pdfTeX {pdf\TeX} +\unexpanded\def\pdfeTeX{pdfe-\TeX} +\unexpanded\def\luaTeX {lua\TeX} +\unexpanded\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) + +% \unexpanded\def\XeTeX +% {X\lower.5ex +% \hbox +% {\kern-.15em +% \ifx\XeTeXcharglyph\undefined +% \mirror{E}% +% \else\ifcase\XeTeXcharglyph"018E\relax +% \mirror{E}% +% \else +% \char"018E% +% \fi}% +% \kern-.1667em \TeX} + +% Adapted from a patch by Mojca: + +\def\@XeTeX@ + {\setbox\scratchbox\hbox{E}% + \raise\dimexpr\ht\scratchbox+\dp\scratchbox\relax\hbox{\rotate[\c!rotation=180]{\box\scratchbox}}} + +\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 +\let\PDFETEX\pdfeTeX +\let\LUATEX \luaTeX +\let\LuaTeX \luaTeX +\let\XETEX \XeTeX + +\unexpanded\def\MkApproved + {\dontleavehmode\rotate + [\c!rotation={\ifnum\texengine=\luatexengine\ctxlua{tex.write(45-45*\the\luatexversion/100)}\else0\fi}, + \c!align=\v!middle, + \c!foregroundstyle=\v!type, + \c!foregroundcolor=darkred, + \c!frame=\v!on, + \c!offset=1ex, + \c!background=\v!color, + \c!backgroundcolor=lightgray, + \c!framecolor=darkred, + \c!rulethickness=2pt] + {Mk\ifnum\texengine=\luatexengine IV\else II\fi\\approved}} + + +% \unexpanded\def\luaTeX +% {\dontleavehmode\begingroup +% Lua% +% \setbox0\hbox{oT}% +% \setbox2\hbox{o\kern0ptT}% +% \ifdim\wd0=\wd2 +% \setbox0\hbox dir TRT{To}% +% \setbox2\hbox{T\kern0pto}% +% \hskip\dimexpr\wd0-\wd2\relax +% \fi +% \TeX +% \endgroup} +% +% a further iteration from the list, patched again + +% \ifx\fontalternative\c!it -\else +% \ifx\fontalternative\c!sl -\else +% \ifx\fontalternative\c!bi -\else +% \ifx\fontalternative\c!bs -\fi\fi\fi\fi + +\def\LuaTeX + {\dontleavehmode + \begingroup + Lua% + % hope for kerning, try aT + \setbox0\hbox{aT}% + \setbox2\hbox{a\kern\zeropoint T}% + \ifdim\wd0=\wd2 % kerns can go two ways + % no aT kerning, try oT as a is not symmetrical + \setbox0\hbox{oT}% + \setbox2\hbox{o\kern\zeropoint T}% + \ifdim\wd0=\wd2 % kerns can go two ways + % no aT and oT kerning, try To + \setbox0\hbox{To}% + \setbox2\hbox{T\kern\zeropoint o}% + % maybe we need to compensate for the angle (sl/it/bs/bi) + \fi + \ifdim\wd0=\wd2\else + \kern\dimexpr\wd0-\wd2\relax + \fi + \fi + \TeX + \endgroup} + +\let\luaTeX \LuaTeX +\let\LUATEX \LuaTeX + +\protect \endinput diff --git a/tex/context/base/cont-mtx.tex b/tex/context/base/cont-mtx.tex new file mode 100644 index 000000000..833785a7f --- /dev/null +++ b/tex/context/base/cont-mtx.tex @@ -0,0 +1,25 @@ +%D \module +%D [ file=cont-mtx, +%D version=2006.01.01, % no date -) +%D title=\CONTEXT\ Miscellaneous Macros, +%D subtitle=Experimental MetaTeX 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. + +% format generation : texexec --make --all --luatex +% +% pdftex compatible run : texexec --luatex filename +% aleph compatible run : texexec --luatex --output=dvipdfmx filename +% +% or, at top of tex file : % engine=luatex + +% \loadcorefile{meta-xxx.tex} + +%D Here we load files that are not yet part of the core. + +\endinput diff --git a/tex/context/base/cont-new.mkii b/tex/context/base/cont-new.mkii new file mode 100644 index 000000000..2defba6d7 --- /dev/null +++ b/tex/context/base/cont-new.mkii @@ -0,0 +1,22 @@ +%D \module +%D [ file=cont-new, +%D version=1995.10.10, +%D title=\CONTEXT\ Miscellaneous Macros, +%D subtitle=New 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. + +\enablemode[mkii] + +\long\def\startluacode#1\stopluacode{} +\long\def\ctxlua #1{} + +\def\enabletrackers [#1]{} +\def\disabletrackers[#1]{} + +\endinput diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv new file mode 100644 index 000000000..6269e5a61 --- /dev/null +++ b/tex/context/base/cont-new.mkiv @@ -0,0 +1,40 @@ +%D \module +%D [ file=cont-new, +%D version=2006.10.04, +%D title=\CONTEXT\ Miscellaneous Macros, +%D subtitle=New 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. + +% potential new defaults: +% +% \setbreakpoints[compound] + +\unprotect + +\ctxlua{logs.report = commands.report} % this will become default + +\def\immediatemessage#1{\ctxlua{commands.writestatus("message","#1")}} + +% 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 + +% till we fixed all styles + +\let\\=\crlf + +\protect \endinput diff --git a/tex/context/base/cont-new.tex b/tex/context/base/cont-new.tex new file mode 100644 index 000000000..9c4fdba18 --- /dev/null +++ b/tex/context/base/cont-new.tex @@ -0,0 +1,992 @@ +%D \module +%D [ file=cont-new, +%D version=1995.10.10, +%D title=\CONTEXT\ Miscellaneous Macros, +%D subtitle=New 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. + +\newcontextversion{2010.05.24 13:05} + +%D This file is loaded at runtime, thereby providing an +%D excellent place for hacks, patches, extensions and new +%D features. + +\unprotect + +% it's about time to clean up this file ... + +\writestatus\m!systems{beware: some patches loaded from cont-new.tex} + +% \ifx\pdfmapfile \undefined \else \pdfmapfile{ } \fi + +% \font\f=dummyfont \rpcode\f0=500 \hbox{..}\char0 +% todo: mp-new +% caption: grid=top|bottom in xml defs + +\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] +% \setupcaption [figure-2] [align=flushleft,leftmargin=10mm,rightmargin=-10mm,width=\textwidth] +% +% \startsetups somefigure +% \ifdim\floatsetupwidth>\textwidth +% \placesetupfloat[figure-2] +% \else +% \placesetupfloat[figure-1] +% \fi +% \stopsetups +% +% \placefloatwithsetups[somefigure]{}{\externalfigure[dummy][width=5cm,height=2cm]} + +\def\placefloatwithsetups + {\dotripleempty\doplacefloatwithsetups} + +\long\def\doplacefloatwithsetups[#1][#2][#3]#4% + {\def\floatsetupcaption {#4}% + \def\floatsetupcontent {\copy\nextbox}% + \def\floatsetupwidth {\wd\nextbox}% + \def\floatsetupheight {\ht\nextbox}% + \def\placesetupfloat[##1]{\placefloat[##1][#2][#3]{#4}{\floatsetupcontent}}% #4 and not \floatsetupcaption (unexpanded) + \dowithnextbox{\setups[#1]}\vbox} + +\def\dividedsize#1#2#3% size gap n + {\dimexpr + \ifnum\dimexpr#1\relax>\plusone + (\dimexpr#1\relax-\numexpr#3-1\relax\dimexpr#2\relax)/#3\else#1% + \fi + \relax} + +% \setuplabeltext[\s!itemcount1={{I(},{)}}] +% \def\labeledcountervalue#1{\labeltexts{#1}{\countervalue{#1}}} + +\def\singlewidened #1{\hbox spread 1em{\hss#1\hss}} +\def\complexwidened[#1]#2{\hbox spread #1{\hss#2\hss}} + +\definecomplexorsimple\widened + +% todo +% +% \def\definelocation{\dodoubleargument\dodefinelocation} +% \def\dodefinelocation[#1][#2]{\setvalue{loc:#1}{#2}} +% +% \definelocation[lt] [\v!left\v!top] +% \definelocation[tl] [\v!left\v!top] +% \definelocation[\v!top\v!left][\v!left\v!top] +% +% \def\getlocation#1{\executeifdefined{loc:#1}{#1}} + +% just in case we load something from a file (pdfr-ec for instance) + +\prependtoks \restoreendofline \to \everybeforeshipout + +\let\cs\getvalue + +% experimental so this may change + +\def\startdescriptions + {\dosingleempty\dostartdescriptions} + +\def\dostartdescriptions[#1]% + {\begingroup + \def\item{\getvalue{#1}}% + \let\dostoppairdescription \donothing + \let\@@description \dostartpairdescription + \let\@@startsomedescription\dostartsomedescription} + +\def\stopdescriptions + {\dostoppairdescription + \endgroup} + +\def\dostartpairdescription[#1][#2]% + {\dostoppairdescription + \def\dostoppairdescription{\@@stopdescription{#1}}% + \bgroup + \def\currentdescription{#1}% + \doifelse{\descriptionparameter{\s!do\c!state}}\v!start + {\@@makedescription{#1}[#2]{}} + {\@@makedescription{#1}[#2]}} + +\def\dostartsomedescription% #1[#2]#3% + {\bgroup + \@@makedescription} % {#1}[#2]{#3}} + +% \starttext +% +% \definedescription[test] +% +% \startdescriptions +% \test{Foo} Bar bar bar +% \test{Foo} Bar bar bar +% \test{Foo} Bar bar bar +% \stopdescriptions +% +% \startdescriptions[test] +% \item{Foo} Bar bar bar +% \item{Foo} Bar bar bar +% \item{Foo} Bar bar bar +% \stopdescriptions +% +% \startdescriptions +% \starttest{Foo} Bar bar bar \stoptest +% \starttest{Foo} Bar bar bar \stoptest +% \starttest{Foo} Bar bar bar \stoptest +% \stopdescriptions +% +% \startdescriptions[test] +% \item{Foo} Bar bar bar +% \item{Foo} Bar bar bar +% \item{Foo} Bar bar bar +% \stopdescriptions +% +% \stoptext + +% to do: +% +% \def\defineshapesynonym +% {\dodoubleargument\dodefineshapesynonym} +% +% \def\dodefineshapesynonym[#1][#2]% +% {\setvalue{shsy:#1}{#2}} +% +% \def\shapesynonym#1% +% {\ifcsname shsy:#1\endcsname +% \expandafter\shapesynonym\csname shsy:#1\endcsname\else#1% +% \fi} +% +%\defineshapesynonym[eacute] [e] +%\defineshapesynonym[egrave] [e] +%\defineshapesynonym[eumlaut [e] +%\defineshapesynonym[eogonek][e] +% +% more reduction +% +%\defineshapesynonym[e][o] +%\defineshapesynonym[w][v] +%\defineshapesynonym[m][n] +% +% \shapesynonym{eacute} + +% this will be activated when + +% \newinsert\thispageinsert % <- installinsertion + +% \def\flushatthispage +% {\bgroup +% \dowithnextbox{\insert\thispageinsert{\box\nextbox}\egroup}% +% \hbox} + +% \appendtoks +% \ifvoid\thispageinsert\else\hbox{\smashedbox\thispageinsert}\fi +% \to \everyshipout + +% \definemarkedpage[nobackgrounds] +% \markpage[nobackgrounds] +% \doifmarkedpageelse{nobackgrounds} + +\newcounter\nofmarkedpages + +\def\definemarkedpage[#1]% + {\definetwopasslist{\v!page:#1}} + +\def\markpage[#1]% looks very much like domarginreference + {\iftrialtypesetting\else + \doglobal\increment\nofmarkedpages\relax + \lazysavetwopassdata{\v!page:#1}{\nofmarkedpages}{\noexpand\realfolio}% + \fi} + +\def\doifmarkedpageelse#1% + {\gettwopassdatalist{\v!page:#1}% + \expanded{\doifinsetelse{\realfolio}{\twopassdatalist}}} + +% Just a simple and fast hanger, for usage in macros. + +\def\setuphanging + {\dodoubleempty\getparameters[\??ha]} + +\setuphanging + [\c!distance=.5em] + +\def\starthanging + {\noindent\bgroup + \dowithnextbox + {\setbox\nextbox\hbox{\flushnextbox\hskip\@@hadistance}% + \hangindent\nextboxwd + \hangafter\plusone + \flushnextbox\ignorespaces} + \hbox} + +\def\stophanging + {\endgraf + \egroup} + +% experimental + +\def\stophangaround + {\endgraf + \egroup} + +\def\starthangaround + {\noindent\bgroup + \dowithnextbox + {\ifdim\nextboxht>\strutht\setbox\nextbox\tbox{\flushnextbox}\fi + \setbox\nextbox\hbox{\flushnextbox\hskip\@@hadistance}% + \getboxheight\scratchdimen\of\box\nextbox + \getnoflines\scratchdimen + \nextboxht\strutht + \nextboxdp\strutdp + \hangindent\nextboxwd + \hangafter-\noflines + \llap{\flushnextbox}\ignorespaces} + \hbox} + +\def\modevalue#1#2#3% + {\@EA\ifx\csname\@mode@\systemmodeprefix#1\endcsname\endcsname\enabledmode#2\else#2\fi} + +\def\systemmodevalue#1% + {\modevalue{\systemmodeprefix#1}} + +% \getmulticolumnlines -> now in cont-loc, to be tested and really needed + +% \tracefonthandlingtrue + +% new, still to be improved +% +% \dorecurse{10} +% {\input thuan +% \placefigure{}{\framed[height=1.5cm]{test}} +% \placefloatplaceholder} + +\def\placefloatplaceholder + {\ifroomforfloat \else + \scratchdimen\pagegoal + \advance\scratchdimen-\pagetotal + \advance\scratchdimen-3\lineheight + \ifdim\scratchdimen>\zeropoint + \startlinecorrection[blank] + \mhbox{\inframed{\labeltexts{placeholder}{\lastcaptiontag}}}% + \stoplinecorrection + \else + \allowbreak + \fi + \fi} + +\setuplabeltext + [placeholder={, moved}] + +% etex only, of course we could just parse (scan for \% in string) + +\newif\ifpercentdimendone + +\bgroup % usage: \setpercentdimen\somedimen{% or dimen} todo: pct +\catcode124=\@@comment +\catcode 37=\@@active +\gdef\setpercentdimen#1#2| + {\xdef\@@expanded{#2}| + \ifx\@@expanded\empty\else + \bgroup + \global\percentdimendonefalse + \def\%{\dimexpr#1/100\relax\global\percentdimendonetrue\ignorespaces}| scantokens add's a space + \catcode`%=\@@active + \catcode`\\=\@@escape + \let%\%| + \scratchdimen#1| + \xdef\@@expanded{\@@expanded\scratchdimen\!!zeropoint}| trick: when 1.2 => .2\scratchdimen and 0pt typeset + \startnointerference + \global\globalscratchdimen\scantokens\@EA{\@@expanded}| i'm lazy and use etex + \stopnointerference + \egroup + #1\globalscratchdimen + \fi} +\egroup + +% TEX alternative, in principle accurate enough and also a bit faster + +% \bgroup +% +% \catcode`\%=\@@other +% \catcode`\|=\@@comment +% +% \gdef\setpercentdimen#1#2| +% {\beforesplitstring#2\at%\to\ascii +% \doifelse\ascii{#2} +% {#1=#2} +% {\divide#1by100\relax#1=\ascii#1\relax}} | or: {#1=\ascii#1\divide#1by100\relax}} +% +% \egroup +% +% \dimen0=1000pt \setpercentdimen{\dimen0}{10%} \the\dimen0 +% \dimen0= 100pt \setpercentdimen{\dimen0}{10%} \the\dimen0 +% \dimen0= 95pt \setpercentdimen{\dimen0}{10%} \the\dimen0 +% \dimen0= 10pt \setpercentdimen{\dimen0}{10%} \the\dimen0 +% \dimen0= 1pt \setpercentdimen{\dimen0}{10%} \the\dimen0 + +\bgroup + +\obeylines % don't remove %'s ! + +\gdef\collapsedspace#1% + {\ifx#1^^M% + \expandafter\collapsedspace + \else + \space + \expandafter#1% + \fi} + +\gdef\collapsespaces + {\prependtoksonce\relax\to\everyeof% + \ignorelines% + \ignoretabs% + \let\obeyedspace\collapsedspace% + \obeyspaces} + +\egroup + +\def\inlinedbox + {\bgroup + \dowithnextbox + {\scratchdimen\nextboxht + \advance\scratchdimen\nextboxdp + \advance\scratchdimen-\lineheight + \divide\scratchdimen\plustwo + \advance\scratchdimen\strutdepth + \setbox\nextbox\hbox{\lower\scratchdimen\flushnextbox}% + \nextboxht\strutht + \nextboxdp\strutdp + \flushnextbox + \egroup}% + \hbox} + +% \readfile{cont-exp}\donothing\donothing % speed up (5-20%) + +\def\dimenratio#1#2% etex only + {\withoutpt\the\dimexpr2\dimexpr(#1)/\dimexpr(#2)/32768\relax\relax} + +\def\doxprecurse#1#2% + {\ifnum#1=\zerocount % no \ifcase + \expandafter\gobblethreearguments + \else + #2\expandafter\expandafter\expandafter\doxprecurse\expandafter + \fi\expandafter{\the\numexpr#1-1\relax}{#2}} + +\def\buttonframed{\dodoubleempty\localframed[\??bt]} % goodie + +\unexpanded\def\asciistr#1{\dontleavehmode{\defconvertedargument\ascii{#1}\verbatimfont\ascii}} + +\def\shapefill{\vskip\zeropoint\!!plus\lineheight\!!minus\lineheight\relax} + +\let\normaltype\type + +\ifx\scantextokens\undefined + \ifx\scantokens\undefined + \unexpanded\def\retype#1{\dontleavehmode{\defconvertedargument\ascii{#1}\@EA\normaltype\@EA{\ascii}}} + \else + \unexpanded\def\retype#1{\dontleavehmode\scantokens{\normaltype{#1}\ignorespaces}\relax} + \fi +\else + \unexpanded\def\retype#1{\dontleavehmode\scantextokens{\normaltype{#1}}} +\fi + +\def\simplifytype{\let\type\retype} + +% \ruledhbox +% {\startignorespaces +% \def\oeps{a} +% \startignorespaces +% \def\oeps{a} +% \stopignorespaces +% \def\oeps{a} +% \stopignorespaces +% \oeps} + +\newsignal\boissignal +\newcount \boislevel + +\long\def\startignorespaces + {\advance\boislevel\plusone + \ifcase\boislevel\or \ifhmode + \hskip\boissignal + \fi \fi + \ignorespaces} + +\long\def\stopignorespaces + {\ifcase\boislevel\or \ifhmode + \doloop + {\ifdim\lastskip=\zeropoint + \exitloop + \else\ifdim\lastskip=\boissignal + \unskip + \exitloop + \else + \unskip + \fi\fi}% + \fi \fi + \advance\boislevel\minusone} + +\def\minimalhbox#1#% + {\dowithnextbox + {\bgroup + \setbox\scratchbox\hbox#1{\hss}% + \ifdim\nextboxwd<\wd\scratchbox\nextboxwd\wd\scratchbox\fi + \flushnextbox + \egroup} + \hbox} + +% \def\dodimchoice#1#2#3% +% {\ifx#3\relax +% #1\@EA\gobbleuntilrelax +% \else\ifdim#1#2% +% #3\@EAEAEA\gobbleuntilrelax +% \else +% \@EAEAEA\dodimchoice +% \fi\fi{#1}} + +% \def\donumchoice#1#2#3% +% {\ifx#3\relax +% #1\@EA\gobbleuntilrelax +% \else\ifnum#1#2% +% #3\@EAEAEA\gobbleuntilrelax +% \else +% \@EAEAEA\dodimchoice +% \fi\fi{#1}} + +% \def\dimchoice#1#2{\dodimchoice{#1}#2\empty\relax} +% \def\numchoice#1#2{\donumchoice{#1}#2\empty\relax} + +\def\gobbleuntilempty#1\empty{} + +\def\dodimchoice#1#2#3% + {\ifdim#1#2% + #3\@EA\gobbleuntilempty + \else + \@EA\dodimchoice + \fi{#1}} + +\def\donumchoice#1#2#3% + {\ifnum#1#2% + #3\@EA\gobbleuntilempty + \else + \@EA\dodimchoice + \fi{#1}} + +\def\dimchoice#1#2{\dodimchoice{#1}#2{=#1}{#1}\empty} +\def\numchoice#1#2{\donumchoice{#1}#2{=#1}{#1}\empty} + +% \the\dimexpr(\dimchoice {7pt}{{<10pt}{8pt}{<12pt}{9pt}{<15pt}{10pt}{=11pt}{12pt}}) +% \the\dimexpr(\dimchoice{11pt}{{<10pt}{8pt}{<12pt}{9pt}{<15pt}{10pt}{=11pt}{12pt}}) +% \the\dimexpr(\dimchoice{14pt}{{<10pt}{8pt}{<12pt}{9pt}{<15pt}{10pt}{=11pt}{12pt}}) + +\def\showsetupsdefinition[#1]{\showvalue{\??su:#1}} % temp hack for debugging + +% documentation : \setupregister[alternative=a|b|A|B] +\unprotected \def\traceposstring#1#2#3% + {\iftracepositions + \smashedhbox% + {#1{\infofont#2#3}% + \scratchdimen.5\points + \kern-2\scratchdimen + \vrule\!!width4\scratchdimen\!!height\scratchdimen\!!depth\scratchdimen}% + \fi} + +% will be a MyWay +% +% \setuplayout[grid=yes] \setupcaption[figure][inbetween=] \useMPlibrary[dum] \setupcolors[state=start] +% +% \starttext \showgrid \showstruts +% +% \input ward \placefigure{}{\externalfigure[dummy][width=.5\hsize,lines=1.4,grid=yes]} +% \input ward \placefigure{}{\externalfigure[dummy][width=.5\hsize,lines=1.4,grid=fit]} +% \input ward \placefigure{}{\externalfigure[dummy][width=.5\hsize,lines=1.4,grid=height]} +% \input ward +% \page +% \input ward \placefigure{}{\externalfigure[dummy][width=.5\hsize,lines=1.5,grid=yes]} +% \input ward \placefigure{}{\externalfigure[dummy][width=.5\hsize,lines=1.5,grid=fit]} +% \input ward \placefigure{}{\externalfigure[dummy][width=.5\hsize,lines=1.5,grid=height]} +% \input ward +% \page +% \input ward \placefigure{}{\externalfigure[dummy][width=.5\hsize,lines=1.6,grid=yes]} +% \input ward \placefigure{}{\externalfigure[dummy][width=.5\hsize,lines=1.6,grid=fit]} +% \input ward \placefigure{}{\externalfigure[dummy][width=.5\hsize,lines=1.6,grid=height]} +% \input ward +% \page +% \input ward \placefigure[none]{}{\externalfigure[dummy][width=.5\hsize,lines=1.4,grid=yes]} +% \input ward \placefigure[none]{}{\externalfigure[dummy][width=.5\hsize,lines=1.4,grid=fit]} +% \input ward \placefigure[none]{}{\externalfigure[dummy][width=.5\hsize,lines=1.4,grid=height]} +% \input ward +% \page +% \input ward \placefigure[none]{}{\externalfigure[dummy][width=.5\hsize,lines=1.5,grid=yes]} +% \input ward \placefigure[none]{}{\externalfigure[dummy][width=.5\hsize,lines=1.5,grid=fit]} +% \input ward \placefigure[none]{}{\externalfigure[dummy][width=.5\hsize,lines=1.5,grid=height]} +% \input ward +% \page +% \input ward \placefigure[none]{}{\externalfigure[dummy][width=.5\hsize,lines=1.6,grid=yes]} +% \input ward \placefigure[none]{}{\externalfigure[dummy][width=.5\hsize,lines=1.6,grid=fit]} +% \input ward \placefigure[none]{}{\externalfigure[dummy][width=.5\hsize,lines=1.6,grid=height]} +% \input ward +% +% \stoptext + +% funny, as field action with e.g. dissolve ... only the field dissolves, bug? + +\setglobalsystemreference\rt!exec{Transition}{transition} + +%def\PDFexecutetransition {/Trans /Trans <>} +\def\PDFexecutetransition {/Trans /Trans <<\executeifdefined{PDFpage\argumentA}\PDFpagereplace>>} + +% new, continuous blocks, \som \par \startdoorlopendblok ... + +% \startitemize +% \item bagger +% \item bagger +% \item \startdoorlopendblok bagger \stopdoorlopendblok +% \item \endgraf \startdoorlopendblok bagger \stopdoorlopendblok +% \item \endgraf \startdoorlopendblok \strut bagger \stopdoorlopendblok +% \item \startdoorlopendblok +% \starttabulate +% \NC test \NC test \NC \NR +% \NC test \NC test \NC \NR +% \NC test \NC test \NC \NR +% \stoptabulate +% \stopdoorlopendblok +% \item test +% \stopitemize + +\def\startdoorlopendblok % for special cases, don't change it too much and don't rely on it + {\ifhmode\endgraf\nobreak\fi % don't remove the \nobreak + \dowithnextboxcontent + {\setlocalhsize \hsize\localhsize \forgetall} + {\bgroup + \forgeteverypar + \forgetparskip + \scratchdimen\nextboxht + \advance\scratchdimen\nextboxdp + \getnoflines\scratchdimen + \advance\scratchdimen-\strutheight + \setbox\nextbox\hbox{\lower\scratchdimen\box\nextbox}% + \ht\nextbox\strutheight + \dp\nextbox\strutdepth + \setbox\nextbox\vbox + {\indent\box\nextbox + \endgraf + \nobreak + \advance\noflines\minusone + \dorecurse\noflines{\crlf\nobreak}}% + \verticalstrut + \endgraf + \nobreak + \offinterlineskip + \kern-2\lineheight % 2\lineheight when no vertical struts in main \vbox + \nobreak + \unvbox\nextbox + \prevdepth\strutdepth + % evt (eerst testen) een signal zodat een direct volgend blok goed gaat) + \egroup} + \vbox\bgroup + \vskip-\lineheight \verticalstrut\endgraf + \insidefloattrue + \doinhibitblank} % beware, no \inhibitblank ! ! ! ! ! ! + +\def\stopdoorlopendblok + {\endgraf\verticalstrut\endgraf\kern-2\lineheight + \egroup} + +\def\tabulaterule % to be redone, not correct + {\dotabulaterule + {\hrule\!!height.5\scratchdimen\!!depth.5\scratchdimen\relax + \doifvalue{\??tt\currenttabulate\c!distance}\v!grid + {\kern-\scratchdimen}}} % experimental tm-prikkels + +% experimental: \synchronizegrid bla bla bla + +\newcounter\currentgridsync + +\def\gridsynctag{grs:\currentgridsync} + +\def\synchronizegrid + {\doglobal\increment\currentgridsync + \par\prevdepth\zeropoint + \nointerlineskip + \hpos\gridsynctag{\strut}\par + \vskip-\lineheight + \nointerlineskip + % top of text + \scratchdimen\MPy{\v!text:\MPp\gridsynctag}% + \advance\scratchdimen\MPh{\v!text:\MPp\gridsynctag}% + % move to first baseline + \advance\scratchdimen-\topskip + % subtract wrong baseline + \advance\scratchdimen-\MPy\gridsynctag + % get minimal number of lines + \advance\scratchdimen\lineheight + \getnoflines\scratchdimen + % calculate difference + \advance\scratchdimen-\noflines\lineheight\relax + \scratchdimen-\scratchdimen\relax + \ifdim\scratchdimen>\zeropoint + \nointerlineskip + \advance\scratchdimen-\lineheight + \vskip\scratchdimen \dontleavehmode \quad \strut + \par + %\else + % \message{no grid correction: \the\scratchdimen}\wait + \fi} + +% needed for extreme (will go away) + +\definesystemvariable{ie} + +\def\definetest + {\dodoubleempty\dodefinetest} + +\def\dodefinetest[#1][#2]#3% + {\setgvalue{\??ie#1}{#3}% + \ifsecondargument + \processaction + [#2] + [% first test true, rest depends + \v!next=>\setgvalue{\??ie#1}{\setgvalue{\??ie#1}{#3}\firstoftwoarguments}, + % rest true if first true + % \v!first=>\setgvalue{\??ie#1}{#3{\letgvalue{\??ie#1}% + % \firstoftwoarguments\firstoftwoarguments}% + % \secondoftwoarguments}, + % always true + \v!yes=>\letgvalue{\??ie#1}\firstoftwoarguments, + % always false + \v!no=>\letgvalue{\??ie#1}\secondoftwoarguments]% + \fi} + +\def\doperformtest#1% + {\executeifdefined{\??ie#1}\secondoftwoarguments} + +\def\definecolumnsethsize#1#2#3#4% will be improved/speed up + {\bgroup + \def\OTRSETidentifier{#1}% + \ifcase\columnsetlevel\relax + \mofcolumns\plusone + \OTRSETinitializecolumns + \OTRSETassignwidths + \OTRSETsethsize + \fi + \!!counta#2\!!countb#3\docalculatecolumnsetspan + \expandafter\egroup\expandafter\edef\expandafter + #4\expandafter{\the\!!widtha}} + +% so far + +% between alignment lines certain rules apply, and even a +% simple test can mess up a table, which is why we have a +% special test facility +% +% \ruledvbox +% {\starttabulate[|l|p|] +% \NC 1test \NC test \NC \NR +% \tableifelse{\doifelse{a}{a}}{\NC Xtest \NC test \NC \NR}{}% +% \stoptabulate} + +\long\def\tableifelse#1% + {\TABLEnoalign{#1% + {\aftergroup \firstoftwoarguments}% + {\aftergroup\secondoftwoarguments}}} + +\long \def\tableiftextelse#1{\tableifelse{\doiftextelse{#1}}} + +% experiment, not yet to be used + +\def\displaybreak + {\ifhmode + \removeunwantedspaces + \ifcase\raggedstatus\hfill\fi + \strut\penalty-9999 % \break fails on case (3) + \fi} + +\def\startdisplay{\displaybreak\ignorespaces\startpacked} +\def\stopdisplay {\stoppacked\displaybreak\ignorespaces} + +\def\tightvbox{\dowithnextbox{\nextboxdp\zeropoint\flushnextbox}\vbox} +\def\tightvtop{\dowithnextbox{\nextboxht\zeropoint\flushnextbox}\vtop} + +% what is this stupid macro meant for: + +\def\hyphenationpoint + {\hskip\zeropoint} + +\def\hyphenated#1% + {\bgroup + \!!counta\zerocount + \def\hyphenated##1{\advance\!!counta\plusone}% + \handletokens#1\with\hyphenated + \!!countb\plusone + \def\hyphenated##1% + {##1% + \advance\!!countb\plusone\relax + \ifnum\!!countb>2 \ifnum\!!countb<\!!counta + \hyphenationpoint + \fi\fi}% + \handletokens#1\with\hyphenated + \egroup} + +\def\obeysupersubletters + {\let\super\normalsuper + \let\suber\normalsuber + \let\normalsuper\letterhat + \let\normalsuber\letterunderscore + \enablesupersub} + +\def\obeysupersubmath + {\let\normalsuper\letterhat + \let\normalsuber\letterunderscore + \enablesupersub} + +%\let\normaltype\type +% +%\def\type#1% +% {\expanded{\normaltype{\detokenize{#1}}}} + +% {x123 \os x123} {\tfa x123 \os x123} {x123 \tx x123 \os x123} +% \definefontsynonym[OldStyle][Serif] +% {x123 \os x123} {\tfa x123 \os x123} {x123 \tx x123 \os x123} + +% testen : +% +% \appendtoks +% \let\registerparoptions\relax +% \to \everyforgetall + +\def\startgridcorrection + {\dosingleempty\dostartgridcorrection} + +\def\dostartgridcorrection[#1]% + {\ifgridsnapping + \iffirstargument\doifsomething{#1}{\moveongrid[#1]}\fi + \snaptogrid\vbox\bgroup + \else + \startbaselinecorrection + \fi} + +\def\stopgridcorrection + {\ifgridsnapping + \egroup + \else + \stopbaselinecorrection + \fi} + +\def\checkgridsnapping + {\lineskip\ifgridsnapping\zeropoint\else\normallineskip\fi} + +\def\startplaatsen + {\dosingleempty\dostartplaatsen} + +\def\dostartplaatsen[#1]% tzt n*links etc + {\endgraf + \noindent\bgroup + \setlocalhsize + \hbox to \localhsize\bgroup + \doifnot{#1}\v!left\hss + \def\stopplaatsen + {\unskip\unskip\unskip + \doifnot{#1}\v!right\hss + \egroup + \egroup + \endgraf}% + \gobblespacetokens} + +% \startplaatsen[links] bla \stopplaatsen + +% we don't register the paragraph characteristics, only the +% width + +\appendtoks + \setinnerparpositions % see "techniek" for application +\to \everytabulate + +\def\fontclassname#1#2% + {\ifcsname\??ff#1#2\endcsname + \fontclassname{#1}{\csname\??ff#1#2\endcsname}% + \else\ifcsname\??ff#2\endcsname + \fontclassname{#1}{\csname\??ff#2\endcsname}% + \else + #2% + \fi\fi} + +\def\defineclassfontsynonym + {\dotripleargument\dodefineclassfontsynonym} + +\def\dodefineclassfontsynonym[#1][#2][#3]% + {\definefontsynonym[#1][\fontclassname{#2}{#3}]} + +%\definefontsynonym [KopFont] [\fontclassname{officina}{SerifBold}] +% +%\defineclassfontsynonym [KopFont] [officina] [SerifBold] + +\def\startcolumnmakeup % don't change + {\bgroup + \getrawnoflines\textheight % teksthoogte kan topskip hebben, dus raw + \scratchdimen\noflines\lineheight + \advance\scratchdimen-\lineheight + \advance\scratchdimen\topskip + \setbox\scratchbox + \ifcase\showgridstate\vbox\else\ruledvbox\fi to \scratchdimen\bgroup + \forgetall} % ! don't change + +\def\stopcolumnmakeup + {\egroup + \dp\scratchbox\zeropoint + \wd\scratchbox\textwidth + \box\scratchbox + \egroup + \synchronizehsize} + +\long\def\startexternalfigure + {\dotripleempty\dostartexternalfigure} + +\long\def\dostartexternalfigure[#1][#2][#3]#4\stopexternalfigure + {\gdef\figuredescription{#4}% + \externalfigure[#1][#2][#3]% + \globallet\figuredescription\empty} + +\let\figuredescription\empty + +%% where does this come from, old code probably +%% +%% +%% \newif\ifpagechanged \let\lastchangedpage\empty +%% +%% \def\checkpagechange#1% +%% {\gettwopassdata\s!paragraph +%% \pagechangedfalse +%% \iftwopassdatafound +%% \ifnum\twopassdata>0\getvalue{\s!paragraph:p:#1}\relax +%% \pagechangedtrue +%% \fi +%% \fi +%% \ifpagechanged +%% \letgvalue{\s!paragraph:p:#1}\twopassdata +%% \globallet\lastchangedpage\twopassdata +%% \else +%% \globallet\lastchangedpage\realfolio +%% \fi +%% \doparagraphreference} +%% +%% \def\changedpage#1% +%% {\getvalue{\s!paragraph:p:#1}} + +\newcount\nofprofiled + +\def\profilemacro#1% + {\nofprofiled\zerocount + \letvalue{\string#1\string#1}#1% + \appendtoks + \normalwritestatus\m!systems{profile \string#1: \number\nofprofiled}% + \to \everystoptext + \unexpanded\def#1% + {\global\advance\nofprofiled\plusone + \csname\string#1\string#1\endcsname}} + +% incomplete, will be a special case of float placement + +\def\startfixed{\dosingleempty\dostartfixed} + +\def\dostartfixed[#1]% + {\expanded{\dowithnextbox{\noexpand\dodofixed{\ifhmode0\else1\fi}{#1}}}% + \vbox\bgroup + \setlocalhsize} + +\def\stopfixed + {\egroup} + +\def\dodofixed#1#2% + {\ifcase#1\relax + \processaction + [#2] + [ \v!high=>\bbox {\flushnextbox}, + \v!low=>\tbox {\flushnextbox}, + \v!middle=>\vcenter{\flushnextbox}, + \v!lohi=>\vcenter{\flushnextbox}, + \s!unknown=>\tbox {\flushnextbox}, + \s!default=>\tbox {\flushnextbox}]% + \else + \startbaselinecorrection + \noindent\flushnextbox + \stopbaselinecorrection + \fi} + +% \startitemize +% +% \item \externalfigure[koe][height=2cm] +% \item \externalfigure[koe][height=2cm] +% \item \externalfigure[koe][height=2cm] +% \item \externalfigure[koe][height=2cm] +% +% \page +% +% \item \startfixed \externalfigure[koe][height=2cm]\stopfixed +% \item \startfixed[high]\externalfigure[koe][height=2cm]\stopfixed +% \item \startfixed[low] \externalfigure[koe][height=2cm]\stopfixed +% \item \startfixed[lohi]\externalfigure[koe][height=2cm]\stopfixed +% +% \page +% +% \item test \startfixed \externalfigure[koe][height=2cm]\stopfixed +% \item test \startfixed[high]\externalfigure[koe][height=2cm]\stopfixed +% \item test \startfixed[low] \externalfigure[koe][height=2cm]\stopfixed +% \item test \startfixed[lohi]\externalfigure[koe][height=2cm]\stopfixed +% +% \page +% +% \item test \par \startfixed \externalfigure[koe][height=2cm]\stopfixed +% \item test \par \startfixed[high]\externalfigure[koe][height=2cm]\stopfixed +% \item test \par \startfixed[low] \externalfigure[koe][height=2cm]\stopfixed +% \item test \par \startfixed[lohi]\externalfigure[koe][height=2cm]\stopfixed +% +% \stopitemize + +\def\obeyfollowingtoken{{}} % end \cs scanning + +% \def\comparedimension#1#2% +% {\chardef\compresult +% \ifdim#1<#2% +% \zerocount +% \else\ifdim#1<#2% +% \plusone +% \else +% \plustwo +% \fi\fi} +% \newdimen\roundingeps \roundingeps=10sp +% \def\comparedimensioneps#1#2% +% {\chardef\compresult +% \ifdim\dimexpr(#1-#2)<\roudingeps +% \zerocount +% \else\ifdim\dimexpr(#2-#1)<\roudingeps +% \zerocount +% \else\ifdim#1<#2% +% \plusone +% \else +% \plustwo +% \fi\fi\fi} + +%D Next we load a few local optimizations and new features. They +%D live on on my machine and are not distributed, but they may end +%D up in the distributed files. + +\loadmarkfile{cont-new} + +\readsysfile {cont-loc} {} {} % local improvements, patches, new features +\readsysfile {cont-exp} {} {} % experimental features (e.g. local speed-ups) +%readsysfile {cont-mtx} {} {} % experimental metatex features + +\protect \endinput diff --git a/tex/context/base/cont-nl.tex b/tex/context/base/cont-nl.tex new file mode 100644 index 000000000..32b82b01a --- /dev/null +++ b/tex/context/base/cont-nl.tex @@ -0,0 +1,42 @@ +%D \module +%D [ file=cont-nl, +%D version=1997.08.19, +%D title=\CONTEXT, +%D subtitle=\CONTEXT\ Dutch Format 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. + +\catcode`\{=1 \catcode`\}=2 \def\defaultinterface{dutch} + +\input context.tex + +\unprotect + +\setupcurrentlanguage[\s!nl] + +\loaduserspecifications + +\installlanguage [\s!us] [\c!state=\v!start] +\installlanguage [\s!gb] [\c!state=\v!start] +\installlanguage [\s!de] [\c!state=\v!start] +\installlanguage [\s!fr] [\c!state=\v!start] +\installlanguage [\s!es] [\c!state=\v!start] +\installlanguage [\s!nl] [\c!state=\v!start] +\installlanguage [\s!it] [\c!state=\v!start] + +\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 new file mode 100644 index 000000000..360b5f2e6 --- /dev/null +++ b/tex/context/base/cont-old.tex @@ -0,0 +1,48 @@ +%D \module +%D [ file=cont-old, +%D version=1995.10.10, +%D title=\CONTEXT\ Miscellaneous Macros, +%D subtitle=Old 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 Old Macros} + +\unprotect + +\def\middleraggedness {6\bodyfontsize} + +\def\dosubstitutecommand#1#2% + {\writestatus\m!systems{\string#1\normalspace -> \string#2}% + \gdef#1{#2}% + #2} + +\def\substitutecommand#1#2% + {\gdef#1{\dosubstitutecommand{#1}{#2}}} + +\substitutecommand \volgendehoofdstuk {\setupheadnumber[hoofdstuk][+1]} +\substitutecommand \volgendeparagraaf {\setupheadnumber[paragraaf][+1]} +\substitutecommand \volgendesubparagraaf {\setupheadnumber[subparagraaf][+1]} +\substitutecommand \volgendesubsubparagraaf {\setupheadnumber[subsubparagraaf][+1]} + +\substitutecommand \volledigeinhoudsopgave \volledigeinhoud +\substitutecommand \plaatsinhoudsopgave \plaatsinhoud +\substitutecommand \stelinhoudsopgavein \stelinhoudin + +\substitutecommand \streep \onderstreep +\substitutecommand \strepen \onderstrepen + +\substitutecommand \pragmakenmerk \referral + +\substitutecommand \definieersynoniem \definesynonyms + +\substitutecommand \setupintermezzos \setupintermezzi + +\let \Everybodyfont \EveryBodyFont + +\protect \endinput diff --git a/tex/context/base/cont-pe.tex b/tex/context/base/cont-pe.tex new file mode 100644 index 000000000..fdf47d680 --- /dev/null +++ b/tex/context/base/cont-pe.tex @@ -0,0 +1,45 @@ +%D \module +%D [ file=cont-en, +%D version=1997.08.19, +%D title=\CONTEXT, +%D subtitle=\CONTEXT\ English Format 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. + +\catcode`\{=1 \catcode`\}=2 \def\defaultinterface{persian} \def\messageinterface{english} + +\input context.tex + +\unprotect + +\setupcurrentlanguage[\s!pe] + +\loaduserspecifications + +% Do we need more defaults? or maybe all languages? + +\installlanguage [\s!us] [\c!state=\v!start] +\installlanguage [\s!gb] [\c!state=\v!start] +\installlanguage [\s!de] [\c!state=\v!start] +\installlanguage [\s!fr] [\c!state=\v!start] +\installlanguage [\s!es] [\c!state=\v!start] +\installlanguage [\s!it] [\c!state=\v!start] +\installlanguage [\s!nl] [\c!state=\v!start] +\installlanguage [\s!pe] [\c!state=\v!start] + +\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 new file mode 100644 index 000000000..9be9b1162 --- /dev/null +++ b/tex/context/base/cont-ro.tex @@ -0,0 +1,38 @@ +%D \module +%D [ file=cont-ro, +%D version=2000.01.09, +%D title=\CONTEXT, +%D subtitle=\CONTEXT\ Romanian Format 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. + +\catcode`\{=1 \catcode`\}=2 \def\defaultinterface{romanian} + +\input context.tex + +\unprotect + +\setupcurrentlanguage[\s!ro] + +\loaduserspecifications + +\installlanguage [\s!en] [\c!state=\v!start] +\installlanguage [\s!de] [\c!state=\v!start] +\installlanguage [\s!ro] [\c!state=\v!start] + +\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 new file mode 100644 index 000000000..11c0141e7 --- /dev/null +++ b/tex/context/base/cont-sys.ori @@ -0,0 +1,182 @@ +%D \module +%D [ file=cont-sys, +%D version=1995.10.10, +%D title=\CONTEXT\ Miscellaneous Macros, +%D subtitle=System Specific Setups, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 + +% Speed up typescript loading, but at the cost of much memory: + +\preloadtypescripts + +% If you want another default font: +% +% \let\preloadfonts\relax +% \usetypescript[palatino][\defaultencoding] +% \setupbodyfont[palatino,rm,12pt] +% +% Please make sure that this defines rm, ss, tt and mm. + +% Occasionally we will support both A4 and letter in +% styles. If you want letter size paper to be the default, +% uncomment: +% +% \enablemode[\systemmodeprefix letter] +% +% If you always want to default to letter, you may uncomment +% the following line, but beware: it makes your documents less +% portable: +% +% \setuppapersize[letter][letter] + +% If you want some extras, just uncomment the following +% line: +% +% \usemodule[plus] % experimental code +% +% Here you can take care of overloading some (style) +% defaults. What goes here, depends on your local system. + +% The following commands sets the default font encoding: +% +% \setupencoding [\s!default=texnansi] +% +% or: + +\setupencoding [\s!default=ec] + +% If you want the default berry names: +% +% \usetypescript [berry] [\defaultencoding] +% +% or, if you also want other encodings: + +\usetypescript [berry] [ec,t5,8r] % texnansi is never present + +% If you run into missing font metrics kind of problems, +% you may want to uncomment: +% +% \usetypescript[adobekb] [\defaultencoding] + +% You can let \CONTEXT\ load the map files for \PDFTEX. + +\autoloadmapfilestrue + +% (1) you can prevent loading with: +% +% \preloadmapfile[<...somename...>.map] +% +% (2) otherwise, use this if you have a fast machine +% +% \resetmapfiles \usetypescript [map] [base] [all] +% +% (3) or this if it's a slow one: + +\resetmapfiles + +% more recent versions of pdftex support map loading on each page + +\donefalse \ifx\pdftexversion\undefined \else \ifnum\number\pdftexversion>119 + \donetrue +\fi \fi \ifdone + + \loadmapfile[original-base.map] + \loadmapfile[original-ams-base.map] + \loadmapfile[original-ams-euler.map] + \loadmapfile[original-public-lm.map] + +\else + + \loadmapfile[original-base.map] + \loadmapfile[texnansi-base.map] + \loadmapfile[ec-base.map] + \loadmapfile[qx-base.map] + \loadmapfile[t5-base.map] + %loadmapfile[il2-base.map] + %loadmapfile[pl0-base.map] + \loadmapfile[8r-base.map] + + \loadmapfile[original-ams-base.map] + \loadmapfile[original-ams-euler.map] + + \loadmapfile[original-public-lm.map] + + %loadmapfile[texnansi-public-lm.map] + %loadmapfile[ec-public-lm.map] + %loadmapfile[qx-public-lm.map] + %loadmapfile[t5-public-lm.map] + %loadmapfile[pl0-public-lm.map] + %loadmapfile[il2-public-lm.map] + +\fi + +% When you have your own fonts installed, you may want to predefine: +% +% \usetypescriptfile[type-buy] + +% Some styles default to Lucida Bright. You can overload +% Lucida by Times cum suis. Watch out, the pos collection +% is not scaled relatively. +% +% \definetypescriptsynonym [lbr] [pos] + +% Compensate for missing files: +% +% \definefontsynonym [gbhei] [gbsong] +% \definefontsynonym [gbheisl] [gbsong] +% \definefontsynonym [gbheisl] [gbsong] + +% Setting up a global figure path +% +% \setupexternalfigures [\c!directory={e:/fig/eps,t:/mine/figs}] +% +% Loading a specific special driver: +% +% \setupoutput [dviwindo] + +% Changing language defaults +% +% \setuplanguage +% [nl] +% [\c!leftquote=\upperleftsinglesixquote, +% \c!leftquotation=\upperleftdoublesixquote] + +% Loading local preferences, for example +% +% \input prag-gen % company styles +% \input prag-log % more company styles +% +% Enabling run time \METAPOST\ (also enable \write18 in +% texmf.cnf): + +\runMPgraphicstrue +\runMPTEXgraphicstrue + +% This saves some runtime, but needs a format, which you can +% make with 'texexec --make --alone metafun'. Make sure that +% the mem files are moved to the used web2c path (locate with +% 'kpsewhich plain.mem'). + +\useMETAFUNformattrue + +% This can be a way to get things working on system with +% name clashes. (Some \TeX's tend do search system wide.) + +\protectbufferstrue + +% You can enable a more extensive figure searching, but +% normally this is not really needed and even annoying. +% +% \runutilityfiletrue + +% So far. + +\protect \endinput diff --git a/tex/context/base/cont-usr.ori b/tex/context/base/cont-usr.ori new file mode 100644 index 000000000..5a3070362 --- /dev/null +++ b/tex/context/base/cont-usr.ori @@ -0,0 +1,109 @@ +%D \module +%D [ file=cont-usr, +%D version=1997.10.05, +%D title=\CONTEXT\ User Format Specifications, +%D subtitle=System Specific Setups, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 User Settings} + +\unprotect + +%D Additional languages can be defined here. Beware of +%D encoding incompatibilities. Please take a look at the +%D \type {cont-en.tex}, \type {cont-nl.tex}, enz.\ files +%D first. Normally you don't have to change a byte. If you +%D want to play safe, use \typ {texexec --make --alone +%D --all}. + +% \preloadallpatterns % will load them all + +% \installlanguage [\s!af] [\c!state=\v!start] % afrikaans +% \installlanguage [\s!ca] [\c!state=\v!start] % catalan +% \installlanguage [\s!cs] [\c!state=\v!start] % czech +% \installlanguage [\s!da] [\c!state=\v!start] % danish +% \installlanguage [\s!de] [\c!state=\v!start] % german +% \installlanguage [\s!en] [\c!state=\v!start] % english us +% \installlanguage [\s!es] [\c!state=\v!start] % spanish +% \installlanguage [\s!fi] [\c!state=\v!start] % finnish +% \installlanguage [\s!fr] [\c!state=\v!start] % french +% \installlanguage [\s!hr] [\c!state=\v!start] % croatian +% \installlanguage [\s!hu] [\c!state=\v!start] % hungarian +% \installlanguage [\s!it] [\c!state=\v!start] % italian +% \installlanguage [\s!la] [\c!state=\v!start] % latin +% \installlanguage [\s!nl] [\c!state=\v!start] % dutch +% \installlanguage [\s!nb] [\c!state=\v!start] % bokmal +% \installlanguage [\s!nn] [\c!state=\v!start] % nynorsk +% \installlanguage [\s!pl] [\c!state=\v!start] % polish +% \installlanguage [\s!pt] [\c!state=\v!start] % portuguese +% \installlanguage [\s!ro] [\c!state=\v!start] % romanian +% \installlanguage [\s!ru] [\c!state=\v!start] % russian +% \installlanguage [\s!sk] [\c!state=\v!start] % slovak +% \installlanguage [\s!sl] [\c!state=\v!start] % slovenian +% \installlanguage [\s!sv] [\c!state=\v!start] % swedish +% \installlanguage [\s!tr] [\c!state=\v!start] % turkish +% \installlanguage [\s!ua] [\c!state=\v!start] % ukrainian +% \installlanguage [\s!gb] [\c!state=\v!start] % english uk +% \installlanguage [\s!vn] [\c!state=\v!start] % vietnamese + +% \installlanguage [deo] [\c!state=\v!start] % old german + +%D The next lines can be used for setting the language to be +%D used at startup time. + +% \setupcurrentlanguage[\s!af] +% \setupcurrentlanguage[\s!ca] +% \setupcurrentlanguage[\s!cs] +% \setupcurrentlanguage[\s!da] +% \setupcurrentlanguage[\s!de] +% \setupcurrentlanguage[\s!en] +% \setupcurrentlanguage[\s!es] +% \setupcurrentlanguage[\s!fi] +% \setupcurrentlanguage[\s!fr] +% \setupcurrentlanguage[\s!hr] +% \setupcurrentlanguage[\s!hu] +% \setupcurrentlanguage[\s!it] +% \setupcurrentlanguage[\s!la] +% \setupcurrentlanguage[\s!nl] +% \setupcurrentlanguage[\s!nb] +% \setupcurrentlanguage[\s!nn] +% \setupcurrentlanguage[\s!pl] +% \setupcurrentlanguage[\s!pt] +% \setupcurrentlanguage[\s!ro] +% \setupcurrentlanguage[\s!ru] +% \setupcurrentlanguage[\s!sk] +% \setupcurrentlanguage[\s!sl] +% \setupcurrentlanguage[\s!sv] +% \setupcurrentlanguage[\s!tr] +% \setupcurrentlanguage[\s!ua] + +%D Local font settings can go here. Normally suitable +%D defaults are already preloaded, almost certainly the +%D Computer Modern Roman typefaces or some derivate. So, the +%D next line is only meant as sample, take a look at the +%D format related files first. + +% This is obsolete due to latin modern: +% +% \definefilesynonym [font-cmr] [font-csr] % czech & slovak +% \definefilesynonym [font-cmr] [font-plr] % polish + +%D In some languages, compound characters, like \type {"e} +%D are used to get accented and non latin characters. + +% Per 21/9/2006 one needs to explicitly enable this. + +% \useencoding[fde] % german +% \useencoding[ffr] % french +% \useencoding[fro] % romanian +% \useencoding[fpl] % polish + +%D Don't remove the next few lines. + +\protect \endinput diff --git a/tex/context/base/context-base.lmx b/tex/context/base/context-base.lmx new file mode 100644 index 000000000..fd27927bf --- /dev/null +++ b/tex/context/base/context-base.lmx @@ -0,0 +1,76 @@ + + + + + + + + + <?lua pv('title') ?> + + 0) and v('refreshurl') then ?> + + + + + + + + +
+ + +
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+ +
+
+ +
+
+ + +
+ + diff --git a/tex/context/base/context-characters.lmx b/tex/context/base/context-characters.lmx new file mode 100644 index 000000000..f018e412b --- /dev/null +++ b/tex/context/base/context-characters.lmx @@ -0,0 +1,110 @@ + + + + + + + + + + <?lua pv('title') ?> + + + + +
+ +
+
+ +
+ + +
+ + +
     
+
characters     
+
unicodes     
+
indices     
+
fonts     
+ + +
     
+
before utf     
+
after utf     
+
before hex     
+
after hex     
+
after hex     
+
after dec     
+
filename     
+ + + + +
+
     
+
     
+
     
+
     
+
     
+
     
+
     
+ + + + +
+ + + + + + + + +

Processed Words

+ + + + + + + +
+
+ +
+
+ Job Name:     + ConTeXt Version:     +
+ + diff --git a/tex/context/base/context-debug.lmx b/tex/context/base/context-debug.lmx new file mode 100644 index 000000000..51b18c837 --- /dev/null +++ b/tex/context/base/context-debug.lmx @@ -0,0 +1,112 @@ + + + + + + + + + + <?lua pv('title') ?> + + + + +
+ +
+
+ +
+ +
+ +

Scratch Variables

+ + + + + + + + + + + + + + + +
index   dimen   count   toks
         
+
+ + + +
type
+
variable
+
value
+ + + + +
+
+
+ + + +

Internal Variables

+ + + + + +
+
+ + +

ConTeXt Variables

+ + + + + +
+
+ +
+
+ Job Name:     + ConTeXt Version:     + Real Page:     + Page:     +
+ + diff --git a/tex/context/base/context-error.lmx b/tex/context/base/context-error.lmx new file mode 100644 index 000000000..b82b552f8 --- /dev/null +++ b/tex/context/base/context-error.lmx @@ -0,0 +1,59 @@ + + + + + + + + + + <?lua pv('title')?> + + + + +
+ +
+
+ +
+ +
+ + + + +
Error   
File    
Line    
+
+
+            
+            
+
+
+ Job Name:     + ConTeXt Version:     + Real Page:     + Page:     +
+ + diff --git a/tex/context/base/context-fonttest.lmx b/tex/context/base/context-fonttest.lmx new file mode 100644 index 000000000..fddb8196b --- /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..5401fb65d --- /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..57b5879ba --- /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 new file mode 100644 index 000000000..f332ae242 --- /dev/null +++ b/tex/context/base/context.css @@ -0,0 +1,241 @@ +body { + color: #FFFFFF ; + background-color: ; + font-family: optima, verdana, futura, "lucida sans", arial, geneva, helvetica, sans ; + font-size: 12px ; + line-height: 18px ; +} +a:link, a:active, a:visited { + color: #FFFFFF ; +} +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 ; + font-size: 18px ; + line-height: 18px ; + margin-bottom: 20px ; +} +h2, .subtitle { + font-style: normal ; + font-weight: normal ; + font-size: 12px ; + margin-top: 18px ; + margin-bottom: 18px ; +} +table { + line-height: 18px ; + 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 ; +} +.empty-line { + margin-top: 4px ; +} +.more-room { + margin-right: 1.5em ; +} +.much-more-room { + margin-right: 3em ; +} +#main { + position: absolute; + left: 10% ; + top: 10% ; + right: 10% ; + bottom: 10% ; + z-index: 2 ; + width: 80% ; + height: 80% ; + padding: 0% ; + margin: 0% ; + overflow: auto ; + border-style: none ; + border-width: 0 ; + background-color: ; +} +#main-settings { + margin: 12px ; + x_max-width: 60em ; + line-height: 18px ; + font-size: 12px ; +} +#left { + position: absolute; + top : 10% ; + left: 0% ; + bottom: 0%; + right: 90% ; + z-index: 1 ; + width: 10% ; + height: 90% ; + padding: 0% ; + margin: 0% ; + font-size: 16px ; + border-style: none ; + border-width: 0 ; + background-color: ; +} +#right { + position: absolute; + top : 0% ; + left: 90% ; + bottom: 10% ; + right: 0% ; + z-index: 1 ; + width: 10% ; + height: 90% ; + padding: 0% ; + margin: 0% ; + font-size: 16px ; + border-style: none ; + border-width: 0 ; + background-color: ; + _margin-left: -15px ; +} +#bottom { + position: absolute ; + left: 10% ; + right: 0% ; + top: 90% ; + bottom: 0% ; + z-index: 1 ; + width: 90% ; + height: 10% ; + padding: 0% ; + margin: 0% ; + font-size: 16px ; + border-style: none ; + border-width: 0 ; + background-color: ; +} +#top { + position: absolute ; + left: 0% ; + right: 10% ; + top: 0% ; + bottom: 90% ; + z-index: 1 ; + width: 90% ; + height: 10% ; + padding: 0% ; + margin: 0% ; + font-size: 16px ; + border-style: none ; + border-width: 0 ; + background-color: ; +} +#top-one { + position: absolute ; + bottom: 50% ; + width: 100% ; + buggedheight: 100% ; +} +#top-two { + position: relative ; + margin-bottom: -9px ; + margin-left: 12px ; + margin-right: 12px ; + line-height: 18px ; + text-align: right ; + vertical-align: middle ; +} +#bottom-one { + position: absolute ; + bottom: 50% ; + width: 100% ; + buggedheight: 100% ; +} +#bottom-two { + position: relative ; + margin-bottom: -9px ; + margin-left: 12px ; + margin-right: 12px ; + line-height: 18px ; + text-align: left ; + vertical-align: middle ; +} +#left-one { + position: absolute ; + width: 100% ; + buggedheight: 100% ; +} +#left-two { + position: relative ; + margin-top: 12px ; + line-height: 18px ; + text-align: center ; + vertical-align: top ; +} +#right-one { + display: table ; + height: 100% ; + width: 100% ; +} +#right-two { + display: table-row ; + height: 100% ; + width: 100% ; +} +#right-three { + display: table-cell ; + width: 100% ; + vertical-align: bottom ; + _position: absolute ; + _top: 100% ; +} +#right-four { + text-align: center ; + margin-bottom: 2ex ; + _position: relative ; + _top: -100% ; +} +#more-top { + position: absolute; + top: 0% ; + left: 90% ; + bottom: 90%; + right: 0% ; + z-index: 3 ; + width: 10% ; + height: 10% ; + padding: 0% ; + margin: 0% ; + border-style: none ; + border-width: 0 ; +} +#more-top-settings { + text-align: center ; +} +#more-right-settings { + margin-right: 12px ; + margin-left: 12px ; + line-height: 18px ; + font-size: 10px ; + text-align: center ; +} +#right-safari { + display: table ; + width: 100% ; + height: 100% ; +} diff --git a/tex/context/base/context.mkii b/tex/context/base/context.mkii new file mode 100644 index 000000000..4be60cbfc --- /dev/null +++ b/tex/context/base/context.mkii @@ -0,0 +1,391 @@ +%D \module +%D [ file=context, +%D version=2008.28.10, % 1995.10.10, +%D title=\CONTEXT, +%D subtitle=\CONTEXT\ Format 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. + +%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} +\loadcorefile{syst-pln} + +\loadcorefile{norm-tex} +\loadcorefile{norm-etx} +\loadcorefile{norm-ptx} +\loadcorefile{norm-xtx} +\loadcorefile{norm-ctx} + +\loadmarkfile{catc-ini} +\loadcorefile{catc-act} +\loadcorefile{catc-def} +\loadcorefile{catc-ctx} +\loadcorefile{catc-sym} + +\loadmarkfile{syst-gen} +\loadmarkfile{syst-ext} +\loadmarkfile{syst-new} +\loadmarkfile{syst-con} +\loadcorefile{syst-ltx} +\loadmarkfile{thrd-trg} % based on: David Carlisle + +\loadmarkfile{syst-fnt} +\loadmarkfile{syst-str} +\loadmarkfile{syst-rtp} + +\ifnum\texengine=\xetexengine + \loadmarkfile{xetx-ini} + \loadmarkfile{xetx-utf} + \loadmarkfile{xetx-chr} + \loadmarkfile{xetx-cls} +\fi + +%D To enable selective loading, we say: + +\newif\ifCONTEXT \CONTEXTtrue % will disappear + +%D In order to conveniently load files, we need a few +%D support modules. + +\loadmarkfile{supp-fil} +\loadmarkfile{supp-dir} + +%D After this we're ready for the multi||lingual interface +%D modules. + +\loadmarkfile{mult-ini} +\loadcorefile{mult-fst} +\loadcorefile{mult-sys} +\loadcorefile{mult-def} +\loadmarkfile{mult-chk} + +%D Now we're ready for some general support modules. These +%D modules implement some basic typesetting functionality. + +\loadmarkfile{core-var} +\loadmarkfile{core-env} + +\loadcorefile{supp-box} +\loadmarkfile{supp-mrk} +\loadcorefile{supp-vis} +\loadcorefile{supp-fun} +%loadmarkfile{supp-eps} +\loadmarkfile{supp-spe} +\loadmarkfile{supp-ran} +\loadmarkfile{supp-mps} +\loadmarkfile{supp-tpi} +\loadmarkfile{supp-mat} +\loadcorefile{supp-ali} +\loadcorefile{supp-num} + +%D Verbatim typesetting is implemented in a separate class of +%D modules. The pretty typesetting modules are loaded at run +%D time. + +\loadmarkfile{verb-ini} + +%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: + +\loadmarkfile{page-ins} +\loadmarkfile{core-fil} +\loadmarkfile{core-con} + +%D We already need some synonyms (patterns). At runtime this +%D file will be reloaded. + +\loadcorefile{cont-fil} + +%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} % based on: Michael Wichura / will be reimplemented + +%D Here comes the last support modules. They take care of +%D some language specific things. + +\loadmarkfile{supp-pat} + +%D The next few modules do what their names state. They +%D load additional definition modules when needed. + +\loadmarkfile{regi-ini} +\loadcorefile{regi-syn} +\loadmarkfile{enco-ini} +%loadmarkfile{filt-ini} +\loadmarkfile{hand-ini} + +\loadmarkfile{lang-ini} +\loadmarkfile{lang-spe} +\loadmarkfile{lang-lab} + +\loadmarkfile{unic-ini} + +\loadmarkfile{core-gen} +\loadmarkfile{core-uti} +\loadmarkfile{core-two} +\loadmarkfile{core-stg} + +\loadmarkfile{spec-ini} +\loadmarkfile{spec-mis} +\loadmarkfile{spec-def} +\loadmarkfile{spec-var} + +\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. + +\loadmarkfile{lang-mis} +\loadmarkfile{lang-url} + +\loadcorefile{lang-ger} +\loadcorefile{lang-ita} +\loadcorefile{lang-sla} +\loadcorefile{lang-alt} +\loadcorefile{lang-ana} +\loadcorefile{lang-art} +\loadcorefile{lang-bal} +\loadcorefile{lang-cel} +\loadcorefile{lang-grk} +\loadcorefile{lang-ind} +\loadcorefile{lang-ura} +\loadcorefile{lang-vn} +\loadcorefile{lang-cyr} + +\loadmarkfile{typo-ini} + +%D All kind of symbols are handled in: + +\loadmarkfile{symb-ini} + +%D Sorting: + +\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. + +\loadmarkfile{spac-gen} +\loadmarkfile{spac-grd} + +\loadmarkfile{strc-mar} +\loadmarkfile{anch-pos} + +\loadmarkfile{buff-ver} +\loadmarkfile{buff-ini} + +\loadmarkfile{pack-rul} +\loadmarkfile{trac-vis} +\loadmarkfile{strc-num} +\loadmarkfile{tabl-com} +\loadmarkfile{tabl-pln} +\loadmarkfile{tabl-tab} +\loadmarkfile{tabl-tsp} +\loadmarkfile{scrn-nav} +\loadmarkfile{strc-ref} +\loadmarkfile{pack-obj} +\loadmarkfile{strc-lst} +\loadmarkfile{strc-itm} +\loadmarkfile{strc-des} +\loadmarkfile{strc-mat} % should come after math-pln etc +\loadmarkfile{strc-syn} +\loadmarkfile{core-sys} + +\loadmarkfile{page-ini} +\loadmarkfile{page-bck} +\loadmarkfile{page-not} +\loadmarkfile{page-one} +\loadmarkfile{page-lay} +\loadmarkfile{page-log} +\loadmarkfile{page-txt} +\loadmarkfile{page-sid} +\loadmarkfile{strc-flt} +\loadmarkfile{page-mis} +\loadmarkfile{page-mul} +\loadmarkfile{page-set} +\loadmarkfile{pack-lyr} +\loadmarkfile{page-mak} +\loadmarkfile{strc-pag} +\loadmarkfile{page-lin} +\loadmarkfile{page-par} +\loadmarkfile{page-mar} + +\loadmarkfile{core-job} % why so late? + +% so far + +\loadmarkfile{strc-sec} +\loadmarkfile{strc-swd} +\loadmarkfile{strc-blk} + +\loadmarkfile{page-imp} +\loadmarkfile{tabl-tbl} +\loadmarkfile{scrn-int} +\loadmarkfile{tabl-ntb} +\loadmarkfile{tabl-nte} +\loadmarkfile{tabl-ltb} + +%D A few more languages, that have specifics using core +%D functionality: + +%loadmarkfile{lang-ara} % undefined +\loadmarkfile{lang-chi} +\loadmarkfile{lang-jap} + +%D How about fill||in fields and related stuff? + +\loadmarkfile{java-ini} +\loadmarkfile{scrn-fld} +\loadmarkfile{scrn-hlp} + +%D Registers can depend on fields, so we load that now. + +\loadmarkfile{strc-reg} + +%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. + +\loadmarkfile{font-ini} + +\ifnum\texengine=\xetexengine + \loadmarkfile{font-xtx} +\fi + +\loadmarkfile{font-unk} +\loadmarkfile{font-uni} +\loadmarkfile{font-bfm} + +\loadmarkfile{enco-pfr} + +\loadmarkfile{type-ini} +\loadmarkfile{type-set} + +%D Properties. Don't ask. + +\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} + +\loadmarkfile{meta-pag} + +%D Special page handling (maybe even later) + +\loadmarkfile{page-flw} +\loadmarkfile{page-spr} +\loadmarkfile{page-plg} +\loadmarkfile{page-str} + +%D Anchoring graphics: + +\loadmarkfile{anch-pgr} +\loadmarkfile{anch-bar} +\loadmarkfile{anch-snc} + +%D Math. + +\loadmarkfile{math-pln} +\loadmarkfile{math-ini} +\loadmarkfile{math-arr} +\loadmarkfile{math-frc} + +%D Now we're ready for more core modules. + +\loadmarkfile{core-fnt} +\loadmarkfile{strc-not} +\loadmarkfile{strc-lnt} + +\loadmarkfile{core-mis} + +\loadmarkfile{grph-trf} +\loadmarkfile{grph-inc} +\loadmarkfile{grph-fig} + +\loadmarkfile{core-par} + +\loadmarkfile{pack-box} +\loadmarkfile{page-app} +\loadmarkfile{meta-fig} + +%D Language specific spacing. + +\loadcorefile{lang-spa} + +%D Bibliographies: + +\loadmarkfile{bibl-tra} + +%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. + +\loadcorefile{xtag-ini} +\loadcorefile{xtag-ext} +\loadcorefile{xtag-exp} +\loadcorefile{xtag-pre} +\loadcorefile{xtag-xsd} +\loadcorefile{xtag-rng} + +%D How about this: + +\loadcorefile{meta-xml} + +%D \TEX\ related logo's are always typeset in a special way. +%D Here they come: + +\loadcorefile{cont-log} + +%D This one overloads af few things: + +\loadmarkfile{core-ctx} + +%D Defaults go here (more will be moved to this module +%D later): + +\loadmarkfile{core-ini} +\loadmarkfile{core-def} + +%D Preloaded modules (some need xml support): + +%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 + +% %D Except from english, no hyphenation patterns are loaded +% %D yet. Users can specify their needs in the next module: +% +% \input cont-usr diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv new file mode 100644 index 000000000..33fa3a901 --- /dev/null +++ b/tex/context/base/context.mkiv @@ -0,0 +1,380 @@ +%D \module +%D [ file=context, +%D version=2008.28.10, % 1995.10.10, +%D title=\CONTEXT, +%D subtitle=\CONTEXT\ Format 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. + +% 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} + +\ifnum\luatexversion<60 % also change message + \writestatus{!!!!}{Your luatex binary is too old, you need at least version 0.60!} + \expandafter\end +\fi + +\newtoks\contextversiontoks \contextversiontoks\expandafter{\contextversion} % at the lua end + +\loadcorefile{norm-ctx} +\loadcorefile{syst-pln} + +\newif\ifCONTEXT \CONTEXTtrue % will disappear + +\loadmarkfile{luat-cod} +\loadmarkfile{luat-bas} +\loadmarkfile{luat-lib} + +\loadmarkfile{catc-ini} +\loadcorefile{catc-act} +\loadcorefile{catc-def} +\loadcorefile{catc-ctx} +\loadcorefile{catc-sym} + +% From here on we have \unexpanded being \normalprotected, as we +% already had \unexpanded long before etex came around. + +\loadmarkfile{syst-aux} +\loadmarkfile{syst-lua} +\loadmarkfile{syst-con} +\loadcorefile{syst-ltx} + +\loadmarkfile{syst-fnt} +\loadmarkfile{syst-str} +\loadmarkfile{syst-rtp} + +\loadmarkfile{supp-fil} +\loadmarkfile{supp-dir} + +\loadmarkfile{char-ini} +\loadmarkfile{char-utf} +\loadmarkfile{char-act} + +\loadmarkfile{mult-ini} +\loadcorefile{mult-fst} +\loadcorefile{mult-sys} +\loadcorefile{mult-def} +\loadmarkfile{mult-chk} +\loadmarkfile{mult-cld} + +\loadmarkfile{luat-ini} + +\loadmarkfile{toks-ini} + +\loadmarkfile{node-ini} +\loadmarkfile{node-fin} +\loadmarkfile{node-mig} +\loadmarkfile{node-par} +%loadmarkfile{node-pag} + +\loadmarkfile{core-var} + +\loadmarkfile{back-ini} +\loadmarkfile{lpdf-ini} % some day back-ini will load this +\loadmarkfile{lpdf-pdx} % might be merged into lpdf-ini +\loadmarkfile{back-pdf} % some day back-ini will load this + +\loadmarkfile{attr-ini} + +\loadmarkfile{core-env} + +\loadmarkfile{trac-tex} +\loadmarkfile{trac-lmx} +\loadmarkfile{trac-deb} + +\loadmarkfile{blob-ini} % not to be used, we only use a helper + +\loadcorefile{supp-box} + +\loadcorefile{supp-vis} +\loadcorefile{supp-fun} + +\loadmarkfile{supp-ran} +\loadmarkfile{supp-mat} +\loadcorefile{supp-ali} +\loadcorefile{supp-num} + +\loadmarkfile{typo-ini} + +\loadmarkfile{page-ins} +\loadmarkfile{core-fil} +\loadmarkfile{core-con} + +\loadcorefile{cont-fil} + +\loadmarkfile{regi-ini} +\loadcorefile{regi-syn} +\loadmarkfile{enco-ini} +\loadmarkfile{hand-ini} + +\loadmarkfile{lang-ini} +\loadmarkfile{lang-lab} +\loadmarkfile{lang-wrd} + +\loadmarkfile{unic-ini} + +\loadmarkfile{core-gen} +\loadmarkfile{core-uti} +\loadmarkfile{core-two} + +\loadmarkfile{colo-ini} +\loadmarkfile{colo-ext} + +\loadmarkfile{trac-vis} + +\loadmarkfile{lang-mis} +\loadmarkfile{lang-url} + +\loadcorefile{lang-ger} +\loadcorefile{lang-ita} +\loadcorefile{lang-sla} +\loadcorefile{lang-alt} +\loadcorefile{lang-ana} +\loadcorefile{lang-art} +\loadcorefile{lang-bal} +\loadcorefile{lang-cel} +\loadcorefile{lang-grk} +\loadcorefile{lang-ind} +\loadcorefile{lang-ura} +\loadcorefile{lang-vn} +\loadcorefile{lang-cyr} + +\loadmarkfile{lang-ara} +\loadmarkfile{lang-cjk} + +\loadmarkfile{symb-ini} + +\loadmarkfile{sort-ini} + +\loadmarkfile{pack-rul} + +\loadmarkfile{lxml-ini} +\loadmarkfile{lxml-sor} + +\loadmarkfile{strc-ini} +\loadmarkfile{strc-doc} +\loadmarkfile{strc-mar} +\loadmarkfile{strc-prc} +\loadmarkfile{strc-sbe} +\loadmarkfile{strc-lst} +\loadmarkfile{strc-sec} +\loadmarkfile{strc-num} +\loadmarkfile{strc-ren} +\loadmarkfile{strc-xml} +\loadmarkfile{strc-pag} % hm, depends on core-num +\loadmarkfile{strc-def} % might happen later +\loadmarkfile{strc-ref} +\loadmarkfile{strc-reg} + +\loadmarkfile{spac-hor} +\loadmarkfile{spac-ver} +\loadmarkfile{spac-ali} +\loadmarkfile{spac-pag} +\loadmarkfile{spac-fnt} +\loadmarkfile{spac-par} +\loadmarkfile{spac-def} +\loadmarkfile{spac-grd} + +\loadmarkfile{anch-pos} + +\loadmarkfile{scrn-nav} +\loadmarkfile{pack-obj} + +\loadmarkfile{strc-itm} +\loadmarkfile{strc-des} +\loadmarkfile{strc-syn} + +\loadmarkfile{core-sys} + +\loadmarkfile{page-ini} +\loadmarkfile{page-flt} +\loadmarkfile{page-bck} +\loadmarkfile{page-not} +\loadmarkfile{page-one} +\loadmarkfile{page-lay} +\loadmarkfile{page-txt} +\loadmarkfile{page-sid} + +\loadmarkfile{strc-flt} + +\loadmarkfile{page-mis} +\loadmarkfile{page-mul} +\loadmarkfile{page-set} +\loadmarkfile{pack-lyr} +\loadmarkfile{page-mak} + +\loadmarkfile{page-lin} +\loadmarkfile{page-par} +\loadmarkfile{page-mar} + +\loadmarkfile{core-job} % why so late? + +\loadmarkfile{buff-ini} +\loadmarkfile{buff-ver} + +\loadmarkfile{strc-blk} + +\loadmarkfile{page-imp} + +\loadmarkfile{scrn-int} +\loadmarkfile{scrn-men} +\loadmarkfile{scrn-but} +\loadmarkfile{scrn-bar} +\loadmarkfile{strc-bkm} % bookmarks + +\loadmarkfile{tabl-com} +\loadmarkfile{tabl-pln} +\loadcorefile{thrd-tab} +\loadmarkfile{tabl-tab} +\loadmarkfile{tabl-tbl} +\loadmarkfile{tabl-ntb} +\loadmarkfile{tabl-nte} +\loadmarkfile{tabl-ltb} +\loadmarkfile{tabl-tsp} + +\loadmarkfile{java-ini} + +\loadmarkfile{scrn-fld} +\loadmarkfile{scrn-hlp} + +\loadmarkfile{char-enc} +\loadmarkfile{font-ini} +\loadmarkfile{font-unk} +\loadmarkfile{font-tra} +\loadmarkfile{font-uni} +\loadmarkfile{font-col} +\loadmarkfile{font-gds} + +\loadmarkfile{typo-spa} +\loadmarkfile{typo-krn} +\loadmarkfile{typo-mir} +\loadmarkfile{typo-brk} +\loadmarkfile{typo-cap} +\loadmarkfile{typo-dig} +\loadmarkfile{typo-rep} + +\loadmarkfile{type-ini} +\loadmarkfile{type-set} + +\loadmarkfile{scrp-ini} + +\loadmarkfile{prop-ini} +\loadmarkfile{prop-lay} +\loadmarkfile{prop-mis} + +\loadmarkfile{mlib-ctx} +\loadmarkfile{mlib-pdf} +\loadmarkfile{mlib-pps} + +\loadmarkfile{meta-ini} +\loadmarkfile{meta-tex} +\loadmarkfile{meta-pdf} +\loadmarkfile{meta-fun} + +\loadmarkfile{meta-pag} + +\loadmarkfile{page-flw} +\loadmarkfile{page-spr} +\loadmarkfile{page-plg} +\loadmarkfile{page-str} + +\loadmarkfile{anch-pgr} % overloads tabl-tbl +\loadmarkfile{anch-bar} +\loadmarkfile{anch-snc} + +\loadmarkfile{math-ini} +\loadmarkfile{math-pln} +\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} +\loadmarkfile{math-lan} + +\loadmarkfile{strc-mat} + +\loadmarkfile{chem-ini} +\loadmarkfile{chem-str} + +\loadmarkfile{core-fnt} +\loadmarkfile{node-rul} + +\loadmarkfile{strc-not} +\loadmarkfile{strc-lnt} + +\loadmarkfile{core-mis} + +\loadmarkfile{grph-trf} +\loadmarkfile{grph-inc} +\loadmarkfile{grph-fig} + +\loadmarkfile{pack-box} +\loadmarkfile{pack-bar} +\loadmarkfile{page-app} +\loadmarkfile{meta-fig} + +\loadmarkfile{node-bck} % overloads anch-pgr (experimental and undocumented) + +\loadcorefile{lang-spa} + +\loadmarkfile{bibl-bib} +\loadmarkfile{bibl-tra} + +\loadmarkfile{x-xtag} % at some point this will not be preloaded + +\loadcorefile{meta-xml} + +\loadcorefile{cont-log} + +\loadmarkfile{task-ini} + +\loadmarkfile{core-ctx} + +\loadmarkfile{core-ini} +\loadmarkfile{core-def} + +%usemodule[x][res-04] % xml resource libraries +%usemodule[x][res-08] % rlx runtime conversion +%usemodule[x][res-12] % rli external indentification + +\unprotect + +\setupcurrentlanguage[\s!en] + +\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 + +\appendtoks + \ctxlua { + statistics.report_storage("log") + statistics.save_fmt_status("\jobname","\contextversion","context.tex") + }% +\to \everydump + +\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 new file mode 100644 index 000000000..47489658e --- /dev/null +++ b/tex/context/base/context.tex @@ -0,0 +1,225 @@ +%D \module +%D [ file=context, +%D version=1995.10.10, +%D title=\CONTEXT, +%D subtitle=\CONTEXT\ Format 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. + +\catcode`\{=1 \catcode`\}=2 \catcode`\#=6 + +%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 +%D 2004.8.30 the low level interface is english. Watch out and adapt +%D your styles an modules. + +\edef\contextformat {\jobname} +\edef\contextversion{2010.05.24 13:05} + +%D For those who want to use this: + +\let\fmtname \contextformat +\let\fmtversion\contextversion + +\let\showcontextbanner\relax + +%D Here we will test for what branch of source files we will take. The +%D file suffix depends on the maintream engine: either lua enhanced, +%D or traditional: +%D +%D \starttyping +%D mki : low level dutch +%D mkii : low level english +%D mkiv : lua enhanced +%D \stoptyping +%D +%D There is no \type {mkiii} unless you want to tag the transition +%D version that way (going completely etex, code cleanup and such). + +\ifx\normalinput\undefined \let\normalinput\input \fi + +%D We have two versions, one for \PDFTEX\ and \XETEX, and one for +%D \LUATEX. + +\chardef\contextmarkmode = \ifx\directlua\undefined 2 \else 4 \fi + +\def\loadcorefile#1{\normalinput#1\relax} +\def\loadmarkfile#1{\normalinput#1.\mksuffix\relax} + +\ifnum\contextmarkmode=4 + \def\loadmarkiifile#1{} \let\loadmarkivfile\loadcorefile \edef\mksuffix {mkiv} \edef\contextmark{MKIV} +\else + \def\loadmarkivfile#1{} \let\loadmarkiifile\loadcorefile \edef\mksuffix {mkii} \edef\contextmark{MKII} +\fi + +\let\loadmkiifile\loadmarkiifile +\let\loadmkivfile\loadmarkivfile +\let\loadmkfile \loadmarkfile + +%D Welcome to the main module. When this module is ran through +%D \type{initex} or \type {tex -i} or \type {whatevertex} using +%D \type{whatever switch}, the \CONTEXT\ format file is +%D generated. During this process the user is asked for an +%D interface language. Supplying \type{dutch} will generate a +%D dutch version of \CONTEXT, supplying \type {english} will of +%D course end op in a english version. +%D +%D Another option is to use \TEXEXEC\ (for \MKII): +%D +%D \starttyping +%D texexec --make [--alone] [--engine] [--all] +%D texexec --make [--alone] [--engine] en nl ... metafun mptopdf +%D \stoptyping +%D +%D More information can be found in the \TEXEXEC\ manual. +%D +%D For \MKIV\ you have to do: +%D +%D \starttyping +%D luatools --generate +%D context --make en nl ... +%D \stoptyping + +%D When you write modules (or extensions) you should avoid +%D conflicts with existing macro names and mechanisms. If you are +%D coming from another macro package, don't assume that macros +%D with the same name are doing the same! \CONTEXT\ was written +%D from scratch and therefore similarities are often a coincidence +%D (to some extent one always ends up with the same names for +%D similar concepts). The underlying models for elementary subsystems +%D that deal with encodings, languages and fonts probably differ. +%D +%D Time has learned that users coming from \LATEX\ should not fall +%D into thinking that macros like \type {\protect} represent the +%D same functionality in both systems; actually, due to the way +%D \CONTEXT\ is set up, some of those macros do complete different +%D things. Macro packages evolve independent of each other, which +%D means that code written for one system will not work in another +%D system, unless it's real generic code. +%D +%D An API will become available soon (keep an eye on the ConTeXt +%D Wiki www.contextgarden.org) and or listen in to the context +%D mailing list (ntg-context@ntg.nl). Much additional information +%D can be found at the PRAGMA website (www.pragma-ade.com). + +%D We now go either the \MKII\ or \MKIV\ route: + +\loadmarkfile{context} + +%D Let's quit this file when doing a \type {cont-..} generation. + +\doifparentfileelse{context}{\donothing}{\endinput} + +%D Unless we're generating a \type {cont-..} format, we also +%D do the following. + +%D Except from english, no hyphenation patterns are loaded +%D yet. Users can specify their needs in the next module: + +\loaduserspecifications + +%D Next we default to the same language as the interface. + +\unprotect + +\installlanguage [\s!us] [\c!state=\v!start] + +\startinterface english + \installlanguage [\s!gb] [\c!state=\v!start] +\stopinterface + +\appendtoks \language [\s!us] \to \everyjob +\appendtoks \mainlanguage [\s!us] \to \everyjob + +\startinterface german + + \installlanguage [\s!de] [\c!state=\v!start] + + \appendtoks \language [\s!de] \to \everyjob + \appendtoks \mainlanguage [\s!de] \to \everyjob + +\stopinterface + +\startinterface dutch + + \installlanguage [\s!nl] [\c!state=\v!start] + + \appendtoks \language [\s!nl] \to \everyjob + \appendtoks \mainlanguage [\s!nl] \to \everyjob + +\stopinterface + +\startinterface czech + + \installlanguage [\s!cs] [\c!state=\v!start] + + \appendtoks \language [\s!cs] \to \everyjob + \appendtoks \mainlanguage [\s!cs] \to \everyjob + +\stopinterface + +\startinterface italian + + \installlanguage [\s!it] [\c!state=\v!start] + + \appendtoks \language [\s!it] \to \everyjob + \appendtoks \mainlanguage [\s!it] \to \everyjob + +\stopinterface + +\startinterface romanian + + \installlanguage [\s!ro] [\c!state=\v!start] + + \appendtoks \language [\s!ro] \to \everyjob + \appendtoks \mainlanguage [\s!ro] \to \everyjob + +\stopinterface + +\startinterface french + + \installlanguage [\s!fr] [\c!state=\v!start] + + \appendtoks \language [\s!fr] \to \everyjob + \appendtoks \mainlanguage [\s!fr] \to \everyjob + +\stopinterface + +\startinterface persian + + \installlanguage [\s!pe] [\c!state=\v!start] + + \appendtoks \language [\s!pe] \to \everyjob + \appendtoks \mainlanguage [\s!pe] \to \everyjob + +\stopinterface + +\protect + +%D Finally we (pre)load some fonts. + +\setupencoding[default=ec] + +\usetypescript[fallback][\defaultencoding] + +\setupbodyfont[rm,12pt] + +%D The next hook can be used to generate a local (extended) +%D format. This file is only searched for at the current +%D path. + +% \readlocfile{cont-def.tex} +% {\writestatus{loading}{adding extensions from cont-def}} +% {} + +%D Now dumping the format is all that's left to be done. + +\errorstopmode \dump + +\endinput diff --git a/tex/context/base/core-con.lua b/tex/context/base/core-con.lua new file mode 100644 index 000000000..dca1c7d10 --- /dev/null +++ b/tex/context/base/core-con.lua @@ -0,0 +1,605 @@ +if not modules then modules = { } end modules ['core-con'] = { + version = 1.001, + comment = "companion to core-con.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--[[ldx-- +

This module implements a bunch of conversions. Some are more +efficient than their counterpart, some are even +slower but look nicer this way.

+ +

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

+--ldx]]-- + +local utf = unicode.utf8 + +local floor, date, time, concat = math.floor, os.date, os.time, table.concat +local lower, format, rep = string.lower, string.format, string.rep +local texsprint, utfchar = tex.sprint, utf.char +local tonumber, tostring = tonumber, tostring + +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, + 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, + 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, + 0x007A + }, + ['slovenian'] = { + 0x0061, 0x0062, 0x0063, 0x010D, 0x0064, + 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, + 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, + 0x006F, 0x0070, 0x0072, 0x0073, 0x0161, + 0x0074, 0x0075, 0x0076, 0x007A, 0x017E + }, + ['greek'] = { -- this should be the lowercase table + 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, + 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, + 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, + 0x03A0, 0x03A1, 0x03A3, 0x03A4, 0x03A5, + 0x03A6, 0x03A7, 0x03A8, 0x03A9 + }, + ['arabic'] = { + 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'] = { + 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, + 0xE055, 0xE056, 0xE057, 0xE058, 0xE059 + }, + ['devangari'] = { + 0x0966, 0x0967, 0x0968, 0x0969, 0x096A, + 0x096B, 0x096C, 0x096D, 0x096E, 0x096F + }, + ['gurmurkhi'] = { + 0x0A66, 0x0A67, 0x0A68, 0x0A69, 0x0A6A, + 0x0A6B, 0x0A6C, 0x0A6D, 0x0A6E, 0x0A6F + }, + ['gujarati'] = { + 0x0AE6, 0x0AE7, 0x0AE8, 0x0AE9, 0x0AEA, + 0x0AEB, 0x0AEC, 0x0AED, 0x0AEE, 0x0AEF + }, + ['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['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 fallback = utf.byte('0') + +local function chr(n,m) + if n > 0 and n < 27 then + texsprint(utfchar(n+m)) + end +end +local function chrs(n,m) + if n > 26 then + chrs(floor((n-1)/26),m) + n = (n-1)%26 + 1 + end + texsprint(utfchar(n+m)) +end +local function maxchrs(n,m,cmd) + if n > m then + maxchrs(floor((n-1)/m),m,cmd) + n = (n-1)%m + 1 + end + texsprint(ctxcatcodes, format("%s{%s}",cmd,n)) +end + +converters.chr = chr +converters.chrs = chrs +converters.maxchrs = maxchrs + +--~ more efficient but needs testing +--~ +--~ local escapes = utffilters.private.escapes +--~ +--~ local function do_alphabetic(n,mapping,chr) +--~ local max = #mapping +--~ if n > max then +--~ do_alphabetic(floor((n-1)/max),max,chr) +--~ n = (n-1)%max+1 +--~ end +--~ n = chr(n,mapping) +--~ texsprint(ctxcatcodes,escapes[n] or utfchar(n)) +--~ end + +--~ local lccodes, uccodes = characters.lccode, characters.uccode + +--~ local function do_alphabetic(n,mapping,chr) +--~ local max = #mapping +--~ if n > max then +--~ do_alphabetic(floor((n-1)/max),mapping,chr) +--~ n = (n-1)%max+1 +--~ end +--~ characters.flush(chr(n,mapping)) +--~ end +--~ +--~ local function lowercased(n,mapping) return characters.lccode(mapping[n] or fallback) end +--~ local function uppercased(n,mapping) return characters.uccode(mapping[n] or fallback) end +--~ +--~ function converters.alphabetic(n,code) +--~ do_alphabetic(n,counters[code] or counters['**'],lowercased) -- lccode catches wrong tables +--~ end +--~ +--~ function converters.Alphabetic(n,code) +--~ do_alphabetic(n,counters[code] or counters['**'],uppercased) +--~ end + +-- + +local function do_alphabetic(n,mapping,mapper) + local chr = mapper(mapping[n] or fallback) + local max = #mapping + if n > max then + do_alphabetic(floor((n-1)/max),mapping,mapper) + n = (n-1)%max+1 + end + characters.flush(chr) +end + +function converters.alphabetic(n,code) + do_alphabetic(n,counters[code] or counters['**'],characters.lccode) +end + +function converters.Alphabetic(n,code) + do_alphabetic(n,counters[code] or counters['**'],characters.uccode) +end + +-- + +function converters.character (n) chr (n,96) end +function converters.Character (n) chr (n,64) end +function converters.characters(n) chrs(n,96) end +function converters.Characters(n) chrs(n,64) end + +function converters.weekday(day,month,year) + texsprint(date("%w",time{year=year,month=month,day=day})+1) +end + +function converters.isleapyear(year) + return (year % 400 == 0) or ((year % 100 ~= 0) and (year % 4 == 0)) +end + +function converters.leapyear(year) + if converters.isleapyear(year) then texsprint(1) else texsprint(0) end +end + +local days = { + [false] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + [true] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +} + +function converters.nofdays(year,month) + texsprint(days[converters.isleapyear(year)][month]) +end + +function converters.year () texsprint(date("%Y")) end +function converters.month () texsprint(date("%m")) end +function converters.hour () texsprint(date("%H")) end +function converters.minute () texsprint(date("%M")) end +function converters.second () texsprint(date("%S")) end +function converters.textime() texsprint(tonumber(date("%H"))*60+tonumber(date("%M"))) end + +local roman = { + { [0] = '', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX' }, + { [0] = '', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC' }, + { [0] = '', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM' }, +} + +local function toroman(n) + if n >= 4000 then + return toroman(floor(n/1000)) .. " " .. toroman(n%1000) + else + return rep("M",floor(n/1000)) .. roman[3][floor((n%1000)/100)] .. + roman[2][floor((n%100)/10)] .. roman[1][floor((n% 10)/1)] + end +end + +function converters.romannumerals(n) return texsprint(lower(toroman(n))) end +function converters.Romannumerals(n) return texsprint( toroman(n) ) end + +converters.toroman = toroman + +--~ local small = { +--~ 0x0627, 0x066E, 0x062D, 0x062F, 0x0647, 0x0648, 0x0631 +--~ } + +--~ local large = { +--~ { 0x0627, 0x0628, 0x062C, 0x062F, 0x0647, 0x0648, 0x0632, 0x062D, 0x0637, }, +--~ { 0x064A, 0x0643, 0x0644, 0x0645, 0x0646, 0x0633, 0x0639, 0x0641, 0x0635, }, +--~ { 0x0642, 0x0631, 0x0634, 0x062A, 0x062B, 0x062E, 0x0630, 0x0636, 0x0638, }, +--~ { 0x063A }, +--~ } + +local small = { + "ا", "ٮ", "ح", "د", "ه", "و", "ر", +} + +local medium = { + "ا", "ب", "ج", "د", "ه", "و","ز", "ح", "ط" , + "ي", "ك", "ل", "م", "ن", "س", "ع", "ف", "ص" , + "ق", "ر", "ش", "ت", "ث", "خ", "ذ", "ض", "ظ" , + "غ" , +} + +local large = { + { "ا", "ب", "ج", "د", "ه", "و","ز", "ح", "ط" }, + { "ي", "ك", "ل", "م", "ن", "س", "ع", "ف", "ص" }, + { "ق", "ر", "ش", "ت", "ث", "خ", "ذ", "ض", "ظ" }, + { "غ" }, +} + +function converters.toabjad(n,what) + if n <= 0 or n >= 2000 then + return tostring(n) + elseif what == 2 and n <= 7 then + return small[n] + elseif what == 3 and n <= 28 then + return medium[n] + else + local a, b, c, d + a, n = floor(n/1000), n % 1000 -- mod(n,1000) + b, n = floor(n/ 100), n % 100 -- mod(n, 100) + c, n = floor(n/ 10), n % 10 -- mod(n, 10) + d, n = floor(n/ 1), n % 1 -- mod(n, 1) + return (large[4][a] or "") .. (large[3][b] or "") .. (large[2][c] or "") .. (large[1][d] or "") + end +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 + +function tochinese(n,name) -- normal, caps, all + -- improved version by Li Yanrui + 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) + result[#result+1] = tochinese(m,name) + result[#result+1] = vector[100000000] + local z = n - m * 100000000 + if z > 0 and z < 10000000 then result[#result+1] = vector[0] end + n = n % 100000000 + elseif n >= 10000000 then + local m = floor(n/10000) + result[#result+1] = tochinese(m,name) + result[#result+1] = vector[10000] + local z = n - m * 10000 + if z > 0 and z < 1000 then result[#result+1] = vector[0] end + n = n % 10000 + elseif n >= 1000000 then + local m = floor(n/10000) + result[#result+1] = tochinese(m,name) + result[#result+1] = vector[10000] + local z = n - m * 10000 + if z > 0 and z < 1000 then result[#result+1] = vector[0] end + n = n % 10000 + elseif n >= 100000 then + local m = floor(n/10000) + result[#result+1] = tochinese(m,name) + result[#result+1] = vector[10000] + local z = n - m * 10000 + if z > 0 and z < 1000 then result[#result+1] = vector[0] end + n = n % 10000 + elseif n >= 10000 then + local m = floor(n/10000) + result[#result+1] = vector[m] + result[#result+1] = vector[10000] + local z = n - m * 10000 + if z > 0 and z < 1000 then result[#result+1] = vector[0] end + n = n % 10000 + elseif n >= 1000 then + local m = floor(n/1000) + result[#result+1] = vector[m] + result[#result+1] = vector[1000] + local z = n - m * 1000 + if z > 0 and z < 100 then result[#result+1] = vector[0] end + n = n % 1000 + elseif n >= 100 then + local m = floor(n/100) + result[#result+1] = vector[m] + result[#result+1] = vector[100] + local z = n - m * 100 + if z > 0 and z < 10 then result[#result+1] = vector[0] end + n = n % 100 + elseif n >= 10 then + local m = floor(n/10) + if m > 1 and 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 + if (result[1] == vector[1] and result[2] == vector[10]) then + result[1] = "" + end + return concat(result) +end + +--~ local t = { 1,10,15,25,35,45,11,100,111,1111,10000,11111,100000,111111,1111111,11111111,111111111,100000000,1111111111,11111111111,111111111111,1111111111111 } +--~ for k=1,#t do +--~ local v = t[k] +--~ 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 new file mode 100644 index 000000000..c39bdd9d4 --- /dev/null +++ b/tex/context/base/core-con.mkii @@ -0,0 +1,969 @@ +%D \module +%D [ file=core-con, +%D version=1997.26.08, +%D title=\CONTEXT\ Core Macros, +%D subtitle=Conversion, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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} + +\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. + +\def\romannumerals#1% + {\romannumeral#1} + +%D For some years we had \unknown +%D +%D \starttyping +%D \def\Romannumerals#1% +%D {\uppercase\expandafter{\romannumeral#1}} +%D \stoptyping +%D +%D \unknown but we need to be fully expandable in order to get +%D the utility output file right, so now we have the following +%D solution. It was Patrick Gundlach who first noticed this +%D ommision. + +\def\Romannumerals#1% + {\expandafter\doRomannumerals\number#1\relax} + +\def\doRomannumerals#1#2\relax % spaces after ifcase prevent \relax + {\ifnum#1#2<10 + \ifcase0#1#2 \or I\or II\or III\or IV\or V\or VI\or VII\or VIII\or IX\fi + \else\ifnum#1#2<100 + \ifcase0#1 \or X\or XX\or XXX\or XL\or L\or LX\or LXX\or LXXX\or XC\fi + \doRomannumerals#2\relax + \else\ifnum#1#2<1000 + \ifcase0#1 \or C\or CC\or CCC\or CD\or D\or DC\or DCC\or DCCC\or CM\fi + \doRomannumerals#2\relax + \else\ifnum#1#2<4000 + \ifcase0#1 \or M\or MM\or MMM\fi + \doRomannumerals#2\relax + \else + \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% + {\ifcase#1\unknowncharacter + \or a\or b\or c\or d\or e\or f\or g\or h\or i\or j\or k\or l\or m% + \or n\or o\or p\or q\or r\or s\or t\or u\or v\or w\or x\or y\or z% + \else + \unknowncharacter + \fi} + +\def\Character#1% + {\ifcase#1\unknowncharacter + \or A\or B\or C\or D\or E\or F\or G\or H\or I\or J\or K\or L\or M% + \or N\or O\or P\or Q\or R\or S\or T\or U\or V\or W\or X\or Y\or Z% + \else + \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 + \alpha \or \beta \or \gamma \or \delta \or + \varepsilon \or \zeta \or \eta \or \theta \or + \iota \or \kappa \or \lambda \or \mu \or + \nu \or \xi \or \omicron \or \pi \or + \varrho \or \sigma \or \tau \or \upsilon \or + \phi \or \chi \or \psi \or \omega + \else + \unknowncharacter + \fi}} + +\def\Greeknumerals#1% + {% no longer needed: \mathematics + {\ifcase#1\unknowncharacter \or + \Alpha \or \Beta \or \Gamma \or \Delta \or + \Epsilon \or \Zeta \or \Eta \or \Theta \or + \Iota \or \Kappa \or \Lambda \or \Mu \or + \Nu \or \Xi \or \Omicron \or \Pi \or + \Rho \or \Sigma \or \Tau \or \Upsilon \or + \Phi \or \Xi \or \Psi \or \Omega + \else + \unknowncharacter + \fi}} + +%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% + {\bgroup + \!!counta#3\relax + \advance\!!counta \minusone + \!!countb\!!counta + \multiply\!!countb 365 + \advance\!!countb \ifcase#2\relax + 0 \or 0 \or 31 \or 59 \or 90 \or120 \or151 \or + 181 \or212 \or243 \or273 \or304 \or334 \or365 \fi + \advance\!!countb #1\relax + \ifnum#2>2 + \doifleapyearelse{#3}{\advance\!!countb 1}{}\relax + \fi + \!!countc\!!counta + \dosetdivision\!!countc4\!!countc + \advance\!!countb \!!countc + \!!countc\!!counta + \dosetdivision\!!countc{100}\!!countc + \advance\!!countb -\!!countc + \!!countc\!!counta + \dosetdivision\!!countc{400}\!!countc + \advance\!!countb \!!countc + \dosetmodulo\!!countb7\!!countb + \advance\!!countb \plusone + \@EA\egroup\@EA\normalweekday\the\!!countb\relax} + +\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 + \!!counta#1% + \dosetmodulo\!!counta4\!!countb + \ifcase\!!countb + \dosetmodulo\!!counta{100}\!!countb + \ifcase\!!countb \else \!!doneatrue \fi + \dosetmodulo\!!counta{400}\!!countb + \ifcase\!!countb \!!doneatrue \fi + \fi + \if!!donea + \egroup\@EA\firstoftwoarguments % \def\next{#2}% + \else + \egroup\@EA\secondoftwoarguments % \def\next{#3}% + \fi} % \next} + +% untested but cleaner: +% +% \def\doifleapyearelse#1% #2#3% +% {\bgroup +% \dosetmodulo{#1}{400}\scratchcounter +% \ifcase\scratchcounter +% \else +% \dosetmodulo{#1}{100}\scratchcounter +% \ifcase\scratchcounter +% \scratchcounter\plusone +% \else +% \dosetmodulo{#1}4\scratchcounter +% \fi +% \fi +% \ifcase\scratchcounter +% \egroup\@EA\firstoftwoarguments +% \else +% \egroup\@EA\secondoftwoarguments +% \fi} + +\def\getdayspermonth#1#2% + {\doifleapyearelse{#1} + {\def\numberofdays{29}} + {\def\numberofdays{28}}% + \edef\numberofdays + {\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 +%D +%D For Adam and friends \unknown +%D +%D \startitemize[persiannummerals] +%D \item test \item test \item test \item test +%D \stopitemize + +\def\defineconversionvector#1#2% name base + {\bgroup + % dirty trick + \uccode`\*=`\1 + % plain: + % \uccode`\0=\numexpr#2+0\relax \uccode`\1=\numexpr#2+1\relax + % \uccode`\2=\numexpr#2+2\relax \uccode`\3=\numexpr#2+3\relax + % \uccode`\4=\numexpr#2+4\relax \uccode`\5=\numexpr#2+5\relax + % \uccode`\6=\numexpr#2+6\relax \uccode`\7=\numexpr#2+7\relax + % \uccode`\8=\numexpr#2+8\relax \uccode`\9=\numexpr#2+9\relax + % context: + \dostepwiserecurse091{\expandafter\uccode\expandafter`\recurselevel=\numexpr#2+\recurselevel}% + % prepared macro + \uppercase\expandafter{\expandafter\gdef\csname::cvn::#1::\endcsname##*% + {\ifcase##* 0\or1\or2\or3\or4\or5\or6\or7\or8\or9\fi}}% + \egroup} + +\def\conversionnumber#1#2% + {\ifcsname::cvn::#1::\endcsname + \expandafter\doconversionnumber\csname::cvn::#1::\expandafter\endcsname\number#2\relax + \else + \number#2% + \fi} + +\def\doconversionnumber#1#2% + {\ifx#2\relax + \expandafter\gobbleoneargument + \else + #1{#2}% + \expandafter\doconversionnumber + \fi#1} + +% actually mkiii code + +\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 new file mode 100644 index 000000000..2d2e5d5d7 --- /dev/null +++ b/tex/context/base/core-con.mkiv @@ -0,0 +1,860 @@ +%D \module +%D [ file=core-con, +%D version=1997.26.08, +%D title=\CONTEXT\ Core Macros, +%D subtitle=Conversion, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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} + +\registerctxluafile{core-con}{1.001} + +\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} + +\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 + \else + \@EA\firstoftwoarguments + \fi} + +\def\getdayspermonth#1#2% + {\edef\numberofdays{\ctxlua{converters.nofdays(\number#1,\number#2)}}} + +\def\dayspermonth#1#2% + {\ctxlua{converters.nofdays(\number#1,\number#2)}} + +% problem is that we calculate with those numbers +% +% \def\time {\numexpr\ctxlua{converters.textime()}\relax} +% \def\year {\numexpr\ctxlua{converters.year ()}\relax} +% \def\month{\numexpr\ctxlua{converters.month ()}\relax} +% \def\day {\numexpr\ctxlua{converters.day ()}\relax} + +% \dayoftheweek{2006}{9}{15} +% \doifleapyearelse{2000}{OK}{NOT OK} +% \doifleapyearelse{2100}{NOT OK}{OK} +% \doifleapyearelse{2004}{OK}{NOT OK} +% \doifleapyearelse{2003}{NOT OK}{OK} +% \dayspermonth{2000}{2} +% [\the\normaltime=\the\time] + +%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}}} +% +% \unexpanded\def\defineconversion% +% {\dodoubleargument\dodefineconversion} + +\unexpanded\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}} + +%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 +\ifx\notsmallcapped\undefined \let\notsmallcapped\firstofoneargument \fi + +\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 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 + [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-ctx.lua b/tex/context/base/core-ctx.lua new file mode 100644 index 000000000..1dad7c2d7 --- /dev/null +++ b/tex/context/base/core-ctx.lua @@ -0,0 +1,93 @@ +if not modules then modules = { } end modules ['core-ctx'] = { + version = 1.001, + comment = "companion to core-ctx.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +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 + +function commands.loadctxpreplist() + local ctlname = file.replacesuffix(tex.jobname,"ctl") + if lfs.isfile(ctlname) then + local x = xml.load(ctlname) + if x then + islocal = xml.found(x,"ctx:preplist[@local=='yes']") +--~ if trace_prepfiles then + if islocal then + commands.writestatus("systems","loading ctx log file (local)") -- todo: m!systems + else + commands.writestatus("systems","loading ctx log file (specified)") -- todo: m!systems + end +--~ end + for e in xml.collected(x,"ctx:prepfile") do + local name = xml.text(e) + if islocal then + name = file.basename(name) + end + local done = e.at['done'] or 'no' + if trace_prepfiles then + commands.writestatus("systems","registering %s -> %s",done) + end + found = true + list[name] = done -- 'yes' or 'no' + end + end + end +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 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 + prepname = found(filename) + if prepname then + return prepname + end + return false +end + +--~ support.doiffileexistelse(name) + +local processfile = commands.processfile +local doifinputfileelse = commands.doifinputfileelse + +function commands.processfile(name,maxreadlevel) -- overloaded + local prepname = resolve(name) + if prepname then + return processfile(prepname,0) + end + return processfile(name,maxreadlevel) +end + +function commands.doifinputfileelse(name,depth) + local prepname = resolve(name) + if prepname then + return doifinputfileelse(prepname,0) + end + return doifinputfileelse(name,depth) +end + +function commands.preparedfile(name) + return resolve(name) or name +end diff --git a/tex/context/base/core-ctx.mkii b/tex/context/base/core-ctx.mkii new file mode 100644 index 000000000..93cf8b4be --- /dev/null +++ b/tex/context/base/core-ctx.mkii @@ -0,0 +1,203 @@ +%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 / Job Control} + +\unprotect + +\chardef\preprocessmethod 2 % 0=no check 1=present_check 2=log_check +\chardef\preprocessstate 0 % 1=found 2=not_present (skip) +\chardef\preprocesslocal 0 % 0=no 1=yes +\def \preprocesssuffix {.prep} + +\def\loadctxpreplist + {\begingroup + \chardef\XMLtokensreduction\plusone + \ifcase\preprocessmethod + % no checking + \or + % simple checking + \or + \doiffileexistselse{./\jobname.ctl} + {\bgroup + \defineXMLenvironment[ctx:preplist][local=no] + {\doifelse{\XMLop{local}}{yes} + {\global\chardef\preprocesslocal\plusone + \writestatus\m!systems{loading ctx log file (local)}}% + {\writestatus\m!systems{loading ctx log file (specified)}}} + \donothing + \defineXMLenvironmentsave[ctx:prepfile][done=no] + \donothing + {\edef\readfilename{\XMLflush{ctx:prepfile}}% + \ifcase\preprocesslocal\else + \splitfilename\readfilename + \let\readfilename\splitoffbase + \fi + \writestatus\m!systems{registering \readfilename\space -> \XMLop{done}}% + \setxvalue{fp..\readfilename}{\XMLop{done}}}% + \processXMLfile{./\jobname.ctl}% + \egroup}% + {\global\chardef\preprocessmode\plusone}% + \fi + \global\let\loadctxpreplist\relax + \endgroup} + +\appendtoks\loadctxpreplist\to\everystarttext % will become: \prependtoks\loadctxpreplist\to\everyjob + +\def\docheckprepfile + {\ifcase\preprocessmethod + \iftracefiles\writestatus\m!systems{preprocessing - not needed}\fi + % no preprocessing + \or + % only check for existence + \iftracefiles\writestatus\m!systems{preprocessing - check existence of \readfilename\preprocesssuffix}\fi + \doiffileexistselse{\readfilename\preprocesssuffix} + {\chardef\preprocessstate\plusone} + \donothing + \or + % check when in list, otherwise assume normal file + \bgroup + \splitfilename\readfilename + \ifx\splitofftype\empty + % saveguard and speed up + \iftracefiles\writestatus\m!systems{preprocessing - no suffix}\fi + \egroup + \else\ifcase\preprocesslocal + % also ./ strippen + \iftracefiles\writestatus\m!systems{preprocessing - check presence of \readfilename\preprocesssuffix}\fi + \doifdefinedelse{fp..\readfilename} + {\egroup + \doiffileexistselse{\readfilename\preprocesssuffix} + {\chardef\preprocessstate\plusone} + {\chardef\preprocessstate\plustwo}}% + {\doifdefinedelse{fp.../\readfilename} + {\egroup + \edef\readfilename{./\readfilename}% + \doiffileexistselse{\readfilename\preprocesssuffix} + {\chardef\preprocessstate\plusone} + {\chardef\preprocessstate\plustwo}}% + {\doifdefinedelse{fp..\splitoffbase}% + {\egroup + \doiffileexistselse{\readfilename\preprocesssuffix} + {\chardef\preprocessstate\plusone} + {\chardef\preprocessstate\plustwo}}% + {\egroup}}}% + \else + % maybe just filecheck, why ctl + \iftracefiles\writestatus\m!systems{preprocessing - check local presence of \readfilename\preprocesssuffix}\fi + \doifdefinedelse{fp..\readfilename} + {\egroup + \doiffileexistselse{\readfilename\preprocesssuffix} + {\chardef\preprocessstate\plusone} + {\chardef\preprocessstate\plustwo}}% + {\egroup}% + \fi + \fi\fi} + +% beware, \readfilename keeps the original one, but we load and store the +% suffixed with .prep file (if present) + +\def\doreadfile#1#2#3#4% beware, this one already works at format generation time! + {\sanitizefilename#2\to\readfilename + \ifx\readfilename\empty + % silently ignore + \else + \let\trackedfilename\readfilename + \chardef\preprocessstate\zerocount + \ifconditional\trackfilenames + \doifundefinedelse{fn..\trackedfilename}\donetrue\donefalse + \else + \donetrue + \fi + \ifdone + \checkfilename\readfilename + \ifcase\kindoffile + % not a full path or url, check for existence + \doifelsenothing{#1} + {\iftracefiles\writestatus\m!systems{searching for \readfilename\space on tex path}\fi + \def\next{\redoreadfile\readfilename{#3}{#4}}}% + {\iftracefiles\writestatus\m!systems{searching for \readfilename\space on #1}\fi + \def\next{\redoreadfile{\pathplusfile{#1}{\readfilename}}{#3}{#4}}}% + \else + % a full path or url, no further checking done + \docheckprepfile + \ifcase\preprocessstate + \doiffileexistselse\readfilename + {\iftracefiles\writestatus\m!systems{located \readfilename}\fi + \def\next{#3\dodoreadfile}}% + {\iftracefiles\writestatus\m!systems{not found \readfilename}\fi + \def\next{#4}}% + \or + \iftracefiles\writestatus\m!systems{located \readfilename\preprocesssuffix}\fi + \def\next{#3\dodoreadfile}% + \or + \iftracefiles\writestatus\m!systems{not found \readfilename\preprocesssuffix}\fi + \def\next{#4}% + \fi + \fi + \else + \edef\readfilename{\getvalue{fn..\readfilename}}% ??? is done ! + \iftracefiles\writestatus\m!systems{already located \readfilename}\fi + \def\next{#3\dodoreadfile}% + \fi + \expandafter\next + \fi} + +\def\redoreadfile#1#2#3% + {\docheckprepfile + \ifcase\preprocessstate + \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}% + \or + \ifcase\preprocesslocal + \edef\readfilename{#1}% nor found + \else + % no path prepending + \fi + \iftracefiles\writestatus\m!systems{#1\preprocesssuffix\space located}\fi + \def\next{#2\dodoreadfile}% + \or + \def\next{#3}% + \fi + \next} + +\def\dodoreadfile % we provide hooks, for instance for \enableXML + {\ifconditional\trackfilenames + \setxvalue{fn..\trackedfilename}{\readfilename\ifcase\preprocessstate\or\preprocesssuffix\fi}% + \fi + \the\everybeforereadfile + \ifcase\preprocessstate + % no checking or not found when using method 1 + \def\dodoreadfileindeed{\inputgivenfile\readfilename}% + \or + % found when using method 1 or 2 + \def\dodoreadfileindeed{\inputgivenfile{\readfilename\preprocesssuffix}}% + \or + % not found when using method 2 + \let\dodoreadfileindeed\relax + \fi + \dodoreadfileindeed + \relax + \the\everyafterreadfile} + +\protect \endinput diff --git a/tex/context/base/core-ctx.mkiv b/tex/context/base/core-ctx.mkiv new file mode 100644 index 000000000..9bf456952 --- /dev/null +++ b/tex/context/base/core-ctx.mkiv @@ -0,0 +1,28 @@ +%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 / Job Control} + +\unprotect + +\chardef\preprocessmethod \plustwo % always check in mkiv + +\registerctxluafile{core-ctx}{1.000} + +\def\loadctxpreplist{\ctxlua{commands.loadctxpreplist()}\global\let\loadctxpreplist\relax} + +% \prependtoks\loadctxpreplist\to\everyjob + +\appendtoks\loadctxpreplist\to\everystarttext + +\protect \endinput diff --git a/tex/context/base/core-def.mkii b/tex/context/base/core-def.mkii new file mode 100644 index 000000000..840f853a7 --- /dev/null +++ b/tex/context/base/core-def.mkii @@ -0,0 +1,105 @@ +%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 + +% temporary here: + +% \in \at \about \from \over + +\unexpanded\def\arg{\mathortext\normalmatharg\normaltextarg} + +% brrr +% normally one does not want this to happen nested, maybe there +% is more; non public vars btw, will become conditionals + +\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 + +\def\synctexwarning + {\ifdefined\synctex \ifnum\synctex=\zerocount \else + \writeline + \writestatus\m!systems{BEWARE: syntex functionality is enabled!}% + \writeline + \globallet\synctexwarning\relax + \fi \fi} + +\prependtoks \synctexwarning \to \everyjob +\prependtoks \synctexwarning \to \everystarttext +\appendtoks \synctexwarning \to \everystoptext + +% last minute hacks + +\protect \endinput diff --git a/tex/context/base/core-def.mkiv b/tex/context/base/core-def.mkiv new file mode 100644 index 000000000..59451a914 --- /dev/null +++ b/tex/context/base/core-def.mkiv @@ -0,0 +1,94 @@ +%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 \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 \initializeMPgraphics \to \everyjob % after loading system files +\appendtoks \initializemainlanguage \to \everyjob +%appendtoks \MPLIBregister \to \everyjob +\appendtoks \xmlinitialize \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]\jobfilename \to \everybye + +%appendtoks \MPLIBallocate{1000} \to \everydump + +\prependtoks \resetallattributes \to \everybeforeoutput + +\appendtoks \the\everybackendshipout \to \everyshipout +\prependtoks \the\everylastbackendshipout \to \everylastshipout + +\prependtoks \lefttoright \to \everybeforeoutput + +% temporary here: + +\ifdefined\in \let\normalmathin \in \unexpanded\def\in {\mathortext\normalmathin \dospecialin } \else \let\in \dospecialin \fi +\ifdefined\at \let\normalmathat \at \unexpanded\def\at {\mathortext\normalmathat \dospecialat } \else \let\at \dospecialat \fi +\ifdefined\about \let\normalmathabout\about \unexpanded\def\about{\mathortext\normalmathabout\dospecialabout} \else \let\about\dospecialabout \fi +\ifdefined\from \let\normalmathfrom \from \unexpanded\def\from {\mathortext\normalmathfrom \dospecialfrom } \else \let\from \dospecialfrom \fi +\ifdefined\over \let\normalmathover \over \unexpanded\def\over {\mathortext\normalmathover \dospecialabout} \else \let\over \dospecialabout \fi + +\unexpanded\def\arg{\mathortext\normalmatharg\normaltextarg} + +% brrr + +\appendtoks + \synchronizegloballinespecs + \synchronizelocallinespecs +\to \everysetupbodyfont + +\appendtoks + \synchronizelocallinespecs +\to \everyswitchtobodyfont + +\def\synctexwarning + {\ifdefined\synctex \ifnum\synctex=\zerocount \else + \writeline + \writestatus\m!systems{BEWARE: synctex functionality is enabled!}% + \writeline + \globallet\synctexwarning\relax + \fi \fi} + +\prependtoks \synctexwarning \to \everyjob +\prependtoks \synctexwarning \to \everystarttext +\appendtoks \synctexwarning \to \everystoptext + +\protect \endinput 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..d927ff3ad --- /dev/null +++ b/tex/context/base/core-env.mkiv @@ -0,0 +1,388 @@ +%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 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 + +\unexpanded\def\doifmodeelse{\unprotect\dodoifmodeelse} +\unexpanded\def\doifmode {\unprotect\dodoifmode} +\unexpanded\def\doifnotmode {\unprotect\dodoifnotmode} +\unexpanded\def\startmode {\unprotect\dostartmode} +\unexpanded\def\startnotmode{\unprotect\dostartnotmode} + +\def\dodoifmodeelse + {\docheckformode\firstoftwoarguments\secondoftwoarguments} + +\def\dodoifmode + {\docheckformode\firstofoneargument\gobbleoneargument} + +\def\dodoifnotmode + {\docheckformode\gobbleoneargument\firstofoneargument} + +\long\unexpanded\def\dostartmode[#1]% + {\docheckformode\donothing\dostopmode{#1}} + +\long\def\dostartnotmode[#1]% + {\docheckformode\dostopnotmode\donothing{#1}} + +\unexpanded\def\stopmode {} % no relax +\unexpanded\def\stopnotmode{} % no relax + +\long\def\dostopmode #1\stopmode {} +\long\def\dostopnotmode#1\stopnotmode{} + +\unexpanded\def\doifallmodeselse{\unprotect\dodoifallmodeselse} +\unexpanded\def\doifallmodes {\unprotect\dodoifallmodes} +\unexpanded\def\doifnotallmodes {\unprotect\dodoifnotallmodes} +\unexpanded\def\startallmodes {\unprotect\dostartallmodes} +\unexpanded\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}} + +\unexpanded\def\stopallmodes {} % no relax +\unexpanded\def\stopnotallmodes{} % no relax + +\long\def\dostopallmodes #1\stopallmodes {} +\long\def\dostopnotallmodes#1\stopnotallmodes{} + +%D Lets now set a mode: + +\enablemode[mkiv] \setsystemmode{mkiv} + +%D Setups: + +\unexpanded\def\startsetups{} % to please dep checker +\unexpanded\def\stopsetups {} % to please dep checker + +\expanded + {\long\def\@EA\noexpand\csname\e!start\v!setups\endcsname + {\begingroup\noexpand\doifnextoptionalelse + {\noexpand\dostartsetupsA\@EA\noexpand\csname\e!stop\v!setups\endcsname} + {\noexpand\dostartsetupsB\@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 + +% the next one is meant for \c!setups situations, hence the check for +% a shortcut + +\def\doprocesslocalsetups#1% + {\edef\tobeprocessedsetups{#1}% + \ifx\tobeprocessedsetups\empty\else + \dodoprocesslocalsetups + \fi} + +\def\dodoprocesslocalsetups + {\@EA\processcommalist\@EA[\tobeprocessedsetups]\dosetups} + +\edef\setupwithargument#1% saves a few expansions + {\noexpand\csname\??su:\noexpand\ifcsname\??su:#1\endcsname#1\noexpand\else\letterpercent\noexpand\fi\endcsname} + +\let\directsetup\dosetups + +\def\doifsetupselse#1% to be done: grid + {\doifdefinedelse{\??su:#1}} + +\chardef\setupseolmode\plusone + +\unexpanded\def\startsetups {\xxstartsetups\plusone \stopsetups } \let\stopsetups \relax +\unexpanded\def\startlocalsetups{\xxstartsetups\plusone \stoplocalsetups} \let\stoplocalsetups\relax +\unexpanded\def\startrawsetups {\xxstartsetups\zerocount\stoprawsetups } \let\stoprawsetups \relax +\unexpanded\def\startxmlsetups {\xxstartsetups\plustwo \stopxmlsetups } \let\stopxmlsetups \relax + +\def\xxstartsetups#1#2% + {\begingroup\let\setupseolmode#1\doifnextoptionalelse{\dostartsetupsA#2}{\dostartsetupsB#2}} + +\def\dostartsetupsA#1% [ ] delimited + {\ifcase\setupseolmode\or\catcode`\^^M\@@ignore\or\catcode`\^^M\@@ignore\catcode`\|\@@other\fi + \dotripleempty\dostartsetups[#1]} + +\def\dostartsetupsB#1#2 % space delimited + {\ifcase\setupseolmode\or\catcode`\^^M\@@ignore\or\catcode`\^^M\@@ignore\catcode`\|\@@other\fi + \dodostartsetups#1\empty{#2}} + +\def\dostartsetupsC[#1][#2][#3]{\dodostartsetups#1{#2}{#3}} % [..] [..] +\def\dostartsetupsD[#1][#2][#3]{\dodostartsetups#1\empty{#2}} % [..] + +\def\dostartsetups + {\ifthirdargument\@EA\dostartsetupsC\else\@EA\dostartsetupsD\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 \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} + +% \unexpanded\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} + +\unexpanded\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-fil.mkii b/tex/context/base/core-fil.mkii new file mode 100644 index 000000000..fca253a7b --- /dev/null +++ b/tex/context/base/core-fil.mkii @@ -0,0 +1,347 @@ +%D \module +%D [ file=core-fil, +%D version=1997.11.15, +%D title=\CONTEXT\ Core Macros, +%D subtitle=File 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 / File Support} + +\unprotect + +%D Files registered as temporary files will be deleted after a +%D run by texexec: + +% \starttext +% \immediate\openout\scratchwrite=oeps.tmp +% \immediate\write\scratchwrite{oeps} +% \immediate\closeout\scratchwrite +% \registertempfile{oeps.tmp} +% \typefile{oeps.tmp} +% \stoptext + +\let\usedtempfile\gobbleoneargument + +\def\registertempfile#1{\immediatewriteutility{f t {#1}}} + +%D \macros +%D {definefilesynonym} +%D +%D One of the problems with loading files is that their names +%D can depend on the interface language. We therefore need a +%D method to define filesynonyms. The actual synonyms are +%D defined elsewhere, but look like: +%D +%D \starttyping +%D \definefilesynonym [chemic] [chemie] +%D \definefilesynonym [einheit] [unit] +%D \definefilesynonym [unit] [unit] +%D \stoptyping +%D +%D So we can say in english: +%D +%D \starttyping +%D \usemodules[pictex,chemic,unit] +%D \stoptyping +%D +%D and in dutch: +%D +%D \starttyping +%D \usemodules[pictex,chemie,unit] +%D \stoptyping + +% will be redone in mkiv + +\def\definefilesynonym + {\dodoubleempty\dodefinefilesynonym} + +\def\dodefinefilesynonym[#1][#2]% + {\ifundefined{\??fs#1}\else + \doifnotvalue{\??fs#1}{#2}{\showmessage\m!files1{#1 (#2),\getvalue{\??fs#1}}}% + \fi + \doifelse{#1}{#2}{\letbeundefined{\??fs#1}{#2}}{\setevalue{\??fs#1}{#2}}} + +%D \macros +%D {definefilefallback} + +\def\definefilefallback + {\dodoubleargument\dodefinefilefallback} + +\def\dodefinefilefallback[#1][#2]% + {\doifnotfile{#1} + {\def\docommand##1{\doiffile{##1}{\definefilesynonym[#1][##1]\quitcommalist}}% + \processcommalist[#2]\docommand}} + +%D \macros +%D {truefilename} +%D +%D At the system level such a filename can be called upon by +%D saying: +%D +%D \starttyping +%D \truefilename{filename/filesynonym} +%D \stoptyping +%D +%D The implementation shows that nesting is supported. + +\def\truefilename#1% + {\ifundefined{\??fs#1}#1\else\truefilename{\csname\??fs#1\endcsname}\fi} + +%D \macros +%D {makeshortfilename} +%D +%D To prevent cross platform problems with filenames, we +%D lowercase them as well as only use the first 8~characters. +%D +%D \starttyping +%D \def\domakeshortfilename[#1#2#3#4#5#6#7#8#9]% +%D {\lowercase{\edef\shortfilename{#1#2#3#4#5#6#7#8.}}% +%D \expandafter\beforesplitstring\shortfilename\at.\to\shortfilename} +%D +%D \def\makeshortfilename[#1]% +%D {\edef\fullfilename{#1.........}% +%D \expanded{\domakeshortfilename[\fullfilename]}} +%D \stoptyping +%D +%D In 2005 there is no need for the 8~character limit any more, so: + +\def\makeshortfilename[#1]% no need for further cleanup and shortening + {\lowercase{\edef\shortfilename{#1.}}% + \expandafter\beforesplitstring\shortfilename\at.\to\shortfilename} + +%D \macros +%D {usemodule} +%D +%D Most of \CONTEXT is preloaded in the format file. Some very +%D domain specific typesetting topics are however dealt with in +%D separate modules, e.g. typesetting of chemical structure +%D formulas. These modules are loaded by: +%D +%D \showsetup{usemodule} +%D +%D More information on the specific modules can be found in +%D their dedicated manuals. We use \type {\next} so that we +%D can \type {\end} in modules. + +\newconditional\moduleisloaded + +\def\dododousemodules#1#2% no \unprotect/\protect when loading, + {\relax % since we need to use ? ! unprotected + \ifconditional\moduleisloaded % sometimes (see xtag-map) + \let\next\relax % or: \expandafter\gobbleoneargument + \else + \makeshortfilename[#1\truefilename{#2}]% beware: *- is not part of syn + \doifelseflagged\shortfilename + {\showmessage\m!systems7{#2 (line \number\inputlineno)}% + \settrue\moduleisloaded + \let\next\relax} + {\doglobal\setflag\shortfilename + \def\next + {\startreadingfile + \readsysfile\shortfilename + {\showmessage\m!systems5{#2}\settrue\moduleisloaded} + {\readsysfile{\shortfilename.\mksuffix} % new + {\showmessage\m!systems5{#2 (\mksuffix)}\settrue\moduleisloaded} + \donothing}% + \stopreadingfile}}% + \fi + \next} + +\def\dodousemodules#1#2% + {\setfalse\moduleisloaded + \doifelsenothing{#1} + {\dododousemodules\f!moduleprefix {#2}% + \dododousemodules\f!privateprefix{#2}% + \dododousemodules\f!styleprefix {#2}% + \dododousemodules\f!xstyleprefix {#2}% + \dododousemodules\f!thirdprefix {#2}% + \dododousemodules\empty {#2}}% new, fall back on raw name + {\dododousemodules{#1-}{#2}}% + \ifconditional\moduleisloaded\else + \showmessage\m!systems6{#2}% + \appendtoks\showmessage\m!systems6{#2}\to\everynotabene + \fi} + +% \def\usemodules +% {\dodoubleempty\dousemodules} +% +% \def\dousemodules[#1][#2]% +% {\ifsecondargument +% \doifelsenothing{#2} +% {\let\next\relax} +% {\def\next{\processcommalist[#2]{\dodousemodules{#1}}}}% +% \else +% \def\next{\usemodules[][#1]}% +% \fi +% \next} +% +% \let\usemodule\usemodules + +\def\usemodules + {\dotripleempty\dousemodules} + +\def\dousemodules[#1][#2][#3]% + {\pushmacro\currentmodule + \pushmacro\currentmoduleparameters + \let\currentmoduleparameters\empty + \ifthirdargument + \doifelsenothing{#2} + {\let\next\relax} + {\def\currentmoduleparameters{#3}% + \def\next{\processcommalist[#2]{\dodousemodules{#1}}}}% + \else\ifsecondargument + \doifelsenothing{#2} + {\let\next\relax} + {\doifassignmentelse{#2} + {\def\currentmoduleparameters{#2}% + \def\next{\processcommalist[#1]{\dodousemodules{}}}} + {\def\next{\processcommalist[#2]{\dodousemodules{#1}}}}}% + \else + \def\next{\processcommalist[#1]{\dodousemodules{}}}% + \fi\fi + \next + \popmacro\currentmoduleparameters + \popmacro\currentmodule} + +\let\currentmoduleparameters\empty +\let\currentmodule \s!unknown + +\def\startmodule + {\doifnextoptionalelse\dostartmodule\nostartmodule} + +\def\nostartmodule #1 % + {\dostartmodule[#1]} + +\def\dostartmodule[#1]% + {\pushmacro\currentmodule + \pushmacro\currentmoduleparameters + \def\currentmodule{#1}} + +\def\stopmodule + {\popmacro\currentmoduleparameters + \popmacro\currentmodule} + +\def\setupmodule + {\dodoubleempty\dosetupmodule} + +\def\dosetupmodule[#1][#2]% + {\scratchtoks\expandafter{\currentmoduleparameters}% + \ifsecondargument + \getparameters[\??md:#1:][#2]% + \expanded{\getparameters[\??md:#1:][\the\scratchtoks]}% + \else + \getparameters[\??md:\currentmodule:][#1]% + \expanded{\getparameters[\??md:\currentmodule:][\the\scratchtoks]}% + \fi + \let\currentmoduleparameters\empty} + +\def\moduleparameter #1#2{\executeifdefined{\??md:#1:#2}\s!empty} +\def\currentmoduleparameter#1{\executeifdefined{\??md:\currentmodule:#1}\s!empty} + +% \usemodule[newmml] +% \usemodule[newmml][a=b] +% \usemodule[x][newmml] +% \usemodule[x][newmml][a=b] +% +% \startmodule [mathml] +% \setupmodule[a=c] \relax [\currentmoduleparameter{a}] % user vars will be set afterwards +% \setupmodule[a=c] \relax [\currentmoduleparameter{a}] % user vars are now forgotten +% \stopmodule + +% one can introduce test sections with: +% +% \enablemode[newmml:test:\currentmoduleparameter{test}] +% \startmode[newmml:test:yes} ... \stopmode +% +% these will be ignored unless test=yes +% +% however, a better way is: + +\let\stopmoduletestsection\donothing + +\def\startmoduletestsection + {\bgroup + \setupmodule % we need to make sure that the vars are set + \doifelse{\currentmoduleparameter\v!test}\v!yes + {\egroup + \writestatus{\currentmodule}{loading experimental code}} + {\egroup + \writestatus{\currentmodule}{skipping experimental code}% + \gobbleuntil\stopmoduletestsection}} + +%D We also support a singular call, which saves us for +%D frustrations when we do a typo. + +\let\usemodule=\usemodules + +% %D The definition shows that the language specific settings +% %D are activated after loading all the modules specified. + +%D \macros +%D {ifprotectbuffers, bufferprefix, +%D TEXbufferfile, MPgraphicfile} +%D +%D The next switch enables protection of temporary filenames, +%D which is needed when we process more files on one path at +%D the same time. + +\newif\ifprotectbuffers + +\def\bufferprefix{\ifprotectbuffers\jobname-\fi} + +% The following filenames are defined here: + +\def\TEXbufferfile #1{\bufferprefix#1.\f!temporaryextension} +\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 +%D in a lazy way. Nota bene: such runtime definitions are +%D global. +%D +%D \starttyping +%D \fetchruntimecommand\showaccents{\f!encodingprefix ...} +%D \stoptyping + +\def\fetchruntimecommand#1#2% + {\def#1{\dofetchruntimecommand#1{#2}}} + +\def\dofetchruntimecommand#1#2% + {\doifnotflagged{#2} + {\let#1\undefined + \startreadingfile + \startnointerference % \bgroup + \cleanupfeatures % better \setnormalcatcodes / test first + \readfile{#2}\donothing\donothing + \stopnointerference % \egroup + \stopreadingfile + \doglobal\setflag{#2}}% + \ifx#1\undefined + \writestatus\m!systems{command \string#1 not found in file #2}% + \def#1{{\infofont[unknown command \string#1]}}% + \fi + #1} + +%D Experimental: + +\let\checkpreprocessor\relax + +%D To be documented and probably moved + +\def\documentresources{\@@erurl} + +\def\setupexternalresources + {\dodoubleargument\getparameters[\??er]} + +\setupexternalresources + [url=] + +%D This module will be perfected / changed / weeded. + +\protect \endinput diff --git a/tex/context/base/core-fil.mkiv b/tex/context/base/core-fil.mkiv new file mode 100644 index 000000000..daef176d2 --- /dev/null +++ b/tex/context/base/core-fil.mkiv @@ -0,0 +1,284 @@ +%D \module +%D [ file=core-fil, +%D version=1997.11.15, +%D title=\CONTEXT\ Core Macros, +%D subtitle=File 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 / File Support} + +\unprotect + +%D \macros +%D {definefilesynonym} +%D +%D One of the problems with loading files is that their names +%D can depend on the interface language. We therefore need a +%D method to define filesynonyms. The actual synonyms are +%D defined elsewhere, but look like: +%D +%D \starttyping +%D \definefilesynonym [chemic] [chemie] +%D \definefilesynonym [einheit] [unit] +%D \definefilesynonym [unit] [unit] +%D \stoptyping +%D +%D So we can say in english: +%D +%D \starttyping +%D \usemodules[pictex,chemic,unit] +%D \stoptyping +%D +%D and in dutch: +%D +%D \starttyping +%D \usemodules[pictex,chemie,unit] +%D \stoptyping + +% will be redone in mkiv + +\unexpanded\def\definefilesynonym + {\dodoubleempty\dodefinefilesynonym} + +\def\dodefinefilesynonym[#1][#2]% + {\ifcsname\??fs#1\endcsname + \doifnotvalue{\??fs#1}{#2}{\showmessage\m!files1{#1 (#2),\getvalue{\??fs#1}}}% + \fi + \doifelse{#1}{#2}{\letbeundefined{\??fs#1}{#2}}{\setevalue{\??fs#1}{#2}}} + +%D \macros +%D {definefilefallback} + +\unexpanded\def\definefilefallback + {\dodoubleargument\dodefinefilefallback} + +\def\dodefinefilefallback[#1][#2]% + {\doifnotfile{#1} + {\def\docommand##1{\doiffile{##1}{\definefilesynonym[#1][##1]\quitcommalist}}% + \processcommalist[#2]\docommand}} + +%D \macros +%D {truefilename} +%D +%D At the system level such a filename can be called upon by +%D saying: +%D +%D \starttyping +%D \truefilename{filename/filesynonym} +%D \stoptyping +%D +%D The implementation shows that nesting is supported. + +\def\truefilename#1% + {\ifcsname\??fs#1\endcsname\expandafter\truefilename\csname\??fs#1\endcsname\else#1\fi} + +%D \macros +%D {makeshortfilename} +%D +%D To prevent cross platform problems with filenames, we +%D lowercase them as well as only use the first 8~characters. +%D +%D \starttyping +%D \def\domakeshortfilename[#1#2#3#4#5#6#7#8#9]% +%D {\lowercase{\edef\shortfilename{#1#2#3#4#5#6#7#8.}}% +%D \expandafter\beforesplitstring\shortfilename\at.\to\shortfilename} +%D +%D \def\makeshortfilename[#1]% +%D {\edef\fullfilename{#1.........}% +%D \expanded{\domakeshortfilename[\fullfilename]}} +%D \stoptyping +%D +%D In 2005 there is no need for the 8~character limit any more, so: + +\def\makeshortfilename[#1]% no need for further cleanup and shortening + {\lowercase{\edef\shortfilename{#1.}}% + \expandafter\beforesplitstring\shortfilename\at.\to\shortfilename} + +%D \macros +%D {usemodule} +%D +%D Most of \CONTEXT is preloaded in the format file. Some very +%D domain specific typesetting topics are however dealt with in +%D separate modules, e.g. typesetting of chemical structure +%D formulas. These modules are loaded by: +%D +%D \showsetup{usemodule} +%D +%D More information on the specific modules can be found in +%D their dedicated manuals. We use \type {\next} so that we +%D can \type {\end} in modules. + +\def\dodousemodules#1#2% + {\ctxlua{support.usemodules("#1","#2","\truefilename{#2}")}} + +\def\usemodules + {\dotripleempty\dousemodules} + +\def\dousemodules[#1][#2][#3]% + {\pushmacro\currentmodule + \pushmacro\currentmoduleparameters + \let\currentmoduleparameters\empty + \ifthirdargument + \doifelsenothing{#2} + {\let\next\relax} + {\def\currentmoduleparameters{#3}% + \def\next{\processcommalist[#2]{\dodousemodules{#1}}}}% + \else\ifsecondargument + \doifelsenothing{#2} + {\let\next\relax} + {\doifassignmentelse{#2} + {\def\currentmoduleparameters{#2}% + \def\next{\processcommalist[#1]{\dodousemodules{}}}} + {\def\next{\processcommalist[#2]{\dodousemodules{#1}}}}}% + \else + \def\next{\processcommalist[#1]{\dodousemodules{}}}% + \fi\fi + \next + \popmacro\currentmoduleparameters + \popmacro\currentmodule} + +\let\currentmoduleparameters\empty +\let\currentmodule \s!unknown + +\unexpanded\def\startmodule + {\doifnextoptionalelse\dostartmodule\nostartmodule} + +\def\nostartmodule #1 % + {\dostartmodule[#1]} + +\def\dostartmodule[#1]% + {\pushmacro\currentmodule + \pushmacro\currentmoduleparameters + \def\currentmodule{#1}} + +\unexpanded\def\stopmodule + {\popmacro\currentmoduleparameters + \popmacro\currentmodule} + +\unexpanded\def\setupmodule + {\dodoubleempty\dosetupmodule} + +\def\dosetupmodule[#1][#2]% + {\scratchtoks\expandafter{\currentmoduleparameters}% + \ifsecondargument + \getparameters[\??md:#1:][#2]% + \expanded{\getparameters[\??md:#1:][\the\scratchtoks]}% + \else + \getparameters[\??md:\currentmodule:][#1]% + \expanded{\getparameters[\??md:\currentmodule:][\the\scratchtoks]}% + \fi + \let\currentmoduleparameters\empty} + +\def\moduleparameter #1#2{\executeifdefined{\??md:#1:#2}\s!empty} +\def\currentmoduleparameter#1{\executeifdefined{\??md:\currentmodule:#1}\s!empty} + +\def\useluamodule [#1]{\ctxlua{dofile(resolvers.findctxfile("#1"))}} +\def\luaenvironment #1 {\ctxlua{dofile(resolvers.findctxfile("#1"))}} + +% \usemodule[newmml] +% \usemodule[newmml][a=b] +% \usemodule[x][newmml] +% \usemodule[x][newmml][a=b] +% +% \startmodule [mathml] +% \setupmodule[a=c] \relax [\currentmoduleparameter{a}] % user vars will be set afterwards +% \setupmodule[a=c] \relax [\currentmoduleparameter{a}] % user vars are now forgotten +% \stopmodule + +% one can introduce test sections with: +% +% \enablemode[newmml:test:\currentmoduleparameter{test}] +% \startmode[newmml:test:yes} ... \stopmode +% +% these will be ignored unless test=yes +% +% however, a better way is: + +\let\stopmoduletestsection\donothing + +\unexpanded\def\startmoduletestsection + {\bgroup + \setupmodule % we need to make sure that the vars are set + \doifelse{\currentmoduleparameter\v!test}\v!yes + {\egroup + \writestatus{\currentmodule}{loading experimental code}} + {\egroup + \writestatus{\currentmodule}{skipping experimental code}% + \gobbleuntil\stopmoduletestsection}} + +%D We also support a singular call, which saves us for +%D frustrations when we do a typo. + +\let\usemodule=\usemodules + +% %D The definition shows that the language specific settings +% %D are activated after loading all the modules specified. + +%D \macros +%D {ifprotectbuffers, bufferprefix, +%D TEXbufferfile, MPgraphicfile} +%D +%D The next switch enables protection of temporary filenames, +%D which is needed when we process more files on one path at +%D the same time. + +\newif\ifprotectbuffers + +\def\bufferprefix{\ifprotectbuffers\jobname-\fi} + +% The following filenames are defined here: + +\def\TEXbufferfile #1{\bufferprefix#1.\f!temporaryextension} +\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 +%D in a lazy way. Nota bene: such runtime definitions are +%D global. +%D +%D \starttyping +%D \fetchruntimecommand\showaccents{\f!encodingprefix ...} +%D \stoptyping + +\def\fetchruntimecommand#1#2% + {\def#1{\dofetchruntimecommand#1{#2}}} + +\def\dofetchruntimecommand#1#2% + {\doifnotflagged{#2} + {\let#1\undefined + \startreadingfile + \startnointerference % \bgroup + \cleanupfeatures % better \setnormalcatcodes / test first + \readfile{#2}\donothing\donothing + \stopnointerference % \egroup + \stopreadingfile + \doglobal\setflag{#2}}% + \ifx#1\undefined + \writestatus\m!systems{command \string#1 not found in file #2}% + \def#1{{\infofont[unknown command \string#1]}}% + \fi + #1} + +%D Experimental: + +\let\checkpreprocessor\relax + +%D To be documented and probably moved + +\def\documentresources{\@@erurl} + +\unexpanded\def\setupexternalresources + {\dodoubleargument\getparameters[\??er]} + +\setupexternalresources + [url=] + +%D This module will be perfected / changed / weeded. + +\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..a7c84a5a0 --- /dev/null +++ b/tex/context/base/core-fnt.mkiv @@ -0,0 +1,293 @@ +%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: + +%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 {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 + +\unexpanded\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}% + +\unexpanded\def\placeinitial + {\doifelse\@@dclocation\v!margin{\chardef\DropMode\plusone}{\chardef\DropMode\zerocount}% + \doif \@@dcstate\v!start{\ifcase\@@dcn\else\AutoDroppedCaps\fi}} + +\let\checkinitial\CheckDroppedCaps + +\protect \endinput diff --git a/tex/context/base/core-gen.mkii b/tex/context/base/core-gen.mkii new file mode 100644 index 000000000..b6ab2a208 --- /dev/null +++ b/tex/context/base/core-gen.mkii @@ -0,0 +1,166 @@ +%D \module +%D [ file=core-gen, +%D version=1995.10.10, +%D title=\CONTEXT\ Core 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. + +\writestatus{loading}{ConTeXt Core Macros / General} + +\unprotect + +%D \macros +%D {assigndimension,assignalfadimension} +%D +%D Hieronder worden enkele commando's gedefinieerd rond +%D toekenningen. Allereerst een commando om waarden aan +%D een \DIMENSION\ toe te kennen: +%D +%D \starttyping +%D \assigndimension +%D {|klein|middel|groot|-klein|-middel|-groot|geen} +%D {\dimension} +%D {waarde klein} +%D {waarde middel} +%D {waarde groot} +%D \stoptyping +%D +%D Hierbij krijgt de \DIMENSION\ \type{\dimension} een waarde +%D afhankelijk van het meegegeven trefwoord. +%D +%D \startnarrower +%D \startlines +%D \type{(-)klein }\qquad (--) waarde klein +%D \type{(-)middel}\qquad (--) waarde middel +%D \type{(-)groot }\qquad (--) waarde groot +%D \type{geen }\qquad 0pt +%D \type{waarde }\qquad waarde +%D \stoplines +%D \stopnarrower +%D +%D Een trefwoord mag worden voorafgegaan door een \type{-}. +%D Deze macro toont een voorbeeld van het gebruik van +%D \type{\processaction} en constanten. +%D +%D Analoog aan het bovenstaande commando kennen we een +%D commando om waarden toe te kennen aan een macro: +%D +%D \starttyping +%D \assignalfadimension +%D {|klein|middel|groot|geen} +%D {\macro} +%D {waarde klein} +%D {waarde middel} +%D {waarde groot} +%D \stoptyping + +% 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} +%D +%D Een variant hierop is het commando: +%D +%D \starttyping +%D \assignvalue +%D {|klein|middel|groot} +%D {\macro} +%D {waarde klein } +%D {waarde middel} +%D {waarde groot} +%D \stoptyping +%D +%D Hierbij krijgt \type{\macro} een waarde afhankelijk van +%D het meegegeven trefwoord: +%D +%D \startnarrower +%D \startlines +%D \type{klein }\qquad waarde klein +%D \type{middel}\qquad waarde middel +%D \type{groot }\qquad waarde groot +%D \type{waarde}\qquad waarde +%D \stoplines +%D \stopnarrower +%D +%D Hier doet \type{geen} dus niet mee. + +\def\@av@{@av@} + +\letvalue{\@av@\v!big }\thirdofthreearguments +\letvalue{\@av@\v!medium}\secondofthreearguments +\letvalue{\@av@\v!small }\firstofthreearguments + +\def\assignvalue#1#2#3#4#5% + {\edef#2{\ifcsname\@av@#1\endcsname + \csname\@av@#1\expandafter\endcsname + \else + #1\expandafter\gobblethreearguments + \fi{#3}{#4}{#5}}} + +%D \macros +%D {assignwidth} +%D +%D Een breedte van een opgegeven tekst kan worden berekend en +%D toegekend aan een \DIMENSION\ met: +%D +%D \starttyping +%D \assignwidth +%D {\dimension} +%D {|passend|ruim} +%D {tekst} +%D \stoptyping +%D +%D Dit commando sluit, evenals de bovenstaande +%D \type{\assign}||commando's, aan op de wijze waarop +%D in de andere \CONTEXT||modules toekenningen +%D plaatsvinden. Bij \type{ruim} wordt de gemeten breedte +%D met 1~em vermeerderd. + +\def\assignwidth#1#2#3#4% + {\doifelsenothing{#2} + {\setbox\scratchbox\hbox{#3}% + #1\wd\scratchbox} + {\doifinsetelse{#2}{\v!fit,\v!broad} + {\setbox\scratchbox\hbox{#3}% + #1\wd\scratchbox + \doif{#2}\v!broad{\advance#1 #4}}% + {#1=#2}}}% + +\protect \endinput diff --git a/tex/context/base/core-gen.mkiv b/tex/context/base/core-gen.mkiv new file mode 100644 index 000000000..b6ab2a208 --- /dev/null +++ b/tex/context/base/core-gen.mkiv @@ -0,0 +1,166 @@ +%D \module +%D [ file=core-gen, +%D version=1995.10.10, +%D title=\CONTEXT\ Core 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. + +\writestatus{loading}{ConTeXt Core Macros / General} + +\unprotect + +%D \macros +%D {assigndimension,assignalfadimension} +%D +%D Hieronder worden enkele commando's gedefinieerd rond +%D toekenningen. Allereerst een commando om waarden aan +%D een \DIMENSION\ toe te kennen: +%D +%D \starttyping +%D \assigndimension +%D {|klein|middel|groot|-klein|-middel|-groot|geen} +%D {\dimension} +%D {waarde klein} +%D {waarde middel} +%D {waarde groot} +%D \stoptyping +%D +%D Hierbij krijgt de \DIMENSION\ \type{\dimension} een waarde +%D afhankelijk van het meegegeven trefwoord. +%D +%D \startnarrower +%D \startlines +%D \type{(-)klein }\qquad (--) waarde klein +%D \type{(-)middel}\qquad (--) waarde middel +%D \type{(-)groot }\qquad (--) waarde groot +%D \type{geen }\qquad 0pt +%D \type{waarde }\qquad waarde +%D \stoplines +%D \stopnarrower +%D +%D Een trefwoord mag worden voorafgegaan door een \type{-}. +%D Deze macro toont een voorbeeld van het gebruik van +%D \type{\processaction} en constanten. +%D +%D Analoog aan het bovenstaande commando kennen we een +%D commando om waarden toe te kennen aan een macro: +%D +%D \starttyping +%D \assignalfadimension +%D {|klein|middel|groot|geen} +%D {\macro} +%D {waarde klein} +%D {waarde middel} +%D {waarde groot} +%D \stoptyping + +% 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} +%D +%D Een variant hierop is het commando: +%D +%D \starttyping +%D \assignvalue +%D {|klein|middel|groot} +%D {\macro} +%D {waarde klein } +%D {waarde middel} +%D {waarde groot} +%D \stoptyping +%D +%D Hierbij krijgt \type{\macro} een waarde afhankelijk van +%D het meegegeven trefwoord: +%D +%D \startnarrower +%D \startlines +%D \type{klein }\qquad waarde klein +%D \type{middel}\qquad waarde middel +%D \type{groot }\qquad waarde groot +%D \type{waarde}\qquad waarde +%D \stoplines +%D \stopnarrower +%D +%D Hier doet \type{geen} dus niet mee. + +\def\@av@{@av@} + +\letvalue{\@av@\v!big }\thirdofthreearguments +\letvalue{\@av@\v!medium}\secondofthreearguments +\letvalue{\@av@\v!small }\firstofthreearguments + +\def\assignvalue#1#2#3#4#5% + {\edef#2{\ifcsname\@av@#1\endcsname + \csname\@av@#1\expandafter\endcsname + \else + #1\expandafter\gobblethreearguments + \fi{#3}{#4}{#5}}} + +%D \macros +%D {assignwidth} +%D +%D Een breedte van een opgegeven tekst kan worden berekend en +%D toegekend aan een \DIMENSION\ met: +%D +%D \starttyping +%D \assignwidth +%D {\dimension} +%D {|passend|ruim} +%D {tekst} +%D \stoptyping +%D +%D Dit commando sluit, evenals de bovenstaande +%D \type{\assign}||commando's, aan op de wijze waarop +%D in de andere \CONTEXT||modules toekenningen +%D plaatsvinden. Bij \type{ruim} wordt de gemeten breedte +%D met 1~em vermeerderd. + +\def\assignwidth#1#2#3#4% + {\doifelsenothing{#2} + {\setbox\scratchbox\hbox{#3}% + #1\wd\scratchbox} + {\doifinsetelse{#2}{\v!fit,\v!broad} + {\setbox\scratchbox\hbox{#3}% + #1\wd\scratchbox + \doif{#2}\v!broad{\advance#1 #4}}% + {#1=#2}}}% + +\protect \endinput diff --git a/tex/context/base/core-ini.mkii b/tex/context/base/core-ini.mkii new file mode 100644 index 000000000..69edf9735 --- /dev/null +++ b/tex/context/base/core-ini.mkii @@ -0,0 +1,67 @@ +%D \module +%D [ file=core-ini, +%D version=2003.12.01, +%D title=\CONTEXT\ Core Macros, +%D subtitle=Additional 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 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. + +\unprotect + +\everypar \emptytoks +\neverypar \emptytoks + +\appendtoks \flushnotes \to \everypar +\appendtoks \synchronizesidefloats \to \everypar + +\appendtoks \checkinlinedirection \to \everypar + +\appendtoks \checkindentation \to \everypar +\appendtoks \showparagraphnumber \to \everypar +\appendtoks \flushmargincontents \to \everypar +\appendtoks \flushcommentanchors \to \everypar +\appendtoks \synchronizenotes \to \everypar +\appendtoks \OTRSETshowstatus \to \everypar +\appendtoks \flushpostponedbookmark \to \everypar +\appendtoks \registerparoptions \to \everypar +\appendtoks \flushsyncpositions \to \everypar +\appendtoks \flushpostponednodedata \to \everypar +\appendtoks \dohandlerepeatdelimitedtext \to \everypar +\appendtoks \insertparagraphintro \to \everypar + +\appendtoks \flushpostponedbookmark \to \neverypar +\appendtoks \flushpostponedbookmark \to \everylistentry + +\appendtoks \flushnotes \to \everydisplay +\appendtoks \adjustsidefloatdisplaylines \to \everydisplay + +\appendtoks \flushsyncpositions \to \everyheadstart + +\appendtoks \flushsyncresets \to \everyendoftextbody + +\appendtoks \ignorespaces \to \everybeginofpar + +\appendtoks \removeunwantedspaces \to \everyendofpar +%appendtoks \strut \to \everyendofpar % option ? +\appendtoks \flushsyncresets \to \everyendofpar +\appendtoks \setlastlinewidth \to \everyendofpar % must happen before endgraf +\appendtoks \endgraf \to \everyendofpar + +% Todo: verbatim, xml, tex, move code to here + +\ifx\normalcompound\undefined \let\normalcompound=| \fi + +\appendtoks \catcode`|=\@@active \let|\normalcompound \to \everyTEXinputmode +\appendtoks \catcode`|=\@@letter \to \everyXMLinputmode + +\protect \endinput diff --git a/tex/context/base/core-ini.mkiv b/tex/context/base/core-ini.mkiv new file mode 100644 index 000000000..d6a72bb26 --- /dev/null +++ b/tex/context/base/core-ini.mkiv @@ -0,0 +1,66 @@ +%D \module +%D [ file=core-ini, +%D version=2003.12.01, +%D title=\CONTEXT\ Core Macros, +%D subtitle=Additional 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 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. + +\unprotect + +\everypar \emptytoks +\neverypar \emptytoks + +\appendtoks \flushnotes \to \everypar +\appendtoks \synchronizesidefloats \to \everypar + +\appendtoks \checkindentation \to \everypar +\appendtoks \showparagraphnumber \to \everypar +\appendtoks \restoreinterlinepenalty \to \everypar +\appendtoks \flushmargincontents \to \everypar +\appendtoks \flushcommentanchors \to \everypar +\appendtoks \synchronizenotes \to \everypar +\appendtoks \OTRSETshowstatus \to \everypar +\appendtoks \flushpostponedbookmark \to \everypar +\appendtoks \registerparoptions \to \everypar +\appendtoks \flushsyncpositions \to \everypar +\appendtoks \flushpostponednodedata \to \everypar +\appendtoks \dohandlerepeatdelimitedtext \to \everypar +\appendtoks \insertparagraphintro \to \everypar + +\appendtoks \flushpostponedbookmark \to \neverypar +\appendtoks \flushpostponedbookmark \to \everylistentry + +\appendtoks \flushnotes \to \everydisplay +\appendtoks \adjustsidefloatdisplaylines \to \everydisplay + +\appendtoks \flushsyncpositions \to \everyheadstart + +\appendtoks \flushsyncresets \to \everyendoftextbody + +\appendtoks \ignorespaces \to \everybeginofpar + +\appendtoks \removeunwantedspaces \to \everyendofpar +%appendtoks \strut \to \everyendofpar % option ? +\appendtoks \flushsyncresets \to \everyendofpar +%appendtoks \setlastlinewidth \to \everyendofpar % gone, will be done in lua +\appendtoks \endgraf \to \everyendofpar + +% Todo: verbatim, xml, tex, move code to here + +\ifx\normalcompound\undefined \let\normalcompound=| \fi + +\appendtoks \catcode`|=\@@active \let|\normalcompound \to \everyTEXinputmode +\appendtoks \catcode`|=\@@letter \to \everyXMLinputmode + +\protect \endinput diff --git a/tex/context/base/core-job.lua b/tex/context/base/core-job.lua new file mode 100644 index 000000000..d557818bb --- /dev/null +++ b/tex/context/base/core-job.lua @@ -0,0 +1,202 @@ +if not modules then modules = { } end modules ['core-job'] = { + version = 1.001, + comment = "companion to core-job.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local texsprint, texprint, texwrite = tex.sprint, tex.print, tex.write +local ctxcatcodes, texcatcodes = tex.ctxcatcodes, tex.texcatcodes +local lower, format, find, gmatch, gsub, match = string.lower, string.format, string.find, string.gmatch, string.gsub, string.match +local concat = table.concat + +-- main code + +resolvers.maxreadlevel = 3 + +directives.register("resolvers.maxreadlevel", function(v) resolvers.maxreadlevel = tonumber(v) or resolvers.maxreadlevel end) + +local function exists(n) + if io.exists(n) then + return n + else + n = file.addsuffix(n,'tex') + if io.exists(n) then + return n + end + end + return nil +end + +function resolvers.findctxfile(name,maxreadlevel) + if file.is_qualified_path(name) then + return name + else + -- not that efficient, too many ./ lookups + local n = "./" .. name + local found = exists(n) + if found then + return found + else + for i=1,maxreadlevel or resolvers.maxreadlevel or 0 do + n = "../" .. n + found = exists(n) + if found then + return found + end + end + end + return resolvers.find_file(name) or "" + end +end + +function commands.maxreadlevel() + texwrite(resolvers.maxreadlevel) +end + +function commands.processfile(name,maxreadlevel) + name = resolvers.findctxfile(name,maxreadlevel) + if name ~= "" then + texsprint(ctxcatcodes,format("\\input %s\\relax",name)) -- we need \input {name} + end +end + +function commands.doifinputfileelse(name,maxreadlevel) + commands.doifelse(resolvers.findctxfile(name,maxreadlevel) ~= "") +end + +function commands.locatefilepath(name,maxreadlevel) + texsprint(texcatcodes,file.dirname(resolvers.findctxfile(name,maxreadlevel))) +end + +function commands.usepath(paths,maxreadlevel) + resolvers.register_extra_path(paths) + texsprint(texcatcodes,concat(resolvers.instance.extra_paths or {}, "")) +end + +function commands.usesubpath(subpaths,maxreadlevel) + resolvers.register_extra_path(nil,subpaths) + texsprint(texcatcodes,concat(resolvers.instance.extra_paths or {}, "")) +end + +function commands.usezipfile(name,tree) + if tree and tree ~= "" then + resolvers.usezipfile(format("zip:///%s?tree=%s",name,tree)) + else + resolvers.usezipfile(format("zip:///%s",name)) + end +end + +-- for the moment here, maybe a module + +--~ +--~ +--~ nee +--~ standaard +--~ + +local function convertexamodes(str) + local x = xml.convert(str) + for e in xml.collected(x,"exa:variable") do + local label = e.at and e.at.label + if label and label ~= "" then + local data = xml.text(e) + local mode = match(label,"^mode:(.+)$") + if mode then + texsprint(ctxcatcodes,format("\\enablemode[%s:%s]",mode,data)) + end + texsprint(ctxcatcodes,format("\\setvariable{exa:variables}{%s}{%s}",label,gsub(data,"([{}])","\\%1"))) + end + end +end + +-- 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.removesuffix(tex.jobname) + end + 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)) + else + commands.writestatus("examodes","no mode file %s",filename) -- todo: message system + 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 = find(a,",") +--~ local bb = find(b,",") +--~ if ba and bb then +--~ for sa in gmatch(a,"[^ ,]+") do +--~ for sb in gmatch(b,"[^ ,]+") do +--~ if sa == sb then +--~ texsprint(ctxcatcodes,"\\def\\commalistelement{",sa,"}") +--~ return true +--~ end +--~ end +--~ end +--~ elseif ba then +--~ for sa in gmatch(a,"[^ ,]+") do +--~ if sa == b then +--~ texsprint(ctxcatcodes,"\\def\\commalistelement{",b,"}") +--~ return true +--~ end +--~ end +--~ elseif bb then +--~ for sb in gmatch(b,"[^ ,]+") do +--~ if a == sb then +--~ texsprint(ctxcatcodes,"\\def\\commalistelement{",a,"}") +--~ return true +--~ end +--~ end +--~ else +--~ if a == b then +--~ texsprint(ctxcatcodes,"\\def\\commalistelement{",a,"}") +--~ return true +--~ end +--~ end +--~ texsprint(ctxcatcodes,"\\let\\commalistelement\\empty") +--~ return false +--~ end +--~ local function doifinsetelse(a,b) +--~ local bb = find(b,",") +--~ if bb then +--~ for sb in gmatch(b,"[^ ,]+") do +--~ if a == sb then +--~ texsprint(ctxcatcodes,"\\def\\commalistelement{",a,"}") +--~ return true +--~ end +--~ end +--~ else +--~ if a == b then +--~ texsprint(ctxcatcodes,"\\def\\commalistelement{",a,"}") +--~ return true +--~ end +--~ end +--~ texsprint(ctxcatcodes,"\\let\\commalistelement\\empty") +--~ return false +--~ end +--~ function commands.doifcommon (a,b) commands.doif (doifcommonelse(a,b)) end +--~ function commands.doifnotcommon (a,b) commands.doifnot (doifcommonelse(a,b)) end +--~ function commands.doifcommonelse(a,b) commands.doifelse(doifcommonelse(a,b)) 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 new file mode 100644 index 000000000..5c280c15b --- /dev/null +++ b/tex/context/base/core-job.mkii @@ -0,0 +1,415 @@ +%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} + +\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}% + \else + \let\filepath\empty + \def\docommand##1% + {\doiffileelse{\pathplusfile{##1}{#1}}{\donetrue\def\filepath{##1}}\donefalse + \ifdone\expandafter\quitcommalist\fi}% + \doifparentfileelse{#1} % new + {\processcommacommand [\allinputpaths]\docommand} + {\processcommacommand[.,\allinputpaths]\docommand}% + \ifx\filepath\empty + \def\next{\processlocalfile\readlocfile}% fall back ../../.. + \else + \def\next{\processlocalfile{\readsetfile\filepath}}% file found + \fi + \fi + \next{#1}} + +\def\doifinputfileelse#1% rarely used + {\ifx\allinputpaths\empty + \@EA\secondoftwoarguments + \else + \let\filepath\empty + \def\docommand##1% + {\doiffileelse{\pathplusfile{##1}{#1}}{\donetrue\def\filepath{##1}}\donefalse + \ifdone\expandafter\quitcommalist\fi}% + \processcommacommand[.,\allinputpaths]\docommand + \ifx\filepath\empty + \@EAEAEA\secondoftwoarguments + \else + \@EAEAEA\firstoftwoarguments + \fi + \fi} + +\let\locatedfilepath\empty + +\def\locatefilepath#1% + {\let\locatedfilepath\empty + \ifx\allinputpaths\empty \else + \def\docommand##1% + {\doiffileelse{\pathplusfile{##1}{#1}}{\donetrue\def\locatedfilepath{##1}}\donefalse + \ifdone\expandafter\quitcommalist\fi}% + \doifparentfileelse{#1} % new + {\processcommacommand [\allinputpaths]\docommand} + {\processcommacommand[.,\allinputpaths]\docommand}% + \fi} + +\def\usepath[#1]% + {\def\docommand##1% + {\doifelse{##1}\v!reset + {\let\allinputpaths\empty} + {\sanitizefilename#1\to\ascii + \defconvertedcommand\ascii\ascii + \addtocommalist\ascii\allinputpaths}}% + \processcommalist[#1]\docommand} + +\def\usesubpath[#1]% test for a real long time, permits ../{name} i.e. braces + {\ifx\allinputpaths\empty + \sanitizefilename#1\to\allinputpaths + \else + \def\docommand##1% + {\def\dodocommand####1% + {\sanitizefilename####1\to\ascii + \defconvertedcommand\ascii\ascii + \addtocommalist{##1/\ascii}\allinputpaths}% + \processcommalist[#1]\dodocommand}% + \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\forcequitjob#1% + {\writestatus\m!systems{forcing quit: #1}% + \batchmode + \dorecurse\textlevel\stoptext + \normalend} + +\let\autostoptext\relax + +\def\autostarttext + {\ifcase\textlevel + \starttext + \writestatus\m!systems{auto \string\starttext..\string\stoptext}% + \let\autostoptext\stoptext + \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 new file mode 100644 index 000000000..de328c92b --- /dev/null +++ b/tex/context/base/core-job.mkiv @@ -0,0 +1,309 @@ +%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} + +\unprotect + +\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")}} +\def\doifinputfileelse #1{\ctxlua{commands.doifinputfileelse("#1")}} +\def\locatefilepath #1{\edef\locatedfilepath{\ctxlua{commands.locatefilepath("#1")}}} +\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")}} + +\def\registerfileinfo[#1#2]#3% geen \showmessage ? + {\writestatus\m!systems{#1#2 file #3 at line \the\inputlineno}} + +\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 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} + +\unexpanded\def\starttext + {\doateverystarttext + \ifcase\textlevel + \registerfileinfo[begin]\jobfilename + \fi + \global\advance\textlevel\plusone} + +\unexpanded\def\stoptext + {\global\advance\textlevel\minusone + \ifnum\textlevel>\zerocount \else + \flushfinallayoutpage % optional + \page % anyway + \the\everystoptext + %\the\everybye % + %\the\everygoodbye % == \end (new) + %\expandafter\normalend % +\ifcase\textlevel + \registerfileinfo[end]\jobfilename +\fi + \expandafter\finalend + \fi} + +\def\forcequitjob#1% + {\writestatus\m!systems{forcing quit: #1}% + \batchmode + \dorecurse\textlevel{\stoptext} + \normalend} + +\let\autostoptext\relax + +\def\autostarttext + {\ifcase\textlevel + \starttext + \writestatus\m!systems{auto \string\starttext..\string\stoptext}% + \let\autostoptext\stoptext + \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\useenvironment[#1]% maybe commalist + {\environment #1 \relax} + +\def\environment #1 % at outermost level only (load only once) + {\pushmacro\startenvironment + \pushmacro\stopenvironment + \unexpanded\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} + +\unexpanded\def\startproject #1 % + {\donextlevel\v!project\currentproject + \donotexecutefile\doexecutefileonce + \doexecutefileonce\doexecutefile#1\\} + +\unexpanded\def\startproduct #1 % + {\doateverystarttext + \donextlevel\v!product\currentproduct + \doexecutefileonce\doexecutefileonce + \donotexecutefile\doexecutefile#1\\} + +\unexpanded\def\startcomponent #1 % + {\doateverystarttext + \donextlevel\v!component\currentcomponent + \doexecutefileonce\doexecutefileonce + \donotexecutefile\doexecutefile#1\\} + +\unexpanded\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 + +\unexpanded\def\stopproject {\doprevlevel} +\unexpanded\def\stopproduct {\doprevlevel} +\unexpanded\def\stopcomponent {\doprevlevel} +\unexpanded\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 + +\protect \endinput diff --git a/tex/context/base/core-mis.mkii b/tex/context/base/core-mis.mkii new file mode 100644 index 000000000..98079830d --- /dev/null +++ b/tex/context/base/core-mis.mkii @@ -0,0 +1,2742 @@ +%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] + +% \definieerplaats[naam][instellingen] +% \stelplaatsin[naam][instellingen] +% \plaats[[instellingen]] +% +% - still undocumented and also not in setupb yet +% - kan ook intern/direct (scheelt duplicatie), zie \framedtext + +\def\dodefineplacement[#1][#2]% + {\getparameters + [\??pl#1] + [\c!left=\hss, + \c!right=\hss, + \c!linecorrection=\v!off, + \c!depthcorrection=\v!off, + \c!margin=\v!standard, + \c!grid=\v!middle, + %\c!before=, + %\c!after=, + #2]% + \setvalue{\e!place#1}{\doplacement[\??pl#1]}} + +\def\defineplacement + {\dodoubleempty\dodefineplacement} + +\def\setupplacement + {\dodoubleempty\dosetupplacement} + +\def\dosetupplacement[#1]% + {\dodoubleempty\getparameters[\??pl#1]} + +\def\doplacement + {\dodoubleempty\dodoplacement} + +\def\dodoplacement[#1][#2]% correctie moet mooier + {\bgroup + \dowithnextboxcontent + {\forgetall} + {\setlocalhsize + \getparameters[#1][#2]% + \getvalue{#1\c!before}% + \begingroup + \disableparpositions + \setbox\nextbox\hbox to \localhsize + {\getvalue{#1\c!left}% + \flushnextbox + \getvalue{#1\c!right}}% + \ifinsidefloat \else + \addlocalbackgroundtobox\nextbox + \fi + \ifgridsnapping + \doifundefined{#1\c!grid}{\letvalue{#1\c!grid}\v!middle}% + % unchecked + \doifinset{\getvalue{#1\c!margin}}{\v!standard,\v!yes}\noindent + \snaptogrid[\getvalue{#1\c!grid}]\hbox{\flushnextbox}% + \else + \doifvalue{#1\c!linecorrection}\v!on \startbaselinecorrection + \doifinset{\getvalue{#1\c!margin}}{\v!standard,\v!yes}\noindent + \flushnextbox + \doifvalue{#1\c!depthcorrection}\v!on\baselinecorrection + \doifvalue{#1\c!linecorrection }\v!on\stopbaselinecorrection + \fi + \endgroup + \getvalue{#1\c!after}% + \egroup} + \vbox} + +% 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..e2bd28bd5 --- /dev/null +++ b/tex/context/base/core-mis.mkiv @@ -0,0 +1,2505 @@ +%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\checkedstrippedcsname#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} + +\unexpanded\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] + +% \definieerplaats[naam][instellingen] +% \stelplaatsin[naam][instellingen] +% \plaats[[instellingen]] +% +% - still undocumented and also not in setupb yet +% - kan ook intern/direct (scheelt duplicatie), zie \framedtext + +\def\dodefineplacement[#1][#2]% + {\getparameters + [\??pl#1] + [\c!left=\hss, + \c!right=\hss, + \c!linecorrection=\v!off, + \c!depthcorrection=\v!off, + \c!margin=\v!standard, + \c!grid=\v!middle, + %\c!before=, + %\c!after=, + #2]% + \setvalue{\e!place#1}{\doplacement[\??pl#1]}} + +\unexpanded\def\defineplacement + {\dodoubleempty\dodefineplacement} + +\unexpanded\def\setupplacement + {\dodoubleempty\dosetupplacement} + +\def\dosetupplacement[#1]% + {\dodoubleempty\getparameters[\??pl#1]} + +\def\doplacement + {\dodoubleempty\dodoplacement} + +\def\dodoplacement[#1][#2]% correctie moet mooier + {\bgroup + \dowithnextboxcontent + {\forgetall} + {\setlocalhsize + \getparameters[#1][#2]% + \getvalue{#1\c!before}% + \begingroup + \disableparpositions + \setbox\nextbox\hbox to \localhsize + {\getvalue{#1\c!left}% + \flushnextbox + \getvalue{#1\c!right}}% + \ifinsidefloat \else + \addlocalbackgroundtobox\nextbox + \fi + \ifgridsnapping + \doifundefined{#1\c!grid}{\letvalue{#1\c!grid}\v!middle}% + % unchecked + \doifinset{\getvalue{#1\c!margin}}{\v!standard,\v!yes}\noindent + \snaptogrid[\getvalue{#1\c!grid}]\hbox{\flushnextbox}% + \else + \doifvalue{#1\c!linecorrection}\v!on \startbaselinecorrection + \doifinset{\getvalue{#1\c!margin}}{\v!standard,\v!yes}\noindent + \flushnextbox + \doifvalue{#1\c!depthcorrection}\v!on\baselinecorrection + \doifvalue{#1\c!linecorrection }\v!on\stopbaselinecorrection + \fi + \endgroup + \getvalue{#1\c!after}% + \egroup} + \vbox} + +% 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]} + +\unexpanded\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} + +\unexpanded\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\dimexpr(\paragraphcellmeter\alcounter\c!distance-\linewidth)/2\relax + \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]} + +\unexpanded\def\setuptab + {\dosingleargument\dosetuptab} + +\setuptab + [\c!location=\v!left] + +\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: + +\unexpanded\def\setuphyphenmark + {\dodoubleargument\getparameters[\??kp]} + +\unexpanded\def\setuphyphenmark[#1]% sign=normal|wide + {\dodoubleargument\getparameters[\??kp][#1]% + \doifelse\@@kpsign {\v!normal}% was inset? + {\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!righthyphen}} + {\hbox{\directsymbol\empty\c!lefthyphen}} + {\hbox{\directsymbol\empty\c!hyphen}}} + +\def\composedhyphendiscretionary + {\discretionary + {\hbox{\directsymbol\empty\c!rightcompoundhyphen}} + {\hbox{\directsymbol\empty\c!leftcompoundhyphen}} + {\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 + +\unexpanded\def\startsubsentence{\beginofsubsentence \prewordbreak\beginofsubsentencespacing} +\unexpanded\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 + \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}}} + +\unexpanded\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} + {\setuvalue{#1}{\delimitedtext[#1]}% + \setvalue{\e!start#1}{\startdelimitedtext[#1]}% + \setvalue{\e!stop #1}{\stopdelimitedtext}}} + +\unexpanded\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 + +\unexpanded\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\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 + \pushmacro\checkindentation + \doifsomething{\delimitedtextparameter\c!indenting} % WS + {\setupindenting[\delimitedtextparameter\c!indenting]}% + \dostartattributes{\??ci\currentdelimitedtext}\c!style\c!color\empty + \leftdelimitedtextmark + \ignorespaces} + +\def\dostopdelimitedtextpar + {\removeunwantedspaces + \removelastskip + \rightdelimitedtextmark + \dostopattributes + \popmacro\checkindentation + \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} + +\unexpanded\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} + +\unexpanded\def\delimitedtext[#1]% + {\dontleavehmode % following ones can be omited + \pushdelimitedtext{#1}% + \doifelse{\delimitedtextparameter\c!method}\s!font + {\dofontdrivendelimited} + {\doifinsetelse{\delimitedtextparameter\c!location}{\v!paragraph,\v!margin}% + \dodelimitedtextpar\dodelimitedtexttxt}} + +% shortcuts + +\unexpanded\def\startdelimited{\startdelimitedtext} +\unexpanded\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] + +\unexpanded\def\setupquotation{\setupdelimitedtext[\v!quotation]} +\unexpanded\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} +% +% \unexpanded\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} +% +% \unexpanded\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 + +\unexpanded\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]}} + +\unexpanded\def\setuppairedbox + {\dodoubleempty\dosetuppairedbox} + +\def\dosetuppairedbox[#1]% + {\getparameters[\??ld#1]} + +\unexpanded\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 + {\ifnum\@@ldn>1 + \rigidcolumnbalance\nextbox + \else + \flushnextbox + \fi}% + \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 ... + +% needs to be mkiv'd + +\newcount\horcombination % counter +\newcount\totcombination + +\unexpanded\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]} + +\unexpanded\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}% + +\unexpanded\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} + +\def\depthonlybox + {\dowithnextbox{\vtop{\hsize\wd\nextbox\kern\zeropoint\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: +% +% \unexpanded\def\stopcombination +% {\egroup +% \egroup} +% +% more robust: +% +% \unexpanded\def\stopcombination +% {{}{}{}{}{}{}{}{}% catches (at most 4) missing entries +% \egroup +% \egroup} +% +% even better: + +\unexpanded\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 + +\unexpanded\def\startfloatcombination + {\dodoubleempty\dostartfloatcombination} + +\def\dostartfloatcombination[#1][#2]% + {\vbox\bgroup + %\insidecolumnstrue % trick, forces no centering, todo: proper switch/feature + \chardef\postcenterfloatmethod\zerocount + \forcelocalfloats + \unexpanded\def\stopfloatcombination + {\scratchtoks\emptytoks + \dorecurse\noflocalfloats + {\appendetoks{\noexpand\getlocalfloat{\recurselevel}}{}\to\scratchtoks}% + \expanded{\startcombination[#1]\the\scratchtoks}\stopcombination + \resetlocalfloats + \egroup}} + +\unexpanded\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} + +\unexpanded\def\placeontopofeachother{\placerelativetoeachother\halign\hss} +\unexpanded\def\placesidebyside {\placerelativetoeachother\valign\vss} + +%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] + +\unexpanded\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} + +\unexpanded\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-par.mkii b/tex/context/base/core-par.mkii new file mode 100644 index 000000000..0b283b294 --- /dev/null +++ b/tex/context/base/core-par.mkii @@ -0,0 +1,300 @@ +%D \module +%D [ file=core-par, +%D version=1997.03.31, +%D title=\CONTEXT\ Core Macros, +%D subtitle=Paragraph Tricks, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Pararaph Tricks} + +\unprotect + +% \ifprocesspreviousparagraphs +% +% \nofskippedparagraphs +% \paragraphnumber +% \nofparagraphs +% +% \dosetparagraph +% \doresetparagraph +% \dobeforeparagraph +% \doafterparagraph +% \dobeforeskipparagraph +% \doafterskipparagraph +% +% \pushparagraphs\endcommand alle alineas tot \endcommand laden +% \pushmoreparagraphs\endcommand alle alineas tot \endcommand toevoegen +% \popparagraphs alle alineas oproepen +% \popparagraphs[a,b,c] enkele alineas oproepen [geen] +% +% tzt een optionele prefix: +% +% \pushparagraphs[xxx]\endcommand alle alineas tot \endcommand laden +% \popparagraphs[xxx] alle alineas oproepen +% \popparagraphs[xxx][a,b,c] enkele alineas oproepen +% +% \numberparagraphs +% \numberparagraphlines +% \resetparagraphlines + +\newif\ifprocesspreviousparagraphs % public +\newif\ifprocessallparagraphs % private + +\newcounter\totalnofparagraphs % private +\newcounter\globalparagraphnumber % private +\newcounter\discardedparagraphs % private +\newcounter\mostrecentparagraphtotal % public + +\let\dosetparagraph = \relax % public +\let\doresetparagraph = \relax % public +\let\dobeforeparagraph = \relax % public +\let\doafterparagraph = \relax % public +\let\dobeforeskipparagraph = \relax % public +\let\doafterskipparagraph = \relax % public + +\def\paragraphnumber {} % public +\def\nofparagraphs {} % public +\def\nofskippedparagraphs {} % public + +\def\paragraphprefix {paragraph} % private + +% voorlopig, wordt nog class + +\def\resetparagraphlines + {\global\linenumber\plusone} + +\def\numberparagraphs % instelbaar maken en slimmer ivm breedte regelnummer !!!!! + {\processpreviousparagraphstrue + \def\dosetparagraph + {\bgroup + \resetparagraphlines + \EveryPar + {\strut\inleftmargin{\tf{\tx\paragraphnumber}\kern2em}% + \ignorespaces}}% + \def\doresetparagraph + {\resetparagraphlines + \egroup}} + +\def\numberparagraphlines + {\processpreviousparagraphstrue + \def\dosetparagraph + {\resetparagraphlines}% + \def\doresetparagraph + {\resetparagraphlines}% + \def\dobeforeparagraph + {\startlinenumbering[\v!continue]}% + \def\doafterparagraph + {\stoplinenumbering}% + \def\dobeforeskipparagraph + {\stoplinenumbering + \let\paragraphnumber\relax}% + \def\doafterskipparagraph + {\startlinenumbering[\v!continue]}} + +\long\def\directpushparagraph#1% + {\doglobal\increment\totalnofparagraphs + \ifnum\totalnofparagraphs>0\nofskippedparagraphs\relax + \setgvalue{\paragraphprefix\totalnofparagraphs}{#1}% + \else + \setgvalue{\paragraphprefix\totalnofparagraphs}{\skipparagraph#1\par}% + \fi} + +\long\def\directskipparagraph#1% + {\doglobal\increment\totalnofparagraphs + \setgvalue{\paragraphprefix\totalnofparagraphs}{\skipparagraph#1\par}} + +\def\dopushparagraphs#1% + {\global\let\mostrecentparagraphtotal\totalnofparagraphs + \ifx#1\undefined + \let#1\relax + \fi + \defconvertedargument\asciia{#1}% + \defconvertedargument\asciib{ }% % lege regel + \def\dopushparagraph##1\par + {\defconvertedargument\asciic{##1}% + \doifelse\asciic\asciia + {#1} + {\doifsomething\asciic % lege paragraaf + {\doifnot\asciic\asciib + {\directpushparagraph{#1}}}% + \dopushparagraph}}% + \dopushparagraph} + +\def\pushparagraphs + {\doglobal\newcounter\totalnofparagraphs + \dopushparagraphs} + +\def\pushmoreparagraphs + {\dopushparagraphs} + +\def\dododopopparagraph#1% no grouping, i.v.m. sidefloats + {\ifnum#1>\totalnofparagraphs\relax + \else + \let\paragraphnumber\globalparagraphnumber + \decrement(\paragraphnumber,\discardedparagraphs)% + \dobeforeparagraph + \ifhmode\indentation\fi\getvalue{\paragraphprefix#1}\par + \doafterparagraph + \fi} + +\long\def\skipparagraph#1\par + {\doglobal\increment\discardedparagraphs + \ifprocessallparagraphs + \dobeforeskipparagraph + \ifhmode\indentation\fi#1\par + \doafterskipparagraph + \fi} + +\def\dodopopparagraph + {\dododopopparagraph} + +\def\dodoprocessparagraph#1% + {\ifprocesspreviousparagraphs + \bgroup + \setbox0\vbox{\dododopopparagraph{#1}}% + \egroup + \fi} + +\def\processpreviousparagraphs[#1]% process previous ones + {\ifprocesspreviousparagraphs + \bgroup + \getfromcommacommand[#1][1]% tzt snelle \..command.. testen + \let\totalnofparagraphs\commalistelement + \decrement\totalnofparagraphs + \let\dodopopparagraph\dodoprocessparagraph + \popparagraphs + \egroup + \fi} + +\def\dopopparagraphs[#1]% + {\doifnotinset{#1}{\v!none,0} + {\dosetparagraph + \doglobal\newcounter\globalparagraphnumber + \doglobal\newcounter\discardedparagraphs + \doifelse{#1}{} + {\processallparagraphstrue} + {\processallparagraphsfalse}% + \def\dopopparagraph + {\doglobal\increment\globalparagraphnumber + \ifnum\globalparagraphnumber>\totalnofparagraphs\relax + \let\dopopparagraph\relax + \else\ifprocessallparagraphs + \ifnum\globalparagraphnumber>\mostrecentparagraphtotal\relax + \dodopopparagraph\globalparagraphnumber + \else + \dodoprocessparagraph\globalparagraphnumber + \fi + \else + \let\paragraphnumber\globalparagraphnumber + \decrement(\paragraphnumber,\discardedparagraphs)% + \ExpandBothAfter\doifinsetelse{\paragraphnumber}{#1} + {\dodopopparagraph\globalparagraphnumber} + {\dodoprocessparagraph\globalparagraphnumber}% + \fi\fi + \dopopparagraph}% + \dopopparagraph + \doresetparagraph}} + +\def\popparagraphs + {\dosingleempty\dopopparagraphs} + +\def\countparagraphs + {\popparagraphs[\!!maxcard]% + \global\let\nofparagraphs\totalnofparagraphs + \doglobal\decrement(\nofparagraphs,\discardedparagraphs)} + +% \showframe +% +% \numberparagraphlines +% \numberparagraphs +% +% \def\nofskippedparagraphs{1} +% +% \pushparagraphs\ThatsIt +% +% \ruledbaseline eerste eerste eerste eerste eerste eerste +% eerste eerste eerste eerste eerste eerste eerste eerste +% eerste eerste eerste eerste eerste eerste eerste eerste +% eerste eerste eerste eerste eerste eerste eerste eerste +% eerste eerste eerste eerste eerste eerste eerste eerste +% eerste eerste eerste eerste eerste +% +% \ruledbaseline eerste eerste eerste eerste eerste eerste +% eerste eerste eerste eerste eerste eerste eerste eerste +% eerste eerste eerste eerste eerste eerste eerste eerste +% eerste eerste eerste eerste eerste eerste eerste eerste +% eerste eerste eerste eerste eerste eerste eerste eerste +% eerste eerste eerste eerste eerste +% +% \ruledbaseline tweede tweede tweede tweede tweede tweede +% tweede tweede tweede tweede tweede tweede tweede tweede +% tweede tweede tweede tweede tweede tweede tweede tweede +% tweede tweede tweede tweede tweede tweede tweede tweede +% tweede tweede tweede tweede tweede tweede tweede tweede +% tweede tweede tweede tweede tweede tweede tweede tweede +% tweede tweede tweede tweede tweede +% +% \skipparagraph \ruledbaseline skipped skipped skipped +% skipped skipped skipped skipped skipped skipped skipped +% skipped skipped skipped skipped skipped skipped skipped +% skipped skipped +% +% \ruledbaseline derde derde derde derde derde derde derde +% derde derde derde derde derde derde derde derde derde derde +% derde derde derde derde derde derde derde derde derde derde +% derde derde derde derde derde derde derde derde derde derde +% derde derde derde derde derde derde derde derde derde derde +% derde derde derde derde derde derde derde derde derde derde +% +% \skipparagraph \ruledbaseline skipped skipped skipped +% skipped skipped skipped skipped skipped skipped skipped +% skipped skipped skipped skipped skipped skipped skipped +% skipped skipped skipped +% +% \ruledbaseline vierde vierde vierde vierde vierde vierde +% vierde vierde vierde vierde vierde vierde vierde vierde +% vierde vierde vierde vierde vierde vierde vierde vierde +% vierde vierde vierde vierde +% +% \ruledbaseline vijfde vijfde vijfde vijfde vijfde vijfde +% vijfde vijfde vijfde vijfde vijfde vijfde vijfde vijfde +% vijfde vijfde vijfde vijfde vijfde vijfde vijfde vijfde +% vijfde vijfde vijfde vijfde vijfde vijfde vijfde vijfde +% vijfde vijfde vijfde +% +% \skipparagraph \ruledbaseline skipped skipped skipped +% skipped skipped skipped skipped skipped skipped skipped +% skipped skipped skipped skipped skipped skipped skipped +% skipped skipped skipped +% +% \ThatsIt +% +% \popparagraphs +% +% \countparagraphs +% +% \blanko[2*groot] +% +% nofparagraphs:~\nofparagraphs +% +% \pagina +% +% \popparagraphs[1] +% \popparagraphs[2] +% \popparagraphs[3] +% \popparagraphs[4] +% \popparagraphs[5] +% +% \pagina +% +% \ruledvbox{\popparagraphs[1,2,3,4,5]} +% +% \pagina + +\protect \endinput diff --git a/tex/context/base/core-stg.mkii b/tex/context/base/core-stg.mkii new file mode 100644 index 000000000..429e1e894 --- /dev/null +++ b/tex/context/base/core-stg.mkii @@ -0,0 +1,72 @@ +%D \module +%D [ file=core-stg, +%D version=2006.08.16, +%D title=\CONTEXT\ Core Macros, +%D subtitle=Strategies, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 prelude to strategies. It is rather old code +%D used in a project many years ago. Use with care since I +%D will pick up this thread. (moved from cont-new) + +\unprotect + +\def\s!strategy{strategy} + +\def\currentstrategypass {1} +\def\currentstrategyvariable{0} +\def\maximumstrategypass {8} + +\newconditional\strategypassneeded +\newconditional\strategypassforced + +\definetwopasslist{\s!strategy} + +\def\registerstrategypass + {\ifnum\currentstrategypass>\maximumstrategypass \else + \ifconditional\strategypassforced + \doglobal\increment\currentstrategypass + \else%\ifconditional\strategypassneeded + %\doglobal\increment\currentstrategypass + \fi%\fi + \fi + \savecurrentvalue\currentstrategypass{\currentstrategypass}} + +\appendtoks \registerstrategypass \to \everybye % \everylastshipout + +\def\setstrategyvariable#1#2% key value + {%\doifnotstrategyvariable{#1}{\global\settrue\strategypassneeded}% + \doglobal\increment\currentstrategyvariable + \savetaggedtwopassdata{\s!strategy}{\currentstrategyvariable}{#1}{#2}} + +\def\doifstrategyvariableelse#1#2#3% + {\getstrategyvariable{#1}\iftwopassdatafound#2\else#3\fi} + +\def\getstrategyvariable#1% key + {\findtwopassdata{\s!strategy}{#1}% + \setxvalue{\s!strategy:#1}{\twopassdata}} + +\def\retainstrategyvariable#1% key + {\expanded{\setstrategyvariable{#1}{\strategyvariable{#1}}}} + +\def\strategyvariable#1% key + {\csname\s!strategy:#1\endcsname} + +\let\stratvar\strategyvariable + +\def\forcestrategy{\global\settrue \strategypassforced} +\def\abortstrategy{\global\setfalse\strategypassforced} + +\def\doifstrategyvariableelse#1#2#3% + {\getstrategyvariable{#1}\iftwopassdatafound#2\else#3\fi} + +\def\doifstrategyvariable #1#2{\doifstrategyvariableelse{#1}{#2}{}} +\def\doifnotstrategyvariable#1#2{\doifstrategyvariableelse{#1}{}{#2}} + +\protect \endinput diff --git a/tex/context/base/core-sys.lua b/tex/context/base/core-sys.lua new file mode 100644 index 000000000..c5aa89d98 --- /dev/null +++ b/tex/context/base/core-sys.lua @@ -0,0 +1,22 @@ +if not modules then modules = { } end modules ['core-sys'] = { + version = 1.001, + comment = "companion to core-sys.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local lower, extname, basename, removesuffix = string.lower, file.extname, file.basename, file.removesuffix + +function commands.updatefilenames(inputfilename,outputfilename) + environment.inputfilename = inputfilename or "" + environment.outputfilename = outputfilename or "" + environment.jobfilename = inputfilename or tex.jobname or "" + environment.jobfilesuffix = lower(extname(environment.jobfilename)) + environment.inputfilebarename = removesuffix(basename(inputfilename)) + environment.inputfilesuffix = lower(extname(inputfilename)) +end + +statistics.register("result saved in file", function() + return string.format( "%s.%s", environment.outputfilename, (tex.pdfoutput>0 and "pdf") or "dvi") +end) diff --git a/tex/context/base/core-sys.mkii b/tex/context/base/core-sys.mkii new file mode 100644 index 000000000..24975ffb6 --- /dev/null +++ b/tex/context/base/core-sys.mkii @@ -0,0 +1,396 @@ +%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: + +\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 new file mode 100644 index 000000000..649e5e65c --- /dev/null +++ b/tex/context/base/core-sys.mkiv @@ -0,0 +1,432 @@ +%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. + +% we need to mkiv-ize this file ! + +\writestatus{loading}{ConTeXt Core Macros / System} + +\registerctxluafile{core-sys}{1.001} + +\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} + +\edef\operatingsystem {\ctxlua{tex.write(os.platform)}} + +\def\jobfilename {\ctxlua{tex.sprint(tex.texcatcodes,environment.jobfilename or "")}} +\def\jobfilesuffix {\ctxlua{tex.sprint(tex.texcatcodes,environment.jobfilesuffix or "")}} +\def\inputfilebarename{\ctxlua{tex.sprint(tex.texcatcodes,environment.inputfilebarename or "")}} +\def\inputfilesuffix {\ctxlua{tex.sprint(tex.texcatcodes,environment.inputfilesuffix or "")}} +\def\inputfilename {\ctxlua{tex.sprint(tex.texcatcodes,environment.inputfilename or "")}} +\def\outputfilename {\ctxlua{tex.sprint(tex.texcatcodes,environment.outputfilename or "")}} + +\def\initializenewlinechar + {\bgroup\newlinechar=10\xdef\outputnewlinechar{^^J}\egroup} + +\newtoks \everysetupsystem + +\unexpanded\def\setupsystem + {\dosingleargument\dosetupsystem} + +\def\dosetupsystem[#1]% + {\getparameters[\??sv][#1]% + \the\everysetupsystem} + +\appendtoks + \edef\outputresolution{\@@svresolution}% +\to \everysetupsystem + +\appendtoks + \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 +\to \everysetupsystem + +\appendtoks + \edef\outputfilename{\@@svfile}% + \edef\inputfilename {\@@svinputfile}% +\to \everysetupsystem + +\let\@@jobsuffix\s!unknown + +\appendtoks + \resetsystemmode{suffix-\@@jobsuffix}% + \edef\@@jobsuffix{\jobsuffix}% + \setsystemmode{suffix-\@@jobsuffix}% +\to \everysetupsystem + +\appendtoks + \ctxlua {commands.updatefilenames("\inputfilename","\outputfilename")}% +\to \everysetupsystem + +% 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}}}} + +\let\systemendofline\outputnewlinechar % will become obsolete + +\def\systemparameter#1{\executeifdefined{\??sv#1}\empty} + +%D There are a couple of system states avaiable: +%D +%D \starttabulate [|T|T|] +%D \NC \type{\jobname} \NC \jobname \NC \NR +%D \NC \type{\jobfilename} \NC \jobfilename \NC \NR +%D \NC \type{\jobfilesuffix} \NC \jobfilesuffix \NC \NR +%D \NC \type{\inputfilename} \NC \inputfilename \NC \NR +%D \NC \type{\inputfilebarename} \NC \inputfilebarename \NC \NR +%D \NC \type{\inputfilesuffix} \NC \inputfilesuffix \NC \NR +%D \NC \type{\outputfilename} \NC \outputfilename \NC \NR +%D \NC \type{\operatingsystem} \NC \operatingsystem \NC \NR +%D \stoptabulate + +%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 + +\unexpanded\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=600,% in dpi, no unit in mkiv + %c!random=, % obsolete here + \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}} + +\unexpanded\def\startlocal {\dostartglobaldefs>-} +\unexpanded\def\stoplocal {\dostopglobaldefs} +\unexpanded\def\startglobal {\dostartglobaldefs<+} +\unexpanded\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]% + \setuvalue{#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} + +\unexpanded\def\definestartstop + {\dodoubleargument\dodefinestartstop} + +\def\dosetupstartstop[#1][#2]% + {\def\docommand##1{\getparameters[\??be##1][#2]}% + \processcommalist[#1]\docommand} + +\unexpanded\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} +% +% \unexpanded\def\defineprotected#1#2% +% {\expandafter\def\csname\??pc\string#2\endcsname} +% +% \unexpanded\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 + +% \startluacode +% local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes +% local format, match, gmatch, rep = string.format, string.match, string.gmatch, string.rep +% local empty = { +% "single", +% "double", +% "triple", +% "quadruple", +% "quintuple", +% } +% local check = { +% "first", +% "second", +% "third", +% "fourth", +% "fifth", +% } +% function commands.define(str) +% -- we could store the defaults in lua and call lua instead but why bother +% local arg, cmd = match(str,"(.*)\\(.-)$") +% local a = { } +% for s in gmatch(arg,"%[(.-)%]") do +% a[#a+1] = s +% end +% local n = tonumber(a[#a]) +% if n then +% a[#a] = nil +% else +% n = 0 +% end +% texsprint(ctxcatcodes,format("\\unexpanded\\def\\%s",cmd)) +% if #a > 0 then +% texsprint(ctxcatcodes,format("{\\do%sempty\\do%s}",empty[#a],cmd)) +% texsprint(ctxcatcodes,format("\\def\\do%s",cmd)) +% for i=1,#a do +% texsprint(ctxcatcodes,"[#",i,"]") +% end +% texsprint(ctxcatcodes,"{") +% for i=#a,1,-1 do +% texsprint(ctxcatcodes,format("\\if%sargument",check[i])) +% texsprint(ctxcatcodes,format("\\def\\next{\\dodo%s",cmd)) +% for j=1,#a-i do +% texsprint(ctxcatcodes,format("[%s]",a[j])) +% end +% for j=1,i do +% texsprint(ctxcatcodes,format("[#%s]",j)) +% end +% texsprint(ctxcatcodes,"}") +% if i == 1 then +% texsprint(ctxcatcodes,rep("\\fi",#a)) +% else +% texsprint(ctxcatcodes,"\\else") +% end +% end +% texsprint(ctxcatcodes,"\\next}") +% texsprint(ctxcatcodes,format("\\def\\dodo%s",cmd)) +% for i=1,#a do +% texsprint(ctxcatcodes,"[#",i,"]") +% end +% end +% for i=1,n do +% texsprint(ctxcatcodes,"#",#a+i) +% end +% end +% \stopluacode +% +% \unexpanded\def\define#1#{\ctxlua{commands.define([[\detokenize{#1}]])}} +% +% \starttext +% \define[2]\whatevera{#1+#2} +% \whatevera{A}{B} +% \define[me][too][2]\whateverb{#1+#2+#3+#4} +% \whateverb[A]{B}{C} +% \whateverb[A][B]{C}{D} +% \stoptext + +\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. +%D +%D We keep this around for \MKII\ \XML\ but it's not used in \MKIV\ +%D code as expansion is controlled in another way there. + +\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 + +\def\dodefconvertedmeaning#1#2#3% watch the double expansion ! + {\bgroup + \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} + +\protect \endinput diff --git a/tex/context/base/core-two.lua b/tex/context/base/core-two.lua new file mode 100644 index 000000000..24a3191a7 --- /dev/null +++ b/tex/context/base/core-two.lua @@ -0,0 +1,137 @@ +if not modules then modules = { } end modules ['core-two'] = { + version = 1.001, + comment = "companion to core-two.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local remove, concat = table.remove, table.concat + +local texprint = tex.print + +--[[ldx-- +

We save multi-pass information in the main utility table. This is a +bit of a mess because we support old and new methods.

+--ldx]]-- + +jobpasses = jobpasses or { } +jobpasses.collected = jobpasses.collected or { } +jobpasses.tobesaved = jobpasses.tobesaved or { } + +local collected, tobesaved = jobpasses.collected, jobpasses.tobesaved + +local function initializer() + collected, tobesaved = jobpasses.collected, jobpasses.tobesaved +end + +job.register('jobpasses.collected', jobpasses.tobesaved, initializer, nil) + +local function allocate(id) + local p = tobesaved[id] + if not p then + p = { } + tobesaved[id] = p + end + return p +end + +jobpasses.define = allocate + +function jobpasses.save(id,str) + local jti = allocate(id) + jti[#jti+1] = str +end + +function jobpasses.savetagged(id,tag,str) + local jti = allocate(id) + jti[tag] = str +end + +function jobpasses.getcollected(id) + return collected[id] or { } +end + +function jobpasses.gettobesaved(id) + return allocate(id) +end + +function jobpasses.get(id) + local jti = collected[id] + if jti and #jti > 0 then + texprint(remove(jti,1)) + end +end + +function jobpasses.first(id) + local jti = collected[id] + if jti and #jti > 0 then + texprint(jti[1]) + end +end + +function jobpasses.last(id) + local jti = collected[id] + if jti and #jti > 0 then + texprint(jti[#jti]) + end +end + +jobpasses.check = jobpasses.first + +function jobpasses.find(id,n) + local jti = collected[id] + if jti and jti[n] then + texprint(jti[n]) + end +end + +function jobpasses.count(id) + local jti = collected[id] + texprint((jti and #jti) or 0) +end + +function jobpasses.list(id) + local jti = collected[id] + if jti then + texprint(concat(jti,',')) + end +end + +function jobpasses.doifinlistelse(id,str) + local jti = collected[id] + if jti then + local found = false + for _, v in next, jti do + if v == str then + found = true + break + end + end + commands.testcase(found) + else + commands.testcase(false) + end +end + +-- + +function jobpasses.savedata(id,data) + local jti = allocate(id) + jti[#jti+1] = data + return #jti +end + +function jobpasses.getdata(id,index,default) + local jti = collected[id] + local value = jit and jti[index] + texprint((value ~= "" and value) or default or "") +end + +function jobpasses.getfield(id,index,tag,default) + local jti = collected[id] + jti = jti and jti[index] + local value = jti and jti[tag] + texprint((value ~= "" and value) or default or "") +end + diff --git a/tex/context/base/core-two.mkii b/tex/context/base/core-two.mkii new file mode 100644 index 000000000..0f2e0048c --- /dev/null +++ b/tex/context/base/core-two.mkii @@ -0,0 +1,206 @@ +%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 \gobblethreearguments % permits loading a MK II file +\let\twopassdata \empty +\let\twopassdatalist\empty + +\newif\iftwopassdatafound + +\addutilityreset{twopassentries} + +\def\immediatesavetwopassdata #1#2#3{\immediatewriteutilitycommand{\twopassentry{#1}{#2}{#3}}} +\def\savetwopassdata #1#2#3{\writeutilitycommand{\twopassentry{#1}{#2}{#3}}} +\def\lazysavetwopassdata #1#2#3{\expanded{\writeutilitycommand{\noexpand\twopassentry{#1}{#2}{#3}}}} % expanded ! +\def\savetaggedtwopassdata #1#2#3#4{\immediatewriteutilitycommand{\twopassentry{#1}{#2}{#3::#4}}} +\def\lazysavetaggedtwopassdata#1#2#3#4{\expanded{\writeutilitycommand{\noexpand\twopassentry{#1}{#2}{#3::#4}}}} % expanded ! + +\def\resettwopassentries + {\let\twopassentry\gobblethreearguments} + +\def\settwopassentries + {\def\twopassentry##1{\executeifdefined{@@##1\s!pass}\gobbletwoarguments}} + +\resettwopassentries + +\def\appendtwopasselement#1#2#3% can sometimes become a large list + {%\debuggerinfo{\m!systems}{twopass data #1 - #2 = #3}% + \expandafter\xdef\csname#1:\s!list\endcsname + {\@EA\ifx\csname#1:\s!list\endcsname\empty \else + \csname#1:\s!list\endcsname,\fi#3}} + +\def\dodefinetwopasslist#1% + {\doifundefined{#1:\s!list} + {%\debuggerinfo\m!systems{defining twopass class #1}% + \doglobal\addutilityreset{#1\s!pass}% + \setgvalue{\s!set #1\s!pass}{\dosettwopasslist {#1}}% + \setgvalue{\s!reset#1\s!pass}{\doresettwopasslist{#1}}% + \getvalue {\s!reset#1\s!pass}}} + +\def\definetwopasslist#1% + {\expanded{\dodefinetwopasslist{#1}}% + \doglobal\addtocommalist{#1}\alltwopasslists} + +\def\dosettwopasslist#1% + {\letgvalue{\s!set#1\s!pass}\gobbletwoarguments + \setgvalue{@@#1\s!pass}{\appendtwopasselement{#1}}} + +\def\doresettwopasslist#1% + {\letgvalue{@@#1\s!pass}\gobbletwoarguments} + +\def\doloadtwopassdata#1% + {\doifundefined{#1:\s!list} + {\startnointerference + \letgvalueempty{#1:\s!list}% + \protectlabels + \doutilities{twopassentries,#1\s!pass}\jobname\empty\relax\relax + \stopnointerference}} + +\def\loadtwopassdata + {\ifx\alltwopasslists\empty\else + \processcommacommand[\alltwopasslists]\doloadtwopassdata + \globallet\alltwopasslists\empty + \fi} + +\def\dogettwopassdata[#1,#2]#3#4% + {\edef\twopassdata{#1}% + \ifx\twopassdata\empty + \twopassdatafoundfalse + \let\twopassdata\empty + \else + \twopassdatafoundtrue + \ifcase#4\or\setxvalue{#3:\s!list}{#2}\fi + \fi} + +\def\gettwopassdata#1% + {\loadtwopassdata \@EAEAEA\dogettwopassdata\@EA\@EA\@EA[\csname#1:\s!list\endcsname,]{#1}\plusone} + +\def\checktwopassdata#1% + {\loadtwopassdata \@EAEAEA\dogettwopassdata\@EA\@EA\@EA[\csname#1:\s!list\endcsname,]{#1}\zerocount} + +\def\findtwopassdata#1#2% + {\loadtwopassdata \expanded{\dofindtwopassdata{#1}{#2}}} + +\def\dofindtwopassdata#1#2% + {\def\dodofindtwopassdata[##1,##2#2::##3,##4]{\edef\twopassdata{##3}}% + \@EAEAEA\dodofindtwopassdata\@EA\@EA\@EA[\@EA\@EA\@EA,\csname#1:\s!list\endcsname,#2,#2::,]% + \ifx\twopassdata\empty + \twopassdatafoundfalse + \else + \twopassdatafoundtrue + \fi} + +\let\getfirsttwopassdata\checktwopassdata + +\def\getlasttwopassdata#1% + {\loadtwopassdata + \scratchcounter\zerocount + \@EAEAEA\rawprocesscommalist\@EA\@EA\@EA[\csname#1:\s!list\endcsname]\dogetlasttwopassdata + \edef\noftwopassitems{\the\scratchcounter}% + \iftwopassdatafound\else + \let\twopassdata\empty + \fi} + +\def\dogetlasttwopassdata#1% + {\edef\nexttwopassdata{#1}% + \ifx\nexttwopassdata\empty \else + \let\twopassdata\nexttwopassdata + \advance\scratchcounter \plusone + \twopassdatafoundtrue + \fi} + +\def\getfromtwopassdata#1#2% + {\loadtwopassdata + \@EAEAEA\getfromcommalist\@EA\@EA\@EA[\csname#1:\s!list\endcsname][#2]% + \ifx\commalistelement\empty + \twopassdatafoundfalse + \let\twopassdata\empty + \else + \twopassdatafoundtrue + \let\twopassdata\commalistelement + \fi} + +\def\gettwopassdatalist#1% + {\loadtwopassdata + \letcscsname\twopassdatalist\csname#1:\s!list\endcsname + \ifx\twopassdatalist\relax\let\twopassdatalist\empty\fi} + +\def\gettwopassdatalist + {\getnamedtwopassdatalist\twopassdatalist} + +\def\doifelseintwopassdata#1#2% tag dat + {\gettwopassdatalist{#1}% + \expanded{\doifinsetelse{#2}{\twopassdatalist}}} + +\protect \endinput diff --git a/tex/context/base/core-two.mkiv b/tex/context/base/core-two.mkiv new file mode 100644 index 000000000..2cc9412af --- /dev/null +++ b/tex/context/base/core-two.mkiv @@ -0,0 +1,106 @@ +%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\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{\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 + +\def\testtwopassdata{\ifx\twopassdata\empty\twopassdatafoundfalse\else\twopassdatafoundtrue\fi} + +% todo: move the edef to lua + +\unexpanded\def\definetwopasslist #1{\ctxlua{jobpasses.define('#1')}} +\def\gettwopassdata #1{\edef\twopassdata{\ctxlua{jobpasses.get("#1")}}\testtwopassdata} +\def\checktwopassdata #1{\edef\twopassdata{\ctxlua{jobpasses.check("#1")}}\testtwopassdata} +\def\findtwopassdata #1#2{\edef\twopassdata{\ctxlua{jobpasses.find("#1","#2")}}\testtwopassdata} +\def\getfirsttwopassdata #1{\edef\twopassdata{\ctxlua{jobpasses.first("#1")}}\testtwopassdata} +\def\getlasttwopassdata #1{\edef\twopassdata{\ctxlua{jobpasses.last("#1")}}\edef\noftwopassitems{\ctxlua{jobpasses.count("#1")}}\testtwopassdata} +\def\getnamedtwopassdatalist#1#2{\edef#1{\ctxlua{jobpasses.list("#2")}}} +\def\gettwopassdatalist #1{\edef\twopassdatalist{\ctxlua{jobpasses.list("#1")}}} +\def\doifelseintwopassdata #1#2{\ctxlua{jobpasses.doifinlistelse("#1","#2")}} + +\let\getfromtwopassdata\findtwopassdata + +\protect \endinput diff --git a/tex/context/base/core-uti.lua b/tex/context/base/core-uti.lua new file mode 100644 index 000000000..01fd8522b --- /dev/null +++ b/tex/context/base/core-uti.lua @@ -0,0 +1,294 @@ +if not modules then modules = { } end modules ['core-uti'] = { + version = 1.001, + comment = "companion to core-uti.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- todo: keep track of changes here (hm, track access, and only true when +-- accessed and changed) + +--[[ldx-- +

A utility file has always been part of and with +the move to we also moved a lot of multi-pass info +to a table. Instead of loading a based +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 sort, concat, format, match = table.sort, table.concat, string.format, string.match +local next, type, tostring = next, type, tostring +local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes + +if not jobs then jobs = { } end +if not job then jobs['main'] = { } end job = jobs['main'] + +jobs.version = 1.10 + +--[[ldx-- +

Variables are saved using in the previously defined table and passed +onto using the following method. Of course one can also +directly access the variable using a call.

+--ldx]]-- + +local savelist, comment = { }, { } + +function job.comment(str) + comment[#comment+1] = str +end + +job.comment(format("version: %1.2f",jobs.version)) + +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 -- used in experiment +if not jobvariables.checksums.new then jobvariables.checksums.new = md5.HEX("new") end -- used in experiment + +job.register('jobvariables.checksums', jobvariables.checksums) + +local function initializer() + local r = jobvariables.collected.randomseed + if not r then + r = math.random() + math.setrandomseedi(r,"initialize") + else + math.setrandomseedi(r,"previous run") + end + jobvariables.tobesaved.randomseed = r + for cs, value in next, jobvariables.collected do + texsprint(ctxcatcodes,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", + "processors", -- might become key under directives or metadata +-- "references", -- we need to rename of them as only one packs (not structure.lists.references) +} + +local jobpacker = packer.new(packlist,1.01) + +job.pack = true + +job._save_, job._load_ = { }, { } -- registers timing + +function job.save(filename) + statistics.starttiming(job._save_) + local f = io.open(filename,'w') + if f then + for c=1,#comment do + f:write("-- ",comment[c],"\n") + end + f:write("\n") + 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 + statistics.stoptiming(job._save_) +end + +function job.load(filename) + statistics.starttiming(job._load_) + local data = io.loaddata(filename) + if data and data ~= "" then + local version = tonumber(match(data,"^-- version: ([%d%.]+)")) + if version ~= jobs.version then + logs.report("job","version mismatch with jobfile: %s <> %s", version or "?", jobs.version) + else + local data = loadstring(data) + if data then + data() + end + 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 + statistics.stoptiming(job._load_) +end + +-- eventually this will end up in strc-ini + +statistics.register("startup time", function() + return statistics.elapsedseconds(ctx,"including runtime option file processing") +end) + +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) + +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 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 + if pages == 0 then pages = shipped end + 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 new file mode 100644 index 000000000..5b8f66f50 --- /dev/null +++ b/tex/context/base/core-uti.mkii @@ -0,0 +1,349 @@ +%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 + +\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}}} + +\let\initializevariable\gdef + +\appendtoks + \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}% +% %rawcharacter{227}% invalid in xetex, which expects utf +% \rawcharacter{195}\rawcharacter{128}} % valid utf code +% +% \def\thisisbytesequence#1% +% {\ifx\testbytesequence\empty\else +% \defconvertedcommand\testbytesequence\testbytesequence +% \defconvertedargument\ascii{#1}% +% \ifx\testbytesequence\ascii \else +% \writestatus\m!systems{possible problem with 8 bit output}% +% \fi +% \fi +% \global\let\thisisbytesequence\gobbleoneargument} +% +% \ifnum\texengine=\xetexengine +% \let\testbytesequence\empty +% \fi +% +% \appendtoks +% \immediatewriteutilitycommand{\thisisbytesequence{\testbytesequence}}% +% \to \everyopenutilities + +\let\testbytesequence \empty % keep this +\let\thisisbytesequence\gobbleoneargument % keep this + +\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 new file mode 100644 index 000000000..6b2dae2c9 --- /dev/null +++ b/tex/context/base/core-uti.mkiv @@ -0,0 +1,66 @@ +%D \module +%D [ file=core-uti, +%D version=1997.03.31, % 2006.09.19 mkiv +%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 + +\registerctxluafile{core-uti}{1.001} + +\def\savecurrentvalue#1#2% + {\ctxlua{jobvariables.save("\strippedcsname#1","#2")}} + +\appendtoks + \ctxlua{storage.dump()}% will move to lua +\to \everydump + +\appendtoks + \ctxlua{storage.finalize()}% will move to lua +\to \everyfinalizeluacode + +\appendtoks + \ctxlua{nodes.cleanup_reserved()}% will move to lua +\to \everydump + +\appendtoks + \ctxlua { + 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 + +\def\notuccompression{\ctxlua{job.pack=false}} + +% cleaner, for the moment + +% \appendtoks +% \ctxlua { +% os.remove("\jobname.tui") +% os.remove("\jobname.tuo") +% }% +% \to \everystarttext + +%D Some styles might use these use these commands: + +\newif \ifutilitydone +\let \checkutilities \relax +\let \currentutilityfilename \jobname +\def \installprogram {\dosingleempty\doinstallprogram} +\def \doinstallprogram [#1]{\gobbleoneargument} +\def \installedprogram [#1]{} +\let \installplugin \gobblethreearguments + +\protect \endinput diff --git a/tex/context/base/core-var.mkii b/tex/context/base/core-var.mkii new file mode 100644 index 000000000..4de1b8718 --- /dev/null +++ b/tex/context/base/core-var.mkii @@ -0,0 +1,286 @@ +%D \module +%D [ file=core-var, +%D version=1998.02.21, +%D title=\CONTEXT\ Core 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 Core Macros / Variables} + +\unprotect + +%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 A few every's. Some are only used in \MKII\ or \MKIV. + +%D Output routine: + +\newtoks \everybeforeoutput +\newtoks \everyafteroutput + +%D Shipout: + +\newtoks \everyshipout +\newtoks \everybeforeshipout +\newtoks \everyaftershipout +\newtoks \everyfirstshipout +\newtoks \everylastshipout + +%D End of run: + +\newtoks \everybye +\newtoks \everygoodbye +\newtoks \everynotabene + +%D Document + +\newtoks \everysetupdocument +\newtoks \everyendoftextbody + +\newtoks \everystarttext +\newtoks \everystoptext + +%D Purity: + +\newtoks \everyforgetall +\newtoks \everycleanupfeatures + +\def\cleanupfeatures{\the\everycleanupfeatures} +\def\forgetall {\the\everyforgetall} + +%D Page building: + +\newtoks \everybeforepagebody +\newtoks \everyafterpagebody + +\let \everypagebody \everybeforepagebody % backward compatible + +%D Multipass: + +\newtoks \everybeforeutilityread +\newtoks \everyafterutilityread + +%D Floats: + +\newtoks \everyinsidefloat + +%D Sectioning: + +\newtoks \everyheadstart + +%D Par building (experimental, used in xml

..

) + +\newtoks \everybeginofpar +\newtoks \everyendofpar +%newtoks \everyparflush + +\def\bpar{\the\everybeginofpar\ignorespaces} % may interfere with \everypar +\def\epar{\ifhmode\removeunwantedspaces\the\everyendofpar\fi} % test prevents problems with \bpar\epar + +%D Lists: + +\newtoks \everylistentry +\newtoks \everysavesortkeys + +%D Marks: + +\newtoks \everymarking + +%D Fonts: + +\newtoks \everyfont +\newtoks \everyglobalbodyfont +\newtoks \everydefinedfont + +\newevery \everybodyfont \EveryBodyFont +\newevery \everyfontswitch \EveryFontSwitch + +%D Math: + +\newtoks \everybeforedisplayformula +\newtoks \everymathematics + +\prependtoks \the\everymathematics \to \everymath +\prependtoks \the\everymathematics \to \everydisplay + +%D Tables + +\newtoks \everytable + +%D State mess: + +\newtoks \everypushsomestate +\newtoks \everypopsomestate + +\def\pushsomestates{\the\everypushsomestate} +\def\popsomestates {\the\everypopsomestate } + +%D More generic (used to be pushcolor etc) + +\newtoks\everypushproperties +\newtoks\everypopproperties +\newtoks\everypopsplitproperties + +\newtoks\everystarttextproperties +\newtoks\everystoptextproperties + +\def\pushproperties {\the\everypushproperties} +\def\popproperties {\the\everypopproperties} +\def\popsplitproperties {\the\everypopsplitproperties} + +\def\starttextproperties{\the\everystarttextproperties} +\def\stoptextproperties {\the\everystoptextproperties} + +%D This is pretty important (esp since we now ignore shipouts). +%D Actually we should nil all writes, marks, specials. + +\appendtoks \globallet\popproperties \relax \to \everylastshipout +\appendtoks \globallet\popsplitproperties\relax \to \everylastshipout + +%D \macros +%D {defineinputmode,setinputmode} +%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\executeifdefined{every#1inputmode}\emptytoks} + +\defineinputmode [TEX] +\defineinputmode [XML] + +\setinputmode [TEX] + +%D \macros +%D {trialtypesetting} +%D +%D We disable trial typesetting in the output routine, +%D just to be sure. + +\newif\iftrialtypesetting + +\prependtoks \trialtypesettingfalse \to \everybeforepagebody + +%D \macros +%D {ifinpagebody,ifinsidecolumns,ifdoublesided,ifsinglesided} + +\newif \ifinpagebody +\newif \ifinsidecolumns +\newif \ifdoublesided \doublesidedfalse +\newif \ifsinglesided \singlesidedtrue +\newif \ifinsidefloat +\newif \ifdoingblocks +\newif \ifgridsnapping + +%D \macros +%D {ifprocessingXML} +%D +%D We need this one even if no \XML\ is supported. + +\newif\ifprocessingXML % old way + +%D \macros +%D {ifproductionrun} +%D +%D This boolean can be used to bypass certain +%D initializations. + +\ifx\protectionlevel\undefined \newcount\protectionlevel \fi + +\newif\ifproductionrun + +\appendtoks \productionruntrue \to \everydump + +\appendtoks \ifcase\protectionlevel\else\reportunprotection\fi \to \everydump + +%D \macros +%D {everyboxedcontent, ifboxedcontent, +%D startboxedcontent, stopboxedcontent} +%D +%D This one is relatively new and will be used as a more +%D robust test for inner situations. + +\newif \ifboxedcontent +\newtoks\everyboxedcontent + +\appendtoks \boxedcontenttrue \to \everyboxedcontent + +\def\startboxedcontent{\bgroup\the\everyboxedcontent} +\let\stopboxedcontent \egroup + +%D \macros +%D {fastmode,silentmode} +%D +%D These commands are obsolete. + +\let\fastmode \relax +\let\silentmode\relax + +%D \macros +%D {defineselector,setupselector} +%D +%D \starttyping +%D \defineselector[caption][max=2,n=2] +%D +%D \start +%D \setupselector[caption][n=1] +%D \placelist[figure][criterium=all] +%D \stop +%D +%D \starttext +%D \placefigure +%D {\select{caption}{zapf}{\input zapf \relax}} +%D {} +%D \stoptext +%D \stoptyping + +\def\defineselector{\dodoubleargument\dodefineselector} +\def\setupselector {\dodoubleargument\dosetupselector} + +\def\dodefineselector[#1][#2]{\getparameters[\??sx#1][\c!max=2,\c!n=1,#2]} +\def\dosetupselector [#1][#2]{\getparameters[\??sx#1][#2]} + +\unexpanded\def\select#1% + {\filterfromnext + {\executeifdefined{\??sx#1\c!max}1} + {\executeifdefined{\??sx#1\c!n }1}} + +%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 + +%D Add-ons: + +\let\startlayoutcomponent\gobbletwoarguments +\let\stoplayoutcomponent \relax + +%D Concepts: + +\chardef\conceptmode\zerocount + +\def\doifconcepttracing + {\ifnum\conceptmode>\plustwo + \expandafter\firstofoneargument + \else + \expandafter\gobbleoneargument + \fi} + +\protect \endinput diff --git a/tex/context/base/core-var.mkiv b/tex/context/base/core-var.mkiv new file mode 100644 index 000000000..62cc9fc50 --- /dev/null +++ b/tex/context/base/core-var.mkiv @@ -0,0 +1,270 @@ +%D \module +%D [ file=core-var, +%D version=1998.02.21, +%D title=\CONTEXT\ Core 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 Core Macros / Variables} + +\unprotect + +%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 A few every's. Some are only used in \MKII\ or \MKIV. + +%D Output routine: + +\newtoks \everybeforeoutput +\newtoks \everyafteroutput + +%D Shipout: + +\newtoks \everyshipout +\newtoks \everybeforeshipout +\newtoks \everyaftershipout +\newtoks \everyfirstshipout +\newtoks \everylastshipout + +%D End of run: + +\newtoks \everybye +\newtoks \everygoodbye +\newtoks \everynotabene + +%D Document + +\newtoks \everysetupdocument +\newtoks \everyendoftextbody + +\newtoks \everystarttext +\newtoks \everystoptext + +%D Purity: + +\newtoks \everyforgetall +\newtoks \everycleanupfeatures + +\def\cleanupfeatures{\the\everycleanupfeatures} +\def\forgetall {\the\everyforgetall} + +%D Page building: + +\newtoks \everybeforepagebody +\newtoks \everyafterpagebody + +\let \everypagebody \everybeforepagebody % backward compatible + +%D Multipass: + +\newtoks \everybeforeutilityread +\newtoks \everyafterutilityread + +%D Floats: + +\newtoks \everyinsidefloat + +%D Sectioning: + +\newtoks \everyheadstart + +%D Par building (experimental, used in xml

..

) + +\newtoks \everybeginofpar +\newtoks \everyendofpar +%newtoks \everyparflush + +\def\bpar{\the\everybeginofpar\ignorespaces} % may interfere with \everypar +\def\epar{\ifhmode\removeunwantedspaces\the\everyendofpar\fi} % test prevents problems with \bpar\epar + +%D Lists: + +\newtoks \everylistentry +\newtoks \everysavesortkeys + +%D Marks: + +\newtoks \everymarking + +%D Fonts: + +\newtoks \everyfont +\newtoks \everyglobalbodyfont +\newtoks \everydefinedfont + +\newevery \everybodyfont \EveryBodyFont +\newevery \everyfontswitch \EveryFontSwitch + +\newtoks \everysetupbodyfont +\newtoks \everyswitchtobodyfont + +%D Math: + +\newtoks \everybeforedisplayformula +\newtoks \everymathematics + +\prependtoks \the\everymathematics \to \everymath +\prependtoks \the\everymathematics \to \everydisplay + +%D Tables + +\newtoks \everytable + +%D State mess: + +\newtoks \everypushsomestate +\newtoks \everypopsomestate + +\def\pushsomestates{\the\everypushsomestate} +\def\popsomestates {\the\everypopsomestate } + +%D More generic (used to be pushcolor etc) + +\newtoks\everystarttextproperties +\newtoks\everystoptextproperties + +\unexpanded\def\starttextproperties{\the\everystarttextproperties} +\unexpanded\def\stoptextproperties {\the\everystoptextproperties} + +%D \macros +%D {defineinputmode,setinputmode} +%D +%D New. Some work needs to be done. + +% not in mkiv + +\unexpanded\def\defineinputmode[#1]{\@EA\newtoks\csname every#1inputmode\endcsname} +\def\setinputmode [#1]{\the\executeifdefined{every#1inputmode}\emptytoks} + +\defineinputmode [TEX] +\defineinputmode [XML] + +\setinputmode [TEX] + +%D \macros +%D {trialtypesetting} +%D +%D We disable trial typesetting in the output routine, +%D just to be sure. + +\newif\iftrialtypesetting + +\prependtoks \trialtypesettingfalse \to \everybeforepagebody + +%D \macros +%D {ifinpagebody,ifinsidecolumns,ifdoublesided,ifsinglesided} + +\newif \ifinpagebody +\newif \ifinsidecolumns +\newif \ifdoublesided \doublesidedfalse +\newif \ifsinglesided \singlesidedtrue +\newif \ifinsidefloat +\newif \ifdoingblocks +\newif \ifgridsnapping + +%D \macros +%D {ifprocessingXML} +%D +%D We need this one even if no \XML\ is supported. + +\newif\ifprocessingXML % old way + +%D \macros +%D {ifproductionrun} +%D +%D This boolean can be used to bypass certain +%D initializations. + +\newif\ifproductionrun \appendtoks \productionruntrue \to \everydump + +%D \macros +%D {everyboxedcontent, ifboxedcontent, +%D startboxedcontent, stopboxedcontent} +%D +%D This one is relatively new and will be used as a more +%D robust test for inner situations. + +\newif \ifboxedcontent +\newtoks\everyboxedcontent + +\appendtoks \boxedcontenttrue \to \everyboxedcontent + +\unexpanded\def\startboxedcontent{\bgroup\the\everyboxedcontent} +\let\stopboxedcontent \egroup + +%D \macros +%D {fastmode,silentmode} +%D +%D These commands are obsolete. + +\let\fastmode \relax +\let\silentmode\relax + +%D \macros +%D {defineselector,setupselector} +%D +%D \starttyping +%D \defineselector[caption][max=2,n=2] +%D +%D \start +%D \setupselector[caption][n=1] +%D \placelist[figure][criterium=all] +%D \stop +%D +%D \starttext +%D \placefigure +%D {\select{caption}{zapf}{\input zapf \relax}} +%D {} +%D \stoptext +%D \stoptyping + +\unexpanded\def\defineselector{\dodoubleargument\dodefineselector} +\unexpanded\def\setupselector {\dodoubleargument\dosetupselector} + +\def\dodefineselector[#1][#2]{\getparameters[\??sx#1][\c!max=2,\c!n=1,#2]} +\def\dosetupselector [#1][#2]{\getparameters[\??sx#1][#2]} + +\unexpanded\def\select#1% + {\filterfromnext + {\executeifdefined{\??sx#1\c!max}1} + {\executeifdefined{\??sx#1\c!n }1}} + +%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 + +%D Add-ons: + +\let\setlayoutcomponentattribute \gobbletwoarguments +\let\resetlayoutcomponentattribute\relax +\let\layoutcomponentboxattribute \empty + +%D Concepts: + +\chardef\conceptmode\zerocount + +\def\doifconcepttracing + {\ifnum\conceptmode>\plustwo + \expandafter\firstofoneargument + \else + \expandafter\gobbleoneargument + \fi} + +\protect \endinput diff --git a/tex/context/base/data-aux.lua b/tex/context/base/data-aux.lua new file mode 100644 index 000000000..26e1f551c --- /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.mkiv", + 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_locating = false trackers.register("resolvers.locating", function(v) trace_locating = 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_locating 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_locating 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_locating then + logs.report("fileio","checking new script %s", newscript) + end + if oldscript == newscript then + if trace_locating then + logs.report("fileio","old and new script are the same") + end + elseif not find(newscript,scriptpath) then + if trace_locating 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_locating then + logs.report("fileio","invalid new script name") + end + else + local newdata = io.loaddata(newscript) + if newdata then + if trace_locating then + logs.report("fileio","old script content replaced by new content") + end + io.savedata(oldscript,newdata) + break + elseif trace_locating 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..5e4397a54 --- /dev/null +++ b/tex/context/base/data-bin.lua @@ -0,0 +1,27 @@ +if not modules then modules = { } end modules ['data-bin'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + 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 +local unpack = unpack or table.unpack + +function resolvers.findbinfile(filename, filetype) + return resolvers.methodhandler('finders',filename, filetype) +end + +function resolvers.openbinfile(filename) + return resolvers.methodhandler('loaders',filename) +end + +function resolvers.loadbinfile(filename, filetype) + local fname = resolvers.methodhandler('finders',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..fabe0baa1 --- /dev/null +++ b/tex/context/base/data-con.lua @@ -0,0 +1,120 @@ +if not modules then modules = { } end modules ['data-con'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + 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) + +--[[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 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..55b1a8fad --- /dev/null +++ b/tex/context/base/data-crl.lua @@ -0,0 +1,60 @@ +if not modules then modules = { } end modules ['data-crl'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local gsub = string.gsub + +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() .. "/" .. gsub(name,"[^%a%d%.]+","-") +-- cachename = gsub(cachename,"[\\/]", io.fileseparator) + cachename = gsub(cachename,"[\\]", "/") -- 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..89eb2742d --- /dev/null +++ b/tex/context/base/data-ctx.lua @@ -0,0 +1,31 @@ +if not modules then modules = { } end modules ['data-ctx'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + 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") + local sorted = table.sortedkeys(found) + for k=1,#sorted do + local v = sorted[k] + 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..5a0755831 --- /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.mkiv", + 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..b7354e1ae --- /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.mkiv", + 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..82f675486 --- /dev/null +++ b/tex/context/base/data-lst.lua @@ -0,0 +1,63 @@ +if not modules then modules = { } end modules ['data-lst'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + 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 + local sorted = table.sortedkeys(list) + for i=1,#sorted do + local key = sorted[i] + 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 + local sorted = table.sortedkeys(instance.kpsevars) + for i=1,#sorted do + local key = sorted[i] + if not instance.pattern or (instance.pattern=="") or find(key,instance.pattern) then + report(format("%s\n",key)) + local order = instance.order + for i=1,#order do + local str = order[i][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..988133fbe --- /dev/null +++ b/tex/context/base/data-lua.lua @@ -0,0 +1,152 @@ +if not modules then modules = { } end modules ['data-lua'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + 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 2 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, insert = string.gsub, table.insert +local unpack = unpack or table.unpack + +local libformats = { 'luatexlibs', 'tex', 'texmfscripts', 'othertextfiles' } -- 'luainputs' +local clibformats = { 'lib' } + +local _path_, libpaths, _cpath_, clibpaths + +function package.libpaths() + if not _path_ or package.path ~= _path_ then + _path_ = package.path + libpaths = file.split_path(_path_,";") + end + return libpaths +end + +function package.clibpaths() + if not _cpath_ or package.cpath ~= _cpath_ then + _cpath_ = package.cpath + clibpaths = file.split_path(_cpath_,";") + end + return clibpaths +end + +local function thepath(...) + local t = { ... } t[#t+1] = "?.lua" + local path = file.join(unpack(t)) + if trace_locating then + logs.report("fileio","! appending '%s' to 'package.path'",path) + end + return path +end + +local p_libpaths, a_libpaths = { }, { } + +function package.append_libpath(...) + insert(a_libpath,thepath(...)) +end + +function package.prepend_libpath(...) + insert(p_libpaths,1,thepath(...)) +end + +-- beware, we need to return a loadfile result ! + +local function loaded(libpaths,name,simple) + for i=1,#libpaths do -- package.path, might become option + local libpath = libpaths[i] + local resolved = gsub(libpath,"%?",simple) + if trace_locating then -- more detail + logs.report("fileio","! checking for '%s' on 'package.path': '%s' => '%s'",simple,libpath,resolved) + end + if resolvers.isreadable.file(resolved) then + if trace_locating then + logs.report("fileio","! lib '%s' located via 'package.path': '%s'",name,resolved) + end + return loadfile(resolved) + end + end +end + + +package.loaders[2] = function(name) -- was [#package.loaders+1] + if trace_locating then -- mode detail + logs.report("fileio","! locating '%s'",name) + end + for i=1,#libformats do + local format = libformats[i] + local resolved = resolvers.find_file(name,format) or "" + if trace_locating then -- mode detail + logs.report("fileio","! checking for '%s' using 'libformat path': '%s'",name,format) + end + if resolved ~= "" then + if trace_locating then + logs.report("fileio","! lib '%s' located via environment: '%s'",name,resolved) + end + return loadfile(resolved) + end + end + -- libpaths + local libpaths, clibpaths = package.libpaths(), package.clibpaths() + local simple = gsub(name,"%.lua$","") + local simple = gsub(simple,"%.","/") + local resolved = loaded(p_libpaths,name,simple) or loaded(libpaths,name,simple) or loaded(a_libpaths,name,simple) + if resolved then + return resolved + end + -- + local libname = file.addsuffix(simple,os.libsuffix) + for i=1,#clibformats do + -- better have a dedicated loop + local format = clibformats[i] + local paths = resolvers.expanded_path_list_from_var(format) + for p=1,#paths do + local path = paths[p] + local resolved = file.join(path,libname) + if trace_locating then -- mode detail + logs.report("fileio","! checking for '%s' using 'clibformat path': '%s'",libname,path) + end + if resolvers.isreadable.file(resolved) then + if trace_locating then + logs.report("fileio","! lib '%s' located via 'clibformat': '%s'",libname,resolved) + end + return package.loadlib(resolved,name) + end + end + end + for i=1,#clibpaths do -- package.path, might become option + local libpath = clibpaths[i] + local resolved = gsub(libpath,"?",simple) + if trace_locating then -- more detail + logs.report("fileio","! checking for '%s' on 'package.cpath': '%s'",simple,libpath) + end + if resolvers.isreadable.file(resolved) then + if trace_locating then + logs.report("fileio","! lib '%s' located via 'package.cpath': '%s'",name,resolved) + end + return package.loadlib(resolved,name) + end + end + -- just in case the distribution is messed up + if trace_loading then -- more detail + logs.report("fileio","! checking for '%s' using 'luatexlibs': '%s'",name) + end + 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 loadfile(resolved) + 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..f73ff9bdc --- /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.mkiv", + 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..9348f6cd3 --- /dev/null +++ b/tex/context/base/data-pre.lua @@ -0,0 +1,109 @@ +if not modules then modules = { } end modules ['data-res'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + 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.auto = function(str) + local fullname = prefixes.relative(str) + if not lfs.isfile(fullname) then + fullname = prefixes.locate(str) + end + return fullname +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 + +function resolvers.allprefixes(separator) + local all = table.sortedkeys(prefixes) + if separator then + for i=1,#all do + all[i] = all[i] .. ":" + end + end + return all +end + +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=1,#str do + local v = str[k] + 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 next, 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..ecef14188 --- /dev/null +++ b/tex/context/base/data-res.lua @@ -0,0 +1,2181 @@ +if not modules then modules = { } end modules ['data-inp'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", +} + +-- 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] +-- 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 lpegmatch = lpeg.match + +local trace_locating, trace_detail, trace_expansions = false, false, false + +trackers.register("resolvers.locating", function(v) trace_locating = v end) +trackers.register("resolvers.details", function(v) trace_detail = v end) +trackers.register("resolvers.expansions", function(v) trace_expansions = v end) -- todo + +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.type == "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', 'dfont' } +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 maps'] = 'cid' -- great, why no cid files +alternatives['font feature files'] = 'fea' -- and fea files here +alternatives['opentype fonts'] = 'otf' +alternatives['truetype fonts'] = 'ttf' +alternatives['truetype collections'] = 'ttc' +alternatives['truetype dictionary'] = 'dfont' +alternatives['type1 fonts'] = 'pfb' + +-- obscure ones + +formats ['misc fonts'] = '' +suffixes['misc fonts'] = { } + +formats ['sfd'] = 'SFDFONTS' +suffixes ['sfd'] = { 'sfd' } +alternatives['subfont definition files'] = 'sfd' + +-- lib paths + +formats ['lib'] = 'CLUAINPUTS' -- new (needs checking) +suffixes['lib'] = (os.libsuffix and { os.libsuffix }) or { 'dll', 'so' } + +-- 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, iv = instance.environment, instance.variables + local function fix(varname,default) + local proname = varname .. "." .. instance.progname or "crap" + local p, v = ie[proname], ie[varname] or iv[varname] + if not ((p and p ~= "") or (v and v ~= "")) then + iv[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 + -- this will go away some day + fix("FONTFEATURES", ".;$TEXMF/fonts/{data,fea}//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS") + fix("FONTCIDMAPS" , ".;$TEXMF/fonts/{data,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_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 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 + +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 + if trace_expansions then + logs.report("fileio","expanding variable '%s'",str) + end + t = t or { } + str = gsub(str,",}",",@}") + str = gsub(str,"{,","{@,") + -- str = "@" .. str .. "@" + local ok, done + 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 + if trace_expansions then + for k=1,#t do + logs.report("fileio","% 4i: %s",k,t[k]) + 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) + +local args = environment and environment.original_arguments or arg -- this needs a cleanup + +resolvers.ownbin = resolvers.ownbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex" +resolvers.ownbin = gsub(resolvers.ownbin,"\\","/") + +function resolvers.getownpath() + local ownpath = resolvers.ownpath or os.selfdir + if not ownpath or ownpath == "" or ownpath == "unset" then + ownpath = args[-1] or arg[-1] + ownpath = ownpath and file.dirname(gsub(ownpath,"\\","/")) + if not ownpath or ownpath == "" then + ownpath = args[-0] or arg[-0] + ownpath = ownpath and file.dirname(gsub(ownpath,"\\","/")) + end + local binary = resolvers.ownbin + if not ownpath or ownpath == "" then + ownpath = ownpath and file.dirname(binary) + end + if not ownpath or ownpath == "" then + if os.binsuffix ~= "" then + binary = file.replacesuffix(binary,os.binsuffix) + 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_locating and p ~= pp then + logs.report("fileio","following symlink '%s' to '%s'",p,pp) + end + ownpath = pp + lfs.chdir(olddir) + else + if trace_locating then + logs.report("fileio","unable to check path '%s'",p) + end + ownpath = p + end + break + end + end + end + if not ownpath or ownpath == "" then + ownpath = "." + logs.report("fileio","forcing fallback ownpath .") + elseif trace_locating then + logs.report("fileio","using ownpath '%s'",ownpath) + end + end + resolvers.ownpath = ownpath + function resolvers.getownpath() + return resolvers.ownpath + end + return ownpath +end + +local own_places = { "SELFAUTOLOC", "SELFAUTODIR", "SELFAUTOPARENT", "TEXMFCNF" } + +local function identify_own() + local ownpath = resolvers.getownpath() or dir.current() + 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_locating 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') + if lfs.isfile(lname) then + local dname = file.dirname(fname) -- 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_locating then + logs.report("fileio","loading configuration file %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_locating then + logs.report("fileio","skipping configuration file '%s'", fname) + end + end +end + +local function collapse_cnf_data() -- potential optimization: pass start index (setup and configuration are shared) + local order = instance.order + for i=1,#order do + local c = order[i] + 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() + local cnffiles = instance.cnffiles + for i=1,#cnffiles do + load_cnf_file(cnffiles[i]) + end + end + -- instance.cnffiles contain complete names now ! + -- we still use a funny mix of cnf and new but soon + -- we will switch to lua exclusively as we only use + -- the file to collect the tree roots + if #instance.cnffiles == 0 then + if trace_locating then + logs.report("fileio","no cnf files found (TEXMFCNF may not be set/known)") + end + else + local cnffiles = instance.cnffiles + instance.rootpath = cnffiles[1] + for k=1,#cnffiles do + instance.cnffiles[k] = file.collapse_path(cnffiles[k]) + 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] + local luafiles = instance.luafiles + for k=1,#luafiles do + instance.luafiles[k] = file.collapse_path(luafiles[k]) + 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 '%s' appended",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 '%s' prepended",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() + local texmfpaths = resolvers.clean_path_list('TEXMF') + for i=1,#texmfpaths do + local path = texmfpaths[i] + if trace_locating 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 '%s' found",specification) + end + resolvers.append_hash('file',specification,filename) + elseif trace_locating then + logs.report("fileio","tex locator '%s' not found",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 + local hashes = instance.hashes + for k=1,#hashes do + local hash = hashes[k] + 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() + local hashes = instance.hashes + for i=1,#hashes do + resolvers.generatedatabase(hashes[i].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")) + +--~ local l_forbidden = lpeg.S("~`!#$%^&*()={}[]:;\"\'||\\/<>,?\n\r\t") +--~ local l_confusing = lpeg.P(" ") +--~ local l_character = lpeg.patterns.utf8 +--~ local l_dangerous = lpeg.P(".") + +--~ local l_normal = (l_character - l_forbidden - l_confusing - l_dangerous) * (l_character - l_forbidden - l_confusing^2)^0 * lpeg.P(-1) +--~ ----- l_normal = l_normal * lpeg.Cc(true) + lpeg.Cc(false) + +--~ local function test(str) +--~ print(str,lpeg.match(l_normal,str)) +--~ end +--~ test("ヒラギノ明朝 Pro W3") +--~ test("..ヒラギノ明朝 Pro W3") +--~ test(":ヒラギノ明朝 Pro W3;") +--~ test("ヒラギノ明朝 /Pro W3;") +--~ test("ヒラギノ明朝 Pro W3") + +function resolvers.generators.tex(specification) + local tag = specification + if trace_locating 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 lpegmatch(weird,name) then + -- if lpegmatch(l_normal,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_locating 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. + +--~ local checkedsplit = string.checkedsplit + +local cache = { } + +local splitter = lpeg.Ct(lpeg.splitat(lpeg.S(os.type == "windows" and ";" or ":;"))) + +local function split_kpse_path(str) -- beware, this can be either a path or a {specification} + local found = cache[str] + if not found then + if str == "" then + found = { } + else + str = gsub(str,"\\","/") +--~ local split = (find(str,";") and checkedsplit(str,";")) or checkedsplit(str,io.pathseparator) +local split = lpegmatch(splitter,str) + found = { } + for i=1,#split do + local s = split[i] + if not find(s,"^{*unset}*") then + found[#found+1] = s + end + end + if trace_expansions then + logs.report("fileio","splitting path specification '%s'",str) + for k=1,#found do + logs.report("fileio","% 4i: %s",k,found[k]) + end + end + cache[str] = found + end + end + return found +end + +resolvers.split_kpse_path = split_kpse_path + +function resolvers.splitconfig() + for i=1,#instance do + local c = instance[i] + for k,v in next, c do + if type(v) == 'string' then + local t = split_kpse_path(v) + if #t > 1 then + c[k] = t + end + end + end + end +end + +function resolvers.joinconfig() + local order = instance.order + for i=1,#order do + local c = order[i] + for k,v in next, c do -- indexed? + 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 split_kpse_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, p = { }, { }, split_kpse_path(v) + for kk=1,#p do + local vv = p[kk] + 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 + local sortedfiles = sortedkeys(files) + for i=1,#sortedfiles do + local k = sortedfiles[i] + local fk = files[k] + if type(fk) == 'table' then + t[#t+1] = "\t['" .. k .. "']={" + local sortedfk = sortedkeys(fk) + for j=1,#sortedfk do + local kk = sortedfk[j] + 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 + +local data_state = { } + +function resolvers.data_state() + return data_state or { } +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_locating 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, + uuid = os.uuid(), + } + local ok = io.savedata(luaname,resolvers.serialize(data)) + if ok then + if trace_locating 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_locating then + logs.report("fileio","'%s' compiled to '%s'",dataname,lucname) + end + else + if trace_locating then + logs.report("fileio","compiling failed for '%s', deleting file '%s'",dataname,lucname) + end + os.remove(lucname) + end + elseif trace_locating 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 + data_state[#data_state+1] = data.uuid + if trace_locating then + logs.report("fileio","loading '%s' for '%s' from '%s'",dataname,pathname,filename) + end + instance[dataname][pathname] = data.content + else + if trace_locating then + logs.report("fileio","skipping '%s' for '%s' from '%s'",dataname,pathname,filename) + end + instance[dataname][pathname] = { } + instance.loaderror = true + end + elseif trace_locating 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() + local luafiles = instance.luafiles + for i=1,#luafiles do + local cnf = luafiles[i] + 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_locating 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_locating then + logs.report("fileio","skipping configuration file '%s'",filename) + end + instance['setup'][pathname] = { } + instance.loaderror = true + end + elseif trace_locating 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 + local cnffiles = instance.cnffiles + for i=1,#cnffiles do + local cnf = cnffiles[i] + 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 { } -- ep ? + 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(tmp) + else + return resolvers.expanded_path_list(str) + 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","file '%s' is readable",name) + else + logs.report("fileio","file '%s' is not readable", 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","checking name '%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","deep checking '%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","no match in '%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) + -- 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","remembering file '%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","file '%s' found directly",filename) + end + instance.found[stamp] = { filename } + return { filename } + end + end + if find(filename,'%*') then + if trace_locating then + logs.report("fileio","checking 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 name '%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 = gsub(filename .. "$","([%.%-])","%%%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 + -- + if basename ~= filename then + 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 find(rr,pattern) then + result[#result+1], ok = rr, true + end + 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 find(ff,pattern) then + -- result[#result+1], ok = ff, true + -- end + -- end + -- end + end + if not ok and trace_locating then + logs.report("fileio","qualified name '%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","checking filename '%s', filetype '%s', wanted files '%s'",filename, filetype or '?',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 dirlist = { } + if filelist then + for i=1,#filelist do + dirlist[i] = file.dirname(filelist[i][2]) .. "/" + end + end + if trace_detail then + logs.report("fileio","checking filename '%s'",filename) + end + -- a bit messy ... esp the doscan setting here + local doscan + for k=1,#pathlist do + local path = pathlist[k] + if find(path,"^!!") then doscan = false else doscan = true end + local pathname = gsub(path,"^!+", '') + done = false + -- using file list + if filelist then + local expression + -- compare list entries with permitted pattern -- /xx /xx// + if not find(pathname,"/$") then + expression = pathname .. "/" + else + expression = pathname + end + expression = gsub(expression,"([%-%.])","%%%1") -- this also influences + expression = gsub(expression,"//+$", '/.*') -- later usage of pathname + expression = gsub(expression,"//", '/.-/') -- not ok for /// but harmless + expression = "^" .. expression .. "$" + if trace_detail then + logs.report("fileio","using pattern '%s' for path '%s'",expression,pathname) + end + for k=1,#filelist do + local fl = filelist[k] + local f = fl[2] + local d = dirlist[k] + if find(d,expression) then + --- todo, test for readable + result[#result+1] = fl[3] + resolvers.register_in_trees(f) -- for tracing used files + done = true + if instance.allresults then + if trace_detail then + logs.report("fileio","match in hash for file '%s' on path '%s', continue scanning",f,d) + end + else + if trace_detail then + logs.report("fileio","match in hash for file '%s' on path '%s', quit scanning",f,d) + end + break + end + elseif trace_detail then + logs.report("fileio","no match in hash for file '%s' on path '%s'",f,d) + 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 '%s' by scanning",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] or { } + 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() -- will become the new method + resolvers.expand_variables() + resolvers.load_cnf() -- will be skipped when we have a lua file + 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_locating then + logs.report("fileio",str) -- has already verbose + else + print(str) + end + end + if trace_locating then + report('') -- ? + end + for f=1,#files do + local file = files[f] + local result = command(file,filetype,mustexist) + if type(result) == 'string' then + report(result) + else + for i=1,#result do + report(result[i]) -- could be unpack + 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 next, t do -- indexed? + s[#s+1] = k .. "=" .. tostring(v) + end + return concat(s, sep or " | ") +end + +function resolvers.methodhandler(what, filename, filetype) -- ... + filename = file.collapse_path(filename) + 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) + local pathlist = resolvers.expanded_path_list(name) + for i=1,#pathlist do + func("^"..resolvers.clean_path(pathlist[i])) + end +end + +function resolvers.do_with_var(name,func) + func(expanded_var(name)) +end + +function resolvers.with_files(pattern,handle) + local hashes = instance.hashes + for i=1,#hashes do + local hash = hashes[i] + 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 next, v do -- indexed + handle(blobtype,blobpath,vv,k) + end + end + end + end + end + end + end +end + +function resolvers.locate_format(name) + local barename, fmtname = gsub(name,"%.%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-sch.lua b/tex/context/base/data-sch.lua new file mode 100644 index 000000000..e68b6cd01 --- /dev/null +++ b/tex/context/base/data-sch.lua @@ -0,0 +1,142 @@ +if not modules then modules = { } end modules ['data-sch'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local http = require("socket.http") +local ltn12 = require("ltn12") + +local gsub, concat, format = string.gsub, table.concat, string.format + +local trace_schemes = false trackers.register("resolvers.schemes",function(v) trace_schemes = v end) + +schemes = schemes or { } + +schemes.cached = { } +schemes.cachepath = caches.definepath("schemes") +schemes.threshold = 24 * 60 * 60 + +directives.register("schemes.threshold", function(v) schemes.threshold = tonumber(v) or schemes.threshold end) + +local cached, loaded, reused = schemes.cached, { }, { } + +local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders + +function schemes.curl(name,cachename) + local command = "curl --silent --create-dirs --output " .. cachename .. " " .. name -- no protocol .. "://" + os.spawn(command) +end + +function schemes.fetch(protocol,name,handler) + local cachename = schemes.cachepath() .. "/" .. gsub(name,"[^%a%d%.]+","-") + cachename = gsub(cachename,"[\\]", "/") -- cleanup + if not cached[name] then + statistics.starttiming(schemes) + if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification) > schemes.threshold) then + cached[name] = cachename + if handler then + if trace_schemes then + logs.report("schemes","fetching '%s', protocol '%s', method 'built-in'",name,protocol) + end + io.flush() + handler(protocol,name,cachename) + else + if trace_schemes then + logs.report("schemes","fetching '%s', protocol '%s', method 'curl'",name,protocol) + end + io.flush() + schemes.curl(name,cachename) + end + end + if io.exists(cachename) then + cached[name] = cachename + if trace_schemes then + logs.report("schemes","using cached '%s', protocol '%s', cachename '%s'",name,protocol,cachename) + end + else + cached[name] = "" + if trace_schemes then + logs.report("schemes","using missing '%s', protocol '%s'",name,protocol) + end + end + loaded[protocol] = loaded[protocol] + 1 + statistics.stoptiming(schemes) + else + if trace_schemes then + logs.report("schemes","reusing '%s', protocol '%s'",name,protocol) + end + reused[protocol] = reused[protocol] + 1 + end + return cached[name] +end + +function finders.schemes(protocol,filename,handler) + local foundname = schemes.fetch(protocol,filename,handler) + return finders.generic(protocol,foundname,filetype) +end + +function openers.schemes(protocol,filename) + return openers.generic(protocol,filename) +end + +function loaders.schemes(protocol,filename) + return loaders.generic(protocol,filename) +end + +-- could be metatable + +function schemes.install(protocol,handler) + loaded [protocol] = 0 + reused [protocol] = 0 + finders[protocol] = function (filename,filetype) return finders.schemes(protocol,filename,handler) end + openers[protocol] = function (filename) return openers.schemes(protocol,filename) end + loaders[protocol] = function (filename) return loaders.schemes(protocol,filename) end +end + +local function http_handler(protocol,name,cachename) + local tempname = cachename .. ".tmp" + local f = io.open(tempname,"wb") + local status, message = http.request { + url = name, + sink = ltn12.sink.file(f) + } + if not status then + os.remove(tempname) + else + os.remove(cachename) + os.rename(tempname,cachename) + end +end + +schemes.install('http',http_handler) +schemes.install('https') +schemes.install('ftp') + +statistics.register("scheme handling time", function() + local l, r = { }, { } + for k, v in table.sortedhash(loaded) do + if v > 0 then + l[#l+1] = k .. ":" .. v + end + end + for k, v in table.sortedhash(reused) do + if v > 0 then + r[#r+1] = k .. ":" .. v + end + end + local n = #l + #r + if n > 0 then + l = (#l > 0 and concat(l)) or "none" + r = (#r > 0 and concat(r)) or "none" + return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s", + statistics.elapsedtime(schemes), n, schemes.threshold, l, r) + else + return nil + end +end) + +--~ trace_schemes = true +--~ print(schemes.fetch("http","http://www.pragma-ade.com/show-man.pdf",http_handler)) diff --git a/tex/context/base/data-tex.lua b/tex/context/base/data-tex.lua new file mode 100644 index 000000000..c9fa3625a --- /dev/null +++ b/tex/context/base/data-tex.lua @@ -0,0 +1,226 @@ +if not modules then modules = { } end modules ['data-tex'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + 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 unpack = unpack or table.unpack + +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","%s finder: file '%s' found",tag,filename) + end + return foundname + else + if trace_locating then + logs.report("fileio","%s finder: unknown file '%s'",tag,filename) + end + return unpack(finders.notfound) + end +end + +--~ local lpegmatch = lpeg.match +--~ local getlines = lpeg.Ct(lpeg.patterns.textline) + +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","%s opener, file '%s' opened using method '%s'",tag,filename,unicode.utfname[u]) + 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","%s closer, file '%s' closed",tag,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","%s opener, file '%s' opened",tag,filename) + end + -- todo: file;name -> freeze / eerste regel scannen -> freeze + --~ local data = lpegmatch(getlines,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","%s closer, file '%s' closed",tag,filename) + end + logs.show_close(filename) + file_handle:close() + t = nil + collectgarbage("step") -- saves some memory + 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) -- todo + if trace_locating then + logs.report("fileio","%s opener, file '%s' opened",tag,filename) + end + return openers.text_opener(filename,f,tag) + end + end + if trace_locating then + logs.report("fileio","%s opener, file '%s' not found",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","%s loader, file '%s' loaded",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","%s loader, file '%s' not found",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',filename, filetype) +end + +function resolvers.opentexfile(filename) + return resolvers.methodhandler('openers',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..7421eacfc --- /dev/null +++ b/tex/context/base/data-tmf.lua @@ -0,0 +1,75 @@ +if not modules then modules = { } end modules ['data-tmf'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local find, gsub, match = string.find, string.gsub, string.match +local getenv, setenv = os.getenv, os.setenv + +-- loads *.tmf files in minimal tree roots (to be optimized and documented) + +function resolvers.check_environment(tree) + logs.simpleline() + setenv('TMP', getenv('TMP') or getenv('TEMP') or getenv('TMPDIR') or getenv('HOME')) + setenv('TEXOS', getenv('TEXOS') or ("texmf-" .. os.platform)) + setenv('TEXPATH', gsub(tree or "tex","\/+$",'')) + setenv('TEXMFOS', getenv('TEXPATH') .. "/" .. getenv('TEXOS')) + logs.simpleline() + logs.simple("preset : TEXPATH => %s", getenv('TEXPATH')) + logs.simple("preset : TEXOS => %s", getenv('TEXOS')) + logs.simple("preset : TEXMFOS => %s", getenv('TEXMFOS')) + logs.simple("preset : TMP => %s", 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 find(line,"^[%%%#]") then + -- skip comment + else + local key, how, value = match(line,"^(.-)%s*([<=>%?]+)%s*(.*)%s*$") + if how then + value = gsub(value,"%%(.-)%%", function(v) return getenv(v) or "" end) + if how == "=" or how == "<<" then + setenv(key,value) + elseif how == "?" or how == "??" then + setenv(key,getenv(key) or value) + elseif how == "<" or how == "+=" then + if getenv(key) then + setenv(key,getenv(key) .. io.fileseparator .. value) + else + setenv(key,value) + end + elseif how == ">" or how == "=+" then + if getenv(key) then + setenv(key,value .. io.pathseparator .. getenv(key)) + else + 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..25f5b975c --- /dev/null +++ b/tex/context/base/data-tmp.lua @@ -0,0 +1,178 @@ +if not modules then modules = { } end modules ['data-tmp'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + 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) -- not used yet + +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) + local dirs = { ... } + if #dirs > 0 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 + loader = loader() + collectgarbage("step") + 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 + data.cache_uuid = os.uuid() + 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..d5ca258e4 --- /dev/null +++ b/tex/context/base/data-tre.lua @@ -0,0 +1,47 @@ +if not modules then modules = { } end modules ['data-tre'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + 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 find, gsub = string.find, string.gsub +local unpack = unpack or table.unpack + +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 = "/" .. gsub(name,"([%.%-%+])", "%%%1") .. "$" + for k=1,#hash do + local v = hash[k] + if find(v,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..5ecd7805f --- /dev/null +++ b/tex/context/base/data-use.lua @@ -0,0 +1,129 @@ +if not modules then modules = { } end modules ['data-use'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format, lower, gsub, find = string.format, string.lower, string.gsub, string.find + +local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v 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 (not mountpaths or #mountpaths == 0) and usecache then + mountpaths = { caches.setpath("mount") } + end + if mountpaths and #mountpaths > 0 then + statistics.starttiming(resolvers.instance) + for k=1,#mountpaths do + local root = mountpaths[k] + local f = io.open(root.."/url.tmi") + if f then + for line in f:lines() do + if line then + if find(line,"^[%%#%-]") then -- or %W + -- skip + elseif find(line,"^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") + local luvbanner = luv.enginebanner or "?" + if luvbanner ~= enginebanner then + return string.format("engine mismatch (luv:%s <> bin:%s)",luvbanner,enginebanner) + end + local luvhash = luv.sourcehash or "?" + if luvhash ~= sourcehash then + return string.format("source mismatch (luv:%s <> bin:%s)",luvhash,sourcehash) + 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..aa3740a83 --- /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.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format, find, match = string.format, string.find, string.match +local unpack = unpack or table.unpack + +local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) + +-- zip:///oeps.zip?name=bla/bla.tex +-- zip:///oeps.zip?tree=tex/texmf-local +-- zip:///texmf.zip?tree=/tex/texmf +-- zip:///texmf.zip?tree=/tex/texmf-local +-- zip:///texmf-mine.zip?tree=/tex/texmf-projects + +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 + +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 + +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, archive '%s' found",specification.original) + else + logs.report("fileio","zip locator, archive '%s' not found",specification.original) + end + end +end + +function hashers.zip(tag,name) + if trace_locating 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, archive '%s' found",specification.path) + end + local dfile = zfile:open(q.name) + if dfile then + dfile = zfile:close() + if trace_locating then + logs.report("fileio","zip finder, file '%s' found",q.name) + end + return specification.original + elseif trace_locating then + logs.report("fileio","zip finder, file '%s' not found",q.name) + end + elseif trace_locating then + logs.report("fileio","zip finder, unknown archive '%s'",specification.path) + end + end + end + if trace_locating then + logs.report("fileio","zip finder, '%s' not found",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 opener, archive '%s' opened",zipspecification.path) + end + local dfile = zfile:open(q.name) + if dfile then + logs.show_open(specification) + if trace_locating then + logs.report("fileio","zip opener, file '%s' found",q.name) + end + return openers.text_opener(specification,dfile,'zip') + elseif trace_locating then + logs.report("fileio","zip opener, file '%s' not found",q.name) + end + elseif trace_locating then + logs.report("fileio","zip opener, unknown archive '%s'",zipspecification.path) + end + end + end + if trace_locating then + logs.report("fileio","zip opener, '%s' not found",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 loader, archive '%s' opened",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, file '%s' loaded",filename) + end + local s = dfile:read("*all") + dfile:close() + return true, s, #s + elseif trace_locating then + logs.report("fileio","zip loader, file '%s' not found",q.name) + end + elseif trace_locating then + logs.report("fileio","zip loader, unknown archive '%s'",specification.path) + end + end + end + if trace_locating then + logs.report("fileio","zip loader, '%s' not found",filename) + end + return unpack(openers.notfound) +end + +-- zip:///somefile.zip +-- zip:///somefile.zip?tree=texmf-local -> mount + +function resolvers.usezipfile(zipname) + zipname = validzip(zipname) + 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 "" + local z = zip.openarchive(zipfile) + if z then + local instance = resolvers.instance + if trace_locating then + logs.report("fileio","zip registering, registering archive '%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","zip registering, unknown archive '%s'",zipname) + end + elseif trace_locating then + logs.report("fileio","zip registering, '%s' not found",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 registering, using filter '%s'",filter) + end + local register, n = resolvers.register_file, 0 + for i in z:files() do + local path, name = match(i.filename,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 registering, %s files registered",n) + return files +end diff --git a/tex/context/base/enco-032.mkii b/tex/context/base/enco-032.mkii new file mode 100644 index 000000000..d7e15126c --- /dev/null +++ b/tex/context/base/enco-032.mkii @@ -0,0 +1,82 @@ +%D \module +%D [ file=enco-032, +%D version=2006.03.30, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=Unicode Goodies, +%D author={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. + +\unprotect + +% unicode table 32 (= hex 20) + +\startencoding [default] + + \definecommand unic@threeperemspace {\hskip .33333em } + \definecommand unic@fourperemspace {\hskip .25em } + \definecommand unic@sixperemspace {\hskip .16667em } + \definecommand unic@figurespace {\hphantom{0}} + \definecommand unic@punctuationspace {\hphantom{,}} + \definecommand unic@hairspace {\hskip .08333em } + \definecommand unic@zerowidthspace {\hskip 0em plus 1sp } + \definecommand unic@zerowidthjoiner {\kern 0em } + \definecommand unic@zerowidthnonjoiner {\hskip 0em } + + \definecommand unic@quotedblleftreversed {\mirror{\quotedblright}} + \definecommand unic@quoteleftreversed {\mirror{\quoteright}} + + \definecommand unic@onedotleader {{\periods[1]}} + \definecommand unic@twodotleader {{\periods[2]}} + \definecommand unic@hyphenationpoint {.\allowbreak } + + \definecommand unic@doubleexclamationmark {!!} + \definecommand unic@exclamationquestionmark {!?} + \definecommand unic@questionexclamationmark {?!} + \definecommand unic@doublequestionmark {??} + + \definecommand unic@reversedpilcrowsign {\mirror{\P}} + \definecommand unic@reversedsemicolon {\mirror{;}} + + \definecommand unic@superscriptzero {\high{0}} + \definecommand unic@superscripti {\high{i}} + \definecommand unic@superscriptfour {\high{4}} + \definecommand unic@superscriptfive {\high{5}} + \definecommand unic@superscriptsix {\high{6}} + \definecommand unic@superscriptseven {\high{7}} + \definecommand unic@superscripteight {\high{8}} + \definecommand unic@superscriptnine {\high{9}} + \definecommand unic@superscriptplus {\high{+}} + \definecommand unic@superscriptminus {\high{\textminus}} + \definecommand unic@superscriptequals {\high{=}} + \definecommand unic@superscriptleft {\high{(}} + \definecommand unic@superscriptright {\high{)}} + \definecommand unic@superscriptn {\high{n}} + \definecommand unic@subscriptzero {\low{0}} + \definecommand unic@subscriptone {\low{1}} + \definecommand unic@subscripttwo {\low{2}} + \definecommand unic@subscriptthree {\low{3}} + \definecommand unic@subscriptfour {\low{4}} + \definecommand unic@subscriptfive {\low{5}} + \definecommand unic@subscriptsix {\low{6}} + \definecommand unic@subscriptseven {\low{7}} + \definecommand unic@subscripteight {\low{8}} + \definecommand unic@subscriptnine {\low{9}} + \definecommand unic@subscriptplus {\low{+}} + \definecommand unic@subscriptminus {\low{\textminus}} + \definecommand unic@subscriptequals {\low{=}} + \definecommand unic@subscriptleft {\low{(}} + \definecommand unic@subscriptright {\low{)}} + \definecommand unic@subscripta {\low{a}} + \definecommand unic@subscripte {\low{e}} + \definecommand unic@subscripto {\low{o}} + \definecommand unic@subscriptx {\low{x}} + \definecommand unic@subscriptschwa {\low{\schwa}} + +\stopencoding + +\protect \endinput diff --git a/tex/context/base/enco-037.mkii b/tex/context/base/enco-037.mkii new file mode 100644 index 000000000..d9fc653b2 --- /dev/null +++ b/tex/context/base/enco-037.mkii @@ -0,0 +1,276 @@ +%D \module +%D [ file=enco-037, +%D version=2006.02.13, +%D title=\CONTEXT\ \UNICODE\ Macros, +%D subtitle=Encoding for vector 37, +%D author=Luigi Scarso, +%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. + +\startencoding[default] + +\definecharacter UnicodeLightHorizontal {\uchar{37}{000}} %%BOX DRAWINGS LIGHT HORIZONTAL +\definecharacter UnicodeHeavyHorizontal {\uchar{37}{001}} %%BOX DRAWINGS HEAVY HORIZONTAL +\definecharacter UnicodeLightVertical {\uchar{37}{002}} %%BOX DRAWINGS LIGHT VERTICAL +\definecharacter UnicodeHeavyVertical {\uchar{37}{003}} %%BOX DRAWINGS HEAVY VERTICAL +\definecharacter UnicodeLightTripleDashHorizontal {\uchar{37}{004}} %%BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL +\definecharacter UnicodeHeavyTripleDashHorizontal {\uchar{37}{005}} %%BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL +\definecharacter UnicodeLightTripleDashVertical {\uchar{37}{006}} %%BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL +\definecharacter UnicodeHeavyTripleDashVertical {\uchar{37}{007}} %%BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL +\definecharacter UnicodeLightQuadrupleDashHorizontal {\uchar{37}{008}} %%BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL +\definecharacter UnicodeHeavyQuadrupleDashHorizontal {\uchar{37}{009}} %%BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL +\definecharacter UnicodeLightQuadrupleDashVertical {\uchar{37}{010}} %%BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL +\definecharacter UnicodeHeavyQuadrupleDashVertical {\uchar{37}{011}} %%BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL +\definecharacter UnicodeLightDownAndRight {\uchar{37}{012}} %%BOX DRAWINGS LIGHT DOWN AND RIGHT +\definecharacter UnicodeDownLightAndRightHeavy {\uchar{37}{013}} %%BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY +\definecharacter UnicodeDownHeavyAndRightLight {\uchar{37}{014}} %%BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT +\definecharacter UnicodeHeavyDownAndRight {\uchar{37}{015}} %%BOX DRAWINGS HEAVY DOWN AND RIGHT +\definecharacter UnicodeLightDownAndLeft {\uchar{37}{016}} %%BOX DRAWINGS LIGHT DOWN AND LEFT +\definecharacter UnicodeDownLightAndLeftHeavy {\uchar{37}{017}} %%BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY +\definecharacter UnicodeDownHeavyAndLeftLight {\uchar{37}{018}} %%BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT +\definecharacter UnicodeHeavyDownAndLeft {\uchar{37}{019}} %%BOX DRAWINGS HEAVY DOWN AND LEFT +\definecharacter UnicodeLightUpAndRight {\uchar{37}{020}} %%BOX DRAWINGS LIGHT UP AND RIGHT +\definecharacter UnicodeUpLightAndRightHeavy {\uchar{37}{021}} %%BOX DRAWINGS UP LIGHT AND RIGHT HEAVY +\definecharacter UnicodeUpHeavyAndRightLight {\uchar{37}{022}} %%BOX DRAWINGS UP HEAVY AND RIGHT LIGHT +\definecharacter UnicodeHeavyUpAndRight {\uchar{37}{023}} %%BOX DRAWINGS HEAVY UP AND RIGHT +\definecharacter UnicodeLightUpAndLeft {\uchar{37}{024}} %%BOX DRAWINGS LIGHT UP AND LEFT +\definecharacter UnicodeUpLightAndLeftHeavy {\uchar{37}{025}} %%BOX DRAWINGS UP LIGHT AND LEFT HEAVY +\definecharacter UnicodeUpHeavyAndLeftLight {\uchar{37}{026}} %%BOX DRAWINGS UP HEAVY AND LEFT LIGHT +\definecharacter UnicodeHeavyUpAndLeft {\uchar{37}{027}} %%BOX DRAWINGS HEAVY UP AND LEFT +\definecharacter UnicodeLightVerticalAndRight {\uchar{37}{028}} %%BOX DRAWINGS LIGHT VERTICAL AND RIGHT +\definecharacter UnicodeVerticalLightAndRightHeavy {\uchar{37}{029}} %%BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY +\definecharacter UnicodeUpHeavyAndRightDownLight {\uchar{37}{030}} %%BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT +\definecharacter UnicodeDownHeavyAndRightUpLight {\uchar{37}{031}} %%BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT +\definecharacter UnicodeVerticalHeavyAndRightLight {\uchar{37}{032}} %%BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT +\definecharacter UnicodeDownLightAndRightUpHeavy {\uchar{37}{033}} %%BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY +\definecharacter UnicodeUpLightAndRightDownHeavy {\uchar{37}{034}} %%BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY +\definecharacter UnicodeHeavyVerticalAndRight {\uchar{37}{035}} %%BOX DRAWINGS HEAVY VERTICAL AND RIGHT +\definecharacter UnicodeLightVerticalAndLeft {\uchar{37}{036}} %%BOX DRAWINGS LIGHT VERTICAL AND LEFT +\definecharacter UnicodeVerticalLightAndLeftHeavy {\uchar{37}{037}} %%BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY +\definecharacter UnicodeUpHeavyAndLeftDownLight {\uchar{37}{038}} %%BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT +\definecharacter UnicodeDownHeavyAndLeftUpLight {\uchar{37}{039}} %%BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT +\definecharacter UnicodeVerticalHeavyAndLeftLight {\uchar{37}{040}} %%BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT +\definecharacter UnicodeDownLightAndLeftUpHeavy {\uchar{37}{041}} %%BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY +\definecharacter UnicodeUpLightAndLeftDownHeavy {\uchar{37}{042}} %%BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY +\definecharacter UnicodeHeavyVerticalAndLeft {\uchar{37}{043}} %%BOX DRAWINGS HEAVY VERTICAL AND LEFT +\definecharacter UnicodeLightDownAndHorizontal {\uchar{37}{044}} %%BOX DRAWINGS LIGHT DOWN AND HORIZONTAL +\definecharacter UnicodeLeftHeavyAndRightDownLight {\uchar{37}{045}} %%BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT +\definecharacter UnicodeRightHeavyAndLeftDownLight {\uchar{37}{046}} %%BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT +\definecharacter UnicodeDownLightAndHorizontalHeavy {\uchar{37}{047}} %%BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY +\definecharacter UnicodeDownHeavyAndHorizontalLight {\uchar{37}{048}} %%BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT +\definecharacter UnicodeRightLightAndLeftDownHeavy {\uchar{37}{049}} %%BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY +\definecharacter UnicodeLeftLightAndRightDownHeavy {\uchar{37}{050}} %%BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY +\definecharacter UnicodeHeavyDownAndHorizontal {\uchar{37}{051}} %%BOX DRAWINGS HEAVY DOWN AND HORIZONTAL +\definecharacter UnicodeLightUpAndHorizontal {\uchar{37}{052}} %%BOX DRAWINGS LIGHT UP AND HORIZONTAL +\definecharacter UnicodeLeftHeavyAndRightUpLight {\uchar{37}{053}} %%BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT +\definecharacter UnicodeRightHeavyAndLeftUpLight {\uchar{37}{054}} %%BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT +\definecharacter UnicodeUpLightAndHorizontalHeavy {\uchar{37}{055}} %%BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY +\definecharacter UnicodeUpHeavyAndHorizontalLight {\uchar{37}{056}} %%BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT +\definecharacter UnicodeRightLightAndLeftUpHeavy {\uchar{37}{057}} %%BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY +\definecharacter UnicodeLeftLightAndRightUpHeavy {\uchar{37}{058}} %%BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY +\definecharacter UnicodeHeavyUpAndHorizontal {\uchar{37}{059}} %%BOX DRAWINGS HEAVY UP AND HORIZONTAL +\definecharacter UnicodeLightVerticalAndHorizontal {\uchar{37}{060}} %%BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL +\definecharacter UnicodeLeftHeavyAndRightVerticalLight {\uchar{37}{061}} %%BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT +\definecharacter UnicodeRightHeavyAndLeftVerticalLight {\uchar{37}{062}} %%BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT +\definecharacter UnicodeVerticalLightAndHorizontalHeavy {\uchar{37}{063}} %%BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY +\definecharacter UnicodeUpHeavyAndDownHorizontalLight {\uchar{37}{064}} %%BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT +\definecharacter UnicodeDownHeavyAndUpHorizontalLight {\uchar{37}{065}} %%BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT +\definecharacter UnicodeVerticalHeavyAndHorizontalLight {\uchar{37}{066}} %%BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT +\definecharacter UnicodeLeftUpHeavyAndRightDownLight {\uchar{37}{067}} %%BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT +\definecharacter UnicodeRightUpHeavyAndLeftDownLight {\uchar{37}{068}} %%BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT +\definecharacter UnicodeLeftDownHeavyAndRightUpLight {\uchar{37}{069}} %%BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT +\definecharacter UnicodeRightDownHeavyAndLeftUpLight {\uchar{37}{070}} %%BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT +\definecharacter UnicodeDownLightAndUpHorizontalHeavy {\uchar{37}{071}} %%BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY +\definecharacter UnicodeUpLightAndDownHorizontalHeavy {\uchar{37}{072}} %%BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY +\definecharacter UnicodeRightLightAndLeftVerticalHeavy {\uchar{37}{073}} %%BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY +\definecharacter UnicodeLeftLightAndRightVerticalHeavy {\uchar{37}{074}} %%BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY +\definecharacter UnicodeHeavyVerticalAndHorizontal {\uchar{37}{075}} %%BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL +\definecharacter UnicodeLightDoubleDashHorizontal {\uchar{37}{076}} %%BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL +\definecharacter UnicodeHeavyDoubleDashHorizontal {\uchar{37}{077}} %%BOX DRAWINGS HEAVY DOUBLE DASH HORIZONTAL +\definecharacter UnicodeLightDoubleDashVertical {\uchar{37}{078}} %%BOX DRAWINGS LIGHT DOUBLE DASH VERTICAL +\definecharacter UnicodeHeavyDoubleDashVertical {\uchar{37}{079}} %%BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL +\definecharacter UnicodeDoubleHorizontal {\uchar{37}{080}} %%BOX DRAWINGS DOUBLE HORIZONTAL +\definecharacter UnicodeDoubleVertical {\uchar{37}{081}} %%BOX DRAWINGS DOUBLE VERTICAL +\definecharacter UnicodeDownSingleAndRightDouble {\uchar{37}{082}} %%BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE +\definecharacter UnicodeDownDoubleAndRightSingle {\uchar{37}{083}} %%BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE +\definecharacter UnicodeDoubleDownAndRight {\uchar{37}{084}} %%BOX DRAWINGS DOUBLE DOWN AND RIGHT +\definecharacter UnicodeDownSingleAndLeftDouble {\uchar{37}{085}} %%BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE +\definecharacter UnicodeDownDoubleAndLeftSingle {\uchar{37}{086}} %%BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE +\definecharacter UnicodeDoubleDownAndLeft {\uchar{37}{087}} %%BOX DRAWINGS DOUBLE DOWN AND LEFT +\definecharacter UnicodeUpSingleAndRightDouble {\uchar{37}{088}} %%BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE +\definecharacter UnicodeUpDoubleAndRightSingle {\uchar{37}{089}} %%BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE +\definecharacter UnicodeDoubleUpAndRight {\uchar{37}{090}} %%BOX DRAWINGS DOUBLE UP AND RIGHT +\definecharacter UnicodeUpSingleAndLeftDouble {\uchar{37}{091}} %%BOX DRAWINGS UP SINGLE AND LEFT DOUBLE +\definecharacter UnicodeUpDoubleAndLeftSingle {\uchar{37}{092}} %%BOX DRAWINGS UP DOUBLE AND LEFT SINGLE +\definecharacter UnicodeDoubleUpAndLeft {\uchar{37}{093}} %%BOX DRAWINGS DOUBLE UP AND LEFT +\definecharacter UnicodeVerticalSingleAndRightDouble {\uchar{37}{094}} %%BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE +\definecharacter UnicodeVerticalDoubleAndRightSingle {\uchar{37}{095}} %%BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE +\definecharacter UnicodeDoubleVerticalAndRight {\uchar{37}{096}} %%BOX DRAWINGS DOUBLE VERTICAL AND RIGHT +\definecharacter UnicodeVerticalSingleAndLeftDouble {\uchar{37}{097}} %%BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE +\definecharacter UnicodeVerticalDoubleAndLeftSingle {\uchar{37}{098}} %%BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE +\definecharacter UnicodeDoubleVerticalAndLeft {\uchar{37}{099}} %%BOX DRAWINGS DOUBLE VERTICAL AND LEFT +\definecharacter UnicodeDownSingleAndHorizontalDouble {\uchar{37}{100}} %%BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE +\definecharacter UnicodeDownDoubleAndHorizontalSingle {\uchar{37}{101}} %%BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE +\definecharacter UnicodeDoubleDownAndHorizontal {\uchar{37}{102}} %%BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL +\definecharacter UnicodeUpSingleAndHorizontalDouble {\uchar{37}{103}} %%BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE +\definecharacter UnicodeUpDoubleAndHorizontalSingle {\uchar{37}{104}} %%BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE +\definecharacter UnicodeDoubleUpAndHorizontal {\uchar{37}{105}} %%BOX DRAWINGS DOUBLE UP AND HORIZONTAL +\definecharacter UnicodeVerticalSingleAndHorizontalDouble {\uchar{37}{106}} %%BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE +\definecharacter UnicodeVerticalDoubleAndHorizontalSingle {\uchar{37}{107}} %%BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE +\definecharacter UnicodeDoubleVerticalAndHorizontal {\uchar{37}{108}} %%BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL +\definecharacter UnicodeLightArcDownAndRight {\uchar{37}{109}} %%BOX DRAWINGS LIGHT ARC DOWN AND RIGHT +\definecharacter UnicodeLightArcDownAndLeft {\uchar{37}{110}} %%BOX DRAWINGS LIGHT ARC DOWN AND LEFT +\definecharacter UnicodeLightArcUpAndLeft {\uchar{37}{111}} %%BOX DRAWINGS LIGHT ARC UP AND LEFT +\definecharacter UnicodeLightArcUpAndRight {\uchar{37}{112}} %%BOX DRAWINGS LIGHT ARC UP AND RIGHT +\definecharacter UnicodeLightDiagonalUpperRightToLowerLeft {\uchar{37}{113}} %%BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT +\definecharacter UnicodeLightDiagonalUpperLeftToLowerRight {\uchar{37}{114}} %%BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT +\definecharacter UnicodeLightDiagonalCross {\uchar{37}{115}} %%BOX DRAWINGS LIGHT DIAGONAL CROSS +\definecharacter UnicodeLightLeft {\uchar{37}{116}} %%BOX DRAWINGS LIGHT LEFT +\definecharacter UnicodeLightUp {\uchar{37}{117}} %%BOX DRAWINGS LIGHT UP +\definecharacter UnicodeLightRight {\uchar{37}{118}} %%BOX DRAWINGS LIGHT RIGHT +\definecharacter UnicodeLightDown {\uchar{37}{119}} %%BOX DRAWINGS LIGHT DOWN +\definecharacter UnicodeHeavyLeft {\uchar{37}{120}} %%BOX DRAWINGS HEAVY LEFT +\definecharacter UnicodeHeavyUp {\uchar{37}{121}} %%BOX DRAWINGS HEAVY UP +\definecharacter UnicodeHeavyRight {\uchar{37}{122}} %%BOX DRAWINGS HEAVY RIGHT +\definecharacter UnicodeHeavyDown {\uchar{37}{123}} %%BOX DRAWINGS HEAVY DOWN +\definecharacter UnicodeLightLeftAndHeavyRight {\uchar{37}{124}} %%BOX DRAWINGS LIGHT LEFT AND HEAVY RIGHT +\definecharacter UnicodeLightUpAndHeavyDown {\uchar{37}{125}} %%BOX DRAWINGS LIGHT UP AND HEAVY DOWN +\definecharacter UnicodeHeavyLeftAndLightRight {\uchar{37}{126}} %%BOX DRAWINGS HEAVY LEFT AND LIGHT RIGHT +\definecharacter UnicodeHeavyUpAndLightDown {\uchar{37}{127}} %%BOX DRAWINGS HEAVY UP AND LIGHT DOWN +\definecharacter UnicodeUpperHalfBlock {\uchar{37}{128}} %%UPPER HALF BLOCK +\definecharacter UnicodeLowerOneEighthBlock {\uchar{37}{129}} %%LOWER ONE EIGHTH BLOCK +\definecharacter UnicodeLowerOneQuarterBlock {\uchar{37}{130}} %%LOWER ONE QUARTER BLOCK +\definecharacter UnicodeLowerThreeEighthsBlock {\uchar{37}{131}} %%LOWER THREE EIGHTHS BLOCK +\definecharacter UnicodeLowerHalfBlock {\uchar{37}{132}} %%LOWER HALF BLOCK +\definecharacter UnicodeLowerFiveEighthsBlock {\uchar{37}{133}} %%LOWER FIVE EIGHTHS BLOCK +\definecharacter UnicodeLowerThreeQuartersBlock {\uchar{37}{134}} %%LOWER THREE QUARTERS BLOCK +\definecharacter UnicodeLowerSevenEighthsBlock {\uchar{37}{135}} %%LOWER SEVEN EIGHTHS BLOCK +\definecharacter UnicodeFullBlock {\uchar{37}{136}} %%FULL BLOCK +\definecharacter UnicodeLeftSevenEighthsBlock {\uchar{37}{137}} %%LEFT SEVEN EIGHTHS BLOCK +\definecharacter UnicodeLeftThreeQuartersBlock {\uchar{37}{138}} %%LEFT THREE QUARTERS BLOCK +\definecharacter UnicodeLeftFiveEighthsBlock {\uchar{37}{139}} %%LEFT FIVE EIGHTHS BLOCK +\definecharacter UnicodeLeftHalfBlock {\uchar{37}{140}} %%LEFT HALF BLOCK +\definecharacter UnicodeLeftThreeEighthsBlock {\uchar{37}{141}} %%LEFT THREE EIGHTHS BLOCK +\definecharacter UnicodeLeftOneQuarterBlock {\uchar{37}{142}} %%LEFT ONE QUARTER BLOCK +\definecharacter UnicodeLeftOneEighthBlock {\uchar{37}{143}} %%LEFT ONE EIGHTH BLOCK +\definecharacter UnicodeRightHalfBlock {\uchar{37}{144}} %%RIGHT HALF BLOCK +\definecharacter UnicodeLightShade {\uchar{37}{145}} %%LIGHT SHADE +\definecharacter UnicodeMediumShade {\uchar{37}{146}} %%MEDIUM SHADE +\definecharacter UnicodeDarkShade {\uchar{37}{147}} %%DARK SHADE +\definecharacter UnicodeUpperOneEighthBlock {\uchar{37}{148}} %%UPPER ONE EIGHTH BLOCK +\definecharacter UnicodeRightOneEighthBlock {\uchar{37}{149}} %%RIGHT ONE EIGHTH BLOCK +\definecharacter UnicodeQuadrantLowerLeft {\uchar{37}{150}} %%[Unassigned U+2596] +\definecharacter UnicodeQuadrantLowerRight {\uchar{37}{151}} %%[Unassigned U+2597] +\definecharacter UnicodeQuadrantUpperLeft {\uchar{37}{152}} %%[Unassigned U+2598] +\definecharacter UnicodeQuadrantUpperLeftAndLowerLeftAndLowerRight {\uchar{37}{153}} %%[Unassigned U+2599] +\definecharacter UnicodeQuadrantUpperLeftAndLowerRight {\uchar{37}{154}} %%[Unassigned U+259A] +\definecharacter UnicodeQuadrantUpperLeftAndUpperRightandLowerLeft {\uchar{37}{155}} %%[Unassigned U+259B] +\definecharacter UnicodeQuadrantUpperLeftAndUpperRightAndLowerRight {\uchar{37}{156}} %%[Unassigned U+259C] +\definecharacter UnicodeQuadrantUpperRight {\uchar{37}{157}} %%[Unassigned U+259D] +\definecharacter UnicodeQuadrantUpperRightAndLowerLeft {\uchar{37}{158}} %%[Unassigned U+259E] +\definecharacter UnicodeQuadrantUpperRightAndLowerLeftAndLowerRight {\uchar{37}{159}} %%[Unassigned U+259F] +\definecharacter UnicodeBlackSquare {\uchar{37}{160}} %%BLACK SQUARE +\definecharacter UnicodeWhiteSquare {\uchar{37}{161}} %%WHITE SQUARE +\definecharacter UnicodeWhiteSquareWithRoundedCorners {\uchar{37}{162}} %%WHITE SQUARE WITH ROUNDED CORNERS +\definecharacter UnicodeWhiteSquareContainingBlackSmallSquare {\uchar{37}{163}} %%WHITE SQUARE CONTAINING BLACK SMALL SQUARE +\definecharacter UnicodeSquareWithHorizontalFill {\uchar{37}{164}} %%SQUARE WITH HORIZONTAL FILL +\definecharacter UnicodeSquareWithVerticalFill {\uchar{37}{165}} %%SQUARE WITH VERTICAL FILL +\definecharacter UnicodeSquareWithOrthogonalCrosshatchFill {\uchar{37}{166}} %%SQUARE WITH ORTHOGONAL CROSSHATCH FILL +\definecharacter UnicodeSquareWithUpperLeftToLowerRightFill {\uchar{37}{167}} %%SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL +\definecharacter UnicodeSquareWithUpperRightToLowerLeftFill {\uchar{37}{168}} %%SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL +\definecharacter UnicodeSquareWithDiagonalCrosshatchFill {\uchar{37}{169}} %%SQUARE WITH DIAGONAL CROSSHATCH FILL +\definecharacter UnicodeBlackSmallSquare {\uchar{37}{170}} %%BLACK SMALL SQUARE +\definecharacter UnicodeWhiteSmallSquare {\uchar{37}{171}} %%WHITE SMALL SQUARE +\definecharacter UnicodeBlackRectangle {\uchar{37}{172}} %%BLACK RECTANGLE +\definecharacter UnicodeWhiteRectangle {\uchar{37}{173}} %%WHITE RECTANGLE +\definecharacter UnicodeBlackVerticalRectangle {\uchar{37}{174}} %%BLACK VERTICAL RECTANGLE +\definecharacter UnicodeWhiteVerticalRectangle {\uchar{37}{175}} %%WHITE VERTICAL RECTANGLE +\definecharacter UnicodeBlackParallelogram {\uchar{37}{176}} %%BLACK PARALLELOGRAM +\definecharacter UnicodeWhiteParallelogram {\uchar{37}{177}} %%WHITE PARALLELOGRAM +\definecharacter UnicodeBlackUpPointingTriangle {\uchar{37}{178}} %%BLACK UP-POINTING TRIANGLE +\definecharacter UnicodeWhiteUpPointingTriangle {\uchar{37}{179}} %%WHITE UP-POINTING TRIANGLE +\definecharacter UnicodeBlackUpPointingSmallTriangle {\uchar{37}{180}} %%BLACK UP-POINTING SMALL TRIANGLE +\definecharacter UnicodeWhiteUpPointingSmallTriangle {\uchar{37}{181}} %%WHITE UP-POINTING SMALL TRIANGLE +\definecharacter UnicodeBlackRightPointingTriangle {\uchar{37}{182}} %%BLACK RIGHT-POINTING TRIANGLE +\definecharacter UnicodeWhiteRightPointingTriangle {\uchar{37}{183}} %%WHITE RIGHT-POINTING TRIANGLE +\definecharacter UnicodeBlackRightPointingSmallTriangle {\uchar{37}{184}} %%BLACK RIGHT-POINTING SMALL TRIANGLE +\definecharacter UnicodeWhiteRightPointingSmallTriangle {\uchar{37}{185}} %%WHITE RIGHT-POINTING SMALL TRIANGLE +\definecharacter UnicodeBlackRightPointingPointer {\uchar{37}{186}} %%BLACK RIGHT-POINTING POINTER +\definecharacter UnicodeWhiteRightPointingPointer {\uchar{37}{187}} %%WHITE RIGHT-POINTING POINTER +\definecharacter UnicodeBlackDownPointingTriangle {\uchar{37}{188}} %%BLACK DOWN-POINTING TRIANGLE +\definecharacter UnicodeWhiteDownPointingTriangle {\uchar{37}{189}} %%WHITE DOWN-POINTING TRIANGLE +\definecharacter UnicodeBlackDownPointingSmallTriangle {\uchar{37}{190}} %%BLACK DOWN-POINTING SMALL TRIANGLE +\definecharacter UnicodeWhiteDownPointingSmallTriangle {\uchar{37}{191}} %%WHITE DOWN-POINTING SMALL TRIANGLE +\definecharacter UnicodeBlackLeftPointingTriangle {\uchar{37}{192}} %%BLACK LEFT-POINTING TRIANGLE +\definecharacter UnicodeWhiteLeftPointingTriangle {\uchar{37}{193}} %%WHITE LEFT-POINTING TRIANGLE +\definecharacter UnicodeBlackLeftPointingSmallTriangle {\uchar{37}{194}} %%BLACK LEFT-POINTING SMALL TRIANGLE +\definecharacter UnicodeWhiteLeftPointingSmallTriangle {\uchar{37}{195}} %%WHITE LEFT-POINTING SMALL TRIANGLE +\definecharacter UnicodeBlackLeftPointingPointer {\uchar{37}{196}} %%BLACK LEFT-POINTING POINTER +\definecharacter UnicodeWhiteLeftPointingPointer {\uchar{37}{197}} %%WHITE LEFT-POINTING POINTER +\definecharacter UnicodeBlackDiamond {\uchar{37}{198}} %%BLACK DIAMOND +\definecharacter UnicodeWhiteDiamond {\uchar{37}{199}} %%WHITE DIAMOND +\definecharacter UnicodeWhiteDiamondContainingBlackSmallDiamond {\uchar{37}{200}} %%WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND +\definecharacter UnicodeFisheye {\uchar{37}{201}} %%FISHEYE +\definecharacter UnicodeLozenge {\uchar{37}{202}} %%LOZENGE +\definecharacter UnicodeWhiteCircle {\uchar{37}{203}} %%WHITE CIRCLE +\definecharacter UnicodeDottedCircle {\uchar{37}{204}} %%DOTTED CIRCLE +\definecharacter UnicodeCircleWithVerticalFill {\uchar{37}{205}} %%CIRCLE WITH VERTICAL FILL +\definecharacter UnicodeBullseye {\uchar{37}{206}} %%BULLSEYE +\definecharacter UnicodeBlackCircle {\uchar{37}{207}} %%BLACK CIRCLE +\definecharacter UnicodeCircleWithLeftHalfBlack {\uchar{37}{208}} %%CIRCLE WITH LEFT HALF BLACK +\definecharacter UnicodeCircleWithRightHalfBlack {\uchar{37}{209}} %%CIRCLE WITH RIGHT HALF BLACK +\definecharacter UnicodeCircleWithLowerHalfBlack {\uchar{37}{210}} %%CIRCLE WITH LOWER HALF BLACK +\definecharacter UnicodeCircleWithUpperHalfBlack {\uchar{37}{211}} %%CIRCLE WITH UPPER HALF BLACK +\definecharacter UnicodeCircleWithUpperRightQuadrantBlack {\uchar{37}{212}} %%CIRCLE WITH UPPER RIGHT QUADRANT BLACK +\definecharacter UnicodeCircleWithAllButUpperLeftQuadrantBlack {\uchar{37}{213}} %%CIRCLE WITH ALL BUT UPPER LEFT QUADRANT BLACK +\definecharacter UnicodeLeftHalfBlackCircle {\uchar{37}{214}} %%LEFT HALF BLACK CIRCLE +\definecharacter UnicodeRightHalfBlackCircle {\uchar{37}{215}} %%RIGHT HALF BLACK CIRCLE +\definecharacter UnicodeInverseBullet {\uchar{37}{216}} %%INVERSE BULLET +\definecharacter UnicodeInverseWhiteCircle {\uchar{37}{217}} %%INVERSE WHITE CIRCLE +\definecharacter UnicodeUpperHalfInverseWhiteCircle {\uchar{37}{218}} %%UPPER HALF INVERSE WHITE CIRCLE +\definecharacter UnicodeLowerHalfInverseWhiteCircle {\uchar{37}{219}} %%LOWER HALF INVERSE WHITE CIRCLE +\definecharacter UnicodeUpperLeftQuadrantCircularArc {\uchar{37}{220}} %%UPPER LEFT QUADRANT CIRCULAR ARC +\definecharacter UnicodeUpperRightQuadrantCircularArc {\uchar{37}{221}} %%UPPER RIGHT QUADRANT CIRCULAR ARC +\definecharacter UnicodeLowerRightQuadrantCircularArc {\uchar{37}{222}} %%LOWER RIGHT QUADRANT CIRCULAR ARC +\definecharacter UnicodeLowerLeftQuadrantCircularArc {\uchar{37}{223}} %%LOWER LEFT QUADRANT CIRCULAR ARC +\definecharacter UnicodeUpperHalfCircle {\uchar{37}{224}} %%UPPER HALF CIRCLE +\definecharacter UnicodeLowerHalfCircle {\uchar{37}{225}} %%LOWER HALF CIRCLE +\definecharacter UnicodeBlackLowerRightTriangle {\uchar{37}{226}} %%BLACK LOWER RIGHT TRIANGLE +\definecharacter UnicodeBlackLowerLeftTriangle {\uchar{37}{227}} %%BLACK LOWER LEFT TRIANGLE +\definecharacter UnicodeBlackUpperLeftTriangle {\uchar{37}{228}} %%BLACK UPPER LEFT TRIANGLE +\definecharacter UnicodeBlackUpperRightTriangle {\uchar{37}{229}} %%BLACK UPPER RIGHT TRIANGLE +\definecharacter UnicodeWhiteBullet {\uchar{37}{230}} %%WHITE BULLET +\definecharacter UnicodeSquareWithLeftHalfBlack {\uchar{37}{231}} %%SQUARE WITH LEFT HALF BLACK +\definecharacter UnicodeSquareWithRightHalfBlack {\uchar{37}{232}} %%SQUARE WITH RIGHT HALF BLACK +\definecharacter UnicodeSquareWithUpperLeftDiagonalHalfBlack {\uchar{37}{233}} %%SQUARE WITH UPPER LEFT DIAGONAL HALF BLACK +\definecharacter UnicodeSquareWithLowerRightDiagonalHalfBlack {\uchar{37}{234}} %%SQUARE WITH LOWER RIGHT DIAGONAL HALF BLACK +\definecharacter UnicodeWhiteSquareWithVerticalBisectingLine {\uchar{37}{235}} %%WHITE SQUARE WITH VERTICAL BISECTING LINE +\definecharacter UnicodeWhiteUpPointingTriangleWithDot {\uchar{37}{236}} %%WHITE UP-POINTING TRIANGLE WITH DOT +\definecharacter UnicodeUpPointingTriangleWithLeftHalfBlack {\uchar{37}{237}} %%UP-POINTING TRIANGLE WITH LEFT HALF BLACK +\definecharacter UnicodeUpPointingTriangleWithRightHalfBlack {\uchar{37}{238}} %%UP-POINTING TRIANGLE WITH RIGHT HALF BLACK +\definecharacter UnicodeLargeCircle {\uchar{37}{239}} %%LARGE CIRCLE +\definecharacter UnicodeWhiteSquareWithUpperLeftQuadrant {\uchar{37}{240}} %%WHITE SQUARE WITH UPPER LEFT QUADRANT +\definecharacter UnicodeWhiteSquareWithLowerLeftQuadrant {\uchar{37}{241}} %%WHITE SQUARE WITH LOWER LEFT QUADRANT +\definecharacter UnicodeWhiteSquareWithLowerRightQuadrant {\uchar{37}{242}} %%WHITE SQUARE WITH LOWER RIGHT QUADRANT +\definecharacter UnicodeWhiteSquareWithUpperRightQuadrant {\uchar{37}{243}} %%WHITE SQUARE WITH UPPER RIGHT QUADRANT +\definecharacter UnicodeWhiteCircleWithUpperLeftQuadrant {\uchar{37}{244}} %%WHITE CIRCLE WITH UPPER LEFT QUADRANT +\definecharacter UnicodeWhiteCircleWithLowerLeftQuadrant {\uchar{37}{245}} %%WHITE CIRCLE WITH LOWER LEFT QUADRANT +\definecharacter UnicodeWhiteCircleWithLowerRightQuadrant {\uchar{37}{246}} %%WHITE CIRCLE WITH LOWER RIGHT QUADRANT +\definecharacter UnicodeWhiteCircleWithUpperRightQuadrant {\uchar{37}{247}} %%WHITE CIRCLE WITH UPPER RIGHT QUADRANT +\definecharacter UnicodeUpperLeftTriangle {\uchar{37}{248}} %%[Unassigned U+25F8] +\definecharacter UnicodeUpperRightTriangle {\uchar{37}{249}} %%[Unassigned U+25F9] +\definecharacter UnicodeLowerLeftTriangle {\uchar{37}{250}} %%[Unassigned U+25FA] +\definecharacter UnicodeWhiteMediumSquare {\uchar{37}{251}} %%[Unassigned U+25FB] +\definecharacter UnicodeBlackMediumSquare {\uchar{37}{252}} %%[Unassigned U+25FC] +\definecharacter UnicodeWhiteMediumSmallSquare {\uchar{37}{253}} %%[Unassigned U+25FD] +\definecharacter UnicodeBlackMediumSmallSquare {\uchar{37}{254}} %%[Unassigned U+25FE] +\definecharacter UnicodeLowerRightTriangle {\uchar{37}{255}} %%[Unassigned U+25FF] + +\stopencoding + +\endinput + diff --git a/tex/context/base/enco-acc.mkii b/tex/context/base/enco-acc.mkii new file mode 100644 index 000000000..e02536be6 --- /dev/null +++ b/tex/context/base/enco-acc.mkii @@ -0,0 +1,139 @@ +%D \module +%D [ file=enco-acc, +%D version=2000.20.12, % split from base file +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=Composed Characters Commands, +%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. + +%D Although it is technically possible to redefine the commands +%D that are responsible for building composed characters, this +%D is seldom needed, since they map onto named glyphs. The +%D meaning of these names glyphs may change, although their +%D visual appearance seldom will. + +\startencoding[default] + +\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} + +\stopencoding + +\startencoding[default] + +% vietnamese: if needed, \useencoding[enco-vna] + +\stopencoding + +% For Tobias Burnus, who wants: +% +% \starttypen +% \setupinteraction[state=start] +% \setupinteractionscreen[option=bookmark] +% \placebookmarks[chapter] +% +% \starttext \chapter{F\"ur Na\"ive und Na\"\i ve} \stoptext +% \stoptypen + +\startencoding[default] + + \defineaccent " {\i} {\idiaeresis} + +\stopencoding + +\endinput diff --git a/tex/context/base/enco-agr.mkii b/tex/context/base/enco-agr.mkii new file mode 100644 index 000000000..cfd86dfd3 --- /dev/null +++ b/tex/context/base/enco-agr.mkii @@ -0,0 +1,364 @@ +%D \module +%D [ file=enco-agr, +%D version=2005.02.20, +%D title=\CONTEXT\ \UNICODE\ Macros, +%D subtitle=Ancient Greek, +%D author=Thomas A. Schmitz, +%D date=\currentdate] + +\startmapping[agr] + + \definecasemaps 13 to 64 lc 0 uc 0 + \definecasemaps 65 to 66 lc +32 uc 0 + \definecasemaps 67 to 67 lc 0 uc 0 + \definecasemaps 68 to 85 lc +32 uc 0 + \definecasemaps 86 to 86 lc 0 uc 0 + \definecasemaps 87 to 90 lc +32 uc 0 + \definecasemaps 91 to 255 lc 0 uc 0 + +\stopmapping + +\startencoding[agr] + +\definecharacter greeksigmalunate 1 +\definecharacter endash 2 +\definecharacter emdash 3 +\definecharacter apostrophe 4 +\definecharacter greekaltbeta 5 +\definecharacter epih 6 + +\definecharacter textbraceleft 8 +\definecharacter textbraceright 9 +\definecharacter textbreve 10 + +\definecharacter greekSigmalunate 13 +\definecharacter greekIotadialytika 14 +\definecharacter greekUpsilondialytika 15 + +\definecharacter greekepsilonperispomeni 18 +\definecharacter greekomicronperispomeni 19 +\definecharacter greekepsilondasiaperispomeni 20 +\definecharacter greekomicrondasiaperispomeni 21 +\definecharacter greekepsilonpsiliperispomeni 22 +\definecharacter greekomicronpsiliperispomeni 23 +\definecharacter greekiotadialytikaperispomeni 24 +\definecharacter greekupsilondialytikaperispomeni 25 +\definecharacter greekdialytikaperispomeni 26 + +\definecharacter textbottomdot 33 +\definecharacter greeksampi 34 +\definecharacter greekdigamma 35 +\definecharacter greekstigma 36 +\definecharacter greeknumkoppa 37 +\definecharacter greekkoppa 38 +\definecharacter guilsingleright 39 + +\definecharacter textdag 43 + +\definecharacter greekoxia 47 + +\definecharacter greekanoteleia 59 +\definecharacter greekdasia 60 + +\definecharacter greekpsili 62 +\definecharacter greekquestionmark 63 +\definecharacter dialytika 64 +\definecharacter greekAlpha 65 +\definecharacter greekBeta 66 +\definecharacter greekomegaiotasub 67 +\definecharacter greekDelta 68 +\definecharacter greekEpsilon 69 +\definecharacter greekPhi 70 +\definecharacter greekGamma 71 +\definecharacter greekEta 72 +\definecharacter greekIota 73 +\definecharacter greekTheta 74 +\definecharacter greekKappa 75 +\definecharacter greekLambda 76 +\definecharacter greekMu 77 +\definecharacter greekNu 78 +\definecharacter greekOmicron 79 +\definecharacter greekPi 80 +\definecharacter greekChi 81 +\definecharacter greekRho 82 +\definecharacter greekSigma 83 +\definecharacter greekTau 84 +\definecharacter greekUpsilon 85 +\definecharacter greeketaiotasub 86 +\definecharacter greekOmega 87 +\definecharacter greekXi 88 +\definecharacter greekPsi 89 +\definecharacter greekZeta 90 +\definecharacter bracketleft 91 +\definecharacter greekvaria 92 +\definecharacter bracketright 93 +\definecharacter greekperispomeni 94 + +\definecharacter guilsingleleft 96 + +% the above is a quote character +\definecharacter greekalpha 97 +\definecharacter greekbeta 98 +\definecharacter greekfinalsigma 99 +\definecharacter greekdelta 100 +\definecharacter greekepsilon 101 +\definecharacter greekphi 102 +\definecharacter greekgamma 103 +\definecharacter greeketa 104 +\definecharacter greekiota 105 +\definecharacter greektheta 106 +\definecharacter greekkappa 107 +\definecharacter greeklambda 108 +\definecharacter greekmu 109 +\definecharacter greeknu 110 +\definecharacter greekomicron 111 +\definecharacter greekpi 112 +\definecharacter greekchi 113 +\definecharacter greekrho 114 +\definecharacter greeksigma 115 +\definecharacter greektau 116 +\definecharacter greekupsilon 117 +\definecharacter greekalphaiotasub 118 +\definecharacter greekomega 119 +\definecharacter greekxi 120 +\definecharacter greekpsi 121 +\definecharacter greekzeta 122 +\definecharacter floorleft 123 +\definecharacter textbar 124 +\definecharacter floorright 125 +\definecharacter greekperispomeni 126 + +\definecharacter quotedblleft 128 +\definecharacter quotedblright 129 +\definecharacter exclam 130 +\definecharacter greekiotadasia 131 +\definecharacter greekiotapsili 132 +\definecharacter greekiotaoxia 133 +\definecharacter greekiotadasiatonos 134 +\definecharacter greekiotapsilitonos 135 +\definecharacter greekiotavaria 136 +\definecharacter greekiotadasiavaria 137 +\definecharacter greekiotapsilivaria 138 +\definecharacter greekiotaperispomeni 139 +\definecharacter greekiotadasiaperispomeni 140 +\definecharacter greekiotapsiliperispomeni 141 +\definecharacter greekiotadialytika 142 +\definecharacter greekiotadialytikatonos 143 +\definecharacter greekiotadialytikavaria 144 +\definecharacter greekdasiaperispomeni 145 +\definecharacter greekpsiliperispomeni 146 +\definecharacter greekdasiatonos 147 +\definecharacter greekpsilitonos 148 +\definecharacter greekdasiavaria 149 +\definecharacter greekpsilivaria 150 +\definecharacter greekdialytikatonos 151 +\definecharacter greekepsilondasia 152 +\definecharacter greekepsilonpsili 153 +\definecharacter greekepsilonoxia 154 +\definecharacter greekepsilondasiatonos 155 +\definecharacter greekepsilonpsilitonos 156 +\definecharacter greekepsilonvaria 157 +\definecharacter greekepsilondasiavaria 158 +\definecharacter greekepsilonpsilivaria 159 +\definecharacter greekdialytikavaria 160 +\definecharacter greekalphadasia 161 +\definecharacter greekalphapsili 162 +\definecharacter greekalphaoxia 163 +\definecharacter greekalphadasiatonos 164 +\definecharacter greekalphapsilitonos 165 +\definecharacter greekalphavaria 166 +\definecharacter greekalphadasiavaria 167 +\definecharacter greekalphapsilivaria 168 +\definecharacter greekalphaperispomeni 169 +\definecharacter greekalphadasiaperispomeni 170 +\definecharacter greekalphapsiliperispomeni 171 +\definecharacter greekalphaiotasubdasia 172 +\definecharacter greekalphaiotasubpsili 173 +\definecharacter greekalphaiotasubtonos 174 +\definecharacter greekalphaiotasubdasiatonos 175 +\definecharacter greekalphaiotasubpsilitonos 176 +\definecharacter greekalphaiotasubvaria 177 +\definecharacter greekalphaiotasubdasiavaria 178 +\definecharacter greekalphaiotasubpsilivaria 179 +\definecharacter greekalphaiotasubperispomeni 180 +\definecharacter greekalphaiotasubdasiaperispomeni 181 +\definecharacter greekalphaiotasubpsiliperispomeni 182 +\definecharacter greekrhodasia 183 +\definecharacter greekrhopsili 184 +\definecharacter greeketadasia 185 +\definecharacter greeketapsili 186 +\definecharacter greeketaoxia 187 +\definecharacter greeketadasiatonos 188 +\definecharacter greeketapsilitonos 189 +\definecharacter greeketavaria 190 +\definecharacter greeketadasiavaria 191 +\definecharacter greeketapsilivaria 192 +\definecharacter greeketaperispomeni 193 +\definecharacter greeketadasiaperispomeni 194 +\definecharacter greeketapsiliperispomeni 195 +\definecharacter textslash 196 +\definecharacter greeketaiotasubdasia 197 +\definecharacter greeketaiotasubpsili 198 +\definecharacter greeketaiotasubtonos 199 +\definecharacter greeketaiotasubdasiatonos 200 +\definecharacter greeketaiotasubpsilitonos 201 +\definecharacter greeketaiotasubvaria 202 +\definecharacter greeketaiotasubdasiavaria 203 +\definecharacter greeketaiotasubpsilivaria 204 +\definecharacter greeketaiotasubperispomeni 205 +\definecharacter greeketaiotasubdasiaperispomeni 206 +\definecharacter greeketaiotasubpsiliperispomeni 207 +\definecharacter greekomicrondasia 208 +\definecharacter greekomicronpsili 209 +\definecharacter greekomicronoxia 210 +\definecharacter greekomicrondasiatonos 211 +\definecharacter greekomicronpsilitonos 212 +\definecharacter greekomicronvaria 213 +\definecharacter greekomicrondasiavaria 214 +\definecharacter greekomicronpsilivaria 215 +\definecharacter greekupsilondasia 216 +\definecharacter greekupsilonpsili 217 +\definecharacter greekupsilonoxia 218 +\definecharacter greekupsilondasiatonos 219 +\definecharacter greekupsilonpsilitonos 220 +\definecharacter greekupsilonvaria 221 +\definecharacter greekupsilondasiavaria 222 +\definecharacter greekupsilonpsilivaria 223 +\definecharacter greekupsilonperispomeni 224 +\definecharacter greekupsilondasiaperispomeni 225 +\definecharacter greekupsilonpsiliperispomeni 226 +\definecharacter greekupsilondiaeresis 227 +\definecharacter greekupsilondialytikatonos 228 +\definecharacter greekupsilondialytikavaria 229 +\definecharacter greekomegadasia 230 +\definecharacter greekomegapsili 231 +\definecharacter greekomegaoxia 232 +\definecharacter greekomegadasiatonos 233 +\definecharacter greekomegapsilitonos 234 +\definecharacter greekomegavaria 235 +\definecharacter greekomegadasiavaria 236 +\definecharacter greekomegapsilivaria 237 +\definecharacter greekomegaperispomeni 238 +\definecharacter greekomegadasiaperispomeni 239 +\definecharacter greekomegapsiliperispomeni 240 +\definecharacter greekomegaiotasubdasia 241 +\definecharacter greekomegaiotasubpsili 242 +\definecharacter greekomegaiotasubtonos 243 +\definecharacter greekomegaiotasubdasiatonos 244 +\definecharacter greekomegaiotasubpsilitonos 245 +\definecharacter greekomegaiotasubvaria 246 +\definecharacter greekomegaiotasubdasiavaria 247 +\definecharacter greekomegaiotasubpsilivaria 248 +\definecharacter greekomegaiotasubperispomeni 249 +\definecharacter greekomegaiotasubdasiaperispomeni 250 +\definecharacter greekomegaiotasubpsiliperispomeni 251 +\definecharacter greeknumeralsign 254 +\definecharacter greeknumeralsignlower 255 + +\stopencoding + +\startencoding[default] + +\definecharacter greekAlphapsili {\greekpsili \greekAlpha} +\definecharacter greekAlphadasia {\greekdasia \greekAlpha} +\definecharacter greekAlphapsilivaria {\greekpsilivaria \greekAlpha} +\definecharacter greekAlphadasiavaria {\greekdasiavaria \greekAlpha} +\definecharacter greekAlphapsilitonos {\greekpsilitonos \greekAlpha} +\definecharacter greekAlphadasiatonos {\greekdasiatonos \greekAlpha} +\definecharacter greekAlphapsiliperispomeni {\greekpsiliperispomeni \greekAlpha} +\definecharacter greekAlphadasiaperispomeni {\greekdasiaperispomeni \greekAlpha} +\definecharacter greekEpsilonpsili {\greekpsili \greekEpsilon} +\definecharacter greekEpsilondasia {\greekdasia \greekEpsilon} +\definecharacter greekEpsilonpsilivaria {\greekpsilivaria \greekEpsilon} +\definecharacter greekEpsilondasiavaria {\greekdasiavaria \greekEpsilon} +\definecharacter greekEpsilonpsilitonos {\greekpsilitonos \greekEpsilon} +\definecharacter greekEpsilondasiatonos {\greekdasiatonos \greekEpsilon} +\definecharacter greekEtapsili {\greekpsili \greekEta} +\definecharacter greekEtadasia {\greekdasia \greekEta} +\definecharacter greekEtapsilivaria {\greekpsilivaria \greekEta} +\definecharacter greekEtadasiavaria {\greekdasiavaria \greekEta} +\definecharacter greekEtapsilitonos {\greekpsilitonos \greekEta} +\definecharacter greekEtadasiatonos {\greekdasiatonos \greekEta} +\definecharacter greekEtapsiliperispomeni {\greekpsiliperispomeni \greekEta} +\definecharacter greekEtadasiaperispomeni {\greekdasiaperispomeni \greekEta} +\definecharacter greekIotapsili {\greekpsili \greekIota} +\definecharacter greekIotadasia {\greekdasia \greekIota} +\definecharacter greekIotapsilivaria {\greekpsilivaria \greekIota} +\definecharacter greekIotadasiavaria {\greekdasiavaria \greekIota} +\definecharacter greekIotapsilitonos {\greekpsilitonos \greekIota} +\definecharacter greekIotadasiatonos {\greekdasiatonos \greekIota} +\definecharacter greekIotapsiliperispomeni {\greekpsiliperispomeni \greekIota} +\definecharacter greekIotadasiaperispomeni {\greekdasiaperispomeni \greekIota} +\definecharacter greekOmicronpsili {\greekpsili \greekOmicron} +\definecharacter greekOmicrondasia {\greekdasia \greekOmicron} +\definecharacter greekOmicronpsilivaria {\greekpsilivaria \greekOmicron} +\definecharacter greekOmicrondasiavaria {\greekdasiavaria \greekOmicron} +\definecharacter greekOmicronpsilitonos {\greekpsilitonos \greekOmicron} +\definecharacter greekOmicrondasiatonos {\greekdasiatonos \greekOmicron} +\definecharacter greekUpsilondasia {\greekdasia \greekUpsilon} +\definecharacter greekUpsilondasiavaria {\greekdasiavaria \greekUpsilon} +\definecharacter greekUpsilondasiatonos {\greekdasiatonos \greekUpsilon} +\definecharacter greekUpsilondasiaperispomeni {\greekdasiaperispomeni \greekUpsilon} +\definecharacter greekOmegapsili {\greekpsili \greekOmega} +\definecharacter greekOmegadasia {\greekdasia \greekOmega} +\definecharacter greekOmegapsilivaria {\greekpsilivaria \greekOmega} +\definecharacter greekOmegadasiavaria {\greekdasiavaria \greekOmega} +\definecharacter greekOmegapsilitonos {\greekpsilitonos \greekOmega} +\definecharacter greekOmegadasiatonos {\greekdasiatonos \greekOmega} +\definecharacter greekOmegapsiliperispomeni {\greekpsiliperispomeni \greekOmega} +\definecharacter greekOmegadasiaperispomeni {\greekdasiaperispomeni \greekOmega} +\definecharacter greekAlphaiotasubpsili {\greekpsili \greekAlpha \greekiota} +\definecharacter greekAlphaiotasubdasia {\greekdasia \greekAlpha \greekiota} +\definecharacter greekAlphaiotasubpsilivaria {\greekpsilivaria \greekAlpha \greekiota} +\definecharacter greekAlphaiotasubdasiavaria {\greekdasiavaria \greekAlpha \greekiota} +\definecharacter greekAlphaiotasubpsilitonos {\greekpsilitonos \greekAlpha \greekiota} +\definecharacter greekAlphaiotasubdasiatonos {\greekdasiatonos \greekAlpha \greekiota} +\definecharacter greekAlphaiotasubpsiliperispomeni {\greekpsiliperispomeni \greekAlpha \greekiota} +\definecharacter greekAlphaiotasubdasiaperispomeni {\greekdasiaperispomeni \greekAlpha \greekiota} +\definecharacter greekEtaiotasubpsili {\greekpsili \greekEta \greekiota} +\definecharacter greekEtaiotasubdasia {\greekdasia \greekEta \greekiota} +\definecharacter greekEtaiotasubpsilivaria {\greekpsilivaria \greekEta \greekiota} +\definecharacter greekEtaiotasubdasiavaria {\greekdasiavaria \greekEta \greekiota} +\definecharacter greekEtaiotasubpsilitonos {\greekpsilitonos \greekEta \greekiota} +\definecharacter greekEtaiotasubdasiatonos {\greekdasiatonos \greekEta \greekiota} +\definecharacter greekEtaiotasubpsiliperispomeni {\greekpsiliperispomeni \greekEta \greekiota} +\definecharacter greekEtaiotasubdasiaperispomeni {\greekdasiaperispomeni \greekEta \greekiota} +\definecharacter greekOmegaiotasubpsili {\greekpsili \greekOmega \greekiota} +\definecharacter greekOmegaiotasubdasia {\greekdasia \greekOmega \greekiota} +\definecharacter greekOmegaiotasubpsilivaria {\greekpsilivaria \greekOmega \greekiota} +\definecharacter greekOmegaiotasubdasiavaria {\greekdasiavaria \greekOmega \greekiota} +\definecharacter greekOmegaiotasubpsilitonos {\greekpsilitonos \greekOmega \greekiota} +\definecharacter greekOmegaiotasubdasiatonos {\greekdasiatonos \greekOmega \greekiota} +\definecharacter greekOmegaiotasubpsiliperispomeni {\greekpsiliperispomeni \greekOmega \greekiota} +\definecharacter greekOmegaiotasubdasiaperispomeni {\greekdasiaperispomeni \greekOmega \greekiota} +\definecharacter greekAlphavaria {\greekvaria \greekAlpha} +\definecharacter greekAlphaoxia {\greekoxia \greekAlpha} +\definecharacter greekAlphaiotasub {\greekAlpha \greekiota} +\definecharacter greekEpsilonvaria {\greekvaria \greekEpsilon} +\definecharacter greekEpsilonoxia {\greekoxia \greekEpsilon} +\definecharacter greekEtavaria {\greekvaria \greekEta} +\definecharacter greekEtaoxia {\greekoxia \greekEta} +\definecharacter greekEtaiotasub {\greekEta \greekiota} +\definecharacter greekIotavaria {\greekvaria \greekIota} +\definecharacter greekIotaoxia {\greekoxia \greekIota} +\definecharacter greekUpsilonvaria {\greekvaria \greekUpsilon} +\definecharacter greekUpsilonoxia {\greekoxia \greekUpsilon} +\definecharacter greekOmicronvaria {\greekvaria \greekOmicron} +\definecharacter greekOmicronoxia {\greekoxia \greekOmicron} +\definecharacter greekOmegavaria {\greekvaria \greekOmega} +\definecharacter greekOmegaoxia {\greekoxia \greekOmega} +\definecharacter greekOmegaiotasub {\greekOmega \greekiota} +\definecharacter greekRhodasia {\greekdasia \greekRho} +\definecharacter digamma {\greekdigamma} +\definecharacter sampi {\greeksampi} +\definecharacter stigma {\greekstigma} +\definecharacter koppa {\greeknumkoppa} +\definecharacter lunars {\greeksigmalunate} +\definecharacter lunarS {\greekSigmalunate} +\definecharacter halfbraceleft {\floorleft} +\definecharacter halfbraceright {\floorright} +\definecharacter crux {\textdag} + +\stopencoding + +\endinput diff --git a/tex/context/base/enco-ans.mkii b/tex/context/base/enco-ans.mkii new file mode 100644 index 000000000..7a48b5b55 --- /dev/null +++ b/tex/context/base/enco-ans.mkii @@ -0,0 +1,237 @@ +%D \module +%D [ file=enco-ans, +%D version=2000.05.07, % 1995.01.01, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=\YandY\ texnansi Encoding, +%D author={Patrick Gundlach, 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. + +%D This is \YandY's texnansi encoding vector, which combines +%D the best of the ansi encoding vector (prebuilt accented +%D characters etc.) and some of \TEX's vectors. + +\startmapping[texnansi] + +\resetcaserange 128 to 158 +\resetcaserange 160 to 191 +\resetcaserange 215 to 215 +\resetcaserange 247 to 247 + +\definecasemaps 192 to 214 lc +32 uc 0 +\definecasemaps 224 to 246 lc 0 uc -32 +\definecasemaps 216 to 222 lc +32 uc 0 +\definecasemaps 248 to 254 lc 0 uc -32 + +\definecaseself 223 +\definecaseswap 156 140 +\definecaseswap 255 159 + +% needed by some patterns: + +% \definecaseself 34 % quotedbl +% \definecaseself 132 % quotedblbase +% \definecaseself 147 % quotedblleft +% \definecaseself 148 % quotedblright +% \definecaseself 129 % quotesingle +% \definecaseself 130 % quotesinglebase +% \definecaseself 145 % quoteleft +% \definecaseself 146 % quoteright + +\stopmapping + +\startencoding[texnansi] + +\definecharacter textacute 19 +\definecharacter textbreve 21 +\definecharacter textcaron 20 +\definecharacter textcedilla 184 +\definecharacter textcircumflex 94 % 136 +\definecharacter textdiaeresis 168 +\definecharacter textdotaccent 5 +\definecharacter textgrave 18 +\definecharacter texthungarumlaut 6 +\definecharacter textmacron 175 +\definecharacter textogonek 7 +\definecharacter textring 23 +\definecharacter texttilde 152 + +\definecharacter dotlessi 16 % 105 +\definecharacter dotlessj 17 + +\definecharacter endash 150 % lig +\definecharacter emdash 151 % lig + +\definecharacter aeligature 230 +\definecharacter AEligature 198 +\definecharacter oeligature 156 +\definecharacter OEligature 140 + +\definecharacter ssharp 223 + +\definecharacter thorn 254 +\definecharacter Thorn 222 + +\definecharacter Dstroke 208 % also Eth, mapped in enco-def +\definecharacter eth 240 + +\definecharacter exclamdown 161 +\definecharacter questiondown 191 + +\definecharacter copyright 169 +\definecharacter registered 174 +\definecharacter trademark 153 + +\definecharacter sectionmark 167 +\definecharacter paragraphmark 182 + +\definecharacter onequarter 188 +\definecharacter onehalf 189 +\definecharacter threequarter 190 + +\definecharacter onesuperior 185 +\definecharacter twosuperior 178 +\definecharacter threesuperior 179 + +\definecharacter textcent 162 % ? +\definecharacter textcurrency 164 +\definecharacter texteuro 1 +\definecharacter textflorin 131 +\definecharacter textsterling 163 +\definecharacter textyen 165 + +\definecharacter percent 37 +\definecharacter perthousand 137 + +\definecharacter softhyphen 45 +\definecharacter periodcentered 183 + +\definecharacter textasciicircum 142 +\definecharacter textasciitilde 158 +\definecharacter textbackslash 92 +\definecharacter textbraceleft 123 +\definecharacter textbar 124 +\definecharacter textbraceright 125 +\definecharacter textunderscore 95 + +\definecharacter textbrokenbar 166 +\definecharacter textbullet 149 +\definecharacter textdag 134 +\definecharacter textddag 135 +\definecharacter textdegree 176 +\definecharacter textdiv 247 +\definecharacter textellipsis 133 +\definecharacter textfraction 4 +\definecharacter textlognot 172 +\definecharacter textminus 143 +\definecharacter textmu 181 +\definecharacter textmultiply 215 +\definecharacter textpm 177 + +\definecharacter quotedbl 34 +\definecharacter quotedblbase 132 +\definecharacter quotedblleft 147 +\definecharacter quotedblright 148 + +\definecharacter quotesingle 129 +\definecharacter quotesinglebase 130 + +\definecharacter quoteleft 145 +\definecharacter quoteright 146 + +\definecharacter guilsingleleft 139 +\definecharacter guilsingleright 155 +\definecharacter leftguillemot 171 +\definecharacter rightguillemot 187 + +\definecharacter aacute 225 +\definecharacter Aacute 193 +\definecharacter eacute 233 +\definecharacter Eacute 201 +\definecharacter iacute 237 +\definecharacter Iacute 205 +\definecharacter oacute 243 +\definecharacter Oacute 211 +\definecharacter uacute 250 +\definecharacter Uacute 218 +\definecharacter yacute 253 +\definecharacter Yacute 221 + +\definecharacter scaron 154 +\definecharacter Scaron 138 +\definecharacter zcaron 157 +\definecharacter Zcaron 141 + +\definecharacter ccedilla 231 +\definecharacter Ccedilla 199 + +\definecharacter acircumflex 226 +\definecharacter Acircumflex 194 +\definecharacter ecircumflex 234 +\definecharacter Ecircumflex 202 +\definecharacter icircumflex 238 +\definecharacter Icircumflex 206 +\definecharacter ocircumflex 244 +\definecharacter Ocircumflex 212 +\definecharacter ucircumflex 251 +\definecharacter Ucircumflex 219 + +\definecharacter adiaeresis 228 +\definecharacter Adiaeresis 196 +\definecharacter ediaeresis 235 +\definecharacter Ediaeresis 203 +\definecharacter idiaeresis 239 +\definecharacter Idiaeresis 207 +\definecharacter odiaeresis 246 +\definecharacter Odiaeresis 214 +\definecharacter udiaeresis 252 +\definecharacter Udiaeresis 220 +\definecharacter ydiaeresis 255 +\definecharacter Ydiaeresis 159 + +\definecharacter agrave 224 +\definecharacter Agrave 192 +\definecharacter egrave 232 +\definecharacter Egrave 200 +\definecharacter igrave 236 +\definecharacter Igrave 204 +\definecharacter ograve 242 +\definecharacter Ograve 210 +\definecharacter ugrave 249 +\definecharacter Ugrave 217 + +\definecharacter aring 229 +\definecharacter Aring 197 + +\definecharacter Lstroke 128 +\definecharacter lstroke 144 +\definecharacter ostroke 248 +\definecharacter Ostoke 216 + +\definecharacter atilde 227 +\definecharacter Atilde 195 +\definecharacter ntilde 241 +\definecharacter Ntilde 209 +\definecharacter otilde 245 +\definecharacter Otilde 213 + +\stopencoding + +% will be replaced by math collection, fails anyway + +\startencoding[texnansi] + +\definecharacter mathgrave "7060 +\definecharacter mathacute "70B4 +\definecharacter mathhat "7088 +\definecharacter mathtilde "7098 +\definecharacter mathddot "70A8 +\definecharacter mathbar "70AF + +\stopencoding + +\endinput diff --git a/tex/context/base/enco-cas.mkii b/tex/context/base/enco-cas.mkii new file mode 100644 index 000000000..38d12f9fa --- /dev/null +++ b/tex/context/base/enco-cas.mkii @@ -0,0 +1,143 @@ +%D \module +%D [ file=enco-cas, +%D version=2005.08.23, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=Named Glyph Case Mapping, +%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. + +%D For quite some years \CONTEXT\ used a rather compact way of +%D defining encoded characters as well as case maps. When late +%D 2000 more advanced remapping features were needed (like pdf +%D unicode remapping), named glyphs were introduced to keep the +%D coding tables more readable. At the same time, we introduced +%D named glyph case mapping. + +\defineULcharacter Acircumflex acircumflex +\defineULcharacter Ccircumflex ccircumflex +\defineULcharacter Ecircumflex ecircumflex +\defineULcharacter Gcircumflex gcircumflex +\defineULcharacter Hcircumflex hcircumflex +\defineULcharacter Icircumflex icircumflex +\defineULcharacter Jcircumflex jcircumflex +\defineULcharacter Ocircumflex ocircumflex +\defineULcharacter Scircumflex scircumflex +\defineULcharacter Ucircumflex ucircumflex +\defineULcharacter Wcircumflex wcircumflex +\defineULcharacter Ycircumflex ycircumflex + +\defineULcharacter Agrave agrave +\defineULcharacter Egrave egrave +\defineULcharacter Igrave igrave +\defineULcharacter Ograve ograve +\defineULcharacter Ugrave ugrave +\defineULcharacter Ygrave ygrave + +\defineULcharacter Atilde atilde +\defineULcharacter Itilde itilde +\defineULcharacter Otilde otilde +\defineULcharacter Ntilde ntilde +\defineULcharacter Utilde utilde + +\defineULcharacter Adiaeresis adiaeresis +\defineULcharacter Ediaeresis ediaeresis +\defineULcharacter Idiaeresis idiaeresis +\defineULcharacter Odiaeresis odiaeresis +\defineULcharacter Udiaeresis udiaeresis +\defineULcharacter Ydiaeresis ydiaeresis + +\defineULcharacter Aacute aacute +\defineULcharacter Cacute cacute +\defineULcharacter Eacute eacute +\defineULcharacter Iacute iacute +\defineULcharacter Lacute lacute +\defineULcharacter Nacute nacute +\defineULcharacter Oacute oacute +\defineULcharacter Racute racute +\defineULcharacter Sacute sacute +\defineULcharacter Uacute uacute +\defineULcharacter Yacute yacute +\defineULcharacter Zacute zacute + +\defineULcharacter Dstroke dstroke +\defineULcharacter Hstroke hstroke +\defineULcharacter Lstroke lstroke +\defineULcharacter Lslash lslash +\defineULcharacter Ostroke ostroke +\defineULcharacter Tstroke tstroke + +\defineULcharacter Cdotaccent cdotaccent +\defineULcharacter Edotaccent edotaccent +\defineULcharacter Gdotaccent gdotaccent +\defineULcharacter Idotaccent idotaccent +\defineULcharacter Zdotaccent zdotaccent + +\defineULcharacter Amacron amacron +\defineULcharacter Emacron emacron +\defineULcharacter Imacron imacron +\defineULcharacter Omacron omacron +\defineULcharacter Umacron umacron + +\defineULcharacter Ccedilla ccedilla +\defineULcharacter Gcedilla gcedilla +\defineULcharacter Kcedilla kcedilla +\defineULcharacter Lcedilla lcedilla +\defineULcharacter Ncedilla ncedilla +\defineULcharacter Rcedilla rcedilla +\defineULcharacter Scedilla scedilla +\defineULcharacter Tcedilla tcedilla + +\defineULcharacter Ccommaaccent ccommaaccent +\defineULcharacter Gcommaaccent gcommaaccent +\defineULcharacter Kcommaaccent kcommaaccent +\defineULcharacter Lcommaaccent lcommaaccent +\defineULcharacter Ncommaaccent ncommaaccent +\defineULcharacter Rcommaaccent rcommaaccent +\defineULcharacter Scommaaccent scommaaccent +\defineULcharacter Tcommaaccent tcommaaccent + +\defineULcharacter Ohungarumlaut ohungarumlaut +\defineULcharacter Uhungarumlaut uhungarumlaut + +\defineULcharacter Aogonek aogonek +\defineULcharacter Eogonek eogonek +\defineULcharacter Iogonek iogonek +\defineULcharacter Uogonek uogonek + +\defineULcharacter Aring aring +\defineULcharacter Uring uring + +\defineULcharacter Abreve abreve +\defineULcharacter Ebreve ebreve +\defineULcharacter Gbreve gbreve +\defineULcharacter Ibreve ibreve +\defineULcharacter Obreve obreve +\defineULcharacter Ubreve ubreve + +\defineULcharacter Ccaron ccaron +\defineULcharacter Dcaron dcaron +\defineULcharacter Ecaron ecaron +\defineULcharacter Lcaron lcaron +\defineULcharacter Ncaron ncaron +\defineULcharacter Rcaron rcaron +\defineULcharacter Scaron scaron +\defineULcharacter Tcaron tcaron +\defineULcharacter Zcaron zcaron + +\defineULcharacter dotlessI dotlessi +\defineULcharacter dotlessJ dotlessj + +\defineULcharacter AEligature aeligature +\defineULcharacter OEligature oeligature +\defineULcharacter Ssharp ssharp +\defineULcharacter IJligature ijligature + +\defineULcharacter Eth eth +\defineULcharacter Thorn thorn + +\endinput diff --git a/tex/context/base/enco-chi.mkii b/tex/context/base/enco-chi.mkii new file mode 100644 index 000000000..9d77893a0 --- /dev/null +++ b/tex/context/base/enco-chi.mkii @@ -0,0 +1,371 @@ +%D \module +%D [ file=enco-chi, +%D version=1999.12.02, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=Traditional and Simplified Chinese, +%D author={Wang Lei \& 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. + +% actually this is also a filter -> enco-fcn.tex + +%D This is an experimental definition. Since we are dealing +%D with unicode's, the registered values are not saved, so +%D actually we're dealing with an pseudo encoding. The digits +%D on the other hand are encoding specific. + +% chinese classes: left=1|right=2|center=3 + +% untested, probably wrong + +\startencoding[cjk-uni] + +\defineuclass 1 32 24 +\defineuclass 1 32 28 +\defineuclass 1 48 20 +\defineuclass 1 48 8 +\defineuclass 1 48 10 +\defineuclass 1 48 12 +\defineuclass 1 48 14 +\defineuclass 1 48 22 +\defineuclass 1 48 16 +\defineuclass 1 255 8 +\defineuclass 1 255 59 +\defineuclass 1 255 64 +\defineuclass 1 255 91 + +\defineuclass 3 0 183 +\defineuclass 3 0 168 +\defineuclass 3 32 38 +\defineuclass 3 255 30 + +\defineuclass 2 48 1 +\defineuclass 2 48 2 +\defineuclass 2 32 20 +\defineuclass 2 255 94 +\defineuclass 2 32 25 +\defineuclass 2 32 29 +\defineuclass 2 48 21 +\defineuclass 2 48 9 +\defineuclass 2 48 11 +\defineuclass 2 48 13 +\defineuclass 2 48 15 +\defineuclass 2 48 23 +\defineuclass 2 48 17 +\defineuclass 2 34 55 +\defineuclass 2 0 176 +\defineuclass 2 32 50 +\defineuclass 2 32 51 +\defineuclass 2 255 1 +\defineuclass 2 255 2 +\defineuclass 2 255 7 +\defineuclass 2 255 9 +\defineuclass 2 255 12 +\defineuclass 2 255 14 +\defineuclass 2 255 26 +\defineuclass 2 255 27 +\defineuclass 2 255 31 +\defineuclass 2 255 61 +\defineuclass 2 255 93 + +\defineudigit 0 37 203 +\defineudigit 1 78 0 +\defineudigit 2 78 140 +\defineudigit 3 78 9 +\defineudigit 4 86 219 +\defineudigit 5 78 148 +\defineudigit 6 81 109 +\defineudigit 7 78 3 +\defineudigit 8 81 107 +\defineudigit 9 78 93 +\defineudigit 10 83 65 +\defineudigit 100 118 126 +\defineudigit 1000 83 67 +\defineudigit 10000 78 7 +\defineudigit 100000000 78 191 + +\defineudigit 0* 150 246 +\defineudigit 1* 88 249 +\defineudigit 2* 141 48 +\defineudigit 3* 83 193 +\defineudigit 4* 128 134 +\defineudigit 5* 79 13 +\defineudigit 6* 150 70 +\defineudigit 7* 103 210 +\defineudigit 8* 99 76 +\defineudigit 9* 115 150 +\defineudigit 10* 98 254 +\defineudigit 100* 79 112 +\defineudigit 1000* 78 223 +\defineudigit 10000* 132 44 +\defineudigit 100000000* 78 191 + +\defineudigit 20 94 255 +\defineudigit 21 78 0 +\defineudigit 22 78 140 +\defineudigit 23 78 9 +\defineudigit 24 86 219 +\defineudigit 25 78 148 +\defineudigit 26 81 109 +\defineudigit 27 78 3 +\defineudigit 28 81 107 +\defineudigit 29 78 93 + +\defineudigit 30 83 69 +\defineudigit 31 78 0 +\defineudigit 32 78 140 +\defineudigit 33 78 9 +\defineudigit 34 86 219 +\defineudigit 35 78 148 +\defineudigit 36 81 109 +\defineudigit 37 78 3 +\defineudigit 38 81 107 +\defineudigit 39 78 93 + +\stopencoding + +% \doif \currentregime {utf} \endinput + +\startencoding[big5] + +\defineuclass 1 161 93 +\defineuclass 1 161 95 +\defineuclass 1 161 97 +\defineuclass 1 161 99 +\defineuclass 1 161 101 +\defineuclass 1 161 103 +\defineuclass 1 161 105 +\defineuclass 1 161 107 +\defineuclass 1 161 111 +\defineuclass 1 161 111 +\defineuclass 1 161 113 +\defineuclass 1 161 115 +\defineuclass 1 161 117 +\defineuclass 1 161 119 +\defineuclass 1 161 121 +\defineuclass 1 161 123 +\defineuclass 1 161 125 +\defineuclass 1 161 161 +\defineuclass 1 161 163 +\defineuclass 1 161 165 +\defineuclass 1 161 167 +\defineuclass 1 161 169 +\defineuclass 1 161 171 + +\defineuclass 3 161 69 +\defineuclass 3 161 75 +\defineuclass 3 161 76 + +\defineuclass 2 161 65 +\defineuclass 2 161 66 +\defineuclass 2 161 67 +\defineuclass 2 161 68 +\defineuclass 2 161 70 +\defineuclass 2 161 71 +\defineuclass 2 161 72 +\defineuclass 2 161 73 +\defineuclass 2 161 74 +\defineuclass 2 161 77 +\defineuclass 2 161 78 +\defineuclass 2 161 79 +\defineuclass 2 161 80 +\defineuclass 2 161 81 +\defineuclass 2 161 82 +\defineuclass 2 161 83 +\defineuclass 2 161 84 +\defineuclass 2 161 88 +\defineuclass 2 161 94 +\defineuclass 2 161 96 +\defineuclass 2 161 98 +\defineuclass 2 161 100 +\defineuclass 2 161 102 +\defineuclass 2 161 104 +\defineuclass 2 161 106 +\defineuclass 2 161 108 +\defineuclass 2 161 110 +\defineuclass 2 161 112 +\defineuclass 2 161 114 +\defineuclass 2 161 116 +\defineuclass 2 161 118 +\defineuclass 2 161 120 +\defineuclass 2 161 122 +\defineuclass 2 161 124 +\defineuclass 2 161 126 +\defineuclass 2 161 162 +\defineuclass 2 161 164 +\defineuclass 2 161 166 +\defineuclass 2 161 168 +\defineuclass 2 161 170 +\defineuclass 2 161 172 +\defineuclass 2 161 196 +\defineuclass 2 161 227 +\defineuclass 2 162 88 +\defineuclass 2 163 223 + +\defineudigit 0 162 179 +\defineudigit 1 164 64 +\defineudigit 2 164 71 +\defineudigit 3 164 84 +\defineudigit 4 165 124 +\defineudigit 5 164 173 +\defineudigit 6 164 187 +\defineudigit 7 164 67 +\defineudigit 8 164 75 +\defineudigit 9 164 69 +\defineudigit 10 164 81 +\defineudigit 100 166 202 +\defineudigit 1000 164 100 +\defineudigit 10000 201 69 +\defineudigit 100000000 187 245 + +\defineudigit 0* 185 115 +\defineudigit 1* 179 252 +\defineudigit 2* 182 76 +\defineudigit 3* 176 209 +\defineudigit 4* 184 118 +\defineudigit 5* 165 238 +\defineudigit 6* 179 176 +\defineudigit 7* 172 110 +\defineudigit 8* 174 195 +\defineudigit 9* 168 104 +\defineudigit 10* 172 66 +\defineudigit 100* 168 213 +\defineudigit 1000* 165 97 +\defineudigit 10000* 184 85 +\defineudigit 100000000* 187 245 + +\defineudigit 20 164 220 +\defineudigit 21 164 64 +\defineudigit 22 164 71 +\defineudigit 23 164 84 +\defineudigit 24 165 124 +\defineudigit 25 164 173 +\defineudigit 26 164 187 +\defineudigit 27 164 67 +\defineudigit 28 164 75 +\defineudigit 29 164 69 + +\defineudigit 30 164 202 +\defineudigit 31 164 64 +\defineudigit 32 164 71 +\defineudigit 33 164 84 +\defineudigit 34 165 124 +\defineudigit 35 164 173 +\defineudigit 36 164 187 +\defineudigit 37 164 67 +\defineudigit 38 164 75 +\defineudigit 39 164 69 + +\stopencoding + +\startencoding[gbk] + +\defineuclass 1 161 174 +\defineuclass 1 161 176 +\defineuclass 1 161 178 +\defineuclass 1 161 180 +\defineuclass 1 161 182 +\defineuclass 1 161 184 +\defineuclass 1 161 186 +\defineuclass 1 161 188 +\defineuclass 1 161 190 +\defineuclass 1 163 168 +\defineuclass 1 163 219 +\defineuclass 1 163 224 +\defineuclass 1 163 251 + +\defineuclass 3 161 164 +\defineuclass 3 161 167 +\defineuclass 3 161 173 +\defineuclass 3 163 190 + +\defineuclass 2 161 162 +\defineuclass 2 161 163 +\defineuclass 2 161 170 +\defineuclass 2 161 171 +\defineuclass 2 161 175 +\defineuclass 2 161 177 +\defineuclass 2 161 179 +\defineuclass 2 161 181 +\defineuclass 2 161 183 +\defineuclass 2 161 185 +\defineuclass 2 161 187 +\defineuclass 2 161 189 +\defineuclass 2 161 191 +\defineuclass 2 161 203 +\defineuclass 2 161 227 +\defineuclass 2 161 228 +\defineuclass 2 161 229 +\defineuclass 2 163 161 +\defineuclass 2 163 162 +\defineuclass 2 163 167 +\defineuclass 2 163 169 +\defineuclass 2 163 172 +\defineuclass 2 163 174 +\defineuclass 2 163 186 +\defineuclass 2 163 187 +\defineuclass 2 163 191 +\defineuclass 2 163 221 +\defineuclass 2 163 253 + +\defineudigit 0 161 240 +\defineudigit 1 210 187 +\defineudigit 2 182 254 +\defineudigit 3 200 253 +\defineudigit 4 203 196 +\defineudigit 5 206 229 +\defineudigit 6 193 249 +\defineudigit 7 198 223 +\defineudigit 8 176 203 +\defineudigit 9 190 197 +\defineudigit 10 202 174 +\defineudigit 100 176 217 +\defineudigit 1000 199 167 +\defineudigit 10000 205 242 +\defineudigit 100000000 210 218 + +\defineudigit 0* 193 227 +\defineudigit 1* 210 188 +\defineudigit 2* 183 161 +\defineudigit 3* 200 254 +\defineudigit 4* 203 193 +\defineudigit 5* 206 233 +\defineudigit 6* 194 189 +\defineudigit 7* 198 226 +\defineudigit 8* 176 198 +\defineudigit 9* 190 193 +\defineudigit 10* 202 176 +\defineudigit 100* 176 219 +\defineudigit 1000* 199 170 +\defineudigit 10000* 200 102 +\defineudigit 100000000* 210 218 + +\defineudigit 20 216 165 +\defineudigit 21 210 187 +\defineudigit 22 182 254 +\defineudigit 23 200 253 +\defineudigit 24 203 196 +\defineudigit 25 206 229 +\defineudigit 26 193 249 +\defineudigit 27 198 223 +\defineudigit 28 176 203 +\defineudigit 29 190 197 + +\defineudigit 30 216 166 +\defineudigit 31 210 187 +\defineudigit 32 182 254 +\defineudigit 33 200 253 +\defineudigit 34 203 196 +\defineudigit 35 206 229 +\defineudigit 36 193 249 +\defineudigit 37 198 223 +\defineudigit 38 176 203 +\defineudigit 39 190 197 + +\stopencoding + +\endinput diff --git a/tex/context/base/enco-com.mkii b/tex/context/base/enco-com.mkii new file mode 100644 index 000000000..42d0d4774 --- /dev/null +++ b/tex/context/base/enco-com.mkii @@ -0,0 +1,37 @@ +%D \module +%D [ file=enco-com, +%D version=2000.20.12, % split from base file +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=Composed Characters Commands, +%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. + +%D Here we map some \quote {short} names onto the more +%D verbose glyph names. + +\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} + +\endinput diff --git a/tex/context/base/enco-cyr.mkii b/tex/context/base/enco-cyr.mkii new file mode 100644 index 000000000..36bca82b5 --- /dev/null +++ b/tex/context/base/enco-cyr.mkii @@ -0,0 +1,1037 @@ +%D \module +%D [ file=enco-cyr, +%D version=2003.01.24, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=Cyrillic, +%D author=..., +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 kerning test is inspired by a test file +%D provided by Victor Figurnov. I hope he still recognizes +%D some bit and pieces. +%D +%D \starttyping +%D \setupoutput[pdftex] +%D +%D \startMPenvironment[global] +%D \useregime[cyr] +%D \useencoding[cyr] +%D \mainlanguage[ru] +%D \enableregime[cp1251] +%D \setupbodyfont[cyr] +%D \stopMPenvironment +%D +%D \startbuffer +%D \starttabulate[|l|l|l|] +%D \NC \ruledhbox{} \NC \ruledhbox{AV} \NC with kerning \NC \NR +%D \NC \ruledhbox{{}{}} \NC \ruledhbox{A{}V} \NC without kerning \NC \NR +%D \NC \ruledhbox{\tfd } \NC \ruledhbox{\tfd AV} \NC with kerning \NC \NR +%D \NC \ruledhbox{\tfd {}{}} \NC \ruledhbox{\tfd A{}V} \NC without kerning \NC \NR +%D \stoptabulate +%D +%D \showkerning{ } +%D \stopbuffer +%D +%D \starttext +%D +%D \title{Kerning test} +%D +%D \typebuffer +%D +%D \rm \subject{Serif font} \getbuffer +%D \ss \subject{SansSerif font} \getbuffer +%D \tt \subject{MonoSpacec font} \getbuffer +%D +%D \stoptext +%D \stoptyping + +%D We start with a fallback, define by HH, who assumes that +%D this is phonetic. + +\startmapping[t2a] + +\resetcaserange 128 to 255 + +\definecasemaps 192 to 223 lc +32 uc 0 % base letters (russian) +\definecasemaps 224 to 255 lc 0 uc -32 + +\definecasemaps 128 to 156 lc +32 uc 0 % extra letters (cyrillic and old-slav) +\definecasemaps 160 to 188 lc 0 uc -32 + +\definecasemap 73 105 73 \definecasemap 105 105 73 % cyrillicII +\definecasemap 74 106 74 \definecasemap 106 106 74 % cyrillicJE +\definecasemap 81 113 81 \definecasemap 113 113 81 % cyrillicQ +\definecasemap 87 119 87 \definecasemap 119 119 87 % cyrillicW + +\stopmapping + +\startencoding[t2a] + +\definecharacter textgrave 0 +\definecharacter textacute 1 +\definecharacter textcircumflex 2 +\definecharacter texttilde 3 +\definecharacter textdiaeresis 4 +\definecharacter texthungarumlaut 5 +\definecharacter textring 6 +\definecharacter textcaron 7 +\definecharacter textbreve 8 +\definecharacter textmacron 9 +\definecharacter textdotaccent 10 +\definecharacter textcedilla 11 +\definecharacter textogonek 12 + +\definecharacter textcyrillicflex 18 +\definecharacter textdblgrave 19 +\definecharacter textcyrillicbreve 20 + +\definecharacter endash 21 +\definecharacter emdash 22 + +\definecharacter textcompwordmark 23 +\definecharacter textbackslash 92 +\definecharacter textasciicircum 94 +\definecharacter textunderscore 95 +\definecharacter textbraceleft 123 +\definecharacter textbraceright 125 +\definecharacter textasciitilde 126 +\definecharacter textnumero 157 +\definecharacter textcurrency 158 +\definecharacter sectionmark 159 + +\definecharacter quotedbl 34 +\definecharacter quoteleft 96 +\definecharacter upperleftsingleninequote 39 +\definecharacter quotedblleft 16 +\definecharacter quotedblright 17 +\definecharacter lowerleftdoubleninequote 189 +\definecharacter upperrightdoublesixquote 16 +\definecharacter upperrightdoubleninequote 17 +\definecharacter quotedblbase 189 + +\definecharacter cyrillicpalochka 13 +\definecharacter cyrilliclangle 14 +\definecharacter cyrillicrangle 15 + +\definecharacter leftguillemot 190 +\definecharacter rightguillemot 191 +\definecharacter dotlessi 25 + +\definecharacter cyrillicA 192 +\definecharacter cyrillica 224 +\definecharacter cyrillicB 193 +\definecharacter cyrillicb 225 +\definecharacter cyrillicV 194 +\definecharacter cyrillicv 226 +\definecharacter cyrillicG 195 +\definecharacter cyrillicg 227 +\definecharacter cyrillicD 196 +\definecharacter cyrillicd 228 +\definecharacter cyrillicE 197 +\definecharacter cyrillice 229 +\definecharacter cyrillicZH 198 +\definecharacter cyrilliczh 230 +\definecharacter cyrillicZ 199 +\definecharacter cyrillicz 231 +\definecharacter cyrillicI 200 +\definecharacter cyrillici 232 +\definecharacter cyrillicISHRT 201 +\definecharacter cyrillicishrt 233 +\definecharacter cyrillicK 202 +\definecharacter cyrillick 234 +\definecharacter cyrillicL 203 +\definecharacter cyrillicl 235 +\definecharacter cyrillicM 204 +\definecharacter cyrillicm 236 +\definecharacter cyrillicN 205 +\definecharacter cyrillicn 237 +\definecharacter cyrillicO 206 +\definecharacter cyrillico 238 +\definecharacter cyrillicP 207 +\definecharacter cyrillicp 239 +\definecharacter cyrillicR 208 +\definecharacter cyrillicr 240 +\definecharacter cyrillicS 209 +\definecharacter cyrillics 241 +\definecharacter cyrillicT 210 +\definecharacter cyrillict 242 +\definecharacter cyrillicU 211 +\definecharacter cyrillicu 243 +\definecharacter cyrillicF 212 +\definecharacter cyrillicf 244 +\definecharacter cyrillicH 213 +\definecharacter cyrillich 245 +\definecharacter cyrillicC 214 +\definecharacter cyrillicc 246 +\definecharacter cyrillicCH 215 +\definecharacter cyrillicch 247 +\definecharacter cyrillicSH 216 +\definecharacter cyrillicsh 248 +\definecharacter cyrillicSHCH 217 +\definecharacter cyrillicshch 249 +\definecharacter cyrillicHRDSN 218 +\definecharacter cyrillichrdsn 250 +\definecharacter cyrillicERY 219 +\definecharacter cyrillicery 251 +\definecharacter cyrillicSFTSN 220 +\definecharacter cyrillicsftsn 252 +\definecharacter cyrillicEREV 221 +\definecharacter cyrillicerev 253 +\definecharacter cyrillicYU 222 +\definecharacter cyrillicyu 254 +\definecharacter cyrillicYA 223 +\definecharacter cyrillicya 255 +\definecharacter cyrillicGUP 128 +\definecharacter cyrillicgup 160 +\definecharacter cyrillicGHCRS 129 +\definecharacter cyrillicghcrs 161 +\definecharacter cyrillicDJE 130 +\definecharacter cyrillicdje 162 +\definecharacter cyrillicTSHE 131 +\definecharacter cyrillictshe 163 +\definecharacter cyrillicSHHA 132 +\definecharacter cyrillicshha 164 +\definecharacter cyrillicZHDSC 133 +\definecharacter cyrilliczhdsc 165 +\definecharacter cyrillicZDSC 134 +\definecharacter cyrilliczdsc 166 +\definecharacter cyrillicLJE 135 +\definecharacter cyrilliclje 167 +\definecharacter cyrillicYI 136 +\definecharacter cyrillicyi 168 +\definecharacter cyrillicKDSC 137 +\definecharacter cyrillickdsc 169 +\definecharacter cyrillicKBEAK 138 +\definecharacter cyrillickbeak 170 +\definecharacter cyrillicKVCRS 139 +\definecharacter cyrillickvcrs 171 +\definecharacter cyrillicAE 140 +\definecharacter cyrillicae 172 +\definecharacter cyrillicNDSC 141 +\definecharacter cyrillicndsc 173 +\definecharacter cyrillicNG 142 +\definecharacter cyrillicng 174 +\definecharacter cyrillicDZE 143 +\definecharacter cyrillicdze 175 +\definecharacter cyrillicOTLD 144 +\definecharacter cyrillicotld 176 +\definecharacter cyrillicSDSC 145 +\definecharacter cyrillicsdsc 177 +\definecharacter cyrillicUSHRT 146 +\definecharacter cyrillicushrt 178 +\definecharacter cyrillicY 147 +\definecharacter cyrillicy 179 +\definecharacter cyrillicYHCRS 148 +\definecharacter cyrillicyhcrs 180 +\definecharacter cyrillicHDSC 149 +\definecharacter cyrillichdsc 181 +\definecharacter cyrillicDZHE 150 +\definecharacter cyrillicdzhe 182 +\definecharacter cyrillicCHVCRS 151 +\definecharacter cyrillicchvcrs 183 +\definecharacter cyrillicCHRDSC 152 +\definecharacter cyrillicchrdsc 184 +\definecharacter cyrillicIE 153 +\definecharacter cyrillicie 185 +\definecharacter cyrillicSCHWA 154 +\definecharacter cyrillicschwa 186 +\definecharacter cyrillicNJE 155 +\definecharacter cyrillicnje 187 +\definecharacter cyrillicYO 156 +\definecharacter cyrillicyo 188 +\definecharacter cyrillicII 73 +\definecharacter cyrillicii 105 +\definecharacter cyrillicJE 74 +\definecharacter cyrillicje 106 +\definecharacter cyrillicQ 81 +\definecharacter cyrillicq 113 +\definecharacter cyrillicW 87 +\definecharacter cyrillicw 119 + +% \definecharacter textperthousand {\%\char 24 } +% \definecharacter textpertenthousand {\%\char 24\char 24 } + +\definecharacter cyrillicgheupturn 160 % to satisfy the patterns + +\stopencoding + +\startmapping[t2b] + +\resetcaserange 128 to 255 + +\definecasemaps 192 to 223 lc +32 uc 0 % base letters (russian) +\definecasemaps 224 to 255 lc 0 uc -32 + +\definecasemaps 128 to 156 lc +32 uc 0 % extra letters (cyrillic and old-slav) +\definecasemaps 160 to 188 lc 0 uc -32 + +\definecasemap 73 105 73 \definecasemap 105 105 73 % cyrillicII +\definecasemap 74 106 74 \definecasemap 106 106 74 % cyrillicJE +\definecasemap 81 113 81 \definecasemap 113 113 81 % cyrillicQ +\definecasemap 83 115 83 \definecasemap 115 115 83 % cyrillicDZE +\definecasemap 87 119 87 \definecasemap 119 119 87 % cyrillicW + +\stopmapping + +\startencoding[t2b] + +\definecharacter textgrave 0 +\definecharacter textacute 1 +\definecharacter textcircumflex 2 +\definecharacter texttilde 3 +\definecharacter textdiaeresis 4 +\definecharacter texthungarumlaut 5 +\definecharacter textring 6 +\definecharacter textcaron 7 +\definecharacter textbreve 8 +\definecharacter textmacron 9 +\definecharacter textdotaccent 10 +\definecharacter textcedilla 11 +\definecharacter textogonek 12 + +\definecharacter textcyrillicflex 18 +\definecharacter textdblgrave 19 +\definecharacter textcyrillicbreve 20 + +\definecharacter endash 21 +\definecharacter emdash 22 + +\definecharacter textcompwordmark 23 +\definecharacter textbackslash 92 +\definecharacter textasciicircum 94 +\definecharacter textunderscore 95 +\definecharacter textbraceleft 123 +\definecharacter textbraceright 125 +\definecharacter textasciitilde 126 +\definecharacter textnumero 157 +\definecharacter textcurrency 158 +\definecharacter sectionmark 159 +\definecharacter quotedbl 34 +\definecharacter quoteleft 96 +\definecharacter upperleftsingleninequote 39 +\definecharacter quotedblleft 16 +\definecharacter quotedblright 17 +\definecharacter lowerleftdoubleninequote 189 + +\definecharacter upperrightdoublesixquote 16 +\definecharacter upperrightdoubleninequote 17 +\definecharacter quotedblbase 189 + +\definecharacter cyrillicpalochka 13 +\definecharacter cyrilliclangle 14 +\definecharacter cyrillicrangle 15 + +\definecharacter leftguillemot 190 +\definecharacter rightguillemot 191 +\definecharacter dotlessi 25 + +\definecharacter cyrillicA 192 +\definecharacter cyrillica 224 +\definecharacter cyrillicB 193 +\definecharacter cyrillicb 225 +\definecharacter cyrillicV 194 +\definecharacter cyrillicv 226 +\definecharacter cyrillicG 195 +\definecharacter cyrillicg 227 +\definecharacter cyrillicD 196 +\definecharacter cyrillicd 228 +\definecharacter cyrillicE 197 +\definecharacter cyrillice 229 +\definecharacter cyrillicZH 198 +\definecharacter cyrilliczh 230 +\definecharacter cyrillicZ 199 +\definecharacter cyrillicz 231 +\definecharacter cyrillicI 200 +\definecharacter cyrillici 232 +\definecharacter cyrillicISHRT 201 +\definecharacter cyrillicishrt 233 +\definecharacter cyrillicK 202 +\definecharacter cyrillick 234 +\definecharacter cyrillicL 203 +\definecharacter cyrillicl 235 +\definecharacter cyrillicM 204 +\definecharacter cyrillicm 236 +\definecharacter cyrillicN 205 +\definecharacter cyrillicn 237 +\definecharacter cyrillicO 206 +\definecharacter cyrillico 238 +\definecharacter cyrillicP 207 +\definecharacter cyrillicp 239 +\definecharacter cyrillicR 208 +\definecharacter cyrillicr 240 +\definecharacter cyrillicS 209 +\definecharacter cyrillics 241 +\definecharacter cyrillicT 210 +\definecharacter cyrillict 242 +\definecharacter cyrillicU 211 +\definecharacter cyrillicu 243 +\definecharacter cyrillicF 212 +\definecharacter cyrillicf 244 +\definecharacter cyrillicH 213 +\definecharacter cyrillich 245 +\definecharacter cyrillicC 214 +\definecharacter cyrillicc 246 +\definecharacter cyrillicCH 215 +\definecharacter cyrillicch 247 +\definecharacter cyrillicSH 216 +\definecharacter cyrillicsh 248 +\definecharacter cyrillicSHCH 217 +\definecharacter cyrillicshch 249 +\definecharacter cyrillicHRDSN 218 +\definecharacter cyrillichrdsn 250 +\definecharacter cyrillicERY 219 +\definecharacter cyrillicery 251 +\definecharacter cyrillicSFTSN 220 +\definecharacter cyrillicsftsn 252 +\definecharacter cyrillicEREV 221 +\definecharacter cyrillicerev 253 +\definecharacter cyrillicYU 222 +\definecharacter cyrillicyu 254 +\definecharacter cyrillicYA 223 +\definecharacter cyrillicya 255 +\definecharacter cyrillicGDSCHCRS 128 +\definecharacter cyrillicgdschcrs 160 +\definecharacter cyrillicGHCRS 129 +\definecharacter cyrillicghcrs 161 +\definecharacter cyrillicGDSC 130 +\definecharacter cyrillicgdsc 162 +\definecharacter cyrillicGHK 131 +\definecharacter cyrillicghk 163 +\definecharacter cyrillicSHHA 132 +\definecharacter cyrillicshha 164 +\definecharacter cyrillicZHDSC 133 +\definecharacter cyrilliczhdsc 165 +\definecharacter cyrillicDELTA 134 +\definecharacter cyrillicdelta 166 +\definecharacter cyrillicABHDZE 135 +\definecharacter cyrillicabhdze 167 +\definecharacter cyrillicLJE 136 +\definecharacter cyrilliclje 168 +\definecharacter cyrillicKDSC 137 +\definecharacter cyrillickdsc 169 +\definecharacter cyrillicLDSC 138 +\definecharacter cyrillicldsc 170 +\definecharacter cyrillicKHK 139 +\definecharacter cyrillickhk 171 +\definecharacter cyrillicLHK 140 +\definecharacter cyrilliclhk 172 +\definecharacter cyrillicNDSC 141 +\definecharacter cyrillicndsc 173 +\definecharacter cyrillicNG 142 +\definecharacter cyrillicng 174 +\definecharacter cyrillicNHK 143 +\definecharacter cyrillicnhk 175 +\definecharacter cyrillicOTLD 144 +\definecharacter cyrillicotld 176 +\definecharacter cyrillicSACRS 145 +\definecharacter cyrillicsacrs 177 +\definecharacter cyrillicUSHRT 146 +\definecharacter cyrillicushrt 178 +\definecharacter cyrillicY 147 +\definecharacter cyrillicy 179 +\definecharacter cyrillicHHCRS 148 +\definecharacter cyrillichhcrs 180 +\definecharacter cyrillicHDSC 149 +\definecharacter cyrillichdsc 181 +\definecharacter cyrillicHHK 150 +\definecharacter cyrillichhk 182 +\definecharacter cyrillicCHLDSC 151 +\definecharacter cyrillicchldsc 183 +\definecharacter cyrillicCHRDSC 152 +\definecharacter cyrillicchrdsc 184 +\definecharacter cyrillicNJE 153 +\definecharacter cyrillicnje 185 +\definecharacter cyrillicSCHWA 154 +\definecharacter cyrillicschwa 186 +\definecharacter cyrillicEPS 155 +\definecharacter cyrilliceps 187 +\definecharacter cyrillicYO 156 +\definecharacter cyrillicyo 188 +\definecharacter cyrillicII 73 +\definecharacter cyrillicii 105 +\definecharacter cyrillicJE 74 +\definecharacter cyrillicje 106 +\definecharacter cyrillicQ 81 +\definecharacter cyrillicq 113 +\definecharacter cyrillicDZE 83 +\definecharacter cyrillicdze 115 +\definecharacter cyrillicW 87 +\definecharacter cyrillicw 119 + +\stopencoding + +\startmapping[t2c] + +\resetcaserange 128 to 255 + +\definecasemaps 192 to 223 lc +32 uc 0 % base letters (russian) +\definecasemaps 224 to 255 lc 0 uc -32 + +\definecasemaps 128 to 156 lc +32 uc 0 % extra letters (cyrillic and old-slav) +\definecasemaps 160 to 188 lc 0 uc -32 + +\definecasemap 73 105 73 \definecasemap 105 105 73 % cyrillicII +\definecasemap 74 106 74 \definecasemap 106 106 74 % cyrillicJE +\definecasemap 81 113 81 \definecasemap 113 113 81 % cyrillicQ +\definecasemap 83 115 83 \definecasemap 115 115 83 % cyrillicDZE +\definecasemap 87 119 87 \definecasemap 119 119 87 % cyrillicW + +\stopmapping + +\startencoding[t2c] + +\definecharacter textgrave 0 +\definecharacter textacute 1 +\definecharacter textcircumflex 2 +\definecharacter texttilde 3 +\definecharacter textdiaeresis 4 +\definecharacter texthungarumlaut 5 +\definecharacter textring 6 +\definecharacter textcaron 7 +\definecharacter textbreve 8 +\definecharacter textmacron 9 +\definecharacter textdotaccent 10 +\definecharacter textcedilla 11 +\definecharacter textogonek 12 + +\definecharacter textcyrillicflex 18 +\definecharacter textdblgrave 19 +\definecharacter textcyrillicbreve 20 + +\definecharacter endash 21 +\definecharacter emdash 22 + +\definecharacter textcompwordmark 23 +\definecharacter textbackslash 92 +\definecharacter textasciicircum 94 +\definecharacter textunderscore 95 +\definecharacter textbraceleft 123 +\definecharacter textbraceright 125 +\definecharacter textasciitilde 126 +\definecharacter textnumero 157 +\definecharacter textcurrency 158 +\definecharacter sectionmark 159 +\definecharacter quotedbl 34 +\definecharacter quoteleft 96 +\definecharacter upperleftsingleninequote 39 +\definecharacter quotedblleft 16 +\definecharacter quotedblright 17 +\definecharacter lowerleftdoubleninequote 189 +\definecharacter upperrightdoublesixquote 16 +\definecharacter upperrightdoubleninequote 17 +\definecharacter quotedblbase 189 + +\definecharacter cyrillicpalochka 13 +\definecharacter cyrilliclangle 14 +\definecharacter cyrillicrangle 15 + +\definecharacter leftguillemot 190 +\definecharacter rightguillemot 191 + +\definecharacter dotlessi 25 + +\definecharacter cyrillicA 192 +\definecharacter cyrillica 224 +\definecharacter cyrillicB 193 +\definecharacter cyrillicb 225 +\definecharacter cyrillicV 194 +\definecharacter cyrillicv 226 +\definecharacter cyrillicG 195 +\definecharacter cyrillicg 227 +\definecharacter cyrillicD 196 +\definecharacter cyrillicd 228 +\definecharacter cyrillicE 197 +\definecharacter cyrillice 229 +\definecharacter cyrillicZH 198 +\definecharacter cyrilliczh 230 +\definecharacter cyrillicZ 199 +\definecharacter cyrillicz 231 +\definecharacter cyrillicI 200 +\definecharacter cyrillici 232 +\definecharacter cyrillicISHRT 201 +\definecharacter cyrillicishrt 233 +\definecharacter cyrillicK 202 +\definecharacter cyrillick 234 +\definecharacter cyrillicL 203 +\definecharacter cyrillicl 235 +\definecharacter cyrillicM 204 +\definecharacter cyrillicm 236 +\definecharacter cyrillicN 205 +\definecharacter cyrillicn 237 +\definecharacter cyrillicO 206 +\definecharacter cyrillico 238 +\definecharacter cyrillicP 207 +\definecharacter cyrillicp 239 +\definecharacter cyrillicR 208 +\definecharacter cyrillicr 240 +\definecharacter cyrillicS 209 +\definecharacter cyrillics 241 +\definecharacter cyrillicT 210 +\definecharacter cyrillict 242 +\definecharacter cyrillicU 211 +\definecharacter cyrillicu 243 +\definecharacter cyrillicF 212 +\definecharacter cyrillicf 244 +\definecharacter cyrillicH 213 +\definecharacter cyrillich 245 +\definecharacter cyrillicC 214 +\definecharacter cyrillicc 246 +\definecharacter cyrillicCH 215 +\definecharacter cyrillicch 247 +\definecharacter cyrillicSH 216 +\definecharacter cyrillicsh 248 +\definecharacter cyrillicSHCH 217 +\definecharacter cyrillicshch 249 +\definecharacter cyrillicHRDSN 218 +\definecharacter cyrillichrdsn 250 +\definecharacter cyrillicERY 219 +\definecharacter cyrillicery 251 +\definecharacter cyrillicSFTSN 220 +\definecharacter cyrillicsftsn 252 +\definecharacter cyrillicEREV 221 +\definecharacter cyrillicerev 253 +\definecharacter cyrillicYU 222 +\definecharacter cyrillicyu 254 +\definecharacter cyrillicYA 223 +\definecharacter cyrillicya 255 +\definecharacter cyrillicPHK 128 +\definecharacter cyrillicphk 160 +\definecharacter cyrillicTETSE 129 +\definecharacter cyrillictetse 161 +\definecharacter cyrillicTDSC 130 +\definecharacter cyrillictdsc 162 +\definecharacter cyrillicGHK 131 +\definecharacter cyrillicghk 163 +\definecharacter cyrillicSHHA 132 +\definecharacter cyrillicshha 164 +\definecharacter cyrillicRDSC 133 +\definecharacter cyrillicrdsc 165 +\definecharacter cyrillicRTICK 134 +\definecharacter cyrillicrtick 166 +\definecharacter cyrillicABHDZE 135 +\definecharacter cyrillicabhdze 167 +\definecharacter cyrillicMDSC 136 +\definecharacter cyrillicmdsc 168 +\definecharacter cyrillicKDSC 137 +\definecharacter cyrillickdsc 169 +\definecharacter cyrillicLDSC 138 +\definecharacter cyrillicldsc 170 +\definecharacter cyrillicKHCRS 139 +\definecharacter cyrillickhcrs 171 +\definecharacter cyrillicLHK 140 +\definecharacter cyrilliclhk 172 +\definecharacter cyrillicNDSC 141 +\definecharacter cyrillicndsc 173 +\definecharacter cyrillicMHK 142 +\definecharacter cyrillicmhk 174 +\definecharacter cyrillicNHK 143 +\definecharacter cyrillicnhk 175 +\definecharacter cyrillicOTLD 144 +\definecharacter cyrillicotld 176 +\definecharacter cyrillicABHCH 145 +\definecharacter cyrillicabhch 177 +\definecharacter cyrillicABHCHDSC 146 +\definecharacter cyrillicabhchdsc 178 +\definecharacter cyrillicSEMISFTSN 147 +\definecharacter cyrillicsemisftsn 179 +\definecharacter cyrillicISHRTDSC 148 +\definecharacter cyrillicishrtdsc 180 +\definecharacter cyrillicHDSC 149 +\definecharacter cyrillichdsc 181 +\definecharacter cyrillicDZHE 150 +\definecharacter cyrillicdzhe 182 +\definecharacter cyrillicABHHA 151 +\definecharacter cyrillicabhha 183 +\definecharacter cyrillicCHRDSC 152 +\definecharacter cyrillicchrdsc 184 +\definecharacter cyrillicNLHK 153 +\definecharacter cyrillicnlhk 185 +\definecharacter cyrillicSCHWA 154 +\definecharacter cyrillicschwa 186 +\definecharacter cyrillicRHK 155 +\definecharacter cyrillicrhk 187 +\definecharacter cyrillicYO 156 +\definecharacter cyrillicyo 188 +\definecharacter cyrillicII 73 +\definecharacter cyrillicii 105 +\definecharacter cyrillicJE 74 +\definecharacter cyrillicje 106 +\definecharacter cyrillicQ 81 +\definecharacter cyrillicq 113 +\definecharacter cyrillicDZE 83 +\definecharacter cyrillicdze 115 +\definecharacter cyrillicW 87 +\definecharacter cyrillicw 119 + +\stopencoding + +\startmapping[x2] + +\resetcaserange 128 to 255 + +\definecasemaps 192 to 223 lc +32 uc 0 % base letters (russian) +\definecasemaps 224 to 255 lc 0 uc -32 + +\definecasemaps 128 to 156 lc +32 uc 0 % extra letters (cyrillic and old-slav) +\definecasemaps 160 to 188 lc 0 uc -32 + +\definecasemaps 65 to 90 lc +32 uc 0 % more extra letters (cyrillic and old-slav) +\definecasemaps 97 to 122 lc 0 uc -32 + +\definecasemap 28 29 28 \definecasemap 29 29 28 % cyrillicNLHK +\definecasemap 30 31 30 \definecasemap 31 31 30 % cyrillicDELTA + +\stopmapping + +\startencoding[x2] + +\definecharacter textgrave 0 +\definecharacter textacute 1 +\definecharacter textcircumflex 2 +\definecharacter texttilde 3 +\definecharacter textdiaeresis 4 +\definecharacter texthungarumlaut 5 +\definecharacter textring 6 +\definecharacter textcaron 7 +\definecharacter textbreve 8 +\definecharacter textmacron 9 +\definecharacter textdotaccent 10 +\definecharacter textcedilla 11 +\definecharacter textogonek 12 + +\definecharacter endash 21 +\definecharacter emdash 22 + +\definecharacter textcompwordmark 23 +\definecharacter textvisiblespace 32 +\definecharacter textdollar 36 +\definecharacter textless 60 +\definecharacter textgreater 62 +\definecharacter textbackslash 92 +\definecharacter textasciicircum 94 +\definecharacter textunderscore 95 +\definecharacter textbraceleft 123 +\definecharacter textbar 124 +\definecharacter textbraceright 125 +\definecharacter textasciitilde 126 +\definecharacter textnumero 157 +\definecharacter textcurrency 158 +\definecharacter textsection 159 +\definecharacter sectionmark 159 +\definecharacter textquotedbl 34 + +\definecharacter cyrillicpalochka 13 +\definecharacter cyrilliclangle 14 +\definecharacter cyrillicrangle 15 + +\definecharacter leftguillemot 190 +\definecharacter rightguillemot 191 + +\definecharacter upperleftsinglesixquote 96 +\definecharacter upperleftsingleninequote 39 +\definecharacter upperleftdoublesixquote 16 +\definecharacter upperleftdoubleninequote 17 +\definecharacter lowerleftdoubleninequote 189 + +\definecharacter upperrightsinglesixquote 96 +\definecharacter upperrightsingleninequote 39 +\definecharacter upperrightdoublesixquote 16 +\definecharacter upperrightdoubleninequote 17 +\definecharacter lowerrightdoubleninequote 189 + +\definecharacter cyrillicA 192 +\definecharacter cyrillica 224 +\definecharacter cyrillicB 193 +\definecharacter cyrillicb 225 +\definecharacter cyrillicV 194 +\definecharacter cyrillicv 226 +\definecharacter cyrillicG 195 +\definecharacter cyrillicg 227 +\definecharacter cyrillicD 196 +\definecharacter cyrillicd 228 +\definecharacter cyrillicE 197 +\definecharacter cyrillice 229 +\definecharacter cyrillicZH 198 +\definecharacter cyrilliczh 230 +\definecharacter cyrillicZ 199 +\definecharacter cyrillicz 231 +\definecharacter cyrillicI 200 +\definecharacter cyrillici 232 +\definecharacter cyrillicISHRT 201 +\definecharacter cyrillicishrt 233 +\definecharacter cyrillicK 202 +\definecharacter cyrillick 234 +\definecharacter cyrillicL 203 +\definecharacter cyrillicl 235 +\definecharacter cyrillicM 204 +\definecharacter cyrillicm 236 +\definecharacter cyrillicN 205 +\definecharacter cyrillicn 237 +\definecharacter cyrillicO 206 +\definecharacter cyrillico 238 +\definecharacter cyrillicP 207 +\definecharacter cyrillicp 239 +\definecharacter cyrillicR 208 +\definecharacter cyrillicr 240 +\definecharacter cyrillicS 209 +\definecharacter cyrillics 241 +\definecharacter cyrillicT 210 +\definecharacter cyrillict 242 +\definecharacter cyrillicU 211 +\definecharacter cyrillicu 243 +\definecharacter cyrillicF 212 +\definecharacter cyrillicf 244 +\definecharacter cyrillicH 213 +\definecharacter cyrillich 245 +\definecharacter cyrillicC 214 +\definecharacter cyrillicc 246 +\definecharacter cyrillicCH 215 +\definecharacter cyrillicch 247 +\definecharacter cyrillicSH 216 +\definecharacter cyrillicsh 248 +\definecharacter cyrillicSHCH 217 +\definecharacter cyrillicshch 249 +\definecharacter cyrillicHRDSN 218 +\definecharacter cyrillichrdsn 250 +\definecharacter cyrillicERY 219 +\definecharacter cyrillicery 251 +\definecharacter cyrillicSFTSN 220 +\definecharacter cyrillicsftsn 252 +\definecharacter cyrillicEREV 221 +\definecharacter cyrillicerev 253 +\definecharacter cyrillicYU 222 +\definecharacter cyrillicyu 254 +\definecharacter cyrillicYA 223 +\definecharacter cyrillicya 255 +\definecharacter cyrillicGUP 128 +\definecharacter cyrillicgup 160 +\definecharacter cyrillicGHCRS 129 +\definecharacter cyrillicghcrs 161 +\definecharacter cyrillicGDSC 130 +\definecharacter cyrillicgdsc 162 +\definecharacter cyrillicGHK 131 +\definecharacter cyrillicghk 163 +\definecharacter cyrillicSHHA 132 +\definecharacter cyrillicshha 164 +\definecharacter cyrillicZHDSC 133 +\definecharacter cyrilliczhdsc 165 +\definecharacter cyrillicZDSC 134 +\definecharacter cyrilliczdsc 166 +\definecharacter cyrillicABHDZE 135 +\definecharacter cyrillicabhdze 167 +\definecharacter cyrillicYI 136 +\definecharacter cyrillicyi 168 +\definecharacter cyrillicKDSC 137 +\definecharacter cyrillickdsc 169 +\definecharacter cyrillicKBEAK 138 +\definecharacter cyrillickbeak 170 +\definecharacter cyrillicKHK 139 +\definecharacter cyrillickhk 171 +\definecharacter cyrillicLHK 140 +\definecharacter cyrilliclhk 172 +\definecharacter cyrillicNDSC 141 +\definecharacter cyrillicndsc 173 +\definecharacter cyrillicNG 142 +\definecharacter cyrillicng 174 +\definecharacter cyrillicNHK 143 +\definecharacter cyrillicnhk 175 +\definecharacter cyrillicOTLD 144 +\definecharacter cyrillicotld 176 +\definecharacter cyrillicSDSC 145 +\definecharacter cyrillicsdsc 177 +\definecharacter cyrillicUSHRT 146 +\definecharacter cyrillicushrt 178 +\definecharacter cyrillicY 147 +\definecharacter cyrillicy 179 +\definecharacter cyrillicYHCRS 148 +\definecharacter cyrillicyhcrs 180 +\definecharacter cyrillicHDSC 149 +\definecharacter cyrillichdsc 181 +\definecharacter cyrillicHHK 150 +\definecharacter cyrillichhk 182 +\definecharacter cyrillicCHLDSC 151 +\definecharacter cyrillicchldsc 183 +\definecharacter cyrillicCHRDSC 152 +\definecharacter cyrillicchrdsc 184 +\definecharacter cyrillicIE 153 +\definecharacter cyrillicie 185 +\definecharacter cyrillicSCHWA 154 +\definecharacter cyrillicschwa 186 +\definecharacter cyrillicEPS 155 +\definecharacter cyrilliceps 187 +\definecharacter cyrillicYO 156 +\definecharacter cyrillicyo 188 +\definecharacter cyrillicAE 65 +\definecharacter cyrillicae 97 +\definecharacter cyrillicDJE 66 +\definecharacter cyrillicdje 98 +\definecharacter cyrillicTSHE 67 +\definecharacter cyrillictshe 99 +\definecharacter cyrillicABHCH 68 +\definecharacter cyrillicabhch 100 +\definecharacter cyrillicABHCHDSC 69 +\definecharacter cyrillicabhchdsc 101 +\definecharacter cyrillicKVCRS 70 +\definecharacter cyrillickvcrs 102 +\definecharacter cyrillicKHCRS 71 +\definecharacter cyrillickhcrs 103 +\definecharacter cyrillicLDSC 72 +\definecharacter cyrillicldsc 104 +\definecharacter cyrillicII 73 +\definecharacter cyrillicii 105 +\definecharacter cyrillicJE 74 +\definecharacter cyrillicje 106 +\definecharacter cyrillicLJE 75 +\definecharacter cyrilliclje 107 +\definecharacter cyrillicMDSC 76 +\definecharacter cyrillicmdsc 108 +\definecharacter cyrillicNJE 77 +\definecharacter cyrillicnje 109 +\definecharacter cyrillicABHHA 78 +\definecharacter cyrillicabhha 110 +\definecharacter cyrillicPHK 79 +\definecharacter cyrillicphk 111 +\definecharacter cyrillicRDSC 80 +\definecharacter cyrillicrdsc 112 +\definecharacter cyrillicQ 81 +\definecharacter cyrillicq 113 +\definecharacter cyrillicTDSC 82 +\definecharacter cyrillictdsc 114 +\definecharacter cyrillicDZE 83 +\definecharacter cyrillicdze 115 +\definecharacter cyrillicTETSE 84 +\definecharacter cyrillictetse 116 +\definecharacter cyrillicDZHE 85 +\definecharacter cyrillicdzhe 117 +\definecharacter cyrillicCHVCRS 86 +\definecharacter cyrillicchvcrs 118 +\definecharacter cyrillicW 87 +\definecharacter cyrillicw 119 +\definecharacter cyrillicYAT 88 +\definecharacter cyrillicyat 120 +\definecharacter cyrillicBYUS 89 +\definecharacter cyrillicbyus 121 +\definecharacter cyrillicIZH 90 +\definecharacter cyrillicizh 122 +\definecharacter cyrillicNLHK 28 +\definecharacter cyrillicnlhk 29 +\definecharacter cyrillicDELTA 30 +\definecharacter cyrillicdelta 31 + +\stopencoding + +\startmapping[lcy] + +\resetcaserange 128 to 255 + +\definecasemaps 128 to 143 lc +32 uc 0 +\definecasemaps 160 to 175 lc 0 uc -32 + +\definecasemaps 144 to 159 lc +80 uc 0 +\definecasemaps 224 to 239 lc 0 uc -80 + +\definecasemap 240 241 240 \definecasemap 241 241 240 % cyrillicYO +\definecasemap 242 243 242 \definecasemap 243 243 242 % cyrillicGUP +\definecasemap 244 245 244 \definecasemap 245 245 244 % cyrillicIE +\definecasemap 244 247 244 \definecasemap 247 247 244 % cyrillicII +\definecasemap 248 249 248 \definecasemap 249 249 248 % cyrillicYI +\definecasemap 250 251 240 \definecasemap 241 241 240 % cyrillicUSHRT + +\stopmapping + +\startencoding[lcy] + +%D Characters 0 to 127 are as in normal cmr slots + +\definecharacter cyrillicA 128 +\definecharacter cyrillicB 129 +\definecharacter cyrillicV 130 +\definecharacter cyrillicG 131 +\definecharacter cyrillicD 132 +\definecharacter cyrillicE 133 +\definecharacter cyrillicZH 134 +\definecharacter cyrillicZ 135 +\definecharacter cyrillicI 136 +\definecharacter cyrillicISHRT 137 +\definecharacter cyrillicK 138 +\definecharacter cyrillicL 139 +\definecharacter cyrillicM 140 +\definecharacter cyrillicN 141 +\definecharacter cyrillicO 142 +\definecharacter cyrillicP 143 +\definecharacter cyrillicR 144 +\definecharacter cyrillicS 145 +\definecharacter cyrillicT 146 +\definecharacter cyrillicU 147 +\definecharacter cyrillicF 148 +\definecharacter cyrillicH 149 +\definecharacter cyrillicC 150 +\definecharacter cyrillicCH 151 +\definecharacter cyrillicSH 152 +\definecharacter cyrillicSHCH 153 +\definecharacter cyrillicHRDSN 154 +\definecharacter cyrillicERY 155 +\definecharacter cyrillicSFTSN 156 +\definecharacter cyrillicEREV 157 +\definecharacter cyrillicYU 158 +\definecharacter cyrillicYA 159 +\definecharacter cyrillica 160 +\definecharacter cyrillicb 161 +\definecharacter cyrillicv 162 +\definecharacter cyrillicg 163 +\definecharacter cyrillicd 164 +\definecharacter cyrillice 165 +\definecharacter cyrilliczh 166 +\definecharacter cyrillicz 167 +\definecharacter cyrillici 168 +\definecharacter cyrillicishrt 169 +\definecharacter cyrillick 170 +\definecharacter cyrillicl 171 +\definecharacter cyrillicm 172 +\definecharacter cyrillicn 173 +\definecharacter cyrillico 174 +\definecharacter cyrillicp 175 +\definecharacter cyrillicr 224 +\definecharacter cyrillics 225 +\definecharacter cyrillict 226 +\definecharacter cyrillicu 227 +\definecharacter cyrillicf 228 +\definecharacter cyrillich 229 +\definecharacter cyrillicc 230 +\definecharacter cyrillicch 231 +\definecharacter cyrillicsh 232 +\definecharacter cyrillicshch 233 +\definecharacter cyrillichrdsn 234 +\definecharacter cyrillicery 235 +\definecharacter cyrillicsftsn 236 +\definecharacter cyrillicerev 237 +\definecharacter cyrillicyu 238 +\definecharacter cyrillicya 239 +\definecharacter cyrillicYO 240 +\definecharacter cyrillicyo 241 +\definecharacter cyrillicGUP 242 +\definecharacter cyrillicgup 243 +\definecharacter cyrillicIE 244 +\definecharacter cyrillicie 245 +\definecharacter cyrillicII 246 +\definecharacter cyrillicii 247 +\definecharacter cyrillicYI 248 +\definecharacter cyrillicyi 249 +\definecharacter cyrillicUSHRT 250 +\definecharacter cyrillicushrt 251 + +\definecharacter emdash 196 +\definecharacter textcurrency 197 +\definecharacter textnumero 252 +\definecharacter leftguillemot 253 +\definecharacter rightguillemot 254 +\definecharacter quotedblbase 255 + +\stopencoding + +\endinput diff --git a/tex/context/base/enco-def.mkii b/tex/context/base/enco-def.mkii new file mode 100644 index 000000000..4d8e280cb --- /dev/null +++ b/tex/context/base/enco-def.mkii @@ -0,0 +1,922 @@ +%D \module +%D [ file=enco-def, +%D version=2000.05.07, % 2000.20.12, % split from less verbose base file +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=Default Character Definitions, +%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. + +%D Instead of overloading plain \TEX\ macros (and keeping them +%D available as an escape), we now use the more verbose +%D definitions in this file. Since memory is less a problem +%D these days, this verbosity has only a small price, but we +%D gain readability. The following definitions are based on +%D usage of the the original \TEX\ fonts, where composed +%D characters were not part of the design. So, occasionally +%D we have to revert to hacks. Thanks to all those users who +%D helped me to fill in the details. + +\startencoding[default] + +\definecharacter textcomma , +\definecharacter textperiod . + +\definecharacter textacute 19 +\definecharacter textbottomdot 46 +\definecharacter textbreve 21 +\definecharacter textcaron 20 +\definecharacter textcedilla 24 +\definecharacter textcircumflex 94 +\definecharacter textdiaeresis 127 +\definecharacter textdotaccent 95 +\definecharacter textgrave 18 +\definecharacter texthungarumlaut 125 +\definecharacter textmacron 22 +\definecharacter textogonek 24 % fake +\definecharacter textring 23 +\definecharacter texttilde 126 + +\definecharacter textat 64 % for mojca + +\definecharacter textbottomcomma {\hbox{\lower.35ex\hbox{\tx,}}} % for mojca + +\definecharacter dotlessi {\char"10 } +\definecharacter dotlessj {\char"11 } +\definecharacter dotlessI {I} +\definecharacter dotlessJ {J} + +\definecharacter endash 123 +\definecharacter emdash 124 + +\definecharacter aeligature {\char26 } % "1A +\definecharacter AEligature {\char29 } % "1D +\definecharacter ijligature {ij} +\definecharacter IJligature {IJ} +\definecharacter oeligature {\char27 } % "1B +\definecharacter OEligature {\char30 } % "1E + +\definecharacter ssharp {\char25 } % "19 +\definecharacter Ssharp {SS} + +\definecharacter thorn {\unknownchar} +\definecharacter Thorn {\unknownchar} + +\definecharacter eth {\unknownchar} % mojca prefers this (was \dstroke) +%definecharacter Eth {\unknownchar} +\definecharacter Eth {\Dstroke} % mojca prefers this too + +\definecharacter exclamdown 60 +\definecharacter questiondown 62 + +\definecharacter copyright {\encircled{\txx C}} +\definecharacter registered {\encircled{\txx R}} +\definecharacter trademark {\high{\txx TM}} + +\definecharacter sectionmark {\mathematics{\mathhexbox278}} +\definecharacter paragraphmark {\mathematics{\mathhexbox27B}} + +\definecharacter onequarter {\vulgarfraction{1}{4}} +\definecharacter onehalf {\vulgarfraction{1}{2}} +\definecharacter threequarter {\vulgarfraction{3}{4}} + +\definecharacter onesuperior {\high{1}} +\definecharacter twosuperior {\high{2}} +\definecharacter threesuperior {\high{3}} + +\definecharacter textcent {c} +\definecharacter textcurrency {\unknownchar} +\definecharacter textdollar {\fakedollar} +\definecharacter texteuro {E} +\definecharacter textflorin {\fakeflorin} +\definecharacter textsterling {\fakesterling} +\definecharacter textyen {Y} + +\definecharacter ordfeminine {\high{\txx a}} +\definecharacter ordmasculine {\high{\txx o}} + +\definecharacter percent {\fakepercent} +\definecharacter perthousand {\fakeperthousand} + +\definecharacter softhyphen 45 +\definecharacter periodcentered {\hbox{\mathematics\cdot}} +\definecharacter compoundwordmark 23 + +\definecharacter textasciicircum 94 +\definecharacter textasciitilde 126 +\definecharacter textslash 47 +\definecharacter textbackslash {\tex{}} % todo +\definecharacter textbraceleft {\mathematics\{} +\definecharacter textbraceright {\mathematics\}} +\definecharacter textunderscore {\fakeunderscore} +\definecharacter textvisiblespace {\fakevisiblespace} + +\definecharacter textbrokenbar {\mathematics\vert} +\definecharacter textbullet {\mathematics\bullet} +\definecharacter textdag {\mathematics\dag} +\definecharacter textddag {\mathematics\ddag} +\definecharacter textdegree {\mathematics{{}^{\circ}}} +\definecharacter textdiv {\mathematics\div} +\definecharacter textellipsis {\mathematics\cdots} +\definecharacter textfraction {\mathematics/} +\definecharacter textlognot {\mathematics\neg} +\definecharacter textminus {\mathematics-} +\definecharacter textmu {\mathematics\mu} +\definecharacter textmultiply {\mathematics\times} +\definecharacter textpm {\mathematics\pm} + +\definecharacter quotedbl {"} +\definecharacter quotedblbase {,,} +\definecharacter quotedblleft {``} +\definecharacter quotedblright {''} + +\definecharacter quotesingle {`} +\definecharacter quotesinglebase {,} + +\definecharacter quoteleft {`} +\definecharacter quoteright {'} + +\definecharacter guilsingleleft {\fakeleftsubguillemot } +\definecharacter guilsingleright {\fakerightsubguillemot} + +\definecharacter leftguillemot {\fakeleftguillemot } +\definecharacter rightguillemot {\fakerightguillemot} + +\definecharacter Acircumflex {\buildtextaccent\textcircumflex A} +\definecharacter acircumflex {\buildtextaccent\textcircumflex a} +\definecharacter Ccircumflex {\buildtextaccent\textcircumflex C} +\definecharacter ccircumflex {\buildtextaccent\textcircumflex c} +\definecharacter Ecircumflex {\buildtextaccent\textcircumflex E} +\definecharacter ecircumflex {\buildtextaccent\textcircumflex e} +\definecharacter Gcircumflex {\buildtextaccent\textcircumflex G} +\definecharacter gcircumflex {\buildtextaccent\textcircumflex g} +\definecharacter Hcircumflex {\buildtextaccent\textcircumflex H} +\definecharacter hcircumflex {\buildtextaccent\textcircumflex h} +\definecharacter Icircumflex {\buildtextaccent\textcircumflex \dotlessI} +\definecharacter icircumflex {\buildtextaccent\textcircumflex \dotlessi} +\definecharacter Jcircumflex {\buildtextaccent\textcircumflex \dotlessJ} +\definecharacter jcircumflex {\buildtextaccent\textcircumflex \dotlessj} +\definecharacter Ocircumflex {\buildtextaccent\textcircumflex O} +\definecharacter ocircumflex {\buildtextaccent\textcircumflex o} +\definecharacter Scircumflex {\buildtextaccent\textcircumflex S} +\definecharacter scircumflex {\buildtextaccent\textcircumflex s} +\definecharacter Ucircumflex {\buildtextaccent\textcircumflex U} +\definecharacter ucircumflex {\buildtextaccent\textcircumflex u} +\definecharacter Wcircumflex {\buildtextaccent\textcircumflex W} +\definecharacter wcircumflex {\buildtextaccent\textcircumflex w} +\definecharacter Ycircumflex {\buildtextaccent\textcircumflex Y} +\definecharacter ycircumflex {\buildtextaccent\textcircumflex y} + +\definecharacter Agrave {\buildtextaccent\textgrave A} +\definecharacter agrave {\buildtextaccent\textgrave a} +\definecharacter Egrave {\buildtextaccent\textgrave E} +\definecharacter egrave {\buildtextaccent\textgrave e} +\definecharacter Igrave {\buildtextaccent\textgrave \dotlessI} +\definecharacter igrave {\buildtextaccent\textgrave \dotlessi} +\definecharacter Ograve {\buildtextaccent\textgrave O} +\definecharacter ograve {\buildtextaccent\textgrave o} +\definecharacter Ugrave {\buildtextaccent\textgrave U} +\definecharacter ugrave {\buildtextaccent\textgrave u} +\definecharacter Ygrave {\buildtextaccent\textgrave Y} +\definecharacter ygrave {\buildtextaccent\textgrave y} + +\definecharacter Atilde {\buildtextaccent\texttilde A} +\definecharacter atilde {\buildtextaccent\texttilde a} +\definecharacter Itilde {\buildtextaccent\texttilde \dotlessI} +\definecharacter itilde {\buildtextaccent\texttilde \dotlessi} +\definecharacter Ntilde {\buildtextaccent\texttilde N} +\definecharacter ntilde {\buildtextaccent\texttilde n} +\definecharacter Otilde {\buildtextaccent\texttilde O} +\definecharacter otilde {\buildtextaccent\texttilde o} +\definecharacter Utilde {\buildtextaccent\texttilde U} +\definecharacter utilde {\buildtextaccent\texttilde u} +\definecharacter Ytilde {\buildtextaccent\texttilde Y} +\definecharacter ytilde {\buildtextaccent\texttilde y} + +\definecharacter Adiaeresis {\buildtextaccent\textdiaeresis A} +\definecharacter adiaeresis {\buildtextaccent\textdiaeresis a} +\definecharacter Ediaeresis {\buildtextaccent\textdiaeresis E} +\definecharacter ediaeresis {\buildtextaccent\textdiaeresis e} +\definecharacter Idiaeresis {\buildtextaccent\textdiaeresis \dotlessI} +\definecharacter idiaeresis {\buildtextaccent\textdiaeresis \dotlessi} +\definecharacter Odiaeresis {\buildtextaccent\textdiaeresis O} +\definecharacter odiaeresis {\buildtextaccent\textdiaeresis o} +\definecharacter Udiaeresis {\buildtextaccent\textdiaeresis U} +\definecharacter udiaeresis {\buildtextaccent\textdiaeresis u} +\definecharacter Ydiaeresis {\buildtextaccent\textdiaeresis Y} +\definecharacter ydiaeresis {\buildtextaccent\textdiaeresis y} + +\definecharacter Aacute {\buildtextaccent\textacute A} +\definecharacter aacute {\buildtextaccent\textacute a} +\definecharacter Cacute {\buildtextaccent\textacute C} +\definecharacter cacute {\buildtextaccent\textacute c} +\definecharacter Eacute {\buildtextaccent\textacute E} +\definecharacter eacute {\buildtextaccent\textacute e} +\definecharacter Iacute {\buildtextaccent\textacute \dotlessI} +\definecharacter iacute {\buildtextaccent\textacute \dotlessi} +\definecharacter Lacute {\buildtextaccent\textacute L} +\definecharacter lacute {\buildtextaccent\textacute l} +\definecharacter Nacute {\buildtextaccent\textacute N} +\definecharacter nacute {\buildtextaccent\textacute n} +\definecharacter Oacute {\buildtextaccent\textacute O} +\definecharacter oacute {\buildtextaccent\textacute o} +\definecharacter Racute {\buildtextaccent\textacute R} +\definecharacter racute {\buildtextaccent\textacute r} +\definecharacter Sacute {\buildtextaccent\textacute S} +\definecharacter sacute {\buildtextaccent\textacute s} +\definecharacter Uacute {\buildtextaccent\textacute U} +\definecharacter uacute {\buildtextaccent\textacute u} +\definecharacter Yacute {\buildtextaccent\textacute Y} +\definecharacter yacute {\buildtextaccent\textacute y} +\definecharacter Zacute {\buildtextaccent\textacute Z} +\definecharacter zacute {\buildtextaccent\textacute z} + +%definecharacter Dstroke {D} +%definecharacter dstroke {d} + +\definecharacter dstroke {\pseudoencodeddj} +\definecharacter Dstroke {\pseudoencodedDJ} +\definecharacter Hstroke {H} +\definecharacter hstroke {h} +\definecharacter Tstroke {T} +\definecharacter tstroke {t} + +\definecharacter Cdotaccent {\buildtextaccent\textdotaccent C} +\definecharacter cdotaccent {\buildtextaccent\textdotaccent c} +\definecharacter Edotaccent {\buildtextaccent\textdotaccent E} +\definecharacter edotaccent {\buildtextaccent\textdotaccent e} +\definecharacter Gdotaccent {\buildtextaccent\textdotaccent G} +\definecharacter gdotaccent {\buildtextaccent\textdotaccent g} +\definecharacter Idotaccent {\buildtextaccent\textdotaccent \dotlessI} +\definecharacter idotaccent {\buildtextaccent\textdotaccent \dotlessi} +\definecharacter Zdotaccent {\buildtextaccent\textdotaccent Z} +\definecharacter zdotaccent {\buildtextaccent\textdotaccent z} + +\definecharacter Amacron {\buildtextaccent\textmacron A} +\definecharacter amacron {\buildtextaccent\textmacron a} +\definecharacter Emacron {\buildtextaccent\textmacron E} +\definecharacter emacron {\buildtextaccent\textmacron e} +\definecharacter Imacron {\buildtextaccent\textmacron \dotlessI} +\definecharacter imacron {\buildtextaccent\textmacron \dotlessi} +\definecharacter Omacron {\buildtextaccent\textmacron O} +\definecharacter omacron {\buildtextaccent\textmacron o} +\definecharacter Umacron {\buildtextaccent\textmacron U} +\definecharacter umacron {\buildtextaccent\textmacron u} + +\definecharacter Ccedilla {\buildtextcedilla C} +\definecharacter ccedilla {\buildtextcedilla c} +\definecharacter Kcedilla {\buildtextcedilla K} +\definecharacter kcedilla {\buildtextcedilla k} +\definecharacter Lcedilla {\buildtextcedilla L} +\definecharacter lcedilla {\buildtextcedilla l} +\definecharacter Ncedilla {\buildtextcedilla N} +\definecharacter ncedilla {\buildtextcedilla n} +\definecharacter Rcedilla {\buildtextcedilla R} +\definecharacter rcedilla {\buildtextcedilla r} +\definecharacter Scedilla {\buildtextcedilla S} +\definecharacter scedilla {\buildtextcedilla s} +\definecharacter Tcedilla {\buildtextcedilla T} +\definecharacter tcedilla {\buildtextcedilla t} + +\definecharacter Ohungarumlaut {\buildtextaccent\texthungarumlaut O} +\definecharacter ohungarumlaut {\buildtextaccent\texthungarumlaut o} +\definecharacter Uhungarumlaut {\buildtextaccent\texthungarumlaut U} +\definecharacter uhungarumlaut {\buildtextaccent\texthungarumlaut u} + +\definecharacter Aogonek {\buildtextogonek A} +\definecharacter aogonek {\buildtextogonek a} +\definecharacter Eogonek {\buildtextogonek E} +\definecharacter eogonek {\buildtextogonek e} +\definecharacter Iogonek {\buildtextogonek I} +\definecharacter iogonek {\buildtextogonek i} +\definecharacter Uogonek {\buildtextogonek U} +\definecharacter uogonek {\buildtextogonek u} + +\definecharacter Aring {\buildtextaccent\textring A} +\definecharacter aring {\buildtextaccent\textring a} +\definecharacter Uring {\buildtextaccent\textring U} +\definecharacter uring {\buildtextaccent\textring u} + +\definecharacter Abreve {\buildtextaccent\textbreve A} +\definecharacter abreve {\buildtextaccent\textbreve a} +\definecharacter Ebreve {\buildtextaccent\textbreve E} +\definecharacter ebreve {\buildtextaccent\textbreve e} +\definecharacter Gbreve {\buildtextaccent\textbreve G} +\definecharacter gbreve {\buildtextaccent\textbreve g} +\definecharacter Ibreve {\buildtextaccent\textbreve \dotlessI} +\definecharacter ibreve {\buildtextaccent\textbreve \dotlessi} +\definecharacter Obreve {\buildtextaccent\textbreve O} +\definecharacter obreve {\buildtextaccent\textbreve o} +\definecharacter Ubreve {\buildtextaccent\textbreve U} +\definecharacter ubreve {\buildtextaccent\textbreve u} + +\definecharacter Ccaron {\buildtextaccent\textcaron C} +\definecharacter ccaron {\buildtextaccent\textcaron c} +\definecharacter Dcaron {\buildtextaccent\textcaron D} +\definecharacter dcaron {\buildtextaccent\textcaron d} +\definecharacter Ecaron {\buildtextaccent\textcaron E} +\definecharacter ecaron {\buildtextaccent\textcaron e} +\definecharacter Lcaron {\buildtextaccent\textcaron L} +\definecharacter lcaron {\buildtextaccent\textcaron l} +\definecharacter Ncaron {\buildtextaccent\textcaron N} +\definecharacter ncaron {\buildtextaccent\textcaron n} +\definecharacter Rcaron {\buildtextaccent\textcaron R} +\definecharacter rcaron {\buildtextaccent\textcaron r} +\definecharacter Scaron {\buildtextaccent\textcaron S} +\definecharacter scaron {\buildtextaccent\textcaron s} +\definecharacter Tcaron {\buildtextaccent\textcaron T} +\definecharacter tcaron {\buildtextaccent\textcaron t} +\definecharacter Ycaron {\buildtextaccent\textcaron Y} +\definecharacter ycaron {\buildtextaccent\textcaron y} +\definecharacter Zcaron {\buildtextaccent\textcaron Z} +\definecharacter zcaron {\buildtextaccent\textcaron z} + +\definecharacter Lstroke {\hsmash{\char32}L} +\definecharacter lstroke {\hsmash{\char32}l} +\definecharacter Ostroke {\char31 } % "1F +\definecharacter ostroke {\char28 } % "1C + +\definecharacter aumlaut {\moveaccent{-.1ex}\adiaeresis} +\definecharacter eumlaut {\moveaccent{-.1ex}\ediaeresis} +\definecharacter iumlaut {\moveaccent{-.1ex}\idiaeresis} +\definecharacter oumlaut {\moveaccent{-.1ex}\odiaeresis} +\definecharacter uumlaut {\moveaccent{-.1ex}\udiaeresis} + +\definecharacter Aumlaut {\smashaccent\Adiaeresis} +\definecharacter Eumlaut {\smashaccent\Ediaeresis} +\definecharacter Iumlaut {\smashaccent\Idiaeresis} +\definecharacter Oumlaut {\smashaccent\Odiaeresis} +\definecharacter Uumlaut {\smashaccent\Udiaeresis} + +\definecharacter scommaaccent {\buildtextbottomcomma s} +\definecharacter Scommaaccent {\buildtextbottomcomma S} +\definecharacter tcommaaccent {\buildtextbottomcomma t} +\definecharacter Tcommaaccent {\buildtextbottomcomma T} +\definecharacter lcommaaccent {\buildtextbottomcomma l} +\definecharacter Lcommaaccent {\buildtextbottomcomma L} + +\definecharacter Etilde {\buildtextaccent\texttilde E} +\definecharacter etilde {\buildtextaccent\texttilde e} + +\definecharacter Ahook {A} +\definecharacter ahook {a} +\definecharacter Ehook {E} +\definecharacter ehook {e} +\definecharacter Ihook {I} +\definecharacter ihook {i} +\definecharacter Ohook {O} +\definecharacter ohook {o} +\definecharacter Uhook {U} +\definecharacter uhook {u} +\definecharacter Yhook {Y} +\definecharacter yhook {y} + +\definecharacter Acircumflexgrave {\Acircumflex} +\definecharacter Acircumflexacute {\Acircumflex} +\definecharacter Acircumflextilde {\Acircumflex} +\definecharacter Acircumflexhook {\Acircumflex} +\definecharacter acircumflexgrave {\acircumflex} +\definecharacter acircumflexacute {\acircumflex} +\definecharacter acircumflextilde {\acircumflex} +\definecharacter acircumflexhook {\acircumflex} +\definecharacter Ecircumflexgrave {\Ecircumflex} +\definecharacter Ecircumflexacute {\Ecircumflex} +\definecharacter Ecircumflextilde {\Ecircumflex} +\definecharacter Ecircumflexhook {\Ecircumflex} +\definecharacter ecircumflexgrave {\ecircumflex} +\definecharacter ecircumflexacute {\ecircumflex} +\definecharacter ecircumflextilde {\ecircumflex} +\definecharacter ecircumflexhook {\ecircumflex} +\definecharacter Ocircumflexgrave {\Ocircumflex} +\definecharacter Ocircumflexacute {\Ocircumflex} +\definecharacter Ocircumflextilde {\Ocircumflex} +\definecharacter Ocircumflexhook {\Ocircumflex} +\definecharacter ocircumflexgrave {\ocircumflex} +\definecharacter ocircumflexacute {\ocircumflex} +\definecharacter ocircumflextilde {\ocircumflex} +\definecharacter ocircumflexhook {\ocircumflex} + +\definecharacter Abrevegrave {\Abreve} +\definecharacter Abreveacute {\Abreve} +\definecharacter Abrevetilde {\Abreve} +\definecharacter Abrevehook {\Abreve} +\definecharacter abrevegrave {\abreve} +\definecharacter abreveacute {\abreve} +\definecharacter abrevetilde {\abreve} +\definecharacter abrevehook {\abreve} + +\definecharacter Adotbelow {\buildtextbottomdot A} +\definecharacter adotbelow {\buildtextbottomdot a} +\definecharacter Edotbelow {\buildtextbottomdot E} +\definecharacter edotbelow {\buildtextbottomdot e} +\definecharacter Idotbelow {\buildtextbottomdot I} +\definecharacter idotbelow {\buildtextbottomdot i} +\definecharacter Odotbelow {\buildtextbottomdot O} +\definecharacter odotbelow {\buildtextbottomdot o} +\definecharacter Udotbelow {\buildtextbottomdot U} +\definecharacter udotbelow {\buildtextbottomdot u} +\definecharacter Ydotbelow {\buildtextbottomdot Y} +\definecharacter ydotbelow {\buildtextbottomdot y} + +\definecharacter Ohorndotbelow {\buildtextbottomdot\Ohorn} +\definecharacter ohorndotbelow {\buildtextbottomdot\ohorn} +\definecharacter Uhorndotbelow {\buildtextbottomdot\Uhorn} +\definecharacter uhorndotbelow {\buildtextbottomdot\uhorn} + +\definecharacter Acircumflexdotbelow {\buildtextbottomdot\Acircumflex} +\definecharacter acircumflexdotbelow {\buildtextbottomdot\acircumflex} +\definecharacter Ecircumflexdotbelow {\buildtextbottomdot\Ecircumflex} +\definecharacter ecircumflexdotbelow {\buildtextbottomdot\ecircumflex} +\definecharacter Ocircumflexdotbelow {\buildtextbottomdot\Ocircumflex} +\definecharacter ocircumflexdotbelow {\buildtextbottomdot\ocircumflex} +\definecharacter Abrevedotbelow {\buildtextbottomdot\Abreve} +\definecharacter abrevedotbelow {\buildtextbottomdot\abreve} + +\definecharacter Ohorn {O} +\definecharacter Ohorngrave {\Ograve} +\definecharacter Ohornacute {\Oacute} +\definecharacter Ohorntilde {\Otilde} +\definecharacter Ohornhook {O} +\definecharacter ohorn {o} +\definecharacter ohorngrave {\ograve} +\definecharacter ohornacute {\oacute} +\definecharacter ohorntilde {\otilde} +\definecharacter ohornhook {o} +\definecharacter Uhorn {U} +\definecharacter Uhorngrave {\Ugrave} +\definecharacter Uhornacute {\Uacute} +\definecharacter Uhorntilde {\Utilde} +\definecharacter Uhornhook {U} +\definecharacter uhorn {u} +\definecharacter uhorngrave {\ugrave} +\definecharacter uhornacute {\uacute} +\definecharacter uhorntilde {\utilde} +\definecharacter uhornhook {u} + +\stopencoding + +%D Needed for transliterated chinese (provided by Tobias Burnus). + +\startencoding[default] + +\definecharacter acaron {\buildtextaccent\textcaron a} % U+01CE +\definecharacter icaron {\buildtextaccent\textcaron \dotlessi} % U+01D0 +\definecharacter ocaron {\buildtextaccent\textcaron o} % U+01D2 +\definecharacter ucaron {\buildtextaccent\textcaron u} % U+01D4 + +\stopencoding + +%D Greek (moved to here): + +\startencoding[default] + +% Uppercase Greek letters + +\definecharacter greekAlpha {\Alpha} +\definecharacter greekBeta {\Beta} +\definecharacter greekGamma {\Gamma} +\definecharacter greekDelta {\Delta} +\definecharacter greekEpsilon {\Epsilon} +\definecharacter greekZeta {\Zeta} +\definecharacter greekEta {\Eta} +\definecharacter greekTheta {\Theta} +\definecharacter greekIota {\Iota} +\definecharacter greekKappa {\Kappa} +\definecharacter greekLambda {\Lambda} +\definecharacter greekMu {\Mu} +\definecharacter greekNu {\Nu} +\definecharacter greekXi {\Xi} +\definecharacter greekOmicron {\Omicron} +\definecharacter greekPi {\Pi} +\definecharacter greekRho {\Rho} +\definecharacter greekSigma {\Sigma} +\definecharacter greekTau {\Tau} +\definecharacter greekUpsilon {\Upsilon} +\definecharacter greekPhi {\Phi} +\definecharacter greekChi {\Chi} +\definecharacter greekPsi {\Psi} +\definecharacter greekOmega {\Omega} + +% Lowercase Greek letters + +\definecharacter greekalpha {\alpha} +\definecharacter greekbeta {\beta} +\definecharacter greekgamma {\gamma} +\definecharacter greekdelta {\delta} +\definecharacter greekepsilon {\varepsilon} +\definecharacter greekepsilonalt {\epsilon} +\definecharacter greekzeta {\zeta} +\definecharacter greeketa {\eta} +\definecharacter greektheta {\theta} +\definecharacter greekthetaalt {\vartheta} +\definecharacter greekiota {\iota} +\definecharacter greekkappa {\kappa} +\definecharacter greeklambda {\lambda} +\definecharacter greekmu {\mu} +\definecharacter greeknu {\nu} +\definecharacter greekxi {\xi} +\definecharacter greekomicron {\omicron} +\definecharacter greekpi {\pi} +\definecharacter greekrho {\rho} +\definecharacter greeksigma {\sigma} +\definecharacter greekfinalsigma {\varsigma} +\definecharacter greektau {\tau} +\definecharacter greekupsilon {\upsilon} +\definecharacter greekphi {\varphi} +\definecharacter greekphialt {\phi} +\definecharacter greekchi {\chi} +\definecharacter greekpsi {\psi} +\definecharacter greekomega {\omega} + +% Accented Uppercase Greek letters + +\definecharacter greekAlphatonos {'A} +\definecharacter greekEpsilontonos {'E} +\definecharacter greekEtatonos {'H} +\definecharacter greekIotatonos {'I} +\definecharacter greekOmicrontonos {'O} +\definecharacter greekUpsilontonos {'U} +\definecharacter greekOmegatonos {'W} +\definecharacter greekIotadialytika {"I} +\definecharacter greekUpsilondialytika {"U} + +% Accented Lowercase Greek letters + +\definecharacter greekalphatonos {'a} +\definecharacter greekepsilontonos {'e} +\definecharacter greeketatonos {'h} +\definecharacter greekiotatonos {'i} +\definecharacter greekomicrontonos {'o} +\definecharacter greekupsilontonos {'u} +\definecharacter greekomegatonos {'w} +\definecharacter greekiotadialytika {"i} +\definecharacter greekupsilondialytika {"u} +\definecharacter greekiotadialytikatonos {'"i} +\definecharacter greekupsilondialytikatonos {'"u} + +% Miscellaneous Greek symbols + +\definecharacter greekleftquot {((} +\definecharacter greekrightquot {))} +\definecharacter greektonos {'} +\definecharacter greekdialytikatonos {'"} +\definecharacter greekapostrophos {''} + +\stopencoding + +%D Cyrillic (moved to here): + +\startencoding[default] + +\definecharacter cyrillicA {A} +\definecharacter cyrillicB {B} +\definecharacter cyrillicV {V} +\definecharacter cyrillicG {G} +\definecharacter cyrillicD {D} +\definecharacter cyrillicE {E} +\definecharacter cyrillicZH {ZH} +\definecharacter cyrillicZ {Z} +\definecharacter cyrillicI {I} +\definecharacter cyrillicISHRT {ISHRT} +\definecharacter cyrillicK {K} +\definecharacter cyrillicL {L} +\definecharacter cyrillicM {M} +\definecharacter cyrillicN {N} +\definecharacter cyrillicO {O} +\definecharacter cyrillicP {P} +\definecharacter cyrillicR {R} +\definecharacter cyrillicS {S} +\definecharacter cyrillicT {T} +\definecharacter cyrillicU {U} +\definecharacter cyrillicF {F} +\definecharacter cyrillicH {H} +\definecharacter cyrillicC {C} +\definecharacter cyrillicCH {CH} +\definecharacter cyrillicSH {SH} +\definecharacter cyrillicSHCH {SHCH} +\definecharacter cyrillicHRDSN {HRDSN} +\definecharacter cyrillicERY {ERY} +\definecharacter cyrillicSFTSN {SFTSN} +\definecharacter cyrillicEREV {EREV} +\definecharacter cyrillicYU {YU} +\definecharacter cyrillicYA {YA} +\definecharacter cyrillicGUP {GUP} +\definecharacter cyrillicGHCRS {GHCRS} +\definecharacter cyrillicDJE {DJE} +\definecharacter cyrillicTSHE {TSHE} +\definecharacter cyrillicSHHA {SHHA} +\definecharacter cyrillicZHDSC {ZHDSC} +\definecharacter cyrillicZDSC {ZDSC} +\definecharacter cyrillicLJE {LJE} +\definecharacter cyrillicYI {YI} +\definecharacter cyrillicKDSC {KDSC} +\definecharacter cyrillicKBEAK {KBEAK} +\definecharacter cyrillicKVCRS {KVCRS} +\definecharacter cyrillicAE {AE} +\definecharacter cyrillicNDSC {NDSC} +\definecharacter cyrillicNG {NG} +\definecharacter cyrillicDZE {DZE} +\definecharacter cyrillicOTLD {OTLD} +\definecharacter cyrillicSDSC {SDSC} +\definecharacter cyrillicUSHRT {USHRT} +\definecharacter cyrillicY {Y} +\definecharacter cyrillicYHCRS {YHCRS} +\definecharacter cyrillicHDSC {HDSC} +\definecharacter cyrillicDZHE {DZHE} +\definecharacter cyrillicCHVCRS {CHVCRS} +\definecharacter cyrillicCHRDSC {CHRDSC} +\definecharacter cyrillicIE {IE} +\definecharacter cyrillicSCHWA {SCHWA} +\definecharacter cyrillicNJE {NJE} +\definecharacter cyrillicYO {YO} +\definecharacter cyrillicII {II} +\definecharacter cyrillicJE {JE} +\definecharacter cyrillicQ {Q} +\definecharacter cyrillicW {W} + +\definecharacter cyrillica {a} +\definecharacter cyrillicb {b} +\definecharacter cyrillicv {v} +\definecharacter cyrillicg {g} +\definecharacter cyrillicd {d} +\definecharacter cyrillice {e} +\definecharacter cyrilliczh {zh} +\definecharacter cyrillicz {z} +\definecharacter cyrillici {i} +\definecharacter cyrillicishrt {ishrt} +\definecharacter cyrillick {k} +\definecharacter cyrillicl {l} +\definecharacter cyrillicm {m} +\definecharacter cyrillicn {n} +\definecharacter cyrillico {o} +\definecharacter cyrillicp {p} +\definecharacter cyrillicr {r} +\definecharacter cyrillics {s} +\definecharacter cyrillict {t} +\definecharacter cyrillicu {u} +\definecharacter cyrillicf {f} +\definecharacter cyrillich {h} +\definecharacter cyrillicc {c} +\definecharacter cyrillicch {ch} +\definecharacter cyrillicsh {sh} +\definecharacter cyrillicshch {shch} +\definecharacter cyrillichrdsn {hrdsn} +\definecharacter cyrillicery {ery} +\definecharacter cyrillicsftsn {sftsn} +\definecharacter cyrillicerev {erev} +\definecharacter cyrillicyu {yu} +\definecharacter cyrillicya {ya} +\definecharacter cyrillicgup {gup} +\definecharacter cyrillicghcrs {ghcrs} +\definecharacter cyrillicdje {dje} +\definecharacter cyrillictshe {tshe} +\definecharacter cyrillicshha {shha} +\definecharacter cyrilliczhdsc {zhdsc} +\definecharacter cyrilliczdsc {zdsc} +\definecharacter cyrilliclje {lje} +\definecharacter cyrillicyi {yi} +\definecharacter cyrillickdsc {kdsc} +\definecharacter cyrillickbeak {kbeak} +\definecharacter cyrillickvcrs {kvcrs} +\definecharacter cyrillicae {ae} +\definecharacter cyrillicndsc {ndsc} +\definecharacter cyrillicng {ng} +\definecharacter cyrillicdze {dze} +\definecharacter cyrillicotld {otld} +\definecharacter cyrillicsdsc {sdsc} +\definecharacter cyrillicushrt {ushrt} +\definecharacter cyrillicy {y} +\definecharacter cyrillicyhcrs {yhcrs} +\definecharacter cyrillichdsc {hdsc} +\definecharacter cyrillicdzhe {dzhe} +\definecharacter cyrillicchvcrs {chvcrs} +\definecharacter cyrillicchrdsc {chrdsc} +\definecharacter cyrillicie {ie} +\definecharacter cyrillicschwa {schwa} +\definecharacter cyrillicnje {nje} +\definecharacter cyrillicyo {yo} +\definecharacter cyrillicii {ii} +\definecharacter cyrillicje {je} +\definecharacter cyrillicq {q} +\definecharacter cyrillicw {w} + +\definecharacter cyrillicGJE {\'\cyrillicG} +\definecharacter cyrillicgje {\'\cyrillicg} +\definecharacter cyrillicKJE {\'\cyrillicK} +\definecharacter cyrillickje {\'\cyrillick} + +\stopencoding + +\def\cyrillicio{\cyrillicyo} +\def\cyrillicIO{\cyrillicYO} + +%D Hebrew: + +\startencoding[default] + +\definecharacter hebrewAlef {'} +\definecharacter hebrewBet {b} +\definecharacter hebrewGimel {g} +\definecharacter hebrewDalet {d} +\definecharacter hebrewHe {h} +\definecharacter hebrewVav {w} +\definecharacter hebrewZayin {z} +\definecharacter hebrewHet {\hstroke} +\definecharacter hebrewTet {\tcedilla} +\definecharacter hebrewYod {y} +\definecharacter hebrewKaffinal {k} +\definecharacter hebrewKaf {k} +\definecharacter hebrewLamed {l} +\definecharacter hebrewMemfinal {m} +\definecharacter hebrewMem {m} +\definecharacter hebrewNunfinal {n} +\definecharacter hebrewNun {n} +\definecharacter hebrewSamekh {s} +\definecharacter hebrewAyin {\gdotaccent} +\definecharacter hebrewPefinal {p} +\definecharacter hebrewPe {p} +\definecharacter hebrewTsadifinal {\scedilla} +\definecharacter hebrewTsadi {\scedilla} +\definecharacter hebrewQof {q} +\definecharacter hebrewResh {r} +\definecharacter hebrewShin {\scaron} +\definecharacter hebrewTav {th} + +\stopencoding + +%D A few goodies: + +\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} + +% \startencoding [default] +% +% \definecharacter scommaaccent {\scedilla} +% \definecharacter Scommaaccent {\Scedilla} +% \definecharacter tcommaaccent {\tcedilla} +% \definecharacter Tcommaaccent {\Tcedilla} +% +% \stopencoding + +% for plain tex's sake + +\def\S {\sectionmark } +\def\P {\paragraphmark} + +% for latex users sake + +\def\textS {\sectionmark } +\def\textP {\paragraphmark} + +% for old times sake + +\def\florin {\textflorin } \def\florijn{\textflorin} +\def\dollar {\textdollar } +\def\pound {\textsterling} +\def\sterling{\textsterling} + +% idem + +\def\promille{\perthousand} +\def\permille{\perthousand} +\def\procent {\percent } +\def\permine {\fakepermine} + +% some more + +\def\hyphen {\softhyphen} +\def\cwm {\compoundwordmark} +\def\nonbreakinghyphen {\hyphen} +\def\breakinghyphen {\hyphen\prewordbreak} + +% 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} + +%D A couple of fallbacks suggestion by users, slightly +%D adapted and obscured by memory saving hacks. + +\unprotect + +\startencoding[default] + +\definecharacter textcent {c\rlap{\hskip-.2\s!em + \vrule\!!width.2\s!pt\!!height1.2\s!ex\!!depth.2\s!ex}} + +\definecharacter texteuro {C\rlap{\hskip-.75\s!em + \vrule\!!width.4\s!em\!!height.85\s!ex\!!depth-.8\s!ex}} + +\definecharacter textblacksquare {\dontleavehmode\hbox{% + \vrule\!!width.3\s!em\!!height.4\s!em\!!depth-.1\s!em}} + +\definecharacter textbrokenbar {\dontleavehmode\hbox{\kern.05\s!em + \vrule\!!width.4\s!pt\!!height1.8\s!ex\!!depth-.85\s!ex + \llap{% + \vrule\!!width.4\s!pt\!!height.35\s!ex\!!depth.6\s!ex}% + \kern.05\s!em}} + +\stopencoding + +\protect + +%D We also use symbolic names for math accents. + +\startencoding[default] + +\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 + +\stopencoding + +% \startencoding [default] + +% \definecommand prime {\mathematics{'}} +% \definecommand doubleprime {\mathematics{''}} +% \definecommand tripleprime {\mathematics{'''}} + +% \stopencoding + +\ifx\zdot\undefined \def\zdot{\zdotaccent} \fi +\ifx\Zdot\undefined \def\Zdot{\Zdotaccent} \fi + +\ifx\greeklamda\undefined \def\greeklamda{\greeklambda} \fi +\ifx\greekLamda\undefined \def\greekLamda{\greekLambda} \fi + +\ifx\leftguillemet \undefined \def\leftguillemet {\leftguillemot } \fi +\ifx\rightguillemet\undefined \def\rightguillemet{\rightguillemot} \fi + +%D New: + +\startencoding[\s!default] + +\definecharacter schwa {\hbox{\rotate[\c!rotation=180,\c!location=\v!high]{\hbox{e}}}} +\definecharacter schwagrave {\buildtextgrave\schwa} + +\stopencoding + +%D Also new, from Taco, for Mojca, who wanted another 8~regimes. + +\startencoding[\s!default] + +\definecharacter texthorizontalbar {{\endash\kern\zeropoint\endash}} +\definecharacter textdong {\underbar{\dstroke}} + +\stopencoding + +%D Goodie (makes more sense): + +\def\normalcontrolspace + {\getglyph{ComputerModernMono}{\char32}} + +\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\relax \!!height-2\scratchdimen \!!depth3\scratchdimen + \vrule \!!width\scratchdimen \!!height5.5\scratchdimen \!!depth3\scratchdimen + \kern\scratchdimen}} + +\def\fakecontrolspace{\let\normalcontrolspace\fakedcontrolspace} + +\endinput diff --git a/tex/context/base/enco-ec.mkii b/tex/context/base/enco-ec.mkii new file mode 100644 index 000000000..1ac41cadf --- /dev/null +++ b/tex/context/base/enco-ec.mkii @@ -0,0 +1,295 @@ +%D \module +%D [ file=enco-ec, +%D version=2000.05.07, % 1999.16.07, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=\LATEX\ EC Encoding, +%D author={Patrick Gundlach, Hans Hagen, Taco Hoekwater, Mojca Miklavec}, +%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. + +%D This is \LATEX2e's T1 encoding vector. All standard \LATEX\ +%D accents will work, including \type{\k}. The only accent that +%D does not work is \type{\t} (there is no tie in T1 encoding). +%D +%D Annoyingly, most \POSTSCRIPT\ fonts do not have \type +%D {\dotlessj}, and T1 encoding does not make the various +%D prebuilts with \type {j} available. When this is the case: +%D +%D \starttyping +%D \startencoding[ec] +%D \definecharacter dotlessj {j} +%D \stopencoding +%D \stoptyping +%D +%D is a way out. + +%D There is hardly a point in supporting TS1 encoding. + +\startmapping[ec] + +% a problem is that the uppercase of dstroke (158) and eth (240) +% is the same glyph (208) so we cannot do lowercase mapping there + +\definecasemaps 128 to 156 lc +32 uc 0 +\definecasemap 157 `i 157 % Idotaccent i +\definecasemap 158 158 208 % dstroke Eth +\definecasemap 159 159 159 % sectionmark +\definecasemaps 160 to 187 lc 0 uc -32 +\resetcaserange 189 to 191 % exclamdown, questiondown, textsterling +\definecasemaps 192 to 223 lc +32 uc 0 +\definecasemaps 224 to 254 lc 0 uc -32 +\definecaseswap 255 223 % ssharp (else patterns fail) +\definecaseswap 25 `I % dotless i + +% 156 vs. 188 IJligature + +%D Some languages need this: + +% \definecaseself 34 % quotedbl +% \definecaseself 18 % quotedblbase +% \definecaseself 16 % quotedblleft +% \definecaseself 17 % quotedblright +% \definecaseself 39 % quotesingle +% \definecaseself 13 % quotesinglebase +% \definecaseself 96 % quoteleft +% \definecaseself 39 % quoteright + +%D So far for the mapping. + +%D The following characters are kind of dangerous, +%D that is, they are normally not part of fonts, unless +%D explicitly constructed. +%D +%D \startitemize[columns,two] +%D \item \type{\dotlessj} - but then it may not be defined!!!! +%D \item \type{\IJligature} +%D \item \type{\ijligature} +%D \item \type{\Ssharp} +%D \item \type{\perthousand} +%D \item \type{\compoundwordmark} +% \item \type{\textvisiblespace} +%D \stopitemize + +%D So, for the moment we nil them; we can always create +%D another vector if needed. + +\stopmapping + +\startencoding[ec][ec] % second arg defines auto regime, needed here ? + +\definecharacter textgrave 0 +\definecharacter textacute 1 +\definecharacter textcircumflex 2 +\definecharacter texttilde 3 +\definecharacter textdiaeresis 4 +\definecharacter texthungarumlaut 5 +\definecharacter textring 6 +\definecharacter textcaron 7 +\definecharacter textbreve 8 +\definecharacter textmacron 9 +\definecharacter textdotaccent 10 +\definecharacter textcedilla 11 +\definecharacter textogonek 12 +\definecharacter quotesinglebase 13 +\definecharacter guilsingleleft 14 +\definecharacter guilsingleright 15 +\definecharacter quotedblleft 16 +\definecharacter quotedblright 17 +\definecharacter quotedblbase 18 +\definecharacter leftguillemot 19 +\definecharacter rightguillemot 20 +\definecharacter endash 21 +\definecharacter emdash 22 +%definecharacter compoundwordmark 23 +%definecharacter perthousand 24 +\definecharacter dotlessi 25 % or when missing: {j} +\definecharacter dotlessj 26 +% ff 27 +% fi 28 +% fl 29 +% ffi 30 +% ffl 31 +%definecharacter textvisiblespace 32 +% exclam ! 33 +\definecharacter quotedbl 34 +% numbersign # 35 +% dollar $ 36 +\definecharacter percent 37 +% ampersand & 38 +%definecharacter quotesingle 39 % fake 'm TODO:enco-def!!!! +\definecharacter quoteright 39 +% parenleft ( 40 +% parenright ) 41 +% asterisk * 42 +% plus + 43 +% comma , 44 +\definecharacter softhyphen 45 +% period . 46 +% slash / 47 +% 0-9 48-57 +% colon : 58 +% semicolon ; 59 +% less < 60 +% equal = 61 +% greater > 62 +% question ? 63 +% at @ 64 +% A-Z 65-90 +% bracketleft [ 91 +\definecharacter textbackslash 92 +% bracketright ] 93 +\definecharacter textasciicircum 94 +\definecharacter textunderscore 95 +\definecharacter quoteleft 96 +% a-z 97-122 +\definecharacter textbraceleft 123 +\definecharacter textbraceright 125 +\definecharacter textasciitilde 126 +%definecharacter softhyphen 127 % -> 45 (127 often undefined) +\definecharacter Abreve 128 % abreve 160 +\definecharacter Aogonek 129 % aogonek 161 +\definecharacter Cacute 130 % cacute 162 +\definecharacter Ccaron 131 % ccaron 163 +\definecharacter Dcaron 132 % dcaron 164 +\definecharacter Ecaron 133 % ecaron 165 +\definecharacter Eogonek 134 % eogonek 166 +\definecharacter Gbreve 135 % gbreve 167 +\definecharacter Lacute 136 % lacute 168 +\definecharacter Lcaron 137 % lcaron 169 +\definecharacter Lstroke 138 % lstroke 170 +\definecharacter Nacute 139 % nacute 171 +\definecharacter Ncaron 140 % ncaron 172 +\definecharacter Eng 141 % eng 173 +\definecharacter Neng 141 % Neng 173 +\definecharacter Ohungarumlaut 142 % ohungarumlaut 174 +\definecharacter Racute 143 % racute 175 +\definecharacter Rcaron 144 % rcaron 176 +\definecharacter Sacute 145 % sacute 177 +\definecharacter Scaron 146 % scaron 178 +\definecharacter Scedilla 147 % scedilla 179 +\definecharacter Tcaron 148 % tcaron 180 +\definecharacter Tcedilla 149 % tcedilla 181 +\definecharacter Uhungarumlaut 150 % uhungarumlaut 182 +\definecharacter Uring 151 % uring 183 +\definecharacter Ydiaeresis 152 % ydiaeresis 184 +\definecharacter Zacute 153 % zacute 185 +\definecharacter Zcaron 154 % zcaron 186 +\definecharacter Zdotaccent 155 % zdotaccent 187 +\definecharacter IJligature 156 % ijligature 188 +\definecharacter Idotaccent 157 +\definecharacter dstroke 158 % Dstroke 208 +\definecharacter sectionmark 159 +\definecharacter abreve 160 % Abreve 128 +\definecharacter aogonek 161 % Aogonek 129 +\definecharacter cacute 162 % Cacute 130 +\definecharacter ccaron 163 % Ccaron 131 +\definecharacter dcaron 164 % Dcaron 132 +\definecharacter ecaron 165 % Ecaron 133 +\definecharacter eogonek 166 % Eogonek 134 +\definecharacter gbreve 167 % Gbreve 135 +\definecharacter lacute 168 % Lacute 136 +\definecharacter lcaron 169 % Lcaron 137 +\definecharacter lstroke 170 % Lstroke 138 +\definecharacter nacute 171 % Nacute 139 +\definecharacter ncaron 172 % Ncaron 140 +\definecharacter eng 173 % Eng 141 +\definecharacter ohungarumlaut 174 % Ohungarumlaut 142 +\definecharacter racute 175 % Racute 143 +\definecharacter rcaron 176 % Rcaron 144 +\definecharacter sacute 177 % Sacute 145 +\definecharacter scaron 178 % Scaron 146 +\definecharacter scedilla 179 % Scedilla 147 +\definecharacter tcaron 180 % Tcaron 148 +\definecharacter tcedilla 181 % Tcedilla 149 +\definecharacter uhungarumlaut 182 % Uhungarumlaut 150 +\definecharacter uring 183 % Uring 151 +\definecharacter ydiaeresis 184 % Ydiaeresis 152 +\definecharacter zacute 185 % Zacute 153 +\definecharacter zcaron 186 % Zcaron 154 +\definecharacter zdotaccent 187 % Zdotaccent 155 +\definecharacter ijligature 188 % IJligature 156 +\definecharacter exclamdown 189 +\definecharacter questiondown 190 +\definecharacter textsterling 191 +\definecharacter Agrave 192 % agrave 224 +\definecharacter Aacute 193 % aacute 225 +\definecharacter Acircumflex 194 % acircumflex 226 +\definecharacter Atilde 195 % atilde 227 +\definecharacter Adiaeresis 196 % adiaeresis 228 +\definecharacter Aring 197 % aring 229 +\definecharacter AEligature 198 % aeligature 230 +\definecharacter Ccedilla 199 % ccedilla 231 +\definecharacter Egrave 200 % egrave 232 +\definecharacter Eacute 201 % eacute 233 +\definecharacter Ecircumflex 202 % ecircumflex 234 +\definecharacter Ediaeresis 203 % ediaeresis 235 +\definecharacter Igrave 204 % igrave 236 +\definecharacter Iacute 205 % iacute 237 +\definecharacter Icircumflex 206 % icircumflex 238 +\definecharacter Idiaeresis 207 % idiaeresis 239 +\definecharacter Eth 208 % eth 240 +\definecharacter Dstroke 208 % dstroke 158 +\definecharacter Ntilde 209 % ntilde 241 +\definecharacter Ograve 210 % ograve 242 +\definecharacter Oacute 211 % oacute 243 +\definecharacter Ocircumflex 212 % ocircumflex 244 +\definecharacter Otilde 213 % otilde 245 +\definecharacter Odiaeresis 214 % odiaeresis 246 +\definecharacter OEligature 215 % oeligature 247 +\definecharacter Ostroke 216 % ostroke 248 +\definecharacter Ugrave 217 % ugrave 249 +\definecharacter Uacute 218 % uacute 250 +\definecharacter Ucircumflex 219 % ucircumflex 251 +\definecharacter Udiaeresis 220 % udiaeresis 252 +\definecharacter Yacute 221 % yacute 253 +\definecharacter Thorn 222 % thorn 254 +\definecharacter Ssharp 223 % ssharp 255 +\definecharacter agrave 224 % Agrave 192 +\definecharacter aacute 225 % Aacute 193 +\definecharacter acircumflex 226 % Acircumflex 194 +\definecharacter atilde 227 % Atilde 195 +\definecharacter adiaeresis 228 % Adiaeresis 196 +\definecharacter aring 229 % Aring 197 +\definecharacter aeligature 230 % AEligature 198 +\definecharacter ccedilla 231 % Ccedilla 199 +\definecharacter egrave 232 % Egrave 200 +\definecharacter eacute 233 % Eacute 201 +\definecharacter ecircumflex 234 % Ecircumflex 202 +\definecharacter ediaeresis 235 % Ediaeresis 203 +\definecharacter igrave 236 % Igrave 204 +\definecharacter iacute 237 % Iacute 205 +\definecharacter icircumflex 238 % Icircumflex 206 +\definecharacter idiaeresis 239 % Idiaeresis 207 +\definecharacter eth 240 % Eth 208 +\definecharacter ntilde 241 % Ntilde 209 +\definecharacter ograve 242 % Ograve 210 +\definecharacter oacute 243 % Oacute 211 +\definecharacter ocircumflex 244 % Ocircumflex 212 +\definecharacter otilde 245 % Otilde 213 +\definecharacter odiaeresis 246 % Odiaeresis 214 +\definecharacter oeligature 247 % OEligature 215 +\definecharacter ostroke 248 % Ostroke 216 +\definecharacter ugrave 249 % Ugrave 217 +\definecharacter uacute 250 % Uacute 218 +\definecharacter ucircumflex 251 % Ucircumflex 219 +\definecharacter udiaeresis 252 % Udiaeresis 220 +\definecharacter yacute 253 % Yacute 221 +\definecharacter thorn 254 % Thorn 222 +\definecharacter ssharp 255 % Ssharp 223 + +\stopencoding + +\startencoding[ec] + +\definecharacter Scommaaccent {\Scedilla} +\definecharacter scommaaccent {\scedilla} +\definecharacter Tcommaaccent {\Tcedilla} +\definecharacter tcommaaccent {\tcedilla} + +\stopencoding + +\endinput diff --git a/tex/context/base/enco-ecm.mkii b/tex/context/base/enco-ecm.mkii new file mode 100644 index 000000000..b74473960 --- /dev/null +++ b/tex/context/base/enco-ecm.mkii @@ -0,0 +1,33 @@ +%D \module +%D [ file=enco-ec, +%D version=2000.05.07, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=Glyphs that may not be present in EC, +%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. + +%D The next typescript removes a few problematic characters +%D from the ec encoding vector. So, in case of troubles, say +%D +%D \starttyping +%D \useencoding[ecm] % ec minus +%D \stoptyping + +\startencoding[ec][ec] + +\definecharacter ijligature {ij} +\definecharacter IJligature {IJ} +\definecharacter Ssharp {SS} +\definecharacter tcaron {\buildtextaccent\textcaron t} +\definecharacter Tcedilla {\buildtextcedilla T} +\definecharacter tcedilla {\buildtextcedilla t} +\definecharacter ydiaeresis {\buildtextaccent\textdiaeresis y} + +\stopencoding + +\endinput diff --git a/tex/context/base/enco-el.mkii b/tex/context/base/enco-el.mkii new file mode 100644 index 000000000..24729967b --- /dev/null +++ b/tex/context/base/enco-el.mkii @@ -0,0 +1,272 @@ +%D \module +%D [ file=enco-el, +%D version=2005.08.24, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=EuroLetter, +%D author={Several Users}, +%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. + +%D This EuroLetter encoding vector, also known as Dense Encoding is +%D the result of discussion among users, most noticably Adam Lindsay, +%D Mojka Miklavec, Patrick Gundlach, Taco Hoekwater and \unknown. +%D It was a follow up of a thread started long ago where we +%D discussed an encoding without the weird, never used symbols, but +%D with as many characters as possible in order to support the utf-8 +%D input regime. + +\startencoding[el] + +\definecasemaps 1 to 15 lc +16 uc 0 +\definecasemaps 17 to 31 lc 0 uc -16 + +\definecasemaps 128 to 159 lc +32 uc 0 +\definecasemaps 160 to 191 lc 0 uc -32 + +\definecasemaps 192 to 223 lc +32 uc 0 +\definecasemaps 224 to 255 lc 0 uc -32 + +\definecasemap 92 92 124 +\definecasemap 92 124 92 + +\definecharacter dotlessi 160 +\definecharacter endash 32 +\definecharacter emdash 16 + +\definecharacter aeligature 230 +\definecharacter AEligature 198 +\definecharacter oeligature 247 +\definecharacter OEligature 215 + +\definecharacter ssharp 38 + +\definecharacter thorn 254 +\definecharacter Thorn 222 + +\definecharacter eth 240 +\definecharacter Eth 208 + +\definecharacter exclamdown 42 +\definecharacter questiondown 43 + +\definecharacter quotedbl 35 +\definecharacter quotedblbase 36 +\definecharacter quotedblleft 34 +\definecharacter quotedblright 35 + +\definecharacter quotesingle 39 +\definecharacter quotesinglebase 0 + +\definecharacter quoteleft 96 +\definecharacter quoteright 39 + +\definecharacter guilsingleleft 60 +\definecharacter guilsingleright 62 + +\definecharacter leftguillemot 123 +\definecharacter rightguillemot 125 + +\definecharacter Acircumflex 194 +\definecharacter acircumflex 226 +%definecharacter Ccircumflex {\buildtextaccent\textcircumflex C} +%definecharacter ccircumflex {\buildtextaccent\textcircumflex c} +\definecharacter Ecircumflex 202 +\definecharacter ecircumflex 234 +%definecharacter Gcircumflex {\buildtextaccent\textcircumflex G} +%definecharacter gcircumflex {\buildtextaccent\textcircumflex g} +%definecharacter Hcircumflex {\buildtextaccent\textcircumflex H} +%definecharacter hcircumflex {\buildtextaccent\textcircumflex h} +\definecharacter Icircumflex 206 +\definecharacter icircumflex 238 +%definecharacter Jcircumflex {\buildtextaccent\textcircumflex \dotlessJ} +%definecharacter jcircumflex {\buildtextaccent\textcircumflex \dotlessj} +\definecharacter Ocircumflex 212 +\definecharacter ocircumflex 244 +%definecharacter Scircumflex {\buildtextaccent\textcircumflex S} +%definecharacter scircumflex {\buildtextaccent\textcircumflex s} +\definecharacter Ucircumflex 219 +\definecharacter ucircumflex 251 +\definecharacter Wcircumflex 154 +\definecharacter wcircumflex 186 +\definecharacter Ycircumflex 156 +\definecharacter ycircumflex 188 + +\definecharacter Agrave 192 +\definecharacter agrave 224 +\definecharacter Egrave 200 +\definecharacter egrave 232 +\definecharacter Igrave 204 +\definecharacter igrave 236 +\definecharacter Ograve 210 +\definecharacter ograve 242 +\definecharacter Ugrave 217 +\definecharacter ugrave 249 +\definecharacter Ygrave 155 +\definecharacter ygrave 187 + +\definecharacter Atilde 195 +\definecharacter atilde 227 +%definecharacter Itilde {\buildtextaccent\texttilde \dotlessI} +%definecharacter itilde {\buildtextaccent\texttilde \dotlessi} +\definecharacter Ntilde 209 +\definecharacter ntilde 241 +\definecharacter Otilde 213 +\definecharacter otilde 245 +%definecharacter Utilde {\buildtextaccent\texttilde U} +%definecharacter utilde {\buildtextaccent\texttilde u} +%definecharacter Ytilde {\buildtextaccent\texttilde Y} +%definecharacter ytilde {\buildtextaccent\texttilde y} + +\definecharacter Adiaeresis 196 +\definecharacter adiaeresis 228 +\definecharacter Ediaeresis 203 +\definecharacter ediaeresis 235 +\definecharacter Idiaeresis 207 +\definecharacter idiaeresis 239 +\definecharacter Odiaeresis 214 +\definecharacter odiaeresis 246 +\definecharacter Udiaeresis 220 +\definecharacter udiaeresis 252 +\definecharacter Ydiaeresis 223 +\definecharacter ydiaeresis 255 + +\definecharacter Aacute 193 +\definecharacter aacute 225 +\definecharacter Cacute 4 +\definecharacter cacute 20 +\definecharacter Eacute 201 +\definecharacter eacute 233 +\definecharacter Iacute 205 +\definecharacter iacute 237 +\definecharacter Lacute 132 +\definecharacter lacute 164 +\definecharacter Nacute 136 +\definecharacter nacute 168 +\definecharacter Oacute 211 +\definecharacter oacute 243 +\definecharacter Racute 141 +\definecharacter racute 173 +\definecharacter Sacute 144 +\definecharacter sacute 176 +\definecharacter Uacute 218 +\definecharacter uacute 250 +\definecharacter Yacute 221 +\definecharacter yacute 253 +\definecharacter Zacute 157 +\definecharacter zacute 189 + +\definecharacter Dstroke 8 +\definecharacter dstroke 24 +\definecharacter Hstroke 92 +\definecharacter hstroke 124 +%definecharacter Tstroke {T} +%definecharacter tstroke {t} + +\definecharacter Cdotaccent 6 +\definecharacter cdotaccent 22 +\definecharacter Edotaccent 10 +\definecharacter edotaccent 26 +\definecharacter Gdotaccent 15 +\definecharacter gdotaccent 31 +\definecharacter Idotaccent 128 +%definecharacter idotaccent {\buildtextaccent\textdotaccent \dotlessi} +\definecharacter Zdotaccent 159 +\definecharacter zdotaccent 191 + +\definecharacter Amacron 2 +\definecharacter amacron 18 +\definecharacter Emacron 11 +\definecharacter emacron 27 +\definecharacter Imacron 129 +\definecharacter imacron 161 +\definecharacter Omacron 140 +\definecharacter omacron 172 +\definecharacter Umacron 152 +\definecharacter umacron 184 + +\definecharacter Ccedilla 199 +\definecharacter ccedilla 231 +\definecharacter Scedilla 146 +\definecharacter scedilla 178 + +\definecharacter Gcommaaccent 14 +\definecharacter gcommaaccent 30 +\definecharacter Kcommaaccent 131 +\definecharacter kcommaaccent 163 +\definecharacter Lcommaaccent 135 +\definecharacter lcommaaccent 167 +\definecharacter Ncommaaccent 138 +\definecharacter ncommaaccent 170 +\definecharacter Rcommaaccent 143 +\definecharacter rcommaaccent 175 +%definecharacter Tcedilla 149 % there is no tcedilla in encoding +%definecharacter tcedilla 181 + +\definecharacter Scommaaccent 147 +\definecharacter scommaaccent 179 +\definecharacter Tcommaaccent 149 +\definecharacter tcommaaccent 181 + +\definecharacter Ohungarumlaut 139 +\definecharacter ohungarumlaut 171 +\definecharacter Uhungarumlaut 150 +\definecharacter uhungarumlaut 182 + +\definecharacter Aogonek 3 +\definecharacter aogonek 19 +\definecharacter Eogonek 12 +\definecharacter eogonek 28 +\definecharacter Iogonek 130 +\definecharacter iogonek 162 +\definecharacter Uogonek 153 +\definecharacter uogonek 185 + +\definecharacter Aring 197 +\definecharacter aring 229 +\definecharacter Uring 151 +\definecharacter uring 183 + +\definecharacter Abreve 1 +\definecharacter abreve 17 +%definecharacter Ebreve {\buildtextaccent\textbreve E} +%definecharacter ebreve {\buildtextaccent\textbreve e} +\definecharacter Gbreve 13 +\definecharacter gbreve 29 +%definecharacter Ibreve {\buildtextaccent\textbreve \dotlessI} +%definecharacter ibreve {\buildtextaccent\textbreve \dotlessi} +%definecharacter Obreve {\buildtextaccent\textbreve O} +%definecharacter obreve {\buildtextaccent\textbreve o} +%definecharacter Ubreve {\buildtextaccent\textbreve U} +%definecharacter ubreve {\buildtextaccent\textbreve u} + +\definecharacter Ccaron 5 +\definecharacter ccaron 21 +\definecharacter Dcaron 7 +\definecharacter dcaron 23 +\definecharacter Ecaron 9 +\definecharacter ecaron 25 +\definecharacter Lcaron 133 +\definecharacter lcaron 165 +\definecharacter Ncaron 137 +\definecharacter ncaron 169 +\definecharacter Rcaron 142 +\definecharacter rcaron 174 +\definecharacter Scaron 145 +\definecharacter scaron 177 +\definecharacter Tcaron 148 +\definecharacter tcaron 180 +%definecharacter Ycaron {\buildtextaccent\textcaron Y} +%definecharacter ycaron {\buildtextaccent\textcaron y} +\definecharacter Zcaron 158 +\definecharacter zcaron 190 + +\definecharacter Lstroke 134 +\definecharacter lstroke 166 +\definecharacter Ostroke 216 +\definecharacter ostroke 248 + +\stopencoding diff --git a/tex/context/base/enco-fde.mkii b/tex/context/base/enco-fde.mkii new file mode 100644 index 000000000..a7c11abfc --- /dev/null +++ b/tex/context/base/enco-fde.mkii @@ -0,0 +1,128 @@ +%D \module +%D [ file=enco-fde, +%D version=2000.08.20, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=German Input Filter, +%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. + +\doifmode{mkiv}{\endinput} + +\unprotect + +\installactivecharacter " + +\startlanguagespecifics[\s!de] + + \installcompoundcharacter "a {\aumlaut\midworddiscretionary} + \installcompoundcharacter "e {\eumlaut\midworddiscretionary} + \installcompoundcharacter "i {\iumlaut\midworddiscretionary} + \installcompoundcharacter "o {\oumlaut\midworddiscretionary} + \installcompoundcharacter "u {\uumlaut\midworddiscretionary} + \installcompoundcharacter "s {\ssharp} + \installcompoundcharacter "z {\ssharp} + + \installcompoundcharacter "A {\Aumlaut} + \installcompoundcharacter "E {\Eumlaut} + \installcompoundcharacter "I {\Iumlaut} + \installcompoundcharacter "O {\Oumlaut} + \installcompoundcharacter "U {\Uumlaut} + \installcompoundcharacter "Z {SZ} + \installcompoundcharacter "S {SS} + +\stoplanguagespecifics + +\startlanguagespecifics[\s!de] + + \installcompoundcharacter "ck {\discretionary {k-}{k}{ck}} + \installcompoundcharacter "ff {\discretionary{ff-}{f}{ff}} + \installcompoundcharacter "ll {\discretionary{ll-}{l}{ll}} + \installcompoundcharacter "mm {\discretionary{mm-}{m}{mm}} + \installcompoundcharacter "nn {\discretionary{nn-}{n}{nn}} + \installcompoundcharacter "pp {\discretionary{pp-}{p}{pp}} + \installcompoundcharacter "rr {\discretionary{rr-}{r}{rr}} + \installcompoundcharacter "tt {\discretionary{tt-}{t}{tt}} + + \installcompoundcharacter "CK {\discretionary {K-}{K}{CK}} + \installcompoundcharacter "FF {\discretionary{FF-}{F}{FF}} + \installcompoundcharacter "LL {\discretionary{LL-}{L}{LL}} + \installcompoundcharacter "MM {\discretionary{MM-}{M}{MM}} + \installcompoundcharacter "NN {\discretionary{NN-}{N}{NN}} + \installcompoundcharacter "PP {\discretionary{PP-}{P}{PP}} + \installcompoundcharacter "RR {\discretionary{RR-}{R}{RR}} + \installcompoundcharacter "TT {\discretionary{TT-}{T}{TT}} + +\stoplanguagespecifics + +\startlanguagespecifics[\s!de] + + \installcompoundcharacter "` {\startdelimitedtext[\v!quotation]} + \installcompoundcharacter "' {\stopdelimitedtext} + \installcompoundcharacter ". {\kern.1em\ignorespaces} + + %installcompoundcharacter "` {\languageparameter\c!leftquotation } + %installcompoundcharacter "' {\languageparameter\c!rightquotation} + + \def\setupDElanguage + {\setuplanguage + [\s!de] + [\c!leftsentence=\leftguillemot, + \c!rightsentence=\rightguillemot, + \c!leftsubsentence=\leftsubguillemot, + \c!rightsubsentence=\rightsubguillemot]} + + \installcompoundcharacter "< {{\setupDElanguage|<|}} + \installcompoundcharacter "> {{\setupDElanguage|>|}} + \installcompoundcharacter "| {|*|} + +\stoplanguagespecifics + +% \hyphenatedword{hinauff|*|liegen} +% \hyphenatedword{hinauff"|liegen} + +%D An experimental hack: + +% no {\simplifiedcompoundcharacter"} + +% \startencoding[pdfdoc] +% \startlanguagespecifics[\s!de]% hm, a % is needed +% \defineactivecharacter " {\"} +% \stoplanguagespecifics +% \stopencoding + +\startencoding[ec] + \startlanguagespecifics[\s!de]% + \installcompoundcharacter "a {\adiaeresis} + \installcompoundcharacter "e {\ediaeresis} + \installcompoundcharacter "i {\idiaeresis} + \installcompoundcharacter "o {\odiaeresis} + \installcompoundcharacter "u {\udiaeresis} + \installcompoundcharacter "A {\Adiaeresis} + \installcompoundcharacter "E {\Ediaeresis} + \installcompoundcharacter "I {\Idiaeresis} + \installcompoundcharacter "O {\Odiaeresis} + \installcompoundcharacter "U {\Udiaeresis} + \stoplanguagespecifics +\stopencoding + +\startencoding[texnansi] + \startlanguagespecifics[\s!de]% + \installcompoundcharacter "a {\adiaeresis} + \installcompoundcharacter "e {\ediaeresis} + \installcompoundcharacter "i {\idiaeresis} + \installcompoundcharacter "o {\odiaeresis} + \installcompoundcharacter "u {\udiaeresis} + \installcompoundcharacter "A {\Adiaeresis} + \installcompoundcharacter "E {\Ediaeresis} + \installcompoundcharacter "I {\Idiaeresis} + \installcompoundcharacter "O {\Odiaeresis} + \installcompoundcharacter "U {\Udiaeresis} + \stoplanguagespecifics +\stopencoding + +\protect \endinput diff --git a/tex/context/base/enco-ffr.mkii b/tex/context/base/enco-ffr.mkii new file mode 100644 index 000000000..093cc6500 --- /dev/null +++ b/tex/context/base/enco-ffr.mkii @@ -0,0 +1,57 @@ +%D \module +%D [ file=enco-ffr, +%D version=2002.05.07, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=French Input Filter, +%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. + +\doifmode{mkiv}{\endinput} + +% \definehspace[fr][:][.25em] +% \definehspace[fr][;][.25em] +% \definehspace[fr][!][.25em] +% \definehspace[fr][?][.25em] + +\enablemode[activecolon] \usemodule[tryout] % for the moment + +\installactivecharacter : +\installactivecharacter ; +\installactivecharacter ? +\installactivecharacter ! + +\unprotect + +\startlanguagespecifics[\s!fr] + \definetextmodediscretionary : {\removeunwantedspaces\prewordbreak\kern\hspaceamount\currentmainlanguage{:}:} + \definetextmodediscretionary ; {\removeunwantedspaces\prewordbreak\kern\hspaceamount\currentmainlanguage{;};} + \definetextmodediscretionary ? {\removeunwantedspaces\prewordbreak\kern\hspaceamount\currentmainlanguage{?}?} + \definetextmodediscretionary ! {\removeunwantedspaces\prewordbreak\kern\hspaceamount\currentmainlanguage{!}!} +\stoplanguagespecifics + +\startlanguagespecifics[\s!fr] + \defineactivecharacter : {\mathortext{:}{\directdiscretionary{:}}} + \defineactivecharacter ; {\mathortext{;}{\directdiscretionary{;}}} + \defineactivecharacter ! {\mathortext{!}{\directdiscretionary{!}}} + \defineactivecharacter ? {\mathortext{?}{\directdiscretionary{?}}} +\stoplanguagespecifics + +\appendtoks % maybe everywhere + \chardef\activecharactermode\zerocount +\to\everyMPgraphic + +% maybe tricky due to possible name clashes: +% +% \def\ieme {\highordinalstr{e}} +% \def\iemes{\highordinalstr{es}} +% \def\ier {\highordinalstr{er}} +% \def\iers {\highordinalstr{ers}} +% \def\iere {\highordinalstr{re}} +% \def\ieres{\highordinalstr{res}} + +\protect \endinput diff --git a/tex/context/base/enco-fpl.mkii b/tex/context/base/enco-fpl.mkii new file mode 100644 index 000000000..14d102ff1 --- /dev/null +++ b/tex/context/base/enco-fpl.mkii @@ -0,0 +1,98 @@ +%D \module +%D [ file=enco-fpl, +%D version=2000.08.20, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=Polish Input Filter, +%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 These definitions used to be part of lang-sla.tex. + +\unprotect + +% todo : named glyphs + +\installactivecharacter / + +\startlanguagespecifics[\s!pl] + +% \appendtoks \makecharacteractive / \to \everynormalcatcodes % obsolete + + \installcompoundcharacter /a {\aogonek} + \installcompoundcharacter /c {\cacute} + \installcompoundcharacter /e {\eogonek} + \installcompoundcharacter /l {\lstroke} + \installcompoundcharacter /n {\nacute} + \installcompoundcharacter /o {\oacute} + \installcompoundcharacter /s {\sacute} + \installcompoundcharacter /x {\zacute} + \installcompoundcharacter /z {\zdotaccent} + \installcompoundcharacter /A {\Aogonek} + \installcompoundcharacter /C {\Cacute} + \installcompoundcharacter /E {\Eogonek} + \installcompoundcharacter /L {\Lstroke} + \installcompoundcharacter /N {\Nacute} + \installcompoundcharacter /O {\Oacute} + \installcompoundcharacter /S {\Sacute} + \installcompoundcharacter /X {\Zacute} + \installcompoundcharacter /Z {\Zdotaccent} + +\stoplanguagespecifics + +\startlanguagespecifics[\s!pl] + + \installcompoundcharacter /, {\handlequotation\c!leftquotation} + \installcompoundcharacter /' {\handlequotation\c!rightquotation} + + \def\setupPLlanguage% + {\setuplanguage + [\s!pl] + [\c!leftsentence=\leftguillemot, + \c!rightsentence=\rightguillemot, + \c!leftsubsentence=\leftsubguillemot, + \c!rightsubsentence=\rightsubguillemot]} + + \installcompoundcharacter /< {{\setupPLlanguage|<|}} + \installcompoundcharacter /> {{\setupPLlanguage|>|}} + + \installcompoundcharacter /- {|-|} + +\stoplanguagespecifics + +% obsolete +% +% \startlanguagespecifics[\s!pl] +% +% \definesortkey {/a}{a}{a}{\k a} +% \definesortkey {/A}{a}{a}{\k a} +% \definesortkey {/c}{c}{a}{\'c} +% \definesortkey {/C}{c}{a}{\'c} +% \definesortkey {/e}{e}{a}{\k e} +% \definesortkey {/E}{e}{a}{\k e} +% \definesortkey {/l}{l}{a}{\l } +% \definesortkey {/L}{l}{a}{\l } +% \definesortkey {/n}{n}{a}{\'n} +% \definesortkey {/N}{n}{a}{\'n} +% \definesortkey {/o}{o}{a}{\'o} +% \definesortkey {/O}{o}{a}{\'o} +% \definesortkey {/s}{s}{a}{\'s} +% \definesortkey {/S}{s}{a}{\'s} +% \definesortkey {/x}{z}{a}{\'x} +% \definesortkey {/X}{z}{a}{\'x} +% \definesortkey {/z}{z}{b}{\.z} +% \definesortkey {/Z}{z}{b}{\.z} +% +% \stoplanguagespecifics + +\startencoding[pdfdoc] + \startlanguagespecifics[pl]% hm + \defineactivecharacter / {\simplifiedcompoundcharacter/} + \stoplanguagespecifics +\stopencoding + +\protect \endinput diff --git a/tex/context/base/enco-fro.mkii b/tex/context/base/enco-fro.mkii new file mode 100644 index 000000000..e5f5e1257 --- /dev/null +++ b/tex/context/base/enco-fro.mkii @@ -0,0 +1,35 @@ +%D \module +%D [ file=enco-fro, +%D version=2000.08.20, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=Romanian Input Filter, +%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 These definitions used to be part of lang-ita.tex. + +\unprotect + +\installactivecharacter " + +\startlanguagespecifics[\s!ro] + + \installcompoundcharacter "a {\acircumflex} + \installcompoundcharacter "i {\icircumflex} + \installcompoundcharacter "s {\scedilla} + \installcompoundcharacter "t {\tcedilla} + \installcompoundcharacter "A {\Acircumflex} + \installcompoundcharacter "I {\Icircumflex} + \installcompoundcharacter "S {\Scedilla} + \installcompoundcharacter "T {\Tcedilla} + \installcompoundcharacter "` {\startdelimitedtext[\v!quotation]} + \installcompoundcharacter "' {\stopdelimitedtext} + +\stoplanguagespecifics + +\protect \endinput diff --git a/tex/context/base/enco-fsl.mkii b/tex/context/base/enco-fsl.mkii new file mode 100644 index 000000000..86a41c88a --- /dev/null +++ b/tex/context/base/enco-fsl.mkii @@ -0,0 +1,32 @@ +%D \module +%D [ file=enco-fsl, +%D version=2005.08.17, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=Slovenian Specialities, +%D author={Hans Hagen, Mojka Miklavec}, +%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 Usage: +%D +%D \starttyping +%D \useencoding[fsl] +%D +%D \starttext +%D \dstroke \language[sl] \dstroke +%D \stoptext +%D \stoptyping + +\unprotect + +\startlanguagespecifics[\s!sl] + \startencoding[\s!default] + \definecharacter dstroke {d\zcaron} % hm, expects a space delimiter + \stopencoding +\stoplanguagespecifics + +\protect \endinput diff --git a/tex/context/base/enco-grk.mkii b/tex/context/base/enco-grk.mkii new file mode 100644 index 000000000..882a3c9b0 --- /dev/null +++ b/tex/context/base/enco-grk.mkii @@ -0,0 +1,190 @@ +%D \module +%D [ file=enco-grk, +%D version=2003.03.01, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=Greek, +%D author=Apostolos Syropoulos, +%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. + +\startmapping[iso-8859-7] + +% Uppercase Greek letters + +\definecasemap 193 193 225 % greekAlpha +\definecasemap 194 194 226 % greekBeta +\definecasemap 195 195 227 % greekGamma +\definecasemap 196 196 228 % greekDelta +\definecasemap 197 197 229 % greekEpsilon +\definecasemap 198 198 230 % greekZeta +\definecasemap 199 199 213 % greekEta +\definecasemap 200 200 232 % greekTheta +\definecasemap 201 201 233 % greekIota +\definecasemap 202 202 234 % greekKappa +\definecasemap 203 203 235 % greekLambda +\definecasemap 204 204 236 % greekMu +\definecasemap 205 205 237 % greekNu +\definecasemap 206 206 238 % greekXi +\definecasemap 207 207 239 % greekOmicron +\definecasemap 208 208 240 % greekPi +\definecasemap 209 209 241 % greekRho +\definecasemap 211 211 243 % greekSigma +\definecasemap 212 212 244 % greekTau +\definecasemap 213 213 245 % greekUpsilon +\definecasemap 214 214 246 % greekPhi +\definecasemap 215 215 247 % greekChi +\definecasemap 216 216 248 % greekPsi +\definecasemap 217 217 249 % greekOmega + +% Lowercase Greek letters + +\definecasemap 225 193 225 % greekalpha +\definecasemap 226 194 226 % greekbeta +\definecasemap 227 195 227 % greekgamma +\definecasemap 228 196 228 % greekdelta +\definecasemap 229 197 229 % greekepsilon +\definecasemap 230 198 230 % greekzeta +\definecasemap 213 199 213 % greeketa +\definecasemap 232 200 232 % greektheta +\definecasemap 233 201 233 % greekiota +\definecasemap 234 202 234 % greekkappa +\definecasemap 235 203 235 % greeklambda +\definecasemap 236 204 236 % greekmu +\definecasemap 237 205 237 % greeknu +\definecasemap 238 206 238 % greekxi +\definecasemap 239 207 239 % greekomicron +\definecasemap 240 208 240 % greekpi +\definecasemap 241 209 241 % greekrho +\definecasemap 242 211 242 % greekfinalsigma +\definecasemap 243 211 243 % greekSigma +\definecasemap 244 212 244 % greekTau +\definecasemap 245 213 245 % greekUpsilon +\definecasemap 246 214 246 % greekPhi +\definecasemap 247 215 247 % greekChi +\definecasemap 248 216 248 % greekPsi +\definecasemap 249 217 249 % greekOmega + +% Accented Uppercase Greek letters + +\definecasemap 182 193 220 % greekAlphatonos +\definecasemap 184 197 221 % greekEpsilontonos +\definecasemap 185 199 222 % greekEtatonos +\definecasemap 186 201 223 % greekIotatonos +\definecasemap 188 207 252 % greekOmicrontonos +\definecasemap 190 213 253 % greekUpsilontonos +\definecasemap 191 217 254 % greekOmegatonos +\definecasemap 218 218 250 % greekIotadialytika +\definecasemap 219 219 251 % greekUpsilondialytika + +% Accented Lowercase Greek letters + +\definecasemap 220 193 220 % greekalphatonos +\definecasemap 221 197 221 % greekepsilontonos +\definecasemap 222 199 222 % greeketatonos +\definecasemap 223 201 223 % greekiotatonos +\definecasemap 252 207 252 % greekomicrontonos +\definecasemap 253 213 253 % greekupsilontonos +\definecasemap 254 217 254 % greekomegatonos +\definecasemap 250 218 250 % greekiotadialytika +\definecasemap 251 219 251 % greekupsilondialytika +\definecasemap 192 218 192 % greekiotadialytikatonos +\definecasemap 224 219 224 % greekupsilondialytikatonos + +\stopmapping + +\startencoding[iso-8859-7] + +% Uppercase Greek letters + +\definecharacter greekAlpha 193 +\definecharacter greekBeta 194 +\definecharacter greekGamma 195 +\definecharacter greekDelta 196 +\definecharacter greekEpsilon 197 +\definecharacter greekZeta 198 +\definecharacter greekEta 199 +\definecharacter greekTheta 200 +\definecharacter greekIota 201 +\definecharacter greekKappa 202 +\definecharacter greekLambda 203 +\definecharacter greekMu 204 +\definecharacter greekNu 205 +\definecharacter greekXi 206 +\definecharacter greekOmicron 207 +\definecharacter greekPi 208 +\definecharacter greekRho 209 +\definecharacter greekSigma 211 +\definecharacter greekTau 212 +\definecharacter greekUpsilon 213 +\definecharacter greekPhi 214 +\definecharacter greekChi 215 +\definecharacter greekPsi 216 +\definecharacter greekOmega 217 + +% Lowercase Greek letters + +\definecharacter greekalpha 225 +\definecharacter greekbeta 226 +\definecharacter greekgamma 227 +\definecharacter greekdelta 228 +\definecharacter greekepsilon 229 +\definecharacter greekzeta 230 +\definecharacter greeketa 231 +\definecharacter greektheta 232 +\definecharacter greekiota 233 +\definecharacter greekkappa 234 +\definecharacter greeklambda 235 +\definecharacter greekmu 236 +\definecharacter greeknu 237 +\definecharacter greekxi 238 +\definecharacter greekomicron 239 +\definecharacter greekpi 240 +\definecharacter greekrho 241 +\definecharacter greekfinalsigma 242 +\definecharacter greeksigma 243 +\definecharacter greektau 244 +\definecharacter greekupsilon 245 +\definecharacter greekphi 246 +\definecharacter greekchi 247 +\definecharacter greekpsi 248 +\definecharacter greekomega 249 + +% Accented Uppercase Greek letters + +\definecharacter greekAlphatonos 182 +\definecharacter greekEpsilontonos 184 +\definecharacter greekEtatonos 185 +\definecharacter greekIotatonos 186 +\definecharacter greekOmicrontonos 188 +\definecharacter greekUpsilontonos 190 +\definecharacter greekOmegatonos 191 +\definecharacter greekIotadialytika 218 +\definecharacter greekUpsilondialytika 219 + +% Accented Lowercase Greek letters + +\definecharacter greekalphatonos 220 +\definecharacter greekepsilontonos 221 +\definecharacter greeketatonos 222 +\definecharacter greekiotatonos 223 +\definecharacter greekomicrontonos 252 +\definecharacter greekupsilontonos 253 +\definecharacter greekomegatonos 254 +\definecharacter greekiotadialytika 250 +\definecharacter greekupsilondialytika 251 +\definecharacter greekiotadialytikatonos 192 +\definecharacter greekupsilondialytikatonos 224 + +% Miscellaneous Greek symbols + +\definecharacter greekleftquot 171 +\definecharacter greekrightquot 187 +\definecharacter greektonos 180 +\definecharacter greekdialytikatonos 181 +\definecharacter greekapostrophos 162 + +\stopencoding diff --git a/tex/context/base/enco-heb.mkii b/tex/context/base/enco-heb.mkii new file mode 100644 index 000000000..443745752 --- /dev/null +++ b/tex/context/base/enco-heb.mkii @@ -0,0 +1,16 @@ +%D \module +%D [ file=enco-heb, +%D version=2005.01.27, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=Hebrew, +%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. + +%D To be done. + +\endinput diff --git a/tex/context/base/enco-ibm.mkii b/tex/context/base/enco-ibm.mkii new file mode 100644 index 000000000..48695ca52 --- /dev/null +++ b/tex/context/base/enco-ibm.mkii @@ -0,0 +1,7 @@ +% temporary module, needed for downward compatibility + +%\input regi-ibm.tex + +\enableregime[ibm] + +\endinput diff --git a/tex/context/base/enco-il2.mkii b/tex/context/base/enco-il2.mkii new file mode 100644 index 000000000..9fb87b2fd --- /dev/null +++ b/tex/context/base/enco-il2.mkii @@ -0,0 +1,157 @@ +%D \module +%D [ file=enco-il2, +%D version=2000.05.07, % 1998.12.01, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=Czech and Slovak ISO Latin 2 Encoding, +%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. + +% This encoding will go but the regime will remain. + +%D This Czech/Slovak encoding is dedicated to Han The Thanh. +%D The numbers are derived from some files he sent me. This +%D definition file is (still) sort of beta. + +\startmapping[il2] + +\resetcaserange 127 to 255 % we map them all to themselves + +\definecaseswap 184 152 +\definecaseswap 181 165 +\definecaseswap 185 169 +\definecaseswap 187 171 +\definecaseswap 190 174 +\definecaseswap 224 192 +\definecaseswap 225 193 +\definecaseswap 228 196 +\definecaseswap 229 197 +\definecaseswap 232 200 +\definecaseswap 233 201 +\definecaseswap 236 204 +\definecaseswap 237 205 +\definecaseswap 239 207 +\definecaseswap 242 210 +\definecaseswap 243 211 +\definecaseswap 244 212 +\definecaseswap 246 214 +\definecaseswap 248 216 +\definecaseswap 249 217 +\definecaseswap 250 218 +\definecaseswap 252 220 +\definecaseswap 253 221 + +\stopmapping + +\startencoding[il2][il2] + +\definecharacter textgrave 18 +\definecharacter textacute 19 +\definecharacter textcaron 20 +\definecharacter textbreve 21 +\definecharacter textmacron 22 +\definecharacter textring 23 +\definecharacter textcedilla 24 +\definecharacter textcircumflex 94 +\definecharacter textdotaccent 95 +\definecharacter texthungarumlaut 125 +\definecharacter texttilde 126 +\definecharacter textdiaeresis 127 + +\definecharacter dotlessi 16 +\definecharacter dotlessj 17 + +\definecharacter aeligature 26 +\definecharacter AEligature 29 +\definecharacter oeligature 27 +\definecharacter OEligature 30 + +\definecharacter ssharp 25 + +\definecharacter Racute 192 +\definecharacter Aacute 193 +\definecharacter Lacute 197 +\definecharacter Eacute 201 +\definecharacter Iacute 205 +\definecharacter Oacute 211 +\definecharacter Uacute 218 +\definecharacter Yacute 221 +\definecharacter racute 224 +\definecharacter aacute 225 +\definecharacter lacute 229 +\definecharacter eacute 233 +\definecharacter iacute 237 +\definecharacter oacute 243 +\definecharacter uacute 250 +\definecharacter yacute 253 + +\definecharacter Lcaron 165 +\definecharacter Scaron 169 +\definecharacter Tcaron 171 +\definecharacter Zcaron 174 +\definecharacter lcaron 181 +\definecharacter scaron 185 +\definecharacter tcaron 187 +\definecharacter zcaron 190 +\definecharacter Ccaron 200 +\definecharacter Ecaron 204 +\definecharacter Dcaron 207 +\definecharacter Ncaron 210 +\definecharacter Rcaron 216 +\definecharacter ccaron 232 +\definecharacter ecaron 236 +\definecharacter dcaron 239 +\definecharacter ncaron 242 +\definecharacter rcaron 248 + +\definecharacter Ocircumflex 212 +\definecharacter ocircumflex 244 + +\definecharacter Adiaeresis 196 +\definecharacter Odiaeresis 214 +\definecharacter Udiaeresis 220 +\definecharacter adiaeresis 228 +\definecharacter odiaeresis 246 +\definecharacter udiaeresis 252 + +\definecharacter Agrave 152 +\definecharacter agrave 184 + +\definecharacter Ohungarumlaut 213 +\definecharacter Uhungarumlaut 219 +\definecharacter ohungarumlaut 245 +\definecharacter uhungarumlaut 251 + +\definecharacter Uring 217 +\definecharacter uring 249 +\definecharacter Aring {\ilencodedrA} + +\definecharacter ostroke 28 +\definecharacter Ostroke 31 +\definecharacter Lstroke {\ilencodedL} +\definecharacter lstroke {\ilencodedl} + +\def\ilencodedrA + {\dontleavehmode\hbox\bgroup + \setbox0\hbox{h}% + \dimen0=\ht0 + \advance\dimen0 by -1ex + \rlap{\raise.67\dimen0\hbox{\char'27}}A% + \egroup} + +\def\ilencodedl + {\dontleavehmode{\char32l}} + +\def\ilencodedL + {\dontleavehmode\hbox\bgroup + \setbox0\hbox{L}% + \hbox to\wd0{\hss\char32L}% + \egroup} + +\stopencoding + +\endinput diff --git a/tex/context/base/enco-ini.mkii b/tex/context/base/enco-ini.mkii new file mode 100644 index 000000000..33825f94d --- /dev/null +++ b/tex/context/base/enco-ini.mkii @@ -0,0 +1,1137 @@ +%D \module +%D [ file=enco-ini, +%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 / Hans Hagen \& Ton Otten}] +%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 / Initialization} + +\unprotect + +%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.mkii} + {\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 + +\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.mkii} +\fetchruntimecommand \showcharacters {\f!encodingprefix\s!run.mkii} +\fetchruntimecommand \showcharacterbounds {\f!encodingprefix\s!run.mkii} +\fetchruntimecommand \showhyphenations {\f!encodingprefix\s!run.mkii} +\fetchruntimecommand \showmapping {\f!encodingprefix\s!run.mkii} + +%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,l7x,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 new file mode 100644 index 000000000..da1892faf --- /dev/null +++ b/tex/context/base/enco-ini.mkiv @@ -0,0 +1,536 @@ +%D \module +%D [ file=enco-ini, +%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 / Hans Hagen \& Ton Otten}] +%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 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. We keep only a few commands +%D around, just in case they are used in styles (and in for instance +%D symb and xtag files). + +\unexpanded\def\startencoding [#1]{} % used in symb +\let\stopencoding \relax +\unexpanded\def\setupencoding [#1]{} +\def\enablemapping [#1]{} +\def\enableencoding[#1]{} + +\def\currentencoding{utf} +\def\currentmapping {utf} +\let\defaultencoding\s!default + +% 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} + +\unexpanded\def\defineaccent#1 #2 #3 % + {\setevalue{\string#1}{\noexpand\dohandleaccent{\string#1}}% + \setvalue{\??ac\string#1\string#2}{#3}} + +\def\dohandleaccent#1#2% + {\csname\??ac\string#1\string#2\empty\endcsname} + +\unexpanded\def\definecharacter#1 #2 % + {\doifnumberelse{\string#2} + {\setevalue{\string#1}{\utfchar{#2}}} % or {\expandafter\chardef\csname#1\endcsname#2\relax} + {\setuvalue {\string#1}{#2}}} + +\unexpanded\def\definecommand#1 #2 % + {\setuvalue{\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 + +\def\buildmathaccent#1% + {\mathaccent#1 } + +\unexpanded\def\buildtextaccent#1#2% + {\begingroup + \global\setbox\accenttestbox\hbox{#1}% + \scratchcounter\ctxlua{characters.charcode(\number\accenttestbox)}% + \ifcase\scratchcounter\else\accent\scratchcounter\fi + \relax#2% + \endgroup} + +\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}}} + +\unexpanded\def\buildtextmacron {\bottomaccent{.25ex}{0}{15}{\textmacron}} +\unexpanded\def\buildtextbottomdot {\bottomaccent{.25ex}{0}{5}{\textbottomdot}} +\unexpanded\def\buildtextcedilla {\bottomaccent{0ex}{0}{5}{\textcedilla}} +\unexpanded\def\buildtextogonek {\bottomaccent{-.1ex}{.5}{0}{\textogonek}} +\unexpanded\def\buildtextbottomcomma{\bottomaccent{.15ex}{0}{5}{\tx,}} + +\let\d\buildtextbottomdot + +\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. + +\unexpanded\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} + +% 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} + +\chardef\textcontrolspace"2423 + +\unexpanded\def\fallbackcontrolspace + %{\getglyph{ComputerModernMono}\textcontrolspace} + {\getglyph{LMTypewriter10-Regular}\textcontrolspace} + +\unexpanded\def\normalcontrolspace + {\iffontchar\font\textcontrolspace + \textcontrolspace + \else + \fallbackcontrolspace + \fi} + +\let\textvisiblespace\normalcontrolspace + +\unexpanded\def\fastcontrolspace % no glyph resolving after first (use grouped) + {\dofastcontrolspace} + +\def\dofastcontrolspace + {\iffontchar\font\textcontrolspace + \nofastfallbackcontrolspace + \else + \dofastfallbackcontrolspace + \fi + \dofastcontrolspace} + +\newbox\controlspacebox + +\def\nofastfallbackcontrolspace + {\let\dofastcontrolspace\textcontrolspace} + +\def\dofastfallbackcontrolspace + {\setbox\controlspacebox\hbox{\space}% + \setbox\controlspacebox\hbox to \wd\controlspacebox{\hss\fallbackcontrolspace\hss}% + \let\dofastcontrolspace\flushcontrolspacebox} + +\def\flushcontrolspacebox + {\copy\controlspacebox} + +% a few defaults (\<whatever>{}), we really need the verbose \empty as it will be +% stringified + +\defineaccent ^ {\empty} {\textcircumflex} +\defineaccent ` {\empty} {\textgrave} +\defineaccent ~ {\empty} {\texttilde} +\defineaccent " {\empty} {\textdiaeresis} +\defineaccent ' {\empty} {\textacute} +\defineaccent . {\empty} {\textdotaccent} +\defineaccent = {\empty} {\textmacron} +\defineaccent c {\empty} {\textcedilla} +\defineaccent H {\empty} {\texthungarumlaut} +\defineaccent k {\empty} {\textogonek} +\defineaccent r {\empty} {\textring} +\defineaccent u {\empty} {\textbreve} +\defineaccent v {\empty} {\textcaron} + +% from enco-acc: +% +% we should to this at the lua end and share code .. + +\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 ~ N {\Ntilde} \defineaccent ~ n {\ntilde} + +\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 +% {\dontleavehmode\hbox % was \leavevmode +% {\setbox\scratchbox\hbox{(}% +% \scratchdimen.2\dp\scratchbox +% \setbox\scratchbox\hbox{\space}% +% \vrule +% \!!depth \scratchdimen +% \!!width \wd\scratchbox +% \!!height\zeropoint}} + +% \startTEXpage +% \ruledhbox{\strut$1\fakeunderscore^{1\fakeunderscore}$} +% \ruledhbox{\strut$1\xfakeunderscore^{1\xfakeunderscore}$} +% \stopTEXpage + +\def\fakeunderscore + {\relax\ifmmode + \vrule\!!depth .12\fontexheight\mathstylefont\normalmathstyle\!!width \fontinterwordspace\mathstylefont\normalmathstyle\!!height\zeropoint\relax + \else + \dontleavehmode\hbox{\vrule\!!depth .12\fontexheight\font\!!width \fontinterwordspace\font\!!height\zeropoint}% + \fi} + +\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-l7x.mkii b/tex/context/base/enco-l7x.mkii new file mode 100644 index 000000000..8f355317b --- /dev/null +++ b/tex/context/base/enco-l7x.mkii @@ -0,0 +1,236 @@ +%D \module +%D [ file=enco-l7x, +%D version=2010.01.22, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=\LATEX\ L7x Encoding, +%D author={Hans Hagen \& Mojca Miklavec}, +%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. + +%D Encoding vector to support Latvian and Lithuanian. The first +%D part is taken from EC encoding, the rest has not been tested +%D extensively. + +\startmapping[l7x] + +\definecaseswap 25 `I % dotless i (TODO - probably wrong; maybe use \defineuppercasecom) +\definecaseswap 156 140 % oeligature +\definecaseswap 184 168 % ostroke +\definecaseswap 186 170 % rcommaaccent +\definecaseswap 191 175 % aeligature +\definecaseself 223 % ssharp (this is wrong, but no better way) + +\definecasemaps 192 to 222 lc +32 uc 0 +\definecasemaps 224 to 254 lc 0 uc -32 +\resetcaserange 215 to 215 % textmultiply +\resetcaserange 247 to 247 % textdiv + +\stopmapping + +\startencoding[l7x] + +\definecharacter textgrave 0 +\definecharacter textacute 1 +\definecharacter textcircumflex 2 +\definecharacter texttilde 3 +\definecharacter textdiaeresis 4 +\definecharacter texthungarumlaut 5 +\definecharacter textring 6 +\definecharacter textcaron 7 +\definecharacter textbreve 8 +\definecharacter textmacron 9 +\definecharacter textdotaccent 10 +\definecharacter textcedilla 11 +\definecharacter textogonek 12 +\definecharacter quotesinglebase 13 +\definecharacter guilsingleleft 14 +\definecharacter guilsingleright 15 +\definecharacter quotedblleft 16 +\definecharacter quotedblright 17 +\definecharacter quotedblbase 18 +\definecharacter leftguillemot 19 +\definecharacter rightguillemot 20 +\definecharacter endash 21 +\definecharacter emdash 22 +%definecharacter compoundwordmark 23 +%definecharacter perthousand 24 +\definecharacter dotlessi 25 % or when missing: {j} +\definecharacter dotlessj 26 +% ff 27 +% fi 28 +% fl 29 +% ffi 30 +% ffl 31 +%definecharacter textvisiblespace 32 +% exclam ! 33 +\definecharacter quotedbl 34 +% numbersign # 35 +% dollar $ 36 +\definecharacter percent 37 +% ampersand & 38 +%definecharacter quotesingle 39 % fake 'm TODO:enco-def!!!! +\definecharacter quoteright 39 +% parenleft ( 40 +% parenright ) 41 +% asterisk * 42 +% plus + 43 +% comma , 44 +\definecharacter softhyphen 45 +% period . 46 +% slash / 47 +% 0-9 48-57 +% colon : 58 +% semicolon ; 59 +% less < 60 +% equal = 61 +% greater > 62 +% question ? 63 +% at @ 64 +% A-Z 65-90 +% bracketleft [ 91 +\definecharacter textbackslash 92 +% bracketright ] 93 +\definecharacter textasciicircum 94 +\definecharacter textunderscore 95 +\definecharacter quoteleft 96 +% a-z 97-122 +\definecharacter textbraceleft 123 +\definecharacter textbraceright 125 +\definecharacter textasciitilde 126 +% .notdef 127 +\definecharacter texteuro 128 +% .notdef 129 +\definecharacter quotesinglebase 130 +\definecharacter textflorin 131 \definecharacter fhook 131 +\definecharacter quotedblbase 132 +\definecharacter textellipsis 133 +\definecharacter textdag 134 +\definecharacter textddag 135 +% .notdef 136 +\definecharacter perthousand 137 +% .notdef 138 +\definecharacter guilsingleleft 139 +\definecharacter OEligature 140 % TODO: also \OE??? +\definecharacter textdiaeresis 141 +\definecharacter textcaron 142 +\definecharacter textcedilla 143 +% .notdef 144 +\definecharacter quoteleft 145 +\definecharacter quoteright 146 +\definecharacter quotedblleft 147 +\definecharacter quotedblright 148 +\definecharacter textbullet 149 +\definecharacter endash 150 +\definecharacter emdash 151 +% .notdef 152 +\definecharacter trademark 153 +% .notdef 154 +\definecharacter guilsingleright 155 +\definecharacter oeligature 156 +\definecharacter textmacron 157 +\definecharacter textogonek 158 +% .notdef 159 +%definecharacter space 160 % TODO!!! +\definecharacter quotedblright 161 +\definecharacter textcent 162 +\definecharacter textsterling 163 +\definecharacter textcurrency 164 +\definecharacter quotedblbase 165 +\definecharacter textbrokenbar 166 +\definecharacter sectionmark 167 +\definecharacter Ostroke 168 +\definecharacter copyright 169 +\definecharacter Rcommaaccent 170 +\definecharacter leftguillemot 171 +\definecharacter textlognot 172 +%definecharacter softhyphen 173 % -> 45 (TODO!!!) +\definecharacter registered 174 +\definecharacter AEligature 175 +\definecharacter textdegree 176 +\definecharacter textpm 177 +\definecharacter twosuperior 178 +\definecharacter threesuperior 179 +\definecharacter quotedblleft 180 +\definecharacter textmu 181 +\definecharacter paragraphmark 182 +\definecharacter periodcentered 183 +\definecharacter ostroke 184 +\definecharacter onesuperior 185 +\definecharacter rcommaaccent 186 +\definecharacter rightguillemot 187 +\definecharacter onequarter 188 +\definecharacter onehalf 189 +\definecharacter threequarter 190 +\definecharacter aeligature 191 +\definecharacter Aogonek 192 +\definecharacter Iogonek 193 +\definecharacter Amacron 194 +\definecharacter Cacute 195 +\definecharacter Adiaeresis 196 +\definecharacter Aring 197 +\definecharacter Eogonek 198 +\definecharacter Emacron 199 +\definecharacter Ccaron 200 +\definecharacter Eacute 201 +\definecharacter Zacute 202 +\definecharacter Edotaccent 203 +\definecharacter Gcommaaccent 204 +\definecharacter Kcommaaccent 205 +\definecharacter Imacron 206 +\definecharacter Lcommaaccent 207 +\definecharacter Scaron 208 +\definecharacter Nacute 209 +\definecharacter Ncommaaccent 210 +\definecharacter Oacute 211 +\definecharacter Omacron 212 +\definecharacter Otilde 213 +\definecharacter Odiaeresis 214 +\definecharacter textmultiply 215 +\definecharacter Uogonek 216 +\definecharacter Lstroke 217 +\definecharacter Sacute 218 +\definecharacter Umacron 219 +\definecharacter Udiaeresis 220 +\definecharacter Zdotaccent 221 +\definecharacter Zcaron 222 +\definecharacter ssharp 223 +\definecharacter aogonek 224 +\definecharacter iogonek 225 +\definecharacter amacron 226 +\definecharacter cacute 227 +\definecharacter adiaeresis 228 +\definecharacter aring 229 +\definecharacter eogonek 230 +\definecharacter emacron 231 +\definecharacter ccaron 232 +\definecharacter eacute 233 +\definecharacter zacute 234 +\definecharacter edotaccent 235 +\definecharacter gcommaaccent 236 +\definecharacter kcommaaccent 237 +\definecharacter imacron 238 +\definecharacter lcommaaccent 239 +\definecharacter scaron 240 +\definecharacter nacute 241 +\definecharacter ncommaaccent 242 +\definecharacter oacute 243 +\definecharacter omacron 244 +\definecharacter otilde 245 +\definecharacter odiaeresis 246 +\definecharacter textdiv 247 +\definecharacter uogonek 248 +\definecharacter lstroke 249 +\definecharacter sacute 250 +\definecharacter umacron 251 +\definecharacter udiaeresis 252 +\definecharacter zdotaccent 253 +\definecharacter zcaron 254 +\definecharacter quoteright 255 + +\stopencoding + +\endinput diff --git a/tex/context/base/enco-lat.mkii b/tex/context/base/enco-lat.mkii new file mode 100644 index 000000000..2623aae8d --- /dev/null +++ b/tex/context/base/enco-lat.mkii @@ -0,0 +1,7 @@ +% temporary module, needed for downward compatibility + +\input regi-lat.tex + +\enableregime[latin2] + +\endinput diff --git a/tex/context/base/enco-mis.mkii b/tex/context/base/enco-mis.mkii new file mode 100644 index 000000000..92dc61b3f --- /dev/null +++ b/tex/context/base/enco-mis.mkii @@ -0,0 +1,188 @@ +%D \module +%D [ file=enco-mis, +%D version=2000.05.07, % 1999.11.11, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=Missing Glyphs, +%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. + +%D In this file we collect some definitions that construct +%D pseudo characters. Some day we will move some definitions +%D from \type {plain.tex} to this file. Some definitions are +%D derived from definitions in the \LATEX\ distribution, +%D especially Johannes Braams' Babel system. + +\startmapping[\s!default] + +\defineuppercasecom \dj \DJ +\defineuppercasecom \Dj \dj +\defineuppercasecom \DJ \dj + +\definecharacter dstroke {\pseudoencodeddj} +\definecharacter Dstroke {\pseudoencodedDJ} + +\stopmapping + +%D We need proper names like in enco-com.tex! + +\definecharacter dj {\dstroke} % {\pseudoencodeddj} +\definecharacter Dj {\Dstroke} % {\pseudoencodedDJ} +\definecharacter DJ {\Dstroke} % {\pseudoencodedDJ} + +\unprotect + +\def\pseudoencodeddj % like in babel, but safer + {\dontleavehmode\hbox\bgroup + \setbox\scratchbox\hbox{d}% + \scratchdimen\ht\scratchbox + \advance\scratchdimen 1ex + \scratchdimen.45\scratchdimen + \dimen2=\withoutpt\the\slantperpoint\dimen0 + \advance\dimen2 .5ex + \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 + \setbox\scratchbox\hbox{D}% + \dimen2=1.1ex + \dimen2=\withoutpt\the\slantperpoint\dimen2 + \hbox to \wd\scratchbox + {\rlap + {\raise.52\ht\scratchbox + \hbox + {\kern\dimen2 + \vbox{\hrule\!!height.04ex\!!depth.04ex\!!width.4\wd\scratchbox}}}% + \box\scratchbox}% + \egroup} + +% currency + +\def\fakedollar % pretty cmr dependent + {\bgroup + \ifnum\fam=\itfam + \sl + \else\ifnum\fam=\bifam + \bs + \fi\fi + \$% + \egroup} + +\def\fakesterling % pretty cmr dependent + {\bgroup + \ifnum\fam=\bffam + \bi + \else\ifnum\fam=\bifam + \bi + \else\ifnum\fam=\bsfam + \bi + \else + \it + \fi\fi\fi + \$% + \egroup} + +\def\fakeflorin + {\bgroup + \ifnum\fam=\bffam + \bi + \else\ifnum\fam=\bifam + \bi + \else\ifnum\fam=\bsfam + \bi + \else + \it + \fi\fi\fi + f% + \egroup} + +% perthings + +\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} + +% guillemots + +%D Yes I know, they are ugly: + +\def\fakeleftguillemot + {\dontleavehmode\hbox{\raise.25ex\hbox{$\scriptscriptstyle\ll$}}} + +\def\fakerightguillemot + {\hbox{\raise.25ex\hbox{$\scriptscriptstyle\gg$}}} + +\def\fakeleftsubguillemot + {\dontleavehmode\hbox{\raise.25ex\hbox{$\scriptscriptstyle<$}}} + +\def\fakerightsubguillemot + {\hbox{\raise.25ex\hbox{$\scriptscriptstyle>$}}} + +%D Needed: + +\def\fakevisiblespace + {\leavevmode\hbox + {\setbox\scratchbox\hbox{(}% + \scratchdimen.1\dp\scratchbox + \setbox\scratchbox\hbox{\space}% + \hbox to \wd\scratchbox + {\vrule + \!!depth 5\scratchdimen + \!!width \scratchdimen + \!!height \zeropoint + \hss + \vrule + \!!depth 5\scratchdimen + \!!width \wd\scratchbox + \!!height-4\scratchdimen + \hss + \vrule + \!!depth 5\scratchdimen + \!!width \scratchdimen + \!!height \zeropoint}}} + +%\def\fakeunderscore{\leavevmode\kern.06em\vbox{\hrule\!!width.3em}} + +\def\fakeunderscore + {\leavevmode\hbox + {\setbox\scratchbox\hbox{(}% + \scratchdimen.2\dp\scratchbox + \setbox\scratchbox\hbox{\space}% + \vrule + \!!depth \scratchdimen + \!!width \wd\scratchbox + \!!height\zeropoint}} + +\ifx\mathunderscore\undefined \let\mathunderscore\fakeunderscore \fi +\ifx\textunderscore\undefined \let\textunderscore\fakeunderscore \fi + +\unexpanded\def\normalunderscore{\ifmmode\mathunderscore\else\textunderscore\fi} + +\let\_\normalunderscore + +% Handy but obsolete, replaced by \unknownchar: +% +% \def\missingglyph{\ruledhbox{?}} + +\protect \endinput diff --git a/tex/context/base/enco-pdf.mkii b/tex/context/base/enco-pdf.mkii new file mode 100644 index 000000000..a03e81df2 --- /dev/null +++ b/tex/context/base/enco-pdf.mkii @@ -0,0 +1,278 @@ +%D \module +%D [ file=enco-pdf, +%D version=1995.01.01, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=\YandY\ texnansi Encoding, +%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 This is the \PDF\ document encoding. + +\startencoding[pdfdoc] % \rawcharacter{number} + +\definecharacter oeligature ^^9c + +\definecharacter leftguillemot ^^ab +\definecharacter rightguillemot ^^bb + +\definecharacter Agrave ^^c0 +\definecharacter Aacute ^^c1 +\definecharacter Acircumflex ^^c2 +\definecharacter Atilde ^^c3 +\definecharacter Adiaeresis ^^c4 +\definecharacter OAligature ^^c5 +\definecharacter AEligature ^^c6 +\definecharacter Ccedilla ^^c7 +\definecharacter Egrave ^^c8 +\definecharacter Eacute ^^c9 +\definecharacter Ecircumflex ^^ca +\definecharacter Ediaeresis ^^cb +\definecharacter Igrave ^^cc +\definecharacter Iacute ^^cd +\definecharacter Icircumflex ^^ce +\definecharacter Idiaeresis ^^cf + +\definecharacter Ntilde ^^d1 +\definecharacter Ograve ^^d2 +\definecharacter Oacute ^^d3 +\definecharacter Ocircumflex ^^d4 +\definecharacter Otilde ^^d5 +\definecharacter Odiaeresis ^^d6 + +\definecharacter Ugrave ^^d9 +\definecharacter Uacute ^^da +\definecharacter Ucircumflex ^^db +\definecharacter Udiaeresis ^^dc +\definecharacter Yacute ^^dd + +\definecharacter ssharp ^^df +\definecharacter agrave ^^e0 +\definecharacter aacute ^^e1 +\definecharacter acircumflex ^^e2 +\definecharacter atilde ^^e3 +\definecharacter adiaeresis ^^e4 +\definecharacter oaligature ^^e5 +\definecharacter aeligature ^^e6 +\definecharacter ccedilla ^^e7 +\definecharacter egrave ^^e8 +\definecharacter eacute ^^e9 +\definecharacter ecircumflex ^^ea +\definecharacter ediaeresis ^^eb +\definecharacter igrave ^^ec +\definecharacter iacute ^^ed +\definecharacter icircumflex ^^ee +\definecharacter idiaeresis ^^ef + +\definecharacter ntilde ^^f1 +\definecharacter ograve ^^f2 +\definecharacter oacute ^^f3 +\definecharacter ocircumflex ^^f4 +\definecharacter otilde ^^f5 +\definecharacter odiaeresis ^^f6 + +\definecharacter ugrave ^^f9 +\definecharacter uacute ^^fa +\definecharacter ucircumflex ^^fb +\definecharacter udiaeresis ^^fc +\definecharacter yacute ^^fd + +\definecharacter ydiaeresis ^^ff + +\definecharacter leftsubguillemot {\leftguillemot} +\definecharacter rightsubguillemot {\rightguillemot} + +\definecharacter Uhungarumlaut {\Ucircumflex} +\definecharacter uhungarumlaut {\ucircumflex} +\definecharacter Ohungarumlaut {\Ocircumflex} +\definecharacter ohungarumlaut {\ocircumflex} + +\definecharacter Aogonek {A} +\definecharacter aogonek {a} +\definecharacter Eogonek {E} +\definecharacter eogonek {e} +\definecharacter Iogonek {I} +\definecharacter iogonek {i} +\definecharacter Uogonek {U} +\definecharacter uogonek {u} + +\definecharacter Aring {A} +\definecharacter aring {a} +\definecharacter Uring {U} +\definecharacter uring {u} + +\definecharacter Abreve {A} +\definecharacter abreve {a} +\definecharacter Ebreve {E} +\definecharacter ebreve {e} +\definecharacter Gbreve {G} +\definecharacter gbreve {g} +\definecharacter Ibreve {I} +\definecharacter ibreve {i} +\definecharacter Obreve {O} +\definecharacter obreve {o} +\definecharacter Ubreve {U} +\definecharacter ubreve {u} + +\definecharacter Ccaron {C} +\definecharacter ccaron {c} +\definecharacter Dcaron {D} +\definecharacter dcaron {d} +\definecharacter Ecaron {E} +\definecharacter ecaron {e} +\definecharacter Lcaron {L} +\definecharacter lcaron {l} +\definecharacter Ncaron {N} +\definecharacter ncaron {n} +\definecharacter Rcaron {R} +\definecharacter rcaron {r} +\definecharacter Scaron {S} +\definecharacter scaron {s} +\definecharacter Tcaron {T} +\definecharacter tcaron {t} +\definecharacter Ycaron {Y} +\definecharacter ycaron {y} +\definecharacter Zcaron {Z} +\definecharacter zcaron {z} + +\definecharacter Lstroke {L} +\definecharacter lstroke {l} +\definecharacter Ostroke {O} +\definecharacter ostroke {o} + +\definecharacter aumlaut {\adiaeresis} +\definecharacter eumlaut {\ediaeresis} +\definecharacter iumlaut {\idiaeresis} +\definecharacter oumlaut {\odiaeresis} +\definecharacter uumlaut {\udiaeresis} + +\definecharacter Aumlaut {\Adiaeresis} +\definecharacter Eumlaut {\Ediaeresis} +\definecharacter Iumlaut {\Idiaeresis} +\definecharacter Oumlaut {\Odiaeresis} +\definecharacter Uumlaut {\Udiaeresis} + +\definecharacter scommaaccent {s} +\definecharacter Scommaaccent {S} +\definecharacter tcommaaccent {t} +\definecharacter Tcommaaccent {T} + +\definecharacter Etilde {E} +\definecharacter etilde {e} + +\definecharacter Ahook {A} +\definecharacter ahook {a} +\definecharacter Ehook {E} +\definecharacter ehook {e} +\definecharacter Ihook {I} +\definecharacter ihook {i} +\definecharacter Ohook {O} +\definecharacter ohook {o} +\definecharacter Uhook {U} +\definecharacter uhook {u} +\definecharacter Yhook {Y} +\definecharacter yhook {y} + +\definecharacter Acircumflexgrave {\Acircumflex} +\definecharacter Acircumflexacute {\Acircumflex} +\definecharacter Acircumflextilde {\Acircumflex} +\definecharacter Acircumflexhook {\Acircumflex} +\definecharacter acircumflexgrave {\acircumflex} +\definecharacter acircumflexacute {\acircumflex} +\definecharacter acircumflextilde {\acircumflex} +\definecharacter acircumflexhook {\acircumflex} +\definecharacter Ecircumflexgrave {\Ecircumflex} +\definecharacter Ecircumflexacute {\Ecircumflex} +\definecharacter Ecircumflextilde {\Ecircumflex} +\definecharacter Ecircumflexhook {\Ecircumflex} +\definecharacter ecircumflexgrave {\ecircumflex} +\definecharacter ecircumflexacute {\ecircumflex} +\definecharacter ecircumflextilde {\ecircumflex} +\definecharacter ecircumflexhook {\ecircumflex} +\definecharacter Ocircumflexgrave {\Ocircumflex} +\definecharacter Ocircumflexacute {\Ocircumflex} +\definecharacter Ocircumflextilde {\Ocircumflex} +\definecharacter Ocircumflexhook {\Ocircumflex} +\definecharacter ocircumflexgrave {\ocircumflex} +\definecharacter ocircumflexacute {\ocircumflex} +\definecharacter ocircumflextilde {\ocircumflex} +\definecharacter ocircumflexhook {\ocircumflex} + +\definecharacter Abrevegrave {A} +\definecharacter Abreveacute {A} +\definecharacter Abrevetilde {A} +\definecharacter Abrevehook {A} +\definecharacter abrevegrave {a} +\definecharacter abreveacute {a} +\definecharacter abrevetilde {a} +\definecharacter abrevehook {a} + +\definecharacter Adotbelow {A} +\definecharacter adotbelow {a} +\definecharacter Edotbelow {E} +\definecharacter edotbelow {e} +\definecharacter Idotbelow {I} +\definecharacter idotbelow {i} +\definecharacter Odotbelow {O} +\definecharacter odotbelow {o} +\definecharacter Udotbelow {U} +\definecharacter udotbelow {u} +\definecharacter Ydotbelow {Y} +\definecharacter ydotbelow {y} +\definecharacter Ohorndotbelow {O} +\definecharacter ohorndotbelow {o} +\definecharacter Uhorndotbelow {U} +\definecharacter uhorndotbelow {u} + +\definecharacter Acircumflexdotbelow {\Acircumflex} +\definecharacter acircumflexdotbelow {\acircumflex} +\definecharacter Ecircumflexdotbelow {\Ecircumflex} +\definecharacter ecircumflexdotbelow {\ecircumflex} +\definecharacter Ocircumflexdotbelow {\Ocircumflex} +\definecharacter ocircumflexdotbelow {\ocircumflex} +\definecharacter Abrevedotbelow {\Abreve} +\definecharacter abrevedotbelow {\abreve} + +\definecharacter Ohorn {O} +\definecharacter Ohorngrave {O} +\definecharacter Ohornacute {O} +\definecharacter Ohorntilde {O} +\definecharacter Ohornhook {O} + +\definecharacter ohorn {o} +\definecharacter ohorngrave {o} +\definecharacter ohornacute {o} +\definecharacter ohorntilde {o} +\definecharacter ohornhook {o} + +\definecharacter Uhorn {U} +\definecharacter Uhorngrave {U} +\definecharacter Uhornacute {U} +\definecharacter Uhorntilde {U} +\definecharacter Uhornhook {U} + +\definecharacter uhorn {u} +\definecharacter uhorngrave {u} +\definecharacter uhornacute {u} +\definecharacter uhorntilde {u} +\definecharacter uhornhook {u} + +\definecharacter Utilde {U} +\definecharacter utilde {u} +\definecharacter Itilde {I} +\definecharacter itilde {i} +\definecharacter Ygrave {Y} +\definecharacter ygrave {y} +\definecharacter Ytilde {Y} +\definecharacter ytilde {y} + +\definecharacter dstroke {d} +\definecharacter Dstroke {D} + +\stopencoding + +\endinput diff --git a/tex/context/base/enco-pfr.mkii b/tex/context/base/enco-pfr.mkii new file mode 100644 index 000000000..b279e40aa --- /dev/null +++ b/tex/context/base/enco-pfr.mkii @@ -0,0 +1,305 @@ +%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 Resources, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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>\pdftexengine + \expandafter \endinput +\fi + +\ifdefined\pdffontresource \else + \expandafter \endinput +\fi + +\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 +%D font resources is that it enables a search engine to +%D perform a search (I'm told). This feature ws requested by +%D Petr Ferdus from Czech. + +%D A simple test file may look like this (watch how we first +%D load the encoding and then the font; previous font +%D definitions are left untouched.) +%D +%D \starttyping +%D % output=pdftex interface=en +%D +%D \useencoding[pfr] +%D \setupbodyfont[csr] +%D +%D \starttext +%D test \`z \'z \bf test \sl test \bs quite funny \`z \page +%D test \`z \'z \bf test \sl test \bs quite funny \`z \page +%D \stoptext +%D \stoptyping +%D +%D We do our best to include a (often large) font resources +%D only once. The current implementation is not that +%D general which is also due to the fact that \type +%D {\pdffontattr} is expanded instantly and persistent. A +%D more versatile (but also slower) approach is to keep track +%D of the fonts and either flush the information at shipout +%D time, or at the end of the document. + +%D \macros +%D {ifincludepdffontresources} +%D +%D You can turn of this feature using the following switch. + +\newif\ifincludepdffontresources \includepdffontresourcestrue + +\ifx\pdfglyphtounicode\undefined \else + \appendtoks + \doif\jobsuffix{pdf}{\readfile{pdfr-def.mkii}\donothing\donothing}% + \to \everystarttext +\fi + +% somehow we cannot preload this beast; also, it's mk dependent +% +% \appendtoks +% \doifelse{\jobsuffix}{pdf}{\loadmkiifile{pdfr-def.mkii}}% +% \to \everystarttext + +% ugly, this should go to the driver spec-tpd + +\ifx\pdfgentounicode\undefined \else + \ifcase\pdfgentounicode \else + \expandafter \expandafter \expandafter \endinput + \fi +\fi + +\unprotect + +% a problem is that there is always an ec vector added even when +% we switch to texnansi early; this has to do with the fact that +% we need to setup fonts at startup; this a pain when we have +% textless documents, so we should have a way around, i.e. an +% extension to pdftex where we can tag numbers inside user specs +% and attributes. +% +% currently we need to use immediate so we end up with entries + +%D The name of the resource is stored in a macro, as is its +%D object reference. A resource is only processed once. When +%D done, the resource name is erased, and we use this fact to +%D prevent redefinition as well as well as reloading. So, a +%D macro defined with \type {\pdffontfileresource} can have +%D three states: +%D +%D \startitemize[packed] +%D \item undefined: not yet loaded, and not yet included +%D \item some value: loaded, but not yet included +%D \item empty: loaded, and already included +%D \stopitemize + +\def\pdffontresource {pdfr:\currentencoding} +\def\pdffontfileresource{pdff:\pdffontresource} + +%D A resource is defined in a file prefixed by \type {pdfr-}. +%D The following \PDF\ code is composed by Ondrej Koala Vacha (I +%D probably mispelled this name). +%D +%D \starttyping +%D \startpdffontresource[il2] +%D /CIDInit /ProcSet findresource begin +%D 12 dict begin +%D begincmap +%D /CIDSystemInfo +%D << /Registry (Adobe) +%D /Ordering (T1UV) +%D /Supplement 0 +%D >> def +%D /CMapName /Adobe-Identity-UCS def +%D /CMapType 1 def +%D 1 begincodespacerange +%D <00> <FF> +%D endcodespacerange +%D %%FontSpecificEncoding +%D 191 beginbfrange +%D <20> <20> <0020> % space dec: 32 oct:040 hex:20 +%D .... .... ...... . ........ .... .. ....... ...... +%D <ff> <ff> <00ff> % dotaccent dec:255 oct:377 hex:ff +%D endbfrange +%D endcmap +%D CMapName currentdict /CMap defineresource pop end +%D end +%D \stoppdffontresource +%D \stoptyping +%D +%D We don't preload such huge definitions, and process them +%D run||time to save memory. Therefore, in the encoding +%D vector, we only add an entry like: +%D +%D \starttyping +%D \startencoding [il2] +%D \usepdffontresource il2 +%D \stopencoding +%D \stoptyping +%D +%D This macro is defined as follows. + +\def\usepdffontresource #1 % + {\doifundefinedelse\pdffontfileresource % okay, undefined, so either + {\setxvalue\pdffontfileresource{#1}} % brand new, or not yet loaded + {\doifvaluesomething\pdffontfileresource % only if not loaded in which + {\setxvalue\pdffontfileresource{#1}}}} % case it's made empty + +%D Watch how we check for duplicated loading. The resource +%D itself, when asked for, is included immediately, after which +%D we save its reference. Normally a document will have one +%D such a resource. + +% \long\def\startpdffontresource[#1]#2\stoppdffontresource +% {\doif{#1}\currentencoding +% {\immediate\pdfobj useobjnum \getvalue{\pdffontresource} stream {#2}}} + +% alternatively we can use object references + +% fails when we switch back and forward between dvi/pdf mode +% +% \long\def\startpdffontresource[#1]#2\stoppdffontresource +% {\doif{#1}\currentencoding{\doifdefined\pdffontresource +% {\immediate\pdfobj useobjnum \getvalue{\pdffontresource} stream {#2}}}} + +\long\def\startpdffontresource[#1]#2\stoppdffontresource + {\doif{#1}\currentencoding{\doifdefined\pdffontresource + {\expanded{\doshipoutpdffontresource{\getvalue{\pdffontresource}}{#2}}}}} + +\def\doshipoutpdffontresource#1#2% + {\ifnum\realpageno<\plustwo + \doglobal\appendtoks + \ifcase\pdfoutput\else\immediate\pdfobj useobjnum #1 stream {#2}\fi + \to\everyfirstshipout + \else + \ifcase\pdfoutput\else\immediate\pdfobj useobjnum #1 stream {#2}\fi + \fi} + +% cleaner but not better: +% +% \newtoks \collectedpdffontresources +% +% \def\doshipoutpdffontresource#1#2% +% {\doglobal\appendtoks +% \ifcase\pdfoutput\else\immediate\pdfobj useobjnum #1 stream {#2}\fi +% \to \collectedpdffontresources} +% +% \def\dofluspdffontresources +% {\the\collectedpdffontresources +% \global\collectedpdffontresources\emptytoks} +% +% \appendtoks \dofluspdffontresources \to \everybeforeshipout + +%D The reference to such a vector is to be handled at font +%D definition time, which is why we hook it into the font +%D loading routine. A little bit of indirectness speeds up +%D the process when this feature is disabled and keeps the +%D macros readable. + +% \newevery \everyfont \relax + +\appendtoksonce \includepdffontresource \to \everyfont + +% \def\includepdffontresource +% {\ifincludepdffontresources +% \ifx\pdffontattr\undefined +% % we're not using (a recent version of) pdftex +% \else\ifcase\pdfoutput +% % we're not in pdf mode +% \else +% \doincludepdffontresource +% \fi\fi +% \fi} + +\def\includepdffontresource + {\ifx\pdfgentounicode\undefined + \expandafter\ifx\the\font\nullfont \else + \ifx\pdffontattr\undefined + % we're not using (a recent version of) pdftex + \else\ifcase\pdfoutput + % we're not in pdf mode + \else + \doincludepdffontresource + \fi\fi + \fi + \else\ifcase\pdfgentounicode + \ifincludepdffontresources + \expandafter\ifx\the\font\nullfont \else + \ifx\pdffontattr\undefined + % we're not using (a recent version of) pdftex + \else\ifcase\pdfoutput + % we're not in pdf mode + \else + \doincludepdffontresource + \fi\fi + \fi + \fi + \or + \global\let\includepdffontresource\relax % automatic, built in + \fi\fi} + +\def\dododoincludepdffontresource#1% encoding + {\bgroup + \edef\currentencoding{#1}% + \doifvaluesomething\pdffontfileresource + {\startreadingfile + \ignorelines % just in case \par is redefined; this thing can get called anywhere + \readsysfile{pdfr-\getvalue\pdffontfileresource.mkii}\donothing\donothing + \stopreadingfile + \letgvalue\pdffontfileresource\empty}% + \egroup} + +\def\doincludepdffontresource + {\ifcsname\s!ucmap\fontfile\endcsname\else + \dodoincludepdffontresource + \fi} + +\def\dodoincludepdffontresource + {% does this font has an encoding specified vector + \doifsomething\currentencoding % no \ifx + {% is there a pdf font encoding resource file defined + \ifcsname\pdffontresource\endcsname + % (fake) object defined + \else\ifcsname\pdffontfileresource\endcsname + % is there a resource already included + \doifsomething\pdffontfileresource + {\pdfobj reserveobjnum {}% + \setxvalue\pdffontresource{\the\pdflastobj}% + \flushatshipout{\dododoincludepdffontresource{\currentencoding}}}% +% \doglobal\appendetoks +% \noexpand\dododoincludepdffontresource{\currentencoding}% +% \to \everybeforeshipout}% prevent multiple loading + \fi\fi + \ifcsname\pdffontresource\endcsname + \expanded{\pdffontattr\font{/ToUnicode \csname\pdffontresource\endcsname\space0 R}}% + % do it only once for each font + \letgvalue{\s!ucmap\fontfile}\empty + \fi}} + +%D For the moment, we keep this definition here, if only +%D because \type {\usepdffontencoding} is not defined in the +%D core. In the end, this will go to \type {enco-*.tex}. +%D +%D Test: +%D +%D \starttyping +%D \useencoding[pfr] \usetypescript[palatino][ec] \setupbodyfont[palatino] +%D +%D \starttext +%D fi ff ffi +%D \stoptext +%D \stoptyping + +\startencoding [il2] \usepdffontresource il2 \stopencoding +\startencoding [ec] \usepdffontresource ec \stopencoding + +\protect \endinput diff --git a/tex/context/base/enco-pol.mkii b/tex/context/base/enco-pol.mkii new file mode 100644 index 000000000..a012f0370 --- /dev/null +++ b/tex/context/base/enco-pol.mkii @@ -0,0 +1,276 @@ +%D \module +%D [ file=enco-pol, +%D version=2000.05.07, % 1999.28.8, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=Polish Mixed Encoding, +%D author={Taco Hoekwater \& 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. + +% This encoding will go but the regime will remain. + +%D Polish native encoding; normally polish users will use +%D translate=cp1250pl in combination with ec encoding. + +\startmapping[pl0] + +\resetcaserange 128 to 255 + +\definecaseswap 161 129 % a ogonek +\definecaseswap 162 130 % c acute +\definecaseswap 166 134 % e ogonek +\definecaseswap 170 138 % l crossed +\definecaseswap 171 139 % n acute +\definecaseswap 177 145 % s acute +\definecaseswap 185 153 % z acute +\definecaseswap 187 155 % z dotaccent +\definecaseswap 243 211 % o acute + +% \definecasemap 161 161 129 % a ogonek +% \definecasemap 162 162 130 % c acute +% \definecasemap 166 166 134 % e ogonek +% \definecasemap 170 170 138 % l crossed +% \definecasemap 171 171 139 % n acute +% \definecasemap 177 177 145 % s acute +% \definecasemap 185 185 153 % z acute +% \definecasemap 187 187 155 % z dotaccent +% \definecasemap 243 243 211 % o acute + +% \definecasemap 129 161 129 % A ogonek +% \definecasemap 130 162 130 % C acute +% \definecasemap 134 166 134 % E ogonek +% \definecasemap 138 170 138 % L crossed +% \definecasemap 139 171 139 % N acute +% \definecasemap 145 177 145 % S acute +% \definecasemap 153 185 153 % Z acute +% \definecasemap 155 187 155 % Z dotaccent +% \definecasemap 211 243 211 % O acute + +\stopmapping + +\startmapping[pl0] + +\definespacemap 129 999 % A ogonek +\definespacemap 130 999 % C acute +\definespacemap 134 999 % E ogonek +\definespacemap 138 999 % L crossed +\definespacemap 139 999 % N acute +\definespacemap 211 999 % O acute +\definespacemap 145 999 % S acute +\definespacemap 153 999 % Z acute +\definespacemap 155 999 % Z dot + +\stopmapping + +\startencoding[pl0][pl0] + +\definecharacter Aogonek 129 +\definecharacter Cacute 130 +\definecharacter Eogonek 134 +\definecharacter Lstroke 138 +\definecharacter Nacute 139 +\definecharacter Sacute 145 +\definecharacter Zacute 153 +\definecharacter Zdotaccent 155 +\definecharacter aogonek 161 +\definecharacter cacute 162 +\definecharacter eogonek 166 +\definecharacter lstroke 170 +\definecharacter nacute 171 +\definecharacter sacute 177 +\definecharacter zacute 185 +\definecharacter zdotaccent 187 +\definecharacter Oacute 211 +\definecharacter oacute 243 + +\stopencoding + +\startencoding[pl0][pl0] + +\definecharacter leftguillemot 174 +\definecharacter rightguillemot 175 +\definecharacter guilsingleleft 174 +\definecharacter guilsingleright 175 + +\stopencoding + +% obsolete +% +% \startencoding[pl0] +% +% \definesortkey {161} {a}{a}{\k a} \definesortkey {129} {a}{a}{\k a} +% \definesortkey {162} {c}{a}{\'c} \definesortkey {130} {c}{a}{\'c} +% \definesortkey {166} {e}{a}{\k e} \definesortkey {134} {e}{a}{\k e} +% \definesortkey {170} {l}{a}{\l } \definesortkey {138} {l}{a}{\l } +% \definesortkey {171} {n}{a}{\'n} \definesortkey {139} {n}{a}{\'n} +% \definesortkey {177} {s}{a}{\'s} \definesortkey {145} {s}{a}{\'s} +% \definesortkey {185} {z}{a}{\'z} \definesortkey {153} {z}{a}{\'z} +% \definesortkey {187} {z}{b}{\.z} \definesortkey {155} {z}{b}{\.z} +% \definesortkey {243} {o}{a}{\'o} \definesortkey {211} {o}{a}{\'o} +% +% \definesortkey {\'c} {c}{a}{\'c} \definesortkey {\'C} {c}{a}{\'c} +% \definesortkey {\'n} {n}{a}{\'n} \definesortkey {\'N} {n}{a}{\'n} +% \definesortkey {\'o} {o}{a}{\'o} \definesortkey {\'O} {o}{a}{\'o} +% \definesortkey {\'s} {s}{a}{\'s} \definesortkey {\'S} {s}{a}{\'s} +% \definesortkey {\'z} {z}{a}{\'z} \definesortkey {\'Z} {z}{a}{\'z} +% \definesortkey {\.z} {z}{b}{\.z} \definesortkey {\.Z} {z}{b}{\.z} +% \definesortkey {\k a}{a}{a}{\k a} \definesortkey {\k A}{a}{a}{\k a} +% \definesortkey {\k e}{e}{a}{\k e} \definesortkey {\k E}{e}{a}{\k e} +% \definesortkey {\l } {l}{a}{\l} \definesortkey {\L } {l}{a}{\l} +% +% \stopencoding + +%D Polish CP-1250 encoding. + +% \startmapping[pl1] +% +% +% \resetcaserange 128 to 255 +% +% \definecasemap 185 185 165 % a ogonek +% \definecasemap 230 230 198 % c acute +% \definecasemap 234 234 202 % e ogonek +% \definecasemap 179 179 163 % l crossed +% \definecasemap 241 241 209 % n acute +% \definecasemap 243 243 211 % o acute +% \definecasemap 156 156 140 % s acute +% \definecasemap 159 159 143 % z acute +% \definecasemap 191 191 175 % z dot +% +% \definecasemap 165 165 185 % A ogonek +% \definecasemap 198 198 230 % C acute +% \definecasemap 202 202 234 % E ogonek +% \definecasemap 163 163 179 % L crossed +% \definecasemap 209 209 241 % N acute +% \definecasemap 211 211 243 % O acute +% \definecasemap 140 140 156 % S acute +% \definecasemap 143 143 159 % Z acute +% \definecasemap 175 175 191 % Z dot +% +% \stopmapping +% +% \startmapping[pl1] +% +% \definespacemap 165 999 % A ogonek +% \definespacemap 198 999 % C acute +% \definespacemap 202 999 % E ogonek +% \definespacemap 163 999 % L crossed +% \definespacemap 209 999 % N acute +% \definespacemap 211 999 % O acute +% \definespacemap 140 999 % S acute +% \definespacemap 143 999 % Z acute +% \definespacemap 175 999 % Z dot +% +% \stopmapping +% +% \startencoding[pl1] +% +% \definecharacter Sacute 140 +% \definecharacter Zacute 143 +% \definecharacter sacute 156 +% \definecharacter zacute 159 +% \definecharacter Lstroke 163 +% \definecharacter Aogonek 165 +% \definecharacter Zdotaccent 175 +% \definecharacter lstroke 179 +% \definecharacter aogonek 185 +% \definecharacter zdotaccent 191 +% \definecharacter Cacute 198 +% \definecharacter Eogonek 202 +% \definecharacter Nacute 209 +% \definecharacter Oacute 211 +% \definecharacter cacute 230 +% \definecharacter eogonek 234 +% \definecharacter nacute 241 +% \definecharacter oacute 243 +% +% \stopencoding +% +% \startencoding[pl1] +% +% \definecharacter leftguillemot 174 +% \definecharacter rightguillemot 175 +% \definecharacter guilsingleleft 174 +% \definecharacter guilsingleright 175 +% +% \stopencoding + +%D Polish ISO-8859-2 encoding. + +% \startmapping[pl2] +% +% \resetcaserange 128 to 255 +% +% \definecasemap 177 177 161 % a ogonek +% \definecasemap 230 230 198 % c acute +% \definecasemap 234 234 202 % e ogonek +% \definecasemap 179 179 163 % l crossed +% \definecasemap 241 241 209 % n acute +% \definecasemap 243 243 211 % o acute +% \definecasemap 182 182 166 % s acute +% \definecasemap 188 188 172 % z acute +% \definecasemap 191 191 175 % z dotaccent +% +% \definecasemap 161 161 177 % A ogonek +% \definecasemap 198 198 230 % C acute +% \definecasemap 202 202 234 % E ogonek +% \definecasemap 163 163 179 % L crossed +% \definecasemap 209 209 241 % N acute +% \definecasemap 211 211 243 % O acute +% \definecasemap 166 166 182 % S acute +% \definecasemap 172 172 188 % Z acute +% \definecasemap 175 175 191 % Z dotaccent +% +% \stopmapping +% +% \startmapping[pl2] +% +% \definespacemap 161 999 % A ogonek +% \definespacemap 198 999 % C acute +% \definespacemap 202 999 % E ogonek +% \definespacemap 163 999 % L crossed +% \definespacemap 209 999 % N acute +% \definespacemap 211 999 % O acute +% \definespacemap 166 999 % S acute +% \definespacemap 172 999 % Z acute +% \definespacemap 175 999 % Z dot +% +% \stopmapping +% +% \startencoding[pl2] +% +% \definecharacter Aogonek 161 +% \definecharacter Lstroke 163 +% \definecharacter Sacute 166 +% \definecharacter Zacute 172 +% \definecharacter Zdotaccent 175 +% \definecharacter aogonek 177 +% \definecharacter lstroke 179 +% \definecharacter sacute 182 +% \definecharacter zacute 188 +% \definecharacter zdotaccent 191 +% \definecharacter Cacute 198 +% \definecharacter Eogonek 202 +% \definecharacter Nacute 209 +% \definecharacter Oacute 211 +% \definecharacter cacute 230 +% \definecharacter eogonek 234 +% \definecharacter nacute 241 +% \definecharacter oacute 243 +% +% \stopencoding +% +% \startencoding[pl2] +% +% \definecharacter leftguillemot 174 +% \definecharacter rightguillemot 175 +% \definecharacter guilsingleleft 174 +% \definecharacter guilsingleright 175 +% +% \stopencoding + +\endinput diff --git a/tex/context/base/enco-qx.mkii b/tex/context/base/enco-qx.mkii new file mode 100644 index 000000000..407d60bd7 --- /dev/null +++ b/tex/context/base/enco-qx.mkii @@ -0,0 +1,266 @@ +%D \module +%D [ file=enco-qx, +%D version=2004.04.03, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=Polish QX Encoding, +%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. + +% to be done + +% 35 numbersign +% 95 dotaccent +% 132 greaterequal +% 133 approxequal +% 137 lessequal +% 142 ell +% 156 IJ +% 173 infinity +% 182 threequartersemdash +% 188 ij +% 247 anglearc +% 248 diameter + +\startmapping[qx] % to be done + +\resetcaserange 128 to 128 +\resetcaserange 131 to 133 +\resetcaserange 136 to 137 +\resetcaserange 140 to 144 +\resetcaserange 148 to 148 +\resetcaserange 150 to 150 +\resetcaserange 157 to 160 +\resetcaserange 163 to 165 +\resetcaserange 168 to 169 +\resetcaserange 172 to 176 +\resetcaserange 180 to 180 +\resetcaserange 182 to 182 +\resetcaserange 189 to 191 +\resetcaserange 198 to 198 +\resetcaserange 215 to 216 +\resetcaserange 223 to 223 +\resetcaserange 230 to 230 +\resetcaserange 247 to 248 +\resetcaserange 255 to 255 + +\definecaseswap 161 129 +\definecaseswap 162 130 + +\definecaseswap 166 134 +\definecaseswap 167 135 + +\definecaseswap 170 138 +\definecaseswap 171 139 + +\definecaseswap 177 145 +\definecaseswap 178 146 +\definecaseswap 179 147 + +\definecaseswap 181 149 + +\definecasemaps 151 to 156 lc +32 uc 0 +\definecasemaps 183 to 188 lc 0 uc -32 + +\definecasemaps 192 to 197 lc +32 uc 0 +\definecasemaps 224 to 229 lc 0 uc -32 + +\definecasemaps 199 to 214 lc +32 uc 0 +\definecasemaps 231 to 246 lc 0 uc -32 + +\definecasemaps 217 to 222 lc +32 uc 0 +\definecasemaps 249 to 254 lc 0 uc -32 + +\stopmapping + +\startencoding[qx] + +\definecharacter textacute 19 +\definecharacter textbreve 21 +\definecharacter textcaron 20 +\definecharacter textcedilla 24 +\definecharacter textcircumflex 94 +\definecharacter textdiaeresis 127 +\definecharacter textdotaccent 94 +\definecharacter textgrave 18 +\definecharacter texthungarumlaut 125 +\definecharacter textmacron 22 +\definecharacter textogonek 150 +\definecharacter textring 23 +\definecharacter texttilde 126 + +\definecharacter dotlessi 16 +\definecharacter dotlessj 17 + +\definecharacter endash 123 +\definecharacter emdash 124 + +\definecharacter aeligature 26 +\definecharacter AEligature 29 +\definecharacter oeligature 27 +\definecharacter OEligature 30 + +\definecharacter ssharp 25 +%definecharacter Ssharp 25 + +\definecharacter thorn 254 +\definecharacter Thorn 222 + +\definecharacter Dstroke 208 % also Eth, mapped into enco-def +\definecharacter eth 240 + +\definecharacter exclamdown 60 +\definecharacter questiondown 62 + +\definecharacter sectionmark 159 + +\definecharacter percent 37 +\definecharacter perthousand 216 + +\definecharacter textasciicircum 141 +\definecharacter textasciitilde 140 +\definecharacter textbackslash 198 +\definecharacter textbraceleft 157 +\definecharacter textbraceright 158 +\definecharacter textunderscore 230 + +\definecharacter textcurrency 215 +\definecharacter textdollar 36 +\definecharacter texteuro 128 + +\definecharacter periodcentered 189 +\definecharacter textdag 143 +\definecharacter textddag 144 +\definecharacter textdegree 148 +\definecharacter textbullet 180 + +\definecharacter paragraphmark 176 + +\definecharacter copyright 164 +\definecharacter registered 163 + +\definecharacter textbrokenbar 223 +\definecharacter textellipsis 8 +\definecharacter textslash 47 +\definecharacter textpm 172 +\definecharacter textdiv 165 +\definecharacter textminus 168 +\definecharacter textmultiply 169 +\definecharacter textmu 7 + +\definecharacter quotedbl 190 +\definecharacter quotedblbase 255 +\definecharacter quotedblleft 92 +\definecharacter quotedblright 34 + +\definecharacter quotesingle 191 + +\definecharacter quoteleft 96 +\definecharacter quoteright 39 + +\definecharacter leftguillemot 174 +\definecharacter rightguillemot 175 + +\definecharacter aacute 225 +\definecharacter Aacute 193 +\definecharacter cacute 162 +\definecharacter Cacute 130 +\definecharacter eacute 233 +\definecharacter Eacute 201 +\definecharacter iacute 237 +\definecharacter Iacute 205 +\definecharacter Nacute 139 +\definecharacter Oacute 211 +\definecharacter nacute 171 +\definecharacter oacute 243 +\definecharacter sacute 177 +\definecharacter Sacute 145 +\definecharacter uacute 250 +\definecharacter Uacute 218 +\definecharacter yacute 253 +\definecharacter Yacute 221 +\definecharacter zacute 185 +\definecharacter Zacute 153 + +\definecharacter scaron 178 +\definecharacter Scaron 146 +\definecharacter zcaron 186 +\definecharacter Zcaron 154 + +\definecharacter ccedilla 231 +\definecharacter Ccedilla 199 + +\definecharacter acircumflex 226 +\definecharacter Acircumflex 194 +\definecharacter ecircumflex 234 +\definecharacter Ecircumflex 202 +\definecharacter icircumflex 238 +\definecharacter Icircumflex 206 +\definecharacter ocircumflex 244 +\definecharacter Ocircumflex 212 +\definecharacter ucircumflex 251 +\definecharacter Ucircumflex 219 + +\definecharacter adiaeresis 228 +\definecharacter Adiaeresis 196 +\definecharacter ediaeresis 235 +\definecharacter Ediaeresis 203 +\definecharacter idiaeresis 239 +\definecharacter Idiaeresis 207 +\definecharacter odiaeresis 246 +\definecharacter Odiaeresis 214 +\definecharacter udiaeresis 252 +\definecharacter Udiaeresis 220 +\definecharacter ydiaeresis 184 +\definecharacter Ydiaeresis 152 + +\definecharacter zdotaccent 187 +\definecharacter Zdotaccent 155 + +\definecharacter agrave 224 +\definecharacter Agrave 192 +\definecharacter egrave 232 +\definecharacter Egrave 200 +\definecharacter igrave 236 +\definecharacter Igrave 204 +\definecharacter ograve 242 +\definecharacter Ograve 210 +\definecharacter ugrave 249 +\definecharacter Ugrave 217 + +\definecharacter aogonek 161 +\definecharacter Aogonek 129 +\definecharacter eogonek 166 +\definecharacter Eogonek 134 +\definecharacter iogonek 167 +\definecharacter Iogonek 135 +\definecharacter uogonek 183 +\definecharacter Uogonek 151 + +\definecharacter aring 229 +\definecharacter Aring 197 + +\definecharacter lstroke 170 +\definecharacter Lstroke 138 +\definecharacter ostroke 28 +\definecharacter Ostroke 31 + +\definecharacter atilde 227 +\definecharacter Atilde 195 +\definecharacter ntilde 241 +\definecharacter Ntilde 209 +\definecharacter otilde 245 +\definecharacter Otilde 213 + +\definecharacter scommaaccent 179 +\definecharacter Scommaaccent 147 +\definecharacter tcommaaccent 181 +\definecharacter Tcommaaccent 149 + +\stopencoding + +\endinput diff --git a/tex/context/base/enco-raw.mkii b/tex/context/base/enco-raw.mkii new file mode 100644 index 000000000..e3a46e3d7 --- /dev/null +++ b/tex/context/base/enco-raw.mkii @@ -0,0 +1,119 @@ +% default instelbaar maken: \enableencoding[main][fallback] + +\startencoding[raw] + +\definecharacter Acircumflex {A} \definecharacter acircumflex {a} +\definecharacter Ccircumflex {C} \definecharacter ccircumflex {c} +\definecharacter Ecircumflex {E} \definecharacter ecircumflex {e} +\definecharacter Gcircumflex {G} \definecharacter gcircumflex {g} +\definecharacter Hcircumflex {H} \definecharacter hcircumflex {h} +\definecharacter Icircumflex {I} \definecharacter icircumflex {i} +\definecharacter Jcircumflex {J} \definecharacter jcircumflex {j} +\definecharacter Ocircumflex {O} \definecharacter ocircumflex {o} +\definecharacter Scircumflex {S} \definecharacter scircumflex {s} +\definecharacter Ucircumflex {U} \definecharacter ucircumflex {u} +\definecharacter Wcircumflex {W} \definecharacter wcircumflex {w} +\definecharacter Ycircumflex {Y} \definecharacter ycircumflex {y} + +\definecharacter Agrave {A} \definecharacter agrave {a} +\definecharacter Egrave {E} \definecharacter egrave {e} +\definecharacter Igrave {I} \definecharacter igrave {i} +\definecharacter Ograve {O} \definecharacter ograve {o} +\definecharacter Ugrave {U} \definecharacter ugrave {u} +\definecharacter Ygrave {Y} \definecharacter ygrave {y} + +\definecharacter Atilde {A} \definecharacter atilde {a} +\definecharacter Itilde {I} \definecharacter itilde {i} +\definecharacter Otilde {O} \definecharacter otilde {o} +\definecharacter Utilde {U} \definecharacter utilde {u} +\definecharacter Utilde {N} \definecharacter utilde {n} + +\definecharacter Adiaeresis {A} \definecharacter adiaeresis {a} +\definecharacter Ediaeresis {E} \definecharacter ediaeresis {e} +\definecharacter Idiaeresis {I} \definecharacter idiaeresis {i} +\definecharacter Odiaeresis {O} \definecharacter odiaeresis {o} +\definecharacter Udiaeresis {U} \definecharacter udiaeresis {u} +\definecharacter Ydiaeresis {Y} \definecharacter ydiaeresis {y} + +\definecharacter Aacute {A} \definecharacter aacute {a} +\definecharacter Cacute {C} \definecharacter cacute {c} +\definecharacter Eacute {E} \definecharacter eacute {e} +\definecharacter Iacute {I} \definecharacter iacute {i} +\definecharacter Lacute {L} \definecharacter lacute {l} +\definecharacter Nacute {N} \definecharacter nacute {n} +\definecharacter Oacute {O} \definecharacter oacute {o} +\definecharacter Racute {R} \definecharacter racute {r} +\definecharacter Sacute {S} \definecharacter sacute {s} +\definecharacter Uacute {U} \definecharacter uacute {u} +\definecharacter Yacute {Y} \definecharacter yacute {y} +\definecharacter Zacute {Z} \definecharacter zacute {z} + +\definecharacter Dstroke {D} \definecharacter dstroke {d} +\definecharacter Hstroke {H} \definecharacter hstroke {h} +\definecharacter Tstroke {T} \definecharacter tstroke {t} + +\definecharacter Cdotaccent {C} \definecharacter cdotaccent {c} +\definecharacter Edotaccent {E} \definecharacter edotaccent {e} +\definecharacter Gdotaccent {G} \definecharacter gdotaccent {g} +\definecharacter Idotaccent {I} \definecharacter idotaccent {i} +\definecharacter Zdotaccent {Z} \definecharacter zdotaccent {z} + +\definecharacter Amacron {A} \definecharacter amacron {a} +\definecharacter Emacron {E} \definecharacter emacron {e} +\definecharacter Imacron {I} \definecharacter imacron {i} +\definecharacter Omacron {O} \definecharacter omacron {o} +\definecharacter Umacron {U} \definecharacter umacron {u} + +\definecharacter Ccedilla {C} \definecharacter ccedilla {c} +\definecharacter Kcedilla {K} \definecharacter kcedilla {k} +\definecharacter Lcedilla {L} \definecharacter lcedilla {l} +\definecharacter Ncedilla {N} \definecharacter ncedilla {n} +\definecharacter Rcedilla {R} \definecharacter rcedilla {r} +\definecharacter Scedilla {S} \definecharacter scedilla {s} +\definecharacter Tcedilla {T} \definecharacter tcedilla {t} + +\definecharacter Ohungarumlaut {O} \definecharacter ohungarumlaut {o} +\definecharacter Uhungarumlaut {U} \definecharacter uhungarumlaut {u} + +\definecharacter Aogonek {A} \definecharacter aogonek {a} +\definecharacter Eogonek {E} \definecharacter eogonek {e} +\definecharacter Iogonek {I} \definecharacter iogonek {i} +\definecharacter Uogonek {U} \definecharacter uogonek {u} + +\definecharacter Aring {A} \definecharacter aring {a} +\definecharacter Uring {U} \definecharacter uring {u} + +\definecharacter Abreve {A} \definecharacter abreve {a} +\definecharacter Ebreve {E} \definecharacter ebreve {e} +\definecharacter Gbreve {G} \definecharacter gbreve {g} +\definecharacter Ibreve {I} \definecharacter ibreve {i} +\definecharacter Obreve {O} \definecharacter obreve {o} +\definecharacter Ubreve {U} \definecharacter ubreve {u} + +\definecharacter Ccaron {C} \definecharacter ccaron {c} +\definecharacter Dcaron {D} \definecharacter dcaron {d} +\definecharacter Ecaron {E} \definecharacter ecaron {e} +\definecharacter Lcaron {L} \definecharacter lcaron {l} +\definecharacter Ncaron {N} \definecharacter ncaron {n} +\definecharacter Rcaron {R} \definecharacter rcaron {r} +\definecharacter Scaron {S} \definecharacter scaron {s} +\definecharacter Tcaron {T} \definecharacter tcaron {t} +\definecharacter Zcaron {Z} \definecharacter zcaron {z} + +\definecharacter dotlessI {I} \definecharacter dotlessi {i} +\definecharacter dotlessJ {J} \definecharacter dotlessj {j} + +\definecharacter AEligature {AE} \definecharacter aeligature {ae} +\definecharacter Lstroke {L} \definecharacter lstroke {l} +\definecharacter Ostroke {O} \definecharacter ostroke {o} +\definecharacter OEligature {OE} \definecharacter oeligature {oe} +\definecharacter Ssharp {SS} \definecharacter ssharp {ss} +\definecharacter IJligature {IJ} \definecharacter ijligature {ij} + +\definecharacter Aumlaut {A} \definecharacter aumlaut {a} +\definecharacter Eumlaut {E} \definecharacter eumlaut {e} +\definecharacter Iumlaut {I} \definecharacter iumlaut {i} +\definecharacter Oumlaut {O} \definecharacter oumlaut {o} +\definecharacter Uumlaut {U} \definecharacter uumlaut {u} + +\stopencoding diff --git a/tex/context/base/enco-run.mkii b/tex/context/base/enco-run.mkii new file mode 100644 index 000000000..50fb52e15 --- /dev/null +++ b/tex/context/base/enco-run.mkii @@ -0,0 +1,149 @@ +%D \module +%D [ file=enco-run, +%D version=2000.27.12, % moved to runtime module +%D title=\CONTEXT\ Encoding 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 + +\gdef\visualizecharacters% {}'s needed + {\def\uchar##1##2{\hbox to 2.5em + {\ifcase##1\relax\red\or\blue\else\green\fi##1\hss##2}}% + \let\normalbuildtextaccent\buildtextaccent + \let\normalbottomaccent \bottomaccent + %\def\char{\green\normalchar}% + \def\char % can be used in \oalign + {\bgroup\def\char{\green\normalchar\scratchcounter\egroup}% + \afterassignment\char\scratchcounter}% + \def\buildtextaccent{\let\green\empty\blue\normalbuildtextaccent}% + \def\bottomaccent{\let\green\empty\red\normalbottomaccent}} + +\unexpanded\gdef\visualizecharacterslegend + {\hbox + {\edef\banner{\currentencoding\space\fontname\font}% + \tttf\banner:\space + {\blue composed}\space{\red bottom}\space{\green char}\space raw}} + +\gdef\showaccents + {\bgroup + \savefont + \setuptextrules[\c!bodyfont=,\c!style=] + \starttextrule{\visualizecharacterslegend} + \whitespace + \restorefont\setupinterlinespace + \visualizecharacters + \def\do##1% + {{\def\dodo####1% + {\hss\hbox to 1em{\hss\expanded{##1####1\recurselevel}\hss}}% + \hbox to \hsize + {\strut + \localcolortrue + \hbox to 2em{\tttf\string##1\hss}% + \dorecurse{26}{\dodo\character}}% + \hbox to \hsize + {\strut + \localcolortrue + \hskip2em + \dorecurse{26}{\dodo\Character}}}% + \par} + \do\'\do\`\do\^\do\~\do\" + \do\H\do\r\do\v\do\u\do\= + \do\.\do\b\do\d\do\k\do\c + \stoptextrule + \egroup} + +\gdef\showcharacters + {\bgroup + \savefont + \setuptextrules[\c!bodyfont=,\c!style=] + \starttextrule{\visualizecharacterslegend} + \whitespace + \dontcomplain + \forgetall + \def\startencoding[##1]{} + \def\stopencoding{\endinput} + \dimen0=\zeropoint + \dimen2=\zeropoint + \def\definecharacter ##1 ##2 % + {\setbox0=\hbox spread 1em{\getvalue{##1}}% + \ifdim\wd0>\dimen0 \dimen0=\wd0 \fi + \setbox2=\hbox spread 1em{\box0 \tttf##1} + \ifdim\wd2>\dimen2 \dimen2=\wd2 \fi}% + \readsysfile{\f!encodingprefix def}{}{} + \edef\encwidth{\the\dimen0} + \dimen0=\hsize + \advance\dimen0 2em + \advance\dimen2 2em + \divide \dimen0 by \dimen2 \advance\dimen0 1sp + \edef\enccols{\number\dimen0} + \visualizecharacters + \startcolumns[\c!n=\enccols,\c!distance=2em] + \restorefont\setupinterlinespace + \def\definecharacter ##1 ##2 % + {\setbox0=\hbox to \hsize{\localcolortrue\hbox to \encwidth{\getvalue{##1}\hss}\tttf##1}% + \ht0\strutheight \dp0\strutdepth \box0 \allowbreak} + \readsysfile{\f!encodingprefix def}{}{} + \stopcolumns + \stoptextrule + \egroup} + +% \hbox +% {\font\test=uplr8t \test \ruledhbox{t} +% \font\test=uplr8r \test \ruledhbox{t}} + +\ifnum\texengine=\pdftexengine + + \gdef\showhyphenations#1% + {\starttabulate[|le|l|] + \NC language \NC \currentlanguage\ (internal code:\the\normallanguage) \NC \NR + \NC font \NC \fontname\font \NC \NR + \NC encoding \NC \ifx\@@fontencoding\empty not set\else\@@fontencoding\fi \NC \NR + \NC mapping \NC \ifx\@@fontmapping \empty not set\else\@@fontmapping \fi \NC \NR + \NC handling \NC \ifx\@@fonthandling\empty not set\else\@@fonthandling\fi \NC \NR + \NC sample \NC \hyphenatedword{#1} \NC \NR + \stoptabulate} + + \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}} + + \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|] + \NC language \NC \currentlanguage\ (internal code:\the\normallanguage) \NC \NR + \NC font \NC \fontname\font \NC \NR + \NC sample \NC \hyphenatedword{#1} \NC \NR + \stoptabulate} + + \globallet\showmapping\relax + + \globallet\showcharacterbounds\relax + +\fi + +\protect \endinput diff --git a/tex/context/base/enco-t5.mkii b/tex/context/base/enco-t5.mkii new file mode 100644 index 000000000..251c68765 --- /dev/null +++ b/tex/context/base/enco-t5.mkii @@ -0,0 +1,244 @@ +%D \module +%D [ file=enco-t5, +%D version=2004.11.16, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=New Vietnamese Encoding, +%D author=Hans Hagen \& Adam Lindsay, +%D date=\currentdate, +%D copyright=PRAGMA \& Adam Lindsay] +%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 derived from the enco-x5 encoding, but now +%D approaches the world with named glyphs. + +\startencoding[t5] + +\definecasemaps 128 to 159 lc +32 uc 0 + +\definecasemaps 160 to 191 lc 0 uc -32 + +\definecasemaps 192 to 223 lc +32 uc 0 + +\definecasemaps 224 to 225 lc 0 uc -32 + +\definecasemap 26 26 27 \definecasemap 27 26 27 +\definecasemap 28 28 29 \definecasemap 29 28 29 +\definecasemap 30 30 31 \definecasemap 31 30 31 + +\definecharacter textgrave 0 +\definecharacter textacute 1 +\definecharacter textcircumflex 2 +\definecharacter texttilde 3 +\definecharacter textdiaeresis 4 +\definecharacter textbottomdot 5 +\definecharacter textring 6 +\definecharacter textcaron 7 +\definecharacter textbreve 8 +\definecharacter textmacron 9 +\definecharacter textdotaccent 10 +\definecharacter textcedilla 11 +\definecharacter texthookabove 12 +\definecharacter textogonek {} + +\definecharacter quotesinglebase 13 +\definecharacter guilsingleleft 14 +\definecharacter guilsingleright 15 +\definecharacter quotedblleft 16 +\definecharacter quotedblright 17 +\definecharacter quotedblbase 18 +\definecharacter leftguillemot 19 +\definecharacter rightguillemot 20 +\definecharacter endash 21 +\definecharacter emdash 22 + +\definecharacter cwm 23 +\definecharacter zeroinferior 24 +\definecharacter Yhook 26 +\definecharacter yhook 27 +\definecharacter Ydotbelow 28 +\definecharacter ydotbelow 29 +\definecharacter Dstroke 30 +\definecharacter dstroke 31 +\definecharacter textvisiblespace 32 + +\definecharacter dotlessi 25 +%definecharacter DJ 30 +%definecharacter dj 31 +\definecharacter Agrave 128 +\definecharacter Aacute 129 +\definecharacter Atilde 130 +\definecharacter Ahook 131 +\definecharacter Adotbelow 132 +\definecharacter Acircumflex 133 +\definecharacter Acircumflexgrave 134 +\definecharacter Acircumflexacute 135 +\definecharacter Acircumflextilde 136 +\definecharacter Acircumflexhook 137 +\definecharacter Acircumflexdotbelow 138 +\definecharacter Abreve 139 +\definecharacter Abrevegrave 140 +\definecharacter Abreveacute 141 +\definecharacter Abrevetilde 142 +\definecharacter Abrevehook 143 +\definecharacter Abrevedotbelow 144 +\definecharacter Egrave 145 +\definecharacter Eacute 146 +\definecharacter Etilde 147 +\definecharacter Ehook 148 +\definecharacter Edotbelow 149 +\definecharacter Ecircumflex 150 +\definecharacter Ecircumflexgrave 151 +\definecharacter Ecircumflexacute 152 +\definecharacter Ecircumflextilde 153 +\definecharacter Ecircumflexhook 154 +\definecharacter Ecircumflexdotbelow 155 +\definecharacter Igrave 156 +\definecharacter Iacute 157 +\definecharacter Itilde 158 +\definecharacter Ihook 159 +\definecharacter agrave 160 +\definecharacter aacute 161 +\definecharacter atilde 162 +\definecharacter ahook 163 +\definecharacter adotbelow 164 +\definecharacter acircumflex 165 +\definecharacter acircumflexgrave 166 +\definecharacter acircumflexacute 167 +\definecharacter acircumflextilde 168 +\definecharacter acircumflexhook 169 +\definecharacter acircumflexdotbelow 170 +\definecharacter abreve 171 +\definecharacter abrevegrave 172 +\definecharacter abreveacute 173 +\definecharacter abrevetilde 174 +\definecharacter abrevehook 175 +\definecharacter abrevedotbelow 176 +\definecharacter egrave 177 +\definecharacter eacute 178 +\definecharacter etilde 179 +\definecharacter ehook 180 +\definecharacter edotbelow 181 +\definecharacter ecircumflex 182 +\definecharacter ecircumflexgrave 183 +\definecharacter ecircumflexacute 184 +\definecharacter ecircumflextilde 185 +\definecharacter ecircumflexhook 186 +\definecharacter ecircumflexdotbelow 187 +\definecharacter igrave 188 +\definecharacter iacute 189 +\definecharacter itilde 190 +\definecharacter ihook 191 +\definecharacter Idotbelow 192 +\definecharacter Ograve 193 +\definecharacter Oacute 194 +\definecharacter Otilde 195 +\definecharacter Ohook 196 +\definecharacter Odotbelow 197 +\definecharacter Ocircumflex 198 +\definecharacter Ocircumflexgrave 199 +\definecharacter Ocircumflexacute 200 +\definecharacter Ocircumflextilde 201 +\definecharacter Ocircumflexhook 202 +\definecharacter Ocircumflexdotbelow 203 +\definecharacter Ohorn 204 +\definecharacter Ohorngrave 205 +\definecharacter Ohornacute 206 +\definecharacter Ohorntilde 207 +\definecharacter Ohornhook 208 +\definecharacter Ohorndotbelow 209 +\definecharacter Ugrave 210 +\definecharacter Uacute 211 +\definecharacter Utilde 212 +\definecharacter Uhook 213 +\definecharacter Udotbelow 214 +\definecharacter Uhorn 215 +\definecharacter Uhorngrave 216 +\definecharacter Uhornacute 217 +\definecharacter Uhorntilde 218 +\definecharacter Uhornhook 219 +\definecharacter Uhorndotbelow 220 +\definecharacter Ytilde 223 +\definecharacter idotbelow 224 +\definecharacter ograve 225 +\definecharacter oacute 226 +\definecharacter otilde 227 +\definecharacter ohook 228 +\definecharacter odotbelow 229 +\definecharacter ocircumflex 230 +\definecharacter ocircumflexgrave 231 +\definecharacter ocircumflexacute 232 +\definecharacter ocircumflextilde 233 +\definecharacter ocircumflexhook 234 +\definecharacter ocircumflexdotbelow 235 +\definecharacter ohorn 236 +\definecharacter ohorngrave 237 +\definecharacter ohornacute 238 +\definecharacter ohorntilde 239 +\definecharacter ohornhook 240 +\definecharacter ohorndotbelow 241 +\definecharacter ugrave 242 +\definecharacter uacute 243 +\definecharacter utilde 244 +\definecharacter uhook 245 +\definecharacter udotbelow 246 +\definecharacter uhorn 247 +\definecharacter uhorngrave 248 +\definecharacter uhornacute 249 +\definecharacter uhorntilde 250 +\definecharacter uhornhook 251 +\definecharacter uhorndotbelow 252 +\definecharacter ygrave 253 +\definecharacter yacute 254 +\definecharacter ytilde 255 + +\stopencoding + +\endinput + +% \startencoding [x5] +% +% \definecharacter aa {\xfiveencodedaa} +% \definecharacter AA {\xfiveencodedAA} +% +% \stopencoding +% +% \def\xfiveencodedaa% +% {\accent23a} +% +% \def\xfiveencodedAA% +% {\leavevmode +% \setbox\zerocount\hbox{h}% +% \dimen@\ht\zerocount +% \advance\dimen@ -1ex +% \rlap{\raise.67\dimen@\hbox{\char23}}A} + +% \quotesinglbase 13 +% \guilsinglleft 14 +% \guilsinglright 15 +% \textquotedblleft 16 +% \textquotedblright 17 +% \quotedblbase 18 +% \guillemotleft 19 +% \guillemotright 20 +% \textendash 21 +% \textemdash 22 +% \textcompwordmark 23 +% \textperthousand \% \char 24 +% \textpertenthousand \%\char 24\char 24 +% \textvisiblespace 32 +% \textquotedbl `\" +% \textdollar `\$ +% \textquoteright `\' +% \textless `\< +% \textgreater `\> +% \textbackslash `\ +% \textasciicircum `\^ +% \textunderscore 95 +% \textquoteleft `\` +% \textbraceleft `\{ +% \textbar `\| +% \textbraceright `\} +% \textasciitilde `\~ diff --git a/tex/context/base/enco-tbo.mkii b/tex/context/base/enco-tbo.mkii new file mode 100644 index 000000000..475be4602 --- /dev/null +++ b/tex/context/base/enco-tbo.mkii @@ -0,0 +1,222 @@ +%D \module +%D [ file=enco-tbo, +%D version=2000.05.07, % 2001.8.4, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=TeXBaseOne Encoding, +%D author={Patrick Gundlach, 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. + +\startmapping[8r] + +\resetcaserange 128 to 255 + +\definecasemap 228 228 196 \definecasemap 196 228 196 +\definecasemap 235 235 203 \definecasemap 203 235 203 +\definecasemap 239 239 207 \definecasemap 207 239 207 +\definecasemap 246 246 214 \definecasemap 214 246 214 +\definecasemap 252 252 220 \definecasemap 220 252 220 +\definecasemap 255 255 159 \definecasemap 159 255 159 + +\definecasemap 225 225 193 \definecasemap 193 225 193 +\definecasemap 233 233 201 \definecasemap 201 233 201 +\definecasemap 237 237 205 \definecasemap 205 237 205 +\definecasemap 243 243 211 \definecasemap 211 243 211 +\definecasemap 250 250 218 \definecasemap 218 250 218 +\definecasemap 253 253 221 \definecasemap 221 253 221 + +\definecasemap 224 224 192 \definecasemap 192 224 192 +\definecasemap 232 232 200 \definecasemap 200 232 200 +\definecasemap 236 236 204 \definecasemap 204 236 204 +\definecasemap 242 242 210 \definecasemap 210 242 210 +\definecasemap 249 249 217 \definecasemap 217 249 217 + +\definecasemap 226 226 194 \definecasemap 194 226 194 +\definecasemap 234 234 202 \definecasemap 202 234 202 +\definecasemap 238 238 206 \definecasemap 206 238 206 +\definecasemap 244 244 212 \definecasemap 212 244 212 +\definecasemap 251 251 219 \definecasemap 219 251 219 + +\definecasemap 227 227 195 \definecasemap 195 227 195 +\definecasemap 241 241 209 \definecasemap 209 241 209 +\definecasemap 245 245 213 \definecasemap 213 245 213 + +\stopmapping + +\startencoding[8r] + +\definecharacter textacute 180 +\definecharacter textbreve 11 +\definecharacter textcaron 16 +\definecharacter textcedilla 184 +\definecharacter textcircumflex 136 +\definecharacter textdiaeresis 168 +\definecharacter textdotaccent 1 +\definecharacter textgrave 30 +\definecharacter texthungarumlaut 5 +\definecharacter textmacron 175 +\definecharacter textogonek 8 +\definecharacter textring 9 +\definecharacter texttilde 152 + +\definecharacter dotlessi 17 +%definecharacter dotlessj 18 + +\definecharacter endash 150 +\definecharacter emdash 151 + +\definecharacter oeligature 156 +\definecharacter OEligature 140 +\definecharacter aeligature 230 +\definecharacter AEligature 198 + +\definecharacter ssharp 223 + +\definecharacter thorn 254 +\definecharacter Thorn 222 + +\definecharacter exclamdown 161 +\definecharacter questiondown 191 + +\definecharacter copyright 169 +\definecharacter registered 174 +\definecharacter trademark 153 + +\definecharacter sectionmark 167 +\definecharacter paragraphmark 182 + +\definecharacter onequarter 188 +\definecharacter onehalf 189 +\definecharacter threequarter 190 +\definecharacter onesuperior 185 +\definecharacter twosuperior 178 +\definecharacter threesuperior 179 + +\definecharacter textcent 162 +\definecharacter textcurrency 164 +\definecharacter texteuro 128 +\definecharacter textflorin 131 +\definecharacter textsterling 163 +\definecharacter textyen 165 + +\definecharacter percent 37 +\definecharacter perthousand 137 + +\definecharacter periodcentered 183 +\definecharacter softhyphen 173 + +\definecharacter textasciicircum 94 +\definecharacter textasciitilde 126 +\definecharacter textslash 47 +\definecharacter textbackslash 92 +\definecharacter textbraceleft 123 +\definecharacter textbraceright 125 +\definecharacter textunderscore 95 + +\definecharacter textbrokenbar 166 +\definecharacter textbullet 149 +\definecharacter textdag 134 +\definecharacter textddag 135 +\definecharacter textdegree 176 +\definecharacter textdiv 247 +\definecharacter textellipsis 133 +\definecharacter textfraction 4 +\definecharacter textlognot 172 +\definecharacter textminus 12 +\definecharacter textmu 181 +\definecharacter textmultiply 215 +\definecharacter textpm 177 + +\definecharacter quotedbl 34 +\definecharacter quotedblbase 132 +\definecharacter quotedblleft 147 +\definecharacter quotedblright 148 + +\definecharacter quotesingle 31 +\definecharacter quotesinglebase 130 + +\definecharacter quoteleft 96 +\definecharacter quoteright 39 + +\definecharacter guilsingleleft 139 +\definecharacter guilsingleright 155 +\definecharacter leftguillemot 171 +\definecharacter rightguillemot 187 + +\definecharacter aacute 225 +\definecharacter Aacute 193 +\definecharacter eacute 233 +\definecharacter Eacute 201 +\definecharacter iacute 237 +\definecharacter Iacute 205 +\definecharacter oacute 243 +\definecharacter Oacute 211 +\definecharacter uacute 250 +\definecharacter Uacute 218 +\definecharacter Yacute 221 +\definecharacter yacute 253 + +\definecharacter scaron 154 +\definecharacter Scaron 138 +%definecharacter Zcaron 141 + +\definecharacter ccedilla 231 +\definecharacter Ccedilla 199 + +\definecharacter acircumflex 226 +\definecharacter Acircumflex 194 +\definecharacter ecircumflex 234 +\definecharacter Ecircumflex 202 +\definecharacter icircumflex 238 +\definecharacter Icircumflex 206 +\definecharacter ocircumflex 244 +\definecharacter Ocircumflex 212 +\definecharacter ucircumflex 251 +\definecharacter Ucircumflex 219 + +\definecharacter adiaeresis 228 +\definecharacter Adiaeresis 196 +\definecharacter ediaeresis 235 +\definecharacter Ediaeresis 203 +\definecharacter idiaeresis 239 +\definecharacter Idiaeresis 207 +\definecharacter odiaeresis 246 +\definecharacter Odiaeresis 214 +\definecharacter udiaeresis 252 +\definecharacter Udiaeresis 220 +\definecharacter ydiaeresis 255 +\definecharacter Ydiaeresis 159 + +\definecharacter agrave 224 +\definecharacter Agrave 192 +\definecharacter egrave 232 +\definecharacter Egrave 200 +\definecharacter igrave 236 +\definecharacter Igrave 204 +\definecharacter ograve 242 +\definecharacter Ograve 210 +\definecharacter ugrave 249 +\definecharacter Ugrave 217 + +\definecharacter aring 229 +\definecharacter Aring 197 + +\definecharacter lstroke 7 +\definecharacter Lstroke 6 +\definecharacter ostroke 248 +\definecharacter Ostroke 216 + +\definecharacter atilde 227 +\definecharacter Atilde 195 +\definecharacter ntilde 241 +\definecharacter Ntilde 209 +\definecharacter otilde 245 +\definecharacter Otilde 213 + +\stopencoding + +\endinput diff --git a/tex/context/base/enco-uc.mkii b/tex/context/base/enco-uc.mkii new file mode 100644 index 000000000..981eb6ae4 --- /dev/null +++ b/tex/context/base/enco-uc.mkii @@ -0,0 +1,1091 @@ +%D \module +%D [ file=enco-uc, +%D version=2000.xx.xx, % and later +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=Unicode (backwards mapping), +%D author={Adam Lindsay \& 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. + +%D An alternative approach would be to misuse the utf vectors, but they +%D don't carry enough info around. + +% todo : \defineucharacter hebrewAlef 5 "D0 + +\startencoding[uc] + +\definecharacter Agrave {\uchar0{192}} +\definecharacter Aacute {\uchar0{193}} +\definecharacter Acircumflex {\uchar0{194}} +\definecharacter Atilde {\uchar0{195}} +\definecharacter Adiaeresis {\uchar0{196}} +\definecharacter Aring {\uchar0{197}} +\definecharacter AEligature {\uchar0{198}} +\definecharacter Ccedilla {\uchar0{199}} +\definecharacter Egrave {\uchar0{200}} +\definecharacter Eacute {\uchar0{201}} +\definecharacter Ediaeresis {\uchar0{203}} +\definecharacter Igrave {\uchar0{204}} +\definecharacter Iacute {\uchar0{205}} +\definecharacter Icircumflex {\uchar0{206}} +\definecharacter Idiaeresis {\uchar0{207}} +\definecharacter Eth {\uchar0{208}} +\definecharacter Ntilde {\uchar0{209}} +\definecharacter Ograve {\uchar0{210}} +\definecharacter Oacute {\uchar0{211}} +\definecharacter Ocircumflex {\uchar0{212}} +\definecharacter Otilde {\uchar0{213}} +\definecharacter Odiaeresis {\uchar0{214}} + +\definecharacter Ostroke {\uchar0{216}} +\definecharacter Ugrave {\uchar0{217}} +\definecharacter Uacute {\uchar0{218}} +\definecharacter Uhungarumlaut {\uchar0{219}} +\definecharacter Udiaeresis {\uchar0{220}} +\definecharacter Yacute {\uchar0{221}} +\definecharacter Thorn {\uchar0{222}} +\definecharacter ssharp {\uchar0{223}} +\definecharacter agrave {\uchar0{224}} +\definecharacter aacute {\uchar0{225}} +\definecharacter acircumflex {\uchar0{226}} +\definecharacter atilde {\uchar0{227}} +\definecharacter adiaeresis {\uchar0{228}} +\definecharacter aring {\uchar0{229}} +\definecharacter aeligature {\uchar0{230}} +\definecharacter ccedilla {\uchar0{231}} +\definecharacter egrave {\uchar0{232}} +\definecharacter eacute {\uchar0{233}} +\definecharacter ecircumflex {\uchar0{234}} +\definecharacter ediaeresis {\uchar0{235}} +\definecharacter igrave {\uchar0{236}} +\definecharacter iacute {\uchar0{237}} +\definecharacter icircumflex {\uchar0{238}} +\definecharacter idiaeresis {\uchar0{239}} +\definecharacter eth {\uchar0{240}} +\definecharacter ntilde {\uchar0{241}} +\definecharacter ograve {\uchar0{242}} +\definecharacter oacute {\uchar0{243}} +\definecharacter ocircumflex {\uchar0{244}} +\definecharacter otilde {\uchar0{245}} +\definecharacter odiaeresis {\uchar0{246}} + +\definecharacter ostroke {\uchar0{248}} +\definecharacter ugrave {\uchar0{249}} +\definecharacter uacute {\uchar0{250}} +\definecharacter ucircumflex {\uchar0{251}} +\definecharacter udiaeresis {\uchar0{252}} +\definecharacter yacute {\uchar0{253}} +\definecharacter thorn {\uchar0{254}} +\definecharacter ydiaeresis {\uchar0{255}} + +\definecharacter Amacron {\uchar1{0}} +\definecharacter amacron {\uchar1{1}} +\definecharacter Abreve {\uchar1{2}} +\definecharacter abreve {\uchar1{3}} +\definecharacter Aogonek {\uchar1{4}} +\definecharacter aogonek {\uchar1{5}} +\definecharacter Cacute {\uchar1{6}} +\definecharacter cacute {\uchar1{7}} +\definecharacter Ccircumflex {\uchar1{8}} +\definecharacter ccircumflex {\uchar1{9}} +\definecharacter Cdotaccent {\uchar1{10}} +\definecharacter cdotaccent {\uchar1{11}} +\definecharacter Ccaron {\uchar1{12}} +\definecharacter ccaron {\uchar1{13}} +\definecharacter Dcaron {\uchar1{14}} +\definecharacter dcaron {\uchar1{15}} +\definecharacter Dstroke {\uchar1{16}} +\definecharacter dstroke {\uchar1{17}} +\definecharacter Emacron {\uchar1{18}} +\definecharacter emacron {\uchar1{19}} +\definecharacter Ebreve {\uchar1{20}} +\definecharacter ebreve {\uchar1{21}} +\definecharacter Edotaccent {\uchar1{22}} +\definecharacter edotaccent {\uchar1{23}} +\definecharacter Eogonek {\uchar1{24}} +\definecharacter eogonek {\uchar1{25}} +\definecharacter Ecaron {\uchar1{26}} +\definecharacter ecaron {\uchar1{27}} +\definecharacter Gcircumflex {\uchar1{28}} +\definecharacter gcircumflex {\uchar1{29}} +\definecharacter Gbreve {\uchar1{30}} +\definecharacter gbreve {\uchar1{31}} +\definecharacter Gdotaccent {\uchar1{32}} +\definecharacter gdotaccent {\uchar1{33}} +\definecharacter Gcommaaccent {\uchar1{34}} +\definecharacter gcommaaccent {\uchar1{35}} +\definecharacter Hcircumflex {\uchar1{36}} +\definecharacter hcircumflex {\uchar1{37}} +\definecharacter Hstroke {\uchar1{38}} +\definecharacter hstroke {\uchar1{39}} +\definecharacter Itilde {\uchar1{40}} +\definecharacter itilde {\uchar1{41}} +\definecharacter Imacron {\uchar1{42}} +\definecharacter imacron {\uchar1{43}} +\definecharacter Ibreve {\uchar1{44}} +\definecharacter ibreve {\uchar1{45}} +\definecharacter Iogonek {\uchar1{46}} +\definecharacter iogonek {\uchar1{47}} +\definecharacter Idotaccent {\uchar1{48}} +\definecharacter dotlessi {\uchar1{49}} +\definecharacter IJligature {\uchar1{50}} +\definecharacter ijligature {\uchar1{51}} +\definecharacter Jcircumflex {\uchar1{52}} +\definecharacter jcircumflex {\uchar1{53}} +\definecharacter Kcommaaccent {\uchar1{54}} +\definecharacter kcommaaccent {\uchar1{55}} +\definecharacter kkra {\uchar1{56}} +\definecharacter Lacute {\uchar1{57}} +\definecharacter lacute {\uchar1{58}} +\definecharacter Lcommaaccent {\uchar1{59}} +\definecharacter lcommaaccent {\uchar1{60}} +\definecharacter Lcaron {\uchar1{61}} +\definecharacter lcaron {\uchar1{62}} +\definecharacter Ldotmiddle {\uchar1{63}} +\definecharacter ldotmiddle {\uchar1{64}} +\definecharacter Lstroke {\uchar1{65}} +\definecharacter lstroke {\uchar1{66}} +\definecharacter Nacute {\uchar1{67}} +\definecharacter nacute {\uchar1{68}} +\definecharacter Ncommaaccent {\uchar1{69}} +\definecharacter ncommaaccent {\uchar1{70}} +\definecharacter Ncaron {\uchar1{71}} +\definecharacter ncaron {\uchar1{72}} +\definecharacter napostrophe {\uchar1{73}} +\definecharacter Neng {\uchar1{74}} +\definecharacter neng {\uchar1{75}} +\definecharacter Omacron {\uchar1{76}} +\definecharacter omacron {\uchar1{77}} +\definecharacter Obreve {\uchar1{78}} +\definecharacter obreve {\uchar1{79}} +\definecharacter Ohungarumlaut {\uchar1{80}} +\definecharacter ohungarumlaut {\uchar1{81}} +\definecharacter OEligature {\uchar1{82}} +\definecharacter oeligature {\uchar1{83}} +\definecharacter Racute {\uchar1{84}} +\definecharacter racute {\uchar1{85}} +\definecharacter Rcommaaccent {\uchar1{86}} +\definecharacter rcommaaccent {\uchar1{87}} +\definecharacter Rcaron {\uchar1{88}} +\definecharacter rcaron {\uchar1{89}} +\definecharacter Sacute {\uchar1{90}} +\definecharacter sacute {\uchar1{91}} +\definecharacter Scircumflex {\uchar1{92}} +\definecharacter scircumflex {\uchar1{93}} +\definecharacter Scedilla {\uchar1{94}} +\definecharacter scedilla {\uchar1{95}} +\definecharacter Scaron {\uchar1{96}} +\definecharacter scaron {\uchar1{97}} +\definecharacter Tcedilla {\uchar1{98}} +\definecharacter tcedilla {\uchar1{99}} +\definecharacter Tcaron {\uchar1{100}} +\definecharacter tcaron {\uchar1{101}} +\definecharacter Tstroke {\uchar1{102}} +\definecharacter tstroke {\uchar1{103}} +\definecharacter Utilde {\uchar1{104}} +\definecharacter utilde {\uchar1{105}} +\definecharacter Umacron {\uchar1{106}} +\definecharacter umacron {\uchar1{107}} +\definecharacter Ubreve {\uchar1{108}} +\definecharacter ubreve {\uchar1{109}} +\definecharacter Uring {\uchar1{110}} +\definecharacter uring {\uchar1{111}} +\definecharacter Uhungarumlaut {\uchar1{112}} +\definecharacter uhungarumlaut {\uchar1{113}} +\definecharacter Uogonek {\uchar1{114}} +\definecharacter uogonek {\uchar1{115}} +\definecharacter Wcircumflex {\uchar1{116}} +\definecharacter wcircumflex {\uchar1{117}} +\definecharacter Ycircumflex {\uchar1{118}} +\definecharacter ycircumflex {\uchar1{119}} +\definecharacter Ydiaeresis {\uchar1{120}} +\definecharacter Zacute {\uchar1{121}} +\definecharacter zacute {\uchar1{122}} +\definecharacter Zdotaccent {\uchar1{123}} +\definecharacter zdotaccent {\uchar1{124}} +\definecharacter Zcaron {\uchar1{125}} +\definecharacter zcaron {\uchar1{126}} +\definecharacter slong {\uchar1{127}} + +\stopencoding + +\startencoding[uc] + +\definecharacter endash {\uchar{32}{19}} +\definecharacter emdash {\uchar{32}{20}} +\definecharacter quoteleft {\uchar{32}{24}} +\definecharacter quoteright {\uchar{32}{25}} +\definecharacter quotesinglebase {\uchar{32}{26}} + +\definecharacter quotedblleft {\uchar{32}{28}} +\definecharacter quotedblright {\uchar{32}{29}} +\definecharacter quotedblbase {\uchar{32}{30}} + +\definecharacter leftguillemot {\uchar0{171}} +\definecharacter rightguillemot {\uchar0{187}} + +\definecharacter guilsingleleft {\uchar{32}{57}} +\definecharacter guilsingleright {\uchar{32}{58}} + +\stopencoding + +%D Adam Lindsay's additions + +\startencoding[uc] + +\definecharacter exclamdown {\uchar0{161}} +\definecharacter textcent {\uchar0{162}} +\definecharacter textsterling {\uchar0{163}} +\definecharacter textcurrency {\uchar0{164}} +\definecharacter textyen {\uchar0{165}} +\definecharacter textbrokenbar {\uchar0{166}} +\definecharacter sectionmark {\uchar0{167}} +\definecharacter textdiaresis {\uchar0{168}} +\definecharacter copyright {\uchar0{169}} + +\definecharacter textlognot {\uchar0{172}} +\definecharacter softhyphen {\uchar0{173}} +\definecharacter registered {\uchar0{174}} +\definecharacter textmacron {\uchar0{175}} +\definecharacter textdegree {\uchar0{176}} +\definecharacter textpm {\uchar0{177}} +\definecharacter twosuperior {\uchar0{178}} +\definecharacter threesuperior {\uchar0{179}} +\definecharacter textacute {\uchar0{180}} +\definecharacter textmu {\uchar0{181}} +\definecharacter paragraphmark {\uchar0{182}} +\definecharacter periodcentered {\uchar0{183}} +\definecharacter textcedilla {\uchar0{184}} +\definecharacter onesuperior {\uchar0{185}} + +\definecharacter textgrave {\uchar3{0}} +\definecharacter textacute {\uchar3{1}} +\definecharacter textcircumflex {\uchar3{2}} +\definecharacter texttilde {\uchar3{3}} +\definecharacter textmacron {\uchar3{4}} +\definecharacter textbreve {\uchar3{6}} +\definecharacter textdotaccent {\uchar3{7}} +\definecharacter textdiaeresis {\uchar3{8}} +\definecharacter textring {\uchar3{10}} +\definecharacter texthungarumlaut {\uchar3{11}} +\definecharacter textcaron {\uchar3{12}} +\definecharacter textogonek {\uchar3{40}} + +\definecharacter percent {\uchar0{37}} +\definecharacter textunderscore {\uchar0{95}} + +\definecharacter ordfeminine {\uchar0{170}} +\definecharacter ordmasculine {\uchar0{186}} +\definecharacter onequarter {\uchar0{188}} +\definecharacter onehalf {\uchar0{189}} +\definecharacter threequarter {\uchar0{190}} +\definecharacter questiondown {\uchar0{191}} + +\definecharacter textmultiply {\uchar0{215}} +\definecharacter textdiv {\uchar0{247}} + +\definecharacter textminus {\uchar{32}{18}} +\definecharacter textdag {\uchar{32}{32}} +\definecharacter textddag {\uchar{32}{33}} +\definecharacter textbullet {\uchar{32}{34}} +\definecharacter textellipsis {\uchar{32}{38}} +\definecharacter perthousand {\uchar{32}{48}} + +%new: +\definecharacter Scommaaccent {\uchar2{24}} +\definecharacter scommaaccent {\uchar2{25}} +\definecharacter Tcommaaccent {\uchar2{26}} +\definecharacter tcommaaccent {\uchar2{27}} + +\stopencoding + +%D Mojca's and Taco's additions: + +\startencoding[uc] + +\definecharacter textasciicircum {\uchar{0}{94}} % 5e +\definecharacter textgrave {\uchar{0}{96}} % 60 +\definecharacter textdiaeresis {\uchar{0}{168}} % a8 +%definecharacter textmacron {\uchar{0}{175}} % af +%definecharacter textacute {\uchar{0}{180}} % b4 +%definecharacter textcedilla {\uchar{0}{184}} % b8 +\definecharacter textcircumflex {\uchar{2}{198}} % c6 +\definecharacter textcaron {\uchar{2}{199}} % c7 +\definecharacter textbreve {\uchar{2}{216}} % d8 +\definecharacter textdotaccent {\uchar{2}{217}} % d9 +\definecharacter textring {\uchar{2}{218}} % da +\definecharacter textogonek {\uchar{2}{219}} % db +\definecharacter texttilde {\uchar{2}{220}} % dc +\definecharacter texthungarumlaut {\uchar{2}{221}} % dd + +\stopencoding + +%D Vietnamese: + +\startencoding[uc] + +\definecharacter Ohorn {\uchar1{160}} +\definecharacter ohorn {\uchar1{161}} +\definecharacter Uhorn {\uchar1{175}} +\definecharacter uhorn {\uchar1{176}} + +\definecharacter Yhook {\uchar{30}{246}} +\definecharacter yhook {\uchar{30}{247}} +\definecharacter Ydotbelow {\uchar{30}{244}} +\definecharacter ydotbelow {\uchar{30}{245}} +\definecharacter Ahook {\uchar{30}{162}} +\definecharacter Adotbelow {\uchar{30}{160}} +\definecharacter Acircumflexgrave {\uchar{30}{166}} +\definecharacter Acircumflexacute {\uchar{30}{164}} +\definecharacter Acircumflextilde {\uchar{30}{170}} +\definecharacter Acircumflexhook {\uchar{30}{168}} +\definecharacter Acircumflexdotbelow {\uchar{30}{172}} +\definecharacter Abrevegrave {\uchar{30}{176}} +\definecharacter Abreveacute {\uchar{30}{174}} +\definecharacter Abrevetilde {\uchar{30}{180}} +\definecharacter Abrevehook {\uchar{30}{178}} +\definecharacter Abrevedotbelow {\uchar{30}{182}} +\definecharacter Ehook {\uchar{30}{186}} +\definecharacter Edotbelow {\uchar{30}{184}} +\definecharacter Ecircumflexgrave {\uchar{30}{192}} +\definecharacter Ecircumflexacute {\uchar{30}{190}} +\definecharacter Ecircumflextilde {\uchar{30}{196}} +\definecharacter Ecircumflexhook {\uchar{30}{194}} +\definecharacter Ecircumflexdotbelow {\uchar{30}{198}} +\definecharacter Ihook {\uchar{30}{200}} +\definecharacter ahook {\uchar{30}{163}} +\definecharacter adotbelow {\uchar{30}{161}} +\definecharacter acircumflexgrave {\uchar{30}{167}} +\definecharacter acircumflexacute {\uchar{30}{165}} +\definecharacter acircumflextilde {\uchar{30}{171}} +\definecharacter acircumflexhook {\uchar{30}{169}} +\definecharacter acircumflexdotbelow {\uchar{30}{173}} +\definecharacter abrevegrave {\uchar{30}{177}} +\definecharacter abreveacute {\uchar{30}{175}} +\definecharacter abrevetilde {\uchar{30}{181}} +\definecharacter abrevehook {\uchar{30}{179}} +\definecharacter abrevedotbelow {\uchar{30}{183}} +\definecharacter ehook {\uchar{30}{187}} +\definecharacter edotbelow {\uchar{30}{185}} +\definecharacter ecircumflexgrave {\uchar{30}{193}} +\definecharacter ecircumflexacute {\uchar{30}{191}} +\definecharacter ecircumflextilde {\uchar{30}{197}} +\definecharacter ecircumflexhook {\uchar{30}{195}} +\definecharacter ecircumflexdotbelow {\uchar{30}{199}} +\definecharacter ihook {\uchar{30}{201}} +\definecharacter Idotbelow {\uchar{30}{202}} +\definecharacter Ohook {\uchar{30}{206}} +\definecharacter Odotbelow {\uchar{30}{204}} +\definecharacter Ocircumflexgrave {\uchar{30}{210}} +\definecharacter Ocircumflexacute {\uchar{30}{208}} +\definecharacter Ocircumflextilde {\uchar{30}{214}} +\definecharacter Ocircumflexhook {\uchar{30}{212}} +\definecharacter Ocircumflexdotbelow {\uchar{30}{216}} +\definecharacter Ohorngrave {\uchar{30}{220}} +\definecharacter Ohornacute {\uchar{30}{218}} +\definecharacter Ohorntilde {\uchar{30}{224}} +\definecharacter Ohornhook {\uchar{30}{222}} +\definecharacter Ohorndotbelow {\uchar{30}{226}} +\definecharacter Uhook {\uchar{30}{230}} +\definecharacter Udotbelow {\uchar{30}{228}} +\definecharacter Uhorngrave {\uchar{30}{234}} +\definecharacter Uhornacute {\uchar{30}{232}} +\definecharacter Uhorntilde {\uchar{30}{238}} +\definecharacter Uhornhook {\uchar{30}{236}} +\definecharacter Uhorndotbelow {\uchar{30}{240}} +\definecharacter Ytilde {\uchar{30}{248}} +\definecharacter idotbelow {\uchar{30}{203}} +\definecharacter ohook {\uchar{30}{207}} +\definecharacter odotbelow {\uchar{30}{205}} +\definecharacter ocircumflexgrave {\uchar{30}{211}} +\definecharacter ocircumflexacute {\uchar{30}{209}} +\definecharacter ocircumflextilde {\uchar{30}{215}} +\definecharacter ocircumflexhook {\uchar{30}{213}} +\definecharacter ocircumflexdotbelow {\uchar{30}{217}} +\definecharacter ohorngrave {\uchar{30}{221}} +\definecharacter ohornacute {\uchar{30}{219}} +\definecharacter ohorntilde {\uchar{30}{225}} +\definecharacter ohornhook {\uchar{30}{223}} +\definecharacter ohorndotbelow {\uchar{30}{227}} +\definecharacter uhook {\uchar{30}{231}} +\definecharacter udotbelow {\uchar{30}{229}} +\definecharacter uhorngrave {\uchar{30}{235}} +\definecharacter uhornacute {\uchar{30}{233}} +\definecharacter uhorntilde {\uchar{30}{239}} +\definecharacter uhornhook {\uchar{30}{237}} +\definecharacter uhorndotbelow {\uchar{30}{241}} +\definecharacter ytilde {\uchar{30}{249}} + +\definecharacter Etilde {\uchar{30}{188}} +\definecharacter etilde {\uchar{30}{189}} +\definecharacter Ygrave {\uchar{30}{242}} +\definecharacter ygrave {\uchar{30}{243}} + +\stopencoding + +% Greek: + +\startencoding[uc] + +\definecharacter greekAlphatonos {\uchar3{134}} +\definecharacter greekEpsilontonos {\uchar3{136}} +\definecharacter greekEtatonos {\uchar3{137}} +\definecharacter greekIotatonos {\uchar3{138}} +\definecharacter greekOmicrontonos {\uchar3{140}} +\definecharacter greekUpsilontonos {\uchar3{142}} +\definecharacter greekOmegatonos {\uchar3{143}} +\definecharacter greekiotadialytikatonos {\uchar3{144}} +\definecharacter greekAlpha {\uchar3{145}} +\definecharacter greekBeta {\uchar3{146}} +\definecharacter greekGamma {\uchar3{147}} +\definecharacter greekDelta {\uchar3{148}} +\definecharacter greekEpsilon {\uchar3{149}} +\definecharacter greekZeta {\uchar3{150}} +\definecharacter greekEta {\uchar3{151}} +\definecharacter greekTheta {\uchar3{152}} +\definecharacter greekIota {\uchar3{153}} +\definecharacter greekKappa {\uchar3{154}} +\definecharacter greekLambda {\uchar3{155}} +\definecharacter greekMu {\uchar3{156}} +\definecharacter greekNu {\uchar3{157}} +\definecharacter greekXi {\uchar3{158}} +\definecharacter greekOmicron {\uchar3{159}} +\definecharacter greekPi {\uchar3{160}} +\definecharacter greekRho {\uchar3{161}} +\definecharacter greekSigma {\uchar3{163}} +\definecharacter greekTau {\uchar3{164}} +\definecharacter greekUpsilon {\uchar3{165}} +\definecharacter greekPhi {\uchar3{166}} +\definecharacter greekChi {\uchar3{167}} +\definecharacter greekPsi {\uchar3{168}} +\definecharacter greekOmega {\uchar3{169}} + +\definecharacter greekalpha {\uchar3{177}} +\definecharacter greekbeta {\uchar3{178}} +\definecharacter greekgamma {\uchar3{179}} +\definecharacter greekdelta {\uchar3{180}} +\definecharacter greekepsilon {\uchar3{181}} +\definecharacter greekzeta {\uchar3{182}} +\definecharacter greeketa {\uchar3{183}} +\definecharacter greektheta {\uchar3{184}} +\definecharacter greekiota {\uchar3{185}} +\definecharacter greekkappa {\uchar3{186}} +\definecharacter greeklambda {\uchar3{187}} +\definecharacter greekmu {\uchar3{188}} +\definecharacter greeknu {\uchar3{189}} +\definecharacter greekxi {\uchar3{190}} +\definecharacter greekomicron {\uchar3{191}} +\definecharacter greekpi {\uchar3{192}} +\definecharacter greekrho {\uchar3{193}} +\definecharacter greekfinalsigma {\uchar3{194}} +\definecharacter greeksigma {\uchar3{195}} +\definecharacter greektau {\uchar3{196}} +\definecharacter greekupsilon {\uchar3{197}} +\definecharacter greekphi {\uchar3{198}} +\definecharacter greekchi {\uchar3{199}} +\definecharacter greekpsi {\uchar3{200}} +\definecharacter greekomega {\uchar3{201}} +\definecharacter greekiotadialytika {\uchar3{202}} +\definecharacter greekupsilondialytika {\uchar3{203}} +\definecharacter greekomicrontonos {\uchar3{204}} +\definecharacter greekupsilontonos {\uchar3{205}} +\definecharacter greekomegatonos {\uchar3{206}} + +\definecharacter greekIotadialytika {\uchar3{170}} +\definecharacter greekUpsilondialytika {\uchar3{171}} + +\definecharacter greekalphatonos {\uchar3{172}} +\definecharacter greekepsilontonos {\uchar3{173}} +\definecharacter greeketatonos {\uchar3{174}} +\definecharacter greekiotatonos {\uchar3{175}} +\definecharacter greekupsilondialytikatonos {\uchar3{176}} + +% new: +\definecharacter greekthetaalt {\uchar3{209}} +\definecharacter greekphialt {\uchar3{213}} +\definecharacter greekpialt {\uchar3{214}} +\definecharacter greekrhoalt {\uchar3{241}} +\definecharacter greekepsilonalt {\uchar3{245}} + +\stopencoding + +% Cyrillic: + +\startencoding[uc] + +\definecharacter cyrillicA {\uchar4{16}} +\definecharacter cyrillicB {\uchar4{17}} +\definecharacter cyrillicV {\uchar4{18}} +\definecharacter cyrillicG {\uchar4{19}} +\definecharacter cyrillicD {\uchar4{20}} +\definecharacter cyrillicE {\uchar4{21}} +\definecharacter cyrillicZH {\uchar4{22}} +\definecharacter cyrillicZ {\uchar4{23}} +\definecharacter cyrillicI {\uchar4{24}} +\definecharacter cyrillicISHRT {\uchar4{25}} +\definecharacter cyrillicK {\uchar4{26}} +\definecharacter cyrillicL {\uchar4{27}} +\definecharacter cyrillicM {\uchar4{28}} +\definecharacter cyrillicN {\uchar4{29}} +\definecharacter cyrillicO {\uchar4{30}} +\definecharacter cyrillicP {\uchar4{31}} +\definecharacter cyrillicR {\uchar4{32}} +\definecharacter cyrillicS {\uchar4{33}} +\definecharacter cyrillicT {\uchar4{34}} +\definecharacter cyrillicU {\uchar4{35}} +\definecharacter cyrillicF {\uchar4{36}} +\definecharacter cyrillicH {\uchar4{37}} +\definecharacter cyrillicC {\uchar4{38}} +\definecharacter cyrillicCH {\uchar4{39}} +\definecharacter cyrillicSH {\uchar4{40}} +\definecharacter cyrillicSHCH {\uchar4{41}} +\definecharacter cyrillicHRDSN {\uchar4{42}} +\definecharacter cyrillicERY {\uchar4{43}} +\definecharacter cyrillicSFTSN {\uchar4{44}} +\definecharacter cyrillicEREV {\uchar4{45}} +\definecharacter cyrillicYU {\uchar4{46}} +\definecharacter cyrillicYA {\uchar4{47}} + +\definecharacter cyrillica {\uchar4{48}} +\definecharacter cyrillicb {\uchar4{49}} +\definecharacter cyrillicv {\uchar4{50}} +\definecharacter cyrillicg {\uchar4{51}} +\definecharacter cyrillicd {\uchar4{52}} +\definecharacter cyrillice {\uchar4{53}} +\definecharacter cyrilliczh {\uchar4{54}} +\definecharacter cyrillicz {\uchar4{55}} +\definecharacter cyrillici {\uchar4{56}} +\definecharacter cyrillicishrt {\uchar4{57}} +\definecharacter cyrillick {\uchar4{58}} +\definecharacter cyrillicl {\uchar4{59}} +\definecharacter cyrillicm {\uchar4{60}} +\definecharacter cyrillicn {\uchar4{61}} +\definecharacter cyrillico {\uchar4{62}} +\definecharacter cyrillicp {\uchar4{63}} +\definecharacter cyrillicr {\uchar4{64}} +\definecharacter cyrillics {\uchar4{65}} +\definecharacter cyrillict {\uchar4{66}} +\definecharacter cyrillicu {\uchar4{67}} +\definecharacter cyrillicf {\uchar4{68}} +\definecharacter cyrillich {\uchar4{69}} +\definecharacter cyrillicc {\uchar4{70}} +\definecharacter cyrillicch {\uchar4{71}} +\definecharacter cyrillicsh {\uchar4{72}} +\definecharacter cyrillicshch {\uchar4{73}} +\definecharacter cyrillichrdsn {\uchar4{74}} +\definecharacter cyrillicery {\uchar4{75}} +\definecharacter cyrillicsftsn {\uchar4{76}} +\definecharacter cyrillicerev {\uchar4{77}} +\definecharacter cyrillicyu {\uchar4{78}} +\definecharacter cyrillicya {\uchar4{79}} + +%D I tried to figure out what these were, but the unicode +%D tables suggested they were the same as cyrillici, which was +%D already defined! So, a temporary definition: + +% \def\cyrillicII{\cyrillicI} +% \def\cyrillicii{\cyrillici} + +%D a guess derived from looking at enco-cyr suggests that this is +%D identical to the Roman I/i pair. To me, that sounds like +%D CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I in the UC tables! + +\definecharacter cyrillicII {\uchar4{6}} +\definecharacter cyrillicii {\uchar4{86}} + +%D Guessing that tlir6a corresponds with t2a encoding as advertised, +%D here are some more, cos I had some spare time: (AL) + +\definecharacter cyrillicDJE {\uchar4{2}} +\definecharacter cyrillicTSHE {\uchar4{11}} +%definecharacter cyrillicSHHA 132 +%definecharacter cyrillicZHDSC 133 +\definecharacter cyrillicZDSC {\uchar4{152}} +\definecharacter cyrillicLJE {\uchar4{9}} +\definecharacter cyrillicYI {\uchar4{7}} +\definecharacter cyrillicAE {\uchar4{212}} +%definecharacter cyrillicNDSC 141 +%definecharacter cyrillicNG 142 +\definecharacter cyrillicDZE {\uchar4{5}} +%definecharacter cyrillicOTLD 144 +\definecharacter cyrillicSDSC {\uchar4{170}} +\definecharacter cyrillicUSHRT {\uchar4{14}} +%definecharacter cyrillicY 147 +%definecharacter cyrillicYHCRS 148 +%definecharacter cyrillicHDSC 149 +\definecharacter cyrillicDZHE {\uchar4{15}} +\definecharacter cyrillicIE {\uchar4{4}} +\definecharacter cyrillicNJE {\uchar4{10}} +\definecharacter cyrillicYO {\uchar4{1}} + +\definecharacter cyrillicdje {\uchar4{82}} +\definecharacter cyrillictshe {\uchar4{91}} +%definecharacter cyrillicshha 164 +%definecharacter cyrilliczhdsc 165 +\definecharacter cyrilliczdsc {\uchar4{153}} +\definecharacter cyrilliclje {\uchar4{89}} +\definecharacter cyrillicyi {\uchar4{87}} +\definecharacter cyrillicae {\uchar4{213}} +%definecharacter cyrillicndsc 173 +%definecharacter cyrillicng 174 +\definecharacter cyrillicdze {\uchar4{85}} +%definecharacter cyrillicotld 176 +\definecharacter cyrillicsdsc {\uchar4{171}} +\definecharacter cyrillicushrt {\uchar4{94}} +%definecharacter cyrillicy 179 +%definecharacter cyrillicyhcrs 180 +%definecharacter cyrillichdsc 181 +\definecharacter cyrillicdzhe {\uchar4{95}} +\definecharacter cyrillicie {\uchar4{84}} +\definecharacter cyrillicnje {\uchar4{90}} +\definecharacter cyrillicyo {\uchar4{81}} + +% is there overlap with the above definitions + +\definecharacter cyrillicEgrave {\uchar4{0}} +\definecharacter cyrillicGJE {\uchar4{3}} +\definecharacter cyrillicJE {\uchar4{8}} +\definecharacter cyrillicKJE {\uchar4{12}} +\definecharacter cyrillicIgrave {\uchar4{13}} +\definecharacter cyrillicegrave {\uchar4{80}} +\definecharacter cyrillicgje {\uchar4{83}} +\definecharacter cyrillicje {\uchar4{88}} +\definecharacter cyrillickje {\uchar4{92}} +\definecharacter cyrillicigrave {\uchar4{93}} +\definecharacter cyrillicOMEGA {\uchar4{96}} +\definecharacter cyrillicomega {\uchar4{97}} +\definecharacter cyrillicYAT {\uchar4{98}} +\definecharacter cyrillicyat {\uchar4{99}} +\definecharacter cyrillicEiotified {\uchar4{100}} +\definecharacter cyrilliceiotified {\uchar4{101}} +\definecharacter cyrillicLITTLEYUS {\uchar4{102}} +\definecharacter cyrilliclittleyus {\uchar4{103}} +\definecharacter cyrillicLITTLEYUSiotified {\uchar4{104}} +\definecharacter cyrilliclittleyusiotified {\uchar4{105}} +\definecharacter cyrillicBIGYUS {\uchar4{106}} +\definecharacter cyrillicbigyus {\uchar4{107}} +\definecharacter cyrillicBIGYUSiotified {\uchar4{108}} +\definecharacter cyrillicbigyusiotified {\uchar4{109}} +\definecharacter cyrillicKSI {\uchar4{110}} +\definecharacter cyrillicksi {\uchar4{111}} +\definecharacter cyrillicPSI {\uchar4{112}} +\definecharacter cyrillicpsi {\uchar4{113}} +\definecharacter cyrillicFITA {\uchar4{114}} +\definecharacter cyrillicfita {\uchar4{115}} +\definecharacter cyrillicIZHITSA {\uchar4{116}} +\definecharacter cyrillicizhitsa {\uchar4{117}} +\definecharacter cyrillicIZHITSAdoublegrave {\uchar4{118}} +\definecharacter cyrillicizhitsadoublegrave {\uchar4{119}} +\definecharacter cyrillicUK {\uchar4{120}} +\definecharacter cyrillicuk {\uchar4{121}} +\definecharacter cyrillicOMEGAround {\uchar4{122}} +\definecharacter cyrillicomegaround {\uchar4{123}} +\definecharacter cyrillicOMEGAtitlo {\uchar4{124}} +\definecharacter cyrillicomegatitlo {\uchar4{125}} +\definecharacter cyrillicOT {\uchar4{126}} +\definecharacter cyrillicot {\uchar4{127}} +\definecharacter cyrillicKOPPA {\uchar4{128}} +\definecharacter cyrillickoppa {\uchar4{129}} +\definecharacter cyrillicTITLO {\uchar4{131}} +\definecharacter cyrillicPALATALIZATION {\uchar4{132}} +\definecharacter cyrillicDASIAPNEUMATA {\uchar4{133}} +\definecharacter cyrillicPSILIPNEUMATA {\uchar4{134}} +\definecharacter cyrillicISHRTtail {\uchar4{138}} +\definecharacter cyrillicishrttail {\uchar4{139}} +\definecharacter cyrillicSEMISOFT {\uchar4{140}} +\definecharacter cyrillicsemisoft {\uchar4{141}} +\definecharacter cyrillicERtick {\uchar4{142}} +\definecharacter cyrillicertick {\uchar4{143}} +\definecharacter cyrillicGHEupturn {\uchar4{144}} +\definecharacter cyrillicgheupturn {\uchar4{145}} +\definecharacter cyrillicGHEstroke {\uchar4{146}} +\definecharacter cyrillicghestroke {\uchar4{147}} +\definecharacter cyrillicGHEmidhook {\uchar4{148}} +\definecharacter cyrillicghemidhook {\uchar4{149}} +\definecharacter cyrillicZHEdescender {\uchar4{150}} +\definecharacter cyrilliczhedescender {\uchar4{151}} +\definecharacter cyrillicZDSC {\uchar4{152}} +\definecharacter cyrilliczdsc {\uchar4{153}} +\definecharacter cyrillicKADC {\uchar4{154}} +\definecharacter cyrillickadc {\uchar4{155}} +\definecharacter cyrillicKAvertstroke {\uchar4{156}} +\definecharacter cyrillickavertstroke {\uchar4{157}} +\definecharacter cyrillicKAstroke {\uchar4{158}} +\definecharacter cyrillickastroke {\uchar4{159}} +\definecharacter cyrillicKAbashkir {\uchar4{160}} +\definecharacter cyrillickabashkir {\uchar4{161}} +\definecharacter cyrillicENDC {\uchar4{162}} +\definecharacter cyrillicendc {\uchar4{163}} +\definecharacter cyrillicENGHE {\uchar4{164}} +\definecharacter cyrillicenghe {\uchar4{165}} +\definecharacter cyrillicPEmidhook {\uchar4{166}} +\definecharacter cyrillicpemidhook {\uchar4{167}} +\definecharacter cyrillicHA {\uchar4{168}} +\definecharacter cyrillicha {\uchar4{169}} +%definecharacter cyrillicSDSC {\uchar4{170}} % already defined +%definecharacter cyrilliccdsc {\uchar4{171}} % already defined +\definecharacter cyrillicTEDC {\uchar4{172}} +\definecharacter cyrillictedc {\uchar4{173}} +\definecharacter cyrillicYstr {\uchar4{174}} +\definecharacter cyrillicystr {\uchar4{175}} +\definecharacter cyrillicYstrstroke {\uchar4{176}} +\definecharacter cyrillicystrstroke {\uchar4{177}} +\definecharacter cyrillicHADC {\uchar4{178}} +\definecharacter cyrillichadc {\uchar4{179}} +\definecharacter cyrillicTETSE {\uchar4{180}} +\definecharacter cyrillictetse {\uchar4{181}} +\definecharacter cyrillicCHEDC {\uchar4{182}} +\definecharacter cyrillicchedc {\uchar4{183}} +\definecharacter cyrillicCHEvertstroke {\uchar4{184}} +\definecharacter cyrillicchevertstroke {\uchar4{185}} +\definecharacter cyrillicSHHA {\uchar4{186}} +\definecharacter cyrillicshha {\uchar4{187}} +\definecharacter cyrillicCHEabkhasian {\uchar4{188}} +\definecharacter cyrilliccheabkhasian {\uchar4{189}} +\definecharacter cyrillicCHEDCabkhasian {\uchar4{190}} +\definecharacter cyrillicchedcabkhasian {\uchar4{191}} +\definecharacter cyrillicPALOCHKA {\uchar4{192}} +\definecharacter cyrillicZHEbreve {\uchar4{193}} +\definecharacter cyrilliczhebreve {\uchar4{194}} +\definecharacter cyrillicKAhook {\uchar4{195}} +\definecharacter cyrillickahook {\uchar4{196}} +\definecharacter cyrillicELtail {\uchar4{197}} +\definecharacter cyrilliceltail {\uchar4{198}} +\definecharacter cyrillicENhook {\uchar4{199}} +\definecharacter cyrillicenhook {\uchar4{200}} +\definecharacter cyrillicENtail {\uchar4{201}} +\definecharacter cyrillicentail {\uchar4{202}} +\definecharacter cyrillicCHEkhakassian {\uchar4{203}} +\definecharacter cyrillicchekhakassian {\uchar4{204}} +\definecharacter cyrillicEMtail {\uchar4{205}} +\definecharacter cyrillicemtail {\uchar4{206}} +\definecharacter cyrillicAbreve {\uchar4{208}} +\definecharacter cyrillicabreve {\uchar4{209}} +\definecharacter cyrillicAdiaeresis {\uchar4{210}} +\definecharacter cyrillicadiaeresis {\uchar4{211}} +%definecharacter cyrillicAE {\uchar4{212}} % already defined +%definecharacter cyrillicae {\uchar4{213}} % already defined +\definecharacter cyrillicEbreve {\uchar4{214}} +\definecharacter cyrillicebreve {\uchar4{215}} +\definecharacter cyrillicSCHWA {\uchar4{216}} +\definecharacter cyrillicschwa {\uchar4{217}} +\definecharacter cyrillicSCHWAdiaeresis {\uchar4{218}} +\definecharacter cyrillicschwadiaeresis {\uchar4{219}} +\definecharacter cyrillicZHEdiaeresis {\uchar4{220}} +\definecharacter cyrilliczhediaeresis {\uchar4{221}} +\definecharacter cyrillicZEdiaeresis {\uchar4{222}} +\definecharacter cyrilliczediaeresis {\uchar4{223}} +\definecharacter cyrillicDZEabkhasian {\uchar4{224}} +\definecharacter cyrillicdzeabkhasian {\uchar4{225}} +\definecharacter cyrillicImacron {\uchar4{226}} +\definecharacter cyrillicimacron {\uchar4{227}} +\definecharacter cyrillicIdiaeresis {\uchar4{228}} +\definecharacter cyrillicidiaeresis {\uchar4{229}} +\definecharacter cyrillicOdiaeresis {\uchar4{230}} +\definecharacter cyrillicodiaeresis {\uchar4{231}} +\definecharacter cyrillicObarred {\uchar4{232}} +\definecharacter cyrillicobarred {\uchar4{233}} +\definecharacter cyrillicObarreddiaeresis {\uchar4{234}} +\definecharacter cyrillicobarreddiaeresis {\uchar4{235}} +\definecharacter cyrillicEdiaeresis {\uchar4{236}} +\definecharacter cyrillicediaeresis {\uchar4{237}} +\definecharacter cyrillicUmacron {\uchar4{238}} +\definecharacter cyrillicumacron {\uchar4{239}} +\definecharacter cyrillicUdiaeresis {\uchar4{240}} +\definecharacter cyrillicudiaeresis {\uchar4{241}} +\definecharacter cyrillicUdoubleacute {\uchar4{242}} +\definecharacter cyrillicudoubleacute {\uchar4{243}} +\definecharacter cyrillicCHEdiaeresis {\uchar4{244}} +\definecharacter cyrillicchediaeresis {\uchar4{245}} +\definecharacter cyrillicYERUdiaeresis {\uchar4{248}} +\definecharacter cyrillicyerudiaeresis {\uchar4{249}} + +\stopencoding + +% Greek Extended + +\startencoding[uc] + +\definecharacter greekalphapsili {\uchar{31}{0}} +\definecharacter greekalphadasia {\uchar{31}{1}} +\definecharacter greekalphapsilivaria {\uchar{31}{2}} +\definecharacter greekalphadasiavaria {\uchar{31}{3}} +\definecharacter greekalphapsilitonos {\uchar{31}{4}} +\definecharacter greekalphadasiatonos {\uchar{31}{5}} +\definecharacter greekalphapsiliperispomeni {\uchar{31}{6}} +\definecharacter greekalphadasiaperispomeni {\uchar{31}{7}} +\definecharacter greekAlphapsili {\uchar{31}{8}} +\definecharacter greekAlphadasia {\uchar{31}{9}} +\definecharacter greekAlphapsilivaria {\uchar{31}{10}} +\definecharacter greekAlphadasiavaria {\uchar{31}{11}} +\definecharacter greekAlphapsilitonos {\uchar{31}{12}} +\definecharacter greekAlphadasiatonos {\uchar{31}{13}} +\definecharacter greekAlphapsiliperispomeni {\uchar{31}{14}} +\definecharacter greekAlphadasiaperispomeni {\uchar{31}{15}} +\definecharacter greekepsilonpsili {\uchar{31}{16}} % 1f10 +\definecharacter greekepsilondasia {\uchar{31}{17}} +\definecharacter greekepsilonpsilivaria {\uchar{31}{18}} +\definecharacter greekepsilondasiavaria {\uchar{31}{19}} +\definecharacter greekepsilonpsilitonos {\uchar{31}{20}} +\definecharacter greekepsilondasiatonos {\uchar{31}{21}} +\definecharacter greekEpsilonpsili {\uchar{31}{24}} +\definecharacter greekEpsilondasia {\uchar{31}{25}} +\definecharacter greekEpsilonpsilivaria {\uchar{31}{26}} +\definecharacter greekEpsilondasiavaria {\uchar{31}{27}} +\definecharacter greekEpsilonpsilitonos {\uchar{31}{28}} +\definecharacter greekEpsilondasiatonos {\uchar{31}{29}} +\definecharacter greeketapsili {\uchar{31}{32}} % 1f20 +\definecharacter greeketadasia {\uchar{31}{33}} +\definecharacter greeketapsilivaria {\uchar{31}{34}} +\definecharacter greeketadasiavaria {\uchar{31}{35}} +\definecharacter greeketapsilitonos {\uchar{31}{36}} +\definecharacter greeketadasiatonos {\uchar{31}{37}} +\definecharacter greeketapsiliperispomeni {\uchar{31}{38}} +\definecharacter greeketadasiaperispomeni {\uchar{31}{39}} +\definecharacter greekEtapsili {\uchar{31}{40}} +\definecharacter greekEtadasia {\uchar{31}{41}} +\definecharacter greekEtapsilivaria {\uchar{31}{42}} +\definecharacter greekEtadasiavaria {\uchar{31}{43}} +\definecharacter greekEtapsilitonos {\uchar{31}{44}} +\definecharacter greekEtadasiatonos {\uchar{31}{45}} +\definecharacter greekEtapsiliperispomeni {\uchar{31}{46}} +\definecharacter greekEtadasiaperispomeni {\uchar{31}{47}} +\definecharacter greekiotapsili {\uchar{31}{48}} % 1f30 +\definecharacter greekiotadasia {\uchar{31}{49}} +\definecharacter greekiotapsilivaria {\uchar{31}{50}} +\definecharacter greekiotadasiavaria {\uchar{31}{51}} +\definecharacter greekiotapsilitonos {\uchar{31}{52}} +\definecharacter greekiotadasiatonos {\uchar{31}{53}} +\definecharacter greekiotapsiliperispomeni {\uchar{31}{54}} +\definecharacter greekiotadasiaperispomeni {\uchar{31}{55}} +\definecharacter greekIotapsili {\uchar{31}{56}} +\definecharacter greekIotadasia {\uchar{31}{57}} +\definecharacter greekIotapsilivaria {\uchar{31}{58}} +\definecharacter greekIotadasiavaria {\uchar{31}{59}} +\definecharacter greekIotapsilitonos {\uchar{31}{60}} +\definecharacter greekIotadasiatonos {\uchar{31}{61}} +\definecharacter greekIotapsiliperispomeni {\uchar{31}{62}} +\definecharacter greekIotadasiaperispomeni {\uchar{31}{63}} +\definecharacter greekomicronpsili {\uchar{31}{64}} % 1f40 +\definecharacter greekomicrondasia {\uchar{31}{65}} +\definecharacter greekomicronpsilivaria {\uchar{31}{66}} +\definecharacter greekomicrondasiavaria {\uchar{31}{67}} +\definecharacter greekomicronpsilitonos {\uchar{31}{68}} +\definecharacter greekomicrondasiatonos {\uchar{31}{69}} +\definecharacter greekOmicronpsili {\uchar{31}{72}} +\definecharacter greekOmicrondasia {\uchar{31}{73}} +\definecharacter greekOmicronpsilivaria {\uchar{31}{74}} +\definecharacter greekOmicrondasiavaria {\uchar{31}{75}} +\definecharacter greekOmicronpsilitonos {\uchar{31}{76}} +\definecharacter greekOmicrondasiatonos {\uchar{31}{77}} +\definecharacter greekupsilonpsili {\uchar{31}{80}} % 1f50 +\definecharacter greekupsilondasia {\uchar{31}{81}} +\definecharacter greekupsilonpsilivaria {\uchar{31}{82}} +\definecharacter greekupsilondasiavaria {\uchar{31}{83}} +\definecharacter greekupsilonpsilitonos {\uchar{31}{84}} +\definecharacter greekupsilondasiatonos {\uchar{31}{85}} +\definecharacter greekupsilonpsiliperispomeni {\uchar{31}{86}} +\definecharacter greekupsilondasiaperispomeni {\uchar{31}{87}} +\definecharacter greekUpsilondasia {\uchar{31}{89}} +\definecharacter greekUpsilondasiavaria {\uchar{31}{91}} +\definecharacter greekUpsilondasiatonos {\uchar{31}{93}} +\definecharacter greekUpsilondasiaperispomeni {\uchar{31}{95}} +\definecharacter greekomegapsili {\uchar{31}{96}} % 1f60 +\definecharacter greekomegadasia {\uchar{31}{97}} +\definecharacter greekomegapsilivaria {\uchar{31}{98}} +\definecharacter greekomegadasiavaria {\uchar{31}{99}} +\definecharacter greekomegapsilitonos {\uchar{31}{100}} +\definecharacter greekomegadasiatonos {\uchar{31}{101}} +\definecharacter greekomegapsiliperispomeni {\uchar{31}{102}} +\definecharacter greekomegadasiaperispomeni {\uchar{31}{103}} +\definecharacter greekOmegapsili {\uchar{31}{104}} +\definecharacter greekOmegadasia {\uchar{31}{105}} +\definecharacter greekOmegapsilivaria {\uchar{31}{106}} +\definecharacter greekOmegadasiavaria {\uchar{31}{107}} +\definecharacter greekOmegapsilitonos {\uchar{31}{108}} +\definecharacter greekOmegadasiatonos {\uchar{31}{109}} +\definecharacter greekOmegapsiliperispomeni {\uchar{31}{110}} +\definecharacter greekOmegadasiaperispomeni {\uchar{31}{111}} +\definecharacter greekalphavaria {\uchar{31}{112}} % 1f70 +\definecharacter greekalphaoxia {\uchar{31}{113}} +\definecharacter greekepsilonvaria {\uchar{31}{114}} +\definecharacter greekepsilonoxia {\uchar{31}{115}} +\definecharacter greeketavaria {\uchar{31}{116}} +\definecharacter greeketaoxia {\uchar{31}{117}} +\definecharacter greekiotavaria {\uchar{31}{118}} +\definecharacter greekiotaoxia {\uchar{31}{119}} +\definecharacter greekomicronvaria {\uchar{31}{120}} +\definecharacter greekomicronoxia {\uchar{31}{121}} +\definecharacter greekupsilonvaria {\uchar{31}{122}} +\definecharacter greekupsilonoxia {\uchar{31}{123}} +\definecharacter greekomegavaria {\uchar{31}{124}} +\definecharacter greekomegaoxia {\uchar{31}{125}} +\definecharacter greekalphaiotasubpsili {\uchar{31}{128}} % 1f80 +\definecharacter greekalphaiotasubdasia {\uchar{31}{129}} +\definecharacter greekalphaiotasubpsilivaria {\uchar{31}{130}} +\definecharacter greekalphaiotasubdasiavaria {\uchar{31}{131}} +\definecharacter greekalphaiotasubpsilitonos {\uchar{31}{132}} +\definecharacter greekalphaiotasubdasiatonos {\uchar{31}{133}} +\definecharacter greekalphaiotasubpsiliperispomeni {\uchar{31}{134}} +\definecharacter greekalphaiotasubdasiaperispomeni {\uchar{31}{135}} +\definecharacter greekAlphaiotasubpsili {\uchar{31}{136}} +\definecharacter greekAlphaiotasubdasia {\uchar{31}{137}} +\definecharacter greekAlphaiotasubpsilivaria {\uchar{31}{138}} +\definecharacter greekAlphaiotasubdasiavaria {\uchar{31}{139}} +\definecharacter greekAlphaiotasubpsilitonos {\uchar{31}{140}} +\definecharacter greekAlphaiotasubdasiatonos {\uchar{31}{141}} +\definecharacter greekAlphaiotasubpsiliperispomeni {\uchar{31}{142}} +\definecharacter greekAlphaiotasubdasiaperispomeni {\uchar{31}{143}} +\definecharacter greeketaiotasubpsili {\uchar{31}{144}} % 1f90 +\definecharacter greeketaiotasubdasia {\uchar{31}{145}} +\definecharacter greeketaiotasubpsilivaria {\uchar{31}{146}} +\definecharacter greeketaiotasubdasiavaria {\uchar{31}{147}} +\definecharacter greeketaiotasubpsilitonos {\uchar{31}{148}} +\definecharacter greeketaiotasubdasiatonos {\uchar{31}{149}} +\definecharacter greeketaiotasubpsiliperispomeni {\uchar{31}{150}} +\definecharacter greeketaiotasubdasiaperispomeni {\uchar{31}{151}} +\definecharacter greekEtaiotasubpsili {\uchar{31}{152}} +\definecharacter greekEtaiotasubdasia {\uchar{31}{153}} +\definecharacter greekEtaiotasubpsilivaria {\uchar{31}{154}} +\definecharacter greekEtaiotasubdasiavaria {\uchar{31}{155}} +\definecharacter greekEtaiotasubpsilitonos {\uchar{31}{156}} +\definecharacter greekEtaiotasubdasiatonos {\uchar{31}{157}} +\definecharacter greekEtaiotasubpsiliperispomeni {\uchar{31}{158}} +\definecharacter greekEtaiotasubdasiaperispomeni {\uchar{31}{159}} +\definecharacter greekomegaiotasubpsili {\uchar{31}{160}} % 1fa0 +\definecharacter greekomegaiotasubdasia {\uchar{31}{161}} +\definecharacter greekomegaiotasubpsilivaria {\uchar{31}{162}} +\definecharacter greekomegaiotasubdasiavaria {\uchar{31}{163}} +\definecharacter greekomegaiotasubpsilitonos {\uchar{31}{164}} +\definecharacter greekomegaiotasubdasiatonos {\uchar{31}{165}} +\definecharacter greekomegaiotasubpsiliperispomeni {\uchar{31}{166}} +\definecharacter greekomegaiotasubdasiaperispomeni {\uchar{31}{167}} +\definecharacter greekOmegaiotasubpsili {\uchar{31}{168}} +\definecharacter greekOmegaiotasubdasia {\uchar{31}{169}} +\definecharacter greekOmegaiotasubpsilivaria {\uchar{31}{170}} +\definecharacter greekOmegaiotasubdasiavaria {\uchar{31}{171}} +\definecharacter greekOmegaiotasubpsilitonos {\uchar{31}{172}} +\definecharacter greekOmegaiotasubdasiatonos {\uchar{31}{173}} +\definecharacter greekOmegaiotasubpsiliperispomeni {\uchar{31}{174}} +\definecharacter greekOmegaiotasubdasiaperispomeni {\uchar{31}{175}} +\definecharacter greekalphavrachy {\uchar{31}{176}} % 1fb0 +\definecharacter greekalphamacron {\uchar{31}{177}} +\definecharacter greekalphaiotasubvaria {\uchar{31}{178}} +\definecharacter greekalphaiotasub {\uchar{31}{179}} +\definecharacter greekalphaiotasubtonos {\uchar{31}{180}} +\definecharacter greekalphaperispomeni {\uchar{31}{182}} +\definecharacter greekalphaiotasubperispomeni {\uchar{31}{183}} +\definecharacter greekAlphavrachy {\uchar{31}{184}} +\definecharacter greekAlphamacron {\uchar{31}{185}} +\definecharacter greekAlphavaria {\uchar{31}{186}} +\definecharacter greekAlphatonos {\uchar{31}{187}} +\definecharacter greekAlphaiotasub {\uchar{31}{188}} +\definecharacter greekCoronis {\uchar{31}{189}} +\definecharacter greekprosgegrammeni {\uchar{31}{190}} +\definecharacter greekpsili {\uchar{31}{191}} +\definecharacter greekperispomeni {\uchar{31}{192}} % 1fc0 +\definecharacter greekdialytikaperispomeni {\uchar{31}{193}} +\definecharacter greeketaiotasubvaria {\uchar{31}{194}} +\definecharacter greeketaiotasub {\uchar{31}{195}} +\definecharacter greeketaiotasubtonos {\uchar{31}{196}} +\definecharacter greeketaperispomeni {\uchar{31}{198}} +\definecharacter greeketaiotasubperispomeni {\uchar{31}{199}} +\definecharacter greekEpsilonvaria {\uchar{31}{200}} +\definecharacter greekEpsilontonos {\uchar{31}{201}} +\definecharacter greekEtavaria {\uchar{31}{202}} +\definecharacter greekEtatonos {\uchar{31}{203}} +\definecharacter greekEtaiotasub {\uchar{31}{204}} +\definecharacter greekpsilivaria {\uchar{31}{205}} +\definecharacter greekpsilitonos {\uchar{31}{206}} +\definecharacter greekpsiliperispomeni {\uchar{31}{207}} +\definecharacter greekiotavrachy {\uchar{31}{208}} % 1fd0 +\definecharacter greekiotamacron {\uchar{31}{209}} +\definecharacter greekiotadialytikavaria {\uchar{31}{210}} +\definecharacter greekiotadialytikatonos {\uchar{31}{211}} +\definecharacter greekiotaperispomeni {\uchar{31}{214}} +\definecharacter greekiotadialytikaperispomeni {\uchar{31}{215}} +\definecharacter greekIotavrachy {\uchar{31}{216}} +\definecharacter greekIotamacron {\uchar{31}{217}} +\definecharacter greekIotavaria {\uchar{31}{218}} +\definecharacter greekIotatonos {\uchar{31}{219}} +\definecharacter greekdasiavaria {\uchar{31}{221}} +\definecharacter greekdasiatonos {\uchar{31}{222}} +\definecharacter greekdasiaperispomeni {\uchar{31}{223}} +\definecharacter greekupsilonvrachy {\uchar{31}{224}} % 1fe0 +\definecharacter greekupsilonmacron {\uchar{31}{225}} +\definecharacter greekupsilondialytikavaria {\uchar{31}{226}} +\definecharacter greekupsilondialytikatonos {\uchar{31}{227}} +\definecharacter greekrhopsili {\uchar{31}{228}} +\definecharacter greekrhodasia {\uchar{31}{229}} +\definecharacter greekupsilonperispomeni {\uchar{31}{230}} +\definecharacter greekupsilondialytikaperispomeni {\uchar{31}{231}} +\definecharacter greekUpsilonvrachy {\uchar{31}{232}} +\definecharacter greekUpsilonmacron {\uchar{31}{233}} +\definecharacter greekUpsilonvaria {\uchar{31}{234}} +\definecharacter greekUpsilontonos {\uchar{31}{235}} +\definecharacter greekRhodasia {\uchar{31}{236}} +\definecharacter greekdialytikavaria {\uchar{31}{237}} +\definecharacter greekdialytikatonos {\uchar{31}{238}} +\definecharacter greekvaria {\uchar{31}{239}} +\definecharacter greekomegaiotasubvaria {\uchar{31}{242}} +\definecharacter greekomegaiotasub {\uchar{31}{243}} +\definecharacter greekomegaiotasubtonos {\uchar{31}{244}} +\definecharacter greekomegaperispomeni {\uchar{31}{246}} +\definecharacter greekomegaiotasubperispomeni {\uchar{31}{247}} +\definecharacter greekOmicronvaria {\uchar{31}{248}} +\definecharacter greekOmicrontonos {\uchar{31}{249}} +\definecharacter greekOmegavaria {\uchar{31}{250}} +\definecharacter greekOmegatonos {\uchar{31}{251}} +\definecharacter greekOmegaiotasub {\uchar{31}{252}} +\definecharacter greekoxia {\uchar{31}{253}} +\definecharacter greekdasia {\uchar{31}{254}} +\definecharacter greeksigmalunate {\uchar3{242}} +\definecharacter greekSigmalunate {\uchar3{249}} +\definecharacter greeksampi {\uchar3{225}} +\definecharacter greekdigamma {\uchar3{221}} +\definecharacter greekstigma {\uchar3{219}} +\definecharacter greeknumkoppa {\uchar3{223}} +\definecharacter greekkoppa {\uchar3{217}} +\definecharacter greekupsilondiaeresis {\uchar3{203}} + +\stopencoding + +% Hebrew: + +\startencoding[uc] + +\definecharacter hebrewAlef {\uchar5{208}} % 05D0 +\definecharacter hebrewBet {\uchar5{209}} +\definecharacter hebrewGimel {\uchar5{210}} +\definecharacter hebrewDalet {\uchar5{211}} +\definecharacter hebrewHe {\uchar5{212}} +\definecharacter hebrewVav {\uchar5{213}} +\definecharacter hebrewZayin {\uchar5{214}} +\definecharacter hebrewHet {\uchar5{215}} +\definecharacter hebrewTet {\uchar5{216}} +\definecharacter hebrewYod {\uchar5{217}} +\definecharacter hebrewKaffinal {\uchar5{218}} +\definecharacter hebrewKaf {\uchar5{219}} +\definecharacter hebrewLamed {\uchar5{220}} +\definecharacter hebrewMemfinal {\uchar5{221}} +\definecharacter hebrewMem {\uchar5{222}} +\definecharacter hebrewNunfinal {\uchar5{223}} +\definecharacter hebrewNun {\uchar5{224}} +\definecharacter hebrewSamekh {\uchar5{225}} +\definecharacter hebrewAyin {\uchar5{226}} +\definecharacter hebrewPefinal {\uchar5{227}} +\definecharacter hebrewPe {\uchar5{228}} +\definecharacter hebrewTsadifinal {\uchar5{229}} +\definecharacter hebrewTsadi {\uchar5{230}} +\definecharacter hebrewQof {\uchar5{231}} +\definecharacter hebrewResh {\uchar5{232}} +\definecharacter hebrewShin {\uchar5{233}} +\definecharacter hebrewTav {\uchar5{234}} % 05EA + +\stopencoding + +\endinput diff --git a/tex/context/base/enco-vis.mkii b/tex/context/base/enco-vis.mkii new file mode 100644 index 000000000..3c1fd7765 --- /dev/null +++ b/tex/context/base/enco-vis.mkii @@ -0,0 +1,3 @@ +% temporary module, needed for downward compatibility + +\input regi-vis.tex \enableregime[viscii] \endinput diff --git a/tex/context/base/enco-vna.mkii b/tex/context/base/enco-vna.mkii new file mode 100644 index 000000000..05753f37b --- /dev/null +++ b/tex/context/base/enco-vna.mkii @@ -0,0 +1,145 @@ +%D \module +%D [ file=enco-vna, +%D version=1999.12.12, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=Vietnamese Accents, +%D author=Han The Thanh & Adam Lindsay & 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 is originally derived from the some files Han The Thanh +%D prepared for \LATEX. The dual accent support is still preliminary, +%D but works ok. It's now adapted to named glyphs, and is activated by +%D \type {\useencoding[thisfile]}. + +%D This was apparently buggy from the start: there is nothing to +%D disambiguate \type {\ohorn} from \type {\ohook}. Both are entered +%D with \type {\h{o}} (AL)! + +%D Once stable, this code will move to \type {enco-acc.tex}. + +\startencoding[default] + +\defineaccent h A {\Ahook} +\defineaccent d A {\Adotbelow} +\defineaccent ` ^A {\Acircumflexgrave} +\defineaccent ' ^A {\Acircumflexacute} +\defineaccent ~ ^A {\Acircumflextilde} +\defineaccent h ^A {\Acircumflexhook} +\defineaccent d ^A {\Acircumflexdotbelow} +\defineaccent ` uA {\Abrevegrave} +\defineaccent ' uA {\Abreveacute} +\defineaccent ~ uA {\Abrevetilde} +\defineaccent h uA {\Abrevehook} +\defineaccent d uA {\Abrevedotbelow} +\defineaccent h E {\Ehook} +\defineaccent d E {\Edotbelow} +\defineaccent ` ^E {\Ecircumflexgrave} +\defineaccent ' ^E {\Ecircumflexacute} +\defineaccent ~ ^E {\Ecircumflextilde} +\defineaccent h ^E {\Ecircumflexhook} +\defineaccent d ^E {\Ecircumflexdotbelow} +\defineaccent h I {\Ihook} +\defineaccent d I {\Idotbelow} +\defineaccent h O {\Ohook} +\defineaccent d O {\Odotbelow} +\defineaccent ` ^O {\Ocircumflexgrave} +\defineaccent ' ^O {\Ocircumflexacute} +\defineaccent ~ ^O {\Ocircumflextilde} +\defineaccent h ^O {\Ocircumflexhook} +\defineaccent d ^O {\Ocircumflexdotbelow} +%defineaccent h O {\Ohorn} % !!! conflict with \Ohook! +\defineaccent ` hO {\Ohorngrave} +\defineaccent ` {\Ohorn} {\Ohorngrave} +\defineaccent ' hO {\Ohornacute} +\defineaccent ' {\Ohorn} {\Ohornacute} +\defineaccent ~ hO {\Ohorntilde} +\defineaccent ~ {\Ohorn} {\Ohorntilde} +\defineaccent h hO {\Ohornhook} +\defineaccent h {\Ohorn} {\Ohornhook} +\defineaccent d hO {\Ohorndotbelow} +\defineaccent d {\Ohorn} {\Ohorndotbelow} +\defineaccent h U {\Uhook} +\defineaccent d U {\Udotbelow} +%defineaccent h U {\Uhorn} % !!! conflict with \Uhook! honestly, people! +\defineaccent ` hU {\Uhorngrave} +\defineaccent ` {\Uhorn} {\Uhorngrave} +\defineaccent ' hU {\Uhornacute} +\defineaccent ' {\Uhorn} {\Uhornacute} +\defineaccent ~ hU {\Uhorntilde} +\defineaccent ~ {\Uhorn} {\Uhorntilde} +\defineaccent h hU {\Uhornhook} +\defineaccent h {\Uhorn} {\Uhornhook} +\defineaccent d hU {\Uhorndotbelow} +\defineaccent d {\Uhorn} {\Uhorndotbelow} +\defineaccent ` Y {\Ygrave} +\defineaccent ' Y {\Yacute} +\defineaccent ~ Y {\Ytilde} +\defineaccent h Y {\Yhook} +\defineaccent d Y {\Ydotbelow} +\defineaccent h a {\ahook} +\defineaccent d a {\adotbelow} +\defineaccent ` ^a {\acircumflexgrave} +\defineaccent ' ^a {\acircumflexacute} +\defineaccent ~ ^a {\acircumflextilde} +\defineaccent h ^a {\acircumflexhook} +\defineaccent d ^a {\acircumflexdotbelow} +\defineaccent ` ua {\abrevegrave} +\defineaccent ' ua {\abreveacute} +\defineaccent ~ ua {\abrevetilde} +\defineaccent h ua {\abrevehook} +\defineaccent d ua {\abrevedotbelow} +\defineaccent h e {\ehook} +\defineaccent d e {\edotbelow} +\defineaccent ` ^e {\ecircumflexgrave} +\defineaccent ' ^e {\ecircumflexacute} +\defineaccent ~ ^e {\ecircumflextilde} +\defineaccent h ^e {\ecircumflexhook} +\defineaccent d ^e {\ecircumflexdotbelow} +\defineaccent h i {\ihook} +\defineaccent d i {\idotbelow} +\defineaccent h o {\ohook} +\defineaccent d o {\odotbelow} +\defineaccent ^ o {\ocircumflex} +\defineaccent ` ^o {\ocircumflexgrave} +\defineaccent ' ^o {\ocircumflexacute} +\defineaccent ~ ^o {\ocircumflextilde} +\defineaccent h ^o {\ocircumflexhook} +\defineaccent d ^o {\ocircumflexdotbelow} +%defineaccent h o {\ohorn} % !!! +\defineaccent ` ho {\ohorngrave} +\defineaccent ' ho {\ohornacute} +\defineaccent ~ ho {\ohorntilde} +\defineaccent h ho {\ohornhook} +\defineaccent d ho {\ohorndotbelow} +\defineaccent ` {\ohorn} {\ohorngrave} +\defineaccent ' {\ohorn} {\ohornacute} +\defineaccent ~ {\ohorn} {\ohorntilde} +\defineaccent h {\ohorn} {\ohornhook} +\defineaccent d {\ohorn} {\ohorndotbelow} +\defineaccent h u {\uhook} +\defineaccent d u {\udotbelow} +%defineaccent h u {\uhorn} % !!! +\defineaccent ` hu {\uhorngrave} +\defineaccent ' hu {\uhornacute} +\defineaccent ~ hu {\uhorntilde} +\defineaccent h hu {\uhornhook} +\defineaccent d hu {\uhorndotbelow} +\defineaccent ` {\uhorn} {\uhorngrave} +\defineaccent ' {\uhorn} {\uhornacute} +\defineaccent ~ {\uhorn} {\uhorntilde} +\defineaccent h {\uhorn} {\uhornhook} +\defineaccent d {\uhorn} {\uhorndotbelow} +\defineaccent ` y {\ygrave} +\defineaccent ' y {\yacute} +\defineaccent ~ y {\ytilde} +\defineaccent h y {\yhook} +\defineaccent d y {\ydotbelow} + +\stopencoding + +\endinput diff --git a/tex/context/base/enco-win.mkii b/tex/context/base/enco-win.mkii new file mode 100644 index 000000000..826371d8a --- /dev/null +++ b/tex/context/base/enco-win.mkii @@ -0,0 +1,7 @@ +% temporary module, needed for downward compatibility + +%\input regi-win.tex + +\enableregime[windows] + +\endinput diff --git a/tex/context/base/enco-x5.mkii b/tex/context/base/enco-x5.mkii new file mode 100644 index 000000000..f82ec6c5c --- /dev/null +++ b/tex/context/base/enco-x5.mkii @@ -0,0 +1,218 @@ +%D \module +%D [ file=enco-x5, +%D version=1999.12.12, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=Vietnamese Encoding, +%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 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] + +\definecharacter textgrave 0 +\definecharacter textacute 1 +\definecharacter textcircumflex 2 +\definecharacter texttilde 3 +\definecharacter textdiaeresis 4 +\definecharacter texthungarumlaut 5 +\definecharacter textring 6 +\definecharacter textcaron 7 +\definecharacter textbreve 8 +\definecharacter textmacron 9 +\definecharacter textdotaccent 10 +\definecharacter textcedilla 11 +\definecharacter textogonek 12 + +\definecharacter dotlessi 25 +\definecharacter DJ 30 +\definecharacter dj 31 + +\defineaccent ` A 128 +\defineaccent ' A 129 +\defineaccent ~ A 130 +\defineaccent h A 131 +\defineaccent d A 132 +\defineaccent ^ A 133 +\defineaccent ` ^A 134 +\defineaccent ' ^A 135 +\defineaccent ~ ^A 136 +\defineaccent h ^A 137 +\defineaccent d ^A 138 +\defineaccent u A 139 +\defineaccent ` uA 140 +\defineaccent ' uA 141 +\defineaccent ~ uA 142 +\defineaccent h uA 143 +\defineaccent d uA 144 +\defineaccent ` E 145 +\defineaccent ' E 146 +\defineaccent ~ E 147 +\defineaccent h E 148 +\defineaccent d E 149 +\defineaccent ^ E 150 +\defineaccent ` ^E 151 +\defineaccent ' ^E 152 +\defineaccent ~ ^E 153 +\defineaccent h ^E 154 +\defineaccent d ^E 155 +\defineaccent ` I 156 +\defineaccent ' I 157 +\defineaccent ~ I 158 +\defineaccent h I 159 +\defineaccent d I 192 +\defineaccent ` O 193 +\defineaccent ' O 194 +\defineaccent ~ O 195 +\defineaccent h O 196 +\defineaccent d O 197 +\defineaccent ^ O 198 +\defineaccent ` ^O 199 +\defineaccent ' ^O 200 +\defineaccent ~ ^O 201 +\defineaccent h ^O 202 +\defineaccent d ^O 203 +\defineaccent h O 204 +\defineaccent ` hO 205 +\defineaccent ' hO 206 +\defineaccent ~ hO 207 +\defineaccent h hO 208 +\defineaccent d hO 209 +\defineaccent ` U 210 +\defineaccent ' U 211 +\defineaccent ~ U 212 +\defineaccent h U 213 +\defineaccent d U 214 +\defineaccent h U 215 +\defineaccent ` hU 216 +\defineaccent ' hU 217 +\defineaccent ~ hU 218 +\defineaccent h hU 219 +\defineaccent d hU 220 +\defineaccent ` Y 221 +\defineaccent ' Y 222 +\defineaccent ~ Y 223 +\defineaccent h Y 26 +\defineaccent d Y 28 +\defineaccent ` a 160 +\defineaccent ' a 161 +\defineaccent ~ a 162 +\defineaccent h a 163 +\defineaccent d a 164 +\defineaccent ^ a 165 +\defineaccent ` ^a 166 +\defineaccent ' ^a 167 +\defineaccent ~ ^a 168 +\defineaccent h ^a 169 +\defineaccent d ^a 170 +\defineaccent u a 171 +\defineaccent ` ua 172 +\defineaccent ' ua 173 +\defineaccent ~ ua 174 +\defineaccent h ua 175 +\defineaccent d ua 176 +\defineaccent ` e 177 +\defineaccent ' e 178 +\defineaccent ~ e 179 +\defineaccent h e 180 +\defineaccent d e 181 +\defineaccent ^ e 182 +\defineaccent ` ^e 183 +\defineaccent ' ^e 184 +\defineaccent ~ ^e 185 +\defineaccent h ^e 186 +\defineaccent d ^e 187 +\defineaccent ` i 188 +\defineaccent ' i 189 +\defineaccent ~ i 190 +\defineaccent h i 191 +\defineaccent d i 224 +\defineaccent ` o 225 +\defineaccent ' o 226 +\defineaccent ~ o 227 +\defineaccent h o 228 +\defineaccent d o 229 +\defineaccent ^ o 230 +\defineaccent ` ^o 231 +\defineaccent ' ^o 232 +\defineaccent ~ ^o 233 +\defineaccent h ^o 234 +\defineaccent d ^o 235 +\defineaccent h o 236 +\defineaccent ` ho 237 +\defineaccent ' ho 238 +\defineaccent ~ ho 239 +\defineaccent h ho 240 +\defineaccent d ho 241 +\defineaccent ` u 242 +\defineaccent ' u 243 +\defineaccent ~ u 244 +\defineaccent h u 245 +\defineaccent d u 246 +\defineaccent h u 247 +\defineaccent ` hu 248 +\defineaccent ' hu 249 +\defineaccent ~ hu 250 +\defineaccent h hu 251 +\defineaccent d hu 252 +\defineaccent ` y 253 +\defineaccent ' y 254 +\defineaccent ~ y 255 +\defineaccent h y 27 +\defineaccent d y 29 + +\stopencoding + +\endinput + +% \startencoding [x5] +% +% \definecharacter aa {\xfiveencodedaa} +% \definecharacter AA {\xfiveencodedAA} +% +% \stopencoding +% +% \def\xfiveencodedaa% +% {\accent23a} +% +% \def\xfiveencodedAA% +% {\leavevmode +% \setbox\zerocount\hbox{h}% +% \dimen@\ht\zerocount +% \advance\dimen@ -1ex +% \rlap{\raise.67\dimen@\hbox{\char23}}A} + +% \quotesinglbase 13 +% \guilsinglleft 14 +% \guilsinglright 15 +% \textquotedblleft 16 +% \textquotedblright 17 +% \quotedblbase 18 +% \guillemotleft 19 +% \guillemotright 20 +% \textendash 21 +% \textemdash 22 +% \textcompwordmark 23 +% \textperthousand \% \char 24 +% \textpertenthousand \%\char 24\char 24 +% \textvisiblespace 32 +% \textquotedbl `\" +% \textdollar `\$ +% \textquoteright `\' +% \textless `\< +% \textgreater `\> +% \textbackslash `\ +% \textasciicircum `\^ +% \textunderscore 95 +% \textquoteleft `\` +% \textbraceleft `\{ +% \textbar `\| +% \textbraceright `\} +% \textasciitilde `\~ diff --git a/tex/context/base/filt-bas.mkii b/tex/context/base/filt-bas.mkii new file mode 100644 index 000000000..ca3bc3d70 --- /dev/null +++ b/tex/context/base/filt-bas.mkii @@ -0,0 +1,63 @@ +%D \module +%D [ file=filt-bas, +%D version=2000.09.19, +%D title=\CONTEXT\ Filter Macros, +%D subtitle=A Base Collection, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% BEWARE: THIS IS A TEST MODULE, NAMES MAY CHANGE! + +\definefiltersynonym [utf8 to unicode16] [inutf8] + +\definefiltersynonym [persian fix] [FarsiToArabic] +\definefiltersynonym [arabic analysis] [uni2cuni] +\definefiltersynonym [arabic glyphs] [cuni2oar] + +\definefiltersequence + [farsi] + [utf8 to unicode16, + persian fix, + arabic analysis, + arabic glyphs] + +\definefiltersynonym [basic context analysis step1] [bcaa-1] +\definefiltersynonym [basic context analysis step2] [bcaa-2] +\definefiltersynonym [basic context analysis step3] [bcaa-3] +\definefiltersynonym [farsi processing for uomarab] [uomarab-farsi] + +\definefiltersynonym [basic presentation forms to sf] [bpftosf] + +\definefiltersynonym [omega persian fix] [FarsiToArabic] +\definefiltersynonym [omega arabic analysis] [uni2cuni] +\definefiltersynonym [omega arabic glyphs] [cuni2oar] + +\definefiltersequence + [farsi-1] + [utf8 to unicode16, + omega persian fix, + omega arabic analysis, + omega arabic glyphs] + +\definefiltersequence + [farsi-2] + [utf8 to unicode16, + basic context analysis step1, + basic context analysis step2, + basic context analysis step3, + farsi processing for uomarab] + +\definefiltersequence + [farsi-3] + [utf8 to unicode16, + basic context analysis step1, + basic context analysis step2, + basic context analysis step3, + basic presentation forms to sf] + +\endinput diff --git a/tex/context/base/filt-ini.mkii b/tex/context/base/filt-ini.mkii new file mode 100644 index 000000000..6e1a16e9a --- /dev/null +++ b/tex/context/base/filt-ini.mkii @@ -0,0 +1,121 @@ +%D \module +%D [ file=filt-ini, +%D version=2000.09.19, +%D title=\CONTEXT\ Filter 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 Filter Macros / Initialization} + +% \ifx\OmegaVersion\undefined + +% \let\definefiltersynonym \gobbledoubleempty +% \let\definefiltersequence \gobbledoubleempty +% \unexpanded\def\usefiltersequence {\gobblesingleempty} +% \let\usefilter \gobblesingleempty +% \let\truefiltername \gobbleoneargument + +% \expandafter \endinput +% \fi + +\unprotect + +%D The real work starts here. + +% We need the {\??ot::#1} check because otherwise aleph will crash. Taco's +% torture test: +% +% \ocp\ArabicContext = contextual +% +% \dorecurse {5000} { +% \message{[\recurselevel]} +% \ocplist\Arabic=\addbeforeocplist 1 \ArabicContext \nullocplist +% } + +%D \macros +%D {definefiltersynonym} + +\def\definefiltersynonym + {\dodoubleargument\dodefinefiltersynonym} + +\def\dodefinefiltersynonym[#1][#2]% + {\setvalue{\??or#1}{#2}} + +%D \macros +%D {truefiltername} + +\def\truefiltername#1% + {\ifundefined{\??or#1}#1\else\truefiltername{\getvalue{\??or#1}}\fi} + +%D \macros +%D {definefiltersequence} + +\def\definefiltersequence + {\dodoubleargument\dodefinefiltersequence} + +% \def\dodefinefiltersequence[#1][#2]% +% {\setvalue{\??ot#1}{#2}} + +\def\dodefinefiltersequence[#1][#2]% + {\setxvalue{\??ot#1}{#2}% + \letgvalue{\??ot::#1}\v!stop} + +%D \macros +%D {usefiltersequence} +%D + +\def\magicocpnumber{1} + +% one can do: +% +% \definefiltersequence +% [farsi] +% [utf8 to unicode16=>5, +% persian fix, +% arabic analysis=>3, +% arabic glyphs] +% +% so, => is used to signal a priority + +\def\dodousefiltersequence#1% + {\expandafter\ocp\csname\??or:#1\endcsname=\truefiltername{#1}\relax + \splitstring#1\at=>\to\!!stringa\and\!!stringb + \edef\!!stringb{\number\ifx\!!stringb\empty\magicocpnumber\else\!!stringb\fi}% + \appendetoks + \noexpand\addbeforeocplist + \!!stringb\space + \expandafter\noexpand\csname\??or:\!!stringa\endcsname + \to \scratchtoks} + +\unexpanded\def\usefiltersequence[#1]% + {\doifdefined{\??ot::#1}% + {\doifvalue{\??ot::#1}\v!stop + {\scratchtoks\emptytoks + \expanded{\processcommalist[\getvalue{\??ot#1}]}\dodousefiltersequence + \expanded{\global\ocplist\csname\??ot:#1\endcsname=\the\scratchtoks}\nullocplist + \letgvalue{\??ot::#1}\v!start}% + \expanded{\pushocplist\csname\??ot:#1\endcsname}\relax}} + +%D \macros +%D {usefilter} + +\def\dousefilter#1% + {\doifundefined{\c!file\f!filterprefix#1}% + {\letvalue{\c!file\f!filterprefix#1}\empty + \makeshortfilename[\truefilename{\f!filterprefix#1}]% + \startreadingfile + \readsysfile{\shortfilename.mkii} + {\showmessage\m!filters1{#1}} + {\showmessage\m!filters2{#1}}% + \stopreadingfile}} + +\def\usefilter[#1]% + {\processcommalist[#1]\dousefilter} + +\protect \endinput diff --git a/tex/context/base/font-afm.lua b/tex/context/base/font-afm.lua new file mode 100644 index 000000000..87dec59c6 --- /dev/null +++ b/tex/context/base/font-afm.lua @@ -0,0 +1,855 @@ +if not modules then modules = { } end modules ['font-afm'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--[[ldx-- +<p>Some code may look a bit obscure but this has to do with the +fact that we also use this code for testing and much code evolved +in the transition from <l n='tfm'/> to <l n='afm'/> to <l +n='otf'/>.</p> + +<p>The following code still has traces of intermediate font support +where we handles font encodings. Eventually font encoding goes +away.</p> +--ldx]]-- + +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, gsub = string.format, string.match, string.gmatch, string.lower, string.gsub +local lpegmatch = lpeg.match +local abs = math.abs + +fonts = fonts or { } +fonts.afm = fonts.afm or { } + +local afm = fonts.afm +local tfm = fonts.tfm + +afm.version = 1.402 -- 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 = { } +afm.features.list = { } +afm.features.default = { } +afm.cache = containers.define("fonts", "afm", afm.version, true) + +--[[ldx-- +<p>We start with the basic reader which we give a name similar to the +built in <l n='tfm'/> and <l n='otf'/> reader.</p> +--ldx]]-- + +--~ Comment FONTIDENTIFIER LMMATHSYMBOLS10 +--~ Comment CODINGSCHEME TEX MATH SYMBOLS +--~ Comment DESIGNSIZE 10.0 pt +--~ Comment CHECKSUM O 4261307036 +--~ Comment SPACE 0 plus 0 minus 0 +--~ Comment QUAD 1000 +--~ Comment EXTRASPACE 0 +--~ Comment NUM 676.508 393.732 443.731 +--~ Comment DENOM 685.951 344.841 +--~ Comment SUP 412.892 362.892 288.889 +--~ Comment SUB 150 247.217 +--~ Comment SUPDROP 386.108 +--~ Comment SUBDROP 50 +--~ Comment DELIM 2390 1010 +--~ Comment AXISHEIGHT 250 + +local c = lpeg.P("Comment") +local s = lpeg.S(" \t") +local l = lpeg.S("\n\r") +local w = lpeg.C((1 - l)^1) +local n = lpeg.C((lpeg.R("09") + lpeg.S("."))^1) / tonumber * s^0 + +local fd = { } + +local pattern = ( c * s^1 * ( + ("CODINGSCHEME" * s^1 * w ) / function(a) end + + ("DESIGNSIZE" * s^1 * n * w ) / function(a) fd[ 1] = a end + + ("CHECKSUM" * s^1 * n * w ) / function(a) fd[ 2] = a end + + ("SPACE" * s^1 * n * "plus" * n * "minus" * n) / function(a,b,c) fd[ 3], fd[ 4], fd[ 5] = a, b, c end + + ("QUAD" * s^1 * n ) / function(a) fd[ 6] = a end + + ("EXTRASPACE" * s^1 * n ) / function(a) fd[ 7] = a end + + ("NUM" * s^1 * n * n * n ) / function(a,b,c) fd[ 8], fd[ 9], fd[10] = a, b, c end + + ("DENOM" * s^1 * n * n ) / function(a,b ) fd[11], fd[12] = a, b end + + ("SUP" * s^1 * n * n * n ) / function(a,b,c) fd[13], fd[14], fd[15] = a, b, c end + + ("SUB" * s^1 * n * n ) / function(a,b) fd[16], fd[17] = a, b end + + ("SUPDROP" * s^1 * n ) / function(a) fd[18] = a end + + ("SUBDROP" * s^1 * n ) / function(a) fd[19] = a end + + ("DELIM" * s^1 * n * n ) / function(a,b) fd[20], fd[21] = a, b end + + ("AXISHEIGHT" * s^1 * n ) / function(a) fd[22] = a end + + (1-l)^0 +) + (1-c)^1)^0 + +local function scan_comment(str) + fd = { } + lpegmatch(pattern,str) + return fd +end + +-- On a rainy day I will rewrite this in lpeg ... + +local keys = { } + +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 = 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 gmatch(charmetrics,"([%a]+) +(.-) *;") do + if k == 'C' then + if str ~= "" then characters[str] = chr end + chr = { } + str = "" + v = tonumber(v) + if v < 0 then + ind = ind + 1 + else + ind = v + end + chr.index = ind + elseif k == 'WX' then + chr.width = v + elseif k == 'N' then + str = v + elseif k == 'B' then + local llx, lly, urx, ury = match(v,"^ *(.-) +(.-) +(.-) +(.-)$") + chr.boundingbox = { tonumber(llx), tonumber(lly), tonumber(urx), tonumber(ury) } + elseif k == 'L' then + local plus, becomes = match(v,"^(.-) +(.-)$") + if not chr.ligatures then chr.ligatures = { } end + chr.ligatures[plus] = becomes + end + end + if str ~= "" then + characters[str] = chr + end +end + +local function get_kernpairs(data,kernpairs) + local characters = data.characters + 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 + chr.kerns[two] = tonumber(value) + end + end +end + +local function get_variables(data,fontmetrics) + 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 pfbfile = file.replacesuffix(filename,"pfb") + local pfbname = resolvers.find_file(pfbfile,"pfb") or "" + if pfbname == "" then + pfbname = resolvers.find_file(file.basename(pfbfile),"pfb") or "" + end + if pfbname ~= "" then + data.luatex.filename = pfbname + local pfbblob = fontloader.open(pfbname) + if pfbblob then + local characters = data.characters + local pfbdata = fontloader.to_table(pfbblob) + --~ print(table.serialize(pfbdata)) + if pfbdata then + local glyphs = pfbdata.glyphs + if glyphs 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 next, glyphs do + local name = glyph.name + if name then + local char = characters[name] + if char 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_loading then + logs.report("load afm","no glyph data in pfb file %s",pfbname) + end + elseif trace_loading then + logs.report("load afm","no data in pfb file %s",pfbname) + end + fontloader.close(pfbblob) + elseif trace_loading then + logs.report("load afm","invalid pfb file %s",pfbname) + end + 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 = resolvers.loadbinfile(filename) -- has logging +-- local ok, afmblob = true, file.readdata(filename) + if ok and afmblob then + local data = { + characters = { }, + metadata = { + version = version or '0', -- hm + filename = file.removesuffix(file.basename(filename)) + } + } + afmblob = gsub(afmblob,"StartCharMetrics(.-)EndCharMetrics", function(charmetrics) + if trace_loading then + logs.report("load afm","loading char metrics") + end + get_charmetrics(data,charmetrics,vector) + return "" + end) + afmblob = gsub(afmblob,"StartKernPairs(.-)EndKernPairs", function(kernpairs) + if trace_loading then + logs.report("load afm","loading kern pairs") + end + get_kernpairs(data,kernpairs) + return "" + end) + afmblob = gsub(afmblob,"StartFontMetrics%s+([%d%.]+)(.-)EndFontMetrics", function(version,fontmetrics) + if trace_loading then + logs.report("load afm","loading variables") + end + data.afmversion = version + get_variables(data,fontmetrics) + data.fontdimens = scan_comment(fontmetrics) -- todo: all lpeg, no time now + return "" + end) + data.luatex = { } + get_indexes(data,filename) + return data + else + if trace_loading then + logs.report("load afm","no valid afm file %s",filename) + end + return nil + end +end + +--[[ldx-- +<p>We cache files. Caching is taken care of in the loader. We cheat a bit +by adding ligatures and kern information to the afm derived data. That +way we can set them faster when defining a font.</p> +--ldx]]-- + +function afm.load(filename) + -- 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", "add tounicode data") + fonts.map.add_to_unicode(data,filename) + data.size = size + data.verbose = fonts.verbose + 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 +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 next, data.characters do + local code = unicodevector[name] -- or characters.name_to_unicode[name] + if not code then + 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 U+%04X for unknown glyph name %s", code, name) + end + end + local index = blob.index + unicodes[name] = code + indices[code] = index + glyphs[index] = blob + names[name] = index + blob.name = name + if verbose then + local bu = blob.unicode + if not bu then + blob.unicode = code + elseif type(bu) == "table" then + bu[#bu+1] = code + else + blob.unicode = { bu, code } + end + else + blob.index = nil + end + end + 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-- +<p>These helpers extend the basic table with extra ligatures, texligatures +and extra kerns. This saves quite some lookups later.</p> +--ldx]]-- + +function afm.add_ligatures(afmdata,ligatures) + 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 next, v do + two, three = b[1], b[2] + if two and three and names[two] and names[three] then + local ol = one[ligatures] + if ol then + if not ol[two] then -- was one.ligatures ... bug + ol[two] = three + end + else + one[ligatures] = { [two] = three } + end + end + end + end + end +end + +--[[ldx-- +<p>We keep the extra kerns in separate kerning tables so that we can use +them selectively.</p> +--ldx]]-- + +function afm.add_kerns(afmdata) + local glyphs = afmdata.glyphs + local names = afmdata.luatex.names + local uncomposed = characters.uncomposed + local function do_it_left(what) + 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(extrakerns) then + glyph.extrakerns = extrakerns + end + end + end + end + local function do_it_copy(what) + for complex, simple in next, uncomposed[what] do + local c = glyphs[names[complex]] + if c then -- optional + local s = glyphs[names[simple]] + 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 + end + -- add complex with values of simplified when present + do_it_left("left") + do_it_left("both") + -- copy kerns from simple char to complex char unless set + do_it_copy("both") + do_it_copy("right") +end + +--[[ldx-- +<p>The copying routine looks messy (and is indeed a bit messy).</p> +--ldx]]-- + +-- once we have otf sorted out (new format) we can try to make the afm +-- cache similar to it (similar tables) + +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 next, data.glyphs do + local bb = glyph.boundingbox + 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 + 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 +end + +fonts.formats.afm = "type1" +fonts.formats.pfb = "type1" + +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 = { }, { }, { } + -- todo : merge into tfm + for u, i in next, indices do + local d = glyphs[i] + characters[u] = { } + descriptions[u] = d + end + local filename = fonts.tfm.checked_filename(luatex) -- was metadata.filename + local fontname = metadata.fontname or metadata.fullname + local fullname = metadata.fullname or metadata.fontname + local endash, emdash, space, spaceunits = unicodes['space'], unicodes['emdash'], "space", 500 + -- same as otf + if metadata.isfixedpitch then + if descriptions[endash] then + spaceunits, spacer = descriptions[endash].width, "space" + end + if not spaceunits and descriptions[emdash] then + spaceunits, spacer = descriptions[emdash].width, "emdash" + end + if not spaceunits and metadata.charwidth then + spaceunits, spacer = metadata.charwidth, "charwidth" + end + else + if descriptions[endash] then + spaceunits, spacer = descriptions[endash].width, "space" + end + if not spaceunits and metadata.charwidth then + spaceunits, spacer = metadata.charwidth, "charwidth" + end + end + spaceunits = tonumber(spaceunits) + if spaceunits < 200 then + -- todo: warning + end + -- + parameters.slant = 0 + parameters.space = spaceunits + parameters.space_stretch = 500 + parameters.space_shrink = 333 + parameters.x_height = 400 + parameters.quad = 1000 + local italicangle = data.metadata.italicangle + if italicangle then + 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 afm.syncspace then + parameters.space_stretch = spaceunits/2 + parameters.space_shrink = spaceunits/3 + end + 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'] + if x then + local x = descriptions[x] + if x then + parameters.x_height = x.height + end + end + -- + end + local fd = data.fontdimens + if fd and fd[8] and fd[9] and fd[10] then -- math + for k,v in next, fd do + parameters[k] = v + end + end + -- + if next(characters) then + return { + characters = characters, + parameters = parameters, + descriptions = descriptions, + indices = indices, + unicodes = unicodes, + luatex = luatex, + encodingbytes = 2, + filename = filename, + fontname = fontname, + fullname = fullname, + psname = fullname, -- in otf: tfm.fontname or tfm.fullname + name = filename or fullname or fontname, + format = fonts.fontformat(filename,"type1"), + type = 'real', + units = 1000, + direction = 0, + boundarychar_label = 0, + boundarychar = 65536, + --~ false_boundarychar = 65536, -- produces invalid tfm in luatex + designsize = (metadata.designsize or 10)*65536, + spacer = spacer, + ascender = abs(metadata.ascender or 0), + descender = abs(metadata.descender or 0), + italicangle = italicangle, + } + end + end + end + return nil +end + +--[[ldx-- +<p>Originally we had features kind of hard coded for <l n='afm'/> +files but since I expect to support more font formats, I decided +to treat this fontformat like any other and handle features in a +more configurable way.</p> +--ldx]]-- + +function afm.features.register(name,default) + afm.features.list[#afm.features.list+1] = name + afm.features.default[name] = default +end + +function afm.set_features(tfmdata) + local shared = tfmdata.shared + local afmdata = shared.afmdata + local features = shared.features + if features and next(features) then + local mode = tfmdata.mode or fonts.mode + 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 i=1,#list do + local f = list[i] + local value = features[f] + 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 + fiafm[f](tfmdata,value) + mode = tfmdata.mode or fonts.mode + fiafm = initializers[mode].afm + end + end + end + end + end + local fm = fonts.methods[mode] + 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 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 + sp[#sp+1] = fmafm[f] + end + end + end + end + end + end + end +end + +function afm.check_features(specification) + local features, done = fonts.define.check(specification.features.normal,afm.features.default) + if done then + specification.features.normal = features + tfm.hash_instance(specification,true) + end +end + +function afm.afm_to_tfm(specification) + local afmname = specification.filename or specification.name + if 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 = resolvers.findbinfile(afmname,"ofm") or "" + if tfmname ~= "" then + if trace_loading then + logs.report("load afm","fallback from afm to tfm for %s",afmname) + end + afmname = "" + end + end + if afmname == "" then + return nil + else + afm.check_features(specification) + specification = fonts.define.resolve(specification) -- new, was forgotten + local features = specification.features.normal + local cache_id = specification.hash + local tfmdata = containers.read(tfm.cache(), cache_id) -- cache with features applied + if not tfmdata then + local afmdata = afm.load(afmname) + if afmdata and next(afmdata) then + afm.add_dimensions(afmdata) + tfmdata = afm.copy_to_tfm(afmdata) + if tfmdata and next(tfmdata) then + tfmdata.shared = tfmdata.shared or { } + tfmdata.unique = tfmdata.unique or { } + tfmdata.shared.afmdata = afmdata + tfmdata.shared.features = features + afm.set_features(tfmdata) + end + 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) + end + return tfmdata + end +end + +--[[ldx-- +<p>As soon as we could intercept the <l n='tfm'/> reader, I implemented an +<l n='afm'/> reader. Since traditional <l n='pdftex'/> could use <l n='opentype'/> +fonts with <l n='afm'/> companions, the following method also could handle +those cases, but now that we can handle <l n='opentype'/> directly we no longer +need this features.</p> +--ldx]]-- + +tfm.default_encoding = 'unicode' + +function tfm.set_normal_feature(specification,name,value) + if specification and name then + specification.features = specification.features or { } + specification.features.normal = specification.features.normal or { } + specification.features.normal[name] = value + end +end + +function tfm.read_from_afm(specification) + local tfmtable = afm.afm_to_tfm(specification) + if tfmtable then + tfmtable.name = specification.name + tfmtable = tfm.scale(tfmtable, specification.size, specification.relativeid) + local afmdata = tfmtable.shared.afmdata +--~ local filename = afmdata and afmdata.luatex and afmdata.luatex.filename +--~ if filename then +--~ tfmtable.encodingbytes = 2 +--~ tfmtable.filename = resolvers.findbinfile(filename,"") or filename +--~ tfmtable.fontname = afmdata.metadata.fontname or afmdata.metadata.fullname +--~ tfmtable.fullname = afmdata.metadata.fullname or afmdata.metadata.fontname +--~ tfmtable.format = 'type1' +--~ tfmtable.name = afmdata.luatex.filename or tfmtable.fullname +--~ end + if fonts.dontembed[filename] then + tfmtable.file = nil -- or filename ? + end + fonts.logger.save(tfmtable,'afm',specification) + end + return tfmtable +end + +--[[ldx-- +<p>Here comes the implementation of a few features. We only implement +those that make sense for this format.</p> +--ldx]]-- + +function afm.features.prepare_ligatures(tfmdata,ligatures,value) + if value then + local afmdata = tfmdata.shared.afmdata + local luatex = afmdata.luatex + local unicodes = luatex.unicodes + local descriptions = tfmdata.descriptions + for u, chr in next, tfmdata.characters do + local d = descriptions[u] + local l = d[ligatures] + if l then + local ligatures = chr.ligatures + if not ligatures then + ligatures = { } + chr.ligatures = ligatures + end + for k, v in next, l do + local uk, uv = unicodes[k], unicodes[v] + if uk and uv then + ligatures[uk] = { + char = uv, + type = 0 + } + end + end + end + end + end +end + +function afm.features.prepare_kerns(tfmdata,kerns,value) + if value then + local afmdata = tfmdata.shared.afmdata + local luatex = afmdata.luatex + local unicodes = luatex.unicodes + local descriptions = tfmdata.descriptions + for u, chr in next, tfmdata.characters do + local d = descriptions[u] + local newkerns = d[kerns] + if newkerns then + local kerns = chr.kerns + if not kerns then + kerns = { } + chr.kerns = kerns + end + for k,v in next, newkerns do + local uk = unicodes[k] + if uk then + kerns[uk] = v + end + end + end + end + end +end + +-- hm, register? + +function fonts.initializers.base.afm.ligatures (tfmdata,value) afm.features.prepare_ligatures(tfmdata,'ligatures', value) end +function fonts.initializers.base.afm.texligatures(tfmdata,value) afm.features.prepare_ligatures(tfmdata,'texligatures',value) end +function fonts.initializers.base.afm.kerns (tfmdata,value) afm.features.prepare_kerns (tfmdata,'kerns', value) end +function fonts.initializers.base.afm.extrakerns (tfmdata,value) afm.features.prepare_kerns (tfmdata,'extrakerns', value) end + +afm.features.register('liga',true) +afm.features.register('kerns',true) +afm.features.register('extrakerns') -- needed? + +fonts.initializers.node.afm.ligatures = fonts.initializers.base.afm.ligatures +fonts.initializers.node.afm.texligatures = fonts.initializers.base.afm.texligatures +fonts.initializers.node.afm.kerns = fonts.initializers.base.afm.kerns +fonts.initializers.node.afm.extrakerns = fonts.initializers.base.afm.extrakerns + +fonts.initializers.base.afm.liga = fonts.initializers.base.afm.ligatures +fonts.initializers.node.afm.liga = fonts.initializers.base.afm.ligatures +fonts.initializers.base.afm.tlig = fonts.initializers.base.afm.texligatures +fonts.initializers.node.afm.tlig = fonts.initializers.base.afm.texligatures + +fonts.initializers.base.afm.trep = tfm.replacements +fonts.initializers.node.afm.trep = tfm.replacements + +afm.features.register('tlig',true) -- todo: also proper features for afm +afm.features.register('trep',true) -- todo: also proper features for afm + +-- tfm features + +fonts.initializers.base.afm.equaldigits = fonts.initializers.common.equaldigits +fonts.initializers.node.afm.equaldigits = fonts.initializers.common.equaldigits +fonts.initializers.base.afm.lineheight = fonts.initializers.common.lineheight +fonts.initializers.node.afm.lineheight = fonts.initializers.common.lineheight + +-- vf features + +fonts.initializers.base.afm.compose = fonts.initializers.common.compose +fonts.initializers.node.afm.compose = fonts.initializers.common.compose + +-- afm specific, encodings ...kind of obsolete + +afm.features.register('encoding') + +fonts.initializers.base.afm.encoding = fonts.initializers.common.encoding +fonts.initializers.node.afm.encoding = fonts.initializers.common.encoding + +-- todo: oldstyle smallcaps as features for afm files (use with care) + +fonts.initializers.base.afm.onum = fonts.initializers.common.oldstyle +fonts.initializers.base.afm.smcp = fonts.initializers.common.smallcaps +fonts.initializers.base.afm.fkcp = fonts.initializers.common.fakecaps + +afm.features.register('onum',false) +afm.features.register('smcp',false) +afm.features.register('fkcp',false) + diff --git a/tex/context/base/font-agl.lua b/tex/context/base/font-agl.lua new file mode 100644 index 000000000..8a087b123 --- /dev/null +++ b/tex/context/base/font-agl.lua @@ -0,0 +1,3695 @@ +if not modules then modules = { } end modules ['font-map'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "derived from http://www.adobe.com/devnet/opentype/archives/glyphlist.txt", + comment = "Adobe Glyph List, version 2.0, September 20, 2002", +} + +fonts = fonts or { } +fonts.map = fonts.map or { } + +fonts.map.unicode_to_agl = { + "controlSTX", + "controlSOT", + "controlETX", + "controlEOT", + "controlENQ", + "controlACK", + "controlBEL", + "controlBS", + "controlHT", + "controlLF", + "controlVT", + "controlFF", + "controlCR", + "controlSO", + "controlSI", + "controlDLE", + "controlDC1", + "controlDC2", + "controlDC3", + "controlDC4", + "controlNAK", + "controlSYN", + "controlETB", + "controlCAN", + "controlEM", + "controlSUB", + "controlESC", + "controlFS", + "controlGS", + "controlRS", + "controlUS", + "spacehackarabic", + "exclam", + "quotedbl", + "numbersign", + "dollar", + "percent", + "ampersand", + "quotesingle", + "parenleft", + "parenright", + "asterisk", + "plus", + "comma", + "hyphen", + "period", + "slash", + "zero", + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "colon", + "semicolon", + "less", + "equal", + "greater", + "question", + "at", + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + "bracketleft", + "backslash", + "bracketright", + "asciicircum", + "underscore", + "grave", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "braceleft", + "verticalbar", + "braceright", + "asciitilde", + "controlDEL", + [0x00A0] = "nonbreakingspace", + [0x00A1] = "exclamdown", + [0x00A2] = "cent", + [0x00A3] = "sterling", + [0x00A4] = "currency", + [0x00A5] = "yen", + [0x00A6] = "brokenbar", + [0x00A7] = "section", + [0x00A8] = "dieresis", + [0x00A9] = "copyright", + [0x00AA] = "ordfeminine", + [0x00AB] = "guillemotleft", + [0x00AC] = "logicalnot", + [0x00AD] = "softhyphen", + [0x00AE] = "registered", + [0x00AF] = "overscore", + [0x00B0] = "degree", + [0x00B1] = "plusminus", + [0x00B2] = "twosuperior", + [0x00B3] = "threesuperior", + [0x00B4] = "acute", + [0x00B5] = "mu1", + [0x00B6] = "paragraph", + [0x00B7] = "periodcentered", + [0x00B8] = "cedilla", + [0x00B9] = "onesuperior", + [0x00BA] = "ordmasculine", + [0x00BB] = "guillemotright", + [0x00BC] = "onequarter", + [0x00BD] = "onehalf", + [0x00BE] = "threequarters", + [0x00BF] = "questiondown", + [0x00C0] = "Agrave", + [0x00C1] = "Aacute", + [0x00C2] = "Acircumflex", + [0x00C3] = "Atilde", + [0x00C4] = "Adieresis", + [0x00C5] = "Aring", + [0x00C6] = "AE", + [0x00C7] = "Ccedilla", + [0x00C8] = "Egrave", + [0x00C9] = "Eacute", + [0x00CA] = "Ecircumflex", + [0x00CB] = "Edieresis", + [0x00CC] = "Igrave", + [0x00CD] = "Iacute", + [0x00CE] = "Icircumflex", + [0x00CF] = "Idieresis", + [0x00D0] = "Eth", + [0x00D1] = "Ntilde", + [0x00D2] = "Ograve", + [0x00D3] = "Oacute", + [0x00D4] = "Ocircumflex", + [0x00D5] = "Otilde", + [0x00D6] = "Odieresis", + [0x00D7] = "multiply", + [0x00D8] = "Oslash", + [0x00D9] = "Ugrave", + [0x00DA] = "Uacute", + [0x00DB] = "Ucircumflex", + [0x00DC] = "Udieresis", + [0x00DD] = "Yacute", + [0x00DE] = "Thorn", + [0x00DF] = "germandbls", + [0x00E0] = "agrave", + [0x00E1] = "aacute", + [0x00E2] = "acircumflex", + [0x00E3] = "atilde", + [0x00E4] = "adieresis", + [0x00E5] = "aring", + [0x00E6] = "ae", + [0x00E7] = "ccedilla", + [0x00E8] = "egrave", + [0x00E9] = "eacute", + [0x00EA] = "ecircumflex", + [0x00EB] = "edieresis", + [0x00EC] = "igrave", + [0x00ED] = "iacute", + [0x00EE] = "icircumflex", + [0x00EF] = "idieresis", + [0x00F0] = "eth", + [0x00F1] = "ntilde", + [0x00F2] = "ograve", + [0x00F3] = "oacute", + [0x00F4] = "ocircumflex", + [0x00F5] = "otilde", + [0x00F6] = "odieresis", + [0x00F7] = "divide", + [0x00F8] = "oslash", + [0x00F9] = "ugrave", + [0x00FA] = "uacute", + [0x00FB] = "ucircumflex", + [0x00FC] = "udieresis", + [0x00FD] = "yacute", + [0x00FE] = "thorn", + [0x00FF] = "ydieresis", + [0x0100] = "Amacron", + [0x0101] = "amacron", + [0x0102] = "Abreve", + [0x0103] = "abreve", + [0x0104] = "Aogonek", + [0x0105] = "aogonek", + [0x0106] = "Cacute", + [0x0107] = "cacute", + [0x0108] = "Ccircumflex", + [0x0109] = "ccircumflex", + [0x010A] = "Cdotaccent", + [0x010B] = "cdotaccent", + [0x010C] = "Ccaron", + [0x010D] = "ccaron", + [0x010E] = "Dcaron", + [0x010F] = "dcaron", + [0x0110] = "Dslash", + [0x0111] = "dmacron", + [0x0112] = "Emacron", + [0x0113] = "emacron", + [0x0114] = "Ebreve", + [0x0115] = "ebreve", + [0x0116] = "Edotaccent", + [0x0117] = "edotaccent", + [0x0118] = "Eogonek", + [0x0119] = "eogonek", + [0x011A] = "Ecaron", + [0x011B] = "ecaron", + [0x011C] = "Gcircumflex", + [0x011D] = "gcircumflex", + [0x011E] = "Gbreve", + [0x011F] = "gbreve", + [0x0120] = "Gdotaccent", + [0x0121] = "gdotaccent", + [0x0122] = "Gcommaaccent", + [0x0123] = "gcommaaccent", + [0x0124] = "Hcircumflex", + [0x0125] = "hcircumflex", + [0x0126] = "Hbar", + [0x0127] = "hbar", + [0x0128] = "Itilde", + [0x0129] = "itilde", + [0x012A] = "Imacron", + [0x012B] = "imacron", + [0x012C] = "Ibreve", + [0x012D] = "ibreve", + [0x012E] = "Iogonek", + [0x012F] = "iogonek", + [0x0130] = "Idotaccent", + [0x0131] = "dotlessi", + [0x0132] = "IJ", + [0x0133] = "ij", + [0x0134] = "Jcircumflex", + [0x0135] = "jcircumflex", + [0x0136] = "Kcommaaccent", + [0x0137] = "kcommaaccent", + [0x0138] = "kgreenlandic", + [0x0139] = "Lacute", + [0x013A] = "lacute", + [0x013B] = "Lcommaaccent", + [0x013C] = "lcommaaccent", + [0x013D] = "Lcaron", + [0x013E] = "lcaron", + [0x013F] = "Ldotaccent", + [0x0140] = "ldotaccent", + [0x0141] = "Lslash", + [0x0142] = "lslash", + [0x0143] = "Nacute", + [0x0144] = "nacute", + [0x0145] = "Ncommaaccent", + [0x0146] = "ncommaaccent", + [0x0147] = "Ncaron", + [0x0148] = "ncaron", + [0x0149] = "quoterightn", + [0x014A] = "Eng", + [0x014B] = "eng", + [0x014C] = "Omacron", + [0x014D] = "omacron", + [0x014E] = "Obreve", + [0x014F] = "obreve", + [0x0150] = "Ohungarumlaut", + [0x0151] = "ohungarumlaut", + [0x0152] = "OE", + [0x0153] = "oe", + [0x0154] = "Racute", + [0x0155] = "racute", + [0x0156] = "Rcommaaccent", + [0x0157] = "rcommaaccent", + [0x0158] = "Rcaron", + [0x0159] = "rcaron", + [0x015A] = "Sacute", + [0x015B] = "sacute", + [0x015C] = "Scircumflex", + [0x015D] = "scircumflex", + [0x015E] = "Scedilla", + [0x015F] = "scedilla", + [0x0160] = "Scaron", + [0x0161] = "scaron", + [0x0162] = "Tcommaaccent", + [0x0163] = "tcommaaccent", + [0x0164] = "Tcaron", + [0x0165] = "tcaron", + [0x0166] = "Tbar", + [0x0167] = "tbar", + [0x0168] = "Utilde", + [0x0169] = "utilde", + [0x016A] = "Umacron", + [0x016B] = "umacron", + [0x016C] = "Ubreve", + [0x016D] = "ubreve", + [0x016E] = "Uring", + [0x016F] = "uring", + [0x0170] = "Uhungarumlaut", + [0x0171] = "uhungarumlaut", + [0x0172] = "Uogonek", + [0x0173] = "uogonek", + [0x0174] = "Wcircumflex", + [0x0175] = "wcircumflex", + [0x0176] = "Ycircumflex", + [0x0177] = "ycircumflex", + [0x0178] = "Ydieresis", + [0x0179] = "Zacute", + [0x017A] = "zacute", + [0x017B] = "Zdotaccent", + [0x017C] = "zdotaccent", + [0x017D] = "Zcaron", + [0x017E] = "zcaron", + [0x017F] = "slong", + [0x0180] = "bstroke", + [0x0181] = "Bhook", + [0x0182] = "Btopbar", + [0x0183] = "btopbar", + [0x0184] = "Tonesix", + [0x0185] = "tonesix", + [0x0186] = "Oopen", + [0x0187] = "Chook", + [0x0188] = "chook", + [0x0189] = "Dafrican", + [0x018A] = "Dhook", + [0x018B] = "Dtopbar", + [0x018C] = "dtopbar", + [0x018D] = "deltaturned", + [0x018E] = "Ereversed", + [0x018F] = "Schwa", + [0x0190] = "Eopen", + [0x0191] = "Fhook", + [0x0192] = "florin", + [0x0193] = "Ghook", + [0x0194] = "Gammaafrican", + [0x0195] = "hv", + [0x0196] = "Iotaafrican", + [0x0197] = "Istroke", + [0x0198] = "Khook", + [0x0199] = "khook", + [0x019A] = "lbar", + [0x019B] = "lambdastroke", + [0x019C] = "Mturned", + [0x019D] = "Nhookleft", + [0x019E] = "nlegrightlong", + [0x019F] = "Ocenteredtilde", + [0x01A0] = "Ohorn", + [0x01A1] = "ohorn", + [0x01A2] = "Oi", + [0x01A3] = "oi", + [0x01A4] = "Phook", + [0x01A5] = "phook", + [0x01A6] = "yr", + [0x01A7] = "Tonetwo", + [0x01A8] = "tonetwo", + [0x01A9] = "Esh", + [0x01AA] = "eshreversedloop", + [0x01AB] = "tpalatalhook", + [0x01AC] = "Thook", + [0x01AD] = "thook", + [0x01AE] = "Tretroflexhook", + [0x01AF] = "Uhorn", + [0x01B0] = "uhorn", + [0x01B1] = "Upsilonafrican", + [0x01B2] = "Vhook", + [0x01B3] = "Yhook", + [0x01B4] = "yhook", + [0x01B5] = "Zstroke", + [0x01B6] = "zstroke", + [0x01B7] = "Ezh", + [0x01B8] = "Ezhreversed", + [0x01B9] = "ezhreversed", + [0x01BA] = "ezhtail", + [0x01BB] = "twostroke", + [0x01BC] = "Tonefive", + [0x01BD] = "tonefive", + [0x01BE] = "glottalinvertedstroke", + [0x01BF] = "wynn", + [0x01C0] = "clickdental", + [0x01C1] = "clicklateral", + [0x01C2] = "clickalveolar", + [0x01C3] = "clickretroflex", + [0x01C4] = "DZcaron", + [0x01C5] = "Dzcaron", + [0x01C6] = "dzcaron", + [0x01C7] = "LJ", + [0x01C8] = "Lj", + [0x01C9] = "lj", + [0x01CA] = "NJ", + [0x01CB] = "Nj", + [0x01CC] = "nj", + [0x01CD] = "Acaron", + [0x01CE] = "acaron", + [0x01CF] = "Icaron", + [0x01D0] = "icaron", + [0x01D1] = "Ocaron", + [0x01D2] = "ocaron", + [0x01D3] = "Ucaron", + [0x01D4] = "ucaron", + [0x01D5] = "Udieresismacron", + [0x01D6] = "udieresismacron", + [0x01D7] = "Udieresisacute", + [0x01D8] = "udieresisacute", + [0x01D9] = "Udieresiscaron", + [0x01DA] = "udieresiscaron", + [0x01DB] = "Udieresisgrave", + [0x01DC] = "udieresisgrave", + [0x01DD] = "eturned", + [0x01DE] = "Adieresismacron", + [0x01DF] = "adieresismacron", + [0x01E0] = "Adotmacron", + [0x01E1] = "adotmacron", + [0x01E2] = "AEmacron", + [0x01E3] = "aemacron", + [0x01E4] = "Gstroke", + [0x01E5] = "gstroke", + [0x01E6] = "Gcaron", + [0x01E7] = "gcaron", + [0x01E8] = "Kcaron", + [0x01E9] = "kcaron", + [0x01EA] = "Oogonek", + [0x01EB] = "oogonek", + [0x01EC] = "Oogonekmacron", + [0x01ED] = "oogonekmacron", + [0x01EE] = "Ezhcaron", + [0x01EF] = "ezhcaron", + [0x01F0] = "jcaron", + [0x01F1] = "DZ", + [0x01F2] = "Dz", + [0x01F3] = "dz", + [0x01F4] = "Gacute", + [0x01F5] = "gacute", + [0x01FA] = "Aringacute", + [0x01FB] = "aringacute", + [0x01FC] = "AEacute", + [0x01FD] = "aeacute", + [0x01FE] = "Ostrokeacute", + [0x01FF] = "ostrokeacute", + [0x0200] = "Adblgrave", + [0x0201] = "adblgrave", + [0x0202] = "Ainvertedbreve", + [0x0203] = "ainvertedbreve", + [0x0204] = "Edblgrave", + [0x0205] = "edblgrave", + [0x0206] = "Einvertedbreve", + [0x0207] = "einvertedbreve", + [0x0208] = "Idblgrave", + [0x0209] = "idblgrave", + [0x020A] = "Iinvertedbreve", + [0x020B] = "iinvertedbreve", + [0x020C] = "Odblgrave", + [0x020D] = "odblgrave", + [0x020E] = "Oinvertedbreve", + [0x020F] = "oinvertedbreve", + [0x0210] = "Rdblgrave", + [0x0211] = "rdblgrave", + [0x0212] = "Rinvertedbreve", + [0x0213] = "rinvertedbreve", + [0x0214] = "Udblgrave", + [0x0215] = "udblgrave", + [0x0216] = "Uinvertedbreve", + [0x0217] = "uinvertedbreve", + [0x0218] = "Scommaaccent", + [0x0219] = "scommaaccent", + [0x0250] = "aturned", + [0x0251] = "ascript", + [0x0252] = "ascriptturned", + [0x0253] = "bhook", + [0x0254] = "oopen", + [0x0255] = "ccurl", + [0x0256] = "dtail", + [0x0257] = "dhook", + [0x0258] = "ereversed", + [0x0259] = "schwa", + [0x025A] = "schwahook", + [0x025B] = "eopen", + [0x025C] = "eopenreversed", + [0x025D] = "eopenreversedhook", + [0x025E] = "eopenreversedclosed", + [0x025F] = "jdotlessstroke", + [0x0260] = "ghook", + [0x0261] = "gscript", + [0x0263] = "gammalatinsmall", + [0x0264] = "ramshorn", + [0x0265] = "hturned", + [0x0266] = "hhook", + [0x0267] = "henghook", + [0x0268] = "istroke", + [0x0269] = "iotalatin", + [0x026B] = "lmiddletilde", + [0x026C] = "lbelt", + [0x026D] = "lhookretroflex", + [0x026E] = "lezh", + [0x026F] = "mturned", + [0x0270] = "mlonglegturned", + [0x0271] = "mhook", + [0x0272] = "nhookleft", + [0x0273] = "nhookretroflex", + [0x0275] = "obarred", + [0x0277] = "omegalatinclosed", + [0x0278] = "philatin", + [0x0279] = "rturned", + [0x027A] = "rlonglegturned", + [0x027B] = "rhookturned", + [0x027C] = "rlongleg", + [0x027D] = "rhook", + [0x027E] = "rfishhook", + [0x027F] = "rfishhookreversed", + [0x0281] = "Rsmallinverted", + [0x0282] = "shook", + [0x0283] = "esh", + [0x0284] = "dotlessjstrokehook", + [0x0285] = "eshsquatreversed", + [0x0286] = "eshcurl", + [0x0287] = "tturned", + [0x0288] = "tretroflexhook", + [0x0289] = "ubar", + [0x028A] = "upsilonlatin", + [0x028B] = "vhook", + [0x028C] = "vturned", + [0x028D] = "wturned", + [0x028E] = "yturned", + [0x0290] = "zretroflexhook", + [0x0291] = "zcurl", + [0x0292] = "ezh", + [0x0293] = "ezhcurl", + [0x0294] = "glottalstop", + [0x0295] = "glottalstopreversed", + [0x0296] = "glottalstopinverted", + [0x0297] = "cstretched", + [0x0298] = "bilabialclick", + [0x029A] = "eopenclosed", + [0x029B] = "Gsmallhook", + [0x029D] = "jcrossedtail", + [0x029E] = "kturned", + [0x02A0] = "qhook", + [0x02A1] = "glottalstopstroke", + [0x02A2] = "glottalstopstrokereversed", + [0x02A3] = "dzaltone", + [0x02A4] = "dezh", + [0x02A5] = "dzcurl", + [0x02A6] = "ts", + [0x02A7] = "tesh", + [0x02A8] = "tccurl", + [0x02B0] = "hsuperior", + [0x02B1] = "hhooksuperior", + [0x02B2] = "jsuperior", + [0x02B4] = "rturnedsuperior", + [0x02B5] = "rhookturnedsuperior", + [0x02B6] = "Rsmallinvertedsuperior", + [0x02B7] = "wsuperior", + [0x02B8] = "ysuperior", + [0x02B9] = "primemod", + [0x02BA] = "dblprimemod", + [0x02BB] = "commaturnedmod", + [0x02BC] = "apostrophemod", + [0x02BD] = "commareversedmod", + [0x02BE] = "ringhalfright", + [0x02BF] = "ringhalfleft", + [0x02C0] = "glottalstopmod", + [0x02C1] = "glottalstopreversedmod", + [0x02C2] = "arrowheadleftmod", + [0x02C3] = "arrowheadrightmod", + [0x02C4] = "arrowheadupmod", + [0x02C5] = "arrowheaddownmod", + [0x02C6] = "circumflex", + [0x02C7] = "caron", + [0x02C8] = "verticallinemod", + [0x02C9] = "firsttonechinese", + [0x02CA] = "secondtonechinese", + [0x02CB] = "fourthtonechinese", + [0x02CC] = "verticallinelowmod", + [0x02CD] = "macronlowmod", + [0x02CE] = "gravelowmod", + [0x02CF] = "acutelowmod", + [0x02D0] = "colontriangularmod", + [0x02D1] = "colontriangularhalfmod", + [0x02D2] = "ringhalfrightcentered", + [0x02D3] = "ringhalfleftcentered", + [0x02D4] = "uptackmod", + [0x02D5] = "downtackmod", + [0x02D6] = "plusmod", + [0x02D7] = "minusmod", + [0x02D8] = "breve", + [0x02D9] = "dotaccent", + [0x02DA] = "ring", + [0x02DB] = "ogonek", + [0x02DC] = "tilde", + [0x02DD] = "hungarumlaut", + [0x02DE] = "rhotichookmod", + [0x02E0] = "gammasuperior", + [0x02E3] = "xsuperior", + [0x02E4] = "glottalstopreversedsuperior", + [0x02E5] = "tonebarextrahighmod", + [0x02E6] = "tonebarhighmod", + [0x02E7] = "tonebarmidmod", + [0x02E8] = "tonebarlowmod", + [0x02E9] = "tonebarextralowmod", + [0x0300] = "gravecomb", + [0x0301] = "acutecomb", + [0x0302] = "circumflexcmb", + [0x0303] = "tildecomb", + [0x0304] = "macroncmb", + [0x0305] = "overlinecmb", + [0x0306] = "brevecmb", + [0x0307] = "dotaccentcmb", + [0x0308] = "dieresiscmb", + [0x0309] = "hookcmb", + [0x030A] = "ringcmb", + [0x030B] = "hungarumlautcmb", + [0x030C] = "caroncmb", + [0x030D] = "verticallineabovecmb", + [0x030E] = "dblverticallineabovecmb", + [0x030F] = "dblgravecmb", + [0x0310] = "candrabinducmb", + [0x0311] = "breveinvertedcmb", + [0x0312] = "commaturnedabovecmb", + [0x0313] = "commaabovecmb", + [0x0314] = "commareversedabovecmb", + [0x0315] = "commaaboverightcmb", + [0x0316] = "gravebelowcmb", + [0x0317] = "acutebelowcmb", + [0x0318] = "lefttackbelowcmb", + [0x0319] = "righttackbelowcmb", + [0x031A] = "leftangleabovecmb", + [0x031B] = "horncmb", + [0x031C] = "ringhalfleftbelowcmb", + [0x031D] = "uptackbelowcmb", + [0x031E] = "downtackbelowcmb", + [0x031F] = "plusbelowcmb", + [0x0320] = "minusbelowcmb", + [0x0321] = "hookpalatalizedbelowcmb", + [0x0322] = "hookretroflexbelowcmb", + [0x0323] = "dotbelowcomb", + [0x0324] = "dieresisbelowcmb", + [0x0325] = "ringbelowcmb", + [0x0327] = "cedillacmb", + [0x0328] = "ogonekcmb", + [0x0329] = "verticallinebelowcmb", + [0x032A] = "bridgebelowcmb", + [0x032B] = "dblarchinvertedbelowcmb", + [0x032C] = "caronbelowcmb", + [0x032D] = "circumflexbelowcmb", + [0x032E] = "brevebelowcmb", + [0x032F] = "breveinvertedbelowcmb", + [0x0330] = "tildebelowcmb", + [0x0331] = "macronbelowcmb", + [0x0332] = "lowlinecmb", + [0x0333] = "dbllowlinecmb", + [0x0334] = "tildeoverlaycmb", + [0x0335] = "strokeshortoverlaycmb", + [0x0336] = "strokelongoverlaycmb", + [0x0337] = "solidusshortoverlaycmb", + [0x0338] = "soliduslongoverlaycmb", + [0x0339] = "ringhalfrightbelowcmb", + [0x033A] = "bridgeinvertedbelowcmb", + [0x033B] = "squarebelowcmb", + [0x033C] = "seagullbelowcmb", + [0x033D] = "xabovecmb", + [0x033E] = "tildeverticalcmb", + [0x033F] = "dbloverlinecmb", + [0x0340] = "gravetonecmb", + [0x0341] = "acutetonecmb", + [0x0342] = "perispomenigreekcmb", + [0x0343] = "koroniscmb", + [0x0344] = "dialytikatonoscmb", + [0x0345] = "ypogegrammenigreekcmb", + [0x0360] = "tildedoublecmb", + [0x0361] = "breveinverteddoublecmb", + [0x0374] = "numeralsigngreek", + [0x0375] = "numeralsignlowergreek", + [0x037A] = "ypogegrammeni", + [0x037E] = "questiongreek", + [0x0384] = "tonos", + [0x0385] = "dieresistonos", + [0x0386] = "Alphatonos", + [0x0387] = "anoteleia", + [0x0388] = "Epsilontonos", + [0x0389] = "Etatonos", + [0x038A] = "Iotatonos", + [0x038C] = "Omicrontonos", + [0x038E] = "Upsilontonos", + [0x038F] = "Omegatonos", + [0x0390] = "iotadieresistonos", + [0x0391] = "Alpha", + [0x0392] = "Beta", + [0x0393] = "Gamma", + [0x0394] = "Deltagreek", + [0x0395] = "Epsilon", + [0x0396] = "Zeta", + [0x0397] = "Eta", + [0x0398] = "Theta", + [0x0399] = "Iota", + [0x039A] = "Kappa", + [0x039B] = "Lambda", + [0x039C] = "Mu", + [0x039D] = "Nu", + [0x039E] = "Xi", + [0x039F] = "Omicron", + [0x03A0] = "Pi", + [0x03A1] = "Rho", + [0x03A3] = "Sigma", + [0x03A4] = "Tau", + [0x03A5] = "Upsilon", + [0x03A6] = "Phi", + [0x03A7] = "Chi", + [0x03A8] = "Psi", + [0x03A9] = "Omegagreek", + [0x03AA] = "Iotadieresis", + [0x03AB] = "Upsilondieresis", + [0x03AC] = "alphatonos", + [0x03AD] = "epsilontonos", + [0x03AE] = "etatonos", + [0x03AF] = "iotatonos", + [0x03B0] = "upsilondieresistonos", + [0x03B1] = "alpha", + [0x03B2] = "beta", + [0x03B3] = "gamma", + [0x03B4] = "delta", + [0x03B5] = "epsilon", + [0x03B6] = "zeta", + [0x03B7] = "eta", + [0x03B8] = "theta", + [0x03B9] = "iota", + [0x03BA] = "kappa", + [0x03BB] = "lambda", + [0x03BC] = "mugreek", + [0x03BD] = "nu", + [0x03BE] = "xi", + [0x03BF] = "omicron", + [0x03C0] = "pi", + [0x03C1] = "rho", + [0x03C2] = "sigmafinal", + [0x03C3] = "sigma", + [0x03C4] = "tau", + [0x03C5] = "upsilon", + [0x03C6] = "phi", + [0x03C7] = "chi", + [0x03C8] = "psi", + [0x03C9] = "omega", + [0x03CA] = "iotadieresis", + [0x03CB] = "upsilondieresis", + [0x03CC] = "omicrontonos", + [0x03CD] = "upsilontonos", + [0x03CE] = "omegatonos", + [0x03D0] = "betasymbolgreek", + [0x03D1] = "thetasymbolgreek", + [0x03D2] = "Upsilonhooksymbol", + [0x03D3] = "Upsilonacutehooksymbolgreek", + [0x03D4] = "Upsilondieresishooksymbolgreek", + [0x03D5] = "phisymbolgreek", + [0x03D6] = "pisymbolgreek", + [0x03DA] = "Stigmagreek", + [0x03DC] = "Digammagreek", + [0x03DE] = "Koppagreek", + [0x03E0] = "Sampigreek", + [0x03E2] = "Sheicoptic", + [0x03E3] = "sheicoptic", + [0x03E4] = "Feicoptic", + [0x03E5] = "feicoptic", + [0x03E6] = "Kheicoptic", + [0x03E7] = "kheicoptic", + [0x03E8] = "Horicoptic", + [0x03E9] = "horicoptic", + [0x03EA] = "Gangiacoptic", + [0x03EB] = "gangiacoptic", + [0x03EC] = "Shimacoptic", + [0x03ED] = "shimacoptic", + [0x03EE] = "Deicoptic", + [0x03EF] = "deicoptic", + [0x03F0] = "kappasymbolgreek", + [0x03F1] = "rhosymbolgreek", + [0x03F2] = "sigmalunatesymbolgreek", + [0x03F3] = "yotgreek", + [0x0401] = "afii10023", + [0x0402] = "afii10051", + [0x0403] = "afii10052", + [0x0404] = "afii10053", + [0x0405] = "afii10054", + [0x0406] = "afii10055", + [0x0407] = "afii10056", + [0x0408] = "afii10057", + [0x0409] = "afii10058", + [0x040A] = "afii10059", + [0x040B] = "afii10060", + [0x040C] = "afii10061", + [0x040E] = "afii10062", + [0x040F] = "afii10145", + [0x0410] = "afii10017", + [0x0411] = "afii10018", + [0x0412] = "afii10019", + [0x0413] = "afii10020", + [0x0414] = "afii10021", + [0x0415] = "afii10022", + [0x0416] = "afii10024", + [0x0417] = "afii10025", + [0x0418] = "afii10026", + [0x0419] = "afii10027", + [0x041A] = "afii10028", + [0x041B] = "afii10029", + [0x041C] = "afii10030", + [0x041D] = "afii10031", + [0x041E] = "afii10032", + [0x041F] = "afii10033", + [0x0420] = "afii10034", + [0x0421] = "afii10035", + [0x0422] = "afii10036", + [0x0423] = "afii10037", + [0x0424] = "afii10038", + [0x0425] = "afii10039", + [0x0426] = "afii10040", + [0x0427] = "afii10041", + [0x0428] = "afii10042", + [0x0429] = "afii10043", + [0x042A] = "afii10044", + [0x042B] = "afii10045", + [0x042C] = "afii10046", + [0x042D] = "afii10047", + [0x042E] = "afii10048", + [0x042F] = "afii10049", + [0x0430] = "afii10065", + [0x0431] = "becyrillic", + [0x0432] = "vecyrillic", + [0x0433] = "gecyrillic", + [0x0434] = "decyrillic", + [0x0435] = "iecyrillic", + [0x0436] = "zhecyrillic", + [0x0437] = "zecyrillic", + [0x0438] = "iicyrillic", + [0x0439] = "iishortcyrillic", + [0x043A] = "kacyrillic", + [0x043B] = "elcyrillic", + [0x043C] = "emcyrillic", + [0x043D] = "encyrillic", + [0x043E] = "ocyrillic", + [0x043F] = "pecyrillic", + [0x0440] = "ercyrillic", + [0x0441] = "escyrillic", + [0x0442] = "tecyrillic", + [0x0443] = "ucyrillic", + [0x0444] = "efcyrillic", + [0x0445] = "khacyrillic", + [0x0446] = "tsecyrillic", + [0x0447] = "checyrillic", + [0x0448] = "shacyrillic", + [0x0449] = "shchacyrillic", + [0x044A] = "hardsigncyrillic", + [0x044B] = "yericyrillic", + [0x044C] = "softsigncyrillic", + [0x044D] = "ereversedcyrillic", + [0x044E] = "iucyrillic", + [0x044F] = "iacyrillic", + [0x0451] = "iocyrillic", + [0x0452] = "djecyrillic", + [0x0453] = "gjecyrillic", + [0x0454] = "ecyrillic", + [0x0455] = "dzecyrillic", + [0x0456] = "icyrillic", + [0x0457] = "yicyrillic", + [0x0458] = "jecyrillic", + [0x0459] = "ljecyrillic", + [0x045A] = "njecyrillic", + [0x045B] = "tshecyrillic", + [0x045C] = "kjecyrillic", + [0x045E] = "ushortcyrillic", + [0x045F] = "dzhecyrillic", + [0x0460] = "Omegacyrillic", + [0x0461] = "omegacyrillic", + [0x0462] = "afii10146", + [0x0463] = "yatcyrillic", + [0x0464] = "Eiotifiedcyrillic", + [0x0465] = "eiotifiedcyrillic", + [0x0466] = "Yuslittlecyrillic", + [0x0467] = "yuslittlecyrillic", + [0x0468] = "Yuslittleiotifiedcyrillic", + [0x0469] = "yuslittleiotifiedcyrillic", + [0x046A] = "Yusbigcyrillic", + [0x046B] = "yusbigcyrillic", + [0x046C] = "Yusbigiotifiedcyrillic", + [0x046D] = "yusbigiotifiedcyrillic", + [0x046E] = "Ksicyrillic", + [0x046F] = "ksicyrillic", + [0x0470] = "Psicyrillic", + [0x0471] = "psicyrillic", + [0x0472] = "afii10147", + [0x0473] = "fitacyrillic", + [0x0474] = "afii10148", + [0x0475] = "izhitsacyrillic", + [0x0476] = "Izhitsadblgravecyrillic", + [0x0477] = "izhitsadblgravecyrillic", + [0x0478] = "Ukcyrillic", + [0x0479] = "ukcyrillic", + [0x047A] = "Omegaroundcyrillic", + [0x047B] = "omegaroundcyrillic", + [0x047C] = "Omegatitlocyrillic", + [0x047D] = "omegatitlocyrillic", + [0x047E] = "Otcyrillic", + [0x047F] = "otcyrillic", + [0x0480] = "Koppacyrillic", + [0x0481] = "koppacyrillic", + [0x0482] = "thousandcyrillic", + [0x0483] = "titlocyrilliccmb", + [0x0484] = "palatalizationcyrilliccmb", + [0x0485] = "dasiapneumatacyrilliccmb", + [0x0486] = "psilipneumatacyrilliccmb", + [0x0490] = "afii10050", + [0x0491] = "gheupturncyrillic", + [0x0492] = "Ghestrokecyrillic", + [0x0493] = "ghestrokecyrillic", + [0x0494] = "Ghemiddlehookcyrillic", + [0x0495] = "ghemiddlehookcyrillic", + [0x0496] = "Zhedescendercyrillic", + [0x0497] = "zhedescendercyrillic", + [0x0498] = "Zedescendercyrillic", + [0x0499] = "zedescendercyrillic", + [0x049A] = "Kadescendercyrillic", + [0x049B] = "kadescendercyrillic", + [0x049C] = "Kaverticalstrokecyrillic", + [0x049D] = "kaverticalstrokecyrillic", + [0x049E] = "Kastrokecyrillic", + [0x049F] = "kastrokecyrillic", + [0x04A0] = "Kabashkircyrillic", + [0x04A1] = "kabashkircyrillic", + [0x04A2] = "Endescendercyrillic", + [0x04A3] = "endescendercyrillic", + [0x04A4] = "Enghecyrillic", + [0x04A5] = "enghecyrillic", + [0x04A6] = "Pemiddlehookcyrillic", + [0x04A7] = "pemiddlehookcyrillic", + [0x04A8] = "Haabkhasiancyrillic", + [0x04A9] = "haabkhasiancyrillic", + [0x04AA] = "Esdescendercyrillic", + [0x04AB] = "esdescendercyrillic", + [0x04AC] = "Tedescendercyrillic", + [0x04AD] = "tedescendercyrillic", + [0x04AE] = "Ustraightcyrillic", + [0x04AF] = "ustraightcyrillic", + [0x04B0] = "Ustraightstrokecyrillic", + [0x04B1] = "ustraightstrokecyrillic", + [0x04B2] = "Hadescendercyrillic", + [0x04B3] = "hadescendercyrillic", + [0x04B4] = "Tetsecyrillic", + [0x04B5] = "tetsecyrillic", + [0x04B6] = "Chedescendercyrillic", + [0x04B7] = "chedescendercyrillic", + [0x04B8] = "Cheverticalstrokecyrillic", + [0x04B9] = "cheverticalstrokecyrillic", + [0x04BA] = "Shhacyrillic", + [0x04BB] = "shhacyrillic", + [0x04BC] = "Cheabkhasiancyrillic", + [0x04BD] = "cheabkhasiancyrillic", + [0x04BE] = "Chedescenderabkhasiancyrillic", + [0x04BF] = "chedescenderabkhasiancyrillic", + [0x04C0] = "palochkacyrillic", + [0x04C1] = "Zhebrevecyrillic", + [0x04C2] = "zhebrevecyrillic", + [0x04C3] = "Kahookcyrillic", + [0x04C4] = "kahookcyrillic", + [0x04C7] = "Enhookcyrillic", + [0x04C8] = "enhookcyrillic", + [0x04CB] = "Chekhakassiancyrillic", + [0x04CC] = "chekhakassiancyrillic", + [0x04D0] = "Abrevecyrillic", + [0x04D1] = "abrevecyrillic", + [0x04D2] = "Adieresiscyrillic", + [0x04D3] = "adieresiscyrillic", + [0x04D4] = "Aiecyrillic", + [0x04D5] = "aiecyrillic", + [0x04D6] = "Iebrevecyrillic", + [0x04D7] = "iebrevecyrillic", + [0x04D8] = "Schwacyrillic", + [0x04D9] = "schwacyrillic", + [0x04DA] = "Schwadieresiscyrillic", + [0x04DB] = "schwadieresiscyrillic", + [0x04DC] = "Zhedieresiscyrillic", + [0x04DD] = "zhedieresiscyrillic", + [0x04DE] = "Zedieresiscyrillic", + [0x04DF] = "zedieresiscyrillic", + [0x04E0] = "Dzeabkhasiancyrillic", + [0x04E1] = "dzeabkhasiancyrillic", + [0x04E2] = "Imacroncyrillic", + [0x04E3] = "imacroncyrillic", + [0x04E4] = "Idieresiscyrillic", + [0x04E5] = "idieresiscyrillic", + [0x04E6] = "Odieresiscyrillic", + [0x04E7] = "odieresiscyrillic", + [0x04E8] = "Obarredcyrillic", + [0x04E9] = "obarredcyrillic", + [0x04EA] = "Obarreddieresiscyrillic", + [0x04EB] = "obarreddieresiscyrillic", + [0x04EE] = "Umacroncyrillic", + [0x04EF] = "umacroncyrillic", + [0x04F0] = "Udieresiscyrillic", + [0x04F1] = "udieresiscyrillic", + [0x04F2] = "Uhungarumlautcyrillic", + [0x04F3] = "uhungarumlautcyrillic", + [0x04F4] = "Chedieresiscyrillic", + [0x04F5] = "chedieresiscyrillic", + [0x04F8] = "Yerudieresiscyrillic", + [0x04F9] = "yerudieresiscyrillic", + [0x0531] = "Aybarmenian", + [0x0532] = "Benarmenian", + [0x0533] = "Gimarmenian", + [0x0534] = "Daarmenian", + [0x0535] = "Echarmenian", + [0x0536] = "Zaarmenian", + [0x0537] = "Eharmenian", + [0x0538] = "Etarmenian", + [0x0539] = "Toarmenian", + [0x053A] = "Zhearmenian", + [0x053B] = "Iniarmenian", + [0x053C] = "Liwnarmenian", + [0x053D] = "Xeharmenian", + [0x053E] = "Caarmenian", + [0x053F] = "Kenarmenian", + [0x0540] = "Hoarmenian", + [0x0541] = "Jaarmenian", + [0x0542] = "Ghadarmenian", + [0x0543] = "Cheharmenian", + [0x0544] = "Menarmenian", + [0x0545] = "Yiarmenian", + [0x0546] = "Nowarmenian", + [0x0547] = "Shaarmenian", + [0x0548] = "Voarmenian", + [0x0549] = "Chaarmenian", + [0x054A] = "Peharmenian", + [0x054B] = "Jheharmenian", + [0x054C] = "Raarmenian", + [0x054D] = "Seharmenian", + [0x054E] = "Vewarmenian", + [0x054F] = "Tiwnarmenian", + [0x0550] = "Reharmenian", + [0x0551] = "Coarmenian", + [0x0552] = "Yiwnarmenian", + [0x0553] = "Piwrarmenian", + [0x0554] = "Keharmenian", + [0x0555] = "Oharmenian", + [0x0556] = "Feharmenian", + [0x0559] = "ringhalfleftarmenian", + [0x055A] = "apostrophearmenian", + [0x055B] = "emphasismarkarmenian", + [0x055C] = "exclamarmenian", + [0x055D] = "commaarmenian", + [0x055E] = "questionarmenian", + [0x055F] = "abbreviationmarkarmenian", + [0x0561] = "aybarmenian", + [0x0562] = "benarmenian", + [0x0563] = "gimarmenian", + [0x0564] = "daarmenian", + [0x0565] = "echarmenian", + [0x0566] = "zaarmenian", + [0x0567] = "eharmenian", + [0x0568] = "etarmenian", + [0x0569] = "toarmenian", + [0x056A] = "zhearmenian", + [0x056B] = "iniarmenian", + [0x056C] = "liwnarmenian", + [0x056D] = "xeharmenian", + [0x056E] = "caarmenian", + [0x056F] = "kenarmenian", + [0x0570] = "hoarmenian", + [0x0571] = "jaarmenian", + [0x0572] = "ghadarmenian", + [0x0573] = "cheharmenian", + [0x0574] = "menarmenian", + [0x0575] = "yiarmenian", + [0x0576] = "nowarmenian", + [0x0577] = "shaarmenian", + [0x0578] = "voarmenian", + [0x0579] = "chaarmenian", + [0x057A] = "peharmenian", + [0x057B] = "jheharmenian", + [0x057C] = "raarmenian", + [0x057D] = "seharmenian", + [0x057E] = "vewarmenian", + [0x057F] = "tiwnarmenian", + [0x0580] = "reharmenian", + [0x0581] = "coarmenian", + [0x0582] = "yiwnarmenian", + [0x0583] = "piwrarmenian", + [0x0584] = "keharmenian", + [0x0585] = "oharmenian", + [0x0586] = "feharmenian", + [0x0587] = "echyiwnarmenian", + [0x0589] = "periodarmenian", + [0x0591] = "etnahtalefthebrew", + [0x0592] = "segoltahebrew", + [0x0593] = "shalshelethebrew", + [0x0594] = "zaqefqatanhebrew", + [0x0595] = "zaqefgadolhebrew", + [0x0596] = "tipehalefthebrew", + [0x0597] = "reviamugrashhebrew", + [0x0598] = "zarqahebrew", + [0x0599] = "pashtahebrew", + [0x059A] = "yetivhebrew", + [0x059B] = "tevirlefthebrew", + [0x059C] = "gereshaccenthebrew", + [0x059D] = "gereshmuqdamhebrew", + [0x059E] = "gershayimaccenthebrew", + [0x059F] = "qarneyparahebrew", + [0x05A0] = "telishagedolahebrew", + [0x05A1] = "pazerhebrew", + [0x05A3] = "munahlefthebrew", + [0x05A4] = "mahapakhlefthebrew", + [0x05A5] = "merkhalefthebrew", + [0x05A6] = "merkhakefulalefthebrew", + [0x05A7] = "dargalefthebrew", + [0x05A8] = "qadmahebrew", + [0x05A9] = "telishaqetanahebrew", + [0x05AA] = "yerahbenyomolefthebrew", + [0x05AB] = "olehebrew", + [0x05AC] = "iluyhebrew", + [0x05AD] = "dehihebrew", + [0x05AE] = "zinorhebrew", + [0x05AF] = "masoracirclehebrew", + [0x05B0] = "shevawidehebrew", + [0x05B1] = "hatafsegolwidehebrew", + [0x05B2] = "hatafpatahwidehebrew", + [0x05B3] = "hatafqamatswidehebrew", + [0x05B4] = "hiriqwidehebrew", + [0x05B5] = "tserewidehebrew", + [0x05B6] = "segolwidehebrew", + [0x05B7] = "patahwidehebrew", + [0x05B8] = "qamatswidehebrew", + [0x05B9] = "holamwidehebrew", + [0x05BB] = "qubutswidehebrew", + [0x05BC] = "dageshhebrew", + [0x05BD] = "siluqlefthebrew", + [0x05BE] = "maqafhebrew", + [0x05BF] = "rafehebrew", + [0x05C0] = "paseqhebrew", + [0x05C1] = "shindothebrew", + [0x05C2] = "sindothebrew", + [0x05C3] = "sofpasuqhebrew", + [0x05C4] = "upperdothebrew", + [0x05D0] = "alefhebrew", + [0x05D1] = "bethebrew", + [0x05D2] = "gimelhebrew", + [0x05D3] = "dalettserehebrew", + [0x05D4] = "hehebrew", + [0x05D5] = "vavhebrew", + [0x05D6] = "zayinhebrew", + [0x05D7] = "hethebrew", + [0x05D8] = "tethebrew", + [0x05D9] = "yodhebrew", + [0x05DA] = "finalkafshevahebrew", + [0x05DB] = "kafhebrew", + [0x05DC] = "lamedholamhebrew", + [0x05DD] = "finalmemhebrew", + [0x05DE] = "memhebrew", + [0x05DF] = "finalnunhebrew", + [0x05E0] = "nunhebrew", + [0x05E1] = "samekhhebrew", + [0x05E2] = "ayinhebrew", + [0x05E3] = "finalpehebrew", + [0x05E4] = "pehebrew", + [0x05E5] = "finaltsadihebrew", + [0x05E6] = "tsadihebrew", + [0x05E7] = "qoftserehebrew", + [0x05E8] = "reshtserehebrew", + [0x05E9] = "shinhebrew", + [0x05EA] = "tavhebrew", + [0x05F0] = "vavvavhebrew", + [0x05F1] = "vavyodhebrew", + [0x05F2] = "yodyodhebrew", + [0x05F3] = "gereshhebrew", + [0x05F4] = "gershayimhebrew", + [0x060C] = "commaarabic", + [0x061B] = "semicolonarabic", + [0x061F] = "questionarabic", + [0x0621] = "hamzasukunarabic", + [0x0622] = "alefmaddaabovearabic", + [0x0623] = "alefhamzaabovearabic", + [0x0624] = "wawhamzaabovearabic", + [0x0625] = "alefhamzabelowarabic", + [0x0626] = "yehhamzaabovearabic", + [0x0627] = "alefarabic", + [0x0628] = "beharabic", + [0x0629] = "tehmarbutaarabic", + [0x062A] = "teharabic", + [0x062B] = "theharabic", + [0x062C] = "jeemarabic", + [0x062D] = "haharabic", + [0x062E] = "khaharabic", + [0x062F] = "dalarabic", + [0x0630] = "thalarabic", + [0x0631] = "rehyehaleflamarabic", + [0x0632] = "zainarabic", + [0x0633] = "seenarabic", + [0x0634] = "sheenarabic", + [0x0635] = "sadarabic", + [0x0636] = "dadarabic", + [0x0637] = "taharabic", + [0x0638] = "zaharabic", + [0x0639] = "ainarabic", + [0x063A] = "ghainarabic", + [0x0640] = "tatweelarabic", + [0x0641] = "feharabic", + [0x0642] = "qafarabic", + [0x0643] = "kafarabic", + [0x0644] = "lamarabic", + [0x0645] = "meemarabic", + [0x0646] = "noonarabic", + [0x0647] = "heharabic", + [0x0648] = "wawarabic", + [0x0649] = "alefmaksuraarabic", + [0x064A] = "yeharabic", + [0x064B] = "fathatanarabic", + [0x064C] = "dammatanarabic", + [0x064D] = "kasratanarabic", + [0x064E] = "fathalowarabic", + [0x064F] = "dammalowarabic", + [0x0650] = "kasraarabic", + [0x0651] = "shaddafathatanarabic", + [0x0652] = "sukunarabic", + [0x0660] = "zerohackarabic", + [0x0661] = "onehackarabic", + [0x0662] = "twohackarabic", + [0x0663] = "threehackarabic", + [0x0664] = "fourhackarabic", + [0x0665] = "fivehackarabic", + [0x0666] = "sixhackarabic", + [0x0667] = "sevenhackarabic", + [0x0668] = "eighthackarabic", + [0x0669] = "ninehackarabic", + [0x066A] = "percentarabic", + [0x066B] = "decimalseparatorpersian", + [0x066C] = "thousandsseparatorpersian", + [0x066D] = "asteriskarabic", + [0x0679] = "tteharabic", + [0x067E] = "peharabic", + [0x0686] = "tcheharabic", + [0x0688] = "ddalarabic", + [0x0691] = "rreharabic", + [0x0698] = "jeharabic", + [0x06A4] = "veharabic", + [0x06AF] = "gafarabic", + [0x06BA] = "noonghunnaarabic", + [0x06C1] = "hehaltonearabic", + [0x06D1] = "yehthreedotsbelowarabic", + [0x06D2] = "yehbarreearabic", + [0x06D5] = "afii57534", + [0x06F0] = "zeropersian", + [0x06F1] = "onepersian", + [0x06F2] = "twopersian", + [0x06F3] = "threepersian", + [0x06F4] = "fourpersian", + [0x06F5] = "fivepersian", + [0x06F6] = "sixpersian", + [0x06F7] = "sevenpersian", + [0x06F8] = "eightpersian", + [0x06F9] = "ninepersian", + [0x0901] = "candrabindudeva", + [0x0902] = "anusvaradeva", + [0x0903] = "visargadeva", + [0x0905] = "adeva", + [0x0906] = "aadeva", + [0x0907] = "ideva", + [0x0908] = "iideva", + [0x0909] = "udeva", + [0x090A] = "uudeva", + [0x090B] = "rvocalicdeva", + [0x090C] = "lvocalicdeva", + [0x090D] = "ecandradeva", + [0x090E] = "eshortdeva", + [0x090F] = "edeva", + [0x0910] = "aideva", + [0x0911] = "ocandradeva", + [0x0912] = "oshortdeva", + [0x0913] = "odeva", + [0x0914] = "audeva", + [0x0915] = "kadeva", + [0x0916] = "khadeva", + [0x0917] = "gadeva", + [0x0918] = "ghadeva", + [0x0919] = "ngadeva", + [0x091A] = "cadeva", + [0x091B] = "chadeva", + [0x091C] = "jadeva", + [0x091D] = "jhadeva", + [0x091E] = "nyadeva", + [0x091F] = "ttadeva", + [0x0920] = "tthadeva", + [0x0921] = "ddadeva", + [0x0922] = "ddhadeva", + [0x0923] = "nnadeva", + [0x0924] = "tadeva", + [0x0925] = "thadeva", + [0x0926] = "dadeva", + [0x0927] = "dhadeva", + [0x0928] = "nadeva", + [0x0929] = "nnnadeva", + [0x092A] = "padeva", + [0x092B] = "phadeva", + [0x092C] = "badeva", + [0x092D] = "bhadeva", + [0x092E] = "madeva", + [0x092F] = "yadeva", + [0x0930] = "radeva", + [0x0931] = "rradeva", + [0x0932] = "ladeva", + [0x0933] = "lladeva", + [0x0934] = "llladeva", + [0x0935] = "vadeva", + [0x0936] = "shadeva", + [0x0937] = "ssadeva", + [0x0938] = "sadeva", + [0x0939] = "hadeva", + [0x093C] = "nuktadeva", + [0x093D] = "avagrahadeva", + [0x093E] = "aavowelsigndeva", + [0x093F] = "ivowelsigndeva", + [0x0940] = "iivowelsigndeva", + [0x0941] = "uvowelsigndeva", + [0x0942] = "uuvowelsigndeva", + [0x0943] = "rvocalicvowelsigndeva", + [0x0944] = "rrvocalicvowelsigndeva", + [0x0945] = "ecandravowelsigndeva", + [0x0946] = "eshortvowelsigndeva", + [0x0947] = "evowelsigndeva", + [0x0948] = "aivowelsigndeva", + [0x0949] = "ocandravowelsigndeva", + [0x094A] = "oshortvowelsigndeva", + [0x094B] = "ovowelsigndeva", + [0x094C] = "auvowelsigndeva", + [0x094D] = "viramadeva", + [0x0950] = "omdeva", + [0x0951] = "udattadeva", + [0x0952] = "anudattadeva", + [0x0953] = "gravedeva", + [0x0954] = "acutedeva", + [0x0958] = "qadeva", + [0x0959] = "khhadeva", + [0x095A] = "ghhadeva", + [0x095B] = "zadeva", + [0x095C] = "dddhadeva", + [0x095D] = "rhadeva", + [0x095E] = "fadeva", + [0x095F] = "yyadeva", + [0x0960] = "rrvocalicdeva", + [0x0961] = "llvocalicdeva", + [0x0962] = "lvocalicvowelsigndeva", + [0x0963] = "llvocalicvowelsigndeva", + [0x0964] = "danda", + [0x0965] = "dbldanda", + [0x0966] = "zerodeva", + [0x0967] = "onedeva", + [0x0968] = "twodeva", + [0x0969] = "threedeva", + [0x096A] = "fourdeva", + [0x096B] = "fivedeva", + [0x096C] = "sixdeva", + [0x096D] = "sevendeva", + [0x096E] = "eightdeva", + [0x096F] = "ninedeva", + [0x0970] = "abbreviationsigndeva", + [0x0981] = "candrabindubengali", + [0x0982] = "anusvarabengali", + [0x0983] = "visargabengali", + [0x0985] = "abengali", + [0x0986] = "aabengali", + [0x0987] = "ibengali", + [0x0988] = "iibengali", + [0x0989] = "ubengali", + [0x098A] = "uubengali", + [0x098B] = "rvocalicbengali", + [0x098C] = "lvocalicbengali", + [0x098F] = "ebengali", + [0x0990] = "aibengali", + [0x0993] = "obengali", + [0x0994] = "aubengali", + [0x0995] = "kabengali", + [0x0996] = "khabengali", + [0x0997] = "gabengali", + [0x0998] = "ghabengali", + [0x0999] = "ngabengali", + [0x099A] = "cabengali", + [0x099B] = "chabengali", + [0x099C] = "jabengali", + [0x099D] = "jhabengali", + [0x099E] = "nyabengali", + [0x099F] = "ttabengali", + [0x09A0] = "tthabengali", + [0x09A1] = "ddabengali", + [0x09A2] = "ddhabengali", + [0x09A3] = "nnabengali", + [0x09A4] = "tabengali", + [0x09A5] = "thabengali", + [0x09A6] = "dabengali", + [0x09A7] = "dhabengali", + [0x09A8] = "nabengali", + [0x09AA] = "pabengali", + [0x09AB] = "phabengali", + [0x09AC] = "babengali", + [0x09AD] = "bhabengali", + [0x09AE] = "mabengali", + [0x09AF] = "yabengali", + [0x09B0] = "rabengali", + [0x09B2] = "labengali", + [0x09B6] = "shabengali", + [0x09B7] = "ssabengali", + [0x09B8] = "sabengali", + [0x09B9] = "habengali", + [0x09BC] = "nuktabengali", + [0x09BE] = "aavowelsignbengali", + [0x09BF] = "ivowelsignbengali", + [0x09C0] = "iivowelsignbengali", + [0x09C1] = "uvowelsignbengali", + [0x09C2] = "uuvowelsignbengali", + [0x09C3] = "rvocalicvowelsignbengali", + [0x09C4] = "rrvocalicvowelsignbengali", + [0x09C7] = "evowelsignbengali", + [0x09C8] = "aivowelsignbengali", + [0x09CB] = "ovowelsignbengali", + [0x09CC] = "auvowelsignbengali", + [0x09CD] = "viramabengali", + [0x09D7] = "aulengthmarkbengali", + [0x09DC] = "rrabengali", + [0x09DD] = "rhabengali", + [0x09DF] = "yyabengali", + [0x09E0] = "rrvocalicbengali", + [0x09E1] = "llvocalicbengali", + [0x09E2] = "lvocalicvowelsignbengali", + [0x09E3] = "llvocalicvowelsignbengali", + [0x09E6] = "zerobengali", + [0x09E7] = "onebengali", + [0x09E8] = "twobengali", + [0x09E9] = "threebengali", + [0x09EA] = "fourbengali", + [0x09EB] = "fivebengali", + [0x09EC] = "sixbengali", + [0x09ED] = "sevenbengali", + [0x09EE] = "eightbengali", + [0x09EF] = "ninebengali", + [0x09F0] = "ramiddlediagonalbengali", + [0x09F1] = "ralowerdiagonalbengali", + [0x09F2] = "rupeemarkbengali", + [0x09F3] = "rupeesignbengali", + [0x09F4] = "onenumeratorbengali", + [0x09F5] = "twonumeratorbengali", + [0x09F6] = "threenumeratorbengali", + [0x09F7] = "fournumeratorbengali", + [0x09F8] = "denominatorminusonenumeratorbengali", + [0x09F9] = "sixteencurrencydenominatorbengali", + [0x09FA] = "issharbengali", + [0x0A02] = "bindigurmukhi", + [0x0A05] = "agurmukhi", + [0x0A06] = "aagurmukhi", + [0x0A07] = "igurmukhi", + [0x0A08] = "iigurmukhi", + [0x0A09] = "ugurmukhi", + [0x0A0A] = "uugurmukhi", + [0x0A0F] = "eegurmukhi", + [0x0A10] = "aigurmukhi", + [0x0A13] = "oogurmukhi", + [0x0A14] = "augurmukhi", + [0x0A15] = "kagurmukhi", + [0x0A16] = "khagurmukhi", + [0x0A17] = "gagurmukhi", + [0x0A18] = "ghagurmukhi", + [0x0A19] = "ngagurmukhi", + [0x0A1A] = "cagurmukhi", + [0x0A1B] = "chagurmukhi", + [0x0A1C] = "jagurmukhi", + [0x0A1D] = "jhagurmukhi", + [0x0A1E] = "nyagurmukhi", + [0x0A1F] = "ttagurmukhi", + [0x0A20] = "tthagurmukhi", + [0x0A21] = "ddagurmukhi", + [0x0A22] = "ddhagurmukhi", + [0x0A23] = "nnagurmukhi", + [0x0A24] = "tagurmukhi", + [0x0A25] = "thagurmukhi", + [0x0A26] = "dagurmukhi", + [0x0A27] = "dhagurmukhi", + [0x0A28] = "nagurmukhi", + [0x0A2A] = "pagurmukhi", + [0x0A2B] = "phagurmukhi", + [0x0A2C] = "bagurmukhi", + [0x0A2D] = "bhagurmukhi", + [0x0A2E] = "magurmukhi", + [0x0A2F] = "yagurmukhi", + [0x0A30] = "ragurmukhi", + [0x0A32] = "lagurmukhi", + [0x0A35] = "vagurmukhi", + [0x0A36] = "shagurmukhi", + [0x0A38] = "sagurmukhi", + [0x0A39] = "hagurmukhi", + [0x0A3C] = "nuktagurmukhi", + [0x0A3E] = "aamatragurmukhi", + [0x0A3F] = "imatragurmukhi", + [0x0A40] = "iimatragurmukhi", + [0x0A41] = "umatragurmukhi", + [0x0A42] = "uumatragurmukhi", + [0x0A47] = "eematragurmukhi", + [0x0A48] = "aimatragurmukhi", + [0x0A4B] = "oomatragurmukhi", + [0x0A4C] = "aumatragurmukhi", + [0x0A4D] = "halantgurmukhi", + [0x0A59] = "khhagurmukhi", + [0x0A5A] = "ghhagurmukhi", + [0x0A5B] = "zagurmukhi", + [0x0A5C] = "rragurmukhi", + [0x0A5E] = "fagurmukhi", + [0x0A66] = "zerogurmukhi", + [0x0A67] = "onegurmukhi", + [0x0A68] = "twogurmukhi", + [0x0A69] = "threegurmukhi", + [0x0A6A] = "fourgurmukhi", + [0x0A6B] = "fivegurmukhi", + [0x0A6C] = "sixgurmukhi", + [0x0A6D] = "sevengurmukhi", + [0x0A6E] = "eightgurmukhi", + [0x0A6F] = "ninegurmukhi", + [0x0A70] = "tippigurmukhi", + [0x0A71] = "addakgurmukhi", + [0x0A72] = "irigurmukhi", + [0x0A73] = "uragurmukhi", + [0x0A74] = "ekonkargurmukhi", + [0x0A81] = "candrabindugujarati", + [0x0A82] = "anusvaragujarati", + [0x0A83] = "visargagujarati", + [0x0A85] = "agujarati", + [0x0A86] = "aagujarati", + [0x0A87] = "igujarati", + [0x0A88] = "iigujarati", + [0x0A89] = "ugujarati", + [0x0A8A] = "uugujarati", + [0x0A8B] = "rvocalicgujarati", + [0x0A8D] = "ecandragujarati", + [0x0A8F] = "egujarati", + [0x0A90] = "aigujarati", + [0x0A91] = "ocandragujarati", + [0x0A93] = "ogujarati", + [0x0A94] = "augujarati", + [0x0A95] = "kagujarati", + [0x0A96] = "khagujarati", + [0x0A97] = "gagujarati", + [0x0A98] = "ghagujarati", + [0x0A99] = "ngagujarati", + [0x0A9A] = "cagujarati", + [0x0A9B] = "chagujarati", + [0x0A9C] = "jagujarati", + [0x0A9D] = "jhagujarati", + [0x0A9E] = "nyagujarati", + [0x0A9F] = "ttagujarati", + [0x0AA0] = "tthagujarati", + [0x0AA1] = "ddagujarati", + [0x0AA2] = "ddhagujarati", + [0x0AA3] = "nnagujarati", + [0x0AA4] = "tagujarati", + [0x0AA5] = "thagujarati", + [0x0AA6] = "dagujarati", + [0x0AA7] = "dhagujarati", + [0x0AA8] = "nagujarati", + [0x0AAA] = "pagujarati", + [0x0AAB] = "phagujarati", + [0x0AAC] = "bagujarati", + [0x0AAD] = "bhagujarati", + [0x0AAE] = "magujarati", + [0x0AAF] = "yagujarati", + [0x0AB0] = "ragujarati", + [0x0AB2] = "lagujarati", + [0x0AB3] = "llagujarati", + [0x0AB5] = "vagujarati", + [0x0AB6] = "shagujarati", + [0x0AB7] = "ssagujarati", + [0x0AB8] = "sagujarati", + [0x0AB9] = "hagujarati", + [0x0ABC] = "nuktagujarati", + [0x0ABE] = "aavowelsigngujarati", + [0x0ABF] = "ivowelsigngujarati", + [0x0AC0] = "iivowelsigngujarati", + [0x0AC1] = "uvowelsigngujarati", + [0x0AC2] = "uuvowelsigngujarati", + [0x0AC3] = "rvocalicvowelsigngujarati", + [0x0AC4] = "rrvocalicvowelsigngujarati", + [0x0AC5] = "ecandravowelsigngujarati", + [0x0AC7] = "evowelsigngujarati", + [0x0AC8] = "aivowelsigngujarati", + [0x0AC9] = "ocandravowelsigngujarati", + [0x0ACB] = "ovowelsigngujarati", + [0x0ACC] = "auvowelsigngujarati", + [0x0ACD] = "viramagujarati", + [0x0AD0] = "omgujarati", + [0x0AE0] = "rrvocalicgujarati", + [0x0AE6] = "zerogujarati", + [0x0AE7] = "onegujarati", + [0x0AE8] = "twogujarati", + [0x0AE9] = "threegujarati", + [0x0AEA] = "fourgujarati", + [0x0AEB] = "fivegujarati", + [0x0AEC] = "sixgujarati", + [0x0AED] = "sevengujarati", + [0x0AEE] = "eightgujarati", + [0x0AEF] = "ninegujarati", + [0x0E01] = "kokaithai", + [0x0E02] = "khokhaithai", + [0x0E03] = "khokhuatthai", + [0x0E04] = "khokhwaithai", + [0x0E05] = "khokhonthai", + [0x0E06] = "khorakhangthai", + [0x0E07] = "ngonguthai", + [0x0E08] = "chochanthai", + [0x0E09] = "chochingthai", + [0x0E0A] = "chochangthai", + [0x0E0B] = "sosothai", + [0x0E0C] = "chochoethai", + [0x0E0D] = "yoyingthai", + [0x0E0E] = "dochadathai", + [0x0E0F] = "topatakthai", + [0x0E10] = "thothanthai", + [0x0E11] = "thonangmonthothai", + [0x0E12] = "thophuthaothai", + [0x0E13] = "nonenthai", + [0x0E14] = "dodekthai", + [0x0E15] = "totaothai", + [0x0E16] = "thothungthai", + [0x0E17] = "thothahanthai", + [0x0E18] = "thothongthai", + [0x0E19] = "nonuthai", + [0x0E1A] = "bobaimaithai", + [0x0E1B] = "poplathai", + [0x0E1C] = "phophungthai", + [0x0E1D] = "fofathai", + [0x0E1E] = "phophanthai", + [0x0E1F] = "fofanthai", + [0x0E20] = "phosamphaothai", + [0x0E21] = "momathai", + [0x0E22] = "yoyakthai", + [0x0E23] = "roruathai", + [0x0E24] = "ruthai", + [0x0E25] = "lolingthai", + [0x0E26] = "luthai", + [0x0E27] = "wowaenthai", + [0x0E28] = "sosalathai", + [0x0E29] = "sorusithai", + [0x0E2A] = "sosuathai", + [0x0E2B] = "hohipthai", + [0x0E2C] = "lochulathai", + [0x0E2D] = "oangthai", + [0x0E2E] = "honokhukthai", + [0x0E2F] = "paiyannoithai", + [0x0E30] = "saraathai", + [0x0E31] = "maihanakatthai", + [0x0E32] = "saraaathai", + [0x0E33] = "saraamthai", + [0x0E34] = "saraithai", + [0x0E35] = "saraiithai", + [0x0E36] = "sarauethai", + [0x0E37] = "saraueethai", + [0x0E38] = "sarauthai", + [0x0E39] = "sarauuthai", + [0x0E3A] = "phinthuthai", + [0x0E3F] = "bahtthai", + [0x0E40] = "saraethai", + [0x0E41] = "saraaethai", + [0x0E42] = "saraothai", + [0x0E43] = "saraaimaimuanthai", + [0x0E44] = "saraaimaimalaithai", + [0x0E45] = "lakkhangyaothai", + [0x0E46] = "maiyamokthai", + [0x0E47] = "maitaikhuthai", + [0x0E48] = "maiekthai", + [0x0E49] = "maithothai", + [0x0E4A] = "maitrithai", + [0x0E4B] = "maichattawathai", + [0x0E4C] = "thanthakhatthai", + [0x0E4D] = "nikhahitthai", + [0x0E4E] = "yamakkanthai", + [0x0E4F] = "fongmanthai", + [0x0E50] = "zerothai", + [0x0E51] = "onethai", + [0x0E52] = "twothai", + [0x0E53] = "threethai", + [0x0E54] = "fourthai", + [0x0E55] = "fivethai", + [0x0E56] = "sixthai", + [0x0E57] = "seventhai", + [0x0E58] = "eightthai", + [0x0E59] = "ninethai", + [0x0E5A] = "angkhankhuthai", + [0x0E5B] = "khomutthai", + [0x1E00] = "Aringbelow", + [0x1E01] = "aringbelow", + [0x1E02] = "Bdotaccent", + [0x1E03] = "bdotaccent", + [0x1E04] = "Bdotbelow", + [0x1E05] = "bdotbelow", + [0x1E06] = "Blinebelow", + [0x1E07] = "blinebelow", + [0x1E08] = "Ccedillaacute", + [0x1E09] = "ccedillaacute", + [0x1E0A] = "Ddotaccent", + [0x1E0B] = "ddotaccent", + [0x1E0C] = "Ddotbelow", + [0x1E0D] = "ddotbelow", + [0x1E0E] = "Dlinebelow", + [0x1E0F] = "dlinebelow", + [0x1E10] = "Dcedilla", + [0x1E11] = "dcedilla", + [0x1E12] = "Dcircumflexbelow", + [0x1E13] = "dcircumflexbelow", + [0x1E14] = "Emacrongrave", + [0x1E15] = "emacrongrave", + [0x1E16] = "Emacronacute", + [0x1E17] = "emacronacute", + [0x1E18] = "Ecircumflexbelow", + [0x1E19] = "ecircumflexbelow", + [0x1E1A] = "Etildebelow", + [0x1E1B] = "etildebelow", + [0x1E1C] = "Ecedillabreve", + [0x1E1D] = "ecedillabreve", + [0x1E1E] = "Fdotaccent", + [0x1E1F] = "fdotaccent", + [0x1E20] = "Gmacron", + [0x1E21] = "gmacron", + [0x1E22] = "Hdotaccent", + [0x1E23] = "hdotaccent", + [0x1E24] = "Hdotbelow", + [0x1E25] = "hdotbelow", + [0x1E26] = "Hdieresis", + [0x1E27] = "hdieresis", + [0x1E28] = "Hcedilla", + [0x1E29] = "hcedilla", + [0x1E2A] = "Hbrevebelow", + [0x1E2B] = "hbrevebelow", + [0x1E2C] = "Itildebelow", + [0x1E2D] = "itildebelow", + [0x1E2E] = "Idieresisacute", + [0x1E2F] = "idieresisacute", + [0x1E30] = "Kacute", + [0x1E31] = "kacute", + [0x1E32] = "Kdotbelow", + [0x1E33] = "kdotbelow", + [0x1E34] = "Klinebelow", + [0x1E35] = "klinebelow", + [0x1E36] = "Ldotbelow", + [0x1E37] = "ldotbelow", + [0x1E38] = "Ldotbelowmacron", + [0x1E39] = "ldotbelowmacron", + [0x1E3A] = "Llinebelow", + [0x1E3B] = "llinebelow", + [0x1E3C] = "Lcircumflexbelow", + [0x1E3D] = "lcircumflexbelow", + [0x1E3E] = "Macute", + [0x1E3F] = "macute", + [0x1E40] = "Mdotaccent", + [0x1E41] = "mdotaccent", + [0x1E42] = "Mdotbelow", + [0x1E43] = "mdotbelow", + [0x1E44] = "Ndotaccent", + [0x1E45] = "ndotaccent", + [0x1E46] = "Ndotbelow", + [0x1E47] = "ndotbelow", + [0x1E48] = "Nlinebelow", + [0x1E49] = "nlinebelow", + [0x1E4A] = "Ncircumflexbelow", + [0x1E4B] = "ncircumflexbelow", + [0x1E4C] = "Otildeacute", + [0x1E4D] = "otildeacute", + [0x1E4E] = "Otildedieresis", + [0x1E4F] = "otildedieresis", + [0x1E50] = "Omacrongrave", + [0x1E51] = "omacrongrave", + [0x1E52] = "Omacronacute", + [0x1E53] = "omacronacute", + [0x1E54] = "Pacute", + [0x1E55] = "pacute", + [0x1E56] = "Pdotaccent", + [0x1E57] = "pdotaccent", + [0x1E58] = "Rdotaccent", + [0x1E59] = "rdotaccent", + [0x1E5A] = "Rdotbelow", + [0x1E5B] = "rdotbelow", + [0x1E5C] = "Rdotbelowmacron", + [0x1E5D] = "rdotbelowmacron", + [0x1E5E] = "Rlinebelow", + [0x1E5F] = "rlinebelow", + [0x1E60] = "Sdotaccent", + [0x1E61] = "sdotaccent", + [0x1E62] = "Sdotbelow", + [0x1E63] = "sdotbelow", + [0x1E64] = "Sacutedotaccent", + [0x1E65] = "sacutedotaccent", + [0x1E66] = "Scarondotaccent", + [0x1E67] = "scarondotaccent", + [0x1E68] = "Sdotbelowdotaccent", + [0x1E69] = "sdotbelowdotaccent", + [0x1E6A] = "Tdotaccent", + [0x1E6B] = "tdotaccent", + [0x1E6C] = "Tdotbelow", + [0x1E6D] = "tdotbelow", + [0x1E6E] = "Tlinebelow", + [0x1E6F] = "tlinebelow", + [0x1E70] = "Tcircumflexbelow", + [0x1E71] = "tcircumflexbelow", + [0x1E72] = "Udieresisbelow", + [0x1E73] = "udieresisbelow", + [0x1E74] = "Utildebelow", + [0x1E75] = "utildebelow", + [0x1E76] = "Ucircumflexbelow", + [0x1E77] = "ucircumflexbelow", + [0x1E78] = "Utildeacute", + [0x1E79] = "utildeacute", + [0x1E7A] = "Umacrondieresis", + [0x1E7B] = "umacrondieresis", + [0x1E7C] = "Vtilde", + [0x1E7D] = "vtilde", + [0x1E7E] = "Vdotbelow", + [0x1E7F] = "vdotbelow", + [0x1E80] = "Wgrave", + [0x1E81] = "wgrave", + [0x1E82] = "Wacute", + [0x1E83] = "wacute", + [0x1E84] = "Wdieresis", + [0x1E85] = "wdieresis", + [0x1E86] = "Wdotaccent", + [0x1E87] = "wdotaccent", + [0x1E88] = "Wdotbelow", + [0x1E89] = "wdotbelow", + [0x1E8A] = "Xdotaccent", + [0x1E8B] = "xdotaccent", + [0x1E8C] = "Xdieresis", + [0x1E8D] = "xdieresis", + [0x1E8E] = "Ydotaccent", + [0x1E8F] = "ydotaccent", + [0x1E90] = "Zcircumflex", + [0x1E91] = "zcircumflex", + [0x1E92] = "Zdotbelow", + [0x1E93] = "zdotbelow", + [0x1E94] = "Zlinebelow", + [0x1E95] = "zlinebelow", + [0x1E96] = "hlinebelow", + [0x1E97] = "tdieresis", + [0x1E98] = "wring", + [0x1E99] = "yring", + [0x1E9A] = "arighthalfring", + [0x1E9B] = "slongdotaccent", + [0x1EA0] = "Adotbelow", + [0x1EA1] = "adotbelow", + [0x1EA2] = "Ahookabove", + [0x1EA3] = "ahookabove", + [0x1EA4] = "Acircumflexacute", + [0x1EA5] = "acircumflexacute", + [0x1EA6] = "Acircumflexgrave", + [0x1EA7] = "acircumflexgrave", + [0x1EA8] = "Acircumflexhookabove", + [0x1EA9] = "acircumflexhookabove", + [0x1EAA] = "Acircumflextilde", + [0x1EAB] = "acircumflextilde", + [0x1EAC] = "Acircumflexdotbelow", + [0x1EAD] = "acircumflexdotbelow", + [0x1EAE] = "Abreveacute", + [0x1EAF] = "abreveacute", + [0x1EB0] = "Abrevegrave", + [0x1EB1] = "abrevegrave", + [0x1EB2] = "Abrevehookabove", + [0x1EB3] = "abrevehookabove", + [0x1EB4] = "Abrevetilde", + [0x1EB5] = "abrevetilde", + [0x1EB6] = "Abrevedotbelow", + [0x1EB7] = "abrevedotbelow", + [0x1EB8] = "Edotbelow", + [0x1EB9] = "edotbelow", + [0x1EBA] = "Ehookabove", + [0x1EBB] = "ehookabove", + [0x1EBC] = "Etilde", + [0x1EBD] = "etilde", + [0x1EBE] = "Ecircumflexacute", + [0x1EBF] = "ecircumflexacute", + [0x1EC0] = "Ecircumflexgrave", + [0x1EC1] = "ecircumflexgrave", + [0x1EC2] = "Ecircumflexhookabove", + [0x1EC3] = "ecircumflexhookabove", + [0x1EC4] = "Ecircumflextilde", + [0x1EC5] = "ecircumflextilde", + [0x1EC6] = "Ecircumflexdotbelow", + [0x1EC7] = "ecircumflexdotbelow", + [0x1EC8] = "Ihookabove", + [0x1EC9] = "ihookabove", + [0x1ECA] = "Idotbelow", + [0x1ECB] = "idotbelow", + [0x1ECC] = "Odotbelow", + [0x1ECD] = "odotbelow", + [0x1ECE] = "Ohookabove", + [0x1ECF] = "ohookabove", + [0x1ED0] = "Ocircumflexacute", + [0x1ED1] = "ocircumflexacute", + [0x1ED2] = "Ocircumflexgrave", + [0x1ED3] = "ocircumflexgrave", + [0x1ED4] = "Ocircumflexhookabove", + [0x1ED5] = "ocircumflexhookabove", + [0x1ED6] = "Ocircumflextilde", + [0x1ED7] = "ocircumflextilde", + [0x1ED8] = "Ocircumflexdotbelow", + [0x1ED9] = "ocircumflexdotbelow", + [0x1EDA] = "Ohornacute", + [0x1EDB] = "ohornacute", + [0x1EDC] = "Ohorngrave", + [0x1EDD] = "ohorngrave", + [0x1EDE] = "Ohornhookabove", + [0x1EDF] = "ohornhookabove", + [0x1EE0] = "Ohorntilde", + [0x1EE1] = "ohorntilde", + [0x1EE2] = "Ohorndotbelow", + [0x1EE3] = "ohorndotbelow", + [0x1EE4] = "Udotbelow", + [0x1EE5] = "udotbelow", + [0x1EE6] = "Uhookabove", + [0x1EE7] = "uhookabove", + [0x1EE8] = "Uhornacute", + [0x1EE9] = "uhornacute", + [0x1EEA] = "Uhorngrave", + [0x1EEB] = "uhorngrave", + [0x1EEC] = "Uhornhookabove", + [0x1EED] = "uhornhookabove", + [0x1EEE] = "Uhorntilde", + [0x1EEF] = "uhorntilde", + [0x1EF0] = "Uhorndotbelow", + [0x1EF1] = "uhorndotbelow", + [0x1EF2] = "Ygrave", + [0x1EF3] = "ygrave", + [0x1EF4] = "Ydotbelow", + [0x1EF5] = "ydotbelow", + [0x1EF6] = "Yhookabove", + [0x1EF7] = "yhookabove", + [0x1EF8] = "Ytilde", + [0x1EF9] = "ytilde", + [0x2002] = "enspace", + [0x200B] = "zerowidthspace", + [0x200C] = "zerowidthnonjoiner", + [0x200D] = "afii301", + [0x200E] = "afii299", + [0x200F] = "afii300", + [0x2010] = "hyphentwo", + [0x2012] = "figuredash", + [0x2013] = "endash", + [0x2014] = "emdash", + [0x2015] = "horizontalbar", + [0x2016] = "dblverticalbar", + [0x2017] = "underscoredbl", + [0x2018] = "quoteleft", + [0x2019] = "quoteright", + [0x201A] = "quotesinglbase", + [0x201B] = "quotereversed", + [0x201C] = "quotedblleft", + [0x201D] = "quotedblright", + [0x201E] = "quotedblbase", + [0x2020] = "dagger", + [0x2021] = "daggerdbl", + [0x2022] = "bullet", + [0x2024] = "onedotenleader", + [0x2025] = "twodotleader", + [0x2026] = "ellipsis", + [0x202C] = "afii61573", + [0x202D] = "afii61574", + [0x202E] = "afii61575", + [0x2030] = "perthousand", + [0x2032] = "minute", + [0x2033] = "second", + [0x2035] = "primereversed", + [0x2039] = "guilsinglleft", + [0x203A] = "guilsinglright", + [0x203B] = "referencemark", + [0x203C] = "exclamdbl", + [0x203E] = "overline", + [0x2042] = "asterism", + [0x2044] = "fraction", + [0x2070] = "zerosuperior", + [0x2074] = "foursuperior", + [0x2075] = "fivesuperior", + [0x2076] = "sixsuperior", + [0x2077] = "sevensuperior", + [0x2078] = "eightsuperior", + [0x2079] = "ninesuperior", + [0x207A] = "plussuperior", + [0x207C] = "equalsuperior", + [0x207D] = "parenleftsuperior", + [0x207E] = "parenrightsuperior", + [0x207F] = "nsuperior", + [0x2080] = "zeroinferior", + [0x2081] = "oneinferior", + [0x2082] = "twoinferior", + [0x2083] = "threeinferior", + [0x2084] = "fourinferior", + [0x2085] = "fiveinferior", + [0x2086] = "sixinferior", + [0x2087] = "seveninferior", + [0x2088] = "eightinferior", + [0x2089] = "nineinferior", + [0x208D] = "parenleftinferior", + [0x208E] = "parenrightinferior", + [0x20A1] = "colonsign", + [0x20A2] = "cruzeiro", + [0x20A3] = "franc", + [0x20A4] = "lira", + [0x20A7] = "peseta", + [0x20A9] = "won", + [0x20AA] = "sheqelhebrew", + [0x20AB] = "dong", + [0x20AC] = "euro", + [0x2103] = "centigrade", + [0x2105] = "careof", + [0x2109] = "fahrenheit", + [0x2111] = "Ifraktur", + [0x2113] = "lsquare", + [0x2116] = "numero", + [0x2118] = "weierstrass", + [0x211C] = "Rfraktur", + [0x211E] = "prescription", + [0x2121] = "telephone", + [0x2122] = "trademark", + [0x2126] = "Omega", + [0x212B] = "angstrom", + [0x212E] = "estimated", + [0x2135] = "aleph", + [0x2153] = "onethird", + [0x2154] = "twothirds", + [0x215B] = "oneeighth", + [0x215C] = "threeeighths", + [0x215D] = "fiveeighths", + [0x215E] = "seveneighths", + [0x2160] = "Oneroman", + [0x2161] = "Tworoman", + [0x2162] = "Threeroman", + [0x2163] = "Fourroman", + [0x2164] = "Fiveroman", + [0x2165] = "Sixroman", + [0x2166] = "Sevenroman", + [0x2167] = "Eightroman", + [0x2168] = "Nineroman", + [0x2169] = "Tenroman", + [0x216A] = "Elevenroman", + [0x216B] = "Twelveroman", + [0x2170] = "oneroman", + [0x2171] = "tworoman", + [0x2172] = "threeroman", + [0x2173] = "fourroman", + [0x2174] = "fiveroman", + [0x2175] = "sixroman", + [0x2176] = "sevenroman", + [0x2177] = "eightroman", + [0x2178] = "nineroman", + [0x2179] = "tenroman", + [0x217A] = "elevenroman", + [0x217B] = "twelveroman", + [0x2190] = "arrowleft", + [0x2191] = "arrowup", + [0x2192] = "arrowright", + [0x2193] = "arrowdown", + [0x2194] = "arrowboth", + [0x2195] = "arrowupdn", + [0x2196] = "arrowupleft", + [0x2197] = "arrowupright", + [0x2198] = "arrowdownright", + [0x2199] = "arrowdownleft", + [0x21A8] = "arrowupdownbase", + [0x21B5] = "carriagereturn", + [0x21BC] = "harpoonleftbarbup", + [0x21C0] = "harpoonrightbarbup", + [0x21C4] = "arrowrightoverleft", + [0x21C5] = "arrowupleftofdown", + [0x21C6] = "arrowleftoverright", + [0x21CD] = "arrowleftdblstroke", + [0x21CF] = "arrowrightdblstroke", + [0x21D0] = "arrowleftdbl", + [0x21D1] = "arrowdblup", + [0x21D2] = "dblarrowright", + [0x21D3] = "arrowdbldown", + [0x21D4] = "dblarrowleft", + [0x21DE] = "pageup", + [0x21DF] = "pagedown", + [0x21E0] = "arrowdashleft", + [0x21E1] = "arrowdashup", + [0x21E2] = "arrowdashright", + [0x21E3] = "arrowdashdown", + [0x21E4] = "arrowtableft", + [0x21E5] = "arrowtabright", + [0x21E6] = "arrowleftwhite", + [0x21E7] = "arrowupwhite", + [0x21E8] = "arrowrightwhite", + [0x21E9] = "arrowdownwhite", + [0x21EA] = "capslock", + [0x2200] = "universal", + [0x2202] = "partialdiff", + [0x2203] = "thereexists", + [0x2205] = "emptyset", + [0x2206] = "increment", + [0x2207] = "nabla", + [0x2208] = "element", + [0x2209] = "notelementof", + [0x220B] = "suchthat", + [0x220C] = "notcontains", + [0x220F] = "product", + [0x2211] = "summation", + [0x2212] = "minus", + [0x2213] = "minusplus", + [0x2215] = "divisionslash", + [0x2217] = "asteriskmath", + [0x2219] = "bulletoperator", + [0x221A] = "radical", + [0x221D] = "proportional", + [0x221E] = "infinity", + [0x221F] = "rightangle", + [0x2220] = "angle", + [0x2223] = "divides", + [0x2225] = "parallel", + [0x2226] = "notparallel", + [0x2227] = "logicaland", + [0x2228] = "logicalor", + [0x2229] = "intersection", + [0x222A] = "union", + [0x222B] = "integral", + [0x222C] = "dblintegral", + [0x222E] = "contourintegral", + [0x2234] = "therefore", + [0x2235] = "because", + [0x2236] = "ratio", + [0x2237] = "proportion", + [0x223C] = "tildeoperator", + [0x223D] = "reversedtilde", + [0x2243] = "asymptoticallyequal", + [0x2245] = "congruent", + [0x2248] = "approxequal", + [0x224C] = "allequal", + [0x2250] = "approaches", + [0x2251] = "geometricallyequal", + [0x2252] = "approxequalorimage", + [0x2253] = "imageorapproximatelyequal", + [0x2260] = "notequal", + [0x2261] = "equivalence", + [0x2262] = "notidentical", + [0x2264] = "lessequal", + [0x2265] = "greaterequal", + [0x2266] = "lessoverequal", + [0x2267] = "greateroverequal", + [0x226A] = "muchless", + [0x226B] = "muchgreater", + [0x226E] = "notless", + [0x226F] = "notgreater", + [0x2270] = "notlessnorequal", + [0x2271] = "notgreaternorequal", + [0x2272] = "lessorequivalent", + [0x2273] = "greaterorequivalent", + [0x2276] = "lessorgreater", + [0x2277] = "greaterorless", + [0x2279] = "notgreaternorless", + [0x227A] = "precedes", + [0x227B] = "succeeds", + [0x2280] = "notprecedes", + [0x2281] = "notsucceeds", + [0x2282] = "subset", + [0x2283] = "superset", + [0x2284] = "notsubset", + [0x2285] = "notsuperset", + [0x2286] = "subsetorequal", + [0x2287] = "supersetorequal", + [0x228A] = "subsetnotequal", + [0x228B] = "supersetnotequal", + [0x2295] = "pluscircle", + [0x2296] = "minuscircle", + [0x2297] = "timescircle", + [0x2299] = "circleot", + [0x22A3] = "tackleft", + [0x22A4] = "tackdown", + [0x22A5] = "perpendicular", + [0x22BF] = "righttriangle", + [0x22C5] = "dotmath", + [0x22CE] = "curlyor", + [0x22CF] = "curlyand", + [0x22DA] = "lessequalorgreater", + [0x22DB] = "greaterequalorless", + [0x22EE] = "ellipsisvertical", + [0x2302] = "house", + [0x2303] = "control", + [0x2305] = "projective", + [0x2310] = "revlogicalnot", + [0x2312] = "arc", + [0x2318] = "propellor", + [0x2320] = "integraltp", + [0x2321] = "integralbt", + [0x2325] = "option", + [0x2326] = "deleteright", + [0x2327] = "clear", + [0x2329] = "angleleft", + [0x232A] = "angleright", + [0x232B] = "deleteleft", + [0x2423] = "blank", + [0x2460] = "onecircle", + [0x2461] = "twocircle", + [0x2462] = "threecircle", + [0x2463] = "fourcircle", + [0x2464] = "fivecircle", + [0x2465] = "sixcircle", + [0x2466] = "sevencircle", + [0x2467] = "eightcircle", + [0x2468] = "ninecircle", + [0x2469] = "tencircle", + [0x246A] = "elevencircle", + [0x246B] = "twelvecircle", + [0x246C] = "thirteencircle", + [0x246D] = "fourteencircle", + [0x246E] = "fifteencircle", + [0x246F] = "sixteencircle", + [0x2470] = "seventeencircle", + [0x2471] = "eighteencircle", + [0x2472] = "nineteencircle", + [0x2473] = "twentycircle", + [0x2474] = "oneparen", + [0x2475] = "twoparen", + [0x2476] = "threeparen", + [0x2477] = "fourparen", + [0x2478] = "fiveparen", + [0x2479] = "sixparen", + [0x247A] = "sevenparen", + [0x247B] = "eightparen", + [0x247C] = "nineparen", + [0x247D] = "tenparen", + [0x247E] = "elevenparen", + [0x247F] = "twelveparen", + [0x2480] = "thirteenparen", + [0x2481] = "fourteenparen", + [0x2482] = "fifteenparen", + [0x2483] = "sixteenparen", + [0x2484] = "seventeenparen", + [0x2485] = "eighteenparen", + [0x2486] = "nineteenparen", + [0x2487] = "twentyparen", + [0x2488] = "oneperiod", + [0x2489] = "twoperiod", + [0x248A] = "threeperiod", + [0x248B] = "fourperiod", + [0x248C] = "fiveperiod", + [0x248D] = "sixperiod", + [0x248E] = "sevenperiod", + [0x248F] = "eightperiod", + [0x2490] = "nineperiod", + [0x2491] = "tenperiod", + [0x2492] = "elevenperiod", + [0x2493] = "twelveperiod", + [0x2494] = "thirteenperiod", + [0x2495] = "fourteenperiod", + [0x2496] = "fifteenperiod", + [0x2497] = "sixteenperiod", + [0x2498] = "seventeenperiod", + [0x2499] = "eighteenperiod", + [0x249A] = "nineteenperiod", + [0x249B] = "twentyperiod", + [0x249C] = "aparen", + [0x249D] = "bparen", + [0x249E] = "cparen", + [0x249F] = "dparen", + [0x24A0] = "eparen", + [0x24A1] = "fparen", + [0x24A2] = "gparen", + [0x24A3] = "hparen", + [0x24A4] = "iparen", + [0x24A5] = "jparen", + [0x24A6] = "kparen", + [0x24A7] = "lparen", + [0x24A8] = "mparen", + [0x24A9] = "nparen", + [0x24AA] = "oparen", + [0x24AB] = "pparen", + [0x24AC] = "qparen", + [0x24AD] = "rparen", + [0x24AE] = "sparen", + [0x24AF] = "tparen", + [0x24B0] = "uparen", + [0x24B1] = "vparen", + [0x24B2] = "wparen", + [0x24B3] = "xparen", + [0x24B4] = "yparen", + [0x24B5] = "zparen", + [0x24B6] = "Acircle", + [0x24B7] = "Bcircle", + [0x24B8] = "Ccircle", + [0x24B9] = "Dcircle", + [0x24BA] = "Ecircle", + [0x24BB] = "Fcircle", + [0x24BC] = "Gcircle", + [0x24BD] = "Hcircle", + [0x24BE] = "Icircle", + [0x24BF] = "Jcircle", + [0x24C0] = "Kcircle", + [0x24C1] = "Lcircle", + [0x24C2] = "Mcircle", + [0x24C3] = "Ncircle", + [0x24C4] = "Ocircle", + [0x24C5] = "Pcircle", + [0x24C6] = "Qcircle", + [0x24C7] = "Rcircle", + [0x24C8] = "Scircle", + [0x24C9] = "Tcircle", + [0x24CA] = "Ucircle", + [0x24CB] = "Vcircle", + [0x24CC] = "Wcircle", + [0x24CD] = "Xcircle", + [0x24CE] = "Ycircle", + [0x24CF] = "Zcircle", + [0x24D0] = "acircle", + [0x24D1] = "bcircle", + [0x24D2] = "ccircle", + [0x24D3] = "dcircle", + [0x24D4] = "ecircle", + [0x24D5] = "fcircle", + [0x24D6] = "gcircle", + [0x24D7] = "hcircle", + [0x24D8] = "icircle", + [0x24D9] = "jcircle", + [0x24DA] = "kcircle", + [0x24DB] = "lcircle", + [0x24DC] = "mcircle", + [0x24DD] = "ncircle", + [0x24DE] = "ocircle", + [0x24DF] = "pcircle", + [0x24E0] = "qcircle", + [0x24E1] = "rcircle", + [0x24E2] = "scircle", + [0x24E3] = "tcircle", + [0x24E4] = "ucircle", + [0x24E5] = "vcircle", + [0x24E6] = "wcircle", + [0x24E7] = "xcircle", + [0x24E8] = "ycircle", + [0x24E9] = "zcircle", + [0x2500] = "SF100000", + [0x2502] = "SF110000", + [0x250C] = "SF010000", + [0x2510] = "SF030000", + [0x2514] = "SF020000", + [0x2518] = "SF040000", + [0x251C] = "SF080000", + [0x2524] = "SF090000", + [0x252C] = "SF060000", + [0x2534] = "SF070000", + [0x253C] = "SF050000", + [0x2550] = "SF430000", + [0x2551] = "SF240000", + [0x2552] = "SF510000", + [0x2553] = "SF520000", + [0x2554] = "SF390000", + [0x2555] = "SF220000", + [0x2556] = "SF210000", + [0x2557] = "SF250000", + [0x2558] = "SF500000", + [0x2559] = "SF490000", + [0x255A] = "SF380000", + [0x255B] = "SF280000", + [0x255C] = "SF270000", + [0x255D] = "SF260000", + [0x255E] = "SF360000", + [0x255F] = "SF370000", + [0x2560] = "SF420000", + [0x2561] = "SF190000", + [0x2562] = "SF200000", + [0x2563] = "SF230000", + [0x2564] = "SF470000", + [0x2565] = "SF480000", + [0x2566] = "SF410000", + [0x2567] = "SF450000", + [0x2568] = "SF460000", + [0x2569] = "SF400000", + [0x256A] = "SF540000", + [0x256B] = "SF530000", + [0x256C] = "SF440000", + [0x2580] = "upblock", + [0x2584] = "dnblock", + [0x2588] = "block", + [0x258C] = "lfblock", + [0x2590] = "rtblock", + [0x2591] = "shadelight", + [0x2592] = "shademedium", + [0x2593] = "shadedark", + [0x25A0] = "filledbox", + [0x25A1] = "whitesquare", + [0x25A3] = "squarewhitewithsmallblack", + [0x25A4] = "squarehorizontalfill", + [0x25A5] = "squareverticalfill", + [0x25A6] = "squareorthogonalcrosshatchfill", + [0x25A7] = "squareupperlefttolowerrightfill", + [0x25A8] = "squareupperrighttolowerleftfill", + [0x25A9] = "squarediagonalcrosshatchfill", + [0x25AA] = "blacksmallsquare", + [0x25AB] = "whitesmallsquare", + [0x25AC] = "filledrect", + [0x25B2] = "triagup", + [0x25B3] = "whiteuppointingtriangle", + [0x25B4] = "blackuppointingsmalltriangle", + [0x25B5] = "whiteuppointingsmalltriangle", + [0x25B6] = "blackrightpointingtriangle", + [0x25B7] = "whiterightpointingtriangle", + [0x25B9] = "whiterightpointingsmalltriangle", + [0x25BA] = "triagrt", + [0x25BC] = "triagdn", + [0x25BD] = "whitedownpointingtriangle", + [0x25BF] = "whitedownpointingsmalltriangle", + [0x25C0] = "blackleftpointingtriangle", + [0x25C1] = "whiteleftpointingtriangle", + [0x25C3] = "whiteleftpointingsmalltriangle", + [0x25C4] = "triaglf", + [0x25C6] = "blackdiamond", + [0x25C7] = "whitediamond", + [0x25C8] = "whitediamondcontainingblacksmalldiamond", + [0x25C9] = "fisheye", + [0x25CA] = "lozenge", + [0x25CB] = "whitecircle", + [0x25CC] = "dottedcircle", + [0x25CE] = "bullseye", + [0x25CF] = "blackcircle", + [0x25D0] = "circlewithlefthalfblack", + [0x25D1] = "circlewithrighthalfblack", + [0x25D8] = "invbullet", + [0x25D9] = "whitecircleinverse", + [0x25E2] = "blacklowerrighttriangle", + [0x25E3] = "blacklowerlefttriangle", + [0x25E4] = "blackupperlefttriangle", + [0x25E5] = "blackupperrighttriangle", + [0x25E6] = "whitebullet", + [0x25EF] = "largecircle", + [0x2605] = "blackstar", + [0x2606] = "whitestar", + [0x260E] = "telephoneblack", + [0x260F] = "whitetelephone", + [0x261C] = "pointingindexleftwhite", + [0x261D] = "pointingindexupwhite", + [0x261E] = "pointingindexrightwhite", + [0x261F] = "pointingindexdownwhite", + [0x262F] = "yinyang", + [0x263A] = "whitesmilingface", + [0x263B] = "invsmileface", + [0x263C] = "sun", + [0x2640] = "venus", + [0x2641] = "earth", + [0x2642] = "mars", + [0x2660] = "spadesuitblack", + [0x2661] = "heartsuitwhite", + [0x2662] = "diamondsuitwhite", + [0x2663] = "clubsuitblack", + [0x2664] = "spadesuitwhite", + [0x2665] = "heartsuitblack", + [0x2666] = "diamond", + [0x2667] = "clubsuitwhite", + [0x2668] = "hotsprings", + [0x2669] = "quarternote", + [0x266A] = "musicalnote", + [0x266B] = "musicalnotedbl", + [0x266C] = "beamedsixteenthnotes", + [0x266D] = "musicflatsign", + [0x266F] = "musicsharpsign", + [0x2713] = "checkmark", + [0x278A] = "onecircleinversesansserif", + [0x278B] = "twocircleinversesansserif", + [0x278C] = "threecircleinversesansserif", + [0x278D] = "fourcircleinversesansserif", + [0x278E] = "fivecircleinversesansserif", + [0x278F] = "sixcircleinversesansserif", + [0x2790] = "sevencircleinversesansserif", + [0x2791] = "eightcircleinversesansserif", + [0x2792] = "ninecircleinversesansserif", + [0x279E] = "arrowrightheavy", + [0x3000] = "ideographicspace", + [0x3001] = "ideographiccomma", + [0x3002] = "ideographicperiod", + [0x3003] = "dittomark", + [0x3004] = "jis", + [0x3005] = "ideographiciterationmark", + [0x3006] = "ideographicclose", + [0x3007] = "ideographiczero", + [0x3008] = "anglebracketleft", + [0x3009] = "anglebracketright", + [0x300A] = "dblanglebracketleft", + [0x300B] = "dblanglebracketright", + [0x300C] = "cornerbracketleft", + [0x300D] = "cornerbracketright", + [0x300E] = "whitecornerbracketleft", + [0x300F] = "whitecornerbracketright", + [0x3010] = "blacklenticularbracketleft", + [0x3011] = "blacklenticularbracketright", + [0x3012] = "postalmark", + [0x3013] = "getamark", + [0x3014] = "tortoiseshellbracketleft", + [0x3015] = "tortoiseshellbracketright", + [0x3016] = "whitelenticularbracketleft", + [0x3017] = "whitelenticularbracketright", + [0x3018] = "whitetortoiseshellbracketleft", + [0x3019] = "whitetortoiseshellbracketright", + [0x301C] = "wavedash", + [0x301D] = "quotedblprimereversed", + [0x301E] = "quotedblprime", + [0x3020] = "postalmarkface", + [0x3021] = "onehangzhou", + [0x3022] = "twohangzhou", + [0x3023] = "threehangzhou", + [0x3024] = "fourhangzhou", + [0x3025] = "fivehangzhou", + [0x3026] = "sixhangzhou", + [0x3027] = "sevenhangzhou", + [0x3028] = "eighthangzhou", + [0x3029] = "ninehangzhou", + [0x3036] = "circlepostalmark", + [0x3041] = "asmallhiragana", + [0x3042] = "ahiragana", + [0x3043] = "ismallhiragana", + [0x3044] = "ihiragana", + [0x3045] = "usmallhiragana", + [0x3046] = "uhiragana", + [0x3047] = "esmallhiragana", + [0x3048] = "ehiragana", + [0x3049] = "osmallhiragana", + [0x304A] = "ohiragana", + [0x304B] = "kahiragana", + [0x304C] = "gahiragana", + [0x304D] = "kihiragana", + [0x304E] = "gihiragana", + [0x304F] = "kuhiragana", + [0x3050] = "guhiragana", + [0x3051] = "kehiragana", + [0x3052] = "gehiragana", + [0x3053] = "kohiragana", + [0x3054] = "gohiragana", + [0x3055] = "sahiragana", + [0x3056] = "zahiragana", + [0x3057] = "sihiragana", + [0x3058] = "zihiragana", + [0x3059] = "suhiragana", + [0x305A] = "zuhiragana", + [0x305B] = "sehiragana", + [0x305C] = "zehiragana", + [0x305D] = "sohiragana", + [0x305E] = "zohiragana", + [0x305F] = "tahiragana", + [0x3060] = "dahiragana", + [0x3061] = "tihiragana", + [0x3062] = "dihiragana", + [0x3063] = "tusmallhiragana", + [0x3064] = "tuhiragana", + [0x3065] = "duhiragana", + [0x3066] = "tehiragana", + [0x3067] = "dehiragana", + [0x3068] = "tohiragana", + [0x3069] = "dohiragana", + [0x306A] = "nahiragana", + [0x306B] = "nihiragana", + [0x306C] = "nuhiragana", + [0x306D] = "nehiragana", + [0x306E] = "nohiragana", + [0x306F] = "hahiragana", + [0x3070] = "bahiragana", + [0x3071] = "pahiragana", + [0x3072] = "hihiragana", + [0x3073] = "bihiragana", + [0x3074] = "pihiragana", + [0x3075] = "huhiragana", + [0x3076] = "buhiragana", + [0x3077] = "puhiragana", + [0x3078] = "hehiragana", + [0x3079] = "behiragana", + [0x307A] = "pehiragana", + [0x307B] = "hohiragana", + [0x307C] = "bohiragana", + [0x307D] = "pohiragana", + [0x307E] = "mahiragana", + [0x307F] = "mihiragana", + [0x3080] = "muhiragana", + [0x3081] = "mehiragana", + [0x3082] = "mohiragana", + [0x3083] = "yasmallhiragana", + [0x3084] = "yahiragana", + [0x3085] = "yusmallhiragana", + [0x3086] = "yuhiragana", + [0x3087] = "yosmallhiragana", + [0x3088] = "yohiragana", + [0x3089] = "rahiragana", + [0x308A] = "rihiragana", + [0x308B] = "ruhiragana", + [0x308C] = "rehiragana", + [0x308D] = "rohiragana", + [0x308E] = "wasmallhiragana", + [0x308F] = "wahiragana", + [0x3090] = "wihiragana", + [0x3091] = "wehiragana", + [0x3092] = "wohiragana", + [0x3093] = "nhiragana", + [0x3094] = "vuhiragana", + [0x309B] = "voicedmarkkana", + [0x309C] = "semivoicedmarkkana", + [0x309D] = "iterationhiragana", + [0x309E] = "voicediterationhiragana", + [0x30A1] = "asmallkatakana", + [0x30A2] = "akatakana", + [0x30A3] = "ismallkatakana", + [0x30A4] = "ikatakana", + [0x30A5] = "usmallkatakana", + [0x30A6] = "ukatakana", + [0x30A7] = "esmallkatakana", + [0x30A8] = "ekatakana", + [0x30A9] = "osmallkatakana", + [0x30AA] = "okatakana", + [0x30AB] = "kakatakana", + [0x30AC] = "gakatakana", + [0x30AD] = "kikatakana", + [0x30AE] = "gikatakana", + [0x30AF] = "kukatakana", + [0x30B0] = "gukatakana", + [0x30B1] = "kekatakana", + [0x30B2] = "gekatakana", + [0x30B3] = "kokatakana", + [0x30B4] = "gokatakana", + [0x30B5] = "sakatakana", + [0x30B6] = "zakatakana", + [0x30B7] = "sikatakana", + [0x30B8] = "zikatakana", + [0x30B9] = "sukatakana", + [0x30BA] = "zukatakana", + [0x30BB] = "sekatakana", + [0x30BC] = "zekatakana", + [0x30BD] = "sokatakana", + [0x30BE] = "zokatakana", + [0x30BF] = "takatakana", + [0x30C0] = "dakatakana", + [0x30C1] = "tikatakana", + [0x30C2] = "dikatakana", + [0x30C3] = "tusmallkatakana", + [0x30C4] = "tukatakana", + [0x30C5] = "dukatakana", + [0x30C6] = "tekatakana", + [0x30C7] = "dekatakana", + [0x30C8] = "tokatakana", + [0x30C9] = "dokatakana", + [0x30CA] = "nakatakana", + [0x30CB] = "nikatakana", + [0x30CC] = "nukatakana", + [0x30CD] = "nekatakana", + [0x30CE] = "nokatakana", + [0x30CF] = "hakatakana", + [0x30D0] = "bakatakana", + [0x30D1] = "pakatakana", + [0x30D2] = "hikatakana", + [0x30D3] = "bikatakana", + [0x30D4] = "pikatakana", + [0x30D5] = "hukatakana", + [0x30D6] = "bukatakana", + [0x30D7] = "pukatakana", + [0x30D8] = "hekatakana", + [0x30D9] = "bekatakana", + [0x30DA] = "pekatakana", + [0x30DB] = "hokatakana", + [0x30DC] = "bokatakana", + [0x30DD] = "pokatakana", + [0x30DE] = "makatakana", + [0x30DF] = "mikatakana", + [0x30E0] = "mukatakana", + [0x30E1] = "mekatakana", + [0x30E2] = "mokatakana", + [0x30E3] = "yasmallkatakana", + [0x30E4] = "yakatakana", + [0x30E5] = "yusmallkatakana", + [0x30E6] = "yukatakana", + [0x30E7] = "yosmallkatakana", + [0x30E8] = "yokatakana", + [0x30E9] = "rakatakana", + [0x30EA] = "rikatakana", + [0x30EB] = "rukatakana", + [0x30EC] = "rekatakana", + [0x30ED] = "rokatakana", + [0x30EE] = "wasmallkatakana", + [0x30EF] = "wakatakana", + [0x30F0] = "wikatakana", + [0x30F1] = "wekatakana", + [0x30F2] = "wokatakana", + [0x30F3] = "nkatakana", + [0x30F4] = "vukatakana", + [0x30F5] = "kasmallkatakana", + [0x30F6] = "kesmallkatakana", + [0x30F7] = "vakatakana", + [0x30F8] = "vikatakana", + [0x30F9] = "vekatakana", + [0x30FA] = "vokatakana", + [0x30FB] = "dotkatakana", + [0x30FC] = "prolongedkana", + [0x30FD] = "iterationkatakana", + [0x30FE] = "voicediterationkatakana", + [0x3105] = "bbopomofo", + [0x3106] = "pbopomofo", + [0x3107] = "mbopomofo", + [0x3108] = "fbopomofo", + [0x3109] = "dbopomofo", + [0x310A] = "tbopomofo", + [0x310B] = "nbopomofo", + [0x310C] = "lbopomofo", + [0x310D] = "gbopomofo", + [0x310E] = "kbopomofo", + [0x310F] = "hbopomofo", + [0x3110] = "jbopomofo", + [0x3111] = "qbopomofo", + [0x3112] = "xbopomofo", + [0x3113] = "zhbopomofo", + [0x3114] = "chbopomofo", + [0x3115] = "shbopomofo", + [0x3116] = "rbopomofo", + [0x3117] = "zbopomofo", + [0x3118] = "cbopomofo", + [0x3119] = "sbopomofo", + [0x311A] = "abopomofo", + [0x311B] = "obopomofo", + [0x311C] = "ebopomofo", + [0x311D] = "ehbopomofo", + [0x311E] = "aibopomofo", + [0x311F] = "eibopomofo", + [0x3120] = "aubopomofo", + [0x3121] = "oubopomofo", + [0x3122] = "anbopomofo", + [0x3123] = "enbopomofo", + [0x3124] = "angbopomofo", + [0x3125] = "engbopomofo", + [0x3126] = "erbopomofo", + [0x3127] = "ibopomofo", + [0x3128] = "ubopomofo", + [0x3129] = "iubopomofo", + [0x3131] = "kiyeokkorean", + [0x3132] = "ssangkiyeokkorean", + [0x3133] = "kiyeoksioskorean", + [0x3134] = "nieunkorean", + [0x3135] = "nieuncieuckorean", + [0x3136] = "nieunhieuhkorean", + [0x3137] = "tikeutkorean", + [0x3138] = "ssangtikeutkorean", + [0x3139] = "rieulkorean", + [0x313A] = "rieulkiyeokkorean", + [0x313B] = "rieulmieumkorean", + [0x313C] = "rieulpieupkorean", + [0x313D] = "rieulsioskorean", + [0x313E] = "rieulthieuthkorean", + [0x313F] = "rieulphieuphkorean", + [0x3140] = "rieulhieuhkorean", + [0x3141] = "mieumkorean", + [0x3142] = "pieupkorean", + [0x3143] = "ssangpieupkorean", + [0x3144] = "pieupsioskorean", + [0x3145] = "sioskorean", + [0x3146] = "ssangsioskorean", + [0x3147] = "ieungkorean", + [0x3148] = "cieuckorean", + [0x3149] = "ssangcieuckorean", + [0x314A] = "chieuchkorean", + [0x314B] = "khieukhkorean", + [0x314C] = "thieuthkorean", + [0x314D] = "phieuphkorean", + [0x314E] = "hieuhkorean", + [0x314F] = "akorean", + [0x3150] = "aekorean", + [0x3151] = "yakorean", + [0x3152] = "yaekorean", + [0x3153] = "eokorean", + [0x3154] = "ekorean", + [0x3155] = "yeokorean", + [0x3156] = "yekorean", + [0x3157] = "okorean", + [0x3158] = "wakorean", + [0x3159] = "waekorean", + [0x315A] = "oekorean", + [0x315B] = "yokorean", + [0x315C] = "ukorean", + [0x315D] = "weokorean", + [0x315E] = "wekorean", + [0x315F] = "wikorean", + [0x3160] = "yukorean", + [0x3161] = "eukorean", + [0x3162] = "yikorean", + [0x3163] = "ikorean", + [0x3164] = "hangulfiller", + [0x3165] = "ssangnieunkorean", + [0x3166] = "nieuntikeutkorean", + [0x3167] = "nieunsioskorean", + [0x3168] = "nieunpansioskorean", + [0x3169] = "rieulkiyeoksioskorean", + [0x316A] = "rieultikeutkorean", + [0x316B] = "rieulpieupsioskorean", + [0x316C] = "rieulpansioskorean", + [0x316D] = "rieulyeorinhieuhkorean", + [0x316E] = "mieumpieupkorean", + [0x316F] = "mieumsioskorean", + [0x3170] = "mieumpansioskorean", + [0x3171] = "kapyeounmieumkorean", + [0x3172] = "pieupkiyeokkorean", + [0x3173] = "pieuptikeutkorean", + [0x3174] = "pieupsioskiyeokkorean", + [0x3175] = "pieupsiostikeutkorean", + [0x3176] = "pieupcieuckorean", + [0x3177] = "pieupthieuthkorean", + [0x3178] = "kapyeounpieupkorean", + [0x3179] = "kapyeounssangpieupkorean", + [0x317A] = "sioskiyeokkorean", + [0x317B] = "siosnieunkorean", + [0x317C] = "siostikeutkorean", + [0x317D] = "siospieupkorean", + [0x317E] = "sioscieuckorean", + [0x317F] = "pansioskorean", + [0x3180] = "ssangieungkorean", + [0x3181] = "yesieungkorean", + [0x3182] = "yesieungsioskorean", + [0x3183] = "yesieungpansioskorean", + [0x3184] = "kapyeounphieuphkorean", + [0x3185] = "ssanghieuhkorean", + [0x3186] = "yeorinhieuhkorean", + [0x3187] = "yoyakorean", + [0x3188] = "yoyaekorean", + [0x3189] = "yoikorean", + [0x318A] = "yuyeokorean", + [0x318B] = "yuyekorean", + [0x318C] = "yuikorean", + [0x318D] = "araeakorean", + [0x318E] = "araeaekorean", + [0x3200] = "kiyeokparenkorean", + [0x3201] = "nieunparenkorean", + [0x3202] = "tikeutparenkorean", + [0x3203] = "rieulparenkorean", + [0x3204] = "mieumparenkorean", + [0x3205] = "pieupparenkorean", + [0x3206] = "siosparenkorean", + [0x3207] = "ieungparenkorean", + [0x3208] = "cieucparenkorean", + [0x3209] = "chieuchparenkorean", + [0x320A] = "khieukhparenkorean", + [0x320B] = "thieuthparenkorean", + [0x320C] = "phieuphparenkorean", + [0x320D] = "hieuhparenkorean", + [0x320E] = "kiyeokaparenkorean", + [0x320F] = "nieunaparenkorean", + [0x3210] = "tikeutaparenkorean", + [0x3211] = "rieulaparenkorean", + [0x3212] = "mieumaparenkorean", + [0x3213] = "pieupaparenkorean", + [0x3214] = "siosaparenkorean", + [0x3215] = "ieungaparenkorean", + [0x3216] = "cieucaparenkorean", + [0x3217] = "chieuchaparenkorean", + [0x3218] = "khieukhaparenkorean", + [0x3219] = "thieuthaparenkorean", + [0x321A] = "phieuphaparenkorean", + [0x321B] = "hieuhaparenkorean", + [0x321C] = "cieucuparenkorean", + [0x3220] = "oneideographicparen", + [0x3221] = "twoideographicparen", + [0x3222] = "threeideographicparen", + [0x3223] = "fourideographicparen", + [0x3224] = "fiveideographicparen", + [0x3225] = "sixideographicparen", + [0x3226] = "sevenideographicparen", + [0x3227] = "eightideographicparen", + [0x3228] = "nineideographicparen", + [0x3229] = "tenideographicparen", + [0x322A] = "ideographicmoonparen", + [0x322B] = "ideographicfireparen", + [0x322C] = "ideographicwaterparen", + [0x322D] = "ideographicwoodparen", + [0x322E] = "ideographicmetalparen", + [0x322F] = "ideographicearthparen", + [0x3230] = "ideographicsunparen", + [0x3231] = "ideographicstockparen", + [0x3232] = "ideographichaveparen", + [0x3233] = "ideographicsocietyparen", + [0x3234] = "ideographicnameparen", + [0x3235] = "ideographicspecialparen", + [0x3236] = "ideographicfinancialparen", + [0x3237] = "ideographiccongratulationparen", + [0x3238] = "ideographiclaborparen", + [0x3239] = "ideographicrepresentparen", + [0x323A] = "ideographiccallparen", + [0x323B] = "ideographicstudyparen", + [0x323C] = "ideographicsuperviseparen", + [0x323D] = "ideographicenterpriseparen", + [0x323E] = "ideographicresourceparen", + [0x323F] = "ideographicallianceparen", + [0x3240] = "ideographicfestivalparen", + [0x3242] = "ideographicselfparen", + [0x3243] = "ideographicreachparen", + [0x3260] = "kiyeokcirclekorean", + [0x3261] = "nieuncirclekorean", + [0x3262] = "tikeutcirclekorean", + [0x3263] = "rieulcirclekorean", + [0x3264] = "mieumcirclekorean", + [0x3265] = "pieupcirclekorean", + [0x3266] = "sioscirclekorean", + [0x3267] = "ieungcirclekorean", + [0x3268] = "cieuccirclekorean", + [0x3269] = "chieuchcirclekorean", + [0x326A] = "khieukhcirclekorean", + [0x326B] = "thieuthcirclekorean", + [0x326C] = "phieuphcirclekorean", + [0x326D] = "hieuhcirclekorean", + [0x326E] = "kiyeokacirclekorean", + [0x326F] = "nieunacirclekorean", + [0x3270] = "tikeutacirclekorean", + [0x3271] = "rieulacirclekorean", + [0x3272] = "mieumacirclekorean", + [0x3273] = "pieupacirclekorean", + [0x3274] = "siosacirclekorean", + [0x3275] = "ieungacirclekorean", + [0x3276] = "cieucacirclekorean", + [0x3277] = "chieuchacirclekorean", + [0x3278] = "khieukhacirclekorean", + [0x3279] = "thieuthacirclekorean", + [0x327A] = "phieuphacirclekorean", + [0x327B] = "hieuhacirclekorean", + [0x327F] = "koreanstandardsymbol", + [0x328A] = "ideographmooncircle", + [0x328B] = "ideographfirecircle", + [0x328C] = "ideographwatercircle", + [0x328D] = "ideographwoodcircle", + [0x328E] = "ideographmetalcircle", + [0x328F] = "ideographearthcircle", + [0x3290] = "ideographsuncircle", + [0x3294] = "ideographnamecircle", + [0x3296] = "ideographicfinancialcircle", + [0x3298] = "ideographiclaborcircle", + [0x3299] = "ideographicsecretcircle", + [0x329D] = "ideographicexcellentcircle", + [0x329E] = "ideographicprintcircle", + [0x32A3] = "ideographiccorrectcircle", + [0x32A4] = "ideographichighcircle", + [0x32A5] = "ideographiccentrecircle", + [0x32A6] = "ideographiclowcircle", + [0x32A7] = "ideographicleftcircle", + [0x32A8] = "ideographicrightcircle", + [0x32A9] = "ideographicmedicinecircle", + [0x3300] = "apaatosquare", + [0x3303] = "aarusquare", + [0x3305] = "intisquare", + [0x330D] = "karoriisquare", + [0x3314] = "kirosquare", + [0x3315] = "kiroguramusquare", + [0x3316] = "kiromeetorusquare", + [0x3318] = "guramusquare", + [0x331E] = "kooposquare", + [0x3322] = "sentisquare", + [0x3323] = "sentosquare", + [0x3326] = "dorusquare", + [0x3327] = "tonsquare", + [0x332A] = "haitusquare", + [0x332B] = "paasentosquare", + [0x3331] = "birusquare", + [0x3333] = "huiitosquare", + [0x3336] = "hekutaarusquare", + [0x3339] = "herutusquare", + [0x333B] = "peezisquare", + [0x3342] = "hoonsquare", + [0x3347] = "mansyonsquare", + [0x3349] = "mirisquare", + [0x334A] = "miribaarusquare", + [0x334D] = "meetorusquare", + [0x334E] = "yaadosquare", + [0x3351] = "rittorusquare", + [0x3357] = "wattosquare", + [0x337B] = "heiseierasquare", + [0x337C] = "syouwaerasquare", + [0x337D] = "taisyouerasquare", + [0x337E] = "meizierasquare", + [0x337F] = "corporationsquare", + [0x3380] = "paampssquare", + [0x3381] = "nasquare", + [0x3382] = "muasquare", + [0x3383] = "masquare", + [0x3384] = "kasquare", + [0x3385] = "KBsquare", + [0x3386] = "MBsquare", + [0x3387] = "GBsquare", + [0x3388] = "calsquare", + [0x3389] = "kcalsquare", + [0x338A] = "pfsquare", + [0x338B] = "nfsquare", + [0x338C] = "mufsquare", + [0x338D] = "mugsquare", + [0x338E] = "squaremg", + [0x338F] = "squarekg", + [0x3390] = "Hzsquare", + [0x3391] = "khzsquare", + [0x3392] = "mhzsquare", + [0x3393] = "ghzsquare", + [0x3394] = "thzsquare", + [0x3395] = "mulsquare", + [0x3396] = "mlsquare", + [0x3397] = "dlsquare", + [0x3398] = "klsquare", + [0x3399] = "fmsquare", + [0x339A] = "nmsquare", + [0x339B] = "mumsquare", + [0x339C] = "squaremm", + [0x339D] = "squarecm", + [0x339E] = "squarekm", + [0x339F] = "mmsquaredsquare", + [0x33A0] = "cmsquaredsquare", + [0x33A1] = "squaremsquared", + [0x33A2] = "kmsquaredsquare", + [0x33A3] = "mmcubedsquare", + [0x33A4] = "cmcubedsquare", + [0x33A5] = "mcubedsquare", + [0x33A6] = "kmcubedsquare", + [0x33A7] = "moverssquare", + [0x33A8] = "moverssquaredsquare", + [0x33A9] = "pasquare", + [0x33AA] = "kpasquare", + [0x33AB] = "mpasquare", + [0x33AC] = "gpasquare", + [0x33AD] = "radsquare", + [0x33AE] = "radoverssquare", + [0x33AF] = "radoverssquaredsquare", + [0x33B0] = "pssquare", + [0x33B1] = "nssquare", + [0x33B2] = "mussquare", + [0x33B3] = "mssquare", + [0x33B4] = "pvsquare", + [0x33B5] = "nvsquare", + [0x33B6] = "muvsquare", + [0x33B7] = "mvsquare", + [0x33B8] = "kvsquare", + [0x33B9] = "mvmegasquare", + [0x33BA] = "pwsquare", + [0x33BB] = "nwsquare", + [0x33BC] = "muwsquare", + [0x33BD] = "mwsquare", + [0x33BE] = "kwsquare", + [0x33BF] = "mwmegasquare", + [0x33C0] = "kohmsquare", + [0x33C1] = "mohmsquare", + [0x33C2] = "amsquare", + [0x33C3] = "bqsquare", + [0x33C4] = "squarecc", + [0x33C5] = "cdsquare", + [0x33C6] = "coverkgsquare", + [0x33C7] = "cosquare", + [0x33C8] = "dbsquare", + [0x33C9] = "gysquare", + [0x33CA] = "hasquare", + [0x33CB] = "HPsquare", + [0x33CD] = "KKsquare", + [0x33CE] = "squarekmcapital", + [0x33CF] = "ktsquare", + [0x33D0] = "lmsquare", + [0x33D1] = "squareln", + [0x33D2] = "squarelog", + [0x33D3] = "lxsquare", + [0x33D4] = "mbsquare", + [0x33D5] = "squaremil", + [0x33D6] = "molsquare", + [0x33D8] = "pmsquare", + [0x33DB] = "srsquare", + [0x33DC] = "svsquare", + [0x33DD] = "wbsquare", + [0x5344] = "twentyhangzhou", + [0xF6BE] = "dotlessj", + [0xF6BF] = "LL", + [0xF6C0] = "ll", + [0xF6C3] = "commaaccent", + [0xF6C4] = "afii10063", + [0xF6C5] = "afii10064", + [0xF6C6] = "afii10192", + [0xF6C7] = "afii10831", + [0xF6C8] = "afii10832", + [0xF6C9] = "Acute", + [0xF6CA] = "Caron", + [0xF6CB] = "Dieresis", + [0xF6CC] = "DieresisAcute", + [0xF6CD] = "DieresisGrave", + [0xF6CE] = "Grave", + [0xF6CF] = "Hungarumlaut", + [0xF6D0] = "Macron", + [0xF6D1] = "cyrBreve", + [0xF6D2] = "cyrFlex", + [0xF6D3] = "dblGrave", + [0xF6D4] = "cyrbreve", + [0xF6D5] = "cyrflex", + [0xF6D6] = "dblgrave", + [0xF6D7] = "dieresisacute", + [0xF6D8] = "dieresisgrave", + [0xF6D9] = "copyrightserif", + [0xF6DA] = "registerserif", + [0xF6DB] = "trademarkserif", + [0xF6DC] = "onefitted", + [0xF6DD] = "rupiah", + [0xF6DE] = "threequartersemdash", + [0xF6DF] = "centinferior", + [0xF6E0] = "centsuperior", + [0xF6E1] = "commainferior", + [0xF6E2] = "commasuperior", + [0xF6E3] = "dollarinferior", + [0xF6E4] = "dollarsuperior", + [0xF6E5] = "hypheninferior", + [0xF6E6] = "hyphensuperior", + [0xF6E7] = "periodinferior", + [0xF6E8] = "periodsuperior", + [0xF6E9] = "asuperior", + [0xF6EA] = "bsuperior", + [0xF6EB] = "dsuperior", + [0xF6EC] = "esuperior", + [0xF6ED] = "isuperior", + [0xF6EE] = "lsuperior", + [0xF6EF] = "msuperior", + [0xF6F0] = "osuperior", + [0xF6F1] = "rsuperior", + [0xF6F2] = "ssuperior", + [0xF6F3] = "tsuperior", + [0xF6F4] = "Brevesmall", + [0xF6F5] = "Caronsmall", + [0xF6F6] = "Circumflexsmall", + [0xF6F7] = "Dotaccentsmall", + [0xF6F8] = "Hungarumlautsmall", + [0xF6F9] = "Lslashsmall", + [0xF6FA] = "OEsmall", + [0xF6FB] = "Ogoneksmall", + [0xF6FC] = "Ringsmall", + [0xF6FD] = "Scaronsmall", + [0xF6FE] = "Tildesmall", + [0xF6FF] = "Zcaronsmall", + [0xF721] = "exclamsmall", + [0xF724] = "dollaroldstyle", + [0xF726] = "ampersandsmall", + [0xF730] = "zerooldstyle", + [0xF731] = "oneoldstyle", + [0xF732] = "twooldstyle", + [0xF733] = "threeoldstyle", + [0xF734] = "fouroldstyle", + [0xF735] = "fiveoldstyle", + [0xF736] = "sixoldstyle", + [0xF737] = "sevenoldstyle", + [0xF738] = "eightoldstyle", + [0xF739] = "nineoldstyle", + [0xF73F] = "questionsmall", + [0xF760] = "Gravesmall", + [0xF761] = "Asmall", + [0xF762] = "Bsmall", + [0xF763] = "Csmall", + [0xF764] = "Dsmall", + [0xF765] = "Esmall", + [0xF766] = "Fsmall", + [0xF767] = "Gsmall", + [0xF768] = "Hsmall", + [0xF769] = "Ismall", + [0xF76A] = "Jsmall", + [0xF76B] = "Ksmall", + [0xF76C] = "Lsmall", + [0xF76D] = "Msmall", + [0xF76E] = "Nsmall", + [0xF76F] = "Osmall", + [0xF770] = "Psmall", + [0xF771] = "Qsmall", + [0xF772] = "Rsmall", + [0xF773] = "Ssmall", + [0xF774] = "Tsmall", + [0xF775] = "Usmall", + [0xF776] = "Vsmall", + [0xF777] = "Wsmall", + [0xF778] = "Xsmall", + [0xF779] = "Ysmall", + [0xF77A] = "Zsmall", + [0xF7A1] = "exclamdownsmall", + [0xF7A2] = "centoldstyle", + [0xF7A8] = "Dieresissmall", + [0xF7AF] = "Macronsmall", + [0xF7B4] = "Acutesmall", + [0xF7B8] = "Cedillasmall", + [0xF7BF] = "questiondownsmall", + [0xF7E0] = "Agravesmall", + [0xF7E1] = "Aacutesmall", + [0xF7E2] = "Acircumflexsmall", + [0xF7E3] = "Atildesmall", + [0xF7E4] = "Adieresissmall", + [0xF7E5] = "Aringsmall", + [0xF7E6] = "AEsmall", + [0xF7E7] = "Ccedillasmall", + [0xF7E8] = "Egravesmall", + [0xF7E9] = "Eacutesmall", + [0xF7EA] = "Ecircumflexsmall", + [0xF7EB] = "Edieresissmall", + [0xF7EC] = "Igravesmall", + [0xF7ED] = "Iacutesmall", + [0xF7EE] = "Icircumflexsmall", + [0xF7EF] = "Idieresissmall", + [0xF7F0] = "Ethsmall", + [0xF7F1] = "Ntildesmall", + [0xF7F2] = "Ogravesmall", + [0xF7F3] = "Oacutesmall", + [0xF7F4] = "Ocircumflexsmall", + [0xF7F5] = "Otildesmall", + [0xF7F6] = "Odieresissmall", + [0xF7F8] = "Oslashsmall", + [0xF7F9] = "Ugravesmall", + [0xF7FA] = "Uacutesmall", + [0xF7FB] = "Ucircumflexsmall", + [0xF7FC] = "Udieresissmall", + [0xF7FD] = "Yacutesmall", + [0xF7FE] = "Thornsmall", + [0xF7FF] = "Ydieresissmall", + [0xF884] = "maihanakatleftthai", + [0xF885] = "saraileftthai", + [0xF886] = "saraiileftthai", + [0xF887] = "saraueleftthai", + [0xF888] = "saraueeleftthai", + [0xF889] = "maitaikhuleftthai", + [0xF88A] = "maiekupperleftthai", + [0xF88B] = "maieklowrightthai", + [0xF88C] = "maieklowleftthai", + [0xF88D] = "maithoupperleftthai", + [0xF88E] = "maitholowrightthai", + [0xF88F] = "maitholowleftthai", + [0xF890] = "maitriupperleftthai", + [0xF891] = "maitrilowrightthai", + [0xF892] = "maitrilowleftthai", + [0xF893] = "maichattawaupperleftthai", + [0xF894] = "maichattawalowrightthai", + [0xF895] = "maichattawalowleftthai", + [0xF896] = "thanthakhatupperleftthai", + [0xF897] = "thanthakhatlowrightthai", + [0xF898] = "thanthakhatlowleftthai", + [0xF899] = "nikhahitleftthai", + [0xF8E5] = "radicalex", + [0xF8E6] = "arrowvertex", + [0xF8E7] = "arrowhorizex", + [0xF8E8] = "registersans", + [0xF8E9] = "copyrightsans", + [0xF8EA] = "trademarksans", + [0xF8EB] = "parenlefttp", + [0xF8EC] = "parenleftex", + [0xF8ED] = "parenleftbt", + [0xF8EE] = "bracketlefttp", + [0xF8EF] = "bracketleftex", + [0xF8F0] = "bracketleftbt", + [0xF8F1] = "bracelefttp", + [0xF8F2] = "braceleftmid", + [0xF8F3] = "braceleftbt", + [0xF8F4] = "braceex", + [0xF8F5] = "integralex", + [0xF8F6] = "parenrighttp", + [0xF8F7] = "parenrightex", + [0xF8F8] = "parenrightbt", + [0xF8F9] = "bracketrighttp", + [0xF8FA] = "bracketrightex", + [0xF8FB] = "bracketrightbt", + [0xF8FC] = "bracerighttp", + [0xF8FD] = "bracerightmid", + [0xF8FE] = "bracerightbt", + [0xF8FF] = "apple", + [0xFB00] = "ff", + [0xFB01] = "fi", + [0xFB02] = "fl", + [0xFB03] = "ffi", + [0xFB04] = "ffl", + [0xFB1F] = "yodyodpatahhebrew", + [0xFB20] = "ayinaltonehebrew", + [0xFB2A] = "shinshindothebrew", + [0xFB2B] = "shinsindothebrew", + [0xFB2C] = "shindageshshindothebrew", + [0xFB2D] = "shindageshsindothebrew", + [0xFB2E] = "alefpatahhebrew", + [0xFB2F] = "alefqamatshebrew", + [0xFB30] = "alefdageshhebrew", + [0xFB31] = "betdageshhebrew", + [0xFB32] = "gimeldageshhebrew", + [0xFB33] = "daletdageshhebrew", + [0xFB34] = "hedageshhebrew", + [0xFB35] = "vavdageshhebrew", + [0xFB36] = "zayindageshhebrew", + [0xFB38] = "tetdageshhebrew", + [0xFB39] = "yoddageshhebrew", + [0xFB3A] = "finalkafdageshhebrew", + [0xFB3B] = "kafdageshhebrew", + [0xFB3C] = "lameddageshhebrew", + [0xFB3E] = "memdageshhebrew", + [0xFB40] = "nundageshhebrew", + [0xFB41] = "samekhdageshhebrew", + [0xFB43] = "pefinaldageshhebrew", + [0xFB44] = "pedageshhebrew", + [0xFB46] = "tsadidageshhebrew", + [0xFB47] = "qofdageshhebrew", + [0xFB48] = "reshdageshhebrew", + [0xFB49] = "shindageshhebrew", + [0xFB4A] = "tavdageshhebrew", + [0xFB4B] = "vavholamhebrew", + [0xFB4C] = "betrafehebrew", + [0xFB4D] = "kafrafehebrew", + [0xFB4E] = "perafehebrew", + [0xFB4F] = "aleflamedhebrew", + [0xFB57] = "pehfinalarabic", + [0xFB58] = "pehinitialarabic", + [0xFB59] = "pehmedialarabic", + [0xFB67] = "ttehfinalarabic", + [0xFB68] = "ttehinitialarabic", + [0xFB69] = "ttehmedialarabic", + [0xFB6B] = "vehfinalarabic", + [0xFB6C] = "vehinitialarabic", + [0xFB6D] = "vehmedialarabic", + [0xFB7B] = "tchehfinalarabic", + [0xFB7C] = "tchehmeeminitialarabic", + [0xFB7D] = "tchehmedialarabic", + [0xFB89] = "ddalfinalarabic", + [0xFB8B] = "jehfinalarabic", + [0xFB8D] = "rrehfinalarabic", + [0xFB93] = "gaffinalarabic", + [0xFB94] = "gafinitialarabic", + [0xFB95] = "gafmedialarabic", + [0xFB9F] = "noonghunnafinalarabic", + [0xFBA4] = "hehhamzaaboveisolatedarabic", + [0xFBA5] = "hehhamzaabovefinalarabic", + [0xFBA7] = "hehfinalaltonearabic", + [0xFBA8] = "hehinitialaltonearabic", + [0xFBA9] = "hehmedialaltonearabic", + [0xFBAF] = "yehbarreefinalarabic", + [0xFC08] = "behmeemisolatedarabic", + [0xFC0B] = "tehjeemisolatedarabic", + [0xFC0C] = "tehhahisolatedarabic", + [0xFC0E] = "tehmeemisolatedarabic", + [0xFC48] = "meemmeemisolatedarabic", + [0xFC4B] = "noonjeemisolatedarabic", + [0xFC4E] = "noonmeemisolatedarabic", + [0xFC58] = "yehmeemisolatedarabic", + [0xFC5E] = "shaddadammatanarabic", + [0xFC5F] = "shaddakasratanarabic", + [0xFC60] = "shaddafathaarabic", + [0xFC61] = "shaddadammaarabic", + [0xFC62] = "shaddakasraarabic", + [0xFC6D] = "behnoonfinalarabic", + [0xFC73] = "tehnoonfinalarabic", + [0xFC8D] = "noonnoonfinalarabic", + [0xFC94] = "yehnoonfinalarabic", + [0xFC9F] = "behmeeminitialarabic", + [0xFCA1] = "tehjeeminitialarabic", + [0xFCA2] = "tehhahinitialarabic", + [0xFCA4] = "tehmeeminitialarabic", + [0xFCC9] = "lamjeeminitialarabic", + [0xFCCA] = "lamhahinitialarabic", + [0xFCCB] = "lamkhahinitialarabic", + [0xFCCC] = "lammeeminitialarabic", + [0xFCD1] = "meemmeeminitialarabic", + [0xFCD2] = "noonjeeminitialarabic", + [0xFCD5] = "noonmeeminitialarabic", + [0xFCDD] = "yehmeeminitialarabic", + [0xFD3E] = "parenleftaltonearabic", + [0xFD3F] = "parenrightaltonearabic", + [0xFD88] = "lammeemhahinitialarabic", + [0xFDF2] = "lamlamhehisolatedarabic", + [0xFDFA] = "sallallahoualayhewasallamarabic", + [0xFE30] = "twodotleadervertical", + [0xFE31] = "emdashvertical", + [0xFE32] = "endashvertical", + [0xFE33] = "underscorevertical", + [0xFE34] = "wavyunderscorevertical", + [0xFE35] = "parenleftvertical", + [0xFE36] = "parenrightvertical", + [0xFE37] = "braceleftvertical", + [0xFE38] = "bracerightvertical", + [0xFE39] = "tortoiseshellbracketleftvertical", + [0xFE3A] = "tortoiseshellbracketrightvertical", + [0xFE3B] = "blacklenticularbracketleftvertical", + [0xFE3C] = "blacklenticularbracketrightvertical", + [0xFE3D] = "dblanglebracketleftvertical", + [0xFE3E] = "dblanglebracketrightvertical", + [0xFE3F] = "anglebracketleftvertical", + [0xFE40] = "anglebracketrightvertical", + [0xFE41] = "cornerbracketleftvertical", + [0xFE42] = "cornerbracketrightvertical", + [0xFE43] = "whitecornerbracketleftvertical", + [0xFE44] = "whitecornerbracketrightvertical", + [0xFE49] = "overlinedashed", + [0xFE4A] = "overlinecenterline", + [0xFE4B] = "overlinewavy", + [0xFE4C] = "overlinedblwavy", + [0xFE4D] = "lowlinedashed", + [0xFE4E] = "lowlinecenterline", + [0xFE4F] = "underscorewavy", + [0xFE50] = "commasmall", + [0xFE52] = "periodsmall", + [0xFE54] = "semicolonsmall", + [0xFE55] = "colonsmall", + [0xFE59] = "parenleftsmall", + [0xFE5A] = "parenrightsmall", + [0xFE5B] = "braceleftsmall", + [0xFE5C] = "bracerightsmall", + [0xFE5D] = "tortoiseshellbracketleftsmall", + [0xFE5E] = "tortoiseshellbracketrightsmall", + [0xFE5F] = "numbersignsmall", + [0xFE61] = "asterisksmall", + [0xFE62] = "plussmall", + [0xFE63] = "hyphensmall", + [0xFE64] = "lesssmall", + [0xFE65] = "greatersmall", + [0xFE66] = "equalsmall", + [0xFE69] = "dollarsmall", + [0xFE6A] = "percentsmall", + [0xFE6B] = "atsmall", + [0xFE82] = "alefmaddaabovefinalarabic", + [0xFE84] = "alefhamzaabovefinalarabic", + [0xFE86] = "wawhamzaabovefinalarabic", + [0xFE88] = "alefhamzabelowfinalarabic", + [0xFE8A] = "yehhamzaabovefinalarabic", + [0xFE8B] = "yehhamzaaboveinitialarabic", + [0xFE8C] = "yehhamzaabovemedialarabic", + [0xFE8E] = "aleffinalarabic", + [0xFE90] = "behfinalarabic", + [0xFE91] = "behinitialarabic", + [0xFE92] = "behmedialarabic", + [0xFE94] = "tehmarbutafinalarabic", + [0xFE96] = "tehfinalarabic", + [0xFE97] = "tehinitialarabic", + [0xFE98] = "tehmedialarabic", + [0xFE9A] = "thehfinalarabic", + [0xFE9B] = "thehinitialarabic", + [0xFE9C] = "thehmedialarabic", + [0xFE9E] = "jeemfinalarabic", + [0xFE9F] = "jeeminitialarabic", + [0xFEA0] = "jeemmedialarabic", + [0xFEA2] = "hahfinalarabic", + [0xFEA3] = "hahinitialarabic", + [0xFEA4] = "hahmedialarabic", + [0xFEA6] = "khahfinalarabic", + [0xFEA7] = "khahinitialarabic", + [0xFEA8] = "khahmedialarabic", + [0xFEAA] = "dalfinalarabic", + [0xFEAC] = "thalfinalarabic", + [0xFEAE] = "rehfinalarabic", + [0xFEB0] = "zainfinalarabic", + [0xFEB2] = "seenfinalarabic", + [0xFEB3] = "seeninitialarabic", + [0xFEB4] = "seenmedialarabic", + [0xFEB6] = "sheenfinalarabic", + [0xFEB7] = "sheeninitialarabic", + [0xFEB8] = "sheenmedialarabic", + [0xFEBA] = "sadfinalarabic", + [0xFEBB] = "sadinitialarabic", + [0xFEBC] = "sadmedialarabic", + [0xFEBE] = "dadfinalarabic", + [0xFEBF] = "dadinitialarabic", + [0xFEC0] = "dadmedialarabic", + [0xFEC2] = "tahfinalarabic", + [0xFEC3] = "tahinitialarabic", + [0xFEC4] = "tahmedialarabic", + [0xFEC6] = "zahfinalarabic", + [0xFEC7] = "zahinitialarabic", + [0xFEC8] = "zahmedialarabic", + [0xFECA] = "ainfinalarabic", + [0xFECB] = "aininitialarabic", + [0xFECC] = "ainmedialarabic", + [0xFECE] = "ghainfinalarabic", + [0xFECF] = "ghaininitialarabic", + [0xFED0] = "ghainmedialarabic", + [0xFED2] = "fehfinalarabic", + [0xFED3] = "fehinitialarabic", + [0xFED4] = "fehmedialarabic", + [0xFED6] = "qaffinalarabic", + [0xFED7] = "qafinitialarabic", + [0xFED8] = "qafmedialarabic", + [0xFEDA] = "kaffinalarabic", + [0xFEDB] = "kafinitialarabic", + [0xFEDC] = "kafmedialarabic", + [0xFEDE] = "lamfinalarabic", + [0xFEDF] = "lammeemkhahinitialarabic", + [0xFEE0] = "lammedialarabic", + [0xFEE2] = "meemfinalarabic", + [0xFEE3] = "meeminitialarabic", + [0xFEE4] = "meemmedialarabic", + [0xFEE6] = "noonfinalarabic", + [0xFEE7] = "nooninitialarabic", + [0xFEE8] = "noonmedialarabic", + [0xFEEA] = "hehfinalarabic", + [0xFEEB] = "hehinitialarabic", + [0xFEEC] = "hehmedialarabic", + [0xFEEE] = "wawfinalarabic", + [0xFEF0] = "alefmaksurafinalarabic", + [0xFEF2] = "yehfinalarabic", + [0xFEF3] = "yehinitialarabic", + [0xFEF4] = "yehmedialarabic", + [0xFEF5] = "lamalefmaddaaboveisolatedarabic", + [0xFEF6] = "lamalefmaddaabovefinalarabic", + [0xFEF7] = "lamalefhamzaaboveisolatedarabic", + [0xFEF8] = "lamalefhamzaabovefinalarabic", + [0xFEF9] = "lamalefhamzabelowisolatedarabic", + [0xFEFA] = "lamalefhamzabelowfinalarabic", + [0xFEFB] = "lamalefisolatedarabic", + [0xFEFC] = "lamaleffinalarabic", + [0xFEFF] = "zerowidthjoiner", + [0xFF01] = "exclammonospace", + [0xFF02] = "quotedblmonospace", + [0xFF03] = "numbersignmonospace", + [0xFF04] = "dollarmonospace", + [0xFF05] = "percentmonospace", + [0xFF06] = "ampersandmonospace", + [0xFF07] = "quotesinglemonospace", + [0xFF08] = "parenleftmonospace", + [0xFF09] = "parenrightmonospace", + [0xFF0A] = "asteriskmonospace", + [0xFF0B] = "plusmonospace", + [0xFF0C] = "commamonospace", + [0xFF0D] = "hyphenmonospace", + [0xFF0E] = "periodmonospace", + [0xFF0F] = "slashmonospace", + [0xFF10] = "zeromonospace", + [0xFF11] = "onemonospace", + [0xFF12] = "twomonospace", + [0xFF13] = "threemonospace", + [0xFF14] = "fourmonospace", + [0xFF15] = "fivemonospace", + [0xFF16] = "sixmonospace", + [0xFF17] = "sevenmonospace", + [0xFF18] = "eightmonospace", + [0xFF19] = "ninemonospace", + [0xFF1A] = "colonmonospace", + [0xFF1B] = "semicolonmonospace", + [0xFF1C] = "lessmonospace", + [0xFF1D] = "equalmonospace", + [0xFF1E] = "greatermonospace", + [0xFF1F] = "questionmonospace", + [0xFF20] = "atmonospace", + [0xFF21] = "Amonospace", + [0xFF22] = "Bmonospace", + [0xFF23] = "Cmonospace", + [0xFF24] = "Dmonospace", + [0xFF25] = "Emonospace", + [0xFF26] = "Fmonospace", + [0xFF27] = "Gmonospace", + [0xFF28] = "Hmonospace", + [0xFF29] = "Imonospace", + [0xFF2A] = "Jmonospace", + [0xFF2B] = "Kmonospace", + [0xFF2C] = "Lmonospace", + [0xFF2D] = "Mmonospace", + [0xFF2E] = "Nmonospace", + [0xFF2F] = "Omonospace", + [0xFF30] = "Pmonospace", + [0xFF31] = "Qmonospace", + [0xFF32] = "Rmonospace", + [0xFF33] = "Smonospace", + [0xFF34] = "Tmonospace", + [0xFF35] = "Umonospace", + [0xFF36] = "Vmonospace", + [0xFF37] = "Wmonospace", + [0xFF38] = "Xmonospace", + [0xFF39] = "Ymonospace", + [0xFF3A] = "Zmonospace", + [0xFF3B] = "bracketleftmonospace", + [0xFF3C] = "backslashmonospace", + [0xFF3D] = "bracketrightmonospace", + [0xFF3E] = "asciicircummonospace", + [0xFF3F] = "underscoremonospace", + [0xFF40] = "gravemonospace", + [0xFF41] = "amonospace", + [0xFF42] = "bmonospace", + [0xFF43] = "cmonospace", + [0xFF44] = "dmonospace", + [0xFF45] = "emonospace", + [0xFF46] = "fmonospace", + [0xFF47] = "gmonospace", + [0xFF48] = "hmonospace", + [0xFF49] = "imonospace", + [0xFF4A] = "jmonospace", + [0xFF4B] = "kmonospace", + [0xFF4C] = "lmonospace", + [0xFF4D] = "mmonospace", + [0xFF4E] = "nmonospace", + [0xFF4F] = "omonospace", + [0xFF50] = "pmonospace", + [0xFF51] = "qmonospace", + [0xFF52] = "rmonospace", + [0xFF53] = "smonospace", + [0xFF54] = "tmonospace", + [0xFF55] = "umonospace", + [0xFF56] = "vmonospace", + [0xFF57] = "wmonospace", + [0xFF58] = "xmonospace", + [0xFF59] = "ymonospace", + [0xFF5A] = "zmonospace", + [0xFF5B] = "braceleftmonospace", + [0xFF5C] = "barmonospace", + [0xFF5D] = "bracerightmonospace", + [0xFF5E] = "asciitildemonospace", + [0xFF61] = "periodhalfwidth", + [0xFF62] = "cornerbracketlefthalfwidth", + [0xFF63] = "cornerbracketrighthalfwidth", + [0xFF64] = "ideographiccommaleft", + [0xFF65] = "middledotkatakanahalfwidth", + [0xFF66] = "wokatakanahalfwidth", + [0xFF67] = "asmallkatakanahalfwidth", + [0xFF68] = "ismallkatakanahalfwidth", + [0xFF69] = "usmallkatakanahalfwidth", + [0xFF6A] = "esmallkatakanahalfwidth", + [0xFF6B] = "osmallkatakanahalfwidth", + [0xFF6C] = "yasmallkatakanahalfwidth", + [0xFF6D] = "yusmallkatakanahalfwidth", + [0xFF6E] = "yosmallkatakanahalfwidth", + [0xFF6F] = "tusmallkatakanahalfwidth", + [0xFF70] = "katahiraprolongmarkhalfwidth", + [0xFF71] = "akatakanahalfwidth", + [0xFF72] = "ikatakanahalfwidth", + [0xFF73] = "ukatakanahalfwidth", + [0xFF74] = "ekatakanahalfwidth", + [0xFF75] = "okatakanahalfwidth", + [0xFF76] = "kakatakanahalfwidth", + [0xFF77] = "kikatakanahalfwidth", + [0xFF78] = "kukatakanahalfwidth", + [0xFF79] = "kekatakanahalfwidth", + [0xFF7A] = "kokatakanahalfwidth", + [0xFF7B] = "sakatakanahalfwidth", + [0xFF7C] = "sikatakanahalfwidth", + [0xFF7D] = "sukatakanahalfwidth", + [0xFF7E] = "sekatakanahalfwidth", + [0xFF7F] = "sokatakanahalfwidth", + [0xFF80] = "takatakanahalfwidth", + [0xFF81] = "tikatakanahalfwidth", + [0xFF82] = "tukatakanahalfwidth", + [0xFF83] = "tekatakanahalfwidth", + [0xFF84] = "tokatakanahalfwidth", + [0xFF85] = "nakatakanahalfwidth", + [0xFF86] = "nikatakanahalfwidth", + [0xFF87] = "nukatakanahalfwidth", + [0xFF88] = "nekatakanahalfwidth", + [0xFF89] = "nokatakanahalfwidth", + [0xFF8A] = "hakatakanahalfwidth", + [0xFF8B] = "hikatakanahalfwidth", + [0xFF8C] = "hukatakanahalfwidth", + [0xFF8D] = "hekatakanahalfwidth", + [0xFF8E] = "hokatakanahalfwidth", + [0xFF8F] = "makatakanahalfwidth", + [0xFF90] = "mikatakanahalfwidth", + [0xFF91] = "mukatakanahalfwidth", + [0xFF92] = "mekatakanahalfwidth", + [0xFF93] = "mokatakanahalfwidth", + [0xFF94] = "yakatakanahalfwidth", + [0xFF95] = "yukatakanahalfwidth", + [0xFF96] = "yokatakanahalfwidth", + [0xFF97] = "rakatakanahalfwidth", + [0xFF98] = "rikatakanahalfwidth", + [0xFF99] = "rukatakanahalfwidth", + [0xFF9A] = "rekatakanahalfwidth", + [0xFF9B] = "rokatakanahalfwidth", + [0xFF9C] = "wakatakanahalfwidth", + [0xFF9D] = "nkatakanahalfwidth", + [0xFF9E] = "voicedmarkkanahalfwidth", + [0xFF9F] = "semivoicedmarkkanahalfwidth", + [0xFFE0] = "centmonospace", + [0xFFE1] = "sterlingmonospace", + [0xFFE3] = "macronmonospace", + [0xFFE5] = "yenmonospace", + [0xFFE6] = "wonmonospace", +} + +fonts.map.agl_to_unicode = table.swapped(fonts.map.unicode_to_agl) diff --git a/tex/context/base/font-arb.mkii b/tex/context/base/font-arb.mkii new file mode 100644 index 000000000..3ec0395f3 --- /dev/null +++ b/tex/context/base/font-arb.mkii @@ -0,0 +1,5 @@ +\unprotected \writestatus\m!systems{load ARABTEX as a module instead} + +\usemodule[arabtex] + +\endinput diff --git a/tex/context/base/font-bfm.mkii b/tex/context/base/font-bfm.mkii new file mode 100644 index 000000000..23e3176c4 --- /dev/null +++ b/tex/context/base/font-bfm.mkii @@ -0,0 +1,196 @@ +%D \module +%D [ file=font-bfm, +%D version=2003.11.25, +%D title=\CONTEXT\ Font Macros, +%D subtitle=Mixed Normal and Bold Math, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / 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 +%D machine we don't show the result. +%D +%D \starttyping +%D \setupformulas +%D [method=bold] +%D +%D \definetypeface [mainface] [rm] [serif] [lucida] [default] [encoding=texnansi] +%D \definetypeface [mainface] [tt] [mono] [lucida] [default] [encoding=texnansi] +%D \definetypeface [mainface] [ss] [sans] [lucida] [default] [encoding=texnansi] +%D \definetypeface [mainface] [mm] [math] [lucida] [default] [encoding=texnansi] +%D \definetypeface [mainface] [mm] [bfmath] [lucida] [default] [encoding=texnansi] +%D +%D \definetypeface [boldmath] [rm] [serif] [lucida] [default] [encoding=texnansi] +%D \definetypeface [boldmath] [tt] [mono] [lucida] [default] [encoding=texnansi] +%D \definetypeface [boldmath] [ss] [sans] [lucida] [default] [encoding=texnansi] +%D \definetypeface [boldmath] [mm] [boldmath] [lucida] [default] [encoding=texnansi] +%D +%D \switchtobodyfont[mainface] +%D +%D \startlines +%D $\mainface x=10 \Gamma \Delta \alpha \delta \zeta$ +%D $\boldmath x=10 \Gamma \Delta \alpha \delta \zeta$ +%D \stoplines +%D +%D \startformula +%D x=12=\fontbody \Gamma \Delta \alpha \delta \zeta +%D \stopformula +%D +%D \startformula[mainface] +%D x=12=\fontbody \Gamma \Delta \alpha \delta \zeta +%D \stopformula +%D +%D \startformula[boldmath] +%D x=12=\fontbody \Gamma \Delta \alpha \delta \zeta +%D \stopformula +%D +%D \startformula[boldmath,8pt] +%D x=8=\fontbody \Gamma \Delta \alpha \delta \zeta +%D \stopformula +%D +%D \startformula[boldmath,12pt,small] +%D x=12s=\fontbody \Gamma \Delta \alpha \delta \zeta +%D \stopformula +%D +%D \startformula[boldmath,small] +%D x=s=\fontbody \Gamma \Delta \alpha \delta \zeta +%D \stopformula +%D +%D \startformula[boldmath,10pt] +%D x=10=\fontbody \Gamma \Delta \alpha \delta \zeta +%D \stopformula +%D +%D \startformula[boldmath,11pt,small] +%D x=11s=\fontbody \Gamma \Delta \alpha \delta \zeta +%D \stopformula +%D +%D \startformula[boldmath,9pt] +%D x=9=\fontbody \Gamma \Delta \alpha \delta \zeta +%D \stopformula +%D +%D \startlines +%D \formula{1=2x} +%D \formula[boldmath]{1=2x} +%D \formula[mainface]{1=2x} +%D \formula[mainface]{1 \theta \Gamma = \bfm 1 \beta \hbox{\sl test}\Gamma \alpha ' x x} +%D \formula[mainface]{1 \theta \Gamma = {\bfm 1 \beta \hbox{\sl test}\Gamma \alpha ' x} x} +%D \stoplines +%D \stoptyping + +\unprotect + +%D \TEX\ has some hard wired expectations about where to look for +%D certain characters. This means that we cannot overload the families +%D 0 upto~3. Also, since we use C upto~F for math as well, we are left +%D with the range 4 upto~B. + +\chardef\mrbffam\itfam \edef\c!mrbf{\c!mr\c!bf} \let\hexmrbffam\hexitfam % 4 it +\chardef\exbffam\slfam \edef\c!exbf{\c!ex\c!bf} \let\hexexbffam\hexslfam % 5 sl +\chardef\mibffam\bffam \edef\c!mibf{\c!mi\c!bf} \let\hexmibffam\hexbffam % 6 bf +\chardef\sybffam\nnfam \edef\c!sybf{\c!sy\c!bf} \let\hexsybffam\hexnnfam % 7 nn +\chardef\mabffam\bsfam \edef\c!mabf{\c!ma\c!bf} \let\hexmabffam\hexbsfam % 8 bs +\chardef\mbbffam\bifam \edef\c!mbbf{\c!mb\c!bf} \let\hexmbbffam\hexbifam % 9 bi +\chardef\mcbffam\scfam \edef\c!mcbf{\c!mc\c!bf} \let\hexmcbffam\hexscfam % A sc +\chardef\mdbffam\scfam \edef\c!mdbf{\c!mc\c!bf} \let\hexmdbffam\hexscfam % B tf % tricky + +%D The next bunch of code looks horrible and tricky but one has to keep in +%D mind that because \TEX\ makes several passes over the math list we need to +%D make sure that grouping is handled well. Later assignments to a family +%D overload previous ones, the last one counts. + +\newtoks \boldmathstrategies +\newtoks \boldsymbstrategies + +\appendtoks + \dosetmathfamily\mrbffam\textface\scriptface\scriptscriptface\c!mrbf\mrfallback + \dosetmathfamily\mibffam\textface\scriptface\scriptscriptface\c!mibf\empty + \dosetmathfamily\sybffam\textface\scriptface\scriptscriptface\c!sybf\empty + \dosetmathfamily\exbffam\textface\textface \textface \c!exbf\empty + \dosetmathfamily\mabffam\textface\scriptface\scriptscriptface\c!mabf\empty + \dosetmathfamily\mbbffam\textface\scriptface\scriptscriptface\c!mbbf\empty + \dosetmathfamily\mcbffam\textface\scriptface\scriptscriptface\c!mcbf\empty +\to \boldmathstrategies + +\appendtoks + \dosetskewchar\mifam\defaultskewcharmi + \dosetskewchar\syfam\defaultskewcharsy +\to \boldmathstrategies + +\appendtoks + \dosetsymbfamily\mrbffam\textface\scriptface\scriptscriptface\c!mrbf + \dosetsymbfamily\mibffam\textface\scriptface\scriptscriptface\c!mibf + \dosetsymbfamily\sybffam\textface\scriptface\scriptscriptface\c!sybf + \dosetsymbfamily\exbffam\textface\textface \textface \c!exbf + \dosetsymbfamily\mabffam\textface\scriptface\scriptscriptface\c!mabf + \dosetsymbfamily\mbbffam\textface\scriptface\scriptscriptface\c!mbbf + \dosetsymbfamily\mcbffam\textface\scriptface\scriptscriptface\c!mcbf +\to \boldsymbstrategies + +%D Here comes the real mess (due to semi||global settings en multiple +%D passes over the math list once the input is expanded. + +\newevery \everyboldfacemath \relax +\chardef \boldfacemathmethod \zerocount + +\appendtoks + \ifcase\boldfacemathmethod \else \the\boldmathstrategies \fi +\to \mathstrategies + +\appendtoks + \ifcase\boldfacemathmethod \else \the\boldsymbstrategies \fi +\to \symbstrategies + +\appendtoks + \let\mrfam\mrbffam \let\c!mr\c!mrbf \let\hexmrfam\hexmrbffam + \let\mifam\mibffam \let\c!mi\c!mibf \let\hexmifam\hexmibffam + \let\syfam\sybffam \let\c!sy\c!sybf \let\hexsyfam\hexsybffam + \let\exfam\exbffam \let\c!ex\c!exbf \let\hexexfam\hexexbffam + \let\mafam\mabffam \let\c!ma\c!mabf \let\hexmafam\hexmabffam + \let\mbfam\mbbffam \let\c!mb\c!mbbf \let\hexmbfam\hexmbbffam + \let\mcfam\mcbffam \let\c!mc\c!mcbf \let\hexmcfam\hexmcbffam +\to \everyboldfacemath + +\appendtoks + \let\mathsubfamily\c!bf +\to \everyboldfacemath + +\appendtoks + \synchronizemath \aftergroup\synchronizemath +\to \everyboldfacemath + +%D \macros +%D {boldfacemath, bfm, autoboldfacemath} +%D +%D These are the user commands, with \type {\bfm} being the most comfortable. + +\def\boldfacemath {\ifcase\boldfacemathmethod\else\the\everyboldfacemath\fi} +\def\bfm {\boldfacemath} % no \let, so that we can redefine +\def\autoboldfacemath{\appendtoks\ifcase\boldfacemathmethod\else\let\bf\boldfacemath\fi\to\everymathematics} + +%D We hook this feature into the formula mechanism. + +\setupformulas + [\c!method=\v!normal] + +\appendtoks + \doifelse{\formulaparameter\c!method}\v!bold + {\chardef\boldfacemathmethod\plusone} + {\chardef\boldfacemathmethod\zerocount}% +\to \everysetupformulas + +%D Of course this only works when bfmath fonts are set up (see example at +%D the top of this file) and bold math is enabled: +%D +%D \starttyping +%D \setupformulas +%D [method=bold] +%D \stoptyping + +\protect \endinput diff --git a/tex/context/base/font-chi.mkii b/tex/context/base/font-chi.mkii new file mode 100644 index 000000000..0acf710d5 --- /dev/null +++ b/tex/context/base/font-chi.mkii @@ -0,0 +1,1156 @@ +%D \module +%D [ file=font-chi, +%D version=1999.10.10, +%D title=\CONTEXT\ Font Macros, +%D subtitle=Chinese, +%D author=Hans Hagen, +%D date=\currentdate, +%D suggestions=Wang Lei, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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\handlechineseunicodeglyph\undefined \else \endinput \fi + +% NOT YET ADAPTED TO THE NEW FONT MACROS + +%D The first implementation (most of which is here) is based on +%D the specific font layout. This is because not all glyphs are +%D available in uniciode, which means that we cannot use +%D unicode codepoints (yet); if it were possible we could use +%D just one table per input encoding. + +\writestatus{loading}{ConTeXt Font Macros / Chinese} + +% much will to typo-chi.tex + +%D Still to be implemented: +%D +%D \startitemize +%D \item columns left right touch +%D \item distance = (hsize-n*bodyfontsize)/(n-1) +%D \item char grids +%D \item char tables +%D \item all kind of rotated combinations +%D \item hanging puctuation +%D \item a few more encodings +%D \item rotation list +%D \stopitemize + +%M \setupbodyfont[chi] +%M +%M \def\WangLei{\purechinese{\uchar{205}{245}\uchar{192}{218}}} + +\useencoding[chi] + +%D When \WangLei\ sent me a mail asking if \CONTEXT\ was able +%D to support Chinese, I wasn't sure if the answer could be +%D yes. I knew that those languages, rich of glyphs, were +%D typeset by \TEX, so in principle it should be possible. I +%D asked or some more input and was told that there were +%D \LATEX\ styles regarding those languages. When I unzipped +%D the accompanying files, it became clear that I had to +%D implement support for Chinese from scratch. There was a +%D multitude of font, with rather unfamiliar encodings, a +%D large collection of files with |<|at least for me|>| +%D unknown purposes, and worse, the documentation was mainly +%D in Chinese. +%D +%D So, \WangLei\ and I started exchanging some emails and it +%D soon became clear that supporting Chinese was not that +%D complicated at all. It mostly came to dealing with handling +%D \UNICODE\ fonts. It also became clear that everything +%D Chinese took place in the upper region of the eight bit +%D character set. I wrote some macros that could process the +%D small \type {Hello World} file \WangLei\ had send me, and +%D after some bug fixes real Chinese came out. I started to +%D like the look and fel of Chinese glyphs, so on we went. +%D +%D The first comments concerned spacing. The mix of English +%D and Chinese demands some rather deliberate handling of +%D spacing. Breaking lines was not so much a problem, and +%D could be solved by adding some glue between Chinese glyphs. +%D +%D In the meantime had asked \WangLei\ for some language bound +%D labels and texts, and implementing these was rather +%D straightforward. But, there were still some issues to deal +%D with: conversion of numbers, date handling and index +%D sorting. +%D +%D I consider(ed) writing Chinese support to be a nice puzzle, +%D since I have to act on chinese \CONTEXT\ code, where I only +%D understand the \CONTEXT\ part. The drawings \WangLei\ made +%D me (in drawing packages) were of great help. Since I write +%D these modules from scratch, although I fall back on some +%D basic encoding and font modules, I consider them to be +%D rather clean. This cannot be said of all \CONTEXT\ font +%D modules \type {-)}. + +\unprotect + +%D Because Chinese glyphs have more height than the average +%D Latin glyph, and at the same time don't have much depth, +%D we adapt the scale. +%D +%D Before and after the glyph we have to deal with Chinese +%D spacing. Special attention is given to punctuation. +%D +%D \starttyping +%D [some short nice chinese text with () and english] +%D \stoptyping +%D +%D We insert a bit of stretch and introduce a signal to +%D keep track of previous characters. We use a similar +%D method in the units module, which may be a nice +%D introduction to using signals. + +%D \macros +%D {chineseunicodescale, chineseinterglyphskip, +%D chineseunicodeheight, chineseunicodedepth, chinesespace} +%D +%D There are a few variables, that can be (re|)|set +%D depending on the current font. They default to: + +% hm, why don't we use the normal unicodestrut mechanism? + +\def\chineseunicodescale {1.00} % not smaller than .85 +\def\chineseunicodeheight {1.00} +\def\chineseunicodedepth {1.00} +\def\chineseinterglyphskip{0pt \!!plus .05em \!!minus .01em} +\def\chinesesurroundskip {.25em \!!plus .15em \!!minus .05em} + +%D We define a few signals. As said, another example of +%D using signals can be found in the module \type {m-units}. + +\newsignal\chineseLsignal % left boundary character +\newsignal\chineseRsignal % right boundary character +\newsignal\chineseSsignal % any other character (symbol) + +\chardef\chineseBstatus=0 % 0=unknown 1=left 2=right 3=chinese 4=nospace +\chardef\chineseAstatus=0 % 0=unknown 1=left 2=right 3=space +\chardef\chineseSstatus=0 % 0=unknown 1=left 2=right + +\sfcode`(=2000 % a temporary hack + +\def\chinesenobreak + {\relax + \iftracechinese + \nobreak + \kern-.5pt\color[red]{\vrule\!!width1pt}\kern-.5pt + \nobreak + \else + \nobreak + \fi} + +\newif\ifcorrectchineseboundarychars + +\def\chineseunskip + {\unskip\unskip\unskip\unskip} + +\def\insertchineseglyph + {\iftracechinese\tracedchineseglyph\else\insertunicodeglyph\fi} + +\newif\ifverticalchinese + +\def\handlechineseunicodeglyph + {\ifinpagebody + \horizontalchineseunicodeglyph + \else\ifverticalchinese + \verticalchineseunicodeglyph + \else + \horizontalchineseunicodeglyph + \fi\fi} + +% chinese classes: left=1|right=2|center=3 + +\chardef\plusfour=4 + +\def\analyzechineseunicodeglyph % beware, no zerocount ! + {\chardef\chineseSstatus0\getvalue{uc\number\unicodeposition}\relax} + +\def\analyzechineseunicodeenviroment + {% left + \ifx (\nextutoken \chardef\chineseAstatus\plusone \else + \ifx [\nextutoken \chardef\chineseAstatus\plusone \else + % right + \ifx ,\nextutoken \chardef\chineseAstatus\plustwo \else + \ifx .\nextutoken \chardef\chineseAstatus\plustwo \else + \ifx ?\nextutoken \chardef\chineseAstatus\plustwo \else + \ifx ;\nextutoken \chardef\chineseAstatus\plustwo \else + \ifx :\nextutoken \chardef\chineseAstatus\plustwo \else + \ifx !\nextutoken \chardef\chineseAstatus\plustwo \else + \ifx )\nextutoken \chardef\chineseAstatus\plustwo \else + \ifx ]\nextutoken \chardef\chineseAstatus\plustwo \else + % space + \ifx\nextutoken\blankspace \chardef\chineseAstatus\plusthree \else + \ifx\nextutoken\space \chardef\chineseAstatus\plusthree \else + \chardef\chineseAstatus\zerocount + % unknown + \fi\fi\fi\fi\fi \fi\fi\fi\fi\fi \fi\fi + % maybe save the last skip? + \chardef\chineseBstatus\ifdim\lastskip=\zeropoint\plusfour\else\zerocount\fi + \ifdim\lastskip=\chineseLsignal \chardef\chineseBstatus\plusone \else + \ifdim\lastskip=\chineseRsignal \chardef\chineseBstatus\plustwo \else + \ifdim\lastskip=\chineseSsignal \chardef\chineseBstatus\plusthree \else + \scratchskip=\lastskip \unskip + \ifdim\lastskip=\chineseLsignal \chardef\chineseBstatus\plusone \else + \ifdim\lastskip=\chineseRsignal \chardef\chineseBstatus\plustwo \else + \ifdim\lastskip=\chineseSsignal \chardef\chineseBstatus\plusthree \else + \space\scratchskip=\lastskip \unskip + \setbox\scratchbox=\hbox\bgroup + (\space + \ifdim\lastskip=\scratchskip + \egroup \chardef\chineseBstatus\plusone + \else + \egroup + \ifdim\scratchskip=\zeropoint \chardef\chineseBstatus\plusfour \fi + \fi + \fi\fi\fi + \fi\fi\fi} + +\def\horizontalchineseunicodeglyph + {\relax + \ifhmode\else\dontleavehmode\fi % added + \setunicodescale\chineseunicodescale % redundant + \setunicodestrut\chineseunicodeheight\chineseunicodedepth % redundant + \ifprocessingverbatim + \iftracechinese + \ruledhbox{\insertunicodeglyph}% + \else + \insertunicodeglyph + \fi + \else\ifx\nextutoken\relax + \insertunicodeglyph + \else + \analyzechineseunicodeglyph + \analyzechineseunicodeenviroment + \ifcase\chineseSstatus\relax + \ifcase\chineseBstatus\relax + \chineseunskip + \hskip\chinesesurroundskip % unknown + \or + \chineseunskip + \chinesenobreak % left + \or + \ifcorrectchineseboundarychars\else\chineseunskip\fi + \hskip\chineseinterglyphskip % right + \or + \chineseunskip + \hskip\chineseinterglyphskip % chinese + \or + % whatever + \fi + \insertchineseglyph + \ifcase\chineseAstatus\relax + \hskip\chineseinterglyphskip % unknown + \hskip\chinesesurroundskip + \ifcase\chineseSstatus + \hskip\chineseSsignal + \or + \hskip\chineseLsignal + \else + \hskip\chineseRsignal + \fi + \or + \hskip\chineseinterglyphskip % left + \chinesenobreak + \hskip\chineseLsignal + \or + \chinesenobreak % right + \hskip\chineseinterglyphskip + \chinesenobreak + \hskip\chineseRsignal + \or + \hskip\chineseinterglyphskip % space + \hskip\chinesesurroundskip + \hskip\chineseSsignal + \fi + \or % left + \ifcorrectchineseboundarychars + \let\unicodecharcommand\chineseleftcharcommand + \fi + \chineseunskip + \insertchineseglyph + \chinesenobreak + \hskip\chineseLsignal + \or % right + \ifcorrectchineseboundarychars + \let\unicodecharcommand\chineserightcharcommand + \fi + \chineseunskip + \chinesenobreak + \insertchineseglyph + \hskip\chineseRsignal + \else % center + \chineseunskip + \chinesenobreak + \insertchineseglyph + \hskip\chineseinterglyphskip + \hskip\chineseRsignal + \fi\fi + \aftergroup\ignorespaces % watch this + \fi} + +\def\verticalchineseunicodeglyph + {\relax + \ifprocessingverbatim % to do + \horizontalchineseunicodeglyph + \else + \setunicodescale\chineseunicodescale % redundant + \setunicodestrut\chineseunicodeheight\chineseunicodedepth % redundant + \ifx\nextutoken\relax + \insertchineseglyph + \ifvmode % catches \hbox{...}, actually \hbox should be \vbox -) + \nointerlineskip + \fi + \allowbreak + \else + \analyzechineseunicodeglyph + \setbox\scratchbox\hbox to \hsize + {\hss + \ifcase\chineseSstatus\relax + \insertchineseglyph + \else % left / right + \setbox\scratchbox\hbox{\insertchineseglyph}% + \rotate[\c!rotation=270]{\box\scratchbox}% + \fi + \hss}% + \ht\scratchbox\unicodeheight\strutht + \dp\scratchbox\unicodedepth \strutdp + \ifvmode % catches \hbox{...}, actually \hbox should be \vbox -) + \nointerlineskip + \fi + \ifcase\prevchineseSstatus\relax + \ifnum\chineseSstatus=\plustwo \par\nobreak\else\allowbreak\fi + \or % left + \par\nobreak + \or % right + \ifnum\chineseSstatus=\plustwo \par\nobreak\else\allowbreak\fi + \fi + \global\chardef\prevchineseSstatus\chineseSstatus % pagebody ... + \box\scratchbox\par + \fi + \aftergroup\ignorespaces % watch this + \fi} + +%D \macros +%D {setupchinese,startvertical,nochinese} +%D +%D The previous macros implement horizontal as well as +%D vertical typesetting. Vertical typesetting is implemented +%D on top of the multi||column routines. + +\def\setupchinese + {\dodoubleargument\getparameters[\??vt]} + +\def\startvertical + {\dosingleempty\dostartvertical} + +\def\dostartvertical[#1]% + {\bgroup + \def\maxnofcolumns{25}% + \verticalchinesetrue + \global\chardef\prevchineseSstatus\zerocount + \let\nochinese\nochineseinvertical + \doif\@@vtn\v!fit + {\dimen0=\textwidth \advance\dimen0 \@@vtdistance + \dimen2=\bodyfontsize \advance\dimen2 \@@vtdistance + \divide\dimen0 \number\dimen2 + \edef\@@vtn{\number\dimen0}}% + \startcolumns + [\c!direction=\@@vtdirection, + \c!balance=\@@vtbalance, + \c!distance=\@@vtdistance, + \c!n=\@@vtn, + #1]} + +\def\stopvertical + {\stopcolumns + \egroup} + +\setupchinese + [\c!direction=\v!left, + \c!balance=\v!no, + \c!n=\v!fit, + \c!distance=1.5\bodyfontsize] + +%D We can set up vertical typesetting with \type +%D {\setupchinese}. + +%D \macros +%D {nochineseinvertical} +%D +%D English (non chinese) text is typeset rotated: + +\def\nochineseinvertical#1% + {\par + \setbox\scratchbox\hbox{\strut#1} + \getnoflines{\wd\scratchbox} + \setbox\scratchbox\hbox to \noflines\openlineheight + {\hss\box\scratchbox\hss} + \hbox to \hsize + {\hss + \rotate + [\c!rotation=270] + {\vbox to \ht\scratchbox{\vss\box\scratchbox\vss}}% + \hss} + \par} + +%D \macros +%D {correctchineseboundarychars} +%D +%D Careful reading of the previous macro learns that we +%D treat left and right glyphs differently. When we say +%D +%D \starttyping +%D \correctchineseboundarycharstrue +%D \stoptyping +%D +%D For the moment correction in on by default. + +\correctchineseboundarycharstrue + +\def\chineserightcharcommand#1% + {\iftracechinese\ruledhbox\else\hbox\fi \!!to .5em{#1\hss}% + \hskip.25em\!!plus .25em\relax}% + +\def\chineseleftcharcommand#1% + {\ifnum\chineseBstatus<4 \hskip.25em \!!plus .25em\relax\fi + \iftracechinese\ruledhbox\else\hbox\fi \!!to .5em{\hss#1}}% + +% \def\chineserightcharcommand#1% +% {\setbox\scratchbox=\hbox{#1}% +% \scratchdimen=.5em +% \ifdim\wd\scratchbox>\scratchdimen +% \iftracechinese\ruledhbox\else\hbox\fi \!!to \scratchdimen +% {\box\scratchbox\hss}% +% \hskip.5\scratchdimen\!!plus.5\scratchdimen\relax +% \else +% \box\scratchbox +% \fi} + +% \def\chineseleftcharcommand#1% +% {\setbox\scratchbox=\hbox{#1}% +% \scratchdimen=.5em +% \ifdim\wd\scratchbox>\scratchdimen +% \ifnum\chineseBstatus<4 +% \hskip.5\scratchdimen\!!plus.5\scratchdimen\relax +% \fi +% \iftracechinese\ruledhbox\else\hbox\fi \!!to \scratchdimen +% {\hss\box\scratchbox}% +% \else +% \box\scratchbox +% \fi} + +%D The long list of numbers in the previous macro identify the +%D characters where special care is needed for breaking lines. +%D A linebreak is not permitted before: +%D +%D \def\DoIt #1 #2 % +%D {\hbox{\hbox to 2em{\uchar{#1}{#2}\hss}#1 #2}\par} +%D +%D \startcolumns[n=5] +%D \DoIt 161 162 \DoIt 161 163 \DoIt 161 164 \DoIt 161 167 \DoIt 161 173 +%D \DoIt 161 175 \DoIt 161 177 \DoIt 161 179 \DoIt 161 181 \DoIt 161 183 +%D \DoIt 161 185 \DoIt 161 187 \DoIt 161 189 \DoIt 161 191 \DoIt 161 227 +%D \DoIt 161 228 \DoIt 161 229 \DoIt 163 161 \DoIt 163 162 \DoIt 163 167 +%D \DoIt 163 169 \DoIt 163 172 \DoIt 163 174 \DoIt 163 186 \DoIt 163 187 +%D \DoIt 163 190 \DoIt 163 191 \DoIt 163 221 \DoIt 163 253 +%D \stopcolumns +%D +%D A linebreak is not permitted after the following glyphs: +%D +%D \startcolumns[n=5] +%D \DoIt 161 174 \DoIt 161 176 \DoIt 161 178 \DoIt 161 180 \DoIt 161 182 +%D \DoIt 161 184 \DoIt 161 186 \DoIt 161 188 \DoIt 161 190 \DoIt 163 168 +%D \DoIt 163 219 \DoIt 163 224 \DoIt 163 251 +%D \stopcolumns + +%D \macros +%D {tracechinesetrue, showchinesetracelegend} +%D +%D When we say \type {\tracechinesetrue}, we get some +%D insight in the way \CONTEXT\ handles the Chinese glyphs. +%D The symbols and color used represent: +%D +%D \showchinesetracelegend + +\newif\iftracechinese + +\def\showchinesetracelegend + {\definetabulate[\s!dummy][|c|l|l|l|]% + \startdummy + \HL + \NC \bf key \NC \bf meaning \NC \bf glyph \NC \bf keys \NC\NR + \HL + \NC u \NC unknown character type \NC \color[green]{current} \NC u l r \NC\NR + \NC l \NC left boundary character \NC \color[red]{previous} \NC u l r c n \NC\NR + \NC r \NC right boundary character \NC \color[blue]{next} \NC u l r s \NC\NR + \NC c \NC chinese character \NC \NC \NC\NR + \NC s \NC following space \NC \NC \NC\NR + \NC n \NC no preceding space \NC \NC \NC\NR + \HL + \stopdummy} + +\def\tracedchineseglyph + {\dontleavehmode + \ruledhbox + {\setbox\scratchbox\hbox{\insertunicodeglyph}% + \hbox to \wd\scratchbox + {\localcolortrue + \copy\scratchbox + \infofont + \hskip-\wd\scratchbox + \hbox to \wd\scratchbox + {\hss + \color[green]{\ifcase\chineseSstatus\relax u\or l\or r\fi}% + \hss}% + \hskip-\wd\scratchbox + \lower\dp\scratchbox\hbox to \wd\scratchbox + {\hss + \color[red]{\ifcase\chineseBstatus\relax u\or l\or r\or c\or n\fi}% + \hss + \color[blue]{\ifcase\chineseAstatus\relax u\or l\or r\or s\fi}% + \hss}}}} + +%D The following example shows how tracing works. +%D +%D \start \tracechinesetrue +%D һθǽܶĵ֧֡ĵ +%D ѯ \nochinese{\CONTEXT} ǷܴʱѾԹ +%D еĺ꼯ûеõζŶĵֻ֧û +%D ʵ֡ +%D +%D һ(θ) () ܶĵ֧֡ĵ, +%D ѯ\nochinese{\CONTEXT}ǷܴʱѾ +%D Թеĺ꼯ûеõζŶĵ֧ +%D ûʵ֡. +%D \stop + +%D Because fonts are defined each time a \UNICODE\ is +%D encountered |<|which is less inefficient than one would +%D imagine, because \TEX\ is optimized quite well in this +%D repect|>| we can define macros like this to take care of +%D font switches. When available, one can add definitions +%D for italic, slanted, bold fonts and combinations of these. + +%D \macros +%D {chinesenumber} +%D +%D The chinese numbering systems rather straightforward. First +%D there are the digits: +%D +%D \starttabulate[|c|c|c|c|c|c|c|c|c|c|] +%D \NC 0 \NC 1 \NC 2 \NC 3 \NC 4 \NC 5 \NC 6 \NC 7 \NC 8 \NC 9 \NC\NR +%D \NC \chinesenumber{0} \NC \chinesenumber{1} \NC \chinesenumber{2} +%D \NC \chinesenumber{3} \NC \chinesenumber{4} \NC \chinesenumber{5} +%D \NC \chinesenumber{6} \NC \chinesenumber{7} \NC \chinesenumber{8} +%D \NC \chinesenumber{9} \NC\NR +%D \stoptabulate +%D +%D Apart from these numbers, we have dedicated representations +%D of some powers of~$10$. +%D +%D \starttabulate[|c|c|c|c|c|] +%D \NC 10 \NC 100 \NC 1000 \NC 10000 \NC 100000000 \NC\NR +%D \NC \chinesenumber{10} \NC \chinesenumber{100} +%D \NC \chinesenumber{1000} \NC \chinesenumber{10000} +%D \NC \chinesenumber{100000000} \NC\NR +%D \stoptabulate +%D +%D The number~12 is a combination of $1\times10+2$, or: +%D \chinesenumber {12}, while~22 becomes \chinesenumber {22}. +%D The numbers below 20 are treated a bit different, just like +%D numbers with series of $0$'s. So $2\times10$ comes out as +%D two glyphs, but $1\times10$ as one, because in the latter +%D case the~$1$ is redundant. The same is true for the powers +%D of~10. +%D +%D \starttabulate[|r|r|r|r|r|r|] +%D \NC 1 \NC \chinesenumber {1} \NC +%D 9 \NC \chinesenumber {9} \NC +%D 4 \NC \chinesenumber {4} \NC\NR +%D \NC 11 \NC \chinesenumber {11} \NC +%D 99 \NC \chinesenumber {99} \NC +%D 16 \NC \chinesenumber {16} \NC\NR +%D \NC 111 \NC \chinesenumber {111} \NC +%D 999 \NC \chinesenumber {999} \NC +%D 256 \NC \chinesenumber {256} \NC\NR +%D \NC 1111 \NC \chinesenumber {1111} \NC +%D 9999 \NC \chinesenumber {9999} \NC +%D 65536 \NC \chinesenumber {65536} \NC\NR +%D \stoptabulate +%D +%D The implementation is rather simple. For internal purposes, +%D we let zero expand to~0. The digits $0-9$ and numbers $10$, +%D $100$, $1000$, $10000$ and $100000000$ are hard coded. + +% This was the first implementation, before \WangLei\ asked +% me to look into Big Five encoding, so, like everthing in +% \TEX, things become a bit more complicated, but also more +% versatile. +% +% \starttypen +% \def\chinesedigit#1% +% {\ifnum #1=100000000 \uchar{210}{218}% 100000000 +% \else\ifnum #1=10000 \uchar{205}{242}% 10000 +% \else\ifnum #1=1000 \uchar{199}{167}% 1000 +% \else\ifnum #1=100 \uchar{176}{217}% 100 +% \else\ifnum #1=10 \uchar{202}{174}% 10 +% \else\ifcase#1 \uchar{193}{227}% 0 +% \or \uchar{210}{187}% 1 +% \or \uchar{182}{254}% 2 +% \or \uchar{200}{253}% 3 +% \or \uchar{203}{196}% 4 +% \or \uchar{206}{229}% 5 +% \or \uchar{193}{249}% 6 +% \or \uchar{198}{223}% 7 +% \or \uchar{176}{203}% 8 +% \or \uchar{190}{197}% 9 +% \fi\fi\fi\fi\fi\fi} +% \stoptypen + +%D We will implement four methods, the one described earlier, +%D a derived one with capitalized characters, an extended +%D version of the first method, and a rather Arabic method. +%D +%D \starttabulate[|l|l|] +%D \HL +%D \NC \bf command \NC \bf number 39 \NC\NR +%D \HL +%D \NC \type{\normalchinesenumber} \NC \normalchinesenumber {39} \NC\NR +%D \NC \type{\capitalizedchinesenumber} \NC \capitalizedchinesenumber{39} \NC\NR +%D \NC \type{\arabicchinesenumber} \NC \arabicchinesenumber {39} \NC\NR +%D \NC \type{\extendedchinesenumber} \NC \extendedchinesenumber {39} \NC\NR +%D \HL +%D \stoptabulate +%D +%D We use a dirty trick to enable Chinese Capital Digits. In +%D the encoding vectors, we define these by appending a suffix +%D \type {*} to the digit, which in the following macro is +%D appended or not (by passing \type {\empty}). + +\def\chinesedigit#1#2% #2: suffix, here * or \empty + {\udigit{\chineseencoding}{\number#1#2}} + +% Normal Chinese Number + +\def\normalchinesenumber#1% + {\expandafter\dochinesenumber\number#1\relax\empty} + +\def\dochinesenumber#1#2\relax#3% + {\ifnum#1#2<10 % 1-10 + \chinesedigit{#1}#3% + \else\ifnum#1#2<20 % 11-99 + \chinesedigit{10}#3% + \dodochinesenumberA#2\relax#3% + \else + \dodochinesenumber#1#2\relax#3% + \fi\fi} + +\def\dodochinesenumber#1#2\relax#3% + {\ifnum#1=0 + \chinesedigit{0}#3% + \dododochinesenumber0#2\relax#3% + \else\ifnum#1#2<10 % 1-10 + \chinesedigit{#1#2}#3% + \dodochinesenumberA#2\relax#3% + \else\ifnum#1#2<100 % 11-99 + \dodochinesenumber#1\relax#3% + \chinesedigit{10}#3% + \dodochinesenumberA#2\relax#3% + \else\ifnum#1#2<1000 % 100-999 + \dodochinesenumber#1\relax#3% + \chinesedigit{100}#3% + \dodochinesenumberA#2\relax#3% + \else\ifnum#1#2<10000 % 1000-9999 + \dodochinesenumber#1\relax#3% + \chinesedigit{1000}#3% + \dodochinesenumberA#2\relax#3% + \else\ifnum#1#2<100000 % 10000-99999 + \dodochinesenumber#1\relax#3% + \chinesedigit{10000}#3% + \dodochinesenumberA#2\relax#3% + \else\ifnum#1#2<1000000 % 100000-999999 + \dodochinesenumberB#1#2\relax#3% + \else\ifnum#1#2<10000000 % 1000000-9999999 + \dodochinesenumberC#1#2\relax#3% + \else\ifnum#1#2<100000000 % 10000000-99999999 + \dodochinesenumberD#1#2\relax#3% + \else\ifnum#1#2<1000000000 % 10000000-99999999 + \dochinesenumber#1\relax#3% + \chinesedigit{100000000}#3% + \dododochinesenumber#2\relax#3% + \else + \dodochinesenumberE#1#2\relax#3% + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} + +\def\dododochinesenumber#1#2\relax#3% + {\ifnum#1=0 + \ifnum0#2>0 \dododochinesenumber#2\relax#3\fi + \else + \dodochinesenumber#1#2\relax#3% + \fi} + +\def\dodochinesenumberA#1\relax#2% + {\ifcase0#1 \else\dodochinesenumber#1\relax#2\fi} + +\def\dodochinesenumberB#1#2#3\relax#4% + {\dochinesenumber#1#2\relax#4% + \chinesedigit{10000}#4% + \dododochinesenumber#3\relax#4} + +\def\dodochinesenumberC#1#2#3#4\relax#5% + {\dochinesenumber#1#2#3\relax#5% + \chinesedigit{10000}#5% + \dododochinesenumber#4\relax#5} + +\def\dodochinesenumberD#1#2#3#4#5\relax#6% + {\dochinesenumber#1#2#3#4\relax#6% + \chinesedigit{10000}#6% + \dododochinesenumber#5\relax#6} + +\def\dodochinesenumberE#1#2#3\relax#4% + {\dochinesenumber#1#2\relax#4% + \chinesedigit{100000000}#4% + \dododochinesenumber#3\relax#4} + +% Capitalized Chinese Number + +\def\capitalizedchinesenumber#1% + {\expandafter\dochinesenumber\number#1\relax*} + +% Extended Chinese Number + +\def\extendedchinesenumber#1% + {\expandafter\doextendedchinesenumber\number#1\relax} + +\def\doextendedchinesenumber#1#2\relax% + {\ifnum #1#2<20 % 0-19 + \dochinesenumber#1#2\relax\empty + \else\ifnum#1#2<30 % 20-29 + \chinesedigit{20}\empty + \ifcase#2\else\chinesedigit{2#2}\fi + \else\ifnum#1#2<40 % 30-39 + \chinesedigit{30}\empty + \ifcase#2\else\chinesedigit{3#2}\fi + \else + \dochinesenumber#1#2\relax\empty + \fi\fi\fi} + +% Arabic Chinese Number + +\def\arabicchinesenumber#1% + {\expandafter\doarabicchinesenumber\number#1@\relax} + +\def\doarabicchinesenumber#1#2\relax + {\if#1@\else + \chinesedigit{#1}\empty + \doarabicchinesenumber#2\relax + \fi} + +% The short call: + +\def\chinesenumber{\normalchinesenumber} + +% \dorecurse{40} +% {\hbox +% {\processingverbatimtrue +% \hbox to 1cm{\hss\recurselevel}\quad +% \hbox to 3cm{\hss\strut\normalchinesenumber {\recurselevel}}\quad +% \hbox to 3cm{\hss\strut\capitalizedchinesenumber{\recurselevel}}\quad +% \hbox to 3cm{\hss\strut\arabicchinesenumber {\recurselevel}}\quad +% \hbox to 3cm{\hss\strut\extendedchinesenumber {\recurselevel}}\crlf}} + +%D The next table demonstates the correctness of the +%D conversion macro. +%D +%D \startbuffer +%D \starttable[|l|l|l|l|l|l|] +%D \HL +%D \NC number \NC converter \NC hard coded \NC +%D number \NC converter \NC hard coded\NC \SR +%D \HL +%D \NC 1 \NC \chinesenumber{1} \NC һ \NC +%D 0 \NC \chinesenumber{0} \NC \NC\FR +%D \NC 11 \NC \chinesenumber{11} \NC ʮһ \NC +%D 10 \NC \chinesenumber{10} \NC ʮ \NC\MR +%D \NC 111 \NC \chinesenumber{111} \NC һһʮһ \NC +%D 100 \NC \chinesenumber{100} \NC һ \NC\MR +%D \NC 101 \NC \chinesenumber{101} \NC һһ \NC +%D 120 \NC \chinesenumber{120} \NC һٶʮ \NC\MR +%D \NC 1111 \NC \chinesenumber{1111} \NC һǧһһʮһ \NC +%D 1000 \NC \chinesenumber{1000} \NC һǧ \NC\MR +%D \NC 1001 \NC \chinesenumber{1001} \NC һǧһ \NC +%D 1020 \NC \chinesenumber{1020} \NC һǧʮ \NC\MR +%D \NC 11111 \NC \chinesenumber{11111} \NC һһǧһһʮһ \NC +%D 10000 \NC \chinesenumber{10000} \NC һ \NC\MR +%D \NC 10001 \NC \chinesenumber{10001} \NC һһ \NC +%D 10200 \NC \chinesenumber{10200} \NC һ \NC\LR +%D \HL +%D \NC 111111 \NC \chinesenumber{111111} \NC ʮһһǧһһʮһ \NC +%D 100000 \NC \chinesenumber{100000} \NC ʮ \NC\FR +%D \NC 1111111 \NC \chinesenumber{1111111} \NC һһʮһһǧһһʮһ \NC +%D 1000000 \NC \chinesenumber{1000000} \NC һ \NC\MR +%D \NC 11111111 \NC \chinesenumber{11111111} \NC һǧһһʮһһǧһһʮһ \NC +%D 10000000 \NC \chinesenumber{10000000} \NC һǧ \NC\MR +%D \NC 111111111 \NC \chinesenumber{111111111} \NC һһǧһһʮһһǧһһʮһ \NC +%D 100000000 \NC \chinesenumber{100000000} \NC һ \NC\MR +%D \NC 1111111111 \NC \chinesenumber{1111111111} \NC ʮһһǧһһʮһһǧһһʮһ \NC +%D 1000000000 \NC \chinesenumber{1000000000} \NC ʮ \NC\LR +%D \HL +%D \stoptable +%D \stopbuffer +%D +%D \placetable{Some Chinese number examples.}{\getbuffer} + +%D Although the conversion can be hooked into most commands +%D that deal with numbers |<|those familiar with \TEX\ macro +%D programming will notice that the macro if fully +%D expandable|>| in many cases Chinese documents use western +%D digits. So, in practice, the change that the next example +%D shows up, is minimal. +%D +%D \starttabulate[|r|r|c|] +%D \NC 2546 \NC \chinesenumber {2546} \NC \NC\NR +%D \NC 9258 \NC \chinesenumber {9258} \NC $+$ \NC\NR +%D \HL +%D \NC 11804 \NC \chinesenumber {11804} \NC \NC\NR +%D \stoptabulate +%D +%D While in arabic arithmics addition leads to more digits, in +%D Chinese the number of glyphs can (temporary) decrease. +%D Given that the number of people dealing with Chinese is +%D considerably larger than the number of latin speaking +%D people, a successor of \TEX\ definitely must provide a +%D \type {\chinesenumeral} primitive. + +\defineconversion [c] [\normalchinesenumber] +\defineconversion [chinese] [\normalchinesenumber] +\defineconversion [nc] [\normalchinesenumber] +\defineconversion [normalchinese] [\normalchinesenumber] +\defineconversion [cc] [\capitalizedchinesenumber] +\defineconversion [capitalizedchinese] [\capitalizedchinesenumber] +\defineconversion [ec] [\extendedchinesenumber] +\defineconversion [extendedchinese] [\extendedchinesenumber] +\defineconversion [ac] [\arabicchinesenumber] +\defineconversion [arabicchinese] [\arabicchinesenumber] + +%D Date conversion: + +\defineconversion [cn] [\v!day] [\chinesenumber] +\defineconversion [cn] [\v!month] [\chinesenumber] +\defineconversion [cn] [\v!year] [\chinesenumber] + +%D \macros +%D {SimChi, TraChi} +%D +%D These components enable us to construct dedicated Chinese +%D font switches, like: + +\setupunicodefont + [chinese] + [ \c!scale=\chineseunicodescale, + \c!height=\chineseunicodeheight, + \c!depth=\chineseunicodedepth, + \c!strut=\v!yes, + \c!interlinespace=\v!yes, + \c!conversion=\chinesenumber, + \c!commands=\setchineseencoding, % needed for digits + \c!command=\handlechineseunicodeglyph] + +%D For the moment, this encoding is implemented rather ugly. The +%D trick is to move the encoding value from the current font +%D definition to the \type {\chineseencoding} macro. + +\let\chineseencoding\empty + +\def\setchineseencoding % normally SomeChineseRegular + {\getfontfileparameters\unicodestyle + \ifx\currentfontfileencoding\undefined \else + \let\chineseencoding\currentfontfileencoding + \fi} + +%D We could have said: +%D +%D \starttyping +%D \defineunicodefont +%D [SimChi] +%D [SimplifiedChinese] +%D [\c!scale=\chineseunicodescale, +%D \c!height=\chineseunicodeheight, +%D \c!depth=\chineseunicodedepth, +%D \c!conversion=\chinesenumber, +%D \c!commands=\setchineseencoding, % needed for digits +%D \c!command=\handlechineseunicodeglyph] +%D \stoptyping +%D +%D However, the former definitions is more general. Next we +%D map a few fonts: + +\definefontsynonym [SimplifiedChineseRegular] [gbsong] [encoding=gbk] +\definefontsynonym [SimplifiedChineseSlanted] [gbsongsl] [encoding=gbk] +\definefontsynonym [SimplifiedChineseItalic] [gbsongsl] [encoding=gbk] +\definefontsynonym [SimplifiedChineseBold] [gbhei] [encoding=gbk] +\definefontsynonym [SimplifiedChineseBoldSlanted] [gbheisl] [encoding=gbk] +\definefontsynonym [SimplifiedChineseBoldItalic] [gbheisl] [encoding=gbk] + +\definefontsynonym [TraditionalChineseRegular] [b5song] [encoding=big5] +\definefontsynonym [TraditionalChineseSlanted] [b5songsl] [encoding=big5] +\definefontsynonym [TraditionalChineseItalic] [b5songsl] [encoding=big5] +\definefontsynonym [TraditionalChineseBold] [b5hei] [encoding=big5] +\definefontsynonym [TraditionalChineseBoldSlanted] [b5heisl] [encoding=big5] +\definefontsynonym [TraditionalChineseBoldItalic] [b5heisl] [encoding=big5] + +% we need to move this to typescripts + +\doifelse \currentregime {utf} { + + \definefontsynonym [SimplifiedChineseRegular] [ChineseRegular] + \definefontsynonym [SimplifiedChineseSlanted] [ChineseSlanted] + \definefontsynonym [SimplifiedChineseItalic] [ChineseItalic] + \definefontsynonym [SimplifiedChineseBold] [ChineseBold] + \definefontsynonym [SimplifiedChineseBoldSlanted] [ChineseBoldSlanted] + \definefontsynonym [SimplifiedChineseBoldItalic] [ChineseBoldItalic] + + \definefontsynonym [TraditionalChineseRegular] [ChineseRegular] + \definefontsynonym [TraditionalChineseSlanted] [ChineseSlanted] + \definefontsynonym [TraditionalChineseItalic] [ChineseItalic] + \definefontsynonym [TraditionalChineseBold] [ChineseBold] + \definefontsynonym [TraditionalChineseBoldSlanted][ChineseBoldSlanted] + \definefontsynonym [TraditionalChineseBoldItalic] [ChineseBoldItalic] + + \definefontsynonym [ChineseRegular] [uni-htsong-][encoding=cjk-uni] + \definefontsynonym [ChineseSlanted] [uni-htsong-][encoding=cjk-uni] + \definefontsynonym [ChineseItalic] [uni-htsong-][encoding=cjk-uni] + \definefontsynonym [ChineseBold] [uni-hthei-] [encoding=cjk-uni] + \definefontsynonym [ChineseBoldSlanted][uni-hthei-] [encoding=cjk-uni] + \definefontsynonym [ChineseBoldItalic] [uni-hthei-] [encoding=cjk-uni] + + \loadmapfile[uni-htsong.map] + \loadmapfile[uni-htfs.map] + \loadmapfile[uni-hthei.map] + \loadmapfile[uni-htkai.map] + +} { + + \loadmapfile[gbk] + +} + +\defineunicodefont [SimChi] [SimplifiedChinese] [chinese] +\defineunicodefont [TraChi] [TraditionalChinese] [chinese] + +%D We default to these so called Simplified Chinese fonts. + +\SimChi + +%D In addition to these fonts, we (pre|)|define some commonly +%D used fonts: + +\definefontsynonym [SimplifiedChineseSongTiRegular] [gbsong] [encoding=gbk] +\definefontsynonym [SimplifiedChineseSongTiSlanted] [gbsongsl] [encoding=gbk] +\definefontsynonym [SimplifiedChineseSongTiBold] [gbsong] [encoding=gbk] +\definefontsynonym [SimplifiedChineseSongTiBoldSlanted] [gbsongsl] [encoding=gbk] + +\definefontsynonym [TraditionalChineseSongTiRegular] [b5song] [encoding=big5] +\definefontsynonym [TraditionalChineseSongTiSlanted] [b5songsl] [encoding=big5] +\definefontsynonym [TraditionalChineseSongTiBold] [b5song] [encoding=big5] +\definefontsynonym [TraditionalChineseSongTiBoldSlanted] [b5songsl] [encoding=big5] + +\definefontsynonym [SimplifiedChineseHeiTiRegular] [gbhei] [encoding=gbk] +\definefontsynonym [SimplifiedChineseHeiTiSlanted] [gbheisl] [encoding=gbk] +\definefontsynonym [SimplifiedChineseHeiTiBold] [gbhei] [encoding=gbk] +\definefontsynonym [SimplifiedChineseHeiTiBoldSlanted] [gbheisl] [encoding=gbk] + +\definefontsynonym [TraditionalChineseHeiTiRegular] [b5hei] [encoding=big5] +\definefontsynonym [TraditionalChineseHeiTiSlanted] [b5heisl] [encoding=big5] +\definefontsynonym [TraditionalChineseHeiTiBold] [b5hei] [encoding=big5] +\definefontsynonym [TraditionalChineseHeiTiBoldSlanted] [b5heisl] [encoding=big5] + +\definefontsynonym [SimplifiedChineseKaiTiRegular] [gbkai] [encoding=gbk] +\definefontsynonym [SimplifiedChineseKaiTiSlanted] [gbkaisl] [encoding=gbk] +\definefontsynonym [SimplifiedChineseKaiTiBold] [gbkai] [encoding=gbk] +\definefontsynonym [SimplifiedChineseKaiTiBoldSlanted] [gbkaisl] [encoding=gbk] + +\definefontsynonym [TraditionalChineseKaiTiRegular] [b5kai] [encoding=big5] +\definefontsynonym [TraditionalChineseKaiTiSlanted] [b5kaisl] [encoding=big5] +\definefontsynonym [TraditionalChineseKaiTiBold] [b5kai] [encoding=big5] +\definefontsynonym [TraditionalChineseKaiTiBoldSlanted] [b5kaisl] [encoding=big5] + +\definefontsynonym [SimplifiedChineseFangSongRegular] [gbfs] [encoding=gbk] +\definefontsynonym [SimplifiedChineseFangSongSlanted] [gbfssl] [encoding=gbk] +\definefontsynonym [SimplifiedChineseFangSongBold] [gbfs] [encoding=gbk] +\definefontsynonym [SimplifiedChineseFangSongBoldSlanted] [gbfssl] [encoding=gbk] + +\definefontsynonym [TraditionalChineseFangSongRegular] [b5fs] [encoding=big5] +\definefontsynonym [TraditionalChineseFangSongSlanted] [b5fssl] [encoding=big5] +\definefontsynonym [TraditionalChineseFangSongBold] [b5fs] [encoding=big5] +\definefontsynonym [TraditionalChineseFangSongBoldSlanted] [b5fssl] [encoding=big5] + +\definefontsynonym [SimplifiedChineseLiShuRegular] [gbli] [encoding=gbk] +\definefontsynonym [SimplifiedChineseLiShuSlanted] [gblisl] [encoding=gbk] +\definefontsynonym [SimplifiedChineseLiShuBold] [gbli] [encoding=gbk] +\definefontsynonym [SimplifiedChineseLiShuBoldSlanted] [gblisl] [encoding=gbk] + +\definefontsynonym [TraditionalChineseLiShuRegular] [b5li] [encoding=big5] +\definefontsynonym [TraditionalChineseLiShuSlanted] [b5lisl] [encoding=big5] +\definefontsynonym [TraditionalChineseLiShuBold] [b5li] [encoding=big5] +\definefontsynonym [TraditionalChineseLiShuBoldSlanted] [b5lisl] [encoding=big5] + +%D The following definitions provide us the commands to switch +%D to these fonts. + +\defineunicodefont [SimSongTi] [SimplifiedChineseSongTi] [chinese] +\defineunicodefont [TraSongTi] [TraditionalChineseSongTi] [chinese] + +\defineunicodefont [SimHeiTi] [SimplifiedChineseHeiTi] [chinese] +\defineunicodefont [TraHeiTi] [TraditionalChineseHeiTi] [chinese] + +\defineunicodefont [SimKaiTi] [SimplifiedChineseKaiTi] [chinese] +\defineunicodefont [TraKaiTi] [TraditionalChineseKaiTi] [chinese] + +\defineunicodefont [SimFangSong] [SimplifiedChineseFangSong] [chinese] +\defineunicodefont [TraFangSong] [TraditionalChineseFangSong] [chinese] + +\defineunicodefont [SimLiShu] [SimplifiedChineseLiShu] [chinese] +\defineunicodefont [TraLiShu] [TraditionalChineseLiShu] [chinese] + +% \definealternativestyle [ChineseTitleFont] [\bfd\SimKaiTi] [] + +%D \macros +%D {purechinese} +%D +%D Use this macro to suppress spacing around Chinese text. + +\def\purechinese#1% evt geen rek + {\hskip\chineseSsignal\relax + #1\unskip\unskip\unskip + \hskip\chineseSsignal\relax} + +%D \macros +%D {stillchinese} +%D +%D Use the next macro when you want the next item to be put +%D tight to the previous chinese character. + +\def\stillchinese + {\hskip\chineseSsignal\relax} + +%D \macros +%D {nochinese} +%D +%D When we want to be sure of non||Chinese inline text, +%D we can package the for instance english text in \type +%D {\nochinese}. + +\def\nochinese#1% + {\unskip\unskip\unskip + \hskip\chinesesurroundskip + \hskip\chineseinterglyphskip\relax + #1% + \hskip\chineseinterglyphskip\relax + \hskip\chinesesurroundskip + \ignorespaces} + +%D \macros +%D {chisize} +%D +%D Chinese font sizes are specified in a different way, +%D using positive and negative numbers: + +\def\chisize#1% + {\ifnum#11<0 % a trick to catch -0 + \ifcase#1\space36\or24\or18\or15\or12\or9\or\else6.5\fi + \else + \ifcase#1\space42\or26\or22\or16\or14\or10.5\or7.5\or5.5\else5\fi + \fi pt} + +%D So: +%D +%D \startbuffer +%D [\chisize{-1}] [\chisize{7}] [\chisize{+4}] +%D \stopbuffer +%D +%D \typebuffer +%D +%D gives: +%D +%D \getbuffer +%D +%D The full range of sizes is: +%D +%D \starttabulate[|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|] +%D \NC 8 \NC 7 \NC -6 \NC 6 \NC +%D -5 \NC 5 \NC -4 \NC 4 \NC +%D -3 \NC 3 \NC -2 \NC 2 \NC +%D -1 \NC 1 \NC -0 \NC 0 \NC\NR +%D \NC\chisize {8}\NC\chisize{7}\NC\chisize{-6}\NC\chisize{6}\NC +%D \chisize{-5}\NC\chisize{5}\NC\chisize{-4}\NC\chisize{4}\NC +%D \chisize{-3}\NC\chisize{3}\NC\chisize{-2}\NC\chisize{2}\NC +%D \chisize{-1}\NC\chisize{1}\NC\chisize{-0}\NC\chisize{0}\NC\NR +%D \stoptabulate + +%D Now it's time for some real Chinese. This example +%D also shows that font switching is supported. +%D +%D \startnarrower +%D \midaligned{\tfd ˮͷ} +%D \blank +%D \midaligned{\tfb ﵩƪ滳ɡ} +%D \blank +%D \midaligned{\tfb } +%D \blank +%D ¼ʱУѾ졣֪ϹڣϦǺꣿ˷ȥ +%D ֿ¥ߴʤŪӰ˼䣿 +%D \blank +%D ת󣬵ͻߡӦкޣƫʱԲбϣ +%D Բȱ¹ȫԸ˳ãǧﹲ濾ꡣ +%D \stopnarrower +%D +%D The english translation is: +%D +%D \startnarrower +%D \midaligned{\tfd Tune: Prelude to the Melody of Water} +%D \blank +%D \midaligned{\tfb On the night of the Mid||Autumn Festival of +%D 1076, I drank happily till dawn and wrote this in my cups +%D while thinking of Zi||you.} +%D \blank +%D \midaligned{\tfb Su Shi} +%D \blank +%D How long will the bright moon appear? Wine||cup in hand, I +%D ask the sky. I do not know waht time of year it would be +%D tonight in the palace on high. Riding the wind, there I +%D would fly, yet I fear the crystal palace would be far too +%D high and cold for me. I rise and dance, with my shadow I +%D play. On high as on earth, would it be as gay? +%D \blank +%D The moon goes round the mansion red though gauze||draped +%D windows soft to shed her light upon the sleepless bed. +%D Against man she should have no spite. Why then when people +%D part is she oft full and bright? Men have sorrow and joy, +%D they part or meet again; The moon may be bright or dim, she +%D may wax or wane. There has been nothing perfect since the +%D olden days. So let us wish that man will live long as he +%D can! Though miles apart, we'll share the beauty she +%D displays. +%D \stopnarrower + +%D This package is written in the city of Hasselt, a pretty +%D small town in the |<|compared to China real small|>| +%D Netherlands. Like most dutch cities, even this small one +%D has a chinese restaurant, run by chinese, speaking chinese, +%D and |<|indeed|>| writing chinese. Eating there will never +%D be the same, since now I can at least pretend to know the +%D glyphs all around the place. The numbers should pose me no +%D problems, but I fear I will never manage to recognize those +%D scribles they draw on their pads when thay take your order. + +%D To make our lives more easy, we put it here (too): + +\setuptyping[\c!tab=\v!no] + +\protect \endinput diff --git a/tex/context/base/font-chk.lua b/tex/context/base/font-chk.lua new file mode 100644 index 000000000..32fdf8894 --- /dev/null +++ b/tex/context/base/font-chk.lua @@ -0,0 +1,90 @@ +if not modules then modules = { } end modules ['font-chk'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + 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 +local remove_node = nodes.remove + +-- 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) + 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 + head = remove_node(head,found[i],true) + end + end + end + return head, false +end + +trackers.register("fonts.missing", function(v) + tasks.enableaction("processors", "fonts.checkers.missing") -- always on then + checkers.enabled = v +end) + +function checkers.enable(delete) + tasks.enableaction("processors", "fonts.checkers.missing") -- always on then + if delete ~= nil then + checkers.delete = delete + end + checkers.enabled = true +end + diff --git a/tex/context/base/font-cid.lua b/tex/context/base/font-cid.lua new file mode 100644 index 000000000..d1c727af2 --- /dev/null +++ b/tex/context/base/font-cid.lua @@ -0,0 +1,147 @@ +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, lower = string.format, string.match, string.lower +local tonumber = tonumber +local lpegmatch = lpeg.match + +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 = { }, { } + lpegmatch(grammar,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 = format(template,registry,ordering,supplement) + local hashname = lower(filename) + local cidmap = fonts.cid.map[hashname] + 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[hashname] = cidmap + cidmap.usedname = file.basename(filename) + 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 new file mode 100644 index 000000000..d313357a2 --- /dev/null +++ b/tex/context/base/font-col.lua @@ -0,0 +1,216 @@ +if not modules then modules = { } end modules ['font-col'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + 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 + +local format, gmatch, texsprint, type = string.format, string.gmatch, tex.sprint, type +local traverse_id, first_character = node.traverse_id, node.first_character +local lpegmatch = lpeg.match + +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 { } + +local collections = fonts.collections +local definitions = fonts.collections.definitions +local vectors = fonts.collections.vectors + +local list, current, active = { }, 0, false + +-- maybe also a copy + +function collections.reset(name,font) + if font and font ~= "" then + local d = definitions[name] + if d then + d[font] = nil + if not next(d) then + definitions[name] = nil + end + end + else + definitions[name] = nil + end +end + +function collections.define(name,font,ranges,details) + -- todo: details -> method=force|conditional rscale= + -- todo: remap=name + local d = definitions[name] + if d then + if name and trace_collecting then + logs.report("fonts","def: extending set %s using %s",name, font) + end + else + if name and trace_collecting then + logs.report("fonts","def: defining set %s using %s",name, font) + end + d = { } + definitions[name] = d + end + details = aux.settings_to_hash(details) + -- todo, combine per font start/stop as arrays + for s in gmatch(ranges,"([^, ]+)") do + local start, stop, description = characters.getrange(s) + if start and stop then + if trace_collecting then + if description then + 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 U+%04x-U+%04X and U+%04x-U+%04X",start,stop,di.start,di.stop) + end + end + end + details.font, details.start, details.stop = font, start, stop + d[#d+1] = table.fastcopy(details) + end + end +end + +function collections.stage_1(name) + local last = font.current() + if trace_collecting then + logs.report("fonts","def: registering font %s with name %s",last,name) + end + list[#list+1] = last +end + +function collections.stage_2(name) + statistics.starttiming(fonts) + local d = definitions[name] + local t = { } + 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_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",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 = 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 + if remap then + t[i] = { id, remap[i] } + else + t[i] = id + end + end + end + else + for i=start,stop do + if force or (not t[i] and not oldchars[i]) then + if remap then + t[i] = { id, remap[i] } + else + t[i] = id + end + end + end + end + end + vectors[current] = t + if trace_collecting then + logs.report("fonts","def: activating collection %s for font %s",name,current) + end + active = true + statistics.stoptiming(fonts) +end + +local P, Cc = lpeg.P, lpeg.Cc +local spec = (P("sa") + P("at") + P("scaled") + P("at") + P("mo")) * P(" ")^1 * (1-P(" "))^1 * P(" ")^0 * -1 +local okay = ((1-spec)^1 * spec * Cc(true)) + Cc(false) + +-- todo: check for already done + +function collections.prepare(name) + current = font.current() + if vectors[current] then + return + end + local d = definitions[name] + if d then + 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(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 lpegmatch(okay,name) then + texsprint(ctxcatcodes,format("\\doclonefonta{%s}{%s}",name,scale)) -- define with unique specs + else + texsprint(ctxcatcodes,format("\\doclonefontb{%s}{%s}",name,scale)) -- define with inherited specs + end + texsprint(ctxcatcodes,format("\\ctxlua{fonts.collections.stage_1('%s')}",name)) -- registering main font + end + 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 collections.message(message) + if trace_collecting then + logs.report("fonts","tex: %s",message) + end +end + +function collections.process(head) + if active then + local done = false + for n in traverse_id(glyph,head) do + local v = vectors[n.font] + if v then + local id = v[n.char] + if id then + if type(id) == "table" then + local newid, newchar = id[1], id[2] + 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_collecting then + logs.report("fonts","lst: remapping font %s to %s for character %s",n.font,id,n.char) + end + n.font = id + end + end + end + end + end + return head, done +end diff --git a/tex/context/base/font-col.mkiv b/tex/context/base/font-col.mkiv new file mode 100644 index 000000000..181b985f6 --- /dev/null +++ b/tex/context/base/font-col.mkiv @@ -0,0 +1,148 @@ +%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 +% +% actually we can now do more at the lua end + +% 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 + +\unexpanded\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-ctx.lua b/tex/context/base/font-ctx.lua new file mode 100644 index 000000000..76e9f095a --- /dev/null +++ b/tex/context/base/font-ctx.lua @@ -0,0 +1,624 @@ +if not modules then modules = { } end modules ['font-ctx'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- needs a cleanup: merge of replace, lang/script etc + +local texsprint, count, texsetcount = tex.sprint, tex.count, tex.setcount +local format, concat, gmatch, match, find, lower, gsub, byte = string.format, table.concat, string.gmatch, string.match, string.find, string.lower, string.gsub, string.byte + +local tostring, next, type = tostring, next, type +local lpegmatch = lpeg.match +local round = math.round + +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.identifiers +local specify = define.specify + +specify.context_setups = specify.context_setups or { } +specify.context_numbers = specify.context_numbers or { } +specify.context_merged = specify.context_merged or { } +specify.synonyms = specify.synonyms or { } + +local setups = specify.context_setups +local numbers = specify.context_numbers +local merged = specify.context_merged +local synonyms = specify.synonyms +local triggers = fonts.triggers + +--[[ldx-- +<p>So far we haven't really dealt with features (or whatever we want +to pass along with the font definition. We distinguish the following +situations:</p> +situations:</p> + +<code> +name:xetex like specs +name@virtual font spec +name*context specification +</code> +--ldx]]-- + +function specify.predefined(specification) + local detail = specification.detail + if detail ~= "" then + -- detail = gsub(detail,"["..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 == "" and find(parent,"=") then + features = parent + parent = "" + end + if features == "" then + features = { } + elseif type(features) == "string" then + features = normalize_meanings(settings_to_hash(features)) + else + features = normalize_meanings(features) + end + -- 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 features[k] == nil then + features[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 features[v] == nil then -- not false ! + local vv = default_features[v] + if vv then features[v] = vv end + end + end + -- sparse 'm so that we get a better hash and less test (experimental + -- optimization) + local t = { } -- can we avoid t ? + for k,v in next, features do + if v then t[k] = v end + end + -- needed for dynamic features + local number = (setups[name] and setups[name].number) or 0 + if number == 0 then + number = #numbers + 1 + numbers[number] = name + end + t.number = number + setups[name] = t + return number, t +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 leftparent = (P"(") +local rightparent = (P")") +local value = C((leftparent * (1-rightparent)^0 * rightparent + (1-space))^1) +local dimension = C((space/"" + P(1))^1) +local rest = C(P(1)^0) +local scale_none = Cc(0) +local scale_at = P("at") * Cc(1) * spaces * dimension -- value +local scale_sa = P("sa") * Cc(2) * spaces * dimension -- value +local scale_mo = P("mo") * Cc(3) * spaces * dimension -- value +local scale_scaled = P("scaled") * Cc(4) * spaces * dimension -- 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 + +-- we can make helper macros which saves parsing (but normaly not +-- that many calls, e.g. in mk a couple of 100 and in metafun 3500) + +function define.command_1(str) + statistics.starttiming(fonts) + local fullname, size = lpegmatch(splitpattern,str) + local lookup, name, sub, method, detail = get_specification(fullname) + if not name then + logs.report("define font","strange definition '%s'",str) + texsprint(ctxcatcodes,"\\fcglet\\somefontname\\defaultfontfile") + elseif name == "unknown" then + texsprint(ctxcatcodes,"\\fcglet\\somefontname\\defaultfontfile") + else + texsprint(ctxcatcodes,"\\fcxdef\\somefontname{",name,"}") + end + -- we can also use a count for the size + if size and size ~= "" then + local mode, size = lpegmatch(sizepattern,size) + if size and mode then + count.scaledfontmode = mode + texsprint(ctxcatcodes,"\\def\\somefontsize{",size,"}") + else + count.scaledfontmode = 0 + texsprint(ctxcatcodes,"\\let\\somefontsize\\empty") + end + elseif true then + -- so we don't need to check in tex + count.scaledfontmode = 2 + texsprint(ctxcatcodes,"\\let\\somefontsize\\empty") + else + count.scaledfontmode = 0 + texsprint(ctxcatcodes,"\\let\\somefontsize\\empty") + end + specification = define.makespecification(str,lookup,name,sub,method,detail,size) +end + +local n = 0 + +-- we can also move rscale to here (more consistent) + +function define.command_2(global,cs,str,size,classfeatures,fontfeatures,classfallbacks,fontfallbacks,mathsize,textsize,relativeid) + if trace_defining then + logs.report("define font","memory usage before: %s",statistics.memused()) + end + -- 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 + if relativeid and relativeid ~= "" then -- experimental hook + local id = tonumber(relativeid) or 0 + specification.relativeid = id > 0 and id + end + specification.name = name + specification.size = size + specification.sub = (sub and sub ~= "" and sub) or specification.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 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) + texsetcount("global","lastfontid",-1) + 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)) + texsetcount("global","lastfontid",tfmdata) + 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 + texsetcount("global","lastfontid",id) + end + if trace_defining then + logs.report("define font","memory usage after: %s",statistics.memused()) + end + statistics.stoptiming(fonts) +end + +local enable_auto_r_scale = false + +experiments.register("fonts.autorscale", function(v) + enable_auto_r_scale = v +end) + +local calculate_scale = fonts.tfm.calculate_scale + +function fonts.tfm.calculate_scale(tfmtable, scaledpoints, relativeid) + local scaledpoints, delta, units = calculate_scale(tfmtable, scaledpoints, relativeid) + if enable_auto_r_scale and relativeid then -- for the moment this is rather context specific + local relativedata = fontdata[relativeid] + local id_x_height = relativedata and relativedata.parameters and relativedata.parameters.x_height + local tf_x_height = id_x_height and tfmtable.parameters and tfmtable.parameters.x_height * delta + if tf_x_height then + scaledpoints = (id_x_height/tf_x_height) * scaledpoints + delta = scaledpoints/units + end + end + return scaledpoints, delta, units +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 + +-- we need a place for this .. outside the generic scope + +local dimenfactors = number.dimenfactors + +function fonts.dimenfactor(unit,tfmdata) + if unit == "ex" then + return (tfmdata and tfmdata.parameters.x_height) or 655360 + elseif unit == "em" then + return (tfmdata and tfmdata.parameters.em_height) or 655360 + else + return dimenfactors[unit] or unit + end +end + +function fonts.cleanname(name) + texsprint(ctxcatcodes,fonts.names.cleanname(name)) +end + +local p, f = 1, "%0.1fpt" -- normally this value is changed only once + +local stripper = lpeg.patterns.strip_zeros + +function fonts.nbfs(amount,precision) + if precision ~= p then + p = precision + f = "%0." .. p .. "fpt" + end + texsprint(ctxcatcodes,lpegmatch(stripper,format(f,amount/65536))) +end + +-- for the moment here, this will become a chain of extras that is +-- hooked into the ctx registration (or scaler or ...) + +function fonts.set_digit_width(font) + local tfmtable = fontdata[font] + local parameters = tfmtable.parameters + local width = parameters.digitwidth + if not width then + width = round(parameters.quad/2) -- maybe tex.scale + local characters = tfmtable.characters + for i=48,57 do + local wd = round(characters[i].width) + if wd > width then + width = wd + end + end + parameters.digitwidth = width + end + return width +end + +fonts.get_digit_width = fonts.set_digit_width + +-- soon to be obsolete: + +local loaded = { -- prevent loading (happens in cont-sys files) + ["original-base.map" ] = true, + ["original-ams-base.map" ] = true, + ["original-ams-euler.map"] = true, + ["original-public-lm.map"] = true, +} + +function fonts.map.loadfile(name) + name = file.addsuffix(name,"map") + if not loaded[name] then + pdf.mapfile(name) + loaded[name] = true + end +end + +local loaded = { -- prevent double loading +} + +function fonts.map.loadline(how,line) + if line then + how = how .. " " .. line + elseif how == "" then + how = "= " .. line + end + if not loaded[how] then + pdf.mapline(how) + loaded[how] = true + end +end + +function fonts.map.reset() + pdf.mapfile("") +end + +fonts.map.reset() -- resets the default file + +-- we need an 'do after the banner hook' + +-- pdf.mapfile("mkiv-base.map") -- loads the default file + +local nounicode = byte("?") + +local function name_to_slot(name) -- maybe some day rawdata + local tfmdata = fonts.ids[font.current()] + local shared = tfmdata and tfmdata.shared + local fntdata = shared and shared.otfdata or shared.afmdata + if fntdata then + local unicode = fntdata.luatex.unicodes[name] + if not unicode then + return nounicode + elseif type(unicode) == "number" then + return unicode + else -- multiple unicodes + return unicode[1] + end + end + return nounicode +end + +fonts.name_to_slot = name_to_slot + +function fonts.char(n) -- todo: afm en tfm + if type(n) == "string" then + n = name_to_slot(n) + end + if type(n) == "number" then + texsprint(ctxcatcodes,format("\\char%s ",n)) + end +end + +-- moved from ini: + +fonts.color = { } -- dummy in ini + +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 become obsolete: + +fonts.otf.name_to_slot = name_to_slot +fonts.afm.name_to_slot = name_to_slot + +fonts.otf.char = fonts.char +fonts.afm.char = fonts.char + +-- 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 + write_nl(format("%s @ %s => U%04X => %s => ",tfmdata.fullname,tfmdata.size,n,utf.char(n)) .. serialize(chr,false)) + end + end +end + +function fonts.show_font_parameters() + local tfmdata = fonts.ids[font.current()] + if tfmdata then + local parameters, mathconstants = tfmdata.parameters, tfmdata.MathConstants + local hasparameters, hasmathconstants = parameters and next(parameters), mathconstants and next(mathconstants) + if hasparameters then + write_nl(format("%s @ %s => parameters => ",tfmdata.fullname,tfmdata.size) .. serialize(parameters,false)) + end + if hasmathconstants then + write_nl(format("%s @ %s => math constants => ",tfmdata.fullname,tfmdata.size) .. serialize(mathconstants,false)) + end + if not hasparameters and not hasmathconstants then + write_nl(format("%s @ %s => no parameters and/or mathconstants",tfmdata.fullname,tfmdata.size)) + end + end +end diff --git a/tex/context/base/font-def.lua b/tex/context/base/font-def.lua new file mode 100644 index 000000000..c3b10162c --- /dev/null +++ b/tex/context/base/font-def.lua @@ -0,0 +1,651 @@ +if not modules then modules = { } end modules ['font-def'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + 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 lpegmatch = lpeg.match + +local trace_defining = false trackers .register("fonts.defining", function(v) trace_defining = v end) +local directive_embedall = false directives.register("fonts.embedall", function(v) directive_embedall = v end) + +trackers.register("fonts.loading", "fonts.defining", "otf.loading", "afm.loading", "tfm.loading") +trackers.register("fonts.all", "fonts.*", "otf.*", "afm.*", "tfm.*") + +--[[ldx-- +<p>Here we deal with defining fonts. We do so by intercepting the +default loader that only handles <l n='tfm'/>.</p> +--ldx]]-- + +fonts = fonts or { } +fonts.define = fonts.define or { } +fonts.tfm = fonts.tfm or { } +fonts.ids = fonts.ids or { } +fonts.vf = fonts.vf or { } +fonts.used = fonts.used or { } + +local tfm = fonts.tfm +local vf = fonts.vf +local define = fonts.define + +tfm.version = 1.01 +tfm.cache = containers.define("fonts", "tfm", tfm.version, false) -- better in font-tfm + +define.method = "afm or tfm" -- afm, tfm, afm or tfm, tfm or afm +define.specify = fonts.define.specify or { } +define.methods = fonts.define.methods or { } + +tfm.fonts = tfm.fonts or { } +tfm.readers = tfm.readers or { } +tfm.internalized = tfm.internalized or { } -- internal tex numbers + +tfm.readers.sequence = { 'otf', 'ttf', 'afm', 'tfm' } + +tfm.auto_afm = true + +local readers = tfm.readers +local sequence = readers.sequence + +--[[ldx-- +<p>We hardly gain anything when we cache the final (pre scaled) +<l n='tfm'/> table. But it can be handy for debugging.</p> +--ldx]]-- + +fonts.version = 1.05 +fonts.cache = containers.define("fonts", "def", fonts.version, false) + +--[[ldx-- +<p>We can prefix a font specification by <type>name:</type> or +<type>file:</type>. The first case will result in a lookup in the +synonym table.</p> + +<typing> +[ name: | file: ] identifier [ separator [ specification ] ] +</typing> + +<p>The following function split the font specification into components +and prepares a table that will move along as we proceed.</p> +--ldx]]-- + +-- beware, we discard additional specs +-- +-- method:name method:name(sub) method:name(sub)*spec method:name*spec +-- name name(sub) name(sub)*spec name*spec +-- name@spec*oeps + +local splitter, specifiers = nil, "" + +local P, C, S, Cc = lpeg.P, lpeg.C, lpeg.S, lpeg.Cc + +local left = P("(") +local right = P(")") +local colon = P(":") +local space = P(" ") + +define.defaultlookup = "file" + +local prefixpattern = P(false) + +function define.add_specifier(symbol) + specifiers = specifiers .. symbol + local method = S(specifiers) + local lookup = C(prefixpattern) * colon + local sub = left * C(P(1-left-right-method)^1) * right + local specification = C(method) * C(P(1)^1) + local name = C((1-sub-specification)^1) + splitter = P((lookup + Cc("")) * name * (sub + Cc("")) * (specification + Cc(""))) +end + +function define.add_lookup(str,default) + prefixpattern = prefixpattern + P(str) +end + +define.add_lookup("file") +define.add_lookup("name") +define.add_lookup("spec") + +function define.get_specification(str) + return lpegmatch(splitter,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 not lookup or lookup == "" then + lookup = define.defaultlookup + end + local t = { + lookup = lookup, -- forced type + specification = specification, -- full specification + size = size, -- size in scaled points or -1000*n + name = name, -- font or filename + sub = sub, -- subfont (eg in ttc) + method = method, -- specification method + detail = detail, -- specification + resolved = "", -- resolved font name + forced = "", -- forced loader + features = { }, -- preprocessed features + } + return t +end + +function define.analyze(specification, size) + -- can be optimized with locals + local lookup, name, sub, method, detail = define.get_specification(specification or "") + return define.makespecification(specification, lookup, name, sub, method, detail, size) +end + +--[[ldx-- +<p>A unique hash value is generated by:</p> +--ldx]]-- + +local sortedhashkeys = table.sortedhashkeys + +function tfm.hash_features(specification) + local features = specification.features + if features then + local t = { } + local normal = features.normal + if normal and next(normal) then + local f = sortedhashkeys(normal) + for i=1,#f do + local v = f[i] + if v ~= "number" and v ~= "features" then -- i need to figure this out, features + t[#t+1] = v .. '=' .. tostring(normal[v]) + end + end + end + local vtf = features.vtf + if vtf and next(vtf) then + local f = sortedhashkeys(vtf) + for i=1,#f do + local v = f[i] + t[#t+1] = v .. '=' .. tostring(vtf[v]) + end + end +--~ if specification.mathsize then +--~ t[#t+1] = "mathsize=" .. specification.mathsize +--~ end + if #t > 0 then + return concat(t,"+") + end + end + return "unknown" +end + +fonts.designsizes = { } + +--[[ldx-- +<p>In principle we can share tfm tables when we are in node for a font, but then +we need to define a font switch as an id/attr switch which is no fun, so in that +case users can best use dynamic features ... so, we will not use that speedup. Okay, +when we get rid of base mode we can optimize even further by sharing, but then we +loose our testcases for <l n='luatex'/>.</p> +--ldx]]-- + +function tfm.hash_instance(specification,force) + local hash, size, fallbacks = specification.hash, specification.size, specification.fallbacks + if force or not hash then + hash = tfm.hash_features(specification) + specification.hash = hash + end + if size < 1000 and fonts.designsizes[hash] then + size = math.round(tfm.scaled(size, fonts.designsizes[hash])) + specification.size = size + end +--~ local mathsize = specification.mathsize or 0 +--~ if mathsize > 0 then +--~ local textsize = specification.textsize +--~ if fallbacks then +--~ return hash .. ' @ ' .. tostring(size) .. ' [ ' .. tostring(mathsize) .. ' : ' .. tostring(textsize) .. ' ] @ ' .. fallbacks +--~ else +--~ return hash .. ' @ ' .. tostring(size) .. ' [ ' .. tostring(mathsize) .. ' : ' .. tostring(textsize) .. ' ]' +--~ end +--~ else + if fallbacks then + return hash .. ' @ ' .. tostring(size) .. ' @ ' .. fallbacks + else + return hash .. ' @ ' .. tostring(size) + end +--~ end +end + +--[[ldx-- +<p>We can resolve the filename using the next function:</p> +--ldx]]-- + +define.resolvers = resolvers + +function define.resolvers.file(specification) + specification.forced = file.extname(specification.name) + specification.name = file.removesuffix(specification.name) +end + +function define.resolvers.name(specification) + local resolve = fonts.names.resolve + if resolve 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 + else + define.resolvers.file(specification) + end +end + +function define.resolvers.spec(specification) + local resolvespec = fonts.names.resolvespec + if resolvespec then + specification.resolved, specification.sub = fonts.names.resolvespec(specification.name,specification.sub) + if specification.resolved then + specification.forced = file.extname(specification.resolved) + specification.name = file.removesuffix(specification.resolved) + end + else + define.resolvers.name(specification) + end +end + +function define.resolve(specification) + if not specification.resolved or specification.resolved == "" then -- resolved itself not per se in mapping hash + local r = define.resolvers[specification.lookup] + if r then + r(specification) + end + end + if specification.forced == "" then + specification.forced = nil + else + specification.forced = specification.forced + end + specification.hash = lower(specification.name .. ' @ ' .. tfm.hash_features(specification)) + if specification.sub and specification.sub ~= "" then + specification.hash = specification.sub .. ' @ ' .. specification.hash + end + return specification +end + +--[[ldx-- +<p>The main read function either uses a forced reader (as determined by +a lookup) or tries to resolve the name using the list of readers.</p> + +<p>We need to cache when possible. We do cache raw tfm data (from <l +n='tfm'/>, <l n='afm'/> or <l n='otf'/>). After that we can cache based +on specificstion (name) and size, that is, <l n='tex'/> only needs a number +for an already loaded fonts. However, it may make sense to cache fonts +before they're scaled as well (store <l n='tfm'/>'s with applied methods +and features). However, there may be a relation between the size and +features (esp in virtual fonts) so let's not do that now.</p> + +<p>Watch out, here we do load a font, but we don't prepare the +specification yet.</p> +--ldx]]-- + +function tfm.read(specification) + local hash = tfm.hash_instance(specification) + local tfmtable = tfm.fonts[hash] -- hashes by size ! + if not tfmtable then + local forced = specification.forced or "" + if forced ~= "" then + tfmtable = readers[lower(forced)](specification) + if not tfmtable then + logs.report("define font","forced type %s of %s not found",forced,specification.name) + end + else + for s=1,#sequence do -- reader sequence + local reader = sequence[s] + if readers[reader] then -- not really needed + if trace_defining then + logs.report("define font","trying (reader sequence driven) type %s for %s with file %s",reader,specification.name,specification.filename or "unknown") + end + tfmtable = readers[reader](specification) + if tfmtable then + break + else + specification.filename = nil + end + end + end + end + if tfmtable then + if directive_embedall then + tfmtable.embedding = "full" + elseif tfmtable.filename and fonts.dontembed[tfmtable.filename] then + tfmtable.embedding = "no" + else + tfmtable.embedding = "subset" + end + tfm.fonts[hash] = tfmtable + fonts.designsizes[specification.hash] = tfmtable.designsize -- we only know this for sure after loading once + --~ tfmtable.mode = specification.features.normal.mode or "base" + end + end + if not tfmtable then + logs.report("define font","font with name %s is not found",specification.name) + end + return tfmtable +end + +--[[ldx-- +<p>For virtual fonts we need a slightly different approach:</p> +--ldx]]-- + +function tfm.read_and_define(name,size) -- no id + local specification = define.analyze(name,size) + local method = specification.method + if method and define.specify[method] then + specification = define.specify[method](specification) + end + specification = define.resolve(specification) + local hash = tfm.hash_instance(specification) + local id = define.registered(hash) + if not id then + local fontdata = tfm.read(specification) + if fontdata then + fontdata.hash = hash + id = font.define(fontdata) + define.register(fontdata,id) + tfm.cleanup_table(fontdata) + else + id = 0 -- signal + end + end + return fonts.ids[id], id +end + +--[[ldx-- +<p>Next follow the readers. This code was written while <l n='luatex'/> +evolved. Each one has its own way of dealing with its format.</p> +--ldx]]-- + +local function check_tfm(specification,fullname) + -- ofm directive blocks local path search unless set; btw, in context we + -- don't support ofm files anyway as this format is obsolete + local foundname = resolvers.findbinfile(fullname, 'tfm') or "" -- just to be sure + if foundname == "" then + foundname = resolvers.findbinfile(fullname, 'ofm') or "" -- bonus for usage outside context + end + if foundname ~= "" then + specification.filename, specification.format = foundname, "ofm" + return tfm.read_from_tfm(specification) + end +end + +local function check_afm(specification,fullname) + local foundname = resolvers.findbinfile(fullname, 'afm') or "" -- just to be sure + if foundname == "" and tfm.auto_afm then + local encoding, shortname = match(fullname,"^(.-)%-(.*)$") -- context: encoding-name.* + if encoding and shortname and fonts.enc.known[encoding] then + shortname = resolvers.findbinfile(shortname,'afm') or "" -- just to be sure + if shortname ~= "" then + foundname = shortname + -- tfm.set_normal_feature(specification,'encoding',encoding) -- will go away + if trace_loading then + logs.report("load afm","stripping encoding prefix from filename %s",afmname) + end + end + end + end + if foundname ~= "" then + specification.filename, specification.format = foundname, "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 + +-- maybe some day a set of names + +local function check_otf(forced,specification,suffix,what) + local name = specification.name + if forced then + name = file.addsuffix(name,suffix) + end + local fullname, tfmtable = resolvers.findbinfile(name,suffix) or "", nil -- one shot + if fullname == "" then + local fb = fonts.names.old_to_new[name] + if fb then + fullname = resolvers.findbinfile(fb,suffix) or "" + end + end + if fullname == "" then + local fb = fonts.names.new_to_old[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(true,specification,forced,"opentype") + elseif forced == "ttf" or forced == "ttc" or forced == "dfont" then + return check_otf(true,specification,forced,"truetype") + else + return check_otf(false,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 -- !! +function readers.dfont(specification) return readers.opentype(specification,"ttf","truetype") end -- !! + +--[[ldx-- +<p>We need to check for default features. For this we provide +a helper function.</p> +--ldx]]-- + +function define.check(features,defaults) -- nb adapts features ! + local done = false + if features and next(features) then + for k,v in next, defaults do + if features[k] == nil then + features[k], done = v, true + end + end + else + features, done = table.fastcopy(defaults), true + end + return features, done -- done signals a change +end + +--[[ldx-- +<p>So far the specifyers. Now comes the real definer. Here we cache +based on id's. Here we also intercept the virtual font handler. Since +it evolved stepwise I may rewrite this bit (combine code).</p> + +In the previously defined reader (the one resulting in a <l n='tfm'/> +table) we cached the (scaled) instances. Here we cache them again, but +this time based on id. We could combine this in one cache but this does +not gain much. By the way, passing id's back to in the callback was +introduced later in the development.</p> +--ldx]]-- + +define.last = nil + +function define.register(fontdata,id) + if fontdata and id then + local hash = fontdata.hash + if not tfm.internalized[hash] then + if trace_defining then + logs.report("define font","loading at 2 id %s, hash: %s",id or "?",hash or "?") + end + fonts.identifiers[id] = fontdata + fonts.characters [id] = fontdata.characters + fonts.quads [id] = fontdata.parameters.quad + -- todo: extra functions, e.g. setdigitwidth etc in list + 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, name:%s size:%s bytes:%s encoding:%s fullname:%s filename:%s", + fontdata.type or "unknown", + id or "?", + fontdata.name or "?", + fontdata.size or "default", + fontdata.encodingbytes or "?", + fontdata.encodingname or "unicode", + fontdata.fullname or "?", + file.basename(fontdata.filename or "?")) + + end + statistics.stoptiming(fonts) + return fontdata +end + +function vf.find(name) + name = file.removesuffix(file.basename(name)) + if tfm.resolve_vf then + local format = fonts.logger.format(name) + if format == 'tfm' or format == 'ofm' then + if trace_defining then + logs.report("define font","locating vf for %s",name) + end + return resolvers.findbinfile(name,"ovf") + else + if trace_defining then + logs.report("define font","vf for %s is already taken care of",name) + end + return nil -- "" + end + else + if trace_defining then + logs.report("define font","locating vf for %s",name) + end + return resolvers.findbinfile(name,"ovf") + end +end + +--[[ldx-- +<p>We overload both the <l n='tfm'/> and <l n='vf'/> readers.</p> +--ldx]]-- + +callbacks.register('define_font' , define.read, "definition of fonts (tfmtable preparation)") +callbacks.register('find_vf_file', vf.find , "locating virtual fonts, insofar needed") -- 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..0a9bcd301 --- /dev/null +++ b/tex/context/base/font-dum.lua @@ -0,0 +1,301 @@ +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 -- only makes sense in context +fonts.tfm.resolve_vf = false -- no sure about this +fonts.tfm.fontname_mode = "specification" -- somehow latex needs 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 +-- +-- Watch out, the version number is the same as the one used in +-- the mtx-fonts.lua function scripts.fonts.names as we use a +-- simplified font database in the plain solution and by using +-- a different number we're less dependent on context. + +fonts.names = fonts.names or { } + +fonts.names.version = 1.001 -- not the same as in context +fonts.names.basename = "luatex-fonts-names.lua" +fonts.names.new_to_old = { } +fonts.names.old_to_new = { } + +local data, loaded = nil, false + +local fileformats = { "lua", "tex", "other text files" } + +function fonts.names.resolve(name,sub) + if not loaded then + local basename = fonts.names.basename + if basename and basename ~= "" then + for i=1,#fileformats do + local format = fileformats[i] + local foundname = resolvers.find_file(basename,format) or "" + if foundname ~= "" then + data = dofile(foundname) + break + end + end + end + loaded = true + end + if type(data) == "table" and data.version == fonts.names.version then + local condensed = string.gsub(string.lower(name),"[^%a%d]","") + local found = data.mappings and data.mappings[condensed] + if found then + local fontname, filename, subfont = found[1], found[2], found[3] + if subfont then + return filename, fontname + else + return filename, false + end + else + return name, false -- fallback to filename + end + end +end + +fonts.names.resolvespec = fonts.names.resolve -- only supported in mkiv + +-- 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 + +-- slant and extend + +function fonts.initializers.common.slant(tfmdata,value) + value = tonumber(value) + if not value then + value = 0 + elseif value > 1 then + value = 1 + elseif value < -1 then + value = -1 + end + tfmdata.slant_factor = value +end + +function fonts.initializers.common.extend(tfmdata,value) + value = tonumber(value) + if not value then + value = 0 + elseif value > 10 then + value = 10 + elseif value < -10 then + value = -10 + end + tfmdata.extend_factor = value +end + +table.insert(fonts.triggers,"slant") +table.insert(fonts.triggers,"extend") + +fonts.initializers.base.otf.slant = fonts.initializers.common.slant +fonts.initializers.node.otf.slant = fonts.initializers.common.slant +fonts.initializers.base.otf.extend = fonts.initializers.common.extend +fonts.initializers.node.otf.extend = fonts.initializers.common.extend + +-- expansion and protrusion + +fonts.protrusions = fonts.protrusions or { } +fonts.protrusions.setups = fonts.protrusions.setups or { } + +local setups = fonts.protrusions.setups + +function fonts.initializers.common.protrusion(tfmdata,value) + if value then + local setup = setups[value] + if setup then + local factor, left, right = setup.factor or 1, setup.left or 1, setup.right or 1 + local emwidth = tfmdata.parameters.quad + tfmdata.auto_protrude = true + for i, chr in next, tfmdata.characters do + local v, pl, pr = setup[i], nil, nil + if v then + pl, pr = v[1], v[2] + end + if pl and pl ~= 0 then chr.left_protruding = left *pl*factor end + if pr and pr ~= 0 then chr.right_protruding = right*pr*factor end + end + end + end +end + +fonts.expansions = fonts.expansions or { } +fonts.expansions.setups = fonts.expansions.setups or { } + +local setups = fonts.expansions.setups + +function fonts.initializers.common.expansion(tfmdata,value) + if value then + local setup = setups[value] + if setup then + local stretch, shrink, step, factor = setup.stretch or 0, setup.shrink or 0, setup.step or 0, setup.factor or 1 + tfmdata.stretch, tfmdata.shrink, tfmdata.step, tfmdata.auto_expand = stretch * 10, shrink * 10, step * 10, true + for i, chr in next, tfmdata.characters do + local v = setup[i] + if v and v ~= 0 then + chr.expansion_factor = v*factor + else -- can be option + chr.expansion_factor = factor + end + end + end + end +end + +table.insert(fonts.manipulators,"protrusion") +table.insert(fonts.manipulators,"expansion") + +fonts.initializers.base.otf.protrusion = fonts.initializers.common.protrusion +fonts.initializers.node.otf.protrusion = fonts.initializers.common.protrusion +fonts.initializers.base.otf.expansion = fonts.initializers.common.expansion +fonts.initializers.node.otf.expansion = fonts.initializers.common.expansion + +-- left over + +function fonts.register_message() +end + +-- example vectors + +local byte = string.byte + +fonts.expansions.setups['default'] = { + + stretch = 2, shrink = 2, step = .5, factor = 1, + + [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, + [byte('S')] = 0.7, [byte('U')] = 0.7, [byte('W')] = 0.7, [byte('Z')] = 0.7, + [byte('a')] = 0.7, [byte('b')] = 0.7, [byte('c')] = 0.7, [byte('d')] = 0.7, [byte('e')] = 0.7, + [byte('g')] = 0.7, [byte('h')] = 0.7, [byte('k')] = 0.7, [byte('m')] = 0.7, [byte('n')] = 0.7, + [byte('o')] = 0.7, [byte('p')] = 0.7, [byte('q')] = 0.7, [byte('s')] = 0.7, [byte('u')] = 0.7, + [byte('w')] = 0.7, [byte('z')] = 0.7, + [byte('2')] = 0.7, [byte('3')] = 0.7, [byte('6')] = 0.7, [byte('8')] = 0.7, [byte('9')] = 0.7, +} + +fonts.protrusions.setups['default'] = { + + factor = 1, left = 1, right = 1, + + [0x002C] = { 0, 1 }, -- comma + [0x002E] = { 0, 1 }, -- period + [0x003A] = { 0, 1 }, -- colon + [0x003B] = { 0, 1 }, -- semicolon + [0x002D] = { 0, 1 }, -- hyphen + [0x2013] = { 0, 0.50 }, -- endash + [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 ۔ + +} + +-- normalizer + +fonts.otf.meanings = fonts.otf.meanings or { } + +fonts.otf.meanings.normalize = fonts.otf.meanings.normalize or function(t) + if t.rand then + t.rand = "random" + end +end + +-- bonus + +function fonts.otf.name_to_slot(name) + local tfmdata = fonts.ids[font.current()] + if tfmdata and tfmdata.shared then + local otfdata = tfmdata.shared.otfdata + local unicode = otfdata.luatex.unicodes[name] + return unicode and (type(unicode) == "number" and unicode or unicode[1]) + end +end + +function fonts.otf.char(n) + if type(n) == "string" then + n = fonts.otf.name_to_slot(n) + end + if type(n) == "number" then + tex.sprint("\\char" .. n) + end +end + +-- another one: + +fonts.strippables = table.tohash { + 0x000AD, 0x017B4, 0x017B5, 0x0200B, 0x0200C, 0x0200D, 0x0200E, 0x0200F, 0x0202A, 0x0202B, + 0x0202C, 0x0202D, 0x0202E, 0x02060, 0x02061, 0x02062, 0x02063, 0x0206A, 0x0206B, 0x0206C, + 0x0206D, 0x0206E, 0x0206F, 0x0FEFF, 0x1D173, 0x1D174, 0x1D175, 0x1D176, 0x1D177, 0x1D178, + 0x1D179, 0x1D17A, 0xE0001, 0xE0020, 0xE0021, 0xE0022, 0xE0023, 0xE0024, 0xE0025, 0xE0026, + 0xE0027, 0xE0028, 0xE0029, 0xE002A, 0xE002B, 0xE002C, 0xE002D, 0xE002E, 0xE002F, 0xE0030, + 0xE0031, 0xE0032, 0xE0033, 0xE0034, 0xE0035, 0xE0036, 0xE0037, 0xE0038, 0xE0039, 0xE003A, + 0xE003B, 0xE003C, 0xE003D, 0xE003E, 0xE003F, 0xE0040, 0xE0041, 0xE0042, 0xE0043, 0xE0044, + 0xE0045, 0xE0046, 0xE0047, 0xE0048, 0xE0049, 0xE004A, 0xE004B, 0xE004C, 0xE004D, 0xE004E, + 0xE004F, 0xE0050, 0xE0051, 0xE0052, 0xE0053, 0xE0054, 0xE0055, 0xE0056, 0xE0057, 0xE0058, + 0xE0059, 0xE005A, 0xE005B, 0xE005C, 0xE005D, 0xE005E, 0xE005F, 0xE0060, 0xE0061, 0xE0062, + 0xE0063, 0xE0064, 0xE0065, 0xE0066, 0xE0067, 0xE0068, 0xE0069, 0xE006A, 0xE006B, 0xE006C, + 0xE006D, 0xE006E, 0xE006F, 0xE0070, 0xE0071, 0xE0072, 0xE0073, 0xE0074, 0xE0075, 0xE0076, + 0xE0077, 0xE0078, 0xE0079, 0xE007A, 0xE007B, 0xE007C, 0xE007D, 0xE007E, 0xE007F, +} + diff --git a/tex/context/base/font-enc.lua b/tex/context/base/font-enc.lua new file mode 100644 index 000000000..874f7c3f4 --- /dev/null +++ b/tex/context/base/font-enc.lua @@ -0,0 +1,122 @@ +if not modules then modules = { } end modules ['font-enc'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local match, gmatch, gsub = string.match, string.gmatch, string.gsub + +--[[ldx-- +<p>Because encodings are going to disappear, we don't bother defining +them in tables. But we may do so some day, for consistency.</p> +--ldx]]-- + +fonts.enc = fonts.enc or { } +fonts.enc.version = 1.03 +fonts.enc.cache = containers.define("fonts", "enc", fonts.enc.version, true) + +fonts.enc.known = { -- sort of obsolete + texnansi = true, + ec = true, + qx = true, + t5 = true, + t2a = true, + t2b = true, + t2c = true, + unicode = true +} + +function fonts.enc.is_known(encoding) + return containers.is_valid(fonts.enc.cache(),encoding) +end + +--[[ldx-- +<p>An encoding file looks like this:</p> + +<typing> +/TeXnANSIEncoding [ +/.notdef +/Euro +... +/ydieresis +] def +</typing> + +<p>Beware! The generic encoding files don't always apply to the ones that +ship with fonts. This has to do with the fact that names follow (slightly) +different standards. However, the fonts where this applies to (for instance +Latin Modern or <l n='tex'> Gyre) come in OpenType variants too, so these +will be used.</p> +--ldx]]-- + +function fonts.enc.load(filename) + local name = file.removesuffix(filename) + local data = containers.read(fonts.enc.cache(),name) + if data then + return data + end + if name == "unicode" then + data = fonts.enc.make_unicode_vector() -- special case, no tex file for this + end + if data then + return data + end + local vector, tag, hash, unicodes = { }, "", { }, { } + local foundname = resolvers.find_file(filename,'enc') + if foundname and foundname ~= "" then + local ok, encoding, size = resolvers.loadbinfile(foundname) + if ok and encoding then + local enccodes = characters.enccodes + encoding = gsub(encoding,"%%(.-)\n","") + local tag, vec = match(encoding,"/(%w+)%s*%[(.*)%]%s*def") + local i = 0 + for ch in gmatch(vec,"/([%a%d%.]+)") do + if ch ~= ".notdef" then + vector[i] = ch + if not hash[ch] then + hash[ch] = i + else + -- duplicate, play safe for tex ligs and take first + end + if enccodes[ch] then + unicodes[enccodes[ch]] = i + end + end + i = i + 1 + end + end + end + local data = { + name=name, + tag=tag, + vector=vector, + hash=hash, + unicodes=unicodes + } + return containers.write(fonts.enc.cache(), name, data) +end + +--[[ldx-- +<p>There is no unicode encoding but for practical purposed we define +one.</p> +--ldx]]-- + +-- maybe make this a function: + +function fonts.enc.make_unicode_vector() + local vector, hash = { }, { } + for code, v in next, characters.data do + local name = v.adobename + if name then + vector[code], hash[name] = name, code + else + vector[code] = '.notdef' + end + end + 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 }) +end diff --git a/tex/context/base/font-enh.lua b/tex/context/base/font-enh.lua new file mode 100644 index 000000000..fc70c04c5 --- /dev/null +++ b/tex/context/base/font-enh.lua @@ -0,0 +1,201 @@ +if not modules then modules = { } end modules ['font-enh'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local next, match = next, string.match + +local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) + +-- tfmdata has also fast access to indices and unicodes +-- to be checked: otf -> tfm -> tfmscaled +-- +-- watch out: no negative depths and negative eights permitted in regular fonts + +--[[ldx-- +<p>Here we only implement a few helper functions.</p> +--ldx]]-- + +local tfm = fonts.tfm + +--[[ldx-- +<p>The next function encapsulates the standard <l n='tfm'/> loader as +supplied by <l n='luatex'/>.</p> +--ldx]]-- + +-- 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 features and next(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 font","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 + +--~ obsolete +--~ +--~ 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 diff --git a/tex/context/base/font-ext.lua b/tex/context/base/font-ext.lua new file mode 100644 index 000000000..05bdaf2fc --- /dev/null +++ b/tex/context/base/font-ext.lua @@ -0,0 +1,623 @@ +if not modules then modules = { } end modules ['font-ext'] = { + version = 1.001, + comment = "companion to font-ini.mkiv and hand-ini.mkiv", + 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, byte = next, type, string.byte +local gmatch, concat = string.gmatch, table.concat +local utfchar = utf.char + +local trace_protrusion = false trackers.register("fonts.protrusion", function(v) trace_protrusion = v end) +local trace_expansion = false trackers.register("fonts.expansion", function(v) trace_expansion = v end) + +commands = commands or { } + +--[[ldx-- +<p>When we implement functions that deal with features, most of them +will depend of the font format. Here we define the few that are kind +of neutral.</p> +--ldx]]-- + +fonts.triggers = fonts.triggers or { } +fonts.initializers = fonts.initializers or { } +fonts.methods = fonts.methods or { } +fonts.initializers.common = fonts.initializers.common or { } + +local initializers = fonts.initializers +local methods = fonts.methods + +--[[ldx-- +<p>This feature will remove inter-digit kerns.</p> +--ldx]]-- + +table.insert(fonts.triggers,"equaldigits") + +function initializers.common.equaldigits(tfmdata,value) + if value then + local chr = tfmdata.characters + for i = utfbyte('0'), utfbyte('9') do + local c = chr[i] + if c then + c.kerns = nil + end + end + end +end + +--[[ldx-- +<p>This feature will give all glyphs an equal height and/or depth. Valid +values are <type>none</type>, <type>height</type>, <type>depth</type> and +<type>both</type>.</p> +--ldx]]-- + +table.insert(fonts.triggers,"lineheight") + +function initializers.common.lineheight(tfmdata,value) + if value and type(value) == "string" then + if value == "none" then + for _,v in next, tfmdata.characters do + v.height, v.depth = 0, 0 + end + else + local ascender, descender = tfmdata.ascender, tfmdata.descender + if ascender and descender then + local ht, dp = ascender or 0, descender or 0 + if value == "height" then + dp = 0 + elseif value == "depth" then + ht = 0 + end + if ht > 0 then + if dp > 0 then + for _,v in next, tfmdata.characters do + v.height, v.depth = ht, dp + end + else + for _,v in next, tfmdata.characters do + v.height = ht + end + end + elseif dp > 0 then + for _,v in next, tfmdata.characters do + v.depth = dp + end + end + end + end + end +end + +-- -- -- -- -- -- +-- shared +-- -- -- -- -- -- + +local function get_class_and_vector(tfmdata,value,where) -- "expansions" + local g_where = tfmdata.goodies and tfmdata.goodies[where] + local f_where = fonts[where] + local g_classes = g_where and g_where.classes + local class = g_where and g_where[value] or f_where.classes[value] + if class then + local class_vector = class.vector + local g_vectors = g_where and g_where.vectors + local vector = g_vectors and g_vectors[class_vector] or f_where.vectors[class_vector] + return class, vector + end +end + +-- -- -- -- -- -- +-- expansion (hz) +-- -- -- -- -- -- + +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 + +classes.preset = { stretch = 2, shrink = 2, step = .5, factor = 1 } + +function commands.setupfontexpansion(class,settings) + aux.getparameters(classes,class,'preset',settings) +end + +classes['quality'] = { + stretch = 2, shrink = 2, step = .5, vector = 'default', factor = 1 +} + +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, + [byte('S')] = 0.7, [byte('U')] = 0.7, [byte('W')] = 0.7, [byte('Z')] = 0.7, + [byte('a')] = 0.7, [byte('b')] = 0.7, [byte('c')] = 0.7, [byte('d')] = 0.7, [byte('e')] = 0.7, + [byte('g')] = 0.7, [byte('h')] = 0.7, [byte('k')] = 0.7, [byte('m')] = 0.7, [byte('n')] = 0.7, + [byte('o')] = 0.7, [byte('p')] = 0.7, [byte('q')] = 0.7, [byte('s')] = 0.7, [byte('u')] = 0.7, + [byte('w')] = 0.7, [byte('z')] = 0.7, + [byte('2')] = 0.7, [byte('3')] = 0.7, [byte('6')] = 0.7, [byte('8')] = 0.7, [byte('9')] = 0.7, +} + +vectors['quality'] = vectors['default'] -- metatable ? + +--~ function table.locator(...) +--~ local k = { ... } +--~ return function(t) +--~ for i=1,#k do +--~ t = t[k[i]] +--~ if not k then +--~ return false +--~ end +--~ end +--~ return t +--~ end +--~ end + +--~ local locate = table.locator { "goodies", "expansions" } + +function initializers.common.expansion(tfmdata,value) + if value then + local class, vector = get_class_and_vector(tfmdata,value,"expansions") + if class then + if vector then + local stretch, shrink, step, factor = class.stretch or 0, class.shrink or 0, class.step or 0, class.factor or 1 + if trace_expansion then + logs.report("fonts","set expansion class %s, vector: %s, factor: %s, stretch: %s, shrink: %s, step: %s",value,class_vector,factor,stretch,shrink,step) + end + tfmdata.stretch, tfmdata.shrink, tfmdata.step, tfmdata.auto_expand = stretch * 10, shrink * 10, step * 10, true + local data = characters and characters.data + for i, chr in next, tfmdata.characters do + local v = vector[i] + if data and not v then -- we could move the data test outside (needed for plain) + local d = data[i] + if d then + local s = d.shcode + if not s then + -- sorry + elseif type(s) == "table" then + v = ((vector[s[1]] or 0) + (vector[s[#s]] or 0)) / 2 + else + v = vector[s] or 0 + end + end + end + if v and v ~= 0 then + chr.expansion_factor = v*factor + else -- can be option + chr.expansion_factor = factor + end + end + elseif trace_expansion then + logs.report("fonts","unknown expansion vector '%s' in class '%s",class_vector,value) + end + elseif trace_expansion then + logs.report("fonts","unknown expansion class '%s'",value) + end + end +end + +table.insert(fonts.manipulators,"expansion") + +initializers.base.otf.expansion = initializers.common.expansion +initializers.node.otf.expansion = initializers.common.expansion + +initializers.base.afm.expansion = initializers.common.expansion +initializers.node.afm.expansion = initializers.common.expansion + +fonts.goodies.register("expansions", function(...) return fonts.goodies.report("expansions", trace_expansion, ...) end) + +-- -- -- -- -- -- +-- protrusion +-- -- -- -- -- -- + +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 + +classes.preset = { factor = 1, left = 1, right = 1 } + +function commands.setupfontprotrusion(class,settings) + aux.getparameters(classes,class,'preset',settings) +end + +classes['pure'] = { + vector = 'pure', factor = 1 +} +classes['punctuation'] = { + vector = 'punctuation', factor = 1 +} +classes['alpha'] = { + vector = 'alpha', factor = 1 +} +classes['quality'] = { + vector = 'quality', factor = 1 +} + +vectors['pure'] = { + + [0x002C] = { 0, 1 }, -- comma + [0x002E] = { 0, 1 }, -- period + [0x003A] = { 0, 1 }, -- colon + [0x003B] = { 0, 1 }, -- semicolon + [0x002D] = { 0, 1 }, -- hyphen + [0x2013] = { 0, 0.50 }, -- endash + [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 ۔ + +} + +vectors['punctuation'] = { + + [0x003F] = { 0, 0.20 }, -- ? + [0x00BF] = { 0, 0.20 }, -- ¿ + [0x0021] = { 0, 0.20 }, -- ! + [0x00A1] = { 0, 0.20 }, -- ¡ + [0x0028] = { 0.05, 0 }, -- ( + [0x0029] = { 0, 0.05 }, -- ) + [0x005B] = { 0.05, 0 }, -- [ + [0x005D] = { 0, 0.05 }, -- ] + [0x002C] = { 0, 0.70 }, -- comma + [0x002E] = { 0, 0.70 }, -- period + [0x003A] = { 0, 0.50 }, -- colon + [0x003B] = { 0, 0.50 }, -- semicolon + [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 + + [0x2039] = { 0.70, 0.70 }, -- left single guillemet ‹ + [0x203A] = { 0.70, 0.70 }, -- right single guillemet › + [0x00AB] = { 0.50, 0.50 }, -- left guillemet « + [0x00BB] = { 0.50, 0.50 }, -- right guillemet » + + [0x2018] = { 0.70, 0.70 }, -- left single quotation mark ‘ + [0x2019] = { 0, 0.70 }, -- right single quotation mark ’ + [0x201A] = { 0.70, 0 }, -- single low-9 quotation mark , + [0x201B] = { 0.70, 0 }, -- single high-reversed-9 quotation mark ‛ + [0x201C] = { 0.50, 0.50 }, -- left double quotation mark “ + [0x201D] = { 0, 0.50 }, -- right double quotation mark ” + [0x201E] = { 0.50, 0 }, -- double low-9 quotation mark „ + [0x201F] = { 0.50, 0 }, -- double high-reversed-9 quotation mark ‟ + +} + +vectors['alpha'] = { + + [byte("A")] = { .05, .05 }, + [byte("F")] = { 0, .05 }, + [byte("J")] = { .05, 0 }, + [byte("K")] = { 0, .05 }, + [byte("L")] = { 0, .05 }, + [byte("T")] = { .05, .05 }, + [byte("V")] = { .05, .05 }, + [byte("W")] = { .05, .05 }, + [byte("X")] = { .05, .05 }, + [byte("Y")] = { .05, .05 }, + + [byte("k")] = { 0, .05 }, + [byte("r")] = { 0, .05 }, + [byte("t")] = { 0, .05 }, + [byte("v")] = { .05, .05 }, + [byte("w")] = { .05, .05 }, + [byte("x")] = { .05, .05 }, + [byte("y")] = { .05, .05 }, + +} + +vectors['quality'] = table.merge( {}, + vectors['punctuation'], + vectors['alpha'] +) + +-- As this is experimental code, users should not depend on it. The +-- implications are still discussed on the ConTeXt Dev List and we're +-- not sure yet what exactly the spec is (the next code is tested with +-- a gyre font patched by / fea file made by Khaled Hosny). The double +-- trick should not be needed it proper hanging punctuation is used in +-- which case values < 1 can be used. +-- +-- preferred (in context, usine vectors): +-- +-- \definefontfeature[whatever][default][mode=node,protrusion=quality] +-- +-- using lfbd and rtbd, with possibibility to enable only one side : +-- +-- \definefontfeature[whocares][default][mode=node,protrusion=yes, opbd=yes,script=latn] +-- \definefontfeature[whocares][default][mode=node,protrusion=right,opbd=yes,script=latn] +-- +-- idem, using multiplier +-- +-- \definefontfeature[whocares][default][mode=node,protrusion=2,opbd=yes,script=latn] +-- \definefontfeature[whocares][default][mode=node,protrusion=double,opbd=yes,script=latn] +-- +-- idem, using named feature file (less frozen): +-- +-- \definefontfeature[whocares][default][mode=node,protrusion=2,opbd=yes,script=latn,featurefile=texgyrepagella-regularxx.fea] + +classes['double'] = { -- for testing opbd + factor = 2, left = 1, right = 1, +} + +local function map_opbd_onto_protrusion(tfmdata,value,opbd) + local characters, descriptions = tfmdata.characters, tfmdata.descriptions + local otfdata = tfmdata.shared.otfdata + local singles = otfdata.shared.featuredata.gpos_single + local script, language = tfmdata.script, tfmdata.language + local done, factor, left, right = false, 1, 1, 1 + local class = classes[value] + if class then + factor = class.factor or 1 + left = class.left or 1 + right = class.right or 1 + else + factor = tonumber(value) or 1 + end + if opbd ~= "right" then + local validlookups, lookuplist = fonts.otf.collect_lookups(otfdata,"lfbd",script,language) + if validlookups then + for i=1,#lookuplist do + local lookup = lookuplist[i] + local data = singles[lookup] + if data then + if trace_protrusion then + logs.report("fonts","set left protrusion using lfbd lookup '%s'",lookup) + end + for k, v in next, data do + -- local p = - v[3] / descriptions[k].width-- or 1 ~= 0 too but the same + local p = - (v[1] / 1000) * factor * left + characters[k].left_protruding = p + if trace_protrusion then + logs.report("opbd","lfbd -> %s -> 0x%05X (%s) -> %0.03f (%s)",lookup,k,utfchar(k),p,concat(v," ")) + end + end + done = true + end + end + end + end + if opbd ~= "left" then + local validlookups, lookuplist = fonts.otf.collect_lookups(otfdata,"rtbd",script,language) + if validlookups then + for i=1,#lookuplist do + local lookup = lookuplist[i] + local data = singles[lookup] + if data then + if trace_protrusion then + logs.report("fonts","set right protrusion using rtbd lookup '%s'",lookup) + end + for k, v in next, data do + -- local p = v[3] / descriptions[k].width -- or 3 + local p = (v[1] / 1000) * factor * right + characters[k].right_protruding = p + if trace_protrusion then + logs.report("opbd","rtbd -> %s -> 0x%05X (%s) -> %0.03f (%s)",lookup,k,utfchar(k),p,concat(v," ")) + end + end + end + done = true + end + end + end + tfmdata.auto_protrude = done +end + +-- The opbd test is just there because it was discussed on the +-- context development list. However, the mentioned fxlbi.otf font +-- only has some kerns for digits. So, consider this feature not +-- supported till we have a proper test font. + +function initializers.common.protrusion(tfmdata,value) + if value then + local opbd = tfmdata.shared.features.opbd + if opbd then + -- possible values: left right both yes no (experimental) + map_opbd_onto_protrusion(tfmdata,value,opbd) + else + local class, vector = get_class_and_vector(tfmdata,value,"protrusions") + if class then + if vector then + local factor = class.factor or 1 + local left = class.left or 1 + local right = class.right or 1 + if trace_protrusion then + logs.report("fonts","set protrusion class %s, vector: %s, factor: %s, left: %s, right: %s",value,class_vector,factor,left,right) + end + local data = characters.data + local emwidth = tfmdata.parameters.quad + 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] + else + local d = data[i] + if d then + local s = d.shcode + if not s then + -- sorry + elseif type(s) == "table" then + local vl, vr = vector[s[1]], vector[s[#s]] + if vl then pl = vl[1] end + if vr then pr = vr[2] end + else + v = vector[s] + if v then + pl, pr = v[1], v[2] + end + end + end + end + if pl and pl ~= 0 then + chr.left_protruding = left *pl*factor + end + if pr and pr ~= 0 then + chr.right_protruding = right*pr*factor + end + end + elseif trace_protrusion then + logs.report("fonts","unknown protrusion vector '%s' in class '%s",class_vector,value) + end + elseif trace_protrusion then + logs.report("fonts","unknown protrusion class '%s'",value) + end + end + end +end + +table.insert(fonts.manipulators,"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 + +fonts.goodies.register("protrusions", function(...) return fonts.goodies.report("protrusions", trace_protrusion, ...) end) + +-- -- -- + +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 + +initializers.base.afm.itlc = initializers.common.itlc +initializers.node.afm.itlc = initializers.common.itlc + +-- slanting + +table.insert(fonts.triggers,"slant") + +function initializers.common.slant(tfmdata,value) + value = tonumber(value) + if not value then + value = 0 + elseif value > 1 then + value = 1 + elseif value < -1 then + value = -1 + end + tfmdata.slant_factor = value +end + +initializers.base.otf.slant = initializers.common.slant +initializers.node.otf.slant = initializers.common.slant + +initializers.base.afm.slant = initializers.common.slant +initializers.node.afm.slant = initializers.common.slant + +table.insert(fonts.triggers,"extend") + +function initializers.common.extend(tfmdata,value) + value = tonumber(value) + if not value then + value = 0 + elseif value > 10 then + value = 10 + elseif value < -10 then + value = -10 + end + tfmdata.extend_factor = value +end + +initializers.base.otf.extend = initializers.common.extend +initializers.node.otf.extend = initializers.common.extend + +initializers.base.afm.extend = initializers.common.extend +initializers.node.afm.extend = initializers.common.extend + +-- historic stuff, move from font-ota + +local delete_node = nodes.delete +local glyph = node.id("glyph") +local fontdata = fonts.ids + +fonts.strippables = fonts.strippables or { -- just a placeholder + [0x200C] = true, -- zwnj + [0x200D] = true, -- zwj +} + +local strippables = fonts.strippables + +local function processformatters(head,font) + local how = fontdata[font].shared.features.formatters + if how == nil or how == "strip" then -- nil when forced + local current, done = head, false + while current do + if current.id == glyph and current.subtype<256 and current.font == font then + local char = current.char + if strippables[char] then + head, current = delete_node(head,current) + done = true + else + current = current.next + end + else + current = current.next + end + end + return head, done + else + return head, false + end +end + +methods.node.otf.formatters = processformatters +methods.base.otf.formatters = processformatters + +fonts.otf.tables.features['formatters'] = 'Hide Formatting Characters' + +fonts.otf.features.register("formatters") + +table.insert(fonts.manipulators,"formatters") -- at end diff --git a/tex/context/base/font-fbk.lua b/tex/context/base/font-fbk.lua new file mode 100644 index 000000000..1ad1cc781 --- /dev/null +++ b/tex/context/base/font-fbk.lua @@ -0,0 +1,316 @@ +if not modules then modules = { } end modules ['font-fbk'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local cos, tan, rad, format = math.cos, math.tan, math.rad, string.format + +local trace_combining = false trackers.register("fonts.combining", function(v) trace_combining = v end) + +--[[ldx-- +<p>This is very experimental code!</p> +--ldx]]-- + +fonts.fallbacks = fonts.fallbacks or { } + +local vf = fonts.vf +local tfm = fonts.tfm + +vf.aux.combine.commands["enable-tracing"] = function(g,v) + trace_combining = true +end + +vf.aux.combine.commands["disable-tracing"] = function(g,v) + trace_combining = false +end + +vf.aux.combine.commands["set-tracing"] = function(g,v) + if v[2] == nil then + trace_combining = true + else + trace_combining = v[2] + end +end + +function vf.aux.combine.initialize_trace() + 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", "", "", "", "" + end +end + +vf.aux.combine.force_fallback = false + +vf.aux.combine.commands["fake-character"] = function(g,v) -- g, nr, fallback_id + local index, fallback = v[2], v[3] + if vf.aux.combine.force_fallback or not g.characters[index] then + if fonts.fallbacks[fallback] then + g.characters[index], g.descriptions[index] = fonts.fallbacks[fallback](g) + end + end +end + +fonts.fallbacks['textcent'] = function (g) + local c = ("c"):byte() + local t = table.fastcopy(g.characters[c]) + 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 + t.commands = { + {"push"}, {"slot", 1, c}, {"pop"}, + {"right", .5*t.width}, + {"down", .2*t.height}, + {special, green}, + {"rule", 1.4*t.height, .02*quad}, + {special, black}, + } + else + t.commands = { + {"push"}, + {"right", .5*t.width-.025*quad}, + {"down", .2*t.height}, + {"special",format("pdf: q 1 0 %s 1 0 0 cm",a)}, + {special, green}, + {"rule", 1.4*t.height, .025*quad}, + {special, black}, + {"special","pdf: Q"}, + {"pop"}, + {"slot", 1, c} -- last else problems with cm + } + end + -- somehow the width is messed up now + -- 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 + +fonts.fallbacks['texteuro'] = function (g) + local c = ("C"):byte() + local t = table.fastcopy(g.characters[c]) + 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 + t.commands = { + {"right", .05*t.width}, + {"push"}, {"slot", 1, c}, {"pop"}, + {"right", .5*t.width*d}, + {"down", -.5*t.height}, + {special, green}, + {"rule", .05*quad, .4*quad}, + {special, black}, + } + g.virtualized = true + return t, g.descriptions[c] +end + +-- maybe store llx etc instead of bbox in tfm blob / more efficient + +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 + local X = ("X"):byte() + local xchar = chars[X] + local xdesc = descs[X] + if xchar and xdesc then + local scale = g.factor or 1 + local cap_lly = scale*xdesc.boundingbox[4] + 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 + 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 + local chr = s[2] + local charschr = chars[chr] + if charschr then + local cc = c.category + if cc == 'll' or cc == 'lu' or cc == 'lt' then + local acc = s[3] + local t = { } + 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 + -- can be sped up for scale == 1 + local c_llx, c_lly, c_urx, c_ury = scale*cb[1], scale*cb[2], scale*cb[3], scale*cb[4] + local a_llx, a_lly, a_urx, a_ury = scale*ab[1], scale*ab[2], scale*ab[3], scale*ab[4] + local dx = (c_urx - a_urx - a_llx + c_llx)/2 + local dd = (c_urx - c_llx)*ita_cor + if a_ury < 0 then + if trace_combining then + t.commands = { + push, + {"right", dx-dd}, + red, + acc_t, + black, + pop, + chr_t, + } + else + t.commands = { + push, + {"right", dx-dd}, + acc_t, + pop, + chr_t, + } + end + elseif c_ury > a_lly then + local dy = cap_lly-a_lly + if trace_combining then + t.commands = { + push, + {"right", dx+dd}, + {"down", -dy}, + green, + acc_t, + black, + pop, + chr_t, + } + else + t.commands = { + push, + {"right", dx+dd}, + {"down", -dy}, + acc_t, + pop, + chr_t, + } + end + else + if trace_combining then + t.commands = { + {"push"}, + {"right", dx+dd}, + blue, + acc_t, + black, + {"pop"}, + chr_t, + } + else + t.commands = { + {"push"}, + {"right", dx+dd}, + acc_t, + {"pop"}, + chr_t, + } + end + end + done = true + end + end + chars[i] = t + local d = { } + for k, v in next, descs[chr] do + d[k] = v + end + d.name = c.adobename or "unknown" + -- d.unicode = i + descs[i] = d + end + end + end + end + end + if done then + g.virtualized = true + end + end +end + +vf.aux.combine.commands["complete-composed-characters"] = function(g,v) + vf.aux.compose_characters(g) +end + +--~ {'special', 'pdf: q ' .. s .. ' 0 0 '.. s .. ' 0 0 cm'}, +--~ {'special', 'pdf: q 1 0 0 1 ' .. -w .. ' ' .. -h .. ' cm'}, +--~ -- {'special', 'pdf: /Fm\XX\space Do'}, +--~ {'special', 'pdf: Q'}, +--~ {'special', 'pdf: Q'}, + +-- for documentation purposes we provide: + +fonts.define.methods.install("fallback", { -- todo: auto-fallback with loop over data.characters + { "fake-character", 0x00A2, 'textcent' }, + { "fake-character", 0x20AC, 'texteuro' } +}) + +vf.aux.combine.commands["enable-force"] = function(g,v) + vf.aux.combine.force_composed = true + vf.aux.combine.force_fallback = true +end +vf.aux.combine.commands["disable-force"] = function(g,v) + vf.aux.combine.force_composed = false + vf.aux.combine.force_fallback = false +end + +fonts.define.methods.install("demo-2", { + { "enable-tracing" }, + { "enable-force" }, + { "initialize" }, + { "include-method", "fallback" }, + { "complete-composed-characters" }, + { "disable-tracing" }, + { "disable-force" }, +}) + +fonts.define.methods.install("demo-3", { + { "enable-tracing" }, + { "initialize" }, + { "complete-composed-characters" }, + { "disable-tracing" }, +}) diff --git a/tex/context/base/font-gds.lua b/tex/context/base/font-gds.lua new file mode 100644 index 000000000..e3db8c816 --- /dev/null +++ b/tex/context/base/font-gds.lua @@ -0,0 +1,294 @@ +if not modules then modules = { } end modules ['font-gds'] = { + version = 1.000, + comment = "companion to font-gds.mkiv", + 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 = string.gmatch + +local trace_goodies = false trackers.register("fonts.goodies", function(v) trace_goodies = v end) + +-- goodies=name,colorscheme=,featureset= +-- +-- goodies=auto + +-- goodies + +fonts.goodies = fonts.goodies or { } +fonts.goodies.data = fonts.goodies.data or { } +fonts.goodies.list = fonts.goodies.list or { } + +local data = fonts.goodies.data +local list = fonts.goodies.list + +function fonts.goodies.report(what,trace,goodies) + if trace_goodies or trace then + local whatever = goodies[what] + if whatever then + logs.report("fonts", "goodie '%s' found in '%s'",what,goodies.name) + end + end +end + +local function getgoodies(filename) -- maybe a merge is better + local goodies = data[filename] -- we assume no suffix is given + if goodies ~= nil then + -- found or tagged unfound + elseif type(filename) == "string" then + local fullname = resolvers.find_file(file.addsuffix(filename,"lfg")) or "" -- prefered suffix + if fullname == "" then + fullname = resolvers.find_file(file.addsuffix(filename,"lua")) or "" -- fallback suffix + end + if fullname == "" then + logs.report("fonts", "goodie file '%s.lfg' is not found",filename) + data[filename] = false -- signal for not found + else + goodies = dofile(fullname) or false + if not goodies then + logs.report("fonts", "goodie file '%s' is invalid",fullname) + return nil + elseif trace_goodies then + logs.report("fonts", "goodie file '%s' is loaded",fullname) + end + goodies.name = goodies.name or "no name" + for name, fnc in next, list do + fnc(goodies) + end + goodies.initialized = true + data[filename] = goodies + end + end + return goodies +end + +function fonts.goodies.register(name,fnc) + list[name] = fnc +end + +fonts.goodies.get = getgoodies + +-- register goodies file + +local preset_context = fonts.define.specify.preset_context + +function fonts.initializers.common.goodies(tfmdata,value) + local goodies = tfmdata.goodies or { } -- future versions might store goodies in the cached instance + for filename in gmatch(value,"[^, ]+") do + -- we need to check for duplicates + local ok = getgoodies(filename) + if ok then + goodies[#goodies+1] = ok + end + end + tfmdata.goodies = goodies -- shared ? +end + +-- featuresets + +local function flattened(t,tt) + -- first set value dominates + local tt = tt or { } + for i=1,#t do + local ti = t[i] + if type(ti) == "table" then + flattened(ti,tt) + elseif tt[ti] == nil then + tt[ti] = true + end + end + for k, v in next, t do + if type(k) ~= "number" then + if type(v) == "table" then + flattened(v,tt) + elseif tt[k] == nil then + tt[k] = v + end + end + end + return tt +end + +fonts.flattened_features = flattened + +function fonts.goodies.prepare_features(goodies,name,set) + if set then + local ff = fonts.flattened_features(set) + local fullname = goodies.name .. "::" .. name + local n, s = preset_context(fullname,"",ff) + goodies.featuresets[name] = s -- set + if trace_goodies then + logs.report("fonts", "feature set '%s' gets number %s and name '%s'",name,n,fullname) + end + return n + end +end + +local function initialize(goodies,tfmdata) + local featuresets = goodies.featuresets + local goodiesname = goodies.name + if featuresets then + if trace_goodies then + logs.report("fonts", "checking featuresets in '%s'",goodies.name) + end + for name, set in next, featuresets do + fonts.goodies.prepare_features(goodies,name,set) + end + end +end + +fonts.goodies.register("featureset",initialize) + +function fonts.initializers.common.featureset(tfmdata,set) + local goodies = tfmdata.goodies -- shared ? + if goodies then + local features = tfmdata.shared.features + local what + for i=1,#goodies do + -- last one counts + local g = goodies[i] + what = (g.featuresets and g.featuresets[set]) or what + end + if what then + for feature, value in next, what do + if features[feature] == nil then + features[feature] = value + end + end + tfmdata.mode = features.mode or tfmdata.mode + end + end +end + +-- colorschemes + +fonts.goodies.colorschemes = fonts.goodies.colorschemes or { } +fonts.goodies.colorschemes.data = fonts.goodies.colorschemes.data or { } + +local colorschemes = fonts.goodies.colorschemes + +function fonts.initializers.common.colorscheme(tfmdata,scheme) + if type(scheme) == "string" then + local goodies = tfmdata.goodies + -- todo : check for already defined in shared + if goodies then + local what + for i=1,#goodies do + -- last one counts + local g = goodies[i] + what = (g.colorschemes and g.colorschemes[scheme]) or what + end + if what then + -- this is font bound but we can share them if needed + -- just as we could hash the conversions (per font) + local hash, reverse = tfmdata.luatex.unicodes, { } + for i=1,#what do + local w = what[i] + for j=1,#w do + local name = w[j] + local unicode = hash[name] + if unicode then + reverse[unicode] = i + end + end + end + tfmdata.colorscheme = reverse + return + end + end + end + tfmdata.colorscheme = false +end + +local fontdata = fonts.ids +local fcs = fonts.color.set +local has_attribute = node.has_attribute +local traverse_id = node.traverse_id +local a_colorscheme = attributes.private('colorscheme') +local glyph = node.id("glyph") + +function fonts.goodies.colorschemes.coloring(head) + local lastfont, lastscheme + for n in traverse_id(glyph,head) do + local a = has_attribute(n,a_colorscheme) + if a then + local f = n.font + if f ~= lastfont then + lastscheme, lastfont = fontdata[f].colorscheme, f + end + if lastscheme then + local sc = lastscheme[n.char] + if sc then + fcs(n,"colorscheme:"..a..":"..sc) -- slow + end + end + end + end +end + +function fonts.goodies.colorschemes.enable() + tasks.appendaction("processors","fonts","fonts.goodies.colorschemes.coloring") + function fonts.goodies.colorschemes.enable() end +end + +-- installation (collected to keep the overview) + +fonts.otf.tables.features['goodies'] = 'Goodies on top of built in features' +fonts.otf.tables.features['featurset'] = 'Goodie Feature Set' +fonts.otf.tables.features['colorscheme'] = 'Goodie Color Scheme' + +fonts.otf.features.register('goodies') +fonts.otf.features.register('featureset') +fonts.otf.features.register('colorscheme') + +table.insert(fonts.triggers, 1, "goodies") +table.insert(fonts.triggers, 2, "featureset") -- insert after +table.insert(fonts.triggers, "colorscheme") + +fonts.initializers.base.otf.goodies = fonts.initializers.common.goodies +fonts.initializers.node.otf.goodies = fonts.initializers.common.goodies + +fonts.initializers.base.otf.featureset = fonts.initializers.common.featureset +fonts.initializers.node.otf.featureset = fonts.initializers.common.featureset + +fonts.initializers.base.otf.colorscheme = fonts.initializers.common.colorscheme +fonts.initializers.node.otf.colorscheme = fonts.initializers.common.colorscheme + +-- experiment, we have to load the definitions immediately as they precede +-- the definition so they need to be initialized in the typescript + +local function initialize(goodies) + local mathgoodies = goodies.mathematics + local virtuals = mathgoodies and mathgoodies.virtuals + local mapfiles = mathgoodies and mathgoodies.mapfiles + local maplines = mathgoodies and mathgoodies.maplines + if virtuals then + for name, specification in next, virtuals do + mathematics.make_font(name,specification) + end + end + if mapfiles then + for i=1,#mapfiles do + fonts.map.loadfile(mapfiles[i]) -- todo: backend function + end + end + if maplines then + for i=1,#maplines do + fonts.map.loadline(maplines[i]) -- todo: backend function + end + end +end + +fonts.goodies.register("mathematics", initialize) + +-- The following file (husayni.lfg) is the experimental setup that we used +-- for Idris font. For the moment we don't store this in the cache and quite +-- probably these files sit in one of the paths: +-- +-- tex/context/fonts/goodies +-- tex/fonts/goodies/context +-- tex/fonts/data/foundry/collection +-- +-- see lfg files in distribution diff --git a/tex/context/base/font-gds.mkiv b/tex/context/base/font-gds.mkiv new file mode 100644 index 000000000..e36116283 --- /dev/null +++ b/tex/context/base/font-gds.mkiv @@ -0,0 +1,83 @@ +%D \module +%D [ file=font-gds, +%D version=2009.10.14, +%D title=\CONTEXT\ Font Support, +%D subtitle=Colorschemes, +%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 Font Support / Colorschemes} + +% \registerctxluafile{font-gds}{1.001} + +\unprotect + +\def\loadfontgoodies[#1]% + {\ctxlua{fonts.goodies.get("#1")}} + + +% this will become colorgroups and move to font-col or so + +\definecolor[colorscheme:1:1][s=.75] +\definecolor[colorscheme:1:2][r=.75] +\definecolor[colorscheme:1:3][g=.75] +\definecolor[colorscheme:1:4][b=.75] +\definecolor[colorscheme:1:5][c=.75] +\definecolor[colorscheme:1:6][m=.75] +\definecolor[colorscheme:1:7][y=.75] + +\definecolor[colorscheme:2:7][s=.75] +\definecolor[colorscheme:2:6][r=.75] +\definecolor[colorscheme:2:5][g=.75] +\definecolor[colorscheme:2:4][b=.75] +\definecolor[colorscheme:2:3][c=.75] +\definecolor[colorscheme:2:2][m=.75] +\definecolor[colorscheme:2:1][y=.75] + +\definesystemattribute[colorscheme] \chardef\colorschemeattribute \dogetattributeid{colorscheme} + +\def\setfontcolorscheme + {\ctxlua{fonts.goodies.colorschemes.enable()}% + \xdef\setfontcolorscheme[##1]{\attribute\colorschemeattribute##1\relax}% + \setfontcolorscheme} + +\edef\resetfontcolorscheme{\attribute\colorschemeattribute\attributeunsetvalue} + +\protect \endinput + +% \definefontfeature[husayni-colored][goodies=husayni,colorscheme=default,featureset=default] +% +% \definedfont[husayni*husayni-colored at 36pt] +% +% \starttext \pardir TRT \textdir TRT +% +% \setfontcolorscheme[1] +% +% اَلْحَمْ‍دُ لِلّٰهِ حَمْدَ مُعْتَرِفٍ بِحَمْدِهٖ، مُغْتَرِفٌ مِنْ بِحَارِ +% مَجْدِهٖ، بِلِسَانِ ٱلثَّنَاۤءِ شَاكِرًا، وَلِحُسْنِ اٰلاۤئِهٖ نَاشِرًا؛ +% اَلَّذِيْ خَلَقَ ٱلْمَوْتَ وَٱلْحَيٰوةَ، وَٱلْخَيْرَ وَٱلشَّرَّ، +% وَٱلنَّفْعَ وَٱلضَّرَّ، وَٱلسُّكُوْنَ وَٱلْحَرَكَةَ، وَٱلْأَرْوَاحَ +% وَٱلْأَجْسَامَ، وَٱلذِّكْرَ وَٱلنِّسْيَانَ. +% +% \setfontcolorscheme[2] +% +% اَلْحَمْ‍دُ لِلّٰهِ حَمْدَ مُعْتَرِفٍ بِحَمْدِهٖ، مُغْتَرِفٌ مِنْ بِحَارِ +% مَجْدِهٖ، بِلِسَانِ ٱلثَّنَاۤءِ شَاكِرًا، وَلِحُسْنِ اٰلاۤئِهٖ نَاشِرًا؛ +% اَلَّذِيْ خَلَقَ ٱلْمَوْتَ وَٱلْحَيٰوةَ، وَٱلْخَيْرَ وَٱلشَّرَّ، +% وَٱلنَّفْعَ وَٱلضَّرَّ، وَٱلسُّكُوْنَ وَٱلْحَرَكَةَ، وَٱلْأَرْوَاحَ +% وَٱلْأَجْسَامَ، وَٱلذِّكْرَ وَٱلنِّسْيَانَ. +% +% \resetfontcolorscheme +% +% اَلْحَمْ‍دُ لِلّٰهِ حَمْدَ مُعْتَرِفٍ بِحَمْدِهٖ، مُغْتَرِفٌ مِنْ بِحَارِ +% مَجْدِهٖ، بِلِسَانِ ٱلثَّنَاۤءِ شَاكِرًا، وَلِحُسْنِ اٰلاۤئِهٖ نَاشِرًا؛ +% اَلَّذِيْ خَلَقَ ٱلْمَوْتَ وَٱلْحَيٰوةَ، وَٱلْخَيْرَ وَٱلشَّرَّ، +% وَٱلنَّفْعَ وَٱلضَّرَّ، وَٱلسُّكُوْنَ وَٱلْحَرَكَةَ، وَٱلْأَرْوَاحَ +% وَٱلْأَجْسَامَ، وَٱلذِّكْرَ وَٱلنِّسْيَانَ. +% +% \stoptext diff --git a/tex/context/base/font-heb.mkii b/tex/context/base/font-heb.mkii new file mode 100644 index 000000000..3ec0395f3 --- /dev/null +++ b/tex/context/base/font-heb.mkii @@ -0,0 +1,5 @@ +\unprotected \writestatus\m!systems{load ARABTEX as a module instead} + +\usemodule[arabtex] + +\endinput diff --git a/tex/context/base/font-ini.lua b/tex/context/base/font-ini.lua new file mode 100644 index 000000000..e45149781 --- /dev/null +++ b/tex/context/base/font-ini.lua @@ -0,0 +1,95 @@ +if not modules then modules = { } end modules ['font-ini'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--[[ldx-- +<p>Not much is happening here.</p> +--ldx]]-- + +local utf = unicode.utf8 +local format, serialize = string.format, table.serialize +local write_nl = texio.write_nl + +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 { } fonts.identifiers = fonts.ids -- aka fontdata +fonts.chr = fonts.chr or { } fonts.characters = fonts.chr -- aka chardata +fonts.qua = fonts.qua or { } fonts.quads = fonts.qua -- aka quaddata + +fonts.tfm = fonts.tfm or { } + +fonts.mode = 'base' +fonts.private = 0xF0000 -- 0x10FFFF +fonts.verbose = false -- more verbose cache tables + +fonts.ids[0] = { -- nullfont + characters = { }, + descriptions = { }, + name = "nullfont", +} + +fonts.chr[0] = { } + +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 + +if not fonts.color then + + fonts.color = { + set = function() end, + reset = function() end, + } + +end + +-- format identification + +fonts.formats = { } + +function fonts.fontformat(filename,default) + local extname = file.extname(filename) + local format = fonts.formats[extname] + if format then + return format + else + logs.report("fonts define","unable to detemine font format for '%s'",filename) + return default + end +end diff --git a/tex/context/base/font-ini.mkii b/tex/context/base/font-ini.mkii new file mode 100644 index 000000000..89fbb5d07 --- /dev/null +++ b/tex/context/base/font-ini.mkii @@ -0,0 +1,4573 @@ +%D \module +%D [ file=font-ini, +%D version=1998.09.11, % (second) +%D version=2001.02.20, % (third) +%D title=\CONTEXT\ Font 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 Font Macros / Initialization} + +\unprotect + +% \def\fontrange#1% +% {\dofontrange{#1 =\bodyfontsize}} +% +% \def\dofontrange#1% +% {\dodofontrange#1 \relax}% \fontstringA +% +% \def\dodofontrange#1 #2 % +% {\ifdim\bodyfontsize#2% +% #1\expandafter\gobbleuntilrelax +% \else +% \expandafter\dodofontrange +% \fi} +% +% \definefont +% [crap] +% [\fontrange +% {Regular <10pt +% RegularBold <12pt +% RegularSlanted <15pt +% Regular} sa 1] +% +% may be better: +% +% \definefontrange +% [crap] +% [Regular <10pt +% RegularBold <12pt +% RegularSlanted <15pt] +% [Regular sa 1] +% +% +% \dostepwiserecurse{2}{15}{1} +% {{\switchtobodyfont[\recurselevel pt]\crap test}\endgraf} + +% adapted, else wrong interlinespace + +\def\setfontparameters + {\synchronizefontsfalse + \the\everybodyfont + \synchronizefontstrue} + +% handy + +\newcounter\pushedfont + +\def\savefont + {\edef\savedfont{\the\font}% + \pushmacro\savedfont + \pushmacro\currentregime + \pushmacro\charactermapping + \pushmacro\characterencoding} + +\def\restorefont + {\popmacro\characterencoding + \popmacro\charactermapping + \popmacro\currentregime + \popmacro\savedfont + \savedfont} + +\def\pushcurrentfont + {\edef\popcurrentfont + {\noexpand\def\noexpand\fontbody{\fontbody}% + \noexpand\def\noexpand\fontstyle{\fontstyle}% + \noexpand\dosetcurrentfontalternative{\fontalternative}% + \noexpand\dosetcurrentfontsize{\fontsize}% + \noexpand\synchronizefont}} + +% \definetypeface[one][rm][serif][computer-roman][default] +% \definetypeface[two][rm][serif][computer-roman][default][rscale=.9] +% +% {\one \bf test \two test} +% {\one \bf test \pushcurrentfont \two \popcurrentfont test} + +%D \macros +%D {definedfont,startfont,doiffontcharelse} +%D +%D A couple of relatively new macros: + +\newevery \everydefinedfont \relax + +\def\dodefinedfont[#1]% + {\iffirstargument\definefont[\string\thedefinedfont][#1]\fi + \csname\string\thedefinedfont\endcsname % can be \relax + \the\everydefinedfont} % hm, redundant + +\unexpanded\def\definedfont + {\dosingleempty\dodefinedfont} + +\unexpanded\def\startfont + {\bgroup\definedfont} + +\def\stopfont + {\egroup} + +\def\doiffontcharelse#1#2% + {\bgroup + \definedfont[#1]% + \iffontchar\font#2\relax + \egroup\expandafter\firstoftwoarguments + \else + \egroup\expandafter\secondoftwoarguments + \fi} + +%%% message 14 added + +% 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 +%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 \macros +%D {rm,ss,tt,hw,cg} +%D +%D Fonts are defined in separate files. When we define a font, +%D we distinguish between several styles. In most cases we will +%D use: +%D +%D \startlinecorrection +%D \starttable[|l||] +%D \HL +%D \NC roman regular serif \NC \type{\rm} \NC\FR +%D \NC sansserif sans support \NC \type{\ss} \NC\MR +%D \NC type teletype mono \NC \type{\tt} \NC\LR +%D \HL +%D \stoptable +%D \stoplinecorrection +%D +%D The number of styles is not limited to these three. When +%D using Lucida Bright we can for instance also define: +%D +%D \startlinecorrection +%D \starttable[|l||] +%D \HL +%D \NC handwritten \NC \type{\hw} \NC\FR +%D \NC calligraphic \NC \type{\cg} \NC\LR +%D \HL +%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 +%D \startlinecorrection +%D \starttable[|l||] +%D \HL +%D \NC typeface \NC \type{\tf} \NC\FR +%D \NC boldface \NC \type{\bf} \NC\MR +%D \NC slanted \NC \type{\sl} \NC\MR +%D \NC italic \NC \type{\it} \NC\MR +%D \NC boldslanted \NC \type{\bs} \NC\MR +%D \NC bolditalic \NC \type{\bi} \NC\MR +%D \NC smallcaps \NC \type{\sc} \NC\LR +%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}. +%D Users are not confronted with sizes, but use the style or +%D style+alternative to activate them. +%D +%D During the definition of a bodyfont one can also declare the +%D available larger alternatives: +%D +%D \starttyping +%D \tf \tfa \tfb \tfc ... +%D \bf \bfa \bfb \bfc ... +%D \sl \sla \slb \slc ... +%D \stoptyping +%D +%D The smaller ones are automatically supplied and derived from +%D the the bodyfont environment. +%D +%D \starttyping +%D \tfx \tfxx +%D \bfx \bfxx +%D \slx \slxx +%D \stoptyping +%D +%D There are only two smaller alternatives per style. The +%D larger alternatives on the other hand have no limitations. +%D +%D These larger alternatives are mostly used in chapter and +%D section titles or on title pages. When one switches to a +%D larger alternative, the bold an other ones automatically +%D adapt themselves: +%D +%D \startbuffer +%D \tfd Hi \bf there\sl, here \tfb I \bf am +%D \stopbuffer +%D +%S \startnarrower +%D \typebuffer +%S \stopnarrower +%D +%D therefore becomes: +%D +%D \startvoorbeeld +%D \getbuffer +%D \stopvoorbeeld +%D +%D Maybe this mechanism isn't always as logic, but as said +%D before, we tried to make it as intuitive as possible. +%D +%D So a specific kind of glyph can be characterized by: +%D +%D \startnarrower +%D family (cmr) + bodyfont (12pt) + style (rm) + alternative (bf) + size (a) +%D \stopnarrower +%D +%D The last component (the size) is optional. +%D +%D We introduced \type{\tf} as command to call for the current +%D normally sized typeface. This commands results in roman, +%D sans serif, teletype or whatever style is in charge. Such +%D rather massive switches of style sometimes take more +%D processing time than comfortable. Of course there is a +%D workaround for this: we can call fonts directly by means of +%D commands like: +%D +%D \starttyping +%D \rmtf \sssl \tttf \rmbsa +%D \stoptyping +%D +%D One should realize that this fast calls have limitations, +%D they lack for instance automatic super- and subscript +%D support. +%D +%D This leaves us two more commands: \type{\tx} and +%D \type{\txx}. These activate a smaller and even more smaller +%D font than the current one and adapt themselves to the +%D current alternative, so when \type{\bf} is active, +%D \type{\tx} gives a smaller boldface, which in turn can be +%D called directly by \type{\bfx}. +%D +%D These two smaller alternatives are specified by the bodyfont +%D environment and therefore not necessarily have similar sizes +%D as \type{\scriptsize} and \type{\scriptscriptsize}. The main +%D reason for this incompatibility (which can easily be undone) +%D lays in the fact that we often want a bit bigger characters +%D than in math mode. In \CONTEXT\ for instance the \type{\tx} +%D and \type{\txx} commands are used for surrogate +%D \cap{smallcaps} which support both nesting and alternatives, +%D like in {\bf\cap{a \cap{small} world}}, which was typeset by +%D +%D \starttyping +%D \bf\cap{a \cap{small} world} +%D \stoptyping +%D +%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 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 +%D \type {d} inside \type {x}. etc.). The following table +%D demonstrates this: +%D +%D \def\FontState{\setstrut\ruledhbox{\strut Hello}} +%D +%D \starttabulate[|||||] +%D \HL +%D \NC \rlap{\quad\bf grouped} \NC \NC \type {\tx} \NC \type {\txx} \NC \NR +%D \HL +%D \NC \type{\tfx} \NC \tfx \FontState \NC \tfx \tx \FontState \NC \tfx \txx \FontState \NC \NR +%D \NC \type{\tfxx} \NC \tfxx \FontState \NC \tfxx\tx \FontState \NC \tfxx\txx \FontState \NC \NR +%D \NC \type{\tf} \NC \tf \FontState \NC \tf \tx \FontState \NC \tf \txx \FontState \NC \NR +%D \NC \type{\tfa} \NC \tfa \FontState \NC \tfa \tx \FontState \NC \tfa \txx \FontState \NC \NR +%D \NC \type{\tfb} \NC \tfb \FontState \NC \tfb \tx \FontState \NC \tfb \txx \FontState \NC \NR +%D \NC \type{\tfc} \NC \tfc \FontState \NC \tfc \tx \FontState \NC \tfc \txx \FontState \NC \NR +%D \NC \type{\tfd} \NC \tfd \FontState \NC \tfd \tx \FontState \NC \tfd \txx \FontState \NC \NR +%D \NC \type{\tfx} \NC \tfx \FontState \NC \tfx \tx \FontState \NC \tfx \txx \FontState \NC \NR +%D \NC \type{\tfxx} \NC \tfxx \FontState \NC \tfxx\tx \FontState \NC \tfxx\txx \FontState \NC \NR +%D \HL +%D \stoptabulate +%D +%D \blank +%D +%D \starttabulate[|||||] +%D \HL +%D \NC \rlap{\quad\bf stacked} \NC \NC \type {\tx} \NC \type {\txx} \NC \NR +%D \HL +%D \NC \type{\tfx} +%D \NC \tfx \FontState +%D \NC \tfx \tx \FontState +%D \NC \tfx \txx \FontState +%D \NC \NR +%D \NC \type{\tfxx} +%D \NC \tfx\tfxx \FontState +%D \NC \tfx\tfxx \tx \FontState +%D \NC \tfx\tfxx \txx \FontState +%D \NC \NR +%D \NC \type{\tf} +%D \NC \tfx\tfxx\tf \FontState +%D \NC \tfx\tfxx\tf \tx \FontState +%D \NC \tfx\tfxx\tf \txx \FontState +%D \NC \NR +%D \NC \type{\tfa} +%D \NC \tfx\tfxx\tf\tfa \FontState +%D \NC \tfx\tfxx\tf\tfa \tx \FontState +%D \NC \tfx\tfxx\tf\tfa \txx \FontState +%D \NC \NR +%D \NC \type{\tfb} +%D \NC \tfx\tfxx\tf\tfa\tfb \FontState +%D \NC \tfx\tfxx\tf\tfa\tfb \tx \FontState +%D \NC \tfx\tfxx\tf\tfa\tfb \txx \FontState +%D \NC \NR +%D \NC \type{\tfc} +%D \NC \tfx\tfxx\tf\tfa\tfb\tfc \FontState +%D \NC \tfx\tfxx\tf\tfa\tfb\tfc \tx \FontState +%D \NC \tfx\tfxx\tf\tfa\tfb\tfc \txx \FontState +%D \NC \NR +%D \NC \type{\tfd} +%D \NC \tfx\tfxx\tf\tfa\tfb\tfd \FontState +%D \NC \tfx\tfxx\tf\tfa\tfb\tfd \tx \FontState +%D \NC \tfx\tfxx\tf\tfa\tfb\tfd \txx \FontState +%D \NC \NR +%D \NC \type{\tfx} +%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx \FontState +%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx \tx \FontState +%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx \txx \FontState +%D \NC \NR +%D \NC \type{\tfxx} +%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx\tfxx \FontState +%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx\tfxx \tx \FontState +%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx\tfxx \txx \FontState +%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 + +\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 \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 \macros +%D {uchar} +%D +%D This macro prepares \CONTEXT\ for \UNICODE\ support. By +%D defining it here, we have at least an safeguard for utility +%D file reading. + +\ifx\uchar\undefined \unexpanded\def\uchar#1#2{[#1,#2]} \fi + +%D We define some (very private) constants to improve speed, +%D memory usage and consistency. + +\def\@size@ {@f@si@} % bodyfont size prefix (12pt etc) +\def\@style@ {@f@st@} % full style prefix (roman etc) +\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 +%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. + +\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} + +\def\synchronizesymb % stylish math stuff in mmode + {\ifsynchronizemathfonts\the\symbstrategies\fi} % \if...\fam\minusone\fi} + +%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 \macros +%D {textonly} +%D +%D We can inhibit this slow||downer with: + +\def\textonly{\synchronizemathfontsfalse} % document this + +\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} + +\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} + +\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 + +\appendtoks + \dosetskewchar\mifam\defaultskewcharmi % implemented later on + \dosetskewchar\syfam\defaultskewcharsy % implemented later on +\to \mathstrategies + +\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\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\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} + +\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} + +%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. + +\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 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 1000\or1200\or1440\or1728\or2074\or2488\or1000\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 +%D Because \type {sa} (scaled at) and \type {mo} (mapped on) +%D are not low level \TEX\ supported alternatives, we have to +%D test for it ourselves. In doing so, we need an auxiliary +%D \DIMENSION. We cannot use \type{\scratchdimen} because font +%D loading can happen at any moment due to postponed loading. +%D We could instead have used dirty grouping tricks, but this +%D one works too. + +\let\defaultrelativefontsize \plusone +\let\localrelativefontsize \plusone +\def\localabsolutefontsize {\fontbody} + +\let\relativefontsize \defaultrelativefontsize + +\def\saverelativefontsize#1#2% #1=rm|ss|.. #2=waarde + {\setxvalue{\fontclass#1\s!rscale}{#2}} + +\def\checkrelativefontsize#1% + {\edef\relativefontsize + {\ifcsname\fontclass#1\s!rscale\endcsname + \csname\fontclass#1\s!rscale\endcsname + \else + \defaultrelativefontsize + \fi}} + +%D We also save: + +\def\savemathtextstyle#1% #1=rm|ss|.. + {\doifsomething{#1}{\setxvalue{\fontclass\c!mm\s!text}{#1}}} + +\def\currentmathtextstyle % we default to empty ! + {\executeifdefined{\fontclass\c!mm\s!text}\empty} + +%D Scaling macros: + +\newdimen\scaledfont + +\let\somefontspec\empty + +\def\@fs@{@fs@} + +% \def\parsefontspec#1% +% {\xdef\somefontspec{#1\space\relax}% +% \@EA\doparsefontspec\somefontspec]% =>#1 \relax] +% \donoparsefontspec} +% +% but, better: + +\let\somefontname\empty + +\def\parsefontspec#1% + {\xdef\somefontspec{#1\space}% + \@EA\doparsefontspec\somefontspec\relax]% =>#1 \relax] + \donoparsefontspec} + +\def\doparsefontspec#1 #2% + {\def\somefontname{#1}% + \ifx\somefontname\empty % space before fontname + \@EA\doparsefontspec + \else\ifx#2\relax + \@EAEAEA\setnaturalfontspec + \else + \@EAEAEA\setforcedfontspec + \fi\fi + #2} + +\def\setnaturalfontspec#1]% + {\@fs@scaled\plusthousand\relax} + +\def\setforcedfontspec#1 #2\relax]% + {\csname\@fs@#1\endcsname#2\relax} + +\def\@fs@scaled + {\afterassignment\do@fs@scaled\scratchcounter} + +\def\do@fs@scaled#1\relax + {\scaledfont\number\scratchcounter\points + \scaledfont\localrelativefontsize\scaledfont + \ifautofontsize\scaledfont\currentfontbodyscale\scaledfont\fi + \scratchcounter\scaledfont % \scaledfont is now pretty large + \advance\scratchcounter \medcard + \divide\scratchcounter \maxcard + \xdef\somefontspec{ scaled \the\scratchcounter}} + +\def\@fs@at + {\afterassignment\do@fs@at\scaledfont} + +\def\do@fs@at#1\relax + {\scaledfont\localrelativefontsize\scaledfont + \ifautofontsize\scaledfont\currentfontbodyscale\scaledfont\fi + \xdef\somefontspec{ at \the\scaledfont}} + +\def\@fs@sa + {\scaledfont\localabsolutefontsize + \setsamofontspec} + +\def\@fs@mo + {\scaledfont\setmappedfontsize\localabsolutefontsize + \setsamofontspec} + +\def\setsamofontspec#1\relax + {\checkfontscale#1\end\scaledfont + \scaledfont\localrelativefontsize\scaledfont + \ifautofontsize\scaledfont\currentfontbodyscale\scaledfont\fi + \xdef\somefontspec{ at \the\scaledfont}} + +\def\getfontparameters + {\expandafter\dogetfontparameter\@@fontdata,]=,} + +\def\getglobalfontparameters + {\expandafter\dogetglobalfontparameter\@@fontdata,]=,} + +\def\dogetfontparameter#1=#2,% + {\if]#1\else + \expandafter\def\csname\??ff\@@fontfile#1\endcsname{#2}% + \expandafter\dogetfontparameter + \fi} + +\def\dogetglobalfontparameter#1=#2,% + {\if]#1\else + \expandafter\gdef\csname\??ff\@@fontfile#1\endcsname{#2}% + \expandafter\dogetglobalfontparameter + \fi} + +\let\@@fontencoding\empty +\let\@@fontmapping \empty +\let\@@fonthandling\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 +%D ($-33$\%) and mfonts from 42 to 34 seconds ($-15$\%). + +\newif\ifskipfontcharacteristics \skipfontcharacteristicstrue + +%D When fontclasses are used, we define the font global, +%D since namespaces are used. Otherwise we parse the specs +%D each time. + +% wrong: this way we cannot set encoding etc +% +% \def\donoparsefontspec#1% +% {\edef\fontfile{\truefontname\somefontname}% +% \ifx\fontfile\s!unknown \let\fontfile\defaultfontfile \fi +% \edef\lastfontname{\fontfile\somefontspec}% +% \ifx\fontclass\empty\else\global\fi +% \expandafter\font\csname#1\endcsname\lastfontname\relax +% \relax} + +\let\fontfile\s!unknown + +\ifx\checkfontfilename\undefined \let\checkfontfilename\relax \fi + +% \definefontsynonym +% [blabla] +% [name:Latin Modern Something] +% \definefontsynonym +% [blabla] +% [file:texnansi-lmr10] +% [encoding=texnansi] +% \definedfont[blabla] test \currentencoding/\fontfile \par +% \definefontsynonym +% [blabla] +% [texnansi-lmtt10] +% [encoding=texnansi] +% \definedfont[blabla] test \currentencoding/\fontfile \par +% \definefontsynonym +% [blabla] +% [ec-lmtt10] +% [encoding=ec] +% \definedfont[blabla] test \currentencoding/\fontfile \par + +\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] +% +% \starttypescript [serif] [palatino-nova-regular] [name] +% \definefontsynonym[Serif] [palatinonova-regular][features=default] +% \definefontsynonym[SerifCaps][palatinonova-regular][features=default-caps] % also sets Serif +% \stoptypescript +% +% \starttypescript [serif] [palatino-nova-regular] [name] +% \definefontsynonym[Serif] [palatinonova-regular*default] +% \definefontsynonym[SerifCaps] [palatinonova-regular*default-caps] +% \stoptypescript + +% \definetypeface[mainface][rm][serif][palatino-nova-regular][default] \setupbodyfont[mainface] +% +% \starttext +% ``Test'' -- --- ff fi fl \sc ``Test'' -- --- ff fi fl +% \stoptext + +% \starttext +% \definefont +% [blabla] +% [name:Latin Modern Something] +% \definefont +% [blabla] +% [file:texnansi-lmr10] +% \blabla test +% \definefont +% [blabla] +% [texnansi-lmtt10] +% \blabla test +% \stoptext + +% \starttext +% +% \setupcolors[state=start] +% +% \definefontfeature +% [default-base] +% [script=latn,language=dflt,liga=yes,kern=yes,tlig=yes,trep=yes] +% \definefontfeature +% [default-node] +% [script=latn,language=dflt,liga=yes,kern=yes,tlig=yes,trep=yes,mode=node] +% \definefontfeature +% [default-none] +% [script=latn,language=dflt,liga=yes,kern=no, tlig=yes,trep=yes] +% +% \startoverlay +% {\vtop{\color[red] {\font\test=name:lmroman12regular*default-node \test \input ward \input zapf \input linden }}} +% {\vtop{\color[green]{\font\test=name:lmroman12regular*default-base \test \input ward \input zapf \input linden }}} +% {\vtop{\color[blue] {\font\test=name:lmroman12regular*default-none \test \input ward \input zapf \input linden }}} +% \stopoverlay +% +% \blank +% +% \startoverlay +% {\vtop{\color[red] {\font\test=name:texgyrepagella*default-node \test \input ward \input zapf \input linden }}} +% {\vtop{\color[green]{\font\test=name:texgyrepagella*default-base \test \input ward \input zapf \input linden }}} +% {\vtop{\color[blue] {\font\test=name:texgyrepagella*default-none \test \input ward \input zapf \input linden }}} +% \stopoverlay +% +% \blank +% +% \startoverlay +% {\vtop{\color[red] {\font\test=name:palatinonovaregular*default-node \test \input ward \input zapf \input linden }}} +% {\vtop{\color[green]{\font\test=name:palatinonovaregular*default-base \test \input ward \input zapf \input linden }}} +% {\vtop{\color[blue] {\font\test=name:palatinonovaregular*default-none \test \input ward \input zapf \input linden }}} +% \stopoverlay +% +% \startoverlay +% {\vtop{\color[red] {\font\test=name:OfficinaSerifBookITC*default-node \test \input ward \input zapf \input linden }}} +% {\vtop{\color[green]{\font\test=name:OfficinaSerifBookITC*default-base \test \input ward \input zapf \input linden }}} +% {\vtop{\color[blue] {\font\test=name:OfficinaSerifBookITC*default-none \test \input ward \input zapf \input linden }}} +% \stopoverlay +% +% \definefontfeature[superdefault][default][compose=yes] +% +% {\font\oeps=name:lmroman10regular*default at 30pt \oeps test \char7683} +% {\font\oeps=name:lmroman10regular*superdefault at 30pt \oeps test \char7683} +% +% \stoptext + +\let\doshowcheckedfontfeatures\relax + +\def\showcheckedfontfeatures + {\def\doshowcheckedfontfeatures{\writestatus\m!fonts{checked: \checkedfontfile}}} + +\def\checkedfontfile{\fontfile} % default + +\newtoks\everydefinefont + +\def\donoparsefontspec % #1 == \cs + {\edef\fontfile{\truefontname\somefontname}% + \ifx\fontfile\s!unknown \let\fontfile\defaultfontfile \fi % can for instance happen with MathGamma + \updatefontparameters + \checkfontfilename + \edef\lastfontname{\checkedfontfile\somefontspec}% + \ifx\fontclass\empty + \expandafter\definefontlocal + \else + \expandafter\definefontglobal + \fi} % #1 == \cs + +\def\definefontlocal#1% + {\expandafter\edef\csname#1\endcsname % ! ! ! ! not needed in luatex ! ! ! ! + {\noexpand\csname#1:\endcsname + \noexpand\reactivatefont{\somefontname}{\fontfile}}% + \expandafter\font\csname#1:\endcsname\lastfontname\relax + \expandafter\let\expandafter\lastrawfontcall\csname#1:\endcsname + \the\everydefinefont} + +\def\definefontglobal#1% stores \somefontname=Mono and \fontfile=cmtt10 + {\expandafter\xdef\csname#1\endcsname % ! ! ! ! not needed in luatex ! ! ! ! + {\noexpand\csname#1:\endcsname + \noexpand\reactivatefont{\somefontname}{\fontfile}}% + \global\expandafter\font\csname#1:\endcsname\lastfontname\relax + \expandafter\let\expandafter\lastrawfontcall\csname#1:\endcsname + \the\everydefinefont} + +\def\reactivatefont#1#2% + {\def\somefontname{#1}% + \def\fontfile {#2}% + \updatefontparameters} + +% can be handy for tracing purposes +% +% \def\reportfontdefinition +% {\bgroup +% \expanded{\infofont +% [\lastfontidentifier +% ->\newfontidentifier +% ->\fontname\csname\newfontidentifier\endcsname]}% +% \endgraf +% \egroup} + +%D An additional the second \type {\font} definition can +%D prevent fuzzy font refs +%D +%D \starttyping +%D \expandafter\font\csname\dummyfontname\endcsname\lastfontname +%D \stoptyping +%D +%D but somehow they changed \TEX\ so that it does not matter +%D any more. + +\def \defaultfontfile{\truefontname{Normal}} % was cmtt10, but that one is gone +\edef\nullfontname {\fontname\nullfont} +\edef\dummyfontname {font\strippedcsname\\} + +%D \macros +%D {everyfont,everyfontswitch} +%D +%D For special purposes, we provide a hook. + +% \newevery \everyfont \relax +% \newevery \everyfontswitch \relax + +% safer but sometimes introducing newlines in the log +% +% \batchmode +% \font\lastloadedfont\fontfile\somefontspec\relax +% \errorstopmode +% \edef\lastfontname{\fontname\lastloadedfont}% +% \ifx\lastfontname\nullfontname +% \showmessage\m!fonts{10}{\fontfile}% +% \expandafter\font\csname#1\endcsname=\defaultfontfile\somefontspec\relax +% \else +% \expandafter\let\csname#1\endcsname\lastloadedfont +% \fi + +%D We also accept \type{sa a}||\type{sa d} as specification. + +\def\checkfontscale#1#2\end#3% + {#3\ifcsname\??ft\s!default\noexpand#1\endcsname + \csname\??ft\s!default\noexpand#1\endcsname\else#1#2% + \fi#3} + +%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} +%D +%D While looking for fonts, fontsynonyms are used for accessing +%D the files! +%D +%D \starttyping +%D \definefontsynonym[Serif][Lucida-Bright] +%D \definefontsynonym[Lucida-Bright][lbr][encoding=texnansi] +%D \stoptyping +%D +%D The definitions can be accessed by: +%D +%D \startlines +%D name: \type {\truefontname{Lucida-Bright}} +%D data: \type {\truefontdata{\truefontname{Lucida-Bright}}} +%D \stoplines + +% \def\definefontsynonym +% {\dotripleempty\dodefinefontsynonym} +% +% \def\dodefinefontsynonym[#1][#2][#3]% +% {\@EA\edef\csname\??ff\fontclass#1\endcsname{#2}% +% \ifthirdargument +% \edef\@@fontdata{#3}% +% \ifx\@@fontdata\empty \else +% \edef\@@fontfile{#2}% +% \ifx\fontclass\empty +% \getfontparameters +% \else +% \getglobalfontparameters +% \fi +% \fi +% \fi} +% +% slightly faster, noticable when loading many typefaces, +% +% \testfeatureonce{5000}{\definefontsynonym[somefont][somename]} \end + +\def\classfont#1#2{#1#2} % \definefont[whatever][\classfont{xx}{yy} at 10pt] + +\def\definefontsynonym[#1]#2[#3]% + {\edef\@@fontfile{#3}% + \@EA\let\csname\??ff\fontclass#1\endcsname\@@fontfile + \doifnextoptionalelse\dodefinefontsynonym\donothing} + +\def\dodefinefontsynonym[#1]% + {\edef\@@fontdata{#1}% + \ifx\@@fontdata\empty \else \ifx\fontclass\empty + \getfontparameters + \else + \getglobalfontparameters + \fi \fi} + +\let\definefontfile\definefontsynonym % dedicated to Taco Hoekwater + +\def\setupfontsynonym + {\dodoubleempty\dosetupfontsynonym} + +\def\dosetupfontsynonym[#1][#2]% + {\edef\@@fontdata{#2}% + \ifx\@@fontdata\empty \else + \edef\@@fontfile{#1}% + \ifx\fontclass\empty + \getfontparameters + \else + \getglobalfontparameters + \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% + {\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} + +\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} + +% \definetypeface[palatino][rm][serif][palatino,allbold][default] +% +% \startfontclass[palatino] +% \definefontsynonym [Serif] [SerifBold] +% \definefontsynonym [SerifItalic] [SerifBoldItalic] +% \definefontsynonym [SerifSlanted] [SerifBoldSlanted] +% \definefontsynonym [SerifCaps] [SerifBold] +% \stopfontclass +% +% \setupbodyfont[palatino] + +\def\startfontclass + {\dosingleempty\dostartfontclass} + +\def\dostartfontclass[#1]% + {\pushmacro\fontclass + \doifelse{#1}{\v!each} + {\let\fontclass\empty} + {\doifsomething{#1}{\def\fontclass{#1}}}} + +\def\stopfontclass + {\popmacro\fontclass} + +%D \macros +%D {tracedfontname} +%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 + \else\ifcsname\??ff#1\endcsname + #1\tracedfontencoding{#1}\space->\space + \@EA\tracedfontname\csname\??ff#1\endcsname + \else + #1% + \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 + +% \def\@@currentfontfile{currentfontfile} +% +% \def\getfontfileparameters#1% +% {\edef\fontdata{\truefontdata{\truefontname{#1}}}% +% \expanded{\getparameters[\@@currentfontfile][\fontdata]}} + +\def\getfontfileparameters#1% can be simpler for mkii + {\edef\@@truefontname{\truefontname{#1}}% + \edef\currentfontfileencoding{\truefontdata\@@truefontname\s!encoding}% + \edef\currentfontfilemapping {\truefontdata\@@truefontname\s!mapping }% + \edef\currentfontfilehandling{\truefontdata\@@truefontname\s!handling}% + \edef\currentfontfilefeatures{\truefontdata\@@truefontname\s!features}} + +%D \macros +%D {definefont} +%D +%D Before we implement the main definition macro, we first show +%D one for local use: +%D +%D \starttyping +%D \definefont[Some][LucidaBright at 100pt] \Some some +%D \definefont[More][LucidaBright scaled 3000] \More more +%D \definefont[Nice][LucidaBright mp 2] \Nice nice +%D \definefont[Text][LucidaBright sa 5.4] \Text last +%D \stoptyping +%D +%D The implementation looks as follows: + +\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]}} + +\def\redodefinefont#1#2#3% + {\dododefinefont{#1}{#2}% + \doifsetupselse{#3} + {\setups[#3]} % don't forget to document this ! + {\setuplocalinterlinespace[#3]% + \setupspacing}} % needed ? + +\def\definefrozenfont + {\dotripleempty\dodefinefrozenfont} + +\def\dodefinefrozenfont[#1][#2][#3]% + {\dodefinefont[#1][#2][#3]% + \expandafter\let\csname\lastfontidentifier\expandafter\endcsname\csname\rawfontidentifier\endcsname} + +% \def\defineclassfont +% {\doquadrupleempty\dodefineclassfont} +% +% \def\dodefineclassfont[#1][#2][#3][#4]% #2 = class +% {\iffourthargument +% \definefont[#1][#2#3][#4]% +% %\else\ifthirdargument +% % \definefont[#1][#2#3]% +% \else +% \definefont[#1][#2]% +% \fi} + +%D The \type {*} makes the switch local, so that we can redefine a +%D logical name and/or change the size in between. + +\newif\ifautofontsize \autofontsizetrue + +\let\lastfontidentifier\empty + +\def\rawfontidentifier{**\lastfontidentifier\fontsize**} +\def\newfontidentifier{*\fontclass\lastfontidentifier\fontsize*} + +% best we can add the style as well because otherwise we get math encoding mixups +% +% \setupbodyfont [8pt] [\currentencoding/\ccaron\scaron\zcaron] +% \blank +% \switchtobodyfont[7pt] [\currentencoding/\ccaron\scaron\zcaron] + +\def\newfontidentifier{*\fontclass\lastfontidentifier\fontstyle\fontsize*} + +\def\dododefinefont#1#2% + {\edef\lastfontidentifier{#1}% + \let\localrelativefontsize\defaultrelativefontsize + \let\localabsolutefontsize\fontbody + \parsefontspec{#2}\rawfontidentifier + \let\localrelativefontsize\defaultrelativefontsize % not needed + \csname\rawfontidentifier\endcsname + \autofontsizefalse + \setfontcharacteristics + \the\everyfontswitch} + +\def\xxdododefinefont#1#2#3#4% \autofontsizetrue is set by calling routine + {\edef\lastfontidentifier{#3}% + \ifcsname\newfontidentifier\endcsname\else + \def\localrelativefontsize{#1}% + \def\localabsolutefontsize{#2}% + \parsefontspec{#4}\newfontidentifier + \let\localrelativefontsize\defaultrelativefontsize % not needed + \fi + \csname\newfontidentifier\endcsname + \autofontsizefalse + %\edef\lastfontidentifier{#3}% + \ifskipfontcharacteristics \else + \setfontcharacteristics + \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 +%D For special purposes, like in math, you may want to use +%D slightly different sizes than the ones given. This happens +%D for instance with the Math Times fonts. Mapped font sizes +%D can be specified by using the \type {mo} key instead of +%D \type {sa} in font definitions. +%D +%D \startbuffer +%D \mapfontsize[10pt][11pt] +%D \mapfontsize[11pt][12pt] +%D \mapfontsize[12pt][13pt] +%D +%D \definefont[test][Serif]\test TEST \par +%D \definefont[test][Serif sa 5]\test TEST \par +%D \definefont[test][Serif mo 5]\test TEST \par +%D \definefont[test][Serif sa d]\test TEST \par +%D \definefont[test][Serif at 60pt]\test TEST \par +%D \definefont[test][Serif scaled 6000]\test TEST \par +%D \stopbuffer +%D +%D \typebuffer +%D +%D \startpacked +%D \getbuffer +%D \stoppacked + +\def\mapfontsize + {\dodoubleargument\domapfontsize} + +\def\domapfontsize[#1][#2]% + {\scratchdimen#1\relax % \relax is really needed here + \setvalue{\??ft*\the\scratchdimen}{#2}} + +\def\setmappedfontsize#1% + {\ifcsname\??ft*#1\endcsname + \csname\??ft*#1\endcsname + \else + #1% + \fi} + +%D \macros +%D {getfontname} +%D +%D The names of the fonts can be called with the rather simple +%D macro \type{\getfontname}. When for instance we pass +%D \type{12ptrmtf} as argument, we get \getfontname{12ptrmtf}. + +\def\getfontname#1% + {\csname\??ft#1\endcsname} + +%D To be documented. + +\let\fontsizelist\empty +\let\fontstylelist\empty + +\def\definefontsize[#1]% sneller met toks + {\addtocommalist{#1}\fontsizelist + \def\docommand##1% + {\def\dodocommand####1% + {\def\dododocommand########1% + %{\checkbodyfont{}{########1}{####1}{##1}}% + {\checkbodyfont{########1}{####1}{##1}}% + \processcommacommand[\fontstylelist]\dododocommand}% + \processcommacommand[\fontalternativelist]\dodocommand}% + \processcommacommand[\fontsizelist]\docommand} + +\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} + +\let\fontalternativelist\fontalternativetextlist % upward compatible + +%D \macros +%D {currentfontscale,currentfontbodyscale} +%D +%D Sometimes we need to have access to the font scale +%D including the \type{a}||\type{d} sizes. The next macro +%D returns the current scaling factor. Take a look at +%D \type {cont-log.tex} for an example of its use. + +\def\currentfontscale + {\csname\??ft\s!default + \ifcsname\??ft\s!default\xfontsize\endcsname \xfontsize \else + \ifcsname\??ft\s!default\s!text \endcsname \s!text \fi\fi + \endcsname} + +\def\currentfontbodyscale + {\csname\??ft\s!default + \ifcsname\??ft\s!default\fontsize\endcsname \fontsize \else + \ifcsname\??ft\s!default\s!text \endcsname \s!text \fi\fi + \endcsname} + +\setvalue{\??ft\s!default}{1} + +%D Both alternatives use \type {\xfontsize}, a macro that +%D expands to the current size in terms of \type {a} \unknown +%D \type {d}, nothing, or \type {x} \unknown \type {xx}. + +\def\xfontsize{\ifcase\currentxfontsize\fontsize\or\c!x\else\c!xx\fi} + +%D A typical use of this command is in commands that switch +%D to another font bypassing the font mechanism: +%D +%D \starttyping +%D \font\myfont=\truefontname{MyFont} at \currentfontscale\bodyfontsize +%D \stoptyping + +%D Now we enter the area of font switching. The switching +%D mechanism has to take care of several situations, like: +%D +%D \startitemize[packed] +%D \item changing the overal document fonts (including margins, +%D headers and footers) +%D \item changing local fonts (only the running text) +%D \item smaller and even more smaller alternatives (super- +%D and subscripts) +%D \stopitemize +%D +%D \TEX\ offers a powerfull family mechanism for super- and +%D subscripts in math mode. In text mode however, we don't use +%D families for the smaller alternatives, and therefore have +%D to take care of it otherwise. + +%D \macros +%D {definebodyfontenvironment,setupbodyfontenvironment} +%D +%D The relationship between the several sizes of a font, is +%D defined by: +%D +%D \showsetup{definebodyfontenvironment} +%D +%D Later on we will see how these parameters are used, so for +%D the moment we stick with an example: +%D +%D \starttyping +%D \definebodyfontenvironment +%D [12pt] +%D [ text=12pt, +%D script=9pt, +%D scriptscript=7pt, +%D x=10pt, +%D xx=8pt, +%D big=12pt, +%D small=10pt] +%D \stoptyping +%D +%D The first argument specifies the bodyfont size to which the +%D settings apply. All second parameters are specified in +%D dimensions and tell us more about related sizes. +%D +%D Afterwards, one can change values with +%D +%D \showsetup{setupbodyfontenvironment} +%D +%D Due to the fact that \type{\c!text} and \type{\s!text} can +%D have a similar meaning, and therefore can lead to an +%D unwanted loop, we temporary redefine \type{\c!text}. For +%D the moment this in only place that some trickery is needed +%D to fool the multilingual interface. +%D +%D When instead of a size the keyword \type{unknown} is +%D passed, fractions (relations) are used instead of fixed +%D sizes. + +\let\bodyfontenvironmentlist\empty + +\newcount\@@fontdefhack + +\def\@@beginfontdef + {\ifcase\@@fontdefhack + \let\k!savedtext \k!text \let\k!text \s!text + \let\k!k!savedtext \k!k!text \let\k!k!text \!!plusone + \let\k!saveddefault \k!default \let\k!default \s!default + \let\k!k!saveddefault\k!k!default \let\k!k!default \!!plusone + \fi + \advance\@@fontdefhack \plusone } + +\def\@@endfontdef + {\advance\@@fontdefhack \minusone + \ifcase\@@fontdefhack + \let\k!k!default\k!k!saveddefault + \let\k!default \k!saveddefault + \let\k!k!text \k!k!savedtext + \let\k!text \k!savedtext + \fi} + +\def\definebodyfontenvironment + {\dotripleempty\dodefinebodyfontenvironment} + +\def\dodefinebodyfontenvironment[#1][#2][#3]% class size settings + {\ifthirdargument + \@@beginfontdef + \doifelse{#2}\s!default + {\getparameters[\??ft\s!default][#3]} + {\normalizebodyfontsize#2\to\tempbodyfontsize + \addtocommalist\tempbodyfontsize\bodyfontenvironmentlist + \@EA\dododefinebodyfontenvironment\@EA[\tempbodyfontsize][#1][#3]}% + \@@endfontdef + \else + \definebodyfontenvironment[\fontclass][#1][#2]% change */* + \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 + \normalizebodyfontsize\scratchdimen\to\tempbodyfontsize + \setevalue{\??ft#2#1##1}{\tempbodyfontsize}}% + \processcommacommand[\fontrelativesizelist]\docommand + \copyparameters + [\??ft#2#1][\??ft\s!default] + [\c!interlinespace,\c!em]}% + \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 + % so far + \setvalue{\@size@#1}{\docompletefontswitch[#1]}} + +%D {\bf Remark:} We need to cover the following cases, +%D otherwise users can get confused: +%D +%D \starttyping +%D \setupbodyfont[23pt] +%D +%D \definebodyfontenvironment[23pt] +%D \setupbodyfont[23pt] +%D +%D \definebodyfontenvironment[23pt] +%D \definebodyfont[23pt][rm,ss,tt][default] +%D \setupbodyfont[23pt] +%D \stoptyping + +%D Beware: while some font defs can be global, the bodyfont +%D environment checks local. This means that multiple local +%D checks resulting in definitions are not that efficient. +%D So, apart from an occasional switch, one should define an +%D environment at the outer level. + +\def\checkbodyfontenvironment[#1]% + {\definebodyfontenvironment[\fontclass][#1][]} + +% original +% +% \def\setupbodyfontenvironment +% {\dotripleempty\dosetupbodyfontenvironment} +% +% \def\dosetupbodyfontenvironment[#1][#2][#3]% class size settings +% {\@@beginfontdef +% \ifthirdargument +% \getparameters[\??ft#1#2][#3]% +% \else +% \getparameters[\??ft#1][#2]% +% \fi +% \@@endfontdef} +% +% 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% + {\??ft\ifcsname\??ft\fontclass#1\endcsname\fontclass\fi#1} + +\def\bodyfontcsname + {\csname\bodyfontvariable} + +\def\bodyfontinterlinespecs + {\bodyfontvariable{\normalizedbodyfontsize\c!interlinespace}} + +\def\bodyfontinterlinespace + {\csname\bodyfontinterlinespecs\endcsname} + +%D We default all parameters to the main bodyfont size (begin +%D \type{#1}), so the next setup is valid too: +%D +%D \starttyping +%D \definebodyfontenvironment[24pt] +%D \stoptyping +%D +%D All parameters can be redefined when needed, so one does +%D not have to stick to the default ones. + +%D \macros +%D {definebodyfont} +%D +%D The next step in defining a bodyfont involves the actual font +%D files, which can be recognized by their extension +%D \type{tfm}. Installing those file is often beyond the +%D scope of the user and up to the system administrator. +%D +%D \showsetup{definebodyfont} +%D +%D This commands takes three arguments: a (series of) bodyfont +%D size(s), the style group to which the definitions belong, +%D and an alternative, as specified by the \TEX\ (math) families, +%D extended with~a, b~\unknown. +%D +%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 +%D \starttyping +%D \definebodyfont [12pt] [rm] +%D [tf=cmr12, +%D bf=cmbx12, +%D it=cmti12, +%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 sc=cmcsc10 at 12pt] +%D +%D \definebodyfont [12pt,11pt,10pt,9pt,8pt] [rm] +%D [tf=lbr sa 1, +%D bf=lbd sa 1, +%D it=lbi sa 1, +%D sl=lbsl sa 1, +%D bi=lbdi sa 1, +%D bs=lbdi sa 1, +%D tfa=lbr sa 1.200, +%D tfb=lbr sa 1.440, +%D tfc=lbr sa 1.728, +%D tfd=lbr sa 2.074, +%D sc=lbr sa 0.833] +%D \stoptyping +%D +%D The second example shows that we can define more sizes at +%D once. The main difference between these examples is that the +%D Computer Modern Roman come in many design sizes. This means +%D that there we cannot define them in bulk using \type{sa}. +%D Instead of \type{rm} (roman) one can define \type{ss} (sans +%D serif), \type{tt} (teletype), \type{hw} (hand written), +%D \type{cg} (calygraphic) and whatever styles. +%D +%D The first argument may be a comma separated list. This, +%D combined with specifications using \type{sa} can save a lot +%D of typing. Although all arguments should be specified, we +%D treat the second argument as optional. +%D +%D Defining a bodyfont involves two actions: defining the +%D specific style related alternatives, like \type{\rma}, +%D \type{\bfa} and \type{\rmsla}, and storing the definitions +%D of their bodyfont size related fonts. The first step is +%D bodyfont independant but executed every time. This permits +%D user definitions like \type{\tfw} or \type{\bfq} for real +%D large alternatives. + +\def\definebodyfont + {\doquadrupleempty\redefinebodyfont} + +\def\redefinebodyfont[#1][#2][#3][#4]% + {\iffourthargument + \processcommacommand[#1]{\reredefinebodyfont[#2][#3][#4]}% + \else + \dodefinebodyfont[#1][#2][#3]% + \fi} + +\def\reredefinebodyfont[#1][#2][#3]#4% + {\pushmacro\fontclass + \doifelse{#4}\s!default + {\let\fontclass\empty} + {\def\fontclass{#4}}% + \definebodyfont[#1][#2][#3]% + \popmacro\fontclass} + +\def\dodefinebodyfont[#1][#2][#3]% body|identifier style defs|identifier + {\ifthirdargument + \doifnumberelse{#1} + {\doifassignmentelse{#3} + {% [12pt] [style] [settings] + \doifundefined{#2}{\expanded{\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]}}}% + \else\ifsecondargument + \definebodyfont[#1][\c!rm][#2]% + \else + \doifundefined{\@size@#1} % Maybe there are default dependancies + {\defineunknownfont{#1}}% defined which we can use ([unknown]) + \doifundefined{\@size@#1} % and if not, then we have at least to + {\definebodyfont[#1][\c!rm][]}% make sure some basics are set up. + \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 + \processcommalist[#1]{\dododefinebodyfont{#2}{#3}}% + \let\relativefontsize\defaultrelativefontsize} + +\def\dododefinebodyfont#1#2#3% style defs body + {\checkbodyfontenvironment[#3]% just to be sure. + \processcommalist[#2]{\dodododefinebodyfont{#1}{#3}}} + +\def\dodododefinebodyfont#1#2#3% style body def + {\dododododefinebodyfont{#1}{#2}[#3]} + +\newif \ifresolvefontfile % protected by fontclass anyway + +\def\resolvefontname#1 {\truefontname{#1} } + +\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}}}% + \else + %\expanded{\writestatus{defining}{[\fontclass][#2#1#3#4#5] \resolvefontname#6 }}% + \global\letbeundefined{*\fontclass#2#1#3#4#5*}% + \ifresolvefontfile + \unexpanded\setxvalue{\fontclass#2#1#3#4#5}% + {\noexpand\xxdododefinefont{\relativefontsize}{#2}% + {#2#1#3#4#5}{\resolvefontname#6 }}% + \else + \scratchtoks{#6}% + \expanded{\unexpanded\noexpand\setgvalue{\fontclass#2#1#3#4#5}% + {\noexpand\xxdododefinefont{\relativefontsize}{#2}% + {#2#1#3#4#5}{\the\scratchtoks}}}% + \fi + \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\checkbodyfont#1% tests for ttsl mmbf + {\def\c!!mm{#1}% + \ifx\c!!mm\c!mm % prevents \max and alike (re)defs + \expandafter\checkmathbodyfont + \else + \expandafter\checktextbodyfont + \fi{#1}} % no \c!!mm, not expanded later on + +\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 + +\def\checktextbodyfont#1#2#3% style alt size / gdef % #3 can be empty + {%\message{!t #1 #2 #3!}% + \unexpanded\setgvalue {#1#3}{\setcurrentfontstylesize {#1}{#3}}% \rma + \unexpanded\setgvalue {#2#3}{\setcurrentfontalternativesize {#2}{#3}}% \sla + \unexpanded\setgvalue {#1#2#3}{\setcurrentfontstylealternativesize{#1}{#2}{#3}}% \rmsla + \unexpanded\setgvalue {#1}{\setcurrentfontstyle {#1}}% \rm + \unexpanded\setgvalue {#2}{\setcurrentfontalternative {#2}}% \sl + \unexpanded\setgvalue {#1\c!x}{\setcurrentfontxstylealternative {#1}}% \rmx + \unexpanded\setgvalue{#1\c!xx}{\setcurrentfontxxstylealternative {#1}}% \rmxx + \unexpanded\setgvalue {#2\c!x}{\setcurrentfontxalternative {#2}}% \slx + \unexpanded\setgvalue{#2\c!xx}{\setcurrentfontxxalternative {#2}}% \slxx + \unexpanded\setgvalue {#1#2}{\setcurrentfontstylealternative {#1}{#2}}}% \rmsl + +\def\dodefinedefaultbodyfont[#1][#2][#3]% sizes styles identifier + {\def\dododefinedefaultbodyfont##1% + {\def\dodododefinedefaultbodyfont####1% + {\def\dododododefinedefaultbodyfont########1% + {\doifdefined{\s!default########1####1} + {% [12pt] [style] [identifier] + \getvalue{\s!default########1####1}{##1}{####1}}}% + \processcommalist[#3]\dododododefinedefaultbodyfont}% + \processcommalist[#2]\dodododefinedefaultbodyfont}% + \processcommalist[#1]\dododefinedefaultbodyfont} + +%D Unknown families are added to the family list! For the +%D moment we also set the direct calls here. Some day a better +%D solution will be implemented. The good news is that unknown +%D fonts are defined automatically. + +\newif\ifdefiningunknownfont + +% \def\defineunknownfont#1% +% {\let\c!savedtext\c!text +% \let\c!text\s!text +% \donefalse +% \def\docommand##1% +% {\doifdefined{\??ft\s!default##1} +% {\donetrue +% \scratchdimen#1\relax +% \scratchdimen\csname\??ft\s!default##1\endcsname\scratchdimen +% \normalizebodyfontsize\scratchdimen\to\!!stringa +% \letvalue{\??ft#1##1}\!!stringa}}% +% \processcommacommand[\fontrelativesizelist]\docommand +% \let\c!text\c!savedtext +% \ifdone +% \donefalse +% \def\defineunknownbodyfont##1% see *** +% %{\doifdefined{\s!default##1} +% % {\donetrue\getvalue{\s!default##1}{#1}}}% +% {\doifdefined{\s!default\s!default##1} +% {\donetrue\getvalue{\s!default\s!default##1}{#1}{##1}}}% +% \processcommacommand +% [\fontstylelist] +% \defineunknownbodyfont +% \ifdone +% \setvalue{\@size@#1}{\docompletefontswitch[#1]}% +% \ifdefiningunknownfont \else +% \definingunknownfonttrue +% \def\defineunknownsubfont##1% +% {\doifundefined{\@size@\getvalue{\??ft#1##1}} +% {\defineunknownfont{\getvalue{\??ft#1##1}}}}% +% \processcommacommand[\fontrelativesizelist]\defineunknownsubfont +% \definingunknownfontfalse +% \fi +% \fi +% \ifdone +% \showmessage\m!fonts{14}{#1}% +% \fi +% \fi} + +\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}} + +% \def\dodefineunknownbodyfont#1#2% see *** +% {\doifdefined{\s!default\s!default#2} +% {\donetrue +% \getvalue{\s!default\s!default#2}{#1}{#2}}} +% +% but ... it needs to be as follows: +% +% \def\dodefineunknownbodyfont#1#2% see *** +% {\doifdefined{\s!default\fontclass#2}% was \s!default\s!default (related to change */*) +% {\donetrue +% \getvalue{\s!default\fontclass#2}{#1}{#2}}} +% +% eh ... this does not work so we revert back to: + +\def\dodefineunknownbodyfont#1#2% see *** + {\doifdefined{\s!default\s!default#2}% somehow related to */* + {\donetrue + \getvalue{\s!default\s!default#2}{#1}{#2}}} + +\def\dodefineunknownsubfont#1#2% + {\doifundefined{\@size@\getvalue{\??ft#1#2}} + {\donetrue + \defineunknownfont{\getvalue{\??ft#1#2}}}} + +\def\defineunknownfont#1% + {\let\c!savedtext\c!text + \let\c!text\s!text + \donefalse + \processcommacommand[\fontrelativesizelist]{\dodefineunknownfont{#1}}% + \let\c!text\c!savedtext + \ifdone + \donefalse + \processcommacommand + [\fontstylelist] + {\dodefineunknownbodyfont{#1}}% + \ifdone + \donefalse + \setvalue{\@size@#1}{\docompletefontswitch[#1]}% + \ifdefiningunknownfont \else + \definingunknownfonttrue + \processcommacommand[\fontrelativesizelist]{\dodefineunknownsubfont{#1}}% + \definingunknownfontfalse + \fi + \fi + \ifdone + \showmessage\m!fonts{14}{#1}% + \fi + \fi} + +% \def\defineunknownfontstyles#1% +% {\def\defineunknownbodyfont##1% see *** +% {\executeifdefined{\s!default\s!default##1}\gobbletwoarguments{#1}{##1}}% +% \rawprocesscommacommand[\fontstylelist]\defineunknownbodyfont} + +%D These macros show that quite some definitions take place. +%D Fonts are not loaded yet! This means that at format +%D generation time, no font files are preloaded. + +%D A previous implementation used: +%D +%D \starttyping +%D \type {\setvalue{name}{\donottest...}} +%D \stoptyping +%D +%D instead of the more memory hungry: +%D +%D \starttyping +%D \unexpanded\setvalue{name}{...} +%D \stoptyping +%D +%D The first alternative saves about 500 hash entries (about +%D 2.5\% of the total number of entries used. The second +%D alternative is currently used, because that one can more +%D easily be made \ETEX\ aware. + +%D \macros +%D {everybodyfont,Everybodyfont,everyglobalbodyfont} +%D +%D Every change in bodyfont size has conseqences for the baseline +%D distance and skips between paragraphs. These are initialized +%D in other modules. Here we only provide the hooks that +%D garantees their handling. + +% \ifx\everybodyfont\undefined % permits reloading +% \newevery \everybodyfont \EveryBodyFont +% \fi + +%D At the system level one can initialize thing like: +%D +%D \starttyping +%D \appendtoks \setupspacing \to \everybodyfont +%D \stoptyping +%D +%D While users can add their own non standard commands like: +%D +%D \starttyping +%D \EveryBodyFont{\message{changing to bodyfont \the\bodyfontsize}} +%D \stoptyping +%D +%D Personnaly I never felt the need for such extensions, but +%D at least its possible. + +%D \macros +%D {globalbodyfontsize,localbodyfontsize} +%D +%D Next we'll do the tough job of font switching. Here we +%D have to distinguish between the global (overal) bodyfont +%D size and the local (sometimes in the textflow) size. We +%D store these dimensions in two \DIMENSION\ registers. + +\ifdefined\globalbodyfontsize\else \newdimen\globalbodyfontsize \fi \globalbodyfontsize=12pt +\ifdefined\localbodyfontsize \else \newdimen\localbodyfontsize \fi \localbodyfontsize =\globalbodyfontsize + +%D \macros +%D {bodyfontsize} +%D +%D These two registers are not to be misused in calculations. +%D For this purpose we keep a copy: + +\newdimen\bodyfontsize \bodyfontsize=\globalbodyfontsize + +%D \macros +%D {outputresolution} +%D +%D Sometimes (to be honest: not in this module) we need to +%D take the system resolution into account. Therefore we also +%D define a macro: + +\def\outputresolution {600} + +%D \macros +%D {bodyfontfactor,bodyfontpoints} +%D +%D For multiplication purposes we keep an auxiliary counter +%D and macro (here the expansion is not explicitly needed): + +\newcount\bodyfontpoints \dimensiontocount\bodyfontsize\bodyfontpoints + +\edef\bodyfontfactor{\withoutpt\the\bodyfontsize} + +%D When we assign for instance 12pt to a \DIMENSION\ register +%D the \type{\the}'d value comes out as 12.0pt, which is +%D often not the way users specify the bodyfont size. Therefore +%D we also store the normalized value. + +\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\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#5\to#6% \points ? + {\edef#6% not \ifcase#2\else due to \relax adding + {#1% + \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}} + +%D To be internationalized: + +\def\korpsgrootte {\bodyfontsize} +\def\korpspunten {\bodyfontpoints} + +%D some day. + +%D \macros +%D {fontstyle,fontalternative,fontsize} +%D +%D Within a bodyfont, fonts can come in different sizes. For +%D instance \type{\tf} is accompanied by \type{\tfa}, +%D \type{\tfb} etc. The first two characters denote the +%D alternative, while the third character in these sequences +%D represents the size. The actual size is saved in a macro +%D +%D The style, being roman (\type{\rm}), sans serif (\type{\ss}) +%D etc. is also available in a macro in \type{rm}, \type{ss} +%D etc. form: + +\let\defaultfontalternative = \c!tf +\let\defaultfontstyle = \empty +\let\defaultfontsize = \empty + +\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.mkii} + {\showmessage\m!fonts2{#2}} + {\showmessage\m!fonts3{#2}}% + \stopreadingfile}} + +%D When \type {\loadfontfileoncetrue}, such files are +%D only loaded once! This permits redundant loading, but at +%D the same time forced grouping when we want continuously mix +%D all kind of font, which of course is a kind of +%D typographically sin. The \type{"} is made inactive if +%D needed to prevent problems with loading files that use this +%D character in numbers. + +\def\doswitchpoints[#1]% + {\expanded{\dodoswitchpoints{#1}}} + +\def\dodoswitchpoints#1% + {\doifundefined{\@size@#1} + {\defineunknownfont{#1}}% + %\defineunknownfontstyles{#1}% + \doifdefinedelse{\@size@#1} + {\getvalue{\@size@#1}% + \localbodyfontsize#1\relax + \normalizebodyfontsize\localbodyfontsize\to\normalizedbodyfontsize + \checkbodyfontenvironment[\normalizedbodyfontsize]} + {\showmessage\m!fonts4{#1}}} + +\unprotected \def\doswitchstyle[#1]% + {\doifdefinedelse{\@style@#1} + {\getvalue{\@style@#1}% + \edef\fontstyle{#1}% + \ifmmode\mr\fi % in order to be compatible with \rm in math mode + }% \the\everybodyfont} % cleaner, in setting size as well as style + {\showmessage\m!fonts5{#1}}} + +%D \TEX\ loads font metric files like \type{cmr10.tfm} and +%D \type{tir.tfm} only once. In \PLAIN\ \TEX\ some font files +%D are {\em preloaded}. This means that the font files are +%D loaded, but not accessible yet by name. This is accomplished +%D by saying: +%D +%D \starttyping +%D \font\preloaded=cmr10 at 11pt +%D \stoptyping +%D +%D and using the name \type{\preloaded} again and again, so +%D fonts are indeed loaded, but unnamed, and therefore +%D unaccessible. In \CONTEXT\ we don't preload fonts, not even +%D the \PLAIN\ \TEX\ ones, although users can access them. Now +%D why is this done? + +%D Defining fonts using \type{\definebodyfont} takes time, so we +%D prefer to predefine at least the Computer Modern Roman +%D fonts. However, loading all those fonts at definition time +%D would take both time and space. But even worse, once fonts +%D are loaded into memory, their encoding vector is fixed, +%D which is a handicap when we want to distribute the compact +%D \type{fmt} files. So what we want to do is defining fonts in +%D a way that postpones the loading. We accomplish this by only +%D loading the fonts when we switch to another bodyfont size. +%D Among the other alternatives, such as loading the font at +%D the moment of activation and redefining the activation +%D macro afterwards, this proved to be the most efficient +%D alternative. +%D +%D The next few macros take care of the one exeption on this +%D scheme. When at format generation time we load the default +%D font file, the one that defines the Computer Modern Fonts, +%D we don't want the fonts metrics to end up in the format +%D file, so we temporary prohibit loading. This means that at +%D runtime we have to load the default bodyfont size just before +%D we start typesetting. +%D +%D Therefore we have to signal the font switching macros that +%D we are preloading fonts. As long as the next boolean is, +%D true, no loading is done. + +\newif\ifloadingfonts \loadingfontstrue + +%D \macros +%D {preloadfonts} +%D +%D Preloading is only called for once, during the startup +%D sequence of a session. After the loading job is done, the +%D macro relaxes itself and reset the signal. + +\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\let\preloadfonts\relax} + +% \prependtoks \preloadfonts \to \everydump % saves .1 s on a DELL P60 - 2GHZ + +%D Here comes the main font switching macros. These macros +%D handle changes in size as well as returning to the global +%D bodyfont size. + +\def\dosetfont#1#2% #1 = set/switch state + {\doifelse{#2}\v!global + {\restoreglobalbodyfont} + {\processcommacommand[#2]{\dodosetfont{#1}}% ##1 get also passed + \ifloadingfonts\else + \doswitchpoints[\normalizedbodyfontsize]% + \doswitchstyle[\fontstyle]% + \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{\bodyfontcsname\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}}}}}} + +\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}}} + +%D In the previous macros we use \type{\currentxfontsize} to +%D hold the current x||size of the font. This enables us to +%D support for instance \type{\sl} inside a \type{\tx} switch. + +\chardef\currentxfontsize=0 + +%D When users specify for instance a 13 point bodyfont while no +%D such bodyfont is defined, the system automatically tries to +%D find a best fit, that is the nearest smaller defined +%D bodyfontzize. A smaller one is definitely better than a larger +%D one, simply because otherwise a lot of overfull box messages +%D are more probable to occur. By taking a value slightly +%D smaller than half a point, we can use the next method. + +\def\dosetsubstitutefont#1#2% #1 = set/switch state + {\scratchdimen#2\relax + \advance\scratchdimen .499\points + \dimensiontocount\scratchdimen\scratchcounter + \advance\scratchcounter \minusone + \ifnum\scratchcounter>\plusthree + \dododosetfont{#1}{\the\scratchcounter\s!pt}{}% + \fi} + +% The following bunch of macros deals with the (run time) +% expansion of names onto the definitions made by \type +% {\definebodyfont}. + +% \let\fontbody \empty % ... 10pt 11pt 12pt ... +% \let\fontstyle \empty % rm ss tt mm hw cg ... +% \let\fontalternative\empty % tf bf sl it bs bi sc ... +% \let\fontsize \empty % xy-abcd ... + +\def\defaultfontbody{\normalizedbodyfontsize} + +\let\fontbody\defaultfontbody + +\let\fontclass\empty \let\globalfontclass\fontclass + +% \def\setcurrentfontclass#1% +% {\edef\fontclass{#1}} + +\def\registerfontclass#1% + {\letgvalue{\@fontclass@#1}\v!yes} % global ? + +\def\setcurrentfontclass#1% + {\ifcsname\@fontclass@#1\endcsname + \edef\fontclass{#1}% + \fi} + +\let\defaultfontstyle \c!rm +\let\defaultfontalternative \c!tf +\let\defaultfontsize \empty + +%D \macros +%D {bigmath,nobigmath} +%D +%D We can inhibit this slow||downer with: + +% these can best be combined + +% 0=never 1=everymath 2=always + +\chardef\synchronizebigmathflag=1 + +\appendtoks + \ifcase\synchronizebigmathflag + % never + \or + \synchronizebigmath + \or + % always + \fi +\to \everymathematics + +\def\nobigmath{\chardef\synchronizebigmathflag 0 } +\def\bigmath {\chardef\synchronizebigmathflag 2 \synchronizebigmath} + +\let\bigmathfontsize\empty + +\def\synchronizebigmath + {\ifx\bigmathfontsize\fontsize + % already in sync + \else + \let\bigmathfontsize\fontsize + \synchronizemath \synchronizetext + \fi} + +\def\checkbigmathsynchronization + {\ifcase\synchronizebigmathflag + % never + \or + \ifmmode \synchronizebigmath \fi + \or + \synchronizebigmath + \fi} + +%D So far for synchronisation. + +\def\dosetcurrentfontsize#1% + {\edef\fontsize{#1}% + \checkbigmathsynchronization} + +\def\dosetcurrentfontalternative#1% + {\edef\fontalternative{#1}% + \ifmmode % maybe no test, or actually, an option + \fam\csname\fontalternative\s!fam\endcsname + \fi} + +\def\setcurrentfont#1#2#3#4% + {%\message{[1 #1 #2 #3 #4]}% + \edef\fontbody{#1}% + \edef\fontstyle{#2}% + \dosetcurrentfontalternative{#3}% + \dosetcurrentfontsize{#4}% + \synchronizefont} + +\def\setcurrentfontbody#1% + {%\message{[2 #1]}% + \edef\fontbody{#1}% + \synchronizefont} + +% \def\setcurrentfontstyle#1% +% {%\message{[3 #1]}% +% \edef\fontstyle{#1}% +% \ifmmode\mr\fi % otherwise \rm not downward compatible +% \synchronizefont} +% +% For Taco: optional fall backs: + +\ifx\checkfontclass\undefined \let\checkfontclass\gobbleoneargument \fi % implemented in type-ini + +\def\setcurrentfontstyle#1% + {%\message{[3 #1]}% + \checkfontclass{#1}% + \edef\fontstyle{#1}% + \ifmmode\mr\fi % otherwise \rm not downward compatible + \synchronizefont} + +\def\setcurrentfontbodyalternative#1#2% + {%\message{[4 #1 #2]}% + \edef\fontbody{#1}% + \dosetcurrentfontalternative{#2}% + \synchronizefont} + +\def\setcurrentfontalternative#1% + {%\message{[5 #1]}% + \dosetcurrentfontalternative{#1}% + \synchronizefont} + +\def\setcurrentfontsize#1% + {%\message{[6 #1]}% + \dosetcurrentfontsize{#1}% + \synchronizefont} + +\def\setcurrentfontstylealternative#1#2% \rmsl + {%\message{[7 #1 #2]}% + \edef\fontstyle{#1}% + \dosetcurrentfontalternative{#2}% + \synchronizefont} + +\def\setcurrentfontstylesize#1#2% \rmsla + {%\message{[8 #1 #2]}% + \edef\fontstyle{#1}% + \dosetcurrentfontsize{#2}% + \synchronizefont} + +\def\setcurrentfontalternativesize#1#2% \sla + {%\message{[9 #1 #2]}% + \dosetcurrentfontalternative{#1}% + \dosetcurrentfontsize{#2}% + \synchronizefont} + +\def\setcurrentfontstylealternativesize#1#2#3% \rmsla + {%\message{[10 #1 #2 #3]}% + \edef\fontstyle{#1}% + \dosetcurrentfontalternative{#2}% + \dosetcurrentfontsize{#3}% + \synchronizefont} + +%D In principle one can assign alternative fallback routines. +%D Some day we will. + +\newtoks\fontstrategies +\newif\iftryingfont + +\let\fontstrategy\relax + +\def\synchronizefont + {\tryingfonttrue + \ifx\fontclass\empty\else + \global\let\fontstrategy\dofontclassstrategy + \the\fontstrategies \relax % \relax still needed ? + \fi + \iftryingfont + \global\let\fontstrategy\dofontstrategy + \the\fontstrategies \relax % \relax still needed ? + \fi + \ifskipfontcharacteristics + \setfontcharacteristics + \the\everyfontswitch + \fi} + +\def\dofontstrategy#1#2#3#4#5% + {\ifcsname#2#3#4#5\endcsname + #1\csname#2#3#4#5\endcsname \tryingfontfalse + \fi} + +\def\dofontclassstrategy#1#2#3#4#5% + {\ifcsname\fontclass#2#3#4#5\endcsname + #1\csname\fontclass#2#3#4#5\endcsname \tryingfontfalse + \fi} + +\appendtoks \iftryingfont \fontstrategy \autofontsizefalse % --- --- --- --- % pt tt bf a + \fontbody \fontstyle \fontalternative \fontsize +\fi \to \fontstrategies + +\appendtoks \iftryingfont \fontstrategy \autofontsizetrue % --- --- --- def % pt tt bf + \fontbody \fontstyle \fontalternative \defaultfontsize +\fi \to \fontstrategies + +\appendtoks \iftryingfont \fontstrategy \autofontsizetrue % --- --- def --- % pt tt tf a + \fontbody \fontstyle \defaultfontalternative \fontsize +\fi \to \fontstrategies + +\appendtoks \iftryingfont \fontstrategy \autofontsizetrue % --- --- def def % pt tt tf + \fontbody \fontstyle \defaultfontalternative \defaultfontsize +\fi \to \fontstrategies + +\appendtoks \iftryingfont \fontstrategy \autofontsizefalse % --- def def def % pt rm tf + \fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize +\fi \to \fontstrategies + +\appendtoks \iftryingfont \fontstrategy \autofontsizetrue % def def def def % rm tf + \defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize +\fi \to \fontstrategies + +%D Let's synchronize: + +\newif\ifsynchronizefonts \synchronizefontstrue + +\prependtoks + \ifsynchronizefonts + \synchronizemath + \synchronizetext + \synchronizefont % problem: syncs last font + \fi +\to \everybodyfont + +%D Setting the normal sized as well as the x and xx smaller +%D sizes is accomplished by the next set of macros. When in +%D math mode, the commands \type{\tx} and \type{\txx} are +%D just a switch to the script and double script styles, but +%D in text mode the values defined by the bodyfontenvironment are +%D used. Here we also set \type{\currentxfontsize}. + +\def\dosetcurrentfontxxxalternative#1#2#3#4% + {\chardef\currentxfontsize#2\relax + \ifmmode + #4% + \else\ifcsname\bodyfontvariable{\normalizedbodyfontsize#3}\endcsname + \setcurrentfontbodyalternative{\bodyfontcsname\normalizedbodyfontsize#3\endcsname}{#1}% + \fi\fi} + +\def\setcurrentfontxalternative#1% + {\dosetcurrentfontxxxalternative{#1}1\c!x\scriptstyle + \let\tx\txx} + +\def\setcurrentfontxxalternative#1% + {\dosetcurrentfontxxxalternative{#1}2\c!xx\scriptscriptstyle + \let\tx\empty + \let\txx\empty} + +\def\checknestedxfontsize % option + {\ifcase\currentxfontsize\else\ifx\fontsize\empty\else + \chardef\currentxfontsize\zeropoint + \let\fontsize\empty + \let\tx\normaltx + \let\txx\normaltxx + \fi\fi} + +\def\setcurrentfontxalternative#1% + {\checknestedxfontsize + \dosetcurrentfontxxxalternative{#1}1\c!x\scriptstyle + \let\tx\txx} + +\def\setcurrentfontxxalternative#1% + {\checknestedxfontsize + \dosetcurrentfontxxxalternative{#1}2\c!xx\scriptscriptstyle + \let\tx\empty + \let\txx\empty} + +% 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} + +%D These macros also show us that when we call for \type{\tx}, +%D this macro is redefined to be \type{\txx}. Therefore calls +%D like: +%D +%D \startbuffer +%D {small \tx is \tx beautiful} +%D {small \tx is \txx beautiful} +%D {small \txx is \tx beautiful} +%D {small \txx is \txx beautiful} +%D \stopbuffer +%D +%D \typebuffer +%D +%D result in: +%D +%D \startvoorbeeld +%D \startlines +%D \getbuffer +%D \stoplines +%D \stopvoorbeeld +%D +%D Setting the main size involves the style list and therefore +%D takes a bit more time. Keep in mind that the fontsize is +%D represented by a character or empty. + +\unexpanded\def\tx {\setcurrentfontxalternative \fontalternative} +\unexpanded\def\txx{\setcurrentfontxxalternative\fontalternative} + +\let\normaltx \tx +\let\normaltxx\txx + +%D \macros +%D {definefontstyle} +%D +%D When setting of switching the overall style we can use the +%D short identifier like rm and ss, but when defined we can +%D also use more verbose names like roman or sansserif. Such +%D names are defined by: +%D +%D \starttyping +%D \definefontstyle [serif,rm] [rm] +%D \definefontstyle [sansserif,ss] [ss] +%D \stoptyping + +\def\dodefinefontstyle[#1][#2]% + {\rawdoifinsetelse{#2}{\fontstylelist} + {}%\debuggerinfo\m!fonts{unknown style #2}} + {\addtocommalist{#2}\fontstylelist + \showmessage\m!fonts8{#2\space (#1)}}% + % check kan hier + \def\docommand##1% + {\setvalue{\@shortstyle@##1}{#2}% + \setvalue{\@style@##1}{\csname#2\endcsname}}% + \processcommalist[#1]\docommand} + +\def\definefontstyle + {\dodoubleargument\dodefinefontstyle} + +\def\setfontstyle#1#2% #1:name (roman, romaan) #2:style (rm) + {\edef\fontstyle{#1}% + \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: +%D +%D \starttyping +%D \setupbodyfont +%D [ams] +%D +%D \definebodyfont [24pt] [mm] +%D [ma=msam10 at 24pt, +%D mb=msbm10 at 24pt] +%D +%D \switchtobodyfont +%D [24pt] +%D +%D This is a 24pt $\blacktriangleleft$ +%D \stoptyping +%D +%D Here we didn't define the 24 point bodyfont environment, so +%D it's defined automatically. Of course one can always use the +%D \TEX\ primitive \type{\font} to switch to whatever font +%D needed. + +%D When asking for a complete font switch, for instance from 10 +%D to 12~points, the next macro does the job. First we +%D normalize the size, next we define the current range of +%D text, script and scriptscript sizes, then we set the text +%D fonts and the math families and finally we activate the +%D default typeface and also set the font specific parameters +%D assigned to \type{\everybodyfont} + +\def\dosetbodyfontface#1#2% + {\edef#1{\bodyfontcsname\normalizedbodyfontsize#2\endcsname}} + +\def\docompletefontswitch[#1]% + {\bodyfontsize#1\relax + \dimensiontocount\bodyfontsize\bodyfontpoints + \edef\bodyfontfactor{\withoutpt\the\bodyfontsize}% + \normalizebodyfontsize\bodyfontsize\to\normalizedbodyfontsize + \dosetbodyfontface \textface \s!text + \dosetbodyfontface \scriptface \s!script + \dosetbodyfontface \scriptscriptface \s!scriptscript} + +\docompletefontswitch[12pt] % init + +%D \macros +%D {setupbodyfont,switchtobodyfont} +%D +%D The next two macros are user ones. With \type{\setupbodyfont} +%D one can set the document bodyfont size, font family, style +%D and/or options defined in files, for example: +%D +%D \starttyping +%D \setupbodyfont[cmr,ams,12pt,roman] +%D \stoptyping +%D +%D This command affects the document as a whole: text, headers +%D and footers. The second macro however affects only the text: +%D +%D \starttyping +%D \switchtobodyfont[10pt] +%D \stoptyping +%D +%D So we've got: +%D +%D \showsetup{setupbodyfont} +%D \showsetup{switchtobodyfont} +%D +%D Both macros look alike. The second one also has to take +%D all kind of keywords into account. + +\ifx\saveinterlinespace \undefined \let\saveinterlinespace \relax \fi +\ifx\restoreinterlinespace\undefined \let\restoreinterlinespace\relax \fi + +\chardef\bodyfontsetstate=0 + +\definecomplexorsimple\setupbodyfont + +\def\simplesetupbodyfont + {\restoreglobalbodyfont + \saveinterlinespace} + +\def\complexsetupbodyfont[#1]% + {\doifsomething{#1} + {\dosetfont1{#1}% + \globalbodyfontsize\localbodyfontsize + \normalizebodyfontsize\globalbodyfontsize\to\normalizedglobalbodyfontsize + \let\globalfontstyle\fontstyle + \ifloadingfonts\else + \the\everybodyfont + \the\everyglobalbodyfont + \saveinterlinespace + \fi}} + +\unexpanded\def\switchtobodyfont[#1]% + {\doifsomething{#1} + {\doifdefinedelse{\??ft\normalizedbodyfontsize\interfaced{#1}} + {\setbodyfontstep{#1}} % so we have a fast [small] switch + {\dosetfont0{#1}}% + \the\everybodyfont}} % indeed needed in case nothing is executed + +%D The following alternative is meant for math||to||text +%D switching and will be optimized. + +\def\fastswitchtobodyfont#1% + {\ifcsname\??ft\normalizedbodyfontsize#1\endcsname + \edef\futurebodyfontsize + {\csname\??ft\normalizedbodyfontsize#1\endcsname}% + \ifcsname\@size@\futurebodyfontsize\endcsname + \csname\@size@\futurebodyfontsize\endcsname + \localbodyfontsize\futurebodyfontsize\relax + \fi + \fi + \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\@@fontencoding{\truefontdata\fontfile \s!encoding}% + \edef\@@fontmapping {\truefontdata\fontfile \s!mapping }% + \edef\@@fonthandling{\truefontdata\somefontname\s!handling}% + \edef\@@fontfeatures{\truefontdata\fontfile \s!features}% + \edef\@@fontskewchar{\truefontdata\fontfile \s!skewchar}} + +\def\setfontcharacteristics + {\updatefontparameters % redundant, will go away, faster too + \fastenableencoding + {\ifx\@@fontencoding\empty + \s!default \else \@@fontencoding + \fi}% + \fastenablemapping + {\ifx\@@fontmapping\empty + \ifx\@@fontencoding\empty + \s!default \else \@@fontencoding + \fi + \else + \@@fontmapping + \fi}% + \fastenablehandling + {\ifx\@@fonthandling\empty + \s!default \else \@@fonthandling + \fi}% + {\lastfontidentifier}% + \the\everyfont + \synchronizepatternswithfont} + +\ifx\synchronizepatternswithfont\undefined + \def\synchronizepatternswithfont{\synchronizepatterns} +\fi + +%D Experimental: + +\def\definefontfeature + {\dotripleargument\dodefinefontfeature} + +\def\dododefinefontfeature#1% + {\edef\!!stringa{\ifx\!!stringa\empty\else\!!stringa,\fi\executeifdefined{\??fa#1}\empty}} + +\def\dodefinefontfeature[#1][#2][#3]% + {\doifassignmentelse{#2} + {\setevalue{\??fa#1}{#2}} + {\let\!!stringa\empty + \processcommalist[#2]\dododefinefontfeature + \setevalue{\??fa#1}{\ifx\!!stringa\empty\else\!!stringa,\fi#3}}} + +\definefontfeature + [default] + [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 + +\definefontfeature + [oldstyle] + [liga=yes,kern=yes,tlig=yes,trep=yes,onum=yes] % texligatures=yes,texquotes=yes + +\definefontfeature % no calt + [arabic] + [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] + +\definefontfeature + [none] + [features=no] + +%D The next auxilliary macro is an alternative to \type +%D {\fontname}. + +% \def\purefontname#1{\expandafter\splitoffpurefontname\fontname#1 \\} +% +% extra level is needed: + +\def\purefontname#1{\@EA\splitoffpurefontname\@EA{\@EA{\@EA\unstringed\fontname#1}} \\} + +\def\splitoffpurefontname#1 #2\\{#1} + +%D \macros +%D {switchstyleonly} +%D +%D For switching a style but keeping the alternative, there +%D is: +%D +%D \starttyping +%D {\bf text \switchstyleonly\ss text} +%D {\bf text \switchstyleonly[ss]text} +%D {\sl text \switchstyleonly[sansserif]text} +%D \stoptyping + +\definecomplexorsimple\switchstyleonly + +\def\simpleswitchstyleonly#1% stupid version + {\complexswitchstyleonly[\strippedcsname#1]} + +\def\complexswitchstyleonly[#1]% todo : check + {\setcurrentfontstyle{\getvalue{\@shortstyle@#1}}% + \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 +%D On behalf of {\frac Tobias Burnus}, we define some more of +%D these. Later we will link these names to real file names. + +% older +% +% \definefont [os] [OldStyle sa *] +% \definefont [frak] [Fraktur sa *] +% \definefont [goth] [Gothic sa *] +% \definefont [cal] [Calligraphic sa *] +% \definefont [bbd] [Blackboard sa *] +% +% newer + +\unexpanded\def\os {\mathortext{\fam\purefamily {oldstyle}}{\symbolicfont {OldStyle}}} +\unexpanded\def\frak{\mathortext{\fam\purefamily {fraktur}}{\symbolicfont {Fraktur}}} +\unexpanded\def\goth{\mathortext{\fam\purefamily {gothic}}{\symbolicfont {Gothic}}} +\unexpanded\def\cal {\mathortext{\fam\purefamily{calligraphic}}{\symbolicfont{Calligraphic}}} +\unexpanded\def\bbd {\mathortext{\fam\purefamily {blackboard}}{\symbolicfont {Blackboard}}} + +\definefontsynonym [OldStyle] [Serif] +\definefontsynonym [Fraktur] [Serif] +\definefontsynonym [Gothic] [Serif] +\definefontsynonym [Calligraphic] [Serif] +\definefontsynonym [Blackboard] [Serif] + +%D \macros +%D {fraktur, gothic, calligraphic, blackboard} +%D +%D These macros assume that we use text fonts, and not math +%D families. + +\ifx\mathtext\undefined \let\mathtext\hbox \fi + +\unexpanded\def\fraktur #1{\mathortext\domathtext\donothing{\frak#1}} +\unexpanded\def\gothic #1{\mathortext\domathtext\donothing{\goth#1}} +\unexpanded\def\calligraphic#1{\mathortext\domathtext\donothing{\cal #1}} +\unexpanded\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 +%D \PLAIN\ \TEX\ defines some macro's like \type{\tenpoint} +%D to switch to a specific bodyfontsize. Just for the sake of +%D compatibility we can define them like: +%D +%D \starttyping +%D \definebodyfontswitch [twelvepoint] [12pt] +%D \stoptyping +%D +%D We don't support language specific synonyms here, mainly +%D because \PLAIN\ \TEX\ is english anyway. + +\def\dodefinebodyfontswitch[#1][#2]% + {\def\docommand##1{\setvalue{##1}{\switchtobodyfont[#2]}}% + \processcommalist[#1]\docommand} + +\def\definebodyfontswitch + {\dodoubleargument\dodefinebodyfontswitch} + +%D \macros +%D {setsmallbodyfont,setmainbodyfont,setbigbodyfont} +%D +%D When we're typesetting at for instance 10pt, we can call for +%D the \type{small} as well as the \type{big} alternative, +%D related to this main size, using \type{\switchtobodyfont[small]}. +%D The three alternatives can be activated by the next three +%D system calls and are defined by the bodyfontenvironment. + +\let\fontstep\empty % we can use \fontstep for tracing purposes + +\def\setbodyfontstep#1% + {\edef\fontstep{\bodyfontcsname\normalizedbodyfontsize\interfaced{#1}\endcsname}% + \doswitchpoints[\fontstep]% + \doswitchstyle[\fontstyle]} + +\unexpanded\def\setsmallbodyfont{\setbodyfontstep\v!small\the\everybodyfont} +\unexpanded\def\setbigbodyfont {\setbodyfontstep\v!big \the\everybodyfont} + +\unexpanded\def\setmainbodyfont + {\doswitchpoints[\normalizedbodyfontsize]% + \doswitchstyle[\fontstyle]% + \the\everybodyfont + \the\everyglobalbodyfont + \saveinterlinespace} + +%D \macros +%D {restoreglobalbodyfont} +%D +%D Users can set whatever font available while typesetting text. +%D Pagenumbers, footers, headers etc. however must be typeset +%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 + +\def\fullrestoreglobalbodyfont + {\let\fontsize\defaultfontsize + \let\fontbody\defaultfontbody + \chardef\currentxfontsize\zerocount + \let\fontclass\globalfontclass + \doswitchpoints[\normalizedglobalbodyfontsize]% + \doswitchstyle[\globalfontstyle]% + \redoconvertfont % just in case a pagebreak occurs + \tf + \the\everybodyfont + \the\everyglobalbodyfont + \saveinterlinespace} + +\def\partialrestoreglobalbodyfont + {\let\fontsize\defaultfontsize + \let\fontbody\defaultfontbody + \chardef\currentxfontsize\zerocount + \redoconvertfont + \tf + \saveinterlinespace} + +\def\restoreglobalbodyfont % ook style etc + {\ifx\fontclass\globalfontclass + \ifx\fontstyle\globalfontstyle + \ifx\normalizedbodyfontsize\normalizedglobalbodyfontsize + \partialrestoreglobalbodyfont + \else + \fullrestoreglobalbodyfont + \fi + \else + \fullrestoreglobalbodyfont + \fi + \else + \fullrestoreglobalbodyfont + \fi} + +% in case of troubles: \let\restorebodyfont\fullrestoreglobalbodyfont + +%D This macro has to be called when entering the pagebody +%D handling routine as well as the footnote insert routine. +%D Users can access this feature |<|for instance when one wants +%D to typeset tables and alike in the main bodyfont and style +%D while the running text is temporary set to a smaller one|>| +%D by saying \type{\switchtobodyfont[global]}. + +%D \macros +%D {rasterfont} +%D +%D There are (at the moment) two situations in which we want to +%D have fast access to a particular font. When we are using +%D \TEX\ to typeset rasters, we use small {\rasterfont.}'s +%D (a rather small period indeed), the same as \PICTEX\ uses +%D for drawing purposes. + +\definefont [rasterfont] [Serif at 5pt] + +%D \macros +%D {infofont} +%D +%D The second situation occurs when we enable the info mode, +%D and put all kind of status information in the margin. We +%D don't want huge switches to the main bodyfont and style, so +%D here too we use a direct method. + +% old mechanism +% +% \def\infofont{\getvalue{\!!sixpoint\c!tt\c!tf}\the\everybodyfont} + +\let\infofont\relax % satisfy dep checker + +\definefont [infofont] [Mono at 6pt] % todo \the\everybodyfont + +%D \macros +%D {definealternativestyle} +%D +%D In the main modules we are going to implement lots of +%D parameterized commands and one of these parameters will +%D concern the font to use. To suit consistent use of fonts we +%D here implement a mechanism for defining the keywords that +%D present a particular style or alternative. +%D +%D \starttyping +%D \definealternativestyle [keywords] [\style] [\nostyle] +%D \stoptyping +%D +%D The first command is used in the normal textflow, while the +%D second command takes care of headings and alike. Consider +%D the next two definitions: +%D +%D \starttyping +%D \definealternativestyle [bold] [\bf] [] +%D \definealternativestyle [cap] [\cap] [\cap] +%D \stoptyping +%D +%D A change \type{\bf} in a heading which is to be set in +%D \type{\tfd} does not look that well, so therefore we leave +%D the second argument of \type{\definealternativestyle} empty. +%D When we capatalize characters using the pseudo small cap +%D command \type{\cap}, we want this to take effect in both +%D text and headings, which is accomplished by assigning both +%D arguments. + +\def\dodefinealternativestyle[#1][#2][#3]% + {\def\docommand##1% + {\doifundefined{##1}{\setvalue{##1}{\groupedcommand{#2}{}}}% + \setvalue{\@letter@ ##1}{#2}% + \setvalue{\@noletter@##1}{#3}}% + \processcommalist[#1]\docommand} + +\def\definealternativestyle + {\dotripleempty\dodefinealternativestyle} + +\def\definestyle{\definealternativestyle} + +%D Maybe too geneneric, but probably ok is the following. (Maybe one +%D day we will use a dedicated grouped command for styles.) + +\appendtoks + \let\groupedcommand\thirdofthreearguments +\to \simplifiedcommands + +%D This command also defines the keyword as command. This means +%D that the example definition of \type{bold} we gave before, +%D results in a command \type{\bold} which can be used as: +%D +%D \startbuffer +%D He's a \bold{bold} man with a {\bold head}. +%D \stopbuffer +%D +%D \typebuffer +%D +%D or +%D +%D \startvoorbeeld +%D \definealternativestyle[bold][\bf][]\getbuffer +%D \stopvoorbeeld +%D +%D Such definitions are of course unwanted for \type{\cap} +%D because this would result in an endless recursive call. +%D Therefore we check on the existance of both the command and +%D the substitution. The latter is needed because for instance +%D \type{\type} is an entirely diferent command. That command +%D handles verbatim, while the style command would just switch +%D to teletype font. This is just an example of a tricky +%D naming coincidence. + +%D \macros +%D {doconvertfont,noconvertfont, +%D dontconvertfont,redoconvertfont} +%D +%D After having defined such keywords, we can call for them by +%D using +%D +%D \starttyping +%D \doconvertfont{keyword}{text} +%D \stoptyping +%D +%D We deliberately pass an argument. This enables us to +%D assign converters that handle one agrument, like +%D \type{\cap}. +%D +%D By default the first specification is used to set the style, +%D exept when we say \type{\dontconvertfont}, after which the +%D second specification is used. We can also directly call for +%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}} + +%D Extras: + +\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 +%D overhead. + +%D \macros +%D {em,emphasistypeface,emphasisboldface} +%D +%D The next macro started as a copy of Donald Arseneau's +%D \type{\em} (\TUGNEWS\ Vol.~3, no.~1, 1994). His +%D implementation was a bit more sophisticated version of the +%D standard \LATEX\ one. We furter enhanced the macro, so now +%D it also adapts itself to boldface mode. Because we favor +%D {\sl slanted} type over {\it italic}, we made the emphasis +%D adaptable, for instance: +%D +%D \starttyping +%D \def\emphasistypeface {\it} +%D \def\emphasisboldface {\bi} +%D \stoptyping +%D +%D But we prefer: + +\def\emphasistypeface {\sl} +\def\emphasisboldface {\bs} + +%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% + {\doifelsevalue{\??ft\fontclass\normalizedbodyfontsize\c!em}\v!slanted + {#1}% + {\doifelsevalue{\??ft\fontclass\normalizedbodyfontsize\c!em}\v!italic + {#2}% + {\doifelsevaluenothing{\??ft\fontclass\normalizedbodyfontsize\c!em} + {\doifelsevalue{\??ft\normalizedbodyfontsize\c!em}\v!slanted + {#1}% + {\doifelsevalue{\??ft\normalizedbodyfontsize\c!em}\v!italic + {#2}% + {\getvalue{\??ft\normalizedbodyfontsize\c!em}}}} + {\getvalue{\??ft\fontclass\normalizedbodyfontsize\c!em}}}}} + +\def\emphasistypeface{\doemphasistypeface\sl\it} +\def\emphasisboldface{\doemphasistypeface\bs\bi} + +%D To be set with the default body font environment: \type +%D {em} being \type {slanted} or \type {italic}. + +\newconditional\emneeded + +\newtoks\everyemphasized + +\unexpanded\def\em + {\relax + \ifdim\slantperpoint>\zeropoint + \settrue\emneeded + \else + \setfalse\emneeded + \fi + \setemphasisboldface % new + \ifx\fontalternative\c!it % \ifnum\fam=\itfam + \def\emphasistypeface{\it}\tf + \else\ifx\fontalternative\c!sl % \ifnum\fam=\slfam + \def\emphasistypeface{\sl}\tf + \else\ifx\fontalternative\c!bf % \ifnum\fam=\bffam + \emphasisboldface + \else\ifx\fontalternative\c!bs % \ifnum\fam=\bsfam + \def\emphasisboldface{\bs}\bf + \else\ifx\fontalternative\c!bi % \ifnum\fam=\bifam + \def\emphasisboldface{\bi}\bf + \else + \emphasistypeface + \fi\fi\fi\fi\fi + \the\everyemphasized + \ifconditional\emneeded\relax + \else + \expandafter\aftergroup + \fi + \emphasiscorrection} + +% compare ... +% +% \appendtoks \red \to \everyemphasized +% \setupbodyfontenvironment [default] [em={\italic\color[red]}] + +%D The next feature was not present in previous versions. It +%D takes care of \type {\em \bf ...} sitiations. + +\def\setemphasisboldface + {\let\normalbf\bf + \let\setemphasisboldface\relax + \unexpanded\def\bf + {%\relax + \let\bf\relax % new + \ifx\fontalternative\c!it % \ifnum\fam=\itfam + \bi + \else\ifx\fontalternative\c!sl % \ifnum\fam=\slfam + \bs + \else + \normalbf + \fi\fi + \let\bf\normalbf}} + +%D Donald's (adapted) macros take the next character into +%D account when placing italic correction. As a bonus we also +%D look for something that looks like a dash, in which case we +%D don't correct. + +\let\italiccorrection=\/ + +\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\doemphasiscorrection + {\futurelet\next\dodoemphasiscorrection} + +\def\dodoemphasiscorrection + {\setbox\scratchbox\hbox{\next}% + \ifdim\ht\scratchbox=\zeropoint % probably a space + \expandafter\dododoemphasiscorrection + \else\ifdim\ht\scratchbox<.3ex + \expandafter\expandafter\expandafter\endgroup + \else + \expandafter\expandafter\expandafter\dododoemphasiscorrection + \fi\fi} + +\def\dododoemphasiscorrection + {\scratchskip\lastskip + \ifdim\scratchskip=\zeropoint\relax % == \ifzeropt\scratchskip + \italiccorrection\relax + \else + \unskip\italiccorrection\hskip\scratchskip + \fi + \endgroup} + +%D We end with some examples which show the behavior when +%D some punctuation is met. We also show how the mechanism +%D adapts itself to bold, italic and slanted typing. +%D +%D \startbuffer +%D test {test}test \par +%D test {\sl test}test \par +%D test {\em test}test \par +%D test {\em test}--test \par +%D +%D test {test}, test \par +%D test {\em test}, test \par +%D +%D test {\em test {\em test {\em test} test} test} test \par +%D test {\bf test {\em test {\em test} test} test} test \par +%D test {\sl test {\em test {\em test} test} test} test \par +%D test {\it test {\em test {\em test} test} test} test \par +%D \stopbuffer +%D +%D \typebuffer +%D +%D We get: +%D +%D \startvoorbeeld +%D \startpacked +%D \getbuffer +%D \stoppacked +%D \stopvoorbeeld + +%D \macros +%D {emphbf,emphit,emphsl,emphtf} +%D +%D The next emphasis alternatives are for \THANH. They adapt +%D their style as good as possible. + +\def\emphbf{\groupedcommand{\bf\def\emphit{\bi}\def\emphsl{\bs}}{}} +\def\emphit{\groupedcommand{\it\def\emphbf{\bi}\def\emphsl{\sl}}{}} +\def\emphsl{\groupedcommand{\sl\def\emphbf{\bs}\def\emphit{\it}}{}} +\def\emphtf{\groupedcommand{\tf\def\emphbf{\bf}\def\emphit{\it}\def\emphsl{\sl}}{}} + +%D \startbuffer +%D TEXT {\emphbf text \emphit text \emphtf text \emphsl text} TEXT +%D TEXT \emphbf{text \emphit{text} \emphtf{text} \emphsl{text}} TEXT +%D \stopbuffer +%D +%D \typebuffer +%D \startlines +%D \getbuffer +%D \stoplines + +%D \macros +%D {setfont} +%D +%D Every now and then we want to define a font directly, for +%D instance when we typeset title pages. The next macro saves +%D some typing: + +\def\setfont% geen \dosetfont mogelijk + {\def\next{\nextfont\setupinterlinespace}% + \afterassignment\next\font\nextfont=} + +%D One can call this macro as: +%D +%D \starttyping +%D \setfont cmr10 at 60pt +%D \stoptyping +%D +%D After which the font is active and the baselines and +%D struts are set. + +%D \macros +%D {showbodyfont} +%D +%D One can call for a rather simple overview of a bodyfont and the +%D relations between its alternative fonts. +%D +%D \showsetup{showbodyfont} +%D +%D The current bodyfont (here we omitted the argument) looks like: +%D +%D \showbodyfont +%D +%D The implementation is rather straightforward in using +%D \type{\halign}. + +\fetchruntimecommand \showbodyfont {\f!fontprefix\s!run.mkii} + +%D \macros +%D {showfontstrip, testminimalbaseline, showminimalbaseline} +%D +%D The next command can come in handy when combining +%D different fonts into a collection (typeface) and +%D determining optimal baseline distances. +%D +%D \showfontstrip \blank \showminimalbaseline + +\fetchruntimecommand \showfontstrip {\f!fontprefix\s!run.mkii} +\fetchruntimecommand \testminimalbaseline {\f!fontprefix\s!run.mkii} +\fetchruntimecommand \showminimalbaseline {\f!fontprefix\s!run.mkii} + +%D \macros +%D {showkerning} +%D +%D A goody is: +%D +%D \showkerning{Can you guess what kerning is?} + +\fetchruntimecommand \showkerning {\f!fontprefix\s!run.mkii} + +%D \macros +%D {showbodyfontenvironment} +%D +%D The current bodyfontenvironment is: +%D +%D \showbodyfontenvironment +%D +%D This overview is generated using: +%D +%D \showsetup{showbodyfontenvironment} + +\fetchruntimecommand \showbodyfontenvironment {\f!fontprefix\s!run.mkii} + +%D \macros +%D {showfont,showfontstyle,showligatures} +%D +%D The following command generates a fontmap: +%D +%D \startbuffer +%D \showfont[SansBold at 12pt] +%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 + +\fetchruntimecommand \showfont {\f!fontprefix\s!run.mkii} +\fetchruntimecommand \showfontstyle {\f!fontprefix\s!run.mkii} +\fetchruntimecommand \showligature {\f!fontprefix\s!run.mkii} +\fetchruntimecommand \showligatures {\f!fontprefix\s!run.mkii} +\fetchruntimecommand \showcharratio {\f!fontprefix\s!run.mkii} + +%D \macros +%D {getglyph, symbolicfont} +%D +%D Individual glyphs can be accessed by using +%D +%D \starttyping +%D \getglyph{fontname}{character} +%D \stoptyping +%D +%D This macro is used in for instance the symbol modules and +%D as one can see, it does obey the small and even smaller +%D sizes. The \type {\symbolicfont} macro can be used to +%D switch to a font named \type {fontname} (see \type +%D {cont-log} and \type {symb-eur} for examples of symbolic +%D definitions. + +\def\fontstringA + {\ifx\fontstyle\c!rm \s!Serif \else + \ifx\fontstyle\c!ss \s!Sans \else + \ifx\fontstyle\c!tt \s!Mono \else + \s!Serif \fi\fi\fi} + +\def\fontstringB + {\ifx\fontstyle\c!rm \s!Regular \else + \ifx\fontstyle\c!ss \s!Support \else + \ifx\fontstyle\c!tt \s!Type \else + \s!Serif \fi\fi\fi} + +\def\fontstringC + {\ifx\fontalternative\c!bf \s!Bold \else + \ifx\fontalternative\c!sl \s!Slanted \else + \ifx\fontalternative\c!it \s!Italic \else + \ifx\fontalternative\c!bs \s!BoldSlanted \else + \ifx\fontalternative\c!bi \s!BoldItalic \fi\fi\fi\fi\fi} + +\def\fontstringD % default fontstyle + {\expandafter\ifx\csname\??tf\fontclass\s!default\endcsname\c!rm \s!Serif \else + \expandafter\ifx\csname\??tf\fontclass\s!default\endcsname\c!ss \s!Sans \else + \expandafter\ifx\csname\??tf\fontclass\s!default\endcsname\c!tt \s!Mono \else + \s!Serif \fi\fi\fi} + +% potential generalization: + +% \letvalue{\??ff:t:\c!rm}\s!Serif +% \letvalue{\??ff:t:\c!ss}\s!Sans +% \letvalue{\??ff:t:\c!tt}\s!Mono +% +% \letvalue{\??ff:s:\c!bf}\s!Bold +% \letvalue{\??ff:s:\c!sl}\s!Slanted +% \letvalue{\??ff:s:\c!it}\s!Italic +% \letvalue{\??ff:s:\c!bs}\s!BoldSlanted +% \letvalue{\??ff:s:\c!bi}\s!BoldItalic +% +% \letvalue{\??ff:a:\c!rm}\s!Regular +% \letvalue{\??ff:a:\c!ss}\s!Support +% \letvalue{\??ff:a:\c!tt}\s!Type +% +% \def\fontstringA{\executeifdefined{\??ff:t:\fontstyle}\s!Serif} +% \def\fontstringB{\executeifdefined{\??ff:a:\fontstyle}\s!Serif} +% \def\fontstringC{\executeifdefined{\??ff:s:\fontstyle}\empty} +% \def\fontstringD{\executeifdefined{\??ff:t:\csname\??tf\fontclass\s!default\endcsname}\s!Serif} + +\def\glyphfontfile#1% + {#1% + \ifcsname\??ff#1\fontstringA\fontstringC\endcsname + \fontstringA\fontstringC + \else\ifcsname\??ff#1\fontstringB\fontstringC\endcsname + \fontstringB\fontstringC + \else\ifcsname\??ff#1\fontstringA\endcsname + \fontstringA + \else\ifcsname\??ff#1\fontstringB\endcsname + \fontstringB + \else\ifcsname\??ff#1\fontstringC\endcsname + \fontstringC + \fi\fi\fi\fi\fi} + +%D The next macro can be used to make decisions based on the shape: + +\def\doifitalicelse#1#2% + {\ifx\fontalternative\c!sl#1\else + \ifx\fontalternative\c!it#1\else + \ifx\fontalternative\c!bs#1\else + \ifx\fontalternative\c!bi#1\else#2\fi\fi\fi\fi} + +%D For an example of usage of the following command, +%D see \type {cont-log.tex}. +%D +%D \starttyping +%D \def\symbolicfont#1% +%D {\definedfont[\glyphfontfile{#1} sa *]} +%D \stoptyping +%D +%D Since we know what scaling it to be applied, we can +%D implement a much faster alternative: + +\let\thedefinedfont\relax + +% \def\symbolicscaledfont#1#2% +% {\scaledfont\fontbody +% \scaledfont#1\scaledfont +% \font\thedefinedfont\truefontname{\glyphfontfile{#2}} at +% \currentfontbodyscale\scaledfont +% \thedefinedfont} +% +% \unexpanded\def\symbolicfont +% {\symbolicscaledfont\plusone} +% +% even more control (needed for mthsqrt etc) + +\def\symbolicsizedfont#1#2#3% + {\scaledfont#1% + \scaledfont#2\scaledfont + \font\thedefinedfont\truefontname{\glyphfontfile{#3}} at + \currentfontbodyscale\scaledfont + \thedefinedfont} + +\def\symbolicscaledfont + {\symbolicsizedfont\fontbody} + +\unexpanded\def\symbolicfont + {\symbolicsizedfont\fontbody\plusone} + +\unexpanded\def\getglyph#1#2% slow, faster, much faster + %{{\definefont[\s!dummy][\glyphfontfile{#1} sa \currentfontscale]\dummy#2}} + %{{\definefont[\s!dummy][\glyphfontfile{#1} sa *]\dummy#2}} + %{{\symbolicfont{#1}#2}} + {{\symbolicfont{#1}\doifnumberelse{#2}\char\donothing#2}} + +\unexpanded\def\getscaledglyph#1#2#3% + {{\symbolicscaledfont{#1}{#2}\doifnumberelse{#3}\char\donothing#3}} + +\unexpanded\def\getrawglyph#1#2% for simple symbols + {{\scaledfont\fontbody + \font\thedefinedfont=#1 at \currentfontbodyscale\scaledfont + \thedefinedfont\doifnumberelse{#2}\char\donothing#2}} + +%D The last implementation of \type {\getglyph} permits +%D definitions like: +%D +%D \starttyping +%D \definefontsynonym [EuroSans] [eurose] +%D \definefontsynonym [EuroSansBold] [euroseb] +%D \definefontsynonym [EuroSansItalic] [eurosei] +%D \definefontsynonym [EuroSansSlanted] [eurosei] +%D \definefontsynonym [EuroSansBoldItalic] [eurosebi] +%D \definefontsynonym [EuroSansBoldSlanted] [eurosebi] +%D +%D \definesymbol [euro] [\getglyph{Euro}{\char160}] +%D +%D \def\euro{\symbol[euro]} +%D \stoptyping +%D +%D These definitions guarantee that the next calls work okay: +%D +%D \starttyping +%D \ss \tf\euro \bf\euro \sla\euro \itd\euro \bs\euro \bic\euro +%D \stoptyping +%D +%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{\mathparentwd}. 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\mathparentwd\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 +%D We are going to redefine \type{\ss} but for those wo still +%D want to have access to the german \SS, we save it's value in +%D \type{\SS}. Ok, I should have used \type{\sf} instead of +%D \type{\ss} in the first place. + +\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 +%D \starttyping +%D \definebodyfont [12pt] [rm] [tf=Times-Roman at 12pt] +%D \stoptyping +%D +%D combined with for instance: +%D +%D \starttyping +%D \definefontsynonym [Times-Roman] [tir] +%D \stoptyping + +%D Now we're up to some definitions. + +\definebodyfontenvironment + [\s!default] + [ \s!text=1.0, + \s!script=0.7, + \s!scriptscript=0.5, + \c!a=1.200, + \c!b=1.440, + \c!c=1.728, + \c!d=2.074, + *=\currentfontscale, % wildcard + \c!x=0.8, + \c!xx=0.6, + \c!big=1.2, + \c!small=0.8, + \c!interlinespace=, + \c!em=\v!slanted] + +\definebodyfontenvironment + [20.7pt] + [ \s!text=20.7pt, + \s!script=\!!fourteenpointfour, + \s!scriptscript=\!!twelvepoint, + \c!x=17.3pt, + \c!xx=\!!fourteenpointfour, + \c!big=20.7pt, % !!!! + \c!small=17.3pt] + +\definebodyfontenvironment + [17.3pt] + [ \s!text=17.3pt, + \s!script=\!!twelvepoint, + \s!scriptscript=\!!tenpoint, + \c!x=\!!fourteenpointfour, + \c!xx=\!!twelvepoint, + \c!big=20.7pt, + \c!small=\!!fourteenpointfour] + +\definebodyfontenvironment + [\!!fourteenpointfour] + [ \s!text=\!!fourteenpointfour, + \s!script=\!!elevenpoint, + \s!scriptscript=\!!ninepoint, + \c!x=\!!twelvepoint, + \c!xx=\!!tenpoint, + \c!big=17.3pt, + \c!small=\!!twelvepoint] + +\definebodyfontenvironment + [\!!twelvepoint] + [ \s!text=\!!twelvepoint, + \s!script=\!!ninepoint, + \s!scriptscript=\!!sevenpoint, + \c!x=\!!tenpoint, + \c!xx=\!!eightpoint, + \c!big=\!!fourteenpointfour, + \c!small=\!!tenpoint] + +\definebodyfontenvironment + [\!!elevenpoint] + [ \s!text=\!!elevenpoint, + \s!script=\!!eightpoint, + \s!scriptscript=\!!sixpoint, + \c!x=\!!ninepoint, + \c!xx=\!!sevenpoint, + \c!big=\!!twelvepoint, + \c!small=\!!ninepoint] + +\definebodyfontenvironment + [\!!tenpoint] + [ \s!text=\!!tenpoint, + \s!script=\!!sevenpoint, + \s!scriptscript=\!!fivepoint, + \c!x=\!!eightpoint, + \c!xx=\!!sixpoint, + \c!big=\!!twelvepoint, + \c!small=\!!eightpoint] + +\definebodyfontenvironment + [\!!ninepoint] + [ \s!text=\!!ninepoint, + \s!script=\!!sevenpoint, + \s!scriptscript=\!!fivepoint, + \c!x=\!!sevenpoint, + \c!xx=\!!fivepoint, + \c!big=\!!elevenpoint, + \c!small=\!!sevenpoint] + +\definebodyfontenvironment + [\!!eightpoint] + [ \s!text=\!!eightpoint, + \s!script=\!!sixpoint, + \s!scriptscript=\!!fivepoint, + \c!x=\!!sixpoint, + \c!xx=\!!fivepoint, + \c!big=\!!tenpoint, + \c!small=\!!sixpoint] + +\definebodyfontenvironment + [\!!sevenpoint] + [ \s!text=\!!sevenpoint, + \s!script=\!!sixpoint, + \s!scriptscript=\!!fivepoint, + \c!x=\!!sixpoint, + \c!xx=\!!fivepoint, + \c!big=\!!ninepoint, + \c!small=\!!fivepoint] + +\definebodyfontenvironment + [\!!sixpoint] + [ \s!text=\!!sixpoint, + \s!script=\!!fivepoint, + \s!scriptscript=\!!fivepoint, + \c!x=\!!fivepoint, + \c!xx=\!!fivepoint, + \c!big=\!!eightpoint, + \c!small=\!!fivepoint] + +\definebodyfontenvironment + [\!!fivepoint] + [ \s!text=\!!fivepoint, + \s!script=\!!fivepoint, + \s!scriptscript=\!!fivepoint, + \c!x=\!!fivepoint, + \c!xx=\!!fivepoint, + \c!big=\!!sevenpoint, + \c!small=\!!fivepoint] + +\definebodyfontenvironment + [\!!fourpoint] + [ \s!text=\!!fourpoint, + \s!script=\!!fourpoint, + \s!scriptscript=\!!fourpoint, + \c!x=\!!fourpoint, + \c!xx=\!!fourpoint, + \c!big=\!!sixpoint, + \c!small=\!!fourpoint] + +\definebodyfontswitch [fourteenpointfour] [\!!fourteenpointfour] +\definebodyfontswitch [twelvepoint] [\!!twelvepoint] +\definebodyfontswitch [elevenpoint] [\!!elevenpoint] +\definebodyfontswitch [tenpoint] [\!!tenpoint] +\definebodyfontswitch [ninepoint] [\!!ninepoint] +\definebodyfontswitch [eightpoint] [\!!eightpoint] +\definebodyfontswitch [sevenpoint] [\!!sevenpoint] +\definebodyfontswitch [sixpoint] [\!!sixpoint] +\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] + +%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] + +\definefontsize[\c!a] \definefontsize[\c!b] +\definefontsize[\c!c] \definefontsize[\c!d] + +\definealternativestyle [\v!mediaeval] [\os] [] +\definealternativestyle [\v!normal] [\tf] [] +\definealternativestyle [\v!bold] [\bf] [] +\definealternativestyle [\v!type] [\tt] [] +\definealternativestyle [\v!mono] [\tt] [] +\definealternativestyle [\v!slanted] [\sl] [] +\definealternativestyle [\v!italic] [\it] [] +\definealternativestyle [\v!boldslanted,\v!slantedbold] [\bs] [] +\definealternativestyle [\v!bolditalic,\v!italicbold] [\bi] [] +\definealternativestyle [\v!small,\v!smallnormal] [\tfx] [] +\definealternativestyle [\v!smallbold] [\bfx] [] +\definealternativestyle [\v!smalltype] [\ttx] [] +\definealternativestyle [\v!smallslanted] [\slx] [] +\definealternativestyle [\v!smallboldslanted,\v!smallslantedbold] [\bsx] [] +\definealternativestyle [\v!smallbolditalic,\v!smallitalicbold] [\bix] [] + +\definealternativestyle [\v!sans,\v!sansserif] [\ss] [] +\definealternativestyle [\v!sansbold] [\ss\bf] [] + +%D Slow but handy: + +\definealternativestyle [\v!smallbodyfont] [\setsmallbodyfont] [] +\definealternativestyle [\v!bigbodyfont] [\setbigbodyfont] [] + +%D We treat {\sc Small Caps} and \cap {Pseudo Caps} a bit +%D different. We also provide an \WORD {uppercase} style. + +\definealternativestyle [\v!cap,\v!capital] [\smallcapped] [\smallcapped] +\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 + \ifx\fontalternative\c!sl \s!Slanted \else + \ifx\fontalternative\c!it \s!Italic \else + \ifx\fontalternative\c!bs \s!BoldSlanted \else + \ifx\fontalternative\c!bi \s!BoldItalic \else + \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 +%D A slightly adapted version of Adam Lindsays variant patches: +%D +%D \starttyping +%D \usetypescriptfile[type-psc] \loadmapfile[texnansi-public-fpl] +%D \usetypescript[palatino][texnansi] \setupbodyfont[palatino] +%D +%D \definefontvariant [Serif][osf] [OsF] +%D +%D \startlines +%D {\sc abcdefgHIJKlmnop} +%D 123{\Var[osf]456}789 +%D {\Var[osf] 123{\Var[reset]456}789} +%D {\it 123{\Var[osf]456}789 +%D {\Var[osf]123{\Var[reset]456}789}} +%D {\tfb\bf 123{\Var[osf]456}789 +%D {\Var[osf] 123{\Var[reset]456}789}} +%D {\sc 123{\Var[osf]456}789 +%D {\Var[osf] 123{\Var[reset]456}789}} +%D \stoplines +%D \stoptyping + +\def\definefontvariant + {\dotripleargument\dodefinefontvariant} + +\def\dodefinefontvariant[#1][#2][#3]% + {\setvalue{\??fv#1#2}{#3}} + +\def\fontvariant#1#2{\executeifdefined{\??fv#1#2}\empty} + +\def\dosetscaledfont + {\checkrelativefontsize\fontstyle + \scaledfont\currentfontscale\bodyfontsize + \scaledfont\relativefontsize\scaledfont} + +\unexpanded\def\variant[#1]% slow + {\dosetscaledfont + \expanded{\definedfont + [\truefontname{\fontstringA\fontstylesuffix\fontvariant\fontstringA{#1}} + at \scaledfont]}% + \ignoreimplicitspaces} + +\ifx\Var\undefined \let\Var\variant \fi + +%D By default we load the Computer Modern Roman fonts (but +%D not yet at this moment) and activate the 12pt roman +%D bodyfont. Sans serif and teletype are also available and +%D can be called for by \type{\ss} and \type{\tt}. + +% \setupbodyfont [unk, rm] + +%D Also needed is: + +\definefont[tinyfont][Mono at 1ex] + +%D \macros +%D {doiffontpresentelse} +%D +%D Some unused left||overs: +%D +%D \starttyping +%D \def\doiffontpresentelse#1#2#3% +%D {\bgroup +%D \batchmode\font\dummy=\truefontname{#1}\errorstopmode +%D \edef\lastfontname{\fontname\dummy}% +%D \ifx\lastfontname\nullfontname\egroup#3\else\egroup#2\fi} +%D +%D \def\abortiffontnotfound#1% +%D {\doiffontpresentelse{#1}{}{\showmessage\m!fonts{10}{\truefontname{#1}}\endinput}} +%D \stoptyping +%D +%D We now provide (slow, but sometimes handy): +%D +%D \starttyping +%D \doiffontpresentelse{texnansi-lmr10}{YES}{NO} +%D \doiffontpresentelse{adam-lindsay-modern-serif}{YES}{NO} +%D \stoptyping + +\def\doiffontpresentelse#1% + {\bgroup + \scratchcounter\interactionmode + \batchmode + \font\dummy=\truefontname{#1}\relax + \interactionmode\scratchcounter + \edef\lastfontname{\fontname\dummy}% + \ifx\lastfontname\nullfontname + \egroup\expandafter\secondoftwoarguments + \else + \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 new file mode 100644 index 000000000..c7d515cca --- /dev/null +++ b/tex/context/base/font-ini.mkiv @@ -0,0 +1,3896 @@ +%D \module +%D [ file=font-ini, +%D version=1998.09.11, % (second) +%D version=2001.02.20, % (third) +%D title=\CONTEXT\ Font 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. + +% runtime commands will move to modules + +% simplification ... we no longer deal with specific mmtfa specifications + +% todo: always fontclass, then less testing + +% \definefontfeature[smallcaps][smcp=yes,script=latn] +% \definefontfeature[smallcaps][SmallCapitals=yes,script=latn] +% \definefontfeature[smallcaps][Small Capitals=yes,script=latn] +% \definefontfeature[smallcaps][small capitals=yes,script=latn] +% \definefontfeature[smallcaps][smallcapitals=yes,script=latn] +% +% \definedfont[cambria*smallcaps] test + +% \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-enh}{1.001} +\registerctxluafile{font-afm}{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-gds}{1.001} +\registerctxluafile{font-ext}{1.001} +\registerctxluafile{font-pat}{1.001} +\registerctxluafile{font-chk}{1.001} +\registerctxluafile{font-agl}{1.001} + +\unprotect + +% \def\fontrange#1% +% {\dofontrange{#1 =\bodyfontsize}} +% +% \def\dofontrange#1% +% {\dodofontrange#1 \relax}% \fontstringA +% +% \def\dodofontrange#1 #2 % +% {\ifdim\bodyfontsize#2% +% #1\expandafter\gobbleuntilrelax +% \else +% \expandafter\dodofontrange +% \fi} +% +% \definefont +% [crap] +% [\fontrange +% {Regular <10pt +% RegularBold <12pt +% RegularSlanted <15pt +% Regular} sa 1] +% +% may be better: +% +% \definefontrange +% [crap] +% [Regular <10pt +% RegularBold <12pt +% RegularSlanted <15pt] +% [Regular sa 1] +% +% +% \dostepwiserecurse{2}{15}{1} +% {{\switchtobodyfont[\recurselevel pt]\crap test}\endgraf} + +% adapted, else wrong interlinespace + +\def\setfontparameters + {\synchronizefontsfalse + \the\everybodyfont + \synchronizefontstrue} + +% handy + +\newcounter\pushedfont + +\def\savefont + {\edef\savedfont{\the\font}% + \pushmacro\savedfont} + +\def\restorefont + {\popmacro\savedfont + \savedfont} + +\def\pushcurrentfont + {\edef\popcurrentfont + {\noexpand\def\noexpand\fontbody{\fontbody}% + \noexpand\def\noexpand\fontstyle{\fontstyle}% + \noexpand\dosetcurrentfontalternative{\fontalternative}% + \noexpand\dosetcurrentfontsize{\fontsize}% + \noexpand\synchronizefont}} + +% \definetypeface[one][rm][serif][computer-roman][default] +% \definetypeface[two][rm][serif][computer-roman][default][rscale=.9] +% +% {\one \bf test \two test} +% {\one \bf test \pushcurrentfont \two \popcurrentfont test} + +%D \macros +%D {definedfont,startfont,doiffontcharelse} +%D +%D A couple of relatively new macros: + +% \newtoks \everydefinedfont % not ot be confused with \everydefinefont + +\def\dodefinedfont[#1]% + {\iffirstargument\definefont[thedefinedfont][#1]\fi % we can speed this one up + \csname thedefinedfont\endcsname + \the\everydefinedfont} + +\unexpanded\def\definedfont + {\dosingleempty\dodefinedfont} + +\unexpanded\def\startfont + {\bgroup\definedfont} + +\unexpanded\def\stopfont + {\egroup} + +\def\doiffontcharelse#1#2% + {\bgroup + \definedfont[#1]% + \iffontchar\font#2\relax + \egroup\expandafter\firstoftwoarguments + \else + \egroup\expandafter\secondoftwoarguments + \fi} + +%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} +%D +%D Fonts are defined in separate files. When we define a font, +%D we distinguish between several styles. In most cases we will +%D use: +%D +%D \startlinecorrection +%D \starttable[|l||] +%D \HL +%D \NC roman regular serif \NC \type{\rm} \NC\FR +%D \NC sansserif sans support \NC \type{\ss} \NC\MR +%D \NC type teletype mono \NC \type{\tt} \NC\LR +%D \HL +%D \stoptable +%D \stoplinecorrection +%D +%D The number of styles is not limited to these three. When +%D using Lucida Bright we can for instance also define: +%D +%D \startlinecorrection +%D \starttable[|l||] +%D \HL +%D \NC handwritten \NC \type{\hw} \NC\FR +%D \NC calligraphic \NC \type{\cg} \NC\LR +%D \HL +%D \stoptable +%D \stoplinecorrection +%D +%D Within such a font set (\type{cmr}) and style (\type{\rm}) +%D we can define a number of text font alternatives: +%D +%D \startlinecorrection +%D \starttable[|l||] +%D \HL +%D \NC typeface \NC \type{\tf} \NC\FR +%D \NC boldface \NC \type{\bf} \NC\MR +%D \NC slanted \NC \type{\sl} \NC\MR +%D \NC italic \NC \type{\it} \NC\MR +%D \NC boldslanted \NC \type{\bs} \NC\MR +%D \NC bolditalic \NC \type{\bi} \NC\MR +%D \NC smallcaps \NC \type{\sc} \NC\LR +%D \HL +%D \stoptable +%D \stoplinecorrection +%D +%D Internally fonts are stored as combination of size, style +%D and alternative, e.g. \type{12pt}+\type{\ss}+\type{\bf}. +%D Users are not confronted with sizes, but use the style or +%D style+alternative to activate them. +%D +%D During the definition of a bodyfont one can also declare the +%D available larger alternatives: +%D +%D \starttyping +%D \tf \tfa \tfb \tfc ... +%D \bf \bfa \bfb \bfc ... +%D \sl \sla \slb \slc ... +%D \stoptyping +%D +%D The smaller ones are automatically supplied and derived from +%D the the bodyfont environment. +%D +%D \starttyping +%D \tfx \tfxx +%D \bfx \bfxx +%D \slx \slxx +%D \stoptyping +%D +%D There are only two smaller alternatives per style. The +%D larger alternatives on the other hand have no limitations. +%D +%D These larger alternatives are mostly used in chapter and +%D section titles or on title pages. When one switches to a +%D larger alternative, the bold an other ones automatically +%D adapt themselves: +%D +%D \startbuffer +%D \tfd Hi \bf there\sl, here \tfb I \bf am +%D \stopbuffer +%D +%S \startnarrower +%D \typebuffer +%S \stopnarrower +%D +%D therefore becomes: +%D +%D \startvoorbeeld +%D \getbuffer +%D \stopvoorbeeld +%D +%D Maybe this mechanism isn't always as logic, but as said +%D before, we tried to make it as intuitive as possible. +%D +%D So a specific kind of glyph can be characterized by: +%D +%D \startnarrower +%D family (cmr) + bodyfont (12pt) + style (rm) + alternative (bf) + size (a) +%D \stopnarrower +%D +%D The last component (the size) is optional. +%D +%D We introduced \type{\tf} as command to call for the current +%D normally sized typeface. This commands results in roman, +%D sans serif, teletype or whatever style is in charge. Such +%D rather massive switches of style sometimes take more +%D processing time than comfortable. Of course there is a +%D workaround for this: we can call fonts directly by means of +%D commands like: +%D +%D \starttyping +%D \rmtf \sssl \tttf \rmbsa +%D \stoptyping +%D +%D One should realize that this fast calls have limitations, +%D they lack for instance automatic super- and subscript +%D support. +%D +%D This leaves us two more commands: \type{\tx} and +%D \type{\txx}. These activate a smaller and even more smaller +%D font than the current one and adapt themselves to the +%D current alternative, so when \type{\bf} is active, +%D \type{\tx} gives a smaller boldface, which in turn can be +%D called directly by \type{\bfx}. +%D +%D These two smaller alternatives are specified by the bodyfont +%D environment and therefore not necessarily have similar sizes +%D as \type{\scriptsize} and \type{\scriptscriptsize}. The main +%D reason for this incompatibility (which can easily be undone) +%D lays in the fact that we often want a bit bigger characters +%D than in math mode. In \CONTEXT\ for instance the \type{\tx} +%D and \type{\txx} commands are used for surrogate +%D \cap{smallcaps} which support both nesting and alternatives, +%D like in {\bf\cap{a \cap{small} world}}, which was typeset by +%D +%D \starttyping +%D \bf\cap{a \cap{small} world} +%D \stoptyping +%D +%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 +%D \type {d} inside \type {x}. etc.). The following table +%D demonstrates this: +%D +%D \def\FontState{\setstrut\ruledhbox{\strut Hello}} +%D +%D \starttabulate[|||||] +%D \HL +%D \NC \rlap{\quad\bf grouped} \NC \NC \type {\tx} \NC \type {\txx} \NC \NR +%D \HL +%D \NC \type{\tfx} \NC \tfx \FontState \NC \tfx \tx \FontState \NC \tfx \txx \FontState \NC \NR +%D \NC \type{\tfxx} \NC \tfxx \FontState \NC \tfxx\tx \FontState \NC \tfxx\txx \FontState \NC \NR +%D \NC \type{\tf} \NC \tf \FontState \NC \tf \tx \FontState \NC \tf \txx \FontState \NC \NR +%D \NC \type{\tfa} \NC \tfa \FontState \NC \tfa \tx \FontState \NC \tfa \txx \FontState \NC \NR +%D \NC \type{\tfb} \NC \tfb \FontState \NC \tfb \tx \FontState \NC \tfb \txx \FontState \NC \NR +%D \NC \type{\tfc} \NC \tfc \FontState \NC \tfc \tx \FontState \NC \tfc \txx \FontState \NC \NR +%D \NC \type{\tfd} \NC \tfd \FontState \NC \tfd \tx \FontState \NC \tfd \txx \FontState \NC \NR +%D \NC \type{\tfx} \NC \tfx \FontState \NC \tfx \tx \FontState \NC \tfx \txx \FontState \NC \NR +%D \NC \type{\tfxx} \NC \tfxx \FontState \NC \tfxx\tx \FontState \NC \tfxx\txx \FontState \NC \NR +%D \HL +%D \stoptabulate +%D +%D \blank +%D +%D \starttabulate[|||||] +%D \HL +%D \NC \rlap{\quad\bf stacked} \NC \NC \type {\tx} \NC \type {\txx} \NC \NR +%D \HL +%D \NC \type{\tfx} +%D \NC \tfx \FontState +%D \NC \tfx \tx \FontState +%D \NC \tfx \txx \FontState +%D \NC \NR +%D \NC \type{\tfxx} +%D \NC \tfx\tfxx \FontState +%D \NC \tfx\tfxx \tx \FontState +%D \NC \tfx\tfxx \txx \FontState +%D \NC \NR +%D \NC \type{\tf} +%D \NC \tfx\tfxx\tf \FontState +%D \NC \tfx\tfxx\tf \tx \FontState +%D \NC \tfx\tfxx\tf \txx \FontState +%D \NC \NR +%D \NC \type{\tfa} +%D \NC \tfx\tfxx\tf\tfa \FontState +%D \NC \tfx\tfxx\tf\tfa \tx \FontState +%D \NC \tfx\tfxx\tf\tfa \txx \FontState +%D \NC \NR +%D \NC \type{\tfb} +%D \NC \tfx\tfxx\tf\tfa\tfb \FontState +%D \NC \tfx\tfxx\tf\tfa\tfb \tx \FontState +%D \NC \tfx\tfxx\tf\tfa\tfb \txx \FontState +%D \NC \NR +%D \NC \type{\tfc} +%D \NC \tfx\tfxx\tf\tfa\tfb\tfc \FontState +%D \NC \tfx\tfxx\tf\tfa\tfb\tfc \tx \FontState +%D \NC \tfx\tfxx\tf\tfa\tfb\tfc \txx \FontState +%D \NC \NR +%D \NC \type{\tfd} +%D \NC \tfx\tfxx\tf\tfa\tfb\tfd \FontState +%D \NC \tfx\tfxx\tf\tfa\tfb\tfd \tx \FontState +%D \NC \tfx\tfxx\tf\tfa\tfb\tfd \txx \FontState +%D \NC \NR +%D \NC \type{\tfx} +%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx \FontState +%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx \tx \FontState +%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx \txx \FontState +%D \NC \NR +%D \NC \type{\tfxx} +%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx\tfxx \FontState +%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx\tfxx \tx \FontState +%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx\tfxx \txx \FontState +%D \NC \NR +%D \HL +%D \stoptabulate +%D +%D Remark: math support has changed a bit. + +%D \macros +%D {uchar} +%D +%D This macro prepares \CONTEXT\ for \UNICODE\ support. By +%D defining it here, we have at least an safeguard for utility +%D file reading. + +\ifdefined\uchar\else \unexpanded\def\uchar#1#2{[#1,#2]} \fi + +%D We define some (very private) constants to improve speed, +%D memory usage and consistency. + +\def\@size@ {@f@si@} % bodyfont size prefix (12pt etc) +\def\@style@ {@f@st@} % full style prefix (roman etc) +\def\@shortstyle@ {@f@sh@} % short style prefix (rm etc) +\def\@letter@ {@f@le@} % first alternative typeface +\def\@noletter@ {@f@no@} % second alternative typeface +\def\@fontclass@ {@f@cl@} % fontclass + +%D \macros +%D {fontclass, defaultfontclass} +%D +%D The fontclass model was introduced a while after we implement +%D the basic font model and at that time we still defaulted to +%D no model at all. Nowadays we default to the \type {modern} +%D fontclass. + +\let\fontclass \empty +\let\defaultfontclass\empty + +%D \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 \mathstrategies + +\newif\ifsynchronizemathfonts \synchronizemathfontstrue + +\def\synchronizemath % math stuff in mmode + {\ifsynchronizemathfonts\the\mathstrategies\fi} + +\def\textonly{\synchronizemathfontsfalse} % document this + +%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. + +\chardef\mrfam\zerocount % math regular +\chardef\mbfam\plusone % math bold + +\unexpanded\def\mr{\ifmmode\fam\zerocount\else\setcurrentfontalternative\c!mr\fi} % \fam\csname\c!mr fam\endcsname +\unexpanded\def\mb{\ifmmode\fam\plusone \else\setcurrentfontalternative\c!mb\fi} % \fam\csname\c!mb fam\endcsname + +\def\mathtextsuffix {-text} +\def\mathscriptsuffix {-script} +\def\mathscriptscriptsuffix{-scriptscript} + +% \let\mathsizesuffix\empty + +\let\currentmathsize\empty + +\def\mathsizesuffix{\ifcase0\currentmathsize\or\mathtextsuffix\or\mathscriptsuffix\or\mathscriptscriptsuffix\fi} + +\def\dodosetmathfamily#1#2% + {\ifcsname\fontclass \fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \autofontsizefalse + \csname\fontclass \fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \else + \ifcsname\fontclass \fontbody\c!mm\fontfamily \currentmathsize\endcsname \autofontsizetrue + \csname\fontclass \fontbody\c!mm\fontfamily \currentmathsize\endcsname \else + \dodosetmathfamilyx#1#2% + \fi\fi + #1#2\font} + +\def\dodosetmathfamilyx#1#2% + {\ifcsname\defaultfontclass\fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \autofontsizefalse + \csname\defaultfontclass\fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \else + \ifcsname\defaultfontclass\fontbody\c!mm\fontfamily \currentmathsize\endcsname \autofontsizetrue + \csname\defaultfontclass\fontbody\c!mm\fontfamily \currentmathsize\endcsname \else + \dodosetmathfamilyxx#1#2% + \fi\fi} + +\def\dodosetmathfamilyxx#1#2% + {\ifcsname \fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \autofontsizefalse + \csname \fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \else + \ifcsname \fontbody\c!mm\fontfamily \currentmathsize\endcsname \autofontsizetrue + \csname \fontbody\c!mm\fontfamily \currentmathsize\endcsname \else + \nullfont \autofontsizetrue + \fi\fi} + +\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\empty + \let\fontbody\savedfontbody + \autofontsizefalse} + +\appendtoks + \dosetmathfamily\mrfam\c!mr +\to \mathstrategies + +% not official ! + +\chardef\boldmathmode\zerocount % might change ... maybe \mathfontsupport 1 (normal) 2 (bold too) + +\def\enableboldmath {\chardef\boldmathmode\plusone } % todo: \setupbodyfont[boldmath,...] +\def\disableboldmath{\chardef\boldmathmode\zerocount} + +\appendtoks + \ifcase\boldmathmode\or\dosetmathfamily\mbfam\c!mb\fi +\to \mathstrategies + +% \chardef\msfam\plustwo % math symbol +% +% \def\c!ms{ms} +% +% \unexpanded\def\ms{\ifmmode\fam\plustwo\else\setcurrentfontalternative\c!ms\fi} +% +% \chardef\symbolmathmode\zerocount +% +% \def\enablesymbolmath {\chardef\symbolmathmode\plusone } +% \def\disablesymbolmath{\chardef\symbolmathmode\zerocount} +% +% \appendtoks +% \ifcase\symbolmathmode\or\dosetmathfamily\msfam\c!ms\fi +% \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. + +\def\fontrelativesizelist{\s!text,\s!script,\s!scriptscript,\c!x,\c!xx,\c!big,\c!small} + +%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 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 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 +%D test for it ourselves. In doing so, we need an auxiliary +%D \DIMENSION. We cannot use \type{\scratchdimen} because font +%D loading can happen at any moment due to postponed loading. +%D We could instead have used dirty grouping tricks, but this +%D one works too. + +% \enableexperiments[fonts.autorscale] +% +% \starttypescript[mscore] +% \definetypeface [mscore] [rm] [serif] [mscoretimes] [default] +% \definetypeface [mscore] [ss] [sans] [mscorearial] [default] [rscale=auto] % 0.860] +% \definetypeface [mscore] [tt] [mono] [mscorecourier] [default] [rscale=auto] % 1.065] +% \definetypeface [mscore] [mm] [math] [times] [default] [rscale=auto] % 1.020] +% \stoptypescript +% +% \starttext +% \setupbodyfont[mscore,12pt] +% \startTEXpage +% test \ss test \tt test +% \stopTEXpage +% \stoptext + +\let\defaultrelativefontsize \plusone +\let\localrelativefontsize \plusone +\def\localabsolutefontsize {\fontbody} + +\let\relativefontsize \defaultrelativefontsize + +% \def\saverelativefontsize#1#2% #1=rm|ss|.. #2=waarde +% {\setxvalue{\fontclass#1\s!rscale}{#2}} + +\def\checkrelativefontid + {\ifcsname\??tf\fontclass\s!rname\endcsname + \@EA\let\@EA\relativefontid\csname\??tf\fontclass\s!rname\endcsname + \else + \@EA\xdef\csname\??tf\fontclass\s!rname\endcsname{\the\lastfontid}% + \let\relativefontid\empty + \fi} + +\def\checkrelativefontsize#1% + {\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}% + \ifx\relativefontsize\v!auto + \let\relativefontsize\plusone + \checkrelativefontid + \else + \let\relativefontid\minusone + \fi} + +%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} + +\let\somefontname\s!unknown +\let\somefontspec\s!unknown +\let\somefontsize\zerocount + +\newcount\scaledfontmode +\newdimen\scaledfontsize +\newtoks \everydefinefont +\newcount\lastfontid + +\def\currentfontbodysize + {\ifcsname\??ft\s!default\somefontsize\endcsname + \csname\??ft\s!default\somefontsize\endcsname + \else + \somefontsize + \fi} + +\let\relativefontid\empty + +\def\lowleveldefinefont#1#2% #2 = cs + {% + \ctxlua{fonts.define.command_1("\luaescapestring{#1}")}% the escapestring catches at \somedimen + % sets \scaledfontmode and \somefontname and \somefontsize + \ifcase\scaledfontmode\relax + % none, avoid the designsize if possible + \scaledfontsize-1000\scaledpoint + \or + % at + \scaledfontsize\somefontsize + \or + % sa + \scaledfontsize\localabsolutefontsize\relax + \scaledfontsize\currentfontbodysize\scaledfontsize + \or + % mo + \scaledfontsize\setmappedfontsize\localabsolutefontsize + \scaledfontsize\currentfontbodysize\scaledfontsize + \or + % scaled, don't use this one as it's unpredictable + \scaledfontsize-\somefontsize\scaledpoint + \fi + \scaledfontsize\localrelativefontsize\scaledfontsize + \ifautofontsize + \scaledfontsize\currentfontbodyscale\scaledfontsize + \fi + \edef\somefontspec{at \number\scaledfontsize sp}% + \edef\somefontfile{\truefontname\somefontname}% + \ifx\somefontfile\s!unknown + \edef\somefontfile{\defaultfontfile}% + \fi + \updatefontparameters + \updatefontclassparameters + \ctxlua{fonts.define.command_2( + \ifx\fontclass\empty false\else true\fi, + "#2", % cs, trailing % is gone + "\somefontfile", + \number\scaledfontsize, + "\@@fontclassfeatures", + "\@@fontfeatures", + "\@@fontclassfallbacks", + "\@@fontfallbacks", + 0\currentmathsize, + \number\dimexpr\textface\relax, + "\relativefontid" % experiment + )}% + \edef\somefontspec{at \somefontsize}% we need the resolved designsize (for fallbacks) + \expandafter\let\expandafter\lastrawfontcall\csname#2\endcsname + \the\everydefinefont} + +\def\updatefontclassparameters + {\edef\@@fontclassfeatures {\ifcsname\fontclass\fontstyle\s!features \endcsname\csname\fontclass\fontstyle\s!features \endcsname\fi}% + \edef\@@fontclassfallbacks{\ifcsname\fontclass\fontstyle\s!fallbacks\endcsname\csname\fontclass\fontstyle\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\@@hyphenchar \empty % todo, will go to encoding + +%D This brings down maps processing from 466 to 309 seconds +%D ($-33$\%) and mfonts from 42 to 34 seconds ($-15$\%). + +\newif\ifskipfontcharacteristics \skipfontcharacteristicstrue + +%D When fontclasses are used, we define the font global, +%D since namespaces are used. Otherwise we parse the specs +%D each time. + +\let\fontfile\s!unknown + +% \definefontfeature[slanted] [default][slant=.25] +% \definefontfeature[stretched][default][stretch=2] +% +% \start \definedfont[SerifBold*slanted at 20pt] \ruledhbox{Test!} \stop +% \start \definedfont[SerifBold*stretched at 20pt] \ruledhbox{Test!} \stop + +% \definefontfeature[default] [liga=yes,texligatures=yes,texquotes=yes] +% \definefontfeature[default-caps][liga=yes,texligatures=yes,texquotes=yes,smcp=yes,script=latn] +% +% \starttypescript [serif] [palatino-nova-regular] [name] +% \definefontsynonym[Serif] [palatinonova-regular][features=default] +% \definefontsynonym[SerifCaps][palatinonova-regular][features=default-caps] % also sets Serif +% \stoptypescript +% +% \starttypescript [serif] [palatino-nova-regular] [name] +% \definefontsynonym[Serif] [palatinonova-regular*default] +% \definefontsynonym[SerifCaps] [palatinonova-regular*default-caps] +% \stoptypescript + +% \definetypeface[mainface][rm][serif][palatino-nova-regular][default] \setupbodyfont[mainface] +% +% \starttext +% ``Test'' -- --- ff fi fl \sc ``Test'' -- --- ff fi fl +% \stoptext + +% \starttext +% \definefont +% [blabla] +% [name:Latin Modern Something] +% \definefont +% [blabla] +% [file:texnansi-lmr10] +% \blabla test +% \definefont +% [blabla] +% [texnansi-lmtt10] +% \blabla test +% \stoptext + +% \starttext +% +% \setupcolors[state=start] +% +% \definefontfeature +% [default-base] +% [script=latn,language=dflt,liga=yes,kern=yes,tlig=yes,trep=yes] +% \definefontfeature +% [default-node] +% [script=latn,language=dflt,liga=yes,kern=yes,tlig=yes,trep=yes,mode=node] +% \definefontfeature +% [default-none] +% [script=latn,language=dflt,liga=yes,kern=no, tlig=yes,trep=yes] +% +% \startoverlay +% {\vtop{\color[red] {\font\test=name:lmroman12regular*default-node \test \input ward \input zapf \input linden }}} +% {\vtop{\color[green]{\font\test=name:lmroman12regular*default-base \test \input ward \input zapf \input linden }}} +% {\vtop{\color[blue] {\font\test=name:lmroman12regular*default-none \test \input ward \input zapf \input linden }}} +% \stopoverlay +% +% \blank +% +% \startoverlay +% {\vtop{\color[red] {\font\test=name:texgyrepagella*default-node \test \input ward \input zapf \input linden }}} +% {\vtop{\color[green]{\font\test=name:texgyrepagella*default-base \test \input ward \input zapf \input linden }}} +% {\vtop{\color[blue] {\font\test=name:texgyrepagella*default-none \test \input ward \input zapf \input linden }}} +% \stopoverlay +% +% \blank +% +% \startoverlay +% {\vtop{\color[red] {\font\test=name:palatinonovaregular*default-node \test \input ward \input zapf \input linden }}} +% {\vtop{\color[green]{\font\test=name:palatinonovaregular*default-base \test \input ward \input zapf \input linden }}} +% {\vtop{\color[blue] {\font\test=name:palatinonovaregular*default-none \test \input ward \input zapf \input linden }}} +% \stopoverlay +% +% \startoverlay +% {\vtop{\color[red] {\font\test=name:OfficinaSerifBookITC*default-node \test \input ward \input zapf \input linden }}} +% {\vtop{\color[green]{\font\test=name:OfficinaSerifBookITC*default-base \test \input ward \input zapf \input linden }}} +% {\vtop{\color[blue] {\font\test=name:OfficinaSerifBookITC*default-none \test \input ward \input zapf \input linden }}} +% \stopoverlay +% +% \definefontfeature[superdefault][default][compose=yes] +% +% {\font\oeps=name:lmroman10regular*default at 30pt \oeps test \char7683} +% {\font\oeps=name:lmroman10regular*superdefault at 30pt \oeps test \char7683} +% +% \stoptext + +\def \defaultfontfile{\truefontname{Normal}} % was cmtt10, but that one is gone +\edef\nullfontname {\fontname\nullfont} + +%D \macros +%D {everyfont,everyfontswitch} +%D +%D For special purposes, we provide a hook. + +% \newevery \everyfont \relax +% \newevery \everyfontswitch \relax + +%D We also accept \type{sa a}||\type{sa d} as specification. + +%D \macros +%D {definefontsynonym, doifelsefontsynonym, +%D expandfontsynonym, truefontname, truefontdata} +%D +%D While looking for fonts, fontsynonyms are used for accessing +%D the files! +%D +%D \starttyping +%D \definefontsynonym[Serif][Lucida-Bright] +%D \definefontsynonym[Lucida-Bright][lbr][encoding=texnansi] +%D \stoptyping + +\def\classfont#1#2{#1#2} % \definefont[whatever][\classfont{xx}{yy} at 10pt] + +% 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. + +\unexpanded\def\definefontsynonym[#1]#2[#3]% + {\edef\@@fontname{#1}% + \edef\@@fontfile{#3}% + \ifx\fontclass\empty + \expandafter\dodefinefontsynonymnop + \else + \expandafter\dodefinefontsynonymyes + \fi} + +\def\dodefinefontsynonymnop + {\@EA\let\csname\??ff\@@fontname\endcsname\@@fontfile % maybe just #1 #3, saves expansion + \doifnextoptionalelse\dododefinefontsynonymnop\nonodefinefontsynonymnop} + +\def\dodefinefontsynonymyes + {\@EA\let\csname\??ff\fontclass\@@fontname\endcsname\@@fontfile % maybe just #1 #3, saves expansion + \doifnextoptionalelse\dododefinefontsynonymyes\nonodefinefontsynonymyes} + +\def\dododefinefontsynonymnop[#1]% + {\let\@@ff@@features \undefined + \let\@@ff@@fallbacks\undefined + \expandafter\dogetfontparameternop#1,]=,} + +\def\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\dogetfontparameteryes#1=#2,% + {\if]#1% + \dodododefinefontsynonymyes + \else + \expandafter\def\csname @@ff@@#1\endcsname{#2}% + \expandafter\dogetfontparameteryes + \fi} + +% hm, was wrong, class/global reversed + +\let\fcglobal\global +\let\fcxdef \xdef +\let\fcglet \glet + +\def\nonodefinefontsynonymnop + {\@EA\let\csname\??ff\@@fontname\s!features \endcsname\undefined + \@EA\let\csname\??ff\@@fontname\s!fallbacks\endcsname\undefined} + +\def\nonodefinefontsynonymyes + {\fcglobal\@EA\let\csname\??ff\fontclass\@@fontname\s!features \endcsname\undefined + \fcglobal\@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 + {\fcglobal\@EA\let\csname\??ff\fontclass\@@fontname\s!features \endcsname\@@ff@@features + \fcglobal\@EA\let\csname\??ff\fontclass\@@fontname\s!fallbacks\endcsname\@@ff@@fallbacks} + +\let\definefontfile\definefontsynonym % dedicated to Taco Hoekwater + +\unexpanded\def\setupfontsynonym + {\dodoubleempty\dosetupfontsynonym} + +\def\dosetupfontsynonym[#1][#2]% not yet supported, will do when needed + {} + +\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\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 + \else + \@EA\redotruefontname\csname\??ff#1\endcsname*#2#3% + \fi + \else + #1\ifx#2\empty\else*#2#3\fi + \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\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} + +\def\expandfontsynonym#1#2% #2 := onelevelexpansion(#1) + {\ifcsname\??ff\fontclass#2\endcsname + \expandafter\def\expandafter#1\expandafter{\csname\??ff\fontclass#2\endcsname}% + \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 + \@EA\firstoftwoarguments + \else\ifcsname\??ff\defaultfontclass#1\endcsname + \@EAEAEA\firstoftwoarguments + \else + \@EAEAEA\secondoftwoarguments + \fi\fi} + +% \definetypeface[palatino][rm][serif][palatino,allbold][default] +% +% \startfontclass[palatino] +% \definefontsynonym [Serif] [SerifBold] +% \definefontsynonym [SerifItalic] [SerifBoldItalic] +% \definefontsynonym [SerifSlanted] [SerifBoldSlanted] +% \definefontsynonym [SerifCaps] [SerifBold] +% \stopfontclass +% +% \setupbodyfont[palatino] + +\unexpanded\def\startfontclass + {\dosingleempty\dostartfontclass} + +\def\dostartfontclass[#1]% + {\pushmacro\fontclass + \doifelse{#1}\v!each + {\let\fontclass\empty} + {\doifsomething{#1}{\def\fontclass{#1}}}} + +\unexpanded\def\stopfontclass + {\popmacro\fontclass} + +%D \macros +%D {tracedfontname} +%D +%D A goody: + +\def\tracedfontname#1% + {#1\ifcsname\??ff\fontclass#1\endcsname + \@EA\tracedfontname\csname\??ff\fontclass#1\endcsname + \else\ifcsname\??ff#1\endcsname + \@EA\tracedfontname\csname\??ff#1\endcsname + \fi\fi} + +%D \macros +%D {definefont} +%D +%D Before we implement the main definition macro, we first show +%D one for local use: +%D +%D \starttyping +%D \definefont[Some][LucidaBright at 100pt] \Some some +%D \definefont[More][LucidaBright scaled 3000] \More more +%D \definefont[Nice][LucidaBright mo 2] \Nice nice +%D \definefont[Text][LucidaBright sa 5.4] \Text last +%D \stoptyping +%D +%D The implementation looks as follows: + +\unexpanded\def\definefont + {\dotripleempty\dodefinefont} + +\def\dodefinefont[#1][#2][#3]% [name][spec][1.6 | line=10pt | setup_id] + {\ifthirdargument + \setuvalue{#1}{\redodefinefont{#1}{#2}{#3}}% + \else + \setuvalue{#1}{\dododefinefont{#1}{#2}}% + \fi} + +\def\redodefinefont#1#2#3% + {\dododefinefont{#1}{#2}% + \doifsetupselse{#3} + {\setups[#3]} % don't forget to document this ! + {\setuplocalinterlinespace[#3]% + \setupspacing}} % needed ? + +\unexpanded\def\definefrozenfont + {\dotripleempty\dodefinefrozenfont} + +\def\dodefinefrozenfont[#1][#2][#3]% + {\dodefinefont[#1][#2][#3]% + \expandafter\let\csname\lastfontidentifier\expandafter\endcsname\csname\rawfontidentifier\endcsname} + +%D The \type {*} makes the switch local, so that we can redefine a +%D logical name and/or change the size in between. + +\newif\ifautofontsize \autofontsizetrue + +\let\lastfontidentifier\empty + +\def\rawfontidentifier{**\lastfontidentifier\fontsize\currentmathsize**} +\def\newfontidentifier{*\fontclass\lastfontidentifier\fontsize\currentmathsize*} + +\let\oldrawfontidentifier\rawfontidentifier +\let\oldnewfontidentifier\newfontidentifier + +\def\newfontidentifier{*\fontclass\lastfontidentifier\fontstyle\fontsize*} + +\def\dododefinefont#1#2% + {\edef\lastfontidentifier{#1}% + \let\localrelativefontsize\defaultrelativefontsize + \let\localabsolutefontsize\fontbody + \lowleveldefinefont{#2}\rawfontidentifier + \csname\rawfontidentifier\endcsname + \autofontsizefalse + \setfontcharacteristics + \the\everyfontswitch + \let\rawfontidentifier\oldrawfontidentifier} + +\def\xxdododefinefont#1#2#3#4% \autofontsizetrue is set by calling routine + {\edef\lastfontidentifier{#3}% + \ifcsname\newfontidentifier\endcsname\else + \def\localrelativefontsize{#1}% + \def\localabsolutefontsize{#2}% + \lowleveldefinefont{#4}\newfontidentifier + \fi + \csname\newfontidentifier\endcsname + \autofontsizefalse + %\edef\lastfontidentifier{#3}% + \ifskipfontcharacteristics \else + \setfontcharacteristics + \the\everyfontswitch + \fi + \let\newfontidentifier\oldnewfontidentifier} + +%D \macros +%D {mapfontsize} +%D +%D For special purposes, like in math, you may want to use +%D slightly different sizes than the ones given. This happens +%D for instance with the Math Times fonts. Mapped font sizes +%D can be specified by using the \type {mo} key instead of +%D \type {sa} in font definitions. +%D +%D \startbuffer +%D \mapfontsize[10pt][11pt] +%D \mapfontsize[11pt][12pt] +%D \mapfontsize[12pt][13pt] +%D +%D \definefont[test][Serif]\test TEST \par +%D \definefont[test][Serif sa 5]\test TEST \par +%D \definefont[test][Serif mo 5]\test TEST \par +%D \definefont[test][Serif sa d]\test TEST \par +%D \definefont[test][Serif at 60pt]\test TEST \par +%D \definefont[test][Serif scaled 6000]\test TEST \par +%D \stopbuffer +%D +%D \typebuffer +%D +%D \startpacked +%D \getbuffer +%D \stoppacked + +\def\mapfontsize + {\dodoubleargument\domapfontsize} + +\def\domapfontsize[#1][#2]% + {\setvalue{\??ft*\the\dimexpr#1\relax}{#2}} + +\def\setmappedfontsize#1% + {\ifcsname\??ft*#1\endcsname + \csname\??ft*#1\endcsname + \else + #1% + \fi} + +%D \macros +%D {getfontname} +%D +%D The names of the fonts can be called with the rather simple +%D macro \type{\getfontname}. When for instance we pass +%D \type{12ptrmtf} as argument, we get \getfontname{12ptrmtf}. + +\def\getfontname#1% + {\csname\??ft#1\endcsname} + +%D To be documented. + +\let\fontsizelist \empty +\let\fontalternativelist\empty +\let\fontstylelist \empty + +\def\checkfontnamecombinations % we need to split math and text here ... todo (math only has mr and mb) + {\def\docommand##1% + {\def\dodocommand####1% + {\def\dododocommand########1{\checkbodyfont{########1}{####1}{##1}}% + \processcommacommand[\fontstylelist]\dododocommand}% + \processcommacommand[\fontalternativelist]\dodocommand}% + \processcommacommand[\fontsizelist]\docommand} + +\unexpanded\def\definefontsize[#1]% sneller met toks + {\addtocommalist{#1}\fontsizelist + \checkfontnamecombinations} + +\unexpanded\def\definefontalternative[#1]% + {\addtocommalist{#1}\fontalternativelist + \checkfontnamecombinations} + +%D \macros +%D {currentfontscale,currentfontbodyscale} +%D +%D Sometimes we need to have access to the font scale +%D including the \type{a}||\type{d} sizes. The next macro +%D returns the current scaling factor. Take a look at +%D \type {cont-log.tex} for an example of its use. + +\def\currentfontscale + {\csname\??ft\s!default + \ifcsname\??ft\s!default\xfontsize\endcsname \xfontsize \else + \ifcsname\??ft\s!default\s!text \endcsname \s!text \fi\fi + \endcsname} + +\def\currentfontbodyscale + {\csname\??ft\s!default + \ifcsname\??ft\s!default\fontsize\endcsname \fontsize \else + \ifcsname\??ft\s!default\s!text \endcsname \s!text \fi\fi + \endcsname} + +\setvalue{\??ft\s!default}{1} + +%D Both alternatives use \type {\xfontsize}, a macro that +%D expands to the current size in terms of \type {a} \unknown +%D \type {d}, nothing, or \type {x} \unknown \type {xx}. + +\def\xfontsize{\ifcase\currentxfontsize\fontsize\or\c!x\else\c!xx\fi} + +%D A typical use of this command is in commands that switch +%D to another font bypassing the font mechanism: +%D +%D \starttyping +%D \font\myfont=\truefontname{MyFont} at \the\dimexpr\currentfontscale\bodyfontsize\relax +%D \stoptyping + +%D Now we enter the area of font switching. The switching +%D mechanism has to take care of several situations, like: +%D +%D \startitemize[packed] +%D \item changing the overal document fonts (including margins, +%D headers and footers) +%D \item changing local fonts (only the running text) +%D \item smaller and even more smaller alternatives (super- +%D and subscripts) +%D \stopitemize +%D +%D \TEX\ offers a powerfull family mechanism for super- and +%D subscripts in math mode. In text mode however, we don't use +%D families for the smaller alternatives, and therefore have +%D to take care of it otherwise. + +%D \macros +%D {definebodyfontenvironment,setupbodyfontenvironment} +%D +%D The relationship between the several sizes of a font, is +%D defined by: +%D +%D \showsetup{definebodyfontenvironment} +%D +%D Later on we will see how these parameters are used, so for +%D the moment we stick with an example: +%D +%D \starttyping +%D \definebodyfontenvironment +%D [12pt] +%D [ text=12pt, +%D script=9pt, +%D scriptscript=7pt, +%D x=10pt, +%D xx=8pt, +%D big=12pt, +%D small=10pt] +%D \stoptyping +%D +%D The first argument specifies the bodyfont size to which the +%D settings apply. All second parameters are specified in +%D dimensions and tell us more about related sizes. +%D +%D Afterwards, one can change values with +%D +%D \showsetup{setupbodyfontenvironment} +%D +%D Due to the fact that \type{\c!text} and \type{\s!text} can +%D have a similar meaning, and therefore can lead to an +%D unwanted loop, we temporary redefine \type{\c!text}. For +%D the moment this in only place that some trickery is needed +%D to fool the multilingual interface. However, long ago +%D we decided to stick to \s!text in definitions as it closely +%D relates to the math model where text, script and scriptscript +%D are used untranslated. Also, we are now english at the low +%D level so it cannot go wrong anymore. +%D +%D When instead of a size the keyword \type{unknown} is +%D passed, fractions (relations) are used instead of fixed +%D sizes. + +\let\bodyfontenvironmentlist\empty + +\newcount\@@fontdefhack % check if this is still needed + +\def\@@beginfontdef + {\ifcase\@@fontdefhack + \let\k!savedtext \k!text \let\k!text \s!text + \let\k!k!savedtext \k!k!text \let\k!k!text \!!plusone + \let\k!saveddefault \k!default \let\k!default \s!default + \let\k!k!saveddefault\k!k!default \let\k!k!default \!!plusone + \fi + \advance\@@fontdefhack \plusone } + +\def\@@endfontdef + {\advance\@@fontdefhack \minusone + \ifcase\@@fontdefhack + \let\k!k!default\k!k!saveddefault + \let\k!default \k!saveddefault + \let\k!k!text \k!k!savedtext + \let\k!text \k!savedtext + \fi} + +\unexpanded\def\definebodyfontenvironment + {\dotripleempty\dodefinebodyfontenvironment} + +\def\dodefinebodyfontenvironment[#1][#2][#3]% class size settings + {\ifthirdargument + \@@beginfontdef + \doifelse{#2}\s!default + {\getparameters[\??ft\s!default][#3]} + {\normalizebodyfontsize#2\to\tempbodyfontsize + \addtocommalist\tempbodyfontsize\bodyfontenvironmentlist + \@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 % \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% + {\scratchdimen\csname\??ft\s!default##1\endcsname\dimexpr#1\relax + \normalizebodyfontsize\scratchdimen\to\tempbodyfontsize + \letvalue{\??ft#2#1##1}\tempbodyfontsize}% + \processcommacommand[\fontrelativesizelist]\docommand + \copyparameters + [\??ft#2#1][\??ft\s!default] + [\c!interlinespace,\c!em]% + \fi + \getparameters[\??ft#2#1][#3]% + \@@endfontdef + % new code, see remark + \ifloadingfonts + % only runtime + \else\ifcsname\@size@#1\endcsname + % only once + \else + % prevent loop (hence \empty) + \letvalue{\@size@#1}\empty + \pushmacro\fontclass % new per 26102009 + \edef\fontclass{#2}% % new per 26102009 + \defineunknownfont{#1}% + \popmacro\fontclass % new per 26102009 + \fi\fi + % so far + \setvalue{\@size@#1}{\docompletefontswitch[#1]}} + +%D {\bf Remark:} We need to cover the following cases, +%D otherwise users can get confused: +%D +%D \starttyping +%D \setupbodyfont[23pt] +%D +%D \definebodyfontenvironment[23pt] +%D \setupbodyfont[23pt] +%D +%D \definebodyfontenvironment[23pt] +%D \definebodyfont[23pt][rm,ss,tt][default] +%D \setupbodyfont[23pt] +%D \stoptyping + +%D Beware: while some font defs can be global, the bodyfont +%D environment checks local. This means that multiple local +%D checks resulting in definitions are not that efficient. +%D So, apart from an occasional switch, one should define an +%D environment at the outer level. + +\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 + +\let\setupbodyfontenvironment\definebodyfontenvironment + +%D Just a couple of interface macros: + +\def\bodyfontvariable#1% + {\??ft\ifcsname\??ft\fontclass#1\endcsname\fontclass\fi#1} + +\def\bodyfontinterlinespecs + {\bodyfontvariable{\normalizedbodyfontsize\c!interlinespace}} + +\def\bodyfontinterlinespace + {\csname\bodyfontinterlinespecs\endcsname} + +%D We default all parameters to the main bodyfont size (begin +%D \type{#1}), so the next setup is valid too: +%D +%D \starttyping +%D \definebodyfontenvironment[24pt] +%D \stoptyping +%D +%D All parameters can be redefined when needed, so one does +%D not have to stick to the default ones. + +%D \macros +%D {definebodyfont} +%D +%D The next step in defining a bodyfont involves the actual font +%D files, which can be recognized by their extension +%D \type{tfm}. Installing those file is often beyond the +%D scope of the user and up to the system administrator. +%D +%D \showsetup{definebodyfont} +%D +%D This commands takes three arguments: a (series of) bodyfont +%D size(s), the style group to which the definitions belong, +%D and an alternative, as specified by the \TEX\ (math) families, +%D extended with~a, b~\unknown. +%D +%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. The magic scaled +%D values are derived from plain \TEX's \type {\magstep}: +%D +%D \starttyping +%D \definebodyfont [12pt] [rm] +%D [tf=cmr12, +%D bf=cmbx12, +%D it=cmti12, +%D sl=cmsl12, +%D bi=cmbxti10 at 12pt, +%D bs=cmbxsl10 at 12pt, +%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] +%D [tf=lbr sa 1, +%D bf=lbd sa 1, +%D it=lbi sa 1, +%D sl=lbsl sa 1, +%D bi=lbdi sa 1, +%D bs=lbdi sa 1, +%D tfa=lbr sa 1.200, +%D tfb=lbr sa 1.440, +%D tfc=lbr sa 1.728, +%D tfd=lbr sa 2.074, +%D sc=lbr sa 0.833] +%D \stoptyping +%D +%D The second example shows that we can define more sizes at +%D once. The main difference between these examples is that the +%D Computer Modern Roman come in many design sizes. This means +%D that there we cannot define them in bulk using \type{sa}. +%D Instead of \type{rm} (roman) one can define \type{ss} (sans +%D serif), \type{tt} (teletype), \type{hw} (hand written), +%D \type{cg} (calygraphic) and whatever styles. +%D +%D The first argument may be a comma separated list. This, +%D combined with specifications using \type{sa} can save a lot +%D of typing. Although all arguments should be specified, we +%D treat the second argument as optional. +%D +%D Defining a bodyfont involves two actions: defining the +%D specific style related alternatives, like \type{\rma}, +%D \type{\bfa} and \type{\rmsla}, and storing the definitions +%D of their bodyfont size related fonts. The first step is +%D bodyfont independant but executed every time. This permits +%D user definitions like \type{\tfw} or \type{\bfq} for real +%D large alternatives. + +\unexpanded\def\definebodyfont + {\doquadrupleempty\redefinebodyfont} + +\def\redefinebodyfont[#1][#2][#3][#4]% + {\iffourthargument + \processcommacommand[#1]{\reredefinebodyfont[#2][#3][#4]}% + \else + \dodefinebodyfont[#1][#2][#3]% + \fi} + +\def\reredefinebodyfont[#1][#2][#3]#4% + {\pushmacro\fontclass + \doifelse{#4}\s!default + {\let\fontclass\empty} + {\def\fontclass{#4}}% + \definebodyfont[#1][#2][#3]% + \popmacro\fontclass} + +\def\dodefinebodyfont[#1][#2][#3]% body|identifier style defs|identifier + {\ifthirdargument + \doifnumberelse{#1} + {\doifassignmentelse{#3} + {% [12pt] [style] [settings] + \ifcsname#2\endcsname\else\normalexpanded{\noexpand\definefontstyle[#2][#2]}\fi % 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{\normalexpanded{\noexpand\xdodefinebodyfont[##1][##2][#3]}}}% + \else\ifsecondargument + \definebodyfont[#1][\c!rm][#2]% + \else + % Maybe there are default dependencies defined which we can use ([unknown]) and + % if not, then we have at least to make sure some basics are set up. + \ifcsname\@size@#1\endcsname \else + \defineunknownfont{#1}% + \fi + \ifcsname\@size@#1\endcsname \else + \definebodyfont[#1][\c!rm][]% + \fi + \fi\fi} + +\def\xdodefinebodyfont[#1][#2][#3]% body|identifier style defs|identifier + {\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} + +\def\dododefinebodyfont#1#2#3% style defs body + {\checkbodyfontenvironment[#3]% just to be sure. + \processcommalist[#2]{\dodododefinebodyfont{#1}{#3}}} + +\def\dodododefinebodyfont#1#2#3% style body def + {\dododododefinebodyfont{#1}{#2}[#3]} + +\def\dododododefinebodyfont + {\ifx\fontclass\empty + \expandafter\dododododefinebodyfontnop + \else + \expandafter\dododododefinebodyfontyes + \fi} + +\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 + \unexpanded\@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] + \fcglobal\@EA\let\csname*\fontclass#2#1#3#4#5*\endcsname\undefined + \unexpanded\@EA\fcxdef\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 + \unexpanded\@EA\edef\csname#2#1#3#4#51\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#51}{\normalunexpanded{#6}}}% + \unexpanded\@EA\edef\csname#2#1#3#4#52\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#52}{\normalunexpanded{#6}}}% + \unexpanded\@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] + \fcglobal\@EA\let\csname*\fontclass#2#1#3#4#51*\endcsname\undefined + \fcglobal\@EA\let\csname*\fontclass#2#1#3#4#52*\endcsname\undefined + \fcglobal\@EA\let\csname*\fontclass#2#1#3#4#53*\endcsname\undefined + \unexpanded\@EA\fcxdef\csname\fontclass#2#1#3#4#51\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#51}{\normalunexpanded{#6}}}% + \unexpanded\@EA\fcxdef\csname\fontclass#2#1#3#4#52\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#52}{\normalunexpanded{#6}}}% + \unexpanded\@EA\fcxdef\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 + {\edef\c!!mm{#1}% + \ifx\c!!mm\c!mm % prevents \max and alike (re)defs + \expandafter\checkmathbodyfont + \else + \expandafter\checktextbodyfont + \fi{#1}} % no \c!!mm, not expanded later on + +% some day we can do an auto-fam if needed + +\def\checkmathbodyfont#1#2#3% style alt size / gdef % #3 can be empty + {%\message{!m #1 #2 #3!}% + % #1 #2 #3 = signal + %setugvalue {#2}{\setcurrentfontalternative {#2}}% \mr \mb + \setugvalue {#1}{\setcurrentfontstyle {#1}}}% \mm + +\def\checktextbodyfont#1#2#3% style alt size / gdef % #3 can be empty + {%\message{!t #1 #2 #3!}% + \setugvalue {#1#3}{\setcurrentfontstylesize {#1}{#3}}% \rma + \setugvalue {#2#3}{\setcurrentfontalternativesize {#2}{#3}}% \sla + \setugvalue {#1#2#3}{\setcurrentfontstylealternativesize{#1}{#2}{#3}}% \rmsla + \setugvalue {#1}{\setcurrentfontstyle {#1}}% \rm + \setugvalue {#2}{\setcurrentfontalternative {#2}}% \sl + \setugvalue {#1\c!x}{\setcurrentfontxstylealternative {#1}}% \rmx + \setugvalue{#1\c!xx}{\setcurrentfontxxstylealternative {#1}}% \rmxx + \setugvalue {#2\c!x}{\setcurrentfontxalternative {#2}}% \slx + \setugvalue{#2\c!xx}{\setcurrentfontxxalternative {#2}}% \slxx + \setugvalue {#1#2}{\setcurrentfontstylealternative {#1}{#2}}}% \rmsl + +\def\dodefinedefaultbodyfont[#1][#2][#3]% sizes styles identifier + {\def\dododefinedefaultbodyfont##1% + {\def\dodododefinedefaultbodyfont####1% + {\def\dododododefinedefaultbodyfont########1% + {\ifcsname\s!default########1####1\endcsname + % [12pt] [style] [identifier] + \csname\s!default########1####1\endcsname{##1}{####1}% + \fi}% + \processcommalist[#3]\dododododefinedefaultbodyfont}% + \processcommalist[#2]\dodododefinedefaultbodyfont}% + \processcommalist[#1]\dododefinedefaultbodyfont} + +%D Unknown families are added to the family list! For the +%D moment we also set the direct calls here. Some day a better +%D solution will be implemented. The good news is that unknown +%D fonts are defined automatically. + +\newif\ifdefiningunknownfont + +\def\dodefineunknownfont#1#2% + {\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 *** + {\ifcsname\s!default\s!default#2\endcsname % somehow related to */* + \donetrue + \csname\s!default\s!default#2\endcsname{#1}{#2}% + \fi} + +\def\dodefineunknownsubfont#1#2% + {\ifcsname\@size@\csname\??ft#1#2\endcsname\endcsname + \else + \donetrue + \defineunknownfont{\csname\??ft#1#2\endcsname}% + \fi} + +\unexpanded\def\defineunknownfont#1% + {\let\c!savedtext\c!text + \let\c!text\s!text + \donefalse + \processcommacommand[\fontrelativesizelist]{\dodefineunknownfont{#1}}% + \let\c!text\c!savedtext + \ifdone + \donefalse + \processcommacommand + [\fontstylelist] + {\dodefineunknownbodyfont{#1}}% + \ifdone + \donefalse + \setvalue{\@size@#1}{\docompletefontswitch[#1]}% + \ifdefiningunknownfont \else + \definingunknownfonttrue + \processcommacommand[\fontrelativesizelist]{\dodefineunknownsubfont{#1}}% + \definingunknownfontfalse + \fi + \fi + \ifdone + \showmessage\m!fonts{14}{#1}% + \fi + \fi} + +%D These macros show that quite some definitions take place. +%D Fonts are not loaded yet! This means that at format +%D generation time, no font files are preloaded. + +%D \macros +%D {everybodyfont,Everybodyfont,everyglobalbodyfont} +%D +%D Every change in bodyfont size has conseqences for the baseline +%D distance and skips between paragraphs. These are initialized +%D in other modules. Here we only provide the hooks that +%D garantees their handling. + +%D At the system level one can initialize thing like: +%D +%D \starttyping +%D \appendtoks \setupspacing \to \everybodyfont +%D \stoptyping +%D +%D While users can add their own non standard commands like: +%D +%D \starttyping +%D \EveryBodyFont{\message{changing to bodyfont \the\bodyfontsize}} +%D \stoptyping +%D +%D Personnaly I never felt the need for such extensions, but +%D at least its possible. + +%D \macros +%D {globalbodyfontsize,localbodyfontsize} +%D +%D Next we'll do the tough job of font switching. Here we +%D have to distinguish between the global (overal) bodyfont +%D size and the local (sometimes in the textflow) size. We +%D store these dimensions in two \DIMENSION\ registers. + +\ifdefined\globalbodyfontsize\else \newdimen\globalbodyfontsize \fi \globalbodyfontsize=12pt +\ifdefined\localbodyfontsize \else \newdimen\localbodyfontsize \fi \localbodyfontsize =\globalbodyfontsize + +%D \macros +%D {bodyfontsize} +%D +%D These two registers are not to be misused in calculations. +%D For this purpose we keep a copy: + +\newdimen\bodyfontsize \bodyfontsize=\globalbodyfontsize + +%D \macros +%D {bodyfontfactor,bodyfontpoints} +%D +%D For multiplication purposes we keep an auxiliary counter +%D and macro (here the expansion is not explicitly needed): + +\newcount\bodyfontpoints \dimensiontocount\bodyfontsize\bodyfontpoints + +\edef\bodyfontfactor{\withoutpt\the\bodyfontsize} + +%D When we assign for instance 12pt to a \DIMENSION\ register +%D the \type{\the}'d value comes out as 12.0pt, which is +%D often not the way users specify the bodyfont size. Therefore +%D we also store the normalized value. + +\chardef\fontdigits=2 % was 1 + +% \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\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 % 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}} + +\def\normalizebodyfontsize#1\to#2% + {\edef#2{\ctxlua{fonts.nbfs(\number\dimexpr#1\relax,\number\fontdigits)}}} + +\def\thenormalizedbodyfontsize#1% + {\ctxlua{fonts.nbfs(\number\dimexpr#1\relax,\number\fontdigits)}} + +\normalizebodyfontsize\bodyfontsize\to\normalizedglobalbodyfontsize +\normalizebodyfontsize\bodyfontsize\to\normalizedlocalbodyfontsize +\normalizebodyfontsize\bodyfontsize\to\normalizedbodyfontsize + +%D \macros +%D {fontstyle,fontalternative,fontsize} +%D +%D Within a bodyfont, fonts can come in different sizes. For +%D instance \type{\tf} is accompanied by \type{\tfa}, +%D \type{\tfb} etc. The first two characters denote the +%D alternative, while the third character in these sequences +%D represents the size. The actual size is saved in a macro +%D +%D The style, being roman (\type{\rm}), sans serif (\type{\ss}) +%D etc. is also available in a macro in \type{rm}, \type{ss} +%D etc. form: + +\let\defaultfontalternative = \c!tf +\let\defaultfontstyle = \empty +\let\defaultfontsize = \empty + +\let\fontalternative = \defaultfontalternative +\let\fontstyle = \defaultfontstyle +\let\fontsize = \defaultfontsize + +%D When \type {\loadfontfileoncetrue}, such files are +%D only loaded once! This permits redundant loading, but at +%D the same time forced grouping when we want continuously mix +%D all kind of font, which of course is a kind of +%D typographically sin. The \type{"} is made inactive if +%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]% + {\normalexpanded{\dodoswitchpoints{#1}}} + +\unexpanded \def\dodoswitchpoints#1% + {\ifcsname\@size@#1\endcsname \else + \defineunknownfont{#1}% + \fi% + %\defineunknownfontstyles{#1}% + \ifcsname\@size@#1\endcsname + \csname\@size@#1\endcsname + \localbodyfontsize#1\relax + \normalizebodyfontsize\localbodyfontsize\to\normalizedbodyfontsize + % \edef\fontbody{\fontbody}% to be tested but we can clean up mkiv further + \checkbodyfontenvironment[\normalizedbodyfontsize]% + \else + \showmessage\m!fonts4{#1}% + \fi} + +\unexpanded \def\doswitchstyle[#1]% + {\ifcsname\@style@#1\endcsname + \csname\@style@#1\endcsname + \edef\fontstyle{#1}% + \ifmmode\mr\fi % in order to be compatible with \rm in math mode + % \the\everybodyfont % cleaner, in setting size as well as style + \else + \showmessage\m!fonts5{#1}% + \fi} + +%D \TEX\ loads font metric files like \type{cmr10.tfm} and +%D \type{tir.tfm} only once. In \PLAIN\ \TEX\ some font files +%D are {\em preloaded}. This means that the font files are +%D loaded, but not accessible yet by name. This is accomplished +%D by saying: +%D +%D \starttyping +%D \font\preloaded=cmr10 at 11pt +%D \stoptyping +%D +%D and using the name \type{\preloaded} again and again, so +%D fonts are indeed loaded, but unnamed, and therefore +%D unaccessible. In \CONTEXT\ we don't preload fonts, not even +%D the \PLAIN\ \TEX\ ones, although users can access them. Now +%D why is this done? + +%D Defining fonts using \type{\definebodyfont} takes time, so we +%D prefer to predefine at least the Computer Modern Roman +%D fonts. However, loading all those fonts at definition time +%D would take both time and space. But even worse, once fonts +%D are loaded into memory, their encoding vector is fixed, +%D which is a handicap when we want to distribute the compact +%D \type{fmt} files. So what we want to do is defining fonts in +%D a way that postpones the loading. We accomplish this by only +%D loading the fonts when we switch to another bodyfont size. +%D Among the other alternatives, such as loading the font at +%D the moment of activation and redefining the activation +%D macro afterwards, this proved to be the most efficient +%D alternative. +%D +%D The next few macros take care of the one exeption on this +%D scheme. When at format generation time we load the default +%D font file, the one that defines the Computer Modern Fonts, +%D we don't want the fonts metrics to end up in the format +%D file, so we temporary prohibit loading. This means that at +%D runtime we have to load the default bodyfont size just before +%D we start typesetting. +%D +%D Therefore we have to signal the font switching macros that +%D we are preloading fonts. As long as the next boolean is, +%D true, no loading is done. + +\newif\ifloadingfonts \loadingfontstrue + +%D \macros +%D {preloadfonts} +%D +%D Preloading is only called for once, during the startup +%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 + {\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} + +% 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 +%D bodyfont size. + +\def\dosetfont#1#2% #1 = set/switch state + {\doifelse{#2}\v!global + {\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}}}} + +% % % 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 + {\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 +%D support for instance \type{\sl} inside a \type{\tx} switch. + +\chardef\currentxfontsize=0 + +%D When users specify for instance a 13 point bodyfont while no +%D such bodyfont is defined, the system automatically tries to +%D find a best fit, that is the nearest smaller defined +%D bodyfontzize. A smaller one is definitely better than a larger +%D one, simply because otherwise a lot of overfull box messages +%D are more probable to occur. By taking a value slightly +%D smaller than half a point, we can use the next method. + +\def\dosetsubstitutefont#1#2% #1 = set/switch state + {\scratchdimen#2\relax + \advance\scratchdimen .499\points + \dimensiontocount\scratchdimen\scratchcounter + \advance\scratchcounter \minusone + \ifnum\scratchcounter>\plusthree + \dododosetfont{#1}{\the\scratchcounter\s!pt}{}% + \fi} + +% The following bunch of macros deals with the (run time) +% expansion of names onto the definitions made by \type +% {\definebodyfont}. + +% \let\fontbody \empty % ... 10pt 11pt 12pt ... +% \let\fontstyle \empty % rm ss tt mm hw cg ... +% \let\fontalternative\empty % tf bf sl it bs bi sc ... +% \let\fontsize \empty % xy-abcd ... + +\def\defaultfontbody{\normalizedbodyfontsize} + +\let\fontbody\defaultfontbody + +\let\fontclass\empty \let\globalfontclass\fontclass + +% we need to check the fontclass + +\def\registerfontclass#1% + {\letgvalue{\@fontclass@#1}\v!yes} % global ? + +\edef\@no@fontclass@{\@fontclass@:?:} + +\def\setcurrentfontclass#1% + {\ifcsname\@fontclass@#1\endcsname + \edef\fontclass{#1}% + \else\ifcsname\@no@fontclass@#1\endcsname + % already tried + \else\ifcase\currentgrouplevel + \trycurrentfontclass{#1}% + \fi\fi\fi} + +\def\savefontclassparameters#1#2#3#4% #1=rm|ss|.. rscale features fallbacks + {\setxvalue{\fontclass#1\s!rscale }{#2}% + \setxvalue{\fontclass#1\s!features }{#3}% + \setxvalue{\fontclass#1\s!fallbacks}{#4}} + +\settrue\autotypescripts + +% \def\trycurrentfontclass#1% +% {\ifconditional\autotypescripts +% \usetypescript[#1]% +% \ifcsname\@fontclass@#1\endcsname +% \edef\fontclass{#1}% +% \else +% \letvalue{\@no@fontclass@#1}\empty +% \fi +% \else +% \letvalue{\@no@fontclass@#1}\empty +% \fi} + +\def\trycurrentfontclass#1% + {\ifconditional\autotypescripts + % try to load typescript #1 + \usetypescript[#1]% + \ifcsname\@fontclass@#1\endcsname + \edef\fontclass{#1}% + \else + % try to load type-#1.mkiv + \usetypescriptfile[\f!typeprefix#1]% + % try to load typescript #1 + \usetypescript[#1]% + \ifcsname\@fontclass@#1\endcsname + \edef\fontclass{#1}% + \else + % todo: message + \letvalue{\@no@fontclass@#1}\empty + \fi + \fi + \else + % todo: message + \letvalue{\@no@fontclass@#1}\empty + \fi} + +\let\defaultfontstyle \c!rm +\let\defaultfontalternative \c!tf +\let\defaultfontsize \empty + +%D \macros +%D {bigmath,nobigmath} +%D +%D We can inhibit this slow||downer with: + +% these can best be combined + +% 0=never 1=everymath 2=always + +\chardef\synchronizebigmathflag=1 + +\appendtoks + \ifcase\synchronizebigmathflag + % never + \or + \synchronizebigmath + \or + % always + \fi +\to \everymathematics + +\def\nobigmath {\chardef\synchronizebigmathflag\zerocount} +\def\autobigmath{\chardef\synchronizebigmathflag\plusone\synchronizebigmath} +\def\bigmath {\chardef\synchronizebigmathflag\plustwo\synchronizebigmath} + +\let\bigmathfontsize\empty + +\def\synchronizebigmath + {\ifx\bigmathfontsize\fontsize + % already in sync + \else + \let\bigmathfontsize\fontsize + \synchronizemath + \fi} + +\def\checkbigmathsynchronization + {\ifcase\synchronizebigmathflag + % never + \or + \ifmmode \synchronizebigmath \fi + \or + \synchronizebigmath + \fi} + +%D So far for synchronisation. (We can inline the following macros.) + +\def\dosetcurrentfontsize#1% + {\edef\fontsize{#1}% + \checkbigmathsynchronization} + +\def\dosetcurrentfontalternative#1% + {\edef\fontalternative{#1}} + +\def\setcurrentfont#1#2#3#4% + {%\message{[1 #1 #2 #3 #4]}% + \edef\fontbody{#1}% + \edef\fontstyle{#2}% + \dosetcurrentfontalternative{#3}% + \dosetcurrentfontsize{#4}% + \synchronizefont} + +\def\setcurrentfontbody#1% + {%\message{[2 #1]}% + \edef\fontbody{#1}% + \synchronizefont} + +% For Taco: optional fall backs: + +\ifx\checkfontclass\undefined \let\checkfontclass\gobbleoneargument \fi % implemented in type-ini + +% \def\setcurrentfontstyle#1% +% {%\message{[3 #1]}% +% \checkfontclass{#1}% +% \edef\fontstyle{#1}% +% \ifmmode\mr\fi % otherwise \rm not downward compatible +% \synchronizefont} + +\def\setcurrentfontstyle#1% + {%\message{[3 #1]}% + \edef\fontstyle{#1}% + \checkfontclass\fontstyle + \ifmmode\mr\fi % otherwise \rm not downward compatible + \synchronizefont} + +\def\setcurrentfontbodyalternative#1#2% + {%\message{[4 #1 #2]}% + \edef\fontbody{#1}% + \dosetcurrentfontalternative{#2}% + \synchronizefont} + +\def\setcurrentfontalternative#1% + {%\message{[5 #1]}% + \dosetcurrentfontalternative{#1}% + \synchronizefont} + +\def\setcurrentfontsize#1% + {%\message{[6 #1]}% + \dosetcurrentfontsize{#1}% + \synchronizefont} + +\def\setcurrentfontstylealternative#1#2% \rmsl + {%\message{[7 #1 #2]}% + \edef\fontstyle{#1}% + \dosetcurrentfontalternative{#2}% + \synchronizefont} + +\def\setcurrentfontstylesize#1#2% \rmsla + {%\message{[8 #1 #2]}% + \edef\fontstyle{#1}% + \dosetcurrentfontsize{#2}% + \synchronizefont} + +\def\setcurrentfontalternativesize#1#2% \sla + {%\message{[9 #1 #2]}% + \dosetcurrentfontalternative{#1}% + \dosetcurrentfontsize{#2}% + \synchronizefont} + +\def\setcurrentfontstylealternativesize#1#2#3% \rmsla + {%\message{[10 #1 #2 #3]}% + \edef\fontstyle{#1}% + \dosetcurrentfontalternative{#2}% + \dosetcurrentfontsize{#3}% + \synchronizefont} + +%D In principle one can assign alternative fallback routines. +%D Some day we will. + +\newtoks\fontstrategies +\newif\iftryingfont + +\let\fontstrategy\relax + +\def\synchronizefont % we can have dups i.e. no need to let fontstrategy + {\tryingfonttrue + \ifx\fontclass\empty + \applyfontstrategies + \else + \applyfontclassstrategies + \fi + \autofontsizefalse + \ifskipfontcharacteristics + \setfontcharacteristics + \the\everyfontswitch + \fi} + +\def\fontclassstrategiesa % --- --- --- --- % pt tt bf a + {\ifcsname\fontclass\fontbody \fontstyle \fontalternative \fontsize\endcsname + \autofontsizefalse + \csname\fontclass\fontbody \fontstyle \fontalternative \fontsize\endcsname + \else + \expandafter\fontclassstrategiesb + \fi} + +\def\fontclassstrategiesb % --- --- --- def % pt tt bf + {\ifcsname\fontclass\fontbody \fontstyle \fontalternative \defaultfontsize\endcsname + \autofontsizetrue + \csname\fontclass\fontbody \fontstyle \fontalternative \defaultfontsize\endcsname + \else + \expandafter\fontclassstrategiesc + \fi} + +\def\fontclassstrategiesc % --- --- def --- % pt tt tf a + {\ifcsname\fontclass\fontbody \fontstyle \defaultfontalternative \fontsize\endcsname + \autofontsizetrue + \csname\fontclass\fontbody \fontstyle \defaultfontalternative \fontsize\endcsname + \else + \expandafter\fontclassstrategiesd + \fi} + +\def\fontclassstrategiesd % --- --- def def % pt tt tf + {\ifcsname\fontclass\fontbody \fontstyle \defaultfontalternative \defaultfontsize\endcsname + \autofontsizetrue + \csname\fontclass\fontbody \fontstyle \defaultfontalternative \defaultfontsize\endcsname + \else + \expandafter\fontclassstrategiese + \fi} + +\def\fontclassstrategiese % --- def def def % pt rm tf + {\ifcsname\fontclass\fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname + \autofontsizefalse + \csname\fontclass\fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname + \else + \expandafter\fontclassstrategiesf + \fi} + +\def\fontclassstrategiesf % def def def def % rm tf + {\ifcsname\fontclass\defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname + \autofontsizetrue + \csname\fontclass\defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname + \else + \expandafter\fontstrategiesa + \fi} + +% no class + +\def\fontstrategiesa % --- --- --- --- % pt tt bf a + {\ifcsname\fontbody \fontstyle \fontalternative \fontsize\endcsname + \autofontsizefalse + \csname\fontbody \fontstyle \fontalternative \fontsize\endcsname + \else + \expandafter\fontstrategiesb + \fi} + +\def\fontstrategiesb % --- --- --- --- % pt tt bf a + {\ifcsname\fontbody \fontstyle \fontalternative \defaultfontsize\endcsname + \autofontsizetrue + \csname\fontbody \fontstyle \fontalternative \defaultfontsize\endcsname + \else + \expandafter\fontstrategiesc + \fi} + +\def\fontstrategiesc % --- --- --- --- % pt tt bf a + {\ifcsname\fontbody \fontstyle \defaultfontalternative \fontsize\endcsname + \autofontsizetrue + \csname\fontbody \fontstyle \defaultfontalternative \fontsize\endcsname + \else + \expandafter\fontstrategiesd + \fi} + +\def\fontstrategiesd % --- --- --- --- % pt tt bf a + {\ifcsname\fontbody \fontstyle \defaultfontalternative \defaultfontsize\endcsname + \autofontsizetrue + \csname\fontbody \fontstyle \defaultfontalternative \defaultfontsize\endcsname + \else + \expandafter\fontstrategiese + \fi} + +\def\fontstrategiese % --- --- --- --- % pt tt bf a + {\ifcsname\fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname + \autofontsizefalse + \csname\fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname + \else + \expandafter\fontstrategiesf + \fi} + +\def\fontstrategiesf % --- --- --- --- % pt tt bf a + {\ifcsname\defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname + \autofontsizetrue + \csname\defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname + \fi} + +\let\applyfontstrategies \fontstrategiesa +\let\applyfontclassstrategies\fontclassstrategiesa + +%D Let's synchronize: + +\newif\ifsynchronizefonts \synchronizefontstrue + +\prependtoks + \ifsynchronizefonts + \synchronizemath + \synchronizefont % problem: syncs last font + \fi +\to \everybodyfont + +%D Setting the normal sizes as well as the x and xx smaller +%D sizes is accomplished by the next set of macros. When in +%D math mode, the commands \type{\tx} and \type{\txx} are +%D just a switch to the script and double script styles, but +%D in text mode the values defined by the bodyfontenvironment are +%D used. Here we also set \type{\currentxfontsize}. + +\def\dosetcurrentfontxxxalternative#1#2#3#4% + {\chardef\currentxfontsize#2\relax + \ifmmode + #4% + \else\ifcsname\bodyfontvariable{\normalizedbodyfontsize#3}\endcsname + \setcurrentfontbodyalternative{\csname\bodyfontvariable\normalizedbodyfontsize#3\endcsname}{#1}% + \fi\fi} + +\def\setcurrentfontxalternative#1% + {\dosetcurrentfontxxxalternative{#1}1\c!x\scriptstyle + \let\tx\txx} + +\def\setcurrentfontxxalternative#1% + {\dosetcurrentfontxxxalternative{#1}2\c!xx\scriptscriptstyle + \let\tx\empty + \let\txx\empty} + +\def\checknestedxfontsize % option + {\ifcase\currentxfontsize\else\ifx\fontsize\empty\else + \chardef\currentxfontsize\zeropoint + \let\fontsize\empty + \let\tx\normaltx + \let\txx\normaltxx + \fi\fi} + +\def\setcurrentfontxalternative#1% + {\checknestedxfontsize + \dosetcurrentfontxxxalternative{#1}1\c!x\scriptstyle + \let\tx\txx} + +\def\setcurrentfontxxalternative#1% + {\checknestedxfontsize + \dosetcurrentfontxxxalternative{#1}2\c!xx\scriptscriptstyle + \let\tx\empty + \let\txx\empty} + +% 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\tx} +\def\setcurrentfontxxstylealternative#1{\csname#1\endcsname\txx} + +%D These macros also show us that when we call for \type{\tx}, +%D this macro is redefined to be \type{\txx}. Therefore calls +%D like: +%D +%D \startbuffer +%D {small \tx is \tx beautiful} +%D {small \tx is \txx beautiful} +%D {small \txx is \tx beautiful} +%D {small \txx is \txx beautiful} +%D \stopbuffer +%D +%D \typebuffer +%D +%D result in: +%D +%D \startvoorbeeld +%D \startlines +%D \getbuffer +%D \stoplines +%D \stopvoorbeeld +%D +%D Setting the main size involves the style list and therefore +%D takes a bit more time. Keep in mind that the fontsize is +%D represented by a character or empty. + +\unexpanded\def\tx {\setcurrentfontxalternative \fontalternative} +\unexpanded\def\txx{\setcurrentfontxxalternative\fontalternative} + +\let\normaltx \tx +\let\normaltxx\txx + +%D \macros +%D {definefontstyle} +%D +%D When setting of switching the overall style we can use the +%D short identifier like rm and ss, but when defined we can +%D also use more verbose names like roman or sansserif. Such +%D names are defined by: +%D +%D \starttyping +%D \definefontstyle [serif,rm] [rm] +%D \definefontstyle [sansserif,ss] [ss] +%D \stoptyping + +\def\dodefinefontstyle[#1][#2]% + {\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}% + \setvalue{\@style@##1}{\csname#2\endcsname}}% + \processcommalist[#1]\docommand} + +\unexpanded\def\definefontstyle + {\dodoubleargument\dodefinefontstyle} + +\def\setfontstyle#1#2% #1:name (roman, romaan) #2:style (rm) + {\edef\fontstyle{#1}% + \checkfontnamecombinations + \setcurrentfontstyle\normalizedbodyfontsize} + +%D When asking for a complete font switch, for instance from 10 +%D to 12~points, the next macro does the job. First we +%D normalize the size, next we define the current range of +%D text, script and scriptscript sizes, then we set the text +%D fonts and the math families and finally we activate the +%D default typeface and also set the font specific parameters +%D assigned to \type{\everybodyfont} + +\def\dosetbodyfontface#1#2% + {\edef#1{\csname\bodyfontvariable\normalizedbodyfontsize#2\endcsname}} + +\def\docompletefontswitch[#1]% + {\bodyfontsize#1\relax + \dimensiontocount\bodyfontsize\bodyfontpoints % rounded, still used in m-chart + \edef\bodyfontfactor{\withoutpt\the\bodyfontsize}% + \normalizebodyfontsize\bodyfontsize\to\normalizedbodyfontsize + \dosetbodyfontface \textface \s!text + \dosetbodyfontface \scriptface \s!script + \dosetbodyfontface \scriptscriptface \s!scriptscript} + +\docompletefontswitch[12pt] % init + +%D \macros +%D {setupbodyfont,switchtobodyfont} +%D +%D The next two macros are user ones. With \type{\setupbodyfont} +%D one can set the document bodyfont size, font family, style +%D and/or options defined in files, for example: +%D +%D \starttyping +%D \setupbodyfont[modern,12pt,roman] +%D \stoptyping +%D +%D This command affects the document as a whole: text, headers +%D and footers. The second macro however affects only the text: +%D +%D \starttyping +%D \switchtobodyfont[10pt] +%D \stoptyping +%D +%D So we've got: +%D +%D \showsetup{setupbodyfont} +%D \showsetup{switchtobodyfont} +%D +%D Both macros look alike. The second one also has to take +%D all kind of keywords into account. + +\ifx\saveinterlinespace \undefined \let\saveinterlinespace \relax \fi +\ifx\restoreinterlinespace\undefined \let\restoreinterlinespace\relax \fi + +% \newtoks \everysetupbodyfont +% \newtoks \everyswitchtobodyfont + +\chardef\bodyfontsetstate=0 + +\definecomplexorsimple\setupbodyfont + +\def\simplesetupbodyfont + {\restoreglobalbodyfont + \saveinterlinespace} + +\def\complexsetupbodyfont[#1]% + {\doifsomething{#1} + {\dosetfont1{#1}% + \globalbodyfontsize\localbodyfontsize + \normalizebodyfontsize\globalbodyfontsize\to\normalizedglobalbodyfontsize + \let\globalfontstyle\fontstyle + \ifloadingfonts\else + \the\everybodyfont + \the\everyglobalbodyfont + \saveinterlinespace + \fi + \the\everysetupbodyfont}} + +\unexpanded\def\switchtobodyfont[#1]% + {\doifsomething{#1} + {\ifcsname\??ft\normalizedbodyfontsize\interfaced{#1}\endcsname + \setbodyfontstep{#1}% so we have a fast [small] switch + \else + \dosetfont0{#1}% + \fi + \the\everybodyfont + \the\everyswitchtobodyfont}} + +%D The following alternative is meant for math||to||text +%D switching and will be optimized. + +\def\fastswitchtobodyfont#1% + {\ifcsname\??ft\normalizedbodyfontsize#1\endcsname + \edef\futurebodyfontsize{\csname\??ft\normalizedbodyfontsize#1\endcsname}% + \ifcsname\@size@\futurebodyfontsize\endcsname + \csname\@size@\futurebodyfontsize\endcsname + \localbodyfontsize\futurebodyfontsize\relax + \fi + \fi + \csname\@style@\fontstyle\endcsname + \the\everybodyfont} + +%D \starttyping +%D $\cases{& \ccaron}$ $x=\hbox{\ccaron $x=\hbox{\ccaron}$}$ +%D \stoptyping + +\def\setfontcharacteristics + {\the\everyfont} + +%D Predefined: + +% \installfontfeature[otf][tlig] +% \installfontfeature[otf][trep] + +%D tricky but ok: + +\appendtoks\ctxlua{fonts.tfm.cleanup()}\to\everyshipout + +%D Todo: + +% \def\os{\groupedcommand{\setfontfeature{oldstyle}}{}} + +%D Experimental: + +\unexpanded\def\definefontfeature + {\dotripleargument\dodefinefontfeature} + +\def\dodefinefontfeature[#1][#2][#3]% + {\global\expandafter\chardef\csname\??fq=#1\endcsname % beware () needed as we get two values returned + \ctxlua{tex.write((fonts.define.specify.preset_context("#1","#2","#3")))}\relax} + +\definefontfeature + [default] + [%mode=node, + liga=yes,kern=yes,tlig=yes,trep=yes] % texligatures=yes,texquotes=yes + +\definefontfeature + [smallcaps] + [%mode=node,liga=yes, + smcp=yes,kern=yes,tlig=yes,trep=yes] % texligatures=yes,texquotes=yes + +\definefontfeature + [oldstyle] + [%mode=node, + onum=yes,liga=yes,kern=yes,tlig=yes,trep=yes] % texligatures=yes,texquotes=yes + +\definefontfeature % == default unless redefined + [ligatures] + [%mode=node, + liga=yes,kern=yes,tlig=yes,trep=yes] + +\definefontfeature % can be used for type1 fonts + [complete] + [liga=yes,kern=yes,compose=yes,tlig=yes,trep=yes] + +\definefontfeature + [arabic] + [mode=node,language=dflt,script=arab,ccmp=yes, + init=yes,medi=yes,fina=yes,isol=yes, + liga=yes,dlig=yes,rlig=yes,clig=yes,calt=yes, + mark=yes,mkmk=yes,kern=yes,curs=yes] + +\definefontfeature + [none] + [mode=none,features=no] + +\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: + +\unexpanded\def\fontchar#1{\ctxlua{fonts.char("#1")}} + +\let\otfchar\fontchar % will disappear, for compatibility only +\let\afmchar\fontchar % will disappear, for compatibility only + +%D: We cannot yet inherit because no colors are predefined. + +\definecolor[font:init][r=.75] +\definecolor[font:medi][g=.75] +\definecolor[font:fina][b=.75] +\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! + +\def\installfontfeature + {\dodoubleargument\doinstallfontfeature} + +\def\doinstallfontfeature[#1][#2]% + {\writestatus\m!fonts{installing font features was experimental}} % \ctxlua{fonts.install_feature("#1","#2")}} + +%D Not yet in \MKII. + +\def\fontfeatureslist + {\dodoubleargument\dofontfeatureslist} + +\def\dofontfeatureslist[#1][#2]% todo: arg voor type + {\ctxlua{tex.sprint(tex.ctxcatcodes,fonts.define.specify.context_tostring("#1","otf","\luaescapestring{#2}","yes","no",true,{"number"}))}} + +\attribute\zerocount\zerocount % first in list, so fast match + +\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} % initial value + +\def\addfontfeaturetoset #1{\ctxlua{fonts.withset("#1", 1)}} % merge +\def\subtractfontfeaturefromset #1{\ctxlua{fonts.withset("#1",-1)}} % merge +\def\addfontfeaturetofont #1{\ctxlua{fonts.withfnt("#1", 2)}} % overload +\def\subtractfontfeaturefromfont#1{\ctxlua{fonts.withfnt("#1",-2)}} % overload + +\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}. + +\def\purefontname#1{\ctxlua{file.basename("\fontname#1"}} % will be function using id + +%D \macros +%D {switchstyleonly} +%D +%D For switching a style but keeping the alternative, there +%D is: +%D +%D \starttyping +%D {\bf text \switchstyleonly\ss text} +%D {\bf text \switchstyleonly[ss]text} +%D {\sl text \switchstyleonly[sansserif]text} +%D \stoptyping + +\definecomplexorsimple\switchstyleonly + +\def\simpleswitchstyleonly#1% stupid version + {\complexswitchstyleonly[\checkedstrippedcsname#1]} + +\def\complexswitchstyleonly[#1]% todo : check + {\setcurrentfontstyle{\csname\@shortstyle@#1\endcsname}% + \the\everybodyfont} % needed ? + +%D \macros +%D {os} +%D +%D In good old \TEX, the old style numerals were often taken +%D from the math fonts. No longer. + +\definefontfeature + [just-os] + [mode=node,onum=yes] + +% \def\sc{\setfontfeature{smallcaps}} +\unexpanded\def\os{\setfontfeature{just-os}} + +%D Code for switching to fraktur and script has also been +%D changed. We now have an alphabet switcher. + +\ifx\mathtext\undefined \let\mathtext\hbox \fi + +%D \macros +%D {definebodyfontswitch} +%D +%D \PLAIN\ \TEX\ defines some macro's like \type{\tenpoint} +%D to switch to a specific bodyfontsize. Just for the sake of +%D compatibility we can define them like: +%D +%D \starttyping +%D \definebodyfontswitch [twelvepoint] [12pt] +%D \stoptyping +%D +%D We don't support language specific synonyms here, mainly +%D because \PLAIN\ \TEX\ is english anyway. + +\def\dodefinebodyfontswitch[#1][#2]% + {\def\docommand##1{\setvalue{##1}{\switchtobodyfont[#2]}}% + \processcommalist[#1]\docommand} + +\unexpanded\def\definebodyfontswitch + {\dodoubleargument\dodefinebodyfontswitch} + +%D \macros +%D {setsmallbodyfont,setmainbodyfont,setbigbodyfont} +%D +%D When we're typesetting at for instance 10pt, we can call for +%D the \type{small} as well as the \type{big} alternative, +%D related to this main size, using \type{\switchtobodyfont[small]}. +%D The three alternatives can be activated by the next three +%D system calls and are defined by the bodyfontenvironment. + +\let\fontstep\empty % we can use \fontstep for tracing purposes + +\def\setbodyfontstep#1% + {\edef\fontstep{\csname\bodyfontvariable\normalizedbodyfontsize\interfaced{#1}\endcsname}% + \doswitchpoints[\fontstep]% + \doswitchstyle[\fontstyle]} + +\unexpanded\def\setsmallbodyfont{\setbodyfontstep\v!small\the\everybodyfont} +\unexpanded\def\setbigbodyfont {\setbodyfontstep\v!big \the\everybodyfont} + +\unexpanded\def\setmainbodyfont + {\doswitchpoints[\normalizedbodyfontsize]% + \doswitchstyle[\fontstyle]% + \the\everybodyfont + \the\everyglobalbodyfont + \saveinterlinespace} + +%D \macros +%D {restoreglobalbodyfont} +%D +%D Users can set whatever font available while typesetting text. +%D Pagenumbers, footers, headers etc. however must be typeset +%D in the main bodyfont and style of the document. Returning to +%D the global state can be done with the next macro: + +\let\globalfontstyle\c!rm + +\def\fullrestoreglobalbodyfont + {\let\fontsize\defaultfontsize + \let\fontbody\defaultfontbody + \chardef\currentxfontsize\zerocount + \let\fontclass\globalfontclass + \doswitchpoints[\normalizedglobalbodyfontsize]% + \doswitchstyle[\globalfontstyle]% + \redoconvertfont % just in case a pagebreak occurs + \tf + \the\everybodyfont + \the\everyglobalbodyfont + \saveinterlinespace} + +\def\partialrestoreglobalbodyfont + {\let\fontsize\defaultfontsize + \let\fontbody\defaultfontbody + \chardef\currentxfontsize\zerocount + \redoconvertfont + \tf + \the\everybodyfont % indeed needed + \the\everyglobalbodyfont % indeed needed + \saveinterlinespace} + +\def\restoreglobalbodyfont % ook style etc + {\ifx\fontclass\globalfontclass + \ifx\fontstyle\globalfontstyle + \ifx\normalizedbodyfontsize\normalizedglobalbodyfontsize + \partialrestoreglobalbodyfont + \else + \fullrestoreglobalbodyfont + \fi + \else + \fullrestoreglobalbodyfont + \fi + \else + \fullrestoreglobalbodyfont + \fi} + +% in case of troubles: \let\restorebodyfont\fullrestoreglobalbodyfont + +%D This macro has to be called when entering the pagebody +%D handling routine as well as the footnote insert routine. +%D Users can access this feature |<|for instance when one wants +%D to typeset tables and alike in the main bodyfont and style +%D while the running text is temporary set to a smaller one|>| +%D by saying \type{\switchtobodyfont[global]}. + +%D \macros +%D {rasterfont} +%D +%D There are (at the moment) two situations in which we want to +%D have fast access to a particular font. When we are using +%D \TEX\ to typeset rasters, we use small {\rasterfont.}'s +%D (a rather small period indeed), the same as \PICTEX\ uses +%D for drawing purposes. + +\definefont [rasterfont] [Serif at 5pt] + +%D \macros +%D {infofont} +%D +%D The second situation occurs when we enable the info mode, +%D and put all kind of status information in the margin. We +%D don't want huge switches to the main bodyfont and style, so +%D here too we use a direct method. + +\let\infofont\relax % satisfy dep checker + +\definefont [infofont] [Mono at 6pt] % todo \the\everybodyfont + +%D \macros +%D {definealternativestyle} +%D +%D In the main modules we are going to implement lots of +%D parameterized commands and one of these parameters will +%D concern the font to use. To suit consistent use of fonts we +%D here implement a mechanism for defining the keywords that +%D present a particular style or alternative. +%D +%D \starttyping +%D \definealternativestyle [keywords] [\style] [\nostyle] +%D \stoptyping +%D +%D The first command is used in the normal textflow, while the +%D second command takes care of headings and alike. Consider +%D the next two definitions: +%D +%D \starttyping +%D \definealternativestyle [bold] [\bf] [] +%D \definealternativestyle [cap] [\cap] [\cap] +%D \stoptyping +%D +%D A change \type{\bf} in a heading which is to be set in +%D \type{\tfd} does not look that well, so therefore we leave +%D the second argument of \type{\definealternativestyle} empty. +%D When we capatalize characters using the pseudo small cap +%D command \type{\cap}, we want this to take effect in both +%D text and headings, which is accomplished by assigning both +%D arguments. + +\def\dodefinealternativestyle[#1][#2][#3]% + {\def\docommand##1% + {\ifcsname##1\endcsname\else\setuvalue{##1}{\groupedcommand{#2}{}}\fi + \setvalue{\@letter@ ##1}{#2}% + \setvalue{\@noletter@##1}{#3}}% + \processcommalist[#1]\docommand} + +\unexpanded\def\definealternativestyle + {\dotripleempty\dodefinealternativestyle} + +\unexpanded\def\definestyle{\definealternativestyle} + +%D Maybe too geneneric, but probably ok is the following. (Maybe one +%D day we will use a dedicated grouped command for styles.) + +\appendtoks + \let\groupedcommand\thirdofthreearguments +\to \simplifiedcommands + +%D This command also defines the keyword as command. This means +%D that the example definition of \type{bold} we gave before, +%D results in a command \type{\bold} which can be used as: +%D +%D \startbuffer +%D He's a \bold{bold} man with a {\bold head}. +%D \stopbuffer +%D +%D \typebuffer +%D +%D or +%D +%D \startvoorbeeld +%D \definealternativestyle[bold][\bf][]\getbuffer +%D \stopvoorbeeld +%D +%D Such definitions are of course unwanted for \type{\cap} +%D because this would result in an endless recursive call. +%D Therefore we check on the existance of both the command and +%D the substitution. The latter is needed because for instance +%D \type{\type} is an entirely diferent command. That command +%D handles verbatim, while the style command would just switch +%D to teletype font. This is just an example of a tricky +%D naming coincidence. + +%D \macros +%D {doconvertfont,noconvertfont, +%D dontconvertfont,redoconvertfont} +%D +%D After having defined such keywords, we can call for them by +%D using +%D +%D \starttyping +%D \doconvertfont{keyword}{text} +%D \stoptyping +%D +%D We deliberately pass an argument. This enables us to +%D assign converters that handle one argument, like +%D \type{\cap}. +%D +%D By default the first specification is used to set the style, +%D exept when we say \type{\dontconvertfont}, after which the +%D second specification is used. We can also directly call for +%D \type{\noconvertfont}. In nested calls, we can restore the +%D conversion by saying \type{\redoconvertfont}. + +% subtle ... \expandafter is needed else problems with lookahead caps + +\def\@@dodoconvertfont{\csname\@letter@ \p!defined\expandafter\endcsname\gobbleoneargument} +\def\@@donoconvertfont{\csname\@noletter@\p!defined\endcsname} +\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 + +\unexpanded\def\dodoconvertfont#1% #2% we need the protection + {\edef\p!defined{#1}% + \ifx\p!defined\empty\else + \@EA\dododoconvertfont + \fi{#1}} + +\def\dododoconvertfont % #1 + {\ifcsname\@letter@\detokenize\@EA{\p!defined}\endcsname + \@EA\@@dodoconvertfont + \else\ifcsname\detokenize\@EA{\p!defined}\endcsname + \@EAEAEA\@@redoconvertfont + \else + \@EAEAEA\firstofoneargument + \fi\fi} % {#1} + +\let\doconvertfont\dodoconvertfont + +\unexpanded\def\noconvertfont#1% #2% + {\edef\p!defined{#1}% + \ifx\p!defined\empty + \else + \@EA\nononoconvertfont + \fi} + +\def\nononoconvertfont + {\ifcsname\@noletter@\detokenize\@EA{\p!defined}\endcsname + \@EA\@@donoconvertfont + \fi} + +%D Extras: + +\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 +%D overhead. + +%D \macros +%D {em,emphasistypeface,emphasisboldface} +%D +%D The next macro started as a copy of Donald Arseneau's +%D \type{\em} (\TUGNEWS\ Vol.~3, no.~1, 1994). His +%D implementation was a bit more sophisticated version of the +%D standard \LATEX\ one. We furter enhanced the macro, so now +%D it also adapts itself to boldface mode. Because we favor +%D {\sl slanted} type over {\it italic}, we made the emphasis +%D adaptable, for instance: +%D +%D \starttyping +%D \def\emphasistypeface {\it} +%D \def\emphasisboldface {\bi} +%D \stoptyping +%D +%D But we prefer: + +\def\emphasistypeface {\sl} +\def\emphasisboldface {\bs} + +%D or even better: + +\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} + +%D To be set with the default body font environment: \type +%D {em} being \type {slanted} or \type {italic}. + +\newconditional\emneeded + +\newtoks\everyemphasized + +\unexpanded\def\em + {\relax + \ifdim\slantperpoint>\zeropoint + \settrue\emneeded + \else + \setfalse\emneeded + \fi + \setemphasisboldface % new + \ifx\fontalternative\c!it + \def\emphasistypeface{\it}\tf + \else\ifx\fontalternative\c!sl + \def\emphasistypeface{\sl}\tf + \else\ifx\fontalternative\c!bf + \emphasisboldface + \else\ifx\fontalternative\c!bs + \def\emphasisboldface{\bs}\bf + \else\ifx\fontalternative\c!bi + \def\emphasisboldface{\bi}\bf + \else + \emphasistypeface + \fi\fi\fi\fi\fi + \the\everyemphasized + \ifconditional\emneeded\relax + \else + \expandafter\aftergroup + \fi + \emphasiscorrection} + +% compare ... +% +% \appendtoks \red \to \everyemphasized +% \setupbodyfontenvironment [default] [em={\italic\color[red]}] + +%D The next feature was not present in previous versions. It +%D takes care of \type {\em \bf ...} sitiations. + +\def\setemphasisboldface + {\let\savedemphasisboldface\bf + \let\setemphasisboldface\relax + \unexpanded\def\bf + {%\relax + \let\bf\relax % new + \ifx\fontalternative\c!it + \bi + \else\ifx\fontalternative\c!sl + \bs + \else + \savedemphasisboldface + \fi\fi + \let\bf\savedemphasisboldface}} + +%D Donald's (adapted) macros take the next character into +%D account when placing italic correction. As a bonus we also +%D look for something that looks like a dash, in which case we +%D don't correct. + +\let\italiccorrection=\/ % tex primitive + +\def\emphasiscorrection + {\ifhmode + \expandafter\emphasislook + \fi} + +\def\emphasislook + {\begingroup + \futurelet\next\emphasistest} + +\def\emphasistest + {\ifcat\noexpand\next,% still ok? + \expandafter\doemphasiscorrection + \else + \expandafter\dododoemphasiscorrection + \fi} + +\def\doemphasiscorrection + {\futurelet\next\dodoemphasiscorrection} + +\def\dodoemphasiscorrection + {\setbox\scratchbox\hbox{\next}% + \ifdim\ht\scratchbox=\zeropoint % probably a space + \expandafter\dododoemphasiscorrection + \else\ifdim\ht\scratchbox<.3ex + \expandafter\expandafter\expandafter\endgroup + \else + \expandafter\expandafter\expandafter\dododoemphasiscorrection + \fi\fi} + +\def\dododoemphasiscorrection + {\scratchskip\lastskip + \ifdim\scratchskip=\zeropoint\relax % == \ifzeropt\scratchskip + \italiccorrection\relax + \else + \unskip\italiccorrection\hskip\scratchskip + \fi + \endgroup} + +%D We end with some examples which show the behavior when +%D some punctuation is met. We also show how the mechanism +%D adapts itself to bold, italic and slanted typing. +%D +%D \startbuffer +%D test {test}test \par +%D test {\sl test}test \par +%D test {\em test}test \par +%D test {\em test}--test \par +%D +%D test {test}, test \par +%D test {\em test}, test \par +%D +%D test {\em test {\em test {\em test} test} test} test \par +%D test {\bf test {\em test {\em test} test} test} test \par +%D test {\sl test {\em test {\em test} test} test} test \par +%D test {\it test {\em test {\em test} test} test} test \par +%D \stopbuffer +%D +%D \typebuffer +%D +%D We get: +%D +%D \startvoorbeeld +%D \startpacked +%D \getbuffer +%D \stoppacked +%D \stopvoorbeeld + +%D \macros +%D {emphbf,emphit,emphsl,emphtf} +%D +%D The next emphasis alternatives are for \THANH. They adapt +%D their style as good as possible. + +\def\emphbf{\groupedcommand{\bf\def\emphit{\bi}\def\emphsl{\bs}}{}} +\def\emphit{\groupedcommand{\it\def\emphbf{\bi}\def\emphsl{\sl}}{}} +\def\emphsl{\groupedcommand{\sl\def\emphbf{\bs}\def\emphit{\it}}{}} +\def\emphtf{\groupedcommand{\tf\def\emphbf{\bf}\def\emphit{\it}\def\emphsl{\sl}}{}} + +%D \startbuffer +%D TEXT {\emphbf text \emphit text \emphtf text \emphsl text} TEXT +%D TEXT \emphbf{text \emphit{text} \emphtf{text} \emphsl{text}} TEXT +%D \stopbuffer +%D +%D \typebuffer +%D \startlines +%D \getbuffer +%D \stoplines + +%D \macros +%D {setfont} +%D +%D Every now and then we want to define a font directly, for +%D instance when we typeset title pages. The next macro saves +%D some typing: + +\def\setfont% geen \dosetfont mogelijk + {\def\next{\nextfont\setupinterlinespace}% hm, we need to use \setuplocalinterlinespace + \afterassignment\next\font\nextfont=} + +%D One can call this macro as: +%D +%D \starttyping +%D \setfont cmr10 at 60pt +%D \stoptyping +%D +%D After which the font is active and the baselines and +%D struts are set. + +%D \macros +%D {showbodyfont} +%D +%D One can call for a rather simple overview of a bodyfont and the +%D relations between its alternative fonts. +%D +%D \showsetup{showbodyfont} +%D +%D The current bodyfont (here we omitted the argument) looks like: +%D +%D \showbodyfont +%D +%D The implementation is rather straightforward in using +%D \type{\halign}. + +\fetchruntimecommand \showbodyfont {\f!fontprefix\s!run.mkiv} + +%D \macros +%D {showfontstrip, testminimalbaseline, showminimalbaseline} +%D +%D The next command can come in handy when combining +%D different fonts into a collection (typeface) and +%D determining optimal baseline distances. +%D +%D \showfontstrip \blank \showminimalbaseline + +\fetchruntimecommand \showfontstrip {\f!fontprefix\s!run.mkiv} +\fetchruntimecommand \testminimalbaseline {\f!fontprefix\s!run.mkiv} +\fetchruntimecommand \showminimalbaseline {\f!fontprefix\s!run.mkiv} + +%D \macros +%D {showkerning} +%D +%D A goody is: +%D +%D \showkerning{Can you guess what kerning is?} + +\fetchruntimecommand \showkerning {\f!fontprefix\s!run.mkiv} + +%D \macros +%D {showbodyfontenvironment} +%D +%D The current bodyfontenvironment is: +%D +%D \showbodyfontenvironment +%D +%D This overview is generated using: +%D +%D \showsetup{showbodyfontenvironment} + +\fetchruntimecommand \showbodyfontenvironment {\f!fontprefix\s!run.mkiv} + +%D \macros +%D {showfont,showfontstyle,showligatures} +%D +%D The following command generates a fontmap: +%D +%D \startbuffer +%D \showfont[SansBold at 12pt] +%D \stopbuffer +%D +%D \typebuffer +%D \getbuffer + +% to be internationalized + +\fetchruntimecommand \showfont {\f!fontprefix\s!run.mkiv} +\fetchruntimecommand \showfontstyle {\f!fontprefix\s!run.mkiv} +\fetchruntimecommand \showligature {\f!fontprefix\s!run.mkiv} +\fetchruntimecommand \showligatures {\f!fontprefix\s!run.mkiv} +\fetchruntimecommand \showcharratio {\f!fontprefix\s!run.mkiv} + +%D \macros +%D {getglyph, symbolicfont} +%D +%D Individual glyphs can be accessed by using +%D +%D \starttyping +%D \getglyph{fontname}{character} +%D \stoptyping +%D +%D This macro is used in for instance the symbol modules and +%D as one can see, it does obey the small and even smaller +%D sizes. The \type {\symbolicfont} macro can be used to +%D switch to a font named \type {fontname} (see \type +%D {cont-log} and \type {symb-eur} for examples of symbolic +%D definitions. + +\def\fontstringA + {\ifx\fontstyle\c!rm \s!Serif \else + \ifx\fontstyle\c!ss \s!Sans \else + \ifx\fontstyle\c!tt \s!Mono \else + \s!Serif \fi\fi\fi} + +\def\fontstringB + {\ifx\fontstyle\c!rm \s!Regular \else + \ifx\fontstyle\c!ss \s!Support \else + \ifx\fontstyle\c!tt \s!Type \else + \s!Serif \fi\fi\fi} + +\def\fontstringC + {\ifx\fontalternative\c!bf \s!Bold \else + \ifx\fontalternative\c!sl \s!Slanted \else + \ifx\fontalternative\c!it \s!Italic \else + \ifx\fontalternative\c!bs \s!BoldSlanted \else + \ifx\fontalternative\c!bi \s!BoldItalic \fi\fi\fi\fi\fi} + +\def\fontstringD % default fontstyle + {\expandafter\ifx\csname\??tf\fontclass\s!default\endcsname\c!rm \s!Serif \else + \expandafter\ifx\csname\??tf\fontclass\s!default\endcsname\c!ss \s!Sans \else + \expandafter\ifx\csname\??tf\fontclass\s!default\endcsname\c!tt \s!Mono \else + \s!Serif \fi\fi\fi} + +% potential generalization: + +% \letvalue{\??ff:t:\c!rm}\s!Serif +% \letvalue{\??ff:t:\c!ss}\s!Sans +% \letvalue{\??ff:t:\c!tt}\s!Mono +% +% \letvalue{\??ff:s:\c!bf}\s!Bold +% \letvalue{\??ff:s:\c!sl}\s!Slanted +% \letvalue{\??ff:s:\c!it}\s!Italic +% \letvalue{\??ff:s:\c!bs}\s!BoldSlanted +% \letvalue{\??ff:s:\c!bi}\s!BoldItalic +% +% \letvalue{\??ff:a:\c!rm}\s!Regular +% \letvalue{\??ff:a:\c!ss}\s!Support +% \letvalue{\??ff:a:\c!tt}\s!Type +% +% \def\fontstringA{\executeifdefined{\??ff:t:\fontstyle}\s!Serif} +% \def\fontstringB{\executeifdefined{\??ff:a:\fontstyle}\s!Serif} +% \def\fontstringC{\executeifdefined{\??ff:s:\fontstyle}\empty} +% \def\fontstringD{\executeifdefined{\??ff:t:\csname\??tf\fontclass\s!default\endcsname}\s!Serif} + +\def\glyphfontfile#1% + {#1% + \ifcsname\??ff#1\fontstringA\fontstringC\endcsname + \fontstringA\fontstringC + \else\ifcsname\??ff#1\fontstringB\fontstringC\endcsname + \fontstringB\fontstringC + \else\ifcsname\??ff#1\fontstringA\endcsname + \fontstringA + \else\ifcsname\??ff#1\fontstringB\endcsname + \fontstringB + \else\ifcsname\??ff#1\fontstringC\endcsname + \fontstringC + \fi\fi\fi\fi\fi} + +%D The next macro can be used to make decisions based on the shape: + +\def\doifitalicelse#1#2% + {\ifx\fontalternative\c!sl#1\else + \ifx\fontalternative\c!it#1\else + \ifx\fontalternative\c!bs#1\else + \ifx\fontalternative\c!bi#1\else#2\fi\fi\fi\fi} + +%D For an example of usage of the following command, +%D see \type {cont-log.tex}. +%D +%D \starttyping +%D \def\symbolicfont#1{\definedfont[\glyphfontfile{#1} sa *]} +%D \stoptyping +%D +%D Since we know what scaling it to be applied, we can +%D implement a much faster alternative: + +\let\thedefinedfont\relax + +\def\symbolicsizedfont#1#2#3% + {\scaledfontsize#1% + \scaledfontsize#2\scaledfontsize + \font\thedefinedfont=\truefontname{\glyphfontfile{#3}} at \currentfontbodyscale\scaledfontsize\relax + \thedefinedfont} + +\def\symbolicscaledfont + {\symbolicsizedfont\fontbody} + +\unexpanded\def\symbolicfont + {\symbolicsizedfont\fontbody\plusone} + +\unexpanded\def\getglyph#1#2% slow, faster, much faster + %{{\definefont[\s!dummy][\glyphfontfile{#1} sa \currentfontscale]\dummy#2}} + %{{\definefont[\s!dummy][\glyphfontfile{#1} sa *]\dummy#2}} + %{{\symbolicfont{#1}#2}} + {{\symbolicfont{#1}\doifnumberelse{#2}\char\donothing#2}} + +\unexpanded\def\getscaledglyph#1#2#3% + {{\symbolicscaledfont{#1}{#2}\doifnumberelse{#3}\char\donothing#3}} + +\unexpanded\def\getrawglyph#1#2% for simple symbols + {{\scaledfontsize\fontbody + \font\thedefinedfont=#1 at \currentfontbodyscale\scaledfontsize\relax + \thedefinedfont\doifnumberelse{#2}\char\donothing#2}} + +%D The last implementation of \type {\getglyph} permits +%D definitions like: +%D +%D \starttyping +%D \definefontsynonym [EuroSans] [eurose] +%D \definefontsynonym [EuroSansBold] [euroseb] +%D \definefontsynonym [EuroSansItalic] [eurosei] +%D \definefontsynonym [EuroSansSlanted] [eurosei] +%D \definefontsynonym [EuroSansBoldItalic] [eurosebi] +%D \definefontsynonym [EuroSansBoldSlanted] [eurosebi] +%D +%D \definesymbol [euro] [\getglyph{Euro}{\char160}] +%D +%D \def\euro{\symbol[euro]} +%D \stoptyping +%D +%D These definitions guarantee that the next calls work okay: +%D +%D \starttyping +%D \ss \tf\euro \bf\euro \sla\euro \itd\euro \bs\euro \bic\euro +%D \stoptyping +%D +%D The shape as well as the size is adapted to the current +%D environment. + +%D \macros +%D {ss, SS, sz} +%D +%D We are going to redefine \type{\ss} but for those wo still +%D want to have access to the german \SS, we save it's value in +%D \type{\SS}. Ok, I should have used \type{\sf} instead of +%D \type{\ss} in the first place. + +\ifx\undefined\SS \let\SS=\ss \fi +\ifx\undefined\sz \let\sz=\ss \fi + +%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] +%D \stoptyping +%D +%D combined with for instance: +%D +%D \starttyping +%D \definefontsynonym [Times-Roman] [tir] +%D \stoptyping + +%D Now we're up to some definitions. + +\definebodyfontenvironment + [\s!default] + [ \s!text=1.0, + \s!script=0.7, + \s!scriptscript=0.5, + \c!a=1.200, + \c!b=1.440, + \c!c=1.728, + \c!d=2.074, + *=\currentfontscale, % wildcard + \c!x=0.8, + \c!xx=0.6, + \c!big=1.2, + \c!small=0.8, + \c!interlinespace=, + \c!em=\v!slanted] + +\definebodyfontenvironment + [20.7pt] + [ \s!text=20.7pt, + \s!script=\!!fourteenpointfour, + \s!scriptscript=\!!twelvepoint, + \c!x=17.3pt, + \c!xx=\!!fourteenpointfour, + \c!big=20.7pt, % !!!! + \c!small=17.3pt] + +\definebodyfontenvironment + [17.3pt] + [ \s!text=17.3pt, + \s!script=\!!twelvepoint, + \s!scriptscript=\!!tenpoint, + \c!x=\!!fourteenpointfour, + \c!xx=\!!twelvepoint, + \c!big=20.7pt, + \c!small=\!!fourteenpointfour] + +\definebodyfontenvironment + [\!!fourteenpointfour] + [ \s!text=\!!fourteenpointfour, + \s!script=\!!elevenpoint, + \s!scriptscript=\!!ninepoint, + \c!x=\!!twelvepoint, + \c!xx=\!!tenpoint, + \c!big=17.3pt, + \c!small=\!!twelvepoint] + +\definebodyfontenvironment + [\!!twelvepoint] + [ \s!text=\!!twelvepoint, + \s!script=\!!ninepoint, + \s!scriptscript=\!!sevenpoint, + \c!x=\!!tenpoint, + \c!xx=\!!eightpoint, + \c!big=\!!fourteenpointfour, + \c!small=\!!tenpoint] + +\definebodyfontenvironment + [\!!elevenpoint] + [ \s!text=\!!elevenpoint, + \s!script=\!!eightpoint, + \s!scriptscript=\!!sixpoint, + \c!x=\!!ninepoint, + \c!xx=\!!sevenpoint, + \c!big=\!!twelvepoint, + \c!small=\!!ninepoint] + +\definebodyfontenvironment + [\!!tenpoint] + [ \s!text=\!!tenpoint, + \s!script=\!!sevenpoint, + \s!scriptscript=\!!fivepoint, + \c!x=\!!eightpoint, + \c!xx=\!!sixpoint, + \c!big=\!!twelvepoint, + \c!small=\!!eightpoint] + +\definebodyfontenvironment + [\!!ninepoint] + [ \s!text=\!!ninepoint, + \s!script=\!!sevenpoint, + \s!scriptscript=\!!fivepoint, + \c!x=\!!sevenpoint, + \c!xx=\!!fivepoint, + \c!big=\!!elevenpoint, + \c!small=\!!sevenpoint] + +\definebodyfontenvironment + [\!!eightpoint] + [ \s!text=\!!eightpoint, + \s!script=\!!sixpoint, + \s!scriptscript=\!!fivepoint, + \c!x=\!!sixpoint, + \c!xx=\!!fivepoint, + \c!big=\!!tenpoint, + \c!small=\!!sixpoint] + +\definebodyfontenvironment + [\!!sevenpoint] + [ \s!text=\!!sevenpoint, + \s!script=\!!sixpoint, + \s!scriptscript=\!!fivepoint, + \c!x=\!!sixpoint, + \c!xx=\!!fivepoint, + \c!big=\!!ninepoint, + \c!small=\!!fivepoint] + +\definebodyfontenvironment + [\!!sixpoint] + [ \s!text=\!!sixpoint, + \s!script=\!!fivepoint, + \s!scriptscript=\!!fivepoint, + \c!x=\!!fivepoint, + \c!xx=\!!fivepoint, + \c!big=\!!eightpoint, + \c!small=\!!fivepoint] + +\definebodyfontenvironment + [\!!fivepoint] + [ \s!text=\!!fivepoint, + \s!script=\!!fivepoint, + \s!scriptscript=\!!fivepoint, + \c!x=\!!fivepoint, + \c!xx=\!!fivepoint, + \c!big=\!!sevenpoint, + \c!small=\!!fivepoint] + +\definebodyfontenvironment + [\!!fourpoint] + [ \s!text=\!!fourpoint, + \s!script=\!!fourpoint, + \s!scriptscript=\!!fourpoint, + \c!x=\!!fourpoint, + \c!xx=\!!fourpoint, + \c!big=\!!sixpoint, + \c!small=\!!fourpoint] + +\definebodyfontswitch [fourteenpointfour] [\!!fourteenpointfour] +\definebodyfontswitch [twelvepoint] [\!!twelvepoint] +\definebodyfontswitch [elevenpoint] [\!!elevenpoint] +\definebodyfontswitch [tenpoint] [\!!tenpoint] +\definebodyfontswitch [ninepoint] [\!!ninepoint] +\definebodyfontswitch [eightpoint] [\!!eightpoint] +\definebodyfontswitch [sevenpoint] [\!!sevenpoint] +\definebodyfontswitch [sixpoint] [\!!sixpoint] +\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] + +%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] + +\definealternativestyle [\v!mediaeval] [\os] [] +\definealternativestyle [\v!normal] [\tf] [] +\definealternativestyle [\v!bold] [\bf] [] +\definealternativestyle [\v!type] [\tt] [] +\definealternativestyle [\v!mono] [\tt] [] +\definealternativestyle [\v!slanted] [\sl] [] +\definealternativestyle [\v!italic] [\it] [] +\definealternativestyle [\v!boldslanted,\v!slantedbold] [\bs] [] +\definealternativestyle [\v!bolditalic,\v!italicbold] [\bi] [] +\definealternativestyle [\v!small,\v!smallnormal] [\tfx] [] +\definealternativestyle [\v!smallbold] [\bfx] [] +\definealternativestyle [\v!smalltype] [\ttx] [] +\definealternativestyle [\v!smallslanted] [\slx] [] +\definealternativestyle [\v!smallboldslanted,\v!smallslantedbold] [\bsx] [] +\definealternativestyle [\v!smallbolditalic,\v!smallitalicbold] [\bix] [] + +\definealternativestyle [\v!sans,\v!sansserif] [\ss] [] +\definealternativestyle [\v!sansbold] [\ss\bf] [] + +%D Slow but handy: + +\definealternativestyle [\v!smallbodyfont] [\setsmallbodyfont] [] +\definealternativestyle [\v!bigbodyfont] [\setbigbodyfont] [] + +%D We treat {\sc Small Caps} and \cap {Pseudo Caps} a bit +%D different. We also provide an \WORD {uppercase} style. + +\definealternativestyle [\v!cap,\v!capital] [\smallcapped] [\smallcapped] +\definealternativestyle [\v!smallcaps] [\sc] [\sc] +\definealternativestyle [\v!WORD] [\WORD] [\WORD] + +%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% why the \s!Regular ? see \getglyph + {\ifx\fontalternative\c!tf \s!Regular \else + \ifx\fontalternative\c!bf \s!Bold \else + \ifx\fontalternative\c!sl \s!Slanted \else + \ifx\fontalternative\c!it \s!Italic \else + \ifx\fontalternative\c!bs \s!BoldSlanted \else + \ifx\fontalternative\c!bi \s!BoldItalic \else + \ifx\fontalternative\c!sc \s!Caps \else + \s!Regular \fi\fi\fi\fi\fi\fi\fi}% + +%D \macros +%D {definefontvariant,fontvariant,variant} +%D +%D This command is obsolete in \MKIV\ as we have features. It might +%D come back using the local features handlers. + +\unexpanded\def\definefontvariant{\dotripleargument\dodefinefontvariant} + +\def\dodefinefontvariant[#1][#2][#3]{} +\def\variant [#1]{} + +\ifdefined\Var\else \let\Var\variant \fi + +%D By default we load the Computer Modern Roman fonts (but +%D not yet at this moment) and activate the 12pt roman +%D bodyfont. Sans serif and teletype are also available and +%D can be called for by \type{\ss} and \type{\tt}. Loading +%D takes place elsewhere. +%D +%D For tracing purposes we define: + +\definefont[tinyfont][Mono at 1ex] + +% \tracinglostchars=1 + +% this needs some interfacing +% +% \setupfonts[check=...] + +\def\checkcharactersinfont {\ctxlua{fonts.checkers.enable()}} +\def\removemissingcharacters{\ctxlua{fonts.checkers.enable(true)}} + +%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}{}} + +\unexpanded\def\startstyle[#1]% + {\begingroup + \ifcsname#1\endcsname\csname#1\endcsname\else\definedfont[#1]\fi} + +\unexpanded\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}} + +\unexpanded\def\definestylecollection + {\dosingleargument\dodefinestylecollection} + +\def\dodefinestylecollection[#1]% + {\iffirstargument + \setuvalue{#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} + +\unexpanded\def\definestyleinstance + {\doquadrupleargument\dodefinestyleinstance} + +\def\dodefinestyleinstance[#1][#2][#3][#4]% [name] [rm|ss|tt|..] [sl|bf|...] [whatever] + {\iffirstargument + \ifcsname#1\endcsname\else\definestylecollection[#1]\fi + \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 made 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} + +%D goodies: + +\def\showchardata#1{\ctxlua{fonts.show_char_data("#1")}} +\def\showfontdata {\ctxlua{fonts.show_font_parameters()}} + +%D some low level helpers +%D +%D \starttyping +%D \def\TestLookup#1% +%D {\dolookupfontbyspec{#1} +%D pattern: #1, found: \dolookupnoffound +%D \blank +%D \dorecurse {\dolookupnoffound} {% +%D \recurselevel:~\dolookupgetkeyofindex{fontname}{\recurselevel}\quad +%D }% +%D \blank} +%D +%D \TestLookup{familyname=helveticaneue} +%D \TestLookup{familyname=helveticaneue,weight=bold} +%D \TestLookup{familyname=helveticaneue,weight=bold,style=italic} +%D \stoptyping + +% we can also move the lookups to the fonts.namespace (of commands) + +\def\dolookupfontbyspec #1{\ctxlua{fonts.names.lookup("#1")}} +\def\dolookupnoffound {\ctxlua{tex.write(fonts.names.noflookups())}} +\def\dolookupgetkeyofindex#1#2{\ctxlua{tex.write(fonts.names.getlookupkey("#1",#2))}} +\def\dolookupgetkey #1{\ctxlua{tex.write(fonts.names.getlookupkey("#1"))}} +\def\cleanfontname #1{\ctxlua{fonts.cleanname("#1")}} + +\protect \endinput + +% \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.mkii b/tex/context/base/font-jap.mkii new file mode 100644 index 000000000..42480df43 --- /dev/null +++ b/tex/context/base/font-jap.mkii @@ -0,0 +1,83 @@ +%D \module +%D [ file=font-jap, +%D version=2006.01.13, +%D title=\CONTEXT\ Font Macros, +%D subtitle=Japanese, +%D author=Hans Hagen, +%D date=\currentdate, +%D suggestions=Wang Lei, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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\handlejapaneseunicodeglyph\undefined \else \endinput \fi +\ifx\handlechineseunicodeglyph \undefined \input font-chi.tex \fi + +\writestatus{loading}{ConTeXt Font Macros / Japanese} + +\unprotect + +\newif\iftracejapanese + +\let\japaneseencoding\empty + +\def\setjapaneseencoding + {\getfontfileparameters\unicodestyle + \ifx\currentfontfileencoding\undefined \else + \let\japaneseencoding\currentfontfileencoding + \fi} + +\def\japaneseunicodescale {\chineseunicodescale } +\def\japaneseunicodeheight {\chineseunicodeheight } +\def\japaneseunicodedepth {\chineseunicodedepth } +\def\japaneseinterglyphskip{\chineseinterglyphskip} +\def\japanesesurroundskip {\chinesesurroundskip } + +\setupunicodefont + [japanese] + [ \c!scale=\japaneseunicodescale, + \c!height=\japaneseunicodeheight, + \c!depth=\japaneseunicodedepth, + \c!strut=\v!yes, + \c!interlinespace=\v!yes, + \c!conversion=\japanesenumber, + \c!commands=\setjapaneseencoding, % needed for digits + \c!command=\handlejapaneseunicodeglyph] + +\def\japanesenumber{\numbers} + +\def\handlejapaneseunicodeglyph + {\begingroup +% \let\chineseunicodescale \japaneseunicodescale +% \let\chineseunicodeheight \japaneseunicodeheight +% \let\chineseunicodedepth \japaneseunicodedepth +% \let\chineseinterglyphskip\japaneseinterglyphskip +% \let\chinesesurroundskip \japanesesurroundskip + \iftracejapanese\tracechinesetrue\else\tracechinesefalse\fi + \handlechineseunicodeglyph + \endgroup} + +\doifelse \currentregime {utf} { + + % todo: typescripts + + \definefontsynonym [JapaneseRegular] [uni-cybercjk-][encoding=cjk-uni] + \definefontsynonym [JapaneseSlanted] [uni-cybercjk-][encoding=cjk-uni] + \definefontsynonym [JapaneseItalic] [uni-cybercjk-][encoding=cjk-uni] + \definefontsynonym [JapaneseBold] [uni-cybercjk-][encoding=cjk-uni] + \definefontsynonym [JapaneseBoldSlanted][uni-cybercjk-][encoding=cjk-uni] + \definefontsynonym [JapaneseBoldItalic] [uni-cybercjk-][encoding=cjk-uni] + + \loadmapfile[uni-cybercjk.map] + + \defineunicodefont [Japanese] [Japanese] [japanese] + +} { + \writestatus{Japanese}{No fonts defined} +} + +\Japanese + +\protect \endinput diff --git a/tex/context/base/font-log.lua b/tex/context/base/font-log.lua new file mode 100644 index 000000000..97cb4ff7c --- /dev/null +++ b/tex/context/base/font-log.lua @@ -0,0 +1,58 @@ +if not modules then modules = { } end modules ['font-log'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local next, format, lower, concat = next, string.format, string.lower, table.concat + +local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) + +fonts.logger = fonts.logger or { } + +--[[ldx-- +<p>The following functions are used for reporting about the fonts +used. The message itself is not that useful in regular runs but since +we now have several readers it may be handy to know what reader is +used for which font.</p> +--ldx]]-- + +function fonts.logger.save(tfmtable,source,specification) -- save file name in spec here ! ! ! ! ! ! + if tfmtable and specification and specification.specification then + local name = lower(specification.name) + if trace_defining and not fonts.used[name] then + logs.report("define font","registering %s as %s (used: %s)",file.basename(specification.name),source,file.basename(specification.filename)) + end + specification.source = source + fonts.loaded[lower(specification.specification)] = specification + -- fonts.used[name] = source + fonts.used[lower(specification.filename or specification.name)] = source + end +end + +function fonts.logger.report(complete) + local t = { } + for name, used in table.sortedhash(fonts.used) do + if complete then + t[#t+1] = used .. "->" .. file.basename(name) + else + t[#t+1] = file.basename(name) + end + 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() + 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 new file mode 100644 index 000000000..299508764 --- /dev/null +++ b/tex/context/base/font-map.lua @@ -0,0 +1,370 @@ +if not modules then modules = { } end modules ['font-map'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local utf = unicode.utf8 +local match, format, find, concat, gsub, lower = string.match, string.format, string.find, table.concat, string.gsub, string.lower +local lpegmatch = lpeg.match +local utfbyte = utf.byte + +local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end) +local trace_unimapping = false trackers.register("otf.unimapping", function(v) trace_unimapping = v end) + +local ctxcatcodes = tex and tex.ctxcatcodes + +--[[ldx-- +<p>Eventually this code will disappear because map files are kind +of obsolete. Some code may move to runtime or auxiliary modules.</p> +<p>The name to unciode related code will stay of course.</p> +--ldx]]-- + +fonts = fonts or { } +fonts.map = fonts.map or { } + +local function load_lum_table(filename) -- will move to font goodies + local lumname = file.replacesuffix(file.basename(filename),"lum") + local lumfile = resolvers.find_file(lumname,"map") or "" + if lumfile ~= "" and lfs.isfile(lumfile) then + if trace_loading or trace_unimapping then + logs.report("load otf","enhance: loading %s ",lumfile) + end + lumunic = dofile(lumfile) + return lumunic, lumfile + end +end + +local hex = lpeg.R("AF","09") +local hexfour = (hex*hex*hex*hex) / function(s) return tonumber(s,16) end +local hexsix = (hex^1) / function(s) return tonumber(s,16) end +local dec = (lpeg.R("09")^1) / tonumber +local period = lpeg.P(".") + +local unicode = lpeg.P("uni") * (hexfour * (period + lpeg.P(-1)) * lpeg.Cc(false) + lpeg.Ct(hexfour^1) * lpeg.Cc(true)) +local ucode = lpeg.P("u") * (hexsix * (period + lpeg.P(-1)) * lpeg.Cc(false) + lpeg.Ct(hexsix ^1) * lpeg.Cc(true)) +local index = lpeg.P("index") * dec * lpeg.Cc(false) + +local parser = unicode + ucode + index + +local parsers = { } + +local function make_name_parser(str) + if not str or str == "" then + return parser + else + local p = parsers[str] + if not p then + p = lpeg.P(str) * period * dec * lpeg.Cc(false) + parsers[str] = p + end + return p + end +end + +--~ local parser = fonts.map.make_name_parser("Japan1") +--~ local parser = fonts.map.make_name_parser() +--~ local function test(str) +--~ local b, a = lpegmatch(parser,str) +--~ print((a and table.serialize(b)) or b) +--~ end +--~ test("a.sc") +--~ test("a") +--~ test("uni1234") +--~ test("uni1234.xx") +--~ test("uni12349876") +--~ test("index1234") +--~ test("Japan1.123") + +local function tounicode16(unicode) + if unicode < 0x10000 then + return format("%04X",unicode) + else + return format("%04X%04X",unicode/1024+0xD800,unicode%1024+0xDC00) + end +end + +local function tounicode16sequence(unicodes) + local t = { } + for l=1,#unicodes do + local unicode = unicodes[l] + if unicode < 0x10000 then + t[l] = format("%04X",unicode) + else + t[l] = format("%04X%04X",unicode/1024+0xD800,unicode%1024+0xDC00) + end + end + return concat(t) +end + +--~ This is quite a bit faster but at the cost of some memory but if we +--~ do this we will also use it elsewhere so let's not follow this route +--~ now. I might use this method in the plain variant (no caching there) +--~ but then I need a flag that distinguishes between code branches. +--~ +--~ local cache = { } +--~ +--~ function fonts.map.tounicode16(unicode) +--~ local s = cache[unicode] +--~ if not s then +--~ if unicode < 0x10000 then +--~ s = format("%04X",unicode) +--~ else +--~ s = format("%04X%04X",unicode/1024+0xD800,unicode%1024+0xDC00) +--~ end +--~ cache[unicode] = s +--~ end +--~ return s +--~ end + +fonts.map.load_lum_table = load_lum_table +fonts.map.make_name_parser = make_name_parser +fonts.map.tounicode16 = tounicode16 +fonts.map.tounicode16sequence = tounicode16sequence + +local separator = lpeg.S("_.") +local other = lpeg.C((1 - separator)^1) +local ligsplitter = lpeg.Ct(other * (separator * other)^0) + +--~ print(table.serialize(lpegmatch(ligsplitter,"this"))) +--~ print(table.serialize(lpegmatch(ligsplitter,"this.that"))) +--~ print(table.serialize(lpegmatch(ligsplitter,"japan1.123"))) +--~ print(table.serialize(lpegmatch(ligsplitter,"such_so_more"))) +--~ print(table.serialize(lpegmatch(ligsplitter,"such_so_more.that"))) + +fonts.map.add_to_unicode = function(data,filename) + local unicodes = data.luatex and data.luatex.unicodes + if not unicodes then + return + end + -- we need to move this code + unicodes['space'] = unicodes['space'] or 32 + unicodes['hyphen'] = unicodes['hyphen'] or 45 + unicodes['zwj'] = unicodes['zwj'] or 0x200D + unicodes['zwnj'] = unicodes['zwnj'] or 0x200C + -- 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 + local lumunic, uparser, oparser + if false then -- will become an option + lumunic = load_lum_table(filename) + lumunic = lumunic and lumunic.tounicode + end + local cidinfo, cidnames, cidcodes = data.cidinfo + local usedmap = cidinfo and cidinfo.usedname + usedmap = usedmap and lower(usedmap) + usedmap = usedmap and fonts.cid.map[usedmap] + if usedmap then + oparser = usedmap and make_name_parser(cidinfo.ordering) + cidnames = usedmap.names + cidcodes = usedmap.unicodes + end + uparser = make_name_parser() + local aglmap = fonts.map and fonts.map.agl_to_unicode + 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 + local unicode = (lumunic and lumunic[name]) or (aglmap and aglmap[name]) + if unicode then + originals[index], tounicode[index], ns = unicode, tounicode16(unicode), ns + 1 + end + -- cidmap heuristics, beware, there is no guarantee for a match unless + -- the chain resolves + if (not unicode) and usedmap then + local foundindex = lpegmatch(oparser,name) + if foundindex then + unicode = cidcodes[foundindex] -- name to number + if unicode then + originals[index], tounicode[index], ns = unicode, tounicode16(unicode), ns + 1 + else + local reference = cidnames[foundindex] -- number to name + if reference then + local foundindex = lpegmatch(oparser,reference) + if foundindex then + unicode = cidcodes[foundindex] + if unicode then + originals[index], tounicode[index], ns = unicode, tounicode16(unicode), ns + 1 + end + end + if not unicode then + local foundcodes, multiple = lpegmatch(uparser,reference) + if foundcodes then + if multiple then + originals[index], tounicode[index], nl, unicode = foundcodes, tounicode16sequence(foundcodes), nl + 1, true + else + originals[index], tounicode[index], ns, unicode = foundcodes, tounicode16(foundcodes), ns + 1, foundcodes + end + end + end + end + end + end + end + -- a.whatever or a_b_c.whatever or a_b_c (no numbers) + if not unicode then + local split = lpegmatch(ligsplitter,name) + local nplit = (split and #split) or 0 + if nplit == 0 then + -- skip + elseif nplit == 1 then + local base = split[1] + unicode = unicodes[base] or (aglmap and aglmap[base]) + if unicode then + if type(unicode) == "table" then + unicode = unicode[1] + end + originals[index], tounicode[index], ns = unicode, tounicode16(unicode), ns + 1 + end + else + local t = { } + for l=1,nplit do + local base = split[l] + local u = unicodes[base] or (aglmap and aglmap[base]) + if not u then + break + elseif type(u) == "table" then + t[#t+1] = u[1] + else + t[#t+1] = u + end + end + if #t > 0 then -- done then + originals[index], tounicode[index], nl, unicode = t, tounicode16sequence(t), nl + 1, true + end + end + end + -- last resort + if not unicode then + local foundcodes, multiple = lpegmatch(uparser,name) + if foundcodes then + if multiple then + originals[index], tounicode[index], nl, unicode = foundcodes, tounicode16sequence(foundcodes), nl + 1, true + else + originals[index], tounicode[index], ns, unicode = foundcodes, tounicode16(foundcodes), ns + 1, foundcodes + end + end + end + if not unicode then + originals[index], tounicode[index] = 0xFFFD, "FFFD" + end + end + end + if trace_unimapping then + for index, glyph in table.sortedhash(data.glyphs) do + local toun, name, unic = tounicode[index], glyph.name, glyph.unicode or -1 -- play safe + if toun then + logs.report("load otf","internal: 0x%05X, name: %s, unicode: 0x%05X, tounicode: %s",index,name,unic,toun) + else + logs.report("load otf","internal: 0x%05X, name: %s, unicode: 0x%05X",index,name,unic) + 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 + +-- the following is sort of obsolete +-- +-- fonts.map.data = fonts.map.data or { } +-- fonts.map.encodings = fonts.map.encodings or { } +-- fonts.map.loaded = fonts.map.loaded or { } +-- fonts.map.line = fonts.map.line or { } +-- +-- function fonts.map.line.pdftex(e) +-- if e.name and e.fontfile then +-- local fullname = e.fullname or "" +-- if e.slant and e.slant ~= 0 then +-- if e.encoding then +-- pdf.mapline(format('= %s %s "%g SlantFont" <%s <%s',e.name,fullname,e.slant,e.encoding,e.fontfile))) +-- else +-- pdf.mapline(format('= %s %s "%g SlantFont" <%s',e.name,fullname,e.slant,e.fontfile))) +-- end +-- elseif e.extend and e.extend ~= 1 and e.extend ~= 0 then +-- if e.encoding then +-- pdf.mapline(format('= %s %s "%g ExtendFont" <%s <%s',e.name,fullname,e.extend,e.encoding,e.fontfile))) +-- else +-- pdf.mapline(format('= %s %s "%g ExtendFont" <%s',e.name,fullname,e.extend,e.fontfile))) +-- end +-- else +-- if e.encoding then +-- pdf.mapline(format('= %s %s <%s <%s',e.name,fullname,e.encoding,e.fontfile))) +-- else +-- pdf.mapline(format('= %s %s <%s',e.name,fullname,e.fontfile))) +-- end +-- end +-- else +-- return nil +-- end +-- 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 next, fonts.map.data do +-- flushline(e) +-- end +-- fonts.map.data = { } +-- end +-- +-- fonts.map.line.dvips = fonts.map.line.pdftex +-- fonts.map.line.dvipdfmx = function() end +-- +-- function fonts.map.convert_entries(filename) +-- if not fonts.map.loaded[filename] then +-- fonts.map.data, fonts.map.encodings = fonts.map.load_file(filename,fonts.map.data, fonts.map.encodings) +-- fonts.map.loaded[filename] = true +-- end +-- end +-- +-- function fonts.map.load_file(filename, entries, encodings) +-- entries = entries or { } +-- encodings = encodings or { } +-- local f = io.open(filename) +-- if f then +-- local data = f:read("*a") +-- if data then +-- for line in gmatch(data,"(.-)[\n\t]") do +-- if find(line,"^[%#%%%s]") then +-- -- print(line) +-- else +-- local extend, slant, name, fullname, fontfile, encoding +-- line = gsub(line,'"(.+)"', function(s) +-- extend = find(s,'"([^"]+) ExtendFont"') +-- slant = find(s,'"([^"]+) SlantFont"') +-- return "" +-- end) +-- if not name then +-- -- name fullname encoding fontfile +-- 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 = match(line,"^(%S+)%s+(%S*)[%d%s<]+(%S*)[%s<]+(%S*)%s*$") +-- end +-- if not name then +-- -- name fontfile +-- name, fontfile = match(line,"^(%S+)%s+[%d%s<]+(%S*)%s*$") +-- end +-- if name then +-- if encoding == "" then encoding = nil end +-- entries[name] = { +-- name = name, -- handy +-- fullname = fullname, +-- encoding = encoding, +-- fontfile = fontfile, +-- slant = tonumber(slant), +-- extend = tonumber(extend) +-- } +-- encodings[name] = encoding +-- elseif line ~= "" then +-- -- print(line) +-- end +-- end +-- end +-- end +-- f:close() +-- end +-- return entries, encodings +-- end diff --git a/tex/context/base/font-mis.lua b/tex/context/base/font-mis.lua new file mode 100644 index 000000000..80a56332a --- /dev/null +++ b/tex/context/base/font-mis.lua @@ -0,0 +1,101 @@ +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 = next +local lower, strip = string.lower, string.strip + +fonts.otf = fonts.otf or { } + +fonts.otf.version = fonts.otf.version or 2.650 +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 + +local featuregroups = { "gsub", "gpos" } + +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" or t == "dfont" 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=1,#featuregroups do + local what = featuregroups[k] + 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 dfscripts = df.scripts + for i=1,#dfscripts do + local ds = dfscripts[i] + local scri = strip(lower(ds.script)) + local fts = ft[scri] if not fts then fts = {} ft[scri] = fts end + local dslangs = ds.langs + for i=1,#dslangs do + local lang = dslangs[i] + 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..0b61e17d1 --- /dev/null +++ b/tex/context/base/font-ota.lua @@ -0,0 +1,286 @@ +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 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, [0xFEF5] = true, [0xFEF7] = true, + [0xFEF9] = true, [0xFEFB] = 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 + +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 + 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 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) + return head, done +end diff --git a/tex/context/base/font-otb.lua b/tex/context/base/font-otb.lua new file mode 100644 index 000000000..a3d347737 --- /dev/null +++ b/tex/context/base/font-otb.lua @@ -0,0 +1,373 @@ +if not modules then modules = { } end modules ['font-otb'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + 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 lpegmatch = lpeg.match + +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 = lpegmatch(split_at_space,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 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 = otf.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 + -- + local actions = { + substitution = function(p,lookup,k,glyph,unicode) + 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 + end, + alternate = function(p,lookup,k,glyph,unicode) + local pc = p[2] -- p.components + if pc then + -- a bit optimized ugliness + if value == 1 then + pc = lpegmatch(splitter,pc) + elseif value == 2 then + local a, b = lpegmatch(splitter,pc) + pc = b or a + else + pc = { lpegmatch(splitter,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 => %s",cref(kind,lookup),tostring(value),gref(descriptions,k),gref(descriptions,upc)) + end + changed[k] = upc + end + end + end + end + end, + ligature = function(p,lookup,k,glyph,unicode) + local pc = p[2] + if pc then + if trace_baseinit and trace_ligatures then + local upc = { lpegmatch(splitter,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, + } + -- + for k,c in next, characters do + local glyph = descriptions[k] + local lookups = glyph.slookups + if lookups then + for l=1,#lookuplist do + local lookup = lookuplist[l] + local p = lookups[lookup] + if p then + local a = actions[p[1]] + if a then + a(p,lookup,k,glyph,unicode) + end + end + end + end + local lookups = glyph.mlookups + 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 a = actions[p[1]] + if a then + a(p,lookup,k,glyph,unicode) + 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 = otf.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 + local sharedkerns = { } + for u, chr in next, characters do + local d = descriptions[u] + if d then + local dk = d.mykerns -- shared + if dk then + local s = sharedkerns[dk] + if s == false then + -- skip + elseif s then + chr.kerns = s + else + 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 + sharedkerns[dk] = t + chr.kerns = t -- no empty assignments + else + sharedkerns[dk] = false + end + end + 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', 'rtlm', -- math +-- 'tlig', 'trep', +} + +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] + local value = features[feature] + prepare_base_substitutions(tfmdata,feature,value) + if value then + h[#h+1] = feature .. "=" .. tostring(value) + end + end + for f=1,#supported_gpos do + local feature = supported_gpos[f] + local value = features[feature] + prepare_base_kerns(tfmdata,feature,features[feature]) + if value then + h[#h+1] = feature .. "=" .. tostring(value) + end + 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 -- tfmdata.psname is the original + --~ logs.report("otf define","fullname base hash: '%s', featureset '%s'",tfmdata.fullname,hash) + 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..357d347b1 --- /dev/null +++ b/tex/context/base/font-otc.lua @@ -0,0 +1,213 @@ +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 + +-- 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 +-- +-- we could have a tnum variant 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 diff --git a/tex/context/base/font-otd.lua b/tex/context/base/font-otd.lua new file mode 100644 index 000000000..41e885331 --- /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.mkiv", + 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 new file mode 100644 index 000000000..9cecf21f0 --- /dev/null +++ b/tex/context/base/font-otf.lua @@ -0,0 +1,1752 @@ +if not modules then modules = { } end modules ['font-otf'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + 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 abs = math.abs +local lpegmatch = lpeg.match + +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) +local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) + +--~ trackers.enable("otf.loading") + +--[[ldx-- +<p>The fontforge table has organized lookups in a certain way. A first implementation +of this code was organized featurewise: information related to features was +collected and processing boiled down to a run over the features. The current +implementation honors the order in the main feature table. Since we can reorder this +table as we want, we can eventually support several models of processing. We kept +the static as well as dynamic feature processing, because it had proved to be +rather useful. The formerly three loop variants have beem discarded but will +reapear at some time.</p> + +<itemize> +<item>we loop over all lookups</item> +<item>for each lookup we do a run over the list of glyphs</item> +<item>but we only process them for features that are enabled</item> +<item>if we're dealing with a contextual lookup, we loop over all contexts</item> +<item>in that loop we quit at a match and then process the list of sublookups</item> +<item>we always continue after the match</item> +</itemize> + +<p>In <l n='context'/> we do this for each font that is used in a list, so in +practice we have quite some nested loops.</p> + +<p>We process the whole list and then consult the glyph nodes. An alternative approach +is to collect strings of characters using the same font including spaces (because some +lookups involve spaces). However, we then need to reconstruct the list which is no fun. +Also, we need to carry quite some information, like attributes, so eventually we don't +gain much (if we gain something at all).</p> + +<p>Another consideration has been to operate on sublists (subhead, subtail) but again +this would complicate matters as we then neext to keep track of a changing subhead +and subtail. On the other hand, this might save some runtime. The number of changes +involved is not that large. This only makes sense when we have many fonts in a list +and don't change to frequently.</p> +--ldx]]-- + +fonts = fonts or { } +fonts.otf = fonts.otf or { } +fonts.tfm = fonts.tfm or { } + +local otf = fonts.otf +local tfm = fonts.tfm + +local fontdata = fonts.ids + +otf.tables = otf.tables or { } -- defined in font-ott.lua +otf.meanings = otf.meanings or { } -- defined in font-ott.lua +otf.tables.features = otf.tables.features or { } -- defined in font-ott.lua +otf.tables.languages = otf.tables.languages or { } -- defined in font-ott.lua +otf.tables.scripts = otf.tables.scripts or { } -- defined in font-ott.lua + +otf.features = otf.features or { } +otf.features.list = otf.features.list or { } +otf.features.default = otf.features.default or { } + +otf.enhancers = otf.enhancers or { } +otf.glists = { "gsub", "gpos" } + +otf.version = 2.650 -- 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 + +local wildcard = "*" +local default = "dflt" + +--[[ldx-- +<p>We start with a lot of tables and related functions.</p> +--ldx]]-- + +otf.tables.global_fields = table.tohash { + "lookups", + "glyphs", + "subfonts", + "luatex", + "pfminfo", + "cidinfo", + "tables", + "names", + "unicodes", + "names", +--~ "math", + "anchor_classes", + "kern_classes", + "gpos", + "gsub" +} + +otf.tables.valid_fields = { + "anchor_classes", + "ascent", + "cache_version", + "cidinfo", + "copyright", + "creationtime", + "descent", + "design_range_bottom", + "design_range_top", + "design_size", + "encodingchanged", + "extrema_bound", + "familyname", + "fontname", + "fontstyle_id", + "fontstyle_name", + "fullname", + "glyphs", + "hasvmetrics", + "head_optimized_for_cleartype", + "horiz_base", + "issans", + "isserif", + "italicangle", + "kerns", + "lookups", + -- "luatex", + "macstyle", + "modificationtime", + "onlybitmaps", + "origname", + "os2_version", + "pfminfo", + "private", + "serifcheck", + "sfd_version", + -- "size", + "strokedfont", + "strokewidth", + "subfonts", + "table_version", + -- "tables", + -- "ttf_tab_saved", + "ttf_tables", + "uni_interp", + "uniqueid", + "units_per_em", + "upos", + "use_typo_metrics", + "uwidth", + "validation_state", + "verbose", + "version", + "vert_base", + "weight", + "weight_width_slope_only", + "xuid", +} + +--[[ldx-- +<p>Here we go.</p> +--ldx]]-- + +local function load_featurefile(ff,featurefile) + if featurefile then + featurefile = resolvers.find_file(file.addsuffix(featurefile,'fea'),'fea') + 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 (%s)",name,filename) + 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 mark classes", + "reorganize kerns", -- moved here + "flatten glyph lookups", "flatten anchor tables", "flatten feature tables", + "simplify glyph lookups", -- some saving + "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", + "check math parameters", +} + +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 (hash: %s)",filename,hash) + 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 + if type(messages) == "string" then + logs.report("load otf","warning: %s",messages) + else + for m=1,#messages do + logs.report("load otf","warning: %s",tostring(messages[m])) + end + end + else + logs.report("load otf","font loaded okay") + 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) + io.flush() -- we want instant messages + 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 + if trace_defining then + logs.report("define font","loading from cache: %s",hash) + end + 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["reorganize mark classes"] = function(data,filename) + if data.mark_classes then + local unicodes = data.luatex.unicodes + local reverse = { } + for name, class in next, data.mark_classes do + local t = { } + for s in gmatch(class,"[^ ]+") do + local us = unicodes[s] + if type(us) == "table" then + for u=1,#us do + t[us[u]] = true + end + else + t[us] = true + end + end + reverse[name] = t + end + data.luatex.markclasses = reverse + data.mark_classes = nil + end +end + +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 + +otf.enhancers["analyse unicodes"] = fonts.map.add_to_unicode + +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, + } + if flags.mark_class then + gk.markclass = luatex.markclasses[flags.mark_class] + end + 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 then + if data.glyphs and next(data.glyphs) then + logs.report("load otf","replacing existing glyph table due to subfonts") + end + local cidinfo = data.cidinfo + local verbose = fonts.verbose + if cidinfo.registry then + local cidmap, cidname = fonts.cid.getmap(cidinfo.registry,cidinfo.ordering,cidinfo.supplement) + if cidmap then + cidinfo.usedname = cidmap.usedname + 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 indices 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 -- the next one is quite slow +--~ 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] +--~ -- weird, as maxfirst and maxseconds can have holes +--~ 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["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 + local separator = lpeg.P(" ") + local other = ((1 - separator)^0) / unicodes + local splitter = lpeg.Ct(other * (separator * other)^0) + 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 -- the next one is quite slow + 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 + local split = { } + for l=1,#lookups do + local lookup = lookups[l] + -- weird, as maxfirst and maxseconds can have holes, first seems to be indexed, seconds starts at 2 + local maxfirsts, maxseconds = getn(firsts), getn(seconds) + for _, s in next, firsts do + split[s] = split[s] or lpegmatch(splitter,s) + end + for _, s in next, seconds do + split[s] = split[s] or lpegmatch(splitter,s) + end + if trace_loading then + logs.report("load otf", "adding kernclass %s with %s times %s pairs",lookup, maxfirsts, maxseconds) + end + local function do_it(fk,first_unicode) + local glyph = glyphs[mapmap[first_unicode]] + 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 + local baseoffset = (fk-1) * maxseconds + for sk=2,maxseconds do + local sv = seconds[sk] + local offset = offsets[baseoffset + sk] + --~ local offset = offsets[sk] -- (fk-1) * maxseconds + sk] + local splt = split[sv] + if splt then + for i=1,#splt do + local second_unicode = splt[i] + if tonumber(second_unicode) then + lookupkerns[second_unicode] = offset + else + for s=1,#second_unicode do + lookupkerns[second_unicode[s]] = offset + end + end + end + end + end + elseif trace_loading then + logs.report("load otf", "no glyph data for U+%04X", first_unicode) + end + end + for fk=1,#firsts do + local fv = firsts[fk] + local splt = split[fv] + if splt then + for i=1,#splt do + local first_unicode = splt[i] + if tonumber(first_unicode) then + do_it(fk,first_unicode) + else + for f=1,#first_unicode do + do_it(fk,first_unicode[f]) + end + 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 + +local private_math_parameters = { + "FractionDelimiterSize", + "FractionDelimiterDisplayStyleSize", +} + +otf.enhancers["check math parameters"] = function(data,filename) + local mathdata = data.metadata.math + if mathdata then + for m=1,#private_math_parameters do + local pmp = private_math_parameters[m] + if not mathdata[pmp] then + if trace_loading then + logs.report("load otf", "setting math parameter '%s' to 0", pmp) + end + mathdata[pmp] = 0 + end + end + end +end + +otf.enhancers["flatten glyph lookups"] = function(data,filename) + for k, v in next, data.glyphs do + local lookups = v.lookups + if lookups then + for kk, vv in next, 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["simplify glyph lookups"] = function(data,filename) + for k, v in next, data.glyphs do + local lookups = v.lookups + if lookups then + local slookups, mlookups + for kk, vv in next, lookups do + if #vv == 1 then + if not slookups then + slookups = { } + v.slookups = slookups + end + slookups[kk] = vv[1] + else + if not mlookups then + mlookups = { } + v.mlookups = mlookups + end + mlookups[kk] = vv + end + end + v.lookups = nil + 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 + +-- for context this will become a task handler + +function otf.set_features(tfmdata,features) + local processes = { } + if features and next(features) then + local lists = { -- why local + 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] -- todo: zonder node/mode otf/... + 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 otfdata and next(otfdata) then + otfdata.shared = otfdata.shared or { + featuredata = { }, + anchorhash = { }, + initialized = false, + } + tfmdata = otf.copy_to_tfm(otfdata,cache_id) + if tfmdata and next(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 + +fonts.formats.dfont = "truetype" +fonts.formats.ttc = "truetype" +fonts.formats.ttf = "truetype" +fonts.formats.otf = "opentype" + +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 designsize = metadata.designsize or metadata.design_size or 100 + if designsize == 0 then + designsize = 100 + end + local spaceunits = 500 + -- 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 and loop over characters + 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 gmatch(variants,"[^ ]+") 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 gmatch(variants,"[^ ]+") 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 + c.vert_italic_correction = m.vert_italic_correction + end + end + local kerns = m.kerns + if kerns then + char.mathkerns = kerns + end + end + end + end + -- end math + local endash, emdash, space = 0x20, 0x2014, "space" -- unicodes['space'], unicodes['emdash'] + if metadata.isfixedpitch then + if descriptions[endash] then + spaceunits, spacer = descriptions[endash].width, "space" + end + if not spaceunits and descriptions[emdash] then + spaceunits, spacer = descriptions[emdash].width, "emdash" + end + if not spaceunits and metadata.charwidth then + spaceunits, spacer = metadata.charwidth, "charwidth" + end + else + if descriptions[endash] then + spaceunits, spacer = descriptions[endash].width, "space" + end + if not spaceunits and descriptions[emdash] then + spaceunits, spacer = descriptions[emdash].width/2, "emdash/2" + end + if not spaceunits and metadata.charwidth then + spaceunits, spacer = metadata.charwidth, "charwidth" + end + end + spaceunits = tonumber(spaceunits) or tfm.units/2 -- 500 -- brrr + -- we need a runtime lookup because of running from cdrom or zip, brrr (shouldn't we use the basename then?) + local filename = fonts.tfm.checked_filename(luatex) + local fontname = metadata.fontname + local fullname = metadata.fullname or fontname + local cidinfo = data.cidinfo + local units = metadata.units_per_em or 1000 + -- + cidinfo.registry = cidinfo and cidinfo.registry or "" -- weird here, fix upstream + -- + parameters.slant = 0 + parameters.space = spaceunits -- 3.333 (cmr10) + parameters.space_stretch = units/2 -- 500 -- 1.666 (cmr10) + parameters.space_shrink = 1*units/3 -- 333 -- 1.111 (cmr10) + parameters.x_height = 2*units/5 -- 400 + parameters.quad = units -- 1000 + if spaceunits < 2*units/5 then + -- todo: warning + end + local italicangle = metadata.italicangle + if italicangle then -- maybe also in afm _ + 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 + -- + return { + characters = characters, + parameters = parameters, + math_parameters = math_parameters, + descriptions = descriptions, + indices = indices, + unicodes = unicodes, + type = "real", + direction = 0, + boundarychar_label = 0, + boundarychar = 65536, + designsize = (designsize/10)*65536, + spacer = "500 units", + encodingbytes = 2, + filename = filename, + fontname = fontname, + fullname = fullname, + psname = fontname or fullname, + name = filename or fullname, + units = units, + format = fonts.fontformat(filename,"opentype"), + cidinfo = cidinfo, + ascender = abs(metadata.ascent or 0), + descender = abs(metadata.descent or 0), + spacer = spacer, + italicangle = italicangle, + } + 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 + -- this will move to a function + 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,specification.relativeid) + if tfm.fontname_mode == "specification" then + -- not to be used in context ! + local specname = specification.specification + if specname then + tfmtable.name = specname + if trace_defining then + logs.report("define font","overloaded fontname: '%s'",specname) + end + end + end + fonts.logger.save(tfmtable,file.extname(specification.filename),specification) + end +--~ print(tfmtable.fullname) + return tfmtable +end + +-- helpers + +function otf.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 diff --git a/tex/context/base/font-oti.lua b/tex/context/base/font-oti.lua new file mode 100644 index 000000000..4cb270626 --- /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.mkiv", + 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..d4f89adc6 --- /dev/null +++ b/tex/context/base/font-otn.lua @@ -0,0 +1,2660 @@ +if not modules then modules = { } end modules ['font-otn'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + 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. + +-- I'm in the process of cleaning up the code (which happens in another +-- file) so don't rely on things staying the same. + +-- some day when we can jit this, we can use more functions + +-- we can use more lpegs when lpeg is extended with function args and so +-- resolving to unicode does not gain much + +-- in retrospect it always looks easy but believe it or not, it took a lot +-- of work to get proper open type support done: buggy fonts, fuzzy specs, +-- special made testfonts, many skype sessions between taco, idris and me, +-- torture tests etc etc ... unfortunately the code does not show how much +-- time it took ... + +-- todo: +-- +-- kerning is probably not yet ok for latin around dics nodes +-- extension infrastructure (for usage out of context) +-- sorting features according to vendors/renderers +-- alternative loop quitters +-- check cursive and r2l +-- find out where ignore-mark-classes went +-- remove unused tables +-- slide tail (always glue at the end so only needed once +-- default features (per language, script) +-- cleanup kern(class) code, remove double info +-- handle positions (we need example fonts) +-- handle gpos_single (we might want an extra width field in glyph nodes because adding kerns might interfere) + +--[[ldx-- +<p>This module is a bit more split up that I'd like but since we also want to test +with plain <l n='tex'/> it has to be so. This module is part of <l n='context'/> +and discussion about improvements and functionality mostly happens on the +<l n='context'/> mailing list.</p> + +<p>The specification of OpenType is kind of vague. Apart from a lack of a proper +free specifications there's also the problem that Microsoft and Adobe +may have their own interpretation of how and in what order to apply features. +In general the Microsoft website has more detailed specifications and is a +better reference. There is also some information in the FontForge help files.</p> + +<p>Because there is so much possible, fonts might contain bugs and/or be made to +work with certain rederers. These may evolve over time which may have the side +effect that suddenly fonts behave differently.</p> + +<p>After a lot of experiments (mostly by Taco, me and Idris) we're now at yet another +implementation. Of course all errors are mine and of course the code can be +improved. There are quite some optimizations going on here and processing speed +is currently acceptable. Not all functions are implemented yet, often because I +lack the fonts for testing. Many scripts are not yet supported either, but I will +look into them as soon as <l n='context'/> users ask for it.</p> + +<p>Because there are different interpretations possible, I will extend the code +with more (configureable) variants. I can also add hooks for users so that they can +write their own extensions.</p> + +<p>Glyphs are indexed not by unicode but in their own way. This is because there is no +relationship with unicode at all, apart from the fact that a font might cover certain +ranges of characters. One character can have multiple shapes. However, at the +<l n='tex'/> end we use unicode so and all extra glyphs are mapped into a private +space. This is needed because we need to access them and <l n='tex'/> has to include +then in the output eventually.</p> + +<p>The raw table as it coms from <l n='fontforge'/> gets reorganized in to fit out needs. +In <l n='context'/> that table is packed (similar tables are shared) and cached on disk +so that successive runs can use the optimized table (after loading the table is +unpacked). The flattening code used later is a prelude to an even more compact table +format (and as such it keeps evolving).</p> + +<p>This module is sparsely documented because it is a moving target. The table format +of the reader changes and we experiment a lot with different methods for supporting +features.</p> + +<p>As with the <l n='afm'/> code, we may decide to store more information in the +<l n='otf'/> table.</p> + +<p>Incrementing the version number will force a re-cache. We jump the number by one +when there's a fix in the <l n='fontforge'/> library or <l n='lua'/> code that +results in different tables.</p> +--ldx]]-- + +-- action handler chainproc chainmore comment +-- +-- gsub_single ok ok ok +-- gsub_multiple ok ok not implemented yet +-- gsub_alternate ok ok not implemented yet +-- gsub_ligature ok ok ok +-- gsub_context ok -- +-- gsub_contextchain ok -- +-- gsub_reversecontextchain ok -- +-- chainsub -- ok +-- reversesub -- ok +-- gpos_mark2base ok ok +-- gpos_mark2ligature ok ok +-- gpos_mark2mark ok ok +-- gpos_cursive ok untested +-- gpos_single ok ok +-- gpos_pair ok ok +-- gpos_context ok -- +-- gpos_contextchain ok -- +-- +-- actions: +-- +-- handler : actions triggered by lookup +-- chainproc : actions triggered by contextual lookup +-- chainmore : multiple substitutions triggered by contextual lookup (e.g. fij -> f + ij) +-- +-- remark: the 'not implemented yet' variants will be done when we have fonts that use them +-- remark: we need to check what to do with discretionaries + +local concat, insert, remove = table.concat, table.insert, table.remove +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 lpegmatch = lpeg.match + +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) +local trace_skips = false trackers.register("otf.skips", function(v) trace_skips = v end) +local trace_directions = false trackers.register("otf.directions", function(v) trace_directions = 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 find_node_tail = node.tail or 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.splitters[" "] or lpeg.Ct(lpeg.splitat(" ")) -- no trailing or multiple spaces anyway + +local glyph = node.id('glyph') +local glue = node.id('glue') +local kern = node.id('kern') +local disc = node.id('disc') +local whatsit = node.id('whatsit') + +local state = attributes.private('state') +local markbase = attributes.private('markbase') +local markmark = attributes.private('markmark') +local markdone = attributes.private('markdone') +local cursbase = attributes.private('cursbase') +local curscurs = attributes.private('curscurs') +local cursdone = attributes.private('cursdone') +local kernpair = attributes.private('kernpair') + +local set_mark = nodes.set_mark +local set_cursive = nodes.set_cursive +local set_kern = nodes.set_kern +local set_pair = nodes.set_pair + +local markonce = true +local cursonce = true +local kernonce = true + +local fontdata = fonts.ids + +otf.features.process = { } + +-- we share some vars here, after all, we have no nested lookups and +-- less code + +local tfmdata = false +local otfdata = false +local characters = false +local descriptions = false +local marks = false +local indices = false +local unicodes = false +local currentfont = false +local lookuptable = false +local anchorlookups = false +local handlers = { } +local rlmode = 0 +local featurevalue = false + +-- we cheat a bit and assume that a font,attr combination are kind of ranged + +local context_setups = fonts.define.specify.context_setups +local context_numbers = fonts.define.specify.context_numbers +local context_merged = fonts.define.specify.context_merged + +-- we cannot optimize with "start = first_character(head)" because then we don't +-- know which rlmode we're in which messes up cursive handling later on +-- +-- head is always a whatsit so we can safely assume that head is not changed + +local special_attributes = { + init = 1, + medi = 2, + fina = 3, + isol = 4 +} + +-- we use this for special testing and documentation + +local checkstep = (nodes and nodes.tracers and nodes.tracers.steppers.check) or function() end +local registerstep = (nodes and nodes.tracers and nodes.tracers.steppers.register) or function() end +local registermessage = (nodes and nodes.tracers and nodes.tracers.steppers.message) or function() end + +local function logprocess(...) + if trace_steps then + registermessage(...) + end + logs.report("otf direct",...) +end +local function logwarning(...) + logs.report("otf direct",...) +end + +local function gref(n) + if type(n) == "number" then + local description = descriptions[n] + local name = description and description.name + if name then + return format("U+%04X (%s)",n,name) + else + return format("U+%04X",n) + end + elseif not n then + return "<error in tracing>" + else + local num, nam = { }, { } + for i=1,#n do + local ni = n[i] + num[#num+1] = format("U+%04X",ni) + local dni = descriptions[ni] + nam[#num] = (dni and dni.name) or "?" + end + return format("%s (%s)",concat(num," "), concat(nam," ")) + end +end + +local function cref(kind,chainname,chainlookupname,lookupname,index) + if index then + return format("feature %s, chain %s, sub %s, lookup %s, index %s",kind,chainname,chainlookupname,lookupname,index) + elseif lookupname then + return format("feature %s, chain %s, sub %s, lookup %s",kind,chainname or "?",chainlookupname or "?",lookupname) + elseif chainlookupname then + return format("feature %s, chain %s, sub %s",kind,chainname or "?",chainlookupname) + elseif chainname then + return format("feature %s, chain %s",kind,chainname) + else + return format("feature %s",kind) + end +end + +local function pref(kind,lookupname) + return format("feature %s, lookup %s",kind,lookupname) +end + +-- we can assume that languages that use marks are not hyphenated +-- we can also assume that at most one discretionary is present + +local function markstoligature(kind,lookupname,start,stop,char) + local n = copy_node(start) + local keep = start + local current + current, start = insert_node_after(start,start,n) + local snext = stop.next + current.next = snext + if snext then + snext.prev = current + end + start.prev, stop.next = nil, nil + current.char, current.subtype, current.components = char, 2, start + return keep +end + +local function toligature(kind,lookupname,start,stop,char,markflag,discfound) -- brr head + if start ~= stop then +--~ if discfound then +--~ local lignode = copy_node(start) +--~ lignode.font = start.font +--~ lignode.char = char +--~ lignode.subtype = 2 +--~ start = node.do_ligature_n(start, stop, lignode) +--~ if start.id == disc then +--~ local prev = start.prev +--~ start = start.next +--~ end + if discfound then + -- print("start->stop",nodes.tosequence(start,stop)) + local lignode = copy_node(start) + lignode.font, lignode.char, lignode.subtype = start.font, char, 2 + local next, prev = stop.next, start.prev + stop.next = nil + lignode = node.do_ligature_n(start, stop, lignode) + prev.next = lignode + if next then + next.prev = lignode + end + lignode.next, lignode.prev = next, prev + start = lignode + -- print("start->end",nodes.tosequence(start)) + 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] + else + value = tonumber(value) + if 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 + 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 + local startchar = start.char + if marks[startchar] 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 stopchar = 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 stopchar = stop.char + start = toligature(kind,lookupname,start,stop,ligature[2],skipmark,discfound) + logprocess("%s: replacing %s upto %s by ligature %s",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char)) + else + start = toligature(kind,lookupname,start,stop,ligature[2],skipmark,discfound) + end + return start, true + end + end + return start, false +end + +--[[ldx-- +<p>We get hits on a mark, but we're not sure if the it has to be applied so +we need to explicitly test for basechar, baselig and basemark entries.</p> +--ldx]]-- + +function handlers.gpos_mark2base(start,kind,lookupname,markanchors,sequence) + local markchar = start.char + if marks[markchar] then + local base = start.prev -- [glyph] [start=mark] + if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + local basechar = base.char + if marks[basechar] then + while true do + base = base.prev + if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + basechar = base.char + if not marks[basechar] then + break + end + else + if trace_bugs then + logwarning("%s: no base for mark %s",pref(kind,lookupname),gref(markchar)) + end + return start, false + end + end + end + local baseanchors = descriptions[basechar] + if baseanchors then + baseanchors = baseanchors.anchors + end + if baseanchors then + local baseanchors = baseanchors['basechar'] + if baseanchors then + local al = anchorlookups[lookupname] + for anchor,ba in next, baseanchors do + if al[anchor] then + local ma = markanchors[anchor] + if ma then + local dx, dy, bound = set_mark(start,base,tfmdata.factor,rlmode,ba,ma) + if trace_marks then + logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%s,%s)", + pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) + end + return start, true + end + end + end + if trace_bugs then + logwarning("%s, no matching anchors for mark %s and base %s",pref(kind,lookupname),gref(markchar),gref(basechar)) + end + end + else -- if trace_bugs then + -- logwarning("%s: char %s is missing in font",pref(kind,lookupname),gref(basechar)) + fonts.register_message(currentfont,basechar,"no base anchors") + end + elseif trace_bugs then + logwarning("%s: prev node is no char",pref(kind,lookupname)) + end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",pref(kind,lookupname),gref(markchar)) + end + return start, false +end + +function handlers.gpos_mark2ligature(start,kind,lookupname,markanchors,sequence) + -- check chainpos variant + local markchar = start.char + if marks[markchar] then + local base = start.prev -- [glyph] [optional marks] [start=mark] + local index = 1 + if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + local basechar = base.char + if marks[basechar] then + index = index + 1 + while true do + base = base.prev + if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + basechar = base.char + if marks[basechar] then + index = index + 1 + else + break + end + else + if trace_bugs then + logwarning("%s: no base for mark %s",pref(kind,lookupname),gref(markchar)) + end + return start, false + end + end + end + local i = has_attribute(start,markdone) + if i then index = i end + local baseanchors = descriptions[basechar] + if baseanchors then + baseanchors = baseanchors.anchors + if baseanchors then + local baseanchors = baseanchors['baselig'] + if baseanchors then + local al = anchorlookups[lookupname] + for anchor,ba in next, baseanchors do + if al[anchor] then + local ma = markanchors[anchor] + if ma then + ba = ba[index] + if ba then + local dx, dy, bound = set_mark(start,base,tfmdata.factor,rlmode,ba,ma,index) + if trace_marks then + logprocess("%s, anchor %s, index %s, bound %s: anchoring mark %s to baselig %s at index %s => (%s,%s)", + pref(kind,lookupname),anchor,index,bound,gref(markchar),gref(basechar),index,dx,dy) + end + return start, true + end + end + end + end + if trace_bugs then + logwarning("%s: no matching anchors for mark %s and baselig %s",pref(kind,lookupname),gref(markchar),gref(basechar)) + end + end + end + else -- if trace_bugs then + -- logwarning("%s: char %s is missing in font",pref(kind,lookupname),gref(basechar)) + fonts.register_message(currentfont,basechar,"no base anchors") + end + elseif trace_bugs then + logwarning("%s: prev node is no char",pref(kind,lookupname)) + end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",pref(kind,lookupname),gref(markchar)) + end + return start, false +end + +function handlers.gpos_mark2mark(start,kind,lookupname,markanchors,sequence) + local markchar = start.char + if marks[markchar] then +--~ local alreadydone = markonce and has_attribute(start,markmark) +--~ if not alreadydone then + local base = start.prev -- [glyph] [basemark] [start=mark] + if base and base.id == glyph and base.subtype<256 and base.font == currentfont then -- subtype test can go + local basechar = base.char + local baseanchors = descriptions[basechar] + if baseanchors then + baseanchors = baseanchors.anchors + if baseanchors then + baseanchors = baseanchors['basemark'] + if baseanchors then + local al = anchorlookups[lookupname] + for anchor,ba in next, baseanchors do + if al[anchor] then + local ma = markanchors[anchor] + if ma then + local dx, dy, bound = set_mark(start,base,tfmdata.factor,rlmode,ba,ma) + if trace_marks then + logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%s,%s)", + pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) + end + return start,true + end + end + end + if trace_bugs then + logwarning("%s: no matching anchors for mark %s and basemark %s",pref(kind,lookupname),gref(markchar),gref(basechar)) + end + end + end + else -- if trace_bugs then + -- logwarning("%s: char %s is missing in font",pref(kind,lookupname),gref(basechar)) + fonts.register_message(currentfont,basechar,"no base anchors") + end + elseif trace_bugs then + logwarning("%s: prev node is no mark",pref(kind,lookupname)) + end +--~ elseif trace_marks and trace_details then +--~ logprocess("%s, mark %s is already bound (n=%s), ignoring mark2mark",pref(kind,lookupname),gref(markchar),alreadydone) +--~ end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",pref(kind,lookupname),gref(markchar)) + end + return start,false +end + +function handlers.gpos_cursive(start,kind,lookupname,exitanchors,sequence) -- to be checked + local alreadydone = cursonce and has_attribute(start,cursbase) + if not alreadydone then + local done = false + local startchar = start.char + if marks[startchar] then + if trace_cursive then + logprocess("%s: ignoring cursive for mark %s",pref(kind,lookupname),gref(startchar)) + end + else + local nxt = start.next + while not done and nxt and nxt.id == glyph and nxt.subtype<256 and nxt.font == currentfont do + local nextchar = nxt.char + if marks[nextchar] then + -- should not happen (maybe warning) + nxt = nxt.next + else + local entryanchors = descriptions[nextchar] + if entryanchors then + entryanchors = entryanchors.anchors + if entryanchors then + entryanchors = entryanchors['centry'] + if entryanchors then + local al = anchorlookups[lookupname] + for anchor, entry in next, entryanchors do + if al[anchor] then + local exit = exitanchors[anchor] + if exit then + local dx, dy, bound = set_cursive(start,nxt,tfmdata.factor,rlmode,exit,entry,characters[startchar],characters[nextchar]) + if trace_cursive then + logprocess("%s: moving %s to %s cursive (%s,%s) using anchor %s and bound %s in rlmode %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound,rlmode) + 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, w, h = set_pair(start,tfmdata.factor,rlmode,sequence.flags[4],kerns,characters[startchar]) + if trace_kerns then + logprocess("%s: shifting single %s by (%s,%s) and correction (%s,%s)",pref(kind,lookupname),gref(startchar),dx,dy,w,h) + 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,sequence.flags[4],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,sequence.flags[4],b,characters[nextchar]) + if trace_kerns then + logprocess("%s: shifting second of pair %s and %s by (%s,%s) and correction (%s,%s)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) + end + end + else + logs.report("%s: check this out (old kern stuff)",pref(kind,lookupname)) + local a, b = krn[3], krn[7] + if a and a ~= 0 then + local k = set_kern(snext,factor,rlmode,a) + if trace_kerns then + logprocess("%s: inserting first kern %s between %s and %s",pref(kind,lookupname),k,gref(prev.char),gref(nextchar)) + end + end + if b and b ~= 0 then + logwarning("%s: ignoring second kern xoff %s",pref(kind,lookupname),b*factor) + end + end + done = true + elseif krn ~= 0 then + local k = set_kern(snext,factor,rlmode,krn) + if trace_kerns then + logprocess("%s: inserting kern %s between %s and %s",pref(kind,lookupname),k,gref(prev.char),gref(nextchar)) + end + done = true + end + break + end + end + return start, done + end +end + +--[[ldx-- +<p>I will implement multiple chain replacements once I run into a font that uses +it. It's not that complex to handle.</p> +--ldx]]-- + +local chainmores = { } +local chainprocs = { } + +local function logprocess(...) + if trace_steps then + registermessage(...) + end + logs.report("otf subchain",...) +end +local function logwarning(...) + logs.report("otf subchain",...) +end + +-- ['coverage']={ +-- ['after']={ "r" }, +-- ['before']={ "q" }, +-- ['current']={ "a", "b", "c" }, +-- }, +-- ['lookups']={ "ls_l_1", "ls_l_1", "ls_l_1" }, + +function chainmores.chainsub(start,stop,kind,chainname,currentcontext,cache,lookuplist,chainlookupname,n) + logprocess("%s: a direct call to chainsub cannot happen",cref(kind,chainname,chainlookupname)) + return start, false +end + +-- handled later: +-- +-- function chainmores.gsub_single(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,n) +-- return chainprocs.gsub_single(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,n) +-- end + +function chainmores.gsub_multiple(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,n) + logprocess("%s: gsub_multiple not yet supported",cref(kind,chainname,chainlookupname)) + return start, false +end +function chainmores.gsub_alternate(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,n) + logprocess("%s: gsub_alternate not yet supported",cref(kind,chainname,chainlookupname)) + return start, false +end + +-- handled later: +-- +-- function chainmores.gsub_ligature(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,n) +-- return chainprocs.gsub_ligature(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,n) +-- end + +local function logprocess(...) + if trace_steps then + registermessage(...) + end + logs.report("otf chain",...) +end +local function logwarning(...) + logs.report("otf chain",...) +end + +-- We could share functions but that would lead to extra function calls with many +-- arguments, redundant tests and confusing messages. + +function chainprocs.chainsub(start,stop,kind,chainname,currentcontext,cache,lookuplist,chainlookupname) + logwarning("%s: a direct call to chainsub cannot happen",cref(kind,chainname,chainlookupname)) + return start, false +end + +-- The reversesub is a special case, which is why we need to store the replacements +-- in a bit weird way. There is no lookup and the replacement comes from the lookup +-- itself. It is meant mostly for dealing with Urdu. + +function chainprocs.reversesub(start,stop,kind,chainname,currentcontext,cache,replacements) + local char = start.char + local replacement = replacements[char] + if replacement then + if trace_singles then + logprocess("%s: single reverse replacement of %s by %s",cref(kind,chainname),gref(char),gref(replacement)) + end + start.char = replacement + return start, true + else + return start, false + end +end + +--[[ldx-- +<p>This chain stuff is somewhat tricky since we can have a sequence of actions to be +applied: single, alternate, multiple or ligature where ligature can be an invalid +one in the sense that it will replace multiple by one but not neccessary one that +looks like the combination (i.e. it is the counterpart of multiple then). For +example, the following is valid:</p> + +<typing> +<line>xxxabcdexxx [single a->A][multiple b->BCD][ligature cde->E] xxxABCDExxx</line> +</typing> + +<p>Therefore we we don't really do the replacement here already unless we have the +single lookup case. The efficiency of the replacements can be improved by deleting +as less as needed but that would also mke the code even more messy.</p> +--ldx]]-- + +local function delete_till_stop(start,stop,ignoremarks) + if start ~= stop then + -- todo keep marks + local done = false + while not done do + done = start == stop + delete_node(start,start.next) + end + end +end + +--[[ldx-- +<p>Here we replace start by a single variant, First we delete the rest of the +match.</p> +--ldx]]-- + +function chainprocs.gsub_single(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,chainindex) + -- todo: marks ? + if not chainindex then + delete_till_stop(start,stop) -- ,currentlookup.flags[1]) + end + local current = start + local subtables = currentlookup.subtables + while current do + if current.id == glyph then + local currentchar = current.char + local lookupname = subtables[1] + local replacement = cache.gsub_single[lookupname] + if not replacement then + if trace_bugs then + logwarning("%s: no single hits",cref(kind,chainname,chainlookupname,lookupname,chainindex)) + end + else + replacement = replacement[currentchar] + if not replacement then + if trace_bugs then + logwarning("%s: no single for %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(currentchar)) + end + else + if trace_singles then + logprocess("%s: replacing single %s by %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(currentchar),gref(replacement)) + end + current.char = replacement + end + end + return start, true + elseif current == stop then + break + else + current = current.next + end + end + return start, false +end + +chainmores.gsub_single = chainprocs.gsub_single + +--[[ldx-- +<p>Here we replace start by a sequence of new glyphs. First we delete the rest of +the match.</p> +--ldx]]-- + +function chainprocs.gsub_multiple(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname) + delete_till_stop(start,stop) + local startchar = start.char + local subtables = currentlookup.subtables + local lookupname = subtables[1] + local replacements = cache.gsub_multiple[lookupname] + if not replacements then + if trace_bugs then + logwarning("%s: no multiple hits",cref(kind,chainname,chainlookupname,lookupname)) + end + else + replacements = replacements[startchar] + if not replacements then + if trace_bugs then + logwarning("%s: no multiple for %s",cref(kind,chainname,chainlookupname,lookupname),gref(startchar)) + end + else + if trace_multiples then + logprocess("%s: replacing %s by multiple characters %s",cref(kind,chainname,chainlookupname,lookupname),gref(startchar),gref(replacements)) + end + local sn = start.next + for k=1,#replacements do + if k == 1 then + start.char = replacements[k] + else + local n = copy_node(start) -- maybe delete the components and such + n.char = replacements[k] + n.next, n.prev = sn, start + if sn then + sn.prev = n + end + start.next, start = n, n + end + end + return start, true + end + end + return start, false +end + +--[[ldx-- +<p>Here we replace start by new glyph. First we delete the rest of the match.</p> +--ldx]]-- + +function chainprocs.gsub_alternate(start,stop,kind,lookupname,currentcontext,cache,currentlookup) + -- todo: marks ? + delete_till_stop(start,stop) + local current = start + local subtables = currentlookup.subtables + while current do + if current.id == glyph then + local currentchar = current.char + local lookupname = subtables[1] + local alternatives = cache.gsub_alternate[lookupname] + if not alternatives then + if trace_bugs then + logwarning("%s: no alternative hits",cref(kind,chainname,chainlookupname,lookupname)) + end + else + alternatives = alternatives[currentchar] + if not alternatives then + if trace_bugs then + logwarning("%s: no alternative for %s",cref(kind,chainname,chainlookupname,lookupname),gref(currentchar)) + end + else + local choice, index = alternative_glyph(current,alternatives,kind,chainname,chainlookupname,lookupname) + current.char = choice + if trace_alternatives then + logprocess("%s: replacing single %s by alternative %s (%s)",cref(kind,chainname,chainlookupname,lookupname),index,gref(currentchar),gref(choice),index) + end + end + end + return start, true + elseif current == stop then + break + else + current = current.next + end + end + return start, false +end + +--[[ldx-- +<p>When we replace ligatures we use a helper that handles the marks. I might change +this function (move code inline and handle the marks by a separate function). We +assume rather stupid ligatures (no complex disc nodes).</p> +--ldx]]-- + +function chainprocs.gsub_ligature(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,chainindex) + local startchar = start.char + local subtables = currentlookup.subtables + local lookupname = subtables[1] + local ligatures = cache.gsub_ligature[lookupname] + if not ligatures then + if trace_bugs then + logwarning("%s: no ligature hits",cref(kind,chainname,chainlookupname,lookupname,chainindex)) + end + else + ligatures = ligatures[startchar] + if not ligatures then + if trace_bugs then + logwarning("%s: no ligatures starting with %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar)) + end + else + local s, discfound, last, nofreplacements = start.next, false, stop, 0 + while s do + local id = s.id + if id == disc then + s = s.next + discfound = true + else + local schar = s.char + if marks[schar] then -- marks + s = s.next + else + local lg = ligatures[1][schar] + if not lg then + break + else + ligatures, last, nofreplacements = lg, s, nofreplacements + 1 + if s == stop then + break + else + s = s.next + end + end + end + end + end + local l2 = ligatures[2] + if l2 then + if chainindex then + stop = last + end + if trace_ligatures then + if start == stop then + logprocess("%s: replacing character %s by ligature %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(l2)) + else + logprocess("%s: replacing character %s upto %s by ligature %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(stop.char),gref(l2)) + end + end + start = toligature(kind,lookup,start,stop,l2,currentlookup.flags[1],discfound) + return start, true, nofreplacements + elseif trace_bugs then + if start == stop then + logwarning("%s: replacing character %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar)) + else + logwarning("%s: replacing character %s upto %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(stop.char)) + end + end + end + end + return start, false, 0 +end + +chainmores.gsub_ligature = chainprocs.gsub_ligature + +function chainprocs.gpos_mark2base(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname) + local markchar = start.char + if marks[markchar] then + local subtables = currentlookup.subtables + local lookupname = subtables[1] + local markanchors = cache.gpos_mark2base[lookupname] + if markanchors then + markanchors = markanchors[markchar] + end + if markanchors then + local base = start.prev -- [glyph] [start=mark] + if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + local basechar = base.char + if marks[basechar] then + while true do + base = base.prev + if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + basechar = base.char + if not marks[basechar] then + break + end + else + if trace_bugs then + logwarning("%s: no base for mark %s",pref(kind,lookupname),gref(markchar)) + end + return start, false + end + end + end + local baseanchors = descriptions[basechar].anchors + if baseanchors then + local baseanchors = baseanchors['basechar'] + if baseanchors then + local al = anchorlookups[lookupname] + for anchor,ba in next, baseanchors do + if al[anchor] then + local ma = markanchors[anchor] + if ma then + local dx, dy, bound = set_mark(start,base,tfmdata.factor,rlmode,ba,ma) + if trace_marks then + logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%s,%s)", + cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) + end + return start, true + end + end + end + if trace_bugs then + logwarning("%s, no matching anchors for mark %s and base %s",cref(kind,chainname,chainlookupname,lookupname),gref(markchar),gref(basechar)) + end + end + end + elseif trace_bugs then + logwarning("%s: prev node is no char",cref(kind,chainname,chainlookupname,lookupname)) + end + elseif trace_bugs then + logwarning("%s: mark %s has no anchors",cref(kind,chainname,chainlookupname,lookupname),gref(markchar)) + end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",cref(kind,chainname,chainlookupname),gref(markchar)) + end + return start, false +end + +function chainprocs.gpos_mark2ligature(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname) + local markchar = start.char + if marks[markchar] then + local subtables = currentlookup.subtables + local lookupname = subtables[1] + local markanchors = cache.gpos_mark2ligature[lookupname] + if markanchors then + markanchors = markanchors[markchar] + end + if markanchors then + local base = start.prev -- [glyph] [optional marks] [start=mark] + local index = 1 + if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + local basechar = base.char + if marks[basechar] then + index = index + 1 + while true do + base = base.prev + if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + basechar = base.char + if marks[basechar] then + index = index + 1 + else + break + end + else + if trace_bugs then + logwarning("%s: no base for mark %s",cref(kind,chainname,chainlookupname,lookupname),markchar) + end + return start, false + end + end + end + -- todo: like marks a ligatures hash + local i = has_attribute(start,markdone) + if i then index = i end + local baseanchors = descriptions[basechar].anchors + if baseanchors then + local baseanchors = baseanchors['baselig'] + if baseanchors then + local al = anchorlookups[lookupname] + for anchor,ba in next, baseanchors do + if al[anchor] then + local ma = markanchors[anchor] + if ma then + ba = ba[index] + if ba then + local dx, dy, bound = set_mark(start,base,tfmdata.factor,rlmode,ba,ma,index) + if trace_marks then + logprocess("%s, anchor %s, bound %s: anchoring mark %s to baselig %s at index %s => (%s,%s)", + cref(kind,chainname,chainlookupname,lookupname),anchor,a or bound,gref(markchar),gref(basechar),index,dx,dy) + end + return start, true + end + end + end + end + if trace_bugs then + logwarning("%s: no matching anchors for mark %s and baselig %s",cref(kind,chainname,chainlookupname,lookupname),gref(markchar),gref(basechar)) + end + end + end + elseif trace_bugs then + logwarning("feature %s, lookup %s: prev node is no char",kind,lookupname) + end + elseif trace_bugs then + logwarning("%s: mark %s has no anchors",cref(kind,chainname,chainlookupname,lookupname),gref(markchar)) + end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",cref(kind,chainname,chainlookupname),gref(markchar)) + end + return start, false +end + +function chainprocs.gpos_mark2mark(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname) + local markchar = start.char + if marks[markchar] then +--~ local alreadydone = markonce and has_attribute(start,markmark) +--~ if not alreadydone then + -- local markanchors = descriptions[markchar].anchors markanchors = markanchors and markanchors.mark + local subtables = currentlookup.subtables + local lookupname = subtables[1] + local markanchors = cache.gpos_mark2mark[lookupname] + if markanchors then + markanchors = markanchors[markchar] + end + if markanchors then + local base = start.prev -- [glyph] [basemark] [start=mark] + if base and base.id == glyph and base.subtype<256 and base.font == currentfont then -- subtype test can go + local basechar = base.char + local baseanchors = descriptions[basechar].anchors + if baseanchors then + baseanchors = baseanchors['basemark'] + if baseanchors then + local al = anchorlookups[lookupname] + for anchor,ba in next, baseanchors do + if al[anchor] then + local ma = markanchors[anchor] + if ma then + local dx, dy, bound = set_mark(start,base,tfmdata.factor,rlmode,ba,ma) + if trace_marks then + logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%s,%s)", + cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) + end + return start, true + end + end + end + if trace_bugs then + logwarning("%s: no matching anchors for mark %s and basemark %s",gref(kind,chainname,chainlookupname,lookupname),gref(markchar),gref(basechar)) + end + end + end + elseif trace_bugs then + logwarning("%s: prev node is no mark",cref(kind,chainname,chainlookupname,lookupname)) + end + elseif trace_bugs then + logwarning("%s: mark %s has no anchors",cref(kind,chainname,chainlookupname,lookupname),gref(markchar)) + end +--~ elseif trace_marks and trace_details then +--~ logprocess("%s, mark %s is already bound (n=%s), ignoring mark2mark",pref(kind,lookupname),gref(markchar),alreadydone) +--~ end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",cref(kind,chainname,chainlookupname),gref(markchar)) + end + return start, false +end + +-- ! ! ! untested ! ! ! + +function chainprocs.gpos_cursive(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname) + local alreadydone = cursonce and has_attribute(start,cursbase) + if not alreadydone then + local startchar = start.char + local subtables = currentlookup.subtables + local lookupname = subtables[1] + local exitanchors = cache.gpos_cursive[lookupname] + if exitanchors then + exitanchors = exitanchors[startchar] + end + if exitanchors then + local done = false + if marks[startchar] then + if trace_cursive then + logprocess("%s: ignoring cursive for mark %s",pref(kind,lookupname),gref(startchar)) + end + else + local nxt = start.next + while not done and nxt and nxt.id == glyph and nxt.subtype<256 and nxt.font == currentfont do + local nextchar = nxt.char + if marks[nextchar] then + -- should not happen (maybe warning) + nxt = nxt.next + else + local entryanchors = descriptions[nextchar] + if entryanchors then + entryanchors = entryanchors.anchors + if entryanchors then + entryanchors = entryanchors['centry'] + if entryanchors then + local al = anchorlookups[lookupname] + for anchor, entry in next, entryanchors do + if al[anchor] then + local exit = exitanchors[anchor] + if exit then + local dx, dy, bound = set_cursive(start,nxt,tfmdata.factor,rlmode,exit,entry,characters[startchar],characters[nextchar]) + if trace_cursive then + logprocess("%s: moving %s to %s cursive (%s,%s) using anchor %s and bound %s in rlmode %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound,rlmode) + 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,chainindex,sequence) + -- 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, w, h = set_pair(start,tfmdata.factor,rlmode,sequence.flags[4],kerns,characters[startchar]) + if trace_kerns then + logprocess("%s: shifting single %s by (%s,%s) and correction (%s,%s)",cref(kind,chainname,chainlookupname),gref(startchar),dx,dy,w,h) + 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,chainindex,sequence) +-- 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 + 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,sequence.flags[4],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,sequence.flags[4],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 show_skip(kind,chainname,char,ck,class) + if ck[9] then + logwarning("%s: skipping char %s (%s) in rule %s, lookuptype %s (%s=>%s)",cref(kind,chainname),gref(char),class,ck[1],ck[2],ck[9],ck[10]) + else + logwarning("%s: skipping char %s (%s) in rule %s, lookuptype %s",cref(kind,chainname),gref(char),class,ck[1],ck[2]) + end +end + +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 !) + local markclass = sequence.markclass -- todo, first we need a proper test + local skipped = false + for k=1,#contexts do + local match, current, last = true, start, start + local ck = contexts[k] + local seq = ck[3] + local s = #seq + -- f..l = mid string + if s == 1 then + -- never happens + match = current.id == glyph and current.subtype<256 and current.font == currentfont and seq[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 seq[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 or (markclass and class == "mark" and not markclass[char]) then + skipped = true + if trace_skips then + show_skip(kind,chainname,char,ck,class) + end + last = last.next + elseif seq[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 + -- before + 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 or (markclass and class == "mark" and not markclass[char]) then + skipped = true + if trace_skips then + show_skip(kind,chainname,char,ck,class) + end + elseif seq[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 seq[n][32] then + n = n -1 + else + match = false break + end + prev = prev.prev + elseif seq[n][32] then + n = n -1 + else + match = false break + end + end + elseif f == 2 then + match = seq[1][32] + else + for n=f-1,1 do + if not seq[n][32] then + match = false break + end + end + end + end + if match and s > l then + -- after + local current = last.next + if current then + -- removed optimization 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 or (markclass and class == "mark" and not markclass[char]) then + skipped = true + if trace_skips then + show_skip(kind,chainname,char,ck,class) + end + elseif seq[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 seq[n][32] then -- brrr + n = n + 1 + else + match = false break + end + current = current.next + elseif seq[n][32] then + n = n + 1 + else + match = false break + end + end + elseif s-l == 1 then + match = seq[s][32] + else + for n=l+1,s do + if not seq[n][32] then + match = false break + end + end + end + end + end + if match then + -- ck == currentcontext + if trace_contexts then + local rule, lookuptype, f, l = ck[1], ck[2], 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,nil,sequence) + 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,sequence) +--~ -- 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 + + local i = 1 + repeat +if skipped then + while true do + local char = start.char + local ccd = descriptions[char] + if ccd then + local class = ccd.class + if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then + start = start.next + else + break + end + else + break + end + end +end + 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,sequence) + -- messy since last can be changed ! + if ok then + done = true + -- skip next one(s) if ligature + i = i + (n or 1) + else + i = i + 1 + end + else + logprocess("%s: multiple subchains for %s are not yet supported",cref(kind,chainname,chainlookupname),chainlookup.type) + i = i + 1 + end + start = start.next + until i > nofchainlookups + + end + else + local replacements = ck[7] + if replacements then + start, done = chainprocs.reversesub(start,last,kind,chainname,ck,cache,replacements) -- sequence + 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,...) -- hm, get rid of ... + 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 + +-- todo: pass all these 'locals' in a table + +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 pardir, txtdir = 0, { } + 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 = s_e or a_e, language + -- elseif l[default] then + -- valid, what = true, default + elseif l[wildcard] then + 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] -- todo: pass to function instead of using a global + 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 ! + local start = find_node_tail(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 { } + local start = head -- local ? + rlmode = 0 -- to be checked ? + 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 has_attribute(start,0,attr) and (not attribute or has_attribute(start,state,attribute)) 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 + 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" or dir == "+TLT" then + insert(txtdir,dir) + elseif dir == "-TRT" or dir == "-TLT" then + remove(txtdir) + end + local d = txtdir[#txtdir] + if d == "+TRT" then + rlmode = -1 + elseif d == "+TLT" then + rlmode = 1 + else + rlmode = pardir + end + if trace_directions then + logs.report("fonts","directions after textdir %s: pardir=%s, txtdir=%s:%s, rlmode=%s",dir,pardir,#txtdir,txtdir[#txtdir] or "unset",rlmode) + end + elseif subtype == 6 then + local dir = start.dir + if dir == "TRT" then + pardir = -1 + elseif dir == "TLT" then + pardir = 1 + else + pardir = 0 + end + rlmode = pardir + --~ txtdir = { } + if trace_directions then + logs.report("fonts","directions after pardir %s: pardir=%s, txtdir=%s:%s, rlmode=%s",dir,pardir,#txtdir,txtdir[#txtdir] or "unset",rlmode) + 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 + local subtype = start.subtype + if subtype == 7 then + local dir = start.dir + if dir == "+TRT" or dir == "+TLT" then + insert(txtdir,dir) + elseif dir == "-TRT" or dir == "-TLT" then + remove(txtdir) + end + local d = txtdir[#txtdir] + if d == "+TRT" then + rlmode = -1 + elseif d == "+TLT" then + rlmode = 1 + else + rlmode = pardir + end + if trace_directions then + logs.report("fonts","directions after textdir %s: pardir=%s, txtdir=%s:%s, rlmode=%s",dir,pardir,#txtdir,txtdir[#txtdir] or "unset",rlmode) + end + elseif subtype == 6 then + local dir = start.dir + if dir == "TRT" then + pardir = -1 + elseif dir == "TLT" then + pardir = 1 + else + pardir = 0 + end + rlmode = pardir + --~ txtdir = { } + if trace_directions then + logs.report("fonts","directions after pardir %s: pardir=%s, txtdir=%s:%s, rlmode=%s",dir,pardir,#txtdir,txtdir[#txtdir] or "unset",rlmode) + 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 (although unicode is a unique enough hash) + local o, t, n = { }, { }, 0 + for s in gmatch(original,"[^ ]+") do + local us = unicodes[s] + if type(us) == "number" then -- tonumber(us) + 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 -- tonumber(us) + 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) + -- + local action = { + substitution = function(p,lookup,k,glyph,unicode) + 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 + end, + multiple = function (p,lookup,k,glyph,unicode) + 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 + end, + alternate = function(p,lookup,k,glyph,unicode) + 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 + end, + ligature = function (p,lookup,k,glyph,unicode) + --~ 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 + end, + position = function(p,lookup,k,glyph,unicode) + -- not used + local s = position[lookup] + if not s then s = { } position[lookup] = s end + s[unicode] = p[2] -- direct pointer to kern spec + end, + pair = function(p,lookup,k,glyph,unicode) + 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, + } + -- + for unicode, glyph in next, descriptions do + local lookups = glyph.slookups + if lookups then + for lookup, p in next, lookups do + action[p[1]](p,lookup,k,glyph,unicode) + end + end + local lookups = glyph.mlookups + if lookups then + for lookup, whatever in next, lookups do + for i=1,#whatever do -- normaly one + local p = whatever[i] + action[p[1]](p,lookup,k,glyph,unicode) + 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 + elseif fmt == "glyphs" 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 + -- nearly the same as coverage so we could as well rename it + local rule = rules[nofrules] + local glyphs = rule.glyphs + if glyphs and glyphs.names then + local fore, back, names, sequence = glyphs.fore, glyphs.back, glyphs.names, { } + if fore and fore ~= "" then + fore = lpegmatch(split_at_space,fore) + uncover(fore,sequence,cache,unicodes) + end + local start = #sequence + 1 + names = lpegmatch(split_at_space,names) + uncover(names,sequence,cache,unicodes) + local stop = #sequence + if back and back ~= "" then + back = lpegmatch(split_at_space,back) + uncover(back,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 + 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..a80c515ad --- /dev/null +++ b/tex/context/base/font-otp.lua @@ -0,0 +1,504 @@ +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, type, tostring = next, type, tostring +local sort, concat = table.sort, table.concat + +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 + +local function tabstr(t) -- hashed from core-uti / experiment + local s = { } + for k, v in next, t do + if type(v) == "table" then + s[#s+1] = k.."={"..tabstr(v).."}" + else + s[#s+1] = k.."="..tostring(v) + end + end + sort(s) + return concat(s,",") +end + +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.slookups + if l then + for k,v in next, l do + l[k] = pack(v) + end + end + local l = v.mlookups + 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 + local cc = c.before if cc then c.before = pack(cc) end + local cc = c.after if cc then c.after = pack(cc) end + local cc = c.current if cc then c.current = pack(cc) end + end + local c = vv.reversecoverage + if c then + local cc = c.before if cc then c.before = pack(cc) end + local cc = c.after if cc then c.after = pack(cc) end + local cc = c.current if cc then c.current = pack(cc) end + end + -- no need to pack vv.glyphs + local c = vv.glyphs + if c then + if c.fore == "" then c.fore = nil end + if c.back == "" then c.back = nil end + 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.mlookups + 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 + local unpacked = { } + for k, v in next, data.glyphs do + local tv = t[v.boundingbox] if tv then v.boundingbox = tv end + local l = v.slookups + if l then + for k,v in next, l do + local tv = t[v] if tv then l[k] = tv end + end + end + local l = v.mlookups + if l then + for k,v in next, l do + for i=1,#v do + local vi = v[i] + local tv = t[vi] + if tv then + v[i] = tv + if unpacked[tv] then + vi = false + else + unpacked[tv], vi = true, tv + end + end + if vi then + 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 + end + local m = v.mykerns + if m then + local tm = t[m] + if tm then + v.mykerns = tm + if unpacked[tm] then + m = false + else + unpacked[tm], m = true, tm + end + end + if m then + for k,v in next, m do + local tv = t[v] if tv then m[k] = tv end + end + end + end + local m = v.math + if m then + local mk = m.kerns + if mk then + local tm = t[mk] + if tm then + m.kerns = tm + if unpacked[tm] then + mk = false + else + unpacked[tm], mk = true, tm + end + end + if mk then + for k,v in next, mk do + local tv = t[v] if tv then mk[k] = tv end + end + end + end + end + local a = v.anchors + if a then + local ta = t[a] + if ta then + v.anchors = ta + if not unpacked[ta] then + unpacked[ta], a = true, ta + else + a = false + end + end + 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 + 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 + 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 + -- no need to unpack vv.glyphs + 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 + if not unpacked[tv] then + unpacked[tv], features = true, tv + else + features = false + end + end + if features then + for script, sdata in next, features do + local tv = t[sdata] if tv then features[script] = tv end + 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..2be1bf06c --- /dev/null +++ b/tex/context/base/font-ott.lua @@ -0,0 +1,956 @@ +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', + ['rtlm'] = 'Right To Left Math', -- math + ['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 + +for k, v in next, to_features do + local stripped = gsub(k,"%-"," ") + to_features[stripped] = v + local stripped = gsub(k,"[^a-zA-Z0-9]","") + to_features[stripped] = v +end +for k, v in next, to_features do + to_features[lower(k)] = v +end + +otf.meanings.checkers = { + rand = function(v) + return v and "random" + end +} + +local checkers = otf.meanings.checkers + +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 + k = to_features[k] or k + local c = checkers[k] + h[k] = c and c(v) or 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 new file mode 100644 index 000000000..6aba4d47e --- /dev/null +++ b/tex/context/base/font-pat.lua @@ -0,0 +1,126 @@ +if not modules then modules = { } end modules ['font-pat'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local match, lower, find = string.match, string.lower, string.find + +local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end) + +-- this will become a per font patch file +-- +-- older versions of latin modern didn't have the designsize set +-- so for them we get it from the name + +local patches = fonts.otf.enhancers.patches + +local function patch(data,filename) + if data.design_size == 0 then + local ds = match(file.basename(lower(filename)),"(%d+)") + if ds then + 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 +patches["^lmsans"] = patch +patches["^lmtypewriter"] = patch + +-- for some reason (either it's a bug in the font, or it's +-- a problem in the library) the palatino arabic fonts don't +-- have the mkmk features properly set up + +local function patch(data,filename) + 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 + if trace_loading then + logs.report("load otf","patching mkmk feature (name: %s)", v.name or "?") + end + v.features = { + { + scripts = { + { + langs = { "ARA ", "FAR ", "URD ", "dflt" }, + script = "arab", + }, + }, + tag = "mkmk" + } + } + end + end + end +end + +patches["palatino.*arabic"] = patch + +local function patch_domh(data,filename,threshold) + local m = data.math + if m then + local d = m.DisplayOperatorMinHeight or 0 + if d < threshold then + if trace_loading then + logs.report("load otf","patching DisplayOperatorMinHeight(%s -> %s)",d,threshold) + end + m.DisplayOperatorMinHeight = threshold + end + end + if tex.luatexversion < 48 then + for _, g in next, data.glyphs do + local name = g.name + if find(name,"^integral$") or find(name,"^integral%.vsize") then + local width, italic = g.width or 0, g.italic_correction or 0 + local newwidth = width - italic + if trace_loading then + logs.report("load otf","patching width of %s: %s (width) - %s (italic) = %s",name,width,italic,newwidth) + end + g.width = newwidth + end + end + end +end + +patches["cambria"] = function(data,filename) patch_domh(data,filename,2800) end +patches["cambmath"] = function(data,filename) patch_domh(data,filename,2800) end +patches["asana"] = function(data,filename) patch_domh(data,filename,1350) end diff --git a/tex/context/base/font-run.mkii b/tex/context/base/font-run.mkii new file mode 100644 index 000000000..0a0ddd057 --- /dev/null +++ b/tex/context/base/font-run.mkii @@ -0,0 +1,326 @@ +%D \module +%D [ file=font-run, +%D version=1998.09.11, % (second) +%D version=2001.02.20, % (third) +%D title=\CONTEXT\ Font 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. + +%D [This code is hooked into the core macros and saves some +%D format space.] + +\unprotect + +\gdef\@@onlyenglish#1% + {\blank{\tttf \type {#1} is only available in the english interface}\blank} + +\gdef\dosetshowfonttitle#1% + {\tabskip\zeropoint + \parindent\zeropoint + \setlocalhsize + \doifelsenothing{#1} + {\def\title{[\the\bodyfontsize]}} + {\switchtobodyfont[#1]\def\title{[#1]}} + \doifsomething\fontclass + {\doifnot{[\fontclass]}\title + {\edef\title{[\fontclass]\space\title}}}} + +\gdef\showbodyfont + {\dosingleempty\doshowbodyfont} + +\gdef\doshowbodyfont[#1]% + {\ifinsidefloat\else\startbaselinecorrection\fi + \vbox + {\dosetshowfonttitle{#1}% + \def\bigstrut##1##2% + {\hbox{\vrule + \!!height##1\strutht + \!!depth ##2\strutdp + \!!width \zeropoint}} + \def\next##1##2##3% + {&&##1&&##2\tf##3&&##2\sc##3% + &&##2\sl##3&&##2\it##3&&##2\bf##3&&##2\bs##3&&##2\bi##3% + &&##2\tfx##3&&##2\tfxx##3% + &&##2\tfa##3&&##2\tfb##3&&##2\tfc##3&&##2\tfd##3&\cr}% + \halign to \localhsize + {\bigstrut{1.5}{2}##&\vrule## + \tabskip=\!!zeropoint \!!plus 1fill + &\hfil##\hfil&\vrule##&\hfil##\hfil&\vrule## + &\hfil##\hfil&\vrule##&\hfil##\hfil&\vrule## + &\hfil##\hfil&\vrule##&\hfil##\hfil&\vrule## + &\hfil##\hfil&\vrule##&\hfil##\hfil&\vrule## + &\hfil##\hfil&\vrule##&\hfil##\hfil&\vrule## + &\hfil##\hfil&\vrule##&\hfil##\hfil&\vrule## + &\hfil##\hfil&\vrule##&\hfil##\hfil&##\vrule + \tabskip=\!!zeropoint\cr + \noalign{\hrule} + &\multispan{29}{\vrule\hfil\tttf\strut\title\hfil + \llap{\string\mr\hbox to 1em{\hss:\hss}$\mr \languageparameter\c!text$\quad}\vrule}\cr + \noalign{\hrule}\next{}{\tt\string}{} + \noalign{\hrule}\next{\tt\string\rm}\rm{\languageparameter\c!text} + \noalign{\hrule}\next{\tt\string\ss}\ss{\languageparameter\c!text} + \noalign{\hrule}\next{\tt\string\tt}\tt{\languageparameter\c!text} + \noalign{\hrule}}} + \ifinsidefloat\else\stopbaselinecorrection\fi} + +\gdef\showbodyfontenvironment + {\dosingleempty\doshowbodyfontenvironment} + +\gdef\doshowbodyfontenvironment[#1]% + {\ifinsidefloat\else\startbaselinecorrection\fi + \vbox + {\dosetshowfonttitle{#1}% + \def\next##1% + {&&\getvalue{\bodyfontvariable{##1\s!text}}% + &&\getvalue{\bodyfontvariable{##1\s!script}}% + &&\getvalue{\bodyfontvariable{##1\s!scriptscript}}% + &&\getvalue{\bodyfontvariable{##1\c!x}}% + &&\getvalue{\bodyfontvariable{##1\c!xx}}% + &&\getvalue{\bodyfontvariable{##1\interfaced\v!small}}% + &&\getvalue{\bodyfontvariable{##1\interfaced\v!big}}% + &&\edef\next{\getvalue{\bodyfontvariable{##1\c!interlinespace}}}\ifx\next\empty not set\else\next\fi&\cr + \noalign{\hrule}} + \halign to \localhsize + {##&\vrule##\strut + \tabskip=\!!zeropoint \!!plus 1fill + &\hfil##\hfil&\vrule##&\hfil##\hfil&\vrule##&\hfil##\hfil&\vrule## + &\hfil##\hfil&\vrule##&\hfil##\hfil&\vrule##&\hfil##\hfil&\vrule## + &\hfil##\hfil&\vrule##&\hfil##\hfil&##\vrule + \tabskip\zeropoint\cr + \noalign{\hrule} + &\multispan{17}{\vrule\hfil\tttf\strut\title\hfil}\vrule\cr + \noalign{\hrule} + &&\tttf\tx\s!text&&\tttf\tx\s!script&&\tttf\tx\s!scriptscript + &&\tttf\tx\c!x&&\tttf\tx\c!xx&&\tttf\tx\v!small&&\tttf\tx\v!big + &&\tttf\tx\c!interlinespace&\cr + \noalign{\hrule} + \@EA\globalprocesscommalist\@EA[\bodyfontenvironmentlist]\next}} + \ifinsidefloat\else\stopbaselinecorrection\fi} + +\gdef\showfont + {\dodoubleempty\doshowfont} + +\gdef\doshowfont[#1][#2]% + {\bgroup + \boxrulewidth=.1pt + \setupcolors[\c!state=\v!local]% + \iffirstargument + \definefont[\s!dummy][#1]\dummy + \else\ifdim2.5em>.05\hsize \tx + \ifdim2.5em>.05\hsize \txx + \fi\fi\fi + \ifinsidefloat\else\startbaselinecorrection\fi + \vbox\bgroup + \forgetall + \startoverlay + {\vbox + {\tf \setstrut \dummy + \localcolortrue \offinterlineskip + \dostepwiserecurse{0}{15}{1} + {\let\row\recurselevel + \hbox + {\red + \dostepwiserecurse{0}{15}{1} + {\let\col\recurselevel + \@EA\scratchcounter\normaldblquote\hexnumber\row\hexnumber\col\relax + \edef\rowcol{\the\scratchcounter}% + \iffontchar\font\scratchcounter + \setbox\scratchbox\ruledhbox{\black\char\scratchcounter}% + \ifdim\wd\scratchbox>\zeropoint + \donetrue \else \donefalse + \fi + \else + \setbox\scratchbox\hbox{\gray\vrule\!!width1ex\!!height.5ex\!!depth.5ex}% + \fi + \startoverlay + {\tf\vbox to 2.5em + {\vss + \hbox to 2.5em + {\dummy\ifdim\interwordspace=\zeropoint + \setbox\scratchbox\hbox + {\raise.5\dp\scratchbox\hbox + {\lower.5\ht\scratchbox\copy\scratchbox}}% + \ht\scratchbox\zeropoint + \dp\scratchbox\zeropoint + \else + \ht\scratchbox\strutht + \dp\scratchbox\strutdp + \strut + \fi + \hss\copy\scratchbox\hss} + \vss}} + {\tf\vbox to 2.3em + {\ifdone + \hsize2.4em + \blue + \edef\theshowfontspecs + {\ifnum\hyphenchar\font=\rowcol hyph\else + \ifnum\skewchar \font=\rowcol skew\fi\fi}% + \tinyfont % after \edef, else wrong font analyzed + \doifnot\v!unknown{#2}{{\red\theshowfontspecs}}\hfill\number\rowcol + \vfill + \octnumber\rowcol\hfill\lchexnumbers\rowcol + \par + \fi}} + \stopoverlay}}} + \par}} + {\tf\basegrid[\c!nx=16,\c!ny=16,\c!dx=2.5,\c!dy=2.5,\c!unit=em]} + \stopoverlay + \nointerlineskip + \vskip2pt + % the \noexpand before \blank is needed for non etex + \edef\ascii{name: {\noexpand\black\fontname\font}} + \def\do##1##2{\ifx##1\undefined\else\ifx##1\empty\else##2\fi\fi}% + \doifelse\v!unknown{#2} + {\edef\theshowfontspecs + {name: {\noexpand\black\fontname\font}}} + {\edef\theshowfontspecs + {name: {\noexpand\black\fontname\font}\noexpand\quad + \do\currentencoding{encoding: {\noexpand\black\currentencoding\noexpand\quad}}% + \do\currentmapping {mapping: {\noexpand\black\currentmapping \noexpand\quad}}% + \do\fonthandling {handling: {\noexpand\black\fonthandling }}}}% + \tf % also sets em + \hbox to 40em{\blue\hfill\tinyfont\setstrut\strut\theshowfontspecs} + \egroup + \ifinsidefloat\else\stopbaselinecorrection\fi + \egroup} + +\gdef\showfontstyle + {\dotripleempty\doshowfontstyle} + +\gdef\doshowfontstyle[#1][#2][#3]% + {\ifthirdargument + \bgroup + \raggedright + \switchtobodyfont[#1] + \def\dodocommand##1##2% + {\starttextrule{\tttf #1 ##1 ##2} + \nobreak \getvalue{##2}% + \dorecurse{255} + {\iffontchar\font\recurselevel\relax + \char\recurselevel\relax\space + \fi} + \par \nobreak + \stoptextrule} + \def\docommand##1% + {\getvalue{##1}\processcommacommand[#3]{\dodocommand{##1}}} + \processcommalist[#2]\docommand + \egroup + \else\ifsecondargument + \showfontstyle[#1][#2][\fontalternativelist]% math is gone + \else + \showfontstyle[#1][\c!rm]\showfontstyle[#1][\c!ss] + \showfontstyle[#1][\c!tt]\showfontstyle[#1][\c!mm] + \fi\fi} + +\gdef\showligature#1% + {\hbox{\type{#1}\enspace\red\ruledhbox{\black#1}}} + +\gdef\showligatures[#1]% + {\ifx\starttabulate\undefined + \@@onlyenglish\showligatures + \else + \bgroup + \setupcolors[\c!state=\v!local]% + \def\show##1{\hbox{\red\ruledhbox{\black##1}}}% + \definefont[\s!dummy][#1]\dummy + \starttabulate[|*{9}{c|}] + \NC\type{ff}\NC\type{fi}\NC\type{fl}\NC\type{ffi}\NC\type{ffl}\NC + \type{``}\NC\type{''}\NC\type{--}\NC\type{---}\NC\NR + \NC\show{ff}\NC\show{fi}\NC\show{fl}\NC\show{ffi}\NC\show{ffl}\NC + \show{``}\NC\show{''}\NC\show{--}\NC\show{---}\NC\NR + \stoptabulate + \egroup + \fi} + +\gdef\showfontstrip + {\dosingleempty\doshowfontstrip} + +\gdef\doshowfontstrip[#1]% + {\ifx\starttabulate\undefined + \@@onlyenglish\showfontstrip + \else + \bgroup + \def\dofontstripa##1##2% + {\tttf\string##1} + \def\dofontstripb##1##2% + {\ruledhbox{\switchtobodyfont[#1]##1{##2}}} + \def\dofontstripc##1##2% + {\setbox\scratchbox\hbox{\switchtobodyfont[#1]##1{##2}}% + \tt\tfx\the\ht\scratchbox}% + \def\dofontstripd##1##2% + {\setbox\scratchbox\hbox{\switchtobodyfont[#1]##1{##2}}% + \tt\tfx\the\wd\scratchbox}% + \def\fontstrip##1##2##3% + {\NC##2\rm{##3}\NC + ##2\ss{##3}\NC + ##2\tt{##3}\NC + ##2\mathematics{##3}\NC + \tttf##1\NR} + \starttabulate[|c|c|c|c|c|] + \fontstrip\relax\dofontstripa\empty + \TB + \fontstrip\relax\dofontstripb{xxxx} + \fontstrip\relax\dofontstripb{12345} + \fontstrip\relax\dofontstripb{(Agw)} + \TB + \fontstrip{(x height)}\dofontstripc{x} + \fontstrip{(m width)}\dofontstripd{m} + \stoptabulate + \egroup + \fi} + +\ifx\databox\undefined \newbox\databox \fi + +\gdef\testminimalbaseline#1% + {\setbox\databox\ruledhbox{#1}% + \scratchdimen\ht\databox + \advance\scratchdimen\dp\databox + \scratchtoks{#1}% + \expanded + {\NC \ruledhbox{\the\scratchtoks} + \noexpand \NC -> + \noexpand \NC \the\scratchdimen + \noexpand \NC = + \noexpand \NC \the\ht\databox + \noexpand \NC + + \noexpand \NC \the\dp\databox + \noexpand \NC \ifdim\scratchdimen<\baselineskip < + \else\ifdim\scratchdimen=\baselineskip = + \else > \fi\fi + \noexpand \NC \the\baselineskip + \noexpand \NC (\ifdim\scratchdimen>\baselineskip not \fi ok) + \noexpand \NC \noexpand \NR }} + +\gdef\showminimalbaseline + {\ifx\starttabulate\undefined + \@@onlyenglish\showminimalbaseline + \else + \starttabulate[||T|T|T|T|T|T|T|T|T|] + \testminimalbaseline{\hbox to 1em{\hss\showstruts\strut\hss}}% + \testminimalbaseline{(/)}% + \testminimalbaseline{$\frac{1}{2}x^2_3$} + \stoptabulate + \fi} + +\gdef\showkerning#1% + {\bgroup + \let\MPfshowcommand\ruledhbox + \setMPtext\s!dummy{#1}% + \startMPcode draw textext(\MPstring\s!dummy);\stopMPcode + \egroup} + +\gdef\showcharratio + {\dowithnextboxcontent + {\switchtobodyfont[10pt]}% + {(\expanded{\withoutpt\the\nextboxht},% + \expanded{\withoutpt\the\nextboxdp})}% + \hbox} + +\protect \endinput diff --git a/tex/context/base/font-run.mkiv b/tex/context/base/font-run.mkiv new file mode 100644 index 000000000..aad6bebe8 --- /dev/null +++ b/tex/context/base/font-run.mkiv @@ -0,0 +1,337 @@ +%D \module +%D [ file=font-run, +%D version=1998.09.11, % (second) +%D version=2001.02.20, % (third) +%D title=\CONTEXT\ Font 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. + +%D [This code is hooked into the core macros and saves some +%D format space.] + +\unprotect + +\gdef\@@onlyenglish#1% + {\blank{\tttf \type {#1} is only available in the english interface}\blank} + +\gdef\dosetshowfonttitle#1% + {\tabskip\zeropoint + \parindent\zeropoint + \setlocalhsize + \doifelsenothing{#1} + {\def\title{[\the\bodyfontsize]}} + {\switchtobodyfont[#1]\def\title{[#1]}} + \doifsomething\fontclass + {\doifnot{[\fontclass]}\title + {\edef\title{[\fontclass]\space\title}}}} + +\gdef\showbodyfont + {\dosingleempty\doshowbodyfont} + +\gdef\doshowbodyfont[#1]% + {\ifinsidefloat\else\startbaselinecorrection\fi + \vbox + {\dosetshowfonttitle{#1}% + \def\bigstrut##1##2% + {\hbox{\vrule + \!!height##1\strutht + \!!depth ##2\strutdp + \!!width \zeropoint}} + \def\next##1##2##3% + {&&##1&&##2\tf##3&&##2\sc##3% + &&##2\sl##3&&##2\it##3&&##2\bf##3&&##2\bs##3&&##2\bi##3% + &&##2\tfx##3&&##2\tfxx##3% + &&##2\tfa##3&&##2\tfb##3&&##2\tfc##3&&##2\tfd##3&\cr}% + \halign to \localhsize + {\bigstrut{1.5}{2}##&\vrule## + \tabskip=\!!zeropoint \!!plus 1fill + &\hfil##\hfil&\vrule##&\hfil##\hfil&\vrule## + &\hfil##\hfil&\vrule##&\hfil##\hfil&\vrule## + &\hfil##\hfil&\vrule##&\hfil##\hfil&\vrule## + &\hfil##\hfil&\vrule##&\hfil##\hfil&\vrule## + &\hfil##\hfil&\vrule##&\hfil##\hfil&\vrule## + &\hfil##\hfil&\vrule##&\hfil##\hfil&\vrule## + &\hfil##\hfil&\vrule##&\hfil##\hfil&##\vrule + \tabskip=\!!zeropoint\cr + \noalign{\hrule} + &\multispan{29}{\vrule\hfil\tttf\strut\title\hfil + \llap{\string\mr\hbox to 1em{\hss:\hss}$\mr \languageparameter\c!text$\quad}\vrule}\cr + \noalign{\hrule}\next{}{\tt\string}{} + \noalign{\hrule}\next{\tt\string\rm}\rm{\languageparameter\c!text} + \noalign{\hrule}\next{\tt\string\ss}\ss{\languageparameter\c!text} + \noalign{\hrule}\next{\tt\string\tt}\tt{\languageparameter\c!text} + \noalign{\hrule}}} + \ifinsidefloat\else\stopbaselinecorrection\fi} + +\gdef\showbodyfontenvironment + {\dosingleempty\doshowbodyfontenvironment} + +\gdef\doshowbodyfontenvironment[#1]% + {\ifinsidefloat\else\startbaselinecorrection\fi + \vbox + {\dosetshowfonttitle{#1}% + \def\next##1% + {&&\getvalue{\bodyfontvariable{##1\s!text}}% + &&\getvalue{\bodyfontvariable{##1\s!script}}% + &&\getvalue{\bodyfontvariable{##1\s!scriptscript}}% + &&\getvalue{\bodyfontvariable{##1\c!x}}% + &&\getvalue{\bodyfontvariable{##1\c!xx}}% + &&\getvalue{\bodyfontvariable{##1\interfaced\v!small}}% + &&\getvalue{\bodyfontvariable{##1\interfaced\v!big}}% + &&\edef\next{\getvalue{\bodyfontvariable{##1\c!interlinespace}}}\ifx\next\empty not set\else\next\fi&\cr + \noalign{\hrule}} + \halign to \localhsize + {##&\vrule##\strut + \tabskip=\!!zeropoint \!!plus 1fill + &\hfil##\hfil&\vrule##&\hfil##\hfil&\vrule##&\hfil##\hfil&\vrule## + &\hfil##\hfil&\vrule##&\hfil##\hfil&\vrule##&\hfil##\hfil&\vrule## + &\hfil##\hfil&\vrule##&\hfil##\hfil&##\vrule + \tabskip\zeropoint\cr + \noalign{\hrule} + &\multispan{17}{\vrule\hfil\tttf\strut\title\hfil}\vrule\cr + \noalign{\hrule} + &&\tttf\tx\s!text&&\tttf\tx\s!script&&\tttf\tx\s!scriptscript + &&\tttf\tx\c!x&&\tttf\tx\c!xx&&\tttf\tx\v!small&&\tttf\tx\v!big + &&\tttf\tx\c!interlinespace&\cr + \noalign{\hrule} + \@EA\globalprocesscommalist\@EA[\bodyfontenvironmentlist]\next}} + \ifinsidefloat\else\stopbaselinecorrection\fi} + +\gdef\showfont + {\dodoubleempty\doshowfont} + +\gdef\doshowfont[#1][#2]% + {\bgroup + \iffirstargument + \definefont[\s!dummy][#1]\dummy + \fi + \doifelsenothing{#2} + {\dodoshowfont{#1}{0}} + {\doifelse{#2}\v!all + {\dostepwiserecurse{0}{255}{1} + {\donefalse + \let\charplane\recurselevel + \dostepwiserecurse{0}{255}{1} + {\iffontchar\font\numexpr\charplane*256+\recurselevel\relax + \donetrue + \exitloop + \fi}% + \ifdone + \dodoshowfont{#1}\charplane + \fi}} + {\processcommalist[#2]{\dodoshowfont{#1}}}}% + \egroup} + +\gdef\dodoshowfont#1#2% + {\bgroup + \edef\charplane{\number#2}% + \boxrulewidth=.1pt + \iffirstargument +% \definefont[\s!dummy][#1]\dummy + \else\ifdim2.5em>.05\hsize \tx + \ifdim2.5em>.05\hsize \txx + \fi\fi\fi + \ifinsidefloat\else\startbaselinecorrection\fi + \vbox\bgroup + \forgetall + \startoverlay + {\vbox + {\tf \setstrut \dummy + \offinterlineskip + \dostepwiserecurse{0}{15}{1} + {\let\row\recurselevel + \hbox + {\red + \dostepwiserecurse{0}{15}{1} + {\let\col\recurselevel + \@EA\scratchcounter\string"\hexnumber\row\hexnumber\col\relax + \edef\rowcol{\the\scratchcounter}% + \iffontchar\font\scratchcounter + \setbox\scratchbox\ruledhbox{\black\char\numexpr\charplane*256+\scratchcounter\relax}% + \ifdim\wd\scratchbox>\zeropoint + \donetrue \else \donefalse + \fi + \else + \setbox\scratchbox\hbox{\gray\vrule\!!width1ex\!!height.5ex\!!depth.5ex}% + \fi + \startoverlay + {\tf\vbox to 2.5em + {\vss + \hbox to 2.5em + {\dummy\ifdim\interwordspace=\zeropoint + \setbox\scratchbox\hbox + {\raise.5\dp\scratchbox\hbox + {\lower.5\ht\scratchbox\copy\scratchbox}}% + \ht\scratchbox\zeropoint + \dp\scratchbox\zeropoint + \else + \ht\scratchbox\strutht + \dp\scratchbox\strutdp + \strut + \fi + \hss\copy\scratchbox\hss} + \vss}} + {\tf\vbox to 2.3em + {\ifdone + \hsize2.4em + \blue + \tinyfont + \hfill\number\rowcol + \vfill + \octnumber\rowcol\hfill\lchexnumbers\rowcol + \par + \fi}} + \stopoverlay}}} + \par}} + {\tf\basegrid[\c!nx=16,\c!ny=16,\c!dx=2.5,\c!dy=2.5,\c!unit=em]} + \stopoverlay + \nointerlineskip + \vskip2pt + % the \noexpand before \blank is needed for non etex + \edef\ascii{name: {\noexpand\black\fontname\font}} + \def\do##1##2{\ifx##1\undefined\else\ifx##1\empty\else##2\fi\fi}% + \edef\theshowfontspecs{name: {\noexpand\black\fontname\font}\quad plane: \charplane\enspace"\hexnumber\charplane}% + \tf % also sets em + \hbox to 40em{\blue\hfill\tinyfont\setstrut\strut\theshowfontspecs} + \egroup + \ifinsidefloat\else\stopbaselinecorrection\fi + \egroup} + +\gdef\showfontstyle + {\dotripleempty\doshowfontstyle} + +\gdef\doshowfontstyle[#1][#2][#3]% + {\ifthirdargument + \bgroup + \raggedright + \switchtobodyfont[#1] + \def\dodocommand##1##2% + {\starttextrule{\tttf #1 ##1 ##2} + \nobreak \getvalue{##2}% + \dorecurse{255} + {\iffontchar\font\recurselevel\relax + \char\recurselevel\relax\space + \fi} + \par \nobreak + \stoptextrule} + \def\docommand##1% + {\getvalue{##1}\processcommacommand[#3]{\dodocommand{##1}}} + \processcommalist[#2]\docommand + \egroup + \else\ifsecondargument + \showfontstyle[#1][#2][\fontalternativelist]% math is gone + \else + \showfontstyle[#1][\c!rm]\showfontstyle[#1][\c!ss] + \showfontstyle[#1][\c!tt]\showfontstyle[#1][\c!mm] + \fi\fi} + +\gdef\showligature#1% + {\hbox{\type{#1}\enspace\red\ruledhbox{\black#1}}} + +\gdef\showligatures[#1]% + {\ifx\starttabulate\undefined + \@@onlyenglish\showligatures + \else + \bgroup + \def\show##1{\hbox{\red\ruledhbox{\black##1}}}% + \definefont[\s!dummy][#1]\dummy + \starttabulate[|*{9}{c|}] + \NC\type{ff}\NC\type{fi}\NC\type{fl}\NC\type{ffi}\NC\type{ffl}\NC + \type{``}\NC\type{''}\NC\type{--}\NC\type{---}\NC\NR + \NC\show{ff}\NC\show{fi}\NC\show{fl}\NC\show{ffi}\NC\show{ffl}\NC + \show{``}\NC\show{''}\NC\show{--}\NC\show{---}\NC\NR + \stoptabulate + \egroup + \fi} + +\gdef\showfontstrip + {\dosingleempty\doshowfontstrip} + +\gdef\doshowfontstrip[#1]% + {\ifx\starttabulate\undefined + \@@onlyenglish\showfontstrip + \else + \bgroup + \def\dofontstripa##1##2% + {\tttf\string##1} + \def\dofontstripb##1##2% + {\ruledhbox{\switchtobodyfont[#1]##1{##2}}} + \def\dofontstripc##1##2% + {\setbox\scratchbox\hbox{\switchtobodyfont[#1]##1{##2}}% + \tt\tfx\the\ht\scratchbox}% + \def\dofontstripd##1##2% + {\setbox\scratchbox\hbox{\switchtobodyfont[#1]##1{##2}}% + \tt\tfx\the\wd\scratchbox}% + \def\fontstrip##1##2##3% + {\NC##2\rm{##3}\NC + ##2\ss{##3}\NC + ##2\tt{##3}\NC + ##2\mathematics{##3}\NC + \tttf##1\NR} + \starttabulate[|c|c|c|c|c|] + \fontstrip\relax\dofontstripa\empty + \TB + \fontstrip\relax\dofontstripb{xxxx} + \fontstrip\relax\dofontstripb{12345} + \fontstrip\relax\dofontstripb{(Agw)} + \TB + \fontstrip{(x height)}\dofontstripc{x} + \fontstrip{(m width)}\dofontstripd{m} + \stoptabulate + \egroup + \fi} + +\ifx\databox\undefined \newbox\databox \fi + +\gdef\testminimalbaseline#1% + {\setbox\databox\ruledhbox{#1}% + \scratchdimen\ht\databox + \advance\scratchdimen\dp\databox + \scratchtoks{#1}% + \expanded + {\NC \ruledhbox{\the\scratchtoks} + \noexpand \NC -> + \noexpand \NC \the\scratchdimen + \noexpand \NC = + \noexpand \NC \the\ht\databox + \noexpand \NC + + \noexpand \NC \the\dp\databox + \noexpand \NC \ifdim\scratchdimen<\baselineskip < + \else\ifdim\scratchdimen=\baselineskip = + \else > \fi\fi + \noexpand \NC \the\baselineskip + \noexpand \NC (\ifdim\scratchdimen>\baselineskip not \fi ok) + \noexpand \NC \noexpand \NR }} + +\gdef\showminimalbaseline + {\ifx\starttabulate\undefined + \@@onlyenglish\showminimalbaseline + \else + \starttabulate[||T|T|T|T|T|T|T|T|T|] + \testminimalbaseline{\hbox to 1em{\hss\showstruts\strut\hss}}% + \testminimalbaseline{(/)}% + \testminimalbaseline{$\frac{1}{2}x^2_3$} + \stoptabulate + \fi} + +\gdef\showkerning#1% + {\bgroup + \let\MPfshowcommand\ruledhbox + \setMPtext\s!dummy{#1}% + \startMPcode draw textext(\MPstring\s!dummy);\stopMPcode + \egroup} + +\gdef\showcharratio + {\dowithnextboxcontent + {\switchtobodyfont[10pt]}% + {(\expanded{\withoutpt\the\nextboxht},% + \expanded{\withoutpt\the\nextboxdp})}% + \hbox} + +\protect \endinput diff --git a/tex/context/base/font-syn.lua b/tex/context/base/font-syn.lua new file mode 100644 index 000000000..5ad92e002 --- /dev/null +++ b/tex/context/base/font-syn.lua @@ -0,0 +1,1454 @@ +if not modules then modules = { } end modules ['font-syn'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- todo: subs in lookups requests + +local utf = unicode.utf8 +local next, tonumber = next, tonumber +local gsub, lower, match, find, lower, upper = string.gsub, string.lower, string.match, string.find, string.lower, string.upper +local find, gmatch = string.find, string.gmatch +local concat, sort, format = table.concat, table.sort, string.format +local lpegmatch = lpeg.match +local utfgsub, utflower = utf.gsub, utf.lower +local unpack = unpack or table.unpack + +local trace_names = false trackers.register("fonts.names", function(v) trace_names = v end) +local trace_warnings = false trackers.register("fonts.warnings", function(v) trace_warnings = v end) + +--[[ldx-- +<p>This module implements a name to filename resolver. Names are resolved +using a table that has keys filtered from the font related files.</p> +--ldx]]-- + +local texsprint = (tex and tex.sprint) or print + +fonts = fonts or { } +input = input or { } +texmf = texmf or { } + +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.103 +names.basename = "names" +names.saved = false +names.loaded = false +names.be_clever = true +names.enabled = true +names.autoreload = toboolean(os.env['MTX.FONTS.AUTOLOAD'] or os.env['MTX_FONTS_AUTOLOAD'] or "no") +names.cache = containers.define("fonts","data",names.version,true) + +--[[ldx-- +<p>A few helpers.</p> +--ldx]]-- + +local P, C, Cc, Cs, Carg = lpeg.P, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Carg + +-- what to do with 'thin' + +local weights = Cs ( -- not extra + P("demibold") + + P("semibold") + + P("mediumbold") + + P("ultrabold") + + P("extrabold") + + P("ultralight") + + P("bold") + + P("demi") + + P("semi") + + P("light") + + P("medium") + + P("heavy") + + P("ultra") + + P("black") + + P("bol") -- / "bold" + + P("regular") / "normal" +) + +local styles = Cs ( + P("reverseoblique") / "reverseitalic" + + P("regular") / "normal" + + P("italic") + + P("oblique") / "italic" + + P("slanted") + + P("roman") / "normal" + + P("ital") / "italic" + + P("ita") / "italic" +) + +local widths = Cs( + P("condensed") + + P("thin") + + P("expanded") + + P("cond") / "condensed" + + P("normal") + + P("book") / "normal" +) + +local variants = Cs( -- fax casual + P("smallcaps") + + P("oldstyle") + + P("caps") / "smallcaps" +) + +local any = P(1) + +local analysed_table + +local analyser = Cs ( + ( + weights / function(s) analysed_table[1] = s return "" end + + styles / function(s) analysed_table[2] = s return "" end + + widths / function(s) analysed_table[3] = s return "" end + + variants / function(s) analysed_table[4] = s return "" end + + any + )^0 +) + +local splitter = lpeg.splitat("-") + +function names.splitspec(askedname) + local name, weight, style, width, variant = lpegmatch(splitter,askedname) + weight = weight and lpegmatch(weights, weight) or weight + style = style and lpegmatch(styles, style) or style + width = width and lpegmatch(widths, width) or width + variant = variant and lpegmatch(variants,variant) or variant + if trace_names then + logs.report("fonts","requested name '%s' split in name '%s', weight '%s', style '%s', width '%s' and variant '%s'", + askedname,name or '',weight or '',style or '',width or '',variant or '') + end + if not weight or not weight or not width or not variant then + weight, style, width, variant = weight or "normal", style or "normal", width or "normal", variant or "normal" + if trace_names then + logs.report("fonts","request '%s' normalized to '%s-%s-%s-%s-%s'", + askedname,name,weight,style,width,variant) + end + end + return name or askedname, weight, style, width, variant +end + +local function analysespec(somename) + if somename then + analysed_table = { } + local name = lpegmatch(analyser,somename) + return name, analysed_table[1], analysed_table[2], analysed_table[3], analysed_table[4] + end +end + +--[[ldx-- +<p>It would make sense to implement the filters in the related modules, +but to keep the overview, we define them here.</p> +--ldx]]-- + +filters.otf = fontloader.info +filters.ttf = fontloader.info +filters.ttc = fontloader.info +filters.dfont = fontloader.info + +function fontloader.fullinfo(...) + local ff = fontloader.open(...) + if ff then + local d = ff and fontloader.to_table(ff) + d.glyphs, d.subfonts, d.gpos, d.gsub, d.lookups = nil, nil, nil, nil, nil + fontloader.close(ff) + return d + else + return nil, "error in loading font" + end +end + +filters.otf = fontloader.fullinfo + +function filters.afm(name) + -- we could parse the afm file as well, and then report an error but + -- it's not worth the trouble + local pfbname = resolvers.find_file(file.removesuffix(name)..".pfb","pfb") or "" + if pfbname == "" then + 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 = match(line,"^(.+)%s+(.+)%s*$") + if key and #key > 0 then + hash[lower(key)] = value + end + if find(line,"StartCharMetrics") then + break + end + end + f:close() + return hash + end + end + return nil, "no matching pfb file" +end + +function filters.pfb(name) + return fontloader.info(name) +end + +--[[ldx-- +<p>The scanner loops over the filters using the information stored in +the file databases. Watch how we check not only for the names, but also +for combination with the weight of a font.</p> +--ldx]]-- + +filters.list = { + "otf", "ttf", "ttc", "dfont", "afm", +--~ "ttc", "otf", "ttf", "dfont", "afm", +} + +names.xml_configuration_file = "fonts.conf" -- a bit weird format, bonus feature +names.environment_path_variable = "OSFONTDIR" -- the official way, in minimals etc + +filters.paths = { } +filters.names = { } + +function names.getpaths(trace) + local hash, result = { }, { } + local function collect(t) + for i=1, #t do + 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 = names.environment_path_variable or "" + if path ~= "" then + collect(resolvers.expanded_path_list(path)) + end + if xml then + local confname = names.xml_configuration_file or "" + if confname ~= "" then + -- first look in the tex tree + local name = resolvers.find_file(confname,"other") + if name == "" then + -- after all, fontconfig is a unix thing + name = file.join("/etc",confname) + if not lfs.isfile(name) then + name = "" -- force quit + end + end + if name ~= "" and lfs.isfile(name) then + if trace_names then + logs.report("fontnames","loading fontconfig file: %s",name) + end + local xmldata = xml.load(name) + -- begin of untested mess + xml.include(xmldata,"include","",true,function(incname) + if not file.is_qualified_path(incname) then + local path = file.dirname(name) -- main name + if path ~= "" then + incname = file.join(path,incname) + end + end + if lfs.isfile(incname) then + if trace_names then + logs.report("fontnames","merging included fontconfig file: %s",incname) + end + return io.loaddata(incname) + elseif trace_names then + logs.report("fontnames","ignoring included fontconfig file: %s",incname) + end + end) + -- end of untested mess + local fontdirs = xml.collect_texts(xmldata,"dir",true) + if trace_names then + logs.report("fontnames","%s dirs found in fontconfig",#fontdirs) + end + collect(fontdirs) + end + end + end + function names.getpaths() + return result + end + return result +end + +local function cleanname(name) + return (gsub(lower(name),"[^%a%d]","")) + -- once we can load files with utf names, we can play with the following: + -- return (utfgsub(utfgsub(lower(str),"[^%a%A%d]",""),"%s","")) +end + +names.cleanname = cleanname + +local function check_names(result) + local names = result.names + if names then + for i=1,#names do + local name = names[i] + if name.lang == "English (US)" then + return name.names + end + end + end +end + +local function walk_tree(pathlist,suffix,identify) + if pathlist then + for i=1,#pathlist do + local path = pathlist[i] + 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) + sort(t,sorter) + for j=1,#t do + local completename = t[j] + identify(completename,file.basename(completename),suffix,completename) + end + end + end +end + +local function check_name(data,result,filename,suffix,subfont) + -- shortcuts + local specifications = data.specifications + local families = data.families + -- prepare + local names = check_names(result) + -- fetch + local familyname = (names and names.preffamilyname) or result.familyname + local fullname = (names and names.fullname) or result.fullname + local fontname = result.fontname + local subfamily = (names and names.subfamily) + local modifiers = (names and names.prefmodifiers) + local weight = (names and names.weight) or result.weight + local italicangle = tonumber(result.italicangle) + local subfont = subfont or nil + local rawname = fullname or fontname or familyname + -- normalize + familyname = familyname and cleanname(familyname) + fullname = fullname and cleanname(fullname) + fontname = fontname and cleanname(fontname) + subfamily = subfamily and cleanname(subfamily) + modifiers = modifiers and cleanname(modifiers) + weight = weight and cleanname(weight) + italicangle = (italicangle == 0) and nil + -- analyse + local a_name, a_weight, a_style, a_width, a_variant = analysespec(fullname or fontname or familyname) + -- check + local width = a_width + local variant = a_variant + local style = modifiers and gsub(modifiers,"[^%a]","") + if not style and italicangle then + style = "italic" + end + if not variant or variant == "" then + variant = "normal" + end + if not weight or weight == "" then + weight = a_weight + end + if not style or style == "" then + style = a_style + end + if not familyname then + familyname = a_name + end + fontname = fontname or fullname or familyname or file.basename(filename) + fullname = fullname or fontname + familyname = familyname or fontname + specifications[#specifications + 1] = { + filename = filename, + format = lower(suffix), + subfont = subfont, + rawname = rawname, + familyname = familyname, + fullname = fullname, + fontname = fontname, + subfamily = subfamily, + modifiers = modifiers, + weight = weight, + style = style, + width = width, + variant = variant, + minsize = result.design_range_bottom or 0, + maxsize = result.design_range_top or 0, + designsize = result.design_size or 0, + } +end + +local function cleanupkeywords() + local data = names.data + local specifications = names.data.specifications + if specifications then + local weights, styles, widths, variants = { }, { }, { }, { } + for i=1,#specifications do + local s = specifications[i] + -- fix (sofar styles are taken from the name, and widths from the specification) + local _, b_weight, b_style, b_width, b_variant = analysespec(s.weight) + local _, c_weight, c_style, c_width, c_variant = analysespec(s.style) + local _, d_weight, d_style, d_width, d_variant = analysespec(s.width) + local _, e_weight, e_style, e_width, e_variant = analysespec(s.variant) + local _, f_weight, f_style, f_width, f_variant = analysespec(s.fullname or "") + local weight = b_weight or c_weight or d_weight or e_weight or f_weight or "normal" + local style = b_style or c_style or d_style or e_style or f_style or "normal" + local width = b_width or c_width or d_width or e_width or f_width or "normal" + local variant = b_variant or c_variant or d_variant or e_variant or f_variant or "normal" + if not weight or weight == "" then weight = "normal" end + if not style or style == "" then style = "normal" end + if not width or width == "" then width = "normal" end + if not variant or variant == "" then variant = "normal" end + weights [weight ] = (weights [weight ] or 0) + 1 + styles [style ] = (styles [style ] or 0) + 1 + widths [width ] = (widths [width ] or 0) + 1 + variants[variant] = (variants[variant] or 0) + 1 + if weight ~= s.weight then + s.fontweight = s.weight + end + s.weight, s.style, s.width, s.variant = weight, style, width, variant + end + local stats = data.statistics + stats.used_weights, stats.used_styles, stats.used_widths, stats.used_variants = weights, styles, widths, variants + end +end + +local function collectstatistics() + local data = names.data + local specifications = data.specifications + if specifications then + local weights, styles, widths, variants = { }, { }, { }, { } + for i=1,#specifications do + local s = specifications[i] + local weight, style, width, variant = s.weight, s.style, s.width, s.variant + if weight then weights [weight ] = (weights [weight ] or 0) + 1 end + if style then styles [style ] = (styles [style ] or 0) + 1 end + if width then widths [width ] = (widths [width ] or 0) + 1 end + if variant then variants[variant] = (variants[variant] or 0) + 1 end + end + local stats = data.statistics + stats.weights, stats.styles, stats.widths, stats.variants, stats.fonts = weights, styles, widths, variants, #specifications + end +end + +local function collecthashes() + local data = names.data + local mappings = data.mappings + local fallbacks = data.fallbacks + local specifications = data.specifications + local nofmappings, noffallbacks = 0, 0 + if specifications then + -- maybe multiple passes + for index=1,#specifications do + local s = specifications[index] + local format, fullname, fontname, familyname, weight, subfamily = s.format, s.fullname, s.fontname, s.familyname, s.weight, s.subfamily + local mf, ff = mappings[format], fallbacks[format] + if fullname and not mf[fullname] then + mf[fullname], nofmappings = index, nofmappings + 1 + end + if fontname and not mf[fontname] then + mf[fontname], nofmappings = index, nofmappings + 1 + end + if familyname and weight then + local madename = familyname .. weight + if not mf[madename] and not ff[madename] then + ff[madename], noffallbacks = index, noffallbacks + 1 + end + end + if familyname and subfamily then + local extraname = familyname .. subfamily + if not mf[extraname] and not ff[extraname] then + ff[extraname], noffallbacks = index, noffallbacks + 1 + end + end + if familyname then + if not mf[familyname] and not ff[familyname] then + ff[familyname], noffallbacks = index, noffallbacks + 1 + end + end + end + end + return nofmappings, noffallbacks +end + +local function collectfamilies() + local data = names.data + local specifications = data.specifications + local families = data.families + for index=1,#specifications do + local familyname = specifications[index].familyname + local family = families[familyname] + if not family then + families[familyname] = { index } + else + family[#family+1] = index + end + end +end + +local function checkduplicate(where) -- fails on "Romantik" but that's a border case anyway + local data = names.data + local mapping = data[where] + local specifications, loaded = data.specifications, { } + if specifications and mapping then + for _, m in next, mapping do + for k, v in next, m do + local s = specifications[v] + local hash = format("%s-%s-%s-%s-%s",s.familyname,s.weight or "*",s.style or "*",s.width or "*",s.variant or "*") + local h = loaded[hash] + if h then + local ok = true + local fn = s.filename + for i=1,#h do + local hn = s.filename + if h[i] == fn then + ok = false + break + end + end + if ok then + h[#h+1] = fn + end + else + loaded[hash] = { s.filename } + end + end + end + end + local n = 0 + for k, v in table.sortedhash(loaded) do + local nv = #v + if nv > 1 then + if trace_warnings then + logs.report("fontnames", "double lookup: %s => %s",k,concat(v," | ")) + end + n = n + nv + end + end + logs.report("fontnames", "%s double lookups in %s",n,where) +end + +local function checkduplicates() + checkduplicate("mappings") + checkduplicate("fallbacks") +end + +local sorter = function(a,b) + return a > b -- to be checked +end + +local function sorthashes() + local data, list = names.data, filters.list + local mappings, fallbacks, sorted_mappings, sorted_fallbacks = data.mappings, data.fallbacks, { }, { } + data.sorted_mappings, data.sorted_fallbacks = sorted_mappings, sorted_fallbacks + for i=1,#list do + local l = list[i] + sorted_mappings[l], sorted_fallbacks[l] = table.keys(mappings[l]), table.keys(fallbacks[l]) + sort(sorted_mappings[l],sorter) + sort(sorted_fallbacks[l],sorter) + end + data.sorted_families = table.keys(data.families) + sort(data.sorted_families,sorter) +end + +local function unpackreferences() + local data = names.data + local specifications = data.specifications + if specifications then + for k, v in next, data.families do + for i=1,#v do + v[i] = specifications[v[i]] + end + end + local mappings = data.mappings + if mappings then + for _, m in next, mappings do + for k, v in next, m do + m[k] = specifications[v] + end + end + end + local fallbacks = data.fallbacks + if fallbacks then + for _, f in next, fallbacks do + for k, v in next, f do + f[k] = specifications[v] + end + end + end + end +end + +local function analysefiles() + local data = names.data + local done, totalnofread, totalnofskipped = { }, 0, 0 + local skip_paths, skip_names = filters.paths, filters.names + local function identify(completename,name,suffix,storedname) + local basename = file.basename(completename) + local basepath = file.dirname(completename) + if done[name] then + -- already done (avoid otf afm clash) + elseif not io.exists(completename) then + -- weird error + elseif not file.is_qualified_path(completename) and resolvers.find_file(completename,suffix) == "" then + -- not locateble by backend anyway + else + nofread = nofread + 1 + if #skip_paths > 0 then + for i=1,#skip_paths do + if find(basepath,skip_paths[i]) then + if trace_names then + logs.report("fontnames","rejecting path of %s font %s",suffix,completename) + logs.push() + end + return + end + end + end + if #skip_names > 0 then + for i=1,#skip_paths do + if find(basename,skip_names[i]) then + done[name] = true + if trace_names then + logs.report("fontnames","rejecting name of %s font %s",suffix,completename) + logs.push() + end + return + end + end + end + if trace_names then + logs.report("fontnames","identifying %s font %s",suffix,completename) + logs.push() + end + local result, message = filters[lower(suffix)](completename) + if trace_names then + logs.pop() + end + if result then + if not result[1] then + local ok = check_name(data,result,storedname,suffix) + if not ok then + nofskipped = nofskipped + 1 + end + else + for r=1,#result do + local ok = check_name(data,result[r],storedname,suffix,r-1) -- subfonts start at zero + if not ok then + nofskipped = nofskipped + 1 + end + end + end + if trace_warnings and message and message ~= "" then + logs.report("fontnames","warning when identifying %s font %s: %s",suffix,completename,message) + end + elseif trace_warnings then + logs.report("fontnames","error when identifying %s font %s: %s",suffix,completename,message or "unknown") + end + done[name] = true + end + end + local function traverse(what, method) + local list = filters.list + for n=1,#list do + local suffix = list[n] + local t = os.gettimeofday() -- use elapser + nofread, nofskipped = 0, 0 + suffix = lower(suffix) + logs.report("fontnames", "identifying %s font files with suffix %s",what,suffix) + method(suffix) + suffix = upper(suffix) + logs.report("fontnames", "identifying %s font files with suffix %s",what,suffix) + method(suffix) + totalnofread, totalnofskipped = totalnofread + nofread, totalnofskipped + nofskipped + local elapsed = os.gettimeofday() - t + logs.report("fontnames", "%s %s files identified, %s hash entries added, runtime %0.3f seconds",nofread,what,nofread-nofskipped,elapsed) + end + end + if not trace_warnings then + logs.report("fontnames", "warnings are disabled (tracker 'fonts.warnings')") + 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,identify) + end) + else + traverse("system", function(suffix) -- OSFONTDIR cum suis + walk_tree(names.getpaths(trace),suffix,identify) + end) + end + data.statistics.readfiles, data.statistics.skippedfiles = totalnofread, totalnofskipped +end + +local function rejectclashes() -- just to be sure, so no explicit afm will be found then + local specifications, used, okay = names.data.specifications, { }, { } + for i=1,#specifications do + local s = specifications[i] + local f = s.fontname + if f then + local fnd, fnm = used[f], s.filename + if fnd then + if trace_warnings then + logs.report("fontnames", "fontname '%s' clashes, rejecting '%s' in favor of '%s'",f,fnm,fnd) + end + else + used[f], okay[#okay+1] = fnm, s + end + else + okay[#okay+1] = s + end + end + local d = #specifications - #okay + if d > 0 then + logs.report("fontnames", "%s files rejected due to clashes",d) + end + names.data.specifications = okay +end + +local function resetdata() + local mappings, fallbacks = { }, { } + for _, k in next, filters.list do + mappings[k], fallbacks[k] = { }, { } + end + names.data = { + version = names.version, + mappings = mappings, + fallbacks = fallbacks, + specifications = { }, + families = { }, + statistics = { }, + data_state = resolvers.data_state(), + } +end + +function names.identify() + resetdata() + analysefiles() + rejectclashes() + collectfamilies() + collectstatistics() + cleanupkeywords() + collecthashes() + checkduplicates() + -- sorthashes() -- will be resorted when saved +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 names.load(reload,verbose) + if not names.loaded then + if reload then + 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 + names.saved = true + end + local data = names.read_data(names.basename) + names.data = data + if not names.saved then + if not data or not next(data) or not data.specifications or not next(data.specifications) then + names.load(true) + end + names.saved = true + end + if not data then + logs.report("font table", "accessing the data table failed") + else + unpackreferences() + sorthashes() + end + names.loaded = true + end +end + +local function list_them(mapping,sorted,pattern,t,all) + if mapping[pattern] then + t[pattern] = mapping[pattern] + else + for k=1,#sorted do + local v = sorted[k] + if not t[v] and find(v,pattern) then + t[v] = mapping[v] + if not all then + return + end + end + end + end +end + +function names.list(pattern,reload,all) -- here? + names.load(reload) + if names.loaded then + local t = { } + local data = names.data + if data then + local list = filters.list + local mappings, sorted_mappings = data.mappings, data.sorted_mappings + local fallbacks, sorted_fallbacks = data.fallbacks, data.sorted_fallbacks + for i=1,#list do + local format = list[i] + list_them(mappings[format],sorted_mappings[format],pattern,t,all) + if next(t) and not all then + return t + end + list_them(fallbacks[format],sorted_fallbacks[format],pattern,t,all) + if next(t) and not all then + return t + end + end + end + return t + end +end + +local reloaded = false + +local function is_reloaded() + if not reloaded then + local data = names.data + if names.autoreload then + local c_status = table.serialize(resolvers.data_state()) + local f_status = table.serialize(data.data_state) + if c_status == f_status then + -- logs.report("fonts","font database matches configuration and file hashes") + return + else + logs.report("fonts","font database does not match configuration and file hashes") + end + end + names.loaded = false + reloaded = true + io.flush() + names.load(true) + end +end + +--[[ldx-- +<p>The resolver also checks if the cached names are loaded. Being clever +here is for testing purposes only (it deals with names prefixed by an +encoding name).</p> +--ldx]]-- + +local function fuzzy(mapping,sorted,name,sub) + local condensed = gsub(name,"[^%a%d]","") + for k=1,#sorted do + local v = sorted[k] + if find(v,condensed) then + return mapping[v], v + end + end +end + +-- we could cache a lookup .. maybe some day ... (only when auto loaded!) + +local function foundname(name,sub) -- sub is not used currently + local data = names.data + local mappings, sorted_mappings = data.mappings, data.sorted_mappings + local fallbacks, sorted_fallbacks = data.fallbacks, data.sorted_fallbacks + local list = filters.list + -- dilemma: we lookup in the order otf ttf ttc ... afm but now an otf fallback + -- can come after an afm match ... well, one should provide nice names anyway + -- and having two lists is not an option + for i=1,#list do + local l = list[i] + local found = mappings[l][name] + if found then + if trace_names then + logs.report("fonts","resolved via direct name match: '%s'",name) + end + return found + end + end + for i=1,#list do + local l = list[i] + local found, fname = fuzzy(mappings[l],sorted_mappings[l],name,sub) + if found then + if trace_names then + logs.report("fonts","resolved via fuzzy name match: '%s' => '%s'",name,fname) + end + return found + end + end + for i=1,#list do + local l = list[i] + local found = fallbacks[l][name] + if found then + if trace_names then + logs.report("fonts","resolved via direct fallback match: '%s'",name) + end + return found + end + end + for i=1,#list do + local l = list[i] + local found, fname = fuzzy(sorted_mappings[l],sorted_fallbacks[l],name,sub) + if found then + if trace_names then + logs.report("fonts","resolved via fuzzy fallback match: '%s' => '%s'",name,fname) + end + return found + end + end +end + +function names.resolvedspecification(askedname,sub) + if askedname and askedname ~= "" and names.enabled then + askedname = cleanname(askedname) + names.load() + local found = foundname(askedname,sub) + if not found and is_reloaded() then + found = foundname(askedname,sub) + end + return found + end +end + +function names.resolve(askedname,sub) + local found = names.resolvedspecification(askedname,sub) + if found then + return found.filename, found.subfont and found.rawname + end +end + +-- specified search + +local function s_collect_weight_style_width_variant(found,done,all,weight,style,width,variant,family) + if family then + for i=1,#family do + local f = family[i] + if f and weight == f.weight and style == f.style and width == f.width and variant == f.variant then + found[#found+1], done[f] = f, true + if not all then return end + end + end + end +end +local function m_collect_weight_style_width_variant(found,done,all,weight,style,width,variant,families,sorted,strictname) + for i=1,#sorted do + local k = sorted[i] + local family = families[k] + for i=1,#family do + local f = family[i] + if not done[f] and weight == f.weight and style == f.style and width == f.width and variant == f.variant and find(f.fontname,strictname) then + found[#found+1], done[f] = f, true + if not all then return end + end + end + end +end + +local function s_collect_weight_style_width(found,done,all,weight,style,width,family) + if family then + for i=1,#family do + local f = family[i] + if f and weight == f.weight and style == f.style and width == f.width then + found[#found+1], done[f] = f, true + if not all then return end + end + end + end +end +local function m_collect_weight_style_width(found,done,all,weight,style,width,families,sorted,strictname) + for i=1,#sorted do + local k = sorted[i] + local family = families[k] + for i=1,#family do + local f = family[i] + if not done[f] and weight == f.weight and style == f.style and width == f.width and find(f.fontname,strictname) then + found[#found+1], done[f] = f, true + if not all then return end + end + end + end +end + +local function s_collect_weight_style(found,done,all,weight,style,family) + if family then + for i=1,#family do local f = family[i] + if f and weight == f.weight and style == f.style then + found[#found+1], done[f] = f, true + if not all then return end + end + end + end +end +local function m_collect_weight_style(found,done,all,weight,style,families,sorted,strictname) + for i=1,#sorted do + local k = sorted[i] + local family = families[k] + for i=1,#family do + local f = family[i] + if not done[f] and weight == f.weight and style == f.style and find(f.fontname,strictname) then + found[#found+1], done[f] = f, true + if not all then return end + end + end + end +end + +local function s_collect_style_width(found,done,all,style,width,family) + if family then + for i=1,#family do local f = family[i] + if f and style == f.style and width == f.width then + found[#found+1], done[f] = f, true + if not all then return end + end + end + end +end +local function m_collect_style_width(found,done,all,style,width,families,sorted,strictname) + for i=1,#sorted do + local k = sorted[i] + local family = families[k] + for i=1,#family do + local f = family[i] + if not done[f] and style == f.style and width == f.width and find(f.fontname,strictname) then + found[#found+1], done[f] = f, true + if not all then return end + end + end + end +end + +local function s_collect_weight(found,done,all,weight,family) + if family then + for i=1,#family do local f = family[i] + if f and weight == f.weight then + found[#found+1], done[f] = f, true + if not all then return end + end + end + end +end +local function m_collect_weight(found,done,all,weight,families,sorted,strictname) + for i=1,#sorted do + local k = sorted[i] + local family = families[k] + for i=1,#family do + local f = family[i] + if not done[f] and weight == f.weight and find(f.fontname,strictname) then + found[#found+1], done[f] = f, true + if not all then return end + end + end + end +end + +local function s_collect_style(found,done,all,style,family) + if family then + for i=1,#family do local f = family[i] + if f and style == f.style then + found[#found+1], done[f] = f, true + if not all then return end + end + end + end +end +local function m_collect_style(found,done,all,style,families,sorted,strictname) + for i=1,#sorted do + local k = sorted[i] + local family = families[k] + for i=1,#family do + local f = family[i] + if not done[f] and style == f.style and find(f.fontname,strictname) then + found[#found+1], done[f] = f, true + if not all then return end + end + end + end +end + +local function s_collect_width(found,done,all,width,family) + if family then + for i=1,#family do local f = family[i] + if f and width == f.width then + found[#found+1], done[f] = f, true + if not all then return end + end + end + end +end +local function m_collect_width(found,done,all,width,families,sorted,strictname) + for i=1,#sorted do + local k = sorted[i] + local family = families[k] + for i=1,#family do + local f = family[i] + if not done[f] and width == f.width and find(f.fontname,strictname) then + found[#found+1], done[f] = f, true + if not all then return end + end + end + end +end + +local function s_collect(found,done,all,family) + if family then + for i=1,#family do local f = family[i] + if f then + found[#found+1], done[f] = f, true + if not all then return end + end + end + end +end +local function m_collect(found,done,all,families,sorted,strictname) + for i=1,#sorted do + local k = sorted[i] + local family = families[k] + for i=1,#family do + local f = family[i] + if not done[f] and find(f.fontname,strictname) then + found[#found+1], done[f] = f, true + if not all then return end + end + end + end +end + +local function collect(stage,found,done,name,weight,style,width,variant,all) + local data = names.data + local families, sorted = data.families, data.sorted_families + strictname = "^".. name -- to be checked + local family = families[name] + if trace_names then + logs.report("fonts","resolving name '%s', weight '%s', style '%s', width '%s', variant '%s'", + name or "?",tostring(weight),tostring(style),tostring(width),tostring(variant)) + end + --~ print(name,table.serialize(family)) + if weight and weight ~= "" then + if style and style ~= "" then + if width and width ~= "" then + if variant and variant ~= "" then + if trace_names then + logs.report("fonts","resolving stage %s, name '%s', weight '%s', style '%s', width '%s', variant '%s'",stage,name,weight,style,width,variant) + end + s_collect_weight_style_width_variant(found,done,all,weight,style,width,variant,family) + m_collect_weight_style_width_variant(found,done,all,weight,style,width,variant,families,sorted,strictname) + else + if trace_names then + logs.report("fonts","resolving stage %s, name '%s', weight '%s', style '%s', width '%s'",stage,name,weight,style,width) + end + s_collect_weight_style_width(found,done,all,weight,style,width,family) + m_collect_weight_style_width(found,done,all,weight,style,width,families,sorted,strictname) + end + else + if trace_names then + logs.report("fonts","resolving stage %s, name '%s', weight '%s', style '%s'",stage,name,weight,style) + end + s_collect_weight_style(found,done,all,weight,style,family) + m_collect_weight_style(found,done,all,weight,style,families,sorted,strictname) + end + else + if trace_names then + logs.report("fonts","resolving stage %s, name '%s', weight '%s'",stage,name,weight) + end + s_collect_weight(found,done,all,weight,family) + m_collect_weight(found,done,all,weight,families,sorted,strictname) + end + elseif style and style ~= "" then + if width and width ~= "" then + if trace_names then + logs.report("fonts","resolving stage %s, name '%s', style '%s', width '%s'",stage,name,style,width) + end + s_collect_style_width(found,done,all,style,width,family) + m_collect_style_width(found,done,all,style,width,families,sorted,strictname) + else + if trace_names then + logs.report("fonts","resolving stage %s, name '%s', style '%s'",stage,name,style) + end + s_collect_style(found,done,all,style,family) + m_collect_style(found,done,all,style,families,sorted,strictname) + end + elseif width and width ~= "" then + if trace_names then + logs.report("fonts","resolving stage %s, name '%s', width '%s'",stage,name,width) + end + s_collect_width(found,done,all,width,family) + m_collect_width(found,done,all,width,families,sorted,strictname) + else + if trace_names then + logs.report("fonts","resolving stage %s, name '%s'",stage,name) + end + s_collect(found,done,all,family) + m_collect(found,done,all,families,sorted,strictname) + end +end + +function heuristic(name,weight,style,width,variant,all) -- todo: fallbacks + local found, done = { }, { } +--~ print(name,weight,style,width,variant) + weight, style, width, variant = weight or "normal", style or "normal", width or "normal", variant or "normal" + name = cleanname(name) + collect(1,found,done,name,weight,style,width,variant,all) + -- still needed ? + if #found == 0 and variant ~= "normal" then -- not weight + variant = "normal" + collect(4,found,done,name,weight,style,width,variant,all) + end + if #found == 0 and width ~= "normal" then + width = "normal" + collect(2,found,done,name,weight,style,width,variant,all) + end + if #found == 0 and weight ~= "normal" then -- not style + weight = "normal" + collect(3,found,done,name,weight,style,width,variant,all) + end + if #found == 0 and style ~= "normal" then -- not weight + style = "normal" + collect(4,found,done,name,weight,style,width,variant,all) + end + -- + local nf = #found + if trace_names then + if nf then + local t = { } + for i=1,nf do + t[#t+1] = format("'%s'",found[i].fontname) + end + logs.report("fonts","name '%s' resolved to %s instances: %s",name,nf,concat(t," ")) + else + logs.report("fonts","name '%s' unresolved",name) + end + end + if all then + return nf > 0 and found + else + return found[1] + end +end + +function names.specification(askedname,weight,style,width,variant,reload,all) + if askedname and askedname ~= "" and names.enabled then + askedname = lower(askedname) -- or cleanname + names.load(reload) + local found = heuristic(askedname,weight,style,width,variant,all) + if not found and is_reloaded() then + found = heuristic(askedname,weight,style,width,variant,all) + if not filename then + found = foundname(askedname) -- old method + end + end + return found + end +end + +function names.collect(askedname,weight,style,width,variant,reload,all) + if askedname and askedname ~= "" and names.enabled then + askedname = lower(askedname) -- or cleanname + names.load(reload) + local list = heuristic(askedname,weight,style,width,variant,true) + if not list or #list == 0 and is_reloaded() then + list = heuristic(askedname,weight,style,width,variant,true) + end + return list + end +end + +function names.collectspec(askedname,reload,all) + local name, weight, style, width, variant = names.splitspec(askedname) + return names.collect(name,weight,style,width,variant,reload,all) +end + +function names.resolvespec(askedname,sub) + local found = names.specification(names.splitspec(askedname)) + if found then + return found.filename, found.subfont and found.rawname + end +end + +function names.collectfiles(askedname,reload) -- no all + if askedname and askedname ~= "" and names.enabled then + askedname = lower(askedname) -- or cleanname + names.load(reload) + local list = { } + local basename = file.basename + local specifications = names.data.specifications + for i=1,#specifications do + local s = specifications[i] + if find(lower(basename(s.filename)),askedname) then + list[#list+1] = s + end + end + return list + end +end + +--[[ldx-- +<p>Fallbacks, not permanent but a transition thing.</p> +--ldx]]-- + +names.new_to_old = { + ["lmroman10-capsregular"] = "lmromancaps10-oblique", + ["lmroman10-capsoblique"] = "lmromancaps10-regular", + ["lmroman10-demi"] = "lmromandemi10-oblique", + ["lmroman10-demioblique"] = "lmromandemi10-regular", + ["lmroman8-oblique"] = "lmromanslant8-regular", + ["lmroman9-oblique"] = "lmromanslant9-regular", + ["lmroman10-oblique"] = "lmromanslant10-regular", + ["lmroman12-oblique"] = "lmromanslant12-regular", + ["lmroman17-oblique"] = "lmromanslant17-regular", + ["lmroman10-boldoblique"] = "lmromanslant10-bold", + ["lmroman10-dunhill"] = "lmromandunh10-oblique", + ["lmroman10-dunhilloblique"] = "lmromandunh10-regular", + ["lmroman10-unslanted"] = "lmromanunsl10-regular", + ["lmsans10-demicondensed"] = "lmsansdemicond10-regular", + ["lmsans10-demicondensedoblique"] = "lmsansdemicond10-oblique", + ["lmsansquotation8-bold"] = "lmsansquot8-bold", + ["lmsansquotation8-boldoblique"] = "lmsansquot8-boldoblique", + ["lmsansquotation8-oblique"] = "lmsansquot8-oblique", + ["lmsansquotation8-regular"] = "lmsansquot8-regular", + ["lmtypewriter8-regular"] = "lmmono8-regular", + ["lmtypewriter9-regular"] = "lmmono9-regular", + ["lmtypewriter10-regular"] = "lmmono10-regular", + ["lmtypewriter12-regular"] = "lmmono12-regular", + ["lmtypewriter10-italic"] = "lmmono10-italic", + ["lmtypewriter10-oblique"] = "lmmonoslant10-regular", + ["lmtypewriter10-capsoblique"] = "lmmonocaps10-oblique", + ["lmtypewriter10-capsregular"] = "lmmonocaps10-regular", + ["lmtypewriter10-light"] = "lmmonolt10-regular", + ["lmtypewriter10-lightoblique"] = "lmmonolt10-oblique", + ["lmtypewriter10-lightcondensed"] = "lmmonoltcond10-regular", + ["lmtypewriter10-lightcondensedoblique"] = "lmmonoltcond10-oblique", + ["lmtypewriter10-dark"] = "lmmonolt10-bold", + ["lmtypewriter10-darkoblique"] = "lmmonolt10-boldoblique", + ["lmtypewritervarwd10-regular"] = "lmmonoproplt10-regular", + ["lmtypewritervarwd10-oblique"] = "lmmonoproplt10-oblique", + ["lmtypewritervarwd10-light"] = "lmmonoprop10-regular", + ["lmtypewritervarwd10-lightoblique"] = "lmmonoprop10-oblique", + ["lmtypewritervarwd10-dark"] = "lmmonoproplt10-bold", + ["lmtypewritervarwd10-darkoblique"] = "lmmonoproplt10-boldoblique", +} + +names.old_to_new = table.swapped(names.new_to_old) + +function names.exists(name) + local found = false + local list = filters.list + for k=1,#list do + local v = list[k] + found = (resolvers.find_file(name,v) or "") ~= "" + if found then + return found + end + end + return ((resolvers.find_file(name,"tfm") or "") ~= "") or ((names.resolve(name) or "") ~= "") +end + +-- for i=1,fonts.names.lookup(pattern) do +-- texio.write_nl(fonts.names.getkey("filename",i)) +-- end + +local lastlookups, lastpattern = { }, "" + +function names.lookup(pattern,name,reload) -- todo: find + if lastpattern ~= pattern then + names.load(reload) + local specifications = names.data.specifications + local families = names.data.families + local lookups = specifications + if name then + lookups = families[name] + elseif not find(pattern,"=") then + lookups = families[pattern] + end + if trace_names then + logs.report("fonts","starting with %s lookups for '%s'",#lookups,pattern) + end + if lookups then + for key, value in gmatch(pattern,"([^=,]+)=([^=,]+)") do + local t = { } + for i=1,#lookups do + local s = lookups[i] + if s[key] == value then + t[#t+1] = lookups[i] + end + end + if trace_names then + logs.report("fonts","%s matches for key '%s' with value '%s'",#t,key,value) + end + lookups = t + end + end + lastpattern = pattern + lastlookups = lookups or { } + end + return #lastlookups +end + +function names.getlookupkey(key,n) + local l = lastlookups[n or 1] + return (l and l[key]) or "" +end + +function names.noflookups() + return #lastlookups +end + +function names.getlookups(pattern,name,reload) + if pattern then + names.lookup(pattern,name,reload) + end + return lastlookups +end + +function table.formatcolumns(result) + if result and #result > 0 then + local widths = { } + local first = result[1] + local n = #first + for i=1,n do + widths[i] = 0 + end + for i=1,#result do + local r = result[i] + for j=1,n do + local w = #r[j] + if w > widths[j] then + widths[j] = w + end + end + end + for i=1,n do + widths[i] = "%-" .. widths[i] .. "s" + end + local template = concat(widths," ") + for i=1,#result do + local str = format(template,unpack(result[i])) + result[i] = string.strip(str) + end + end + return result +end diff --git a/tex/context/base/font-tfm.lua b/tex/context/base/font-tfm.lua new file mode 100644 index 000000000..31ae2cae1 --- /dev/null +++ b/tex/context/base/font-tfm.lua @@ -0,0 +1,736 @@ +if not modules then modules = { } end modules ['font-tfm'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + 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, gsub = next, string.format, string.match, string.lower, string.gsub +local concat, sortedkeys, utfbyte, serialize = table.concat, table.sortedkeys, utf.byte, table.serialize + +local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) +local trace_scaling = false trackers.register("fonts.scaling" , function(v) trace_scaling = v end) + +-- tfmdata has also fast access to indices and unicodes +-- to be checked: otf -> tfm -> tfmscaled +-- +-- watch out: no negative depths and negative eights permitted in regular fonts + +--[[ldx-- +<p>Here we only implement a few helper functions.</p> +--ldx]]-- + +fonts = fonts or { } +fonts.tfm = fonts.tfm or { } +fonts.ids = fonts.ids or { } + +local tfm = fonts.tfm + +fonts.loaded = fonts.loaded or { } +fonts.dontembed = fonts.dontembed or { } +fonts.triggers = fonts.triggers or { } -- brrr +fonts.initializers = fonts.initializers or { } +fonts.initializers.common = fonts.initializers.common or { } + +local fontdata = fonts.ids +local disc = node.id('disc') +local glyph = node.id('glyph') +local set_attribute = node.set_attribute + +--[[ldx-- +<p>The next function encapsulates the standard <l n='tfm'/> loader as +supplied by <l n='luatex'/>.</p> +--ldx]]-- + +tfm.resolve_vf = true -- false +tfm.share_base_kerns = false -- true (.5 sec slower on mk but brings down mem from 410M to 310M, beware: then script/lang share too) +tfm.mathactions = { } +tfm.fontname_mode = "fullpath" + +tfm.enhance = tfm.enhance or function() end + +function tfm.read_from_tfm(specification) + local fname, tfmdata = specification.filename or "", nil + if fname ~= "" then + if trace_defining then + logs.report("define font","loading tfm file %s at size %s",fname,specification.size) + end + tfmdata = font.read_tfm(fname,specification.size) -- not cached, fast enough + if tfmdata then + tfmdata.descriptions = tfmdata.descriptions or { } + if tfm.resolve_vf then + fonts.logger.save(tfmdata,file.extname(fname),specification) -- strange, why here + fname = resolvers.findbinfile(specification.name, 'ovf') + if fname and fname ~= "" then + local vfdata = font.read_vf(fname,specification.size) -- not cached, fast enough + if vfdata then + local chars = tfmdata.characters + for k,v in next, vfdata.characters do + chars[k].commands = v.commands + end + tfmdata.type = 'virtual' + tfmdata.fonts = vfdata.fonts + end + end + end + tfm.enhance(tfmdata,specification) + end + elseif trace_defining then + logs.report("define font","loading tfm with name %s fails",specification.name) + end + return tfmdata +end + +--[[ldx-- +<p>We need to normalize the scale factor (in scaled points). This has to +do with the fact that <l n='tex'/> uses a negative multiple of 1000 as +a signal for a font scaled based on the design size.</p> +--ldx]]-- + +local factors = { + pt = 65536.0, + bp = 65781.8, +} + +function tfm.setfactor(f) + tfm.factor = factors[f or 'pt'] or factors.pt +end + +tfm.setfactor() + +function tfm.scaled(scaledpoints, designsize) -- handles designsize in sp as well + if scaledpoints < 0 then + if designsize then + if designsize > tfm.factor then -- or just 1000 / when? mp? + return (- scaledpoints/1000) * designsize -- sp's + else + return (- scaledpoints/1000) * designsize * tfm.factor + end + else + return (- scaledpoints/1000) * 10 * tfm.factor + end + else + return scaledpoints + end +end + +--[[ldx-- +<p>Before a font is passed to <l n='tex'/> we scale it. Here we also need +to scale virtual characters.</p> +--ldx]]-- + +function tfm.get_virtual_id(tfmdata) + -- since we don't know the id yet, we use 0 as signal + if not tfmdata.fonts then + tfmdata.type = "virtual" + tfmdata.fonts = { { id = 0 } } + return 1 + else + tfmdata.fonts[#tfmdata.fonts+1] = { id = 0 } + return #tfmdata.fonts + end +end + +function tfm.check_virtual_id(tfmdata, id) + if tfmdata and tfmdata.type == "virtual" then + if not tfmdata.fonts or #tfmdata.fonts == 0 then + tfmdata.type, tfmdata.fonts = "real", nil + else + local vfonts = tfmdata.fonts + for f=1,#vfonts do + local fnt = vfonts[f] + if fnt.id and fnt.id == 0 then + fnt.id = id + end + end + end + end +end + +--[[ldx-- +<p>Beware, the boundingbox is passed as reference so we may not overwrite it +in the process; numbers are of course copies. Here 65536 equals 1pt. (Due to +excessive memory usage in CJK fonts, we no longer pass the boundingbox.)</p> +--ldx]]-- + +fonts.trace_scaling = false + +-- the following hack costs a bit of runtime but safes memory +-- +-- basekerns are scaled and will be hashed by table id +-- sharedkerns are unscaled and are be hashed by concatenated indexes + +--~ function tfm.check_base_kerns(tfmdata) +--~ if tfm.share_base_kerns then +--~ local sharedkerns = tfmdata.sharedkerns +--~ if sharedkerns then +--~ local basekerns = { } +--~ tfmdata.basekerns = basekerns +--~ return sharedkerns, basekerns +--~ end +--~ end +--~ return nil, nil +--~ end + +--~ function tfm.prepare_base_kerns(tfmdata) +--~ if tfm.share_base_kerns and not tfmdata.sharedkerns then +--~ local sharedkerns = { } +--~ tfmdata.sharedkerns = sharedkerns +--~ for u, chr in next, tfmdata.characters do +--~ local kerns = chr.kerns +--~ if kerns then +--~ local hash = concat(sortedkeys(kerns), " ") +--~ local base = sharedkerns[hash] +--~ if not base then +--~ sharedkerns[hash] = kerns +--~ else +--~ chr.kerns = base +--~ end +--~ end +--~ end +--~ end +--~ end + +-- we can have cache scaled characters when we are in node mode and don't have +-- protruding and expansion: hash == fullname @ size @ protruding @ expansion +-- but in practice (except from mk) the otf hash will be enough already so it +-- makes no sense to mess up the code now + +local charactercache = { } + +-- The scaler is only used for otf and afm and virtual fonts. If +-- a virtual font has italic correction make sure to set the +-- has_italic flag. Some more flags will be added in the future. + +function tfm.calculate_scale(tfmtable, scaledpoints, relativeid) + if scaledpoints < 0 then + scaledpoints = (- scaledpoints/1000) * tfmtable.designsize -- already in sp + end + local units = tfmtable.units or 1000 + local delta = scaledpoints/units -- brr, some open type fonts have 2048 + return scaledpoints, delta, units +end + +function tfm.do_scale(tfmtable, scaledpoints, relativeid) + -- tfm.prepare_base_kerns(tfmtable) -- optimalization + local t = { } -- the new table + local scaledpoints, delta, units = tfm.calculate_scale(tfmtable, scaledpoints, relativeid) + t.units_per_em = units or 1000 + local hdelta, vdelta = delta, delta + -- 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 + local extend_factor = tfmtable.extend_factor or 0 + if extend_factor ~= 0 and extend_factor ~= 1 then + hdelta = hdelta * extend_factor + t.extend = extend_factor * 1000 + else + t.extend = 1000 + end + local slant_factor = tfmtable.slant_factor or 0 + if slant_factor ~= 0 then + t.slant = slant_factor * 1000 + else + t.slant = 0 + end + -- status + local isvirtual = tfmtable.type == "virtual" or tfmtable.virtualized + local hasmath = (tfmtable.math_parameters ~= nil and next(tfmtable.math_parameters) ~= nil) or (tfmtable.MathConstants ~= nil and next(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.goodies = tfmtable.goodies +t.colorscheme = tfmtable.colorscheme +--~ t.embedding = tfmtable.embedding + 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)*hdelta + tp.space_stretch = (tfmp.space_stretch or tfmp[3] or 0)*hdelta + tp.space_shrink = (tfmp.space_shrink or tfmp[4] or 0)*hdelta + tp.x_height = (tfmp.x_height or tfmp[5] or 0)*vdelta + tp.quad = (tfmp.quad or tfmp[6] or 0)*hdelta + tp.extra_space = (tfmp.extra_space or tfmp[7] or 0)*hdelta + 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 = changed and next(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 * hdelta + local scaledheight = defaultheight * vdelta + local scaleddepth = defaultdepth * vdelta + local stackmath = tfmtable.ignore_stack_math ~= true + local private = fonts.private + local sharedkerns = { } + 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 = hdelta*width else width = scaledwidth end + if height then height = vdelta*height else height = scaledheight end + -- if depth then depth = vdelta*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] -- nb: index! + if tu then + chr.tounicode = tu + end + end + if hasquality then + -- we could move these calculations elsewhere (saves calculations) + 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*hdelta + 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)*vdelta, + ["end"] = (vvi["end"] or 0)*vdelta, + ["advance"] = (vvi["advance"] or 0)*vdelta, + ["extender"] = vvi["extender"], + ["glyph"] = vvi["glyph"], + } + end + chr.vert_variants = t + --~ local ic = v.vert_italic_correction + --~ if ic then + --~ chr.italic = ic * hdelta + --~ print(format("0x%05X -> %s",k,chr.italic)) + --~ end + 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)*hdelta, + ["end"] = (hvi["end"] or 0)*hdelta, + ["advance"] = (hvi["advance"] or 0)*hdelta, + ["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 = vdelta*vt + end + if stackmath then + local mk = v.mathkerns + if mk then + local kerns = { } + local v = mk.top_right if v then local k = { } for i=1,#v do local vi = v[i] + k[i] = { height = vdelta*vi.height, kern = vdelta*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 = vdelta*vi.height, kern = vdelta*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 = vdelta*vi.height, kern = vdelta*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 = vdelta*vi.height, kern = vdelta*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*hdelta end + --~ basekerns[vk] = base + --~ end + --~ chr.kerns = base + --~ else + --~ local tt = {} + --~ for k,v in next, vk do tt[k] = v*hdelta end + --~ chr.kerns = tt + --~ end + local s = sharedkerns[vk] + if not s then + s = { } + for k,v in next, vk do s[k] = v*hdelta end + sharedkerns[vk] = s + end + chr.kerns = s + 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 + -- tricky .. we need to scale pseudo math glyphs too + -- which is why we deal with rules too + 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" then + tt[#tt+1] = { key, ivc[2]*hdelta } + elseif key == "down" then + tt[#tt+1] = { key, ivc[2]*vdelta } + elseif key == "rule" then + tt[#tt+1] = { key, ivc[2]*vdelta, ivc[3]*hdelta } + 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 + t.hfactor = hdelta + t.vfactor = vdelta + 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,hdelta,vdelta) -- what delta? + end + end + -- needed for \high cum suis + local tpx = tp.x_height + if hasmath then + 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 + end + t.tounicode = 1 + t.cidinfo = tfmtable.cidinfo + -- 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 + if hasmath then + if trace_defining then + logs.report("define font","math enabled for: name '%s', fullname: '%s', filename: '%s'",t.name or "noname",t.fullname or "nofullname",t.filename or "nofilename") + end + else + if trace_defining then + logs.report("define font","math disabled for: name '%s', fullname: '%s', filename: '%s'",t.name or "noname",t.fullname or "nofullname",t.filename or "nofilename") + end + t.nomath, t.MathConstants = true, nil + end + if not t.psname then + -- name used in pdf file as well as for selecting subfont in ttc/dfont + t.psname = t.fontname or (t.fullname and fonts.names.cleanname(t.fullname)) + end + if trace_defining then + logs.report("define font","used for accesing subfont: '%s'",t.psname or "nopsname") + logs.report("define font","used for subsetting: '%s'",t.fontname or "nofontname") + end +--~ print(t.fontname,table.serialize(t.MathConstants)) + return t, delta +end + +--[[ldx-- +<p>The reason why the scaler is split, is that for a while we experimented +with a helper function. However, in practice the <l n='api'/> calls are too slow to +make this profitable and the <l n='lua'/> based variant was just faster. A days +wasted day but an experience richer.</p> +--ldx]]-- + +tfm.auto_cleanup = true + +local lastfont = nil + +-- we can get rid of the tfm instance when we have fast access to the +-- scaled character dimensions at the tex end, e.g. a fontobject.width +-- +-- flushing the kern and ligature tables from memory saves a lot (only +-- base mode) but it complicates vf building where the new characters +-- demand this data .. solution: functions that access them + +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 + -- if v.kerns then v.kerns = nil end + end + else + -- for k, v in next, tfmdata.characters do + -- if v.kerns then v.kerns = 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, relativeid) + local t, factor = tfm.do_scale(tfmtable, scaledpoints, relativeid) + t.factor = factor + t.ascender = factor*(tfmtable.ascender or 0) + t.descender = factor*(tfmtable.descender or 0) + t.shared = tfmtable.shared or { } + t.unique = table.fastcopy(tfmtable.unique or {}) +--~ print("scaling", t.name, t.factor) -- , tfm.hash_features(tfmtable.specification)) + tfm.cleanup(t) + return t +end + +--[[ldx-- +<p>Analyzers run per script and/or language and are needed in order to +process features right.</p> +--ldx]]-- + +fonts.analyzers = fonts.analyzers or { } +fonts.analyzers.aux = fonts.analyzers.aux or { } +fonts.analyzers.methods = fonts.analyzers.methods or { } +fonts.analyzers.initializers = fonts.analyzers.initializers or { } + +-- todo: analyzers per script/lang, cross font, so we need an font id hash -> script +-- e.g. latin -> hyphenate, arab -> 1/2/3 analyze + +-- an example analyzer (should move to font-ota.lua) + +local state = attributes.private('state') + +function fonts.analyzers.aux.setstate(head,font) + local tfmdata = fontdata[font] + local characters = tfmdata.characters + local descriptions = tfmdata.descriptions + local first, last, current, n, done = nil, nil, head, 0, false -- maybe make n boolean + while current do + local id = current.id + if 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 + elseif id == disc then + -- always in the middle + set_attribute(current,state,2) -- midi + last = current + 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 + +-- checking + +function tfm.checked_filename(metadata,whatever) + local foundfilename = metadata.foundfilename + if not foundfilename then + local askedfilename = metadata.filename or "" + if askedfilename ~= "" then + foundfilename = resolvers.findbinfile(askedfilename,"") or "" + if foundfilename == "" then + logs.report("fonts","source file '%s' is not found",askedfilename) + foundfilename = resolvers.findbinfile(file.basename(askedfilename),"") or "" + if foundfilename ~= "" then + logs.report("fonts","using source file '%s' (cache mismatch)",foundfilename) + end + end + elseif whatever then + logs.report("fonts","no source file for '%s'",whatever) + foundfilename = "" + end + metadata.foundfilename = foundfilename + -- logs.report("fonts","using source file '%s'",foundfilename) + end + return foundfilename +end + +-- status info + +statistics.register("fonts load time", function() + return statistics.elapsedseconds(fonts) +end) diff --git a/tex/context/base/font-tra.mkiv b/tex/context/base/font-tra.mkiv new file mode 100644 index 000000000..e47c8c49d --- /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 + +\unexpanded\def\startotfcollecting{\ctxlua{nodes.tracers.steppers.start()}} +\unexpanded\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}} + +\unexpanded\def\startotfsample + {\enabletrackers[*otf.sample]% beware, kind of global + \startotfcollecting + \begingroup} + +\unexpanded\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..02ab6ce2c --- /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 + \expandafter \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 <filename>80 ... <filename>ff +%D \stoptyping +%D +%D The \type {<filename>} 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-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-vf.lua b/tex/context/base/font-vf.lua new file mode 100644 index 000000000..4f99c47b9 --- /dev/null +++ b/tex/context/base/font-vf.lua @@ -0,0 +1,213 @@ +if not modules then modules = { } end modules ['font-vf'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--[[ldx-- +<p>This is very experimental code! Not yet adapted to recent +changes. This will change.</p> +--ldx]]-- + +-- define.methods elsewhere ! + +fonts = fonts or { } +fonts.vf = fonts.vf or { } + +local vf = fonts.vf +local tfm = fonts.tfm + +fonts.define = fonts.define or { } +fonts.define.methods = fonts.define.methods or { } + +vf.combinations = vf.combinations or { } +vf.aux = vf.aux or { } +vf.aux.combine = vf.aux.combine or { } + +function fonts.define.methods.install(tag, rules) + vf.combinations[tag] = rules + fonts.define.methods[tag] = function(specification) + return vf.combine(specification,tag) + end +end + +function vf.aux.combine.assign(g, name, from, to, start, force) + local f, id = vf.aux.combine.load(g,name) + if f and id then + -- optimize for whole range, then just g = f + if not from then from, to = 0, 0xFF00 end + if not to then to = from end + if not start then start = from end + local fc, gc = f.characters, g.characters + local fd, gd = f.descriptions, g.descriptions + local hn = #g.fonts+1 + g.fonts[hn] = { id = id } -- no need to be sparse + for i=from,to do + if fc[i] and (force or not gc[i]) then + gc[i] = table.fastcopy(fc[i]) -- can be optimized + gc[i].commands = { { 'slot', hn, start } } + gd[i] = fd[i] + end + start = start + 1 + end + if not g.parameters and #g.fonts > 0 then -- share this code ! + g.parameters = table.fastcopy(f.parameters) + g.italicangle = f.italicangle + g.ascender = f.ascender + g.descender = f.descender + g.factor = f.factor -- brrr + end + end +end + +function vf.aux.combine.process(g,list) + if list then + for _,v in next, list do + (vf.aux.combine.commands[v[1]] or nop)(g,v) + end + end +end + +function vf.aux.combine.load(g,name) + return tfm.read_and_define(name or g.specification.name,g.specification.size) +end + +function vf.aux.combine.names(g,name,force) + local f, id = tfm.read_and_define(name,g.specification.size) + if f and id then + local fc, gc = f.characters, g.characters + 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 next, fc do + if force or not gc[k] then + gc[k] = table.fastcopy(v) + gc[k].commands = { { 'slot', hn, k } } + gd[i] = fd[i] + end + end + if not g.parameters and #g.fonts > 0 then -- share this code ! + g.parameters = table.fastcopy(f.parameters) + g.italicangle = f.italicangle + g.ascender = f.ascender + g.descender = f.descender + g.factor = f.factor -- brrr + end + end +end + +vf.aux.combine.commands = { + ["initialize"] = function(g,v) vf.aux.combine.assign (g,g.name) end, + ["include-method"] = function(g,v) vf.aux.combine.process (g,vf.combinations[v[2]]) end, -- name + ["copy-parameters"] = function(g,v) vf.aux.combine.parameters(g,v[2]) end, -- name + ["copy-range"] = function(g,v) vf.aux.combine.assign (g,v[2],v[3],v[4],v[5],true) end, -- name, from-start, from-end, to-start + ["copy-char"] = function(g,v) vf.aux.combine.assign (g,v[2],v[3],v[3],v[4],true) end, -- name, from, to + ["fallback-range"] = function(g,v) vf.aux.combine.assign (g,v[2],v[3],v[4],v[5],false) end, -- name, from-start, from-end, to-start + ["fallback-char"] = function(g,v) vf.aux.combine.assign (g,v[2],v[3],v[3],v[4],false) end, -- name, from, to + ["copy_names"] = function(g,v) vf.aux.combine.names (g,v[2],true) end, + ["fallback_names"] = function(g,v) vf.aux.combine.names (g,v[2],false) end, +} + +function vf.combine(specification,tag) + local g = { + name = specification.name, + -- type = 'virtual', + virtualized = true, + fonts = { }, + characters = { }, + descriptions = { }, + specification = table.fastcopy(specification) + } + vf.aux.combine.process(g,vf.combinations[tag]) + return g +end + +vf.aux.combine.commands["feature"] = function(g,v) + local key, value = v[2], v[3] + if key then + if value == nil then + value = true + end + if g.specification and g.specification.features.normal then + g.specification.features.normal[key] = value -- otf? + end + end +end + +-- simple example with features + +fonts.define.methods.install( + "ligatures", { + { "feature", "liga" } , + { "feature", "dlig" } , + { "initialize" } , + } +) + +--~ fonts.define.methods.install ( +--~ "ligatures-x", { +--~ { "feature", "liga" } , +--~ { "feature", "dlig" } , +--~ { "initialize" } , +--~ { "lineheight" } +--~ } +--~ ) + +--~ fonts.define.methods.install( +--~ "lmsymbol10", { +--~ { "fallback_names", "lmsy10.afm" } , +--~ { "fallback_names", "msam10.afm" } , +--~ { "fallback_names", "msbm10.afm" } +--~ } +--~ ) +--~ \font\TestFont=dummy@lmsymbol10 at 24pt + +-- docu case + +--~ fonts.define.methods.install( +--~ "weird", { +--~ { "copy-range", "lmroman10-regular" } , +--~ { "copy-char", "lmroman10-regular", 65, 66 } , +--~ { "copy-range", "lmsans10-regular", 0x0100, 0x01FF } , +--~ { "copy-range", "lmtypewriter10-regular", 0x0200, 0xFF00 } , +--~ { "fallback-range", "lmtypewriter10-regular", 0x0000, 0x0200 } +--~ } +--~ ) + +-- demo case -> move to module + +fonts.define.methods["demo-1"] = function(specification) + local name = specification.name -- symbolic name + local size = specification.size -- given size + 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.virtualized = name, true + f.fonts = { + { id = id }, + { name = 'lmsans10-regular' , size = size*capscale }, -- forced extra name + { name = 'lmtypewriter10-regular', size = size*digscale } -- forced extra name + } + local i_is_of_category = characters.i_is_of_category + local characters, descriptions = f.characters, f.descriptions + 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 = { red, {'slot',2,u}, black } + elseif u and i_is_of_category(u,'nd') then + v.width = digscale*v.width + v.commands = { blue, {'slot',3,u}, black } + else + v.commands = { green, {'slot',1,u}, black } + end + end + end + return f +end diff --git a/tex/context/base/font-xtx.lua b/tex/context/base/font-xtx.lua new file mode 100644 index 000000000..eac75dd29 --- /dev/null +++ b/tex/context/base/font-xtx.lua @@ -0,0 +1,122 @@ +if not modules then modules = { } end modules ['font-xtx'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + 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 lpegmatch = lpeg.match + +local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) + +--[[ldx-- +<p>Choosing a font by name and specififying its size is only part of the +game. In order to prevent complex commands, <l n='xetex'/> introduced +a method to pass feature information as part of the font name. At the +risk of introducing nasty parsing and compatinility problems, this +syntax was expanded over time.</p> + +<p>For the sake of users who have defined fonts using that syntax, we +will support it, but we will provide additional methods as well. +Normally users will not use this direct way, but use a more abstract +interface.</p> + +<p>The next one is the official one. However, in the plain +variant we need to support the crappy [] specification as +well and that does not work too well with the general design +of the specifier.</p> +--ldx]]-- + +--~ function fonts.define.specify.colonized(specification) -- xetex mode +--~ local list = { } +--~ if specification.detail and specification.detail ~= "" then +--~ for v in gmatch(specification.detail,"%s*([^;]+)%s*") do +--~ local a, b = match(v,"^(%S*)%s*=%s*(%S*)$") +--~ if a and b then +--~ list[a] = b:is_boolean() +--~ if type(list[a]) == "nil" then +--~ list[a] = b +--~ end +--~ else +--~ local a, b = match(v,"^([%+%-]?)%s*(%S+)$") +--~ if a and b then +--~ list[b] = a ~= "-" +--~ end +--~ end +--~ end +--~ end +--~ specification.features.normal = list +--~ return specification +--~ end + +--~ check("oeps/BI:+a;-b;c=d") +--~ check("[oeps]/BI:+a;-b;c=d") +--~ check("file:oeps/BI:+a;-b;c=d") +--~ check("name:oeps/BI:+a;-b;c=d") + +local list = { } + +fonts.define.specify.colonized_default_lookup = "file" + +local function issome () list.lookup = fonts.define.specify.colonized_default_lookup end +local function isfile () list.lookup = 'file' end +local function isname () list.lookup = 'name' end +local function thename(s) list.name = s end +local function issub (v) list.sub = v end +local function iscrap (s) list.crap = string.lower(s) end +local function istrue (s) list[s] = 'yes' end +local function isfalse(s) list[s] = 'no' end +local function iskey (k,v) list[k] = v end + +local function istrue (s) list[s] = true end +local function isfalse(s) list[s] = false end + +local spaces = lpeg.P(" ")^0 +local namespec = (1-lpeg.S("/:("))^0 -- was: (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","AZ","09") + lpeg.S("+-."))^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 + +local normalize_meanings = fonts.otf.meanings.normalize + +function fonts.define.specify.colonized(specification) -- xetex mode + list = { } + lpegmatch(pattern,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 + specification.features.normal = normalize_meanings(list) + return specification +end + +fonts.define.register_split(":", fonts.define.specify.colonized) diff --git a/tex/context/base/font-xtx.mkii b/tex/context/base/font-xtx.mkii new file mode 100644 index 000000000..d6086b44e --- /dev/null +++ b/tex/context/base/font-xtx.mkii @@ -0,0 +1,376 @@ +%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} + +\newconditional\enabledfontfeatures + +\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 + {\settrue\enabledfontfeatures + \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\ifconditional\enabledfontfeatures + \edef\checkedfontfeatures{:\convertedfontfeatures}% + \else + \let\checkedfontfeatures\empty + \fi\fi + \fi + \fi + \docheckfontfilenameprefix#1:\empty:\empty\relax + \doshowcheckedfontfeatures} + +\edef\@@fontfeaturesareno {features\v!no} +\edef\@@fontfeaturesareoff{features\v!off} + +\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\!!stringc{#1#2#3}% + \ifx\!!stringc\@@fontfeaturesareoff + \setfalse\enabledfontfeatures + \else\ifx\!!stringc\@@fontfeaturesareno + \setfalse\enabledfontfeatures + \else + \edef\convertedfontfeatures + {\convertedfontfeatures + \ifx\!!stringb\v!yes + +\!!stringa + \else\ifx\!!stringb\v!on + +\!!stringa + \else\ifx\!!stringb\v!no + -\!!stringa + \else\ifx\!!stringb\v!off + -\!!stringa + \else + \!!stringa=\!!stringb + \fi\fi\fi\fi;}% + \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/grph-fig.mkii b/tex/context/base/grph-fig.mkii new file mode 100644 index 000000000..c7f990af2 --- /dev/null +++ b/tex/context/base/grph-fig.mkii @@ -0,0 +1,559 @@ +%D \module +%D [ file=grph-fig, +%D version=2006.08.26, % overhaul of 1997.03.31 +%D title=\CONTEXT\ Graphic 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 Graphic Macros / Figure Handling} + +\unprotect + +\def\setupexternalfigures + {\dosingleempty\dosetupexternalfigures} + +\def\dosetupexternalfigures[#1]% + {\getparameters[\??ef][#1]% local settings + \getparameters[\??ex][#1]% global settings + \setfigurepathlist} % the path may be used elsewhere too (as in x-res-04) + +\presetlocalframed[\??ef] + +\newconditional\externalfigurelevel % true=background false=normal +\newconditional\externalfigureflush % true=place false=ignore + +\setfalse\externalfigurelevel +\settrue \externalfigureflush + +\def\doplaceexternalfigure[#1][#2][#3][#4][#5]% + {\doifsomething{#2}% catches \defineexternalfigure dummies + {\doifundefinedelse{\??ef\??ef#2} + {\dodoplaceexternalfigure[#1][#2][#3][#4][#5]} + {\doifelse{#1}{#2} + {\dodoplaceexternalfigure[#1][#2][#3][#4][#5]} + {\getvalue{\??ef\??ef#2}[#5]}}}} + +\def\dodoplaceexternalfigure[#1][#2][#3][#4][#5]% + {\bgroup + \pushmacro\textunderscore + \edef\textunderscore{\string_}% brrr, temp hack, still needed? + \calculateexternalfigure [][#1][#2][#3][#4][#5]% [] is dummy dwcomp + \calculateexternalscreenfigure[][#1][#2][#3][#4][#5]% [] is dummy dwcomp + \popmacro\textunderscore + \box\foundexternalfigure + \egroup} + +\def\externalfigurereplacement#1#2#3% + {\setupcolors + [\c!state=\v!local]% + \expanded{\localframed + [\??ef] + [\c!width=\figurewidth, + \c!height=\figureheight, + \c!background=\v!screen, + \c!backgroundscreen=.8, + \c!frame=\@@efframe]}% + {\tt\tfxx \nohyphens + name: \expanded{\verbatimstring{#1}}\\% + file: \expanded{\verbatimstring{#2}}\\% + state: \expanded{\verbatimstring{#3}}}} + +\def\externalfigureplaceholder#1#2#3% + {\localframed + [\??ef] + [\c!width=#2, + \c!height=#3, + \c!frame=\v!on]% + {\tt\tfxx \nohyphens + name: \expanded{\verbatimstring{#1}}\\% + state: \expanded{\verbatimstring{placeholder}}}} + +% new: more convenient/efficient than +% +% \use..[a][a][setting] \externalfigure[b][a] +% +% is equivalent to: +% +% \def..[a][setting] \externalfigure[b][a] +% +% see x-res modules for usage: +% +% \defineexternalfigure[name][settings] + +\def\defineexternalfigure + {\dodoubleargument\dodefineexternalfigure} + +\def\dodefineexternalfigure[#1][#2]% + {\setvalue{\??ef\??ef#1}{\doplaceexternalfigure[#1][][][#2]}} + +\def\getexternalfigure#1% efef has 4 args already and take an 5th + {\wait} % OBSOLETE + +% \useexternalfigure[alpha][koe] +% \useexternalfigure[beta] [koe] [breedte=1cm] +% \useexternalfigure[gamma][koe][alpha] +% \useexternalfigure[delta][koe][alpha][breedte=2cm] +% +% volle breedte: \externalfigure[koe] \par +% 3cm breed: \externalfigure[koe] [breedte=3cm] \par +% volle breedte: \externalfigure[alpha] \par +% 1cm breed: \externalfigure[beta] \par +% volle breedte: \externalfigure[gamma] \par +% 2cm breed: \externalfigure[delta] \par +% 4cm breed: \externalfigure[beta] [breedte=4cm] \par +% 5cm breed: \externalfigure[gamma][breedte=5cm] \par + +% \defineexternalfigure[a][width=10cm] +% \defineexternalfigure[b][width=5cm] +% \externalfigure[cow][a] +% \externalfigure[cow][b][height=8cm] + +% \useexternalfigure[x][cow][width=10cm,height=1cm] +% \externalfigure[x] +% \externalfigure[x][width=3cm] + +\def\useexternalfigure + {\doquadrupleempty\douseexternalfigure} + +% [label] [filename] +% [label] [filename] [parent] +% [label] [filename] [parent] [settings] +% [label] [filename] [settings] + +\def\useexternalfigure + {\doquadrupleempty\douseexternalfigure} + +\def\douseexternalfigure[#1][#2][#3][#4]% + {\doifelsenothing{#1} + {\doifsomething{#2} + {\doifassignmentelse{#3} + {\setvalue{\??ef\??ef#2}{\doplaceexternalfigure[#2][#2][#3][#4]}} + {\setvalue{\??ef\??ef#2}{\doplaceexternalfigure[#2][#2][][#4]}}}} + {\doifelsenothing{#2} + {\doifassignmentelse{#3} + {\setvalue{\??ef\??ef#1}{\doplaceexternalfigure[#1][#1][][#3]}} + {\setvalue{\??ef\??ef#1}{\doplaceexternalfigure[#1][#1][#3][#4]}}} + {\doifassignmentelse{#3} + {\setvalue{\??ef\??ef#1}{\doplaceexternalfigure[#1][#2][][#3]}} + {\setvalue{\??ef\??ef#1}{\doplaceexternalfigure[#1][#2][#3][#4]}}}}} + +\def\dosetefparameters#1#2#3% parent_id use_settings current_settings + {\doifelsenothing{#1} % inherit from parent + {\getparameters[\??ef][#2,#3]} + {\doifdefinedelse{\??ef\??ef#1} + {\pushmacro\doplaceexternalfigure + \def\doplaceexternalfigure[##1][##2][##3][##4]{\getparameters[\??ef][##4,#2,#3]}% + \getvalue{\??ef\??ef#1}% + \popmacro\doplaceexternalfigure} + {\getparameters[\??ef][#2,#3]}}} + +\unexpanded\def\externalfigure + {\dotripleempty\doexternalfigure} + +\def\doexternalfigure[#1][#2][#3]% [label][file][settings] | [file][settings] | [file][parent][settings] + {\bgroup + \doifelsenothing{#1} + {\framed[\c!width=\defaultfigurewidth,\c!height=\defaultfigureheight]{external\\figure\\no name}} + {\doifundefinedelse{\??ef\??ef#1} + {\useexternalfigure[\s!dummy][#1][#2][#3]% + \getvalue{\??ef\??ef\s!dummy}[]} % [] is dummy arg 5 + {\doifassignmentelse{#2} + {\getvalue{\??ef\??ef#1}[#2]}% + {\getvalue{\??ef\??ef#1}[#3]}}}% + \globallet\currentresourcecomment\empty + \egroup} + +\long\def\resourcecomment#1% + {\long\gdef\currentresourcecomment{#1}} + +\long\def\startresourcecomment#1\stopresourcecomment + {\long\gdef\currentresourcecomment{#1}} + +\let\currentresourcecomment\empty + +\def\showexternalfigures % maybe run time command is better, but no core-run, unless figs-run ... + {%\writestatus\m!systems{for \string\showexternalfigures\space see \truefilename{x-res-20}.tex} + \usemodule[res-20]\showexternalfigures} % so for the moment we do it this way + +\def\overlayfigure#1% + {\externalfigure[#1][\c!width=\overlaywidth,\c!height=\overlayheight]} + +%D Still undocumented! No one uses it I think, better be done with layers. + +\newcount\efreference +\newdimen\efxsteps +\newdimen\efysteps + +\def\calculateefsteps + {\ifnum0\@@exxmax=\zerocount + \ifnum0\@@exymax=\zerocount + \def\@@exymax{24}% + \fi + \efysteps\figureheight \divide\efysteps \@@exymax + \efxsteps\efysteps + \dimen0=\figurewidth + \advance\dimen0 \efysteps + \divide \dimen0 \efysteps + \edef\@@exxmax{\number\dimen0}% + \else + \efxsteps\figurewidth \divide\efxsteps \@@exxmax + \efysteps\figureheight \divide\efysteps \@@exymax + \fi} + +\def\efcomment#1(#2,#3)#4(#5,#6)% {kader}(x,y)(h,b)[...]{tekst} + {\def\complexefdocomment[##1]##2% + {\position(#2,#3)% + {\setnostrut + \framed + [\c!width=#5\efxsteps, + \c!height=#6\exysteps, + \c!offset=\v!none, + \c!frame=#1, + ##1]% + {##2}}}% + \complexorsimpleempty\efdocomment} + +\def\efnocomment(#1,#2)#3(#4,#5)% (x,y)(h,b)[...]{tekst} + {\def\complexefdonocomment[##1]##2{}% + \complexorsimpleempty\efdonocomment} + +\def\efdomarker(#1,#2)#3#4% (h,b){kader}{tekst} + {\framed + [\c!width=#1\efxsteps, + \c!height=#2\efysteps, + \c!offset=\v!none, + \c!frame=#3]% + {#4}} + +\def\effigure#1% + {\position(0,0){\getvalue{#1}}} + +\def\efdoarea(#1,#2)#3#4% (h,b){kader}{tekst} + {\bgroup + \setnostrut + \framed + [\c!width=#1\efxsteps, + \c!height=#2\efysteps, + \c!offset=\!!zeropoint, + \c!frame=#3] + {#4}% + \egroup} + +\def\efgoto(#1,#2)#3[#4]% (h,b)kader[ref] + {\setbox0=\vbox{\efdoarea(#1,#2)#3{}}% + \gotobox{\copy0}[#4]} + +\def\efmark(#1,#2)#3(#4,#5)#6[#7]% + {\advance\efreference \plusone + \position(#1,#2) + {\hbox{\the\efreference}}% + \position(#1,#2) + {\gotosomeinternal\s!vwb{#7}\realfolio + {\efdomarker(#4,#5)\v!on{\thisissomeinternal\s!vwa{#7}}}}} + +\def\eftext#1(#2,#3)#4(#5,#6)#7[#8]% + {\advance\efreference \plusone + \hbox + {\quad + \thisissomeinternal\s!vwb{#8}% + \gotosomeinternal \s!vwa{#8}\realfolio + {\hbox to 1.5em{\the\efreference\presetgoto\hfill}}% + \quad#1 (#2,#3) (#5,#6) [#8]\hfill}% + \endgraf} + +\def\efthisis(#1,#2)#3[#4]% + {\efdoarea(#1,#2){#3}{\pagereference[#4]}} + +\newbox\colorbarbox + +\def\makecolorbar[#1]% + {\def\docommand##1% + {\color[##1] + {\blackrule + [\c!width=2em, + \c!height=1ex, + \c!depth=\!!zeropoint]}% + \endgraf}% + \global\setbox\colorbarbox\vbox + {\forgetall + \processcommalist[#1]\docommand}% + \global\setbox\colorbarbox\vbox + {\hskip2em\box\colorbarbox}% + \global\wd\colorbarbox\zeropoint} + +\def\placestartfigure[#1][#2][#3]#4\placestopfigure[#5]% + {\hbox + {\setbox0\hbox + {\useexternalfigure[\s!dummy][#2][#3,#5]% + \externalfigure[\s!dummy]}% + \calculateefsteps + \startpositioning + \def\referring(##1,##2)##3(##4,##5)##6[##7]% + {\position(##1,##2){\efgoto(##4,##5){\@@exframes}[##7]}}% + \def\marking(##1,##2)##3(##4,##5)##6[##7]% + {\position(##1,##2){\efthisis(##4,##5){\@@exframes}[##7]}}% + \def\remark{\efnocomment}% + \def\colorbar##1[##2]{}% + \position(0,0){\box0}% + \linewidth\onepoint + \setuppositioning + [\c!unit=pt, + \c!xscale=\withoutpt\the\efxsteps, + \c!yscale=\withoutpt\the\efysteps, + \c!factor=1]% + \ignorespaces#4% + \def\referring(##1,##2)##3(##4,##5)##6[##7]% + {}% + \let\marking\referring + \def\remark{\efcomment\v!no}% + \def\colorbar##1[##2]{\makecolorbar[##2]}% + \ignorespaces#4% + \stoppositioning + \box\colorbarbox}} + +\def\dodostartfigure[#1][#2][#3]#4\stopfigure + {\doifelse\v!test\@@exoption + {\teststartfigure[#1][#2][#3]#4\teststopfigure + \let\@@exframes\v!on} + {\let\@@exframes\v!off}% + \setvalue{\??ef\??ef#1}% + {\dosingleempty{\placestartfigure[#1][#2][#3]#4\placestopfigure}}% + }% no longer \doifundefined{#1}{\setvalue{#1}{\getexternalfigure{#1}}}} + +% De onderstaande macro mag niet zondermeer worden aangepast +% en is afgestemd op gebruik in de handleiding. + +\def\teststartfigure[#1][#2][#3]#4\teststopfigure% + {\begingroup + \setbox0\hbox + {\useexternalfigure[\s!dummy][#2][\c!wfactor=\v!max]% + \externalfigure[\s!dummy]}% + \def\referring{\efmark}% + \def\marking{\efmark}% + \def\remark{\efcomment\v!yes}% + \def\colorbar##1[##2]{}% + \efreference\zerocount + \setbox0\vbox + {\hsize240pt + \startpositioning + \calculateefsteps + \position(0,0) + {\box0}% + \position(0,0) + {\basegrid + [\c!nx=\@@exxmax, + \c!dx=\withoutpt\the\efxsteps, + \c!ny=\@@exymax, + \c!dy=\withoutpt\the\efysteps, + \c!xstep=1, + \c!ystep=1, + \c!scale=1, + \c!offset=\v!no, + \c!unit=pt]}% + \setuppositioning + [\c!unit=pt, + \c!xscale=\withoutpt\the\efxsteps, + \c!yscale=\withoutpt\the\efysteps, + \c!factor=1]% + \linewidth\onepoint + \ignorespaces#4\relax + \stoppositioning + \vfill}% + \efreference\zerocount + \def\referring{\eftext{$\rightarrow$}}% + \def\marking{\eftext{$\leftarrow$}}% + \def\remark{\efnocomment}% + \def\colorbar##1[##2]{}% + \setbox2\vbox + {{\tfa\doifelsenothing{#1}{#2}{#1}} + \blank + \tfxx#4 + \vfilll}% + \ifdim\ht0>\ht2 + \ht2\ht0 + \else + \ht0\ht2 + \fi + \hbox + {\hskip3em + \vtop{\vskip12pt\box0\vskip6pt}% + \vtop{\vskip12pt\box2\vskip6pt}}% + \endgroup} + +\def\dodostartfigure[#1][#2][#3]#4\stopfigure + {\doifelse\v!test\@@exoption + {\teststartfigure[#1][#2][#3]#4\teststopfigure + \let\@@exframe\v!on} + {\let\@@exframe\v!off}% + \setvalue{\??ef\??ef#1}% + {\def\next{\placestartfigure[#1][#2][#3]#4\placestopfigure}% + \dosingleempty\next}% + }% no longer: \doifundefined{#1}{\setvalue{#1}{\getexternalfigure{#1}}}} + +\long\def\dostartfigure#1% + {\dotripleargument\dodostartfigure#1\stopfigure} + +\def\startfigure + {\grabuntil{\e!stop\v!figure}\dostartfigure} + +%D defining sound tracks: +%D +%D \starttyping +%D \useexternalsoundtrack[label][file] +%D \stoptyping +%D +%D associated actions: StartSound StopSound PauseSound ResumeSound +%D +%D Todo: like external figures, also search on path, +%D although, they need to be present ar viewing time, so ... + +\def\useexternalsoundtrack + {\dodoubleargument\douseexternalsoundtrack} + +\def\douseexternalsoundtrack[#1][#2]% + {\setgvalue{\??sd:#1}{#2}} + +\def\checksoundtrack#1% + {\iflocation + \doifdefined{\??sd:#1}{\doifvaluesomething{\??sd:#1} + {\doinsertsoundtrack{\getvalue{\??sd:#1}}{#1}\@@sdoption + % brr, \..empty not really needed and maybe even wrong; + % also, not here but in driver + % well, no: sounds need to be reinitialize each time (i.e., be on page), so no + }}% \letgvalueempty{\??sd:#1}}}% + \fi} + +\setexecutecommandcheck {startsound} \checksoundtrack + +\def\setupexternalsoundtracks + {\dodoubleargument\getparameters[\??sd]} + +\setupexternalsoundtracks + [\c!option=] + +%D NEW: used in styledesign manual + +% \setbuffer[typeset-b]\endbuffer +% \setbuffer[typeset-a]\endbuffer +% +% todo: +% +% \appendtoks \setbuffer[typeset-b]\endbuffer\to \everystarttext +% \appendtoks \setbuffer[typeset-a]\endbuffer\to \everystarttext + +\def\typesetbuffer + {\dodoubleempty\dotypesetbuffer} + +\newcounter\noftypesetbuffers % all loaded at the end + +\defineexternalfigure + [typeset] + [\c!background=\v!color, + \c!backgroundcolor=\s!white] + +\def\dotypesetbuffer[#1][#2]% beware: this will mix up the mp graphics + {\bgroup + \def\TEXbufferfile##1{\bufferprefix##1.tex}% + \expanded{\setbuffer[typeset]% + \def\noexpand\bufferprefix{\ifprotectbuffers\jobname-\fi typeset-}}% + \starttext + \getbuffer[b,#1,a]% + \stoptext + \endbuffer + \doglobal\increment\noftypesetbuffers + % batch is needed + \executesystemcommand{texmfstart texexec --batch --pdf --result=\bufferprefix typeset-\noftypesetbuffers\space \bufferprefix typeset.tex}% + %\externalfigure[\bufferprefix typeset-\noftypesetbuffers.pdf][\c!object=\v!no,#2]% + \externalfigure[\bufferprefix typeset-\noftypesetbuffers.pdf][#2]% + \egroup} + +% for me only (manuals and such) + +\definesystemvariable{tz} + +\def\definetypesetting{\dotripleempty\dodefinetypesetting} +\def\typesetfile {\dotripleempty\dotypesetfile} + +\def\dodefinetypesetting[#1][#2][#3]% + {\doifsomething{#1}{\setvalue{\??tz#1}{\dodotypesetfile{#2}{#3}}}} + +\def\dotypesetfile[#1][#2][#3]% + {\executeifdefined{\??tz#1}\gobbletwoarguments{#2}{#3}} + +\def\dodotypesetfile#1#2#3#4% args settings file settings + {\doifmode{*\v!first}{\executesystemcommand{texmfstart texexec.pl --batch --pdf #1 #3}}% + \doglobal\beforesplitstring#3\at.\to\typesetfilename + \externalfigure[\typesetfilename.pdf][#2,#4]} + +\setupexternalfigures + [\c!option=, + \c!object=\v!yes, % we only check for no + \c!reset=\v!no, + \c!maxwidth=\@@efwidth, + \c!maxheight=\@@efheight, + \c!bodyfont=\bodyfontsize, + \c!directory=, + \c!file=\f!utilityfilename.\f!figureextension, + \c!radius=.5\bodyfontsize, + \c!corner=\v!rectangular, + \c!frame=\v!off, + \c!background=, % new + \c!splitcolor=\s!white, + \c!conversion=, + \c!prefix=, + \c!cache=, +% \c!grid=, + \c!equalwidth=, + \c!equalheight=, + \c!location={\v!local,\v!global}] + +\setupexternalfigures + [\c!frames=\v!off, + \c!ymax=24, + \c!xmax=] + +\useexternalfigure + [buffer] [\jobname] [\c!type=\v!buffer,\c!object=\v!no] + +\protect \endinput + +% alternative for positioning + +% \definelayer[figure][width=\overlaywidth,height=\overlayheight] +% \defineoverlay[figure][{\directsetup{figure}\tightlayer[figure]}] + +% \setupcolors[state=start] + +% \starttext + +% \startsetups figure +% \setlayerframed[figure][preset=rightbottom,x=.25\layerwidth,y=.25\layerheight]{HERE} +% \setlayerframed[figure][preset=leftbottom, x=.15\layerwidth,y=.35\layerheight]{THERE} +% \stopsetups + +% \externalfigure[cow][background={foreground,figure},width=4cm,height=8cm] + +% \startsetups figure +% \setlayerframed[figure][preset=righttop,x=.25\layerwidth,y=.25\layerheight]{MORE} +% \setlayerframed[figure][preset=middle,foregroundcolor=green]{EVEN MORE} +% \stopsetups + +% \externalfigure[cow][background={foreground,figure},width=14cm,height=2cm] + +% \defineexternalfigure[whatever][background={foreground,figure}] + +% \startsetups figure +% \setlayerframed[figure][preset=righttop,x=.25\layerwidth,y=.25\layerheight]{\red MORE} +% \setlayerframed[figure][preset=middle,foregroundcolor=green]{EVEN MORE} +% \stopsetups + +% \externalfigure[cow][whatever][width=14cm,height=4cm] + +% \stoptext + diff --git a/tex/context/base/grph-fig.mkiv b/tex/context/base/grph-fig.mkiv new file mode 100644 index 000000000..e10dc0a32 --- /dev/null +++ b/tex/context/base/grph-fig.mkiv @@ -0,0 +1,640 @@ +%D \module +%D [ file=grph-fig, +%D version=2006.08.26, % overhaul of 1997.03.31 +%D title=\CONTEXT\ Graphic 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 Graphic Macros / Figure Handling} + +\unprotect + +\unexpanded\def\setupexternalfigures + {\dosingleempty\dosetupexternalfigures} + +\def\dosetupexternalfigures[#1]% + {\getparameters[\??ef][#1]% local settings + \getparameters[\??ex][#1]% global settings + \setfigurepathlist} % the path may be used elsewhere too (as in x-res-04) + +\presetlocalframed[\??ef] + +\newconditional\externalfigurelevel % true=background false=normal +\newconditional\externalfigureflush % true=place false=ignore + +\setfalse\externalfigurelevel +\settrue \externalfigureflush + +\def\doplaceexternalfigure[#1][#2][#3][#4][#5]% + {\doifsomething{#2}% catches \defineexternalfigure dummies + {\doifundefinedelse{\??ef\??ef#2} + {\dodoplaceexternalfigure[#1][#2][#3][#4][#5]} + {\doifelse{#1}{#2} + {\dodoplaceexternalfigure[#1][#2][#3][#4][#5]} + {\getvalue{\??ef\??ef#2}[#5]}}}} + +\def\dodoplaceexternalfigure[#1][#2][#3][#4][#5]% + {\bgroup + \pushmacro\textunderscore + \edef\textunderscore{\string_}% brrr, temp hack, still needed? + \calculateexternalfigure[][#1][#2][#3][#4][#5]% [] is dummy dwcomp + \popmacro\textunderscore + \box\foundexternalfigure + \egroup} + +\def\externalfigurereplacement#1#2#3% + {\setupcolors + [\c!state=\v!local]% + \expanded{\localframed + [\??ef] + [\c!width=\figurewidth, + \c!height=\figureheight, + \c!background=\v!color, + \c!backgroundcolor=missingfigurecolor, + \c!frame=\@@efframe]}% + {\tt\tfxx \nohyphens + name: \expanded{\verbatimstring{#1}}\\% + file: \expanded{\verbatimstring{#2}}\\% + state: \expanded{\verbatimstring{#3}}}} + +\definecolor[missingfigurecolor][s=.8] + +\def\externalfigureplaceholder#1#2#3% + {\localframed + [\??ef] + [\c!width=#2, + \c!height=#3, + \c!frame=\v!on]% + {\tt\tfxx \nohyphens + name: \expanded{\verbatimstring{#1}}\\% + state: \expanded{\verbatimstring{placeholder}}}} + +% new: more convenient/efficient than +% +% \use..[a][a][setting] \externalfigure[b][a] +% +% is equivalent to: +% +% \def..[a][setting] \externalfigure[b][a] +% +% see x-res modules for usage: +% +% \defineexternalfigure[name][settings] + +\unexpanded\def\defineexternalfigure + {\dodoubleargument\dodefineexternalfigure} + +\def\dodefineexternalfigure[#1][#2]% + {\setvalue{\??ef\??ef#1}{\doplaceexternalfigure[#1][][][#2]}} + +\def\getexternalfigure#1% efef has 4 args already and take an 5th + {\wait} % OBSOLETE + +% \useexternalfigure[alpha][koe] +% \useexternalfigure[beta] [koe] [breedte=1cm] +% \useexternalfigure[gamma][koe][alpha] +% \useexternalfigure[delta][koe][alpha][breedte=2cm] +% +% volle breedte: \externalfigure[koe] \par +% 3cm breed: \externalfigure[koe] [breedte=3cm] \par +% volle breedte: \externalfigure[alpha] \par +% 1cm breed: \externalfigure[beta] \par +% volle breedte: \externalfigure[gamma] \par +% 2cm breed: \externalfigure[delta] \par +% 4cm breed: \externalfigure[beta] [breedte=4cm] \par +% 5cm breed: \externalfigure[gamma][breedte=5cm] \par + +% \defineexternalfigure[a][width=10cm] +% \defineexternalfigure[b][width=5cm] +% \externalfigure[cow][a] +% \externalfigure[cow][b][height=8cm] + +% \useexternalfigure[x][cow][width=10cm,height=1cm] +% \externalfigure[x] +% \externalfigure[x][width=3cm] + +\def\useexternalfigure + {\doquadrupleempty\douseexternalfigure} + +% [label] [filename] +% [label] [filename] [parent] +% [label] [filename] [parent] [settings] +% [label] [filename] [settings] + +\def\useexternalfigure + {\doquadrupleempty\douseexternalfigure} + +% \def\douseexternalfigure[#1][#2][#3][#4]% +% {\doifelsenothing{#1} +% {\doifsomething{#2} +% {\doifassignmentelse{#3} +% {\setvalue{\??ef\??ef#2}{\doplaceexternalfigure[#2][#2][#3][#4]}} +% {\setvalue{\??ef\??ef#2}{\doplaceexternalfigure[#2][#2][][#4]}}}} +% {\doifelsenothing{#2} +% {\doifassignmentelse{#3} +% {\setvalue{\??ef\??ef#1}{\doplaceexternalfigure[#1][#1][][#3]}} +% {\setvalue{\??ef\??ef#1}{\doplaceexternalfigure[#1][#1][#3][#4]}}} +% {\doifassignmentelse{#3} +% {\setvalue{\??ef\??ef#1}{\doplaceexternalfigure[#1][#2][][#3]}} +% {\setvalue{\??ef\??ef#1}{\doplaceexternalfigure[#1][#2][#3][#4]}}}}} + +\def\douseexternalfigure[#1][#2][#3][#4]% + {\doifelsenothing{#1} + {\doifsomething{#2} + {\doifassignmentelse{#3} + {\dodouseexternalfigure{#2}{#2}{#3}{#4}} + {\dodouseexternalfigure{#2}{#2}{}{#4}}}} + {\doifelsenothing{#2} + {\doifassignmentelse{#3} + {\dodouseexternalfigure{#1}{#1}{}{#3}} + {\dodouseexternalfigure{#1}{#1}{#3}{#4}}} + {\doifassignmentelse{#3} + {\dodouseexternalfigure{#1}{#2}{}{#3}} + {\dodouseexternalfigure{#1}{#2}{#3}{#4}}}}} + +\def\dodouseexternalfigure#1#2#3#4% + {\setvalue{\??ef\??ef#1}{\doplaceexternalfigure[#1][#2][#3][#4]}% + \doanalyseexternalfigurecollection[#2][#4]} + +\newconditional\inexternalfigurecollection +\newdimen\xexternalfigurecollectionminwidth +\newdimen\xexternalfigurecollectionmaxwidth +\newdimen\xexternalfigurecollectionminheight +\newdimen\xexternalfigurecollectionmaxheight + +\def\doanalyseexternalfigurecollection[#1][#2]% + {\ifconditional\inexternalfigurecollection + \setfalse\inexternalfigurecollection + \getfiguredimensions[#1][#2]% + \settrue\inexternalfigurecollection + \scratchdimen\naturalfigurewidth + \ifdim\scratchdimen>\xexternalfigurecollectionmaxwidth \xexternalfigurecollectionmaxwidth \scratchdimen \fi + \ifdim\scratchdimen<\xexternalfigurecollectionminwidth \xexternalfigurecollectionminwidth \scratchdimen \fi + \scratchdimen\naturalfigureheight + \ifdim\scratchdimen>\xexternalfigurecollectionmaxheight \xexternalfigurecollectionmaxheight\scratchdimen \fi + \ifdim\scratchdimen<\xexternalfigurecollectionminheight \xexternalfigurecollectionminheight\scratchdimen \fi + \fi} + +\unexpanded\def\startexternalfigurecollection[#1]% + {\begingroup + \def\currentexternalfigurecollection{#1}% + \settrue\inexternalfigurecollection + \xexternalfigurecollectionminwidth \maxdimen + \xexternalfigurecollectionmaxwidth \zeropoint + \xexternalfigurecollectionminheight\maxdimen + \xexternalfigurecollectionmaxheight\zeropoint} + +\unexpanded\def\stopexternalfigurecollection + {\setxvalue{\??ef:c:\currentexternalfigurecollection:\c!minwidth }{\the\xexternalfigurecollectionminwidth }% + \setxvalue{\??ef:c:\currentexternalfigurecollection:\c!maxwidth }{\the\xexternalfigurecollectionmaxwidth }% + \setxvalue{\??ef:c:\currentexternalfigurecollection:\c!minheight}{\the\xexternalfigurecollectionminheight}% + \setxvalue{\??ef:c:\currentexternalfigurecollection:\c!maxheight}{\the\xexternalfigurecollectionmaxheight}% + \endgroup} + +\def\externalfigurecollectionparameter#1#2% + {\csname\ifcsname\??ef:c:#1:#2\endcsname\??ef:c:#1:#2\else\s!empty\fi\endcsname} + +\def\externalfigurecollectionminwidth #1{\externalfigurecollectionparameter{#1}\c!minwidth } +\def\externalfigurecollectionmaxwidth #1{\externalfigurecollectionparameter{#1}\c!maxwidth } +\def\externalfigurecollectionminheight#1{\externalfigurecollectionparameter{#1}\c!minheight} +\def\externalfigurecollectionmaxheight#1{\externalfigurecollectionparameter{#1}\c!maxheight} + +\let\efcparameter\externalfigurecollectionparameter +\let\efcminwidth \externalfigurecollectionminwidth +\let\efcmaxwidth \externalfigurecollectionmaxwidth +\let\efcminheight\externalfigurecollectionminheight +\let\efcmaxheight\externalfigurecollectionmaxheight + +% \startexternalfigurecollection[name] +% \useexternalfigure[cow] [cow.pdf] +% \useexternalfigure[mill][mill.png] +% \stopexternalfigurecollection +% \starttext +% \bTABLE +% \bTR +% \bTD \externalfigure[cow] [height=\externalfigurecollectionmaxheight{name}] \eTD +% \bTD \externalfigure[mill][height=\externalfigurecollectionmaxheight{name}] \eTD +% \eTR +% \eTABLE +% \stoptext + +\def\dosetefparameters#1#2#3% parent_id use_settings current_settings + {\doifelsenothing{#1} % inherit from parent + {\getparameters[\??ef][#2,#3]} + {\doifdefinedelse{\??ef\??ef#1} + {\pushmacro\doplaceexternalfigure + \def\doplaceexternalfigure[##1][##2][##3][##4]{\getparameters[\??ef][##4,#2,#3]}% + \getvalue{\??ef\??ef#1}% + \popmacro\doplaceexternalfigure} + {\getparameters[\??ef][#2,#3]}}} + +\unexpanded\def\externalfigure + {\dotripleempty\doexternalfigure} + +\def\doexternalfigure[#1][#2][#3]% [label][file][settings] | [file][settings] | [file][parent][settings] + {\bgroup + \doifelsenothing{#1} + {\framed[\c!width=\defaultfigurewidth,\c!height=\defaultfigureheight]{external\\figure\\no name}} + {\doifundefinedelse{\??ef\??ef#1} + {\useexternalfigure[\s!dummy][#1][#2][#3]% + \getvalue{\??ef\??ef\s!dummy}[]} % [] is dummy arg 5 + {\doifassignmentelse{#2} + {\getvalue{\??ef\??ef#1}[#2]}% + {\getvalue{\??ef\??ef#1}[#3]}}}% + \globallet\currentresourcecomment\empty + \egroup} + +\long\def\resourcecomment#1% + {\long\gdef\currentresourcecomment{#1}} + +\long\unexpanded\def\startresourcecomment#1\stopresourcecomment + {\long\gdef\currentresourcecomment{#1}} + +\let\currentresourcecomment\empty + +\def\showexternalfigures % maybe run time command is better, but no core-run, unless figs-run ... + {%\writestatus\m!systems{for \string\showexternalfigures\space see \truefilename{x-res-20}.tex} + \usemodule[res-20]\showexternalfigures} % so for the moment we do it this way + +\def\overlayfigure#1% + {\externalfigure[#1][\c!width=\overlaywidth,\c!height=\overlayheight]} + +%D Still undocumented! No one uses it I think, better be done with layers. + +% when there is need for this i'll reimplement it +% +% \newcount\efreference +% \newdimen\efxsteps +% \newdimen\efysteps +% +% \def\calculateefsteps +% {\ifnum0\@@exxmax=\zerocount +% \ifnum0\@@exymax=\zerocount +% \def\@@exymax{24}% +% \fi +% \efysteps\figureheight \divide\efysteps \@@exymax +% \efxsteps\efysteps +% \dimen0=\figurewidth +% \advance\dimen0 \efysteps +% \divide \dimen0 \efysteps +% \edef\@@exxmax{\number\dimen0}% +% \else +% \efxsteps\figurewidth \divide\efxsteps \@@exxmax +% \efysteps\figureheight \divide\efysteps \@@exymax +% \fi} +% +% \def\efcomment#1(#2,#3)#4(#5,#6)% {kader}(x,y)(h,b)[...]{tekst} +% {\def\complexefdocomment[##1]##2% +% {\position(#2,#3)% +% {\setnostrut +% \framed +% [\c!width=#5\efxsteps, +% \c!height=#6\exysteps, +% \c!offset=\v!none, +% \c!frame=#1, +% ##1]% +% {##2}}}% +% \complexorsimpleempty\efdocomment} +% +% \def\efnocomment(#1,#2)#3(#4,#5)% (x,y)(h,b)[...]{tekst} +% {\def\complexefdonocomment[##1]##2{}% +% \complexorsimpleempty\efdonocomment} +% +% \def\efdomarker(#1,#2)#3#4% (h,b){kader}{tekst} +% {\framed +% [\c!width=#1\efxsteps, +% \c!height=#2\efysteps, +% \c!offset=\v!none, +% \c!frame=#3]% +% {#4}} +% +% \def\effigure#1% +% {\position(0,0){\getvalue{#1}}} +% +% \def\efdoarea(#1,#2)#3#4% (h,b){kader}{tekst} +% {\bgroup +% \setnostrut +% \framed +% [\c!width=#1\efxsteps, +% \c!height=#2\efysteps, +% \c!offset=\!!zeropoint, +% \c!frame=#3] +% {#4}% +% \egroup} +% +% \def\efgoto(#1,#2)#3[#4]% (h,b)kader[ref] +% {\setbox0=\vbox{\efdoarea(#1,#2)#3{}}% +% \gotobox{\copy0}[#4]} +% +% \def\efmark(#1,#2)#3(#4,#5)#6[#7]% +% {\advance\efreference \plusone +% \position(#1,#2) +% {\hbox{\the\efreference}}% +% \position(#1,#2) +% {\gotosomeinternal\s!vwb{#7}\realfolio +% {\efdomarker(#4,#5)\v!on{\thisissomeinternal\s!vwa{#7}}}}} +% +% \def\eftext#1(#2,#3)#4(#5,#6)#7[#8]% +% {\advance\efreference \plusone +% \hbox +% {\quad +% \thisissomeinternal\s!vwb{#8}% +% \gotosomeinternal \s!vwa{#8}\realfolio +% {\hbox to 1.5em{\the\efreference\presetgoto\hfill}}% +% \quad#1 (#2,#3) (#5,#6) [#8]\hfill}% +% \endgraf} +% +% \def\efthisis(#1,#2)#3[#4]% +% {\efdoarea(#1,#2){#3}{\pagereference[#4]}} + +\newbox\colorbarbox + +\def\makecolorbar[#1]% + {\def\docommand##1% + {\color[##1] + {\blackrule + [\c!width=2em, + \c!height=1ex, + \c!depth=\!!zeropoint]}% + \endgraf}% + \global\setbox\colorbarbox\vbox + {\forgetall + \processcommalist[#1]\docommand}% + \global\setbox\colorbarbox\vbox + {\hskip2em\box\colorbarbox}% + \global\wd\colorbarbox\zeropoint} + +\unexpanded\def\placestartfigure[#1][#2][#3]#4\placestopfigure[#5]% + {\hbox + {\setbox0\hbox + {\useexternalfigure[\s!dummy][#2][#3,#5]% + \externalfigure[\s!dummy]}% + \calculateefsteps + \startpositioning + \def\referring(##1,##2)##3(##4,##5)##6[##7]% + {\position(##1,##2){\efgoto(##4,##5){\@@exframes}[##7]}}% + \def\marking(##1,##2)##3(##4,##5)##6[##7]% + {\position(##1,##2){\efthisis(##4,##5){\@@exframes}[##7]}}% + \def\remark{\efnocomment}% + \def\colorbar##1[##2]{}% + \position(0,0){\box0}% + \linewidth\onepoint + \setuppositioning + [\c!unit=pt, + \c!xscale=\withoutpt\the\efxsteps, + \c!yscale=\withoutpt\the\efysteps, + \c!factor=1]% + \ignorespaces#4% + \def\referring(##1,##2)##3(##4,##5)##6[##7]% + {}% + \let\marking\referring + \def\remark{\efcomment\v!no}% + \def\colorbar##1[##2]{\makecolorbar[##2]}% + \ignorespaces#4% + \stoppositioning + \box\colorbarbox}} + +\def\dodostartfigure[#1][#2][#3]#4\stopfigure + {\doifelse\v!test\@@exoption + {\teststartfigure[#1][#2][#3]#4\teststopfigure + \let\@@exframes\v!on} + {\let\@@exframes\v!off}% + \setvalue{\??ef\??ef#1}% + {\dosingleempty{\placestartfigure[#1][#2][#3]#4\placestopfigure}}% + }% no longer \doifundefined{#1}{\setvalue{#1}{\getexternalfigure{#1}}}} + +% De onderstaande macro mag niet zondermeer worden aangepast +% en is afgestemd op gebruik in de handleiding. + +\def\teststartfigure[#1][#2][#3]#4\teststopfigure% + {\begingroup + \setbox0\hbox + {\useexternalfigure[\s!dummy][#2][\c!wfactor=\v!max]% + \externalfigure[\s!dummy]}% + \def\referring{\efmark}% + \def\marking{\efmark}% + \def\remark{\efcomment\v!yes}% + \def\colorbar##1[##2]{}% + \efreference\zerocount + \setbox0\vbox + {\hsize240pt + \startpositioning + \calculateefsteps + \position(0,0) + {\box0}% + \position(0,0) + {\basegrid + [\c!nx=\@@exxmax, + \c!dx=\withoutpt\the\efxsteps, + \c!ny=\@@exymax, + \c!dy=\withoutpt\the\efysteps, + \c!xstep=1, + \c!ystep=1, + \c!scale=1, + \c!offset=\v!no, + \c!unit=pt]}% + \setuppositioning + [\c!unit=pt, + \c!xscale=\withoutpt\the\efxsteps, + \c!yscale=\withoutpt\the\efysteps, + \c!factor=1]% + \linewidth\onepoint + \ignorespaces#4\relax + \stoppositioning + \vfill}% + \efreference\zerocount + \def\referring{\eftext{$\rightarrow$}}% + \def\marking{\eftext{$\leftarrow$}}% + \def\remark{\efnocomment}% + \def\colorbar##1[##2]{}% + \setbox2\vbox + {{\tfa\doifelsenothing{#1}{#2}{#1}} + \blank + \tfxx#4 + \vfilll}% + \ifdim\ht0>\ht2 + \ht2\ht0 + \else + \ht0\ht2 + \fi + \hbox + {\hskip3em + \vtop{\vskip12pt\box0\vskip6pt}% + \vtop{\vskip12pt\box2\vskip6pt}}% + \endgroup} + +\def\dodostartfigure[#1][#2][#3]#4\stopfigure + {\doifelse\v!test\@@exoption + {\teststartfigure[#1][#2][#3]#4\teststopfigure + \let\@@exframe\v!on} + {\let\@@exframe\v!off}% + \setvalue{\??ef\??ef#1}% + {\def\next{\placestartfigure[#1][#2][#3]#4\placestopfigure}% + \dosingleempty\next}% + }% no longer: \doifundefined{#1}{\setvalue{#1}{\getexternalfigure{#1}}}} + +\long\def\dostartfigure#1% + {\dotripleargument\dodostartfigure#1\stopfigure} + +\unexpanded\def\startfigure + {\grabuntil{\e!stop\v!figure}\dostartfigure} + +%D NEW: used in styledesign manual + +% beware in mkiv we don't have the typeset- prefix +% +% \setbuffer[typeset-b]\endbuffer +% \setbuffer[typeset-a]\endbuffer +% +% todo: +% +% \appendtoks \setbuffer[typeset-b]\endbuffer\to \everystarttext +% \appendtoks \setbuffer[typeset-a]\endbuffer\to \everystarttext + +\newcount\noftypesetbuffers + +\def\typesetbuffer + {\dodoubleempty\dotypesetbuffer} + +\def\dotypesetbuffer[#1][#2]% beware: this will mix up the mp graphics + {\ifsecondargument + \dodotypesetbuffer[#1][#2]% + \else\iffirstargument + \doifassignmentelse{#1} + {\dodotypesetbuffer[\jobname][#1]}% + {\dodotypesetbuffer[#1][]}% + \else + \dodotypesetbuffer[\jobname][] + \fi\fi} + +% \def\dodotypesetbuffer[#1][#2]% +% {\bgroup +% \global\advance\noftypesetbuffers\plusone +% \edef\bufferfilename{\jobname-buffer-\the\noftypesetbuffers}% +% \doifmode{*\v!first} +% {\ctxlua{buffers.save("\bufferfilename.tmp","#1",true)}% +% \executesystemcommand{context \bufferfilename.tmp}}% +% \externalfigure[\bufferfilename.pdf][#2]% +% \egroup} + +\def\dodotypesetbuffer[#1][#2]% + {\bgroup + \global\advance\noftypesetbuffers\plusone + \edef\bufferfilename{\jobname-buffer-\the\noftypesetbuffers}% + \ctxlua{buffers.run("\bufferfilename.tmp","#1",true)}% + \externalfigure[\bufferfilename.pdf][#2]% + \egroup} + +\def\dodotypesetbufferindeed#1% + {} + +% for me only (manuals and such) +% +% \definetypesetting [name] [options] [settings-a] +% +% \typesetfile [name] [file] [settings-b] +% \typesetfile [file] [options] [settings-b] +% \typesetfile [file] [settings-b] +% \typesetfile [file] +% +% \enabletrackers[files.run] +% \starttext +% \typesetfile[oepsoeps.tex][width=10cm,frame=on] +% \stoptext + +\definesystemvariable{tz} + +\unexpanded\def\definetypesetting{\dotripleempty\dodefinetypesetting} +\def\typesetfile {\dotripleempty\dotypesetfile} + +\unexpanded\def\definetypesetting{\dotripleempty\dodefinetypesetting} +\def\typesetfile {\dotripleempty\dotypesetfile} + +\def\dodefinetypesetting[#1][#2][#3]% <name> options settings-a + {\doifsomething{#1}{\setvalue{\??tz#1}{\dodotypesetfile{#2}{#3}}}} + +\def\dotypesetfile[#1][#2][#3]% <name> filename settings-b | filename options settings + {\ifcsname\??tz#1\endcsname + \csname\??tz#1\endcsname{#2}{#3}% + \else\ifthirdargument % filename options settings + \dodotypesetfile{#2}{#3}{#1}{}% + \else\ifsecondargument % filename settings + \dodotypesetfile{}{#2}{#1}{}% + \fi\fi\fi} + +\def\dodotypesetfile#1#2#3#4% options settings-a filename settings-b + {\edef\typesetfilename{\ctxlua{tex.write(jobfiles.run("#3","#1"))}}% + \expanded{\externalfigure[\typesetfilename]}[#2,#4]} + +\setupexternalfigures + [\c!option=, + \c!object=\v!yes, % we only check for no + \c!reset=\v!no, + \c!maxwidth=\@@efwidth, + \c!maxheight=\@@efheight, + \c!bodyfont=\bodyfontsize, + \c!directory=, + \c!file=\f!utilityfilename.\f!figureextension, + \c!radius=.5\bodyfontsize, + \c!corner=\v!rectangular, + \c!frame=\v!off, + \c!background=, % new + \c!splitcolor=\s!white, + \c!conversion=, + \c!prefix=, + \c!cache=, +% \c!grid=, + \c!equalwidth=, + \c!equalheight=, + \c!location={\v!local,\v!global}] + +\setupexternalfigures + [\c!frames=\v!off, + \c!ymax=24, + \c!xmax=] + +\useexternalfigure + [buffer] [\jobname.buffer] [\c!object=\v!no] + +\protect \endinput + +% alternative for positioning + +% \definelayer[figure][width=\overlaywidth,height=\overlayheight] +% \defineoverlay[figure][{\directsetup{figure}\tightlayer[figure]}] + +% \setupcolors[state=start] + +% \starttext + +% \startsetups figure +% \setlayerframed[figure][preset=rightbottom,x=.25\layerwidth,y=.25\layerheight]{HERE} +% \setlayerframed[figure][preset=leftbottom, x=.15\layerwidth,y=.35\layerheight]{THERE} +% \stopsetups + +% \externalfigure[cow][background={foreground,figure},width=4cm,height=8cm] + +% \startsetups figure +% \setlayerframed[figure][preset=righttop,x=.25\layerwidth,y=.25\layerheight]{MORE} +% \setlayerframed[figure][preset=middle,foregroundcolor=green]{EVEN MORE} +% \stopsetups + +% \externalfigure[cow][background={foreground,figure},width=14cm,height=2cm] + +% \defineexternalfigure[whatever][background={foreground,figure}] + +% \startsetups figure +% \setlayerframed[figure][preset=righttop,x=.25\layerwidth,y=.25\layerheight]{\red MORE} +% \setlayerframed[figure][preset=middle,foregroundcolor=green]{EVEN MORE} +% \stopsetups + +% \externalfigure[cow][whatever][width=14cm,height=4cm] + +% \stoptext + diff --git a/tex/context/base/grph-fil.lua b/tex/context/base/grph-fil.lua new file mode 100644 index 000000000..2e32c7a60 --- /dev/null +++ b/tex/context/base/grph-fil.lua @@ -0,0 +1,42 @@ +if not modules then modules = { } end modules ['grph-fil'] = { + version = 1.001, + comment = "companion to grph-fig.mkiv", + 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 + +local trace_run = false trackers.register("files.run",function(v) trace_run = v end) + +local command = "context %s" + +jobfiles = jobfiles or { } +jobfiles.collected = jobfiles.collected or { } +jobfiles.tobesaved = jobfiles.tobesaved or { } + +local tobesaved, collected = jobfiles.tobesaved, jobfiles.collected + +local function initializer() + tobesaved, collected = jobfiles.tobesaved, jobfiles.collected +end + +job.register('jobfiles.collected', jobfiles.tobesaved, initializer) + +jobfiles.forcerun = false + +function jobfiles.run(name,...) + local oldchecksum = collected[name] + local newchecksum = file.checksum(name) + if jobfiles.forcerun or not oldchecksum or oldchecksum ~= newchecksum then + if trace_run then + commands.writestatus("buffers","changes in '%s', processing forced",name) + end + os.execute(format(command,concat({ name, ... }," "))) + elseif trace_run then + commands.writestatus("buffers","no changes in '%s', not processed",name) + end + tobesaved[name] = newchecksum + return file.replacesuffix(name,"pdf") +end diff --git a/tex/context/base/grph-inc.lua b/tex/context/base/grph-inc.lua new file mode 100644 index 000000000..508240a3b --- /dev/null +++ b/tex/context/base/grph-inc.lua @@ -0,0 +1,1115 @@ +if not modules then modules = { } end modules ['grph-inc'] = { + version = 1.001, + comment = "companion to grph-inc.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- lowercase types +-- mps tex tmp svg +-- partly qualified +-- dimensions +-- consult rlx + +-- figures.boxnumber can go as we now can use names + +--[[ +The ConTeXt figure inclusion mechanisms are among the oldest code +in ConTeXt and evolve dinto a complex whole. One reason is that we +deal with backend in an abstract way. What complicates matters is +that we deal with internal graphics as well: TeX code, MetaPost code, +etc. Later on figure databases were introduced, which resulted in +a plug in model for locating images. On top of that runs a conversion +mechanism (with caching) and resource logging. + +Porting that to Lua is not that trivial because quite some +status information is kept between al these stages. Of course, image +reuse also has some price, and so I decided to implement the graphics +inclusion in several layers: detection, loading, inclusion, etc. + +Object sharing and scaling can happen at each stage, depending on the +way the resource is dealt with. + +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 format, lower, find, match, gsub, gmatch = string.format, string.lower, string.find, string.match, string.gsub, string.gmatch +local texsprint, texbox = tex.sprint, tex.box +local contains = table.contains +local concat = table.concat +local todimen = string.todimen + +local ctxcatcodes = tex.ctxcatcodes +local variables = interfaces.variables + +local trace_figures = false trackers.register("figures.locating", function(v) trace_figures = v end) +local trace_bases = false trackers.register("figures.bases", function(v) trace_bases = v end) +local trace_programs = false trackers.register("figures.programs", function(v) trace_programs = v end) +local trace_conversion = false trackers.register("figures.conversion", function(v) trace_conversion = v end) +local trace_inclusion = false trackers.register("figures.inclusion", function(v) trace_inclusion = v end) + +--- some extra img functions --- + +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 result +end + +function img.serialize(i) + return table.serialize(img.totable(i)) +end + +function img.clone(i,data) + i.width = data.width or i.width + i.height = data.height or i.height + -- attr etc + return i +end + +local validsizes = table.tohash(img.boxes()) +local validtypes = table.tohash(img.types()) + +function img.check_size(size) + if size then + size = gsub(size,"box","") + return (validsizes[size] and size) or "crop" + else + return "crop" + end +end + +--- + +figures = figures or { } +figures.loaded = figures.loaded or { } +figures.used = figures.used or { } +figures.found = figures.found or { } +figures.suffixes = figures.suffixes or { } +figures.patterns = figures.patterns or { } +figures.boxnumber = figures.boxnumber or 0 +figures.defaultsearch = true +figures.defaultwidth = 0 +figures.defaultheight = 0 +figures.defaultdepth = 0 +figures.n = 0 +figures.prefer_quality = true -- quality over location + +figures.localpaths = { + ".", "..", "../.." +} +figures.cachepaths = { + prefix = "", + path = ".", + subpath = ".", +} + +figures.paths = table.copy(figures.localpaths) + +figures.order = { + "pdf", "mps", "jpg", "png", "jbig", "svg", "eps", "gif", "mov", "buffer", "tex", +} + +figures.formats = { + ["pdf"] = { list = { "pdf" } }, + ["mps"] = { patterns = { "mps", "%d+" } }, + ["jpg"] = { list = { "jpg", "jpeg" } }, + ["png"] = { list = { "png" } }, + ["jbig"] = { list = { "jbig", "jbig2", "jb2" } }, + ["svg"] = { list = { "svg", "svgz" } }, + ["eps"] = { list = { "eps", "ai" } }, + ["gif"] = { list = { "gif" } }, + ["mov"] = { list = { "mov", "avi" } }, + ["buffer"] = { list = { "tmp", "buffer", "buf" } }, + ["tex"] = { list = { "tex" } }, +} + +function figures.setlookups() + figures.suffixes, figures.patterns = { }, { } + for _, format in next, figures.order do + local data = figures.formats[format] + local fs, fp = figures.suffixes, figures.patterns + local list = data.list + if list then + for i=1,#list do + fs[list[i]] = format -- hash + end + else + fs[format] = format + end + local patterns = data.patterns + if patterns then + for i=1,#patterns do + fp[#fp+1] = { patterns[i], format } -- array + end + end + end +end + +figures.setlookups() + +local function register(tag,target,what) + local data = figures.formats[target] -- resolver etc + if not data then + data = { } + figures.formats[target] = data + end + local d = data[tag] -- list or pattern + if d and not contains(d,what) then + d[#d+1] = what -- suffix or patternspec + else + data[tag] = { what } + end + if not contains(figures.order,target) then + figures.order[#figures.order+1] = target + end + figures.setlookups() +end + +function figures.registersuffix (suffix, target) register('list', target,suffix ) end +function figures.registerpattern(pattern,target) register('pattern',target,pattern) end + +local last_locationset, last_pathlist = last_locationset or nil, last_pathlist or nil + +function figures.setpaths(locationset,pathlist) + if last_locationset == locationset and last_pathlist == pathlist then + -- this function can be called each graphic so we provide this optimization + return + end + local iv, t, h = interfaces.variables, figures.paths, locationset:tohash() + if last_locationset ~= locationset then + -- change == reset (actually, a 'reset' would indeed reset + if h[iv["local"]] then + t = table.fastcopy(figures.localpaths or { }) + else + t = { } + end + figures.defaultsearch = h[iv["default"]] + last_locationset = locationset + end + if h[iv["global"]] then + -- for s in gmatch(pathlist,",* *([^,]+)") do + local list = aux.settings_to_array(pathlist) + for i=1,#list do + local s = list[i] + if not contains(t,s) then + t[#t+1] = s + end + end + end + figures.paths, last_pathlist = t, pathlist + if trace_figures then + commands.writestatus("figures","locations: %s",last_locationset) + commands.writestatus("figures","path list: %s",concat(figures.paths, " ")) + end +end + +-- check conversions and handle it here + +function figures.hash(data) + return data.status.hash or tostring(data.status.private) -- the <img object> +-- return data.status.fullname .. "+".. (data.status.page or data.request.page or 1) -- img is still not perfect +end + +-- interfacing to tex + +do + + local figuredata = { } + local callstack = { } + + function figures.new() + figuredata = { + request = { + name = false, + label = false, + format = false, + page = false, + width = false, + height = false, + preview = false, + ["repeat"] = false, + controls = false, + display = false, + conversion = false, + cache = false, + prefix = false, + size = false, + }, + used = { + fullname = false, + format = false, + name = false, + path = false, + suffix = false, + width = false, + height = false, + }, + status = { + status = 0, + converted = false, + cached = false, + fullname = false, + format = false, + }, + } + return figuredata + end + + function figures.push(request) + local ncs = #callstack + 1 + if ncs == 1 then + statistics.starttiming(figures) + end + local figuredata = figures.new() + if request then + 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] == variables.yes + request["repeat"] = iv[request["repeat"]] == variables.yes + request.preview = iv[request.preview] == variables.yes + 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 + table.merge(figuredata.request,request) + end + callstack[ncs] = figuredata + return figuredata + end + function figures.pop() + local ncs = #callstack + figuredata = callstack[ncs] + callstack[ncs] = nil + if ncs == 1 then + statistics.stoptiming(figures) + end + end + -- maybe move texsprint to tex + function figures.get(category,tag,default) + local value = figuredata[category] + value = value and value[tag] + if not value or value == "" or value == true then + return default or "" + else + return value + end + end + function figures.tprint(category,tag,default) + texsprint(ctxcatcodes,figures.get(category,tag,default)) + end + function figures.current() + return callstack[#callstack] + end + +end + +local defaultformat = "pdf" +local defaultprefix = "m_k_v_i_" + +local function register(askedname,specification) + if specification then + local format = specification.format + if format then + local conversion = specification.conversion + if conversion == "" then + conversion = nil + end + local newformat = conversion + if not newformat or newformat == "" then + newformat = defaultformat + end + local converter = (newformat ~= format) and figures.converters[format] + if trace_conversion then + logs.report("figures","checking conversion of '%s': old format '%s', new format '%s', conversion '%s'", + askedname,format,newformat,conversion or "default") + end + if converter then + if converter[newformat] then + converter = converter[newformat] + else + newformat = defaultformat + if converter[newformat] then + converter = converter[newformat] + else + newformat = defaultformat + end + end + end + if converter then + local oldname = specification.fullname + local newpath = file.dirname(oldname) + local oldbase = file.basename(oldname) + local newbase = file.replacesuffix(oldbase,newformat) + local fc = specification.cache or figures.cachepaths.path + if fc and fc ~= "" and fc ~= "." then + newpath = fc + else + newbase = defaultprefix .. newbase + 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) + oldname = file.collapse_path(oldname) + newname = file.collapse_path(newname) + local oldtime = lfs.attributes(oldname,'modification') or 0 + local newtime = lfs.attributes(newname,'modification') or 0 + if oldtime > newtime then + if trace_conversion then + logs.report("figures","converting '%s' from '%s' to '%s'",askedname,format,newformat) + end + converter(oldname,newname) + else + if trace_conversion then + logs.report("figures","no need to convert '%s' from '%s' to '%s'",askedname,format,newformat) + end + 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 + end + local found = figures.suffixes[format] -- validtypes[format] + if not found then + specification.found = false + if trace_figures then + commands.writestatus("figures","format not supported: %s",format) + end + else + specification.found = true + if trace_figures then + if validtypes[format] then + commands.writestatus("figures","format natively supported by backend: %s",format) + else + commands.writestatus("figures","format supported by output file format: %s",format) + end + end + end + else + specification = { } + end + specification.foundname = specification.foundname or specification.fullname + figures.found[askedname .. "->" .. (specification.conversion or "default")] = specification + return specification +end + +local resolve_too = true -- urls + +local function locate(request) -- name, format, cache + local askedname = resolvers.clean_path(request.name) + local foundname = figures.found[askedname .. "->" .. (request.conversion or "default")] + if foundname then + return foundname + end + -- protocol check + local hashed = url.hashed(askedname) + if hashed and hashed.scheme ~= "file" then + local foundname = resolvers.findbinfile(askedname) + if foundname then + askedname = foundname + end + end + -- we could use the hashed data instead + local askedpath= file.is_rootbased_path(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 + local askedconversion = request.conversion + if askedformat ~= "" then + if trace_figures then + commands.writestatus("figures","strategy: forced format") + end + askedformat = lower(askedformat) + local format = figures.suffixes[askedformat] + if not format then + local figurepatterns = figures.patterns + for i=1,#figurepatterns do + local pattern = figurepatterns[i] + if find(askedformat,pattern[1]) then + format = pattern[2] + break + end + end + end + if format then + local foundname = figures.exists(askedname,format,resolve_too) -- not askedformat + if foundname then + return register(askedname, { + askedname = askedname, + fullname = askedname, + format = format, + cache = askedcache, + foundname = foundname, + conversion = askedconversion, + }) + end + end + if askedpath then + -- path and type given, todo: strip pieces of path + if figures.exists(askedname,askedformat,resolve_too) then + return register(askedname, { + askedname = askedname, + fullname = askedname, + format = askedformat, + cache = askedcache, + conversion = askedconversion, + }) + end + else + -- type given + local figurepaths = figures.paths + for i=1,#figurepaths do + local path = figurepaths[i] + local check = path .. "/" .. askedname + -- we pass 'true' as it can be an url as well, as the type + -- is given we don't waste much time + if figures.exists(check,askedformat,resolve_too) then + return register(check, { + askedname = askedname, + fullname = check, + format = askedformat, + cache = askedcache, + conversion = askedconversion, + }) + end + end + if figures.defaultsearch then + local check = resolvers.find_file(askedname) + if check and check ~= "" then + return register(askedname, { + askedname = askedname, + fullname = check, + format = askedformat, + cache = askedcache, + conversion = askedconversion, + }) + end + end + end + elseif askedpath then + if trace_figures then + commands.writestatus("figures","strategy: rootbased path") + end + local figureorder = figures.order + for i=1,#figureorder do + local format = figureorder[i] + local list = figures.formats[format].list or { format } + for j=1,#list do + local suffix = list[j] + local check = file.addsuffix(askedname,suffix) + if figures.exists(check,format,resolve_too) then + return register(askedname, { + askedname = askedname, + fullname = check, + format = format, + cache = askedcache, + conversion = askedconversion, + }) + end + end + end + else + if figures.prefer_quality then + if trace_figures then + commands.writestatus("figures","strategy: unknown format, prefer quality") + end + local figurepaths = figures.paths + local figureorder = figures.order + for j=1,#figureorder do + local format = figureorder[j] + local list = figures.formats[format].list or { format } + for k=1,#list do + local suffix = list[k] + -- local name = file.replacesuffix(askedbase,suffix) + local name = file.replacesuffix(askedname,suffix) + for i=1,#figurepaths do + local path = figurepaths[i] + local check = path .. "/" .. name + local isfile = url.hashed(check).scheme == "file" + if not isfile then + if trace_figures then + commands.writestatus("figures","warning: skipping path %s",path) + end + elseif figures.exists(check,format,true) then + return register(askedname, { + askedname = askedname, + fullname = check, + format = format, + cache = askedcache, + conversion = askedconversion, + }) + end + end + end + end + else -- 'location' + if trace_figures then + commands.writestatus("figures","strategy: unknown format, prefer path") + end + local figurepaths = figures.paths + local figureorder = figures.order + for i=1,#figurepaths do + local path = figurepaths[i] + for j=1,#figureorder do + local format = figureorder[j] + local list = figures.formats[format].list or { format } + for k=1,#list do + local suffix = list[k] + local check = path .. "/" .. file.replacesuffix(askedbase,suffix) + if figures.exists(check,format,resolve_too) then + return register(askedname, { + askedname = askedname, + fullname = check, + format = format, + cache = askedcache, + conversion = askedconversion, + }) + end + end + end + end + end + if figures.defaultsearch then + if trace_figures then + commands.writestatus("figures","strategy: default tex path") + end + local figureorder = figures.order + for j=1,#figureorder do + local format = figureorder[j] + local list = figures.formats[format].list or { format } + for k=1,#list do + local suffix = list[k] + 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, + conversion = askedconversion, + }) + end + end + end + end + end + return register(askedname) +end + +-- -- -- 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.programs = figures.programs or { } + +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 +end + +function figures.identify(data) + data = data or figures.current() + local list = figures.identifiers.list + for i=1,#list do + local identifier = list[i] + data = identifier(data) + if data.status.status > 0 then + break + end + end + return data +end +function figures.exists(askedname,format,resolve) + return (figures.existers[format] or figures.existers.generic)(askedname,resolve) +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() +--~ print(table.serialize(figures.current())) + local dr, du, ds, nr = data.request, data.used, data.status, figures.boxnumber + local box = texbox[nr] + ds.width = box.width + ds.height = box.height + ds.xscale = ds.width /(du.width or 1) + ds.yscale = ds.height/(du.height or 1) +--~ print(table.serialize(figures.current())) + return data +end + +function figures.dummy(data) + data = data or figures.current() + local dr, du, ds, nr = data.request, data.used, data.status, figures.boxnumber + local box = node.hpack(node.new("hlist")) -- we need to set the dir (luatex 0.60 buglet) + du.width = du.width or figures.defaultwidth + du.height = du.height or figures.defaultheight + du.depth = du.depth or figures.defaultdepth + -- box.dir = "TLT" + box.width = du.width + box.height = du.height + box.depth = du.depth + texbox[nr] = box -- hm, should be global (to be checked for consistency) +end + +-- -- -- generic -- -- -- + +function figures.existers.generic(askedname,resolve) + -- not findbinfile + local result + if lfs.isfile(askedname) then + result = askedname + elseif resolve then + result = resolvers.findbinfile(askedname) or "" + if result == "" then result = false end + end + if trace_figures then + if result then + commands.writestatus("figures","found: %s -> %s",askedname,result) + else + commands.writestatus("figures","not found: %s",askedname) + end + end + return result +end +function figures.checkers.generic(data) + local dr, du, ds = data.request, data.used, data.status + local name, page, size, color = du.fullname or "unknown generic", du.page or dr.page, dr.size or "crop", dr.color or "natural" + local conversion = dr.conversion + if not conversion or conversion == "" then + conversion = "unknown" + end + local hash = name .. "->" .. page .. "->" .. size .. "->" .. color .. "->" .. conversion + local figure = figures.loaded[hash] + if figure == nil then + figure = img.new { filename = name, page = page, pagebox = dr.size } + backends.codeinjections.setfigurecolorspace(data,figure) + figure = (figure and img.scan(figure)) or false + local f, d = backends.codeinjections.setfigurealternative(data,figure) + figure, data = f or figure, d or data + figures.loaded[hash] = figure + if trace_conversion then + logs.report("figures","new graphic, hash: %s",hash) + end + else + if trace_conversion then + logs.report("figures","existing graphic, hash: %s",hash) + end + end + if figure then + du.width = figure.width + du.height = figure.height + du.pages = figure.pages + ds.private = figure + ds.hash = hash + end + return data +end +function figures.includers.generic(data) + local dr, du, ds = data.request, data.used, data.status + -- 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 + figure = ds.private + if figure then + figure = img.copy(figure) + figure = (figure and img.clone(figure,data.request)) or false + end + figures.used[hash] = figure + end + if figure then + local nr = figures.boxnumber + -- it looks like we have a leak in attributes here .. todo + local box = node.hpack(img.node(figure)) -- img.node(figure) not longer valid + box.width, box.height, box.depth = figure.width, figure.height, 0 -- new, hm, tricky, we need to do that in tex (yet) + texbox[nr] = box + ds.objectnumber = figure.objnum + texsprint(ctxcatcodes,"\\relocateexternalfigure") + end + return data +end + +-- -- -- nongeneric -- -- -- + +function figures.checkers.nongeneric(data,command) + local dr, du, ds = data.request, data.used, data.status + local name = du.fullname or "unknown nongeneric" + local hash = name + if dr.object then + -- hm, bugged + if not jobobjects.get("FIG::"..hash) then + texsprint(ctxcatcodes,command) + texsprint(ctxcatcodes,format("\\setobject{FIG}{%s}\\vbox{\\box\\foundexternalfigure}",hash)) + end + texsprint(ctxcatcodes,format("\\global\\setbox\\foundexternalfigure\\vbox{\\getobject{FIG}{%s}}",hash)) + else + texsprint(ctxcatcodes,command) + end + return data +end +function figures.includers.nongeneric(data) + return data +end + +-- -- -- mov -- -- -- + +function figures.checkers.mov(data) + local dr, du, ds = data.request, data.used, data.status + local width = todimen(dr.width or figures.defaultwidth) + local height = todimen(dr.height or figures.defaultheight) + local foundname = du.fullname + dr.width, dr.height = width, height + du.width, du.height, du.foundname = width, height, foundname + if trace_inclusion then + logs.report("figures","including movie '%s': width %s, height %s",foundname,width,height) + end + -- we need to push the node.write in between ... we could make a shared helper for this + context.startfoundexternalfigure(width .. "sp",height .. "sp") + context(function() + backends.codeinjections.insertmovie { + width = width, + height = height, + factor = number.dimenfactors.bp, + ["repeat"] = dr["repeat"], + controls = dr.controls, + preview = dr.preview, + label = dr.label, + foundname = foundname, + } + end) + context.stopfoundexternalfigure() + return data +end + +figures.includers.mov = figures.includers.nongeneric + +-- -- -- mps -- -- -- + +local function internal(askedname) + local spec, mprun, mpnum = match(lower(askedname),"mprun(:?)(.-)%.(%d+)") + if spec == ":" then + return mprun, mpnum + else + return "", mpnum + end +end + +function figures.existers.mps(askedname) + local mprun, mpnum = internal(askedname) + if mpnum then + return askedname + else + return figures.existers.generic(askedname) + end +end +function figures.checkers.mps(data) + local mprun, mpnum = internal(data.used.fullname) + if mpnum then + return figures.checkers.nongeneric(data,format("\\docheckfiguremprun{%s}{%s}",mprun,mpnum)) + else + return figures.checkers.nongeneric(data,format("\\docheckfiguremps{%s}",data.used.fullname)) + end +end +figures.includers.mps = figures.includers.nongeneric + +-- -- -- buffer -- -- -- + +function figures.existers.buffer(askedname) + askedname = file.nameonly(askedname) + return buffers.exists(askedname) and askedname +end +function figures.checkers.buffer(data) + return figures.checkers.nongeneric(data,format("\\docheckfigurebuffer{%s}", file.nameonly(data.used.fullname))) +end +figures.includers.buffers = figures.includers.nongeneric + +-- -- -- tex -- -- -- + +function figures.existers.tex(askedname) + askedname = resolvers.find_file(askedname) + return (askedname ~= "" and askedname) or false +end +function figures.checkers.tex(data) + return figures.checkers.nongeneric(data,format("\\docheckfiguretex{%s}", data.used.fullname)) +end +figures.includers.tex = figures.includers.nongeneric + +-- -- -- converters -- -- -- + +local function makeoptions(program) + local to = type(options) + return (to == "table" and concat(options," ")) or (to == "string" and options) or "" +end + +local function runprogram(...) + local command = format(...) + if trace_conversion or trace_programs then + logs.report("figures","running %s",command) + end + os.spawn(command) +end + +-- -- -- eps -- -- -- + +local epsconverter = { } +figures.converters.eps = epsconverter + +figures.programs.gs = { + options = { + "-dAutoRotatePages=/None", + "-dPDFSETTINGS=/prepress", + "-dEPSCrop", + }, + command = (os.type == "windows" and "gswin32") or "gs" +} + +function epsconverter.pdf(oldname,newname) + local gs = figures.programs.gs + runprogram ( + '%s -q -sDEVICE=pdfwrite -dNOPAUSE -dNOCACHE -dBATCH %s -sOutputFile="%s" "%s" -c quit', + gs.command, makeoptions(gs.options), newname, oldname + ) +end + +epsconverter.default = epsconverter.pdf + +-- -- -- svg -- -- -- + +local svgconverter = { } +figures.converters.svg = svgconverter +figures.converters.svgz = svgconverter + +-- inkscape on windows only works with complete paths + +figures.programs.inkscape = { + options = { + "--export-dpi=600" + }, + command = "inkscape" +} + +function svgconverter.pdf(oldname,newname) + local inkscape = figures.programs.inkscape + runprogram ( + '%s "%s" --export-pdf="%s" %s', + inkscape.command, oldname, newname, makeoptions(inkscape.options) + ) +end + +function svgconverter.png(oldname,newname) + local inkscape = figures.programs.inkscape + runprogram ( + '%s "%s" --export-png="%s" %s', + inkscape.command, oldname, newname, makeoptions(inkscape.options) + ) +end + +svgconverter.default = svgconverter.pdf + +-- -- -- gif -- -- -- + +local gifconverter = { } +figures.converters.gif = gifconverter + +figures.programs.convert = { + command = "convert" -- imagemagick +} + +function gifconverter.pdf(oldname,newname) + local convert = figures.programs.convert + runprogram ( + "convert %s %s", + convert.command, makeoptions(convert.options), oldname, newname + ) +end + +gifconverter.default = gifconverter.pdf + +-- todo: lowres + +-- -- -- bases -- -- -- + +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 + +local bases = figures.bases + +function bases.use(basename) + if basename == "reset" then + bases.list, bases.used, bases.found, bases.enabled = { }, { }, { }, false + else + basename = file.addsuffix(basename,"xml") + if not bases.used[basename] then + local t = { basename, nil, nil } + 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 + if trace_bases then + commands.writestatus("figures","registering base '%s'",basename) + end + end + end +end + +function bases.find(basename,askedlabel) + if trace_bases then + commands.writestatus("figures","checking for '%s' in base '%s'",askedlabel,basename) + end + basename = file.addsuffix(basename,"xml") + local t = bases.found[askedlabel] + if t == nil then + local base = bases.used[basename] + local page = 0 + if base[2] == nil then + -- no yet located + local figurepaths = figures.paths + for i=1,#figurepaths do + local path = figurepaths[i] + local xmlfile = path .. "/" .. basename + if io.exists(xmlfile) then + base[2] = xmlfile + base[3] = xml.load(xmlfile) + if trace_bases then + commands.writestatus("figures","base '%s' loaded",xmlfile) + end + break + end + end + end + t = false + if base[2] and base[3] then -- rlx:library + for e in xml.collected(base[3],"/(*:library|figurelibrary)/*:figure/*:label") do + page = page + 1 + if xml.text(e) == askedlabel then + t = { + base = file.replacesuffix(base[2],"pdf"), + format = "pdf", + name = xml.text(e,"../*:file"), -- to be checked + page = page, + } + bases.found[askedlabel] = t + if trace_bases then + commands.writestatus("figures","figure '%s' found in base '%s'",askedlabel,base[2]) + end + return t + end + end + if trace_bases and not t then + commands.writestatus("figures","figure '%s' not found in base '%s'",askedlabel,base[2]) + end + end + end + return t +end + +-- we can access sequential or by name + +function bases.locate(askedlabel) + local list = bases.list + for i=1,#list do + local entry = list[i] + local t = bases.find(entry[1],askedlabel) + if t then + return t + end + end + return false +end + +function figures.identifiers.base(data) + if bases.enabled then + local dr, du, ds = data.request, data.used, data.status + local fbl = bases.locate(dr.name or dr.label) + if fbl then + du.page = fbl.page + du.format = fbl.format + du.fullname = fbl.base + ds.fullname = fbl.name + ds.format = fbl.format + ds.page = fbl.page + ds.status = 10 + end + end + return data +end + +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/grph-inc.mkii b/tex/context/base/grph-inc.mkii new file mode 100644 index 000000000..1bd7544d8 --- /dev/null +++ b/tex/context/base/grph-inc.mkii @@ -0,0 +1,1243 @@ +%D \module +%D [ file=grph-inc, % moved from core-fig +%D version=2006.08.26, % overhaul of 1997.03.31 +%D title=\CONTEXT\ Graphic 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 Graphic Macros / Figure Inclusion} + +% todo: directory : system -> \allinputpaths (so that we can \usesubpath) + +%D This is a reimplementation of the original module, which +%D over time had evolved into a pretty complex whole. This +%D was partly due to the fact that we needed to handle many +%D formats, deal with substitute graphics, handle fallbacks +%D and driver specifics (objects), etc. In the meantime we +%D have more clever backends, moved away from texutil to +%D rlxtools, can use runtime or betweentime runs etc. Also, +%D more memory permits a cleaner implementation. Time to +%D move on. We can now also assume that scaling is available. +%D +%D Another mess that can go is the llx/lly handling since +%D drivers now automatically can determine such things. + +%D Messages 3 and 5 needs to be translated! + +\unprotect + +%D Due to the mere fact that \DVI|/|\PDF\ drivers differ in their +%D needs for figure dimensions, we have to provide the width, +%D height, horizontal and vertical scale. Also we want to +%D specify at the user level either width and|/|or height, scale, +%D or a factor related to the current document bodyfont size. +%D Even better: we can also specify isometric scaling and +%D automatically let \CONTEXT\ calculate the maximum possible +%D dimensions. Whatever we calculate, the results will come +%D available in the next registers. + +\letempty \@@DriverImageBox +\letempty \@@DriverImageOptions +\letempty \@@DriverImageWidth +\letempty \@@DriverImageHeight +\letempty \@@DriverImageFile +\letempty \@@DriverImageLabel +\letempty \@@DriverImageType +\letempty \@@DriverImageMethod +\letempty \@@DriverImagePage + +%D Because looking for dimensions can take many steps (locating +%D the figure, maybe on more directories, scanning the figure +%D on dimension, or when not found, trying to find them in the +%D utility file, and again when not found, trying to generate +%D such a file, and, as a last resort, trying to use the +%D dimensions. Now when things do not work out the way we want, +%D we can set a switch and get some information on what takes +%D place. + +\newif\iftraceexternalfigures + +\let\traceexternalfigures\traceexternalfigurestrue + +\def\doshowfigurestate + {\iftraceexternalfigures + \expandafter\writestatus\expandafter\m!figures + \else + \expandafter\gobbleoneargument + \fi} + +\def\doshowfiguremessage + {\iftraceexternalfigures + \expandafter\gobbletwoarguments + \else + \expandafter\showmessage\expandafter\m!figures + \fi} + +%D Another switch tells \CONTEXT\ to locate and calculate a +%D figure, but does not actually insert it. Especially when we +%D use \PDFTEX\ this saves a lot of time on trialruns. (Keep +%D in mind that \PDFTEX\ is both a \TEX\ pre|| and postprocessor.) + +\newif\ifskipexternalfigures % can be set elsewhere + +% \newif\ifrunutilityfile +% \newif\ifconsultutilityfile +% +% Let's save two hash entries: + +\let\runutilityfiletrue \relax \let\runutilityfilefalse \relax +\let\consultutilityfiletrue\relax \let\consultutilityfilefalse\relax + +%D Intermediate, private. + +\newdimen\determinedfigurewidth +\newdimen\determinedfigureheight + +\let\naturalfigureheight\!!zeropoint +\let\naturalfigurewidth \!!zeropoint + +\def\defaultfigurewidth {8\lineheight} +\def\defaultfigureheight{6\lineheight} + +\def\defaultfigurepathsignal{(\v!default)} + +\def\checknaturalfiguredimensions + {\edef\naturalfigurewidth{\the\dimexpr\ifzeropt\determinedfigurewidth + \defaultfigurewidth \else\determinedfigurewidth \fi\relax}% + \edef\naturalfigureheight{\the\dimexpr\ifzeropt\determinedfigureheight + \defaultfigureheight\else\determinedfigureheight\fi\relax}} + +%D Locating figures. Dilemma: we do support eps and svg parsing but drivers +%D don't always support it. + +\def\figuretypes{\c!mps,\c!pdf,\c!eps,\c!svg,\c!svg z,\c!png,\c!tif,jb2,\c!jpg} + +\def\supportedfiguretypes{\figuretypes} + +\def\checksupportedfiguretypes + {\begingroup + \global\let\supportedfiguretypes\empty + \def\docommand##1% + {\doiffileinsertionsupportedelse{##1} + {\doglobal\addtocommalist{##1}\supportedfiguretypes} + \donothing}% + \processcommacommand[\figuretypes]\docommand + \gdef\checksupportedfiguretypes{\let\figuretypes\supportedfiguretypes}% + \endgroup + \checksupportedfiguretypes} + +%D The next box is used to store the graphic. It's globally assigned. + +\newbox\foundexternalfigure + +\chardef\figurestatus\zerocount % nothing found + +\def\noffigurepages{\nofinsertpages} + +%D Variables. + +\newtoks\everyexternalfigureresets + +\def\resetfigurevariables + {\the\everyexternalfigureresets} + +%D Example usage: + +\appendtoks + \global\let\externalfigurelog\empty +\to\everyexternalfigureresets + +%D Intermediate, private + +\def\resetprivatefigurevariables + {\let \wantedfigurefull \empty + \let \wantedfigurepath \empty + \let \wantedfigurename \empty + \let \wantedfigurebase \empty + \let \wantedfiguretype \empty + \let \wantedfigurefullname \empty + \let \wantedfiguretypespec \empty + \let \wantedfiguremethod \empty + \let \wantedfigurepage \empty + \let \wantedfigureoptions \empty + \let \wantedfigureconversion\empty + \let \wantedfigureprefix \empty + \let \wantedfiguretypelist \figuretypes + \let \figurepathlist \empty + \chardef \figurestatus \zerocount + \let \expandedfigurename \empty + \global\let \analyzedfigurewidth \!!zeropoint % set by indentifying code + \global\let \analyzedfigureheight \!!zeropoint % set by indentifying code + \global\setbox\foundexternalfigure \emptybox + \def \frozenfigurestamp {\externalfigurestamp}} % no edef + +\resetprivatefigurevariables + +\appendtoks + \resetprivatefigurevariables +\to\everyexternalfigureresets + +%D Private/public. + +\def\resetpublicfigurevariables + {\let\figurewidth \!!zeropoint + \let\figureheight \!!zeropoint + \let\figurenaturalwidth \!!zeropoint + \let\figurenaturalheight \!!zeropoint + \let\figurelabel \empty + \let\figurefileoriginal \empty + \let\figurefileoptions \empty + \let\figurefilename \empty + \let\figurefiletype \empty + \let\figurefilepage \!!zerocount + \let\figurefileconversion\empty + \let\figurefileprefix \empty + \let\figurefilepath \empty + \let\figurefilecache \empty} + +\resetpublicfigurevariables + +\appendtoks + \resetpublicfigurevariables +\to\everyexternalfigureresets + +\newcounter\figurenestinglevel + +\def\pushpublicfigurevariables + {\ifcase\figurenestinglevel\else + \doshowfigurestate{variables : push}% + \globalpushmacro\figurewidth + \globalpushmacro\figureheight + \globalpushmacro\figurenaturalwidth + \globalpushmacro\figurenaturalheight + \globalpushmacro\figurelabel + \globalpushmacro\figurefileoriginal + \globalpushmacro\figurefileoptions + \globalpushmacro\figurefilename + \globalpushmacro\figurefiletype + \globalpushmacro\figurefilepage + \globalpushmacro\figurefileconversion + \globalpushmacro\figurefileprefix + \globalpushmacro\figurefilepath + \globalpushmacro\figurefilecache + \fi} + +\def\poppublicfigurevariables + {\ifcase\figurenestinglevel\else + \doshowfigurestate{variables : pop}% + \globalpopmacro\figurefilecache + \globalpopmacro\figurefilepath + \globalpopmacro\figurefileprefix + \globalpopmacro\figurefileconversion + \globalpopmacro\figurefilepage + \globalpopmacro\figurefiletype + \globalpopmacro\figurefilename + \globalpopmacro\figurefileoptions + \globalpopmacro\figurefileoriginal + \globalpopmacro\figurelabel + \globalpopmacro\figurenaturalheight + \globalpopmacro\figurenaturalwidth + \globalpopmacro\figureheight + \globalpopmacro\figurewidth + \fi} + +\def\setpublicfigurevariables % todo: type vs typespec + {\xdef\figurewidth {\the\wd\foundexternalfigure}% + \xdef\figureheight {\the\ht\foundexternalfigure}% + \xdef\figurenaturalwidth {\naturalfigurewidth}% + \xdef\figurenaturalheight {\naturalfigureheight}% + \xdef\figurelabel {\wantedfigurelabel}% + \xdef\figurefilepath {\wantedfigurepath}% + \xdef\figurefilename {\wantedfigurename}% + \xdef\figurefiletype {\wantedfiguretypespec}% + \xdef\figurefilepage {\wantedfigurepage}% + \xdef\figurefileoptions {\wantedfigureoptions}% + \xdef\figurefileconversion{\wantedfigureconversion}% + \xdef\figurefilecache {\wantedconversioncache}% + \xdef\figurefileprefix {\wantedconversionprefix}% + \xdef\figurefileoriginal {\wantedconversionname}% + \xdef\figurefullname {\wantedfigurepath/\wantedfigurename.\wantedfiguretypespec}% + \ifcase\figurestatus + \let\figurefiletype\empty % ? + \fi} + +\def\setpublicfigurescalevariables + {\edef\figurescalewidth {\finalscaleboxwidth }% + \edef\figurescaleheight {\finalscaleboxheight}% + \edef\figurescalexscale {\finalscaleboxxscale}% + \edef\figurescaleyscale {\finalscaleboxyscale}} + +\def\resetpublicfigurescalevariables + {\let\figurescalewidth \!!zeropoint + \let\figurescaleheight \!!zeropoint + \let\figurescalexscale \!!plusone + \let\figurescaleyscale \!!plusone} + +\resetpublicfigurescalevariables + +\appendtoks + \resetpublicfigurescalevariables +\to \everyexternalfigureresets + +%D The next one is for instance used in symbols. Since +%D we only need to reset some parameters, we can +%D better use the fast alternative: +%D +%D \starttyping +%D \def\resetexternalfigures +%D {\getparameters[\??ef] +%D [\c!option=,\c!maxwidth=,\c!maxheight=, +%D \c!foregroundcolor=,\c!color=, +%D %\c!conversion=,\c!prefix=,\c!splitcolor=, +%D \c!frame=\v!off,\c!background=]} +%D \stoptyping +%D +%D This one dropped the runtime of the \MAPS\ bibliography +%D from over 110 seconds down to less than 105 seconds. The +%D tremendously faster (but uglier) implementation is: + +\def\resetexternalfigures + {\let\@@efoption \empty % \let\@@efprefix\empty + \let\@@efmaxwidth \empty % \let\@@efcache \empty + \let\@@efmaxheight \empty % \let\@@efframe \v!off + \let\@@efforegroundcolor\empty + \let\@@efcolor \empty + \let\@@efconversion \empty + \let\@@efbackground \empty} + +%D The following code will move: + +\appendtoks \resetexternalfigures \to \everyoverlay +\appendtoks \resetexternalfigures \to \everybeforepagebody % not really needed +%appendtoks \resetexternalfigures \to \everysymbol + +%D We need this one for bookkeeping: + +\newcounter\forcedMPSobject % better something \every<type> + +%D Features: + +% converted -> prefix, suffix +% alternative -> other suffix +% buffer -> prefix + +%D Still messy: + +\newtoks\everyfiguretypepresets + +\def\presetfiguretypeprocessing + {\the\everyfiguretypepresets} + +\def\presetspecialfigure#1% + {\doif\wantedfiguretype{#1}% + {\let\@@efobject\v!no + \let\@@efpreset\v!no + \ifx\@@efwidth \empty\def\@@efwidth {\defaultfigurewidth }\fi + \ifx\@@efheight\empty\def\@@efheight{\defaultfigureheight}\fi}} + +\appendtoks + \presetspecialfigure\c!mov + \presetspecialfigure\c!avi +\to \everyfiguretypepresets + +\def\checkformpsfigurefiles % to be checked + {\doif\wantedfigurename{mprun} + {\doshowfigurestate{type check : forcing mps (mprun)}% + \doifnotinstring{^\bufferprefix}{^\wantedfigurename} + {\edef\wantedfigurename{\bufferprefix\wantedfigurename}}% + \let\wantedfiguremethod \c!mps + \let\wantedfiguretypespec\c!mps}% + \doifnumberelse\wantedfiguretype + {\doshowfigurestate{type check : forcing mps (number)}% + \let\wantedfiguremethod \c!mps + \let\wantedfiguretypespec\c!mps} + \donothing + \doif\wantedfiguretypespec\c!mps + {\let\wantedfiguretypelist\wantedfiguretypespec + \ifcase\EPSspecial\else\ifinobject\else + \doglobal\increment\forcedMPSobject + \edef\externalfigurestamp{\c!mps::\forcedMPSobject}% + \let\@@efobject\v!yes + \fi\fi}} + +\appendtoks + \checkformpsfigurefiles +\to \everyfiguretypepresets + +\def\checkfortexfigurefiles % to be checked (brrr: c!) / brrr: eftype + {\doifinset\wantedfiguretype{\c!tex,\c!tmp} + {\let\wantedfiguretypespec \wantedfiguretype}% + \doifinset\wantedfiguretypespec{\c!tex,\c!tmp,\v!buffer} + {\doshowfigurestate{type check : forcing tex (\wantedfiguretypespec)}% + \let\wantedfiguretypelist\wantedfiguretypespec + \let\wantedfiguremethod \c!tex + \let\@@efobject\v!no + \doifnothing\wantedfiguretype{\let\wantedfiguretype\c!tmp}% + % there can be a non buffer \jobname.tmp (made by texexec) + \doifnotinstring{^\bufferprefix}{^\wantedfigurename} + {\edef\wantedfigurename{\bufferprefix\wantedfigurename}}}} + +\appendtoks + \checkfortexfigurefiles +\to \everyfiguretypepresets + +\def\checkforunknownfigurefiles + {\doifnothing\wantedfiguretype + {\dogetcommacommandelement\plusone\from\@@eftype\to\commalistelement + \edef\wantedfigurefullname{\wantedfigurename.\commalistelement}}} + +\appendtoks + \checkforunknownfigurefiles +\to \everyfiguretypepresets + +% note * : this is needed because reusable graphics +% combined with funny page aspect aspect ratio's can lead to +% strange side effects of preceding factor=max specs. This +% surfaced in the metafun manual, where the two side by +% side clipped cow heads [the second one was a reused object] +% where the second one inherited some characteristics from +% the factor=max one some 30 pages back. Sigh. + +\chardef\splitexternalfigure\zerocount % 0 nosplit 1 split/yes 2 split/no + +\def\checkfigurecolorsettings + {% seperation, seldom used + \doifseparatingcolorselse + {\let\@@efforegroundcolor\empty + \doifelsenothing\@@efsplit + {\chardef\splitexternalfigure\zerocount} + {\doifcolorchannelelse\@@efsplit + {\let\@@efobject\v!no % why? + \chardef\splitexternalfigure\plusone} + {\chardef\splitexternalfigure\plustwo}}} + {\chardef\splitexternalfigure\zerocount}% + % fake color in gray bitmaps, assumes that + % a transparent color is used + \doifsomething\@@efforegroundcolor + {\def\@@efbackground{\v!foreground,\v!color}% + \def\@@efbackgroundcolor{\@@efforegroundcolor}}% + \doifsomething\@@efcolor + {\doifcolorelse\@@efcolor + {\checkpredefinedcolor[\@@efcolor]% + \doregisterfigurecolor\@@efcolor}}% + \donothing} + +\def\setextrafiguredriveroptions + {\let\@@DriverImageOptions\empty + \doifsomething\@@efpage {\addtocommalist\@@efpage \@@DriverImageOptions}% + \doif \@@efpreview \v!yes{\addtocommalist\v!preview \@@DriverImageOptions}% + \doif \@@efcontrols\v!yes{\addtocommalist\v!controls\@@DriverImageOptions}% + \doif \@@efrepeat \v!yes{\addtocommalist\v!repeat \@@DriverImageOptions}% + \doifinsetelse\@@efsize{mediabox,cropbox,artbox,bleedbox,trimbox} + {\let \@@DriverImageBox \@@efsize}% + {\doifinsetelse\@@efsize{media,crop,art,bleed,trim} + {\edef\@@DriverImageBox{\@@efsize box}}% + {\let \@@DriverImageBox \empty}}% + \let\wantedfigureoptions\@@DriverImageOptions} + +\def\checkiffigureobjectpresent + {\doifnot\@@efobject\v!no + {\doifobjectssupportedelse + {\doifobjectfoundelse{FIG}\externalfigurestamp + {\doshowfigurestate{object found : \externalfigurestamp}% + \getobjectdimensions{FIG}\externalfigurestamp + \edef\frozenfigurestamp{\externalfigurestamp}% + \xdef\analyzedfigurewidth {\the\dimexpr\objectwidth \relax}% + \xdef\analyzedfigureheight{\the\dimexpr\objectheight\relax}% + \setanalyzedfiguredimensions\plusone} + {\doshowfigurestate{unknown object: \externalfigurestamp}}} + {}}} + +\def\checkifknownfigureobjectpresent + {\ifx\wantedfiguretype\empty + \let\savedwantedfiguretype\wantedfiguretype + \def\docommand##1% + {\ifcase\figurestatus + \edef\wantedfiguretype{##1}% + \checkiffigureobjectpresent + \fi}% + \processcommacommand[\figuretypes]\docommand + \ifcase\figurestatus + \let\wantedfiguretype\savedwantedfiguretype + \fi + \fi} + +\def\checkforfigurefile + {\ifcase\figurestatus + \ifconditional\externalfigureflush + \analyzefigurefiles + \fi + \fi} + +\def\externalfigurestamp % needs \edef'd macros! + {\ifx\wantedfigurepath\empty\else + -\wantedfigurepath + \fi + \wantedfigurename + \ifx\wantedfiguretype\empty\else + \ifx\wantedfiguretype\s!unknown\else + -\wantedfiguretype + \fi + \fi + \ifx\wantedfiguretypespec\empty\else + \ifx\wantedfiguretypespec\s!unknown\else + \ifx\wantedfiguretypespec\wantedfiguretype\else + -\wantedfiguretypespec + \fi + \fi + \fi + \ifnum\wantedfigurepage>\zeropoint + -\wantedfigurepage + \fi} + +\def\checkfigurerenderingoptions + {\ifcase\figurestatus + \let\@@efframe\v!on + \fi + \doif\@@exoption\v!frame + {\let\@@efframe\v!on}% + \doif\@@exoption\v!empty + {\skipexternalfigurestrue + \let\@@efframe\v!off}} + +\newtoks\externalfigurepostprocessors + +\def\resetfigureusersettings + {\let\@@eftype \s!unknown \let\@@efmethod \empty \let\@@efpreset\v!yes + \let\@@eflabel \empty \let\@@efsize \empty \let\@@efpage \!!zerocount + \let\@@efobject \@@exobject \let\@@efdisplay \empty + \let\@@efsplit \empty \let\@@efcolor \empty \let\@@efsymbol\v!no + \let\@@efcontrols \v!no \let\@@efpreview \v!no \let\@@efrepeat\v!no + \let\@@efhfactor \empty \let\@@efwfactor \empty \let\@@effactor\empty + \let\@@efmaxwidth \@@exmaxwidth \let\@@efmaxheight\@@exmaxheight + \let\@@efxscale \empty \let\@@efyscale \empty \let\@@efscale \empty + \let\@@efsx \!!plusone \let\@@efsy \!!plusone + \let\@@efwidth \empty \let\@@efheight \empty + \let\@@eflines \empty \let\@@efgrid \empty + \let\@@efconversion\@@exconversion \let\@@efprefix \@@exprefix \let\@@efcache \@@excache} + +%D Types and Methods are a bit history. Anyhow, user scan use the +%D type to force the handler. So, what to do with the method. We can +%D use that one to force a handler with a given suffix, so when no +%D type is given, but a suffix is part of the name, the method will +%D determine the handler. + +\def\checkfigureusersettings + {\doif\@@efreset\v!yes\resetexternalfigures + \doifelsenothing\@@eflabel + {\doifnothing\wantedfigurelabel{\let\wantedfigurelabel\wantedfigurename}}% + {\let\wantedfigurelabel\@@eflabel}% + \doifsomething\@@eftype + {\doifnot\@@eftype\s!unknown + {\edef\wantedfiguretypespec{\@@eftype}% + \let\wantedfiguremethod\wantedfiguretypespec}}% + \doifnothing\wantedfigurepage % can be set by plug in + {\let\wantedfigurepage\@@efpage}% + \doif\wantedfigurepage\empty + {\let\wantedfigurepage\!!zerocount}% 0 is signal ! + \doifsomething\@@efmethod % rather untested misusage of the remapper + {\doifsomething\wantedfiguretype + {\definegraphictypesynonym[\wantedfiguretype][\@@method]}}} + +% #1 is now obsolete + +\def\calculateexternalfigure[#1][#2][#3][#4][#5][#6]% \cmd label filename parent_id preset current + {\doshowfigurestate{begin}% + \dontcomplain + % let's limit the search, which means that e.g. svg has to be given explicitly + \checksupportedfiguretypes + % recently added; we presume local use + \restorecatcodes + % collected resets (token list) + \resetfigurevariables +\resetwantedconversionvariables % new here + % analyze filename and set wanted variables + \analyzefigurefilename{#3}{#2}% + \doanalyzefiguredimensionsfromfile + % handle user settings + \resetfigureusersettings + \dosetefparameters{#4}{#5}{#6}% + \checkfigureusersettings + \checkfigurecolorsettings + % adapt settings based on suffix and/or type + \presetfiguretypeprocessing + % now we really start + \checkiffigureobjectpresent % first guess, we may not yet know the typespec + \checkifknownfigureobjectpresent + \checkforfigurefilepresence + \checkiffigureobjectpresent % to be sure, in case we now know the typespec + \checkfigurerenderingoptions % was later, moved here + \checknaturalfiguredimensions % inherit from global values and/or fallbacks + % by now we know what we're dealing with (put in box and scale) + \setextrafiguredriveroptions + \prepackageexternalfigureobject + % set public variables in case postprocessing needs them + \pushpublicfigurevariables + \setpublicfigurevariables + \setpublicfigureconversionvariables + \setpublicfigurescalevariables + % package final graphic, only now we can apply backgrounds and such + \doglobal\increment\figurenestinglevel + \finishexternalfigure + \doglobal\decrement\figurenestinglevel + % restore variables + \poppublicfigurevariables + \doshowfigurestate{end}} + +\def\checkforfigurefilepresence + {\checkforconvertedfigure + \checkforfigurefile} + +%D Figure objects. + +\def\setfigureobject + {\doshowfigurestate{object set : \externalfigurestamp}% + \setobject{FIG}\externalfigurestamp} + +% \def\getfigureobject +% {\doshowfigurestate{object used : \externalfigurestamp}% +% \getobject{FIG}\externalfigurestamp} + +\def\getfigureobject + {\doshowfigurestate{object used : \frozenfigurestamp}% + \getobject{FIG}\frozenfigurestamp} + +\def\prepackageexternalfigureobject + {\ifcase\figurestatus + \doshowfiguremessage1\expandedfigurename + \doshowfigurestate{state : figure not found (\expandedfigurename)}% + \global\setbox\foundexternalfigure\naturalvbox + {\doscalebox\??ef{\blackrule[\c!width=\naturalfigurewidth,\c!height=\naturalfigureheight]}}% + \xdef\noffigurepages{0}% + \or + \doshowfiguremessage8\expandedfigurename + \doshowfigurestate{state : reusing existing figure}% + \global\setbox\foundexternalfigure\naturalvbox + {\doscalebox\??ef{\dowithfigure{\getfigureobject}}}% + \xdef\noffigurepages{\number\getvalue{\externalfigurestamp\c!n}}% + \or + \doshowfiguremessage2\expandedfigurename + \doshowfigurestate{state : using special figure}% + \setbox\scratchbox\naturalvbox % make a dummy + {\doscalebox\??ef{\blackrule[\c!width=\naturalfigurewidth,\c!height=\naturalfigureheight]}}% + \global\setbox\foundexternalfigure\naturalvbox to \finalscaleboxheight + {\vfill + \hsize\finalscaleboxwidth + \dowithfigure{\insertscaledfiguredriverdata}}% + \xdef\noffigurepages{\number\nofinsertpages}% + \else + \ifdim\naturalfigurewidth>\zeropoint + \ifnum\figurestatus>\!!ten\relax + \doshowfiguremessage3\expandedfigurename + \else + \doshowfiguremessage4\expandedfigurename + \fi + \else + \doshowfiguremessage5\expandedfigurename + \fi + \doshowfigurestate{state : using found figure}% 3=self 4=rlx + \doifelse\@@efobject\v!no + {\donefalse} + {\doifobjectssupportedelse\donetrue\donefalse}% + \ifdone + % make an object and use it + \packageexternalfigureobject + \setfigureobject\vbox{\box\foundexternalfigure}% + \setxvalue{\externalfigurestamp\c!n}{\number\nofinsertpages}% + \global\setbox\foundexternalfigure\naturalvbox + {\doscalebox\??ef{\dowithfigure{\getfigureobject}}}% + \xdef\noffigurepages{\number\getvalue{\externalfigurestamp\c!n}}% + \else + % maybe a tex figure + \global\setbox\foundexternalfigure\naturalvbox + {\doscalebox\??ef{\dowithfigure{\box\foundexternalfigure}}}% + \xdef\noffigurepages{\number\nofinsertpages}% + \fi + \fi + \global\wd\foundexternalfigure\finalscaleboxwidth + \global\ht\foundexternalfigure\finalscaleboxheight + \global\let\lastfigureobjectname\externalfigurestamp + \doresetobjects} % clean up driver left overs + +\def\packageexternalfigureobject + {\global\setbox\foundexternalfigure\vbox to \naturalfigureheight + {\vfill + \ifdim\wd\foundexternalfigure=\zeropoint + \setextrafiguredriveroptions + \insertunscaledfiguredriverdata + \else\ifskipexternalfigures + \ruledhbox{\backgroundline[\@@efsplitcolor]{\fakebox\foundexternalfigure}}% + \else + \box\foundexternalfigure + \fi\fi}% + \wd\foundexternalfigure\naturalfigurewidth + \ht\foundexternalfigure\naturalfigureheight} + +\def\finishexternalfigure % here we use \figurevariables + {\global\setbox\foundexternalfigure\vbox + {\forgetall + \ifcase\figurestatus + \resetsystemmode\v!figure % todo, also: \v!resource + \else + \setsystemmode \v!figure % todo, also: \v!resource + \fi + \ifconditional\externalfigureflush + \ifconditional\externalfigurelevel % probably background + \ifskipexternalfigures + % nothing + \fakebox\foundexternalfigure + \else\ifcase\figurestatus + % nothing + \else\ifnum\splitexternalfigure=\plustwo\else + \the\externalfigurepostprocessors + \box\foundexternalfigure + \fi\fi\fi + \else + \iftrialtypesetting \else \feedbackexternalfigure \fi + \settrue\externalfigurelevel + \ifskipexternalfigures + \ifcase\figurestatus + \externalfigurereplacement\figurelabel\figurefilename{unknown}% + \else + \externalfigurereplacement\figurelabel\figurefullname{skipped}% + \fi + \else\ifcase\figurestatus + \externalfigurereplacement\figurelabel\figurefilename{unknown}% + \else\ifnum\splitexternalfigure=\plustwo + \backgroundline[\@@efsplitcolor]{\fakebox\foundexternalfigure}% + \else + \the\externalfigurepostprocessors + \doifelse\@@efreset\v!yes + {\wd\foundexternalfigure\figurewidth + \ht\foundexternalfigure\figureheight + \dp\foundexternalfigure\zeropoint + \box\foundexternalfigure} + {\localframed % should also be applied to high res ! + [\??ef] + [\c!offset=\v!overlay, + \c!width=\figurewidth, + \c!height=\figureheight] + {\vfilll + \ifnum\splitexternalfigure=\plusone + % hm, eigenlijk in dit geval achtergrondkleur + \hidesplitcolorfalse % really needed + \backgroundline[\@@efsplitcolor]{\box\foundexternalfigure}% + \else % = 0, no split mode + \box\foundexternalfigure + \fi}}% + \fi\fi\fi + \fi + \else + % maybe also \the\externalfigurepostprocessors + \iftrialtypesetting \else \feedbackexternalfigure \fi + \fi}} + +\def\insertfiguredriverdata#1#2% + {\lowercasestring\wantedfiguretypespec\to\lcwantedfiguretypespec + \lowercasestring\wantedfiguremethod \to\lcwantedfiguremethod + \edef\@@DriverImageWidth {\the\dimexpr#1\relax}% + \edef\@@DriverImageHeight{\the\dimexpr#2\relax}% + \let \@@DriverImageFile \wantedfigurefullname + \let \@@DriverImageType \lcwantedfiguretypespec + \let \@@DriverImageMethod \lcwantedfiguremethod + \let \@@DriverImageLabel \wantedfigurelabel + \let \@@DriverImagePage \wantedfigurepage + \doinsertfile} + +\def\insertunscaledfiguredriverdata + {\insertfiguredriverdata\naturalfigurewidth\naturalfigureheight} + +\def\insertscaledfiguredriverdata + {\insertfiguredriverdata\finalscaleboxwidth\finalscaleboxheight} + +\ifx\externalfigurereplacement\undefined\let\externalfigurereplacement\gobblethreearguments\fi +\ifx\externalfigureplaceholder\undefined\let\externalfigureplaceholder\gobblethreearguments\fi + +\def\registerexternalfigure % no placement, handy for preprocessing + {\dotripleempty\doregisterexternalfigure} + +\def\doregisterexternalfigure[#1][#2][#3]% + {\bgroup + \setfalse\externalfigureflush + \externalfigure[#1][#2][#3]% or \doexternalfigure + \egroup} + +\let\feedbackexternalfigure\relax % \gobblefourarguments +\let\dowithfigure \relax + +%D Conversion stuff: + +\newcount\nofconversionfigures + +\def\resetwantedconversionvariables + {\let\wantedconversionpath \empty % these point to the to be converted graphic + \let\wantedconversionname \empty + \let\wantedconversiontype \empty + \let\wantedconversioncache \empty + \let\wantedconversionprefix\empty} + +\resetwantedconversionvariables + +\def\checkforconvertedfigure + {\ifcase\figurestatus + \resetwantedconversionvariables + \doifsomething\@@efconversion + {\global\advance\nofconversionfigures\plusone + \doshowfigurestate{n-of-conversions : \number\nofconversionfigures}% + \edef\wantedfigureconversion{\@@efconversion}% + \edef\wantedconversioncache {\@@efcache}% + \edef\wantedconversionprefix{\@@efprefix}% + \doshowfigurestate{checking paths : \figurepathlist}% + \processcommacommand[\figurepathlist]\dolocatefigureconversionfile + \ifcase\figurestatus + \doshowfigurestate{remark : no conversion file found}% + \else + \doshowfigurestate{remark : conversion file found}% + \chardef\figurestatus\zerocount + \fi + \let\wantedconversionname\wantedfigurename + \edef\wantedfigurename{\wantedconversionprefix\wantedfigurename}% + \ifx\wantedconversioncache\empty + \let \wantedfigurepath \wantedconversionpath + \else + \checkfilename\@@efcache + \ifnum\kindoffile=\plusone + \let\wantedfigurepath\@@efcache % root related path + \else % brrr + \edef\wantedfigurepath{\@@efcache,\wantedconversionpath/\@@efcache}% in case of explicit paths, what a mess + \fi + \fi + \let\wantedfiguretype \empty + \let\wantedfiguretypelist\figuretypes % hm, why needed + \ifx\figurepathlist\empty + \let\figurepathlist\wantedfigurepath + \else + \edef\figurepathlist{\wantedfigurepath,\figurepathlist}% + \fi + \doshowfigurestate{conversion path : \wantedconversionpath}% + \doshowfigurestate{conversion name : \wantedconversionname}}% + \doshowfigurestate{new figure path : \wantedfigurepath}% + \fi} + +\def\dolocatefigureconversionfile#1% + {\ifcase\figurestatus + \setwantedfigurefullname{#1}\wantedfigurename\wantedfiguretype + \doshowfigurestate{locating original : \wantedfigurefullname}% + \doiffile\wantedfigurefullname + {\def\wantedconversionpath{#1}% + \let\wantedconversionname\wantedfigurename + \let\wantedconversiontype\wantedfiguretype + \chardef\figurestatus\plusfive}% + \fi} + +\def\setpublicfigureconversionvariables % also prefix, cache + {\doifsomething\@@efconversion + {\doifmode{\systemmodeprefix\v!first} + {\let\figurefilepath\wantedconversionpath + \let\figurefilename\wantedconversionname + \let\figurefiletype\wantedconversiontype + \let\figurefileconversion\wantedfigureconversion + \def\figurefullname + {\ifx\wantedconversionpath\empty\else\wantedconversionpath/\fi + \wantedconversionname + \ifx\wantedconversiontype\empty\else.\wantedconversiontype\fi}}}} + +%D In \PDF\ one can specify an alternative graphic. This means +%D that for instance a low resolution graphic can be used for +%D viewing and a high res one for printing. Because this +%D feature depends much on the driver, here we only take care +%D of perparations. It is up to the special driver to handle +%D the inclusion. The driver routines can change the content of +%D box \type {\foundexternalfigure} if suitable. +%D +%D One complication is for instance that an alternative may +%D not itself have an alternative, and these kind of situations +%D are best handled by the driver. + +\let\lastfigureobjectname\empty + +%D The next macro does not work well with figure bases yet. + +\def\calculateexternalscreenfigure[#1][#2][#3][#4][#5][#6]% + {\ifx\@@efdisplay\empty\else + \doifnot\@@efobject\v!no + {\doifobjectssupportedelse + {\doifspecialavailableelse\doregisterfigure + {\doshowfigurestate{screen alternative : start}% + \bgroup + \dosetefparameters{#4}{#5}{#6}% + \doregisterfigure{FIG}{\lastfigureobjectname}% + \let\@@ef@@scherm\@@efdisplay + \calculateexternalfigure[#1][\@@ef@@scherm][\@@ef@@scherm][#4,\c!display=][#5][#6]% + \doshowfigurestate{screen alternative : stop}% + \egroup} + {}} + {}}% + \fi} + +\def\getfiguredimensions + {\dodoubleempty\dogetfiguredimensions} + +\def\dogetfiguredimensions[#1][#2]% + {{\let\immediate\relax % very dirty but prevents flushing, will change + \setbox0\hbox{\externalfigure[#1][#2,\c!display=,\c!object=\v!no]}}} + +% use the next one when the object must be forgotten (xobj +% nums can migrate to the next object; maybe it should +% always be done; todo .... + +\def\getfiguredimensionsonly + {\dodoubleempty\dogetfiguredimensionsonly} + +\def\dogetfiguredimensionsonly[#1][#2]% + {\dogetfiguredimensions[#1][#2]% + \doresetobjects} + +\def\doiffigureelse#1% + {\getfiguredimensions[#1]% so data is available ! + \ifdim\analyzedfigurewidth=\zeropoint % todo: \figurestatus + \expandafter\secondoftwoarguments + \else + \expandafter\firstoftwoarguments + \fi} + +%D Size determination. +%D +%D An analyzer must set the following dimensions (global macros): +%D +%D \starttyping +%D \analyzedfigurewidth +%D \analyzedfigureheight +%D \stoptyping +%D +%D And afterwards, when succeeded, call: +%D +%D \starttyping +%D \setanalyzedfiguredimensions{number>=10} +%D \stoptyping +%D +%D Numbers upto 9 are reserved for special purposes: +%D +%D \starttabulate +%D \NC 0 \NC not found \NC \NR +%D \NC 1 \NC object (will be reused) \NC \NR +%D \NC 2 \NC found but no dimensions (e.g. special annotation) \NC \NR +%D \stoptabulate + +\let\doanalyzefiguredimensionsfromfile\relax % hook for figuredatabase +\let\doanalyzefiguredimensionsinternal\relax +\let\doanalyzefiguredimensionsexternal\relax % hook for rli support (see later) +\let\doanalyzefiguredimensionsfallback\relax + +\def\doanalyzefiguredimensions + {\lowercasestring\wantedfiguretypespec\to\lcwantedfiguretypespec + \doiffileinsertionsupportedelse\lcwantedfiguretypespec + {\doiffileelse\wantedfigurefullname + {\doshowfigurestate{analyzing : \wantedfigurefullname}% + \doanalyzefiguredimensionsinternal + \doanalyzefiguredimensionsexternal + \doanalyzefiguredimensionsfallback} + {\doshowfigurestate{not found : \wantedfigurefullname}}} + {}} + +\def\setanalyzedfiguredimensions#1% + {\ifdim\analyzedfigurewidth>\zeropoint + \ifdim\analyzedfigureheight>\zeropoint + \determinedfigurewidth \analyzedfigurewidth + \determinedfigureheight\analyzedfigureheight + \chardef\figurestatus #1\relax + \doshowfigurestate{dimensions : + \the\dimexpr\analyzedfigurewidth\relax\space x\space + \the\dimexpr\analyzedfigureheight\relax}% + \else + \determinedfigurewidth \zeropoint + \determinedfigureheight\zeropoint + \chardef\figurestatus \zerocount + \fi + \else + \determinedfigurewidth \zeropoint + \determinedfigureheight\zeropoint + \chardef\figurestatus \zerocount + \fi} + +%D We can remap types. This is to be dealt with in the driver files. + +\def\definegraphictypesynonym + {\dodoubleargument\dodefinegraphictypesynonym} + +\def\dodefinegraphictypesynonym[#1][#2]% + {\setvalue{\??ef:\??ex:#1}{#2}} + +\def\truegraphictype#1% + {\ifcsname\??ef:\??ex:#1\endcsname + \expandafter\truegraphictype\csname\??ef:\??ex:#1\endcsname\else#1% + \fi} + +\definegraphictypesynonym[epdf] [pdf] +\definegraphictypesynonym[jpeg] [jpg] +\definegraphictypesynonym[jp2] [jpg] +\definegraphictypesynonym[jbig] [jb2] +\definegraphictypesynonym[jbig2][jb2] +\definegraphictypesynonym[jbg] [jb2] + +%D The self method (mostly used) uses the driver. + +% todo: when zero width mps, ok +% +% analyzer must set the analyzed dimensions + +\def\doanalyzefiguredimensionsinternal + {\ifcase\figurestatus + \lowercasestring\wantedfiguretypespec\to\lcwantedfiguretypespec + \let\@@DriverImageFile \wantedfigurefullname + \let\@@DriverImagePage \wantedfigurepage + \let\@@DriverImageType\lcwantedfiguretypespec + % use internal when available, otherwise try driver (\dogetfiguresize) + \executeifdefined{dogetfiguresize\@@DriverImageType}\dogetfiguresize + \setanalyzedfiguredimensions\!!ten + \fi} + +%D The tex method. + +\def\dogetfiguresizetex + {\ifcase\figurestatus + \global\setbox\foundexternalfigure\vbox + {\insidefloattrue + \forgetall + \blank[\v!disable]% niet meer weg ! + \startreadingfile + \readfile\wantedfigurefullname \donothing \donothing + \stopreadingfile + \endgraf + \removelastskip}% + \global\setbox\foundexternalfigure\hbox + {\raise\dp\foundexternalfigure\box\foundexternalfigure}% + \xdef\analyzedfigurewidth {\the\wd\foundexternalfigure}% + \xdef\analyzedfigureheight{\the\ht\foundexternalfigure}% + \fi} + +\let\dogetfiguresizetmp \dogetfiguresizetex +\let\dogetfiguresizebuffer\dogetfiguresizetex + +%D The eps, mps and svg files are read directly. + +\def\dogetfiguresizeeps + {\dogetEPSboundingbox\wantedfigurefullname\!!widtha\!!heighta\!!widthb\!!heightb + \xdef\analyzedfigurewidth {\the\!!widthb}% + \xdef\analyzedfigureheight{\the\!!heightb}} + +\let\dogetfiguresizemps\dogetfiguresizeeps + +\def\dogetfiguresizesvg + {\doifinset\wantedfiguretypespec\c!svg + {\startnointerference + \startXMLignore + \defineXMLcommand[svg][width=100,height=75] + {\doifdimensionelse{\XMLop{width}} + {\xdef\analyzedfigurewidth {\the\dimexpr\XMLop{width}\relax}} + {\xdef\analyzedfigurewidth {\the\dimexpr\XMLop{width}\onebasepoint\relax}}% + \doifdimensionelse{\XMLop{height}} + {\xdef\analyzedfigurewidth {\the\dimexpr\XMLop{height}\relax}} + {\xdef\analyzedfigurewidth {\the\dimexpr\XMLop{height}\onebasepoint\relax}}% + \endinput}% + \processXMLfilegrouped\wantedfigurefullname + \stopXMLignore + \stopnointerference}} + +%D Do some checking on the filename. + +\newconditional \figurefileisqualified + +\def\setfigurepathlist + {\let\figurepathlist\empty + \expanded{\doifinset{\v!global }{\@@exlocation}} + {\let\figurepathlist\@@exdirectory}% + \expanded{\doifinset{\v!local }{\@@exlocation}} + {\prependtocommalist\f!currentpath\figurepathlist}% + \expanded{\doifinset{\v!default}{\@@exlocation}} + {\appendtocommalist\defaultfigurepathsignal\figurepathlist}} + +% The combined path and qualified path hack is dedicated to Onno Tomson, +% our partner in fighting inconsistent and faulty image specifications in +% user files. + +\def\analyzefigurefilename#1#2% + {\sanitizefilename#1\to\expandedfigurename + \expanded{\checkfilename{\expandedfigurename}}% + \ifcase\kindoffile + \splitfigurefilename + \ifcase\splitoffkind + \let\wantedfigurepath\empty % no . either + \setfigurepathlist + \setfalse\figurefileisqualified + \else + \splitfigurefilename + % will become splitoffkind 3 ! ! ! ! + \setfalse\figurefileisqualified + \doifinstring{$$/}{$$\wantedfigurepath}{\settrue\figurefileisqualified}% + \doifinstring {:} {\wantedfigurepath}{\settrue\figurefileisqualified}% + \ifconditional\figurefileisqualified + \let\figurepathlist\wantedfigurepath + \let\wantedfigurepath\empty + \settrue\figurefileisqualified + \else + \let\figurepathlist\@@exdirectory + \let\oldfigurepathlist\figurepathlist + \let\figurepathlist\wantedfigurepath + \def\docommand##1{\edef\figurepathlist{\figurepathlist,##1/\wantedfigurepath}}% + \processcommacommand[\oldfigurepathlist]\docommand + \fi + \fi + \else % fully qualified + \splitfigurefilename + \let\wantedfigurepath\empty + \settrue\figurefileisqualified + \fi + \ifx\figurepathlist\empty + \let\figurepathlist\defaultfigurepathsignal % will prepend no path + \fi + \doifelsenothing\wantedfiguretype + {\doifparentfileelse\wantedfigurename + {\@EA\removefromcommalist\@EA{\jobsuffix }\wantedfiguretypelist + \@EA\removefromcommalist\@EA{\jobfilesuffix}\wantedfiguretypelist} + {}} + {\let\wantedfiguretypelist\empty + \let\wantedfiguretypespec\wantedfiguretype}% + \edef\wantedfigurelabel{#2}% + \doshowfigurestate{type check : \ifx\wantedfiguretypelist\empty forced type \wantedfiguretypespec\else\wantedfiguretypelist\fi}% + \doshowfigurestate{file specs : \wantedfigurefull\space [\wantedfigurepath] [\wantedfigurename] [\wantedfiguretype]}% + \doshowfigurestate{file type : \ifconditional\figurefileisqualified qualified\else simple\fi}} + +\def\setwantedfigurefullname#1#2#3% path name spec + {\ifx\wantedfiguremethod\empty + % the either explicit or gambled typespec determines the method + \edef\wantedfiguretypespec{#3}% + \doifelse{#1}\defaultfigurepathsignal + {\edef\wantedfigurefullname {#2.\wantedfiguretypespec}} + {\edef\wantedfigurefullname{#1/#2.\wantedfiguretypespec}}% + \else\ifx\wantedfiguretype\empty % + % the typespec (probably the same as the method) determines the suffix + \doifelse{#1}\defaultfigurepathsignal + {\edef\wantedfigurefullname {#2.\wantedfiguretypespec}} + {\edef\wantedfigurefullname{#1/#2.\wantedfiguretypespec}}% + \let\wantedfiguretypespec\wantedfiguremethod + \else + % the given suffix is used + \let\wantedfiguretypespec\wantedfiguremethod + \doifelse{#1}\defaultfigurepathsignal + {\edef\wantedfigurefullname {#2.\wantedfiguretype}} + {\edef\wantedfigurefullname{#1/#2.\wantedfiguretype}}% + \fi\fi} + +\def\splitfigurefilename + {\splitfilename\expandedfigurename + \let\wantedfigurefull\splitofffull + \let\wantedfigurepath\splitoffpath + \let\wantedfigurename\splitoffname + \let\wantedfigurebase\splitoffbase + \let\wantedfiguretype\splitofftype} + +\def\analyzefigurefiles + {\ifconditional\figurefileisqualified + \ifx\wantedfiguretype\empty + \doshowfigurestate{locating : unknown type}% + \doanalyzeunknownfiguretype + \else + % this file or none + \doshowfigurestate{locating : known type}% + \doanalyzequalifiedfigure + \fi + \else + \ifx\wantedfiguretype\empty + % locate best fit / check support + \doshowfigurestate{locating : best fit}% + \doanalyzeunknownfiguretype + \else + % only check on paths + \doshowfigurestate{locating : known types}% + \doanalyzeknownfiguretype + \fi + \fi} + +\def\doanalyzequalifiedfigure + {\let\wantedfigurefullname\wantedfigurefull + \let\wantedfiguretypespec\wantedfiguretype + \doshowfigurestate{forced type : \wantedfiguretype}% + \doshowfigurestate{identifying : \wantedfigurefullname}% + \doanalyzefiguredimensions} + +\def\doanalyzeknownfiguretype + {\doshowfigurestate{using paths : \figurepathlist}% + \doshowfigurestate{known type : \wantedfiguretype}% + \doshowfigurestate{identifying : \wantedfigurename}% + \let\wantedfiguretypespec\wantedfiguretype + \processcommacommand[\figurepathlist]\dodoanalyzeknownfiguretype} + +\def\dodoanalyzeknownfiguretype#1% path + {\ifcase\figurestatus + \setwantedfigurefullname{#1}\wantedfigurename\wantedfiguretype + \doanalyzefiguredimensions + \fi} + +\def\doanalyzeunknownfiguretype + {\doshowfigurestate{using paths : \figurepathlist}% + \doshowfigurestate{using types : \wantedfiguretypelist}% + \doshowfigurestate{identifying : \wantedfigurename}% + \processcommacommand[\wantedfiguretypelist]\dodoanalyzeunknownfiguretype} + +\def\dodoanalyzeunknownfiguretype#1% + {\processcommacommand[\figurepathlist]{\dododoanalyzeunknownfiguretype{#1}}} + +\def\dododoanalyzeunknownfiguretype#1#2% type path + {\ifcase\figurestatus + \setwantedfigurefullname{#2}\wantedfigurename{#1}% path spec + \doanalyzefiguredimensions + \fi} + +%D Some files, take for instance movies, cannot easilly be +%D parsed on dimensions, that is, not yet. Although the current +%D mechanism has no problems with this, as long as the user +%D specified width and height reflect the right aspect ratio. +%D Nevertheless, when one does not want any scanning done, one +%D can disable \type{preset}. When no preset is needed, we only +%D locate the file. + +\def\doanalyzefiguredimensionsfallback + {\ifcase\figurestatus + \doshowfigurestate{warning : assuming adaptive figure}% + \xdef\analyzedfigurewidth {\the\dimexpr\@@efwidth +\zeropoint\relax}% + \xdef\analyzedfigureheight{\the\dimexpr\@@efheight+\zeropoint\relax}% + \setanalyzedfiguredimensions\plustwo + \fi} + +%D This is \MKII\ only and comes from cont-new (maybe used in a project). + +% maybe to be integrated (option=...) + +\def\directexternalfigure + {\dodoubleempty\dodirectexternalfigure} + +\def\dodirectexternalfigure[#1][#2]% + {\bgroup + \getparameters[\??ef][\c!type=\splitofftype,\c!page=1,#2]% + \sanitizefilename#1\to\expandedfigurename + \splitfilename\expandedfigurename + \let\@@DriverImageWidth \!!zeropoint + \let\@@DriverImageHeight \!!zeropoint + \let\@@DriverImageFile \splitofffull + \let\@@DriverImageType \@@eftype + \let\@@DriverImageMethod \@@eftype + \let\@@DriverImageLabel \empty + \let\@@DriverImagePage \@@efpage + \doinsertfile + \egroup} + +% \directexternalfigure[cow.pdf] + +\protect \endinput diff --git a/tex/context/base/grph-inc.mkiv b/tex/context/base/grph-inc.mkiv new file mode 100644 index 000000000..16ee1097a --- /dev/null +++ b/tex/context/base/grph-inc.mkiv @@ -0,0 +1,433 @@ +%D \module +%D [ file=grph-inc, % moved from core-fig +%D version=2006.08.26, % overhaul of 1997.03.31 +%D title=\CONTEXT\ Graphic 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 Graphic Macros / Figure Inclusion} + +%D todo: +%D +%D - color conversion +%D - alternative images +%D - a few more obscure things + +\registerctxluafile{grph-inc}{1.001} +\registerctxluafile{grph-fil}{1.001} +\registerctxluafile{grph-u3d}{1.001} % this will change +\registerctxluafile{grph-swf}{1.001} % this will change + +\unprotect + +%D The following registers are used (if only to be downward compatible). + +\newbox \foundexternalfigure +\newif \ifskipexternalfigures +\newtoks \everyexternalfigureresets +\newtoks \everyexternalfigurechecks +\newtoks \externalfigurepostprocessors + +\def\resetfigurevariables {\the\everyexternalfigureresets} +\def\checkfigurevariables {\the\everyexternalfigurechecks} + +%D Historic feature: + +\appendtoks + \global\let\externalfigurelog\empty +\to \everyexternalfigureresets + +\let\runutilityfiletrue \relax \let\runutilityfilefalse \relax +\let\consultutilityfiletrue\relax \let\consultutilityfilefalse\relax + +%D You can register additional suffixes with the following command: +%D +%D \starttyping +%D \definegraphictypesynonym[jbig] [jb2] +%D \definegraphictypesynonym[jbig2][jb2] +%D \definegraphictypesynonym[jbg] [jb2] +%D \stoptyping + +\unexpanded\def\definegraphictypesynonym + {\dodoubleargument\dodefinegraphictypesynonym} + +\def\dodefinegraphictypesynonym[#1][#2]% + {\ctxlua{figures.registersuffix("#1","#2")}} + +%D Additional paths can be installed with the regular setup command. The next +%D macro picks up the list. + +\def\setfigurepathlist + {\ctxlua{figures.setpaths("\@@exlocation",\!!bs\@@exdirectory\!!es)}} + +%D Variables: + +\def\defaultfigurewidth {8\lineheight} +\def\defaultfigureheight {6\lineheight} + +\def\figurestatus {\numexpr\ctxlua{figures.tprint("status","status",0)}\relax} % number: 0 = not found +\def\figurewidth {\ctxlua{figures.tprint("status","width",0)}sp} +\def\figureheight {\ctxlua{figures.tprint("status","height",0)}sp} +\def\figurexscale {\ctxlua{figures.tprint("status","xscale",1)}} +\def\figureyscale {\ctxlua{figures.tprint("status","yscale",1)}} + +\def\figurelabel {\ctxlua{figures.tprint("request","label")}} +\def\figurefileoriginal {\ctxlua{figures.tprint("request","name")}} +\def\figurefilepage {\ctxlua{figures.tprint("request","page",1)}} +\def\figurefileoptions {\ctxlua{figures.tprint("request","options")}} +\def\figurefileconversion{\ctxlua{figures.tprint("request","conversion")}} +\def\figurefilecache {\ctxlua{figures.tprint("request","cache")}} +\def\figurefileprefix {\ctxlua{figures.tprint("request","prefix")}} + +\def\figurenaturalwidth {\ctxlua{figures.tprint("used","width", \number\dimexpr\defaultfigurewidth \relax)}sp} +\def\figurenaturalheight {\ctxlua{figures.tprint("used","height",\number\dimexpr\defaultfigureheight\relax)}sp} + +\def\figurefilepath {\ctxlua{tex.sprint(tex.ctxcatcodes,file.dirname (figures.get("used","fullname")))}} +\def\figurefilename {\ctxlua{tex.sprint(tex.ctxcatcodes,file.nameonly(figures.get("used","fullname")))}} +\def\figurefiletype {\ctxlua{tex.sprint(tex.ctxcatcodes,file.extname (figures.get("used","fullname")))}} +\def\figurefullname {\ctxlua{figures.tprint("used","fullname")}} +\def\noffigurepages {\ctxlua{figures.tprint("used","pages",0)}} + +\let\naturalfigurewidth \figurenaturalwidth +\let\naturalfigureheight \figurenaturalheight + +\let\figurescalewidth \figurewidth +\let\figurescaleheight \figureheight +\let\figurescalexscale \figurexscale +\let\figurescaleyscale \figureyscale + +\appendtoks + \ctxlua { % figures.defaultwidth .. why not dimen + figures.setpaths("\@@exlocation","\@@exdirectory") ; + figures.defaultwidth = \number\dimexpr\defaultfigurewidth \relax ; + figures.defaultheight = \number\dimexpr\defaultfigureheight\relax ; + figures.boxnumber = \number\foundexternalfigure ; + }% +\to \everyexternalfigureresets + +%D In some situations we need to make sure that the figure related variables +%D are reset. This is especially important when we are nesting. Is this still +%D needed in \MKIV. + +\def\resetexternalfigures + {\let\@@efoption \empty % \let\@@efprefix\empty + \let\@@efmaxwidth \empty % \let\@@efcache \empty + \let\@@efmaxheight \empty % \let\@@efframe \v!off + \let\@@efforegroundcolor\empty + \let\@@efcolor \empty + \let\@@efconversion \empty + \let\@@efbackground \empty} + +\appendtoks \resetexternalfigures \to \everyoverlay +\appendtoks \resetexternalfigures \to \everybeforepagebody % not really needed + +\def\resetfigureusersettings + {% + \let\@@efmethod \empty + \let\@@eflabel \empty + \let\@@efsize \empty + \let\@@efconversion\@@exconversion + \let\@@efprefix \@@exprefix + \let\@@efcache \@@excache + \let\@@efpage \!!zerocount + \let\@@efobject \@@exobject + \let\@@efdisplay \empty + % + \let\@@efpreset \v!yes + \let\@@efsplit \empty + \let\@@efcolor \empty + % + \let\@@efsymbol \v!no + % + \let\@@efcontrols \v!no + \let\@@efpreview \v!no + \let\@@efrepeat \v!no + % + \let\@@efforegroundcolor\empty + % + \let\@@efhfactor \empty + \let\@@efwfactor \empty + \let\@@effactor \empty + \let\@@efmaxwidth \@@exmaxwidth + \let\@@efmaxheight \@@exmaxheight + \let\@@efxscale \empty + \let\@@efyscale \empty + \let\@@efscale \empty + \let\@@efsx \!!plusone + \let\@@efsy \!!plusone + \let\@@efwidth \empty + \let\@@efheight \empty + \let\@@eflines \empty + \let\@@efgrid \empty} + +\resetfigureusersettings + +\appendtoks + \resetfigureusersettings +\to \everyexternalfigureresets + +\def\checkfigureusersettings + {% old features + \doif\@@exoption\v!frame + {\let\@@efframe\v!on}% + \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}% + % fake color in gray bitmaps, assumes that + % a transparent color is used + \doifsomething\@@efforegroundcolor + {\def\@@efbackground{\v!foreground,\v!color}% + \def\@@efbackgroundcolor{\@@efforegroundcolor}}} + +\appendtoks + \checkfigureusersettings +\to \everyexternalfigurechecks + +%D Internal graphics are handled at the \TEX\ end: + +\def\doprocesstexlikefigure#1% retrofit into mkii + {\global\setbox\foundexternalfigure\vbox\framed + [\c!strut=\v!no,\c!align=\v!normal,\c!frame=\v!off, + \c!offset=\v!overlay,\c!width=\v!fit,\c!height=\v!fit] + {\blank[\v!disable]#1\endgraf\removelastskip}} % disable should stay here! + +\def\doprocessmpslikefigure#1% retrofit into mkii + {\global\setbox\foundexternalfigure\vbox{\convertMPtoPDF{#1}11}} + +\def\docheckfigurebuffer #1{\doprocesstexlikefigure{\getbuffer[#1]}} +\def\docheckfiguretex #1{\doprocesstexlikefigure{\input#1\relax}} +\def\docheckfiguremps #1{\doprocessmpslikefigure{#1}} +\def\docheckfiguremprun #1#2{\doprocesstexlikefigure{\useMPrun{#1}{#2}}} + +\def\doscalefigure + {\global\setbox\foundexternalfigure\vbox{\doscalebox\??ef{\dowithfigure{\box\foundexternalfigure}}}} + +\newconditional\testexternalfigureonly + +% \enabletrackers[figures.conversion] +% \externalfigure[demo.svg] +% \externalfigure[demo.svg][conversion=png] + +\def\calculateexternalfigure[#1][#2][#3][#4][#5][#6]% \cmd label filename parent_id preset current + {\dontcomplain + \restorecatcodes + \forgetall + \resetfigurevariables + \dosetefparameters{#4}{#5}{#6}% + \checkfigurevariables +% \begingroup +% \color[\@@efcolor]{\xdef\globcolorattr{\internalspotcolorname}} +% \endgroup + \ctxlua{figures.push { + name="#3", + label="#2", % todo: \@eflabel + page="\@@efpage", + size="\@@efsize", + object="\@@efobject", + prefix="\@@efprefix", + cache="\@@efcache", + format="\@@efmethod", + preset="\@@efprefix", + controls="\@@efcontrols", + preview="\@@efpreview", + display="\@@efdisplay", + conversion="\@@efconversion", + color="\internalspotcolorparent\@@efcolor", % hack is needed + ["repeat"]="\@@efrepeat", + width="\@@efwidth", % can be crap + height="\@@efheight", % can be crap + } }% + \ctxlua{figures.identify()}% + \ifconditional\testexternalfigureonly + \ifcase\figurestatus \else + \ctxlua{figures.check()}% + \ctxlua{figures.dummy()}% + \ctxlua{figures.scale()}% + \ctxlua{figures.done()}% + \fi + \signalexternalfigure + \else + \ifcase\figurestatus + \ctxlua{figures.dummy()}% + \ctxlua{figures.scale()}% + \else + \ctxlua{figures.check()}% + \ctxlua{figures.include()}% + \ctxlua{figures.scale()}% + \fi + \ctxlua{figures.done()}% + \signalexternalfigure + \finishexternalfigure + \fi + \ctxlua{figures.pop()}} + +\def\relocateexternalfigure % easier here than in lua + {\global\setbox\foundexternalfigure\vbox to \ht\foundexternalfigure\bgroup + \vss + \ht\foundexternalfigure\zeropoint + \hbox to \wd\foundexternalfigure\bgroup + \box\foundexternalfigure + \hss + \egroup + \egroup} + +\def\signalexternalfigure % global + {\ifcase\figurestatus + \global\resetsystemmode\v!figure % todo, also: \v!resource + \else + \global\setsystemmode \v!figure % todo, also: \v!resource + \fi} + +\unexpanded\def\startfoundexternalfigure#1#2% ht wd + {\global\setbox\foundexternalfigure\vbox to #2\bgroup\vss\hbox to #1\bgroup} + +\unexpanded\def\stopfoundexternalfigure + {\hss\egroup\egroup} + +\def\emptyfoundexternalfigure + {\startfoundexternalfigure\defaultfigurewidth\defaultfigureheight + \stopfoundexternalfigure} + +\def\finishexternalfigure % here we use \figurevariables + {\global\setbox\foundexternalfigure\vbox + {\ifcase\figurestatus + \let\@@efframe\v!on + \fi + \ifconditional\externalfigureflush + \ifconditional\externalfigurelevel % probably background + \ifskipexternalfigures + % nothing + \fakebox\foundexternalfigure + \else\ifcase\figurestatus + % nothing + \else + \the\externalfigurepostprocessors + \box\foundexternalfigure + \fi\fi + \else + \iftrialtypesetting \else \feedbackexternalfigure \fi + \settrue\externalfigurelevel + \ifskipexternalfigures + \ifcase\figurestatus + \externalfigurereplacement\figurelabel\figurefileoriginal{unknown}% + \else + \externalfigurereplacement\figurelabel\figurefullname{skipped}% + \fi + \else\ifcase\figurestatus + \externalfigurereplacement\figurelabel\figurefileoriginal{unknown}% + \else + \the\externalfigurepostprocessors + \doifelse\@@efreset\v!yes + {\wd\foundexternalfigure\figurewidth + \ht\foundexternalfigure\figureheight + \dp\foundexternalfigure\zeropoint + \box\foundexternalfigure} + {\localframed % should also be applied to high res ! + [\??ef] + [\c!offset=\v!overlay, + \c!width=\figurewidth, + \c!height=\figureheight] + {\vfilll\box\foundexternalfigure}}% + \fi\fi + \fi + \else + % maybe also \the\externalfigurepostprocessors + \iftrialtypesetting \else \feedbackexternalfigure \fi + \fi}} + +\ifx\externalfigurereplacement\undefined\let\externalfigurereplacement\gobblethreearguments\fi +\ifx\externalfigureplaceholder\undefined\let\externalfigureplaceholder\gobblethreearguments\fi + +\let\feedbackexternalfigure\relax % \gobblefourarguments +\let\dowithfigure \relax + +\def\getfiguredimensions + {\dodoubleempty\dogetfiguredimensions} + +\def\dogetfiguredimensions[#1][#2]% + {\startnointerference + \settrue\testexternalfigureonly + \externalfigure[#1][#2,\c!display=,\c!object=\v!no]% + \stopnointerference} + +\let\getfiguredimensionsonly\getfiguredimensions + +\def\doiffigureelse#1% + {\getfiguredimensions[#1]% so data is available ! + \ifdim\figurewidth=\zeropoint % todo: \figurestatus + \expandafter\secondoftwoarguments + \else + \expandafter\firstoftwoarguments + \fi} + +\def\registerexternalfigure % no placement, handy for preprocessing + {\dotripleempty\doregisterexternalfigure} + +\def\doregisterexternalfigure[#1][#2][#3]% + {\startnointerference + \testexternalfigureonly + \setfalse\externalfigureflush % == test ? + \externalfigure[#1][#2][#3]% or \doexternalfigure + \externalfigure[#1][#2,\c!display=,\c!object=\v!no]% + \stopnointerference} + +% figurebases + +\def\usefigurebase[#1]% + {\ctxlua{figures.bases.use("#1")}} + +\protect \endinput + +% \startbuffer +% \definecolor [blue] [c=1,m=.38,y=0,k=.64] +% \definecolor [yellow] [c=0,m=.28,y=1,k=.06] +% +% \definespotcolor [blue-100] [blue] [p=1] +% \definespotcolor [yellow-100] [yellow] [p=1] +% +% \definemultitonecolor [combicolor] [blue=.12,yellow=.28] [c=.1,m=.1,y=.3,k=.1] +% +% \definemultitonecolor [combicolor-b] [blue=1] [c=1,m=.38,y=0,k=.64] % force multitone +% \definemultitonecolor [combicolor-y] [yellow=1] [c=0,m=.28,y=1,k=.06] % force multitone +% +% \useexternalfigure[demo-a][mill.png] [object=no,width=.2\textwidth] +% \useexternalfigure[demo-b][hacker-bw.jpg][object=no,width=.2\textwidth] +% +% \startbaselinecorrection \startcombination[4*1] +% {\externalfigure[demo-a]} {no color} +% {\externalfigure[demo-a][color=combicolor]} {indexed duotone} +% {\externalfigure[demo-a][color=combicolor-b]} {spot color} +% {\externalfigure[demo-a][color=combicolor-y]} {spot color} +% \stopcombination \stopbaselinecorrection +% +% \startbaselinecorrection \startcombination[4*1] +% {\externalfigure[demo-b]} {no color} +% {\externalfigure[demo-b][color=combicolor]} {indexed duotone} +% {\externalfigure[demo-b][color=combicolor-b]} {spot color} +% {\externalfigure[demo-b][color=combicolor-y]} {spot color} +% \stopcombination \stopbaselinecorrection +% +% \startbaselinecorrection \startcombination[4*1] +% {\externalfigure[demo-a]} {no color} +% {\externalfigure[demo-a][color=combicolor]} {indexed duotone} +% {\externalfigure[demo-a][color=blue-100]} {spot color} +% {\externalfigure[demo-a][color=yellow-100]} {spot color} +% \stopcombination \stopbaselinecorrection +% +% \startbaselinecorrection \startcombination[4*1] +% {\externalfigure[demo-b]} {no color} +% {\externalfigure[demo-b][color=combicolor]} {indexed duotone} +% {\externalfigure[demo-b][color=blue-100]} {spot color} +% {\externalfigure[demo-b][color=yellow-100]} {spot color} +% \stopcombination \stopbaselinecorrection +% \stopbuffer +% +% \getbuffer \typebuffer diff --git a/tex/context/base/grph-swf.lua b/tex/context/base/grph-swf.lua new file mode 100644 index 000000000..e55454b52 --- /dev/null +++ b/tex/context/base/grph-swf.lua @@ -0,0 +1,43 @@ +if not modules then modules = { } end modules ['grph-swf'] = { + version = 1.001, + comment = "companion to grph-inc.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format = string.format + +local texsprint = tex.sprint +local ctxcatcodes = tex.ctxcatcodes +local pdfannotation = nodes.pdfannotation + +function figures.checkers.swf(data) + local dr, du, ds = data.request, data.used, data.status + local width = (dr.width or figures.defaultwidth):todimen() + local height = (dr.height or figures.defaultheight):todimen() + local foundname = du.fullname + dr.width, dr.height = width, height + du.width, du.height, du.foundname = width, height, foundname + texsprint(ctxcatcodes,format("\\startfoundexternalfigure{%ssp}{%ssp}",width,height)) + local annot, preview, ref = backends.pdf.helpers.insertswf { + foundname = foundname, + width = width, + height = height, + -- factor = number.dimenfactors.bp, + -- display = dr.display, + -- controls = dr.controls, + -- label = dr.label, + } + -- node.write(pdfannotation(width,-height,0,annot())) + texsprint(ctxcatcodes,format("\\pdfannot width %ssp height %ssp {%s}",width,height,annot())) -- brrrr +--~ if ref then -- wrong ! a direct ref should work +--~ texsprint(ctxcatcodes,format("\\smash{\\pdfrefximage%s\\relax}",ref)) -- brrrr +--~ end + texsprint(ctxcatcodes,"\\stopfoundexternalfigure") + return data +end + +figures.includers.swf = figures.includers.nongeneric + +figures.registersuffix("swf","swf") diff --git a/tex/context/base/grph-trf.mkii b/tex/context/base/grph-trf.mkii new file mode 100644 index 000000000..3e32395b4 --- /dev/null +++ b/tex/context/base/grph-trf.mkii @@ -0,0 +1,579 @@ +%D \module +%D [ file=grph-fig, +%D version=2006.08.26, % overhaul/split of 1997.03.31 core-fig +%D title=\CONTEXT\ Graphic Macros, +%D subtitle=Transformations, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 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 Graphic Macros / Transformations} + +\unprotect + +%D Scaling: + +\unexpanded\def\scale{\dodoubleempty\doscalenextbox[\??xy]} + +% probably too many dimens / the width calculations can go +% since we may assume scaling is available (was not true +% long ago which is why we also calculate the width) + +\newdimen\scaleboxwidth +\newdimen\scaleboxheight +\newdimen\scaleboxdepth + +\newdimen\scaleboxsizex +\newdimen\scaleboxsizey +\newdimen\scaleboxoffsetx +\newdimen\scaleboxoffsety + +\newdimen\scaleboxhsize +\newdimen\scaleboxvsize + +% global + +\newdimen\scaleboxdimx \let\figwid \scaleboxdimx +\newdimen\scaleboxdimy \let\fighei \scaleboxdimy +\newcount\scaleboxscax \let\figxsca\scaleboxscax +\newcount\scaleboxscay \let\figysca\scaleboxscay + +\newdimen\scaleboxoutervsize % we cannot manipulate any global vsize ! + +\let\finalscaleboxxscale \!!plusone +\let\finalscaleboxyscale \!!plusone +\let\finalscaleboxwidth \!!zeropoint +\let\finalscaleboxheight \!!zeropoint +\let\finalscaleboxxfactor\!!hundred +\let\finalscaleboxyfactor\!!hundred + +\newconditional\scaleboxdone + +\def\doscalenextbox[#1][#2]% + {\bgroup + \getparameters + [#1] + [\c!scale=,\c!xscale=,\c!yscale=,\c!width=,\c!height=,\c!lines=, + \c!factor=,\c!hfactor=,\c!wfactor=,\c!grid=,\c!sx=1,\c!sy=1, + \c!equalwidth=,\c!equalheight=, + \c!maxwidth=\scaleparameter\c!width,\c!maxheight=\scaleparameter\c!height, + #2]% + \dowithnextbox{\dodoscalenextbox{#1}\egroup}\hbox} + +\def\doscalebox#1% + {\bgroup\dowithnextbox{\dodoscalenextbox{#1}\egroup}\hbox} + +\let\currentscaletag\??xy + +\def\scaleparameter#1% + {\csname\currentscaletag#1\endcsname} + +\def\setscaleparameter#1#2% + {\setvalue{\currentscaletag#1}{#2}} + +\def\dodoscalenextbox#1% + {\edef\currentscaletag{#1}% + \doif{\scaleparameter\c!depth}\v!no{\setbox\nextbox\hbox{\raise\nextboxdp\box\nextbox}}% new + \forgetall + \dontshowcomposition + \dontcomplain + \doscaleboxcalculations + \doscaleboxindeed + \doscaleboxposition + \flushnextbox} + +\def\doscaleboxindeed + {\ifconditional\scaleboxdone + \scaleboxwidth \finalscaleboxxscale\nextboxwd + \scaleboxheight\finalscaleboxyscale\nextboxht + \scaleboxdepth \finalscaleboxyscale\nextboxdp + \setbox\nextbox\hbox + {\dostartscaling \finalscaleboxxscale \finalscaleboxyscale + \smashedbox\nextbox + \dostopscaling}% + \nextboxwd\scaleboxwidth + \nextboxht\scaleboxheight + \nextboxdp\scaleboxdepth + \fi} + +\def\doscaleboxcalculations + {\setfalse\scaleboxdone + % initial final value + \global\let\finalscaleboxxscale \!!plusone + \global\let\finalscaleboxyscale \!!plusone + \xdef \finalscaleboxwidth {\the\nextboxwd}% + \xdef \finalscaleboxheight{\the\nextboxht}% + \global\let\finalscaleboxxfactor\!!hundred + \global\let\finalscaleboxyfactor\!!hundred + \ifdim\nextboxht>\zeropoint \ifdim\nextboxwd>\zeropoint + \edef\scaleboxstampa % slow way [can be combined] + {\scaleparameter\c!scale \scaleparameter\c!xscale \scaleparameter\c!yscale + \scaleparameter\c!factor\scaleparameter\c!wfactor\scaleparameter\c!hfactor + \scaleparameter\c!lines \scaleparameter\c!width \scaleparameter\c!height}% + \edef\scaleboxstampb % fast way [just sx/sy] + {\scaleparameter\c!sx + \scaleparameter\c!sy}% + \edef\scaleboxstampc + {11}% + \ifx\scaleboxstampa\empty + \ifx\scaleboxstampb\scaleboxstampc + % no scaling, but still check; new, gone again +% wrong: scaled proportionally as side effect +% \doifsomething{\scaleparameter\c!maxwidth }{\letvalue{\currentscaletag\c!factor}\v!fit}% +% \doifsomething{\scaleparameter\c!maxheight}{\letvalue{\currentscaletag\c!factor}\v!fit}% + \insidefloattrue % trick + \dodoscaleboxcalculations + \else + \dosetscalboxsxsy + \nodoscaleboxcalculations + \fi + \else + \ifx\scaleboxstampb\empty + % no need to check further + \else + \dosetscalboxsxsy + \fi + \dodoscaleboxcalculations + \fi + \fi \fi} + +\def\dosetscalboxsxsy + {\ifdim\scaleparameter\c!sx\onepoint=\onepoint\else + \setevalue{\currentscaletag\c!width }{\the\dimexpr\scaleparameter\c!sx\wd\nextbox\relax}% + \fi + \ifdim\scaleparameter\c!sy\onepoint=\onepoint\else + \setevalue{\currentscaletag\c!height}{\the\dimexpr\scaleparameter\c!sy\ht\nextbox\relax}% + \fi} + +\def\doscaleboxrounding#1.#2\relax{#1} + +\def\scaleboxrounding#1% + {\@EA\@EA\@EA\doscaleboxrounding\@EA\WITHOUTPT\the\dimexpr#1\points*100+32768sp\relax.\relax} + +\def\nodoscaleboxcalculations + {\settrue\scaleboxdone + \xdef\finalscaleboxwidth {\the\dimexpr\scaleparameter\c!sx\wd\nextbox\relax}% + \xdef\finalscaleboxheight {\the\dimexpr\scaleparameter\c!sy\ht\nextbox\relax}% + \xdef\finalscaleboxxscale {\scaleparameter\c!sx}% + \xdef\finalscaleboxyscale {\scaleparameter\c!sy}% + \ifx\finalscaleboxxscale\empty\let\finalscaleboxxscale\!!plusone\fi + \ifx\finalscaleboxyscale\empty\let\finalscaleboxyscale\!!plusone\fi + \xdef\finalscaleboxxfactor{\scaleboxrounding\finalscaleboxxscale}% + \xdef\finalscaleboxyfactor{\scaleboxrounding\finalscaleboxyscale}} + +\def\dodoscaleboxcalculations + {\settrue\scaleboxdone + % initial values + \scaleboxoffsetx\zeropoint + \scaleboxoffsety\zeropoint + \scaleboxsizex \nextboxwd + \scaleboxsizey \nextboxht % alleen ht wordt geschaald! + % final values + \global\scaleboxdimx \zeropoint % see note * (core-fig) + \global\scaleboxdimy \zeropoint % see note * (core-fig) + \scaleboxscax \plusone % see note * (core-fig) + \scaleboxscay \plusone % see note * (core-fig) + % preparations + \setfalse\scaleboxscalingdone + \checkscaleboxsettings + % calculators + % beware, they operate in sequence, and calculate missing dimensions / messy + %setscaleboxbynature % when? needed? + \ifconditional\scaleboxscalingdone\else\setscaleboxbyfactor \fi + \ifconditional\scaleboxscalingdone\else\setscaleboxbyscale \fi + \ifconditional\scaleboxscalingdone\else\setscaleboxbydimension\fi + % finalizers / to be done (no longer needed this way, clean up) + \convertscaleboxinsertscale\scaleboxhsize\figx\scaleboxscax\scax + \convertscaleboxinsertscale\scaleboxvsize\figy\scaleboxscay\scay + % used in actual scaling + \xdef\finalscaleboxwidth {\the\scaleboxdimx}% + \xdef\finalscaleboxheight {\the\scaleboxdimy}% + \xdef\finalscaleboxxfactor{\the\scaleboxscax}% + \xdef\finalscaleboxyfactor{\the\scaleboxscay}% + \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}}% + \doifsomething{\scaleparameter\c!maxheight}% can be defined in itself + {\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}}% + \getvalue{\??xy:\c!grid:\scaleparameter\c!grid}} + +\def\setscaleboxbynature % where ! ! ! ! ! + {\doifsomething{\scaleparameter\c!width }{\global\scaleboxdimx\scaleparameter\c!width }% + \doifsomething{\scaleparameter\c!height}{\global\scaleboxdimy\scaleparameter\c!height}% + \doifsomething{\scaleparameter\c!scale } {\scaleboxscax\scaleparameter\c!scale + \scaleboxscay\scaleparameter\c!scale }% + \doifsomething{\scaleparameter\c!xscale} {\scaleboxscax\scaleparameter\c!xscale}% + \doifsomething{\scaleparameter\c!yscale} {\scaleboxscay\scaleparameter\c!yscale}} % oeps, was x + +% \defineexternalfigure[width-6][factor=auto,maxwidth=\textheight,maxheight=\textwidth] +% \defineexternalfigure[width-7][factor=auto,maxwidth=\textwidth,maxheight=\textheight] +% \placefigure{none}{\rotate[frame=on,offset=overlay]{\externalfigure[t:/sources/cow.pdf][width-6]}} \page +% \placefigure{none}{\framed[frame=on,offset=overlay]{\externalfigure[t:/sources/cow.pdf][width-7]}} + +\def\setscaleboxbyfactor + {\doifinsetelse{\scaleparameter\c!factor}{\v!max,\v!fit,\v!broad,\v!auto} + {\doapplyscaleboxsize + \ifdim\scaleboxsizex>\scaleboxsizey + \docalculatescaleboxnorm \scaleboxdimx\c!factor\c!maxwidth\hsize\scaleboxhsize + \docalculatescaleboxscales\scaleboxdimx\scaleboxsizex\scaleboxdimy\scaleboxsizey + \else + \docalculatescaleboxnorm \scaleboxdimy\c!factor\c!maxheight\scaleboxoutervsize\scaleboxvsize + \docalculatescaleboxscales\scaleboxdimy\scaleboxsizey\scaleboxdimx\scaleboxsizex + \fi + \donetrue} + {\doifinsetelse{\scaleparameter\c!hfactor}{\v!max,\v!fit,\v!broad,\v!auto} + {\doapplyscaleboxsize + \docalculatescaleboxnorm \scaleboxdimy\c!hfactor\c!maxheight\scaleboxoutervsize\scaleboxvsize + \docalculatescaleboxscales\scaleboxdimy\scaleboxsizey\scaleboxdimx\scaleboxsizex + \donetrue} + {\doifinsetelse{\scaleparameter\c!wfactor}{\v!max,\v!fit,\v!broad,\v!auto} + {\doapplyscaleboxsize + \docalculatescaleboxnorm \scaleboxdimx\c!wfactor\c!maxwidth\hsize\scaleboxhsize + \docalculatescaleboxscales\scaleboxdimx\scaleboxsizex\scaleboxdimy\scaleboxsizey + \donetrue} + {\docalculatescaleboxnorm\scaleboxdimy\c!factor \c!height \textheight\scaleboxvsize + \docalculatescaleboxnorm\scaleboxdimy\c!hfactor\c!height \textheight\scaleboxvsize + \docalculatescaleboxnorm\scaleboxdimx\c!wfactor\c!width \hsize \hsize + \donefalse}}}% + \ifdone + \settrue\scaleboxscalingdone + \ifdim\scaleboxdimx>\scaleboxhsize + \global\scaleboxdimy\zeropoint \global\scaleboxdimx\scaleboxhsize + \else\ifdim\scaleboxdimy>\scaleboxvsize + \global\scaleboxdimx\zeropoint \global\scaleboxdimy\scaleboxvsize + \fi\fi + \setscaleboxbydimension + \fi} + +\def\setscaleboxbyscale + {\doifsomething{\scaleparameter\c!scale\scaleparameter\c!xscale\scaleparameter\c!yscale} + {\doapplyscaleboxscale\scaleboxdimx\scaleboxsizex\scaleboxscax\c!xscale + \doapplyscaleboxscale\scaleboxdimy\scaleboxsizey\scaleboxscay\c!yscale + \global\scaleboxdimx\zeropoint + \global\scaleboxdimy\zeropoint + \doifelsenothing{\scaleparameter\c!maxwidth} + {\doifsomething{\scaleparameter\c!maxheight} + {\ifdim\scaleboxsizey>\scaleparameter\c!maxheight\relax + \global\scaleboxdimy\scaleparameter\c!maxheight + \fi}} + {\ifdim\scaleboxsizex>\scaleparameter\c!maxwidth\relax + \global\scaleboxdimx\scaleparameter\c!maxwidth + \fi}}} + +\def\setscaleboxbydimension + {\ifdim\scaleboxdimx>\zeropoint + \ifdim\scaleboxdimy>\zeropoint + \dosetdimensionscaleboxsize + {\docalculatescaleboxscale\scaleboxdimy\scaleboxsizey\scaleboxscay + \docalculatescaleboxscale\scaleboxdimx\scaleboxsizex\scaleboxscax}% + {\docalculatescaleboxscale\scaleboxdimy\scaleboxsizey\scaleboxscay + \docalculatescaleboxscale\scaleboxdimx\scaleboxsizex\scaleboxscax}% + {\docalculatescaleboxscale\scaleboxdimy\scaleboxsizey\scaleboxscay + \docalculatescaleboxscale\scaleboxdimx\scaleboxsizex\scaleboxscax}% + \else + \dosetdimensionscaleboxsize + {\docalculatescaleboxscales\scaleboxdimx\scaleboxsizex\scaleboxdimy\scaleboxsizey}% + {\docalculatescaleboxscales\scaleboxdimx\scaleboxsizex\scaleboxdimy\scaleboxsizey}% + {\docalculatescaleboxscales\scaleboxdimx\scaleboxsizex\scaleboxdimy\scaleboxsizey}% + \fi + \else + \ifdim\scaleboxdimy>\zeropoint + \dosetdimensionscaleboxsize + {\docalculatescaleboxscales\scaleboxdimy\scaleboxsizey\scaleboxdimx\scaleboxsizex}% + {\docalculatescaleboxscales\scaleboxdimy\scaleboxsizey\scaleboxdimx\scaleboxsizex}% + {\docalculatescaleboxscales\scaleboxdimy\scaleboxsizey\scaleboxdimx\scaleboxsizex}% + \else + \dosetdimensionscaleboxsize + {\doapplyscaleboxscale\scaleboxdimx\scaleboxsizex\scaleboxscax\c!xscale + \doapplyscaleboxscale\scaleboxdimy\scaleboxsizey\scaleboxscay\c!yscale}% + {\docalculatescaleboxscales\scaleboxdimx\scaleboxsizex\scaleboxdimy\scaleboxsizey}% + {\docalculatescaleboxscales\scaleboxdimy\scaleboxsizey\scaleboxdimx\scaleboxsizex}% + \fi + \fi} + +\def\dosetdimensionscaleboxsize#1#2#3% + {#1\relax + \doifsomething{\scaleparameter\c!maxwidth} + {\ifdim\scaleboxdimx>\scaleparameter\c!maxwidth\relax + \global\scaleboxdimx\scaleparameter\c!maxwidth + #2\relax + \fi}% + \doifsomething{\scaleparameter\c!maxheight} + {\ifdim\scaleboxdimy>\scaleparameter\c!maxheight\relax + \global\scaleboxdimy\scaleparameter\c!maxheight + #3\relax + \fi}} + +\def\docalculatescaleboxnorm#1#2#3#4#5% 2 3 parameters (dodo:speedup) + {\processaction + [\scaleparameter#2] + [ \v!max=>\global#1\dimexpr#4\relax, + \v!fit=>\global#1\dimexpr#5\relax, + \v!broad=>\global#1\dimexpr#5-4\@@exbodyfont\relax, + \v!auto=>\doifsomething{\scaleparameter#3}{\global#1\dimexpr\scaleparameter#3\relax}, + \s!default=>\doifsomething{\scaleparameter#3}{\global#1\dimexpr\scaleparameter#3\relax}, + \s!unknown=>\global#1\dimexpr\scaleparameter#2\dimexpr\@@exbodyfont/10\relax\relax]} + +\def\docalculatescaleboxscales#1#2#3#4% + {\scratchdimen\dimexpr#1/\dimexpr#2/\plusthousand\relax\relax + \scaleboxscax\scratchdimen + \scaleboxscay\scratchdimen + #3\dimexpr\scaleboxscax\dimexpr#4/\plusthousand\relax\relax} + +\def\docalculatescaleboxscale#1#2#3% + {#3\dimexpr#1/\dimexpr#2/\plusthousand\relax\relax} + +\def\doapplyscaleboxscale#1#2#3#4% $4 = parameter / scale can be empty + {\ifcase0\scaleparameter#4\relax + \ifcase0\scaleparameter\c!scale\relax + #3=\plusthousand + \else + #3=\scaleparameter\c!scale + \fi + \else + #3=\scaleparameter#4% + \fi + \relax % important ! still ? + \global#1\ifnum#3=\plusthousand#2\else\dimexpr#3\dimexpr#2/\plusthousand\relax\relax\fi + \relax} + +\def\doapplyscaleboxsize + {\doifelsenothing{\scaleparameter\c!maxheight} + {\scaleboxoutervsize\textheight + \ifinner + \scaleboxoutervsize \vsize % \textheight =\vsize + \scratchdimen\vsize % \scratchdimen=\textheight + \else\ifinsidefloat + \scaleboxoutervsize \vsize % \textheight =\vsize + \scratchdimen\vsize % \scratchdimen=\textheight + \else\ifinpagebody + \scaleboxoutervsize \vsize % \textheight =\vsize + \scratchdimen\vsize % \scratchdimen=\textheight + \else % hm, there should be an option to force this + \ifdim\pagegoal<\maxdimen + \ifdim\pagetotal<\pagegoal + \scratchdimen\pagegoal + \advance\scratchdimen -\pagetotal + \else + \scratchdimen\scaleboxoutervsize % \textheight + \fi + \else + \scratchdimen\scaleboxoutervsize % \textheight + \fi + \fi\fi\fi} + {\scratchdimen\scaleparameter\c!maxheight + \scaleboxoutervsize\scratchdimen}% + \doifelsenothing{\scaleparameter\c!height} + {\scaleboxvsize\scratchdimen} + {\scaleboxvsize\scaleparameter\c!height}% + \doifelsenothing{\scaleparameter\c!width} + {\scaleboxhsize\hsize} + {\scaleboxhsize\scaleparameter\c!width}} + +\def\convertscaleboxinsertscale#1#2#3#4% + {\scratchdimen#1\relax + \ifnum#3=\plusthousand + % == scale 1 + \else + % better 1000 100 10 ranges, evt round 2sp + \divide\scratchdimen \plusthousand + \multiply\scratchdimen #3\relax + \fi + \scratchdimen-\scratchdimen % beter hier - dan in driver + \edef#2{\the\scratchdimen}% + \scratchcounter#3\relax + \ifnum\scratchcounter>\plustenthousand + \divide\scratchcounter\!!ten \scratchdimen\the\scratchcounter\points + \else + \scratchdimen\the\scratchcounter\points \divide\scratchdimen\!!ten + \fi + \edef#4{\withoutpt\the\scratchdimen}} + +% \startcombination +% {\externalfigure[cow.pdf] [frame=on,height=3cm,equalwidth=6cm]} {} +% {\externalfigure[mill.png][frame=on,height=3cm,equalwidth=6cm]} {} +% \stopcombination + +\def\doscaleboxposition + {\doifsomething{\scaleparameter\c!equalwidth} + {\scratchdimen\scaleparameter\c!equalwidth\relax + \ifdim\wd\nextbox<\scratchdimen + \setbox\nextbox\hbox to \scratchdimen{\hss\box\nextbox\hss}% + \fi}% + \doifsomething{\scaleparameter\c!equalheight} + {\scratchdimen\scaleparameter\c!equalheight\relax + \ifdim\ht\nextbox<\scratchdimen + \setbox\nextbox\vbox to \scratchdimen{\vss\box\nextbox\vss}% + \fi}} + +%D \macros +%D {clip, setupclipping} +%D +%D Although related to figures, clipping can be applied to +%D arbitrary content. We can use \METAPOST\ to provide a non +%D rectangular clipping path. +%D +%D \starttyping +%D \startMPclip{fun} +%D clip currentpicture to fullcircle +%D shifted (.5,.5) xscaled \width yscaled \height ; +%D \stopMPclip +%D \stoptyping +%D +%D We get a rectangular piece of the figure when we say: +%D +%D \starttyping +%D \clip[x=2,y=1]{\externalfigure[photo]} +%D \stoptyping +%D +%D When we want to clip to the oval we defined a few lines ago, +%D we say: +%D +%D \starttyping +%D \clip[nx=1,ny=1,x=1,y=1,mp=fun]{\externalfigure[photo]} +%D \stoptyping +%D +%D The general characteristics of clipping can be set up with +%D +%D \showsetup{setupclipping} + +\def\setupclipping + {\dodoubleargument\getparameters[\??cp]} + +\def\clip + {\dosingleempty\doclip} + +\def\doclip[#1]% nb top->bottom left->right + {\bgroup + \getparameters[\??cp][#1]% + \doifelse\@@cpstate\v!start\dodoclip{\egroup\hbox}} + +\def\dodoclip + {\dowithnextbox + {\ifdim\@@cpwidth>\zeropoint + \!!dimena\@@cpwidth + \!!dimenc\@@cphoffset + \else + \!!dimena\nextboxwd + \divide\!!dimena \@@cpnx + \!!dimenc\@@cpx\!!dimena + \advance\!!dimenc -\!!dimena + \!!dimena\@@cpsx\!!dimena + \fi + \relax % sure + \ifdim\@@cpheight>\zeropoint + \!!dimenb\@@cpheight + \!!dimend\nextboxht + \advance\!!dimend -\@@cpvoffset + \advance\!!dimend -\!!dimenb + \else + \!!dimenb\nextboxht + \divide\!!dimenb \@@cpny + \!!dimend-\@@cpy\!!dimenb + \advance\!!dimend -\@@cpsy\!!dimenb + \advance\!!dimend \!!dimenb + \!!dimenb\@@cpsy\!!dimenb + \advance\!!dimend \nextboxht % dimend ! + \fi + \setbox\nextbox\hbox % old + {\advance\!!dimenc -\@@cpleftoffset % new ! + \advance\!!dimend -\@@cpbottomoffset % new ! % - added + \hskip-\!!dimenc\lower\!!dimend\flushnextbox}% old + \nextboxwd\zeropoint + \nextboxht\zeropoint + \nextboxdp\zeropoint + \setbox\nextbox\hbox + {\advance\!!dimena \@@cpleftoffset % new ! + \advance\!!dimena \@@cprightoffset % new ! + \advance\!!dimenb \@@cpbottomoffset % new ! + \advance\!!dimenb \@@cptopoffset % new ! + \dostartclipping\@@cpmp\!!dimena\!!dimenb % old + \flushnextbox + \dostopclipping}% + \setbox\nextbox\hbox % new ! + {\!!dimena-\@@cpleftoffset % new ! + \!!dimenb \@@cpbottomoffset % new ! % - removed + \hskip\!!dimena\lower\!!dimenb\flushnextbox}% new ! + \nextboxwd\!!dimena + \nextboxht\!!dimenb + \nextboxdp\zeropoint + \flushnextbox + \egroup}% + \hbox} + +\setupclipping + [\c!state=\v!start, + \c!n=1, % was 2 + \c!nx=\@@cpn,\c!x=1,\c!sx=1, + \c!ny=\@@cpn,\c!y=1,\c!sy=1, + \c!width=\!!zeropoint, + \c!height=\!!zeropoint, + \c!hoffset=\!!zeropoint, + \c!voffset=\!!zeropoint, + \c!offset=\zeropoint, + \c!leftoffset=\@@cpoffset, % \zeropoint, + \c!rightoffset=\@@cpoffset, % \zeropoint, + \c!topoffset=\@@cpoffset, % \zeropoint, + \c!bottomoffset=\@@cpoffset,% \zeropoint, + \c!mp=] + +%D \startbuffer +%D \startuseMPgraphic{test} +%D path p ; p := fullcircle scaled 4cm ; +%D draw p withpen pencircle scaled 1cm ; +%D setbounds currentpicture to boundingbox p ; +%D \stopuseMPgraphic +%D +%D \hbox to \hsize \bgroup +%D \hss +%D \ruledhbox{\useMPgraphic{test}}% +%D \hss +%D \ruledhbox{\clip{\useMPgraphic{test}}}% +%D \hss +%D \egroup +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +%D Mirroring. + +\def\domirrorbox % \hbox/\vbox/\vtop + {\bgroup + \dowithnextbox + {\dontshowcomposition + \scratchdimen\nextboxwd + % better use an hbox (if no \forgetall, leftskip etc may creep in) + %\setbox\nextbox\vbox{\forgetall\dostartmirroring\hskip-\nextboxwd\flushnextbox\dostopmirroring}% + \setbox\nextbox\hbox{\dostartmirroring\hskip-\nextboxwd\flushnextbox\dostopmirroring}% + \nextboxwd\scratchdimen + \flushnextbox + \egroup}} + +\unexpanded\def\mirror + {\domirrorbox\hbox} + +% \setbox0=\hbox{gans} +% \ruledhbox{\copy0 \schaal[sx=2,sy=2]{\copy0}} +% \mirror{\ruledhbox{\copy0 \schaal{\box0}}} + +\protect \endinput diff --git a/tex/context/base/grph-trf.mkiv b/tex/context/base/grph-trf.mkiv new file mode 100644 index 000000000..9924a68e8 --- /dev/null +++ b/tex/context/base/grph-trf.mkiv @@ -0,0 +1,580 @@ +%D \module +%D [ file=grph-fig, +%D version=2006.08.26, % overhaul/split of 1997.03.31 core-fig +%D title=\CONTEXT\ Graphic Macros, +%D subtitle=Transformations, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 It may be that some functionality got lost. If it concerns +%D defined features, let me know and it will be sorted out. + +%D We will move the calculations to lua. + +\writestatus{loading}{ConTeXt Graphic Macros / Transformations} + +\unprotect + +%D Scaling: + +\unexpanded\def\scale{\dodoubleempty\doscalenextbox[\??xy]} + +% probably too many dimens / the width calculations can go +% since we may assume scaling is available (was not true +% long ago which is why we also calculate the width) + +\newdimen\scaleboxwidth +\newdimen\scaleboxheight +\newdimen\scaleboxdepth + +\newdimen\scaleboxsizex +\newdimen\scaleboxsizey +\newdimen\scaleboxoffsetx +\newdimen\scaleboxoffsety + +\newdimen\scaleboxhsize +\newdimen\scaleboxvsize + +% global + +\newdimen\scaleboxdimx \let\figwid \scaleboxdimx +\newdimen\scaleboxdimy \let\fighei \scaleboxdimy +\newcount\scaleboxscax \let\figxsca\scaleboxscax +\newcount\scaleboxscay \let\figysca\scaleboxscay + +\newdimen\scaleboxoutervsize % we cannot manipulate any global vsize ! + +\let\finalscaleboxxscale \!!plusone +\let\finalscaleboxyscale \!!plusone +\let\finalscaleboxwidth \!!zeropoint +\let\finalscaleboxheight \!!zeropoint +\let\finalscaleboxxfactor\!!hundred +\let\finalscaleboxyfactor\!!hundred + +\newconditional\scaleboxdone + +\def\doscalenextbox[#1][#2]% + {\bgroup + \getparameters + [#1] + [\c!scale=,\c!xscale=,\c!yscale=,\c!width=,\c!height=,\c!lines=, + \c!factor=,\c!hfactor=,\c!wfactor=,\c!grid=,\c!sx=1,\c!sy=1, + \c!equalwidth=,\c!equalheight=, + \c!maxwidth=\scaleparameter\c!width,\c!maxheight=\scaleparameter\c!height, + #2]% + \dowithnextbox{\dodoscalenextbox{#1}\egroup}\hbox} + +\def\doscalebox#1% + {\bgroup\dowithnextbox{\dodoscalenextbox{#1}\egroup}\hbox} + +\let\currentscaletag\??xy + +\def\scaleparameter#1% + {\csname\currentscaletag#1\endcsname} + +\def\setscaleparameter#1#2% + {\setvalue{\currentscaletag#1}{#2}} + +\def\dodoscalenextbox#1% + {\edef\currentscaletag{#1}% + \doif{\scaleparameter\c!depth}\v!no{\setbox\nextbox\hbox{\raise\nextboxdp\box\nextbox}}% new + \forgetall + \dontshowcomposition + \dontcomplain + \doscaleboxcalculations + \doscaleboxindeed + \doscaleboxposition + \flushnextbox} + +\def\doscaleboxindeed + {\ifconditional\scaleboxdone + \scaleboxwidth \finalscaleboxxscale\nextboxwd + \scaleboxheight\finalscaleboxyscale\nextboxht + \scaleboxdepth \finalscaleboxyscale\nextboxdp + \setbox\nextbox\hbox + {\dostartscaling \finalscaleboxxscale \finalscaleboxyscale + \smashedbox\nextbox + \dostopscaling}% + \nextboxwd\scaleboxwidth + \nextboxht\scaleboxheight + \nextboxdp\scaleboxdepth + \fi} + +\def\doscaleboxcalculations + {\setfalse\scaleboxdone + % initial final value + \global\let\finalscaleboxxscale \!!plusone + \global\let\finalscaleboxyscale \!!plusone + \xdef \finalscaleboxwidth {\the\nextboxwd}% + \xdef \finalscaleboxheight{\the\nextboxht}% + \global\let\finalscaleboxxfactor\!!hundred + \global\let\finalscaleboxyfactor\!!hundred + \ifdim\nextboxht>\zeropoint \ifdim\nextboxwd>\zeropoint + % hm, still useful? better in lua anyway + \edef\scaleboxstampa % slow way [can be combined] + {\scaleparameter\c!scale \scaleparameter\c!xscale \scaleparameter\c!yscale + \scaleparameter\c!factor\scaleparameter\c!wfactor\scaleparameter\c!hfactor + \scaleparameter\c!lines \scaleparameter\c!width \scaleparameter\c!height}% + \edef\scaleboxstampb % fast way [just sx/sy] + {\scaleparameter\c!sx + \scaleparameter\c!sy}% + \edef\scaleboxstampc + {11}% + \ifx\scaleboxstampa\empty + \ifx\scaleboxstampb\scaleboxstampc + % no scaling, but still check; new, gone again +% wrong: scaled proportionally as side effect +% \doifsomething{\scaleparameter\c!maxwidth }{\letvalue{\currentscaletag\c!factor}\v!fit}% +% \doifsomething{\scaleparameter\c!maxheight}{\letvalue{\currentscaletag\c!factor}\v!fit}% + \insidefloattrue % trick + \dodoscaleboxcalculations + \else + \dosetscalboxsxsy + \nodoscaleboxcalculations + \fi + \else + \ifx\scaleboxstampb\empty + % no need to check further + \else + \dosetscalboxsxsy + \fi + \dodoscaleboxcalculations + \fi + \fi \fi} + +\def\dosetscalboxsxsy + {\ifdim\scaleparameter\c!sx\onepoint=\onepoint\else + \setevalue{\currentscaletag\c!width }{\the\dimexpr\scaleparameter\c!sx\wd\nextbox\relax}% + \fi + \ifdim\scaleparameter\c!sy\onepoint=\onepoint\else + \setevalue{\currentscaletag\c!height}{\the\dimexpr\scaleparameter\c!sy\ht\nextbox\relax}% + \fi} + +\def\doscaleboxrounding#1.#2\relax{#1} + +\def\scaleboxrounding#1% + {\@EA\@EA\@EA\doscaleboxrounding\@EA\WITHOUTPT\the\dimexpr#1\points*100+32768sp\relax.\relax} + +\def\nodoscaleboxcalculations + {\settrue\scaleboxdone + \xdef\finalscaleboxwidth {\the\dimexpr\scaleparameter\c!sx\wd\nextbox\relax}% + \xdef\finalscaleboxheight {\the\dimexpr\scaleparameter\c!sy\ht\nextbox\relax}% + \xdef\finalscaleboxxscale {\scaleparameter\c!sx}% + \xdef\finalscaleboxyscale {\scaleparameter\c!sy}% + \ifx\finalscaleboxxscale\empty\let\finalscaleboxxscale\!!plusone\fi + \ifx\finalscaleboxyscale\empty\let\finalscaleboxyscale\!!plusone\fi + \xdef\finalscaleboxxfactor{\scaleboxrounding\finalscaleboxxscale}% + \xdef\finalscaleboxyfactor{\scaleboxrounding\finalscaleboxyscale}} + +\def\dodoscaleboxcalculations + {\settrue\scaleboxdone + % initial values + \scaleboxoffsetx\zeropoint + \scaleboxoffsety\zeropoint + \scaleboxsizex \nextboxwd + \scaleboxsizey \nextboxht % alleen ht wordt geschaald! + % final values + \global\scaleboxdimx \zeropoint % see note * (core-fig) + \global\scaleboxdimy \zeropoint % see note * (core-fig) + \scaleboxscax \plusone % see note * (core-fig) + \scaleboxscay \plusone % see note * (core-fig) + % preparations + \setfalse\scaleboxscalingdone + \checkscaleboxsettings + % calculators + % beware, they operate in sequence, and calculate missing dimensions / messy + %setscaleboxbynature % when? needed? + \ifconditional\scaleboxscalingdone\else\setscaleboxbyfactor \fi + \ifconditional\scaleboxscalingdone\else\setscaleboxbyscale \fi + \ifconditional\scaleboxscalingdone\else\setscaleboxbydimension\fi + % finalizers / to be done (no longer needed this way, clean up) + \convertscaleboxinsertscale\scaleboxhsize\figx\scaleboxscax\scax + \convertscaleboxinsertscale\scaleboxvsize\figy\scaleboxscay\scay + % used in actual scaling + \xdef\finalscaleboxwidth {\the\scaleboxdimx}% + \xdef\finalscaleboxheight {\the\scaleboxdimy}% + \xdef\finalscaleboxxfactor{\the\scaleboxscax}% + \xdef\finalscaleboxyfactor{\the\scaleboxscay}% + \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}}% + \doifsomething{\scaleparameter\c!maxheight}% can be defined in itself + {\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}}% + \getvalue{\??xy:\c!grid:\scaleparameter\c!grid}} + +\def\setscaleboxbynature % where ! ! ! ! ! + {\doifsomething{\scaleparameter\c!width }{\global\scaleboxdimx\scaleparameter\c!width }% + \doifsomething{\scaleparameter\c!height}{\global\scaleboxdimy\scaleparameter\c!height}% + \doifsomething{\scaleparameter\c!scale } {\scaleboxscax\scaleparameter\c!scale + \scaleboxscay\scaleparameter\c!scale }% + \doifsomething{\scaleparameter\c!xscale} {\scaleboxscax\scaleparameter\c!xscale}% + \doifsomething{\scaleparameter\c!yscale} {\scaleboxscay\scaleparameter\c!yscale}} % oeps, was x + +% \defineexternalfigure[width-6][factor=auto,maxwidth=\textheight,maxheight=\textwidth] +% \defineexternalfigure[width-7][factor=auto,maxwidth=\textwidth,maxheight=\textheight] +% \placefigure{none}{\rotate[frame=on,offset=overlay]{\externalfigure[t:/sources/cow.pdf][width-6]}} \page +% \placefigure{none}{\framed[frame=on,offset=overlay]{\externalfigure[t:/sources/cow.pdf][width-7]}} + +\def\setscaleboxbyfactor + {\doifinsetelse{\scaleparameter\c!factor}{\v!max,\v!fit,\v!broad,\v!auto} + {\doapplyscaleboxsize + \ifdim\scaleboxsizex>\scaleboxsizey + \docalculatescaleboxnorm \scaleboxdimx\c!factor\c!maxwidth\hsize\scaleboxhsize + \docalculatescaleboxscales\scaleboxdimx\scaleboxsizex\scaleboxdimy\scaleboxsizey + \else + \docalculatescaleboxnorm \scaleboxdimy\c!factor\c!maxheight\scaleboxoutervsize\scaleboxvsize + \docalculatescaleboxscales\scaleboxdimy\scaleboxsizey\scaleboxdimx\scaleboxsizex + \fi + \donetrue} + {\doifinsetelse{\scaleparameter\c!hfactor}{\v!max,\v!fit,\v!broad,\v!auto} + {\doapplyscaleboxsize + \docalculatescaleboxnorm \scaleboxdimy\c!hfactor\c!maxheight\scaleboxoutervsize\scaleboxvsize + \docalculatescaleboxscales\scaleboxdimy\scaleboxsizey\scaleboxdimx\scaleboxsizex + \donetrue} + {\doifinsetelse{\scaleparameter\c!wfactor}{\v!max,\v!fit,\v!broad,\v!auto} + {\doapplyscaleboxsize + \docalculatescaleboxnorm \scaleboxdimx\c!wfactor\c!maxwidth\hsize\scaleboxhsize + \docalculatescaleboxscales\scaleboxdimx\scaleboxsizex\scaleboxdimy\scaleboxsizey + \donetrue} + {\docalculatescaleboxnorm\scaleboxdimy\c!factor \c!height \textheight\scaleboxvsize + \docalculatescaleboxnorm\scaleboxdimy\c!hfactor\c!height \textheight\scaleboxvsize + \docalculatescaleboxnorm\scaleboxdimx\c!wfactor\c!width \hsize \hsize + \donefalse}}}% + \ifdone + \settrue\scaleboxscalingdone + \ifdim\scaleboxdimx>\scaleboxhsize + \global\scaleboxdimy\zeropoint \global\scaleboxdimx\scaleboxhsize + \else\ifdim\scaleboxdimy>\scaleboxvsize + \global\scaleboxdimx\zeropoint \global\scaleboxdimy\scaleboxvsize + \fi\fi + \setscaleboxbydimension + \fi} + +\def\setscaleboxbyscale + {\doifsomething{\scaleparameter\c!scale\scaleparameter\c!xscale\scaleparameter\c!yscale} + {\doapplyscaleboxscale\scaleboxdimx\scaleboxsizex\scaleboxscax\c!xscale + \doapplyscaleboxscale\scaleboxdimy\scaleboxsizey\scaleboxscay\c!yscale + \global\scaleboxdimx\zeropoint + \global\scaleboxdimy\zeropoint + \doifelsenothing{\scaleparameter\c!maxwidth} + {\doifsomething{\scaleparameter\c!maxheight} + {\ifdim\scaleboxsizey>\scaleparameter\c!maxheight\relax + \global\scaleboxdimy\scaleparameter\c!maxheight + \fi}} + {\ifdim\scaleboxsizex>\scaleparameter\c!maxwidth\relax + \global\scaleboxdimx\scaleparameter\c!maxwidth + \fi}}} + +\def\setscaleboxbydimension + {\ifdim\scaleboxdimx>\zeropoint + \ifdim\scaleboxdimy>\zeropoint + \dosetdimensionscaleboxsize + {\docalculatescaleboxscale\scaleboxdimy\scaleboxsizey\scaleboxscay + \docalculatescaleboxscale\scaleboxdimx\scaleboxsizex\scaleboxscax}% + {\docalculatescaleboxscale\scaleboxdimy\scaleboxsizey\scaleboxscay + \docalculatescaleboxscale\scaleboxdimx\scaleboxsizex\scaleboxscax}% + {\docalculatescaleboxscale\scaleboxdimy\scaleboxsizey\scaleboxscay + \docalculatescaleboxscale\scaleboxdimx\scaleboxsizex\scaleboxscax}% + \else + \dosetdimensionscaleboxsize + {\docalculatescaleboxscales\scaleboxdimx\scaleboxsizex\scaleboxdimy\scaleboxsizey}% + {\docalculatescaleboxscales\scaleboxdimx\scaleboxsizex\scaleboxdimy\scaleboxsizey}% + {\docalculatescaleboxscales\scaleboxdimx\scaleboxsizex\scaleboxdimy\scaleboxsizey}% + \fi + \else + \ifdim\scaleboxdimy>\zeropoint + \dosetdimensionscaleboxsize + {\docalculatescaleboxscales\scaleboxdimy\scaleboxsizey\scaleboxdimx\scaleboxsizex}% + {\docalculatescaleboxscales\scaleboxdimy\scaleboxsizey\scaleboxdimx\scaleboxsizex}% + {\docalculatescaleboxscales\scaleboxdimy\scaleboxsizey\scaleboxdimx\scaleboxsizex}% + \else + \dosetdimensionscaleboxsize + {\doapplyscaleboxscale\scaleboxdimx\scaleboxsizex\scaleboxscax\c!xscale + \doapplyscaleboxscale\scaleboxdimy\scaleboxsizey\scaleboxscay\c!yscale}% + {\docalculatescaleboxscales\scaleboxdimx\scaleboxsizex\scaleboxdimy\scaleboxsizey}% + {\docalculatescaleboxscales\scaleboxdimy\scaleboxsizey\scaleboxdimx\scaleboxsizex}% + \fi + \fi} + +\def\dosetdimensionscaleboxsize#1#2#3% + {#1\relax + \doifsomething{\scaleparameter\c!maxwidth} + {\ifdim\scaleboxdimx>\scaleparameter\c!maxwidth\relax + \global\scaleboxdimx\scaleparameter\c!maxwidth + #2\relax + \fi}% + \doifsomething{\scaleparameter\c!maxheight} + {\ifdim\scaleboxdimy>\scaleparameter\c!maxheight\relax + \global\scaleboxdimy\scaleparameter\c!maxheight + #3\relax + \fi}} + +\def\docalculatescaleboxnorm#1#2#3#4#5% 2 3 parameters (dodo:speedup) + {\processaction + [\scaleparameter#2] + [ \v!max=>\global#1\dimexpr#4\relax, + \v!fit=>\global#1\dimexpr#5\relax, + \v!broad=>\global#1\dimexpr#5-4\@@exbodyfont\relax, + \v!auto=>\doifsomething{\scaleparameter#3}{\global#1\dimexpr\scaleparameter#3\relax}, + \s!default=>\doifsomething{\scaleparameter#3}{\global#1\dimexpr\scaleparameter#3\relax}, + \s!unknown=>\global#1\dimexpr\scaleparameter#2\dimexpr\@@exbodyfont/10\relax\relax]} + +\def\docalculatescaleboxscales#1#2#3#4% + {\scratchdimen\dimexpr#1/\dimexpr#2/\plusthousand\relax\relax + \scaleboxscax\scratchdimen + \scaleboxscay\scratchdimen + #3\dimexpr\scaleboxscax\dimexpr#4/\plusthousand\relax\relax} + +\def\docalculatescaleboxscale#1#2#3% + {#3\dimexpr#1/\dimexpr#2/\plusthousand\relax\relax} + +\def\doapplyscaleboxscale#1#2#3#4% $4 = parameter / scale can be empty + {\ifcase0\scaleparameter#4\relax + \ifcase0\scaleparameter\c!scale\relax + #3=\plusthousand + \else + #3=\scaleparameter\c!scale + \fi + \else + #3=\scaleparameter#4% + \fi + \relax % important ! still ? + \global#1\ifnum#3=\plusthousand#2\else\dimexpr#3\dimexpr#2/\plusthousand\relax\relax\fi + \relax} + +\def\doapplyscaleboxsize + {\doifelsenothing{\scaleparameter\c!maxheight} + {\scaleboxoutervsize\textheight + \ifinner + \scaleboxoutervsize \vsize % \textheight =\vsize + \scratchdimen\vsize % \scratchdimen=\textheight + \else\ifinsidefloat + \scaleboxoutervsize \vsize % \textheight =\vsize + \scratchdimen\vsize % \scratchdimen=\textheight + \else\ifinpagebody + \scaleboxoutervsize \vsize % \textheight =\vsize + \scratchdimen\vsize % \scratchdimen=\textheight + \else % hm, there should be an option to force this + \ifdim\pagegoal<\maxdimen + \ifdim\pagetotal<\pagegoal + \scratchdimen\dimexpr\pagegoal-\pagetotal\relax + \else + \scratchdimen\scaleboxoutervsize % \textheight + \fi + \else + \scratchdimen\scaleboxoutervsize % \textheight + \fi + \fi\fi\fi} + {\scratchdimen\scaleparameter\c!maxheight + \scaleboxoutervsize\scratchdimen}% + \doifelsenothing{\scaleparameter\c!height} + {\scaleboxvsize\scratchdimen} + {\scaleboxvsize\scaleparameter\c!height}% + \doifelsenothing{\scaleparameter\c!width} + {\scaleboxhsize\hsize} + {\scaleboxhsize\scaleparameter\c!width}} + +\def\convertscaleboxinsertscale#1#2#3#4% + {\scratchdimen#1\relax + \ifnum#3=\plusthousand + % == scale 1 + \else + % better 1000 100 10 ranges, evt round 2sp + \divide\scratchdimen \plusthousand + \multiply\scratchdimen #3\relax + \fi + \scratchdimen-\scratchdimen % beter hier - dan in driver + \edef#2{\the\scratchdimen}% + \scratchcounter#3\relax + \ifnum\scratchcounter>\plustenthousand + \divide\scratchcounter\!!ten \scratchdimen\the\scratchcounter\points + \else + \scratchdimen\the\scratchcounter\points \divide\scratchdimen\!!ten + \fi + \edef#4{\withoutpt\the\scratchdimen}} + +% \startcombination +% {\externalfigure[cow.pdf] [frame=on,height=3cm,equalwidth=6cm]} {} +% {\externalfigure[mill.png][frame=on,height=3cm,equalwidth=6cm]} {} +% \stopcombination + +\def\doscaleboxposition + {\doifsomething{\scaleparameter\c!equalwidth} + {\scratchdimen\scaleparameter\c!equalwidth\relax + \ifdim\wd\nextbox<\scratchdimen + \setbox\nextbox\hbox to \scratchdimen{\hss\box\nextbox\hss}% + \fi}% + \doifsomething{\scaleparameter\c!equalheight} + {\scratchdimen\scaleparameter\c!equalheight\relax + \ifdim\ht\nextbox<\scratchdimen + \setbox\nextbox\vbox to \scratchdimen{\vss\box\nextbox\vss}% + \fi}} + +%D \macros +%D {clip, setupclipping} +%D +%D Although related to figures, clipping can be applied to +%D arbitrary content. We can use \METAPOST\ to provide a non +%D rectangular clipping path. +%D +%D \starttyping +%D \startMPclip{fun} +%D clip currentpicture to fullcircle +%D shifted (.5,.5) xscaled \width yscaled \height ; +%D \stopMPclip +%D \stoptyping +%D +%D We get a rectangular piece of the figure when we say: +%D +%D \starttyping +%D \clip[x=2,y=1]{\externalfigure[photo]} +%D \stoptyping +%D +%D When we want to clip to the oval we defined a few lines ago, +%D we say: +%D +%D \starttyping +%D \clip[nx=1,ny=1,x=1,y=1,mp=fun]{\externalfigure[photo]} +%D \stoptyping +%D +%D The general characteristics of clipping can be set up with +%D +%D \showsetup{setupclipping} + +\unexpanded\def\setupclipping + {\dodoubleargument\getparameters[\??cp]} + +\def\clip + {\dosingleempty\doclip} + +\def\doclip[#1]% nb top->bottom left->right + {\bgroup + \getparameters[\??cp][#1]% + \doifelse\@@cpstate\v!start\dodoclip{\egroup\hbox}} + +\def\dodoclip + {\dowithnextbox + {\ifdim\@@cpwidth>\zeropoint + \!!dimena\@@cpwidth + \!!dimenc\@@cphoffset + \else + \!!dimena\nextboxwd + \divide\!!dimena \@@cpnx + \!!dimenc\@@cpx\!!dimena + \advance\!!dimenc -\!!dimena + \!!dimena\@@cpsx\!!dimena + \fi + \relax % sure + \ifdim\@@cpheight>\zeropoint + \!!dimenb\@@cpheight + \!!dimend\nextboxht + \advance\!!dimend -\@@cpvoffset + \advance\!!dimend -\!!dimenb + \else + \!!dimenb\nextboxht + \divide\!!dimenb \@@cpny + \!!dimend-\@@cpy\!!dimenb + \advance\!!dimend -\@@cpsy\!!dimenb + \advance\!!dimend \!!dimenb + \!!dimenb\@@cpsy\!!dimenb + \advance\!!dimend \nextboxht % dimend ! + \fi + \setbox\nextbox\hbox % old + {\advance\!!dimenc -\@@cpleftoffset % new ! + \advance\!!dimend -\@@cpbottomoffset % new ! % - added + \hskip-\!!dimenc\lower\!!dimend\flushnextbox}% old + \nextboxwd\zeropoint + \nextboxht\zeropoint + \nextboxdp\zeropoint + \setbox\nextbox\hbox + {\advance\!!dimena \@@cpleftoffset % new ! + \advance\!!dimena \@@cprightoffset % new ! + \advance\!!dimenb \@@cpbottomoffset % new ! + \advance\!!dimenb \@@cptopoffset % new ! + \dostartclipping\@@cpmp\!!dimena\!!dimenb % old + \flushnextbox + \dostopclipping}% + \setbox\nextbox\hbox % new ! + {\!!dimena-\@@cpleftoffset % new ! + \!!dimenb \@@cpbottomoffset % new ! % - removed + \hskip\!!dimena\lower\!!dimenb\flushnextbox}% new ! + \nextboxwd\!!dimena + \nextboxht\!!dimenb + \nextboxdp\zeropoint + \flushnextbox + \egroup}% + \hbox} + +\setupclipping + [\c!state=\v!start, + \c!n=1, % was 2 + \c!nx=\@@cpn,\c!x=1,\c!sx=1, + \c!ny=\@@cpn,\c!y=1,\c!sy=1, + \c!width=\!!zeropoint, + \c!height=\!!zeropoint, + \c!hoffset=\!!zeropoint, + \c!voffset=\!!zeropoint, + \c!offset=\zeropoint, + \c!leftoffset=\@@cpoffset, % \zeropoint, + \c!rightoffset=\@@cpoffset, % \zeropoint, + \c!topoffset=\@@cpoffset, % \zeropoint, + \c!bottomoffset=\@@cpoffset,% \zeropoint, + \c!mp=] + +%D \startbuffer +%D \startuseMPgraphic{test} +%D path p ; p := fullcircle scaled 4cm ; +%D draw p withpen pencircle scaled 1cm ; +%D setbounds currentpicture to boundingbox p ; +%D \stopuseMPgraphic +%D +%D \hbox to \hsize \bgroup +%D \hss +%D \ruledhbox{\useMPgraphic{test}}% +%D \hss +%D \ruledhbox{\clip{\useMPgraphic{test}}}% +%D \hss +%D \egroup +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +%D Mirroring. + +\def\domirrorbox % \hbox/\vbox/\vtop + {\bgroup + \dowithnextbox + {\dontshowcomposition + \scratchdimen\nextboxwd + % better use an hbox (if no \forgetall, leftskip etc may creep in) + %\setbox\nextbox\vbox{\forgetall\dostartmirroring\hskip-\nextboxwd\flushnextbox\dostopmirroring}% + \setbox\nextbox\hbox{\dostartmirroring\hskip-\nextboxwd\flushnextbox\dostopmirroring}% + \nextboxwd\scratchdimen + \flushnextbox + \egroup}} + +\unexpanded\def\mirror + {\domirrorbox\hbox} + +% \setbox0=\hbox{gans} +% \ruledhbox{\copy0 \schaal[sx=2,sy=2]{\copy0}} +% \mirror{\ruledhbox{\copy0 \schaal{\box0}}} + +\protect \endinput diff --git a/tex/context/base/grph-u3d.lua b/tex/context/base/grph-u3d.lua new file mode 100644 index 000000000..f3bf17631 --- /dev/null +++ b/tex/context/base/grph-u3d.lua @@ -0,0 +1,49 @@ +if not modules then modules = { } end modules ['grph-u3d'] = { + version = 1.001, + comment = "companion to grph-inc.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- see lpdf-u3d.lua for comment + +local trace_inclusion = false trackers.register("figures.inclusion", function(v) trace_inclusion = v end) + +local pdfannotation = nodes.pdfannotation +local todimen = string.todimen + +-- maybe todo: backends.codeinjections.insertu3d + +function figures.checkers.u3d(data) + local dr, du, ds = data.request, data.used, data.status + local width = todimen(dr.width or figures.defaultwidth) + local height = todimen(dr.height or figures.defaultheight) + local foundname = du.fullname + dr.width, dr.height = width, height + du.width, du.height, du.foundname = width, height, foundname + if trace_inclusion then + logs.report("figures","including u3d '%s': width %s, height %s",foundname,width,height) + end + context.startfoundexternalfigure(width .. "sp",height .. "sp") + context(function() + local annotation, preview, ref = backends.pdf.helpers.insert3d { + foundname = foundname, + width = width, + height = height, + factor = number.dimenfactors.bp, + display = dr.display, + controls = dr.controls, + label = dr.label, + } +--~ print(annotation, preview, ref) + node.write(pdfannotation(width,height,0,annotation())) + end) + context.stopfoundexternalfigure() + return data +end + +figures.includers.u3d = figures.includers.nongeneric + +figures.registersuffix("u3d","u3d") +figures.registersuffix("prc","u3d") diff --git a/tex/context/base/hand-def.mkii b/tex/context/base/hand-def.mkii new file mode 100644 index 000000000..0a19ce270 --- /dev/null +++ b/tex/context/base/hand-def.mkii @@ -0,0 +1,577 @@ +%D \module +%D [ file=hand-def, % was enco-pro +%D version=2000.29.09, +%D title=\CONTEXT\ Handling Macros, +%D subtitle=Default Protruding Factors, +%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 This is an experimental definition file. The protruding +%D values we use here are those found from \THANH's thesis. + +\startfonthandling [pure] + + \defineprotrudefactor , 0 1 + \defineprotrudefactor . 0 1 + \defineprotrudefactor : 0 1 + \defineprotrudefactor ; 0 1 + \defineprotrudefactor - 0 1 + + \defineprotrudefactor hyphen 0 1 + \defineprotrudefactor endash 0 .5 + \defineprotrudefactor emdash 0 .33 % .5 + +\stopfonthandling + +\startfonthandling [punctuation] + + \defineprotrudefactor ! 0 .2 + \defineprotrudefactor ' 0 .7 + \defineprotrudefactor ` .7 0 + \defineprotrudefactor ( .05 0 + \defineprotrudefactor ) 0 .05 + \defineprotrudefactor [ .05 0 + \defineprotrudefactor ] 0 .05 + \defineprotrudefactor , 0 .7 + \defineprotrudefactor - 0 .7 + \defineprotrudefactor . 0 .7 + \defineprotrudefactor : 0 .5 + \defineprotrudefactor ; 0 .5 + + \defineprotrudefactor rightupperninequote 0 .5 + \defineprotrudefactor leftupperninequote .5 0 + \defineprotrudefactor endash 0 .3 + \defineprotrudefactor emdash 0 .2 + + \defineprotrudefactor hyphen 0 .7 + +\stopfonthandling + +\startfonthandling [alpha] + + \defineprotrudefactor A .05 .05 + \defineprotrudefactor F 0 .05 + \defineprotrudefactor J .05 0 + \defineprotrudefactor K 0 .05 + \defineprotrudefactor L 0 .05 + \defineprotrudefactor T .05 .05 + \defineprotrudefactor V .05 .05 + \defineprotrudefactor W .05 .05 + \defineprotrudefactor X .05 .05 + \defineprotrudefactor Y .05 .05 + + \defineprotrudefactor k 0 .05 + \defineprotrudefactor r 0 .05 + \defineprotrudefactor t 0 .05 + \defineprotrudefactor v .05 .05 + \defineprotrudefactor w .05 .05 + \defineprotrudefactor x .05 .05 + \defineprotrudefactor y .05 .05 + +\stopfonthandling + +% ogoneks may need another treatment + +\startfonthandling [extended] + + \inherithandling Acircumflex A + \inherithandling acircumflex a + \inherithandling Ccircumflex C + \inherithandling ccircumflex c + \inherithandling Ecircumflex E + \inherithandling ecircumflex e + \inherithandling Gcircumflex G + \inherithandling gcircumflex g + \inherithandling Hcircumflex H + \inherithandling hcircumflex h + \inherithandling Icircumflex I + \inherithandling icircumflex i + \inherithandling Jcircumflex J + \inherithandling jcircumflex j + \inherithandling Ocircumflex O + \inherithandling ocircumflex o + \inherithandling Scircumflex S + \inherithandling scircumflex s + \inherithandling Ucircumflex U + \inherithandling ucircumflex u + \inherithandling Wcircumflex W + \inherithandling wcircumflex w + \inherithandling Ycircumflex Y + \inherithandling ycircumflex y + + \inherithandling Agrave A + \inherithandling agrave a + \inherithandling Egrave E + \inherithandling egrave e + \inherithandling Igrave I + \inherithandling igrave i + \inherithandling Ograve O + \inherithandling ograve o + \inherithandling Ugrave U + \inherithandling ugrave u + \inherithandling Ygrave Y + \inherithandling ygrave y + + \inherithandling Atilde A + \inherithandling atilde a + \inherithandling Itilde I + \inherithandling itilde i + \inherithandling Ntilde N + \inherithandling ntilde n + \inherithandling Otilde O + \inherithandling otilde o + \inherithandling Utilde U + \inherithandling utilde u + + \inherithandling Adiaeresis A + \inherithandling adiaeresis a + \inherithandling Ediaeresis E + \inherithandling ediaeresis e + \inherithandling Idiaeresis I + \inherithandling idiaeresis i + \inherithandling Odiaeresis O + \inherithandling odiaeresis o + \inherithandling Udiaeresis U + \inherithandling udiaeresis u + \inherithandling Ydiaeresis Y + \inherithandling ydiaeresis y + + \inherithandling Aacute A + \inherithandling aacute a + \inherithandling Cacute C + \inherithandling cacute c + \inherithandling Eacute E + \inherithandling eacute e + \inherithandling Iacute I + \inherithandling iacute i + \inherithandling Lacute L + \inherithandling lacute l + \inherithandling Nacute N + \inherithandling nacute n + \inherithandling Oacute O + \inherithandling oacute o + \inherithandling Racute R + \inherithandling racute r + \inherithandling Sacute s + \inherithandling sacute s + \inherithandling Uacute U + \inherithandling uacute u + \inherithandling Yacute Y + \inherithandling yacute y + \inherithandling Zacute Z + \inherithandling zacute z + + \inherithandling Dstroke D + \inherithandling dstroke d + \inherithandling Hstroke H + \inherithandling hstroke h + \inherithandling Tstroke T + \inherithandling tstroke t + + \inherithandling Cdotaccent C + \inherithandling cdotaccent c + \inherithandling Edotaccent E + \inherithandling edotaccent e + \inherithandling Gdotaccent G + \inherithandling gdotaccent g + \inherithandling Idotaccent I + \inherithandling idotaccent i + \inherithandling Zdotaccent Z + \inherithandling zdotaccent z + + \inherithandling Amacron A + \inherithandling amacron a + \inherithandling Emacron E + \inherithandling emacron e + \inherithandling Imacron I + \inherithandling imacron i + \inherithandling Omacron O + \inherithandling omacron o + \inherithandling Umacron U + \inherithandling umacron u + + \inherithandling Ccedilla C + \inherithandling ccedilla c + \inherithandling Kcedilla K + \inherithandling kcedilla k + \inherithandling Lcedilla L + \inherithandling lcedilla l + \inherithandling Ncedilla N + \inherithandling ncedilla n + \inherithandling Rcedilla R + \inherithandling rcedilla r + \inherithandling Scedilla S + \inherithandling scedilla s + \inherithandling Tcedilla T + \inherithandling tcedilla t + + \inherithandling Ohungarumlaut O + \inherithandling ohungarumlaut o + \inherithandling Uhungarumlaut U + \inherithandling uhungarumlaut u + + \inherithandling Aogonek A + \inherithandling aogonek a + \inherithandling Eogonek E + \inherithandling eogonek e + \inherithandling Iogonek I + \inherithandling iogonek i + \inherithandling Uogonek U + \inherithandling uogonek u + + \inherithandling Aring A + \inherithandling aring a + \inherithandling Uring U + \inherithandling uring u + + \inherithandling Abreve A + \inherithandling abreve a + \inherithandling Ebreve E + \inherithandling ebreve e + \inherithandling Gbreve G + \inherithandling gbreve g + \inherithandling Ibreve I + \inherithandling ibreve i + \inherithandling Obreve O + \inherithandling obreve o + \inherithandling Ubreve U + \inherithandling ubreve u + + \inherithandling Ccaron C + \inherithandling ccaron c + \inherithandling Dcaron D + \inherithandling dcaron d + \inherithandling Ecaron E + \inherithandling ecaron e + \inherithandling Lcaron L + \inherithandling lcaron l + \inherithandling Ncaron N + \inherithandling ncaron n + \inherithandling Rcaron R + \inherithandling rcaron r + \inherithandling Scaron S + \inherithandling scaron s + \inherithandling Tcaron T + \inherithandling tcaron t + \inherithandling Ycaron Y + \inherithandling ycaron y + \inherithandling Zcaron Z + \inherithandling zcaron z + + \inherithandling AEligature E + \inherithandling aeligature e + \inherithandling Lstroke I + \inherithandling lstroke o + \inherithandling Ostroke O + \inherithandling ostroke o + \inherithandling OEligature O + \inherithandling oeligature o + + \inherithandling Ssharp S + \inherithandling ssharp s + \inherithandling IJligature J + \inherithandling ijligature j + + \inherithandling aumlaut a + \inherithandling eumlaut e + \inherithandling iumlaut i + \inherithandling oumlaut o + \inherithandling uumlaut u + + \inherithandling Aumlaut A + \inherithandling Eumlaut E + \inherithandling Iumlaut I + \inherithandling Oumlaut O + \inherithandling Uumlaut U + + \inherithandling Lslash L + \inherithandling lslash l + \inherithandling Dslash D + \inherithandling dslash d + \inherithandling Oslash O + \inherithandling oslash o + + \inherithandling Eszett S + \inherithandling eszett s + + \inherithandling Thorn P + \inherithandling thorn p + + % vietnamese + + \inherithandling Ahook A + \inherithandling ahook a + \inherithandling Ehook E + \inherithandling ehook e + \inherithandling Ihook I + \inherithandling ihook i + \inherithandling Ohook O + \inherithandling ohook o + \inherithandling Uhook U + \inherithandling uhook u + \inherithandling Yhook Y + \inherithandling yhook y + + \inherithandling Acircumflexgrave A + \inherithandling Acircumflexacute A + \inherithandling Acircumflextilde A + \inherithandling Acircumflexhook A + \inherithandling acircumflexgrave a + \inherithandling acircumflexacute a + \inherithandling acircumflextilde a + \inherithandling acircumflexhook a + \inherithandling Ecircumflexgrave E + \inherithandling Ecircumflexacute E + \inherithandling Ecircumflextilde E + \inherithandling Ecircumflexhook E + \inherithandling ecircumflexgrave e + \inherithandling ecircumflexacute e + \inherithandling ecircumflextilde e + \inherithandling ecircumflexhook e + \inherithandling Ocircumflexgrave O + \inherithandling Ocircumflexacute O + \inherithandling Ocircumflextilde O + \inherithandling Ocircumflexhook O + \inherithandling ocircumflexgrave o + \inherithandling ocircumflexacute o + \inherithandling ocircumflextilde o + \inherithandling ocircumflexhook o + + \inherithandling Abrevegrave A + \inherithandling Abreveacute A + \inherithandling Abrevetilde A + \inherithandling Abrevehook A + \inherithandling abrevegrave a + \inherithandling abreveacute a + \inherithandling abrevetilde a + \inherithandling abrevehook a + + \inherithandling Adotbelow A + \inherithandling adotbelow a + \inherithandling Edotbelow E + \inherithandling edotbelow e + \inherithandling Idotbelow I + \inherithandling idotbelow i + \inherithandling Odotbelow O + \inherithandling odotbelow o + \inherithandling Udotbelow U + \inherithandling udotbelow u + \inherithandling Ydotbelow Y + \inherithandling ydotbelow y + + \inherithandling Ohorndotbelow O + \inherithandling ohorndotbelow o + \inherithandling Uhorndotbelow U + \inherithandling uhorndotbelow u + + \inherithandling Acircumflexdotbelow A + \inherithandling acircumflexdotbelow a + \inherithandling Ecircumflexdotbelow E + \inherithandling ecircumflexdotbelow e + \inherithandling Ocircumflexdotbelow O + \inherithandling ocircumflexdotbelow o + + \inherithandling Abrevedotbelow A + \inherithandling abrevedotbelow a + + \inherithandling Ohorn O + \inherithandling Ohorngrave O + \inherithandling Ohornacute O + \inherithandling Ohorntilde O + \inherithandling Ohornhook O + \inherithandling ohorn o + \inherithandling ohorngrave o + \inherithandling ohornacute o + \inherithandling ohorntilde o + \inherithandling ohornhook o + \inherithandling Uhorn U + \inherithandling Uhorngrave U + \inherithandling Uhornacute U + \inherithandling Uhorntilde U + \inherithandling Uhornhook U + \inherithandling uhorn u + \inherithandling uhorngrave u + \inherithandling uhornacute u + \inherithandling uhorntilde u + \inherithandling uhornhook u + + \inherithandling Ytilde Y + \inherithandling ytilde y + \inherithandling Etilde E + \inherithandling etilde e + +\stopfonthandling + +\startfonthandling [hz] + + \defineadjustfactor A .5 + \defineadjustfactor B .7 + \defineadjustfactor C .7 + \defineadjustfactor D .5 + \defineadjustfactor E .7 + \defineadjustfactor F .7 + \defineadjustfactor G .5 + \defineadjustfactor H .7 + \defineadjustfactor K .7 + \defineadjustfactor M .7 + \defineadjustfactor N .7 + \defineadjustfactor O .5 + \defineadjustfactor P .7 + \defineadjustfactor Q .5 + \defineadjustfactor R .7 + \defineadjustfactor S .7 + \defineadjustfactor U .7 + \defineadjustfactor W .7 + \defineadjustfactor Z .7 + + \defineadjustfactor a .7 + \defineadjustfactor b .7 + \defineadjustfactor c .7 + \defineadjustfactor d .7 + \defineadjustfactor e .7 + \defineadjustfactor g .7 + \defineadjustfactor h .7 + \defineadjustfactor k .7 + \defineadjustfactor m .7 + \defineadjustfactor n .7 + \defineadjustfactor o .7 + \defineadjustfactor p .7 + \defineadjustfactor q .7 + \defineadjustfactor s .7 + \defineadjustfactor u .7 + \defineadjustfactor w .7 + \defineadjustfactor z .7 + + \defineadjustfactor 2 .7 + \defineadjustfactor 3 .7 + \defineadjustfactor 6 .7 + \defineadjustfactor 8 .7 + \defineadjustfactor 9 .7 + +% \defineadjustfactor hyphen ? +% \defineadjustfactor endash ? +% \defineadjustfactor emdash ? + +\stopfonthandling + +% no ligs other than fi fl etc, no --- and '' + +\startfonthandling[noligs] + + \settagcode - {\notagcode} + \settagcode ' {\notagcode} + \settagcode ` {\notagcode} + \settagcode ? {\notagcode} + \settagcode ! {\notagcode} + +\stopfonthandling + +% \startfonthandling[noligs] +% \dostepwiserecurse{0}{255}{1}{\expanded{\settagcode \recurselevel\space\notagcode\space}} +% \stopfonthandling + +% \definefonthandling [noligs] [noligs] [type=tag] + % \setupfontsynonym[Serif][handling=noligs] +% \definefont[test][Serif at 12.34pt] +% +% {``fi--ffl---ffi'' \test ``fi--ffl---ffi''} + +\unprotect + +% beware: extended extends the preceding vector (both protruding and +% adjusting) but as long as the normal ascii characters are not set +% beforehand, they default to normal + +% protruding variants -- slanted/italic is yet incomplete + +\definefonthandling [pure] [pure] [\c!type=\v!hanging] +\definefonthandling [purebold] [pure] [\c!type=\v!hanging] +\definefonthandling [pureslanted] [pure] [\c!type=\v!hanging,\c!right=1.5] +\definefonthandling [pureitalic] [pure] [\c!type=\v!hanging,\c!right=1.5] +\definefonthandling [pureboldslanted] [pure] [\c!type=\v!hanging,\c!right=1.5] +\definefonthandling [purebolditalic] [pure] [\c!type=\v!hanging,\c!right=1.5] + +\definefonthandling [normal] [punctuation,alpha,extended] [\c!type=\v!hanging] +\definefonthandling [normalbold] [punctuation,alpha,extended] [\c!type=\v!hanging] +\definefonthandling [normalslanted] [punctuation,alpha,extended] [\c!type=\v!hanging,\c!right=1.5] +\definefonthandling [normalitalic] [punctuation,alpha,extended] [\c!type=\v!hanging,\c!right=1.5] +\definefonthandling [normalboldslanted] [punctuation,alpha,extended] [\c!type=\v!hanging,\c!right=1.5] +\definefonthandling [normalbolditalic] [punctuation,alpha,extended] [\c!type=\v!hanging,\c!right=1.5] + +% for old times sake + +\definefonthandling [bold] [punctuation,alpha,extended] [\c!type=\v!hanging] +\definefonthandling [slanted] [punctuation,alpha,extended] [\c!type=\v!hanging,\c!right=1.5] +\definefonthandling [italic] [punctuation,alpha,extended] [\c!type=\v!hanging,\c!right=1.5] +\definefonthandling [boldslanted] [punctuation,alpha,extended] [\c!type=\v!hanging,\c!right=1.5] +\definefonthandling [bolditalic] [punctuation,alpha,extended] [\c!type=\v!hanging,\c!right=1.5] + +% hz variants + +\definefonthandling [hz] [hz,extended] [\c!type=\v!hz] % min=20 max=20 step=5 + +% combined variants + +\definefonthandling [quality] [hz,pure] +\definefonthandling [highquality] [hz,normal] + +% noligs (xml) : \definefonthandling [default] [noligs] + +\definefonthandling [noligs] [noligs] [\c!type=tag] + +% experimental values ! +% +% \definefontsynonym[myfont][Serif][handling=prespacing] +% \definefont[whatever][myfont sa 1] +% \setupalign[spacing] +% +% \whatever look at this: we now have a proper spacing feature and, hurray, +% get rid of active punctuation! + +\startfonthandling [flexspacing] + + \definespacefactor : 0 1.25 .25 .25 + + \definespacefactor , 0 1 .25 .25 + \inheritspacefactor ; , + + \definespacefactor . 0 1.5 .25 .25 + \inheritspacefactor ! . + \inheritspacefactor ? . + +\stopfonthandling + +\definefonthandling[flexspacing][flexspacing][\c!type=\v!spacing] + +\startfonthandling [prespacing] % better name needed + + \definespacefactor : .25 .25 0 0 + \inheritspacefactor ; : + \inheritspacefactor ! : + \inheritspacefactor ? : + +\stopfonthandling + +\definefonthandling[prespacing][prespacing][\c!type=\v!spacing] % factor=.5 + +% A special case of guillemots, beware: when used ungrouped, +% it overloads all successive (current) encoding vector +% instances! Will be obsolete soon. + +\startfonthandling [glm] + + \overloadcharacter guilsingleleft {\defaultcharacter\guilsingleleft } + \overloadcharacter guilsingleright {\defaultcharacter\guilsingleright} + \overloadcharacter leftguillemot {\defaultcharacter\leftguillemot } + \overloadcharacter rightguillemot {\defaultcharacter\rightguillemot } + +\stopfonthandling + +\definefonthandling [glm] [glm] + +\protect \endinput diff --git a/tex/context/base/hand-ini.mkii b/tex/context/base/hand-ini.mkii new file mode 100644 index 000000000..ac8a94696 --- /dev/null +++ b/tex/context/base/hand-ini.mkii @@ -0,0 +1,483 @@ +%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. + +%D {\em This module is experimental and implements font +%D specific features, like hanging punctuation.} + +\unprotect + +\newif\iftracefonthandling % \tracefonthandlingtrue + +\newif\ifskiphandlingdef \skiphandlingdeffalse + +\newtoks\everyenablefonthandling + +% much in common with hz/protruding defs +% todo: fix others + +\def\dosetsomehandling#1#2#3 #4 % no define since directly set + {\ifskiphandlingdef \else + \doifnumberelse{\string#2} + {#1{#2#3}{#4}} + {\doifelsenothing{#3} + {#1{`#2}{#4}} + {\let\char\empty + \doifnumberelse{\csname#2#3\endcsname}{#1{\csname#2#3\endcsname}{#4}}\donothing + \let\char\normalchar}}% + \fi} + +\def\dosetpairhandling#1#2#3 #4 #5 % no define since directly set + {\ifskiphandlingdef \else + \doifnumberelse{\string#2} + {#1{#2#3}{#4}{#5}} + {\doifelsenothing{#3} + {#1{`#2}{#4}{#5}} + {\let\char\empty + \doifnumberelse{\csname#2#3\endcsname}{#1{\csname#2#3\endcsname}{#4}{#5}}\donothing + \let\char\normalchar}}% + \fi} + +\def\dosetquartethandling#1#2#3 #4 #5 #6 #7 % no define since directly set + {\ifskiphandlingdef \else + \doifnumberelse{\string#2} + {#1{#2#3}{#4}{#5}{#6}{#7}} + {\doifelsenothing{#3} + {#1{`#2}{#4}{#5}{#6}{#7}} + {\let\char\empty + \doifnumberelse{\csname#2#3\endcsname}{#1{\csname#2#3\endcsname}{#4}{#5}{#6}{#7}}\donothing + \let\char\normalchar}}% + \fi} + +\def\doinhsomehandling#1#2#3 #4 % to be checked + {\ifskiphandlingdef \else + \if#3\relax\relax + #1{`#2}{`#4}% + \else + \let\char\empty + \doifnumberelse{\csname#2#3\endcsname}{#1{\csname#2#3\endcsname}{`#4}}\donothing + \let\char\normalchar + \fi + \fi} + +% adjustspacing + +\newdimen\adjustdimen \let\handledfont\font + +\ifx\undefined\pdfadjustspacing % we don't use pdftex + + \let\enableadjusting \relax + \let\disableadjusting \relax + \let\setadjusting \gobbletwoarguments + + \def\defineadjustfactor #1 #2 {} + \def\inheritadjustfactor #1 #2 {} + + \let\setfontadjusting \gobbleoneargument + +\else + + \def\enableadjusting {\pdfadjustspacing\plustwo} + \def\disableadjusting {\pdfadjustspacing\zerocount} + + \appendtoks \disableadjusting \to \everyforgetall % Here or not here? + + \def\dododefineadjustfactor#1#2% + {\efcode\handledfont#1\dimexpr#2\onepoint*\plusthousand/\maxcard\relax} + + \def\dodoinheritadjustfactor#1#2% + {\efcode\handledfont#1\efcode\handledfont#2\relax} + + \def\defineadjustfactor#1 #2 % + {\setfonttoks + \let\inherithandling\inheritadjustfactor + \appendtoks\dosetsomehandling\dododefineadjustfactor#1 #2 \to\fonttoks} + + \def\inheritadjustfactor#1 #2 % + {\setfonttoks + \appendtoks\doinhsomehandling\dodoinheritadjustfactor#1 #2 \to\fonttoks} + + \ifnum\pdftexversion<120 + \let\@@pdfexpandbonus\plusthousand + \else + \def\@@pdfexpandbonus{autoexpand}% + \fi + + \def\setfontadjusting#1% + {\doifvalue{\@fha@\@fha@#1\c!type}\v!hz{\dosetfontadjusting{#1}}} + + \def\dosetfontadjusting#1% + {\iftracefonthandling\showfontadjusting{#1}\fi + \pdffontexpand\handledfont + \csname\@fha@\@fha@#1\c!max \endcsname\space + \csname\@fha@\@fha@#1\c!min \endcsname\space + \csname\@fha@\@fha@#1\c!step\endcsname\space + \@@pdfexpandbonus\relax} + + \def\showfontadjusting#1% + {\writestatus\m!handlings{[adjust]\space#1\space + \csname\@fha@\@fha@#1\c!max \endcsname/% + \csname\@fha@\@fha@#1\c!min \endcsname/% + \csname\@fha@\@fha@#1\c!step\endcsname\space + \fontname\handledfont}} +\fi + +\ifx\setfontadjusting\gobbleoneargument \else + \appendtoks + \setfontadjusting\askedfonthandling + \to \everyenablefonthandling +\fi + +% protruding + +\newif\ifembasedprotruding \embasedprotrudingfalse + +\newdimen\lproddimen \newdimen\rproddimen \let\handledfont\font + +\ifx\undefined\pdfprotrudechars % we don't use pdftex + + \let\enableprotruding \relax + \let\disableprotruding \relax + \let\setprotrudingfactor \gobbleoneargument + + \def\defineprotrudefactor #1 #2 #3 {} + \def\inheritprotrudefactor #1 #2 {} + +\else + + \def\enableprotruding {\pdfprotrudechars\plustwo} + \def\disableprotruding{\pdfprotrudechars\zerocount} + + \appendtoks \disableprotruding \to \everyforgetall % Here or not here? + + \lproddimen1000\onepoint \divide\lproddimen\maxcard + \rproddimen1000\onepoint \divide\rproddimen\maxcard + + \def\setprotrudingfactor#1% + {\doifvalue{\@fha@\@fha@#1\c!type}\v!hanging{\dosetprotrudingfactor{#1}}} + + \def\dosetprotrudingfactor#1% no \onepoint instead of pt + {\lproddimen\dimexpr\csname\@fha@\@fha@#1\c!left \endcsname\onepoint*\plusthousand/\maxcard\relax + \rproddimen\dimexpr\csname\@fha@\@fha@#1\c!right\endcsname\onepoint*\plusthousand/\maxcard\relax + \iftracefonthandling\showprotrudingfactor{#1}\fi} + + \def\showprotrudingfactor#1% + {\writestatus\m!handlings{[protrude]\space#1\space + \csname\@fha@\@fha@#1\c!left \endcsname\space + \csname\@fha@\@fha@#1\c!right\endcsname\space + \fontname\handledfont}} + + % division before multiplication, else overflow with "sa>5" + + \newdimen\protrudethreshold \protrudethreshold=36pt + + \def\dododefineprotrudefactor#1#2#3% + {\lpcode\handledfont#1\dimexpr#2\lproddimen + \ifembasedprotruding \else + \ifdim\emwidth>\protrudethreshold + /\emwidth*\fontcharwd\handledfont#1% + \else + *\fontcharwd\handledfont#1/\emwidth + \fi + \fi + \relax + \rpcode\handledfont#1\dimexpr#3\rproddimen + \ifembasedprotruding \else + \ifdim\emwidth>\protrudethreshold + /\emwidth*\fontcharwd\handledfont#1% + \else + *\fontcharwd\handledfont#1/\emwidth + \fi + \fi + \relax} + + \def\dodoinheritprotrudefactor#1#2% + {\lpcode\handledfont#1\lpcode\handledfont#2\relax + \rpcode\handledfont#1\rpcode\handledfont#2\relax} + + \def\defineprotrudefactor#1 #2 #3 % + {\setfonttoks + \let\inherithandling\inheritprotrudefactor + \appendtoks\dosetpairhandling\dododefineprotrudefactor#1 #2 #3 \to\fonttoks} + + \def\inheritprotrudefactor#1 #2 % + {\setfonttoks + \appendtoks\doinhsomehandling\dodoinheritprotrudefactor#1 #2 \to\fonttoks} + +\fi + +\ifx\setprotrudingfactor\gobbleoneargument \else + \appendtoks + \setprotrudingfactor\askedfonthandling + \to \everyenablefonthandling +\fi + +% Basic support for a new pdftex feature: space factors +% +% \knbccode -- kern before char code +% \knbscode -- kern before space code +% \stbscode -- stretch before space code +% \shbscode -- shrink before space code +% +% Setting \knsbcode\font`\.=200 means that if a period sits before +% a interword space (glue), then the interword glue will be increased +% by an amount of 1em*200/1000, i.e. the value is given in thousandths +% of an em. (HTT) + +\newdimen\spfacdimen + +\ifx\undefined\pdfadjustinterwordglue % we don't use pdftex + + \let\enablespacehandling \relax + \let\disablespacehandling \relax + \let\enablekernhandling \relax + \let\disablekernhandling \relax + + \let\setspacehandling \gobbleoneargument + + \def\definespacefactor #1 #2 #3 #4 #5 {} + \def\inheritspacefactor #1 #2 {} + +\else + + \def\enablespacehandling {\pdfadjustinterwordglue\plusone } + \def\disablespacehandling{\pdfadjustinterwordglue\minusone} + \def\enablekernhandling {\pdfprependkern \plusone } + \def\disablekernhandling {\pdfprependkern \minusone} + + \appendtoks \disablespacehandling \to \everyforgetall % Here or not here? + + \def\dosetspacehandling#1% + {\spfacdimen\csname\@fha@\@fha@#1\c!factor\endcsname\s!pt + \multiply\spfacdimen\plusthousand\divide\spfacdimen\maxcard\relax} + + \def\setspacehandling#1% + {\doifvalue{\@fha@\@fha@#1\c!type}\v!spacing{\dosetspacehandling{#1}}} + + \def\dododefinespacefactor#1#2#3#4#5% + {\sfcode#1\plusthousand + \knbccode\handledfont#1\dimexpr#2\spfacdimen\relax + \knbscode\handledfont#1\dimexpr#3\spfacdimen\relax + \stbscode\handledfont#1\dimexpr#4\spfacdimen\relax + \shbscode\handledfont#1\dimexpr#5\spfacdimen\relax} + + \def\dodoinheritspacefactor#1#2% + {\sfcode#1\plusthousand + \knbccode\handledfont#1\knbccode\handledfont#2\relax + \knbscode\handledfont#1\knbscode\handledfont#2\relax + \stbscode\handledfont#1\stbscode\handledfont#2\relax + \shbscode\handledfont#1\shbscode\handledfont#2\relax} + + \def\definespacefactor#1 #2 #3 #4 #5 % + {\setfonttoks + \let\inherithandling\inheritspacefactor + \appendtoks\dosetquartethandling\dododefinespacefactor#1 #2 #3 #4 #5 \to\fonttoks} + + \def\inheritspacefactor#1 #2 % + {\setfonttoks + \appendtoks\doinhsomehandling\dodoinheritspacefactor#1 #2 \to\fonttoks} + +\fi + +\ifx\setspacehandling\gobbleoneargument \else + \appendtoks + \setspacehandling\askedfonthandling + \to \everyenablefonthandling +\fi + +% font attributes + +\let\notagcode\minusone + +\ifx\tagcode\undefined + + \def\settagcode #1 #2 {} + +\else + + \def\dodosettagcode#1#2% + {\tagcode\handledfont#1 #2\relax} + + \def\settagcode#1 #2 % + {\setfonttoks + \appendtoks\dosetsomehandling\dodosettagcode#1 #2 \to\fonttoks} + +\fi + +% hook into font mechanism + +\let\fonthandling\empty + +\def\startfonthandling[#1]% + {\def\fonthandling{#1}% + \ifcsname\@fha@\fonthandling\endcsname\else + \expandafter\newtoks\csname\@fha@\fonthandling\endcsname + \fi + \setfonttoks} + +\def\stopfonthandling + {\let\fonthandling\empty} + +\def\setfonttoks + {\@EA\let\@EA\fonttoks\csname\@fha@\fonthandling\endcsname} + +\def\definefonthandling + {\dotripleempty\dodefinefonthandling} + +\def\dodefinefonthandling[#1][#2][#3]% + {\ifthirdargument + \setvalue{\@fha@\@fha@#1}{#2}% + \getparameters + [\@fha@\@fha@#1] + [\c!type=\v!hanging,% + \c!left=1,\c!right=1,% + \c!min=20,\c!max=20,\c!step=5,% + \c!factor=1,% + #3]% + \else + \setvalue{\@fha@\@fha@\@fha@#1}{#2}% + \fi} + +\def\setupfonthandling + {\dodoubleempty\dosetupfonthandling} + +\def\dosetupfonthandling[#1][#2]% + {\getparameters[\@fha@\@fha@#1][#2]} + +\def\enablehandling + {\dodoubleempty\doenablehandling} + +\def\doenablehandling[#1][#2]% handling / symbolic fontname + {\fastenablehandling{#1}{#2}} % for the moment the same as: + +\def\fastenablehandling#1#2% also gets #2 passed + {\edef\askedfonthandling{#1}% + \edef\filoffonthandling{#2}% + \ifcsname\@fha@\@fha@\@fha@\askedfonthandling\endcsname + \@EA\redofastenablehandling + \else\ifcsname\@fha@\@fha@\askedfonthandling\endcsname + \@EAEAEA\dofastenablehandling + \else + \@EAEAEA\nofastenablehandling + \fi\fi} + +\def\xfastenablehandling#1% + {\edef\askedfonthandling{#1}% + \ifcsname\@fha@\@fha@\askedfonthandling\endcsname + \@EA\dofastenablehandling + \else + \@EA\nofastenablehandling + \fi} + +\def\redofastenablehandling + {\startdirectcharacters + \edef\fonthandling{\csname\@fha@\@fha@\@fha@\askedfonthandling\endcsname}% + \rawprocesscommacommand[\fonthandling]\xfastenablehandling + \stopdirectcharacters} + +\def\dofastenablehandling + {\startdirectcharacters + \the\everyenablefonthandling + \edef\fonthandling{\csname\@fha@\@fha@\askedfonthandling\endcsname}% + \checkfonthandling\filoffonthandling + \rawprocesscommacommand[\fonthandling]\dodoenablehandling + \registerfonthandling\filoffonthandling + \stopdirectcharacters} + +\def\nofastenablehandling + {\the\everyenablefonthandling + \let\fonthandling\askedfonthandling + \dodoenablehandling\fonthandling} + +\def\dodoenablehandling#1% + {\ifcsname\@fha@#1\endcsname + \the\csname\@fha@#1\endcsname + \fi} + +%D We must not use \type {\purefontname} here (was a bug)! + +% not robust as long as tex reuses definitions internally +% +% \def\checkfonthandling#1% we need a fast compare +% {\doifelsevalue{#1\s!handling\c!file}{\fontname\font} +% \skiphandlingdeftrue\skiphandlingdeffalse} +% +% \def\registerfonthandling#1% +% {\@EA\xdef\csname#1\s!handling\c!file\endcsname{\fontname\font}} + +\def\checkfonthandling #1{\skiphandlingdeffalse} +\let\registerfonthandling \gobbleoneargument + +%D This one makes live easier (less definitions): + +\def\inherithandling #1 #2 % + {\inheritprotrudefactor #1 #2 % + \inheritadjustfactor #1 #2 } + +%D \macros +%D {usehandling} +%D +%D Handling definitions are collected in dedicated files and +%D loaded only once: +%D +%D % \showsetup{usehandling} + +\def\dousehandling#1% is the same as encoding + {\doifundefined{\c!file\f!handlingprefix#1}% + {\letvalueempty{\c!file\f!handlingprefix#1}% + \makeshortfilename[\truefilename{\f!handlingprefix#1}]% + \startreadingfile + \readsysfile{\shortfilename.mkii} + {\showmessage\m!handlings2{#1}} + {\showmessage\m!handlings3{#1}}% + \stopreadingfile}} + +\def\usehandling[#1]% + {\processcommalist[#1]\dousehandling} + +%D New: + +\def\overloadcharacter#1 #2 % + {\setfonttoks + \doifnumberelse{\string#2} + {\appendtoks\dooverloadcharacter{#1}{\char#2 }\to\fonttoks} + {\appendtoks\dooverloadcharacter{#1}{#2}\to\fonttoks}} + +\def\dooverloadcharacter#1% + {\setvalue{\characterencoding\string#1}} + +%D Let's now see if this macro works: + +% \setupfonthandling +% [\s!default] +% [\c!links=1,\c!rechts=1,\c!min=20,\c!max=20,\c!stap=5] + +% Beware of fonttoks: +% +% \startfonthandling[morespacing] +% \appendtoks +% \fontdimen2\handledfont=.50em +% \fontdimen3\handledfont=.25em +% \fontdimen4\handledfont=.25em +% \to \fonttoks +% \stopfonthandling +% +% \definefonthandling [morespacing] [morespacing] +% +% \definefontsynonym[xtexnansi-lmr7][texnansi-lmr7][handling=morespacing] +% \definefont[crap][texnansi-lmr7] +% +% \crap \the\fontdimen2\font, \the\fontdimen3\font, \the\fontdimen4\font + +\usehandling [def] + +\protect \endinput diff --git a/tex/context/base/hand-ini.mkiv b/tex/context/base/hand-ini.mkiv new file mode 100644 index 000000000..0285b10cb --- /dev/null +++ b/tex/context/base/hand-ini.mkiv @@ -0,0 +1,74 @@ +%D \module +%D [ file=hand-ini, +%D version=2008.02.12, +%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. + +%D Handling is implemented differently in \MKIV. Maybe I'll cook up +%D some compatibility hack. + +% \definefontfeature[demo][default][mode=node,expansion=quality] +% \definefontfeature[demo][default][mode=node,protrusion=pure] + +% experimental setup: +% +% \showframe \setupalign[hanging] \enabletrackers[fonts.protrusion] +% +% \definefontfeature[default] [default][mode=node,script=latn] +% %definefontfeature[whatever][default][mode=node,lfbd=yes,rtbd=yes,script=latn] +% \definefontfeature[whatever][default][mode=node,protrusion=quality] +% \definefontfeature[whocares][default][mode=node,protrusion=yes,opbd=yes,script=latn] % left|right|yes +% +% \definedfont[fxlbi.otf*default] \input tufte 0123456789 \par \dorecurse{15}{1 2 3 4 5 6 7 8 9 0 } \par +% \definedfont[fxlbi.otf*whatever] \input tufte 0123456789 \par \dorecurse{15}{1 2 3 4 5 6 7 8 9 0 } \par +% \definedfont[fxlbi.otf*whocares] \input tufte 0123456789 \par \dorecurse{15}{1 2 3 4 5 6 7 8 9 0 } \par +% +% %definefontfeature[whocares][default][mode=node,protrusion=2,opbd=yes,script=latn,featurefile=texgyrepagella-regularxx.fea] +% \definefontfeature[whocares][default][mode=node,protrusion=2,opbd=yes,script=latn] +% +% \definedfont[texgyrepagella-regularxx.otf*whocares] \input tufte + +\unprotect + +%D New stuff. + +\unexpanded\def\setupfontexpansion {\dodoubleargument\dosetupfontexpansion } +\unexpanded\def\setupfontprotrusion{\dodoubleargument\dosetupfontprotrusion} + +\def\dosetupfontexpansion [#1][#2]{\ctxlua{commands.setupfontexpansion ("#1","#2")}} +\def\dosetupfontprotrusion[#1][#2]{\ctxlua{commands.setupfontprotrusion("#1","#2")}} + +% \setupfontprotrusion[quality-upright][vector=quality] +% \setupfontprotrusion[quality-slanted][vector=quality,right=1.5] + +%D Old stuff. + +\def\fonthandlingerror{\writestatus\m!fonts{font handling is replaced by features in mkiv}} + +\def\enableadjusting {\pdfadjustspacing\plustwo } \let\enableexpansion \enableadjusting +\def\disableadjusting {\pdfadjustspacing\zerocount} \let\disableexpansion\disableadjusting +\def\enableprotruding {\pdfprotrudechars\plustwo } +\def\disableprotruding{\pdfprotrudechars\zerocount} + +\appendtoks \disableadjusting \to \everyforgetall % Here or not here? +\appendtoks \disableprotruding \to \everyforgetall % Here or not here? + +\unexpanded\def\startfonthandling #1{\fonthandlingerror\fonthandlingerror\gobbleuntil\stopfonthandling} % can't happen +\unexpanded\def\definefonthandling {\dotripleempty\dodefinefonthandling} +\unexpanded\def\setupfonthandling {\dodoubleempty\dosetupfonthandling } +\def\dodefinefonthandling[#1][#2][#3]{\fonthandlingerror} +\def\dosetupfonthandling [#1][#2]{\fonthandlingerror} +\def\usehandling [#1]{\fonthandlingerror} + +%D Just to be sure, maybe users use it: + +\let\fonthandling\empty + +\protect \endinput diff --git a/tex/context/base/java-ans.tex b/tex/context/base/java-ans.tex new file mode 100644 index 000000000..636c894f9 --- /dev/null +++ b/tex/context/base/java-ans.tex @@ -0,0 +1,28 @@ +%D \module +%D [ file=java-ans, +%D version=1998.06.01, +%D title=\CONTEXT\ JavaScript Macros, +%D subtitle=Answer Analization, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startJSpreamble{Do_Check_Answer} used later + + function Do_Check_Answer (field, value) + { if (event.value.toLowerCase()==value.toLowerCase()) + { event.target.hidden = true } + % { event.target.display = display.hidden } + return("\040") } // funny, "" does not work + +\stopJSpreamble + +\startJScode{Check_Answer} uses {Do_Check_Answer} + event.value = Do_Check_Answer(JS_S_1, JS_S_2) ; +\stopJScode + +\endinput diff --git a/tex/context/base/java-exa.tex b/tex/context/base/java-exa.tex new file mode 100644 index 000000000..f40f70f84 --- /dev/null +++ b/tex/context/base/java-exa.tex @@ -0,0 +1,395 @@ +%D \module +%D [ file=java-exa, +%D version=2002.??.??, +%D title=\CONTEXT\ JavaScript Macros, +%D subtitle=Example 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. + +% XFDF versus HTML +% localhost versus remote versus set + +% filename | filename-nr => name +% fakename | fakename-nr => file upload, unless localhost +% +% we erase the list because otherwise we end up in browser remembering +% problems; also, it is not possible to set upload fields 'manually' + +\startJSpreamble request_1 used now + + var example_method = "HTML" ; + var example_host = "" ; + var example_port = "" ; + var example_url = "" ; + var example_file = "" ; + + var example_log = true ; % false + + function stripped_exa_value( name ) { + f = this.getField(name) ; + if (f) { + str = f.value ; + if (str.indexOf(name+'-')==0) { + str = str.substr(name.length+1) ; + } + return str ; + } else { + return "" ; + } + } + + function identify_example_url ( ) { + if (example_log) { + console.clear ; + console.println("base url: "+this.baseURL) ; + console.println("this url: "+this.URL) ; + } + if (this.baseURL != "") { + example_url = this.baseURL ; + } else { + if (this.URL != "") { + example_url = this.URL + } + } + if (example_url.indexOf("file://")>=0) { + example_url = "" ; + } + str = stripped_exa_value("examplehost") ; + if (str != "auto") { + example_host = str ; + if (str == "localhost") { + example_port = "8061" + } + } + str = stripped_exa_value("exampleport") ; + if (str != "auto") { + example_port = str ; + } + if (example_log) { + console.println("example_url: "+example_url) ; + console.println("example_host: "+example_host) ; + console.println("example_port: "+example_port) ; + } + } + + function check_example_url ( url ) { + if (url.indexOf("file://")>=0) { + url = "http://localhost:8061" ; + console.println("file url replaced by: "+url) ; + } else { + if (url.indexOf("://")<0) { + url = "http://" + url ; + } + if (example_log) { + console.println("url before check: "+url) ; + } +% url = url.replace(/(http:\\\/\\\/.+)(\\\/.*$)/, "$1") ; + url = url.replace(/(https*:\\\/\\\/.+?)(\\\/.*$)/, "$1/exarequest") ; + if (example_log) { + console.println("url after check: "+url) ; + } + } + return url ; + } + + function set_example_xfdf ( method ) { + example_method = method ; + } + + function set_example_file ( file ) { + example_method = file ; + } + + function set_example_host ( host ) { + example_host = host ; + } + + function set_example_port ( port ) { + example_host = host ; + } + + function do_erase_example_file(tag) { + f = this.getField(tag) ; + if (f) { + f.value = "" ; + } + } + + function do_erase_example_list(tag) { + for (i=1;i<=100;i++) { + f = this.getField(tag+"-"+i) ; + if (f) { + f.value = "" ; + } else { + return + } + } + } + + function do_submit_example_url ( url ) { + if ((example_method == "XFDF" ) || (url.indexOf("localhost")>=0)) { + do_erase_example_file("fakename") ; + do_erase_example_list("fakename") ; + } + url = check_example_url(url) ; + if (example_log) { + console.println("submitting form to "+url+" using method "+example_method) ; + } + if (example_file != "") { + url = url + "/" + example_file ; + } + % we need the bFDF for acrobat 5 + this.submitForm({cURL : url, bFDF : false, cSubmitAs : example_method}) ; + } + + function submit_example_form ( ) { + identify_example_url() ; + if (example_host != "") { + if (example_port != "") { + do_submit_example_url(example_host+":"+example_port) ; + } else { + do_submit_example_url(example_host) ; + } + } else { + if (example_url != "") { + do_submit_example_url(example_url) ; + } else { + if (example_port != "") { + do_submit_example_url("localhost"+":"+example_port) ; + } else { + do_submit_example_url("localhost:8061") ; % local exampler + } + } + } + resetfilename () ; + } + + function submit_form ( host, port) { + set_example_host(host) ; + set_example_post(post) ; + submit_example_form ; + } + +\stopJSpreamble + +\startJSpreamble request_2 used now + + var exa_command = "" ; + var exa_option = "" ; + var exa_filename = "" ; + var exa_filelist = "" ; + var exa_registered = "" ; + + function set_request (command,option) { + exa_command = command ; + if (exa_command == "") { + exa_option = option ; + } else { if (option == "") { + exa_option = "" ; + } else { if (option.indexOf("--")<0) { + exa_option = "--action=" + option ; + } else { + exa_option = option ; + } } } + } + + function assemble_request ( ) { + v = this.getField('filename') ; + if (v) { + exa_filename = v.value ; + } + v = this.getField('filelist') ; + if (v) { + exa_filelist = v.value ; + } +% exa_filename = exa_filename.replace(/\\\\/g,'/') ; +% exa_filelist = exa_filelist.replace(/\\\\/g,'/') ; + str = "<?xml version='1.0' ?>\\n" ; + str = str+"<exa:request xmlns:exa='http://www.pragma-ade.com/schemas/example.rng'><exa:application>" ; + if (exa_filelist == "") { + exa_filelist = exa_registered ; + } else { if (exa_registered != "") { + exa_filelist = exa_filelist + "\\n" + exa_registered ; + } } + if (exa_command != "") { + str = str+"<exa:command>"+exa_command+"</exa:command>" ; + } + if (exa_option != "") { + str = str+"<exa:option>"+exa_option+"</exa:option>" ; + } + if (exa_filename != "") { + str = str+"<exa:filename>"+exa_filename+"</exa:filename>" ; + } + var fls = "" ; + if (exa_filelist != "") { + % old method, soon obsolete + lst = exa_filelist.split(/\\s/) ; + for (i=0;i<lst.length;i++) { + fls = fls+"<exa:entry>"+lst[i]+"</exa:entry>" ; + } + } else { if (exa_multiple) { + for (i=1;i<=100;i++) { + % console.println("file field "+i) ; + f = this.getField("filename-"+ i) ; +% if (f) { if (f.value != "") { +% if (g) { if (g.value == "") { +% fls = fls+"<exa:entry>"+f.value+"</exa:entry>" ; +% } else { +% fls = fls+"<exa:entry label='" + g.value + "'>"+f.value+"</exa:entry>" ; +% } } else { +% fls = fls+"<exa:entry>"+f.value+"</exa:entry>" ; +% } +% } } + if (f) { if (f.value != "") { + fls = fls + "<exa:entry" ; + g = this.getField("dataname-"+ i) ; + if (g) { if (g.value == "") { + % console.println("a") ; + fls = fls + ">" ; + } else { + % console.println("b") ; + fls = fls + " label='" + g.value + "'>" ; + } } else { + % console.println("c") ; + fls = fls + ">" ; + } + fls = fls + f.value + "</exa:entry>" ; + } } + } + } } + if (fls != "") { + str = str + "<exa:filelist>" + fls + "</exa:filelist>" ; + } + str = str + "</exa:application></exa:request>" ; + v = this.getField('exa:request') ; + if (v) { + v.value = str ; + } + } + +\stopJSpreamble + +\startJSpreamble request_3 used now + + var exa_multiple = false ; + + function setfilename ( suffixes ) { + if (event.targetName) { + var name = event.targetName ; + var fake = name.replace(/filename/,"fakename") ; + } else { + var name = 'filename' ; + var fake = 'fakename' ; + } + f = this.getField(fake) ; + if (f) { + f.browseForFileToSubmit() ; + if ((suffixes != "") && (f.value != "")) { + % + s = suffixes.replace(/,/g,"|") ; + r = new RegExp() ; + s = "\\\\.(" + s + ")$" ; + r.compile(s, "i") ; + if (f.value.search(r)<=0) { + f.value = "" ; + app.alert('This filetype is not permitted.') ; + % + % lst = suffixes.split(/,/) ; + % ok = false ; + % for (i=0;i<lst.length;i++) { + % if (f.value == lst[i]) { + % ok = true ; + % } + % } + % if (! ok) { + % f.value = "" ; + % app.alert('This filetype is not permitted.') ; + % + } + } + g = this.getField(name) ; + if (g) { + g.value = f.value ; + } +% we need to set the value of the selector to empty else +% we get some funny preloading of multimeg files in spite +% of the specs that say that xml fields will not get sent +% if (example_method == "XFDF" ) { +% f.value = "" ; +% } else { +% identify_example_url ; +% if (example_url.indexOf("localhost")>=0) { +% f.value = "" ; +% } +% } + } + this.dirty = false ; + } + + function addfilename () { + if (exa_multiple) { + h = this.getField("filelist") ; + g = this.getField("filename") ; + if ((g) && (h)) { + str = g.value ; + if (h.value == "") { + h.value = str ; + } else { + h.value = h.value + "\\n" + str ; + } + g.value = "" ; + this.value = "" ; + } + } + this.dirty = false ; + } + + % this only works with client that assembles request + + function registerfilename (str) { + if (str!="") { + h = this.getField("filelist") ; + if (h) { + if (h.value != "") { + h.value = h.value + "\\n" ; + } + h.value = h.value + str ; + } else { + if (exa_registered != "") { + exa_registered = exa_registered + "\\n" ; + } + exa_registered = exa_registered + str ; + } + } + console.show ; + console.println('registered files') ; + console.println("file: "+str) ; + console.println("list: "+exa_registered) ; + this.dirty = false ; + } + + function checkfilename () { + } + + function getfilename ( suffixes ) { + setfilename(suffixes) ; + checkfilename() ; + addfilename() ; + } + + function resetfilename () { + do_erase_example_file("fakename") ; + do_erase_example_file("filename") ; + do_erase_example_file("filelist") ; + do_erase_example_list("filename") ; + do_erase_example_list("fakename") ; + } + +\stopJSpreamble + +\endinput diff --git a/tex/context/base/java-fil.tex b/tex/context/base/java-fil.tex new file mode 100644 index 000000000..4d79a2ace --- /dev/null +++ b/tex/context/base/java-fil.tex @@ -0,0 +1,48 @@ +%D \module +%D [ file=java-fil, +%D version=1998.06.01, +%D title=\CONTEXT\ JavaScript Macros, +%D subtitle=Filing and Printing, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startJSpreamble Auxiliary used now + + function DocumentFileName () + { var Paths = this.path.split("/") ; + Paths = Paths[Paths.length-1].split(".") ; + return(Paths[0]) } + + function Print_Page_Range(From, To) % gaat mis, nog geen args mogelijk + { if ((Number(From)>0)&&(Number(To)>=Number(From))) + { var myFrom = Number(From)-1 ; + var myTo = Number(To)-1 ; + this.print(false,myFrom,myTo,true) } } + + function Print_This_Page () + { this.print(false,this.pageNum,this.pageNum,true) } + +\stopJSpreamble + +\definereference + [PrintSubPaginas] + [JS(Print_Page_Range{\firstsubpage,\lastsubpage})] + +\definereference + [PrintSubPages] + [JS(Print_Page_Range{\firstsubpage,\lastsubpage})] + +\definereference + [PrintDezePagina] + [JS(Print_This_Page)] + +\definereference + [PrintThisPage] + [JS(Print_This_Page)] + +\endinput diff --git a/tex/context/base/java-fld.tex b/tex/context/base/java-fld.tex new file mode 100644 index 000000000..3c24b7e02 --- /dev/null +++ b/tex/context/base/java-fld.tex @@ -0,0 +1,282 @@ +%D \module +%D [ file=java-fld, +%D version=1998.05.20, +%D title=\CONTEXT\ JavaScript Macros, +%D subtitle=Field 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. + +% will be simplified, since we now parse functions + +% nu nog alles geladen, moet dus anders + +\startJSpreamble {Sanitize_TeX_Input} used later + + function Sanitized_TeX_String (value) + { var v = value ; + v = v.replace( /\\\\oe/g,"\\234") ; + v = v.replace( /\\\\<</g,"\\253") ; + v = v.replace( /\\\\>>/g,"\\273") ; + v = v.replace( /\\\\`A/g,"\\300") ; + v = v.replace( /\\\\'A/g,"\\301") ; + v = v.replace( /\\\\^A/g,"\\302") ; + v = v.replace( /\\\\~A/g,"\\303") ; + v = v.replace( /\\\\"A/g,"\\304") ; + v = v.replace( /\\\\oA/g,"\\305") ; + v = v.replace( /\\\\AE/g,"\\306") ; + v = v.replace( /\\\\,C/g,"\\307") ; + v = v.replace( /\\\\`E/g,"\\310") ; + v = v.replace( /\\\\'E/g,"\\311") ; + v = v.replace( /\\\\^E/g,"\\312") ; + v = v.replace( /\\\\"E/g,"\\313") ; + v = v.replace( /\\\\`I/g,"\\314") ; + v = v.replace( /\\\\'I/g,"\\315") ; + v = v.replace( /\\\\^I/g,"\\316") ; + v = v.replace( /\\\\"I/g,"\\317") ; + v = v.replace( /\\\\~N/g,"\\321") ; + v = v.replace( /\\\\`O/g,"\\322") ; + v = v.replace( /\\\\'O/g,"\\323") ; + v = v.replace( /\\\\^O/g,"\\324") ; + v = v.replace( /\\\\~O/g,"\\325") ; + v = v.replace( /\\\\"O/g,"\\326") ; + v = v.replace( /\\\\`U/g,"\\331") ; + v = v.replace( /\\\\'U/g,"\\332") ; + v = v.replace( /\\\\^U/g,"\\333") ; + v = v.replace( /\\\\"U/g,"\\334") ; + v = v.replace( /\\\\'Y/g,"\\335") ; + v = v.replace( /\\\\ss/g,"\\337") ; + v = v.replace( /\\\\`a/g,"\\340") ; + v = v.replace( /\\\\'a/g,"\\341") ; + v = v.replace( /\\\\^a/g,"\\342") ; + v = v.replace( /\\\\~a/g,"\\343") ; + v = v.replace( /\\\\"a/g,"\\344") ; + v = v.replace( /\\\\oa/g,"\\345") ; + v = v.replace( /\\\\ae/g,"\\346") ; + v = v.replace( /\\\\,c/g,"\\347") ; + v = v.replace( /\\\\`e/g,"\\350") ; + v = v.replace( /\\\\'e/g,"\\351") ; + v = v.replace( /\\\\^e/g,"\\352") ; + v = v.replace( /\\\\"e/g,"\\353") ; + v = v.replace( /\\\\`i/g,"\\354") ; + v = v.replace( /\\\\'i/g,"\\355") ; + v = v.replace( /\\\\^i/g,"\\356") ; + v = v.replace( /\\\\"i/g,"\\357") ; + v = v.replace( /\\\\~n/g,"\\361") ; + v = v.replace( /\\\\`o/g,"\\362") ; + v = v.replace( /\\\\'o/g,"\\363") ; + v = v.replace( /\\\\^o/g,"\\364") ; + v = v.replace( /\\\\~o/g,"\\365") ; + v = v.replace( /\\\\"o/g,"\\366") ; + v = v.replace( /\\\\`u/g,"\\371") ; + v = v.replace( /\\\\'u/g,"\\372") ; + v = v.replace( /\\\\^u/g,"\\373") ; + v = v.replace( /\\\\"u/g,"\\374") ; + v = v.replace( /\\\\'y/g,"\\375") ; + v = v.replace( /\\\\"y/g,"\\377") ; + return(v) } + + var TeX_Key_Mode = 0 ; + + function Initialize_TeX_Keystroke () + { TeX_Key_Char = "" ; + TeX_Key_Mode = 0 } + + function Sanitized_TeX_Keystroke (change) + { if (change=="\\\\") + { TeX_Key_Mode = 1 ; + return("") } + else if (TeX_Key_Mode==1) + { TeX_Key_Mode = 2 ; + TeX_Key_Char = change ; + return("") } + else if (TeX_Key_Mode==2) + { TeX_Key_Mode = 0 ; + TeX_Key_Char = "\\\\"+TeX_Key_Char+change ; + return(Sanitized_TeX_String(TeX_Key_Char)) } + else + { TeX_Key_Mode = 0 ; + return(change) } } + +\stopJSpreamble + +\startJScode {Initialize_TeX_Key} uses {Sanitize_TeX_Input} + Initialize_TeX_Keystroke() ; +\stopJScode + +\startJScode {Convert_TeX_Key} uses {Sanitize_TeX_Input} + if (!event.willCommit) + { event.change = Sanitized_TeX_Keystroke(event.change) } +\stopJScode + +\startJScode{Convert_TeX_String} uses {Sanitize_TeX_Input} + event.value = Sanitized_TeX_String(event.value) ; +\stopJScode + +\startJSpreamble fields_1 used now + +var visible_field = new Array() ; +var visible_fields = 0 ; + +function PresetFields ( ) + { this.syncAnnotScan() } + +function Preset_Fields ( ) + { this.syncAnnotScan() } + +function Hide_When_Down ( ) + { event.target.hidden = true } + +function Hide_Field ( Name ) + { var v = this.getField(Name) ; + if (v) + { v.hidden = true ; + v.readonly = true ; + this.dirty = false } } + +function Do_Vide_Field ( Name, Closable ) + { var v = this.getField(Name) ; + if (v) + { ++visible_fields ; + visible_field[visible_fields] = Name ; + v.hidden = false ; + if (Closable) + { v.readonly = false ; + v.value = "On" } + this.dirty = false } } + +function Vide_Field ( Name ) + { Do_Vide_Field(Name,false) } + +function Vide_Hide_Field ( Name ) + { Do_Vide_Field(Name,true) } + +function Hide_Fields () + { while (visible_fields>0) + { Hide_Field(visible_field[visible_fields]) ; + --visible_fields } } + +function Vide_Fields ( Name ) + { Hide_Fields () ; + Vide_Field ( Name) } + +function Vide_Hide_Fields ( Name ) + { Hide_Fields () ; + Vide_Hide_Field ( Name) } + +function Toggle_Hide ( Name ) + { var v = this.getField(Name) ; + if (v) + { v.hidden = !v.hidden ; + this.dirty = false } } + +function Field_On ( Name ) + { v = this.getField(Name) ; + if (v) { v.value = "On" ; this.dirty = false } } + +function Field_Off ( Name ) + { var v = this.getField(Name) ; + if (v) { v.value = "Off" ; this.dirty = false } } + +function Toggle_Value ( Name ) + { var v = this.getField(Name) ; + if (v) + { if (v.value=="On") + { v.value = "Off" } + else + { v.value = "On" } } + this.dirty = false } + +function Toggle_Read ( Name ) + { var v = this.getField(Name); + if (v) { v.readonly = !v.readonly } } + +function Flip_Fields ( Name ) + { var Names = Name.split(",") ; + for (var i=0;i<Names.length;i++) + { v = this.getField(Names[i]) ; + if (v) + { v.hidden = !v.hidden ; + v.value = "On" } } } + +function Forget_Changes () + { this.dirty = false } + +function ForgetChanges () + { this.dirty = false } +\stopJSpreamble + +%\startJScode{Hide_When_Down} Hide_When_Down() \stopJScode +%\startJScode{Hide_Field} Hide_Field(JS_S_1) \stopJScode +%\startJScode{Vide_Field} Vide_Field(JS_S_1) \stopJScode +%\startJScode{Toggle_Hide} Toggle_Hide(JS_S_1) \stopJScode +%\startJScode{Field_On} Field_On(JS_S_1) \stopJScode +%\startJScode{Field_Off} Field_Off(JS_S_1) \stopJScode +%\startJScode{Toggle_Value} Toggle_Value(JS_S_1) \stopJScode +%\startJScode{Toggle_Read} Toggle_Read(JS_S_1) \stopJScode +%\startJScode{Flip_Fields} Flip_Fields(JS_S_1) \stopJScode +% +%\startJScode{Forget_Changes} this.dirty = false \stopJScode + +\definereference[ForgetChanges][JS(Forget_Changes)] + +% This can be done more efficient, by keeping track of the +% current top of the stack. + +\startJSpreamble FieldStack used later + +function Reset_Fields ( FieldSet ) + { var i = 1 ; + while (true) + { v = this.getField(FieldSet+":"+i) ; + if (!v) + { break } + else + { v.value = "Off" } + i++ } } + +function Set_Fields ( FieldSet ) + { var i = 1 ; + while (true) + { v = this.getField(FieldSet+":"+i) ; + if (!v) + { break } + else + { v.value = "On" } + i++ } } + +function Set_Field ( FieldSet, FieldName ) + { Reset_Fields(FieldSet) ; + v = this.getField(FieldSet+":"+FieldName) ; + if (v) { v.value = "On" } } + +function Reset_Field ( FieldSet, FieldName ) + { Set_Fields(FieldSet) ; + v = this.getField(FieldSet+":"+FieldName) ; + if (v) { v.value = "Off" } } + +function Walk_Field ( FieldSet ) + { var i = 1 ; + while (true) + { v = this.getField(FieldSet+":"+i) ; + if (v) + { if (v.value=="On") + { v.value = "Off" ; + var ii = i ; ii++ ; + v = this.getField(FieldSet+":"+ii) ; + if (!v) + { v = this.getField(FieldSet+":"+1) } + if (v) + { v.value = "On" } + break } + i++ } + else + { break } } } + +\stopJSpreamble + +\endinput diff --git a/tex/context/base/java-ini.lua b/tex/context/base/java-ini.lua new file mode 100644 index 000000000..f64a8a18f --- /dev/null +++ b/tex/context/base/java-ini.lua @@ -0,0 +1,120 @@ +if not modules then modules = { } end modules ['java-ini'] = { + version = 1.001, + comment = "companion to java-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format = string.format +local lpegmatch = lpeg.match + +javascripts = javascripts or { } +javascripts.codes = javascripts.codes or { } +javascripts.preambles = javascripts.preambles or { } +javascripts.functions = javascripts.functions or { } + +local codes, preambles, functions = javascripts.codes, javascripts.preambles, javascripts.functions + +local preambled = { } + +local function storefunction(s) + functions[s] = true +end + +local uses = lpeg.P("uses") +local used = lpeg.P("used") +local left = lpeg.P("{") +local right = lpeg.P("}") +local space = lpeg.S(" \r\n") +local spaces = space^0 +local braced = left * lpeg.C((1-right-space)^1) * right +local unbraced = lpeg.C((1-space)^1) +local name = spaces * (braced + unbraced) * spaces +local any = lpeg.P(1) +local script = lpeg.C(any^1) +local funct = lpeg.P("function") +local leftp = lpeg.P("(") +local rightp = lpeg.P(")") +local fname = spaces * funct * spaces * (((1-space-left)^1)/storefunction) * spaces * leftp + +local parsecode = name * ((uses * name) + lpeg.Cc("")) * spaces * script +local parsepreamble = name * ((used * name) + lpeg.Cc("")) * spaces * script +local parsefunctions = (fname + any)^0 + +function javascripts.storecode(str) + local name, uses, script = lpegmatch(parsecode,str) + if name and name ~= "" then + javascripts.codes[name] = { uses, script } + end +end + +function javascripts.storepreamble(str) -- now later + local name, used, script = lpegmatch(parsepreamble,str) + if name and name ~= "" then + preambles[#preambles+1] = { name, used, script } + preambled[name] = #preambles + lpegmatch(parsefunctions,script) + end +end + +function javascripts.setpreamble(name,script) -- now later + if name and name ~= "" then + preambles[#preambles+1] = { name, "now", script } + preambled[name] = #preambles + lpegmatch(parsefunctions,script) + end +end + +function javascripts.addtopreamble(name,script) -- now later + if name and name ~= "" then + local p = preambled[name] + if p then + preambles[p] = { "now", preambles[p] .. " ;\n" .. script } + else + preambles[#preambles+1] = { name, "now", script } + preambled[name] = #preambles + lpegmatch(parsefunctions,script) + end + end +end + +function javascripts.usepreamblenow(name) -- now later + if name and name ~= "" and preambled[name] then + preambles[preambled[name]][2] = "now" + end +end + +function javascripts.code(name,arguments) + local c = codes[name] + if c then + local u, code = c[1], c[2] + if u ~= "" then + local p = preambled[u] + if p then + preambles[p][1] = "now" + end + end + return code + end + local f = functions[name] + if f then + -- temporary hack, i need a more clever approach + if arguments then + return format("%s(%s)",name,'"' .. arguments.gsub(arguments,'%s*,%s*','"%1",') .. '"') + else + return format("%s()",name) + end + end +end + +function javascripts.flushpreambles() + local t = { } + for i=1,#preambles do + local preamble = preambles[i] + if preamble[2] == "now" then + t[#t+1] = { preamble[1], preamble[3] } + end + end + return t +end 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; j<N.length; j++) +%D { if (N[j].value!="") +%D { Total.value += N[j].value } } ; +%D if ((JS_N>0) && (JS_R_1!="")) +%D { gotoNamedDest(JS_R_1) }; +%D \stopJScode +%D \stoptyping +%D +%D Such a piece of code is closely related to the interpreter +%D used. Watch the last two lines, here the script adapts +%D itself to the presence of a reference. +%D +%D While +%D +%D \starttyping +%D \startJScode{name} +%D name = 4 ; +%D \stopJScode +%D \stoptyping +%D +%D assumes uses no preamble or presumes that the preamble is +%D always loaded, the next definition also tells \CONTEXT\ to +%D actually include the preamble needed. +%D +%D \starttyping +%D \startJScode{uses} uses {later} +%D uses = 6 ; +%D \stopJScode +%D \stoptyping + +\long\def\startJScode#1 #2 + {\doifelse{#2}{uses} + {\dostartJScodeA{#1}} + {\dostartJScodeB{#1} #2 }} + +\long\def\dostartJScodeA#1#2 #3\stopJScode + {\long\setgvalue{\r!java#1}{\do{#2}{#3}}} + +\long\def\dostartJScodeB#1#2\stopJScode + {\long\setgvalue{\r!java#1}{\do{}{#2}}} + +\let\stopJScode\relax + +%D \macros +%D {presetJScode} +%D +%D The code can be retrieved by saying +%D +%D \starttyping +%D \presetJScode{SomeScript}{template} +%D \stoptyping +%D +%D Such a template is a comma separated list, where +%D individual entries can optionally be transformed by +%D \type{R{}} and \type{V{}}. +%D +%D After this call, the code is available in \type{\JScode}. + +\newif\ifdirectJScode + +\def\presetJScode#1#2% #1=operation #2=arguments + {\setverbosecscharacters + \def\par{\delcharacter}% was: { } + \scratchcounter\zerocount + \globallet\JScode\empty + \def\do##1##2% + {\doifelse{##2}{!}\directJScodetrue\directJScodefalse}% + \getvalue{\r!java#1}% + \edef\!!stringa{#2}% + \ifx\!!stringa\empty \else + \processcommacommand[\!!stringa]\dopresetJSvariables + \fi + \def\docommand##1% + {\doifundefinedelse{\r!java\r!java##1} + {\showmessage\m!javascript2{##1}} + {\useJSpreamblenow{##1}}}% +% {\doglobal\increment\currentJSpreamble +% \doglobal\addtocommalist{##1}\allJSpreambles}}% + \def\do##1##2% + {\xdef\JScode{\ifdirectJScode#1(\JScode)\else\JScode##2\fi}% + %\xdef\JScode{JS\string_N=\the\scratchcounter;\JScode}% + \processcommalist[##1]\docommand}% + \getvalue{\r!java#1}} + +\def\dopresetJSvariables#1% + {\advance\scratchcounter \plusone + \donefalse + \dodopresetJSvariables#1\end}% + +\def\dodopresetJSvariables + {\doifnextcharelse R\dodopresetJSrefvariables + {\doifnextcharelse V\dodopresetJSvervariables + {\doifnextcharelse S\dodopresetJSstrvariables + \dodopresetJSrawvariables}}} + +\def\dodopresetJSrefvariables R#1\end + {\doifreferencefoundelse{#1} + {\donetrue \dododopresetJSvariables R{\referenceprefix#1}% + \donefalse\dododopresetJSvariables P{\currentrealreference}} + {\unknownreference{#1}}% + \ifminimalizeJScode \else + \donetrue\dododopresetJSvariables S{#1}% + \fi} + +\def\dodopresetJSvervariables V#1\end + {\donefalse\dododopresetJSvariables V{#1}% + \ifminimalizeJScode \else + \donetrue\dododopresetJSvariables S{#1}% + \fi} + +\def\dodopresetJSstrvariables S#1\end + {\donetrue\dododopresetJSvariables S{#1}} + +\def\dodopresetJSrawvariables #1\end + {\donetrue\dododopresetJSvariables S{#1}} + +\def\JSprefix#1% + {JS\string_#1\string_\the\scratchcounter} + +\def\dododopresetJSvariables#1#2% + {\iftraceJScode + \writestatus{JavaScript}{\JSprefix#1=#2} + \xdef\JScode{\JScode console.println("\JSprefix#1=#2"); }% + \fi + \ifdirectJScode + \xdef\JScode{\ifx\JScode\empty\else\JScode,\fi\ifdone"#2"\else#2\fi}% + \else + \xdef\JScode{\JScode\JSprefix#1=\ifdone"#2"\else#2\fi; }% + \fi} + +%D \macros +%D {startJSpreamble, flushJSpreamble} +%D +%D One can define insert \JAVASCRIPT\ code at the document level +%D by using: +%D +%D \starttyping +%D \startJSpreamble{oeps} +%D oeps = 1 ; +%D \stopJSpreamble +%D \stoptyping +%D +%D which is the same as: +%D +%D \starttyping +%D \startJSpreamble{now} used now +%D now = 2 ; +%D \stopJSpreamble +%D \stoptyping +%D +%D while the next definition is only included when actually +%D used. +%D +%D \starttyping +%D \startJSpreamble{later} used later +%D later = 3 ; +%D \stopJSpreamble +%D \stoptyping +%D +%D This command may be used more that once, but always before +%D the first page is shipped out. + +\newif\ifoneJSpreamble \oneJSpreamblefalse + +\let\allJSpreambles\empty +\newcounter\nofJSpreambles +\newcounter\currentJSpreamble + +\long\def\startJSpreamble#1 #2 % + {\bgroup % we need to restore the catcodes + \restoreendofline % just in case it happens while reading lists + \doifelse{#2}{used} + {\dostartJSpreamble#1 } + {\dostartJSpreamble#1 now #2 }} + +\long\def\dostartJSpreamble#1 #2 % + {\processaction + [#2] + [ later=>\chardef\JSstatus\zerocount,% + now=>\chardef\JSstatus\plusone ,% + \s!default=>\chardef\JSstatus\plustwo ,% + \s!unknown=>\chardef\JSstatus\plustwo ]% + \ifaddJSlinebreaks + \obeylines \let\obeyedline \normalpar + \obeyspaces \let\obeyedspace\normalspace + \fi + \dodostartJSpreamble{#1}} + +\long\def\dodostartJSpreamble#1#2\stopJSpreamble + {\presetJSfunctions #2function ()\end + \long\setgvalue{\r!java\r!java#1}{#2}% + \ifcase\JSstatus \else + \useJSpreamblenow{#1}% + \fi + \egroup} + +%D \macros +%D {setJSpreamble, addtoJSpreamble} +%D +%D In addition to the previous preamble definitions, we can +%D set a preamble \quote {in||line} and add tokens to a +%D preamble. + +\def\setJSpreamble#1#2% + {\doifundefined{\r!java\r!java#1} + {\setgvalue{\r!java\r!java#1}{#2;}% + \doglobal\increment\currentJSpreamble + \doglobal\addtocommalist{#1}\allJSpreambles}} + +\def\addtoJSpreamble#1#2% + {\doifdefinedelse{\r!java\r!java#1} + {\edef\!!stringa{\r!java\r!java#1}% + \edef\!!stringb{\csname\!!stringa\endcsname}% + \@EA\setgvalue\@EA\!!stringa\@EA{\!!stringb #2;}} + {\setJSpreamble{#1}{#2}}} + +%D \macros +%D {useJSpreamblenow} +%D +%D The next macro can be used to force inclusion of postponed +%D \JAVASCRIPT\ preambles. + +\def\useJSpreamblenow#1% + {\doglobal\increment\currentJSpreamble + \doglobal\addtocommalist{#1}\allJSpreambles} + +%D Because we want to check for valid calls, we preload the +%D functions. This means that we can call them directly as +%D well as indirectly when defined by \type {\startJScode} etc. + +% \long\def\presetJSfunctions#1function #2(#3)% +% {\doifelsenothing{#2} +% {\long\def\presetJSfunctions##1\end{}} +% {\stripspaces\from#2\to\ascii +% \doifundefined{\r!java\ascii}{\setgvalue{\r!java\ascii}{\do{}{!}}}}% +% \presetJSfunctions} + +\long\def\presetJSfunctions#1function#2(#3)% + {\doifelse{#2}\space + {\long\def\presetJSfunctions##1\end{}} + {\stripspaces\from#2\to\ascii + \doifundefined{\r!java\ascii}{\setgvalue{\r!java\ascii}{\do{}{!}}}}% + \presetJSfunctions} + +\def\getJSpreamble#1% + {\getvalue{\r!java\r!java#1}} + +\def\presetJSpreamble + {\ifx\allJSpreambles\empty\else + \bgroup + \setverbosecscharacters + \obeyspaces \let\obeyedspace\normalspace + \def\par{\delcharacter}% was: { } + \globallet\JSpreamble\empty + \def\@@collectedJSpreamble{\r!java\r!java collected}% + \letvalue{\@@collectedJSpreamble}=\empty + \def\docommand##1% + {\xdef\JScode{\getvalue{\r!java\r!java##1}}% + \ifoneJSpreamble % \global\letcdcsname + \@EA\setxvalue\@EA\@@collectedJSpreamble\@EA + {\csname\@@collectedJSpreamble\endcsname\JScode}% + \else + \setxvalue{\r!java\r!java##1}{\JScode}% + \fi}% + \processcommacommand[\allJSpreambles]\docommand + \ifoneJSpreamble + \gdef\allJSpreambles{collected}% + \fi + \globallet\presetJSpreamble\relax + \egroup + \fi} + +\def\flushJSpreamble + {\iflocation\ifx\allJSpreambles\empty\else + \ifcase\nofJSpreambles\else\ifnum\nofJSpreambles=\currentJSpreamble + \bgroup + \presetJSpreamble + \expanded{\doflushJSpreamble{\allJSpreambles}}% + \globallet\flushJSpreamble\relax + \globallet\allJSpreambles\empty + \egroup + \fi\fi + \fi\fi} + +\def\finalflushJSpreamble + {\iflocation + \flushJSpreamble + \ifcase\currentJSpreamble\relax\else + \savecurrentvalue\nofJSpreambles\currentJSpreamble + \globallet\currentJSpreamble\nofJSpreambles + \fi + \fi} + +\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..6536ced48 --- /dev/null +++ b/tex/context/base/java-ini.mkiv @@ -0,0 +1,164 @@ +%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} + +\registerctxluafile{java-ini}{1.001} + +\unprotect + +%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 \macros +%D {startJScode} +%D +%D A piece of \JAVASCRIPT\ code is defined by saying: +%D +%D \starttyping +%D \startJScode{name} +%D name = 4 ; +%D \stopJScode +%D \stoptyping +%D +%D This 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 +%D +%D \macros +%D {startJSpreamble} +%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. +%D +%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. +%D +%D \macros +%D {useJSpreamblenow} +%D +%D This macro can be used to force inclusion of postponed +%D \JAVASCRIPT\ preambles. + +\unexpanded\def\startJScode + {\begingroup\obeylualines\obeyluatokens\dostartJScode} + +\long\def\dostartJScode#1\stopJScode + {\normalexpanded{\endgroup\ctxlua{javascripts.storecode(\!!bs#1\!!es)}}} + +\let\stopJScode\relax + +\unexpanded\def\startJSpreamble + {\begingroup\obeylualines\obeyluatokens\dostartJSpreamble} + +\long\def\dostartJSpreamble#1\stopJSpreamble + {\normalexpanded{\endgroup\ctxlua{javascripts.storepreamble(\!!bs#1\!!es)}}} + +\let\stopJSpreamble\relax + +\def\setJSpreamble #1#2{\ctxlua{javascripts.storepreamble ("#1",\!!bs#2\!!es)}} +\def\addtoJSpreamble #1#2{\ctxlua{javascripts.addtopreamble ("#1",\!!bs#2\!!es)}} +\def\useJSpreamblenow #1{\ctxlua{javascripts.usepreamblenow("#1")}} +\def\finalflushJSpreamble{\iflocation\ctxlua{javascripts.flushpreambles()}\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} + {\ifcsname\c!file\f!javascriptprefix#1\endcsname \else + \startnointerference + \letgvalueempty{\c!file\f!javascriptprefix#1}% + \makeshortfilename[\f!javascriptprefix#1]% + \startreadingfile + \readsysfile\shortfilename{\showmessage\m!javascript1{#1}}\donothing + \stopreadingfile + \stopnointerference + \fi}} + +\def\douseJSscripts[#1][#2]% + {\processcommalist[#1]\dodouseJSscripts + \processcommalist[#2]\useJSpreamblenow} + +\def\useJSscripts + {\dodoubleempty\douseJSscripts} + +\protect \endinput diff --git a/tex/context/base/java-stp.tex b/tex/context/base/java-stp.tex new file mode 100644 index 000000000..df4fbcc2f --- /dev/null +++ b/tex/context/base/java-stp.tex @@ -0,0 +1,121 @@ +%D \module +%D [ file=java-stp, +%D version=2004.03.15, +%D title=\CONTEXT\ JavaScript Macros, +%D subtitle=Stepping, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% we define ocglist global, otherwise we quickly run into a memory hog (even +% out of memory in a 512 Meg machine) + +% we cannot use doc_visited[this.pageNum] instead of doc_currentstep because +% of some funny side effect (i.e. dup or so) + +\startJSpreamble Steps used now + + var doc_ocglist = this.getOCGs() ; + var doc_stepname = "step" ; + var doc_currentstep = 0 ; + var doc_maxstep = 50 ; + var doc_visited = new Array() ; + var doc_busy = new Array() ; + + function SetupStepper ( layername, laststep ) { + doc_stepname = layername ; + doc_maxstep = laststep ; + for (var i=0; i<=this.numPages; i++) { + doc_visited[i] = 0 ; + doc_busy[i] = 0 ; + } + } + + for (var i=0; i<=this.numPages; i++) { + doc_visited[i] = 0 ; + doc_busy[i] = 0 ; + } + + function GetOCG ( name ) { + for (var i=0; i < doc_ocglist.length; i++) { + if (doc_ocglist[i].name == name) { + return doc_ocglist[i] ; + } + } + return null ; + } + + function CheckBusy ( ) { + var ocg = GetOCG("step:busy") ; + if (ocg != null) { + if (doc_visited[this.pageNum]==0) { + ocg.state = true ; + } else { + if (doc_visited[this.pageNum]<doc_busy[this.pageNum]) { + ocg.state = true ; + } else { + ocg.state = false ; + } + } + } + } + + function SetStepper ( maxstep, state ) { + for (var i=1; i<=maxstep; i++) { + try { + var ocg = GetOCG(doc_stepname + ':' + String(i)) ; + if (ocg != null) { + ocg.state = state ; + } + } catch (e) { + return ; + } + } + } + + function CheckStepper ( maxsteps ) { + SetStepper(doc_visited[this.pageNum], true) ; + doc_busy[this.pageNum] = Number(maxsteps) ; + doc_currentstep = doc_visited[this.pageNum] ; + CheckBusy() ; + } + + function ResetStepper ( ) { + SetStepper(doc_maxstep, false) ; + doc_currentstep = 0 ; + } + + function InvokeStepper ( ) { + try { + if (doc_currentstep<doc_busy[this.pageNum]) { + doc_currentstep += 1 ; + doc_visited[this.pageNum] = doc_currentstep ; + var ocg = GetOCG(doc_stepname + ':' + String(doc_currentstep)) ; + if (ocg != null) { + ocg.state = true ; + } + } else { + if (this.pageNum+1==this.numPages) { + this.pageNum = 0 ; + } else { + this.pageNum += 1 ; + } + } + CheckBusy() ; + } catch (e) { + return ; + } + } + +\stopJSpreamble + +% \definereference [SetupStepper] [JS(SetupStepper{step,50})] +% \definereference [ResetStepper] [JS(ResetStepper)] +% \definereference [CheckStepper] [JS(CheckStepper{\StepCounter})] +% \definereference [InvokeStepper] [JS(InvokeStepper)] + +\endinput diff --git a/tex/context/base/l-aux.lua b/tex/context/base/l-aux.lua new file mode 100644 index 000000000..97063e3bc --- /dev/null +++ b/tex/context/base/l-aux.lua @@ -0,0 +1,261 @@ +if not modules then modules = { } end modules ['l-aux'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- for inline, no store split : for s in string.gmatch(str,",* *([^,]+)") do .. end + +aux = aux or { } + +local concat, format, gmatch = table.concat, string.format, string.gmatch +local tostring, type = tostring, type +local lpegmatch = lpeg.match + +local P, R, V = lpeg.P, lpeg.R, lpeg.V + +local escape, left, right = P("\\"), P('{'), P('}') + +lpeg.patterns.balanced = P { + [1] = ((escape * (left+right)) + (1 - (left+right)) + V(2))^0, + [2] = left * V(1) * right +} + +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 value = lpeg.P(lbrace * lpeg.C((nobrace + nested)^0) * rbrace) + lpeg.C((nested + (1-comma))^0) + +local key = lpeg.C((1-equal-comma)^1) +local pattern_a = (space+comma)^0 * (key * equal * value + key * lpeg.C("")) +local pattern_c = (space+comma)^0 * (key * equal * value) + +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 +local pattern_c_s = (pattern_c/set)^1 + +aux.settings_to_hash_pattern_a = pattern_a_s +aux.settings_to_hash_pattern_b = pattern_b_s +aux.settings_to_hash_pattern_c = pattern_c_s + +function aux.make_settings_to_hash_pattern(set,how) + if how == "strict" then + return (pattern_c/set)^1 + elseif how == "tolerant" then + return (pattern_b/set)^1 + else + return (pattern_a/set)^1 + end +end + +function aux.settings_to_hash(str,existing) + if str and str ~= "" then + hash = existing or { } + if moretolerant then + lpegmatch(pattern_b_s,str) + else + lpegmatch(pattern_a_s,str) + end + return hash + else + return { } + end +end + +function aux.settings_to_hash_tolerant(str,existing) + if str and str ~= "" then + hash = existing or { } + lpegmatch(pattern_b_s,str) + return hash + else + return { } + end +end + +function aux.settings_to_hash_strict(str,existing) + if str and str ~= "" then + hash = existing or { } + lpegmatch(pattern_c_s,str) + return next(hash) and hash + else + return nil + end +end + +local separator = 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*(separator*value)^0) + +-- "aap, {noot}, mies" : outer {} removes, leading spaces ignored + +aux.settings_to_array_pattern = pattern + +-- we could use a weak table as cache + +function aux.settings_to_array(str) + if not str or str == "" then + return { } + else + return lpegmatch(pattern,str) + end +end + +local function set(t,v) + t[#t+1] = v +end + +local value = lpeg.P(lpeg.Carg(1)*value) / set +local pattern = value*(separator*value)^0 * lpeg.Carg(1) + +function aux.add_settings_to_array(t,str) + return lpegmatch(pattern,str,nil,t) +end + +function aux.hash_to_string(h,separator,yes,no,strict,omit) + if h then + local t, s = { }, table.sortedkeys(h) + omit = omit and table.tohash(omit) + for i=1,#s do + local key = s[i] + if not omit or not omit[key] then + local value = h[key] + if type(value) == "boolean" then + if yes and no then + if value then + t[#t+1] = key .. '=' .. yes + elseif not strict then + t[#t+1] = key .. '=' .. no + end + elseif value or not strict then + t[#t+1] = key .. '=' .. tostring(value) + end + else + t[#t+1] = key .. '=' .. value + end + end + end + return concat(t,separator or ",") + else + return "" + end +end + +function aux.array_to_string(a,separator) + if a then + return concat(a,separator or ",") + else + return "" + end +end + +function aux.settings_to_set(str,t) + t = t or { } + for s in gmatch(str,"%s*([^,]+)") do + t[s] = true + end + return t +end + +local value = lbrace * lpeg.C((nobrace + nested)^0) * rbrace +local pattern = lpeg.Ct((space + value)^0) + +function aux.arguments_to_table(str) + return lpegmatch(pattern,str) +end + +-- temporary here + +function aux.getparameters(self,class,parentclass,settings) + local sc = self[class] + if not sc then + sc = table.clone(self[parent]) + self[class] = sc + end + aux.settings_to_hash(settings,sc) +end + +-- temporary here + +local digit = lpeg.R("09") +local period = lpeg.P(".") +local zero = lpeg.P("0") +local trailingzeros = zero^0 * -digit -- suggested by Roberto R +local case_1 = period * trailingzeros / "" +local case_2 = period * (digit - trailingzeros)^1 * (trailingzeros / "") +local number = digit^1 * (case_1 + case_2) +local stripper = lpeg.Cs((number + 1)^0) + +--~ local sample = "bla 11.00 bla 11 bla 0.1100 bla 1.00100 bla 0.00 bla 0.001 bla 1.1100 bla 0.100100100 bla 0.00100100100" +--~ collectgarbage("collect") +--~ str = string.rep(sample,10000) +--~ local ts = os.clock() +--~ lpegmatch(stripper,str) +--~ print(#str, os.clock()-ts, lpegmatch(stripper,sample)) + +lpeg.patterns.strip_zeros = stripper + +function aux.strip_zeros(str) + return lpegmatch(stripper,str) +end + +function aux.definetable(target) -- defines undefined tables + local composed, t = nil, { } + for name in gmatch(target,"([^%.]+)") do + if composed then + composed = composed .. "." .. name + else + composed = name + end + t[#t+1] = format("%s = %s or { }",composed,composed) + end + return concat(t,"\n") +end + +function aux.accesstable(target) + local t = _G + for name in gmatch(target,"([^%.]+)") do + t = t[name] + end + return t +end + +--~ function string.commaseparated(str) +--~ return gmatch(str,"([^,%s]+)") +--~ end + +-- as we use this a lot ... + +--~ function aux.cachefunction(action,weak) +--~ local cache = { } +--~ if weak then +--~ setmetatable(cache, { __mode = "kv" } ) +--~ end +--~ local function reminder(str) +--~ local found = cache[str] +--~ if not found then +--~ found = action(str) +--~ cache[str] = found +--~ end +--~ return found +--~ end +--~ return reminder, cache +--~ end diff --git a/tex/context/base/l-boolean.lua b/tex/context/base/l-boolean.lua new file mode 100644 index 000000000..be7ec7d57 --- /dev/null +++ b/tex/context/base/l-boolean.lua @@ -0,0 +1,55 @@ +if not modules then modules = { } end modules ['l-boolean'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + 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 diff --git a/tex/context/base/l-dimen.lua b/tex/context/base/l-dimen.lua new file mode 100644 index 000000000..da5ab143e --- /dev/null +++ b/tex/context/base/l-dimen.lua @@ -0,0 +1,432 @@ +if not modules then modules = { } end modules ['l-dimen'] = { + version = 1.001, + comment = "support for dimensions", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--[[ldx-- +<p>Internally <l n='luatex'/> work with scaled point, which are +represented by integers. However, in practice, at east at the +<l n='tex'/> end we work with more generic units like points (pt). Going +from scaled points (numbers) to one of those units can be +done by using the conversion factors collected in the following +table.</p> +--ldx]]-- + +local format, match, gsub, type, setmetatable = string.format, string.match, string.gsub, type, setmetatable +local P, S, R, Cc, lpegmatch = lpeg.P, lpeg.S, lpeg.R, lpeg.Cc, lpeg.match + +number = number or { } + +number.tonumberf = function(n) return match(format("%.20f",n),"(.-0?)0*$") end -- one zero too much but alas +number.tonumberg = function(n) return format("%.20g",n) end + +local dimenfactors = { + ["pt"] = 1/65536, + ["in"] = ( 100/ 7227)/65536, + ["cm"] = ( 254/ 7227)/65536, + ["mm"] = ( 2540/ 7227)/65536, + ["sp"] = 1, -- 65536 sp in 1pt + ["bp"] = ( 7200/ 7227)/65536, + ["pc"] = ( 1/ 12)/65536, + ["dd"] = ( 1157/ 1238)/65536, + ["cc"] = ( 1157/14856)/65536, + ["nd"] = (20320/21681)/65536, + ["nc"] = ( 5080/65043)/65536 +} + +--~ print(table.serialize(dimenfactors)) +--~ +--~ %.99g: +--~ +--~ t={ +--~ ["bp"]=1.5201782378580324e-005, +--~ ["cc"]=1.1883696112892098e-006, +--~ ["cm"]=5.3628510057769479e-007, +--~ ["dd"]=1.4260435335470516e-005, +--~ ["em"]=0.000152587890625, +--~ ["ex"]=6.103515625e-005, +--~ ["in"]=2.1113586636917117e-007, +--~ ["mm"]=5.3628510057769473e-008, +--~ ["nc"]=1.1917446679504327e-006, +--~ ["nd"]=1.4300936015405194e-005, +--~ ["pc"]=1.2715657552083333e-006, +--~ ["pt"]=1.52587890625e-005, +--~ ["sp"]=1, +--~ } +--~ +--~ patched %s and tonumber +--~ +--~ t={ +--~ ["bp"]=0.00001520178238, +--~ ["cc"]=0.00000118836961, +--~ ["cm"]=0.0000005362851, +--~ ["dd"]=0.00001426043534, +--~ ["em"]=0.00015258789063, +--~ ["ex"]=0.00006103515625, +--~ ["in"]=0.00000021113587, +--~ ["mm"]=0.00000005362851, +--~ ["nc"]=0.00000119174467, +--~ ["nd"]=0.00001430093602, +--~ ["pc"]=0.00000127156576, +--~ ["pt"]=0.00001525878906, +--~ ["sp"]=1, +--~ } + +--[[ldx-- +<p>A conversion function that takes a number, unit (string) and optional +format (string) is implemented using this table.</p> +--ldx]]-- + +-- was: + +local function todimen(n,unit,fmt) + if type(n) == 'string' then + return n + else + unit = unit or 'pt' + return format(fmt or "%s%s",n*dimenfactors[unit],unit) + -- if fmt then + -- return format(fmt,n*dimenfactors[unit],unit) + -- else + -- return match(format("%.20f",n*dimenfactors[unit]),"(.-0?)0*$") .. unit + -- end + end +end + +--[[ldx-- +<p>We collect a bunch of converters in the <type>number</type> namespace.</p> +--ldx]]-- + +number.maxdimen = 1073741823 +number.todimen = todimen +number.dimenfactors = dimenfactors + +function number.topoints (n) return todimen(n,"pt") end +function number.toinches (n) return todimen(n,"in") end +function number.tocentimeters (n) return todimen(n,"cm") end +function number.tomillimeters (n) return todimen(n,"mm") end +function number.toscaledpoints(n) return todimen(n,"sp") end +function number.toscaledpoints(n) return n .. "sp" end +function number.tobasepoints (n) return todimen(n,"bp") end +function number.topicas (n) return todimen(n "pc") end +function number.todidots (n) return todimen(n,"dd") end +function number.tociceros (n) return todimen(n,"cc") end +function number.tonewdidots (n) return todimen(n,"nd") end +function number.tonewciceros (n) return todimen(n,"nc") end + +--[[ldx-- +<p>More interesting it to implement a (sort of) dimen datatype, one +that permits calculations too. First we define a function that +converts a string to scaledpoints. We use <l n='lpeg'/>. We capture +a number and optionally a unit. When no unit is given a constant +capture takes place.</p> +--ldx]]-- + +local amount = (S("+-")^0 * R("09")^0 * P(".")^0 * R("09")^0) + Cc("0") +local unit = R("az")^1 + +local dimenpair = amount/tonumber * (unit^1/dimenfactors + Cc(1)) -- tonumber is new + +lpeg.patterns.dimenpair = dimenpair + +--[[ldx-- +<p>We use a metatable to intercept errors. When no key is found in +the table with factors, the metatable will be consulted for an +alternative index function.</p> +--ldx]]-- + +local mt = { } setmetatable(dimenfactors,mt) + +mt.__index = function(t,s) + -- error("wrong dimension: " .. (s or "?")) -- better a message + return false +end + +function string:todimen() + if type(self) == "number" then + return self + else + local value, unit = lpegmatch(dimenpair,self) + return value/unit + end +end + +local amount = S("+-")^0 * R("09")^0 * S(".,")^0 * R("09")^0 +local unit = P("pt") + P("cm") + P("mm") + P("sp") + P("bp") + P("in") + + P("pc") + P("dd") + P("cc") + P("nd") + P("nc") + +local validdimen = amount * unit + +lpeg.patterns.validdimen = pattern + +--[[ldx-- +<p>This converter accepts calls like:</p> + +<typing> +string.todimen("10") +string.todimen(".10") +string.todimen("10.0") +string.todimen("10.0pt") +string.todimen("10pt") +string.todimen("10.0pt") +</typing> + +<p>And of course the often more efficient:</p> + +<typing> +somestring:todimen("12.3cm") +</typing> + +<p>With this in place, we can now implement a proper datatype for dimensions, one +that permits us to do this:</p> + +<typing> +s = dimen "10pt" + dimen "20pt" + dimen "200pt" + - dimen "100sp" / 10 + "20pt" + "0pt" +</typing> + +<p>We create a local metatable for this new type:</p> +--ldx]]-- + +local dimensions = { } + +--[[ldx-- +<p>The main (and globally) visible representation of a dimen is defined next: it is +a one-element table. The unit that is returned from the match is normally a number +(one of the previously defined factors) but we also accept functions. Later we will +see why.</p> +--ldx]]-- + +function dimen(a) + if a then + local ta= type(a) + if ta == "string" then + local value, unit = lpegmatch(pattern,a) + if type(unit) == "function" then + k = value/unit() + else + k = value/unit + end + a = k + elseif ta == "table" then + a = a[1] + end + return setmetatable({ a }, dimensions) + else + return setmetatable({ 0 }, dimensions) + end +end + +--[[ldx-- +<p>This function return a small hash with a metatable attached. It is +through this metatable that we can do the calculations. We could have +shared some of the code but for reasons of speed we don't.</p> +--ldx]]-- + +function dimensions.__add(a, b) + local ta, tb = type(a), type(b) + if ta == "string" then a = a:todimen() elseif ta == "table" then a = a[1] end + if tb == "string" then b = b:todimen() elseif tb == "table" then b = b[1] end + return setmetatable({ a + b }, dimensions) +end + +function dimensions.__sub(a, b) + local ta, tb = type(a), type(b) + if ta == "string" then a = a:todimen() elseif ta == "table" then a = a[1] end + if tb == "string" then b = b:todimen() elseif tb == "table" then b = b[1] end + return setmetatable({ a - b }, dimensions) +end + +function dimensions.__mul(a, b) + local ta, tb = type(a), type(b) + if ta == "string" then a = a:todimen() elseif ta == "table" then a = a[1] end + if tb == "string" then b = b:todimen() elseif tb == "table" then b = b[1] end + return setmetatable({ a * b }, dimensions) +end + +function dimensions.__div(a, b) + local ta, tb = type(a), type(b) + if ta == "string" then a = a:todimen() elseif ta == "table" then a = a[1] end + if tb == "string" then b = b:todimen() elseif tb == "table" then b = b[1] end + return setmetatable({ a / b }, dimensions) +end + +function dimensions.__unm(a) + local ta = type(a) + if ta == "string" then a = a:todimen() elseif ta == "table" then a = a[1] end + return setmetatable({ - a }, dimensions) +end + +--[[ldx-- +<p>It makes no sense to implement the power and modulo function but +the next two do make sense because they permits is code like:</p> + +<typing> +local a, b = dimen "10pt", dimen "11pt" +... +if a > b then + ... +end +</typing> +--ldx]]-- + +-- makes no sense: dimensions.__pow and dimensions.__mod + +function dimensions.__lt(a, b) + return a[1] < b[1] +end + +function dimensions.__eq(a, b) + return a[1] == b[1] +end + +--[[ldx-- +<p>We also need to provide a function for conversion to string (so that +we can print dimensions). We print them as points, just like <l n='tex'/>.</p> +--ldx]]-- + +function dimensions.__tostring(a) + return a[1]/65536 .. "pt" -- instead of todimen(a[1]) +end + +--[[ldx-- +<p>Since it does not take much code, we also provide a way to access +a few accessors</p> + +<typing> +print(dimen().pt) +print(dimen().sp) +</typing> +--ldx]]-- + +function dimensions.__index(tab,key) + local d = dimenfactors[key] + if not d then + error("illegal property of dimen: " .. key) + d = 1 + end + return 1/d +end + +--[[ldx-- +<p>In the converter from string to dimension we support functions as +factors. This is because in <l n='tex'/> we have a few more units: +<type>ex</type> and <type>em</type>. These are not constant factors but +depend on the current font. They are not defined by default, but need +an explicit function call. This is because at the moment that this code +is loaded, the relevant tables that hold the functions needed may not +yet be available.</p> +--ldx]]-- + +function dimensions.texify() -- todo: % + 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 + else + dimenfactors["ex"] = 1/65536* 4 -- 4pt + dimenfactors["em"] = 1/65536*10 -- 10pt + end +end + +--[[ldx-- +<p>In order to set the defaults we call this function now. At some point +the macro package needs to make sure the function is called again.</p> +--ldx]]-- + +dimensions.texify() + +--[[ldx-- +<p>The previous code is rather efficient (also thanks to <l n='lpeg'/>) but we +can speed it up by caching converted dimensions. On my machine (2008) the following +loop takes about 25.5 seconds.</p> + +<typing> +for i=1,1000000 do + local s = dimen "10pt" + dimen "20pt" + dimen "200pt" + - dimen "100sp" / 10 + "20pt" + "0pt" +end +</typing> + +<p>When we cache converted strings this becomes 16.3 seconds. In order not +to waste too much memory on it, we tag the values of the cache as being +week which mean that the garbage collector will collect them in a next +sweep. This means that in most cases the speed up is mostly affecting the +current couple of calculations and as such the speed penalty is small.</p> + +<p>We redefine two previous defined functions that can benefit from +this:</p> +--ldx]]-- + +local known = { } setmetatable(known, { __mode = "v" }) + +function dimen(a) + if a then + local ta= type(a) + if ta == "string" then + local k = known[a] + if k then + a = k + else + local value, unit = lpegmatch(dimenpair,a) + if type(unit) == "function" then + k = value/unit() + else + k = value/unit + end + known[a] = k + a = k + end + elseif ta == "table" then + a = a[1] + end + return setmetatable({ a }, dimensions) + else + return setmetatable({ 0 }, dimensions) + end +end + +function string:todimen() + if type(self) == "number" then + return self + else + local k = known[self] + if not k then + local value, unit = lpegmatch(dimenpair,self) + if value and unit then + k = value/unit + else + k = 0 + end + -- print(self,value,unit) + known[self] = k + end + return k + end +end + +function number.toscaled(d) + return format("0.5f",d/2^16) +end + +--[[ldx-- +<p>In a similar fashion we can define a glue datatype. In that case we +probably use a hash instead of a one-element table.</p> +--ldx]]-- + +--[[ldx-- +<p>Goodie:s</p> +--ldx]]-- + +function number.percent(n) -- will be cleaned up once luatex 0.30 is out + local hsize = tex.hsize + if type(hsize) == "string" then + hsize = hsize:todimen() + end + return (n/100) * hsize +end + +number["%"] = number.percent diff --git a/tex/context/base/l-dir.lua b/tex/context/base/l-dir.lua new file mode 100644 index 000000000..2643f538b --- /dev/null +++ b/tex/context/base/l-dir.lua @@ -0,0 +1,363 @@ +if not modules then modules = { } end modules ['l-dir'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- dir.expand_name will be merged with cleanpath and collapsepath + +local type = type +local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub +local lpegmatch = lpeg.match + +dir = dir or { } + +-- handy + +function dir.current() + return (gsub(lfs.currentdir(),"\\","/")) +end + +-- optimizing for no string.find (*) does not save time + +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 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 + +local function collect_pattern(path,patt,recurse,result) + local ok, scanner + result = result or { } + 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 attr = attributes(full) + local mode = attr.mode + if mode == 'file' then + if find(full,patt) then + result[name] = attr + end + elseif recurse and (mode == "directory") and (name ~= '.') and (name ~= "..") then + attr.list = collect_pattern(full,patt,recurse) + result[name] = attr + end + end + end + return result +end + +dir.collect_pattern = collect_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 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 function glob(str,t) + if type(t) == "function" then + if type(str) == "table" then + for s=1,#str do + glob(str[s],t) + end + elseif lfs.isfile(str) then + t(str) + else + local split = lpegmatch(pattern,str) + if split then + local root, path, base = split[1], split[2], split[3] + local recurse = find(base,"%*%*") + local start = root .. path + local result = lpegmatch(filter,start .. base) + glob_pattern(start,result,recurse,t) + end + end + else + 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 = lpegmatch(pattern,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 = find(base,"%*%*") + local start = root .. path + local result = lpegmatch(filter,start .. base) + glob_pattern(start,result,recurse,action) + return t + else + return { } + end + end + end +end + +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") + +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 + end + return files +end + +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")) + +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") + +local make_indeed = true -- false + +if string.find(os.getenv("PATH"),";") then -- os.type == "windows" + + function dir.mkdirs(...) + local str, pth, t = "", "", { ... } + for i=1,#t do + local s = t[i] + if s ~= "" then + if str ~= "" then + str = str .. "/" .. s + else + str = s + end + end + end + local first, middle, last + local drive = false + first, middle, last = match(str,"^(//)(//*)(.*)$") + if first then + -- empty network path == local path + else + first, last = match(str,"^(//)/*(.-)$") + if first then + middle, last = match(str,"([^/]+)/+(.-)$") + if middle then + pth = "//" .. middle + else + pth = "//" .. last + last = "" + end + else + first, middle, last = match(str,"^([a-zA-Z]:)(/*)(.-)$") + if first then + pth, drive = first .. middle, true + else + middle, last = match(str,"^(/*)(.-)$") + if not middle then + last = str + end + end + 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 + end + return pth, (lfs.isdir(pth) == true) + end + +--~ print(dir.mkdirs("","","a","c")) +--~ print(dir.mkdirs("a")) +--~ print(dir.mkdirs("a:")) +--~ print(dir.mkdirs("a:/b/c")) +--~ print(dir.mkdirs("a:b/c")) +--~ print(dir.mkdirs("a:/bbb/c")) +--~ print(dir.mkdirs("/a/b/c")) +--~ print(dir.mkdirs("/aaa/b/c")) +--~ print(dir.mkdirs("//a/b/c")) +--~ print(dir.mkdirs("///a/b/c")) +--~ print(dir.mkdirs("a/bbb//ccc/")) + + function dir.expand_name(str) -- will be merged with cleanpath and collapsepath + local first, nothing, last = match(str,"^(//)(//*)(.*)$") + if first then + first = dir.current() .. "/" + end + if not first then + first, last = match(str,"^(//)/*(.*)$") + end + if not first then + first, last = match(str,"^([a-zA-Z]:)(.*)$") + if first and not find(last,"^/") then + local d = lfs.currentdir() + if lfs.chdir(first) then + first = dir.current() + end + lfs.chdir(d) + end + end + if not first then + first, last = dir.current(), str + end + last = gsub(last,"//","/") + last = gsub(last,"/%./","/") + last = gsub(last,"^/*","") + first = gsub(first,"/*$","") + if last == "" then + return first + else + return first .. "/" .. last + end + end + +else + + function dir.mkdirs(...) + local str, pth, t = "", "", { ... } + for i=1,#t do + local s = t[i] + if s ~= "" then + if str ~= "" then + str = str .. "/" .. s + else + str = s + end + end + end + str = gsub(str,"/+","/") + if find(str,"^/") then + pth = "/" + for s in gmatch(str,"[^/]+") 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 gmatch(str,"[^/]+") do + pth = pth .. "/" .. s + if make_indeed and not lfs.isdir(pth) then + lfs.mkdir(pth) + end + end + end + return pth, (lfs.isdir(pth) == true) + end + +--~ print(dir.mkdirs("","","a","c")) +--~ print(dir.mkdirs("a")) +--~ print(dir.mkdirs("/a/b/c")) +--~ print(dir.mkdirs("/aaa/b/c")) +--~ print(dir.mkdirs("//a/b/c")) +--~ print(dir.mkdirs("///a/b/c")) +--~ print(dir.mkdirs("a/bbb//ccc/")) + + function dir.expand_name(str) -- will be merged with cleanpath and collapsepath + if not find(str,"^/") then + str = lfs.currentdir() .. "/" .. str + end + str = gsub(str,"//","/") + str = gsub(str,"/%./","/") + return str + end + +end + +dir.makedirs = dir.mkdirs diff --git a/tex/context/base/l-file.lua b/tex/context/base/l-file.lua new file mode 100644 index 000000000..2bfc07090 --- /dev/null +++ b/tex/context/base/l-file.lua @@ -0,0 +1,314 @@ +if not modules then modules = { } end modules ['l-file'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + 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, sub, char = string.find, string.gmatch, string.match, string.gsub, string.sub, string.char +local lpegmatch = lpeg.match + +function file.removesuffix(filename) + return (gsub(filename,"%.[%a%d]+$","")) +end + +function file.addsuffix(filename, suffix) + if not suffix or suffix == "" then + return filename + elseif 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,default) + return match(name,"^.+%.([^/\\]-)$") or default or "" +end + +file.suffix = file.extname + +--~ 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 + +local trick_1 = char(1) +local trick_2 = "^" .. trick_1 .. "/+" + +function file.join(...) + local lst = { ... } + local a, b = lst[1], lst[2] + if a == "" then + lst[1] = trick_1 + elseif b and find(a,"^/+$") and find(b,"^/") then + lst[1] = "" + lst[2] = gsub(b,"^/+","") + end + local pth = concat(lst,"/") + 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 + pth = gsub(pth,trick_2,"") + return (gsub(pth,"//+","/")) +end + +--~ print(file.join("//","/y")) +--~ print(file.join("/","/y")) +--~ print(file.join("","/y")) +--~ print(file.join("/x/","/y")) +--~ 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.iswritable(name) + local a = lfs.attributes(name) or lfs.attributes(file.dirname(name,".")) + return a and sub(a.permissions,2,2) == "w" +end + +function file.isreadable(name) + local a = lfs.attributes(name) + return a and sub(a.permissions,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 + +local checkedsplit = string.checkedsplit + +function file.split_path(str,separator) + str = gsub(str,"\\","/") + return checkedsplit(str,separator or io.pathseparator) +end + +function file.join_path(tab) + return concat(tab,io.pathseparator) -- can have trailing // +end + +-- we can hash them weakly + +function file.collapse_path(str) + str = gsub(str,"\\","/") + if find(str,"/") then + str = gsub(str,"^%./",(gsub(lfs.currentdir(),"\\","/")) .. "/") -- ./xx in qualified + 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,"^%./","") -- ./xx in qualified + str = gsub(str,"/%.$","") + end + if str == "" then str = "." end + return str +end + +--~ print(file.collapse_path("/a")) +--~ 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 lpegmatch(pattern,name) or "" +--~ end + +--~ local pattern = lpeg.Cs(((period * noperiod^1 * -1)/"" + 1)^1) + +--~ function file.removesuffix(name) +--~ return lpegmatch(pattern,name) +--~ end + +--~ local pattern = (noslashes^0 * slashes)^1 * lpeg.C(noslashes^1) * -1 + +--~ function file.basename(name) +--~ return lpegmatch(pattern,name) or name +--~ end + +--~ local pattern = (noslashes^0 * slashes)^1 * lpeg.Cp() * noslashes^1 * -1 + +--~ function file.dirname(name) +--~ local p = lpegmatch(pattern,name) +--~ if p then +--~ return sub(name,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 = lpegmatch(pattern,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 = lpegmatch(pattern,name) +--~ if p then +--~ return sub(name,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 = lpegmatch(pattern,name) +--~ if b then +--~ return sub(name,a,b-2) +--~ elseif a then +--~ return sub(name,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 lpegmatch(qualified,filename) ~= nil +end + +function file.is_rootbased_path(filename) + return lpegmatch(rootbased,filename) ~= nil +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 lpegmatch(pattern,str) +end + +-- function test(t) for k, v in next, 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" } + +--~ -- todo: +--~ +--~ if os.type == "windows" then +--~ local currentdir = lfs.currentdir +--~ function lfs.currentdir() +--~ return (gsub(currentdir(),"\\","/")) +--~ end +--~ end diff --git a/tex/context/base/l-io.lua b/tex/context/base/l-io.lua new file mode 100644 index 000000000..66e279309 --- /dev/null +++ b/tex/context/base/l-io.lua @@ -0,0 +1,187 @@ +if not modules then modules = { } end modules ['l-io'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local byte, find, gsub = string.byte, string.find, string.gsub + +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 + -- collectgarbage("step") -- sometimes makes a big difference in mem consumption + 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 or "") + 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 = gsub(answer,"^%s*(.*)%s*$","%1") + if answer == "" and default then + return default + elseif not options then + return answer + else + for k=1,#options do + if options[k] == answer then + return answer + end + end + local pattern = "^" .. answer + for k=1,#options do + local v = options[k] + if find(v,pattern) then + return v + end + end + end + end +end diff --git a/tex/context/base/l-lpeg.lua b/tex/context/base/l-lpeg.lua new file mode 100644 index 000000000..b107a8e64 --- /dev/null +++ b/tex/context/base/l-lpeg.lua @@ -0,0 +1,165 @@ +if not modules then modules = { } end modules ['l-lpeg'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local lpeg = require("lpeg") + +lpeg.patterns = lpeg.patterns or { } -- so that we can share +local patterns = lpeg.patterns + +local P, R, S, Ct, C, Cs, Cc, V = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc, lpeg.V +local match = lpeg.match + +local digit, sign = R('09'), S('+-') +local cr, lf, crlf = P("\r"), P("\n"), P("\r\n") +local utf8byte = R("\128\191") + +patterns.utf8byte = utf8byte +patterns.utf8one = R("\000\127") +patterns.utf8two = R("\194\223") * utf8byte +patterns.utf8three = R("\224\239") * utf8byte * utf8byte +patterns.utf8four = R("\240\244") * utf8byte * utf8byte * utf8byte + +patterns.digit = digit +patterns.sign = sign +patterns.cardinal = sign^0 * digit^1 +patterns.integer = sign^0 * digit^1 +patterns.float = sign^0 * digit^0 * P('.') * digit^1 +patterns.number = patterns.float + patterns.integer +patterns.oct = P("0") * R("07")^1 +patterns.octal = patterns.oct +patterns.HEX = P("0x") * R("09","AF")^1 +patterns.hex = P("0x") * R("09","af")^1 +patterns.hexadecimal = P("0x") * R("09","AF","af")^1 +patterns.lowercase = R("az") +patterns.uppercase = R("AZ") +patterns.letter = patterns.lowercase + patterns.uppercase +patterns.space = S(" ") +patterns.eol = S("\n\r") +patterns.spacer = S(" \t\f\v") -- + string.char(0xc2, 0xa0) if we want utf (cf mail roberto) +patterns.newline = crlf + cr + lf +patterns.nonspace = 1 - patterns.space +patterns.nonspacer = 1 - patterns.spacer +patterns.whitespace = patterns.eol + patterns.spacer +patterns.nonwhitespace = 1 - patterns.whitespace +patterns.utf8 = patterns.utf8one + patterns.utf8two + patterns.utf8three + patterns.utf8four +patterns.utfbom = P('\000\000\254\255') + P('\255\254\000\000') + P('\255\254') + P('\254\255') + P('\239\187\191') + +function lpeg.anywhere(pattern) --slightly adapted from website + return P { P(pattern) + 1 * V(1) } -- why so complex? +end + +function lpeg.splitter(pattern, action) + return (((1-P(pattern))^1)/action+1)^0 +end + +local spacing = patterns.spacer^0 * patterns.newline -- sort of strip +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 match(capture,self) +end + +patterns.textline = content + +--~ local p = lpeg.splitat("->",false) print(match(p,"oeps->what->more")) -- oeps what more +--~ local p = lpeg.splitat("->",true) print(match(p,"oeps->what->more")) -- oeps what->more +--~ local p = lpeg.splitat("->",false) print(match(p,"oeps")) -- oeps +--~ local p = lpeg.splitat("->",true) print(match(p,"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 lpeg.split(separator,str) + local c = cache[separator] + if not c then + c = Ct(splitat(separator)) + cache[separator] = c + end + return match(c,str) +end + +function string:split(separator) + local c = cache[separator] + if not c then + c = Ct(splitat(separator)) + cache[separator] = c + end + return match(c,self) +end + +lpeg.splitters = cache + +local cache = { } + +function lpeg.checkedsplit(separator,str) + local c = cache[separator] + if not c then + separator = P(separator) + local other = C((1 - separator)^0) + c = Ct(separator^0 * other * (separator^1 * other)^0) + cache[separator] = c + end + return match(c,str) +end + +function string:checkedsplit(separator) + local c = cache[separator] + if not c then + separator = P(separator) + local other = C((1 - separator)^0) + c = Ct(separator^0 * other * (separator^1 * other)^0) + cache[separator] = c + end + return match(c,self) +end + +--~ function lpeg.append(list,pp) +--~ local p = pp +--~ for l=1,#list do +--~ if p then +--~ p = p + P(list[l]) +--~ else +--~ p = P(list[l]) +--~ end +--~ end +--~ return p +--~ end + +--~ from roberto's site: + +local f1 = string.byte + +local function f2(s) local c1, c2 = f1(s,1,2) return c1 * 64 + c2 - 12416 end +local function f3(s) local c1, c2, c3 = f1(s,1,3) return (c1 * 64 + c2) * 64 + c3 - 925824 end +local function f4(s) local c1, c2, c3, c4 = f1(s,1,4) return ((c1 * 64 + c2) * 64 + c3) * 64 + c4 - 63447168 end + +patterns.utf8byte = patterns.utf8one/f1 + patterns.utf8two/f2 + patterns.utf8three/f3 + patterns.utf8four/f4 diff --git a/tex/context/base/l-math.lua b/tex/context/base/l-math.lua new file mode 100644 index 000000000..fc8db4721 --- /dev/null +++ b/tex/context/base/l-math.lua @@ -0,0 +1,41 @@ +if not modules then modules = { } end modules ['l-math'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + 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 diff --git a/tex/context/base/l-md5.lua b/tex/context/base/l-md5.lua new file mode 100644 index 000000000..27955ef9b --- /dev/null +++ b/tex/context/base/l-md5.lua @@ -0,0 +1,72 @@ +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" +} + +-- This also provides file checksums and checkers. + +local gsub, format, byte = string.gsub, string.format, string.byte + +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 + +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 (gsub(data,"%s","")) + end + return nil +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 new file mode 100644 index 000000000..a1249f055 --- /dev/null +++ b/tex/context/base/l-number.lua @@ -0,0 +1,58 @@ +if not modules then modules = { } end modules ['l-number'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local tostring = tostring +local format, floor, insert, match = string.format, math.floor, table.insert, string.match +local lpegmatch = lpeg.match + +number = number or { } + +-- a,b,c,d,e,f = number.toset(100101) + +function number.toset(n) + return match(tostring(n),"(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)") +end + +function number.toevenhex(n) + local s = format("%X",n) + if #s % 2 == 0 then + return s + else + return "0" .. s + end +end + +-- the lpeg way is slower on 8 digits, but faster on 4 digits, some 7.5% +-- on +-- +-- for i=1,1000000 do +-- local a,b,c,d,e,f,g,h = number.toset(12345678) +-- local a,b,c,d = number.toset(1234) +-- local a,b,c = number.toset(123) +-- end +-- +-- of course dedicated "(.)(.)(.)(.)" matches are even faster + +local one = lpeg.C(1-lpeg.S(''))^1 + +function number.toset(n) + return lpegmatch(one,tostring(n)) +end + +function number.bits(n,zero) + local t, i = { }, (zero and 0) or 1 + while n > 0 do + local m = n % 2 + if m > 0 then + insert(t,1,i) + end + n = floor(n/2) + i = i + 1 + end + return t +end diff --git a/tex/context/base/l-os.lua b/tex/context/base/l-os.lua new file mode 100644 index 000000000..fba2cd317 --- /dev/null +++ b/tex/context/base/l-os.lua @@ -0,0 +1,301 @@ +if not modules then modules = { } end modules ['l-os'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- maybe build io.flush in os.execute + +local find, format, gsub = string.find, string.format, string.gsub +local random, ceil = math.random, math.ceil + +local execute, spawn, exec, ioflush = os.execute, os.spawn or os.execute, os.exec or os.execute, io.flush + +function os.execute(...) ioflush() return execute(...) end +function os.spawn (...) ioflush() return spawn (...) end +function os.exec (...) ioflush() return exec (...) end + +function os.resultof(command) + ioflush() -- else messed up logging + local handle = io.popen(command,"r") + if not handle then + -- print("unknown command '".. command .. "' in os.resultof") + return "" + else + return handle:read("*all") or "" + end +end + +--~ os.type : windows | unix (new, we already guessed os.platform) +--~ os.name : windows | msdos | linux | macosx | solaris | .. | generic (new) +--~ os.platform : extended os.name with architecture + +if not io.fileseparator then + if find(os.getenv("PATH"),";") then + io.fileseparator, io.pathseparator, os.type = "\\", ";", os.type or "mswin" + else + io.fileseparator, io.pathseparator, os.type = "/" , ":", os.type or "unix" + end +end + +os.type = os.type or (io.pathseparator == ";" and "windows") or "unix" +os.name = os.name or (os.type == "windows" and "mswin" ) or "linux" + +if os.type == "windows" then + os.libsuffix, os.binsuffix = 'dll', 'exe' +else + os.libsuffix, os.binsuffix = 'so', '' +end + +function os.launch(str) + if os.type == "windows" then + os.execute("start " .. str) -- os.spawn ? + else + os.execute(str .. " &") -- os.spawn ? + end +end + +if not os.times then + -- utime = user time + -- stime = system time + -- cutime = children user time + -- cstime = children system time + function os.times() + return { + utime = os.gettimeofday(), -- user + stime = 0, -- system + cutime = 0, -- children user + cstime = 0, -- children system + } + end +end + +os.gettimeofday = os.gettimeofday or os.clock + +local startuptime = os.gettimeofday() + +function os.runtime() + return os.gettimeofday() - startuptime +end + +--~ print(os.gettimeofday()-os.time()) +--~ os.sleep(1.234) +--~ print (">>",os.runtime()) +--~ print(os.date("%H:%M:%S",os.gettimeofday())) +--~ print(os.date("%H:%M:%S",os.time())) + +-- no need for function anymore as we have more clever code and helpers now +-- this metatable trickery might as well disappear + +os.resolvers = os.resolvers or { } + +local resolvers = os.resolvers + +local osmt = getmetatable(os) or { __index = function(t,k) t[k] = "unset" return "unset" end } -- maybe nil +local osix = osmt.__index + +osmt.__index = function(t,k) + return (resolvers[k] or osix)(t,k) +end + +setmetatable(os,osmt) + +if not os.setenv then + + -- we still store them but they won't be seen in + -- child processes although we might pass them some day + -- using command concatination + + local env, getenv = { }, os.getenv + + function os.setenv(k,v) + env[k] = v + end + + function os.getenv(k) + return env[k] or getenv(k) + end + +end + +-- we can use HOSTTYPE on some platforms + +local name, platform = os.name or "linux", os.getenv("MTX_PLATFORM") or "" + +local function guess() + local architecture = os.resultof("uname -m") or "" + if architecture ~= "" then + return architecture + end + architecture = os.getenv("HOSTTYPE") or "" + if architecture ~= "" then + return architecture + end + return os.resultof("echo $HOSTTYPE") or "" +end + +if platform ~= "" then + + os.platform = platform + +elseif os.type == "windows" then + + -- we could set the variable directly, no function needed here + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.getenv("PROCESSOR_ARCHITECTURE") or "" + if find(architecture,"AMD64") then + platform = "mswin-64" + else + platform = "mswin" + end + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "linux" then + + function os.resolvers.platform(t,k) + -- we sometims have HOSTTYPE set so let's check that first + local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or "" + if find(architecture,"x86_64") then + platform = "linux-64" + elseif find(architecture,"ppc") then + platform = "linux-ppc" + else + platform = "linux" + end + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "macosx" then + + --[[ + Identifying the architecture of OSX is quite a mess and this + is the best we can come up with. For some reason $HOSTTYPE is + a kind of pseudo environment variable, not known to the current + environment. And yes, uname cannot be trusted either, so there + is a change that you end up with a 32 bit run on a 64 bit system. + Also, some proper 64 bit intel macs are too cheap (low-end) and + therefore not permitted to run the 64 bit kernel. + ]]-- + + function os.resolvers.platform(t,k) + -- local platform, architecture = "", os.getenv("HOSTTYPE") or "" + -- if architecture == "" then + -- architecture = os.resultof("echo $HOSTTYPE") or "" + -- end + local platform, architecture = "", os.resultof("echo $HOSTTYPE") or "" + if architecture == "" then + -- print("\nI have no clue what kind of OSX you're running so let's assume an 32 bit intel.\n") + platform = "osx-intel" + elseif find(architecture,"i386") then + platform = "osx-intel" + elseif find(architecture,"x86_64") then + platform = "osx-64" + else + platform = "osx-ppc" + end + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "sunos" then + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.resultof("uname -m") or "" + if find(architecture,"sparc") then + platform = "solaris-sparc" + else -- if architecture == 'i86pc' + platform = "solaris-intel" + end + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "freebsd" then + + function os.resolvers.platform(t,k) + local platform, architecture = "", os.resultof("uname -m") or "" + if find(architecture,"amd64") then + platform = "freebsd-amd64" + else + platform = "freebsd" + end + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +elseif name == "kfreebsd" then + + function os.resolvers.platform(t,k) + -- we sometims have HOSTTYPE set so let's check that first + local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or "" + if find(architecture,"x86_64") then + platform = "kfreebsd-64" + else + platform = "kfreebsd-i386" + end + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +else + + -- platform = "linux" + -- os.setenv("MTX_PLATFORM",platform) + -- os.platform = platform + + function os.resolvers.platform(t,k) + local platform = "linux" + os.setenv("MTX_PLATFORM",platform) + os.platform = platform + return platform + end + +end + +-- beware, we set the randomseed + +-- from wikipedia: Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the +-- version number as well as two reserved bits. All other bits are set using a random or pseudorandom +-- data source. Version 4 UUIDs have the form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx with hexadecimal +-- digits x and hexadecimal digits 8, 9, A, or B for y. e.g. f47ac10b-58cc-4372-a567-0e02b2c3d479. +-- +-- as we don't call this function too often there is not so much risk on repetition + +local t = { 8, 9, "a", "b" } + +function os.uuid() + return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x", + random(0xFFFF),random(0xFFFF), + random(0x0FFF), + t[ceil(random(4))] or 8,random(0x0FFF), + random(0xFFFF), + random(0xFFFF),random(0xFFFF),random(0xFFFF) + ) +end + +local d + +function os.timezone(delta) + d = d or tonumber(tonumber(os.date("%H")-os.date("!%H"))) + if delta then + if d > 0 then + return format("+%02i:00",d) + else + return format("-%02i:00",-d) + end + else + return 1 + end +end diff --git a/tex/context/base/l-pdfview.lua b/tex/context/base/l-pdfview.lua new file mode 100644 index 000000000..627477ee8 --- /dev/null +++ b/tex/context/base/l-pdfview.lua @@ -0,0 +1,95 @@ +if not modules then modules = { } end modules ['l-pdfview'] = { + version = 1.001, + comment = "companion to mtx-context.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format, getenv = string.format, os.getenv + +pdfview = pdfview or { } + +local opencalls = { + ['default'] = "pdfopen --file", -- "pdfopen --back --file" + ['xpdf'] = "xpdfopen", +} + +local closecalls= { + ['default'] = "pdfclose --file", + ['xpdf'] = nil, +} + +local allcalls = { + ['default'] = "pdfclose --all", + ['xpdf'] = nil, +} + +if os.type == "windows" then + opencalls['okular'] = 'start "test" "c:/program files/kde/bin/okular.exe" --unique' -- todo: get focus +else + opencalls['okular'] = 'okular --unique' +end + +pdfview.METHOD = "MTX_PDFVIEW_METHOD" +pdfview.method = getenv(pdfview.METHOD) or 'default' +pdfview.method = (opencalls[pdfview.method] and pdfview.method) or 'default' + +function pdfview.methods() + return table.concat(table.sortedkeys(opencalls), " ") +end + +function pdfview.status() + return format("pdfview methods: %s, current method: %s, MTX_PDFVIEW_METHOD=%s",pdfview.methods(),pdfview.method,getenv(pdfview.METHOD) or "<unset>") +end + +local openedfiles = { } + +local function fullname(name) + return file.addsuffix(name,"pdf") +end + +function pdfview.open(...) + local opencall = opencalls[pdfview.method] + if opencall then + local t = { ... } + for i=1,#t do + local name = fullname(t[i]) + if io.exists(name) then + os.execute(format('%s "%s" 2>&1', opencall, name)) + openedfiles[name] = true + end + end + end +end + +function pdfview.close(...) + local closecall = closecalls[pdfview.method] + if closecall then + local t = { ... } + for i=1,#t do + local name = fullname(t[i]) + if openedfiles[name] then + os.execute(format('%s "%s" 2>&1', closecall, name)) + openedfiles[name] = nil + else + pdfview.closeall() + break + end + end + end +end + +function pdfview.closeall() + local allcall = allcalls[pdfview.method] + if allcall then + os.execute(format('%s 2>&1', allcall)) + end + openedfiles = { } +end + +--~ pdfview.open("t:/document/show-exa.pdf") +--~ os.sleep(3) +--~ pdfview.close("t:/document/show-exa.pdf") + +return pdfview diff --git a/tex/context/base/l-set.lua b/tex/context/base/l-set.lua new file mode 100644 index 000000000..f844d0b40 --- /dev/null +++ b/tex/context/base/l-set.lua @@ -0,0 +1,84 @@ +if not modules then modules = { } end modules ['l-set'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +set = set or { } + +local nums = { } +local tabs = { } +local concat = table.concat +local next, type = next, type + +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 next, t do + if v then + -- why bother about the leading space + s = s .. " " .. k + end + end + local n = nums[s] + if not n then + n = #tabs + 1 + tabs[n] = t + nums[s] = n + end + return n + else + return 0 + end +end + +function set.totable(n) + if n == 0 then + return { } + else + return tabs[n] or { } + end +end + +function set.tolist(n) + if n == 0 or not tabs[n] then + return "" + else + local t = { } + for k, v in next, tabs[n] do + if v then + t[#t+1] = k + end + end + return concat(t," ") + 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'} +--~ local s = set.tonumber(c) +--~ local t = set.totable(s) +--~ print(t['aap']) +--~ local c = set.create{'zus','wim','jet'} +--~ local s = set.tonumber(c) +--~ local t = set.totable(s) +--~ print(t['aap']) +--~ print(t['jet']) +--~ print(set.contains(t,'jet')) +--~ print(set.contains(t,'aap')) + diff --git a/tex/context/base/l-string.lua b/tex/context/base/l-string.lua new file mode 100644 index 000000000..9856d5212 --- /dev/null +++ b/tex/context/base/l-string.lua @@ -0,0 +1,288 @@ +if not modules then modules = { } end modules ['l-string'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + 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, lower = string.sub, string.gsub, string.find, string.match, string.gmatch, string.format, string.char, string.byte, string.rep, string.lower +local lpegmatch = lpeg.match + +-- some functions may disappear as they are not used anywhere + +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:unquote() +--~ if find(self,"^[\'\"]") then +--~ return sub(self,2,-2) +--~ else +--~ return self +--~ end +--~ end + +function string:quote() -- we could use format("%q") + return format("%q",self) +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() -- the .- is quite efficient +--~ -- return match(self,"^%s*(.-)%s*$") or "" +--~ -- return match(self,'^%s*(.*%S)') or '' -- posted on lua list +--~ return find(s,'^%s*$') and '' or match(s,'^%s*(.*%S)') +--~ end + +do -- roberto's variant: + local space = lpeg.S(" \t\v\n") + local nospace = 1 - space + local stripper = space^0 * lpeg.C((space^0 * nospace^1)^0) + function string.strip(str) + return lpegmatch(stripper,str) or "" + end +end + +function string:is_empty() + return not find(self,"%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, sub(str,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(sub(str,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 .. rep(chr or " ",m) + else + return self + end +end + +function string:lpadd(n,chr) + local m = n-#self + if m > 0 then + return 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 + +local simple_escapes = { + ["-"] = "%-", + ["."] = "%.", + ["?"] = ".", + ["*"] = ".*", +} + +function string:simpleesc() + return (gsub(self,".",simple_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 lpegmatch(pattern,self) +end + +--~ local t = { +--~ "1234567123456712345671234567", +--~ "a\tb\tc", +--~ "aa\tbb\tcc", +--~ "aaa\tbbb\tccc", +--~ "aaaa\tbbbb\tcccc", +--~ "aaaaa\tbbbbb\tccccc", +--~ "aaaaaa\tbbbbbb\tcccccc", +--~ } +--~ for k,v do +--~ print(string.tabtospace(t[k])) +--~ 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 + +function string:compactlong() -- strips newlines and leading spaces + self = gsub(self,"[\n\r]+ *","") + self = gsub(self,"^ *","") + return self +end + +function string:striplong() -- strips newlines and leading spaces + self = gsub(self,"^%s*","") + self = gsub(self,"[\n\r]+ *","\n") + return self +end + +function string:topattern(lowercase,strict) + if lowercase then + self = lower(self) + end + self = gsub(self,".",simple_escapes) + if self == "" then + self = ".*" + elseif strict then + self = "^" .. self .. "$" + end + return self +end diff --git a/tex/context/base/l-table.lua b/tex/context/base/l-table.lua new file mode 100644 index 000000000..ee395d0f1 --- /dev/null +++ b/tex/context/base/l-table.lua @@ -0,0 +1,910 @@ +if not modules then modules = { } end modules ['l-table'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + 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, match = string.format, string.find, string.gsub, string.lower, string.dump, string.match +local getmetatable, setmetatable = getmetatable, setmetatable +local type, next, tostring, tonumber, ipairs = type, next, tostring, tonumber, ipairs + +-- Starting with version 5.2 Lua no longer provide ipairs, which makes +-- sense. As we already used the for loop and # in most places the +-- impact on ConTeXt was not that large; the remaining ipairs already +-- have been replaced. In a similar fashio we also hardly used pairs. +-- +-- Just in case, we provide the fallbacks as discussed in Programming +-- in Lua (http://www.lua.org/pil/7.3.html): + +if not ipairs then + + -- for k, v in ipairs(t) do ... end + -- for k=1,#t do local v = t[k] ... end + + local function iterate(a,i) + i = i + 1 + local v = a[i] + if v ~= nil then + return i, v --, nil + end + end + + function ipairs(a) + return iterate, a, 0 + end + +end + +if not pairs then + + -- for k, v in pairs(t) do ... end + -- for k, v in next, t do ... end + + function pairs(t) + return next, t -- , nil + end + +end + +-- Also, unpack has been moved to the table table, and for compatiility +-- reasons we provide both now. + +if not table.unpack then + table.unpack = _G.unpack +elseif not unpack then + _G.unpack = table.unpack +end + +-- extra functions, some might go (when not used) + +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 + +function table.keys(t) + local k = { } + for key, _ in next, t do + k[#k+1] = key + end + return k +end + +local function compare(a,b) + return (tostring(a) < tostring(b)) +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,compare) + 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.sortedhash(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 + +table.sortedpairs = table.sortedhash + +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 + +-- roughly: 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) -- obolete, use inline code instead + return not t or not next(t) +end + +function table.one_entry(t) -- obolete, use inline code instead + local n = next(t) + return n and not next(t,n) +end + +--~ function table.starts_at(t) -- obsolete, not nice anyway +--~ 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) ) + +-- problem: there no good number_to_string converter with the best resolution + +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 + -- we could check for k (index) being number (cardinal) + if root and next(root) then + local first, last = nil, 0 -- #root cannot be trusted here (will be ok in 5.2 when ipairs is gone) + 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)) -- %.99g + end + elseif t == "string" then + if reduce and tonumber(v) 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)) -- %.99g + --~ 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)) -- %.99g + 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)) -- %.99g + end + else + if hexify then + handle(format("%s [%q]=0x%04X,",depth,k,v)) + else + handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g + end + end + elseif t == "string" then + if reduce and tonumber(v) 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) -- is this used? meybe a variant with next, ... + 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 + +-- a better one: + +local function flattened(t,f) + if not f then + f = { } + end + for k, v in next, t do + if type(v) == "table" then + flattened(v,f) + else + f[k] = v + end + end + return f +end + +table.flattened = flattened + +-- 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 and b and #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 }) -- why not __index = p ? + 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.insert_before_value(t,value,extra) + for i=1,#t do + if t[i] == extra then + remove(t,i) + end + end + for i=1,#t do + if t[i] == value then + insert(t,i,extra) + return + end + end + insert(t,1,extra) +end + +function table.insert_after_value(t,value,extra) + for i=1,#t do + if t[i] == extra then + remove(t,i) + end + end + for i=1,#t do + if t[i] == value then + insert(t,i+1,extra) + return + end + end + insert(t,#t+1,extra) +end + diff --git a/tex/context/base/l-unicode.lua b/tex/context/base/l-unicode.lua new file mode 100644 index 000000000..0c5a60142 --- /dev/null +++ b/tex/context/base/l-unicode.lua @@ -0,0 +1,199 @@ +if not modules then modules = { } end modules ['l-unicode'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +if not unicode then + + unicode = { utf8 = { } } + + local floor, char = math.floor, string.char + + function unicode.utf8.utfchar(n) + if n < 0x80 then + return char(n) + elseif n < 0x800 then + return char(0xC0 + floor(n/0x40)) .. char(0x80 + (n % 0x40)) + elseif n < 0x10000 then + return char(0xE0 + floor(n/0x1000)) .. char(0x80 + (floor(n/0x40) % 0x40)) .. char(0x80 + (n % 0x40)) + elseif n < 0x40000 then + return char(0xF0 + floor(n/0x40000)) .. char(0x80 + floor(n/0x1000)) .. char(0x80 + (floor(n/0x40) % 0x40)) .. char(0x80 + (n % 0x40)) + else -- wrong: + -- return char(0xF1 + floor(n/0x1000000)) .. char(0x80 + floor(n/0x40000)) .. char(0x80 + floor(n/0x1000)) .. char(0x80 + (floor(n/0x40) % 0x40)) .. char(0x80 + (n % 0x40)) + return "?" + end + end + +end + +utf = utf or unicode.utf8 + +local concat, utfchar, utfgsub = table.concat, utf.char, utf.gsub +local char, byte, find, bytepairs = string.char, string.byte, string.find, string.bytepairs + +-- 0 EF BB BF UTF-8 +-- 1 FF FE UTF-16-little-endian +-- 2 FE FF UTF-16-big-endian +-- 3 FF FE 00 00 UTF-32-little-endian +-- 4 00 00 FE FF UTF-32-big-endian + +unicode.utfname = { + [0] = 'utf-8', + [1] = 'utf-16-le', + [2] = 'utf-16-be', + [3] = 'utf-32-le', + [4] = 'utf-32-be' +} + +-- \000 fails in <= 5.0 but is valid in >=5.1 where %z is depricated + +function unicode.utftype(f) + local str = f:read(4) + if not str then + f:seek('set') + return 0 + -- elseif find(str,"^%z%z\254\255") then -- depricated + -- elseif find(str,"^\000\000\254\255") then -- not permitted and bugged + elseif find(str,"\000\000\254\255",1,true) then -- seems to work okay (TH) + return 4 + -- elseif find(str,"^\255\254%z%z") then -- depricated + -- elseif find(str,"^\255\254\000\000") then -- not permitted and bugged + elseif find(str,"\255\254\000\000",1,true) then -- seems to work okay (TH) + return 3 + elseif find(str,"^\254\255") then + f:seek('set',2) + return 2 + elseif find(str,"^\255\254") then + f:seek('set',2) + return 1 + elseif find(str,"^\239\187\191") then + f:seek('set',3) + return 0 + else + f:seek('set') + return 0 + end +end + +function unicode.utf16_to_utf8(str, endian) -- maybe a gsub is faster or an lpeg + local result, tmp, n, m, p = { }, { }, 0, 0, 0 + -- lf | cr | crlf / (cr:13, lf:10) + local function doit() + if n == 10 then + if p ~= 13 then + result[#result+1] = concat(tmp) + tmp = { } + p = 0 + end + elseif n == 13 then + result[#result+1] = concat(tmp) + tmp = { } + p = n + else + tmp[#tmp+1] = utfchar(n) + p = 0 + end + end + for l,r in bytepairs(str) do + if r then + if endian then + n = l*256 + r + else + n = r*256 + l + end + if m > 0 then + n = (m-0xD800)*0x400 + (n-0xDC00) + 0x10000 + m = 0 + doit() + elseif n >= 0xD800 and n <= 0xDBFF then + m = n + else + doit() + end + end + end + if #tmp > 0 then + result[#result+1] = concat(tmp) + end + return result +end + +function unicode.utf32_to_utf8(str, endian) + local result = { } + local tmp, n, m, p = { }, 0, -1, 0 + -- lf | cr | crlf / (cr:13, lf:10) + local function doit() + if n == 10 then + if p ~= 13 then + result[#result+1] = concat(tmp) + tmp = { } + p = 0 + end + elseif n == 13 then + result[#result+1] = concat(tmp) + tmp = { } + p = n + else + tmp[#tmp+1] = utfchar(n) + p = 0 + end + end + for a,b in bytepairs(str) do + if a and b then + if m < 0 then + if endian then + m = a*256*256*256 + b*256*256 + else + m = b*256 + a + end + else + if endian then + n = m + a*256 + b + else + n = m + b*256*256*256 + a*256*256 + end + m = -1 + doit() + end + else + break + end + end + if #tmp > 0 then + result[#result+1] = concat(tmp) + end + 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,".",little) + else + 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 new file mode 100644 index 000000000..e3e6f8130 --- /dev/null +++ b/tex/context/base/l-url.lua @@ -0,0 +1,134 @@ +if not modules then modules = { } end modules ['l-url'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local char, gmatch, gsub = string.char, string.gmatch, string.gsub +local tonumber, type = tonumber, type +local lpegmatch = lpeg.match + +-- from the spec (on the web): +-- +-- foo://example.com:8042/over/there?name=ferret#nose +-- \_/ \______________/\_________/ \_________/ \__/ +-- | | | | | +-- scheme authority path query fragment +-- | _____________________|__ +-- / \ / \ +-- urn:example:animal:ferret:nose + +url = url or { } + +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 hexdigit = lpeg.R("09","AF","af") +local plus = lpeg.P("+") +local escaped = (plus / " ") + (percent * lpeg.C(hexdigit * hexdigit) / tochar) + +-- we assume schemes with more than 1 character (in order to avoid problems with windows disks) + +local scheme = lpeg.Cs((escaped+(1-colon-slash-qmark-hash))^2) * 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) + +-- todo: reconsider Ct as we can as well have five return values (saves a table) +-- so we can have two parsers, one with and one without + +function url.split(str) + return (type(str) == "string" and lpegmatch(parser,str)) or str +end + +-- todo: cache them + +function url.hashed(str) + local s = url.split(str) + local somescheme = s[1] ~= "" + return { + scheme = (somescheme and s[1]) or "file", + authority = s[2], + path = s[3], + query = s[4], + fragment = s[5], + original = str, + noscheme = not somescheme, + } +end + +function url.hasscheme(str) + return url.split(str)[1] ~= "" +end + +function url.addscheme(str,scheme) + return (url.hasscheme(str) and str) or ((scheme or "file:///") .. str) +end + +function url.construct(hash) + local fullurl = hash.sheme .. "://".. hash.authority .. hash.path + if hash.query then + fullurl = fullurl .. "?".. hash.query + end + if hash.fragment then + fullurl = fullurl .. "?".. hash.fragment + end + return fullurl +end + +function url.filename(filename) + local t = url.hashed(filename) + return (t.scheme == "file" and (gsub(t.path,"^/([a-zA-Z])([:|])/)","%1:"))) or filename +end + +function url.query(str) + if type(str) == "string" then + local t = { } + for k, v in gmatch(str,"([^&=]*)=([^&=]*)") do + t[k] = v + end + return t + else + return str + end +end + +--~ print(url.filename("file:///c:/oeps.txt")) +--~ print(url.filename("c:/oeps.txt")) +--~ print(url.filename("file:///oeps.txt")) +--~ print(url.filename("file:///etc/test.txt")) +--~ print(url.filename("/oeps.txt")) + +--~ 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") +--~ test("file:///etc/oeps.txt") +--~ test("file://./etc/oeps.txt") +--~ test("file:////etc/oeps.txt") +--~ test("ftp://ftp.is.co.za/rfc/rfc1808.txt") +--~ test("http://www.ietf.org/rfc/rfc2396.txt") +--~ test("ldap://[2001:db8::7]/c=GB?objectClass?one#what") +--~ test("mailto:John.Doe@example.com") +--~ test("news:comp.infosystems.www.servers.unix") +--~ test("tel:+1-816-555-1212") +--~ test("telnet://192.0.2.16:80/") +--~ test("urn:oasis:names:specification:docbook:dtd:xml:4.1.2") +--~ test("/etc/passwords") +--~ test("http://www.pragma-ade.com/spaced%20name") + +--~ test("zip:///oeps/oeps.zip#bla/bla.tex") +--~ test("zip:///oeps/oeps.zip?bla/bla.tex") diff --git a/tex/context/base/l-utils.lua b/tex/context/base/l-utils.lua new file mode 100644 index 000000000..ebc27b8cf --- /dev/null +++ b/tex/context/base/l-utils.lua @@ -0,0 +1,176 @@ +if not modules then modules = { } end modules ['l-utils'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- hm, quite unreadable + +local gsub = string.gsub +local concat = table.concat +local type, next = type, next + +if not utils then utils = { } end +if not utils.merger then utils.merger = { } end +if not utils.lua then utils.lua = { } end + +utils.merger.m_begin = "begin library merge" +utils.merger.m_end = "end library merge" +utils.merger.pattern = + "%c+" .. + "%-%-%s+" .. utils.merger.m_begin .. + "%c+(.-)%c+" .. + "%-%-%s+" .. utils.merger.m_end .. + "%c+" + +function utils.merger._self_fake_() + return + "-- " .. "created merged file" .. "\n\n" .. + "-- " .. utils.merger.m_begin .. "\n\n" .. + "-- " .. utils.merger.m_end .. "\n\n" +end + +function utils.report(...) + print(...) +end + +utils.merger.strip_comment = true + +function utils.merger._self_load_(name) + local f, data = io.open(name), "" + if f then + utils.report("reading merge from %s",name) + data = f:read("*all") + f:close() + else + utils.report("unknown file to merge %s",name) + end + if data and utils.merger.strip_comment then + -- saves some 20K + data = gsub(data,"%-%-~[^\n\r]*[\r\n]", "") + end + return data or "" +end + +function utils.merger._self_save_(name, data) + if data ~= "" then + local f = io.open(name,'w') + if f then + utils.report("saving merge from %s",name) + f:write(data) + f:close() + end + end +end + +function utils.merger._self_swap_(data,code) + if data ~= "" then + return (gsub(data,utils.merger.pattern, function(s) + return "\n\n" .. "-- "..utils.merger.m_begin .. "\n" .. code .. "\n" .. "-- "..utils.merger.m_end .. "\n\n" + end, 1)) + else + return "" + end +end + +--~ stripper: +--~ +--~ data = gsub(data,"%-%-~[^\n]*\n","") +--~ data = gsub(data,"\n\n+","\n") + +function utils.merger._self_libs_(libs,list) + 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 i=1,#libs do + local lib = libs[i] + for j=1,#list do + local pth = gsub(list[j],"\\","/") -- 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 i=1,#libs do + local lib = libs[i] + 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 + -- wrong[#wrong+1] = lib + utils.report("no library %s",fullname) + end + end + if #right > 0 then + utils.report("merged libraries: %s",concat(right," ")) + end + if #wrong > 0 then + utils.report("skipped libraries: %s",concat(wrong," ")) + end + else + utils.report("no valid library path found") + end + return concat(result, "\n\n") +end + +function utils.merger.selfcreate(libs,list,target) + if target then + utils.merger._self_save_( + target, + utils.merger._self_swap_( + utils.merger._self_fake_(), + utils.merger._self_libs_(libs,list) + ) + ) + end +end + +function utils.merger.selfmerge(name,libs,list,target) + utils.merger._self_save_( + target or name, + utils.merger._self_swap_( + utils.merger._self_load_(name), + utils.merger._self_libs_(libs,list) + ) + ) +end + +function utils.merger.selfclean(name) + utils.merger._self_save_( + name, + utils.merger._self_swap_( + utils.merger._self_load_(name), + "" + ) + ) +end + +function utils.lua.compile(luafile, lucfile, cleanup, strip) -- defaults: cleanup=false strip=true + -- utils.report("compiling",luafile,"into",lucfile) + os.remove(lucfile) + local command = "-o " .. string.quote(lucfile) .. " " .. string.quote(luafile) + if strip ~= false then + command = "-s " .. command + end + local done = (os.spawn("texluac " .. command) == 0) or (os.spawn("luac " .. command) == 0) + if done and cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then + -- utils.report("removing",luafile) + os.remove(luafile) + end + return done +end + diff --git a/tex/context/base/l-xml.lua b/tex/context/base/l-xml.lua new file mode 100644 index 000000000..14e97337b --- /dev/null +++ b/tex/context/base/l-xml.lua @@ -0,0 +1,23 @@ +if not modules then modules = { } end modules ['l-xml'] = { + version = 1.001, + comment = "this module is replaced by the lxml-* ones", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- We asume that the helper modules l-*.lua are loaded +-- already. But anyway if you use mtxrun to run your script +-- all is taken care of. + +if not trackers then + require('trac-tra') +end + +if not xml then + require('lxml-tab') + require('lxml-lpt') + require('lxml-mis') + require('lxml-aux') + require('lxml-xml') +end diff --git a/tex/context/base/lang-all.xml b/tex/context/base/lang-all.xml new file mode 100644 index 000000000..503cb0ae5 --- /dev/null +++ b/tex/context/base/lang-all.xml @@ -0,0 +1,376 @@ +<?xml version='1.0' standalone='yes'?> + +<!-- author: Willy Egger --> + +<descriptions> + +<description language='ba'> + <sourcefile>bahyph.tex</sourcefile> + <title>TeX hyphenation patterns for the Basque language + + 1991 + Julio Sanchez (jsanchez@gmv.es) + These patterns have been derived from "On Word Division in Spanish" + Jos'e A. Ma~nas + + + 1997 + Juan M. Aguirregabiria (wtpagagj@lg.ehu.es) + Adaption to TeX based on shyphen.sh + + + + + cahyph.tex + TeX hyphenation patterns for the Catalan language + Version 1.11 + + 1991-1995 + Gon\c{c}al Badenes,Francina Turon + + + 1991-2003 + Gon\c{c}al Badenes + + + + + cyhyph.tex + TeX hyphenation patterns for the Welsh Language + v3,GNU General Public License + + 1996 + Yannis Haralambous + Inputs cathyph.tex, patterns in EC/DC encoding + + + + + czhyphen.tex + TeX hyphenation patterns for the Czech language + + 1991 + Karel Horak + List of exceptions + + + 1995 + Pavel Sevecek (\v{S}eve\v{c}ek) (pavel@lingea.cz) + Macros, adaption for TeX 2 + + + + + + dkspecial.tex dkcommon.tex + TeX hyphenation patterns for the Danish language + + + + + dehyphn.tex + TeX hyphenation patterns for the German language (new orthography) + + 1988, 1991 + Rechenzentrum der Ruhr-Universitaet Bochum + German hyphen patterns + + + 1993, 1994, 1999 + Bernd Raichle/DANTE e.V. + Macros, adaption for TeX 2 + + + 1998-2001 + Walter Schmidt + Adaption to new German orthography + + + + + dehypht.tex + TeX hyphenation patterns for the German language (traditional orthography) + + 1988, 1991 + Rechenzentrum der Ruhr-Universitaet Bochum + German hyphen patterns + + + 1993, 1994, 1999 + Bernd Raichle/DANTE e.V. + Macros, adaption for TeX 2 + + + + + hyphen.tex + Plain TeX hyphenation patterns for the English language (US) + [NOT TO BE CHANGED IN ANY WAY!] + + + + + eshyph.tex + TeX hyphenation patterns for the Spanish language + + 1993 + Francesc Carmona (franc@porthos.bio.ub.es) + + + + + fihyph.tex + TeX hyphenation patterns for the Finnish language + + 1986 + Kauko Saarinen + First release + + + 1988 + Fred Karlsson + Completely rewritten patterns + + + 1989 + Fred Karlsson + Some vowel tripples added + + + 1995 + Thomas Esser + Added \uccode and \lccode + + + + + frhyph.tex + TeX hyphenation patterns for the French language + V2.11 + + Jacques Desarmenien, Norman Buckle, Michael Ferguson, Justin Bur, Daniel Flipo and Bernard Gaulle + + + 1996 + Bernd Raichle/DANTE e.V. + Adaption for TeX 3.x and MLTeX 3.x (2.x) + + + + + hrhyph.tex + TeX hyphenation patterns for the Croatian language + + 1994, 1996 + Marinovi\'c Igor (migor@student.math.hr) + + + + + huhyphn.tex + TeX hyphenation patterns for the Hungarian language + + + + ishyph.tex + Plain TeX hyphenation patterns for the Icelandic language + [NOT TO BE CHANGED IN ANY WAY!] + + 1987 + Jorgen Pind + + + + + ithyph.tex + TeX hyphenation patterns for the Italian language + v4.8d + + 1998, 2001 + Claudio Beccari + + + 1993, 1994, 1999 + Bernd Raichle/DANTE e.V. + Macros, adaption for TeX 2 + + + + + lahyph.tex + TeX hyphenation patterns for the Latin language + v3.0b + + 1999-2001 + Claudio Beccari + + + 1993, 1994, 1998, 1999 + Bernd Raichle/DANTE e.V. + Macro code in 'dehypht.tex' + + + + + nehyph96.tex + TeX hyphenation patterns for the Dutch language + + 1996 + Piet Tutelaers (P.T.H.Tutelaers@tue.nl) + 8-bit hyphenation patterns for TeX based upon the new Dutch + spelling, officially since 1 August 1996. These patterns follow + the new hyphenation rules in the `Woordenlijst Nederlandse + Taal, SDU Uitgevers, Den Haag 1995' (the so called `Groene + Boekje') described in section 5.2 (Het afbreekteken) + + + + + + + nohyph.tex + TeX hyphenation patterns for the Norwegian language + + 2005 + Rune Kleveland with patches from Ole Michael Selberg + nohyphbx.tex + + + 200+ + Rune Kleveland + nohyphb.tex + + + 199+ + Dag Langmyhr and student + nohyph2.tex + + + 199+ + Ivar Aavatsmark and others + nohyph.tex sometimes named nohyph1.tex + + + 1992,1993 + Ivar Aavatsmark + nohyphen.tex based on danhyph.tex + + + 1994 + Preben Randhol, Jon Martin Solaas + + + 1995 + Thomas Esser (te@dbs.uni-hannover.de) + Make patterns work with non-T1 encoding + + + + + plhyph.tex + TeX hyphenation patterns for the Polish language + + + + + pthyph.tex + TeX hyphenation patterns for the Portuguese language + + + + + rohyph.tex + TeX hyphenation patterns for the Romanian language + + + + + skhyphen.tex skhyphen.ex + TeX hyphenation patterns for the Slovakian language + + 1992 + Jana Chlebikova + + + 1991 + Karel Horak + List of exceptions + + + + + sihyph.tex + TeX hyphenation patterns for the Slovenian language + + 1990 + TeXCeX (SLO),TeXCeH Norbert Schwarz + + + 1994 + Leon "Zlajpah (leon.zlajpah@ijs.si) + Use of code page 852 in patterns + + + 1995,1997 + Leon "Zlajpah (leon.zlajpah@ijs.si) + Adaptaion of Slovenian hyphenation pattens, macros + + + + + svhyph.tex + TeX hyphenation patterns for the Swedish language + + 1991,1994 + Jan Michael Rynning + + + + + tkhyph.tex + TeX hyphenation patterns for the modern Turkish language + + 1996 + Yannis Haralambous + A mechanically generated Turkish Hyphenation table for TeX, + using the University of Washington diacritical coding + developed by P. A. MacKay for the Ottoman Texts Project + + + + + ukhyphen.tex + TeX hyphenation patterns for the English language (UK) + + + + + Vietnamese needs no patterns. + + + + grahyph4.tex + TeX hyphenation patterns for the ancient Greek language + + 2004 + Dimitrios Filippou + These hyphenation patterns are explained in "ancient.pdf". + Hyphenation examples are given in the file "anc-test.pdf". + Some doubtful patterns are marked by three question marks "???". + + + + diff --git a/tex/context/base/lang-alt.tex b/tex/context/base/lang-alt.tex new file mode 100644 index 000000000..f65acbda3 --- /dev/null +++ b/tex/context/base/lang-alt.tex @@ -0,0 +1,152 @@ +%D \module +%D [ file=lang-alt, +%D version=1997.09.03, +%D title=\CONTEXT\ Language Macros, +%D subtitle=Altaic Languages, +%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}{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 +%D on, corrections were made by users. If you have suggestions, +%D or feel that your name missing here, don't hesitate to send +%D us an email. + +% Uigur, Uzbek +% Azeri/Azerbaijani, Chuvash, Turkish, Turkmen +% Kazakh, Kazar, Kireghiz, Noghay, Talar +% Buryat, Kalmuck, Khalkha +% +% Turkmen translation by Nazar Annagurban 18. March 2010 + +\unprotect + +\installlanguage + [\s!tr] + [\c!spacing=\v!packed, + \c!leftsentence=---, + \c!rightsentence=---, + \c!leftsubsentence=---, + \c!rightsubsentence=---, + \c!leftquote=\upperleftsinglesixquote, + \c!rightquote=\upperrightsingleninequote, + \c!leftquotation=\upperleftdoublesixquote, + \c!rightquotation=\upperrightdoubleninequote, + \c!date={\v!year,\ ,\v!month,\ ,\v!day}] + +\installlanguage + [\s!tk] + [\c!spacing=\v!broad, + \c!leftsentence=---, + \c!rightsentence=---, + \c!leftsubsentence=---, + \c!rightsubsentence=---, + \c!leftquote=\upperleftsinglesixquote, + \c!rightquote=\upperrightsingleninequote, + \c!leftquotation=\upperleftdoublesixquote, + \c!rightquotation=\upperrightdoubleninequote, + \c!date={\v!year,\ ,\v!month,\ ,\v!day} + \s!patterns=\s!tk, + \s!lefthyphenmin=1, + \s!righthyphenmin=2] + +\installlanguage [turkish] [\s!tr] +\installlanguage [turkmen] [\s!tk] + +\setupheadtext [\s!tr] [\v!content=Fihrist] +\setupheadtext [\s!tk] [\v!content=Mazmuny] +\setupheadtext [\s!tr] [\v!tables=Tablolar] +\setupheadtext [\s!tk] [\v!tables=Tablisalar] +\setupheadtext [\s!tr] [\v!figures=\Scedilla ekiller] +\setupheadtext [\s!tk] [\v!figures=Suratlar] +\setupheadtext [\s!tr] [\v!graphics=Grafikler] +\setupheadtext [\s!tk] [\v!graphics=Grafikler] +\setupheadtext [\s!tr] [\v!intermezzi=...] +\setupheadtext [\s!tk] [\v!intermezzi=Arakesmeler] +\setupheadtext [\s!tr] [\v!index=\Idotaccent ndex] +\setupheadtext [\s!tk] [\v!index=Indeks] +\setupheadtext [\s!tr] [\v!abbreviations=K\dotlessi saltmalar] +\setupheadtext [\s!tk] [\v!abbreviations=Gysgaltmalar] +\setupheadtext [\s!tr] [\v!logos=Logolar] +\setupheadtext [\s!tk] [\v!logos=Logolar] +\setupheadtext [\s!tr] [\v!units=Birimler] +\setupheadtext [\s!tk] [\v!units=Birlikler] + +\setuplabeltext [\s!tr] [\v!table=Tablo ] +\setuplabeltext [\s!tk] [\v!table=Tablisa] +\setuplabeltext [\s!tr] [\v!figure=\Scedilla ekil ] +\setuplabeltext [\s!tk] [\v!figure=Surat] +\setuplabeltext [\s!tr] [\v!intermezzo=... ] +\setuplabeltext [\s!tk] [\v!intermezzo=Arakesme] +\setuplabeltext [\s!tr] [\v!graphic=Grafik] +\setuplabeltext [\s!tk] [\v!graphic=Grafik] +\setuplabeltext [\s!tr] [\v!chapter=] +\setuplabeltext [\s!tk] [\v!chapter=Bap] +\setuplabeltext [\s!tr] [\v!section=] +\setuplabeltext [\s!tk] [\v!section=] +\setuplabeltext [\s!tr] [\v!subsection=] +\setuplabeltext [\s!tk] [\v!subsection=] +\setuplabeltext [\s!tr] [\v!subsubsection=] +\setuplabeltext [\s!tr] [\v!subsubsubsection=] +\setuplabeltext [\s!tk] [\v!subsubsubsection=] +\setuplabeltext [\s!tr] [\v!appendix=] +\setuplabeltext [\s!tk] [\v!appendix=Go\scedilla ma\ccedilla a] +\setuplabeltext [\s!tr] [\v!part=Cilt ] +\setuplabeltext [\s!tk] [\v!part=B\odiaeresis l\udiaeresis m] +\setuplabeltext [\s!tr] [\v!line=sat\dotlessi r ] +\setuplabeltext [\s!tk] [\v!line=setir] +\setuplabeltext [\s!tr] [\v!lines=sat\dotlessi rlar ] +\setuplabeltext [\s!tk] [\v!lines=setirler] + +\setuplabeltext [\s!tk] [\v!january=\yacute anwar] +\setuplabeltext [\s!tk] [\v!february=fewral] +\setuplabeltext [\s!tk] [\v!march=mart] +\setuplabeltext [\s!tk] [\v!april=aprel] +\setuplabeltext [\s!tk] [\v!may=ma\yacute] +\setuplabeltext [\s!tk] [\v!june=i\yacute un] +\setuplabeltext [\s!tk] [\v!july=i\yacute ul] +\setuplabeltext [\s!tk] [\v!august=awgust] +\setuplabeltext [\s!tk] [\v!september=sent\yacute abr] +\setuplabeltext [\s!tk] [\v!october=okt\yacute abr] +\setuplabeltext [\s!tk] [\v!november=no\yacute abr] +\setuplabeltext [\s!tk] [\v!december=dekabr] + +\setuplabeltext [\s!tr] [\v!january=ocak] +\setuplabeltext [\s!tr] [\v!february=\Scedilla ubat] +\setuplabeltext [\s!tr] [\v!march=mart] +\setuplabeltext [\s!tr] [\v!april=nisan] +\setuplabeltext [\s!tr] [\v!may=may\dotlessi s] +\setuplabeltext [\s!tr] [\v!june=haziran] +\setuplabeltext [\s!tr] [\v!july=temmuz] +\setuplabeltext [\s!tr] [\v!august=a\gbreve ustos] +\setuplabeltext [\s!tr] [\v!september=eyl\udiaeresis l] +\setuplabeltext [\s!tr] [\v!october=ekim] +\setuplabeltext [\s!tr] [\v!november=kas\dotlessi m] +\setuplabeltext [\s!tr] [\v!december=aral\dotlessi k] + +\setuplabeltext [\s!tr] [\v!sunday=pazar] +\setuplabeltext [\s!tr] [\v!monday=pazartesi] +\setuplabeltext [\s!tr] [\v!tuesday=sal\dotlessi] +\setuplabeltext [\s!tr] [\v!wednesday=\ccedilla ar\scedilla amba] +\setuplabeltext [\s!tr] [\v!thursday=per\scedilla embe] +\setuplabeltext [\s!tr] [\v!friday=cuma] +\setuplabeltext [\s!tr] [\v!saturday=cumartesi] + +\setuplabeltext [\s!tk] [\v!sunday=dyn\ccedilla\ g\udiaeresis n] +\setuplabeltext [\s!tk] [\v!monday=birinji g\udiaeresis n] +\setuplabeltext [\s!tk] [\v!tuesday=ikinji g\udiaeresis n] +\setuplabeltext [\s!tk] [\v!wednesday=\udiaeresis\ccedilla\udiaeresis nji] +\setuplabeltext [\s!tk] [\v!thursday=d\odiaeresis rd\udiaeresis nji g\udiaeresis n] +\setuplabeltext [\s!tk] [\v!friday=b\adiaeresis\scedilla inji g\udiaeresis n] +\setuplabeltext [\s!tk] [\v!saturday=altynjy g\udiaeresis n] + +%D \ShowAllLanguageValues [\s!tr] [turkish] {Turkish} {delight} % turks fruit + +\protect \endinput diff --git a/tex/context/base/lang-ana.tex b/tex/context/base/lang-ana.tex new file mode 100644 index 000000000..c108655c4 --- /dev/null +++ b/tex/context/base/lang-ana.tex @@ -0,0 +1,24 @@ +%D \module +%D [ file=lang-ana, +%D version=1997.09.03, +%D title=\CONTEXT\ Language Macros, +%D subtitle=Anatolian Languages, +%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}{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 +%D on, corrections were made by users. If you have suggestions, +%D or feel that your name missing here, don't hesitate to send +%D us an email. + +\unprotect + +\protect \endinput diff --git a/tex/context/base/lang-ara.mkiv b/tex/context/base/lang-ara.mkiv new file mode 100644 index 000000000..3c4d3c522 --- /dev/null +++ b/tex/context/base/lang-ara.mkiv @@ -0,0 +1,150 @@ +%D \module +%D [ file=lang-ara, +%D version=2008.06.20, +%D title=\CONTEXT\ Language Macros, +%D subtitle=Arabic Languages, +%D author=Khaled Hosny, +%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 Language Macros / Arabic Languages} + +\unprotect + +\definesystemconstant {arabic} +\definesystemvariable {ar} + +\installlanguage + [\s!ar] + [\c!spacing=\v!broad, + \c!leftsentence=---, + \c!rightsentence=---, + \c!leftsubsentence=---, + \c!rightsubsentence=---, + \c!leftquote=\upperleftsinglesixquote, + \c!rightquote=\upperrightsingleninequote, + \c!leftquotation=\upperleftdoublesixquote, + \c!rightquotation=\upperrightdoubleninequote, + \c!date={\v!day,\ ,\v!month,{،\ },\v!year}] + +\installlanguage [\s!arabic] [\s!ar] + +% Just aliases to "ar" for now + +\installlanguage[\s!ar-ae][\c!default=\s!ar] % U.A.E. +\installlanguage[\s!ar-bh][\c!default=\s!ar] % Bahrain +\installlanguage[\s!ar-eg][\c!default=\s!ar] % Egypt +\installlanguage[\s!ar-in][\c!default=\s!ar] % India? +\installlanguage[\s!ar-kw][\c!default=\s!ar] % Kuwait +\installlanguage[\s!ar-ly][\c!default=\s!ar] % Libya +\installlanguage[\s!ar-om][\c!default=\s!ar] % Oman +\installlanguage[\s!ar-qa][\c!default=\s!ar] % Qatar +\installlanguage[\s!ar-sa][\c!default=\s!ar] % Saudi Arabia +\installlanguage[\s!ar-sd][\c!default=\s!ar] % Sudan +\installlanguage[\s!ar-tn][\c!default=\s!ar] % Tunisia +\installlanguage[\s!ar-ye][\c!default=\s!ar] % Yemen + +% Syriac months + +\installlanguage[\s!ar-sy][\c!default=\s!ar] % Syria +\installlanguage[\s!ar-iq][\c!default=\s!ar-sy] % Iraq +\installlanguage[\s!ar-jo][\c!default=\s!ar-sy] % Jordan +\installlanguage[\s!ar-lb][\c!default=\s!ar-sy] % Lebanon + +% Maghribi months + +\installlanguage[\s!ar-dz][\c!default=\s!ar] % Algeria +\installlanguage[\s!ar-ma][\c!default=\s!ar] % Morocco + +\setupheadtext [\s!ar] [\v!content=المحتويات] +\setupheadtext [\s!ar] [\v!tables=الجداول] +\setupheadtext [\s!ar] [\v!figures=الأشكال] +\setupheadtext [\s!ar] [\v!graphics=الرسوم] +\setupheadtext [\s!ar] [\v!intermezzi=فسح] +\setupheadtext [\s!ar] [\v!index=الفهرس] +\setupheadtext [\s!ar] [\v!abbreviations=الاختصارات] +\setupheadtext [\s!ar] [\v!logos=الشعارات] +\setupheadtext [\s!ar] [\v!units=الوحدات] +\setuplabeltext [\s!ar] [\v!table=جدول ] +\setuplabeltext [\s!ar] [\v!figure=شكل ] +\setuplabeltext [\s!ar] [\v!intermezzo=فسحة ] +\setuplabeltext [\s!ar] [\v!graphic=رسم ] + +%D We don't set these here. One can do that in a style. + +\setuplabeltext [\s!ar] [\v!chapter=] % باب +\setuplabeltext [\s!ar] [\v!section=] % فصل or قسم +\setuplabeltext [\s!ar] [\v!subsection=] % فصل أدنى +\setuplabeltext [\s!ar] [\v!subsubsection=] % فصل أ دنى أدنى +\setuplabeltext [\s!ar] [\v!subsubsubsection=] % فصل أدنى أدنى أدنى +\setuplabeltext [\s!ar] [\v!appendix=] % ملحق +\setuplabeltext [\s!ar] [\v!part=جزء ] +\setuplabeltext [\s!ar] [\v!line=سطر ] +\setuplabeltext [\s!ar] [\v!lines=السطور ] + +\setuplabeltext [\s!ar] [\v!january=يناير] +\setuplabeltext [\s!ar] [\v!february=فبراير] +\setuplabeltext [\s!ar] [\v!march=مارس] +\setuplabeltext [\s!ar] [\v!april=أبريل] +\setuplabeltext [\s!ar] [\v!may=مايو] +\setuplabeltext [\s!ar] [\v!june=يونيو] +\setuplabeltext [\s!ar] [\v!july=يوليو] +\setuplabeltext [\s!ar] [\v!august=أغسطس] +\setuplabeltext [\s!ar] [\v!september=سبتمبر] +\setuplabeltext [\s!ar] [\v!october=أكتوبر] +\setuplabeltext [\s!ar] [\v!november=نوفمبر] +\setuplabeltext [\s!ar] [\v!december=ديسمبر] + +\setuplabeltext [\s!ar-sy] [\v!january=كانون الثاني] +\setuplabeltext [\s!ar-sy] [\v!february=شباط] +\setuplabeltext [\s!ar-sy] [\v!march=آذار] +\setuplabeltext [\s!ar-sy] [\v!april=نيسان] +\setuplabeltext [\s!ar-sy] [\v!may=أيار] +\setuplabeltext [\s!ar-sy] [\v!june=حزيران] +\setuplabeltext [\s!ar-sy] [\v!july=تموز] +\setuplabeltext [\s!ar-sy] [\v!august=آب] +\setuplabeltext [\s!ar-sy] [\v!september=أيلول] +\setuplabeltext [\s!ar-sy] [\v!october=تشرين الأول] +\setuplabeltext [\s!ar-sy] [\v!november=تشرين الثاني] +\setuplabeltext [\s!ar-sy] [\v!december=كانون الأول] + +\setuplabeltext [\s!ar-ma] [\v!may=ماي] +\setuplabeltext [\s!ar-ma] [\v!july=يوليوز] +\setuplabeltext [\s!ar-ma] [\v!august=غشت] +\setuplabeltext [\s!ar-ma] [\v!september=شتنبر] +\setuplabeltext [\s!ar-ma] [\v!november=نونبر] +\setuplabeltext [\s!ar-ma] [\v!december=دجنبر] + +\setuplabeltext [\s!ar-dz] [\v!january=جانفي] +\setuplabeltext [\s!ar-dz] [\v!february=فيفري] +\setuplabeltext [\s!ar-dz] [\v!april=أفريل] +\setuplabeltext [\s!ar-dz] [\v!may=ماي] +\setuplabeltext [\s!ar-dz] [\v!june=جوان] +\setuplabeltext [\s!ar-dz] [\v!july=جويلة] +\setuplabeltext [\s!ar-dz] [\v!august=أوت] + +\setuplabeltext [\s!ar] [\v!sunday=الأحد] +\setuplabeltext [\s!ar] [\v!monday=الاثنين] +\setuplabeltext [\s!ar] [\v!tuesday=الثلاثاء] +\setuplabeltext [\s!ar] [\v!wednesday=الأربعاء] +\setuplabeltext [\s!ar] [\v!thursday=الخميس] +\setuplabeltext [\s!ar] [\v!friday=الجمعة] +\setuplabeltext [\s!ar] [\v!saturday=السبت] + +%D Rather new ... + +\setuplabeltext [\s!ar] [\v!page=صفحة ] +\setuplabeltext [\s!ar] [\v!atpage=في صفحة ] +\setuplabeltext [\s!ar] [\v!hencefore=كما وضحنا سابقا] +\setuplabeltext [\s!ar] [\v!hereafter=كما نوضح لاحقا] +\setuplabeltext [\s!ar] [\v!see=انظر ] + +%D ... and to be completed! + +%D \ShowAllLanguageValues [\s!ar] [arabic] {Arabic} {horn} % engelse humor + +\protect \endinput diff --git a/tex/context/base/lang-art.tex b/tex/context/base/lang-art.tex new file mode 100644 index 000000000..e8be91630 --- /dev/null +++ b/tex/context/base/lang-art.tex @@ -0,0 +1,26 @@ +%D \module +%D [ file=lang--art, +%D version=1997.09.03, +%D title=\CONTEXT\ Language Macros, +%D subtitle=Artificial Languages, +%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}{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 +%D on, corrections were made by users. If you have suggestions, +%D or feel that your name missing here, don't hesitate to send +%D us an email. + +% Esperanto + +\unprotect + +\protect \endinput diff --git a/tex/context/base/lang-bal.tex b/tex/context/base/lang-bal.tex new file mode 100644 index 000000000..394e9d93c --- /dev/null +++ b/tex/context/base/lang-bal.tex @@ -0,0 +1,118 @@ +%D \module +%D [ file=lang-bal, +%D version=2010.01.21, +%D title=\CONTEXT\ Language Macros, +%D subtitle=Baltic Languages, +%D author=Marius Aleknevičius, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Baltic Languages} + +%D The framework of this module is set up by Hans Hagen while +%D all the translations were done by Marius Aleknevičius. If +%D you have suggestions, don't hesitate to send us an email. + +%D This file is in \UTF\ encoding and is meant for \MKIV. + +% Lettish/Latvian, Lietuvių/Lithuanian + +\unprotect + +\installlanguage + [\s!lt] + [\c!spacing=\v!packed, + \c!leftsentence=---, + \c!rightsentence=---, + \c!leftsubsentence=---, + \c!rightsubsentence=---, + \c!leftquote=\lowerleftdoubleninequote, + \c!rightquote=\upperrightdoublesixquote, + \c!leftquotation=\lowerleftdoubleninequote, + \c!rightquotation=\upperrightdoublesixquote, + \c!date={\v!year,~m.,\ ,\v!month,\ ,\v!day,~d.}, + \s!patterns=\s!lt, + \s!encoding=l7x, + \s!mapping=l7x, + \s!lefthyphenmin=2, + \s!righthyphenmin=2] + +\installlanguage [lithuanian] [\s!lt] + +\setupheadtext [\s!lt] [\v!content=Turinys] +\setupheadtext [\s!lt] [\v!tables=Lentelės] +\setupheadtext [\s!lt] [\v!figures=Iliustracijos] +\setupheadtext [\s!lt] [\v!graphics=Graphics] % TODO what is the difference between the "graphics" and the "figures"? +\setupheadtext [\s!lt] [\v!intermezzi=Intermezzos] % TODO what is the "intermezzi"? +\setupheadtext [\s!lt] [\v!index=Rodyklė] +\setupheadtext [\s!lt] [\v!abbreviations=Santrumpos] +\setupheadtext [\s!lt] [\v!logos=Logos] % TODO where it is used? +\setupheadtext [\s!lt] [\v!units=Units] % TODO where it is used? +\setupheadtext [\s!lt] [pubs=Literatūra] + +\setuplabeltext [\s!lt] [\v!table={, lentelė.}] +\setuplabeltext [\s!lt] [\v!figure={, pav.}] +\setuplabeltext [\s!lt] [\v!intermezzo=Intermezzo ] % TODO +\setuplabeltext [\s!lt] [\v!graphic=Graphic ] % TODO + +%\startlanguagespecifics[\s!lt] +% \setupheads[\c!sectionstopper=.] %TODO how do I set dots after section numbers? +%\stoplanguagespecifics + +\setuplabeltext [\s!lt] [\v!chapter=] % Chapter +\setuplabeltext [\s!lt] [\v!section=] +\setuplabeltext [\s!lt] [\v!subsection=] +\setuplabeltext [\s!lt] [\v!subsubsection=] +\setuplabeltext [\s!lt] [\v!subsubsubsection=] +\setuplabeltext [\s!lt] [\v!appendix=] % Appendix +\setuplabeltext [\s!lt] [\v!part={, dalis}] +\setuplabeltext [\s!lt] [\v!line=line ] % TODO where it is used? +\setuplabeltext [\s!lt] [\v!lines=lines ] % TODO where it is used? + +\setuplabeltext [\s!lt] [\v!january=sausio] +\setuplabeltext [\s!lt] [\v!february=vasario] +\setuplabeltext [\s!lt] [\v!march=kovo] +\setuplabeltext [\s!lt] [\v!april=balandžio] +\setuplabeltext [\s!lt] [\v!may=gegužės] +\setuplabeltext [\s!lt] [\v!june=birželio] +\setuplabeltext [\s!lt] [\v!july=liepos] +\setuplabeltext [\s!lt] [\v!august=rugpjūčio] +\setuplabeltext [\s!lt] [\v!september=rugsėjo] +\setuplabeltext [\s!lt] [\v!october=spalio] +\setuplabeltext [\s!lt] [\v!november=lapkričio] +\setuplabeltext [\s!lt] [\v!december=gruodžio] + +\setuplabeltext [\s!lt] [\v!sunday=sekmadienis] +\setuplabeltext [\s!lt] [\v!monday=pirmadienis] +\setuplabeltext [\s!lt] [\v!tuesday=antradienis] +\setuplabeltext [\s!lt] [\v!wednesday=trečiadienis] +\setuplabeltext [\s!lt] [\v!thursday=ketvirtadienis] +\setuplabeltext [\s!lt] [\v!friday=penktadienis] +\setuplabeltext [\s!lt] [\v!saturday=šeštadienis] + +\setuplabeltext [\s!lt] [\v!page=puslapis ] % TODO how to test? +\setuplabeltext [\s!lt] [\v!atpage=puslapyje ] % TODO how to test? +\setuplabeltext [\s!lt] [\v!hencefore=kaip parodyta aukščiau] % TODO how to test? +\setuplabeltext [\s!lt] [\v!hereafter=kaip parodyta žemiau] % TODO how to test? +\setuplabeltext [\s!lt] [\v!see=žiūrėti ] % TODO how to test? + +\setuplabeltext [\s!lt] [\v!january :\s!mnem=jan] % I think, there is no abbreviated versions of months in lithuanian +\setuplabeltext [\s!lt] [\v!february :\s!mnem=feb] +\setuplabeltext [\s!lt] [\v!march :\s!mnem=mar] +\setuplabeltext [\s!lt] [\v!april :\s!mnem=apr] +\setuplabeltext [\s!lt] [\v!may :\s!mnem=may] +\setuplabeltext [\s!lt] [\v!june :\s!mnem=jun] +\setuplabeltext [\s!lt] [\v!july :\s!mnem=jul] +\setuplabeltext [\s!lt] [\v!august :\s!mnem=aug] +\setuplabeltext [\s!lt] [\v!september:\s!mnem=sep] +\setuplabeltext [\s!lt] [\v!october :\s!mnem=oct] +\setuplabeltext [\s!lt] [\v!november :\s!mnem=nov] +\setuplabeltext [\s!lt] [\v!december :\s!mnem=dec] + +%D \ShowAllLanguageValues [\s!lt] [lithuanian] {Lithuanian} {doll} % What does this mean? Do I need it? + +\protect \endinput diff --git a/tex/context/base/lang-cel.tex b/tex/context/base/lang-cel.tex new file mode 100644 index 000000000..4d93957f1 --- /dev/null +++ b/tex/context/base/lang-cel.tex @@ -0,0 +1,26 @@ +%D \module +%D [ file=lang-cel, +%D version=1997.09.03, +%D title=\CONTEXT\ Language Macros, +%D subtitle=Celtic Languages, +%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}{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 +%D on, corrections were made by users. If you have suggestions, +%D or feel that your name missing here, don't hesitate to send +%D us an email. + +% Breton, Welsh, Irish, Manx, Scottish Gaelic + +\unprotect + +\protect \endinput diff --git a/tex/context/base/lang-chi.mkii b/tex/context/base/lang-chi.mkii new file mode 100644 index 000000000..278e10745 --- /dev/null +++ b/tex/context/base/lang-chi.mkii @@ -0,0 +1,305 @@ +%D \module +%D [ file=lang-chi, +%D version=2002.06.25, % 1998.10.10, +%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. + +\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 +%D characters. + +\unprotect + +\definesystemconstant {chinese} \definesystemconstant {cn} + +\installlanguage + [\s!cn] + [\c!leftsentence=\cnencoding\cnleftsentence, + \c!rightsentence=\cnencoding\cnrightsentence, + \c!leftsubsentence=\cnencoding\cnleftsubsentence, + \c!rightsubsentence=\cnencoding\cnrightsubsentence, + \c!leftquote=\cnencoding\cnupperleftsinglequote, + \c!rightquote=\cnencoding\cnupperrightsinglequote, + \c!leftquotation=\cnencoding\cnupperleftdoublequote, + \c!rightquotation=\cnencoding\cnupperrightdoublequote, + \c!date={\v!year,\cnyear,\ ,\v!month,\v!day,\cnday}] + +\setupheadtext [\s!cn] [\v!content={\cnencoding\cnencodedcontents}] +\setupheadtext [\s!cn] [\v!tables={\cnencoding\cnencodedtables}] +\setupheadtext [\s!cn] [\v!figures={\cnencoding\cnencodedfigures}] +\setupheadtext [\s!cn] [\v!graphics={\cnencoding\cnencodedgraphics}]% RG & XJF +\setupheadtext [\s!cn] [\v!intermezzi={\cnencoding\cnencodedintermezzo}]% RG & XJF +\setupheadtext [\s!cn] [\v!index={\cnencoding\cnencodedindex}] +\setupheadtext [\s!cn] [\v!abbreviations={\cnencoding\cnencodedabbreviations}] +\setupheadtext [\s!cn] [\v!logos={\cnencoding\cnencodedlogos}] +\setupheadtext [\s!cn] [\v!units={\cnencoding\cnencodedunits}] + +\setuplabeltext [\s!cn] [\v!table={\cnencoding\cnencodedtable}] +\setuplabeltext [\s!cn] [\v!figure={\cnencoding\cnencodedfigure}] +\setuplabeltext [\s!cn] [\v!intermezzo={\cnencoding\cnencodedintermezzo}]% RG & XJF +\setuplabeltext [\s!cn] [\v!graphic={\cnencoding\cnencodedillustration}]% RG & XJF +\setuplabeltext [\s!cn] [\v!appendix={\cnencoding\cnencodedappendix}]% RG +\setuplabeltext [\s!cn] [\v!part={\cnencoding\cnencodedintro,\cnencoding\cnencodedpart}] +\setuplabeltext [\s!cn] [\v!chapter={\cnencoding\cnencodedintro,\cnencoding\cnencodedchapter}] +\setuplabeltext [\s!cn] [\v!section={\cnencoding\cnencodedintro,\cnencoding\cnencodedsection}] +\setuplabeltext [\s!cn] [\v!line={\cnencoding\cnencodedline}]% RG & XJF +\setuplabeltext [\s!cn] [\v!lines={\cnencoding\cnencodedline}]% RG & XJF + +\setuplabeltext [\s!cn] [\v!subsection=] +\setuplabeltext [\s!cn] [\v!subsubsection=] +\setuplabeltext [\s!cn] [\v!subsubsubsection=] + +%D From this definition one can deduce that language, input +%D encoding, font encoding, and glyph meaning form a pretty +%D complex four dimensional space. + +\startlanguagespecifics[\s!cn] + +\setuplabeltext [\s!cn] [\v!january=\cnencoding\cnencodedjanuary ] +\setuplabeltext [\s!cn] [\v!february=\cnencoding\cnencodedfebrary ] +\setuplabeltext [\s!cn] [\v!march=\cnencoding\cnencodedmarch ] +\setuplabeltext [\s!cn] [\v!april=\cnencoding\cnencodedapril ] +\setuplabeltext [\s!cn] [\v!may=\cnencoding\cnencodedmay ] +\setuplabeltext [\s!cn] [\v!june=\cnencoding\cnencodedjune ] +\setuplabeltext [\s!cn] [\v!july=\cnencoding\cnencodedjuly ] +\setuplabeltext [\s!cn] [\v!august=\cnencoding\cnencodedaugust ] +\setuplabeltext [\s!cn] [\v!september=\cnencoding\cnencodedseptember] +\setuplabeltext [\s!cn] [\v!october=\cnencoding\cnencodedoctober ] +\setuplabeltext [\s!cn] [\v!november=\cnencoding\cnencodednovember ] +\setuplabeltext [\s!cn] [\v!december=\cnencoding\cnencodeddecember ] + +\setuplabeltext [\s!cn] [\v!sunday=\cnencoding\cnencodedsunday ] +\setuplabeltext [\s!cn] [\v!monday=\cnencoding\cnencodedmonday ] +\setuplabeltext [\s!cn] [\v!tuesday=\cnencoding\cnencodedtuesday ] +\setuplabeltext [\s!cn] [\v!wednesday=\cnencoding\cnencodedwednesday] +\setuplabeltext [\s!cn] [\v!thursday=\cnencoding\cnencodedthursday ] +\setuplabeltext [\s!cn] [\v!friday=\cnencoding\cnencodedfriday ] +\setuplabeltext [\s!cn] [\v!saturday=\cnencoding\cnencodedsaturday ] + +\stoplanguagespecifics + +%D One can specify a split labeltext, as demonstrated in +%D the definition of the \type {part} label. Unfortunately +%D the glyphs of both part depend on the encoding. Therefore, +%D we have an encoding section here. + +\unexpanded\def\cnencoding{\enableencoding[\chineseencoding]} % ugly and temporary + +\startencoding[cjk-uni] + \definecommand cnleftsentence {\uchar{32}{20}\uchar{32}{20}} + \definecommand cnrightsentence {\uchar{32}{20}\uchar{32}{20}} + \definecommand cnleftsubsentence {\uchar{32}{20}\uchar{32}{20}} + \definecommand cnrightsubsentence {\uchar{32}{20}\uchar{32}{20}} + \definecommand cnupperleftsinglequote {\uchar{32}{24}} + \definecommand cnupperrightsinglequote {\uchar{32}{25}} + \definecommand cnupperleftdoublequote {\uchar{32}{28}} + \definecommand cnupperrightdoublequote {\uchar{32}{29}} + \definecommand cnupperleftsinglequote-v {\uchar{48}{12}} + \definecommand cnupperrightsinglequote-v {\uchar{48}{13}} + \definecommand cnupperleftdoublequote-v {\uchar{48}{14}} + \definecommand cnupperrightdoublequote-v {\uchar{48}{15}} + \definecommand cnencodedcontents {\uchar{118}{238}\uchar{95}{85}} + \definecommand cnencodedtables {\uchar{136}{104}\uchar{104}{60}} + \definecommand cnencodedfigures {\uchar{86}{254}\uchar{95}{98}} + \definecommand cnencodedindex {\uchar{125}{34}\uchar{95}{21}} + \definecommand cnencodedabbreviations {\uchar{127}{41}\uchar{117}{101}\uchar{139}{237}} + \definecommand cnencodedlogos {\uchar{95}{189}\uchar{141}{44}} + \definecommand cnencodedunits {\uchar{139}{161}\uchar{145}{207}\uchar{83}{85}\uchar{79}{77}} + \definecommand cnencodedtable {\uchar{136}{104}} + \definecommand cnencodedfigure {\uchar{86}{254}} + \definecommand cnencodedintro {\uchar{123}{44}} + \definecommand cnencodedpart {\uchar{144}{232}\uchar{82}{6}} + \definecommand cnencodedchapter {\uchar{122}{224}} + \definecommand cnencodedsection {\uchar{130}{130}} + \definecommand cnencodedjanuary {\uchar{78}{0}\uchar{103}{8}} + \definecommand cnencodedfebrary {\uchar{78}{140}\uchar{103}{8}} + \definecommand cnencodedmarch {\uchar{78}{9}\uchar{103}{8}} + \definecommand cnencodedapril {\uchar{86}{219}\uchar{103}{8}} + \definecommand cnencodedmay {\uchar{78}{148}\uchar{103}{8}} + \definecommand cnencodedjune {\uchar{81}{109}\uchar{103}{8}} + \definecommand cnencodedjuly {\uchar{78}{3}\uchar{103}{8}} + \definecommand cnencodedaugust {\uchar{81}{107}\uchar{103}{8}} + \definecommand cnencodedseptember {\uchar{78}{93}\uchar{103}{8}} + \definecommand cnencodedoctober {\uchar{83}{65}\uchar{103}{8}} + \definecommand cnencodednovember {\uchar{83}{65}\uchar{78}{0}\uchar{103}{8}} + \definecommand cnencodeddecember {\uchar{83}{65}\uchar{78}{140}\uchar{103}{8}} + \definecommand cnencodedsunday {\uchar{102}{31}\uchar{103}{31}\uchar{101}{229}} + \definecommand cnencodedmonday {\uchar{102}{31}\uchar{103}{31}\uchar{78}{0}} + \definecommand cnencodedtuesday {\uchar{102}{31}\uchar{103}{31}\uchar{78}{140}} + \definecommand cnencodedwednesday {\uchar{102}{31}\uchar{103}{31}\uchar{78}{9}} + \definecommand cnencodedthursday {\uchar{102}{31}\uchar{103}{31}\uchar{86}{219}} + \definecommand cnencodedfriday {\uchar{102}{31}\uchar{103}{31}\uchar{78}{148}} + \definecommand cnencodedsaturday {\uchar{102}{31}\uchar{103}{31}\uchar{81}{109}} + % RG & XJF + \definecommand cnencodedgraphics {\uchar{86}{254}} + \definecommand cnencodedintermezzo {\uchar{210}{99}\uchar{242}{102}} + \definecommand cnencodedillustration {\uchar{99}{210}\uchar{86}{254}} + \definecommand cnencodedappendix {\uchar{150}{68}\uchar{95}{85}} + \definecommand cnencodedline {\uchar{136}{76}} + % Tobias Burnus & XJF + \definecommand cnyear {\uchar{94}{116}} + \definecommand cnmonth {\uchar{103}{8}} + \definecommand cnday {\uchar{101}{229}} +\stopencoding + +\startencoding[gbk] + \definecommand cnleftsentence {\uchar{161}{170}\uchar{161}{170}} + \definecommand cnrightsentence {\uchar{161}{170}\uchar{161}{170}} + \definecommand cnleftsubsentence {\uchar{161}{170}\uchar{161}{170}} + \definecommand cnrightsubsentence {\uchar{161}{170}\uchar{161}{170}} + \definecommand cnupperleftsinglequote {\uchar{161}{174}} + \definecommand cnupperrightsinglequote {\uchar{161}{175}} + \definecommand cnupperleftdoublequote {\uchar{161}{176}} + \definecommand cnupperrightdoublequote {\uchar{161}{177}} + \definecommand cnupperleftsinglequote-v {\uchar{161}{184}} + \definecommand cnupperrightsinglequote-v {\uchar{161}{185}} + \definecommand cnupperleftdoublequote-v {\uchar{161}{186}} + \definecommand cnupperrightdoublequote-v {\uchar{161}{187}} + \definecommand cnencodedcontents {\uchar{196}{191}\uchar{194}{188}} + \definecommand cnencodedtables {\uchar{177}{237}\uchar{184}{241}} + \definecommand cnencodedfigures {\uchar{205}{188}\uchar{208}{206}} + \definecommand cnencodedindex {\uchar{203}{247}\uchar{210}{253}} + \definecommand cnencodedabbreviations {\uchar{203}{245}\uchar{194}{212}\uchar{211}{239}} + \definecommand cnencodedlogos {\uchar{187}{213}\uchar{177}{225}} + \definecommand cnencodedunits {\uchar{188}{198}\uchar{193}{191}\uchar{181}{165}\uchar{206}{187}} + \definecommand cnencodedtable {\uchar{177}{237}} + \definecommand cnencodedfigure {\uchar{205}{188}} + \definecommand cnencodedintro {\uchar{181}{218}} + \definecommand cnencodedpart {\uchar{178}{191}\uchar{183}{214}} + \definecommand cnencodedchapter {\uchar{213}{194}} + \definecommand cnencodedsection {\uchar{189}{218}} + \definecommand cnencodedjanuary {\uchar{210}{187}\uchar{212}{194}} + \definecommand cnencodedfebrary {\uchar{182}{254}\uchar{212}{194}} + \definecommand cnencodedmarch {\uchar{200}{253}\uchar{212}{194}} + \definecommand cnencodedapril {\uchar{203}{196}\uchar{212}{194}} + \definecommand cnencodedmay {\uchar{206}{229}\uchar{212}{194}} + \definecommand cnencodedjune {\uchar{193}{249}\uchar{212}{194}} + \definecommand cnencodedjuly {\uchar{198}{223}\uchar{212}{194}} + \definecommand cnencodedaugust {\uchar{176}{203}\uchar{212}{194}} + \definecommand cnencodedseptember {\uchar{190}{197}\uchar{212}{194}} + \definecommand cnencodedoctober {\uchar{202}{174}\uchar{212}{194}} + \definecommand cnencodednovember {\uchar{202}{174}\uchar{210}{187}\uchar{212}{194}} + \definecommand cnencodeddecember {\uchar{202}{174}\uchar{182}{254}\uchar{212}{194}} + \definecommand cnencodedsunday {\uchar{208}{199}\uchar{198}{218}\uchar{200}{213}} + \definecommand cnencodedmonday {\uchar{208}{199}\uchar{198}{218}\uchar{210}{187}} + \definecommand cnencodedtuesday {\uchar{208}{199}\uchar{198}{218}\uchar{182}{254}} + \definecommand cnencodedwednesday {\uchar{208}{199}\uchar{198}{218}\uchar{200}{253}} + \definecommand cnencodedthursday {\uchar{208}{199}\uchar{198}{218}\uchar{203}{196}} + \definecommand cnencodedfriday {\uchar{208}{199}\uchar{198}{218}\uchar{206}{229}} + \definecommand cnencodedsaturday {\uchar{208}{199}\uchar{198}{218}\uchar{193}{249}} + % RG & XJF + \definecommand cnencodedgraphics {\uchar{205}{188}} + \definecommand cnencodedintermezzo {\uchar{178}{229}\uchar{199}{250}} + \definecommand cnencodedillustration {\uchar{178}{229}\uchar{205}{188}} + \definecommand cnencodedappendix {\uchar{184}{189}\uchar{194}{188}} + \definecommand cnencodedline {\uchar{208}{208}} + % Tobias Burnus & XJF + \definecommand cnyear {\uchar{196}{234}} + \definecommand cnmonth {\uchar{212}{194}} + \definecommand cnday {\uchar{200}{213}} +\stopencoding + +\startencoding[big5] + \definecommand cnleftsentence {\uchar{162}{119}\uchar{162}{119}} + \definecommand cnrightsentence {\uchar{162}{119}\uchar{162}{119}} + \definecommand cnleftsubsentence {\uchar{162}{119}\uchar{162}{119}} + \definecommand cnrightsubsentence {\uchar{162}{119}\uchar{162}{119}} + \definecommand cnupperleftsinglequote {\uchar{161}{165}} + \definecommand cnupperrightsinglequote {\uchar{161}{166}} + \definecommand cnupperleftdoublequote {\uchar{161}{167}} + \definecommand cnupperrightdoublequote {\uchar{161}{168}} + \definecommand cnupperleftsinglequote-v {\uchar{161}{117}} + \definecommand cnupperrightsinglequote-v {\uchar{161}{118}} + \definecommand cnupperleftdoublequote-v {\uchar{161}{121}} + \definecommand cnupperrightdoublequote-v {\uchar{161}{122}} + \definecommand cnencodecontents {\uchar{165}{216}\uchar{191}{253}} + \definecommand cnencodetables {\uchar{170}{237}\uchar{174}{230}} + \definecommand cnencodefigures {\uchar{185}{207}\uchar{167}{206}} + \definecommand cnencodeindex {\uchar{175}{193}\uchar{174}{222}} + \definecommand cnencodeabbreviations {\uchar{191}{89}\uchar{178}{164}\uchar{187}{121}} + \definecommand cnencodelogos {\uchar{192}{178}\uchar{188}{208}} + \definecommand cnencodeunits {\uchar{173}{112}\uchar{182}{113}\uchar{179}{230}\uchar{166}{236}} + \definecommand cnencodetable {\uchar{170}{237}} + \definecommand cnencodefigure {\uchar{185}{207}} + \definecommand cnencodedintro {\uchar{178}{196}} + \definecommand cnencodedpart {\uchar{179}{161}\uchar{164}{192}} + \definecommand cnencodedchapter {\uchar{179}{185}} + \definecommand cnencodedsection {\uchar{184} {96}} + \definecommand cnencodedjanuary {\uchar{164} {64}\uchar{164}{235}} + \definecommand cnencodedfebrary {\uchar{164} {71}\uchar{164}{235}} + \definecommand cnencodedmarch {\uchar{164} {84}\uchar{164}{235}} + \definecommand cnencodedapril {\uchar{165}{124}\uchar{164}{235}} + \definecommand cnencodedmay {\uchar{164}{173}\uchar{164}{235}} + \definecommand cnencodedjune {\uchar{164}{187}\uchar{164}{235}} + \definecommand cnencodedjuly {\uchar{164} {67}\uchar{164}{235}} + \definecommand cnencodedaugust {\uchar{164} {75}\uchar{164}{235}} + \definecommand cnencodedseptember {\uchar{164} {69}\uchar{164}{235}} + \definecommand cnencodedoctober {\uchar{164} {81}\uchar{164}{235}} + \definecommand cnencodednovember {\uchar{164} {81}\uchar{164} {64}\uchar{164}{235}} + \definecommand cnencodeddecember {\uchar{164} {81}\uchar{164} {71}\uchar{164}{235}} + \definecommand cnencodedsunday {\uchar{172} {80}\uchar{180}{193}\uchar{164}{233}} + \definecommand cnencodedmonday {\uchar{172} {80}\uchar{180}{193}\uchar{164} {64}} + \definecommand cnencodedtuesday {\uchar{172} {80}\uchar{180}{193}\uchar{164} {71}} + \definecommand cnencodedwednesday {\uchar{172} {80}\uchar{180}{193}\uchar{164} {84}} + \definecommand cnencodedthursday {\uchar{172} {80}\uchar{180}{193}\uchar{165}{124}} + \definecommand cnencodedfriday {\uchar{172} {80}\uchar{180}{193}\uchar{164}{173}} + \definecommand cnencodedsaturday {\uchar{172} {80}\uchar{180}{193}\uchar{164}{187}} + % Tobias Burnus &\XJF + \definecommand cnyear {\uchar{166}{126}} + \definecommand cnmonth {\uchar{164}{235}} + \definecommand cnday {\uchar{164}{233}} + +% Traditional Chinese characters (only where they differ to the +% simplified ones) for lang-chi.tex and font-chi.tex. + +% \startencoding[cjk-uni] +% \defineudigit 10000 132 44 +% \defineudigit 100000000 81 4 + +% \definecommand cnencodedsection {\uchar{123}{192}} +% \definecommand cnencodedfigure {\uchar{87}{22}} +% \definecommand cnencodedunits {\uchar{138}{8}\uchar{145}{207}\uchar{85}{174}\uchar{79}{77}} +% \definecommand cnencodedlogos {\uchar{95}{189}\uchar{140}{182}} +% \definecommand cnencodedabbreviations {\uchar{126}{46}\uchar{117}{101}\uchar{138}{158}} +% \definecommand cnencodedfigures {\uchar{87}{22}\uchar{95}{98}} +% \definecommand cnencodedcontents {\uchar{118}{238}\uchar{147}{4}} +% \stopencoding + +% \startencoding[gbk] +% \defineudigit 10000 200 102 +% \defineudigit 100000000 131 124 + +% \definecommand cnencodedsection {\uchar{185}{157}} +% \definecommand cnencodedfigure {\uchar{136}{68}} +% \definecommand cnencodedunits {\uchar{211}{139}\uchar{193}{191}\uchar{134}{206}\uchar{206}{187}} +% \definecommand cnencodedlogos {\uchar{187}{213}\uchar{217}{72} +% \definecommand cnencodedabbreviations {\uchar{191}{115}\uchar{194}{212}\uchar{213}{90}} +% \definecommand cnencodedfigures {\uchar{136}{68}\uchar{208}{206}} +% \definecommand cnencodedcontents {\uchar{196}{191}\uchar{228}{155}} +% \stopencoding + +% \startencoding[big5] +% \defineudigit 10000 184 85 +% \defineudigit 100000000 187 245 + +% \definecommand cnencodedsection {\uchar{184}{96}} +% \definecommand cnencodedfigure {\uchar{185}{207}} +% \definecommand cnencodedunits {\uchar{173}{112}\uchar{182}{113}\uchar{179}{230}\uchar{166}{236}} +% \definecommand cnencodedlogos {\uchar{192}{178}\uchar{182}{83}} +% \definecommand cnencodedabbreviations {\uchar{193}{89}\uchar{178}{164}\uchar{187}{121}} +% \definecommand cnencodedfigures {\uchar{185}{207}\uchar{167}{206}} +% \definecommand cnencodedcontents {\uchar{165}{216}\uchar{191}{253}} +% \stopencoding + +\stopencoding + +\protect \endinput diff --git a/tex/context/base/lang-cjk.mkiv b/tex/context/base/lang-cjk.mkiv new file mode 100644 index 000000000..5f736d4a1 --- /dev/null +++ b/tex/context/base/lang-cjk.mkiv @@ -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!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=土曜日] +\setuplabeltext [\s!ja] [\v!sunday=日曜日] + +%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.mkii b/tex/context/base/lang-ctx.mkii new file mode 100644 index 000000000..09f28dda1 --- /dev/null +++ b/tex/context/base/lang-ctx.mkii @@ -0,0 +1,53 @@ +%D \module +%D [ file=lang-ctx, +%D version=2005.02.12, +%D title=\CONTEXT\ Language Macros, +%D subtitle=Generic Patterns, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Generic Patterns} + +\unprotect + +%D The \CONTEXT\ specific patterns are more generic and +%D are more or less encoding independent. They are generated +%D from the ones shipped with distributions using: +%D +%D \starttyping +%D ctxtools --pattern --all +%D \stoptyping + +%D In order to get 8 bit characters hyphenated, we need to load +%D patterns under the right circumstances. In some countries, more +%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!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 + +% greek + +% \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 new file mode 100644 index 000000000..470402bb1 --- /dev/null +++ b/tex/context/base/lang-cyr.tex @@ -0,0 +1,371 @@ +%D \module +%D [ file=lang-cyr, +%D version=2003.01.24, +%D title=\CONTEXT\ Language Macros, +%D subtitle=Cyrillic Languages, +%D author=see below, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Cyrillic Languages} + +%D The cyrillic languages always use a dedicated input regime. +%D Therefore we define the labels using symbolic names. +%D Support for cyrillic is initiated by Olga Briginets who +%D also layed the base for the language, encoding and font +%D definition. Later Alexander Bokovoy and Victor Figurnov +%D improved things. I (Hans Hagen) mainly cleaned things up +%D a bit. + +\unprotect + +\installlanguage + [\s!ru] + [\s!lefthyphenmin=2, + \s!righthyphenmin=2, + \c!spacing=\v!packed, + \c!leftsentence=\leftguillemot, + \c!rightsentence=\rightguillemot, + \c!leftsubsentence=\lowerleftdoubleninequote, + \c!rightsubsentence=\upperrightdoubleninequote, + \c!leftquote=\lowerleftdoubleninequote, + \c!rightquote=\upperrightdoubleninequote, + \c!leftquotation=\leftguillemot, + \c!rightquotation=\rightguillemot, + \c!date={\v!day,\ ,\v!month,\ ,\v!year}, + \s!mapping=t2a, + \s!encoding=t2a] + +\installlanguage + [\s!ua] + [\s!lefthyphenmin=2, + \s!righthyphenmin=2, + \c!spacing=\v!packed, + \c!leftsentence=\leftguillemot, + \c!rightsentence=\rightguillemot, + \c!leftsubsentence=\lowerleftdoubleninequote, + \c!rightsubsentence=\upperrightdoubleninequote, + \c!leftquote=\lowerleftdoubleninequote, + \c!rightquote=\upperrightdoubleninequote, + \c!leftquotation=\leftguillemot, + \c!rightquotation=\rightguillemot, + \c!date={\v!day,\ ,\v!month,\ ,\v!year}, + \s!patterns=\s!uk, + \s!mapping=t2a, + \s!encoding=t2a] + +\installlanguage [russian] [\s!ru] +\installlanguage [ukrainian] [\s!ua] + +%D Labels and header texts. + +\setupheadtext [\s!ru] [ \v!content=\cyrillicS \cyrillico \cyrillicd + \cyrillice \cyrillicr \cyrilliczh + \cyrillica \cyrillicn \cyrillici + \cyrillice] +\setupheadtext [\s!ua] [\v!content=\cyrillicZ \cyrillicm \cyrillicii + \cyrillics \cyrillict] + +\setupheadtext [\s!ru] [\v!tables=\cyrillicS \cyrillicp \cyrillici + \cyrillics \cyrillico \cyrillick + \space \cyrillict \cyrillica + \cyrillicb \cyrillicl \cyrillici + \cyrillicc] +\setupheadtext [\s!ua] [\v!tables=\cyrillicP \cyrillice \cyrillicr + \cyrillice \cyrillicl \cyrillicii + \cyrillick \space \cyrillict + \cyrillica \cyrillicb \cyrillicl + \cyrillici \cyrillicc \cyrillicsftsn] + +\setupheadtext [\s!ru] [\v!figures=\cyrillicS \cyrillicp \cyrillici + \cyrillics \cyrillico \cyrillick + \space \cyrillici \cyrillicl + \cyrillicl \cyrillicyu\cyrillics + \cyrillict \cyrillicr \cyrillica + \cyrillicc \cyrillici \cyrillicishrt] +\setupheadtext [\s!ua] [\v!figures=\cyrillicP \cyrillice \cyrillicr + \cyrillice \cyrillicl \cyrillicii + \cyrillick \space \cyrillicii + \cyrillicl \cyrillicyu\cyrillics + \cyrillict \cyrillicr \cyrillica + \cyrillicc \cyrillicii\cyrillicishrt] + +\setupheadtext [\s!ru] [\v!graphics=\cyrillicS \cyrillicp \cyrillici + \cyrillics \cyrillico \cyrillick + \space \cyrillicg \cyrillicr + \cyrillica \cyrillicf \cyrillici + \cyrillick \cyrillico \cyrillicv] +\setupheadtext [\s!ua] [\v!graphics=\cyrillicP \cyrillice \cyrillicr + \cyrillice \cyrillicl \cyrillicii + \cyrillick \space \cyrillicg + \cyrillicr \cyrillica \cyrillicf + \cyrillicii\cyrillick \cyrillico + \cyrillicv] + +\setupheadtext [\s!ru] [\v!intermezzi=\cyrillicS \cyrillicp \cyrillici + \cyrillics \cyrillico \cyrillick + \space \cyrillicv \cyrillics + \cyrillict \cyrillica \cyrillicv + \cyrillico \cyrillick] +\setupheadtext [\s!ua] [\v!intermezzi=\cyrillicP \cyrillice \cyrillicr + \cyrillice \cyrillicl \cyrillicii + \cyrillick \space \cyrillicv + \cyrillics \cyrillict \cyrillica + \cyrillicv \cyrillico \cyrillick] + +\setupheadtext [\s!ru] [\v!index=\cyrillicA \cyrillicl \cyrillicf + \cyrillica \cyrillicv \cyrillici + \cyrillict \cyrillicn \cyrillicery + \cyrillicishrt \space \cyrillicu + \cyrillick \cyrillica \cyrillicz + \cyrillica \cyrillict \cyrillice + \cyrillicl \cyrillicsftsn] +\setupheadtext [\s!ua] [\v!index=\cyrillicP \cyrillico \cyrillick + \cyrillica \cyrilliczh\cyrillicch + \cyrillici \cyrillick] + +\setupheadtext [\s!ru] [\v!abbreviations=\cyrillicS \cyrillicp \cyrillici + \cyrillics \cyrillico \cyrillick + \space \cyrillics \cyrillico + \cyrillick \cyrillicr \cyrillica + \cyrillicshch \cyrillice + \cyrillicn + \cyrillici \cyrillicishrt] +\setupheadtext [\s!ua] [\v!abbreviations=\cyrillicP \cyrillice \cyrillicr + \cyrillice \cyrillicl \cyrillicii + \cyrillick \space \cyrillics + \cyrillick \cyrillico \cyrillicr + \cyrillico \cyrillicch\cyrillice + \cyrillicn \cyrillicsftsn] + +\setupheadtext [\s!ru] [\v!logos=\cyrillicL \cyrillico \cyrillicg + \cyrillico \cyrillict \cyrillici + \cyrillicp \cyrillicery] +\setupheadtext [\s!ua] [\v!logos=\cyrillicL \cyrillico \cyrillicg + \cyrillico \cyrillict \cyrillici + \cyrillicp \cyrillici] + +\setupheadtext [\s!ru] [\v!units=\cyrillicE \cyrillicd \cyrillici + \cyrillicn \cyrillici \cyrillicc + \cyrillicery \space \cyrillici + \cyrillicz \cyrillicm \cyrillice + \cyrillicr \cyrillice \cyrillicn + \cyrillici \cyrillicya] +\setupheadtext [\s!ua] [\v!units=\cyrillicO \cyrillicd \cyrillici + \cyrillicn \cyrillici \cyrillicc + \cyrillicii\space \cyrillicv + \cyrillici \cyrillicm \cyrillicii + \cyrillicr \cyrillicu] + +\setuplabeltext [\s!ru] [\v!table=\cyrillicT \cyrillica \cyrillicb + \cyrillicl \cyrillici \cyrillicc + \cyrillica \space] +\setuplabeltext [\s!ua] [\v!table=\cyrillicT \cyrillica \cyrillicb + \cyrillicl \cyrillici \cyrillicc + \cyrillicya\space] + +\setuplabeltext [\s!ru] [\v!figure=\cyrillicR \cyrillici \cyrillics + \cyrillicu \cyrillicn \cyrillico + \cyrillick \space] +\setuplabeltext [\s!ua] [\v!figure=\cyrillicM \cyrillica \cyrillicl + \cyrillicyu\cyrillicn \cyrillico + \cyrillick \space] + +\setuplabeltext [\s!ru] [\v!intermezzo=\cyrillicV \cyrillics \cyrillict + \cyrillica \cyrillicv \cyrillick + \cyrillica \space] +\setuplabeltext [\s!ua] [\v!intermezzo=\cyrillicV \cyrillics \cyrillict + \cyrillica \cyrillicv \cyrillick + \cyrillica \space] + +\setuplabeltext [\s!ru] [\v!graphic=\cyrillicG \cyrillicr \cyrillica + \cyrillicf \cyrillici \cyrillick + \space] +\setuplabeltext [\s!ua] [\v!graphic=\cyrillicG \cyrillicr \cyrillica + \cyrillicf \cyrillici \cyrillick + \space] + +\setuplabeltext [\s!ru] [\v!chapter=] +\setuplabeltext [\s!ua] [\v!chapter=] + +\setuplabeltext [\s!ru] [\v!section=] +\setuplabeltext [\s!ua] [\v!section=] + +\setuplabeltext [\s!ru] [\v!subsection=] +\setuplabeltext [\s!ua] [\v!subsection=] + +\setuplabeltext [\s!ru] [\v!subsubsection=] +\setuplabeltext [\s!ua] [\v!subsubsection=] + +\setuplabeltext [\s!ru] [\v!subsubsubsection=] +\setuplabeltext [\s!ua] [\v!subsubsubsection=] + +\setuplabeltext [\s!ru] [\v!appendix=] +\setuplabeltext [\s!ua] [\v!appendix=] + +\setuplabeltext [\s!ru] [\v!part=\cyrillicCH\cyrillica \cyrillics + \cyrillict \cyrillicsftsn + \space] +\setuplabeltext [\s!ua] [\v!part=\cyrillicCH\cyrillica \cyrillics + \cyrillict \cyrillici \cyrillicn + \cyrillica \space] + +\setuplabeltext [\s!ru] [\v!line=\cyrillics \cyrillict \cyrillicr + \cyrillico \cyrillick \cyrillica + \space] +\setuplabeltext [\s!ua] [\v!line=\cyrillicr \cyrillicya\cyrillicd + \cyrillico \cyrillick \space] + +\setuplabeltext [\s!ru] [\v!lines=\cyrillics \cyrillict \cyrillicr + \cyrillico \cyrillick \cyrillici + \space] +\setuplabeltext [\s!ua] [\v!lines=\cyrillicr \cyrillicya\cyrillicd + \cyrillick \cyrillici \space] + +\setuplabeltext [\s!ru] [\v!page=\cyrillics \cyrillict \cyrillicr + \cyrillica \cyrillicn \cyrillici + \cyrillicc \cyrillica \space] +\setuplabeltext [\s!ua] [\v!page=\cyrillics \cyrillict \cyrillico + \cyrillicr \cyrillicii\cyrillicn + \cyrillick \cyrillica \space ] + +\setuplabeltext [\s!ru] [\v!atpage=\cyrillicn \cyrillica \space + \cyrillics \cyrillict \cyrillicr + \cyrillica \cyrillicn \cyrillici + \cyrillicc \cyrillice \space] +\setuplabeltext [\s!ua] [\v!atpage=\cyrillicn \cyrillica \space + \cyrillics \cyrillict \cyrillico + \cyrillicr \cyrillicii\cyrillicn + \cyrillicc \cyrillicii\space ] + +\setuplabeltext [\s!ru] [\v!hencefore=\cyrillics \cyrillicm.\space + \cyrillicv \cyrillicery \cyrillicsh + \cyrillice] +\setuplabeltext [\s!ua] [\v!hencefore=\cyrillicya\cyrillick \space + \cyrillicp \cyrillico \cyrillick + \cyrillica \cyrillicz \cyrillica + \cyrillicn \cyrillico \space + \cyrillicv \cyrillici \cyrillicshch + \cyrillice] + +\setuplabeltext [\s!ru] [\v!hereafter=\cyrillics \cyrillicm.\space + \cyrillicn \cyrillici \cyrilliczh + \cyrillice] +\setuplabeltext [\s!ua] [\v!hereafter=\cyrillicya\cyrillick \space + \cyrillicp \cyrillico \cyrillick + \cyrillica \cyrillicz \cyrillica + \cyrillicn \cyrillico \space + \cyrillicn \cyrillici \cyrilliczh + \cyrillicch\cyrillice] + +\setuplabeltext [\s!ru] [\v!see=\cyrillics \cyrillicm.\space] +\setuplabeltext [\s!ua] [\v!see=\cyrillicd \cyrillici + \cyrillicv.\space ] + +\setuplabeltext [\s!ru] [\v!january=\cyrillicya\cyrillicn \cyrillicv + \cyrillica \cyrillicr \cyrillicya] +\setuplabeltext [\s!ru] [\v!february=\cyrillicf \cyrillice \cyrillicv + \cyrillicr \cyrillica \cyrillicl + \cyrillicya] +\setuplabeltext [\s!ru] [\v!march=\cyrillicm \cyrillica \cyrillicr + \cyrillict \cyrillica] +\setuplabeltext [\s!ru] [\v!april=\cyrillica \cyrillicp \cyrillicr + \cyrillice \cyrillicl \cyrillicya] +\setuplabeltext [\s!ru] [\v!may=\cyrillicm \cyrillica \cyrillicya] +\setuplabeltext [\s!ru] [\v!june=\cyrillici \cyrillicyu\cyrillicn + \cyrillicya] +\setuplabeltext [\s!ru] [\v!july=\cyrillici \cyrillicyu\cyrillicl + \cyrillicya] +\setuplabeltext [\s!ru] [\v!august=\cyrillica \cyrillicv \cyrillicg + \cyrillicu \cyrillics \cyrillict + \cyrillica] +\setuplabeltext [\s!ru] [\v!september=\cyrillics \cyrillice \cyrillicn + \cyrillict \cyrillicya\cyrillicb + \cyrillicr \cyrillicya] +\setuplabeltext [\s!ru] [\v!october=\cyrillico \cyrillick \cyrillict + \cyrillicya\cyrillicb \cyrillicr + \cyrillicya] +\setuplabeltext [\s!ru] [\v!november=\cyrillicn \cyrillico \cyrillicya + \cyrillicb \cyrillicr \cyrillicya] +\setuplabeltext [\s!ru] [\v!december=\cyrillicd \cyrillice \cyrillick + \cyrillica \cyrillicb \cyrillicr + \cyrillicya] + +\setuplabeltext [\s!ua] [\v!january=\cyrillics \cyrillicii\cyrillicch + \cyrillicn \cyrillicya] +\setuplabeltext [\s!ua] [\v!february=\cyrillicl \cyrillicyu\cyrillict + \cyrillico \cyrillicg \cyrillico] +\setuplabeltext [\s!ua] [\v!march=\cyrillicb \cyrillice \cyrillicr + \cyrillice \cyrillicz \cyrillicn + \cyrillicya] +\setuplabeltext [\s!ua] [\v!april=\cyrillick \cyrillicv \cyrillicii + \cyrillict \cyrillicn \cyrillicya] +\setuplabeltext [\s!ua] [\v!may=\cyrillict \cyrillicr \cyrillica + \cyrillicv \cyrillicn \cyrillicya] +\setuplabeltext [\s!ua] [\v!june=\cyrillicch\cyrillice \cyrillicr + \cyrillicv \cyrillicn \cyrillicya] +\setuplabeltext [\s!ua] [\v!july=\cyrillicl \cyrillici \cyrillicp + \cyrillicn \cyrillicya] +\setuplabeltext [\s!ua] [\v!august=\cyrillics \cyrillice \cyrillicr + \cyrillicp \cyrillicn \cyrillicya] +\setuplabeltext [\s!ua] [\v!september=\cyrillicv \cyrillice \cyrillicr + \cyrillice \cyrillics \cyrillicn + \cyrillicya] +\setuplabeltext [\s!ua] [\v!october=\cyrilliczh\cyrillico \cyrillicv + \cyrillict \cyrillicn \cyrillicya] +\setuplabeltext [\s!ua] [\v!november=\cyrillicl \cyrillici \cyrillics + \cyrillict \cyrillico \cyrillicp + \cyrillica \cyrillicd \cyrillica] +\setuplabeltext [\s!ua] [\v!december=\cyrillicg \cyrillicr \cyrillicu + \cyrillicd \cyrillicn \cyrillicya] + +\setuplabeltext [\s!ru] [\v!sunday=\cyrillicv \cyrillico \cyrillics + \cyrillick \cyrillicr \cyrillice + \cyrillics \cyrillice \cyrillicn + \cyrillicsftsn \cyrillice] +\setuplabeltext [\s!ru] [\v!monday=\cyrillicp \cyrillico \cyrillicn + \cyrillice \cyrillicd \cyrillice + \cyrillicl \cyrillicsftsn + \cyrillicn \cyrillici \cyrillick] +\setuplabeltext [\s!ru] [\v!tuesday=\cyrillicv \cyrillict \cyrillico + \cyrillicr \cyrillicn \cyrillici + \cyrillick] +\setuplabeltext [\s!ru] [\v!wednesday=\cyrillics \cyrillicr \cyrillice + \cyrillicd \cyrillica] +\setuplabeltext [\s!ru] [\v!thursday=\cyrillicch\cyrillice \cyrillict + \cyrillicv \cyrillice \cyrillicr + \cyrillicg] +\setuplabeltext [\s!ru] [\v!friday=\cyrillicp \cyrillicya\cyrillict + \cyrillicn \cyrillici \cyrillicc + \cyrillica] +\setuplabeltext [\s!ru] [\v!saturday=\cyrillics \cyrillicu \cyrillicb + \cyrillicb \cyrillico \cyrillict + \cyrillica] + +\setuplabeltext [\s!ua] [\v!sunday=\cyrillicn \cyrillice \cyrillicd + \cyrillicii\cyrillicl \cyrillicya] +\setuplabeltext [\s!ua] [\v!monday=\cyrillicp \cyrillico \cyrillicn + \cyrillice \cyrillicd \cyrillicii + \cyrillicl \cyrillico \cyrillick] +\setuplabeltext [\s!ua] [\v!tuesday=\cyrillicv \cyrillicii\cyrillicv + \cyrillict \cyrillico \cyrillicr + \cyrillico \cyrillick] +\setuplabeltext [\s!ua] [\v!wednesday=\cyrillics \cyrillice \cyrillicr + \cyrillice \cyrillicd \cyrillica] +\setuplabeltext [\s!ua] [\v!thursday=\cyrillicch\cyrillice \cyrillict + \cyrillicv \cyrillice \cyrillicr] +\setuplabeltext [\s!ua] [\v!friday=\cyrillicp'\cyrillicya\cyrillict + \cyrillicn \cyrillici \cyrillicc + \cyrillicya] +\setuplabeltext [\s!ua] [\v!saturday=\cyrillics \cyrillicu \cyrillicb + \cyrillico \cyrillict \cyrillica] + + +%D \ShowAllLanguageValues [\s!ru] [russian] {Russian} {doll} +%D \ShowAllLanguageValues [\s!ua] [ukranian] {Ukranian} {dance} + +\protect \endinput diff --git a/tex/context/base/lang-dis.mkii b/tex/context/base/lang-dis.mkii new file mode 100644 index 000000000..f081bf4a9 --- /dev/null +++ b/tex/context/base/lang-dis.mkii @@ -0,0 +1,59 @@ +%D \module +%D [ file=lang-dis, +%D version=2005.02.12, +%D title=\CONTEXT\ Language Macros, +%D subtitle=Distribution Patterns, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 used to be part of cont-usr.tex but now that we +%D use more generic pattern files, we decided to isolate these +%D mappings. + +\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 +%D patterns take precedence. This list will be adapted to +%D the actual situation, given that it's noticed. + +%D The us/uk hyph 1/2 files will go + +\unprotect + +% \definefilefallback [lang-ca.pat] [cahyph.tex] +% \definefilefallback [lang-da.pat] [dkhyph.tex] +% \definefilefallback [lang-de.pat] [dehyphn.tex] +% \definefilefallback [lang-es.pat] [eshyph.tex] +% \definefilefallback [lang-fi.pat] [fihyph.tex] +% \definefilefallback [lang-fr.pat] [frhyph.tex] +% \definefilefallback [lang-hr.pat] [hrhyph.tex] +% \definefilefallback [lang-hu.pat] [huhyph.tex] +% \definefilefallback [lang-it.pat] [ithyph.tex] +% \definefilefallback [lang-la.pat] [lahyph7.tex] +% \definefilefallback [lang-no.pat] [nohyph.tex] +% \definefilefallback [lang-pl.pat] [plhyph.tex] +% \definefilefallback [lang-pt.pat] [pthyph.tex] +% \definefilefallback [lang-ro.pat] [rohyph.tex] +% \definefilefallback [lang-ru.pat] [ruenhyph.tex] +% \definefilefallback [lang-sl.pat] [sihyph.tex,slhyph.tex] +% \definefilefallback [lang-sv.pat] [svhyph.tex,sehyph.tex] +% \definefilefallback [lang-tr.pat] [tkhyph.tex,trhyph.tex] +% \definefilefallback [lang-ua.pat] [ukrenhyp.tex] +% \definefilefallback [lang-uk.pat] [ukhyphen.tex,ukhyph.tex] +% \definefilefallback [lang-us.pat] [ushyphmax.tex,ushyph.tex,ushyph1.tex,ushyph2.tex,hyphen.tex] +% \definefilefallback [lang-nl.pat] [nehyph96.tex,dutch96.pat,nehyph.tex] +% \definefilefallback [lang-cz.pat] [czhyphen.tex,czhyph.pat] +% \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] + +\protect \endinput diff --git a/tex/context/base/lang-frd.tex b/tex/context/base/lang-frd.tex new file mode 100644 index 000000000..6cc27080b --- /dev/null +++ b/tex/context/base/lang-frd.tex @@ -0,0 +1,140 @@ +%D \module +%D [ file=lang-frd, +%D version=2004.01.15, +%D title=\CONTEXT\ Language Macros, +%D subtitle=Language Frequency Table 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. + +%D This is expewrimental work! + +% http://www.onzetaal.nl/advies/letterfreq.html + +\startcharactertable[nl] + \charfreq a 7.47 + \charfreq b 1.58 + \charfreq c 1.24 + \charfreq d 5.93 + \charfreq e 18.91 + \charfreq f .81 + \charfreq g 3.4 + \charfreq h 2.38 + \charfreq i 6.5 + \charfreq j 1.46 + \charfreq k 2.25 + \charfreq l 3.57 + \charfreq m 2.21 + \charfreq n 10.03 + \charfreq o 6.06 + \charfreq p 1.57 + \charfreq q .009 + \charfreq r 6.41 + \charfreq s 3.73 + \charfreq t 6.79 + \charfreq u 1.99 + \charfreq v 2.85 + \charfreq w 1.52 + \charfreq x .04 + \charfreq y .035 + \charfreq z 1.39 +\stopcharactertable + +% http://caislab.icu.ac.kr/course/2001/spring/ice605/down/010306.pdf + +% \startcharactertable[en] +% \charfreq a 8.2 +% \charfreq b 1.5 +% \charfreq c 2.8 +% \charfreq d 4.3 +% \charfreq e 12.7 +% \charfreq f 2.2 +% \charfreq g 2 +% \charfreq h 6.1 +% \charfreq i 7 +% \charfreq j .2 +% \charfreq k .8 +% \charfreq l 4 +% \charfreq m 2.4 +% \charfreq n 6.7 +% \charfreq o 7.5 +% \charfreq p 1.9 +% \charfreq q .1 +% \charfreq r 6 +% \charfreq s 6.3 +% \charfreq t 9.1 +% \charfreq u 2.8 +% \charfreq v 1 +% \charfreq w 2.3 +% \charfreq x .1 +% \charfreq y 2 +% \charfreq z .1 +% \stopcharactertable + +% http://www.blankenburg.de/gat/pages/fach/info/analyse2.htm + +\startcharactertable[en] + \charfreq a 8.04 + \charfreq b 1.54 + \charfreq c 3.06 + \charfreq d 3.99 + \charfreq e 12.51 + \charfreq f 2.3 + \charfreq g 1.96 + \charfreq h 5.49 + \charfreq i 7.26 + \charfreq j .16 + \charfreq k .67 + \charfreq l 4.14 + \charfreq m 2.53 + \charfreq n 7.09 + \charfreq o 7.6 + \charfreq p 2 + \charfreq q .11 + \charfreq r 6.12 + \charfreq s 6.54 + \charfreq t 9.25 + \charfreq u 2.71 + \charfreq v .99 + \charfreq w 1.92 + \charfreq x .19 + \charfreq y 1.73 + \charfreq z .09 +\stopcharactertable + +% http://www.blankenburg.de/gat/pages/fach/info/analyse2.htm + +\startcharactertable[de] + \charfreq a 6.47 + \charfreq b 1.93 + \charfreq c 2.68 + \charfreq d 4.83 + \charfreq e 17.48 + \charfreq f 1.65 + \charfreq g 3.06 + \charfreq h 4.23 + \charfreq i 7.73 + \charfreq j .27 + \charfreq k 1.46 + \charfreq l 3.49 + \charfreq m 2.58 + \charfreq n 9.84 + \charfreq o 2.98 + \charfreq p .96 + \charfreq q .02 + \charfreq r 7.54 + \charfreq s 6.83 + \charfreq t 6.13 + \charfreq u 4.17 + \charfreq v .94 + \charfreq w 1.48 + \charfreq x .04 + \charfreq y .08 + \charfreq z 1.14 +\stopcharactertable + +\endinput diff --git a/tex/context/base/lang-frq.tex b/tex/context/base/lang-frq.tex new file mode 100644 index 000000000..773230e6c --- /dev/null +++ b/tex/context/base/lang-frq.tex @@ -0,0 +1,207 @@ +%D \module +%D [ file=lang-frq, +%D version=2004.01.15, +%D title=\CONTEXT\ Language Macros, +%D subtitle=Frequency 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 Language Macros / Frequency Tables} + +\unprotect + +\ifx\s!en\undefined \def\v!en{en} \fi +\ifx\??lg\undefined \def\??lg{@@lg} \fi + +%M \usemodule[layout] + +%D \macros +%D {charwidthmethod} +%D +%D This module implements a method for determining the width of an +%D average character in a language. It uses the dimensions of the +%D current fonts. +%D +%D \def\ShwChrWd#1#2#3% +%D {\chardef\charwidthmethod#1\relax +%D \mainlanguage[#2#3]\the\dimexpr(\averagecharwidth)} +%D +%D \starttabulate[|c|c|c|c|c|c|] +%D \HL +%D \NC \NC\bf0=amount\NC\bf1=.5em\NC2=ex\NC\bf3=frequency\NC\bf4=list\NC\NR +%D \HL +%D \NC\bf en\NC\ShwChrWd0en\NC\ShwChrWd1en\NC\ShwChrWd2en\NC\ShwChrWd3en\NC\ShwChrWd4en\NC\NR +%D \NC\bf nl\NC\ShwChrWd0nl\NC\ShwChrWd1nl\NC\ShwChrWd2nl\NC\ShwChrWd3nl\NC\ShwChrWd4nl\NC\NR +%D \NC\bf de\NC\ShwChrWd0de\NC\ShwChrWd1de\NC\ShwChrWd2de\NC\ShwChrWd3de\NC\ShwChrWd4de\NC\NR +%D \HL +%D \stoptabulate +%D +%D Method~1 ignores the widths and assumes that each character has a +%D width of .5em, which is true for most monospaced fonts. Method~2 +%D takes the x as starting point, and assumes that it's height kind of +%D matches its width. Method~3 is the best one, and determines the +%D average width based on the language specific character table. +%D Method~4 is a mixture between the first two methods: character +%D specific widths applied to an equal distribution. Method~0 reports +%D the total count, which normally is~100. + +\chardef\charwidthmethod=3 % 0=amount 1=em 2=ex 3=frequency 4=flattened >4=ex + +%D \macros +%D {charwidthlanguage} +%D +%D The language used for the calculations is defined as: + +\def\charwidthlanguage{\currentmainlanguage} + +%D \macros +%D {charfreq} +%D +%D This method comes into action in the following macro: + +\def\charfreq#1 #2 % character fraction + {+(\ifcase\charwidthmethod + #2\dimexpr100\onepoint\relax + \or + #2\dimexpr.5em\relax % \emwidth/2 + \or + #2\dimexpr\exheight\relax + \or + #2\fontcharwd\font`#1% + \or + \dimexpr100\fontcharwd\font`#1/\charactertsize\charwidthlanguage\relax % ugly hack + \else + #2\dimexpr\exheight\relax + \fi)} + +%D \macros +%D {startcharactertable} +%D +%D A frequency table is defined with the following macro. The \type +%D {charfreq} macro is used in this table. + +\def\startcharactertable[#1]#2\stopcharactertable % \dimexpr has fuzzy lookahead + {\startnointerference + \long\setgvalue{\??lg:w:#1}{#2}% the width vector + \scratchcounter\zerocount \def\charfreq##1 ##2 {\advance\scratchcounter\plusone} #2% + \long\setxvalue{\??lg:c:#1}{\the\scratchcounter}% the character count + \stopnointerference} + +%D \macros +%D {charactertable,charactertsize} +%D +%D The table content as well as the number of entries can be fetched with +%D the following two macros. The architecture of the table and calling +%D macro permits a fully expandable application. + +\def\charactertable#1% + {\csname\??lg:w:\ifcsname\??lg:w:#1\endcsname#1\else\s!en\fi\endcsname} + +\def\charactertsize#1% + {\csname\??lg:c:\ifcsname\??lg:c:#1\endcsname#1\else\s!en\fi\endcsname} + +%D Although it is of hardly any use, you can inherit a character table: +%D +%D \starttyping +%D \startcharactertable[cz] \charactertable{en} \stopcharactertable +%D \stoptyping +%D +%D We define a default vector with 100\% x's. + +\startcharactertable[en] 100 x \stopcharactertable % kind of default + +%D \macros +%D {averagecharwidth} +%D +%D This macro reports the average width for the current main +%D language (\the \dimexpr (\averagecharwidth)). + +\def\averagecharwidth{\dimexpr((\zeropoint\charactertable\charwidthlanguage)/100)} + +\def\showcharfreq + {\hbox\bgroup + \charwidthlanguage:% + \dostepwiserecurse041% + {\chardef\charwidthmethod\recurselevel\relax + \enspace\recurselevel/\the\dimexpr(\averagecharwidth)}% + \egroup} + +%D Just for fun, we show a few frequency tables as graphic (\in {figure} +%D [fig:charfreq]). +%D +%D \startbuffer +%D \definepalet [charfreq] [en=darkred, nl=darkgreen, de=darkblue] +%D +%D \def\charfreq#1 #2 % +%D {\startMPdrawing +%D interim linejoin := butt ; +%D a := ASCII "#1" ; +%D if (a >= (ASCII "a")) and (a <= (ASCII "z")) : +%D draw ((0,#2*.25cm)--origin--(0,#2*.5cm)) +%D shifted (a*4mm+o,0) +%D withpen pencircle scaled .5mm +%D withcolor c; +%D fi ; +%D \stopMPdrawing} +%D +%D \resetMPdrawing +%D \startMPdrawing +%D numeric a, o ; a := o := 0 ; +%D color c ; c := .5white ; +%D string s ; s := "" ; +%D \stopMPdrawing +%D +%D \startMPdrawing o := 0mm ; c := \MPcolor{charfreq:en} ; \stopMPdrawing +%D \charactertable{en} +%D +%D \startMPdrawing o := 1mm ; c := \MPcolor{charfreq:nl} ; \stopMPdrawing +%D \charactertable{nl} +%D +%D \startMPdrawing o := 2mm ; c := \MPcolor{charfreq:de} ; \stopMPdrawing +%D \charactertable{de} +%D +%D \startMPdrawing +%D for a := ASCII "a" upto ASCII "z" : +%D draw textext.bot("\strut\tttf " & char a) shifted (a*4mm+1mm,-1mm) ; +%D endfor ; +%D \stopMPdrawing +%D +%D \MPdrawingdonetrue \getMPdrawing \resetMPdrawing +%D \stopbuffer +%D +%D \placefigure +%D [here] +%D [fig:charfreq] +%D {The character distributions for English, Dutch and German.} +%D {\getbuffer} +%D +%D A few samples of usage of this mechanism are shown below: +%D +%D \startbuffer +%D {\mainlanguage[en]\hsize65\averagecharwidth\mainlanguage[en]\input ward \blank} +%D {\mainlanguage[nl]\hsize65\averagecharwidth\mainlanguage[en]\input ward \blank} +%D {\mainlanguage[de]\hsize65\averagecharwidth\mainlanguage[en]\input ward \blank} +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D Although the widthts differ, the consequenes for breaking the paragraph +%D into lines are minimal. + +%D \macros +%D {freezeaveragecharacterwidth} +%D +%D This macro can be used to make sure that the width does not change during a +%D page break when another font is used. + +\let\normalaveragecharacterwidth\averagecharacterwidth + +\def\freezeaveragecharacterwidth % global + {\xdef\averagecharacterwidth{\dimexpr(\the\normalaveragecharacterwidth)}} + +\protect \endinput diff --git a/tex/context/base/lang-ger.tex b/tex/context/base/lang-ger.tex new file mode 100644 index 000000000..1ffbb33e6 --- /dev/null +++ b/tex/context/base/lang-ger.tex @@ -0,0 +1,738 @@ +%D \module +%D [ file=lang-ger, +%D version=1997.09.03, +%D title=\CONTEXT\ Language Macros, +%D subtitle=Germanic Languages, +%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}{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 +%D on, corrections were made by users. If you have suggestions, +%D or feel that your name missing here, don't hesitate to send +%D us an email. +%D +%D \starttabulate[|lB|l|] +%D \NC Norwegian \NC Hans Fredrik Nordhaug \NC \NR +%D \NC Danish \NC Arne Jorgensen \NC \NR % check the o +%D \NC Afrikaans \NC \NC \NR +%D \stoptabulate + +% Danish, Faeroese, Icelandic, Norwegian, Swedish, German, Yiddish +% Afrikaans, Dutch, English, Flemush, Frisian, Plattdeutsch + +\unprotect + +\installlanguage + [\s!nl] + [\c!spacing=\v!packed, + \c!leftsentence=---, + \c!rightsentence=---, + \c!leftsubsentence=---, + \c!rightsubsentence=---, + \c!leftquote=\lowerleftsingleninequote, + \c!rightquote=\upperrightsingleninequote, + \c!leftquotation=\lowerleftdoubleninequote, + \c!rightquotation=\upperrightdoubleninequote, + \c!date={\v!day,\ ,\v!month,\ ,\v!year}, + \s!mapping={texnansi,ec}, + \s!encoding={texnansi,ec}] + +\installlanguage + [\s!en] + [\c!spacing=\v!broad, + \c!leftsentence=---, + \c!rightsentence=---, + \c!leftsubsentence=---, + \c!rightsubsentence=---, + \c!leftquote=\upperleftsinglesixquote, + \c!rightquote=\upperrightsingleninequote, + \c!leftquotation=\upperleftdoublesixquote, + \c!rightquotation=\upperrightdoubleninequote, + \c!date={\v!month,\ ,\v!day,{,\ },\v!year}, + \s!patterns=\s!us, + \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={--}, + \c!rightsubsentence={--}, + \c!leftquote=\lowerleftsingleninequote, + \c!rightquote=\upperrightsinglesixquote, + \c!leftquotation=\lowerleftdoubleninequote, + \c!rightquotation=\upperrightdoublesixquote, + \c!date={\v!day,{.},\ ,\v!month,\ ,\v!year}, + \s!mapping={texnansi,ec}, + \s!encoding={texnansi,ec}] + +\installlanguage + [\s!da] + [\c!spacing=\v!packed, + \c!leftsentence={\hbox{--\hskip.5em}}, + \c!rightsentence={\hbox{\hskip.5em--}}, + \c!leftsubsentence={--}, + \c!rightsubsentence={--}, + \c!leftquote=\lowerleftsingleninequote, + \c!rightquote=\upperrightsinglesixquote, + \c!leftquotation=\lowerleftdoubleninequote, + \c!rightquotation=\upperrightdoublesixquote, + \c!date={\v!day,{.},\ ,\v!month,\ ,\v!year}] + +\installlanguage + [\s!sv] + [\c!spacing=\v!packed, + \c!leftsentence={\hbox{--~}}, + \c!rightsentence={\hbox{~--}}, + \c!leftsubsentence={--}, + \c!rightsubsentence={--}, + \c!leftquote=\upperrightsingleninequote, + \c!rightquote=\upperrightsingleninequote, + \c!leftquotation=\upperrightdoubleninequote, + \c!rightquotation=\upperrightdoubleninequote, + \c!date={\v!day,\ ,\v!month,\ ,\v!year}] + +\installlanguage + [\s!af] + [\c!spacing=\v!packed, + \c!leftsentence=---, + \c!rightsentence=---, + \c!leftsubsentence=---, + \c!rightsubsentence=---, + \c!leftquote=\upperleftsinglesixquote, + \c!rightquote=\upperrightsingleninequote, + \c!leftquotation=\upperleftdoublesixquote, + \c!rightquotation=\upperrightdoubleninequote, + \c!date={\v!year,\ ,\v!month,\ ,\v!day}, + \s!patterns=\s!nl] + +\installlanguage + [\s!nb] + [spacing=packed, + lefthyphenmin=2, + righthyphenmin=2, + leftsentence=---, + rightsentence=---, + leftsubsentence=---, + rightsubsentence=---, + leftquote=\upperleftsinglesixquote, + rightquote=\upperrightsingleninequote, + leftquotation=\leftguillemot, + rightquotation=\rightguillemot, + date={day,{.},\ ,month,\ ,year}, + state=stop] + +\installlanguage + [\s!nn] + [spacing=packed, + lefthyphenmin=2, + righthyphenmin=2, + leftsentence=---, + rightsentence=---, + leftsubsentence=---, + rightsubsentence=---, + leftquote=\upperleftsinglesixquote, + rightquote=\upperrightsingleninequote, + leftquotation=\leftguillemot, + rightquotation=\rightguillemot, + date={day,{.},\ ,month,\ ,year}, + state=stop] + +\installlanguage [\s!no] [\s!nb] +\installlanguage [\s!norwegian] [\s!nb] +\installlanguage [\s!bokmal] [\s!nb] +\installlanguage [\s!nynorsk] [\s!nn] + +%D Extra: + +% \mainlanguage[en] +% \mainlanguage[de] +% \mainlanguage[deo] +% \mainlanguage[de-de] +% \mainlanguage[de-at] +% \mainlanguage[de-ch] +% +% \starttext +% Die Herren Meier\index{Meier}, Müller\index{Müller}, Huber\index{Huber} +% und Schmidt\index{Schmidt} arbeiten in der gleichen Firma. +% +% \index{Mass}\index{Mas}\index{Maß}\index{Maße}\index{Masse} +% \index{Muller}\index{Mûller} +% \index{Hutte}\index{Hütte}\index{Huttf} +% \index{paar}\index{Paar} +% \index{a}\index{aa}\index{ä}\index{az}\index{aza} +% \index{o}\index{oo}\index{ö}\index{oz}\index{oza} +% \index{u}\index{uu}\index{ü}\index{uz}\index{uza}\index{üa} +% \index{call}\index{chip} +% +% \subject{Index} \placeindex +% \stoptext + +\installlanguage % old german + [deo] + [\c!spacing=\v!packed, + \c!default=\s!de] + +\installlanguage + [de-de] + [\c!spacing=\v!packed, + \c!default=\s!de] + +\installlanguage + [de-at] + [\c!spacing=\v!packed, + \c!default=\s!de, + \c!leftquote=\leftguillemot, + \c!rightquote=\rightguillemot, + \c!leftquotation=\leftguillemot, + \c!rightquotation=\rightguillemot] + +\installlanguage + [de-ch] + [\c!spacing=\v!packed, + \c!default=\s!de] + +%D And some alternative (but very real) english patterns: + +\installlanguage + [en-gb] + [\c!default=\s!en, + \s!patterns=\s!gb, + \s!lefthyphenmin=3, + \s!righthyphenmin=3] + +\installlanguage + [en-us] + [\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 [sp] [\s!es] % old times context /lang-ita + +\installlanguage [usenglish] [en-us] +\installlanguage [ukenglish] [en-gb] +\installlanguage [english] [en-us] +\installlanguage [dutch] [\s!nl] +\installlanguage [german] [\s!de] +\installlanguage [danish] [\s!da] +\installlanguage [swedish] [\s!sv] +\installlanguage [afrikaans] [\s!af] + +\setupheadtext [\s!en] [\v!content=Contents] +\setupheadtext [\s!nl] [\v!content=Inhoud] +\setupheadtext [\s!de] [\v!content=Inhalt] +\setupheadtext [\s!da] [\v!content=Indhold] +\setupheadtext [\s!sv] [\v!content=Inneh\aring ll] +\setupheadtext [\s!af] [\v!content=Inhoud] +\setupheadtext [\s!nb] [\v!content=Innhold] +\setupheadtext [\s!nn] [\v!content=Innhald] + +\setupheadtext [\s!en] [\v!tables=Tables] +\setupheadtext [\s!nl] [\v!tables=Tabellen] +\setupheadtext [\s!de] [\v!tables=Tabellen] +\setupheadtext [\s!da] [\v!tables=Tabeller] +\setupheadtext [\s!sv] [\v!tables=Tabeller] +\setupheadtext [\s!af] [\v!tables=Tabelle] +\setupheadtext [\s!nb] [\v!tables=Tabeller] +\setupheadtext [\s!nn] [\v!tables=Tabellar] + +\setupheadtext [\s!en] [\v!figures=Figures] +\setupheadtext [\s!nl] [\v!figures=Figuren] +\setupheadtext [\s!de] [\v!figures=Abbildungen] +\setupheadtext [\s!da] [\v!figures=Figurer] +\setupheadtext [\s!sv] [\v!figures=Figurer] +\setupheadtext [\s!af] [\v!figures=Figure] +\setupheadtext [\s!nb] [\v!figures=Figurer] +\setupheadtext [\s!nn] [\v!figures=Figurar] + +\setupheadtext [\s!en] [\v!graphics=Graphics] +\setupheadtext [\s!nl] [\v!graphics=Grafieken] +\setupheadtext [\s!de] [\v!graphics=Graphiken] +\setupheadtext [\s!da] [\v!graphics=Grafik] +\setupheadtext [\s!sv] [\v!graphics=Grafik] +\setupheadtext [\s!af] [\v!graphics=Grafieke] +\setupheadtext [\s!nb] [\v!graphics=Bilde] +\setupheadtext [\s!nn] [\v!graphics=Bilete] + +\setupheadtext [\s!en] [\v!intermezzi=Intermezzos] +\setupheadtext [\s!nl] [\v!intermezzi=Intermezzo's] +\setupheadtext [\s!de] [\v!intermezzi=Intermezzi] +\setupheadtext [\s!da] [\v!intermezzi=Intermezzoer] +\setupheadtext [\s!sv] [\v!intermezzi=Intermezzon] +\setupheadtext [\s!af] [\v!intermezzi=Intermezzos] +\setupheadtext [\s!nb] [\v!intermezzi=Intermesso] +\setupheadtext [\s!nn] [\v!intermezzi=Intermesso] + +\setupheadtext [\s!en] [\v!index=Index] +\setupheadtext [\s!nl] [\v!index=Index] +\setupheadtext [\s!de] [\v!index=Index] +\setupheadtext [\s!da] [\v!index=Indeks] +\setupheadtext [\s!sv] [\v!index=Sakregister] +\setupheadtext [\s!af] [\v!index=Indeks] +\setupheadtext [\s!nb] [\v!index=Register] +\setupheadtext [\s!nn] [\v!index=Register] + +\setupheadtext [\s!en] [\v!abbreviations=Abbreviations] +\setupheadtext [\s!nl] [\v!abbreviations=Afkortingen] +\setupheadtext [\s!de] [\v!abbreviations=Abk\uumlaut rzungen] +\setupheadtext [\s!da] [\v!abbreviations=Forkortelser] +\setupheadtext [\s!sv] [\v!abbreviations=F\oumlaut rkortningar] +\setupheadtext [\s!af] [\v!abbreviations=Afkortings] +\setupheadtext [\s!nb] [\v!abbreviations=Forkortelser] +\setupheadtext [\s!nn] [\v!abbreviations=Forkortingar] + +\setupheadtext [\s!en] [\v!logos=Logos] +\setupheadtext [\s!nl] [\v!logos=Logo's] +\setupheadtext [\s!de] [\v!logos=Logos] +\setupheadtext [\s!da] [\v!logos=Logoer] +\setupheadtext [\s!sv] [\v!logos=Loggor] +\setupheadtext [\s!af] [\v!logos=Logos] +\setupheadtext [\s!nb] [\v!logos=Logoer] +\setupheadtext [\s!nn] [\v!logos=Logoar] + +\setupheadtext [\s!en] [\v!units=Units] +\setupheadtext [\s!nl] [\v!units=Eenheden] +\setupheadtext [\s!de] [\v!units=Einheiten] +\setupheadtext [\s!da] [\v!units=Enheder] +\setupheadtext [\s!sv] [\v!units=Enheter] +\setupheadtext [\s!af] [\v!units=Eenhede] +\setupheadtext [\s!nb] [\v!units=Enheter] +\setupheadtext [\s!nn] [\v!units=Einingar] + +\setupheadtext [\s!en] [pubs=References] +\setupheadtext [\s!nl] [pubs=Literatuur] +\setupheadtext [\s!de] [pubs=Literatur] +%setupheadtext [\s!da] [pubs=?] +%setupheadtext [\s!sv] [pubs=?] +%setupheadtext [\s!af] [pubs=?] +%setupheadtext [\s!nb] [pubs=?] +%setupheadtext [\s!nn] [pubs=?] + +\setuplabeltext [\s!en] [\v!table=Table ] +\setuplabeltext [\s!nl] [\v!table=Tabel ] +\setuplabeltext [\s!de] [\v!table=Tabelle ] +\setuplabeltext [\s!da] [\v!table=Tabel ] +\setuplabeltext [\s!sv] [\v!table=Tabell ] +\setuplabeltext [\s!af] [\v!table=Tabel] +\setuplabeltext [\s!nb] [\v!table=Tabell ] +\setuplabeltext [\s!nn] [\v!table=Tabell ] + +\setuplabeltext [\s!en] [\v!figure=Figure ] +\setuplabeltext [\s!nl] [\v!figure=Figuur ] +\setuplabeltext [\s!de] [\v!figure=Abbildung ] +\setuplabeltext [\s!da] [\v!figure=Figur ] +\setuplabeltext [\s!sv] [\v!figure=Figur ] +\setuplabeltext [\s!af] [\v!figure=Figuur ] +\setuplabeltext [\s!nb] [\v!figure=Figur ] +\setuplabeltext [\s!nn] [\v!figure=Figur ] + +\setuplabeltext [\s!en] [\v!intermezzo=Intermezzo ] +\setuplabeltext [\s!nl] [\v!intermezzo=Intermezzo ] +\setuplabeltext [\s!de] [\v!intermezzo=Intermezzo ] +\setuplabeltext [\s!da] [\v!intermezzo=Intermezzo ] +\setuplabeltext [\s!sv] [\v!intermezzo=Intermezzo ] +\setuplabeltext [\s!af] [\v!intermezzo=Intermezzo ] +\setuplabeltext [\s!nb] [\v!intermezzo=Intermesso ] +\setuplabeltext [\s!nn] [\v!intermezzo=Intermesso ] + +\setuplabeltext [\s!en] [\v!graphic=Graphic ] +\setuplabeltext [\s!nl] [\v!graphic=Grafiek ] +\setuplabeltext [\s!de] [\v!graphic=Graphik ] +\setuplabeltext [\s!da] [\v!graphic=Grafik ] +\setuplabeltext [\s!sv] [\v!graphic=Grafik ] +\setuplabeltext [\s!af] [\v!graphic=Grafiek ] +\setuplabeltext [\s!nb] [\v!graphic=Bilde ] +\setuplabeltext [\s!nn] [\v!graphic=Bilete ] + +%D We don't set these here. One can do that in a style. + +\setuplabeltext [\s!en] [\v!chapter=] % Chapter +\setuplabeltext [\s!nl] [\v!chapter=] +\setuplabeltext [\s!de] [\v!chapter=] % Kapitel +\setuplabeltext [\s!da] [\v!chapter=] +\setuplabeltext [\s!sv] [\v!chapter=] +\setuplabeltext [\s!af] [\v!chapter=] % Hoofstuk +\setuplabeltext [\s!nb] [\v!chapter=] +\setuplabeltext [\s!nn] [\v!chapter=] + +\setuplabeltext [\s!en] [\v!section=] +\setuplabeltext [\s!nl] [\v!section=] +\setuplabeltext [\s!de] [\v!section=] +\setuplabeltext [\s!da] [\v!section=] +\setuplabeltext [\s!sv] [\v!section=] +\setuplabeltext [\s!af] [\v!section=] % Paragraaf +\setuplabeltext [\s!nb] [\v!section=] +\setuplabeltext [\s!nn] [\v!section=] + +\setuplabeltext [\s!en] [\v!subsection=] +\setuplabeltext [\s!nl] [\v!subsection=] +\setuplabeltext [\s!de] [\v!subsection=] +\setuplabeltext [\s!da] [\v!subsection=] +\setuplabeltext [\s!sv] [\v!subsection=] +\setuplabeltext [\s!af] [\v!subsection=] +\setuplabeltext [\s!nb] [\v!subsection=] +\setuplabeltext [\s!nn] [\v!subsection=] + +\setuplabeltext [\s!en] [\v!subsubsection=] +\setuplabeltext [\s!nl] [\v!subsubsection=] +\setuplabeltext [\s!de] [\v!subsubsection=] +\setuplabeltext [\s!da] [\v!subsubsection=] +\setuplabeltext [\s!sv] [\v!subsubsection=] +\setuplabeltext [\s!af] [\v!subsubsection=] +\setuplabeltext [\s!nb] [\v!subsubsection=] +\setuplabeltext [\s!nn] [\v!subsubsection=] + +\setuplabeltext [\s!en] [\v!subsubsubsection=] +\setuplabeltext [\s!nl] [\v!subsubsubsection=] +\setuplabeltext [\s!de] [\v!subsubsubsection=] +\setuplabeltext [\s!da] [\v!subsubsubsection=] +\setuplabeltext [\s!sv] [\v!subsubsubsection=] +\setuplabeltext [\s!af] [\v!subsubsubsection=] +\setuplabeltext [\s!nb] [\v!subsubsubsection=] +\setuplabeltext [\s!nn] [\v!subsubsubsection=] + +\setuplabeltext [\s!en] [\v!appendix=] % Appendix +\setuplabeltext [\s!nl] [\v!appendix=] +\setuplabeltext [\s!de] [\v!appendix=] % Anhang +\setuplabeltext [\s!da] [\v!appendix=] % Bilag +\setuplabeltext [\s!sv] [\v!appendix=] +\setuplabeltext [\s!af] [\v!appendix=] % Bylae +\setuplabeltext [\s!nb] [\v!appendix=] % Tillegg +\setuplabeltext [\s!nn] [\v!appendix=] % Tillegg + +\setuplabeltext [\s!en] [\v!part=Part ] +\setuplabeltext [\s!nl] [\v!part=Deel ] +\setuplabeltext [\s!de] [\v!part=Teil ] +\setuplabeltext [\s!da] [\v!part=Del ] +\setuplabeltext [\s!sv] [\v!part=Del ] +\setuplabeltext [\s!af] [\v!part=Deel ] +\setuplabeltext [\s!nb] [\v!part=Del] +\setuplabeltext [\s!nn] [\v!part=Del] + +\setuplabeltext [\s!en] [\v!line=line ] +\setuplabeltext [\s!nl] [\v!line=regel ] +\setuplabeltext [\s!de] [\v!line=Zeile ] +\setuplabeltext [\s!da] [\v!line=linie ] % or linje +\setuplabeltext [\s!sv] [\v!line=rad ] +\setuplabeltext [\s!af] [\v!line=re\ediaeresis l ] +\setuplabeltext [\s!nb] [\v!line=linje ] +\setuplabeltext [\s!nn] [\v!line=linje ] + +\setuplabeltext [\s!en] [\v!lines=lines ] +\setuplabeltext [\s!nl] [\v!lines=regels ] +\setuplabeltext [\s!de] [\v!lines=Zeilen ] +\setuplabeltext [\s!da] [\v!lines=linier ] % or linjer +\setuplabeltext [\s!sv] [\v!lines=rader ] +\setuplabeltext [\s!af] [\v!lines=re\ediaeresis ls ] +\setuplabeltext [\s!nb] [\v!lines=linjer ] +\setuplabeltext [\s!nn] [\v!lines=linjer ] + +\setuplabeltext [\s!en] [\v!january=January] +\setuplabeltext [\s!en] [\v!february=February] +\setuplabeltext [\s!en] [\v!march=March] +\setuplabeltext [\s!en] [\v!april=April] +\setuplabeltext [\s!en] [\v!may=May] +\setuplabeltext [\s!en] [\v!june=June] +\setuplabeltext [\s!en] [\v!july=July] +\setuplabeltext [\s!en] [\v!august=August] +\setuplabeltext [\s!en] [\v!september=September] +\setuplabeltext [\s!en] [\v!october=October] +\setuplabeltext [\s!en] [\v!november=November] +\setuplabeltext [\s!en] [\v!december=December] + +\setuplabeltext [\s!nl] [\v!january=januari] +\setuplabeltext [\s!nl] [\v!february=februari] +\setuplabeltext [\s!nl] [\v!march=maart] +\setuplabeltext [\s!nl] [\v!april=april] +\setuplabeltext [\s!nl] [\v!may=mei] +\setuplabeltext [\s!nl] [\v!june=juni] +\setuplabeltext [\s!nl] [\v!july=juli] +\setuplabeltext [\s!nl] [\v!august=augustus] +\setuplabeltext [\s!nl] [\v!september=september] +\setuplabeltext [\s!nl] [\v!october=oktober] +\setuplabeltext [\s!nl] [\v!november=november] +\setuplabeltext [\s!nl] [\v!december=december] + +\setuplabeltext [\s!de] [\v!january=Januar] +\setuplabeltext [\s!de] [\v!february=Februar] +\setuplabeltext [\s!de] [\v!march=M\aumlaut rz] +\setuplabeltext [\s!de] [\v!april=April] +\setuplabeltext [\s!de] [\v!may=Mai] +\setuplabeltext [\s!de] [\v!june=Juni] +\setuplabeltext [\s!de] [\v!july=Juli] +\setuplabeltext [\s!de] [\v!august=August] +\setuplabeltext [\s!de] [\v!september=September] +\setuplabeltext [\s!de] [\v!october=Oktober] +\setuplabeltext [\s!de] [\v!november=November] +\setuplabeltext [\s!de] [\v!december=Dezember] + +\setuplabeltext [\s!da] [\v!january=januar] +\setuplabeltext [\s!da] [\v!february=februar] +\setuplabeltext [\s!da] [\v!march=marts] +\setuplabeltext [\s!da] [\v!april=april] +\setuplabeltext [\s!da] [\v!may=maj] +\setuplabeltext [\s!da] [\v!june=juni] +\setuplabeltext [\s!da] [\v!july=juli] +\setuplabeltext [\s!da] [\v!august=august] +\setuplabeltext [\s!da] [\v!september=september] +\setuplabeltext [\s!da] [\v!october=oktober] +\setuplabeltext [\s!da] [\v!november=november] +\setuplabeltext [\s!da] [\v!december=december] + +\setuplabeltext [\s!sv] [\v!january=januari] +\setuplabeltext [\s!sv] [\v!february=februari] +\setuplabeltext [\s!sv] [\v!march=mars] +\setuplabeltext [\s!sv] [\v!april=april] +\setuplabeltext [\s!sv] [\v!may=maj] +\setuplabeltext [\s!sv] [\v!june=juni] +\setuplabeltext [\s!sv] [\v!july=juli] +\setuplabeltext [\s!sv] [\v!august=augusti] +\setuplabeltext [\s!sv] [\v!september=september] +\setuplabeltext [\s!sv] [\v!october=oktober] +\setuplabeltext [\s!sv] [\v!november=november] +\setuplabeltext [\s!sv] [\v!december=december] + +\setuplabeltext [\s!af] [\v!january=januarie] +\setuplabeltext [\s!af] [\v!february=februarie] +\setuplabeltext [\s!af] [\v!march=maart] +\setuplabeltext [\s!af] [\v!april=april] +\setuplabeltext [\s!af] [\v!may=mei] +\setuplabeltext [\s!af] [\v!june=junie] +\setuplabeltext [\s!af] [\v!july=julie] +\setuplabeltext [\s!af] [\v!august=augustus] +\setuplabeltext [\s!af] [\v!september=september] +\setuplabeltext [\s!af] [\v!october=oktober] +\setuplabeltext [\s!af] [\v!november=november] +\setuplabeltext [\s!af] [\v!december=desember] + +\setuplabeltext [\s!nb] [\v!january=januar] +\setuplabeltext [\s!nb] [\v!february=februar] +\setuplabeltext [\s!nb] [\v!march=mars] +\setuplabeltext [\s!nb] [\v!april=april] +\setuplabeltext [\s!nb] [\v!may=mai] +\setuplabeltext [\s!nb] [\v!june=juni] +\setuplabeltext [\s!nb] [\v!july=juli] +\setuplabeltext [\s!nb] [\v!august=august] +\setuplabeltext [\s!nb] [\v!september=september] +\setuplabeltext [\s!nb] [\v!october=oktober] +\setuplabeltext [\s!nb] [\v!november=november] +\setuplabeltext [\s!nb] [\v!december=desember] + +\setuplabeltext [\s!nn] [\v!january=januar] +\setuplabeltext [\s!nn] [\v!february=februar] +\setuplabeltext [\s!nn] [\v!march=mars] +\setuplabeltext [\s!nn] [\v!april=april] +\setuplabeltext [\s!nn] [\v!may=mai] +\setuplabeltext [\s!nn] [\v!june=juni] +\setuplabeltext [\s!nn] [\v!july=juli] +\setuplabeltext [\s!nn] [\v!august=august] +\setuplabeltext [\s!nn] [\v!september=september] +\setuplabeltext [\s!nn] [\v!october=oktober] +\setuplabeltext [\s!nn] [\v!november=november] +\setuplabeltext [\s!nn] [\v!december=desember] + +\setuplabeltext [\s!en] [\v!sunday=Sunday] +\setuplabeltext [\s!en] [\v!monday=Monday] +\setuplabeltext [\s!en] [\v!tuesday=Tuesday] +\setuplabeltext [\s!en] [\v!wednesday=Wednesday] +\setuplabeltext [\s!en] [\v!thursday=Thursday] +\setuplabeltext [\s!en] [\v!friday=Friday] +\setuplabeltext [\s!en] [\v!saturday=Saturday] + +\setuplabeltext [\s!nl] [\v!sunday=zondag] +\setuplabeltext [\s!nl] [\v!monday=maandag] +\setuplabeltext [\s!nl] [\v!tuesday=dinsdag] +\setuplabeltext [\s!nl] [\v!wednesday=woensdag] +\setuplabeltext [\s!nl] [\v!thursday=donderdag] +\setuplabeltext [\s!nl] [\v!friday=vrijdag] +\setuplabeltext [\s!nl] [\v!saturday=zaterdag] + +\setuplabeltext [\s!de] [\v!sunday=Sonntag] +\setuplabeltext [\s!de] [\v!monday=Montag] +\setuplabeltext [\s!de] [\v!tuesday=Dienstag] +\setuplabeltext [\s!de] [\v!wednesday=Mittwoch] +\setuplabeltext [\s!de] [\v!thursday=Donnerstag] +\setuplabeltext [\s!de] [\v!friday=Freitag] +\setuplabeltext [\s!de] [\v!saturday=Samstag] + +\setuplabeltext [\s!da] [\v!sunday=s\ostroke ndag] +\setuplabeltext [\s!da] [\v!monday=mandag] +\setuplabeltext [\s!da] [\v!tuesday=tirsdag] +\setuplabeltext [\s!da] [\v!wednesday=onsdag] +\setuplabeltext [\s!da] [\v!thursday=torsdag] +\setuplabeltext [\s!da] [\v!friday=fredag] +\setuplabeltext [\s!da] [\v!saturday=l\ostroke rdag] + +\setuplabeltext [\s!sv] [\v!sunday=s\oumlaut ndag] +\setuplabeltext [\s!sv] [\v!monday=m\aring ndag] +\setuplabeltext [\s!sv] [\v!tuesday=tisdag] +\setuplabeltext [\s!sv] [\v!wednesday=onsdag] +\setuplabeltext [\s!sv] [\v!thursday=torsdag] +\setuplabeltext [\s!sv] [\v!friday=fredag] +\setuplabeltext [\s!sv] [\v!saturday=l\oumlaut rdag] + +\setuplabeltext [\s!af] [\v!sunday=sondag] +\setuplabeltext [\s!af] [\v!monday=maandag] +\setuplabeltext [\s!af] [\v!tuesday=dinsdag] +\setuplabeltext [\s!af] [\v!wednesday=woensdag] +\setuplabeltext [\s!af] [\v!thursday=donderdag] +\setuplabeltext [\s!af] [\v!friday=vrydag] +\setuplabeltext [\s!af] [\v!saturday=saterdag] + +\setuplabeltext [\s!nb] [\v!sunday=s\ostroke ndag] +\setuplabeltext [\s!nb] [\v!monday=mandag] +\setuplabeltext [\s!nb] [\v!tuesday=tirsdag] +\setuplabeltext [\s!nb] [\v!wednesday=onsdag] +\setuplabeltext [\s!nb] [\v!thursday=torsdag] +\setuplabeltext [\s!nb] [\v!friday=fredag] +\setuplabeltext [\s!nb] [\v!saturday=l\ostroke rdag] + +\setuplabeltext [\s!nn] [\v!sunday=sundag] +\setuplabeltext [\s!nn] [\v!monday=m\aring ndag] +\setuplabeltext [\s!nn] [\v!tuesday=tysdag] +\setuplabeltext [\s!nn] [\v!wednesday=onsdag] +\setuplabeltext [\s!nn] [\v!thursday=torsdag] +\setuplabeltext [\s!nn] [\v!friday=fredag] +\setuplabeltext [\s!nn] [\v!saturday=laurdag] + +%D Rather new ... + +\setuplabeltext [\s!nl] [\v!page=pagina ] +\setuplabeltext [\s!nl] [\v!atpage=op pagina ] +\setuplabeltext [\s!nl] [\v!hencefore=hierboven] +\setuplabeltext [\s!nl] [\v!hereafter=hieronder] +\setuplabeltext [\s!nl] [\v!see=zie ] + +\setuplabeltext [\s!en] [\v!page=page ] +\setuplabeltext [\s!en] [\v!atpage=at page ] +\setuplabeltext [\s!en] [\v!hencefore=as we show above] +\setuplabeltext [\s!en] [\v!hereafter=as we show below] +\setuplabeltext [\s!en] [\v!see=see ] + +\setuplabeltext [\s!de] [\v!page=Seite ] +\setuplabeltext [\s!de] [\v!atpage=auf Seite ] +\setuplabeltext [\s!de] [\v!hencefore=siehe oben] +\setuplabeltext [\s!de] [\v!hereafter=siehe unten] +\setuplabeltext [\s!de] [\v!see=siehe ] + +\setuplabeltext [\s!da] [\v!page=Side ] +\setuplabeltext [\s!da] [\v!atpage=p\aring\ side ] +\setuplabeltext [\s!da] [\v!hencefore=se foroven] +\setuplabeltext [\s!da] [\v!hereafter=se forneden] +\setuplabeltext [\s!da] [\v!see=se ] + +\setuplabeltext [\s!sv] [\v!page=Sida ] +\setuplabeltext [\s!sv] [\v!atpage=p\aring\ sida ] +\setuplabeltext [\s!sv] [\v!hencefore=se ovan] +\setuplabeltext [\s!sv] [\v!hereafter=se nedan] +\setuplabeltext [\s!sv] [\v!see=se ] + +\setuplabeltext [\s!nb] [\v!page=side ] +\setuplabeltext [\s!nb] [\v!atpage=p\aring\ side ] +\setuplabeltext [\s!nb] [\v!hencefore=som vist over] +\setuplabeltext [\s!nb] [\v!hereafter=som vist under] +\setuplabeltext [\s!nb] [\v!see=se ] + +\setuplabeltext [\s!nn] [\v!page=side ] +\setuplabeltext [\s!nn] [\v!atpage=p\aring\ side ] +\setuplabeltext [\s!nn] [\v!hencefore=som vist over] +\setuplabeltext [\s!nn] [\v!hereafter=som vist under] +\setuplabeltext [\s!nn] [\v!see=sj\aring\ ] + +%D ... and to be completed! + +%D Next we implement couple of ordinal mumber converters: + +\def\enordinaldaynumber#1% + {#1\ifnum\lasttwodigits{#1}=11 + \highordinalstr{th}% + \else\ifnum\lasttwodigits{#1}=12 + \highordinalstr{th}% + \else\ifnum\lasttwodigits{#1}=13 + \highordinalstr{th}% + \else\ifcase\lastdigit{#1}% + \highordinalstr{th}% + \or % 1 + \highordinalstr{st}% + \or % 2 + \highordinalstr{nd}% + \or % 3 + \highordinalstr{rd}% + \else + \highordinalstr{th}% + \fi\fi\fi\fi} + +% \def\enordinaldaynumber#1% +% {#1\ordinalstr{\ifnum\lasttwodigits{#1}=11 th\else\ifcase\lastdigit{#1} +% th\or st\or nd\or rd\else th\fi\fi}} + +\def\nlordinaldaynumber#1% + {#1\highordinalstr{e}} + +%D \ShowAllLanguageValues [\s!en] [english] {English} {horn} % engelse humor +%D \ShowAllLanguageValues [\s!nl] [dutch] {Dutch} {treat} % nederlandse zuinigheid +%D \ShowAllLanguageValues [\s!de] [german] {German} {beer} % duitse degelijkheid +%D \ShowAllLanguageValues [\s!da] [danish] {Danish} {pastry} +%D \ShowAllLanguageValues [\s!sv] [swedish] {Swedish} {design} +%D \ShowAllLanguageValues [\s!af] [afrikaans] {Afrikaaner} {boer} % afrikaanse gasvryheid +%D \ShowAllLanguageValues [\s!nb] [bokmal] {Norwegian} {wood} +%D \ShowAllLanguageValues [\s!nn] [nynorsk] {Norwegian} {fish} + +%D Extra month names: + +\setuplabeltext [\s!en] [\v!january :\s!mnem=jan] +\setuplabeltext [\s!en] [\v!february :\s!mnem=feb] +\setuplabeltext [\s!en] [\v!march :\s!mnem=mar] +\setuplabeltext [\s!en] [\v!april :\s!mnem=apr] +\setuplabeltext [\s!en] [\v!may :\s!mnem=may] +\setuplabeltext [\s!en] [\v!june :\s!mnem=jun] +\setuplabeltext [\s!en] [\v!july :\s!mnem=jul] +\setuplabeltext [\s!en] [\v!august :\s!mnem=aug] +\setuplabeltext [\s!en] [\v!september:\s!mnem=sep] +\setuplabeltext [\s!en] [\v!october :\s!mnem=oct] +\setuplabeltext [\s!en] [\v!november :\s!mnem=nov] +\setuplabeltext [\s!en] [\v!december :\s!mnem=dec] + +\setuplabeltext [\s!nb] [\v!january :\s!mnem=jan.] +\setuplabeltext [\s!nb] [\v!february :\s!mnem=feb.] +\setuplabeltext [\s!nb] [\v!march :\s!mnem=mars] +\setuplabeltext [\s!nb] [\v!april :\s!mnem=april] +\setuplabeltext [\s!nb] [\v!may :\s!mnem=mai] +\setuplabeltext [\s!nb] [\v!june :\s!mnem=juni] +\setuplabeltext [\s!nb] [\v!july :\s!mnem=juli] +\setuplabeltext [\s!nb] [\v!august :\s!mnem=aug.] +\setuplabeltext [\s!nb] [\v!september:\s!mnem=sep.] +\setuplabeltext [\s!nb] [\v!october :\s!mnem=okt.] +\setuplabeltext [\s!nb] [\v!november :\s!mnem=nov.] +\setuplabeltext [\s!nb] [\v!december :\s!mnem=des.] + +\setuplabeltext [\s!nn] [\v!january :\s!mnem=jan.] +\setuplabeltext [\s!nn] [\v!february :\s!mnem=feb.] +\setuplabeltext [\s!nn] [\v!march :\s!mnem=mars] +\setuplabeltext [\s!nn] [\v!april :\s!mnem=april] +\setuplabeltext [\s!nn] [\v!may :\s!mnem=mai] +\setuplabeltext [\s!nn] [\v!june :\s!mnem=juni] +\setuplabeltext [\s!nn] [\v!july :\s!mnem=juli] +\setuplabeltext [\s!nn] [\v!august :\s!mnem=aug.] +\setuplabeltext [\s!nn] [\v!september:\s!mnem=sep.] +\setuplabeltext [\s!nn] [\v!october :\s!mnem=okt.] +\setuplabeltext [\s!nn] [\v!november :\s!mnem=nov.] +\setuplabeltext [\s!nn] [\v!december :\s!mnem=des.] + +\protect \endinput diff --git a/tex/context/base/lang-grk.tex b/tex/context/base/lang-grk.tex new file mode 100644 index 000000000..e4ba781eb --- /dev/null +++ b/tex/context/base/lang-grk.tex @@ -0,0 +1,94 @@ +%D \module +%D [ file=lang-grk, +%D version=2003.04.01, +%D title=\CONTEXT\ Language Macros, +%D subtitle=Uralic Languages, +%D author=Apostolos Syropoulos +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Greek} + +%D The framework of this module is set up by Hans Hagen while +%D all the translations have been done by Apostolos Syropoulos + +\unprotect + +\installlanguage + [\s!gr] + [\c!spacing=\v!packed, + \c!leftsentence=---, + \c!rightsentence=---, + \c!leftsubsentence=---, + \c!rightsubsentence=---, + \c!leftquote=\greekleftquot, + \c!rightquote=\greekrightquot, + \c!leftquotation=\greekleftquot, + \c!rightquotation=\greekrightquot, + \c!date={\v!day\ \v!month\ \v!year}] + +\installlanguage [greek] [\s!gr] + +\setupheadtext [\s!gr] [\v!content=\greekPi\greekepsilon\greekrho\greekiota\greekepsilon\greekchi\greekomicrontonos\greekmu\greekepsilon\greeknu\greekalpha] +\setupheadtext [\s!gr] [\v!tables=\greekPi\greekiotatonos\greeknu\greekalpha\greekkappa\greekepsilon\greekfinalsigma] +\setupheadtext [\s!gr] [\v!figures=\greekSigma\greekchi\greeketatonos\greekmu\greekalpha\greektau\greekalpha] +\setupheadtext [\s!gr] [\v!graphics=\greekGamma\greekrho\greekalpha\greekphi\greekiota\greekkappa\greekalphatonos] +\setupheadtext [\s!gr] [\v!intermezzi=\greekPi\greekalpha\greekupsilontonos\greeksigma\greekepsilon\greekiota\greekfinalsigma] +\setupheadtext [\s!gr] [\v!index=\greekEpsilon\greekupsilon\greekrho\greekepsilon\greektau\greeketatonos\greekrho\greekiota\greekomicron] +\setupheadtext [\s!gr] [\v!abbreviations=\greekSigma\greekupsilon\greeknu\greektau\greekomicron\greekmu\greekomicron\greekgamma\greekrho\greekalpha\greekphi\greekiotatonos\greekepsilon\greekfinalsigma] +\setupheadtext [\s!gr] [\v!logos=\greekLambda\greekomicron\greekgamma\greekomicrontonos\greektau\greekupsilon\greekpi\greekalpha] +\setupheadtext [\s!gr] [\v!units=\greekMu\greekomicron\greeknu\greekalphatonos\greekdelta\greekepsilon\greekfinalsigma] + +\setuplabeltext [\s!gr] [\v!table=\greekPi\greekiotatonos\greeknu\greekalpha\greekkappa\greekalpha\greekfinalsigma] +\setuplabeltext [\s!gr] [\v!figure=\greekSigma\greekchi\greeketatonos\greekmu\greekalpha] +\setuplabeltext [\s!gr] [\v!intermezzo=\greekPi\greekalpha\greekupsilontonos\greeksigma\greeketa] +\setuplabeltext [\s!gr] [\v!graphic=\greekGamma\greekrho\greekalpha\greekphi\greekiota\greekkappa\greekomicrontonos] + +\setuplabeltext [\s!gr] [\v!chapter=\greekKappa\greekepsilon\greekphi\greekalphatonos\greeklambda\greekalpha\greekiota\greekomicron] +\setuplabeltext [\s!gr] [\v!section=\greekEpsilon\greeknu\greekomicrontonos\greektau\greeketa\greektau\greekalpha] +\setuplabeltext [\s!gr] [\v!subsection=\greekUpsilon\greekpi\greekomicrontonos\greekepsilon\greeknu\greekomicrontonos\greektau\greeketa\greektau\greekalpha] +\setuplabeltext [\s!gr] [\v!subsubsection=] +\setuplabeltext [\s!gr] [\v!subsubsubsection=] + +\setuplabeltext [\s!gr] [\v!appendix=\greekPi\greekalpha\greekrho\greekalphatonos\greekrho\greektau\greeketa\greekmu\greekalpha] +\setuplabeltext [\s!gr] [\v!part=\greekMu\greekepsilontonos\greekrho\greekomicron\greekfinalsigma] +\setuplabeltext [\s!gr] [\v!line=\greekGamma\greekrho\greekalpha\greekmu\greekmu\greeketatonos] +\setuplabeltext [\s!gr] [\v!lines=\greekGamma\greekrho\greekalpha\greekmu\greekmu\greekepsilontonos\greekfinalsigma] + +\setuplabeltext [\s!gr] [\v!january=\greekIota\greekalpha\greeknu\greekomicron\greekupsilon\greekalphatonos\greekrho\greekiota\greekomicron\greekfinalsigma] +\setuplabeltext [\s!gr] [\v!february=\greekPhi\greekepsilon\greekbeta\greekrho\greekomicron\greekupsilon\greekalphatonos\greekrho\greekiota\greekomicron\greekfinalsigma] +\setuplabeltext [\s!gr] [\v!march=\greekMu\greekalphatonos\greekrho\greektau\greekiota\greekomicron\greekfinalsigma] +\setuplabeltext [\s!gr] [\v!april=\greekAlpha\greekpi\greekrho\greekiotatonos\greeklambda\greekiota\greekomicron\greekfinalsigma] +\setuplabeltext [\s!gr] [\v!may=\greekMu\greekalphatonos\greekiota\greekomicron\greekfinalsigma] +\setuplabeltext [\s!gr] [\v!june=\greekIota\greekomicron\greekupsilontonos\greeknu\greekiota\greekomicron\greekfinalsigma] +\setuplabeltext [\s!gr] [\v!july=\greekIota\greekomicron\greekupsilontonos\greeklambda\greekiota\greekomicron\greekfinalsigma] +\setuplabeltext [\s!gr] [\v!august=\greekAlpha\greekupsilontonos\greekgamma\greekomicron\greekupsilon\greeksigma\greektau\greekomicron\greekfinalsigma] +\setuplabeltext [\s!gr] [\v!september=\greekSigma\greekepsilon\greekpi\greektau\greekepsilontonos\greekmu\greekbeta\greekrho\greekiota\greekomicron\greekfinalsigma] +\setuplabeltext [\s!gr] [\v!october=\greekOmicron\greekkappa\greektau\greekomegatonos\greekbeta\greekrho\greekiota\greekomicron\greekfinalsigma] +\setuplabeltext [\s!gr] [\v!november=\greekNu\greekomicron\greekepsilontonos\greekmu\greekbeta\greekrho\greekiota\greekomicron\greekfinalsigma] +\setuplabeltext [\s!gr] [\v!december=\greekDelta\greekepsilon\greekkappa\greekepsilontonos\greekmu\greekbeta\greekrho\greekiota\greekomicron\greekfinalsigma] + +\setuplabeltext [\s!gr] [\v!sunday=\greekKappa\greekupsilon\greekrho\greekiota\greekalpha\greekkappa\greeketatonos] +\setuplabeltext [\s!gr] [\v!monday=\greekDelta\greekepsilon\greekupsilon\greektau\greekepsilontonos\greekrho\greekalpha] +\setuplabeltext [\s!gr] [\v!tuesday=\greekTau\greekrho\greekiotatonos\greektau\greeketa] +\setuplabeltext [\s!gr] [\v!wednesday=\greekTau\greekepsilon\greektau\greekalphatonos\greekrho\greektau\greeketa] +\setuplabeltext [\s!gr] [\v!thursday=\greekPi\greekepsilontonos\greekmu\greekpi\greektau\greeketa] +\setuplabeltext [\s!gr] [\v!friday=\greekPi\greekalpha\greekrho\greekalpha\greeksigma\greekkappa\greekepsilon\greekupsilon\greeketatonos] +\setuplabeltext [\s!gr] [\v!saturday=\greekSigma\greekalphatonos\greekbeta\greekbeta\greekalpha\greektau\greekomicron] + +%D % \ShowAllLanguageValues [\s!gr] [\greekEpsilon\greeklambda\greeklambda\greeketa\greeknu\greekiota\greekkappa\greekalphatonos] {Greek} {love} + +\installlanguage + [\s!agr] + [\s!default=\s!gr, + \s!patterns=\s!agr, + \s!mapping=\s!agr, + \s!encoding=\s!agr] + +\installlanguage [ancientgreek] [\s!agr] + +\protect \endinput diff --git a/tex/context/base/lang-ind.tex b/tex/context/base/lang-ind.tex new file mode 100644 index 000000000..9b6e5ff1d --- /dev/null +++ b/tex/context/base/lang-ind.tex @@ -0,0 +1,26 @@ +%D \module +%D [ file=lang--ind, +%D version=1997.09.03, +%D title=\CONTEXT\ Language Macros, +%D subtitle=Indo Iranian Languages, +%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}{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 +%D on, corrections were made by users. If you have suggestions, +%D or feel that your name missing here, don't hesitate to send +%D us an email. + +% 34 languages + +\unprotect + +\protect \endinput diff --git a/tex/context/base/lang-ini.lua b/tex/context/base/lang-ini.lua new file mode 100644 index 000000000..239e5390c --- /dev/null +++ b/tex/context/base/lang-ini.lua @@ -0,0 +1,321 @@ +if not modules then modules = { } end modules ['lang-ini'] = { + version = 1.001, + comment = "companion to lang-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- needs a cleanup (share locals) + +local utf = unicode.utf8 +local utfbyte = utf.byte +local format = string.format +local concat = table.concat +local lpegmatch = lpeg.match + +local trace_patterns = false trackers.register("languages.patterns", function(v) trace_patterns = v end) + +languages = languages or {} +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 +-- 2013 : endash (compound hyphen) + +--~ lang:hyphenation(string) +--~ string =lang:hyphenation() +--~ lang:clear_hyphenation() + +-- we can consider hiding data (faster access too) + +-- loading the 26 languages that we normally load in mkiv, the string based variant +-- takes .84 seconds (probably due to the sub's) while the lpeg variant takes .78 +-- seconds +-- +-- the following lpeg can probably be improved (it was one of the first I made) + +local leftbrace = lpeg.P("{") +local rightbrace = lpeg.P("}") +local spaces = lpeg.S(" \r\n\t\f") +local spacing = spaces^0 +local validchar = 1-(spaces+rightbrace+leftbrace) +local validword = validchar^1 +local content = spacing * leftbrace * spacing * lpeg.C((spacing * validword)^0) * spacing * rightbrace * lpeg.P(true) + +local command = lpeg.P("\\patterns") +local parser = (1-command)^0 * command * content + +local function filterpatterns(filename) + if file.extname(filename) == "rpl" then + return io.loaddata(resolvers.find_file(filename)) or "" + else + return lpegmatch(parser,io.loaddata(resolvers.find_file(filename)) or "") + end +end + +local command = lpeg.P("\\hyphenation") +local parser = (1-command)^0 * command * content + +local function filterexceptions(filename) + if file.extname(filename) == "rhl" then + return io.loaddata(resolvers.find_file(filename)) or "" + else + return lpegmatch(parser,io.loaddata(resolvers.find_file(filename)) or {}) -- "" ? + end +end + +local function record(tag) + local data = langdata[tag] + if not data then + data = lang.new() + langdata[tag] = data or 0 + end + return data +end + +languages.hyphenation.record = record + +function languages.hyphenation.define(tag) + local data = record(tag) + return data:id() +end + +function languages.hyphenation.number(tag) + local d = langdata[tag] + return (d and d:id()) or 0 +end + +lang.exceptions = lang.hyphenation + +local function loadthem(tag, filename, filter, target) + statistics.starttiming(languages) + local data = record(tag) + local fullname = (filename and filename ~= "" and resolvers.find_file(filename)) or "" + local ok = fullname ~= "" + if ok then + if trace_patterns then + logs.report("languages","filtering %s for language '%s' from '%s'",target,tag,fullname) + end + lang[target](data,filterpatterns(fullname)) + else + if trace_patterns then + logs.report("languages","no %s for language '%s' in '%s'",target,tag,filename or "?") + end + lang[target](data,"") + end + langdata[tag] = data + statistics.stoptiming(languages) + return ok +end + +function languages.hyphenation.loadpatterns(tag, patterns) + return loadthem(tag, patterns, filterpatterns, "patterns") +end + +function languages.hyphenation.loadexceptions(tag, exceptions) + return loadthem(tag, patterns, filterexceptions, "exceptions") +end + +function languages.hyphenation.exceptions(tag, ...) + local data = record(tag) + data:hyphenation(...) +end + +function languages.hyphenation.hyphenate(tag, str) + return lang.hyphenate(record(tag), str) +end + +function languages.hyphenation.lefthyphenmin(tag, value) + local data = record(tag) + if value then data:lefthyphenmin(value) end + return data:lefthyphenmin() +end +function languages.hyphenation.righthyphenmin(tag, value) + local data = record(tag) + if value then data:righthyphenmin(value) end + return data:righthyphenmin() +end + +function languages.hyphenation.n() + return table.count(langdata) +end + +languages.registered = languages.registered or { } +languages.associated = languages.associated or { } +languages.numbers = languages.numbers or { } + +storage.register("languages/registered",languages.registered,"languages.registered") +storage.register("languages/associated",languages.associated,"languages.associated") + +local numbers = languages.numbers +local registered = languages.registered +local associated = languages.associated + +-- we can speed this one up with locals if needed + +local function tolang(what) + local kind = type(what) + if kind == "number" then + local w = what >= 0 and what <= 0x7FFF and numbers[what] + return (w and langdata[w]) or 0 + elseif kind == "string" then + return langdata[what] + else + return what + end +end + +function languages.setup(what,settings) + what = languages.tolang(what or tex.language) + local lefthyphen = settings.lefthyphen + local righthyphen = settings.righthyphen + lefthyphen = lefthyphen ~= "" and lefthyphen or nil + righthyphen = righthyphen ~= "" and righthyphen or nil + lefthyphen = lefthyphen and utfbyte(lefthyphen) or 0 + righthyphen = righthyphen and utfbyte(righthyphen) or 0 + lang.posthyphenchar(what,lefthyphen) + lang.prehyphenchar (what,righthyphen) + lang.postexhyphenchar(what,lefthyphen) + lang.preexhyphenchar (what,righthyphen) +end + +function languages.prehyphenchar(what) + return lang.prehyphenchar(tolang(what)) +end +function languages.posthyphenchar(what) + return lang.posthyphenchar(tolang(what)) +end + +languages.tolang = tolang + +function languages.register(tag,parent,patterns,exceptions) + parent = parent or tag + registered[tag] = { + parent = parent, + patterns = patterns or format("lang-%s.pat",parent), + exceptions = exceptions or format("lang-%s.hyp",parent), + loaded = false, + number = 0, + } +end + +function languages.associate(tag,script,language) + associated[tag] = { script, language } +end + +function languages.association(tag) + if type(tag) == "number" then + tag = numbers[tag] + end + local lat = tag and associated[tag] + if lat then + return lat[1], lat[2] + else + return nil, nil + end +end + +function languages.loadable(tag) + local l = registered[tag] + if l and l.patterns and resolvers.find_file(patterns) then + return true + else + return false + end +end + +languages.share = false -- we don't share language numbers + +function languages.enable(tags) + -- beware: we cannot set tex.language, but need tex.normallanguage + for i=1,#tags do + local tag = tags[i] + local l = registered[tag] + if l and l ~= "" then + if not l.loaded then + local tag = l.parent + local number = languages.hyphenation.number(tag) + if languages.share and number > 0 then + l.number = number + else + -- we assume the same filenames + l.number = languages.hyphenation.define(tag) + languages.hyphenation.loadpatterns(tag,l.patterns) + languages.hyphenation.loadexceptions(tag,l.exceptions) + numbers[l.number] = tag + end + l.loaded = true + if trace_patterns then + logs.report("languages","assigning number %s",l.number) + end + end + if l.number > 0 then + return l.number + end + end + end + return 0 +end + +-- e['implementer']= 'imple{m}{-}{-}menter' +-- e['manual'] = 'man{}{}{}' +-- e['as'] = 'a-s' +-- e['user-friendly'] = 'user=friend-ly' +-- e['exceptionally-friendly'] = 'excep-tionally=friend-ly' + +function languages.hyphenation.loadwords(tag, filename) + local id = languages.hyphenation.number(tag) + if id > 0 then + local l = lang.new(id) or 0 + statistics.starttiming(languages) + local data = io.loaddata(filename) or "" + l:hyphenation(data) + statistics.stoptiming(languages) + end +end + +languages.hyphenation.define ("zerolanguage") +languages.hyphenation.loadpatterns ("zerolanguage") -- else bug +languages.hyphenation.loadexceptions("zerolanguage") -- else bug + +languages.logger = languages.logger or { } + +function languages.logger.report() + local result = { } + local sorted = table.sortedkeys(registered) + for i=1,#sorted do + local tag = sorted[i] + local l = registered[tag] + if l.loaded then + local p = (l.patterns and "pat") or '-' + local e = (l.exceptions and "exc") or '-' + result[#result+1] = format("%s:%s:%s:%s:%s", tag, l.parent, p, e, l.number) + end + end + return (#result > 0 and concat(result," ")) or "none" +end + +-- must happen at the tex end + +languages.associate('en','latn','eng') +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() + return statistics.elapsedseconds(languages, format(", n=%s",languages.hyphenation.n())) +end) diff --git a/tex/context/base/lang-ini.mkii b/tex/context/base/lang-ini.mkii new file mode 100644 index 000000000..91ac59847 --- /dev/null +++ b/tex/context/base/lang-ini.mkii @@ -0,0 +1,696 @@ +%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} + +\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->\specificlanguageparameter{#1}\s!lefthyphenmin:\specificlanguageparameter{#1}\s!righthyphenmin\space} + +\def\preloadlanguages + {\doifsomething\preloadedpmessage{\showmessage\m!linguals{10}\preloadedpmessage}} + +\def\preloadallpatterns + {\gdef\preloadallpatterns##1{\installlanguage[##1][\c!state=\v!start]}% + \processcommacommand[\installedlanguages]\preloadallpatterns + \global\let\preloadallpatterns\relax} + +% ^^ \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\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/\askedlanguageencoding]}% + \dorecurse\commalistsize + {\expanded{\getfromcommacommand[\askedlanguageencoding][\recurselevel]}% + \let\patternencoding\commalistelement + \expanded{\getfromcommacommand[\askedlanguagemapping][\recurselevel]}% + \let\patternmapping \commalistelement + %\message{[patterns: #1/#2/\patternencoding/\patternmapping]}% + \dodoloadpatterns{#1}{#2}\patternencoding\patternmapping}% + \else + %\message{[patterns: #1/#2]}% + \dodoloadpatterns{#1}{#2}{}{}% + \fi} + +\ifnum\texengine=\xetexengine + + \def\doloadpatterns#1#2% + {%\letvalue{\??la#2\s!encoding}\empty + %\letvalue{\??la#2\s!mapping }\empty + \dodoloadpatterns{#1}{#2}{}{}} + +\fi + +\def\setuphyppatencoding + {\pathypsettings + \enableregime[utf]} + +\def\dodoloadpatterns#1#2#3#4% beware, loaded language also incr + {\normallanguage\loadedlanguage % when not really needed + \bgroup + \let\synchronizepatterns\relax % needed? + \let\enabledmapping \empty % needed? + \doifelsenothing{#3}{\enableencoding[\s!default]}{\enableencoding[#3]}% + \doifelsenothing{#4}{\enablemapping [\s!default]}{\enablemapping [#4]}% + \setuphyppatencoding + \ifundefined{\??la\??la:\currentencoding:\currentmapping:#2}% + \let\doshowpatterns\relax + \edef\alreadyloadedlanguage + {\executeifdefined{\??la\??la:\currentencoding:\currentmapping:\truefilename{\f!languageprefix#2.\f!patternsextension}}\empty}% + \edef\alreadyloadedlanguage + {\executeifdefined{\??la\??la:\currentencoding:\currentmapping:\f!languageprefix#2.\f!patternsextension}\alreadyloadedlanguage}% + \ifx\alreadyloadedlanguage\empty + \letgvalue{\??la\??la:\currentencoding:\currentmapping:#2}\loadedlanguage + \doifundefined{\??la\??la:\s!default:\s!default:#2}{\letgvalue{\??la\??la:\s!default:\s!default:#2}\loadedlanguage}% fall back + \startpatternloading{\truefilename{\f!languageprefix#2.\f!patternsextension}}{#3}{#4}% + \readsysfile{\truefilename{\f!languageprefix#2.\f!patternsextension}} + {\setxvalue{\??la#1\s!patterns}{#2}% + \setxvalue{\??la\??la:\currentencoding:\currentmapping:\truefilename{\f!languageprefix#2.\f!patternsextension}}{\number\loadedlanguage}% + \xdef\preloadedpmessage{\preloadedpmessage\doshowpatterns{#2}{\number\normallanguage}{\currentencoding}{\currentmapping}}% + \doglobal\addtocommalist{#2}\preloadedpatterns + \showmessage\m!linguals1{#2,#1,\loadedlanguage,\currentencoding,\currentmapping}} + {\showmessage\m!linguals2{#2,#1,\loadedlanguage,\currentencoding,\currentmapping,\f!languageprefix#2.\f!patternsextension,\truefilename{\f!languageprefix#2.\f!patternsextension}}}% + \stoppatternloading + \startpatternloading{\truefilename{\f!languageprefix#2.\f!hyphensextension}}{#3}{#4}% + \readsysfile{\truefilename{\f!languageprefix#2.\f!hyphensextension}} + {\showmessage\m!linguals3{#2,#1,\loadedlanguage,\currentencoding,\currentmapping}} + {\showmessage\m!linguals4{#2,#1,\loadedlanguage,\currentencoding,\currentmapping}}% + \stoppatternloading + \doglobal\increment\loadedlanguage + % \stopencoding + \else % optimization, introduced 2004.08.24, while sorting out changes in tl + \letgvalue{\??la\??la:\currentencoding:\currentmapping:#2}\alreadyloadedlanguage + \doifundefined{\??la\??la:\s!default:\s!default:#2}{\letgvalue{\??la\??la:\s!default:\s!default:#2}\loadedlanguage}% fall back + \setxvalue{\??la#1\s!patterns}{#2}% + \xdef\preloadedpmessage{\preloadedpmessage\doshowpatterns{#2}{[\number\alreadyloadedlanguage]}{\currentencoding}{\currentmapping}}% + \doglobal\addtocommalist{#2}\preloadedpatterns + \showmessage\m!linguals1{#2,#1,[\alreadyloadedlanguage],\currentencoding,\currentmapping}% + \fi + \fi + \egroup} + +\fetchruntimecommand \showpatterns {\f!languageprefix\s!run.mkii} + +%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). + +\appendtoks + \gdef\doloadpatterns{\doglobal\increment\loadedlanguage\gobbletwoarguments}% + \globallet\dodoloadpatterns\gobblefourarguments +\to \everydump + +%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, + \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=] + +%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: + \ifnum\normallanguage<\zerocount + % we've blocked hyphenation (e.g. verbatim) + \else + \edef\synchronizepatterns{\noexpand\dosetnormallanguage{\languageparameter\s!patterns}}% + \donefalse + \synchronizepatterns + \ifdone\else + \def\synchronizepatterns{\dosetnormallanguage\currentlanguage}% + \synchronizepatterns + \ifdone\else + \ifx\currentdefaultlanguage\empty\else + \edef\synchronizepatterns{\noexpand\dosetnormallanguage{\specificlanguageparameter\currentdefaultlanguage\s!patterns}}% + \synchronizepatterns + \ifdone\else + \dosetnormallanguage\currentdefaultlanguage + \synchronizepatterns + \fi + \fi + \fi + \fi + \fi} + +\normallanguage\zerocount + +\def\dosetnormallanguage#1% #1 == \cs (no longer) + {\ifnum\normallanguage<\zerocount + % we've blocked hyphenation (e.g. verbatim) + \else + \dodosetnormallanguage{:\currentencoding:\currentmapping:}{#1}{% + \dodosetnormallanguage{:\currentencoding:\s!default :}{#1}{% + \dodosetnormallanguage{:\s!default :\currentmapping:}{#1}{% + \dodosetnormallanguage{:\s!default :\s!default :}{#1}\empty}}}% + \fi} + +\def\dodosetnormallanguage#1#2% + {\ifcsname\??la\??la#1#2\endcsname + \edef\thenormallanguage{\csname\??la\??la#1#2\endcsname}% can be \chardef + \ifx\thenormallanguage\empty + \@EAEAEA\firstofoneargument + \else + \donetrue + \@EA\xdef\csname\??la\currentlanguage\s!patterns\endcsname{#2}% + \normallanguage\thenormallanguage\relax % \relax is needed for lookahead problems + \@EAEAEA\gobbleoneargument + \fi + \else + \@EA\firstofoneargument + \fi} + +\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\dosetnormallanguage #1{\dodosetnormallanguage{:\s!default:\s!default:}{#1}\empty} + \def\setuphyppatencoding {\pathypsettings} + +\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 new file mode 100644 index 000000000..45bb71b85 --- /dev/null +++ b/tex/context/base/lang-ini.mkiv @@ -0,0 +1,560 @@ +%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} + +\registerctxluafile{lang-ini}{1.001} + +\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 + +\unexpanded\def\setupcurrentlanguage[#1]{\setcurrentlanguage\currentmainlanguage{#1}} + +\def\setcurrentlanguage#1#2% sets modes: **id (currentmain) *id (current) + {\edef\xaskedlanguage{#1}% otherwise clash with \askedlanguage + \ifx\xaskedlanguage\empty \else + \ifx\currentmainlanguage\empty\else\resetsystemmode{\systemmodeprefix\currentmainlanguage}\fi + \let\currentmainlanguage\xaskedlanguage + \setsystemmode{\systemmodeprefix\currentmainlanguage}% + \fi + \edef\xaskedlanguage{#2}% + \ifx\xaskedlanguage\empty \else + \ifx\currentlanguage\empty\else\resetsystemmode\currentlanguage\fi + \let\currentlanguage\xaskedlanguage + \setsystemmode\currentlanguage + \fi} + +%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 + {\expanded{\noexpand\uppercase{\noexpand\edef\noexpand\ascii{#1}}}% + \ifcsname #1\endcsname\else\setvalue {#1}{\complexlanguage[#2]}\fi + \ifcsname\ascii\endcsname\else\setvalue\ascii{\complexlanguage[#2]}\fi} + +%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\doloadpatterns#1#2% + {\ctxlua{languages.register( + "#1", + "#2", + "\truefilename{\f!languageprefix#2.\f!patternsextension}", + "\truefilename{\f!languageprefix#2.\f!hyphensextension }") + }} + +\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"))}} + +%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. + +\unexpanded\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, + \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!rightcompoundhyphen=\compoundhyphen, + \c!leftcompoundhyphen=] + +%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","#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\sethyphenationvariables % as we can have cloning we need to set it each time, unless we move all to lua + {\ctxlua{languages.setup(tex.language, { + lefthyphen = "\languageparameter\c!lefthyphen", + righthyphen = "\languageparameter\c!righthyphen", + } )}% + \lefthyphenmin \numexpr0\languageparameter\s!lefthyphenmin +\hyphenminoffset\relax + \righthyphenmin\numexpr0\languageparameter\s!righthyphenmin+\hyphenminoffset\relax} + +\def\docomplexlanguage% assumes that \currentlanguage is set + {\edef\currentdefaultlanguage{\defaultlanguage\currentlanguage}% + \setnormallanguage\currentlanguage\currentdefaultlanguage + \the\everylanguage + \sethyphenationvariables + \relax + % will be definable and move to core-spa ! + \doifelse{\languageparameter\c!spacing}\v!broad\nonfrenchspacing\frenchspacing} + +% \mainlanguage[nl] \setuplanguage[nl][lefthyphen=,righthyphen=?] +% +% \dorecurse{100}{dit is toch wel een heel\normalhyphendiscretionary lang\normalhyphendiscretionary woord \recurselevel\ } +% \dorecurse{100}{dit is toch wel een heellangwoord \recurselevel\ } + +% The following may be a solution for the fact that one cannot +% change catcodes of characters like : and ; inside an environment. + +\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 + +\uchyph=1 + +\exhyphenchar=45 % to permit breaking at explicit hyphens + +\protect \endinput diff --git a/tex/context/base/lang-ita.tex b/tex/context/base/lang-ita.tex new file mode 100644 index 000000000..03efb0614 --- /dev/null +++ b/tex/context/base/lang-ita.tex @@ -0,0 +1,518 @@ +%D \module +%D [ file=lang-ita, +%D version=1997.09.03, +%D title=\CONTEXT\ Language Macros, +%D subtitle=Italic Languages, +%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. + +% Todo: replace \'.. by \namedglyph + +\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 +%D on, corrections were made by users. If you have suggestions, +%D or feel that your name missing here, don't hesitate to send +%D us an email. +%D +%D \starttabulate[|lB|l|] +%D \NC Italian \NC Giuseppe Bilotta \NC \NR +%D \NC Romanian \NC Dan Seracu \NC \NR +%D \NC Portuguese \NC Pedro F. M. Mendon\c a \NC \NR +%D \stoptabulate + +% Latin, Italian, Rhaeto-Romanic, Rumanian, Sardian +% Catalan, French, Ladino, Portuguese, Proven\c{c}al, Spanish + +\unprotect + +\ifx\guillemotspace\undefined \let\guillemotspace\empty \fi +\ifx\sentencespace \undefined \let\sentencespace \empty \fi + +\installlanguage + [\s!fr] + [\c!spacing=\v!packed, + \c!leftsentence=\emdash, + \c!rightsentence=\emdash, + \c!leftsubsentence=\emdash, + \c!rightsubsentence=\emdash, + \c!leftquote=\leftguillemot, + \c!rightquote=\rightguillemot, + \c!leftquotation=\leftguillemot, + \c!rightquotation=\rightguillemot, + \c!date={\v!day+,\v!space,\v!month,\v!space,\v!year}, + \s!mapping={texnansi,ec}, + \s!encoding={texnansi,ec}] + +\installlanguage + [\s!es] + [\c!spacing=\v!packed, + \c!leftsentence=---, + \c!rightsentence=---, + \c!leftsubsentence=---, + \c!rightsubsentence=---, + \c!leftquote=\upperleftsinglesixquote, + \c!rightquote=\upperrightsingleninequote, + \c!leftquotation=\upperleftdoublesixquote, + \c!rightquotation=\upperrightdoubleninequote, + \c!date={\v!day,\ ,\v!month,\ ,\v!year}] + +\installlanguage [sp] [\s!es] % old times context + +\installlanguage + [\s!ca] + [\c!spacing=\v!packed, + \c!leftsentence=---, + \c!rightsentence=---, + \c!leftsubsentence=---, + \c!rightsubsentence=---, + \c!leftquote=\upperleftsinglesixquote, + \c!rightquote=\upperrightsingleninequote, + \c!leftquotation=\upperleftdoublesixquote, + \c!rightquotation=\upperrightdoubleninequote, + \c!date={\v!day,\ ,\v!month,\ ,\v!year}] + +% Note GB left|/|right (sub)sentences are for \quote {incisi}. + +\installlanguage + [\s!it] + [\c!spacing=\v!packed, + \c!leftsentence=---, + \c!rightsentence=---, + \c!leftsubsentence=--, + \c!rightsubsentence=--, + \c!leftquote=\upperleftsinglesixquote, + \c!rightquote=\upperrightsingleninequote, + \c!leftquotation=\upperleftdoublesixquote, + \c!rightquotation=\upperrightdoubleninequote, + \c!leftspeech=\leftguillemot, + \c!middlespeech=\leftguillemot, + \c!rightspeech=\rightguillemot, + \c!date={\v!day,\ ,\v!month,\ ,\v!year}, + \s!mapping={texnansi,ec}, + \s!encoding={texnansi,ec}] + +\installlanguage % the same as italian + [\s!la] + [\c!spacing=\v!packed, + \c!leftsentence=---, + \c!rightsentence=---, + \c!leftsubsentence=---, + \c!rightsubsentence=---, + \c!leftquote=\upperleftsinglesixquote, + \c!rightquote=\lowerrightsingleninequote, + \c!leftquotation=\upperleftdoublesixquote, + \c!rightquotation=\lowerrightdoubleninequote, + \c!date={\v!day,\ ,\v!month,\ ,\v!year}] + +\installlanguage + [\s!pt] + [\c!spacing=\v!packed, + \c!leftsentence=---, + \c!rightsentence=---, + \c!leftsubsentence=---, + \c!rightsubsentence=---, + \c!leftquote=\upperleftsinglesixquote, + \c!rightquote=\upperrightsingleninequote, + \c!leftquotation=\upperleftdoublesixquote, + \c!rightquotation=\upperrightdoubleninequote, + \c!date={\v!year,\ ,\v!month,\ ,\v!day}, + \s!mapping={texnansi,ec}, + \s!encoding={texnansi,ec}] + +\installlanguage + [\s!ro] + [\c!spacing=\v!packed, + \c!leftsentence=---, + \c!rightsentence=---, + \c!leftsubsentence=---, + \c!rightsubsentence=---, + \c!leftquote=\leftguillemot, + \c!rightquote=\rightguillemot, + \c!leftquotation=\lowerrightdoubleninequote, + \c!rightquotation=\upperleftdoublesixquote, + \c!date={\v!day,\ ,\v!month,\ ,\v!year}] + +%D For compatibility reasons we also define: + +\installlanguage [fa] [\s!fr] % for dutchies only + +\installlanguage [french] [\s!fr] +\installlanguage [spanish] [\s!es] +\installlanguage [catalan] [\s!ca] +\installlanguage [italian] [\s!it] +\installlanguage [latin] [\s!la] +\installlanguage [portuguese] [\s!pt] +\installlanguage [romanian] [\s!ro] + +%D Labels and header texts. + +\setupheadtext [\s!fr] [\v!content=Table des mati\`eres] +\setupheadtext [\s!es] [\v!content=\'Indice] +\setupheadtext [\s!ca] [\v!content=\'Index de continguts] +\setupheadtext [\s!it] [\v!content=Indice] +\setupheadtext [\s!la] [\v!content=Quod in libro continetur] %Argumentum +\setupheadtext [\s!pt] [\v!content=Conte\'udo] +\setupheadtext [\s!ro] [\v!content=Cuprins] + +\setupheadtext [\s!fr] [\v!tables=Tableaux] +\setupheadtext [\s!es] [\v!tables=Tablas] +\setupheadtext [\s!ca] [\v!tables=Taules] +\setupheadtext [\s!it] [\v!tables=Tabelle] +\setupheadtext [\s!la] [\v!tables=Tabulae] +\setupheadtext [\s!pt] [\v!tables=Tabelas] +\setupheadtext [\s!ro] [\v!tables=Tabele] + +\setupheadtext [\s!fr] [\v!figures=Figures] +\setupheadtext [\s!es] [\v!figures=Ilustraciones] +\setupheadtext [\s!ca] [\v!figures=Figures] +\setupheadtext [\s!it] [\v!figures=Figure] +\setupheadtext [\s!la] [\v!figures=Imagines] +\setupheadtext [\s!pt] [\v!figures=Figuras] +\setupheadtext [\s!ro] [\v!figures=Figuri] + +\setupheadtext [\s!fr] [\v!graphics=Graphiques] +\setupheadtext [\s!es] [\v!graphics=Gr\'aficos] +\setupheadtext [\s!it] [\v!graphics=Grafici] +\setupheadtext [\s!ca] [\v!graphics=Gr\`afiques] +\setupheadtext [\s!la] [\v!graphics=Typi] +\setupheadtext [\s!pt] [\v!graphics=Gr\'aficos] +\setupheadtext [\s!ro] [\v!graphics=Grafice] + +\setupheadtext [\s!fr] [\v!intermezzi=Interm\`edes] +\setupheadtext [\s!es] [\v!intermezzi=Intermedios] +\setupheadtext [\s!ca] [\v!intermezzi=Intermedis] +\setupheadtext [\s!it] [\v!intermezzi=Intermezzi] +\setupheadtext [\s!la] [\v!intermezzi=Intermissa] +\setupheadtext [\s!pt] [\v!intermezzi=Interm\'edios] +\setupheadtext [\s!ro] [\v!intermezzi=Intermzzo] + +\setupheadtext [\s!fr] [\v!index=Index] +\setupheadtext [\s!es] [\v!index=\'Indice alfab\'etico] +\setupheadtext [\s!ca] [\v!index=\'Index alfab\`etic] +\setupheadtext [\s!it] [\v!index=Indice] +\setupheadtext [\s!la] [\v!index=Indices] +\setupheadtext [\s!pt] [\v!index=\'Indice] +\setupheadtext [\s!ro] [\v!index=Index] + +\setupheadtext [\s!fr] [\v!abbreviations=Abr\'eviations] +\setupheadtext [\s!es] [\v!abbreviations=Abreviaturas] +\setupheadtext [\s!ca] [\v!abbreviations=Abreviacions] +\setupheadtext [\s!it] [\v!abbreviations=Abbreviazioni] +\setupheadtext [\s!la] [\v!abbreviations=Notae] +\setupheadtext [\s!pt] [\v!abbreviations=Abreviaturas] +\setupheadtext [\s!ro] [\v!abbreviations=Abrevieri] + +\setupheadtext [\s!fr] [\v!logos=Logos] +\setupheadtext [\s!es] [\v!logos=Logotipos] +\setupheadtext [\s!ca] [\v!logos=Logotips] +\setupheadtext [\s!it] [\v!logos=Logotipi] +\setupheadtext [\s!la] [\v!logos=Typi negotiales] +\setupheadtext [\s!pt] [\v!logos=Logotipos] +\setupheadtext [\s!ro] [\v!logos=Logo-uri] + +\setupheadtext [\s!fr] [\v!units=Unit\'es] +\setupheadtext [\s!es] [\v!units=Unidades] +\setupheadtext [\s!ca] [\v!units=Unitats] +\setupheadtext [\s!it] [\v!units=Unit\`a] +\setupheadtext [\s!la] [\v!units=Modi] +\setupheadtext [\s!pt] [\v!units=Unidades] +\setupheadtext [\s!ro] [\v!units=Unit\u{a}\c{t}i] + +\setupheadtext [\s!fr] [pubs=Bibliographie] +\setupheadtext [\s!es] [pubs=Bibliograf\'\ia] +\setupheadtext [\s!ca] [pubs=Referències] +\setupheadtext [\s!it] [pubs=Bibliografia] +%setupheadtext [\s!la] [pubs=?] +%setupheadtext [\s!pt] [pubs=?] +%setupheadtext [\s!ro] [pubs=?] + +\setuplabeltext [\s!fr] [\v!table=Tableau ] +\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 ] +\setuplabeltext [\s!ro] [\v!table=Tabelul ] + +\setuplabeltext [\s!fr] [\v!figure=Figure ] +\setuplabeltext [\s!es] [\v!figure=Ilustraci\'on ] +\setuplabeltext [\s!ca] [\v!figure=Figura ] +\setuplabeltext [\s!it] [\v!figure=Fig. ] +\setuplabeltext [\s!la] [\v!figure=Imago ] +\setuplabeltext [\s!pt] [\v!figure=Figura ] +\setuplabeltext [\s!ro] [\v!figure=Figura ] + +\setuplabeltext [\s!fr] [\v!intermezzo=Interm\`ede ] +\setuplabeltext [\s!es] [\v!intermezzo=Intermedio ] +\setuplabeltext [\s!ca] [\v!intermezzo=Intermedi ] +\setuplabeltext [\s!it] [\v!intermezzo=Intermezzo ] +\setuplabeltext [\s!la] [\v!intermezzo=Intermissum ] +\setuplabeltext [\s!pt] [\v!intermezzo=Interm\'edio ] +\setuplabeltext [\s!ro] [\v!intermezzo=Intermezzo ] + +\setuplabeltext [\s!fr] [\v!graphic=Illustration ] +\setuplabeltext [\s!es] [\v!graphic=Gr\'afico ] +\setuplabeltext [\s!ca] [\v!graphic=Gr\`afica ] +\setuplabeltext [\s!it] [\v!graphic=Grafico ] +\setuplabeltext [\s!la] [\v!graphic=Typus ] +\setuplabeltext [\s!pt] [\v!graphic=Gr\'afico ] +\setuplabeltext [\s!ro] [\v!graphic=Graficul ] + +\setuplabeltext [\s!fr] [\v!chapter=] % Chapitre +\setuplabeltext [\s!es] [\v!chapter=] % Cap\'\i tulo +\setuplabeltext [\s!ca] [\v!chapter=] % Cap\'\i tol +\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=] % 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=] % Soussection +\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=] % Soussoussection +\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=] % Soussoussoussection +\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=] % Annexe +\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=] +\setuplabeltext [\s!ro] [\v!appendix=] + +\setuplabeltext [\s!fr] [\v!part=Partie ] +\setuplabeltext [\s!es] [\v!part=Parte ] +\setuplabeltext [\s!ca] [\v!part=Part ] +\setuplabeltext [\s!it] [\v!part=Parte ] +\setuplabeltext [\s!la] [\v!part=Pars ] +\setuplabeltext [\s!pt] [\v!part=Parte ] +\setuplabeltext [\s!ro] [\v!part=Partea ] + +\setuplabeltext [\s!fr] [\v!line=ligne ] +\setuplabeltext [\s!es] [\v!line=l\'\i nea ] +\setuplabeltext [\s!ca] [\v!line=l\'\i nia ] +\setuplabeltext [\s!it] [\v!line=riga ] +\setuplabeltext [\s!la] [\v!line=versus ] +\setuplabeltext [\s!pt] [\v!line=linha ] +\setuplabeltext [\s!ro] [\v!line=linia ] + +\setuplabeltext [\s!fr] [\v!lines=lignes ] +\setuplabeltext [\s!es] [\v!lines=l\'\i neas ] +\setuplabeltext [\s!ca] [\v!lines=l\'\i nies ] +\setuplabeltext [\s!it] [\v!lines=righe ] +\setuplabeltext [\s!la] [\v!lines=versus ] +\setuplabeltext [\s!pt] [\v!lines=linhas ] +\setuplabeltext [\s!ro] [\v!lines=liniile ] + +\setuplabeltext [\s!fr] [\v!january=janvier] +\setuplabeltext [\s!fr] [\v!february=f\'evrier] +\setuplabeltext [\s!fr] [\v!march=mars] +\setuplabeltext [\s!fr] [\v!april=avril] +\setuplabeltext [\s!fr] [\v!may=mai] +\setuplabeltext [\s!fr] [\v!june=juin] +\setuplabeltext [\s!fr] [\v!july=juillet] +\setuplabeltext [\s!fr] [\v!august=ao\^ut] +\setuplabeltext [\s!fr] [\v!september=septembre] +\setuplabeltext [\s!fr] [\v!october=octobre] +\setuplabeltext [\s!fr] [\v!november=novembre] +\setuplabeltext [\s!fr] [\v!december=d\'ecembre] + +\setuplabeltext [\s!es] [\v!january=enero] +\setuplabeltext [\s!es] [\v!february=febrero] +\setuplabeltext [\s!es] [\v!march=marzo] +\setuplabeltext [\s!es] [\v!april=abril] +\setuplabeltext [\s!es] [\v!may=mayo] +\setuplabeltext [\s!es] [\v!june=junio] +\setuplabeltext [\s!es] [\v!july=julio] +\setuplabeltext [\s!es] [\v!august=agosto] +\setuplabeltext [\s!es] [\v!september=septiembre] +\setuplabeltext [\s!es] [\v!october=octubre] +\setuplabeltext [\s!es] [\v!november=noviembre] +\setuplabeltext [\s!es] [\v!december=diciembre] + +\setuplabeltext [\s!ca] [\v!january=gener] +\setuplabeltext [\s!ca] [\v!february=febrer] +\setuplabeltext [\s!ca] [\v!march=mar\c{c}] +\setuplabeltext [\s!ca] [\v!april=abril] +\setuplabeltext [\s!ca] [\v!may=maig] +\setuplabeltext [\s!ca] [\v!june=juny] +\setuplabeltext [\s!ca] [\v!july=juliol] +\setuplabeltext [\s!ca] [\v!august=agost] +\setuplabeltext [\s!ca] [\v!september=setembre] +\setuplabeltext [\s!ca] [\v!october=octubre] +\setuplabeltext [\s!ca] [\v!november=novembre] +\setuplabeltext [\s!ca] [\v!december=desembre] + +\setuplabeltext [\s!it] [\v!january=gennaio] +\setuplabeltext [\s!it] [\v!february=febbraio] +\setuplabeltext [\s!it] [\v!march=marzo] +\setuplabeltext [\s!it] [\v!april=aprile] +\setuplabeltext [\s!it] [\v!may=maggio] +\setuplabeltext [\s!it] [\v!june=giugno] +\setuplabeltext [\s!it] [\v!july=luglio] +\setuplabeltext [\s!it] [\v!august=agosto] +\setuplabeltext [\s!it] [\v!september=settembre] +\setuplabeltext [\s!it] [\v!october=ottobre] +\setuplabeltext [\s!it] [\v!november=novembre] +\setuplabeltext [\s!it] [\v!december=dicembre] + +\setuplabeltext [\s!la] [\v!january=Ianuarius] +\setuplabeltext [\s!la] [\v!february=Februarius] +\setuplabeltext [\s!la] [\v!march=Martius] +\setuplabeltext [\s!la] [\v!april=Aprilis] +\setuplabeltext [\s!la] [\v!may=Maius] +\setuplabeltext [\s!la] [\v!june=Iunius] +\setuplabeltext [\s!la] [\v!july=Iulius] % formerly Quintilis +\setuplabeltext [\s!la] [\v!august=Augustus] % formerly Sextilis +\setuplabeltext [\s!la] [\v!september=September] +\setuplabeltext [\s!la] [\v!october=October] +\setuplabeltext [\s!la] [\v!november=November] +\setuplabeltext [\s!la] [\v!december=December] + +\setuplabeltext [\s!pt] [\v!january=janeiro] +\setuplabeltext [\s!pt] [\v!february=fevereiro] +\setuplabeltext [\s!pt] [\v!march=mar\c{c}o] +\setuplabeltext [\s!pt] [\v!april=abril] +\setuplabeltext [\s!pt] [\v!may=maio] +\setuplabeltext [\s!pt] [\v!june=junho] +\setuplabeltext [\s!pt] [\v!july=julho] +\setuplabeltext [\s!pt] [\v!august=agosto] +\setuplabeltext [\s!pt] [\v!september=setembro] +\setuplabeltext [\s!pt] [\v!october=outubro] +\setuplabeltext [\s!pt] [\v!november=novembro] +\setuplabeltext [\s!pt] [\v!december=dezembro] + +\setuplabeltext [\s!ro] [\v!january=ianuarie] +\setuplabeltext [\s!ro] [\v!february=februarie] +\setuplabeltext [\s!ro] [\v!march=martie] +\setuplabeltext [\s!ro] [\v!april=aprilie] +\setuplabeltext [\s!ro] [\v!may=mai] +\setuplabeltext [\s!ro] [\v!june=iunie] +\setuplabeltext [\s!ro] [\v!july=iulie] +\setuplabeltext [\s!ro] [\v!august=august] +\setuplabeltext [\s!ro] [\v!september=septembrie] +\setuplabeltext [\s!ro] [\v!october=octombrie] +\setuplabeltext [\s!ro] [\v!november=noiembrie] +\setuplabeltext [\s!ro] [\v!december=decembrie] + +\setuplabeltext [\s!fr] [\v!sunday=dimanche] +\setuplabeltext [\s!fr] [\v!monday=lundi] +\setuplabeltext [\s!fr] [\v!tuesday=mardi] +\setuplabeltext [\s!fr] [\v!wednesday=mercredi] +\setuplabeltext [\s!fr] [\v!thursday=jeudi] +\setuplabeltext [\s!fr] [\v!friday=vendredi] +\setuplabeltext [\s!fr] [\v!saturday=samedi] + +\setuplabeltext [\s!es] [\v!sunday=domingo] +\setuplabeltext [\s!es] [\v!monday=lunes] +\setuplabeltext [\s!es] [\v!tuesday=martes] +\setuplabeltext [\s!es] [\v!wednesday=mi\'ercoles] +\setuplabeltext [\s!es] [\v!thursday=jueves] +\setuplabeltext [\s!es] [\v!friday=viernes] +\setuplabeltext [\s!es] [\v!saturday=s\'abado] + +\setuplabeltext [\s!ca] [\v!sunday=diumenge] +\setuplabeltext [\s!ca] [\v!monday=dilluns] +\setuplabeltext [\s!ca] [\v!tuesday=dimarts] +\setuplabeltext [\s!ca] [\v!wednesday=dimecres] +\setuplabeltext [\s!ca] [\v!thursday=dijous] +\setuplabeltext [\s!ca] [\v!friday=divendres] +\setuplabeltext [\s!ca] [\v!saturday=dissabte] + +\setuplabeltext [\s!it] [\v!sunday=domenica] +\setuplabeltext [\s!it] [\v!monday=luned\`\i] +\setuplabeltext [\s!it] [\v!tuesday=marted\`\i] +\setuplabeltext [\s!it] [\v!wednesday=mercoled\`\i] +\setuplabeltext [\s!it] [\v!thursday=gioved\`\i] +\setuplabeltext [\s!it] [\v!friday=venerd\`\i] +\setuplabeltext [\s!it] [\v!saturday=sabato] + +\setuplabeltext [\s!la] [\v!sunday=Dies Solis] +\setuplabeltext [\s!la] [\v!monday=Dies Lunae] +\setuplabeltext [\s!la] [\v!tuesday=Dies Martis] +\setuplabeltext [\s!la] [\v!wednesday=Dies Mercuri] +\setuplabeltext [\s!la] [\v!thursday=Dies Iovis] +\setuplabeltext [\s!la] [\v!friday=Dies Veneris] +\setuplabeltext [\s!la] [\v!saturday=Dies Saturni] + +\setuplabeltext [\s!pt] [\v!sunday=domingo] +\setuplabeltext [\s!pt] [\v!monday=segunda-feira] +\setuplabeltext [\s!pt] [\v!tuesday=ter\c{c}a-feira] +\setuplabeltext [\s!pt] [\v!wednesday=quarta-feira] +\setuplabeltext [\s!pt] [\v!thursday=quinta-feira] +\setuplabeltext [\s!pt] [\v!friday=sexta-feira] +\setuplabeltext [\s!pt] [\v!saturday=s\'abado] + +\setuplabeltext [\s!ro] [\v!sunday=duminic\u{a}] +\setuplabeltext [\s!ro] [\v!monday=luni] +\setuplabeltext [\s!ro] [\v!tuesday=mar\c{t}i] +\setuplabeltext [\s!ro] [\v!wednesday=miercuri] +\setuplabeltext [\s!ro] [\v!thursday=joi] +\setuplabeltext [\s!ro] [\v!friday=vineri] +\setuplabeltext [\s!ro] [\v!saturday=s\^{a}mb\u{a}t\u{a}] + +%D Rather new \unknown + +\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!page=page ] +\setuplabeltext [\s!fr] [\v!atpage=à la page ] +\setuplabeltext [\s!fr] [\v!hencefore=ci-dessus] +\setuplabeltext [\s!fr] [\v!hereafter=ci-dessous] +\setuplabeltext [\s!fr] [\v!see=cf. ] + +%D Ordinal converters: + +\def\frordinaldaynumber#1% date is masculine + {\number#1\ifcase#1\or + \highordinalstr{er}% + \fi} + +\defineconversion [\s!fr] [\v!day+] [\frordinaldaynumber] + +%D \ShowAllLanguageValues [\s!fr] [french] {French} {kiss} % franse slag +%D \ShowAllLanguageValues [\s!es] [spanish] {Spanish} {guitar} % spaans benauwd +%D \ShowAllLanguageValues [\s!ca] [catalan] {Catalan} {cream} +%D \ShowAllLanguageValues [\s!it] [italian] {Italian} {aria} +%D \ShowAllLanguageValues [\s!la] [latin] {Latin} {lover} % latijnse missen +%D \ShowAllLanguageValues [\s!pt] [portuguese] {Portuguese} {fisherman} +%D \ShowAllLanguageValues [\s!ro] [romanian] {Romanian} {traveller} + +\protect \endinput diff --git a/tex/context/base/lang-jap.mkii b/tex/context/base/lang-jap.mkii new file mode 100644 index 000000000..05c9b1d41 --- /dev/null +++ b/tex/context/base/lang-jap.mkii @@ -0,0 +1,234 @@ +%D \module +%D [ file=lang-jap, +%D version=2006.01.13, +%D title=\CONTEXT\ Language Macros, +%D subtitle=Japanese, +%D author={Richard Gabriel}, +%D date=\currentdate, +%D copyright={PRAGMA / RG}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% rgabriel@kerio.com + +\writestatus{loading}{ConTeXt Language Macros / Japanese} + +\unprotect + +\definesystemconstant {japanese} \definesystemconstant {ja} + +\installlanguage + [\s!ja] + [\c!leftsentence=\jaencoding\jaleftsentence, + \c!rightsentence=\jaencoding\jarightsentence, + \c!leftsubsentence=\jaencoding\jaleftsubsentence, + \c!rightsubsentence=\jaencoding\jarightsubsentence, + \c!leftquote=\jaencoding\jaencodedsinglestartquote, + \c!rightquote=\jaencoding\jaencodedsingleendquote, + \c!leftquotation=\jaencoding\jaencodedstartquote, + \c!rightquotation=\jaencoding\jaencodedendquote, + \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}] +\setupheadtext [\s!ja] [\v!figures={\jaencoding\jaencodedfigures}] +\setupheadtext [\s!ja] [\v!graphics={\jaencoding\jaencodedgraphics}] +\setupheadtext [\s!ja] [\v!intermezzi={\jaencoding\jaencodedintermezzos}] +\setupheadtext [\s!ja] [\v!index={\jaencoding\jaencodedindex}] +\setupheadtext [\s!ja] [\v!abbreviations={\jaencoding\jaencodedabbreviations}] +\setupheadtext [\s!ja] [\v!logos={\jaencoding\jaencodedlogos}] +\setupheadtext [\s!ja] [\v!units={\jaencoding\jaencodedunits}] + +\setuplabeltext [\s!ja] [\v!table={\jaencoding\jaencodedtable}] +\setuplabeltext [\s!ja] [\v!figure={\jaencoding\jaencodedfigure}] +\setuplabeltext [\s!ja] [\v!intermezzo={\jaencoding\jaencodedintermezzo}] +\setuplabeltext [\s!ja] [\v!graphic={\jaencoding\jaencodedillustration}] +\setuplabeltext [\s!ja] [\v!appendix={\jaencoding\jaencodedappendix}] +\setuplabeltext [\s!ja] [\v!part={\jaencoding\jaencodedintro,\jaencoding\jaencodedpart}] +\setuplabeltext [\s!ja] [\v!chapter={\jaencoding\jaencodedintro,\jaencoding\jaencodedchapter}] +\setuplabeltext [\s!ja] [\v!section={\jaencoding\jaencodedintro,\jaencoding\jaencodedsection}] +\setuplabeltext [\s!ja] [\v!line={\jaencoding\jaencodedline}] +\setuplabeltext [\s!ja] [\v!lines={\jaencoding\jaencodedline}] + +\setuplabeltext [\s!ja] [\v!subsection=] +\setuplabeltext [\s!ja] [\v!subsubsection=] +\setuplabeltext [\s!ja] [\v!subsubsubsection=] + +%D Why are these languagespecifics ? + +\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=\jaencoding\jaencodedsunday ] +\setuplabeltext [\s!ja] [\v!monday=\jaencoding\jaencodedmonday ] +\setuplabeltext [\s!ja] [\v!tuesday=\jaencoding\jaencodedtuesday ] +\setuplabeltext [\s!ja] [\v!wednesday=\jaencoding\jaencodedwednesday] +\setuplabeltext [\s!ja] [\v!thursday=\jaencoding\jaencodedthursday ] +\setuplabeltext [\s!ja] [\v!friday=\jaencoding\jaencodedfriday ] +\setuplabeltext [\s!ja] [\v!saturday=\jaencoding\jaencodedsaturday ] + +% Hardcoded - \japaneseencoding should be defined similarly to \chineseencoding + +\unexpanded\def\jaencoding{\enableencoding[cjk-uni]} + +%D This list is taken from DocBook XSL stylesheets (http://docbook.sourceforge.net/). + +\startencoding[cjk-uni] + + \definecommand jaencodedabstract {\uchar{105}{130}\uchar{137}{129}} + \definecommand jaencodedand {\uchar{48}{1}} + \definecommand jaencodedanswer {\uchar{123}{84}\uchar{255}{26}} + \definecommand jaencodedappendix {\uchar{78}{216}\uchar{147}{50}} + \definecommand jaencodedarticle {\uchar{152}{5}\uchar{118}{238}} + \definecommand jaencodedbibliography {\uchar{83}{194}\uchar{128}{3}\uchar{101}{135}\uchar{115}{46}} + \definecommand jaencodedbook {\uchar{48}{214}\uchar{48}{195}\uchar{48}{175}} + \definecommand jaencodedbridgehead {\uchar{152}{5}} + \definecommand jaencodedbullet {\uchar{37}{207}} + \definecommand jaencodedby {\uchar{255}{26}} + \definecommand jaencodedcaution {\uchar{108}{232}\uchar{97}{15}} + \definecommand jaencodedcolophon {\uchar{89}{101}\uchar{78}{216}} + \definecommand jaencodedcopyright {\uchar{136}{253}\uchar{79}{92}\uchar{132}{87}\uchar{79}{92}} + \definecommand jaencodeddedication {\uchar{139}{29}\uchar{143}{158}} + \definecommand jaencodededited {\uchar{125}{232}\uchar{128}{5}} + \definecommand jaencodededitedby {\uchar{125}{232}\uchar{128}{5}\uchar{255}{26}} + \definecommand jaencodededition {\uchar{125}{232}\uchar{150}{198}} + \definecommand jaencodedendquote {\uchar{48}{13}} + \definecommand jaencodedequation {\uchar{95}{15}} + \definecommand jaencodedexample {\uchar{79}{139}} + \definecommand jaencodedfigure {\uchar{86}{243}} + \definecommand jaencodedglossary {\uchar{117}{40}\uchar{138}{158}\uchar{150}{198}} + \definecommand jaencodedglosssee {\uchar{83}{194}\uchar{113}{103}} + \definecommand jaencodedglossseealso {\uchar{83}{194}\uchar{113}{103}} + \definecommand jaencodedchapter {\uchar{122}{224}} + \definecommand jaencodedimportant {\uchar{145}{205}\uchar{137}{129}\uchar{152}{5}\uchar{118}{238}} + \definecommand jaencodedindex {\uchar{118}{238}\uchar{107}{33}} + \definecommand jaencodedindexsymbols {\uchar{48}{183}\uchar{48}{243}\uchar{48}{220}\uchar{48}{235}} + \definecommand jaencodedintro {\uchar{123}{44}} + \definecommand jaencodedlistofequations {\uchar{95}{15}\uchar{118}{238}\uchar{107}{33}} + \definecommand jaencodedlistofexamples {\uchar{79}{139}\uchar{118}{238}\uchar{107}{33}} + \definecommand jaencodedlistoffigures {\uchar{86}{243}\uchar{118}{238}\uchar{107}{33}} + \definecommand jaencodedlistoftables {\uchar{136}{104}\uchar{118}{238}\uchar{107}{33}} + \definecommand jaencodedlistofunknown {\uchar{78}{13}\uchar{102}{14}\uchar{118}{238}\uchar{107}{33}} + \definecommand jaencodedmsgaud {\uchar{91}{254}\uchar{140}{97}\uchar{128}{5}} + \definecommand jaencodedmsglevel {\uchar{48}{236}\uchar{48}{217}\uchar{48}{235}} + \definecommand jaencodedmsgorig {\uchar{118}{122}\uchar{79}{225}\uchar{81}{67}} + \definecommand jaencodednavhome {\uchar{48}{219}\uchar{48}{252}\uchar{48}{224}} + \definecommand jaencodednavnext {\uchar{107}{33}\uchar{48}{110}\uchar{48}{218}\uchar{48}{252}\uchar{48}{184}} + \definecommand jaencodednavnextsibling {\uchar{101}{233}\uchar{144}{1}\uchar{48}{138}} + \definecommand jaencodednavprev {\uchar{82}{77}\uchar{48}{110}\uchar{48}{218}\uchar{48}{252}\uchar{48}{184}} + \definecommand jaencodednavprevsibling {\uchar{93}{251}\uchar{98}{59}\uchar{48}{87}} + \definecommand jaencodednavup {\uchar{78}{10}\uchar{48}{107}\uchar{98}{59}\uchar{48}{139}} + \definecommand jaencodednestedendquote {\uchar{48}{15}} + \definecommand jaencodednestedstartquote {\uchar{48}{14}} + \definecommand jaencodednonexistantelement {\uchar{137}{129}\uchar{125}{32}\uchar{48}{76}\uchar{91}{88}\uchar{87}{40}\uchar{48}{87}\uchar{48}{126}\uchar{48}{91}\uchar{48}{147}} + \definecommand jaencodednote {\uchar{108}{232}\uchar{97}{15}} + \definecommand jaencodednotes {\uchar{108}{232}\uchar{97}{15}} + \definecommand jaencodedpages {\uchar{80}{103}\uchar{115}{46}} + \definecommand jaencodedpart {\uchar{48}{209}\uchar{48}{252}\uchar{48}{200}} + \definecommand jaencodedpreface {\uchar{94}{143}\uchar{101}{135}} + \definecommand jaencodedprocedure {\uchar{98}{75}\uchar{152}{6}} + \definecommand jaencodedprocedureformal {\uchar{98}{75}\uchar{152}{6}} + \definecommand jaencodedproductionset {\uchar{48}{215}\uchar{48}{237}\uchar{48}{192}\uchar{48}{175}\uchar{48}{183}\uchar{48}{231}\uchar{48}{243}} + \definecommand jaencodedproductionsetformal {\uchar{48}{215}\uchar{48}{237}\uchar{48}{192}\uchar{48}{175}\uchar{48}{183}\uchar{48}{231}\uchar{48}{243}} + \definecommand jaencodedpublished {\uchar{118}{122}\uchar{136}{76}} + \definecommand jaencodedqandadiv {\uchar{85}{79}\uchar{255}{26}\uchar{48}{1}\uchar{123}{84}\uchar{255}{26}} + \definecommand jaencodedqandaentry {\uchar{85}{79}\uchar{255}{26}} + \definecommand jaencodedquestion {\uchar{85}{79}\uchar{255}{26}} + \definecommand jaencodedreference {\uchar{83}{194}\uchar{113}{103}} + \definecommand jaencodedrefname {\uchar{84}{13}\uchar{82}{77}} + \definecommand jaencodedrefsection {\uchar{152}{5}} + \definecommand jaencodedrefsynopsisdiv {\uchar{105}{130}\uchar{137}{129}} + \definecommand jaencodedrevhistory {\uchar{101}{57}\uchar{138}{2}\uchar{92}{101}\uchar{107}{116}} + \definecommand jaencodedrevision {\uchar{101}{57}\uchar{138}{2}} + \definecommand jaencodedsection {\uchar{152}{5}} + \definecommand jaencodedsee {\uchar{83}{194}\uchar{113}{103}} + \definecommand jaencodedseealso {\uchar{83}{194}\uchar{113}{103}} + \definecommand jaencodedseparator {\uchar{48}{1}} + \definecommand jaencodedset {\uchar{138}{45}\uchar{91}{154}} + \definecommand jaencodedsetindex {\uchar{118}{238}\uchar{107}{33}\uchar{138}{45}\uchar{91}{154}} + \definecommand jaencodedsidebar {\uchar{48}{181}\uchar{48}{164}\uchar{48}{201}\uchar{48}{208}\uchar{48}{252}} + \definecommand jaencodedsimplesect {\uchar{152}{5}} + \definecommand jaencodedsingleendquote {\uchar{32}{25}} + \definecommand jaencodedsinglestartquote {\uchar{32}{24}} + \definecommand jaencodedstartquote {\uchar{48}{12}} + \definecommand jaencodedstep {\uchar{48}{185}\uchar{48}{198}\uchar{48}{195}\uchar{48}{215}} + \definecommand jaencodedtable {\uchar{136}{104}} + \definecommand jaencodedtablenotes {\uchar{108}{232}\uchar{97}{15}} + \definecommand jaencodedtableofcontents {\uchar{118}{238}\uchar{107}{33}} + \definecommand jaencodedtip {\uchar{48}{198}\uchar{48}{163}\uchar{48}{195}\uchar{48}{215}} + \definecommand jaencodedunexpectedelementname {\uchar{78}{13}\uchar{102}{14}\uchar{48}{106}\uchar{137}{129}\uchar{125}{32}\uchar{84}{13}} + \definecommand jaencodedunsupported {\uchar{48}{181}\uchar{48}{221}\uchar{48}{252}\uchar{48}{200}\uchar{48}{87}\uchar{48}{126}\uchar{48}{91}\uchar{48}{147}} + \definecommand jaencodedwarning {\uchar{139}{102}\uchar{84}{74}} + + \definecommand jaencodedyear {\uchar{94}{116}} + \definecommand jaencodedmonth {\uchar{103}{8}} + \definecommand jaencodedday {\uchar{101}{229}} + +\stopencoding + +%D Taken from Chinese (will be investigated yet...) + +\startencoding[cjk-uni] + + \definecommand jaencodedleftsentence {\uchar{32}{20}\uchar{32}{20}} + \definecommand jaencodedrightsentence {\uchar{32}{20}\uchar{32}{20}} + \definecommand jaencodedleftsubsentence {\uchar{32}{20}\uchar{32}{20}} + \definecommand jaencodedrightsubsentence {\uchar{32}{20}\uchar{32}{20}} + +\stopencoding + +%D Special thanxx to Eizo Tsuchihashi (eizo@arcbrain.jp) for the following stuff + +\startencoding[cjk-uni] + + \definecommand jaencodedchristiandate {\uchar{137}{127}\uchar{102}{166}} + + \definecommand jaencodedtables {\uchar{103}{58}} + \definecommand jaencodedfigures {\uchar{86}{243}} + \definecommand jaencodedabbreviations {\uchar{117}{101}\uchar{138}{158}} + \definecommand jaencodedlogos {\uchar{116}{6}\uchar{96}{39}} + \definecommand jaencodedunits {\uchar{48}{230}\uchar{48}{203}\uchar{48}{195}\uchar{48}{196}} + + \definecommand jaencodedgraphics {\uchar{48}{176}\uchar{48}{233}\uchar{48}{213}} + \definecommand jaencodedintermezzo {\uchar{149}{147}\uchar{89}{79}\uchar{102}{242}} + \definecommand jaencodedintermezzos {\uchar{149}{147}\uchar{89}{79}\uchar{102}{242}} + \definecommand jaencodedillustration {\uchar{48}{164}\uchar{48}{233}\uchar{48}{185}\uchar{48}{200}} + \definecommand jaencodedline {\uchar{125}{218}} + \definecommand jaencodedlines {\uchar{125}{218}} + + \definecommand jaencodedjanuary {\uchar{78}{0}\uchar{103}{8}} + \definecommand jaencodedfebruary {\uchar{78}{140}\uchar{103}{8}} + \definecommand jaencodedmarch {\uchar{78}{9}\uchar{103}{8}} + \definecommand jaencodedapril {\uchar{86}{219}\uchar{103}{8}} + \definecommand jaencodedmay {\uchar{78}{148}\uchar{103}{8}} + \definecommand jaencodedjune {\uchar{81}{109}\uchar{103}{8}} + \definecommand jaencodedjuly {\uchar{78}{3}\uchar{103}{8}} + \definecommand jaencodedaugust {\uchar{81}{107}\uchar{103}{8}} + \definecommand jaencodedseptember {\uchar{78}{93}\uchar{103}{8}} + \definecommand jaencodedoctober {\uchar{83}{65}\uchar{103}{8}} + \definecommand jaencodednovember {\uchar{83}{65}\uchar{78}{0}\uchar{103}{8}} + \definecommand jaencodeddecember {\uchar{83}{65}\uchar{78}{140}\uchar{103}{8}} + + \definecommand jaencodedsunday {\uchar{103}{8}\uchar{102}{220}\uchar{101}{229}} + \definecommand jaencodedmonday {\uchar{112}{107}\uchar{102}{220}\uchar{101}{229}} + \definecommand jaencodedtuesday {\uchar{108}{52}\uchar{102}{220}\uchar{101}{229}} + \definecommand jaencodedwednesday {\uchar{103}{40}\uchar{102}{220}\uchar{101}{229}} + \definecommand jaencodedthursday {\uchar{145}{209}\uchar{102}{220}\uchar{101}{229}} + \definecommand jaencodedfriday {\uchar{87}{31}\uchar{102}{220}\uchar{101}{229}} + \definecommand jaencodedsaturday {\uchar{101}{229}\uchar{102}{220}\uchar{101}{229}} + +\stopencoding + +\protect \endinput 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..42f2db8ff --- /dev/null +++ b/tex/context/base/lang-lab.mkiv @@ -0,0 +1,283 @@ +%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 A regular \CONTEXT\ stores some 1500 labels at most. + +\let\handletextprefix\relax + +\newconditional\protecttextprefixes + +\let\currenttextprefixtag \s!unknown +\let\currenttextprefixclass\s!unknown + +\unexpanded\def\setupheadtext {\setfalse\protecttextprefixes\let\currenttextprefixclass\??mh\dodoubleempty\dosetupsometextprefix} +\unexpanded\def\setuplabeltext {\setfalse\protecttextprefixes\let\currenttextprefixclass\??ml\dodoubleempty\dosetupsometextprefix} +\unexpanded\def\setupmathlabeltext{\setfalse\protecttextprefixes\let\currenttextprefixclass\??mm\dodoubleempty\dosetupsometextprefix} + +\def\dosetupsometextprefix[#1][#2]% + {\ifsecondargument + \edef\currenttextprefixtag{\reallanguagetag{#1}}% + \processcommalist[#2]\dodosetupsometextprefix + \else + \edef\currenttextprefixtag{\reallanguagetag\currentmainlanguage}% + \processcommalist[#1]\dodosetupsometextprefix + \fi} + +\def\dodosetupsometextprefix#1% + {\dododosetupsometextprefix[#1]} + +\def\dododosetupsometextprefix[#1=#2]% + {\doassignsometextprefix{#1}[#2,,]} + +\def\doassignsometextprefix#1% + {\ifconditional\protecttextprefixes + \ifcsname\currenttextprefixclass\currenttextprefixtag#1\endcsname + \expandafter\expandafter\expandafter\doassignsometextprefixnop + \else + \expandafter\expandafter\expandafter\doassignsometextprefixyes + \fi + \else + \expandafter\doassignsometextprefixyes + \fi{#1}} + +\ifdefined\Word\else \let\Word\relax \fi + +% Checking saves some 8K in the compressed format and getting rid of the embedded +% \handletextprefix was good for another 6K. In the end the new solution is not +% even that inefficient. And the checking is done at format generation time anyway. + +\def\doassignsometextprefixyes#1[#2,#3,#4]% + {\edef\!!stringa{#2}% + \edef\!!stringb{#3}% + \ifx\!!stringb\empty + \ifx\!!stringa\empty + \expandafter\def\csname\currenttextprefixclass\currenttextprefixtag#1\endcsname{\empty\empty}% + \else + \expandafter\def\csname\currenttextprefixclass\currenttextprefixtag#1\endcsname{{#2}\empty}% + \fi + \else + \expandafter\def\csname\currenttextprefixclass\currenttextprefixtag#1\endcsname{{#2}{#3}}% + \fi} + +\def\doassignsometextprefixnop#1[#2]% + {} + +%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 {\reallanguagetag{\defaultlanguage\currentmainlanguage}} +\def\headlanguage {\reallanguagetag{\defaultlanguage\currentmainlanguage}} +\def\mathlabellanguage{\reallanguagetag{\defaultlanguage\currentmainlanguage}} + +\appendtoks \let\labellanguage\currentlanguage \to \everycurrentdate + +\def\dummytextprefix{\empty\empty} + +\def\dogetupsomelabeltext {\dodogetupsomelabeltext \labellanguage } % second argument is textlabel +\def\dogetupsomeheadtext {\dodogetupsomeheadtext \headlanguage } % second argument is headlabel +\def\dogetupsomemathlabeltext{\dodogetupsomemathlabeltext\mathlabellanguage } % second argument is headlabel + +\def\dodogetupsomelabeltext#1#2% + {\ifcsname\??ml#1#2\endcsname + \expandafter\let\expandafter\thetextprefix\csname\??ml#1#2\endcsname + \else\ifcsname\??la\labellanguage\s!default\endcsname + \expandafter\dodogetupsomelabeltext\csname\??la\labellanguage\s!default\endcsname{#2}% + \else\ifcsname\??ml#2\endcsname + \expandafter\let\expandafter\thetextprefix\csname\??ml#2\endcsname + \else\ifcsname\??ml\s!en#2\endcsname + \expandafter\let\expandafter\thetextprefix\csname\??ml\s!en#2\endcsname + \else + \let\thetextprefix\dummytextprefix + \fi\fi\fi\fi} + +\def\dodogetupsomeheadtext#1#2% + {\ifcsname\??mh#1#2\endcsname + \expandafter\let\expandafter\thetextprefix\csname\??mh#1#2\endcsname + \else\ifcsname\??la\headlanguage\s!default\endcsname + \expandafter\dodogetupsomeheadtext\csname\??la\headlanguage\s!default\endcsname{#2}% + \else\ifcsname\??mh#2\endcsname + \expandafter\let\expandafter\thetextprefix\csname\??mh#2\endcsname + \else\ifcsname\??mh\s!en#2\endcsname + \expandafter\let\expandafter\thetextprefix\csname\??mh\s!en#2\endcsname + \else + \let\thetextprefix\dummytextprefix + \fi\fi\fi\fi} + +\def\dodogetupsomemathlabeltext#1#2% + {\ifcsname\??mm#1#2\endcsname + \expandafter\let\expandafter\thetextprefix\csname\??mm#1#2\endcsname + \else\ifcsname\??la\mathlabellanguage\s!default\endcsname + \expandafter\dodogetupsomemathlabeltext\csname\??la\mathlabellanguage\s!default\endcsname{#2}% + \else\ifcsname\??mm#2\endcsname + \expandafter\let\expandafter\thetextprefix\csname\??mm#2\endcsname + \else\ifcsname\??mm\s!en#2\endcsname + \expandafter\let\expandafter\thetextprefix\csname\??mm\s!en#2\endcsname + \else + \let\thetextprefix\dummytextprefix + \fi\fi\fi\fi} + +% The WORD variants are a bit inefficient when #1/#2 are empty but they are +% seldom used (one can better set the style). + +\let\flushleftlabeltext \firstoftwoarguments +\let\flushrightlabeltext \secondoftwoarguments +\let\flushleftmathlabeltext \firstoftwoarguments +\let\flushrightmathlabeltext\secondoftwoarguments + +\def\flushleftlabelWORD #1#2{\WORD{#1}} +\def\flushrightlabelWORD #1#2{\WORD{#2}} +\def\flushbothlabeltexts #1#2#3{#1#3#2} +\def\flushbothlabelTEXTS #1#2#3{\WORD{#1}#3\WORD{#2}} + +\unexpanded\def\headtext #1{\dogetupsomeheadtext {#1}\expandafter\flushleftlabeltext \thetextprefix} +\unexpanded\def\leftlabeltext #1{\dogetupsomelabeltext {#1}\expandafter\flushleftlabeltext \thetextprefix} +\unexpanded\def\rightlabeltext #1{\dogetupsomelabeltext {#1}\expandafter\flushrightmathlabeltext\thetextprefix} +\unexpanded\def\LEFTLABELTEXT #1{\dogetupsomelabeltext {#1}\expandafter\flushleftlabelWORD \thetextprefix} +\unexpanded\def\RIGHTLABELTEXT #1{\dogetupsomelabeltext {#1}\expandafter\flushrightlabelWORD \thetextprefix} +\unexpanded\def\labeltexts #1{\dogetupsomelabeltext {#1}\expandafter\flushbothlabeltexts \thetextprefix} % #2 +\unexpanded\def\LABELTEXTS #1{\dogetupsomelabeltext {#1}\expandafter\flushbothlabelTEXTS \thetextprefix} % #2 +\unexpanded\def\leftmathlabeltext #1{\dogetupsomemathlabeltext{#1}\expandafter\flushleftmathlabeltext \thetextprefix} +\unexpanded\def\rightmathlabeltext#1{\dogetupsomemathlabeltext{#1}\expandafter\flushrightlabeltext \thetextprefix} + +\let\labeltext \leftlabeltext +\let\LABELTEXT \LEFTLABELTEXT +\let\mathlabeltext\leftmathlabeltext + +\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 + \let \mathlabeltext \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\presetheadtext {\settrue\protecttextprefixes\let\currenttextprefixclass\??mh\dodoubleempty\dosetupsometextprefix} +\def\presetlabeltext {\settrue\protecttextprefixes\let\currenttextprefixclass\??ml\dodoubleempty\dosetupsometextprefix} +\def\presetmathlabeltext{\settrue\protecttextprefixes\let\currenttextprefixclass\??mm\dodoubleempty\dosetupsometextprefix} + +%D \macros +%D {translate} +%D +%D Sometismes macros contain language specific words that are to +%D be typeset. Such macros can be made (more) language +%D independant by using: +%D +%D \showsetup{translate} +%D +%D like for instance: +%D +%D \starttyping +%D \translate[en=something,nl=iets] +%D \stoptyping +%D +%D which expands to {\em something} or {\em iets}, depending on +%D de current language. + +\def\dotranslate[#1]% + {\getparameters[\??lg][#1]% + \ifcsname\??lg\currentlanguage\endcsname + \csname\??lg\currentlanguage\endcsname + \else\ifcsname\??lg\s!en\endcsname + \csname\??lg\s!en\endcsname + \else + [translation #1]% + \fi\fi} + +\unexpanded\def\translate + {\dosingleempty\dotranslate} + +%D When used without argument, the last defined values are +%D used. This enables repetitive use like +%D +%D \starttyping +%D \en \translate\ means \nl \translate +%D \stoptyping + +%D \macros +%D {assigntranslation} +%D +%D This macro is a system macro, and can be used to assign a +%D translation to a macro. Its form is: +%D +%D \starttyping +%D \assigntranslation[en=something,nl=iets]\to\command +%D \stoptyping + +\def\assigntranslation[#1]\to#2% + {\getparameters[\??lg][#1]% + \edef#2{\csname\??lg\currentlanguage\endcsname}} + +\protect \endinput diff --git a/tex/context/base/lang-mis.mkii b/tex/context/base/lang-mis.mkii new file mode 100644 index 000000000..eb7bb1a04 --- /dev/null +++ b/tex/context/base/lang-mis.mkii @@ -0,0 +1,683 @@ +%D \module +%D [ file=lang-mis, +%D version=1997.03.20, % used to be supp-lan.tex +%D title=\CONTEXT\ Language Macros, +%D subtitle=Compounds, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Compounds} + +%D \gdef\starttest +%D {\blank +%D \noindent +%D \halign\bgroup\tt##\hskip2em&##\hskip2em&##\cr} +%D +%D \gdef\stoptest +%D {\egroup +%D \blank} +%D +%D \gdef\test#1% +%D {\defconvertedargument\ascii{#1}\ascii&\hyphenatedword{#1}\cr} + +\unprotect + +%D One of \TEX's strong points in building paragraphs is the way +%D hyphenations are handled. Although for real good hyphenation +%D of non||english languages some extensions to the program are +%D needed, fairly good results can be reached with the standard +%D mechanisms and an additional macro, at least in Dutch. + +%D \CONTEXT\ originates in the wish to typeset educational +%D materials, especially in a technical environment. In +%D production oriented environments, a lot of compound words +%D are used. Because the Dutch language poses no limits on +%D combining words, we often favor putting dashes between those +%D words, because it facilitates reading, at least for those +%D who are not that accustomed to it. +%D +%D In \TEX\ compound words, separated by a hyphen, are not +%D hyphenated at all. In spite of the multiple pass paragraph +%D typesetting this can lead to parts of words sticking into +%D the margin. The solution lays in saying \type +%D {spoelwater||terugwinunit} instead of \type +%D {spoelwater-terugwinunit}. By using a one character command +%D like \type {|}, delimited by the same character \type {|}, +%D we get ourselves both a decent visualization (in \TEXEDIT\ +%D and colored verbatim we color these commands yellow) and an +%D efficient way of combining words. +%D +%D The sequence \type{||} simply leads to two words connected by +%D a hyphen. Because we want to distinguish such a hyphen from +%D the one inserted when \TEX\ hyphenates a word, we use a bit +%D longer one. +%D +%D \hyphenation {spoel-wa-ter te-rug-win-unit} +%D +%D \starttest +%D \test {spoelwater||terugwinunit} +%D \stoptest +%D +%D As we already said, the \type{|} is a command. This commands +%D accepts an optional argument before it's delimiter, which is +%D also a \type{|}. +%D +%D \hyphenation {po-ly-meer che-mie} +%D +%D \starttest +%D \test {polymeer|*|chemie} +%D \stoptest +%D +%D Arguments like \type{*} are not interpreted and inserted +%D directly, in contrary to arguments like: +%D +%D \starttest +%D \test {polymeer|~|chemie} +%D \test {|(|polymeer|)|chemie} +%D \test {polymeer|(|chemie|)| } +%D \stoptest +%D +%D Although such situations seldom occur |<|we typeset thousands +%D of pages before we encountered one that forced us to enhance +%D this mechanism|>| we also have to take care of comma's. +%D +%D \hyphenation {uit-stel-len} +%D +%D \starttest +%D \test {op||, in|| en uitstellen} +%D \stoptest +%D +%D The next special case (concerning quotes) was brought to my +%D attention by Piet Tutelaers, one of the driving forces +%D behind rebuilding hyphenation patterns for the dutch +%D language.\footnote{In 1996 the spelling of the dutch +%D language has been slightly reformed which made this topic +%D actual again.} We'll also take care of this case. +%D +%D \starttest +%D \test {AOW|'|er} +%D \test {cd|'|tje} +%D \test {ex|-|PTT|'|er} +%D \test {rock|-|'n|-|roller} +%D \stoptest +%D +%D Tobias Burnus pointed out that I should also support +%D something like +%D +%D \starttest +%D \test {well|_|known} +%D \stoptest +%D +%D to stress the compoundness of hyphenated words. +%D +%D Of course we also have to take care of the special case: +%D +%D \starttest +%D \test {text||color and ||font} +%D \stoptest + +%D \macros +%D {installdiscretionaries} +%D +%D The mechanism described here is one of the older inner parts +%D of \CONTEXT. The most recent extensions concerns some +%D special cases as well as the possibility to install other +%D characters as delimiters. The prefered way of specifying +%D compound words is using \type{||}, which is installed by: +%D +%D \starttyping +%D \installdiscretionaries || - +%D \stoptyping +%D +%D Some alternative definitions are: +%D +%D \startbuffer +%D \installdiscretionaries ** - +%D \installdiscretionaries ++ - +%D \installdiscretionaries // - +%D \installdiscretionaries ~~ - +%D \stopbuffer +%D +%D \typebuffer +%D +%D after which we can say: +%D +%D \bgroup +%D \getbuffer +%D \starttest +%D \test {test**test**test} +%D \test {test++test++test} +%D \test {test//test//test} +%D \test {test~~test~~test} +%D \stoptest +%D \egroup + +%D \macros +%D {compoundhyphen, +%D beginofsubsentence,endofsubsentence} +%D +%D Now let's go to the macros. First we define some variables. +%D In the main \CONTEXT\ modules these can be tuned by a setup +%D command. Watch the (maybe) better looking compound hyphen. + +\ifx\compoundhyphen \undefined \def\compoundhyphen{\hbox{-\kern-.25ex-}} \fi + +\ifx\beginofsubsentence \undefined \def\beginofsubsentence{\hbox{---}} \fi +\ifx\endofsubsentence \undefined \def\endofsubsentence {\hbox{---}} \fi + +%D The last two variables are needed for subsentences +%D |<|like this one|>| which we did not yet mention. +%D +%D We want to enable breaking but at the same time don't want +%D compound characters like |-| or || to be separated from the +%D words. \TEX\ hackers will recognise the next two macro's: + +\ifx\prewordbreak \undefined \def\prewordbreak {\penalty\plustenthousand\hskip\zeropoint\relax} \fi +%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{.16667em} \fi % language specific + +%D \macros +%D {beginofsubsentencespacing,endofsubsentencespacing} +%D +%D In the previous macros we provided two hooks which can be +%D used to support nested sub||sentences. In \CONTEXT\ these +%D hooks are used to insert a small space when needed. + +\ifx\beginofsubsentencespacing\undefined \let\beginofsubsentencespacing\relax \fi +\ifx\endofsubsentencespacing \undefined \let\endofsubsentencespacing \relax \fi + +%D The following piece of code is a torture test compound +%D hndling. The \type {\relax} before the \type {\ifmmode} is +%D needed because of the alignment scanner (in \ETEX\ this +%D problem is not present because there a protected macro is +%D not expanded. Thanks to Tobias Burnus for providing this +%D example. +%D +%D \startformula +%D \left|f(x_n)-{1\over2}\right| = +%D {\cases{|{1\over2}-x_n| &for $0\le x_n < {1\over2}$\cr +%D |x_n-{1\over2}| &for ${1\over2}\zeropoint + (\prewordbreak + \else + \prewordbreak\discretionary{}{(-}{(}\prewordbreak + \fi} + +\definetextmodediscretionary ~ + {\prewordbreak\discretionary{-}{}{\thinspace}\postwordbreak} + +\definetextmodediscretionary ' + {\prewordbreak\discretionary{-}{}{'}\postwordbreak} + +\definetextmodediscretionary ^ + {\prewordbreak\discretionary{\hbox{$|$}}{}{\hbox{$|$}}% + \allowbreak\postwordbreak} % bugged + +\definetextmodediscretionary < + {\beginofsubsentence\prewordbreak\beginofsubsentencespacing} + +\definetextmodediscretionary > + {\endofsubsentencespacing\prewordbreak\endofsubsentence} + +\definetextmodediscretionary = + {\prewordbreak\midsentence\prewordbreak} % {\prewordbreak\compoundhyphen} + +% french + +\definetextmodediscretionary : {\removeunwantedspaces\prewordbreak\kern\hspaceamount\empty{:}:} +\definetextmodediscretionary ; {\removeunwantedspaces\prewordbreak\kern\hspaceamount\empty{;};} +\definetextmodediscretionary ? {\removeunwantedspaces\prewordbreak\kern\hspaceamount\empty{?}?} +\definetextmodediscretionary ! {\removeunwantedspaces\prewordbreak\kern\hspaceamount\empty{!}!} + +\definetextmodediscretionary * + {\prewordbreak\discretionary{-}{}{\kern.05em}\prewordbreak} + +% spanish + +\definetextmodediscretionary ?? {\prewordbreak\questiondown} +\definetextmodediscretionary !! {\prewordbreak\exclamdown} + +% \ifx\normalcompound\undefined \let\normalcompound=| \fi + +%D \installdiscretionary | + +%D \installdiscretionary + = + +\def\defaultdiscretionaryhyphen{\compoundhyphen} + +\installdiscretionary | \defaultdiscretionaryhyphen % installs in ctx and prt will fall back on it + +%D \macros +%D {fakecompoundhyphen} +%D +%D In headers and footers as well as in active pieces of text +%D we need a dirty hack. Try to imagine what is needed to +%D savely break the next text across a line and at the same +%D time make the words interactive. +%D +%D \starttyping +%D \goto{Some||Long||Word} +%D \stoptyping + +\def\fakecompoundhyphen + {\def\|{\mathortext\vert\dofakecompoundhyphen}} + +\def\dofakecompoundhyphen + {\def##1|% + {\doifelsenothing{##1}\compoundhyphen{##1}% + \kern\compoundbreakpoint\allowbreak}} + +%D \macros +%D {midworddiscretionary} +%D +%D If needed, one can add a discretionary hyphen using \type +%D {\midworddiscretionary}. This macro does the same as +%D \PLAIN\ \TEX's \type {\-}, but, like the ones implemented +%D earlier, this one also looks ahead for spaces and grouping +%D tokens. + +\def\midworddiscretionary + {\futurelet\next\domidworddiscretionary} + +\def\domidworddiscretionary + {\ifx\next\blankspace\else + \ifx\next\bgroup \else + \ifx\next\egroup \else + \discretionary{-}{}{}% + \fi\fi\fi} + +%D \macros +%D {installcompoundcharacter} +%D +%D When Tobias Burnus started translating the dutch manual of +%D \PPCHTEX\ into german, he suggested to let \CONTEXT\ support +%D the \type{german.sty} method of handling compound +%D characters, especially the umlaut. This package is meant for +%D use with \PLAIN\ \TEX\ as well as \LATEX. +%D +%D I decided to implement compound character support as +%D versatile as possible. As a result one can define his own +%D compound character support, like: +%D +%D \starttyping +%D \installcompoundcharacter "a {\"a} +%D \installcompoundcharacter "e {\"e} +%D \installcompoundcharacter "i {\"i} +%D \installcompoundcharacter "u {\"u} +%D \installcompoundcharacter "o {\"o} +%D \installcompoundcharacter "s {\SS} +%D \stoptyping +%D +%D or even +%D +%D \starttyping +%D \installcompoundcharacter "ck {\discretionary {k-}{k}{ck}} +%D \installcompoundcharacter "ff {\discretionary{ff-}{f}{ff}} +%D \stoptyping +%D +%D The support is not limited to alphabetic characters, so the +%D next definition is also valid. +%D +%D \starttyping +%D \installcompoundcharacter ". {.\doifnextcharelse{\spacetoken}{}{\kern.125em}} +%D \stoptyping +%D +%D The implementation looks familiar and uses the same tricks as +%D mentioned earlier in this module. We take care of two +%D arguments, which complicates things a bit. + +\def\@nc@{@nc@} % normal character +\def\@cc@{@cc@} % compound character +\def\@cs@{@cs@} % compound characters +\def\@cx@{@cx@} % compound definition + +%D When we started working on MK IV code, we needed a different +%D approach for defining the active character itself. In MK II as +%D well as in MK IV we now use the catcode vectors. + +\chardef\compoundcharactermode\plusone + +\def\installcompoundcharacter #1#2#3 #4% {#4} no grouping + {\ifcase\compoundcharactermode + % ignore mode + \else + \chardef\thecompoundcharacter`#1% + \@EA\chardef\csname\@nc@\string#1\endcsname\thecompoundcharacter + \def\!!stringa{#3}% + \@EA\def\csname\ifx\!!stringa\empty\@cc@\else\@cs@\fi\detokenize{#1#2#3}\endcsname{#4}% + \setevalue{\@cx@\detokenize{#1}}{\noexpand\handlecompoundcharacter{\detokenize{#1}}}% beter nr's +% \@EA\letcatcodecommand\@EA\prtcatcodes\@EA\thecompoundcharacter\csname\@cx@\detokenize{#1}\endcsname +% \@EA\letcatcodecommand\@EA\texcatcodes\@EA\thecompoundcharacter\csname\@cx@\detokenize{#1}\endcsname + \@EA\letcatcodecommand\@EA\ctxcatcodes\@EA\thecompoundcharacter\csname\@cx@\detokenize{#1}\endcsname + \fi} + +%D In order to serve the language specific well, we will introduce +%D a namespace: + +% \ifx\currentlanguage\undefined + \let\compoundcharacterclass\empty +% \else +% \def\compoundcharacterclass{\currentlanguage} +% \fi + +\def\@cc@{@cc@\compoundcharacterclass} % compound character +\def\@cs@{@cs@\compoundcharacterclass} % compound characters + +%D We can also ignore definitions (needed in for instance \XML). Beware, +%D this macro is supposed to be used grouped! + +\def\ignorecompoundcharacter + {\chardef\compoundcharactermode\zerocount} + +\let\restorecompoundcharacter \gobbleoneargument % obsolete +\let\enableactivediscretionaries\relax % obsolete + +%D In handling the compound characters we have to take care of +%D \type{\bgroup} and \type{\egroup} tokens, so we end up with +%D a multi||step interpretation macro. We look ahead for a +%D \type{\bgroup}, \type{\egroup} or \type{\blankspace}. Being +%D no user of this mechanism, the credits for testing them goes +%D to Tobias Burnus, the first german user of \CONTEXT. +%D +%D We define these macros as \type{\long} because we can +%D expect \type{\par} tokens. We need to look into the future +%D with \type{\futurelet} to prevent spaces from +%D disappearing. + +\def\handlecompoundcharacter#1% + {\def\xhandlecompoundcharacter{\dohandlecompoundcharacter{#1}}% + \futurelet\next\xhandlecompoundcharacter} + +\def\dohandlecompoundcharacter + {\ifx\next\bgroup + %\@EA\dodohandlecompoundcharacter % handle "{ee} -> \"ee + %\@EA\gobbleoneargument % forget "{ee} -> ee + \@EA\handlecompoundcharacterone % ignore "{ee} -> "ee + \else\ifx\next\egroup + \@EAEAEA\donohandlecompoundcharacter + \else\ifx\next\blankspace + \@EA\@EAEAEA\@EA\donohandlecompoundcharacter + \else + \@EA\@EAEAEA\@EA\dodohandlecompoundcharacter + \fi\fi\fi} + +\def\donohandlecompoundcharacter#1{\csname\@nc@\string#1\endcsname} + +\def\dododohandlecompoundcharacter + {\ifx\next\bgroup + \@EA\handlecompoundcharacterone + \else\ifx\next\egroup + \@EAEAEA\handlecompoundcharacterone + \else\ifx\next\blankspace + \@EA\@EAEAEA\@EA\handlecompoundcharacterone + \else + \@EA\@EAEAEA\@EA\handlecompoundcharactertwo + \fi\fi\fi} + +\def\dodohandlecompoundcharacter#1#2% preserve space + {\def\xdodohandlecompoundcharacter{\dododohandlecompoundcharacter#1#2}% + \futurelet\next\xdodohandlecompoundcharacter} + +%D Besides taken care of the grouping and space tokens, we have +%D to deal with three situations. First we look if the next +%D character equals the first one, if so, then we just insert +%D the original. Next we look if indeed a compound character is +%D defined. We either execute the compound character or just +%D insert the first. So we have +%D +%D \starttyping +%D +%D \stoptyping +%D +%D In later modules we will see how these commands are used. + +\long\def\handlecompoundcharacterone#1#2% + {\if\string#1\string#2% was: \ifx#1#2% + \def\next{\csname\@nc@\string#1\endcsname}% + \else\ifcsname\@cc@\string#1\string#2\endcsname + \def\next{\csname\@cc@\string#1\string#2\endcsname}% + \else + \def\next{\csname\@nc@\string#1\endcsname#2}% + \fi\fi + \next} + +\long\def\handlecompoundcharactertwo#1#2#3% + {\if\string#1\string#2% + \def\next{\csname\@nc@\string#1\endcsname#3}% + \else\ifcsname\@cs@\string#1\string#2\string#3\endcsname + \def\next{\csname\@cs@\string#1\string#2\string#3\endcsname}% + \else\ifcsname\@cc@\string#1\string#2\endcsname + \def\next{\csname\@cc@\string#1\string#2\endcsname#3}% + \else + \def\next{\csname\@nc@\string#1\endcsname#2#3}% + \fi\fi\fi + \next} + +%D For very obscure applications (see for an application \type +%D {lang-sla.tex}) we provide: + +\def\simplifiedcompoundcharacter#1#2% + {\ifcsname\@cc@\string#1\string#2\endcsname + \@EA\@EA\@EA\firstofoneargument\csname\@cc@\string#1\string#2\endcsname + \else + #2% + \fi} + +%D \macros +%D {disablediscretionaries,disablecompoundcharacter} +%D +%D Occasionally we need to disable this mechanism. For the +%D moment we assume that \type {|} is used. + +\let\disablediscretionaries \ignorediscretionaries +\let\disablecompoundcharacters\ignorecompoundcharacter + +%D \macros +%D {normalcompound} +%D +%D Handy in for instance XML. (Kind of obsolete) + +\ifx\normalcompound\undefined \let\normalcompound=| \fi + +\protect \endinput diff --git a/tex/context/base/lang-mis.mkiv b/tex/context/base/lang-mis.mkiv new file mode 100644 index 000000000..0df45877b --- /dev/null +++ b/tex/context/base/lang-mis.mkiv @@ -0,0 +1,689 @@ +%D \module +%D [ file=lang-mis, +%D version=1997.03.20, % used to be supp-lan.tex +%D title=\CONTEXT\ Language Macros, +%D subtitle=Compounds, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Compounds} + +%D \gdef\starttest +%D {\blank +%D \noindent +%D \halign\bgroup\tt##\hskip2em&##\hskip2em&##\cr} +%D +%D \gdef\stoptest +%D {\egroup +%D \blank} +%D +%D \gdef\test#1% +%D {\defconvertedargument\ascii{#1}\ascii&\hyphenatedword{#1}\cr} + +\unprotect + +%D One of \TEX's strong points in building paragraphs is the way +%D hyphenations are handled. Although for real good hyphenation +%D of non||english languages some extensions to the program are +%D needed, fairly good results can be reached with the standard +%D mechanisms and an additional macro, at least in Dutch. + +%D \CONTEXT\ originates in the wish to typeset educational +%D materials, especially in a technical environment. In +%D production oriented environments, a lot of compound words +%D are used. Because the Dutch language poses no limits on +%D combining words, we often favor putting dashes between those +%D words, because it facilitates reading, at least for those +%D who are not that accustomed to it. +%D +%D In \TEX\ compound words, separated by a hyphen, are not +%D hyphenated at all. In spite of the multiple pass paragraph +%D typesetting this can lead to parts of words sticking into +%D the margin. The solution lays in saying \type +%D {spoelwater||terugwinunit} instead of \type +%D {spoelwater-terugwinunit}. By using a one character command +%D like \type {|}, delimited by the same character \type {|}, +%D we get ourselves both a decent visualization (in \TEXEDIT\ +%D and colored verbatim we color these commands yellow) and an +%D efficient way of combining words. +%D +%D The sequence \type{||} simply leads to two words connected by +%D a hyphen. Because we want to distinguish such a hyphen from +%D the one inserted when \TEX\ hyphenates a word, we use a bit +%D longer one. +%D +%D \hyphenation {spoel-wa-ter te-rug-win-unit} +%D +%D \starttest +%D \test {spoelwater||terugwinunit} +%D \stoptest +%D +%D As we already said, the \type{|} is a command. This commands +%D accepts an optional argument before it's delimiter, which is +%D also a \type{|}. +%D +%D \hyphenation {po-ly-meer che-mie} +%D +%D \starttest +%D \test {polymeer|*|chemie} +%D \stoptest +%D +%D Arguments like \type{*} are not interpreted and inserted +%D directly, in contrary to arguments like: +%D +%D \starttest +%D \test {polymeer|~|chemie} +%D \test {|(|polymeer|)|chemie} +%D \test {polymeer|(|chemie|)| } +%D \stoptest +%D +%D Although such situations seldom occur |<|we typeset thousands +%D of pages before we encountered one that forced us to enhance +%D this mechanism|>| we also have to take care of comma's. +%D +%D \hyphenation {uit-stel-len} +%D +%D \starttest +%D \test {op||, in|| en uitstellen} +%D \stoptest +%D +%D The next special case (concerning quotes) was brought to my +%D attention by Piet Tutelaers, one of the driving forces +%D behind rebuilding hyphenation patterns for the dutch +%D language.\footnote{In 1996 the spelling of the dutch +%D language has been slightly reformed which made this topic +%D actual again.} We'll also take care of this case. +%D +%D \starttest +%D \test {AOW|'|er} +%D \test {cd|'|tje} +%D \test {ex|-|PTT|'|er} +%D \test {rock|-|'n|-|roller} +%D \stoptest +%D +%D Tobias Burnus pointed out that I should also support +%D something like +%D +%D \starttest +%D \test {well|_|known} +%D \stoptest +%D +%D to stress the compoundness of hyphenated words. +%D +%D Of course we also have to take care of the special case: +%D +%D \starttest +%D \test {text||color and ||font} +%D \stoptest + +%D \macros +%D {installdiscretionaries} +%D +%D The mechanism described here is one of the older inner parts +%D of \CONTEXT. The most recent extensions concerns some +%D special cases as well as the possibility to install other +%D characters as delimiters. The prefered way of specifying +%D compound words is using \type{||}, which is installed by: +%D +%D \starttyping +%D \installdiscretionaries || - +%D \stoptyping +%D +%D Some alternative definitions are: +%D +%D \startbuffer +%D \installdiscretionaries ** - +%D \installdiscretionaries ++ - +%D \installdiscretionaries // - +%D \installdiscretionaries ~~ - +%D \stopbuffer +%D +%D \typebuffer +%D +%D after which we can say: +%D +%D \bgroup +%D \getbuffer +%D \starttest +%D \test {test**test**test} +%D \test {test++test++test} +%D \test {test//test//test} +%D \test {test~~test~~test} +%D \stoptest +%D \egroup + +%D \macros +%D {compoundhyphen, +%D beginofsubsentence,endofsubsentence} +%D +%D Now let's go to the macros. First we define some variables. +%D In the main \CONTEXT\ modules these can be tuned by a setup +%D command. Watch the (maybe) better looking compound hyphen. + +\ifx\compoundhyphen \undefined \def\compoundhyphen{\hbox{-\kern-.25ex-}} \fi + +\ifx\beginofsubsentence \undefined \def\beginofsubsentence{\hbox{---}} \fi +\ifx\endofsubsentence \undefined \def\endofsubsentence {\hbox{---}} \fi + +%D The last two variables are needed for subsentences +%D |<|like this one|>| which we did not yet mention. +%D +%D We want to enable breaking but at the same time don't want +%D compound characters like |-| or || to be separated from the +%D words. \TEX\ hackers will recognise the next two macro's: + +\ifx\prewordbreak \undefined \def\prewordbreak {\penalty\plustenthousand\hskip\zeropoint\relax} \fi +%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{.16667em} \fi % language specific + +%D \macros +%D {beginofsubsentencespacing,endofsubsentencespacing} +%D +%D In the previous macros we provided two hooks which can be +%D used to support nested sub||sentences. In \CONTEXT\ these +%D hooks are used to insert a small space when needed. + +\ifx\beginofsubsentencespacing\undefined \let\beginofsubsentencespacing\relax \fi +\ifx\endofsubsentencespacing \undefined \let\endofsubsentencespacing \relax \fi + +%D The following piece of code is a torture test compound +%D hndling. The \type {\relax} before the \type {\ifmmode} is +%D needed because of the alignment scanner (in \ETEX\ this +%D problem is not present because there a protected macro is +%D not expanded. Thanks to Tobias Burnus for providing this +%D example. +%D +%D \startformula +%D \left|f(x_n)-{1\over2}\right| = +%D {\cases{|{1\over2}-x_n| &for $0\le x_n < {1\over2}$\cr +%D |x_n-{1\over2}| &for ${1\over2}2xxx + +\def\hyphenliketextmodediscretionary#1#2% + {\ifconditional\spaceafterdiscretionary + \prewordbreak\hbox{#1}\relax + \else\ifconditional\punctafterdiscretionary + \prewordbreak\hbox{#1}\relax + \else + \prewordbreak#2\postwordbreak % was prewordbreak + \fi\fi} + +\definetextmodediscretionary {} + {\hyphenliketextmodediscretionary\textmodehyphen\textmodehyphendiscretionary} + +\definetextmodediscretionary - + {\hyphenliketextmodediscretionary\normalhyphen\normalhyphendiscretionary} + +\definetextmodediscretionary _ + {\hyphenliketextmodediscretionary\composedhyphen\composedhyphendiscretionary} + +\definetextmodediscretionary ) + {\hyphenliketextmodediscretionary{)}{\discretionary{-)}{}{)}}} + +\definetextmodediscretionary ( + {\ifdim\lastskip>\zeropoint + (\prewordbreak + \else + \prewordbreak\discretionary{}{(-}{(}\prewordbreak + \fi} + +\definetextmodediscretionary ~ + {\prewordbreak\discretionary{-}{}{\thinspace}\postwordbreak} + +\definetextmodediscretionary ' + {\prewordbreak\discretionary{-}{}{'}\postwordbreak} + +\definetextmodediscretionary ^ + {\prewordbreak\discretionary{\hbox{$|$}}{}{\hbox{$|$}}% + \allowbreak\postwordbreak} % bugged + +\definetextmodediscretionary < + {\beginofsubsentence\prewordbreak\beginofsubsentencespacing} + +\definetextmodediscretionary > + {\endofsubsentencespacing\prewordbreak\endofsubsentence} + +\definetextmodediscretionary = + {\prewordbreak\midsentence\prewordbreak} % {\prewordbreak\compoundhyphen} + +% french + +\definetextmodediscretionary : {\removeunwantedspaces\prewordbreak\kern\hspaceamount\empty{:}:} +\definetextmodediscretionary ; {\removeunwantedspaces\prewordbreak\kern\hspaceamount\empty{;};} +\definetextmodediscretionary ? {\removeunwantedspaces\prewordbreak\kern\hspaceamount\empty{?}?} +\definetextmodediscretionary ! {\removeunwantedspaces\prewordbreak\kern\hspaceamount\empty{!}!} + +\definetextmodediscretionary * + {\prewordbreak\discretionary{-}{}{\kern.05em}\prewordbreak} + +% spanish + +\definetextmodediscretionary ?? {\prewordbreak\questiondown} +\definetextmodediscretionary !! {\prewordbreak\exclamdown} + +% \ifx\normalcompound\undefined \let\normalcompound=| \fi + +%D \installdiscretionary | + +%D \installdiscretionary + = + +\def\defaultdiscretionaryhyphen{\compoundhyphen} + +\installdiscretionary | \defaultdiscretionaryhyphen % installs in ctx and prt will fall back on it + +%D \macros +%D {fakecompoundhyphen} +%D +%D In headers and footers as well as in active pieces of text +%D we need a dirty hack. Try to imagine what is needed to +%D savely break the next text across a line and at the same +%D time make the words interactive. +%D +%D \starttyping +%D \goto{Some||Long||Word} +%D \stoptyping + +\def\fakecompoundhyphen + {\def\|{\mathortext\vert\dofakecompoundhyphen}} + +\def\dofakecompoundhyphen + {\def##1|% + {\doifelsenothing{##1}\compoundhyphen{##1}% + \kern\compoundbreakpoint\allowbreak}} + +%D \macros +%D {midworddiscretionary} +%D +%D If needed, one can add a discretionary hyphen using \type +%D {\midworddiscretionary}. This macro does the same as +%D \PLAIN\ \TEX's \type {\-}, but, like the ones implemented +%D earlier, this one also looks ahead for spaces and grouping +%D tokens. + +\def\midworddiscretionary + {\futurelet\next\domidworddiscretionary} + +\def\domidworddiscretionary + {\ifx\next\blankspace\else + \ifx\next\bgroup \else + \ifx\next\egroup \else + \discretionary{-}{}{}% + \fi\fi\fi} + +%D \macros +%D {installcompoundcharacter} +%D +%D When Tobias Burnus started translating the dutch manual of +%D \PPCHTEX\ into german, he suggested to let \CONTEXT\ support +%D the \type{german.sty} method of handling compound +%D characters, especially the umlaut. This package is meant for +%D use with \PLAIN\ \TEX\ as well as \LATEX. +%D +%D I decided to implement compound character support as +%D versatile as possible. As a result one can define his own +%D compound character support, like: +%D +%D \starttyping +%D \installcompoundcharacter "a {\"a} +%D \installcompoundcharacter "e {\"e} +%D \installcompoundcharacter "i {\"i} +%D \installcompoundcharacter "u {\"u} +%D \installcompoundcharacter "o {\"o} +%D \installcompoundcharacter "s {\SS} +%D \stoptyping +%D +%D or even +%D +%D \starttyping +%D \installcompoundcharacter "ck {\discretionary {k-}{k}{ck}} +%D \installcompoundcharacter "ff {\discretionary{ff-}{f}{ff}} +%D \stoptyping +%D +%D The support is not limited to alphabetic characters, so the +%D next definition is also valid. +%D +%D \starttyping +%D \installcompoundcharacter ". {.\doifnextcharelse{\spacetoken}{}{\kern.125em}} +%D \stoptyping +%D +%D The implementation looks familiar and uses the same tricks as +%D mentioned earlier in this module. We take care of two +%D arguments, which complicates things a bit. + +\def\@nc@{@nc@} % normal character +\def\@cc@{@cc@} % compound character +\def\@cs@{@cs@} % compound characters +\def\@cx@{@cx@} % compound definition + +%D When we started working on MK IV code, we needed a different +%D approach for defining the active character itself. In MK II as +%D well as in MK IV we now use the catcode vectors. + +\chardef\compoundcharactermode\plusone + +\def\installcompoundcharacter #1#2#3 #4% {#4} no grouping + {\ifcase\compoundcharactermode + % ignore mode + \else + \chardef\thecompoundcharacter`#1% + \@EA\chardef\csname\@nc@\string#1\endcsname\thecompoundcharacter + \def\!!stringa{#3}% + \@EA\def\csname\ifx\!!stringa\empty\@cc@\else\@cs@\fi\detokenize{#1#2#3}\endcsname{#4}% + \setevalue{\@cx@\detokenize{#1}}{\noexpand\handlecompoundcharacter{\detokenize{#1}}}% beter nr's +% \@EA\letcatcodecommand\@EA\prtcatcodes\@EA\thecompoundcharacter\csname\@cx@\detokenize{#1}\endcsname +% \@EA\letcatcodecommand\@EA\texcatcodes\@EA\thecompoundcharacter\csname\@cx@\detokenize{#1}\endcsname + \@EA\letcatcodecommand\@EA\ctxcatcodes\@EA\thecompoundcharacter\csname\@cx@\detokenize{#1}\endcsname + \fi} + +%D In order to serve the language specific well, we will introduce +%D a namespace: + +% \ifx\currentlanguage\undefined + \let\compoundcharacterclass\empty +% \else +% \def\compoundcharacterclass{\currentlanguage} +% \fi + +\def\@cc@{@cc@\compoundcharacterclass} % compound character +\def\@cs@{@cs@\compoundcharacterclass} % compound characters + +%D We can also ignore definitions (needed in for instance \XML). Beware, +%D this macro is supposed to be used grouped! + +\def\ignorecompoundcharacter + {\chardef\compoundcharactermode\zerocount} + +\let\restorecompoundcharacter \gobbleoneargument % obsolete +\let\enableactivediscretionaries\relax % obsolete + +%D In handling the compound characters we have to take care of +%D \type{\bgroup} and \type{\egroup} tokens, so we end up with +%D a multi||step interpretation macro. We look ahead for a +%D \type{\bgroup}, \type{\egroup} or \type{\blankspace}. Being +%D no user of this mechanism, the credits for testing them goes +%D to Tobias Burnus, the first german user of \CONTEXT. +%D +%D We define these macros as \type{\long} because we can +%D expect \type{\par} tokens. We need to look into the future +%D with \type{\futurelet} to prevent spaces from +%D disappearing. + +\def\handlecompoundcharacter#1% + {\def\xhandlecompoundcharacter{\dohandlecompoundcharacter{#1}}% + \futurelet\next\xhandlecompoundcharacter} + +\def\dohandlecompoundcharacter + {\ifx\next\bgroup + %\@EA\dodohandlecompoundcharacter % handle "{ee} -> \"ee + %\@EA\gobbleoneargument % forget "{ee} -> ee + \@EA\handlecompoundcharacterone % ignore "{ee} -> "ee + \else\ifx\next\egroup + \@EAEAEA\donohandlecompoundcharacter + \else\ifx\next\blankspace + \@EA\@EAEAEA\@EA\donohandlecompoundcharacter + \else + \@EA\@EAEAEA\@EA\dodohandlecompoundcharacter + \fi\fi\fi} + +\def\donohandlecompoundcharacter#1{\csname\@nc@\string#1\endcsname} + +\def\dododohandlecompoundcharacter + {\ifx\next\bgroup + \@EA\handlecompoundcharacterone + \else\ifx\next\egroup + \@EAEAEA\handlecompoundcharacterone + \else\ifx\next\blankspace + \@EA\@EAEAEA\@EA\handlecompoundcharacterone + \else + \@EA\@EAEAEA\@EA\handlecompoundcharactertwo + \fi\fi\fi} + +\def\dodohandlecompoundcharacter#1#2% preserve space + {\def\xdodohandlecompoundcharacter{\dododohandlecompoundcharacter#1#2}% + \futurelet\next\xdodohandlecompoundcharacter} + +%D Besides taken care of the grouping and space tokens, we have +%D to deal with three situations. First we look if the next +%D character equals the first one, if so, then we just insert +%D the original. Next we look if indeed a compound character is +%D defined. We either execute the compound character or just +%D insert the first. So we have +%D +%D \starttyping +%D +%D \stoptyping +%D +%D In later modules we will see how these commands are used. + +\long\def\handlecompoundcharacterone#1#2% + {\if\string#1\string#2% was: \ifx#1#2% + \def\next{\csname\@nc@\string#1\endcsname}% + \else\ifcsname\@cc@\string#1\string#2\endcsname + \def\next{\csname\@cc@\string#1\string#2\endcsname}% + \else + \def\next{\csname\@nc@\string#1\endcsname#2}% + \fi\fi + \next} + +\long\def\handlecompoundcharactertwo#1#2#3% + {\if\string#1\string#2% + \def\next{\csname\@nc@\string#1\endcsname#3}% + \else\ifcsname\@cs@\string#1\string#2\string#3\endcsname + \def\next{\csname\@cs@\string#1\string#2\string#3\endcsname}% + \else\ifcsname\@cc@\string#1\string#2\endcsname + \def\next{\csname\@cc@\string#1\string#2\endcsname#3}% + \else + \def\next{\csname\@nc@\string#1\endcsname#2#3}% + \fi\fi\fi + \next} + +%D For very obscure applications (see for an application \type +%D {lang-sla.tex}) we provide: + +\def\simplifiedcompoundcharacter#1#2% + {\ifcsname\@cc@\string#1\string#2\endcsname + \@EA\@EA\@EA\firstofoneargument\csname\@cc@\string#1\string#2\endcsname + \else + #2% + \fi} + +%D \macros +%D {disablediscretionaries,disablecompoundcharacter} +%D +%D Occasionally we need to disable this mechanism. For the +%D moment we assume that \type {|} is used. + +\let\disablediscretionaries \ignorediscretionaries +\let\disablecompoundcharacters\ignorecompoundcharacter + +%D \macros +%D {normalcompound} +%D +%D Handy in for instance XML. (Kind of obsolete) + +\ifx\normalcompound\undefined \let\normalcompound=| \fi + +\protect \endinput diff --git a/tex/context/base/lang-run.mkii b/tex/context/base/lang-run.mkii new file mode 100644 index 000000000..4b332cfb9 --- /dev/null +++ b/tex/context/base/lang-run.mkii @@ -0,0 +1,36 @@ +%D \module +%D [ file=lang-run, +%D version=2005.09.08, +%D title=\CONTEXT\ Language 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. + +%D [This code is hooked into the core macros and saves some +%D format space.] + +\unprotect + +\gdef\showpatterns + {\bgroup + \def\doshowpatterns##1##2##3##4% language number encoding mapping + {\NC##1\NC##3\NC##4\NC##2\NC + \specificlanguageparameter{##1}\s!lefthyphenmin \NC + \specificlanguageparameter{##1}\s!righthyphenmin\NC\NR}% + \starttabulate[|c|c|c|c|c|c|] + \HL + \NC \bf language \NC \bf encoding \NC \bf mapping \NC \bf number \NC + \bf left\low{min} \NC + \bf right\low{min} \NC \NR + \HL + \preloadedpmessage + \HL + \stoptabulate + \egroup} + +\protect \endinput diff --git a/tex/context/base/lang-sla.mkii b/tex/context/base/lang-sla.mkii new file mode 100644 index 000000000..62483aeb6 --- /dev/null +++ b/tex/context/base/lang-sla.mkii @@ -0,0 +1,30 @@ +%D \module +%D [ file=lang-sla, +%D version=1999.09.13, % 1997.09.03 +%D title=\CONTEXT\ Language Macros, +%D subtitle=Slavic Languages, +%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. + +\def\sloveniancharacter#1% + {\ifcase#1\unknowncharacter + \or a\or b\or c\or \ccaron\or d\or e\or f\or g\or h\or i\or j\or k\or l\or m% + \or n\or o\or p\or r\or s\or \scaron\or t\or u\or v\or z\or \zcaron + \else + \unknowncharacter + \fi} + +\def\slovenianCharacter#1% + {\ifcase#1\unknowncharacter + \or A\or B\or C\or \Ccaron\or D\or E\or F\or G\or H\or I\or J\or K\or L\or M% + \or N\or O\or P\or R\or S\or \Scaron\or T\or U\or V\or Z\or \Zcaron + \else + \unknowncharacter + \fi} + +\endinput diff --git a/tex/context/base/lang-sla.mkiv b/tex/context/base/lang-sla.mkiv new file mode 100644 index 000000000..479012615 --- /dev/null +++ b/tex/context/base/lang-sla.mkiv @@ -0,0 +1,17 @@ +%D \module +%D [ file=lang-sla, +%D version=2006.09.16, +%D title=\CONTEXT\ Language Macros, +%D subtitle=Slavic Languages, +%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. + +\def\sloveniancharacters#1{\ctxlua{converters.alphabetic(\number#1,"sl")}} +\def\slovenianCharacters#1{\ctxlua{converters.Alphabetic(\number#1,"sl")}} + +\endinput diff --git a/tex/context/base/lang-sla.tex b/tex/context/base/lang-sla.tex new file mode 100644 index 000000000..2c645af5a --- /dev/null +++ b/tex/context/base/lang-sla.tex @@ -0,0 +1,497 @@ +%D \module +%D [ file=lang-sla, +%D version=1999.09.13, % 1997.09.03 +%D title=\CONTEXT\ Language Macros, +%D subtitle=Slavic Languages, +%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. + +% Todo: replace \'.. by \namedglyph + +%D The framework of this module is set up by Hans Hagen while +%D many of the first translations were done by Tobias. Later +%D on, corrections were made by users. If you have suggestions, +%D or feel that your name missing here, don't hesitate to send +%D us an email. +%D +%D \starttabulate[|lB|l|] +%D \NC Czech \NC Tom Hudec, Petr Sojka \NC \NR +%D \NC Polish \NC Grzegorz Sapijaszko \NC \NR +%D \NC Croatian \NC \Zcaron eljko Vrba \NC \NR +%D \NC Slovenian \NC Mojca Miklavec \NC \NR +%D \NC Cz and Sk \NC Richard Gabriel \NC \NR +%D \stoptabulate + +% Belarussian, Russian, Ukrainian, Bulgarian, Macedonian, +% Serbo-Croatian, Slovenian, Czech, Kushubian, +% Lusatian/Sorbian/Wendish, Polish, Slovak, Albanian, +% Illyrian, Armenian + +\writestatus{loading}{ConTeXt Language Macros / Slavic Languages} + +\unprotect + +% \unexpanded\def\textormathglue#1#2#3% submitted original +% {\begingroup +% \scratchdimen=#1\hspaceamount\empty{#3}% +% \scratchskip=\zeropoint\!!plus.5\scratchdimen\!!minus.3\scratchdimen\relax +% \ifmmode +% \mskip#1#2% +% \else +% \kern#1\hspaceamount\empty{#3}% +% \hskip\scratchskip +% \fi +% \endgroup} + +% actually we could use the new pdftex features + +\unexpanded\def\textormathglue#1#2#3% cleaned up one + {\begingroup + \ifmmode + \mskip#1#2% + \else + \scratchdimen#1\hspaceamount\empty{#3}% + \scratchskip\scratchdimen\!!plus.5\scratchdimen\!!minus.3\scratchdimen + \hskip\scratchskip + \fi + \endgroup} + +\def\thinglue {\textormathglue+\thinmuskip 1} +\def\medglue {\textormathglue+\medmuskip 2} +\def\thickglue{\textormathglue+\thickmuskip3} + +\installlanguage + [\s!pl] + [\c!spacing=\v!packed, + \c!leftsentence=---, + \c!rightsentence=---, + \c!leftsubsentence=---, + \c!rightsubsentence=---, + \c!leftquote=\lowerleftsingleninequote, + \c!rightquote=\upperrightsingleninequote, + \c!leftquotation=\lowerleftdoubleninequote, + \c!rightquotation=\upperrightdoubleninequote, + \c!date={\v!day,{.},\ ,\v!month,\ ,\v!year}, + \s!mapping={pl0,ec,qx}, + \s!encoding={pl0,ec,qx}] + +\installlanguage + [\s!cs] + [\c!spacing=\v!packed, + \c!leftsentence=\thickglue--\thickglue\penalty-20\relax, % hh, \relax added + \c!rightsentence=\thickglue--\thickglue\penalty-20\relax, + \c!leftsubsentence=~---~\penalty-20\relax, + \c!rightsubsentence=~---~\penalty-20\relax, + \c!leftquote=\lowerleftsingleninequote, + \c!rightquote=\upperrightsinglesixquote, + \c!leftquotation=\lowerleftdoubleninequote, + \c!rightquotation=\upperrightdoublesixquote, + \c!date={\v!day,{.\,},\v!month,\ ,\v!year}, + \s!mapping={il2,ec}, + \s!encoding={il2,ec}] + +\installlanguage + [\s!sk] + [\c!spacing=\v!packed, + \c!leftsentence=---, + \c!rightsentence=---, + \c!leftsubsentence=---, + \c!rightsubsentence=---, + \c!leftquote=\upperleftsinglesixquote, + \c!rightquote=\upperrightsingleninequote, + \c!leftquotation=\upperleftdoublesixquote, + \c!rightquotation=\upperrightdoubleninequote, + \c!date={\v!day,{.\,},\v!month,\ ,\v!year}, + \s!mapping={il2,ec}, + \s!encoding={il2,ec}] + +\installlanguage + [\s!hr] + [\c!spacing=\v!packed, + \c!leftsentence=---, + \c!rightsentence=---, + \c!leftsubsentence=---, + \c!rightsubsentence=---, + \c!leftquote=\upperleftsinglesixquote, + \c!rightquote=\upperrightsingleninequote, + \c!leftquotation=\upperleftdoublesixquote, + \c!rightquotation=\upperrightdoubleninequote, + \c!date={\v!day,\ ,\v!month,\ ,\v!year}, + \s!mapping=ec, + \s!encoding=ec] + +%D The default quotation marks for Slovenian were chosen as +%D \lowerleftdoubleninequote these ones\upperrightdoublesixquote\ +%D which was probably due to the strong influence computers +%D had on typesetting, but \rightguillemot these ones\leftguillemot\ +%D are \quotation{more correct}. +%D +%D If you still want the other quotation marks, use this: +%D +%D \starttyping +%D \installlanguage +%D [sl] +%D [leftquote=\lowerleftsingleninequote, +%D rightquote=\upperrightsinglesixquote, +%D leftquotation=\lowerleftdoubleninequote, +%D rightquotation=\upperrightdoublesixquote] +%D \stoptyping +%D +%D If you disagree with the change, please send an email to Mojca, but +%D best use some pretty strong arguments because she loves S{\sl love}nia +%D to much to comprimise on this. +%D +%D German faces approximately the same problem. I (MM) would prefer to +%D have something like: +%D +%D \starttyping +%D \mainlanguage[sl][quotationstyle=guillemot|doublequote] % better name needed +%D \stoptyping +%D +%D but users are expected to respect the rules of nice and correct +%D typography anyway. + +\installlanguage + [\s!sl] + [\c!spacing=\v!packed, + \c!leftsentence={\hbox{--~}}, + \c!rightsentence={\hbox{~--}}, + \c!leftsubsentence={--}, + \c!rightsubsentence={--}, + %\c!leftquote=\lowerleftsingleninequote, + %\c!rightquote=\upperrightsinglesixquote, + %\c!leftquotation=\lowerleftdoubleninequote, + %\c!rightquotation=\upperrightdoublesixquote, + \c!leftquote=\guilsingleright, + \c!rightquote=\guilsingleleft, + \c!leftquotation=\rightguillemot, + \c!rightquotation=\leftguillemot, + \c!date={\v!day,{.},\ ,\v!month,\ ,\v!year}, + \s!mapping=ec, + \s!encoding=ec] + +\installlanguage [polish] [\s!pl] +\installlanguage [czech] [\s!cs] +\installlanguage [slovak] [\s!sk] +\installlanguage [croatian] [\s!hr] +\installlanguage [slovenian] [\s!sl] +\installlanguage [slovene] [\s!sl] % both possible (mojca: still needed?) + +\installlanguage [cz] [\s!cs] + +% labels + +\setupheadtext [\s!pl] [\v!content=Spis tre\sacute ci] +\setupheadtext [\s!cs] [\v!content=Obsah] +\setupheadtext [\s!sk] [\v!content=Obsah] +\setupheadtext [\s!hr] [\v!content=Sadr\zcaron aj] +\setupheadtext [\s!sl] [\v!content=Kazalo] + +\setupheadtext [\s!pl] [\v!tables=Tabele] +\setupheadtext [\s!cs] [\v!tables=Tabulky] +\setupheadtext [\s!sk] [\v!tables=Tabuliek] +\setupheadtext [\s!hr] [\v!tables=Tablice] +\setupheadtext [\s!sl] [\v!tables=Tabele] + +\setupheadtext [\s!pl] [\v!figures=Ilustracje] +\setupheadtext [\s!cs] [\v!figures=Obr\aacute zky] +\setupheadtext [\s!sk] [\v!figures=Obr\aacute zkov] +\setupheadtext [\s!hr] [\v!figures=Slike] +\setupheadtext [\s!sl] [\v!figures=Slike] + +\setupheadtext [\s!pl] [\v!graphics=Grafika] +\setupheadtext [\s!cs] [\v!graphics=Grafy] +\setupheadtext [\s!sk] [\v!graphics=Graf] +\setupheadtext [\s!hr] [\v!graphics=Slike] +\setupheadtext [\s!sl] [\v!graphics=Slike] + +\setupheadtext [\s!pl] [\v!intermezzi=Intermezza] +\setupheadtext [\s!cs] [\v!intermezzi=Intermezza] +\setupheadtext [\s!sk] [\v!intermezzi=Intermezz\aacute] +\setupheadtext [\s!hr] [\v!intermezzi=Intermezza] +\setupheadtext [\s!sl] [\v!intermezzi=Intermezzi] + +\setupheadtext [\s!pl] [\v!index=Indeks] +\setupheadtext [\s!cs] [\v!index=Rejst\rcaron\iacute k] +\setupheadtext [\s!sk] [\v!index=Zoznam] +\setupheadtext [\s!hr] [\v!index=Indeks] +\setupheadtext [\s!sl] [\v!index=Stvarno kazalo] + +\setupheadtext [\s!pl] [\v!abbreviations=Skr\oacute cenie] +\setupheadtext [\s!cs] [\v!abbreviations=Zkratky] +\setupheadtext [\s!sk] [\v!abbreviations=Skratky] +\setupheadtext [\s!hr] [\v!abbreviations=Kratice] +\setupheadtext [\s!sl] [\v!abbreviations=Kratice] + +\setupheadtext [\s!pl] [\v!logos=Znaki] +\setupheadtext [\s!cs] [\v!logos=Loga] +\setupheadtext [\s!sk] [\v!logos=Log\aacute] +\setupheadtext [\s!hr] [\v!logos=Znakovi] +\setupheadtext [\s!sl] [\v!logos=Logotipi] + +\setupheadtext [\s!pl] [\v!units=Jednostki] +\setupheadtext [\s!cs] [\v!units=Jednotky] +\setupheadtext [\s!sk] [\v!units=Jednotky] +\setupheadtext [\s!hr] [\v!units=Jednostki] +\setupheadtext [\s!sl] [\v!units=Enote] + +%setupheadtext [\s!pl] [pubs=?] +\setupheadtext [\s!cs] [pubs=Literatura] +%setupheadtext [\s!sk] [pubs=?] +%setupheadtext [\s!hr] [pubs=?] +\setupheadtext [\s!sl] [pubs=Literatura] + +\setuplabeltext [\s!pl] [\v!table=Tabela ] +\setuplabeltext [\s!cs] [\v!table=Tabulka ] +\setuplabeltext [\s!sk] [\v!table=Tabu\lcaron ka ] +\setuplabeltext [\s!hr] [\v!table=T\aacute bl\aacute zat ] % [\v!table=Tablica ] +\setuplabeltext [\s!sl] [\v!table=Tabela ] + +\setuplabeltext [\s!pl] [\v!figure=Ilustracja ] +\setuplabeltext [\s!cs] [\v!figure=Obr\aacute zek ] +\setuplabeltext [\s!sk] [\v!figure=Obr\aacute zok ] +\setuplabeltext [\s!hr] [\v!figure=Slika ] +\setuplabeltext [\s!sl] [\v!figure=Slika ] + +\setuplabeltext [\s!pl] [\v!intermezzo=Intermezzo ] +\setuplabeltext [\s!cs] [\v!intermezzo=Intermezzo ] +\setuplabeltext [\s!sk] [\v!intermezzo=Intermezzo ] +\setuplabeltext [\s!hr] [\v!intermezzo=Intermezzo ] +\setuplabeltext [\s!sl] [\v!intermezzo=Intermezzo ] + +\setuplabeltext [\s!pl] [\v!graphic=Grafika ] +\setuplabeltext [\s!cs] [\v!graphic=Graf ] +\setuplabeltext [\s!sk] [\v!graphic=Graf ] +\setuplabeltext [\s!hr] [\v!graphic=Slika ] +\setuplabeltext [\s!sl] [\v!graphic=Slika ] + +\setuplabeltext [\s!pl] [\v!chapter=] % Rozdzia\l +\setuplabeltext [\s!cs] [\v!chapter=] % Kapitola +\setuplabeltext [\s!sk] [\v!chapter=] % Kapitola +\setuplabeltext [\s!hr] [\v!chapter=] % Rozdzia\l +\setuplabeltext [\s!sl] [\v!chapter=] % Poglavje + +\setuplabeltext [\s!pl] [\v!section=] % Podrozdzia\l +\setuplabeltext [\s!cs] [\v!section=] % Sekce +\setuplabeltext [\s!sk] [\v!section=] % Sekcia +\setuplabeltext [\s!hr] [\v!section=] % Podrozdzia\l +\setuplabeltext [\s!sl] [\v!section=] + +\setuplabeltext [\s!pl] [\v!subsection=] +\setuplabeltext [\s!cs] [\v!subsection=] % Podsekce +\setuplabeltext [\s!sk] [\v!subsection=] % Podsekcia +\setuplabeltext [\s!hr] [\v!subsection=] +\setuplabeltext [\s!sl] [\v!subsection=] + +\setuplabeltext [\s!pl] [\v!subsubsection=] +\setuplabeltext [\s!cs] [\v!subsubsection=] % Podpodsekce +\setuplabeltext [\s!sk] [\v!subsubsection=] % Podpodsekcia +\setuplabeltext [\s!hr] [\v!subsubsection=] +\setuplabeltext [\s!sl] [\v!subsubsection=] + +\setuplabeltext [\s!pl] [\v!subsubsubsection=] +\setuplabeltext [\s!cs] [\v!subsubsubsection=] % Podpodpodsekce +\setuplabeltext [\s!sk] [\v!subsubsubsection=] % Podpodpodsekcia +\setuplabeltext [\s!hr] [\v!subsubsubsection=] +\setuplabeltext [\s!sl] [\v!subsubsubsection=] + +\setuplabeltext [\s!pl] [\v!appendix=] % Dodatek +\setuplabeltext [\s!cs] [\v!appendix=P\rcaron\iacute loha ] +\setuplabeltext [\s!sk] [\v!appendix=Pr\iacute loha ] +\setuplabeltext [\s!hr] [\v!appendix=Dodatak ] +\setuplabeltext [\s!sl] [\v!appendix=Dodatek ] + +\setuplabeltext [\s!pl] [\v!part=Ust\eogonek p ] +\setuplabeltext [\s!cs] [\v!part=\Ccaron \aacute st ] +\setuplabeltext [\s!sk] [\v!part=\Ccaron as\tcaron{} ] +\setuplabeltext [\s!hr] [\v!part=Dio ] +\setuplabeltext [\s!sl] [\v!part=Del ] + +\setuplabeltext [\s!pl] [\v!line=wiersz ] +\setuplabeltext [\s!cs] [\v!line=\rcaron\aacute dek ] +\setuplabeltext [\s!sk] [\v!line=riadok ] +\setuplabeltext [\s!hr] [\v!line=red ] +\setuplabeltext [\s!sl] [\v!line=vrstica ] + +\setuplabeltext [\s!pl] [\v!lines=wiersze ] +\setuplabeltext [\s!cs] [\v!lines=\rcaron\aacute dky ] +\setuplabeltext [\s!sk] [\v!lines=riadky ] +\setuplabeltext [\s!hr] [\v!lines=redovi ] +\setuplabeltext [\s!sl] [\v!lines=vrstice ] + +\setuplabeltext [\s!pl] [\v!january=stycznia] +\setuplabeltext [\s!pl] [\v!february=lutego] +\setuplabeltext [\s!pl] [\v!march=marca] +\setuplabeltext [\s!pl] [\v!april=kwietnia] +\setuplabeltext [\s!pl] [\v!may=maja] +\setuplabeltext [\s!pl] [\v!june=czerwca] +\setuplabeltext [\s!pl] [\v!july=lipca] +\setuplabeltext [\s!pl] [\v!august=sierpnia] +\setuplabeltext [\s!pl] [\v!september=wrze\sacute nia] +\setuplabeltext [\s!pl] [\v!october=pa\zacute dziernika] +\setuplabeltext [\s!pl] [\v!november=listopada] +\setuplabeltext [\s!pl] [\v!december=grudnia] + +\setuplabeltext [\s!cs] [\v!january=ledna] +\setuplabeltext [\s!cs] [\v!february=\uacute nora] +\setuplabeltext [\s!cs] [\v!march=b\rcaron ezna] +\setuplabeltext [\s!cs] [\v!april=dubna] +\setuplabeltext [\s!cs] [\v!may=kv\ecaron tna] +\setuplabeltext [\s!cs] [\v!june=\ccaron ervna] +\setuplabeltext [\s!cs] [\v!july=\ccaron ervence] +\setuplabeltext [\s!cs] [\v!august=srpna] +\setuplabeltext [\s!cs] [\v!september=z\aacute\rcaron\iacute{}] +\setuplabeltext [\s!cs] [\v!october=\rcaron\iacute jna] +\setuplabeltext [\s!cs] [\v!november=listopadu] +\setuplabeltext [\s!cs] [\v!december=prosince] + +\setuplabeltext [\s!sk] [\v!january=janu\aacute ra] +\setuplabeltext [\s!sk] [\v!february=febru\aacute ra] +\setuplabeltext [\s!sk] [\v!march=marca] +\setuplabeltext [\s!sk] [\v!april=apr\iacute la] +\setuplabeltext [\s!sk] [\v!may=m\aacute ja] +\setuplabeltext [\s!sk] [\v!june=j\uacute na] +\setuplabeltext [\s!sk] [\v!july=j\uacute la] +\setuplabeltext [\s!sk] [\v!august=augusta] +\setuplabeltext [\s!sk] [\v!september=septembra] +\setuplabeltext [\s!sk] [\v!october=okt\oacute bra] +\setuplabeltext [\s!sk] [\v!november=novembra] +\setuplabeltext [\s!sk] [\v!december=decembra] + +\setuplabeltext [\s!hr] [\v!january=sije\ccaron anj] +\setuplabeltext [\s!hr] [\v!february=velja\ccaron a] +\setuplabeltext [\s!hr] [\v!march=o\zcaron ujak] +\setuplabeltext [\s!hr] [\v!april=travanj] +\setuplabeltext [\s!hr] [\v!may=svibanj] +\setuplabeltext [\s!hr] [\v!june=lipanj] +\setuplabeltext [\s!hr] [\v!july=srpanj] +\setuplabeltext [\s!hr] [\v!august=kolovoz] +\setuplabeltext [\s!hr] [\v!september=rujan] +\setuplabeltext [\s!hr] [\v!october=listopad] +\setuplabeltext [\s!hr] [\v!november=studeni] +\setuplabeltext [\s!hr] [\v!december=prosinac] + +\setuplabeltext [\s!sl] [\v!january=januar] +\setuplabeltext [\s!sl] [\v!february=februar] +\setuplabeltext [\s!sl] [\v!march=marec] +\setuplabeltext [\s!sl] [\v!april=april] +\setuplabeltext [\s!sl] [\v!may=maj] +\setuplabeltext [\s!sl] [\v!june=junij] +\setuplabeltext [\s!sl] [\v!july=julij] +\setuplabeltext [\s!sl] [\v!august=avgust] +\setuplabeltext [\s!sl] [\v!september=september] +\setuplabeltext [\s!sl] [\v!october=oktober] +\setuplabeltext [\s!sl] [\v!november=november] +\setuplabeltext [\s!sl] [\v!december=december] + +\setuplabeltext [\s!pl] [\v!sunday=niedziela] +\setuplabeltext [\s!pl] [\v!monday=poniedzia\lstroke ek] +\setuplabeltext [\s!pl] [\v!tuesday=wtorek] +\setuplabeltext [\s!pl] [\v!wednesday=\sacute roda] +\setuplabeltext [\s!pl] [\v!thursday=czwartek] +\setuplabeltext [\s!pl] [\v!friday=pi\aogonek tek] +\setuplabeltext [\s!pl] [\v!saturday=sobota] + +% new +\setuplabeltext [\s!cs] [\v!sunday=ned\ecaron le] +\setuplabeltext [\s!cs] [\v!monday=pond\ecaron l\iacute] +\setuplabeltext [\s!cs] [\v!tuesday=\uacute ter\yacute] +\setuplabeltext [\s!cs] [\v!wednesday=st\rcaron eda] +\setuplabeltext [\s!cs] [\v!thursday=\ccaron tvrtek] +\setuplabeltext [\s!cs] [\v!friday=p\aacute tek] +\setuplabeltext [\s!cs] [\v!saturday=sobota] + +\setuplabeltext [\s!hr] [\v!sunday=nedjelja] +\setuplabeltext [\s!hr] [\v!monday=ponedjeljak] +\setuplabeltext [\s!hr] [\v!tuesday=utorak] +\setuplabeltext [\s!hr] [\v!wednesday=srijeda] +\setuplabeltext [\s!hr] [\v!thursday=\ccaron etvrtak] +\setuplabeltext [\s!hr] [\v!friday=petak] +\setuplabeltext [\s!hr] [\v!saturday=subota] + +\setuplabeltext [\s!sl] [\v!sunday=nedelja] +\setuplabeltext [\s!sl] [\v!monday=ponedeljek] +\setuplabeltext [\s!sl] [\v!tuesday=torek] +\setuplabeltext [\s!sl] [\v!wednesday=sreda] +\setuplabeltext [\s!sl] [\v!thursday=\ccaron etrtek] +\setuplabeltext [\s!sl] [\v!friday=petek] +\setuplabeltext [\s!sl] [\v!saturday=sobota] + +%D Rather new ... +%\installlanguage +% [\s!cs] +% [\c!spacing=\v!packed, +% \c!leftsentence=---, +% \c!rightsentence=---, +% \c!leftsubsentence=---, +% \c!rightsubsentence=---, +% \c!leftquote=\lowerleftsingleninequote, +% \c!rightquote=\upperrightsinglesixquote, +% \c!leftquotation=\lowerleftdoubleninequote, +% \c!rightquotation=\upperrightdoublesixquote, +% \c!date={\v!day,\ ,\v!month,\ ,\v!year}] + +\setuplabeltext [\s!sl] [\v!page=stran ] +\setuplabeltext [\s!sl] [\v!atpage=na strani ] +\setuplabeltext [\s!sl] [\v!hencefore=glej zgoraj] +\setuplabeltext [\s!sl] [\v!hereafter=glej spodaj] +\setuplabeltext [\s!sl] [\v!see=glej ] + +% new +\setuplabeltext [\s!cs] [\v!page=strana ] +\setuplabeltext [\s!cs] [\v!atpage=na stran\ecaron\ ] +\setuplabeltext [\s!cs] [\v!hencefore=viz v\yacute\scaron e ] +\setuplabeltext [\s!cs] [\v!hereafter=viz n\iacute\zcaron e ] +\setuplabeltext [\s!cs] [\v!see=viz ] + +%D \ShowAllLanguageValues [\s!pl] [polish] {Polish} {furniture} +%D \ShowAllLanguageValues [\s!cs] [czech] {Czech} {mate} +%D \ShowAllLanguageValues [\s!sk] [slovak] {Slovakian} {face} +%D \ShowAllLanguageValues [\s!hr] [croatian] {Croatian} {heartthrob} +%D \ShowAllLanguageValues [\s!sl] [slovenian] {Slovenian} {mountains} + +%D A present from Brooks Moses and Hans Hagen for Mojca Miklavec: + +\def\doconvertsloveniancharacters{\dodoconvertcharacters{25}} + +\def\sloveniancharacters{\doconvertsloveniancharacters\sloveniancharacter} +\def\slovenianCharacters{\doconvertsloveniancharacters\slovenianCharacter} + +%D Define general-purpose macros for Slovenian character enumerations: + +\defineconversion [sloveniancharacter] [\sloveniancharacter] +\defineconversion [slovenianCharacter] [\slovenianCharacter] + +\defineconversion [sloveniancharacters] [\sloveniancharacters] +\defineconversion [slovenianCharacters] [\slovenianCharacters] + +%D Define these as the general character enumeration when +%D language is Slovenian. If you feel uncomfortable with this, +%D mail Mojca, since she promised to to take the heat. + +\defineconversion [sl] [character] [\sloveniancharacter] +\defineconversion [sl] [Character] [\slovenianCharacter] + +\defineconversion [sl] [characters] [\sloveniancharacters] +\defineconversion [sl] [Characters] [\slovenianCharacters] + +\defineconversion [sl] [a] [\sloveniancharacters] +\defineconversion [sl] [A] [\slovenianCharacters] +\defineconversion [sl] [AK] [\smallcapped\sloveniancharacters] +\defineconversion [sl] [KA] [\smallcapped\sloveniancharacters] + +% this will become more generic : \languagecharacters{sl}{..} + +\let\sloveniancharacter\gobbleoneargument +\let\slovenianCharacter\gobbleoneargument + +%D Plugins: + +\loadmarkfile{lang-sla} + +\protect \endinput diff --git a/tex/context/base/lang-spa.tex b/tex/context/base/lang-spa.tex new file mode 100644 index 000000000..f6e22aa51 --- /dev/null +++ b/tex/context/base/lang-spa.tex @@ -0,0 +1,74 @@ +%D \module +%D [ file=lang-spa, +%D version=2002.04.17, +%D title=\CONTEXT\ Language 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 Language Macros / Spacing} + +%D This module was created in the process of enhancing +%D support for French (with the help of Daniel Flipo). + +\unprotect + +\definehspace [\s!fr] [quotation] [\flexiblespaceamount{.8}{.3}{.8}] +\definehspace [\s!fr] [sentence] [\fixedspaceamount{1}] + +%definehspace [\s!fr] [quote] [\flexiblespaceamount{.8}{.3}{.8}] +%definehspace [\s!fr] [speech] [\flexiblespaceamount{.8}{.3}{.8}] + +\definehspace [\s!fr] [interquotation] [\zeropoint] +\definehspace [\s!fr] [intersentence] [\zeropoint] + +\definehspace [\string :] [\zeropoint] +\definehspace [\string ;] [\zeropoint] +\definehspace [\string !] [\zeropoint] +\definehspace [\string ?] [\zeropoint] + +\definehspace [\s!fr] [\string :] [\spaceamount] +\definehspace [\s!fr] [\string ;] [.16667em] +\definehspace [\s!fr] [\string !] [.16667em] +\definehspace [\s!fr] [\string ?] [.16667em] + +%D Alternative discretionary handlers: + +\definetextmodediscretionary : + {\removeunwantedspaces\prewordbreak\kern\hspaceamount\currentlanguage{:}:} + +\definetextmodediscretionary ; + {\removeunwantedspaces\prewordbreak\kern\hspaceamount\currentlanguage{;};} + +\definetextmodediscretionary ? + {\removeunwantedspaces\prewordbreak\kern\hspaceamount\currentlanguage{?}?} + +\definetextmodediscretionary ! + {\removeunwantedspaces\prewordbreak\kern\hspaceamount\currentlanguage{!}!} + +%D \startbuffer +%D \mainlanguage[en] \quotation{test \quotation{test} test}\par +%D \mainlanguage[nl] \quotation{test \quotation{test} test}\par +%D \mainlanguage[fr] \quotation{test \quotation{test} test}\par +%D +%D \mainlanguage[en] \quotation{\quotation{test} test}\par +%D \mainlanguage[nl] \quotation{\quotation{test} test}\par +%D \mainlanguage[fr] \quotation{\quotation{test} test}\par +%D +%D \mainlanguage[en] |<|test |<|test|>| test|>| \par +%D \mainlanguage[nl] |<|test |<|test|>| test|>| \par +%D \mainlanguage[fr] |<|test |<|test|>| test|>| \par +%D +%D \mainlanguage[en] |<||<|test|>| test|>| \par +%D \mainlanguage[nl] |<||<|test|>| test|>| \par +%D \mainlanguage[fr] |<||<|test|>| test|>| \par +%D \stopbuffer +%D +%D \typebuffer {\getbuffer} + +\protect \endinput 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-ura.tex b/tex/context/base/lang-ura.tex new file mode 100644 index 000000000..a2bcd3d2b --- /dev/null +++ b/tex/context/base/lang-ura.tex @@ -0,0 +1,158 @@ +%D \module +%D [ file=lang-sla, +%D version=1997.09.03, +%D title=\CONTEXT\ Language Macros, +%D subtitle=Uralic Languages, +%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. + +% Todo: replace \'.. by \namedglyph + +\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 +%D on, corrections were made by users. If you have suggestions, +%D or feel that your name missing here, don't hesitate to send +%D us an email. +%D +%D \starttabulate[|lB|l|] +%D \NC Finnish \NC \NC \NR +%D \NC Hungarian \NC Balazs Nagy \NC \NR +%D \stoptabulate + +% Cheremiss, Estonian, Finnish, Karelian, Laap, Mordvinian, +% Permian tongues, Hungarian, Ostyak, Vogul, Samoyed + +\unprotect + +\installlanguage + [\s!fi] + [\c!spacing=\v!packed, + \c!leftsentence=---, + \c!rightsentence=---, + \c!leftsubsentence=---, + \c!rightsubsentence=---, + \c!leftquote=\upperleftsinglesixquote, + \c!rightquote=\upperrightsingleninequote, + \c!leftquotation=\upperleftdoublesixquote, + \c!rightquotation=\upperrightdoubleninequote, + \c!date={\v!year,\ ,\v!month,\ ,\v!day}] + +\installlanguage + [\s!hu] + [\c!spacing=\v!packed, + \c!leftsentence=---, + \c!rightsentence=---, + \c!leftsubsentence=---, + \c!rightsubsentence=---, + \c!leftquote=\lowerleftsingleninequote, + \c!rightquote=\upperrightsingleninequote, + \c!leftquotation=\lowerleftdoubleninequote, + \c!rightquotation=\upperrightdoubleninequote, + \c!date={\v!year,.,\ ,\v!month,\ ,\v!day,.}, + \s!mapping=ec, + \s!encoding=ec] + +\installlanguage [finish] [\s!fi] +\installlanguage [hungarian] [\s!hu] + +\setupheadtext [\s!fi] [\v!content=Sis\"allys] +\setupheadtext [\s!fi] [\v!tables=Taulukkoj] +\setupheadtext [\s!fi] [\v!figures=Kuvi] +\setupheadtext [\s!fi] [\v!graphics=Grafiikkaoi] +\setupheadtext [\s!fi] [\v!intermezzi=Intermezzos] +\setupheadtext [\s!fi] [\v!index=Indeksiluku] +\setupheadtext [\s!fi] [\v!abbreviations=Lyhennyksi] +\setupheadtext [\s!fi] [\v!logos=Vertauskuva] +\setupheadtext [\s!fi] [\v!units=Yksik\"ot] + +\setupheadtext [\s!hu] [\v!content=Tartalom] +\setupheadtext [\s!hu] [\v!tables=T\'abl\'azatok] +\setupheadtext [\s!hu] [\v!figures=\'Abr\'ak] +\setupheadtext [\s!hu] [\v!graphics=Grafik\'ak] +\setupheadtext [\s!hu] [\v!intermezzi=Intermezzok] +\setupheadtext [\s!hu] [\v!index=Index] +\setupheadtext [\s!hu] [\v!abbreviations=R\"ovid\'it\'esek] +\setupheadtext [\s!hu] [\v!logos=Fejl\'ecek] +\setupheadtext [\s!hu] [\v!units=M\'ert\'ekegys\'egek] + +\setuplabeltext [\s!fi] [\v!table=Taulukko ] +\setuplabeltext [\s!fi] [\v!figure=Kuva ] +\setuplabeltext [\s!fi] [\v!intermezzo=Intermezzo ] +\setuplabeltext [\s!fi] [\v!graphic=Grafiikka ] +\setuplabeltext [\s!fi] [\v!chapter=] +\setuplabeltext [\s!fi] [\v!section=] +\setuplabeltext [\s!fi] [\v!subsection=] +\setuplabeltext [\s!fi] [\v!subsubsection=] +\setuplabeltext [\s!fi] [\v!subsubsubsection=] +\setuplabeltext [\s!fi] [\v!appendix=] +\setuplabeltext [\s!fi] [\v!part=Osa ] +\setuplabeltext [\s!fi] [\v!line=rivi ] +\setuplabeltext [\s!fi] [\v!lines=rivie ] + +\setuplabeltext [\s!hu] [\v!table={,.~t\'abl\'azat:}] +\setuplabeltext [\s!hu] [\v!figure={,.~\'abra:}] +\setuplabeltext [\s!hu] [\v!intermezzo={,.~intermezzo:}] +\setuplabeltext [\s!hu] [\v!graphic={,.~k\'ep:}] +\setuplabeltext [\s!hu] [\v!chapter={,.~fejezet:}] +\setuplabeltext [\s!hu] [\v!section={,.}] +\setuplabeltext [\s!hu] [\v!subsection={,.}] +\setuplabeltext [\s!hu] [\v!subsubsection={,.}] +\setuplabeltext [\s!hu] [\v!subsubsubsection={,.}] +\setuplabeltext [\s!hu] [\v!appendix=] +\setuplabeltext [\s!hu] [\v!part={,.~r\'esz:}] +\setuplabeltext [\s!hu] [\v!line={,.~sor:}] +\setuplabeltext [\s!hu] [\v!lines=sorok] + +\setuplabeltext [\s!fi] [\v!january=tammikuu] +\setuplabeltext [\s!fi] [\v!february=helmikuu] +\setuplabeltext [\s!fi] [\v!march=maaliskuu] +\setuplabeltext [\s!fi] [\v!april=huhtikuu] +\setuplabeltext [\s!fi] [\v!may=toukokuu] +\setuplabeltext [\s!fi] [\v!june=kes\"akuu] +\setuplabeltext [\s!fi] [\v!july=hein\"akuu] +\setuplabeltext [\s!fi] [\v!august=elokuu] +\setuplabeltext [\s!fi] [\v!september=syyskuu] +\setuplabeltext [\s!fi] [\v!october=lokakuu] +\setuplabeltext [\s!fi] [\v!november=marraskuu] +\setuplabeltext [\s!fi] [\v!december=joulukuu] + +\setuplabeltext [\s!hu] [\v!january=janu\'ar] +\setuplabeltext [\s!hu] [\v!february=febru\'ar] +\setuplabeltext [\s!hu] [\v!march=m\'arcius] +\setuplabeltext [\s!hu] [\v!april=\'aprilis] +\setuplabeltext [\s!hu] [\v!may=m\'ajus] +\setuplabeltext [\s!hu] [\v!june=j\'unius] +\setuplabeltext [\s!hu] [\v!july=j\'ulius] +\setuplabeltext [\s!hu] [\v!august=augusztus] +\setuplabeltext [\s!hu] [\v!september=szeptember] +\setuplabeltext [\s!hu] [\v!october=okt\'ober] +\setuplabeltext [\s!hu] [\v!november=november] +\setuplabeltext [\s!hu] [\v!december=december] + +\setuplabeltext [\s!fi] [\v!sunday=sunnuntai] +\setuplabeltext [\s!fi] [\v!monday=maanantai] +\setuplabeltext [\s!fi] [\v!tuesday=tiistai] +\setuplabeltext [\s!fi] [\v!wednesday=keskiviikko] +\setuplabeltext [\s!fi] [\v!thursday=torstai] +\setuplabeltext [\s!fi] [\v!friday=perjantai] +\setuplabeltext [\s!fi] [\v!saturday=lauantai] + +\setuplabeltext [\s!hu] [\v!sunday=vas\'arnap] +\setuplabeltext [\s!hu] [\v!monday=h\'etf\H{o}] +\setuplabeltext [\s!hu] [\v!tuesday=kedd] +\setuplabeltext [\s!hu] [\v!wednesday=szerda] +\setuplabeltext [\s!hu] [\v!thursday=cs\"ut\"ort\"ok] +\setuplabeltext [\s!hu] [\v!friday=p\'entek] +\setuplabeltext [\s!hu] [\v!saturday=szombat] + +%D \ShowAllLanguageValues [\s!fi] [finnish] {Finnish} {phone} +%D \ShowAllLanguageValues [\s!hu] [hungarian] {Hungarian} {rhapsody} + +\protect \endinput diff --git a/tex/context/base/lang-url.lua b/tex/context/base/lang-url.lua new file mode 100644 index 000000000..b0a71ec67 --- /dev/null +++ b/tex/context/base/lang-url.lua @@ -0,0 +1,101 @@ +if not modules then modules = { } end modules ['lang-url'] = { + version = 1.001, + comment = "companion to lang-url.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local utf = unicode.utf8 + +local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues +local utfbyte, utfgsub = utf.byte, utf.gsub + +local ctxcatcodes, texsprint = tex.ctxcatcodes, tex.sprint + +commands = commands or { } + +--[[ +

Hyphenating 's is somewhat tricky and a matter of taste. I did +consider using a dedicated hyphenation pattern or dealing with it by node +parsing, but the following solution suits as well. After all, we're mostly +dealing with characters.

+]]-- + +commands.hyphenatedurl = commands.hyphenatedurl or { } + +local hyphenatedurl = commands.hyphenatedurl + +hyphenatedurl.characters = { + ["!"] = 1, + ["\""] = 1, + ["#"] = 1, + ["$"] = 1, + ["%"] = 1, + ["&"] = 1, + ["("] = 1, + ["*"] = 1, + ["+"] = 1, + [","] = 1, + ["-"] = 1, + ["."] = 1, + ["/"] = 1, + [":"] = 1, + [";"] = 1, + ["<"] = 1, + ["="] = 1, + [">"] = 1, + ["?"] = 1, + ["@"] = 1, + ["["] = 1, + ["\\"] = 1, + ["^"] = 1, + ["_"] = 1, + ["`"] = 1, + ["{"] = 1, + ["|"] = 1, + ["~"] = 1, + + ["'"] = 2, + [")"] = 2, + ["]"] = 2, + ["}"] = 2 +} + +hyphenatedurl.lefthyphenmin = 2 +hyphenatedurl.righthyphenmin = 3 +hyphenatedurl.discretionary = nil + +local chars = hyphenatedurl.characters + +function hyphenatedurl.action(str, left, right, disc) + local n = 0 + local b = math.max( left or hyphenatedurl.lefthyphenmin, 2) + local e = math.min(#str-(right or hyphenatedurl.righthyphenmin)+2,#str) + local d = disc or hyphenatedurl.discretionary + for s in utfcharacters(str) do + n = n + 1 + if s == d then + texsprint(ctxcatcodes,"\\d{",utfbyte(s),"}") + else + local c = chars[s] + if not c or n<=b or n>=e then + texsprint(ctxcatcodes,"\\n{",utfbyte(s),"}") + elseif c == 1 then + texsprint(ctxcatcodes,"\\b{",utfbyte(s),"}") + elseif c == 2 then + texsprint(ctxcatcodes,"\\a{",utfbyte(s),"}") + end + end + end +end + +-- todo, no interface in mkiv yet + +function hyphenatedurl.setcharacters(str,value) -- 1, 2 == before, after + for s in utfcharacters(str) do + chars[s] = value or 1 + end +end + +-- .hyphenatedurl.setcharacters("')]}",2) diff --git a/tex/context/base/lang-url.mkii b/tex/context/base/lang-url.mkii new file mode 100644 index 000000000..fdf530b45 --- /dev/null +++ b/tex/context/base/lang-url.mkii @@ -0,0 +1,306 @@ +%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. + +\unprotect + +%D This is rather old code. The following solution was used +%D for a long time and is kind of built-up over the years. + +\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 +% 1 => . : na, rest voor +% 2 => alles na +% 3 => alles voor + +% \bgroup \catcode`\~=\active \catcode`\/=\active +% +% \unexpanded\gdef\hyphenatedurl#1% {}{} handles accents +% {\bgroup +% \ifnum\hyphenpenalty<10000 \else +% \def\discretionary##1##2##3{##1\allowbreak##2}% +% \fi +% \obeyhyphens +% \def\splitbefore##1% +% {\setbox\scratchbox=\hbox{##1{}{}}% +% \ifcase\urlsplitmode +% \box\scratchbox +% \or +% \postwordbreak\box\scratchbox\prewordbreak +% \or +% \prewordbreak\discretionary{\box\scratchbox}{}{\box\scratchbox}\prewordbreak +% \else +% \postwordbreak\box\scratchbox\prewordbreak +% \fi}% +% \def\splitafter##1% +% {\ifcase\urlsplitmode +% ##1{}{}% +% \or +% \prewordbreak\discretionary{##1{}{}}{}{##1{}{}}\prewordbreak +% \or +% \prewordbreak\discretionary{##1{}{}}{}{##1{}{}}\prewordbreak +% \else +% \prewordbreak\discretionary{}{##1{}{}}{##1{}{}}\prewordbreak +% \fi}% +% \def\splitanyway##1% +% {\prewordbreak##1\prewordbreak}% +% \def\flushurl% +% {\savedurl\let\savedurl\empty}% +% \def\\% +% {\spliturl\#}% +% \let\~=\lettertilde\let~=\~% +% \let\/=\letterslash\let/=\/% +% \let\savedurl\empty +% \scratchcounter\zerocount % used for hyphenmethod +% \handletokens#1\with\scanurl\savedurl +% \egroup} +% +% \egroup + +% \chardef\urlhyphenmethod=0 + +% \def\scanurl#1% +% {\advance\scratchcounter\plusone +% \ifx#1\blankspace +% \flushurl\splitanyway\normalspace +% \else\ifx#1\ % +% \flushurl\splitanyway\normalspace +% \else\ifx#1\space +% \flushurl\splitanyway\normalspace +% \else\ifx#1\~% +% \flushurl\splitbefore\~% +% \else\ifx#1\#% +% \flushurl\splitbefore\#% +% \else\ifx#1\&% +% \flushurl\splitbefore\&% +% \else\ifx#1\%% +% \flushurl\splitbefore\%% +% \else\ifx#1\_% +% \flushurl\splitbefore\_% +% \else\if\noexpand#1\relax +% #1% +% \else\ifnum\catcode`#1=8 +% \flushurl\splitbefore\_% +% \else\ifnum\catcode`#1=6 +% \flushurl\splitbefore\#% +% \else\ifnum\catcode`#1=4 +% \flushurl\splitbefore\&% +% \else\expandafter\if\string#1\lettertilde +% \flushurl\splitbefore\~% +% \else\expandafter\if\string#1\letterpercent +% \flushurl\splitbefore\%% +% \else\expandafter\if\string#1\letterunderscore +% \flushurl\splitbefore\_% +% \else\expandafter\if\string#1\letterquestionmark +% \flushurl\splitafter\letterquestionmark +% \else\expandafter\if\string#1\letterat +% \flushurl\splitafter\letterat +% \else\expandafter\if\string#1\letterslash +% \edef\savedurl{\savedurl\letterslash}% +% \else\expandafter\if\string#1+% +% \flushurl\splitafter+% +% \else\expandafter\if\string#1:% +% \flushurl\splitafter:% +% \else\expandafter\if\string#1.% +% \flushurl\splitafter.% +% \else\expandafter\if\string#1(% +% \flushurl\splitbefore(% +% \else\expandafter\if\string#1)% +% \flushurl\splitafter)% +% \else +% \ifx\savedurl\empty\else +% \splitbefore\savedurl +% \let\savedurl\empty +% \fi +% \ifcase\urlhyphenmethod +% \string#1% +% \else +% \ifnum\scratchcounter>\plusthree % so, \http: will not break +% \edef\savedurl{\string#1}% +% \else +% \string#1% +% \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} + +%D The following approach takes more resources but is cleaner (after all, we now +%D have huge \TEX's. It's is basically a \TEX\ version of the \MKIV\ variant. + +\newtoks\everyhyphenatedurl + +\appendtoks + \let\&\letterampersand + \let\#\letterhash + \let\~\lettertilde + \let\\\letterbackslash + \let\$\letterdollar + \let\^\letterhat + \let\_\letterunderscore + \let\{\letterleftbrace + \let\}\letterrightbrace + \let\|\letterbar + \let~=\lettertilde + \let|=\letterbar +\to \everyhyphenatedurl + +\def\hyphenatedurlseparator{} % \periodcentered + +\def\dohyphenatedurlnormal#1{\char#1\relax}% +\def\dohyphenatedurlafter #1{\char#1\discretionary{}{\hyphenatedurlseparator}{}}% +\def\dohyphenatedurlbefore#1{\discretionary{\hyphenatedurlseparator}{}{}\char#1\relax}% + +% 0=normal 1=before 2=after + +\def\sethyphenatedurlnormal#1{\expandafter\chardef\csname url @ #1\endcsname\zerocount} +\def\sethyphenatedurlbefore#1{\expandafter\chardef\csname url @ #1\endcsname\plusone } +\def\sethyphenatedurlafter #1{\expandafter\chardef\csname url @ #1\endcsname\plustwo } + +\sethyphenatedurlbefore ! +\sethyphenatedurlbefore " +\sethyphenatedurlbefore \letterhash +\sethyphenatedurlbefore \letterdollar +\sethyphenatedurlbefore \letterpercent +\sethyphenatedurlbefore \letterampersand +\sethyphenatedurlbefore ( +\sethyphenatedurlbefore * +\sethyphenatedurlbefore + +\sethyphenatedurlbefore , +\sethyphenatedurlbefore - +\sethyphenatedurlbefore . +\sethyphenatedurlbefore / +\sethyphenatedurlbefore : +\sethyphenatedurlbefore ; +\sethyphenatedurlbefore < +\sethyphenatedurlbefore = +\sethyphenatedurlbefore > +\sethyphenatedurlbefore ? +\sethyphenatedurlbefore @ +\sethyphenatedurlbefore [ +\sethyphenatedurlbefore \letterbackslash +\sethyphenatedurlbefore ^ +\sethyphenatedurlbefore _ +\sethyphenatedurlbefore ` +\sethyphenatedurlbefore \letteropenbrace +\sethyphenatedurlbefore \letterbar +\sethyphenatedurlbefore \lettertilde + +\sethyphenatedurlafter ' +\sethyphenatedurlafter ) +\sethyphenatedurlafter ] +\sethyphenatedurlafter \letterclosebrace + +\unexpanded \def\hyphenatedurl#1% + {\dontleavehmode + \begingroup + \the\everyhyphenatedurl + \edef\ascii{#1}% + \expanded{\handletokens{\detokenize\expandafter{\ascii}}}\with\dohyphenatedurl + \endgroup} + +\def\dohyphenatedurl#1% + {\ifcase\executeifdefined{url @ #1}\zerocount\relax + \expandafter\dohyphenatedurlnormal + \or + \expandafter\dohyphenatedurlbefore + \or + \expandafter\dohyphenatedurlafter + \fi{\number`#1}} + +% maybe ... to be finished +% +% \def\hyphenatedstring#1% +% {\bgroup +% \nohyphens +% \def\next##1{##1\doif{##1}{-}{\allowbreak}}% +% \handletokens#1\with\next +% \egroup} +% +% {\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 new file mode 100644 index 000000000..0f6b23d05 --- /dev/null +++ b/tex/context/base/lang-url.mkiv @@ -0,0 +1,117 @@ +%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. + +\registerctxluafile{lang-url}{1.001} + +\unprotect + +%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 + +\appendtoks + \let\&\letterampersand + \let\#\letterhash + \let\~\lettertilde + \let\\\letterbackslash + \let\$\letterdollar + \let\^\letterhat + \let\_\letterunderscore + \let\{\letterleftbrace + \let\}\letterrightbrace + \let\|\letterbar + \let~=\lettertilde + \let|=\letterbar +\to \everyhyphenatedurl + +\def\hyphenatedurlseparator{} % \periodcentered + +\def\dohyphenatedurlafter #1{\char#1\discretionary{}{\hyphenatedurlseparator}{}}% +\def\dohyphenatedurlbefore#1{\discretionary{\hyphenatedurlseparator}{}{}\char#1\relax}% +\def\dohyphenatedurlnormal#1{\char#1\relax}% +\def\dohyphenatedurldisc #1{\discretionary{}{}{}} + +\def\sethyphenatedurlnormal #1{\ctxlua{commands.hyphenatedurl.setcharacters(\!!bs#1\!!es,0)}} +\def\sethyphenatedurlbefore #1{\ctxlua{commands.hyphenatedurl.setcharacters(\!!bs#1\!!es,1)}} +\def\sethyphenatedurlafter #1{\ctxlua{commands.hyphenatedurl.setcharacters(\!!bs#1\!!es,2)}} + +\def\hyphenatedurldiscretionary{} + +% \sethyphenatedurlafter{ABCDEF} + +\chardef\hyphenatedurllefthyphenmin = 3 +\chardef\hyphenatedurlrighthyphenmin = 3 + +\unexpanded \def\hyphenatedurl#1% + {\dontleavehmode + \begingroup + \the\everyhyphenatedurl + \let\n\dohyphenatedurlnormal + \let\b\dohyphenatedurlbefore + \let\a\dohyphenatedurlafter + \let\d\dohyphenatedurldisc + \normalexpanded{\noexpand\ctxlua{commands.hyphenatedurl.action( + \!!bs\noexpand\detokenize{#1}\!!es, + \number\hyphenatedurllefthyphenmin, + \number\hyphenatedurlrighthyphenmin, + "\hyphenatedurldiscretionary" + )}}% + \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-vn.tex b/tex/context/base/lang-vn.tex new file mode 100644 index 000000000..27d2a48a1 --- /dev/null +++ b/tex/context/base/lang-vn.tex @@ -0,0 +1,92 @@ +%D \module +%D [ file=lang-vn, +%D version=2004.11.22, % 1999.12.12, +%D title=\CONTEXT\ Language Macros, +%D subtitle=Vietnamese, +%D author={Han The Thanh \& Adam Lindsay \& 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 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 +%D on, corrections were made by users. If you have suggestions, +%D or feel that your name missing here, don't hesitate to send +%D us an email. +%D +%D \starttabulate[|lB|l|] +%D \NC Vietnamese \NC \THANH\ \NC \NR +%D \stoptabulate + +\unprotect + +\installlanguage + [\s!vi] + [\c!spacing=\v!packed, + \c!leftsentence=---, + \c!rightsentence=---, + \c!leftsubsentence=---, + \c!rightsubsentence=---, + \c!leftquote=\quoteleft, + \c!rightquote=\quoteright, + \c!leftquotation=\quotedblleft, + \c!rightquotation=\quotedblright, + \c!date={{ },dd,{/},mm,{/},yy}, + \s!mapping=t5, + \s!encoding=t5] + +\installlanguage [vietnamese] [\s!vi] + +\setupheadtext [\s!vi] [\v!content=M\udotbelow c l\udotbelow c] +\setupheadtext [\s!vi] [\v!tables=Danh s\aacute ch b\ahook ng] +\setupheadtext [\s!vi] [\v!figures=Danh s\aacute ch h\igrave nh v\etilde] +\setupheadtext [\s!vi] [\v!graphics=\Dstroke\ocircumflexgrave\ th\idotbelow] +\setupheadtext [\s!vi] [\v!intermezzi=Intermezzos] +\setupheadtext [\s!vi] [\v!index=Ch\ihook\ s\ocircumflexacute] +\setupheadtext [\s!vi] [\v!abbreviations=Ch\uhorntilde\ vi\ecircumflexacute t t\abreveacute t] +\setupheadtext [\s!vi] [\v!logos=Bi\ecircumflexhook u t\uhorn \ohorndotbelow ng] +\setupheadtext [\s!vi] [\v!units=\Dstroke\ohorn n v\idotbelow] + +\setuplabeltext [\s!vi] [\v!table=B\ahook ng ] +\setuplabeltext [\s!vi] [\v!figure=H\igrave nh ] +\setuplabeltext [\s!vi] [\v!intermezzo=intermezzo] +\setuplabeltext [\s!vi] [\v!graphic=\Dstroke\ocircumflexgrave\ th\idotbelow] +\setuplabeltext [\s!vi] [\v!chapter=Ch\uhorn \ohorn ng ] +\setuplabeltext [\s!vi] [\v!section=] % not set +\setuplabeltext [\s!vi] [\v!subsection=] % not set +\setuplabeltext [\s!vi] [\v!subsubsection=] % not set +\setuplabeltext [\s!vi] [\v!subsubsubsection=] % not set +\setuplabeltext [\s!vi] [\v!appendix=] % not set +\setuplabeltext [\s!vi] [\v!part=Ph\acircumflexgrave n ] +\setuplabeltext [\s!vi] [\v!line=d\ograve ng ] +\setuplabeltext [\s!vi] [\v!lines=d\ograve ng ] + +\setuplabeltext [\s!vi] [\v!sunday=ch\uhook\ nh\acircumflexdotbelow t] +\setuplabeltext [\s!vi] [\v!monday=th\uhornacute\ hai] +\setuplabeltext [\s!vi] [\v!tuesday=th\uhornacute\ ba] +\setuplabeltext [\s!vi] [\v!wednesday=th\uhornacute\ t\uhorn] +\setuplabeltext [\s!vi] [\v!thursday=th\uhornacute\ n\abreve m] +\setuplabeltext [\s!vi] [\v!friday=th\uhornacute\ s\aacute u] +\setuplabeltext [\s!vi] [\v!saturday=th\uhornacute\ b\ahook y] + +\setuplabeltext [\s!vi] [\v!january=th\aacute ng gi\ecircumflex ng] +\setuplabeltext [\s!vi] [\v!february=th\aacute ng hai] +\setuplabeltext [\s!vi] [\v!march=th\aacute ng ba] +\setuplabeltext [\s!vi] [\v!april=th\aacute ng t\uhorn] +\setuplabeltext [\s!vi] [\v!may=th\aacute ng n\abreve m] +\setuplabeltext [\s!vi] [\v!june=th\aacute ng s\aacute u] +\setuplabeltext [\s!vi] [\v!july=th\aacute ng b\ahook y] +\setuplabeltext [\s!vi] [\v!august=th\aacute ng t\aacute m] +\setuplabeltext [\s!vi] [\v!september=th\aacute ng ch\iacute n] +\setuplabeltext [\s!vi] [\v!october=th\aacute ng m\uhorn\ohorngrave i] +\setuplabeltext [\s!vi] [\v!november=th\aacute ng m\uhorn\ohorngrave i m\ocircumflexdotbelow t] +\setuplabeltext [\s!vi] [\v!december=th\aacute ng m\uhorn\ohorngrave i hai] + +%D \ShowAllLanguageValues [\s!vi] [vietnamese] {Vietnamese} {water||puppets} + +\protect \endinput diff --git a/tex/context/base/lang-wrd.lua b/tex/context/base/lang-wrd.lua new file mode 100644 index 000000000..095e44443 --- /dev/null +++ b/tex/context/base/lang-wrd.lua @@ -0,0 +1,225 @@ +if not modules then modules = { } end modules ['lang-ini'] = { + version = 1.001, + comment = "companion to lang-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local utf = unicode.utf8 +local lower, utfchar = string.lower, utf.char +local lpegmatch = lpeg.match + +languages.words = languages.words or { } + +local words = languages.words + +words.data = words.data or { } +words.enables = false +words.threshold = 4 + +local set_attribute = node.set_attribute +local unset_attribute = node.unset_attribute +local traverse_nodes = node.traverse +local node_id = node.id +local wordsdata = words.data +local chardata = characters.data + +local glyph_node = node_id('glyph') +local disc_node = node_id('disc') +local kern_node = node_id('kern') + +words.colors = { + ["known"] = "green", + ["unknown"] = "red", +} + +local spacing = lpeg.S(" \n\r\t") +local markup = lpeg.S("-=") +local lbrace = lpeg.P("{") +local rbrace = lpeg.P("}") +local disc = (lbrace * (1-rbrace)^0 * rbrace)^1 -- or just 3 times, time this +local word = lpeg.Cs((markup/"" + disc/"" + (1-spacing))^1) + +local loaded = { } -- we share lists + +function words.load(tag,filename) + local fullname = resolvers.find_file(filename,'other text file') or "" + if fullname ~= "" then + statistics.starttiming(languages) + local list = loaded[fullname] + if not list then + list = wordsdata[tag] or { } + local parser = (spacing + word/function(s) list[s] = true end)^0 + lpegmatch(parser,io.loaddata(fullname) or "") + loaded[fullname] = list + end + wordsdata[tag] = list + statistics.stoptiming(languages) + else + logs.report("languages","missing words file '%s'",filename) + end +end + +function words.found(id, str) + local tag = languages.numbers[id] + if tag then + local data = wordsdata[tag] + return data and (data[str] or data[lower(str)]) + else + return false + end +end + +-- The following code is an adaption of experimental code for +-- hyphenating and spell checking. + +local function mark_words(head,whenfound) -- can be optimized + local current, start, str, language, n = head, nil, "", nil, 0 + local function action() + if #str > 0 then + local f = whenfound(language,str) + if f then + for i=1,n do + f(start) + start = start.next + end + end + end + str, start, n = "", nil, 0 + end + while current do + local id = current.id + if id == glyph_node then + local a = current.lang + if a then + if a ~= language then + if start then + action() + end + language = a + end + elseif start then + action() + language = a + end + local components = current.components + if components then + start = start or current + n = n + 1 + for g in traverse_nodes(components) do + str = str .. utfchar(g.char) + end + else + local code = current.char + if chardata[code].uccode or chardata[code].lccode then + start = start or current + n = n + 1 + str = str .. utfchar(code) + elseif start then + action() + end + end + elseif id == disc_node then + if n > 0 then + n = n + 1 + end + elseif id == kern_node and current.subtype == 0 and start then + -- ok + elseif start then + action() + end + current = current.next + end + if start then + action() + end + return head +end + +words.methods = { } +words.method = 1 + +local methods = words.methods + +methods[1] = function(head, attribute, yes, nop) + local right, wrong = false, false + if yes then right = function(n) set_attribute(n,attribute,yes) end end + if nop then wrong = function(n) set_attribute(n,attribute,nop) end end + for n in traverse_nodes(head) do + unset_attribute(n,attribute) -- hm, not that selective (reset color) + end + local found, done = words.found, false + mark_words(head, function(language,str) + if #str < words.threshold then + return false + elseif found(language,str) then + done = true + return right + else + done = true + return wrong + end + end) + return head, done +end + +local list, dump = { }, false -- todo: per language + +local lower = characters.lower + +methods[2] = function(head, attribute) + dump = true + mark_words(head, function(language,str) + if #str >= words.threshold then + str = lower(str) + list[str] = (list[str] or 0) + 1 + end + end) + return head, true +end + +words.used = list + +function words.dump_used_words(name) + if dump then + logs.report("languages","saving list of used words in '%s'",name) + io.savedata(name,table.serialize(list)) + end +end + +local color = attributes.private('color') + +function words.check(head) + if words.enabled and head.next then + local colors = words.colors + local alc = attributes.list[color] + return methods[words.method](head, color, alc[colors.known], alc[colors.unknown]) + else + return head, false + end +end + +function words.enable(method) + tasks.enableaction("processors","languages.words.check") + words.method = method or words.method or 1 + words.enabled = true +end + +function words.disable() + words.enabled = false +end + +-- for the moment we hook it into the attribute handler + +--~ languagehacks = { } + +--~ function languagehacks.process(namespace,attribute,head) +--~ return languages.check(head) +--~ end + +--~ chars.plugins[chars.plugins+1] = { +--~ name = "language", +--~ namespace = languagehacks, +--~ processor = languagehacks.process +--~ } diff --git a/tex/context/base/lang-wrd.mkiv b/tex/context/base/lang-wrd.mkiv new file mode 100644 index 000000000..b6fc6a9d3 --- /dev/null +++ b/tex/context/base/lang-wrd.mkiv @@ -0,0 +1,54 @@ +%D \module +%D [ file=lang-wrd, +%D version=2006.XX.XX, +%D title=\CONTEXT\ Language Macros, +%D subtitle=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. + +%D Experimental. + +\writestatus{loading}{ConTeXt Language Macros / Checking} + +\registerctxluafile{lang-wrd}{1.001} + +\unprotect + +% \loadspellchecklist[en][words-en.txt] +% \loadspellchecklist[us][words-en.txt] +% \loadspellchecklist[nl][words-nl.txt] +% \setupspellchecking[state=start,method=1] +% +% \setupspellchecking[state=start,method=2] +% ... +% \typefile{\jobname.words} + +\def\loadspellchecklist + {\dodoubleempty\doloadspellchecklist} + +\def\doloadspellchecklist[#1][#2]% + {\ctxlua{languages.words.load("#1","#2")}} + +\unexpanded\def\setupspellchecking + {\dosingleargument\dosetupspellchecking} + +\unexpanded\def\setupspellchecking[#1]% todo colors + {\getparameters[\??wl][#1]% + \doifelse\@@wlstate\v!start + {\ctxlua{languages.words.enable(\@@wlmethod)}} + {\ctxlua{languages.words.disable()}}} + +\setupspellchecking + [\c!state=\v!stop, + \c!method=1] + +\appendtoks + \ctxlua{languages.words.dump_used_words("\jobname.words")}% +\to \everybye + +\protect \endinput diff --git a/tex/context/base/lpdf-ano.lua b/tex/context/base/lpdf-ano.lua new file mode 100644 index 000000000..e9e67e163 --- /dev/null +++ b/tex/context/base/lpdf-ano.lua @@ -0,0 +1,589 @@ +if not modules then modules = { } end modules ['lpdf-ano'] = { + version = 1.001, + comment = "companion to lpdf-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local tostring, format, rep = tostring, string.rep, string.format +local texcount = tex.count + +local trace_references = false trackers.register("references.references", function(v) trace_references = v end) +local trace_destinations = false trackers.register("references.destinations", function(v) trace_destinations = v end) +local trace_bookmarks = false trackers.register("references.bookmarks", function(v) trace_bookmarks = v end) + +local variables = interfaces.variables +local constants = interfaces.constants + +local nodeinjections = backends.pdf.nodeinjections +local codeinjections = backends.pdf.codeinjections +local registrations = backends.pdf.registrations + +jobreferences = jobreferences or { } +jobreferences.runners = jobreferences.runners or { } +jobreferences.specials = jobreferences.specials or { } +jobreferences.handlers = jobreferences.handlers or { } +jobreferences.executers = jobreferences.executers or { } + +local runners = jobreferences.runners +local specials = jobreferences.specials +local handlers = jobreferences.handlers +local executers = jobreferences.executers + +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfreference = lpdf.reference +local pdfunicode = lpdf.unicode +local pdfconstant = lpdf.constant +local pdfflushobject = lpdf.flushobject +local pdfreserveobject = lpdf.reserveobject +local pdfannotation = nodes.pdfannotation +local pdfdestination = nodes.pdfdestination + +local pdfpagereference = tex.pdfpageref + +local pdf_uri = pdfconstant("URI") +local pdf_gotor = pdfconstant("GoToR") +local pdf_goto = pdfconstant("GoTo") +local pdf_launch = pdfconstant("Launch") +local pdf_javascript = pdfconstant("JavaScript") +local pdf_link = pdfconstant("Link") +local pdf_n = pdfconstant("N") +local pdf_t = pdfconstant("T") +local pdf_border = pdfarray { 0, 0, 0 } + +local cache = { } + +local function pagedest(n) + local pd = cache[n] + if not pd then + local a = pdfarray { + pdfreference(pdfpagereference(n)), + pdfconstant("Fit") + } + pd = pdfreference(pdfflushobject(a)) + cache[n] = pd + end + return pd +end + +lpdf.pagedest = pagedest + +local defaultdestination = pdfarray { 0, pdfconstant("Fit") } + +local function link(url,filename,destination,page,actions) + if filename and filename ~= "" then + if file.basename(filename) == tex.jobname then + return false + else + filename = file.addsuffix(filename,"pdf") + end + end + if url and url ~= "" then + if filename and filename ~= "" then + if destination and destination ~= "" then + url = file.join(url,filename).."#"..destination + else + url = file.join(url,filename) + end + end + return pdfdictionary { + S = pdf_uri, + URI = url, + } + elseif filename and filename ~= "" then + return pdfdictionary { + S = pdf_gotor, -- can also be pdf_launch + F = filename, + D = (destination and destination ~= "" and destination), -- or defaultdestination, + NewWindow = (actions.newwindow and true) or nil, + } + elseif destination and destination ~= "" then + local realpage, p = texcount.realpageno, tonumber(page) + if not p then + -- sorry + elseif p > realpage then + texcount.referencepagestate = 3 + elseif p < realpage then + texcount.referencepagestate = 2 + else + texcount.referencepagestate = 1 + end + return pdfdictionary { + S = pdf_goto, + D = destination, + } + elseif page and page ~= "" then + local realpage, p = texcount.realpageno, tonumber(page) + if p then + if p > realpage then + texcount.referencepagestate = 3 + elseif p < realpage then + texcount.referencepagestate = 2 + else + texcount.referencepagestate = 1 + end + return pdfdictionary { + S = pdf_goto, + D = pagedest(p), + } + else + commands.writestatus("references","invalid page reference: %s",page or "?") + end + end + return false +end + +lpdf.link = link + +function lpdf.launch(program,parameters) + if program and program ~= "" then + local d = pdfdictionary { + S = pdf_launch, + F = program, + D = ".", + } + if parameters and parameters ~= "" then + d.P = parameters + end + return d + end +end + +function lpdf.javascript(name,arguments) + local script = javascripts.code(name,arguments) -- make into object (hash) + if script then + return pdfdictionary { + S = pdf_javascript, + JS = script, + } + end +end + +local function pdfaction(actions) + local nofactions = #actions + texcount.referencepagestate = 0 -- goodie, as we do all in the backend, we need to set it here too + if nofactions > 0 then + local a = actions[1] + local action = runners[a.kind] + if action then + action = action(a,actions) + end + if action then + local first = action + for i=2,nofactions do + local a = actions[i] + local what = runners[a.kind] + if what then + what = what(a,actions) + end + if what then + action.next = what + action = what + else + -- error + return nil + end + end + return first + end + end +end + +lpdf.pdfaction = pdfaction + +function codeinjections.prerollreference(actions) + local main = actions and pdfaction(actions) + if main then + main = pdfdictionary { + Subtype = pdf_link, + Border = pdf_border, + H = (not actions.highlight and pdf_n) or nil, + A = main, + -- does not work at all in spite of specification + -- OC = (actions.layer and lpdf.layerreferences[actions.layer]) or nil, + -- OC = backends.pdf.layerreference(actions.layer), + } + return main("A") -- todo: cache this, maybe weak + end +end + +-- local cache = { } -- no real gain in thsi +-- +-- function codeinjections.prerollreference(actions) +-- local main = actions and pdfaction(actions) +-- if main then +-- main = pdfdictionary { +-- Subtype = pdf_link, +-- Border = pdf_border, +-- H = (not actions.highlight and pdf_n) or nil, +-- A = main, +-- } +-- local cm = cache[main] +-- if not cm then +-- cm = "/A ".. tostring(pdfreference(pdfflushobject(main)) +-- cache[main] = cm +-- end +-- return cm +-- end +-- end + +function nodeinjections.reference(width,height,depth,prerolled) + if prerolled then + if swapdir then + width = - width + end + if trace_references then + logs.report("references","w=%s, h=%s, d=%s, a=%s",width,height,depth,prerolled) + end + return pdfannotation(width,height,depth,prerolled) + end +end + +function nodeinjections.destination(width,height,depth,name,view) + if swapdir then + width = - width + end + if trace_destinations then + logs.report("destinations","w=%s, h=%s, d=%s, n=%s, v=%s",width,height,depth,name,view or "no view") + end + return pdfdestination(width,height,depth,name,view) +end + +-- runners and specials + +local method = "internal" + +runners["inner"] = function(var,actions) + if method == "internal" then + local vir = var.i.references + local internal = vir and vir.internal + if internal then + var.inner = "aut:"..internal + end + end + return link(nil,nil,var.inner,var.r,actions) +end + +runners["inner with arguments"] = function(var,actions) + logs.report("references","todo: inner with arguments") + return false +end + +runners["outer"] = function(var,actions) + local file, url = jobreferences.checkedfileorurl(var.outer,var.outer) + return link(url,file,var.arguments,nil,actions) +end + +runners["outer with inner"] = function(var,actions) + local file = jobreferences.checkedfile(var.f) + return link(nil,file,var.inner,var.r,actions) +end + +runners["special outer with operation"] = function(var,actions) + local handler = specials[var.special] + return handler and handler(var,actions) +end + +runners["special outer"] = function(var,actions) + logs.report("references","todo: special outer") + return false +end + +runners["special"] = function(var,actions) + local handler = specials[var.special] + return handler and handler(var,actions) +end + +runners["outer with inner with arguments"] = function(var,actions) + logs.report("references","todo: outer with inner with arguments") + return false +end + +runners["outer with special and operation and arguments"] = function(var,actions) + logs.report("references","todo: outer with special and operation and arguments") + return false +end + +runners["outer with special"] = function(var,actions) + logs.report("references","todo: outer with special") + return false +end + +runners["outer with special and operation"] = function(var,actions) + logs.report("references","todo: outer with special and operation") + return false +end + +runners["special operation"] = runners["special"] +runners["special operation with arguments"] = runners["special"] + +function specials.internal(var,actions) -- better resolve in strc-ref + local i = tonumber(var.operation) + local v = jobreferences.internals[i] + if not v then + -- error + elseif method == "internal" then + -- named + return link(nil,nil,"aut:"..i,v.references.realpage,actions) + else + -- page + return link(nil,nil,nil,v.references.realpage,actions) + end +end + +specials.i = specials.internal + +function specials.page(var,actions) -- better resolve in strc-ref + local file = var.f + if file then + file = jobreferences.checkedfile(file) + return link(nil,file,nil,p or var.operation,actions) + else + local p = jobreferences.pages[var.operation] + if type(p) == "function" then + p = p() + end + return link(nil,nil,nil,p or var.operation,actions) + end +end + +-- todo, do this in references namespace ordered instead (this is an experiment) + +local splitter = lpeg.splitat(":") + +function specials.order(var,actions) -- jobreferences.specials ! + local operation = var.operation + if operation then + local kind, name, n = lpegmatch(splitter,operation) + local order = lists.ordered[kind] + order = order and order[name] + local v = order[tonumber(n)] + local r = v and v.references.realpage + if r then + var.operation = r -- brrr, but test anyway + return specials.page(var,actions) + end + end +end + +function specials.url(var,actions) + local url = jobreferences.checkedurl(var.operation) + return link(url,nil,var.arguments,nil,actions) +end + +function specials.file(var,actions) + local file = jobreferences.checkedfile(var.operation) + return link(nil,file,var.arguments,nil,actions) +end + +function specials.fileorurl(var,actions) + local file, url = jobreferences.checkedfileorurl(var.operation,var.operation) + return link(url,file,var.arguments,nil,actions) +end + +function specials.program(var,content) + local program = jobreferences.checkedprogram(var.operation) + return lpdf.launch(program,var.arguments) +end + +function specials.javascript(var) + return lpdf.javascript(var.operation,var.arguments) +end + +specials.JS = specials.javascript + +local pdf_named = pdfconstant("Named") + +executers.importform = pdfdictionary { S = pdf_named, N = pdfconstant("AcroForm:ImportFDF") } +executers.exportform = pdfdictionary { S = pdf_named, N = pdfconstant("AcroForm:ExportFDF") } +executers.first = pdfdictionary { S = pdf_named, N = pdfconstant("FirstPage") } +executers.previous = pdfdictionary { S = pdf_named, N = pdfconstant("PrevPage") } +executers.next = pdfdictionary { S = pdf_named, N = pdfconstant("NextPage") } +executers.last = pdfdictionary { S = pdf_named, N = pdfconstant("LastPage") } +executers.backward = pdfdictionary { S = pdf_named, N = pdfconstant("GoBack") } +executers.forward = pdfdictionary { S = pdf_named, N = pdfconstant("GoForward") } +executers.print = pdfdictionary { S = pdf_named, N = pdfconstant("Print") } +executers.exit = pdfdictionary { S = pdf_named, N = pdfconstant("Quit") } +executers.close = pdfdictionary { S = pdf_named, N = pdfconstant("Close") } +executers.save = pdfdictionary { S = pdf_named, N = pdfconstant("Save") } +executers.savenamed = pdfdictionary { S = pdf_named, N = pdfconstant("SaveAs") } +executers.opennamed = pdfdictionary { S = pdf_named, N = pdfconstant("Open") } +executers.help = pdfdictionary { S = pdf_named, N = pdfconstant("HelpUserGuide") } +executers.toggle = pdfdictionary { S = pdf_named, N = pdfconstant("FullScreen") } +executers.search = pdfdictionary { S = pdf_named, N = pdfconstant("Find") } +executers.searchagain = pdfdictionary { S = pdf_named, N = pdfconstant("FindAgain") } +executers.gotopage = pdfdictionary { S = pdf_named, N = pdfconstant("GoToPage") } +executers.query = pdfdictionary { S = pdf_named, N = pdfconstant("AcroSrch:Query") } +executers.queryagain = pdfdictionary { S = pdf_named, N = pdfconstant("AcroSrch:NextHit") } +executers.fitwidth = pdfdictionary { S = pdf_named, N = pdfconstant("FitWidth") } +executers.fitheight = pdfdictionary { S = pdf_named, N = pdfconstant("FitHeight") } + +local function fieldset(arguments) + -- [\dogetfieldset{#1}] + return nil +end + +function executers.resetform(arguments) + arguments = (type(arguments) == "table" and arguments) or aux.settings_to_array(arguments) + return pdfdictionary { + S = pdfconstant("ResetForm"), + Field = fieldset(arguments[1]) + } +end + +local formmethod = "post" -- "get" "post" +local formformat = "xml" -- "xml" "html" "fdf" + +-- bit 3 = html bit 6 = xml bit 4 = get + +local flags = { + get = { + html = 12, fdf = 8, xml = 40, + }, + post = { + html = 4, fdf = 0, xml = 32, + } +} + +function executers.submitform(arguments) + arguments = (type(arguments) == "table" and arguments) or aux.settings_to_array(arguments) + local flag = flags[formmethod] or flags.post + flag = (flag and (flag[formformat] or flag.xml)) or 32 -- default: post, xml + return pdfdictionary { + S = pdfconstant("ResetForm"), + F = fieldset(arguments[1]), + Field = fieldset(arguments[2]), + Flags = flag, + -- \PDFsubmitfiller + } +end + +function executers.hide(arguments) + return pdfdictionary { + S = pdfconstant("Hide"), + H = true, + T = arguments, + } +end + +function executers.show(arguments) + return pdfdictionary { + S = pdfconstant("Hide"), + H = false, + T = arguments, + } +end + +local pdf_movie = pdfconstant("Movie") +local pdf_start = pdfconstant("Start") +local pdf_stop = pdfconstant("Stop") +local pdf_resume = pdfconstant("Resume") +local pdf_pause = pdfconstant("Pause") + +local function movie_or_sound(operation,arguments) + arguments = (type(arguments) == "table" and arguments) or aux.settings_to_array(arguments) + return pdfdictionary { + S = pdf_movie, + T = format("movie %s",arguments[1] or "noname"), + Operation = operation, + } +end + +function executers.startmovie (arguments) return movie_or_sound(pdf_start ,arguments) end +function executers.stopmovie (arguments) return movie_or_sound(pdf_stop ,arguments) end +function executers.resumemovie(arguments) return movie_or_sound(pdf_resume,arguments) end +function executers.pausemovie (arguments) return movie_or_sound(pdf_pause ,arguments) end + +function executers.startsound (arguments) return movie_or_sound(pdf_start ,arguments) end +function executers.stopsound (arguments) return movie_or_sound(pdf_stop ,arguments) end +function executers.resumesound(arguments) return movie_or_sound(pdf_resume,arguments) end +function executers.pausesound (arguments) return movie_or_sound(pdf_pause ,arguments) end + +function specials.action(var) + local operation = var.operation + if var.operation and operation ~= "" then + local e = executers[operation] + if type(e) == "table" then + return e + elseif type(e) == "function" then + return e(var.arguments) + end + end +end + +--~ entry.A = pdfdictionary { +--~ S = pdfconstant("GoTo"), +--~ D = .... +--~ } + +local function build(levels,start,parent,method) + local startlevel = levels[start][1] + local i, n = start, 0 + local child, entry, m, prev, first, last, f, l +-- to be tested: i can be nil + while i and i <= #levels do + local li = levels[i] + local level, title, reference, open = li[1], li[2], li[3], li[4] + if level == startlevel then + if trace_bookmarks then + logs.report("bookmark","%3i %s%s %s",reference.realpage,rep(" ",level-1),(open and "+") or "-",title) + end + local prev = child + child = pdfreserveobject() + if entry then + entry.Next = child and pdfreference(child) + pdfflushobject(prev,entry) + end + entry = pdfdictionary { + Title = pdfunicode(title), + Parent = parent, + Prev = prev and pdfreference(prev), + } + if method == "internal" then + entry.Dest = "aut:" .. reference.internal + else -- if method == "page" then + entry.Dest = pagedest(reference.realpage) + end + if not first then first, last = child, child end + prev = child + last = prev + n = n + 1 + i = i + 1 + elseif level < startlevel then + pdfflushobject(child,entry) + return i, n, first, last + elseif i < #levels and level > startlevel then + i, m, f, l = build(levels,i,pdfreference(child),method) + entry.Count = (open and m) or -m + if m > 0 then + entry.First, entry.Last = pdfreference(f), pdfreference(l) + end + else + -- missing intermediate level but ok + i, m, f, l = build(levels,i,pdfreference(child),method) + entry.Count = (open and m) or -m + if m > 0 then + entry.First, entry.Last = pdfreference(f), pdfreference(l) + end + pdfflushobject(child,entry) + return i, n, first, last + end + end + pdfflushobject(child,entry) + return nil, n, first, last +end + +function codeinjections.addbookmarks(levels,method) + local parent = pdfreserveobject() + local _, m, first, last = build(levels,1,pdfreference(parent),method or "internal") + local dict = pdfdictionary { + Type = pdfconstant("Outlines"), + First = pdfreference(first), + Last = pdfreference(last), + Count = m, + } + pdfflushobject(parent,dict) + lpdf.addtocatalog("Outlines",lpdf.reference(parent)) +end diff --git a/tex/context/base/lpdf-col.lua b/tex/context/base/lpdf-col.lua new file mode 100644 index 000000000..18aa848ff --- /dev/null +++ b/tex/context/base/lpdf-col.lua @@ -0,0 +1,150 @@ +if not modules then modules = { } end modules ['lpdf-mis'] = { + version = 1.001, + comment = "companion to lpdf-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local type = type +local format, gsub = string.format, string.gsub + +-- colors = colors or { } +-- transparencies = transparencies or { } + +local registercolor = colors.register +local registertransparancy = transparencies.register +local colorsvalue = colors.value +local transparenciesvalue = transparencies.value + +-- Literals needed to inject code in the mp stream, we cannot use attributes there +-- since literals may have qQ's, much may go away once we have mplib code in place. +-- +-- This module assumes that some functions are defined in the colors namespace +-- which mostlikely will be loaded later. + +function lpdf.color(model,ca,default) -- todo: use gray when no color + local cv = colorsvalue(ca) + if cv then + if model == 1 then + model = cv[1] + end + if model == 2 then + local s = cv[2] + return format("%s g %s G",s,s) + elseif model == 3 then + local r, g, b = cv[3], cv[4], cv[5] + return format("%s %s %s rg %s %s %s RG",r,g,b,r,g,b) + elseif model == 4 then + local c, m, y, k = cv[6],cv[7],cv[8],cv[9] + return format("%s %s %s %s k %s %s %s %s K",c,m,y,k,c,m,y,k) + else + local n,f,d,p = cv[10],cv[11],cv[12],cv[13] + if type(p) == "string" then + p = gsub(p,","," ") -- brr misuse of spot + end + return format("/%s cs /%s CS %s SCN %s scn",n,n,p,p) + end + else + return format("%s g %s G",default or 0,default or 0) + end +end + +function lpdf.transparency(ct,default) -- kind of overlaps with transparencycode + -- beware, we need this hack because normally transparencies are not + -- yet registered and therefore the number is not not known ... we + -- might use the attribute number itself in the future + local ct = transparenciesvalue(ct) + if ct then + return format("/Tr%s gs",registertransparancy(nil,ct[1],ct[2],true)) + else + return "/Tr0 gs" + end +end + +function lpdf.colorvalue(model,ca,default) + local cv = colorsvalue(ca) + if cv then + if model == 1 then + model = cv[1] + end + if model == 2 then + return format("%s",cv[2]) + elseif model == 3 then + return format("%s %s %s",cv[3],cv[4],cv[5]) + elseif model == 4 then + return format("%s %s %s %s",cv[6],cv[7],cv[8],cv[9]) + else + return format("%s",cv[13]) + end + else + return format("%s",default or 0) + end +end + +function lpdf.fdfcolor(model,ca,default) + local cv = colorsvalue(ca) + if cv then + if model == 1 then + model = cv[1] + end + if model == 2 then + return format("[%s]",cv[2]) + elseif model == 3 then + return format("[%s %s %s]",cv[3],cv[4],cv[5]) + elseif model == 4 then + return format("[%s %s %s %s]",cv[6],cv[7],cv[8],cv[9]) + elseif model == 4 then + return format("[%s]",cv[13]) + end + else + return format("[%s]",default or 0) + end +end + +function lpdf.colorspace(model,ca) + local cv = colorsvalue(ca) + if cv then + if model == 1 then + model = cv[1] + end + if model == 2 then + return "DeviceGray" + elseif model == 3 then + return "DeviceRGB" + elseif model == 4 then + return "DeviceCMYK" + end + end + return "DeviceGRAY" +end + +-- by registering we getconversion for free (ok, at the cost of overhead) + +local intransparency = false +local pdfcolor = lpdf.color + +function lpdf.rgbcode(model,r,g,b) + return pdfcolor(model,registercolor(nil,'rgb',r,g,b)) +end +function lpdf.cmykcode(model,c,m,y,k) + return pdfcolor(model,registercolor(nil,'cmyk',c,m,y,k)) +end +function lpdf.graycode(model,s) + return pdfcolor(model,registercolor(nil,'gray',s)) +end +function lpdf.spotcode(model,n,f,d,p) + return pdfcolor(model,registercolor(nil,'spot',n,f,d,p)) -- incorrect +end +function lpdf.transparencycode(a,t) + intransparency = true + return format("/Tr%s gs",registertransparancy(nil,a,t,true)) -- true forces resource +end +function lpdf.finishtransparencycode() + if intransparency then + intransparency = false + return "/Tr0 gs" -- we happen to know this -) + else + return "" + end +end diff --git a/tex/context/base/lpdf-fld.lua b/tex/context/base/lpdf-fld.lua new file mode 100644 index 000000000..c034aec6c --- /dev/null +++ b/tex/context/base/lpdf-fld.lua @@ -0,0 +1,885 @@ +if not modules then modules = { } end modules ['lpdf-fld'] = { + version = 1.001, + comment = "companion to lpdf-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- cleaned up, e.g. no longer older viewers +-- always kids so no longer explicit main / clone / copy +-- some optimizations removed (will come bakc if needed) + +local gmatch, lower, format = string.gmatch, string.lower, string.format +local lpegmatch = lpeg.match + +local trace_fields = false trackers.register("widgets.fields", function(v) trace_fields = v end) + +local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes + +local variables = interfaces.variables + +local nodeinjections = backends.pdf.nodeinjections +local codeinjections = backends.pdf.codeinjections +local registrations = backends.pdf.registrations + +local registeredsymbol = codeinjections.registeredsymbol + +local pdfstream = lpdf.stream +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfreference = lpdf.reference +local pdfunicode = lpdf.unicode +local pdfstring = lpdf.string +local pdfconstant = lpdf.constant +local pdftoeight = lpdf.toeight +local pdfflushobject = lpdf.flushobject +local pdfreserveobject = lpdf.reserveobject +local pdfannotation = nodes.pdfannotation + +local submitoutputformat = 0 -- 0=unknown 1=HTML 2=FDF 3=XML => not yet used, needs to be checked + +local splitter = lpeg.splitat("=>") + +local formats = { + html = 1, fdf = 2, xml = 3, +} + +function codeinjections.setformsmethod(name) + submitoutputformat = formats[lower(name)] or 3 +end + +local flag = { + MultiLine = 4096, -- 13 + NoToggleToOff = 16384, -- 15 + Radio = 32768, -- 16 + PushButton = 65536, -- 17 + PopUp = 131072, -- 18 + Edit = 262144, -- 19 + RadiosInUnison = 33554432, -- 26 + DoNotSpellCheck = 4194304, -- 23 + DoNotScroll = 8388608, -- 24 + ReadOnly = 1, -- 1 + Required = 2, -- 2 + NoExport = 4, -- 3 + Password = 8192, -- 14 + Sort = 524288, -- 20 + FileSelect = 1048576, -- 21 +} + +local plus = { + Invisible = 1, -- 1 + Hidden = 2, -- 2 + Printable = 4, -- 3 + NoView = 32, -- 6 + ToggleNoView = 256, -- 9 + AutoView = 256, -- 288 (6+9) +} + +-- todo: check what is interfaced + +flag.readonly = flag.ReadOnly +flag.required = flag.Required +flag.protected = flag.Password +flag.sorted = flag.Sort +flag.unavailable = flag.NoExport +flag.nocheck = flag.DoNotSpellCheck +flag.fixed = flag.DoNotScroll +flag.file = flag.FileSelect + +plus.hidden = plus.Hidden +plus.printable = plus.Printable +plus.auto = plus.AutoView + +-- some day .. lpeg with function or table + +local function fieldflag(specification) + local o, n = specification.options, 0 + if o and o ~= "" then + for f in gmatch(o,"[^, ]+") do + n = n + (flag[f] or 0) + end + end + return n +end + +local function fieldplus(specification) + local o, n = specification.options, 0 + if o and o ~= "" then + for p in gmatch(o,"[^, ]+") do + n = n + (plus[p] or 0) + end + end + return n +end + + +local function checked(what) + if what and what ~= "" then + local set, bug = jobreferences.identify("",what) + return not bug and #set > 0 and lpdf.pdfaction(set) + end +end + +local function fieldactions(specification) -- share actions +--~ print(table.serialize(specification)) + local d, a = { }, nil + a = specification.mousedown if a and a ~= "" then d.D = checked(a) end + a = specification.mouseup if a and a ~= "" then d.U = checked(a) end + a = specification.regionin if a and a ~= "" then d.E = checked(a) end -- Enter + a = specification.regionout if a and a ~= "" then d.X = checked(a) end -- eXit + a = specification.afterkeystroke if a and a ~= "" then d.K = checked(a) end + a = specification.formatresult if a and a ~= "" then d.F = checked(a) end + a = specification.validateresult if a and a ~= "" then d.V = checked(a) end + a = specification.calculatewhatever if a and a ~= "" then d.C = checked(a) end + a = specification.focusin if a and a ~= "" then d.Fo = checked(a) end + a = specification.focusout if a and a ~= "" then d.Bl = checked(a) end + -- a = specification.openpage if a and a ~= "" then d.PO = checked(a) end + -- a = specification.closepage if a and a ~= "" then d.PC = checked(a) end + -- a = specification.visiblepage if a and a ~= "" then d.PV = checked(a) end + -- a = specification.invisiblepage if a and a ~= "" then d.PI = checked(a) end + return next(d) and pdfdictionary(d) +end + +-- fonts and color + +local fontnames = { + rm = { + tf = "Times-Roman", + bf = "Times-Bold", + it = "Times-Italic", + sl = "Times-Italic", + bi = "Times-BoldItalic", + bs = "Times-BoldItalic", + }, + ss = { + tf = "Helvetica", + bf = "Helvetica-Bold", + it = "Helvetica-Oblique", + sl = "Helvetica-Oblique", + bi = "Helvetica-BoldOblique", + bs = "Helvetica-BoldOblique", + }, + tt = { + tf = "Courier", + bf = "Courier-Bold", + it = "Courier-Oblique", + sl = "Courier-Oblique", + bi = "Courier-BoldOblique", + bs = "Courier-BoldOblique", + } +} + +local usedfonts = { } + +local function fieldsurrounding(specification) + local size = specification.fontsize or "12pt" + local style = specification.fontstyle or "rm" + local alternative = specification.fontalternative or "tf" + local s = fontnames[style] + if not s then + style, s = "rm", fontnames.rm + end + local a = s[alternative] + if not a then + alternative, a = "tf", s.tf + end + local tag = style .. alternative + size = string.todimen(size) + local stream = pdfstream { + pdfconstant(tag), + format("%0.4f Tf",(size and (number.dimenfactors.bp * size)) or 12), + } + usedfonts[tag] = a -- the name + -- add color to stream: 0 g + -- move up with "x.y Ts" + return tostring(stream) +end + +local function registerfonts() + if next(usedfonts) then + local d = pdfdictionary() + for tag, name in next, usedfonts do + local f = pdfdictionary { + Type = pdfconstant("Font"), + Subtype = pdfconstant("Type1"), -- todo + Name = pdfconstant(tag), + BaseFont = pdfconstant(name), + } + d[tag] = pdfreference(pdfflushobject(f)) + end + return d + end +end + +-- cache + +local function fieldattributes(specification) +--~ return pdfarray { +--~ -- BG = -- backgroundcolor +--~ -- BC = -- framecolor +--~ } + return nil +end + +-- symbols + +local function fieldappearances(specification) + -- todo: caching + local values = specification.values + local default = specification.default -- todo + if not values then + -- error + return + end + local v = aux.settings_to_array(values) + local n, r, d + if #v == 1 then + n, r, d = v[1], v[1], v[1] + elseif #v == 2 then + n, r, d = v[1], v[1], v[2] + else + n, r, d = v[1], v[2], v[3] + end + local appearance = pdfdictionary { -- cache this one + N = registeredsymbol(n), R = registeredsymbol(r), D = registeredsymbol(d), + } + return lpdf.sharedobj(tostring(appearance)) +end + +local function fieldstates(specification,forceyes,values,default) + -- we don't use Opt here (too messy for radio buttons) + local values, default = values or specification.values, default or specification.default + if not values then + -- error + return + end + local v = aux.settings_to_array(values) + local yes, off + if #v == 1 then + yes, off = v[1], v[1] + else + yes, off = v[1], v[2] + end + local yesshown, yesvalue = lpegmatch(splitter,yes) + if not (yesshown and yesvalue) then + yesshown = yes, yes + end + yes = aux.settings_to_array(yesshown) + local offshown, offvalue = lpegmatch(splitter,off) + if not (offshown and offvalue) then + offshown = off, off + end + off = aux.settings_to_array(offshown) + if #yes == 1 then + yesn, yesr, yesd = yes[1], yes[1], yes[1] + elseif #yes == 2 then + yesn, yesr, yesd = yes[1], yes[1], yes[2] + else + yesn, yesr, yesd = yes[1], yes[2], yes[3] + end + if #off == 1 then + offn, offr, offd = off[1], off[1], off[1] + elseif #off == 2 then + offn, offr, offd = off[1], off[1], off[2] + else + offn, offr, offd = off[1], off[2], off[3] + end + if not yesvalue then + yesvalue = yesn + end + if not offvalue then + offvalue = offn + end + if forceyes == true then + forceyes = forceyes and "On" -- spec likes Yes more but we've used On for ages now + else + -- false or string + end + if default == yesn then + default = pdfconstant(forceyes or yesn) + else + default = pdfconstant("Off") + end + local appearance = pdfdictionary { -- maybe also cache components + N = pdfdictionary { [forceyes or yesn] = registeredsymbol(yesn), Off = registeredsymbol(offn) }, + R = pdfdictionary { [forceyes or yesr] = registeredsymbol(yesr), Off = registeredsymbol(offr) }, + D = pdfdictionary { [forceyes or yesd] = registeredsymbol(yesd), Off = registeredsymbol(offd) } + } + local appearanceref = lpdf.sharedobj(tostring(appearance)) + return appearanceref, default +end + +local function fieldoptions(specification) + local values = specification.values + local default = specification.default + if values then + local v = aux.settings_to_array(values) + for i=1,#v do + local vi = v[i] + local shown, value = lpegmatch(splitter,vi) + if shown and value then + v[i] = pdfarray { pdfunicode(value), shown } + else + v[i] = pdfunicode(v[i]) + end + end + return pdfarray(v) + end +end + +local function radiodefault(parent,field,forceyes) + local default, values = parent.default, parent.values + if not default or default == "" then + values = aux.settings_to_array(values) + default = values[1] + end + local name = field.name + local fieldvalues = aux.settings_to_array(field.values) + local yes, off = fieldvalues[1], fieldvalues[2] or fieldvalues[1] + if not default then + return pdfconstant((forceyes and "On") or yes) + elseif default == name then + return pdfconstant((forceyes and "On") or default) + else + return pdfconstant("Off") + end +end + +-- layers + +local function fieldlayer(specification) -- we can move this in line + local layer = specification.layer + return (layer and lpdf.layerreferences[layer]) or nil +end + +-- defining + +local fields, radios, clones, fieldsets, calculationset = { }, { }, { }, { }, nil + +function codeinjections.definefieldset(tag,list) + fieldsets[tag] = list +end + +function codeinjections.getfieldset(tag) + return fieldsets[tag] +end + +local function fieldsetlist(tag) + if tag then + local ft = fieldsets[tag] + if ft then + local a = pdfarray() + for name in gmatch(list,"[^, ]+") do + local f = field[name] + if f and f.pobj then + a[#a+1] = pdfreference(f.pobj) + end + end + return a + end + end +end + +function codeinjections.setfieldcalculationset(tag) + calculationset = tag +end + +local function predefinesymbols(specification) + local values = specification.values + if values then + local symbols = aux.settings_to_array(values) + for i=1,#symbols do + local symbol = symbols[i] + local a, b = lpegmatch(splitter,symbol) + codeinjections.presetsymbol(a or symbol) + end + end +end + +function codeinjections.getdefaultfieldvalue(name) + local f = fields[name] + if f then + local values = f.values + local default = f.default + if not default or default == "" then + local symbols = aux.settings_to_array(values) + local symbol = symbols[1] + if symbol then + local a, b = lpegmatch(splitter,symbol) -- splits at => + default = a or symbol + end + end + if default then + tex.sprint(ctxcatcodes,default) + end + end +end + +function codeinjections.definefield(specification) + local n = specification.name + local f = fields[n] + if not f then + local kind = specification.kind + if not kind then + if trace_fields then + logs.report("fields","invalid definition of '%s': unknown type",n) + end + elseif kind == "radio" then + local values = specification.values + if values and values ~= "" then + values = aux.settings_to_array(values) + for v=1,#values do + radios[values[v]] = { parent = n } + end + fields[n] = specification + if trace_fields then + logs.report("fields","defining '%s' as radio",n or "?") + end + elseif trace_fields then + logs.report("fields","invalid definition of radio '%s': missing values",n) + end + elseif kind == "sub" then + -- not in main field list ! + local radio = radios[n] + if radio then + -- merge specification + for key, value in next, specification do + radio[key] = value + end + if trace_fields then + local p = radios[n] and radios[n].parent + logs.report("fields","defining '%s' as sub of radio '%s'",n or "?",p or "?") + end + elseif trace_fields then + logs.report("fields","invalid definition of radio sub '%s': no parent",n) + end + predefinesymbols(specification) + elseif kind == "text" or kind == "line" then + fields[n] = specification + if trace_fields then + logs.report("fields","defining '%s' as %s",n,kind) + end + if specification.values ~= "" and specification.default == "" then + specification.default, specification.values = specification.values, nil + end + else + fields[n] = specification + if trace_fields then + logs.report("fields","defining '%s' as %s",n,kind) + end + predefinesymbols(specification) + end + elseif trace_fields then + logs.report("fields","invalid definition of '%s': already defined",n) + end +end + +function codeinjections.clonefield(specification) + local p, c, v = specification.parent, specification.children, specification.variant + if not p or not c then + if trace_fields then + logs.report("fields","invalid clone: children: '%s', parent '%s', variant: '%s'",p or "?",c or "?", v or "?") + end + else + for n in gmatch(c,"[^, ]+") do + local f, r, c, x = fields[n], radios[n], clones[n], fields[p] + if f or r or c then + if trace_fields then + logs.report("fields","already cloned: child: '%s', parent '%s', variant: '%s'",p or "?",n or "?", v or "?") + end + elseif x then + if trace_fields then + logs.report("fields","invalid clone: child: '%s', variant: '%s', no parent",n or "?", v or "?") + end + else + if trace_fields then + logs.report("fields","cloning: child: '%s', parent '%s', variant: '%s'",p or "?",n or "?", v or "?") + end + clones[n] = specification + predefinesymbols(specification) + end + end + end +end + +function codeinjections.getfieldgroup(name) + local f = fields[name] or radios[name] or clones[name] + local g = f and f.group + if not g or g == "" then + local v, p, k = f.variant, f.parent, f.kind + if v == "clone" or v == "copy" then + f = fields[p] or radios[p] + g = f and f.group + elseif k == "sub" then + f = fields[p] + g = f and f.group + end + end + if g then + texsprint(ctxcatcodes,g) + end +end + +-- + +function codeinjections.doiffieldset(tag) + commands.testcase(fieldsets[tag]) +end + +function codeinjections.doiffieldelse(name) + commands.testcase(fields[name]) +end + +-- + +local alignments = { + flushleft = 0, right = 0, + center = 1, middle = 1, + flushright = 2, left = 2, +} + +local function fieldalignment(specification) + return alignments[specification.align] or 0 +end + +local function enhance(specification,option) + local so = specification.options + if so and so ~= "" then + specification.options = so .. "," .. option + else + specification.options = option + end + return specification +end + +-- finish + +local collected = pdfarray() + +local function finishfields() + for name, field in next, fields do + local kids = field.kids + if kids then + pdfflushobject(field.kobj,kids) + end + local pobj = field.pobj + end + for name, field in next, radios do + local kids = field.kids + if kids then + pdfflushobject(field.kobj,kids) + end + end + if #collected > 0 then + usedfonts.tttf = fontnames.tt.tf + local acroform = pdfdictionary { + NeedAppearances = true, + Fields = pdfreference(pdfflushobject(collected)), + DR = pdfdictionary { Font = registerfonts() }, + CO = fieldsetlist(calculationset), + DA = "/tttf 12 Tf 0 g", + } + lpdf.addtocatalog("AcroForm",pdfreference(pdfflushobject(acroform))) + end +end + +lpdf.registerdocumentfinalizer(finishfields) + +local pdf_widget = pdfconstant("Widget") +local pdf_tx = pdfconstant("Tx") +local pdf_ch = pdfconstant("Ch") +local pdf_btn = pdfconstant("Btn") +local pdf_yes = pdfconstant("Yes") +local pdf_p = pdfconstant("P") -- None Invert Outline Push +local pdf_n = pdfconstant("N") -- None Invert Outline Push +-- +local pdf_no_rect = pdfarray { 0, 0, 0, 0 } + +local methods = { } + +function codeinjections.typesetfield(name,specification) + local field = fields[name] or radios[name] or clones[name] + if not field then + logs.report("fields", "unknown child '%s'",name) + -- unknown field + return + end + local variant, parent = field.variant, field.parent + if variant == "copy" or variant == "clone" then -- only in clones + field = fields[parent] or radios[parent] + end + local method = methods[field.kind] + if method then + method(name,specification,variant) + else + logs.report("fields", "unknown method '%s' for child '%s'",field.kind,name) + end +end + +-- can be optional multipass optimization (share objects) + +local function save_parent(field,specification,d) + local kn = pdfreserveobject() + d.Kids = pdfreference(kn) + field.kobj = kn + field.kids = pdfarray() + local pn = pdfflushobject(d) + field.pobj = pn + collected[#collected+1] = pdfreference(pn) +end + +local function save_kid(field,specification,d) + local kn = pdfreserveobject() + field.kids[#field.kids+1] = pdfreference(kn) + node.write(pdfannotation(specification.width,specification.height,0,d(),kn)) +end + +function methods.line(name,specification,variant,extras) + local field = fields[name] + if variant == "copy" or variant == "clone" then + logs.report("fields","todo: clones of text fields") + end + local kind = field.kind + if not field.pobj then + if trace_fields then + logs.report("fields","using parent text '%s'",name) + end + if extras then + enhance(specification,extras) + end + local text = pdfunicode(field.default) + local d = pdfdictionary { + Subtype = pdf_widget, + T = pdfunicode(specification.title), + F = fieldplus(specification), + Ff = fieldflag(specification), + OC = fieldlayer(specification), + MK = fieldsurrounding(specification), -- needed ? + DA = fieldsurrounding(specification), + AA = fieldactions(specification), + FT = pdf_tx, + Q = fieldalignment(specification), + MaxLen = (specification.length == 0 and 1000) or specification.length, + DV = text, + V = text, + } + save_parent(field,specification,d) + field.specification = specification + end + specification = field.specification or { } -- todo: radio spec + if trace_fields then + logs.report("fields","using child text '%s'",name) + end + local d = pdfdictionary { + Subtype = pdf_widget, + Parent = pdfreference(field.pobj), + F = fieldplus(specification), + DA = fieldattributes(specification), + OC = fieldlayer(specification), + MK = fieldsurrounding(specification), + DA = fieldsurrounding(specification), + AA = fieldactions(specification), + Q = fieldalignment(specification), + } + save_kid(field,specification,d) +end + +function methods.text(name,specification,variant) + methods.line(name,specification,variant,"MultiLine") +end + +function methods.choice(name,specification,variant,extras) + local field = fields[name] + if variant == "copy" or variant == "clone" then + logs.report("fields","todo: clones of choice fields") + end + local kind = field.kind + local d + if not field.pobj then + if trace_fields then + logs.report("fields","using parent choice '%s'",name) + end + if extras then + enhance(specification,extras) + end + local d = pdfdictionary { + Subtype = pdf_widget, + T = pdfunicode(specification.title), + F = fieldplus(specification), + Ff = fieldflag(specification), + OC = fieldlayer(specification), + AA = fieldactions(specification), + FT = pdf_ch, + Opt = fieldoptions(field), + } + save_parent(field,specification,d) + field.specification = specification + end + specification = field.specification or { } + if trace_fields then + logs.report("fields","using child choice '%s'",name) + end + local d = pdfdictionary { + Subtype = pdf_widget, + Parent = pdfreference(field.pobj), + F = fieldplus(specification), + DA = fieldattributes(specification), + OC = fieldlayer(specification), + AA = fieldactions(specification), + } + save_kid(field,specification,d) +end + +function methods.popup(name,specification,variant) + methods.choice(name,specification,variant,"PopUp") +end +function methods.combo(name,specification,variant) + methods.choice(name,specification,variant,"PopUp,Edit") +end + +-- Probably no default appearance needed for first kid and no javascripts for the +-- parent ... I will look into it when I have to make a complex document. + +function methods.check(name,specification,variant) + -- no /Opt because (1) it's messy - see pdf spec, (2) it discouples kids and + -- contrary to radio there is no way to associate then + local field = fields[name] + if variant == "copy" or variant == "clone" then + logs.report("fields","todo: clones of check fields") + end + local kind = field.kind + local appearance, default = fieldstates(field,true) + if not field.pobj then + if trace_fields then + logs.report("fields","using parent check '%s'",name) + end + local d = pdfdictionary { + Subtype = pdf_widget, + T = pdfunicode(specification.title), + F = fieldplus(specification), + Ff = fieldflag(specification), + OC = fieldlayer(specification), + AA = fieldactions(specification), + FT = pdf_btn, + DV = default, + V = default, + AS = default, + AP = appearance, + H = pdf_n, + } + save_parent(field,specification,d) + field.specification = specification + end + specification = field.specification or { } -- todo: radio spec + if trace_fields then + logs.report("fields","using child check '%s'",name) + end + local d = pdfdictionary { + Subtype = pdf_widget, + Parent = pdfreference(field.pobj), + F = fieldplus(specification), + DA = fieldattributes(specification), + OC = fieldlayer(specification), + AA = fieldactions(specification), + DV = default, + V = default, + AS = default, + AP = appearance, + H = pdf_n, + } + save_kid(field,specification,d) +end + +function methods.push(name,specification,variant) + local field = fields[name] + if variant == "copy" or variant == "clone" then + logs.report("fields","todo: clones of push fields") + end + local kind = field.kind + if not field.pobj then + if trace_fields then + logs.report("fields","using parent push '%s'",name) + end + enhance(specification,"PushButton") + local d = pdfdictionary { + Subtype = pdf_widget, + T = pdfunicode(specification.title), + F = fieldplus(specification), + Ff = fieldflag(specification), + OC = fieldlayer(specification), + AA = fieldactions(specification), + FT = pdf_btn, + AP = fieldappearances(field), + H = pdf_p, + } + save_parent(field,specification,d) + field.specification = specification + end + specification = field.specification or { } -- todo: radio spec + if trace_fields then + logs.report("fields","using child push '%s'",name) + end + local d = pdfdictionary { + Subtype = pdf_widget, + Parent = pdfreference(field.pobj), + F = fieldplus(specification), + DA = fieldattributes(specification), + OC = fieldlayer(specification), + AA = fieldactions(specification), + AP = fieldappearances(field), + H = pdf_p, + } + save_kid(field,specification,d) +end + +function methods.sub(name,specification,variant) + local field = radios[name] or fields[name] or clones[name] -- fields in case of a clone, maybe use dedicated clones + local values + if variant == "copy" or variant == "clone" then + name = field.parent + values = field.values -- clone only, copy has nil so same as parent + field = radios[name] + else + values = field.values + end + local parent = fields[field.parent] + if not parent then + return + end + local appearance = fieldstates(field,name,values) -- we need to force the 'On' name + local default = radiodefault(parent,field) + if not parent.pobj then + if trace_fields then + logs.report("fields","using parent '%s' of radio '%s' with values '%s' and default '%s'",parent.name,name,parent.values or "?",parent.default or "?") + end + local specification = parent.specification or { } + -- enhance(specification,"Radio,RadiosInUnison") + enhance(specification,"RadiosInUnison") -- maybe also PushButton as acrobat does + local d = pdfdictionary { + T = parent.name, + FT = pdf_btn, + Rect = pdf_no_rect, + F = fieldplus(specification), + Ff = fieldflag(specification), + H = pdf_n, + V = default, + } + save_parent(parent,specification,d) + end + if trace_fields then + logs.report("fields","using child radio '%s' with values '%s'",name,values or "?") + end + local d = pdfdictionary { + Subtype = pdf_widget, + Parent = pdfreference(parent.pobj), + F = fieldplus(specification), + DA = fieldattributes(specification), + OC = fieldlayer(specification), + AA = fieldactions(specification), + AS = default, + AP = appearance, + H = pdf_n, + } + save_kid(parent,specification,d) +end diff --git a/tex/context/base/lpdf-grp.lua b/tex/context/base/lpdf-grp.lua new file mode 100644 index 000000000..ad01e4d4f --- /dev/null +++ b/tex/context/base/lpdf-grp.lua @@ -0,0 +1,68 @@ +if not modules then modules = { } end modules ['lpdf-grp'] = { + version = 1.001, + comment = "companion to lpdf-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format = string.format + +local nodeinjections = backends.pdf.nodeinjections +local codeinjections = backends.pdf.codeinjections +local registrations = backends.pdf.registrations + +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfconstant = lpdf.constant +local pdfreference = lpdf.reference +local pdfflushobject = lpdf.flushobject + +local function shade(stype,name,domain,color_a,color_b,n,colorspace,coordinates) + local f = pdfdictionary { + FunctionType = 2, + Domain = pdfarray(domain), -- domain is actually a string + C0 = pdfarray(color_a), + C1 = pdfarray(color_b), + N = tonumber(n), + } + local s = pdfdictionary { + ShadingType = stype, + ColorSpace = pdfconstant(colorspace), + Function = pdfreference(pdfflushobject(f)), + Coords = pdfarray(coordinates), + Extend = pdfarray { true, true }, + } + lpdf.adddocumentshade(name,pdfreference(pdfflushobject(s))) +end + +function lpdf.circularshade(name,domain,color_a,color_b,n,colorspace,coordinates) + shade(3,name,domain,color_a,color_b,n,colorspace,coordinates) +end + +function lpdf.linearshade(name,domain,color_a,color_b,n,colorspace,coordinates) + shade(2,name,domain,color_a,color_b,n,colorspace,coordinates) +end + +function lpdf.colorspec(model,ca,default) + if ca and ca > 0 then + local cv = colors.value(ca) + if cv then + if model == 1 then + model = cv[1] + end + if model == 2 then + return pdfarray { cv[2] } + elseif model == 3 then + return pdfarray { cv[3],cv[4],cv[5] } + elseif model == 4 then + return pdfarray { cv[6],cv[7],cv[8],cv[9] } + elseif model == 5 then + return pdfarray { cv[13] } + end + end + end + if default then + return default + end +end diff --git a/tex/context/base/lpdf-ini.lua b/tex/context/base/lpdf-ini.lua new file mode 100644 index 000000000..e0ffd4052 --- /dev/null +++ b/tex/context/base/lpdf-ini.lua @@ -0,0 +1,670 @@ +if not modules then modules = { } end modules ['lpdf-ini'] = { + version = 1.001, + comment = "companion to lpdf-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local setmetatable, getmetatable, type, next, tostring, tonumber, rawset = setmetatable, getmetatable, type, next, tostring, tonumber, rawset +local char, byte, format, gsub, concat, match, sub, gmatch = string.char, string.byte, string.format, string.gsub, table.concat, string.match, string.sub, string.gmatch +local utfvalues = string.utfvalues +local texwrite, texset, texsprint, ctxcatcodes = tex.write, tex.set, tex.sprint, tex.ctxcatcodes +local sind, cosd = math.sind, math.cosd +local lpegmatch = lpeg.match + +local pdfreserveobj = pdf and pdf.reserveobj or function() return 1 end -- for testing +local pdfimmediateobj = pdf and pdf.immediateobj or function() return 2 end -- for testing + +local trace_finalizers = false trackers.register("backend.finalizers", function(v) trace_finalizers = v end) +local trace_resources = false trackers.register("backend.resources", function(v) trace_resources = v end) +local trace_objects = false trackers.register("backend.objects", function(v) trace_objects = v end) +local trace_detail = false trackers.register("backend.detail", function(v) trace_detail = v end) + +lpdf = lpdf or { } + +local function tosixteen(str) + if not str or str == "" then + return "()" + else + local r = { ""] = "\\>", +-- ["["] = "\\[", ["]"] = "\\]", +-- ["("] = "\\(", [")"] = "\\)", +-- } +-- +-- local escaped = lpeg.Cs(lpeg.Cc("(") * (lpeg.S("\\/#<>[]()")/escapes + lpeg.P(1))^0 * lpeg.Cc(")")) +-- +-- local function toeight(str) +-- if not str or str == "" then +-- return "()" +-- else +-- return lpegmatch(escaped,str) +-- end +-- end +-- +-- -- no need for escaping .. just use unicode instead + +-- \0 \t \n \r \f ( ) [ ] { } / % + +local function toeight(str) + return "(" .. str .. ")" +end + +lpdf.toeight = toeight + +--~ local escaped = lpeg.Cs((lpeg.S("\0\t\n\r\f ()[]{}/%")/"#" + lpeg.P(1))^0) +--~ +--~ local function cleaned(str) +--~ return (str and str ~= "" and lpegmatch(escaped,str)) or "" +--~ end +--~ +--~ lpdf.cleaned = cleaned -- not public yet + +local function merge_t(a,b) + local t = { } + for k,v in next, a do t[k] = v end + for k,v in next, b do t[k] = v end + return setmetatable(t,getmetatable(a)) +end + +local tostring_a, tostring_d + +tostring_d = function(t,contentonly,key) + if not next(t) then + if contentonly then + return "" + else + return "<< >>" + end + else + local r = { } + for k, v in next, t do + local tv = type(v) + if tv == "string" then + r[#r+1] = format("/%s %s",k,toeight(v)) + elseif tv == "unicode" then + r[#r+1] = format("/%s %s",k,tosixteen(v)) + elseif tv == "table" then + local mv = getmetatable(v) + if mv and mv.__lpdftype then + r[#r+1] = format("/%s %s",k,tostring(v)) + elseif v[1] then + r[#r+1] = format("/%s %s",k,tostring_a(v)) + else + r[#r+1] = format("/%s %s",k,tostring_d(v)) + end + else + r[#r+1] = format("/%s %s",k,tostring(v)) + end + end + if contentonly then + return concat(r, " ") + elseif key then + return format("/%s << %s >>", key, concat(r, " ")) + else + return format("<< %s >>", concat(r, " ")) + end + end +end + +tostring_a = function(t,contentonly,key) + if #t == 0 then + if contentonly then + return "" + else + return "[ ]" + end + else + local r = { } + for k, v in next, t do + local tv = type(v) + if tv == "string" then + r[#r+1] = toeight(v) + elseif tv == "unicode" then + r[#r+1] = tosixteen(v) + elseif tv == "table" then + local mv = getmetatable(v) + local mt = mv and mv.__lpdftype + if mt then + r[#r+1] = tostring(v) + elseif v[1] then + r[#r+1] = tostring_a(v) + else + r[#r+1] = tostring_d(v) + end + else + r[#r+1] = tostring(v) + end + end + if contentonly then + return concat(r, " ") + elseif key then + return format("/%s [ %s ]", key, concat(r, " ")) + else + return format("[ %s ]", concat(r, " ")) + end + end +end + +local tostring_x = function(t) return concat(t, " ") end +local tostring_s = function(t) return toeight(t[1]) end +local tostring_u = function(t) return tosixteen(t[1]) end +local tostring_n = function(t) return tostring(t[1]) end -- tostring not needed +local tostring_c = function(t) return t[1] end -- already prefixed (hashed) +local tostring_z = function() return "null" end +local tostring_t = function() return "true" end +local tostring_f = function() return "false" end +local tostring_r = function(t) return t[1] .. " 0 R" end + +local tostring_v = function(t) + local s = t[1] + if type(s) == "table" then + return concat(s,"") + else + return s + end +end + +local function value_x(t) return t end -- the call is experimental +local function value_s(t,key) return t[1] end -- the call is experimental +local function value_u(t,key) return t[1] end -- the call is experimental +local function value_n(t,key) return t[1] end -- the call is experimental +local function value_c(t) return sub(t[1],2) end -- the call is experimental +local function value_d(t) return tostring_d(t,true,key) end -- the call is experimental +local function value_a(t) return tostring_a(t,true,key) end -- the call is experimental +local function value_z() return nil end -- the call is experimental +local function value_t(t) return t.value or true end -- the call is experimental +local function value_f(t) return t.value or false end -- the call is experimental +local function value_r() return t[1] end -- the call is experimental +local function value_v() return t[1] end -- the call is experimental + +local function add_x(t,k,v) rawset(t,k,tostring(v)) end + +local mt_x = { __lpdftype = "stream", __tostring = tostring_x, __call = value_x, __newindex = add_x } +local mt_d = { __lpdftype = "dictionary", __tostring = tostring_d, __call = value_d } +local mt_a = { __lpdftype = "array", __tostring = tostring_a, __call = value_a } +local mt_u = { __lpdftype = "unicode", __tostring = tostring_u, __call = value_u } +local mt_s = { __lpdftype = "string", __tostring = tostring_s, __call = value_s } +local mt_n = { __lpdftype = "number", __tostring = tostring_n, __call = value_n } +local mt_c = { __lpdftype = "constant", __tostring = tostring_c, __call = value_c } +local mt_z = { __lpdftype = "null", __tostring = tostring_z, __call = value_z } +local mt_t = { __lpdftype = "true", __tostring = tostring_t, __call = value_t } +local mt_f = { __lpdftype = "false", __tostring = tostring_f, __call = value_f } +local mt_r = { __lpdftype = "reference", __tostring = tostring_r, __call = value_r } +local mt_v = { __lpdftype = "verbose", __tostring = tostring_v, __call = value_v } + +local function pdfstream(t) -- we need to add attrbutes + if t then + for i=1,#t do + t[i] = tostring(t[i]) + end + end + return setmetatable(t or { },mt_x) +end + +local function pdfdictionary(t) + return setmetatable(t or { },mt_d) +end + +local function pdfarray(t) + if type(t) == "string" then + return setmetatable({ t },mt_a) + else + return setmetatable(t or { },mt_a) + end +end + +local function pdfstring(str,default) + return setmetatable({ str or default or "" },mt_s) +end + +local function pdfunicode(str,default) + return setmetatable({ str or default or "" },mt_u) +end + +local cache = { } -- can be weak + +local function pdfnumber(n,default) -- 0-10 + n = n or default + local c = cache[n] + if not c then + c = setmetatable({ n },mt_n) + -- cache[n] = c -- too many numbers + end + return c +end + +for i=-1,9 do cache[i] = pdfnumber(i) end + +local cache = { } -- can be weak + +local forbidden, replacements = "\0\t\n\r\f ()[]{}/%%#\\", { } -- table faster than function + +for s in gmatch(forbidden,".") do + replacements[s] = format("#%02x",byte(s)) +end + +local escaped = lpeg.Cs(lpeg.Cc("/") * (lpeg.S(forbidden)/replacements + lpeg.P(1))^0) + +local function pdfconstant(str,default) + str = str or default or "" + local c = cache[str] + if not c then + -- c = setmetatable({ "/" .. str },mt_c) + c = setmetatable({ lpegmatch(escaped,str) },mt_c) + cache[str] = c + end + return c +end + +local p_null = { } setmetatable(p_null, mt_z) +local p_true = { } setmetatable(p_true, mt_t) +local p_false = { } setmetatable(p_false,mt_f) + +local function pdfnull() + return p_null +end + +--~ print(pdfboolean(false),pdfboolean(false,false),pdfboolean(false,true)) +--~ print(pdfboolean(true),pdfboolean(true,false),pdfboolean(true,true)) +--~ print(pdfboolean(nil,true),pdfboolean(nil,false)) + +local function pdfboolean(b,default) + if type(b) == "boolean" then + return b and p_true or p_false + else + return default and p_true or p_false + end +end + +local function pdfreference(r) + return setmetatable({ r or 0 },mt_r) +end + +local function pdfverbose(t) -- maybe check for type + return setmetatable({ t or "" },mt_v) +end + +lpdf.stream = pdfstream +lpdf.dictionary = pdfdictionary +lpdf.array = pdfarray +lpdf.string = pdfstring +lpdf.unicode = pdfunicode +lpdf.number = pdfnumber +lpdf.constant = pdfconstant +lpdf.null = pdfnull +lpdf.boolean = pdfboolean +lpdf.reference = pdfreference +lpdf.verbose = pdfverbose + +-- n = pdf.obj(n, str) +-- n = pdf.obj(n, "file", filename) +-- n = pdf.obj(n, "stream", streamtext, attrtext) +-- n = pdf.obj(n, "streamfile", filename, attrtext) + +-- we only use immediate objects + +-- todo: tracing + +local names, cache = { }, { } + +function lpdf.reserveobject(name) + local r = pdfreserveobj() + if name then + names[name] = r + if trace_objects then + logs.report("backends", "reserving object number %s under name '%s'",r,name) + end + elseif trace_objects then + logs.report("backends", "reserving object number %s",r) + end + return r +end + +--~ local pdfreserveobject = lpdf.reserveobject + +function lpdf.flushobject(name,data) + if data then + name = names[name] or name + if name then + if trace_objects then + if trace_detail then + logs.report("backends", "flushing object data to reserved object with name '%s' -> %s",name,tostring(data)) + else + logs.report("backends", "flushing object data to reserved object with name '%s'",name) + end + end + return pdfimmediateobj(name,tostring(data)) + else + if trace_objects then + if trace_detail then + logs.report("backends", "flushing object data to reserved object with number %s -> %s",name,tostring(data)) + else + logs.report("backends", "flushing object data to reserved object with number %s",name) + end + end + return pdfimmediateobj(tostring(data)) + end + else + if trace_objects and trace_detail then + logs.report("backends", "flushing object data -> %s",tostring(name)) + end + return pdfimmediateobj(tostring(name)) + end +end + +function lpdf.sharedobj(content) + local r = cache[content] + if not r then + r = pdfreference(pdfimmediateobj(content)) + cache[content] = r + end + return r +end + +--~ local d = lpdf.dictionary() +--~ local e = lpdf.dictionary { ["e"] = "abc", x = lpdf.dictionary { ["f"] = "ABC" } } +--~ local f = lpdf.dictionary { ["f"] = "ABC" } +--~ local a = lpdf.array { lpdf.array { lpdf.string("xxx") } } + +--~ print(a) +--~ os.exit() + +--~ d["test"] = lpdf.string ("test") +--~ d["more"] = "more" +--~ d["bool"] = true +--~ d["numb"] = 1234 +--~ d["oeps"] = lpdf.dictionary { ["hans"] = "ton" } +--~ d["whow"] = lpdf.array { lpdf.string("ton") } + +--~ a[#a+1] = lpdf.string("xxx") +--~ a[#a+1] = lpdf.string("yyy") + +--~ d.what = a + +--~ print(e) + +--~ local d = lpdf.dictionary() +--~ d["abcd"] = { 1, 2, 3, "test" } +--~ print(d) +--~ print(d()) + +--~ local d = lpdf.array() +--~ d[#d+1] = 1 +--~ d[#d+1] = 2 +--~ d[#d+1] = 3 +--~ d[#d+1] = "test" +--~ print(d) + +--~ local d = lpdf.array() +--~ d[#d+1] = { 1, 2, 3, "test" } +--~ print(d) + +--~ local d = lpdf.array() +--~ d[#d+1] = { a=1, b=2, c=3, d="test" } +--~ print(d) + +--~ local s = lpdf.constant("xx") +--~ print(s) -- fails somehow +--~ print(s()) -- fails somehow + +--~ local s = lpdf.boolean(false) +--~ s.value = true +--~ print(s) +--~ print(s()) + +-- three priority levels, default=2 + +local pagefinalizers, documentfinalizers = { { }, { }, { } }, { { }, { }, { } } + +local pageresources, pageattributes, pagesattributes + +local function resetpageproperties() + pageresources = pdfdictionary() + pageattributes = pdfdictionary() + pagesattributes = pdfdictionary() +end + +local function setpageproperties() +--~ texset("global", "pdfpageresources", pageresources ()) +--~ texset("global", "pdfpageattr", pageattributes ()) +--~ texset("global", "pdfpagesattr", pagesattributes()) + pdf.pageresources = pageresources () + pdf.pageattributes = pageattributes () + pdf.pagesattributes = pagesattributes() +end + +function lpdf.addtopageresources (k,v) pageresources [k] = v end +function lpdf.addtopageattributes (k,v) pageattributes [k] = v end +function lpdf.addtopagesattributes(k,v) pagesattributes[k] = v end + +local function set(where,f,when,what) + when = when or 2 + local w = where[when] + w[#w+1] = f + if trace_finalizers then + logs.report("backend","%s set: [%s,%s]",what,when,#w) + end +end + +local function run(where,what) + for i=1,#where do + local w = where[i] + for j=1,#w do + if trace_finalizers then + logs.report("backend","%s finalizer: [%s,%s]",what,i,j) + end + w[j]() + end + end +end + +function lpdf.registerpagefinalizer(f,when) + set(pagefinalizers,f,when,"page") +end + +function lpdf.registerdocumentfinalizer(f,when) + set(documentfinalizers,f,when,"document") +end + +function lpdf.finalizepage() + if not environment.initex then + resetpageproperties() + run(pagefinalizers,"page") + setpageproperties() + end +end + +function lpdf.finalizedocument() + if not environment.initex then + run(documentfinalizers,"document") + function lpdf.finalizedocument() + logs.report("backend","serious error: the document is finalized multiple times") + function lpdf.finalizedocument() end + end + end +end + +-- some minimal tracing, handy for checking the order + +local function trace_set(what,key) + if trace_resources then + logs.report("backend", "setting key '%s' in '%s'",key,what) + end +end +local function trace_flush(what) + if trace_resources then + logs.report("backend", "flushing '%s'",what) + end +end + +lpdf.protectresources = true + +local catalog, info, names = pdfdictionary(), pdfdictionary(), pdfdictionary() + +local function flushcatalog() if not environment.initex then trace_flush("catalog") pdf.catalog = catalog() end end +local function flushinfo () if not environment.initex then trace_flush("info") pdf.info = info () end end +local function flushnames () if not environment.initex then trace_flush("names") pdf.names = names () end end + +function lpdf.addtocatalog(k,v) if not (lpdf.protectresources and catalog[k]) then trace_set("catalog",k) catalog[k] = v end end +function lpdf.addtoinfo (k,v) if not (lpdf.protectresources and info [k]) then trace_set("info", k) info [k] = v end end +function lpdf.addtonames (k,v) if not (lpdf.protectresources and names [k]) then trace_set("names", k) names [k] = v end end + +local dummy = pdfreserveobj() -- else bug in hvmd due so some internal luatex conflict + +local r_extgstates, d_extgstates = pdfreserveobj(), pdfdictionary() local p_extgstates = pdfreference(r_extgstates) +local r_colorspaces, d_colorspaces = pdfreserveobj(), pdfdictionary() local p_colorspaces = pdfreference(r_colorspaces) +local r_patterns, d_patterns = pdfreserveobj(), pdfdictionary() local p_patterns = pdfreference(r_patterns) +local r_shades, d_shades = pdfreserveobj(), pdfdictionary() local p_shades = pdfreference(r_shades) + +local function checkextgstates () if next(d_extgstates ) then lpdf.addtopageresources("ExtGState", p_extgstates ) end end +local function checkcolorspaces() if next(d_colorspaces) then lpdf.addtopageresources("ColorSpace",p_colorspaces) end end +local function checkpatterns () if next(d_patterns ) then lpdf.addtopageresources("Pattern", p_patterns ) end end +local function checkshades () if next(d_shades ) then lpdf.addtopageresources("Shading", p_shades ) end end + +local function flushextgstates () if next(d_extgstates ) then trace_flush("extgstates") pdfimmediateobj(r_extgstates, tostring(d_extgstates )) end end +local function flushcolorspaces() if next(d_colorspaces) then trace_flush("colorspaces") pdfimmediateobj(r_colorspaces,tostring(d_colorspaces)) end end +local function flushpatterns () if next(d_patterns ) then trace_flush("patterns") pdfimmediateobj(r_patterns, tostring(d_patterns )) end end +local function flushshades () if next(d_shades ) then trace_flush("shades") pdfimmediateobj(r_shades, tostring(d_shades )) end end + +local collected = pdfdictionary { + ExtGState = p_extgstates, + ColorSpace = p_colorspaces, + Pattern = p_patterns, + Shading = p_shades, +} ; collected = collected() + +function lpdf.collectedresources() + tex.sprint(tex.ctxcatcodes,collected) +end + +function lpdf.adddocumentextgstate (k,v) d_extgstates [k] = v end +function lpdf.adddocumentcolorspace(k,v) d_colorspaces[k] = v end +function lpdf.adddocumentpattern (k,v) d_patterns [k] = v end +function lpdf.adddocumentshade (k,v) d_shades [k] = v end + +lpdf.registerdocumentfinalizer(flushextgstates,3) +lpdf.registerdocumentfinalizer(flushcolorspaces,3) +lpdf.registerdocumentfinalizer(flushpatterns,3) +lpdf.registerdocumentfinalizer(flushshades,3) + +lpdf.registerdocumentfinalizer(flushcatalog,3) +lpdf.registerdocumentfinalizer(flushinfo,3) +lpdf.registerdocumentfinalizer(flushnames,3) + +lpdf.registerpagefinalizer(checkextgstates,3) +lpdf.registerpagefinalizer(checkcolorspaces,3) +lpdf.registerpagefinalizer(checkpatterns,3) +lpdf.registerpagefinalizer(checkshades,3) + +-- in strc-bkm: lpdf.registerdocumentfinalizer(function() structure.bookmarks.place() end,1) + +function lpdf.rotationcm(a) + local s, c = sind(a), cosd(a) + texwrite(format("%s %s %s %s 0 0 cm",c,s,-s,c)) +end + +-- ! -> universaltime + +local timestamp = os.date("%Y-%m-%dT%X") .. os.timezone(true) + +function lpdf.timestamp() + return timestamp +end + +function lpdf.pdftimestamp(str) + local Y, M, D, h, m, s, Zs, Zh, Zm = match(str,"^(%d%d%d%d)%-(%d%d)%-(%d%d)T(%d%d):(%d%d):(%d%d)([%+%-])(%d%d):(%d%d)$") + return Y and format("D:%s%s%s%s%s%s%s%s'%s'",Y,M,D,h,m,s,Zs,Zh,Zm) +end + +function lpdf.id() + return format("%s.%s",tex.jobname,timestamp) +end + +function lpdf.checkedkey(t,key,kind) + local pn = t[key] + if pn then + local tn = type(pn) + if tn == kind then + if kind == "string" then + return pn ~= "" and pn + elseif kind == "table" then + return next(pn) and pn + else + return pn + end + elseif tn == "string" and kind == "number" then + return tonumber(pn) + end + end +end + +function lpdf.checkedvalue(value,kind) -- code not shared + if value then + local tv = type(value) + if tv == kind then + if kind == "string" then + return value ~= "" and value + elseif kind == "table" then + return next(value) and value + else + return value + end + elseif tv == "string" and kind == "number" then + return tonumber(value) + end + end +end + +function lpdf.limited(n,min,max,default) + if not n then + return default + else + n = tonumber(n) + if not n then + return default + elseif n > max then + return max + elseif n < min then + return min + else + return n + end + end +end + +-- lpdf.addtoinfo("ConTeXt.Version", tex.contextversiontoks) +-- lpdf.addtoinfo("ConTeXt.Time", os.date("%Y.%m.%d %H:%M")) -- :%S +-- lpdf.addtoinfo("ConTeXt.Jobname", tex.jobname) +-- lpdf.addtoinfo("ConTeXt.Url", "www.pragma-ade.com") + +-- saves definitions later on + +backends = backends or { } +backends.pdf = backends.pdf or { + comment = "backend for directly generating pdf output", + nodeinjections = { }, + codeinjections = { }, + registrations = { }, + helpers = { }, +} diff --git a/tex/context/base/lpdf-ini.mkiv b/tex/context/base/lpdf-ini.mkiv new file mode 100644 index 000000000..7c7dce3ef --- /dev/null +++ b/tex/context/base/lpdf-ini.mkiv @@ -0,0 +1,271 @@ +%D \module +%D [ file=lpdf-ini, +%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{lpdf-ini}{1.001} +\registerctxluafile{lpdf-xmp}{1.001} +\registerctxluafile{lpdf-nod}{1.001} +%registerctxluafile{lpdf-col}{1.001} % will be loaded later +\registerctxluafile{lpdf-mis}{1.001} +\registerctxluafile{lpdf-ano}{1.001} +\registerctxluafile{lpdf-ren}{1.001} +\registerctxluafile{lpdf-grp}{1.001} +\registerctxluafile{lpdf-wid}{1.001} +\registerctxluafile{lpdf-fld}{1.001} +\registerctxluafile{lpdf-u3d}{1.001} +\registerctxluafile{lpdf-swf}{1.001} + +\unprotect + +% for the moment here + +%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. This code is +%D somewhat obsolete as we now have metapost embedded. + +\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 + \pdfliteral + {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} + +\unexpanded\def\pdfactualtext#1#2% + {\pdfliteral direct{/Span <> BDC}% + #1% + \pdfliteral direct{EMC}} + +% \starttext +% text \pdfactualtext{Meier}{Müller} text +% \stoptext + +\protect \endinput diff --git a/tex/context/base/lpdf-mis.lua b/tex/context/base/lpdf-mis.lua new file mode 100644 index 000000000..a68c7b487 --- /dev/null +++ b/tex/context/base/lpdf-mis.lua @@ -0,0 +1,292 @@ +if not modules then modules = { } end modules ['lpdf-mis'] = { + version = 1.001, + comment = "companion to lpdf-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- Although we moved most pdf handling to the lua end, we didn't change +-- the overall approach. For instance we share all resources i.e. we +-- don't make subsets for each xform or page. The current approach is +-- quite efficient. A big difference between MkII and MkIV is that we +-- now use forward references. In this respect the MkII code shows that +-- it evolved over a long period, when backends didn't provide forward +-- referencing and references had to be tracked in multiple passes. Of +-- course there are a couple of more changes. + +local next, tostring = next, tostring +local format = string.format +local texsprint, texset = tex.sprint, tex.set +local ctxcatcodes = tex.ctxcatcodes + +local nodeinjections = backends.pdf.nodeinjections +local codeinjections = backends.pdf.codeinjections +local registrations = backends.pdf.registrations + +local copy_node = node.copy + +local pdfliteral, register = nodes.pdfliteral, nodes.register + +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfboolean = lpdf.boolean +local pdfconstant = lpdf.constant +local pdfreference = lpdf.reference +local pdfunicode = lpdf.unicode +local pdfverbose = lpdf.verbose +local pdfstring = lpdf.string +local pdfflushobject = lpdf.flushobject + +local pdfimmediateobj = pdf.immediateobj + +local tobasepoints = number.tobasepoints +local variables = interfaces.variables + +-- + +local positive = register(pdfliteral("/GSpositive gs")) +local negative = register(pdfliteral("/GSnegative gs")) +local overprint = register(pdfliteral("/GSoverprint gs")) +local knockout = register(pdfliteral("/GSknockout gs")) + +local function initializenegative() + local a = pdfarray { 0, 1 } + local g = pdfconstant("ExtGState") + local d = pdfdictionary { + FunctionType = 4, + Range = a, + Domain = a, + } + local negative = pdfdictionary { Type = g, TR = pdfreference(pdf.immediateobj("stream","1 exch sub",d())) } + local positive = pdfdictionary { Type = g, TR = pdfconstant("Identity") } + lpdf.adddocumentextgstate("GSnegative", pdfreference(pdfflushobject(negative))) + lpdf.adddocumentextgstate("GSPositive", pdfreference(pdfflushobject(positive))) + initializenegative = nil +end + +local function initializeoverprint() + local g = pdfconstant("ExtGState") + local knockout = pdfdictionary { Type = g, OP = false, OPM = 0 } + local overprint = pdfdictionary { Type = g, OP = true, OPM = 1 } + lpdf.adddocumentextgstate("GSknockout", pdfreference(pdfflushobject(knockout))) + lpdf.adddocumentextgstate("GSoverprint", pdfreference(pdfflushobject(overprint))) + initializeoverprint = nil +end + +function nodeinjections.overprint() + if initializeoverprint then initializeoverprint() end + return copy_node(overprint) +end +function nodeinjections.knockout () + if initializeoverprint then initializeoverprint() end + return copy_node(knockout) +end + +function nodeinjections.positive() + if initializenegative then initializenegative() end + return copy_node(positive) +end +function nodeinjections.negative() + if initializenegative then initializenegative() end + return copy_node(negative) +end + +-- + +function codeinjections.addtransparencygroup() + -- png: /CS /DeviceRGB /I true + local d = pdfdictionary { + S = pdfconstant("Transparency"), + I = true, + K = true, + } + lpdf.registerpagefinalizer(function() lpdf.addtopageattributes("Group",d) end) -- hm +end + +-- actions (todo: store and update when changed) + +local openpage, closepage, opendocument, closedocument + +function codeinjections.flushdocumentactions(open,close) + opendocument, closedocument = open, close +end + +function codeinjections.flushpageactions(open,close) + openpage, closepage = open, close +end + +local function flushdocumentactions() + if opendocument then + lpdf.addtocatalog("OpenAction",lpdf.pdfaction(opendocument)) + end + if closedocument then + lpdf.addtocatalog("CloseAction",lpdf.pdfaction(closedocument)) + end +end + +local function flushpageactions() + if openpage or closepage then + local d = pdfdictionary() + if openpage then + d.O = lpdf.pdfaction(openpage) + end + if closepage then + d.C = lpdf.pdfaction(closepage) + end + lpdf.addtopageattributes("AA",d) + end +end + +lpdf.registerpagefinalizer(flushpageactions) +lpdf.registerdocumentfinalizer(flushdocumentactions) + +--- info + +function codeinjections.setupidentity(specification) + local title = specification.title or "" + if title ~= "" then + lpdf.addtoinfo("Title", pdfunicode(title), title) + end + local subject = specification.subject or "" + if subject ~= "" then + lpdf.addtoinfo("Subject", pdfunicode(subject), subject) + end + local author = specification.author or "" + if author ~= "" then + lpdf.addtoinfo("Author", pdfunicode(author), author) -- '/Author' in /Info, 'Creator' in XMP + end + local creator = specification.creator or "" + if creator ~= "" then + lpdf.addtoinfo("Creator", pdfunicode(creator), creator) -- '/Creator' in /Info, 'CreatorTool' in XMP + end + lpdf.addtoinfo("CreationDate", pdfstring(lpdf.pdftimestamp(lpdf.timestamp()))) + local date = specification.date or "" + local pdfdate = lpdf.pdftimestamp(date) + if pdfdate then + lpdf.addtoinfo("ModDate", pdfstring(pdfdate), date) + else + -- users should enter the date in 2010-01-19T23:27:50+01:00 format + -- and if not provided that way we use the creation time instead + date = lpdf.timestamp() + lpdf.addtoinfo("ModDate", pdfstring(lpdf.pdftimestamp(date)), date) + end + local keywords = specification.keywords or "" + if keywords ~= "" then + keywords = string.gsub(keywords, "[%s,]+", " ") + lpdf.addtoinfo("Keywords",pdfunicode(keywords), keywords) + end + local id = lpdf.id() + lpdf.addtoinfo("ID", pdfstring(id), id) -- needed for pdf/x +end + +local function flushjavascripts() + local t = javascripts.flushpreambles() + if #t > 0 then + local a = pdfarray() + local pdf_javascript = pdfconstant("JavaScript") + for i=1,#t do + local name, script = t[i][1], t[i][2] + local j = pdfdictionary { + S = pdf_javascript, + JS = pdfreference(pdfimmediateobj("stream",script)), + } + a[#a+1] = pdfstring(name) + a[#a+1] = pdfreference(pdfflushobject(j)) + end + lpdf.addtonames("JavaScript",pdfreference(pdfflushobject(pdfdictionary{ Names = a }))) + end +end + +lpdf.registerdocumentfinalizer(flushjavascripts) + +-- -- -- + +local pagespecs = { + [variables.max] = { "FullScreen", false, false }, + [variables.bookmark] = { "UseOutlines", false, false }, + [variables.fit] = { "UseNone", false, true }, + [variables.doublesided] = { "UseNone", "TwoColumnRight", true }, + [variables.singlesided] = { "UseNone", false, false }, + [variables.default] = { "UseNone", "auto", false }, + [variables.auto] = { "UseNone", "auto", false }, + [variables.none] = { false, false, false }, +} + +local pagespec, topoffset, leftoffset, height, width, doublesided = "default", 0, 0, 0, 0, false + +function codeinjections.setupcanvas(specification) + local paperheight = specification.paperheight + local paperwidth = specification.paperwidth + local paperdouble = specification.doublesided + if paperheight then + texset('global','pdfpageheight',paperheight) + end + if paperwidth then + texset('global','pdfpagewidth',paperwidth) + end + pagespec = specification.mode or pagespec + topoffset = specification.topoffset or 0 + leftoffset = specification.leftoffset or 0 + height = specification.height or tex.pdfpageheight + width = specification.width or tex.pdfpagewidth + if paperdouble ~= nil then + doublesided = paperdouble + end +end + +local function documentspecification() + local spec = pagespecs[pagespec] or pagespecs[variables.default] + if spec then + local mode, layout, fit = spec[1], spec[2], spec[3] + if layout == variables.auto then + if doublesided then + spec = pagespecs[variables.doublesided] -- to be checked voor interfaces + if spec then + mode, layout, fit = spec[1], spec[2], spec[3] + end + else + layout = false + end + end + mode = mode and pdfconstant(mode) + layout = layout and pdfconstant(layout) + fit = fit and pdfdictionary { FitWindow = true } + if layout then + lpdf.addtocatalog("PageLayout",layout) + end + if mode then + lpdf.addtocatalog("PageMode",mode) + end + if fit then + lpdf.addtocatalog("ViewerPreferences",fit) + end + lpdf.addtoinfo ("Trapped", pdfconstant("False")) -- '/Trapped' in /Info, 'Trapped' in XMP + lpdf.addtocatalog("Version", pdfconstant(format("1.%s",tex.pdfminorversion))) + end +end + +-- temp hack: the mediabox is not under our control and has a precision of 4 digits + +local factor = number.dimenfactors.bp + +local function boxvalue(n) -- we could share them + return pdfverbose(format("%0.4f",factor * n)) +end + +local function pagespecification() + local pageheight = tex.pdfpageheight + local box = pdfarray { -- can be cached + boxvalue(leftoffset), + boxvalue(pageheight-topoffset-height), + boxvalue(width-leftoffset), + boxvalue(pageheight-topoffset), + } + lpdf.addtopageattributes("CropBox",box) -- mandate for rendering + lpdf.addtopageattributes("TrimBox",box) -- mandate for pdf/x + -- lpdf.addtopageattributes("BleedBox",box) + -- lpdf.addtopageattributes("ArtBox",box) +end + +lpdf.registerpagefinalizer(pagespecification) +lpdf.registerdocumentfinalizer(documentspecification) diff --git a/tex/context/base/lpdf-nod.lua b/tex/context/base/lpdf-nod.lua new file mode 100644 index 000000000..0ae900123 --- /dev/null +++ b/tex/context/base/lpdf-nod.lua @@ -0,0 +1,53 @@ +if not modules then modules = { } end modules ['lpdf-nod'] = { + version = 1.001, + comment = "companion to lpdf-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local copy_node, new_node = node.copy, node.new + +local pdfliteral = nodes.register(new_node("whatsit", 8)) pdfliteral.mode = 1 +local pdfdest = nodes.register(new_node("whatsit",19)) pdfdest.named_id = 1 -- xyz_zoom untouched +local pdfannot = nodes.register(new_node("whatsit",15)) + +local variables = interfaces.variables + +local views = { -- beware, we do support the pdf keys but this is *not* official + xyz = 0, [variables.standard] = 0, + fit = 1, [variables.fit] = 1, + fith = 2, [variables.width] = 2, + fitv = 3, [variables.height] = 3, + fitb = 4, + fitbh = 5, [variables.minwidth] = 5, + fitbv = 6, [variables.minheight] = 6, + fitr = 7, +} + +function nodes.pdfliteral(str) + local t = copy_node(pdfliteral) + t.data = str + return t +end + +function nodes.pdfannotation(w,h,d,data,n) + local t = copy_node(pdfannot) + if w and w ~= 0 then t.width = w end + if h and h ~= 0 then t.height = h end + if d and d ~= 0 then t.depth = d end + if n then t.objnum = n end + if data and data ~= "" then t.data = data end + return t +end + +function nodes.pdfdestination(w,h,d,name,view,n) + local t = copy_node(pdfdest) + if w and w ~= 0 then t.width = w end + if h and h ~= 0 then t.height = h end + if d and d ~= 0 then t.depth = d end + if n then t.objnum = n end + t.dest_id = name + t.dest_type = views[view] or view or 1 -- fit is default + return t +end diff --git a/tex/context/base/lpdf-pdx.lua b/tex/context/base/lpdf-pdx.lua new file mode 100644 index 000000000..0a440c1e6 --- /dev/null +++ b/tex/context/base/lpdf-pdx.lua @@ -0,0 +1,139 @@ +if not modules then modules = { } end modules ['lpdf-pdx'] = { + version = 1.001, + comment = "companion to lpdf-ini.mkiv", + author = "Peter Rold and Hans Hagen", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", +} + +local codeinjections = backends.codeinjections -- normally it is registered +local variables = interfaces.variables + +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfconstant = lpdf.constant +local pdfreference = lpdf.reference +local pdfflushobject = lpdf.flushobject +local pdfstring = lpdf.string +local pdfverbose = lpdf.verbose + +local lower, gmatch = string.lower, string.gmatch + +local channels = { + gray = 1, + grey = 1, + rgb = 3, + cmyk = 4, +} + +local prefixes = { + gray = "DefaultGray", + grey = "DefaultGray", + rgb = "DefaultRGB", + cmyk = "DefaultCMYK", +} + +local profiles = { } +local defaults = { } +local intents = pdfarray() +local lastprofile = nil + +function codeinjections.useinternalICCprofile(colorspace,filename) + local name = lower(file.basename(filename)) + local profile = profiles[name] + if not profile then + local colorspace = lower(colorspace) + local filename = resolvers.findctxfile(filename) or "" + local channel = channels[colorspace] + if channel and filename ~= "" then + local a = pdfdictionary { N = channel } + profile = pdf.obj { + compresslevel = 0, + immediate = true, + type = "stream", + file = filename, + attr = a(), + } + profiles[name] = profile + end + end + lastprofile = profile + return profile +end + +function codeinjections.useexternalICCprofile(colorspace,name,urls,checksum,version) + local profile = profiles[name] + if not profile then + local u = pdfarray() + for url in gmatch(urls,"([^, ]+)") do + u[#u+1] = pdfdictionary { + FS = pdfconstant("URL"), + F = pdfstring(url), + } + end + local d = pdfdictionary { + ProfileName = name, -- not file name! + ProfileCS = colorspace, + URLs = u, -- array containing at least one URL + CheckSum = pdfverbose { "<", checksum, ">" }, -- 16byte MD5 hash + ICCVersion = pdfverbose { "<", version, ">" }, -- bytes 8..11 from the header of the ICC profile, as a hex string + } + local n = pdfflushobject(d) + profiles[name] = n + lastprofile = n + return n + end +end + +local function embedprofile(colorspace,filename) + local colorspace = lower(colorspace) + local n = codeinjections.useinternaliccprofile(colorspace,filename) + if n then + local a = pdfarray { + pdfconstant("ICCBased"), + pdfreference(n), + } + lpdf.adddocumentcolorspace(prefixes[colorspace],pdfreference(pdfflushobject(a))) -- part of page /Resources + defaults[lower(colorspace)] = filename + end +end + + +function codeinjections.useICCdefaultprofile(colorspace,filename) + defaults[lower(colorspace)] = filename +end + +local function flushembeddedprofiles() + for colorspace, filename in next, defaults do + embedprofile(colorspace,filename) + end +end + +function codeinjections.usePDFXoutputintent(id,name,reference,outputcondition,info) + local d = { + Type = pdfconstant("OutputIntent"), + S = pdfconstant("GTS_PDFX"), + OutputConditionIdentifier = id, + RegistryName = name, + OutputCondition = outputcondition, + Info = info, + } + local icc = lastprofile + if reference == variables.yes then + d["DestOutputProfileRef"] = pdfreference(icc) + else + d["DestOutputProfile"] = pdfreference(icc) + end + -- intents[#intents+1] = pdfdictionary(d) + intents[#intents+1] = pdfreference(pdfflushobject(pdfdictionary(d))) -- nicer as separate object +end + +local function flushoutputintents() + if #intents > 0 then + lpdf.addtocatalog("OutputIntents",pdfreference(pdfflushobject(intents))) + end +end + + +lpdf.registerdocumentfinalizer(flushoutputintents,1) +lpdf.registerdocumentfinalizer(flushembeddedprofiles,1) diff --git a/tex/context/base/lpdf-pdx.mkiv b/tex/context/base/lpdf-pdx.mkiv new file mode 100644 index 000000000..ffb7f5269 --- /dev/null +++ b/tex/context/base/lpdf-pdx.mkiv @@ -0,0 +1,71 @@ +%D \module +%D [ file=lpdf-pdx, +%D version=2010.02.11, +%D title=\CONTEXT\ Backend Macros, +%D subtitle=PDF-X, +%D author=Peter Rolf \& Hans Hagen, +%D date=\currentdate, +%D copyright=\PRAGMA] % and peter +%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-X} + +\unprotect + +% declare default color space +% all device based entries of the same CS are mapped to the defined ICCprofile then; +% i.e. /DeviceRGB --> /ICCBased RGB profile +% TODO: allow multiple default profiles (one per CS) +% +% external ICC profile dictionary (PDF/X-4p and PDF/X-5p) +% +% - ProfileName (not file name!) +% - URLs (array containing at least one URL); the keyword FSA is wrong! +% - CheckSum (16byte MD5 hash) +% - ProfileCS (GRAY,RGB,CMYK) +% - ICCVersion (bytes 8..11 from the header of the ICC profile, as a hex string) + +\registerctxluafile{lpdf-pdx} {} + +% \def\embedICCprofile#1#2% colorspace, name +% {\ctxlua{backends.codeinjections.addiccprofile("#1","#2")}} + +\def\douseinternalICCprofile[#1]% + {\getparameters[\??ic][colorspace=,filename=,#1]% + \ctxlua{backends.codeinjections.useinternalICCprofile( + "\@@iccolorspace","\@@icfilename")}} + +% create a dictionary for an external ICC profile (PDF/X-4p and PDF/X-5pg only) +% the referenced ICC profile is not embedded + +\def\douseexternalICCprofile[#1]% + {\getparameters[\??ic][colorspace=,name=,url=,checksum=,version=,#1]% + \ctxlua{backends.codeinjections.useexternalICCprofile( + "\@@iccolorspace","\@@icname","\@@icurl","\@@icchecksum","\@@icversion")}} + +% use an ICC profile as default colorspace for all device dependend colors; +% all device based entries of the same CS are mapped to the defined ICCprofile then; +% i.e. /DeviceRGB --> /ICCBased RGB profile always embed the profile! + +\def\douseICCdefaultprofile[#1]% + {\getparameters[\??ic][colorspace=,filename=,#1]% + \ctxlua{backends.codeinjections.useICCdefaultprofile( + "\@@iccolorspace","\@@icfilename")}} + +% embedding rules for output intent profile differ for the PDF/X versions + +\def\dousePDFXoutputintent[#1]% + {\getparameters[\??ic][reference=\v!yes,outputcondition=,info=,id=,name=,#1]% + \ctxlua{backends.codeinjections.usePDFXoutputintent( + "\@@icid","\@@icname","\@@icreference","\@@icoutputcondition","\@@icinfo")}} + +\def\useinternalICCprofile{\dosingleempty\douseinternalICCprofile} +\def\useexternalICCprofile{\dosingleempty\douseexternalICCprofile} +\def\useICCdefaultprofile {\dosingleempty\douseICCdefaultprofile } +\def\usePDFXoutputintent {\dosingleempty\dousePDFXoutputintent } + +\protect \endinput + diff --git a/tex/context/base/lpdf-ren.lua b/tex/context/base/lpdf-ren.lua new file mode 100644 index 000000000..e6bbd67fe --- /dev/null +++ b/tex/context/base/lpdf-ren.lua @@ -0,0 +1,207 @@ +if not modules then modules = { } end modules ['lpdf-ren'] = { + version = 1.001, + comment = "companion to lpdf-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- rendering + +local tostring, tonumber, next = tostring, tonumber, next +local format = string.format +local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes + +local nodeinjections = backends.pdf.nodeinjections +local codeinjections = backends.pdf.codeinjections +local registrations = backends.pdf.registrations + +jobreferences = jobreferences or { } +--~ jobreferences.runners = jobreferences.runners or { } +--~ jobreferences.specials = jobreferences.specials or { } +--~ jobreferences.handlers = jobreferences.handlers or { } +jobreferences.executers = jobreferences.executers or { } + +--~ local runners = jobreferences.runners +--~ local specials = jobreferences.specials +--~ local handlers = jobreferences.handlers +local executers = jobreferences.executers + +local variables = interfaces.variables + +local pdfconstant = lpdf.constant +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfreference = lpdf.reference +local pdfflushobject = lpdf.flushobject + +local pdf_ocg = pdfconstant("OCG") +local pdf_ocmd = pdfconstant("OCMD") +local pdf_off = pdfconstant("OFF") +local pdf_on = pdfconstant("ON") +local pdf_toggle = pdfconstant("Toggle") +local pdf_setocgstate = pdfconstant("SetOCGState") + +local lpdf_usage = pdfdictionary { Print = pdfdictionary { PrintState = pdfconstant("OFF") } } + +local pdfln, pdfld = { }, { } +local textlayers, hidelayers, videlayers = pdfarray(), pdfarray(), pdfarray() +local pagelayers = pdfdictionary() + +lpdf.layerreferences = pdfln + +function backends.pdf.layerreference(name) + return pdfln[name] +end + +function codeinjections.defineviewerlayer(specification) + if textlayers then + local tag = specification.tag + -- todo: reserve + local n = pdfdictionary { + Type = pdf_ocg, + Name = specification.title or "unknown", + Intent = ((specification.kind > 0) and pdf_design) or nil, -- disable layer hiding by user + Usage = ((specification.printable == variables.no) and lpdf_usage) or nil , -- printable or not + } + local nr = pdfreference(pdfflushobject(n)) + pdfln[tag] = nr -- was n + local d = pdfdictionary { + Type = pdf_ocmd, + OCGs = pdfarray { nr }, + } + local dr = pdfreference(pdfflushobject(d)) + pdfld[tag] = dr + textlayers[#textlayers+1] = nr + if specification.visible == variables.start then + videlayers[#videlayers+1] = nr + else + hidelayers[#hidelayers+1] = nr + end + pagelayers[tag] = dr -- check + end +end + +local function flushtextlayers() + if textlayers and #textlayers > 0 then + local d = pdfdictionary { + OCGs = textlayers, + D = pdfdictionary { + Order = textlayers, + ON = videlayers, + OFF = hidelayers, + }, + } + lpdf.addtocatalog("OCProperties",d) + textlayers = nil + end +end + +local function flushpagelayers() + if next(pagelayers) then + lpdf.addtopageresources("Properties",pagelayers) + end +end + +lpdf.registerpagefinalizer (flushpagelayers) +lpdf.registerdocumentfinalizer(flushtextlayers) + +local function setlayer(what,arguments) + -- maybe just a gmatch of even better, earlier in lpeg + arguments = (type(arguments) == "table" and arguments) or aux.settings_to_array(arguments) + local state = pdfarray { what } + for i=1,#arguments do + local p = pdfln[arguments[i]] + if p then + state[#state+1] = p + end + end + return pdfdictionary { + S = pdf_setocgstate, + State = state, + } +end + +function executers.hidelayer (arguments) setlayer(pdf_off, arguments) end +function executers.videlayer (arguments) setlayer(pdf_on, arguments) end +function executers.togglelayer(arguments) setlayer(pdf_toggle,arguments) end + +-- transitions + +local 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"}, +} + +local mapping = { + split = { "S" , pdfconstant("Split") }, + blinds = { "S" , pdfconstant("Blinds") }, + box = { "S" , pdfconstant("Box") }, + wipe = { "S" , pdfconstant("Wipe") }, + dissolve = { "S" , pdfconstant("Dissolve") }, + glitter = { "S" , pdfconstant("Glitter") }, + replace = { "S" , pdfconstant("R") }, + fly = { "S" , pdfconstant("Fly") }, + push = { "S" , pdfconstant("Push") }, + cover = { "S" , pdfconstant("Cover") }, + uncover = { "S" , pdfconstant("Uncover") }, + fade = { "S" , pdfconstant("Fade") }, + horizontal = { "Dm" , pdfconstant("H") }, + vertical = { "Dm" , pdfconstant("V") }, + ["in"] = { "M" , pdfconstant("I") }, + out = { "M" , pdfconstant("O") }, + east = { "Di" , 0 }, + north = { "Di" , 90 }, + west = { "Di" , 180 }, + south = { "Di" , 270 }, +} + +local last = 0 + +-- n: number, "stop", "reset", "random", "a,b,c" delay: number, "none" + +function codeinjections.setpagetransition(specification) + local n, delay = specification.n, specification.delay + if n == variables.auto then + if last >= #pagetransitions then + last = 0 + end + n = last + 1 + elseif n == variables.stop then + return + elseif n == variables.reset then + last = 0 + return + elseif n == variables.random then + n = math.random(1,#pagetransitions) + else + n = tonumber(n) + end + local t = n and pagetransitions[n] or pagetransitions[1] + if not t then + t = aux.settings_to_array(n) + end + if t and #t > 0 then + local d = pdfdictionary() + for i=1,#t do + local m = mapping[t[i]] + d[m[1]] = m[2] + end + delay = tonumber(delay) + if delay and delay > 0 then + lpdf.addtopageattributes("Dur",delay) + end + lpdf.addtopageattributes("Trans",d) + end +end diff --git a/tex/context/base/lpdf-swf.lua b/tex/context/base/lpdf-swf.lua new file mode 100644 index 000000000..9fe0cd09f --- /dev/null +++ b/tex/context/base/lpdf-swf.lua @@ -0,0 +1,109 @@ +if not modules then modules = { } end modules ['lpdf-swf'] = { + version = 1.001, + comment = "companion to lpdf-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- The following code is based on tests by Luigi Scarso. His prototype +-- was using tex code. This is the official implementation. + +local format = string.format + +local pdfconstant = lpdf.constant +local pdfboolean = lpdf.boolean +local pdfstring = lpdf.string +local pdfunicode = lpdf.unicode +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfnull = lpdf.null +local pdfreference = lpdf.reference + +function backends.pdf.helpers.insertswf(spec) + + local width, height, filename = spec.width, spec.height, spec.foundname + + local eref = backends.codeinjections.embedfile(filename) + + local flash = pdfdictionary { + Subtype = pdfconstant("Flash"), + Instances = pdfarray { + pdfdictionary { + Asset = eref, + Params = pdfdictionary { + Binding = pdfconstant("Foreground") + } + }, + }, + } + + local fref = pdfreference(pdf.immediateobj(tostring(flash))) + + local configuration = pdfdictionary { + Configurations = pdfarray { fref }, + Assets = pdfdictionary { + Names = pdfarray { + pdfstring(filename), + eref, + } + }, + } + + local cref = pdfreference(pdf.immediateobj(tostring(configuration))) + + local activation = pdfdictionary { + Activation = pdfdictionary { + Type = pdfconstant("RichMediaActivation"), + Condition = pdfconstant("PO"), + Configuration = fref, + Animation = pdfdictionary { + Subtype = pdfconstant("Linear"), + Speed = 1, + Playcount = 1, + }, + Deactivation = pdfdictionary { + Type = pdfconstant("RichMediaDeactivation"), + Condition = pdfconstant("XD"), + }, + Presentation = pdfdictionary { + PassContextClick = false, + Style = pdfconstant("Embedded"), + Toolbar = false, + NavigationPane = false, + Transparent = true, + Window = pdfdictionary { + Type = pdfconstant("RichMediaWindow"), + Width = pdfdictionary { + Default = 100, + Min = 100, + Max = 100, + }, + Height = pdfdictionary { + Default = 100, + Min = 100, + Max = 100, + }, + Position = pdfdictionary { + Type = pdfconstant("RichMediaPosition"), + HAlign = pdfconstant("Near"), + VAlign = pdfconstant("Near"), + HOffset = 0, + VOffset = 0, + } + } + } + } + } + + local aref = pdfreference(pdf.immediateobj(tostring(activation))) + + local annotation = pdfdictionary { + Subtype = pdfconstant("RichMedia"), + RichMediaContent = cref, + RichMediaSettings = aref, + } + + return annotation, nil, nil + +end diff --git a/tex/context/base/lpdf-u3d.lua b/tex/context/base/lpdf-u3d.lua new file mode 100644 index 000000000..f7a62c6c9 --- /dev/null +++ b/tex/context/base/lpdf-u3d.lua @@ -0,0 +1,474 @@ +if not modules then modules = { } end modules ['lpdf-u3d'] = { + version = 1.001, + comment = "companion to lpdf-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- The following code is based on a working prototype provided +-- by Michael Vidiassov. It is rewritten using the lpdf library +-- and different checking is used. The macro calls are adapted +-- (and will eventually be removed). The user interface needs +-- an overhaul. There are some messy leftovers that will be +-- removed in future versions. + +local format, find = string.format, string.find +local cos, sin, sqrt, pi, atan2, abs = math.cos, math.sin, math.sqrt, math.pi, math.atan2, math.abs + +local pdfconstant = lpdf.constant +local pdfboolean = lpdf.boolean +local pdfnumber = lpdf.number +local pdfunicode = lpdf.unicode +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfnull = lpdf.null +local pdfreference = lpdf.reference + +local pdfimmediateobj = pdf.immediateobj + +local checkedkey = lpdf.checkedkey +local limited = lpdf.limited + +local schemes = table.tohash { + "Artwork", "None", "White", "Day", "Night", "Hard", + "Primary", "Blue", "Red", "Cube", "CAD", "Headlamp", +} + +local modes = table.tohash { + "Solid", "SolidWireframe", "Transparent", "TransparentWireframe", "BoundingBox", + "TransparentBoundingBox", "TransparentBoundingBoxOutline", "Wireframe", + "ShadedWireframe", "HiddenWireframe", "Vertices", "ShadedVertices", "Illustration", + "SolidOutline", "ShadedIllustration", +} + +local function normalize(x, y, z) + local modulo = sqrt(x*x + y*y + z*z); + if modulo ~= 0 then + return x/modulo, y/modulo, z/modulo + else + return x, y, z + end +end + +local function rotate(vect_x,vect_y,vect_z, tet, axis_x,axis_y,axis_z) + -- rotate vect by tet about axis counterclockwise + local c, s = cos(tet*pi/180), sin(tet*pi/180) + local r = 1 - c + local n = sqrt(axis_x*axis_x+axis_y*axis_y+axis_z*axis_z) + axis_x, axis_y, axis_z = axis_x/n, axis_y/n, axis_z/n + return + (axis_x*axis_x*r+c )*vect_x + (axis_x*axis_y*r-axis_z*s)*vect_y + (axis_x*axis_z*r+axis_y*s)*vect_z, + (axis_x*axis_y*r+axis_z*s)*vect_x + (axis_y*axis_y*r+c )*vect_y + (axis_y*axis_z*r-axis_x*s)*vect_z, + (axis_x*axis_z*r-axis_y*s)*vect_x + (axis_y*axis_z*r+axis_x*s)*vect_y + (axis_z*axis_z*r+c )*vect_z +end + +local function make3dview(view) + + local name = view.name + local name = pdfunicode(name ~= "" and name or "unknown view") + + local viewdict = pdfdictionary { + Type = pdfconstant("3DView"), + XN = name, + IN = name, + NR = true, + } + + local bg = checkedkey(view,"bg","table") + if bg then + viewdict.BG = pdfdictionary { + Type = pdfconstant("3DBG"), + C = pdfarray { limited(bg[1],1,1,1), limited(bg[2],1,1,1), limited(bg[3],1,1,1) }, + } + end + + local lights = checkedkey(view,"lights","string") + if lights and schemes[lights] then + viewdict.LS = pdfdictionary { + Type = pdfconstant("3DLightingScheme"), + Subtype = pdfconstant(lights), + } + end + + -- camera position is taken from 3d model + + local u3dview = checkedkey(view, "u3dview", "string") + if u3dview then + viewdict.MS = pdfconstant("U3D") + viewdict.U3DPath = u3dview + end + + -- position the camera as given + + local c2c = checkedkey(view, "c2c", "table") + local coo = checkedkey(view, "coo", "table") + local roo = checkedkey(view, "roo", "number") + local azimuth = checkedkey(view, "azimuth", "number") + local altitude = checkedkey(view, "altitude", "number") + + if c2c or coo or roo or azimuth or altitude then + + local pos = checkedkey(view, "pos", "table") + local dir = checkedkey(view, "dir", "table") + local upv = checkedkey(view, "upv", "table") + local roll = checkedkey(view, "roll", "table") + + local coo_x, coo_y, coo_z = 0, 0, 0 + local dir_x, dir_y, dir_z = 0, 0, 0 + local trans_x, trans_y, trans_z = 0, 0, 0 + local left_x, left_y, left_z = 0, 0, 0 + local up_x, up_y, up_z = 0, 0, 0 + + -- point camera is aimed at + + if coo then + coo_x, coo_y, coo_z = tonumber(coo[1]) or 0, tonumber(coo[2]) or 0, tonumber(coo[3]) or 0 + end + + -- distance from camera to target + + if roo then + roo = abs(roo) + end + if not roo or roo == 0 then + roo = 0.000000000000000001 + end + + -- set it via camera position + + if pos then + dir_x = coo_x - (tonumber(pos[1]) or 0) + dir_y = coo_y - (tonumber(pos[2]) or 0) + dir_z = coo_z - (tonumber(pos[3]) or 0) + if not roo then + roo = sqrt(dir_x*dir_x + dir_y*dir_y + dir_z*dir_z) + end + if dir_x == 0 and dir_y == 0 and dir_z == 0 then dir_y = 1 end + dir_x, dir_y, dir_z = normalize(dir_x,dir_y,dir_z) + end + + -- set it directly + + if dir then + dir_x, dir_y, dir_z = tonumber(dir[1] or 0), tonumber(dir[2] or 0), tonumber(dir[3] or 0) + if dir_x == 0 and dir_y == 0 and dir_z == 0 then dir_y = 1 end + dir_x, dir_y, dir_z = normalize(dir_x,dir_y,dir_z) + end + + -- set it movie15 style with vector from target to camera + + if c2c then + dir_x, dir_y, dir_z = - tonumber(c2c[1] or 0), - tonumber(c2c[2] or 0), - tonumber(c2c[3] or 0) + if dir_x == 0 and dir_y == 0 and dir_z == 0 then dir_y = 1 end + dir_x, dir_y, dir_z = normalize(dir_x,dir_y,dir_z) + end + + -- set it with azimuth and altitutde + + if altitude or azimuth then + dir_x, dir_y, dir_z = -1, 0, 0 + if altitude then dir_x, dir_y, dir_z = rotate(dir_x,dir_y,dir_z, -altitude, 0,1,0) end + if azimuth then dir_x, dir_y, dir_z = rotate(dir_x,dir_y,dir_z, azimuth, 0,0,1) end + end + + -- set it with rotation like in MathGL + + if rot then + if dir_x == 0 and dir_y == 0 and dir_z == 0 then dir_z = -1 end + dir_x,dir_y,dir_z = rotate(dir_x,dir_y,dir_z, tonumber(rot[1]) or 0, 1,0,0) + dir_x,dir_y,dir_z = rotate(dir_x,dir_y,dir_z, tonumber(rot[2]) or 0, 0,1,0) + dir_x,dir_y,dir_z = rotate(dir_x,dir_y,dir_z, tonumber(rot[3]) or 0, 0,0,1) + end + + -- set it with default movie15 orientation looking up y axis + + if dir_x == 0 and dir_y == 0 and dir_z == 0 then dir_y = 1 end + + -- left-vector + -- up-vector + + if upv then + up_x, up_y, up_z = tonumber(upv[1]) or 0, tonumber(upv[2]) or 0, tonumber(upv[3]) or 0 + else + -- set default up-vector + if abs(dir_x) == 0 and abs(dir_y) == 0 then + if dir_z < 0 then + up_y = 1 -- top view + else + up_y = -1 -- bottom view + end + else + -- other camera positions than top and bottom, up-vector = up_world - (up_world dot dir) dir + up_x, up_y, up_z = - dir_z*dir_x, - dir_z*dir_y, - dir_z*dir_z + 1 + end + end + + -- normalize up-vector + + up_x, up_y, up_z = normalize(up_x,up_y,up_z) + + -- left vector = up x dir + + left_x, left_y, left_z = dir_z*up_y - dir_y*up_z, dir_x*up_z - dir_z*up_x, dir_y*up_x - dir_x*up_y + + -- normalize left vector + + left_x, left_y, left_z = normalize(left_x,left_y,left_z) + + -- apply camera roll + + if roll then + local sinroll = sin((roll/180.0)*pi) + local cosroll = cos((roll/180.0)*pi) + left_x = left_x*cosroll + up_x*sinroll + left_y = left_y*cosroll + up_y*sinroll + left_z = left_z*cosroll + up_z*sinroll + up_x = up_x*cosroll + left_x*sinroll + up_y = up_y*cosroll + left_y*sinroll + up_z = up_z*cosroll + left_z*sinroll + end + + -- translation vector + + trans_x, trans_y, trans_z = coo_x - roo*dir_x, coo_y - roo*dir_y, coo_z - roo*dir_z + + viewdict.MS = pdfconstant("M") + viewdict.CO = roo + viewdict.C2W = pdfarray { + left_x, left_y, left_z, + up_x, up_y, up_z, + dir_x, dir_y, dir_z, + trans_x, trans_y, trans_z, + } + + end + + local aac = tonumber(view.aac) -- perspective projection + local mag = tonumber(view.mag) -- ortho projection + + if aac and aac > 0 and aac < 180 then + viewdict.P = pdfdictionary { + Subtype = pdfconstant("P"), + PS = pdfconstant("Min"), + FOV = aac, + } + elseif mag and mag > 0 then + viewdict.P = pdfdictionary { + Subtype = pdfconstant("O"), + OS = mag, + } + end + + local mode = modes[view.rendermode] + if mode then + pdfdictionary { + Type = pdfconstant("3DRenderMode"), + Subtype = pdfconstant(mode), + } + end + + -- crosssection + + local crosssection = checkedkey(view,"crosssection","table") + if crosssection then + local crossdict = pdfdictionary { + Type = pdfconstant("3DCrossSection") + } + + local c = checkedkey(crosssection,"point","table") or checkedkey(crosssection,"center","table") + if c then + crossdict.C = pdfarray { tonumber(c[1]) or 0, tonumber(c[2]) or 0, tonumber(c[3]) or 0 } + end + + local normal = checkedkey(crosssection,"normal","table") + if normal then + local x, y, z = tonumber(normal[1] or 0), tonumber(normal[2] or 0), tonumber(normal[3] or 0) + if sqrt(x*x + y*y + z*z) == 0 then + x, y, z = 1, 0, 0 + end + crossdict.O = pdfarray { + pdfnull, + atan2(-z,sqrt(x*x + y*y))*180/pi, + atan2(y,x)*180/pi, + } + end + + local orient = checkedkey(crosssection,"orient","table") + if orient then + crossdict.O = pdfarray { + tonumber(orient[1]) or 1, + tonumber(orient[2]) or 0, + tonumber(orient[3]) or 0, + } + end + + crossdict.IV = cross.intersection or false + crossdict.ST = cross.transparent or false + + viewdict.SA = next(crossdict) and pdfarray { crossdict } -- maybe test if # > 1 + end + + local nodes = checkedkey(view,"nodes","table") + if nodes then + local nodelist = pdfarray() + for i=1,#nodes do + local node = checkedkey(nodes,i,"table") + if node then + local position = checkedkey(node,"position","table") + nodelist[#nodelist+1] = pdfdictionary { + Type = pdfconstant("3DNode"), + N = node.name or ("node_" .. i), -- pdfunicode ? + M = position and #position == 12 and pdfarray(position), + V = node.visible or true, + O = node.opacity or 0, + RM = pdfdictionary { + Type = pdfconstant("3DRenderMode"), + Subtype = pdfconstant(node.rendermode or "Solid"), + }, + } + end + end + viewdict.NA = nodelist + end + + return viewdict + +end + +local stored_js, stored_3d, stored_pr, streams = { }, { }, { }, { } + +function backends.pdf.helpers.insert3d(spec) -- width, height, factor, display, controls, label, foundname + + local width, height, factor = spec.width, spec.height, spec.factor or number.dimenfactors.bp + local display, controls, label, foundname = spec.display, spec.controls, spec.label, spec.foundname + + local param = (display and parametersets[display]) or { } + local streamparam = (controls and parametersets[controls]) or { } + local name = "3D Artwork " .. (param.name or label or "Unknown") + + local activationdict = pdfdictionary { + TB = pdfboolean(param.toolbar,true), + NP = pdfboolean(param.tree,false), + } + + local stream = streams[label] + if not stream then + + local subtype, subdata = "U3D", io.loaddata(foundname) or "" + if find(subdata,"^PRC") then + subtype = "PRC" + elseif find(subdata,"^U3D") then + subtype = "U3D" + elseif file.extname(foundname) == "prc" then + subtype = "PRC" + end + + local attr = pdfdictionary { + Type = pdfconstant("3D"), + Subtype = pdfconstant(subtype), + } + local streamviews = checkedkey(streamparam, "views", "table") + if streamviews then + local list = pdfarray() + for i=1,#streamviews do + local v = checkedkey(streamviews, i, "table") + if v then + list[#list+1] = make3dview(v) + end + end + attr.VA = list + end + if checkedkey(streamparam, "view", "table") then + attr.DV = make3dview(streamparam.view) + elseif checkedkey(streamparam, "view", "string") then + attr.DV = streamparam.view + end + local js = checkedkey(streamparam, "js", "string") + if js then + local jsref = stored_js[js] + if not jsref then + jsref = pdfimmediateobj("streamfile",js) + stored_js[js] = jsref + end + attr.OnInstantiate = pdfreference(jsref) + end + stored_3d[label] = pdfimmediateobj("streamfile",foundname,attr()) + stream = 1 + else + stream = stream + 1 + end + streams[label] = stream + + local name = pdfunicode(name) + + local annot = pdfdictionary { + Subtype = pdfconstant("3D"), + T = name, + Contents = name, + NM = name, + ["3DD"] = pdfreference(stored_3d[label]), + ["3DA"] = activationdict, + } + if checkedkey(param,"view","table") then + annot["3DV"] = make3dview(param.view) + elseif checkedkey(param,"view","string") then + annot["3DV"] = param.view + end + + local preview = checkedkey(param,"preview","string") + if preview then + activationdict.A = pdfconstant("XA") + local tag = format("%s:%s:%s",label,stream,preview) + local ref = stored_pr[tag] + if not ref then + local figure = img.immediatewrite { + filename = preview, + width = width, + height = height + } + -- local figure = img.immediatewrite { + -- stream = ".5 .75 .75 rg 0 0 20 10 re f", + -- bbox = { 0, 0, 20, 10 } + -- } + ref = figure.objnum + stored_pr[tag] = ref + end + if ref then + local zero, one = pdfnumber(0), pdfnumber(1) -- not really needed + local pw = pdfdictionary { + Type = pdfconstant("XObject"), + Subtype = pdfconstant("Form"), + FormType = one, + BBox = pdfarray { zero, zero, pdfnumber(factor*width), pdfnumber(factor*height) }, + Matrix = pdfarray { one, zero, zero, one, zero, zero }, + Resources = pdfdictionary { + XObject = pdfdictionary { + IM = pdfreference(ref) + } + }, + ExtGState = pdfdictionary { + GS = pdfdictionary { + Type = pdfconstant("ExtGState"), + CA = one, + ca = one, + } + }, + ProcSet = pdfarray { pdfconstant("PDF"), pdfconstant("ImageC") }, + } + local pwd = pdfimmediateobj( + "stream", + format("q /GS gs %s 0 0 %s 0 0 cm /IM Do Q", + factor*width,factor*height), + pw() + ) + annot.AP = pdfdictionary { + N = pdfreference(pwd) + } + end + return annot, figure, ref + else + activationdict.A = pdfconstant("PV") + return annot, nil, nil + end +end diff --git a/tex/context/base/lpdf-wid.lua b/tex/context/base/lpdf-wid.lua new file mode 100644 index 000000000..40a81e7d4 --- /dev/null +++ b/tex/context/base/lpdf-wid.lua @@ -0,0 +1,355 @@ +if not modules then modules = { } end modules ['lpdf-wid'] = { + version = 1.001, + comment = "companion to lpdf-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format, gmatch, gsub, find = string.format, string.gmatch, string.gsub, string.find +local texsprint, ctxcatcodes, texbox, texcount = tex.sprint, tex.ctxcatcodes, tex.box, tex.count + +local nodeinjections = backends.pdf.nodeinjections +local codeinjections = backends.pdf.codeinjections +local registrations = backends.pdf.registrations + +local executers = jobreferences.executers +local variables = interfaces.variables + +local pdfconstant = lpdf.constant +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfreference = lpdf.reference +local pdfunicode = lpdf.unicode +local pdfstring = lpdf.string +local pdfcolorspec = lpdf.colorspec +local pdfflushobject = lpdf.flushobject +local pdfreserveobject = lpdf.reserveobject + +local pdfreserveobj = pdf.reserveobj +local pdfimmediateobj = pdf.immediateobj + +local pdfannotation = nodes.pdfannotation + +local hpack_node, write_node = node.hpack, node.write + +-- symbols + +local presets = { } -- xforms + +function codeinjections.registersymbol(name,n) + presets[name] = pdfreference(n) +end + +function codeinjections.registeredsymbol(name) + return presets[name] +end + +function codeinjections.presetsymbol(symbol) + if not presets[symbol] then + texsprint(ctxcatcodes,format("\\predefinesymbol[%s]",symbol)) + end +end + +function codeinjections.presetsymbollist(list) + if list then + for symbol in gmatch(list,"[^, ]+") do + codeinjections.presetsymbol(symbol) + end + end +end + +-- comments + +local symbols = { + New = pdfconstant("Insert"), + Insert = pdfconstant("Insert"), + Balloon = pdfconstant("Comment"), + Comment = pdfconstant("Comment"), + Text = pdfconstant("Note"), + Addition = pdfconstant("NewParagraph"), + NewParagraph = pdfconstant("NewParagraph"), + Help = pdfconstant("Help"), + Paragraph = pdfconstant("Paragraph"), + Key = pdfconstant("Key"), + Graph = pdfconstant("Graph"), + Paperclip = pdfconstant("Paperclip"), + Attachment = pdfconstant("Attachment"), + Tag = pdfconstant("Tag"), +} + +symbols[variables.normal] = pdfconstant("Note") + +local nofcomments, usepopupcomments, stripleading = 0, true, true + +local function analyzesymbol(symbol) + if not symbol or symbol == "" then + return symbols.normal, nil + elseif symbols[symbol] then + return symbols[symbol], nil + else + local set = aux.settings_to_array(symbol) + local normal, down = set[1], set[2] + if normal then + normal = codeinjections.registeredsymbol(down or normal) + end + if down then + down = codeinjections.registeredsymbol(normal) + end + if down or normal then + return nil, pdfdictionary { + N = normal, + D = down, + } + end + end +end + +local function analyzelayer(layer) + -- todo: (specification.layer ~= "" and pdfreference(specification.layer)) or nil, -- todo: ref to layer +end + +function codeinjections.registercomment(specification) + nofcomments = nofcomments + 1 + local text = buffers.collect(specification.buffer) + if stripleading then + text = gsub(text,"[\n\r] *","\n") + end + local name, appearance = analyzesymbol(specification.symbol) + local d = pdfdictionary { + Subtype = pdfconstant("Text"), + Open = specification.open, + Contents = pdfunicode(text), + T = (specification.title ~= "" and pdfunicode(specification.title)) or nil, + C = pdfcolorspec(specification.colormodel,specification.colorvalue), + OC = analyzelayer(specification.layer), + Name = name, + AP = appearance, + } + -- watch the nice feed back to tex hack + if usepopupcomments then + local nd = pdfreserveobject() + local nc = pdfreserveobject() + local c = pdfdictionary { + Subtype = pdfconstant("Popup"), + Parent = pdfreference(nd), + } + d.Popup = pdfreference(nc) + texbox["commentboxone"] = hpack_node(pdfannotation(0,0,0,d(),nd)) -- current dir + texbox["commentboxtwo"] = hpack_node(pdfannotation(specification.width,specification.height,0,c(),nc)) -- current dir + else + texbox["commentboxone"] = hpack_node(pdfannotation(0,0,0,d())) -- current dir + texbox["commentboxtwo"] = nil + end +end + +-- + +local nofattachments, attachments, filestreams = 0, { }, { } + +function codeinjections.embedfile(filename) + local r = filestreams[filename] + if r == false then + return nil + elseif r then + return r + elseif not lfs.isfile(filename) then + interfaces.showmessage("interactions",5,filename) + filestreams[filename] = false + return nil + else + local basename = file.basename(filename) + local a = pdfdictionary { Type = pdfconstant("EmbeddedFile") } + local f = pdfimmediateobj("streamfile",filename,a()) + local d = pdfdictionary { + Type = pdfconstant("Filespec"), + F = pdfstring(newname or basename), + UF = pdfstring(newname or basename), + EF = pdfdictionary { F = pdfreference(f) }, + } + local r = pdfreference(pdfflushobject(d)) + filestreams[filename] = r + return r + end +end + +function codeinjections.attachfile(specification) + local attachment = interactions.attachment(specification.label) + if not attachment then + -- todo: message + return + end + local filename = attachment.filename + if not filename or filename == "" then + -- todo: message + return + end + nofattachments = nofattachments + 1 + local label = attachment.label or "" + local title = attachment.title or "" + local newname = attachment.newname or "" + if label == "" then label = filename end + if title == "" then title = label end + if newname == "" then newname = filename end + local aref = attachments[label] + if not aref then + aref = codeinjections.embedfile(filename,newname) + attachments[label] = aref + end + local name, appearance = analyzesymbol(specification.symbol) + local d = pdfdictionary { + Subtype = pdfconstant("FileAttachment"), + FS = aref, + Contents = pdfunicode(title), + Name = name, + AP = appearance, + OC = analyzelayer(specification.layer), + C = pdfcolorspec(specification.colormodel,specification.colorvalue), + } + -- as soon as we can ask for the dimensions of an xform we can + -- use them here + local width = specification.width or 0 + local height = specification.height or 0 + local depth = specification.depth or 0 + write_node(pdfannotation(width,height,depth,d())) +end + +function codeinjections.attachmentid(filename) + return filestreams[filename] +end + +-- rendering stuff +-- +-- object_1 -> <> >> +-- object_2 -> <> >> +-- rendering -> <> +-- +-- we only work foreward here +-- annotation is to be packed at the tex end + +-- 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 + +local ms, mu, mf = { }, { }, { } + +local delayed = { } + +local function insertrenderingwindow(label,width,height,specification) + if options == variables.auto then + if openpageaction then + -- \handlereferenceactions{\v!StartRendering{#2}} + end + if closepageaction then + -- \handlereferenceactions{\v!StopRendering {#2}} + end + end + local actions = nil + if openpage or closepage then + actions = pdfdictionary { + PO = (openpage and lpdf.pdfaction(openpage )) or nil, + PC = (closepage and lpdf.pdfaction(closepage)) or nil, + } + end + local page = tonumber(specification.page) or texcount.realpageno + local d = pdfdictionary { + Subtype = pdfconstant("Screen"), + P = pdfreference(tex.pdfpageref(page)), + A = mf[label], + Border = pdfarray { 0, 0, 0 } , + AA = actions, + } + local r = pdfreserveobj("annot") + write_node(pdfannotation(width,height,0,d(),r)) -- save ref + return pdfreference(r) +end + +local function insertrendering(specification) + local label = specification.label + if not mf[label] then + local filename = specification.filename + local isurl = find(filename,"://") + local d = pdfdictionary { + Type = pdfconstant("Rendition"), + S = pdfconstant("MR"), + C = pdfdictionary { + Type = pdfconstant("MediaClip"), + S = pdfconstant("MCD"), + N = label, + CT = specification.mime, + Alt = pdfarray { + "", "file not found", -- language id + message + }, + D = pdfdictionary { + Type = pdfconstant("Filespec"), + F = filename, + FS = (isurl and pdfconstant("URL")) or nil, + } + } + } + mf[label] = pdfreference(pdfflushobject(d)) + if not ms[label] then + mu[label] = insertrenderingwindow(label,0,0,specification.options) + end + end +end + +local function insertrenderingobject(specification) + local label = specification.label + if not mf[label] then + local d = pdfdictionary { + Type = pdfconstant("Rendition"), + S = pdfconstant("MR"), + C = pdfdictionary { + Type = pdfconstant("MediaClip"), + S = pdfconstant("MCD"), + N = label, + D = pdfreference(unknown), -- not label but objectname, hm + } + } + mf[label] = pdfreference(pdfflushobject(d)) + if ms[label] then + insertrenderingwindow(label,0,0,specification) + end + end +end + +function codeinjections.insertrenderingwindow(specification) + local label = specification.label + codeinjections.processrendering(label) -- was check at tex end + ms[label] = insertrenderingwindow(label,specification.width,specification.height,specification) +end + +function codeinjections.processrendering(label) + local specification = interactions.rendering(label) + if specification then + if specification.kind == "external" then + insertrendering(specification) + else + insertrenderingobject(specification) + end + end +end + +local function set(operation,arguments) + codeinjections.processrendering(arguments) -- was check at the tex end + return pdfdictionary { + S = pdfconstant("Rendition"), + OP = operation, + R = mf[arguments], + AN = ms[arguments] or mu[arguments], + } +end + +function executers.startrendering (arguments) return set(0,arguments) end +function executers.stoprendering (arguments) return set(1,arguments) end +function executers.pauserendering (arguments) return set(2,arguments) end +function executers.resumerendering(arguments) return set(3,arguments) end diff --git a/tex/context/base/lpdf-xmp.lua b/tex/context/base/lpdf-xmp.lua new file mode 100644 index 000000000..c8e7b2b57 --- /dev/null +++ b/tex/context/base/lpdf-xmp.lua @@ -0,0 +1,165 @@ +if not modules then modules = { } end modules ['lpdf-xmp'] = { + version = 1.001, + comment = "companion to lpdf-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", + comment = "with help from Peter Rolf", +} + +local format, random, char, gsub, concat = string.format, math.random, string.char, string.gsub, table.concat +local xmlfillin = xml.fillin + +local trace_xmp = false trackers.register("backend.xmp", function(v) trace_xmp = v end) + +local pdfdictionary = lpdf.dictionary +local pdfconstant = lpdf.constant + +-- i wonder why this begin end is empty / w (no time now to look into it) + +local xpacket = [[ + + +%s + +]] + +local mapping = { + -- user defined keys (pdfx:) + ["ConTeXt.Jobname"] = "rdf:Description/pdfx:ConTeXt.Jobname", + ["ConTeXt.Time"] = "rdf:Description/pdfx:ConTeXt.Time", + ["ConTeXt.Url"] = "rdf:Description/pdfx:ConTeXt.Url", + ["ConTeXt.Version"] = "rdf:Description/pdfx:ConTeXt.Version", + ["ID"] = "rdf:Description/pdfx:ID", + ["PTEX.Fullbanner"] = "rdf:Description/pdfx:PTEX.Fullbanner", + -- Adobe PDF schema + ["Keywords"] = "rdf:Description/pdf:Keywords", + ["Producer"] = "rdf:Description/pdf:Producer", + -- ["Trapped"] = "rdf:Description/pdf:Trapped", -- '/False' in /Info, but 'False' in XMP + -- Dublin Core schema + ["Author"] = "rdf:Description/dc:creator/rdf:Seq/rdf:li", + ["Format"] = "rdf:Description/dc:format", -- optional, but nice to have + ["Subject"] = "rdf:Description/dc:description", + ["Title"] = "rdf:Description/dc:title/rdf:Alt/rdf:li", + -- XMP Basic schema + ["CreateDate"] = "rdf:Description/xmp:CreateDate", + ["Creator"] = "rdf:Description/xmp:CreatorTool", + ["MetadataDate"] = "rdf:Description/xmp:MetadataDate", + ["ModifyDate"] = "rdf:Description/xmp:ModifyDate", + -- XMP Media Management schema + ["DocumentID"] = "rdf:Description/xmpMM:DocumentID", + ["InstanceID"] = "rdf:Description/xmpMM:InstanceID", + ["RenditionClass"] = "rdf:Description/xmpMM:RenditionClass", -- PDF/X-4 + ["VersionID"] = "rdf:Description/xmpMM:VersionID", -- PDF/X-4 + -- additional entries + -- PDF/X + ["GTS_PDFXVersion"] = "rdf:Description/pdfxid:GTS_PDFXVersion", + -- optional entries + -- all what is visible in the 'document properties --> additional metadata' window + -- XMP Rights Management schema (optional) + ["Marked"] = "rdf:Description/xmpRights:Marked", + -- ["Owner"] = "rdf:Description/xmpRights:Owner/rdf:Bag/rdf:li", -- maybe useful (not visible) + -- ["UsageTerms"] = "rdf:Description/xmpRights:UsageTerms", -- maybe useful (not visible) + ["WebStatement"] = "rdf:Description/xmpRights:WebStatement", + -- Photoshop PDF schema (optional) + ["AuthorsPosition"] = "rdf:Description/photoshop:AuthorsPosition", + ["Copyright"] = "rdf:Description/photoshop:Copyright", + ["CaptionWriter"] = "rdf:Description/photoshop:CaptionWriter", +} + +-- maybe some day we will load the xmp file at runtime + +local xmp, xmpfile, xmpname = nil, nil, "lpdf-xmp.xml" + +function lpdf.setxmpfile(name) + xmpfile = resolvers.findctxfile(name) or "" + if xmpfile == "" then + xmpfile = nil + end +end + +local function valid_xmp() + if not xmp then + local xmpfile = xmpfile or resolvers.find_file(xmpname) or "" + local xmpdata = (xmpfile ~= "" and io.loaddata(xmpfile)) or "" + xmp = xml.convert(xmpdata) + end + return xmp +end + +function lpdf.addxmpinfo(tag,value,check) + local pattern = mapping[tag] + if pattern then + xmlfillin(xmp or valid_xmp(),pattern,value,check) + end +end + +-- redefined + +local addtoinfo = lpdf.addtoinfo +local addxmpinfo = lpdf.addxmpinfo + +function lpdf.addtoinfo(tag,pdfvalue,strvalue) + addtoinfo(tag,pdfvalue) + addxmpinfo(tag,strvalue or gsub(tostring(pdfvalue),"^%((.*)%)$","%1")) -- hack +end + +-- for the do-it-yourselvers + +function lpdf.insertxmpinfo(pattern,whatever,prepend) + xml.insert(xmp or valid_xmp(),pattern,whatever,prepend) +end + +function lpdf.injectxmpinfo(pattern,whatever,prepend) + xml.inject(xmp or valid_xmp(),pattern,whatever,prepend) +end + +-- flushing + +local t = { } for i=1,24 do t[i] = random() end + +local function flushxmpinfo() + + commands.freezerandomseed(os.clock()) -- hack + + local t = { } for i=1,24 do t[i] = char(96 + random(26)) end + local packetid = concat(t) + local time = lpdf.timestamp() + addxmpinfo("Producer",format("LuaTeX-%0.2f.%s",tex.luatexversion/100,tex.luatexrevision)) + addxmpinfo("DocumentID",format("uuid:%s",os.uuid())) + addxmpinfo("InstanceID",format("uuid:%s",os.uuid())) + addxmpinfo("CreatorTool","LuaTeX + ConTeXt MkIV") + addxmpinfo("CreateDate",time) + addxmpinfo("ModifyDate",time) + addxmpinfo("MetadataDate",time) + addxmpinfo("PTEX.Fullbanner", tex.pdftexbanner) + local blob = xml.tostring(xml.first(xmp or valid_xmp(),"/x:xmpmeta")) + local md = pdfdictionary { + Subtype = pdfconstant("XML"), + Type = pdfconstant("Metadata"), + } + if trace_xmp then + commands.writestatus("system","xmp data flushed (see log file)") + texio.write_nl("log","") + texio.write("log","\n% ",(gsub(blob,"[\r\n]","\n%% ")),"\n") + end + blob = format(xpacket,packetid,blob) + if tex.pdfcompresslevel > 0 then + blob = gsub(blob,">%s+<","><") + end + local r = pdf.obj { + immediate = true, + compresslevel = 0, + type = "stream", + string = blob, + attr = md(), + } + lpdf.addtocatalog("Metadata",lpdf.reference(r)) + + commands.defrostrandomseed() -- hack + +end + +-- his will be enabled when we can inhibit compression for a stream at the lua end + +lpdf.registerdocumentfinalizer(flushxmpinfo,1) diff --git a/tex/context/base/lpdf-xmp.xml b/tex/context/base/lpdf-xmp.xml new file mode 100644 index 000000000..2947211bd --- /dev/null +++ b/tex/context/base/lpdf-xmp.xml @@ -0,0 +1,43 @@ + + + + + + application/pdf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + + + + + + + diff --git a/tex/context/base/luat-bas.mkiv b/tex/context/base/luat-bas.mkiv new file mode 100644 index 000000000..581a5d95a --- /dev/null +++ b/tex/context/base/luat-bas.mkiv @@ -0,0 +1,65 @@ +%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{l-dimen} {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 new file mode 100644 index 000000000..3cb63ad6e --- /dev/null +++ b/tex/context/base/luat-cbk.lua @@ -0,0 +1,247 @@ +if not modules then modules = { } end modules ['luat-cbk'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local insert, remove, find = table.insert, table.remove, string.find +local collectgarbage, type, next = collectgarbage, type, next +local round = math.round + +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 +auxiliary functions.

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

When you (temporarily) want to install a callback function, and after a +while wants to revert to the original one, you can use the following two +functions.

+--ldx]]-- + +local trace_callbacks = false trackers.register("system.callbacks", function(v) trace_callbacks = v end) + +local register_callback, find_callback = callback.register, callback.find +local frozen, stack = { }, { } + +callback.original_register_callback = register_callback + +local function frozen_message(what,name) + logs.report("callbacks","not %s frozen '%s' (%s)",what,name,frozen[name]) +end + +local function frozen_callback(name) + return nil, format("callback '%s' is frozen (%s)",name,frozen[name]) +end + +local function state(name) + local f = find_callback(name) + if f == false then + return "disabled" + elseif f then + return "enabled" + else + return "undefined" + end +end + +function callbacks.report() + local list = callback.list() + for name, func in table.sortedhash(list) do + local str = frozen[name] + if str then + logs.report("callbacks","%s: %s -> %s",state(name),name,str) + else + logs.report("callbacks","%s: %s",state(name),name) + end + end +end + +function callbacks.table() + local NC, NR, verbatim = context.NC, context.NR, context.type + context.starttabulate { "|l|l|p|" } + for name, func in table.sortedhash(callback.list()) do + NC() verbatim(name) NC() verbatim(state(name)) NC() context(frozen[name] or "") NC() NR() + end + context.stoptabulate() +end + +function callbacks.freeze(name,freeze) + freeze = type(freeze) == "string" and freeze +--~ print(name) + if find(name,"%*") then + local pattern = name -- string.simpleesc(name) + local list = callback.list() + for name, func in next, list do + if find(name,pattern) then + frozen[name] = freeze or frozen[name] or "frozen" + end + end + else + frozen[name] = freeze or frozen[name] or "frozen" + end +end + +function callbacks.register(name,func,freeze) + if frozen[name] then + if trace_callbacks then + frozen_message("registering",name) + end + return frozen_callback(name) + elseif freeze then + frozen[name] = (type(freeze) == "string" and freeze) or "registered" + end + return register_callback(name,func) +end + +function callback.register(name,func) -- original + if not frozen[name] then + return register_callback(name,func) + elseif trace_callbacks then + frozen_message("registering",name) + end + return frozen_callback(name) +end + +function callbacks.push(name, func) + if not frozen[name] then + local sn = stack[name] + if not sn then + sn = { } + stack[name] = sn + end + insert(sn,find_callback(name)) + register_callback(name, func) + elseif trace_callbacks then + frozen_message("pushing",name) + end +end + +function callbacks.pop(name) + if not frozen[name] then + local sn = stack[name] + if not sn or #sn == 0 then + -- some error + register_callback(name, nil) -- ! really needed + else + -- this fails: register_callback(name, remove(stack[name])) + local func = remove(sn) + register_callback(name, func) + end + end +end + +--~ -- somehow crashes later on +--~ +--~ callbacks.freeze("find_.*_file","finding file") +--~ callbacks.freeze("read_.*_file","reading file") +--~ callbacks.freeze("open_.*_file","opening file") + +--[[ldx-- +

The simple case is to remove the callback:

+ + +callbacks.push('linebreak_filter') +... some actions ... +callbacks.pop('linebreak_filter') + + +

Often, in such case, another callback or a macro call will pop +the original.

+ +

In practice one will install a new handler, like in:

+ + +callbacks.push('linebreak_filter', function(...) + return something_done(...) +end) + + +

Even more interesting is:

+ + +callbacks.push('linebreak_filter', function(...) + callbacks.pop('linebreak_filter') + return something_done(...) +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 +sense to disable or tune the garbage collector in order to +keep the use of resources acceptable.

+ +

At some point in the development we did some tests with counting +nodes (in this case 121049).

+ + + + + + + + + + +
setstepmulsecondsmegabytes
20024.080.5
17521.078.2
15022.074.6
16022.074.6
16521.077.6
12521.589.2
10021.588.4
+ +

The following code is kind of experimental. In the documents +that describe the development of we report +on speed tests. One observation is thta it sometimes helps to +restart the collector. Okay, experimental code has been removed, +because messing aroudn with the gc is too unpredictable.

+--ldx]]-- + +garbagecollector = garbagecollector or { } + +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 +-- files) we get a prominent memory consumption. Even when a variable +-- is nilled, there is some delay in freeing the associated memory (the +-- hashed string) because if we do the same thing directly afterwards, +-- we see only a slight increase in memory. For that reason it makes +-- sense to do a collector pass after a huge file. +-- +-- test file: +-- +-- function test() +-- local b = collectgarbage("count") +-- local s = io.loaddata("some font table, e.g. a big tmc file") +-- local a = collectgarbage("count") +-- print(">>> STATUS",b,a,a-b,#s,1000*(a-b)/#s) +-- end +-- +-- test() test() test() test() collectgarbage("collect") test() test() test() test() +-- +-- 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. + +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 trace_checking then + local b = collectgarbage("count") + collectgarbage("collect") + local a = collectgarbage("count") + logs.report("memory","forced sweep, collected: %s MB, used: %s MB",round((b-a)/1000),round(a/1000)) + else + collectgarbage("collect") + end + 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..e45aceb79 --- /dev/null +++ b/tex/context/base/luat-cnf.lua @@ -0,0 +1,115 @@ +if not modules then modules = { } end modules ['luat-cnf'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format, concat, find = string.format, table.concat, string.find + +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 find(x,"^%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 { } + +-- we provide our own file handling + +texconfig.kpse_init = false +texconfig.shell_escape = 't' + +-- as soon as possible + +luatex.starttime = os.gettimeofday() + +-- 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 + -- collectgarbage('step') + 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.mkiv b/tex/context/base/luat-cod.mkiv new file mode 100644 index 000000000..d3b37d0e1 --- /dev/null +++ b/tex/context/base/luat-cod.mkiv @@ -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. + +\normalprotected\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 + +\normalprotected\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 + \normalexpanded{\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 (modules and core code) + {\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-dum.lua b/tex/context/base/luat-dum.lua new file mode 100644 index 000000000..4530c2ef3 --- /dev/null +++ b/tex/context/base/luat-dum.lua @@ -0,0 +1,126 @@ +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, +} +directives = { + register = dummyfunction, + enable = dummyfunction, + disable = dummyfunction, +} +trackers = { + register = dummyfunction, + enable = dummyfunction, + disable = dummyfunction, +} +experiments = { + register = dummyfunction, + enable = dummyfunction, + disable = dummyfunction, +} +storage = { + register = dummyfunction, + shared = { }, +} +logs = { + report = dummyfunction, + simple = dummyfunction, +} +tasks = { + new = dummyfunction, + actions = dummyfunction, + appendaction = dummyfunction, + prependaction = dummyfunction, +} +callbacks = { + register = function(n,f) return callback.register(n,f) end, +} + +-- 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", + dfont = "truetype dictionary", + cid = "cid maps", + fea = "font feature 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 file.extname(name,"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 + +-- Caches ... I will make a real stupid version some day when I'm in the +-- mood. After all, the generic code does not need the more advanced +-- ConTeXt features. Cached data is not shared between ConTeXt and other +-- usage as I don't want any dependency at all. Also, ConTeXt might have +-- different needs and tricks added. + +caches = { } + +--~ containers.usecache = true + +function caches.setpath(category,subcategory) + local root = kpse.var_value("TEXMFCACHE") or "" + if root == "" then + root = kpse.var_value("VARTEXMF") or "" + end + if root ~= "" then + root = file.join(root,category) + lfs.mkdir(root) + root = file.join(root,subcategory) + lfs.mkdir(root) + return lfs.isdir(root) and root + end +end + +local function makefullname(path,name) + if path and path ~= "" then + name = "temp-" and name -- clash prevention + return file.addsuffix(file.join(path,name),"lua") + end +end + +function caches.iswritable(path,name) + local fullname = makefullname(path,name) + return fullname and file.iswritable(fullname) +end + +function caches.loaddata(path,name) + local fullname = makefullname(path,name) + if fullname then + local data = loadfile(fullname) + return data and data() + end +end + +function caches.savedata(path,name,data) + local fullname = makefullname(path,name) + if fullname then + table.tofile(fullname,data,'return',false,true,false) + end +end diff --git a/tex/context/base/luat-env.lua b/tex/context/base/luat-env.lua new file mode 100644 index 000000000..0e21fca31 --- /dev/null +++ b/tex/context/base/luat-env.lua @@ -0,0 +1,283 @@ +if not modules then modules = { } end modules ['luat-env'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- 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 and so a lot of +-- code has disappeared already. + +local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) + +local format, sub, match, gsub, find = string.format, string.sub, string.match, string.gsub, string.find +local unquote, quote = string.unquote, string.quote + +-- precautions + +os.setlocale(nil,nil) -- useless feature and even dangerous in luatex + +function os.setlocale() + -- no way you can mess with it +end + +-- dirty tricks + +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 + +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=1,#arg do + local argument = arg[index] + if index > 0 then + local flag, value = match(argument,"^%-+(.-)=(.-)$") + if flag then + arguments[flag] = unquote(value or "") + else + flag = match(argument,"^%-+(.+)") + 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 = table.sortedkeys(arguments) + for k=1,#sortedflags do + sortedflags[k] = "^" .. sortedflags[k] + end + environment.sortedflags = sortedflags + end + -- example of potential clash: ^mode ^modefile + for k=1,#sortedflags do + local v = sortedflags[k] + if find(name,v) then + return arguments[sub(v,2,#v)] + end + end + end + return nil +end + +environment.argument("x",true) + +function environment.split_arguments(separator) -- rather special, cut-off before separator + local done, before, after = false, { }, { } + local original_arguments = environment.original_arguments + for k=1,#original_arguments do + local v = original_arguments[k] + 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 = unquote(a) + return a + elseif #arg > 0 then + local result = { } + for i=1,#arg do + local a = arg[i] + a = resolvers.resolve(a) + a = unquote(a) + a = gsub(a,'"','\\"') -- tricky + if find(a," ") then + result[#result+1] = quote(a) + 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 remove the " then and add them later) + local newarg, instring = { }, false + + for index=1,#arg do + local argument = arg[index] + if find(argument,"^\"") then + newarg[#newarg+1] = gsub(argument,"^\"","") + if not find(argument,"\"$") then + instring = true + end + elseif find(argument,"\"$") then + newarg[#newarg] = newarg[#newarg] .. " " .. gsub(argument,"\"$","") + 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 resolvers.find_file(filename,'tex') +end + +function environment.luafile(filename) + 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 + +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 + if trace_locating then + logs.report("fileio","loading file %s", fullname) + end + return environment.loadedluacode(fullname) + else + if trace_locating then + logs.report("fileio","unknown file %s", filename) + end + return nil + end +end + +-- the next ones can use the previous ones / combine + +function environment.loadluafile(filename, version) + local lucname, luaname, chunk + local basename = file.removesuffix(filename) + if basename == filename then + lucname, luaname = basename .. ".luc", basename .. ".lua" + else + lucname, luaname = nil, basename -- forced suffix + end + -- when not overloaded by explicit suffix we look for a luc file first + local fullname = (lucname and environment.luafile(lucname)) or "" + if fullname ~= "" then + if trace_locating 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 + assert(chunk)() + if version then + -- we check of the version number of this chunk matches + local v = version -- can be nil + if modules and modules[filename] then + v = modules[filename].version -- new method + elseif versions and versions[filename] then + v = versions[filename] -- old method + end + if v == version then + return true + else + if trace_locating then + logs.report("fileio","version mismatch for %s: lua=%s, luc=%s", filename, v, version) + end + environment.loadluafile(filename) + end + else + return true + end + end + fullname = (luaname and environment.luafile(luaname)) or "" + if fullname ~= "" then + if trace_locating 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 + if trace_locating then + logs.report("fileio","unknown file %s", filename) + end + else + assert(chunk)() + return true + end + end + return false +end diff --git a/tex/context/base/luat-exe.lua b/tex/context/base/luat-exe.lua new file mode 100644 index 000000000..ca3b75162 --- /dev/null +++ b/tex/context/base/luat-exe.lua @@ -0,0 +1,71 @@ +if not modules then modules = { } end modules ['luat-exe'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local match, find = string.match, string.find +local concat = table.concat + +if not executer then executer = { } end + +executer.permitted = { } +executer.execute = os.execute + +function executer.register(...) + local ep = executer.permitted + local t = { ... } + for k=1,#t do + local v = t[k] + ep[#ep+1] = (v == "*" and ".*") or v + end +end + +function executer.finalize() -- todo: os.exec, todo: report ipv print + local execute = os.execute + function executer.execute(...) + local t, name, arguments = {...}, "", "" + if #t == 1 then + if type(t[1]) == 'table' then + name, arguments = t[1], concat(t," ",2,#t) + else + name, arguments = match(t[1],"^(.-)%s+(.+)$") + if not (name and arguments) then + name, arguments = t[1], "" + end + end + else + name, arguments = t[1], concat(t," ",2,#t) + end + local permitted = executer.permitted + for k=1,#permitted do + local v = permitted[k] + if find(name,v) then + execute(name .. " " .. arguments) + -- print("executed: " .. name .. " " .. arguments) + else + print("not permitted: " .. name .. " " .. arguments) + end + end + end + function executer.finalize() + print("executer is already finalized") + end + function executer.register(name) + print("executer is already finalized") + end + os.execute = executer.execute +end + +--~ executer.register('.*') +--~ executer.register('*') +--~ executer.register('dir','ls') +--~ executer.register('dir') + +--~ executer.finalize() +--~ executer.execute('dir',"*.tex") +--~ executer.execute("dir *.tex") +--~ executer.execute("ls *.tex") +--~ os.execute('ls') diff --git a/tex/context/base/luat-fio.lua b/tex/context/base/luat-fio.lua new file mode 100644 index 000000000..0d1bd1808 --- /dev/null +++ b/tex/context/base/luat-fio.lua @@ -0,0 +1,83 @@ +if not modules then modules = { } end modules ['luat-fio'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + 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) + -- output + callback.register('read_pk_file' , function(file) return resolvers.loadbinfile(file,"pk") end) -- 600dpi/manfnt.720pk + callback.register('read_sfd_file' , function(file) return resolvers.loadbinfile(file,"sfd") 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('find_vf_file' , function(name) return resolvers.findbinfile(name,"ovf") end) + + callback.register('read_font_file' , function(file) return resolvers.loadbinfile(file,"ofm") end) + callback.register('read_vf_file' , function(file) return resolvers.loadbinfile(file,"ovf") end) + + -- callback.register('read_opentype_file' , function(file) return resolvers.loadbinfile(file,"otf") 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('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 new file mode 100644 index 000000000..e6a715c07 --- /dev/null +++ b/tex/context/base/luat-ini.lua @@ -0,0 +1,162 @@ +if not modules then modules = { } end modules ['luat-ini'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + 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 { } -- might be used +thirddata = thirddata or { } -- might be used +moduledata = moduledata or { } -- might be used +document = document or { } +parametersets = parametersets or { } -- experimental + +--[[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!

+ + +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 debug = require "debug" + +local string, table, lpeg, math, io, system = string, table, lpeg, math, io, system +local next, setfenv = next, setfenv or debug.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 + +if not setfenv then + texio.write_nl("warning: we need to fix setfenv by using 'load in' or '_ENV'") +end + +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") + +--~ local arguments, files = document.arguments, document.files -- set later + +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.setfilename(i,name) + document.files[tonumber(i)] = name +end + +function document.getfilename(i) + tex.sprint(tex.ctxcatcodes,document.files[i] or "") +end diff --git a/tex/context/base/luat-ini.mkiv b/tex/context/base/luat-ini.mkiv new file mode 100644 index 000000000..c9d88bf4f --- /dev/null +++ b/tex/context/base/luat-ini.mkiv @@ -0,0 +1,243 @@ +%D \module +%D [ file=luat-ini, +%D version=2005.08.11, +%D title=\CONTEXT\ Lua 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 Lua Macros / Initialization} + +\unprotect + +%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 +%D we keep outside the format. We will keep code outside \TEX\ files as +%D much as possible. + +\ifx\setnaturalcatcodes\undefined \let\setnaturalcatcodes\relax \fi +\ifx\obeylualines \undefined \let\obeylualines \relax \fi +\ifx\obeyluatokens \undefined \let\obeyluatokens \relax \fi + +%D A few more goodies: + +\long\def\dostartlua + {\begingroup + \obeylualines + \dodostartlua} + +\long\def\dodostartlua#1\stoplua + {\normalexpanded{\endgroup\noexpand\directlua\zerocount{#1}}} + +\long\def\dostartluacode + {\begingroup + \obeylualines + \obeyluatokens + \dodostartluacode} + +\long\def\dodostartluacode#1\stopluacode + {\normalexpanded{\endgroup\noexpand\directlua\zerocount{#1}}} + +\unexpanded\def\startlua {\dostartlua } % tex catcodes +\unexpanded\def\startluacode{\dostartluacode} % lua catcodes + +%D Some delayed definitions: + +\ifx\obeylines \undefined \let\obeylines \relax \fi +\ifx\obeyedline \undefined \let\obeyedline \relax \fi +\ifx\obeyspaces \undefined \let\obeyspaces \relax \fi +\ifx\obeyedspace \undefined \let\obeyedspace \relax \fi +\ifx\outputnewlinechar\undefined \let\outputnewlinechar\relax \fi + +%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} \def\!!name{name} \def\s!data{data} + +%D Beware: because \type {\expanded} is een convert command, the error +%D message will show \type{} as part of the message. + +\long\def\dostartnamedluacode#1% + {\begingroup + \obeylualines + \obeyluatokens + \csname dodostartnamed#1\v!code\endcsname} + +\unexpanded\def\definenamedlua[#1]#2[#3]% no optional arg handling here yet + {\scratchcounter\ctxlua{lua.registername("#1","#3")}% + \normalexpanded{\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}}} + +%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\setdocumentargumentdefault#1#2{\ctxlua{document.setdefaultargument("#1","#2")}} +\def\getdocumentfilename #1{\ctxlua{document.getfilename("#1")}} +\def\getdocumentargument #1{\ctxlua{document.getargument("#1")}} +\def\getdocumentargumentdefault#1#2{\ctxlua{document.getargument("#1","#2")}} +\def\doifdocumentargumentelse #1{\doifsomethingelse{\getdocumentargument{#1}}} +\def\doifdocumentargument #1{\doifsomething {\getdocumentargument{#1}}} +\def\doifnotdocumentargument #1{\doifnothing {\getdocumentargument{#1}}} +\def\doifdocumentfilenameelse #1{\doifsomethingelse{\getdocumentfilename{#1}}} +\def\doifdocumentfilename #1{\doifsomething {\getdocumentfilename{#1}}} +\def\doifnotdocumentfilename #1{\doifnothing {\getdocumentfilename{#1}}} + +\let\doifelsedocumentargument\doifdocumentargumentelse + +%D A handy helper: + +\def\luaexpanded#1{\luaescapestring\expandafter{\normalexpanded{#1}}} + +%D Experimental: + +\unexpanded\def\startluaparameterset[#1]% + {\begingroup + \obeylualines + \obeyluatokens + \dostartluaparameterset{#1}} + +\long\def\dostartluaparameterset#1#2\stopluaparameterset + {\ctxlua{parametersets["#1"]={#2}}% + \endgroup} + +\def\luaparameterset#1#2{\ctxlua{parametersets["#1"]={#2} tex.sprint("#1")}} + +% todo: \mergeparameterset + +% usage: +% +% \startluaparameterset [u3d:myset:display:1] +% toolbar=false, +% tree=true +% \stopluaparameterset +% +% options=u3d:myset:display:1 +% +% or: +% +% options=\luaparameterset{u3d:myset:display:1}{toolbar=false,tree=true} + +%D A Handy helper: + +\def\luaconditional#1{\ifcase#1tru\else fals\fi e} + +\protect \endinput diff --git a/tex/context/base/luat-iop.lua b/tex/context/base/luat-iop.lua new file mode 100644 index 000000000..e5722d2bd --- /dev/null +++ b/tex/context/base/luat-iop.lua @@ -0,0 +1,148 @@ +if not modules then modules = { } end modules ['luat-iop'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + 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 + +local lower, find, sub = string.lower, string.find, string.sub + +local ioinp = io.inp if not ioinp then ioinp = { } io.inp = ioinp end +local ioout = io.out if not ioout then ioout = { } io.out = ioout end + +ioinp.modes, ioout.modes = { }, { } -- functions + +local inp_blocked, inp_permitted = { }, { } +local out_blocked, out_permitted = { }, { } + +local function i_inhibit(name) inp_blocked [#inp_blocked +1] = name end +local function o_inhibit(name) out_blocked [#out_blocked +1] = name end +local function i_permit (name) inp_permitted[#inp_permitted+1] = name end +local function o_permit (name) out_permitted[#out_permitted+1] = name end + +ioinp.inhibit, ioinp.permit = i_inhibit, o_permit +ioout.inhibit, ioout.permit = o_inhibit, o_permit + +local blocked_openers = { } -- *.open(name,method) + +function io.register_opener(func) + blocked_openers[#blocked_openers+1] = func +end + +local function checked(name,blocked,permitted) + local n = lower(name) + for _,b in next, blocked do + if find(n,b) then + for _,p in next, permitted do + if find(n,p) then + return true + end + end + return false + end + end + return true +end + +function io.finalize_openers(func) + if #out_blocked > 0 or #inp_blocked > 0 then + local open = func -- why not directly? + return function(name,method) + if method and find(method,'[wa]') then + if #out_blocked > 0 and not checked(name,out_blocked,out_permitted) then + -- print("writing to " .. name .. " is not permitted") + return nil + end + else + if #inp_blocked > 0 and not checked(name,inp_blocked,inp_permitted) then + -- print("reading from " .. name .. " is not permitted") + return nil + end + end + return open(name,method) + end + else + return func + end +end + +--~ io.inp.inhibit('^%.') +--~ io.inp.inhibit('^/etc') +--~ io.inp.inhibit('/windows/') +--~ io.inp.inhibit('/winnt/') +--~ io.inp.permit('c:/windows/wmsetup.log') + +--~ io.open = io.finalize_openers(io.open) + +--~ f = io.open('.tex') print(f) +--~ f = io.open('tufte.tex') print(f) +--~ f = io.open('t:/sources/tufte.tex') print(f) +--~ f = io.open('/etc/passwd') print(f) +--~ f = io.open('c:/windows/crap.log') print(f) +--~ f = io.open('c:/windows/wmsetup.log') print(f) + +local inpout = { 'inp', 'out' } + +function io.set_opener_modes(i,o) + local first = sub(i,1,1) + for k=1,#inpout do + local iov = io[inpout[k]] + local f = iov[i] or iov[first] + if f then f() end + end + io.open = io.finalize_openers(io.open) +end + +-- restricted + +function ioinp.modes.restricted() + i_inhibit('^%.[%a]') +end + +function ioout.modes.restricted() + o_inhibit('^%.[%a]') +end + +-- paranoid + +function ioinp.modes.paranoid() + i_inhibit('.*') + i_inhibit('%.%.') + i_permit('^%./') + i_permit('[^/]') + resolvers.do_with_path('TEXMF',i_permit) +end + +function ioout.modes.paranoid() + o_inhibit('.*') + resolvers.do_with_path('TEXMFOUTPUT',o_permit) +end + +-- handy + +function ioinp.modes.handy() + i_inhibit('%.%.') + if os.type == 'windows' then + i_inhibit('/windows/') + i_inhibit('/winnt/') + else + i_inhibit('^/etc') + end +end + +function ioout.modes.handy() + o_inhibit('.*') + o_permit('%./') + o_permit('^%./') + o_permit('[^/]') +end + +--~ io.set_opener_modes('p','p') +--~ io.set_opener_modes('r','r') +--~ io.set_opener_modes('h','h') diff --git a/tex/context/base/luat-lib.mkiv b/tex/context/base/luat-lib.mkiv new file mode 100644 index 000000000..91ddec0aa --- /dev/null +++ b/tex/context/base/luat-lib.mkiv @@ -0,0 +1,70 @@ +%D \module +%D [ file=luat-lib, +%D version=2006.09.11, +%D title=\CONTEXT\ Lua Macros, +%D subtitle=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 / Libraries} + +\registerctxluafile{trac-inf} {1.001} +\registerctxluafile{trac-tra} {1.001} +\registerctxluafile{trac-log} {1.001} + +\registerctxluafile{luat-cbk} {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-sch} {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-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-sto} {1.001} +\registerctxluafile{luat-ini} {1.001} +\registerctxluafile{luat-env} {1.001} + +\registerctxluafile{lxml-tab} {1.001} +\registerctxluafile{lxml-lpt} {1.001} +\registerctxluafile{lxml-xml} {1.001} +\registerctxluafile{lxml-aux} {1.001} +\registerctxluafile{lxml-mis} {1.001} + +\startruntimeluacode + \edef\asciia{\ctxlua{tex.sprint(logs.mode)}} + \edef\asciib{xml} + \ifx\asciia\asciib % brrr + \long\def\writebanner #1{\writestring {#1}} + \long\def\writestatus#1#2{\writestring {#2}} + \long\def\message #1{\normalmessage{#1}} + \else + \let\writebanner\writestring + %\let\writestatus\normalwritestatus + \let\message \normalmessage + \fi +\stopruntimeluacode + +%registerctxluafile{luat-tmp}{1.001} +\registerctxluafile{luat-exe}{1.001} +\registerctxluafile{luat-iop}{1.001} + +\endinput diff --git a/tex/context/base/luat-lua.lua b/tex/context/base/luat-lua.lua new file mode 100644 index 000000000..b964bf8e8 --- /dev/null +++ b/tex/context/base/luat-lua.lua @@ -0,0 +1,43 @@ +if not modules then modules = { } end modules ['luat-lua'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +if lua then do + + local delayed = { } + + function lua.delay(f) + delayed[#delayed+1] = f + end + + function lua.flush_delayed(...) + local t = delayed + delayed = { } + for i=1, #t do + t[i](...) + end + end + + function lua.flush(...) + tex.sprint("\\directlua0{lua.flush_delayed(",table.concat({...},','),")}") + end + +end end + +--~ See mk.pdf for an explanation of the following code: +--~ +--~ function test(n) +--~ lua.delay(function(...) +--~ tex.sprint(string.format("pi: %s %s %s\\par",...)) +--~ end) +--~ lua.delay(function(...) +--~ tex.sprint(string.format("more pi: %s %s %s\\par",...)) +--~ end) +--~ tex.sprint(string.format("\\setbox0=\\hbox{%s}",math.pi*n)) +--~ local box = tex.box[0] +--~ lua.flush(box.width,box.height,box.depth) +--~ end diff --git a/tex/context/base/luat-run.lua b/tex/context/base/luat-run.lua new file mode 100644 index 000000000..b64a99fc6 --- /dev/null +++ b/tex/context/base/luat-run.lua @@ -0,0 +1,74 @@ +if not modules then modules = { } end modules ['luat-run'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + 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 + +callbacks.register('start_run', main.start, "actions performed at the beginning of a run") +callbacks.register('stop_run', main.stop, "actions performed at the end of a run") + +callbacks.register('report_output_pages', main.report_output_pages, "actions performed when reporting pages") +callbacks.register('report_output_log', main.report_output_log, "actions performed when reporting log file") + +callbacks.register('start_page_number', main.start_shipout_page, "actions performed at the beginning of a shipout") +callbacks.register('stop_page_number', main.stop_shipout_page, "actions performed at the end of a shipout") + +callbacks.register('process_input_buffer', false, "actions performed when reading data") +callbacks.register('process_output_buffer', false, "actions performed when writing data") 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 new file mode 100644 index 000000000..a81b0c206 --- /dev/null +++ b/tex/context/base/luat-sta.lua @@ -0,0 +1,196 @@ +if not modules then modules = { } end modules ['luat-sta'] = { + version = 1.001, + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- this code is used in the updater + +local gmatch, match = string.gmatch, string.match +local type = type + +states = states or { } +states.data = states.data or { } +states.hash = states.hash or { } +states.tag = states.tag or "" +states.filename = states.filename or "" + +function states.save(filename,tag) + tag = tag or states.tag + filename = file.addsuffix(filename or states.filename,'lus') + io.savedata(filename, + "-- generator : luat-sta.lua\n" .. + "-- state tag : " .. tag .. "\n\n" .. + table.serialize(states.data[tag or states.tag] or {},true) + ) +end + +function states.load(filename,tag) + states.filename = filename + states.tag = tag or "whatever" + states.filename = file.addsuffix(states.filename,'lus') + states.data[states.tag], states.hash[states.tag] = (io.exists(filename) and dofile(filename)) or { }, { } +end + +function states.set_by_tag(tag,key,value,default,persistent) + local d, h = states.data[tag], states.hash[tag] + if d then + if type(d) == "table" then + local dkey, hkey = key, key + local pre, post = match(key,"(.+)%.([^%.]+)$") + if pre and post then + for k in gmatch(pre,"[^%.]+") do + local dk = d[k] + if not dk then + dk = { } + d[k] = dk + elseif type(dk) == "string" then + -- invalid table, unable to upgrade structure + -- hope for the best or delete the state file + break + end + d = dk + 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 + end + d[dkey], h[hkey] = value, value + elseif type(d) == "string" then + -- weird + states.data[tag], states.hash[tag] = value, value + end + end +end + +function states.get_by_tag(tag,key,default) + local h = states.hash[tag] + if h and h[key] then + return h[key] + else + local d = states.data[tag] + if d then + for k in gmatch(key,"[^%.]+") do + local dk = d[k] + if dk then + d = dk + else + return default + end + end + return d or default + end + end +end + +function states.set(key,value,default,persistent) + states.set_by_tag(states.tag,key,value,default,persistent) +end + +function states.get(key,default) + return states.get_by_tag(states.tag,key,default) +end + +--~ states.data.update = { +--~ ["version"] = { +--~ ["major"] = 0, +--~ ["minor"] = 1, +--~ }, +--~ ["rsync"] = { +--~ ["server"] = "contextgarden.net", +--~ ["module"] = "minimals", +--~ ["repository"] = "current", +--~ ["flags"] = "-rpztlv --stats", +--~ }, +--~ ["tasks"] = { +--~ ["update"] = true, +--~ ["make"] = true, +--~ ["delete"] = false, +--~ }, +--~ ["platform"] = { +--~ ["host"] = true, +--~ ["other"] = { +--~ ["mswin"] = false, +--~ ["linux"] = false, +--~ ["linux-64"] = false, +--~ ["osx-intel"] = false, +--~ ["osx-ppc"] = false, +--~ ["sun"] = false, +--~ }, +--~ }, +--~ ["context"] = { +--~ ["available"] = {"current", "beta", "alpha", "experimental"}, +--~ ["selected"] = "current", +--~ }, +--~ ["formats"] = { +--~ ["cont-en"] = true, +--~ ["cont-nl"] = true, +--~ ["cont-de"] = false, +--~ ["cont-cz"] = false, +--~ ["cont-fr"] = false, +--~ ["cont-ro"] = false, +--~ }, +--~ ["engine"] = { +--~ ["pdftex"] = { +--~ ["install"] = true, +--~ ["formats"] = { +--~ ["pdftex"] = true, +--~ }, +--~ }, +--~ ["luatex"] = { +--~ ["install"] = true, +--~ ["formats"] = { +--~ }, +--~ }, +--~ ["xetex"] = { +--~ ["install"] = true, +--~ ["formats"] = { +--~ ["xetex"] = false, +--~ }, +--~ }, +--~ ["metapost"] = { +--~ ["install"] = true, +--~ ["formats"] = { +--~ ["mpost"] = true, +--~ ["metafun"] = true, +--~ }, +--~ }, +--~ }, +--~ ["fonts"] = { +--~ }, +--~ ["doc"] = { +--~ }, +--~ ["modules"] = { +--~ ["f-urwgaramond"] = false, +--~ ["f-urwgothic"] = false, +--~ ["t-bnf"] = false, +--~ ["t-chromato"] = false, +--~ ["t-cmscbf"] = false, +--~ ["t-cmttbf"] = false, +--~ ["t-construction-plan"] = false, +--~ ["t-degrade"] = false, +--~ ["t-french"] = false, +--~ ["t-lettrine"] = false, +--~ ["t-lilypond"] = false, +--~ ["t-mathsets"] = false, +--~ ["t-tikz"] = false, +--~ ["t-typearea"] = false, +--~ ["t-vim"] = false, +--~ }, +--~ } + +--~ states.save("teststate", "update") +--~ states.load("teststate", "update") + +--~ print(states.get_by_tag("update","rsync.server","unknown")) +--~ states.set_by_tag("update","rsync.server","oeps") +--~ print(states.get_by_tag("update","rsync.server","unknown")) +--~ states.save("teststate", "update") +--~ states.load("teststate", "update") +--~ print(states.get_by_tag("update","rsync.server","unknown")) diff --git a/tex/context/base/luat-sto.lua b/tex/context/base/luat-sto.lua new file mode 100644 index 000000000..08da735db --- /dev/null +++ b/tex/context/base/luat-sto.lua @@ -0,0 +1,135 @@ +if not modules then modules = { } end modules ['luat-sto'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + 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) + collectgarbage("step") + 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.sortedhash(storage.data) do + write_nl(whereto,format("%03i %s",k,v[1])) + end + write_nl(whereto," ","stored modules:"," ") + for k,v in table.sortedhash(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.sortedhash(attributes.names) do + write_nl(whereto,format("%03i %s",k,v)) + end + write_nl(whereto," ","stored catcodetables:"," ") + for k,v in table.sortedhash(catcodes.names) do + write_nl(whereto,format("%03i %s",k,table.concat(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/lxml-aux.lua b/tex/context/base/lxml-aux.lua new file mode 100644 index 000000000..00f791909 --- /dev/null +++ b/tex/context/base/lxml-aux.lua @@ -0,0 +1,543 @@ +if not modules then modules = { } end modules ['lxml-aux'] = { + 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" +} + +-- not all functions here make sense anymore vbut we keep them for +-- compatibility reasons + +local trace_manipulations = false trackers.register("lxml.manipulations", function(v) trace_manipulations = v end) + +local xmlparseapply, xmlconvert, xmlcopy, xmlname = xml.parse_apply, xml.convert, xml.copy, xml.name +local xmlinheritedconvert = xml.inheritedconvert + +local type = type +local insert, remove = table.insert, table.remove +local gmatch, gsub = string.gmatch, string.gsub + +local function report(what,pattern,c,e) + logs.report("xml","%s element '%s' (root: '%s', position: %s, index: %s, pattern: %s)",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern) +end + +local function withelements(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) + withelements(e,handle,depth+1) + end + end + end + end +end + +xml.withelements = withelements + +function xml.withelement(e,n,handle) -- slow + if e and n ~= 0 and handle then + local edt = e.dt + if edt then + if n > 0 then + for i=1,#edt do + local ei = edt[i] + if type(ei) == "table" then + if n == 1 then + handle(ei) + return + else + n = n - 1 + end + end + end + elseif n < 0 then + for i=#edt,1,-1 do + local ei = edt[i] + if type(ei) == "table" then + if n == -1 then + handle(ei) + return + else + n = n + 1 + end + end + end + end + end + end +end + +xml.elements_only = xml.collected + +function xml.each_element(root,pattern,handle,reverse) + local collected = xmlparseapply({ root },pattern) + if collected then + if reverse then + for c=#collected,1,-1 do + handle(collected[c]) + end + else + for c=1,#collected do + handle(collected[c]) + end + end + return collected + end +end + +xml.process_elements = xml.each_element + +function xml.process_attributes(root,pattern,handle) + local collected = xmlparseapply({ root },pattern) + if collected and handle then + for c=1,#collected do + handle(collected[c].at) + end + end + return collected +end + +--[[ldx-- +

The following functions collect elements and texts.

+--ldx]]-- + +-- are these still needed -> lxml-cmp.lua + +function xml.collect_elements(root, pattern) + return xmlparseapply({ root },pattern) +end + +function xml.collect_texts(root, pattern, flatten) -- todo: variant with handle + local collected = xmlparseapply({ root },pattern) + if collected and flatten then + local xmltostring = xml.tostring + for c=1,#collected do + collected[c] = xmltostring(collected[c].dt) + end + end + return collected or { } +end + +function xml.collect_tags(root, pattern, nonamespace) + local collected = xmlparseapply({ root },pattern) + if collected then + local t = { } + for c=1,#collected do + local e = collected[c] + local ns, tg = e.ns, e.tg + if nonamespace then + t[#t+1] = tg + elseif ns == "" then + t[#t+1] = tg + else + t[#t+1] = ns .. ":" .. tg + end + end + return t + end +end + +--[[ldx-- +

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

+--ldx]]-- + +local no_root = { no_root = true } + +function xml.redo_ni(d) + for k=1,#d do + local dk = d[k] + if type(dk) == "table" then + dk.ni = k + end + end +end + +local function xmltoelement(whatever,root) + if not whatever then + return nil + end + local element + if type(whatever) == "string" then + element = xmlinheritedconvert(whatever,root) + else + element = whatever -- we assume a table + end + if element.error then + return whatever -- string + end + if element then + --~ if element.ri then + --~ element = element.dt[element.ri].dt + --~ else + --~ element = element.dt + --~ end + end + return element +end + +xml.toelement = xmltoelement + +local function copiedelement(element,newparent) + if type(element) == "string" then + return element + else + element = xmlcopy(element).dt + if newparent and type(element) == "table" then + element.__p__ = newparent + end + return element + end +end + +function xml.delete_element(root,pattern) + local collected = xmlparseapply({ root },pattern) + if collected then + for c=1,#collected do + local e = collected[c] + local p = e.__p__ + if p then + if trace_manipulations then + report('deleting',pattern,c,e) + end + local d = p.dt + remove(d,e.ni) + xml.redo_ni(d) -- can be made faster and inlined + end + end + end +end + +function xml.replace_element(root,pattern,whatever) + local element = root and xmltoelement(whatever,root) + local collected = element and xmlparseapply({ root },pattern) + if collected then + for c=1,#collected do + local e = collected[c] + local p = e.__p__ + if p then + if trace_manipulations then + report('replacing',pattern,c,e) + end + local d = p.dt + d[e.ni] = copiedelement(element,p) + xml.redo_ni(d) -- probably not needed + end + end + end +end + +local function inject_element(root,pattern,whatever,prepend) + local element = root and xmltoelement(whatever,root) + local collected = element and xmlparseapply({ root },pattern) + if collected then + for c=1,#collected do + local e = collected[c] + local r = e.__p__ + local d, k, rri = r.dt, e.ni, r.ri + local edt = (rri and d[rri].dt) or (d and d[k] and d[k].dt) + if edt then + local be, af + local cp = copiedelement(element,e) + if prepend then + be, af = cp, edt + else + be, af = edt, cp + end + for i=1,#af do + be[#be+1] = af[i] + end + if rri then + r.dt[rri].dt = be + else + d[k].dt = be + end + xml.redo_ni(d) + end + end + end +end + +local function insert_element(root,pattern,whatever,before) -- todo: element als functie + local element = root and xmltoelement(whatever,root) + local collected = element and xmlparseapply({ root },pattern) + if collected then + for c=1,#collected do + local e = collected[c] + local r = e.__p__ + local d, k = r.dt, e.ni + if not before then + k = k + 1 + end + insert(d,k,copiedelement(element,r)) + xml.redo_ni(d) + end + end +end + +xml.insert_element = insert_element +xml.insert_element_after = insert_element +xml.insert_element_before = function(r,p,e) insert_element(r,p,e,true) end +xml.inject_element = inject_element +xml.inject_element_after = inject_element +xml.inject_element_before = function(r,p,e) inject_element(r,p,e,true) end + +local function include(xmldata,pattern,attribute,recursive,loaddata) + -- parse="text" (default: xml), encoding="" (todo) + -- attribute = attribute or 'href' + pattern = pattern or 'include' + loaddata = loaddata or io.loaddata + local collected = xmlparseapply({ xmldata },pattern) + if collected then + for c=1,#collected do + local ek = collected[c] + local name = nil + local ekdt = ek.dt + local ekat = ek.at + local epdt = ek.__p__.dt + if not attribute or attribute == "" then + name = (type(ekdt) == "table" and ekdt[1]) or ekdt -- ckeck, probably always tab or str + end + if not name then + for a in gmatch(attribute or "href","([^|]+)") do + name = ekat[a] + if name then break end + end + end + local data = (name and name ~= "" and loaddata(name)) or "" + if data == "" then + epdt[ek.ni] = "" -- xml.empty(d,k) + elseif ekat["parse"] == "text" then + -- for the moment hard coded + epdt[ek.ni] = xml.escaped(data) -- d[k] = xml.escaped(data) + else +--~ local settings = xmldata.settings +--~ settings.parent_root = xmldata -- to be tested +--~ local xi = xmlconvert(data,settings) + local xi = xmlinheritedconvert(data,xmldata) + if not xi then + epdt[ek.ni] = "" -- xml.empty(d,k) + else + if recursive then + include(xi,pattern,attribute,recursive,loaddata) + end + epdt[ek.ni] = xml.body(xi) -- xml.assign(d,k,xi) + end + end + end + end +end + +xml.include = include + +--~ local function manipulate(xmldata,pattern,manipulator) -- untested and might go away +--~ local collected = xmlparseapply({ xmldata },pattern) +--~ if collected then +--~ local xmltostring = xml.tostring +--~ for c=1,#collected do +--~ local e = collected[c] +--~ local data = manipulator(xmltostring(e)) +--~ if data == "" then +--~ epdt[e.ni] = "" +--~ else +--~ local xi = xmlinheritedconvert(data,xmldata) +--~ if not xi then +--~ epdt[e.ni] = "" +--~ else +--~ epdt[e.ni] = xml.body(xi) -- xml.assign(d,k,xi) +--~ end +--~ end +--~ end +--~ end +--~ end + +--~ xml.manipulate = manipulate + +function xml.strip_whitespace(root, pattern, nolines) -- strips all leading and trailing space ! + local collected = xmlparseapply({ root },pattern) + if collected then + for i=1,#collected do + local e = collected[i] + local edt = e.dt + if edt then + local t = { } + for i=1,#edt do + local str = edt[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 + --~ str.ni = i + t[#t+1] = str + end + end + e.dt = t + end + end + end +end + +function xml.strip_whitespace(root, pattern, nolines, anywhere) -- strips all leading and trailing spacing + local collected = xmlparseapply({ root },pattern) -- beware, indices no longer are valid now + if collected then + for i=1,#collected do + local e = collected[i] + local edt = e.dt + if edt then + if anywhere then + local t = { } + for e=1,#edt do + local str = edt[e] + if type(str) ~= "string" then + t[#t+1] = str + elseif str ~= "" then + -- todo: lpeg for each case + if nolines then + str = gsub(str,"%s+"," ") + end + str = gsub(str,"^%s*(.-)%s*$","%1") + if str ~= "" then + t[#t+1] = str + end + end + end + e.dt = t + else + -- we can assume a regular sparse xml table with no successive strings + -- otherwise we should use a while loop + if #edt > 0 then + -- strip front + local str = edt[1] + if type(str) ~= "string" then + -- nothing + elseif str == "" then + remove(edt,1) + else + if nolines then + str = gsub(str,"%s+"," ") + end + str = gsub(str,"^%s+","") + if str == "" then + remove(edt,1) + else + edt[1] = str + end + end + end + if #edt > 1 then + -- strip end + local str = edt[#edt] + if type(str) ~= "string" then + -- nothing + elseif str == "" then + remove(edt) + else + if nolines then + str = gsub(str,"%s+"," ") + end + str = gsub(str,"%s+$","") + if str == "" then + remove(edt) + else + edt[#edt] = str + end + end + end + end + end + 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) + local collected = xmlparseapply({ root },pattern) + if collected then + for c=1,#collected do + collected[c].tg = newtg + end + end +end + +function xml.remap_namespace(root, pattern, newns) + local collected = xmlparseapply({ root },pattern) + if collected then + for c=1,#collected do + collected[c].ns = newns + end + end +end + +function xml.check_namespace(root, pattern, newns) + local collected = xmlparseapply({ root },pattern) + if collected then + for c=1,#collected do + local e = collected[c] + if (not e.rn or e.rn == "") and e.ns == "" then + e.rn = newns + end + end + end +end + +function xml.remap_name(root, pattern, newtg, newns, newrn) + local collected = xmlparseapply({ root },pattern) + if collected then + for c=1,#collected do + local e = collected[c] + e.tg, e.ns, e.rn = newtg, newns, newrn + end + end +end + +--[[ldx-- +

Here are a few synonyms.

+--ldx]]-- + +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 diff --git a/tex/context/base/lxml-ctx.lua b/tex/context/base/lxml-ctx.lua new file mode 100644 index 000000000..765754953 --- /dev/null +++ b/tex/context/base/lxml-ctx.lua @@ -0,0 +1,131 @@ +if not modules then modules = { } end modules ['lxml-ctx'] = { + version = 1.001, + comment = "companion to lxml-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- is this still used? + +xml.ctx = { } +xml.ctx.enhancers = { } + +-- hashen + +function xml.ctx.enhancers.compound(root,lpath,before,tokens,after) -- todo lpeg + local before = before or "[%a%d][%a%d][%a%d]" + local tokens = tokens or "[%/%-]" + local after = after or "[%a%d][%a%d][%a%d]" + local pattern = "(" .. before .. ")(" .. tokens .. ")(" .. after .. ")" + local action = function(a,b,c) + return a .. "" .. c + end + xml.enhance(root,lpath,pattern,action) -- still present? +end + +local loaded = { } + +local nodesettostring = xml.nodesettostring + +-- maybe use detokenize instead of \type + +function xml.ctx.tshow(specification) + local pattern = specification.pattern + local xmlroot = specification.xmlroot + local attribute = specification.attribute + if context then + local xmlpattern = pattern + if not string.find(xmlpattern,"^[%a]+://") then + xmlpattern = "xml://" .. pattern + end + parsed = xml.parse_pattern(xmlpattern) + titlecommand = specification.title or "type" + if parsed.state then + context[titlecommand]("pattern: " .. pattern .. " (".. parsed.state .. ")") + else + context[titlecommand]("pattern: " .. pattern) + end + context.starttabulate({ "|Tr|Tl|Tp|" } ) + if specification.warning then + local comment = parsed.comment + if comment then + for k=1,#comment do + context.NC() + context("!") + context.NC() + context.rlap(comment[k]) + context.NR() + end + context.TB() + end + end + for p=1,#parsed do + local pp = parsed[p] + local kind = pp.kind + context.NC() + context(p) + context.NC() + context(kind) + context.NC() + if kind == "axis" then + context(pp.axis) + elseif kind == "nodes" then + context(nodesettostring(pp.nodes,pp.nodetest)) + elseif kind == "expression" then +--~ context("%s => %s",pp.expression,pp.converted) + context(pp.expression) + elseif kind == "finalizer" then + context("%s(%s)",pp.name,pp.arguments) + elseif kind == "error" and pp.error then + context(pp.error) + end + context.NC() + context.NR() + end + context.stoptabulate() + if xmlroot and xmlroot ~= "" then + if not loaded[xmlroot] then + loaded[xmlroot] = { xml.convert(buffers.content(xmlroot) or "") } + end + local collected = xml.parse_apply(loaded[xmlroot],xmlpattern) + if collected then + local tc = type(collected) + if not tc then + -- skip + else + context.blank() + context.type("result : ") + if tc == "string" then + context.type(collected) + elseif tc == "table" then + if collected.tg then + collected = { collected } + end + for c=1,#collected do + local cc = collected[c] + if attribute and attribute ~= "" then + local ccat = cc.at + local a = ccat and ccat[attribute] + if a and a ~= "" then + context.type(a) + context.type(">") + end + end + local ccns = cc.ns + if ccns == "" then + context.type(cc.tg) + else + context.type(ccns .. ":" .. cc.tg) + end + context.space() + end + else + context.type(tostring(tc)) + end + context.blank() + end + end + end + end +end diff --git a/tex/context/base/lxml-ctx.mkiv b/tex/context/base/lxml-ctx.mkiv new file mode 100644 index 000000000..73d082d0d --- /dev/null +++ b/tex/context/base/lxml-ctx.mkiv @@ -0,0 +1,64 @@ +%D \module +%D [ file=lxml-ini, +%D version=2007.08.17, +%D title=\CONTEXT\ \XML\ Support, +%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 Experimental. This might change! Also, it might become a module +%D instead if core code. + +\writestatus{loading}{ConTeXt XML Support / Goodies} + +\registerctxluafile{lxml-ctx}{1.001} + +\unprotect + +% the letterbar is a messy hack and is needed for the tabulate + +\settrue \xmllshowbuffer +\setfalse\xmllshowtitle +\settrue \xmllshowwarning + +\definehead[lshowtitle][subsubsubsubsubject] +\setuphead[lshowtitle][style=\tta] + +% \unexpanded\def\setuplxmlshow[#1]% +% {\dodoubleargument\getparameters[\??xl]} + +\def\xmllshow#1% + {\begingroup + \let|=\letterbar + \ctxlua{xml.ctx.tshow { + pattern = \!!bs#1\!!es, + \ifconditional\xmllshowtitle + title = "lshowtitle", + \fi + \ifconditional\xmllshowwarning + warning = true, + \fi + } }% + \endgroup} + +\def\xmllshowbuffer#1#2#3% + {\begingroup + \let|=\letterbar + \ctxlua{xml.ctx.tshow { + pattern = \!!bs#2\!!es, + \ifconditional\xmllshowbuffer + xmlroot = "#1", + attribute = "#3", + \fi + \ifconditional\xmllshowwarning + warning = true, + \fi + } }% + \endgroup} + +\protect diff --git a/tex/context/base/lxml-dir.lua b/tex/context/base/lxml-dir.lua new file mode 100644 index 000000000..617ce3e20 --- /dev/null +++ b/tex/context/base/lxml-dir.lua @@ -0,0 +1,112 @@ +if not modules then modules = { } end modules ['lxml-dir'] = { + 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 format, gsub = string.format, string.gsub +local get_id = lxml.id +local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes +local xmlparseapply = xml.parse_apply + +--~ +--~ +--~ +--~ +--~ +--~ +--~ + + + +lxml.directives = lxml.directives or { } + +local directives = lxml.directives + +local data = { + setup = { }, + before = { }, + after = { } +} + +local function load_setup(filename) + local fullname = resolvers.findtexfile(filename) or "" + if fullname ~= "" then + filename = fullname + end + local collection = xmlparseapply({ get_id(xml.load(filename)) },"directive") + if collection then + local valid = 0 + for i=1,#collection do + local at = collection[i].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 + valid = valid + 1 + end + end + commands.writestatus("lxml","%s directives found in '%s', %s valid",#collection,filename,valid) + else + commands.writestatus("lxml","no directives found in '%s'",filename) + end +end + +local function handle_setup(category,root,attribute,element) + root = get_id(root) + 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 + end + local setup = data[format("%s::%s::%s",element,attribute,value)] + if setup then + setup = setup[category] + end + if setup then + texsprint(ctxcatcodes,"\\directsetup{",setup,"}") + else + setup = data[format("%s::%s::*",element,attribute)] + if setup then + setup = setup[category] + end + if setup then + texsprint(ctxcatcodes,"\\directsetup{",gsub(setup,'%*',value),"}") + end + end + end + end +end + +directives.load = load_setup +directives.handle = handle_setup + +function directives.setup(root,attribute,element) + handle_setup('setup',root,attribute,element) +end +function directives.before(root,attribute,element) + handle_setup('before',root,attribute,element) +end +function directives.after(root,attribute,element) + handle_setup('after',root,attribute,element) +end diff --git a/tex/context/base/lxml-ent.lua b/tex/context/base/lxml-ent.lua new file mode 100644 index 000000000..193611937 --- /dev/null +++ b/tex/context/base/lxml-ent.lua @@ -0,0 +1,69 @@ +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 = type, next, tonumber +local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes +local utf = unicode.utf8 +local byte, format = string.byte, string.format +local utfupper, utfchar = utf.upper, utf.char +local lpegmatch = lpeg.match + +--[[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.

+ +

We do things different now but it's still somewhat experimental

+--ldx]]-- + +local trace_entities = false trackers.register("xml.entities", function(v) trace_entities = v end) + +xml.entities = xml.entities or { } -- xml.entity_handler == function + +storage.register("xml/entities",xml.entities,"xml.entities") -- this will move to lxml + +local entities = xml.entities -- this is a shared hash + +xml.unknown_any_entity_format = nil -- has to be per xml + +local parsedentity = xml.parsedentitylpeg + +function xml.register_entity(key,value) + entities[key] = value + if trace_entities then + logs.report("xml","registering entity '%s' as: %s",key,value) + end +end + +function xml.resolved_entity(str) + local e = entities[str] + if e then + local te = type(e) + if te == "function" then + e(str) + elseif e then + texsprint(ctxcatcodes,e) + end + else + -- resolve hex and dec, todo: escape # & etc for ctxcatcodes + -- normally this is already solved while loading the file + local chr, err = lpegmatch(parsedentity,str) + if chr then + texsprint(ctxcatcodes,chr) + elseif err then + texsprint(ctxcatcodes,err) + else + texsprint(ctxcatcodes,"\\xmle{",str,"}{",utfupper(str),"}") -- we need to use our own upper + end + end +end + +entities.amp = function() tex.write("&") end +entities.lt = function() tex.write("<") end +entities.gt = function() tex.write(">") end diff --git a/tex/context/base/lxml-inf.lua b/tex/context/base/lxml-inf.lua new file mode 100644 index 000000000..629c869ec --- /dev/null +++ b/tex/context/base/lxml-inf.lua @@ -0,0 +1,53 @@ +if not modules then modules = { } end modules ['lxml-inf'] = { + 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" +} + +-- This file will be loaded runtime by x-pending.tex. + +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 = 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 + +local function get_command_status(id) + status, stack = {}, {} + if id then + xmlwithelements(get_id(id),get) + return status + else + local t = { } + for id, _ in next, loaded do + t[id] = get_command_status(id) + end + return t + end +end + +lxml.get_command_status = get_command_status diff --git a/tex/context/base/lxml-ini.mkiv b/tex/context/base/lxml-ini.mkiv new file mode 100644 index 000000000..0f04d0488 --- /dev/null +++ b/tex/context/base/lxml-ini.mkiv @@ -0,0 +1,414 @@ +%D \module +%D [ file=lxml-ini, +%D version=2007.08.17, +%D title=\CONTEXT\ \XML\ Support, +%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 Todo: auto apply setups (manage at lua end) + +\writestatus{loading}{ConTeXt XML Support / Initialization} + +%registerctxluafile{lxml-tab}{1.001} % loader +%registerctxluafile{lxml-lpt}{1.001} % parser +%registerctxluafile{lxml-xml}{1.001} % xml finalizers +%registerctxluafile{lxml-aux}{1.001} % extras using parser +%registerctxluafile{lxml-mis}{1.001} % extras independent of parser +\registerctxluafile{lxml-ent}{1.001} % entity hacks +\registerctxluafile{lxml-tex}{1.001} % tex finalizers +\registerctxluafile{lxml-dir}{1.001} % ctx hacks + +\unprotect + +\def\c!entities{entities} % to be internationalized + +\def\xmlmain #1{\ctxlua{lxml.main("#1")}} +\def\xmlmatch #1{\ctxlua{lxml.match("#1")}} +\def\xmlall #1#2{\ctxlua{lxml.all("#1","#2")}} +\def\xmlatt #1#2{\ctxlua{lxml.att("#1","#2")}} +\def\xmlattdef #1#2#3{\ctxlua{lxml.att("#1","#2","#3")}} +\def\xmlchainatt #1#2{\ctxlua{lxml.chainattribute("#1","/","#2")}} +\def\xmlchainattdef #1#2#3{\ctxlua{lxml.chainattribute("#1","/","#2","#3")}} +\def\xmlattribute #1#2#3{\ctxlua{lxml.attribute("#1","#2","#3")}} +\def\xmlattributedef #1#2#3#4{\ctxlua{lxml.attribute("#1","#2","#3","#4")}} +\def\xmlcommand #1#2#3{\ctxlua{lxml.command("#1","#2","#3")}} +\def\xmlconcat #1#2#3{\ctxlua{lxml.concat("#1","#2",[[\detokenize{#3}]])}} +\def\xmlconcatrange#1#2#3#4#5{\ctxlua{lxml.concatrange("#1","#2","#3","#4",[[\detokenize{#5}]])}} +\def\xmlcount #1#2{\ctxlua{lxml.count("#1","#2")}} +\def\xmldelete #1#2{\ctxlua{lxml.delete("#1","#2")}} +\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",\!!bs#2\!!es)}} +\def\xmlfilterlist #1#2{\ctxlua{lxml.filterlist("#1",\!!bs#2\!!es)}} +\def\xmlfunction #1#2{\ctxlua{lxml["function"]("#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")}} +%def\xmlflushstripped #1{\ctxlua{lxml.strip("#1",true)}} +\def\xmldirect #1{\ctxlua{lxml.direct("#1")}} % in loops, not dt but root +\def\xmlidx #1#2#3{\ctxlua{lxml.idx("#1","#2",\number#3)}} +\def\xmlinclude #1#2#3{\ctxlua{lxml.include("#1","#2","#3",true)}} +\def\xmlindex #1#2#3{\ctxlua{lxml.index("#1","#2",\number#3)}} +\def\xmlinfo #1{\hbox{\ttxx[\ctxlua{lxml.info("#1")}]}} +\def\xmlshow #1{\startpacked\ttx\xmlverbatim{#1}\stoppacked} +\def\xmllast #1#2{\ctxlua{lxml.last("#1","#2")}} +\def\xmlname #1{\ctxlua{lxml.name("#1")}} +\def\xmlnamespace #1{\ctxlua{lxml.namespace("#1")}} +\def\xmlnonspace #1#2{\ctxlua{lxml.nonspace("#1","#2")}} +\def\xmlraw #1#2{\ctxlua{lxml.raw("#1","#2")}} +\def\xmlcontext #1#2{\ctxlua{lxml.context("#1","#2")}} +\def\xmlflushcontext #1{\ctxlua{lxml.context("#1")}} +\def\xmlsnippet #1#2{\ctxlua{lxml.snippet("#1",#2)}} +\def\xmlelement #1#2{\ctxlua{lxml.element("#1",#2)}} +\def\xmlregisterns #1#2{\ctxlua{xml.registerns("#1","#2")}} % document +\def\xmlremapname #1#2#3#4{\ctxlua{xml.remapname(lxml.id("#1"),"#2","#3","#4")}} % element +\def\xmlremapnamespace #1#2#3{\ctxlua{xml.rename_space(lxml.id("#1"),"#2","#3")}} % document +\def\xmlchecknamespace #1#2#3{\ctxlua{xml.check_namespace(lxml.id("#1"),"#2","#3")}} % element +\def\xmlsetfunction #1#2#3{\ctxlua{lxml.setaction("#1","#2",#3)}} +\def\xmlsetsetup #1#2#3{\ctxlua{lxml.setsetup("#1","#2","#3")}} +\def\xmlstrip #1#2{\ctxlua{lxml.strip("#1","#2")}} +\def\xmlstripnolines #1#2{\ctxlua{lxml.strip("#1","#2",true)}} +\def\xmlstripanywhere #1#2{\ctxlua{lxml.strip("#1","#2",true,true)}} +\def\xmlstripped #1#2{\ctxlua{lxml.stripped("#1","#2")}} +\def\xmlstrippednolines #1#2{\ctxlua{lxml.stripped("#1","#2",true)}} +\def\xmltag #1{\ctxlua{lxml.tag("#1")}} +\def\xmltext #1#2{\ctxlua{lxml.text("#1","#2")}} +\def\xmlverbatim #1{\ctxlua{lxml.verbatim("#1")}} +\def\xmldisplayverbatim #1{\ctxlua{lxml.displayverbatim("#1")}} +\def\xmlinlineverbatim #1{\ctxlua{lxml.inlineverbatim("#1")}} + +\def\xmlload #1#2{\ctxlua{lxml.load("#1","#2","\@@xmentities","\@@xmcompress")}} +\def\xmlloadbuffer #1#2{\ctxlua{lxml.loadbuffer("#1","#2","\@@xmentities","\@@xmcompress")}} +\def\xmlloaddata #1#2{\ctxlua{lxml.loaddata("#1",\!!bs#2\!!es,"\@@xmentities","\@@xmcompress")}} +\def\xmlloadregistered #1#2{\ctxlua{lxml.loadregistered("#1","\@@xmentities","\@@xmcompress")}} +\def\xmlloaddirectives #1{\ctxlua{lxml.directives.load("any:///#1")}} +\def\xmlpos #1{\ctxlua{lxml.pos("#1")}} + +%def\xmldoifelse #1#2{\ctxlua{cs.testcase(xml.found(lxml.id("#1"),"#2",false))}} +%def\xmldoifelsetext #1#2{\ctxlua{cs.testcase(xml.found(lxml.id("#1"),"#2",true ))}} + +% kind of special: + +\def\xmlstartraw{\ctxlua{lxml.startraw()}} +\def\xmlstopraw {\ctxlua{lxml.stopraw()}} + +% todo: \xmldoifelseattribute + +\def\xmldoif #1#2{\ctxlua{lxml.doif (\!!bs#1\!!es,\!!bs#2\!!es)}} +\def\xmldoifnot #1#2{\ctxlua{lxml.doifnot (\!!bs#1\!!es,\!!bs#2\!!es)}} +\def\xmldoifelse #1#2{\ctxlua{lxml.doifelse (\!!bs#1\!!es,\!!bs#2\!!es)}} +\def\xmldoiftext #1#2{\ctxlua{lxml.doiftext (\!!bs#1\!!es,\!!bs#2\!!es)}} +\def\xmldoifnottext #1#2{\ctxlua{lxml.doifnottext (\!!bs#1\!!es,\!!bs#2\!!es)}} +\def\xmldoifelsetext #1#2{\ctxlua{lxml.doifelsetext(\!!bs#1\!!es,\!!bs#2\!!es)}} + +%def\xmldoifelseempty #1#2{\ctxlua{lxml.doifelseempty("#1","#2")}} % #2, "*" or "" == self not yet implemented +%def\xmldoifelseselfempty #1{\ctxlua{lxml.doifelseempty("#1")}} + +% \startxmlsetups xml:include +% \xmlinclude{main}{include}{filename|href} +% \stopxmlsetups +% +% \xmlprependsetup{xml:include} + +\let\xmlgrab\xmlsetsetup % obsolete +\let\xmlself\s!unknown % obsolete + +\def\xmlsetup#1#2{\setupwithargument{#2}{#1}} + +\let\xmls\xmlsetup +\let\xmlw\setupwithargument + +\newtoks \registeredxmlsetups + +% todo: 1:xml:whatever always before 3:xml:something + +\def\xmlprependsetup #1{\ctxlua{lxml.installsetup(1,"*","#1")}} +\def\xmlappendsetup #1{\ctxlua{lxml.installsetup(2,"*","#1")}} +\def\xmlbeforesetup #1#2{\ctxlua{lxml.installsetup(3,"*","#1","#2"))}} +\def\xmlaftersetup #1#2{\ctxlua{lxml.installsetup(4,"*","#1","#2"))}} + +\def\xmlprependdocumentsetup #1#2{\ctxlua{lxml.installsetup(1,"#1","#2")}} +\def\xmlappenddocumentsetup #1#2{\ctxlua{lxml.installsetup(2,"#1","#2")}} +\def\xmlbeforedocumentsetup#1#2#3{\ctxlua{lxml.installsetup(3,"#1","#2","#3"))}} +\def\xmlafterdocumentsetup #1#2#3{\ctxlua{lxml.installsetup(4,"#1","#2","#3"))}} + +\def\xmlremovesetup #1{\ctxlua{lxml.removesetup("*","#1")}} +\def\xmlremovedocumentsetup #1#2{\ctxlua{lxml.removesetup("#1","#2")}} + +\def\xmlflushdocumentsetups #1#2{\ctxlua{lxml.flushsetups("#1","*","#2")}} % #1 == id where to apply * and #2 +\def\xmlresetdocumentsetups #1{\ctxlua{lxml.resetsetups("#1")}} + +\let\xmlregistersetup \xmlappendsetup +\let\xmlregisterdocumentsetup\xmlappenddocumentsetup + +\def\xmldocument{main} + +\def\xmlregisteredsetups + {\xmlstarttiming + \xmlflushsetups + \xmldefaulttotext\xmldocument % after include + \xmlstoptiming} + +\def\xmlregistereddocumentsetups#1#2% id setups + {\xmlstarttiming + % todo: test for duplicates ! + \xmlflushdocumentsetups{#1}{#2}% + \xmldefaulttotext{#1}% after include + \xmlstoptiming} + +\def\xmlstarttiming{\ctxlua{statistics.starttiming(lxml)}} +\def\xmlstoptiming {\ctxlua{statistics.stoptiming (lxml)}} + +\def\doxmlprocess#1#2#3#4#5% flag \loader id name what initializersetup + {\begingroup + \edef\xmldocument{#3}% #2 can be \xmldocument and set as such + %xmlpushdocument{#3}% + #2{#3}{#4}% + \setcatcodetable\notcatcodes + \doifelsenothing{#5} + {\xmlsetup{#3}{xml:process}} + {\xmlsetup{#3}{#5}}% + %xmlpopdocument + \endgroup} + +\def\xmlprocessfile {\doxmlprocess\plusone \xmlload} +\def\xmlprocessdata {\doxmlprocess\zerocount\xmlloaddata} +\def\xmlprocessbuffer {\doxmlprocess\zerocount\xmlloadbuffer} +\def\xmlprocessregistered{\doxmlprocess\zerocount\xmlloadregistered} +\let\xmlprocess \xmlprocessfile + +\startxmlsetups xml:flush + \xmlflush{#1} +\stopxmlsetups + +\startxmlsetups xml:process + \xmlregistereddocumentsetups{#1}{#1} + \xmlmain{#1} +\stopxmlsetups + +\def\xmlloadonly#1#2#3% + {\xmlload{#1}{#2}% + \xmlregistereddocumentsetups{#1}{#3}} + +% beware: \xmlmain takes the real root, so also processing +% instructions preceding the root element; well, in some +% sense that is the root + +\long\def\xmlconnect#1#2#3% inefficient + {\scratchcounter\xmlcount{#1}{#2}\relax + \ifcase\scratchcounter \or + \xmlall{#1}{#2}% + \else + \dorecurse \scratchcounter + {\ifnum\recurselevel>\plusone#3\fi + \xmlidx{#1}{#2}\recurselevel}% + \fi} + +\def\xmlcdataobeyedline {\obeyedline} +\def\xmlcdataobeyedspace{\strut\obeyedspace} +\def\xmlcdatabefore {\bgroup\tt} +\def\xmlcdataafter {\egroup} + +% verbatim (dodo:pre/post whitespace, maybe splot verbatim and +% cdata commands), experimental: +% +% \xmlsetfunction{main}{verbatim}{lxml.displayverbatim} +% \xmlsetfunction{main}{verb} {lxml.inlineverbatim} + +% \unexpanded\def\startxmldisplayverbatim[#1]{} +% \unexpanded\def\stopxmldisplayverbatim {} +% \unexpanded\def\startxmlinlineverbatim [#1]{} +% \unexpanded\def\stopxmlinlineverbatim {} + +% we use an xml: namespace so one has to define a suitable verbatim, say +% +% \definetyping[xml:verbatim][typing] +% +% this is experimental! + +\unexpanded\def\startxmldisplayverbatim[#1]% + {\startpacked % \begingroup + \let\currenttypingclass\??tp + \edef\currenttyping{xml:#1}% + \unexpanded\def\stopxmldisplayverbatim + {\endofverbatimlines + \stoppacked} % \endgroup + \doinitializeverbatim + \beginofverbatimlines} + +\unexpanded\def\startxmlinlineverbatim[#1]% + {\begingroup + \let\currenttypingclass\??ty + \edef\currenttyping{xml:#1}% + \let\stopxmldisplayverbatim\endgroup + \doinitializeverbatim} + +% will move but is developed for xml + +\newtoks \collectingtoks + +\unexpanded\def\startcollect#1\stopcollect + {\collectingtoks\@EA{\the\collectingtoks#1}} + +\unexpanded\def\startexpandedcollect#1\stopexpandedcollect + {\normalexpanded{\collectingtoks{\the\collectingtoks#1}}} + +\unexpanded\def\startcollecting{\collectingtoks\emptytoks} +\unexpanded\def\stopcollecting {\the\collectingtoks} + +\def\inlinemessage #1{\dontleavehmode{\tttf#1}} +\def\displaymessage#1{\blank\inlinemessage{#1}\blank} + +\def\xmltraceentities + {\ctxlua{xml.set_text_cleanup(lxml.trace_text_entities)}% + \appendtoks\ctxlua{lxml.show_text_entities()}\to\everygoodbye} + +% processing instructions + +\def\xmlcontextdirective#1% kind class key value + {\executeifdefined{xml#1directive}\gobblethreearguments} + +% setting up xml: +% +% \setupxml[\c!default=] % mkiv only == text +% \setupxml[\c!default=\v!none] % mkiv only, undefined -> hidden +% \setupxml[\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=unset, 1=text, 2=hidden + +\newtoks\everysetupxml + +\unexpanded\def\setupxml[#1]{\getparameters[\??xm][#1]\the\everysetupxml} + + +\letvalue{\??xm:\s!default:\v!normal}\zerocount +\letvalue{\??xm:\s!default:\v!none }\zerocount +\letvalue{\??xm:\s!default:\v!text }\plusone +\letvalue{\??xm:\s!default:\v!hidden}\plustwo + +\def\xmldefaulttotext#1% + {\ifcase\xmlprocessingmode + % unset + \or + \ctxlua{lxml.set_command_to_text("#1")}% 1 + \or + \ctxlua{lxml.set_command_to_none("#1")}% 2 + \else + % unset + \fi} + +\appendtoks + \chardef\xmlprocessingmode\executeifdefined{\??xm:\s!default:\@@xmdefault}\plusone +\to \everysetupxml + +\def\xmlinitialize{\the\everysetupxml} + +\setupxml + [\c!default=, % flush all + \c!compress=\v!no, % strip comment + \c!entities=\v!yes] % replace entities + +% \defineXMLenvironment[y]{(}{)} +% +% \startxmlsetups x +% /\xmlflush{#1}/ +% \stopxmlsetups +% +% \startxmlsetups xx +% \xmlsetsetup{main}{x}{*} +% \stopxmlsetups +% +% \xmlregistersetup{xx} +% +% \startbuffer +% a <&>{b} c +% \stopbuffer +% +% mkii: [\processXMLbuffer]\quad mkiv: [\xmlprocessbuffer{main}{}{}] + +\def\xmlmapvalue #1#2#3{\setvalue{\??xm:v:#1:#2}{#3}} % keep #3 to grab spaces +\def\xmlvalue #1#2#3{\executeifdefined{\??xm:v:#1:#2}{#3}} +%def\xmlvalue #1#2{\ifcsname\??xm:v:#1:#2\endcsname\csname\??xm:v:#1:#2\expandafter\expandafter\gobbleoneargument\expandafter\endcsname\else\expandafter\firstofoneargument\fi} +\def\xmldoifelsevalue #1#2{\ifcsname\??xm:v:#1:#2\endcsname\expandafter\firstoftwoarguments\else\expandafter\secondoftwoarguments\fi} + +\let\xmlmapval\xmlmapvalue +\let\xmlval \xmlvalue + +%D Experimental: + +\def\xmlgetindex #1{\ctxlua{lxml.getindex("\xmldocument","#1")}} +\def\xmlrawindex #1{\ctxlua{lxml.rawindex("#1")}} +\def\xmlwithindex #1#2{\ctxlua{lxml.withindex("\xmldocument","#1","#2")}} +\def\xmlreference #1#2{\string\xmlwithindex{#1}{#2}} + +%D Entities: + +\chardef\xmlautoentities=1 % 0=off, 1=upper, 2=upper,lower + +\let\isolatedentity\firstofoneargument + +\def\xmlsetentity#1#2{\ctxlua{xml.register_entity('#1',\!!bs\detokenize{#2}\!!es)}} +\def\xmltexentity#1#2{\ctxlua{xml.register_entity('#1',\!!bs\detokenize{\isolatedentity{#2}}\!!es)}} + +% \xmlsetentity{tex}{\TEX{}} % {} needed + +\unexpanded\def\xmle + {\ifcase\xmlautoentities + \expandafter\xmle@none + \or + \expandafter\xmle@upper + \or + \expandafter\xmle@upperlower + \else + \expandafter\xmle@none + \fi} + +\def\xmle@none#1#2% safe + {#1} + +\def\xmle@upper#1#2% can be abbreviation + {\ifcsname#2\endcsname + \csname#2\expandafter\endcsname + \else + #1% + \fi} + +\def\xmle@upperlower#1#2% can be anything, so unsafe + {\ifcsname#2\endcsname + \csname#2\expandafter\endcsname + \else\ifcsname#1\endcsname + \csname#1\expandafter\expandafter\expandafter\endcsname + \else + #1% + \fi\fi} + +\protect \endinput + +% \newcount\charactersactiveoffset \charactersactiveoffset="10000 +% +% \startextendcatcodetable\ctxcatcodes +% \catcode\numexpr\charactersactiveoffset+`<\relax=13 +% \catcode\numexpr\charactersactiveoffset+`&\relax=13 +% \catcode\numexpr\charactersactiveoffset+`>\relax=13 +% \stopextendcatcodetable +% +% \startextendcatcodetable\xmlcatcodes % not needed +% \catcode\numexpr\charactersactiveoffset+`<\relax=13 +% \catcode\numexpr\charactersactiveoffset+`&\relax=13 +% \catcode\numexpr\charactersactiveoffset+`>\relax=13 +% \stopextendcatcodetable +% +% \ctxlua { % entities are remembered in the format +% characters.remapentity("<",characters.active_offset + utf.byte("<")) +% characters.remapentity("&",characters.active_offset + utf.byte("&")) +% characters.remapentity(">",characters.active_offset + utf.byte(">")) +% } diff --git a/tex/context/base/lxml-lpt.lua b/tex/context/base/lxml-lpt.lua new file mode 100644 index 000000000..bddbe4868 --- /dev/null +++ b/tex/context/base/lxml-lpt.lua @@ -0,0 +1,1259 @@ +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" +} + +-- e.ni is only valid after a filter run + +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, upper, lower, gmatch, gsub, find, rep = string.format, string.upper, string.lower, string.gmatch, string.gsub, string.find, string.rep +local lpegmatch = lpeg.match + +-- beware, this is not xpath ... e.g. position is different (currently) and +-- we have reverse-sibling as reversed preceding sibling + +--[[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.

+

If I can get in the mood I will make a variant that is XSLT compliant +but I wonder if it makes sense.

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

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) + +--ldx]]-- + +local trace_lpath = false if trackers then trackers.register("xml.path", function(v) trace_lpath = v end) end +local trace_lparse = false if trackers then trackers.register("xml.parse", function(v) trace_lparse = v end) end +local trace_lprofile = false if trackers then trackers.register("xml.profile", function(v) trace_lpath = v trace_lparse = v trace_lprofile = v end) end + +--[[ldx-- +

We've now arrived at an interesting 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 function xml.lpathcalls () return lpathcalls end +local lpathcached = 0 function xml.lpathcached() return lpathcached end + +xml.functions = xml.functions or { } -- internal +xml.expressions = xml.expressions or { } -- in expressions +xml.finalizers = xml.finalizers or { } -- fast do-with ... (with return value other than collection) +xml.specialhandler = xml.specialhandler or { } + +local functions = xml.functions +local expressions = xml.expressions +local finalizers = xml.finalizers + +finalizers.xml = finalizers.xml or { } +finalizers.tex = finalizers.tex or { } + +local function fallback (t, name) + local fn = finalizers[name] + if fn then + t[name] = fn + else + logs.report("xml","unknown sub finalizer '%s'",tostring(name)) + fn = function() end + end + return fn +end + +setmetatable(finalizers.xml, { __index = fallback }) +setmetatable(finalizers.tex, { __index = fallback }) + +xml.defaultprotocol = "xml" + +-- as xsl does not follow xpath completely here we will also +-- be more liberal especially with regards to the use of | and +-- the rootpath: +-- +-- test : all 'test' under current +-- /test : 'test' relative to current +-- a|b|c : set of names +-- (a|b|c) : idem +-- ! : not +-- +-- after all, we're not doing transformations but filtering. in +-- addition we provide filter functions (last bit) +-- +-- todo: optimizer +-- +-- .. : parent +-- * : all kids +-- / : anchor here +-- // : /**/ +-- ** : all in between +-- +-- so far we had (more practical as we don't transform) +-- +-- {/test} : kids 'test' under current node +-- {test} : any kid with tag 'test' +-- {//test} : same as above + +-- evaluator (needs to be redone, for the moment copied) + +-- todo: apply_axis(list,notable) and collection vs single + +local apply_axis = { } + +apply_axis['root'] = function(list) + local collected = { } + for l=1,#list do + local ll = list[l] + local rt = ll + while ll do + ll = ll.__p__ + if ll then + rt = ll + end + end + collected[#collected+1] = rt + end + return collected +end + +apply_axis['self'] = function(list) +--~ local collected = { } +--~ for l=1,#list do +--~ collected[#collected+1] = list[l] +--~ end +--~ return collected + return list +end + +apply_axis['child'] = function(list) + local collected = { } + for l=1,#list do + local ll = list[l] + local dt = ll.dt + local en = 0 + for k=1,#dt do + local dk = dt[k] + if dk.tg then + collected[#collected+1] = dk + dk.ni = k -- refresh + en = en + 1 + dk.ei = en + end + end + ll.en = en + end + return collected +end + +local function collect(list,collected) + local dt = list.dt + if dt then + local en = 0 + for k=1,#dt do + local dk = dt[k] + if dk.tg then + collected[#collected+1] = dk + dk.ni = k -- refresh + en = en + 1 + dk.ei = en + collect(dk,collected) + end + end + list.en = en + end +end +apply_axis['descendant'] = function(list) + local collected = { } + for l=1,#list do + collect(list[l],collected) + end + return collected +end + +local function collect(list,collected) + local dt = list.dt + if dt then + local en = 0 + for k=1,#dt do + local dk = dt[k] + if dk.tg then + collected[#collected+1] = dk + dk.ni = k -- refresh + en = en + 1 + dk.ei = en + collect(dk,collected) + end + end + list.en = en + end +end +apply_axis['descendant-or-self'] = function(list) + local collected = { } + for l=1,#list do + local ll = list[l] + if ll.special ~= true then -- catch double root + collected[#collected+1] = ll + end + collect(ll,collected) + end + return collected +end + +apply_axis['ancestor'] = function(list) + local collected = { } + for l=1,#list do + local ll = list[l] + while ll do + ll = ll.__p__ + if ll then + collected[#collected+1] = ll + end + end + end + return collected +end + +apply_axis['ancestor-or-self'] = function(list) + local collected = { } + for l=1,#list do + local ll = list[l] + collected[#collected+1] = ll + while ll do + ll = ll.__p__ + if ll then + collected[#collected+1] = ll + end + end + end + return collected +end + +apply_axis['parent'] = function(list) + local collected = { } + for l=1,#list do + local pl = list[l].__p__ + if pl then + collected[#collected+1] = pl + end + end + return collected +end + +apply_axis['attribute'] = function(list) + return { } +end + +apply_axis['namespace'] = function(list) + return { } +end + +apply_axis['following'] = function(list) -- incomplete +--~ local collected = { } +--~ for l=1,#list do +--~ local ll = list[l] +--~ local p = ll.__p__ +--~ local d = p.dt +--~ for i=ll.ni+1,#d do +--~ local di = d[i] +--~ if type(di) == "table" then +--~ collected[#collected+1] = di +--~ break +--~ end +--~ end +--~ end +--~ return collected + return { } +end + +apply_axis['preceding'] = function(list) -- incomplete +--~ local collected = { } +--~ for l=1,#list do +--~ local ll = list[l] +--~ local p = ll.__p__ +--~ local d = p.dt +--~ for i=ll.ni-1,1,-1 do +--~ local di = d[i] +--~ if type(di) == "table" then +--~ collected[#collected+1] = di +--~ break +--~ end +--~ end +--~ end +--~ return collected + return { } +end + +apply_axis['following-sibling'] = function(list) + local collected = { } + for l=1,#list do + local ll = list[l] + local p = ll.__p__ + local d = p.dt + for i=ll.ni+1,#d do + local di = d[i] + if type(di) == "table" then + collected[#collected+1] = di + end + end + end + return collected +end + +apply_axis['preceding-sibling'] = function(list) + local collected = { } + for l=1,#list do + local ll = list[l] + local p = ll.__p__ + local d = p.dt + for i=1,ll.ni-1 do + local di = d[i] + if type(di) == "table" then + collected[#collected+1] = di + end + end + end + return collected +end + +apply_axis['reverse-sibling'] = function(list) -- reverse preceding + local collected = { } + for l=1,#list do + local ll = list[l] + local p = ll.__p__ + local d = p.dt + for i=ll.ni-1,1,-1 do + local di = d[i] + if type(di) == "table" then + collected[#collected+1] = di + end + end + end + return collected +end + +apply_axis['auto-descendant-or-self'] = apply_axis['descendant-or-self'] +apply_axis['auto-descendant'] = apply_axis['descendant'] +apply_axis['auto-child'] = apply_axis['child'] +apply_axis['auto-self'] = apply_axis['self'] +apply_axis['initial-child'] = apply_axis['child'] + +local function apply_nodes(list,directive,nodes) + -- todo: nodes[1] etc ... negated node name in set ... when needed + -- ... currently ignored + local maxn = #nodes + if maxn == 3 then --optimized loop + local nns, ntg = nodes[2], nodes[3] + if not nns and not ntg then -- wildcard + if directive then + return list + else + return { } + end + else + local collected, m, p = { }, 0, nil + if not nns then -- only check tag + for l=1,#list do + local ll = list[l] + local ltg = ll.tg + if ltg then + if directive then + if ntg == ltg then + local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end + collected[#collected+1], ll.mi = ll, m + end + elseif ntg ~= ltg then + local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end + collected[#collected+1], ll.mi = ll, m + end + end + end + elseif not ntg then -- only check namespace + for l=1,#list do + local ll = list[l] + local lns = ll.rn or ll.ns + if lns then + if directive then + if lns == nns then + local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end + collected[#collected+1], ll.mi = ll, m + end + elseif lns ~= nns then + local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end + collected[#collected+1], ll.mi = ll, m + end + end + end + else -- check both + for l=1,#list do + local ll = list[l] + local ltg = ll.tg + if ltg then + local lns = ll.rn or ll.ns + local ok = ltg == ntg and lns == nns + if directive then + if ok then + local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end + collected[#collected+1], ll.mi = ll, m + end + elseif not ok then + local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end + collected[#collected+1], ll.mi = ll, m + end + end + end + end + return collected + end + else + local collected, m, p = { }, 0, nil + for l=1,#list do + local ll = list[l] + local ltg = ll.tg + if ltg then + local lns = ll.rn or ll.ns + local ok = false + for n=1,maxn,3 do + local nns, ntg = nodes[n+1], nodes[n+2] + ok = (not ntg or ltg == ntg) and (not nns or lns == nns) + if ok then + break + end + end + if directive then + if ok then + local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end + collected[#collected+1], ll.mi = ll, m + end + elseif not ok then + local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end + collected[#collected+1], ll.mi = ll, m + end + end + end + return collected + end +end + +local quit_expression = false + +local function apply_expression(list,expression,order) + local collected = { } + quit_expression = false + for l=1,#list do + local ll = list[l] + if expression(list,ll,l,order) then -- nasty, order alleen valid als n=1 + collected[#collected+1] = ll + end + if quit_expression then + break + end + end + return collected +end + +local P, V, C, Cs, Cc, Ct, R, S, Cg, Cb = lpeg.P, lpeg.V, lpeg.C, lpeg.Cs, lpeg.Cc, lpeg.Ct, lpeg.R, lpeg.S, lpeg.Cg, lpeg.Cb + +local spaces = S(" \n\r\t\f")^0 +local lp_space = S(" \n\r\t\f") +local lp_any = P(1) +local lp_noequal = P("!=") / "~=" + P("<=") + P(">=") + P("==") +local lp_doequal = P("=") / "==" +local lp_or = P("|") / " or " +local lp_and = P("&") / " and " + +local lp_builtin = P ( + P("firstindex") / "1" + + P("lastindex") / "(#ll.__p__.dt or 1)" + + P("firstelement") / "1" + + P("lastelement") / "(ll.__p__.en or 1)" + + P("first") / "1" + + P("last") / "#list" + + P("rootposition") / "order" + + P("position") / "l" + -- is element in finalizer + P("order") / "order" + + P("element") / "(ll.ei or 1)" + + P("index") / "(ll.ni or 1)" + + P("match") / "(ll.mi or 1)" + + P("text") / "(ll.dt[1] or '')" + + -- P("name") / "(ll.ns~='' and ll.ns..':'..ll.tg)" + + P("name") / "((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)" + + P("tag") / "ll.tg" + + P("ns") / "ll.ns" + ) * ((spaces * P("(") * spaces * P(")"))/"") + +local lp_attribute = (P("@") + P("attribute::")) / "" * Cc("(ll.at and ll.at['") * R("az","AZ","--","__")^1 * Cc("'])") +local lp_fastpos_p = ((P("+")^0 * R("09")^1 * P(-1)) / function(s) return "l==" .. s end) +local lp_fastpos_n = ((P("-") * R("09")^1 * P(-1)) / function(s) return "(" .. s .. "<0 and (#list+".. s .. "==l))" end) +local lp_fastpos = lp_fastpos_n + lp_fastpos_p +local lp_reserved = C("and") + C("or") + C("not") + C("div") + C("mod") + C("true") + C("false") + +local lp_lua_function = C(R("az","AZ","__")^1 * (P(".") * R("az","AZ","__")^1)^1) * ("(") / 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 "expr." .. t .. "(" + else + return "expr.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)*")"} + +local lp_child = Cc("expr.child(ll,'") * R("az","AZ","--","__")^1 * Cc("')") +local lp_number = S("+-") * R("09")^1 +local lp_string = Cc("'") * R("az","AZ","--","__")^1 * Cc("'") +local lp_content = (P("'") * (1-P("'"))^0 * P("'") + P('"') * (1-P('"'))^0 * P('"')) + +local cleaner + +local lp_special = (C(P("name")+P("text")+P("tag")+P("count")+P("child"))) * value / function(t,s) + if expressions[t] then + s = s and s ~= "" and lpegmatch(cleaner,s) + if s and s ~= "" then + return "expr." .. t .. "(ll," .. s ..")" + else + return "expr." .. t .. "(ll)" + end + else + return "expr.error(" .. t .. ")" + end +end + +local content = + lp_builtin + + lp_attribute + + lp_special + + lp_noequal + lp_doequal + + lp_or + lp_and + + lp_reserved + + lp_lua_function + lp_function + + lp_content + -- too fragile + lp_child + + lp_any + +local converter = Cs ( + lp_fastpos + (P { lparent * (V(1))^0 * rparent + content } )^0 +) + +cleaner = Cs ( ( +--~ lp_fastpos + + lp_reserved + + lp_number + + lp_string + +1 )^1 ) + + +--~ expr + +local template_e = [[ + local expr = xml.expressions + return function(list,ll,l,order) + return %s + end +]] + +local template_f_y = [[ + local finalizer = xml.finalizers['%s']['%s'] + return function(collection) + return finalizer(collection,%s) + end +]] + +local template_f_n = [[ + return xml.finalizers['%s']['%s'] +]] + +-- + +local register_self = { kind = "axis", axis = "self" } -- , apply = apply_axis["self"] } +local register_parent = { kind = "axis", axis = "parent" } -- , apply = apply_axis["parent"] } +local register_descendant = { kind = "axis", axis = "descendant" } -- , apply = apply_axis["descendant"] } +local register_child = { kind = "axis", axis = "child" } -- , apply = apply_axis["child"] } +local register_descendant_or_self = { kind = "axis", axis = "descendant-or-self" } -- , apply = apply_axis["descendant-or-self"] } +local register_root = { kind = "axis", axis = "root" } -- , apply = apply_axis["root"] } +local register_ancestor = { kind = "axis", axis = "ancestor" } -- , apply = apply_axis["ancestor"] } +local register_ancestor_or_self = { kind = "axis", axis = "ancestor-or-self" } -- , apply = apply_axis["ancestor-or-self"] } +local register_attribute = { kind = "axis", axis = "attribute" } -- , apply = apply_axis["attribute"] } +local register_namespace = { kind = "axis", axis = "namespace" } -- , apply = apply_axis["namespace"] } +local register_following = { kind = "axis", axis = "following" } -- , apply = apply_axis["following"] } +local register_following_sibling = { kind = "axis", axis = "following-sibling" } -- , apply = apply_axis["following-sibling"] } +local register_preceding = { kind = "axis", axis = "preceding" } -- , apply = apply_axis["preceding"] } +local register_preceding_sibling = { kind = "axis", axis = "preceding-sibling" } -- , apply = apply_axis["preceding-sibling"] } +local register_reverse_sibling = { kind = "axis", axis = "reverse-sibling" } -- , apply = apply_axis["reverse-sibling"] } + +local register_auto_descendant_or_self = { kind = "axis", axis = "auto-descendant-or-self" } -- , apply = apply_axis["auto-descendant-or-self"] } +local register_auto_descendant = { kind = "axis", axis = "auto-descendant" } -- , apply = apply_axis["auto-descendant"] } +local register_auto_self = { kind = "axis", axis = "auto-self" } -- , apply = apply_axis["auto-self"] } +local register_auto_child = { kind = "axis", axis = "auto-child" } -- , apply = apply_axis["auto-child"] } + +local register_initial_child = { kind = "axis", axis = "initial-child" } -- , apply = apply_axis["initial-child"] } + +local register_all_nodes = { kind = "nodes", nodetest = true, nodes = { true, false, false } } + +local skip = { } + +local function errorrunner_e(str,cnv) + if not skip[str] then + logs.report("lpath","error in expression: %s => %s",str,cnv) + skip[str] = cnv or str + end + return false +end +local function errorrunner_f(str,arg) + logs.report("lpath","error in finalizer: %s(%s)",str,arg or "") + return false +end + +local function register_nodes(nodetest,nodes) + return { kind = "nodes", nodetest = nodetest, nodes = nodes } +end + +local function register_expression(expression) + local converted = lpegmatch(converter,expression) + local runner = loadstring(format(template_e,converted)) + runner = (runner and runner()) or function() errorrunner_e(expression,converted) end + return { kind = "expression", expression = expression, converted = converted, evaluator = runner } +end + +local function register_finalizer(protocol,name,arguments) + local runner + if arguments and arguments ~= "" then + runner = loadstring(format(template_f_y,protocol or xml.defaultprotocol,name,arguments)) + else + runner = loadstring(format(template_f_n,protocol or xml.defaultprotocol,name)) + end + runner = (runner and runner()) or function() errorrunner_f(name,arguments) end + return { kind = "finalizer", name = name, arguments = arguments, finalizer = runner } +end + +local expression = P { "ex", + ex = "[" * C((V("sq") + V("dq") + (1 - S("[]")) + V("ex"))^0) * "]", + sq = "'" * (1 - S("'"))^0 * "'", + dq = '"' * (1 - S('"'))^0 * '"', +} + +local arguments = P { "ar", + ar = "(" * Cs((V("sq") + V("dq") + V("nq") + P(1-P(")")))^0) * ")", + nq = ((1 - S("),'\""))^1) / function(s) return format("%q",s) end, + sq = P("'") * (1 - P("'"))^0 * P("'"), + dq = P('"') * (1 - P('"'))^0 * P('"'), +} + +-- todo: better arg parser + +local function register_error(str) + return { kind = "error", error = format("unparsed: %s",str) } +end + +-- there is a difference in * and /*/ and so we need to catch a few special cases + +local special_1 = P("*") * Cc(register_auto_descendant) * Cc(register_all_nodes) -- last one not needed +local special_2 = P("/") * Cc(register_auto_self) +local special_3 = P("") * Cc(register_auto_self) + +local parser = Ct { "patterns", -- can be made a bit faster by moving pattern outside + + patterns = spaces * V("protocol") * spaces * ( + ( V("special") * spaces * P(-1) ) + + ( V("initial") * spaces * V("step") * spaces * (P("/") * spaces * V("step") * spaces)^0 ) + ), + + protocol = Cg(V("letters"),"protocol") * P("://") + Cg(Cc(nil),"protocol"), + + -- the / is needed for // as descendant or self is somewhat special + -- step = (V("shortcuts") + V("axis") * spaces * V("nodes")^0 + V("error")) * spaces * V("expressions")^0 * spaces * V("finalizer")^0, + step = ((V("shortcuts") + P("/") + V("axis")) * spaces * V("nodes")^0 + V("error")) * spaces * V("expressions")^0 * spaces * V("finalizer")^0, + + axis = V("descendant") + V("child") + V("parent") + V("self") + V("root") + V("ancestor") + + V("descendant_or_self") + V("following_sibling") + V("following") + + V("reverse_sibling") + V("preceding_sibling") + V("preceding") + V("ancestor_or_self") + + #(1-P(-1)) * Cc(register_auto_child), + + special = special_1 + special_2 + special_3, + + initial = (P("/") * spaces * Cc(register_initial_child))^-1, + + error = (P(1)^1) / register_error, + + shortcuts_a = V("s_descendant_or_self") + V("s_descendant") + V("s_child") + V("s_parent") + V("s_self") + V("s_root") + V("s_ancestor"), + + shortcuts = V("shortcuts_a") * (spaces * "/" * spaces * V("shortcuts_a"))^0, + + s_descendant_or_self = (P("***/") + P("/")) * Cc(register_descendant_or_self), --- *** is a bonus + -- s_descendant_or_self = P("/") * Cc(register_descendant_or_self), + s_descendant = P("**") * Cc(register_descendant), + s_child = P("*") * #(1-P(":")) * Cc(register_child ), +-- s_child = P("*") * #(P("/")+P(-1)) * Cc(register_child ), + s_parent = P("..") * Cc(register_parent ), + s_self = P("." ) * Cc(register_self ), + s_root = P("^^") * Cc(register_root ), + s_ancestor = P("^") * Cc(register_ancestor ), + + descendant = P("descendant::") * Cc(register_descendant ), + child = P("child::") * Cc(register_child ), + parent = P("parent::") * Cc(register_parent ), + self = P("self::") * Cc(register_self ), + root = P('root::') * Cc(register_root ), + ancestor = P('ancestor::') * Cc(register_ancestor ), + descendant_or_self = P('descendant-or-self::') * Cc(register_descendant_or_self ), + ancestor_or_self = P('ancestor-or-self::') * Cc(register_ancestor_or_self ), + -- attribute = P('attribute::') * Cc(register_attribute ), + -- namespace = P('namespace::') * Cc(register_namespace ), + following = P('following::') * Cc(register_following ), + following_sibling = P('following-sibling::') * Cc(register_following_sibling ), + preceding = P('preceding::') * Cc(register_preceding ), + preceding_sibling = P('preceding-sibling::') * Cc(register_preceding_sibling ), + reverse_sibling = P('reverse-sibling::') * Cc(register_reverse_sibling ), + + nodes = (V("nodefunction") * spaces * P("(") * V("nodeset") * P(")") + V("nodetest") * V("nodeset")) / register_nodes, + + expressions = expression / register_expression, + + letters = R("az")^1, + name = (1-lpeg.S("/[]()|:*!"))^1, + negate = P("!") * Cc(false), + + nodefunction = V("negate") + P("not") * Cc(false) + Cc(true), + nodetest = V("negate") + Cc(true), + nodename = (V("negate") + Cc(true)) * spaces * ((V("wildnodename") * P(":") * V("wildnodename")) + (Cc(false) * V("wildnodename"))), + wildnodename = (C(V("name")) + P("*") * Cc(false)) * #(1-P("(")), + nodeset = spaces * Ct(V("nodename") * (spaces * P("|") * spaces * V("nodename"))^0) * spaces, + + finalizer = (Cb("protocol") * P("/")^-1 * C(V("name")) * arguments * P(-1)) / register_finalizer, + +} + +local cache = { } + +local function nodesettostring(set,nodetest) + local t = { } + for i=1,#set,3 do + local directive, ns, tg = set[i], set[i+1], set[i+2] + if not ns or ns == "" then ns = "*" end + if not tg or tg == "" then tg = "*" end + tg = (tg == "@rt@" and "[root]") or format("%s:%s",ns,tg) + t[#t+1] = (directive and tg) or format("not(%s)",tg) + end + if nodetest == false then + return format("not(%s)",concat(t,"|")) + else + return concat(t,"|") + end +end + +local function tagstostring(list) + if #list == 0 then + return "no elements" + else + local t = { } + for i=1, #list do + local li = list[i] + local ns, tg = li.ns, li.tg + if not ns or ns == "" then ns = "*" end + if not tg or tg == "" then tg = "*" end + t[#t+1] = (tg == "@rt@" and "[root]") or format("%s:%s",ns,tg) + end + return concat(t," ") + end +end + +xml.nodesettostring = nodesettostring + +local parse_pattern -- we have a harmless kind of circular reference + +local function lshow(parsed) + if type(parsed) == "string" then + parsed = parse_pattern(parsed) + end + local s = table.serialize_functions -- ugly + table.serialize_functions = false -- ugly + logs.report("lpath","%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,table.serialize(parsed,false)) + table.serialize_functions = s -- ugly +end + +xml.lshow = lshow + +local function add_comment(p,str) + local pc = p.comment + if not pc then + p.comment = { str } + else + pc[#pc+1] = str + end +end + +parse_pattern = function (pattern) -- the gain of caching is rather minimal + lpathcalls = lpathcalls + 1 + if type(pattern) == "table" then + return pattern + else + local parsed = cache[pattern] + if parsed then + lpathcached = lpathcached + 1 + else + parsed = lpegmatch(parser,pattern) + if parsed then + parsed.pattern = pattern + local np = #parsed + if np == 0 then + parsed = { pattern = pattern, register_self, state = "parsing error" } + logs.report("lpath","parsing error in '%s'",pattern) + lshow(parsed) + else + -- we could have done this with a more complex parser but this + -- is cleaner + local pi = parsed[1] + if pi.axis == "auto-child" then + if false then + add_comment(parsed, "auto-child replaced by auto-descendant-or-self") + parsed[1] = register_auto_descendant_or_self + else + add_comment(parsed, "auto-child replaced by auto-descendant") + parsed[1] = register_auto_descendant + end + elseif pi.axis == "initial-child" and np > 1 and parsed[2].axis then + add_comment(parsed, "initial-child removed") -- we could also make it a auto-self + remove(parsed,1) + end + local np = #parsed -- can have changed + if np > 1 then + local pnp = parsed[np] + if pnp.kind == "nodes" and pnp.nodetest == true then + local nodes = pnp.nodes + if nodes[1] == true and nodes[2] == false and nodes[3] == false then + add_comment(parsed, "redundant final wildcard filter removed") + remove(parsed,np) + end + end + end + end + else + parsed = { pattern = pattern } + end + cache[pattern] = parsed + if trace_lparse and not trace_lprofile then + lshow(parsed) + end + end + return parsed + end +end + +-- we can move all calls inline and then merge the trace back +-- technically we can combine axis and the next nodes which is +-- what we did before but this a bit cleaner (but slower too) +-- but interesting is that it's not that much faster when we +-- go inline +-- +-- beware: we need to return a collection even when we filter +-- else the (simple) cache gets messed up + +-- caching found lookups saves not that much (max .1 sec on a 8 sec run) +-- and it also messes up finalizers + +-- watch out: when there is a finalizer, it's always called as there +-- can be cases that a finalizer returns (or does) something in case +-- there is no match; an example of this is count() + +local profiled = { } xml.profiled = profiled + +local function profiled_apply(list,parsed,nofparsed,order) + local p = profiled[parsed.pattern] + if p then + p.tested = p.tested + 1 + else + p = { tested = 1, matched = 0, finalized = 0 } + profiled[parsed.pattern] = p + end + local collected = list + for i=1,nofparsed do + local pi = parsed[i] + local kind = pi.kind + if kind == "axis" then + collected = apply_axis[pi.axis](collected) + elseif kind == "nodes" then + collected = apply_nodes(collected,pi.nodetest,pi.nodes) + elseif kind == "expression" then + collected = apply_expression(collected,pi.evaluator,order) + elseif kind == "finalizer" then + collected = pi.finalizer(collected) + p.matched = p.matched + 1 + p.finalized = p.finalized + 1 + return collected + end + if not collected or #collected == 0 then + local pn = i < nofparsed and parsed[nofparsed] + if pn and pn.kind == "finalizer" then + collected = pn.finalizer(collected) + p.finalized = p.finalized + 1 + return collected + end + return nil + end + end + if collected then + p.matched = p.matched + 1 + end + return collected +end + +local function traced_apply(list,parsed,nofparsed,order) + if trace_lparse then + lshow(parsed) + end + logs.report("lpath", "collecting : %s",parsed.pattern) + logs.report("lpath", " root tags : %s",tagstostring(list)) + logs.report("lpath", " order : %s",order or "unset") + local collected = list + for i=1,nofparsed do + local pi = parsed[i] + local kind = pi.kind + if kind == "axis" then + collected = apply_axis[pi.axis](collected) + logs.report("lpath", "% 10i : ax : %s",(collected and #collected) or 0,pi.axis) + elseif kind == "nodes" then + collected = apply_nodes(collected,pi.nodetest,pi.nodes) + logs.report("lpath", "% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest)) + elseif kind == "expression" then + collected = apply_expression(collected,pi.evaluator,order) + logs.report("lpath", "% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted) + elseif kind == "finalizer" then + collected = pi.finalizer(collected) + logs.report("lpath", "% 10i : fi : %s : %s(%s)",(type(collected) == "table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "") + return collected + end + if not collected or #collected == 0 then + local pn = i < nofparsed and parsed[nofparsed] + if pn and pn.kind == "finalizer" then + collected = pn.finalizer(collected) + logs.report("lpath", "% 10i : fi : %s : %s(%s)",(type(collected) == "table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pn.name,pn.arguments or "") + return collected + end + return nil + end + end + return collected +end + +local function normal_apply(list,parsed,nofparsed,order) + local collected = list + for i=1,nofparsed do + local pi = parsed[i] + local kind = pi.kind + if kind == "axis" then + local axis = pi.axis + if axis ~= "self" then + collected = apply_axis[axis](collected) + end + elseif kind == "nodes" then + collected = apply_nodes(collected,pi.nodetest,pi.nodes) + elseif kind == "expression" then + collected = apply_expression(collected,pi.evaluator,order) + elseif kind == "finalizer" then + return pi.finalizer(collected) + end + if not collected or #collected == 0 then + local pf = i < nofparsed and parsed[nofparsed].finalizer + if pf then + return pf(collected) -- can be anything + end + return nil + end + end + return collected +end + +local function parse_apply(list,pattern) + -- we avoid an extra call + local parsed = cache[pattern] + if parsed then + lpathcalls = lpathcalls + 1 + lpathcached = lpathcached + 1 + elseif type(pattern) == "table" then + lpathcalls = lpathcalls + 1 + parsed = pattern + else + parsed = parse_pattern(pattern) or pattern + end + if not parsed then + return + end + local nofparsed = #parsed + if nofparsed == 0 then + return -- something is wrong + end + local one = list[1] + if not one then + return -- something is wrong + elseif not trace_lpath then + return normal_apply(list,parsed,nofparsed,one.mi) + elseif trace_lprofile then + return profiled_apply(list,parsed,nofparsed,one.mi) + else + return traced_apply(list,parsed,nofparsed,one.mi) + end +end + +-- internal (parsed) + +expressions.child = function(e,pattern) + return parse_apply({ e },pattern) -- todo: cache +end +expressions.count = function(e,pattern) + local collected = parse_apply({ e },pattern) -- todo: cache + return (collected and #collected) or 0 +end + +-- external + +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",tostring(str or "?")) + return false +end +expressions.undefined = function(s) + return s == nil +end + +expressions.quit = function(s) + if s or s == nil then + quit_expression = true + end + return true +end + +expressions.print = function(...) + print(...) + return true +end + +expressions.contains = find +expressions.find = find +expressions.upper = upper +expressions.lower = lower +expressions.number = tonumber +expressions.boolean = toboolean + +-- user interface + +local function traverse(root,pattern,handle) + logs.report("xml","use 'xml.selection' instead for '%s'",pattern) + local collected = parse_apply({ root },pattern) + if collected then + for c=1,#collected do + local e = collected[c] + local r = e.__p__ + handle(r,r.dt,e.ni) + end + end +end + +local function selection(root,pattern,handle) + local collected = parse_apply({ root },pattern) + if collected then + if handle then + for c=1,#collected do + handle(collected[c]) + end + else + return collected + end + end +end + +xml.parse_parser = parser +xml.parse_pattern = parse_pattern +xml.parse_apply = parse_apply +xml.traverse = traverse -- old method, r, d, k +xml.selection = selection -- new method, simple handle + +local lpath = parse_pattern + +xml.lpath = lpath + +function xml.cached_patterns() + return cache +end + +-- generic function finalizer (independant namespace) + +local function dofunction(collected,fnc) + if collected then + local f = functions[fnc] + if f then + for c=1,#collected do + f(collected[c]) + end + else + logs.report("xml","unknown function '%s'",fnc) + end + end +end + +xml.finalizers.xml["function"] = dofunction +xml.finalizers.tex["function"] = dofunction + +-- functions + +expressions.text = function(e,n) + local rdt = e.__p__.dt + return (rdt and rdt[n]) or "" +end + +expressions.name = function(e,n) -- ns + tg + local found = false + n = tonumber(n) or 0 + if n == 0 then + found = type(e) == "table" and e + elseif n < 0 then + local d, k = e.__p__.dt, e.ni + 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 + local d, k = e.__p__.dt, e.ni + 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 + +expressions.tag = function(e,n) -- only tg + if not e then + return "" + else + local found = false + n = tonumber(n) or 0 + if n == 0 then + found = (type(e) == "table") and e -- seems to fail + elseif n < 0 then + local d, k = e.__p__.dt, e.ni + 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 + local d, k = e.__p__.dt, e.ni + 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 +end + +--[[ldx-- +

This is the main filter function. It returns whatever is asked for.

+--ldx]]-- + +function xml.filter(root,pattern) -- no longer funny attribute handling here + return parse_apply({ root },pattern) +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]) -- old method +end +for e in xml.collected(xml.load('text.xml'),"title") do + print(e) -- new one +end + +--ldx]]-- + +local wrap, yield = coroutine.wrap, coroutine.yield + +function xml.elements(root,pattern,reverse) -- r, d, k + local collected = parse_apply({ root },pattern) + if collected then + if reverse then + return wrap(function() for c=#collected,1,-1 do + local e = collected[c] local r = e.__p__ yield(r,r.dt,e.ni) + end end) + else + return wrap(function() for c=1,#collected do + local e = collected[c] local r = e.__p__ yield(r,r.dt,e.ni) + end end) + end + end + return wrap(function() end) +end + +function xml.collected(root,pattern,reverse) -- e + local collected = parse_apply({ root },pattern) + if collected then + if reverse then + return wrap(function() for c=#collected,1,-1 do yield(collected[c]) end end) + else + return wrap(function() for c=1,#collected do yield(collected[c]) end end) + end + end + return wrap(function() end) +end diff --git a/tex/context/base/lxml-mis.lua b/tex/context/base/lxml-mis.lua new file mode 100644 index 000000000..9fd4270af --- /dev/null +++ b/tex/context/base/lxml-mis.lua @@ -0,0 +1,99 @@ +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, match = string.format, string.gsub, string.match +local lpegmatch = lpeg.match + +--[[ldx-- +

The following helper functions best belong to the lxml-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]]-- + +local function xmlgsub(t,old,new) -- will be replaced + 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 + xmlgsub(v,old,new) + end + end + end +end + +--~ xml.gsub = xmlgsub + +function xml.strip_leading_spaces(dk,d,k) -- cosmetic, for manual + if d and k then + local dkm = d[k-1] + if dkm and type(dkm) == "string" then + local s = match(dkm,"\n(%s+)") + xmlgsub(dk,"\n"..rep(" ",#s),"\n") + end + end +end + +--~ xml.escapes = { ['&'] = '&', ['<'] = '<', ['>'] = '>', ['"'] = '"' } +--~ xml.unescapes = { } for k,v in next, 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) + +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 lpegmatch(escaped,str) end +function xml.unescaped(str) return lpegmatch(unescaped,str) end +function xml.cleansed (str) return lpegmatch(cleansed,str) end + +-- this might move + +function xml.fillin(root,pattern,str,check) + local e = xml.first(root,pattern) + if e then + local n = #e.dt + if not check or n == 0 or (n == 1 and e.dt[1] == "") then + e.dt = { str } + end + end +end diff --git a/tex/context/base/lxml-sor.lua b/tex/context/base/lxml-sor.lua new file mode 100644 index 000000000..e220bfad6 --- /dev/null +++ b/tex/context/base/lxml-sor.lua @@ -0,0 +1,158 @@ +if not modules then modules = { } end modules ['lxml-sor'] = { + version = 1.001, + comment = "companion to lxml-sor.mkiv", + 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 +local lpegmatch = lpeg.match +local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes + +lxml.sorters = lxml.sorters or { } + +if not lxml.splitid then + local splitter = lpeg.C((1-lpeg.P(":"))^1) * lpeg.P("::") * lpeg.C(lpeg.P(1)^1) + function lxml.splitid(id) + local d, i = lpegmatch(splitter,id) + if d then + return d, i + else + return "", id + end + end +end + +local lists = { } + +function lxml.sorters.reset(name) + lists[name] = { + sorted = false, + entries = { }, + reverse = { }, + results = { }, + } +end + +function lxml.sorters.add(name,n,key) + local list = lists[name] + if list.sorted then + -- reverse is messed up, we could regenerate it and go on + else + local entries = list and list.entries + if entries then + local reverse = list.reverse + local e = reverse[n] + if e then + local keys = entries[e][2] + keys[#keys+1] = key + else + entries[#entries+1] = { n, { key } } + reverse[n] = #entries + end + end + end +end + +function lxml.sorters.show(name) + local list = lists[name] + local entries = list and list.entries + local NC, NR, bold = context.NC, context.NR, context.bold -- somehow bold is not working + if entries then + local maxn = 1 + for i=1,#entries do + if #entries[i][2] > maxn then maxn = #entries[i][2] end + end + context.starttabulate { "|Tr|Tr|" .. string.rep("Tlp|",maxn) } + NC() bold("n") + NC() bold("id") + if maxn > 1 then + for i=1,maxn do + NC() bold("entry " .. i) + end + else + NC() bold("entry") + end + NC() NR() + context.HL() + for i=1,#entries do + local entry = entries[i] + local document, node = lxml.splitid(entry[1]) + NC() context(i) + NC() context(node) + local e = entry[2] + for i=1,#e do + NC() context.detokenize(e[i]) + end + NC() NR() + end + context.stoptabulate() + end +end + +lxml.sorters.compare = sorters.comparers.basic -- (a,b) + +function lxml.sorters.sort(name) + local list = lists[name] + local entries = list and list.entries + if entries then + -- filtering + local results = { } + list.results = results + for i=1,#entries do + local entry = entries[i] + results[i] = { + entry = entry[1], + key = concat(entry[2], " "), + } + end + -- preparation + local strip = sorters.strip + local splitter = sorters.splitters.utf + local firstofsplit = sorters.firstofsplit + for i=1, #results do + local r = results[i] + r.split = splitter(strip(r.key)) + end + -- sorting + sorters.sort(results,lxml.sorters.compare) + -- finalizing + list.nofsorted = #results + local split = { } + for k=1,#results do -- rather generic so maybe we need a function + local v = results[k] + local entry, tag = firstofsplit(v) + local s = split[entry] -- keeps track of change + if not s then + s = { tag = tag, data = { } } + split[entry] = s + end + s.data[#s.data+1] = v + end + list.results = split + -- done + list.sorted = true + end +end + +function lxml.sorters.flush(name,setup) + local list = lists[name] + local results = list and list.results + local xmlw = context.xmlw + if results and next(results) then + for key, result in next, results do + local tag, data = result.tag, result.data + for d=1,#data do + xmlw(setup,data[d].entry) + end + end + else + local entries = list and list.entries + if entries then + for i=1,#entries do + xmlw(setup,entries[i][1]) + end + end + end +end diff --git a/tex/context/base/lxml-sor.mkiv b/tex/context/base/lxml-sor.mkiv new file mode 100644 index 000000000..14425967b --- /dev/null +++ b/tex/context/base/lxml-sor.mkiv @@ -0,0 +1,94 @@ +%D \module +%D [ file=lxml-sor, +%D version=2009.08.24, +%D title=\CONTEXT\ \XML\ Support, +%D subtitle=Sorting, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 VERY EXPERIMENTAL! + +\writestatus{loading}{ConTeXt XML Support / Sorting} + +\registerctxluafile{lxml-sor}{1.001} + +\unprotect + +\def\xmlresetsorter #1{\ctxlua{lxml.sorters.reset("#1")}} +\def\xmladdsortentry#1#2#3{\ctxlua{lxml.sorters.add("#1","#2",\!!bs#3\!!es)}} +\def\xmlshowsorter #1{\ctxlua{lxml.sorters.show("#1")}} +\def\xmlflushsorter #1#2{\ctxlua{lxml.sorters.flush("#1","#2")}} +\def\xmlsortentries #1{\ctxlua{lxml.sorters.sort("#1")}} + +\protect \endinput + +\startbuffer[test] + + + one + alpha + alpha indeed + + + one + gamma + gamma indeed + + + one + beta + beta indeed + + + two + alpha + alpha again + + + two + gamma + gamma again + + + two + beta + beta again + + +\stopbuffer + +\startxmlsetups xml:mysetups + \xmlsetsetup{\xmldocument}{demo|entry|content}{xml:*} +\stopxmlsetups + +\xmlregistersetup{xml:mysetups} + +\startxmlsetups xml:demo + \xmlresetsorter{demo} + \xmlfilter{#1}{entry/command(xml:entry:getkeys)} + \blank sortkeys: \blank\xmlshowsorter{demo}\blank + \xmlsortentries{demo} + \xmlflushsorter{demo}{xml:entry:flush} +\stopxmlsetups + +\startxmlsetups xml:entry:getkeys + \xmladdsortentry{demo}{#1}{\xmltext{#1}{category}} + \xmladdsortentry{demo}{#1}{\xmltext{#1}{key|entry}} +\stopxmlsetups + +\startxmlsetups xml:entry:flush + \xmltext{#1}{content}\par +\stopxmlsetups + +\startxmlsetups xml:entry + \xmltext{#1}{content}\par +\stopxmlsetups + +\starttext + \xmlprocessbuffer{main}{test}{} +\stoptext diff --git a/tex/context/base/lxml-tab.lua b/tex/context/base/lxml-tab.lua new file mode 100644 index 000000000..23cd1cf04 --- /dev/null +++ b/tex/context/base/lxml-tab.lua @@ -0,0 +1,1174 @@ +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" +} + +-- this module needs a cleanup: check latest lpeg, passing args, (sub)grammar, etc etc +-- stripping spaces from e.g. cont-en.xml saves .2 sec runtime so it's not worth the +-- trouble + +local trace_entities = false trackers.register("xml.entities", function(v) trace_entities = v end) + +--[[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.

+ +

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, getmetatable, tonumber = type, next, setmetatable, getmetatable, tonumber +local format, lower, find, match, gsub = string.format, string.lower, string.find, string.match, string.gsub +local utfchar = unicode.utf8.char +local lpegmatch = lpeg.match +local P, S, R, C, V, C, Cs = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.V, lpeg.C, lpeg.Cs + +--[[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 = 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 + C(P(lower(pattern))) / namespace + parse = P { P(check) + 1 * 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 = lpegmatch(parse,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 lpegmatch(parse,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.

+ +

Valid entities are:

+ + + + + + +--ldx]]-- + +-- 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 strip, cleanup, utfize, resolve, resolve_predefined, unify_predefined = false, false, false, false, false, false +local dcache, hcache, acache = { }, { }, { } + +local mt = { } + +function initialize_mt(root) + mt = { __index = root } -- will be redefined later +end + +function xml.setproperty(root,k,v) + getmetatable(root).__index[k] = v +end + +function xml.check_error(top,toclose) + return "" +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 == "" then + at[tag] = value + elseif namespace == "xmlns" then + xml.checkns(tag,value) + at["xmlns:" .. tag] = value + else + -- for the moment this way: + at[namespace .. ":" .. tag] = value + 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_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 -- nasty circular reference when serializing table + if toclose.at.xmlns then + remove(xmlns) + end +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 reported_attribute_errors = { } + +local function attribute_value_error(str) + if not reported_attribute_errors[str] then + logs.report("xml","invalid attribute value: %q",str) + reported_attribute_errors[str] = true + at._error_ = str + end + return str +end +local function attribute_specification_error(str) + if not reported_attribute_errors[str] then + logs.report("xml","invalid attribute specification: %q",str) + reported_attribute_errors[str] = true + at._error_ = str + end + return str +end + +function xml.unknown_dec_entity_format(str) return (str == "" and "&error;") or format("&%s;",str) end +function xml.unknown_hex_entity_format(str) return format("&#x%s;",str) end +function xml.unknown_any_entity_format(str) return format("&#x%s;",str) end + +local function fromhex(s) + local n = tonumber(s,16) + if n then + return utfchar(n) + else + return format("h:%s",s), true + end +end + +local function fromdec(s) + local n = tonumber(s) + if n then + return utfchar(n) + else + return format("d:%s",s), true + end +end + +-- one level expansion (simple case), no checking done + +local rest = (1-P(";"))^0 +local many = P(1)^0 + +local parsedentity = + P("&") * (P("#x")*(rest/fromhex) + P("#")*(rest/fromdec)) * P(";") * P(-1) + + (P("#x")*(many/fromhex) + P("#")*(many/fromdec)) + +-- parsing in the xml file + +local predefined_unified = { + [38] = "&", + [42] = """, + [47] = "'", + [74] = "<", + [76] = "&gr;", +} + +local predefined_simplified = { + [38] = "&", amp = "&", + [42] = '"', quot = '"', + [47] = "'", apos = "'", + [74] = "<", lt = "<", + [76] = ">", gt = ">", +} + +local function handle_hex_entity(str) + local h = hcache[str] + if not h then + local n = tonumber(str,16) + h = unify_predefined and predefined_unified[n] + if h then + if trace_entities then + logs.report("xml","utfize, converting hex entity &#x%s; into %s",str,h) + end + elseif utfize then + h = (n and utfchar(n)) or xml.unknown_hex_entity_format(str) or "" + if not n then + logs.report("xml","utfize, ignoring hex entity &#x%s;",str) + elseif trace_entities then + logs.report("xml","utfize, converting hex entity &#x%s; into %s",str,h) + end + else + if trace_entities then + logs.report("xml","found entity &#x%s;",str) + end + h = "&#x" .. str .. ";" + end + hcache[str] = h + end + return h +end + +local function handle_dec_entity(str) + local d = dcache[str] + if not d then + local n = tonumber(str) + d = unify_predefined and predefined_unified[n] + if d then + if trace_entities then + logs.report("xml","utfize, converting dec entity &#%s; into %s",str,d) + end + elseif utfize then + d = (n and utfchar(n)) or xml.unknown_dec_entity_format(str) or "" + if not n then + logs.report("xml","utfize, ignoring dec entity &#%s;",str) + elseif trace_entities then + logs.report("xml","utfize, converting dec entity &#%s; into %s",str,h) + end + else + if trace_entities then + logs.report("xml","found entity &#%s;",str) + end + d = "&#" .. str .. ";" + end + dcache[str] = d + end + return d +end + +xml.parsedentitylpeg = parsedentity + +local function handle_any_entity(str) + if resolve then + local a = acache[str] -- per instance ! todo + if not a then + a = resolve_predefined and predefined_simplified[str] + if a then + -- one of the predefined + elseif type(resolve) == "function" then + a = resolve(str) or entities[str] + else + a = entities[str] + end + if a then + if trace_entities then + logs.report("xml","resolved entity &%s; -> %s (internal)",str,a) + end + a = lpegmatch(parsedentity,a) or a + else + if xml.unknown_any_entity_format then + a = xml.unknown_any_entity_format(str) or "" + end + if a then + if trace_entities then + logs.report("xml","resolved entity &%s; -> %s (external)",str,a) + end + else + if trace_entities then + logs.report("xml","keeping entity &%s;",str) + end + if str == "" then + a = "&error;" + else + a = "&" .. str .. ";" + end + end + end + acache[str] = a + elseif trace_entities then + if not acache[str] then + logs.report("xml","converting entity &%s; into %s",str,a) + acache[str] = a + end + end + return a + else + local a = acache[str] + if not a then + if trace_entities then + logs.report("xml","found entity &%s;",str) + end + a = resolve_predefined and predefined_simplified[str] + if a then + -- one of the predefined + acache[str] = a + elseif str == "" then + a = "&error;" + acache[str] = a + else + a = "&" .. str .. ";" + acache[str] = a + end + end + return a + end +end + +local function handle_end_entity(chr) + logs.report("xml","error in entity, %q found instead of ';'",chr) +end + +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 semicolon = P(';') +local ampersand = 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 = lpeg.patterns.utfbom -- no capture +local spacing = C(space^0) + +----- entitycontent = (1-open-semicolon)^0 +local anyentitycontent = (1-open-semicolon-space-close)^0 +local hexentitycontent = R("AF","af","09")^0 +local decentitycontent = R("09")^0 +local parsedentity = P("#")/"" * ( + P("x")/"" * (hexentitycontent/handle_hex_entity) + + (decentitycontent/handle_dec_entity) + ) + (anyentitycontent/handle_any_entity) +local entity = ampersand/"" * parsedentity * ( (semicolon/"") + #(P(1)/handle_end_entity)) + +local text_unparsed = C((1-open)^1) +local text_parsed = Cs(((1-open-ampersand)^1 + entity)^1) + +local somespace = space^1 +local optionalspace = space^0 + +----- value = (squote * C((1 - squote)^0) * squote) + (dquote * C((1 - dquote)^0) * dquote) -- ampersand and < also invalid in value +local value = (squote * Cs((entity + (1 - squote))^0) * squote) + (dquote * Cs((entity + (1 - dquote))^0) * dquote) -- ampersand and < also invalid in value + +local endofattributes = slash * close + close -- recovery of flacky html +local whatever = space * name * optionalspace * equal +local wrongvalue = C(P(1-whatever-close)^1 + P(1-close)^1) / attribute_value_error +----- wrongvalue = C(P(1-whatever-endofattributes)^1 + P(1-endofattributes)^1) / attribute_value_error +----- wrongvalue = C(P(1-space-endofattributes)^1) / attribute_value_error +local wrongvalue = Cs(P(entity + (1-space-endofattributes))^1) / attribute_value_error + +local attributevalue = value + wrongvalue + +local attribute = (somespace * name * optionalspace * equal * optionalspace * attributevalue) / add_attribute +----- attributes = (attribute)^0 + +local attributes = (attribute + somespace^-1 * (((1-endofattributes)^1)/attribute_specification_error))^0 + +local parsedtext = text_parsed / add_text +local unparsedtext = text_unparsed / 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 normalentity(k,v ) entities[k] = v end +local function systementity(k,v,n) entities[k] = v end +local function publicentity(k,v,n) entities[k] = v end + +local begindoctype = open * P("!DOCTYPE") +local enddoctype = close +local beginset = P("[") +local endset = P("]") +local doctypename = C((1-somespace-close)^0) +local elementdoctype = optionalspace * P(" & + cleanup = settings.text_cleanup + stack, top, at, xmlns, errorstr, result, entities = { }, { }, { }, { }, nil, nil, settings.entities or { } + acache, hcache, dcache = { }, { }, { } -- not stored + reported_attribute_errors = { } + if settings.parent_root then + mt = getmetatable(settings.parent_root) + else + initialize_mt(top) + end + stack[#stack+1] = top + top.dt = { } + dt = top.dt + if not data or data == "" then + errorstr = "empty xml file" + elseif utfize or resolve then + if lpegmatch(grammar_parsed_text,data) then + errorstr = "" + else + errorstr = "invalid xml file - parsed text" + end + elseif type(data) == "string" then + if lpegmatch(grammar_unparsed_text,data) then + errorstr = "" + else + errorstr = "invalid xml file - unparsed text" + end + else + errorstr = "invalid xml file - no text at all" + end + if errorstr and errorstr ~= "" then + result = { dt = { { ns = "", tg = "error", dt = { errorstr }, at={ }, er = true } } } + setmetatable(stack, mt) + local error_handler = settings.error_handler + if error_handler == false then + -- no error message + else + error_handler = error_handler or xml.error_handler + if error_handler then + xml.error_handler("load",errorstr) + end + end + else + result = stack[1] + end + if not settings.no_root then + result = { special = true, ns = "", tg = '@rt@', dt = result.dt, at={ }, entities = entities, settings = settings } + setmetatable(result, mt) + local rdt = result.dt + for k=1,#rdt do + local v = rdt[k] + if type(v) == "table" and not v.special then -- always table -) + result.ri = k -- rootindex +v.__p__ = result -- new, experiment, else we cannot go back to settings, we need to test this ! + break + end + end + end + if errorstr and errorstr ~= "" then + result.error = true + end + return result +end + +xml.convert = xmlconvert + +function xml.inheritedconvert(data,xmldata) + local settings = xmldata.settings + settings.parent_root = xmldata -- to be tested + -- settings.no_root = true + local xc = xmlconvert(data,settings) + -- xc.settings = nil + -- xc.entities = nil + -- xc.special = nil + -- xc.ri = nil + -- print(xc.tg) + return xc +end + +--[[ldx-- +

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 = match(tag,"^(.-):?([^:]+)$") + 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,settings) + local data = "" + if type(filename) == "string" then + -- local data = io.loaddata(filename) - -todo: check type in io.loaddata + local f = io.open(filename,'r') + if f then + data = f:read("*all") + f:close() + end + elseif filename then -- filehandle + data = filename:read("*all") + end + return xmlconvert(data,settings) +end + +--[[ldx-- +

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

+--ldx]]-- + +local no_root = { no_root = true } + +function xml.toxml(data) + if type(data) == "string" then + local root = { xmlconvert(data,no_root) } + 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]]-- + +local 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 next, 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 + +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[1],"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]]-- + +-- new experimental reorganized serialize + +local function verbose_element(e,handlers) + local handle = handlers.handle + local serialize = handlers.serialize + local ens, etg, eat, edt, ern = e.ns, e.tg, e.at, e.dt, e.rn + local ats = eat and next(eat) and { } + if ats then + for k,v in next, eat do + ats[#ats+1] = format('%s=%q',k,v) + 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("<",ens,":",etg," ",concat(ats," "),">") + else + handle("<",ens,":",etg,">") + end + for i=1,#edt do + local e = edt[i] + if type(e) == "string" then + handle(e) + else + serialize(e,handlers) + end + end + handle("") + else + if ats then + handle("<",ens,":",etg," ",concat(ats," "),"/>") + else + handle("<",ens,":",etg,"/>") + end + end + else + if edt and #edt > 0 then + if ats then + handle("<",etg," ",concat(ats," "),">") + else + handle("<",etg,">") + end + for i=1,#edt do + local ei = edt[i] + if type(ei) == "string" then + handle(ei) + else + serialize(ei,handlers) + end + end + handle("") + else + if ats then + handle("<",etg," ",concat(ats," "),"/>") + else + handle("<",etg,"/>") + end + end + end +end + +local function verbose_pi(e,handlers) + handlers.handle("") +end + +local function verbose_comment(e,handlers) + handlers.handle("") +end + +local function verbose_cdata(e,handlers) + handlers.handle("") +end + +local function verbose_doctype(e,handlers) + handlers.handle("") +end + +local function verbose_root(e,handlers) + handlers.serialize(e.dt,handlers) +end + +local function verbose_text(e,handlers) + handlers.handle(e) +end + +local function verbose_document(e,handlers) + local serialize = handlers.serialize + local functions = handlers.functions + for i=1,#e do + local ei = e[i] + if type(ei) == "string" then + functions["@tx@"](ei,handlers) + else + serialize(ei,handlers) + end + end +end + +local function serialize(e,handlers,...) + local initialize = handlers.initialize + local finalize = handlers.finalize + local functions = handlers.functions + if initialize then + local state = initialize(...) + if not state == true then + return state + end + end + local etg = e.tg + if etg then + (functions[etg] or functions["@el@"])(e,handlers) + -- elseif type(e) == "string" then + -- functions["@tx@"](e,handlers) + else + functions["@dc@"](e,handlers) + end + if finalize then + return finalize() + end +end + +local function xserialize(e,handlers) + local functions = handlers.functions + local etg = e.tg + if etg then + (functions[etg] or functions["@el@"])(e,handlers) + -- elseif type(e) == "string" then + -- functions["@tx@"](e,handlers) + else + functions["@dc@"](e,handlers) + end +end + +local handlers = { } + +local function newhandlers(settings) + local t = table.copy(handlers.verbose or { }) -- merge + if settings then + for k,v in next, settings do + if type(v) == "table" then + tk = t[k] if not tk then tk = { } t[k] = tk end + for kk,vv in next, v do + tk[kk] = vv + end + else + t[k] = v + end + end + if settings.name then + handlers[settings.name] = t + end + end + return t +end + +local nofunction = function() end + +function xml.sethandlersfunction(handler,name,fnc) + handler.functions[name] = fnc or nofunction +end + +function xml.gethandlersfunction(handler,name) + return handler.functions[name] +end + +function xml.gethandlers(name) + return handlers[name] +end + +newhandlers { + name = "verbose", + initialize = false, -- faster than nil and mt lookup + finalize = false, -- faster than nil and mt lookup + serialize = xserialize, + handle = print, + functions = { + ["@dc@"] = verbose_document, + ["@dt@"] = verbose_doctype, + ["@rt@"] = verbose_root, + ["@el@"] = verbose_element, + ["@pi@"] = verbose_pi, + ["@cm@"] = verbose_comment, + ["@cd@"] = verbose_cdata, + ["@tx@"] = verbose_text, + } +} + +--[[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 + + +

Beware, these were timing with the old routine but measurements will not be that +much different I guess.

+--ldx]]-- + +-- maybe this will move to lxml-xml + +local result + +local xmlfilehandler = newhandlers { + name = "file", + initialize = function(name) result = io.open(name,"wb") return result end, + finalize = function() result:close() return true end, + handle = function(...) result:write(...) end, +} + +-- no checking on writeability here but not faster either +-- +-- local xmlfilehandler = newhandlers { +-- initialize = function(name) io.output(name,"wb") return true end, +-- finalize = function() io.close() return true end, +-- handle = io.write, +-- } + + +function xml.save(root,name) + serialize(root,xmlfilehandler,name) +end + +local result + +local xmlstringhandler = newhandlers { + name = "string", + initialize = function() result = { } return result end, + finalize = function() return concat(result) end, + handle = function(...) result[#result+1] = concat { ... } end +} + +local function xmltostring(root) -- 25% overhead due to collecting + if root then + if type(root) == 'string' then + return root + else -- if next(root) then -- next is faster than type (and >0 test) + return serialize(root,xmlstringhandler) or "" + end + end + return "" +end + +local function xmltext(root) -- inline + return (root and xmltostring(root)) or "" +end + +function initialize_mt(root) + mt = { __tostring = xmltext, __index = root } +end + +xml.defaulthandlers = handlers +xml.newhandlers = newhandlers +xml.serialize = serialize +xml.tostring = xmltostring + +--[[ldx-- +

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

+--ldx]]-- + +local function xmlstring(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 + xmlstring(edt[i],handle) + end + end + else + handle(e) + end +end + +xml.string = xmlstring + +--[[ldx-- +

A few helpers:

+--ldx]]-- + +--~ xmlsetproperty(root,"settings",settings) + +function xml.settings(e) + while e do + local s = e.settings + if s then + return s + else + e = e.__p__ + end + end + return nil +end + +function xml.root(e) + local r = e + while e do + e = e.__p__ + if e then + r = e + end + end + return r +end + +function xml.parent(root) + return root.__p__ +end + +function xml.body(root) + return (root.ri and root.dt[root.ri]) or root -- not ok yet +end + +function xml.name(root) + if not root then + return "" + elseif root.ns == "" then + return root.tg + else + return root.ns .. ":" .. root.tg + 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:

+--ldx]]-- + +function xml.erase(dt,k) + if dt then + if k then + dt[k] = "" + else for k=1,#dt do + dt[1] = { "" } + end end + 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 + +-- the following helpers may move + +--[[ldx-- +

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

+ +xml.tocdata(e) +xml.tocdata(e,"error") + +--ldx]]-- + +function xml.tocdata(e,wrapper) + local whatever = xmltostring(e.dt) + if wrapper then + whatever = format("<%s>%s",wrapper,whatever,wrapper) + end + local t = { special = true, ns = "", tg = "@cd@", at = {}, rn = "", dt = { whatever }, __p__ = e } + setmetatable(t,getmetatable(e)) + e.dt = { t } +end + +function xml.makestandalone(root) + if root.ri then + local dt = root.dt + for k=1,#dt do + local v = dt[k] + if type(v) == "table" and v.special and v.tg == "@pi@" then + local txt = v.dt[1] + if find(txt,"xml.*version=") then + v.dt[1] = txt .. " standalone='yes'" + break + end + end + end + end +end diff --git a/tex/context/base/lxml-tex.lua b/tex/context/base/lxml-tex.lua new file mode 100644 index 000000000..aaa90217f --- /dev/null +++ b/tex/context/base/lxml-tex.lua @@ -0,0 +1,1410 @@ +if not modules then modules = { } end modules ['lxml-tst'] = { + version = 1.001, + comment = "companion to lxml-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local utf = unicode.utf8 + +local utfchar = utf.char +local concat, insert, remove, gsub, find = table.concat, table.insert, table.remove +local format, sub, gsub, find, gmatch, match = string.format, string.sub, string.gsub, string.find, string.gmatch, string.match +local type, next, tonumber, tostring = type, next, tonumber, tostring +local lpegmatch = lpeg.match +local P, S, C, Cc = lpeg.P, lpeg.S, lpeg.C, lpeg.Cc + +if not tex and not tex.sprint then + tex = { + sprint = function(catcodes,...) texio.write(table.concat{...}) end, + print = function(catcodes,...) texio.write(table.concat{...}) end, + write = function( ...) texio.write(table.concat{...}) end, + } + commands = { + writestatus = logs.report + } + resolvers.loadbinfile = function(filename) return true, io.loaddata(filename) end +end + +local texsprint, texprint, texwrite = tex.sprint, tex.print, tex.write +local texcatcodes, ctxcatcodes, vrbcatcodes, notcatcodes = tex.texcatcodes, tex.ctxcatcodes, tex.vrbcatcodes, tex.notcatcodes + +local xmlelements, xmlcollected, xmlsetproperty = xml.elements, xml.collected, xml.setproperty +local xmlparseapply, xmlwithelements = xml.parse_apply, xml.withelements +local xmlserialize, xmlcollect, xmltext, xmltostring = xml.serialize, xml.collect, xml.text, xml.tostring + +local variables = (interfaces and interfaces.variables) or { } + +local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming + +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) +local trace_access = false trackers.register("lxml.access", function(v) trace_access = v end) +local trace_comments = false trackers.register("lxml.comments", function(v) trace_comments = v end) + +lxml = lxml or { } +lxml.loaded = lxml.loaded or { } + +local loaded = lxml.loaded + +-- print(contextdirective("context-mathml-directive function reduction yes ")) +-- print(contextdirective("context-mathml-directive function ")) + +xml.defaultprotocol = "tex" + +local finalizers = xml.finalizers + +finalizers.xml = finalizers.xml or { } +finalizers.tex = finalizers.tex or { } + +-- this might look inefficient but it's actually rather efficient +-- because we avoid tokenization of leading spaces and xml can be +-- rather verbose (indented) + +local newline = lpeg.patterns.newline +local space = lpeg.patterns.spacer +local ampersand = P("&") +local semicolon = P(";") +local spacing = newline * space^0 +local content = C((1-spacing-ampersand)^1) +local verbose = C((1-(space+newline))^1) +local entity = ampersand * C((1-semicolon)^1) * semicolon + +local xmltextcapture = ( + space^0 * newline^2 * Cc("") / texprint + -- better ^-2 ? + space^0 * newline * space^0 * Cc(" ") / texsprint + + content / function(str) return texsprint(notcatcodes,str) end + -- was just texsprint, current catcodes regime is notcatcodes + entity / xml.resolved_entity +)^0 + +local ctxtextcapture = ( + space^0 * newline^2 * Cc("") / texprint + -- better ^-2 ? + space^0 * newline * space^0 * Cc(" ") / texsprint + + content / function(str) return texsprint(ctxcatcodes,str) end + -- was just texsprint, current catcodes regime is notcatcodes + entity / xml.resolved_entity +)^0 + +local forceraw, rawroot = false, nil + +function lxml.startraw() + forceraw = true +end + +function lxml.stopraw() + forceraw = false +end + +function lxml.rawroot() + return rawroot +end + +--~ function lxml.rawpath(rootid) +--~ if rawroot and type(rawroot) == "table" then +--~ local text, path, rp +--~ if not rawroot.dt then +--~ text, path, rp = "text", "", rawroot[0] +--~ else +--~ path, rp = "tree", "", rawroot.__p__ +--~ end +--~ while rp do +--~ local rptg = rp.tg +--~ if rptg then +--~ path = rptg .. "/" .. path +--~ end +--~ rp = rp.__p__ +--~ end +--~ return { rootid, "/" .. path, text } +--~ end +--~ end + +-- cdata + +local linecommand = "\\obeyedline" +local spacecommand = "\\obeyedspace" -- "\\strut\\obeyedspace" +local beforecommand = "" +local aftercommand = "" + +local xmlverbosecapture = ( + 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(texcatcodes,beforecommand,"{}") end + lpegmatch(xmlverbosecapture,str) + if aftercommand then texsprint(texcatcodes,aftercommand,"{}") end +end + +function lxml.set_verbatim(before,after,obeyedline,obeyedspace) + beforecommand, aftercommand, linecommand, spacecommand = before, after, obeyedline, obeyedspace +end + +local obeycdata = true + +function lxml.set_cdata() + obeycdata = true +end + +function lxml.reset_cdata() + obeycdata = false +end + +-- cdata and verbatim + +lxml.set_verbatim("\\xmlcdatabefore", "\\xmlcdataafter", "\\xmlcdataobeyedline", "\\xmlcdataobeyedspace") + +-- local capture = (space^0*newline)^0 * capture * (space+newline)^0 * -1 + +function lxml.toverbatim(str) + if beforecommand then texsprint(texcatcodes,beforecommand,"{}") end + -- todo: add this to capture + str = gsub(str,"^[ \t]+[\n\r]+","") + str = gsub(str,"[ \t\n\r]+$","") + lpegmatch(xmlverbosecapture,str) + if aftercommand then texsprint(texcatcodes,aftercommand,"{}") end +end + +-- storage + +function lxml.store(id,root,filename) + loaded[id] = root + xmlsetproperty(root,"name",id) + if filename then + xmlsetproperty(root,"filename",filename) + end +end + +local splitter = lpeg.splitat("::") + +lxml.idsplitter = splitter + +function lxml.splitid(id) + local d, i = lpegmatch(splitter,id) + if d then + return d, i + else + return "", id + end +end + +local function get_id(id, qualified) + if id then + local lid = loaded[id] + if lid then + return lid + elseif type(id) == "table" then + return id + else + local d, i = lpegmatch(splitter,id) + if d then + local ld = loaded[d] + if ld then + local ldi = ld.index + if ldi then + local root = ldi[tonumber(i)] + if root then + if qualified then -- we need this else two args that confuse others + return root, d + else + return root + end + elseif trace_access then + logs.report("lxml","'%s' has no index entry '%s'",d,i) + end + elseif trace_access then + logs.report("lxml","'%s' has no index",d) + end + elseif trace_access then + logs.report("lxml","'%s' is not loaded",d) + end + elseif trace_access then + logs.report("lxml","'%s' is not loaded",i) + end + end + elseif trace_access then + logs.report("lxml","invalid id (nil)") + end +end + +lxml.id = get_id +lxml.get_id = get_id + +function lxml.root(id) + return loaded[id] +end + +-- index + +local nofindices = 0 + +local function addindex(name,check_sum,force) + local root = get_id(name) + if root and (not root.index or force) then -- weird, only called once + local n, index, maxindex, check = 0, root.index or { }, root.maxindex or 0, root.check or { } + local function nest(root) + local dt = root.dt + if not root.ix then + maxindex = maxindex + 1 + root.ix = maxindex + check[maxindex] = root.tg -- still needed ? + index[maxindex] = root + n = n + 1 + end + if dt then + for k=1,#dt do + local dk = dt[k] + if type(dk) == "table" then + nest(dk) + end + end + end + end + nest(root) + nofindices = nofindices + n + -- + if type(name) ~= "string" then + name = "unknown" + end + root.index = index + root.maxindex = maxindex + if trace_access then + logs.report("lxml","%s indexed, %s nodes",tostring(name),maxindex) + end + end +end + +lxml.addindex = addindex + +-- another cache + +local function lxmlparseapply(id,pattern) -- better inline, saves call + return xmlparseapply({ get_id(id) }, pattern) +end + +lxml.filter = lxmlparseapply + +function lxml.filterlist(list,pattern) + for s in gmatch(list,"[^, ]+") do -- we could cache a table + lxmlparseapply(s,pattern) + end +end + +lxml["function"] = function(id,name) + local f = xml.functions[name] + return f and f(get_id(id)) +end + +-- rather new, indexed storage (backward refs), maybe i will merge this + +function lxml.checkindex(name) + local root = get_id(name) + return (root and root.index) or 0 +end + +function lxml.withindex(name,n,command) -- will change as name is always there now + local i, p = lpegmatch(splitter,n) + if p then + texsprint(ctxcatcodes,"\\xmlw{",command,"}{",n,"}") + else + texsprint(ctxcatcodes,"\\xmlw{",command,"}{",name,"::",n,"}") + end +end + +function lxml.getindex(name,n) -- will change as name is always there now + local i, p = lpegmatch(splitter,n) + if p then + texsprint(ctxcatcodes,n) + else + texsprint(ctxcatcodes,name,"::",n) + end +end + +-- loading (to be redone, no overload) + +xml.originalload = xml.originalload or xml.load + +local noffiles, nofconverted = 0, 0 + +function xml.load(filename,settings) + noffiles, nofconverted = noffiles + 1, nofconverted + 1 + starttiming(xml) + local ok, data = resolvers.loadbinfile(filename) + local xmltable = xml.convert((ok and data) or "",settings) + stoptiming(xml) + return xmltable +end + +local entities = xml.entities + +local function entityconverter(id,str) + return entities[str] and "&"..str..";" -- feed back into tex end later +end + +function lxml.convert(id,data,entities,compress) + local settings = { + unify_predefined_entities = true, + } + if compress and compress == variables.yes then + settings.strip_cm_and_dt = true + end + if entities and entities == variables.yes then + settings.utfize_entities = true + settings.resolve_entities = function (str) return entityconverter(id,str) end + end + return xml.convert(data,settings) +end + +function lxml.load(id,filename,compress,entities) + filename = commands.preparedfile(filename) + if trace_loading then + commands.writestatus("lxml","loading file '%s' as '%s'",filename,id) + end + noffiles, nofconverted = noffiles + 1, nofconverted + 1 + -- local xmltable = xml.load(filename) + local ok, data = resolvers.loadbinfile(filename) + local xmltable = lxml.convert(id,(ok and data) or "",compress,entities) + lxml.store(id,xmltable,filename) + return xmltable, filename +end + +function lxml.register(id,xmltable,filename) + lxml.store(id,xmltable,filename) + return xmltable +end + +function lxml.include(id,pattern,attribute,recurse) + starttiming(xml) + local root = get_id(id) + xml.include(root,pattern,attribute,recurse,function(filename) + if filename then + filename = commands.preparedfile(filename) + if file.dirname(filename) == "" and root.filename then + local dn = file.dirname(root.filename) + if dn ~= "" then + filename = file.join(dn,filename) + end + end + if trace_loading then + commands.writestatus("lxml","including file: %s",filename) + end + noffiles, nofconverted = noffiles + 1, nofconverted + 1 + return resolvers.loadtexfile(filename) or "" + else + return "" + end + end) + stoptiming(xml) +end + +function xml.getbuffer(name,compress,entities) -- we need to make sure that commands are processed + if not name or name == "" then + name = tex.jobname + end + nofconverted = nofconverted + 1 + xmltostring(lxml.convert(name,concat(buffers.data[name] or {},""),compress,entities)) +end + +function lxml.loadbuffer(id,name,compress,entities) + if not name or name == "" then + name = tex.jobname + end + starttiming(xml) + nofconverted = nofconverted + 1 + local xmltable = lxml.convert(id,buffers.collect(name or id,"\n"),compress,entities) + lxml.store(id,xmltable) + stoptiming(xml) + return xmltable, name or id +end + +function lxml.loaddata(id,str,compress,entities) + starttiming(xml) + nofconverted = nofconverted + 1 + local xmltable = lxml.convert(id,str or "",compress,entities) + lxml.store(id,xmltable) + stoptiming(xml) + return xmltable, id +end + +function lxml.loadregistered(id) + return loaded[id], id +end + +-- e.command: +-- +-- string : setup +-- true : text (no ) +-- false : ignore +-- function : call + +local function tex_doctype(e,handlers) + -- ignore +end + +local function tex_comment(e,handlers) + if trace_comments then + logs.report("lxml","comment: %s",e.dt[1]) + end +end + +local default_element_handler = xml.gethandlers("verbose").functions["@el@"] + +local function tex_element(e,handlers) + local command = e.command + if command == nil then + default_element_handler(e,handlers) + elseif command == true then + -- text (no ) / so, no mkii fallback then + handlers.serialize(e.dt,handlers) + elseif command == false then + -- ignore + else + local tc = type(command) + if tc == "string" then + local rootname, ix = e.name, e.ix + if rootname then + if not ix then + addindex(rootname,false,true) + ix = e.ix + end + texsprint(ctxcatcodes,"\\xmlw{",command,"}{",rootname,"::",ix,"}") + else + logs.report("lxml", "fatal error: no index for '%s'",command) + texsprint(ctxcatcodes,"\\xmlw{",command,"}{",ix or 0,"}") + end + elseif tc == "function" then + command(e) + end + end +end + +local pihandlers = { } xml.pihandlers = pihandlers + +local kind = P("context-") * C((1-P("-"))^1) * P("-directive") +local space = S(" \n\r") +local spaces = space^0 +local class = C((1-space)^0) +local key = class +local value = C(P(1-(space * -1))^0) + +local parser = kind * spaces * class * spaces * key * spaces * value + +pihandlers[#pihandlers+1] = function(str) +-- local kind, class, key, value = lpegmatch(parser,str) + if str then + local a, b, c, d = lpegmatch(parser,str) + if d then + texsprint(ctxcatcodes,"\\xmlcontextdirective{",a",}{",b,"}{",c,"}{",d,"}") + end + end +end + +local function tex_pi(e,handlers) + local str = e.dt[1] + for i=1,#pihandlers do + pihandlers[i](str) + end +end + +local function tex_cdata(e,handlers) + if obeycdata then + toverbatim(e.dt[1]) + end +end + +local function tex_text(e) + lpegmatch(xmltextcapture,e) +end + +local function ctx_text(e) + lpegmatch(ctxtextcapture,e) +end + +local function tex_handle(...) +-- logs.report("lxml", "error while flushing: %s", concat { ... }) + texsprint(...) -- notcatcodes is active anyway +end + +local xmltexhandler = xml.newhandlers { + name = "tex", + handle = tex_handle, + functions = { + -- ["@dc@"] = tex_document, + ["@dt@"] = tex_doctype, + -- ["@rt@"] = tex_root, + ["@el@"] = tex_element, + ["@pi@"] = tex_pi, + ["@cm@"] = tex_comment, + ["@cd@"] = tex_cdata, + ["@tx@"] = tex_text, + } +} + +lxml.xmltexhandler = xmltexhandler + +function lxml.serialize(root) + xmlserialize(root,xmltexhandler) +end + +function lxml.setaction(id,pattern,action) + local collected = lxmlparseapply(id,pattern) + if collected then + for c=1,#collected do + collected[c].command = action + end + end +end + +local function sprint(root) + if root then + local tr = type(root) + if tr == "string" then -- can also be result of lpath + -- rawroot = false + lpegmatch(xmltextcapture,root) + elseif tr == "table" then + if forceraw then + rawroot = root + texwrite(xmltostring(root)) + else + xmlserialize(root,xmltexhandler) + end + end + end +end + +local function tprint(root) -- we can move sprint inline + local tr = type(root) + if tr == "table" then + local n = #root + if n == 0 then + -- skip + else + for i=1,n do + sprint(root[i]) + end + end + elseif tr == "string" then + lpegmatch(xmltextcapture,root) + end +end + +local function cprint(root) -- content + if not root then + -- rawroot = false + -- quit + elseif type(root) == 'string' then + -- rawroot = false + lpegmatch(xmltextcapture,root) + else + local rootdt = root.dt + if forceraw then + rawroot = root + texwrite(xmltostring(rootdt or root)) + else + xmlserialize(rootdt or root,xmltexhandler) + end + end +end + +xml.sprint = sprint local xmlsprint = sprint -- redo these names +xml.tprint = tprint local xmltprint = tprint +xml.cprint = cprint local xmlcprint = cprint + +-- now we can flush + +function lxml.main(id) + xmlserialize(get_id(id),xmltexhandler) -- the real root (@rt@) +end + +--~ -- lines (untested) +--~ +--~ local buffer = { } +--~ +--~ local xmllinescapture = ( +--~ newline^2 / function() buffer[#buffer+1] = "" end + +--~ newline / function() buffer[#buffer] = buffer[#buffer] .. " " end + +--~ content / function(s) buffer[#buffer] = buffer[#buffer] .. s end +--~ )^0 +--~ +--~ local xmllineshandler = table.copy(xmltexhandler) +--~ +--~ xmllineshandler.handle = function(...) lpegmatch(xmllinescapture,concat{ ... }) end +--~ +--~ function lines(root) +--~ if not root then +--~ -- rawroot = false +--~ -- quit +--~ elseif type(root) == 'string' then +--~ -- rawroot = false +--~ lpegmatch(xmllinescapture,root) +--~ elseif next(root) then -- tr == 'table' +--~ xmlserialize(root,xmllineshandler) +--~ end +--~ end +--~ +--~ function xml.lines(root) -- used at all? +--~ buffer = { "" } +--~ lines(root) +--~ return result +--~ end + +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 + +-- setups + +local setups = { } + +function lxml.set_command_to_text(id) + xmlwithelements(get_id(id),to_text) +end + +function lxml.set_command_to_none(id) + xmlwithelements(get_id(id),to_none) +end + +function lxml.installsetup(what,document,setup,where) + document = document or "*" + local sd = setups[document] + if not sd then sd = { } setups[document] = sd end + for k=1,#sd do + if sd[k] == setup then sd[k] = nil break end + end + if what == 1 then + if trace_loading then + commands.writestatus("lxml","prepending setup %s for %s",setup,document) + end + insert(sd,1,setup) + elseif what == 2 then + if trace_loading then + commands.writestatus("lxml","appending setup %s for %s",setup,document) + end + insert(sd,setup) + elseif what == 3 then + 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 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 +end + +function lxml.flushsetups(id,...) + local done, list = { }, { ... } + for i=1,#list do + local document = list[i] + local sd = setups[document] + if sd then + for k=1,#sd do + local v= sd[k] + if not done[v] then + if trace_loading then + commands.writestatus("lxml","applying setup %02i = %s to %s",k,v,document) + end + texsprint(ctxcatcodes,"\\xmlsetup{",id,"}{",v,"}") + done[v] = true + end + end + elseif trace_loading then + commands.writestatus("lxml","no setups for %s",document) + end + end +end + +function lxml.resetsetups(document) + if trace_loading then + commands.writestatus("lxml","resetting all setups for %s",document) + end + setups[document] = { } +end + +function lxml.removesetup(document,setup) + local s = setups[document] + if s then + for i=1,#s do + if s[i] == setup then + if trace_loading then + commands.writestatus("lxml","removing setup %s for %s",setup,document) + end + remove(t,i) + break + end + end + end +end + +function lxml.setsetup(id,pattern,setup) + if not setup or setup == "" or setup == "*" or setup == "-" or setup == "+" then + local collected = lxmlparseapply(id,pattern) + if collected then + if trace_setups then + for c=1, #collected do + local e = collected[c] + local ix = e.ix or 0 + if setup == "-" then + e.command = false + logs.report("lxml","lpath matched (a) %5i: %s = %s -> skipped",c,ix,setup) + elseif setup == "+" then + e.command = true + logs.report("lxml","lpath matched (b) %5i: %s = %s -> text",c,ix,setup) + else + local tg = e.tg + if tg then -- to be sure + e.command = tg + local ns = e.rn or e.ns + if ns == "" then + logs.report("lxml","lpath matched (c) %5i: %s = %s -> %s",c,ix,tg,tg) + else + logs.report("lxml","lpath matched (d) %5i: %s = %s:%s -> %s",c,ix,ns,tg,tg) + end + end + end + end + else + for c=1, #collected do + local e = collected[c] + if setup == "-" then + e.command = false + elseif setup == "+" then + e.command = true + else + e.command = e.tg + end + end + end + elseif trace_setups then + logs.report("lxml","no lpath matches for %s",pattern) + end + else + local a, b = match(setup,"^(.+:)([%*%-])$") + if a and b then + local collected = lxmlparseapply(id,pattern) + if collected then + if trace_setups then + for c=1, #collected do + local e = collected[c] + local ns, tg, ix = e.rn or e.ns, e.tg, e.ix or 0 + if b == "-" then + e.command = false + if ns == "" then + logs.report("lxml","lpath matched (e) %5i: %s = %s -> skipped",c,ix,tg) + else + logs.report("lxml","lpath matched (f) %5i: %s = %s:%s -> skipped",c,ix,ns,tg) + end + elseif b == "+" then + e.command = true + if ns == "" then + logs.report("lxml","lpath matched (g) %5i: %s = %s -> text",c,ix,tg) + else + logs.report("lxml","lpath matched (h) %5i: %s = %s:%s -> text",c,ix,ns,tg) + end + else + e.command = a .. tg + if ns == "" then + logs.report("lxml","lpath matched (i) %5i: %s = %s -> %s",c,ix,tg,e.command) + else + logs.report("lxml","lpath matched (j) %5i: %s = %s:%s -> %s",c,ix,ns,tg,e.command) + end + end + end + else + for c=1, #collected do + local e = collected[c] + if b == "-" then + e.command = false + elseif b == "+" then + e.command = true + else + e.command = a .. e.tg + end + end + end + elseif trace_setups then + logs.report("lxml","no lpath matches for %s",pattern) + end + else + local collected = lxmlparseapply(id,pattern) + if collected then + if trace_setups then + for c=1, #collected do + local e = collected[c] + e.command = setup + local ns, tg, ix = e.rn or e.ns, e.tg, e.ix or 0 + if ns == "" then + logs.report("lxml","lpath matched (k) %5i: %s = %s -> %s",c,ix,tg,setup) + else + logs.report("lxml","lpath matched (l) %5i: %s = %s:%s -> %s",c,ix,ns,tg,setup) + end + end + else + for c=1, #collected do + collected[c].command = setup + end + end + elseif trace_setups then + logs.report("lxml","no lpath matches for %s",pattern) + end + end + end +end + +-- finalizers + +local finalizers = xml.finalizers.tex + +local function first(collected) + if collected then + xmlsprint(collected[1]) + end +end + +local function last(collected) + if collected then + xmlsprint(collected[#collected]) + end +end + +local function all(collected) + if collected then + for c=1,#collected do + xmlsprint(collected[c]) + end + end +end + +local function reverse(collected) + if collected then + for c=#collected,1,-1 do + xmlsprint(collected[c]) + end + end +end + +local function count(collected) + texwrite((collected and #collected) or 0) +end + +local function position(collected,n) + -- todo: if not n then == match + if collected then + n = tonumber(n) or 0 + if n < 0 then + n = #collected + n + 1 + end + if n > 0 then + xmlsprint(collected[n]) + end + end +end + +local function match(collected) -- is match in preceding collected, never change, see bibxml + texwrite((collected and collected[1].mi) or 0) +end + +local function index(collected,n) + if collected then + n = tonumber(n) or 0 + if n < 0 then + n = #collected + n + 1 + end + if n > 0 then + texwrite(collected[n].ni or 0) + end + end +end + +local function command(collected,cmd) + if collected then + for c=1,#collected do + local e = collected[c] + local ix = e.ix + if not ix then + lxml.addindex(e.name,false,true) + ix = e.ix + end + texsprint(ctxcatcodes,"\\xmlw{",cmd,"}{",e.name,"::",ix,"}") + end + end +end + +local function attribute(collected,a,default) + if collected and #collected > 0 then + local at = collected[1].at + local str = (at and at[a]) or default + if str and str ~= "" then + texsprint(notcatcodes,str) + end + elseif default then + texsprint(notcatcodes,default) + end +end + +local function chainattribute(collected,arguments) -- todo: optional levels + if collected then + local e = collected[1] + while e do + local at = e.at + if at then + local a = at[arguments] + if a then + texsprint(notcatcodes,a) + end + else + break -- error + end + e = e.__p__ + end + end +end + +local function text(collected) + if collected then + local nc = #collected + if nc == 1 then -- hardly any gain so this will go + cprint(collected[1]) + else for c=1,nc do + cprint(collected[c]) + end end + end +end + +local function ctxtext(collected) + if collected then + for c=1,#collected do + texsprint(ctxcatcodes,collected[1].dt) + end + end +end + +local lowerchars, upperchars = characters.lower, characters.upper + +local function lower(collected) + if collected then + for c=1,#collected do + texsprint(ctxcatcodes,lowerchars(collected[1].dt[1])) + end + end +end + +local function upper(collected) + if collected then + for c=1,#collected do + texsprint(ctxcatcodes,upperchars(collected[1].dt[1])) + end + end +end + +local function number(collected) + if collected then + local n = 0 + for c=1,#collected do + n = n + tonumber(collected[c].dt[1] or 0) + end + texwrite(n) + end +end + +local function concatrange(collected,start,stop,separator,lastseparator,textonly) -- test this on mml + if collected then + local nofcollected = #collected + local separator = separator or "" + local lastseparator = lastseparator or separator or "" + start, stop = (start == "" and 1) or tonumber(start) or 1, (stop == "" and nofcollected) or tonumber(stop) or nofcollected + if stop < 0 then stop = nofcollected + stop end -- -1 == last-1 + for i=start,stop do + if textonly then + xmlcprint(collected[i]) + else + xmlsprint(collected[i]) + end + if i == nofcollected then + -- nothing + elseif i == nofcollected-1 and lastseparator ~= "" then + texsprint(ctxcatcodes,lastseparator) + elseif separator ~= "" then + texsprint(ctxcatcodes,separator) + end + end + end +end + +local function concat(collected,separator,lastseparator,textonly) -- test this on mml + concatrange(collected,false,false,separator,lastseparator,textonly) +end + +finalizers.first = first +finalizers.last = last +finalizers.all = all +finalizers.reverse = reverse +finalizers.count = count +finalizers.command = command +finalizers.attribute = attribute +finalizers.text = text +finalizers.lower = lower +finalizers.upper = upper +finalizers.ctxtext = ctxtext +finalizers.context = ctxtext +finalizers.position = position +finalizers.match = match +finalizers.index = index +finalizers.concat = concat +finalizers.concatrange = concatrange +finalizers.chainattribute = chainattribute +finalizers.default = all -- !! + +local concat = table.concat + +function finalizers.tag(collected) + if collected then + local c + if n == 0 or not n then + c = collected[1] + elseif n > 1 then + c = collected[n] + else + c = collected[#collected-n+1] + end + if c then + texsprint(c.tg) + end + end +end + +function finalizers.name(collected) + if collected then + local c + if n == 0 or not n then + c = collected[1] + elseif n > 1 then + c = collected[n] + else + c = collected[#collected-n+1] + end + if c then + if c.ns == "" then + texsprint(c.tg) + else + texsprint(c.ns,":",c.tg) + end + end + end +end + +function finalizers.tags(collected,nonamespace) + if collected then + for c=1,#collected do + local e = collected[c] + local ns, tg = e.ns, e.tg + if nonamespace or ns == "" then + texsprint(tg) + else + texsprint(ns,":",tg) + end + end + end +end + +-- + +local function verbatim(id,before,after) + local root = get_id(id) + if root then + if before then texsprint(ctxcatcodes,before,"[",root.tg or "?","]") end + lxml.toverbatim(xmltostring(root.dt)) + if after then texsprint(ctxcatcodes,after) end + end +end +function lxml.inlineverbatim(id) + verbatim(id,"\\startxmlinlineverbatim","\\stopxmlinlineverbatim") +end +function lxml.displayverbatim(id) + verbatim(id,"\\startxmldisplayverbatim","\\stopxmldisplayverbatim") +end + +lxml.verbatim = verbatim + +-- helpers + +function lxml.first(id,pattern) + local collected = lxmlparseapply(id,pattern) + if collected then + first(collected) + end +end + +function lxml.last(id,pattern) + local collected = lxmlparseapply(id,pattern) + if collected then + last(collected) + end +end + +function lxml.all(id,pattern) + local collected = lxmlparseapply(id,pattern) + if collected then + all(collected) + end +end + +function lxml.count(id,pattern) + -- always needs to produce a result so no test here + count(lxmlparseapply(id,pattern)) +end + +function lxml.attribute(id,pattern,a,default) + local collected = lxmlparseapply(id,pattern) + if collected then + attribute(collected,a,default) + end +end + +function lxml.raw(id,pattern) -- the content, untouched by commands + local collected = (pattern and lxmlparseapply(id,pattern)) or get_id(id) + if collected then + texsprint(xmltostring(collected[1].dt)) + end +end + +function lxml.context(id,pattern) -- the content, untouched by commands + if not pattern then + local collected = get_id(id) + -- texsprint(ctxcatcodes,collected.dt[1]) + ctx_text(collected.dt[1]) + else + local collected = lxmlparseapply(id,pattern) or get_id(id) + if collected and #collected > 0 then + texsprint(ctxcatcodes,collected[1].dt) + end + end +end + +function lxml.text(id,pattern) + local collected = (pattern and lxmlparseapply(id,pattern)) or get_id(id) + if collected then + text(collected) + end +end + +lxml.content = text + +function lxml.position(id,pattern,n) + local collected = lxmlparseapply(id,pattern) + if collected then + position(collected,n) + end +end + +function lxml.chainattribute(id,pattern,a,default) + local collected = lxmlparseapply(id,pattern) + if collected then + chainattribute(collected,a,default) + end +end + +function lxml.concatrange(id,pattern,start,stop,separator,lastseparator,textonly) -- test this on mml + concatrange(lxmlparseapply(id,pattern),start,stop,separator,lastseparator,textonly) +end + +function lxml.concat(id,pattern,separator,lastseparator,textonly) + concatrange(lxmlparseapply(id,pattern),false,false,separator,lastseparator,textonly) +end + +function lxml.element(id,n) + position(lxmlparseapply(id,"/*"),n) +end + +lxml.index = lxml.position + +function lxml.pos(id) + local root = get_id(id) + texwrite((root and root.ni) or 0) +end + +function lxml.att(id,a,default) + local root = get_id(id) + if root then + local at = root.at + local str = (at and at[a]) or default + if str and str ~= "" then + texsprint(notcatcodes,str) + end + elseif default then + texsprint(notcatcodes,default) + end +end + +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) + else + texsprint(r.tg) + end +end + +function lxml.match(id) -- or remapped name? -> lxml.info, combine + texsprint(get_id(id).mi or 0) +end + +function lxml.tag(id) -- tag vs name -> also in l-xml tag->name + texsprint(get_id(id).tg or "") +end + +function lxml.namespace(id) -- or remapped name? + local root = get_id(id) + texsprint(root.rn or root.ns or "") +end + +function lxml.flush(id) + id = get_id(id) + local dt = id and id.dt + if dt then + xmlsprint(dt) + end +end + +function lxml.snippet(id,i) + local e = get_id(id) + if e then + local edt = e.dt + if edt then + xmlsprint(edt[i]) + end + end +end + +function lxml.direct(id) + xmlsprint(get_id(id)) +end + +function lxml.command(id,pattern,cmd) + local i, p = get_id(id,true) + local collected = lxmlparseapply(i,pattern) + if collected then + local rootname = p or i.name + for c=1,#collected do + local e = collected[c] + local ix = e.ix + if not ix then + addindex(rootname,false,true) + ix = e.ix + end + texsprint(ctxcatcodes,"\\xmlw{",cmd,"}{",rootname,"::",ix,"}") + end + end +end + +-- loops + +function lxml.collected(id,pattern,reverse) + return xmlcollected(get_id(id),pattern,reverse) +end + +function lxml.elements(id,pattern,reverse) + return xmlelements(get_id(id),pattern,reverse) +end + +-- obscure ones + +lxml.info = lxml.name + +-- testers + +local found, empty = xml.found, xml.empty + +local doif, doifnot, doifelse = commands.doif, commands.doifnot, commands.doifelse + +function lxml.doif (id,pattern) doif (found(get_id(id),pattern)) end +function lxml.doifnot (id,pattern) doifnot (found(get_id(id),pattern)) end +function lxml.doifelse (id,pattern) doifelse(found(get_id(id),pattern)) end +function lxml.doiftext (id,pattern) doif (not empty(get_id(id),pattern)) end +function lxml.doifnottext (id,pattern) doifnot (not empty(get_id(id),pattern)) end +function lxml.doifelsetext (id,pattern) doifelse(not empty(get_id(id),pattern)) end + +-- special case: "*" and "" -> self else lpath lookup + +--~ function lxml.doifelseempty(id,pattern) doifelse(isempty(get_id(id),pattern ~= "" and pattern ~= nil)) end -- not yet done, pattern + +-- status info + +statistics.register("xml load time", function() + if noffiles > 0 or nofconverted > 0 then + return format("%s seconds, %s files, %s converted", statistics.elapsedtime(xml), noffiles, nofconverted) + else + return nil + end +end) + +statistics.register("lxml preparation time", function() + local calls, cached = xml.lpathcalls(), xml.lpathcached() + if calls > 0 or cached > 0 then + return format("%s seconds, %s nodes, %s lpath calls, %s cached calls", + statistics.elapsedtime(lxml), nofindices, calls, cached) + else + return nil + end +end) + +statistics.register("lxml lpath profile", function() + local p = xml.profiled + if p and next(p) then + local s = table.sortedkeys(p) + local tested, matched, finalized = 0, 0, 0 + texio.write_nl("log","\nbegin of lxml profile\n") + texio.write_nl("log","\n tested matched finalized pattern\n\n") + for i=1,#s do + local pattern = s[i] + local pp = p[pattern] + local t, m, f = pp.tested, pp.matched, pp.finalized + tested, matched, finalized = tested + t, matched + m, finalized + f + texio.write_nl("log",format("%9i %9i %9i %s",t,m,f,pattern)) + end + texio.write_nl("log","\nend of lxml profile\n") + return format("%s patterns, %s tested, %s matched, %s finalized (see log for details)",#s,tested,matched,finalized) + else + return nil + end +end) + +-- misc + +function lxml.nonspace(id,pattern) -- slow, todo loop + xmltprint(xmlcollect(get_id(id),pattern,true)) +end + +function lxml.strip(id,pattern,nolines,anywhere) + xml.strip(get_id(id),pattern,nolines,anywhere) +end + +function lxml.stripped(id,pattern,nolines) + local str = xmltext(get_id(id),pattern) or "" + str = gsub(str,"^%s*(.-)%s*$","%1") + if nolines then + str = gsub(str,"%s+"," ") + end + xmlsprint(str) +end + +function lxml.delete(id,pattern) + xml.delete(get_id(id),pattern) +end diff --git a/tex/context/base/lxml-xml.lua b/tex/context/base/lxml-xml.lua new file mode 100644 index 000000000..f791ec0f8 --- /dev/null +++ b/tex/context/base/lxml-xml.lua @@ -0,0 +1,288 @@ +if not modules then modules = { } end modules ['lxml-xml'] = { + 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 finalizers = xml.finalizers.xml +local xmlfilter = xml.filter -- we could inline this one for speed +local xmltostring = xml.tostring +local xmlserialize = xml.serialize + +local function first(collected) -- wrong ? + return collected and collected[1] +end + +local function last(collected) + return collected and collected[#collected] +end + +local function all(collected) + return collected +end + +local function reverse(collected) + if collected then + local reversed = { } + for c=#collected,1,-1 do + reversed[#reversed+1] = collected[c] + end + return reversed + end +end + +local function attribute(collected,name) + if collected and #collected > 0 then + local at = collected[1].at + return at and at[name] + end +end + +local function att(id,name) + local at = id.at + return at and at[name] +end + +local function count(collected) + return (collected and #collected) or 0 +end + +local function position(collected,n) + if collected then + n = tonumber(n) or 0 + if n < 0 then + return collected[#collected + n + 1] + elseif n > 0 then + return collected[n] + else + return collected[1].mi or 0 + end + end +end + +local function match(collected) + return (collected and collected[1].mi) or 0 -- match +end + +local function index(collected) + if collected then + return collected[1].ni + end +end + +local function attributes(collected,arguments) + if collected then + local at = collected[1].at + if arguments then + return at[arguments] + elseif next(at) then + return at -- all of them + end + end +end + +local function chainattribute(collected,arguments) -- todo: optional levels + if collected then + local e = collected[1] + while e do + local at = e.at + if at then + local a = at[arguments] + if a then + return a + end + else + break -- error + end + e = e.__p__ + end + end + return "" +end + +local function raw(collected) -- hybrid + if collected then + local e = collected[1] or collected + return (e and xmlserialize(e)) or "" -- only first as we cannot concat function + else + return "" + end +end + +local function text(collected) -- hybrid + if collected then + local e = collected[1] or collected + return (e and xmltostring(e.dt)) or "" + else + return "" + end +end + +local function texts(collected) + if collected then + local t = { } + for c=1,#collected do + local e = collection[c] + if e and e.dt then + t[#t+1] = e.dt + end + end + return t + end +end + +local function tag(collected,n) + if collected then + local c + if n == 0 or not n then + c = collected[1] + elseif n > 1 then + c = collected[n] + else + c = collected[#collected-n+1] + end + return c and c.tg + end +end + +local function name(collected,n) + if collected then + local c + if n == 0 or not n then + c = collected[1] + elseif n > 1 then + c = collected[n] + else + c = collected[#collected-n+1] + end + if c then + if c.ns == "" then + return c.tg + else + return c.ns .. ":" .. c.tg + end + end + end +end + +local function tags(collected,nonamespace) + if collected then + local t = { } + for c=1,#collected do + local e = collected[c] + local ns, tg = e.ns, e.tg + if nonamespace or ns == "" then + t[#t+1] = tg + else + t[#t+1] = ns .. ":" .. tg + end + end + return t + end +end + +local function empty(collected) + if collected then + for c=1,#collected do + local e = collected[c] + if e then + local edt = e.dt + if edt then + local n = #edt + if n == 1 then + local edk = edt[1] + local typ = type(edk) + if typ == "table" then + return false + elseif edk ~= "" then -- maybe an extra tester for spacing only + return false + end + elseif n > 1 then + return false + end + end + end + end + end + return true +end + +finalizers.first = first +finalizers.last = last +finalizers.all = all +finalizers.reverse = reverse +finalizers.elements = all +finalizers.default = all +finalizers.attribute = attribute +finalizers.att = att +finalizers.count = count +finalizers.position = position +finalizers.match = match +finalizers.index = index +finalizers.attributes = attributes +finalizers.chainattribute = chainattribute +finalizers.text = text +finalizers.texts = texts +finalizers.tag = tag +finalizers.name = name +finalizers.tags = tags +finalizers.empty = empty + +-- shortcuts -- we could support xmlfilter(id,pattern,first) + +function xml.first(id,pattern) + return first(xmlfilter(id,pattern)) +end + +function xml.last(id,pattern) + return last(xmlfilter(id,pattern)) +end + +function xml.count(id,pattern) + return count(xmlfilter(id,pattern)) +end + +function xml.attribute(id,pattern,a,default) + return attribute(xmlfilter(id,pattern),a,default) +end + +function xml.raw(id,pattern) + if pattern then + return raw(xmlfilter(id,pattern)) + else + return raw(id) + end +end + +function xml.text(id,pattern) + if pattern then + -- return text(xmlfilter(id,pattern)) + local collected = xmlfilter(id,pattern) + return (collected and xmltostring(collected[1].dt)) or "" + elseif id then + -- return text(id) + return xmltostring(id.dt) or "" + else + return "" + end +end + +xml.content = text + +function xml.position(id,pattern,n) -- element + return position(xmlfilter(id,pattern),n) +end + +function xml.match(id,pattern) -- number + return match(xmlfilter(id,pattern)) +end + +function xml.empty(id,pattern) + return empty(xmlfilter(id,pattern)) +end + +xml.all = xml.filter +xml.index = xml.position +xml.found = xml.filter diff --git a/tex/context/base/m-arabtex.tex b/tex/context/base/m-arabtex.tex new file mode 100644 index 000000000..61e56e93a --- /dev/null +++ b/tex/context/base/m-arabtex.tex @@ -0,0 +1,450 @@ +%D \module +%D [ file=m-arabtex, % was font-arb, +%D version=2003.02.22, % 1999.11.06, +%D title=\CONTEXT\ Modules, +%D subtitle=Arabic, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% I still need to hook in some features into the setup +% macro. I also have to (re)define farsi etc. in ways +% similar to arab, so that we have dedicated environments. +% +% keywords needed: vocalize transscribe +% +% \startarabic[option=vocalize] % or vocalize=yes +% ...... +% \stoparabic + +\writestatus{loading}{ConTeXt Font Macros / ArabTeX support} + +%D At the \NTG\ 10\high{th} anniversary meeting Klaus Lagally +%D introduced the audience to arabic typesetting, and after +%D that I knew that some day I really had to look into his +%D generic package. And then, sort of simultaniously Maarten +%D Wisse and Imran Ahsan Nyazee asked me if \CONTEXT\ could +%D support \ARABTEX, a package that provides right to left +%D typesetting of (several variants of) arab and hebrew. +%D Having implemented support for chinese a few weeks before, +%D I could not resist to build in support for arab and hebrew +%D too. Writing support for languages that don't give me any +%D cue on how to pronounce their script, is kind of special. + +%D This is a beta version, since I still have to take care of some +%D macros that conflict with existing stuff. + +\unprotect + +\definesystemvariable{ARABTEX} + +\def\setupARABTEX + {\getparameters[\??ARABTEX]} + +\setupARABTEX + [\s!rscale=1.2, + \c!before=, + \c!after=, + \c!inner=\setarab, + \c!style=\setarabicfont\fontstylesuffix] + +%D A few (maybe too) simple hooks into the font mechanism. The +%D hook into the language module is not yet done. + +% \unexpanded\def\setarabicfont#1% rscale +% {\scratchdimen\@@ARABTEXrscale\bodyfontsize +% \font\arbfont\truefontname{Arabic#1} at \currentfontscale\scratchdimen +% \setx@skels +% \newfonttrue +% \arbfont} +% +% more modern +% +% \unexpanded\def\setarabicfont#1% rscale +% {\definefont[arbfont][Arabic#1 sa \@@ARABTEXrscale]% +% \setx@skels +% \newfonttrue +% \arbfont} +% +% more efficient + +\unexpanded\def\setarabicfont#1% + {\setx@skels + \newfonttrue + \definedfont[Arabic#1 sa \ARABTEXparameter\s!rscale]} + +%D Just to be compatible with Arab\TEX\ we define: + +\unexpanded\def\nash {\setarabicfont\s!Regular} +\unexpanded\def\nashbf {\setarabicfont\s!Bold } +\unexpanded\def\pnash {\setarabicfont\s!Regular} +\unexpanded\def\pnashbf{\setarabicfont\s!Bold } +\unexpanded\def\xnash {\setarabicfont\s!Regular} +\unexpanded\def\xnashbf{\setarabicfont\s!Bold } + +%D The display arabic environment (will be an installable +%D object) uses a few conditionals. Let's do it the +%D \CONTEXT\ way and define an anvironment that we later can +%D adapt. + +\newif\if@ignore +\newif\if@endpe + +\def\setupARABTEXalternative[#1]% + {\dodoubleempty\getparameters[\??ARABTEX#1]} + +\def\defineARABTEXalternative + {\dodoubleempty\dodefineARABTEXalternative} + +\def\dodefineARABTEXalternative[#1][#2]% + {\iffirstargument % \startarab is defined but used already + \getparameters + [\??ARABTEX#1] + [\c!before=\@@ARABTEXbefore, + \c!after=\@@ARABTEXafter, + \c!inner=\@@ARABTEXinner, + \c!style=\@@ARABTEXstyle, + \s!rscale=\@@ARABTEXrscale, + #2]% + \setvalue {\e!start#1}{\displayARABTEXalternative{#1}}% + \unexpanded\setvalue{#1}{\inlineARABTEXalternative {#1}}% + \unexpanded\def\RL{\getvalue{#1}}% + \unexpanded\def\LR{\a@LR}% + \let\R=\RL + \let\L=\LR + \expandafter\all@wcmd\csname\e!stop#1\endcsname + \else + \defineARABTEXalternative[arabic]% + \fi} + +\def\initializeARABTEXinternals + {\ARABTEXparameter\c!inner + \the\everyARABTEXpreset} + +\newtoks \everyARABTEXpreset + +\let\currentARABTEXalternative\empty + +\def\ARABTEXparameter#1% + {\csname\??ARABTEX\currentARABTEXalternative#1\endcsname} + +\def\inlineARABTEXalternative#1#2% + {\bgroup + \edef\currentARABTEXalternative{#1}% + \initializeARABTEXinternals + \a@RL{#2}% + \egroup} + +\def\displayARABTEXalternative#1% + {\dodoubleempty\dostartARABTEXalternative[#1]} + +\def\dostartARABTEXalternative[#1][#2]% + {\begingroup + \edef\currentARABTEXalternative{#1}% + \getparameters[\??ARABTEX\currentARABTEXalternative][#2]% + \ifnum1<0\ARABTEXparameter\c!n\relax + \startcolumns + \else + \ARABTEXparameter\c!before + \fi + \initializeARABTEXinternals + \initializeARABTEXend + \arabtext + \initializeARABTEXalternative} + +\def\initializeARABTEXalternative + {\ARABTEXparameter\c!style} + +\def\initializeARABTEXend% \CONTEXT\ does use \end quite differently + {\long\def\end##1% + {\endarabtext + \ifnum1<0\ARABTEXparameter\c!n\relax + \stopcolumns + \else + \ARABTEXparameter\c!after + \fi + \endgroup}% + \let\a@l@end\end + \letvalue{\e!stop\currentARABTEXalternative}=\end + \long\def\end##1% + {\endarabtext + \endgroup + \if@ignore\global\@ignorefalse\expandafter\ignorespaces\fi}} + +%D Arabic verbatim. + +\def\typearab{\a@@verb} + +%D Some \LATEX\ macros. + +\def \makeatletter{\unprotect} +\def \makeatother {\protect} +\def \typeout {\writestatus{arabtex}} + +%D We have to save some macros. + +\let\ARABTEXversion=\empty + +\def\startloadingARABTEX% ugly hacks + {\catcode`!=12 + \catcode`?=12 + \pushmacro\output \let \output \scratchtoks + \pushmacro\LaTeX \let \LaTeX \undefined + \pushmacro\CJK \let \CJK \undefined +% \pushmacro\peek@token \let \peek@token \undefined +% \pushmacro\edmacloaded \let \edmacloaded \undefined + \pushmacro\year \let \year \normalyear + \pushmacro\month \let \month \normalmonth + \pushmacro\day \let \day \normalday + \pushmacro\input \def \input ##1 {\normalinput ##1 } + \pushmacro\linewidth + \pushmacro\datum \def\datum {\toks0} + \pushmacro\version \def\version {\toks2} + \pushmacro\theversion \let\theversion \ARABTEXversion + \pushmacro\emphasize + \pushmacro\cap} + +\def\stoploadingARABTEX + {\catcode`!=11 + \catcode`?=11 + \popmacro\cap + \popmacro\emphasize + \popmacro\theversion + \popmacro\version + \popmacro\datum + \popmacro\linewidth + \popmacro\input + \popmacro\day + \popmacro\month + \popmacro\year +% \popmacro\edmacloaded +% \popmacro\peek@token + \popmacro\CJK + \popmacro\LaTeX + \popmacro\output} + +%D We save some macros: + +\startloadingARABTEX + +%D When loading \ARABTEX\ we have to set back the~! and~?. + +\input arabtex.sty + +%D Since \ARABTEX\ has its own \type {\cap}, we save the +%D new meaning. We also redefine some \PLAIN\ macros, which +%D happen to have a different meaning in \LATEX. + +\let\ARABTEXversion\theversion +\let\ARABTEXcap \cap + +\appendtoks + \let\cap\ARABTEXcap +\to \everyARABTEXpreset + +\def\ARABTEXsh@ft#1% + {\dimen@.00#1ex + \multiply\dimen@\slantperpoint + \kern-.0156\dimen@} + +\appendtoks + \let\sh@ft\ARABTEXsh@ft +\to \everyARABTEXpreset + +\def\ARABTEXd#1% + {{\o@lign{\relax#1\crcr\hidewidth\sh@ft{10}% + .\hidewidth}}} + +\def\ARABTEXb#1% + {{\o@lign{\relax#1\crcr\hidewidth\sh@ft{29}% + \vbox to.2ex{\hbox{\char22}\vss}\hidewidth}}} + +\appendtoks + \let\b\ARABTEXb + \let\d\ARABTEXd +\to \everyARABTEXpreset + +\def \ARABTEXbreakA {\hfill\break} +\def \ARABTEXbreakB {\break} +\edef\ARABTEXbar {\string|} +\def \ARABTEXcomma {\relax\ifmmode\mskip\thinmuskip\else\thinspace\fi} + +\appendtoks + \let\\=\ARABTEXbreakA + \let\|=\ARABTEXbreakB + \let |=\ARABTEXbar + \let\,=\ARABTEXcomma +\to \everyARABTEXpreset + +\let\ARABTEXprotect\relax + +\appendtoks + \let\protect\ARABTEXprotect +\to \everyARABTEXpreset + +%D Now we can pop the saved macros. + +\stoploadingARABTEX + +%D Ah, we have to get rid of some \type {\protect} stuff but +%D to permit testing we add it in the \CONTEXT\ way. + +% \bgroup +% \catcode`\<=\@other +% \unexpanded\gdef\a@ins +% {\ifmmode +% \expandafter<% +% \else +% \dontleavehmode \bgroup +% \arab@codes \set@arabfont \@waslafalse \@wasfalse +% \expandafter\arab@insert +% \fi} +% \unexpanded\gdef\<{\a@ins} +% \catcode`\<=\active +% \global\let<=\a@ins +% \egroup +% +% cleaner: + +\defineactivecharacter < {\a@ins} \unexpanded\gdef\<{\a@ins}% + +\def\normal@a@ins + {\dontleavehmode % context prefers this instead of \leavevmode + \bgroup + \arab@codes + \set@arabfont + \@waslafalse + \@wasfalse + \arab@insert} + +\unexpanded\gdef\a@ins + {\mathortext<\normal@a@ins} + +%D We also need to register a few macros: + +\all@wcmd\initializeARABTEXalternative % no argument, internal command +\all@wcmd\tx % no argument, small font +\all@wcmd\txx % no argument, smaller font + +%D We also hook it into the presetter. + +\appendtoks + \let\normaltx \tx \def\tx {\normaltx \setarabicfont\fontstylesuffix}% + \let\normaltxx\txx\def\txx{\normaltxx\setarabicfont\fontstylesuffix}% +\to \everyARABTEXpreset + +%D The main definitions are: + +\definefontsynonym [ArabicRegular] [xnsh14] +\definefontsynonym [ArabicBold] [xnsh14bf] + +\defineARABTEXalternative + [arabic] + [\c!inner=\setarab, + \c!style=\setarabicfont\fontstylesuffix] + +\defineARABTEXalternative + [farsi] + [\c!inner=\setfarsi, + \c!style=\setarabicfont\fontstylesuffix] + +\defineARABTEXalternative + [urdu] + [\c!inner=\seturdu, + \c!style=\setarabicfont\fontstylesuffix] + +\defineARABTEXalternative + [maghribi] + [\c!inner=\setmaghribi, + \c!style=\setarabicfont\fontstylesuffix] + +%D Apart from such definitions, one can adapt the settings +%D using \type {\setupARABTEXalternative}. +%D +%D A few years ago at the Holland Festivities, I attended {\em +%D The Cave}, one of the most impressive combinations of music +%D and video I know. This composition of Steve Reich (music) +%D and .. (video) concentrates on the common grounds of arabs +%D and jews: their ancestor Abram. Listening to the \CDROM's +%D of {\em The Cave}, provided me the right ambiance for +%D filling in the details of this module. In {\em The Cave}, +%D interviews, music, and |<|believe it or not|>| rhythmic +%D typography are the cornerstones. Remembering those big +%D screens, it strikes me that like music, \TEX\ too is a +%D perfect instrument to cross cultural and linguistic +%D borders. So, let's load Hebrew support as well: + +\unexpanded\def\sethebrewfont#1% + {\setx@skels + \newfonttrue + \definedfont[Hebrew#1 sa \ARABTEXparameter\s!rscale]} + +% \let \setheb \sethebrew + +\unexpanded\def\pheb {\sethebrewfont\s!Regular} +\unexpanded\def\phebbf{\sethebrewfont\s!Bold} + +% \startloadingARABTEX + +% \ReadFile{hebtex.sty} +% \ReadFile{apatch.sty} +% \ReadFile{hepatch.sty} + +% \stoploadingARABTEX + +\definefontsynonym [HebrewRegular] [hclassic] +\definefontsynonym [HebrewBold] [hcaption] + +\defineARABTEXalternative + [hebrew] + [\c!inner=\sethebrew, + \c!style=\sethebrewfont\fontstylesuffix] + +%D Now we're done: + +\protect \endinput + +% everyoutput : \charsubdefmax \arab@charsubdefmax + +% \defineconversion [abjad] [\abj@d] +% +% voetnoten verbatim lijsten indexen tabellen uitlijnen +% +% \v!hoofdstuk=al-fa.slu +% \v!inhoud=al-mu.htawayAtu +% \v!figuren=qA'imaTu al-.suwaru +% \v!tabellen=qA'imaTu al-^gadAwilu +% \v!grafieken=qA'imaTu al-rusUmu +% \v!index=al-fihrisu +% \v!bijlage=al-mul.haqu + +% \usemodule[arabtex] +% +% \usetypescript[postscript] \switchtotypeface[postscript] +% +% \setarab \novocalize +% +% \starttext +% +% \placecontent +% +% \section{\} % short arabic use \< .. > +% \section{\} % short arabic use \< .. > +% +% \startarabic +% mu.hammad 'i_d q"aAm zay"d" + i_d yaqUm zyd + A_d zyd q"aAm +% +% mu.hammad 'i_d q"aAm zay"d" + i_d yaqUm zyd + A_d zyd q"aAm +% \stoparabic +% +% \section{\} +% +% \startarabic +% mu.hammad 'i_d q"aAm zay"d" + i_d yaqUm zyd + A_d zyd q"aAm +% \stoparabic +% +% \stoptext diff --git a/tex/context/base/m-barcodes.mkiv b/tex/context/base/m-barcodes.mkiv new file mode 100644 index 000000000..b0eae1485 --- /dev/null +++ b/tex/context/base/m-barcodes.mkiv @@ -0,0 +1,122 @@ +%D \module +%D [ file=m-pstricks, +%D version=2010.03.14, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Barcodes, +%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. + +% \startTEXpage +% \startPSTRICKS +% \pspicture(-4mm,-1mm)(38mm,26mm) +% \psbarcode{9781860742712}{includetext guardwhitespace}{ean13}% +% \endpspicture +% \stopPSTRICKS +% \stopTEXpage + +% 978-94-90688-01-1 +% +% 978 = ean isbn identifier (979 also) +% 94 = country code +% 90688 = publisher code +% 01 = title 1 +% 1 = checksum + +\usemodule[pstricks] + +\usePSTRICKSmodule[pst-barcode] + +\definefont[barcodefont][file:ocrb10] +% \definefont[barcodefont][file:texgyreheros-regular] + +\startluacode +plugins.barcodes = { } + +local function split(code) + local t = { string.byte(code,1,#code) } + if #t >= 12 then + local s = 0 + for i=1,11,2 do + s = s + (t[i]-48) + end + for i=2,12,2 do + s = s + 3 * (t[i]-48) + end + local m = s % 10 + local c = (m > 0 and (10 - m)) or 0 + return t, s, m, c + end +end + +function plugins.barcodes.isbn_1(original) + local code = string.gsub(original,"%-","") + local t, s, m, c = split(code) + if t then + if #t == 13 then + local e = ((c == t[13] - 48) and "correct") or "wrong" + logs.report("isbn code","code=%s, sum=%s, checksum=%s, modulo=%s, status=%s",original,s,m,c,e) + else + logs.report("isbn code","code=%s, sum=%s, checksum=%s, modulo=%s",original,s,m,c) + code= code .. c + end + end + tex.sprint(code) +end + +function plugins.barcodes.isbn_2(original) + local code = string.gsub(original,"%-","") + local t, s, m, c = split(code) + if t and #t == 12 then + original = original .. "-" .. c + end + tex.sprint(original) +end +\stopluacode + +\startsetups barcode:isbn + \scale + [width=5cm] + { + \vbox { + \hbox { + \hskip3.7mm + \scale[width=34mm]{\barcodefont ISBN \ctxlua{plugins.barcodes.isbn_2("\getvariable{barcode}{code}")}} + } + \par + \normalexpanded { \noexpand \setPSTRICKS { + \noexpand \pspicture(-4mm,-1mm)(38mm,26mm) + \noexpand \psbarcode { + \ctxlua{plugins.barcodes.isbn_1("\getvariable{barcode}{code}")} + } { + includetext guardwhitespace + } { + ean13 + } + \noexpand \endpspicture + } + \noexpand \processPSTRICKS } + } + } +\stopsetups + +\def\barcode[#1]% + {\bgroup + \setvariables[barcode][type=isbn,#1]% + \directsetup{barcode:\getvariable{barcode}{type}}% + \egroup} + +% \usemodule[barcodes] +% +% \starttext +% \startTEXpage +% \barcode[type=isbn,code=978-94-90688-01-1] +% \stopTEXpage +% \stoptext + +\endinput + diff --git a/tex/context/base/m-chart.mkii b/tex/context/base/m-chart.mkii new file mode 100644 index 000000000..2554fa2d4 --- /dev/null +++ b/tex/context/base/m-chart.mkii @@ -0,0 +1,48 @@ +%D \module +%D [ file=m-chart, +%D version=1998.10.10, +%D title=\CONTEXT\ Modules, +%D subtitle=Flow Charts, +%D author={Hans Hagen \& Ton Otten}, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D The \XML\ interface: + +\unprotect + +\startXMLdefinitions flowchart + +\defineXMLargument [flowchartdefinition] + {\defineFLOWchart[\XMLpar{flowchartdefinition}{identifier}{unknown}]} + +\defineXMLpickup [flowcell] + {\startFLOWcell + \defineXMLargument[name]{\unspaceafter\name}% + \defineXMLargument[shape]{\unspaceafter\shape}% + \defineXMLnestedargument[text]{\text}} + {\stopFLOWcell} + +\defineXMLenvironment [location] % global unspace/store + {\bgroup\defineXMLpush[x]\defineXMLpush[y]} + {\XMLunspace{x}\XMLunspace{y}% + \expanded{\egroup\noexpand\location{\XMLpop{x},\XMLpop{y}}}} + +\defineXMLenvironment [connection] + {\bgroup\defineXMLpush[type]\defineXMLpush[name]}% + {\XMLunspace{type}\XMLunspace{name}% + \expanded{\egroup\noexpand\connection[\XMLpop{type}]{\XMLpop{name}}}} + +\defineXMLsingular [flowchart] + {\expanded{\FLOWchart[\XMLpar{flowchart}{identifier}{unknown}]}} + +\defineXMLdirective [flowchart] [shapes] \setupFLOWshapes +\defineXMLdirective [flowchart] [lines] \setupFLOWlines + +\stopXMLdefinitions + +\protect \endinput diff --git a/tex/context/base/m-chart.mkiv b/tex/context/base/m-chart.mkiv new file mode 100644 index 000000000..4c008a5ee --- /dev/null +++ b/tex/context/base/m-chart.mkiv @@ -0,0 +1,20 @@ +%D \module +%D [ file=m-chart, +%D version=1998.10.10, +%D title=\CONTEXT\ Modules, +%D subtitle=Flow Charts, +%D author={Hans Hagen \& Ton Otten}, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D The \XML\ interface: + +\unprotect + +\writestatus\m!systems{The chart mkiv xml interface is not yet defined!} + +\protect \endinput diff --git a/tex/context/base/m-chart.tex b/tex/context/base/m-chart.tex new file mode 100644 index 000000000..5ccf4c2ad --- /dev/null +++ b/tex/context/base/m-chart.tex @@ -0,0 +1,1285 @@ +%D \module +%D [ file=m-chart, +%D version=1998.10.10, +%D title=\CONTEXT\ Modules, +%D subtitle=Flow Charts, +%D author={Hans Hagen \& Ton Otten}, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% todo: \localpushmacro/\localpopmacro (dohandleflowchart etc) +% todo: make mkiv variant +% todo: use dimexpr/numspr + +% will be redone with layers and dimexpr or even better, by just using +% textext .. a nice example of old code + +%D This is an experimental module. Pieces of code will be moved +%D to other modules. More features are possible but will be +%D interfaces later. +%D +%D When finished this module will be documented. The main macro +%D is still a rather big one and there is some redundant and +%D slow code that needs a clean up. + +% arrow, dash +% crossing +% \goto -> \normalgoto +% class -> class:name (ref prefix) +% c, automatisch geen overlap zoeken +% eind eerder chart connecties +% relateren aan korps +% check op bestaan naam, bestaan shape +% auto als extern figuur +% subchart +% pijlen +% focus +% ook nog \MPmessage +% areapath -> krappe vlak +% clippath -> gehele vlak +% +% offset : clip offset +% breedte : breedte cel +% hoogte : hoogte cel +% dx : halve afstand in breedte (grid breedte = breedte + 2dx) +% dy : halve afstand in hoogte (grid hoogte = hoogte + 2dy) +% x : x offset (clipping) +% y : y offset (clipping) +% nx : minimaal aantal cellen horizontaal +% ny : minimaal aantal cellen vertikaal +% +% shape none en geen equivalent maken +% +% kaderkleur achtergrondkleur +% lijnkleur lijndikte +% focus focuskaderkleur focusachtergrondkleur +% richting +% +% focus koppelen aan kleur + +\unprotect + +\definesorting [flowchart] [flowcharts] [\v!none] % no access +\setupsorting [flowchart] [\c!state=\v!stop] % off by default + +\def\@FLOW@{@FLOW@} +\def\@FLOC@{@FLOC@} +\def\@FLOX@{@FLOX@} + +\def\@@FLOW{@@FLOW} +\def\@@FLOL{@@FLOL} +\def\@@FLOS{@@FLOS} +\def\@@FLOF{@@FLOF} +\def\@@FLOT{@@FLOT} +\def\@@FLOX{@@FLOX} + +\def\@@MPx {@@MPx} +\def\@@MPy {@@MPy} + +\def\FLOWbufferprefix{flw-} + +\def\processFLOWbuffer#1{\getbuffer[\FLOWbufferprefix#1]} +\def\typeFLOWbuffer #1{\typebuffer[\FLOWbufferprefix#1]} + +\def\setFLOWname#1#2% funny hack that makes sure that we get + {\bgroup % names that are acceptable for METAPOST + \lccode`0=`a\lccode`1=`b\lccode`2=`c\lccode`3=`d\lccode`4=`e% + \lccode`5=`f\lccode`6=`g\lccode`7=`h\lccode`8=`i\lccode`9=`j% + \lccode` =`\_\lccode`-=`\_\lccode`_=`\_% + \lowercase{\gdef#1{#2}}% + \egroup} + +% een gobble als default is sneller, en dan alleen setten als +% nodig + +\def\resetFLOWcell + {% variables + \global\let\FLOWname \empty + \global\let\FLOWalign \empty + \global\let\FLOWshape \empty + \global\let\FLOWlocation \empty + \global\let\FLOWtext \empty + \global\let\FLOWhelp \empty + \global\let\FLOWdestination\empty + \global\let\FLOWoverlay \empty + \global\let\FLOWfocus \empty + \global\let\tFLOWlabel \empty + \global\let\bFLOWlabel \empty + \global\let\lFLOWlabel \empty + \global\let\rFLOWlabel \empty + \global\let\bcFLOWlabel \empty + \global\let\tcFLOWlabel \empty + \global\let\lcFLOWlabel \empty + \global\let\rcFLOWlabel \empty + \global\let\tFLOWexit \empty + \global\let\bFLOWexit \empty + \global\let\lFLOWexit \empty + \global\let\rFLOWexit \empty + % commands + \let\name \doFLOWname + \let\shape \doFLOWshape + \let\destination\doFLOWdestination + \let\location \doFLOWlocation + \let\focus \doFLOWfocus + \let\overlay \doFLOWoverlay + \let\figure \doFLOWfigure + \let\text \doFLOWtext + \let\comment \doFLOWcomment + \let\label \doFLOWlabel + \let\help \doFLOWhelp + \let\connection \doFLOWconnection + \let\exit \doFLOWexit + % convenience commands + \let\locate \doFLOWlocate + \let\connect \doFLOWconnect} + +\let\FLOWcell \s!unknown +\let\FLOWshape \s!unknown +\let\FLOWdestination\s!unknown +\let\FLOWfocus \s!unknown +\let\FLOWoverlay \empty +\let\FLOWtext \empty + +\def\doFLOWname#1% + {\def\FLOWcell{#1}\setFLOWname\FLOWname{name_#1}\ignorespaces} + +\def\doFLOWshape#1% + {\gdef\FLOWshape{#1}\ignorespaces} + +\def\doFLOWdestination#1% + {\gdef\FLOWdestination{#1}\ignorespaces} + +\def\doFLOWlocation#1% + {\setFLOWlocation#1\end\ignorespaces} + +\def\doFLOWfocus#1% + {\gdef\FLOWfocus{#1}\ignorespaces} + +\def\doFLOWoverlay#1% + {\gdef\FLOWoverlay{#1}\ignorespaces} + +\def\doFLOWfigure#1% + {\defineoverlay[\s!dummy][\overlayfigure{#1}]% + \overlay\s!dummy} + +\def\doFLOWtext + {\dosingleempty\dodoFLOWtext} + +\def\dodoFLOWtext[#1]% % #2% + {\gdef\FLOWalign{#1}\gdef\FLOWtext}% {#2}} + +\def\doFLOWcomment[#1]#2% + {\ignorespaces\dogobblesingleempty} + +\def\doFLOWlabel[#1]#2% wordt dit gebruikt ? + {\setgvalue{#1FLOWlabel}{#2}\ignorespaces} + +\def\doFLOWhelp#1% + {\gdef\FLOWhelp{#1}\ignorespaces} + +\def\doFLOWconnection + {\dodoubleempty\dodoFLOWconnection} + +\def\dodoFLOWconnection[#1][#2]#3% + {\ignorespaces} + +\def\doFLOWconnect + {\connection} + +\def\doFLOWlocate + {\location} + +\def\doFLOWexit[#1]#2% + {\setgvalue{#1FLOWexit}{#2}\ignorespaces} + +\def\startFLOWchart + {\bgroup + \let\stopFLOWchart\egroup + \obeylines % lelijk, buffers nog eens fatsoeneren + \dodoubleempty\dostartFLOWchart} + +\def\dostartFLOWchart[#1][#2]% + {\preparenextFLOWchart{#1}{#2}% + \dostartbuffer[\FLOWbufferprefix\nofFLOWcharts][startFLOWchart][stopFLOWchart]} + +\def\defineFLOWchart% + {\dodoubleempty\dodefineFLOWchart} + +\long\def\dodefineFLOWchart[#1][#2]#3% + {\preparenextFLOWchart{#1}{#2}% + \setbuffer[\FLOWbufferprefix\nofFLOWcharts]#3\endbuffer} + +\def\preparenextFLOWchart#1#2% + {\doglobal\increment\nofFLOWcharts + \flowchart{#1}% + \setxvalue{\@FLOW@-#1}{\noexpand\dohandleflowchart[\nofFLOWcharts][#2]}} + +\def\setupFLOWcharts{\dodoubleargument\getparameters[\@@FLOW]} +\def\setupFLOWlines {\dodoubleargument\getparameters[\@@FLOL]} +\def\setupFLOWshapes{\dodoubleargument\getparameters[\@@FLOS]} +\def\setupFLOWfocus {\dodoubleargument\getparameters[\@@FLOF]} +\def\setupFLOWsets {\dodoubleargument\getparameters[\@@FLOX]} + +\setupFLOWcharts + [\c!option=, + \c!bodyfont=, + \c!dot=, % private option + \c!width=12\bodyfontsize, + \c!height=7\bodyfontsize, + \c!maxwidth=, + \c!maxheight=, + \c!offset=\v!standard, % == auto offset + \c!dx=2\bodyfontsize, + \c!dy=2\bodyfontsize, + \c!nx=0, % 1, + \c!ny=0, % 1, + \c!x=1, + \c!y=1, + \c!autofocus=, + \c!focus=, + \c!background=, % \v!color, + \c!backgroundcolor=\s!white, + \c!rulethickness=\linewidth, + \c!frame=\v!off, + \c!framecolor=] + +\setupFLOWlines + [\c!corner=\v!round, + \c!arrow=\v!yes, + \c!dash=\v!no, + \c!radius=.375\bodyfontsize, % 2.5\c!rulethickness + \c!color=FLOWlinecolor, + \c!rulethickness=.15\bodyfontsize, % 2pt, + \c!offset=\v!none] + +\setupFLOWshapes + [\c!default=action, + \c!framecolor=FLOWframecolor, + \c!background=\v!color, + \c!backgroundcolor=FLOWbackgroundcolor, + \c!backgroundscreen=\@@rsscreen, + \c!rulethickness=.15\bodyfontsize, % 2pt, + \c!offset=.5\bodyfontsize] + +\setupFLOWfocus + [\c!framecolor=FLOWfocuscolor, + \c!background=\@@FLOSbackground, + \c!backgroundcolor=\@@FLOSbackgroundcolor, + \c!backgroundscreen=\@@FLOSbackgroundscreen, + \c!rulethickness=\@@FLOSrulethickness, + \c!offset=\@@FLOSoffset] + +\definecolor [FLOWfocuscolor] [s=.2] +\definecolor [FLOWlinecolor] [s=.5] +\definecolor [FLOWframecolor] [s=.7] +\definecolor [FLOWbackgroundcolor] [s=.9] + +\newcounter\includeFLOWx +\newcounter\includeFLOWy + +\def\includeFLOWchart + {\dodoubleempty\doincludeFLOWchart} + +\def\doincludeFLOWchart[#1][#2]% + {\pushmacro\includeFLOWx + \pushmacro\includeFLOWy + \getparameters[FLOWi][x=1,y=1,#2]% + \increment(\includeFLOWx,0\FLOWix)\decrement\includeFLOWx + \increment(\includeFLOWy,0\FLOWiy)\decrement\includeFLOWy + \def\dodoincludeFLOWchart##1% + {\doifdefined{\@FLOW@-##1} + {\globalpushmacro\dohandleflowchart % was local + \gdef\dohandleflowchart[####1][####2]% + {\globalpopmacro\dohandleflowchart % was local + \resetFLOWlocation + \processFLOWbuffer{####1}}% + \getvalue{\@FLOW@-##1}}}% + \processcommalist[#1]\dodoincludeFLOWchart + \popmacro\includeFLOWx + \popmacro\includeFLOWy} + +\def\resetFLOWlocation + {\globallet\lastFLOWx\!!zerocount + \globallet\lastFLOWy\!!zerocount} + +\def\dosetFLOWlocation[#1#2]#3#4% + {\processaction + [#1#2] + [ +=>\scratchcounter\numexpr#4+ 1+#3\relax, + -=>\scratchcounter\numexpr#4- 1+#3\relax, + +#2=>\scratchcounter\numexpr#4+#2+#3\relax, + -#2=>\scratchcounter\numexpr#4-#2+#3\relax, + \s!default=>\scratchcounter\numexpr#4 +#3\relax, + \s!unknown=>\scratchcounter\numexpr0#1#2+#3\relax]% + \xdef#4{\the\scratchcounter}} + +\def\setFLOWlocation#1,#2\end + {\dosetFLOWlocation[#1\empty]\includeFLOWx\lastFLOWx + \dosetFLOWlocation[#2\empty]\includeFLOWy\lastFLOWy + \xdef\FLOWlocation{\lastFLOWx,\lastFLOWy}} + +\def\FLOWshapes + {node, action, procedure, product, decision, archive, + loop, wait, subprocedure, singledocument, multidocument, + sub procedure, single document, multi document, up, down, + left, right} + +\def\FLOWlines + {up, down, left, right} + +\def\FLOWsetconnect#1% + {\donefalse + \let\cFLOWfrom\empty + \let\cFLOWto\empty + \let\zFLOWfrom\!!zerocount + \let\zFLOWto\!!zerocount + \handletokens#1\with\doFLOWsetconnect + \ifx\cFLOWto\empty\let\cFLOWfrom\empty\fi} + +\def\doFLOWsetconnect#1% + {\ifx #1p% + \ifdone\def\zFLOWto{+1}\else\def\zFLOWfrom{+1}\fi + \else\ifx#1+% + \ifdone\def\zFLOWto{+1}\else\def\zFLOWfrom{+1}\fi + \else\ifx#1n% + \ifdone\def\zFLOWto{-1}\else\def\zFLOWfrom{-1}\fi + \else\ifx#1-% + \ifdone\def\zFLOWto{-1}\else\def\zFLOWfrom{-1}\fi + \else\ifdone + \edef\cFLOWto{\FLOWconnector#1}% + \else + \edef\cFLOWfrom{\FLOWconnector#1}% + \donetrue + \fi\fi\fi\fi\fi} + +\def\FLOWconnector#1% + {\if#1bbottom\else\if#1ttop\else\if#1lleft\else\if#1rright\fi\fi\fi\fi} + +\newif\ifFLOWscaling \FLOWscalingtrue + +\def\@@FLOW@@offset{\@@FLOWoffset} + +\def\getFLOWchart + {\dodoubleempty\dogetFLOWchart} + +\def\dogetFLOWchart[#1][#2]% + {\doifundefinedelse{\@FLOW@-#1} + {\writestatus{FLOW}{unknown chart #1}% + \framed + [\c!width=12\bodyfontsize,\c!height=8\bodyfontsize] + {\tttf [chart #1]}} + {\dodogetFLOWchart[#1][#2]}} + +\def\dodogetFLOWchart[#1][#2]% to be split a bit more + {\vbox\bgroup + \insidefloattrue + \forgetall + \dontcomplain + % \offinterlineskip % we now explicitly use \nointerlineskip later on + \def\dohandleflowchart[##1][##2]% + {\def\currentFLOWnumber{##1}% + \getparameters[\@@FLOW][##2]}% + \getvalue{\@FLOW@-#1}% + \getparameters[\@@FLOW][#2]% dubbelop ? + \doifsomething{\@@FLOWautofocus} + {\checkFLOWautofocus}% + %\message{AUTOSHAPE 3: (\@@FLOWx,\@@FLOWy)->(\@@FLOWnx,\@@FLOWny)}\wait + \global\let\FLOWwidth \@@FLOWnx + \global\let\FLOWheight\@@FLOWny + \let\startFLOWcell\startFLOWcellA + \resetFLOWlocation + \processFLOWbuffer\currentFLOWnumber + \ifcase\@@FLOWnx\relax \let\@@FLOWnx\FLOWwidth \fi + \ifcase\@@FLOWny\relax \let\@@FLOWny\FLOWheight \fi + \doifnothing{\@@FLOWmaxwidth\@@FLOWmaxheight}{\FLOWscalingfalse}% + \ifFLOWscaling + \doifnothing{\@@FLOWmaxwidth }{\let\@@FLOWmaxwidth \maxdimen}% + \doifnothing{\@@FLOWmaxheight}{\let\@@FLOWmaxheight\maxdimen}% + \scratchcounter\bodyfontpoints + \doloop % NOG FONTSWITCH OM EX EN EM TE LATEN WERKEN + {\ifnum\scratchcounter>1 % NU DIMENSIONS IN TERMS OF BODYFONTSIZE + \bodyfontsize=\the\scratchcounter pt + \dimen0=\@@FLOWmaxwidth + \dimen2=\@@FLOWwidth + \dimen4=\@@FLOWdx + \advance\dimen2 2\dimen4 + \dimen2=\@@FLOWnx\dimen2 + \advance\dimen2 2\dimen4 + \ifdim\dimen2>\dimen0 + \advance\scratchcounter \minusone + \else + \dimen0=\@@FLOWmaxheight + \dimen2=\@@FLOWheight + \dimen4=\@@FLOWdy + \advance\dimen2 2\dimen4 + \dimen2=\@@FLOWny\dimen2 + \advance\dimen2 2\dimen4 + \ifdim\dimen2>\dimen0 + \advance\scratchcounter \minusone + \else + \exitloop + \fi + \fi + \else + \exitloop + \fi}% + \expanded{\switchtobodyfont[\the\scratchcounter pt]}% + \forgetall + % \offinterlineskip % needed ? + \else\ifx\@@FLOWbodyfont\empty\else + \expanded{\switchtobodyfont[\@@FLOWbodyfont]}% \expanded ? + \fi\fi + \global\let\FLOWcells\empty + \dimen0=\@@FLOWwidth + \edef\FLOWshapewidth{\the\dimen0}% + \dimen2=\@@FLOWdx + \advance\dimen0 2\dimen2 + \edef\FLOWgridwidth{\the\dimen0}% + \dimen0=\@@FLOWheight + \edef\FLOWshapeheight{\the\dimen0}% + \dimen2=\@@FLOWdy + \advance\dimen0 2\dimen2 + \edef\FLOWgridheight{\the\dimen0}% + \scratchdimen=\@@FLOSrulethickness + \edef\@@FLOSrulethickness{\the\scratchdimen}% + \scratchdimen=\@@FLOFrulethickness + \edef\@@FLOFrulethickness{\the\scratchdimen}% + \scratchdimen=\@@FLOLrulethickness + \edef\@@FLOLrulethickness{\the\scratchdimen}% + \ifdim\@@FLOLradius<2.5\scratchdimen + \scratchdimen=2.5\scratchdimen + \edef\@@FLOLradius{\the\scratchdimen}% + \ifdim\@@FLOLradius>\@@FLOWdx + \scratchdimen=\@@FLOWdx + \edef\@@FLOLradius{\the\scratchdimen}% + \fi + \ifdim\@@FLOLradius>\@@FLOWdy + \scratchdimen=\@@FLOWdy + \edef\@@FLOLradius{\the\scratchdimen}% + \fi + \else + \scratchdimen=\@@FLOLradius + \edef\@@FLOLradius{\the\scratchdimen}% + \fi + \processaction % magic 2.5 + [\@@FLOWoffset] + [ \v!none=>\scratchdimen=-2.5\scratchdimen, + \v!overlay=>\scratchdimen=-2.5\scratchdimen, + \v!standard=>\scratchdimen=\scratchdimen, + \s!unknown=>\scratchdimen=\@@FLOWoffset, + \s!default=>\scratchdimen=-2.5\scratchdimen]% + \edef\@@FLOW@@offset{\the\scratchdimen}% + \forgetall + \offinterlineskip + \resetMPdrawing + \doglobal\newcounter\FLOWcomment + \startMPdrawing + if unknown context_char : input mp-char.mp ; fi ; + grid_width := \FLOWgridwidth ; + grid_height := \FLOWgridheight ; + shape_width := \FLOWshapewidth ; + shape_height := \FLOWshapeheight ; + connection_line_width := \@@FLOLrulethickness ; + connection_smooth_size := \@@FLOLradius ; + connection_arrow_size := \@@FLOLradius ; + connection_dash_size := \@@FLOLradius ; + currentpicture := nullpicture ; + begin_chart(0,\FLOWwidth,\FLOWheight); + reverse_y := true ; + chart_offset := \@@FLOW@@offset ; + \stopMPdrawing + \doifelsenothing\@@FLOWbackgroundcolor + {\startMPdrawing + chart_background_color := white ; + \stopMPdrawing} + {\startMPdrawing + chart_background_color := \MPcolor{\@@FLOWbackgroundcolor} ; + \stopMPdrawing}% + \doif\@@FLOWoption\v!test + {\startMPdrawing + show_con_points := true ; + show_mid_points := true ; + show_all_points := true ; + \stopMPdrawing}% + \processaction % private + [\@@FLOWdot] + [ \v!yes=>\startMPdrawing + show_con_points := true ; + show_mid_points := true ; + show_all_points := true ; + \stopMPdrawing, + \s!unknown=>\startMPdrawing + show_\@@FLOWdot_points := true ; + \stopMPdrawing]% +\doglobal\newcounter\FLOWcomment + \let\startFLOWcell\startFLOWcellB + \resetFLOWlocation + \processFLOWbuffer\currentFLOWnumber +\doglobal\newcounter\FLOWcomment + \let\startFLOWcell\startFLOWcellC + \resetFLOWlocation + \processFLOWbuffer\currentFLOWnumber + \startMPdrawing + clip_chart(\@@FLOWx,\@@FLOWy,\@@FLOWnx,\@@FLOWny) ; + end_chart ; + \stopMPdrawing + \MPdrawingdonetrue + \setbox0\hbox + {\MPstaticgraphictrue + \MPshiftdrawingfalse + \getMPdrawing}% + \def\MPmessage##1% + {\writestatus{MP charts}{##1}}% + \def\MPposition##1##2##3% + {\setvalue{\@@MPx##1}{##2}\setvalue{\@@MPy##1}{##3}}% + \def\MPclippath##1##2##3##4% + {\def\clipMPllx{##1bp}\def\clipMPlly{##2bp}% + \def\clipMPurx{##3bp}\def\clipMPury{##4bp}}% + \def\MPareapath##1##2##3##4% + {\def\areaMPllx{##1bp}\def\areaMPlly{##2bp}% + \def\areaMPurx{##3bp}\def\areaMPury{##4bp}}% + \getMPdata + \doglobal\newcounter\FLOWcomment + \let\startFLOWcell\startFLOWcellD + \setbox2\vbox to \ht0 + {\forgetall % \offinterlineskip + \resetFLOWlocation + \processFLOWbuffer\currentFLOWnumber\vss}% + \setbox2\hbox + {\hskip\@@FLOW@@offset\lower\@@FLOW@@offset\box2}% + \wd2\wd0\ht2\ht0\dp2\dp0 + \let\startFLOWcell\startFLOWcellE + \setbox4\vbox to \ht0 + {\forgetall % \offinterlineskip + \resetFLOWlocation + \processFLOWbuffer\currentFLOWnumber\vss}% + \setbox4\hbox + {\hskip\@@FLOW@@offset\lower\@@FLOW@@offset\box4}% + \wd4\wd0\ht4\ht0\dp4\dp0 + \doifelse\@@FLOWoption\v!test + {\setbox6\vbox + {\forgetall + \vskip\@@FLOW@@offset + \hskip\@@FLOW@@offset + \basegrid + [\c!x=\@@FLOWx,\c!nx=\@@FLOWnx,\c!dx=\withoutpt\FLOWgridwidth, + \c!y=\@@FLOWy,\c!ny=\@@FLOWny,\c!dy=\withoutpt\FLOWgridheight, + \c!xstep=1,\c!ystep=1, + \c!unit=pt,\c!location=\v!middle]}% + \wd6\wd0\ht6\ht0\dp6\dp0 + \setbox8\vbox + {\forgetall + \offinterlineskip + \vskip\@@FLOW@@offset + \dostepwiserecurse\@@FLOWy\@@FLOWny\plusone + {\vbox to \FLOWgridheight + {\vfill + \hskip\@@FLOW@@offset + \hbox + {\dostepwiserecurse\@@FLOWx\@@FLOWnx\plusone + {\hbox to \FLOWgridwidth + {\hfill + \framed + [\c!framecolor=red, + \c!width=\FLOWshapewidth, + \c!height=\FLOWshapeheight] + {}% + \hfill}}} + \vfill}}}% + \wd8\wd0\ht8\ht0\dp8\dp0 + \framed + [\c!offset=\v!overlay,\c!framecolor=green] + {\hbox{\box4\hskip-\wd0\box0\hskip-\wd2\box2\hskip-\wd6\box6\hskip-\wd8\box8}}} + {\framed + [\c!offset=\v!overlay, + \c!frame=\@@FLOWframe, + \c!rulethickness=\@@FLOWrulethickness, + \c!framecolor=\@@FLOWframecolor, + \c!background=\@@FLOWbackground, + \c!backgroundcolor=\@@FLOWbackgroundcolor] + {\hbox{\box4\hskip-\wd0\box0\hskip-\wd2\box2}}}% + %\message{[\FLOWcells]}\wait + \egroup} + +% Pass A + +\long\def\startFLOWcellA#1\stopFLOWcell% + {\resetFLOWcell + \ignorespaces#1\unskip + \expandafter\getFLOWlocationA\FLOWlocation\end + \ignorespaces} + +\def\getFLOWlocationA#1,#2\end + {\ifnum0#1>\FLOWwidth \xdef\FLOWwidth {#1}\fi + \ifnum0#2>\FLOWheight\xdef\FLOWheight{#2}\fi} + +% Pass B +% +% beware: the - after \@FLOC@ is needed since name can be +% empty and we don't want to redefine \@FLOC@ itself by +% mistake + +\long\def\startFLOWcellB#1\stopFLOWcell + {\resetFLOWcell\ignorespaces#1\unskip + \setxvalue{\@FLOC@-\FLOWname}{\FLOWlocation}% kost veel cs's + \ifx\FLOWshape\empty + \global\let\FLOWshape\@@FLOSdefault + \fi + \doifnot\FLOWshape{none} % {\v!none} + {\ExpandBothAfter\doifinsetelse{\FLOWshape}{\FLOWshapes} + {\edef\FLOWshapetag{shape_\FLOWshape}% beter \expanded + \@EA\setFLOWname\@EA\FLOWshapetag\@EA{\FLOWshapetag}} + {\doifnumberelse\FLOWshape + {\let\FLOWshapetag\FLOWshape} + {\let\FLOWshapetag\empty}}% + \ifx\FLOWshapetag\empty \else + \ExpandBothAfter\doifinsetelse{\FLOWshape}{\FLOWlines} + {\chardef\FLOWstate0 } + {\ExpandBothAfter\doifcommonelse{\FLOWcell,\FLOWfocus}{\@@FLOWfocus} + {\chardef\FLOWstate1 } + {\chardef\FLOWstate2 }}% + \startMPdrawing + begin_sub_chart ; + \ifcase\FLOWstate + shape_line_color := \MPcolor{\@@FLOLcolor} ; + shape_fill_color := \MPcolor{\@@FLOLcolor} ; + shape_line_width := \@@FLOLrulethickness ; + \or + shape_line_color := \MPcolor{\@@FLOFframecolor} ; + shape_fill_color := \MPcolor{\@@FLOFbackgroundcolor} ; + shape_line_width := \@@FLOFrulethickness ; + \or + shape_line_color := \MPcolor{\@@FLOSframecolor} ; + shape_fill_color := \MPcolor{\@@FLOSbackgroundcolor} ; + shape_line_width := \@@FLOSrulethickness ; + \fi + %\ifx\FLOWoverlay\empty + % peepshape := false ; + %\else + % peepshape := true ; + %\fi + peepshape := \ifx\FLOWoverlay\empty false \else true \fi ; + new_shape(\FLOWlocation,\FLOWshapetag) ; + end_sub_chart ; + \stopMPdrawing + \fi}% + \ignorespaces} + +% Pass C + +\long\def\startFLOWcellC#1\stopFLOWcell% + {\resetFLOWcell +\pushmacro\lastFLOWx +\pushmacro\lastFLOWy + \ignorespaces#1\unskip % makes sure that vars are set +\popmacro\lastFLOWy +\popmacro\lastFLOWx + \let\connection\doFLOWconnectionC + \ignorespaces#1\unskip} + +\def\FLOWorigin{0,0} + +\def\doFLOWdisplace[#1,#2,#3]% experiment + {dsp_x := #1 ; dsp_y := #2 ;} + +\def\doFLOWconnectionC + {\dodoubleempty\dodoFLOWconnectionC} + +\def\dodoFLOWconnectionC[#1][#2]#3% + {\doglobal\increment\FLOWcomment + \setFLOWname\otherFLOWname{name_#3}% + \doifdefinedelse{\@FLOC@-\FLOWname} + {\edef\FLOWfrom{\getvalue{\@FLOC@-\FLOWname}}} + {\let \FLOWfrom \FLOWorigin}% + \ifx\FLOWfrom\FLOWorigin \else + \doifdefinedelse{\@FLOC@-\otherFLOWname} + {\edef\FLOWto {\getvalue{\@FLOC@-\otherFLOWname}}} + {\let \FLOWto \FLOWorigin}% + \ifx\FLOWto\FLOWorigin \else + \FLOWsetconnect{#1}% + \ifx\cFLOWfrom\empty \else + \doifelse\@@FLOLcorner\v!round + {\startMPdrawing smooth := true ; \stopMPdrawing} + {\startMPdrawing smooth := false ; \stopMPdrawing}% + \doifelse\@@FLOLdash\v!yes + {\startMPdrawing dashline := true ; \stopMPdrawing} + {\startMPdrawing dashline := false ; \stopMPdrawing}% + \doifelse\@@FLOLarrow\v!yes + {\startMPdrawing arrowtip := true ; \stopMPdrawing} + {\startMPdrawing arrowtip := false ; \stopMPdrawing}% + \doifelse\@@FLOLoffset\v!none + {\startMPdrawing touchshape := true ; \stopMPdrawing} + {\startMPdrawing touchshape := false ; \stopMPdrawing}% +%\doifsomething{#2} +% {\startMPdrawing +% \doFLOWdisplace[0#2,0,0]% +% \stopMPdrawing}% + \startMPdrawing +\doFLOWdisplace[0#2,0,0]% + connection_line_color := \MPcolor{\@@FLOLcolor} ; + connection_line_width := \@@FLOLrulethickness ; + connect_\cFLOWfrom_\cFLOWto (\FLOWfrom,\zFLOWfrom) (\FLOWto,\zFLOWto) ; +\doFLOWdisplace[0,0,0]% + \stopMPdrawing + \fi + \fi + \fi + \ignorespaces} + +% Pass D + +\long\def\startFLOWcellD#1\stopFLOWcell + {\resetFLOWcell +\pushmacro\lastFLOWx +\pushmacro\lastFLOWy + \ignorespaces#1\unskip % presets vars +\popmacro\lastFLOWy +\popmacro\lastFLOWx + \let\doprocessFLOWcell\doprocessFLOWcellD + \expandafter\doprocessFLOWcellD\FLOWlocation\end + \let\connection\doFLOWconnectionD + \let\comment\doFLOWcommentD + \ignorespaces#1\unskip\ignorespaces} + +\def\doFLOWconnectionD + {\dodoubleempty\dodoFLOWconnectionD} + +\def\dodoFLOWconnectionD[#1][#2]#3% + {\doglobal\increment\FLOWcomment + \ignorespaces} + +\def\doFLOWcommentD[#1]#2% + {\bgroup + \let\FLOW \middlebox + \let\FLOWb \bottombox + \let\FLOWbl\bottomleftbox + \let\FLOWbr\bottomrightbox + \let\FLOWt \topbox + \let\FLOWtl\topleftbox + \let\FLOWtr\toprightbox + \let\FLOWl \leftbox + \let\FLOWlt\lefttopbox + \let\FLOWlb\leftbottombox + \let\FLOWr \rightbox + \let\FLOWrt\righttopbox + \let\FLOWrb\rightbottombox + \let\FLOWc \middlebox +%\ifdefined{FLOW#1}% + \ifcase0\getvalue{\@@MPx\FLOWcomment}\getvalue{\@@MPy\FLOWcomment}\relax + \else + \ifdim\getvalue{\@@MPx\FLOWcomment}\s!bp<\areaMPllx\relax\else + \ifdim\getvalue{\@@MPx\FLOWcomment}\s!bp>\areaMPurx\relax\else + \ifdim\getvalue{\@@MPy\FLOWcomment}\s!bp<\areaMPlly\relax\else + \ifdim\getvalue{\@@MPy\FLOWcomment}\s!bp>\areaMPury\relax\else + \dimen0=\getvalue{\@@MPx\FLOWcomment}\s!bp + \advance\dimen0 -\@@FLOW@@offset + \advance\dimen0 -\clipMPllx + \dimen2=\clipMPury + \advance\dimen2 -\@@FLOW@@offset + \advance\dimen2 -\getvalue{\@@MPy\FLOWcomment}\s!bp + \setbox\scratchbox\hbox{\strut#2}% + \boxoffset.5\bodyfontsize + \setbox\scratchbox\hbox{\hskip\dimen0\lower\dimen2\getvalue{FLOW#1}{\box\scratchbox}}% + \smashbox\scratchbox + \box\scratchbox + \boxoffset\zeropoint + \nointerlineskip % really needed + \fi + \fi + \fi + \fi + \fi +%\fi + \egroup + \ignorespaces} + +% pass D + +\def\dophaseoneFLOWcellX#1#2% + {\!!counta#1\relax + \!!countb#2\relax + \!!countc\@@FLOWx + \!!countd\@@FLOWy + \advance\!!countc \@@FLOWnx + \advance\!!countd \@@FLOWny + \advance\!!countc \minusone + \advance\!!countd \minusone + \ifnum\!!counta<\@@FLOWx\relax \donefalse + \else\ifnum\!!counta>\!!countc \donefalse + \else\ifnum\!!countb<\@@FLOWy\relax \donefalse + \else\ifnum\!!countb>\!!countd \donefalse + \else \donetrue + \fi\fi\fi\fi} + +\def\dophasetwoFLOWcellX + {\advance\!!counta -\@@FLOWx + \advance\!!counta \plusone + \advance\!!countb -\@@FLOWy + \advance\!!countb \plusone + \dimen0=\FLOWgridwidth + \dimen0=\!!counta\dimen0 + \advance\dimen0 -\FLOWgridwidth + \dimen4=\FLOWgridwidth + \advance\dimen4 -\FLOWshapewidth + \advance\dimen0 .5\dimen4 + \dimen2=\FLOWgridheight + \dimen2=\!!countb\dimen2 + \dimen4=\FLOWgridheight + \advance\dimen4 -\FLOWshapeheight + \advance\dimen2 -.5\dimen4 + \edef\FLOWdx{\the\dimen0}% + \edef\FLOWdy{\the\dimen2}} + +\def\positionFLOWzero% assumes \FLOWdx and \FLOWdy are set + {\setbox0\hbox{\hskip\FLOWdx\lower\FLOWdy\box0}% + \smashbox0\box0 + \nointerlineskip} % new, needed since we somehow reset that + +\def\doFLOWtlabel#1#2#3% + {\scratchdimen\ifcase#2 \zeropoint\else\@@FLOWdy\fi + \setbox0\hbox{\hskip\dimen2\raise\scratchdimen + \hbox{\raise\dimen4\hbox{#1{\strut#3}}}}% + \positionFLOWzero}% + +\def\doFLOWblabel#1#2#3% + {\scratchdimen\ifcase#2 \zeropoint\else\@@FLOWdy\fi + \setbox0\hbox{\hskip\dimen2\raise-\scratchdimen + \hbox{#1{\strut#3}}}% + \positionFLOWzero}% + +\def\doFLOWllabel#1#2#3% + {\scratchdimen\ifcase#2 \zeropoint\else\@@FLOWdx\fi + \setbox0\hbox{\hskip-\scratchdimen\raise\dimen6 + \hbox{#1{\strut#3}}}% + \positionFLOWzero}% + +\def\doFLOWrlabel#1#2#3% + {\scratchdimen\ifcase#2 \zeropoint\else\@@FLOWdx\fi + \setbox0\hbox{\hskip\dimen0\hskip\scratchdimen + \hbox{\raise\dimen6\hbox{#1{\strut#3}}}}% + \positionFLOWzero} + +\def\doprocessFLOWcellD#1,#2\end + {\dophaseoneFLOWcellX{#1}{#2}% + \ifdone + \dophasetwoFLOWcellX + \doglobal\addtocommalist\FLOWcell\FLOWcells + \def\FLOWx{#1}% + \def\FLOWy{#2}% + \directsetup{flowcell}% + \setbox0\hbox + {\ifx\FLOWalign\empty\else + \setupframed + [\c!align=\v!normal,\c!bottom=\vfill,\c!top=\vfill]% + \@EA\processallactionsinset\@EA + [\FLOWalign] + [t=>{\setupframed[\c!bottom=\vfill,\c!top=]}, + b=>{\setupframed[\c!bottom=,\c!top=\vfill]}, + l=>{\setupframed[\c!align=\v!right]}, + r=>{\setupframed[\c!align=\v!left]}, + m=>{\setupframed[\c!align=\v!middle]}, + c=>{\setupframed[\c!align=\v!middle]}]% + \fi + \doifelse\FLOWshape{none} % {\v!none} + {\setupframed[\c!offset=\v!overlay]} + {\setupframed[\c!offset=\@@FLOSoffset]}% + \framed + [\c!frame=\v!off,\c!background=flowcell, + \c!width=\FLOWshapewidth,\c!height=\FLOWshapeheight] + {\FLOWtext}}% + \showFLOWhelp0 + \ifx\FLOWdestination\empty\else + \setbox0\hbox + {\setupinteraction[\c!color=,\c!contrastcolor=]% + \gotobox{\box0}[\FLOWdestination]}% + \fi + \positionFLOWzero + \dimen0=\FLOWshapewidth \dimen2=.5\dimen0 + \dimen4=\FLOWshapeheight\dimen6=.5\dimen4 + \boxoffset.5\bodyfontsize + \doFLOWtlabel \righttopbox0\tFLOWlabel + \doFLOWblabel\rightbottombox0\bFLOWlabel + \doFLOWllabel \lefttopbox0\lFLOWlabel + \doFLOWrlabel \righttopbox0\rFLOWlabel + \doFLOWtlabel \topbox0\tcFLOWlabel % for me only + \doFLOWblabel \bottombox0\bcFLOWlabel % for me only + \doFLOWllabel \leftbox0\lcFLOWlabel % for me only + \doFLOWrlabel \rightbox0\rcFLOWlabel % for me only + \ifnum#1=\@@FLOWx\relax \doFLOWllabel \leftbox1\lFLOWexit \fi + \ifnum#1=\!!countc \doFLOWrlabel \rightbox1\rFLOWexit \fi + \ifnum#2=\@@FLOWy\relax \doFLOWtlabel \topbox1\tFLOWexit \fi + \ifnum#2=\!!countd \doFLOWblabel \bottombox1\bFLOWexit \fi + \boxoffset\zeropoint + \fi} + +% For Willy Egger: +% +% \startsetups flowcell +% \definelayer +% [flowcell] +% [width=\FLOWshapewidth, +% height=\FLOWshapeheight] +% \setlayerframed +% [flowcell] +% [preset=rightbottom,offset=1ex] +% [frame=off] +% {\tx(\FLOWx,\FLOWy)} +% \stopsetups + +% Pass E + +\long\def\startFLOWcellE#1\stopFLOWcell + {\resetFLOWcell + \ignorespaces#1\unskip + \let\doprocessFLOWcell\doprocessFLOWcellE + \expandafter\doprocessFLOWcell\FLOWlocation\end} + +\def\doprocessFLOWcellE#1,#2\end % redundant + {\ifx\FLOWoverlay\empty \else + \dophaseoneFLOWcellX{#1}{#2}% + \ifdone + \dophasetwoFLOWcellX + \edef\FLOWdx{\the\dimen0}% + \edef\FLOWdy{\the\dimen2}% + \setbox0\hbox + {\framed + [%\c!frame=\v!off, + \c!background={\@@FLOWbackground,\FLOWoverlay}, + \c!backgroundcolor=\@@FLOSbackgroundcolor, + \c!width=\FLOWshapewidth,\c!height=\FLOWshapeheight] + {}}% + \positionFLOWzero + \fi + \fi} + +% Pass F + +\def\checkFLOWautofocus + {\def\@@FLOWminx{100}\let\@@FLOWminy\@@FLOWminx + \def\@@FLOWmaxx {0}\let\@@FLOWmaxy\@@FLOWmaxx + \def\@@FLOWabsx {0}\let\@@FLOWabsy\@@FLOWabsx + \let\startFLOWcell\startFLOWcellF + \resetFLOWlocation + \processFLOWbuffer\currentFLOWnumber + %\message{AUTOSHAPE 1: (\@@FLOWminx,\@@FLOWminy)->(\@@FLOWmaxx,\@@FLOWmaxy)}% + \ifnum\@@FLOWabsx<\@@FLOWmaxx\let\@@FLOWmaxx\@@FLOWabsx\fi + \ifnum\@@FLOWabsy<\@@FLOWmaxy\let\@@FLOWmaxy\@@FLOWabsy\fi + %\message{AUTOSHAPE 2: (\@@FLOWminx,\@@FLOWminy)->(\@@FLOWmaxx,\@@FLOWmaxy)}% + \donetrue + \ifnum\@@FLOWminx=100 \donefalse\fi + \ifnum\@@FLOWminy=100 \donefalse\fi + \ifnum\@@FLOWmaxx=0 \donefalse\fi + \ifnum\@@FLOWmaxy=0 \donefalse\fi + \doFLOWcheckF\@@FLOWx\@@FLOWminx\@@FLOWmaxx\@@FLOWnx + \doFLOWcheckF\@@FLOWy\@@FLOWminy\@@FLOWmaxy\@@FLOWny} + +\def\startFLOWcellF#1\stopFLOWcell% + {\resetFLOWcell + \ignorespaces#1\unskip + \expandafter\doFLOWlocationF\FLOWlocation\end}% + +\def\doFLOWlocationF#1,#2\end% + {\ifnum#1>\@@FLOWabsx\def\@@FLOWabsx{#1}\fi + \ifnum#2>\@@FLOWabsy\def\@@FLOWabsy{#2}\fi + \ExpandBothAfter\doifinset{\FLOWcell}{\@@FLOWautofocus} + {\dodoFLOWlocationF{#1}<-\@@FLOWminx + \dodoFLOWlocationF{#1}>+\@@FLOWmaxx + \dodoFLOWlocationF{#2}<-\@@FLOWminy + \dodoFLOWlocationF{#2}>+\@@FLOWmaxy}} + +\def\dodoFLOWlocationF#1#2#3#4% + {\ifnum#1#2#4\relax + \!!counta=#1\advance\!!counta #31\relax + \edef#4{\ifnum\!!counta<1 1\else\the\!!counta\fi}% + \fi} + +\def\doFLOWcheckF#1#2#3#4% + {\ifdone + \let#1=#2% + \!!counta=#3% + \advance\!!counta \plusone\advance\!!counta -#2\relax + \ifnum\!!counta<1 \!!counta=1 \fi + \edef#4{\the\!!counta}% + \else + \let#1\!!plusone + \let#4\!!zerocount % no {1} + \fi} + +% \useFLOWchart[name][parent][setting,setting][additional settings] +% \useFLOWchart[name][parent][additional settings] + +\let\currentFLOWchart\empty + +\def\useFLOWchart + {\doquadrupleempty\douseFLOWchart} + +\def\douseFLOWchart[#1][#2][#3][#4]% name parent sets mainsettings + {\iffourthargument + \setvalue{\@FLOW@--#1}[##1]{\setgetFLOWchart[#2][#3][#4,##1]}% + \else + \checkparameters[#3]% + \ifparameters + \setvalue{\@FLOW@--#1}[##1]{\setgetFLOWchart[#2][][#3,##1]}% + \else + \setvalue{\@FLOW@--#1}[##1]{\setgetFLOWchart[#2][#3][##1]}% + \fi + \fi} + +\def\setgetFLOWchart[#1][#2][#3]% + {\def\docommand##1{}% cell line focus ? + \processcommalist[#2]\docommand + \getFLOWchart[#1][#3]} + +\def\doFLOWchart[#1][#2]% + {\hbox\bgroup\vbox\bgroup % vmode suppresses spaces +\def\currentFLOWchart{#1}% + \doifundefinedelse{\@FLOW@--#1} + {\getFLOWchart[#1][#2]} + {\getvalue{\@FLOW@--#1}[#2]}% + \egroup\egroup} + +\def\FLOWchart% + {\dodoubleempty\doFLOWchart} + +%D A hook into the help system. + +\def\showFLOWhelp#1% + {\doifhelpinfo\FLOWhelp + {\setbox#1=\hbox + {\setbox\scratchbox=\hbox{\lower\@@FLOWdy\hbox + {\helpbutton + [\c!width=\wd0,\c!color=,\c!height=\@@FLOWdy,\c!frame=\v!no]% + [\FLOWhelp]}}% + \smashbox\scratchbox + \setbox#1=\vbox + {\forgetall\offinterlineskip\box#1\box\scratchbox}% + \box#1}}} + +%D The next section is dedicated to splitting up charts. + +\def\getFLOWsize[#1]% + {\bgroup\let\dodogetFLOWchart\dogetFLOWsize\FLOWchart[#1]\egroup} + +\def\dogetFLOWsize[#1][#2]% + {\setbox\scratchbox=\vbox + {\globallet\FLOWmaxwidth \!!zerocount + \globallet\FLOWmaxheight\!!zerocount + \def\getFLOWlocation##1,##2\end + {\ifnum0##1>\FLOWmaxwidth \xdef\FLOWmaxwidth {##1}\fi + \ifnum0##2>\FLOWmaxheight\xdef\FLOWmaxheight{##2}\fi}% + \resetFLOWcell + \long\def\startFLOWcell##1\stopFLOWcell + {{##1\expandafter\getFLOWlocation\FLOWlocation\end}}% + \def\dohandleflowchart[##1][##2]% + {\resetFLOWlocation + \processFLOWbuffer{##1}}% + \getvalue{\@FLOW@-#1}}} + +\def\setupFLOWsplit% + {\dodoubleargument\getparameters[\@@FLOT]} + +\setupFLOWsplit% + [\c!nx=3,\c!ny=3, + \c!dx=1,\c!dy=1, + \c!command=, + \c!marking=\v!on, + \c!before=,\c!after=] + +\def\FLOWsplitx {1} +\def\FLOWsplity {1} +\def\FLOWsplitnx{1} +\def\FLOWsplitny{1} + +\def\FLOWcharts% + {\dodoubleempty\doFLOWcharts} + +%D While splitting, the following variables are available: +%D +%D \starttyping +%D \FLOWsplitnx \FLOWsplitny \FLOWsplitx \FLOWsplity +%D \stoptyping + +\def\doFLOWcharts[#1][#2]% + {\bgroup + \getFLOWsize[#1]% + \dodoFLOWcharts\relax + \global\let\FLOWsplitnx\FLOWsplitx + \global\let\FLOWsplitny\FLOWsplity + \dodoFLOWcharts{\dododoFLOWcharts[#1][#2]}% + \egroup} + +\def\dodoFLOWcharts#1% + {\def\@@FLOTx{1}% + \global\let\FLOWsplitx\@@FLOTx + \doloop + {\def\@@FLOTy{1}% + \global\let\FLOWsplity\@@FLOTy + \doloop + {\bgroup + \scratchcounter\FLOWmaxwidth + \advance\scratchcounter -\@@FLOTx + \advance\scratchcounter \plusone + \ifnum\scratchcounter<\@@FLOTnx\edef\@@FLOTnx{\the\scratchcounter}\fi + \scratchcounter\FLOWmaxheight + \advance\scratchcounter -\@@FLOTy + \advance\scratchcounter \plusone + \ifnum\scratchcounter<\@@FLOTny\edef\@@FLOTny{\the\scratchcounter}\fi + #1% does something with the float, or not + \egroup + \increment(\@@FLOTy,\@@FLOTny)% + \ifnum\@@FLOTy>\FLOWmaxheight + \exitloop + \else + \doglobal\increment\FLOWsplity + \decrement(\@@FLOTy,\@@FLOTdy)% + \fi}% + \increment(\@@FLOTx,\@@FLOTnx)% + \ifnum\@@FLOTx>\FLOWmaxwidth + \exitloop + \else + \doglobal\increment\FLOWsplitx + \decrement(\@@FLOTx,\@@FLOTdx)% + \fi}} + +\def\dododoFLOWcharts[#1][#2]% + {\bgroup + \@@FLOTbefore + \doifnot\@@FLOTmarking\v!on{\let\cuthbox\hbox}% + \cuthbox + {\@@FLOTcommand + {\FLOWchart[#1][#2, + \c!x=\@@FLOTx,\c!nx=\@@FLOTnx, + \c!y=\@@FLOTy,\c!ny=\@@FLOTny]}}% + \@@FLOTafter + \egroup} + +%D An example of splitting is given below: +%D +%D \starttyping +%D \setupFLOWsplit +%D [nx=5,ny=10, +%D dx=0,dy=0, +%D before=, +%D after=\page] +%D +%D \FLOWcharts[mybigflow] +%D \stoptyping +%D +%D Or, one can say: +%D +%D \starttyping +%D \splitfloat +%D {\placefigure{What a big flowchart this is!}} +%D {\FLOWcharts[mybigflow]} +%D \stoptyping + +%D \macros +%D {typeFLOWchart} +%D +%D For documentation purposes the following macro is +%D provided. Watch the use of the first and last line hooks, +%D which is needed because the start and stop commands are +%D not part of the buffer. + +\def\typeFLOWchart[#1]% + {\bgroup + \def\dohandleflowchart[##1][##2]{\typeFLOWbuffer{##1}}% + \defconvertedargument\firstverbatimfileline{\startFLOWchart[#1]}% + \defconvertedargument\lastverbatimfileline {\stopFLOWchart}% + \getvalue{\@FLOW@-#1} + \egroup} + +%D New: +%D +%D \starttyping +%D \setupFLOWcharts[command=\Whow] +%D +%D \startFLOWset[convert-en] % [tag][convert-en] +%D \subFLOWchart[a][x=1,y=1,nx=3,ny=3] +%D \subFLOWchart[b][x=1,y=2,nx=3,ny=3] +%D \subFLOWchart[c][x=2,y=1,nx=3,ny=3] +%D \stopFLOWset +%D +%D \def\Whow#1% +%D {\ifnum\currentFLOWset=1 \framed{Some Chart}\fi} +%D +%D \FLOWset[convert-en] % [tag] +%D +%D \def\Whow#1% +%D {\setuphead[state=high] +%D \startstandardmakeup +%D \centerbox{#1} +%D \stopstandardmakeup} +%D +%D \FLOWset[convert-en] % [tag] +%D \stoptyping + +\def\startFLOWset + {\dodoubleempty\dostartFLOWset} + +\def\dostartFLOWset[#1][#2]#3\stopFLOWset % tag name data + {\ifsecondargument + \long\setvalue{\@FLOX@#1}{\dohandleFLOWset{#1}{#2}{#3}}% + \else + \long\setvalue{\@FLOX@#1}{\dohandleFLOWset{#1}{#1}{#3}}% + \fi} + +\long\def\dohandleFLOWset#1#2#3% tag name data + {\bgroup + \def\subFLOWchart + {\dodoubleempty\dosubFLOWchart}% + \def\dosubFLOWchart[##1][##2]% subtag settings + {\ifsecondargument + \dodohandleFLOWset{#1}{##1}{#2}{##2}% + \else + \subFLOWchart[][##1]% + \fi}% + #3% + \egroup} + +\def\dodohandleFLOWset#1#2#3#4% tag subtag name settings + {\increment\currentFLOWset + \bgroup + \@@FLOXcommand + {\ifnum\currentFLOWset=1 \pagereference[#1]\fi + \doifsomething{#2} + {\setupreferencing[\c!prefix=]% + \pagereference[#1:#2]% -:#1:#2 + \setupreferencing[\c!prefix=#1:#2]}% + \FLOWchart[#3][#4]}% + \egroup} + +\def\FLOWset[#1]% + {\newcounter\currentFLOWset + \doifdefinedelse{\@FLOX@#1} + {\getvalue{\@FLOX@#1}} + {\dodohandleFLOWset{#1}{}{#1}{}}} + +\newcounter\currentFLOWset + +\setupFLOWsets + [\c!command=] + +%D This will be an option: + +% \def\startFLOWchart% +% {\dodoubleempty\dostartFLOWchart} +% +% \long\def\dostartFLOWchart[#1][#2]#3\stopFLOWchart +% {\preparenextFLOWchart{#1}{#2}% +% \long\setgvalue{\FLOWbufferprefix\nofFLOWcharts}{#3}} +% +% \long\def\dodefineFLOWchart[#1][#2]#3% +% {\preparenextFLOWchart{#1}{#2}% +% \long\setgvalue{\FLOWbufferprefix\nofFLOWcharts}{#3}} +% +% \def\processFLOWbuffer#1{\getvalue{\FLOWbufferprefix#1}} +% \def\typeFLOWbuffer #1{[Sorry, no verbatim chart #1 available.]} + +\loadmarkfile{m-chart} + +\protect \endinput 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..bd4cb093e --- /dev/null +++ b/tex/context/base/m-chemic.mkiv @@ -0,0 +1,20 @@ +%D \module +%D [ file=ppchtex (m-chemic), +%D version=1997.03.19, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=\PPCHTEX\ (Plain Pictex Context cHemie \TEX), +%D author=Hans Hagen, +%D date=\currentdate, +%D 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. + +\writestatus{ppchtex}{not loaded as support for chemistry in now built in} + +% \usemodule[pictex] % we will get rid of this +% \input ppchtex.mkiv \relax + +\endinput diff --git a/tex/context/base/m-chemic.tex b/tex/context/base/m-chemic.tex new file mode 100644 index 000000000..7bacf4a90 --- /dev/null +++ b/tex/context/base/m-chemic.tex @@ -0,0 +1,17 @@ +%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. + +\loadmarkfile{m-chemic} + +\endinput diff --git a/tex/context/base/m-cweb.tex b/tex/context/base/m-cweb.tex new file mode 100644 index 000000000..c416c9b36 --- /dev/null +++ b/tex/context/base/m-cweb.tex @@ -0,0 +1,1371 @@ +%D \module +%D [ file=m-cweb, +%D version=1997.01.15, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=\CWEB\ Pretty Printing Macros, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D First some auxiliary stuff, to be moved to system module. + +\def\dodofindfirstcharacter#1% + {\ifx#1\relax + \let\next=\egroup + \else + \handlecase + {\expandafter\ifnum\expandafter\catcode\expandafter`#1=11 + \def\next##1\relax{\egroup\def\firstcharacter{#1}}% + \fi}% + \fi + \next} + +\def\dofindfirstcharacter#1#2% + {\def\firstcharacter{}% + \bgroup + \defconvertedargument\ascii{#2}% + \let\next\dodofindfirstcharacter + \let\handlecase#1% + \expandafter\next\ascii\relax} + +\def\normalcase#1% + {#1} + +\def\findfirstcharacter% + {\dofindfirstcharacter\lowercase} + +\def\FindFirstCharacter% + {\dofindfirstcharacter\normalcase} + +\def\FINDFIRSTCHARACTER% + {\dofindfirstcharacter\uppercase} + +% nog doen: +% +% \deactivateCWEB in output routine +% status info +% gelinkte entries +% parskip en parindent + +%D \gdef\CWEBquote#1.{{\em Quote :}\ #1.} % checks the . + +%D This module (re)implements the \CWEB\ macros as defined in +%D the file \type{cwebmac.tex}. +%D +%D \CWEB\ uses short, often one character long, names for +%D macros. This is no real problem because no one is supposed +%D to read and understand the files generated by \CWEB. The +%D standard macros are meant for \PLAIN\ \TEX\ users. In +%D \CONTEXT\ and other macro packages however, there is a +%D potential conflict with format specific or user defined +%D commands. Furthermore, the \CWEB\ macros implement their own +%D output routines. When integrating \CWEB\ documents in +%D another environment, the \CWEB\ specific macros have to be +%D made local. The first part of this module is dedicated to +%D this feature. +%D +%D Instead of using \type{\def} and \type{\let} for defining +%D macros, we use: +%D +%D \starttyping +%D \defCEBmacro arguments {meaning} +%D \letCEBmacro arguments {meaning} +%D \stoptyping +%D +%D \CWEB files contain implicit calls to macros that generate +%D the table of contents, the lists of sections and the index. +%D Because we want to be much more flexible, we implemented our +%D own alternatives, and therefore have to bypass the original +%D ones. The next macro is used for defining these obsolete +%D \CWEB\ macros. The dummies take care of arguments. +%D +%D \starttyping +%D \defCEBdummy arguments {meaning} +%D \stoptyping +%D +%D The list of \CWEB\ specific macro names is saved in a +%D \TOKENLIST. This serves two purposes. First it enables us to +%D activate the \CWEB\ macros, which are saved under a +%D different name, second it can be used to temporary restore +%D the meanings, for instance when the output routine builds +%D the page. + +\newtoks\CWEBmacros + +%D Activating and deactivating is done by means of: +%D +%D \starttyping +%D \activateCWEB +%D \deactivateCWEB +%D \stoptyping +%D +%D Which are implemented as: + +\def\activateCWEB% + {\let\doCWEB=\activateCWEBmacro + \the\CWEBmacros} + +\def\deactivateCWEB% + {\let\doCWEB=\deactivateCWEBmacro + \the\CWEBmacros} + +%D The three definition macros append the name of the macro to +%D the list. The first two macros save the meaning, the last one +%D assigns \type{{}} to the macro and gobbles original meaning. + +\long\def\defCWEBmacro#1% + {\appendtoks\doCWEB#1\to\CWEBmacros + \setvalue{newCWEB\string#1}} + +\long\def\letCWEBmacro#1% + {\appendtoks\doCWEB#1\to\CWEBmacros + \letvalue{newCWEB\string#1}} + +\long\def\defCWEBdummy#1#2#% + {\appendtoks\doCWEB#1\to\CWEBmacros + \setvalue{newCWEB\string#1}#2{}% + \gobbleoneargument} + +%D The macro \type{\defCWEBdummy} of course takes care of the +%D argument. This leaves the two (de|)|activating macros: + +\def\CWEBmacro#1% + {\getvalue{newCWEB\string#1}} + +\def\activateCWEBmacro#1% + {\letvalue{oldCWEB\string#1}=#1% + \def#1{\CWEBmacro#1}} + +\def\deactivateCWEBmacro#1% + {\expandafter\let\expandafter#1\expandafter=\csname oldCWEB\string#1\endcsname} + +%D I did consider loading the \CWEB\ macros using temporary +%D substitutes of \type{\def}, \type{\font}, \type{\newbox} etc. +%D The main problem is that the file contains more than +%D definitions and taking all kind of assignments into account +%D too would not make things easier. So I decided to stick to +%D the method as just described. + +%D Now we're ready for the real job. What follows is a partial +%D adaption of the file \type{cwebmac.tex}, version 3.1, dated +%D September 1994 and written by Levy and Knuth. When possible +%D we kept the original meaning, but we've granted ourselves +%D the freedom to reformat the macro's for readibility. +%D +%D We'll only present the macros we actually use. The source +%D however contains the original implementation. + +% standard macros for CWEB listings (in addition to plain.tex) +% Version 3.1 --- September 1994. +% +% \ifx\documentstyle\undefined\else\endinput\fi % LaTeX will use other macros +% +% \xdef\fmtversion{\fmtversion+CWEB3.1} + +%D \macros{.}{} +%D +%D \CWEBquote preserve a way to get the dot accent (all +%D other accents will still work as usual). + +\letCWEBmacro\: = \. + +% \parskip = 0pt % no stretch between paragraphs +% \parindent = 1em % for paragraphs and for the first line of C text + +% \font\ninerm = cmr9 +% \let\mc = \ninerm % medium caps +% \font\eightrm = cmr8 +% \let\sc = \eightrm % small caps (NOT a caps-and-small-caps font) +% \let\mainfont = \tenrm +% \let\cmntfont = \tenrm +% \font\tenss = cmss10 +% \let\cmntfont = \tenss % alternative comment font +% \font\titlefont = cmr7 scaled \magstep4 % title on the contents page +% \font\ttitlefont = cmtt10 scaled \magstep2 % typewriter type in title +% \font\tentex = cmtex10 % TeX extended character set (used in strings) +% \fontextraspace\tentex = 0pt % no double space after sentences + +%D \macros{mc,sc,cmntfont,eightrm}{} +%D +%D The naming of the fonts in in line with those in \PLAIN\ +%D \TEX. Although \CONTEXT\ implements its own scheme, there is +%D still support for the \PLAIN\ ones. We keep the original +%D names, but change their meaning. That way the macros obey +%D switching to other sizes or styles. + +\defCWEBmacro\mc {\tx} +\defCWEBmacro\sc {\txx} +\defCWEBmacro\cmntfont {\ss} +\defCWEBmacro\eightrm {\tx} + +%D \macros{tentex,sevenrm,sevensy,teni}{} +%D +%D The next one uses a temporary solution. The \type{cmtex10} +%D font is not part of the default mechanism. We make use of +%D the \CONTEXT\ variables \type{\textface}, \type{\scriptface} +%D and \type{\scriptscriptface}, which hold the current +%D sizes. + +\defCWEBmacro\tentex% + {\font\next=cmtex10 at \textface + \fontextraspace\next\zeropoint + \next} + +\defCWEBmacro\sevenrm {\getvalue{\scriptface rmtf}} +\defCWEBmacro\sevensy {\getvalue{\scriptface mmsy}} +\defCWEBmacro\teni {\getvalue{\textface mmmi}} + +%D \macros{CWEBpt}{} +%D +%D The original macros are based on a 10~point bodyfont size. We +%D therefore have to specify dimension in points a bit +%D different. Specifications like .6pt are changed to +%D \type{.06} times \type{\bodyfontsize}. + +\defCWEBmacro\CWEBpt {\bodyfontsize} % still dutch + +%D \macros{CEE,UNIX,TEX,CPLUSPLUS}{} +%D +%D Next come some logo's. It does not make much sense to use +%D the \CONTEXT\ logo mechanism here, so we simply say: + +\defCWEBmacro \CEE/{{\mc C\spacefactor1000}} +\defCWEBmacro \UNIX/{{\mc U\kern-.05emNIX\spacefactor1000}} +\defCWEBmacro \TEX/{\TeX} +\defCWEBmacro\CPLUSPLUS/{{\mc C\PP\spacefactor1000}} +\defCWEBmacro \Cee{\CEE/} % for backward compatibility + +%D \macros{\ }{} +%D +%D Now we come to the real work: the short commands that make +%D up the typography. +%D +%D \CWEBquote italic type for identifiers. + +\defCWEBmacro\\#1% + {\leavevmode\hbox{\it#1\/\kern.05em}} + +%D \macros{\string|}{} +%D +%D \CWEBquote one letter identifiers look better this way. + +\defCWEBmacro\|#1% + {\leavevmode\hbox{$#1$}} + +%D \macros{\string\&}{} +%D +%D \CWEBquote boldface type for reserved words. + +\defCWEBmacro\% + {\leavevmode + \hbox + {\def\_% + {\kern.04em + \vbox{\hrule width.3em height .06\CWEBpt}% .6pt}% + \kern.08em}% + \bf#1\/\kern.05em}} + +%D \macros{.}{} +%D +%D Here we use the previously saved period. This macro +%D takes care of special characters in strings. + +\defCWEBmacro\.#1% + {\leavevmode + \hbox + {\tentex % typewriter type for strings + \let\\=\BS % backslash in a string + \let\{=\LB % left brace in a string + \let\}=\RB % right brace in a string + \let\~=\TL % tilde in a string + \let\ =\SP % space in a string + \let\_=\UL % underline in a string + \let\&=\AM % ampersand in a string + \let\^=\CF % circumflex in a string + #1\kern.05em}} + +%D \macros{)}{} +%D +%D Some discretionary hack. + +\defCWEBmacro\)% + {\discretionary{\hbox{\tentex\BS}}{}{}} + +%D \macros{AT}{} +%D +%D \CWEBquote at sign for control text (not needed in versions +%D $>=$ 2.9). + +\defCWEBmacro\AT{@} + +%D \macros{ATL,postATL,NOATL}{} +%D +%D A two step macro that handles whatever. + +\defCWEBmacro\ATL% + {\par + \noindent + \bgroup + \catcode`\_=12 + \postATL} + +\defCWEBmacro\postATL#1 #2 % + {\bf letter \\{\uppercase{\char"#1}} tangles as \tentex "#2"% + \egroup + \par} + +\defCWEBmacro\noATL#1 #2 % + {} + +%D \macros{noatl}{} +%D +%D \CWEBquote suppress output from \type{@l}. + +\defCWEBmacro\noatl% + {\let\ATL=\noATL} + +% \defCWEBmacro\ATH% +% {\X\kern-.5em:Preprocessor definitions\X} + +%D \macros{PB} +%D +%D \CWEBquote hook for program brackets {\tttf\string|...\string|} +%D in TeX part or section name. + +\defCWEBmacro\PB% + {\relax} + +% \chardef\AM = `\& % ampersand character in a string +% \chardef\BS = `\\ % backslash in a string +% \chardef\LB = `\{ % left brace in a string +% \chardef\RB = `\} % right brace in a string +% \chardef\TL = `\~ % tilde in a string +% \chardef\UL = `\_ % underline character in a string +% \chardef\CF = `\^ % circumflex character in a string + +\defCWEBmacro\AM {\char`\&} % ampersand character in a string +\defCWEBmacro\BS {\char`\\} % backslash in a string +\defCWEBmacro\LB {\char`\{} % left brace in a string +\defCWEBmacro\RB {\char`\}} % right brace in a string +\defCWEBmacro\TL {\char`\~} % tilde in a string +\defCWEBmacro\UL {\char`\_} % underline character in a string +\defCWEBmacro\CF {\char`\^} % circumflex character in a string + +\defCWEBmacro\SP {{\tt\char`\ }} % (visible) space in a string + +% \newbox\PPbox \setbox\PPbox=\hbox +% {\kern.5pt\raise1pt\hbox{\sevenrm+\kern-1pt+}\kern.5pt} +% \newbox\MMbox \setbox\MMbox=\hbox +% {\kern.5pt\raise1pt\hbox{\sevensy\char0\kern-1pt\char0}\kern.5pt} +% \newbox\MGbox \setbox\MGbox=\hbox % symbol for -> +% {\kern-2pt\lower3pt\hbox{\teni\char'176}\kern1pt} +% \newbox\MODbox \setbox\MODbox=\hbox +% {\eightrm\%} +% +% \def\PP {\copy\PPbox} +% \def\MM {\copy\MMbox} +% \def\MG {\copy\MGbox} +% \def\MOD {\mathbin{\copy\MODbox}} + +\defCWEBmacro\PP% symbol for ++ + {\kern.05\CWEBpt + \raise.1\CWEBpt\hbox{\sevenrm+\kern-.1\CWEBpt+}% + \kern.05\CWEBpt} + +\defCWEBmacro\MM% + {\kern.05\CWEBpt + \raise.1\CWEBpt\hbox{\sevensy\char0\kern-.1\CWEBpt\char0}% + \kern.05\CWEBpt} + +\defCWEBmacro\MG% + {\kern-.2\CWEBpt + \lower.3\CWEBpt\hbox{\teni\char'176}% + \kern .1\CWEBpt} + +\defCWEBmacro\MRL#1% + {\mathrel{\let\K==#1}} + +% \def\MRL#1% +% {\KK#1} +% \def\KK#1#2% +% {\buildrel\;#1\over{#2}} + +\letCWEBmacro\GG = \gg +\letCWEBmacro\LL = \ll +\letCWEBmacro\NULL = \Lambda + +% \mathchardef\AND = "2026 % bitwise and; also \& (unary operator) + +\defCWEBmacro\AND% redefines itself (funny) + {\mathchardef\AND="2026 \AND} % bitwise and; also \& (unary operator) + +\letCWEBmacro\OR = \mid % bitwise or +\letCWEBmacro\XOR = \oplus % bitwise exclusive or +\defCWEBmacro\CM {{\sim}} % bitwise complement +\defCWEBmacro\MOD {\mathbin{\eightrm\%}} +\defCWEBmacro\DC {\kern.1em{::}\kern.1em} % symbol for :: +\defCWEBmacro\PA {\mathbin{.*}} % symbol for .* +\defCWEBmacro\MGA {\mathbin{\MG*}} % symbol for ->* +\defCWEBmacro\this {\&{this}} + +% \newbox \bak % backspace one em +% \newbox \bakk % backspace two ems +% +% \setbox\bak =\hbox to -1em{} +% \setbox\bakk=\hbox to -2em{} + +\newcount\CWEBind % current indentation in ems + +\defCWEBmacro\1% indent one more notch + {\global\advance\CWEBind by 1 + \hangindent\CWEBind em} + +\defCWEBmacro\2% indent one less notch + {\global\advance\CWEBind by -1 } + +\defCWEBmacro\3#1% optional break within a statement + {\hfil + \penalty#10 + \hfilneg} + +\defCWEBmacro\4% backspace one notch + {\hbox to -1em{}} + +\defCWEBmacro\5% optional break + {\hfil + \penalty-1 + \hfilneg + \kern2.5em + \hbox to -2em{}% + \ignorespaces} + +\defCWEBmacro\6% forced break + {\ifmmode + \else + \par + \hangindent\CWEBind em + \noindent + \kern\CWEBind em + \hbox to -2em{}% + \ignorespaces + \fi} + +\defCWEBmacro\7% forced break and a little extra space + {\Y + \6} + +\defCWEBmacro\8% no indentation + {\hskip-\CWEBind em + \hskip 2em} + +\defCWEBmacro\9#1% + {} + +\newcount\gdepth % depth of current major group, plus one +\newcount\secpagedepth +\secpagedepth=3 % page breaks will occur for depths -1, 0, and 1 + +% \newtoks\gtitle % title of current major group +% \newskip\intersecskip +% \intersecskip=12pt minus 3pt % space between sections + +% \let\yskip=\smallskip + +\defCWEBmacro\?% + {\mathrel?} + +% \def\note#1#2.% +% {\Y\noindent +% {\hangindent2em\baselineskip10pt\eightrm#1~#2.\par}} + +\defCWEBmacro\lapstar% + {\rlap{*}} + +% \def\stsec% +% {\rightskip=0pt % get out of C mode (cf. \B) +% \sfcode`;=1500 +% \pretolerance 200 +% \hyphenpenalty 50 +% \exhyphenpenalty 50 +% \noindent{\let\*=\lapstar\bf\secstar.\quad}} +% +% \let\startsection=\stsec + +\defCWEBmacro\defin#1% + {\global\advance\CWEBind by 2 \1\&{#1 } } % begin `define' or `format' + +% \def\A% xref for doubly defined section name +% {\note{See also section}} +% +% \def\As% xref for multiply defined section name +% {\note{See also sections}} + +\defCWEBmacro\B% + {\rightskip=0pt plus 100pt minus 10pt % go into C mode + \sfcode`;=3000 + \pretolerance 10000 + \hyphenpenalty 1000 % so strings can be broken (discretionary \ is inserted) + \exhyphenpenalty 10000 + \global\CWEBind=2 \1\ \unskip} + +\defCWEBmacro\C#1% + {\5\5\quad$/\ast\,${\cmntfont #1}$\,\ast/$} + +% \let\SHC\C % "// short comments" treated like "/* ordinary comments */" + +\defCWEBmacro\SHC#1% + {\5\5\quad$//\,${\cmntfont#1}} + +% \def\C#1{\5\5\quad$\triangleright\,${\cmntfont#1}$\,\triangleleft$} +% \def\SHC#1{\5\5\quad$\diamond\,${\cmntfont#1}} + +\defCWEBmacro\D% macro definition + {\defin{\#define}} + +\letCWEBmacro\E=\equiv % equivalence sign + +% \def\ET% conjunction between two section numbers +% { and~} +% +% \def\ETs% conjunction between the last two of several section numbers +% {, and~} + +\defCWEBmacro\F% format definition + {\defin{format}} + +\letCWEBmacro\G = \ge % greater than or equal sign + +% \H is long Hungarian umlaut accent + +\letCWEBmacro\I = \ne % unequal sign + +\defCWEBmacro\J% TANGLE's join operation + {\.{@\&}} + +% \let\K== % assignment operator + +\letCWEBmacro\K = \leftarrow % "honest" alternative to standard assignment operator + +% \L is Polish letter suppressed-L + +% \outer\def\M#1% +% {\MN{#1}% +% \ifon +% \vfil +% \penalty-100 +% \vfilneg % beginning of section +% \vskip\intersecskip +% \startsection +% \ignorespaces} +% +% \outer\def\N#1#2#3.% +% {\gdepth=#1% +% \gtitle={#3}% +% \MN{#2}% beginning of starred section +% \ifon +% \ifnum#1<\secpagedepth +% \vfil +% \eject % force page break if depth is small +% \else +% \vfil +% \penalty-100 +% \vfilneg +% \vskip\intersecskip +% \fi +% \fi +% \message{*\secno}% progress report +% \edef\next% +% {\write\cont % write to contents file +% {\ZZ{#3}{#1}{\secno}{\noexpand\the\pageno}}}% +% \next % \ZZ{title}{depth}{sec}{page} +% \ifon +% \startsection +% {\bf#3.\quad}% +% \ignorespaces} +% +% \def\MN#1% +% {\par % common code for \M, \N +% {\xdef\secstar{#1}% +% \let\*=\empty +% \xdef\secno{#1}}% remove \* from section name +% \ifx\secno\secstar +% \onmaybe +% \else +% \ontrue +% \fi +% \mark{{{\tensy x}\secno}{\the\gdepth}{\the\gtitle}}} +% +% each \mark is {section reference or null}{depth plus 1}{group title} + +% \O is Scandinavian letter O-with-slash +% \P is paragraph sign + +\defCWEBmacro\Q {\note{This code is cited in section}} % xref for mention of a section +\defCWEBmacro\Qs {\note{This code is cited in sections}} % xref for mentions of a section + +% \S is section sign + +\defCWEBmacro\T#1% + {\leavevmode % octal, hex or decimal constant + \hbox + {$\def\?{\kern.2em}% + \def\$##1{\egroup_{\,\rm##1}\bgroup}% suffix to constant + \def\_{\cdot 10^{\aftergroup}}% power of ten (via dirty trick) + \let\~=\oct + \let\^=\hex + {#1}$}} + +\defCWEBmacro\U {\note{This code is used in section}} % xref for use of a section +\defCWEBmacro\Us {\note{This code is used in sections}} % xref for uses of a section + +\letCWEBmacro\R = \lnot % logical not +\letCWEBmacro\V = \lor % logical or +\letCWEBmacro\W = \land % logical and + +% defined later on +% +% \def\X#1:#2\X% +% {\ifmmode +% \gdef\XX{\null$\null}% +% \else +% \gdef\XX{}% +% \fi % section name +% \XX$\langle\,${#2\eightrm\kern.5em#1}$\,\rangle$\XX} + +\unprotect + +\def\theCWEByskip {\blank[\v!small]} +\def\theCWEBvskip {\blank[\v!big]} + +\protect + +\defCWEBmacro\Y% + {\par + \yskip} + +\defCWEBmacro\yskip% + {\theCWEByskip} + +\letCWEBmacro\Z = \le +% \letCWEBmacro\ZZ = \let % now you can \write the control sequence \ZZ +\letCWEBmacro\* = * + +\defCWEBmacro\oct% + {\hbox{$^\circ$\kern-.1em\it\aftergroup\?\aftergroup}} + +\defCWEBmacro\hex% + {\hbox{$^{\scriptscriptstyle\#}$\tt\aftergroup}} + +\defCWEBmacro\vb#1% + {\leavevmode + \hbox + {\kern.2\CWEBpt + \vrule + \vtop + {\vbox + {\hrule + \hbox{\strut\kern.2\CWEBpt\.{#1}\kern.2\CWEBpt}} + \hrule}% + \vrule + \kern.2\CWEBpt}} % verbatim string + +\def\onmaybe% + {\let\ifon=\maybe} + +\let\maybe=\iftrue + +\newif\ifon + +% \newif\iftitle +% \newif\ifpagesaved +% +% \def\lheader% +% {\mainfont +% \the\pageno +% \eightrm +% \qquad +% \grouptitle +% \hfill +% \title +% \qquad +% \mainfont +% \topsecno} % top line on left-hand pages +% +% \def\rheader% +% {\mainfont +% \topsecno +% \eightrm +% \qquad +% \title +% \hfill +% \grouptitle +% \qquad +% \mainfont +% \the\pageno} % top line on right-hand pages +% +% \def\grouptitle +% {\let\i=I +% \let\j=J +% \uppercase\expandafter{\expandafter\takethree\topmark}} +% +% \def\topsecno% +% {\expandafter\takeone\topmark} +% +% \def\takeone #1#2#3{#1} +% \def\taketwo #1#2#3{#2} +% \def\takethree #1#2#3{#3} +% +% \def\nullsec% +% {\eightrm +% \kern-2em} % the \kern-2em cancels \qquad in headers +% +% \let\page=\pagebody % \def\page {\box255 } +% \raggedbottom % \normalbottom % faster, but loses plain TeX footnotes +% +% \def\normaloutput#1#2#3% +% {\shipout\vbox +% {\ifodd +% \pageno +% \hoffset=\pageshift +% \fi +% \vbox to \fullpageheight +% {\iftitle +% \global\titlefalse +% \else +% \hbox to \pagewidth +% {\vbox to 10pt{}% +% \ifodd\pageno #3\else#2\fi} +% \fi +% \vfill#1}} % parameter #1 is the page itself +% \global\advance\pageno by 1} +% +% \gtitle={\.{CWEB} output} % this running head is reset by starred sections +% +% \mark{\noexpand\nullsec0{\the\gtitle}} +% +% \def\title% +% {\expandafter\uppercase\expandafter{\jobname}} +% +% \def\topofcontents% +% {\centerline{\titlefont\title} +% \vskip.7in +% \vfill} % this material will start the table of contents page + +\def\botofcontents% + {\vfill + \centerline{\covernote}} % this material will end the table of contents page + +\def\covernote% + {} + +% some leftover + +\defCWEBmacro\contentspagenumber{0} % default page number for table of contents + +% \newdimen\pagewidth \pagewidth = 158mm % the width of each page +% \newdimen\pageheight \pageheight = 223mm % the height of each page +% \newdimen\fullpageheight \fullpageheight = 240mm % page height including headlines +% \newdimen\pageshift \pageshift = 0in % shift righthand pages wrt lefthand ones +% +% \def\magnify#1% +% {\mag=#1 +% \pagewidth=6.5truein +% \pageheight=8.7truein +% \fullpageheight=9truein +% \setpage} +% +% \def\setpage% +% {\hsize\pagewidth +% \vsize\pageheight} % use after changing page size +% +% \def\contentsfile {\jobname.toc} % file that gets table of contents info +% \def\readcontents {\input \contentsfile} +% \def\readindex {\input \jobname.idx} +% \def\readsections {\input \jobname.scn} +% +% \newwrite\cont +% \output{\setbox0=\page % the first page is garbage +% \openout\cont=\contentsfile +% \write\cont{\catcode `\noexpand\@=11\relax} % \makeatletter +% \global\output{\normaloutput\page\lheader\rheader}} +% \setpage +% \vbox to \vsize{} % the first \topmark won't be null + +\defCWEBdummy\magnify#1% magnify the page + {} + +\defCWEBmacro\ch% + {\note{The following sections were changed by the change file:} + \let\*=\relax} + +% \newbox\sbox % saved box preceding the index +% \newbox\lbox % lefthand column in the index +% +% \def\inx% +% {\par\vskip6pt plus 1fil % we are beginning the index +% \def\page{\box255 } +% \normalbottom +% \write\cont{} % ensure that the contents file isn't empty +% \write\cont{\catcode `\noexpand\@=12\relax} % \makeatother +% \closeout\cont % the contents information has been fully gathered +% \output +% {\ifpagesaved +% \normaloutput{\box\sbox}\lheader\rheader +% \fi +% \global\setbox\sbox=\page +% \global\pagesavedtrue} +% \pagesavedfalse +% \eject % eject the page-so-far and predecessors +% \setbox\sbox\vbox{\unvbox\sbox} % take it out of its box +% \vsize=\pageheight +% \advance\vsize by -\ht\sbox % the remaining height +% \hsize=.5\pagewidth +% \advance\hsize by -10pt +% % column width for the index (20pt between cols) +% \parfillskip 0pt plus .6\hsize % try to avoid almost empty lines +% \def\lr{L} % this tells whether the left or right column is next +% \output +% {\if L\lr +% \global\setbox\lbox=\page +% \gdef\lr{R} +% \else +% \normaloutput +% {\vbox to\pageheight +% {\box\sbox +% \vss +% \hbox to\pagewidth{\box\lbox\hfil\page}}} +% \lheader +% \rheader +% \global\vsize\pageheight\gdef\lr{L}\global\pagesavedfalse\fi} +% \message{Index:} +% \parskip 0pt plus .5pt +% \outer\def\I##1, {\par\hangindent2em\noindent##1:\kern1em} % index entry +% \def\[##1]{$\underline{##1}$} % underlined index item +% \rm +% \rightskip0pt plus 2.5em +% \tolerance 10000 +% \let\*=\lapstar +% \hyphenpenalty 10000 +% \parindent0pt +% \readindex} +% +% \def\fin% +% {\par\vfill\eject % this is done when we are ending the index +% \ifpagesaved\null\vfill\eject\fi % output a null index column +% \if L\lr\else\null\vfill\eject\fi % finish the current page +% \parfillskip 0pt plus 1fil +% \def\grouptitle{NAMES OF THE SECTIONS} +% \let\topsecno=\nullsec +% \message{Section names:} +% \output={\normaloutput\page\lheader\rheader} +% \setpage +% \def\note##1##2.{\quad{\eightrm##1~##2.}} +% \def\Q{\note{Cited in section}} % crossref for mention of a section +% \def\Qs{\note{Cited in sections}} % crossref for mentions of a section +% \def\U{\note{Used in section}} % crossref for use of a section +% \def\Us{\note{Used in sections}} % crossref for uses of a section +% \def\I{\par\hangindent 2em}\let\*=* +% \readsections} +% +% \def\con% +% {\par\vfill\eject % finish the section names +% %\ifodd\pageno\else\titletrue\null\vfill\eject\fi % for duplex printers +% \rightskip = 0pt +% \hyphenpenalty = 50 +% \tolerance = 200 +% \setpage +% \output={\normaloutput\page\lheader\rheader} +% \titletrue % prepare to output the table of contents +% \pageno=\contentspagenumber +% \def\grouptitle{TABLE OF CONTENTS} +% \message{Table of contents:} +% \topofcontents +% \line{\hfil Section\hbox to3em{\hss Page}} +% \let\ZZ=\contentsline +% \readcontents\relax % read the contents info +% \botofcontents +% \end} % print the contents page(s) and terminate +% +% \def\contentsline#1#2#3#4% +% {\ifnum#2=0 +% \smallbreak +% \fi +% \line{\consetup{#2}#1 +% \rm\leaders\hbox to .5em{.\hfil}\hfil\ #3\hbox to3em{\hss#4}}} +% + +\defCWEBmacro\consetup#1% + {\ifcase#1 \bf % depth -1 (@**) + \or % depth 0 (@*) + \or \hskip2em % depth 1 (@*1) + \or \hskip4em % depth 2 (@*2) + \or \hskip6em % depth 3 (@*3) + \or \hskip8em % depth 4 (@*4) + \or \hskip10em % depth 5 (@*5) + \else \hskip12em + \fi} % depth 6 or more + +\defCWEBdummy \inx {} % index +\defCWEBdummy \fin {} % finish +\defCWEBdummy \con {} % table of contents and finish + +\defCWEBdummy \noinx {} % no indexes or table of contents +\defCWEBdummy \nosecs {} % no index of section names or table of contents +\defCWEBdummy \nocon {} % no table of contents + +\defCWEBmacro\,% + {\relax + \ifmmode + \mskip\thinmuskip + \else + \thinspace + \fi} + +% \def\noinx% +% {\let\inx=\end} +% +% \def\nosecs% +% {\let\FIN=\fin +% \def\fin% +% {\let\parfillskip=\end +% \FIN}} +% +% \def\nocon% +% {\let\con=\end} +% +% \newcount\twodigits +% +% \def\hours% +% {\twodigits=\time +% \divide\twodigits by 60 +% \printtwodigits +% \multiply\twodigits by -60 +% \advance\twodigits by \time +% :\printtwodigits} +% +% \def\gobbleone1{} +% +% \def\printtwodigits% +% {\advance\twodigits by 100 +% \expandafter\gobbleone\number\twodigits +% \advance\twodigits by -100 } +% +% \def\today% +% {\ifcase\month +% \or January\or February\or March\or April\or May\or June% +% \or July\or August\or September\or October\or November\or December% +% \fi +% \space +% \number\day, \number\year} +% +% \def\datethis% +% {\def\startsection% +% {\leftline{\sc\today\ at \hours} +% \bigskip +% \let\startsection=\stsec +% \stsec}} +% +% \def\datecontentspage% +% {\def\topofcontents% +% {\leftline{\sc\today\ at \hours} +% \bigskip +% \centerline{\titlefont\title} +% \vfill}} + +\defCWEBdummy\datethis {} % say `\datethis' in limbo, to get your listing timestamped before section 1 +\defCWEBdummy\datecontentspage {} % timestamps the contents page + +\defCWEBmacro\TeX% + {{\ifmmode\it\fi + \leavevmode + \hbox{T\kern-.1667em\lower.424ex\hbox{E}\hskip-.125em X}}} + +% alternative implementation + +\newif\ifCWEBnotes + +\defCWEBmacro\Q {\CWEBnotesfalse \note{This code is cited in section}} % xref for mention of a section +\defCWEBmacro\Qs {\CWEBnotestrue \note{This code is cited in sections}} % xref for mentions of a section + +\defCWEBmacro\U {\CWEBnotesfalse \note{This code is used in section}} % xref for use of a section +\defCWEBmacro\Us {\CWEBnotestrue \note{This code is used in sections}} % xref for uses of a section + +\defCWEBmacro\A {\CWEBnotesfalse \note{See also section}} % xref for doubly defined section name +\defCWEBmacro\As {\CWEBnotestrue \note{See also sections}} % xref for multiply defined section name + +\defCWEBmacro\ET% conjunction between two section numbers + { and~} + +\defCWEBmacro\ETs% conjunction between the last two of several section numbers + {, and~} + +%\def\processCWEBsectionnumbers[#1]% +% {\bgroup +% \def\CWEBcomma% +% {\def\CWEBcomma{, }}% +% \def\docommand##1% +% {\bgroup +% \def\[####1]{####1}% +% \xdef\CWEBreference{##1}% +% \egroup +% \CWEBcomma{\naar{\donottest{##1}}[web:\CWEBreference]}}% +% \processcommalist[{#1}]\docommand +% \egroup} + +% \def\processCWEBsectionnumbers[#1]% +% {\bgroup +% \def\CWEBcomma% +% {\def\CWEBcomma{, }}% +% \def\docommand##1% +% {\bgroup +% \def\(####1){####1}% +% \xdef\CWEBreference{##1}% +% \egroup +% \CWEBcomma +% {\localcolortrue\naar{\donottest{##1}}[web:\CWEBreference]}}% +% \bgroup +% \def\[##1]{\(##1)}\let\(=\relax\xdef\CWEBreferences{#1}% +% \egroup +% \unexpanded\def\(##1){\[##1]}% +% \processcommacommand[\CWEBreferences]\docommand +% \egroup} + +\def\processCWEBsectionnumbers[#1]% + {\bgroup + \def\CWEBcomma% + {\def\CWEBcomma{, }}% + \def\docommand##1% + {\bgroup + \def\[####1]{####1}% + \xdef\CWEBreference{##1}% + \egroup + \CWEBcomma{\localcolortrue\goto{\donottest{##1}}[web:\CWEBreference]}}% + \processlist{(}{)}{,}\docommand(#1) + \egroup} + +\def\processCWEBsectionnotes% + {\catcode`\s=12 + \doprocessCWEBsectionnotes} + +\def\doprocessCWEBsectionnotes#1.% + {\ifCWEBnotes + \def\next##1\ET##2##3.% + {\processCWEBsectionnumbers[##1]% + \if##2s% + {, and~\goto{##3}[web:##3]}% + \else + { and~\goto{##2##3}[web:##2##3]}% + \fi}% + \next#1.% + \else + \goto{#1}[web:#1]% + \fi + \afterCWEBnote % inside group! + \egroup} + +\let\afterCWEBnote=\relax + +\defCWEBmacro\note#1% + {\bgroup + \Y\noindent + \def\afterCWEBnote{\par}% + \hangindent2em + %\baselineskip10pt + \eightrm#1~\processCWEBsectionnotes} + +\def\oldCWEBmacroX#1:#2\X% original + {\ifmmode + \gdef\XX{\null$\null}% + \else + \gdef\XX{}% + \fi % section name + \XX$\langle\,${#2\eightrm\kern.5em#1}$\,\rangle$\XX} + +\defCWEBmacro\ATH% + {\oldCWEBmacroX\kern-.5em:Preprocessor definitions\X} + +\def\newCWEBmacroX#1:#2\X% original + {\ifmmode + \gdef\XX{\null$\null}% + \else + \gdef\XX{}% + \fi % section name + \XX$\langle\,$% + {#2\eightrm\kern.5em\processCWEBsectionnumbers[{#1}]}% + $\,\rangle$\XX} + +\defCWEBmacro\X#1:#2\X% + {\newCWEBmacroX#1:#2\X} + +\definemarking[CWEBfilename] +\definemarking[CWEBsectiontitle] +\definemarking[CWEBsectionnumber] +\definemarking[CWEBsectiondepth] + +\defCWEBmacro\M#1% + {\MN{#1}% + \ifon + \vfil + \penalty-100 + \vfilneg % beginning of section + \theCWEBvskip + \startsection + \pagereference[web:#1]% + \expanded{\marking[CWEBsectionnumber]{\secno}}% + \expanded{\marking[CWEBsectiondepth]{\the\gdepth}}% + \ignorespaces} + +\defCWEBmacro\N#1#2#3.% + {\gdepth=#1% + \MN{#2}% beginning of starred section + \ifon + \ifnum#1<\secpagedepth + \vfil + \eject % force page break if depth is small + \else + \vfil + \penalty-100 + \vfilneg + \theCWEBvskip + \fi + \fi + \message{*\secno}% progress report + \makesectionformat % context + \defconvertedargument\ascii{#3}% + \edef\next% + {\write\CWEBcont % write to contents file + {\string\ZZ{\ascii}{#1}{\secno}% + {\sectionformat::\noexpand\userfolio}{\noexpand\realfolio}}}% + \next % \ZZ{title}{depth}{sec}{page} + \ifon + \startsection + \pagereference[web:#2]% + \marking[CWEBsectiontitle] {#3}% + \expanded{\marking[CWEBsectionnumber]{\secno}}% + \expanded{\marking[CWEBsectiondepth]{\the\gdepth}}% + {\bf#3.\quad}% + \ignorespaces} + +\defCWEBmacro\MN#1% + {\par % common code for \M, \N + {\xdef\secstar{#1}% + \let\*=\empty + \xdef\secno{#1}}% remove \* from section name + \ifx\secno\secstar + \onmaybe + \else + \ontrue + \fi} + +\newif\iflinktoCWEBfile + +\def\setCWEBlinkfile#1% + {\linktoCWEBfiletrue + \def\otherCWEBfile{#1}} + +\unprotect + +\def\gotoCWEBsection#1[#2]% + {\iflinktoCWEBfile + \bgroup + \setupinteraction[\c!color=,\c!style=]% + \let\savedreferenceprefix=\referenceprefix + \localcolortrue + \goto{#1}[\otherCWEBfile::\savedreferenceprefix web:#2]% + \egroup + \else + #1% + \fi} + +\protect + +\defCWEBmacro\startsection% + {\rightskip=0pt % get out of C mode (cf. \B) + \sfcode`;=1500 + \pretolerance 200 + \hyphenpenalty 50 + \exhyphenpenalty 50 + \noindent + \bgroup + \let\*=\lapstar + \gotoCWEBsection{\bf\secstar.\quad}[\secno]% + \egroup} + +\def\ignoreCWEBinput% + {\let\normalinput=\input + \def\input ##1 % + {\let\input=\normalinput}} + +\def\loadCWEBmacros#1% + {\let\oldN=\N + \def\N{\bgroup\setbox0=\vbox\bgroup\endinput}% + \ignoreCWEBinput + \ReadFile{#1.tex}% + \egroup\egroup + \let\N=\oldN} + +\def\resetCWEBcontext% + {\catcode`\|=12 % used in context discretionaries + \everypar{} % used for context indentation and floats + \parskip=0pt % no stretch between cweb paragraphs + \parindent=1em} % is related to cweb backspace etc + +\newwrite\CWEBcont + +\def\processCWEBsource #1 % + {\bgroup + \resetCWEBcontext + \activateCWEB + \ignoreCWEBinput + \immediate\openout\CWEBcont=#1.toc + \write\CWEBcont{\noexpand\unprotect} + \message{Source:} + \marking[CWEBfilename]{#1} + \ReadFile{#1.tex}\relax + \write\CWEBcont{\noexpand\protect} + \closeout\CWEBcont + \par + \egroup} + +\def\resetCWEBindexentry% + {\xdef\currentCWEBindexentry{}} + +\def\showCWEBindexentry#1% can be redefined + {\theCWEBvskip + \vskip3\lineheight + \goodbreak + \vskip-3\lineheight + {\pagereference[web:#1]\bf#1}% + \theCWEBvskip} + +\def\checkCWEBindexentry#1% + {\bgroup + \def\\##1{##1}% a dummy that also removes the {} + \def\|##1{##1}% another dummy + \def\.##1{*##1}% and another (the typewriter one) + \def\&##1{##1}% and a last one + \def\9##1{##1}% hold this one + \catcode`*=11 + \expandafter\def\expandafter\entry\expandafter{#1}% + \defconvertedcommand\ascii\entry + \expanded{\FINDFIRSTCHARACTER{\ascii}}% + \doifnot{\currentCWEBindexentry}{\firstcharacter} + {\doifnot{\firstcharacter}{*} % signal for \firstbunch + {\global\let\currentCWEBindexentry=\firstcharacter + \showCWEBindexentry{\currentCWEBindexentry}}}% + \egroup} + +\def\theCWEBbeforeindex {\startcolumns} +\def\theCWEBafterindex {\stopcolumns} + +\def\processCWEBindex #1 % + {\bgroup + \resetCWEBcontext + \activateCWEB + \resetCWEBindexentry + \def\I##1, % + {\par + \checkCWEBindexentry{##1}% + \hangindent2em + \noindent##1:\kern1em% + \def\next####1.% + {\processCWEBsectionnumbers[{####1}]}% + \next}% + \def\[##1]% + {$\underline{##1}$}% + \let\*=\lapstar + \parfillskip 0pt plus .6\hsize % try to avoid almost empty lines +% \parskip 0pt plus .5pt + \rightskip0pt plus 2.5em + \tolerance 10000 + \hyphenpenalty 10000 + \parindent0pt + \message{Index:} + \marking[CWEBfilename] {#1} + \marking[CWEBsectiontitle] {index} + \marking[CWEBsectionnumber]{} + \marking[CWEBsectiondepth]{} + \loadCWEBmacros{#1} + \theCWEBbeforeindex + \ReadFile{#1.idx}\relax + \theCWEBafterindex + \par + \egroup} + +\def\processCWEBsections #1 % + {\bgroup + \resetCWEBcontext + \activateCWEB + \loadCWEBmacros{#1} + \parfillskip = 0pt plus 1fil + \parindent = 0pt + \let\topsecno=\nullsec + \def\note##1% + {\quad + \bgroup + \eightrm + ##1~\processCWEBsectionnotes} + \def\Q {\CWEBnotesfalse \note{Cited in section}} % crossref for mention of a section + \def\Qs{\CWEBnotestrue \note{Cited in sections}} % crossref for mentions of a section + \def\U {\CWEBnotesfalse \note{Used in section}} % crossref for use of a section + \def\Us{\CWEBnotestrue \note{Used in sections}} % crossref for uses of a section + \def\I {\par\hangindent 2em}% + \let\*=* + \message{Section names:} + \marking[CWEBfilename] {#1} + \marking[CWEBsectiontitle] {sections} + \marking[CWEBsectionnumber]{} + \marking[CWEBsectiondepth]{} + \loadCWEBmacros{#1} + \ReadFile{#1.scn}\relax + \par + \botofcontents + \par + \egroup} + +\def\processCWEBcontents #1 % + {\bgroup + \resetCWEBcontext + \activateCWEB + \loadCWEBmacros{#1} + \rightskip = 0pt + \hyphenpenalty = 50 + \tolerance = 200 + \parindent = 0pt + \line{\hfil Section\hbox to3em{\hss Page}} + \let\ZZ=\contentsline + \message{Table of contents:} + \marking[CWEBfilename] {#1} + \marking[CWEBsectiontitle] {table of contents} + \marking[CWEBsectionnumber]{} + \marking[CWEBsectiondepth]{} + \loadCWEBmacros{#1} + \ReadFile{#1.toc}\relax + \par + \egroup} + +\defCWEBmacro\contentsline#1#2#3#4#5% + {\ifnum#2=0 + \smallbreak + \fi + \line{\consetup{#2}#1 + \rm + \leaders\hbox to .5em{.\hfil}\hfil\ + {\localcolortrue\goto{#3}[web:#3]}% below: \gotorealpage ? should be changed + \hbox to3em{\localcolortrue\hss\gotorealpage{}{}{#5}{\translatednumber[#4]\presetgoto}}}} + +%D A last hack, needed because a file can overload of the +%D above. (Some day: a check like \type{\ifx#1\CWEBdefined}.) + +\def\outer#1#2% + {\ifx#2\undefined + \expandafter#1\expandafter#2% + \else + \expandafter#1\expandafter\ThrowAway + \fi} + +\endinput diff --git a/tex/context/base/m-database.tex b/tex/context/base/m-database.tex new file mode 100644 index 000000000..3bb050f14 --- /dev/null +++ b/tex/context/base/m-database.tex @@ -0,0 +1,421 @@ +%D \module +%D [ file=m-database, +%D version=2006.04.23, +%D title=\CONTEXT\ Modules, +%D subtitle=Database Thingies, +%D author=Hans Hagen\& Taco Hoekwater, +%D date=\currentdate, +%D copyright=PRAGMA +%D ] + +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\unprotect + +% % % to be added to mult-* files +% +% % % todo: \dontcollectseparatedlist via k/v + +\definesystemvariable{ls} + +\def\c!first {first} +\def\c!last {last} +\def\c!quotechar {quotechar} + +\let\@NX\noexpand + +%D {processquotedlist} +%D +%D An even more general list processing macro is the +%D following one: +%D +%D \starttyping +%D \processquotedlist{beginsym}{endsym}{separator}\docommand list +%D \stoptyping +%D +%D This one supports arbitrary open and close symbols as well +%D as user defined separators. +%D +%D \starttyping +%D \processquotedlist(){,}{"}\docommand(a=>b=>c=>d) +%D \stoptyping + +\def\processquotedlist#1#2#3#4#5% + {\def\csvquotechar{#4}% + \edef\doconvertcsvquoteditem#4##1#4##2% + {\@NX\ifx##2#3% + \let\@NX\next\@NX\doconvertcsvlist + \def\@NX\arg{#3}% + \edef\@NX\temp{##1}% + \@NX\expanded{\@NX#5{\@NX\temp}}% + \@NX\else + \let\@NX\next\@NX\redoconvertcsvquoteditem + \def\@NX\arg{##1\@NX\csvquotechar}% + \@NX\fi + \@NX\expandafter\@NX\next\@NX\arg}% + \edef\redoconvertcsvquoteditem##1#4##2% + {\@NX\ifx##2#3% + \let\@NX\next\@NX\doconvertcsvlist + \def\@NX\arg{#3}% + \edef\@NX\temp{##1}% + \@NX\expanded{\@NX#5{\@NX\temp}}% + \@NX\else + \let\@NX\next\@NX\redoconvertcsvquoteditem + \def\@NX\arg{##1\@NX\csvquotechar}% + \@NX\fi + \@NX\expandafter\@NX\next\@NX\arg}% + \edef\doconvertcsvitem##1#3% + {\edef\@NX\temp{##1}% + \@NX\expanded{\@NX#5{\@NX\temp}}% + \@NX\doconvertcsvlist#3}% + \edef\doconvertcsvlist#3##1% + {\@NX\ifx##1\@NX#2% + \let\@NX\next \@NX\gobbleoneargument + \@NX\else\@NX\ifx##1#4% + \let\@NX\next \@NX\doconvertcsvquoteditem + \@NX\else + \let\@NX\next \@NX\doconvertcsvitem + \@NX\fi\@NX\fi \@NX\next##1}% + \doconvertcsvitem} + +\gdef\doprocessseparatedquoteditem#1% + {\appendseparatedlistparameter\c!left% + \appendseparatedlistcontent{#1}% + \appendseparatedlistparameter\c!right} + +% a version more robust with regard to {a a} b c d situations: + +\edef\detokenizedrelax{\detokenize{\relax}} + +\edef\processseplistseparator{\detokenize{,}}% + +\def\dodefineprocessseplist#1#2% separator \docommand + {\edef\processseplistseparator{\detokenize{#1}}% + \def\dodoprocessseplist##1##2#1% + {\edef\!!stringa{\detokenize{##1}}% + \ifx\detokenizedrelax\!!stringa + \expandafter\nodoprocessseplist + % \else\ifx\!!stringa#1% + \else\ifx\!!stringa\processseplistseparator + #2{}% + #2{##2}% + \expandafter\expandafter\expandafter\dodoprocessseplist + \else + #2{##1##2}% + \expandafter\expandafter\expandafter\dodoprocessseplist + \fi\fi}% + \def\doprocessseplist##1\relax + {\dodoprocessseplist##1#1\relax#1\relax\relax\end}} + +\def\nodoprocessseplist#1\end + {} + +\long\def\processseplist#1#2#3\relax raw version + {\dodefineprocessseplist{#1}{#2}% + \dodoprocessseplist#3#1\relax#1\relax\relax\end} + +% \dodefineprocessseplist{,}\test +% \dodoprocessseplist{,}a,b,c\relax,\relax\relax\end +% \doprocessseplista,b,c\relax + +% \def\test#1{[#1]} +% \startlines +% \processseplist{,}\test ,2,,\relax +% \processseplist{,}\test ,,,44\relax +% \processseplist{,}\test ,,33,44\relax +% \processseplist{,}\test 11,,33,44\relax +% \processseplist{,}\test 1,2,3,4\relax +% \stoplines + +\newtoks\separatedlistdata + +\def\appendseparatedlistparameter#1% + {\@EAEAEA\appendtoks\csname\??ls\currentseparatedlist#1\endcsname\to\separatedlistdata} + +\def\appendseparatedlistcontent#1% + {\appendtoks#1\to\separatedlistdata} + +\def\flushseparatedlistdata + {\the\separatedlistdata + \separatedlistdata\emptytoks} + +\def\initializeseparatedlistdata + {\separatedlistdata{\egroup}} + +\def\dontcollectseparatedlist + {\def\dodoprocessseparatedfileline + {\the\separatedlistdata + \separatedlistdata\emptytoks + \doprocessseparatedfileline}% + \def\dodoprocessseparatedline + {\the\separatedlistdata + \separatedlistdata\emptytoks + \doprocessseparatedline}% + \let\flushseparatedlistdata\egroup + \let\initializeseparatedlistdata\donothing} + +\chardef\separatedlistmode\zerocount + +\def\setcurrentlistseparator + {\edef\currentlistseparator + {\executeifdefined + {\??ls::\csname\??ls\currentseparatedlist\c!separator\endcsname}% + {\csname\??ls\currentseparatedlist\c!separator\endcsname}}% + \doifvalue{\??ls\currentseparatedlist\c!separator}{tab} + {\catcode`\^^I=12\relax}% + \ifx\currentlistseparator\empty\def\currentlistseparator{,}\fi} + +\bgroup \catcode`\^^I=12 + \setgvalue{\??ls::tab}{ } + \setgvalue{\??ls::space}{ } + \setgvalue{\??ls::comma}{,} +\egroup + +\def\doprocessseparatedfileline + {\ifeof\scratchread + \ifcase\separatedlistmode\appendseparatedlistparameter\c!after\fi + \immediate\closein\scratchread + \expandafter\flushseparatedlistdata + \else\ifx\line\empty + % skip, can be comment + \read\scratchread to\line + \@EA\dodoprocessseparatedfileline + \else + \appendseparatedlistparameter{\ifcase\separatedlistmode\c!first\else\c!command\fi}% + \ifx\currentlistquotechar\empty% + \expandafter\doprocessseplist\line\relax + \else + \expanded{\processquotedlist{}{\noexpand\end}% + {\currentlistseparator}{\currentlistquotechar}% + \noexpand\doprocessseparatedquoteditem \line\currentlistseparator\noexpand\end}% + \fi + \ifcase\separatedlistmode\appendseparatedlistparameter\c!last\fi + \read\scratchread to\line + \@EAEAEA\dodoprocessseparatedfileline + \fi\fi} + +\def\dodoprocessseparatedfileline + {\doprocessseparatedfileline} + +\def\doprocessseparatedfile[#1][#2]% + {\bgroup + \edef\currentseparatedlist{#1}% + \doifdefined{\??ls\currentseparatedlist\c!command}{\chardef\separatedlistmode\plusone}% + \setcurrentlistseparator + \edef\currentlistquotechar{\csname\??ls\currentseparatedlist\c!quotechar\endcsname}% + \expandafter\dodefineprocessseplist\expandafter{\currentlistseparator}\doprocessseparateditem + \initializeseparatedlistdata + \directsetup{\currentseparatedlist:\executeifdefined{\??ls\currentseparatedlist\c!setups}\s!default}% + \ifcase\separatedlistmode\appendseparatedlistparameter\c!before\fi + \endlinechar\minusone + \ignorelines + \catcode`\#\@@comment + \immediate\openin\scratchread=#2\relax % todo: \doopenin + \read\scratchread to\line + \doprocessseparatedfileline} + +\def\dostartseparatedlist#1[#2]% + {\bgroup + \edef\currentseparatedlist{#2}% + \doifdefined{\??ls\currentseparatedlist\c!command}{\chardef\separatedlistmode\plusone}% + \obeylines + \let#1\relax + \def\separateslistend{#1}% + \setcurrentlistseparator + \edef\currentlistquotechar{\csname\??ls\currentseparatedlist\c!quotechar\endcsname}% + \expandafter\dodefineprocessseplist\expandafter{\currentlistseparator}\doprocessseparateditem + \directsetup{\currentseparatedlist:\executeifdefined{\??ls\currentseparatedlist\c!setups}\s!default}% + \initializeseparatedlistdata + \ifcase\separatedlistmode\appendseparatedlistparameter\c!before\fi + \dodostartseparatedlist} + +\def\redoprocessseparatedline#1% + {\def\!!stringa{#1}% + \ifx\!!stringa\separateslistend + \ifcase\separatedlistmode\appendseparatedlistparameter\c!after\fi + \expandafter\flushseparatedlistdata + \else% + \appendseparatedlistparameter{\ifcase\separatedlistmode\c!first\else\c!command\fi}% + \ifx\currentlistquotechar\empty% + \doprocessseplist#1\relax + \else% + \defconvertedargument\csvdata{#1}% + \expanded{\processquotedlist{}{\noexpand\end}% + {\currentlistseparator}{\currentlistquotechar}% + \noexpand\doprocessseparatedquoteditem \csvdata\currentlistseparator\noexpand\end}% + \fi + \ifcase\separatedlistmode\appendseparatedlistparameter\c!last\fi + \expandafter\dodoprocessseparatedline + \fi} + +\def\doprocessseparatedline + {\doifnextbgroupelse\xdoprocessseparatedline\ydoprocessseparatedline} + +\def\dodoprocessseparatedline + {\doprocessseparatedline} + +\def\doprocessseparateditem#1% + {\ifcase\separatedlistmode + \appendseparatedlistparameter\c!left + \appendseparatedlistcontent{#1}% + \appendseparatedlistparameter\c!right + \else + \appendseparatedlistcontent{{#1}}% + \fi} + + +\bgroup \obeylines + + \gdef\dodostartseparatedlist#1 + {\doprocessseparatedline} + + \gdef\xdoprocessseparatedline#1#2 + {\redoprocessseparatedline{{{#1}}#2}} + + \gdef\ydoprocessseparatedline#1 + {\redoprocessseparatedline{#1}} + +\egroup + +\startsetups CSV:unix + \catcode`\#=\@@comment +\stopsetups + +\def\defineseparatedlist + {\dodoubleempty\dodefineseparatedlist} + +\def\dodefineseparatedlist[#1][#2]% + {\setvalue{\e!start#1}{\expandafter\dostartseparatedlist\csname\e!stop#1\endcsname[#1]}% + \getparameters + [\??ls#1] + [\c!separator=, + \c!quotechar=, + \c!first=, + \c!left=, + \c!before=, + \c!right=, + \c!last=, + \c!after=, +% \c!command=, + #2]} + +\def\setupseparatedlist + {\dodoubleempty\dosetupseparatedlist} + +\def\dosetupseparatedlist[#1]% [#2] + {\getparameter[\??ls#1]} % [#2] + +\def\startseparatedlist[#1]% + {\dostartseparatedlist\stopseparatedlist[#1]} + +\def\processseparatedfile + {\dodoubleargument\doprocessseparatedfile} + +\protect \doifnotmode{demo}{\endinput} + +\defineseparatedlist + [CSV] + [separator={,}, + first=\bTR,last=\eTR, + left=\bTD,right=\eTD, + before=\bTABLE,after=\eTABLE] + +\startseparatedlist[CSV] +a,b,c +d,e,f +\stopseparatedlist + +\startCSV +a,b,c +d,e,f +\stopCSV + +\defineseparatedlist + [CSV] + [separator={,}, + quotechar={"}, + first=\NC,last=\NR, + left=,right=\NC, + before={\starttabulate[|l|l|l|]},after=\stoptabulate] + +\startCSV +a,b,"c,d" +d,"""",f +\stopCSV + +\defineseparatedlist + [CSV] + [separator={ }, + first=\NC,last=\NR, + left=,right=\NC, + before={\starttabulate[|l|l|l|]},after=\stoptabulate] + +\startCSV +a b c +d e f +\stopCSV + +\defineseparatedlist + [CSV] + [setups=unix, + first=\NC,last=\NR, + left=,right=\NC, + before={\starttabulate[|l|l|l|]},after=\stoptabulate] + +% \startsetups CSV:unix +% \catcode`\#=\@@comment +% \stopsetups + +% %1,2,3 +% 1,2,3 +% # 4,5,6 +% 4,5,6 + +\processseparatedfile[CSV][test.dat] + +\defineseparatedlist + [CSVX] + [command=\Whatever, + separator={,}, + first=\bTR,last=\eTR, + left=\bTD,right=\eTD, + before=\bTABLE,after=\eTABLE] + +\def\Whatever#1#2#3{[#1][#2][#3]\endgraf} + +\startseparatedlist[CSVX] +a,b,c +d,e,f +\stopseparatedlist + +\defineseparatedlist[CSV] + [separator=comma, + before=\bTABLE, after=\eTABLE, + first=\bTR, last=\eTR, + left=\bTD, right=\eTD] + +\startCSV +a,b,c,č +d,e,f,š +\stopCSV + +\enableregime[utf] + +\defineseparatedlist[X][separator=X,left=(,right=),first=\endgraf,last=\endgraf] +\defineseparatedlist[Y][separator=Y,left=(,right=),first=\endgraf,last=\endgraf] + +\startX +aXb +Xc +čXš +\stopX + +\startY +aYb +Yc +čYš +\stopY + +\stoptext diff --git a/tex/context/base/m-datastrc.tex b/tex/context/base/m-datastrc.tex new file mode 100644 index 000000000..4a6faa66b --- /dev/null +++ b/tex/context/base/m-datastrc.tex @@ -0,0 +1,228 @@ +%D \module +%D [ file=m-datastrc, % was: core-dat % was core-02a +%D version=1999.08.10, % 1997.03.31, +%D title=\CONTEXT\ Modules, +%D subtitle=Database Support, % 2A +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Database Support} + +\unprotect + +%D This module is a (limited) rewrite of the original \type +%D {core-02a} module, the module that dealt with managing a +%D database of addresses. The principles and methods have not +%D changed; they are only generalized. +%D +%D A database file |<|in most cases such a base is generated +%D from another one|>| is structured as follows: +%D +%D \starttyping +%D \startrecord{tag} +%D \memberofgroup{grouplist} +%D \setrecordentry{name}{...} +%D .... +%D \stoprecord +%D \stoptyping +%D +%D The interface to such a database is defined as follows: +%D +%D \starttyping +%D \definerecord[class][settings] +%D \setuprecord[class][settings] +%D \definerecordentry[class][name] +%D \stoptyping +%D +%D and processed by +%D +%D \starttyping +%D \processrecords[file list][tag and/or group list] +%D \stoptyping +%D +%D The actual processing is done by a macro assigned to \type +%D {command}: +%D +%D \starttyping +%D \setuprecord[class][command=\DoWithRecord] +%D \stoptyping +%D +%D Given that one can ask for a field with +%D +%D \starttyping +%D \getrecordentry{name} +%D \stoptyping +%D +%D such a command can look like: +%D +%D \starttyping +%D \def\DoWithRecord#1% +%D {\startpacked +%D \let\\=\quad +%D name: \getrecordentry{name}~\getrecordentry{family name}\par +%D address: \getrecordentry{postal address}\par +%D \stoppacked} +%D \stoptyping +%D +%D The argument passed is the tag. The database can look like: +%D +%D \starttyping +%D \startrecord{hagenj} +%D \memberofgroup{a,b} +%D \setrecordentry{naam}{Hans} +%D \setrecordentry{family name}{Hagen} +%D \setrecordentry{postal address}{J. Hagen\\Ridderstraat 29\\Hasselt NL} +%D \stoprecord +%D +%D \startrecord{ottenaf} +%D \memberofgroup{a} +%D \setrecordentry{name}{Ton} +%D \setrecordentry{family name}{Otten} +%D \setrecordentry{postal address}{A.F. Otten\\Prinsengracht 17\\Hasselt NL} +%D \stoprecord +%D \stoptyping +%D +%D The definition of this database looks like: +%D +%D \starttyping +%D \definerecord[address][command=\DoWithRecord] +%D +%D \definerecordentry[address][name] +%D \definerecordentry[address][family name] +%D \definerecordentry[address][postal address] +%D \stoptyping +%D +%D The actual processing is now done by (for instance): +%D +%D \starttyping +%D \processrecords[datafile][hagenj] +%D \processrecords[datafile][hagenj,offenaf] +%D \processrecords[datafile][all] +%D \processrecords[datafile][a] +%D \processrecords[datafile][b] +%D \stoptyping +%D +%D Of course one can reassign the command used to handle the +%D records in between. + +% \??kt -> +% \??kw -> + +\def\??db {@@db} +\def\c!velden{velden} + +%\newevery \everyrecord \EveryRecord + +\def\definerecord + {\dodoubleempty\dodefinerecord} + +\def\dodefinerecord[#1][#2]% + {\getparameters + [\??db#1] + [\c!velden=, + \c!command=\gobbleoneargument, + #2]} + +\def\setuprecord + {\dodoubleargument\dosetuprecord} + +\def\dosetuprecord[#1][#2]% + {\getparameters[\??db#1][#2]}% + +\def\definerecordentry[#1][#2]% + {\edef\recordentries{\getvalue{\??db#1\c!velden}}% + \addtocommalist{#2}\recordentries + \letvalue{\??db#1\c!velden}\recordentries} + +%D Watch out: the entries are defined global! While +%D processing a record, no grouping is applied. + +\def\getrecordentry #1{\getvalue {\??db:#1}} +\def\resetrecordentry #1{\letgvalueempty{\??db:#1}} +\def\assignrecordentry#1{\setgvalue {\??db:#1}} + +\long\def\skiprecord#1\stoprecord + {\egroup} + +\newif\ifrecordok + +\newtoks\resetrecordlist + +\def\processrecords + {\dotripleargument\doprocessrecords} + +\def\doprocessrecords[#1][#2][#3]% + {\bgroup + \ifx\\\undefined\let\\\relax\fi + \def\docommand##1% + {\resetrecordentry{##1}% + \appendtoks\resetrecordentry{##1}\to\resetrecordlist}% + \processcommacommand[\getvalue{\??db#1\c!velden}]\docommand + \let\setrecordentry\skiprecord + \the\resetrecordlist + \doifelse{#2}\v!all % 't Is nu eenmaal alles + \recordoktrue + {\doifelsenothing{#2} % of niets + \recordoktrue + \recordokfalse}% % zullen we maar zeggen. + \ifrecordok + \let\askedrecords\v!all + \else + \makerawcommalist[#2]\askedrecords + \fi + \def\checkrecord##1% + {\rawdoifinsetelse{##1}{\askedrecords}{\recordoktrue}{}}% + \def\presetrecord##1% + {\let\setrecordentry\assignrecordentry + \let\memberofgroup\gobbleoneargument + \the\resetrecordlist + \def\stoprecord{\dostoprecord{##1}}}% + \def\memberofgroup##1% + {\doifsomething{##1} + {\rawprocesscommalist[##1]\checkrecord}% + \ifrecordok + \presetrecord{##1}% + \else + \expandafter\skiprecord + \fi}% + \def\startrecord##1% + {\bgroup + \ifrecordok + \presetrecord{##1}% + \else + \checkrecord{##1}% + \ifrecordok + \presetrecord{##1}% + \fi + \fi}% + \def\dostoprecord##1% + {\relax + \egroup + %\the\everyrecord + \getvalue{\??db#1\c!command}{##1}}% + \showmessage\m!databases1\askedrecords + \def\doprocessrecords##1% + {\readjobfile{##1} + {\showmessage\m!databases2{(job)}} + {\readsysfile{##1} + {\showmessage\m!databases3{(sys)}} + {\showmessage\m!databases4{}}}}% + \processcommalist[#3]\doprocessrecords + \egroup} + +%D While writing the original implementation, I did some +%D experiments with \type {%} before each entry and changing +%D the category code of the comment char. Because \TEX\ scans +%D the line anyway |<|this is needed because the end of line +%D character can be non standard|>| this is not faster. +%D +%D Although this mechanism could have been combined with the +%D block moving mechanism, the current implementation is +%D prefered out of speed reasons. + +\protect \endinput diff --git a/tex/context/base/m-directives.tex b/tex/context/base/m-directives.tex new file mode 100644 index 000000000..c958f6cad --- /dev/null +++ b/tex/context/base/m-directives.tex @@ -0,0 +1,5 @@ +\doifnotmode{mkiv} {\endinput} + +\starttext + \showdirectives +\stoptext diff --git a/tex/context/base/m-dratex.tex b/tex/context/base/m-dratex.tex new file mode 100644 index 000000000..6c088daf9 --- /dev/null +++ b/tex/context/base/m-dratex.tex @@ -0,0 +1,21 @@ +%D \module +%D [ file=m-dratex, +%D version=2005.11.25, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=\DRATEX\ Loading Macros, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details + +\readfile{DraTex.sty}{}{\readfile{dratex.sty}{}{\endinput}} + +\letvalue{:NewCount}\newcount +\letvalue{:NewDimen}\newdimen + +\readfile{AlDraTex.sty}{}{\readfile{aldratex.sty}{}{\endinput}} + +\endinput diff --git a/tex/context/base/m-edtsnc.tex b/tex/context/base/m-edtsnc.tex new file mode 100644 index 000000000..0926f4488 --- /dev/null +++ b/tex/context/base/m-edtsnc.tex @@ -0,0 +1,207 @@ +%D \module +%D [ file=m-editsnc, +%D version=2003.12.23, +%D title=\CONTEXT\ Modules, +%D subtitle=Editor Synchronization, +%D author={Hans Hagen \& Ton Otten}, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.edit for +%C details. + +% \enablemode[demo] + +% This file is a variation of the file m-pdfsync. This time we do it +% in a more abstract way and prepare ourselves for support in dvi +% output. + +% \enableeditsync +% \disableeditsync +% \editsync +% \editsynctext {string} +% \editsyncnode {char} +% \editsynctracemode [chardef: 0-4] + +\writestatus{editsync}{loading and enabling editor synchronization support} + +\unprotect % not really needed + +\ifx\pdfoutput\undefined + \donefalse +\else\ifcase\pdfoutput + \donefalse +\else\ifx\pdfsavepos\undefined + \donefalse +\else + \donetrue +\fi\fi\fi + +\chardef \editsyncstate \zerocount +\chardef \editsynctracemode \zerocount +\newcount \editsynccounter +\newwrite \editsyncwrite + +\def\enableeditsync {\chardef\editsyncstate\plusone} +\def\disableeditsync{\chardef\editsyncstate\zerocount} + +% The following definitions can go into the special drivers, but +% for the moment we do it this way. + +\ifdone + + \def\dostarteditsync + {\immediate\openout\editsyncwrite\jobname.pdfsync + \immediate\write\editsyncwrite{\jobname}% + \immediate\write\editsyncwrite{version 0}} + + \def\dostopeditsync + {\closeout\editsyncwrite} + + \def\doeditsyncregisterpage#1{\immediate\write\editsyncwrite{s\space\number#1}} + \def\doeditsyncopenfile #1{\immediate\write\editsyncwrite{(\space#1}} + \def\doeditsyncclosefile #1{\immediate\write\editsyncwrite{)}} + + \def\doregistereditsyncnode#1#2#3% tag counter linenumber + {\pdfsavepos + \immediate\write\editsyncwrite{l\space\number#2\space\number#3}% + \expanded{\write\editsyncwrite{p\ifnum#1=\plusone*\fi\space\number#2\space\noexpand\the\pdflastxpos\space\noexpand\the\pdflastypos}}} + +\else + + \let\dostarteditsync \relax + \let\dostopeditsync \relax + + \let\doeditsyncregisterpage\gobbleoneargument + \let\doeditsyncopenfile \gobbleoneargument + \let\doeditsyncclosefile \gobbleoneargument + \let\doregistereditsyncnode\gobblethreearguments + + % These specials could be filtered by a dvitopdf backend and + % written to a jobname.pdfsync file. In that case, the x and + % y coordinates have to be to be resolved by driver. + + % \def\doeditsyncregisterpage#1{\special{pdfsync: s\space\number#1}} + % \def\doeditsyncopenfile #1{\special{pdfsync: ( #1}} + % \def\doeditsyncclosefile #1{\special{pdfsync: )}} + + % \def\doregistereditsyncnode#1#2#3% + % {\special{pdfsync: l the\editsynccounter\space\number#3}% + % \special{pdfsync: p\ifnum#1=\plusone*\fi\space\number#2}} + +\fi + +\let\editsynctracer\gobbleoneargument + +\editsynccounter\minusone % counting starts at zero and we increment beforehand + +\def\registereditsyncnode#1% we assume #1 is one token + {\ifcase\editsyncstate + \expandafter\gobbleoneargument + \else + \global\advance\editsynccounter\plusone + \doregistereditsyncnode#1\editsynccounter\inputlineno + \expandafter\editsynctracer + \fi} + +\def\editsync {\registereditsyncnode\plusone *} +\def\editsyncnode{\registereditsyncnode\zerocount} +\def\editsynctext{\registereditsyncnode\plusone } + +\appendtoks \dostarteditsync \to \everystarttext +%appendtoks \dostopeditsync \to \everystoptext +\appendtoks \doeditsyncregisterpage\realfolio \to \everyshipout +\appendtoks \doeditsyncopenfile\readfilename \to \everybeforereadfile +\appendtoks \doeditsyncclosefile\readfilename \to \everyafterreadfile + +\appendtoks \enableeditsync \to \everystarttext +\appendtoks \disableeditsync \to \everypagebody + +\def\editsynctracer#1% + {\ifcase\editsynctracemode\else + \begingroup + \forgetall + \disableeditsync + \ifcase\editsynctracemode\or % could be done more efficient, box around ifcase + \setbox\scratchbox\hbox to \zeropoint{\hss\infofont#1\hss}% 1 + \else + \setbox\scratchbox\hbox to \zeropoint{\hss\traceboxplacementtrue\boxcursor\hss}% 2/3/4 + \fi + \smashbox\scratchbox\box\scratchbox + \ifcase\editsynctracemode\or\or\or + \setbox\scratchbox\hbox to \zeropoint{\hss\raise1.25ex\hbox{\infofont#1}\hss}% 3 + \smashbox\scratchbox\box\scratchbox + \or + \setbox\scratchbox\hbox to \zeropoint{\hss\lower1.25ex\hbox{\infofont#1}\hss}% 4 + \smashbox\scratchbox\box\scratchbox + \fi + \endgroup + \fi} + +% \def\editsynctracer#1% more efficient but unreadable +% {\ifcase\editsynctracemode\else +% \ifcase\editsyncstate\else +% \begingroup +% \forgetall +% \disableeditsync +% \setbox\scratchbox\hbox to \zeropoint +% {\hss +% \ifcase\editsynctracemode\or +% \infofont#1% 1 +% \else +% \traceboxplacementtrue\boxcursor% 2/3/4 +% \fi +% \hss}% +% \smashbox\scratchbox\box\scratchbox +% \setbox\scratchbox\hbox to \zeropoint +% {\hss +% \ifcase\editsynctracemode\or\or\or +% \raise1.25ex\hbox{\infofont#1}% 3 +% \or +% \lower1.25ex\hbox{\infofont#1}% 4 +% \fi +% \hss}% +% \smashbox\scratchbox\box\scratchbox +% \endgroup +% \fi +% \fi} + +% beware, adding nodes this way will interfere with the typesetting + +\appendtoks \editsyncnode p\to \everypar +\appendtoks \editsyncnode m\to \everymath +\appendtoks \editsyncnode d\to \everydisplay +\appendtoks \editsyncnode h\to \everyhbox + +% For compatibility with 'pdfsync4context' we provide: + +\let\pdfsyncstart\enableeditsync +\let\pdfsyncstop \disablepdfsync +\let\pdfsync \editsync + +\protect + +\doifnotmode{demo}{\endinput} + +\chardef\editsynctracemode=3 + +\starttext + +\chapter{Test} + +\processfile{tufte} + +\startitemize +\item first +\item second +\stopitemize + +\processfile{tufte} + +\startlines +some local \editsync sync and \editsynctext{here}a marked point +some local \editsync sync and \editsyncnode{here}a marked point +\stoplines + +\stoptext diff --git a/tex/context/base/m-educat.tex b/tex/context/base/m-educat.tex new file mode 100644 index 000000000..ddfb72ff4 --- /dev/null +++ b/tex/context/base/m-educat.tex @@ -0,0 +1,217 @@ +%D \module +%D [ file=m-educat, +%D version=2003.03.05, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Educational Extras, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This module will collect a few macros cq.\ definitions +%D meant for educational use. Most of the code has been laying +%D around for some time and has been (or is still) used in +%D \PRAGMA\ projects. + +\unprotect + +\definesystemvariable{iv} + +\definecolor [answerareacolor] [s=.90] +\definecolor [answerlinecolor] [white] + +\definetextbackground + [\v!answerarea] + [\c!location=\v!text, + \c!n=0, + \c!frame=\v!off, + \c!framecolor=answerlinecolor, + \c!rulethickness=2pt, + \c!background=\v!color, + \c!backgroundcolor=answerareacolor, + \c!alternative=2] % betweenline + +% n=gedwongen +% m=extra auto + +\def\setupanswerarea + {\setuptextbackground[\v!answerarea]} + +\setvalue\e!answerspace + {\dosingleempty\doanswerspace} + +\def\doanswerspace[#1]% + {\begingroup + \dontcomplain + \setupanswerarea + [\c!n=0,\c!m=,#1,\c!location=\v!text]% + \doifelsenothing{\backgroundvariable\c!m} + {\expandafter\donoanswerspace} + {\expandafter\dodoanswerspace}% + [#1]} + +\def\donoanswerspace[#1]#2% + {\setupthinrules + [\c!alternative=\backgroundvariable\c!alternative, + \c!color=\backgroundvariable\c!framecolor, + \c!background=\backgroundvariable\c!background, + \c!backgroundcolor=\backgroundvariable\c!backgroundcolor, + \c!rulethickness=\backgroundvariable\c!rulethickness]% + \doifelse{\backgroundvariable\c!n}{*} + {\thinrule + \par} + {\scratchcounter0\backgroundvariable\c!n\relax + % tricky, guess + \def\processisolatedword##1% + {\setbox\scratchbox=\hbox{##1}% + \vbox{\hsize\wd\scratchbox\thinrule + \ifcase\scratchcounter\else + \setbox\scratchbox=\hbox{\space}% + \nobreak\hskip\zeropoint \!!minus \wd\scratchbox + \vbox{\hsize\wd\scratchbox\thinrule}% + \fi}}% + \processisolatedwords{#2}\processisolatedword + % so far + \ifcase\scratchcounter \else \ifnum\scratchcounter<3 + \nobreak \vbox{\hsize\scratchcounter em\thinrule}% + \else % more + \advance \scratchcounter -2 + \dorecurse\scratchcounter{\allowbreak\vbox{\hsize1em\thinrule}}% + \nobreak \vbox{\hsize2em\thinrule}% + \fi \fi}% + \endgroup} + +\def\dodoanswerspace[#1]#2% m case + {\getvalue{\e!start\v!answerarea}% + #2% + \doifelse{\backgroundvariable\c!m}{*} + {\hfill\strut + \getvalue{\e!stop\v!answerarea}% + \par} + {\scratchcounter0\backgroundvariable\c!m\relax + \ifcase\scratchcounter \else \ifnum\scratchcounter<3 + \nobreak \hbox to \scratchcounter em{\strut\hss}% + \else % more + \advance \scratchcounter -2 + \dorecurse\scratchcounter{\allowbreak\hbox to 1em{\strut\hss}}% + \nobreak \hbox to 2em{\strut\hss}% + \fi \fi + \getvalue{\e!stop\v!answerarea}}% + \endgroup} + +\setvalue{\e!start\e!answerlines}% + {\dosingleempty\dostartanswerlines} + +\def\dostartanswerlines[#1]% + {\begingroup + \dontcomplain + \setupanswerarea + [\c!n=0,\c!m=,#1,\c!location=\v!text]% + \doifnot{\backgroundvariable\c!option}\v!joinedup\softbreak + \doifelsenothing{\backgroundvariable\c!m} + {\expandafter\donostartanswerlines} + {\expandafter\dodostartanswerlines}% + [#1]} + +\def\donostartanswerlines[#1]% + {\setupthinrules + [\c!alternative=\backgroundvariable\c!alternative, + \c!color=\backgroundvariable\c!framecolor, + \c!background=\backgroundvariable\c!background, + \c!backgroundcolor=\backgroundvariable\c!backgroundcolor, + \c!rulethickness=\backgroundvariable\c!rulethickness]% + \thinrules[\c!n=\backgroundvariable\c!n]\par + \endgroup + \grabuntil{\e!stop\e!answerlines}} + +\def\dodostartanswerlines[#1]% + {\begingroup + \getvalue{\e!start\v!answerarea}% + \ignorespaces} + +\setvalue{\e!stop\e!answerlines}% + {\scratchcounter0\backgroundvariable\c!m\relax + % a \softbreak is more efficient in pos dan \par + \ifcase\scratchcounter + % nothing + \or + \softbreak + \else + \softbreak + \advance \scratchcounter \minusone + \dorecurse\scratchcounter{\strut\hfill\strut\softbreak}% + \fi + \strut\hfill\strut + \getvalue{\e!stop\v!answerarea}% + \par\endgroup\endgroup} + +\setvalue\e!answerlines + {\dosingleempty\doanswerlines} + +\def\doanswerlines[#1]#2% + {\getvalue{\e!start\e!answerlines}[#1]% + #2% + \getvalue{\e!stop\e!answerlines}} + +\protect \doifnotmode{demo}{\endinput} + +%D Test materiaal. + +\starttext + +\startnotmode[answers] + + \setupanswerarea[level=+1] + +\stopnotmode + +\setupcolors[state=start] + +test test test \answerspace [n=10] {Whow}. test test test +test tets test test \answerspace [n=10] {Whow}. test test +test test tets test test \answerspace [n=10] {Whow}. test +test test test tets test test \answerspace [n=10] {Whow}. +test test test test test test \answerspace [n=*] {Whow.} + +test test test test test test test \startanswerlines +[n=3] What A Junk Answer \stopanswerlines + +test test test test test test test \startanswerlines +[n=3,alternative=0] What A Junk Answer \stopanswerlines + +test test test test test test test \startanswerlines +[n=3,alternative=1] What A Junk Answer \stopanswerlines + +test test test test test test test \startanswerlines +[n=3,alternative=2] What A Junk Answer \stopanswerlines + +\startitemize[paragraph] +\item \startanswerlines [option=seried,n=2] xxx \stopanswerlines +\stopitemize + +test test test \answerspace [m=10] {Whow}. test test test +test tets test test \answerspace [m=10] {Whow}. test test +test test tets test test \answerspace [m=10] {Whow}. test +test test test tets test test \answerspace [m=10] {Whow}. +test test test test test test \answerspace [m=*] {Whow.} + +test test test test test test test \startanswerlines +[m=2] What A Junk Answer \stopanswerlines + +test test test test test test test \startanswerlines +[m=2,alternative=0] What A Junk Answer \stopanswerlines + +test test test test test test test \startanswerlines +[m=2,alternative=1] What A Junk Answer \stopanswerlines + +test test test test test test test \startanswerlines +[m=2,alternative=2] What A Junk Answer \stopanswerlines + +\startitemize[paragraph] +\item \startanswerlines [option=seried,m=2] xxx \stopanswerlines +\stopitemize + +\stoptext diff --git a/tex/context/base/m-format.tex b/tex/context/base/m-format.tex new file mode 100644 index 000000000..0f274b236 --- /dev/null +++ b/tex/context/base/m-format.tex @@ -0,0 +1,409 @@ +%D \module +%D [ file=m-formay, +%D version=ancient, +%D title=\CONTEXT\ Modules, +%D subtitle=Ancient Formatting Code, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Here is some code that I had laying around and had forgotten +%D about. Let's make it a module and see if there is interest in +%D such things. + +% \defineformatblock [poem] +% \defineformatsegment [verse] % [poem] +% \defineformatline [line] % [verse] +% +% \startpoem [title] [author] +% \startverse [ref] +% \startline [ref] +% +% block : voor na tussen *tekstletter *tekstkleur +% +% segment : voor na tussen *tekstletter *tekstkleur +% : links rechts linkeroffset rechteroffset +% : ?marge *evenmarge *onevenmarge breedte +% : nummer *nummercommando *conversie +% : nummerletter nummerkleur *label +% +% line : voor na tussen *tekstletter *tekstkleur +% : nummer *nummercommando *conversie +% : nummerletter nummerkleur *label +% +% * = todo + +\unprotect + +\definesystemvariable {fx} % format block +\definesystemvariable {fy} % format segment +\definesystemvariable {fz} % format line + +\def\defineformatblock + {\dodoubleempty\dodefineformatblock} + +\def\dodefineformatblock[#1][#2]% + {\setupformatblock + [#1] + [\c!before=\blank,\c!after=\blank,\c!inbetween=\blank, + \c!textstyle=,\c!textcolor=,#2]% + \setvalue{\e!start#1}{\startformatblock[#1]}% + \setvalue{\e!stop #1}{\stopformatblock}} + +\def\setupformatblock + {\dodoubleempty\dosetupformatblock} + +\def\setupformatblock[#1]% + {\getparameters[\??fx#1]} + +\def\startformatblock[#1]% + {\dotriplegroupempty\dostartformatblock{#1}} + +\def\dostartformatblock#1#2#3 + {\bgroup + \getvalue{\??fx#1\c!before} + \doglobal\newcounter\formatsegmentcounter + \doglobal\newcounter\formatlinecounter + \doglobal\newcounter\formatlinesubcounter + \doglobal\newcounter\formatlinemaxcounter + \doifsomething{#2}{\leftaligned{#2}\getvalue{\??fx#1\c!inbetween}} + \def\stopformatblock% + {\doifsomething{#3}{\getvalue{\??fx#1\c!inbetween}\leftaligned{#3}} + \getvalue{\??fx#1\c!after} + \egroup}} + +\def\defineformatsegment + {\dodoubleempty\dodefineformatsegment} + +\def\dodefineformatsegment[#1][#2]% + {\setupformatsegment + [#1] + [\c!before=\blank,\c!after=\blank,\c!inbetween=\blank, + \c!textstyle=,\c!textcolor=,\c!left=,\c!right=, + \c!leftoffset=\!!zeropoint,\c!rightoffset=\!!zeropoint, + %\c!margin=\!!zeropoint,\c!evenmargin=\!!zeropoint,\c!oddmargin=\hsize, + \c!width=\hsize,\c!numberstyle=,\c!numbercolor=,\c!number=\v!no, + \c!numbercommand=,\c!conversion=,\c!label=, + #2]% + \setvalue{\e!start#1}{\startformatsegment[#1]}% + \setvalue{\e!stop #1}{\stopformatsegment}} + +\def\setupformatsegment + {\dodoubleempty\dosetupformatsegment} + +\def\setupformatsegment[#1]% + {\getparameters[\??fy#1]} + +\def\placeformatsegmentcounter + {\formatsegmentcounter\quad\hphantom{\placeformatlinecounter}} + +\def\placeformatlinecounter + {\formatlinecounter} + +\def\startformatsegment[#1]% + {\bgroup + \doifelsevalue{\??fy#1\c!number}\v!yes + {\def\doplaceformatsegmentcounter + {\inleftmargin + {\doattributes{\??fy#1}\c!numberstyle\c!numbercolor + {\placeformatsegmentcounter}}}} + {\let\doplaceformatsegmentcounter\relax}% + \getvalue{\??fy#1\c!before} + \doglobal\increment\formatsegmentcounter + \def\formatrightoffset{\getvalue{\??fy#1\c!rightoffset}} + \def\formatleftoffset {\getvalue{\??fy#1\c!leftoffset}} + \def\formatminwidth {\getvalue{\??fy#1\c!minwidth}} + \def\formatwidth {\getvalue{\??fy#1\c!width}} + %\def\formatmargin {\getvalue{\??fy#1\c!margin}} + \def\formatbefore {\getvalue{\??fy#1\c!before}} + \def\formatinbetween {\getvalue{\??fy#1\c!inbetween}} + \def\formatafter {\getvalue{\??fy#1\c!after}} + \def\formatleft {\getvalue{\??fy#1\c!left}} + \def\formatright {\getvalue{\??fy#1\c!right}} + \@@segmentvarianta + \getvalue{@@segmentvariant\getvalue{\??fy#1\c!alternative}} + \def\stopformatsegment + {\getvalue{\??fy#1\c!after} + \egroup}} + +\newif\iftraceformatblock + +\def\@@segmentvarianta % ragged right, symbols + {\let\formatraggedness\raggedright + \let\dostartformatline\dostartformatlineab + \let\formatleftfirst\relax \let\formatrightfirst\hfill + \let\formatleftnext \hfill \let\formatrightnext \relax} + +\def\@@segmentvariantb % ragged right, equal parts, symbols + {\let\formatraggedness\raggedcenter + \let\dostartformatline\dostartformatlineab + \let\formatleftfirst\relax \let\formatrightfirst\hfill + \let\formatleftnext \hfill \let\formatrightnext \relax} + +\def\@@segmentvariantc % ragged right + {\let\formatraggedness\veryraggedright + \let\dostartformatline\dostartformatlinecde + \let\formatleftnext\relax \let\formatrightnext\hfill} + +\def\@@segmentvariantd % ragged center + {\let\formatraggedness\veryraggedcenter + \let\dostartformatline\dostartformatlinecde + \let\formatleftnext\hfill \let\formatrightnext\hfill} + +\def\@@segmentvariante % ragged left + {\let\formatraggedness\veryraggedleft + \let\dostartformatline\dostartformatlinecde + \let\formatleftnext\hfill \let\formatrightnext\relax} + +\def\defineformatline + {\dodoubleempty\dodefineformatline} + +\def\dodefineformatline[#1][#2]% + {\setupformatline + [#1] + [\c!before=\blank,\c!after=\blank,\c!inbetween=\blank, + \c!textstyle=,\c!textcolor=, + \c!number=\v!no,\c!numbercommand=,\c!conversion=, + \c!numberstyle=,\c!numbercolor=,\c!label=, + #2]% + \setvalue{\e!start#1}{\startformatline[#1]}% + \setvalue{\e!stop #1}{\stopformatline}} + +\def\setupformatline + {\dodoubleempty\dosetupformatline} + +\def\setupformatline[#1]% + {\getparameters[\??fz#1]} + +\newconditional\formatforcedbreak + +\def\startformatline[#1]% + {\bgroup + \doifelsevalue{\??fz#1\c!number}\v!yes + {\def\doplaceformatlinecounter + {\inleftmargin + {\doattributes{\??fz#1}\c!numberstyle\c!numbercolor + {\placeformatlinecounter}}}} + {\let\doplaceformatlinecounter\relax}% + \global\setfalse\formatforcedbreak + \def\\{\break\global\settrue\formatforcedbreak}% + \hsize\formatwidth + \doglobal\increment\formatlinecounter + \par + \nobreak + \def\stopformatline + {\unskip\unskip\unskip\unskip\unskip\egroup + \let\doplaceformatsegmentcounter\relax} + \postponenotes + \dowithnextbox{\dostartformatline}\hbox\bgroup\ignorespaces} + +\def\dostartformatlineab + {%\dosetleftskipadaption\formatmargin + %\advance\hsize-\leftskipadaption\relax + \ifdim\nextboxwd>\hsize + \beginofshapebox + \forgetall + \hangafter\plusone + \hangindent\formatleftoffset + \formatraggedness + \hskip\formatrightoffset + \unhbox\nextbox\par + \endofshapebox + %\advance\hsize \leftskipadaption + \doglobal\newcounter\formatlinesubcounter + \reshapebox + {\doglobal\increment\formatlinesubcounter} + \global\let\formatlinemaxcounter\formatlinesubcounter + \reshapebox + {\doglobal\decrement\formatlinesubcounter + \ifnum\formatlinesubcounter=\zerocount + \doplaceformatsegmentcounter + \doplaceformatlinecounter + \hskip-\formatrightoffset + %\hskip\leftskipadaption + \formatleftfirst + \unhbox\shapebox + \ifnum\formatlinemaxcounter>\plusone + \ifx\formatright\empty\else + \shapedhbox to \zeropoint{\formatright\hss}% + \fi + \fi + \formatrightfirst + \iftraceformatblock + \ruledhskip\formatrightoffset\hskip-\formatrightoffset + \fi + \else + %\hskip\leftskipadaption + \iftraceformatblock + \ruledhskip\formatleftoffset\hskip-\formatleftoffset + \fi + \formatleftnext + \ifx\formatleft\empty\else + \shapedhbox to \zeropoint{\hss\formatleft}% + \fi + \unhbox\shapebox + \formatrightnext + \fi} + \flushshapebox + \else + \dontleavehmode\hbox + {\doplaceformatsegmentcounter + \doplaceformatlinecounter + %\hskip\leftskipadaption + \formatleftfirst + \unhbox\nextbox + \formatrightfirst} + \fi + \par + \egroup} + +\def\dostartformatlinecde + {%\dosetleftskipadaption\formatmargin + %\advance\hsize -\leftskipadaption\relax + \dimen0=\hsize + \ifconditional\formatforcedbreak\else + \ifdim\formatminwidth>\zeropoint\relax + \ifdim\nextboxwd>\hsize + \doloop + {\global\dimen1=\dimen0 + \beginofshapebox + \hsize\dimen0 + \forgetall + \formatraggedness + \unhcopy\nextbox\par + \endofshapebox + \reshapebox + {\setbox\scratchbox=\hbox{\unhbox\shapebox}% + \ifdim\wd\scratchbox<\dimen1 + \global\dimen1=\wd\scratchbox + \fi} + \ifdim\dimen1<\formatminwidth\relax + \advance\dimen0 by -.25em + \else + \exitloop + \fi + \ifdim\dimen0<10em + \dimen0=\hsize + \exitloop + \fi} + \fi + \fi + \fi + \beginofshapebox + \hsize\dimen0 + \forgetall + \formatraggedness + \unhcopy\nextbox\par + \endofshapebox + %\advance\hsize \leftskipadaption + \doglobal\newcounter\formatlinesubcounter + \reshapebox + {\doglobal\increment\formatlinesubcounter}% + \global\let\formatlinemaxcounter\formatlinesubcounter + \reshapebox + {\doglobal\decrement\formatlinesubcounter + \ifnum\formatlinesubcounter=\zerocount + \doplaceformatsegmentcounter + \doplaceformatlinecounter + \fi + %\hskip\leftskipadaption + \formatleftnext + \unhbox\shapebox + \formatrightnext\strut}% strut prevents unskip + \flushshapebox + \par + \egroup} + +\defineformatblock[poem] + [\c!before=\blank, + \c!inbetween={\blank[\v!medium]}, + \c!after=\blank] + +\defineformatsegment[verse] + [\c!alternative=\v!left, + \c!width=\hsize, + %\c!margin=\!!zeropoint, + \c!before={\blank[\v!medium]}, + \c!after={\blank[\v!medium]}, + \c!inbetween={\blank[\v!medium]}, + \c!leftoffset=3em, + \c!rightoffset=2em, + \c!minwidth=5em, + \c!left={$[$\enspace}, + \c!right={\enspace$]$}] + +\defineformatline[line] + [] + +\protect \doifnotmode{demo} {\endinput} + +% evt defineblank[formatbefore,formatinbetween,formatafter] + +%\showframe \traceformatblocktrue + +\usemodule[visual] + +\setuplayout[height=middle,topspace=1cm,header=0pt,footer=0pt] +\setupbodyfont[10pt] + +% All interfaces supported, but testing with english; todo: +% more options, more alternatives, inheritance and mixed +% definitions, and so. + +\starttext + +\startbuffer +\startbuffer[poem] +\startpoem{A Random Poem}{Hans Hagen} + \startverse + \startline \fakewords{4}{8} \stopline + \startline \fakewords{4}{8} \stopline + \startline \fakewords{4}{8} \stopline + \startline \fakewords{4}{8} \stopline + \stopverse + \startverse + \startline \fakewords{4}{8} \stopline + \startline \fakewords{4}{8} \stopline + \startline \fakewords{4}{8} \stopline + \startline \fakewords{4}{8} \stopline + \stopverse +\stoppoem +\stopbuffer + +\setupformatsegment[verse][width=.4\hsize,number=yes,numberstyle=slanted] +\setupformatline [line] [number=yes,numberstyle=smallslanted] + +\startbuffer[x] +\setupformatsegment[verse][leftoffset=0pt,rightoffset=0pt,left=,right=] +\stopbuffer + +\section{Alternative A} + +\setupformatsegment[verse][alternative=a] {\getbuffer[poem]} +\setupformatsegment[verse][alternative=a] {\getbuffer[x,poem]} + +\section{Alternative B} + +\setupformatsegment[verse][alternative=b] {\getbuffer[poem]} +\setupformatsegment[verse][alternative=b] {\getbuffer[x,poem]} + +\section{Alternative C} + +\setupformatsegment[verse][alternative=c] {\getbuffer[poem]} + +\section{Alternative D} + +\setupformatsegment[verse][alternative=d] {\getbuffer[poem]} + +\section{Alternative E} + +\setupformatsegment[verse][alternative=e] {\getbuffer[poem]} +\stopbuffer + +\typebuffer \getbuffer + +\stoptext diff --git a/tex/context/base/m-graph.mkii b/tex/context/base/m-graph.mkii new file mode 100644 index 000000000..db7538e98 --- /dev/null +++ b/tex/context/base/m-graph.mkii @@ -0,0 +1,72 @@ +%D \module +%D [ file=m-graph, +%D version=2000.08.06, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=\METAPOST\ graph module support, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D I finally finished graph support, if only because I could +%D not stand the idea that Karel Wesseling would revert to +%D \PiCTeX. + +% pre 2000.08.06 version +% +% \forceMPTEXgraphictrue +% +% \startMPinitializations +% initialize_numbers ; % make sure that pseudo typesetting is set up +% input graph ; % load the graph package +% Autoform := "@g" ; % change the % template char into @ +% \stopMPinitializations + +%D The latest version does things more automatically (and +%D efficiently when no text processing is needed). For +%D definitions embedded in your document, you need to +%D use \type {@} as template character, in external files, +%D \type {%} is also supported. + +\startMPinclusions + input graph ; +\stopMPinclusions + +%D Graphics that have \type {begingraph} in them are +%D recognized as such and force handling of embedded \TEX\ +%D code. + +\forceMPTEXcheck{begingraph} + +%D If you run into troubles, try: +%D +%D \starttyping +%D \forceMPTEXgraphictrue +%D \stoptyping +%D +%D A demo can be run with: +%D +%D \starttyping +%D texexec --mode=demo --pdf m-graph +%D \stoptyping + +\startMPinclusions + % @# is X_ or Y_; $ is Gxcvlin_ or Gycvlin_; l and h are numeric or string + % It would not be OK to set (@#low,@#high) to a pair expression because $ might + % try to rescale @#low when evaluating the right-hand side for @#high. + vardef Gsetr_@\#(suffix $)(expr l, h) = + Gclbnds_@\# ; + if @\#ctyp>0 : + @\#low = if abs @\#ctyp<>log: $ fi Mlog_Str l ; + @\#high = if abs @\#ctyp<>log: $ fi Mlog_Str h ; + else : + -@\#high = if abs @\#ctyp<>log: $ fi Mlog_Str l ; + -@\#low = if abs @\#ctyp<>log: $ fi Mlog_Str h ; + fi + enddef ; +\stopMPinclusions + +\endinput diff --git a/tex/context/base/m-graph.mkiv b/tex/context/base/m-graph.mkiv new file mode 100644 index 000000000..c92234884 --- /dev/null +++ b/tex/context/base/m-graph.mkiv @@ -0,0 +1,63 @@ +%D \module +%D [ file=m-graph, +%D version=2008.09.08, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=\METAPOST\ graph module support, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% We just assume lua specification instead of the graph ones that +% are limited by what mp can do. We support @ as replacement for +% the percent symbol. We also add a specifier when no one is given. + +\startluacode + local function strip(s) + return "\\times10^{"..(s:gsub("%+*0*","")).."}" + end + function metapost.format_n(fmt,str) + fmt = fmt:gsub("@","%%") + local initial, format, final = fmt:match("^(.-)(%%.-[%a])(.-)$") + if format then + str = fmt:format(str) + str = str:gsub("e(.-)$",strip) + str = ("%s\\mathematics{%s}%s"):format(initial,str,final) + elseif not fmt:find("%%") then + str = ("%"..fmt):format(str) + str = str:gsub("e(.-)$",strip) + str = ("\\mathematics{%s}"):format(str) + end + tex.sprint(str) + end +\stopluacode + +\unexpanded\long\def\MPgraphformat#1#2{\ctxlua{metapost.format_n("#1","#2")}} + +\startMPinclusions + input graph.mp ; + vardef escaped_format(expr s) = + "" for n=1 upto length(s) : & + if ASCII substring (n,n+1) of s = 37 : + "@" + else : + substring (n,n+1) of s + fi + endfor + enddef ; + vardef dofmt_@\#(expr f, x) = + textext("\MPgraphformat{"&escaped_format(f)&"}{"&(if string x : x else: decimal x fi)&"}") + enddef ; + + % vardef format(expr f, x) = + % textext("\MPgraphformatN{"&escaped_format(f)&"}{"&(if string x : x else: decimal x fi)&"}") + % enddef; + % vardef Mformat(expr f, x) = + % format(f,x) + % enddef; +\stopMPinclusions + +\endinput diff --git a/tex/context/base/m-graph.tex b/tex/context/base/m-graph.tex new file mode 100644 index 000000000..6f71cca3c --- /dev/null +++ b/tex/context/base/m-graph.tex @@ -0,0 +1,175 @@ +%D \module +%D [ file=m-graph, +%D version=2000.08.06, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=\METAPOST\ graph module support, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\loadmarkfile{m-graph} + +\doifnotmode {demo} {\endinput} + +%D You need to have the data files in your path, +%D otherwise the run is aborted. + +\doiffileelse {agepop91.d} {} {\writestatus{graph}{no data files found}\wait\end} + +%D The test: + +\starttext + +\startMPpage +draw begingraph(3in,2in); + gdraw "agepop91.d"; + endgraph; +\stopMPpage + +\startMPpage +draw begingraph(3in,2in); + gdraw "agepop91.d" plot btex$\bullet$etex; + endgraph; +\stopMPpage + +\startMPpage +draw begingraph(3in,2in); + glabel.lft(btex \vbox{\hbox{Population} \hbox{in millions}} etex, OUT); + glabel.bot(btex Age in years etex, OUT); + gdraw "agepopm.d"; + endgraph; +\stopMPpage + +\startMPpage +draw begingraph(3in,2in); + glabel.lft(btex \vbox{\hbox{Population} \hbox{in millions}} etex, OUT); + glabel.bot(btex Age in years etex, OUT); + setrange(origin, whatever,whatever); + gdraw "agepopm.d"; + endgraph; +\stopMPpage + +\startMPpage +draw begingraph(2.3in,2in); + setcoords(log,log); + glabel.lft(btex Seconds etex,OUT); + glabel.bot(btex Matrix size etex, + OUT); + gdraw "matmul.d" dashed evenly; + glabel.ulft(btex Standard etex,8); + gdraw "matmul.d"; + glabel.lrt(btex Strassen etex,7); + endgraph; +\stopMPpage + +\startMPpage +draw begingraph(6.5cm,4.5cm); + setrange(80,0, 90,whatever); + glabel.bot(btex Year etex, OUT); + glabel.lft(btex \vbox{\hbox{Emissions in} \hbox{thousands of} + \hbox{metric tons} \hbox{(heavy line)}}etex, OUT); + gdraw "lead.d" withpen pencircle scaled 1.5pt; + autogrid(,otick.lft); + setcoords(linear,linear); + setrange(80,0, 90,whatever); + glabel.rt(btex \vbox{\hbox{Micrograms} \hbox{per cubic} + \hbox{meter of air} \hbox{(thin line)}}etex, OUT); + gdraw "lead.d"; + autogrid(otick.bot,otick.rt); + endgraph; +\stopMPpage + +\stoptext + +% No longer needed, since John will fix it. +% +% %D For the moment we need the following patch. Adam T. Lindsay +% %D found out that the following code produced an error: +% %D +% %D \starttyping +% %D \startMPcode +% %D draw begingraph(130mm,35mm); +% %D setrange(0,0,10,22000); +% %D glabel.lft(btex {correct 0--22000} etex rotated 90, OUT); +% %D autogrid(itick.bot,grid.lft) withcolor .75white ; +% %D endgraph; +% %D \stopMPcode +% %D +% %D \startMPcode +% %D draw begingraph(130mm,35mm); +% %D setrange(0,50,10,22000); +% %D glabel.lft(btex {wrong 50--22000} etex rotated 90, OUT); +% %D autogrid(itick.bot,grid.lft) withcolor .75white ; +% %D endgraph; +% %D \stopMPcode +% %D +% %D \startMPcode +% %D draw begingraph(130mm,35mm); +% %D setrange(0,110,10,30000); +% %D glabel.lft(btex {failed 110--22000} etex rotated 90, OUT); +% %D autogrid(itick.bot,grid.lft) withcolor .75white ; +% %D endgraph; +% %D \stopMPcode +% %D \stoptyping +% %D +% %D The bug is a rather nasty one and needs some tweaking in +% %D the low level graph code. John Hobby suggested for the +% %D moment to initialize \type {setrange} as follows: +% %D +% %D \starttyping +% %D setrange(0,0,"22000","22000") +% %D \stoptyping +% %D +% %D Folowing this suggesion, I provide the following +% %D extension: + +% def begingraph(expr w, h) = +% begingroup +% save X_, Y_, Gfin_, Gcur_, Gcbb_, Gneedgr_, Gneedfr_, Gdidsc_; +% save Gdpic_, Gppic_, Ggl_, Garw_; +% picture Gfin_, Gcur_, Gcbb_, Gdpic_, Gppic_, Ggl_[]; +% boolean Gneedgr_, Gneedfr_, Gdidsc_; +% Gfin_ = nullpicture; +% Gcur_ = nullpicture; +% Gcbb_ = nullpicture; +% X_.ctyp = Y_.ctyp = linear; +% Z_.gdim = (w,h); +% X_.sc = Y_.sc = 0; +% Gneedgr_ = true; +% Gneedfr_ = true; +% Gdidsc_ = false; +% Gdpic_ = nullpicture; +% Garw_ = 0; +% scantokens everybegingraph ; +% enddef; +% +% boolean fixsetrange ; fixsetrange := true ; +% +% vardef dosetrange(text t) = +% interim warningcheck:=0; +% save r_; r_=0; +% string r_[]s; +% for x_= +% for p_=t: if pair p_: xpart p_, ypart fi p_, endfor: +% r_[incr r_] if string x_: s fi = x_; +% if r_>2: +% Gsetr_ if r_=3: X_(Gxcvlin_) else: Y_(Gycvlin_) fi( +% r_[r_-2] if unknown r_[r_-2]: s fi, x_); +% fi +% exitif r_=4; +% endfor +% enddef; +% +% vardef setrange(text t) = +% if fixsetrange : dosetrange(0,0,20000,20000) ; fi ; +% dosetrange(t) ; +% enddef ; +% +% if unknown everybegingraph : +% string everybegingraph ; +% % everybegingraph := "setrange(0,0,20000,20000)" ; +% fi ; diff --git a/tex/context/base/m-layout.tex b/tex/context/base/m-layout.tex new file mode 100644 index 000000000..0ee71da47 --- /dev/null +++ b/tex/context/base/m-layout.tex @@ -0,0 +1,102 @@ +%D \module +%D [ file=m-layout, +%D version=2004.01.16, +%D title=\CONTEXT\ Modules, +%D subtitle=Additional Layouts, +%D author={Hans Hagen \& Ton Otten}, +%D date=\currentdate, +%D copyright={PRAGMA ADE/ Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% layout-preset - thf th tf + +%D This is a preliminary module, don't depend on these dimensions yet. + +\readsysfile{lang-frq}\donothing\donothing +\readsysfile{lang-frd}\donothing\donothing + +\unprotect + +% \def\layouthwratio{\withoutpt\the\dimexpr8\paperheight/\dimexpr(\paperwidth/ 8192)\relax} +% \def\layouthwratio{\withoutpt\the\dimexpr4\paperheight/\dimexpr(\paperwidth/16384)\relax} +% \def\layouthwratio{\withoutpt\the\dimexpr2\paperheight/\dimexpr(\paperwidth/32768)\relax} + +\def\layouthwratio + {\withoutpt\the\dimexpr2\paperheight/(\paperwidth/32768)\relax} + +\def\layouthfheight + {\dimexpr\layoutparameter\c!header+\layoutparameter\c!headerdistance+ + \layoutparameter\c!footer+\layoutparameter\c!footerdistance\relax} + +\startsetups[preset-1] + + \xdef\layoutwidth {\dimexpr\layoutparameter\c!width\relax} + \gdef\layoutheight{\dimexpr\layouthwratio\dimexpr\layoutwidth\relax+\layouthfheight\relax} + +\stopsetups + +\definelayout + [preset-1-1] + [\c!preset=preset-1, + \c!backspace=\dimexpr(\paperwidth-\layoutwidth)/2\relax, + \c!width=\dimexpr2\paperwidth/3\relax, + \c!cutspace=\dimexpr(\paperwidth-\layoutwidth)/2\relax, + \c!margin=\dimexpr(\paperwidth-\layoutwidth)/3\relax, + \c!header=2\lineheight, + \c!headerdistance=\lineheight, + \c!height=\v!middle, % \layoutheight + \c!footerdistance=\layoutparameter\c!headerdistance, % \lineheight, + \c!footer=\layoutparameter\c!header, % 2\lineheight, + \c!topspace=\dimexpr1\dimexpr\paperheight-(\layoutheight+\layouthfheight)\relax/3\relax, + \c!bottomspace=\dimexpr2\dimexpr\paperheight-(\layoutheight+\layouthfheight)\relax/3\relax] + +\startsetups[preset-2] + + \gdef\layouthstep{\dimexpr\paperwidth /\layoutparameter\c!columns\relax} + \gdef\layoutvstep{\dimexpr\paperheight/\layoutparameter\c!columns\relax} + +\stopsetups + +\definelayout + [preset-2-1] + [\c!preset=preset-2, + \c!columns=12, + \c!backspace=\layouthstep, + \c!width=\v!middle, + \c!cutspace=2\layouthstep, + \c!margin=\layouthstep, + \c!header=2\lineheight, + \c!headerdistance=\lineheight, + \c!height=\v!middle, % \layoutheight + \c!footerdistance=\layoutparameter\c!headerdistance, + \c!footer=\layoutparameter\c!header, + \c!topspace=\dimexpr\layoutvstep-\layoutparameter\c!header-\layoutparameter\c!headerdistance\relax, + \c!bottomspace=\dimexpr(2\layoutvstep)-\layoutparameter\c!header-\layoutparameter\c!headerdistance\relax] + +\definelayout + [preset-2-2] + [\c!preset=preset-2, + \c!columns=12, + \c!backspace=\layouthstep, + \c!width=\v!middle, + \c!cutspace=2\layouthstep, + \c!margin=\layouthstep, + \c!header=2\lineheight, + \c!headerdistance=\lineheight, + \c!height=\v!middle, % \layoutheight + \c!footerdistance=\layoutparameter\c!headerdistance, + \c!footer=\layoutparameter\c!header, + \c!topspace=\layoutvstep, + \c!bottomspace=\layoutvstep] % maybe 1.5 + +% \setuplayout[preset-1-1] test \showframe \page +% \setuplayout[preset-1-1][width=65\averagecharwidth] \setuplayout[preset-1-1] test \showframe \page +% \setuplayout[preset-2-1] test \showframe \page +% \setuplayout[preset-2-1][columns=10] \setuplayout[preset-2-1] test \showframe \page +% \setuplayout[preset-2-2] test \showframe \page +% \setuplayout[preset-2-2][columns=10] \setuplayout[preset-2-2] test \showframe \page + +\protect \endinput diff --git a/tex/context/base/m-level.tex b/tex/context/base/m-level.tex new file mode 100644 index 000000000..67d598733 --- /dev/null +++ b/tex/context/base/m-level.tex @@ -0,0 +1,94 @@ +%D \module +%D [ file=level, +%D version=2002.10.20, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Catching Nesting Errors, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=\PRAGMA] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\unprotect + +\newcount\currentnesting + +\def\startnesting#1% + {\global\advance\currentnesting\plusone + \setxvalue{level::\number\currentnesting}{#1}} + +\def\stopnesting#1% + {\edef\nestingstring{#1}% + \relax\ifnum\currentnesting>\zerocount + \doifelsevalue{level::\number\currentnesting}\nestingstring + {\global\advance\currentnesting\minusone} + {\@EA\reportnestingerror\@EA\stoptext} + \else + \@EA\reportnestingerror\@EA\stoptext + \fi} + +\def\checknesting + {\relax\ifnum\currentnesting>\zerocount + \def\nestingstring{end of document}% + \@EA\reportnestingerror + \fi} + +\def\reportnestingerror + {\endgraf + \global\let\checknesting\relax + \bgroup \definedfont[Mono at 18pt]\incolortrue + \setupinterlinespace + \raggedright + \bgroup \red + \ifnum\currentnesting>\plusone + wrong end level + \else + too many end levels + \fi + at \nestingstring\space in line \number\inputlineno + \ifnum\currentnesting>\zerocount, stack:\fi\endgraf + \egroup + \dostepwiserecurse\currentnesting\plusone\minusone + {\space\getvalue{level::\recurselevel}} + \endgraf + \egroup + \writestatus\m!systems{quitting due to level error}\wait + \batchmode} + +\prependtoks + \checknesting +\to \everystoptext + +\protect \doifnotmode{demo}{\endinput} + +\starttext + +% \startnesting{eerste} +% \startnesting{tweede} +% \startnesting{derde} +% \startnesting{vierde} +% test +% \stopnesting{vierde} +% \stopnesting{eerste} + +% \startnesting{eerste} +% \startnesting{tweede} +% test +% \stopnesting{vierde} +% \stopnesting{derde} +% \stopnesting{tweede} +% \stopnesting{eerste} + +\startnesting{eerste} + \startnesting{tweede} + \startnesting{derde} + \startnesting{vierde} + test + \stopnesting{vierde} + \stopnesting{derde} + \stopnesting{tweede} +\stopnesting{eerste} + +\stoptext diff --git a/tex/context/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-mkivhacks.tex b/tex/context/base/m-mkivhacks.tex new file mode 100644 index 000000000..f47658739 --- /dev/null +++ b/tex/context/base/m-mkivhacks.tex @@ -0,0 +1,52 @@ +%D \module +%D [ file=m-mkivhacks, +%D version=2008.10.20, +%D title=\CONTEXT\ Modules, +%D subtitle=Temporary Compatilibility Hacks, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\doifnotmode{mkiv}{\endinput} + +%D For Aditya, who needed it for his thesis. + +\startluacode + -- -- a lot or work + -- + -- mathematics.slots.euler = { + -- [0x03B1] = { "mr", 0x0B }, -- alpha + -- } + -- + -- mathematics.slots.euler = table.merge(mathematics.slots.traditional,mathematics.slots.euler) + -- + -- versus a quick hack + + document.hacks = document.hacks or { } + + function document.hacks() + mathematics.families.lcgreek = mathematics.families.mr + mathematics.families.ucgreek = mathematics.families.mr + mathematics.families.vargreek = mathematics.families.mr + + mathematics.define(mathematics.slots.euler) + end +\stopluacode + +% \usemodule[mkivhacks] \setups{eulermath} +% \definetypeface[modern][mm][math][euler][default] +% \usemathcollection[eul] +% \switchtobodyfont[modern,11pt] +% \starttext +% $\alpha$ +% \stoptext + +\startsetups eulermath + \ctxlua{document.hacks()} +\stopsetups + +\endinput diff --git a/tex/context/base/m-narrowtt.tex b/tex/context/base/m-narrowtt.tex new file mode 100644 index 000000000..2e11b99ad --- /dev/null +++ b/tex/context/base/m-narrowtt.tex @@ -0,0 +1,39 @@ +%D \module +%D [ file=m-narrowtt, +%D version=2005.09.08, +%D title=\CONTEXT\ Modules, +%D subtitle=Narrow Verbatim, +%D author={Hans Hagen \& Ton Otten}, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Test file +%D +%D \starttyping +%D \startTEX +%D \usemodule[narrowtt] +%D \starttext +%D \starttyping +%D Test test test. +%D \stoptyping +%D test \type {test} test \type{test} test +%D \starttyping +%D Test test test. +%D \stoptyping +%D \stoptext +%D \stopTEX + +\unprotect + +\definetypeface + [narrowtt] [tt] + [mono] [modern-condensed] [default] [encoding=\defaultencoding] + +\definetyping[n\v!typing] \setuptyping[n\v!typing][style=\narrowtt] +\definetype [n\v!type] \setuptype [n\v!type] [style=\narrowtt] + +\protect \endinput diff --git a/tex/context/base/m-newmat.tex b/tex/context/base/m-newmat.tex new file mode 100644 index 000000000..08ce33b4c --- /dev/null +++ b/tex/context/base/m-newmat.tex @@ -0,0 +1,337 @@ +%D \module +%D [ file=m-newmat, +%D version=2000.11.16, +%D title=\CONTEXT\ Math Module, +%D subtitle=AMS-like math extensions, +%D author={Taco Hoekwater \& Hans Hagen}, +%D date=\currentdate, +%D copyright={PRAGMA / Taco Hoekwater}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See licen-en.pdf for +%C details. + +%D This module collects macros that \TEX\ users kind of expect +%D to be available when typesetting math. Most of them +%D originate in the \AMS\ macro packages. We have taken the +%D freedom to adapt them to \CONTEXT. This module is derived +%D from the \type {m-math} module by Taco Hoekwater (partially +%D derived from AMS math modules) and adapted|/|extended by +%D Hans Hagen. + +%D Here we will add code on demand. So, just let us know what +%D should go in here. + +%M \usemodule[newmat] + +\unprotect + +%D \macros +%D {qedsymbol} +%D +%D [HH] The general Quod Erat Domonstrandum symbol is defined +%D in such a way that we can configure it. Because this symbol +%D is also used in text mode, we make it a normal text symbol +%D with special behavior. + +\def\qedsymbol#1% + {\ifhmode + \unskip~\hfill#1\par + \else\ifmmode + \eqno#1\relax % Do we really need the \eqno here? + \else + \leavevmode\hbox{}\hfill#1\par + \fi\fi} + +\definesymbol [qed] [\qedsymbol{\mathematics{\square}}] + +%D \macros +%D {QED} +%D +%D [HH] For compatbility reasons we also provide the \type +%D {\QED} command. In case this command is overloaded, we still +%D have the symbol available. \symbol[qed] + +\def\QED{\symbol[qed]} + +%D \macros +%D {genfrac} +%D +%D [TH] The definition of \type {\genfrac} \& co. is not +%D trivial, because it allows some flexibility. This is +%D supposed to be a user||level command, but will fail quite +%D desparately if called outside math mode (\CONTEXT\ redefines +%D \type {\over}) +%D +%D [HH] We clean up this macro a bit and (try) to make it +%D understandable. The expansion is needed for generating +%D the second argument to \type {\dogenfrac}, which is to +%D be a control sequence like \type {\over}. + +\unexpanded\def\genfrac#1#2#3#4% + {\edef\!!stringa + {#1#2}% + \expanded + {\dogenfrac{#4}% + \csname + \ifx @#3@% + \ifx\!!stringa\empty + \strippedcsname\normalover + \else + \strippedcsname\normaloverwithdelims + \fi + \else + \ifx\!!stringa\empty + \strippedcsname\normalabove + \else + \strippedcsname\normalabovewithdelims + \fi + \fi + \endcsname}% + {#1#2#3}} + +\def\dogenfrac#1#2#3#4#5% + {{#1{\begingroup#4\endgroup#2#3\relax#5}}} + +%D \macros +%D {dfrac, tfrac, frac, dbinom, tbinom, binom} +%D +%D [TH] No need to make these \type {\unexpanded} as well. + +%\def\dfrac {\genfrac\empty\empty\empty\displaystyle} +%\def\tfrac {\genfrac\empty\empty\empty\textstyle} +%\def\frac {\genfrac\empty\empty\empty\donothing} + +\def\dfrac {\genfrac\empty\empty{}\displaystyle} +\def\tfrac {\genfrac\empty\empty{}\textstyle} +\def\frac {\genfrac\empty\empty{}\donothing} + +\def\dbinom{\genfrac()\zeropoint\displaystyle} +\def\tbinom{\genfrac()\zeropoint\textstyle} +\def\binom {\genfrac()\zeropoint\donothing} + +\def\xfrac {\genfrac\empty\empty{}\scriptstyle} +\def\xxfrac{\genfrac\empty\empty{}\scriptscriptstyle} + +%D Better: + +\unexpanded\def\frac#1#2{\mathematics{\genfrac\empty\empty{}\donothing{#1}{#2}}} + +%D [HH] This shows up as: +%D +%D \startbuffer +%D $\dfrac {1}{2} \tfrac {1}{2} \frac {1}{2}$ +%D $\dbinom{1}{2} \tbinom{1}{2} \binom{1}{2}$ +%D \stopbuffer +%D +%D \typebuffer +%D +%D \getbuffer + +%D \macros +%D {text} +%D +%D [TH] \type {\text} is a command to typeset more or less +%D ordinary text inside of super- and sub|-|scripts. It has to +%D do a full font switch to get the sides right, so it will be +%D quite slow. \type {\text} kind of replaces \CONTEXT's \type +%D {\mathstyle} command. + +%D [HH] This macro is now also moved to the core, but we +%D keep it here as well for completeness. +%D +%D \starttyping +%D \unexpanded\def\mathtext +%D {\mathortext\domathtext\hbox} % {\ifmmode\@EA\dotext\else\@EA\hbox\fi} +%D +%D \def\domathtext#1% +%D {\mathchoice +%D {\dodomathtext\displaystyle\textface {#1}}% +%D {\dodomathtext\textstyle \textface {#1}}% +%D {\dodomathtext\textstyle \scriptface {#1}}% +%D {\dodomathtext\textstyle \scriptscriptface{#1}}} +%D +%D \def\dodomathtext#1#2#3% no \everymath ! +%D %{\hbox{\everymath{#1}\switchtobodyfont [#2]#3}} % 15 sec +%D {\hbox{\everymath{#1}\setcurrentfontbody{#2}#3}} % 3 sec (no math) +%D \stoptyping + +%D [HH] We use the following indirectness because \type {\text} +%D is a natural candidate for user macros (actually, it is +%D used in some modules). +%D +%D \starttyping +%D \let\text\mathtext +%D \stoptyping + +%D [HH] Actually, the font switch is not that slow when +%D typefaces are used. If needed this macro can be sped up. +%D +%D \startbuffer +%D ordinary text $x^{\text{extra ordinary text}}$ +%D \stopbuffer +%D +%D \typebuffer +%D +%D \getbuffer + +%D \macros +%D {mathhexbox} +%D +%D [TH] \type {\mathhexbox} is also user||level (already +%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{$\mathsurround\zeropoint\mathchar"#1#2#3$}} + +%D \macros +%D {boxed} +%D +%D [HH] Another macro that users expect (slightly adapted): + +\def\boxed + {\ifmmode\expandafter\mframed\else\expandafter\framed\fi} + +%D \macros +%D {cfrac} +%D +%D [HH] Now let us see what this one does: +%D +%D \startbuffer +%D $\cfrac{12}{3} \cfrac[l]{12}{3} \cfrac[c]{12}{3} \cfrac[r]{12}{3}$ +%D $\cfrac{1}{23} \cfrac[l]{1}{23} \cfrac[c]{1}{23} \cfrac[r]{1}{23}$ +%D \stopbuffer +%D +%D \typebuffer +%D +%D \getbuffer + +\definecomplexorsimple\cfrac + +\def\simplecfrac + {\complexcfrac[c]} + +\def\complexcfrac[#1]#2#3% + {{\displaystyle + \frac + {\strut\ifx r#1\hfill\fi#2\ifx l#1\hfill\fi}% + {#3}}% + \kern-\nulldelimiterspace} + +%D [HH] The next alternative is nicer: + +\def\simplecfrac {\docfrac[cc]} +\def\complexcfrac[#1]{\docfrac[#1cc]} + +\def\docfrac[#1#2#3]#4#5% + {{\displaystyle + \frac + {\strut + \ifx r#1\hfill\fi#4\ifx l#1\hfill\fi}% + {\ifx r#2\hfill\fi#5\ifx l#2\hfill\fi}% + \kern-\nulldelimiterspace}} + +%D [HH] Now we can align every combination we want: +%D +%D \startbuffer +%D $\cfrac{12}{3} \cfrac[l]{12}{3} \cfrac[c]{12}{3} \cfrac[r]{12}{3}$ +%D $\cfrac{1}{23} \cfrac[l]{1}{23} \cfrac[c]{1}{23} \cfrac[r]{1}{23}$ +%D $\cfrac[cl]{12}{3} \cfrac[cc]{12}{3} \cfrac[cr]{12}{3}$ +%D $\cfrac[lc]{1}{23} \cfrac[cc]{1}{23} \cfrac[rc]{1}{23}$ +%D \stopbuffer +%D +%D \typebuffer +%D +%D \getbuffer + +%D \macros +%D {splitfrac, splitdfrac} +%D +%D Occasionally one needs to typeset multi||line fractions. +%D These commands use \tex{genfrac} to create such fractions. +%D +%D \startbuffer +%D \startformula +%D a=\frac{ +%D \splitfrac{xy + xy + xy + xy + xy} +%D {+ xy + xy + xy + xy} +%D } +%D {z} +%D =\frac{ +%D \splitdfrac{xy + xy + xy + xy + xy} +%D {+ xy + xy + xy + xy} +%D } +%D {z} +%D \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D These macros are based on Michael J.~Downes posting on +%D comp.text.tex on 2001/12/06 + +\def\splitfrac#1#2% + {\genfrac\empty\empty\zeropoint\textstyle% + {\textstyle#1\quad\hfill}% + {\textstyle\hfill\quad\mathstrut#2}} + +\def\splitdfrac#1#2% + {\genfrac\empty\empty\zeropoint\displaystyle% + {#1\quad\hfill} + {\hfill\quad\mathstrut #2}} + +\protect \endinput + +%D \macros +%D {startsubarray,substack,startsmallmatrix} +%D +%D [HH] I wonder what these are supposed to do. An example +%D will be inserted later. Contrary to the original we +%D support an optional argument between either \type {{}} or +%D \type {[]}. + +\def\startsubarray + {\doifnextcharelse\bgroup + \simplestartsubarray{\dosingleempty\complexstartsubarray}} + +\def\complexstartsubarray[#1]% + {\simplestartsubarray{#1}} + +\def\simplestartsubarray#1% + {\vcenter\bgroup + \baselineskip\fontdimen10 \scriptfont\plustwo + \advance\baselineskip\fontdimen12 \scriptfont\plustwo + \lineskip\plusthree\fontdimen8 \scriptfont\plusthree + \lineskiplimit\lineskip + \ialign\bgroup\ifx c#1\hfil\fi$\mathsurround\zeropoint\scriptstyle##$\hfil\crcr} + +\def\stopsubarray + {\crcr\egroup + \egroup} + +\def\startsubstack + {\doifnextcharelse\bgroup + \simplestartsubstack{\dosingleempty\complexstartsubstack}} + +\def\complexstartsubstack[#1]% + {\simplestartsubstack{#1}} + +\def\simplesubstack#1% + {\startsubarray[c]#1\stopsubarray} + +\def\startsmallmatrix + {\null + \,% + \vcenter\bgroup + \baselineskip6\ex@ + \lineskip1.5\ex@ + \lineskiplimit\lineskip + \ialign\bgroup\hfil$\mathsurround\zeropoint\scriptstyle##$\hfil&&\thickspace\hfil + $\mathsurround\zeropoint\scriptstyle##$\hfil\crcr} + +\def\stopsmallmatrix + {\crcr\egroup + \egroup + \,} + +\protect \endinput diff --git a/tex/context/base/m-obsolete.tex b/tex/context/base/m-obsolete.tex new file mode 100644 index 000000000..a97002cf6 --- /dev/null +++ b/tex/context/base/m-obsolete.tex @@ -0,0 +1,5 @@ +\unprotect + +\writestatus\m!systems{skipping obsolete module} + +\protect \endinput diff --git a/tex/context/base/m-pdfsnc.tex b/tex/context/base/m-pdfsnc.tex new file mode 100644 index 000000000..da59ab5d8 --- /dev/null +++ b/tex/context/base/m-pdfsnc.tex @@ -0,0 +1,200 @@ +%D \module +%D [ file=m-pdfsnc, +%D version=2003.12.23, +%D title=\CONTEXT\ Modules, +%D subtitle=Editor Synchronization, +%D author={Hans Hagen \& Ton Otten}, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% \enablemode[demo] + +% This file is a variation of the file pdfsync4context.tex that ships +% with the pdfsync package (used by iTeXMac and TeXShop) by Piero +% D'Ancona and Jrme Laurens. I made the macros a bit more efficient +% and added some basic tracing options as well as a few more options. +% I made this one while playing a bit with the Mac and TeX). Maybe I'll +% add a bit of support to the kernel in in order to get rid of redundant +% markers. Also, this had better be rewritten in a bit less \pdf +% dependent way so that it can also be supported by dvipdfmx. I could +% write a generic file as well, but since there is already support for +% other packages I'll not do that (now). + +% compatible commands: +% +% \pdfsyncstart \pdfsyncstop \pdfsync +% +% extra commands: +% +% \enablepdfsync \disablepdfsync \pdfsynctext \pdfsyncnode \pdfsynctracemode + +\ifx\pdfoutput\undefined + \donefalse +\else\ifcase\pdfoutput + \donefalse +\else\ifx\pdfsavepos\undefined + \donefalse +\else + \donetrue +\fi\fi\fi + +\chardef \pdfsyncstate \zerocount +\chardef \pdfsynctracemode \zerocount + +\ifdone + + \writestatus{pdfsync}{loading and enabling synchronization support} + +\else + + \writestatus{pdfsync}{synchronization is only available with pdftex} + + \let \pdfsyncstart \relax % brr, not per se symmetrically used, so + \let \pdfsyncstop \relax % enable and disable are better names + \let \pdfsync \relax + + \let \pdfsynctext \gobbleoneargument + \let \pdfsyncnode \gobbleoneargument + + \let \enablepdfsync \pdfsyncstart + \let \disablepdfsync \pdfsyncstop + + \expandafter\endinput +\fi + +\unprotect % not really needed + +\newcount \pdfsynccounter +\newwrite \pdfsyncwrite + +\def\pdfsyncstart{\chardef\pdfsyncstate\plusone} \let\enablepdfsync \pdfsyncstart +\def\pdfsyncstop {\chardef\pdfsyncstate\zerocount} \let\disablepdfsync\pdfsyncstop + +\def\dostartpdfsync + {\immediate\openout\pdfsyncwrite\jobname.pdfsync + \immediate\write\pdfsyncwrite{\jobname}% + \immediate\write\pdfsyncwrite{version 0}} + +\def\dostoppdfsync + {\immediate\closeout\pdfsyncwrite} + +\def\doregisterpdfsyncpage + {\immediate\write\pdfsyncwrite{s\space\realfolio}} + +\def\dopdfsyncopenfile + {\immediate\write\pdfsyncwrite{(\space\readfilename}} + +\def\dopdfsyncclosefile + {\immediate\write\pdfsyncwrite{)}} + +\def\doregisterpdfsyncnode#1% + {\ifcase\pdfsyncstate\else + \pdfsavepos + \immediate\write\pdfsyncwrite{l\space\the\pdfsynccounter\space\the\inputlineno}% + \expanded{\write\pdfsyncwrite{p\ifnum#1=\plusone*\fi\space\the\pdfsynccounter\space\noexpand\the\pdflastxpos\space\noexpand\the\pdflastypos}}% + \global\advance\pdfsynccounter\plusone + \fi} + +\let\pdfsynctracer\gobbleoneargument + +\def\pdfsync {\doregisterpdfsyncnode\plusone \pdfsynctracer*} +\def\pdfsyncnode{\doregisterpdfsyncnode\zerocount\pdfsynctracer} +\def\pdfsynctext{\doregisterpdfsyncnode\plusone \pdfsynctracer} + +\appendtoks \dostartpdfsync \to \everystarttext +%appendtoks \dostoppdfsync \to \everystoptext +\appendtoks \doregisterpdfsyncpage \to \everyshipout +\appendtoks \dopdfsyncopenfile \to \everybeforereadfile +\appendtoks \dopdfsyncclosefile \to \everyafterreadfile + +\appendtoks \enablepdfsync \to \everystarttext +\appendtoks \disablepdfsync \to \everypagebody + +% beware, adding nodes this way will interfere with the typesetting + +\appendtoks \pdfsyncnode p\to \everypar +\appendtoks \pdfsyncnode m\to \everymath +\appendtoks \pdfsyncnode h\to \everyhbox + +% just for fun + +\def\pdfsynctracer#1% + {\ifcase\pdfsynctracemode\else + \ifcase\pdfsyncstate\else + \begingroup + \forgetall + \disablepdfsync + \ifcase\pdfsynctracemode\or % could be done more efficient, box around ifcase + \setbox\scratchbox\hbox to \zeropoint{\hss\infofont#1\hss}% 1 + \else + \setbox\scratchbox\hbox to \zeropoint{\hss\traceboxplacementtrue\boxcursor\hss}% 2/3/4 + \fi + \smashbox\scratchbox\box\scratchbox + \ifcase\pdfsynctracemode\or\or\or + \setbox\scratchbox\hbox to \zeropoint{\hss\raise1.25ex\hbox{\infofont#1}\hss}% 3 + \smashbox\scratchbox\box\scratchbox + \or + \setbox\scratchbox\hbox to \zeropoint{\hss\lower1.25ex\hbox{\infofont#1}\hss}% 4 + \smashbox\scratchbox\box\scratchbox + \fi + \endgroup + \fi + \fi} + +% \def\pdfsynctracer#1% more efficient but unreadable +% {\ifcase\pdfsynctracemode\else +% \ifcase\pdfsyncstate\else +% \begingroup +% \forgetall +% \disablepdfsync +% \setbox\scratchbox\hbox to \zeropoint +% {\hss +% \ifcase\pdfsynctracemode\or +% \infofont#1% 1 +% \else +% \traceboxplacementtrue\boxcursor% 2/3/4 +% \fi +% \hss}% +% \smashbox\scratchbox\box\scratchbox +% \setbox\scratchbox\hbox to \zeropoint +% {\hss +% \ifcase\pdfsynctracemode\or\or\or +% \raise1.25ex\hbox{\infofont#1}% 3 +% \or +% \lower1.25ex\hbox{\infofont#1}% 4 +% \fi +% \hss}% +% \smashbox\scratchbox\box\scratchbox +% \endgroup +% \fi +% \fi} + +\protect + +\doifnotmode{demo}{\endinput} + +\chardef\pdfsynctracemode=3 + +\starttext + +\chapter{Test} + +\processfile{tufte} + +\startitemize +\item first +\item second +\stopitemize + +\processfile{tufte} + +\startlines +some local \pdfsync sync and \pdfsynctext{here}a marked point +some local \pdfsync sync and \pdfsyncnode{here}a marked point +\stoplines + +\stoptext diff --git a/tex/context/base/m-pictex.tex b/tex/context/base/m-pictex.tex new file mode 100644 index 000000000..abb81b76e --- /dev/null +++ b/tex/context/base/m-pictex.tex @@ -0,0 +1,255 @@ +%D \module +%D [ file=m-pictex, +%D version=1997.01.15, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=\PICTEX\ Loading Macros, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This module is one big hack. This hack is not needed when +%D using \ETEX, so there we simply load \PICTEX\ and quit. + +%D Not every package defines \type{\fiverm}, \PICTEX's pixel, +%D so let's take care of that omision here. The actual loading +%D of \PICTEX\ depends on the package. For \LATEX\ users we +%D take care of loading the auxiliary ones too. + +\def\loadpictex + {\ifx\grid\undefined \else \let\normalgrid\grid \fi + \ifx\axis\undefined \else \let\normalaxis\axis \fi + \ifx\undefined\fiverm + \font\fiverm=cmr5 + \fi + \ifx\beginpicture\undefined + \ifx\newenvironment\undefined + \readfile{thrd-pic.tex}{}{} + \else + \input prepictex.tex \relax + \input pictex.tex \relax + \input postpictex.tex \relax + \fi + \fi + \ifx\normalgrid\undefined \else + \let\pictexgrid\grid + \let\grid\normalgrid + \fi + \ifx\normalaxis\undefined \else + \let\pictexaxis\axis + \let\axis\normalaxis + \fi} + +\ifx\eTeXversion\undefined \else \loadpictex \expandafter \endinput \fi + +%D When not in \ETEX\ and not in \CONTEXT, we load a few +%D auxiliary macros. + +\ifx \undefined \writestatus \input supp-mis.tex \relax \fi + +\unprotect + +%D \TEX\ provides 256 \DIMENSIONS\ and 256 \SKIPS. In \CONTEXT\ +%D this is no problem, but in packages that have many +%D authors, one can be quite sure that a lot of \DIMENSIONS\ are +%D allocated. Packages that use \PICTEX\ can therefore run out +%D of \DIMENSIONS\ quite fast. This module was written as a +%D reaction to persistent problems with loading \PPCHTEX\ in +%D \LATEX\ and \PICTEX\ deserves a solution. I therefore +%D dedicate this module to Tobias Burnus and Dirk Kuypers, who +%D use \PPCHTEX\ in a \LATEX\ environment and suggested a lot +%D of extensions to the repertoire of \PPCHTEX\ commands. +%D +%D This module presents a solution that is quite effective: all +%D \DIMENSIONS\ are drawn from the pool of \DIMENSIONS\ and +%D \SKIPS, depending on the availability. This is possible +%D because \DIMENSIONS\ are \SKIPS\ without a glue component. +%D Therefore we can use \SKIPS\ as \DIMENSIONS. However, some +%D incompatibility can result from assignments that look like: +%D +%D \starttyping +%D \somedimen=\someskip +%D \stoptyping +%D +%D In such cases the \DIMENSION\ equals the fixed part of the +%D \SKIP\ or in other words: this assignment strips off the +%D glue. Because \PICTEX\ uses no glue components, I thought +%D I could interchange both register types without problems, +%D but alas, this didn't hold for all \DIMENSIONS. + +%D In \PLAIN\ \TEX\ the allocation macros are defined with (as) +%D \type{\outer}. This means that they cannot appear inside +%D macros, not even in an indirect way. We therefore have to +%D redefine both \type{\newdimen} and \type{\newskip} to +%D non||\type{\outer} alternatives. In most macro packages this +%D redefinition already took place. We save the original +%D meanings, so we can restores them afterwards. + +% \def\temporarynewdimen {\alloc@1\dimen\dimendef\insc@unt} +% \def\temporarynewskip {\alloc@2\skip \skipdef \insc@unt} + +\let\normalnewdimen \newdimen +\let\normalnewskip \newskip + +\let\temporarynewdimen\newdimen +\let\temporarynewskip \newskip + +%D Here comes the trick. Depending on how many \DIMENSIONS\ and +%D \SKIPS\ are allocated, the \type{\newdimen} assigns a +%D \DIMENSIONS\ or \SKIP. \PLAIN\ \TEX\ allocates 15 \DIMENSIONS\ +%D and 17 \SKIPS. After loading \PICTEX, 71 \DIMENSIONS\ and +%D and 71 \SKIPS\ are allocated. Indeed, \PICTEX\ needs 110 +%D \DIMENSIONS ! +%D +%D \starttyping +%D \def\newdimen +%D {\ifnum\count11>\count12 +%D \let\next\temporarynewskip +%D \else +%D \let\next\temporarynewdimen +%D \fi +%D \next} +%D \stoptyping +%D +%D When I was testing a new version of \PPCHTEX\ in \PLAIN\ +%D \TEX\ I had to find out that this exchange of registers +%D sometimes leads to unwanted results. It took me some hours +%D to find out that the source of errors originated in +%D constructions like: +%D +%D \starttyping +%D \ifdim\DimenOne<\DimenTwo whatever you want \else or not \fi +%D \stoptyping +%D +%D When \type{\DimenOne} is a \SKIP\ and \type{\DimenTwo} is a +%D \DIMENSION, \TEX\ scans for some optional glue component, +%D like in: +%D +%D \starttyping +%D \skip0=\dimen0 plus 10pt minus 5pt +%D \stoptyping +%D +%D The most robust solution to this problem is: +%D +%D \starttyping +%D \ifdim\DimenOne<\DimenTwo\relax right \else wrong \fi +%D \stoptyping +%D +%D Some close reading of the \PICTEX\ source however learned me +%D that this problem could be solved best by just honoring the +%D allocation of \DIMENSIONS\ when the name of the macro +%D explictly stated the character sequence \type{dimen}. A next +%D implementation therefore automatically declared all +%D \DIMENSIONS\ with this sequence in their names with +%D \type{\dimen}. Again I was too optimistic, so now we do it +%D this way (the comments are from \PICTEX, which like \TABLE, +%D is an example of a well documented package): + +\temporarynewdimen\!dimenA %.AW.X.DVEUL..OYQRST +\temporarynewdimen\!dimenB %....X.DVEU...O.QRS. +\temporarynewdimen\!dimenC %..W.X.DVEU......RS. +\temporarynewdimen\!dimenD %..W.X.DVEU....Y.RS. +\temporarynewdimen\!dimenE %..W........G..YQ.S. +\temporarynewdimen\!dimenF %...........G..YQ.S. +\temporarynewdimen\!dimenG %...........G..YQ.S. +\temporarynewdimen\!dimenH %...........G..Y..S. +\temporarynewdimen\!dimenI %...BX.........Y.... +\temporarynewdimen\!dxpos %..W......U..P....S. +\temporarynewdimen\!dypos %..WB.....U..P...... +\temporarynewdimen\!xloc %..WB.....U.......S. +\temporarynewdimen\!xpos %..........L.P..Q.ST +\temporarynewdimen\!yloc %..WB.....U.......S. +\temporarynewdimen\!ypos %..........L.P..Q.ST +\temporarynewdimen\!zpt %.AWBX.DVEULGP.YQ.ST + +%D Tobias tested this module in all kind of \LATEX\ dialects +%D so we were able to find out that we also needed to declare: + +\temporarynewdimen\linethickness + +%D After all, the new definition of \type{\newdimen} became: + +\def\newdimen#1% + {\ifx#1\undefined + \ifnum\count11>\count12\relax + \temporarynewskip#1\relax + \else + \temporarynewdimen#1\relax + \fi + %\edef\ascii{\meaning#1}% + %\immediate\write20{\string#1 becomes \ascii}% + \else + %\edef\ascii{\meaning#1}% + %\immediate\write20{\string#1 already is \ascii}% + \fi} + +% \def\newdimen#1% +% {\bgroup +% \escapechar=-1 +% \def\next##1##2% +% {\def\next####1##1####2####3\next% +% {\egroup +% \if####2@ +% \temporarynewdimen#1\relax +% \ifnum\count11>\count12 +% \temporarynewskip#1\relax +% \else +% \temporarynewdimen#1\relax +% \fi\fi}% +% \expandafter\next\string##2##1@@\next}% +% \expandafter\next\expandafter{\string\dimen}#1} +% +% This macro is as unreadable, inefficient and as compact as +% can be, but uses no extra hash entries, which sometimes are +% scarce too. A more readable alternative, that also takes +% explicit \SKIPS\ into account, is included in the source. +% +% \def\doifregisterpreferenceelse#1#2#3#4% +% {\def\dodoifregisterpreferenceelse##1#1##2##3\war{\if##2@}% +% \expandafter\dodoifregisterpreferenceelse\string#2#1@@\war +% #4% +% \else +% #3% +% \fi} +% +% \def\newdimen#1% +% {\bgroup +% \escapechar=-1 +% \expandafter\doifregisterpreferenceelse\expandafter{\string\dimen}#1 +% {\egroup +% \temporarynewdimen#1} +% {\expandafter\doifregisterpreferenceelse\expandafter{\string\skip}#1 +% {\egroup +% \temporarynewskip#1} +% {\egroup +% \ifnum\count11>\count12 +% \temporarynewskip#1\relax +% \else +% \temporarynewdimen#1\relax +% \fi}}} + +%D Curious readers can still find the previous solution in +%D the source. The next macro is used instead of +%D \type{\input}. This macro also reports some statistics. + +\def\dimeninput#1 % + {\message{[before: d=\the\count11,s=\the\count12]}% + \input #1 \relax + \message{[after: d=\the\count11,s=\the\count12]}}% + +%D Now we can load \PICTEX: + +\loadpictex + +%D Finally we restore the old definitions of \type{\newdimen} +%D and \type{\newskip}: + +\let\newdimen=\normalnewdimen +\let\newskip =\normalnewskip + +%D and just hope for the best. + +\protect \endinput diff --git a/tex/context/base/m-plus.tex b/tex/context/base/m-plus.tex new file mode 100644 index 000000000..312d9f931 --- /dev/null +++ b/tex/context/base/m-plus.tex @@ -0,0 +1,30 @@ +%D \module +%D [ file=m-plus, +%D version=2003.03.16, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Loading extra features, +%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. + +%D Somewhere in 2001 I started collecting new functionality +%D in a module \type {m-yesno}. As the name suggests, I was +%D not entirely sure if this functionality belonged in the +%D kernel. When (again) on the \CONTEXT\ list a request for +%D side bars was posted, I decided to move such code to plus +%D modules. Users who want this additional functionality can +%D put the following call in their \type {cont-sys.tex} file: +%D +%D \starttyping +%D \usemodule[plus] +%D \stoptyping + +% \readfile {plus-rul} \donothing \donothing +% \readfile {page-str} \donothing \donothing +% \readfile {page-plg} \donothing \donothing + +\endinput diff --git a/tex/context/base/m-pstricks.lua b/tex/context/base/m-pstricks.lua new file mode 100644 index 000000000..35cae93f6 --- /dev/null +++ b/tex/context/base/m-pstricks.lua @@ -0,0 +1,73 @@ +if not modules then modules = { } end modules ['m-pstricks'] = { + version = 1.001, + comment = "companion to m-pstricks.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- The following will be done when I need ps tricks figures +-- in large quantities: +-- +-- + hash graphics and only process them once +-- + save md5 checksums in tuc file +-- +-- It's no big deal but has a low priority. + +local format, lower, concat, gmatch = string.format, string.lower, table.concat, string.gmatch +local variables = interfaces.variables + +plugins = plugins or { } +plugins.pstricks = plugins.pstricks or { } + +local template = [[ +\starttext + \pushcatcodetable + \setcatcodetable\texcatcodes + \usemodule[pstric] + %s + \popcatcodetable + \startTEXpage + \hbox\bgroup + \ignorespaces + %s + \removeunwantedspaces + \egroup + \obeydepth %% temp hack as we need to figure this out + \stopTEXpage +\stoptext +]] + +local modules = { } +local graphics = 0 + +function plugins.pstricks.usemodule(names) + for name in gmatch(names,"([^%s,]+)") do + modules[#modules+1] = format([[\readfile{%s}{}{}]],name) + end +end + +function plugins.pstricks.process(n) + graphics = graphics + 1 + local name = string.format("%s-pstricks-%04i",tex.jobname,graphics) + local data = buffers.collect("def-"..n) + local tmpfile = name .. ".tmp" + local epsfile = name .. ".ps" + local pdffile = name .. ".pdf" + local modules = concat(modules,"\n") + os.remove(epsfile) + os.remove(pdffile) + io.savedata(tmpfile,format(template,modules,data)) + os.execute(format("mtxrun --script texexec %s --once --dvips",tmpfile)) + if lfs.isfile(epsfile) then + os.execute(format("ps2pdf %s %s",epsfile,pdffile)) + -- todo: direct call but not now + if lfs.isfile(pdffile) then + context.externalfigure( { pdffile }, { object = variables.no } ) + else + logs.report("plugins","pstricks run failed, no pdf file") + end + else + logs.report("plugins","pstricks run failed, no ps file") + end +end diff --git a/tex/context/base/m-pstricks.mkii b/tex/context/base/m-pstricks.mkii new file mode 100644 index 000000000..3ada9e07e --- /dev/null +++ b/tex/context/base/m-pstricks.mkii @@ -0,0 +1,127 @@ +%D \module +%D [ file=m-pstricks, +%D version=1997.01.15, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=\PSTRICKS\ Connections, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% pstricks is not supported in context mkii (it's no problem doing that +% but as we also need to support latex it would become quite messy so for +% context we use metapost and for latex pstricks) + +%M \usemodule[pstric] + +\letvalue{@unused}\plussixteen +\letvalue{alloc@}\gobblefivearguments + +\chardef\oldbarcode\the\catcode`\| \catcode`\|=12 + +\def\loadpstrickscolors#1% + {\pushmacro\dodefinecolor + \pushmacro\dodefinepalet + \pushmacro\dodefinecolorgroup + \def\dodefinecolor[##1][##2]% + {\doifassignmentelse{##2} + {\getparameters[pstricks][r=0,g=0,b=0,##2]% + \expanded{\newrgbcolor{##1}{{\pstricksr} {\pstricksg} {\pstricksb}}}}% + {}}% + \def\dodefinepalet [##1][##2]{}% + \def\dodefinecolorgroup[##1][##2][##3]{}% + \writestatus{pstricks}{loading colors from #1}% + \input #1 \relax + \popmacro\dodefinecolorgroup + \popmacro\dodefinepalet + \popmacro\dodefinecolor} + +\doifelse{\jobsuffix}{dvi} + {\input multido \relax + \input pstricks \relax + \input pst-plot \relax + \loadpstrickscolors{colo-rgb}} + {\writestatus{pstricks}{using indirect method; enable write18}} + +\catcode`\|=\oldbarcode + +\def\loadpstricksmodule[#1]% + {\chardef\oldbarcode\the\catcode`\| + \catcode`\|=12 + \readfile{#1}{}{}% + \catcode`\|=\oldbarcode} + +%D The next piece of code is for John Culleton who suggested to +%D handle \PSTRICKS\ in a similar fashion as \METAPOST, i.e.\ +%D using a child process. For the moment there is no support +%D for passing environments, so these should be called +%D explicitly inside this environment. + +\unprotect + +%D \startPSTRICKS[offset=2pt] ... \stopPSTRICKS +%D +%D works in both dvi and pdf mode +%D +%D % \usemodule[pstric] +%D +%D \startPSTRICKS +%D \pspicture(0,0)(10,10) +%D \dorecurse{10}{\psline(0,0)(\recurselevel,10)} +%D \dorecurse{10}{\psline(0,0)(10,\recurselevel)} +%D \endpspicture +%D \stopPSTRICKS + +\def\startPSTRICKS + {\dosingleempty\dostartPSTRICKS} + +% \ifx\startTEXapplication\undefined +% +% \long\def\dostartPSTRICKS[#1]#2\stopPSTRICKS +% {\doifelse{\jobsuffix}{dvi} +% {#2} +% {\bgroup +% \setbuffer[pstricks]% +% \usemodule[pstric]% +% \setbox\scratchbox\hbox{#2}% +% % There is probably a nicer way to handle this +% \immediate\openout\scratchwrite=\bufferprefix dim.tmp +% \immediate\write\scratchwrite{\dimen0=\the\ht\scratchbox}% +% \immediate\write\scratchwrite{\dimen2=\the\wd\scratchbox}% +% \immediate\closeout\scratchwrite +% % Quick and dirty +% \startTEXpage[#1]\box\scratchbox\stopTEXpage +% \endbuffer +% % Here we go! +% %\immediate\write18{texexec \bufferprefix pstricks.tmp --once --batch}% +% %\immediate\write18{dvips -G0 -Ppdf \bufferprefix pstricks -o}% +% %\immediate\write18{ps2pdf \bufferprefix pstricks.ps \bufferprefix pstricks.pdf}% +% \executesystemcommand{texexec \bufferprefix pstricks.tmp --once --batch}% +% \executesystemcommand{dvips -G0 -Ppdf \bufferprefix pstricks -o}% +% \executesystemcommand{texmfstart pstopdf \bufferprefix pstricks.ps \bufferprefix pstricks.pdf}% +% % We pick up the dimensions from the scratch file. +% \readlocfile{\bufferprefix pstricks-dim.tmp}{}{}% +% % Since the graphic is put on a page (sigh) by dvips/gs +% % we need to shift it around a bit. +% \setbox\scratchbox\hbox +% {\externalfigure[\bufferprefix pstricks.pdf][\c!object=\v!no]}% +% \setbox\scratchbox\hbox +% {\lower\ht\scratchbox\hbox{\raise\dimen2\box\scratchbox}}% +% \wd\scratchbox\dimen0 +% \ht\scratchbox\dimen2 +% \dp\scratchbox\zeropoint +% \box\scratchbox +% \egroup}} +% +% \fi + +\long\def\dostartPSTRICKS[#1]#2\stopPSTRICKS + {\doifelse{\jobsuffix}{dvi} % will some day move to app as switch + {\hbox{#2}} +% {\startTEXapplication[#1]{\usemodule[pstric]}#2\stopTEXapplication}} + {\startTEXapplication[#1]{}#2\stopTEXapplication}} + +\protect \endinput diff --git a/tex/context/base/m-pstricks.mkiv b/tex/context/base/m-pstricks.mkiv new file mode 100644 index 000000000..c800ec199 --- /dev/null +++ b/tex/context/base/m-pstricks.mkiv @@ -0,0 +1,66 @@ +%D \module +%D [ file=m-pstricks, +%D version=2010.03.14, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=\PSTRICKS\ Connections, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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{m-pstricks}{} + +%D \startbuffer +%D \usePSTRICKSmodule[pst-barcode] +%D +%D \startPSTRICKS +%D \pspicture(-4mm,-1mm)(38mm,26mm) +%D \psbarcode{9781860742712}{includetext guardwhitespace}{ean13}% +%D \endpspicture +%D \stopPSTRICKS +%D \stopbuffer +%D +%D \typebuffer \startlinecorrection \getbuffer \stoplinecorrection + +\unprotect + +% best we can make a special colors module +% +% \let\@unused\plussixteen +% \let\alloc@ \gobblefivearguments +% +% \def\loadpstrickscolors#1% +% {\pushmacro\dodefinecolor +% \pushmacro\dodefinepalet +% \pushmacro\dodefinecolorgroup +% \def\dodefinecolor[##1][##2]% +% {\doifassignmentelse{##2} +% {\getparameters[pstricks][r=0,g=0,b=0,##2]% +% \expanded{\newrgbcolor{##1}{{\pstricksr} {\pstricksg} {\pstricksb}}}}% +% {}}% +% \def\dodefinepalet [##1][##2]{}% +% \def\dodefinecolorgroup[##1][##2][##3]{}% +% \writestatus{pstricks}{loading colors from #1}% +% \input #1 \relax +% \popmacro\dodefinecolorgroup +% \popmacro\dodefinepalet +% \popmacro\dodefinecolor} +% +% \input multido \relax +% \input pstricks \relax +% \input pst-plot \relax +% +% \loadpstrickscolors{colo-rgb} + +\definebuffer[PSTRICKS] + +\unexpanded\def\processPSTRICKS {\ctxlua{plugins.pstricks.process(\thebuffernumber{PSTRICKS})}} +\unexpanded\def\usePSTRICKSmodule[#1]{\ctxlua{plugins.pstricks.usemodule("#1")}} +\unexpanded\def\setPSTRICKS #1{\setbuffer[def-\thebuffernumber{PSTRICKS}]#1\endbuffer} + +\let\stopPSTRICKS\processPSTRICKS + +\protect \endinput diff --git a/tex/context/base/m-pstricks.tex b/tex/context/base/m-pstricks.tex new file mode 100644 index 000000000..28bc9f30f --- /dev/null +++ b/tex/context/base/m-pstricks.tex @@ -0,0 +1,16 @@ +%D \module +%D [ file=m-pstricks, +%D version=1997.01.15, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=\PSTRICKS\ Connections, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\loadmarkfile{m-pstricks} + +\endinput diff --git a/tex/context/base/m-punk.mkiv b/tex/context/base/m-punk.mkiv new file mode 100644 index 000000000..65bf03974 --- /dev/null +++ b/tex/context/base/m-punk.mkiv @@ -0,0 +1,243 @@ +%D \module +%D [ file=m-punk, +%D version=2008.04.15, +%D title=\CONTEXT\ Modules, +%D subtitle=Punk Support, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\ifx\luaversion\undefined \endinput \fi + +% At some point the font generation code will move into the +% ConTeXt MkIV kernel. + +\startluacode +do + local concat = table.concat + local chardata = characters.data + local fontdata = fonts.ids + + fonts.mp = fonts.mp or { } + + fonts.mp.version = fonts.mp.version or 1.11 + fonts.mp.inline = true + fonts.mp.cache = containers.define("fonts", "mp", fonts.mp.version, true) + + metapost.characters = metapost.characters or { } + +-- todo: use table share as in otf + + local characters, descriptions = { }, { } + local factor, l, n, w, h, d, total, variants = 100, { }, 0, 0, 0, 0, 0, 0, true + + -- A next version of mplib will provide the tfm font information which + -- gives better glyph dimensions, plus additional kerning information. + + local flusher = { + startfigure = function(chrnum,llx,lly,urx,ury) + l, n = { }, chrnum + w, h, d = urx - llx, ury, -lly + total = total + 1 + inline = fonts.mp.inline + end, + flushfigure = function(t) + for i=1, #t do + l[#l+1] = t[i] + end + end, + stopfigure = function() + local cd = chardata[n] + if inline then + descriptions[n] = { + -- unicode = n, + name = cd and cd.adobename, + width = w*100, + height = h*100, + depth = d*100, + boundingbox = { 0, -d, w, h }, + } + characters[n] = { + commands = { -- todo: xforms, should happen in backend + { "special", "pdf: " .. concat(l," ") }, + } + } + else + descriptions[n] = { + -- unicode = n, + name = cd and cd.adobename, + width = w*100, + height = h*100, + depth = d*100, + boundingbox = { 0, -d, w, h }, + } + characters[n] = { + commands = { + { "image", { stream = concat(l," "), bbox = { 0, -d*65536, w*65536, h*65536 } } }, + } + } + end + end + } + + metapost.characters.instances = metapost.characters.instances or 10 + + function metapost.characters.process(mpxformat, name, instances, scalefactor) + statistics.starttiming(metapost.characters) + scalefactor = scalefactor or 1 + instances = instances or metapost.characters.instances or 10 + local fontname = file.removesuffix(file.basename(name)) + local hash = file.robustname(string.format("%s %05i %03i", fontname, scalefactor*1000, instances)) + local lists = containers.read(fonts.mp.cache(), hash) + if not lists then + statistics.starttiming(flusher) + -- we can use a format per font + local data = io.loaddata(resolvers.find_file(name)) + metapost.reset(mpxformat) + metapost.set_outer_color(2) -- no outer color and no reset either + lists = { } + for i=1,instances do + list = { } + characters, descriptions = { }, { } + metapost.process( + mpxformat, + { + "randomseed := " .. i*10 .. ";", + "scale_factor := " .. scalefactor .. " ;", + data + }, + false, + flusher + ) + lists[i] = { + designsize = 655360, + name = string.format("%s-%03i",hash,i), + parameters = { + slant = 0, + space = 333 * scalefactor, + space_stretch = 166.5 * scalefactor, + space_shrink = 111 * scalefactor, + x_height = 431 * scalefactor, + quad =1000 * scalefactor, + extra_space = 0 + }, + ["type"] = "virtual", + characters = characters, + descriptions = descriptions, + -- embedding = "subset", + -- mkiv: + spacer = "space", + unit = 1000, + shared = { }, + unique = { }, + } + end + metapost.reset(mpxformat) -- saves memory + lists = containers.write(fonts.mp.cache(), hash, lists) + statistics.stoptiming(flusher) + end + variants = variants + #lists + statistics.stoptiming(metapost.characters) + return lists + end + + function fonts.vf.aux.combine.commands.metafont(g,v) + local size = g.specification.size + local data = metapost.characters.process(v[2],v[3],v[4],size/655360) + local list, t = { }, { } + for d=1,#data do + t = data[d] + t = fonts.tfm.scale(t, -1000) + local id = font.nextid() + t.fonts = { { id = id } } + fontdata[id] = t + fonts.vf.aux.compose_characters(t) + list[d] = font.define(t) + end + for k=1,#t do + g[k] = t[k] -- kind of replace, when not present, make nil + end + g.virtualized = true + g.variants = list + end + + fonts.define.methods.install( "punk", { + { "metafont", "mfplain", "punkfont.mp", 10 }, + } ) + + cases.actions[99] = function(current) + local used = fontdata[current.font].variants + if used then + local f = math.random(1,#used) + current.font = used[f] + return current, true + else + return current, false + end + end + + metapost.characters.flusher = flusher + + statistics.register("metapost font generation", function() + local time = statistics.elapsedtime(flusher) + if total > 0 then + return string.format("%i glyphs, %.3f seconds runtime, %i glyphs/second", total, time, total/time) + else + return string.format("%i glyphs, %.3f seconds runtime", total, time) + end + end) + + statistics.register("metapost font loading",function() + local time = statistics.elapsedtime(metapost.characters) + if variants > 0 then + return string.format("%.3f seconds, %i instances, %0.3f instances/second", time, variants, variants/time) + else + return string.format("%.3f seconds, %i instances", time, variants) + end + end) + +end +\stopluacode + +\unexpanded\def\EnableRandomPunk {\setcharactercasing[99]} +\unexpanded\def\RandomPunk {\groupedcommand\EnableRandomPunk\donothing} +\unexpanded\def\StartRandomPunk {\begingroup\EnableRandomPunk} +\unexpanded\def\StopRandomPunk {\endgroup} + +\starttypescript [serif] [punk] [default] + \setups[font:fallback:serif] % no style variants yet + \definefontsynonym [Serif] [demo@punk] +\stoptypescript + +\starttypescript [punk] + \definetypeface [punk] [rm] [serif] [punk] [default] +\stoptypescript + +\definefontfeature[punknova][mode=node,script=latn,rand=yes,kern=yes,liga=yes,tlig=yes] + +\starttypescript [serif] [punknova] + \setups[font:fallback:serif] % no style variants yet, actually it's a sans + \definefontsynonym [Serif] [file:punknova] [features=punknova] +\stoptypescript + +\starttypescript [punknova] + \definetypeface [punknova] [rm] [serif] [punknova] [default] +\stoptypescript + +\endinput + +\usetypescript[punk] + +\setupbodyfont[punk,14pt] + +\starttext + \definedfont[demo@punk at 10pt]hello world\par + \definedfont[demo@punk at 12pt]hello world\par + \definedfont[demo@punk at 16pt]hello world\par + \definedfont[demo@punk at 20pt]hello world\par +\stoptext + diff --git a/tex/context/base/m-punk.tex b/tex/context/base/m-punk.tex new file mode 100644 index 000000000..fe7ec85cc --- /dev/null +++ b/tex/context/base/m-punk.tex @@ -0,0 +1,3 @@ +% this file will disasppear but we need it as it is still in tex live + +\loadmarkfile{m-punk} diff --git a/tex/context/base/m-quest.tex b/tex/context/base/m-quest.tex new file mode 100644 index 000000000..d20c86c93 --- /dev/null +++ b/tex/context/base/m-quest.tex @@ -0,0 +1,232 @@ +%D \module +%D [ file=m-invull, +%D version=1995.01.10, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Exercise, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%I Invuloefeningen kunnen worden vormgegeven met het +%I de commando's: +%I +%I \definieerinvulwoord[trefwoord]{woord,woord} +%I \invulwoord[trefwoord] +%I \invulwoord{woord,woord,...} +%I +%I Daarbij kan het een en ander worden ingesteld met +%I +%I \stelinvullenin[status=,nummer=,links=,rechts=,letter=] +%P +%I Er zijn drie manieren om woorden in te vullen. De meest +%I eenvoudige is die waarbij de in te vullen woorden in de +%I tekst staan. +%I +%I bla bla \invulwoord{een,alfa} bla bla bla bla bla bla +%I bla bla bla bla bla bla bla bla \invulwoord{twee,beta}. +%I +%I De gezette tekst hangt af van de instellingen: +%I +%I [status=leeg] ________ +%I [status=vol,nummer=1] 'een' respectievelijk 'twee' +%I [status=vol,nummer=2] 'alfa' respectievelijk 'beta' +%I +%I Het nummer heeft dus betrekking op het volgnummer in de +%I opgegeven reeks. +%P +%I Bij de tweede manier worden eerste de alternatieven +%I gedefinieerd: +%I +%I \definieerinvulwoord{een,alfa} +%I \definieerinvulwoord{twee,beta} +%I +%I die vervolgens worden opgeroepen: +%I +%I bla \invulwoord[+] bla bla bla bla bla bla bla bla bla +%I bla bla bla bla bla bla bla bla bla bla \invulwoord[+]. +%I +%I De mogelijke instellingen komen overeen met die van de +%I eerste manier. +%P +%I De derde manier is een variant op de tweede. Bij grote +%I teksten kan men het overzicht kwijtraken. Het is daarom +%I mogelijk 'logische' namen toe te kennen aan woorden. +%I +%I \definieerinvulwoord[a]{een,alfa} +%I \definieerinvulwoord[b]{twee,beta} +%I +%I die vervolgens worden opgeroepen: +%I +%I bla \invulwoord[a] bla bla bla bla bla bla bla bla bla +%I bla bla bla bla bla bla bla bla bla bla \invulwoord[b]. +%I +%I Dit maakt het bovendien mogelijk woorden meerdere malen +%I (in een willekeurige volgorde op te roepen: +%I +%I bla \invulwoord[a] bla \invulwoord[b] bla bla bla bla +%I bla bla bla bla \invulwoord[b] bla bla \invulwoord[a]. +%P +%I Bij [status=leeg] wordt een streep gezet die in breedte +%I overeenkomt met het woord dat er eigenlijk hoort te +%I staan. De ingevulde tekst komt visueel daardoor overeen +%I met de in te vullen tekst, wat vergelijken vereenvoudigd. +%I +%I Met [status=reset] worden enkele tellers weer op 0 gezet. +%I Dit kan nodig zijn als meerdere invuloefeningen in een +%I tekst worden gezet. +%I +%I Als \versie[voorlopig] is ingesteld, worden bij invullers +%I zonder logische namen tussen haakjes de volgnummers +%I getoond. + +%S \startsetup +%S \command +%S [stelinvullenin] +%S \type +%S [\c!vars!] +%S \variable +%S [\c!letter] +%S [\v!normaal,\v!vet,\v!schuin,\v!vetschuin,\v!type,\v!kap, +%S \v!klein...,\c!command!] +%S [\v!vet] +%S \variable +%S [\c!links] +%S [\c!text!] +%S [] +%S \variable +%S [\c!rechts] +%S [\c!text!] +%S [] +%S \variable +%S [\c!status] +%S [\v!leeg,\v!vol,\v!reset] +%S [\v!vol] +%S \variable +%S [\c!nummer] +%S [\c!number!] +%S [1] +%S \variable +%S [\c!lijn] +%S [\v!aan,\v!uit] +%S [\v!aan] +%S \stopsetup + +%S \startsetup +%S \command +%S [invulwoord] +%S \type +%S [\c!ref!,\c!opt!\c!val!\c!opt!\c!args!] +%S \value +%S [\c!text!] +%S \stopsetup + +%S \startsetup +%S \command +%S [definieerinvulwoord] +%S \type +%S [\c!ref!,\c!opt!\c!val!\c!args!] +%S \value +%S [\c!text!] +%S \stopsetup + +% Mogelijke uitbreidingen +% +% - [breedte=,passend,ruim] +% - invullijst met nummers +% - weergeven lijst tijdens definitie blokkeren +% - door elkaar definieren + +\unprotect + +\definesystemvariable {iv} + +\definereferenceconstant {fillin} {:iv:} + +\newcount\invulteller \newcount\invulput \newcount\invulget + +\def\stelinvullenin + {\dosingleargument\dostelinvullenin} + +\def\dostelinvullenin[#1]% + {\getparameters[\??iv][#1]% + \doif\@@ivstate\v!reset + {\global\invulput\zerocount + \global\invulget\zerocount + \let\@@ivstate\empty}} + +\def\definieerinvulwoord + {\dosingleempty\dodefinieerinvulwoord} + +\def\dodefinieerinvulwoord[#1]#2% + {\iffirstargument + \setgvalue{\r!fillin#1}{\simpleinvulwoord{#2}}% + \else + \global\advance\invulput \plusone + \setgvalue{\r!fillin\the\invulput}{\simpleinvulwoord{#2}}% + \fi + \doifconcepttracing + {\ifnum\invulput>\zerocount + \setbox\scratchbox\hbox{~\ttx(\the\invulput)}% + \wd\scratchbox\zeropoint + \box\scratchbox + \par + \fi}} + +\def\dosimpleinvulwoord#1% + {\ifnum\@@ivnumber>\zerocount \advance\invulteller \plusone \fi + \ifnum\invulteller=\@@ivnumber\relax + \bgroup + \doconvertfont\@@ivstyle + {\@@ivleft + \doifelse\@@ivstate\v!empty + {\doifelse\@@ivrule\v!on\leeginvulwoord\geeninvulwoord} + {\doifelse\@@ivrule\v!on\underbar \firstofoneargument}% + {#1}% + \@@ivright}% + \egroup + \fi}% + +\def\simpleinvulwoord#1% + {\ifnum\@@ivnumber>0 + \invulteller\zerocount + \processcommalist[#1]\dosimpleinvulwoord + \else + \dosimpleinvulwoord{#1}% + \fi} + +\def\complexinvulwoord[#1]% + {\bgroup + \doifsomething{#1} + {\global\advance\invulget \plusone + \doconvertfont\@@ivstyle + {\@@ivleft\getvalue{\r!fillin\the\invulget}\@@ivright}} + {\doconvertfont\@@ivstyle + {\@@ivleft\getvalue{\r!fillin #1}\@@ivright}}% + \egroup} + +\definecomplexorsimple\invulwoord + +\def\leeginvulwoord#1% + {{\let\redounderbar\dodounderbar + \def\dodounderbar##1{\redounderbar{\hphantom{##1}}}% + \underbar{#1}}} + +\def\geeninvulwoord#1% + {{\def\dodounderbar##1{\hphantom{##1}}% + \underbar{#1}}} + +% when nummer > 0, then commalist processing; beware of $(1,2)$, use { } there + +\stelinvullenin + [\c!number=0, + \c!style=\v!bold, + \c!rule=\v!on, + \c!left=, + \c!right=, + \c!state=] + +\protect \endinput diff --git a/tex/context/base/m-r.tex b/tex/context/base/m-r.tex new file mode 100644 index 000000000..bf7b07a14 --- /dev/null +++ b/tex/context/base/m-r.tex @@ -0,0 +1,174 @@ +%D \module +%D [ file=m-r, +%D version=2006.06.06, +%D title=\CONTEXT\ Modules, +%D subtitle=R Support, +%D author={Johan Sandblom \& Hans Hagen}, +%D date=\currentdate, +%D copyright={PRAGMA / Johan Sandblom}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\unprotect + +%D The following R-processor is a variation on Johan Sandblom's +%D prototype. +%D +%D We can combine both variants in one macro definition. Also, we +%D can minimize the number of runs by checking for a change. + +%D JS: The call to R has \type {-q} in order to prevent banner, +%D \type {--save} to make sure it saves the workspace after the run, +%D \type {--restore} to make sure it reads any workspace from a +%D previous session. + +%D An easier and better solution is to use the buffering mechanisms: + +\def\Rbufferprefix{r-} + +\newcounter\nofRfiles + +\def\Rfile{\TEXbufferfile{\Rbufferprefix\nofRfiles}}% + +\def\startR + {\doglobal\increment\nofRfiles + \dostartbuffer[\Rbufferprefix\nofRfiles][startR][stopR]} + +\def\stopR + {\doifmode{*\v!first}\runR + \typefile{\Rfile.out}} + +\def\startRhidden + {\doglobal\increment\nofRfiles + \dostartbuffer[\Rbufferprefix\nofRfiles][startRhidden][stopRhidden]} + +\def\stopRhidden + {\doifmode{*\v!first}\runR} + +\def\runR + {\executesystemcommand{texmfstart + --ifchanged=\Rfile\space --direct R + CMD BATCH -q --save --restore \Rfile\space \Rfile.out}} + +\protect \doifnotmode{demo}{\endinput} + +% Johan's test file: + +\usemodule[r] + +\def\R{R} + +\setupcolors[state=start] + +\setuptyping + [Rtype] + [color=darkgreen] + +\starttext + +First a test of whether the workspace is persistent: +bla + +\startR +a <- "bla" +b <- "blabla" +ls() +\stopR + +One \R run ends, another begins. + +\startR +ls() +\stopR + +Now follows a hidden \R run which cleans the R workspace + +\startRhidden +rm(list=ls()) +save.image() +\stopRhidden + +What is in the workspace now? + +\startR +ls() +\stopR + +Then a small test of generating a graphic, in this case a pdf +\startR +ushape <- c(rexp(500000), 12-rexp(500000)) +pdf("ushape.pdf") +par(mfrow=c(1,2)) +hist(ushape) +plot(density(ushape), main="Density") +dev.off() +\stopR + +The graphic \type{ushape.pdf} can be included in the standard \CONTEXT\ way +\startbuffer +\placefigure{An ugly distribution}{\externalfigure[ushape]} +\stopbuffer +\typebuffer +\getbuffer + +\startR +x <- rnorm(900) +y <- rexp(900) +# test comment +f <- gl(9,9,900) +summary(aov(y~x+Error(f))) +library(lattice) +pdf("lattice.pdf") +xyplot(y~x|f) +dev.off() +\stopR + +With \type{Sweave} lattice graphics calls must be enclosed in +\type{print()} statements but that is not necessary here. + +\startbuffer +\placefigure[here]{Lattice graphics}{\externalfigure[lattice]} +\stopbuffer +\typebuffer +\getbuffer + +A test string with nasty characters. In \R, the result of a statement +is not printed by default. Enclosing the statement in parentheses, +however causes the parser to see only the value of the statement and +applying the \type{print()} method. +\startR +(test <- ".*\\\\ [[{[{]{[{[{}\]\}=?!+%#|<|>@$") +cat(test) +\stopR + +A combination +\startbuffer +\placefigure{A combination of two previously used graphics}{ +\startcombination[2*1] + {\externalfigure[ushape][width=.4\textwidth]}{The first graphic, rescaled} + {\externalfigure[lattice][width=.4\textwidth]}{The second graphic, rescaled}} +\stopcombination +\stopbuffer +\typebuffer +\getbuffer + +Testing a function definition. + +\startR +a.df <- data.frame(a=1:2, b=rnorm(2)) +a.df$a +testfunction <- function(a=NULL, ...) { + for(i in 1:length(a)) { + gsub(a[[i]], "([a-r]|[A-R])", "bla")} + print(a)} +\stopR + +What is in the workspace now? + +\startR +ls() +\stopR + +\stoptext diff --git a/tex/context/base/m-steps.mkii b/tex/context/base/m-steps.mkii new file mode 100644 index 000000000..3e1f86312 --- /dev/null +++ b/tex/context/base/m-steps.mkii @@ -0,0 +1,83 @@ +%D \module +%D [ file=m-steps, +%D version=2001.05.28, +%D title=\CONTEXT\ Modules, +%D subtitle=Step Charts \& Tables, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D The \XML\ interface: + +\unprotect + +\defineXMLdirective [stepchart] [charts] \setupSTEPcharts +\defineXMLdirective [stepchart] [cells] \setupSTEPcells +\defineXMLdirective [stepchart] [texts] \setupSTEPtexts +\defineXMLdirective [stepchart] [lines] \setupSTEPlines + +\defineXMLdirective [steptable] [tables] \setupSTEPtables +\defineXMLdirective [steptable] [cells] \setupSTEPcells +\defineXMLdirective [steptable] [texts] \setupSTEPtexts +\defineXMLdirective [steptable] [lines] \setupSTEPlines + +\defineXMLpickup[stepchart][@@STPC] + {\bgroup + \defineXMLpush[top]% + \defineXMLpush[bot]% + \defineXMLenvironment[lines][@@STEL] + {\expanded{\startlines[\theXMLarguments{@@STEL}]}} + {\stoplines}% + \defineXMLenvironment[cells][@@STEC] + {\XMLerase{top}\XMLerase{bot}} + {\expanded{\cells[\theXMLarguments{@@STEC}]{\XMLpop{top}}{\XMLpop{bot}}}}% + \defineXMLenvironment[texts][@@STET] + {\XMLerase{top}\XMLerase{bot}} + {\expanded{\texts[\theXMLarguments{@@STET}]{\XMLpop{top}}{\XMLpop{bot}}}}% + \defineXMLenvironmentpush[cell][@@STEC] + {\XMLerase{cell}} + {\expanded{\cell [\theXMLarguments{@@STEC}]{\XMLpop{cell}}}}% + \defineXMLenvironmentpush [text] [@@STET] + {\XMLerase{text}} + {\expanded{\text [\theXMLarguments{@@STET}]{\XMLpop{text}}}}% + \expanded{\startSTEPchart[\theXMLarguments{@@STPC}]}} + {\stopSTEPchart + \egroup} + +\defineXMLpickup[steptable][@@STPT] + {\bgroup + \defineXMLenvironment[lines][@@STEL] + {\expanded{\startlines[\theXMLarguments{@@STEL}]}} + {\stoplines}% + \defineXMLargument[cell][@@STEC] + {\expanded{\cell[\theXMLarguments{@@STEC}]}}% + \defineXMLargument[text][@@STET] + {\expanded{\text[\theXMLarguments{@@STET}]}}% + \defineXMLargument[prep] + {\prep}% + \expanded{\startSTEPtable[\theXMLarguments{@@STPT}]}} + {\stopSTEPtable + \egroup} + +\defineXMLpickup[stepaligntable][@@STPT] + {\bgroup + \defineXMLenvironment[lines][@@STEL] + {\expanded{\setupSTEPlines[\theXMLarguments{@@STEL}]}} + {}% + \defineXMLpush[c1]\defineXMLpush[c2]\defineXMLpush[c3]% + \defineXMLenvironment[cells][@@STEC] + {\XMLerase{c1}\XMLerase{c1}\XMLerase{c3}} + {\expanded{\cells[\theXMLarguments{@@STEC}]{\XMLpop{c1}}{\XMLpop{c2}}{\XMLpop{c3}}}}% + \defineXMLargument[text][@@STET] + {\expanded{\text[\theXMLarguments{@@STET}]}}% + \defineXMLargument[prep] + {\prep}% + \expanded{\startSTEPaligntable[\theXMLarguments{@@STPT}]}} + {\stopSTEPaligntable + \egroup} + +\protect \endinput diff --git a/tex/context/base/m-steps.mkiv b/tex/context/base/m-steps.mkiv new file mode 100644 index 000000000..9bb56c532 --- /dev/null +++ b/tex/context/base/m-steps.mkiv @@ -0,0 +1,20 @@ +%D \module +%D [ file=m-steps, +%D version=2001.05.28, +%D title=\CONTEXT\ Modules, +%D subtitle=Step Charts \& Tables, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D The \XML\ interface: + +\unprotect + +\writestatus\m!systems{The steps mkiv xml interface is not yet defined!} + +\protect \endinput diff --git a/tex/context/base/m-steps.tex b/tex/context/base/m-steps.tex new file mode 100644 index 000000000..1f6a37403 --- /dev/null +++ b/tex/context/base/m-steps.tex @@ -0,0 +1,835 @@ +%D \module +%D [ file=m-steps, +%D version=2001.05.28, +%D title=\CONTEXT\ Modules, +%D subtitle=Step Charts \& Tables, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D When I need this module, I will reimplement it by using the new +%D sometxt macro. Anyhow, it reflects the state of 2001. + +\unprotect + +% temp hack : + +% \ifx\v!kleinkorps\undefined \let\v!kleinkorps\setsmallbodyfont \fi + +% end of hack + +\definecolor [STEPlinecolor] [s=.5] +\definecolor [STEPframecolor] [s=.7] +\definecolor [STEPbackgroundcolor] [s=.9] + +\def\@@STPF{@@STPF} % frames + +\def\@@STPC{@@STPC} % charts +\def\@@STPT{@@STPT} % tables + +\def\@@STEC{@@STEC} % cells +\def\@@STET{@@STET} % tables +\def\@@STEL{@@STEL} % lines + +\def\setupSTEPcharts{\dodoubleargument\getparameters[\@@STPC]} +\def\setupSTEPtables{\dodoubleargument\getparameters[\@@STPT]} +\def\setupSTEPcells {\dodoubleargument\getparameters[\@@STEC]} +\def\setupSTEPtexts {\dodoubleargument\getparameters[\@@STET]} +\def\setupSTEPlines {\dodoubleargument\getparameters[\@@STEL]} + +\setupSTEPcharts + [\c!before=\blank, + \c!after=\blank, + %\c!distance=.25em, % nvt + \c!hoffset=1em, + \c!voffset=1ex, + \c!method=1, + \c!height=2ex, + \c!offset=.15\bodyfontsize] + +\setupSTEPtables + [\c!before=\blank, + \c!after=\blank, + \c!distance=.25em, + %\c!hoffset=1em, % nvt + \c!voffset=1ex, + \c!method=1, + \c!width=4em, + \c!offset=.15\bodyfontsize] + +\setupSTEPcells + [\c!alternative=24, + \c!background=\v!color, + \c!backgroundcolor=STEPbackgroundcolor, + \c!rulethickness=.1\bodyfontsize, + \c!framecolor=STEPframecolor, + \c!offset=.25\bodyfontsize, + \c!style=, + \c!color=] + +\setupSTEPtexts + [\c!alternative=24, + \c!background=\v!color, + \c!backgroundcolor=STEPbackgroundcolor, + \c!rulethickness=.1\bodyfontsize, + \c!framecolor=STEPframecolor, + \c!offset=.25\bodyfontsize, + \c!style=\v!smallbodyfont, + \c!color=] + +\setupSTEPlines + [\c!alternative=1, + \c!rulethickness=.15\bodyfontsize, + \c!color=STEPlinecolor] + +\def\initializeSTEP + {\initializeSTET \initializeSTEC \initializeSTEL} + +\def\initializeSTPC + {\freezedimenmacro\@@STPCoffset + \startMPdrawing + line_v_offset := \@@STPCoffset ; + line_method := \@@STPCmethod ; % only charts + \stopMPdrawing} + +\def\initializeSTPT + {\freezedimenmacro\@@STPToffset + \startMPdrawing + line_h_offset := \@@STPToffset ; + line_method := \@@STPTmethod ; % only charts + \stopMPdrawing} + +\def\initializeSTET + {\freezedimenmacro\@@STETrulethickness + \freezedimenmacro\@@STEToffset} + +\def\initializeSTEC + {\freezedimenmacro\@@STECrulethickness + \freezedimenmacro\@@STECoffset} + +\def\initializeSTEL + {\freezedimenmacro\@@STELrulethickness} + +%D ... + +\presetlocalframed[\@@STPF] + +\def\@@stepcell#1% + {\doattributes\@@STEC\c!style\c!color + {\localframed + [\@@STPF][\c!offset=\@@STECoffset,\c!frame=\v!off] + {\ignorespaces#1\unskip}}} + +\def\@@stepfake#1% + {\doattributes\@@STEC\c!style\c!color + {\ignorespaces#1\unskip}} + +\def\@@steptext#1% + {\doattributes\@@STET\c!style\c!color + {\localframed + [\@@STPF][\c!offset=\@@STEToffset,\c!frame=\v!off] + {\ignorespaces#1\unskip}}} + +%D The first attempt was purely \METAPOST\ based and spawned +%D the typesetting to the \METAFUN\ handler. This method +%D collects the cells, and directly passes them on to +%D \METAPOST. This method is the cleanest, but has the +%D disadvantage that one cannot embed hyperlinks or document +%D dependent definitions in the cells. The implementation +%D roughly looks as follows: +%D +%D \starttyping +%D \def\startSTEPchart% +%D {\bgroup +%D \startMPdrawing +%D input mp-step ; begin_step_chart ; +%D \stopMPdrawing +%D \initializeSTEP +%D \let\cells\stepchartcells \def\cell{\cells{}}% +%D \let\texts\stepcharttexts \def\text{\texts{}}} +%D +%D \def\stepchartcells#1#2% +%D {\setMPtext{tdummy}{\strut\ignorespaces#1\unskip}% beter etex/btex +%D \setMPtext{bdummy}{\strut\ignorespaces#2\unskip}% beter etex/btex +%D \startMPdrawing +%D set_step_chart_cells(\MPstring{tdummy},\MPstring{bdummy}) ; +%D \stopMPdrawing} +%D +%D \def\stepcharttexts#1#2% +%D {\setMPtext{tdummy}{\strut\ignorespaces#1\unskip}% beter etex/btex +%D \setMPtext{bdummy}{\strut\ignorespaces#2\unskip}% beter etex/btex +%D \startMPdrawing +%D set_step_chart_texts(\MPstring{tdummy},\MPstring{bdummy}) ; +%D \stopMPdrawing} +%D +%D \def\stopSTEPchart +%D {\startMPdrawing +%D end_step_chart ; +%D \stopMPdrawing +%D \MPdrawingdonetrue +%D \getMPdrawing +%D \resetMPdrawing +%D \egroup} +%D \stoptyping +%D +%D This method has the advantage that it does the job in +%D (virtually) one pass, while the next methods need multiple +%D passes: one to build the table, another to synchronize the +%D positions, and a third one beause the dimensions may have +%D changed. The last pass is a result from the fact that +%D positions are related to the page. +%D +%D The second attempt was based on tabulations and used the +%D build in position tracking mechanism, which uses two +%D position nodes per cell. +%D +%D This method collects the content in token list registers +%D and build a table from them. In the collecting pass, the +%D graphics are build stepwise. We need to collect because the +%D order of definitions is not the same as the order of +%D typesetting. We show this alternative too because it +%D demonstrates how to apply backgrounds to table cells. +%D +%D \starttyping +%D \newtoks\stepsonetop \newtoks\stepstwotop +%D \newtoks\stepsonebot \newtoks\stepstwobot +%D \stoptyping +%D +%D During the collecting phase, we temporarily have to +%D increment the name space counter. +%D +%D \starttyping +%D \def\startSTEPchart% +%D {\bgroup +%D \resetMPdrawing +%D \advance\noftabpositions\plusone % begin of preroll +%D \startMPdrawing +%D input mp-step ; +%D begin_step_chart ; +%D \stopMPdrawing +%D \initializeSTEP +%D \newcounter\cellcounter +%D \stepsonetop\emptytoks \chardef\somesteponetop=1 +%D \stepsonebot\emptytoks \chardef\somesteponebot=1 +%D \stepstwotop\emptytoks \chardef\somesteptwotop=1 +%D \stepstwobot\emptytoks \chardef\somesteptwobot=1 +%D \let\cells\stepchartcells \def\cell{\cells{}}% +%D \let\texts\stepcharttexts \def\text{\texts{}}} +%D \stoptyping +%D +%D Now we collect the steps and texts, and in the process the +%D graphic is built. Then we continue with building the table. +%D +%D Watch how we anchor the graphic to the main table box. This +%D is needed since the graphic may be larger than the table +%D itself. Actually, these small point took me the most time to +%D digest, even with the right tools (anchors) already in +%D place. +%D +%D \starttyping +%D \def\stopSTEPchart +%D {\splittabulatefalse +%D \insidefloattrue +%D \startMPdrawing +%D nofcells := \cellcounter ; +%D end_step_chart ; +%D anchor_box(\MPpos{\tbPOSprefix origin}) ; +%D \stopMPdrawing +%D \MPdrawingdonetrue +%D \advance\noftabpositions\minusone % end of preroll +%D \setbox0=\vbox +%D {\getMPdrawing} +%D \resetMPdrawing +%D \increment(\cellcounter,\cellcounter)\decrement\cellcounter +%D \setbox2=\vbox +%D {\definetabulate[chart][|*{\cellcounter}{ck0|}] % k0 nills space +%D \startchart +%D \ifcase\somesteptwotop \the\stepstwotop \NC \NR \noalign{\kern2ex} \fi +%D \ifcase\somesteponetop \the\stepsonetop \NC \NR \noalign{\kern2ex} \fi +%D \ifcase\somesteponebot \the\stepsonebot \NC \NR \noalign{\kern2ex} \fi +%D \ifcase\somesteptwobot \the\stepstwobot \NC \NR \noalign{\kern2ex} \fi +%D \noalign{\kern-2ex}% +%D \stopchart} +%D \hbox +%D {\scratchdimen\wd0 +%D \advance\scratchdimen \MPllx bp +%D \raise\MPlly bp\box0 +%D \hskip-\scratchdimen +%D \hpos{\tbPOSprefix origin}{\box2}} +%D \egroup} +%D \stoptyping +%D +%D The steps and texts fill the (at most 4) lines that make up +%D the table. We also feed the (automatically registerd) cell +%D dimensions to the graphic backend. +%D +%D \starttyping +%D \newcounter\cellcounter +%D \newcounter\textcounter +%D +%D \def\stepchartcells#1#2% +%D {\doloop +%D {\ifnum\cellcounter>\textcounter +%D \stepcharttexts{}{}% +%D \else +%D \exitloop +%D \fi}% +%D \increment\cellcounter +%D \doifelsenothing{#1} +%D {\startMPdrawing +%D cells[t][\cellcounter] := origin ; +%D \stopMPdrawing +%D \appendtoks\NC\NC\to\stepsonetop} +%D {\chardef\somesteponetop=0 +%D \edef\stepidentifier{\cellcounter-t-c}% +%D \startMPdrawing +%D initialize_area(\MPpos{b:\tbPOSprefix\stepidentifier}, +%D \MPpos{e:\tbPOSprefix\stepidentifier}) ; +%D cells[t][\cellcounter] := pxy ; +%D \stopMPdrawing +%D \@EA\appendtoks\@EA\stepidentifierposition\@EA{\stepidentifier}#1\NC\to\stepsonetop}% +%D \doifelsenothing{#2} +%D {\startMPdrawing +%D cells[b][\cellcounter] := origin ; +%D \stopMPdrawing +%D \appendtoks\NC\NC\to\stepsonebot} +%D {\chardef\somesteponebot=0 +%D \edef\stepidentifier{\cellcounter-b-c}% +%D \startMPdrawing +%D initialize_area(\MPpos{b:\tbPOSprefix\stepidentifier}, +%D \MPpos{e:\tbPOSprefix\stepidentifier}) ; +%D cells[b][\cellcounter] := pxy ; +%D \stopMPdrawing +%D \@EA\appendtoks\@EA\stepidentifierposition\@EA{\stepidentifier}#2\NC\to\stepsonebot}} +%D +%D \def\stepcharttexts#1#2% \cellcounter = nofcells +%D {\increment\textcounter +%D \doifelsenothing{#1} +%D {\startMPdrawing +%D texts[t][\cellcounter][\textcounter] := origin ; +%D \stopMPdrawing +%D \appendtoks\NC\NC\to\stepstwotop} +%D {\chardef\somesteptwotop=0 +%D \edef\stepidentifier{\cellcounter-\textcounter-t-t}% +%D \startMPdrawing +%D initialize_area(\MPpos{b:\tbPOSprefix\stepidentifier}, +%D \MPpos{e:\tbPOSprefix\stepidentifier}) ; +%D texts[t][\cellcounter][\textcounter] := pxy ; +%D \stopMPdrawing +%D \@EA\appendtoks\@EA\NC\@EA\textcellposition\@EA{\stepidentifier}#1\to\stepstwotop}% +%D \doifelsenothing{#2} +%D {\startMPdrawing +%D texts[b][\cellcounter][\textcounter] := origin ; +%D \stopMPdrawing +%D \appendtoks\NC\NC\to\stepstwobot} +%D {\chardef\somesteptwobot=0 +%D \edef\stepidentifier{\cellcounter-\textcounter-b-t}% +%D \startMPdrawing +%D initialize_area(\MPpos{b:\tbPOSprefix\stepidentifier}, +%D \MPpos{e:\tbPOSprefix\stepidentifier}) ; +%D texts[b][\cellcounter][\textcounter] := pxy ; +%D \stopMPdrawing +%D \@EA\appendtoks\@EA\NC\@EA\textcellposition\@EA{\stepidentifier}#2\to\stepstwobot}} +%D \stoptyping +%D +%D Here are the hooks that take care of calculating the cell +%D dimensions. +%D +%D \starttyping +%D \def\textcellposition#1{\GSC[#1:text]} +%D \def\stepidentifierposition#1{\GSC[#1:step]} +%D \stoptyping +%D +%D We abandoned this method after some testing and went for +%D a third one. It was this third method that evolved into the +%D current mechanism. +%D +%D Since this method was not that efficient, a third one was +%D implemented, which used one position per cell. So, +%D +%D \blank {\bf Here starts the real implementation!} \blank +%D +%D Because we want to build one graphic only we need to store +%D the graphic directives. We also need to collect the cells, +%D which are not defined in the order they show up. This +%D solution uses multiple passes over the definitions. First +%D the cells and texts are processed and the associated +%D graphics are defined in the \METAPOST\ file. Next the +%D lines are flushed. We need to do that in a second pass, +%D because in order to determine the nature of the line, +%D \METAPOST\ needs to know if the start and end cells exist. +%D This need comes from the fact that we store the shapes +%D and lines kind of directly with their associated colors and +%D types, so that we can change the settings in between. So, +%D changing for instance the line color, can take place +%D locally. + +\newbox\stepboxone \newbox\stepboxtwo +\newbox\textboxone \newbox\textboxtwo + +%D We need to define a dedicated name space counter. + +\newcounter\currentstepchart + +\def\stepchartprefix{@sc@-\currentstepchart-} + +%D Next we define the initialization part of the macros. + +\newcounter\cellcounter +\newcounter\textcounter + +\def\startSTEPchart + {\dosingleempty\dostartSTEPchart} + +\long\def\dostartSTEPchart[#1]#2\stopSTEPchart + {\ifinsidefloat + \else + \whitespace + \@@STPCbefore + \startbaselinecorrection + \setlocalhsize + \noindent + \fi + \vbox\bgroup + \setupSTEPcharts[#1]% + \forgetall + \pushMPdrawing + \resetMPdrawing + \doglobal\increment\currentstepchart + \startMPdrawing + input mp-step ; + begin_step_chart ; + \stopMPdrawing + \initializeSTEP + \initializeSTPC + \global\chardef\somestepboxone\plusone + \global\chardef\sometextboxone\plusone + \global\chardef\somestepboxtwo\somestepboxone + \global\chardef\sometextboxtwo\sometextboxone + \def\startlines{\bgroup\setupSTEPlines}% + \def\stoplines {\egroup}% + \def\cells{\dosingleempty\dostepchartcells} + \def\texts{\dosingleempty\dostepcharttexts} + \def\cell {\dosingleempty\docell}% + \def\text {\dosingleempty\dotext}% + \def\docell[##1]{\dostepchartcells[##1]{}}% + \def\dotext[##1]{\dostepcharttexts[##1]{}} + \doglobal\newcounter\cellcounter + \doglobal\newcounter\textcounter + \let\dostepchartcells\doSTEPchartcellsA + \let\dostepcharttexts\doSTEPcharttextsA + {#2} % pass one: cells and texts {} keeps setting local + \startMPdrawing + nofcells := \cellcounter ; + analyze_step_chart ; + \stopMPdrawing + \doglobal\newcounter\cellcounter + \doglobal\newcounter\textcounter + \let\dostepchartcells\doSTEPchartcellsB + \let\dostepcharttexts\doSTEPcharttextsB + {#2} % pass two: lines + \startMPdrawing + end_step_chart ; + % if box_found(\MPpos{\stepchartprefix origin}) : + % initialize_box(\MPpos{\stepchartprefix origin}) ; + % draw pxy ; + % fi ; + anchor_box(\MPpos{\stepchartprefix origin}) ; + \stopMPdrawing + \MPdrawingdonetrue + \doifelse\@@STPCmethod{0} + {\setbox0\null} + {\setbox0\vbox{\MPstaticgraphictrue\getMPdrawing}}% + \resetMPdrawing + \setbox2\vbox + {\offinterlineskip + \scratchdimen\@@STPCheight + \advance\scratchdimen\@@STPCoffset + \advance\scratchdimen\@@STPCoffset + \ifcase\sometextboxone \box\textboxone \vskip\scratchdimen \fi + \ifcase\somestepboxone \box\stepboxone \vskip\@@STPCvoffset \fi + \ifcase\somestepboxtwo \box\stepboxtwo \vskip\scratchdimen \fi + \ifcase\sometextboxtwo \box\textboxtwo \vskip\@@STPCvoffset \fi + \global\resetbox\stepboxone \global\resetbox\stepboxtwo % needed indeed + \global\resetbox\textboxone \global\resetbox\textboxtwo % needed indeed + %\kern-\scratchdimen % no, instead: + \vskip-\lastskip} + \hbox + {\scratchdimen\wd0 + \advance\scratchdimen \MPllx bp + \raise\MPlly bp\box0 + \hskip-\scratchdimen + \hpos{\stepchartprefix origin}{\box2}}% + \popMPdrawing + \egroup + \ifinsidefloat \else \stopbaselinecorrection \@@STPCafter \fi} + +%D The next macro looks more complicated than it is. We collect +%D the cells in boxes. Before adding a new step cell, we padd +%D the text rows. After adding the step cells, we flush text +%D cells that are defined but not yet processed. + +\def\doSTEPchartcellsA[#1]#2#3% + {% synchronize texts + \doSTEPchartcellsAB[#1]{#2}{#3}% + % package steps + \setbox0\hbox{\doifsomething{#2}{\@@stepcell{#2}}}% + \setbox2\hbox{\doifsomething{#3}{\@@stepcell{#3}}}% + \ifdim\wd0>\zeropoint \!!doneafalse \else \!!doneatrue \fi + \ifdim\wd2>\zeropoint \!!donebfalse \else \!!donebtrue \fi + \ifdim\wd0>\wd2 + \setbox2\hbox to \wd0{\hss\box2\hss}% + \else + \setbox0\hbox to \wd2{\hss\box0\hss}% + \fi + \if!!donea + \startMPdrawing + cells[t][\cellcounter] := nullpicture ; + \stopMPdrawing + \else + \global\chardef\somestepboxone\zerocount + \edef\stepidentifier{\stepchartprefix\cellcounter-t-c}% + \setbox0\hbox{\hpos{\stepidentifier}{\box0}}% + \bgroup + \iffirstargument\setupSTEPcells[#1]\fi\initializeSTEC + \startMPdrawing + initialize_box(\MPpos{\stepidentifier}) ; + cells[t][\cellcounter] := \MPcellsgraphic ; + \stopMPdrawing + \egroup + \fi + \if!!doneb + \startMPdrawing + cells[b][\cellcounter] := nullpicture ; + \stopMPdrawing + \else + \global\chardef\somestepboxtwo\zerocount + \edef\stepidentifier{\stepchartprefix\cellcounter-b-c}% + \setbox2\hbox{\hpos{\stepidentifier}{\box2}}% + \bgroup + \iffirstargument\setupSTEPcells[#1]\fi\initializeSTEC + \startMPdrawing + initialize_box(\MPpos{\stepidentifier}) ; + cells[b][\cellcounter] := \MPcellsgraphic ; + \stopMPdrawing + \egroup + \fi + \global\setbox\stepboxone\hbox + {\ifdim\wd\stepboxone>\zeropoint + \box\stepboxone\hskip\@@STPChoffset\else + \fi\box0}% + \global\setbox\stepboxtwo\hbox + {\ifdim\wd\stepboxtwo>\zeropoint + \box\stepboxtwo\hskip\@@STPChoffset\else + \fi\box2}% + % flush saved texts + \doSTEPchartcellsBA} + +\def\doSTEPchartcellsB[#1]#2#3% + {\doSTEPchartcellsAB[#1]{#2}{#3}% + \doSTEPchartcellsBA} + +\def\doSTEPchartcellsAB[#1]#2#3% + {\doloop + {\ifnum\cellcounter>\textcounter + \texts{}{}\else\exitloop + \fi}% + \doglobal\increment\cellcounter} + +\def\doSTEPchartcellsBA + {\scratchtoks\stepchartbuffer + \stepchartbuffer\emptytoks + \the\scratchtoks} + +\def\MPcellsgraphic + {image ( drawshape ( + \@@STECalternative, pxy enlarged (-.5*\@@STECoffset), + \@@STECrulethickness, \MPcolor{\@@STECframecolor}, + \MPcolor{\@@STECbackgroundcolor} ) )} + +%D Although each step can have only one associated text, the +%D place where the text is defined determines the starting +%D point of the connecting arrow. Although several methods are +%D possible, we've chosen a funny collector that flushes one +%D step text at a time. + +\newtoks\stepchartbuffer + +\def\doSTEPcharttextsA[#1]% #2 #3 + {\dodoSTEPcharttextsA{\cellcounter}{#1}} + +\def\dodoSTEPcharttextsA#1#2#3#4% #1=number #2=setup + {\dodoSTEPcharttextsAB{#1}{#2}{#3}{#4}\dodoSTEPcharttextsA + \ifnum\textcounter>\cellcounter\relax + \doglobal\decrement\textcounter\relax + \else + \setbox0\hbox{\doifsomething{#3}{\@@steptext{#3}}}% + \setbox2\hbox{\doifsomething{#4}{\@@steptext{#4}}}% + \ifdim\wd0>\zeropoint \!!doneafalse \else \!!doneatrue \fi + \ifdim\wd2>\zeropoint \!!donebfalse \else \!!donebtrue \fi + \if!!donea + \setbox0\hbox to \@@STPChoffset{\hss}% + \startMPdrawing + texts[t][#1][\textcounter] := nullpicture ; + \stopMPdrawing + \else + \global\chardef\sometextboxone\zerocount + \edef\stepidentifier{\stepchartprefix#1-\textcounter-t-t}% + \setbox0\hbox to \@@STPChoffset + {\hss\hpos{\stepidentifier}{\box0}\hss}% + \bgroup + \setupSTEPtexts[#2]\initializeSTET + \startMPdrawing + initialize_box(\MPpos{\stepidentifier}) ; + texts[t][#1][\textcounter] := \MPtextsgraphic ; + \stopMPdrawing + \egroup + \fi + \if!!doneb + \setbox2\hbox to \@@STPChoffset{\hss}% + \startMPdrawing + texts[b][#1][\textcounter] := nullpicture ; + \stopMPdrawing + \else + \global\chardef\sometextboxtwo\zerocount + \edef\stepidentifier{\stepchartprefix#1-\textcounter-b-t}% + \setbox2\hbox to \@@STPChoffset + {\hss\hpos{\stepidentifier}{\box2}\hss}% + \bgroup + \setupSTEPtexts[#2]\initializeSTET + \startMPdrawing + initialize_box(\MPpos{\stepidentifier}) ; + texts[b][#1][\textcounter] := \MPtextsgraphic ; + \stopMPdrawing + \egroup + \fi + \global\setbox\textboxone\hbox + {\hbox to \wd\stepboxone{\box\textboxone\hss}\box0} + \global\setbox\textboxtwo\hbox + {\hbox to \wd\stepboxtwo{\box\textboxtwo\hss}\box2} + \fi} + +\def\doSTEPcharttextsB[#1]% #2 #3 + {\dodoSTEPcharttextsB{\cellcounter}{#1}} + +\def\dodoSTEPcharttextsB#1#2#3#4% #1=number #2=setup + {\dodoSTEPcharttextsAB{#1}{#2}{#3}{#4}\dodoSTEPcharttextsB + \ifnum\textcounter>\cellcounter\relax + \doglobal\decrement\textcounter\relax + \else + \bgroup + \initializeSTEL + \startMPdrawing + lines[t][#1][\textcounter] := \MPcharttoplinesgraphic{#1}\textcounter ; + lines[b][#1][\textcounter] := \MPchartbotlinesgraphic{#1}\textcounter ; + \stopMPdrawing + \egroup + \fi} + +\def\dodoSTEPcharttextsAB#1#2#3#4#5% #1=number #2=setup + {\doglobal\increment\textcounter\relax + \ifnum\textcounter>\cellcounter\relax + \@EA\appendtoks\@EA#5\@EA{#1}{#2}{#3}{#4}\to\stepchartbuffer + \fi} + +\def\MPtextsgraphic + {image(drawshape( + \@@STETalternative, pxy enlarged (-.5*\@@STEToffset), + \@@STETrulethickness, \MPcolor{\@@STETframecolor}, + \MPcolor{\@@STETbackgroundcolor} ) )} + +\def\MPcharttoplinesgraphic#1#2% + {image(drawline( + \@@STELalternative, get_step_chart_top_line(#1,#2), + \@@STELrulethickness, \MPcolor{\@@STELcolor} ) )} + +\def\MPchartbotlinesgraphic#1#2% + {image(drawline( + \@@STELalternative, get_step_chart_bot_line(#1,#2), + \@@STELrulethickness, \MPcolor{\@@STELcolor} ) )} + +%D Step tables are the vertical counterpart of stepcharts. + +\newcounter\currentsteptable + +\def\steptableprefix{@st@-\currentsteptable-} + +\def\startSTEPtable + {\dosingleempty\dostartSTEPtable} + +\def\dostartSTEPtable[#1]#2\stopSTEPtable + {\dostartSTEPaligntable[0][#1]#2\stopSTEPaligntable} + +\def\startSTEPaligntable + {\dodoubleempty\dostartSTEPaligntable[1]} + +\def\dostartSTEPaligntable[#1][#2]#3\stopSTEPaligntable % flag settings data + {\ifinsidefloat + \else + \whitespace + \@@STPTbefore + \startbaselinecorrection + \setlocalhsize + \noindent + \fi + \vbox\bgroup + \setupSTEPtables[#2]% + \forgetall + \pushMPdrawing + \doglobal\increment\currentsteptable + \startMPdrawing + input mp-step ; + begin_step_table ; + \stopMPdrawing + \initializeSTEP + \initializeSTPT + \def\startlines{\bgroup\setupSTEPlines}% + \def\stoplines {\egroup}% + \def\prep##1{\ignorespaces##1\unskip\enspace\ignorespaces}% + \def\cell {\dosingleempty\docell}% + \def\cells {\dosingleempty\docells}% + \def\text {\dosingleempty\dotext}% + % first graphic pass, also trial pass + \global\dimen1\zeropoint + \global\dimen3\zeropoint + \global\dimen5\zeropoint + \def\docell[##1]% + {\docells[##1]{}{}}% + \def\docells[##1]##2##3##4% + {\doglobal\increment\cellcounter + \bgroup + \iffirstargument\setupSTEPcells[##1]\fi + \initializeSTEC + \startMPdrawing + if box_found(\MPpos{\steptableprefix\cellcounter-c}) : + initialize_box(\MPpos{\steptableprefix\cellcounter-c}) ; + cells[\cellcounter] := \MPcellsgraphic ; + fi ; + \stopMPdrawing + \egroup + \def\do####1####2% + {\setbox\scratchbox\hbox{\@@stepfake{####2}}% + \ifdim\wd\scratchbox>\dimen####1\global\dimen####1=\wd\scratchbox\fi}% + \ifcase#1\else\do1{##2}\do3{##3}\fi\do5{##4}}% + \def\dotext[##1]##2% + {\bgroup + \iffirstargument\setupSTEPtexts[##1]\fi + \initializeSTET + \startMPdrawing + if box_found(\MPpos{\steptableprefix\cellcounter-t}) : + initialize_box(\MPpos{\steptableprefix\cellcounter-t}) ; + texts[\cellcounter] := \MPtextsgraphic ; + fi ; + \stopMPdrawing + \egroup} + \doglobal\newcounter\cellcounter#3 + % second graphic pass pass, drawing lines + \def\docells[##1]##2##3##4% + {\doglobal\increment\cellcounter} + \def\dotext[##1]##2% + {\bgroup + \initializeSTEL + \startMPdrawing + lines[\cellcounter] := \MPtablelinesgraphic ; + \stopMPdrawing + \egroup} + \doglobal\newcounter\cellcounter#3 + % finishing graphic touch + \startMPdrawing + nofcells := \cellcounter ; + end_step_table ; + anchor_box(\MPpos{\steptableprefix origin}) ; + \stopMPdrawing + \MPdrawingdonetrue + \doifelse\@@STPTmethod{0} + {\setbox0\null} + {\setbox0\vbox{\MPstaticgraphictrue\getMPdrawing}}% + \resetMPdrawing + % typesetting pass + \dimen6=\@@STPTdistance \dimen6=2\dimen6 + % cell width + \dimen8=\dimen1 + \advance\dimen8\dimen3 + \advance\dimen8\dimen5 + % offset width + \ifcase#1\else \advance\dimen8 \dimen6 \fi + % arrow width + \advance\dimen8 \@@STPTwidth + \advance\dimen8 \@@STPToffset + \advance\dimen8 \@@STPToffset + \def\docells[##1]##2##3##4% + {\doglobal\increment\cellcounter + \def\do####1####2####3####4% % strut really needed there ! + {\hbox to \dimen####1{####2\@@stepfake{####3}\strut####4}}% + \setbox8\hbox + {\ifcase#1\else + \do1\hss{##2}\relax \hskip\@@STPTdistance + \do3\hss{##3}\hss \hskip\@@STPTdistance + \fi + \do5\relax{##4}\hss}% + \hpos{\steptableprefix\cellcounter-c}{\@@stepcell{\box8}} + \endgraf + \nointerlineskip + \kern\@@STPTvoffset} + \def\dotext[##1]##2% + {\bgroup + \hskip\dimen8 + \advance\hsize-\dimen8 + \advance\hsize-\dimen6 % twice the offset + \setbox0\hbox{\@@steptext{##2}}% +% to do +% \ifdim\wd0>\hsize +% \setbox0=\vbox{\@@steptext{##2}}% +% \fi +% align + \hpos{\steptableprefix\cellcounter-t}{\box0}% + \endgraf + \egroup + \nointerlineskip + \kern\@@STPTvoffset} + \setbox2\vbox + {\doglobal\newcounter\cellcounter + #3\kern-\@@STPTvoffset} + \hbox + {\scratchdimen\wd0 + \advance\scratchdimen \MPllx bp + \raise\MPlly bp\box0 + \hskip-\scratchdimen + \hpos{\steptableprefix origin}{\box2}} + \popMPdrawing + \egroup + \ifinsidefloat \else \stopbaselinecorrection \@@STPTafter \fi} + +\def\MPtablelinesgraphic + {image ( drawline ( + \@@STELalternative, get_step_table_line(\cellcounter), + \@@STELrulethickness, \MPcolor{\@@STELcolor} ) )} + +\protect \endinput + +% A simple paragraph-flow test: + +\starttext + +\startbuffer +\startSTEPchart +\cells {A} {B} +\cells {one} {five} \texts{$+2$}{$-2$} +\cells {two} {four} \texts{$+3$}{$-3$} +\cells {three} {three} \texts{$+4$}{$-4$} +\cells {four} {two} \texts{$+5$}{$-5$} +\cells {five} {one} +\stopSTEPchart +\stopbuffer + +\getbuffer + +\startnarrower \getbuffer \stopnarrower + +\placefigure[left]{}{} \getbuffer + +\stoptext diff --git a/tex/context/base/m-streams.tex b/tex/context/base/m-streams.tex new file mode 100644 index 000000000..9d7e8d7dd --- /dev/null +++ b/tex/context/base/m-streams.tex @@ -0,0 +1,446 @@ +%D \module +%D [ file=m-streams, +%D version=2006.03.21, +%D title=\CONTEXT\ Modules, +%D subtitle=Streams, +%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 First we implement a simple left||right synchronization +%D mechanism, which we may perfect and extend over time. + +\unprotect + +\defineoutputstream [\v!left] +\defineoutputstream [\v!right] + +\definemarknote[\v!left] +\definemarknote[\v!right] + +\startsetups stream:\v!left:bottom + \flushmarknotes[\v!left] +\stopsetups +\startsetups stream:\v!right:bottom + \flushmarknotes[\v!right] +\stopsetups +\startsetups stream:\v!left:reset + \erasemarknotes[\v!left] +\stopsetups +\startsetups stream:\v!right:reset + \erasemarknotes[\v!right] +\stopsetups + +\def\LeftNote {\setmarknote [\v!left]} % {#1} +\def\RightNote {\setmarknote [\v!right]} % {#1} +\def\SwitchToLeft {\enableoutputstream [\v!left]} +\def\SwitchToRight {\enableoutputstream [\v!right]} +\def\SwitchToNormal {\enableoutputstream [\s!default]} +\def\SynchronizeLeftAndRight{\synchronizeoutputstreams[\v!left,\v!right]} +\def\FlushLeftAndRight {\flushoutputstreampages [\v!left,\v!right]} + +\protect + +% \topskip \strutheight +% \splittopskip\strutheight + +%D Example of usage: +%D +%D \starttyping +%D \nopenalties \setupinterlinespace[top=height] \setupcolors[state=start] +%D +%D \showgrid \showstruts +%D +%D \starttext +%D +%D \title{Whatever} \page +%D +%D \dorecurse {5} { +%D \let\RecurseLevel\recurselevel +%D \SwitchToLeft \dorecurse{10}{\dontleavehmode{\tf\RecurseLevel:l \begstrut \input tufte \endstrut \endgraf}} +%D \SwitchToRight \dorecurse{10}{\dontleavehmode{\sl\RecurseLevel:r \begstrut \input knuth \endstrut \endgraf}} +%D \SwitchToNormal \SynchronizeLeftAndRight +%D \SwitchToLeft \dorecurse{10}{\dontleavehmode{\bf\RecurseLevel:l \begstrut \input zapf \endstrut \endgraf}} +%D \SwitchToRight \dorecurse{10}{\dontleavehmode{\bs\RecurseLevel:r \begstrut \input davis \endstrut \endgraf}} +%D \SwitchToNormal \SynchronizeLeftAndRight +%D } +%D +%D \FlushLeftAndRight +%D +%D \stoptext +%D \stoptyping +%D +%D Another example: +%D +%D \starttyping +%D \nopenalties \setupinterlinespace[top=height] \setupcolors[state=start] +%D +%D \showgrid \showstruts +%D +%D \starttext +%D +%D \SwitchToNormal \FlushLeftAndRight \page +%D +%D \def\StartCouple{\page\SwitchToNormal} +%D \def\StopCouple {\SwitchToNormal \SynchronizeLeftAndRight \FlushLeftAndRight} +%D +%D \def\Original {\SwitchToNormal\SynchronizeLeftAndRight\SwitchToLeft} +%D \def\Translation{\SwitchToRight} +%D +%D \StartCouple +%D \dorecurse{10} { +%D \Original o: \begstrut \inright{\blackrule}\input tufte \endstrut \LeftNote {tufte} \endgraf +%D \Translation t: \begstrut \inleft {\blackrule}\input zapf \endstrut \RightNote{zapf} \endgraf +%D \Original o: \begstrut \inright{\blackrule}\input knuth \endstrut \LeftNote {knuth} \endgraf +%D \Translation t: \begstrut \inleft {\blackrule}\input davis \endstrut \RightNote{davis} \endgraf +%D \Original o: \begstrut \inright{\blackrule}\input douglas \endstrut \LeftNote {douglas} \endgraf +%D \Translation t: \begstrut \inleft {\blackrule}\input bryson \endstrut \RightNote{bryson} \endgraf +%D } +%D \StopCouple +%D \stoptext +%D \stoptyping + +%D Next we implement stream layers. + +\unprotect + +\def\overloadtextwidth#1% + {\makeupwidth#1\relax + \textwidth\makeupwidth + \hsize\makeupwidth} + +\startsetups streamlayer:default:settings + % set hsize etc, like \overloadtextwidth{12cm} +\stopsetups + +\startsetups streamlayer:default:extras + % flush goodies, like local floats +\stopsetups + +\startsetups streamlayer:default:place + \setlayer + [\currentstreamlayer] + [\c!preset=\v!left\v!top] + {\outputstreambox[\currentstreamlayer]}% +\stopsetups + +\startsetups streamlayer:default:copy + \setlayer + [\currentstreamlayer] + [\c!preset=\v!left\v!top] + {\outputstreamcopy[\currentstreamlayer]}% +\stopsetups + +\startsetups streamlayer:default:reset + \outputstreambox[\currentstreamlayer] +\stopsetups + +\startsetups streamlayer:default:flush + \tightlayer[\currentstreamlayer] +\stopsetups + +\def\definestreamlayer + {\dodoubleempty\dodefinestreamlayer} + +\def\dodefinestreamlayer[#1][#2]% + {\defineoutputstream[#1]% + \defineoutputstream[main]% + \definelayer[#1][\c!method=\v!fit,\c!width=\textwidth,#2]} + +\def\dostreamsetups#1% + {\doifsetupselse{streamlayer:\currentstreamlayer:#1} + {\directsetup{streamlayer:\currentstreamlayer:#1}} + {\directsetup{streamlayer:\s!default:#1}}} + +\def\startstreamlayer[#1]% + {\bgroup +% \def\startstreamlayer[##1]{\bgroup\let\stopstreamlayer\egroup}% + \edef\currentstreamlayer{#1}% + \enableoutputstream[main]% + \synchronizeoutput + \enableoutputstream[\currentstreamlayer]% + \bgroup + \dostreamsetups{settings}} + +\def\stopstreamlayer + {\endgraf + \egroup + \disableoutputstream % \enableoutputstream[\s!default]% + \outputstreambox[main]% +% \dostreamsetups{place}% +% \dostreamsetups{extras}% +% \dostreamsetups{flush}% + \egroup} + +\def\preparestreamlayer{\dosingleempty\dopreparestreamlayer} +\def\flushstreamlayer {\dosingleempty\doflushstreamlayer } +\def\placestreamlayer {\dosingleempty\doplacestreamlayer } + +\def\dopreparestreamlayer[#1]% + {\bgroup + \edef\currentstreamlayer{\iffirstargument#1\else\currentstreamlayer\fi}% + \dostreamsetups{place}% + \dostreamsetups{extras}% +% \dostreamsetups{flush}% + \egroup} + +\def\doflushstreamlayer[#1]% + {\bgroup + \edef\currentstreamlayer{\iffirstargument#1\else\currentstreamlayer\fi}% + \dostreamsetups{flush}% + \egroup} + +\def\doplacestreamlayer[#1]% + {\preparestreamlayer[#1]% + \flushstreamlayer[#1]} + +\protect + +%D Usage: + +%D \starttyping +%D \setupinterlinespace[top=height] +%D +%D \setupcolors[state=start] +%D +%D \definestreamlayer[block] +%D +%D \definemeasure[localtextwidth] [\dimexpr.7\textwidth\relax] +%D \definemeasure[localfloatwidth][\dimexpr.3\textwidth-2\bodyfontsize\relax] +%D +%D \startsetups streamlayer:block:settings +%D \hsize=\measure{localtextwidth} +%D \setupfloat[figure][maxwidth=\measure{localfloatwidth}] +%D \stopsetups +%D +%D \startsetups streamlayer:block:extras +%D \setuplocalfloats +%D [before=\blank, +%D after=\blank, +%D inbetween=\blank] +%D \setbox\scratchbox\vbox{\hsize\measure{localfloatwidth}\getlocalfloats} +%D \ifdim\ht\scratchbox>\thelayerheight\currentstreamlayer\relax +%D % more float than text +%D \setlayerframed +%D [\currentstreamlayer] +%D [preset=righttop] +%D [frame=off, +%D offset=overlay] +%D {\box\scratchbox} +%D \else +%D % more text than float +%D \setuplocalfloats +%D [before=\vfill, +%D after=\removedepth\vfill, +%D inbetween=\removedepth\vfill] +%D \setlayerframed +%D [\currentstreamlayer] +%D [preset=righttop] +%D [frame=off, +%D offset=overlay] +%D {\vbox to \thelayerheight\currentstreamlayer {\hsize\measure{localfloatwidth}\getlocalfloats}} +%D \fi +%D \resetlocalfloats +%D \stopsetups +%D +%D \startsetups streamlayer:block:place +%D \setlayerframed +%D [\currentstreamlayer] +%D [preset=lefttop] +%D [frame=off, +%D offset=overlay] +%D {\outputstreambox[\currentstreamlayer]}% +%D \stopsetups +%D +%D \startsetups streamlayer:block:flush +%D \framed +%D [offset=overlay, +%D frame=off, +%D background=color, +%D backgroundcolor=red] +%D {\tightlayer[\currentstreamlayer]} +%D \stopsetups +%D +%D \setupbodyfont[small] +%D +%D \starttext +%D +%D \dorecurse {10} { +%D \startstreamlayer[block] +%D \title{Sample \recurselevel} +%D \input tufte \endgraf +%D \placefigure[local]{}{} +%D \placefigure[local]{}{} +%D \ifodd\recurselevel\relax \placefigure[local]{}{} \fi +%D \startitemize[columns] +%D \item xxx +%D \item xxx +%D \item xxx +%D \item xxx +%D \item xxx +%D \stopitemize +%D \stopstreamlayer +%D \placestreamlayer[block] +%D } +%D +%D \dorecurse {10} { +%D \startstreamlayer[block] +%D \title{Sample \recurselevel} +%D \startcolumns +%D \input tufte +%D \stopcolumns +%D \stopstreamlayer +%D \placestreamlayer[block] +%D } +%D +%D \stoptext +%D \stoptyping + +\def\starttextstreamlayer + {\startstreamlayer} + +\def\stoptextstreamlayer + {\endgraf + % maybe depth if no proper depth and no skip + \removelastskip + \stopstreamlayer} + +\def\placetextstreamlayer{\placestreamlayer} + +%D \starttyping +%D \definestreamlayer[whatever][width=12cm] +%D +%D \startstreamlayer[whatever] +%D \startitemize[columns,two][after=] +%D \item one +%D \item two +%D \item three +%D \item four +%D \stopitemize +%D \stopstreamlayer +%D +%D \framed[strut=no,align=normal]{\placestreamlayer[whatever]\obeydepth} +%D +%D \starttextstreamlayer[whatever] +%D \startitemize[columns,two] +%D \item one +%D \item two +%D \item three +%D \item four +%D \stopitemize +%D \stoptextstreamlayer +%D +%D \framed[strut=no]{\placetextstreamlayer[whatever]} +%D \stoptyping + +\endinput + +\setupinterlinespace[top=height] + +\setupcolors[state=start] + +\definestreamlayer[block] + +\definemeasure[localtextwidth] [\dimexpr.7\textwidth\relax] +\definemeasure[localfloatwidth][\dimexpr.3\textwidth-2\bodyfontsize\relax] + +\startsetups streamlayer:block:settings + \hsize=\measure{localtextwidth} + \setupfloat[figure][maxwidth=\measure{localfloatwidth}] +\stopsetups + +\startsetups streamlayer:block:extras + \setuplocalfloats + [before=\whitespace\blank, + after=\whitespace\blank, + inbetween=\whitespace\blank] + \setbox\scratchbox\vbox{\hsize\measure{localfloatwidth}\getlocalfloats} + \ifdim\ht\scratchbox>\thelayerheight\currentstreamlayer\relax + % more float than text + \setlayerframed + [\currentstreamlayer] + [preset=righttop] + [frame=off, + offset=overlay] + {\box\scratchbox} + \else + % more text than float + \setuplocalfloats + [before=\vfill, + after=\removedepth\vfill, + inbetween=\removedepth\vfill] + \setlayerframed + [\currentstreamlayer] + [preset=righttop] + [frame=off, + offset=overlay] + {\vbox to \thelayerheight\currentstreamlayer {\hsize\measure{localfloatwidth}\getlocalfloats}} + \fi + \resetlocalfloats +\stopsetups + +\startsetups streamlayer:block:place + \setlayerframed + [\currentstreamlayer] + [preset=lefttop] + [frame=off, + offset=overlay] + {\outputstreambox[\currentstreamlayer]}% +\stopsetups + +\startsetups streamlayer:block:flush + \framed + [offset=overlay, + frame=off, + background=color, + backgroundcolor=red] + {\tightlayer[\currentstreamlayer]} +\stopsetups + +\setupbodyfont[small] + +\starttext + +% \definestreamlayer[block] +% +% \startstreamlayer[block] +% \title{Sample \recurselevel} +% \startcolumns +% \dorecurse{4}{\input tufte \par} +% \stopcolumns +% \stopstreamlayer +% \placestreamlayer[block] + +\dorecurse {10} { + \startstreamlayer[block] + \title{Sample \recurselevel} + \input tufte \endgraf + \placefigure[local]{}{} + \placefigure[local]{}{} + \ifodd\recurselevel\relax \placefigure[local]{}{} \fi + \startitemize[columns] + \item xxx + \item xxx + \item xxx + \item xxx + \item xxx + \stopitemize + \stopstreamlayer + \placestreamlayer[block] +} + +\dorecurse {10} { + \startstreamlayer[block] + \title{Sample \recurselevel} + \startcolumns + \input tufte + \stopcolumns + \stopstreamlayer + \placestreamlayer[block] +} + +\stoptext diff --git a/tex/context/base/m-subsub.tex b/tex/context/base/m-subsub.tex new file mode 100644 index 000000000..4395ded8a --- /dev/null +++ b/tex/context/base/m-subsub.tex @@ -0,0 +1,76 @@ +%D \module +%D [ file=m-subsub, +%D version=2000.12.14, +%D title=\CONTEXT\ Private Modules, +%D subtitle=More Section Levels, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. This module is not public. + +\unprotect + +\definesection[\s!section-8] +\definesection[\s!section-9] +\definesection[\s!section-10] +\definesection[\s!section-11] +\definesection[\s!section-12] + +\definehead + [\v!subsubsubsubsubsection] + [\c!section=\s!section-8, + \c!default=\v!subsubsubsubsection] + +\definehead + [\v!subsubsubsubsubsubsection] + [\c!section=\s!section-9, + \c!default=\v!subsubsubsubsubsection] + +\definehead + [\v!subsubsubsubsubsubsubsection] + [\c!section=\s!section-10, + \c!default=\v!subsubsubsubsubsubsection] + +\definehead + [\v!subsubsubsubsubsubsubsubsection] + [\c!section=\s!section-11, + \c!default=\v!subsubsubsubsubsubsubsection] + +\definehead + [\v!subsubsubsubsubsubsubsubsubsection] + [\c!section=\s!section-12, + \c!default=\v!subsubsubsubsubsubsubsubsection] + +\definehead + [\v!subsubsubsubsubsubject] + [\c!coupling=\v!subsubsubsubsubsection, + \c!default=\v!subsubsubsubsubsection, + \c!incrementnumber=\v!no] + +\definehead + [\v!subsubsubsubsubsubsubject] + [\c!coupling=\v!subsubsubsubsubsubsection, + \c!default=\v!subsubsubsubsubsubsection, + \c!incrementnumber=\v!no] + +\definehead + [\v!subsubsubsubsubsubsubsubject] + [\c!coupling=\v!subsubsubsubsubsubsubsection, + \c!default=\v!subsubsubsubsubsubsubsection, + \c!incrementnumber=\v!no] + +\definehead + [\v!subsubsubsubsubsubsubsubsubject] + [\c!coupling=\v!subsubsubsubsubsubsubsubsection, + \c!default=\v!subsubsubsubsubsubsubsubsection, + \c!incrementnumber=\v!no] + +\definehead + [\v!subsubsubsubsubsubsubsubsubsubject] + [\c!coupling=\v!subsubsubsubsubsubsubsubsubsection, + \c!default=\v!subsubsubsubsubsubsubsubsubsection, + \c!incrementnumber=\v!no] + +\protect \endinput diff --git a/tex/context/base/m-tex4ht.tex b/tex/context/base/m-tex4ht.tex new file mode 100644 index 000000000..8a3dc9dbb --- /dev/null +++ b/tex/context/base/m-tex4ht.tex @@ -0,0 +1,9 @@ +%D Preliminaty module + +\input tex4ht.sty + +\appendtoks + \Preamble{\env{ht-1},\env{ht-2},html}\EndPreamble +\to \everystarttext + +\endinput \ No newline at end of file diff --git a/tex/context/base/m-timing.tex b/tex/context/base/m-timing.tex new file mode 100644 index 000000000..f02a90087 --- /dev/null +++ b/tex/context/base/m-timing.tex @@ -0,0 +1,102 @@ +%D \module +%D [ file=m-timing, +%D version=2007.12.23, +%D title=\CONTEXT\ Modules, +%D subtitle=Timing, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=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. + +\doifnotmode{mkiv}{\endinput} + +\ifx\ShowNamedUsage\undefined \else \endinput \fi + +%D Written at the end of 2007, this module is dedicated to Taco. Reaching this +%D point in \LUATEX\ was a non trivial effort. By visualizing a bit what happens +%D when pages come out of \LUATEX, you may get an idea what is involved. It took +%D much time an dedication to reach this point in the development. Add to that +%D those daily Skype intense discussion, testing and debugging moments. Time flies +%D but progress is impressive. The motto of this module could be: what you see +%D is what you get. An there is much more to come \unknown. + +% \usemodule[timing] +% \setupcolors[state=start] +% \starttext +% \dorecurse{200}{\input tufte \par} \ShowUsage{} +% \stoptext + +\definecolor[usage:line] [darkred] +\definecolor[usage:time] [darkblue] +\definecolor[usage:frame][darkgray] + +\ctxloadluafile{trac-tim}{} + +\startluacode +local progress = plugins.progress + +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 + 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 + +\startnotmode[no-timing] + \appendtoks\ctxlua{plugins.progress.store()}\to\everystarttext + \appendtoks\ctxlua{plugins.progress.store()}\to\everyshipout + \ctxlua{main.register_stop_actions(function() plugins.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(plugins.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 + p := p xstretched w ; + b := boundingbox (llcorner p -- llcorner p shifted (w,h)) ; + pickup pencircle scaled 3pt ; linecap := butt ; + draw b withcolor \MPcolor{usage:frame} ; + draw p withcolor \MPcolor{usage:line} ; + if ("#3" <> "") and ("#3" <> "#2") : + q := \ctxlua{tex.sprint(plugins.progress.path("#1","#3"))} ; +% q := q shifted -llcorner q ; + if bbwidth(q) > 1 : + q := q xstretched w ; + pickup pencircle scaled 1.5pt ; linecap := butt ; + draw q withcolor \MPcolor{usage:time} ; + fi ; + fi ; + fi ; + endgroup ; + \stopMPcode\egroup + \scratchdimen\wd\scratchbox + \ifdim\scratchdimen>\zeropoint + \startlinecorrection + \box\scratchbox \endgraf + \hbox to \scratchdimen{\tttf\strut\detokenize{#2}\hss + min:\ctxlua{tex.sprint(plugins.progress.bot("#1","\detokenize{#2}"))}, % + max:\ctxlua{tex.sprint(plugins.progress.top("#1","\detokenize{#2}"))}, % + pages:\ctxlua{tex.sprint(plugins.progress.pages("#1"))}% + }% + \stoplinecorrection + \fi} + +\def\LoadUsage #1{\ctxlua{plugins.progress.convert("#1")}} +\def\ShowUsage #1{\ctxlua{plugins.progress.show("#1",nil,nil,"elapsed_time")}} +\def\ShowMemoryUsage#1{\ctxlua{plugins.progress.show("#1",nil,{}, "elapsed_time")}} +\def\ShowNodeUsage #1{\ctxlua{plugins.progress.show("#1",{},nil, "elapsed_time")}} + +\endinput diff --git a/tex/context/base/m-trackers.tex b/tex/context/base/m-trackers.tex new file mode 100644 index 000000000..cfcbbabff --- /dev/null +++ b/tex/context/base/m-trackers.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 new file mode 100644 index 000000000..9c550eca7 --- /dev/null +++ b/tex/context/base/m-translate.tex @@ -0,0 +1,88 @@ +%D \module +%D [ file=m-translate, +%D version=2008.10.09, +%D title=\CONTEXT\ Modules, +%D subtitle=Translations, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=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. + +\doifnotmode{mkiv}{\endinput} + +%D We can make this module more clever (wildcards and such) but since +%D it's only a demo we stick to the simple case for now. After all, it's +%D better to fix your source. + +\startluacode + translators = { } + + local compiled, list = nil, nil + + function translators.register(from,to) + local l = lpeg.P(from)/to + if not list then + list = l + else + list = list + l + end + compiled = nil + end + + function translators.translate(s) + if list then + if not compiled then + compiled = lpeg.Cs((list + lpeg.P(1))^0) + end + return compiled:match(s) + else + return s + end + end + + function translators.reset(s) + resolvers.install_text_filter("user",nil) + list, compiled = nil, nil + end + function translators.enable(s) + resolvers.install_text_filter("user",translators.translate) + end + function translators.disable(s) + resolvers.install_text_filter("user",nil) + end +\stopluacode + +\unprotect + +\def\translateinput{\dodoubleargument\dotranslateinput} + +\def\dotranslateinput[#1][#2]{\ctxlua{translators.register(\!!bs#1\!!es,\!!bs#2\!!es)}} + +\def\resetinputtranslation {\ctxlua{translators.reset()}} +\def\enableinputtranslation {\ctxlua{translators.enable()}} +\def\disableinputtranslation{\ctxlua{translators.disable()}} + +\def\readtranslatedfile#1% + {\enableinputtranslation + \readfile{#1}\donothing\donothing + \disableinputtranslation} + +\protect + +\doifnotmode{demo}{\endinput} + +\starttext + + \translateinput[Moica][Mojca] + \translateinput[Idris][Idris (aka ادريس)] + + \enableinputtranslation + + Well, it's not that hard to satisfy Idris and Moica. + + \readtranslatedfile{tufte} + +\stoptext diff --git a/tex/context/base/m-tryout.tex b/tex/context/base/m-tryout.tex new file mode 100644 index 000000000..4aa50376d --- /dev/null +++ b/tex/context/base/m-tryout.tex @@ -0,0 +1,55 @@ +%D \module +%D [ file=m-tryout, +%D version=2002.05.10, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Tryout Features, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 + +\unprotect + +%D The following macros make sure that active colons work well +%D in French, a feature enabled with: +%D +%D \starttyping +%D \useencoding[ffr] \mainlanguage[fr] +%D \stoptyping +%D +%D This trick will disappear when proved robust. + +\startmode[activecolon] + +% this is now default + +\gdef\sectionseparator{-} + +\gdef\@@filterfirstpart [#1--#2]{#1} +\gdef\@@filtersecondpart [#1--#2]{#2} + +\gdef\@@filterblockpart [#1--#2--#3]{#1} +\gdef\@@filternumberpart [#1--#2--#3]{#2} +\gdef\@@filterpagepart [#1--#2--#3]{#3} +\gdef\@@filterblocknumberpart[#1--#2--#3]{#1--#2} + +\gdef\@@filterheadpart[#1]{\@EA\@@dofilterheadpart\@EA[#1-0]} +\gdef\@@filtertailpart[#1]{\@EA\@@dofiltertailpart\@EA[#1-0]} + +\gdef\@@dofilterheadpart[#1-#2]{#1} +\gdef\@@dofiltertailpart[#1-#2]{#2} + +\gdef\@@filterlevelpart[#1--#2--#3]{\@@dofilterlevelpart[#2-0-0-0-0]} + +\gdef\@@dofilterlevelpart[#1-0-0-0-#2]{#1} + +\reopenutilities + +\stopmode + +\protect \endinput diff --git a/tex/context/base/m-units.tex b/tex/context/base/m-units.tex new file mode 100644 index 000000000..d186c542b --- /dev/null +++ b/tex/context/base/m-units.tex @@ -0,0 +1,825 @@ +%D \module +%D [ file=m-units, +%D version=1997.03.19, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Scientific Units, +%D author={Hans Hagen \& Ton Otten}, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Scientific units can be typeset in math mode pretty well, +%D but occasionally one has to take care of spacing. +%D Furthermore, entering these units is not that natural as +%D wanted. Therefore this module presents a more natural way of +%D doing things, like: +%D +%D \starttyping +%D 1.23 \Cubic \Meter \Per \Second +%D \stoptyping +%D +%D This example shows that we use the order in which we say +%D things, instead of typeset things. There is a separate +%D manual for this module. + +%D Message number~1 deals with overruling the \type {\Degrees} +%D macro defined in the core modules. Let's say that this is +%D an upward compatibility issue. + +\startmessages dutch library: units + title: eenheden + 1: gebruik \string\Degrees\space\string\Celsius\space in plaats van \string\Celsius ! +\stopmessages + +\startmessages english library: units + title: units + 1: use \string\Degrees\space\string\Celsius\space instead of \string\Celsius ! +\stopmessages + +\startmessages german library: units + title: Einheiten + 1: Verwende \string\Degrees\space\string\Celsius\space statt \string\Celsius ! +\stopmessages + +\startmessages italian library: units + title: unita + 1: usare \string\Degrees\space\string\Celsius\space invece di \string\Celsius ! +\stopmessages + +\startmessages norwegian library: units + title: enheter + 1: bruk \string\Degrees\space\string\Celsius\space istedenfor \string\Celsius ! +\stopmessages + +\startmessages romanian library: units + title: unitati + 1: folositi \string\Degrees\space\string\Celsius\space in locul \string\Celsius ! +\stopmessages + +\startmessages french library: units + title: unitas + 1: utilisez \string\Degrees\space\string\Celsius\space A la place de \string\Celsius ! +\stopmessages + +\unprotect + +%D This runtime loadable module implements a way of defining +%D units. The core macro is \type {\dimension}, a rather clever +%D one that is able to cooperate with some other dimension +%D related macros. As said, this module enables user to enter: +%D +%D \startbuffer +%D some 10 \Square \Meter \Per \Second or more +%D \stopbuffer +%D +%D \getbuffer +%D +%D as: +%D +%D \typebuffer +%D +%D The units itself are implemented as synonyms. +%D +%D \starttyping +%D \definesynonyms [unit] [units] [\unitmeaning] +%D \setupsynonyms [unit] [textstyle=\dimension] +%D \stoptyping +%D +%D This definition means that we can ask for the meaning of a +%D unit using \type {\unitmeaning} and get a list of used +%D units by saying \type {\placelistofunits} +%D +%D We have to use the command \type {\unitmeaning} instead +%D of \type {\meaning}, simply because the latter is a \TEX\ +%D primitive we don't want to loose. We use the label text +%D mechanism for translations. + +%D \macros +%D {dimension} +%D +%D The core of this module is the low level macro \type +%D {\dimension}. Before presenting this macro, it's best to +%D look at some applications, because it's supposed to show +%D some intelligence that can beter be understood from the +%D context. +%D +%D The next useless examples show some of the cases we want +%D to handle in a proper way. +%D +%D \startbuffer +%D ... 10 \Square \Meter \Per \Volt \ +%D ... 10 \Square \Meter \Volt \ +%D ... 10 \Meter \Volt \ +%D ... 10 \Milli \Square \Meter \Per \Volt \ +%D ... 10 \Square \Milli \Meter \Per \Volt \ +%D ... 10 \Meter \Times \Meter \ +%D ... 10 \Square \Meter \Times \Meter \ +%D ... 10 \Square \Milli \Meter \Times \Meter \ +%D \stopbuffer +%D +%D \typebuffer +%D +%D Becomes: +%D +%D \getbuffer + +%D \macros +%D {mathematicstypeface, dimensiontypeface, +%D dimensionhalfspace, dimensionbackspace} +%D +%D There are some low level constants, that can be changed +%D when needed. Some day I will write a decent setup command. + +\def\mathematicstypeface{\rm} +\def\dimensiontypeface {\tf} + +\def\dimensionhalfspace {\ifmmode\,\else\hskip+.1em\relax\fi} +\def\dimensionbackspace {\ifmmode\!\else\hskip-.1em\relax\fi} + +%D \macros +%D {smashdimensionpower} +%D +%D Sometimes the baseline distance is not enough to provide +%D for superscripts, so we smash their height by default. + +\newif\ifsmashdimensionpower \smashdimensionpowertrue + +%D The dimension mechanism uses a lot of signals to keep +%D track if the current state. + +\newsignal\dimensionsignal +\newsignal\dimensionpowersignal +\newsignal\dimensionmidfixsignal +\newsignal\dimensionaddfixsignal + +\let\thedimensionprefix = \empty +\let\thedimensionpower = \empty + +%D \macros +%D {spaceddimensions,textdimensions} +%D +%D The actual definition of \type {\dimension} overruled the +%D one in the core modules. The boolean can be used to +%D force spacing between units. Vergelijk {\Newton \Meter} +%D eens met {\spaceddimensionstrue \Newton \Meter}. The +%D rather ugly test prevents problems with nested dimensions. + +\newif\ifspaceddimensions \spaceddimensionsfalse % user switch +\newif\iftextdimensions \textdimensionsfalse % user switch + +%D You can see the consequence of forcing text dimensions +%D when you compare the following code: +%D +%D \starttyping +%D {\rm test \Square \Meter \Per \Second\ ziezo\Degrees} \par +%D {\ss test \Square \Meter \Per \Second\ ziezo} \par +%D {\tt test \Square \Meter \Per \Second\ ziezo} +%D +%D \textdimensionstrue +%D +%D {\rm test \Square \Meter \Per \Second\ ziezo} \par +%D {\ss test \Square \Meter \Per \Second\ ziezo} \par +%D {\tt test \Square \Meter \Per \Second\ ziezo} +%D \stoptyping + +\newif\ifnesteddimension \nesteddimensionfalse % local switch + +\def\dodimensionpower#1% + {\iftextdimensions\expandafter\high\else\expandafter^\fi{#1}} + +\def\ustartmathmode {\iftextdimensions\else\expandafter\startmathmode \fi} +\def\ustopmathmode {\iftextdimensions\else\expandafter\stopmathmode \fi} +\def\umathematicstypeface{\iftextdimensions\else\expandafter\mathematicstypeface\fi} + +%D In forced text mode, we ignore spacing in monospaced fonts. + +\def\udimensionhalfspace {\dodimensionspace\dimensionhalfspace} +\def\udimensionbackspace {\dodimensionspace\dimensionbackspace} + +\def\dodimensionspace + {\iftextdimensions + \begingroup + \setbox0\hbox{i}% + \setbox2\hbox{m}% + \ifdim\wd0=\wd2 + \endgroup + \@EAEAEA\gobbleoneargument + \else + \endgroup + \fi + \fi} + +\unexpanded\def\dimension#1% + {\begingroup + \global\let\savedthedimensionprefix\thedimensionprefix + \global\let\savedthedimensionpower\thedimensionpower + \unexpanded\def\dimension##1{\global\nesteddimensiontrue}% + \let\dimensionprefix\dimension + \let\dimensionmidfix\dimension + \let\dimensionsuffix\dimension + \let\dimensionpower \dimension + \global\nesteddimensionfalse + \setbox\scratchbox\hbox{\ustartmathmode#1\ustopmathmode}% pre-roll + \global\let\thedimensionprefix\savedthedimensionprefix + \global\let\thedimensionpower \savedthedimensionpower + \endgroup + \ifnesteddimension#1\else\dodimension{#1}\fi} + +\def\dodimension#1% + {\dontbreakdimension + \ifdim\scratchdimen=\zeropoint\relax + \ifmmode + \udimensionhalfspace + \udimensionhalfspace + \fi + \ustartmathmode\dimensiontypeface + \else + \ustartmathmode\dimensiontypeface + \ifspaceddimensions + \ifdim\scratchdimen=\dimensionsignal\relax + \udimensionhalfspace + \else\ifdim\scratchdimen=\dimensionpowersignal\relax + \udimensionhalfspace + \fi + \fi + \fi + \fi + \umathematicstypeface\thedimensionprefix#1% + \ifx\thedimensionpower\empty + \else\ifsmashdimensionpower + \setbox\scratchbox=\hbox + {\iftextdimensions + \tx\thedimensionpower + \else + $\scriptstyle\thedimensionpower$% + \fi}% + \ht\scratchbox=\zeropoint + \dodimensionpower{\box\scratchbox}% + \else + \dodimensionpower{\thedimensionpower}% + \fi\fi + \ustopmathmode + % otherwise nobreak before space in 2 \Milli \Meter\ blabla + \doifnotmode{atpragma}{\nobreak}% this was always \nobreak + % only test this at pragma + \ifx\thedimensionpower\empty + \hskip\dimensionsignal + \else + \hskip\dimensionpowersignal + \fi + \global\let\thedimensionprefix\empty + \global\let\thedimensionpower\empty} + +%D \macros +%D {dontbreakdimension, +%D dimensionprefix, dimensionaddfix, +%D dimensionnopfix, dimensionmidfix, +%D dimensionpower} +%D +%D Here are some auxilliary macros. + +\def\dontbreakdimension + {\scratchdimen\lastskip + \unskip + \nobreak + \hskip\scratchdimen + \nobreak} + +\def\dimensionprefix#1% + {\gdef\thedimensionprefix{#1}} + +\def\dimensionaddfix#1% + {\unskip + %\mathematics{\umathematicstypeface#1}% + \ustartmathmode\umathematicstypeface#1\ustopmathmode + \nobreak + \hskip\dimensionaddfixsignal} + +\def\dimensionnopfix#1% + {\dontbreakdimension + \ifdim\scratchdimen=\dimensionpowersignal\relax + \ustartmathmode + \else + \ustartmathmode + \udimensionhalfspace + \nobreak + \fi + \umathematicstypeface#1% + \ustopmathmode + \nobreak + \hskip\dimensionsignal} + +\def\dimensionmidfix#1% + {\dontbreakdimension + \ifdim\scratchdimen=\dimensionpowersignal\relax + \ustartmathmode + \udimensionbackspace + \nobreak + \else + \ustartmathmode + \fi + \umathematicstypeface#1% + \ustopmathmode + \nobreak + \hskip\dimensionmidfixsignal} + +\def\dimensionpower#1% + {\gdef\thedimensionpower{#1}} + +%D \macros +%D {SIunits, noSI, doSI} +%D +%D Some low level unit switching macros: + +\newif\ifSIunits \SIunitstrue + +\def\noSI#1{\begingroup\SIunitsfalse#1\endgroup} +\def\doSI#1{\begingroup\SIunitstrue #1\endgroup} + +%D \macros +%D {Degrees} +%D +%D We can fake the degrees symbol with: + +\def\Degrees{\dimensionaddfix{\mathematics{^\circ}}} + +%D \macros +%D {Unit, NoUnit} +%D +%D When a dimension has no leading number, we can use \type +%D {\Unit}, and when no unit is appended, \type {\NoUnit} is +%D to be used, just to prevent the prefix migrating to the +%D next occasion. + +\def\Unit {\hskip\dimensionsignal} +\def\NoUnit {\dimension{}} + +%D The mechanism described at the top of this module, depends +%D on several dimensional components, like prefixes: + +\def\Atto {\dimensionprefix{a}} +\def\Femto {\dimensionprefix{f}} +\def\Pico {\dimensionprefix{p}} +\def\Nano {\dimensionprefix{n}} +\def\Micro {\dimensionprefix{\iftextdimensions u\else\mu\fi}} +\def\Milli {\dimensionprefix{m}} +\def\Centi {\dimensionprefix{c}} +\def\Deci {\dimensionprefix{d}} +\def\Hecto {\dimensionprefix{h}} +\def\Kilo {\dimensionprefix{k}} +\def\Mega {\dimensionprefix{M}} +\def\Giga {\dimensionprefix{G}} +\def\Terra {\dimensionprefix{T}} % for old times sake +\def\Tera {\dimensionprefix{T}} +\def\Peta {\dimensionprefix{P}} +\def\Exa {\dimensionprefix{E}} + +%D and operators: + +\def\Times {\dimensionnopfix{\iftextdimensions.\else\cdot\fi}} +\def\Solidus {\dimensionmidfix{/}} +\def\Per {\dimensionmidfix{/}} +\def\OutOf {\dimensionnopfix{:}} + +%D and suffixes: + +\def\Linear {\dimensionpower{1}} +\def\Square {\dimensionpower{2}} +\def\Cubic {\dimensionpower{3}} + +\def\Inverse {\dimensionpower{-1}} +\def\ILinear {\dimensionpower{-1}} +\def\ISquare {\dimensionpower{-2}} +\def\ICubic {\dimensionpower{-3}} + +%D Apart from these components, the units themselves are +%D defined using the synonym mechanism. First we define some +%D length and volume related units. + +\getvalue{\v!unit} [Meter] {m} {meter} +\getvalue{\v!unit} [pMeter] {\Pico \Meter} {picometer} +\getvalue{\v!unit} [nMeter] {\Nano \Meter} {nanometer} +\getvalue{\v!unit} [uMeter] {\Micro \Meter} {micrometer} +\getvalue{\v!unit} [mMeter] {\Milli \Meter} {millimeter} +\getvalue{\v!unit} [cMeter] {\Centi \Meter} {centimeter} +\getvalue{\v!unit} [dMeter] {\Deci \Meter} {decimeter} +\getvalue{\v!unit} [hMeter] {\Hecto \Meter} {hectometer} +\getvalue{\v!unit} [kMeter] {\Kilo \Meter} {kilometer} + +%D After some discussion on the \CONTEXT\ mailing list in +%D february 2002 it was decided to go from L to l for liters +%D (Karel Wesselings alternative: \mathematics{\ell}). + +\getvalue{\v!unit} [Liter] {l} {liter} +\getvalue{\v!unit} [mLiter] {\Milli \Liter} {milliliter} +\getvalue{\v!unit} [cLiter] {\Centi \Liter} {centiliter} +\getvalue{\v!unit} [dLiter] {\Deci \Liter} {deciliter} + +%D Next we define time related units (\type {\ifSI} still dutch only). + +\getvalue{\v!unit} [Sec] {s} {\labeltext{u:sec}} +\getvalue{\v!unit} [fSec] {\Femto \Sec} {\labeltext{u:fsec}} +\getvalue{\v!unit} [pSec] {\Pico \Sec} {\labeltext{u:psec}} +\getvalue{\v!unit} [nSec] {\Nano \Sec} {\labeltext{u:nsec}} +\getvalue{\v!unit} [uSec] {\Micro \Sec} {\labeltext{u:usec}} +\getvalue{\v!unit} [mSec] {\Milli \Sec} {\labeltext{u:msec}} +\getvalue{\v!unit} [Year] {\ifSIunits a \else j\fi} {\labeltext{u:year}} +\getvalue{\v!unit} [Month] {m} {\labeltext{u:month}} +\getvalue{\v!unit} [Week] {w} {\labeltext{u:week}} +\getvalue{\v!unit} [Day] {d} {\labeltext{u:day}} +\getvalue{\v!unit} [Hour] {\ifSIunits h \else u\fi} {\labeltext{u:hour}} +\getvalue{\v!unit} [Min] {min} {\labeltext{u:min}} + +\setuplabeltext + [\s!nl] + [u:sec=seconde, + u:psec=picoseconde, + u:fsec=femtoseconde, + u:nsec=nanoseconde, + u:usec=microseconde, + u:msec=milliseconde, + u:year=jaar, + u:month=maand, + u:week=week, + u:day=dag, + u:hour=uur, + u:min=minuten] + +\setuplabeltext + [\s!en] + [u:sec=second, + u:fsec=femtosecond, + u:psec=picosecond, + u:nsec=nanosecond, + u:usec=microsecond, + u:msec=millisecond, + u:year=year, + u:month=month, + u:week=week, + u:day=day, + u:hour=hour, + u:min=minutes] + +\setuplabeltext + [\s!de] + [u:sec=Sekunde, + u:fsec=Femtosekunde, + u:psec=Picosekunde, + u:nsec=Nanosekunde, + u:usec=Microsekunde, + u:msec=Millisekunde, + u:year=Jahr, + u:month=Monat, + u:week=Woche, + u:day=Tag, + u:hour=Stunde, + u:min=Minuten] + +\setuplabeltext + [\s!it] + [u:sec=secondo, + u:fsec=femtosecondo, + u:psec=picosecondo, + u:nsec=nanosecondo, + u:usec=microsecondo, + u:msec=millisecondo, + u:year=anno, + u:month=mese, + u:week=settimana, + u:day=giorno, + u:hour=ora, + u:min=minuti] + +%D Then we define some angles. + +\getvalue{\v!unit} [Rad] {rad} {\labeltext{u:rad}} +\getvalue{\v!unit} [Deg] {{\mathematics{^\circ}}} {\labeltext{u:deg}} + +\setuplabeltext + [\s!nl] + [u:rad=hoek radialen, + u:deg=hoek graden] + +\setuplabeltext + [\s!en] + [u:rad=angle radians, + u:deg=angle degrees] + +\setuplabeltext + [\s!de] + [u:rad=Bogenma\SS, + u:deg=Gradma\SS] + +\setuplabeltext + [\s!it] + [u:rad=radianti, + u:deg=angoli sessagesimali] + +%D Rotation and frequency related units are defined by: + +\getvalue{\v!unit} [Hertz] {Hz} {Hertz} +\getvalue{\v!unit} [kHertz] {\Kilo \Hertz} {kilo Hertz} +\getvalue{\v!unit} [MHertz] {\Mega \Hertz} {mega Hertz} +\getvalue{\v!unit} [GHertz] {\Giga \Hertz} {giga Hertz} +\getvalue{\v!unit} [THertz] {\Tera \Hertz} {tera Hertz} +\getvalue{\v!unit} [mHertz] {\Milli \Hertz} {milli Hertz} + +\getvalue{\v!unit} [RevPerSec] {RPS} {\labeltext{u:rps}} +\getvalue{\v!unit} [RevPerMin] {RPM} {\labeltext{u:rpm}} + +\setuplabeltext + [\s!nl] + [u:rps=omwentelingen per seconde, + u:rpm=omwentelingen per minuut] + +\setuplabeltext + [\s!en] + [u:rps=revolutions per second, + u:rpm=revolutions per minute] + +\setuplabeltext + [\s!de] + [u:rps=Umdrehungen pro Sekunde, + u:rpm=Umdrehungen pro Minute] + +\setuplabeltext + [\s!it] + [u:rps=giri al secondo, + u:rpm=giri al minuto] + +%D Mass and force: + +\getvalue{\v!unit} [Gram] {g} {gram} +\getvalue{\v!unit} [uGram] {\Micro \Gram} {microgram} +\getvalue{\v!unit} [mGram] {\Milli \Gram} {milligram} +\getvalue{\v!unit} [kGram] {\Kilo \Gram} {kilogram} +\getvalue{\v!unit} [Atom] {u} {\labeltext{u:u}} + +\getvalue{\v!unit} [Newton] {N} {Newton} +\getvalue{\v!unit} [kNewton] {\Kilo \Newton} {kilo Newton} + +\getvalue{\v!unit} [Pascal] {Pa} {Pascal} +\getvalue{\v!unit} [mPascal] {\Milli \Pascal} {milli Pascal} +\getvalue{\v!unit} [kPascal] {\Kilo \Pascal} {kilo Pascal} + +\setuplabeltext + [\s!nl] + [u:u=atomaire massa eenheid] + +\setuplabeltext + [\s!en] + [u:u=atom mass unit] + +\setuplabeltext + [\s!de] + [u:u=Atomare Masseneinheit] + +\setuplabeltext + [\s!it] + [u:u=unit\`a di massa atomica] + +%D Energy units comes in two alternatives: + +\getvalue{\v!unit} [Joule] {J} {Joule} +\getvalue{\v!unit} [mJoule] {\Milli \Joule} {milli Joule} +\getvalue{\v!unit} [kJoule] {\Kilo \Joule} {kilo Joule} +\getvalue{\v!unit} [MJoule] {\Mega \Joule} {mega Joule} +\getvalue{\v!unit} [GJoule] {\Giga \Joule} {giga Joule} + +\getvalue{\v!unit} [Watt] {W} {Watt} +\getvalue{\v!unit} [mWatt] {\Milli \Watt} {milli Watt} +\getvalue{\v!unit} [kWatt] {\Kilo \Watt} {kilo Watt} +\getvalue{\v!unit} [MWatt] {\Mega \Watt} {mega Watt} +\getvalue{\v!unit} [GWatt] {\Giga \Watt} {giga Watt} +\getvalue{\v!unit} [TWatt] {\Tera \Watt} {tera Watt} + +%D Although Celsius is no longer permitted, we define it by +%D saying: + +\getvalue{\v!unit} [Celsius] {C} {Celsius} +\getvalue{\v!unit} [Kelvin] {K} {Kelvin} +\getvalue{\v!unit} [Fahrenheit] {F} {Fahrenheit} + +%D Some chemic related units are: + +\getvalue{\v!unit} [Mol] {mol} {mol} +\getvalue{\v!unit} [mMol] {\Milli \Mol} {millimol} +\getvalue{\v!unit} [kMol] {\Kilo \Mol} {kilomol} +\getvalue{\v!unit} [Molair] {M} {molair (\Mol \Per \Liter)} +\getvalue{\v!unit} [Equivalent] {eq} {equivalent} +\getvalue{\v!unit} [mEquivalent] {\Milli \Equivalent} {milli equivalent} + +%D There are quite a lot units related to electricity and +%D magnetism: + +\getvalue{\v!unit} [Farad] {F} {Farad} +\getvalue{\v!unit} [pFarad] {\Pico \Farad} {pico Farad} +\getvalue{\v!unit} [nFarad] {\Nano \Farad} {nano Farad} +\getvalue{\v!unit} [uFarad] {\Micro \Farad} {micro Farad} +\getvalue{\v!unit} [mFarad] {\Milli \Farad} {milli Farad} + +\getvalue{\v!unit} [Ohm] {\Omega} {Ohm} +\getvalue{\v!unit} [kOhm] {\Kilo \Ohm} {kilo Ohm} + +\getvalue{\v!unit} [Siemens] {S} {Siemens} + +\getvalue{\v!unit} [Ampere] {A} {Amp\`ere} +\getvalue{\v!unit} [mAmpere] {\Milli \Ampere} {milli Amp\`ere} + +\getvalue{\v!unit} [Coulomb] {C} {Coulomb} + +\getvalue{\v!unit} [Volt] {V} {Volt} +\getvalue{\v!unit} [mVolt] {\Milli \Volt} {milli Volt} +\getvalue{\v!unit} [kVolt] {\Kilo \Volt} {kilo Volt} +\getvalue{\v!unit} [eVolt] {eV} {electronvolt} +\getvalue{\v!unit} [keVolt] {\Kilo \eVolt} {kilo electronvolt} +\getvalue{\v!unit} [MeVolt] {\Mega \eVolt} {mega electronvolt} + +\getvalue{\v!unit} [Tesla] {T} {Tesla} + +\getvalue{\v!unit} [VoltAC] {V_{\xbox{ac}}} {\labeltext{u:vac}} +\getvalue{\v!unit} [VoltDC] {V_{\xbox{dc}}} {\labeltext{u:vdc}} + +\setuplabeltext + [\s!nl] + [u:vac=wisselspanning, + u:vdc=gelijkspanning] + +\setuplabeltext + [\s!en] + [u:vac=alternating current, + u:vdc=direct current] + +\setuplabeltext + [\s!de] + [u:vac=Wechselspannung, + u:vdc=Gleichspannung] + +\setuplabeltext + [\s!it] + [u:vac=corrente alternata, + u:vdc=corrente continua] + +%D Computer memory is specified in Bytes: + +\getvalue{\v!unit} [Baud] {Baud} {Baud (Bit/s)} +\getvalue{\v!unit} [Bit] {Bit} {Bit} + +\getvalue{\v!unit} [Byte] {Byte} {Byte} +\getvalue{\v!unit} [kByte] {\Kilo \Byte} {kilo Byte} +\getvalue{\v!unit} [MByte] {\Mega \Byte} {mega Byte} +\getvalue{\v!unit} [GByte] {\Giga \Byte} {giga Byte} +\getvalue{\v!unit} [TByte] {\Tera \Byte} {tera Byte} + +%D Some radiation related units: + +\getvalue{\v!unit} [Bequerel] {Bq} {Bequerel} +\getvalue{\v!unit} [MBequerel] {\Mega \Bequerel} {Bequerel} +\getvalue{\v!unit} [Sievert] {Sv} {Sievert} +\getvalue{\v!unit} [mSievert] {\Milli \Sievert} {milli Sievert} + +%D Light: + +\getvalue{\v!unit} [Candela] {cd} {Candela} + +%D and some sound ones: + +\getvalue{\v!unit} [Bell] {B} {Bell} +\getvalue{\v!unit} [dBell] {\Deci \Bell} {decibel} + +%D We also define some non||regular, sometimes even forbidden, +%D units: + +\getvalue{\v!unit} [At] {at} {\labeltext{u:at}} +\getvalue{\v!unit} [Atm] {atm} {\labeltext{u:atm}} +\getvalue{\v!unit} [Bar] {bar} {bar (100 \Kilo \Pascal)} +\getvalue{\v!unit} [EVolt] {eV} {electronvolt} +\getvalue{\v!unit} [Foot] {ft} {\labeltext{u:ft}} +\getvalue{\v!unit} [Inch] {inch} {inch} +\getvalue{\v!unit} [Cal] {cal} {\labeltext{u:cal}} +\getvalue{\v!unit} [Force] {f} {\labeltext{u:f}} +\getvalue{\v!unit} [kCal] {\Kilo \Cal} {\labeltext{u:kcal}} +\getvalue{\v!unit} [Lux] {lux} {lux} + + +\def\xPercent {\dimensionaddfix{\percent }} +\def\xPromille{\dimensionaddfix{\promille}} + +\getvalue{\v!unit} [Percent] {\xPercent } {percent} +\getvalue{\v!unit} [Permille] {\xPromille} {promille} +\getvalue{\v!unit} [Promille] {\xPromille} {promille} + +%D Some more, thanks to Tobias: + +\getvalue{\v!unit} [Gray] {Gr} {Gray} +\getvalue{\v!unit} [Weber] {Wb} {Weber} +\getvalue{\v!unit} [Henry] {H} {Henry} +\getvalue{\v!unit} [Sterant] {sr} {Sterant} +\getvalue{\v!unit} [Angstrom] {\hbox{\Aring}} {\Aring ngstr\"om} +\getvalue{\v!unit} [Gauss] {G} {Gauss} + +\setuplabeltext + [\s!nl] + [u:at=technische atmosfeer, + u:atm=fysische atmosfeer, + u:ft=voet, + u:cal=calorie, + u:f=kracht (force), + u:kcal=kilocalorie] + +\setuplabeltext + [\s!en] + [u:at=technical atmosferic pressure, + u:atm=physical atmosferic pressure, + u:ft=foot, + u:cal=calory, + u:f=force, + u:kcal=kilocalory] + +\setuplabeltext + [\s!de] + [u:at=Technischer atmosph\"arischer Druck, + u:atm=physkalischer atmosph\"arischer Druck + u:ft=Fu\SS, + u:cal=Kalorien, + u:f=Force, + u:kcal=Kilokalorien] + +\setuplabeltext + [\s!it] + [u:at=pressione atmosferica tecnica, + u:atm=pressione atmosfera fisica, + u:ft=piede, + u:cal=caloria, + u:f=forza, + u:kcal=chilocaloria] + +%D Here are some old ones, still there for compatibility +%D reasons. These will probably be obsolete in a few years. + +\def\MeterTwee {\Square \Meter} +\def\mMeterTwee {\Square \Milli \Meter} +\def\cMeterTwee {\Square \Centi \Meter} +\def\dMeterTwee {\Square \Deci \Meter} +\def\kMeterTwee {\Square \Kilo \Meter} + +\def\MeterDrie {\Cubic \Meter} +\def\mMeterDrie {\Cubic \Milli \Meter} +\def\cMeterDrie {\Kubic \Centi \Meter} +\def\dMeterDrie {\Cubic \Deci \Meter} +\def\kMeterDrie {\Cubic \Kilo \Meter} + +\def\LiterTwee {\Square \Liter} +\def\SecTwee {\Square \Sec} +\def\SecMinEen {\Inverse \Sec} + +%D To make ourselves happy, we define some dutch specific +%D units: + +\startinterface dutch + + \getvalue{\v!unit} [PaardenKracht] {pk} {paardenkracht} + \getvalue{\v!unit} [Duits] {D} {duits} + \getvalue{\v!unit} [Kwik] {Hg} {kwikkolom} + \getvalue{\v!unit} [Hectare] {ha} {hectare} + \getvalue{\v!unit} [kGramForce] {\Kilo \Gram \Force} {kilogramforce} + \getvalue{\v!unit} [kWattUur] {\Kilo \Watt \Uur} {kilowattuur} + \getvalue{\v!unit} [MeterKwik] {\Meter \Kwik} {meter kwikkolom} + \getvalue{\v!unit} [Waterkolom] {WK} {waterkolom} + \getvalue{\v!unit} [MeterWater] {\Meter \Waterkolom} {meter waterkolom} + \getvalue{\v!unit} [DrogeStof] {ds} {droge stof} + \getvalue{\v!unit} [Normaal] {N} {normaal} + + \getvalue{\v!unit} [Ton] {t} {ton} + \getvalue{\v!unit} [kTon] {\Kilo \Ton} {kiloton} + + \let \OmwPerSec \RevPerSec + \let \OmwPerMin \RevPerMin + \let \Graden \Deg + \let \PaardeKracht \PaardenKracht + \let \Atoom \Atom + \let \Heure \Hour + \let \Jaar \Year + \let \Maand \Month + \let \Dag \Day + \let \Uur \Hour + +\stopinterface + +%D Finally we define some equivalents. By using \type {\let} +%D we can be sure that they don't end up double in the lists of +%D units. + +\let \Second \Sec +\let \Kubic \Cubic +\let \IKubic \ICubic + +%D Option: + +% \def\Micro{\dimensionprefix{\iftextdimensions\mathematics\mu \else\mu \fi}} +% \def\Times{\dimensionnopfix{\iftextdimensions\mathematics\cdot\else\cdot\fi}} + +\protect \endinput diff --git a/tex/context/base/m-visual.tex b/tex/context/base/m-visual.tex new file mode 100644 index 000000000..d78455190 --- /dev/null +++ b/tex/context/base/m-visual.tex @@ -0,0 +1,316 @@ +%D \module +%D [ file=m-visual, +%D version=2000.01.10, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Visualization and Faking, +%D author={Hans Hagen \& Ton Otten}, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\unprotect + +%D This module collect a few more visual debugger features. I +%D needed them for manuals and styles. The macros are documented +%D in a my way document. + +%D For Mojca: +%D +%D \starttyping +%D \def\simplethesis +%D {\setupsystem[random=1234] +%D \title{\fakewords{3}{4}} +%D \placelist[chapter,section] +%D \dorecurse{6} +%D {\chapter{\fakewords{5}{10}} +%D \dorecurse{5} +%D {\section{\fakewords{2}{5}} +%D \dorecurse{2} +%D {\dorecurse{3}{\fakewords{100}{200}\endgraf} +%D \placefigure{\fakewords{8}{15}}{\fakefigure{5cm}{3cm}{10cm}{5cm}} +%D \dorecurse{2}{\fakewords{100}{200}\endgraf}}}}} +%D +%D \starttext +%D \simplethesis +%D \stoptext +%D \stoptyping + +\definecolor[fakerulecolor] [black] +\definecolor[fakebaselinecolor] [green] +\definecolor[fakeparindentcolor][blue] + +\newif\iffakebaseline \fakebaselinetrue + +\def\fakerule#1% + {\strut + \startcolor[fakerulecolor]% + \iffakebaseline + \vrule\!!height1.25ex\!!depth-.05ex\!!width#1% + \kern-#1% + \vrule\!!height-.05ex\!!depth .25ex\!!width#1% + \else + \vrule\!!height1.25ex\!!depth .25ex\!!width#1% + \fi + \stopcolor + \allowbreak} + +\def\dorandomrecurse#1% + {\getrandomcount\scratchcounter{1}{#1}% + \dorecurse\scratchcounter} + +% can be used in hbox, so %'s are really needed + +\unexpanded\def\fakelines#1#2% min max / 3 10 + {\fakeparindent + \scratchdimen\hsize + \ifindentation + \advance\scratchdimen -\parindent + \fi + \fakerule\scratchdimen\break + \getrandomcount\scratchcounter{\ifcase0#1 3\else#1\fi}{\ifcase0#2 10\else#2\fi}% + \dorecurse\scratchcounter{\fakerule\hsize}% + \getrandomdimen\scratchdimen{.25\hsize}\hsize + \fakerule\scratchdimen + \par} % indeed + +\unexpanded\def\fakewords + {\ifvmode\fakeparindent\fi\onlyfakewords} + +\definepalet + [fakerule] + [fr1c=darkred, + fr2c=darkgreen, + fr3c=darkblue, + fr4c=darkyellow, + fr5c=darkgray] + +\unexpanded\def\onlyfakewords#1#2% min max / 10 40 + {\getrandomcount\scratchcounter{\ifcase0#1 10\else#1\fi}{\ifcase0#2 40\else#2\fi}% + \dofakewords\scratchcounter + } % no \par + +\unexpanded\def\fakenwords#1#2% words seed + {\fakeparindent + \getrandomseed\fakedwordseed + \setrandomseed{\ifcase0#2 #1\else#2\fi}% + \dofakewords{#1}% + \setrandomseed\fakedwordseed + } % no \par + +\def\dofakewords#1% + {\bgroup + \dorecurse{#1} + {\getrandomcount\scratchcounter{1}{5}% + \dorecurse\scratchcounter + {\getrandomdimen\scratchdimen{.5em}{1.25em}% + \fakerule\scratchdimen}% + \space}% + \removeunwantedspaces + \egroup} + +\def\doshowfakewords#1% + {\bgroup + \setuppalet[fakerule]% + \definecolor[fakerulecolor]% + \dorecurse{#1} + {\getrandomcount\scratchcounter{1}{5}% + \dorecurse\scratchcounter + {\getrandomdimen\scratchdimen{.5em}{1.25em}% + \color[fr\recurselevel c]{\fakerule\scratchdimen}}% + \space}% + \removeunwantedspaces + \egroup} + +\def\showfakewords{\let\dofakewords\doshowfakewords} + +\def\fakeword + {\fakewords{1}{1}} % no \plusone + +\def\fakeparindent + {\noindent + \ifindentation + \ifx\dofakedroppedcaps\relax + {\fakeparindentcolor + \vrule + \!!height \strutheight % not longer .5ex + \!!depth \strutdepth % not longer 0pt + \!!width \parindent}% + \else + \dofakedroppedcaps \let\dofakedroppedcaps\relax + \fi +% \else +% \dontleavehmode + \fi} + +\let\dofakedroppedcaps\relax + +\unexpanded\def\fakedroppedcaps#1% + {\ifnum#1>0 + \def\dofakedroppedcaps + {\setbox\scratchbox\hbox + {\setbox\scratchbox\hbox{W}% + \scratchdimen#1\lineheight + \advance\scratchdimen -\lineheight + \advance\scratchdimen \dp\strutbox + \vrule + \!!width#1\wd\scratchbox + \!!height\ht\scratchbox + \!!depth\scratchdimen}% + \ht\scratchbox\ht\strutbox + \dp\scratchbox\dp\strutbox + \hangindent\wd\scratchbox + \advance\hangindent .5em + \wd\scratchbox\hangindent + \hangafter-#1\noindent + \llap{\fakeparindentcolor\box\scratchbox}}% + \fi} + +\newcounter\noffakedfigures + +\unexpanded\def\showfakefigure + {\donetrue\dodoubleempty\dofakefigure} + +\unexpanded\def\fakefigure + {\donefalse\dodoubleempty\dofakefigure} + +\def\dofakefigure[#1][#2]#3#4#5#6% [] [] minwidth maxwidth minheight maxheight + {\doglobal\increment\noffakedfigures + \ifdone + \endgraf + \hbox to \hsize + {\hss\fakeparindentcolor + \strut\bf Figure \noffakedfigures + \doifsomething{#1}{\space(#1)}% + \hss} + \endgraf + \fi + \getvalue{\e!place\v!figure} + [#1][#2]% + {\freezerandomseed + \let\endstrut\relax + \let\begstrut\relax + \doifinsetelse{#1}{\v!left,\v!right} + {\fakewords{2}{4}} + {\fakewords{4}{10}}}% + {\getrandomdimen{\dimen0}{#3}{#4}% + \getrandomdimen{\dimen2}{#5}{#6}% + \doifinset{#1}{\v!left,\v!right} + {\dimen0=.75\dimen0 + \ifdim\dimen0>.6\hsize \dimen0=.5\hsize\fi + \ifdim\dimen0<.3\hsize \dimen0=.3\hsize\fi}% + \framed + [\c!width=\dimen0, + \c!height=\dimen2, + \c!frame=\ifincolor\v!off\else\v!on\fi, + \c!background=\v!color, + \c!backgroundcolor=fakeparindentcolor] + {\bf\white#1}}% + \defrostrandomseed} + +\def\fakeformula + {\dimen0\zeropoint + \getrandomcount\scratchcounter{3}{6}% + \dorecurse\scratchcounter + {\getrandomdimen\scratchdimen{1em}{3em}% + \mathinner{\red\fakerule\scratchdimen}% + \ifnum\recurselevel<\scratchcounter+\fi + \advance\scratchdimen\dimen0}% + =\mathinner{\red\fakerule\scratchdimen}} + +\def\fakespacingformula + {\color[fakebaselinecolor]{\ruledbaseline}\fakeformula} + +%D test \type{\bodyfontgrid}\space test +%D test \type{\emexgrid} \space test + + +\def\smashedgrid + {\dosingleempty\dosmashedgrid} + +\def\dosmashedgrid[#1]% + {\hsmashed + {\setbox\scratchbox=\hbox + {\basegrid + [\c!nx=10,\c!ny=10,\c!dx=1,\c!dy=1, + \c!unit=\bodyfontsize,#1]}% + \hbox to \zeropoint + {\hss\lower.5\ht\scratchbox\box\scratchbox\hss}% + \hbox to \zeropoint + {\hss + \black\vrule\!!width6\linewidth\!!height3\linewidth\!!depth3\linewidth + \hss}}} + +\def\bodyfontgrid + {\hbox + {{\linewidth.1pt\yellow\smashedgrid[\c!nx=30,\c!ny=30,\c!scale=.3333]}% + {\linewidth.2pt\green \smashedgrid[\c!nx=20,\c!ny=20,\c!scale=.5]}% + {\linewidth.3pt\red \smashedgrid[\c!nx=10,\c!ny=10,\c!scale=1]}}} + +\def\emexgrid + {\hbox + {{\linewidth.15pt\green\smashedgrid[\c!nx=20,\c!ny=20,\c!unit=ex]}% + {\linewidth.15pt\red \smashedgrid[\c!nx=10,\c!ny=10,\c!unit=em]}}} + +%D The next few macros are not really public and kind of low +%D level. They are obscure and a bit perverse. + +\definecolor[llblack][s=0.01] + +\def\lowlevelstream#1#2#3% + {\ifinotr \else + \dontleavehmode + \prewordbreak + \bgroup\bgroup % make sure aftergroup stuff is handled + %\let#1#2\optimizetransparencyfalse\black + \infofont\clap{\vl}\ignorespaces#3\unskip\clap{\vl}% + \egroup\egroup + \prewordbreak + \fi + #2{#3}} + +\let\normalPDFcode\PDFcode + +\def\showlowlevelstream + {\def\PDFcode{\lowlevelstream\PDFcode\normalPDFcode}% + \def\special{\lowlevelstream\special\normalspecial}} + +\def\showlowlevelstreamonly + {\def\PDFcode{\lowlevelstream\PDFcode\gobbleoneargument}% + \def\special{\lowlevelstream\special\gobbleoneargument}} + +\startnotmode[mkiv] + + \let\normaldostartgraymode \dostartgraymode + \let\normaldostartgraycolormode\dostartgraycolormode + \let\normaldostartrgbcolormode \dostartrgbcolormode + \let\normaldostartcmykcolormode\dostartcmykcolormode + \let\normaldostartspotcolormode\dostartspotcolormode + + \def\traceddostartgraymode#1% + {#1\normaldostartgraymode{#1}} + + \def\traceddostartgraycolormode#1% + {#1\normaldostartgraycolormode{#1}} + + \def\traceddostartrgbcolormode#1#2#3% + {#1 #2 #3\normaldostartrgbcolormode{#1}{#2}{#3}} + + \def\traceddostartcmykcolormode#1#2#3#4% + {#1 #2 #3 #4\normaldostartcmykcolormode{#1}{#2}{#3}{#4}} + + \def\traceddostartspotcolormode#1#2% + {#1 #2\normaldostartspotcolormode{#1}{#2}} + + \def\showcolormodes + {\let\dostartgraymode \traceddostartgraymode + \let\dostartgraycolormode\traceddostartgraycolormode + \let\dostartrgbcolormode \traceddostartrgbcolormode + \let\dostartcmykcolormode\traceddostartcmykcolormode + \let\dostartspotcolormode\traceddostartspotcolormode} + +\stopnotmode + +\protect \endinput diff --git a/tex/context/base/math-ali.mkiv b/tex/context/base/math-ali.mkiv new file mode 100644 index 000000000..31f71219a --- /dev/null +++ b/tex/context/base/math-ali.mkiv @@ -0,0 +1,1296 @@ +%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. + +\unexpanded\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} + +\unexpanded\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 + +\unexpanded\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} + +\unexpanded\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 + +\unexpanded\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} + +\unexpanded\def\definemathmatrix + {\dodoubleempty\dodefinemathmatrix} + +\def\dodefinemathmatrix[#1]% [#2]% + {\setuvalue{\e!start#1}{\dodoubleempty\dostartmathmatrix[#1]}% + \setuvalue{\e!stop #1}{\dostopmathmatrix}% + \setupmathmatrix[#1]}% [#2] + +\definemathmatrix[matrix] +\definemathmatrix[\v!mathmatrix] + +\unexpanded\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: + +\unexpanded\def\startmatrices + {\begingroup + \setupmathmatrix} + +\unexpanded\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 % does not run well: \getbuffer + +%D \macros +%D {startintertext} +%D +%D Preliminary feature: +%D +%D {\em example code} + +\unexpanded\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 + +% \unexpanded\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} + +% \unexpanded\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 \stopbuffer +%D +%D \typebuffer which gives \getbuffer + +\unexpanded\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} + +\unexpanded\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}}} + +%D The following code comes from \type {math-str.mkiv}. + +%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. + +\unexpanded\def\startinnermath + {\getvalue{\e!start\??fm\formulaparameter\c!align}} + +\unexpanded\def\stopinnermath + {\getvalue{\e!stop \??fm\formulaparameter\c!align}} + +\def\mathinnerstrut + {\doif{\formulaparameter\c!strut}\v!yes\strut} + +\long\unexpanded\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 + +\unexpanded\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} + +\unexpanded\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 + +% \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.mkii b/tex/context/base/math-ams.mkii new file mode 100644 index 000000000..83070d01a --- /dev/null +++ b/tex/context/base/math-ams.mkii @@ -0,0 +1,336 @@ +%D \module +%D [ file=math-ams, +%D version=2001.04.12, +%D title=\CONTEXT\ Math Macros, +%D subtitle=AMS Specials, +%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. + +\unprotect + +% maybe we should just include these into the default tex one + +\definefamilysynonym [default] [blackboard] [mb] + +\startmathcollection [default] + +\definemathsymbol [varGamma] [ord] [letters] ["00] +\definemathsymbol [varDelta] [ord] [letters] ["01] +\definemathsymbol [varTheta] [ord] [letters] ["02] +\definemathsymbol [varLambda] [ord] [letters] ["03] +\definemathsymbol [varXi] [ord] [letters] ["04] +\definemathsymbol [varPi] [ord] [letters] ["05] +\definemathsymbol [varSigma] [ord] [letters] ["06] +\definemathsymbol [varUpsilon] [ord] [letters] ["07] +\definemathsymbol [varPhi] [ord] [letters] ["08] +\definemathsymbol [varPsi] [ord] [letters] ["09] +\definemathsymbol [varOmega] [ord] [letters] ["0A] + +\stopmathcollection + +\startmathcollection[default] + +\definemathsymbol [internalAnd] [rel] [operators] ["26] + +\stopmathcollection + +\startmathcollection [default] + +\definemathsymbol [boxdot] [bin] [ma] ["00] +\definemathsymbol [boxplus] [bin] [ma] ["01] +\definemathsymbol [boxtimes] [bin] [ma] ["02] +\definemathsymbol [square] [ord] [ma] ["03] +\definemathsymbol [Box] [ord] [ma] ["03] % square +\definemathsymbol [blacksquare] [ord] [ma] ["04] +\definemathsymbol [centerdot] [bin] [ma] ["05] +\definemathsymbol [Diamond] [ord] [ma] ["06] +\definemathsymbol [lozenge] [ord] [ma] ["06] % Diamond +\definemathsymbol [blacklozenge] [ord] [ma] ["07] +\definemathsymbol [circlearrowright] [rel] [ma] ["08] +\definemathsymbol [circlearrowleft] [rel] [ma] ["09] +\definemathsymbol [rightleftharpoons] [rel] [ma] ["0A] +\definemathsymbol [leftrightharpoons] [rel] [ma] ["0B] +\definemathsymbol [boxminus] [bin] [ma] ["0C] +\definemathsymbol [Vdash] [rel] [ma] ["0D] +\definemathsymbol [Vvdash] [rel] [ma] ["0E] +\definemathsymbol [vDash] [rel] [ma] ["0F] +\definemathsymbol [twoheadrightarrow] [rel] [ma] ["10] +\definemathsymbol [twoheadleftarrow] [rel] [ma] ["11] +\definemathsymbol [leftleftarrows] [rel] [ma] ["12] +\definemathsymbol [rightrightarrows] [rel] [ma] ["13] +\definemathsymbol [upuparrows] [rel] [ma] ["14] +\definemathsymbol [downdownarrows] [rel] [ma] ["15] +\definemathsymbol [upharpoonright] [rel] [ma] ["16] +\definemathsymbol [restriction] [rel] [ma] ["16] +\definemathsymbol [downharpoonright] [rel] [ma] ["17] +\definemathsymbol [upharpoonleft] [rel] [ma] ["18] +\definemathsymbol [downharpoonleft] [rel] [ma] ["19] +\definemathsymbol [rightarrowtail] [rel] [ma] ["1A] +\definemathsymbol [leftarrowtail] [rel] [ma] ["1B] +\definemathsymbol [leftrightarrows] [rel] [ma] ["1C] +\definemathsymbol [rightleftarrows] [rel] [ma] ["1D] +\definemathsymbol [Lsh] [rel] [ma] ["1E] +\definemathsymbol [Rsh] [rel] [ma] ["1F] +\definemathsymbol [rightsquigarrow] [rel] [ma] ["20] +\definemathsymbol [leadsto] [rel] [ma] ["20] % rightsquigarrow +\definemathsymbol [leftrightsquigarrow] [rel] [ma] ["21] +\definemathsymbol [looparrowleft] [rel] [ma] ["22] +\definemathsymbol [looparrowright] [rel] [ma] ["23] +\definemathsymbol [circeq] [rel] [ma] ["24] +\definemathsymbol [succsim] [rel] [ma] ["25] +\definemathsymbol [gtrsim] [rel] [ma] ["26] +\definemathsymbol [gtrapprox] [rel] [ma] ["27] +\definemathsymbol [multimap] [rel] [ma] ["28] +\definemathsymbol [therefore] [rel] [ma] ["29] +\definemathsymbol [because] [rel] [ma] ["2A] +\definemathsymbol [doteqdot] [rel] [ma] ["2B] +\definemathsymbol [Doteq] [rel] [ma] ["2B] % doteqdot +\definemathsymbol [triangleq] [rel] [ma] ["2C] +\definemathsymbol [precsim] [rel] [ma] ["2D] +\definemathsymbol [lesssim] [rel] [ma] ["2E] +\definemathsymbol [lessapprox] [rel] [ma] ["2F] +\definemathsymbol [eqslantless] [rel] [ma] ["30] +\definemathsymbol [eqslantgtr] [rel] [ma] ["31] +\definemathsymbol [curlyeqprec] [rel] [ma] ["32] +\definemathsymbol [curlyeqsucc] [rel] [ma] ["33] +\definemathsymbol [preccurlyeq] [rel] [ma] ["34] +\definemathsymbol [leqq] [rel] [ma] ["35] +\definemathsymbol [leqslant] [rel] [ma] ["36] +\definemathsymbol [lessgtr] [rel] [ma] ["37] +\definemathsymbol [backprime] [ord] [ma] ["38] +\definemathsymbol [dabar@] [ord] [ma] ["39] % @ +\definemathsymbol [risingdotseq] [rel] [ma] ["3A] +\definemathsymbol [fallingdotseq] [rel] [ma] ["3B] +\definemathsymbol [succcurlyeq] [rel] [ma] ["3C] +\definemathsymbol [geqq] [rel] [ma] ["3D] +\definemathsymbol [geqslant] [rel] [ma] ["3E] +\definemathsymbol [gtrless] [rel] [ma] ["3F] +\definemathsymbol [sqsubset] [rel] [ma] ["40] +\definemathsymbol [sqsupset] [rel] [ma] ["41] +\definemathsymbol [vartriangleright] [rel] [ma] ["42] +\definemathsymbol [rhd] [bin] [ma] ["42] +\definemathsymbol [lhd] [bin] [ma] ["43] +\definemathsymbol [vartriangleleft] [rel] [ma] ["43] +\definemathsymbol [trianglerighteq] [rel] [ma] ["44] +\definemathsymbol [unrhd] [bin] [ma] ["44] % trianglerighteq +\definemathsymbol [trianglelefteq] [rel] [ma] ["45] +\definemathsymbol [unlhd] [bin] [ma] ["45] % trianglelefteq +\definemathsymbol [bigstar] [ord] [ma] ["46] +\definemathsymbol [between] [rel] [ma] ["47] +\definemathsymbol [blacktriangledown] [ord] [ma] ["48] +\definemathsymbol [blacktriangleright] [rel] [ma] ["49] +\definemathsymbol [blacktriangleleft] [rel] [ma] ["4A] +\definemathsymbol [vartriangle] [rel] [ma] ["4D] +\definemathsymbol [triangleup] [ord] [ma] ["4D] % vartriangle +\definemathsymbol [blacktriangle] [ord] [ma] ["4E] +\definemathsymbol [triangledown] [ord] [ma] ["4F] +\definemathsymbol [eqcirc] [rel] [ma] ["50] +\definemathsymbol [lesseqgtr] [rel] [ma] ["51] +\definemathsymbol [gtreqless] [rel] [ma] ["52] +\definemathsymbol [lesseqqgtr] [rel] [ma] ["53] +\definemathsymbol [gtreqqless] [rel] [ma] ["54] +\definemathsymbol [Rrightarrow] [rel] [ma] ["56] +\definemathsymbol [Lleftarrow] [rel] [ma] ["57] +\definemathsymbol [veebar] [bin] [ma] ["59] +\definemathsymbol [barwedge] [bin] [ma] ["5A] +\definemathsymbol [doublebarwedge] [bin] [ma] ["5B] +\definemathsymbol [angle] [ord] [ma] ["5C] +\definemathsymbol [measuredangle] [ord] [ma] ["5D] +\definemathsymbol [sphericalangle] [ord] [ma] ["5E] +\definemathsymbol [varpropto] [rel] [ma] ["5F] +\definemathsymbol [smallsmile] [rel] [ma] ["60] +\definemathsymbol [smallfrown] [rel] [ma] ["61] +\definemathsymbol [Subset] [rel] [ma] ["62] +\definemathsymbol [Supset] [rel] [ma] ["63] +\definemathsymbol [Cup] [bin] [ma] ["64] +\definemathsymbol [doublecup] [bin] [ma] ["64] % Cup +\definemathsymbol [Cap] [bin] [ma] ["65] +\definemathsymbol [doublecap] [bin] [ma] ["65] +\definemathsymbol [curlywedge] [bin] [ma] ["66] +\definemathsymbol [curlyvee] [bin] [ma] ["67] +\definemathsymbol [leftthreetimes] [bin] [ma] ["68] +\definemathsymbol [rightthreetimes] [bin] [ma] ["69] +\definemathsymbol [subseteqq] [rel] [ma] ["6A] +\definemathsymbol [supseteqq] [rel] [ma] ["6B] +\definemathsymbol [bumpeq] [rel] [ma] ["6C] +\definemathsymbol [Bumpeq] [rel] [ma] ["6D] +\definemathsymbol [llless] [rel] [ma] ["6E] +\definemathsymbol [lll] [rel] [ma] ["6E] % llless +\definemathsymbol [gggtr] [rel] [ma] ["6F] +\definemathsymbol [ggg] [rel] [ma] ["6F] % gggtr +\definemathsymbol [ulcorner] [open] [ma] ["70] [ma] ["70] +\definemathsymbol [urcorner] [close] [ma] ["71] [ma] ["71] +\definemathsymbol [circledS] [ord] [ma] ["73] +\definemathsymbol [pitchfork] [rel] [ma] ["74] +\definemathsymbol [dotplus] [bin] [ma] ["75] +\definemathsymbol [backsim] [rel] [ma] ["76] +\definemathsymbol [backsimeq] [rel] [ma] ["77] +\definemathsymbol [llcorner] [open] [ma] ["78] [ma] ["78] +\definemathsymbol [lrcorner] [close] [ma] ["79] [ma] ["79] +\definemathsymbol [complement] [ord] [ma] ["7B] +\definemathsymbol [intercal] [bin] [ma] ["7C] +\definemathsymbol [circledcirc] [bin] [ma] ["7D] +\definemathsymbol [circledast] [bin] [ma] ["7E] +\definemathsymbol [circleddash] [bin] [ma] ["7F] + +\stopmathcollection + +\startmathcollection [default] + +\definemathcommand [integers] {\blackboard{Z}} +\definemathcommand [reals] {\blackboard{R}} +\definemathcommand [rationals] {\blackboard{Q}} +\definemathcommand [naturalnumbers] {\blackboard{N}} +\definemathcommand [complexes] {\blackboard{C}} +\definemathcommand [primes] {\blackboard{P}} + +\stopmathcollection + +\startmathcollection [default] + +\definemathsymbol [lvertneqq] [rel] [mb] ["00] +\definemathsymbol [gvertneqq] [rel] [mb] ["01] +\definemathsymbol [nleq] [rel] [mb] ["02] +\definemathsymbol [ngeq] [rel] [mb] ["03] +\definemathsymbol [nless] [rel] [mb] ["04] +\definemathsymbol [ngtr] [rel] [mb] ["05] +\definemathsymbol [nprec] [rel] [mb] ["06] +\definemathsymbol [nsucc] [rel] [mb] ["07] +\definemathsymbol [lneqq] [rel] [mb] ["08] +\definemathsymbol [gneqq] [rel] [mb] ["09] +\definemathsymbol [nleqslant] [rel] [mb] ["0A] +\definemathsymbol [ngeqslant] [rel] [mb] ["0B] +\definemathsymbol [lneq] [rel] [mb] ["0C] +\definemathsymbol [gneq] [rel] [mb] ["0D] +\definemathsymbol [npreceq] [rel] [mb] ["0E] +\definemathsymbol [nsucceq] [rel] [mb] ["0F] +\definemathsymbol [precnsim] [rel] [mb] ["10] +\definemathsymbol [succnsim] [rel] [mb] ["11] +\definemathsymbol [lnsim] [rel] [mb] ["12] +\definemathsymbol [gnsim] [rel] [mb] ["13] +\definemathsymbol [nleqq] [rel] [mb] ["14] +\definemathsymbol [ngeqq] [rel] [mb] ["15] +\definemathsymbol [precneqq] [rel] [mb] ["16] +\definemathsymbol [succneqq] [rel] [mb] ["17] +\definemathsymbol [precnapprox] [rel] [mb] ["18] +\definemathsymbol [succnapprox] [rel] [mb] ["19] +\definemathsymbol [lnapprox] [rel] [mb] ["1A] +\definemathsymbol [gnapprox] [rel] [mb] ["1B] +\definemathsymbol [nsim] [rel] [mb] ["1C] +\definemathsymbol [ncong] [rel] [mb] ["1D] +\definemathsymbol [diagup] [ord] [mb] ["1E] +\definemathsymbol [diagdown] [ord] [mb] ["1F] +\definemathsymbol [varsubsetneq] [rel] [mb] ["20] +\definemathsymbol [varsupsetneq] [rel] [mb] ["21] +\definemathsymbol [nsubseteqq] [rel] [mb] ["22] +\definemathsymbol [nsupseteqq] [rel] [mb] ["23] +\definemathsymbol [subsetneqq] [rel] [mb] ["24] +\definemathsymbol [supsetneqq] [rel] [mb] ["25] +\definemathsymbol [varsubsetneqq] [rel] [mb] ["26] +\definemathsymbol [varsupsetneqq] [rel] [mb] ["27] +\definemathsymbol [subsetneq] [rel] [mb] ["28] +\definemathsymbol [supsetneq] [rel] [mb] ["29] +\definemathsymbol [nsubseteq] [rel] [mb] ["2A] +\definemathsymbol [nsupseteq] [rel] [mb] ["2B] +\definemathsymbol [nparallel] [rel] [mb] ["2C] +\definemathsymbol [nmid] [rel] [mb] ["2D] +\definemathsymbol [nshortmid] [rel] [mb] ["2E] +\definemathsymbol [nshortparallel] [rel] [mb] ["2F] +\definemathsymbol [nvdash] [rel] [mb] ["30] +\definemathsymbol [nVdash] [rel] [mb] ["31] +\definemathsymbol [nvDash] [rel] [mb] ["32] +\definemathsymbol [nVDash] [rel] [mb] ["33] +\definemathsymbol [ntrianglerighteq] [rel] [mb] ["34] +\definemathsymbol [ntrianglelefteq] [rel] [mb] ["35] +\definemathsymbol [ntriangleleft] [rel] [mb] ["36] +\definemathsymbol [ntriangleright] [rel] [mb] ["37] +\definemathsymbol [nleftarrow] [rel] [mb] ["38] +\definemathsymbol [nrightarrow] [rel] [mb] ["39] +\definemathsymbol [nLeftarrow] [rel] [mb] ["3A] +\definemathsymbol [nRightarrow] [rel] [mb] ["3B] +\definemathsymbol [nLeftrightarrow] [rel] [mb] ["3C] +\definemathsymbol [nleftrightarrow] [rel] [mb] ["3D] +\definemathsymbol [divideontimes] [bin] [mb] ["3E] +\definemathsymbol [varnothing] [ord] [mb] ["3F] +\definemathsymbol [nexists] [ord] [mb] ["40] +\definemathsymbol [Finv] [ord] [mb] ["60] +\definemathsymbol [Game] [ord] [mb] ["61] +\definemathsymbol [mho] [ord] [mb] ["66] +\definemathsymbol [eth] [ord] [mb] ["67] +\definemathsymbol [eqsim] [rel] [mb] ["68] +\definemathsymbol [beth] [ord] [mb] ["69] +\definemathsymbol [gimel] [ord] [mb] ["6A] +\definemathsymbol [daleth] [ord] [mb] ["6B] +\definemathsymbol [lessdot] [bin] [mb] ["6C] +\definemathsymbol [gtrdot] [bin] [mb] ["6D] +\definemathsymbol [ltimes] [bin] [mb] ["6E] +\definemathsymbol [rtimes] [bin] [mb] ["6F] +\definemathsymbol [shortmid] [rel] [mb] ["70] +\definemathsymbol [shortparallel] [rel] [mb] ["71] +\definemathsymbol [smallsetminus] [bin] [mb] ["72] +\definemathsymbol [thicksim] [rel] [mb] ["73] +\definemathsymbol [thickapprox] [rel] [mb] ["74] +\definemathsymbol [approxeq] [rel] [mb] ["75] +\definemathsymbol [succapprox] [rel] [mb] ["76] +\definemathsymbol [precapprox] [rel] [mb] ["77] +\definemathsymbol [curvearrowleft] [rel] [mb] ["78] +\definemathsymbol [curvearrowright] [rel] [mb] ["79] +\definemathsymbol [digamma] [ord] [mb] ["7A] +\definemathsymbol [varkappa] [ord] [mb] ["7B] +\definemathsymbol [Bbbk] [ord] [mb] ["7C] +\definemathsymbol [hslash] [ord] [mb] ["7D] +\definemathsymbol [hbar] [ord] [mb] ["7E] +\definemathsymbol [backepsilon] [rel] [mb] ["7F] + +\stopmathcollection + +\startmathcollection [default] + +\definemathcommand [yen] [nothing] {\mathhexbox{\hexmafam}55} +\definemathcommand [checkmark] [nothing] {\mathhexbox{\hexmafam}58} +\definemathcommand [circledR] [nothing] {\mathhexbox{\hexmafam}72} +\definemathcommand [maltese] [nothing] {\mathhexbox{\hexmafam}7A} + +\stopmathcollection + +\startmathcollection [default] + +\definemathcommand [dashrightarrow] [rel] {\dabar@\dabar@ \mathchar"0C4B} +\definemathcommand [dashleftarrow] [rel] {\mathchar"0C4C\dabar@ \dabar@} +\definemathcommand [dasharrow] [rel] {\dabar@\dabar@ \mathchar"0C4B} +\definemathcommand [Join] [rel] {\mathchar"0D6F\mkern-13.8mu\mathchar"0D6E} +\definemathcommand [implies] [rel] {\;\Longrightarrow\;} +\definemathcommand [impliedby] [rel] {\;\Longleftarrow\;} +\definemathcommand [And] [rel] {\;\internalAnd\;} + +\stopmathcollection + +\def\AMSwidehat#1% + {\setbox\scratchbox\hbox{$\mathsurround\zeropoint#1$}% + \ifdim\wd\scratchbox>2em + \mathaccent"0\purefamilyhex{mb}5B{#1}% + \else + \mathaccent"0\purefamilyhex{ex}62{#1}% + \fi} + +\def\AMSwidetilde#1% + {\setbox\scratchbox\hbox{$\mathsurround\zeropoint#1$}% + \ifdim\wd\scratchbox>2em + \mathaccent"0\purefamilyhex{mb}5D{#1}% + \else + \mathaccent"0\purefamilyhex{ex}65{#1}% + \fi} + +\startmathcollection [default] + +\definemathcommand [widehat] {\AMSwidehat} +\definemathcommand [widetilde] {\AMSwidetilde} + +\stopmathcollection + +\protect \endinput 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..389112b16 --- /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} + +\unexpanded\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]{\setuvalue{#1}{\dohandlemtharrow[#2][##2]}}% + % == \def\dohandlemtharrow[##1][##2]{\dodefinebotharrow{#1}{#2}{##2}}% + \getvalue{#1}% + \popmacro\dohandlemtharrow}} + +\def\dodefinebotharrow#1#2#3% + {\setuvalue{#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. + +\unexpanded\def\specrightarrowfill {\defaultmtharrowfill \relbar \relbar \rightarrow} +\unexpanded\def\specleftarrowfill {\defaultmtharrowfill \leftarrow \relbar \relbar} + +\unexpanded\def\rightarrowfill {\specrightarrowfill \textstyle} +\unexpanded\def\leftarrowfill {\specleftarrowfill \textstyle} + +\unexpanded\def\equalfill {\defaultmtharrowfill \Relbar \Relbar \Relbar} +\unexpanded\def\Rightarrowfill {\defaultmtharrowfill \Relbar \Relbar \Rightarrow} +\unexpanded\def\Leftarrowfill {\defaultmtharrowfill \Leftarrow \Relbar \Relbar} +\unexpanded\def\Leftrightarrowfill {\defaultmtharrowfill \Leftarrow \Relbar \Rightarrow} +\unexpanded\def\leftrightarrowfill {\defaultmtharrowfill \leftarrow \relbar \rightarrow} +\unexpanded\def\mapstofill {\defaultmtharrowfill{\mapstochar\relbar} \relbar \rightarrow} +\unexpanded\def\twoheadrightarrowfill{\defaultmtharrowfill \relbar \relbar \twoheadrightarrow} +\unexpanded\def\twoheadleftarrowfill {\defaultmtharrowfill \twoheadleftarrow \relbar \relbar} +\unexpanded\def\rightharpoondownfill {\defaultmtharrowfill \relbar \relbar \rightharpoondown} +\unexpanded\def\rightharpoonupfill {\defaultmtharrowfill \relbar \relbar \rightharpoonup} +\unexpanded\def\leftharpoondownfill {\defaultmtharrowfill \leftharpoondown \relbar \relbar} +\unexpanded\def\leftharpoonupfill {\defaultmtharrowfill \leftharpoonup \relbar \relbar} +\unexpanded\def\hookleftfill {\defaultmtharrowfill \leftarrow \relbar{\relbar\joinrel\rhook}} +\unexpanded\def\hookrightfill {\defaultmtharrowfill{\lhook\joinrel\relbar}\relbar \rightarrow} +\unexpanded\def\relfill {\defaultmtharrowfill \relbar \relbar \relbar} + +\unexpanded\def\triplerelbar {\mathrel\equiv} +\unexpanded\def\triplerelfill{\defaultmtharrowfill\triplerelbar\triplerelbar\triplerelbar} + +\unexpanded\def\singlebond{{\xrel}} % or \def\singlebond{{\xrel[2]}} +\unexpanded\def\doublebond{{\xequal}} +\unexpanded\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} + +\unexpanded\def\definemathoverarrow + {\dotripleargument\dodefinemathoverarrow} + +\def\dodefinemathoverarrow[#1][#2][#3]% + {\ifthirdargument + \setuvalue{#1}{\dohandlemathoverarrow[#2][#3]}% + \else + \setuvalue{#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 + +\unexpanded\def\definemathunderarrow + {\dotripleargument\dodefinemathunderarrow} + +%D For underarrows the default kern is 0.3ex + +\def\dodefinemathunderarrow[#1][#2][#3]% + {\ifthirdargument + \setuvalue{#1}{\dohandlemathunderarrow[#2][#3]}% + \else + \setuvalue{#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-cow.mkii b/tex/context/base/math-cow.mkii new file mode 100644 index 000000000..f0fc811c8 --- /dev/null +++ b/tex/context/base/math-cow.mkii @@ -0,0 +1,31 @@ +%D \module +%D [ file=math-cow, +%D version=2006.06.23, +%D title=\CONTEXT\ Math Macros, +%D subtitle=Cow Math, +%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. + +\unprotect + +\def\COWsqrt {\mthsqrt{\char"7A}{\char"7B}} +\def\COWfrac {\mthfrac{\char"7C}{\char"7A}{\char"7B}} +\def\COWarrowfill{\mtharrowfill 1001} + +\startmathcollection [cow] + % todo +\stopmathcollection + +\startrawmathcollection[cow] + \definemathcommand [frac] {\COWfrac} + \definemathcommand [sqrt] {\COWsqrt} + %definemathcommand [r@@t] {\COWroot} + %definemathcommand [matrix] {\COWmatrix} +\stoprawmathcollection + +\protect \endinput diff --git a/tex/context/base/math-def.mkiv b/tex/context/base/math-def.mkiv new file mode 100644 index 000000000..50c9902dd --- /dev/null +++ b/tex/context/base/math-def.mkiv @@ -0,0 +1,374 @@ +%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\attribute\mathpunctuationattribute\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] {\mfunctionlabeltext{arccos}} +\definemathcommand [arcsin] [nolop] {\mfunctionlabeltext{arcsin}} +\definemathcommand [arctan] [nolop] {\mfunctionlabeltext{arctan}} +\definemathcommand [arg] [nolop] {\mfunctionlabeltext{arg}} +\definemathcommand [cosh] [nolop] {\mfunctionlabeltext{cosh}} +\definemathcommand [cos] [nolop] {\mfunctionlabeltext{cos}} +\definemathcommand [coth] [nolop] {\mfunctionlabeltext{coth}} +\definemathcommand [cot] [nolop] {\mfunctionlabeltext{cot}} +\definemathcommand [csc] [nolop] {\mfunctionlabeltext{csc}} +\definemathcommand [deg] [nolop] {\mfunctionlabeltext{deg}} +\definemathcommand [det] [limop] {\mfunctionlabeltext{det}} +\definemathcommand [dim] [nolop] {\mfunctionlabeltext{dim}} +\definemathcommand [exp] [nolop] {\mfunctionlabeltext{exp}} +\definemathcommand [gcd] [limop] {\mfunctionlabeltext{gcd}} +\definemathcommand [hom] [nolop] {\mfunctionlabeltext{hom}} +\definemathcommand [inf] [limop] {\mfunctionlabeltext{inf}} +\definemathcommand [injlim] [limop] {\mfunctionlabeltext{injlim}} +\definemathcommand [ker] [nolop] {\mfunctionlabeltext{ker}} +\definemathcommand [lg] [nolop] {\mfunctionlabeltext{lg}} +\definemathcommand [liminf] [limop] {\mfunctionlabeltext{liminf}} +\definemathcommand [limsup] [limop] {\mfunctionlabeltext{limsup}} +\definemathcommand [lim] [limop] {\mfunctionlabeltext{lim}} +\definemathcommand [ln] [nolop] {\mfunctionlabeltext{ln}} +\definemathcommand [log] [nolop] {\mfunctionlabeltext{log}} +\definemathcommand [median] [limop] {\mfunctionlabeltext{median}} +\definemathcommand [max] [limop] {\mfunctionlabeltext{max}} +\definemathcommand [min] [limop] {\mfunctionlabeltext{min}} +\definemathcommand [mod] [limop] {\mfunctionlabeltext{mod}} +%definemathcommand [div] [limop] {\mfunctionlabeltext{div}} % overloads \div symbol +\definemathcommand [projlim] [limop] {\mfunctionlabeltext{projlim}} +\definemathcommand [Pr] [limop] {\mfunctionlabeltext{Pr}} +\definemathcommand [sec] [nolop] {\mfunctionlabeltext{sec}} +\definemathcommand [sinh] [nolop] {\mfunctionlabeltext{sinh}} +\definemathcommand [sin] [nolop] {\mfunctionlabeltext{sin}} +\definemathcommand [sup] [limop] {\mfunctionlabeltext{sup}} +\definemathcommand [tanh] [nolop] {\mfunctionlabeltext{tanh}} +\definemathcommand [tan] [nolop] {\mfunctionlabeltext{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}} + +\let\normalmatharg\arg % todo: maybe automatically + +% using attributes + +\chardef\bigmathdelimitermethod\plusone + +\def\plainbigdelimiters % traditional method + {\chardef\bigmathdelimitermethod\plustwo} + +\def\doplainbigmath#1#2% + {{\hbox{$% + \nulldelimiterspace\zeropoint\relax + \mathsurround\zeropoint + $}}} + +\def\doleftbigmath #1{\ifx#1\relax\else\left#1\expandafter\doleftbigmath \fi} +\def\dorightbigmath#1{\ifx#1\relax\else\right.\expandafter\dorightbigmath\fi} + +\def\choosemathbig#1#2% so we accent \big{||} as well + {{\hbox{$% + \ifcase\bigmathdelimitermethod + \doleftbigmath#2\relax + \dorightbigmath#2\relax + \or + \attribute\mathsizeattribute#1\relax + \doleftbigmath#2\relax + \dorightbigmath#2\relax + \else + \doleftbigmath#2\relax + \vbox\!!to\getvalue{\??mm:b:\number#1}\bodyfontsize{}% + \dorightbigmath#2\relax + \fi + \nulldelimiterspace\zeropoint\relax + \mathsurround\zeropoint + $}}} + +\definemathcommand [big] {\choosemathbig\plusone } \setvalue{\??mm:b:1}{0.85} +\definemathcommand [Big] {\choosemathbig\plustwo } \setvalue{\??mm:b:2}{1.15} +\definemathcommand [bigg] {\choosemathbig\plusthree} \setvalue{\??mm:b:3}{1.45} +\definemathcommand [Bigg] {\choosemathbig\plusfour } \setvalue{\??mm:b:4}{1.75} + +\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{\csname normal\strippedcsname#1\endcsname#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 } + +\let\normalsurd\surd + +\unexpanded\def\surd{\normalsurd{}} + +% 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..62d805126 --- /dev/null +++ b/tex/context/base/math-dim.lua @@ -0,0 +1,313 @@ +if not modules then modules = { } end modules ['math-dim'] = { + version = 1.001, + comment = "companion to math-ini.mkiv", + 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']={ "FractionDelimiterSize", "delim2" }, + ['cramped_display_style']={ "FractionDelimiterDisplayStyleSize", "delim1" }, + ['display_style']={ "FractionDelimiterDisplayStyleSize", "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" }, -- todo + }, + ['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) +-- return t.default or t.text_style or 0 +-- end + +function mathematics.dimensions(dimens) + if dimens.SpaceAfterScript then + dimens.SubscriptShiftDownWithSuperscript = dimens.SubscriptShiftDown * 1.5 + 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 +--~ logs.report("warning", "version 0.47 is needed for proper delimited math") + 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, + FractionDelimiterSize = t . fraction_del_size . text_style, + FractionDelimiterDisplayStyleSize = t . fraction_del_size . display_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, + SubscriptShiftDownWithSuperscript = t . sub_sup_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 + 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-ent.lua b/tex/context/base/math-ent.lua new file mode 100644 index 000000000..e5e5b98f0 --- /dev/null +++ b/tex/context/base/math-ent.lua @@ -0,0 +1,2102 @@ +if not modules then modules = { } end modules ['math-ent'] = { + version = 1.001, + comment = "companion to math-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "derived from the mathml 2.0 specification", +} + +mathematics.entities={ + ["Aacute"]=0x000C1, + ["aacute"]=0x000E1, + ["Abreve"]=0x00102, + ["abreve"]=0x00103, + ["ac"]=0x0223E, + ["acd"]=0x0223F, + ["acE"]=0x0223E, + ["Acirc"]=0x000C2, + ["acirc"]=0x000E2, + ["acute"]=0x000B4, + ["Acy"]=0x00410, + ["acy"]=0x00430, + ["AElig"]=0x000C6, + ["aelig"]=0x000E6, + ["af"]=0x02061, + ["Afr"]=0x1D504, + ["afr"]=0x1D51E, + ["Agrave"]=0x000C0, + ["agrave"]=0x000E0, + ["aleph"]=0x02135, + ["alpha"]=0x003B1, + ["Amacr"]=0x00100, + ["amacr"]=0x00101, + ["amalg"]=0x02A3F, + ["amp"]=0x00026, + ["And"]=0x02A53, + ["and"]=0x02227, + ["andand"]=0x02A55, + ["andd"]=0x02A5C, + ["andslope"]=0x02A58, + ["andv"]=0x02A5A, + ["ang"]=0x02220, + ["ange"]=0x029A4, + ["angle"]=0x02220, + ["angmsd"]=0x02221, + ["angmsdaa"]=0x029A8, + ["angmsdab"]=0x029A9, + ["angmsdac"]=0x029AA, + ["angmsdad"]=0x029AB, + ["angmsdae"]=0x029AC, + ["angmsdaf"]=0x029AD, + ["angmsdag"]=0x029AE, + ["angmsdah"]=0x029AF, + ["angrt"]=0x0221F, + ["angrtvb"]=0x022BE, + ["angrtvbd"]=0x0299D, + ["angsph"]=0x02222, + ["angst"]=0x0212B, + ["angzarr"]=0x0237C, + ["Aogon"]=0x00104, + ["aogon"]=0x00105, + ["Aopf"]=0x1D538, + ["aopf"]=0x1D552, + ["ap"]=0x02248, + ["apacir"]=0x02A6F, + ["apE"]=0x02A70, + ["ape"]=0x0224A, + ["apid"]=0x0224B, + ["apos"]=0x00027, + ["ApplyFunction"]=0x02061, + ["approx"]=0x02248, + ["approxeq"]=0x0224A, + ["Aring"]=0x000C5, + ["aring"]=0x000E5, + ["Ascr"]=0x1D49C, + ["ascr"]=0x1D4B6, + ["Assign"]=0x02254, + ["ast"]=0x0002A, + ["asymp"]=0x02248, + ["asympeq"]=0x0224D, + ["Atilde"]=0x000C3, + ["atilde"]=0x000E3, + ["Auml"]=0x000C4, + ["auml"]=0x000E4, + ["awconint"]=0x02233, + ["awint"]=0x02A11, + ["backcong"]=0x0224C, + ["backepsilon"]=0x003F6, + ["backprime"]=0x02035, + ["backsim"]=0x0223D, + ["backsimeq"]=0x022CD, + ["Backslash"]=0x02216, + ["Barv"]=0x02AE7, + ["barvee"]=0x022BD, + ["Barwed"]=0x02306, + ["barwed"]=0x02305, + ["barwedge"]=0x02305, + ["bbrk"]=0x023B5, + ["bbrktbrk"]=0x023B6, + ["bcong"]=0x0224C, + ["Bcy"]=0x00411, + ["bcy"]=0x00431, + ["becaus"]=0x02235, + ["Because"]=0x02235, + ["because"]=0x02235, + ["bemptyv"]=0x029B0, + ["bepsi"]=0x003F6, + ["bernou"]=0x0212C, + ["Bernoullis"]=0x0212C, + ["beta"]=0x003B2, + ["beth"]=0x02136, + ["between"]=0x0226C, + ["Bfr"]=0x1D505, + ["bfr"]=0x1D51F, + ["bigcap"]=0x022C2, + ["bigcirc"]=0x025EF, + ["bigcup"]=0x022C3, + ["bigodot"]=0x02A00, + ["bigoplus"]=0x02A01, + ["bigotimes"]=0x02A02, + ["bigsqcup"]=0x02A06, + ["bigstar"]=0x02605, + ["bigtriangledown"]=0x025BD, + ["bigtriangleup"]=0x025B3, + ["biguplus"]=0x02A04, + ["bigvee"]=0x022C1, + ["bigwedge"]=0x022C0, + ["bkarow"]=0x0290D, + ["blacklozenge"]=0x029EB, + ["blacksquare"]=0x025AA, + ["blacktriangle"]=0x025B4, + ["blacktriangledown"]=0x025BE, + ["blacktriangleleft"]=0x025C2, + ["blacktriangleright"]=0x025B8, + ["blank"]=0x02423, + ["blk12"]=0x02592, + ["blk14"]=0x02591, + ["blk34"]=0x02593, + ["block"]=0x02588, + ["bne"]=0x0003D, + ["bnequiv"]=0x02261, + ["bNot"]=0x02AED, + ["bnot"]=0x02310, + ["Bopf"]=0x1D539, + ["bopf"]=0x1D553, + ["bot"]=0x022A5, + ["bottom"]=0x022A5, + ["bowtie"]=0x022C8, + ["boxbox"]=0x029C9, + ["boxDL"]=0x02557, + ["boxDl"]=0x02556, + ["boxdL"]=0x02555, + ["boxdl"]=0x02510, + ["boxDR"]=0x02554, + ["boxDr"]=0x02553, + ["boxdR"]=0x02552, + ["boxdr"]=0x0250C, + ["boxH"]=0x02550, + ["boxh"]=0x02500, + ["boxHD"]=0x02566, + ["boxHd"]=0x02564, + ["boxhD"]=0x02565, + ["boxhd"]=0x0252C, + ["boxHU"]=0x02569, + ["boxHu"]=0x02567, + ["boxhU"]=0x02568, + ["boxhu"]=0x02534, + ["boxminus"]=0x0229F, + ["boxplus"]=0x0229E, + ["boxtimes"]=0x022A0, + ["boxUL"]=0x0255D, + ["boxUl"]=0x0255C, + ["boxuL"]=0x0255B, + ["boxul"]=0x02518, + ["boxUR"]=0x0255A, + ["boxUr"]=0x02559, + ["boxuR"]=0x02558, + ["boxur"]=0x02514, + ["boxV"]=0x02551, + ["boxv"]=0x02502, + ["boxVH"]=0x0256C, + ["boxVh"]=0x0256B, + ["boxvH"]=0x0256A, + ["boxvh"]=0x0253C, + ["boxVL"]=0x02563, + ["boxVl"]=0x02562, + ["boxvL"]=0x02561, + ["boxvl"]=0x02524, + ["boxVR"]=0x02560, + ["boxVr"]=0x0255F, + ["boxvR"]=0x0255E, + ["boxvr"]=0x0251C, + ["bprime"]=0x02035, + ["Breve"]=0x002D8, + ["breve"]=0x002D8, + ["brvbar"]=0x000A6, + ["Bscr"]=0x0212C, + ["bscr"]=0x1D4B7, + ["bsemi"]=0x0204F, + ["bsim"]=0x0223D, + ["bsime"]=0x022CD, + ["bsol"]=0x0005C, + ["bsolb"]=0x029C5, + ["bsolhsub"]=0x0005C, + ["bull"]=0x02022, + ["bullet"]=0x02022, + ["bump"]=0x0224E, + ["bumpE"]=0x02AAE, + ["bumpe"]=0x0224F, + ["Bumpeq"]=0x0224E, + ["bumpeq"]=0x0224F, + ["Cacute"]=0x00106, + ["cacute"]=0x00107, + ["Cap"]=0x022D2, + ["cap"]=0x02229, + ["capand"]=0x02A44, + ["capbrcup"]=0x02A49, + ["capcap"]=0x02A4B, + ["capcup"]=0x02A47, + ["capdot"]=0x02A40, + ["CapitalDifferentialD"]=0x02145, + ["caps"]=0x02229, + ["caret"]=0x02041, + ["caron"]=0x002C7, + ["Cayleys"]=0x0212D, + ["ccaps"]=0x02A4D, + ["Ccaron"]=0x0010C, + ["ccaron"]=0x0010D, + ["Ccedil"]=0x000C7, + ["ccedil"]=0x000E7, + ["Ccirc"]=0x00108, + ["ccirc"]=0x00109, + ["Cconint"]=0x02230, + ["ccups"]=0x02A4C, + ["ccupssm"]=0x02A50, + ["Cdot"]=0x0010A, + ["cdot"]=0x0010B, + ["cedil"]=0x000B8, + ["Cedilla"]=0x000B8, + ["cemptyv"]=0x029B2, + ["cent"]=0x000A2, + ["CenterDot"]=0x000B7, + ["centerdot"]=0x000B7, + ["Cfr"]=0x0212D, + ["cfr"]=0x1D520, + ["CHcy"]=0x00427, + ["chcy"]=0x00447, + ["check"]=0x02713, + ["checkmark"]=0x02713, + ["chi"]=0x003C7, + ["cir"]=0x025CB, + ["circ"]=0x002C6, + ["circeq"]=0x02257, + ["circlearrowleft"]=0x021BA, + ["circlearrowright"]=0x021BB, + ["circledast"]=0x0229B, + ["circledcirc"]=0x0229A, + ["circleddash"]=0x0229D, + ["CircleDot"]=0x02299, + ["circledR"]=0x000AE, + ["circledS"]=0x024C8, + ["CircleMinus"]=0x02296, + ["CirclePlus"]=0x02295, + ["CircleTimes"]=0x02297, + ["cirE"]=0x029C3, + ["cire"]=0x02257, + ["cirfnint"]=0x02A10, + ["cirmid"]=0x02AEF, + ["cirscir"]=0x029C2, + ["ClockwiseContourIntegral"]=0x02232, + ["CloseCurlyDoubleQuote"]=0x0201D, + ["CloseCurlyQuote"]=0x02019, + ["clubs"]=0x02663, + ["clubsuit"]=0x02663, + ["Colon"]=0x02237, + ["colon"]=0x0003A, + ["Colone"]=0x02A74, + ["colone"]=0x02254, + ["coloneq"]=0x02254, + ["comma"]=0x0002C, + ["commat"]=0x00040, + ["comp"]=0x02201, + ["compfn"]=0x02218, + ["complement"]=0x02201, + ["complexes"]=0x02102, + ["cong"]=0x02245, + ["congdot"]=0x02A6D, + ["Congruent"]=0x02261, + ["Conint"]=0x0222F, + ["conint"]=0x0222E, + ["ContourIntegral"]=0x0222E, + ["Copf"]=0x02102, + ["copf"]=0x1D554, + ["coprod"]=0x02210, + ["Coproduct"]=0x02210, + ["copy"]=0x000A9, + ["copysr"]=0x02117, + ["CounterClockwiseContourIntegral"]=0x02233, + ["Cross"]=0x02A2F, + ["cross"]=0x02717, + ["Cscr"]=0x1D49E, + ["cscr"]=0x1D4B8, + ["csub"]=0x02ACF, + ["csube"]=0x02AD1, + ["csup"]=0x02AD0, + ["csupe"]=0x02AD2, + ["ctdot"]=0x022EF, + ["cudarrl"]=0x02938, + ["cudarrr"]=0x02935, + ["cuepr"]=0x022DE, + ["cuesc"]=0x022DF, + ["cularr"]=0x021B6, + ["cularrp"]=0x0293D, + ["Cup"]=0x022D3, + ["cup"]=0x0222A, + ["cupbrcap"]=0x02A48, + ["CupCap"]=0x0224D, + ["cupcap"]=0x02A46, + ["cupcup"]=0x02A4A, + ["cupdot"]=0x0228D, + ["cupor"]=0x02A45, + ["cups"]=0x0222A, + ["curarr"]=0x021B7, + ["curarrm"]=0x0293C, + ["curlyeqprec"]=0x022DE, + ["curlyeqsucc"]=0x022DF, + ["curlyvee"]=0x022CE, + ["curlywedge"]=0x022CF, + ["curren"]=0x000A4, + ["curvearrowleft"]=0x021B6, + ["curvearrowright"]=0x021B7, + ["cuvee"]=0x022CE, + ["cuwed"]=0x022CF, + ["cwconint"]=0x02232, + ["cwint"]=0x02231, + ["cylcty"]=0x0232D, + ["Dagger"]=0x02021, + ["Dagger"]=0x02021, + ["dagger"]=0x02020, + ["dagger"]=0x02020, + ["daleth"]=0x02138, + ["Darr"]=0x021A1, + ["dArr"]=0x021D3, + ["darr"]=0x02193, + ["dash"]=0x02010, + ["Dashv"]=0x02AE4, + ["dashv"]=0x022A3, + ["dbkarow"]=0x0290F, + ["dblac"]=0x002DD, + ["Dcaron"]=0x0010E, + ["dcaron"]=0x0010F, + ["Dcy"]=0x00414, + ["dcy"]=0x00434, + ["DD"]=0x02145, + ["dd"]=0x02146, + ["ddagger"]=0x02021, + ["ddarr"]=0x021CA, + ["DDotrahd"]=0x02911, + ["ddotseq"]=0x02A77, + ["deg"]=0x000B0, + ["Del"]=0x02207, + ["Delta"]=0x00394, + ["delta"]=0x003B4, + ["demptyv"]=0x029B1, + ["dfisht"]=0x0297F, + ["Dfr"]=0x1D507, + ["dfr"]=0x1D521, + ["dHar"]=0x02965, + ["dharl"]=0x021C3, + ["dharr"]=0x021C2, + ["DiacriticalAcute"]=0x000B4, + ["DiacriticalDot"]=0x002D9, + ["DiacriticalDoubleAcute"]=0x002DD, + ["DiacriticalGrave"]=0x00060, + ["DiacriticalTilde"]=0x002DC, + ["diam"]=0x022C4, + ["Diamond"]=0x022C4, + ["diamond"]=0x022C4, + ["diamondsuit"]=0x02666, + ["diams"]=0x02666, + ["die"]=0x000A8, + ["DifferentialD"]=0x02146, + ["digamma"]=0x003DD, + ["disin"]=0x022F2, + ["div"]=0x000F7, + ["divide"]=0x000F7, + ["divideontimes"]=0x022C7, + ["divonx"]=0x022C7, + ["DJcy"]=0x00402, + ["djcy"]=0x00452, + ["dlcorn"]=0x0231E, + ["dlcrop"]=0x0230D, + ["dollar"]=0x00024, + ["Dopf"]=0x1D53B, + ["dopf"]=0x1D555, + ["Dot"]=0x000A8, + ["dot"]=0x002D9, + ["DotDot"]=0x020DC, + ["doteq"]=0x02250, + ["doteqdot"]=0x02251, + ["DotEqual"]=0x02250, + ["dotminus"]=0x02238, + ["dotplus"]=0x02214, + ["dotsquare"]=0x022A1, + ["doublebarwedge"]=0x02306, + ["DoubleContourIntegral"]=0x0222F, + ["DoubleDot"]=0x000A8, + ["DoubleDownArrow"]=0x021D3, + ["DoubleLeftArrow"]=0x021D0, + ["DoubleLeftRightArrow"]=0x021D4, + ["DoubleLeftTee"]=0x02AE4, + ["DoubleLongLeftArrow"]=0x027F8, + ["DoubleLongLeftRightArrow"]=0x027FA, + ["DoubleLongRightArrow"]=0x027F9, + ["DoubleRightArrow"]=0x021D2, + ["DoubleRightTee"]=0x022A8, + ["DoubleUpArrow"]=0x021D1, + ["DoubleUpDownArrow"]=0x021D5, + ["DoubleVerticalBar"]=0x02225, + ["DownArrow"]=0x02193, + ["Downarrow"]=0x021D3, + ["downarrow"]=0x02193, + ["DownArrowBar"]=0x02913, + ["DownArrowUpArrow"]=0x021F5, + ["DownBreve"]=0x00311, + ["downdownarrows"]=0x021CA, + ["downharpoonleft"]=0x021C3, + ["downharpoonright"]=0x021C2, + ["DownLeftRightVector"]=0x02950, + ["DownLeftTeeVector"]=0x0295E, + ["DownLeftVector"]=0x021BD, + ["DownLeftVectorBar"]=0x02956, + ["DownRightTeeVector"]=0x0295F, + ["DownRightVector"]=0x021C1, + ["DownRightVectorBar"]=0x02957, + ["DownTee"]=0x022A4, + ["DownTeeArrow"]=0x021A7, + ["drbkarow"]=0x02910, + ["drcorn"]=0x0231F, + ["drcrop"]=0x0230C, + ["Dscr"]=0x1D49F, + ["dscr"]=0x1D4B9, + ["DScy"]=0x00405, + ["dscy"]=0x00455, + ["dsol"]=0x029F6, + ["Dstrok"]=0x00110, + ["dstrok"]=0x00111, + ["dtdot"]=0x022F1, + ["dtri"]=0x025BF, + ["dtrif"]=0x025BE, + ["duarr"]=0x021F5, + ["duhar"]=0x0296F, + ["dwangle"]=0x029A6, + ["DZcy"]=0x0040F, + ["dzcy"]=0x0045F, + ["dzigrarr"]=0x027FF, + ["Eacute"]=0x000C9, + ["eacute"]=0x000E9, + ["easter"]=0x02A6E, + ["Ecaron"]=0x0011A, + ["ecaron"]=0x0011B, + ["ecir"]=0x02256, + ["Ecirc"]=0x000CA, + ["ecirc"]=0x000EA, + ["ecolon"]=0x02255, + ["Ecy"]=0x0042D, + ["ecy"]=0x0044D, + ["eDDot"]=0x02A77, + ["Edot"]=0x00116, + ["eDot"]=0x02251, + ["edot"]=0x00117, + ["ee"]=0x02147, + ["efDot"]=0x02252, + ["Efr"]=0x1D508, + ["efr"]=0x1D522, + ["eg"]=0x02A9A, + ["Egrave"]=0x000C8, + ["egrave"]=0x000E8, + ["egs"]=0x02A96, + ["egsdot"]=0x02A98, + ["el"]=0x02A99, + ["Element"]=0x02208, + ["elinters"]=0x0FFFD, + ["ell"]=0x02113, + ["els"]=0x02A95, + ["elsdot"]=0x02A97, + ["Emacr"]=0x00112, + ["emacr"]=0x00113, + ["empty"]=0x02205, + ["emptyset"]=0x02205, + ["EmptySmallSquare"]=0x025FB, + ["emptyv"]=0x02205, + ["EmptyVerySmallSquare"]=0x025AB, + ["emsp"]=0x02003, + ["emsp13"]=0x02004, + ["emsp14"]=0x02005, + ["ENG"]=0x0014A, + ["eng"]=0x0014B, + ["ensp"]=0x02002, + ["Eogon"]=0x00118, + ["eogon"]=0x00119, + ["Eopf"]=0x1D53C, + ["eopf"]=0x1D556, + ["epar"]=0x022D5, + ["eparsl"]=0x029E3, + ["eplus"]=0x02A71, + ["epsi"]=0x003F5, + ["epsiv"]=0x003B5, + ["eqcirc"]=0x02256, + ["eqcolon"]=0x02255, + ["eqsim"]=0x02242, + ["eqslantgtr"]=0x02A96, + ["eqslantless"]=0x02A95, + ["Equal"]=0x02A75, + ["equals"]=0x0003D, + ["EqualTilde"]=0x02242, + ["equest"]=0x0225F, + ["Equilibrium"]=0x021CC, + ["equiv"]=0x02261, + ["equivDD"]=0x02A78, + ["eqvparsl"]=0x029E5, + ["erarr"]=0x02971, + ["erDot"]=0x02253, + ["Escr"]=0x02130, + ["escr"]=0x0212F, + ["esdot"]=0x02250, + ["Esim"]=0x02A73, + ["esim"]=0x02242, + ["eta"]=0x003B7, + ["ETH"]=0x000D0, + ["eth"]=0x000F0, + ["Euml"]=0x000CB, + ["euml"]=0x000EB, + ["excl"]=0x00021, + ["exist"]=0x02203, + ["Exists"]=0x02203, + ["expectation"]=0x02130, + ["ExponentialE"]=0x02147, + ["exponentiale"]=0x02147, + ["fallingdotseq"]=0x02252, + ["Fcy"]=0x00424, + ["fcy"]=0x00444, + ["female"]=0x02640, + ["ffilig"]=0x0FB03, + ["fflig"]=0x0FB00, + ["ffllig"]=0x0FB04, + ["Ffr"]=0x1D509, + ["ffr"]=0x1D523, + ["filig"]=0x0FB01, + ["FilledSmallSquare"]=0x025FC, + ["FilledVerySmallSquare"]=0x025AA, + ["flat"]=0x0266D, + ["fllig"]=0x0FB02, + ["fltns"]=0x025B1, + ["fnof"]=0x00192, + ["Fopf"]=0x1D53D, + ["fopf"]=0x1D557, + ["ForAll"]=0x02200, + ["forall"]=0x02200, + ["fork"]=0x022D4, + ["forkv"]=0x02AD9, + ["Fouriertrf"]=0x02131, + ["fpartint"]=0x02A0D, + ["frac12"]=0x000BD, + ["frac13"]=0x02153, + ["frac14"]=0x000BC, + ["frac15"]=0x02155, + ["frac16"]=0x02159, + ["frac18"]=0x0215B, + ["frac23"]=0x02154, + ["frac25"]=0x02156, + ["frac34"]=0x000BE, + ["frac35"]=0x02157, + ["frac38"]=0x0215C, + ["frac45"]=0x02158, + ["frac56"]=0x0215A, + ["frac58"]=0x0215D, + ["frac78"]=0x0215E, + ["frown"]=0x02322, + ["Fscr"]=0x02131, + ["fscr"]=0x1D4BB, + ["gacute"]=0x001F5, + ["Gamma"]=0x00393, + ["gamma"]=0x003B3, + ["Gammad"]=0x003DC, + ["gammad"]=0x003DD, + ["gap"]=0x02A86, + ["Gbreve"]=0x0011E, + ["gbreve"]=0x0011F, + ["Gcedil"]=0x00122, + ["Gcirc"]=0x0011C, + ["gcirc"]=0x0011D, + ["Gcy"]=0x00413, + ["gcy"]=0x00433, + ["Gdot"]=0x00120, + ["gdot"]=0x00121, + ["gE"]=0x02267, + ["ge"]=0x02265, + ["gEl"]=0x02A8C, + ["gel"]=0x022DB, + ["geq"]=0x02265, + ["geqq"]=0x02267, + ["geqslant"]=0x02A7E, + ["ges"]=0x02A7E, + ["gescc"]=0x02AA9, + ["gesdot"]=0x02A80, + ["gesdoto"]=0x02A82, + ["gesdotol"]=0x02A84, + ["gesl"]=0x022DB, + ["gesles"]=0x02A94, + ["Gfr"]=0x1D50A, + ["gfr"]=0x1D524, + ["Gg"]=0x022D9, + ["gg"]=0x0226B, + ["ggg"]=0x022D9, + ["gimel"]=0x02137, + ["GJcy"]=0x00403, + ["gjcy"]=0x00453, + ["gl"]=0x02277, + ["gla"]=0x02AA5, + ["glE"]=0x02A92, + ["glj"]=0x02AA4, + ["gnap"]=0x02A8A, + ["gnapprox"]=0x02A8A, + ["gnE"]=0x02269, + ["gne"]=0x02A88, + ["gneq"]=0x02A88, + ["gneqq"]=0x02269, + ["gnsim"]=0x022E7, + ["Gopf"]=0x1D53E, + ["gopf"]=0x1D558, + ["grave"]=0x00060, + ["GreaterEqual"]=0x02265, + ["GreaterEqualLess"]=0x022DB, + ["GreaterFullEqual"]=0x02267, + ["GreaterGreater"]=0x02AA2, + ["GreaterLess"]=0x02277, + ["GreaterSlantEqual"]=0x02A7E, + ["GreaterTilde"]=0x02273, + ["Gscr"]=0x1D4A2, + ["gscr"]=0x0210A, + ["gsim"]=0x02273, + ["gsime"]=0x02A8E, + ["gsiml"]=0x02A90, + ["Gt"]=0x0226B, + ["gt"]=0x0003E, + ["gtcc"]=0x02AA7, + ["gtcir"]=0x02A7A, + ["gtdot"]=0x022D7, + ["gtlPar"]=0x02995, + ["gtquest"]=0x02A7C, + ["gtrapprox"]=0x02A86, + ["gtrarr"]=0x02978, + ["gtrdot"]=0x022D7, + ["gtreqless"]=0x022DB, + ["gtreqqless"]=0x02A8C, + ["gtrless"]=0x02277, + ["gtrsim"]=0x02273, + ["gvertneqq"]=0x02269, + ["gvnE"]=0x02269, + ["Hacek"]=0x002C7, + ["hairsp"]=0x0200A, + ["half"]=0x000BD, + ["hamilt"]=0x0210B, + ["HARDcy"]=0x0042A, + ["hardcy"]=0x0044A, + ["hArr"]=0x021D4, + ["harr"]=0x02194, + ["harrcir"]=0x02948, + ["harrw"]=0x021AD, + ["Hat"]=0x0005E, + ["hbar"]=0x0210F, + ["Hcirc"]=0x00124, + ["hcirc"]=0x00125, + ["hearts"]=0x02665, + ["heartsuit"]=0x02665, + ["hellip"]=0x02026, + ["hercon"]=0x022B9, + ["Hfr"]=0x0210C, + ["hfr"]=0x1D525, + ["HilbertSpace"]=0x0210B, + ["hksearow"]=0x02925, + ["hkswarow"]=0x02926, + ["hoarr"]=0x021FF, + ["homtht"]=0x0223B, + ["hookleftarrow"]=0x021A9, + ["hookrightarrow"]=0x021AA, + ["Hopf"]=0x0210D, + ["hopf"]=0x1D559, + ["horbar"]=0x02015, + ["HorizontalLine"]=0x02500, + ["Hscr"]=0x0210B, + ["hscr"]=0x1D4BD, + ["hslash"]=0x0210F, + ["Hstrok"]=0x00126, + ["hstrok"]=0x00127, + ["HumpDownHump"]=0x0224E, + ["HumpEqual"]=0x0224F, + ["hybull"]=0x02043, + ["hyphen"]=0x02010, + ["Iacute"]=0x000CD, + ["iacute"]=0x000ED, + ["ic"]=0x02063, + ["Icirc"]=0x000CE, + ["icirc"]=0x000EE, + ["Icy"]=0x00418, + ["icy"]=0x00438, + ["Idot"]=0x00130, + ["IEcy"]=0x00415, + ["iecy"]=0x00435, + ["iexcl"]=0x000A1, + ["iff"]=0x021D4, + ["Ifr"]=0x02111, + ["ifr"]=0x1D526, + ["Igrave"]=0x000CC, + ["igrave"]=0x000EC, + ["ii"]=0x02148, + ["iiiint"]=0x02A0C, + ["iiint"]=0x0222D, + ["iinfin"]=0x029DC, + ["iiota"]=0x02129, + ["IJlig"]=0x00132, + ["ijlig"]=0x00133, + ["Im"]=0x02111, + ["Imacr"]=0x0012A, + ["imacr"]=0x0012B, + ["image"]=0x02111, + ["ImaginaryI"]=0x02148, + ["imagline"]=0x02110, + ["imagpart"]=0x02111, + ["imath"]=0x00131, + ["imof"]=0x022B7, + ["imped"]=0x001B5, + ["Implies"]=0x021D2, + ["in"]=0x02208, + ["incare"]=0x02105, + ["infin"]=0x0221E, + ["infintie"]=0x029DD, + ["inodot"]=0x00131, + ["Int"]=0x0222C, + ["int"]=0x0222B, + ["intcal"]=0x022BA, + ["integers"]=0x02124, + ["Integral"]=0x0222B, + ["intercal"]=0x022BA, + ["Intersection"]=0x022C2, + ["intlarhk"]=0x02A17, + ["intprod"]=0x02A3C, + ["InvisibleComma"]=0x02063, + ["InvisibleTimes"]=0x02062, + ["IOcy"]=0x00401, + ["iocy"]=0x00451, + ["Iogon"]=0x0012E, + ["iogon"]=0x0012F, + ["Iopf"]=0x1D540, + ["iopf"]=0x1D55A, + ["iota"]=0x003B9, + ["iprod"]=0x02A3C, + ["iquest"]=0x000BF, + ["Iscr"]=0x02110, + ["iscr"]=0x1D4BE, + ["isin"]=0x02208, + ["isindot"]=0x022F5, + ["isinE"]=0x022F9, + ["isins"]=0x022F4, + ["isinsv"]=0x022F3, + ["isinv"]=0x02208, + ["it"]=0x02062, + ["Itilde"]=0x00128, + ["itilde"]=0x00129, + ["Iukcy"]=0x00406, + ["iukcy"]=0x00456, + ["Iuml"]=0x000CF, + ["iuml"]=0x000EF, + ["Jcirc"]=0x00134, + ["jcirc"]=0x00135, + ["Jcy"]=0x00419, + ["jcy"]=0x00439, + ["Jfr"]=0x1D50D, + ["jfr"]=0x1D527, + ["jmath"]=0x0006A, + ["Jopf"]=0x1D541, + ["jopf"]=0x1D55B, + ["Jscr"]=0x1D4A5, + ["jscr"]=0x1D4BF, + ["Jsercy"]=0x00408, + ["jsercy"]=0x00458, + ["Jukcy"]=0x00404, + ["jukcy"]=0x00454, + ["kappa"]=0x003BA, + ["kappav"]=0x003F0, + ["Kcedil"]=0x00136, + ["kcedil"]=0x00137, + ["Kcy"]=0x0041A, + ["kcy"]=0x0043A, + ["Kfr"]=0x1D50E, + ["kfr"]=0x1D528, + ["kgreen"]=0x00138, + ["KHcy"]=0x00425, + ["khcy"]=0x00445, + ["KJcy"]=0x0040C, + ["kjcy"]=0x0045C, + ["Kopf"]=0x1D542, + ["kopf"]=0x1D55C, + ["Kscr"]=0x1D4A6, + ["kscr"]=0x1D4C0, + ["lAarr"]=0x021DA, + ["Lacute"]=0x00139, + ["lacute"]=0x0013A, + ["laemptyv"]=0x029B4, + ["lagran"]=0x02112, + ["Lambda"]=0x0039B, + ["lambda"]=0x003BB, + ["Lang"]=0x0300A, + ["lang"]=0x02329, + ["langd"]=0x02991, + ["langle"]=0x02329, + ["lap"]=0x02A85, + ["Laplacetrf"]=0x02112, + ["laquo"]=0x000AB, + ["Larr"]=0x0219E, + ["lArr"]=0x021D0, + ["larr"]=0x02190, + ["larrb"]=0x021E4, + ["larrbfs"]=0x0291F, + ["larrfs"]=0x0291D, + ["larrhk"]=0x021A9, + ["larrlp"]=0x021AB, + ["larrpl"]=0x02939, + ["larrsim"]=0x02973, + ["larrtl"]=0x021A2, + ["lat"]=0x02AAB, + ["lAtail"]=0x0291B, + ["latail"]=0x02919, + ["late"]=0x02AAD, + ["lates"]=0x02AAD, + ["lBarr"]=0x0290E, + ["lbarr"]=0x0290C, + ["lbbrk"]=0x03014, + ["lbrace"]=0x0007B, + ["lbrack"]=0x0005B, + ["lbrke"]=0x0298B, + ["lbrksld"]=0x0298F, + ["lbrkslu"]=0x0298D, + ["Lcaron"]=0x0013D, + ["lcaron"]=0x0013E, + ["Lcedil"]=0x0013B, + ["lcedil"]=0x0013C, + ["lceil"]=0x02308, + ["lcub"]=0x0007B, + ["Lcy"]=0x0041B, + ["lcy"]=0x0043B, + ["ldca"]=0x02936, + ["ldquo"]=0x0201C, + ["ldquor"]=0x0201E, + ["ldrdhar"]=0x02967, + ["ldrushar"]=0x0294B, + ["ldsh"]=0x021B2, + ["lE"]=0x02266, + ["le"]=0x02264, + ["LeftAngleBracket"]=0x02329, + ["LeftArrow"]=0x02190, + ["Leftarrow"]=0x021D0, + ["leftarrow"]=0x02190, + ["LeftArrowBar"]=0x021E4, + ["LeftArrowRightArrow"]=0x021C6, + ["leftarrowtail"]=0x021A2, + ["LeftCeiling"]=0x02308, + ["LeftDoubleBracket"]=0x0301A, + ["LeftDownTeeVector"]=0x02961, + ["LeftDownVector"]=0x021C3, + ["LeftDownVectorBar"]=0x02959, + ["LeftFloor"]=0x0230A, + ["leftharpoondown"]=0x021BD, + ["leftharpoonup"]=0x021BC, + ["leftleftarrows"]=0x021C7, + ["LeftRightArrow"]=0x02194, + ["Leftrightarrow"]=0x021D4, + ["leftrightarrow"]=0x02194, + ["leftrightarrows"]=0x021C6, + ["leftrightharpoons"]=0x021CB, + ["leftrightsquigarrow"]=0x021AD, + ["LeftRightVector"]=0x0294E, + ["LeftTee"]=0x022A3, + ["LeftTeeArrow"]=0x021A4, + ["LeftTeeVector"]=0x0295A, + ["leftthreetimes"]=0x022CB, + ["LeftTriangle"]=0x022B2, + ["LeftTriangleBar"]=0x029CF, + ["LeftTriangleEqual"]=0x022B4, + ["LeftUpDownVector"]=0x02951, + ["LeftUpTeeVector"]=0x02960, + ["LeftUpVector"]=0x021BF, + ["LeftUpVectorBar"]=0x02958, + ["LeftVector"]=0x021BC, + ["LeftVectorBar"]=0x02952, + ["lEg"]=0x02A8B, + ["leg"]=0x022DA, + ["leq"]=0x02264, + ["leqq"]=0x02266, + ["leqslant"]=0x02A7D, + ["les"]=0x02A7D, + ["lescc"]=0x02AA8, + ["lesdot"]=0x02A7F, + ["lesdoto"]=0x02A81, + ["lesdotor"]=0x02A83, + ["lesg"]=0x022DA, + ["lesges"]=0x02A93, + ["lessapprox"]=0x02A85, + ["lessdot"]=0x022D6, + ["lesseqgtr"]=0x022DA, + ["lesseqqgtr"]=0x02A8B, + ["LessEqualGreater"]=0x022DA, + ["LessFullEqual"]=0x02266, + ["LessGreater"]=0x02276, + ["lessgtr"]=0x02276, + ["LessLess"]=0x02AA1, + ["lesssim"]=0x02272, + ["LessSlantEqual"]=0x02A7D, + ["LessTilde"]=0x02272, + ["lfisht"]=0x0297C, + ["lfloor"]=0x0230A, + ["Lfr"]=0x1D50F, + ["lfr"]=0x1D529, + ["lg"]=0x02276, + ["lgE"]=0x02A91, + ["lHar"]=0x02962, + ["lhard"]=0x021BD, + ["lharu"]=0x021BC, + ["lharul"]=0x0296A, + ["lhblk"]=0x02584, + ["LJcy"]=0x00409, + ["ljcy"]=0x00459, + ["Ll"]=0x022D8, + ["ll"]=0x0226A, + ["llarr"]=0x021C7, + ["llcorner"]=0x0231E, + ["Lleftarrow"]=0x021DA, + ["llhard"]=0x0296B, + ["lltri"]=0x025FA, + ["Lmidot"]=0x0013F, + ["lmidot"]=0x00140, + ["lmoust"]=0x023B0, + ["lmoustache"]=0x023B0, + ["lnap"]=0x02A89, + ["lnapprox"]=0x02A89, + ["lnE"]=0x02268, + ["lne"]=0x02A87, + ["lneq"]=0x02A87, + ["lneqq"]=0x02268, + ["lnsim"]=0x022E6, + ["loang"]=0x03018, + ["loarr"]=0x021FD, + ["lobrk"]=0x0301A, + ["LongLeftArrow"]=0x027F5, + ["Longleftarrow"]=0x027F8, + ["longleftarrow"]=0x027F5, + ["LongLeftRightArrow"]=0x027F7, + ["Longleftrightarrow"]=0x027FA, + ["longleftrightarrow"]=0x027F7, + ["longmapsto"]=0x027FC, + ["LongRightArrow"]=0x027F6, + ["Longrightarrow"]=0x027F9, + ["longrightarrow"]=0x027F6, + ["looparrowleft"]=0x021AB, + ["looparrowright"]=0x021AC, + ["lopar"]=0x02985, + ["Lopf"]=0x1D543, + ["lopf"]=0x1D55D, + ["loplus"]=0x02A2D, + ["lotimes"]=0x02A34, + ["lowast"]=0x02217, + ["lowbar"]=0x0005F, + ["LowerLeftArrow"]=0x02199, + ["LowerRightArrow"]=0x02198, + ["loz"]=0x025CA, + ["lozenge"]=0x025CA, + ["lozf"]=0x029EB, + ["lpar"]=0x00028, + ["lparlt"]=0x02993, + ["lrarr"]=0x021C6, + ["lrcorner"]=0x0231F, + ["lrhar"]=0x021CB, + ["lrhard"]=0x0296D, + ["lrtri"]=0x022BF, + ["Lscr"]=0x02112, + ["lscr"]=0x1D4C1, + ["Lsh"]=0x021B0, + ["lsh"]=0x021B0, + ["lsim"]=0x02272, + ["lsime"]=0x02A8D, + ["lsimg"]=0x02A8F, + ["lsqb"]=0x0005B, + ["lsquo"]=0x02018, + ["lsquor"]=0x0201A, + ["Lstrok"]=0x00141, + ["lstrok"]=0x00142, + ["Lt"]=0x0226A, + ["lt"]=0x0003C, + ["ltcc"]=0x02AA6, + ["ltcir"]=0x02A79, + ["ltdot"]=0x022D6, + ["lthree"]=0x022CB, + ["ltimes"]=0x022C9, + ["ltlarr"]=0x02976, + ["ltquest"]=0x02A7B, + ["ltri"]=0x025C3, + ["ltrie"]=0x022B4, + ["ltrif"]=0x025C2, + ["ltrPar"]=0x02996, + ["lurdshar"]=0x0294A, + ["luruhar"]=0x02966, + ["lvertneqq"]=0x02268, + ["lvnE"]=0x02268, + ["macr"]=0x000AF, + ["male"]=0x02642, + ["malt"]=0x02720, + ["maltese"]=0x02720, + ["Map"]=0x02905, + ["map"]=0x021A6, + ["mapsto"]=0x021A6, + ["mapstodown"]=0x021A7, + ["mapstoleft"]=0x021A4, + ["mapstoup"]=0x021A5, + ["marker"]=0x025AE, + ["mcomma"]=0x02A29, + ["Mcy"]=0x0041C, + ["mcy"]=0x0043C, + ["mdash"]=0x02014, + ["mDDot"]=0x0223A, + ["measuredangle"]=0x02221, + ["MediumSpace"]=0x0205F, + ["Mellintrf"]=0x02133, + ["Mfr"]=0x1D510, + ["mfr"]=0x1D52A, + ["mho"]=0x02127, + ["micro"]=0x000B5, + ["mid"]=0x02223, + ["midast"]=0x0002A, + ["midcir"]=0x02AF0, + ["middot"]=0x000B7, + ["minus"]=0x02212, + ["minusb"]=0x0229F, + ["minusd"]=0x02238, + ["minusdu"]=0x02A2A, + ["MinusPlus"]=0x02213, + ["mlcp"]=0x02ADB, + ["mldr"]=0x02026, + ["mnplus"]=0x02213, + ["models"]=0x022A7, + ["Mopf"]=0x1D544, + ["mopf"]=0x1D55E, + ["mp"]=0x02213, + ["Mscr"]=0x02133, + ["mscr"]=0x1D4C2, + ["mstpos"]=0x0223E, + ["mu"]=0x003BC, + ["multimap"]=0x022B8, + ["mumap"]=0x022B8, + ["nabla"]=0x02207, + ["Nacute"]=0x00143, + ["nacute"]=0x00144, + ["nang"]=0x02220, + ["nap"]=0x02249, + ["napE"]=0x02A70, + ["napid"]=0x0224B, + ["napos"]=0x00149, + ["napprox"]=0x02249, + ["natur"]=0x0266E, + ["natural"]=0x0266E, + ["naturals"]=0x02115, + ["nbsp"]=0x000A0, + ["nbump"]=0x0224E, + ["nbumpe"]=0x0224F, + ["ncap"]=0x02A43, + ["Ncaron"]=0x00147, + ["ncaron"]=0x00148, + ["Ncedil"]=0x00145, + ["ncedil"]=0x00146, + ["ncong"]=0x02247, + ["ncongdot"]=0x02A6D, + ["ncup"]=0x02A42, + ["Ncy"]=0x0041D, + ["ncy"]=0x0043D, + ["ndash"]=0x02013, + ["ne"]=0x02260, + ["nearhk"]=0x02924, + ["neArr"]=0x021D7, + ["nearr"]=0x02197, + ["nearrow"]=0x02197, + ["nedot"]=0x02250, + ["NegativeMediumSpace"]=0x0200B, + ["NegativeThickSpace"]=0x0200B, + ["NegativeThinSpace"]=0x0200B, + ["NegativeVeryThinSpace"]=0x0200B, + ["nequiv"]=0x02262, + ["nesear"]=0x02928, + ["nesim"]=0x02242, + ["NestedGreaterGreater"]=0x0226B, + ["NestedLessLess"]=0x0226A, + ["NewLine"]=0x0000A, + ["nexist"]=0x02204, + ["nexists"]=0x02204, + ["Nfr"]=0x1D511, + ["nfr"]=0x1D52B, + ["ngE"]=0x02267, + ["nge"]=0x02271, + ["ngeq"]=0x02271, + ["ngeqq"]=0x02267, + ["ngeqslant"]=0x02A7E, + ["nges"]=0x02A7E, + ["nGg"]=0x022D9, + ["ngsim"]=0x02275, + ["nGt"]=0x0226B, + ["ngt"]=0x0226F, + ["ngtr"]=0x0226F, + ["nGtv"]=0x0226B, + ["nhArr"]=0x021CE, + ["nharr"]=0x021AE, + ["nhpar"]=0x02AF2, + ["ni"]=0x0220B, + ["nis"]=0x022FC, + ["nisd"]=0x022FA, + ["niv"]=0x0220B, + ["NJcy"]=0x0040A, + ["njcy"]=0x0045A, + ["nlArr"]=0x021CD, + ["nlarr"]=0x0219A, + ["nldr"]=0x02025, + ["nlE"]=0x02266, + ["nle"]=0x02270, + ["nLeftarrow"]=0x021CD, + ["nleftarrow"]=0x0219A, + ["nLeftrightarrow"]=0x021CE, + ["nleftrightarrow"]=0x021AE, + ["nleq"]=0x02270, + ["nleqq"]=0x02266, + ["nleqslant"]=0x02A7D, + ["nles"]=0x02A7D, + ["nless"]=0x0226E, + ["nLl"]=0x022D8, + ["nlsim"]=0x02274, + ["nLt"]=0x0226A, + ["nlt"]=0x0226E, + ["nltri"]=0x022EA, + ["nltrie"]=0x022EC, + ["nLtv"]=0x0226A, + ["nmid"]=0x02224, + ["NoBreak"]=0x02060, + ["NonBreakingSpace"]=0x000A0, + ["Nopf"]=0x02115, + ["nopf"]=0x1D55F, + ["Not"]=0x02AEC, + ["not"]=0x000AC, + ["NotCongruent"]=0x02262, + ["NotCupCap"]=0x0226D, + ["NotDoubleVerticalBar"]=0x02226, + ["NotElement"]=0x02209, + ["NotEqual"]=0x02260, + ["NotEqualTilde"]=0x02242, + ["NotExists"]=0x02204, + ["NotGreater"]=0x0226F, + ["NotGreaterEqual"]=0x02271, + ["NotGreaterFullEqual"]=0x02266, + ["NotGreaterGreater"]=0x0226B, + ["NotGreaterLess"]=0x02279, + ["NotGreaterSlantEqual"]=0x02A7E, + ["NotGreaterTilde"]=0x02275, + ["NotHumpDownHump"]=0x0224E, + ["NotHumpEqual"]=0x0224F, + ["notin"]=0x02209, + ["notindot"]=0x022F5, + ["notinE"]=0x022F9, + ["notinva"]=0x02209, + ["notinvb"]=0x022F7, + ["notinvc"]=0x022F6, + ["NotLeftTriangle"]=0x022EA, + ["NotLeftTriangleBar"]=0x029CF, + ["NotLeftTriangleEqual"]=0x022EC, + ["NotLess"]=0x0226E, + ["NotLessEqual"]=0x02270, + ["NotLessGreater"]=0x02278, + ["NotLessLess"]=0x0226A, + ["NotLessSlantEqual"]=0x02A7D, + ["NotLessTilde"]=0x02274, + ["NotNestedGreaterGreater"]=0x02AA2, + ["NotNestedLessLess"]=0x02AA1, + ["notni"]=0x0220C, + ["notniva"]=0x0220C, + ["notnivb"]=0x022FE, + ["notnivc"]=0x022FD, + ["NotPrecedes"]=0x02280, + ["NotPrecedesEqual"]=0x02AAF, + ["NotPrecedesSlantEqual"]=0x022E0, + ["NotReverseElement"]=0x0220C, + ["NotRightTriangle"]=0x022EB, + ["NotRightTriangleBar"]=0x029D0, + ["NotRightTriangleEqual"]=0x022ED, + ["NotSquareSubset"]=0x0228F, + ["NotSquareSubsetEqual"]=0x022E2, + ["NotSquareSuperset"]=0x02290, + ["NotSquareSupersetEqual"]=0x022E3, + ["NotSubset"]=0x02282, + ["NotSubsetEqual"]=0x02288, + ["NotSucceeds"]=0x02281, + ["NotSucceedsEqual"]=0x02AB0, + ["NotSucceedsSlantEqual"]=0x022E1, + ["NotSucceedsTilde"]=0x0227F, + ["NotSuperset"]=0x02283, + ["NotSupersetEqual"]=0x02289, + ["NotTilde"]=0x02241, + ["NotTildeEqual"]=0x02244, + ["NotTildeFullEqual"]=0x02247, + ["NotTildeTilde"]=0x02249, + ["NotVerticalBar"]=0x02224, + ["npar"]=0x02226, + ["nparallel"]=0x02226, + ["nparsl"]=0x02AFD, + ["npart"]=0x02202, + ["npolint"]=0x02A14, + ["npr"]=0x02280, + ["nprcue"]=0x022E0, + ["npre"]=0x02AAF, + ["nprec"]=0x02280, + ["npreceq"]=0x02AAF, + ["nrArr"]=0x021CF, + ["nrarr"]=0x0219B, + ["nrarrc"]=0x02933, + ["nrarrw"]=0x0219D, + ["nRightarrow"]=0x021CF, + ["nrightarrow"]=0x0219B, + ["nrtri"]=0x022EB, + ["nrtrie"]=0x022ED, + ["nsc"]=0x02281, + ["nsccue"]=0x022E1, + ["nsce"]=0x02AB0, + ["Nscr"]=0x1D4A9, + ["nscr"]=0x1D4C3, + ["nshortmid"]=0x02224, + ["nshortparallel"]=0x02226, + ["nsim"]=0x02241, + ["nsime"]=0x02244, + ["nsimeq"]=0x02244, + ["nsmid"]=0x02224, + ["nspar"]=0x02226, + ["nsqsube"]=0x022E2, + ["nsqsupe"]=0x022E3, + ["nsub"]=0x02284, + ["nsubE"]=0x02AC5, + ["nsube"]=0x02288, + ["nsubset"]=0x02282, + ["nsubseteq"]=0x02288, + ["nsubseteqq"]=0x02AC5, + ["nsucc"]=0x02281, + ["nsucceq"]=0x02AB0, + ["nsup"]=0x02285, + ["nsupE"]=0x02AC6, + ["nsupe"]=0x02289, + ["nsupset"]=0x02283, + ["nsupseteq"]=0x02289, + ["nsupseteqq"]=0x02AC6, + ["ntgl"]=0x02279, + ["Ntilde"]=0x000D1, + ["ntilde"]=0x000F1, + ["ntlg"]=0x02278, + ["ntriangleleft"]=0x022EA, + ["ntrianglelefteq"]=0x022EC, + ["ntriangleright"]=0x022EB, + ["ntrianglerighteq"]=0x022ED, + ["nu"]=0x003BD, + ["num"]=0x00023, + ["numero"]=0x02116, + ["numsp"]=0x02007, + ["nvap"]=0x0224D, + ["nVDash"]=0x022AF, + ["nVdash"]=0x022AE, + ["nvDash"]=0x022AD, + ["nvdash"]=0x022AC, + ["nvge"]=0x02265, + ["nvgt"]=0x0003E, + ["nvHarr"]=0x02904, + ["nvinfin"]=0x029DE, + ["nvlArr"]=0x02902, + ["nvle"]=0x02264, + ["nvlt"]=0x0003C, + ["nvltrie"]=0x022B4, + ["nvrArr"]=0x02903, + ["nvrtrie"]=0x022B5, + ["nvsim"]=0x0223C, + ["nwarhk"]=0x02923, + ["nwArr"]=0x021D6, + ["nwarr"]=0x02196, + ["nwarrow"]=0x02196, + ["nwnear"]=0x02927, + ["Oacute"]=0x000D3, + ["oacute"]=0x000F3, + ["oast"]=0x0229B, + ["ocir"]=0x0229A, + ["Ocirc"]=0x000D4, + ["ocirc"]=0x000F4, + ["Ocy"]=0x0041E, + ["ocy"]=0x0043E, + ["odash"]=0x0229D, + ["Odblac"]=0x00150, + ["odblac"]=0x00151, + ["odiv"]=0x02A38, + ["odot"]=0x02299, + ["odsold"]=0x029BC, + ["OElig"]=0x00152, + ["oelig"]=0x00153, + ["ofcir"]=0x029BF, + ["Ofr"]=0x1D512, + ["ofr"]=0x1D52C, + ["ogon"]=0x002DB, + ["Ograve"]=0x000D2, + ["ograve"]=0x000F2, + ["ogt"]=0x029C1, + ["ohbar"]=0x029B5, + ["ohm"]=0x02126, + ["oint"]=0x0222E, + ["olarr"]=0x021BA, + ["olcir"]=0x029BE, + ["olcross"]=0x029BB, + ["olt"]=0x029C0, + ["Omacr"]=0x0014C, + ["omacr"]=0x0014D, + ["Omega"]=0x003A9, + ["omega"]=0x003C9, + ["omid"]=0x029B6, + ["ominus"]=0x02296, + ["Oopf"]=0x1D546, + ["oopf"]=0x1D560, + ["opar"]=0x029B7, + ["OpenCurlyDoubleQuote"]=0x0201C, + ["OpenCurlyQuote"]=0x02018, + ["operp"]=0x029B9, + ["oplus"]=0x02295, + ["Or"]=0x02A54, + ["or"]=0x02228, + ["orarr"]=0x021BB, + ["ord"]=0x02A5D, + ["order"]=0x02134, + ["orderof"]=0x02134, + ["ordf"]=0x000AA, + ["ordm"]=0x000BA, + ["origof"]=0x022B6, + ["oror"]=0x02A56, + ["orslope"]=0x02A57, + ["orv"]=0x02A5B, + ["oS"]=0x024C8, + ["Oscr"]=0x1D4AA, + ["oscr"]=0x02134, + ["Oslash"]=0x000D8, + ["oslash"]=0x000F8, + ["osol"]=0x02298, + ["Otilde"]=0x000D5, + ["otilde"]=0x000F5, + ["Otimes"]=0x02A37, + ["otimes"]=0x02297, + ["otimesas"]=0x02A36, + ["Ouml"]=0x000D6, + ["ouml"]=0x000F6, + ["ovbar"]=0x0233D, + ["OverBar"]=0x000AF, + ["OverBrace"]=0x0FE37, + ["OverBracket"]=0x023B4, + ["OverParenthesis"]=0x0FE35, + ["par"]=0x02225, + ["para"]=0x000B6, + ["parallel"]=0x02225, + ["parsim"]=0x02AF3, + ["parsl"]=0x02AFD, + ["part"]=0x02202, + ["PartialD"]=0x02202, + ["Pcy"]=0x0041F, + ["pcy"]=0x0043F, + ["percnt"]=0x00025, + ["period"]=0x0002E, + ["permil"]=0x02030, + ["perp"]=0x022A5, + ["pertenk"]=0x02031, + ["Pfr"]=0x1D513, + ["pfr"]=0x1D52D, + ["Phi"]=0x003A6, + ["phi"]=0x003D5, + ["phiv"]=0x003C6, + ["phmmat"]=0x02133, + ["phone"]=0x0260E, + ["Pi"]=0x003A0, + ["pi"]=0x003C0, + ["pitchfork"]=0x022D4, + ["piv"]=0x003D6, + ["planck"]=0x0210F, + ["planckh"]=0x0210E, + ["plankv"]=0x0210F, + ["plus"]=0x0002B, + ["plusacir"]=0x02A23, + ["plusb"]=0x0229E, + ["pluscir"]=0x02A22, + ["plusdo"]=0x02214, + ["plusdu"]=0x02A25, + ["pluse"]=0x02A72, + ["PlusMinus"]=0x000B1, + ["plusmn"]=0x000B1, + ["plussim"]=0x02A26, + ["plustwo"]=0x02A27, + ["pm"]=0x000B1, + ["Poincareplane"]=0x0210C, + ["pointint"]=0x02A15, + ["Popf"]=0x02119, + ["popf"]=0x1D561, + ["pound"]=0x000A3, + ["Pr"]=0x02ABB, + ["pr"]=0x0227A, + ["prap"]=0x02AB7, + ["prcue"]=0x0227C, + ["prE"]=0x02AB3, + ["pre"]=0x02AAF, + ["prec"]=0x0227A, + ["precapprox"]=0x02AB7, + ["preccurlyeq"]=0x0227C, + ["Precedes"]=0x0227A, + ["PrecedesEqual"]=0x02AAF, + ["PrecedesSlantEqual"]=0x0227C, + ["PrecedesTilde"]=0x0227E, + ["preceq"]=0x02AAF, + ["precnapprox"]=0x02AB9, + ["precneqq"]=0x02AB5, + ["precnsim"]=0x022E8, + ["precsim"]=0x0227E, + ["Prime"]=0x02033, + ["prime"]=0x02032, + ["primes"]=0x02119, + ["prnap"]=0x02AB9, + ["prnE"]=0x02AB5, + ["prnsim"]=0x022E8, + ["prod"]=0x0220F, + ["Product"]=0x0220F, + ["profalar"]=0x0232E, + ["profline"]=0x02312, + ["profsurf"]=0x02313, + ["prop"]=0x0221D, + ["Proportion"]=0x02237, + ["Proportional"]=0x0221D, + ["propto"]=0x0221D, + ["prsim"]=0x0227E, + ["prurel"]=0x022B0, + ["Pscr"]=0x1D4AB, + ["pscr"]=0x1D4C5, + ["Psi"]=0x003A8, + ["psi"]=0x003C8, + ["puncsp"]=0x02008, + ["Qfr"]=0x1D514, + ["qfr"]=0x1D52E, + ["qint"]=0x02A0C, + ["Qopf"]=0x0211A, + ["qopf"]=0x1D562, + ["qprime"]=0x02057, + ["Qscr"]=0x1D4AC, + ["qscr"]=0x1D4C6, + ["quaternions"]=0x0210D, + ["quatint"]=0x02A16, + ["quest"]=0x0003F, + ["questeq"]=0x0225F, + ["quot"]=0x00022, + ["rAarr"]=0x021DB, + ["race"]=0x029DA, + ["Racute"]=0x00154, + ["racute"]=0x00155, + ["radic"]=0x0221A, + ["raemptyv"]=0x029B3, + ["Rang"]=0x0300B, + ["rang"]=0x0232A, + ["rangd"]=0x02992, + ["range"]=0x029A5, + ["rangle"]=0x0232A, + ["raquo"]=0x000BB, + ["Rarr"]=0x021A0, + ["rArr"]=0x021D2, + ["rarr"]=0x02192, + ["rarrap"]=0x02975, + ["rarrb"]=0x021E5, + ["rarrbfs"]=0x02920, + ["rarrc"]=0x02933, + ["rarrfs"]=0x0291E, + ["rarrhk"]=0x021AA, + ["rarrlp"]=0x021AC, + ["rarrpl"]=0x02945, + ["rarrsim"]=0x02974, + ["Rarrtl"]=0x02916, + ["rarrtl"]=0x021A3, + ["rarrw"]=0x0219D, + ["rAtail"]=0x0291C, + ["ratail"]=0x0291A, + ["ratio"]=0x02236, + ["rationals"]=0x0211A, + ["RBarr"]=0x02910, + ["rBarr"]=0x0290F, + ["rbarr"]=0x0290D, + ["rbbrk"]=0x03015, + ["rbrace"]=0x0007D, + ["rbrack"]=0x0005D, + ["rbrke"]=0x0298C, + ["rbrksld"]=0x0298E, + ["rbrkslu"]=0x02990, + ["Rcaron"]=0x00158, + ["rcaron"]=0x00159, + ["Rcedil"]=0x00156, + ["rcedil"]=0x00157, + ["rceil"]=0x02309, + ["rcub"]=0x0007D, + ["Rcy"]=0x00420, + ["rcy"]=0x00440, + ["rdca"]=0x02937, + ["rdldhar"]=0x02969, + ["rdquo"]=0x0201D, + ["rdquor"]=0x0201D, + ["rdsh"]=0x021B3, + ["Re"]=0x0211C, + ["real"]=0x0211C, + ["realine"]=0x0211B, + ["realpart"]=0x0211C, + ["reals"]=0x0211D, + ["rect"]=0x025AD, + ["reg"]=0x000AE, + ["ReverseElement"]=0x0220B, + ["ReverseEquilibrium"]=0x021CB, + ["ReverseUpEquilibrium"]=0x0296F, + ["rfisht"]=0x0297D, + ["rfloor"]=0x0230B, + ["Rfr"]=0x0211C, + ["rfr"]=0x1D52F, + ["rHar"]=0x02964, + ["rhard"]=0x021C1, + ["rharu"]=0x021C0, + ["rharul"]=0x0296C, + ["rho"]=0x003C1, + ["rhov"]=0x003F1, + ["RightAngleBracket"]=0x0232A, + ["RightArrow"]=0x02192, + ["Rightarrow"]=0x021D2, + ["rightarrow"]=0x02192, + ["RightArrowBar"]=0x021E5, + ["RightArrowLeftArrow"]=0x021C4, + ["rightarrowtail"]=0x021A3, + ["RightCeiling"]=0x02309, + ["RightDoubleBracket"]=0x0301B, + ["RightDownTeeVector"]=0x0295D, + ["RightDownVector"]=0x021C2, + ["RightDownVectorBar"]=0x02955, + ["RightFloor"]=0x0230B, + ["rightharpoondown"]=0x021C1, + ["rightharpoonup"]=0x021C0, + ["rightleftarrows"]=0x021C4, + ["rightleftharpoons"]=0x021CC, + ["rightrightarrows"]=0x021C9, + ["rightsquigarrow"]=0x0219D, + ["RightTee"]=0x022A2, + ["RightTeeArrow"]=0x021A6, + ["RightTeeVector"]=0x0295B, + ["rightthreetimes"]=0x022CC, + ["RightTriangle"]=0x022B3, + ["RightTriangleBar"]=0x029D0, + ["RightTriangleEqual"]=0x022B5, + ["RightUpDownVector"]=0x0294F, + ["RightUpTeeVector"]=0x0295C, + ["RightUpVector"]=0x021BE, + ["RightUpVectorBar"]=0x02954, + ["RightVector"]=0x021C0, + ["RightVectorBar"]=0x02953, + ["ring"]=0x002DA, + ["risingdotseq"]=0x02253, + ["rlarr"]=0x021C4, + ["rlhar"]=0x021CC, + ["rmoust"]=0x023B1, + ["rmoustache"]=0x023B1, + ["rnmid"]=0x02AEE, + ["roang"]=0x03019, + ["roarr"]=0x021FE, + ["robrk"]=0x0301B, + ["ropar"]=0x02986, + ["Ropf"]=0x0211D, + ["ropf"]=0x1D563, + ["roplus"]=0x02A2E, + ["rotimes"]=0x02A35, + ["RoundImplies"]=0x02970, + ["rpar"]=0x00029, + ["rpargt"]=0x02994, + ["rppolint"]=0x02A12, + ["rrarr"]=0x021C9, + ["Rrightarrow"]=0x021DB, + ["Rscr"]=0x0211B, + ["rscr"]=0x1D4C7, + ["Rsh"]=0x021B1, + ["rsh"]=0x021B1, + ["rsqb"]=0x0005D, + ["rsquo"]=0x02019, + ["rsquor"]=0x02019, + ["rthree"]=0x022CC, + ["rtimes"]=0x022CA, + ["rtri"]=0x025B9, + ["rtrie"]=0x022B5, + ["rtrif"]=0x025B8, + ["rtriltri"]=0x029CE, + ["RuleDelayed"]=0x029F4, + ["ruluhar"]=0x02968, + ["rx"]=0x0211E, + ["Sacute"]=0x0015A, + ["sacute"]=0x0015B, + ["Sc"]=0x02ABC, + ["sc"]=0x0227B, + ["scap"]=0x02AB8, + ["Scaron"]=0x00160, + ["scaron"]=0x00161, + ["sccue"]=0x0227D, + ["scE"]=0x02AB4, + ["sce"]=0x02AB0, + ["Scedil"]=0x0015E, + ["scedil"]=0x0015F, + ["Scirc"]=0x0015C, + ["scirc"]=0x0015D, + ["scnap"]=0x02ABA, + ["scnE"]=0x02AB6, + ["scnsim"]=0x022E9, + ["scpolint"]=0x02A13, + ["scsim"]=0x0227F, + ["Scy"]=0x00421, + ["scy"]=0x00441, + ["sdot"]=0x022C5, + ["sdotb"]=0x022A1, + ["sdote"]=0x02A66, + ["searhk"]=0x02925, + ["seArr"]=0x021D8, + ["searr"]=0x02198, + ["searrow"]=0x02198, + ["sect"]=0x000A7, + ["semi"]=0x0003B, + ["seswar"]=0x02929, + ["setminus"]=0x02216, + ["setmn"]=0x02216, + ["sext"]=0x02736, + ["Sfr"]=0x1D516, + ["sfr"]=0x1D530, + ["sfrown"]=0x02322, + ["sharp"]=0x0266F, + ["SHCHcy"]=0x00429, + ["shchcy"]=0x00449, + ["SHcy"]=0x00428, + ["shcy"]=0x00448, + ["ShortDownArrow"]=0x02193, + ["ShortLeftArrow"]=0x02190, + ["shortmid"]=0x02223, + ["shortparallel"]=0x02225, + ["ShortRightArrow"]=0x02192, + ["ShortUpArrow"]=0x02191, + ["shy"]=0x000AD, + ["Sigma"]=0x003A3, + ["sigma"]=0x003C3, + ["sigmav"]=0x003C2, + ["sim"]=0x0223C, + ["simdot"]=0x02A6A, + ["sime"]=0x02243, + ["simeq"]=0x02243, + ["simg"]=0x02A9E, + ["simgE"]=0x02AA0, + ["siml"]=0x02A9D, + ["simlE"]=0x02A9F, + ["simne"]=0x02246, + ["simplus"]=0x02A24, + ["simrarr"]=0x02972, + ["slarr"]=0x02190, + ["SmallCircle"]=0x02218, + ["smallsetminus"]=0x02216, + ["smashp"]=0x02A33, + ["smeparsl"]=0x029E4, + ["smid"]=0x02223, + ["smile"]=0x02323, + ["smt"]=0x02AAA, + ["smte"]=0x02AAC, + ["smtes"]=0x02AAC, + ["SOFTcy"]=0x0042C, + ["softcy"]=0x0044C, + ["sol"]=0x0002F, + ["solb"]=0x029C4, + ["solbar"]=0x0233F, + ["Sopf"]=0x1D54A, + ["sopf"]=0x1D564, + ["spades"]=0x02660, + ["spadesuit"]=0x02660, + ["spar"]=0x02225, + ["sqcap"]=0x02293, + ["sqcaps"]=0x02293, + ["sqcup"]=0x02294, + ["sqcups"]=0x02294, + ["Sqrt"]=0x0221A, + ["sqsub"]=0x0228F, + ["sqsube"]=0x02291, + ["sqsubset"]=0x0228F, + ["sqsubseteq"]=0x02291, + ["sqsup"]=0x02290, + ["sqsupe"]=0x02292, + ["sqsupset"]=0x02290, + ["sqsupseteq"]=0x02292, + ["squ"]=0x025A1, + ["Square"]=0x025A1, + ["square"]=0x025A1, + ["SquareIntersection"]=0x02293, + ["SquareSubset"]=0x0228F, + ["SquareSubsetEqual"]=0x02291, + ["SquareSuperset"]=0x02290, + ["SquareSupersetEqual"]=0x02292, + ["SquareUnion"]=0x02294, + ["squarf"]=0x025AA, + ["squf"]=0x025AA, + ["srarr"]=0x02192, + ["Sscr"]=0x1D4AE, + ["sscr"]=0x1D4C8, + ["ssetmn"]=0x02216, + ["ssmile"]=0x02323, + ["sstarf"]=0x022C6, + ["Star"]=0x022C6, + ["star"]=0x02606, + ["starf"]=0x02605, + ["straightepsilon"]=0x003F5, + ["straightphi"]=0x003D5, + ["strns"]=0x000AF, + ["Sub"]=0x022D0, + ["sub"]=0x02282, + ["subdot"]=0x02ABD, + ["subE"]=0x02AC5, + ["sube"]=0x02286, + ["subedot"]=0x02AC3, + ["submult"]=0x02AC1, + ["subnE"]=0x02ACB, + ["subne"]=0x0228A, + ["subplus"]=0x02ABF, + ["subrarr"]=0x02979, + ["Subset"]=0x022D0, + ["subset"]=0x02282, + ["subseteq"]=0x02286, + ["subseteqq"]=0x02AC5, + ["SubsetEqual"]=0x02286, + ["subsetneq"]=0x0228A, + ["subsetneqq"]=0x02ACB, + ["subsim"]=0x02AC7, + ["subsub"]=0x02AD5, + ["subsup"]=0x02AD3, + ["succ"]=0x0227B, + ["succapprox"]=0x02AB8, + ["succcurlyeq"]=0x0227D, + ["Succeeds"]=0x0227B, + ["SucceedsEqual"]=0x02AB0, + ["SucceedsSlantEqual"]=0x0227D, + ["SucceedsTilde"]=0x0227F, + ["succeq"]=0x02AB0, + ["succnapprox"]=0x02ABA, + ["succneqq"]=0x02AB6, + ["succnsim"]=0x022E9, + ["succsim"]=0x0227F, + ["SuchThat"]=0x0220B, + ["Sum"]=0x02211, + ["sum"]=0x02211, + ["sung"]=0x0266A, + ["Sup"]=0x022D1, + ["sup"]=0x02283, + ["sup1"]=0x000B9, + ["sup2"]=0x000B2, + ["sup3"]=0x000B3, + ["supdot"]=0x02ABE, + ["supdsub"]=0x02AD8, + ["supE"]=0x02AC6, + ["supe"]=0x02287, + ["supedot"]=0x02AC4, + ["Superset"]=0x02283, + ["SupersetEqual"]=0x02287, + ["suphsol"]=0x02283, + ["suphsub"]=0x02AD7, + ["suplarr"]=0x0297B, + ["supmult"]=0x02AC2, + ["supnE"]=0x02ACC, + ["supne"]=0x0228B, + ["supplus"]=0x02AC0, + ["Supset"]=0x022D1, + ["supset"]=0x02283, + ["supseteq"]=0x02287, + ["supseteqq"]=0x02AC6, + ["supsetneq"]=0x0228B, + ["supsetneqq"]=0x02ACC, + ["supsim"]=0x02AC8, + ["supsub"]=0x02AD4, + ["supsup"]=0x02AD6, + ["swarhk"]=0x02926, + ["swArr"]=0x021D9, + ["swarr"]=0x02199, + ["swarrow"]=0x02199, + ["swnwar"]=0x0292A, + ["szlig"]=0x000DF, + ["Tab"]=0x00009, + ["target"]=0x02316, + ["tau"]=0x003C4, + ["tbrk"]=0x023B4, + ["Tcaron"]=0x00164, + ["tcaron"]=0x00165, + ["Tcedil"]=0x00162, + ["tcedil"]=0x00163, + ["Tcy"]=0x00422, + ["tcy"]=0x00442, + ["tdot"]=0x020DB, + ["telrec"]=0x02315, + ["Tfr"]=0x1D517, + ["tfr"]=0x1D531, + ["there4"]=0x02234, + ["Therefore"]=0x02234, + ["therefore"]=0x02234, + ["Theta"]=0x00398, + ["theta"]=0x003B8, + ["thetav"]=0x003D1, + ["thickapprox"]=0x02248, + ["thicksim"]=0x0223C, + ["ThickSpace"]=0x02009, + ["thinsp"]=0x02009, + ["ThinSpace"]=0x02009, + ["thkap"]=0x02248, + ["thksim"]=0x0223C, + ["THORN"]=0x000DE, + ["thorn"]=0x000FE, + ["Tilde"]=0x0223C, + ["tilde"]=0x002DC, + ["TildeEqual"]=0x02243, + ["TildeFullEqual"]=0x02245, + ["TildeTilde"]=0x02248, + ["times"]=0x000D7, + ["timesb"]=0x022A0, + ["timesbar"]=0x02A31, + ["timesd"]=0x02A30, + ["tint"]=0x0222D, + ["toea"]=0x02928, + ["top"]=0x022A4, + ["topbot"]=0x02336, + ["topcir"]=0x02AF1, + ["Topf"]=0x1D54B, + ["topf"]=0x1D565, + ["topfork"]=0x02ADA, + ["tosa"]=0x02929, + ["tprime"]=0x02034, + ["trade"]=0x02122, + ["triangle"]=0x025B5, + ["triangledown"]=0x025BF, + ["triangleleft"]=0x025C3, + ["trianglelefteq"]=0x022B4, + ["triangleq"]=0x0225C, + ["triangleright"]=0x025B9, + ["trianglerighteq"]=0x022B5, + ["tridot"]=0x025EC, + ["trie"]=0x0225C, + ["triminus"]=0x02A3A, + ["TripleDot"]=0x020DB, + ["triplus"]=0x02A39, + ["trisb"]=0x029CD, + ["tritime"]=0x02A3B, + ["trpezium"]=0x0FFFD, + ["Tscr"]=0x1D4AF, + ["tscr"]=0x1D4C9, + ["TScy"]=0x00426, + ["tscy"]=0x00446, + ["TSHcy"]=0x0040B, + ["tshcy"]=0x0045B, + ["Tstrok"]=0x00166, + ["tstrok"]=0x00167, + ["twixt"]=0x0226C, + ["twoheadleftarrow"]=0x0219E, + ["twoheadrightarrow"]=0x021A0, + ["Uacute"]=0x000DA, + ["uacute"]=0x000FA, + ["Uarr"]=0x0219F, + ["uArr"]=0x021D1, + ["uarr"]=0x02191, + ["Uarrocir"]=0x02949, + ["Ubrcy"]=0x0040E, + ["ubrcy"]=0x0045E, + ["Ubreve"]=0x0016C, + ["ubreve"]=0x0016D, + ["Ucirc"]=0x000DB, + ["ucirc"]=0x000FB, + ["Ucy"]=0x00423, + ["ucy"]=0x00443, + ["udarr"]=0x021C5, + ["Udblac"]=0x00170, + ["udblac"]=0x00171, + ["udhar"]=0x0296E, + ["ufisht"]=0x0297E, + ["Ufr"]=0x1D518, + ["ufr"]=0x1D532, + ["Ugrave"]=0x000D9, + ["ugrave"]=0x000F9, + ["uHar"]=0x02963, + ["uharl"]=0x021BF, + ["uharr"]=0x021BE, + ["uhblk"]=0x02580, + ["ulcorn"]=0x0231C, + ["ulcorner"]=0x0231C, + ["ulcrop"]=0x0230F, + ["ultri"]=0x025F8, + ["Umacr"]=0x0016A, + ["umacr"]=0x0016B, + ["uml"]=0x000A8, + ["UnderBar"]=0x00332, + ["UnderBrace"]=0x0FE38, + ["UnderBracket"]=0x023B5, + ["UnderParenthesis"]=0x0FE36, + ["Union"]=0x022C3, + ["UnionPlus"]=0x0228E, + ["Uogon"]=0x00172, + ["uogon"]=0x00173, + ["Uopf"]=0x1D54C, + ["uopf"]=0x1D566, + ["UpArrow"]=0x02191, + ["Uparrow"]=0x021D1, + ["uparrow"]=0x02191, + ["UpArrowBar"]=0x02912, + ["UpArrowDownArrow"]=0x021C5, + ["UpDownArrow"]=0x02195, + ["Updownarrow"]=0x021D5, + ["updownarrow"]=0x02195, + ["UpEquilibrium"]=0x0296E, + ["upharpoonleft"]=0x021BF, + ["upharpoonright"]=0x021BE, + ["uplus"]=0x0228E, + ["UpperLeftArrow"]=0x02196, + ["UpperRightArrow"]=0x02197, + ["Upsi"]=0x003D2, + ["upsi"]=0x003C5, + ["Upsilon"]=0x003A5, + ["upsilon"]=0x003C5, + ["UpTee"]=0x022A5, + ["UpTeeArrow"]=0x021A5, + ["upuparrows"]=0x021C8, + ["urcorn"]=0x0231D, + ["urcorner"]=0x0231D, + ["urcrop"]=0x0230E, + ["Uring"]=0x0016E, + ["uring"]=0x0016F, + ["urtri"]=0x025F9, + ["Uscr"]=0x1D4B0, + ["uscr"]=0x1D4CA, + ["utdot"]=0x022F0, + ["Utilde"]=0x00168, + ["utilde"]=0x00169, + ["utri"]=0x025B5, + ["utrif"]=0x025B4, + ["uuarr"]=0x021C8, + ["Uuml"]=0x000DC, + ["uuml"]=0x000FC, + ["uwangle"]=0x029A7, + ["vangrt"]=0x0299C, + ["varepsilon"]=0x003B5, + ["varkappa"]=0x003F0, + ["varnothing"]=0x02205, + ["varphi"]=0x003C6, + ["varpi"]=0x003D6, + ["varpropto"]=0x0221D, + ["vArr"]=0x021D5, + ["varr"]=0x02195, + ["varrho"]=0x003F1, + ["varsigma"]=0x003C2, + ["varsubsetneq"]=0x0228A, + ["varsubsetneqq"]=0x02ACB, + ["varsupsetneq"]=0x0228B, + ["varsupsetneqq"]=0x02ACC, + ["vartheta"]=0x003D1, + ["vartriangleleft"]=0x022B2, + ["vartriangleright"]=0x022B3, + ["Vbar"]=0x02AEB, + ["vBar"]=0x02AE8, + ["vBarv"]=0x02AE9, + ["Vcy"]=0x00412, + ["vcy"]=0x00432, + ["VDash"]=0x022AB, + ["Vdash"]=0x022A9, + ["vDash"]=0x022A8, + ["vdash"]=0x022A2, + ["Vdashl"]=0x02AE6, + ["Vee"]=0x022C1, + ["vee"]=0x02228, + ["veebar"]=0x022BB, + ["veeeq"]=0x0225A, + ["vellip"]=0x022EE, + ["Verbar"]=0x02016, + ["verbar"]=0x0007C, + ["Vert"]=0x02016, + ["vert"]=0x0007C, + ["VerticalBar"]=0x02223, + ["VerticalLine"]=0x0007C, + ["VerticalSeparator"]=0x02758, + ["VerticalTilde"]=0x02240, + ["VeryThinSpace"]=0x0200A, + ["Vfr"]=0x1D519, + ["vfr"]=0x1D533, + ["vltri"]=0x022B2, + ["vnsub"]=0x02282, + ["vnsup"]=0x02283, + ["Vopf"]=0x1D54D, + ["vopf"]=0x1D567, + ["vprop"]=0x0221D, + ["vrtri"]=0x022B3, + ["Vscr"]=0x1D4B1, + ["vscr"]=0x1D4CB, + ["vsubnE"]=0x02ACB, + ["vsubne"]=0x0228A, + ["vsupnE"]=0x02ACC, + ["vsupne"]=0x0228B, + ["Vvdash"]=0x022AA, + ["vzigzag"]=0x0299A, + ["Wcirc"]=0x00174, + ["wcirc"]=0x00175, + ["wedbar"]=0x02A5F, + ["Wedge"]=0x022C0, + ["wedge"]=0x02227, + ["wedgeq"]=0x02259, + ["weierp"]=0x02118, + ["Wfr"]=0x1D51A, + ["wfr"]=0x1D534, + ["Wopf"]=0x1D54E, + ["wopf"]=0x1D568, + ["wp"]=0x02118, + ["wr"]=0x02240, + ["wreath"]=0x02240, + ["Wscr"]=0x1D4B2, + ["wscr"]=0x1D4CC, + ["xcap"]=0x022C2, + ["xcirc"]=0x025EF, + ["xcup"]=0x022C3, + ["xdtri"]=0x025BD, + ["Xfr"]=0x1D51B, + ["xfr"]=0x1D535, + ["xhArr"]=0x027FA, + ["xharr"]=0x027F7, + ["Xi"]=0x0039E, + ["xi"]=0x003BE, + ["xlArr"]=0x027F8, + ["xlarr"]=0x027F5, + ["xmap"]=0x027FC, + ["xnis"]=0x022FB, + ["xodot"]=0x02A00, + ["Xopf"]=0x1D54F, + ["xopf"]=0x1D569, + ["xoplus"]=0x02A01, + ["xotime"]=0x02A02, + ["xrArr"]=0x027F9, + ["xrarr"]=0x027F6, + ["Xscr"]=0x1D4B3, + ["xscr"]=0x1D4CD, + ["xsqcup"]=0x02A06, + ["xuplus"]=0x02A04, + ["xutri"]=0x025B3, + ["xvee"]=0x022C1, + ["xwedge"]=0x022C0, + ["Yacute"]=0x000DD, + ["yacute"]=0x000FD, + ["YAcy"]=0x0042F, + ["yacy"]=0x0044F, + ["Ycirc"]=0x00176, + ["ycirc"]=0x00177, + ["Ycy"]=0x0042B, + ["ycy"]=0x0044B, + ["yen"]=0x000A5, + ["Yfr"]=0x1D51C, + ["yfr"]=0x1D536, + ["YIcy"]=0x00407, + ["yicy"]=0x00457, + ["Yopf"]=0x1D550, + ["yopf"]=0x1D56A, + ["Yscr"]=0x1D4B4, + ["yscr"]=0x1D4CE, + ["YUcy"]=0x0042E, + ["yucy"]=0x0044E, + ["Yuml"]=0x00178, + ["yuml"]=0x000FF, + ["Zacute"]=0x00179, + ["zacute"]=0x0017A, + ["Zcaron"]=0x0017D, + ["zcaron"]=0x0017E, + ["Zcy"]=0x00417, + ["zcy"]=0x00437, + ["Zdot"]=0x0017B, + ["zdot"]=0x0017C, + ["zeetrf"]=0x02128, + ["ZeroWidthSpace"]=0x0200B, + ["zeta"]=0x003B6, + ["Zfr"]=0x02128, + ["zfr"]=0x1D537, + ["ZHcy"]=0x00416, + ["zhcy"]=0x00436, + ["zigrarr"]=0x021DD, + ["Zopf"]=0x02124, + ["zopf"]=0x1D56B, + ["Zscr"]=0x1D4B5, + ["zscr"]=0x1D4CF, + + ["plusminus"]=0x000B1, + ["minusplus"]=0x02213, + ["cdots"]=0x2026, + +} diff --git a/tex/context/base/math-eul.mkii b/tex/context/base/math-eul.mkii new file mode 100644 index 000000000..7552957a8 --- /dev/null +++ b/tex/context/base/math-eul.mkii @@ -0,0 +1,277 @@ +%D \module +%D [ file=math-eul, +%D version=2003.02.03, +%D title=\CONTEXT\ Math Macros, +%D subtitle=Virtual Euler Specials, +%D author={Hans Hagen \& Taco Hoekwater \& Adam Lindsay}, +%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. Further modified by Adam Lindsay. + +\unprotect + +%D We follow the following mappings from type-eul: +%D +%D mr [MathRoman] [Euler-Roman] [zeurm10] + +%D mi [MathItalic] [Euler-Italic] [eufm10] + +%D ex [MathExtension] [Euler-Extension] [zeuex10] +%D sy [MathSymbol] [Euler-Symbol] [zeusm10] + +%D mb [MathBeta] [Charter-Roman] [bchr8r] XXX +%D mc [MathGamma] [Euler-Fraktur] [eufm10] XXX +%D +%D The inclusion of Bitstream Charter was originally for the text accents. +%D Obviously, it's not a proper ``MathBeta'' font. + +%D The varrho and varsigma characters don't exist in eulervm, +%D so we point at the normal types. + +\definefamilysynonym [eul] [calligraphic] [sy] +\definefamilysynonym [eul] [oldstyle] [mi] +\definefamilysynonym [eul] [gothic] [mi] +\definefamilysynonym [eul] [fraktur] [mi] + +\definefamilysynonym [eul] [lcgreek] [mr] +\definefamilysynonym [eul] [ucgreek] [mr] +\definefamilysynonym [eul] [vargreek] [mr] + +%% Well, you don't know until you try! +%\definefamilysynonym [eul] [accents] [Serif] + +\startmathcollection [eul] + +\definemathsymbol [varrho] [nothing] [vargreek] ["1A] +\definemathsymbol [varsigma] [nothing] [vargreek] ["1B] + +%D Changes necessitated by collapsing mr \& mi into one: +\definemathsymbol [imath] [nothing] [mr] ["7B] +\definemathsymbol [jmath] [nothing] [mr] ["7C] +\definemathsymbol [ell] [nothing] [mr] ["60] +\definemathsymbol [wp] [nothing] [mr] ["7D] +\definemathsymbol [partial] [nothing] [mr] ["40] + +\definemathsymbol [flat] [ord] [mr] ["5B] +\definemathsymbol [natural] [ord] [mr] ["5C] +\definemathsymbol [sharp] [ord] [mr] ["5D] + +\definemathsymbol [triangleleft] [bin] [mr] ["2F] +\definemathsymbol [triangleright][bin] [mr] ["2E] + +\definemathsymbol [star] [bin] [mr] ["3F] + +\definemathsymbol [smile] [rel] [mr] ["5E] +\definemathsymbol [frown] [rel] [mr] ["5F] +\definemathsymbol [leftharpoonup] [rel] [mr] ["28] +\definemathsymbol [leftharpoondown] [rel] [mr] ["29] +\definemathsymbol [rightharpoonup] [rel] [mr] ["2A] +\definemathsymbol [rightharpoondown] [rel] [mr] ["2B] +\definemathsymbol [lhook] [rel] [mr] ["2C] +\definemathsymbol [rhook] [rel] [mr] ["2D] + +\definemathsymbol [mathperiod] [ord] [mr] ["3A] +\definemathsymbol [textperiod] [punct] [mr] ["3A] + +\definemathsymbol [mathcomma] [ord] [mr] ["3B] +\definemathsymbol [textcomma] [punct] [mr] ["3B] + +\definemathsymbol [ldotp] [punct] [mr] ["3A] + +% extras from AMS: +\definemathsymbol [hslash] [ord] [mr] ["80] %beauty over truth + +\stopmathcollection + +\startmathcollection [eul] +% Ugh. no way around this to keep it compact in the font defs. + +\definemathcharacter [a] [alpha] [mr] ["61] +\definemathcharacter [b] [alpha] [mr] ["62] +\definemathcharacter [c] [alpha] [mr] ["63] +\definemathcharacter [d] [alpha] [mr] ["64] +\definemathcharacter [e] [alpha] [mr] ["65] +\definemathcharacter [f] [alpha] [mr] ["66] +\definemathcharacter [g] [alpha] [mr] ["67] +\definemathcharacter [h] [alpha] [mr] ["68] +\definemathcharacter [i] [alpha] [mr] ["69] +\definemathcharacter [j] [alpha] [mr] ["6A] +\definemathcharacter [k] [alpha] [mr] ["6B] +\definemathcharacter [l] [alpha] [mr] ["6C] +\definemathcharacter [m] [alpha] [mr] ["6D] +\definemathcharacter [n] [alpha] [mr] ["6E] +\definemathcharacter [o] [alpha] [mr] ["6F] +\definemathcharacter [p] [alpha] [mr] ["70] +\definemathcharacter [q] [alpha] [mr] ["71] +\definemathcharacter [r] [alpha] [mr] ["72] +\definemathcharacter [s] [alpha] [mr] ["73] +\definemathcharacter [t] [alpha] [mr] ["74] +\definemathcharacter [u] [alpha] [mr] ["75] +\definemathcharacter [v] [alpha] [mr] ["76] +\definemathcharacter [w] [alpha] [mr] ["77] +\definemathcharacter [x] [alpha] [mr] ["78] +\definemathcharacter [y] [alpha] [mr] ["79] +\definemathcharacter [z] [alpha] [mr] ["7A] + +\definemathcharacter [A] [alpha] [mr] ["41] +\definemathcharacter [B] [alpha] [mr] ["42] +\definemathcharacter [C] [alpha] [mr] ["43] +\definemathcharacter [D] [alpha] [mr] ["44] +\definemathcharacter [E] [alpha] [mr] ["45] +\definemathcharacter [F] [alpha] [mr] ["46] +\definemathcharacter [G] [alpha] [mr] ["47] +\definemathcharacter [H] [alpha] [mr] ["48] +\definemathcharacter [I] [alpha] [mr] ["49] +\definemathcharacter [J] [alpha] [mr] ["4A] +\definemathcharacter [K] [alpha] [mr] ["4B] +\definemathcharacter [L] [alpha] [mr] ["4C] +\definemathcharacter [M] [alpha] [mr] ["4D] +\definemathcharacter [N] [alpha] [mr] ["4E] +\definemathcharacter [O] [alpha] [mr] ["4F] +\definemathcharacter [P] [alpha] [mr] ["50] +\definemathcharacter [Q] [alpha] [mr] ["51] +\definemathcharacter [R] [alpha] [mr] ["52] +\definemathcharacter [S] [alpha] [mr] ["53] +\definemathcharacter [T] [alpha] [mr] ["54] +\definemathcharacter [U] [alpha] [mr] ["55] +\definemathcharacter [V] [alpha] [mr] ["56] +\definemathcharacter [W] [alpha] [mr] ["57] +\definemathcharacter [X] [alpha] [mr] ["58] +\definemathcharacter [Y] [alpha] [mr] ["59] +\definemathcharacter [Z] [alpha] [mr] ["5A] + +\stopmathcollection + +\startmathcollection [eul] + +\definemathcharacter [!] [close] [sy] ["A1] +\definemathcharacter [(] [open] [sy] ["A8] +\definemathcharacter [)] [close] [sy] ["A9] +\definemathcharacter [+] [bin] [sy] ["AB] +\definemathcharacter [:] [rel] [sy] ["BA] +\definemathcharacter [;] [punct] [sy] ["BB] +\definemathcharacter [=] [rel] [sy] ["BD] +\definemathcharacter [?] [close] [sy] ["BF] +\definemathcharacter [91] [open] [sy] ["DB] % [ +\definemathcharacter [93] [close] [sy] ["DD] % ] + +\definemathcharacter [,] [punct] [mr] ["3B] +\definemathcharacter [.] [ord] [mr] ["3A] +\definemathcharacter [/] [ord] [mr] ["3D] +\definemathcharacter [<] [rel] [mr] ["3C] +\definemathcharacter [>] [rel] [mr] ["3E] + +\stopmathcollection + +\startmathcollection [eul] + +\definemathcharacter [(] [nothing] [sy] ["A8] [ex] ["00] +\definemathcharacter [)] [nothing] [sy] ["A9] [ex] ["01] +\definemathcharacter [91] [nothing] [sy] ["DB] [ex] ["02] % [ +\definemathcharacter [93] [nothing] [sy] ["DD] [ex] ["03] % ] +\definemathcharacter [/] [nothing] [mr] ["3D] [ex] ["0E] + +\stopmathcollection + +\startmathcollection [eul] + +\definemathsymbol [hbar] [nothing] [mr] ["80] + +\stopmathcollection + +\startmathcollection [eul] + +\definemathsymbol [ddagger] [bin] [sy] ["7A] +\definemathsymbol [dagger] [bin] [sy] ["79] + +\stopmathcollection + +\startmathcollection [eul] + +\definemathsymbol [colon] [punct] [sy] ["BA] + +\stopmathcollection + +%D This used to be very hackish; it brought in text +%D accents from the well-matched Bitstream Charter. + +%D But now, these characters don't exist. I would prefer to pull +%D them from the text font, but I don't know how. +%D Instead, I'm just pointing to null characters! + +\startmathcollection [eul] + +\definemathsymbol [acute] [accent] [mr] ["90] +\definemathsymbol [grave] [accent] [mr] ["91] +\definemathsymbol [ddot] [accent] [mr] ["92] +\definemathsymbol [tilde] [accent] [mr] ["93] +\definemathsymbol [bar] [accent] [mr] ["94] +\definemathsymbol [breve] [accent] [mr] ["95] +\definemathsymbol [check] [accent] [mr] ["96] +\definemathsymbol [hat] [accent] [mr] ["97] +\definemathsymbol [dot] [accent] [mr] ["98] +%\definemathsymbol [acute] [accent] [accents] ["B4] +%\definemathsymbol [grave] [accent] [accents] ["1E] +%\definemathsymbol [ddot] [accent] [accents] ["A8] +%\definemathsymbol [tilde] [accent] [accents] ["98] +%\definemathsymbol [bar] [accent] [accents] ["AF] +%\definemathsymbol [breve] [accent] [accents] ["0B] +%\definemathsymbol [check] [accent] [accents] ["10] +%\definemathsymbol [hat] [accent] [accents] ["5E] +%\definemathsymbol [dot] [accent] [accents] ["01] + +\definemathsymbol [vec] [accent] [mr] ["7E] % [ord] +\definemathsymbol [hat] [accent] [sy] ["DE] + +\stopmathcollection + +\startmathcollection [eul] + +\definemathsymbol [lgroup] [open] [sy] ["A8] [ex] ["3A] % ? +\definemathsymbol [rgroup] [close] [sy] ["A9] [ex] ["3B] % ? + +\stopmathcollection + +\startmathcollection [eul] + +\definemathsymbol [dag] [box] [sy] ["79] +\definemathsymbol [ddag] [box] [sy] ["7A] +\definemathsymbol [S] [box] [sy] ["78] +\definemathsymbol [P] [box] [sy] ["7B] + +\stopmathcollection + +%D Aditya's additionl definitions: + +\startmathcollection[eul:texnansi] + \definemathsymbol [acute] [accent] [tf] ["13] + \definemathsymbol [grave] [accent] [tf] ["12] + \definemathsymbol [ddot] [accent] [tf] ["A8] + \definemathsymbol [tilde] [accent] [tf] ["98] + \definemathsymbol [bar] [accent] [tf] ["16] + \definemathsymbol [breve] [accent] [tf] ["15] + \definemathsymbol [check] [accent] [tf] ["14] + \definemathsymbol [hat] [accent] [tf] ["88] + \definemathsymbol [dot] [accent] [tf] ["5] + % Why is mathring not defined?? + \definemathsymbol [mathring] [accent] [tf] ["17] +\stopmathcollection + +\startmathcollection[eul:ec] + \definemathsymbol [acute] [accent] [tf] ["1] + \definemathsymbol [grave] [accent] [tf] ["0] + \definemathsymbol [ddot] [accent] [tf] ["4] + \definemathsymbol [tilde] [accent] [tf] ["3] + \definemathsymbol [bar] [accent] [tf] ["9] + \definemathsymbol [breve] [accent] [tf] ["8] + \definemathsymbol [check] [accent] [tf] ["7] + \definemathsymbol [hat] [accent] [tf] ["2] + \definemathsymbol [dot] [accent] [tf] ["A] + % Why is mathring not defined?? + \definemathsymbol [mathring] [accent] [tf] ["6] +\stopmathcollection + +\protect \endinput diff --git a/tex/context/base/math-ext.lua b/tex/context/base/math-ext.lua new file mode 100644 index 000000000..673103677 --- /dev/null +++ b/tex/context/base/math-ext.lua @@ -0,0 +1,154 @@ +if not modules then modules = { } end modules ['math-ext'] = { + version = 1.001, + comment = "companion to math-ini.mkiv", + 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="MATHEMATICAL SHORT BAR", +-- direction="on", +-- linebreak="nu", + mathclass="relation", + mathname="mapstochar", + unicodeslot=0xFE321, +} ) + +mathematics.extras.add(0xFE322, { + category="sm", + description="MATHEMATICAL LEFT HOOK", + mathclass="relation", + mathname="lhook", + unicodeslot=0xFE322, +} ) + +mathematics.extras.add(0xFE323, { + category="sm", + description="MATHEMATICAL RIGHT HOOK", + mathclass="relation", + mathname="rhook", + unicodeslot=0xFE323, +} ) + +--~ mathematics.extras.add(0xFE304, { +--~ category="sm", +--~ description="TOP AND BOTTOM PARENTHESES", +--~ direction="on", +--~ linebreak="al", +--~ mathclass="doubleaccent", +--~ mathname="doubleparent", +--~ unicodeslot=0xFE304, +--~ accents={ 0x023DC, 0x023DD }, +--~ } ) + +--~ mathematics.extras.add(0xFE305, { +--~ category="sm", +--~ description="TOP AND BOTTOM BRACES", +--~ direction="on", +--~ linebreak="al", +--~ mathclass="doubleaccent", +--~ mathname="doublebrace", +--~ unicodeslot=0xFE305, +--~ accents={ 0x023DE, 0x023DF }, +--~ } ) + +--~ \Umathchardef\braceld="0 "1 "FF07A +--~ \Umathchardef\bracerd="0 "1 "FF07B +--~ \Umathchardef\bracelu="0 "1 "FF07C +--~ \Umathchardef\braceru="0 "1 "FF07D diff --git a/tex/context/base/math-for.mkiv b/tex/context/base/math-for.mkiv new file mode 100644 index 000000000..e33276d53 --- /dev/null +++ b/tex/context/base/math-for.mkiv @@ -0,0 +1,79 @@ +%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} + +\def\getformulaparameters{\getparameters[\??fm]} + +%D \macros +%D {setupformulas} + +\newtoks \everysetupformulas + +\unexpanded\def\setupformulas + {\dodoubleempty\dosetupformulas} + +\def\dosetupformulas[#1][#2]% + {\ifsecondargument + \edef\currentformula{#1}% + \getparameters[\??fm#1][#2]% + \else +% \let\currentformula\v!formula % hm + \let\currentformula\empty + \getparameters[\??fm][#1]% + \fi + \the\everysetupformulas + \let\currentformula\empty} + +%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 + +\unexpanded\def\setuptextformulas + {\dosingleempty\dosetuptextformulas} + +\def\dosetuptextformulas[#1]% + {\getparameters[\??mt][#1]% + \the\everysetuptextformulas} + +\protect \endinput diff --git a/tex/context/base/math-fou.mkii b/tex/context/base/math-fou.mkii new file mode 100644 index 000000000..8a72f1288 --- /dev/null +++ b/tex/context/base/math-fou.mkii @@ -0,0 +1,196 @@ +%D \module +%D [ file=math-fou, +%D version=2001.04.12, +%D title=\CONTEXT\ Math Macros, +%D subtitle=Fourier Specials, +%D author={Michel Biovani \& 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. + +% see end of file for todo + +\unprotect + +\startmathcollection [fou] + + \definemathsymbol [Gamma] [alpha] [mi] ["00] + \definemathsymbol [Delta] [alpha] [mi] ["01] + \definemathsymbol [Theta] [alpha] [mi] ["02] + \definemathsymbol [Lambda] [alpha] [mi] ["03] + \definemathsymbol [Xi] [alpha] [mi] ["04] + \definemathsymbol [Pi] [alpha] [mi] ["05] + \definemathsymbol [Sigma] [alpha] [mi] ["06] + \definemathsymbol [Upsilon] [alpha] [mi] ["07] + \definemathsymbol [Phi] [alpha] [mi] ["08] + \definemathsymbol [Psi] [alpha] [mi] ["09] + \definemathsymbol [Omega] [alpha] [mi] ["0A] + +\stopmathcollection + +\startmathcollection [fou] + + \definemathcharacter [+] [bin] [sy] ["80] + \definemathcharacter [=] [rel] [sy] ["81] + \definemathcharacter [<] [rel] [sy] ["82] + \definemathcharacter [>] [rel] [sy] ["83] + +\stopmathcollection + +\startmathcollection [fou] + + \definemathsymbol [leqslant] [rel] [sy] ["84] + \definemathsymbol [geqslant] [rel] [sy] ["85] + \definemathsymbol [parallelslant] [rel] [sy] ["86] + \definemathsymbol [thething] [ord] [sy] ["87] + \definemathsymbol [vDash] [rel] [sy] ["88] + \definemathsymbol [blacktriangleleft] [rel] [sy] ["89] + \definemathsymbol [blacktriangleright] [rel] [sy] ["8A] + \definemathsymbol [nleqslant] [rel] [sy] ["8B] + \definemathsymbol [ngeqslant] [rel] [sy] ["8C] + \definemathsymbol [parallel] [rel] [sy] ["8D] + \definemathsymbol [nparallel] [rel] [sy] ["8E] + \definemathsymbol [nparallelslant] [rel] [sy] ["8F] + \definemathsymbol [nvDash] [rel] [sy] ["90] + \definemathsymbol [intercal] [bin] [sy] ["91] + \definemathsymbol [hslash] [ord] [sy] ["92] + \definemathsymbol [nexists] [ord] [sy] ["93] + \definemathsymbol [varsubsetneq] [rel] [sy] ["93] + +\stopmathcollection + +\startmathcollection [fou] + + \definemathcharacter [(] [nothing] [mr] ["28] [ex] ["A1] + \definemathcharacter [)] [nothing] [mr] ["29] [ex] ["A2] + \definemathcharacter [91] [nothing] [mr] ["5B] [ex] ["A3] % [ + \definemathcharacter [93] [nothing] [mr] ["5D] [ex] ["A4] % ] + \definemathcharacter [/] [nothing] [mr] ["2F] [ex] ["B1] + + \definemathcharacter [124] [nothing] [sy] ["6A] [ex] ["AF] % | + \definemathcharacter [92] [nothing] [sy] ["6E] [ex] ["B2] % \ + +\stopmathcollection + +\startmathcollection [fou] + + \definemathsymbol [Vert] [nothing] [sy] ["6B] [ex] ["B0] + \definemathsymbol [vert] [nothing] [sy] ["6A] [ex] ["AF] + \definemathsymbol [VERT] [nothing] [sy] ["98] [ex] ["93] + \definemathsymbol [Downarrow] [rel] [sy] ["2B] [ex] ["C4] + \definemathsymbol [backslash] [nothing] [sy] ["6E] [ex] ["B2] + \definemathsymbol [rangle] [close] [sy] ["69] [ex] ["AE] + \definemathsymbol [langle] [open] [sy] ["68] [ex] ["AD] + \definemathsymbol [rbrace] [close] [sy] ["67] [ex] ["AA] + \definemathsymbol [lbrace] [open] [sy] ["66] [ex] ["A9] + \definemathsymbol [rceil] [close] [sy] ["65] [ex] ["A8] + \definemathsymbol [lceil] [open] [sy] ["64] [ex] ["A7] + \definemathsymbol [rfloor] [close] [sy] ["63] [ex] ["A6] + \definemathsymbol [lfloor] [open] [sy] ["62] [ex] ["A5] + \definemathsymbol [dblbrackleft] [open] [sy] ["99] [ex] ["85] + \definemathsymbol [dblbrackright] [close] [sy] ["9A] [ex] ["86] + +\stopmathcollection + +\startmathcollection [fou] + + \definemathsymbol [varkappa] [ord] [mi] ["80] % check this + \definemathsymbol [varvarrho] [ord] [mi] ["81] % check this + \definemathsymbol [xswordsup] [ord] [sy] ["96] + \definemathsymbol [xswordsdown] [ord] [sy] ["97] + \definemathsymbol [notowns] [rel] [sy] ["9C] + \definemathsymbol [hbar] [ord] [sy] ["9D] + \definemathsymbol [smallsetminus] [bin] [sy] ["9E] + +\stopmathcollection + +\startmathcollection [fou] + + \definemathsymbol [notin] [rel] [sy] ["9B] + +\stopmathcollection + +\startmathcollection [fou] + + \definemathsymbol [iintop] [op] [ex] ["CE] + \definemathsymbol [iiintop] [op] [ex] ["D0] + \definemathsymbol [oiintop] [op] [ex] ["D2] + \definemathsymbol [oiiintop] [op] [ex] ["D4] + \definemathsymbol [slashintop] [op] [ex] ["D6] + +\stopmathcollection + +\startmathcollection [fou] + + \definemathcommand [iint] {\iintop \nolimits} + \definemathcommand [iiint] {\iiintop \nolimits} + \definemathcommand [oiint] {\oiintop \nolimits} + \definemathcommand [oiiint] {\oiiintop \nolimits} + \definemathcommand [slashint] {\slashintop\nolimits} + +\stopmathcollection + +\startmathcollection [fou] + + \definemathsymbol [acute] [accent] [mr] ["1] + \definemathsymbol [grave] [accent] [mr] ["0] + \definemathsymbol [ddot] [accent] [mr] ["4] + \definemathsymbol [tilde] [accent] [mr] ["3] + \definemathsymbol [bar] [accent] [mr] ["9] + \definemathsymbol [breve] [accent] [mr] ["8] + \definemathsymbol [check] [accent] [mr] ["7] + \definemathsymbol [hat] [accent] [mr] ["2] + \definemathsymbol [dot] [accent] [mr] ["A] + \definemathsymbol [mathring] [accent] [mr] ["6] + +\stopmathcollection + +\startmathcollection [fou] + + \definemathsymbol [otheralpha] [ord] [mi] ["0B] + \definemathsymbol [otherbeta] [ord] [mi] ["0C] + \definemathsymbol [othergamma] [ord] [mi] ["0D] + \definemathsymbol [otherdelta] [ord] [mi] ["0E] + \definemathsymbol [otherepsilon] [ord] [mi] ["0F] + \definemathsymbol [otherzeta] [ord] [mi] ["10] + +\stopmathcollection + +\protect \endinput + +% from a mail of Michel B / todo + +% \definemathsymbol [acute] [accent] [operators] ["1] +% \definemathsymbol [grave] [accent] [operators] ["0] +% \definemathsymbol [ddot] [accent] [operators] ["4] +% \definemathsymbol [tilde] [accent] [operators] ["3] +% \definemathsymbol [bar] [accent] [operators] ["9] +% \definemathsymbol [breve] [accent] [operators] ["8] +% \definemathsymbol [check] [accent] [operators] ["7] +% \definemathsymbol [hat] [accent] [operators] ["2] +% \definemathsymbol [dot] [accent] [operators] ["A] +% \definemathsymbol [mathring] [accent] [operators] ["6] + +% \definemathsymbol [wideparen] [ord] [largesymbols] ["94] +% \definemathsymbol [widearc] [accent] [largesymbols] ["D8] + +% check for definition of \overset (ams) + +% \def\FOUwidering#1% +% {\overset{\smash{\vbox to .2ex{\hbox{$\mathring{}$}}}}{\wideparen{#1}}} + +% \startmathcollection [default] % [ams] +% +% \definemathcommand [widering] {\FOUwidering} +% +% \stopmathcollection + +% \definemathsymbol [otheralpha] [ord] [otherletters] ["0B] +% \definemathsymbol [otherbeta] [ord] [otherletters] ["0C] +% \definemathsymbol [othergamma] [ord] [otherletters] ["0D] +% \definemathsymbol [otherdelta] [ord] [otherletters] ["0E] +% \definemathsymbol [otherepsilon] [ord] [otherletters] ["0F] +% \definemathsymbol [otherzeta] [ord] [otherletters] ["10] 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..2305cec30 --- /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% +% {\ifdefined\@@chemicalletter +% \dosetsubscripts +% \mathstyle{\@@chemicalletter{#1}}% +% \doresetsubscripts +% \else +% \mathstyle{\rm#1}% +% \fi} + +% \unexpanded\def\ch#1% +% {\ifdefined\@@chemicalletter +% \dosetsubscripts +% \mathematics{\@@chemicalletter{#1}}% +% \doresetsubscripts +% \else +% \mathematics{\rm#1}% +% \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 new file mode 100644 index 000000000..63d7cad38 --- /dev/null +++ b/tex/context/base/math-ini.lua @@ -0,0 +1,340 @@ +if not modules then modules = { } end modules ['math-ext'] = { + version = 1.001, + comment = "companion to math-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- 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 + +local trace_defining = false trackers.register("math.defining", function(v) trace_defining = v end) + +mathematics = mathematics or { } + +mathematics.extrabase = 0xFE000 -- here we push some virtuals +mathematics.privatebase = 0xFF000 -- here we push the ex + +local families = { + tf = 0, it = 1, sl = 2, bf = 3, bi = 4, bs = 5, -- virtual fonts or unicode otf +} + +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 +} + +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) +-- no need for " in class and family (saves space) + +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 +local function radical(family,slot) + return format('\\Uradical "%X "%X ',family,slot) +end +local function mathchardef(name,class,family,slot) + return format('\\Umathchardef\\%s "%X "%X "%X ',name,class,family,slot) +end +local function mathcode(target,class,family,slot) + return format('\\Umathcode%s="%X "%X "%X ',target,class,family,slot) +end +local function mathtopaccent(class,family,slot) + return format('\\Umathaccent "%X "%X "%X ',0,family,slot) -- no class +end +local function mathbotaccent(class,family,slot) + return format('\\Umathbotaccent "%X "%X "%X ',0,family,slot) -- no class +end +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 + +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 + -- 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 + +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 + +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 + +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 +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 + 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 + end + 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 + 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 + name = name or character.contextname + if name then + if trace_defining then + report(class,family,unicode,name) + end + 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 + +-- needed for mathml analysis + +function mathematics.utfmathclass(chr, default) + local cd = characters.data[utfbyte(chr)] + return (cd and cd.mathclass) or default or "unknown" +end +function mathematics.utfmathstretch(chr, default) -- "h", "v", "b", "" + local cd = characters.data[utfbyte(chr)] + return (cd and cd.mathstretch) or default or "" +end +function mathematics.utfmathcommand(chr, default) + local cd = characters.data[utfbyte(chr)] + local cmd = cd and cd.mathname + tex.sprint(cmd or default or "") +end +function mathematics.utfmathfiller(chr, default) + local cd = characters.data[utfbyte(chr)] + local cmd = cd and (cd.mathfiller or cd.mathname) + tex.sprint(cmd or default or "") +end + +mathematics.entities = mathematics.entities or { } + +function mathematics.register_xml_entities() + local entities = xml.entities + for name, unicode in next, mathematics.entities do + if not entities[name] then + entities[name] = utfchar(unicode) + end + end +end + +-- helpers + +function mathematics.big(tfmdata,unicode,n) + local t = tfmdata.characters + local c = t[unicode] + if c then + local vv = c.vert_variants or c.next and t[c.next].vert_variants + if vv then + local vvn = vv[n] + return vvn and vvn.glyph or vv[#vv].glyph or unicode + else + local next = c.next + while next do + if n <= 1 then + return next + else + n = n - 1 + local tn = t[next].next + if tn then + next = tn + else + return next + end + end + end + end + end + return unicode +end + +-- plugins + +local hvars = table.tohash { + --~ "RadicalKernBeforeDegree", + --~ "RadicalKernAfterDegree", +} + +function mathematics.scaleparameters(t,tfmtable,delta,hdelta,vdelta) + local math_parameters = tfmtable.math_parameters + if math_parameters and next(math_parameters) then + delta = delta or 1 + hdelta, vdelta = hdelta or delta, vdelta or delta + local _, mp = mathematics.dimensions(math_parameters) + for name, value in next, mp do + if name == "RadicalDegreeBottomRaisePercent" then + mp[name] = value + elseif hvars[name] then + mp[name] = hdelta * value + else + mp[name] = vdelta * 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 new file mode 100644 index 000000000..f9dd859c4 --- /dev/null +++ b/tex/context/base/math-ini.mkii @@ -0,0 +1,684 @@ +%D \module +%D [ file=math-ini, +%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] +%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 / 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}.mkii}% + \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.mkii}% + \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 + {\relax + \ifmmode + \the\everymathpunctuation + \fi + \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 new file mode 100644 index 000000000..828a6eccb --- /dev/null +++ b/tex/context/base/math-ini.mkiv @@ -0,0 +1,657 @@ +%D \module +%D [ file=math-ini, +%D version=2008.01.02, +%D title=\CONTEXT\ Math Macros, +%D subtitle=Initializations, +%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 / 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 New: + +\let\startimath\Ustartmath \let\stopimath \Ustopmath +\let\startdmath\Ustartdisplaymath \let\stopdmath \Ustopmath + +%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[mathalphabet] \chardef\mathalphabetattribute \dogetattributeid{mathalphabet} +\definesystemattribute[mathsize] \chardef\mathsizeattribute \dogetattributeid{mathsize} +\definesystemattribute[mathpunctuation] \chardef\mathpunctuationattribute \dogetattributeid{mathpunctuation} +\definesystemattribute[mathgreek] \chardef\mathgreekattribute \dogetattributeid{mathgreek} + +% todo: only in mmode + +\unexpanded\def\mathgreekupright{\attribute\mathgreekattribute11 } +\unexpanded\def\mathgreekitalic {\attribute\mathgreekattribute22 } +\unexpanded\def\mathgreekdefault{\attribute\mathgreekattribute\attributeunsetvalue} + +\let\mathgreeknormal\mathgreekupright +\let\mathgreeknone \mathgreekdefault + +\def\setmathattribute#1#2{\ifmmode\ctxlua{mathematics.sync_a_both ("#1","#2")}\fi} +\def\setmathalphabet #1{\ifmmode\ctxlua{mathematics.sync_a_name ("#1")}\fi} +\def\setmathstyle #1{\ifmmode\ctxlua{mathematics.sync_a_style("#1")}\fi} + +\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 + +\let\Bbb\mathblackboard + +\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{{\mathscript #1}} % for AMS compatibility +\unexpanded\def\mathfrak#1{{\mathfraktur #1}} % for AMS compatibility +\unexpanded\def\mathbb #1{{\mathblackboard#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 + +\let\normaltf\tf \unexpanded\def\tf{\ifmmode\mathtf\else\normaltf\fi} +\let\normalbf\bf \unexpanded\def\bf{\ifmmode\mathbf\else\normalbf\fi} +\let\normalit\it \unexpanded\def\it{\ifmmode\mathit\else\normalit\fi} +\let\normalsl\sl \unexpanded\def\sl{\ifmmode\mathsl\else\normalsl\fi} +\let\normalbi\bi \unexpanded\def\bi{\ifmmode\mathbi\else\normalbi\fi} +\let\normalbs\bs \unexpanded\def\bs{\ifmmode\mathbs\else\normalbs\fi} + +\let\normalrm\rm \unexpanded\def\rm{\ifmmode\mathrm\else\normalrm\fi} +\let\normalss\ss \unexpanded\def\ss{\ifmmode\mathss\else\normalss\fi} +\let\normaltt\tt \unexpanded\def\tt{\ifmmode\mathtt\else\normaltt\fi} + \unexpanded\def\mr{\ifmmode \normalmr\fi} + +\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 To be done. + +\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\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\Ustartmath\mathsurround\zeropoint#1\Ustopmath} +\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 + +% this will be sorted out: + +\let\mathcharacter \getvalue +\let\textcharacter \getvalue +\unexpanded\def\definefamilysynonym {\dotripleempty\dodefinefamilysynonym} +\def\dodefinefamilysynonym [#1][#2][#3]{} +\unexpanded\def\definemathsymbol {\dosixtupleempty\dodefinemathsymbol} +\def\dodefinemathsymbol [#1][#2][#3][#4][#5][#6]{} +\unexpanded\def\definemathcharacter {\dosixtupleempty\dodefinemathcharacter} +\def\dodefinemathcharacter [#1][#2][#3][#4][#5][#6]{} + +\unexpanded\def\definemathcommand + {\dotripleempty\dodefinemathcommand} + +\def\dodefinemathcommand[#1][#2][#3]#4% command class args meaning + {\ifthirdargument + \processaction + [#3] + [one=>\setuvalue{#1}##1{\puremathcomm{#2}{#4{##1}}}, + two=>\setuvalue{#1}##1##2{\puremathcomm{#2}{#4{##1}{##2}}}]% + \else\ifsecondargument + \setuvalue{#1}{\puremathcomm{#2}{#4}}% + \else + \setuvalue{#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 + +\let\mathfunction\firstofoneargument + +\def\mfunction #1{{\mr#1}} +\def\mfunctionlabeltext#1{{\mr\mathlabeltext{#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 + +\unexpanded\def\do@mathopnolimits #1{\mathop{\mscaledtext{#1}}\nolimits} +\unexpanded\def\do@mfunction #1{\mscaledtext{#1}} +\unexpanded\def\do@mfunctionlabeltext#1{\mscaledtext{\mathlabeltext{#1}}} + +\def\setmathfunctionstyle#1% rm ss tt (can be made faster if needed) + {\doifsomething{#1} + {\def\currentmscaledstyle{#1}% + \let\mathopnolimits \do@mathopnolimits + \let\mfunction \do@mfunction + \let\mfunctionlabeltext\do@mfunctionlabeltext}} + +\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: + +% no longer supported this way, has to be done with \setupmathematics +% +% \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. + +\newtoks\everydonknuthmode +\newtoks\everynonknuthmode + +\def\nonknuthmode{\the\everynonknuthmode\let\nonknuthmode\relax} +\def\donknuthmode{\the\everydonknuthmode} + +\ifdefined\normalsuber\else \def\normalsuber{_} \fi +\ifdefined\normalsuper\else \def\normalsuper{^} \fi +\ifdefined\normalaltab\else \def\normalaltab{&} \fi + +\bgroup + + \catcode`_=\active + \catcode`^=\active + \catcode`&=\active + + \global \everynonknuthmode {\appendtoks + \let_\normalsuber + \let^\normalsuper + \let&\normalaltab + \to \everymathematics} + +\egroup + +\appendtoks + \mathcode`_="8000 + \mathcode`^="8000 + \mathcode`&="8000 + \catcode`_=\@@other + \catcode`^=\@@other + \catcode`&=\@@other +\to \everynonknuthmode + +\appendtoks + \catcode`_=\@@subscript + \catcode`^=\@@superscript + \catcode`&=\@@alignment +\to \everydonknuthmode + +\appendtoks + \startextendcatcodetable\ctxcatcodes + \catcode`_=\@@other + \catcode`^=\@@other + \catcode`&=\@@other + \stopextendcatcodetable +\to \everynonknuthmode + +\appendtoks + \startextendcatcodetable\ctxcatcodes + \catcode`_=\@@subscript + \catcode`^=\@@superscript + \catcode`&=\@@alignment + \stopextendcatcodetable +\to \everydonknuthmode + +%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 + +\unexpanded\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 Delayed: greek. +%D +%D \starttyping +%D \usetypescript[cambria]\setupbodyfont[cambria] +%D \startTEXpage +%D $\alpha \mathgreekupright \alpha \mathgreekitalic \alpha$ +%D \stopTEXpage +%D \stoptyping + +% [lc uc] normal (upright) = 2, italic = 3, none = 0/1 + +\setevalue{\??mo:greek:\v!normal :\v!normal}{\attribute\mathgreekattribute22 } +\setevalue{\??mo:greek:\v!normal :\v!italic}{\attribute\mathgreekattribute23 } +\setevalue{\??mo:greek:\v!normal :\v!none }{\attribute\mathgreekattribute21 } + +\setevalue{\??mo:greek:\v!italic :\v!normal}{\attribute\mathgreekattribute32 } +\setevalue{\??mo:greek:\v!italic :\v!italic}{\attribute\mathgreekattribute33 } +\setevalue{\??mo:greek:\v!italic :\v!none }{\attribute\mathgreekattribute31 } + +\setevalue{\??mo:greek:\v!none :\v!normal}{\attribute\mathgreekattribute12 } +\setevalue{\??mo:greek:\v!none :\v!italic}{\attribute\mathgreekattribute13 } +\setevalue{\??mo:greek:\v!none :\v!none }{\attribute\mathgreekattribute\attributeunsetvalue} + +\appendtoks + \csname\??mo:greek:\@@molcgreek:\@@moucgreek\endcsname +\to \everymathematics + +\setupmathematics + [lcgreek=\v!italic, + ucgreek=\v!normal] % was: none + +%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\attribute\mathpunctuationattribute\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}} + +\def\mathstylefont#1% #1 is number (\normalmathstyle) + {\ifcase#1\relax + \textfont \or + \textfont \or + \textfont \or + \textfont \or + \scriptfont \or + \scriptfont \or + \scriptscriptfont \or + \scriptscriptfont \else + \textfont + \fi\zerocount} + +%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 Safeguard against redefinitions: + +\appendtoks + \let\_\normalunderscore % is textunderscore or fakeunderscore +\to \everymathematics + +%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$ + +% force text mode, will be overloaded later + +\ifx\text\undefined \let\text\hbox \fi + +\def\mathoptext#1{\mathop{\text{#1}}} + +\protect \endinput diff --git a/tex/context/base/math-inl.mkiv b/tex/context/base/math-inl.mkiv new file mode 100644 index 000000000..89de0242b --- /dev/null +++ b/tex/context/base/math-inl.mkiv @@ -0,0 +1,26 @@ +%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 + +% Obsolete, as we do snapping differently now. + +\def\snappedinlineformula {\dosingleempty\dosnappedinlineformula} +\def\dosnappedinlineformula[#1]#2{\mathematics{#2}} +\let\tform \mathematics +\let\gform \snappedinlineformula +\let\enableautomath \relax + +\protect \endinput diff --git a/tex/context/base/math-int.mkiv b/tex/context/base/math-int.mkiv new file mode 100644 index 000000000..2af471b5c --- /dev/null +++ b/tex/context/base/math-int.mkiv @@ -0,0 +1,90 @@ +%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\integralrepeatsymbol{\intop} +\def\integralrepeatsymbol{{\int}} + +\def\repeatintegral#1% + {\scratchtoks\emptytoks + \let\dointlimits\donothing + \let\dodointlimits\intlimits + \dorecurse{#1}{\appendtoks \integralrepeatsymbol \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-lan.mkiv b/tex/context/base/math-lan.mkiv new file mode 100644 index 000000000..1d3132578 --- /dev/null +++ b/tex/context/base/math-lan.mkiv @@ -0,0 +1,67 @@ +%D \module +%D [ file=math-lan, +%D version=2009.03.10, +%D title=\CONTEXT\ Math Macros, +%D subtitle=Language 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}{ConTeXt Math Macros / Language Support} + +\unprotect + +\setupmathlabeltext [\s!en] [arccos=arccos] +\setupmathlabeltext [\s!en] [arcsin=arcsin] +\setupmathlabeltext [\s!en] [arctan=arctan] +\setupmathlabeltext [\s!en] [arg=arg] +\setupmathlabeltext [\s!en] [cosh=cosh] +\setupmathlabeltext [\s!en] [cos=cos] +\setupmathlabeltext [\s!en] [coth=coth] +\setupmathlabeltext [\s!en] [cot=cot] +\setupmathlabeltext [\s!en] [csc=csc] +\setupmathlabeltext [\s!en] [deg=deg] +\setupmathlabeltext [\s!en] [det=det] +\setupmathlabeltext [\s!en] [dim=dim] +\setupmathlabeltext [\s!en] [exp=exp] +\setupmathlabeltext [\s!en] [gcd=gcd] +\setupmathlabeltext [\s!en] [hom=hom] +\setupmathlabeltext [\s!en] [inf=inf] +\setupmathlabeltext [\s!en] [injlim=inj\,lim] +\setupmathlabeltext [\s!en] [ker=ker] +\setupmathlabeltext [\s!en] [lg=lg] +\setupmathlabeltext [\s!en] [liminf=lim\,inf] +\setupmathlabeltext [\s!en] [limsup=lim\,sup] +\setupmathlabeltext [\s!en] [lim=lim] +\setupmathlabeltext [\s!en] [ln=ln] +\setupmathlabeltext [\s!en] [log=log] +\setupmathlabeltext [\s!en] [median=median] +\setupmathlabeltext [\s!en] [max=max] +\setupmathlabeltext [\s!en] [min=min] +\setupmathlabeltext [\s!en] [mod=mod] +\setupmathlabeltext [\s!en] [projlim=proj\,lim] +\setupmathlabeltext [\s!en] [Pr=Pr] +\setupmathlabeltext [\s!en] [sec=sec] +\setupmathlabeltext [\s!en] [sinh=sinh] +\setupmathlabeltext [\s!en] [sin=sin] +\setupmathlabeltext [\s!en] [sup=sup] +\setupmathlabeltext [\s!en] [tanh=tanh] +\setupmathlabeltext [\s!en] [tan=tan] + +\setupmathlabeltext [\s!pl] [tg=tg] +\setupmathlabeltext [\s!pl] [cot=ctg] +\setupmathlabeltext [\s!pl] [ctg=ctg] +\setupmathlabeltext [\s!pl] [arcsin=arc\,sin] +\setupmathlabeltext [\s!pl] [arccos=arc\,cos] +\setupmathlabeltext [\s!pl] [arctan=arc\,tg] +\setupmathlabeltext [\s!pl] [arctg=arc\,tg] +\setupmathlabeltext [\s!pl] [arcctg=arc\,ctg] + +\setupmathlabeltext [\s!nl] [gcd=ggd] +\setupmathlabeltext [\s!nl] [lcm=kgv] + +\protect \endinput diff --git a/tex/context/base/math-lbr.mkii b/tex/context/base/math-lbr.mkii new file mode 100644 index 000000000..cf69eec1f --- /dev/null +++ b/tex/context/base/math-lbr.mkii @@ -0,0 +1,481 @@ +%D \module +%D [ file=math-lbr, +%D version=2001.04.12, +%D title=\CONTEXT\ Math Macros, +%D subtitle=Lucida Specials, +%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. + +\unprotect + +\definefamilysynonym [lbr] [calligraphy] [sy] +\definefamilysynonym [lbr] [oldstyle] [mi] + +\definefamilysynonym [lbr] [blackboard] [ma] +\definefamilysynonym [lbr] [ucgreek] [mb] +\definefamilysynonym [lbr] [vargreek] [mi] + +\startmathcollection[lbr] + +\definemathsymbol [boxdot] [bin] [sy] ["ED] +\definemathsymbol [boxplus] [bin] [sy] ["EA] +\definemathsymbol [boxtimes] [bin] [sy] ["EC] +\definemathsymbol [square] [ord] [ma] ["02] +\definemathsymbol [Box] [ord] [ma] ["02] % square +\definemathsymbol [blacksquare] [ord] [ma] ["03] +\definemathsymbol [centerdot] [bin] [ma] ["E1] % [sy] ["01] +\definemathsymbol [Diamond] [ord] [sy] ["05] +\definemathsymbol [lozenge] [ord] [sy] ["05] % Diamond +\definemathsymbol [blacklozenge] [ord] [ma] ["09] +\definemathsymbol [circlearrowright] [rel] [ma] ["8C] +\definemathsymbol [circlearrowleft] [rel] [ma] ["8B] +\definemathsymbol [rightleftharpoons] [rel] [sy] ["8E] +\definemathsymbol [leftrightharpoons] [rel] [sy] ["8D] +\definemathsymbol [boxminus] [bin] [sy] ["EB] +\definemathsymbol [Vdash] [rel] [sy] ["F0] +\definemathsymbol [Vvdash] [rel] [mb] ["D3] +\definemathsymbol [vDash] [rel] [mb] ["D6] +\definemathsymbol [twoheadrightarrow] [rel] [ma] ["25] +\definemathsymbol [twoheadleftarrow] [rel] [ma] ["23] +\definemathsymbol [leftleftarrows] [rel] [ma] ["71] +\definemathsymbol [rightrightarrows] [rel] [ma] ["73] +\definemathsymbol [upuparrows] [rel] [ma] ["72] +\definemathsymbol [downdownarrows] [rel] [ma] ["74] +\definemathsymbol [upharpoonright] [rel] [ma] ["75] +\definemathsymbol [restriction] [rel] [ma] ["77] +\definemathsymbol [downharpoonright] [rel] [ma] ["77] +\definemathsymbol [upharpoonleft] [rel] [ma] ["76] +\definemathsymbol [downharpoonleft] [rel] [ma] ["78] +\definemathsymbol [rightarrowtail] [rel] [ma] ["29] +\definemathsymbol [leftarrowtail] [rel] [ma] ["28] +\definemathsymbol [leftrightarrows] [rel] [ma] ["6E] +\definemathsymbol [rightleftarrows] [rel] [ma] ["6D] +\definemathsymbol [Lsh] [rel] [ma] ["7B] +\definemathsymbol [Rsh] [rel] [ma] ["7D] +\definemathsymbol [rightsquigarrow] [rel] [ma] ["8E] +\definemathsymbol [leadsto] [rel] [ma] ["8E] % rightsquigarrow +\definemathsymbol [leftrightsquigarrow] [rel] [ma] ["91] +\definemathsymbol [looparrowleft] [rel] [ma] ["3F] +\definemathsymbol [looparrowright] [rel] [ma] ["40] +\definemathsymbol [circeq] [rel] [sy] ["D0] +\definemathsymbol [succsim] [rel] [sy] ["E1] +\definemathsymbol [gtrsim] [rel] [sy] ["DD] +\definemathsymbol [gtrapprox] [rel] [mb] ["DB] +\definemathsymbol [multimap] [rel] [mb] ["C7] +\definemathsymbol [therefore] [rel] [sy] ["90] +\definemathsymbol [because] [rel] [sy] ["91] +\definemathsymbol [doteqdot] [rel] [sy] ["CA] +\definemathsymbol [Doteq] [rel] [sy] ["CA] % doteqdot +\definemathsymbol [triangleq] [rel] [sy] ["D5] +\definemathsymbol [precsim] [rel] [sy] ["E0] +\definemathsymbol [lesssim] [rel] [sy] ["DC] +\definemathsymbol [lessapprox] [rel] [mb] ["DA] +\definemathsymbol [eqslantless] [rel] [mb] ["E2] +\definemathsymbol [eqslantgtr] [rel] [mb] ["E3] +\definemathsymbol [curlyeqprec] [rel] [mb] ["E6] +\definemathsymbol [curlyeqsucc] [rel] [mb] ["E7] +\definemathsymbol [preccurlyeq] [rel] [mb] ["E4] +\definemathsymbol [leqq] [rel] [sy] ["DA] +\definemathsymbol [leqslant] [rel] [mb] ["E0] +\definemathsymbol [lessgtr] [rel] [sy] ["DE] +\definemathsymbol [backprime] [ord] [mb] ["C8] +\definemathsymbol [dabar@] [ord] [ma] ["03] % !! @ +\definemathsymbol [risingdotseq] [rel] [sy] ["CC] +\definemathsymbol [fallingdotseq] [rel] [sy] ["CB] +\definemathsymbol [succcurlyeq] [rel] [mb] ["E5] +\definemathsymbol [geqq] [rel] [sy] ["DB] +\definemathsymbol [geqslant] [rel] [mb] ["E1] +\definemathsymbol [gtrless] [rel] [sy] ["DF] +\definemathsymbol [sqsubset] [rel] [sy] ["E4] +\definemathsymbol [sqsupset] [rel] [sy] ["E5] +\definemathsymbol [vartriangleright] [rel] [mb] ["2E] +\definemathsymbol [rhd] [bin] [mb] ["2E] +\definemathsymbol [lhd] [bin] [mb] ["2F] +\definemathsymbol [vartriangleleft] [rel] [mb] ["2F] +\definemathsymbol [trianglerighteq] [rel] [sy] ["F5] +\definemathsymbol [unrhd] [bin] [sy] ["F5] % trianglerighteq +\definemathsymbol [trianglelefteq] [rel] [sy] ["F4] +\definemathsymbol [unlhd] [bin] [sy] ["F4] % trianglelefteq +\definemathsymbol [bigstar] [ord] [ma] ["AB] +\definemathsymbol [between] [rel] [mb] ["F2] +\definemathsymbol [blacktriangledown] [ord] [ma] ["07] +\definemathsymbol [blacktriangleright] [rel] [mb] ["F1] +\definemathsymbol [blacktriangleleft] [rel] [mb] ["F0] +\definemathsymbol [vartriangle] [rel] [ma] ["04] +\definemathsymbol [triangleup] [ord] [ma] ["04] % vartriangle +\definemathsymbol [blacktriangle] [ord] [ma] ["05] +\definemathsymbol [triangledown] [ord] [ma] ["06] +\definemathsymbol [eqcirc] [rel] [sy] ["CF] +\definemathsymbol [lesseqgtr] [rel] [mb] ["E8] +\definemathsymbol [gtreqless] [rel] [mb] ["E9] +\definemathsymbol [lesseqqgtr] [rel] [mb] ["EA] +\definemathsymbol [gtreqqless] [rel] [mb] ["EB] +\definemathsymbol [Rrightarrow] [rel] [ma] ["6C] +\definemathsymbol [Lleftarrow] [rel] [ma] ["6A] +\definemathsymbol [veebar] [bin] [mb] ["D2] +\definemathsymbol [barwedge] [bin] [sy] ["F6] +\definemathsymbol [doublebarwedge] [bin] [sy] ["D4] +\definemathsymbol [angle] [ord] [sy] ["8B] +\definemathsymbol [measuredangle] [ord] [sy] ["8C] +\definemathsymbol [sphericalangle] [ord] [sy] ["8D] +\definemathsymbol [varpropto] [rel] [sy] ["2F] +\definemathsymbol [smallsmile] [rel] [mb] ["5E] +\definemathsymbol [smallfrown] [rel] [mb] ["5F] +\definemathsymbol [Subset] [rel] [sy] ["F8] +\definemathsymbol [Supset] [rel] [sy] ["F9] +\definemathsymbol [Cup] [bin] [sy] ["FA] +\definemathsymbol [doublecup] [bin] [sy] ["FA] % Cup +\definemathsymbol [Cap] [bin] [sy] ["FB] +\definemathsymbol [doublecap] [bin] [sy] ["FB] +\definemathsymbol [curlywedge] [bin] [sy] ["84] +\definemathsymbol [curlyvee] [bin] [sy] ["85] +\definemathsymbol [leftthreetimes] [bin] [mb] ["D0] +\definemathsymbol [rightthreetimes] [bin] [mb] ["D1] +\definemathsymbol [subseteqq] [rel] [mb] ["EE] +\definemathsymbol [supseteqq] [rel] [mb] ["EF] +\definemathsymbol [bumpeq] [rel] [sy] ["C8] +\definemathsymbol [Bumpeq] [rel] [sy] ["C7] +\definemathsymbol [llless] [rel] [mb] ["DE] +\definemathsymbol [lll] [rel] [mb] ["DE] % llless +\definemathsymbol [gggtr] [rel] [mb] ["DF] +\definemathsymbol [ggg] [rel] [mb] ["DF] % gggtr +\definemathsymbol [ulcorner] [open] [ma] ["5B] [ma] ["5B] +\definemathsymbol [urcorner] [close] [ma] ["5C] [ma] ["5C] +\definemathsymbol [circledS] [ord] [mb] ["CA] +\definemathsymbol [pitchfork] [rel] [ma] ["F3] +\definemathsymbol [dotplus] [bin] [sy] ["89] +\definemathsymbol [backsim] [rel] [sy] ["24] +\definemathsymbol [backsimeq] [rel] [sy] ["27] +\definemathsymbol [llcorner] [open] [ma] ["5D] [ma] ["5D] +\definemathsymbol [lrcorner] [close] [ma] ["5E] [ma] ["5E] +\definemathsymbol [complement] [ord] [mb] ["94] +\definemathsymbol [intercal] [bin] [ma] ["03] % !! +\definemathsymbol [circledcirc] [bin] [sy] ["E6] +\definemathsymbol [circledast] [bin] [sy] ["E7] +\definemathsymbol [circleddash] [bin] [mb] ["CC] + +\stopmathcollection + +\startmathcollection [lbr] + +\definemathsymbol [lvertneqq] [rel] [ma] ["DE] +\definemathsymbol [gvertneqq] [rel] [ma] ["DE] +\definemathsymbol [nleq] [rel] [ma] ["9C] +\definemathsymbol [ngeq] [rel] [ma] ["9D] +\definemathsymbol [nless] [rel] [ma] ["9A] +\definemathsymbol [ngtr] [rel] [ma] ["9B] +\definemathsymbol [nprec] [rel] [ma] ["E5] +\definemathsymbol [nsucc] [rel] [ma] ["E6] +\definemathsymbol [lneqq] [rel] [ma] ["DC] +\definemathsymbol [gneqq] [rel] [ma] ["DE] +\definemathsymbol [nleqslant] [rel] [ma] ["D6] +\definemathsymbol [ngeqslant] [rel] [ma] ["D7] +\definemathsymbol [lneq] [rel] [ma] ["DA] +\definemathsymbol [gneq] [rel] [ma] ["DB] +\definemathsymbol [npreceq] [rel] [ma] ["E7] +\definemathsymbol [nsucceq] [rel] [ma] ["E8] +\definemathsymbol [precnsim] [rel] [ma] ["EB] +\definemathsymbol [succnsim] [rel] [ma] ["EC] +\definemathsymbol [lnsim] [rel] [ma] ["E0] +\definemathsymbol [gnsim] [rel] [ma] ["E2] +\definemathsymbol [nleqq] [rel] [ma] ["D8] +\definemathsymbol [ngeqq] [rel] [ma] ["D9] +\definemathsymbol [precneqq] [rel] [ma] ["E9] +\definemathsymbol [succneqq] [rel] [ma] ["EA] +\definemathsymbol [precnapprox] [rel] [ma] ["ED] +\definemathsymbol [succnapprox] [rel] [ma] ["EE] +\definemathsymbol [lnapprox] [rel] [ma] ["E4] +\definemathsymbol [gnapprox] [rel] [ma] ["E3] +\definemathsymbol [nsim] [rel] [ma] ["96] +\definemathsymbol [ncong] [rel] [ma] ["99] +\definemathsymbol [diagup] [ord] [mb] ["CD] +\definemathsymbol [diagdown] [ord] [mb] ["D8] +\definemathsymbol [varsubsetneq] [rel] [ma] ["D0] +\definemathsymbol [varsupsetneq] [rel] [ma] ["D1] +\definemathsymbol [nsubseteqq] [rel] [ma] ["CA] +\definemathsymbol [nsupseteqq] [rel] [ma] ["CB] +\definemathsymbol [subsetneqq] [rel] [ma] ["CE] +\definemathsymbol [supsetneqq] [rel] [ma] ["CF] +\definemathsymbol [varsubsetneqq] [rel] [ma] ["D2] +\definemathsymbol [varsupsetneqq] [rel] [ma] ["D3] +\definemathsymbol [subsetneq] [rel] [ma] ["CC] +\definemathsymbol [supsetneq] [rel] [ma] ["CD] +\definemathsymbol [nsubseteq] [rel] [ma] ["C8] +\definemathsymbol [nsupseteq] [rel] [ma] ["C9] +\definemathsymbol [nparallel] [rel] [ma] ["F7] +\definemathsymbol [nmid] [rel] [ma] ["F6] +\definemathsymbol [nshortmid] [rel] [ma] ["F4] +\definemathsymbol [nshortparallel] [rel] [ma] ["F5] +\definemathsymbol [nvdash] [rel] [ma] ["F8] +\definemathsymbol [nVdash] [rel] [ma] ["F9] +\definemathsymbol [nvDash] [rel] [ma] ["FA] +\definemathsymbol [nVDash] [rel] [ma] ["FB] +\definemathsymbol [ntrianglerighteq] [rel] [ma] ["F2] +\definemathsymbol [ntrianglelefteq] [rel] [ma] ["F1] +\definemathsymbol [ntriangleleft] [rel] [ma] ["EF] +\definemathsymbol [ntriangleright] [rel] [ma] ["F0] +\definemathsymbol [nleftarrow] [rel] [ma] ["32] +\definemathsymbol [nrightarrow] [rel] [ma] ["33] +\definemathsymbol [nLeftarrow] [rel] [ma] ["66] +\definemathsymbol [nRightarrow] [rel] [ma] ["68] +\definemathsymbol [nLeftrightarrow] [rel] [ma] ["67] +\definemathsymbol [nleftrightarrow] [rel] [ma] ["34] +\definemathsymbol [divideontimes] [bin] [mb] ["F7] +\definemathsymbol [varnothing] [ord] [sy] ["53] +\definemathsymbol [nexists] [ord] [ma] ["20] +\definemathsymbol [Finv] [ord] [mb] ["90] +\definemathsymbol [Game] [ord] [mb] ["91] +\definemathsymbol [mho] [ord] [mb] ["92] +\definemathsymbol [eth] [ord] [ma] ["03] % !! +\definemathsymbol [eqsim] [rel] [sy] ["99] +\definemathsymbol [beth] [ord] [mb] ["95] +\definemathsymbol [gimel] [ord] [mb] ["96] +\definemathsymbol [daleth] [ord] [mb] ["97] +\definemathsymbol [lessdot] [bin] [mb] ["DC] +\definemathsymbol [gtrdot] [bin] [mb] ["DD] +\definemathsymbol [ltimes] [bin] [mb] ["CF] +\definemathsymbol [rtimes] [bin] [mb] ["CE] +\definemathsymbol [shortmid] [rel] [mb] ["F4] +\definemathsymbol [shortparallel] [rel] [mb] ["F5] +\definemathsymbol [smallsetminus] [bin] [mb] ["D8] +\definemathsymbol [thicksim] [rel] [sy] ["18] % not that thick +\definemathsymbol [thickapprox] [rel] [sy] ["19] % not that thick +\definemathsymbol [approxeq] [rel] [sy] ["9D] +\definemathsymbol [succapprox] [rel] [mb] ["ED] +\definemathsymbol [precapprox] [rel] [mb] ["EC] +\definemathsymbol [curvearrowleft] [rel] [ma] ["87] +\definemathsymbol [curvearrowright] [rel] [ma] ["88] +\definemathsymbol [digamma] [ord] [ma] ["03] % !! +\definemathsymbol [varkappa] [ord] [mb] ["9B] +\definemathsymbol [Bbbk] [ord] [ma] ["6B] +\definemathsymbol [hslash] [ord] [mb] ["9D] +\definemathsymbol [hbar] [ord] [ma] ["1B] +\definemathsymbol [backepsilon] [rel] [ma] ["03] % !! + +\stopmathcollection + +\startmathcollection [lbr] + +\definemathsymbol [yen] [nothing] [ma] ["03] % !! +\definemathsymbol [checkmark] [nothing] [ma] ["AC] +\definemathsymbol [circledR] [nothing] [mb] ["C9] +\definemathsymbol [maltese] [nothing] [mb] ["CB] + +\stopmathcollection + +\startmathcollection [lbr] + +\definemathsymbol [dashrightarrow] [rel] [ma] ["3A] +\definemathsymbol [dashleftarrow] [rel] [ma] ["38] +\definemathcommand [dasharrow] [rel] {\dashleftarrow\mkern-15.8mu\dashrightarrow} +%definemathcommand [Join] [rel] {\mathchar"0D6F\mkern-15.8mu\mathchar"0D6E} % !! + +\stopmathcollection + +\startmathcollection[lbr] + +\definemathcharacter [91] [open] [mi] ["86] +\definemathcharacter [93] [close] [mi] ["87] +\definemathcharacter [(] [open] [mi] ["84] +\definemathcharacter [)] [close] [mi] ["85] +\definemathcharacter [/] [nothing] [mi] ["3D] +\definemathcharacter [=] [rel] [sy] ["83] +\definemathcharacter [+] [bin] [sy] ["82] + +\definemathcharacter [91] [nothing] [mi] ["86] [ex] ["02] +\definemathcharacter [93] [nothing] [mi] ["87] [ex] ["03] +\definemathcharacter [(] [nothing] [mi] ["84] [ex] ["00] +\definemathcharacter [)] [nothing] [mi] ["85] [ex] ["01] +\definemathcharacter [/] [nothing] [mi] ["3D] [ex] ["0E] + +\stopmathcollection + +% \startmathcollection[lbr] +% +% \definemathcharacter [:] [punct] [tf] ["3A] % unbelievable +% \definemathcharacter [;] [punct] [tf] ["3B] % unbelievable +% +% \stopmathcollection + +\startmathcollection[lbr] + +\definemathsymbol [ldbrack] [open] [mi] ["82] [ex] ["82] +\definemathsymbol [rdbrack] [close] [mi] ["83] [ex] ["83] +\definemathsymbol [surfintop] [op] [ex] ["90] +\definemathsymbol [midintop] [op] [ex] ["92] +\definemathsymbol [midointop] [op] [ex] ["93] +\definemathsymbol [midsurfintop] [op] [ex] ["94] +\definemathsymbol [largeint] [op] [ex] ["5A] [ex] ["95] + +% \definemathcommand [surfint] [nolop] {\surfintop} +% \definemathcommand [midint] [nolop] {\midintop} +% \definemathcommand [midoint] [nolop] {\midointop} +% \definemathcommand [midsurfint] [nolop] {\midsurfintop} + +\definemathsymbol [surfint] [nolop] [ex] ["90] +\definemathsymbol [midint] [nolop] [ex] ["92] +\definemathsymbol [midoint] [nolop] [ex] ["93] +\definemathsymbol [midsurfint] [nolop] [ex] ["94] + +\definemathsymbol [dblint] [ord] [mi] ["88] +\definemathsymbol [trplint] [ord] [mi] ["89] +\definemathsymbol [contint] [ord] [mi] ["8A] +\definemathsymbol [surfint] [ord] [mi] ["8B] +\definemathsymbol [volint] [ord] [mi] ["8C] +\definemathsymbol [clwint] [ord] [mi] ["8D] +\definemathsymbol [cclwcint] [ord] [mi] ["8E] +\definemathsymbol [clwcint] [ord] [mi] ["8F] +\definemathsymbol [bowtie] [rel] [mi] ["F6] +\definemathsymbol [models] [rel] [sy] ["EE] +\definemathsymbol [doteq] [rel] [sy] ["C9] +\definemathsymbol [cong] [rel] [sy] ["9B] +\definemathsymbol [hbar] [ord] [mi] ["9D] +\definemathsymbol [neq] [rel] [ma] ["94] +\definemathsymbol [rightleftharpoons] [rel] [ma] ["7A] +\definemathsymbol [leftrightharpoons] [rel] [ma] ["79] +\definemathsymbol [hookleftarrow] [rel] [ma] ["3C] +\definemathsymbol [hookrightarrow] [rel] [ma] ["3E] +\definemathsymbol [mapsto] [rel] [ma] ["2C] + +\definemathcommand [longmapsto] {\mapstochar\longrightarrow} + +\stopmathcollection + +\startmathcollection[lbr] + +\definemathsymbol [Gamma] [alpha] [ucgreek] ["00] +\definemathsymbol [Delta] [alpha] [ucgreek] ["01] +\definemathsymbol [Theta] [alpha] [ucgreek] ["02] +\definemathsymbol [Lambda] [alpha] [ucgreek] ["03] +\definemathsymbol [Xi] [alpha] [ucgreek] ["04] +\definemathsymbol [Pi] [alpha] [ucgreek] ["05] +\definemathsymbol [Sigma] [alpha] [ucgreek] ["06] +\definemathsymbol [Upsilon] [alpha] [ucgreek] ["07] +\definemathsymbol [Phi] [alpha] [ucgreek] ["08] +\definemathsymbol [Psi] [alpha] [ucgreek] ["09] +\definemathsymbol [Omega] [alpha] [ucgreek] ["0A] + +\definemathsymbol [varGamma] [ord] [vargreek] ["00] +\definemathsymbol [varDelta] [ord] [vargreek] ["01] +\definemathsymbol [varTheta] [ord] [vargreek] ["02] +\definemathsymbol [varLambda] [ord] [vargreek] ["03] +\definemathsymbol [varXi] [ord] [vargreek] ["04] +\definemathsymbol [varPi] [ord] [vargreek] ["05] +\definemathsymbol [varSigma] [ord] [vargreek] ["06] +\definemathsymbol [varUpsilon] [ord] [vargreek] ["07] +\definemathsymbol [varPhi] [ord] [vargreek] ["08] +\definemathsymbol [varPsi] [ord] [vargreek] ["09] +\definemathsymbol [varOmega] [ord] [vargreek] ["0A] + +\stopmathcollection + +% we define the whole lot, although only a few differ (esp dot) + +% \startmathcollection[lbr] +% +% \definemathsymbol [acute] [accent] [tf] ["13] % mr -> tf +% \definemathsymbol [grave] [accent] [tf] ["12] % mr -> tf +% \definemathsymbol [ddot] [accent] [tf] ["7F] % mr -> tf +% \definemathsymbol [tilde] [accent] [tf] ["7E] % mr -> tf +% \definemathsymbol [bar] [accent] [tf] ["16] % mr -> tf +% \definemathsymbol [breve] [accent] [tf] ["15] % mr -> tf +% \definemathsymbol [check] [accent] [tf] ["14] % mr -> tf +% \definemathsymbol [hat] [accent] [tf] ["5E] % mr -> tf +% \definemathsymbol [vec] [accent] [mi] ["7E] % [ord] +% \definemathsymbol [dot] [accent] [tf] ["05] % mr -> tf, 5F -> 05 +% \definemathsymbol [widetilde] [accent] [ex] ["65] % [ord] +% \definemathsymbol [widehat] [accent] [ex] ["62] % [ord] +% +% \stopmathcollection + +\startmathcollection[lbr:texnansi] + \definemathsymbol [acute] [accent] [tf] ["13] + \definemathsymbol [grave] [accent] [tf] ["12] + \definemathsymbol [ddot] [accent] [tf] ["7F] + %definemathsymbol [ddot] [accent] [tf] ["A8] % both is OK + \definemathsymbol [tilde] [accent] [tf] ["7E] + %definemathsymbol [tilde] [accent] [tf] ["98] % both is OK + \definemathsymbol [bar] [accent] [tf] ["16] + \definemathsymbol [breve] [accent] [tf] ["15] + \definemathsymbol [check] [accent] [tf] ["14] + \definemathsymbol [hat] [accent] [tf] ["5E] + %definemathsymbol [hat] [accent] [tf] ["88] % both is OK + \definemathsymbol [dot] [accent] [tf] ["05] + % Why is mathring not defined?? + \definemathsymbol [mathring] [accent] [tf] ["17] +\stopmathcollection + +\startmathcollection[lbr:ec] + \definemathsymbol [acute] [accent] [tf] ["01] + \definemathsymbol [grave] [accent] [tf] ["00] + \definemathsymbol [ddot] [accent] [tf] ["04] + \definemathsymbol [tilde] [accent] [tf] ["03] + \definemathsymbol [bar] [accent] [tf] ["09] + \definemathsymbol [breve] [accent] [tf] ["08] + \definemathsymbol [check] [accent] [tf] ["07] + \definemathsymbol [hat] [accent] [tf] ["02] + \definemathsymbol [dot] [accent] [tf] ["0A] + % Why is mathring not defined?? + \definemathsymbol [mathring] [accent] [tf] ["06] +\stopmathcollection + +\def\LBRroot#1#2% + {\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\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}}}\,} + +\startrawmathcollection[lbr] + +\definemathcommand [mathstrut] {\vphantom{f}} +\definemathcommand [joinrel] {\mathrel{\mkern-4mu}} +\definemathcommand [r@@t] {\LBRroot} +\definemathcommand [matrix] {\LBRmatrix} + +\stoprawmathcollection + +\def\LBRbig {\@@dobig{8.20}} +\def\LBRBig {\@@dobig{10.80}} +\def\LBRbigg {\@@dobig{13.42}} +\def\LBRBigg {\@@dobig{16.03}} +\def\LBRbiggg{\@@dobig{17.72}} +\def\LBRBiggg{\@@dobig{21.25}} + +% \def\LBRbig {\@@dobig{0.820}} +% \def\LBRBig {\@@dobig{1.080}} +% \def\LBRbigg {\@@dobig{1.342}} +% \def\LBRBigg {\@@dobig{1.603}} +% \def\LBRbiggg{\@@dobig{1.772}} +% \def\LBRBiggg{\@@dobig{2.125}} + +\startrawmathcollection[lbr] + +\definemathcommand [big] {\LBRbig} +\definemathcommand [Big] {\LBRBig} +\definemathcommand [bigg] {\LBRbigg} +\definemathcommand [Bigg] {\LBRBigg} +\definemathcommand [biggg] {\LBRbiggg} +\definemathcommand [Biggg] {\LBRBiggg} + +\stoprawmathcollection + +\startrawmathcollection[lbr] + +\definemathcommand [bigggl] [open] {\biggg} +\definemathcommand [bigggr] [close] {\biggg} +\definemathcommand [Bigggl] [open] {\Biggg} +\definemathcommand [Bigggr] [close] {\Biggg} + +\stoprawmathcollection + +\protect \endinput diff --git a/tex/context/base/math-map.lua b/tex/context/base/math-map.lua new file mode 100644 index 000000000..2d34dc1c3 --- /dev/null +++ b/tex/context/base/math-map.lua @@ -0,0 +1,440 @@ +if not modules then modules = { } end modules ['math-map'] = { + version = 1.001, + comment = "companion to math-ini.mkiv", + 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 +local floor = math.floor + +local texattribute = tex.attribute + +local trace_greek = false trackers.register("math.greek", function(v) trace_greek = v end) + +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, + ucgreek = { + [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, + }, + lcgreek = { + [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, + }, + symbols = { + [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, + }, + ucgreek = { + [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, + }, + lcgreek = { + [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, + }, + symbols = { + [0x2202]=0x1D715, [0x2207]=0x1D6FB, + }, + }, + bf= { + digits = 0x1D7CE, + ucletters = 0x1D400, + lcletters = 0x1D41A, + ucgreek = { + [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, + }, + lcgreek = { + [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, + }, + symbols = { + [0x2202]=0x1D6DB, [0x2207]=0x1D6C1, + }, + }, + bi = { + ucletters = 0x1D468, + lcletters = 0x1D482, + ucgreek = { + [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, + }, + lcgreek = { + [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, + }, + symbols = { + [0x2202]=0x1D74F, [0x2207]=0x1D735, + }, + }, + }, + sansserif = { + tf = { + digits = 0x1D7E2, + ucletters = 0x1D5A0, + lcletters = 0x1D5BA, + }, + it = { + ucletters = 0x1D608, + lcletters = 0x1D622, + }, + bf = { + digits = 0x1D7EC, + ucletters = 0x1D5D4, + lcletters = 0x1D5EE, + ucgreek = { + [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, + }, + lcgreek = { + [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, + }, + symbols = { + [0x2202]=0x1D789, [0x2207]=0x1D76F, + }, + }, + bi = { + ucletters = 0x1D63C, + lcletters = 0x1D656, + ucgreek = { + [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, + }, + lcgreek = { + [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, + }, + symbols = { + [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, + lcgreek = { -- gamma pi + [0x03B3]=0x0213C, [0x03C0]=0x0213D, + }, + ucgreek = { -- Gamma pi + [0x0393]=0x0213E, [0x03A0]=0x0213F, + }, + symbols = { -- sum + [0x2211]=0x02140, + }, + }, + }, + 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 mathremap = { } + +for alphabet, styles in next, alphabets do + for style, data in next, styles do + -- let's keep the long names (for tracing) + local n = #mathremap + 1 + data.attribute = n + data.alphabet = alphabet + data.style = style + mathremap[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.lcgreek = alphabets.regular.tf.lcgreek +alphabets.sansserif.tf.ucgreek = alphabets.regular.tf.ucgreek +alphabets.sansserif.tf.digits = alphabets.regular.tf.digits +alphabets.sansserif.it.symbols = alphabets.regular.tf.symbols +alphabets.sansserif.it.lcgreek = alphabets.regular.tf.lcgreek +alphabets.sansserif.it.ucgreek = alphabets.regular.tf.ucgreek +alphabets.sansserif.bi.digits = alphabets.regular.bf.digits + +alphabets.monospaced.tf.symbols = alphabets.sansserif.tf.symbols +alphabets.monospaced.tf.lcgreek = alphabets.sansserif.tf.lcgreek +alphabets.monospaced.tf.ucgreek = alphabets.sansserif.tf.ucgreek +alphabets.monospaced.it = alphabets.sansserif.tf +alphabets.monospaced.bf = alphabets.sansserif.tf +alphabets.monospaced.bi = alphabets.sansserif.bf + +alphabets.blackboard.tf.symbols = table.merge(alphabets.regular.tf.symbols, alphabets.blackboard.tf.symbols) +alphabets.blackboard.tf.lcgreek = table.merge(alphabets.regular.tf.lcgreek, alphabets.blackboard.tf.lcgreek) +alphabets.blackboard.tf.ucgreek = table.merge(alphabets.regular.tf.ucgreek, alphabets.blackboard.tf.ucgreek) + +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.tf.lcgreek = alphabets.regular.tf.lcgreek +alphabets.fraktur.tf.ucgreek = alphabets.regular.tf.ucgreek +alphabets.fraktur.bf.digits = alphabets.regular.bf.digits +alphabets.fraktur.bf.symbols = alphabets.regular.bf.symbols +alphabets.fraktur.bf.lcgreek = alphabets.regular.bf.lcgreek +alphabets.fraktur.bf.ucgreek = alphabets.regular.bf.ucgreek +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.tf.lcgreek = alphabets.regular.tf.lcgreek +alphabets.script.tf.ucgreek = alphabets.regular.tf.ucgreek +alphabets.script.bf.digits = alphabets.regular.bf.digits +alphabets.script.bf.symbols = alphabets.regular.bf.symbols +alphabets.script.bf.lcgreek = alphabets.regular.bf.lcgreek +alphabets.script.bf.ucgreek = alphabets.regular.bf.ucgreek +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 = mathremap[attribute] + return r and r.style or "tf" +end + +function mathematics.to_a_name(attribute) + local r = mathremap[attribute] + return r and r.alphabet or "regular" +end + +-- of course we could do some div/mod trickery instead + +local mathalphabet = attributes.private("mathalphabet") + +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[mathalphabet] = data and data.attribute or texattribute[mathalphabet] +end + +function mathematics.sync_a_style(style) +--~ local r = mathremap[mathalphabet] + local r = mathremap[texattribute[mathalphabet]] + local alphabet = r and r.alphabet or "regular" + local data = alphabets[alphabet][style] + texattribute[mathalphabet] = data and data.attribute or texattribute[mathalphabet] +end + +function mathematics.sync_a_name(alphabet) +--~ local r = mathremap[mathalphabet] + local r = mathremap[texattribute[mathalphabet]] + local style = r and r.style or "tf" + local data = alphabets[alphabet][style] + texattribute[mathalphabet] = data and data.attribute or texattribute[mathalphabet] +end + +local issymbol = mathematics.alphabets.regular.tf.symbols +local islcgreek = mathematics.alphabets.regular.tf.lcgreek +local isucgreek = mathematics.alphabets.regular.tf.ucgreek + +local remapping = { + [1] = { what = "unchanged" }, -- upright + [2] = { what = "upright", it = "tf", bi = "bf" }, -- upright + [3] = { what = "italic", tf = "it", bf = "bi" }, -- italic +} + +function mathematics.remap_alphabets(char,mathalphabet,mathgreek) + if mathgreek > 0 then + local lc, uc = floor(mathgreek/10), mathgreek % 10 -- 2 == upright 3 == italic + if lc > 1 or uc > 1 then + local islc, isuc = islcgreek[char] and lc, isucgreek[char] and uc + if islc or isuc then + local r = mathremap[mathalphabet] -- what if 0 + local alphabet = r and r.alphabet or "regular" + local style = r and r.style or "tf" + if trace_greek then + logs.report("math","before: char: %05X, alphabet: %s %s, lcgreek: %s, ucgreek: %s",char,alphabet,style,remapping[lc].what,remapping[uc].what) + end + local s = remapping[islc or isuc][style] + if s then + local data = alphabets[alphabet][s] + mathalphabet, style = data and data.attribute or mathalphabet, s + end + if trace_greek then + logs.report("math","after : char: %05X, alphabet: %s %s, lcgreek: %s, ucgreek: %s",char,alphabet,style,remapping[lc].what,remapping[uc].what) + end + end + end + end + if mathalphabet > 0 then + local newchar + local offset = mathremap[mathalphabet] + if not offset then + -- nothing to remap + elseif 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 islcgreek[char] then + newchar = offset.lcgreek[char] + elseif isucgreek[char] then + newchar = offset.ucgreek[char] + 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-noa.lua b/tex/context/base/math-noa.lua new file mode 100644 index 000000000..02bbe0a62 --- /dev/null +++ b/tex/context/base/math-noa.lua @@ -0,0 +1,369 @@ +if not modules then modules = { } end modules ['math-noa'] = { + version = 1.001, + comment = "companion to math-ini.mkiv", + 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.identifiers + +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 + logs.report("math","%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 mathalphabet = attributes.private("mathalphabet") +local mathgreek = attributes.private("mathgreek") + +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 + +-- we can have a global famdata == fonts.famdata and chrdata == fonts.chrdata + +--~ This does not work out well, as there are no fallbacks. Ok, we could +--~ define a poor mans simplify mechanism. +--~ +--~ local function checked(pointer) +--~ local char = pointer.char +--~ local fam = pointer.fam +--~ local id = font_of_family(fam) +--~ local tfmdata = fontdata[id] +--~ local tc = tfmdata and tfmdata.characters +--~ if not tc[char] then +--~ local specials = characters.data[char].specials +--~ if specials and (specials[1] == "char" or specials[1] == "font") then +--~ newchar = specials[#specials] +--~ if trace_remapping then +--~ report_remap("fallback",id,char,newchar) +--~ end +--~ if trace_analyzing then +--~ fcs(pointer,"font:isol") +--~ end +--~ pointer.char = newchar +--~ return true +--~ end +--~ end +--~ end + +noads.processors.relocate[math_char] = function(pointer) + local g = has_attribute(pointer,mathgreek) or 0 + local a = has_attribute(pointer,mathalphabet) or 0 + if a > 0 or g > 0 then + if a > 0 then + set_attribute(pointer,mathgreek,0) + end + if g > 0 then + set_attribute(pointer,mathalphabet,0) + end + local char = pointer.char + local newchar = remap_alphabets(char,a,g) + if newchar then + local fam = pointer.fam + 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 true + elseif trace_remapping then + report_remap("char",id,char,newchar," fails") + end + else + -- return checked(pointer) + end + else + -- return checked(pointer) + 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,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 mathsize = attributes.private("mathsize") + +noads.processors.resize = { } + +noads.processors.resize[math_fence] = function(pointer) + if pointer.subtype == 1 then -- left + local a = has_attribute(pointer,mathsize) + if a and a > 0 then + set_attribute(pointer,mathsize,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,style,penalties) + process(head,noads.processors.resize) + return true +end + +-- respacing + +local mathpunctuation = attributes.private("mathpunctuation") + +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,mathpunctuation) + if a and a > 0 then + set_attribute(pointer,mathpunctuation,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,style,penalties) + noads.process(head,noads.processors.respace) + return true +end + +-- the normal builder + +function noads.mlist_to_hlist(head,style,penalties) + return mlist_to_hlist(head,style,penalties), true +end + +tasks.new ( + "math", + { + "before", + "normalizers", + "builders", + "after", + } +) + +local actions = tasks.actions("math",2) -- head, style, penalties + +local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming + +function nodes.processors.mlist_to_hlist(head,style,penalties) + starttiming(noads) + local head, done = actions(head,style,penalties) + stoptiming(noads) + return head, done +end + +callbacks.register('mlist_to_hlist',nodes.processors.mlist_to_hlist,"preprocessing math list") + +-- tracing + +statistics.register("math processing time", function() + return statistics.elapsedseconds(noads) +end) diff --git a/tex/context/base/math-pln.mkii b/tex/context/base/math-pln.mkii new file mode 100644 index 000000000..f2f3ff183 --- /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\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.mkiv b/tex/context/base/math-pln.mkiv new file mode 100644 index 000000000..ab584f10a --- /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} % beware, this overloades cambria native +\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 (weird code) + +% \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..6bc4bf4d5 --- /dev/null +++ b/tex/context/base/math-run.mkii @@ -0,0 +1,105 @@ +%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.mkii}\!!doneatrue\!!doneafalse + \readsysfile{\f!mathprefix ams.mkii}\!!donebtrue\!!donebfalse + \if!!donea + \if!!doneb + \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.mkii}\donothing\donothing + \readsysfile{\f!mathprefix ams.mkii}\donothing\donothing + \stopcolumns + \else + \par \tttf no chars in \f!mathprefix ams\par + \fi + \else + \par \tttf no chars in \f!mathprefix tex\par + \fi + \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..eb1db4714 --- /dev/null +++ b/tex/context/base/math-scr.mkiv @@ -0,0 +1,135 @@ +%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}. +%D +%D The grid snapping has been removed. + +\global\let\normalsuper=^ +\global\let\normalsuber=_ + +\ifdefined\supersubmode \else \newcount\supersubmode \fi +\ifdefined\newevery \else \everysupersub \EverySuperSub \fi + +\appendtoks \advance\supersubmode \plusone \to \everysupersub + +\setuptextformulas + [\c!size=\v!normal] + +\def\normalsupsub#1#2% + {^{\the\everysupersub#1}_{\the\everysupersub#2}} + +\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}} + +%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.mkii b/tex/context/base/math-tex.mkii new file mode 100644 index 000000000..8f34a190e --- /dev/null +++ b/tex/context/base/math-tex.mkii @@ -0,0 +1,720 @@ +%D \module +%D [ file=math-tex, +%D version=2001.04.12, +%D subtitle=Plain Specials, +%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. + +% beware: in mkiv we will do it differently + +\unprotect + +\mathcode`\ ="8000 \mathcode`\_="8000 \mathcode`\'="8000 + +\definefamilysynonym [default] [calligraphic] [sy] +\definefamilysynonym [default] [oldstyle] [mi] +\definefamilysynonym [default] [blackboard] [mr] +\definefamilysynonym [default] [gothic] [mr] +\definefamilysynonym [default] [fraktur] [mr] + +\definefamilysynonym [default] [lcgreek] [mi] +\definefamilysynonym [default] [ucgreek] [mr] +\definefamilysynonym [default] [vargreek] [mi] + + +%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). + +\chardef\intlimitcode\zerocount % 0 nolimits 1 displaylimits 2 limits + +\def\intlimits + {\ifcase\intlimitcode \nolimits \or \displaylimits \or \limits \fi} + +\def\setupmathematics + {\dosingleargument\dosetupmathematics} + +\def\dosetupmathematics[#1]% + {\getparameters[\??mo][#1] + \processaction[\@@mointegral] + [ nolimits=>\chardef\intlimitcode\zerocount, + displaylimits=>\chardef\intlimitcode\plusone, + limits=>\chardef\intlimitcode\plustwo]} + +%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 + +\startmathcollection [default] + +\definemathsymbol [alpha] [nothing] [lcgreek] ["0B] +\definemathsymbol [beta] [nothing] [lcgreek] ["0C] +\definemathsymbol [gamma] [nothing] [lcgreek] ["0D] +\definemathsymbol [delta] [nothing] [lcgreek] ["0E] +\definemathsymbol [epsilon] [nothing] [lcgreek] ["0F] +\definemathsymbol [zeta] [nothing] [lcgreek] ["10] +\definemathsymbol [eta] [nothing] [lcgreek] ["11] +\definemathsymbol [theta] [nothing] [lcgreek] ["12] +\definemathsymbol [iota] [nothing] [lcgreek] ["13] +\definemathsymbol [kappa] [nothing] [lcgreek] ["14] +\definemathsymbol [lambda] [nothing] [lcgreek] ["15] +\definemathsymbol [mu] [nothing] [lcgreek] ["16] +\definemathsymbol [nu] [nothing] [lcgreek] ["17] +\definemathsymbol [xi] [nothing] [lcgreek] ["18] +\definemathsymbol [omicron] [nothing] [lcgreek] ["6F] +\definemathsymbol [pi] [nothing] [lcgreek] ["19] +\definemathsymbol [rho] [nothing] [lcgreek] ["1A] +\definemathsymbol [sigma] [nothing] [lcgreek] ["1B] +\definemathsymbol [tau] [nothing] [lcgreek] ["1C] +\definemathsymbol [upsilon] [nothing] [lcgreek] ["1D] +\definemathsymbol [phi] [nothing] [lcgreek] ["1E] +\definemathsymbol [chi] [nothing] [lcgreek] ["1F] +\definemathsymbol [psi] [nothing] [lcgreek] ["20] +\definemathsymbol [omega] [nothing] [lcgreek] ["21] + +\stopmathcollection + +\startmathcollection [default] + +\definemathsymbol [varepsilon] [nothing] [vargreek] ["22] +\definemathsymbol [vartheta] [nothing] [vargreek] ["23] +\definemathsymbol [varpi] [nothing] [vargreek] ["24] +\definemathsymbol [varrho] [nothing] [vargreek] ["25] +\definemathsymbol [varsigma] [nothing] [vargreek] ["26] +\definemathsymbol [varphi] [nothing] [vargreek] ["27] + +\stopmathcollection + +\startmathcollection [default] + +\definemathsymbol [Alpha] [alpha] [ucgreek] ["41] % A +\definemathsymbol [Beta] [alpha] [ucgreek] ["42] % B +\definemathsymbol [Gamma] [alpha] [ucgreek] ["00] +\definemathsymbol [Delta] [alpha] [ucgreek] ["01] +\definemathsymbol [Epsilon] [alpha] [ucgreek] ["45] % E +\definemathsymbol [Zeta] [alpha] [ucgreek] ["5A] % Z +\definemathsymbol [Eta] [alpha] [ucgreek] ["48] % H +\definemathsymbol [Theta] [alpha] [ucgreek] ["02] +\definemathsymbol [Iota] [alpha] [ucgreek] ["49] % I +\definemathsymbol [Kappa] [alpha] [ucgreek] ["4B] % K +\definemathsymbol [Lambda] [alpha] [ucgreek] ["03] +\definemathsymbol [Mu] [alpha] [ucgreek] ["4D] % M +\definemathsymbol [Nu] [alpha] [ucgreek] ["4E] % N +\definemathsymbol [Xi] [alpha] [ucgreek] ["04] +\definemathsymbol [Omicron] [alpha] [ucgreek] ["4F] % O +\definemathsymbol [Pi] [alpha] [ucgreek] ["05] +\definemathsymbol [Rho] [alpha] [ucgreek] ["52] % R +\definemathsymbol [Sigma] [alpha] [ucgreek] ["06] +\definemathsymbol [Tau] [alpha] [ucgreek] ["54] % T +\definemathsymbol [Upsilon] [alpha] [ucgreek] ["07] +\definemathsymbol [Phi] [alpha] [ucgreek] ["08] +\definemathsymbol [Chi] [alpha] [ucgreek] ["58] % X +\definemathsymbol [Psi] [alpha] [ucgreek] ["09] +\definemathsymbol [Omega] [alpha] [ucgreek] ["0A] + +\stopmathcollection + +% The \mfunction macro is an alternative for \hbox with a +% controlable font switch. + +\startmathcollection[default] + +\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}} + +\stopmathcollection + +\let\normalmatharg\arg % todo: maybe automatically + +\startmathcollection[default] + +\definemathcommand [integers] {\mfunction{Z}} +\definemathcommand [reals] {\mfunction{R}} +\definemathcommand [rationals] {\mfunction{Q}} +\definemathcommand [naturalnumbers] {\mfunction{N}} +\definemathcommand [complexes] {\mfunction{C}} +\definemathcommand [primes] {\mfunction{P}} + +\stopmathcollection + +\startmathcollection[default] + +\definemathcharacter [!] [close] [mr] ["21] +\definemathcharacter [(] [open] [mr] ["28] +\definemathcharacter [)] [close] [mr] ["29] +\definemathcharacter [*] [bin] [sy] ["03] +\definemathcharacter [+] [bin] [mr] ["2B] +\definemathcharacter [,] [punct] [mi] ["3B] +\definemathcharacter [-] [bin] [sy] ["00] +\definemathcharacter [.] [ord] [mi] ["3A] +\definemathcharacter [/] [ord] [mi] ["3D] +\definemathcharacter [:] [rel] [mr] ["3A] +\definemathcharacter [;] [punct] [mr] ["3B] +\definemathcharacter [<] [rel] [mi] ["3C] +\definemathcharacter [=] [rel] [mr] ["3D] +\definemathcharacter [>] [rel] [mi] ["3E] +\definemathcharacter [?] [close] [mr] ["3F] +\definemathcharacter [91] [open] [mr] ["5B] % [ +\definemathcharacter [92] [ord] [sy] ["6E] % \ +\definemathcharacter [93] [close] [mr] ["5D] % ] +\definemathcharacter [123] [open] [sy] ["66] % { +\definemathcharacter [124] [ord] [sy] ["6A] % | +\definemathcharacter [125] [close] [sy] ["67] % } + +\stopmathcollection + +\startmathcollection[default] + +\definemathcharacter [(] [nothing] [mr] ["28] [ex] ["00] +\definemathcharacter [)] [nothing] [mr] ["29] [ex] ["01] +\definemathcharacter [91] [nothing] [mr] ["5B] [ex] ["02] % [ +\definemathcharacter [93] [nothing] [mr] ["5D] [ex] ["03] % ] +\definemathcharacter [<] [nothing] [sy] ["68] [ex] ["0A] +\definemathcharacter [>] [nothing] [sy] ["69] [ex] ["0B] +\definemathcharacter [/] [nothing] [mr] ["2F] [ex] ["0E] +\definemathcharacter [124] [nothing] [sy] ["6A] [ex] ["0C] % | +\definemathcharacter [92] [nothing] [sy] ["6E] [ex] ["0F] % \ + +\stopmathcollection + +\def\PLAINangle + {{\vbox{\ialign{$\mathsurround\zeropoint\scriptstyle##$\crcr + \not\mathrel{\mkern14mu}\crcr + \noalign{\nointerlineskip} + \mkern2.5mu\leaders\hrule height.34pt\hfill\mkern2.5mu\crcr}}}} + +\startmathcollection[default] + +\definemathsymbol [aleph] [nothing] [sy] ["40] +\definemathsymbol [imath] [nothing] [mi] ["7B] +\definemathsymbol [jmath] [nothing] [mi] ["7C] +\definemathsymbol [ell] [nothing] [mi] ["60] +\definemathsymbol [wp] [nothing] [mi] ["7D] +\definemathsymbol [Re] [nothing] [sy] ["3C] +\definemathsymbol [Im] [nothing] [sy] ["3D] +\definemathsymbol [partial] [nothing] [mi] ["40] +\definemathsymbol [infty] [nothing] [sy] ["31] +\definemathsymbol [prime] [nothing] [sy] ["30] +\definemathsymbol [emptyset] [nothing] [sy] ["3B] +\definemathsymbol [nabla] [nothing] [sy] ["72] +\definemathsymbol [top] [nothing] [sy] ["3E] +\definemathsymbol [bot] [nothing] [sy] ["3F] + +\definemathcommand [hbar] {{\mathchar'26\mkern-9muh}} +\definemathcommand [surd] {{\mathchar"1270}} % ? +\definemathcommand [angle] {\PLAINangle} + +\stopmathcollection + +\startmathcollection[default] + +\definemathsymbol [triangle] [ord] [sy] ["34] +\definemathsymbol [forall] [ord] [sy] ["38] +\definemathsymbol [exists] [ord] [sy] ["39] +\definemathsymbol [neg] [ord] [sy] ["3A] +\definemathsymbol [flat] [ord] [mi] ["5B] +\definemathsymbol [natural] [ord] [mi] ["5C] +\definemathsymbol [sharp] [ord] [mi] ["5D] +\definemathsymbol [clubsuit] [ord] [sy] ["7C] +\definemathsymbol [diamondsuit] [ord] [sy] ["7D] +\definemathsymbol [heartsuit] [ord] [sy] ["7E] +\definemathsymbol [spadesuit] [ord] [sy] ["7F] + +\stopmathcollection + +\startmathcollection[default] + +\definemathcommand [square] {\hbox{\hsmash{$\sqcup$}$\sqcap$}} + +\stopmathcollection + +\startmathcollection[default] + +\definemathsymbol [coprod] [op] [ex] ["60] +\definemathsymbol [bigvee] [op] [ex] ["57] +\definemathsymbol [bigwedge] [op] [ex] ["56] +\definemathsymbol [biguplus] [op] [ex] ["55] +\definemathsymbol [bigcap] [op] [ex] ["54] +\definemathsymbol [bigcup] [op] [ex] ["53] +\definemathsymbol [intop] [op] [ex] ["52] +\definemathsymbol [prod] [op] [ex] ["51] +\definemathsymbol [sum] [op] [ex] ["50] +\definemathsymbol [bigotimes] [op] [ex] ["4E] +\definemathsymbol [bigoplus] [op] [ex] ["4C] +\definemathsymbol [bigodot] [op] [ex] ["4A] +\definemathsymbol [ointop] [op] [ex] ["48] +\definemathsymbol [bigsqcup] [op] [ex] ["46] +\definemathsymbol [smallint] [op] [sy] ["73] + +\stopmathcollection + +\startmathcollection[default] + +\definemathsymbol [triangleleft] [bin] [mi] ["2F] +\definemathsymbol [triangleright] [bin] [mi] ["2E] +\definemathsymbol [bigtriangleup] [bin] [sy] ["34] +\definemathsymbol [bigtriangledown] [bin] [sy] ["35] +\definemathsymbol [wedge] [bin] [sy] ["5E] +\definemathsymbol [vee] [bin] [sy] ["5F] +\definemathsymbol [cap] [bin] [sy] ["5C] +\definemathsymbol [cup] [bin] [sy] ["5B] +\definemathsymbol [ddagger] [bin] [sy] ["7A] +\definemathsymbol [dagger] [bin] [sy] ["79] +\definemathsymbol [sqcap] [bin] [sy] ["75] +\definemathsymbol [sqcup] [bin] [sy] ["74] +\definemathsymbol [uplus] [bin] [sy] ["5D] +\definemathsymbol [amalg] [bin] [sy] ["71] +\definemathsymbol [diamond] [bin] [sy] ["05] +\definemathsymbol [bullet] [bin] [sy] ["0F] +\definemathsymbol [wr] [bin] [sy] ["6F] +\definemathsymbol [div] [bin] [sy] ["04] +\definemathsymbol [odot] [bin] [sy] ["0C] +\definemathsymbol [oslash] [bin] [sy] ["0B] +\definemathsymbol [otimes] [bin] [sy] ["0A] +\definemathsymbol [ominus] [bin] [sy] ["09] +\definemathsymbol [oplus] [bin] [sy] ["08] +\definemathsymbol [mp] [bin] [sy] ["07] +\definemathsymbol [pm] [bin] [sy] ["06] +\definemathsymbol [circ] [bin] [sy] ["0E] +\definemathsymbol [bigcirc] [bin] [sy] ["0D] +\definemathsymbol [setminus] [bin] [sy] ["6E] +\definemathsymbol [cdot] [bin] [sy] ["01] +\definemathsymbol [ast] [bin] [sy] ["03] +\definemathsymbol [times] [bin] [sy] ["02] +\definemathsymbol [star] [bin] [mi] ["3F] + +\stopmathcollection + +\startmathcollection[default] + +\definemathsymbol [propto] [rel] [sy] ["2F] +\definemathsymbol [sqsubseteq] [rel] [sy] ["76] +\definemathsymbol [sqsupseteq] [rel] [sy] ["77] +\definemathsymbol [parallel] [rel] [sy] ["6B] +\definemathsymbol [mid] [rel] [sy] ["6A] +\definemathsymbol [dashv] [rel] [sy] ["61] +\definemathsymbol [vdash] [rel] [sy] ["60] +\definemathsymbol [nearrow] [rel] [sy] ["25] +\definemathsymbol [searrow] [rel] [sy] ["26] +\definemathsymbol [nwarrow] [rel] [sy] ["2D] +\definemathsymbol [swarrow] [rel] [sy] ["2E] +\definemathsymbol [Leftrightarrow] [rel] [sy] ["2C] +\definemathsymbol [Leftarrow] [rel] [sy] ["28] +\definemathsymbol [Rightarrow] [rel] [sy] ["29] + +\stopmathcollection + +\startmathcollection[default] + +\definemathcommand [lnot] {\neg} +\definemathcommand [int] {\intop \intlimits} +\definemathcommand [oint] {\ointop\intlimits} +\definemathcommand [land] {\wedge} +\definemathcommand [lor] {\vee} +\definemathcommand [neq] {\not=} +\definemathcommand [ne] {\neq} +\definemathcommand [le] {\leq} +\definemathcommand [ge] {\geq} +\definemathcommand [eq] {=} +\definemathcommand [gt] {>} +\definemathcommand [lt] {<} +\definemathcommand [gets] {\leftarrow} +\definemathcommand [owns] {\ni} +\definemathcommand [to] {\rightarrow} +\definemathcommand [mapsto] {\mapstochar\rightarrow} + +\stopmathcollection + +\startmathcollection[default] + +\definemathsymbol [leq] [rel] [sy] ["14] +\definemathsymbol [geq] [rel] [sy] ["15] +\definemathsymbol [succ] [rel] [sy] ["1F] +\definemathsymbol [prec] [rel] [sy] ["1E] +\definemathsymbol [approx] [rel] [sy] ["19] +\definemathsymbol [succeq] [rel] [sy] ["17] +\definemathsymbol [preceq] [rel] [sy] ["16] +\definemathsymbol [supset] [rel] [sy] ["1B] +\definemathsymbol [subset] [rel] [sy] ["1A] +\definemathsymbol [supseteq] [rel] [sy] ["13] +\definemathsymbol [subseteq] [rel] [sy] ["12] +\definemathsymbol [in] [rel] [sy] ["32] +\definemathsymbol [ni] [rel] [sy] ["33] +\definemathsymbol [gg] [rel] [sy] ["1D] +\definemathsymbol [ll] [rel] [sy] ["1C] +\definemathsymbol [not] [rel] [sy] ["36] +\definemathsymbol [leftrightarrow] [rel] [sy] ["24] +\definemathsymbol [leftarrow] [rel] [sy] ["20] +\definemathsymbol [rightarrow] [rel] [sy] ["21] +\definemathsymbol [mapstochar] [rel] [sy] ["37] +\definemathsymbol [sim] [rel] [sy] ["18] +\definemathsymbol [simeq] [rel] [sy] ["27] +\definemathsymbol [perp] [rel] [sy] ["3F] +\definemathsymbol [equiv] [rel] [sy] ["11] +\definemathsymbol [asymp] [rel] [sy] ["10] +\definemathsymbol [smile] [rel] [mi] ["5E] +\definemathsymbol [frown] [rel] [mi] ["5F] +\definemathsymbol [leftharpoonup] [rel] [mi] ["28] +\definemathsymbol [leftharpoondown] [rel] [mi] ["29] +\definemathsymbol [rightharpoonup] [rel] [mi] ["2A] +\definemathsymbol [rightharpoondown] [rel] [mi] ["2B] +\definemathsymbol [lhook] [rel] [mi] ["2C] +\definemathsymbol [rhook] [rel] [mi] ["2D] + +\stopmathcollection + +\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\hbox{.}\mkern2mu\raise.1\bodyfontsize\hbox{.}\mkern1mu} + +\startmathcollection[default] + +\definemathcommand [hookrightarrow] {\lhook\joinrel\rightarrow} +\definemathcommand [hookleftarrow] {\leftarrow\joinrel\rhook} +\definemathcommand [bowtie] {\mathrel\triangleright\joinrel\mathrel\triangleleft} +\definemathcommand [models] {\mathrel|\joinrel=} +\definemathcommand [iff] {\;\Longleftrightarrow\;} + +\definemathsymbol [ldotp] [punct] [mi] ["3A] +\definemathsymbol [cdotp] [punct] [sy] ["01] +\definemathsymbol [colon] [punct] [mr] ["3A] + +\definemathcommand [ldots] [inner] {\PLAINldots} +\definemathcommand [cdots] [inner] {\PLAINcdots} +\definemathcommand [vdots] [nothing] {\PLAINvdots} +\definemathcommand [ddots] [inner] {\PLAINddots} + +\stopmathcollection + +\startmathcollection[default] + +\definemathsymbol [acute] [accent] [mr] ["13] +\definemathsymbol [grave] [accent] [mr] ["12] +\definemathsymbol [ddot] [accent] [mr] ["7F] +\definemathsymbol [tilde] [accent] [mr] ["7E] +\definemathsymbol [mathring] [accent] [mr] ["17] +\definemathsymbol [bar] [accent] [mr] ["16] +\definemathsymbol [breve] [accent] [mr] ["15] +\definemathsymbol [check] [accent] [mr] ["14] +\definemathsymbol [hat] [accent] [mr] ["5E] +\definemathsymbol [vec] [accent] [mi] ["7E] % [ord] +\definemathsymbol [dot] [accent] [mr] ["5F] +\definemathsymbol [widetilde] [accent] [ex] ["65] % [ord] +\definemathsymbol [widehat] [accent] [ex] ["62] % [ord] + +\stopmathcollection + +\startmathcollection[default] + +\definemathsymbol [lmoustache] [open] [ex] ["7A] [ex] ["40] +\definemathsymbol [rmoustache] [close] [ex] ["7B] [ex] ["41] +\definemathsymbol [lgroup] [open] [mr] ["28] [ex] ["3A] % ? +\definemathsymbol [rgroup] [close] [mr] ["29] [ex] ["3B] % ? +\definemathsymbol [arrowvert] [nothing] [sy] ["6A] [ex] ["3C] +\definemathsymbol [Arrowvert] [nothing] [sy] ["6B] [ex] ["3D] +\definemathsymbol [bracevert] [nothing] [ex] ["3E] % ? +\definemathsymbol [Vert] [nothing] [sy] ["6B] [ex] ["0D] +\definemathsymbol [vert] [nothing] [sy] ["6A] [ex] ["0C] +\definemathsymbol [uparrow] [rel] [sy] ["22] [ex] ["78] +\definemathsymbol [downarrow] [rel] [sy] ["23] [ex] ["79] +\definemathsymbol [updownarrow] [rel] [sy] ["6C] [ex] ["3F] +\definemathsymbol [Uparrow] [rel] [sy] ["2A] [ex] ["7E] +\definemathsymbol [Downarrow] [rel] [sy] ["2B] [ex] ["7F] +\definemathsymbol [Updownarrow] [rel] [sy] ["6D] [ex] ["77] +\definemathsymbol [backslash] [nothing] [sy] ["6E] [ex] ["0F] +\definemathsymbol [langle] [open] [sy] ["68] [ex] ["0A] +\definemathsymbol [rangle] [close] [sy] ["69] [ex] ["0B] +\definemathsymbol [lbrace] [open] [sy] ["66] [ex] ["08] +\definemathsymbol [rbrace] [close] [sy] ["67] [ex] ["09] +\definemathsymbol [lceil] [open] [sy] ["64] [ex] ["06] +\definemathsymbol [rceil] [close] [sy] ["65] [ex] ["07] +\definemathsymbol [lfloor] [open] [sy] ["62] [ex] ["04] +\definemathsymbol [rfloor] [close] [sy] ["63] [ex] ["05] + +\definemathsymbol [sqrt] [radical] [sy] ["70] [ex] ["70] + +\stopmathcollection + +%D By request: + +\startmathcollection[default] + +\definemathsymbol [lvert] [open] [sy] ["6A] [ex] ["0C] +\definemathsymbol [rvert] [close] [sy] ["6A] [ex] ["0C] + +\definemathsymbol [lVert] [open] [sy] ["6B] [ex] ["0D] +\definemathsymbol [rVert] [close] [sy] ["6B] [ex] ["0D] + +\stopmathcollection + +%D For brooks: +%D +%D \starttyping +%D $\sqrt[3]{10}$ +%D \stoptyping + +\ifx\normalsqrt\undefined \let\normalsqrt\sqrt \fi % just set to: \dohandlemathtoken {sqrt} + +\def\notsosqrt[#1]{\root#1\of} + +\unexpanded\def\sqrt{\doifnextoptionalelse\notsosqrt\normalsqrt} + +\def\PLAINbig {\@@dobig{0.85}} +\def\PLAINBig {\@@dobig{1.15}} +\def\PLAINbigg{\@@dobig{1.45}} +\def\PLAINBigg{\@@dobig{1.75}} + +\startrawmathcollection [default] + +\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} + +\definemathcommand [big] {\PLAINbig} +\definemathcommand [Big] {\PLAINBig} +\definemathcommand [bigg] {\PLAINbigg} +\definemathcommand [Bigg] {\PLAINBigg} + +\stoprawmathcollection + +\startmathcollection[default] + +\definemathsymbol [dag] [box] [sy] ["79] +\definemathsymbol [ddag] [box] [sy] ["7A] +\definemathsymbol [S] [box] [sy] ["78] +\definemathsymbol [P] [box] [sy] ["7B] +\definemathsymbol [Orb] [box] [sy] ["0D] + +\stopmathcollection + +\def\PLAINroot#1#2% + {\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\mathsurround\zeropoint + \ialign{\hfil$##$\hfil&&\quad\hfil$##$\hfil\crcr + \mathstrut\crcr\noalign{\kern-\baselineskip} + #1\crcr\mathstrut\crcr\noalign{\kern-\baselineskip}}}\,} + +\startrawmathcollection[default] + +\definemathcommand [mathstrut] {\vphantom{(}} +\definemathcommand [joinrel] {\mathrel{\mkern-3mu}} +\definemathcommand [r@@t] {\PLAINroot} +\definemathcommand [matrix] {\PLAINmatrix} + +\definemathcommand [over] {\normalover} % hack, to do + +\stoprawmathcollection + +\def\{{\lbrace} +\def\}{\rbrace} + +%def\bbd{\fam\purefamily{blackboard}} +%def\cal{\fam\purefamily{calfamily}} + +\def\mit{\fam\purefamily{mitfamily}} + +\def\Bbb{\blackboard} % conforming amstex + +\startmathcollection[default] + + \definemathsymbol [mathperiod] [ord] [mi] ["3A] + \definemathsymbol [textperiod] [punct] [mi] ["3A] + + \definemathsymbol [mathcomma] [ord] [mi] ["3B] + \definemathsymbol [textcomma] [punct] [mi] ["3B] + +\stopmathcollection + +\definemathpunctuation . mathperiod textperiod +\definemathpunctuation , mathcomma textcomma + +%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 More integrals (AM): + +\def\dointkern{\mkern-6mu\mathchoice{\mkern-3mu}{}{}{}} + +\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\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} + +\setupmathematics + [integral=nolimits] + +\protect \endinput diff --git a/tex/context/base/math-tim.mkii b/tex/context/base/math-tim.mkii new file mode 100644 index 000000000..3b9aea103 --- /dev/null +++ b/tex/context/base/math-tim.mkii @@ -0,0 +1,371 @@ +%D \module +%D [ file=math-tim, +%D version=2001.04.12, +%D title=\CONTEXT\ Math Macros, +%D subtitle=Mathtime Specials, +%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. + +\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. + +% version 0 : Michael Spivak +% version 1 : Taco Hoekwater +% version 2 : Hans Hagen +% version 3 : etc etc etc + +\unprotect + +%D We use the predefined spare families \type {\mcfam} and +%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? + +% \font\tenmd =mtgu at 10pt +% \font\sevenmd=mtgu at 7.6pt +% \font\fivemd =mtgu at 6pt +% \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 + +% \addtocommalist{gk}\familylist +% \addtocommalist{gb}\familylist +% +% \defineinterfaceconstant {ca} {ca} % boohoo! +% \defineinterfaceconstant {gk} {gk} % boohoo! +% \defineinterfaceconstant {gb} {gb} % boohoo! + +% \definealternativestyle[script] [\ca][\ca] +% \definealternativestyle[greek] [\gk][\gk] +% \definealternativestyle[boldgreek][\gb][\gb] + +% \definebodyfont +% [5pt,6pt,7pt,8pt,9pt,10pt,11pt,12pt,14.4pt] [rm] +% [ca=mtms sa 1, +% 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 +%D \starttabulate[|Bl|c|c|c|c|c|c|c|c|c|c|] +%D \NC Computer Modern\NC +%D 5 \NC6 \NC7 \NC8 \NC9 \NC10 \NC11 \NC12 \NC14 \NC18\NC\NR +%D \NC Math Times \NC +%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 moved code + +%D The next lines set up coding dependant versions of math +%D accents (for \type {texnansi} of course). These are needed +%D in commands like \type {\bf} and \type {\it} (which use the +%D text font encoding) a opposed to \type {_no spec_} and +%D \type {mi} that use the math font encoding. This stuff +%D should be made more general! + +% \daghex, \ddaghex and \dothex were wrong in my version of mtmacs + +\def\daghex {86} % to do +\def\ddaghex {87} +\def\Shex {A7} +\def\Phex {B6} +\def\barhex {16} +\def\gravehex{12} +\def\acutehex{13} +\def\checkhex{14} +\def\brevehex{15} +\def\hathex {5E} +\def\dothex {05} +\def\tildehex{7E} +\def\ddothex {7F} + +%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 \type {mtmacs.tex}, which banner said: +%D +%D \starttyping +%D MTMACS.TEX VERSION 1.1.1 (1996 Dec 8) +%D COPYRIGHT (C) 1992, 1993, 1996 BY THE TEXPLORATORS CORPORATION +%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. + +\mathchardef\Gamma = "0130 +\mathchardef\Delta = "0131 +\mathchardef\Theta = "0132 +\mathchardef\Lambda = "0133 +\mathchardef\Xi = "0134 +\mathchardef\Pi = "0135 +\mathchardef\Sigma = "0136 +\mathchardef\Upsilon = "0137 +\mathchardef\Phi = "0138 +\mathchardef\Psi = "0139 +\mathchardef\Omega = "017F +\mathchardef\varGamma = "0100 +\mathchardef\varDelta = "0101 +\mathchardef\varTheta = "0102 +\mathchardef\varLambda = "0103 +\mathchardef\varXi = "0104 +\mathchardef\varPi = "0105 +\mathchardef\varSigma = "0106 +\mathchardef\varUpsilon = "0107 +\mathchardef\varPhi = "0108 +\mathchardef\varPsi = "0109 +\mathchardef\varOmega = "010A +\mathchardef\varkappa = "017E + +\mathchardef\ldotp = "613A + +\mathchardef\triangleleft = "2247 +\mathchardef\triangleright = "2246 +\mathchardef\comp = "2242 + +\mathchardef\Relbar = "3248 +\mathchardef\dagger = "20\daghex % to do +\mathchardef\ddagger = "20\ddaghex % to do +\mathchardef\dotacc = "0250 + +\mathcode`\( = "412E +\mathcode`\) = "512F +\mathcode`\. = "013A +\mathcode`\, = "613B +\mathcode`\+ = "2243 +\mathcode`\= = "3244 +\mathcode`\; = "6249 + +\delcode `\( = "12E300 +\delcode `\) = "12F301 + +\let\mit=\undefined % to do + +\def\vec{\mathaccent"0245 } +\def\t#1{{\edef\next{\the\font}\the\textfont2\accent"41\next#1}} + +% fam equals -1 unless the user has said something +% like \rm (cf. the texbook page 290) + +\def\ifdefaultfamelse#1#2% + {\ifnum\fam=\minusone\mathaccent#1\else\mathaccent#2\fi} + +\let\noaccents@\relax + +\def\grave {\ifdefaultfamelse{"024A}{"70\gravehex}} +\def\acute {\ifdefaultfamelse{"024B}{"70\acutehex}} +\def\check {\ifdefaultfamelse{"024C}{"70\checkhex}} +\def\breve {\ifdefaultfamelse{"024D}{"70\brevehex}} +\def\bar {\ifdefaultfamelse{"024E}{"70\barhex }} +\def\hat {\ifdefaultfamelse{"024F}{"70\hathex }} +\def\dot {\ifdefaultfamelse{"0250}{"70\dothex }} +\def\tilde {\ifdefaultfamelse{"0251}{"70\tildehex}} +\def\ddot {\ifdefaultfamelse{"0252}{"70\ddothex }} + +\def\widebar{\mathaccent"0253 } + +\def\mathhexbox@#1#2#3% + {\relax + \ifmmode + \mathpalette{}{\mathsurround\zeropoint\rm\mathchar"#1#2#3}% + \else + \leavevmode + \hbox{$\mathsurround\zeropoint\rm\mathchar"#1#2#3$}% + \fi} + +\def\dag {\edef\next@{0\daghex }\expandafter\mathhexbox@\next@} +\def\ddag{\edef\next@{0\ddaghex}\expandafter\mathhexbox@\next@} + +\def\S{\edef\next@{0\Shex}\expandafter\mathhexbox@\next@} +\def\P{\edef\next@{0\Phex}\expandafter\mathhexbox@\next@} + +\def\vdots% + {\vbox + {\baselineskip4\points + \lineskiplimit\zeropoint + \kern6\points\hbox{$\mathsurround\zeropoint.$}\hbox{$\mathsurround\zeropoint.$}\hbox{$\mathsurround\zeropoint.$}}} + +\def\ddots% + {\mathinner + {\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 + {\hbox{\lower.07em \hbox{$\mathchar"\barhex$}}} + {\hbox{\lower.07em \hbox{$\mathchar"\barhex$}}} + {\hbox{\lower.049em\hbox{$\scriptstyle\mathchar"\barhex$}}} + {\hbox{\lower.035em\hbox{$\scriptscriptstyle\mathchar"\barhex$}}}% + \mkern-6.3muh}} + +\def\angle% + {{\vbox{\ialign{$\mathsurround\zeropoint\scriptstyle##$\crcr + \not\mathrel{\mkern14mu}\crcr + \noalign{\nointerlineskip} + \mkern2.5mu\leaders\hrule height.48\points\hfill\mkern2.5mu\crcr}}}} + +\newdimen\amstexex + +\amstexex = .2326ex + +\def\varinjlim% + {\mathop{\vtop{\ialign{##\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\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\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. + +\def\domultidot#1#2% + {\setbox0\hbox{$#1#2$}% + \setbox2\hbox{$#1\infty$}% + \dimen0\ht2 + \ifdim\ht0<\dimen0 \dimen0\ht0 \fi + \setbox2\hbox{$#1#2\mathchar"012D$}% + \dimen2\wd2 + \advance\dimen2-\wd0 + \setbox0\hbox{$#1\rhook$}% + \advance\dimen2-\wd0 + \vbox + {\offinterlineskip + \ialign{\hfil$#1##$\hfil\cr + \kern\dimen2\dotacc\mkern-2.5mu\dotacc\mkern-2.5mu\dotacc\thirddot\cr + \noalign{\vskip-\dimen0}% + #2\cr}}} + +\def\dddot% + {\def\thirddot{}% + \mathpalette\domultidot} + +\def\ddddot% + {\def\thirddot{\mkern-2.5mu\dotacc}% + \mathpalette\domultidot} + +\newcount\uproot@ +\newcount\leftroot@ + +\def\nonmatherr#1% + {\errmessage{\noexpand#1allowed only in math mode}} + +\def\uproot#1% + {\relax + \ifmmode + \uproot@#1\relax + \else + \nonmatherr\uproot + \fi} + +\def\leftroot#1% + {\relax + \ifmmode + \leftroot@#1\relax + \else + \nonmatherr\leftroot + \fi} + +\def\root#1\of#2% + {\setbox\rootbox=\hbox{$\mathsurround\zeropoint\scriptscriptstyle{#1}$}% + \mathpalette\r@@t{#2}} + +\def\r@@t#1#2% + {\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\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\zerocount\leftroot\zerocount\uproot\zerocount} + +\def\space@.{\futurelet\space@\relax} \space@. % really needed ? + +\def\jadjust% + {\mkern-\plustwo mu} + +%D For the moment the following code is left unchanged. It is +%D not used anyway. + +\newif\ifsubscriptcorrection \subscriptcorrectionfalse + +\ifsubscriptcorrection + + \expandafter\let\csname subscript character \string_\endcsname_ + + \catcode`\_=\active + + \def_% + {\ifmmode + \expandafter\sb@ + \else + \expandafter\csname subscript character \string_\endcsname + \fi} + + \let\sb_ + + \ifnum\catcode`\^^A=8 \catcode`\^^A\active\let^^A_\fi + + \def\sb@#1% + {\csname subscript character \string_\endcsname + {\futurelet\next\sb@@#1}} + + \def\sb@@% + {\ifx\next\space@ + \def\next@. % + {\futurelet\next\sb@@}% + \else + \def\next@.% + {\ifx\next j% + \mkern-\plustwo mu\else + \ifx\next f% + \mkern-\plustwo mu\else + \ifx\next p% + \mkern-\plusone mu\fi\fi\fi}% + \fi + \next@.} + +\fi + +\protect diff --git a/tex/context/base/math-uni.mkii b/tex/context/base/math-uni.mkii new file mode 100644 index 000000000..e8fd3f05d --- /dev/null +++ b/tex/context/base/math-uni.mkii @@ -0,0 +1,237 @@ +%D \module +%D [ file=math-uni, +%D version=2005.06.11, +%D title=\CONTEXT\ Math Macros, +%D subtitle=unicode support, +%D author={Nikolai Weibull \& Taco Hoekwater}, +%D date=\currentdate, +%D copyright=PRAGMA] + +\unprotect + +% needed for unic-032 % TH + +\startmathcollection[default] + + \definemathcommand [unic@doubleverticalline] {\mathord{\parallel}} + \definemathcommand [unic@doublelowline] {\underline{\textunderscore}} + + \definemathcommand [unic@doubleprime] {''} + \definemathcommand [unic@tripleprime] {'''} + + \definemathcommand [unic@reverseddoubleprime] {\mathord{\backprime\backprime}} + \definemathcommand [unic@reversedtripleprime] {\mathord{\backprime\backprime\backprime}} + + \definemathcommand [unic@fractionslash] {\vulgarfraction{}{}} + \definemathcommand [unic@lowasterisk] {\mathord{\lower-.2em\hbox{$\ast$}}} + + \definemathcommand [unic@functionapplication] {\mathop{}} + \definemathcommand [unic@invisibletimes] {\mathbin{}} + \definemathcommand [unic@invisibleseparator] {\mathpunct{}} + +\stopmathcollection + +% needed for unic-033 % TH + +\def\unic@vulgarfraction#1#2% + {\hbox + {\high{{\tfx\it #1}\kern -.2em}% + \symbol[vulgarfraction]% + \kern -.2em\low{{\tfx\it #2}}}} + +\startmathcollection[default] + + \definemathcommand [unic@accountof] {\unic@vulgarfraction{a}{c}} + \definemathcommand [unic@addressedtothesubject] {\unic@vulgarfraction{a}{s}} + \definemathcommand [unic@doublestruckC] {{\Bbb C}} + \definemathcommand [unic@degreecelsius] {{\textdegree \tf C}} + \definemathcommand [unic@centrelinesymbol] {\unknownchar} + \definemathcommand [unic@careof] {\unic@vulgarfraction{c}{o}} + \definemathcommand [unic@cadauna] {\unic@vulgarfraction{c}{u}} + \definemathcommand [unic@eulerconstant] {{\rm e}} + \definemathcommand [unic@scruple] {\unknownchar} + \definemathcommand [unic@degreefahrenheit] {{\textdegree \tf F}} + \definemathcommand [unic@scriptg] {\unknownchar} + \definemathcommand [unic@scriptH] {{\cal H}} + \definemathcommand [unic@blackletterH] {{\fraktur H}} + \definemathcommand [unic@doublestruckH] {{\Bbb H}} + \definemathcommand [unic@planckconstant] {h} + \definemathcommand [unic@planckconstantovertwopi] {\hslash} + \definemathcommand [unic@scriptI] {{\cal I}} + \definemathcommand [unic@blackletterI] {{\fraktur I}} + \definemathcommand [unic@scriptL] {{\cal L}} + \definemathcommand [unic@scriptl] {\ell} + \definemathcommand [unic@lbbarsymbol] {\unknownchar} + \definemathcommand [unic@doublestruckN] {{\Bbb N}} + \definemathcommand [unic@numerosign] {\hbox{\symbol[numero]}} + \definemathcommand [unic@soundrecordingcopyright] {\encircled{{\tfx P}}} + \definemathcommand [unic@scriptP] {{\cal P}} + \definemathcommand [unic@doublestruckP] {{\Bbb P}} + \definemathcommand [unic@doublestruckQ] {{\Bbb Q}} + \definemathcommand [unic@scriptR] {{\cal R}} + \definemathcommand [unic@blackletterR] {{\fraktur R}} + \definemathcommand [unic@doublestruckR] {{\Bbb R}} + \definemathcommand [unic@prescriptiontake] {\unknownchar} + \definemathcommand [unic@response] {\unknownchar} + \definemathcommand [unic@servicemark] {\high{\txx SM}} + \definemathcommand [unic@telephonesign] {\high{\txx TEL}} + \definemathcommand [unic@trademarksign] {\trademark} + \definemathcommand [unic@versickle] {\unknownchar} + \definemathcommand [unic@doublestruckZ] {{\Bbb Z}} + \definemathcommand [unic@ouncesign] {\unknownchar} + \definemathcommand [unic@ohmsign] {\Omega} + \definemathcommand [unic@invertedohmsign] {\rotate[\c!rotation=180]{\Omega}} + \definemathcommand [unic@blackletterZ] {{\fraktur Z}} + \definemathcommand [unic@turnedgreekletteriota] {\rotate[\c!rotation=180]{\iota}} + \definemathcommand [unic@kelvinsign] {{\tf K}} + \definemathcommand [unic@angstromsign] {\Angstrom} + \definemathcommand [unic@scriptB] {{\cal B}} + \definemathcommand [unic@blackletterC] {{\fraktur C}} + \definemathcommand [unic@estimatedsymbol] {\unknownchar} + \definemathcommand [unic@scripte] {\unknownchar} + \definemathcommand [unic@scriptE] {{\cal E}} + \definemathcommand [unic@scriptF] {{\cal F}} + \definemathcommand [unic@turnedF] {\rotate[\c!rotation=180]{{\tf F}}} + \definemathcommand [unic@scriptM] {{\cal M}} + \definemathcommand [unic@scripto] {\unknownchar} + + \definemathcommand [unic@informationsource] {{\bf i}} + \definemathcommand [unic@rotatedQ] {\rotate[\c!rotation=90]{{\tf Q}}} + \definemathcommand [unic@facsimilesign] {\unknownchar} + \definemathcommand [unic@doublestruckpi] {\pi}%{\unknownchar} + \definemathcommand [unic@doublestruckgamma] {\gamma}%{\unknownchar} + \definemathcommand [unic@doublestruckGamma] {\Gamma}%{\unknownchar} + \definemathcommand [unic@doublestruckPi] {\Pi}%{\unknownchar} + \definemathcommand [unic@doublestrucknarysummation] {\unknownchar} + \definemathcommand [unic@turnedsansserifG] {\rotate[\c!rotation=180]{{\ss G}}} + \definemathcommand [unic@turnedsansserifL] {\rotate[\c!rotation=180]{{\ss L}}} + \definemathcommand [unic@reversedsansserifL] {\mirror{{\ss L}}} + \definemathcommand [unic@turnedsansserifY] {\rotate[\c!rotation=180]{{\ss Y}}} + \definemathcommand [unic@doublestruckitalicD] {D}%{\unknownchar} + \definemathcommand [unic@doublestruckitalicd] {d}%{\unknownchar} + \definemathcommand [unic@doublestruckitalice] {e}%{\unknownchar} + \definemathcommand [unic@doublestruckitalici] {i}%{\unknownchar} + \definemathcommand [unic@doublestruckitalicj] {j}%{\unknownchar} + \definemathcommand [unic@propertyline] {\unknownchar} + \definemathcommand [unic@turnedampersand] {\rotate[\c!rotation=180]{\&}} + \definemathcommand [unic@persign] {\unknownchar} + + \definemathcommand [unic@fractiononethird] {\vulgarfraction{1}{3}} + \definemathcommand [unic@fractiontwothirds] {\vulgarfraction{2}{3}} + \definemathcommand [unic@fractiononefifth] {\vulgarfraction{1}{5}} + \definemathcommand [unic@fractiontwofifths] {\vulgarfraction{2}{5}} + \definemathcommand [unic@fractionthreefifths] {\vulgarfraction{3}{5}} + \definemathcommand [unic@fractionfourfifths] {\vulgarfraction{4}{5}} + \definemathcommand [unic@fractiononesixth] {\vulgarfraction{1}{6}} + \definemathcommand [unic@fractionfivesixths] {\vulgarfraction{5}{6}} + \definemathcommand [unic@fractiononeeighth] {\vulgarfraction{1}{8}} + \definemathcommand [unic@fractionthreeeighths] {\vulgarfraction{3}{8}} + \definemathcommand [unic@fractionfiveeighths] {\vulgarfraction{5}{8}} + \definemathcommand [unic@fractionseveneighths] {\vulgarfraction{7}{8}} + \definemathcommand [unic@fractionnumeratorone] {\vulgarfraction{1}{}} + \definemathcommand [unic@romannumeralOne] {{\tf I}} + \definemathcommand [unic@romannumeralTwo] {{\tf II}} + \definemathcommand [unic@romannumeralThree] {{\tf III}} + \definemathcommand [unic@romannumeralFour] {{\tf IV}} + \definemathcommand [unic@romannumeralFive] {{\tf V}} + \definemathcommand [unic@romannumeralSix] {{\tf VI}} + \definemathcommand [unic@romannumeralSeven] {{\tf VII}} + \definemathcommand [unic@romannumeralEight] {{\tf VIII}} + \definemathcommand [unic@romannumeralNine] {{\tf IX}} + \definemathcommand [unic@romannumeralTen] {{\tf X}} + \definemathcommand [unic@romannumeralEleven] {{\tf XI}} + \definemathcommand [unic@romannumeralTwelve] {{\tf XII}} + \definemathcommand [unic@romannumeralFifty] {{\tf L}} + \definemathcommand [unic@romannumeralOnehundred] {{\tf C}} + \definemathcommand [unic@romannumeralFivehundred] {{\tf D}} + \definemathcommand [unic@romannumeralOnethousand] {{\tf M}} + \definemathcommand [unic@romannumeralone] {{\tf i}} + \definemathcommand [unic@romannumeraltwo] {{\tf ii}} + \definemathcommand [unic@romannumeralthree] {{\tf iii}} + \definemathcommand [unic@romannumeralfour] {{\tf iv}} + \definemathcommand [unic@romannumeralfive] {{\tf v}} + \definemathcommand [unic@romannumeralsix] {{\tf vi}} + \definemathcommand [unic@romannumeralseven] {{\tf vii}} + \definemathcommand [unic@romannumeraleight] {{\tf viii}} + \definemathcommand [unic@romannumeralnine] {{\tf ix}} + \definemathcommand [unic@romannumeralten] {{\tf x}} + \definemathcommand [unic@romannumeraleleven] {{\tf xi}} + \definemathcommand [unic@romannumeraltwelve] {{\tf xii}} + \definemathcommand [unic@romannumeralfifty] {{\tf l}} + \definemathcommand [unic@romannumeralonehundred] {{\tf c}} + \definemathcommand [unic@romannumeralfivehundred] {{\tf d}} + \definemathcommand [unic@romannumeralonethousand] {{\tf m}} + \definemathcommand [unic@romannumeralonethousandCD] {\unknownchar} + \definemathcommand [unic@romannumeralfivethousand] {\unknownchar} + \definemathcommand [unic@romannumeraltenthousand] {\unknownchar} + \definemathcommand [unic@romannumeralreversedonehundred] {\mirror{C}} + +\stopmathcollection + +% needed for unic-033 % NW + +\startmathcollection[default] + + \definemathcommand [unic@leftarrowtobar] {\mapstochar\leftarrow} + +\stopmathcollection + +% needed for unic-034 % NW + +\startmathcollection[default] + + \definemathcommand [unic@in] {\in} + \definemathcommand [unic@nin] {\not\in} + \definemathcommand [unic@nni] {\not\ni} + \definemathcommand [unic@minus] {-} + \definemathcommand [unic@divisionslash] {/} + \definemathcommand [unic@sqrt] {\sqrt{}} + \definemathcommand [unic@cubesqrt] {\root 3 \of {}} + \definemathcommand [unic@fourthsqrt] {\root 4 \of {}} + \definemathcommand [unic@divides] [op] {|} % TODO + \definemathcommand [unic@ndivides] [rel] {\mathop{\not|}} % TODO: horrible + \definemathcommand [unic@cap] {\cap} + \definemathcommand [unic@dblint] {\int\!\!\!\int} + \definemathcommand [unic@triint] {\int\!\!\!\int\!\!\!\int} + \definemathcommand [unic@ratio] [rel] {:} + \definemathcommand [unic@proportion] [rel] {::} + \definemathcommand [unic@excess] [op] {-\!\!:} + \definemathcommand [unic@geomprop] [op] {:\!\!\!-\!\!\!:} + \definemathcommand [unic@homothetic] [op] {\sim\!\!\!:} + \definemathcommand [unic@nsimeq] {\not\simeq} + \definemathcommand [unic@cong] {\cong} + \definemathcommand [unic@napproxeq] {\not\approxeq} + \definemathcommand [unic@napprox] {\not\approx} + \definemathcommand [unic@doteq] {\doteq} + \definemathcommand [unic@correspondsto] {\buildrel \frown \over =} + \definemathcommand [unic@estimates] {\buildrel \wedge \over =} + \definemathcommand [unic@equiangularto] {\buildrel \vee \over =} + \definemathcommand [unic@stareq] {\buildrel \star \over =} + \definemathcommand [unic@eqbydef] {\buildrel \rm def \over =} + \definemathcommand [unic@measuredby] {\buildrel \rm m \over =} + \definemathcommand [unic@questionedeq] {\buildrel \rm ? \over =} + \definemathcommand [unic@nequiv] {\not\equiv} + \definemathcommand [unic@nasymp] {\not\asymp} + \definemathcommand [unic@nlesssim] {\not\lesssim} + \definemathcommand [unic@ngtrsim] {\not\gtrsim} + \definemathcommand [unic@nlessgtr] {\not\lessgtr} + \definemathcommand [unic@ngtrless] {\not\gtrless} + \definemathcommand [unic@nsubset] {\not\subset} + \definemathcommand [unic@nsupset] {\not\supset} + \definemathcommand [unic@nsqsubseteq] {\not\sqsubseteq} + \definemathcommand [unic@nsqsupseteq] {\not\sqsupseteq} + +\stopmathcollection + +% needed for unic-039 % NW + +\startmathcollection[default] + + \definemathcommand [unic@Lbracket] [open] {[\![} + \definemathcommand [unic@Rbracket] [close] {]\!]} + \definemathcommand [unic@Langle] [open] {\langle\!\langle} + \definemathcommand [unic@Rangle] [close] {\rangle\!\rangle} + +\stopmathcollection + +\protect \endinput diff --git a/tex/context/base/math-vfu.lua b/tex/context/base/math-vfu.lua new file mode 100644 index 000000000..5023e6b4d --- /dev/null +++ b/tex/context/base/math-vfu.lua @@ -0,0 +1,1379 @@ +if not modules then modules = { } end modules ['math-vfu'] = { + version = 1.001, + comment = "companion to math-ini.mkiv", + 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. If you have problems with math fonts or miss +-- characters report it to the ConTeXt mailing list. + +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,characters,id,size,unicode,basecode) + 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,characters,id,size,unicode,first,rule,left,right,rule,last) + 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,characters,id,size,unicode,arrow,minus,isleft) + if characters[unicode] then + 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 } + characters[unicode].horiz_variants = t + end +end + +local function parent(main,characters,id,size,unicode,first,rule,last) + 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,characters,id,size,n,m) + local old = 0xFF000+n + local c = characters[old] + if c then + local upslot, dnslot, uprule, dnrule = 0xFF100+n, 0xFF200+n, 0xFF300+m, 0xFF400+m + local xu = main.parameters.x_height + 0.3*size + local xd = 0.3*size + 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,characters,id,size,unicode) + local minus = characters[0x002D] + if minus then + local mu = size/18 + 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 +end + +local function dots(main,characters,id,size,unicode) + local c = characters[0x002E] + if c then + 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 +end + +local function vertbar(main,characters,id,size,parent,scale,unicode) + local cp = characters[parent] + if cp then + local sc = scale * size + local pc = { "slot", id, parent } + characters[unicode] = { + width = cp.width, + height = cp.height + sc, + depth = cp.depth + sc, + commands = { + push, { "down", -sc }, pc, pop, + push, { "down", sc }, pc, pop, + pc, + }, + next = cp.next -- can be extensible + } + cp.next = unicode + end +end + +function fonts.vf.math.alas(main,id,size) + local characters = main.characters + for i=0x7A,0x7D do + make(main,characters,id,size,i,1) + end + brace (main,characters,id,size,0x23DE,0xFF17A,0xFF301,0xFF17D,0xFF17C,0xFF301,0xFF17B) + brace (main,characters,id,size,0x23DF,0xFF27C,0xFF401,0xFF27B,0xFF27A,0xFF401,0xFF27D) + parent (main,characters,id,size,0x23DC,0xFF17A,0xFF301,0xFF17B) + parent (main,characters,id,size,0x23DD,0xFF27C,0xFF401,0xFF27D) + negate (main,characters,id,size,0x2260,0x003D) + dots (main,characters,id,size,0x2026) -- ldots + dots (main,characters,id,size,0x22EE) -- vdots + dots (main,characters,id,size,0x22EF) -- cdots + dots (main,characters,id,size,0x22F1) -- ddots + dots (main,characters,id,size,0x22F0) -- udots + minus (main,characters,id,size,0xFF501) + arrow (main,characters,id,size,0x2190,0xFE190,0xFF501,true) -- left + arrow (main,characters,id,size,0x2192,0xFE192,0xFF501,false) -- right + vertbar(main,characters,id,size,0x0007C,0.10,0xFF601) -- big : 0.85 bodyfontsize + vertbar(main,characters,id,size,0xFF601,0.30,0xFF602) -- Big : 1.15 bodyfontsize + vertbar(main,characters,id,size,0xFF602,0.30,0xFF603) -- bigg : 1.45 bodyfontsize + vertbar(main,characters,id,size,0xFF603,0.30,0xFF604) -- Bigg : 1.75 bodyfontsize + vertbar(main,characters,id,size,0x02225,0.10,0xFF605) + vertbar(main,characters,id,size,0xFF605,0.30,0xFF606) + vertbar(main,characters,id,size,0xFF606,0.30,0xFF607) + vertbar(main,characters,id,size,0xFF607,0.30,0xFF608) +end + +local unique = 0 -- testcase: \startTEXpage \math{!\text{-}\text{-}\text{-}} \stopTEXpage + +function fonts.basecopy(tfmtable,name) + local characters, parameters, fullname = tfmtable.characters, tfmtable.parameters, tfmtable.fullname + local t, c, p = { }, { }, { } + for k, v in next, tfmtable do + t[k] = v + end + if characters then + for k, v in next, characters do + c[k] = v + end + t.characters = c + else + logs.report("math virtual","font %s has no characters",name) + end + if parameters then + for k, v in next, parameters do + p[k] = v + end + t.parameters = p + else + logs.report("math virtual","font %s has no parameters",name) + end + -- tricky ... what if fullname does not exist + if fullname then + unique = unique + 1 + t.fullname = fullname .. "-" .. unique + end + return t +end + +local reported = { } +local reverse -- index -> unicode + +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() + 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],name) + main.name, main.fonts, main.virtualized, main.math_parameters = name, lst, true, { } + local characters, descriptions = main.characters, main.descriptions + local mp = main.parameters + if mp then + mp.x_height = mp.x_height or 0 + end + local already_reported = false + 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 mm and fp and mp then + 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 + mp.x_height = fp.x_height or mp.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 + else + logs.report("math virtual","font %s, no parameters set",name) + 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 + local fontname = fs.name or "unknown" + local rf = reported[fontname] + if not rf then rf = { } reported[fontname] = rf end + local rv = rf[vectorname] + if not rv then rv = { } rf[vectorname] = rv end + local ru = rv[unicode] + if not ru then + if trace_virtual then + logs.report("math virtual", "unicode point U+%05X has no index %04X in vector %s for font %s",unicode,index,vectorname,fontname) + elseif not already_reported then + logs.report("math virtual", "the mapping is incomplete for '%s' at %s",name,number.topoints(size)) + already_reported = true + end + rv[unicode] = true + 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] + if not fci then +--~ characters[unicode] = { +--~ width = 0, +--~ height = 0, +--~ depth = 0, +--~ index = 0, +--~ } + 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 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 + end + mathematics.extras.copy(main) --not needed here (yet) + end + end + lst[#lst+1] = { id = font.nextid(), size = size } + if mp then -- weak catch + fonts.vf.math.alas(main,#lst,size) + end + 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) + main.nomath = false +--~ print(table.serialize(characters[0x222B])) +--~ print(main.fontname,table.serialize(main.MathConstants)) + 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-mr-missing"] = { + [0x02236] = 0x3A, -- colon +} + +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, -- rightharpoonup + [0x021C1] = 0x2B, -- rightharpoondown + [0xFE322] = 0x2C, -- lhook (hook for combining arrows) + [0xFE323] = 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 +-- + [0x0266D] = 0x5B, -- flat + [0x0266E] = 0x5C, -- natural + [0x0266F] = 0x5D, -- sharp + [0x02323] = 0x5E, -- smile + [0x02322] = 0x5F, -- frown + [0x02113] = 0x60, -- ell +-- + [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-it"] = { +-- [0x1D434] = 0x41, -- A + [0x1D6E2] = 0x41, -- Alpha +-- [0x1D435] = 0x42, -- B + [0x1D6E3] = 0x42, -- Beta +-- [0x1D436] = 0x43, -- C +-- [0x1D437] = 0x44, -- D +-- [0x1D438] = 0x45, -- E + [0x1D6E6] = 0x45, -- Epsilon +-- [0x1D439] = 0x46, -- F +-- [0x1D43A] = 0x47, -- G +-- [0x1D43B] = 0x48, -- H + [0x1D6E8] = 0x48, -- Eta +-- [0x1D43C] = 0x49, -- I + [0x1D6EA] = 0x49, -- Iota +-- [0x1D43D] = 0x4A, -- J +-- [0x1D43E] = 0x4B, -- K + [0x1D6EB] = 0x4B, -- Kappa +-- [0x1D43F] = 0x4C, -- L +-- [0x1D440] = 0x4D, -- M + [0x1D6ED] = 0x4D, -- Mu +-- [0x1D441] = 0x4E, -- N + [0x1D6EE] = 0x4E, -- Nu +-- [0x1D442] = 0x4F, -- O + [0x1D6F0] = 0x4F, -- Omicron +-- [0x1D443] = 0x50, -- P + [0x1D6F2] = 0x50, -- Rho +-- [0x1D444] = 0x51, -- Q +-- [0x1D445] = 0x52, -- R +-- [0x1D446] = 0x53, -- S +-- [0x1D447] = 0x54, -- T + [0x1D6F5] = 0x54, -- Tau +-- [0x1D448] = 0x55, -- U +-- [0x1D449] = 0x56, -- V +-- [0x1D44A] = 0x57, -- W +-- [0x1D44B] = 0x58, -- X + [0x1D6F8] = 0x58, -- Chi +-- [0x1D44C] = 0x59, -- Y +-- [0x1D44D] = 0x5A, -- Z +-- +-- [0x1D44E] = 0x61, -- a +-- [0x1D44F] = 0x62, -- b +-- [0x1D450] = 0x63, -- c +-- [0x1D451] = 0x64, -- d +-- [0x1D452] = 0x65, -- e +-- [0x1D453] = 0x66, -- f +-- [0x1D454] = 0x67, -- g +-- [0x1D455] = 0x68, -- h + [0x0210E] = 0x68, -- Planck constant (h) +-- [0x1D456] = 0x69, -- i +-- [0x1D457] = 0x6A, -- j +-- [0x1D458] = 0x6B, -- k +-- [0x1D459] = 0x6C, -- l +-- [0x1D45A] = 0x6D, -- m +-- [0x1D45B] = 0x6E, -- n +-- [0x1D45C] = 0x6F, -- o + [0x1D70A] = 0x6F, -- omicron +-- [0x1D45D] = 0x70, -- p +-- [0x1D45E] = 0x71, -- q +-- [0x1D45F] = 0x72, -- r +-- [0x1D460] = 0x73, -- s +-- [0x1D461] = 0x74, -- t +-- [0x1D462] = 0x75, -- u +-- [0x1D463] = 0x76, -- v +-- [0x1D464] = 0x77, -- w +-- [0x1D465] = 0x78, -- x +-- [0x1D466] = 0x79, -- y +-- [0x1D467] = 0x7A, -- z +} + +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-it", 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 +-- todo: we can make ss tt etc an option diff --git a/tex/context/base/meta-clp.tex b/tex/context/base/meta-clp.tex new file mode 100644 index 000000000..be2506b19 --- /dev/null +++ b/tex/context/base/meta-clp.tex @@ -0,0 +1,164 @@ +%D \module +%D [ file=meta-clp, +%D version=2000.07.06, +%D title=\METAPOST\ Graphics, +%D subtitle=Clipping, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 this library, we define a bunch of clipping paths that +%D can be fed to \type {\clip}. + +\startMPclip{ellipse} + clip currentpicture to unitcircle + xscaled \width yscaled \height ; +\stopMPclip + +\startMPclip{negellipse} + clip currentpicture to (unitcircle peepholed unitsquare) + xscaled \width yscaled \height ; +\stopMPclip + +\startMPclip{urellipse} + clip currentpicture to urcircle scaled 2 + xscaled \width yscaled \height ; +\stopMPclip + +\startMPclip{ulellipse} + clip currentpicture to ulcircle scaled 2 shifted (1,0) + xscaled \width yscaled \height ; +\stopMPclip + +\startMPclip{llellipse} + clip currentpicture to llcircle scaled 2 shifted (1,1) + xscaled \width yscaled \height ; +\stopMPclip + +\startMPclip{lrellipse} + clip currentpicture to lrcircle scaled 2 shifted (0,1) + xscaled \width yscaled \height ; +\stopMPclip + +\startMPclip{tellipse} + clip currentpicture to tcircle shifted (.5,0) yscaled 2 + xscaled \width yscaled \height ; +\stopMPclip + +\startMPclip{bellipse} + clip currentpicture to bcircle shifted (.5,.5) yscaled 2 + xscaled \width yscaled \height ; +\stopMPclip + +\startMPclip{lellipse} + clip currentpicture to lcircle shifted (.5,.5) xscaled 2 + xscaled \width yscaled \height ; +\stopMPclip + +\startMPclip{rellipse} + clip currentpicture to rcircle shifted (0,.5) xscaled 2 + xscaled \width yscaled \height ; +\stopMPclip + +\startMPclip{diamond} + clip currentpicture to unitdiamond + xscaled \width yscaled \height ; +\stopMPclip + +\startMPclip{negdiamond} + clip currentpicture to (unitdiamond peepholed unitsquare) + xscaled \width yscaled \height ; +\stopMPclip + +\startMPclip{urtriangle} + clip currentpicture to urtriangle scaled 2 + xscaled \width yscaled \height ; +\stopMPclip + +\startMPclip{ultriangle} + clip currentpicture to ultriangle scaled 2 shifted (1,0) + xscaled \width yscaled \height ; +\stopMPclip + +\startMPclip{lltriangle} + clip currentpicture to lltriangle scaled 2 shifted (1,1) + xscaled \width yscaled \height ; +\stopMPclip + +\startMPclip{lrtriangle} + clip currentpicture to lrtriangle scaled 2 shifted (0,1) + xscaled \width yscaled \height ; +\stopMPclip + +% More efficient: +% +% \def\dosimpleMPclip#1 +% {clip currentpicture to (#1) xscaled \width yscaled \height ;} +% +% \def\simpleMPclip#1#2% +% {\startMPclip{#1}\dosimpleMPclip{#2}\stopMPclip} +% +% \simpleMPclip {ellipse} {unitcircle} +% \simpleMPclip {diamond} {unitdiamond} +% +% \simpleMPclip {negellipse} {unitcircle peepholed unitsquare} +% \simpleMPclip {negdiamond} {unitdiamond peepholed unitsquare} +% +% \simpleMPclip {urellipse} {urcircle scaled 2 shifted (0,0)} +% \simpleMPclip {ulellipse} {ulcircle scaled 2 shifted (1,0)} +% \simpleMPclip {llellipse} {llcircle scaled 2 shifted (1,1)} +% \simpleMPclip {lrellipse} {lrcircle scaled 2 shifted (0,1)} +% +% \simpleMPclip {tellipse} {tcircle shifted (.5,0) yscaled 2} +% \simpleMPclip {bellipse} {bcircle shifted (.5,.5) yscaled 2} +% \simpleMPclip {lellipse} {lcircle shifted (.5,.5) xscaled 2} +% \simpleMPclip {rellipse} {rcircle shifted (0,.5) xscaled 2} +% +% \simpleMPclip {urtriangle} {urtriangle scaled 2 shifted (0,0)} +% \simpleMPclip {ultriangle} {ultriangle scaled 2 shifted (1,0)} +% \simpleMPclip {lltriangle} {lltriangle scaled 2 shifted (1,1)} +% \simpleMPclip {lrtriangle} {lrtriangle scaled 2 shifted (0,1)} + +%D \in {Figure} [fig:clipping paths] shows which paths are +%D predefined. When applied to a whole picture, their usage +%D is: +%D +%D \starttyping +%D \clip[nx=1,ny=1,mp=ellipse]{some clippable content} +%D \stoptyping +%D +%D \startbuffer +%D \setupclipping [nx=1,ny=1,x=1,y=1] +%D \setupblackrules[width=2cm,height=1cm] +%D \startcombination[6*3] % \startcombination[6*3] +%D {\clip[mp=urellipse] {\blackrule}} {urellipse} +%D {\clip[mp=ulellipse] {\blackrule}} {ulellipse} +%D {\clip[mp=llellipse] {\blackrule}} {llellipse} +%D {\clip[mp=lrellipse] {\blackrule}} {lrellipse} +%D {\clip[mp=ellipse] {\blackrule}} {ellipse} +%D {\clip[mp=negellipse]{\blackrule}} {negellipse} +%D {\clip[mp=tellipse] {\blackrule}} {tellipse} +%D {\clip[mp=bellipse] {\blackrule}} {bellipse} +%D {\clip[mp=lellipse] {\blackrule}} {lellipse} +%D {\clip[mp=rellipse] {\blackrule}} {rellipse} +%D {} {} +%D {} {} +%D {\clip[mp=urtriangle]{\blackrule}} {urtriangle} +%D {\clip[mp=ultriangle]{\blackrule}} {ultriangle} +%D {\clip[mp=lltriangle]{\blackrule}} {lltriangle} +%D {\clip[mp=lrtriangle]{\blackrule}} {lrtriangle} +%D {\clip[mp=diamond] {\blackrule}} {diamond} +%D {\clip[mp=negdiamond]{\blackrule}} {negdiamond} +%D \stopcombination % \stopcombination +%D \stopbuffer +%D +%D \placefigure % \placefigure +%D [here][fig:clipping paths] +%D {The predefined clipping paths.} +%D {\getbuffer} % {\getbuffer} + +\endinput diff --git a/tex/context/base/meta-dum.tex b/tex/context/base/meta-dum.tex new file mode 100644 index 000000000..bc19f3c5f --- /dev/null +++ b/tex/context/base/meta-dum.tex @@ -0,0 +1,123 @@ +%D \module +%D [ file=meta-dum, +%D version=2003.03.21, +%D title=\METAPOST\ Graphics, +%D subtitle=Dummy (External) Graphics, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\unprotect + +%D This library overloads the normal external figure +%D placeholder by a nicer one. +%D +%D \startbuffer +%D \useMPlibrary[dum] +%D +%D \startlinecorrection +%D \externalfigure[unknown-a][width=3cm,height=1cm] +%D \stoplinecorrection +%D +%D \startlinecorrection +%D \externalfigure[unknown-b][width=4cm,height=5cm] +%D \stoplinecorrection +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +% currently preparempvariables is unable to resolve number +% fractions like reduction + +% June 22, 2003, this definition was patched to adapt itself +% to transparent colors + +\startuseMPgraphic{placeholder}{width,height,reduction,color} + numeric w, h, d, r ; color c, b, cc ; path p ; boolean t ; + t := is_transparent(\MPvar{color}) ; + c := not_transparent(\MPvar{color}) ; + b := not_transparent(white) ; + w := \MPvar{width} ; + h := \MPvar{height} ; + r := \MPvar{reduction} ; + d := max(w,h) ; + p := unitsquare xyscaled (w,h) ; + cc := r[.5c,b] ; + fill p withcolor if t : transparent(1,.5,cc) else : cc fi ; + for i := 1 upto 60 : + cc := r[c randomized(.3,.9),b] ; + fill fullcircle + scaled (d/5 randomized (d/5)) + shifted (center p randomized (d)) + withcolor if t : transparent(1,.5,cc) else : cc fi ; + endfor ; + clip currentpicture to p ; +\stopuseMPgraphic + +\definepalet + [placeholder] + [1=red,2=green,3=blue,4=cyan,5=magenta,6=yellow] + +% \newcounter \figurereplacementcycle + +\let\figurereplacementcycle\relax + +\setupexternalfigures + [\c!reduction=0, + \c!text=\v!yes] + +\let\normalexternalfigurereplacement\externalfigurereplacement + +\def\externalfigurereplacement#1#2#3% + {\getpaletsize[placeholder]% + \ifx\figurereplacementcycle\relax + \getrandomnumber \figurereplacementcycle \!!plusone \paletsize + \globallet \figurereplacementcycle \figurereplacementcycle + \else + \doglobal\increment\figurereplacementcycle + \fi + \ifnum\figurereplacementcycle>\paletsize + \globallet\figurereplacementcycle\!!plusone + \fi + \weightGRAYfalse % monochrome anyway + \MPcmykcolorsfalse + \MPspotcolorsfalse + \defineoverlay + [\s!dummy] + [\useMPgraphic + {placeholder}% + {width=\figurewidth, + height=\figureheight, + reduction=\@@efreduction, + color=placeholder:\figurereplacementcycle}]% + \expanded{\localframed + [\??ef] + [\c!width=\figurewidth, + \c!height=\figureheight, + \c!frame=\v!off, + \c!strut=\v!no, + \c!background=\s!dummy, + \c!foregroundcolor=\s!white]}% + {\doif\@@eftext\v!yes + {\infofont \setupinterlinespace \dohyphens % \nohyphens + \doifelse{#1}\s!dummy \!!doneafalse\!!doneatrue + \doifelse{#2}\s!dummy \!!donebfalse\!!donebtrue + \doifelse{#3}\s!unknown\!!donecfalse\!!donectrue + \if!!donea + name: \expanded{\verbatimstring{#1}}\strut\endgraf + \fi + \if!!doneb + \if!!donea file: \else \if!!donec file: \fi \fi + \expanded{\verbatimstring{#2}}\strut\endgraf + \fi + \if!!donec + state: \expanded{\verbatimstring{#3}}\strut\endgraf + \fi}}} + +\def\dummyfigure{\externalfigure[placeholder]} + +\protect \endinput diff --git a/tex/context/base/meta-fig.mkii b/tex/context/base/meta-fig.mkii new file mode 100644 index 000000000..3edd73b57 --- /dev/null +++ b/tex/context/base/meta-fig.mkii @@ -0,0 +1,89 @@ +%D \module +%D [ file=meta-fig, +%D version=2000.09.07, +%D title=\METAPOST\ Graphics, +%D subtitle=Stand Alone Graphics, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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}{MetaPost Graphics / Stand Alone Graphics} + +\unprotect + +%D This module implements a method for defining +%D stand||alone||graphics, that is, each graphic gets is own +%D page. Because graphics are wrapped in a \type {\framed}, +%D you can add overlays to the graphic directly, and since the +%D whole \CONTEXT\ machinery is available, you can also add +%D page backgrounds. +%D +%D \starttyping +%D \setupMPpage +%D [offset=1pt, +%D background=color, +%D backgroundcolor=green] +%D +%D \startMPpage +%D fill fullcircle scaled 10cm withcolor red ; +%D \stopMPpage +%D +%D \startMPpage +%D fill fullsquare rotated 45 scaled 8cm withcolor blue ; +%D \stopMPpage +%D \stoptyping +%D +%D Although this is hardly of any use, you can mix these +%D definitions with the text flow, since all settings are +%D kept local. The page is clipped to the image size. + +\presetlocalframed[\??mg] + +\def\setupMPpage + {\dodoubleargument\getparameters[\??mg]} + +\def\startMPpage + {\dodoubleempty\dostartMPpage} + +\long\def\dostartMPpage[#1][#2]% second arg gobbles space + {\dostartfittingpage[\??mg][#1]% + \obeyMPlines + \dodostartMPpage} + +\long\def\dodostartMPpage#1\stopMPpage + {\startuseMPgraphic{@@}#1\stopuseMPgraphic + \useMPgraphic{@@}% + \dostopfittingpage} + +\let\stopMPpage \relax % so that we can use it in \expanded + +\setupMPpage + [\c!scale=1000, + \c!strut=\v!no, + \c!align=, + \c!offset=\v!overlay, + \c!width=\v!fit, + \c!height=\v!fit, + \c!frame=\v!off] + +%D \macros +%D {MPfigure} +%D +%D A bit out of place, here but nevertheless: + +\def\MPfigure#1#2% test for dup figure + {\bgroup + \getfiguredimensionsonly[#1]% [\c!object=\v!no] already set + \startMPcode + externalfigure "#1" + xscaled \figurewidth\space + yscaled \figureheight\space + #2 ; + \stopMPcode + \egroup} + +\protect \endinput diff --git a/tex/context/base/meta-fig.mkiv b/tex/context/base/meta-fig.mkiv new file mode 100644 index 000000000..4738316da --- /dev/null +++ b/tex/context/base/meta-fig.mkiv @@ -0,0 +1,84 @@ +%D \module +%D [ file=meta-fig, +%D version=2000.09.07, +%D title=\METAPOST\ Graphics, +%D subtitle=Stand Alone Graphics, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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}{MetaPost Graphics / Stand Alone Graphics} + +\unprotect + +%D This module implements a method for defining +%D stand||alone||graphics, that is, each graphic gets is own +%D page. Because graphics are wrapped in a \type {\framed}, +%D you can add overlays to the graphic directly, and since the +%D whole \CONTEXT\ machinery is available, you can also add +%D page backgrounds. +%D +%D \starttyping +%D \setupMPpage +%D [offset=1pt, +%D background=color, +%D backgroundcolor=green] +%D +%D \startMPpage +%D fill fullcircle scaled 10cm withcolor red ; +%D \stopMPpage +%D +%D \startMPpage +%D fill fullsquare rotated 45 scaled 8cm withcolor blue ; +%D \stopMPpage +%D \stoptyping +%D +%D Although this is hardly of any use, you can mix these +%D definitions with the text flow, since all settings are +%D kept local. The page is clipped to the image size. + +\presetlocalframed[\??mg] + +\unexpanded\def\setupMPpage + {\dodoubleargument\getparameters[\??mg]} + +\def\startMPpage + {\dodoubleempty\dostartMPpage} + +\long\def\dostartMPpage[#1][#2]#3\stopMPpage % second arg gobbles space + {\dostartfittingpage[\??mg][#1]% + \processMPgraphic{#3}% + \dostopfittingpage} + +\let\stopMPpage \relax % so that we can use it in \expanded + +\setupMPpage + [\c!scale=1000, + \c!strut=\v!no, + \c!align=, + \c!offset=\v!overlay, + \c!width=\v!fit, + \c!height=\v!fit, + \c!frame=\v!off] + +%D \macros +%D {MPfigure} +%D +%D A bit out of place, here but nevertheless: + +\def\MPfigure#1#2% test for dup figure, can be replaced by a textext + {\bgroup + \getfiguredimensionsonly[#1]% [\c!object=\v!no] already set + \startMPcode + externalfigure "#1" + xscaled \the\dimexpr\figurewidth \relax\space % must be points + yscaled \the\dimexpr\figureheight\relax\space % must be points + #2 ; + \stopMPcode + \egroup} + +\protect \endinput diff --git a/tex/context/base/meta-fun.lua b/tex/context/base/meta-fun.lua new file mode 100644 index 000000000..fef2aa12b --- /dev/null +++ b/tex/context/base/meta-fun.lua @@ -0,0 +1,55 @@ +if not modules then modules = { } end modules ['meta-fun'] = { + version = 1.001, + comment = "companion to meta-fun.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", +} + +-- very experimental, actually a joke ... see metafun manual for usage + +local format, loadstring, type = string.format, loadstring, type +local texwrite = tex.write + +metafun = metafun or { } + +function metafun.topath(t,connector) + tex.write("(") + if #t > 0 then + for i=1,#t do + if i > 1 then + texwrite(connector or "..") + end + local ti = t[i] + if type(ti) == "string" then + texwrite(ti) + else + texwrite(format("(%s,%s)",ti.x or ti[1] or 0,ti.y or ti[2] or 0)) + end + end + else + texwrite("origin") + end + texwrite(")") +end + +function metafun.interpolate(f,b,e,s,c) + local done = false + tex.write("(") + for i=b,e,(e-b)/s do + local d = loadstring(format("return function(x) return %s end",f)) + if d then + d = d() + if done then + texwrite(c or "...") + else + done = true + end + texwrite(format("(%s,%s)",i,d(i))) + end + end + if not done then + texwrite("origin") + end + texwrite(")") +end diff --git a/tex/context/base/meta-fun.mkiv b/tex/context/base/meta-fun.mkiv new file mode 100644 index 000000000..a43ffefff --- /dev/null +++ b/tex/context/base/meta-fun.mkiv @@ -0,0 +1,20 @@ +%D \module +%D [ file=meta-fun, +%D version=2009.06.02, +%D title=\METAPOST\ Graphics, +%D subtitle=Goodies, +%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}{MetaPost Graphics / Goodies} + +\registerctxluafile{meta-fun}{1.001} + +\unprotect + +\protect \endinput diff --git a/tex/context/base/meta-ini.mkii b/tex/context/base/meta-ini.mkii new file mode 100644 index 000000000..e7c6d218e --- /dev/null +++ b/tex/context/base/meta-ini.mkii @@ -0,0 +1,1054 @@ +%D \module +%D [ file=meta-ini, +%D version=1999.07.10, +%D title=\METAPOST\ Graphics, +%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. + +% currently the running color influences the mp graphic in +% pdftex, but this will change [i.e. become optional]; one +% problem is that pdf has no grouping with regards to the +% color + +\writestatus{loading}{MetaPost Graphics / Initializations} + +\unprotect + +%D This module extends the functionality of the support module +%D \type {supp-mps}, the module that is responsible for +%D \METAPOST\ inclusion in \CONTEXT. Some basic macros will be +%D extended. Since some support is depends on \METAPOST\ +%D macros. so let's first preload a few auxiliary \METAPOST\ +%D files. + +\maxnofMPgraphics = 4000 % metafun disables the 4K boundary + +\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; +\stopMPextensions + +%D Since we want lables to follow the document settings, we +%D also set the font related variables. + +\ifnum\texengine=\xetexengine + \startMPinitializations % scale is not yet ok + defaultfont:="rm-lmtt10"; + defaultscale:=\the\bodyfontsize/10pt; + \stopMPinitializations +\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"; +\stopMPextensions + +% \startMPextensions +% textextdirective "\the\everyMPTEXgraphic"; +% \stopMPextensions + +%D A signal that we're in combines \CONTEXT||\METAFUN mode: + +\startMPextensions + string contextversion; + contextversion:="\contextversion"; +\stopMPextensions + +%D Some safeguards: +%D +%D \starttyping +%D \appendtoks \cleanupfeatures \to \everyMPgraphic +%D \stoptyping +%D +%D No, we don't want that (else we loose UTF etc). + +%D Another one: + +\prependtoks \MPstaticgraphictrue \to \everyoverlay +\prependtoks \MPstaticgraphictrue \to \everypagebody + +%D We save the number of graphics for the sake of \TEXEXEC. + +\newcounter\totalnofMPgraphics + +\def\thenofMPgraphics{\the\nofMPgraphics} % from supp-mps + +\appendtoks + \savecurrentvalue\totalnofMPgraphics\thenofMPgraphics +\to \everybye + +%D \macros +%D {setupMPvariables} +%D +%D When we build collections of \METAPOST\ graphics, like +%D background and buttons, the need for passing settings +%D arises. By (mis|)|using the local prefix that belongs to +%D \type {\framed}, we get a rather natural interface to +%D backgrounds. To prevent conflicts, we will use the \type +%D {-} in \METAPOST\ specific variables, like: +%D +%D \starttyping +%D \setupMPvariables[meta:button][size=20pt] +%D \stoptyping + +\def\@@meta{meta:} + +\def\setupMPvariables + {\dodoubleempty\dosetupMPvariables} + +\def\dosetupMPvariables[#1][#2]% + {\ifsecondargument + \getrawparameters[#1:][#2]% brr, todo: [\@@meta#1:] + \else + \getrawparameters[\@@meta][#1]% + \fi} + +\let\@@framed\s!unknown + +\def\MPvariable#1% + {\csname + \ifcsname\@@framed\@@meta#1\endcsname\@@framed\fi\@@meta#1% + \endcsname} + +\let\MPvar\MPvariable + +\let\setMPvariables\setupMPvariables + +\def\MPrawvar#1#2{\csname#1:#2\endcsname} + +\def\presetMPvariable + {\dodoubleargument\dopresetMPvariable} + +\def\dopresetMPvariable[#1][#2=#3]% + {\doifundefined{#1:#2}{\setvalue{#1:#2}{#3}}} + +\def\useMPvariables + {\dodoubleargument\douseMPvariables} + +\def\douseMPvariables[#1][#2]% + {\def\@@meta{#1:}% + \prepareMPvariables{#2}} + +%D \macros +%D {startuniqueMPgraphic, uniqueMPgraphic} +%D +%D This macros is probably of most use to myself, since I like +%D to use graphics that adapt themselves. The next \METAPOST\ +%D kind of graphic is both unique and reused when possible. +%D +%D \starttyping +%D \defineoverlay[example][\uniqueMPgraphic{test}] +%D +%D \startuniqueMPgraphic {test} +%D draw unitsquare xscaled \overlaywidth yscaled \overlayheight ; +%D \stopuniqueMPgraphic +%D \stoptyping + +%D For educational purposes, we show the original version +%D first. This one used a rather simple method for determining +%D the uniqueness. +%D +%D \starttyping +%D \long\def\startuniqueMPgraphic#1#2\stopuniqueMPgraphic% +%D {\setvalue{\@@MPG#1}% +%D {\startreusableMPgraphic{\overlaystamp:#1}#2\stopreusableMPgraphic +%D \reuseMPgraphic{\overlaystamp:#1}}} +%D +%D \def\uniqueMPgraphic#1% +%D {\getvalue{\@@MPG#1}} +%D \stoptyping + +%\def\overlaystamp % watch the \MPcolor, since colors can be redefined +% {\overlaywidth:\overlayheight:\overlaydepth +% :\MPcolor{\overlaycolor}:\MPcolor{\overlaylinecolor}} + +\def\overlaystamp % watch the \MPcolor, since colors can be redefined + {\overlaywidth:\overlayheight:\overlaydepth + :\MPcolor\overlaycolor:\MPcolor\overlaylinecolor} + +%D A better approach is to let additional variables play a role +%D in determining the uniqueness. In the next macro, the +%D second, optional, argument is used to guarantee the +%D uniqueness, as well as prepare variables for passing them to +%D \METAPOST. +%D +%D \starttyping +%D \startuniqueMPgraphic{meta:hash}{gap,angle,...} +%D \stoptyping +%D +%D The calling macro also accepts a second argument. For +%D convenient use in overlay definitions, we use \type {{}} +%D instead of \type {[]}. +%D +%D \starttyping +%D \uniqueMPgraphic{meta:hash}{gap=10pt,angle=30} +%D \stoptyping + +\long\def\handleuniqueMPgraphic#1#2#3% + {\blabelgroup + \def\@@meta{#1:}% + \extendMPoverlaystamp{#2}% incl prepare + \ifundefined{\@@MPG\overlaystamp:#1}% + \enableincludeMPgraphics + \startMPgraphic#3\stopMPgraphic + \doifobjectssupportedelse\donothing\useMPboxfalse + \ifuseMPbox + \@EA\douseMPbox + \else + \@EA\nouseMPbox + \fi {\@@MPG\overlaystamp:#1}% + \fi + \getvalue{\@@MPG\overlaystamp:#1}% + \elabelgroup} + +\long\def\startuniqueMPgraphic + {\blabelgroup + \dodoublegroupempty\dostartuniqueMPgraphic} + +\long\def\dostartuniqueMPgraphic + {\obeyMPlines + \dodostartuniqueMPgraphic} + +\long\def\dodostartuniqueMPgraphic#1#2#3\stopuniqueMPgraphic% + {\long\setgvalue{\@@MPG#1}{\handleuniqueMPgraphic{#1}{#2}{#3}}% + \elabelgroup} + +\unexpanded\def\uniqueMPgraphic + {\dodoublegroupempty\douniqueMPgraphic} + +\def\douniqueMPgraphic#1#2% + {\blabelgroup + \setupMPvariables[#1][#2]% + \getvalue{\@@MPG#1}{}% + \elabelgroup} + +\let\stopuniqueMPcode \relax % so that we can use it in \expanded + +\def\includeMPgraphic#1% + {\executeifdefined{\@@MPG#1};} % ; if not found + +\long\def\handleuseMPgraphic#1#2#3% + {\blabelgroup + \def\@@meta{#1:}% + \prepareMPvariables{#2}% + \enableincludeMPgraphics + \startMPgraphic#3\stopMPgraphic + \ifMPrun \else % see mfun-004 : processing buffer + \loadMPgraphic{\MPgraphicfile.\the\currentMPgraphic}{}% + \placeMPgraphic + \fi + \deallocateMPslot\currentMPgraphic + \elabelgroup} + +\long\def\startuseMPgraphic + {\blabelgroup + \dodoublegroupempty\dostartuseMPgraphic} + +\long\def\dostartuseMPgraphic + {\obeyMPlines + \dodostartuseMPgraphic} + +\long\def\dodostartuseMPgraphic#1#2#3\stopuseMPgraphic + {\long\setgvalue{\@@MPG#1}{\handleuseMPgraphic{#1}{#2}{#3}}% + \elabelgroup} + +\long\def\startusableMPgraphic % redundant but handy + {\blabelgroup + \dodoublegroupempty\dostartusableMPgraphic} + +\long\def\dostartusableMPgraphic % redundant but handy + {\obeyMPlines + \dodostartusableMPgraphic} + +\long\def\dodostartusableMPgraphic#1#2#3\stopusableMPgraphic + {\long\setgvalue{\@@MPG#1}{\handleuseMPgraphic{#1}{#2}{#3}}% + \elabelgroup} + +\long\def\handlereusableMPgraphic#1#2#3% + {\blabelgroup + \def\@@meta{#1:}% + \prepareMPvariables{#2}% + \enableincludeMPgraphics + \startMPgraphic#3\stopMPgraphic + \doifobjectssupportedelse\donothing\useMPboxfalse + \ifuseMPbox + \@EA\douseMPbox + \else + \@EA\nouseMPbox + \fi {\@@MPG#1}% + \getvalue{\@@MPG#1}% + \elabelgroup} + +\long\def\startreusableMPgraphic + {\blabelgroup + \dodoublegroupempty\dostartreusableMPgraphic} + +\def\dostartreusableMPgraphic + {\obeyMPlines + \dodostartreusableMPgraphic} + +\long\def\dodostartreusableMPgraphic#1#2#3\stopreusableMPgraphic + {\long\setgvalue{\@@MPG#1}{\handlereusableMPgraphic{#1}{#2}{#3}}% + \elabelgroup} + +\unexpanded\def\useMPgraphic + {\dodoublegroupempty\douseMPgraphic} + +\def\douseMPgraphic#1#2% + {\blabelgroup + \setupMPvariables[#1][#2]% + \getvalue{\@@MPG#1}{}% + \elabelgroup} + +\let\reuseMPgraphic\useMPgraphic + +\let\stopuseMPcode \relax % so that we can use it in \expanded +\let\stopusableMPcode \relax % so that we can use it in \expanded +\let\stopreusableMPcode \relax % so that we can use it in \expanded +\let\stopuniqueMPcode \relax % so that we can use it in \expanded + +\def\enableincludeMPgraphics + {\let\handleuseMPgraphic \thirdofthreearguments + \let\handlereusableMPgraphic\thirdofthreearguments} + +% todo: each code/page/buffer a var class + +%D \macros +%D {startuniqueMPpagegraphic,uniqueMPpagegraphic} +%D +%D Experimental. + +\def\MPpageprefix{\doifoddpageelse oe:} + +\def\overlaypagestamp + {\MPpageprefix\overlaywidth:\overlayheight:\overlaydepth + :\MPcolor\overlaycolor:\MPcolor\overlaylinecolor} + +\long\def\startuniqueMPpagegraphic + {\blabelgroup + \dodoublegroupempty\dostartuniqueMPpagegraphic} + +\long\def\dostartuniqueMPpagegraphic + {\obeyMPlines + \dodostartuniqueMPpagegraphic} + +\long\def\dodostartuniqueMPpagegraphic#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} + +\unexpanded\def\uniqueMPpagegraphic + {\dodoublegroupempty\douniqueMPpagegraphic} + +% \def\douniqueMPpagegraphic#1#2% +% {\blabelgroup +% \let\overlaystamp\overlaypagestamp +% \setupMPvariables[#1][#2]% +% \getvalue{\@@MPG\MPpageprefix#1}{}% +% \elabelgroup} + +\def\douniqueMPpagegraphic#1#2% + {\blabelgroup + \let\overlaystamp\overlaypagestamp + \setupMPvariables[\MPpageprefix#1][#2]% prefix is new here + \getvalue{\@@MPG\MPpageprefix#1}{}% + \elabelgroup} + +%D One way of defining a stamp is: +%D +%D \starttyping +%D \def\extendMPoverlaystamp#1% +%D {\def\docommand##1% +%D {\edef\overlaystamp{\overlaystamp:\MPvariable{##1}}}% +%D \processcommalist[#1]\docommand} +%D \stoptyping + +%D Since we need to feed \METAPOST\ with expanded dimensions, +%D we introduce a dedicated expansion engine. + +\def\prepareMPvariable#1% + {\ifundefined{\@@framed\@@meta#1}% + \doprepareMPvariable{\@@meta#1}% + \else + \doprepareMPvariable{\@@framed\@@meta#1}% + \fi} + +% \startlines +% \def\xxx{\lineheight} \doprepareMPvariable{xxx} \xxx +% \def\xxx{2pt} \doprepareMPvariable{xxx} \xxx +% \def\xxx{2} \doprepareMPvariable{xxx} \xxx +% \def\xxx{\scratchcounter} \doprepareMPvariable{xxx} \xxx +% \def\xxx{red} \doprepareMPvariable{xxx} \xxx +% \def\xxx{0.4} \doprepareMPvariable{xxx} \xxx +% \stoplines + +\def\doprepareMPvariable#1% + {\edef\theMPvariable{\getvalue{#1}}% + \doifelsenothing\theMPvariable + {\setevalue{#1}{\MPcolor{black}}} + {\defconvertedcommand\ascii\theMPvariable % otherwise problems + \doifcolorelse \ascii % with 2\bodyfontsize + {\setevalue{#1}{\MPcolor\theMPvariable}} + {% can be aux macro + \setbox\scratchbox\hbox{\scratchdimen\theMPvariable sp}% + \ifdim\wd\scratchbox=\zeropoint + % \scratchcounter\theMPvariable + % \setevalue{#1}{\the\scratchcounter}% + % also accepts 0.number : + \setevalue{#1}{\number\theMPvariable}% + \else + \scratchdimen\theMPvariable + \setevalue{#1}{\the\scratchdimen}% + \fi}}} + +%D We redefine \type {\extendMPoverlaystamp} to preprocess +%D variables using \type {\prepareMPvariable}. + +\def\doextendMPoverlaystamp#1% + {\prepareMPvariable{#1}% + \edef\overlaystamp{\overlaystamp:\MPvariable{#1}}} + +\def\extendMPoverlaystamp#1% + {\processcommalist[#1]\doextendMPoverlaystamp} + +\def\prepareMPvariables#1% + {\processcommalist[#1]\prepareMPvariable} + +%D \macros +%D {MPdatafile} +%D +%D We redefine a macro from \type {supp-mps.tex}: + +\def\MPdatafile + {\bufferprefix mpd-\the\currentMPgraphic.mpd} + +%D \macros +%D {MPrunfile} +%D +%D This one is more abstract and does not assume knowledge +%D of buffer prefixes. + +\def\MPrunfile#1% + {\bufferprefix mprun.#1} + +%D \macros +%D {getMPdata} +%D +%D When we collect graphics in one file, we run into +%D troubles, since \METAPOST\ has a built in limit (of 4) +%D on the number of files it can handle. It's therefore +%D better to collect all data in one file and filter it. + +\def\MPdataMPDfile{\jobname-mpgraph.mpd} +\def\MPdataMPOfile{\jobname-mpgraph.mpo} +\def\MPdataMPYfile{\jobname-mpgraph.mpy} + +\startMPextensions + boolean collapse_data; collapse_data:=true; + def data_mpd_file = "\MPdataMPDfile" enddef ; + def data_mpo_file = "\MPdataMPOfile" enddef ; + def data_mpy_file = "\MPdataMPYfile" enddef ; +\stopMPextensions + +\def\getMPdata + {\long\def\MPdata##1##2{\ifnum##1=\currentMPgraphic\relax##2\fi}% + \startreadingfile + % \startnointerference % no, else we need to do all data global + \readlocfile\MPdataMPDfile\donothing\donothing + % \stopnointerference + \stopreadingfile} + +%D We have to enable this mechanism with: + +\startMPextensions +\stopMPextensions + +%D For the moment, the next one is a private macro: + +\def\processMPbuffer + {\dosingleempty\doprocessMPbuffer} + +\def\doprocessMPbuffer[#1]% + {\doifelsenothing{#1} + {\doprocessMPbuffer[\jobname]} + {\bgroup + \setnormalcatcodes + \obeyMPlines + %\let\par\empty % oeps, this makes dvi mode graphics hang when not found + \!!toksa\emptytoks + \def\copyMPbufferline{\expandafter\appendtoks\fileline\to\!!toksa}% + \def\dodoprocessMPbuffer##1% + {\doprocessfile\scratchread{\TEXbufferfile{##1}}\copyMPbufferline}% + \processcommalist[#1]\dodoprocessMPbuffer + \@EA\startMPcode\the\!!toksa\stopMPcode % more efficient + \egroup}} + +\def\runMPbuffer + {\dosingleempty\dorunMPbuffer} + +\def\dorunMPbuffer[#1]% processing only + {{\MPruntrue\doprocessMPbuffer[#1]}} + +%D \macros +%D {startMPenvironment, resetMPenvironment} +%D +%D In order to synchronize the main \TEX\ run and the runs +%D local to \METAPOST, environments can be passed. + +\ifx\everyMPTEXgraphic\undefined + \newtoks\everyMPTEXgraphic +\fi + +%D A more general way of passing environments is: + +\def\startMPenvironment % second arg gobbles spaces, so that reset gives \emptytoks + {\bgroup + \catcode`\^^M=\@@space + \dodoubleempty\dostartMPenvironment} + +\long\def\dostartMPenvironment[#1][#2]#3\stopMPenvironment + {\egroup + \doif{#1}\s!reset\resetMPenvironment % reset mp toks + \doif{#1}\v!global{#3}% % use in main doc too + \doif{#1}+{#3}% % use in main doc too + \defconvertedargument\ascii{#3}% + \expandafter\appendtoks\ascii\to\everyMPTEXgraphic} + +\def\resetMPenvironment + {\everyMPTEXgraphic\emptytoks % = is really needed ! + \startMPenvironment + \global\loadfontfileoncetrue + \stopMPenvironment} + +\resetMPenvironment + +\def\useMPenvironmentbuffer[#1]% + {\expanded{\startMPenvironment\noexpand\readfile{\TEXbufferfile{\jobname}}{}{}}\stopMPenvironment} + +% \useMPenvironmentbuffer[mp] % what was this? + +%D This command takes \type {[reset]} as optional +%D argument. +%D +%D \starttyping +%D \startMPenvironment +%D \setupbodyfont[pos,14.4pt] +%D \stopMPenvironment +%D +%D \startMPcode +%D draw btex \sl Hans Hagen etex scaled 5 ; +%D \stopMPcode +%D \stoptyping +%D +%D The \type {\resetMPenvironment} is a quick way to erase +%D the token list. +%D +%D You should be aware of independencies. For instance, if you use a font +%D in a graphic that is not used in the main document, you need to load the +%D typescript at the outer level (either directly or by using the global +%D option). +%D +%D \starttyping +%D \usetypescript[palatino][texnansi] +%D +%D \startMPenvironment +%D \usetypescript[palatino][texnansi] +%D \enableregime[utf] +%D \setupbodyfont[palatino] +%D \stopMPenvironment +%D +%D \startMPpage +%D draw btex aap‒noot coördinatie – één etex ; +%D \stopMPpage +%D \stoptyping + +%D We don't want spurious files, do we? + +%\def\initializeMPgraphics +% {%\ifx\bufferprefix\empty \else +% \immediate\openout\MPwrite\MPgraphicfile.mp +% \immediate\write\MPwrite{end.}% +% \immediate\closeout\MPwrite +% }%\fi} + +% strange : + +% \def\initializeMPgraphicfile +% {\bgroup +% \doinitializeMPgraphicfile +% \MPruntrue +% \doinitializeMPgraphicfile +% \egroup} + +% \def\doinitializeMPgraphicfile +% {\immediate\openout\scratchwrite\MPgraphicfile.mp +% \immediate\write\scratchwrite{end.}% +% \immediate\closeout\scratchwrite} + +\def\initializeMPgraphicfile + {\immediate\openout\scratchwrite\MPgraphicfile.mp + \immediate\write\scratchwrite{end.}% + \immediate\closeout\scratchwrite} + +\def\initializeMPgraphics + {\bgroup + \initializeMPgraphicfile + \ifx\bufferprefix\empty\else + \let\bufferprefix\empty + \initializeMPgraphicfile + \fi + \egroup} + +%D Loading specific \METAPOST\ related definitions is +%D accomplished by: + +\def\douseMPlibrary#1% + {\ifundefined{\c!file\f!metapostprefix#1}% + \letvalueempty{\c!file\f!metapostprefix#1}% + \makeshortfilename[\truefilename{\f!metapostprefix#1}]% + \startreadingfile + \readsysfile\shortfilename{\showmessage\m!metapost1{#1}}\donothing + \stopreadingfile + \fi} + +\def\useMPlibrary[#1]% + {\processcommalist[#1]\douseMPlibrary} + +%D \macros +%D {setMPtext, MPtext, MPstring, MPbetex} +%D +%D To be documented: +%D +%D \starttyping +%D \setMPtext{identifier}{text} +%D +%D \MPtext {identifier} +%D \MPstring{identifier} +%D \MPbetex {identifier} +%D \stoptyping + +\def\@@MPT{@MPT@} + +\def\forceMPTEXgraphic + {\long\def\checkMPTEXgraphic##1{\global\MPTEXgraphictrue}} + +\def\setMPtext#1#2% todo : #1 must be made : safe + {%\forceMPTEXgraphic + \defconvertedargument\ascii{#2}% + \dodoglobal\letvalue{\@@MPT#1}\ascii} + +% \def\MPtext #1{\getvalue{\@@MPT#1}} +% \def\MPstring #1{"\getvalue{\@@MPT#1}"} +% \def\MPbetex #1{btex \getvalue{\@@MPT#1} etex} + +\def\MPtext #1{\executeifdefined{\@@MPT#1}\empty} +\def\MPstring #1{"\executeifdefined{\@@MPT#1}\empty"} +\def\MPbetex #1{btex \executeifdefined{\@@MPT#1}\empty\space etex} + +%D Unfortunately \METAPOST\ does not have \CMYK\ support +%D built in, but by means of specials we can supply the +%D information needed to handle them naturaly. + +\newif\ifMPcmykcolors \MPcmykcolorstrue +\newif\ifMPspotcolors \MPspotcolorstrue + +\startMPinitializations + cmykcolors:=\ifMPcmykcolors true\else false\fi; + spotcolors:=\ifMPspotcolors true\else false\fi; +\stopMPinitializations + +%D In order to communicate conveniently with the \TEX\ +%D engine, we introduce some typesetting variables. + +% todo : backgroundoffsets + +\startMPextensions + color OverlayColor,OverlayLineColor; +\stopMPextensions + +\startMPinitializations + OverlayWidth:=\overlaywidth; + OverlayHeight:=\overlayheight; + OverlayDepth:=\overlayheight; + OverlayColor:=\MPcolor{\overlaycolor}; + OverlayLineWidth:=\overlaylinewidth; + OverlayLineColor:=\MPcolor{\overlaylinecolor}; + % + BaseLineSkip:=\the\baselineskip; + LineHeight:=\the\baselineskip; + BodyFontSize:=\the\bodyfontsize; + % + TopSkip:=\the\topskip; + StrutHeight:=\strutheight; + StrutDepth:=\strutdepth; + % + CurrentWidth:=\the\hsize; + CurrentHeight:=\the\vsize; + % + EmWidth:=\the\emwidth; + ExHeight:=\the\exheight; + % + PageNumber:=\the\pageno; + RealPageNumber:=\the\realpageno; + LastPageNumber:= \lastpage; +\stopMPinitializations + +\appendtoks + \disablediscretionaries + \disablecompoundcharacters +\to\everyMPgraphic + +% New, experimental (if complaints than only in enco-ffr.mkii), well +% Mojca complained that it does not work with utf-8 and textext, see +% ** in meta-tex. + +\appendtoks + \chardef\activecharactermode\zerocount +\to\everyMPgraphic + +\appendtoks + \expanded{\definecolor[currentcolor][\currentcolorname]}% +\to \everyMPgraphic + +\appendtoks + \baselineskip1\baselineskip + \lineheight 1\lineheight + \topskip 1\topskip +\to \everyMPgraphic + +%D Alas, the prologue settings differ per driver. + +\ifx\undefined\MPprologues \def\MPprologues{0} \fi + +\startMPinitializations + prologues:=\MPprologues; + mpprocset:=1; +\stopMPinitializations + +\appendtoks + \def\MPprologues{0}% + \def\MPOSTdriver{dvips}% +\to \everyresetspecials + +%D \macros +%D {PDFMPformoffset} +%D +%D In \PDF, forms are clipped and therefore we have to take +%D precautions to get this right. Since this is related to +%D objects, we use the same offset as used there. + +\def\PDFMPformoffset{\objectoffset} + +%D \macros +%D {insertMPfile} +%D +%D Bypassing the special driver and figure mechanism is not +%D that nice but saves upto 5\% time in embedding \METAPOST\ +%D graphics by using the low level \PDF\ converter directly, +%D given of course that we use \PDFTEX. As a result we need to +%D fool around with the object trigger. + +\newtoks\everyinsertMPfile + +%D First we present the reasonable fast alternative that we +%D happily used for some time. +%D +%D \starttyping +%D \def\insertMPfile#1#2% +%D {\ifx\undefined\externalfigure +%D \message{[insert file #1 here]}% +%D \else +%D \bgroup +%D \the\everyinsertMPfile +%D \externalfigure +%D [#1] +%D [\c!type=\c!mps,\c!object=\v!no,% +%D \c!symbol=\v!yes,\c!reset=\v!yes,% +%D \c!maxwidth=,\c!maxheight=,% +%D \c!frame=\v!off,\c!background=,% +%D #2]% +%D \egroup +%D \fi} +%D \stoptyping +%D +%D However, on a 1 Gig Pentium, the next alternative saves +%D us 20 seconds run time for the 300 page \METAFUN\ manual: + +\let\insertMPfileARG\insertMPfile + +\def\insertMPfile#1#2% in context #2 is empty + {\doifelsenothing{#2}{\doinsertMPfile{#1}}{\insertMPfileARG{#1}{#2}}} + +\def\includeMPasEPS#1% untested !! + {\bgroup + \message{[MP as EPS #1]}% + \the\everyinsertMPfile + \dogetEPSboundingbox{#1}\!!widtha\!!heighta\!!widthb\!!heightb + \setbox\scratchbox\vbox to \!!heightb + {\vfill + \let \@@DriverImageType \c!mps + \def \@@DriverImageFile {#1}% + \edef\@@DriverImageWidth {\the\!!widthb }% + \edef\@@DriverImageHeight{\the\!!heightb}% + \doinsertfile}% + \wd\scratchbox\!!widthb + \dp\scratchbox\zeropoint + \box\scratchbox + \egroup} + +\def\includeMPasPDF#1% + {\bgroup + \the\everyinsertMPfile + \ifinobject \else \chardef\makeMPintoPDFobject\plustwo \fi % when needed + \convertMPtoPDF{#1}{1}{1}% no \plusone ! + \egroup} + +%D So, using a low level approach (thereby avoiding the slower +%D figure analysis macros) pays off. This kind of +%D optimizations are a bit tricky since we must make sure that +%D special resources end up in the (PDF) files. Because the +%D \METAPOST\ to \PDF\ can handle objects itself, it is not +%D that complicated. + +%D We hook a couple of initializations into the graphic +%D macros. + +\appendtoks + \let\figuretypes\c!mps + \runutilityfilefalse + \consultutilityfilefalse +\to \everyinsertMPfile + +%D One more: (still needed?) + +\startMPextensions + def initialize_form_numbers = + do_initialize_numbers; + enddef; +\stopMPextensions + +\startMPinitializations + HSize:=\the\hsize ; + VSize:=\the\vsize ; +\stopMPinitializations + +\startMPextensions + vardef ForegroundBox = + unitsquare xysized(HSize,VSize) + enddef ; + vardef PageFraction = + if \lastpage>1: (\realfolio-1)/(\lastpage-1) else: 1 fi + enddef ; +\stopMPextensions + +%D And some more. These are not really needed since we +%D don't use the normal figure inclusion macros any longer. + +\appendtoks + \externalfigurepostprocessors\emptytoks % safeguard +\to \everyinsertMPfile + +%D We also take care of disabling fancy figure features, that +%D can terribly interfere when dealing with symbols, +%D background graphics and running (postponed) graphics. +%D You won't believe me if I tell you what funny side effects +%D can occur. One took me over a day to uncover when +%D processing the screen version of the \METAFUN\ manual. + +%D For my eyes only: + +\def\doifelseMPgraphic#1{\doifdefinedelse{\@@MPG#1}} + +%D \macros +%D {startMPcolor} +%D +%D The following time consuming method uses \METAPOST\ to +%D calculate a color. This enables a match between colors +%D resulting from a complex calculation (e.g. for a title +%D page) and those in the text. + +% \startuseMPgraphic{somecolors} +% color c[] ; c[1] := .7[red,green] ; c[2] := .7[blue,yellow] ; +% \stopuseMPgraphic + +% \startMPcolor[shade-1][t=.2,a=1] +% \includeMPgraphic{somecolors} ; fill fullcircle withcolor c[1] ; +% \stopMPcolor + +% \startMPcolor[shade-2][t=.2,a=1] +% \includeMPgraphic{somecolors} ; fill fullcircle withcolor c[2] ; +% \stopMPcolor + +% \blackrule[width=\hsize,height=4cm,color=shade-1] +% \blackrule[width=\hsize,height=4cm,color=shade-2] + +\def\startMPcolor + {\dodoubleempty\dostartMPcolor} + +\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]}}% + \startMPcode#3\stopMPcode + \stopnointerference} + +%D New: + +\definelayerpreset % no dx,dy - else nasty non-mp placement + [mp] + [\c!y=-\MPury bp, + \c!x=\MPllx bp, + \c!method=\v!fit] + +\definelayer + [mp] + [\c!preset=mp] + +%D Usage: +%D +%D \starttyping +%D \defineproperty[one][layer][state=start] +%D \defineproperty[two][layer][state=stop] +%D +%D \startuseMPgraphic{step-1} +%D fill fullcircle scaled 10cm withcolor red ; +%D \stopuseMPgraphic +%D +%D \startuseMPgraphic{step-2} +%D fill fullcircle scaled 5cm withcolor green ; +%D \stopuseMPgraphic +%D +%D \setlayer[mp]{\property[one]{\useMPgraphic{step-1}}} +%D \setlayer[mp]{\property[two]{\useMPgraphic{step-2}}} +%D +%D \ruledhbox{\flushlayer[mp]} +%D \stoptyping +%D +%D Reusing graphics is also possible (now): +%D +%D \starttyping +%D \startreusableMPgraphic{axis} +%D tickstep := 1cm ; ticklength := 2mm ; +%D drawticks unitsquare xscaled 4cm yscaled 3cm shifted (-1cm,-1cm) ; +%D tickstep := tickstep/2 ; ticklength := ticklength/2 ; +%D drawticks unitsquare xscaled 4cm yscaled 3cm shifted (-1cm,-1cm) ; +%D \stopreusableMPgraphic +%D +%D \startuseMPgraphic{demo} +%D drawpoint "1cm,1.5cm" ; +%D \stopuseMPgraphic +%D +%D \definelayer[mp][preset=mp] +%D \setlayer[mp]{\reuseMPgraphic{axis}} +%D \setlayer[mp]{\useMPgraphic{demo}} +%D \ruledhbox{\flushlayer[mp]} +%D \stoptyping + +%D \macros +%D {startstaticMPfigure,useMPstaticfigure} +%D +%D Static figures are processed only when there has been +%D something changed. Here is Aditya Mahajan's testcase: +%D +%D \startbuffer +%D \startstaticMPfigure{circle} +%D fill fullcircle scaled 1cm withcolor blue; +%D \stopstaticMPfigure +%D +%D \startstaticMPfigure{axis} +%D drawarrow (0,0)--(2cm,0) ; +%D drawarrow (0,0)--(0,2cm) ; +%D label.llft(textext("(0,0)") ,origin) ; +%D \stopstaticMPfigure +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +\def\usestaticMPfigure[#1]% + {\dodoubleempty\externalfigure[\jobname-#1.pdf]} + +\def\startstaticMPfigure + {\begingroup + \obeyMPlines + \dostartstaticMPfigure} + +\def\dostartstaticMPfigure#1#2\stopstaticMPfigure + {\startstaticMPgraphic{\jobname-#1}#2\stopstaticMPgraphic + \endgroup} + +% faster, but more tricky +% +% \def\startstaticMPfigure +% {\doifmodeelse{*\v!first} +% {\begingroup +% \obeyMPlines +% \dostartstaticMPfigure} +% {\gobbleuntil\stopstaticMPfigure}} +% +% \def\dostartstaticMPfigure#1#2\stopstaticMPfigure +% {\startMPstaticgraphic{\jobname-#1}#2\stopMPstaticgraphic +% % dirty trick, don't register, so no second main run of texexec: +% \global\advance\nofMPgraphics \minusone +% \endgroup}} + +%D New: + +% \appendtoks \closeMPgraphicfiles \to \everystoptext + +%D New: + +\newconditional\manyMPspecials % when set to true, > 1000 specials can be used + +\settrue \manyMPspecials % per 1/4/2006 + +\prependtoks + _special_div_ := 1000\ifconditional\manyMPspecials0\fi ; +\to \MPextensions + +%D Needed (will become default): + +\prependtoks + \resetlanguagespecifics +\to \everyMPgraphic + +%D Goody for preventing overflows: + +\def\MPdivten[#1]{\withoutpt\the\dimexpr#1pt/10\relax} + +%D Done. + +\protect \endinput + +%D Experimental: + +\appendtoks + \ifrunMPgraphics \ifcase\systemcommandmode \or + \runMPgraphicsfalse + \fi \fi +\to \everyjob + +% also: +% +% linecap := rounded ; +% linejoin := rounded ; +% drawoptions () ; diff --git a/tex/context/base/meta-ini.mkiv b/tex/context/base/meta-ini.mkiv new file mode 100644 index 000000000..61acbca32 --- /dev/null +++ b/tex/context/base/meta-ini.mkiv @@ -0,0 +1,1275 @@ +%D \module +%D [ file=meta-ini, +%D version=2008.03.25, +%D title=\METAPOST\ Graphics, +%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}{MetaPost Graphics / Initializations} + +\unprotect + +%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. + +\let \useMETAFUNformattrue\relax \let \useMETAFUNformatfalse\relax +\let \longMPlinestrue\relax \let \longMPlinesfalse\relax +\let \runMPgraphicstrue\relax \let \runMPgraphicsfalse\relax +\let \runMPTEXgraphicstrue\relax \let \runMPTEXgraphicsfalse\relax +\let \MPstaticgraphictrue\relax \let \MPstaticgraphicfalse\relax +\let\forceMPTEXgraphictrue\relax \let\forceMPTEXgraphicfalse\relax + +\let \obeyMPlines\relax +\let \forceMPTEXcheck\gobbleoneargument +\let\maxnofMPgraphics\scratchcounter + +\newtoks \MPextensions % mp, once +\newtoks \MPinitializations % tex, each +\newtoks \MPuserinclusions % mp, user +\newtoks \MPfinalizations % mp, user +\newtoks \everyMPgraphic % mp +\newtoks \everyMPTEXgraphic % tex + +\newif\ifMPrun +\def\MPruntimefile{mprun} + +% 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}} + +\long\def\startMPinitializations#1\stopMPinitializations + {\global\MPinitializations\expandafter{\the\MPinitializations#1}} + +\long\def\startMPinclusions + {\dosingleempty\dostartMPinclusions} + +\long\def\dostartMPinclusions[#1]#2\stopMPinclusions + {\doifnot{#1}{+}{\global\MPuserinclusions\emptytoks}% + \global\MPuserinclusions\expandafter{\the\MPuserinclusions#2}} + +\def\MPinclusions + {\dosingleempty\doMPinclusions} + +\long\def\doMPinclusions[#1]#2% + {\doifnot{#1}{+}{\global\MPuserinclusions\emptytoks}% + \global\MPuserinclusions\expandafter{\the\MPuserinclusions#2}} + +\def\presetMPdefinitions + {\edef\overlaywidth {\overlaywidth \space}% + \edef\overlayheight {\overlayheight \space}% + \edef\overlaylinewidth{\overlaylinewidth\space}% + \edef\currentwidth {\the\hsize \space}% + \edef\currentheight {\the\vsize \space}} + +\def\currentMPformat{metafun} + +\def\@@MPF{@MPF@} + +\def\MPinstancetoks{\csname\@@MPF::\currentMPgraphicinstance\endcsname} + +\unexpanded\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 + {\ifcsname\@@MPF\currentMPgraphicinstance\s!format\endcsname + \csname\@@MPF\currentMPgraphicinstance\s!format\endcsname + \else + \defaultMPgraphicinstance + \fi}} + +\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[mprun] [\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 + +\def\MPaskedfigure{false} + +\def\currentMPinitializations + {\ifconditional\includeMPinitializations\the\MPinitializations;\fi\theMPrandomseed;} + +\def\currentMPpreamble + {\ifconditional\includeMPextensions\the\MPextensions;\the\MPuserinclusions;\fi\the\MPinstancetoks;} + +\def\dostartcurrentMPgraphic + {\begingroup + \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}% + {\setfalse\includeMPinitializations}} + +\def\dostopcurrentMPgraphic + {\global\MPinstancetoks\emptytoks + \global\settrue\METAFUNinitialized % becomes obsolete + \endgroup} + +\unexpanded\long\def\processMPgraphic#1% todo: extensions and inclusions outside beginfig + {\dostartcurrentMPgraphic + \forgetall + \setbox\MPgraphicbox\hbox\bgroup + \normalexpanded{\noexpand\ctxlua{metapost.graphic( + "\currentMPgraphicinstance", + "\currentMPgraphicformat", + \!!bs#1\!!es, + \!!bs\currentMPinitializations\!!es, + \!!bs\currentMPpreamble\!!es, + \MPaskedfigure + )}}% + \egroup + \placeMPgraphic + \dostopcurrentMPgraphic} + +\newif\ifsetMPrandomseed \setMPrandomseedtrue % false by default + +\def\setMPrandomseed + {\let\theMPrandomseed\empty + \ifsetMPrandomseed \ifx\getrandomnumber\undefined \else + \getrandomnumber\localMPseed\zerocount{4095}% + \def\theMPrandomseed{randomseed:=\localMPseed}% + \fi\fi} + +%D To be integrated + +\def\@@MPG{@MPG@} + +\def\doifMPgraphicelse#1% + {\ifcsname\@@MPG#1\endcsname\expandafter\firstoftwoarguments\else\expandafter\secondoftwoarguments\fi} + +\def\includeMPgraphic#1% + {\executeifdefined{\@@MPG#1};} % ; if not found + +\def\enableincludeMPgraphics + {\let\handleuseMPgraphic \thirdofthreearguments + \let\handlereusableMPgraphic\thirdofthreearguments} + +\let\MPdrawingdata\empty + +\newif\ifMPdrawingdone \MPdrawingdonefalse + +\def\resetMPdrawing + {\globallet\MPdrawingdata\empty + \global\MPdrawingdonefalse} + +\def\pushMPdrawing + {\globalpushmacro\MPdrawingdata + \globallet\MPdrawingdata\empty} + +\def\popMPdrawing + {\globalpopmacro\MPdrawingdata} + +\def\getMPdrawing{\dosinglegroupempty\dogetMPdrawing} + +\def\startMPdrawing + {\dosingleempty\dostartMPdrawing} + +\long\def\dostartMPdrawing[#1]#2\stopMPdrawing + {\relax + \bgroup + \enableincludeMPgraphics + \presetMPdefinitions % in case #2 has measures + \doifelse{#1}{-}{\convertargument#2\to\asciia}{\long\def\asciia{#2}}% + \long\xdef\MPdrawingdata{\MPdrawingdata\asciia}% + \egroup} + +\let\stopMPdrawing\relax + +\let\MPdrawingdata\empty + +\newif\ifMPshiftdrawing \MPshiftdrawingfalse + +\def\resetMPdrawing + {\globallet\MPdrawingdata\empty + \global\MPdrawingdonefalse} + +\def\pushMPdrawing + {\globalpushmacro\MPdrawingdata + \globallet\MPdrawingdata\empty} + +\def\popMPdrawing + {\globalpopmacro\MPdrawingdata} + +\def\getMPdrawing + {\ifMPdrawingdone + \expandafter\processMPgraphic\expandafter{\MPdrawingdata}% is this expansion still needed? + \fi} + +\def\startMPdrawing + {\dosingleempty\dostartMPdrawing} + +\long\def\dostartMPdrawing[#1]#2\stopMPdrawing + {\relax + \bgroup + \enableincludeMPgraphics + \presetMPdefinitions % in case #2 has measures + \doifelse{#1}{-}{\convertargument#2\to\asciia}{\long\def\asciia{#2}}% + \long\xdef\MPdrawingdata{\MPdrawingdata\asciia}% + \egroup} + +\let\stopMPdrawing\relax + +\let\stopMPclip\relax + +\long\def\startMPclip#1#2\stopMPclip % todo: store at the lua end or just store less + {\long\setgvalue{MPC:#1}{#2}} + +\def\grabMPclippath#1#2#3#4#5% #5 is alternative + {\begingroup + \edef\width {#3\space}\let\overlaywidth \width + \edef\height{#4\space}\let\overlayheight\height + \ifcsname MPC:#1\endcsname + \dostartcurrentMPgraphic + \xdef\MPclippath{\normalexpanded{\noexpand\ctxlua{metapost.theclippath( + "\currentMPgraphicinstance", + "\currentMPgraphicformat", + \!!bs\getvalue{MPC:#1}\!!es, + \!!bs\currentMPinitializations\!!es, + \!!bs\currentMPpreamble\!!es + )}}}% + \dostopcurrentMPgraphic + \ifx\MPclippath\empty\xdef\MPclippath{#5}\fi + \else + \xdef\MPclippath{#5}% + \fi + % #2 : method is obsolete, only pdf now, we can always + % gsub the result to ps + \endgroup} + +%D Next we will use these support macros. + +\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; +\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 + +% 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 + +%D A signal that we're in combines \CONTEXT||\METAFUN mode: + +\startMPextensions + string contextversion; + contextversion:="\contextversion"; +\stopMPextensions + +%D Some safeguards: +%D +%D \starttyping +%D \appendtoks \cleanupfeatures \to \everyMPgraphic +%D \stoptyping +%D +%D No, we don't want that (else we loose UTF etc). + +%D Another one: + +\prependtoks \MPstaticgraphictrue \to \everyoverlay +\prependtoks \MPstaticgraphictrue \to \everypagebody + +%D \macros +%D {setupMPvariables} +%D +%D When we build collections of \METAPOST\ graphics, like +%D background and buttons, the need for passing settings +%D arises. By (mis|)|using the local prefix that belongs to +%D \type {\framed}, we get a rather natural interface to +%D backgrounds. To prevent conflicts, we will use the \type +%D {-} in \METAPOST\ specific variables, like: +%D +%D \starttyping +%D \setupMPvariables[meta:button][size=20pt] +%D \stoptyping + +\def\@@meta{meta:} + +\unexpanded\def\setupMPvariables + {\dodoubleempty\dosetupMPvariables} + +\def\dosetupMPvariables[#1][#2]% + {\ifsecondargument + \getrawparameters[#1:][#2]% brr, todo: [\@@meta#1:] + \else + \getrawparameters[\@@meta][#1]% + \fi} + +\let\@@framed\s!unknown + +\def\MPvariable#1% + {\csname + \ifcsname\@@framed\@@meta#1\endcsname\@@framed\fi\@@meta#1% + \endcsname} + +\let\MPvar\MPvariable + +\let\setMPvariables\setupMPvariables + +\def\MPrawvar#1#2{\csname#1:#2\endcsname} + +\def\presetMPvariable + {\dodoubleargument\dopresetMPvariable} + +\def\dopresetMPvariable[#1][#2=#3]% + {\ifcsname#1:#2\endcsname\else\setvalue{#1:#2}{#3}\fi} + +\def\useMPvariables + {\dodoubleargument\douseMPvariables} + +\def\douseMPvariables[#1][#2]% + {\def\@@meta{#1:}% + \prepareMPvariables{#2}} + +%D \macros +%D {startuniqueMPgraphic, uniqueMPgraphic} +%D +%D This macros is probably of most use to myself, since I like +%D to use graphics that adapt themselves. The next \METAPOST\ +%D kind of graphic is both unique and reused when possible. +%D +%D \starttyping +%D \defineoverlay[example][\uniqueMPgraphic{test}] +%D +%D \startuniqueMPgraphic {test} +%D draw unitsquare xscaled \overlaywidth yscaled \overlayheight ; +%D \stopuniqueMPgraphic +%D \stoptyping + +\def\overlaystamp % watch the \MPcolor, since colors can be redefined + {\overlaywidth:\overlayheight:\overlaydepth:\MPcolor\overlaycolor:\MPcolor\overlaylinecolor} + +%D A better approach is to let additional variables play a role +%D in determining the uniqueness. In the next macro, the +%D second, optional, argument is used to guarantee the +%D uniqueness, as well as prepare variables for passing them to +%D \METAPOST. +%D +%D \starttyping +%D \startuniqueMPgraphic{meta:hash}{gap,angle,...} +%D \stoptyping +%D +%D The calling macro also accepts a second argument. For +%D convenient use in overlay definitions, we use \type {{}} +%D instead of \type {[]}. +%D +%D \starttyping +%D \uniqueMPgraphic{meta:hash}{gap=10pt,angle=30} +%D \stoptyping + +\newcount\MPobjectcounter +\newbox \MPgraphicbox + +\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 + +\unexpanded\def\placeMPgraphic + {\ifcase\MPboxmode + \or % 1 + \doobeyMPboxdepth + \or % 2 + \doignoreMPboxdepth + \fi + \box\MPgraphicbox} + +\def\reuseMPbox#1#2#3#4#5% space delimiting would save some tokens + {\xdef\MPllx{#2}% but it's not worth the effort and looks + \xdef\MPlly{#3}% ugly as well + \xdef\MPurx{#4}% + \xdef\MPury{#5}% + \hbox{\forcecolorhack\getobject{MP}{#1}}} % else no proper color intent + +\long\def\handleuniqueMPgraphic#1#2#3% + {\begingroup + \def\@@meta{#1:}% + \extendMPoverlaystamp{#2}% incl prepare + \ifcsname\@@MPG\overlaystamp:#1\endcsname\else + \enableincludeMPgraphics % redundant + \global\advance\MPobjectcounter\plusone + \setobject{MP}{\number\MPobjectcounter}\hbox{\processMPgraphic{#3}}% was vbox, graphic must end up as hbox + \setxvalue{\@@MPG\overlaystamp:#1}{\noexpand\reuseMPbox{\number\MPobjectcounter}{\MPllx}{\MPlly}{\MPurx}{\MPury}}% + \fi + \getvalue{\@@MPG\overlaystamp:#1}% + \endgroup} + +\long\unexpanded\def\startuniqueMPgraphic + {\dodoublegroupempty\dostartuniqueMPgraphic} + +\long\def\dostartuniqueMPgraphic#1#2#3\stopuniqueMPgraphic% + {\long\setgvalue{\@@MPG#1}{\handleuniqueMPgraphic{#1}{#2}{#3}}} + +\unexpanded\def\uniqueMPgraphic + {\dodoublegroupempty\douniqueMPgraphic} + +\def\douniqueMPgraphic#1#2% + {\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% + {\begingroup + \def\@@meta{#1:}% + \prepareMPvariables{#2}% + \enableincludeMPgraphics % redundant + \processMPgraphic{#3}% + \endgroup} + +\long\unexpanded\def\startuseMPgraphic + {\dodoublegroupempty\dostartuseMPgraphic} + +\long\def\dostartuseMPgraphic#1#2#3\stopuseMPgraphic + {\long\setgvalue{\@@MPG#1}{\handleuseMPgraphic{#1}{#2}{#3}}} + +\long\unexpanded\def\startusableMPgraphic % redundant but handy + {\dodoublegroupempty\dostartusableMPgraphic} + +\long\def\dostartusableMPgraphic#1#2#3\stopusableMPgraphic + {\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% + {\begingroup + \def\@@meta{#1:}% + \prepareMPvariables{#2}% + \enableincludeMPgraphics % redundant + \global\advance\MPobjectcounter\plusone + \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}% + \endgroup} + +\long\unexpanded\def\startreusableMPgraphic + {\dodoublegroupempty\dostartreusableMPgraphic} + +\long\def\dostartreusableMPgraphic#1#2#3\stopreusableMPgraphic + {\long\setgvalue{\@@MPG#1}{\handlereusableMPgraphic{#1}{#2}{#3}}} + +\let\stopreusableMPgraphic \relax % so that we can use it in \expanded + +\unexpanded\def\useMPgraphic + {\dodoublegroupempty\douseMPgraphic} + +\def\douseMPgraphic#1#2% + {\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 + +\let\stopuseMPcode \relax % so that we can use it in \expanded +\let\stopusableMPcode \relax % so that we can use it in \expanded +\let\stopreusableMPcode \relax % so that we can use it in \expanded +\let\stopuniqueMPcode \relax % so that we can use it in \expanded + +\def\enableincludeMPgraphics + {\let\handleuseMPgraphic \thirdofthreearguments + \let\handlereusableMPgraphic\thirdofthreearguments} + +%D \macros +%D {startuniqueMPpagegraphic,uniqueMPpagegraphic} +%D +%D Experimental. + +\def\MPpageprefix{\doifoddpageelse oe:} + +\def\overlaypagestamp + {\MPpageprefix\overlaywidth:\overlayheight:\overlaydepth:\MPcolor\overlaycolor:\MPcolor\overlaylinecolor} + +\long\unexpanded\def\startuniqueMPpagegraphic + {\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}}} + +\unexpanded\def\uniqueMPpagegraphic + {\dodoublegroupempty\douniqueMPpagegraphic} + +\def\douniqueMPpagegraphic#1#2% + {\beginMPgraphicgroup{#1}% + \let\overlaystamp\overlaypagestamp + \setupMPvariables[\MPpageprefix\currentMPgraphicname][#2]% prefix is new here + \getvalue{\@@MPG\MPpageprefix\currentMPgraphicname}{}% + \endMPgraphicgroup} + +%D One way of defining a stamp is: +%D +%D \starttyping +%D \def\extendMPoverlaystamp#1% +%D {\def\docommand##1% +%D {\edef\overlaystamp{\overlaystamp:\MPvariable{##1}}}% +%D \processcommalist[#1]\docommand} +%D \stoptyping + +%D Since we need to feed \METAPOST\ with expanded dimensions, +%D we introduce a dedicated expansion engine. + +\def\prepareMPvariable#1% + {\ifcsname\@@framed\@@meta#1\endcsname + \doprepareMPvariable{\@@framed\@@meta#1}% + \else + \doprepareMPvariable{\@@meta#1}% + \fi} + +% \startlines +% \def\xxx{\lineheight} \doprepareMPvariable{xxx} \xxx +% \def\xxx{2pt} \doprepareMPvariable{xxx} \xxx +% \def\xxx{2} \doprepareMPvariable{xxx} \xxx +% \def\xxx{\scratchcounter} \doprepareMPvariable{xxx} \xxx +% \def\xxx{red} \doprepareMPvariable{xxx} \xxx +% \def\xxx{0.4} \doprepareMPvariable{xxx} \xxx +% \stoplines + +\def\doprepareMPvariable#1% + {\edef\theMPvariable{\getvalue{#1}}% + \doifelsenothing\theMPvariable + {\setevalue{#1}{\MPcolor{black}}} + {\defconvertedcommand\ascii\theMPvariable % otherwise problems + \doifcolorelse \ascii % with 2\bodyfontsize + {\setevalue{#1}{\MPcolor\theMPvariable}} + {% can be aux macro + \setbox\scratchbox\hbox{\scratchdimen\theMPvariable sp}% + \ifdim\wd\scratchbox=\zeropoint + % \scratchcounter\theMPvariable + % \setevalue{#1}{\the\scratchcounter}% + % also accepts 0.number : + \setevalue{#1}{\number\theMPvariable}% + \else + \scratchdimen\theMPvariable + \setevalue{#1}{\the\scratchdimen}% + \fi}}} + +%D We redefine \type {\extendMPoverlaystamp} to preprocess +%D variables using \type {\prepareMPvariable}. + +\def\doextendMPoverlaystamp#1% + {\prepareMPvariable{#1}% + \edef\overlaystamp{\overlaystamp:\MPvariable{#1}}} + +\def\extendMPoverlaystamp#1% + {\processcommalist[#1]\doextendMPoverlaystamp} + +\def\prepareMPvariables#1% + {\processcommalist[#1]\prepareMPvariable} + +%D \macros +%D {MPdatafile} +%D +%D We redefine a macro from \type {supp-mps.tex}: + +\def\MPdataMPDfile{\jobname-mpgraph.mpd} +\def\MPdataMPOfile{\jobname-mpgraph.mpo} +\def\MPdataMPYfile{\jobname-mpgraph.mpy} + +\startMPextensions + boolean collapse_data; collapse_data:=true; + def data_mpd_file = "\MPdataMPDfile" enddef ; + def data_mpo_file = "\MPdataMPOfile" enddef ; + def data_mpy_file = "\MPdataMPYfile" enddef ; +\stopMPextensions + +\chardef\currentMPgraphic\plusone + +\def\getMPdata + {\let\MPdata\secondoftwoarguments + \startreadingfile + % \startnointerference % no, else we need to do all data global + \readlocfile\MPdataMPDfile\donothing\donothing + % \stopnointerference + \stopreadingfile} + +%D \macros +%D {MPrunfile} +%D +%D This one is more abstract and does not assume knowledge +%D of buffer prefixes. + +\def\MPrunfile#1% + {\bufferprefix mprun.#1} + +%D For the moment, the next one is a private macro: + +\def\processMPbuffer + {\dosingleempty\doprocessMPbuffer} + +\def\doprocessMPbuffer[#1]% + {\doifelsenothing{#1} + {\dodoprocessMPbuffer{\jobname}} + {\dodoprocessMPbuffer{#1}}} + +% we need to go via a toks because we have no multiline print in +% luatex (i.e. tex.sprint does not interpret lines) and therefore +% omits all after a comment token + +\newtoks\mpbuffertoks + +\def\doprocessMPbuffer[#1]% + {\doifelsenothing{#1} + {\doprocessMPbuffer[\jobname]} + {\beginMPgraphicgroup{#1}% + % we need this trick because tex.sprint does not interprets newlines and the scanner + % stops at a newline; also, we do need to flush the buffer under a normal catcode + % regime in order to expand embedded tex macros; #1 can be a list + \processMPgraphic{\ctxlua{buffers.feedback("\currentMPgraphicname")}}% + \endMPgraphicgroup}} + +\def\runMPbuffer + {\dosingleempty\dorunMPbuffer} + +\def\dorunMPbuffer[#1]% processing only + {\startnointerference\doprocessMPbuffer[#1]\stopnointerference} + +%D \macros +%D {startMPenvironment, resetMPenvironment} +%D +%D In order to synchronize the main \TEX\ run and the runs +%D local to \METAPOST, environments can be passed. + +\ifx\everyMPTEXgraphic\undefined + \newtoks\everyMPTEXgraphic +\fi + +%D A more general way of passing environments is: + +\def\startMPenvironment % second arg gobbles spaces, so that reset gives \emptytoks + {\dodoubleempty\dostartMPenvironment} + +\long\def\dostartMPenvironment[#1][#2]#3\stopMPenvironment + {\doif{#1}\s!reset\resetMPenvironment % reset mp toks + \doif{#1}\v!global{#3}% % use in main doc too + \doif{#1}+{#3}% % use in main doc too + \ctxlua{metapost.tex.set(\!!bs\detokenize{#3}\!!es)}} + +\def\resetMPenvironment + {\ctxlua{metapost.tex.reset()}} + +\resetMPenvironment + +\def\useMPenvironmentbuffer[#1]% + {\ctxlua{metapost.tex.set(buffers.content("#1"))}} + +%D This command takes \type {[reset]} as optional +%D argument. +%D +%D \starttyping +%D \startMPenvironment +%D \setupbodyfont[pos,14.4pt] +%D \stopMPenvironment +%D +%D \startMPcode +%D draw btex \sl Hans Hagen etex scaled 5 ; +%D \stopMPcode +%D \stoptyping +%D +%D The most simple case: + +\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 + +% a bit nasty (also needed for compatibility: + +% \startMPrun input mp-www.mp ; \stopMPrun +% \externalfigure[mprun.3][width=10cm,height=8cm] + +% \startMPrun{mprun} input mp-www.mp ; \stopMPrun % instance +% \externalfigure[mprun.4][width=10cm,height=8cm] + +\let\MPruninstance\defaultMPgraphicinstance + +\def\useMPrun#1#2% name n + {\begingroup + \def\MPaskedfigure{#2}% + \doifelsenothing{#1} + {\useMPgraphic{mprun}}% + {\useMPgraphic{#1}}% + \endgroup} + +\def\startMPrun + {\dosinglegroupempty\dostartMPrun} + +\long\def\dostartMPrun#1#2\stopMPrun + {\iffirstargument + \startuseMPgraphic{#1}#2\stopuseMPgraphic + \else + \startuseMPgraphic{mprun}#2\stopuseMPgraphic + \fi} + +% for old time sake + +\def\dostartMPgraphic + {\iffirstargument + \expandafter\dodostartMPgraphic + \else + \expandafter\nodostartMPgraphic + \fi} + +\def\dodostartMPgraphic#1#2\stopMPgraphic + {\beginMPgraphicgroup{#1::\s!dummy}% name does not matter + \processMPgraphic{#2}% + \endMPgraphicgroup} + +\def\nodostartMPgraphic#1#2\stopMPcode + {\processMPgraphic{#2}} + +\let\stopMPcode\relax + +%D The \type {\resetMPenvironment} is a quick way to erase +%D the token list. +%D +%D You should be aware of independencies. For instance, if you use a font +%D in a graphic that is not used in the main document, you need to load the +%D typescript at the outer level (either directly or by using the global +%D option). +%D +%D \starttyping +%D \usetypescript[palatino][texnansi] +%D +%D \startMPenvironment +%D \usetypescript[palatino][texnansi] +%D \enableregime[utf] +%D \setupbodyfont[palatino] +%D \stopMPenvironment +%D +%D \startMPpage +%D draw btex aap‒noot coördinatie – één etex ; +%D \stopMPpage +%D \stoptyping + +%D Loading specific \METAPOST\ related definitions is +%D accomplished by: + +\def\douseMPlibrary#1% + {\ifcsname\c!file\f!metapostprefix#1\endcsname\else + \letvalueempty{\c!file\f!metapostprefix#1}% + \makeshortfilename[\truefilename{\f!metapostprefix#1}]% + \startreadingfile + \readsysfile\shortfilename{\showmessage\m!metapost1{#1}}\donothing + \stopreadingfile + \fi} + +\def\useMPlibrary[#1]% + {\processcommalist[#1]\douseMPlibrary} + +%D \macros +%D {setMPtext, MPtext, MPstring, MPbetex} +%D +%D To be documented: +%D +%D \starttyping +%D \setMPtext{identifier}{text} +%D +%D \MPtext {identifier} +%D \MPstring{identifier} +%D \MPbetex {identifier} +%D \stoptyping + +\def\@@MPT{@MPT@} + +\def\forceMPTEXgraphic + {\long\def\checkMPTEXgraphic##1{\global\MPTEXgraphictrue}} + +\def\setMPtext#1#2% todo : #1 must be made : safe + {%\forceMPTEXgraphic + \defconvertedargument\ascii{#2}% + \dodoglobal\letvalue{\@@MPT#1}\ascii} + +\def\MPtext #1{\executeifdefined{\@@MPT#1}\empty} +\def\MPstring #1{"\executeifdefined{\@@MPT#1}\empty"} +\def\MPbetex #1{btex \executeifdefined{\@@MPT#1}\empty\space etex} + +%D Unfortunately \METAPOST\ does not have \CMYK\ support +%D built in, but by means of specials we can supply the +%D information needed to handle them naturaly. + +% \newif\ifMPcmykcolors \MPcmykcolorstrue +% \newif\ifMPspotcolors \MPspotcolorstrue + +\startMPinitializations + cmykcolors:=\ifMPcmykcolors true\else false\fi; + spotcolors:=\ifMPspotcolors true\else false\fi; +\stopMPinitializations + +%D In order to communicate conveniently with the \TEX\ +%D engine, we introduce some typesetting variables. + +\startMPextensions + color OverlayColor,OverlayLineColor; +\stopMPextensions + +\startMPinitializations + OverlayWidth:=\overlaywidth; + OverlayHeight:=\overlayheight; + OverlayDepth:=\overlayheight; + OverlayColor:=\MPcolor{\overlaycolor}; + OverlayLineWidth:=\overlaylinewidth; + OverlayLineColor:=\MPcolor{\overlaylinecolor}; + % + BaseLineSkip:=\the\baselineskip; + LineHeight:=\the\baselineskip; + BodyFontSize:=\the\bodyfontsize; + % + TopSkip:=\the\topskip; + StrutHeight:=\strutheight; + StrutDepth:=\strutdepth; + % + CurrentWidth:=\the\hsize; + CurrentHeight:=\the\vsize; + % + EmWidth:=\the\emwidth; + ExHeight:=\the\exheight; + % + PageNumber:=\the\pageno; + RealPageNumber:=\the\realpageno; + LastPageNumber:= \lastpage; +\stopMPinitializations + +\appendtoks + \disablediscretionaries + \disablecompoundcharacters +\to \everyMPgraphic + +\appendtoks % before color + %\normalexpanded{\noexpand\definecolor[currentcolor][\currentcolorname]}% + \doregistercolor{currentcolor}\currentcolorname +\to \everyMPgraphic + +% \color[green]{abc \startMPcode +% fill fullcircle scaled 3cm withoutcolor; +% fill fullcircle scaled 2cm withcolor \MPcolor{currentcolor} ; +% fill fullcircle scaled 1cm withcolor \MPcolor{red} ; +% \stopMPcode def} + +% \appendtoks +% \doactivatecolor\s!black\forcecolorhack % we can also move this to the backend +% \to \everyMPgraphic + +\appendtoks + \baselineskip1\baselineskip + \lineheight 1\lineheight + \topskip 1\topskip +\to \everyMPgraphic + +\appendtoks + \let \# \letterhash + \let \_ \letterunderscore + \let \& \letterampersand + \let \{ \letteropenbrace + \let \} \letterclosebrace +\to \everyMPgraphic + +\startMPinitializations + prologues:=0; + mpprocset:=1; +\stopMPinitializations + +%D \macros +%D {PDFMPformoffset} +%D +%D In \PDF, forms are clipped and therefore we have to take +%D precautions to get this right. Since this is related to +%D objects, we use the same offset as used there. + +\def\PDFMPformoffset{\objectoffset} + +% %D \macros +% %D {insertMPfile} +% %D +% %D Bypassing the special driver and figure mechanism is not +% %D that nice but saves upto 5\% time in embedding \METAPOST\ +% %D graphics by using the low level \PDF\ converter directly, +% %D given of course that we use \PDFTEX. As a result we need to +% %D fool around with the object trigger. + +\newtoks\everyinsertMPfile + +% removed in backend: +% +% \def\doinsertMPfile#1% +% {\doiffileelse{./#1}{\includeMPasPDF{./#1}}{\message{[MP #1]}}} +% +% \let\insertMPfileARG\insertMPfile +% +% \def\insertMPfile#1#2% in context #2 is empty +% {\doifelsenothing{#2}{\doinsertMPfile{#1}}{\insertMPfileARG{#1}{#2}}} +% +% \def\includeMPasEPS#1% untested !! +% {\bgroup +% \message{[MP as EPS #1]}% +% \the\everyinsertMPfile +% \dogetEPSboundingbox{#1}\!!widtha\!!heighta\!!widthb\!!heightb +% \setbox\scratchbox\vbox to \!!heightb +% {\vfill +% \let \@@DriverImageType \c!mps +% \def \@@DriverImageFile {#1}% +% \edef\@@DriverImageWidth {\the\!!widthb }% +% \edef\@@DriverImageHeight{\the\!!heightb}% +% \doinsertfile}% +% \wd\scratchbox\!!widthb +% \dp\scratchbox\zeropoint +% \box\scratchbox +% \egroup} +% +% \def\includeMPasPDF#1% +% {\bgroup +% \the\everyinsertMPfile +% \ifinobject \else \chardef\makeMPintoPDFobject\plustwo \fi % when needed +% \convertMPtoPDF{#1}{1}{1}% no \plusone ! +% \egroup} +% +% %D So, using a low level approach (thereby avoiding the slower +% %D figure analysis macros) pays off. This kind of +% %D optimizations are a bit tricky since we must make sure that +% %D special resources end up in the (PDF) files. Because the +% %D \METAPOST\ to \PDF\ can handle objects itself, it is not +% %D that complicated. +% +% %D We hook a couple of initializations into the graphic +% %D macros. +% +% \appendtoks +% \let\figuretypes\c!mps +% \runutilityfilefalse +% \consultutilityfilefalse +% \to \everyinsertMPfile +% +% %D One more: (still needed?) + +\startMPextensions + def initialize_form_numbers = + do_initialize_numbers; + enddef; +\stopMPextensions + +\startMPinitializations + HSize:=\the\hsize ; + VSize:=\the\vsize ; +\stopMPinitializations + +\startMPextensions + vardef ForegroundBox = + unitsquare xysized(HSize,VSize) + enddef ; + vardef PageFraction = + if \lastpage>1: (\realfolio-1)/(\lastpage-1) else: 1 fi + enddef ; +\stopMPextensions + +%D And some more. These are not really needed since we +%D don't use the normal figure inclusion macros any longer. + +\appendtoks + \externalfigurepostprocessors\emptytoks % safeguard +\to \everyinsertMPfile + +%D We also take care of disabling fancy figure features, that +%D can terribly interfere when dealing with symbols, +%D background graphics and running (postponed) graphics. +%D You won't believe me if I tell you what funny side effects +%D can occur. One took me over a day to uncover when +%D processing the screen version of the \METAFUN\ manual. + +%D For my eyes only: + +\def\doifelseMPgraphic#1{\doifdefinedelse{\@@MPG#1}} + +%D \macros +%D {startMPcolor} + +\long\unexpanded\def\startMPcolor#1\stopMPcolor + {\writestatus \m!metapost % eventually this placeholder will go away + {\string\startMPcolor...\stopMPcolor\space is obsolete,\space + use \string\defineintermediatecolor\space instead}} + +\let\stopMPcolor\relax + +%D New: + +\definelayerpreset % no dx,dy - else nasty non-mp placement + [mp] + [\c!y=-\MPury bp, + \c!x=\MPllx bp, + \c!method=\v!fit] + +\definelayer + [mp] + [\c!preset=mp] + +%D Usage: +%D +%D \starttyping +%D \defineproperty[one][layer][state=start] +%D \defineproperty[two][layer][state=stop] +%D +%D \startuseMPgraphic{step-1} +%D fill fullcircle scaled 10cm withcolor red ; +%D \stopuseMPgraphic +%D +%D \startuseMPgraphic{step-2} +%D fill fullcircle scaled 5cm withcolor green ; +%D \stopuseMPgraphic +%D +%D \setlayer[mp]{\property[one]{\useMPgraphic{step-1}}} +%D \setlayer[mp]{\property[two]{\useMPgraphic{step-2}}} +%D +%D \ruledhbox{\flushlayer[mp]} +%D \stoptyping +%D +%D Reusing graphics is also possible (now): +%D +%D \starttyping +%D \startreusableMPgraphic{axis} +%D tickstep := 1cm ; ticklength := 2mm ; +%D drawticks unitsquare xscaled 4cm yscaled 3cm shifted (-1cm,-1cm) ; +%D tickstep := tickstep/2 ; ticklength := ticklength/2 ; +%D drawticks unitsquare xscaled 4cm yscaled 3cm shifted (-1cm,-1cm) ; +%D \stopreusableMPgraphic +%D +%D \startuseMPgraphic{demo} +%D drawpoint "1cm,1.5cm" ; +%D \stopuseMPgraphic +%D +%D \definelayer[mp][preset=mp] +%D \setlayer[mp]{\reuseMPgraphic{axis}} +%D \setlayer[mp]{\useMPgraphic{demo}} +%D \ruledhbox{\flushlayer[mp]} +%D \stoptyping + +%D \macros +%D {startstaticMPfigure,useMPstaticfigure} +%D +%D Static figures are processed only when there has been +%D something changed. Here is Aditya Mahajan's testcase: +%D +%D \startbuffer +%D \startstaticMPfigure{circle} +%D fill fullcircle scaled 1cm withcolor blue; +%D \stopstaticMPfigure +%D +%D \startstaticMPfigure{axis} +%D drawarrow (0,0)--(2cm,0) ; +%D drawarrow (0,0)--(0,2cm) ; +%D label.llft(textext("(0,0)") ,origin) ; +%D \stopstaticMPfigure +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +\def\usestaticMPfigure + {\dodoubleempty\dousestaticMPfigure} + +\def\dousestaticMPfigure[#1][#2]% + {\ifsecondargument + \scale[#2]{\reuseMPgraphic{\@@MPG#1@S@}}% + \else + \reuseMPgraphic{\@@MPG#1@S@}% + \fi} + +\unexpanded\def\startstaticMPfigure#1#2\stopstaticMPfigure + {\startreusableMPgraphic{\@@MPG#1@S@}#2\stopreusableMPgraphic} + +\long\unexpanded\def\startstaticMPgraphic + {\dodoublegroupempty\dostartstaticMPgraphic} + +\long\def\dostartstaticMPgraphic#1#2#3\stopstaticMPgraphic + {\long\setgvalue{\@@MPG#1@S@}{\handlereusableMPgraphic{#1}{#2}{#3}}} + +%D New: + +\newconditional\manyMPspecials % when set to true, > 1000 specials can be used + +\settrue \manyMPspecials % per 1/4/2006 + +\prependtoks + _special_div_ := 1000\ifconditional\manyMPspecials0\fi ; +\to \MPextensions + +%D Needed too. + +\let\initializeMPgraphics\relax + +%D Goody for preventing overflows: + +\def\MPdivten[#1]{\withoutpt\the\dimexpr#1pt/10\relax} + +%D There is no way to distinguish the black color that you get when +%D you issue a \type {draw} without color specification from a color +%D that has an explicit black specification unless you set the +%D variable \type {defaultcolormodel} to 1. Hoewever, in that case +%D you cannot distinguish that draw from one with a \type +%D {withoutcolor} specification. This means that we have to provide +%D multiple variants of inheritance. +%D +%D In any case we need to tell the converter what the inherited color +%D is to start with. Case~3 is kind of unpredictable as it closely +%D relates to the order in which paths are flushed. If you want to +%Dinherit automatically from the surrounding, you can best stick to +%D variant 1. Variant 0 (an isolated graphic) is the default. +%D +%D \startbuffer +%D \startuseMPgraphic{test} +%D drawoptions(withpen pencircle scaled 1pt) ; +%D def shift_cp = currentpicture := currentpicture shifted (-15pt,0) ; enddef ; +%D draw fullcircle scaled 10pt withoutcolor ; shift_cp ; +%D fill fullcircle scaled 10pt ; shift_cp ; +%D draw fullcircle scaled 10pt withoutcolor ; shift_cp ; +%D fill fullcircle scaled 10pt withcolor red ; shift_cp ; +%D draw fullcircle scaled 10pt withoutcolor ; shift_cp ; +%D fill fullcircle scaled 10pt ; shift_cp ; +%D \stopuseMPgraphic +%D +%D \starttabulate +%D \NC 0\quad \NC \chardef\MPcolormethod0 \green XX\quad \useMPgraphic{test}\quad XX \NC \NR +%D \NC 1\quad \NC \chardef\MPcolormethod1 \green XX\quad \useMPgraphic{test}\quad XX \NC \NR +%D \NC 2\quad \NC \chardef\MPcolormethod2 \green XX\quad \useMPgraphic{test}\quad XX \NC \NR +%D \NC 3\quad \NC \chardef\MPcolormethod3 \green XX\quad \useMPgraphic{test}\quad XX \NC \NR +%D \stoptabulate +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +\chardef\MPcolormethod\zerocount + +% can be faster, just + +\appendtoks + \ctxlua{metapost.set_outer_color(\number\MPcolormethod,\number\currentcolormodel,\number\dogetattribute{color},\number\dogetattribute{transparency})}% +\to \everyMPgraphic + +\startMPinitializations + defaultcolormodel := \ifcase\MPcolormethod1\or1\or3\else3\fi; +\stopMPinitializations + +%D \macros +%D {setupMPgraphics} +%D +%D Here is a generic setup command: + +\newtoks \everysetupMPgraphics + +\unexpanded\def\setupMPgraphics[#1]% + {\getparameters[\??mp][#1]% + \the\everysetupMPgraphics} + +%D Here we hook in the outer color. When \type {color} is set to \type +%D {global} we get the outer color automatically. If you change this +%D setting, you should do it grouped in order not to make other graphics +%D behave in unexpected ways. + +\appendtoks + \doifelse\@@mpcolor\v!global{\chardef\MPcolormethod\plusone}{\chardef\MPcolormethod\zerocount}% +\to \everysetupMPgraphics + +\setupMPgraphics + [\c!color=\v!local] + +%D Done. + +\protect \endinput diff --git a/tex/context/base/meta-mis.tex b/tex/context/base/meta-mis.tex new file mode 100644 index 000000000..29ab43007 --- /dev/null +++ b/tex/context/base/meta-mis.tex @@ -0,0 +1,54 @@ +%D \module +%D [ file=meta-mis, +%D version=2006.06.06, +%D title=\METAPOST\ Graphics, +%D subtitle=Misc Test Graphics, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 + +% p/s 1/false 1/true 2/false 2/true +% +% MKII 8.5 8.0 8.8 8.5 +% MKIV 16.1 7.2 16.3 7.4 + +\startuseMPgraphic{mptopdf-test} + prologues := 2; + mpprocset := 1 ; + 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(1,0,0,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 (-bbheight(currentpicture)/2+2.5mm) withpen pencircle scaled 1pt withcolor .5white ; +\stopuseMPgraphic + +\protect \endinput diff --git a/tex/context/base/meta-nav.tex b/tex/context/base/meta-nav.tex new file mode 100644 index 000000000..9c1cbb4db --- /dev/null +++ b/tex/context/base/meta-nav.tex @@ -0,0 +1,65 @@ +%D \module +%D [ file=meta-nav, +%D version=2003.03.28, +%D title=\METAPOST\ Graphics, +%D subtitle=Navigational Graphics, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startuniqueMPgraphic{navplus}{size,color,type,mode} + color c ; numeric s, t ; path p ; + t := \MPvar{type} ; c := \MPvar{color} ; s := \MPvar{size} ; + if \MPvar{mode} = 1 : c := .5[c,white] fi ; + if t = 1 : + p := ((0,0)--(1/2,0)--(1,1/3)--(1,1)--(0,1)--(0,0)--cycle) + xyscaled (3,4) ; + elseif t = 2 : + p := ((0,0)--(1,0)--(1,1)--(0,1)--(1/2,2/5)--(1,1)--(0,1)--cycle) + xyscaled (4,3) ; + else : + p := fullsquare xyscaled (3,3) ; + fi ; + draw p withpen pencircle scaled (1/2) withcolor .75white ; + fill p withcolor c ; + draw p withpen pencircle scaled (1/3) withcolor .5c ; + currentpicture := currentpicture scaled s ; + currentpicture := currentpicture shifted -center currentpicture ; +\stopuniqueMPgraphic + +\setupMPvariables + [navplus] + [size=1ex, + color=black, + type=1, + mode=0] + +\definepalet + [navplus] + [attach=darkred, + comment=darkblue] + +\definesymbol + [comment-normal] + [\uniqueMPgraphic{navplus}{type=1,color=navplus:comment}] +\definesymbol + [comment-down] + [\uniqueMPgraphic{navplus}{type=1,color=navplus:comment,mode=1}] + +\definesymbol + [attach-normal] + [\uniqueMPgraphic{navplus}{type=2,color=navplus:attach}] +\definesymbol + [attach-down] + [\uniqueMPgraphic{navplus}{type=2,color=navplus:attach,mode=1}] + +\unprotect + +\setupcomment [\c!symbol={comment-normal,comment-down}] +\setupattachments[\c!symbol={attach-normal,attach-down}] + +\protect \endinput diff --git a/tex/context/base/meta-pag.mkii b/tex/context/base/meta-pag.mkii new file mode 100644 index 000000000..000e56a2e --- /dev/null +++ b/tex/context/base/meta-pag.mkii @@ -0,0 +1,226 @@ +%D \module +%D [ file=meta-pag, +%D version=1999.07.10, +%D title=\METAPOST\ Graphics, +%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 These definitions used to be part of the old \type +%D {core-mps} file, later changed into \type {meta-ini}, but +%D keeping them separate is cleaner. + +\writestatus{loading}{MetaPost Graphics / Page Data Management} + +\unprotect + +\startMPextensions + if unknown context_page: input mp-page; fi; +\stopMPextensions + +%D The next few macros tell \METAPOST\ how the \CONTEXT\ +%D pagebody looks. + +\startMPextensions + boolean PageStateAvailable,OnRightPage,InPageBody; + PageStateAvailable:=true; +\stopMPextensions + +\startMPinitializations + OnRightPage:=true; + InPageBody:=\ifinpagebody true \else false \fi; +\stopMPinitializations + +\startMPinitializations + def LoadPageState = + OnRightPage:=\MPonrightpage; + OnOddPage:=\MPonoddpage; + RealPageNumber:=\the\realpageno; + PageNumber:=\the\pageno; + NOfPages:=\lastpage; + PaperHeight:=\the\paperheight; + PaperWidth:=\the\paperwidth; + PrintPaperHeight:=\the\printpaperheight; + PrintPaperWidth:=\the\printpaperwidth; + TopSpace:=\the\topspace; + BottomSpace:=\the\bottomspace; + BackSpace:=\the\backspace; + CutSpace:=\the\cutspace; + MakeupHeight:=\the\makeupheight; + MakeupWidth:=\the\makeupwidth; + TopHeight:=\the\topheight; + TopDistance:=\the\topdistance; + HeaderHeight:=\the\headerheight; + HeaderDistance:=\the\headerdistance; + TextHeight:=\the\textheight; + FooterDistance:=\the\footerdistance; + FooterHeight:=\the\footerheight; + BottomDistance:=\the\bottomdistance; + BottomHeight:=\the\bottomheight; + LeftEdgeWidth:=\the\leftedgewidth; + LeftEdgeDistance:=\the\leftedgedistance; + LeftMarginWidth:=\the\leftmarginwidth; + LeftMarginDistance:=\the\leftmargindistance; + TextWidth:=\the\textwidth ; + RightMarginDistance:=\the\rightmargindistance; + RightMarginWidth:=\the\rightmarginwidth; + RightEdgeDistance:=\the\rightedgedistance; + RightEdgeWidth:=\the\rightedgewidth; + InnerMarginDistance:=\the\innermargindistance; + InnerMarginWidth:=\the\innermarginwidth; + OuterMarginDistance:=\the\outermargindistance; + OuterMarginWidth:=\the\outermarginwidth; + InnerEdgeDistance:=\the\inneredgedistance; + InnerEdgeWidth:=\the\inneredgewidth; + OuterEdgeDistance:=\the\outeredgedistance; + OuterEdgeWidth:=\the\outeredgewidth; + PageOffset:=\the\pageoffset; + PageDepth:=\the\pagedepth; + LayoutColumns:=\the\layoutcolumns; + LayoutColumnDistance:=\the\layoutcolumndistance; + LayoutColumnWidth:=\the\layoutcolumnwidth; + enddef; +\stopMPinitializations + +\def\MPonrightpage{true} +\def\MPonoddpage {true} + +\def\freezeMPpagelayout + {\doifbothsides + {\def\MPonrightpage{true}} + {\def\MPonrightpage{true}} + {\def\MPonrightpage{false}}% + \edef\MPonoddpage{\doifoddpageelse{true}{false}}} + +\let\freezeMPlayout\relax % obsolete + +%D We need to freeze the pagelayout before the backgrounds +%D are build, because the overlay will temporarily become +%D zero (overlay). + +\appendtoks + \freezeMPpagelayout +\to \everybeforepagebody + +%D By freezing these value every graphic, we can use layout +%D variables that change halfways a page, whatever use that +%D has. + +\prependtoks + \calculatereducedvsizes % this is really needed + \freezeMPpagelayout + \freezeMPlayout % to be used grouped +\to \everyMPgraphic + +%D The next feature provides information about for instance +%D column positions. This is an experimental feature, +%D introduced when we needed backgrounds in columns (fill||in +%D questions as implemented in a private module). +%D +%D See \type {mp-page.mp} for the definition of the macros: +%D +%D \starttabulate[|tl|l|p|] +%D \NC ResetTextAreas \NC no arguments \NC +%D reset areas on page \NC \NR +%D \NC RegisterTextArea \NC x, y, w, h \NC +%D adds area to the list \NC \NR +%D \NC TextAreaX,Y,W,H,XY,WH \NC x and/or y \NC +%D reports offsets and dimensions \NC \NR +%D \stoptabulate +%D +%D The \type {TextArea*} macros can be used to determine +%D overlap. + +\newcount\currentMPtextareadata + +\newtoks\MPsavedtextareadata +\newtoks\MPtextareadata +\newtoks\MPlocaltextareadata + +% optimaliseren voor herhaling + +\def\registerMPtextarea#1% + {\ifpositioning + \bgroup + \global\advance\currentMPtextareadata\plusone + %\hpos{gbd:\the\currentMPtextareadata}{#1}% + \hpos{gbd:\the\currentMPtextareadata}% + {\iftracetextareas\boxrulewidth1.5pt\ruledhbox\fi{#1}}% + \edef\!!stringa{gbd:\the\currentMPtextareadata}% + \edef\!!stringa{RegisterTextArea(% + \MPx\!!stringa,\MPy\!!stringa,% + \MPw\!!stringa,\MPh\!!stringa,\MPd\!!stringa);}% + \@EA \doglobal \@EA \appendtoks \!!stringa \to \MPtextareadata + \egroup + \else + \hbox{#1}% + \fi} + +\def\registerMPlocaltextarea#1% + {\ifpositioning + \bgroup + \global\advance\currentMPtextareadata\plusone + %\hpos{gbd:\the\currentMPtextareadata}{#1}% + \hpos{gbd:\the\currentMPtextareadata}% + {\iftracetextareas\boxrulewidth3pt\ruledhbox\fi{#1}}% + \edef\!!stringa{gbd:\the\currentMPtextareadata}% + \edef\!!stringa{RegisterLocalTextArea(% + \MPx\!!stringa,\MPy\!!stringa,% + \MPw\!!stringa,\MPh\!!stringa,\MPd\!!stringa);}% + \global\MPlocaltextareadata\@EA{\!!stringa}% + \egroup + \else + \hbox{#1}% + \fi} + +% better, so that we can force a key and share with e.g. renumbering +% +% \let\namedtextarea\empty +% +% \def\registerMPlocaltextarea#1% +% {\ifpositioning +% \bgroup +% \ifx\namedtextarea\empty +% \global\advance\currentMPtextareadata\plusone +% \edef\namedtextarea{gbd:\the\currentMPtextareadata}% +% \fi +% \hpos\namedtextarea{\iftracetextareas\boxrulewidth3pt\ruledhbox\fi{#1}}% +% \edef\ascii{RegisterLocalTextArea(% +% \MPx\namedtextarea,\MPy\namedtextarea,% +% \MPw\namedtextarea,\MPh\namedtextarea,\MPd\namedtextarea);}% +% \global\MPlocaltextareadata\@EA{\ascii}% +% \egroup +% \else +% \hbox{#1}% +% \fi} + +\def\resetMPlocaltextarea + {\global\MPlocaltextareadata\emptytoks} + +\startMPextensions + path PlainTextArea; +\stopMPextensions + +\startMPinitializations + ResetTextAreas; + \the\MPsavedtextareadata; + SaveTextAreas; + ResetTextAreas; + \the\MPtextareadata; + \the\MPlocaltextareadata; + PlainTextArea:=boundingbox(\MPxy{text:\realfolio}--\MPxy{text:\realfolio} + shifted (\MPw{text:\realfolio},\MPh{text:\realfolio})); +\stopMPinitializations + +\appendtoks + \global\MPsavedtextareadata\MPtextareadata + \global\MPtextareadata \emptytoks + \global\MPlocaltextareadata\emptytoks +\to \everyshipout + +\protect \endinput diff --git a/tex/context/base/meta-pag.mkiv b/tex/context/base/meta-pag.mkiv new file mode 100644 index 000000000..ef3817721 --- /dev/null +++ b/tex/context/base/meta-pag.mkiv @@ -0,0 +1,223 @@ +%D \module +%D [ file=meta-pag, +%D version=1999.07.10, +%D title=\METAPOST\ Graphics, +%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 These definitions used to be part of the old \type +%D {core-mps} file, later changed into \type {meta-ini}, but +%D keeping them separate is cleaner. + +\writestatus{loading}{MetaPost Graphics / Page Data Management} + +\unprotect + +\startMPextensions + if unknown context_page: input mp-page; fi; +\stopMPextensions + +%D The next few macros tell \METAPOST\ how the \CONTEXT\ +%D pagebody looks. + +\startMPextensions + boolean PageStateAvailable,OnRightPage,InPageBody; + PageStateAvailable:=true; +\stopMPextensions + +\startMPinitializations + OnRightPage:=true; + InPageBody:=\ifinpagebody true \else false \fi; +\stopMPinitializations + +\startMPinitializations + def LoadPageState = + OnRightPage:=\MPonrightpage; + OnOddPage:=\MPonoddpage; + RealPageNumber:=\the\realpageno; + PageNumber:=\the\pageno; + NOfPages:=\lastpage; + PaperHeight:=\the\paperheight; + PaperWidth:=\the\paperwidth; + PrintPaperHeight:=\the\printpaperheight; + PrintPaperWidth:=\the\printpaperwidth; + TopSpace:=\the\topspace; + BottomSpace:=\the\bottomspace; + BackSpace:=\the\backspace; + CutSpace:=\the\cutspace; + MakeupHeight:=\the\makeupheight; + MakeupWidth:=\the\makeupwidth; + TopHeight:=\the\topheight; + TopDistance:=\the\topdistance; + HeaderHeight:=\the\headerheight; + HeaderDistance:=\the\headerdistance; + TextHeight:=\the\textheight; + FooterDistance:=\the\footerdistance; + FooterHeight:=\the\footerheight; + BottomDistance:=\the\bottomdistance; + BottomHeight:=\the\bottomheight; + LeftEdgeWidth:=\the\leftedgewidth; + LeftEdgeDistance:=\the\leftedgedistance; + LeftMarginWidth:=\the\leftmarginwidth; + LeftMarginDistance:=\the\leftmargindistance; + TextWidth:=\the\textwidth ; + RightMarginDistance:=\the\rightmargindistance; + RightMarginWidth:=\the\rightmarginwidth; + RightEdgeDistance:=\the\rightedgedistance; + RightEdgeWidth:=\the\rightedgewidth; + InnerMarginDistance:=\the\innermargindistance; + InnerMarginWidth:=\the\innermarginwidth; + OuterMarginDistance:=\the\outermargindistance; + OuterMarginWidth:=\the\outermarginwidth; + InnerEdgeDistance:=\the\inneredgedistance; + InnerEdgeWidth:=\the\inneredgewidth; + OuterEdgeDistance:=\the\outeredgedistance; + OuterEdgeWidth:=\the\outeredgewidth; + PageOffset:=\the\pageoffset; + PageDepth:=\the\pagedepth; + LayoutColumns:=\the\layoutcolumns; + LayoutColumnDistance:=\the\layoutcolumndistance; + LayoutColumnWidth:=\the\layoutcolumnwidth; + enddef; +\stopMPinitializations + +\def\MPonrightpage{true} +\def\MPonoddpage {true} + +\def\freezeMPpagelayout + {\edef\MPonrightpage{\doifbothsides {tru}{tru}{fals}e}% + \edef\MPonoddpage {\doifoddpageelse {tru}{fals}e}} + +\let\freezeMPlayout\relax % obsolete + +%D We need to freeze the pagelayout before the backgrounds +%D are build, because the overlay will temporarily become +%D zero (overlay). + +\appendtoks + \freezeMPpagelayout +\to \everybeforepagebody + +%D By freezing these value every graphic, we can use layout +%D variables that change halfways a page, whatever use that +%D has. + +\prependtoks + \calculatereducedvsizes % this is really needed + \freezeMPpagelayout + \freezeMPlayout % to be used grouped +\to \everyMPgraphic + +%D The next feature provides information about for instance +%D column positions. This is an experimental feature, +%D introduced when we needed backgrounds in columns (fill||in +%D questions as implemented in a private module). +%D +%D See \type {mp-page.mp} for the definition of the macros: +%D +%D \starttabulate[|tl|l|p|] +%D \NC ResetTextAreas \NC no arguments \NC +%D reset areas on page \NC \NR +%D \NC RegisterTextArea \NC x, y, w, h \NC +%D adds area to the list \NC \NR +%D \NC TextAreaX,Y,W,H,XY,WH \NC x and/or y \NC +%D reports offsets and dimensions \NC \NR +%D \stoptabulate +%D +%D The \type {TextArea*} macros can be used to determine +%D overlap. + +\newcount\currentMPtextareadata + +\newtoks\MPsavedtextareadata +\newtoks\MPtextareadata +\newtoks\MPlocaltextareadata + +% optimaliseren voor herhaling + +\def\registerMPtextarea#1% + {\ifpositioning + \bgroup + \global\advance\currentMPtextareadata\plusone + %\hpos{gbd:\the\currentMPtextareadata}{#1}% + \hpos{gbd:\the\currentMPtextareadata}% + {\iftracetextareas\boxrulewidth1.5pt\ruledhbox\fi{#1}}% + \edef\!!stringa{gbd:\the\currentMPtextareadata}% + \edef\!!stringa{RegisterTextArea(% + \MPx\!!stringa,\MPy\!!stringa,% + \MPw\!!stringa,\MPh\!!stringa,\MPd\!!stringa);}% + \@EA \doglobal \@EA \appendtoks \!!stringa \to \MPtextareadata + \egroup + \else + \hbox{#1}% + \fi} + +\def\registerMPlocaltextarea#1% + {\ifpositioning + \bgroup + \global\advance\currentMPtextareadata\plusone + %\hpos{gbd:\the\currentMPtextareadata}{#1}% + \hpos{gbd:\the\currentMPtextareadata}% + {\iftracetextareas\boxrulewidth3pt\ruledhbox\fi{#1}}% + \edef\!!stringa{gbd:\the\currentMPtextareadata}% + \edef\!!stringa{RegisterLocalTextArea(% + \MPx\!!stringa,\MPy\!!stringa,% + \MPw\!!stringa,\MPh\!!stringa,\MPd\!!stringa);}% + \global\MPlocaltextareadata\@EA{\!!stringa}% + \egroup + \else + \hbox{#1}% + \fi} + +% better, so that we can force a key and share with e.g. renumbering +% +% \let\namedtextarea\empty +% +% \def\registerMPlocaltextarea#1% +% {\ifpositioning +% \bgroup +% \ifx\namedtextarea\empty +% \global\advance\currentMPtextareadata\plusone +% \edef\namedtextarea{gbd:\the\currentMPtextareadata}% +% \fi +% \hpos\namedtextarea{\iftracetextareas\boxrulewidth3pt\ruledhbox\fi{#1}}% +% \edef\ascii{RegisterLocalTextArea(% +% \MPx\namedtextarea,\MPy\namedtextarea,% +% \MPw\namedtextarea,\MPh\namedtextarea,\MPd\namedtextarea);}% +% \global\MPlocaltextareadata\@EA{\ascii}% +% \egroup +% \else +% \hbox{#1}% +% \fi} + +\def\resetMPlocaltextarea + {\global\MPlocaltextareadata\emptytoks} + +\startMPextensions + path PlainTextArea; +\stopMPextensions + +\startMPinitializations + ResetTextAreas; + \the\MPsavedtextareadata; + SaveTextAreas; + ResetTextAreas; + \the\MPtextareadata; + \the\MPlocaltextareadata; + PlainTextArea:=boundingbox(\MPxy{text:\realfolio}--\MPxy{text:\realfolio} + shifted (\MPw{text:\realfolio},\MPh{text:\realfolio})); +\stopMPinitializations + +\appendtoks + \global\MPsavedtextareadata\MPtextareadata + \global\MPtextareadata \emptytoks + \global\MPlocaltextareadata\emptytoks +\to \everyshipout + +\protect \endinput diff --git a/tex/context/base/meta-pdf.lua b/tex/context/base/meta-pdf.lua new file mode 100644 index 000000000..23f8d4de0 --- /dev/null +++ b/tex/context/base/meta-pdf.lua @@ -0,0 +1,553 @@ +if not modules then modules = { } end modules ['meta-pdf'] = { + version = 1.001, + comment = "companion to meta-pdf.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- 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. This module keeps changing as it is also a testbed. + +local concat, format, gsub, find, byte, gmatch, match = table.concat, string.format, string.gsub, string.find, string.byte, string.gmatch, string.match +local lpegmatch = lpeg.match +local round = math.round +local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes + +local pdfrgbcode = lpdf.rgbcode +local pdfcmykcode = lpdf.cmykcode +local pdfgraycode = lpdf.graycode +local pdfspotcode = lpdf.spotcode +local pdftransparencycode = lpdf.transparencycode +local pdffinishtransparencycode = lpdf.finishtransparencycode + +mptopdf = { } +mptopdf.n = 0 + +local m_path, m_stack, m_texts, m_version, m_date, m_shortcuts = { }, { }, { }, 0, 0, false + +local m_stack_close, m_stack_path, m_stack_concat = false, { }, nil +local extra_path_code, ignore_path = nil, false +local specials = { } + +local function resetpath() + m_stack_close, m_stack_path, m_stack_concat = false, { }, nil +end + +local function resetall() + m_path, m_stack, m_texts, m_version, m_shortcuts = { }, { }, { }, 0, false + extra_path_code, ignore_path = nil, false + specials = { } + resetpath() +end + +resetall() + +-- todo: collect and flush packed using pdfliteral node injection but we're +-- in no hurry as this kind of conversion does not happen that often in mkiv + +local function pdfcode(str) -- could be a node.write instead + texsprint(ctxcatcodes,"\\pdfliteral{",str,"}") +end + +local function texcode(str) + texsprint(ctxcatcodes,str) +end + +function mpscode(str) + if ignore_path then + pdfcode("h W n") + if extra_path_code then + pdfcode(extra_path_code) + extra_path_code = nil + end + ignore_path = false + else + pdfcode(str) + end +end + +-- auxiliary functions + +local function flushconcat() + if m_stack_concat then + mpscode(concat(m_stack_concat," ") .. " cm") + m_stack_concat = nil + end +end + +local function flushpath(cmd) + if #m_stack_path > 0 then + local path = { } + 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) + 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 + 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] = concat(v," ") + end + else + for k=1,#m_stack_path do + path[#path+1] = concat(m_stack_path[k]," ") + end + end + flushconcat() + pdfcode(concat(path," ")) + if m_stack_close then + mpscode("h " .. cmd) + else + mpscode(cmd) + end + end + resetpath() +end + +-- mp interface + +mps = mps or { } + +function mps.creator(a, b, c) + m_version = tonumber(b) +end + +function mps.creationdate(a) + m_date = a +end + +function mps.newpath() + m_stack_path = { } +end + +function mps.boundingbox(llx, lly, urx, ury) + texcode("\\MPSboundingbox{" .. llx .. "}{" .. lly .. "}{" .. urx .. "}{" .. ury .. "}") +end + +function mps.moveto(x,y) + m_stack_path[#m_stack_path+1] = {x,y,"m"} +end + +function mps.curveto(ax, ay, bx, by, cx, cy) + m_stack_path[#m_stack_path+1] = {ax,ay,bx,by,cx,cy,"c"} +end + +function mps.lineto(x,y) + m_stack_path[#m_stack_path+1] = {x,y,"l"} +end + +function mps.rlineto(x,y) + local dx, dy = 0, 0 + if #m_stack_path > 0 then + dx, dy = m_stack_path[#m_stack_path][1], m_stack_path[#m_stack_path][2] + end + m_stack_path[#m_stack_path+1] = {dx,dy,"l"} +end + +function mps.translate(tx,ty) + mpscode("1 0 0 0 1 " .. tx .. " " .. ty .. " cm") +end + +function mps.scale(sx,sy) + m_stack_concat = {sx,0,0,sy,0,0} +end + +function mps.concat(sx, rx, ry, sy, tx, ty) + m_stack_concat = {sx,rx,ry,sy,tx,ty} +end + +function mps.setlinejoin(d) + mpscode(d .. " j") +end + +function mps.setlinecap(d) + mpscode(d .. " J") +end + +function mps.setmiterlimit(d) + mpscode(d .. " M") +end + +function mps.gsave() + mpscode("q") +end + +function mps.grestore() + mpscode("Q") +end + +function mps.setdash(...) -- can be made faster, operate on t = { ... } + local n = select("#",...) + mpscode("[" .. concat({...}," ",1,n-1) .. "] " .. select(n,...) .. " d") +end + +function mps.resetdash() + mpscode("[ ] 0 d") +end + +function mps.setlinewidth(d) + mpscode(d .. " w") +end + +function mps.closepath() + m_stack_close = true +end + +function mps.fill() + flushpath('f') +end + +function mps.stroke() + flushpath('S') +end + +function mps.both() + flushpath('B') +end + +function mps.clip() + flushpath('W n') +end + +function mps.textext(font, scale, str) -- old parser + local dx, dy = 0, 0 + if #m_stack_path > 0 then + dx, dy = m_stack_path[1][1], m_stack_path[1][2] + end + flushconcat() + texcode("\\MPStextext{"..font.."}{"..scale.."}{"..str.."}{"..dx.."}{"..dy.."}") + resetpath() +end + +local handlers = { } + +handlers[1] = function(s) + pdfcode(pdffinishtransparencycode()) + pdfcode(pdfcmykcode(mps.colormodel,s[3],s[4],s[5],s[6])) +end +handlers[2] = function(s) + pdfcode(pdffinishtransparencycode()) + pdfcode(pdfspotcode(mps.colormodel,s[3],s[4],s[5],s[6])) +end +handlers[3] = function(s) + pdfcode(pdfrgbcode(mps.colormodel,s[4],s[5],s[6])) + pdfcode(pdftransparencycode(s[2],s[3])) +end +handlers[4] = function(s) + pdfcode(pdfcmykcode(mps.colormodel,s[4],s[5],s[6],s[7])) + pdfcode(pdftransparencycode(s[2],s[3])) +end +handlers[5] = function(s) + pdfcode(pdfspotcode(mps.colormodel,s[4],s[5],s[6],s[7])) + pdfcode(pdftransparencycode(s[2],s[3])) +end + +-- todo: color conversion + +local nofshades, tn = 0, tonumber + +local function linearshade(colorspace,domain,ca,cb,coordinates) + pdfcode(pdffinishtransparencycode()) + nofshades = nofshades + 1 + local name = format("MpsSh%s",nofshades) + lpdf.linearshade(name,domain,ca,cb,1,colorspace,coordinates) + extra_path_code, ignore_path = format("/%s sh Q",name), true + pdfcode("q /Pattern cs") +end + +local function circularshade(colorspace,domain,ca,cb,coordinates) + pdfcode(pdffinishtransparencycode()) + nofshades = nofshades + 1 + local name = format("MpsSh%s",nofshades) + lpdf.circularshade(name,domain,ca,cb,1,colorspace,coordinates) + extra_path_code, ignore_path = format("/%s sh Q",name), true + pdfcode("q /Pattern cs") +end + +handlers[30] = function(s) + linearshade("DeviceRGB", { tn(s[ 2]), tn(s[ 3]) }, + { tn(s[ 5]), tn(s[ 6]), tn(s[ 7]) }, { tn(s[10]), tn(s[11]), tn(s[12]) }, + { tn(s[ 8]), tn(s[ 9]), tn(s[13]), tn(s[14]) } ) +end + +handlers[31] = function(s) + circularshade("DeviceRGB", { tn(s[ 2]), tn(s[ 3]) }, + { tn(s[ 5]), tn(s[ 6]), tn(s[ 7]) }, { tn(s[11]), tn(s[12]), tn(s[13]) }, + { tn(s[ 8]), tn(s[ 9]), tn(s[10]), tn(s[14]), tn(s[15]), tn(s[16]) } ) +end + +handlers[32] = function(s) + linearshade("DeviceCMYK", { tn(s[ 2]), tn(s[ 3]) }, + { tn(s[ 5]), tn(s[ 6]), tn(s[ 7]), tn(s[ 8]) }, { tn(s[11]), tn(s[12]), tn(s[13]), tn(s[14]) }, + { tn(s[ 9]), tn(s[10]), tn(s[15]), tn(s[16]) } ) +end + +handlers[33] = function(s) + circularshade("DeviceCMYK", { tn(s[ 2]), tn(s[ 3]) }, + { tn(s[ 5]), tn(s[ 6]), tn(s[ 7]), tn(s[ 8]) }, { tn(s[12]), tn(s[13]), tn(s[14]), tn(s[15]) }, + { tn(s[ 9]), tn(s[10]), tn(s[11]), tn(s[16]), tn(s[17]), tn(s[18]) } ) +end + +handlers[34] = function(s) -- todo (after further cleanup) + linearshade("DeviceGray", { tn(s[ 2]), tn(s[ 3]) }, { 0 }, { 1 }, { tn(s[9]), tn(s[10]), tn(s[15]), tn(s[16]) } ) +end + +handlers[35] = function(s) -- todo (after further cleanup) + circularshade("DeviceGray", { tn(s[ 2]), tn(s[ 3]) }, { 0 }, { 1 }, { tn(s[9]), tn(s[10]), tn(s[15]), tn(s[16]) } ) +end + +-- not supported in mkiv , use mplib instead + +handlers[10] = function() logs.report("mptopdf","skipping special %s",10) end +handlers[20] = function() logs.report("mptopdf","skipping special %s",20) end +handlers[50] = function() logs.report("mptopdf","skipping special %s",50) end + +--end of not supported + +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 + g, b = round(g*10000), round(b*10000) + local s = specials[b] + local h = round(s[#s]) + local handler = handlers[h] + if handler then + handler(s) + else + logs.report("mptopdf","unknown special handler %s (1)",h) + end + elseif r == 0.123 and g < 0.1 then + g, b = round(g*1000), round(b*1000) + local s = specials[b] + local h = round(s[#s]) + local handler = handlers[h] + if handler then + handler(s) + else + logs.report("mptopdf","unknown special handler %s (2)",h) + end + else + pdfcode(pdffinishtransparencycode()) + pdfcode(pdfrgbcode(mps.colormodel,r,g,b)) + end +end + +function mps.setcmykcolor(c,m,y,k) + pdfcode(pdffinishtransparencycode()) + pdfcode(pdfcmykcode(mps.colormodel,c,m,y,k)) +end + +function mps.setgray(s) + pdfcode(pdffinishtransparencycode()) + pdfcode(pdfgrayliteral(mps.colormodel,s)) +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 t = { ... } + local n = tonumber(t[#t-1]) + specials[n] = t +end + +function mps.begindata() +end + +function mps.enddata() +end + +function mps.showpage() +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. + +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,lpegmatch(package,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 + +-- experimental + +local preamble = ( + prolog + setup + + boundingbox + highresboundingbox + specials + special + + comment +) + +local procset = ( + lj + ml + lc + + c + l + m + n + p + r + + 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 + + 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 captures_new = ( space + verbose + procset + preamble )^0 + +local function parse(m_data) + if find(m_data,"%%%%BeginResource: procset mpost") then + lpegmatch(captures_new,m_data) + else + lpegmatch(captures_old,m_data) + end +end + +-- main converter + +local a_colorspace = attributes.private('colormodel') + +function mptopdf.convertmpstopdf(name) + resetall() + local ok, m_data, n = resolvers.loadbinfile(name, 'tex') -- we need a binary load ! + if ok then + mps.colormodel = tex.attribute[a_colorspace] + statistics.starttiming(mptopdf) + mptopdf.n = mptopdf.n + 1 + pdfcode(format("\\letterpercent\\space mptopdf begin: n=%s, file=%s",mptopdf.n,file.basename(name))) + pdfcode("q 1 0 0 1 0 0 cm") + parse(m_data) + pdfcode(pdffinishtransparencycode()) + pdfcode("Q") + pdfcode("\\letterpercent\\space mptopdf end") + resetall() + statistics.stoptiming(mptopdf) + else + commands.writestatus("mptopdf","file '%s' not found",name) + end +end + + +-- 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 new file mode 100644 index 000000000..2099b0d37 --- /dev/null +++ b/tex/context/base/meta-pdf.mkii @@ -0,0 +1,2761 @@ +%D \module +%D [ file=meta-pdf, +%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] +%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}{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 {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}% + \vbox\bgroup + \forgetall + \offinterlineskip + \ifx\pdfdecimaldigits\undefined\else \pdfdecimaldigits=5 \fi % new + \global\let\MPheight\!!zeropoint + \global\let\MPwidth \!!zeropoint + \setbox\scratchbox\vbox\bgroup + \message{[MP to PDF]}% + \startMPresources + \PDFcomment{mps begin}% + \PDFcode{q}% + \PDFcode{1 0 0 1 0 0 cm}% + \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 + \the\everyMPtoPDFconversion + \catcode`\^^M=\@@endofline + \startMPscanning + \let\do\empty + \donefalse + \let\handleMPsequence\dohandleMPsequence + \input\MPfilename\relax} + +\def\finishMPgraphic + {\PDFcode{Q}% + \PDFcomment{mps end}% + \stopMPresources + \egroup + \setbox\scratchbox\hbox\bgroup + \hskip-\MPllx\onebasepoint + \raise-\MPlly\onebasepoint + \box\scratchbox + \egroup + \setbox\scratchbox\vbox to \MPheight\bgroup + \vfill + \hsize\MPwidth + \smashbox\scratchbox + \box\scratchbox + \egroup + \wd\scratchbox\MPwidth + \ht\scratchbox\MPheight + \dopackageMPgraphic\scratchbox + \egroup + \endinput} + +%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. + +\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 +%D {xPSmoveto}}. For everyday documents with relatively +%D small graphics the gain in speed can be neglected. + +\def \PScurveto {curveto} +\def \PSlineto {lineto} +\def \PSmoveto {moveto} +\def \PSshowpage {showpage} +\def \PSnewpath {newpath} +\def \PSfshow {fshow} +\def \PSclosepath {closepath} +\def \PSfill {fill} +\def \PSstroke {stroke} +\def \PSclip {clip} +\def \PSrlineto {rlineto} +\def \PSsetlinejoin {setlinejoin} +\def \PSsetlinecap {setlinecap} +\def \PSsetmiterlimit {setmiterlimit} +\def \PSsetgray {setgray} +\def \PSsetrgbcolor {setrgbcolor} +\def \PSsetcmykcolor {setcmykcolor} +\def \PSsetdash {setdash} +\def \PSgsave {gsave} +\def \PSgrestore {grestore} +\def \PStranslate {translate} +\def \PSscale {scale} +\def \PSconcat {concat} +\def \PSdtransform {dtransform} +\def \PSsetlinewidth {setlinewidth} +\def \PSpop {pop} + +\def \PSnfont {nfont} % was needed for TUG98 proceedings +\def \PSspecial {special} % extensions to MetaPost + +%D A previous version set \type {%} to ignore, which +%D simplified the following definitions. At the start of +%D conversion the percent character was made active again. +%D Because the whole graphic is one paragraph (there are no +%D empty lines) this does not give the desired effect. This +%D went unnoticed untill Scott Pakin sent me a test file +%D percent characters in a string. So, from now on we have +%D to prefix the following strings with percentages. + +%D Some day I'll figure out a better solution (line by line reading +%D using \ETEX). + +\edef \PSBoundingBox {\letterpercent\letterpercent BoundingBox:} +\edef \PSHiResBoundingBox {\letterpercent\letterpercent HiResBoundingBox:} +\edef \PSExactBoundingBox {\letterpercent\letterpercent ExactBoundingBox:} +\edef \PSMetaPostSpecial {\letterpercent\letterpercent MetaPostSpecial:} +\edef \PSMetaPostSpecials {\letterpercent\letterpercent MetaPostSpecials:} +\edef \PSPage {\letterpercent\letterpercent Page:} +\edef \PSBeginProlog {\letterpercent\letterpercent BeginProlog} +\edef \PSEndProlog {\letterpercent\letterpercent EndProlog} +\edef \PSEof {\letterpercent\letterpercent EOF} + +%D By the way, the \type {setcmykcolor} operator is not +%D output by \METAPOST\ but can result from converting the +%D \cap{RGB} color specifications, as implemented in +%D \type{supp-mps}. + +%D In \POSTSCRIPT\ arguments precede the operators. Due to the +%D fact that in some translations we need access to those +%D arguments, and also because sometimes we have to skip them, +%D we stack them up. The stack is one||dimensional for non path +%D operators and two||dimensional for operators inside a path. +%D This is because we have to save the whole path for +%D (optional) postprocessing. Values are pushed onto the stack +%D by: +%D +%D \starttyping +%D \setMPargument {value} +%D \stoptyping +%D +%D They can be retrieved by the short named macros: +%D +%D \starttyping +%D \gMPa {number} +%D \gMPs {number} +%D \stoptyping +%D +%D When scanning a path specification, we also save the +%D operator, using +%D +%D \starttyping +%D \setMPkeyword {n} +%D \stoptyping +%D +%D The path drawing operators are coded for speed: \type{clip}, +%D \type{stroke}, \type{fill} and \type{fillstroke} become +%D 1, 2, 3 and~4. +%D +%D When processing the path this code can be retrieved +%D using +%D +%D \starttyping +%D \getMPkeyword % {n} +%D \stoptyping +%D +%D When setting an argument, the exact position on the stack +%D depends on the current value of the \COUNTERS\ +%D \type{\nofMPsegments} and \type{\nofMParguments}. + +\newcount\nofMPsegments +\newcount\nofMParguments + +%D These variables hold the coordinates. The argument part of +%D the stack is reset by: +%D +%D \starttyping +%D \resetMPstack +%D \stoptyping +%D +%D We use the prefix \type{@@MP} to keep the stack from +%D conflicting with existing macros. To speed up things a bit +%D more, we use the constant \type{\@@MP}. + +\def\@@MP{@@MP} + +\def\setMPargument% #1% + {\advance\nofMParguments \plusone + \expandafter\def\csname\@@MP\the\nofMPsegments\the\nofMParguments\endcsname} % {#1} + +\def\letMPargument + {\advance\nofMParguments \plusone + \expandafter\let\csname\@@MP\the\nofMPsegments\the\nofMParguments\endcsname} + +\def\setMPsequence#1 % + {\advance\nofMParguments \plusone + \expandafter\def\csname\@@MP\the\nofMPsegments\the\nofMParguments\endcsname{#1}% + \handleMPsequence} + +\def\gMPa#1% + {\csname\@@MP0\number#1\endcsname} + +\def\gMPs#1% + {\csname\@@MP\the\nofMPsegments\number#1\endcsname} + +\def\dogMPa#1% + {\@EAEAEA\do\csname\@@MP0\number#1\endcsname} + +\def\setMPkeyword#1 % + {\expandafter\def\csname\@@MP\the\nofMPsegments0\endcsname{#1}% + \advance\nofMPsegments \plusone + \nofMParguments\zerocount} + +\def\getMPkeyword% #1% + {\csname\@@MP\the\nofMPsegments0\endcsname} % {\csname\@@MP#10\endcsname} + +\def\docleanupMPargument#1% we need this because args can have [ or ] pre/appended + {\expandafter\edef\csname\@@MP\the\nofMPsegments\number#1\endcsname + {\csname\@@MP\the\nofMPsegments\number#1\endcsname}} + +%D When we reset the stack, we can assume that all further +%D comment is to be ignored and handled in strings. +%D By redefining the reset macro after the first call, we +%D save some run time. Only use this macro after all +%D comments are processed and use the simple alternative +%D when dealing with comments. + +\def\doresetMPstack + {\nofMParguments\zerocount} + +\def\resetMPstack + {\let\handleMPgraphic\handleMPendgraphic + \let\resetMPstack\doresetMPstack + \resetMPstack} + +%D The arguments are saved with the preceding command +%D \type{\do}. By default this command expands to nothing, but +%D when we deal with strings it's used to strip off the +%D \type{(} and \type{)}. +%D +%D Strings are kind of tricky, because characters can be +%D passed verbatim \type{(hello)}, by octal number +%D \type{(\005)} or as command \type{(\()}. We therefore +%D cannot simply ignore \type{(} and \type{)}, the way we do +%D with \type{[} and \type{]}. Another complication is that +%D strings may contain characters that normally have a +%D special meaning in \TEX, like \type{$} and \type{{}}. +%D +%D A previous solution made \type{\} an active character and +%D let it look ahead for a number or characters. We had to +%D abandon this scheme because of the need for verbatim +%D support. The next solution involved some \CATCODE\ +%D trickery but works well. + +\def\octalMPcharacter#1#2#3% + {\char'#1#2#3\relax} + +%D curly braces and squarly brackets are stored in the argument stack +%D as part of strings, for instance in: +%D +%D \starttyping +%D /fshow {exch findfont exch scalefont setfont show}bind def +%D [3 3 ] 0 setdash +%D \stoptyping +%D +%D but we need to keep them in situation like +%D +%D \starttyping +%D ([bla bla] bla bla) ec-lmr10 9.96265 fshow +%D ({bla bla} bla bla) ec-lmr10 9.96265 fshow +%D \stoptyping +%D +%D So, when we store the snippets, we keep the special tokens, and +%D when needed we either ignore or obey them + +%D We could use a catcodetable here. + +\bgroup +\catcode`\|=\@@comment +\catcode`\%=\@@active +\catcode`\[=\@@active +\catcode`\]=\@@active +\catcode`\{=\@@active +\catcode`\}=\@@active +\catcode`B=\@@begingroup +\catcode`E=\@@endgroup +\gdef\keepMPspecials| + B\let%\letterpercent| + \def[B\noexpand[E| + \def]B\noexpand]E| + \def{B\noexpand{E| + \def}B\noexpand}EE +\gdef\ignoreMPspecials| + B\let%\letterpercent| + \def[BE| + \def]BE| + \def{BE| + \def}BEE +\gdef\obeyMPspecials| + B\def%B\char 37\relax E| + \def[B\char 91\relax E| + \def]B\char 93\relax E| + \def{B\char123\relax E| + \def}B\char125\relax EE +\gdef\setMPspecials| + B\setnaturalcatcodes + \catcode`\\=\@@escape + \catcode`\%=\@@active + \catcode`\[=\@@active + \catcode`\]=\@@active + \catcode`\{=\@@active + \catcode`\}=\@@active + \lccode`\-=0 | latex sets this to `\- + \lccode`\%=`\%| otherwise it's seen as a number + \def\(B\char40\relax E| + \def\)B\char41\relax E| + \def\\B\char92\relax E| + \def\0B\octalMPcharacter0E| + \def\1B\octalMPcharacter1E| + \def\2B\octalMPcharacter2E| + \def\3B\octalMPcharacter3E| + \def\4B\octalMPcharacter4E| + \def\5B\octalMPcharacter5E| + \def\6B\octalMPcharacter6E| + \def\7B\octalMPcharacter7E| + \def\8B\octalMPcharacter8E| + \def\9B\octalMPcharacter9EE +\egroup + +%D We use the comment symbol as a sort of trigger. Beware! +%D The whole graphic is seen as on eparagraph, which means +%D that we cannot change the catcodes in between. + +\bgroup +\catcode`\%=\@@active +\gdef\startMPscanning{\let%=\startMPconversion} +\egroup + +%D In earlier versions we used the sequence +%D +%D \starttyping +%D \expandafter\handleMPsequence\input filename\relax +%D \stoptyping +%D +%D Persistent problems in \LATEX\ however forced us to use a +%D different scheme. Every \POSTSCRIPT\ file starts with a +%D \type{%}, so we temporary make this an active character +%D that starts the scanning and redefines itself. (The problem +%D originates in the redefinition by \LATEX\ of the +%D \type{\input} primitive.) + +\def\startMPconversion + {\keepMPspecials + \handleMPsequence} + +%D Here comes the main loop. Most arguments are numbers. This +%D means that they can be recognized by their \type{\lccode}. +%D This method saves a lot of processing time. We could +%D speed up the conversion by handling the \type{path} +%D seperately. + +\def\dohandleMPsequence#1% + {\ifdone + \ifcase\lccode`#1\relax + \@EAEAEA\dohandleMPsequenceA + \else + \@EAEAEA\dohandleMPsequenceB + \fi + \else + \@EA\dohandleMPsequenceC + \fi#1} + +\let\dohandleMPsequenceA\setMPsequence + +\def\installMPSkeywordN#1#2% + {\expandafter\def\csname\@@MP:N:#1\endcsname{#2}} + +\def\installMPSshortcutN#1#2% todo: \let + {\expandafter\let\csname\@@MP:N:#1\expandafter\endcsname\csname\@@MP:N:#2\endcsname} + +\def\dohandleMPsequenceB#1 % + {\edef\somestring{#1}% + \executeifdefined{\@@MP:N:\somestring}\handleMPgraphic + \handleMPsequence} + +\installMPSkeywordN \PSmoveto + {\edef\lastMPmoveX{\gMPa1}% + \edef\lastMPmoveY{\gMPa2}% + \resetMPstack} +\installMPSkeywordN \PSnewpath + {\let\handleMPsequence\handleMPpath} +\installMPSkeywordN \PSgsave + {\PDFcode{q}% + \resetMPstack} +\installMPSkeywordN \PSgrestore + {\PDFcode{Q}% + \resetMPstack} +\installMPSkeywordN \PSdtransform % == setlinewidth + {\let\handleMPsequence\handleMPdtransform} + % after that we will encounter more tokens until setlinewidth+pop + % or pop+setlinewidth which we catch next; we explicitly need to + % reset the stack since [] n setdash may follow; a more clever + % approach would be to read on till the condition is met, but it's + % the only pop / setlinewidth we will encounter so ... +\installMPSkeywordN \PSsetlinewidth + {% already handled in dtransform + \resetMPstack} +\installMPSkeywordN \PSpop + {% already handled in dtransform + \resetMPstack} +\installMPSkeywordN \PSconcat + {\cleanupMPconcat + \PDFcode{\gMPa1 \gMPa2 \gMPa3 \gMPa4 \gMPa5 \gMPa6 cm}% + \resetMPstack} +\installMPSkeywordN \PSsetrgbcolor + {\handleMPrgbcolor + \resetMPstack} +\installMPSkeywordN \PSsetcmykcolor + {\handleMPcmykcolor + \resetMPstack} +\installMPSkeywordN \PSsetgray + {\handleMPgraycolor + \resetMPstack} +\installMPSkeywordN \PStranslate + {\PDFcode{1 0 0 1 \gMPa1 \gMPa2 cm}% + \resetMPstack} +\installMPSkeywordN \PSsetdash + {\handleMPsetdash + \resetMPstack} +\installMPSkeywordN \PSsetlinejoin + {\PDFcode{\gMPa1 j}% + \resetMPstack} +\installMPSkeywordN \PSsetmiterlimit + {\PDFcode{\gMPa1 M}% + \resetMPstack} +\installMPSkeywordN \PSfshow + {%\PDFcode{n}% removed ! + \handleMPfshow + \resetMPstack} +\installMPSkeywordN \PSsetlinecap + {\PDFcode{\gMPa1 J}% + \resetMPstack} +\installMPSkeywordN \PSrlineto + {\flushMPmoveto + \PDFcode{\!MP\lastMPmoveX\space\!MP\lastMPmoveY\space l S}% + \resetMPmoveto + \resetMPstack} +\installMPSkeywordN \PSscale + {\PDFcode{\gMPa1 0 0 \gMPa2 0 0 cm}% + \resetMPstack} +\installMPSkeywordN \PSspecial + {\handleMPspecialcommand + \resetMPstack} + +\installMPSshortcutN {n} \PSnewpath +\installMPSshortcutN {p} \PSclosepath +\installMPSshortcutN {l} \PSlineto +\installMPSshortcutN {r} \PSrlineto +\installMPSshortcutN {m} \PSmoveto +\installMPSshortcutN {c} \PScurveto +\installMPSshortcutN {C} \PSsetcmykcolor +\installMPSshortcutN {G} \PSsetgray +\installMPSshortcutN {R} \PSsetrgbcolor +\installMPSshortcutN {lj} \PSsetlinejoin +\installMPSshortcutN {ml} \PSsetmiterlimit +\installMPSshortcutN {lc} \PSsetlinecap +\installMPSshortcutN {sd} \PSsetdash +\installMPSshortcutN {S} \PSstroke +\installMPSshortcutN {F} \PSfill +\installMPSshortcutN {W} \PSclip + +\installMPSshortcutN {q} \PSgsave +\installMPSshortcutN {Q} \PSgrestore + +\installMPSshortcutN {s} \PSscale +\installMPSshortcutN {t} \PSconcat +\installMPSshortcutN {P} \PSshowpage + +\installMPSkeywordN {hlw} {\PDFcode{\gMPa1 w}\resetMPstack} +\installMPSkeywordN {vlw} {\PDFcode{\gMPa1 w}\resetMPstack} +\installMPSkeywordN {rd} {\PDFcode{[] 0 d}\resetMPstack} + +\def\dohandleMPsequenceC#1 % + {\edef\somestring{#1}% + \handleMPgraphic + \handleMPsequence} + +%D Since colors are not sensitive to transformations, they +%D are sometimes used for signaling. Therefore, we handle them +%D separately. The next macro can be redefined if needed. + +\def\handleMPrgbcolor + {\PDFcode{\!MPgMPa1 \!MPgMPa2 \!MPgMPa3 rg + \!MPgMPa1 \!MPgMPa2 \!MPgMPa3 RG}} + +\def\handleMPcmykcolor + {\PDFcode{\!MPgMPa1 \!MPgMPa2 \!MPgMPa3 \!MPgMPa4 k + \!MPgMPa1 \!MPgMPa2 \!MPgMPa3 \!MPgMPa4 K}} + +\def\handleMPgraycolor + {\PDFcode{\!MPgMPa1 g + \!MPgMPa1 G}} + +\def\handleMPspotcolor + {\PDFcode{0 g + 0 G}} + +%D Beginning and ending the graphics is taken care of by the +%D macro \type{\handleMPgraphic}, which is redefined when +%D the first graphics operator is met. + +\def\handleMPendgraphic % #1% + {\ifx\somestring\PSshowpage + \let\handleMPsequence\finishMPgraphic + \else\ifx\somestring\PSEof + \let\handleMPsequence\finishMPgraphic + \else + \letMPargument\somestring % {#1}% + \fi\fi} + +\def\handleMPbegingraphic % #1% + {\ifx\somestring\PSBoundingBox + \def\handleMPsequence{\handleMPboundingbox1}% + \else\ifx\somestring\PSHiResBoundingBox + \def\handleMPsequence{\handleMPboundingbox2}% + \else\ifx\somestring\PSExactBoundingBox + \def\handleMPsequence{\handleMPboundingbox3}% + \else\ifx\somestring\PSshowpage + \let\handleMPsequence\finishMPgraphic + \else\ifx\somestring\PSEof + \let\handleMPsequence\finishMPgraphic + \else\ifx\somestring\PSPage + \let\handleMPsequence\handleMPpage + \else\ifx\somestring\PSMetaPostSpecials + \let\handleMPsequence\handleMPspecialscomment + \else\ifx\somestring\PSMetaPostSpecial + \let\handleMPsequence\handleMPspecialcomment + \else\ifx\somestring\PSBeginProlog + \let\handleMPsequence\handleMPprolog + \else + \letMPargument\somestring % {#1}% + \fi\fi\fi\fi\fi\fi\fi\fi\fi} + +\let\handleMPgraphic=\handleMPbegingraphic + +%D New: we can best filter the prolog because nowdays it can contain +%D quite some code. + +% hm, catcode mess, so we need to tweak %'s catcode here +% \long\expandafter\def\expandafter\handleMPprolog\expandafter#\expandafter1\PSEndProlog% +% but today i'm not in the mood for ugly stuff + +\long\def\handleMPprolog#1EndProlog % + {\doresetMPstack + \let\handleMPsequence\dohandleMPsequence + \handleMPsequence} + +%D We check for three kind of bounding boxes: the normal one +%D and two high precision ones: +%D +%D \starttyping +%D BoundingBox: llx lly ucx ucy +%D HiResBoundingBox: llx lly ucx ucy +%D ExactBoundingBox: llx lly ucx ucy +%D \stoptyping +%D +%D The original as well as the recalculated dimensions are +%D saved for later use. + +\newif\ifskipemptyMPgraphic \skipemptyMPgraphicfalse + +\chardef\currentMPboundingbox=0 + +\def\handleMPboundingbox#1#2 #3 #4 #5 + {\ifnum#1>\currentMPboundingbox + \chardef\currentMPboundingbox#1\relax + \xdef\MPllx {#2}% + \xdef\MPlly {#3}% + \xdef\MPurx {#4}% + \xdef\MPury {#5}% + \xdef\MPwidth {\the\dimexpr\MPurx\onebasepoint-\MPllx\onebasepoint\relax}% + \xdef\MPheight{\the\dimexpr\MPury\onebasepoint-\MPlly\onebasepoint\relax}% + \fi + \doresetMPstack + \let\handleMPsequence\dohandleMPsequence + \let\next\handleMPsequence + \ifskipemptyMPgraphic + \ifdim\MPheight=\zeropoint\ifdim\MPwidth=\zeropoint + \def\next{\endinput\finishMPgraphic}% + \fi\fi + \fi + \next} + +%D Unless defined otherwise, we simply ignore specialcomments. + +\def\handleMPspecialcomment + {\doresetMPstack + \let\handleMPsequence\dohandleMPsequence + \handleMPsequence} + +\let\handleMPspecialscomment\handleMPspecialcomment + +%D We use the \type{page} comment as a signal that +%D stackbuilding can be started. + +\def\handleMPpage #1 #2 + {\doresetMPstack + \donetrue + \let\handleMPsequence\dohandleMPsequence + \handleMPsequence} + +%D The same applies to the special extensions. + +\def\handleMPspecialcommand + {\doresetMPstack + \let\handleMPsequence\dohandleMPsequence + \handleMPsequence} + +%D \METAPOST\ draws its dots by moving to a location and +%D invoking \type{0 0 rlineto}. This operator is not +%D available in \PDF. Our solution is straightforward: we draw +%D a line from $(current\_x, current\_y)$ to itself. This +%D means that the arguments of the preceding \type{moveto} have +%D to be saved. + +%D These saved coordinates are also used when we handle the +%D texts. Text handling proved to be a bit of a nuisance, but +%D finally I saw the light. It proved that we also had to +%D take care of \type{(split arguments)}. + +% \startMPcode +% draw btex Ga toch effe f\kern0ptietsen?{}` etex ; +% \stopMPcode + +\newtoks \everyMPshowfont + +\def\setMPfshowfont#1#2% + {\font\temp=#1\space at #2\relax\temp + \the\everyMPshowfont} + +\let\MPfshowcommand\empty + +\def\dohandleMPfshow + {\setbox\scratchbox\hbox + {\obeyMPspecials + \edef\MPtextsize{\gMPa\nofMParguments}% + \def\do(##1){##1}% only works in latest mp + \edef\MPtextdata{\dogMPa1}% beware, stack can have more + \handleMPtext}% + \setbox\scratchbox\hbox + {\hskip\lastMPmoveX\onebasepoint + \raise\lastMPmoveY\onebasepoint + \box\scratchbox}% + \smashbox\scratchbox + \box\scratchbox} + +\def\handleMPtext {\handleMPtextnormal} % so we can overload this one later +\def\handleMPfshow{\dohandleMPfshow } % so we can overload this one later + +\def\handleMPtext + {\ifnum\nofMParguments>\plusthree + \handleMPtextnormal + \else + \defconvertedcommand\MPtextdata\MPtextdata + \expanded{\splitstring\MPtextdata}\at::::\to\MPtexttag\and\MPtextnumber + \executeifdefined{handleMPtext\MPtexttag}\handleMPtextnormal + \fi} + +% elsewhere we will implement \handleMPtextmptxt + +\def\doflushMPtext#1% + {\edef\!!stringa{#1}% + \@EA\dodoflushMPtext\!!stringa\relax} + +\def\dodoflushMPtext + {\afterassignment\dododoflushMPtext\let\nexttoken=} + +\def\dododoflushMPtext + {\ifx\nexttoken\relax + % done + \else\ifx\nexttoken\char + \@EA\@EA\@EA\dodododoflushMPtext + \else + {\nexttoken}% + \@EA\@EA\@EA\dodoflushMPtext + \fi\fi} + +\def\dodododoflushMPtext + {\afterassignment\dododododoflushMPtext\scratchcounter} + +\def\dododododoflushMPtext + {{\char\scratchcounter}\let\next\dodoflushMPtext} + +\def\handleMPtextnormal + {\let\ \relax % mp breaks long lines and appends a \ + \ifx\MPtextsize\PSnfont % round font size (to pt) + \advance\nofMParguments \minusone + \expandafter\scratchdimen\gMPa\nofMParguments\onepoint\relax + \ifdim\scratchdimen<\onepoint + \def\MPtextsize{1pt}% + \else + \advance\scratchdimen .5\onepoint + \def\MPtextsize##1.##2\relax{\def\MPtextsize{##1pt}}% + \expandafter\MPtextsize\the\scratchdimen\relax + \fi + \else + \edef\MPtextsize{\MPtextsize bp}% + \fi + \advance\nofMParguments \minusone + \setMPfshowfont{\gMPa\nofMParguments}\MPtextsize + \advance\nofMParguments \minusone + \temp + \MPfshowcommand + {\ifnum\nofMParguments=\plusone + \def\do(##1){##1}% + \doflushMPtext{\dogMPa1}% + \else % can't happen anymore in mp version 1+ + % we need to catch ( a ) (a a a) (\123 \123 \123) etc + \scratchcounter\plusone + \def\dodo##1% Andreas Fieger's bug: (\304...) + {\edef\!!stringa{##1\empty\empty}% and another one: ( 11) -> \ifx 11 + \ifx\!!stringa\MPspacechar\MPspacechar\else\expandafter##1\fi}% + \def\do(##1{\dodo{##1}}% + \dogMPa\scratchcounter\MPspacechar + \let\do\relax + \loop + \advance\scratchcounter \plusone + \ifnum\scratchcounter<\nofMParguments\relax + \gMPa\scratchcounter\MPspacechar + \repeat + \def\do##1){\dodo{##1}}% + \dogMPa\scratchcounter + \fi + \unskip}} + +%D You could consider the following definition to be the most +%D natural one. + +% \def\MPspacechar{\space} % normal case + +\def\MPspacechar{\char32\relax} % old solution does not work with math + +%D However, the following implementation is more robust, since +%D some fonts have funny visible spaces in the space slot. This +%D gives a mismatch between the space that \METAPOST\ took into +%D account and the \quote {natural} space. This only happens in +%D labels, since \type {btex}||\type {etex} thingies don't have +%D spaces. This phenomena showed up when preparing the +%D \METAFUN\ manual, where Palatino fonts are used. We can +%D safely assume that \METAPOST\ considers \type {\char32} to +%D be the space. + +\def\MPspacechar{\setbox\scratchbox\hbox{\char32}\kern\wd\scratchbox} + +%D Well, this does not work with math fonts, so: + +\def\MPspacechar{\char32\relax} + +%D Most operators are just converted and keep their +%D arguments. Dashes however need a bit different treatment, +%D otherwise \PDF\ viewers complain loudly. Another +%D complication is that one argument comes after the \type{]}. +%D When reading the data, we simply ignore the array boundary +%D characters. We save ourselves some redundant newlines and +%D at the same time keep the output readable by packing the +%D literals. + +\def\handleMPsetdash + {\bgroup + \ignoreMPspecials + \let\somestring\empty + \scratchcounter\plusone + \loop + \ifnum\scratchcounter<\nofMParguments + \edef\somestring{\somestring\space\gMPa\scratchcounter}% + \advance\scratchcounter \plusone + \repeat + \edef\somestring{[\somestring]\space\gMPa\scratchcounter\space d}% + \PDFcode{\somestring}% + \egroup} + +%D The \type{setlinewidth} commands looks a bit complicated. There are +%D two alternatives, that result in a similar look in both +%D $x$- and $y$-dorection. As John Hobby says: +%D +%D \startnarrower \switchtobodyfont[ss] +%D \starttyping +%D x 0 dtransform exch truncate exch idtransform pop setlinewidth +%D 0 y dtransform truncate idtransform setlinewidth pop +%D \stoptyping +%D +%D These are just fancy versions of \type{x setlinewidth} and +%D \type{y setlinewidth}. The \type{x 0 ...} form is used if +%D the path is {\em primarily vertical}. It rounds the width +%D so that vertical lines come out an integer number of pixels +%D wide in device space. The \type{0 y ...} form does the same +%D for paths that are {\em primarily horizontal}. The reason +%D why I did this is Knuth insists on getting exactly the +%D widths \TEX\ intends for the horizontal and vertical rules +%D in \type{btex...etex} output. (Note that PostScript scan +%D conversion rules cause a horizontal or vertical line of +%D integer width $n$ in device space to come out $n+1$ pixels +%D wide, regardless of the phase relative to the pixel grid.) +%D \stopnarrower +%D +%D The common operator in these sequences is \type{dtransform}, +%D so we can use this one to trigger setting the linewidth. + +\def\handleMPdtransform + {\ifdim\gMPa1\onepoint>\zeropoint + \PDFcode{\gMPa1 w}% + \def\next##1 ##2 ##3 ##4 ##5 ##6 {\handleMPsequence}% + \else + \PDFcode{\gMPa2 w}% + \def\next##1 ##2 ##3 ##4 {\handleMPsequence}% + \fi + \let\handleMPsequence\dohandleMPsequence + \resetMPstack + \next} + +%D The most complicated command is \type{concat}. \METAPOST\ +%D applies this operator to \type{stroke}. At that moment the +%D points set by \type{curveto} and \type{moveto}, are already +%D fixed. In \PDF\ however the \type{cm} operator affects the +%D points as well as the pen (stroke). Like more \PDF\ +%D operators, \type{cm} is defined in a bit ambiguous way. +%D The only save route for non||circular penshapes, is saving +%D the path, recalculating the points and applying the +%D transformation matrix in such a way that we can be sure +%D that its behavior is well defined. This comes down to +%D inverting the path and applying \type{cm} to that path as +%D well as the pen. This all means that we have to save the +%D path. + +%D In \METAPOST\ there are three ways to handle a path $p$: +%D +%D \starttyping +%D draw p; fill p; filldraw p; +%D \stoptyping +%D +%D The last case outputs a \type{gsave fill grestore} before +%D \type{stroke}. Handling the path outside the main loops +%D saves about 40\% run time.\footnote{We can save some more by +%D following the \METAPOST\ output routine, but for the moment +%D we keep things simple.} Switching between the main loop and +%D the path loop is done by means of the recursely called +%D macro \type{\handleMPsequence}. + +\def\handleMPpath + {\chardef\finiMPpath\zerocount + \let\closeMPpath\relax + \let\flushMPpath\flushnormalMPpath + \resetMPstack + \nofMPsegments\plusone + \let\handleMPsequence\dohandleMPpath + \dohandleMPpath} + +%D Most paths are drawn with simple round pens. Therefore we've +%D split up the routine in two. + +\def\resetMPmoveto + {\let\lastMPmoveX\empty + \let\lastMPmoveY\empty} + +\resetMPmoveto + +\def\flushMPmoveto + {\ifx\lastMPmoveX\empty \else + \PDFcode{\!MP\lastMPmoveX\space \!MP\lastMPmoveY\space m}% + \fi} + +\def\flushnormalMPsegment + {\ifcase\getMPkeyword\relax + \flushMPmoveto + \resetMPmoveto + \PDFcode{\!MPgMPs1 \!MPgMPs2 l}% + \or + \flushMPmoveto + \resetMPmoveto + \PDFcode{\!MPgMPs1 \!MPgMPs2 \!MPgMPs3 \!MPgMPs4 \!MPgMPs5 \!MPgMPs6 c}% + \or + \ifx\lastMPmoveX\empty \else % we assume 0,0 rlineto + \flushMPmoveto + \PDFcode{\!MP\lastMPmoveX\space \!MP\lastMPmoveY\space l}% + \resetMPmoveto + \fi + \or + % \flushMPmoveto + % \resetMPmoveto + \fi} + +\def\flushMPconcatmoveto + {\ifx\lastMPmoveX\empty\else + \doMPconcat\lastMPmoveX\lastMPmoveX\lastMPmoveY\lastMPmoveY + \flushMPmoveto + \fi} + +\def\flushconcatMPsegment + {\ifcase\getMPkeyword\relax + \flushMPconcatmoveto + \resetMPmoveto + \doMPconcat{\gMPs1}\a{\gMPs2}\b% + \PDFcode{\!MP\a\space\!MP\b\space l}% + \or + \flushMPconcatmoveto + \resetMPmoveto + \doMPconcat{\gMPs1}\a{\gMPs2}\b% + \doMPconcat{\gMPs3}\c{\gMPs4}\d% + \doMPconcat{\gMPs5}\e{\gMPs6}\f% + \PDFcode{\!MP\a\space\!MP\b\space + \!MP\c\space\!MP\d\space + \!MP\e\space\!MP\f\space c}% + \or % rather mp specific ... rline always has 0,0 + \bgroup + \noMPtranslate + \flushMPconcatmoveto + % next should be \lastMPmoveX+\a,\lastMPmoveY+\b but we know it's 0,0 + \PDFcode{\!MP\lastMPmoveX\space\!MP\lastMPmoveY\space l S}% + \resetMPmoveto + \egroup + \or +% \flushMPconcatmoveto +% \resetMPmoveto + \fi} + +\def\doflushsomeMPpath + {\dodoflushsomeMPpath + \advance\nofMPsegments \plusone + \ifnum\nofMPsegments<\scratchcounter + \expandafter\doflushsomeMPpath + \fi} + +\def\flushsomeMPpath + {\scratchcounter\nofMPsegments + \nofMPsegments\plusone + \doflushsomeMPpath} + +\def\flushnormalMPpath{\let\dodoflushsomeMPpath\flushnormalMPsegment\flushsomeMPpath} + +%OLD \def\flushconcatMPpath{\let\dodoflushsomeMPpath\flushconcatMPsegment\flushsomeMPpath} + +%NEW pre-calculate 1/D so it needn't be repeated for each control point. + +\def\flushconcatMPpath + {\MPreciprocaldeterminant + \let\dodoflushsomeMPpath\flushconcatMPsegment\flushsomeMPpath} + +%D The transformation of the coordinates is handled by one of +%D the macros Tanmoy posted to the \PDFTEX\ mailing list. +%D I rewrote and optimized the original macro to suit the other +%D macros in this module. +%D +%D \starttyping +%D \doMPconcat {x position} \xresult {y position} \yresult +%D \stoptyping +%D +%D By setting the auxiliary \DIMENSIONS\ \type{\dimen0} upto +%D \type{\dimen10} only once per path, we save over 20\% run +%D time. Some more speed was gained by removing some parameter +%D passing. These macros can be optimized a bit more by using +%D more constants. There is however not much need for further +%D optimization because penshapes usually are round and +%D therefore need no transformation. Nevertheless we move the +%D factor to the outer level and use a bit different \type{pt} +%D removal macro. Although the values represent base points, +%D we converted them to pure points, simply because those can +%D be converted back. + +%OLD \mathchardef\MPconcatfactor=256 % beware don't remove spaces before it + +%OLD \def\doMPreducedimen#1 +%OLD {\count0\MPconcatfactor +%OLD \advance\dimen#1 \ifdim\dimen#1>\zeropoint .5\else -.5\fi\count0 +%OLD \divide\dimen#1 \count0\relax} + +%OLD % too inaccurate (see old pragma logo) +%OLD +%OLD \def\doMPreducedimen#1 +%OLD {\count0=\MPconcatfactor +%OLD \divide\dimen#1 \count0\relax} + +%OLD \def\doMPreducedimen#1 +%OLD {\advance\dimen#1 \ifdim\dimen#1>\zeropoint .5\else -.5\fi\MPconcatfactor +%OLD \divide\dimen#1 \MPconcatfactor} + +%D The transformation code is rewritten by Daniel H. Luecking who +%D describes his patch as follows: +%D +%D We would like to divide 1 by $X$, but all divisions are integer so +%D for accuracy we want to convert to large integers and make sure the +%D integer quotient has as many significant digits as possible. Thus we +%D need to replace $1/X$ with $M/N$ where $N$ is as large as possible +%D and $M/N$ is as large as possible. Also for simplicity $M$ should be +%D a power of 2. So we make $M = 2^{30}$ \footnote{$2^{31} - 1$ is the +%D largest legal integer. Using it (and simply ignoring the inaccuracy +%D caused by $-1$) turns out to be at least as accurate in all cases, +%D and more accurate in some.} (largest legal power of 2) and adjust +%D $X$ downward (if necessary) to the the range $1-2^{16}$. This gives +%D at least 15 significant binary digits, (almost as accurate as +%D \METAPOST\ for numbers near 1) or almost 5 significant figures +%D (decimal). + +\newcount\MPscratchCnt +\newdimen\MPscratchDim % will be assigned global + +\def\MPadjustdimen % sets \MPscratchDim and \MPscratchCnt + {\MPscratchCnt\zerocount + \doMPadjustdimen} + +\def\doMPadjustdimen + {\ifdim\MPscratchDim>\onepoint + \divide \MPscratchDim\plustwo + \advance\MPscratchCnt\plusone + \expandafter\doMPadjustdimen + \fi} + +%OLD \def\doMPexpanddimen#1 +%OLD {\multiply\dimen#1 \MPconcatfactor\relax} + +%D DHL: When viewed as an integer, $1 \hbox{pt}=2^{16}$ so $2^{32}/X$ +%D is the right way to do $(1 \hbox{pt})/(X \hbox{pt})$ and get the +%D answer in points. But we are limited to $2^{30}/X$. However, we +%D actually do $[ 2^{30} / (X/2^K) ]*2^{2-K}$ where $K$ is the number +%D of halvings it takes to bring $X$ below $1 \hbox{pt}$. If $K$ is 0 +%D or 1 we readjust by multiplying by 4 or 2, otherwise by halving +%D $(K-2)$ times \type {\MPscratchCnt} holds the value of $K$ from +%D \type {\MPadjustdimen}. + +\def\MPreadjustdimen % acts on \MPscratchDim and MPscratchCnt + {\ifcase\MPscratchCnt + \multiply\scratchdimen \plusfour + \or + \multiply\scratchdimen \plustwo + \else + \expandafter\doMPreadjustdimen + \fi} + +\def\doMPreadjustdimen + {\ifnum\MPscratchCnt>\plustwo + \divide \scratchdimen\plustwo + \advance\MPscratchCnt\minusone + \expandafter\doMPreadjustdimen + \fi} + +\def\MPreciprocaldeterminant + {\scratchdimen\withoutpt\the\dimen0 \dimen6 % s_x*s_y + \advance\scratchdimen -\withoutpt\the\dimen2 \dimen4 % s_x*s_y - r_x*r_y + \ifdim\scratchdimen<\zeropoint % we need a positive dimension + \scratchdimen-\scratchdimen % for \MPadjustdimen (?) + \doMPreciprocal + \scratchdimen-\scratchdimen + \else + \doMPreciprocal + \fi + \edef\MPreciprocal{\withoutpt\the\scratchdimen}} + +\newcount\MPnumerator \MPnumerator = 1073741824 % 2^{30} + +% todo: dimexpr + +\def\doMPreciprocal % replace \scratchdimen with its reciprocal + {\ifdim\scratchdimen=\onepoint \else + \MPadjustdimen + \scratchcounter\MPnumerator + \divide\scratchcounter\scratchdimen + \scratchdimen1\scratchcounter % 1 needed + \MPreadjustdimen + \fi} + +%OLD \def\presetMPconcat +%OLD {\dimen 0=\gMPs1\onepoint \doMPreducedimen 0 % r_x +%OLD \dimen 2=\gMPs2\onepoint \doMPreducedimen 2 % s_x +%OLD \dimen 4=\gMPs3\onepoint \doMPreducedimen 4 % s_y +%OLD \dimen 6=\gMPs4\onepoint \doMPreducedimen 6 % r_y +%OLD \dimen 8=\gMPs5\onepoint \doMPreducedimen 8 % t_x +%OLD \dimen10=\gMPs6\onepoint \doMPreducedimen10 } % t_y +%OLD +%OLD \def\presetMPscale +%OLD {\dimen 0=\gMPs1\onepoint \doMPreducedimen 0 +%OLD \dimen 2 \zeropoint +%OLD \dimen 4 \zeropoint +%OLD \dimen 6=\gMPs2\onepoint \doMPreducedimen 6 +%OLD \dimen 8 \zeropoint +%OLD \dimen10 \zeropoint} + +\def\cleanupMPconcat + {\ignoreMPspecials + \docleanupMPargument1% + \docleanupMPargument6% + \keepMPspecials} + +\def\presetMPconcat + {\dimen 0=\gMPs1\onepoint % s_x + \dimen 2=\gMPs2\onepoint % r_x + \dimen 4=\gMPs3\onepoint % r_y + \dimen 6=\gMPs4\onepoint % s_y + \dimen 8=\gMPs5\onepoint % t_x + \dimen10=\gMPs6\onepoint} % t_y + +\def\presetMPscale + {\dimen 0=\gMPs1\onepoint + \dimen 2 \zeropoint + \dimen 4 \zeropoint + \dimen 6=\gMPs2\onepoint + \dimen 8 \zeropoint + \dimen10 \zeropoint} + +\def\noMPtranslate % use this one grouped + {\dimen 8 \zeropoint % t_x + \dimen10 \zeropoint} % t_y + +%D \starttyping +%D \def\doMPconcat#1#2#3#4% +%D {\dimen12=#1 pt \doMPreducedimen12 % p_x +%D \dimen14=#3 pt \doMPreducedimen14 % p_y +%D % +%D \dimen16 \dimen 0 +%D \multiply \dimen16 \dimen 6 +%D \dimen20 \dimen 2 +%D \multiply \dimen20 \dimen 4 +%D \advance \dimen16 -\dimen20 +%D % +%D \dimen18 \dimen12 +%D \multiply \dimen18 \dimen 6 +%D \dimen20 \dimen14 +%D \multiply \dimen20 \dimen 4 +%D \advance \dimen18 -\dimen20 +%D \dimen20 \dimen 4 +%D \multiply \dimen20 \dimen10 +%D \advance \dimen18 \dimen20 +%D \dimen20 \dimen 6 +%D \multiply \dimen20 \dimen 8 +%D \advance \dimen18 -\dimen20 +%D % +%D \multiply \dimen12 -\dimen 2 +%D \multiply \dimen14 \dimen 0 +%D \advance \dimen12 \dimen14 +%D \dimen20 \dimen 2 +%D \multiply \dimen20 \dimen 8 +%D \advance \dimen12 \dimen20 +%D \dimen20 \dimen 0 +%D \multiply \dimen20 \dimen10 +%D \advance \dimen12 -\dimen20 +%D % +%D \doMPreducedimen16 +%D \divide \dimen18 \dimen16 \doMPexpanddimen18 +%D \divide \dimen12 \dimen16 \doMPexpanddimen12 +%D % +%D \edef#2{\withoutpt\the\dimen18}% % p_x^\prime +%D \edef#4{\withoutpt\the\dimen12}} % p_y^\prime +%D \stoptyping + +%D The following optimization resulted from some tests by +%D and email exchanges with Sanjoy Mahajan. +%D +%D \starttyping +%D \def\doMPconcat#1#2#3#4% +%D {\dimen12=#1 pt \doMPreducedimen12 % p_x +%D \dimen14=#3 pt \doMPreducedimen14 % p_y +%D % +%D \dimen16 \dimen 0 +%D \multiply \dimen16 \dimen 6 +%D \dimen20 \dimen 2 +%D \multiply \dimen20 \dimen 4 +%D \advance \dimen16 -\dimen20 +%D % +%D \dimen18 \dimen12 +%D \multiply \dimen18 \dimen 6 +%D \dimen20 \dimen14 +%D \multiply \dimen20 \dimen 4 +%D \advance \dimen18 -\dimen20 +%D \dimen20 \dimen 4 +%D \multiply \dimen20 \dimen10 +%D \advance \dimen18 \dimen20 +%D \dimen20 \dimen 6 +%D \multiply \dimen20 \dimen 8 +%D \advance \dimen18 -\dimen20 +%D % +%D \multiply \dimen12 -\dimen 2 +%D \multiply \dimen14 \dimen 0 +%D \advance \dimen12 \dimen14 +%D \dimen20 \dimen 2 +%D \multiply \dimen20 \dimen 8 +%D \advance \dimen12 \dimen20 +%D \dimen20 \dimen 0 +%D \multiply \dimen20 \dimen10 +%D \advance \dimen12 -\dimen20 +%D % +%D %\ifdim\dimen16>\onepoint % oeps, can be < 1pt too +%D \ifdim\dimen16=\onepoint \else +%D \ifdim\dimen16>\MPconcatfactor pt +%D \doMPreducedimen16 +%D \divide \dimen18 \dimen16 \doMPexpanddimen18 +%D \divide \dimen12 \dimen16 \doMPexpanddimen12 +%D \else +%D \divide \dimen18 \dimen16 \doMPexpanddimen18 \doMPexpanddimen18 +%D \divide \dimen12 \dimen16 \doMPexpanddimen12 \doMPexpanddimen12 +%D \fi +%D \fi +%D % +%D \edef#2{\withoutpt\the\dimen18}% % p_x^\prime +%D \edef#4{\withoutpt\the\dimen12}} % p_y^\prime +%D \stoptyping +%D +%D But, this one is still too inaccurate, so we now have: + +%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 +%D arithmetic instead of using real factors because it's faster. +%D However, the actual macros test slower, possibly because I've +%D omitted three nested loops. In my test files, my approach is more +%D accurate. It is also far simpler and overflow does not seem to be a +%D significant concern. The scale factors written by Metapost are (?) +%D always $<=1$ (it scales coordinates internally) and coordinates are +%D always likely to be less than \type {\maxdimen}. +%D +%D If this should ever cause problems, the scale factors can be reduced. + +% the original: +% +% \def\doMPconcat#1#2#3#4% +% {\dimen12=#1\onepoint% p_x % #1\onepoint +% \dimen14=#3\onepoint% p_y % #3\onepoint +% \advance\dimen12 -\dimen8 % p_x - t_x +% \advance\dimen14 -\dimen10 % p_y - t_y +% \dimen18=\withoutpt\the\dimen6 \dimen12 % s_y(p_x - t_x) +% \advance\dimen18 -\withoutpt\the\dimen4 \dimen14 % - r_y(p_y-t_y) +% \dimen14=\withoutpt\the\dimen0 \dimen14 % s_x(p_y-t_y) +% \advance\dimen14 -\withoutpt\the\dimen2 \dimen12 % - r_x(p_x-t_x) +% % \MPreciprocal contains precomputed 1/D: +% \dimen18=\MPreciprocal\dimen18 +% \dimen14=\MPreciprocal\dimen14 +% \edef#2{\withoutpt\the\dimen18}% % p_x^\prime +% \edef#4{\withoutpt\the\dimen14}} % p_y^\prime +% +% faster but not that often used + +\def\doMPconcat#1#2#3#4% + {\dimen12\dimexpr#1\points-\dimen 8\relax % p_x-t_x + \dimen14\dimexpr#3\points-\dimen10\relax % p_y-t_y + \dimen18\dimexpr\withoutpt\the\dimen6\dimen12-\withoutpt\the\dimen4\dimen14\relax % s_y(p_x-t_x)-r_y(p_y-t_y) + \dimen14\dimexpr\withoutpt\the\dimen0\dimen14-\withoutpt\the\dimen2\dimen12\relax % s_x(p_y-t_y)-r_x(p_x-t_x) + \edef#2{\withoutpt\the\dimexpr\MPreciprocal\dimen18\relax}% % p_x^\prime + \edef#4{\withoutpt\the\dimexpr\MPreciprocal\dimen14\relax}} % p_y^\prime + +%D One reason for Daniel to write this patch was that at small sizes +%D the accuracy was less than optimal. Here is a test that demonstrates +%D that his alternative is pretty good: +%D +%D \startlinecorrection +%D \startMPcode +%D for i = 5cm,1cm,5mm,1mm,.5mm,.1mm,.01mm : +%D draw fullcircle scaled i withpen pencircle xscaled (i/10) yscaled (i/20) rotated 45 ; +%D endfor ; +%D \stopMPcode +%D \stoplinecorrection + +%D The following explanation of the conversion process was +%D posted to the \PDFTEX\ mailing list by Tanmoy. The original +%D macro was part of a set of macro's that included sinus and +%D cosinus calculations as well as scaling and translating. The +%D \METAPOST\ to \PDF\ conversion however only needs +%D transformation. + +%M \start \switchtobodyfont [ss] + +%D Given a point $(U_x, U_y)$ in user coordinates, the business +%D of \POSTSCRIPT\ is to convert it to device space. Let us say +%D that the device space coordinates are $(D_x, D_y)$. Then, in +%D \POSTSCRIPT\ $(D_x, D_y)$ can be written in terms of +%D $(U_x, U_y)$ in matrix notation, either as +%D +%D \placeformula +%D \startformula +%D \pmatrix{D_x&D_y&1\cr} = \pmatrix{U_x&U_y&1\cr} +%D \pmatrix{s_x&r_x&0\cr +%D r_y&s_y&0\cr +%D t_x&t_y&1\cr} +%D \stopformula +%D +%D or +%D +%D \placeformula +%D \startformula +%D \pmatrix{D_x\cr D_y\cr 1} = \pmatrix{s_x&r_y&t_x\cr +%D r_x&s_y&t_y\cr +%D 0 &0 &1 \cr} +%D \pmatrix{U_x\cr +%D U_y\cr +%D 1 \cr} +%D \stopformula +%D +%D both of which is a shorthand for the same set of equations: +%D +%D \placeformula +%D \startformula +%D D_x = s_x U_x + r_y U_y + t_x +%D \stopformula +%D +%D \placeformula +%D \startformula +%D D_y = r_x U_x + s_y U_y + t_y +%D \stopformula +%D +%D which define what is called an `affine transformation'. +%D +%D \POSTSCRIPT\ represents the `transformation matrix' as a +%D six element matrix instead of a $3\times 3$ array because +%D three of the elements are always~0, 0 and~1. Thus the above +%D transformation is written in postscript as $[s_x\, r_x\, +%D r_y\, s_y\, t_x\, t_y]$. However, when doing any +%D calculations, it is useful to go back to the original +%D matrix notation (whichever: I will use the second) and +%D continue from there. +%D +%D As an example, if the current transformation matrix is +%D $[s_x\, r_x\, r_y\, s_y\, t_x\, t_y]$ and you say \typ{[a b +%D c d e f] concat}, this means: +%D +%D \startnarrower +%D Take the user space coordinates and transform them to an +%D intermediate set of coordinates using array $[a\, b\, c\, d\, +%D e\, f]$ as the transformation matrix. +%D +%D Take the intermediate set of coordinates and change them to +%D device coordinates using array $[s_x\, r_x\, r_y\, s_y\, t_x\, t_y]$ +%D as the transformation matrix. +%D \stopnarrower +%D +%D Well, what is the net effect? In matrix notation, it is +%D +%D \placeformula +%D \startformula +%D \pmatrix{I_x\cr I_y\cr 1\cr} = \pmatrix{a&c&e\cr +%D b&d&f\cr +%D 0&0&1\cr} +%D \pmatrix{U_x\cr +%D U_y\cr +%D 1 \cr} +%D \stopformula +%D +%D \placeformula +%D \startformula +%D \pmatrix{D_y\cr D_y\cr 1\cr} = \pmatrix{s_x&r_y&t_x\cr +%D r_x&s_y&t_y\cr +%D 0 &0 &1 \cr} +%D \pmatrix{I_x\cr +%D I_y\cr +%D 1 \cr} +%D \stopformula +%D +%D where $(I_x, I_y)$ is the intermediate coordinate. +%D +%D Now, the beauty of the matrix notation is that when there is +%D a chain of such matrix equations, one can always compose +%D them into one matrix equation using the standard matrix +%D composition law. The composite matrix from two matrices can +%D be derived very easily: the element in the $i$\high{th} +%D horizontal row and $j$\high{th} vertical column is +%D calculated by`multiplying' the $i$\high{th} row of the first +%D matrix and the $j$\high{th} column of the second matrix (and +%D summing over the elements). Thus, in the above: +%D +%D \placeformula +%D \startformula +%D \pmatrix{D_x\cr D_y\cr 1} = \pmatrix{s_x^\prime&r_y^\prime&t_x^\prime\cr +%D r_x^\prime&s_y^\prime&t_y^\prime\cr +%D 0 &0 &0 \cr} +%D \pmatrix{U_x\cr +%D U_y\cr +%D 1 \cr} +%D \stopformula +%D +%D with +%D +%D \placeformula +%D \startformula +%D \eqalign +%D {s_x^\prime & = s_x a + r_y b \cr +%D r_x^\prime & = r_x a + s_y b \cr +%D r_y^\prime & = s_x c + r_y d \cr +%D s_y^\prime & = r_x c + s_y d \cr +%D t_x^\prime & = s_x e + r_y f + t_x \cr +%D t_y^\prime & = r_x e + s_y f + t_y \cr} +%D \stopformula + +%D In fact, the same rule is true not only when one is going +%D from user coordinates to device coordinates, but whenever +%D one is composing two `transformations' together +%D (transformations are `associative'). Note that the formula +%D is not symmetric: you have to keep track of which +%D transformation existed before (i.e.\ the equivalent of +%D $[s_x\, r_x\, r_y\, s_y\, t_x\, t_y]$) and which was +%D specified later (i.e.\ the equivalent of $[a\, b\, c\, d\, +%D e\, f]$). Note also that the language can be rather +%D confusing: the one specified later `acts earlier', +%D converting the user space coordinates to intermediate +%D coordinates, which are then acted upon by the pre||existing +%D transformation. The important point is that order of +%D transformation matrices cannot be flipped (transformations +%D are not `commutative'). +%D +%D Now what does it mean to move a transformation matrix +%D before a drawing? What it means is that given a point +%D $(P_x, P_y)$ we need a different set of coordinates +%D $(P_x^\prime, P_y^\prime)$ such that if the transformation +%D acts on $(P_x^\prime, P_y^\prime)$, they produce $(P_x, +%D P_y)$. That is we need to solve the set of equations: +%D +%D \placeformula +%D \startformula +%D \pmatrix{P_x\cr P_y\cr 1\cr} = \pmatrix{s_x&r_y&t_x\cr +%D r_x&s_y&t_y\cr +%D 0 &0 &1 \cr} +%D \pmatrix{P_x^\prime\cr +%D P_y^\prime\cr +%D 1 \cr} +%D \stopformula +%D +%D Again matrix notation comes in handy (i.e. someone has +%D already solved the problem for us): we need the inverse +%D transformation matrix. The inverse transformation matrix can +%D be calculated very easily: +%D +%D \placeformula +%D \startformula +%D \pmatrix{P_x^\prime\cr P_y^\prime\cr 1\cr} = +%D \pmatrix{s_x^\prime&r_y^\prime&t_x^\prime\cr +%D r_x^\prime&s_y^\prime&t_y^\prime\cr +%D 0 &0 &1 \cr} +%D \pmatrix{P_x\cr +%D P_y\cr +%D 1 \cr} +%D \stopformula +%D +%D where, the inverse transformation matrix is given by +%D +%D \placeformula +%D \startformula +%D \eqalign +%D {D & = s_x s_y - r_x r_y \cr +%D s_x^\prime & = s_y / D \cr +%D s_y^\prime & = s_x / D \cr +%D r_x^\prime & = - r_x / D \cr +%D r_y^\prime & = - r_y / D \cr +%D t_x^\prime & = ( - s_y t_x + r_y t_y ) / D \cr +%D t_y^\prime & = ( r_x t_x - s_x t_y ) / D \cr} +%D \stopformula +%D +%D And you can see that when expanded out, this does +%D give the formulas: +%D +%D \placeformula +%D \startformula +%D P_x^\prime = { { s_y(p_x-t_x) + r_y(t_y-p_y) } \over +%D { s_x s_y-r_x r_y } } +%D \stopformula +%D +%D \placeformula +%D \startformula +%D P_y^\prime = { { s_x(p_y-t_y) + r_x(t_x-p_x) } \over +%D { s_x*s_y-r_x*r_y } } +%D \stopformula +%D +%D The code works by representing a real number by converting +%D it to a dimension to be put into a \DIMENSION\ register: 2.3 would +%D be represented as 2.3pt for example. In this scheme, +%D multiplying two numbers involves multiplying the \DIMENSION\ +%D registers and dividing by 65536. Accuracy demands that the +%D division be done as late as possible, but overflow +%D considerations need early division. +%D +%D Division involves dividing the two \DIMENSION\ registers and +%D multiplying the result by 65536. Again, accuracy would +%D demand that the numerator be multiplied (and|/|or the +%D denominator divided) early: but that can lead to overflow +%D which needs to be avoided. +%D +%D If nothing is known about the numbers to start with (in +%D concat), I have chosen to divide the 65536 as a 256 in each +%D operand. However, in the series calculating the sine and +%D cosine, I know that the terms are small (because I never +%D have an angle greater than 45 degrees), so I chose to +%D apportion the factor in a different way. + +%M \stop + +%D The path is output using the values saved on the stack. If +%D needed, all coordinates are recalculated. + +\def\finishMPpath + {\PDFcode{\ifcase\finiMPpath W n\or S\or f\or B\fi}} + +\def\processMPpath + {\checkMPpath + \ifcase\nofMPsegments\else + \flushMPpath + \closeMPpath + \finishMPpath + \fi + \let\handleMPsequence\dohandleMPsequence + \resetMPstack + \nofMPsegments\zerocount + \handleMPsequence} + +%D The following \METAPOST\ code is quite valid but, when +%D processed and converted to \PDF, will make a file +%D unprintable on a Hewlett Packard printer (from Acrobat +%D $v<=5$). Who is to blame, the driver of the OS layer in +%D between, is hard to determine, so we add an additional +%D check. +%D +%D \starttyping +%D clip currentpicture to origin -- cycle ; +%D setbounds currentpicture to fullsquare scaled 5cm ; +%D \stoptyping + +\def\checkMPpath + {\ifcase\finiMPpath + \ifnum\nofMPsegments<\plusthree % n is one ahead + \message{omitting zero clip path}% + \nofMPsegments\zerocount + \fi + \fi} + +%D In \PDF\ the \type{cm} operator must precede the path +%D specification. We therefore can output the \type{cm} at +%D the moment we encounter it. + +\def\handleMPpathconcat + {\presetMPconcat + \PDFcode{\gMPs1 \gMPs2 \gMPs3 \gMPs4 \gMPs5 \gMPs6 cm}% + \resetMPstack} + +\def\handleMPpathscale + {\presetMPscale + \PDFcode{\gMPs1 0 0 \gMPs2 0 0 cm}% + \resetMPstack} + +%D This macro interprets the path and saves it as compact as +%D possible. + +\def\dohandleMPpath#1% + {\ifcase\lccode`#1\relax + \@EA\dohandleMPpathA + \else + \@EA\dohandleMPpathB + \fi#1} + +\let\dohandleMPpathA\setMPsequence + +\def\installMPSkeywordP#1#2% + {\expandafter\def\csname\@@MP:P:#1\endcsname{#2}} + +\def\installMPSshortcutP#1#2% todo: \let + {\expandafter\let\csname\@@MP:P:#1\expandafter\endcsname\csname\@@MP:P:#2\endcsname} + +\def\dohandleMPpathB#1 % + {\def\somestring{#1}% + \executeifdefined{\@@MP:P:\somestring}\relax + \handleMPsequence} + +\installMPSkeywordP \PSlineto + {\setMPkeyword0 } +\installMPSkeywordP \PScurveto + {\setMPkeyword1 } +\installMPSkeywordP \PSrlineto + {\setMPkeyword2 } +\installMPSkeywordP \PSmoveto + {\edef\lastMPmoveX{\gMPs1}% + \edef\lastMPmoveY{\gMPs2}% + \resetMPstack + \setMPkeyword3 } +\installMPSkeywordP \PSclip + {% \chardef\finiMPpath\zerocount % already + \let\handleMPsequence\processMPpath} +\installMPSkeywordP \PSgsave + {\chardef\finiMPpath\plusthree} +\installMPSkeywordP \PSgrestore + {} +\installMPSkeywordP \PSfill + {\ifcase\finiMPpath + \chardef\finiMPpath\plustwo + \let\handleMPsequence\processMPpath + \fi} +\installMPSkeywordP \PSstroke + {\ifcase\finiMPpath + \chardef\finiMPpath\plusone + \fi + \let\handleMPsequence\processMPpath} +\installMPSkeywordP \PSclosepath + {\def\closeMPpath{\PDFcode{h}}} +\installMPSkeywordP \PSconcat + {\cleanupMPconcat + \let\flushMPpath\flushconcatMPpath + \handleMPpathconcat} +\installMPSkeywordP \PSscale + {\let\flushMPpath\flushconcatMPpath + \handleMPpathscale} + +\installMPSshortcutP {l} \PSlineto +\installMPSshortcutP {r} \PSrlineto +\installMPSshortcutP {m} \PSmoveto +\installMPSshortcutP {c} \PScurveto + +\installMPSshortcutP {q} \PSgsave +\installMPSshortcutP {Q} \PSgrestore +\installMPSshortcutP {S} \PSstroke +\installMPSshortcutP {F} \PSfill +\installMPSshortcutP {B} \PSgsave +\installMPSshortcutP {W} \PSclip +\installMPSshortcutP {p} \PSclosepath + +\installMPSshortcutP {s} \PSscale +\installMPSshortcutP {t} \PSconcat + +%D \macros +%D {twodigitMPoutput} +%D +%D We can limit the precision to two digits after the comma +%D by saying: +%D +%D \starttyping +%D \twodigitMPoutput +%D \stoptyping +%D +%D This option only works in \CONTEXT\ combined with \ETEX. + +\def\twodigitMPoutput + {\let\!MP \twodigitrounding + \def\!MPgMPs##1{\twodigitrounding{\gMPs##1}}% + \def\!MPgMPa##1{\twodigitrounding{\gMPa##1}}} + +\let\!MP \empty +\let\!MPgMPa\gMPa +\let\!MPgMPs\gMPs + +%D Here comes the special-specific code: + +\def\setMPextensions + {\ifconditional\manyMPspecials + \def\MPrgbnumber##1{\expandafter\doMPrgbnumber##10000.00000\relax}% + \def\doMPrgbnumber##1.##2##3##4##5##6\relax{##2##3##4##5}% + \else + \def\MPrgbnumber##1{\expandafter\doMPrgbnumber##1000.0000\relax}% + \def\doMPrgbnumber##1.##2##3##4##5\relax{##2##3##4}% + \fi} + +% \settrue\manyMPspecials \setMPextensions + +%D This macro handles the special definitions that are +%D passed as comment. + +%D The implementation below saves the data on the stack in +%D a way similar to the macros in \type {supp-pdf.tex}, and +%D just overload a few already defined handlers. That way, +%D the existing macros are still generic. \footnote {Actually, +%D the macros here are just as generic.} +%D +%D Currently the only extension concerns shading, which is +%D accomplished by handling yet another value of \type +%D {\finiMPpath}. The recource disctionary is stored and +%D later picked up by the general \CONTEXT\ figure inclusion +%D macros. + +%D The \type {%%MetaPostSpecials: version.revision signal} line +%D triggers this module into handling color specifications kind +%D of special. We need this safeguard for non||special +%D usage. + +%D When defined inline, we use another macro to handle the +%D definitions. Actually, this macro is called by the +%D previous ones. + +\chardef\MPspecialversion = 0 % specials when >1 +\chardef\MPspecialrevision = 0 % specials when >1 +\chardef\MPspecialsignal = 0 % passed on by graphic + +\chardef\inlineMPspecials = 1 % only needed for stack resetting + +\def\dohandleMPspecialcomment#1 + {\setMPargument{#1}% + \advance\scratchcounter \minusone + \ifcase\scratchcounter + \handleMPspecialcommand + \donetrue + \doresetMPstack + \let\handleMPsequence\dohandleMPsequence + \expandafter\handleMPsequence + \else + \expandafter\dohandleMPspecialcomment + \fi} + +\def\handleMPspecialcomment #1 % number of arguments + {\doresetMPstack + \scratchcounter#1\relax + \ifcase\scratchcounter % when zero, inline shading is used + \chardef\inlineMPspecials\plusone + \let\handleMPsequence\dohandleMPsequence + \expandafter\handleMPsequence + \else + \chardef\inlineMPspecials\zerocount + \expandafter\dohandleMPspecialcomment + \fi} + +%D When defined inline, we use another macro to handle the +%D definitions. Actually, this macro is called by the +%D previous ones. + +\def\handleMPspecialcommand + {\ifcase\inlineMPspecials\or + \advance\nofMParguments \minusone % pop the size + \fi + \ifundefined\MPspecial % beware, no real \if + \message{[unknown \MPspecial]}% + \else + \csname\MPspecial\endcsname + \fi + \ifcase\inlineMPspecials + \doresetMPstack % 0 + \else + \resetMPstack % 1 + \fi} + +\def\handleMPspecialscomment #1.#2 #3 % version.revision signal #4=div=1000|10000 + {\doresetMPstack + \chardef\MPspecialversion #1% + \chardef\MPspecialrevision#2% + \chardef\MPspecialsignal #3% + \let\handleMPsequence\dohandleMPsequence + \ifnum#1=\plusone + \expandafter\handleMPsequence + \else + \expandafter\handleMPspecialscommentx + \fi} + +\def\handleMPspecialscommentx #1 % version 2 + {\ifnum10000=0#1\relax + \settrue \manyMPspecials + \else + \setfalse\manyMPspecials + \fi + \setMPextensions + \handleMPsequence} + +\def\handleMPrgbcolor + {\edef\lastMPrvalue{\csname\@@MP01\endcsname}%{\gMPs1}% + \edef\lastMPgvalue{\csname\@@MP02\endcsname}%{\gMPs2}% + \edef\lastMPbvalue{\csname\@@MP03\endcsname}%{\gMPs3}% + \ifnum\MPrgbnumber\lastMPrvalue=123\relax + \csname\@@MPSK\number\MPrgbnumber\lastMPbvalue\endcsname + \else + \dohandleMPrgb\lastMPrvalue\lastMPgvalue\lastMPbvalue + \fi} + +\def\handleMPgraycolor{\dohandleMPgray{\gMPs1}} +\def\handleMPcmykcolor{\dohandleMPcmyk{\gMPs1}{\gMPs2}{\gMPs3}{\gMPs4}} +\def\handleMPspotcolor{\dohandleMPspot{\gMPs1}{\gMPs2}{\gMPs3}{\gMPs4}} + +% \newcontitional\ignoreMPpath + +\def\finishMPpath + {\ifconditional\ignoreMPpath + \PDFcode{W n\space}% + \else + \PDFcode{\ifcase\finiMPpath W n\or S\or f\or B\else W n\fi}% + \fi + \ifx\extraMPpathcode\empty\else + \PDFcode{\extraMPpathcode}% + \let\extraMPpathcode\empty + \fi + \setfalse\ignoreMPpath} + +\def\processMPpath + {\checkMPpath % ! + \flushMPpath + \closeMPpath + \finishMPpath + \let\handleMPsequence\dohandleMPsequence + \resetMPstack + \nofMPsegments\zerocount + \handleMPsequence} + +\protect \endinput + +% When i'm bored ... + +% \newcatcodetable\mpscatcodes + +% \startcatcodetable \mpscatcodes +% \catcode`\| \@@comment +% \catcode`\% \@@active +% \catcode`\[ \@@active +% \catcode`\] \@@active +% \catcode`\{ \@@active +% \catcode`\} \@@active +% \stopcatcodetable + +% \def\keepMPspecials +% {\setcatcodecommand \mpscatcodes `\% \letterpercent +% \setcatcodecommand \mpscatcodes `\[ \letterleftbracket +% \setcatcodecommand \mpscatcodes `\] \letterrightbracket +% \setcatcodecommand \mpscatcodes `\{ \letterleftbrace +% \setcatcodecommand \mpscatcodes `\} \letterrightbrace} + +% \def\ignoreMPspecials +% {\setcatcodecommand \mpscatcodes `\% \letterpercent +% \setcatcodecommand \mpscatcodes `\[ \empty +% \setcatcodecommand \mpscatcodes `\] \empty +% \setcatcodecommand \mpscatcodes `\{ \empty +% \setcatcodecommand \mpscatcodes `\} \empty} + +% \def\obeyMPspecials +% {\setcatcodecommand \mpscatcodes `\% \letterpercent +% \setcatcodecommand \mpscatcodes `\[ \letterleftbracket +% \setcatcodecommand \mpscatcodes `\] \letterrightbracket +% \setcatcodecommand \mpscatcodes `\{ \letterleftbrace +% \setcatcodecommand \mpscatcodes `\} \letterrightbrace} + +% \gdef\setMPspecials| +% {\setcatcodetable\mpscatcodes +% \lccode`\-=\zerocount % to be sure, it could be a letter +% \lccode`\%=`\%% % otherwise it's seen as a number +% \def\({\char40\relax }% +% \def\){\char41\relax }% +% \def\\{\char92\relax }% +% \def\0{\octalMPcharacter0}% +% \def\1{\octalMPcharacter1}% +% \def\2{\octalMPcharacter2}% +% \def\3{\octalMPcharacter3}% +% \def\4{\octalMPcharacter4}% +% \def\5{\octalMPcharacter5}% +% \def\6{\octalMPcharacter6}% +% \def\7{\octalMPcharacter7}% +% \def\8{\octalMPcharacter8}% +% \def\9{\octalMPcharacter9}} diff --git a/tex/context/base/meta-pdf.mkiv b/tex/context/base/meta-pdf.mkiv new file mode 100644 index 000000000..fa9627fbe --- /dev/null +++ b/tex/context/base/meta-pdf.mkiv @@ -0,0 +1,474 @@ +%D \module +%D [ file=meta-pdf, +%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] +%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{meta-pdf}{1.003} + +%D We will clean up the color mess later. + +\writestatus{loading}{MetaPost Graphics / MPS to PDF} + +\unprotect + +%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 + +\def\PDFMPformoffset + {\ifdefined\objectoffset\objectoffset\else\zeropoint\fi} + +%D The main macro: + +\def\convertMPtoPDF#1#2#3% scaling no longer supported at this level (so #2 & #3 ignored) + {\vbox\bgroup + \message{[MP to PDF]}% + \xdef\MPfilename{#1}% + \glet\MPwidth \!!zeropoint + \glet\MPheight\!!zeropoint + \glet\MPllx \!!zerocount + \glet\MPlly \!!zerocount + \glet\MPurx \!!zerocount + \glet\MPury \!!zerocount + \forgetall + \offinterlineskip + \setbox\scratchbox\vbox\bgroup + \ctxlua{mptopdf.convertmpstopdf("\MPfilename")}\removeunwantedspaces + \egroup + \setbox\scratchbox\hbox\bgroup + \hskip-\MPllx\onebasepoint + \raise-\MPlly\onebasepoint + \box\scratchbox + \egroup + \setbox\scratchbox\vbox to \MPheight\bgroup + \vfill + \hsize\MPwidth + \smashbox\scratchbox + \box\scratchbox + \egroup + \wd\scratchbox\MPwidth + \ht\scratchbox\MPheight + \dopackageMPgraphic\scratchbox + \egroup} + +%D Objects (move all to backend) + +% \def\dopackageMPgraphic#1% #1 = boxregister +% {\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{#1}% +% \ifdim\scratchdimen>\zeropoint % compensate for error +% \vbox to \MPheight +% {\forgetall\vss\hbox to \MPwidth{\hss\getMPPDFobject\hss}\vss}% +% \else +% \getMPPDFobject +% \fi} +% +% \def\setMPPDFobject#1% boxnumber +% {\the\pdfbackendeveryxform +% \finalizeobjectbox{#1}% +% \immediate\pdfxform resources{\pdfcurrentresources}#1% +% \edef\getMPPDFobject{\noexpand\pdfrefxform\the\pdflastxform}} +% +% \let\getMPPDFobject\relax + +% we don't need to package as each page has all resources anyway + +\let\dopackageMPgraphic\box + +%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 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 + +%D We support specials but assume that the files are somewhat simple +%D ones wo we have dropped a few. The reason is that runtime \METAPOST\ +%D processing now uses \MPLIB\ so we only need to deal with the +%D conversion here. See meta-pdh.mkiv (and older files) for more +%D details. Here we just give a few examples. +%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]} +%D +%D Transparency support used specials 60 (rgb) and 61 +%D (cmyk). +%D +%D \startbuffer +%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 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 \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 \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 \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 \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 +%D +%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 + +\startMPinitializations + mp_shade_version := 2 ; +\stopMPinitializations + +%D This is done much cleaner in \MPLIB. + +% %D A common hook. +% +% \let\MPfshowcommand\empty +% +% \def\MPStextext#1#2#3#4#5% if we clean up this plugin model, we can +% {\def\MPtextdata{#3}% % delegate the splitter to lua + redesign +% \def\MPtextsize{#2}% +% \def\lastMPmoveX{#4}% +% \def\lastMPmoveY{#5}% +% \defconvertedcommand\MPtextdata\MPtextdata % no edef +% \splitstring\MPtextdata\at::::\to\MPtexttag\and\MPtextnumber +% \executeifdefined{handleMPtext\MPtexttag} +% {\setbox\scratchbox\hbox +% {\font\temp=#1\space at #2\onebasepoint +% \let\c\char +% \temp +% \MPfshowcommand{#3}}% +% \setbox\scratchbox\hbox +% {\hskip#4\onebasepoint +% \raise#5\onebasepoint +% \box\scratchbox}% +% \smashbox\scratchbox +% \box\scratchbox}} + +\unexpanded\def\MPStextext#1#2#3#4#5% if we clean up this plugin model, we can + {\setbox\scratchbox\hbox + {\font\temp=#1\space at #2\onebasepoint \let\c\char \temp #3}% + \setbox\scratchbox\hbox + {\hskip#4\onebasepoint \raise#5\onebasepoint \box\scratchbox}% + \smashbox\scratchbox + \box\scratchbox} + +%D The boundingbox. + +\def\MPSboundingbox#1#2#3#4% + {\xdef\MPllx{#1}\xdef\MPlly{#2}\xdef\MPurx{#3}\xdef\MPury{#4}% + \xdef\MPwidth {\the\dimexpr#3\onebasepoint-#1\onebasepoint\relax}% + \xdef\MPheight{\the\dimexpr#4\onebasepoint-#2\onebasepoint\relax}} + +\MPSboundingbox0000 + +%D Test code: +%D +%D \startbuffer +%D \startMPcode +%D fill fullcircle scaled 3cm withcolor red ; +%D fill fullcircle scaled 2cm withcolor green ; +%D fill fullcircle scaled 1cm withcolor blue ; +%D currentpicture := currentpicture shifted (-4cm,0) ; +%D fill fullcircle scaled 3cm withcolor cmyk(0,0,1,0) ; +%D fill fullcircle scaled 2cm withcolor cmyk(0,1,0,0) ; +%D fill fullcircle scaled 1cm withcolor cmyk(0,0,1,0) ; +%D currentpicture := currentpicture shifted (-4cm,0) ; +%D draw fullcircle scaled 3cm dashed evenly ; +%D draw fullcircle scaled 2cm dashed withdots ; +%D draw origin withpen pencircle scaled 3mm; +%D currentpicture := currentpicture shifted (-4cm,0) ; +%D fill fullcircle scaled 2cm shifted (-.5cm,+.5cm) withcolor transparent(1,.5,red); +%D fill fullcircle scaled 2cm shifted (-.5cm,-.5cm) withcolor transparent(1,.5,red); +%D fill fullcircle scaled 2cm shifted (+.5cm,+.5cm) withcolor transparent(1,.5,green); +%D fill fullcircle scaled 2cm shifted (+.5cm,-.5cm) withcolor transparent(1,.5,cmyk(1,0,1,.5)); +%D currentpicture := currentpicture shifted (12cm,-4cm) ; +%D draw "o e p s" infont defaultfont scaled 2 shifted (-1cm,0) ; +%D currentpicture := currentpicture shifted (-4cm,0) ; +%D % bug: shift +%D draw fullcircle scaled 3cm withpen pencircle yscaled 3mm xscaled 2mm rotated 30 ; +%D draw fullcircle scaled 2cm withpen pencircle yscaled 3mm xscaled 2mm rotated 20 withcolor red ; +%D filldraw fullcircle scaled 1cm withpen pencircle yscaled 3mm xscaled 2mm rotated 10 withcolor green ; +%D currentpicture := currentpicture shifted (-4cm,0) ; +%D % shade cannot handle shift +%D circular_shade(fullcircle scaled 3cm,0,.2red,.9green) ; +%D circular_shade(fullcircle scaled 3cm shifted(+4cm,0),0,cmyk(1,0,0,0),cmyk(0,1,0,0)) ; +%D filldraw boundingbox currentpicture enlarged -3cm withpen pencircle scaled 1pt withcolor .5white ; +%D \stopMPcode +%D \stopbuffer +%D +%D \typebuffer \startlinecorrection \getbuffer \stoplinecorrection + +\protect \endinput diff --git a/tex/context/base/meta-pdh.lua b/tex/context/base/meta-pdh.lua new file mode 100644 index 000000000..05cdfc176 --- /dev/null +++ b/tex/context/base/meta-pdh.lua @@ -0,0 +1,602 @@ +if not modules then modules = { } end modules ['meta-pdf'] = { + version = 1.001, + comment = "companion to meta-pdf.mkiv", + 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, find, gsub, gmatch = table.concat, string.format, string.find, string.gsub, string.gmatch +local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes +local tostring, tonumber, select = tostring, tonumber, select +local lpegmatch = lpeg.match + +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 = gsub(str,"\\(%d%d%d)",function(n) + return "\\char" .. tonumber(n,8) .. " " + end) + return gsub(str,"\\([%(%)\\])",mptopdf.descapes) +end + +function mptopdf.steps.descape(str) + str = gsub(str,"\\(%d%d%d)",function(n) + return "\\\\char" .. tonumber(n,8) .. " " + end) + return gsub(str,"\\([%(%)\\])",mptopdf.descapes) +end + +function mptopdf.steps.strip() -- .3 per expr + mptopdf.data = gsub(mptopdf.data,"^(.-)%%+Page:.-%c+(.*)%s+%a+%s+%%+EOF.*$", function(preamble, graphic) + local bbox = "0 0 0 0" + for b in gmatch(preamble,"%%%%%a+oundingBox: +(.-)%c+") do + bbox = b + end + local name, version = gmatch(preamble,"%%%%Creator: +(.-) +(.-) ") + mptopdf.version = tostring(version or "0") + if find(preamble,"/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 = gsub(mptopdf.data,"%%%%MetaPostSpecials: +(.-)%c+", "%1 specials\n", 1) + mptopdf.data = gsub(mptopdf.data,"%%%%MetaPostSpecial: +(.-)%c+", "%1 special\n") + mptopdf.data = gsub(mptopdf.data,"%%.-%c+", "") +end + +function mptopdf.steps.cleanup() + if not mptopdf.shortcuts then + mptopdf.data = gsub(mptopdf.data,"gsave%s+fill%s+grestore%s+stroke", "both") + mptopdf.data = gsub(mptopdf.data,"([%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 = gsub(mptopdf.data,"([%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 = gsub(mptopdf.data,"%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 = gsub(mptopdf.data,"%[%s*(.-)%s*%]", function(str) + return gsub(str,"%s+"," ") + end) + local t + mptopdf.data = gsub(mptopdf.data,"%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 .. "(" .. gsub(args," +",",") .. ")\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) + texsprint(ctxcatcodes,"\\pdfliteral{" .. str .. "}") -- \\MPScode +end + +function mptopdf.texcode(str) + texsprint(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 loop + 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 + +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 + +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,lpegmatch(package,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 find(mptopdf.data,"%%%%BeginResource: procset mpost") then + lpegmatch(captures_new,mptopdf.data) + else + lpegmatch(captures_old,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-pdh.mkiv b/tex/context/base/meta-pdh.mkiv new file mode 100644 index 000000000..7cdd1471f --- /dev/null +++ b/tex/context/base/meta-pdh.mkiv @@ -0,0 +1,780 @@ +%D \module +%D [ file=meta-pdf, +%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] +%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 and meta-pdf.mkiv. +%D +%D Beware: this file is not used but kept for historic purposed! + +% \useMPgraphic{1} +% \testfeatureonce{250}{\setbox0\hbox{\convertMPtoPDF{test-mps-mpgraph.1}{1}{1}}} +% +% 8.4 : mkii, direct parsing by tex +% 11.8 : mkiv, dirty conversion (10.8 with dirty tricks) +% 14.5 : mkiv, clean conversion +% 7.4 : mkiv, simulated clean direct lua from mp +% 0.3 : time taken by tex to handle converted code +% +% timings may differ now that we revamped the backend + +\registerctxluafile{meta-pdf}{1.003} + +%D We will clean up the color mess later. + +\writestatus{loading}{MetaPost Graphics / MPS to PDF} + +\unprotect + +%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\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% watch the transparency reset + {\resetMPvariables{#1}{#2}{#3}% + \vbox\bgroup + \forgetall + \offinterlineskip + \setbox\scratchbox\vbox\bgroup + \setnormalcatcodes % we can be in verbatim or so + \message{[MP to PDF]}% + \startMPresources + \pdfliteral{\letterpercent\space mps begin}% + \pdfliteral{q 1 0 0 1 0 0 cm}% + \ctxlua{mptopdf.convertmpstopdf("\MPfilename")}\removeunwantedspaces + \pdfliteral{Q}% + \pdfliteral{\letterpercent\space mps end}% + \stopMPresources + \egroup + \setbox\scratchbox\hbox\bgroup + \hskip-\MPllx\onebasepoint + \raise-\MPlly\onebasepoint + \box\scratchbox + \egroup + \setbox\scratchbox\vbox to \MPheight\bgroup + \vfill + \hsize\MPwidth + \smashbox\scratchbox + \box\scratchbox + \egroup + \wd\scratchbox\MPwidth + \ht\scratchbox\MPheight + \dopackageMPgraphic\scratchbox + \egroup} + +\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\everyPDFxform\undefined\else\the\everyPDFxform\fi + \immediate\pdfxform resources{#1}#2% + \edef\getMPPDFobject{\noexpand\pdfrefxform\the\pdflastxform}} + +\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 + +%D Specials: + +% \settrue \manyMPspecials \newcount\nofMParguments \let\extraMPpathcode\empty +% +% \def\@@MP {@@MP} +% \def\@@MPSK{@MPSK@} +% +% \def\MPspecial{\@@MPSK\@@MPSK\gMPs\nofMParguments} +% +% \unexpanded\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]} + +% \let\revokeMPtransparencyspecial\relax + +%D Transparency support used specials 60 (rgb) and 61 +%D (cmyk). +%D +%D \startbuffer +%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 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 +% \ctxlua{lpdf.adddocumentshade("Sh\the\currentPDFshade",lpdf.reference(\the\pdflastobj))}% +% \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}% +% \pdfliteral{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]}}% +% \pdfliteral{q #1 #2 #3 #4 #5 #6 cm}% +% \rlap{\getvalue{mps:x:#7}}% +% \pdfliteral{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 + +% \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 +% \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}% scratchdimen ? +% {\the\dimexpr\gMPs3\onebasepoint\relax}% +% {\the\dimexpr\gMPs4\onebasepoint\relax}% +% {0pt}} + +\startMPinitializations + mp_shade_version := 2 ; +\stopMPinitializations + +%D This is done much cleaner in \MPLIB. + +\def\MPStextext#1#2#3#4#5% if we clean up this plugin model, we can + {\def\MPtextdata{#3}% % delegate the splitter to lua + redesign + \def\MPtextsize{#2}% + \def\lastMPmoveX{#4}% + \def\lastMPmoveY{#5}% + \defconvertedcommand\MPtextdata\MPtextdata % no edef + \splitstring\MPtextdata\at::::\to\MPtexttag\and\MPtextnumber + \executeifdefined{handleMPtext\MPtexttag} + {\setbox\scratchbox\hbox + {\font\temp=#1\space at #2\onebasepoint + \let\c\char + \temp + \MPfshowcommand{#3}}% + \setbox\scratchbox\hbox + {\hskip#4\onebasepoint + \raise#5\onebasepoint + \box\scratchbox}% + \smashbox\scratchbox + \box\scratchbox}} + +%D We save the special variables on a stack. It's not that +%D fast, but it make implementing the special more convenient. + +% \def\MPSbegin +% {\nofMParguments\zerocount} +% +% \def\MPSend +% {\csname\MPspecial\endcsname} +% +% \def\MPSset +% {\advance\nofMParguments\plusone +% \expandafter\def\csname\@@MP\number\nofMParguments\endcsname} +% +% \def\gMPs#1{\csname\@@MP\number#1\endcsname} + +%D The boundingbox. + +\def\MPSboundingbox#1#2#3#4% + {\xdef\MPllx{#1}\xdef\MPlly{#2}\xdef\MPurx{#3}\xdef\MPury{#4}% + \xdef\MPwidth {\the\dimexpr#3\onebasepoint-#1\onebasepoint\relax}% + \xdef\MPheight{\the\dimexpr#4\onebasepoint-#2\onebasepoint\relax}} + +\MPSboundingbox0000 + +% \def\MPSspecial#1#2% +% {\csname\@@MPSK#2\endcsname} + +%D A path is (in most cases) just a sequence of \PDF\ commands. + +% \newconditional\ignoreMPpath + +% \def\MPSpath +% {\pdfliteral} + +% \def\MPScode % hack, will be improved +% {\ifconditional\ignoreMPpath +% \pdfliteral{h W n}% +% \ifx\extraMPpathcode\empty\else +% \pdfliteral{\extraMPpathcode}% +% \let\extraMPpathcode\empty +% \fi +% \setfalse\ignoreMPpath +% \expandafter\gobbleoneargument +% \else +% \expandafter\pdfliteral +% \fi} + +%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. + +% \def\dohandleMPshade#1% +% {\revokeMPtransparencyspecial +% \settrue\ignoreMPpath +% \def\extraMPpathcode{/#1 sh Q}% +% \pdfliteral{q /Pattern cs}} + +\protect \endinput diff --git a/tex/context/base/meta-pre.tex b/tex/context/base/meta-pre.tex new file mode 100644 index 000000000..cb861ff20 --- /dev/null +++ b/tex/context/base/meta-pre.tex @@ -0,0 +1,68 @@ +%D \module +%D [ file=meta-pre, +%D version=2001.03.21, +%D title=\METAPOST\ Graphics, +%D subtitle=Predefined 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 In this library, we define a couple of handy graphics. + +% todo: use the predefine grid macros, mp code will move to +% mp-* file + +\startuseMPgraphic{pagegrid} + StartPage ; + drawoptions(withcolor .8white) ; + fill Field[Text][Text] ; + drawoptions(withcolor .65white) ; + fill Field[Footer][Text] ; + fill Field[Header][Text] ; + fill Field[LeftMargin][Text] ; + fill Field[RightMargin][Text] ; + drawoptions(withcolor .65yellow) ; + fill Field[LeftEdge][Text] ; + fill Field[RightEdge][Text] ; + fill Field[Bottom][Text] ; + fill Field[Top][Text] ; + drawoptions(withpen pencircle scaled .3pt withcolor .65white) ; + for i=-3cm step 1cm until PaperWidth+3cm : + draw (i,-3cm)--(i,PaperHeight+3cm) ; + endfor ; + for i=PaperHeight+3cm step -1cm until -3cm : + draw (-3cm,i)--(PaperWidth+3cm,i) ; + endfor ; + drawoptions(withpen pencircle scaled .15pt) ; + for i=.5cm-3cm step 1cm until PaperWidth+3cm : + draw (i,-3cm)--(i,PaperHeight+3cm) ; + endfor ; + for i=PaperHeight-.5cm+3cm step -1cm until -3cm : + draw (-3cm,i)--(PaperWidth+3cm,i) ; + endfor ; + drawoptions(withpen pencircle scaled .3pt withcolor .65red) ; + for i=0 step 1cm until PaperWidth : + draw (i,0)--(i,PaperHeight) ; + endfor ; + for i=PaperHeight step -1cm until 0 : + draw (0,i)--(PaperWidth,i) ; + endfor ; + drawoptions(withpen pencircle scaled .15pt withcolor .65red) ; + for i=.5cm step 1cm until PaperWidth : + draw (i,0)--(i,PaperHeight) ; + endfor ; + for i=PaperHeight-.5cm step -1cm until 0 : + draw (0,i)--(PaperWidth,i) ; + endfor ; + drawoptions(withpen pencircle scaled 5pt withcolor .65red) ; + draw ulcorner Page ; + StopPage ; +\stopuseMPgraphic + +\defineoverlay[pagegrid][\useMPgraphic{pagegrid}] + +\endinput diff --git a/tex/context/base/meta-tex.mkii b/tex/context/base/meta-tex.mkii new file mode 100644 index 000000000..190a694d9 --- /dev/null +++ b/tex/context/base/meta-tex.mkii @@ -0,0 +1,350 @@ +%D \module +%D [ file=meta-tex, +%D version=2006.06.07, +%D title=\CONTEXT\ Support Macros, +%D subtitle=\METAPOST\ fast text insertion, +%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 Many thanks to Fabrice Popineau and Taco Hoekwater in helping me +%D figure out some aspects of the text inclusion method implemented +%D here. The following code is derived from a more advanced (and to +%D be used) mechanism where \TEX, \METAPOST\ and \LUA\ play together. + +%D Much of this mechanism was written with running live DVD's of +%D the Dave Matthews band in the background (or the corner of my +%D screen). + +% todo: testmacro for empty pic + +\unprotect + +\newwrite\TeXtextwrite + +\def\openTeXtexts {\immediate\openout \TeXtextwrite\currentTeXtext.mpb\relax} +\def\closeTeXtexts{\immediate\closeout\TeXtextwrite} + +\def\currentTeXtext {\jobname-mpgraph} +\def\currentTeXstack{mpgtxt} + +\initializeboxstack\currentTeXstack + +\newtoks\collectedmptexts +\newtoks\everyTeXtexts + +\chardef\TeXtextsmode\zerocount % no inheritance + +\long\def\startTeXtexts#1\stopTeXtexts + {\global\collectedmptexts\expandafter{\the\collectedmptexts#1}} + +\def\dostartTeXtexts + {\global\setfalse\TeXtextdone + \startnointerference + \openTeXtexts + \ifcase\TeXtextsmode + % normally there is no need for this (faster anyway) + \or + \scantokens\expandafter{\the\everyMPTEXgraphic}% brr + \or + \the\everyTeXtexts + \fi + \ifrunMPgraphics + \initializeboxstack\currentTeXstack + \else + \global\let\openTeXtexts\relax + \global\let\finishTeXtexts\closeTeXtexts + \fi} + +\def\dostopTeXtexts + {\ifrunMPgraphics + \closeTeXtexts + \fi + \stopnointerference} + +\let\finishTeXtexts\relax + +\appendtoks + \finishTeXtexts +\to \everystoptext + +\newconditional\TeXtextdone + +% \long\def\TeXtext#1% +% {\dowithnextboxcontent +% {\setnormalcatcodes} +% {\global\settrue\TeXtextdone +% \immediate\write\TeXtextwrite{savetxt(#1,\the\wd\nextbox,\the\ht\nextbox,\the\dp\nextbox);}% +% \savebox\currentTeXstack{#1}{\box\nextbox}} +% \hbox} + +\long\def\TeXtext + {\dosingleempty\doTeXtext} + +% currently, colors in the converter don't use the color stack +% +% 0 = nothing, withcolor works ok, but nested colors fail +% 1 = local color stack ok +% 2 = obey color stack (not yet supported) + +\chardef\TeXtextcolormode\plusone + +\def\definetextext[#1]#2{\setvalue{textext@@#1}{#2}} + +% \definetextext[framed]{\framed} +% +% \startMPcode +% draw \sometxt[framed]{black} rotated 45 ; +% \stopMPcode + +\long\def\doTeXtext[#1]#2#3% + {\begingroup + \setnormalcatcodes + \chardef\activecharactermode\plusone % compensates ** in meta-ini.mkii + \endlinechar\minusone + \everyeof\emptytoks + %\def\ascii{#3}\scantokens\expandafter{\ascii}}% + \setbox\nextbox\hbox + {\ifcase\TeXtextcolormode + \scantokens{\executeifdefined{textext@@#1}\firstofoneargument{#3}}% + \else + \localcolortrue + \startcurrentcolor + \scantokens{\executeifdefined{textext@@#1}\firstofoneargument{#3}}% + \stopcurrentcolor + \fi}% + \global\settrue\TeXtextdone + \edef\currenttextxt{\number#2}% + \executeifdefined{textext::#1}{\getvalue{textext::depth}}% + \savebox\currentTeXstack\currenttextxt{\box\nextbox}% + \endgroup} + +\setvalue{textext::depth}{\immediate\write\TeXtextwrite{savetxt(\currenttextxt,\the\nextboxwd,\the\nextboxht,\the\nextboxdp) shifted (0,-\the\nextboxdp);}} +\setvalue{textext::nodepth}{\immediate\write\TeXtextwrite{savetxt(\currenttextxt,\the\nextboxwd,\the\nextboxht,\the\nextboxdp);}} + +\setvalue{textext::d}{\getvalue{textext::depth}} +\setvalue{textext::n}{\getvalue{textext::nodepth}} + +\newbox\mptextbox + +% \loadmapfile[lm-texnansi.map] % the font is not really used, i.e. nothing ends up in the file +\definefontsynonym[MPtxtfont][texnansi-lmtt10] +\definefont[localMPtxtfont][MPtxtfont at 10bp] + +\ifx\getTeXtext\undefined + + % this took a while to figure out + + \let\MPtextdata\empty + + \def\getTeXtext + {\ifx\MPtextdata\empty\else + \localMPtxtfont + \setbox\mptextbox\hbox{\foundbox\currentTeXstack{\number\nofTeXtexts}}% + \setbox\scratchbox\hbox{\MPtextdata}% set in meta-pdf.mkii/mkiv + \edef\mpwd{\the\dimexpr\MPtextsize\dimexpr\wd\scratchbox/10\relax\relax}% + \edef\mpht{\the\dimexpr\MPtextsize\dimexpr\ht\scratchbox/10\relax\relax}% + \setbox\mptextbox\hbox{\raise\dp\mptextbox\box\mptextbox}% + \dp\mptextbox\zeropoint + \scale[\c!width=\mpwd,\c!height=\mpht]{\box\mptextbox}% + \fi} + +\fi + +\let\nofTeXtexts\!!zerocount + +\setvalue{handleMPtext00001}% only height in tag (00001) + {\setbox\scratchbox\hbox + {\obeyMPspecials + \edef\nofTeXtexts{\number\MPtextnumber}% + \getTeXtext}% + \setbox\scratchbox\hbox + {\hskip\lastMPmoveX\onebasepoint\raise\lastMPmoveY\onebasepoint + \box\scratchbox}% + \ht\scratchbox\zeropoint + \dp\scratchbox\zeropoint + \wd\scratchbox\zeropoint + \box\scratchbox} + +\startMPextensions + string txtfile ; txtfile := "\currentTeXtext.mpb" ; + string txtfont ; txtfont := "\truefontname{MPtxtfont}" ; + string txtpref ; txtpref := "00001::::" ; +\stopMPextensions + +\newcount\metatxtcounter + +\long\def\dodofiltersometxt#1#2#3% + {\ifx#2\empty + \else + \advance\metatxtcounter\plusone + \TeXtext{\the\metatxtcounter}{#1}% + \expandafter\filtersometxt + \fi#2#3} + +\long\def\redofiltersometxt[#1]#2% + {\advance\metatxtcounter\plusone + \TeXtext[#1]{\the\metatxtcounter}{#2}% + \filtersometxt} + +\long\def\filtersometxt#1\sometxt + {\doifnextoptionalelse\redofiltersometxt\dodofiltersometxt} + +% cleaner in mkiv +% +% \filtersometxt abc\sometxt{def};hij\sometxt{klm};\sometxt{}\empty\relax + +\long\def\flushTeXtexts#1% + {\metatxtcounter\zerocount + \dostartTeXtexts + \the\collectedmptexts + \filtersometxt#1\sometxt{}\empty\relax + \dostopTeXtexts + \ifconditional\TeXtextdone + \immediate\write\MPwrite{loadtxts ; txtnext := 0 ;}% + \global\collectedmptexts\emptytoks + \fi + \metatxtcounter\zerocount} + +% \long\def\sometxt#1{sometxt(nexttxt)} % to be used in mp definitions, no ; here + +\long\def\sometxt #1#{\dosometxt} % grab optional [args] +\long\def\dosometxt#1{sometxt(nexttxt)} % to be used in mp definitions, no ; here + +% we redefine the writer: + +\long\def\writecheckedMPgraphic#1% + {\ifforceMPTEXgraphic + \global\MPTEXgraphictrue + \else + \global\MPTEXgraphicfalse + \edef\ascii{#1}\defconvertedcommand\MPascii\ascii + \the\MPTEXgraphicchecks\relax % \relax is end condition! + \fi + \flushMPTEXgraphic% % verbatimtex etc + \flushTeXtexts{#1}% added + \writeMPgraphic{#1}} % potential optimization: pass \ascii + +\protect \endinput + +% torture test (will move) + +\startMPpage + numeric a_b_c ; + picture p ; pickup pencircle scaled .1pt ; + p := \sometxt{Just a \color[blue]{simple} example text.} ; + p := image(draw p; draw boundingbox p withcolor red; ) ; + p := p rotatedaround(center p, 360*(5/100)) ; + draw p ; draw boundingbox p withcolor blue ; + currentpicture := currentpicture scaled 20 ; + draw boundingbox currentpicture withcolor .5white ; + setbounds currentpicture to boundingbox currentpicture enlarged 10pt ; +\stopMPpage + +\startMPpage + picture p ; + p := \sometxt{\framed[width=fit,align=middle]{\input tufte\relax}} ; + draw p rotatedaround(center p, 30) ; +\stopMPpage + +\startMPpage + picture p ; + p := \sometxt{\framed[width=fit,align=middle]{\input tufte\relax}} ; + draw p slanted .5 ; +\stopMPpage + +\dorecurse{10} { + \startTeXtexts + \TeXtext{\recurselevel}{\ruledhbox{I must be {\green crazy} to implement this}} + \stopTeXtexts + \startMPpage + picture p ; pickup pencircle scaled .1pt ; + numeric i ; i := \recurselevel ; + p := sometxt(i) ; + p := p rotatedaround(center p, 360*(i*5/100)) ; + draw p ; draw boundingbox p withcolor blue ; + currentpicture := currentpicture scaled 20 ; + draw boundingbox currentpicture withcolor .5white ; + \stopMPpage +} + +\startTeXtexts + \dorecurse{100}{\TeXtext{\recurselevel}{\ruledhbox{\strut interesting \recurselevel}}} +\stopTeXtexts + +\startMPpage + picture p ; pickup pencircle scaled .1pt ; + for i = 1 upto 100: + p := sometxt(i) ; + p := p rotatedaround(center p, 360*(i*5/100)) ; + draw p ; draw boundingbox p withcolor blue ; + endfor ; + currentpicture := currentpicture scaled 20 ; + draw boundingbox currentpicture withcolor .5white ; +\stopMPpage + +\startTeXtexts + \dorecurse{100}{\TeXtext{\recurselevel}{\ruledhbox{\strut interesting \recurselevel}}} +\stopTeXtexts + +\startMPpage + picture p ; pickup pencircle scaled .1pt ; + for i = 1 step 5 until 100 : + p := sometxt(i) ; + p := p rotatedaround(center p, 360*(i/100)) ; + draw p ; draw boundingbox p withcolor blue ; + endfor ; + currentpicture := currentpicture scaled 20 ; + draw boundingbox currentpicture withcolor .5white ; +\stopMPpage + +\startTeXtexts + \dorecurse{20}{\TeXtext{\recurselevel}{\externalfigure[t:/sources/cow.pdf][width=1cm]}} +\stopTeXtexts + +\startMPpage + picture p ; pickup pencircle scaled .1pt ; + for i = 1 upto 20 : + p := sometxt(i) ; + p := p shifted (2.5cm,0) rotated (360*(i/20)) ; + draw p ; draw boundingbox p withcolor blue ; + endfor ; + currentpicture := currentpicture scaled 10 ; + draw boundingbox currentpicture withcolor .5white ; +\stopMPpage + +\startTeXtexts + \dorecurse{200}{\TeXtext{\recurselevel}{\ruledhbox{\strut I must be {\green crazy} \recurselevel}}} +\stopTeXtexts + +\startMPpage + picture p ; pickup pencircle scaled .1pt ; + numeric i ; i := 100 ; + p := sometxt(i) ; + p := p rotatedaround(center p, 360*(i*36/100)) ; + draw p ; draw boundingbox p withcolor blue ; + currentpicture := currentpicture scaled 20 ; + draw boundingbox currentpicture withcolor .5white ; +\stopMPpage + +\dorecurse{10}{ + \startTeXtexts + \dorecurse{200}{\TeXtext{\recurselevel}{\ruledhbox{\strut I must be {\green crazy} \recurselevel}}} + \stopTeXtexts + \startMPpage + picture p ; pickup pencircle scaled .1pt ; + j := 10*\recurselevel-9; + k := 10*\recurselevel; + for i = j upto k: + p := sometxt(i) ; + p := p rotatedaround(center p, 360*(i/100)) ; + draw p ; draw boundingbox p withcolor blue ; + endfor ; + currentpicture := currentpicture scaled 20 ; + draw boundingbox currentpicture withcolor red ; + \stopMPpage +} diff --git a/tex/context/base/meta-tex.mkiv b/tex/context/base/meta-tex.mkiv new file mode 100644 index 000000000..e35f95385 --- /dev/null +++ b/tex/context/base/meta-tex.mkiv @@ -0,0 +1,72 @@ +%D \module +%D [ file=meta-tex, +%D version=2006.06.07, +%D title=\CONTEXT\ Support Macros, +%D subtitle=\METAPOST\ fast text insertion, +%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 + +% Ok, we support this in MkIV because Mojca kept the pressure on. It +% looks a bit like a hack. + +\long\def\startTeXtexts#1\stopTeXtexts + {#1} + +\long\def\TeXtext + {\dosingleempty\doTeXtext} + +\long\def\doTeXtext[#1]#2#3% contrary to mkii we don't process yet but we do expand + {\long\setxvalue{@@st@@::#2}{\noexpand\dodoTeXtext{#1}{#3}}} + +\long\def\dodoTeXtext#1#2% + {\begingroup + \setbox\nextbox\hbox{\executeifdefined{textext@@#1}\firstofoneargument{#2}}% + \executeifdefined{textext::#1}{\getvalue{textext::depth}}% + \box\nextbox + \endgroup} + +\def\getTeXtext#1% + {\getvalue{@@st@@::#1}} + +\setvalue{textext::d}{\setbox\nextbox\hbox{\lower\dp\nextbox\box\nextbox}} % unchecked +\setvalue{textext::n}{} % unchecked + +\setvalue {textext::depth}{\getvalue{textext::d}} +\setvalue{textext::nodepth}{\getvalue{textext::n}} + +% \definetextext[framed]{\framed} +% +% \startMPcode +% draw \sometxt[framed]{black} rotated 45 ; +% \stopMPcode + +\unexpanded\def\definetextext[#1]#2{\setvalue{@@st@@[#1]}{#2}\setvalue{@@st@@[#1] }{#2}} % we don't grab spaces after [#1] + +\long\def\sometxt#1#{\dosometxt{#1}} % grab optional [args] + +\long\def\dosometxt#1#2% + {textext.drt("\ifcsname @@st@@#1\endcsname\csname @@st@@#1\endcsname{#2}\else#2\fi")} + +% Best use the mp macro instead since it provides positioning. +% +% \startuseMPgraphic{testgraphic} +% draw \sometxt{\ruledhbox{\strut hans hagen}} scaled 3; +% % draw textext.drt("\ruledhbox{\strut hans hagen}") scaled 3; +% % draw textext.dlft("\ruledhbox{\strut hans hagen}") scaled 3; +% % draw textext.lft("\ruledhbox{\strut hans hagen}") scaled 3; +% draw llcorner currentpicture -- urcorner currentpicture withcolor yellow; +% draw lrcorner currentpicture -- ulcorner currentpicture withcolor yellow; +% draw boundingbox currentpicture withcolor blue ; +% draw origin withcolor red withpen pencircle scaled 1pt; +% \stopuseMPgraphic +% +% {\showstruts\useMPgraphic{testgraphic}} + +\protect \endinput diff --git a/tex/context/base/meta-txt.tex b/tex/context/base/meta-txt.tex new file mode 100644 index 000000000..474253a40 --- /dev/null +++ b/tex/context/base/meta-txt.tex @@ -0,0 +1,304 @@ +%D \module +%D [ file=meta-txt, +%D version=2000.07.06, +%D title=\METAPOST\ Graphics, +%D subtitle=Text Tricks, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 this library some handy text manipulations are +%D defined. Some can and will be improved as soon as the +%D \TEX||\METAPOST\ interface is stable. Some of the +%D solutions may look weird, which is entirely my fault, +%D since I implemented them in the process of getting grip +%D on this kind of manipulations. Undoubtly better +%D \METAPOST\ code is possible, but my way of learning +%D this kind of trickery happens to be by \quote {trial +%D and error} and \quote {look and feel} (as well as +%D identifying tricks in Hobby's code). + +% textext ipv btex ... etex + +% we need a proper prefix here + +\unprotect + +\startMPextensions + if unknown context_text: input mp-text; fi; +\stopMPextensions + +%%%%%%% + +% \def\newchar#1{\chardef#1=0 } + +\ifdefined\MPtoks \else \newtoks\MPtoks \fi +\ifdefined\MPbox \else \newbox \MPbox \fi + +\ifdefined\parwidth \else \newdimen\parwidth \fi +\ifdefined\parheight \else \newdimen\parheight \fi +\ifdefined\parvoffset \else \newdimen\parvoffset \fi +\ifdefined\parhoffset \else \newdimen\parhoffset \fi +\ifdefined\parlines \else \newcount\parlines \fi +\ifdefined\partoks \else \newtoks \partoks \fi +\ifdefined\shapetextbox \else \newbox \shapetextbox \fi + \newif \ifparseries +\ifdefined\parfirst \else \chardef \parfirst=0 \fi + +\def\startshapetext[#1]% + {\global\newcounter\currentshapetext + \global\setbox\shapetextbox\vbox\bgroup + \expanded{\switchtobodyfont[\@@shbodyfont]}% + \dontcomplain + \hsize\parwidth + \setuptolerance[\v!verytolerant,\v!stretch]% + \!!counta\zerocount + \!!toksa\emptytoks + \def\docommand##1% + {\setbox\scratchbox\hbox{\useMPgraphic{##1}}% + \global\chardef\parfirst\zerocount + \getMPdata % \readlocfile{\MPdatafile}{}{}% + \setshapecharacteristics + \advance\!!counta by \parlines + \expandafter\appendtoks\the\partoks\to\!!toksa}% + \processcommalist[#1]\docommand + \global\parseriestrue + \xdef\totalparlines{\the\!!counta}% + \global\partoks\!!toksa + %\ifx\partoks\emptytoks\else % safeguard + \expanded{\parshape \the\!!counta \the\!!toksa}% + %\fi + \setshapecharacteristics % extra dummy + \ifparseries\def\par{\endgraf\adaptparshape}\fi + \EveryPar{\begstrut}} + +\def\stopshapetext + {\endstrut + %\removebottomthings + \egroup + \global\newcounter\currentshapetext + \getshapecharacteristics} + +\def\adaptparshape% + {\def\docommand##1% + {\ifcase\!!counta + \expandafter\appendtoks\space##1 \to\!!toksa + \else + \advance\!!counta \minusone + \fi}% + \!!counta\prevgraf + \doglobal\decrement(\totalparlines,\!!counta)% + \multiply\!!counta \plustwo + \!!toksa\emptytoks + \expanded{\processseparatedlist[\the\partoks][\space]}\docommand + \global\partoks\!!toksa + %\ifx\partoks\emptytoks\else % safeguard + \expanded{\parshape\totalparlines\the\partoks}% + }%\fi} + +\def\getshapecharacteristics% + {\doglobal\increment\currentshapetext + \doifdefinedelse{parlines:\currentshapetext} + {\global\parlines \getvalue{parlines:\currentshapetext}% + \global\chardef\parfirst \getvalue{parfirst:\currentshapetext}% + \global\parvoffset \getvalue{parvoffset:\currentshapetext}% + \global\parhoffset \getvalue{parhoffset:\currentshapetext}% + \global\parwidth \getvalue{parwidth:\currentshapetext}% + \global\parheight \getvalue{parheight:\currentshapetext}} + {\global\parlines \plusone + \global\chardef\parfirst \zerocount + \global\parvoffset \zeropoint + \global\parhoffset \zeropoint + \global\parwidth \hsize + \global\parheight \vsize}} + +\def\setshapecharacteristics% + {\doglobal\increment\currentshapetext + \setxvalue{parlines:\currentshapetext }{\the\parlines}% + \setxvalue{parfirst:\currentshapetext }{\the\parfirst}% + \setxvalue{parvoffset:\currentshapetext}{\the\parvoffset}% + \setxvalue{parhoffset:\currentshapetext}{\the\parhoffset}% + \setxvalue{parwidth:\currentshapetext }{\the\parwidth}% + \setxvalue{parheight:\currentshapetext }{\the\parheight}} + +\def\getshapetext% option: unvbox + {\vbox\bgroup + \forgetall + \setbox\scratchbox\vbox to \parheight + {\expanded{\switchtobodyfont[\@@shbodyfont]}% evt strutheight en + \splittopskip\strutheight % lineheight opslaan + \vskip\parvoffset % scheelt switch en + \ifcase\parfirst\or\vskip\lineheight\fi % is ook veiliger + \hskip\parhoffset + \hbox{\vsplit\shapetextbox to \parlines\lineheight}}% + \wd\scratchbox\parwidth + \ht\scratchbox\parheight + \dp\scratchbox\zeropoint + \box\scratchbox + \getshapecharacteristics + \egroup} + +\def\setupshapetexts% + {\dodoubleempty\getparameters[\??sh]} + +\setupshapetexts% + [\c!bodyfont=] + +%%%%%%% rotfont nog definieren + +\doifundefined{RotFont}{\definefont[RotFont][RegularBold]} + +\def\processfollowingtoken#1% strut toegevoegd + {\appendtoks#1\to\MPtoks + \setbox\MPbox=\hbox{\RotFont\setstrut\strut\the\MPtoks}% + \startMPdrawing + n := n + 1 ; len[n] := \the\wd\MPbox ; + \stopMPdrawing + \startMPdrawing[-] + % pic[n] := textext{\RotFont\setstrut\strut#1} ; % btex \RotFont\setstrut\strut#1 etex ; + pic[n] := btex \RotFont\setstrut\strut#1 etex ; + pic[n] := pic[n] shifted - llcorner pic[n] ; + \stopMPdrawing} + +\startuseMPgraphic{followtokens} + % we default to nothing +\stopuseMPgraphic + +\def\followtokens#1% + {\vbox\bgroup + \forgetall + \dontcomplain + \startMPenvironment + \doifundefined{RotFont}{\definefont[RotFont][RegularBold]} + \stopMPenvironment + \MPtoks\emptytoks + \resetMPdrawing + \startMPdrawing + \includeMPgraphic{followtokens} ; + picture pic[] ; numeric len[], n ; n := 0 ; + \stopMPdrawing + \handletokens#1\with\processfollowingtoken + \startMPdrawing + if unknown RotPath : path RotPath ; RotPath := origin ; fi ; + if unknown RotColor : color RotColor ; RotColor := black ; fi ; + if unknown TraceRot : boolean TraceRot ; TraceRot := false ; fi ; + if unknown ExtraRot : numeric ExtraRot ; ExtraRot := 0 ; fi ; + numeric al, at, pl, wid, pos ; pair ap, ad ; + al := arclength RotPath ; + if al=0 : + al := len[n] + ExtraRot ; + RotPath := origin -- (al,0) ; + fi ; + if al1 : (n-1) else : 1 fi) ; + if TraceRot : + draw RotPath withpen pencircle scaled 1pt withcolor blue ; + fi ; + for i=1 upto n : + wid := abs(xpart urcorner pic[i] - xpart llcorner pic[i]) ; + pos := len[i]-wid/2 + (i-1)*pl ; + at := arctime pos of RotPath ; + ap := point at of RotPath ; + ad := direction at of RotPath ; + draw pic[i] shifted (-wid/2,0) rotated(angle(ad)) shifted ap + withcolor RotColor ; + if TraceRot : + draw boundingbox + pic[i] shifted (-wid/2,0) rotated(angle(ad)) shifted ap + withpen pencircle scaled .25pt withcolor red ; + draw ap + withpen pencircle scaled .50pt withcolor green ; + fi ; + endfor ; + \stopMPdrawing + \MPdrawingdonetrue + \getMPdrawing + \resetMPdrawing + \egroup} + +% \followtokens +% {This is just a dummy text, kerned by T{\kern +% -.1667em\lower .5ex\hbox {E}}{\kern -.125emX} and typeset +% in a circle using {\setMFPfont M}{\setMFPfont +% E}{\setMFPfont T}{\setMFPfont A}{\setMFPfont +% P}{\setMFPfont O}{\setMFPfont S}{\setMFPfont T}.\quad} + +\startuseMPgraphic{fuzzycount} + begingroup + save height, span, drift, d, cp ; + height := 3/ 5 * \baselinedistance ; + span := 1/ 3 * height ; + drift := 1/10 * height ; + pickup pencircle scaled (1/12 * height) ; + def d = (uniformdeviate drift) enddef ; + for i := 1 upto \MPvar{n} : + draw + if (i mod 5)=0 : ((-d-4.5span,d)--(+d-0.5span,height-d)) + else : ((-d,+d)--(+d,height-d)) fi + shifted (span*i,d-drift) ; + endfor; + picture cp ; cp := currentpicture ; % for readability + setbounds currentpicture to + (llcorner cp shifted (0,-ypart llcorner cp) -- + lrcorner cp shifted (0,-ypart lrcorner cp) -- + urcorner cp -- ulcorner cp -- cycle) ; + endgroup ; +\stopuseMPgraphic + +\setupMPvariables + [fuzzycount] + [n=10] + +\def\fuzzycount#1% + {{\tx\useMPgraphic{fuzzycount}{n=#1}}} + +\defineconversion[fuzzy][\fuzzycount] + +%%%%%%% + +\setupMPvariables + [EnglishRule] + [height=1ex, + width=\the\localhsize, % without \the, problems in non e-tex + color=darkgray] + +\defineblank + [EnglishRule] + [medium] + +\startuniqueMPgraphic{EnglishRule}{height,width,color} + height = \MPvar{height} ; + x1 = 0 ; x3 = \MPvar{width} ; x2 = x4 = .5x3 ; + y1 = y3 = 0 ; y2 = -y4 = height/2 ; + fill z1..z2..z3 & z3..z4..z1 & cycle withcolor \MPvar{color} ; +\stopuniqueMPgraphic + +\def\EnglishRule% + {\startlinecorrection[EnglishRule] + \setlocalhsize \noindent \reuseMPgraphic{EnglishRule} + \stoplinecorrection} + +%D The following macro returns a tight bound character +%D sequence. +%D +%D \useMPlibrary[txt] +%D +%D \startlinecorrection +%D \TightText{\ss\bf 123}{0cm}{3cm}{red} +%D \stoplinecorrection + +\def\TightText#1#2#3#4% + {\hbox % \ruledhbox + {\startMPcode + picture p ; p := image (graphictext "#1" withfillcolor red) ; + draw p xsized #2 ysized #3 withcolor \MPcolor{#4} ; + \stopMPcode}} + +\protect \endinput diff --git a/tex/context/base/meta-xml.tex b/tex/context/base/meta-xml.tex new file mode 100644 index 000000000..f6f81f767 --- /dev/null +++ b/tex/context/base/meta-xml.tex @@ -0,0 +1,29 @@ +%D \module +%D [ file=meta-xml, +%D version=2002.11.27, +%D title=\METAPOST\ Graphics, +%D subtitle=XML Hacks, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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}{MetaPost Graphics / XML Hacks} + +%D When we are dealing with XML, we need to make sure that +%D \METAPOST\ knows about it. The next macro expands its +%D argument (think of widget XFDF) into \type {\getXMLentity} +%D calls. + +\unprotect + +\def\setMPtextXML#1#2% + {\bgroup + \enableXML + \expanded{\defconvertedcommand\noexpand\ascii{#2}}% + \expanded{\egroup\noexpand\dodoglobal\noexpand\setvalue{\@@MPT#1}{\ascii}}} + +\protect \endinput diff --git a/tex/context/base/metatex.tex b/tex/context/base/metatex.tex new file mode 100644 index 000000000..e90af709c --- /dev/null +++ b/tex/context/base/metatex.tex @@ -0,0 +1,154 @@ +%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 We can experiment here with runtime loading, id est no longer +%D use a format. However, we still need a stub then but it could +%D as well be luatools (mtxrun) itself then. + +%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.tex \relax} +\def\loadmarkfile#1{\normalinput#1.mkiv\relax} + +\loadcorefile{syst-ini} + +\ifnum\luatexversion<60 % also change message + \writestatus{!!!!}{Your luatex binary is too old, you need at least version 0.60!} + \expandafter\end +\fi + +\newtoks\metatexversiontoks \metatexversiontoks\expandafter{\metatexversion} % at the lua end + +\loadcorefile{syst-pln} % plain tex initializations of internal registers (no further code) + +\loadmarkfile{luat-cod} % +\loadmarkfile{luat-bas} % +\loadmarkfile{luat-lib} % + +% needs stripping: + +\loadmarkfile{catc-ini} % catcode table management +\loadcorefile{catc-act} % active character definition mechanisms +\loadcorefile{catc-def} % some generic catcode tables +\loadcorefile{catc-ctx} % a couple of context specific tables but expected by later modules +\loadcorefile{catc-sym} % some definitions related to \letter + +% helpers, maybe less + +\loadmarkfile{syst-aux} % a whole lot of auxiliary macros +%loadmarkfile{syst-lua} % some helpers using lua instead +%loadmarkfile{syst-con} % some rather basic conversions +%loadmarkfile{syst-fnt} +%loadmarkfile{syst-str} +%loadmarkfile{syst-rtp} + +% not needed + +% \loadmarkfile{supp-fil} +% \loadmarkfile{supp-dir} + +% characters + +\loadmarkfile{char-utf} +\loadmarkfile{char-ini} +\loadmarkfile{char-enc} % \registerctxluafile{char-enc}{1.001} + +% nodes + +\loadmarkfile{node-ini} +%loadmarkfile{node-fin} +%loadmarkfile{node-par} + +% attributes, not needed: + +%loadmarkfile{attr-ini} + +% regimes + +% \loadmarkfile{regi-ini} +% \loadcorefile{regi-syn} + +% 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 + +% why not ... + +\pdfoutput\plusone + +% done + +\errorstopmode \dump \endinput diff --git a/tex/context/base/mlib-ctx.lua b/tex/context/base/mlib-ctx.lua new file mode 100644 index 000000000..cc5682e6f --- /dev/null +++ b/tex/context/base/mlib-ctx.lua @@ -0,0 +1,84 @@ +if not modules then modules = { } end modules ['mlib-ctx'] = { + version = 1.001, + comment = "companion to mlib-ctx.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", +} + +-- todo + +local format, join = string.format, table.concat +local sprint = tex.sprint + +local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming + +metapost = metapost or {} +metapost.defaultformat = "metafun" + +function metapost.graphic(instance,mpsformat,str,initializations,preamble,askedfig) + local mpx = metapost.format(instance,mpsformat or metapost.defaultformat) + metapost.graphic_base_pass(mpx,str,initializations,preamble,askedfig) +end + +function metapost.getclippath(instance,mpsformat,data,initializations,preamble) + local mpx = metapost.format(instance,mpsformat or metapost.defaultformat) + if mpx and data then + starttiming(metapost) + starttiming(metapost.exectime) + local result = mpx:execute(format("%s;beginfig(1);%s;%s;endfig;",preamble or "",initializations or "",data)) + stoptiming(metapost.exectime) + if result.status > 0 then + logs.report("metafun", "%s: %s", result.status, result.error or result.term or result.log) + result = nil + else + result = metapost.filterclippath(result) + end + stoptiming(metapost) + return result + end +end + +function metapost.filterclippath(result) + if result then + local figures = result.fig + if figures and #figures > 0 then + local figure = figures[1] + local objects = figure:objects() + if objects then + local lastclippath + for o=1,#objects do + local object = objects[o] + if object.type == "start_clip" then + lastclippath = object.path + end + end + return lastclippath + end + end + end +end + +function metapost.theclippath(...) + local result = metapost.getclippath(...) + if result then -- we could just print the table + result = join(metapost.flushnormalpath(result),"\n") + sprint(result) + end +end + +statistics.register("metapost processing time", function() + local n = metapost.n + if n > 0 then + local e, t = metapost.externals.n, statistics.elapsedtime + local str = format("%s seconds, loading: %s seconds, execution: %s seconds, n: %s", + t(metapost), t(mplib), t(metapost.exectime), n) + if e > 0 then + return format("%s, external: %s seconds (%s calls)", str, t(metapost.externals), e) + else + return str + end + else + return nil + end +end) diff --git a/tex/context/base/mlib-ctx.mkiv b/tex/context/base/mlib-ctx.mkiv new file mode 100644 index 000000000..6f56b7e68 --- /dev/null +++ b/tex/context/base/mlib-ctx.mkiv @@ -0,0 +1,81 @@ +%D \module +%D [ file=mlib-ctx, +%D version=2008.03.25, +%D title=\METAPOST\ Integrated Graphics, +%D subtitle=Basics, +%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 contains the \MPLIB\ variants of the by now ancient +%D \MPTOPDF\ code. + +\writestatus{loading}{MetaPost Library Graphics / Initializations} + +\registerctxluafile{mlib-run}{1.001} +\registerctxluafile{mlib-ctx}{1.001} + +\unprotect + +\protect \endinput + +% local mpgraphic = [[ +% for i=1 upto 1000 : +% beginfig(0); +% draw halfcircle scaled 1cm withcolor green ; +% picture p ; p := "oeps" infont defaultfont scaled .75 rotated 45 ; +% p := p shifted - (xpart center p,0) ; +% draw p ; draw boundingbox p ; +% endfig ; +% beginfig(0); +% draw halfcircle scaled 1cm dashed evenly withcolor green ; +% endfig ; +% beginfig(0); +% pickup pencircle xscaled .5mm yscaled .25mm rotated 45 ; +% draw halfcircle scaled 1cm withcolor red ; +% endfig ; +% beginfig(0); +% draw halfcircle scaled 1cm ; +% endfig ; +% beginfig(0); +% pickup pencircle xscaled .5mm yscaled .25mm rotated 45 ; +% for k:=1 upto 10 : +% draw halfcircle scaled uniformdeviate(1cm) withcolor (red/(k/4)) ; +% endfor ; +% endfig ; +% endfor ; +% ]] +% -- local mpx = metapost.format("metafun") +% metapost.process(metapost.format("metafun"),mpgraphic) + +% \starttext +% \setupcolors[state=start] +% \definecolor[red] [r=1] +% \definecolor[cyan][c=1] +% \setbox\scratchbox\hbox{\startMPcode\stopMPcode} % first specials are forgotten +% \definecolor[sss][t=.5,a=1,r=1] +% \definespotcolor[oeps1][green][p=.5] +% \definespotcolor[oeps2][green][p=.25] +% \definespotcolor[oeps3][green][p=.25,t=.5,a=1] +% \startMPpage +% fill fullcircle scaled 10cm withcolor \MPcolor{red} ; +% fill fullcircle scaled 8cm withcolor cmyk(1,0,0,0) ; +% fill fullcircle scaled 6cm withcolor cmyk(0,1,0,0) ; +% fill fullcircle scaled 4cm withcolor cmyk(0,0,1,0) ; +% fill fullcircle scaled 2cm withcolor cmyk(0,0,0,1) ; +% currentpicture := currentpicture shifted (-7.5cm,0) ; +% fill fullcircle scaled 10cm withcolor transparent(1,0.75,cmyk(0,0,1,0)) ; +% fill fullcircle scaled 8cm withcolor \MPcolor{sss} ; +% fill fullcircle scaled 6cm withcolor \MPcolor{oeps1} ; +% fill fullcircle scaled 4cm withcolor \MPcolor{oeps2} ; +% currentpicture := currentpicture shifted (-7.5cm,0) ; +% fill fullcircle scaled 10cm withcolor \MPcolor{oeps3} ; +% circular_shade(fullcircle scaled 8cm, 1, red, blue) ; +% circular_shade(fullcircle scaled 6cm, 1, (1,0,0,0), (0,1,0,0)) ; +% circular_shade(fullcircle scaled 4cm, 1, cmyk(.5,.5,1,0), (0,1,0,0)) ; +% \stopMPpage +% \stoptext diff --git a/tex/context/base/mlib-pdf.lua b/tex/context/base/mlib-pdf.lua new file mode 100644 index 000000000..352070408 --- /dev/null +++ b/tex/context/base/mlib-pdf.lua @@ -0,0 +1,530 @@ +if not modules then modules = { } end modules ['mlib-pdf'] = { + version = 1.001, + comment = "companion to mlib-ctx.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", +} + +local format, concat, gsub = string.format, table.concat, string.gsub +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 +metapost.optimize = true -- false + +--~ Because in MKiV we always have two passes, we save the objects. When an extra +--~ mp run is done (due to for instance texts identifier in the parse pass), we +--~ get a new result table and the stored objects are forgotten. Otherwise they +--~ are reused. + +local function getobjects(result,figure,f) + if metapost.optimize then + local objects = result.objects + if not objects then + result.objects = { } + end + objects = result.objects[f] + if not objects then + objects = figure:objects() + result.objects[f] = objects + end + return objects + else + return figure:objects() + end +end + +function metapost.convert(result, trialrun, flusher, multipass, askedfig) + if trialrun then + metapost.multipass = false + metapost.parse(result, askedfig) + if multipass and not metapost.multipass and metapost.optimize then + metapost.flush(result, flusher, askedfig) -- saves a run + else + return false + end + else + metapost.flush(result, flusher, askedfig) + end + return true -- done +end + +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 + +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 + 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.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 + 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 = gsub(text,".","\\hbox{%1}") -- kerning happens in metapost (i have to check if this is true for mplib) + texsprint(ctxcatcodes,format("\\MPLIBtextext{%s}{%s}{%s}{%s}{%s}",font,size,text,0,-number.dimenfactors.bp*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 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 + 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, t, open) + t = t or { } + local pth, ith + for i=1,#path do + pth = path[i] + if not ith then + t[#t+1] = format("%f %f m",pth.x_coord,pth.y_coord) + elseif curved(ith,pth) then + t[#t+1] = format("%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 + t[#t+1] = format("%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 + t[#t+1] = format("%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 + t[#t+1] = format("%f %f l",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",one.x_coord,one.y_coord) + end + return t +end + +local function flushconcatpath(path, t, open) + t = t or { } + t[#t+1] = format("%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 + t[#t+1] = format("%f %f m",mpconcat(pth.x_coord,pth.y_coord)) + elseif curved(ith,pth) then + 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",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 = 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",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",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 + +-- the flusher is pdf based, if another backend is used, we need to overload the +-- flusher; this is beta code, the organization will change + +function metapost.flush(result,flusher,askedfig) -- pdf flusher, table en dan concat is sneller, 1 literal + if result then + local figures = result.fig + if figures then + flusher = flusher or metapost.flushers.pdf + local colorconverter = metapost.colorconverter() -- function ! + local colorhandler = metapost.colorhandler + for f=1, #figures do + local figure = figures[f] + local objects = getobjects(result,figure,f) + local fignum = figure:charcode() or 0 + if not askedfig or (askedfig == fignum) then + local t = { } + 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 + metapost.llx = llx + metapost.lly = lly + metapost.urx = urx + metapost.ury = ury + if urx < llx then + -- invalid + flusher.startfigure(fignum,0,0,0,0,"invalid",figure) + flusher.stopfigure() + else + flusher.startfigure(fignum,llx,lly,urx,ury,"begin",figure) + t[#t+1] = "q" + if objects then + t[#t+1] = metapost.colorinitializer() + -- once we have multiple prescripts we can do more tricky things like + -- text and special colors at the same time + 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 + t[#t+1] = "q" + flushnormalpath(object.path,t,false) + t[#t+1] = "W n" + elseif objecttype == "stop_clip" then + t[#t+1] = "Q" + miterlimit, linecap, linejoin, dashed = -1, -1, -1, false + elseif objecttype == "special" then + metapost.specials.register(object.prescript) + elseif objecttype == "text" then + t[#t+1] = "q" + local ot = object.transform -- 3,4,5,6,1,2 + t[#t+1] = format("%f %f %f %f %f %f cm",ot[3],ot[4],ot[5],ot[6],ot[1],ot[2]) -- TH: format("%f %f m %f %f %f %f 0 0 cm",unpack(ot)) + flusher.flushfigure(t) -- flush accumulated literals + t = { } + flusher.textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth) + t[#t+1] = "Q" + else + -- alternatively we can pass on the stack, could be a helper + -- can be optimized with locals + local currentobject = { -- not needed when no extensions + type = object.type, + miterlimit = object.miterlimit, + linejoin = object.linejoin, + linecap = object.linecap, + color = object.color, + dash = object.dash, + path = object.path, + htap = object.htap, + pen = object.pen, + prescript = object.prescript, + postscript = object.postscript, + } + -- + local before, inbetween, after = nil, nil, nil + -- + local cs, cr = currentobject.color, nil + -- todo document why ... + if cs and colorhandler and #cs > 0 and round(cs[1]*10000) == 123 then -- test in function + currentobject, cr = colorhandler(cs,currentobject,t,colorconverter) + objecttype = currentobject.type + end + -- + local prescript = currentobject.prescript + if prescript and prescript ~= "" then + -- move test to function + local special = metapost.specials[prescript] + if special then + currentobject, before, inbetween, after = special(currentobject.postscript,currentobject,t,flusher) + objecttype = currentobject.type + end + end + -- + cs = currentobject.color + if cs and #cs > 0 then + t[#t+1], cr = colorconverter(cs) + end + -- + if before then currentobject, t = before() end + local ml = currentobject.miterlimit + if ml and ml ~= miterlimit then + miterlimit = ml + t[#t+1] = format("%f M",ml) + end + local lj = currentobject.linejoin + if lj and lj ~= linejoin then + linejoin = lj + t[#t+1] = format("%i j",lj) + end + local lc = currentobject.linecap + if lc and lc ~= linecap then + linecap = lc + t[#t+1] = format("%i J",lc) + end + local dl = currentobject.dash + if dl then + local d = format("[%s] %i d",concat(dl.dashes or {}," "),dl.offset) + if d ~= dashed then + dashed = d + t[#t+1] = dashed + end + elseif dashed then + t[#t+1] = "[] 0 d" + dashed = false + end + if inbetween then currentobject, t = inbetween() end + local path = currentobject.path + local transformed, penwidth = false, 1 + local open = path and path[1].left_type and path[#path].right_type -- at this moment only "end_point" + local pen = currentobject.pen + if pen then + if pen.type == 'elliptical' then + transformed, penwidth = pen_characteristics(object) -- boolean, value + t[#t+1] = format("%f w",penwidth) -- todo: only if changed + if objecttype == 'fill' then + objecttype = 'both' + end + else -- calculated by mplib itself + objecttype = 'fill' + end + end + if transformed then + t[#t+1] = "q" + end + if path then + if transformed then + flushconcatpath(path,t,open) + else + flushnormalpath(path,t,open) + end + if objecttype == "fill" then + t[#t+1] = "h f" + elseif objecttype == "outline" then + t[#t+1] = (open and "S") or "h S" + elseif objecttype == "both" then + t[#t+1] = "h B" + end + end + if transformed then + t[#t+1] = "Q" + end + local path = currentobject.htap + if path then + if transformed then + t[#t+1] = "q" + end + if transformed then + flushconcatpath(path,t,open) + else + flushnormalpath(path,t,open) + end + if objecttype == "fill" then + t[#t+1] = "h f" + elseif objecttype == "outline" then + t[#t+1] = (open and "S") or "h S" + elseif objecttype == "both" then + t[#t+1] = "h B" + end + if transformed then + t[#t+1] = "Q" + end + end + if cr then + t[#t+1] = cr + end + if after then currentobject, t = after() end + end + end + end + t[#t+1] = "Q" + flusher.flushfigure(t) + flusher.stopfigure("end") + end + if askedfig then + break + end + end + end + end + end +end + +function metapost.parse(result,askedfig) + if result then + local figures = result.fig + if figures then + for f=1, #figures do + local figure = figures[f] + local fignum = figure:charcode() or 0 + if not askedfig or (askedfig == fignum) then + local bbox = figure:boundingbox() + local llx, lly, urx, ury = bbox[1], bbox[2], bbox[3], bbox[4] -- faster than unpack + metapost.llx = llx + metapost.lly = lly + metapost.urx = urx + metapost.ury = ury + local objects = getobjects(result,figure,f) + if objects then + for o=1,#objects do + local object = objects[o] + if object.type == "outline" then + local prescript = object.prescript + if prescript then + local special = metapost.specials[prescript] + if special then + special(object.postscript,object) + end + end + end + end + end + break + end + end + end + end +end + +-- tracing: + +local t = { } + +local flusher = { + startfigure = function() + t = { } + texsprint(ctxcatcodes,"\\startnointerference") + end, + flushfigure = function(literals) + for i=1, #literals do + t[#t+1] = literals[i] + end + end, + stopfigure = function() + texsprint(ctxcatcodes,"\\stopnointerference") + end +} + +function metapost.pdfliterals(result) + metapost.flush(result,flusher) + return t +end + +-- so far + +function metapost.totable(result) + local figure = result and result.fig and result.fig[1] + if figure then + local t = { } + local objects = figure:objects() + for o=1,#objects do + local object = objects[o] + local tt = { } + local fields = mplib.fields(object) + for f=1,#fields do + local field = fields[f] + tt[field] = object[field] + end + t[#t+1] = tt + end + local b = figure:boundingbox() + return { + boundingbox = { llx = b[1], lly = b[2], urx = b[3], ury = b[4] }, + objects = t + } + else + return nil + end +end + +-- will be overloaded later + +function metapost.colorconverter() + return function(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/context/base/mlib-pdf.mkiv b/tex/context/base/mlib-pdf.mkiv new file mode 100644 index 000000000..2681b0810 --- /dev/null +++ b/tex/context/base/mlib-pdf.mkiv @@ -0,0 +1,91 @@ +%D \module +%D [ file=mlib-pdf, +%D version=2008.03.25, +%D title=\METAPOST\ Integrated Graphics, +%D subtitle=Conversion to 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. + +\unprotect + +\registerctxluafile{mlib-pdf}{1.001} + +\def\MPLIBtoPDF#1{\ctxlua{metapost.flush_literal(#1)}} + +\def\MPLIBboundingbox#1#2#3#4% + {\xdef\MPllx{#1}% + \xdef\MPlly{#2}% + \xdef\MPurx{#3}% + \xdef\MPury{#4}% + \xdef\MPwidth {\the\dimexpr#3\onebasepoint-#1\onebasepoint\relax}% + \xdef\MPheight{\the\dimexpr#4\onebasepoint-#2\onebasepoint\relax}} + +\def\startMPLIBtoPDF#1#2#3#4% watch the transparency reset + {\naturalhbox\bgroup + \doactivatecolor\s!black\forcecolorhack + \MPLIBboundingbox{#1}{#2}{#3}{#4}% + %\forgetall % done already elsewhere + \setbox\scratchbox\vbox\bgroup + \noindent % this is really needed in order to force tex into proper cm's + \startMPresources} + +\def\stopMPLIBtoPDF % watch the transparency reset + {%\dohandleMPresettransparency % not needed + \stopMPresources + \egroup + \setbox\scratchbox\hbox\bgroup + \hskip-\MPllx\onebasepoint + \raise-\MPlly\onebasepoint + \box\scratchbox + \egroup + \setbox\scratchbox\vbox to \MPheight\bgroup + \vfill + \hsize\MPwidth + \smashbox\scratchbox + \box\scratchbox + \egroup + \wd\scratchbox\MPwidth + \ht\scratchbox\MPheight + \dopackageMPgraphic\scratchbox + \egroup} + +% \def\MPLIBtextext#1#2#3#4#5% +% {\begingroup +% \def\MPtextdata{#3}% delegate the splitter to lua +% \defconvertedcommand\MPtextdata\MPtextdata % no edef +% \splitstring\MPtextdata\at::::\to\MPtexttag\and\MPtextnumber +% \executeifdefined{handleMPtext\MPtexttag} +% {\setbox\scratchbox\hbox +% {\font\temp=#1\space at #2\onebasepoint +% \let\c\char +% \temp +% \MPfshowcommand{#3}}% +% \setbox\scratchbox\hbox +% {\hskip#4\onebasepoint +% \raise#5\onebasepoint +% \box\scratchbox}% +% \smashbox\scratchbox +% \box\scratchbox}% +% \endgroup} + +\def\MPLIBtextext#1#2#3#4#5% + {\begingroup + \setbox\scratchbox\hbox + {\font\temp=#1\space at #2\onebasepoint + \let\c\char + \temp + #3}% + \setbox\scratchbox\hbox + {\hskip#4\onebasepoint + \raise#5\onebasepoint + \box\scratchbox}% + \smashbox\scratchbox + \box\scratchbox + \endgroup} + +\protect \endinput diff --git a/tex/context/base/mlib-pps.lua b/tex/context/base/mlib-pps.lua new file mode 100644 index 000000000..8b36660d3 --- /dev/null +++ b/tex/context/base/mlib-pps.lua @@ -0,0 +1,897 @@ +if not modules then modules = { } end modules ['mlib-pps'] = { -- prescript, postscripts and specials + version = 1.001, + comment = "companion to mlib-ctx.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", +} + +-- current limitation: if we have textext as well as a special color then due to +-- prescript/postscript overload we can have problems +-- +-- todo: report max textexts + +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 lpegmatch = lpeg.match +local texbox = tex.box +local copy_list = node.copy_list + +local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming + +local ctxcatcodes = tex.ctxcatcodes + +local trace_textexts = false trackers.register("metapost.textexts", function(v) trace_textexts = v end) + +colors = colors or { } + +local rgbtocmyk = colors.rgbtocmyk or function() return 0,0,0,1 end +local cmyktorgb = colors.cmyktorgb or function() return 0,0,0 end +local rgbtogray = colors.rgbtogray or function() return 0 end +local cmyktogray = colors.cmyktogray or function() return 0 end + +metapost = metapost or { } +metapost.specials = metapost.specials or { } +metapost.specials.data = metapost.specials.data or { } +metapost.externals = metapost.externals or { n = 0 } + +local data = metapost.specials.data + +local colordata = { {}, {}, {}, {}, {} } + +--~ (r,g,b) => cmyk : r=123 g= 1 b=hash +--~ => spot : r=123 g= 2 b=hash +--~ => transparent rgb : r=123 g= 3 b=hash +--~ => transparent cmyk : r=123 g= 4 b=hash +--~ => transparent spot : r=123 g= 5 b=hash +--~ => rest : r=123 g=n>10 b=whatever + +local nooutercolor = "0 g 0 G" +local nooutertransparency = "/Tr0 gs" -- only when set +local outercolormode = 0 +local outercolor = nooutercolor +local outertransparency = nooutertransparency +local innercolor = nooutercolor +local innertransparency = nooutertransparency + +local pdfcolor, pdftransparency = lpdf.color, lpdf.transparency +local registercolor, registerspotcolor = colors.register, colors.registerspotcolor +local registertransparency = transparencies.register + +function metapost.set_outer_color(mode,colormodel,colorattribute,transparencyattribute) + -- has always to be called before conversion + -- todo: transparency (not in the mood now) + outercolormode = mode + if mode == 1 or mode == 3 then + -- inherit from outer (registered color) + outercolor = pdfcolor(colormodel,colorattribute) or nooutercolor + outertransparency = pdftransparency(transparencyattribute) or nooutertransparency + elseif mode == 2 then + -- stand alone (see m-punk.tex) + outercolor = "" + outertransparency = "" + else -- 0 + outercolor = nooutercolor + outertransparency = nooutertransparency + end + innercolor = outercolor + innertransparency = outertransparency -- not yet used +end + +local function checked_color_pair(color) + if not color then + return innercolor, outercolor + elseif outercolormode == 3 then + innercolor = color + return innercolor, innercolor + else + return color, outercolor + end +end + +metapost.checked_color_pair = checked_color_pair + +function metapost.colorinitializer() + innercolor = outercolor + innertransparency = outertransparency + return outercolor, outertransparency +end + +function metapost.specials.register(str) -- only colors + local size, content, n, class = match(str,"^%%%%MetaPostSpecial: (%d+) (.*) (%d+) (%d+)$") + if class then + -- use lpeg splitter + local data = { } + for s in gmatch(content,"[^ ]+") do + data[#data+1] = s + end + class, n = tonumber(class), tonumber(n) + if class == 3 or class == 4 or class == 5 then + -- hm, weird + else + n = tonumber(data[1]) + end + if n then + local cc = colordata[class] + if cc then + cc[n] = data + else + logs.report("mplib","problematic special: %s (no colordata class %s)", str or "?",class) + end + else + -- there is some bug to be solved, so we issue a message + logs.report("mplib","problematic special: %s", str or "?") + end + end +--~ if match(str,"^%%%%MetaPostOption: multipass") then +--~ metapost.multipass = true +--~ end +end + +local function spotcolorconverter(parent, n, d, p) + registerspotcolor(parent) + return pdfcolor(colors.model,registercolor(nil,'spot',parent,n,d,p)) +end + +function metapost.colorhandler(cs, object, result, colorconverter) -- handles specials + local cr = outercolor + local what = round(cs[2]*10000) + local data = colordata[what] + if data then + data = data[round(cs[3]*10000)] + end + if not data then + -- + elseif what == 1 then + result[#result+1], cr = colorconverter({ data[2], data[3], data[4], data[5] }) + elseif what == 2 then + result[#result+1] = spotcolorconverter(data[2],data[3],data[4],data[5]) + else + if what == 3 then + result[#result+1], cr = colorconverter({ data[3], data[4], data[5]}) + elseif what == 4 then + result[#result+1], cr = colorconverter({ data[3], data[4], data[5], data[6]}) + elseif what == 5 then + result[#result+1] = spotcolorconverter(data[3],data[4],data[5],data[6]) + end + object.prescript = "tr" + object.postscript = data[1] .. "," .. data[2] + end + object.color = nil + return object, cr +end + +function metapost.colorspec(cs) -- used for shades ... returns table (for checking) or string (spot) + local what = round(cs[2]*10000) + local data = colordata[what][round(cs[3]*10000)] + if not data then + return { 0 } + elseif what == 1 then + return { tonumber(data[2]), tonumber(data[3]), tonumber(data[4]), tonumber(data[5]) } + elseif what == 2 then + return spotcolorconverter(data[2],data[3],data[4],data[5]) + elseif what == 3 then + return { tonumber(data[3]), tonumber(data[4]), tonumber(data[5]) } + elseif what == 4 then + return { tonumber(data[3]), tonumber(data[4]), tonumber(data[5]), tonumber(data[6]) } + elseif what == 5 then + return spotcolorconverter(data[3],data[4],data[5],data[6]) + end +end + +function metapost.specials.tr(specification,object,result) + local a, t = match(specification,"^(.+),(.+)$") + local before = a and t and function() + result[#result+1] = format("/Tr%s gs",registertransparency(nil,a,t,true)) -- maybe nil instead of 'mp' + return object, result + end + local after = before and function() + result[#result+1] = outertransparency -- here we could revert to the outer color + return object, result + end + return object, before, nil, after +end + +local specificationsplitter = lpeg.Ct(lpeg.splitat(" ")) +local colorsplitter = lpeg.Ct(lpeg.splitat(":")) +local colorsplitter = lpeg.Ct(lpeg.splitter(":",tonumber)) + +-- Unfortunately we cannot use cmyk colors natively because there is no +-- generic color allocation primitive ... it's just an rgbcolor color.. This +-- means that we cannot pass colors in either cmyk or rgb form. +-- +-- def cmyk(expr c,m,y,k) = +-- 1 withprescript "cc" withpostscript ddddecimal (c,m,y,k) +-- enddef ; +-- +-- This is also an example of a simple plugin. + +--~ function metapost.specials.cc(specification,object,result) +--~ object.color = lpegmatch(specificationsplitter,specification) +--~ return object, nil, nil, nil +--~ end +--~ function metapost.specials.cc(specification,object,result) +--~ local c = lpegmatch(specificationsplitter,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 +--~ end + +-- thanks to taco's reading of the postscript manual: +-- +-- x' = sx * x + ry * y + tx +-- y' = rx * x + sy * y + ty + +function metapost.specials.fg(specification,object,result,flusher) -- graphics + 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 + local before = specification and function() + flusher.flushfigure(result) + sprint(ctxcatcodes,format("\\MPLIBfigure{%f}{%f}{%f}{%f}{%f}{%f}{%s}",sx,rx,ry,sy,tx,ty,specification)) + object.path = nil + return object, { } + end + return { } , before, nil, nil -- replace { } by object for tracing +end + +function metapost.specials.ps(specification,object,result) -- positions + local op = object.path + local first, third = op[1], op[3] + local x, y = first.x_coord, first.y_coord + local w, h = third.x_coord - x, third.y_coord - y + local label = specification + x = x - metapost.llx + y = metapost.ury - y + -- logs.report("mplib", "todo: position '%s' at (%s,%s) with (%s,%s)",label,x,y,w,h) + sprint(ctxcatcodes,format("\\dosavepositionwhd{%s}{0}{%sbp}{%sbp}{%sbp}{%sbp}{0pt}",label,x,y,w,h)) + return { }, nil, nil, nil +end + +local nofshades = 0 -- todo: hash resources, start at 1000 in order not to clash with older + +local function normalize(ca,cb) + if #cb == 1 then + if #ca == 4 then + cb[1], cb[2], cb[3], cb[4] = 0, 0, 0, 1-cb[1] + else + cb[1], cb[2], cb[3] = cb[1], cb[1], cb[1] + end + elseif #cb == 3 then + if #ca == 4 then + cb[1], cb[2], cb[3], cb[4] = rgbtocmyk(cb[1],cb[2],cb[3]) + else + cb[1], cb[2], cb[3] = cmyktorgb(cb[1],cb[2],cb[3],cb[4]) + end + end +end + +-- todo: check for the same colorspace (actually a backend issue), now we can +-- have several similar resources +-- +-- normalize(ca,cb) fails for spotcolors + +function metapost.specials.cs(specification,object,result,flusher) -- spot colors? + -- a mess, not dynamic anyway + nofshades = nofshades + 1 + flusher.flushfigure(result) + result = { } + local t = lpegmatch(specificationsplitter,specification) + -- we need a way to move/scale + local ca = lpegmatch(colorsplitter,t[4]) + local cb = lpegmatch(colorsplitter,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 + local name = format("MplSh%s",nofshades) + local domain = { tonumber(t[1]), tonumber(t[2]) } + local coordinates = { tonumber(t[5]), tonumber(t[6]), tonumber(t[7]), tonumber(t[9]), tonumber(t[10]), tonumber(t[11]) } + if type(ca) == "string" then + -- backend specific (will be renamed) + lpdf.circularshade(name,domain,{ 0 },{ 1 },1,"DeviceGray",coordinates) + else + if #ca > #cb then + normalize(ca,cb) + elseif #ca < #cb then + normalize(cb,ca) + end + local model = colors.model + if model == "all" then + model= (#ca == 4 and "cmyk") or (#ca == 3 and "rgb") or "gray" + end + if model == "rgb" then + if #ca == 4 then + ca[1], ca[2], ca[3] = cmyktorgb(ca[1],ca[2],ca[3],ca[4]) + cb[1], cb[2], cb[3] = cmyktorgb(cb[1],cb[2],cb[3],cb[4]) + ca[4], cb[4] = nil, nil + elseif #ca == 1 then + local a, b = 1-ca[1], 1-cb[1] + ca[1], ca[2], ca[3] = a, a, a + cb[1], cb[2], cb[3] = b, b, b + end + -- backend specific (will be renamed) + lpdf.circularshade(name,domain,ca,cb,1,"DeviceRGB",coordinates) + elseif model == "cmyk" then + if #ca == 3 then + ca[1], ca[2], ca[3], ca[4] = rgbtocmyk(ca[1],ca[2],ca[3]) + cb[1], cb[2], cb[3], ca[4] = rgbtocmyk(cb[1],cb[2],cb[3]) + elseif #ca == 1 then + 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 + -- backend specific (will be renamed) + lpdf.circularshade(name,domain,ca,cb,1,"DeviceCMYK",coordinates) + else + if #ca == 4 then + ca[1] = cmyktogray(ca[1],ca[2],ca[3],ca[4]) + cb[1] = cmyktogray(cb[1],cb[2],cb[3],cb[4]) + elseif #ca == 3 then + ca[1] = rgbtogray(ca[1],ca[2],ca[3]) + cb[1] = rgbtogray(cb[1],cb[2],cb[3]) + end + -- backend specific (will be renamed) + lpdf.circularshade(name,domain,ca,cb,1,"DeviceGRAY",coordinates) + end + end + local before = function() + result[#result+1] = "q /Pattern cs" + return object, result + end + local after = function() + result[#result+1] = format("W n /%s sh Q", name) + return object, result + end + object.color, object.type = nil, nil + return object, before, nil, after +end + +function metapost.specials.ls(specification,object,result,flusher) + nofshades = nofshades + 1 + flusher.flushfigure(result) + result = { } + local t = lpegmatch(specificationsplitter,specification) + -- we need a way to move/scale + local ca = lpegmatch(colorsplitter,t[4]) + local cb = lpegmatch(colorsplitter,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 + local name = format("MpSh%s",nofshades) + local domain = { tonumber(t[1]), tonumber(t[2]) } + local coordinates = { tonumber(t[5]), tonumber(t[6]), tonumber(t[8]), tonumber(t[9]) } + if type(ca) == "string" then + -- backend specific (will be renamed) + lpdf.linearshade(name,domain,{ 0 },{ 1 },1,"DeviceGray",coordinates) + else + if #ca > #cb then + normalize(ca,cb) + elseif #ca < #cb then + normalize(cb,ca) + end + local model = colors.model + if model == "all" then + model= (#ca == 4 and "cmyk") or (#ca == 3 and "rgb") or "gray" + end + if model == "rgb" then + if #ca == 4 then + ca[1], ca[2], ca[3] = cmyktorgb(ca[1],ca[2],ca[3],ca[4]) + cb[1], cb[2], cb[3] = cmyktorgb(cb[1],cb[2],cb[3],cb[4]) + elseif #ca == 1 then + local a, b = 1-ca[1], 1-cb[1] + ca[1], ca[2], ca[3] = a, a, a + cb[1], cb[2], cb[3] = b, b, b + end + -- backend specific (will be renamed) + lpdf.linearshade(name,domain,ca,cb,1,"DeviceRGB",coordinates) + elseif model == "cmyk" then + if #ca == 3 then + ca[1], ca[2], ca[3], ca[4] = rgbtocmyk(ca[1],ca[2],ca[3]) + cb[1], cb[2], cb[3], ca[4] = rgbtocmyk(cb[1],cb[2],cb[3]) + elseif #ca == 1 then + 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 + -- backend specific (will be renamed) + lpdf.linearshade(name,domain,ca,cb,1,"DeviceCMYK",coordinates) + else + if #ca == 4 then + ca[1] = cmyktogray(ca[1],ca[2],ca[3],ca[4]) + cb[1] = cmyktogray(cb[1],cb[2],cb[3],cb[4]) + elseif #ca == 3 then + ca[1] = rgbtogray(ca[1],ca[2],ca[3]) + cb[1] = rgbtogray(cb[1],cb[2],cb[3]) + end + -- backend specific (will be renamed) + lpdf.linearshade(name,domain,ca,cb,1,"DeviceGRAY",coordinates) + end + end + local before = function() + result[#result+1] = "q /Pattern cs" + return object, result + end + local after = function() + result[#result+1] = format("W n /%s sh Q", name) + return object, result + end + object.color, object.type = nil, nil + return object, before, nil, after +end + +-- no need for a before here + +local current_format, current_graphic, current_initializations + +-- metapost.first_box = metapost.first_box or 1000 +-- metapost.last_box = metapost.last_box or 1100 +--~ metapost.textext_current = metapost.first_box +metapost.multipass = false + +local textexts = { } + +function metapost.free_boxes() -- todo: mp direct list ipv box + -- for i = metapost.first_box,metapost.last_box do + -- local b = texbox[i] + -- if b then + -- texbox[i] = nil -- no node.flush_list(b) needed, else double free error + -- else + -- break + -- end + -- end + for n, box in next, textexts do + local tn = textexts[n] + if tn then + -- somehow not flushed (used) + textexts[n] = nil + end + end + textexts = { } +end + +function metapost.settext(box,slot) + textexts[slot] = copy_list(texbox[box]) + texbox[box] = nil + -- this will become + -- textexts[slot] = texbox[box] + -- unsetbox(box) +end + +function metapost.gettext(box,slot) + texbox[box] = copy_list(textexts[slot]) +-- textexts[slot] = nil -- no, pictures can be placed several times +end + +function metapost.specials.tf(specification,object) +--~ print("setting", metapost.textext_current) + local n, str = match(specification,"^(%d+):(.+)$") + if n and str then + n = tonumber(n) + -- 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) + logs.report("metapost","first pass: order %s",n) + end + -- sprint(ctxcatcodes,format("\\MPLIBsettext{%s}{%s}",metapost.textext_current,str)) + sprint(ctxcatcodes,format("\\MPLIBsettext{%s}{%s}",n,str)) + metapost.multipass = true + end + return { }, nil, nil, nil +end + +function metapost.specials.ts(specification,object,result,flusher) + -- print("getting", metapost.textext_current) + local n, str = match(specification,"^(%d+):(.+)$") + if n and str then + n = tonumber(n) + if trace_textexts then + -- logs.report("metapost","second pass: order %s, box %s",n,metapost.textext_current) + logs.report("metapost","second pass: order %s",n) + 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 trace_textexts then + object.path = nil + end + local before = function() -- no need for before function (just do it directly) + --~ 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 + -- local box = texbox[b] + local box = textexts[n] + if box then + -- sprint(ctxcatcodes,format("\\MPLIBgettextscaled{%s}{%s}{%s}",b,metapost.sxsy(box.width,box.height,box.depth))) + sprint(ctxcatcodes,format("\\MPLIBgettextscaled{%s}{%s}{%s}",n,metapost.sxsy(box.width,box.height,box.depth))) + else + -- error + end + 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 +end + +-- rather generic pdf, so use this elsewhere too it no longer pays +-- off to distinguish between outline and fill (we now have both +-- too, e.g. in arrows) + +metapost.reducetogray = true + +local models = { } + +function models.all(cr) + local n = #cr + if n == 0 then + return checked_color_pair() + elseif metapost.reducetogray then + if n == 1 then + local s = cr[1] + return checked_color_pair(format("%.3f g %.3f G",s,s)) + elseif n == 3 then + local r, g, b = cr[1], cr[2], cr[3] + if r == g and g == b then + return checked_color_pair(format("%.3f g %.3f G",r,r)) + else + return checked_color_pair(format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b)) + end + else + local c, m, y, k = cr[1], cr[2], cr[3], cr[4] + if c == m and m == y and y == 0 then + k = 1 - k + return checked_color_pair(format("%.3f g %.3f G",k,k)) + else + return checked_color_pair(format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k)) + end + end + elseif n == 1 then + local s = cr[1] + return checked_color_pair(format("%.3f g %.3f G",s,s)) + elseif n == 3 then + local r, g, b = cr[1], cr[2], cr[3] + return checked_color_pair(format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b)) + else + local c, m, y, k = cr[1], cr[2], cr[3], cr[4] + return checked_color_pair(format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k)) + end +end + +function models.rgb(cr) + local n = #cr + if n == 0 then + return checked_color_pair() + elseif metapost.reducetogray then + if n == 1 then + local s = cr[1] + checked_color_pair(format("%.3f g %.3f G",s,s)) + elseif n == 3 then + local r, g, b = cr[1], cr[2], cr[3] + if r == g and g == b then + return checked_color_pair(format("%.3f g %.3f G",r,r)) + else + return checked_color_pair(format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b)) + end + else + local c, m, y, k = cr[1], cr[2], cr[3], cr[4] + if c == m and m == y and y == 0 then + k = 1 - k + return checked_color_pair(format("%.3f g %.3f G",k,k)) + else + local r, g, b = cmyktorgb(c,m,y,k) + return checked_color_pair(format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b)) + end + end + elseif n == 1 then + local s = cr[1] + return checked_color_pair(format("%.3f g %.3f G",s,s)) + else + local r, g, b + if n == 3 then + r, g, b = cmyktorgb(cr[1],cr[2],cr[3],cr[4]) + else + r, g, b = cr[1], cr[2], cr[3] + end + return checked_color_pair(format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b)) + end +end + +function models.cmyk(cr) + local n = #cr + if n == 0 then + return checked_color_pair() + elseif metapost.reducetogray then + if n == 1 then + local s = cr[1] + return checked_color_pair(format("%.3f g %.3f G",s,s)) + elseif n == 3 then + local r, g, b = cr[1], cr[2], cr[3] + if r == g and g == b then + return checked_color_pair(format("%.3f g %.3f G",r,r)) + else + local c, m, y, k = rgbtocmyk(r,g,b) + return checked_color_pair(format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k)) + end + else + local c, m, y, k = cr[1], cr[2], cr[3], cr[4] + if c == m and m == y and y == 0 then + k = 1 - k + return checked_color_pair(format("%.3f g %.3f G",k,k)) + else + return checked_color_pair(format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k)) + end + end + elseif n == 1 then + local s = cr[1] + return checked_color_pair(format("%.3f g %.3f G",s,s)) + else + local c, m, y, k + if n == 3 then + c, m, y, k = rgbtocmyk(cr[1],cr[2],cr[3]) + else + c, m, y, k = cr[1], cr[2], cr[3], cr[4] + end + return checked_color_pair(format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k)) + end +end + +function models.gray(cr) + local n, s = #cr, 0 + if n == 0 then + return checked_color_pair() + elseif n == 4 then + s = cmyktogray(cr[1],cr[2],cr[3],cr[4]) + elseif n == 3 then + s = rgbtogray(cr[1],cr[2],cr[3]) + else + s = cr[1] + end + return checked_color_pair(format("%.3f g %.3f G",s,s)) +end + +function metapost.colorconverter() + return models[colors.model] or gray +end + +do + + local P, S, V, Cs = lpeg.P, lpeg.S, lpeg.V, lpeg.Cs + + local btex = P("btex") + local etex = P(" etex") + local vtex = P("verbatimtex") + local ttex = P("textext") + local gtex = P("graphictext") + local multipass = P("forcemultipass") + local spacing = S(" \n\r\t\v")^0 + local dquote = P('"') + + local found, forced = false, false + + local function convert(str) + found = true + return "rawtextext(\"" .. str .. "\")" -- centered + end + local function ditto(str) + return "\" & ditto & \"" + end + local function register() + found = true + end + local function force() + forced = true + end + + local texmess = (dquote/ditto + (1 - etex))^0 + + local function ignore(s) + logs.report("mplib","ignoring verbatim tex: %s",s) + return "" + end + + local parser = P { + [1] = Cs((V(2)/register + V(4)/ignore + V(3)/convert + V(5)/force + 1)^0), + [2] = ttex + gtex, + [3] = btex * spacing * Cs(texmess) * etex, + [4] = vtex * spacing * Cs(texmess) * etex, + [5] = multipass, -- experimental, only for testing + } + + -- currently a a one-liner produces less code + + local parser = Cs(( + (ttex + gtex)/register + + (btex * spacing * Cs(texmess) * etex)/convert + + (vtex * spacing * Cs(texmess) * etex)/ignore + + 1 + )^0) + + function metapost.check_texts(str) + found, forced = false, false + return lpegmatch(parser,str), found, forced + end + +end + +local factor = 65536*(7227/7200) + +function metapost.edefsxsy(wd,ht,dp) -- helper for figure + 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 + local hd = ht + dp + return (wd ~= 0 and factor/wd) or 0, (hd ~= 0 and factor/hd) or 0 +end + +local no_trial_run = "_trial_run_ := false ;" +local do_trial_run = "if unknown _trial_run_ : boolean _trial_run_ fi ; _trial_run_ := true ;" +local text_data_template = "_tt_w_[%i]:=%f;_tt_h_[%i]:=%f;_tt_d_[%i]:=%f;" +local do_begin_fig = "; beginfig(1); " +local do_end_fig = "; endfig ;" +local do_safeguard = ";" + +function metapost.text_texts_data() + local t, n = { }, 0 +--~ for i = metapost.first_box, metapost.last_box do +--~ n = n + 1 +--~ local box = texbox[i] + for n, box in next, textexts do + if trace_textexts then + logs.report("metapost","passed data: order %s, box %s",n,i) + end + if box then + t[#t+1] = format(text_data_template,n,box.width/factor,n,box.height/factor,n,box.depth/factor) + else + break + end + end +--~ print(table.serialize(t)) + return t +end + +metapost.intermediate = metapost.intermediate or {} +metapost.intermediate.actions = metapost.intermediate.actions or {} +metapost.intermediate.needed = false + +metapost.method = 1 -- 1:dumb 2:clever + +function metapost.graphic_base_pass(mpsformat,str,initializations,preamble,askedfig) + local nofig = (askedfig and "") or false + local done_1, done_2, forced_1, forced_2 + str, done_1, forced_1 = metapost.check_texts(str) + if not preamble or preamble == "" then + preamble, done_2, forced_2 = "", false, false + else + preamble, done_2, forced_2 = metapost.check_texts(preamble) + end + -- metapost.textext_current = metapost.first_box + metapost.intermediate.needed = false + metapost.multipass = false -- no needed here + current_format, current_graphic, current_initializations = mpsformat, str, initializations or "" + if metapost.method == 1 or (metapost.method == 2 and (done_1 or done_2)) then + -- first true means: trialrun, second true means: avoid extra run if no multipass + local flushed = metapost.process(mpsformat, { + preamble, + nofig or do_begin_fig, + do_trial_run, + current_initializations, + do_safeguard, + current_graphic, + nofig or do_end_fig + -- }, true, nil, true ) + }, true, nil, not (forced_1 or forced_2), false, askedfig) + if metapost.intermediate.needed then + for _, action in next, metapost.intermediate.actions do + action() + end + end + 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(ctxcatcodes,format("\\ctxlua{metapost.graphic_extra_pass(%s)}",askedfig or "false")) + end + else + metapost.process(mpsformat, { + preamble, + nofig or do_begin_fig, + no_trial_run, + current_initializations, + do_safeguard, + current_graphic, + nofig or do_end_fig + }, false, nil, false, false, askedfig ) + end + -- here we could free the textext boxes + metapost.free_boxes() +end + +function metapost.graphic_extra_pass(askedfig) + local nofig = (askedfig and "") or false + -- metapost.textext_current = metapost.first_box + metapost.process(current_format, { + nofig or do_begin_fig, + no_trial_run, + concat(metapost.text_texts_data()," ;\n"), + current_initializations, + do_safeguard, + current_graphic, + nofig or do_end_fig + }, false, nil, false, true, askedfig ) +end + +metapost.tex = metapost.tex or { } + +do -- only used in graphictexts + + local environments = { } + + function metapost.tex.set(str) + environments[#environments+1] = str + end + function metapost.tex.reset() + environments = { } + end + function metapost.tex.get() + return concat(environments,"\n") + end + +end + +local graphics = { } +local start = [[\starttext]] +local preamble = [[\long\def\MPLIBgraphictext#1{\startTEXpage[scale=10000]#1\stopTEXpage}]] +local stop = [[\stoptext]] + +function metapost.specials.gt(specification,object) -- number, so that we can reorder + graphics[#graphics+1] = format("\\MPLIBgraphictext{%s}",specification) + metapost.intermediate.needed = true + metapost.multipass = true + return { }, nil, nil, nil +end + +function metapost.intermediate.actions.makempy() + if #graphics > 0 then + local externals = metapost.externals + externals.n = externals.n + 1 + starttiming(externals) + local mpofile = tex.jobname .. "-mpgraph" + local mpyfile = file.replacesuffix(mpofile,"mpy") + local pdffile = file.replacesuffix(mpofile,"pdf") + local texfile = file.replacesuffix(mpofile,"tex") + io.savedata(texfile, { start, preamble, metapost.tex.get(), concat(graphics,"\n"), stop }, "\n") + local command = format("context --once %s %s", (tex.interactionmode == 0 and "--batchmode") or "", texfile) + os.execute(command) + if io.exists(pdffile) then + command = format("pstoedit -ssp -dt -f mpost %s %s", pdffile, mpyfile) + os.execute(command) + local result = { } + if io.exists(mpyfile) then + local data = io.loaddata(mpyfile) + for figure in gmatch(data,"beginfig(.-)endfig") do + result[#result+1] = format("begingraphictextfig%sendgraphictextfig ;\n", figure) + end + io.savedata(mpyfile,concat(result,"")) + end + end + stoptiming(externals) + graphics = { } -- ? + end +end diff --git a/tex/context/base/mlib-pps.mkiv b/tex/context/base/mlib-pps.mkiv new file mode 100644 index 000000000..0a78a8704 --- /dev/null +++ b/tex/context/base/mlib-pps.mkiv @@ -0,0 +1,70 @@ +%D \module +%D [ file=mlib-pps, +%D version=2008.03.25, +%D title=\METAPOST\ Integrated Graphics, +%D subtitle=Basics, +%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 + +\registerctxluafile{mlib-pps}{1.001} + +%D Todo: catch nested graphics like external figures with dummies. + +% \newtoks\everyMPLIBtext % not yet used + +% \appendtoks +% \let\handleuseMPgraphic \thirdofthreearguments +% \let\handlereusableMPgraphic\thirdofthreearguments +% \to \everyMPLIBtext + +% this will move ! + +% Instead of preallocated boxes we now use a table of lists so that we +% have no limitation. Typically an example of a next version solution +% due to \LUATEX\ evolving. + +\newbox \MPtextbox +\newtoks\everyMPLIBsettext + +\def\MPLIBfigure#1#2#3#4#5#6#7% todo: move Q q to lua + {\setbox\scratchbox\hbox{\externalfigure[#7]}% + \ctxlua{metapost.edefsxsy(\number\wd\scratchbox,\number\ht\scratchbox,0)}% + \pdfliteral direct{q #1 #2 #3 #4 #5 #6 cm}% no direct + \vbox to \zeropoint{\vss\hbox to \zeropoint{\scale[sx=\sx,sy=\sy]{\box\scratchbox}\hss}}% + \pdfliteral direct{Q}} + +\def\MPLIBsettext#1% #2% + {\dowithnextbox{\ctxlua{metapost.settext(\number\nextbox,#1)}}\hbox} + +\def\MPLIBgettextscaled#1#2#3% why a copy + {\ctxlua{metapost.gettext(\number\MPtextbox,#1)}% + \vbox to \zeropoint{\vss\hbox to \zeropoint{\black\scale[sx=#2,sy=#3]{\raise\dp\MPtextbox\box\MPtextbox}\hss}}} + +\def\MPLIBgraphictext#1% + {\startTEXpage[\c!scale=10000]#1\stopTEXpage} + +\protect \endinput + +% \def\MPLIBsettext#1% #2% we could as well store in hlists at the lua end i.e. just one box +% {\global\setbox#1\hbox} +% +% \def\MPLIBfreetext#1% +% {\global\setbox#1\emptybox} +% +% \def\MPLIBgettextscaled#1#2#3% why a copy +% {\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}{\let\MPLIBlast\relax\newbox\MPLIBlast}% +% \MPLIBregister} +% +% \def\MPLIBregister % after allocate! +% {\ctxlua{metapost.first_box, metapost.last_box = \number\MPLIBfirst, \number\MPLIBlast}} diff --git a/tex/context/base/mlib-run.lua b/tex/context/base/mlib-run.lua new file mode 100644 index 000000000..f352e1db1 --- /dev/null +++ b/tex/context/base/mlib-run.lua @@ -0,0 +1,379 @@ +if not modules then modules = { } end modules ['mlib-run'] = { + version = 1.001, + comment = "companion to mlib-ctx.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", +} + +--~ cmyk -> done, native +--~ spot -> done, but needs reworking (simpler) +--~ multitone -> +--~ shade -> partly done, todo: cm +--~ figure -> done +--~ hyperlink -> low priority, easy + +-- new * run +-- or +-- new * execute^1 * finish + +-- a*[b,c] == b + a * (c-b) + +--[[ldx-- +

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

+--ldx]]-- + +local trace_graphics = false trackers.register("metapost.graphics", function(v) trace_graphics = v end) + +local format, gsub, match = string.format, string.gsub, string.match + +local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming + +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 file.is_qualified_path(name) then + return name + else + return resolvers.find_file(name,ftype) + end +end + +metapost.finder = finder + +metapost.parameters = { + hash_size = 100000, + main_memory = 4000000, + max_in_open = 50, + param_size = 100000, +} + +metapost.exectime = metapost.exectime or { } -- hack + +local preamble = [[ +boolean mplib; string mp_parent_version; +mplib := true; +mp_parent_version := "%s"; +input %s ; dump ; +]] + +function metapost.make(name, target, version) + 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.removesuffix(target), + } + ) ) + if mpx then + starttiming(metapost.exectime) + local result = mpx:execute(format(preamble,version or "unknown",name)) + stoptiming(metapost.exectime) + mpx:finish() + end + stoptiming(mplib) +end + +function metapost.load(name) + starttiming(mplib) + local mpx = mplib.new ( table.merged ( + metapost.parameters, + { + ini_version = false, + mem_name = file.replacesuffix(name,"mem"), + find_file = finder, + -- job_name = "mplib", + } + ) ) + local result + if not mpx then + result = { status = 99, error = "out of memory"} + end + stoptiming(mplib) + return mpx, result +end + +function metapost.unload(mpx) + starttiming(mplib) + if mpx then + mpx:finish() + end + stoptiming(mplib) +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 and t ~= "" then + metapost.report("mp terminal: %s",t) + end + if e then + 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") + end + else + return false + end + return true +end + +function metapost.checkformat(mpsinput, mpsformat, dirname) + mpsinput = file.addsuffix(mpsinput or "metafun", "mp") + 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 = 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 '%s' from '%s'", mpsinput, mpsformat) + local mpx, result = metapost.load(mpsformat) + if mpx then + local result = mpx:execute("show mp_parent_version ;") + if not result.log then + metapost.reporterror(result) + else + local version = match(result.log,">> *(.-)[\n\r]") or "unknown" + version = gsub(version,"[\'\"]","") + if version ~= the_version then + commands.writestatus("mplib","version mismatch: %s <> %s", version or "unknown", the_version) + else + return mpx + end + end + else + commands.writestatus("mplib","error in loading '%s' from '%s'", mpsinput, mpsformat) + metapost.reporterror(result) + end + end + 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 '%s' from '%s'", mpsinput, mpsformat) + return metapost.load(mpsformat) + else + commands.writestatus("mplib","problems with '%s' from '%s'", mpsinput, mpsformat) + end +end + +local mpxformats = { } + +function metapost.format(instance,name) + name = name or instance + local mpx = mpxformats[instance] + if not mpx then + commands.writestatus("mplib","initializing instance '%s' using format '%s'",instance,name) + mpx = metapost.checkformat(name) + mpxformats[instance] = mpx + end + return mpx +end + +function metapost.reset(mpx) + if not mpx then + -- nothing + elseif type(mpx) == "string" then + if mpxformats[mpx] then + mpxformats[mpx]:finish() + mpxformats[mpx] = nil + end + else + for name, instance in next, mpxformats do + if instance == mpx then + mpx:finish() + mpxformats[name] = nil + break + end + end + end +end + +local mp_inp, mp_log, mp_tag = { }, { }, 0 + +function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, askedfig) + local converted, result = false, {} + if type(mpx) == "string" then + mpx = metapost.format(mpx) -- goody + end + if mpx and data then + starttiming(metapost) + if trace_graphics then + if not mp_inp[mpx] then + mp_tag = mp_tag + 1 + mp_inp[mpx] = io.open(format("%s-mplib-run-%03i.mp", tex.jobname,mp_tag),"w") + mp_log[mpx] = io.open(format("%s-mplib-run-%03i.log",tex.jobname,mp_tag),"w") + end + local banner = format("%% begin graphic: n=%s, trialrun=%s, multipass=%s, isextrapass=%s\n\n", metapost.n, tostring(trialrun), tostring(multipass), tostring(isextrapass)) + mp_inp[mpx]:write(banner) + mp_log[mpx]:write(banner) + end + if type(data) == "table" then + for i=1,#data do + local d = data[i] + if d then + if trace_graphics then + mp_inp[mpx]:write(d) + end + starttiming(metapost.exectime) + result = mpx:execute(d) + stoptiming(metapost.exectime) + if trace_graphics and result then + local str = result.log or result.error + if str and str ~= "" then + mp_log[mpx]:write(str) + end + end + 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 + if result.fig then + converted = metapost.convert(result, trialrun, flusher, multipass, askedfig) + end + end + else + metapost.report("mp error: invalid graphic component %s",i) + end + end + else + if trace_graphics then + mp_inp:write(data) + end + starttiming(metapost.exectime) + result = mpx[mpx]:execute(data) + stoptiming(metapost.exectime) + if trace_graphics and result then + local str = result.log or result.error + if str and str ~= "" then + mp_log[mpx]:write(str) + end + end + -- 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")) + 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, askedfig) + end + end + end + if trace_graphics then + local banner = "\n% end graphic\n\n" + mp_inp[mpx]:write(banner) + mp_log[mpx]:write(banner) + end + stoptiming(metapost) + end + return converted, result +end + +function metapost.convert() + metapost.report('mp warning: no converter set') +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=1,#sorted do + local v = sorted[k] + 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=1,#sorted do + local v = sorted[k] + 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..73431567d --- /dev/null +++ b/tex/context/base/mtx-context-arrange.tex @@ -0,0 +1,111 @@ +% 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 + context.insertpages ( + { filename }, + { emptypages }, + { width = 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..8a861ab83 --- /dev/null +++ b/tex/context/base/mtx-context-combine.tex @@ -0,0 +1,116 @@ +%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=spec : paper*print or paperxprint +% --nobanner : no footerlines +% --bannerheight=dimension : height of banner +% --bannerstring=dimension : height of bannerstring +% +% end help + +\input mtx-context-common.tex + +\doifdocumentargumentelse {paperoffset} { + + \setuplayout + [topspace=\getdocumentargument{paperoffset}, + backspace=\getdocumentargument{paperoffset}] + +} { + + \setuplayout + [topspace=0pt, + backspace=0pt] + +} + +\setuplayout + [header=0pt, + footer=0pt, + width=middle, + height=middle] + +\setuppapersize + [\getdocumentargument{paperformat_paper}] + [\getdocumentargument{paperformat_print}] + +\doifnotdocumentargument {bannerheight} { + \setuplayout + [footer=1cm] +} + +\doifelse {\getdocumentargument{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 + + 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.combination_nx or 2 + local ny = document.arguments.combination_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 + context("\\setuptexttexts[{\\setlayerframed[page][preset=middlebottom][frame=off,height=%s]{%s}}]",bannerheight,bannerstring) + else + context("\\setupfootertexts[{%s}]",bannerstring) + end + end + context("\\combinepages[%s][nx=%s,ny=%s]",filename,nx,ny) + context("\\page") + end + end + else + context("no files given") + end +\stopluacode + +\stoptext + diff --git a/tex/context/base/mtx-context-common.tex b/tex/context/base/mtx-context-common.tex new file mode 100644 index 000000000..8327dd28d --- /dev/null +++ b/tex/context/base/mtx-context-common.tex @@ -0,0 +1,43 @@ +%D \module +%D [ file=mtx-context-common, +%D version=2009.03.21, +%D title=\CONTEXT\ Extra Trickry, +%D subtitle=Common Stuff, +%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. + +\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("combination_nx",nx) + document.setargument("combination_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("paperformat_paper",f) + document.setargument("paperformat_print",t) +\stopluacode + +\endinput diff --git a/tex/context/base/mtx-context-ideas.tex b/tex/context/base/mtx-context-ideas.tex new file mode 100644 index 000000000..24d11a5b5 --- /dev/null +++ b/tex/context/base/mtx-context-ideas.tex @@ -0,0 +1,52 @@ +%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..d0dbcbba0 --- /dev/null +++ b/tex/context/base/mtx-context-listing.tex @@ -0,0 +1,100 @@ +%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) +% --bodyfont=list : additional bodyfont settings +% --paperformat=spec : paper*print or paperxprint +% +% end help + +\input mtx-context-common.tex + +\setupbodyfont + [11pt,tt,\getdocumentargument{bodyfont}] + +\setuptyping + [lines=yes] + +\setuplayout + [header=0cm, + footer=1.5cm, + topspace=\getdocumentargumentdefault{topspace}{1.5cm}, + backspace=\getdocumentargumentdefault{backspace}{1.5cm}, + width=middle, + height=middle] + +\setuppapersize + [\getdocumentargument{paperformat_paper}] + [\getdocumentargument{paperformat_print}] + +% \startluacode +% -- syntax check +% local topspace = dimen(document.arguments.topspace or 0) +% local backspace = dimen(document.arguments.backspace or 0) +% local zeropoint = dimen(0) +% if topspace > zeropoint then +% context.setuplayout { topspace = tostring(topspace) } +% end +% if backspace > zeropoint then +% context.setuplayout { backspace = tostring(backspace) } +% end +% \stopluacode + +\starttext + +\startluacode + local types = { + mkiv = "tex", + mkii = "tex", + cld = "lua", + lfg = "lua", + } + + 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 + local pretty = document.arguments.pretty + if pretty == true then + pretty = file.extname(filename) or "" + elseif pretty == false then + pretty = "" + else + -- forced + end + context.page() + context.setupfootertexts( -- return true: we need to keep this entry + { function() context.detokenize(file.basename(filename)) return true end }, + { function() context.pagenumber() return true end } + ) + context.setuptyping { option = types[pretty] or pretty } + context.typefile(filename) + end + end + else + context("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..b788d4b63 --- /dev/null +++ b/tex/context/base/mtx-context-timing.tex @@ -0,0 +1,44 @@ +%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..bdbd1dd22 --- /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.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format = string.format +local lpegmatch = lpeg.match +local type = type +local texsprint, ctxcatcodes = tex.sprint, 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,"tolerant") + +function commands.getcheckedparameters(k,p,s) + if s and s ~= "" then + prefix, kind = p, k + keys = k and k ~= "" and interfaces.syntax[k].keys + lpegmatch(pattern,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..60f568a1e --- /dev/null +++ b/tex/context/base/mult-chk.mkii @@ -0,0 +1,29 @@ +%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\gobbleparameters{\doquadrupleempty\dogobbleparameters} % todo: 1,2,3,4 case +\def\dogobbleparameters[#1][#2][#3][#4]{} + +\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-cld.lua b/tex/context/base/mult-cld.lua new file mode 100644 index 000000000..81038b68b --- /dev/null +++ b/tex/context/base/mult-cld.lua @@ -0,0 +1,212 @@ +if not modules then modules = { } end modules ['mult-cld'] = { + version = 1.001, + comment = "companion to mult-cld.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- This is an experiment: generating context code at the lua end. After all +-- it is surprisingly simple to implement due to metatables. I was wondering +-- if there was a more natural way to deal with commands at the lua end. +-- Of course it's a bit slower but often more readable when mixed with lua +-- code. It can also be handy when generating documents from databases or +-- when constructing large tables or so. +-- +-- Todo: optional checking against interface +-- Todo: coroutine trickery + +context = context or { } + +local format, concat = string.format, table.concat +local next, type = next, type +local texsprint, texiowrite, ctxcatcodes = tex.sprint, texio.write, tex.ctxcatcodes + +local flush = texsprint or function(cct,...) print(table.concat{...}) end + +local _stack_, _n_ = { }, 0 + +local function _store_(ti) + _n_ = _n_ + 1 + _stack_[_n_] = ti + return _n_ +end + +local function _flush_(n) + if not _stack_[n]() then + _stack_[n] = nil + else + -- keep, beware, that way the stack can grow + end +end + +context._stack_ = _stack_ +context._store_ = _store_ +context._flush_ = _flush_ + +function tex.fprint(...) -- goodie + texsprint(ctxcatcodes,format(...)) +end + +function context.trace(intercept) + local normalflush = flush + flush = function(c,...) + logs.report("context",concat({...})) + if not intercept then + normalflush(c,...) + end + end + context.trace = function() end +end + +trackers.register("context.flush", function(v) if v then context.trace() end end) +trackers.register("context.intercept", function(v) if v then context.trace(true) end end) + +local function writer(k,...) + if k then + flush(ctxcatcodes,k) + local t = { ... } + local nt = #t + if nt > 0 then + for i=1,nt do + local ti = t[i] + local typ = type(ti) + if ti == nil then + -- next + elseif typ == "function" then + flush(ctxcatcodes,"{\\mkivflush{" .. _store_(ti) .. "}}") + elseif typ == "string" or typ == "number" then + flush(ctxcatcodes,"{",ti,"}") + elseif typ == "table" then + local tn = #ti + if tn > 0 then + for j=1,tn do + local tj = ti[j] + if type(tj) == "function" then + ti[j] = "\\mkivflush{" .. _store_(tj) .. "}" + end + end + flush(ctxcatcodes,"[",concat(ti,","),"]") + else + flush(ctxcatcodes,"[") + local done = false + for k, v in next, ti do + if done then + flush(ctxcatcodes,",",k,'=',v) + else + flush(ctxcatcodes,k,'=',v) + done = true + end + end + flush(ctxcatcodes,"]") + end + -- elseif typ == "boolean" then + -- flush(ctxcatcodes,"\n") + elseif ti == true then + flush(ctxcatcodes,"\n") + elseif typ == false then + -- if force == "direct" then + flush(ctxcatcodes,tostring(ti)) + -- end + elseif typ == "thread" then + logs.report("interfaces","coroutines not supported as we cannot yeild across boundaries") + else + logs.report("interfaces","error: %s gets a weird argument %s",k,tostring(ti)) + end + end + end + end +end + +-- -- -- + +local function indexer(t,k) + local c = "\\" .. k .. " " + local f = function(...) return writer(c,...) end + t[k] = f + return f +end + +local function caller(t,f,a,...) + if a then + flush(ctxcatcodes,format(f,a,...)) + elseif type(f) == "function" then + flush(ctxcatcodes,"{\\mkivflush{" .. _store_(f) .. "}}") + elseif f then + flush(ctxcatcodes,f) + else + flush(ctxcatcodes,"\n") + end +end + +setmetatable(context, { __index = indexer, __call = caller } ) + +-- the only non macro: + +local trace_cld = false + +function context.runfile(filename) + filename = resolvers.findtexfile(filename) or "" + if filename ~= "" then + local ok = dofile(filename) + if type(ok) == "function" then + if trace_cld then + commands.writestatus("cld","begin of file '%s' (function call)",filename) + end + ok() + if trace_cld then + commands.writestatus("cld","end of file '%s' (function call)",filename) + end + elseif ok then + commands.writestatus("cld","file '%s' is processed and returns true",filename) + else + commands.writestatus("cld","file '%s' is processed and returns nothing",filename) + end + else + commands.writestatus("cld","unknown file '%s'",filename) + end +end + +-- tracking is using the regular mechanism; we need to define +-- these 'macro' functions explictly as otherwise they are are +-- delayed (as all commands print back to tex, so that tracing +-- would be enabled afterwards) + +trackers.register("cld.print", function(v) + trace_cld = v + if v then + flush = function(c,...) + texiowrite(...) + texsprint(c,...) + end + else + flush = texsprint + end +end) + +function context.enabletrackers (str) trackers.enable (str) end +function context.disabletrackers(str) trackers.disable(str) end + +-- see demo-cld.cld for an example + +-- context.starttext(true) +-- context.chapter({ "label" }, "title", true) +-- context.chapter(function() return { "label" } end, "title", true) +-- +-- context.startchapter({ title = "test" }, { more = "oeps" }, true) +-- +-- context.bTABLE(true) +-- for i=1,10 do +-- context.bTR() +-- for i=1,10 do +-- context.bTD() +-- context("%#2i",math.random(99)) +-- context.eTD() +-- end +-- context.eTR(true) +-- end +-- context.eTABLE(true) +-- +-- context.stopchapter(true) +-- +-- context.stoptext(true) diff --git a/tex/context/base/mult-cld.mkiv b/tex/context/base/mult-cld.mkiv new file mode 100644 index 000000000..1c5ebd34a --- /dev/null +++ b/tex/context/base/mult-cld.mkiv @@ -0,0 +1,29 @@ +%D \module +%D [ file=mult-ini, +%D version=2008.10.22, % 1996.06.01, +%D title=\CONTEXT\ Multilingual 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 is just an idea, maybe a bad one. + +\writestatus{loading}{ConTeXt Multilingual Macros / Lua} + +\registerctxluafile{mult-cld}{1.001} +\registerctxluafile{mult-clm}{1.001} + +\unprotect + +\def\defmkivstart#1{\unexpanded\expandafter\def\csname\e!start#1\endcsname} +\def\defmkivstop #1{\unexpanded\def\csname\e!stop #1\endcsname} +\def\defmkiv #1{\unexpanded\def\csname #1\endcsname} + +\def\mkivflush #1{\ctxlua{context._flush_(#1)}} + +\protect \endinput diff --git a/tex/context/base/mult-clm.lua b/tex/context/base/mult-clm.lua new file mode 100644 index 000000000..8838ea532 --- /dev/null +++ b/tex/context/base/mult-clm.lua @@ -0,0 +1,184 @@ +if not modules then modules = { } end modules ['mult-clm'] = { + version = 1.001, + comment = "companion to mult-clm.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- another experiment +-- todo: multilingual + +local texsprint, ctxcatcodes, vrbcatcodes = tex.sprint, tex.ctxcatcodes, tex.vrbcatcodes +local format, insert, remove, concat = string.format, table.insert, table.remove, table.concat +local unpack = unpack or table.unpack + +local trace_define = false trackers.register("context.define", function(v) trace_define = v end) + +mkiv = mkiv or { } + +mkiv.h, mkiv.a = aux.settings_to_hash, aux.settings_to_array + +local starters, stoppers, macros, stack = { }, { }, { }, { } + +local checkers = { + "\\dosingleempty", + "\\dodoubleempty", + "\\dotripleempty", + "\\doquadrupleempty", + "\\doquintupleempty", + "\\dosixtupleempty", +} + +function mkiv.m(name,...) + macros[name](...) +end + +function mkiv.b(name,...) + local sn = stack[name] + insert(sn,{...}) + starters[name](...) +end + +function mkiv.e(name) + local sn = stack[name] + local sv = remove(sn) + if sv then + stoppers[name](unpack(sv)) + else + -- nesting error + end +end + +mkiv.n = tonumber + +function mkiv.define(name,specification) -- name is optional + if type(name) == "table" then + specification = name + name = specification.name + end + if name and specification then + local arguments = specification.arguments + local na = (arguments and #arguments) or 0 + local environment = specification.environment + if na == 0 then + if environment then + texsprint(ctxcatcodes,"\\defmkstart{",name,"}{\\ctxlua{mkiv.b('",name,"')}}") + texsprint(ctxcatcodes,"\\defmkstop{", name,"}{\\ctxlua{mkiv.b('",name,"')}}") + else + texsprint(ctxcatcodes,"\\defmkiv{", name,"}{\\ctxlua{mkiv.m('",name,"')}}") + end + else + stack[name] = { } + local opt, done = 0, false + local mkivdo = "\\mkivdo" .. name + texsprint(ctxcatcodes,"\\def",mkivdo) + for i=1,na do + local a = arguments[i] + local kind = a[1] + if kind == "option" then + texsprint(ctxcatcodes,"[#",i,"]") + if not done then + opt = opt + 1 + end + else + done = true -- no more optional checking after this + texsprint(ctxcatcodes,"#",i) + end + end + if environment then + texsprint(ctxcatcodes,"{\\ctxlua{mkiv.b('",name,"'") + else + texsprint(ctxcatcodes,"{\\ctxlua{mkiv.m('",name,"'") + end + for i=1,na do + local a = arguments[i] + local kind = a[2] + if kind == "list" then + texsprint(ctxcatcodes,",mkiv.a([[#",i,"]])") + elseif kind == "hash" then + texsprint(ctxcatcodes,",mkiv.h([[#",i,"]])") + elseif kind == "number" then + texsprint(ctxcatcodes,",mkiv.n([[#",i,"]])") + else + texsprint(ctxcatcodes,",[[#",i,"]]") + end + end + texsprint(ctxcatcodes,")}}") + if environment then + texsprint(ctxcatcodes,"\\defmkivstop{" ,name,"}{\\ctxlua{mkiv.e('",name,"')}}") + texsprint(ctxcatcodes,"\\defmkivstart{",name,"}{",checkers[opt],mkivdo,"}") + else + texsprint(ctxcatcodes,"\\defmkiv{", name,"}{",checkers[opt],mkivdo,"}") + end + end + if environment then + starters[name] = specification.starter + stoppers[name] = specification.stopper + else + macros[name] = specification.macro + end + end +end + +function mkiv.tolist(t) + local r = { } + for i=1,#t do + r[i] = t[i] + end + for k,v in table.sortedhash(t) do + if type(k) ~= "number" then + r[#r+1] = k .. "=" .. v + end + end + return concat(r,", ") +end + +--~ \startluacode +--~ function test(opt_1, opt_2, arg_1) +--~ context.startnarrower() +--~ context("options 1: %s",mkiv.tolist(opt_1)) +--~ context.par() +--~ context("options 2: %s",mkiv.tolist(opt_2)) +--~ context.par() +--~ context("argument 1: %s",arg_1) +--~ context.stopnarrower() +--~ end + +--~ mkiv.define { +--~ name = "test", +--~ arguments = { +--~ { "option", "list" }, +--~ { "option", "hash" }, +--~ { "content", "string" }, +--~ }, +--~ macro = test, +--~ } +--~ \stopluacode + +--~ test: \test[1][a=3]{whatever} + +--~ \startluacode +--~ local function startmore(opt_1) +--~ context.startnarrower() +--~ context("start more, options: %s",mkiv.tolist(opt_1)) +--~ context.startnarrower() +--~ end + +--~ local function stopmore(opt_1) +--~ context.stopnarrower() +--~ context("stop more, options: %s",mkiv.tolist(opt_1)) +--~ context.stopnarrower() +--~ end + +--~ mkiv.define ( "more", { +--~ environment = true, +--~ arguments = { +--~ { "option", "list" }, +--~ }, +--~ starter = startmore, +--~ stopper = stopmore, +--~ } ) +--~ \stopluacode + +--~ more: \startmore[1] one \startmore[2] two \stopmore one \stopmore diff --git a/tex/context/base/mult-com.tex b/tex/context/base/mult-com.tex new file mode 100644 index 000000000..118616837 --- /dev/null +++ b/tex/context/base/mult-com.tex @@ -0,0 +1,31 @@ +%D \module +%D [ file=mult-com, +%D version=1996.06.01, +%D title=\CONTEXT\ Multilingual Macros, +%D subtitle=Commands, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See licen-en.pdf for +%C details. + +%D This file has been replaced by \type {mult-def.lua} from which we +%D generate separate interface definition files. + +% obsolete: +% +% \startcommands dutch english +% german czech +% italian romanian +% french +% +% language: taal language +% sprache jazyk +% lingua limba +% langue +% +% \stopcommands + +\endinput diff --git a/tex/context/base/mult-con.tex b/tex/context/base/mult-con.tex new file mode 100644 index 000000000..62e97d567 --- /dev/null +++ b/tex/context/base/mult-con.tex @@ -0,0 +1,53 @@ +%D \module +%D [ file=mult-con, +%D version=2000.09.12, +%D title=\CONTEXT\ Multilingual Macros, +%D subtitle=Constants, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 has been replaced by \type {mult-def.lua} from which we +%D generate separate interface definition files. + +% obsolete: +% +% +% \startvariables dutch english +% german czech +% italian romanian +% french +% +% one: een one +% eins jedna +% uno unu +% un +% \stopvariables +% +% \startconstants dutch english +% german czech +% italian romanian +% french +% +% sorttype: sortering sorttype +% sorttype sorttype +% sorttype sorttype +% sorttype +% \stopconstants +% +% \startelements dutch english +% german czech +% italian romanian +% french +% +% begin: beginvan begin +% anfang zacatek +% inizio inceput +% debut +% \stopelements + +\endinput diff --git a/tex/context/base/mult-de.tex b/tex/context/base/mult-de.tex new file mode 100644 index 000000000..f6f4f3bf9 --- /dev/null +++ b/tex/context/base/mult-de.tex @@ -0,0 +1,1693 @@ +% this file is auto-generated, don't edit this file +% +% definitions for interface variables for language de +% +\setinterfacevariable{Addition}{Zusatz} +\setinterfacevariable{Balloon}{Ballon} +\setinterfacevariable{Character}{Buchstabe} +\setinterfacevariable{Characters}{Buchstaben} +\setinterfacevariable{CloseDocument}{SchliesseDokument} +\setinterfacevariable{ExitViewer}{BeendeViewer} +\setinterfacevariable{FirstPage}{ErsteSeite} +\setinterfacevariable{FitHeight}{HoehePassend} +\setinterfacevariable{FitWidth}{BreitePassend} +\setinterfacevariable{GotoPage}{GotoPage} +\setinterfacevariable{Greek}{Griechisch} +\setinterfacevariable{Help}{Hilfe} +\setinterfacevariable{HideField}{VerbergeFeld} +\setinterfacevariable{HideLayer}{HideLayer} +\setinterfacevariable{Key}{Schluessel} +\setinterfacevariable{LastPage}{LetzteSeite} +\setinterfacevariable{LoadForm}{LadeFormular} +\setinterfacevariable{MONTH}{MONAT} +\setinterfacevariable{New}{Neu} +\setinterfacevariable{NextJump}{NaechsterSprung} +\setinterfacevariable{NextPage}{FolgendeSeite} +\setinterfacevariable{Numbers}{Ziffern} +\setinterfacevariable{OpenNamedDocument}{OpenNamedDocument} +\setinterfacevariable{Paragraph}{Absatz} +\setinterfacevariable{PauseMovie}{PauseFilm} +\setinterfacevariable{PauseRendering}{PauseRendering} +\setinterfacevariable{PauseSound}{PauseSound} +\setinterfacevariable{PreviousJump}{VorigerSprung} +\setinterfacevariable{PreviousPage}{VorigeSeite} +\setinterfacevariable{PrintDocument}{DruckeDokument} +\setinterfacevariable{Query}{Query} +\setinterfacevariable{QueryAgain}{QueryAgain} +\setinterfacevariable{ResetForm}{ZuruecksetzenFormular} +\setinterfacevariable{ResumeMovie}{FortsetzenFilm} +\setinterfacevariable{ResumeRendering}{ResumeRendering} +\setinterfacevariable{ResumeSound}{ResumeSound} +\setinterfacevariable{Romannumerals}{Roemischezahlen} +\setinterfacevariable{SaveDocument}{SpeichereDokument} +\setinterfacevariable{SaveForm}{SpeicheFormular} +\setinterfacevariable{SaveNamedDocument}{SaveNamedDocument} +\setinterfacevariable{SearchAgain}{WeiterSuchen} +\setinterfacevariable{SearchDocument}{DokumentDurchsuchen} +\setinterfacevariable{ShowBookmarks}{ShowBookmarks} +\setinterfacevariable{ShowField}{ZeigeFeld} +\setinterfacevariable{ShowThumbs}{ShowThumbs} +\setinterfacevariable{StartMovie}{StartFilm} +\setinterfacevariable{StartRendering}{StartRendering} +\setinterfacevariable{StartSound}{StartSound} +\setinterfacevariable{StopMovie}{StopFilm} +\setinterfacevariable{StopRendering}{StopRendering} +\setinterfacevariable{StopSound}{StopSound} +\setinterfacevariable{SubmitForm}{VersendeFormular} +\setinterfacevariable{ToggleLayer}{ToggleLayer} +\setinterfacevariable{ToggleViewer}{WechseleViewer} +\setinterfacevariable{URL}{URL} +\setinterfacevariable{VideLayer}{VideLayer} +\setinterfacevariable{ViewerHelp}{ViewerHilfe} +\setinterfacevariable{WEEKDAY}{WOCHENTAG} +\setinterfacevariable{WORD}{WORT} +\setinterfacevariable{abbreviation}{abkuerzung} +\setinterfacevariable{abbreviations}{abkuerzungen} +\setinterfacevariable{absolute}{absolut} +\setinterfacevariable{action}{aktion} +\setinterfacevariable{after}{nach} +\setinterfacevariable{all}{alles} +\setinterfacevariable{always}{immer} +\setinterfacevariable{answerarea}{answerarea} +\setinterfacevariable{appendices}{anhaenge} +\setinterfacevariable{appendix}{anhang} +\setinterfacevariable{april}{April} +\setinterfacevariable{atmargin}{amrand} +\setinterfacevariable{atpage}{aufseite} +\setinterfacevariable{august}{August} +\setinterfacevariable{author}{autor} +\setinterfacevariable{auto}{auto} +\setinterfacevariable{autointro}{autointro} +\setinterfacevariable{back}{zurueck} +\setinterfacevariable{background}{hintergrund} +\setinterfacevariable{backmatter}{epiloge} +\setinterfacevariable{backpart}{epilog} +\setinterfacevariable{backspace}{rumpfspatium} +\setinterfacevariable{backward}{rueckwaerts} +\setinterfacevariable{bbl}{bbl} +\setinterfacevariable{before}{vor} +\setinterfacevariable{begin}{begin} +\setinterfacevariable{bib}{bib} +\setinterfacevariable{big}{gross} +\setinterfacevariable{bigbodyfont}{bigbodyfont} +\setinterfacevariable{bigpreference}{grosszuegig} +\setinterfacevariable{blank}{blanko} +\setinterfacevariable{blockquote}{blockquote} +\setinterfacevariable{bodymatter}{haupttexte} +\setinterfacevariable{bodypart}{haupttext} +\setinterfacevariable{bold}{fett} +\setinterfacevariable{bolditalic}{fettitalic} +\setinterfacevariable{boldslanted}{fettgeneigt} +\setinterfacevariable{bookmark}{bookmark} +\setinterfacevariable{both}{beide} +\setinterfacevariable{bottom}{unten} +\setinterfacevariable{brief}{brief} +\setinterfacevariable{broad}{breit} +\setinterfacevariable{buffer}{puffer} +\setinterfacevariable{by}{pro} +\setinterfacevariable{calligraphic}{kalligraphie} +\setinterfacevariable{cap}{kap} +\setinterfacevariable{capital}{versalien} +\setinterfacevariable{center}{center} +\setinterfacevariable{chapter}{kapitel} +\setinterfacevariable{character}{buchstabe} +\setinterfacevariable{characters}{buchstaben} +\setinterfacevariable{cite}{cite} +\setinterfacevariable{color}{farbe} +\setinterfacevariable{column}{column} +\setinterfacevariable{columns}{spalten} +\setinterfacevariable{command}{befehl} +\setinterfacevariable{commands}{befehle} +\setinterfacevariable{comment}{kommentar} +\setinterfacevariable{component}{komponente} +\setinterfacevariable{concept}{konzept} +\setinterfacevariable{content}{inhalt} +\setinterfacevariable{contents}{inhalte} +\setinterfacevariable{continue}{fortsetzten} +\setinterfacevariable{controls}{controls} +\setinterfacevariable{conversion}{konversion} +\setinterfacevariable{current}{aktuell} +\setinterfacevariable{cutspace}{cutspace} +\setinterfacevariable{date}{datum} +\setinterfacevariable{day}{tag} +\setinterfacevariable{december}{Dezember} +\setinterfacevariable{default}{default} +\setinterfacevariable{depth}{tiefe} +\setinterfacevariable{description}{beschreibung} +\setinterfacevariable{disable}{sperren} +\setinterfacevariable{display}{bildschirm} +\setinterfacevariable{dot}{punkt} +\setinterfacevariable{doublesided}{doppelseitig} +\setinterfacevariable{down}{down} +\setinterfacevariable{each}{jede} +\setinterfacevariable{edge}{kante} +\setinterfacevariable{empty}{leer} +\setinterfacevariable{end}{end} +\setinterfacevariable{endnote}{endnote} +\setinterfacevariable{enumeration}{nummerierung} +\setinterfacevariable{environment}{umgebung} +\setinterfacevariable{even}{gerade} +\setinterfacevariable{external}{extern} +\setinterfacevariable{fact}{gegeben} +\setinterfacevariable{february}{Februar} +\setinterfacevariable{figure}{abbildung} +\setinterfacevariable{figures}{abbildungen} +\setinterfacevariable{file}{datei} +\setinterfacevariable{final}{endfassung} +\setinterfacevariable{first}{erste} +\setinterfacevariable{firstcolumn}{firstcolumn} +\setinterfacevariable{firstpage}{ersteseite} +\setinterfacevariable{firstsubpage}{ersteunterseite} +\setinterfacevariable{fit}{passend} +\setinterfacevariable{five}{fuenf} +\setinterfacevariable{fix}{stellewiederher} +\setinterfacevariable{fixed}{fest} +\setinterfacevariable{flexible}{flexibel} +\setinterfacevariable{float}{gleitobjekt} +\setinterfacevariable{flushinner}{flushinner} +\setinterfacevariable{flushleft}{flushleft} +\setinterfacevariable{flushouter}{flushouter} +\setinterfacevariable{flushright}{flushright} +\setinterfacevariable{footer}{fusszeile} +\setinterfacevariable{footnote}{fussnote} +\setinterfacevariable{force}{zwinge} +\setinterfacevariable{foreground}{vordergrund} +\setinterfacevariable{formeel}{formeel} +\setinterfacevariable{formula}{formel} +\setinterfacevariable{formulae}{formeln} +\setinterfacevariable{forward}{vorwaerts} +\setinterfacevariable{four}{vier} +\setinterfacevariable{frame}{rahmen} +\setinterfacevariable{framedtext}{umrahmtertext} +\setinterfacevariable{friday}{freitag} +\setinterfacevariable{frontmatter}{einleitungen} +\setinterfacevariable{frontpart}{einleitung} +\setinterfacevariable{global}{global} +\setinterfacevariable{graphic}{grafik} +\setinterfacevariable{graphics}{grafiken} +\setinterfacevariable{gray}{grau} +\setinterfacevariable{greek}{griechisch} +\setinterfacevariable{grid}{gritter} +\setinterfacevariable{halfline}{halbezeile} +\setinterfacevariable{handwritten}{handschrift} +\setinterfacevariable{hang}{haengend} +\setinterfacevariable{hanging}{haengend} +\setinterfacevariable{head}{kopf} +\setinterfacevariable{header}{kopfzeile} +\setinterfacevariable{height}{hoehe} +\setinterfacevariable{helptext}{hilfetext} +\setinterfacevariable{hencefore}{vorher} +\setinterfacevariable{here}{hier} +\setinterfacevariable{hereafter}{nachher} +\setinterfacevariable{hidden}{versteckt} +\setinterfacevariable{hiding}{verbergen} +\setinterfacevariable{high}{hoch} +\setinterfacevariable{horizontal}{horizontal} +\setinterfacevariable{hyphenated}{hyphenate} +\setinterfacevariable{hz}{hz} +\setinterfacevariable{inbetween}{zwischen} +\setinterfacevariable{index}{index} +\setinterfacevariable{indices}{indizies} +\setinterfacevariable{informeel}{informeel} +\setinterfacevariable{inherit}{inherit} +\setinterfacevariable{inleft}{imlinken} +\setinterfacevariable{inmargin}{imrand} +\setinterfacevariable{inner}{innen} +\setinterfacevariable{inneredge}{inneredge} +\setinterfacevariable{innermargin}{innermargin} +\setinterfacevariable{inright}{imrechten} +\setinterfacevariable{interaction}{interaktion} +\setinterfacevariable{interactionmenu}{interaktionsmenue} +\setinterfacevariable{intermezzi}{intermezzi} +\setinterfacevariable{intermezzo}{intermezzo} +\setinterfacevariable{intext}{imtext} +\setinterfacevariable{intro}{intro} +\setinterfacevariable{italic}{italic} +\setinterfacevariable{italicbold}{italicfett} +\setinterfacevariable{item}{pos} +\setinterfacevariable{itemize}{aufzaehlung} +\setinterfacevariable{its}{its} +\setinterfacevariable{january}{Januar} +\setinterfacevariable{joinedup}{keinabstand} +\setinterfacevariable{july}{Juli} +\setinterfacevariable{june}{Juni} +\setinterfacevariable{keep}{behalte} +\setinterfacevariable{knockout}{knockout} +\setinterfacevariable{label}{label} +\setinterfacevariable{landscape}{querformat} +\setinterfacevariable{last}{letzte} +\setinterfacevariable{lastcolumn}{lastcolumn} +\setinterfacevariable{lastpage}{letzteseite} +\setinterfacevariable{lastpagenumber}{lastpagenumber} +\setinterfacevariable{lastsubpage}{letzteunterseite} +\setinterfacevariable{layer}{layer} +\setinterfacevariable{left}{links} +\setinterfacevariable{leftedge}{linkekante} +\setinterfacevariable{lefthanging}{lefthanging} +\setinterfacevariable{leftmargin}{linkerrand} +\setinterfacevariable{leftpage}{linkerseite} +\setinterfacevariable{lefttoright}{lefttoright} +\setinterfacevariable{legend}{legende} +\setinterfacevariable{lesshyphenation}{lesshyphenation} +\setinterfacevariable{line}{zeile} +\setinterfacevariable{linenote}{linenote} +\setinterfacevariable{lines}{zeilen} +\setinterfacevariable{list}{liste} +\setinterfacevariable{local}{lokal} +\setinterfacevariable{localenvironment}{lokaleumgebung} +\setinterfacevariable{logo}{logo} +\setinterfacevariable{logos}{logos} +\setinterfacevariable{lohi}{hoti} +\setinterfacevariable{loose}{lose} +\setinterfacevariable{low}{tief} +\setinterfacevariable{ls}{ls} +\setinterfacevariable{makeup}{umbruch} +\setinterfacevariable{mar}{mar} +\setinterfacevariable{march}{Maerz} +\setinterfacevariable{margin}{marginalie} +\setinterfacevariable{marginedge}{marginalkante} +\setinterfacevariable{margintitle}{marginaltitel} +\setinterfacevariable{marking}{beschriftung} +\setinterfacevariable{mathalignment}{mathalignment} +\setinterfacevariable{mathcases}{mathcases} +\setinterfacevariable{mathmatrix}{mathmatrix} +\setinterfacevariable{max}{max} +\setinterfacevariable{maxdepth}{maxdepth} +\setinterfacevariable{maxheight}{maxheight} +\setinterfacevariable{maxwidth}{maxwidth} +\setinterfacevariable{may}{Mai} +\setinterfacevariable{mediaeval}{mittelalterlich} +\setinterfacevariable{medium}{mittel} +\setinterfacevariable{middle}{mittig} +\setinterfacevariable{min}{min} +\setinterfacevariable{mindepth}{mindepth} +\setinterfacevariable{minheight}{minhoehe} +\setinterfacevariable{minwidth}{minbreite} +\setinterfacevariable{mirrored}{gespiegelt} +\setinterfacevariable{monday}{montag} +\setinterfacevariable{mono}{mono} +\setinterfacevariable{month}{monat} +\setinterfacevariable{morehyphenation}{morehyphenation} +\setinterfacevariable{name}{name} +\setinterfacevariable{narrow}{schmall} +\setinterfacevariable{negative}{negativ} +\setinterfacevariable{never}{nie} +\setinterfacevariable{new}{neu} +\setinterfacevariable{next}{folgende} +\setinterfacevariable{nextevenpage}{naechstegeradeseite} +\setinterfacevariable{nextoddpage}{naechsteungeradeseite} +\setinterfacevariable{nextpage}{folgendeseite} +\setinterfacevariable{nextsubpage}{folgendeunterseite} +\setinterfacevariable{no}{nein} +\setinterfacevariable{nocheck}{nocheck} +\setinterfacevariable{nofit}{nofit} +\setinterfacevariable{nogrid}{nogrid} +\setinterfacevariable{nohz}{nohz} +\setinterfacevariable{nomarking}{keinebeschriftung} +\setinterfacevariable{none}{kein} +\setinterfacevariable{nonumber}{nonumber} +\setinterfacevariable{normal}{normal} +\setinterfacevariable{nospacing}{nospacing} +\setinterfacevariable{not}{nicht} +\setinterfacevariable{note}{note} +\setinterfacevariable{nothanging}{nothanging} +\setinterfacevariable{nothyphenated}{nothyphenated} +\setinterfacevariable{november}{November} +\setinterfacevariable{nowhere}{nirgens} +\setinterfacevariable{nowhite}{keinweiss} +\setinterfacevariable{number}{nummer} +\setinterfacevariable{numbers}{ziffern} +\setinterfacevariable{october}{Oktober} +\setinterfacevariable{odd}{ungerade} +\setinterfacevariable{off}{aus} +\setinterfacevariable{offset}{offset} +\setinterfacevariable{old}{old} +\setinterfacevariable{on}{an} +\setinterfacevariable{one}{eins} +\setinterfacevariable{opposite}{gegenueber} +\setinterfacevariable{outer}{aussen} +\setinterfacevariable{outeredge}{outeredge} +\setinterfacevariable{outermargin}{outermargin} +\setinterfacevariable{overbar}{ueberstrichen} +\setinterfacevariable{overbars}{ueberstreichen} +\setinterfacevariable{overlay}{overlay} +\setinterfacevariable{overprint}{overprint} +\setinterfacevariable{overstrike}{durchgestrichen} +\setinterfacevariable{overstrikes}{durchstreichen} +\setinterfacevariable{packed}{gepackt} +\setinterfacevariable{page}{seite} +\setinterfacevariable{pagecomment}{pagecomment} +\setinterfacevariable{pagenumber}{seitennummer} +\setinterfacevariable{paper}{papier} +\setinterfacevariable{paragraph}{absatz} +\setinterfacevariable{part}{teil} +\setinterfacevariable{positive}{positiv} +\setinterfacevariable{postponing}{verschieben} +\setinterfacevariable{postscript}{postscript} +\setinterfacevariable{preference}{einstellung} +\setinterfacevariable{preview}{vorschau} +\setinterfacevariable{previous}{vorig} +\setinterfacevariable{previousevenpage}{vorigegeradeseite} +\setinterfacevariable{previousoddpage}{vorigeungeradeseite} +\setinterfacevariable{previouspage}{vorigeseite} +\setinterfacevariable{previoussubpage}{vorigeunterseite} +\setinterfacevariable{printable}{druckbar} +\setinterfacevariable{process}{process} +\setinterfacevariable{product}{produkt} +\setinterfacevariable{program}{programm} +\setinterfacevariable{project}{projekt} +\setinterfacevariable{protected}{geschuetzt} +\setinterfacevariable{quadruple}{viertel} +\setinterfacevariable{quotation}{zitat} +\setinterfacevariable{quote}{zitieren} +\setinterfacevariable{ran}{ran} +\setinterfacevariable{random}{zufaellig} +\setinterfacevariable{readonly}{nurlesbar} +\setinterfacevariable{rectangular}{rechteckig} +\setinterfacevariable{referral}{merkmal} +\setinterfacevariable{register}{register} +\setinterfacevariable{regular}{regular} +\setinterfacevariable{rekening}{rekening} +\setinterfacevariable{relative}{relativ} +\setinterfacevariable{repeat}{wiederholen} +\setinterfacevariable{required}{obligatorisch} +\setinterfacevariable{reset}{zuruecksetzten} +\setinterfacevariable{reverse}{reverse} +\setinterfacevariable{right}{rechts} +\setinterfacevariable{rightedge}{rechterkante} +\setinterfacevariable{righthanging}{righthanging} +\setinterfacevariable{rightmargin}{rechterrand} +\setinterfacevariable{rightpage}{rechterseite} +\setinterfacevariable{righttoleft}{righttoleft} +\setinterfacevariable{roman}{antiqua} +\setinterfacevariable{romannumerals}{roemischezahlen} +\setinterfacevariable{rotate}{drehe} +\setinterfacevariable{rotated}{gedreht} +\setinterfacevariable{round}{rund} +\setinterfacevariable{row}{row} +\setinterfacevariable{rule}{linie} +\setinterfacevariable{samepage}{selbeseite} +\setinterfacevariable{sans}{sans} +\setinterfacevariable{sansbold}{sansfett} +\setinterfacevariable{sansserif}{grotesk} +\setinterfacevariable{saturday}{samstag} +\setinterfacevariable{screen}{raster} +\setinterfacevariable{section}{absatz} +\setinterfacevariable{sectionblockenvironment}{sectionblockenvironment} +\setinterfacevariable{sectionnumber}{abschnittsnummer} +\setinterfacevariable{see}{sieh} +\setinterfacevariable{september}{September} +\setinterfacevariable{serif}{serif} +\setinterfacevariable{serried}{kleinerabstand} +\setinterfacevariable{setups}{impostazioni} +\setinterfacevariable{sheet}{sheet} +\setinterfacevariable{short}{kurz} +\setinterfacevariable{singlesided}{einzelseitig} +\setinterfacevariable{slanted}{geneigt} +\setinterfacevariable{slantedbold}{geneigtfett} +\setinterfacevariable{small}{klein} +\setinterfacevariable{smallbodyfont}{smallbodyfont} +\setinterfacevariable{smallbold}{kleinfett} +\setinterfacevariable{smallbolditalic}{kleinfettitalic} +\setinterfacevariable{smallboldslanted}{kleinfettgeneigt} +\setinterfacevariable{smallcaps}{smallcaps} +\setinterfacevariable{smallitalic}{kleinitalic} +\setinterfacevariable{smallitalicbold}{kleinitalicfett} +\setinterfacevariable{smallnormal}{kleinnormal} +\setinterfacevariable{smallslanted}{kleingeneigt} +\setinterfacevariable{smallslantedbold}{kleingeneigtfett} +\setinterfacevariable{smalltype}{kleintippen} +\setinterfacevariable{somewhere}{irgendwo} +\setinterfacevariable{sorted}{sortiert} +\setinterfacevariable{space}{spatium} +\setinterfacevariable{spacing}{spatiumausgleich} +\setinterfacevariable{speech}{speech} +\setinterfacevariable{split}{split} +\setinterfacevariable{spot}{spot} +\setinterfacevariable{standard}{standard} +\setinterfacevariable{start}{start} +\setinterfacevariable{starter}{starter} +\setinterfacevariable{sticker}{sticker} +\setinterfacevariable{stop}{stop} +\setinterfacevariable{stopper}{trenner} +\setinterfacevariable{stretch}{strecken} +\setinterfacevariable{strict}{streng} +\setinterfacevariable{strong}{strong} +\setinterfacevariable{strut}{strut} +\setinterfacevariable{sub}{unter} +\setinterfacevariable{subbackward}{unterrueckwaerts} +\setinterfacevariable{subformula}{subformel} +\setinterfacevariable{subforward}{untervorwaerts} +\setinterfacevariable{subject}{thema} +\setinterfacevariable{subpage}{unterseite} +\setinterfacevariable{subsection}{unterabsatz} +\setinterfacevariable{subsubject}{unterthema} +\setinterfacevariable{subsubsection}{unterunterabsatz} +\setinterfacevariable{subsubsubject}{unterunterthema} +\setinterfacevariable{subsubsubsection}{unterunterunterabsatz} +\setinterfacevariable{subsubsubsubject}{unterunterunterthema} +\setinterfacevariable{subsubsubsubsection}{unterunterunterunterabsatz} +\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} +\setinterfacevariable{symbol}{symbol} +\setinterfacevariable{synchronize}{synchronize} +\setinterfacevariable{system}{systeme} +\setinterfacevariable{table}{tabelle} +\setinterfacevariable{tablehead}{tabellenueberschrift} +\setinterfacevariable{tables}{tabellen} +\setinterfacevariable{tabletail}{tabellenende} +\setinterfacevariable{tabulate}{tabulator} +\setinterfacevariable{tabulatehead}{tabulatehead} +\setinterfacevariable{tabulatetail}{tabulatetail} +\setinterfacevariable{tall}{lang} +\setinterfacevariable{teletype}{fernschreiber} +\setinterfacevariable{temporary}{temporaer} +\setinterfacevariable{test}{test} +\setinterfacevariable{text}{text} +\setinterfacevariable{three}{drei} +\setinterfacevariable{thursday}{donnerstag} +\setinterfacevariable{title}{titel} +\setinterfacevariable{toggle}{toggle} +\setinterfacevariable{tolerant}{tolerant} +\setinterfacevariable{top}{oben} +\setinterfacevariable{tuesday}{dienstag} +\setinterfacevariable{two}{zwei} +\setinterfacevariable{txt}{txt} +\setinterfacevariable{type}{tippen} +\setinterfacevariable{typing}{tippen} +\setinterfacevariable{unavailable}{nichtverfuegbar} +\setinterfacevariable{underbar}{unterstrichen} +\setinterfacevariable{underbars}{unterstreichen} +\setinterfacevariable{unit}{einheit} +\setinterfacevariable{units}{einheiten} +\setinterfacevariable{unknown}{unbekannt} +\setinterfacevariable{unpacked}{ungepackt} +\setinterfacevariable{up}{up} +\setinterfacevariable{url}{url} +\setinterfacevariable{used}{verwende} +\setinterfacevariable{value}{wert} +\setinterfacevariable{vertical}{vertikal} +\setinterfacevariable{very}{sehr} +\setinterfacevariable{verystrict}{sehrstreng} +\setinterfacevariable{verytolerant}{sehrtolerant} +\setinterfacevariable{weak}{weak} +\setinterfacevariable{wednesday}{mittwoch} +\setinterfacevariable{week}{woche} +\setinterfacevariable{weekday}{wochentag} +\setinterfacevariable{white}{weiss} +\setinterfacevariable{wide}{breit} +\setinterfacevariable{width}{breite} +\setinterfacevariable{xml}{xml} +\setinterfacevariable{year}{jahr} +\setinterfacevariable{yes}{ja} +% definitions for interface constants for language de +% +\setinterfaceconstant{action}{aktion} +\setinterfaceconstant{address}{adresse} +\setinterfaceconstant{after}{nach} +\setinterfaceconstant{afterhead}{nachkopf} +\setinterfaceconstant{afterkey}{nachtaste} +\setinterfaceconstant{align}{ausrichtung} +\setinterfaceconstant{aligncharacter}{aligncharacter} +\setinterfaceconstant{alignmentcharacter}{alignmentcharacter} +\setinterfaceconstant{alignsymbol}{alignsymbol} +\setinterfaceconstant{aligntitle}{titelausrichten} +\setinterfaceconstant{alternative}{alternative} +\setinterfaceconstant{andtext}{andtext} +\setinterfaceconstant{apa}{apa} +\setinterfaceconstant{arrow}{pfeil} +\setinterfaceconstant{artauthor}{artauthor} +\setinterfaceconstant{artauthoretaldisplay}{artauthoretaldisplay} +\setinterfaceconstant{artauthoretallimit}{artauthoretallimit} +\setinterfaceconstant{artauthoretaltext}{artauthoretaltext} +\setinterfaceconstant{at}{bei} +\setinterfaceconstant{author}{autor} +\setinterfaceconstant{authoretaldisplay}{authoretaldisplay} +\setinterfaceconstant{authoretallimit}{authoretallimit} +\setinterfaceconstant{authoretaltext}{authoretaltext} +\setinterfaceconstant{auto}{auto} +\setinterfaceconstant{autofile}{autofile} +\setinterfaceconstant{autofocus}{autofocus} +\setinterfaceconstant{autohang}{autohang} +\setinterfaceconstant{autostrut}{autostrut} +\setinterfaceconstant{autowidth}{autobreite} +\setinterfaceconstant{axis}{achsen} +\setinterfaceconstant{background}{hintergrund} +\setinterfaceconstant{backgroundcolor}{hintergrundfarbe} +\setinterfaceconstant{backgroundcorner}{hintergrundwinkel} +\setinterfaceconstant{backgrounddepth}{hintergrundtiefe} +\setinterfaceconstant{backgroundoffset}{hintergrundoffset} +\setinterfaceconstant{backgroundradius}{hintergrundradius} +\setinterfaceconstant{backgroundscreen}{hintergrundraster} +\setinterfaceconstant{backspace}{rumpfspatium} +\setinterfaceconstant{balance}{ausgleichen} +\setinterfaceconstant{before}{vor} +\setinterfaceconstant{beforehead}{vorkopf} +\setinterfaceconstant{bet}{bet} +\setinterfaceconstant{big}{gross} +\setinterfaceconstant{blank}{blanko} +\setinterfaceconstant{blockway}{blockauf} +\setinterfaceconstant{bodyfont}{fliesstext} +\setinterfaceconstant{bookmark}{bookmark} +\setinterfaceconstant{bottom}{unten} +\setinterfaceconstant{bottomafter}{bottomafter} +\setinterfaceconstant{bottombefore}{bottombefore} +\setinterfaceconstant{bottomdistance}{abstandunten} +\setinterfaceconstant{bottomframe}{untenrahmen} +\setinterfaceconstant{bottomoffset}{untenoffset} +\setinterfaceconstant{bottomspace}{bottomspace} +\setinterfaceconstant{bottomstate}{untenstatus} +\setinterfaceconstant{cache}{cache} +\setinterfaceconstant{calculate}{berechnen} +\setinterfaceconstant{ccommand}{cbefehl} +\setinterfaceconstant{click}{klick} +\setinterfaceconstant{clickin}{klickin} +\setinterfaceconstant{clickout}{klickaus} +\setinterfaceconstant{clipoffset}{clipoffset} +\setinterfaceconstant{closeaction}{schliessenaktion} +\setinterfaceconstant{closecommand}{closecommand} +\setinterfaceconstant{closepageaction}{closepageaction} +\setinterfaceconstant{closesymbol}{closesymbol} +\setinterfaceconstant{color}{farbe} +\setinterfaceconstant{column}{spalte} +\setinterfaceconstant{columndistance}{spaltenabstand} +\setinterfaceconstant{columns}{spalten} +\setinterfaceconstant{command}{befehl} +\setinterfaceconstant{commandafter}{zumbefehl} +\setinterfaceconstant{commandbefore}{vorbefehl} +\setinterfaceconstant{commands}{befehle} +\setinterfaceconstant{component}{component} +\setinterfaceconstant{compoundhyphen}{compoundhyphen} +\setinterfaceconstant{compress}{compress} +\setinterfaceconstant{connector}{connector} +\setinterfaceconstant{continue}{fortsetzen} +\setinterfaceconstant{contrastcolor}{kontrastfarbe} +\setinterfaceconstant{controls}{controls} +\setinterfaceconstant{conversion}{konversion} +\setinterfaceconstant{convertfile}{konvertieredatei} +\setinterfaceconstant{corner}{winkel} +\setinterfaceconstant{coupling}{verknuepfung} +\setinterfaceconstant{couplingway}{verkopplungsart} +\setinterfaceconstant{criterium}{kriterium} +\setinterfaceconstant{current}{aktuell} +\setinterfaceconstant{cutspace}{cutspace} +\setinterfaceconstant{dash}{strich} +\setinterfaceconstant{dat}{dat} +\setinterfaceconstant{database}{database} +\setinterfaceconstant{date}{datum} +\setinterfaceconstant{deepnumbercommand}{deepnumbercommand} +\setinterfaceconstant{deeptextcommand}{deeptextcommand} +\setinterfaceconstant{default}{default} +\setinterfaceconstant{delay}{wartezeit} +\setinterfaceconstant{depth}{tiefe} +\setinterfaceconstant{depthcorrection}{tiefekorrektur} +\setinterfaceconstant{direction}{richtung} +\setinterfaceconstant{directory}{verzeichnis} +\setinterfaceconstant{display}{bildschirm} +\setinterfaceconstant{distance}{abstand} +\setinterfaceconstant{dot}{punkt} +\setinterfaceconstant{doublesided}{doppelseitig} +\setinterfaceconstant{dummy}{dummy} +\setinterfaceconstant{dx}{dx} +\setinterfaceconstant{dy}{dy} +\setinterfaceconstant{edge}{kante} +\setinterfaceconstant{edgedistance}{kantenabstand} +\setinterfaceconstant{editor}{editor} +\setinterfaceconstant{editoretaldisplay}{editoretaldisplay} +\setinterfaceconstant{editoretallimit}{editoretallimit} +\setinterfaceconstant{editoretaltext}{editoretaltext} +\setinterfaceconstant{empty}{leer} +\setinterfaceconstant{equalheight}{equalheight} +\setinterfaceconstant{equalwidth}{equalwidth} +\setinterfaceconstant{escape}{escape} +\setinterfaceconstant{evenmargin}{geraderand} +\setinterfaceconstant{expansion}{expansion} +\setinterfaceconstant{export}{export} +\setinterfaceconstant{extras}{extras} +\setinterfaceconstant{factor}{faktor} +\setinterfaceconstant{fallback}{fallback} +\setinterfaceconstant{family}{familie} +\setinterfaceconstant{fieldbackgroundcolor}{feldhintergrundfarbe} +\setinterfaceconstant{fieldframecolor}{feldrahmenfarbe} +\setinterfaceconstant{fieldlayer}{fieldlayer} +\setinterfaceconstant{fieldoffset}{feldoffset} +\setinterfaceconstant{file}{datei} +\setinterfaceconstant{filtercommand}{filtercommand} +\setinterfaceconstant{finalnamesep}{finalnamesep} +\setinterfaceconstant{firstnamesep}{firstnamesep} +\setinterfaceconstant{focus}{focus} +\setinterfaceconstant{focusin}{focusin} +\setinterfaceconstant{focusout}{focusout} +\setinterfaceconstant{footer}{fusszeile} +\setinterfaceconstant{footerdistance}{fusszeilenabstand} +\setinterfaceconstant{footerstate}{fusszeilenstatus} +\setinterfaceconstant{foregroundcolor}{foregroundcolor} +\setinterfaceconstant{foregroundstyle}{foregroundstyle} +\setinterfaceconstant{format}{formatieren} +\setinterfaceconstant{frame}{rahmen} +\setinterfaceconstant{framecolor}{rahmenfarbe} +\setinterfaceconstant{framecorner}{rahmenwinkel} +\setinterfaceconstant{framedepth}{rahmentiefe} +\setinterfaceconstant{frameoffset}{rahmenoffset} +\setinterfaceconstant{frameradius}{rahmenradius} +\setinterfaceconstant{frames}{umrahmen} +\setinterfaceconstant{from}{von} +\setinterfaceconstant{get}{hole} +\setinterfaceconstant{global}{global} +\setinterfaceconstant{grid}{gritter} +\setinterfaceconstant{hang}{haengend} +\setinterfaceconstant{headalign}{headalign} +\setinterfaceconstant{headcolor}{kopffarbe} +\setinterfaceconstant{headcommand}{headcommand} +\setinterfaceconstant{headconversion}{headconversion} +\setinterfaceconstant{header}{kopfzeile} +\setinterfaceconstant{headerdistance}{kopfzeilenabstand} +\setinterfaceconstant{headerstate}{kopfzeilenstatus} +\setinterfaceconstant{headlabel}{headlabel} +\setinterfaceconstant{headnumber}{kopfnummer} +\setinterfaceconstant{headstyle}{kopfstil} +\setinterfaceconstant{height}{hoehe} +\setinterfaceconstant{hfactor}{hfaktor} +\setinterfaceconstant{hfil}{hfil} +\setinterfaceconstant{hidenumber}{hidenumber} +\setinterfaceconstant{hoffset}{hoffset} +\setinterfaceconstant{horoffset}{rumpfabstand} +\setinterfaceconstant{hyphen}{hyphen} +\setinterfaceconstant{icommand}{ibefehl} +\setinterfaceconstant{in}{in} +\setinterfaceconstant{inbetween}{zwischen} +\setinterfaceconstant{increment}{erhoehen} +\setinterfaceconstant{incrementnumber}{nummererhoehen} +\setinterfaceconstant{indenting}{einziehen} +\setinterfaceconstant{indentnext}{ziehefolgendeein} +\setinterfaceconstant{indicator}{indikator} +\setinterfaceconstant{inner}{innen} +\setinterfaceconstant{innermargin}{innermargin} +\setinterfaceconstant{inputfile}{inputfile} +\setinterfaceconstant{intent}{intent} +\setinterfaceconstant{interaction}{interaktion} +\setinterfaceconstant{interlinespace}{zeilenabstande} +\setinterfaceconstant{itemalign}{itemalign} +\setinterfaceconstant{items}{posten} +\setinterfaceconstant{juniorsep}{juniorsep} +\setinterfaceconstant{ken}{ken} +\setinterfaceconstant{keyexpansion}{keyexpansion} +\setinterfaceconstant{keyword}{keyword} +\setinterfaceconstant{label}{label} +\setinterfaceconstant{lastnamesep}{lastnamesep} +\setinterfaceconstant{lastpubsep}{lastpubsep} +\setinterfaceconstant{left}{links} +\setinterfaceconstant{leftcolor}{linkerfarbe} +\setinterfaceconstant{leftcompoundhyphen}{leftcompoundhyphen} +\setinterfaceconstant{leftedge}{linkekante} +\setinterfaceconstant{leftedgedistance}{linkerkantenabstand} +\setinterfaceconstant{leftframe}{linkerrahmen} +\setinterfaceconstant{lefthyphen}{lefthyphen} +\setinterfaceconstant{leftmargin}{linkerrand} +\setinterfaceconstant{leftmargindistance}{linkerrandabstand} +\setinterfaceconstant{leftoffset}{linkeroffset} +\setinterfaceconstant{leftquotation}{linkerzitat} +\setinterfaceconstant{leftquote}{linkerzitieren} +\setinterfaceconstant{leftsentence}{linkersatz} +\setinterfaceconstant{leftspeech}{leftspeech} +\setinterfaceconstant{leftstyle}{linkerstil} +\setinterfaceconstant{leftsubsentence}{linkersubsatz} +\setinterfaceconstant{lefttext}{linkertext} +\setinterfaceconstant{leftwidth}{linkerbreite} +\setinterfaceconstant{level}{niveau} +\setinterfaceconstant{levels}{niveaus} +\setinterfaceconstant{limittext}{limittext} +\setinterfaceconstant{line}{zeile} +\setinterfaceconstant{linecorrection}{zeilekorrektur} +\setinterfaceconstant{lines}{zeilen} +\setinterfaceconstant{list}{liste} +\setinterfaceconstant{listtext}{listtext} +\setinterfaceconstant{local}{lokal} +\setinterfaceconstant{location}{platz} +\setinterfaceconstant{logo}{logo} +\setinterfaceconstant{logos}{logos} +\setinterfaceconstant{marcolor}{beschrfarbe} +\setinterfaceconstant{margin}{marginalie} +\setinterfaceconstant{margindistance}{marginalabstand} +\setinterfaceconstant{marginedge}{marginalkante} +\setinterfaceconstant{marginedgetext}{marginalkantetext} +\setinterfaceconstant{margintext}{marginaltext} +\setinterfaceconstant{marking}{beschriftung} +\setinterfaceconstant{marstyle}{beschrstil} +\setinterfaceconstant{max}{max} +\setinterfaceconstant{maxdepth}{maxdepth} +\setinterfaceconstant{maxheight}{maxhoehe} +\setinterfaceconstant{maxwidth}{maxbreite} +\setinterfaceconstant{maybeyear}{maybeyear} +\setinterfaceconstant{menu}{menue} +\setinterfaceconstant{method}{methode} +\setinterfaceconstant{middle}{mittig} +\setinterfaceconstant{middlespeech}{middlespeech} +\setinterfaceconstant{middletext}{mittigertext} +\setinterfaceconstant{midsentence}{midsentence} +\setinterfaceconstant{min}{min} +\setinterfaceconstant{mindepth}{mindepth} +\setinterfaceconstant{minheight}{minhoehe} +\setinterfaceconstant{minwidth}{minbreite} +\setinterfaceconstant{monthconversion}{monthconversion} +\setinterfaceconstant{n}{n} +\setinterfaceconstant{name}{name} +\setinterfaceconstant{namesep}{namesep} +\setinterfaceconstant{nbottom}{nunten} +\setinterfaceconstant{nc}{nc} +\setinterfaceconstant{next}{folgende} +\setinterfaceconstant{nl}{nl} +\setinterfaceconstant{nleft}{nlinks} +\setinterfaceconstant{nlines}{zzeile} +\setinterfaceconstant{norm}{norm} +\setinterfaceconstant{nr}{nr} +\setinterfaceconstant{nright}{nrechts} +\setinterfaceconstant{ntop}{noben} +\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{numberstarter}{numberstarter} +\setinterfaceconstant{numberstopper}{numberstopper} +\setinterfaceconstant{numberstyle}{nummernstil} +\setinterfaceconstant{numberwidth}{numberwidth} +\setinterfaceconstant{nx}{nx} +\setinterfaceconstant{ny}{ny} +\setinterfaceconstant{object}{objekt} +\setinterfaceconstant{obstruction}{gesperrt} +\setinterfaceconstant{oddmargin}{ungeraderand} +\setinterfaceconstant{offset}{offset} +\setinterfaceconstant{openaction}{oeffenaktion} +\setinterfaceconstant{openpageaction}{openpageaction} +\setinterfaceconstant{option}{option} +\setinterfaceconstant{order}{order} +\setinterfaceconstant{orientation}{orientation} +\setinterfaceconstant{otherstext}{otherstext} +\setinterfaceconstant{outermargin}{outermargin} +\setinterfaceconstant{overprint}{overprint} +\setinterfaceconstant{ownnumber}{eigenenummer} +\setinterfaceconstant{page}{seite} +\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{pageprefixstarter}{pageprefixstarter} +\setinterfaceconstant{pageprefixstopper}{pageprefixstopper} +\setinterfaceconstant{pagesegments}{pagesegments} +\setinterfaceconstant{pageseparatorset}{pageseparatorset} +\setinterfaceconstant{pageset}{pageset} +\setinterfaceconstant{pagestarter}{pagestarter} +\setinterfaceconstant{pagestate}{pagestate} +\setinterfaceconstant{pagestopper}{pagestopper} +\setinterfaceconstant{pagestyle}{seitenstil} +\setinterfaceconstant{palet}{palette} +\setinterfaceconstant{paper}{papier} +\setinterfaceconstant{paragraph}{absatz} +\setinterfaceconstant{place}{platziere} +\setinterfaceconstant{placehead}{setzekopf} +\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{prefixstarter}{prefixstarter} +\setinterfaceconstant{prefixstopper}{prefixstopper} +\setinterfaceconstant{preset}{voreinstellung} +\setinterfaceconstant{preview}{vorschau} +\setinterfaceconstant{previous}{vorige} +\setinterfaceconstant{previousnumber}{vorigenummer} +\setinterfaceconstant{process}{process} +\setinterfaceconstant{pubsep}{pubsep} +\setinterfaceconstant{radius}{radius} +\setinterfaceconstant{random}{zufaellig} +\setinterfaceconstant{range}{range} +\setinterfaceconstant{reduction}{reduktion} +\setinterfaceconstant{ref}{ref} +\setinterfaceconstant{refcommand}{refcommand} +\setinterfaceconstant{reference}{referenz} +\setinterfaceconstant{referenceprefix}{referenceprefix} +\setinterfaceconstant{referencing}{referieren} +\setinterfaceconstant{regionin}{regionin} +\setinterfaceconstant{regionout}{regionaus} +\setinterfaceconstant{repeat}{wiederholen} +\setinterfaceconstant{reset}{reset} +\setinterfaceconstant{resetnumber}{resetnumber} +\setinterfaceconstant{resolution}{aufloesung} +\setinterfaceconstant{right}{rechts} +\setinterfaceconstant{rightcolor}{rechterfarbe} +\setinterfaceconstant{rightcompoundhyphen}{rightcompoundhyphen} +\setinterfaceconstant{rightedge}{rechtekante} +\setinterfaceconstant{rightedgedistance}{rechterkantenabstand} +\setinterfaceconstant{rightframe}{rechterrahmen} +\setinterfaceconstant{righthyphen}{righthyphen} +\setinterfaceconstant{rightmargin}{rechterrand} +\setinterfaceconstant{rightmargindistance}{rechterrandabstand} +\setinterfaceconstant{rightoffset}{rechterabstand} +\setinterfaceconstant{rightquotation}{rechterzitat} +\setinterfaceconstant{rightquote}{rechterzitieren} +\setinterfaceconstant{rightsentence}{rechtersatz} +\setinterfaceconstant{rightspeech}{rightspeech} +\setinterfaceconstant{rightstyle}{rechterstil} +\setinterfaceconstant{rightsubsentence}{rechtersubsatz} +\setinterfaceconstant{righttext}{rechtertext} +\setinterfaceconstant{rightwidth}{rechterbreite} +\setinterfaceconstant{rotation}{rotation} +\setinterfaceconstant{rule}{linie} +\setinterfaceconstant{rulecolor}{linienfarbe} +\setinterfaceconstant{rulethickness}{liniendicke} +\setinterfaceconstant{samepage}{selbeseite} +\setinterfaceconstant{sample}{muster} +\setinterfaceconstant{samplesize}{samplesize} +\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{sectionresetset}{sectionresetset} +\setinterfaceconstant{sectionsegments}{sectionsegments} +\setinterfaceconstant{sectionseparatorset}{sectionseparatorset} +\setinterfaceconstant{sectionset}{sectionset} +\setinterfaceconstant{sectionstarter}{sectionstarter} +\setinterfaceconstant{sectionstopper}{sectionstopper} +\setinterfaceconstant{separator}{seperator} +\setinterfaceconstant{set}{set} +\setinterfaceconstant{setups}{setups} +\setinterfaceconstant{side}{objektabstand} +\setinterfaceconstant{sidealign}{sidealign} +\setinterfaceconstant{sidemethod}{sidemethod} +\setinterfaceconstant{sidespaceafter}{nebennachspatium} +\setinterfaceconstant{sidespacebefore}{nebenvorspatium} +\setinterfaceconstant{sign}{zeichen} +\setinterfaceconstant{size}{groesse} +\setinterfaceconstant{small}{klein} +\setinterfaceconstant{sort}{sort} +\setinterfaceconstant{sorttype}{sorttype} +\setinterfaceconstant{source}{quelle} +\setinterfaceconstant{space}{spatium} +\setinterfaceconstant{spaceafter}{nachspatium} +\setinterfaceconstant{spacebefore}{vorspatium} +\setinterfaceconstant{spaceinbetween}{spaceinbetween} +\setinterfaceconstant{spacing}{spatiumausgleich} +\setinterfaceconstant{split}{split} +\setinterfaceconstant{splitcolor}{splitcolor} +\setinterfaceconstant{splitmethod}{splitmethod} +\setinterfaceconstant{splitoffset}{splitoffset} +\setinterfaceconstant{spot}{spot} +\setinterfaceconstant{stack}{stack} +\setinterfaceconstant{start}{start} +\setinterfaceconstant{starter}{starter} +\setinterfaceconstant{state}{status} +\setinterfaceconstant{step}{schritt} +\setinterfaceconstant{stop}{stop} +\setinterfaceconstant{stopper}{abschnitttrenner} +\setinterfaceconstant{stretch}{strecken} +\setinterfaceconstant{strip}{strip} +\setinterfaceconstant{strut}{strut} +\setinterfaceconstant{style}{stil} +\setinterfaceconstant{sub}{unter} +\setinterfaceconstant{subtitle}{untertitel} +\setinterfaceconstant{suffix}{suffix} +\setinterfaceconstant{surnamesep}{surnamesep} +\setinterfaceconstant{sx}{sx} +\setinterfaceconstant{sy}{sy} +\setinterfaceconstant{symalign}{symausrichtung} +\setinterfaceconstant{symbol}{symbol} +\setinterfaceconstant{symbolset}{symbolset} +\setinterfaceconstant{symcolor}{symfarbe} +\setinterfaceconstant{symstyle}{symstil} +\setinterfaceconstant{synonym}{synonym} +\setinterfaceconstant{synonymcolor}{synonymfarbe} +\setinterfaceconstant{synonymcommand}{synonymbefehl} +\setinterfaceconstant{synonymstyle}{synonymstil} +\setinterfaceconstant{tab}{tab} +\setinterfaceconstant{text}{text} +\setinterfaceconstant{textcolor}{textfarbe} +\setinterfaceconstant{textcommand}{textbefehl} +\setinterfaceconstant{textdistance}{textdistance} +\setinterfaceconstant{textlayer}{textlayer} +\setinterfaceconstant{textmargin}{textmargin} +\setinterfaceconstant{textmethod}{textmethod} +\setinterfaceconstant{textseparator}{textseparator} +\setinterfaceconstant{textsize}{textgroesse} +\setinterfaceconstant{textstate}{textstatus} +\setinterfaceconstant{textstyle}{textstil} +\setinterfaceconstant{textwidth}{textbreite} +\setinterfaceconstant{title}{titel} +\setinterfaceconstant{titlecolor}{titelfarbe} +\setinterfaceconstant{titlecommand}{titlecommand} +\setinterfaceconstant{titledistance}{titelabstand} +\setinterfaceconstant{titleleft}{titleleft} +\setinterfaceconstant{titleright}{titleright} +\setinterfaceconstant{titlestyle}{titelstil} +\setinterfaceconstant{to}{zu} +\setinterfaceconstant{tolerance}{toleranz} +\setinterfaceconstant{top}{oben} +\setinterfaceconstant{topdistance}{obenabstand} +\setinterfaceconstant{topframe}{obenrahmen} +\setinterfaceconstant{topoffset}{obenoffset} +\setinterfaceconstant{topspace}{kopfspatium} +\setinterfaceconstant{topstate}{statusoben} +\setinterfaceconstant{totalnumber}{totalnumber} +\setinterfaceconstant{type}{typ} +\setinterfaceconstant{unit}{einheit} +\setinterfaceconstant{unknownreference}{unbekantereferenz} +\setinterfaceconstant{urlalternative}{urlalternative} +\setinterfaceconstant{urlspace}{urlspatium} +\setinterfaceconstant{validate}{validieren} +\setinterfaceconstant{vcommand}{vbefehl} +\setinterfaceconstant{veroffset}{kopfoffset} +\setinterfaceconstant{vfil}{vfil} +\setinterfaceconstant{voffset}{voffset} +\setinterfaceconstant{vonsep}{vonsep} +\setinterfaceconstant{way}{art} +\setinterfaceconstant{wfactor}{bfaktor} +\setinterfaceconstant{white}{weiss} +\setinterfaceconstant{width}{breite} +\setinterfaceconstant{xfactor}{xfaktor} +\setinterfaceconstant{xmax}{xmax} +\setinterfaceconstant{xoffset}{xoffset} +\setinterfaceconstant{xscale}{xformat} +\setinterfaceconstant{xstep}{xschritt} +\setinterfaceconstant{yfactor}{yfaktor} +\setinterfaceconstant{ymax}{ymax} +\setinterfaceconstant{yoffset}{yoffset} +\setinterfaceconstant{yscale}{yformat} +\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} +\setinterfaceelement{currentlocal}{aktuelllokal} +\setinterfaceelement{emptyone}{vuoto} +\setinterfaceelement{emptytwo}{leer} +\setinterfaceelement{end}{ende} +\setinterfaceelement{endsetup}{ein} +\setinterfaceelement{get}{get} +\setinterfaceelement{increment}{erhoehen} +\setinterfaceelement{list}{auflisten} +\setinterfaceelement{listof}{auflistenvon} +\setinterfaceelement{load}{laden} +\setinterfaceelement{local}{lokal} +\setinterfaceelement{makeup}{umbruch} +\setinterfaceelement{next}{folgende} +\setinterfaceelement{place}{platziere} +\setinterfaceelement{previous}{vorige} +\setinterfaceelement{previouslocal}{voriglokal} +\setinterfaceelement{reserve}{reservieren} +\setinterfaceelement{see}{sieh} +\setinterfaceelement{setup}{stelle} +\setinterfaceelement{start}{start} +\setinterfaceelement{stop}{stop} +\setinterfaceelement{text}{text} +\setinterfaceelement{type}{type} +% definitions for interface commands for language de +% +\setinterfacecommand{CAPPED}{KAP} +\setinterfacecommand{Character}{Buchstabe} +\setinterfacecommand{Characters}{Buchstaben} +\setinterfacecommand{LABELTEXT}{LABELTEXT} +\setinterfacecommand{MONTH}{MONAT} +\setinterfacecommand{Numbers}{Ziffern} +\setinterfacecommand{Romannumerals}{Roemischezahlen} +\setinterfacecommand{SmallCapped}{Kap} +\setinterfacecommand{SmallCaps}{Kaps} +\setinterfacecommand{WEEKDAY}{WOCHENTAG} +\setinterfacecommand{WORD}{WORT} +\setinterfacecommand{WORDS}{WOERTER} +\setinterfacecommand{Word}{Wort} +\setinterfacecommand{Words}{Woerter} +\setinterfacecommand{about}{ueber} +\setinterfacecommand{adaptlayout}{passelayoutan} +\setinterfacecommand{arg}{arg} +\setinterfacecommand{at}{bei} +\setinterfacecommand{atleftmargin}{atleftmargin} +\setinterfacecommand{atpage}{aufseite} +\setinterfacecommand{atrightmargin}{atrightmargin} +\setinterfacecommand{background}{hintergrund} +\setinterfacecommand{backspace}{rumpfweite} +\setinterfacecommand{blackrule}{rechteck} +\setinterfacecommand{blackrules}{rechtecke} +\setinterfacecommand{blank}{blanko} +\setinterfacecommand{bookmark}{bookmark} +\setinterfacecommand{bottomdistance}{abstandunten} +\setinterfacecommand{bottomheight}{hoeheunten} +\setinterfacecommand{bottomspace}{bottomspace} +\setinterfacecommand{but}{but} +\setinterfacecommand{button}{knopf} +\setinterfacecommand{bypassblocks}{bypassblocks} +\setinterfacecommand{character}{buchstabe} +\setinterfacecommand{characters}{buchstaben} +\setinterfacecommand{chem}{chem} +\setinterfacecommand{clip}{ausschnitt} +\setinterfacecommand{clonefield}{klonierefeld} +\setinterfacecommand{color}{farbe} +\setinterfacecommand{colorbar}{farbbalken} +\setinterfacecommand{colorvalue}{farbewert} +\setinterfacecommand{column}{spalte} +\setinterfacecommand{comment}{kommentar} +\setinterfacecommand{comparecolorgroup}{vergleichefarbengruppe} +\setinterfacecommand{comparepalet}{vergleichepalette} +\setinterfacecommand{completepagenumber}{completepagenumber} +\setinterfacecommand{completeregister}{completeregister} +\setinterfacecommand{component}{komponente} +\setinterfacecommand{convertnumber}{konvertierezahl} +\setinterfacecommand{copyfield}{kopierefeld} +\setinterfacecommand{correctwhitespace}{korrigierezwischenraum} +\setinterfacecommand{coupledocument}{verknuepfedokument} +\setinterfacecommand{couplemarking}{verknuepfebeschriftung} +\setinterfacecommand{couplepage}{doppelseite} +\setinterfacecommand{couplepaper}{doppelseitigespapier} +\setinterfacecommand{coupleregister}{verknuepfregister} +\setinterfacecommand{crlf}{crlf} +\setinterfacecommand{currentdate}{heutigesdatum} +\setinterfacecommand{currentheadnumber}{heutigeskopfnummer} +\setinterfacecommand{cutspace}{cutspace} +\setinterfacecommand{date}{datum} +\setinterfacecommand{decouplemarking}{entknuepfebeschriftung} +\setinterfacecommand{decrementnumber}{decrementnumber} +\setinterfacecommand{define}{definieren} +\setinterfacecommand{defineaccent}{definiereakzent} +\setinterfacecommand{defineblank}{definiereblanko} +\setinterfacecommand{defineblock}{definiereblock} +\setinterfacecommand{definebodyfont}{definierefliesstext} +\setinterfacecommand{definebodyfontenvironment}{definierefliesstextumgebung} +\setinterfacecommand{definebuffer}{definierepuffer} +\setinterfacecommand{definecharacter}{definierezeichen} +\setinterfacecommand{definecolor}{definierefarbe} +\setinterfacecommand{definecolorgroup}{definierefarbengruppe} +\setinterfacecommand{definecolumnbreak}{definecolumnbreak} +\setinterfacecommand{definecolumnset}{definecolumnset} +\setinterfacecommand{definecombination}{definecombination} +\setinterfacecommand{definecombinedlist}{definierezusammengestellteliste} +\setinterfacecommand{definecommand}{definierebefehl} +\setinterfacecommand{defineconversion}{definierekonversion} +\setinterfacecommand{definedescription}{definierebeschreibung} +\setinterfacecommand{defineenumeration}{definierenummerierung} +\setinterfacecommand{definefield}{definierefeld} +\setinterfacecommand{definefieldstack}{definierefeldstapel} +\setinterfacecommand{definefiguresymbol}{definiereabbsymbol} +\setinterfacecommand{definefloat}{definieregleitobjekt} +\setinterfacecommand{definefont}{definiereschrift} +\setinterfacecommand{definefontstyle}{definiereschriftstil} +\setinterfacecommand{definefontsynonym}{defineschriftsynonym} +\setinterfacecommand{defineframed}{definiereumrahmt} +\setinterfacecommand{defineframedtext}{definiereumrahmtertext} +\setinterfacecommand{definehbox}{definierehbox} +\setinterfacecommand{definehead}{definiereueberschrift} +\setinterfacecommand{defineindenting}{definiereeinzug} +\setinterfacecommand{defineinmargin}{defineinmargin} +\setinterfacecommand{defineinteractionmenu}{definiereinteraktionsmenue} +\setinterfacecommand{defineitemgroup}{defineitemgroup} +\setinterfacecommand{definelabel}{definierelabel} +\setinterfacecommand{definelayer}{definelayer} +\setinterfacecommand{definelayout}{definelayout} +\setinterfacecommand{definelist}{definiereliste} +\setinterfacecommand{definelogo}{definierelogo} +\setinterfacecommand{definemainfield}{definierehauptfeld} +\setinterfacecommand{definemakeup}{definiereumbruch} +\setinterfacecommand{definemarking}{definierebeschriftung} +\setinterfacecommand{definemathalignment}{definemathalignment} +\setinterfacecommand{defineoutput}{defineoutput} +\setinterfacecommand{defineoverlay}{definiereoverlay} +\setinterfacecommand{definepagebreak}{definepagebreak} +\setinterfacecommand{definepalet}{definierepalette} +\setinterfacecommand{definepapersize}{definierepapierformat} +\setinterfacecommand{defineparagraphs}{definiereabsaetze} +\setinterfacecommand{defineplacement}{defineplacement} +\setinterfacecommand{defineprofile}{definiereprofil} +\setinterfacecommand{defineprogram}{definiereprogramme} +\setinterfacecommand{definerawfont}{definerawfont} +\setinterfacecommand{definereference}{definierereferenz} +\setinterfacecommand{definereferenceformat}{definierereferenzformat} +\setinterfacecommand{definereferencelist}{definierereferenzliste} +\setinterfacecommand{defineregister}{definiereregister} +\setinterfacecommand{definerule}{definerule} +\setinterfacecommand{definesection}{definiereabschnitt} +\setinterfacecommand{definesectionblock}{definiereabschnittsblock} +\setinterfacecommand{definesorting}{definieresortieren} +\setinterfacecommand{definestartstop}{definierestartstop} +\setinterfacecommand{definestyle}{definierestil} +\setinterfacecommand{definesubfield}{definieresubfeld} +\setinterfacecommand{definesymbol}{definieresymbol} +\setinterfacecommand{definesynonyms}{definieresynonyme} +\setinterfacecommand{definetabletemplate}{definieretabellenvorlage} +\setinterfacecommand{definetabulate}{definieretabulator} +\setinterfacecommand{definetext}{definieretext} +\setinterfacecommand{definetextposition}{definetextposition} +\setinterfacecommand{definetextvariable}{definetextvariable} +\setinterfacecommand{definetype}{definetype} +\setinterfacecommand{definetyping}{definieretippen} +\setinterfacecommand{defineversion}{definiereversion} +\setinterfacecommand{determineheadnumber}{bestimmekopfnummer} +\setinterfacecommand{determinelistcharacteristics}{bestimmelistencharakeristika} +\setinterfacecommand{determineregistercharacteristics}{bestimmeregistercharakteristika} +\setinterfacecommand{dimension}{dimension} +\setinterfacecommand{disableinteractionmenu}{inaktiviereinteraktionsmenue} +\setinterfacecommand{domicile}{wohnort} +\setinterfacecommand{donttest}{keintest} +\setinterfacecommand{edgedistance}{randabstand} +\setinterfacecommand{edgewidth}{randbreite} +\setinterfacecommand{emptylines}{emptylines} +\setinterfacecommand{environment}{umgebung} +\setinterfacecommand{externalfigure}{externeabbildung} +\setinterfacecommand{fact}{geg} +\setinterfacecommand{field}{feld} +\setinterfacecommand{fieldstack}{feldstapel} +\setinterfacecommand{fillinfield}{ausfuellfeld} +\setinterfacecommand{fillinline}{gefuelltezeile} +\setinterfacecommand{fillinrules}{gefuelltesrechteck} +\setinterfacecommand{fillintext}{ausfuelltext} +\setinterfacecommand{fitfield}{passendfeld} +\setinterfacecommand{fixedspace}{festesspatium} +\setinterfacecommand{fixedspaces}{festesspatium} +\setinterfacecommand{followprofile}{folgeprofil} +\setinterfacecommand{followprofileversion}{folgeprofilversion} +\setinterfacecommand{followversion}{folgeversion} +\setinterfacecommand{footerdistance}{fusszeileabstand} +\setinterfacecommand{footerheight}{fusszeilenhoehe} +\setinterfacecommand{footnote}{fussnote} +\setinterfacecommand{footnotetext}{footnotetext} +\setinterfacecommand{forceblocks}{forceblocks} +\setinterfacecommand{formulanumber}{formelnummer} +\setinterfacecommand{fraction}{bruch} +\setinterfacecommand{framed}{umrahmt} +\setinterfacecommand{from}{von} +\setinterfacecommand{getbuffer}{holepuffer} +\setinterfacecommand{getmarking}{holebeschriftung} +\setinterfacecommand{getnumber}{getnumber} +\setinterfacecommand{godown}{nachunten} +\setinterfacecommand{goto}{zu} +\setinterfacecommand{gotobox}{zurbox} +\setinterfacecommand{gotopage}{zurseite} +\setinterfacecommand{graycolor}{graufarbe} +\setinterfacecommand{greyvalue}{grauwert} +\setinterfacecommand{grid}{gitter} +\setinterfacecommand{hairline}{haarlinie} +\setinterfacecommand{head}{kopf} +\setinterfacecommand{headerdistance}{kopfzeilenabstand} +\setinterfacecommand{headerheight}{kopfzeilenhoehe} +\setinterfacecommand{headlevel}{kopfniveau} +\setinterfacecommand{headnumber}{kopfnummer} +\setinterfacecommand{headsym}{headsym} +\setinterfacecommand{headtext}{ueberschrifttext} +\setinterfacecommand{hideblocks}{verbergebloecke} +\setinterfacecommand{high}{hoch} +\setinterfacecommand{hl}{hl} +\setinterfacecommand{immediatebetweenlist}{immediatebetweenlist} +\setinterfacecommand{immediatetolist}{immediatetolist} +\setinterfacecommand{in}{in} +\setinterfacecommand{incrementnumber}{nummererhoehen} +\setinterfacecommand{indenting}{einziehen} +\setinterfacecommand{inframed}{imumriss} +\setinterfacecommand{infull}{volleswort} +\setinterfacecommand{ininner}{ininner} +\setinterfacecommand{inleft}{imlinken} +\setinterfacecommand{inleftedge}{imlinkenrand} +\setinterfacecommand{inleftmargin}{inlinkermarginale} +\setinterfacecommand{inline}{inzeile} +\setinterfacecommand{inmargin}{inmarginalie} +\setinterfacecommand{inmframed}{immaumrise} +\setinterfacecommand{inneredgedistance}{inneredgedistance} +\setinterfacecommand{inneredgewidth}{inneredgewidth} +\setinterfacecommand{innermargindistance}{innermargindistance} +\setinterfacecommand{innermarginwidth}{innermarginwidth} +\setinterfacecommand{inothermargin}{inanderermarginale} +\setinterfacecommand{inouter}{inouter} +\setinterfacecommand{inright}{imrechten} +\setinterfacecommand{inrightedge}{imrechtenrand} +\setinterfacecommand{inrightmargin}{inrechtermarginale} +\setinterfacecommand{installlanguage}{installieresprache} +\setinterfacecommand{interactionbar}{interaktionsbalken} +\setinterfacecommand{interactionbuttons}{interaktionsknopfe} +\setinterfacecommand{interactionmenu}{interaktionsmenue} +\setinterfacecommand{item}{pos} +\setinterfacecommand{items}{posten} +\setinterfacecommand{its}{its} +\setinterfacecommand{keepblocks}{behaltebloecke} +\setinterfacecommand{label}{label} +\setinterfacecommand{labels}{labels} +\setinterfacecommand{labeltext}{labeltext} +\setinterfacecommand{language}{sprache} +\setinterfacecommand{leftaligned}{linksbuendig} +\setinterfacecommand{leftedgedistance}{abstandlinkerrand} +\setinterfacecommand{leftedgewidth}{breitelinkerrand} +\setinterfacecommand{leftmargindistance}{linkemarginalafstand} +\setinterfacecommand{leftmarginwidth}{linkemarginalbreite} +\setinterfacecommand{leg}{leg} +\setinterfacecommand{linewidth}{liniendicke} +\setinterfacecommand{listheight}{listenhoehe} +\setinterfacecommand{listlength}{listenlaenge} +\setinterfacecommand{listsymbol}{listsymbol} +\setinterfacecommand{listwidth}{listenbreite} +\setinterfacecommand{logfields}{registrierefelder} +\setinterfacecommand{lohi}{tiho} +\setinterfacecommand{low}{tief} +\setinterfacecommand{macroname}{name} +\setinterfacecommand{mainlanguage}{hauptsprache} +\setinterfacecommand{makeupheight}{satzhoehe} +\setinterfacecommand{makeupwidth}{satzbreite} +\setinterfacecommand{mar}{mar} +\setinterfacecommand{margindistance}{marginalafstand} +\setinterfacecommand{marginrule}{marginallinie} +\setinterfacecommand{margintext}{marginaltext} +\setinterfacecommand{margintitle}{marginaltitel} +\setinterfacecommand{marginwidth}{marginalbreite} +\setinterfacecommand{marginword}{marginalwort} +\setinterfacecommand{marking}{beschriftung} +\setinterfacecommand{markversion}{beschrifteversion} +\setinterfacecommand{mathematics}{mathematik} +\setinterfacecommand{menubutton}{menueknopf} +\setinterfacecommand{mframed}{maumrise} +\setinterfacecommand{midaligned}{zentriert} +\setinterfacecommand{mirror}{spiegeln} +\setinterfacecommand{month}{monat} +\setinterfacecommand{moveformula}{moveformula} +\setinterfacecommand{moveongrid}{amgitterneuausrichten} +\setinterfacecommand{movesidefloat}{movesidefloat} +\setinterfacecommand{navigating}{navigating} +\setinterfacecommand{nodimension}{keindimension} +\setinterfacecommand{noheaderandfooterlines}{keinekopfundfusszeilen} +\setinterfacecommand{noindenting}{nichteinziehen} +\setinterfacecommand{nolist}{keineliste} +\setinterfacecommand{nomarking}{keinebeschriftung} +\setinterfacecommand{nomoreblocks}{keinebloeckemehr} +\setinterfacecommand{nomorefiles}{keinedateienmehr} +\setinterfacecommand{nop}{nop} +\setinterfacecommand{nospace}{keinspatium} +\setinterfacecommand{note}{notiz} +\setinterfacecommand{notopandbottomlines}{keinzeilenobenundunten} +\setinterfacecommand{notsmallcapped}{nokap} +\setinterfacecommand{nowhitespace}{keinzwischenraum} +\setinterfacecommand{numberofsubpages}{numberofsubpages} +\setinterfacecommand{numbers}{ziffern} +\setinterfacecommand{outeredgedistance}{outeredgedistance} +\setinterfacecommand{outeredgewidth}{outeredgewidth} +\setinterfacecommand{outermargindistance}{outermargindistance} +\setinterfacecommand{outermarginwidth}{outermarginwidth} +\setinterfacecommand{packed}{kleinerdurchschuss} +\setinterfacecommand{page}{seite} +\setinterfacecommand{pagedepth}{pagedepth} +\setinterfacecommand{pagenumber}{seitenummer} +\setinterfacecommand{pageoffset}{pageoffset} +\setinterfacecommand{pagereference}{seitenreferenz} +\setinterfacecommand{pagetype}{seitentyp} +\setinterfacecommand{paperheight}{papierhoehe} +\setinterfacecommand{paperwidth}{papierbreite} +\setinterfacecommand{periods}{punkt} +\setinterfacecommand{plaatsruwelijst}{placerawlist} +\setinterfacecommand{placebookmarks}{platzierebookmarks} +\setinterfacecommand{placecombinedlist}{platzierezusammengestellteliste} +\setinterfacecommand{placefloat}{placefloat} +\setinterfacecommand{placefootnotes}{platzierefussnoten} +\setinterfacecommand{placeformula}{platziereformel} +\setinterfacecommand{placeheadnumber}{placeheadnumber} +\setinterfacecommand{placeheadtext}{placeheadtext} +\setinterfacecommand{placelegend}{platzierelegende} +\setinterfacecommand{placelist}{platziereliste} +\setinterfacecommand{placelocalfootnotes}{platzierelokalefussnoten} +\setinterfacecommand{placelogos}{platzierelogo} +\setinterfacecommand{placeongrid}{amgitterausrichten} +\setinterfacecommand{placeontopofeachother}{platziereuntereinander} +\setinterfacecommand{placepagenumber}{placepagenumber} +\setinterfacecommand{placereferencelist}{placereferencelist} +\setinterfacecommand{placeregister}{platziereregister} +\setinterfacecommand{placerule}{placerule} +\setinterfacecommand{placesidebyside}{platzierenebeneinander} +\setinterfacecommand{placesubformula}{platziereunterformel} +\setinterfacecommand{placetextvariable}{placetextvariable} +\setinterfacecommand{position}{position} +\setinterfacecommand{positiontext}{positiontext} +\setinterfacecommand{printpaperheight}{printpapierhoehe} +\setinterfacecommand{printpaperwidth}{printpapierbreite} +\setinterfacecommand{processblocks}{bearbeitebloecke} +\setinterfacecommand{processpage}{bearbeiteseite} +\setinterfacecommand{product}{produkt} +\setinterfacecommand{program}{programm} +\setinterfacecommand{project}{projekt} +\setinterfacecommand{publication}{publikation} +\setinterfacecommand{quotation}{zitat} +\setinterfacecommand{quote}{zitieren} +\setinterfacecommand{ran}{ran} +\setinterfacecommand{redo}{wiederholen} +\setinterfacecommand{ref}{ref} +\setinterfacecommand{reference}{referenz} +\setinterfacecommand{referral}{verweis} +\setinterfacecommand{referraldate}{verweisdatum} +\setinterfacecommand{referring}{referieren} +\setinterfacecommand{remark}{bemerkung} +\setinterfacecommand{reset}{ruecksetzten} +\setinterfacecommand{resetmarking}{ruecksetztenbeschriftung} +\setinterfacecommand{resetnumber}{resetnumber} +\setinterfacecommand{resettext}{resettextcontent} +\setinterfacecommand{rightaligned}{rechtsbuendig} +\setinterfacecommand{rightedgedistance}{abstandrechterrand} +\setinterfacecommand{rightedgewidth}{breiterechterrand} +\setinterfacecommand{rightmargindistance}{rechtemarginalafstand} +\setinterfacecommand{rightmarginwidth}{rechtemarginalbreite} +\setinterfacecommand{romannumerals}{roemischezahlen} +\setinterfacecommand{rotate}{drehen} +\setinterfacecommand{scale}{format} +\setinterfacecommand{screen}{bildschirm} +\setinterfacecommand{selectblocks}{waehlebloeckeaus} +\setinterfacecommand{selectpaper}{waehlepapieraus} +\setinterfacecommand{selectversion}{waehleversionaus} +\setinterfacecommand{setnumber}{setnumber} +\setinterfacecommand{settextcontent}{settext} +\setinterfacecommand{settextvariable}{settextvariable} +\setinterfacecommand{setupalign}{stelleausrichtungein} +\setinterfacecommand{setupanswerarea}{setupanswerarea} +\setinterfacecommand{setuparranging}{stelleanordnenein} +\setinterfacecommand{setupbackground}{stellehintergrundein} +\setinterfacecommand{setupbackgrounds}{stellehintergruendeein} +\setinterfacecommand{setupblackrules}{stellerechteckein} +\setinterfacecommand{setupblank}{stelleblankoein} +\setinterfacecommand{setupblock}{stelleblockein} +\setinterfacecommand{setupbodyfont}{stellefliesstextein} +\setinterfacecommand{setupbodyfontenvironment}{stellefliesstextumgebungein} +\setinterfacecommand{setupbottom}{stelleuntenein} +\setinterfacecommand{setupbottomtexts}{stelletextuntenein} +\setinterfacecommand{setupbuffer}{stellepufferein} +\setinterfacecommand{setupbuttons}{stelleknopfein} +\setinterfacecommand{setupcapitals}{stelleversalienein} +\setinterfacecommand{setupcaption}{stellebildunterschriftein} +\setinterfacecommand{setupcaptions}{stellebilderunterschriftein} +\setinterfacecommand{setupclipping}{stelleausschnittein} +\setinterfacecommand{setupcolor}{stellefarbeein} +\setinterfacecommand{setupcolors}{stellefarbenein} +\setinterfacecommand{setupcolumns}{stellespaltenein} +\setinterfacecommand{setupcolumnset}{setupcolumnset} +\setinterfacecommand{setupcolumnsetlines}{setupcolumnsetlines} +\setinterfacecommand{setupcolumnsetstart}{setupcolumnsetstart} +\setinterfacecommand{setupcombinations}{stellekombinationein} +\setinterfacecommand{setupcombinedlist}{stellezusammengestelltelisteein} +\setinterfacecommand{setupcomment}{stellekommentarein} +\setinterfacecommand{setupdescriptions}{definierebeschreibungen} +\setinterfacecommand{setupenumerations}{stellebeschreibungein} +\setinterfacecommand{setupexternalfigures}{stelleexterneabbildungenein} +\setinterfacecommand{setupfield}{stellefeldein} +\setinterfacecommand{setupfields}{stellefelderin} +\setinterfacecommand{setupfillinlines}{stellegefuelltezeileein} +\setinterfacecommand{setupfillinrules}{stellegefuelltesrechteckein} +\setinterfacecommand{setupfloat}{stellegleitobjektein} +\setinterfacecommand{setupfloats}{stellegleitobjekteein} +\setinterfacecommand{setupfloatsplitting}{stelleplatziegeteiltegleitobjekt} +\setinterfacecommand{setupfooter}{stellefusszeileein} +\setinterfacecommand{setupfootertexts}{stellefusszeilentextein} +\setinterfacecommand{setupfootnotedefinition}{stellefussnotendefinitionein} +\setinterfacecommand{setupfootnotes}{stellefussnotenein} +\setinterfacecommand{setupforms}{setupforms} +\setinterfacecommand{setupformulas}{stelleformelnein} +\setinterfacecommand{setupframed}{stelleumrahmtein} +\setinterfacecommand{setupframedtexts}{stelleumrahmtetexteein} +\setinterfacecommand{setuphead}{stelleueberschriftein} +\setinterfacecommand{setupheader}{stellekopfzeileein} +\setinterfacecommand{setupheadertexts}{stellekopfzeilentextein} +\setinterfacecommand{setupheadnumber}{stellekopfzahlein} +\setinterfacecommand{setupheads}{stelleueberschriftenein} +\setinterfacecommand{setupheadtext}{stelleueberschrifttextein} +\setinterfacecommand{setuphyphenmark}{stellebindestrichein} +\setinterfacecommand{setupindentations}{stelleeinzuegein} +\setinterfacecommand{setupindenting}{stelleeinziehenein} +\setinterfacecommand{setupinmargin}{stelleinmarginalieein} +\setinterfacecommand{setupinteraction}{stelleinteraktionein} +\setinterfacecommand{setupinteractionbar}{stelleinteraktionsbalkenein} +\setinterfacecommand{setupinteractionmenu}{stelleinteraktionsmenueein} +\setinterfacecommand{setupinteractionscreen}{stelleinteraktionsbildschirmein} +\setinterfacecommand{setupinterlinespace}{stellezeilenabstandein} +\setinterfacecommand{setupitemgroup}{setupitemgroup} +\setinterfacecommand{setupitemgroups}{stelleaufzaehlungenein} +\setinterfacecommand{setupitems}{stellepostenein} +\setinterfacecommand{setuplabeltext}{stellelabeltextein} +\setinterfacecommand{setuplanguage}{stellespracheein} +\setinterfacecommand{setuplayout}{stellelayoutein} +\setinterfacecommand{setuplegend}{stellelegendeein} +\setinterfacecommand{setuplinenumbering}{stellezeilennumerierungein} +\setinterfacecommand{setuplines}{stellezeilenein} +\setinterfacecommand{setuplinewidth}{stellelinienbreiteein} +\setinterfacecommand{setuplist}{stellelisteein} +\setinterfacecommand{setupmakeup}{stelleumbruchein} +\setinterfacecommand{setupmarginblocks}{stellemarginalblockein} +\setinterfacecommand{setupmarginrules}{stellemarginallinieein} +\setinterfacecommand{setupmarking}{stellebeschriftungein} +\setinterfacecommand{setupmathalignment}{setupmathalignment} +\setinterfacecommand{setupnarrower}{stelleengerein} +\setinterfacecommand{setupnumber}{setupnumber} +\setinterfacecommand{setupnumbering}{stellenummerierungein} +\setinterfacecommand{setupoppositeplacing}{stellegegenueberplatzierenein} +\setinterfacecommand{setupoutput}{stelleausgabeein} +\setinterfacecommand{setuppagecomment}{stelleseitenkommentarein} +\setinterfacecommand{setuppagenumber}{stelleseitennummerein} +\setinterfacecommand{setuppagenumbering}{stelleseitennummeriernungein} +\setinterfacecommand{setuppagetransitions}{stelleseitenuebergangein} +\setinterfacecommand{setuppalet}{stellepaletteein} +\setinterfacecommand{setuppaper}{setuppaper} +\setinterfacecommand{setuppapersize}{stellepapierformatein} +\setinterfacecommand{setupparagraphnumbering}{stelleabsatznummerierungein} +\setinterfacecommand{setupparagraphs}{stelleabsaetzeein} +\setinterfacecommand{setupplacement}{setupplacement} +\setinterfacecommand{setuppositioning}{stellepositionierenein} +\setinterfacecommand{setupprofiles}{stelleprofilein} +\setinterfacecommand{setupprograms}{stelleprogrammein} +\setinterfacecommand{setuppublications}{stellepublikationein} +\setinterfacecommand{setupquote}{stellezitierenein} +\setinterfacecommand{setupreferencelist}{stellereferenzlisteein} +\setinterfacecommand{setupreferencing}{stellereferenzierenein} +\setinterfacecommand{setupregister}{stelleregisterein} +\setinterfacecommand{setuprotate}{stelledrehenein} +\setinterfacecommand{setuprule}{setuprule} +\setinterfacecommand{setups}{einstellungen} +\setinterfacecommand{setupscreens}{stellerasterein} +\setinterfacecommand{setupsection}{stelleabschnittein} +\setinterfacecommand{setupsectionblock}{stelleabschnittsblockein} +\setinterfacecommand{setupsorting}{stellesortierenein} +\setinterfacecommand{setupspacing}{stellespatiumein} +\setinterfacecommand{setupstartstop}{setupstartstop} +\setinterfacecommand{setupstrut}{setupstrut} +\setinterfacecommand{setupsubpagenumber}{stelleunterseitennummerein} +\setinterfacecommand{setupsymbolset}{stellesymbolsetein} +\setinterfacecommand{setupsynchronization}{stellesynchronisationein} +\setinterfacecommand{setupsynchronizationbar}{stellesynchronisationsbalkenein} +\setinterfacecommand{setupsynonyms}{stellesynonymein} +\setinterfacecommand{setupsystem}{stellesystemein} +\setinterfacecommand{setuptab}{stelletabein} +\setinterfacecommand{setuptables}{stelletabellenein} +\setinterfacecommand{setuptabulate}{stelletabulatorein} +\setinterfacecommand{setuptext}{stelletextein} +\setinterfacecommand{setuptextposition}{setuptextposition} +\setinterfacecommand{setuptextrules}{stelletextumrissein} +\setinterfacecommand{setuptexttexts}{stelletexttexteein} +\setinterfacecommand{setuptextvariable}{setuptextvariable} +\setinterfacecommand{setupthinrules}{stelleduennerumrissein} +\setinterfacecommand{setuptolerance}{stelletoleranzein} +\setinterfacecommand{setuptop}{stellenobenein} +\setinterfacecommand{setuptoptexts}{stelletextobenein} +\setinterfacecommand{setuptype}{stelletipein} +\setinterfacecommand{setuptyping}{stelletippenein} +\setinterfacecommand{setupunderbar}{stelleunterstreichenein} +\setinterfacecommand{setupurl}{stelleurlein} +\setinterfacecommand{setupversions}{stelleversionein} +\setinterfacecommand{setupwhitespace}{stellezwischenraumein} +\setinterfacecommand{showbodyfont}{zeigefliesstext} +\setinterfacecommand{showbodyfontenvironment}{zeigefliesstextumgebung} +\setinterfacecommand{showcolor}{zeigefarbe} +\setinterfacecommand{showcolorgroup}{zeigefarbengruppe} +\setinterfacecommand{showexternalfigures}{zeigeexterneabbildungen} +\setinterfacecommand{showfields}{zeigefelder} +\setinterfacecommand{showframe}{zeigerahmen} +\setinterfacecommand{showgrid}{zeigegitter} +\setinterfacecommand{showlayout}{zeigelayout} +\setinterfacecommand{showmakeup}{zeigeumbruch} +\setinterfacecommand{showpalet}{zeigepalette} +\setinterfacecommand{showprint}{zeigedruck} +\setinterfacecommand{showsetups}{zeigeeinstellungen} +\setinterfacecommand{showstruts}{zeigestruts} +\setinterfacecommand{showsymbolset}{showsymbolset} +\setinterfacecommand{smallcapped}{kap} +\setinterfacecommand{someline}{einezeile} +\setinterfacecommand{somewhere}{irgendwo} +\setinterfacecommand{space}{spatium} +\setinterfacecommand{splitfloat}{teilegleitobjekt} +\setinterfacecommand{startalignment}{startausrichtung} +\setinterfacecommand{startbackground}{starthintergrund} +\setinterfacecommand{startcoding}{startkodierung} +\setinterfacecommand{startcolor}{startfarbe} +\setinterfacecommand{startcolumnmakeup}{startcolumnmakeup} +\setinterfacecommand{startcolumns}{startspalten} +\setinterfacecommand{startcolumnset}{startcolumnset} +\setinterfacecommand{startcombination}{startkombination} +\setinterfacecommand{startcomponent}{startkomponente} +\setinterfacecommand{startdocument}{startdokument} +\setinterfacecommand{startenvironment}{startumgebung} +\setinterfacecommand{startfigure}{startabbildung} +\setinterfacecommand{startglobal}{startglobal} +\setinterfacecommand{startline}{startzeile} +\setinterfacecommand{startlinecorrection}{startzeilenkorrektur} +\setinterfacecommand{startlinenumbering}{startzeilennumerierung} +\setinterfacecommand{startlines}{startzeilen} +\setinterfacecommand{startlocal}{startlokal} +\setinterfacecommand{startlocalfootnotes}{startlokalefussnoten} +\setinterfacecommand{startmakeup}{startumbruch} +\setinterfacecommand{startmarginblock}{startmarginalblock} +\setinterfacecommand{startmarginrule}{startmarginallinie} +\setinterfacecommand{startnarrower}{startenger} +\setinterfacecommand{startopposite}{startgegenueber} +\setinterfacecommand{startoverlay}{startoverlay} +\setinterfacecommand{startoverzicht}{startueberblick} +\setinterfacecommand{startpacked}{startkleinerdurchschuss} +\setinterfacecommand{startpositioning}{startpositionieren} +\setinterfacecommand{startproduct}{startprodukt} +\setinterfacecommand{startprofile}{startprofil} +\setinterfacecommand{startproject}{startprojekt} +\setinterfacecommand{startquotation}{startzitat} +\setinterfacecommand{startraster}{startraster} +\setinterfacecommand{startsymbolset}{startsymbolset} +\setinterfacecommand{startsynchronization}{startsynchronisation} +\setinterfacecommand{starttable}{starttabelle} +\setinterfacecommand{starttables}{starttabellen} +\setinterfacecommand{starttext}{starttext} +\setinterfacecommand{starttextrule}{starttextlinie} +\setinterfacecommand{startunpacked}{startgrosserdurchschuss} +\setinterfacecommand{startversion}{startversion} +\setinterfacecommand{stopalignment}{stopausrichtung} +\setinterfacecommand{stopbackground}{stophintergrund} +\setinterfacecommand{stopcoding}{stopkodierung} +\setinterfacecommand{stopcolor}{stopfarbe} +\setinterfacecommand{stopcolumnmakeup}{stopcolumnmakeup} +\setinterfacecommand{stopcolumns}{stopspalten} +\setinterfacecommand{stopcolumnset}{stopcolumnset} +\setinterfacecommand{stopcombination}{stopkombination} +\setinterfacecommand{stopcomponent}{stopkomponente} +\setinterfacecommand{stopdocument}{stopdokument} +\setinterfacecommand{stopenvironment}{stopumgebung} +\setinterfacecommand{stopglobal}{stopglobal} +\setinterfacecommand{stopline}{stopzeile} +\setinterfacecommand{stoplinecorrection}{stopzeilenkorrektur} +\setinterfacecommand{stoplinenumbering}{stopzeilennumerierung} +\setinterfacecommand{stoplines}{stopzeilen} +\setinterfacecommand{stoplocal}{stoplokal} +\setinterfacecommand{stoplocalfootnotes}{stoplokalefussnoten} +\setinterfacecommand{stopmakeup}{stopumbruch} +\setinterfacecommand{stopmarginblock}{stopmarginalblock} +\setinterfacecommand{stopmarginrule}{stopmarginallinie} +\setinterfacecommand{stopnarrower}{stopenger} +\setinterfacecommand{stopopposite}{stopgegenueber} +\setinterfacecommand{stopoverlay}{stopoverlay} +\setinterfacecommand{stopoverzicht}{stopueberblick} +\setinterfacecommand{stoppacked}{stopkleinerdurchschuss} +\setinterfacecommand{stoppositioning}{stoppositionieren} +\setinterfacecommand{stopproduct}{stopprodukt} +\setinterfacecommand{stopprofile}{stopprofil} +\setinterfacecommand{stopproject}{stopprojekt} +\setinterfacecommand{stopquotation}{stopzitat} +\setinterfacecommand{stopraster}{stopraster} +\setinterfacecommand{stopsynchronization}{stopsynchronisation} +\setinterfacecommand{stoptable}{stoptabelle} +\setinterfacecommand{stoptables}{stoptabellen} +\setinterfacecommand{stoptext}{stoptext} +\setinterfacecommand{stoptextrule}{stoptextlinie} +\setinterfacecommand{stopunpacked}{stopgrosserdurchschuss} +\setinterfacecommand{stopversion}{stopversion} +\setinterfacecommand{stretched}{gestreckt} +\setinterfacecommand{subformulanumber}{unterformelnummer} +\setinterfacecommand{subpagenumber}{subpagenumber} +\setinterfacecommand{switchtobodyfont}{wechselezumfliesstext} +\setinterfacecommand{switchtorawfont}{switchtorawfont} +\setinterfacecommand{sym}{sym} +\setinterfacecommand{symbol}{symbol} +\setinterfacecommand{synchronizationbar}{synchronisationsbalken} +\setinterfacecommand{synchronize}{synchronisieren} +\setinterfacecommand{tab}{tab} +\setinterfacecommand{testcolumn}{testcolumn} +\setinterfacecommand{testpage}{testpage} +\setinterfacecommand{tex}{tex} +\setinterfacecommand{textheight}{texthoehe} +\setinterfacecommand{textreference}{textreferenz} +\setinterfacecommand{textrule}{textlinie} +\setinterfacecommand{textvariable}{textvariable} +\setinterfacecommand{textwidth}{textbreite} +\setinterfacecommand{thinrule}{duennelinie} +\setinterfacecommand{thinrules}{duennerumriss} +\setinterfacecommand{tooltip}{tooltip} +\setinterfacecommand{topdistance}{abstandoben} +\setinterfacecommand{topheight}{hoeheoben} +\setinterfacecommand{topspace}{kopfweite} +\setinterfacecommand{totalnumberofpages}{gesamtseitenanzahl} +\setinterfacecommand{translate}{uebersetzten} +\setinterfacecommand{txt}{txt} +\setinterfacecommand{typ}{tip} +\setinterfacecommand{type}{tippen} +\setinterfacecommand{typebuffer}{tippepuffer} +\setinterfacecommand{typefile}{tippedatei} +\setinterfacecommand{unitmeaning}{bedeutung} +\setinterfacecommand{unknown}{unbekant} +\setinterfacecommand{useJSscripts}{verwendeJSscript} +\setinterfacecommand{useURL}{verwendeURL} +\setinterfacecommand{useXMLfilter}{useXMLfilter} +\setinterfacecommand{useblocks}{verwendebloecke} +\setinterfacecommand{usecommands}{verwendebefehl} +\setinterfacecommand{useencoding}{benutzekodierung} +\setinterfacecommand{useexternaldocument}{verwendeexteresdokument} +\setinterfacecommand{useexternalfigure}{verwendeexterneabbildung} +\setinterfacecommand{useexternalfile}{verwendeexternedatei} +\setinterfacecommand{useexternalfiles}{verwendeexternedateien} +\setinterfacecommand{useexternalsoundtrack}{verwendeexternestonstueck} +\setinterfacecommand{usemodule}{verwendemodul} +\setinterfacecommand{usemodules}{verwendemodule} +\setinterfacecommand{usepath}{benutzeverzeichnis} +\setinterfacecommand{usereferences}{verwendereferenzen} +\setinterfacecommand{usespecials}{benutzespezielles} +\setinterfacecommand{usesymbols}{verwendesymbole} +\setinterfacecommand{usetypescript}{usetypescript} +\setinterfacecommand{usetypescriptfile}{usetypescriptfile} +\setinterfacecommand{useurl}{verwendeurl} +\setinterfacecommand{version}{version} +\setinterfacecommand{vl}{vl} +\setinterfacecommand{weekday}{wochentag} +\setinterfacecommand{whitespace}{zwischenraum} +\setinterfacecommand{wordright}{wortrechts} +\setinterfacecommand{writebetweenlist}{schreibezwischenliste} +\setinterfacecommand{writetolist}{schreibezurliste} +\setinterfacecommand{writetoreferencelist}{schreibezurreferenzliste} +\setinterfacecommand{writetoregister}{schreibezumregister} +% +\endinput \ No newline at end of file diff --git a/tex/context/base/mult-def.lua b/tex/context/base/mult-def.lua new file mode 100644 index 000000000..ce5af2bba --- /dev/null +++ b/tex/context/base/mult-def.lua @@ -0,0 +1,16149 @@ +if not modules then modules = { } end modules ['mult-def'] = { + version = 1.001, + comment = "companion to mult-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +return { + ["commands"]={ + ["CAPPED"]={ + ["cs"]="KAP", + ["de"]="KAP", + ["en"]="CAP", + ["fr"]="CAP", + ["it"]="CAP", + ["nl"]="KAP", + ["pe"]="CAP", + ["ro"]="KAP", + }, + ["Character"]={ + ["cs"]="Znak", + ["de"]="Buchstabe", + ["en"]="Character", + ["fr"]="Caractere", + ["it"]="Lettera", + ["nl"]="Letter", + ["pe"]="Character", + ["ro"]="Litera", + }, + ["Characters"]={ + ["cs"]="Znaky", + ["de"]="Buchstaben", + ["en"]="Characters", + ["fr"]="Caracteres", + ["it"]="Lettere", + ["nl"]="Letters", + ["pe"]="Characters", + ["ro"]="Litere", + }, + ["LABELTEXT"]={ + ["cs"]="TEXTPOPISKU", + ["de"]="LABELTEXT", + ["en"]="LABELTEXT", + ["fr"]="LABELTEXTE", + ["it"]="TESTOETICHETTA", + ["nl"]="LABELTEKST", + ["pe"]="LABELTEXT", + ["ro"]="TEXTETICHETA", + }, + ["MONTH"]={ + ["cs"]="MESIC", + ["de"]="MONAT", + ["en"]="MONTH", + ["fr"]="MOIS", + ["it"]="MESE", + ["nl"]="MAAND", + ["pe"]="MONTH", + ["ro"]="LUNA", + }, + ["Numbers"]={ + ["cs"]="Cisla", + ["de"]="Ziffern", + ["en"]="Numbers", + ["fr"]="Numeros", + ["it"]="Numeri", + ["nl"]="Cijfers", + ["pe"]="Numbers", + ["ro"]="Numere", + }, + ["Romannumerals"]={ + ["cs"]="Rimskecislice", + ["de"]="Roemischezahlen", + ["en"]="Romannumerals", + ["fr"]="Chiffresromains", + ["it"]="Numeriromani", + ["nl"]="Romeins", + ["pe"]="Romannumerals", + ["ro"]="Numereromane", + }, + ["SmallCapped"]={ + ["cs"]="Kap", + ["de"]="Kap", + ["en"]="Cap", + ["fr"]="Cap", + ["it"]="Cap", + ["nl"]="Kap", + ["pe"]="Cap", + ["ro"]="Kap", + }, + ["SmallCaps"]={ + ["cs"]="Kaps", + ["de"]="Kaps", + ["en"]="Caps", + ["fr"]="Caps", + ["it"]="Caps", + ["nl"]="Kaps", + ["pe"]="Caps", + ["ro"]="Kaps", + }, + ["WEEKDAY"]={ + ["cs"]="VSEDNIDEN", + ["de"]="WOCHENTAG", + ["en"]="WEEKDAY", + ["fr"]="JOURSEMAINE", + ["it"]="GIORNOSETTIMANA", + ["nl"]="WEEKDAG", + ["pe"]="WEEKDAY", + ["ro"]="ZIDINSAPTAMANA", + }, + ["WORD"]={ + ["cs"]="SLOVO", + ["de"]="WORT", + ["en"]="WORD", + ["fr"]="MOT", + ["it"]="PAROLA", + ["nl"]="WOORD", + ["pe"]="WORD", + ["ro"]="CUVANT", + }, + ["WORDS"]={ + ["cs"]="SLOVA", + ["de"]="WOERTER", + ["en"]="WORDS", + ["fr"]="MOTS", + ["it"]="PAROLE", + ["nl"]="WOORDEN", + ["pe"]="WORDS", + ["ro"]="CUVINTE", + }, + ["Word"]={ + ["cs"]="Slovo", + ["de"]="Wort", + ["en"]="Word", + ["fr"]="Mot", + ["it"]="Parola", + ["nl"]="Woord", + ["pe"]="Word", + ["ro"]="Cuvant", + }, + ["Words"]={ + ["cs"]="Slova", + ["de"]="Woerter", + ["en"]="Words", + ["fr"]="Mots", + ["it"]="Parole", + ["nl"]="Woorden", + ["pe"]="Words", + ["ro"]="Cuvinte", + }, + ["about"]={ + ["cs"]="oref", + ["de"]="ueber", + ["en"]="about", + ["fr"]="concernant", + ["it"]="intorno", + ["nl"]="about", + ["pe"]="درمورد", + ["ro"]="despre", + }, + ["adaptlayout"]={ + ["cs"]="prizpusobvzhled", + ["de"]="passelayoutan", + ["en"]="adaptlayout", + ["fr"]="adaptedisposition", + ["it"]="adattalayout", + ["nl"]="paslayoutaan", + ["pe"]="تنظیم‌طرح‌بندی", + ["ro"]="adapteazaaspect", + }, + ["adding"]={}, + ["arg"]={ + ["cs"]="arg", + ["de"]="arg", + ["en"]="arg", + ["fr"]="arg", + ["it"]="arg", + ["nl"]="arg", + ["pe"]="افزودن", + ["ro"]="arg", + }, + ["at"]={ + ["cs"]="pref", + ["de"]="bei", + ["en"]="at", + ["fr"]="a", + ["it"]="al", + ["nl"]="op", + ["pe"]="در", + ["ro"]="la", + }, + ["atleftmargin"]={ + ["cs"]="atleftmargin", + ["de"]="atleftmargin", + ["en"]="atleftmargin", + ["fr"]="atleftmargin", + ["it"]="atleftmargin", + ["nl"]="oplinkermarge", + ["pe"]="درحاشیه‌چپ", + ["ro"]="atleftmargin", + }, + ["atpage"]={ + ["cs"]="nastrane", + ["de"]="aufseite", + ["en"]="atpage", + ["fr"]="alapage", + ["it"]="apagina", + ["nl"]="oppagina", + ["pe"]="درصفحه", + ["ro"]="lapagina", + }, + ["atrightmargin"]={ + ["cs"]="atrightmargin", + ["de"]="atrightmargin", + ["en"]="atrightmargin", + ["fr"]="atrightmargin", + ["it"]="atrightmargin", + ["nl"]="oprechtermarge", + ["pe"]="درحاشیه‌راست", + ["ro"]="atrightmargin", + }, + ["background"]={ + ["cs"]="pozadi", + ["de"]="hintergrund", + ["en"]="background", + ["fr"]="arriereplan", + ["it"]="sfondo", + ["nl"]="achtergrond", + ["pe"]="پس‌زمینه", + ["ro"]="fundal", + }, + ["backspace"]={ + ["cs"]="odsazenizleva", + ["de"]="rumpfweite", + ["en"]="backspace", + ["fr"]="retourarriere", + ["it"]="spaziodietro", + ["nl"]="rugwit", + ["pe"]="فاصله‌پشت", + ["ro"]="spatiuspate", + }, + ["blackrule"]={ + ["cs"]="cernalinka", + ["de"]="rechteck", + ["en"]="blackrule", + ["fr"]="lignenoire", + ["it"]="lineanera", + ["nl"]="blokje", + ["pe"]="خط‌سیاه", + ["ro"]="linieneagra", + }, + ["blackrules"]={ + ["cs"]="cernelinky", + ["de"]="rechtecke", + ["en"]="blackrules", + ["fr"]="lignesnoires", + ["it"]="lineenere", + ["nl"]="blokjes", + ["pe"]="خطهای‌سیاه", + ["ro"]="liniinegre", + }, + ["blank"]={ + ["cs"]="preskoc", + ["de"]="blanko", + ["en"]="blank", + ["fr"]="vide", + ["it"]="rigovuoto", + ["nl"]="blanko", + ["pe"]="خالی", + ["ro"]="blanc", + }, + ["bookmark"]={ + ["cs"]="zalozka", + ["de"]="bookmark", + ["en"]="bookmark", + ["fr"]="marquepage", + ["it"]="segnalibro", + ["nl"]="bookmark", + ["pe"]="چوبخط", + ["ro"]="semncarte", + }, + ["bottomdistance"]={ + ["cs"]="vzdalenostspodku", + ["de"]="abstandunten", + ["en"]="bottomdistance", + ["fr"]="distanceinf", + ["it"]="distanzafondo", + ["nl"]="onderafstand", + ["pe"]="فاصله‌پایین", + ["ro"]="distantajos", + }, + ["bottomheight"]={ + ["cs"]="vyskaspodku", + ["de"]="hoeheunten", + ["en"]="bottomheight", + ["fr"]="hauteurinf", + ["it"]="altezzafondo", + ["nl"]="onderhoogte", + ["pe"]="ارتفاع‌پایین", + ["ro"]="inaltimejos", + }, + ["bottomspace"]={ + ["cs"]="bottomspace", + ["de"]="bottomspace", + ["en"]="bottomspace", + ["fr"]="espaceinf", + ["it"]="spaziofondo", + ["nl"]="bodemwit", + ["pe"]="فضای‌پایین", + ["ro"]="spatiujos", + }, + ["but"]={ + ["cs"]="spodek", + ["de"]="but", + ["en"]="but", + ["fr"]="but", + ["it"]="fondo", + ["nl"]="but", + ["pe"]="اما", + ["ro"]="but", + }, + ["button"]={ + ["cs"]="tlacitko", + ["de"]="knopf", + ["en"]="button", + ["fr"]="bouton", + ["it"]="pulsante", + ["nl"]="button", + ["pe"]="دکمه", + ["ro"]="buton", + }, + ["bypassblocks"]={ + ["cs"]="bypassblocks", + ["de"]="bypassblocks", + ["en"]="bypassblocks", + ["fr"]="sauteblocs", + ["it"]="saltablocchi", + ["nl"]="passeerblokken", + ["pe"]="عبوربلوکها", + ["ro"]="saripesteblocuri", + }, + ["character"]={ + ["cs"]="znak", + ["de"]="buchstabe", + ["en"]="character", + ["fr"]="caractere", + ["it"]="lettera", + ["nl"]="letter", + ["pe"]="حرف", + ["ro"]="litera", + }, + ["characters"]={ + ["cs"]="znaky", + ["de"]="buchstaben", + ["en"]="characters", + ["fr"]="caracteres", + ["it"]="lettere", + ["nl"]="letters", + ["pe"]="حرفها", + ["ro"]="litere", + }, + ["chem"]={ + ["cs"]="chem", + ["de"]="chem", + ["en"]="chem", + ["fr"]="chem", + ["it"]="chim", + ["nl"]="chem", + ["pe"]="chem", + ["ro"]="chem", + }, + ["clip"]={ + ["cs"]="orez", + ["de"]="ausschnitt", + ["en"]="clip", + ["fr"]="clip", + ["it"]="clip", + ["nl"]="clip", + ["pe"]="گیره", + ["ro"]="clip", + }, + ["clonefield"]={ + ["cs"]="klonujpole", + ["de"]="klonierefeld", + ["en"]="clonefield", + ["fr"]="clonechamp", + ["it"]="clonacampo", + ["nl"]="kloonveld", + ["pe"]="میدان‌شبیه‌سازی", + ["ro"]="cloneazacamp", + }, + ["color"]={ + ["cs"]="barva", + ["de"]="farbe", + ["en"]="color", + ["fr"]="couleur", + ["it"]="colore", + ["nl"]="kleur", + ["pe"]="رنگ", + ["ro"]="culoare", + }, + ["colorbar"]={ + ["cs"]="barevnalista", + ["de"]="farbbalken", + ["en"]="colorbar", + ["fr"]="barrecouleur", + ["it"]="barracolori", + ["nl"]="kleurenbalk", + ["pe"]="میله‌رنگ", + ["ro"]="baraculoare", + }, + ["colorvalue"]={ + ["cs"]="hodnotabarvy", + ["de"]="farbewert", + ["en"]="colorvalue", + ["fr"]="valeurcouleur", + ["it"]="valorecolore", + ["nl"]="kleurwaarde", + ["pe"]="مقداررنگ", + ["ro"]="valoareculoare", + }, + ["column"]={ + ["cs"]="sloupec", + ["de"]="spalte", + ["en"]="column", + ["fr"]="colonne", + ["it"]="colonna", + ["nl"]="kolom", + ["pe"]="ستون", + ["ro"]="coloana", + }, + ["comment"]={ + ["cs"]="komentar", + ["de"]="kommentar", + ["en"]="comment", + ["fr"]="commentaire", + ["it"]="commento", + ["nl"]="commentaar", + ["pe"]="توضیح", + ["ro"]="comentariu", + }, + ["comparecolorgroup"]={ + ["cs"]="porovnejskupinubarev", + ["de"]="vergleichefarbengruppe", + ["en"]="comparecolorgroup", + ["fr"]="comparegroupecouleur", + ["it"]="confrontagruppocolori", + ["nl"]="vergelijkkleurgroep", + ["pe"]="مقایسه‌گروه‌رنگ", + ["ro"]="comparagrupculoare", + }, + ["comparepalet"]={ + ["cs"]="porovnejpaletu", + ["de"]="vergleichepalette", + ["en"]="comparepalet", + ["fr"]="comparepalette", + ["it"]="confrontatavolozza", + ["nl"]="vergelijkpalet", + ["pe"]="لوح‌مقایسه", + ["ro"]="comparapaleta", + }, + ["completepagenumber"]={ + ["cs"]="completepagenumber", + ["de"]="completepagenumber", + ["en"]="completepagenumber", + ["fr"]="completenumeropage", + ["it"]="numeropaginacompleto", + ["nl"]="volledigepaginanummer", + ["pe"]="شماره‌صفحه‌کامل", + ["ro"]="completeazanumarpagina", + }, + ["completeregister"]={ + ["cs"]="completeregister", + ["de"]="completeregister", + ["en"]="completeregister", + ["fr"]="completeregistre", + ["it"]="completeregister", + ["nl"]="volledigregister", + ["pe"]="ثبت‌کامل", + ["ro"]="completeregister", + }, + ["component"]={ + ["cs"]="komponenta", + ["de"]="komponente", + ["en"]="component", + ["fr"]="composant", + ["it"]="componenet", + ["nl"]="onderdeel", + ["pe"]="مولفه", + ["ro"]="componenta", + }, + ["convertnumber"]={ + ["cs"]="konvertujcislo", + ["de"]="konvertierezahl", + ["en"]="convertnumber", + ["fr"]="convertitnumero", + ["it"]="convertinumero", + ["nl"]="converteernummer", + ["pe"]="شماره‌مبدل", + ["ro"]="convertestenumar", + }, + ["copyfield"]={ + ["cs"]="kopirujpole", + ["de"]="kopierefeld", + ["en"]="copyfield", + ["fr"]="copitchamp", + ["it"]="copiacampo", + ["nl"]="copieerveld", + ["pe"]="میدان‌کپی", + ["ro"]="copiazacamp", + }, + ["correctwhitespace"]={ + ["cs"]="korekcebilehomista", + ["de"]="korrigierezwischenraum", + ["en"]="correctwhitespace", + ["fr"]="corrigeespaceblanc", + ["it"]="correggispaziobianco", + ["nl"]="corrigeerwitruimte", + ["pe"]="فضای‌سفیدصحیح", + ["ro"]="corecteazaspatiualb", + }, + ["coupledocument"]={ + ["cs"]="propojenydokument", + ["de"]="verknuepfedokument", + ["en"]="coupledocument", + ["fr"]="coupledocument", + ["it"]="accoppiadocumento", + ["nl"]="koppeldocument", + ["pe"]="نوشتارزوج", + ["ro"]="cupleazadocument", + }, + ["couplemarking"]={ + ["cs"]="propojeneznaceni", + ["de"]="verknuepfebeschriftung", + ["en"]="couplemarking", + ["fr"]="couplemarquage", + ["it"]="accoppiamarcatura", + ["nl"]="koppelmarkering", + ["pe"]="نشانه‌گذاری‌زوج", + ["ro"]="cupleazamarcaje", + }, + ["couplepage"]={ + ["cs"]="parovastrana", + ["de"]="doppelseite", + ["en"]="couplepage", + ["fr"]="pagedouble", + ["it"]="accoppiapagina", + ["nl"]="koppelpagina", + ["pe"]="صفحه‌زوج", + ["ro"]="paginadubla", + }, + ["couplepaper"]={ + ["cs"]="dvoustrannypapir", + ["de"]="doppelseitigespapier", + ["en"]="couplepaper", + ["fr"]="couplepapier", + ["it"]="accoppiacarta", + ["nl"]="koppelpapier", + ["pe"]="کاغذزوج", + ["ro"]="hartiedubla", + }, + ["coupleregister"]={ + ["cs"]="propojenyrejstrik", + ["de"]="verknuepfregister", + ["en"]="coupleregister", + ["fr"]="coupleregistre", + ["it"]="accoppiaregistro", + ["nl"]="koppelregister", + ["pe"]="ثبت‌زوج", + ["ro"]="cupleazaregistru", + }, + ["crlf"]={ + ["cs"]="crlf", + ["de"]="crlf", + ["en"]="crlf", + ["fr"]="crlf", + ["it"]="crlf", + ["nl"]="crlf", + ["pe"]="crlf", + ["ro"]="crlf", + }, + ["currentdate"]={ + ["cs"]="aktualnidatum", + ["de"]="heutigesdatum", + ["en"]="currentdate", + ["fr"]="datecourante", + ["it"]="datadioggi", + ["nl"]="huidigedatum", + ["pe"]="تاریخ‌جاری", + ["ro"]="datacurenta", + }, + ["currentheadnumber"]={ + ["cs"]="aktualnicislonadpisu", + ["de"]="heutigeskopfnummer", + ["en"]="currentheadnumber", + ["fr"]="numerotetecourant", + ["it"]="numerotestacorrente", + ["nl"]="huidigekopnummer", + ["pe"]="شماره‌سرجاری", + ["ro"]="numartitlucurent", + }, + ["cutspace"]={ + ["cs"]="cutspace", + ["de"]="cutspace", + ["en"]="cutspace", + ["fr"]="cutspace", + ["it"]="cutspace", + ["nl"]="snijwit", + ["pe"]="فضای‌برش", + ["ro"]="cutspace", + }, + ["date"]={ + ["cs"]="datum", + ["de"]="datum", + ["en"]="date", + ["fr"]="date", + ["it"]="data", + ["nl"]="datum", + ["pe"]="تاریخ", + ["ro"]="data", + }, + ["decouplemarking"]={ + ["cs"]="rozpojeneznaceni", + ["de"]="entknuepfebeschriftung", + ["en"]="decouplemarking", + ["fr"]="decouplemarquage", + ["it"]="separamarcatura", + ["nl"]="ontkoppelmarkering", + ["pe"]="جداسازی‌نشانه‌گذاری", + ["ro"]="decupleazamarcaje", + }, + ["decrementnumber"]={ + ["cs"]="decrementnumber", + ["de"]="decrementnumber", + ["en"]="decrementnumber", + ["fr"]="decrementenumero", + ["it"]="decrementnumber", + ["nl"]="verlaagnummer", + ["pe"]="شماره‌کاهش", + ["ro"]="decrementnumber", + }, + ["define"]={ + ["cs"]="definuj", + ["de"]="definieren", + ["en"]="define", + ["fr"]="definit", + ["it"]="definisci", + ["nl"]="definieer", + ["pe"]="تعریف", + ["ro"]="defineste", + }, + ["defineaccent"]={ + ["cs"]="definujakcent", + ["de"]="definiereakzent", + ["en"]="defineaccent", + ["fr"]="definitaccent", + ["it"]="definisciaccento", + ["nl"]="definieeraccent", + ["pe"]="تعریف‌لهجه", + ["ro"]="definesteaccent", + }, + ["defineblank"]={ + ["cs"]="definujpreskok", + ["de"]="definiereblanko", + ["en"]="defineblank", + ["fr"]="definitvide", + ["it"]="definiscirigovuoto", + ["nl"]="definieerblanko", + ["pe"]="تعریف‌خالی", + ["ro"]="definesteblanc", + }, + ["defineblock"]={ + ["cs"]="definujblok", + ["de"]="definiereblock", + ["en"]="defineblock", + ["fr"]="definitbloc", + ["it"]="definisciblocco", + ["nl"]="definieerblok", + ["pe"]="تعریف‌بلوک", + ["ro"]="definestebloc", + }, + ["definebodyfont"]={ + ["cs"]="definujzakladnifont", + ["de"]="definierefliesstext", + ["en"]="definebodyfont", + ["fr"]="definitpolicecorps", + ["it"]="definiscifontdeltesto", + ["nl"]="definieerkorps", + ["pe"]="تعریف‌قلم‌متن", + ["ro"]="definestefonttext", + }, + ["definebodyfontenvironment"]={ + ["cs"]="definujprostredizakladnihofontu", + ["de"]="definierefliesstextumgebung", + ["en"]="definebodyfontenvironment", + ["fr"]="definitenvironnementpolicecorps", + ["it"]="definisciambientefontdeltesto", + ["nl"]="definieerkorpsomgeving", + ["pe"]="تعریف‌محیط‌قلم‌بدنه", + ["ro"]="definestemediulfonttext", + }, + ["definebuffer"]={ + ["cs"]="definujbuffer", + ["de"]="definierepuffer", + ["en"]="definebuffer", + ["fr"]="definitbuffer", + ["it"]="definiscibuffer", + ["nl"]="definieerbuffer", + ["pe"]="تعریف‌بافر", + ["ro"]="definestebuffer", + }, + ["definecharacter"]={ + ["cs"]="definujznak", + ["de"]="definierezeichen", + ["en"]="definecharacter", + ["fr"]="definicaractere", + ["it"]="definiscicarattere", + ["nl"]="definieerkarakter", + ["pe"]="تعریف‌حرف", + ["ro"]="definestecaracter", + }, + ["definecolor"]={ + ["cs"]="definujbarvu", + ["de"]="definierefarbe", + ["en"]="definecolor", + ["fr"]="definitcouleur", + ["it"]="definiscicolore", + ["nl"]="definieerkleur", + ["pe"]="تعریف‌رنگ", + ["ro"]="definesteculoare", + }, + ["definecolorgroup"]={ + ["cs"]="definujskupinubarev", + ["de"]="definierefarbengruppe", + ["en"]="definecolorgroup", + ["fr"]="definitgroupecouleur", + ["it"]="definiscigruppocolori", + ["nl"]="definieerkleurgroep", + ["pe"]="تعریف‌گروه‌رنگ", + ["ro"]="definestegrupculori", + }, + ["definecolumnbreak"]={ + ["cs"]="definecolumnbreak", + ["de"]="definecolumnbreak", + ["en"]="definecolumnbreak", + ["fr"]="definitsautdecolonne", + ["it"]="definecolumnbreak", + ["nl"]="definieerkolomovergang", + ["pe"]="تعریف‌شکستن‌ستون", + ["ro"]="definecolumnbreak", + }, + ["definecolumnset"]={ + ["cs"]="definecolumnset", + ["de"]="definecolumnset", + ["en"]="definecolumnset", + ["fr"]="definitjeucolonne", + ["it"]="definiscigruppocolonne", + ["nl"]="definieerkolomgroep", + ["pe"]="تعریف‌مجموعه‌ستون", + ["ro"]="definecolumnset", + }, + ["definecombination"]={ + ["cs"]="definecombination", + ["de"]="definecombination", + ["en"]="definecombination", + ["fr"]="definecombination", + ["it"]="definecombination", + ["nl"]="definieercombinatie", + ["pe"]="تعریف‌ترکیب", + ["ro"]="definecombination", + }, + ["definecombinedlist"]={ + ["cs"]="definujkombinovanyseznam", + ["de"]="definierezusammengestellteliste", + ["en"]="definecombinedlist", + ["fr"]="definitlisteimbriquee", + ["it"]="definiscielencocombinato", + ["nl"]="definieersamengesteldelijst", + ["pe"]="تعریف‌لیست‌ترکیبی", + ["ro"]="definestelistacombinata", + }, + ["definecommand"]={ + ["cs"]="definujprikaz", + ["de"]="definierebefehl", + ["en"]="definecommand", + ["fr"]="definitcommande", + ["it"]="definiscicomando", + ["nl"]="definieercommando", + ["pe"]="تعریف‌فرمان", + ["ro"]="definestecomanda", + }, + ["defineconversion"]={ + ["cs"]="definujkonverzi", + ["de"]="definierekonversion", + ["en"]="defineconversion", + ["fr"]="definitconversion", + ["it"]="definisciconversione", + ["nl"]="definieerconversie", + ["pe"]="تعریف‌تبدیل", + ["ro"]="definesteconversie", + }, + ["definedescription"]={ + ["cs"]="definujpopis", + ["de"]="definierebeschreibung", + ["en"]="definedescription", + ["fr"]="definitdescription", + ["it"]="definiscidescrizione", + ["nl"]="doordefinieren", + ["pe"]="تعریف‌شرح", + ["ro"]="definestedescriere", + }, + ["defineenumeration"]={ + ["cs"]="definujvycet", + ["de"]="definierenummerierung", + ["en"]="defineenumeration", + ["fr"]="definitenumeration", + ["it"]="definiscienumerazione", + ["nl"]="doornummeren", + ["pe"]="تعریف‌شماره‌بندی", + ["ro"]="definesteenumerare", + }, + ["definefield"]={ + ["cs"]="definujpole", + ["de"]="definierefeld", + ["en"]="definefield", + ["fr"]="definitchamp", + ["it"]="definiscicampo", + ["nl"]="definieerveld", + ["pe"]="تعریف‌میدان", + ["ro"]="definestecamp", + }, + ["definefieldstack"]={ + ["cs"]="definujzasobnikpoli", + ["de"]="definierefeldstapel", + ["en"]="definefieldstack", + ["fr"]="definitpilechamp", + ["it"]="definiscistackcampi", + ["nl"]="definieerveldstapel", + ["pe"]="تعریف‌توده‌میدان", + ["ro"]="definestestivacampuri", + }, + ["definefiguresymbol"]={ + ["cs"]="definujobrazeksymbol", + ["de"]="definiereabbsymbol", + ["en"]="definefiguresymbol", + ["fr"]="definitsymbolefigure", + ["it"]="definiscifigurasimbolo", + ["nl"]="definieerfiguursymbool", + ["pe"]="تعریف‌نمادشکل", + ["ro"]="definestesimbolfigura", + }, + ["definefloat"]={ + ["cs"]="definujplvouciobjekt", + ["de"]="definieregleitobjekt", + ["en"]="definefloat", + ["fr"]="definitflottant", + ["it"]="definiscioggettomobile", + ["nl"]="definieerplaatsblok", + ["pe"]="تعریف‌شناور", + ["ro"]="definestefloat", + }, + ["definefont"]={ + ["cs"]="definujfont", + ["de"]="definiereschrift", + ["en"]="definefont", + ["fr"]="definitpolice", + ["it"]="definiscifont", + ["nl"]="definieerfont", + ["pe"]="تعریف‌قلم", + ["ro"]="definestefont", + }, + ["definefontstyle"]={ + ["cs"]="definujstylfontu", + ["de"]="definiereschriftstil", + ["en"]="definefontstyle", + ["fr"]="definitstylepolice", + ["it"]="definiscistilefont", + ["nl"]="definieerfontstijl", + ["pe"]="تعریف‌سبک‌قلم", + ["ro"]="definestestilfont", + }, + ["definefontsynonym"]={ + ["cs"]="definujsynonumumfontu", + ["de"]="defineschriftsynonym", + ["en"]="definefontsynonym", + ["fr"]="definitsynonymepolice", + ["it"]="definiscisinonimofont", + ["nl"]="definieerfontsynoniem", + ["pe"]="تعریف‌مترادف‌قلم", + ["ro"]="definestesinonimfont", + }, + ["defineframed"]={ + ["cs"]="definujoramovani", + ["de"]="definiereumrahmt", + ["en"]="defineframed", + ["fr"]="defineframed", + ["it"]="definisciincorniciato", + ["nl"]="definieeromlijnd", + ["pe"]="تعریف‌قالبی", + ["ro"]="definesteinconjurare", + }, + ["defineframedtext"]={ + ["cs"]="definujoramovanytext", + ["de"]="definiereumrahmtertext", + ["en"]="defineframedtext", + ["fr"]="defineframedtext", + ["it"]="definiscitestoincorniciato", + ["nl"]="definieerkadertekst", + ["pe"]="تعریف‌متن‌قالبی", + ["ro"]="definestetextinconjurat", + }, + ["definehbox"]={ + ["cs"]="definujhbox", + ["de"]="definierehbox", + ["en"]="definehbox", + ["fr"]="definithbox", + ["it"]="definiscihbox", + ["nl"]="definieerhbox", + ["pe"]="تعریف‌جعبه‌‌افقی", + ["ro"]="definestehbox", + }, + ["definehead"]={ + ["cs"]="definujnadpis", + ["de"]="definiereueberschrift", + ["en"]="definehead", + ["fr"]="definittete", + ["it"]="definiscitesta", + ["nl"]="definieerkop", + ["pe"]="تعریف‌سر", + ["ro"]="definesteantet", + }, + ["defineindenting"]={ + ["cs"]="definujodsazovani", + ["de"]="definiereeinzug", + ["en"]="defineindenting", + ["fr"]="definitcompoalinea", + ["it"]="definiscirientro", + ["nl"]="doorspringen", + ["pe"]="تعریف‌تورفتگی", + ["ro"]="definestealiat", + }, + ["defineinmargin"]={ + ["cs"]="defineinmargin", + ["de"]="defineinmargin", + ["en"]="defineinmargin", + ["fr"]="definitdansmarge", + ["it"]="defineinmargin", + ["nl"]="definieerinmarge", + ["pe"]="تعریف‌درون‌حاشیه", + ["ro"]="defineinmargin", + }, + ["defineinteractionmenu"]={ + ["cs"]="definujinterakcnimenu", + ["de"]="definiereinteraktionsmenue", + ["en"]="defineinteractionmenu", + ["fr"]="definitmenuinteraction", + ["it"]="definiscimenuinterazione", + ["nl"]="definieerinteractiemenu", + ["pe"]="تعریف‌منوی‌پانل", + ["ro"]="definestemeniuinteractiune", + }, + ["defineitemgroup"]={ + ["cs"]="defineitemgroup", + ["de"]="defineitemgroup", + ["en"]="defineitemgroup", + ["fr"]="defineitemgroup", + ["it"]="defineitemgroup", + ["nl"]="definieeritemgroep", + ["pe"]="تعریف‌گروه‌آیتم", + ["ro"]="defineitemgroup", + }, + ["definelabel"]={ + ["cs"]="definujpopisek", + ["de"]="definierelabel", + ["en"]="definelabel", + ["fr"]="definitetiquette", + ["it"]="definiscietichetta", + ["nl"]="doorlabelen", + ["pe"]="تعریف‌برچسب", + ["ro"]="definesteeticheta", + }, + ["definelayer"]={ + ["cs"]="definelayer", + ["de"]="definelayer", + ["en"]="definelayer", + ["fr"]="definitcalque", + ["it"]="definelayer", + ["nl"]="definieerlayer", + ["pe"]="تعریف‌لایه", + ["ro"]="definelayer", + }, + ["definelayout"]={ + ["cs"]="definelayout", + ["de"]="definelayout", + ["en"]="definelayout", + ["fr"]="definitdisposition", + ["it"]="definiscilayout", + ["nl"]="definieerlayout", + ["pe"]="تعریف‌طرح‌بندی", + ["ro"]="definelayout", + }, + ["definelist"]={ + ["cs"]="definujseznam", + ["de"]="definiereliste", + ["en"]="definelist", + ["fr"]="definitliste", + ["it"]="definiscielenco", + ["nl"]="definieerlijst", + ["pe"]="تعریف‌لیست", + ["ro"]="definestelista", + }, + ["definelogo"]={ + ["cs"]="definujlogo", + ["de"]="definierelogo", + ["en"]="definelogo", + ["fr"]="definitlogo", + ["it"]="definiscilogo", + ["nl"]="definieerbeeldmerk", + ["pe"]="تعریف‌آرم", + ["ro"]="definestelogo", + }, + ["definemainfield"]={ + ["cs"]="definujhlavnipole", + ["de"]="definierehauptfeld", + ["en"]="definemainfield", + ["fr"]="definitchampprincipal", + ["it"]="definiscicampoprincipale", + ["nl"]="definieerhoofdveld", + ["pe"]="تعریف‌میدان‌اصلی", + ["ro"]="definestecampprincipal", + }, + ["definemakeup"]={ + ["cs"]="definujupravu", + ["de"]="definiereumbruch", + ["en"]="definemakeup", + ["fr"]="definitmakeup", + ["it"]="definiscimakeup", + ["nl"]="definieeropmaak", + ["pe"]="تعریف‌آرایش", + ["ro"]="definestemakeup", + }, + ["definemarking"]={ + ["cs"]="definujznaceni", + ["de"]="definierebeschriftung", + ["en"]="definemarking", + ["fr"]="definitmarquage", + ["it"]="definiscimarcatura", + ["nl"]="definieermarkering", + ["pe"]="تعریف‌نشانه‌گذاری", + ["ro"]="definestemarcaje", + }, + ["definemathalignment"]={ + ["cs"]="definemathalignment", + ["de"]="definemathalignment", + ["en"]="definemathalignment", + ["fr"]="definemathalignment", + ["it"]="definemathalignment", + ["nl"]="definieerwiskundeuitlijnen", + ["pe"]="تعریف‌تنظیم‌ریاضی", + ["ro"]="definemathalignment", + }, + ["defineoutput"]={ + ["cs"]="definujvystup", + ["de"]="defineoutput", + ["en"]="defineoutput", + ["fr"]="definitsortie", + ["it"]="definiscioutput", + ["nl"]="definieeruitvoer", + ["pe"]="تعریف‌خروجی", + ["ro"]="definesteoutput", + }, + ["defineoverlay"]={ + ["cs"]="definujprekryv", + ["de"]="definiereoverlay", + ["en"]="defineoverlay", + ["fr"]="definitrevetement", + ["it"]="definiscisovrapposizione", + ["nl"]="definieeroverlay", + ["pe"]="تعریف‌پوشش", + ["ro"]="definesteoverlay", + }, + ["definepagebreak"]={ + ["cs"]="definepagebreak", + ["de"]="definepagebreak", + ["en"]="definepagebreak", + ["fr"]="definitsautdepage", + ["it"]="definepagebreak", + ["nl"]="definieerpaginaovergang", + ["pe"]="تعریف‌شکست‌صفحه", + ["ro"]="definepagebreak", + }, + ["definepalet"]={ + ["cs"]="definujpaletu", + ["de"]="definierepalette", + ["en"]="definepalet", + ["fr"]="definitpalette", + ["it"]="definiscitavolozza", + ["nl"]="definieerpalet", + ["pe"]="تعریف‌لوح", + ["ro"]="definestepaleta", + }, + ["definepapersize"]={ + ["cs"]="definujvelikostpapiru", + ["de"]="definierepapierformat", + ["en"]="definepapersize", + ["fr"]="definittaillepapier", + ["it"]="definiscidimensionicarta", + ["nl"]="definieerpapierformaat", + ["pe"]="تعریف‌اندازه‌برگ", + ["ro"]="definestedimensiunehartie", + }, + ["defineparagraphs"]={ + ["cs"]="definujodstavce", + ["de"]="definiereabsaetze", + ["en"]="defineparagraphs", + ["fr"]="definitparagraphes", + ["it"]="definiscicapoversi", + ["nl"]="definieeralineas", + ["pe"]="تعریف‌پاراگرافها", + ["ro"]="definesteparagraf", + }, + ["defineplacement"]={ + ["cs"]="defineplacement", + ["de"]="defineplacement", + ["en"]="defineplacement", + ["fr"]="defineplacement", + ["it"]="defineplacement", + ["nl"]="definieerplaats", + ["pe"]="تعریف‌جانشانی", + ["ro"]="defineplacement", + }, + ["defineprofile"]={ + ["cs"]="definujprofil", + ["de"]="definiereprofil", + ["en"]="defineprofile", + ["fr"]="definitprofil", + ["it"]="definisciprofilo", + ["nl"]="definieerprofiel", + ["pe"]="تعریف‌پروفایل", + ["ro"]="definesteprofil", + }, + ["defineprogram"]={ + ["cs"]="definujprogram", + ["de"]="definiereprogramme", + ["en"]="defineprogram", + ["fr"]="definitprogramme", + ["it"]="definisciprogramma", + ["nl"]="definieerprogramma", + ["pe"]="تعریف‌برنامه", + ["ro"]="definesteprogram", + }, + ["definerawfont"]={ + ["cs"]="definerawfont", + ["de"]="definerawfont", + ["en"]="definerawfont", + ["fr"]="definitpolicebrute", + ["it"]="definiscifontgrezzo", + ["nl"]="definerawfont", + ["pe"]="تعریف‌قلم‌خام", + ["ro"]="definestefontraw", + }, + ["definereference"]={ + ["cs"]="definujodkaz", + ["de"]="definierereferenz", + ["en"]="definereference", + ["fr"]="definitreference", + ["it"]="definisciriferimento", + ["nl"]="definieerreferentie", + ["pe"]="تعریف‌مرجع", + ["ro"]="definestereferinte", + }, + ["definereferenceformat"]={ + ["cs"]="definujformatodkazu", + ["de"]="definierereferenzformat", + ["en"]="definereferenceformat", + ["fr"]="definitformatreference", + ["it"]="definisciformatoriferimento", + ["nl"]="definieerreferentieformaat", + ["pe"]="تعریف‌شمایل‌مرجع", + ["ro"]="definesteformatreferinte", + }, + ["definereferencelist"]={ + ["cs"]="definujseznamodkazu", + ["de"]="definierereferenzliste", + ["en"]="definereferencelist", + ["fr"]="definitlistereference", + ["it"]="definiscilistariferimenti", + ["nl"]="definieerreferentielijst", + ["pe"]="تعریف‌لیست‌مرجع", + ["ro"]="definestelistareferinte", + }, + ["defineregister"]={ + ["cs"]="definujrejstrik", + ["de"]="definiereregister", + ["en"]="defineregister", + ["fr"]="definitregistre", + ["it"]="definisciregistro", + ["nl"]="definieerregister", + ["pe"]="تعریف‌ثبت", + ["ro"]="definesteregistru", + }, + ["definerule"]={ + ["cs"]="definerule", + ["de"]="definerule", + ["en"]="definerule", + ["fr"]="definitregle", + ["it"]="definiscilinea", + ["nl"]="definieerlijn", + ["pe"]="تعریف‌خط‌حائل", + ["ro"]="definesterigla", + }, + ["definesection"]={ + ["cs"]="definujsekci", + ["de"]="definiereabschnitt", + ["en"]="definesection", + ["fr"]="definitsection", + ["it"]="definiscisezione", + ["nl"]="definieersectie", + ["pe"]="تعریف‌بخش", + ["ro"]="definestesectiune", + }, + ["definesectionblock"]={ + ["cs"]="definujbloksekce", + ["de"]="definiereabschnittsblock", + ["en"]="definesectionblock", + ["fr"]="definitblocsection", + ["it"]="definiscibloccosezione", + ["nl"]="definieersectieblok", + ["pe"]="تعریف‌بلوک‌بخش", + ["ro"]="definesteblocsectiune", + }, + ["definesorting"]={ + ["cs"]="definujtrideni", + ["de"]="definieresortieren", + ["en"]="definesorting", + ["fr"]="definittri", + ["it"]="definisciordinamento", + ["nl"]="definieersorteren", + ["pe"]="تعریف‌ترتیب", + ["ro"]="definestesortare", + }, + ["definestartstop"]={ + ["cs"]="definujstartstop", + ["de"]="definierestartstop", + ["en"]="definestartstop", + ["fr"]="definitdemarrestoppe", + ["it"]="definisciiniziatermina", + ["nl"]="definieerstartstop", + ["pe"]="تعریف‌شروع‌پایان", + ["ro"]="definestestartstop", + }, + ["definestyle"]={ + ["cs"]="definujstyl", + ["de"]="definierestil", + ["en"]="definestyle", + ["fr"]="definitstyle", + ["it"]="definiscistile", + ["nl"]="definieerletter", + ["pe"]="تعریف‌سبک", + ["ro"]="definestestil", + }, + ["definesubfield"]={ + ["cs"]="definujpodpole", + ["de"]="definieresubfeld", + ["en"]="definesubfield", + ["fr"]="definitsouschamp", + ["it"]="definiscisottocampo", + ["nl"]="definieersubveld", + ["pe"]="تعریف‌زیرمیدان", + ["ro"]="definestesubcamp", + }, + ["definesymbol"]={ + ["cs"]="definujsymbol", + ["de"]="definieresymbol", + ["en"]="definesymbol", + ["fr"]="definitsymbole", + ["it"]="definiscisimbolo", + ["nl"]="definieersymbool", + ["pe"]="تعریف‌نماد", + ["ro"]="definestesimbol", + }, + ["definesynonyms"]={ + ["cs"]="definujsynonyma", + ["de"]="definieresynonyme", + ["en"]="definesynonyms", + ["fr"]="definitsynonymes", + ["it"]="definiscisinonimi", + ["nl"]="definieersynoniemen", + ["pe"]="تعریف‌مترادفها", + ["ro"]="definestesinonim", + }, + ["definetabletemplate"]={ + ["cs"]="definujsablonutabulky", + ["de"]="definieretabellenvorlage", + ["en"]="definetabletemplate", + ["fr"]="definittrametableau", + ["it"]="definiscimodellotabella", + ["nl"]="definieertabelvorm", + ["pe"]="تعریف‌الگوی‌جدول", + ["ro"]="definestesablontabel", + }, + ["definetabulate"]={ + ["cs"]="definujtabelaci", + ["de"]="definieretabulator", + ["en"]="definetabulate", + ["fr"]="definittabulation", + ["it"]="definiscitabulato", + ["nl"]="definieertabulatie", + ["pe"]="تعریف‌جدول‌بندی", + ["ro"]="definestetabulatori", + }, + ["definetext"]={ + ["cs"]="definujtext", + ["de"]="definieretext", + ["en"]="definetext", + ["fr"]="definittexte", + ["it"]="definiscitesto", + ["nl"]="definieertekst", + ["pe"]="تعریف‌متن", + ["ro"]="definestetext", + }, + ["definetextposition"]={ + ["cs"]="definetextposition", + ["de"]="definetextposition", + ["en"]="definetextposition", + ["fr"]="definitpositiontexte", + ["it"]="definisciposizionetesto", + ["nl"]="definieertekstpositie", + ["pe"]="تعریف‌مکان‌متن", + ["ro"]="definestepozitietext", + }, + ["definetextvariable"]={ + ["cs"]="definetextvariable", + ["de"]="definetextvariable", + ["en"]="definetextvariable", + ["fr"]="definitvariabletexte", + ["it"]="definiscivariabiletesto", + ["nl"]="definieertekstvariabele", + ["pe"]="تعریف‌متغیرمتن", + ["ro"]="definestevariabilatext", + }, + ["definetype"]={ + ["cs"]="definetype", + ["de"]="definetype", + ["en"]="definetype", + ["fr"]="definittype", + ["it"]="definiscitype", + ["nl"]="definieertype", + ["pe"]="تعریف‌تایپ", + ["ro"]="definetype", + }, + ["definetyping"]={ + ["cs"]="definujopis", + ["de"]="definieretippen", + ["en"]="definetyping", + ["fr"]="definitdactylo", + ["it"]="definiscityping", + ["nl"]="definieertypen", + ["pe"]="تعریف‌تایپ‌کردن", + ["ro"]="definestetyping", + }, + ["defineversion"]={ + ["cs"]="definujverzi", + ["de"]="definiereversion", + ["en"]="defineversion", + ["fr"]="definitversion", + ["it"]="definisciversion", + ["nl"]="definieerversie", + ["pe"]="تعریف‌نسخه", + ["ro"]="definesteversiune", + }, + ["determineheadnumber"]={ + ["cs"]="stanovcislonadpisu", + ["de"]="bestimmekopfnummer", + ["en"]="determineheadnumber", + ["fr"]="determinenumerotete", + ["it"]="determinanumerotesta", + ["nl"]="bepaalkopnummer", + ["pe"]="تعیین‌شماره‌سر", + ["ro"]="determinanumartitlu", + }, + ["determinelistcharacteristics"]={ + ["cs"]="stanovcharakteristickuseznamu", + ["de"]="bestimmelistencharakeristika", + ["en"]="determinelistcharacteristics", + ["fr"]="determinecaracteristiqueliste", + ["it"]="determinacarattersticheelenco", + ["nl"]="bepaallijstkenmerken", + ["pe"]="تعیین‌مشخصات‌لیست", + ["ro"]="determinacaracteristicilelistei", + }, + ["determineregistercharacteristics"]={ + ["cs"]="urcicharakteristikurejstriku", + ["de"]="bestimmeregistercharakteristika", + ["en"]="determineregistercharacteristics", + ["fr"]="determinecaracteristiquesregistre", + ["it"]="determinacaratteristicheregistro", + ["nl"]="bepaalregisterkenmerken", + ["pe"]="تعیین‌مشخصات‌ثبت", + ["ro"]="determinacaracteristiciregistru", + }, + ["dimension"]={ + ["cs"]="rozmer", + ["de"]="dimension", + ["en"]="dimension", + ["fr"]="dimension", + ["it"]="dimensione", + ["nl"]="dimensie", + ["pe"]="بعد", + ["ro"]="dimensiune", + }, + ["disableinteractionmenu"]={ + ["cs"]="zablokujinterakcnimenu", + ["de"]="inaktiviereinteraktionsmenue", + ["en"]="disableinteractionmenu", + ["fr"]="inhibemenuinteraction", + ["it"]="disabilitamenuinterazione", + ["nl"]="blokkeerinteractiemenu", + ["pe"]="ازکارانداختن‌منوی‌پانل", + ["ro"]="dezactiveazameniuinteractiune", + }, + ["domicile"]={ + ["cs"]="bydliste", + ["de"]="wohnort", + ["en"]="domicile", + ["fr"]="domicile", + ["it"]="domicilio", + ["nl"]="woonplaats", + ["pe"]="مسکن", + ["ro"]="domiciliu", + }, + ["donttest"]={ + ["cs"]="zadnytest", + ["de"]="keintest", + ["en"]="donttest", + ["fr"]="sanstest", + ["it"]="notest", + ["nl"]="geentest", + ["pe"]="امتحان‌نکن", + ["ro"]="nutesta", + }, + ["edgedistance"]={ + ["cs"]="vzdalenostokraje", + ["de"]="randabstand", + ["en"]="edgedistance", + ["fr"]="distancebord", + ["it"]="distanzabordo", + ["nl"]="randafstand", + ["pe"]="فاصله‌لبه", + ["ro"]="distantacolt", + }, + ["edgewidth"]={ + ["cs"]="sirkaokraje", + ["de"]="randbreite", + ["en"]="edgewidth", + ["fr"]="largeurbord", + ["it"]="ampiezzabordo", + ["nl"]="randbreedte", + ["pe"]="عرض‌لبه", + ["ro"]="latimecolturi", + }, + ["emptylines"]={ + ["cs"]="emptylines", + ["de"]="emptylines", + ["en"]="emptylines", + ["fr"]="emptylines", + ["it"]="emptylines", + ["nl"]="legeregels", + ["pe"]="خطها‌خالی", + ["ro"]="emptylines", + }, + ["environment"]={ + ["cs"]="prostredi", + ["de"]="umgebung", + ["en"]="environment", + ["fr"]="environement", + ["it"]="ambiente", + ["nl"]="omgeving", + ["pe"]="محیط", + ["ro"]="mediu", + }, + ["externalfigure"]={ + ["cs"]="externiobraz", + ["de"]="externeabbildung", + ["en"]="externalfigure", + ["fr"]="figureexterne", + ["it"]="figuraesterna", + ["nl"]="externfiguur", + ["pe"]="شکل‌خارجی", + ["ro"]="figuraexterna", + }, + ["fact"]={ + ["cs"]="fakt", + ["de"]="geg", + ["en"]="fact", + ["fr"]="fait", + ["it"]="fatto", + ["nl"]="geg", + ["pe"]="حقیقت", + ["ro"]="fact", + }, + ["field"]={ + ["cs"]="pole", + ["de"]="feld", + ["en"]="field", + ["fr"]="champ", + ["it"]="campi", + ["nl"]="veld", + ["pe"]="میدان", + ["ro"]="camp", + }, + ["fieldstack"]={ + ["cs"]="zasobnikpoli", + ["de"]="feldstapel", + ["en"]="fieldstack", + ["fr"]="pilechamp", + ["it"]="stackcampi", + ["nl"]="veldstapel", + ["pe"]="میدان‌پشته", + ["ro"]="stivacampuri", + }, + ["fillinfield"]={ + ["cs"]="vyplnovepole", + ["de"]="ausfuellfeld", + ["en"]="fillinfield", + ["fr"]="remplitchamp", + ["it"]="camporiempimento", + ["nl"]="invulveld", + ["pe"]="درج‌درمیدان", + ["ro"]="campumplere", + }, + ["fillinline"]={ + ["cs"]="vyplnovyradek", + ["de"]="gefuelltezeile", + ["en"]="fillinline", + ["fr"]="remplitligne", + ["it"]="rigariempimento", + ["nl"]="invulregel", + ["pe"]="درج‌درخط", + ["ro"]="linieumplere", + }, + ["fillinrules"]={ + ["cs"]="vyplnovelinky", + ["de"]="gefuelltesrechteck", + ["en"]="fillinrules", + ["fr"]="remplitlignesreglees", + ["it"]="lineeriempimento", + ["nl"]="invullijnen", + ["pe"]="درج‌درخطها", + ["ro"]="rigleumplere", + }, + ["fillintext"]={ + ["cs"]="vyplnenytext", + ["de"]="ausfuelltext", + ["en"]="fillintext", + ["fr"]="remplittexte", + ["it"]="testoriempimento", + ["nl"]="invultekst", + ["pe"]="درج‌درمتن", + ["ro"]="textumplere", + }, + ["fitfield"]={ + ["cs"]="prizpusobivepole", + ["de"]="passendfeld", + ["en"]="fitfield", + ["fr"]="ajustechamp", + ["it"]="adattacampo", + ["nl"]="passendveld", + ["pe"]="پرکردن‌میدان", + ["ro"]="potrivestecamp", + }, + ["fixedspace"]={ + ["cs"]="tvrdamezera", + ["de"]="festesspatium", + ["en"]="fixedspace", + ["fr"]="espacefixe", + ["it"]="spaziofisso", + ["nl"]="vastespatie", + ["pe"]="فضای‌ثابت", + ["ro"]="spatiufixat", + }, + ["fixedspaces"]={ + ["cs"]="tvrdemezery", + ["de"]="festesspatium", + ["en"]="fixedspaces", + ["fr"]="espacesfixes", + ["it"]="spazifissi", + ["nl"]="vastespaties", + ["pe"]="فضاهای‌ثابت", + ["ro"]="spatiifixate", + }, + ["followprofile"]={ + ["cs"]="dodrzujprofil", + ["de"]="folgeprofil", + ["en"]="followprofile", + ["fr"]="suivantprofil", + ["it"]="seguiprofilo", + ["nl"]="volgprofiel", + ["pe"]="پیروی‌پروفایل", + ["ro"]="urmeazaprofil", + }, + ["followprofileversion"]={ + ["cs"]="dodrzujverziprofilu", + ["de"]="folgeprofilversion", + ["en"]="followprofileversion", + ["fr"]="suivantversionprofil", + ["it"]="seguiversioneprofilo", + ["nl"]="volgprofielversie", + ["pe"]="پیروی‌نسخه‌پروفایل", + ["ro"]="urmeazaversiuneprofil", + }, + ["followversion"]={ + ["cs"]="dodrzujverzi", + ["de"]="folgeversion", + ["en"]="followversion", + ["fr"]="suivantversion", + ["it"]="seguiversione", + ["nl"]="volgversie", + ["pe"]="پیروی‌نسخه", + ["ro"]="urmeazaversiune", + }, + ["footerdistance"]={ + ["cs"]="vzdalenostupati", + ["de"]="fusszeileabstand", + ["en"]="footerdistance", + ["fr"]="distancepdp", + ["it"]="distanzapdp", + ["nl"]="voetafstand", + ["pe"]="فاصله‌ته‌برگ", + ["ro"]="distantasubsol", + }, + ["footerheight"]={ + ["cs"]="vyskaupati", + ["de"]="fusszeilenhoehe", + ["en"]="footerheight", + ["fr"]="hauteurpdp", + ["it"]="altezzapdp", + ["nl"]="voethoogte", + ["pe"]="ارتفاع‌ته‌برگ", + ["ro"]="inaltimesubsol", + }, + ["footnote"]={ + ["cs"]="poznamkapodcarou", + ["de"]="fussnote", + ["en"]="footnote", + ["fr"]="notepdp", + ["it"]="notapdp", + ["nl"]="voetnoot", + ["pe"]="پانوشت", + ["ro"]="notasubsol", + }, + ["footnotetext"]={ + ["cs"]="footnotetext", + ["de"]="footnotetext", + ["en"]="footnotetext", + ["fr"]="textenotepdp", + ["it"]="testonotapdp", + ["nl"]="voetnoottekst", + ["pe"]="متن‌پانوشت", + ["ro"]="footnotetext", + }, + ["forceblocks"]={ + ["cs"]="forceblocks", + ["de"]="forceblocks", + ["en"]="forceblocks", + ["fr"]="forceblocs", + ["it"]="forzablocchi", + ["nl"]="forceerblokken", + ["pe"]="اجباربلوکها", + ["ro"]="forteazablocuri", + }, + ["formulanumber"]={ + ["cs"]="cislorovnice", + ["de"]="formelnummer", + ["en"]="formulanumber", + ["fr"]="numeroformule", + ["it"]="numeroformula", + ["nl"]="formulenummer", + ["pe"]="شماره‌فرمول", + ["ro"]="numarformula", + }, + ["fraction"]={ + ["cs"]="zlomek", + ["de"]="bruch", + ["en"]="fraction", + ["fr"]="fraction", + ["it"]="frazione", + ["nl"]="breuk", + ["pe"]="کسر", + ["ro"]="fractie", + }, + ["framed"]={ + ["cs"]="oramovani", + ["de"]="umrahmt", + ["en"]="framed", + ["fr"]="framed", + ["it"]="incorniciato", + ["nl"]="omlijnd", + ["pe"]="قالبی", + ["ro"]="framed", + }, + ["from"]={ + ["cs"]="zref", + ["de"]="von", + ["en"]="from", + ["fr"]="de", + ["it"]="da", + ["nl"]="uit", + ["pe"]="از", + ["ro"]="din", + }, + ["getbuffer"]={ + ["cs"]="ziskejbuffer", + ["de"]="holepuffer", + ["en"]="getbuffer", + ["fr"]="prendbuffer", + ["it"]="prendibuffer", + ["nl"]="haalbuffer", + ["pe"]="دریافت‌بافر", + ["ro"]="adubuffer", + }, + ["getmarking"]={ + ["cs"]="ziskejznaceni", + ["de"]="holebeschriftung", + ["en"]="getmarking", + ["fr"]="obtientmarquage", + ["it"]="prendimarcatura", + ["nl"]="haalmarkering", + ["pe"]="دریافت‌نشانه", + ["ro"]="adumarcaje", + }, + ["getnumber"]={ + ["cs"]="getnumber", + ["de"]="getnumber", + ["en"]="getnumber", + ["fr"]="getnumber", + ["it"]="getnumber", + ["nl"]="haalnummer", + ["pe"]="دریافت‌شماره", + ["ro"]="getnumber", + }, + ["godown"]={ + ["cs"]="jdidolu", + ["de"]="nachunten", + ["en"]="godown", + ["fr"]="vaenbas", + ["it"]="vaigiu", + ["nl"]="omlaag", + ["pe"]="بروپایین", + ["ro"]="injos", + }, + ["goto"]={ + ["cs"]="jdina", + ["de"]="zu", + ["en"]="goto", + ["fr"]="va", + ["it"]="vaia", + ["nl"]="naar", + ["pe"]="بروبه", + ["ro"]="dute", + }, + ["gotobox"]={ + ["cs"]="jdinabox", + ["de"]="zurbox", + ["en"]="gotobox", + ["fr"]="vaalaboite", + ["it"]="vaiabox", + ["nl"]="naarbox", + ["pe"]="بروبه‌جعبه", + ["ro"]="dutebox", + }, + ["gotopage"]={ + ["cs"]="jdinastranu", + ["de"]="zurseite", + ["en"]="gotopage", + ["fr"]="vaalapage", + ["it"]="vaiapagina", + ["nl"]="naarpagina", + ["pe"]="بروبه‌صفحه", + ["ro"]="dutepagina", + }, + ["graycolor"]={ + ["cs"]="sedabarva", + ["de"]="graufarbe", + ["en"]="graycolor", + ["fr"]="couleurgrise", + ["it"]="coloregrigio", + ["nl"]="grijskleur", + ["pe"]="رنگ‌خاکستری", + ["ro"]="culoaregri", + }, + ["greyvalue"]={ + ["cs"]="hodnotasedi", + ["de"]="grauwert", + ["en"]="greyvalue", + ["fr"]="valeurgris", + ["it"]="valoregrigio", + ["nl"]="grijswaarde", + ["pe"]="مقدارخاکستری", + ["ro"]="valoaregri", + }, + ["grid"]={ + ["cs"]="mrizka", + ["de"]="gitter", + ["en"]="grid", + ["fr"]="grille", + ["it"]="griglia", + ["nl"]="rooster", + ["pe"]="توری", + ["ro"]="grid", + }, + ["hairline"]={ + ["cs"]="vlasovalinka", + ["de"]="haarlinie", + ["en"]="hairline", + ["fr"]="ligneh", + ["it"]="capello", + ["nl"]="haarlijn", + ["pe"]="خط‌مو", + ["ro"]="firdepar", + }, + ["head"]={ + ["cs"]="nadpis", + ["de"]="kopf", + ["en"]="head", + ["fr"]="tete", + ["it"]="testa", + ["nl"]="kop", + ["pe"]="سر", + ["ro"]="titlu", + }, + ["headerdistance"]={ + ["cs"]="vzdalenostzahlavi", + ["de"]="kopfzeilenabstand", + ["en"]="headerdistance", + ["fr"]="distanceentete", + ["it"]="distanzaintestazione", + ["nl"]="hoofdafstand", + ["pe"]="فاصله‌سربرگ", + ["ro"]="distantaantet", + }, + ["headerheight"]={ + ["cs"]="vyskazahlavi", + ["de"]="kopfzeilenhoehe", + ["en"]="headerheight", + ["fr"]="hauteurentete", + ["it"]="altezzaintestazione", + ["nl"]="hoofdhoogte", + ["pe"]="ارتفاع‌سربرگ", + ["ro"]="inaltimeantet", + }, + ["headlevel"]={ + ["cs"]="hlavniuroven", + ["de"]="kopfniveau", + ["en"]="headlevel", + ["fr"]="niveautete", + ["it"]="livellotesta", + ["nl"]="kopniveau", + ["pe"]="مرحله‌سر", + ["ro"]="niveltitlu", + }, + ["headnumber"]={ + ["cs"]="cislonadpisu", + ["de"]="kopfnummer", + ["en"]="headnumber", + ["fr"]="numerotete", + ["it"]="numerotesta", + ["nl"]="kopnummer", + ["pe"]="شماره‌سر", + ["ro"]="numartitlu", + }, + ["headsym"]={ + ["cs"]="headsym", + ["de"]="headsym", + ["en"]="headsym", + ["fr"]="headsym", + ["it"]="headsym", + ["nl"]="kopsym", + ["pe"]="نمادسر", + ["ro"]="headsym", + }, + ["headtext"]={ + ["cs"]="texthlavicky", + ["de"]="ueberschrifttext", + ["en"]="headtext", + ["fr"]="textetete", + ["it"]="testoinstestazioni", + ["nl"]="koptekst", + ["pe"]="متن‌سر", + ["ro"]="texttitlu", + }, + ["hideblocks"]={ + ["cs"]="schovejbloky", + ["de"]="verbergebloecke", + ["en"]="hideblocks", + ["fr"]="cacheblocs", + ["it"]="nascondiblocchi", + ["nl"]="verbergblokken", + ["pe"]="بلوکها‌پنهان", + ["ro"]="ascundeblocuri", + }, + ["high"]={ + ["cs"]="vysoky", + ["de"]="hoch", + ["en"]="high", + ["fr"]="haut", + ["it"]="ap", + ["nl"]="hoog", + ["pe"]="بلند", + ["ro"]="inalt", + }, + ["hl"]={ + ["cs"]="hl", + ["de"]="hl", + ["en"]="hl", + ["fr"]="hl", + ["it"]="hl", + ["nl"]="hl", + ["pe"]="خ‌ا", + ["ro"]="hl", + }, + ["immediatebetweenlist"]={ + ["cs"]="immediatebetweenlist", + ["de"]="immediatebetweenlist", + ["en"]="immediatebetweenlist", + ["fr"]="immediatebetweenlist", + ["it"]="immediatebetweenlist", + ["nl"]="directtussenlijst", + ["pe"]="فوری‌بین‌لیست", + ["ro"]="immediatebetweenlist", + }, + ["immediatetolist"]={ + ["cs"]="immediatetolist", + ["de"]="immediatetolist", + ["en"]="immediatetolist", + ["fr"]="immediatetolist", + ["it"]="immediatetolist", + ["nl"]="directnaarlijst", + ["pe"]="فوری‌به‌لیست", + ["ro"]="immediatetolist", + }, + ["in"]={ + ["cs"]="tref", + ["de"]="in", + ["en"]="in", + ["fr"]="dans", + ["it"]="in", + ["nl"]="in", + ["pe"]="درون", + ["ro"]="in", + }, + ["incrementnumber"]={ + ["cs"]="zvysujicicislo", + ["de"]="nummererhoehen", + ["en"]="incrementnumber", + ["fr"]="incrementenumero", + ["it"]="incrementanumero", + ["nl"]="verhoognummer", + ["pe"]="شماره‌افزایش", + ["ro"]="numarincrement", + }, + ["indenting"]={ + ["cs"]="odsazovani", + ["de"]="einziehen", + ["en"]="indenting", + ["fr"]="composeenalinea", + ["it"]="rientro", + ["nl"]="inspringen", + ["pe"]="تورفتگی", + ["ro"]="aliniat", + }, + ["inframed"]={ + ["cs"]="zaramovani", + ["de"]="imumriss", + ["en"]="inframed", + ["fr"]="inframed", + ["it"]="circondato", + ["nl"]="inlijnd", + ["pe"]="درقالبی", + ["ro"]="inframed", + }, + ["infull"]={ + ["cs"]="plnezneni", + ["de"]="volleswort", + ["en"]="infull", + ["fr"]="infull", + ["it"]="perlungo", + ["nl"]="voluit", + ["pe"]="درپر", + ["ro"]="pelung", + }, + ["ininner"]={ + ["cs"]="ininner", + ["de"]="ininner", + ["en"]="ininner", + ["fr"]="ininner", + ["it"]="ininner", + ["nl"]="inbinnen", + ["pe"]="درداخلی", + ["ro"]="ininner", + }, + ["inleft"]={ + ["cs"]="vlevo", + ["de"]="imlinken", + ["en"]="inleft", + ["fr"]="dansgauche", + ["it"]="insinistra", + ["nl"]="inlinker", + ["pe"]="درچپ", + ["ro"]="instanga", + }, + ["inleftedge"]={ + ["cs"]="nalevo", + ["de"]="imlinkenrand", + ["en"]="inleftedge", + ["fr"]="dansbordgauche", + ["it"]="inlatosinistro", + ["nl"]="inlinkerrand", + ["pe"]="درلبه‌چپ", + ["ro"]="inparteastanga", + }, + ["inleftmargin"]={ + ["cs"]="nalevyokraj", + ["de"]="inlinkermarginale", + ["en"]="inleftmargin", + ["fr"]="dansmargegauche", + ["it"]="inmarginesinistro", + ["nl"]="inlinkermarge", + ["pe"]="درحاشیه‌چپ", + ["ro"]="inmargineastanga", + }, + ["inline"]={ + ["cs"]="vradku", + ["de"]="inzeile", + ["en"]="inline", + ["fr"]="alaligne", + ["it"]="inriga", + ["nl"]="inregel", + ["pe"]="درخط", + ["ro"]="inlinie", + }, + ["inmargin"]={ + ["cs"]="naokraj", + ["de"]="inmarginalie", + ["en"]="inmargin", + ["fr"]="dansmarge", + ["it"]="inmargine", + ["nl"]="inmarge", + ["pe"]="درحاشیه", + ["ro"]="marginal", + }, + ["inmframed"]={ + ["cs"]="mazaramovani", + ["de"]="immaumrise", + ["en"]="inmaframed", + ["fr"]="inmframed", + ["it"]="inmaframed", + ["nl"]="inwilijnd", + ["pe"]="inmframed", + ["ro"]="inmaframed", + }, + ["inneredgedistance"]={ + ["cs"]="inneredgedistance", + ["de"]="inneredgedistance", + ["en"]="inneredgedistance", + ["fr"]="inneredgedistance", + ["it"]="inneredgedistance", + ["nl"]="binnenrandafstand", + ["pe"]="فاصله‌لبه‌داخلی", + ["ro"]="inneredgedistance", + }, + ["inneredgewidth"]={ + ["cs"]="inneredgewidth", + ["de"]="inneredgewidth", + ["en"]="inneredgewidth", + ["fr"]="inneredgewidth", + ["it"]="inneredgewidth", + ["nl"]="binnenrandbreedte", + ["pe"]="عرض‌لبه‌داخلی", + ["ro"]="inneredgewidth", + }, + ["innermargindistance"]={ + ["cs"]="innermargindistance", + ["de"]="innermargindistance", + ["en"]="innermargindistance", + ["fr"]="innermargindistance", + ["it"]="innermargindistance", + ["nl"]="binnenmargeafstand", + ["pe"]="فاصله‌حاشیه‌داخلی", + ["ro"]="innermargindistance", + }, + ["innermarginwidth"]={ + ["cs"]="innermarginwidth", + ["de"]="innermarginwidth", + ["en"]="innermarginwidth", + ["fr"]="innermarginwidth", + ["it"]="innermarginwidth", + ["nl"]="binnenmargebreedte", + ["pe"]="عرض‌حاشیه‌داخلی", + ["ro"]="innermarginwidth", + }, + ["inothermargin"]={ + ["cs"]="nadruhyokraj", + ["de"]="inanderermarginale", + ["en"]="inothermargin", + ["fr"]="dansautremarge", + ["it"]="inaltromargine", + ["nl"]="inanderemarge", + ["pe"]="درحاشیه‌دیگر", + ["ro"]="inaltamargine", + }, + ["inouter"]={ + ["cs"]="inouter", + ["de"]="inouter", + ["en"]="inouter", + ["fr"]="inouter", + ["it"]="inouter", + ["nl"]="inbuiten", + ["pe"]="درخارجی", + ["ro"]="inouter", + }, + ["inright"]={ + ["cs"]="vpravo", + ["de"]="imrechten", + ["en"]="inright", + ["fr"]="dansdroite", + ["it"]="indestra", + ["nl"]="inrechter", + ["pe"]="درراست", + ["ro"]="indreapta", + }, + ["inrightedge"]={ + ["cs"]="napravo", + ["de"]="imrechtenrand", + ["en"]="inrightedge", + ["fr"]="dansborddroit", + ["it"]="inlatodestro", + ["nl"]="inrechterrand", + ["pe"]="درلبه‌راست", + ["ro"]="inparteadreapta", + }, + ["inrightmargin"]={ + ["cs"]="napravyokraj", + ["de"]="inrechtermarginale", + ["en"]="inrightmargin", + ["fr"]="dansmargedroite", + ["it"]="inmarginedestro", + ["nl"]="inrechtermarge", + ["pe"]="درحاشیه‌راست", + ["ro"]="inmargineadreapta", + }, + ["installlanguage"]={ + ["cs"]="instalacejazyka", + ["de"]="installieresprache", + ["en"]="installlanguage", + ["fr"]="installelangue", + ["it"]="installalingua", + ["nl"]="installeertaal", + ["pe"]="نصب‌زبان", + ["ro"]="instalarelimba", + }, + ["interactionbar"]={ + ["cs"]="interakcnilista", + ["de"]="interaktionsbalken", + ["en"]="interactionbar", + ["fr"]="barreinteraction", + ["it"]="barrainterazione", + ["nl"]="interactiebalk", + ["pe"]="میله‌پانل", + ["ro"]="barainteractiune", + }, + ["interactionbuttons"]={ + ["cs"]="interakcnitlacitka", + ["de"]="interaktionsknopfe", + ["en"]="interactionbuttons", + ["fr"]="boutonsinteraction", + ["it"]="pulsantinterazione", + ["nl"]="interactiebuttons", + ["pe"]="دکمه‌پانل", + ["ro"]="butoaneinteractiune", + }, + ["interactionmenu"]={ + ["cs"]="interaktivnimenu", + ["de"]="interaktionsmenue", + ["en"]="interactionmenu", + ["fr"]="menuinteraction", + ["it"]="menuinterattivo", + ["nl"]="interactiemenu", + ["pe"]="منوی‌پانل", + ["ro"]="meniuinteractiune", + }, + ["item"]={ + ["cs"]="polozka", + ["de"]="pos", + ["en"]="item", + ["fr"]="element", + ["it"]="elemento", + ["nl"]="som", + ["pe"]="آیتم", + ["ro"]="element", + }, + ["items"]={ + ["cs"]="polozky", + ["de"]="posten", + ["en"]="items", + ["fr"]="elements", + ["it"]="elementi", + ["nl"]="items", + ["pe"]="آیتمها", + ["ro"]="element", + }, + ["its"]={ + ["cs"]="pol", + ["de"]="its", + ["en"]="its", + ["fr"]="el", + ["it"]="el", + ["nl"]="its", + ["pe"]="its", + ["ro"]="el", + }, + ["keepblocks"]={ + ["cs"]="zachovejbloky", + ["de"]="behaltebloecke", + ["en"]="keepblocks", + ["fr"]="gardeblocs", + ["it"]="tieniblocchi", + ["nl"]="handhaafblokken", + ["pe"]="حفظ‌بلوکها", + ["ro"]="pastreazablocuri", + }, + ["label"]={ + ["cs"]="poppisek", + ["de"]="label", + ["en"]="label", + ["fr"]="etiquette", + ["it"]="etichetta", + ["nl"]="label", + ["pe"]="برچسب", + ["ro"]="eticheta", + }, + ["labels"]={ + ["cs"]="popisky", + ["de"]="labels", + ["en"]="labels", + ["fr"]="etiquettes", + ["it"]="etichette", + ["nl"]="labels", + ["pe"]="برچسبها", + ["ro"]="etichete", + }, + ["labeltext"]={ + ["cs"]="textpopisku", + ["de"]="labeltext", + ["en"]="labeltext", + ["fr"]="labeltexte", + ["it"]="testoetichetta", + ["nl"]="labeltekst", + ["pe"]="متن‌برچسب", + ["ro"]="texteticheta", + }, + ["language"]={ + ["cs"]="jazyk", + ["de"]="sprache", + ["en"]="language", + ["fr"]="langue", + ["it"]="lingua", + ["nl"]="taal", + ["pe"]="زبان", + ["ro"]="limba", + }, + ["leftaligned"]={ + ["cs"]="zarovnanovlevo", + ["de"]="linksbuendig", + ["en"]="leftaligned", + ["fr"]="aligneagauche", + ["it"]="allineasinistra", + ["nl"]="regellinks", + ["pe"]="چپ‌چین", + ["ro"]="aliniatstanga", + }, + ["leftedgedistance"]={ + ["cs"]="vzdalenostlevehookraje", + ["de"]="abstandlinkerrand", + ["en"]="leftedgedistance", + ["fr"]="distancebordgauche", + ["it"]="distanzabordosinistro", + ["nl"]="linkerrandafstand", + ["pe"]="فاصله‌لبه‌چپ", + ["ro"]="distantacoltstanga", + }, + ["leftedgewidth"]={ + ["cs"]="sirkalevehookraje", + ["de"]="breitelinkerrand", + ["en"]="leftedgewidth", + ["fr"]="largeurbordgauche", + ["it"]="ampiezzabordosinistro", + ["nl"]="linkerrandbreedte", + ["pe"]="عرض‌لبه‌چپ", + ["ro"]="latimecoltstanga", + }, + ["leftmargindistance"]={ + ["cs"]="vzdalenostlevemarginalie", + ["de"]="linkemarginalafstand", + ["en"]="leftmargindistance", + ["fr"]="distancemargegauche", + ["it"]="distanzamarginesinistro", + ["nl"]="linkermargeafstand", + ["pe"]="فاصله‌حاشیه‌چپ", + ["ro"]="distantamarginestanga", + }, + ["leftmarginwidth"]={ + ["cs"]="sirkalevemarginalie", + ["de"]="linkemarginalbreite", + ["en"]="leftmarginwidth", + ["fr"]="largeurmargegauche", + ["it"]="ampiezzamarginesinistro", + ["nl"]="linkermargebreedte", + ["pe"]="عرض‌حاشیه‌چپ", + ["ro"]="latimemarginestanga", + }, + ["leg"]={ + ["cs"]="leg", + ["de"]="leg", + ["en"]="leg", + ["fr"]="leg", + ["it"]="leg", + ["nl"]="leg", + ["pe"]="پا", + ["ro"]="leg", + }, + ["linewidth"]={ + ["cs"]="tloustkacary", + ["de"]="liniendicke", + ["en"]="linethickness", + ["fr"]="largeurligne", + ["it"]="spessoreriga", + ["nl"]="lijndikte", + ["pe"]="عرض‌خط", + ["ro"]="grosimelinie", + }, + ["listheight"]={ + ["cs"]="vyskaseznamu", + ["de"]="listenhoehe", + ["en"]="listheight", + ["fr"]="hauteurliste", + ["it"]="altezzaelenco", + ["nl"]="lijsthoogte", + ["pe"]="ارتفاع‌خط", + ["ro"]="inaltimelista", + }, + ["listlength"]={ + ["cs"]="delkaseznamu", + ["de"]="listenlaenge", + ["en"]="listlength", + ["fr"]="llongueurliste", + ["it"]="lunghezzaelenco", + ["nl"]="lijstlengte", + ["pe"]="طول‌لیست", + ["ro"]="lungimelista", + }, + ["listsymbol"]={ + ["cs"]="listsymbol", + ["de"]="listsymbol", + ["en"]="listsymbol", + ["fr"]="listesymbole", + ["it"]="listsymbol", + ["nl"]="lijstsymbool", + ["pe"]="نمادلیست", + ["ro"]="listsymbol", + }, + ["listwidth"]={ + ["cs"]="sirkaseznamu", + ["de"]="listenbreite", + ["en"]="listwidth", + ["fr"]="largeurliste", + ["it"]="ampiezzaelenco", + ["nl"]="lijstbreedte", + ["pe"]="عرض‌لیست", + ["ro"]="latimelista", + }, + ["logfields"]={ + ["cs"]="zaznamovepole", + ["de"]="registrierefelder", + ["en"]="logfields", + ["fr"]="logchamp", + ["it"]="logcampi", + ["nl"]="registreervelden", + ["pe"]="میدانهای‌گزارش", + ["ro"]="logcampuri", + }, + ["lohi"]={ + ["cs"]="nivy", + ["de"]="tiho", + ["en"]="lohi", + ["fr"]="baha", + ["it"]="pedap", + ["nl"]="laho", + ["pe"]="پابا", + ["ro"]="jossus", + }, + ["low"]={ + ["cs"]="nizky", + ["de"]="tief", + ["en"]="low", + ["fr"]="bas", + ["it"]="ped", + ["nl"]="laag", + ["pe"]="پایین", + ["ro"]="jos", + }, + ["macroname"]={ + ["cs"]="jmeno", + ["de"]="name", + ["en"]="name", + ["fr"]="nommacro", + ["it"]="nome", + ["nl"]="naam", + ["pe"]="نام‌ماکرو", + ["ro"]="nume", + }, + ["mainlanguage"]={ + ["cs"]="hlavnijazyk", + ["de"]="hauptsprache", + ["en"]="mainlanguage", + ["fr"]="langueprincipale", + ["it"]="linguaprincipale", + ["nl"]="hoofdtaal", + ["pe"]="زبان‌اصلی", + ["ro"]="limbaprincipala", + }, + ["makeupheight"]={ + ["cs"]="vyskasazby", + ["de"]="satzhoehe", + ["en"]="makeupheight", + ["fr"]="hauteurmakeup", + ["it"]="altezzamakeup", + ["nl"]="zethoogte", + ["pe"]="ارتفاع‌آرایش", + ["ro"]="inaltimemakeup", + }, + ["makeupwidth"]={ + ["cs"]="sirkasazby", + ["de"]="satzbreite", + ["en"]="makeupwidth", + ["fr"]="largeurmakeup", + ["it"]="ampiezzamakeup", + ["nl"]="zetbreedte", + ["pe"]="عرض‌آرایش", + ["ro"]="latimemakeup", + }, + ["mar"]={ + ["cs"]="okr", + ["de"]="mar", + ["en"]="mar", + ["fr"]="mar", + ["it"]="mar", + ["nl"]="mar", + ["pe"]="حاش", + ["ro"]="mar", + }, + ["margindistance"]={ + ["cs"]="vzdalenostmarginalie", + ["de"]="marginalafstand", + ["en"]="margindistance", + ["fr"]="distancemarge", + ["it"]="distanzamargine", + ["nl"]="margeafstand", + ["pe"]="فاصله‌حاشیه", + ["ro"]="distantamargine", + }, + ["marginrule"]={ + ["cs"]="marginalnilinka", + ["de"]="marginallinie", + ["en"]="marginrule", + ["fr"]="margereglee", + ["it"]="lineamargine", + ["nl"]="kantlijn", + ["pe"]="خط‌حاشیه", + ["ro"]="liniemargine", + }, + ["margintext"]={ + ["cs"]="marginalnitext", + ["de"]="marginaltext", + ["en"]="margintext", + ["fr"]="textemarge", + ["it"]="testoinmargine", + ["nl"]="margetekst", + ["pe"]="متن‌حاشیه", + ["ro"]="textmarginal", + }, + ["margintitle"]={ + ["cs"]="marginalninadpis", + ["de"]="marginaltitel", + ["en"]="margintitle", + ["fr"]="titremarge", + ["it"]="titoloinmargine", + ["nl"]="margetitel", + ["pe"]="عنوان‌حاشیه", + ["ro"]="titlumarginal", + }, + ["marginwidth"]={ + ["cs"]="sirkamarginalie", + ["de"]="marginalbreite", + ["en"]="marginwidth", + ["fr"]="largeurmarge", + ["it"]="ampiezzamargine", + ["nl"]="margebreedte", + ["pe"]="عرض‌حاشیه", + ["ro"]="latimemargine", + }, + ["marginword"]={ + ["cs"]="marginalnislovo", + ["de"]="marginalwort", + ["en"]="marginword", + ["fr"]="motmarge", + ["it"]="parolainmargine", + ["nl"]="margewoord", + ["pe"]="کلمه‌حاشیه", + ["ro"]="cuvantmarginal", + }, + ["marking"]={ + ["cs"]="znaceni", + ["de"]="beschriftung", + ["en"]="marking", + ["fr"]="marquage", + ["it"]="marcatura", + ["nl"]="markeer", + ["pe"]="نشانه‌گذاری", + ["ro"]="marcaje", + }, + ["markversion"]={ + ["cs"]="oznacverzi", + ["de"]="beschrifteversion", + ["en"]="markversion", + ["fr"]="marquageversion", + ["it"]="marcaversione", + ["nl"]="markeerversie", + ["pe"]="نسخه‌نشانه", + ["ro"]="marcheazaversiune", + }, + ["mathematics"]={ + ["cs"]="matematika", + ["de"]="mathematik", + ["en"]="mathematics", + ["fr"]="mathematique", + ["it"]="matematica", + ["nl"]="wiskunde", + ["pe"]="ریاضی", + ["ro"]="matematica", + }, + ["menubutton"]={ + ["cs"]="tlacitkomenu", + ["de"]="menueknopf", + ["en"]="menubutton", + ["fr"]="boutonmenu", + ["it"]="pulsantemenu", + ["nl"]="menubutton", + ["pe"]="دکمه‌منو", + ["ro"]="butonmeniu", + }, + ["mframed"]={ + ["cs"]="maoramovani", + ["de"]="maumrise", + ["en"]="maframed", + ["fr"]="mframed", + ["it"]="maframed", + ["nl"]="wilijnd", + ["pe"]="mframed", + ["ro"]="maframed", + }, + ["midaligned"]={ + ["cs"]="zarovnanonastred", + ["de"]="zentriert", + ["en"]="midaligned", + ["fr"]="aligneaumilieu", + ["it"]="allineacentro", + ["nl"]="regelmidden", + ["pe"]="تنظیم‌وسط", + ["ro"]="aliniatcentru", + }, + ["mirror"]={ + ["cs"]="zrcadlit", + ["de"]="spiegeln", + ["en"]="mirror", + ["fr"]="reflete", + ["it"]="riflessione", + ["nl"]="spiegel", + ["pe"]="آینه", + ["ro"]="reflexie", + }, + ["month"]={ + ["cs"]="mesic", + ["de"]="monat", + ["en"]="month", + ["fr"]="mois", + ["it"]="mese", + ["nl"]="maand", + ["pe"]="ماه", + ["ro"]="luna", + }, + ["moveformula"]={ + ["cs"]="moveformula", + ["de"]="moveformula", + ["en"]="moveformula", + ["fr"]="deplaceformule", + ["it"]="spostaformula", + ["nl"]="verplaatsformule", + ["pe"]="انتقال‌فرمول", + ["ro"]="moveformula", + }, + ["moveongrid"]={ + ["cs"]="premistinamrizku", + ["de"]="amgitterneuausrichten", + ["en"]="moveongrid", + ["fr"]="deplacesurgrille", + ["it"]="spostaagriglia", + ["nl"]="verplaatsopgrid", + ["pe"]="انتقال‌به‌توری", + ["ro"]="mutapegrid", + }, + ["movesidefloat"]={ + ["cs"]="movesidefloat", + ["de"]="movesidefloat", + ["en"]="movesidefloat", + ["fr"]="movesidefloat", + ["it"]="movesidefloat", + ["nl"]="verplaatszijblok", + ["pe"]="انتقال‌کنار‌شناور", + ["ro"]="movesidefloat", + }, + ["navigating"]={ + ["cs"]="navigating", + ["de"]="navigating", + ["en"]="navigating", + ["fr"]="navigating", + ["it"]="navigating", + ["nl"]="navigerend", + ["pe"]="هدایت", + ["ro"]="navigating", + }, + ["nodimension"]={ + ["cs"]="zadnyrozmer", + ["de"]="keindimension", + ["en"]="nodimension", + ["fr"]="sansdimension", + ["it"]="nientedimensioni", + ["nl"]="geendimensie", + ["pe"]="بدون‌بعد", + ["ro"]="faradimensiune", + }, + ["noheaderandfooterlines"]={ + ["cs"]="zadnezahlaviaupati", + ["de"]="keinekopfundfusszeilen", + ["en"]="noheaderandfooterlines", + ["fr"]="sanslignesenteteetpdp", + ["it"]="nientelineintestazionepdp", + ["nl"]="geenhoofdenvoetregels", + ["pe"]="بدون‌خط‌سروته‌برگ", + ["ro"]="faraliniiantetsisubsol", + }, + ["noindenting"]={ + ["cs"]="zadneodsazovani", + ["de"]="nichteinziehen", + ["en"]="noindenting", + ["fr"]="sansalinea", + ["it"]="nienterientro", + ["nl"]="nietinspringen", + ["pe"]="بدون‌تورفتگی", + ["ro"]="faraaliniat", + }, + ["nolist"]={ + ["cs"]="zadnyseznam", + ["de"]="keineliste", + ["en"]="nolist", + ["fr"]="sansliste", + ["it"]="nienteelenco", + ["nl"]="geenlijst", + ["pe"]="بدون‌لیست", + ["ro"]="faralista", + }, + ["nomarking"]={ + ["cs"]="zadneznaceni", + ["de"]="keinebeschriftung", + ["en"]="nomarking", + ["fr"]="sansmarquage", + ["it"]="nientemarcatura", + ["nl"]="geenmarkering", + ["pe"]="بدون‌نشانه‌گذاری", + ["ro"]="faramarcaje", + }, + ["nomoreblocks"]={ + ["cs"]="zadnedalsibloky", + ["de"]="keinebloeckemehr", + ["en"]="nomoreblocks", + ["fr"]="pasplusdeblocs", + ["it"]="bastablocchi", + ["nl"]="geenblokkenmeer", + ["pe"]="بدون‌بلوکهای‌بیشتر", + ["ro"]="gatablocuri", + }, + ["nomorefiles"]={ + ["cs"]="zadnedalsisoubory", + ["de"]="keinedateienmehr", + ["en"]="nomorefiles", + ["fr"]="pasplusdefichiers", + ["it"]="bastafile", + ["nl"]="geenfilesmeer", + ["pe"]="بدون‌فایلهای‌بیشتر", + ["ro"]="farafisiere", + }, + ["nop"]={ + ["cs"]="nop", + ["de"]="nop", + ["en"]="nop", + ["fr"]="nop", + ["it"]="nop", + ["nl"]="nop", + ["pe"]="منفی", + ["ro"]="nop", + }, + ["nospace"]={ + ["cs"]="zadnamezera", + ["de"]="keinspatium", + ["en"]="nospace", + ["fr"]="sansespace", + ["it"]="nientespazio", + ["nl"]="geenspatie", + ["pe"]="بدون‌فضا", + ["ro"]="faraspatiu", + }, + ["note"]={ + ["cs"]="poznamka", + ["de"]="notiz", + ["en"]="note", + ["fr"]="note", + ["it"]="nota", + ["nl"]="noot", + ["pe"]="یادداشت", + ["ro"]="nota", + }, + ["notopandbottomlines"]={ + ["cs"]="zadnehorniadolniradky", + ["de"]="keinzeilenobenundunten", + ["en"]="notopandbottomlines", + ["fr"]="sanslignessupetinf", + ["it"]="nientelineecimafondo", + ["nl"]="geenbovenenonderregels", + ["pe"]="بدون‌خط‌بالاوپایین", + ["ro"]="faraliniisussijos", + }, + ["notsmallcapped"]={ + ["cs"]="nokap", + ["de"]="nokap", + ["en"]="nocap", + ["fr"]="nocap", + ["it"]="nocap", + ["nl"]="nokap", + ["pe"]="سرپوش‌کوچک‌نه", + ["ro"]="nokap", + }, + ["nowhitespace"]={ + ["cs"]="zadnebilemisto", + ["de"]="keinzwischenraum", + ["en"]="nowhitespace", + ["fr"]="sansespaceblanc", + ["it"]="nientespaziobianco", + ["nl"]="geenwitruimte", + ["pe"]="بدون‌فضای‌سفید", + ["ro"]="faraspatiualb", + }, + ["numberofsubpages"]={ + ["cs"]="numberofsubpages", + ["de"]="numberofsubpages", + ["en"]="numberofsubpages", + ["fr"]="nombredesouspages", + ["it"]="numberofsubpages", + ["nl"]="aantalsubpaginas", + ["pe"]="شماره‌زیرصفحه", + ["ro"]="numberofsubpages", + }, + ["numbers"]={ + ["cs"]="cisla", + ["de"]="ziffern", + ["en"]="numbers", + ["fr"]="numeros", + ["it"]="numeri", + ["nl"]="cijfers", + ["pe"]="شماره‌ها", + ["ro"]="numere", + }, + ["outeredgedistance"]={ + ["cs"]="outeredgedistance", + ["de"]="outeredgedistance", + ["en"]="outeredgedistance", + ["fr"]="outeredgedistance", + ["it"]="outeredgedistance", + ["nl"]="buitenrandafstand", + ["pe"]="فاصله‌لبه‌خارجی", + ["ro"]="outeredgedistance", + }, + ["outeredgewidth"]={ + ["cs"]="outeredgewidth", + ["de"]="outeredgewidth", + ["en"]="outeredgewidth", + ["fr"]="outeredgewidth", + ["it"]="outeredgewidth", + ["nl"]="buitenrandbreedte", + ["pe"]="عرض‌لبه‌خارجی", + ["ro"]="outeredgewidth", + }, + ["outermargindistance"]={ + ["cs"]="outermargindistance", + ["de"]="outermargindistance", + ["en"]="outermargindistance", + ["fr"]="outermargindistance", + ["it"]="outermargindistance", + ["nl"]="buitenmargeafstand", + ["pe"]="فاصله‌حاشیه‌خارجی", + ["ro"]="outermargindistance", + }, + ["outermarginwidth"]={ + ["cs"]="outermarginwidth", + ["de"]="outermarginwidth", + ["en"]="outermarginwidth", + ["fr"]="outermarginwidth", + ["it"]="outermarginwidth", + ["nl"]="buitenmargebreedte", + ["pe"]="عرض‌حاشیه‌خارجی", + ["ro"]="outermarginwidth", + }, + ["packed"]={ + ["cs"]="zhustene", + ["de"]="kleinerdurchschuss", + ["en"]="packed", + ["fr"]="groupe", + ["it"]="impaccato", + ["nl"]="opelkaar", + ["pe"]="فشرده", + ["ro"]="impachetat", + }, + ["page"]={ + ["cs"]="strana", + ["de"]="seite", + ["en"]="page", + ["fr"]="page", + ["it"]="pagina", + ["nl"]="pagina", + ["pe"]="صفحه", + ["ro"]="pagina", + }, + ["pagedepth"]={ + ["cs"]="pagedepth", + ["de"]="pagedepth", + ["en"]="pagedepth", + ["fr"]="pagedepth", + ["it"]="pagedepth", + ["nl"]="paginadiepte", + ["pe"]="عمق‌صفحه", + ["ro"]="pagedepth", + }, + ["pagenumber"]={ + ["cs"]="cislostrany", + ["de"]="seitenummer", + ["en"]="pagenumber", + ["fr"]="numeropage", + ["it"]="numeropagina", + ["nl"]="paginanummer", + ["pe"]="شماره‌صفحه", + ["ro"]="numarpagina", + }, + ["pageoffset"]={ + ["cs"]="pageoffset", + ["de"]="pageoffset", + ["en"]="pageoffset", + ["fr"]="pageoffset", + ["it"]="pageoffset", + ["nl"]="paginaoffset", + ["pe"]="آفست‌صفحه", + ["ro"]="pageoffset", + }, + ["pagereference"]={ + ["cs"]="odkaznastranu", + ["de"]="seitenreferenz", + ["en"]="pagereference", + ["fr"]="referencepage", + ["it"]="riferimentopagina", + ["nl"]="paginareferentie", + ["pe"]="مرجع‌صفحه", + ["ro"]="referintapagina", + }, + ["pagetype"]={ + ["cs"]="typstrany", + ["de"]="seitentyp", + ["en"]="pagetype", + ["fr"]="tapepage", + ["it"]="tipopagina", + ["nl"]="soortpagina", + ["pe"]="نوع‌صفحه", + ["ro"]="tippagina", + }, + ["paperheight"]={ + ["cs"]="vyskapapiru", + ["de"]="papierhoehe", + ["en"]="paperheight", + ["fr"]="hauteurpapier", + ["it"]="altezzacarta", + ["nl"]="papierhoogte", + ["pe"]="ارتفاع‌برگ", + ["ro"]="inaltimehartie", + }, + ["paperwidth"]={ + ["cs"]="sirkapapiru", + ["de"]="papierbreite", + ["en"]="paperwidth", + ["fr"]="largeurpapier", + ["it"]="ampiezzacarta", + ["nl"]="papierbreedte", + ["pe"]="عرض‌برگ", + ["ro"]="latimehartie", + }, + ["periods"]={ + ["cs"]="tecky", + ["de"]="punkt", + ["en"]="periods", + ["fr"]="periodes", + ["it"]="punti", + ["nl"]="punten", + ["pe"]="نقطه‌ها", + ["ro"]="puncte", + }, + ["plaatsruwelijst"]={ + ["cs"]="placerawlist", + ["de"]="placerawlist", + ["en"]="placerawlist", + ["fr"]="placerawlist", + ["it"]="placerawlist", + ["nl"]="plaatsruwelijst", + ["pe"]="درج‌لیست‌خام", + ["ro"]="placerawlist", + }, + ["placebookmarks"]={ + ["cs"]="umistizalozky", + ["de"]="platzierebookmarks", + ["en"]="placebookmarks", + ["fr"]="placemarquespages", + ["it"]="mettisegnalibro", + ["nl"]="plaatsbookmarks", + ["pe"]="درج‌چوب‌خط", + ["ro"]="plaseazasemnecarte", + }, + ["placecombinedlist"]={ + ["cs"]="umistikombinovanyseznam", + ["de"]="platzierezusammengestellteliste", + ["en"]="placecombinedlist", + ["fr"]="placelisteinmbriquee", + ["it"]="mettielencocombinato", + ["nl"]="plaatssamengesteldelijst", + ["pe"]="درج‌لیست‌مختلط", + ["ro"]="punelistacombinata", + }, + ["placefloat"]={ + ["cs"]="placefloat", + ["de"]="placefloat", + ["en"]="placefloat", + ["fr"]="placeflottant", + ["it"]="placefloat", + ["nl"]="plaatsplaatsblok", + ["pe"]="درج‌شناور", + ["ro"]="placefloat", + }, + ["placefootnotes"]={ + ["cs"]="umistipoznamkypodcarou", + ["de"]="platzierefussnoten", + ["en"]="placefootnotes", + ["fr"]="placenotespdp", + ["it"]="mettinotepdp", + ["nl"]="plaatsvoetnoten", + ["pe"]="درج‌پانوشتها", + ["ro"]="punenotesubsol", + }, + ["placeformula"]={ + ["cs"]="umistirovnici", + ["de"]="platziereformel", + ["en"]="placeformula", + ["fr"]="placeformule", + ["it"]="mettiformula", + ["nl"]="plaatsformule", + ["pe"]="درج‌فرمول", + ["ro"]="puneformula", + }, + ["placeheadnumber"]={ + ["cs"]="placeheadnumber", + ["de"]="placeheadnumber", + ["en"]="placeheadnumber", + ["fr"]="placenumerotete", + ["it"]="posizionanumerotesta", + ["nl"]="plaatskopnummer", + ["pe"]="درج‌شماره‌سر", + ["ro"]="placeheadnumber", + }, + ["placeheadtext"]={ + ["cs"]="placeheadtext", + ["de"]="placeheadtext", + ["en"]="placeheadtext", + ["fr"]="placetextetete", + ["it"]="posizionatestotesta", + ["nl"]="plaatskoptekst", + ["pe"]="درج‌متن‌سر", + ["ro"]="placeheadtext", + }, + ["placelegend"]={ + ["cs"]="umistilegendu", + ["de"]="platzierelegende", + ["en"]="placelegend", + ["fr"]="placelegende", + ["it"]="mettilegenda", + ["nl"]="plaatslegenda", + ["pe"]="درج‌راهنما", + ["ro"]="punelegenda", + }, + ["placelist"]={ + ["cs"]="umistiseznam", + ["de"]="platziereliste", + ["en"]="placelist", + ["fr"]="placeliste", + ["it"]="mettielenco", + ["nl"]="plaatslijst", + ["pe"]="درج‌لیست", + ["ro"]="punelista", + }, + ["placelocalfootnotes"]={ + ["cs"]="umistilokalnipoznamkypodcarou", + ["de"]="platzierelokalefussnoten", + ["en"]="placelocalfootnotes", + ["fr"]="placenotespdplocales", + ["it"]="mettinotepdplocali", + ["nl"]="plaatslokalevoetnoten", + ["pe"]="درج‌پانوشتهای‌موضعی", + ["ro"]="punenotesubsollocale", + }, + ["placelogos"]={ + ["cs"]="umistiloga", + ["de"]="platzierelogo", + ["en"]="placelogos", + ["fr"]="placelogos", + ["it"]="mettiloghi", + ["nl"]="plaatsbeeldmerken", + ["pe"]="درج‌آرمها", + ["ro"]="punelogouri", + }, + ["placeongrid"]={ + ["cs"]="umistinamrizku", + ["de"]="amgitterausrichten", + ["en"]="placeongrid", + ["fr"]="placesurgrille", + ["it"]="mettiingriglia", + ["nl"]="plaatsopgrid", + ["pe"]="درج‌در‌توری", + ["ro"]="plaseazapegrid", + }, + ["placeontopofeachother"]={ + ["cs"]="umistinadsebe", + ["de"]="platziereuntereinander", + ["en"]="placeontopofeachother", + ["fr"]="placelesunsaudessusdesautres", + ["it"]="mettiunosullaltro", + ["nl"]="plaatsonderelkaar", + ["pe"]="درج‌در‌بالای‌یکدیگر", + ["ro"]="punedeasuprafiecareia", + }, + ["placepagenumber"]={ + ["cs"]="placepagenumber", + ["de"]="placepagenumber", + ["en"]="placepagenumber", + ["fr"]="placenumeropage", + ["it"]="mettinumeropagina", + ["nl"]="plaatspaginanummer", + ["pe"]="درج‌شماره‌صفحه", + ["ro"]="punenumarpagina", + }, + ["placereferencelist"]={ + ["cs"]="placereferencelist", + ["de"]="placereferencelist", + ["en"]="placereferencelist", + ["fr"]="placelistereference", + ["it"]="placereferencelist", + ["nl"]="plaatsreferentielijst", + ["pe"]="درج‌لیست‌مرجع", + ["ro"]="placereferencelist", + }, + ["placeregister"]={ + ["cs"]="umistirejstrik", + ["de"]="platziereregister", + ["en"]="placeregister", + ["fr"]="placeregistre", + ["it"]="mettiregistro", + ["nl"]="plaatsregister", + ["pe"]="درج‌ثبت", + ["ro"]="puneregistru", + }, + ["placerule"]={ + ["cs"]="placerule", + ["de"]="placerule", + ["en"]="placerule", + ["fr"]="placeregle", + ["it"]="mettilinea", + ["nl"]="plaatslijn", + ["pe"]="درج‌خط", + ["ro"]="punerigla", + }, + ["placesidebyside"]={ + ["cs"]="umistivedlesebe", + ["de"]="platzierenebeneinander", + ["en"]="placesidebyside", + ["fr"]="placecoteacote", + ["it"]="mettifiancoafianco", + ["nl"]="plaatsnaastelkaar", + ["pe"]="درج‌کنار‌به‌کنار", + ["ro"]="punefatainfata", + }, + ["placesubformula"]={ + ["cs"]="umistipodrovnici", + ["de"]="platziereunterformel", + ["en"]="placesubformula", + ["fr"]="placesousformule", + ["it"]="mettisottoformula", + ["nl"]="plaatssubformule", + ["pe"]="درج‌زیرفرمول", + ["ro"]="punesubformula", + }, + ["placetextvariable"]={ + ["cs"]="placetextvariable", + ["de"]="placetextvariable", + ["en"]="placetextvariable", + ["fr"]="placevariabletexte", + ["it"]="mettivariabiletesto", + ["nl"]="plaatstekstvariabele", + ["pe"]="درج‌متغیرمتن", + ["ro"]="punevariabilatext", + }, + ["position"]={ + ["cs"]="pozice", + ["de"]="position", + ["en"]="position", + ["fr"]="position", + ["it"]="posizione", + ["nl"]="positioneer", + ["pe"]="مکان", + ["ro"]="pozitie", + }, + ["positiontext"]={ + ["cs"]="positiontext", + ["de"]="positiontext", + ["en"]="positiontext", + ["fr"]="positionnetexte", + ["it"]="posizionatesto", + ["nl"]="positioneertekst", + ["pe"]="مکان‌متن", + ["ro"]="pozitietext", + }, + ["printpaperheight"]={ + ["cs"]="vyskatiskpapiru", + ["de"]="printpapierhoehe", + ["en"]="printpaperheight", + ["fr"]="hauteureditionpapier", + ["it"]="altezzacartastampa", + ["nl"]="printpapierhoogte", + ["pe"]="چاپ‌ارتفاع‌برگ", + ["ro"]="inaltimehartieimprimanta", + }, + ["printpaperwidth"]={ + ["cs"]="sirkatiskpapiru", + ["de"]="printpapierbreite", + ["en"]="printpaperwidth", + ["fr"]="largeureditionpapier", + ["it"]="ampiezzacartastampa", + ["nl"]="printpapierbreedte", + ["pe"]="چاپ‌عرض‌برگ", + ["ro"]="latimehartieimprimanta", + }, + ["processblocks"]={ + ["cs"]="zpracujbloky", + ["de"]="bearbeitebloecke", + ["en"]="processblocks", + ["fr"]="traiteblocs", + ["it"]="elaborablocchi", + ["nl"]="verwerkblokken", + ["pe"]="بلوکهای‌پردازش", + ["ro"]="proceseazabloc", + }, + ["processpage"]={ + ["cs"]="zpracujstranu", + ["de"]="bearbeiteseite", + ["en"]="processpage", + ["fr"]="traitepage", + ["it"]="elaborapagina", + ["nl"]="verwerkpagina", + ["pe"]="صفحه‌پردازش", + ["ro"]="proceseazapagina", + }, + ["product"]={ + ["cs"]="produkt", + ["de"]="produkt", + ["en"]="product", + ["fr"]="produit", + ["it"]="prodotto", + ["nl"]="produkt", + ["pe"]="تولید", + ["ro"]="produs", + }, + ["program"]={ + ["cs"]="program", + ["de"]="programm", + ["en"]="program", + ["fr"]="programme", + ["it"]="programma", + ["nl"]="programma", + ["pe"]="برنامه", + ["ro"]="program", + }, + ["project"]={ + ["cs"]="projekt", + ["de"]="projekt", + ["en"]="project", + ["fr"]="projet", + ["it"]="progetto", + ["nl"]="projekt", + ["pe"]="پروژه", + ["ro"]="proiect", + }, + ["publication"]={ + ["cs"]="publikace", + ["de"]="publikation", + ["en"]="publication", + ["fr"]="publication", + ["it"]="pubblicazione", + ["nl"]="publicatie", + ["pe"]="نشر", + ["ro"]="publicatie", + }, + ["quotation"]={ + ["cs"]="citace", + ["de"]="zitat", + ["en"]="quotation", + ["fr"]="citation", + ["it"]="citazione", + ["nl"]="citaat", + ["pe"]="نقل‌قول", + ["ro"]="citat", + }, + ["quote"]={ + ["cs"]="citovat", + ["de"]="zitieren", + ["en"]="quote", + ["fr"]="citer", + ["it"]="menzione", + ["nl"]="citeer", + ["pe"]="نقل", + ["ro"]="minicitat", + }, + ["ran"]={ + ["cs"]="ran", + ["de"]="ran", + ["en"]="ran", + ["fr"]="ran", + ["it"]="ran", + ["nl"]="ran", + ["pe"]="ran", + ["ro"]="ran", + }, + ["redo"]={ + ["cs"]="opakovat", + ["de"]="wiederholen", + ["en"]="redo", + ["fr"]="refait", + ["it"]="rifai", + ["nl"]="herhaal", + ["pe"]="انجام‌دوباره", + ["ro"]="refa", + }, + ["ref"]={ + ["cs"]="ref", + ["de"]="ref", + ["en"]="ref", + ["fr"]="ref", + ["it"]="rif", + ["nl"]="ref", + ["pe"]="رج", + ["ro"]="ref", + }, + ["reference"]={ + ["cs"]="odkaz", + ["de"]="referenz", + ["en"]="reference", + ["fr"]="reference", + ["it"]="riferimento", + ["nl"]="referentie", + ["pe"]="مرجع", + ["ro"]="referinta", + }, + ["referral"]={ + ["cs"]="odkaz", + ["de"]="verweis", + ["en"]="referral", + ["fr"]="recommandation", + ["it"]="referral", + ["nl"]="kenmerk", + ["pe"]="رجوع", + ["ro"]="referit", + }, + ["referraldate"]={ + ["cs"]="odkaznadatum", + ["de"]="verweisdatum", + ["en"]="referraldate", + ["fr"]="daterecommandation", + ["it"]="datareferral", + ["nl"]="kenmerkdatum", + ["pe"]="تاریخ‌رجوع", + ["ro"]="datareferit", + }, + ["referring"]={ + ["cs"]="odkazujici", + ["de"]="referieren", + ["en"]="referring", + ["fr"]="faitreference", + ["it"]="referring", + ["nl"]="refereer", + ["pe"]="مراجعه", + ["ro"]="referring", + }, + ["remark"]={ + ["cs"]="oznaceni", + ["de"]="bemerkung", + ["en"]="remark", + ["fr"]="commentaire", + ["it"]="commento", + ["nl"]="toelichting", + ["pe"]="توجه", + ["ro"]="remarca", + }, + ["reset"]={ + ["cs"]="reset", + ["de"]="ruecksetzten", + ["en"]="reset", + ["fr"]="raz", + ["it"]="reimposta", + ["nl"]="reset", + ["pe"]="بازنشانی", + ["ro"]="reset", + }, + ["resetmarking"]={ + ["cs"]="resetznaceni", + ["de"]="ruecksetztenbeschriftung", + ["en"]="resetmarking", + ["fr"]="razmarquage", + ["it"]="reimpostamarcatura", + ["nl"]="resetmarkering", + ["pe"]="بازنشانی‌نشانه‌گذاری", + ["ro"]="reseteazamarcaje", + }, + ["resetnumber"]={ + ["cs"]="resetnumber", + ["de"]="resetnumber", + ["en"]="resetnumber", + ["fr"]="raznumero", + ["it"]="resetnumber", + ["nl"]="resetnummer", + ["pe"]="بازنشانی‌شماره", + ["ro"]="resetnumber", + }, + ["resettext"]={ + ["cs"]="resettextcontent", + ["de"]="resettextcontent", + ["en"]="resettextcontent", + ["fr"]="resettextcontent", + ["it"]="resettextcontent", + ["nl"]="resettekstinhoud", + ["pe"]="بازنشانی‌متن", + ["ro"]="resettextcontent", + }, + ["rightaligned"]={ + ["cs"]="zarovnanovpravo", + ["de"]="rechtsbuendig", + ["en"]="rightaligned", + ["fr"]="aligneadroite", + ["it"]="allineadestra", + ["nl"]="regelrechts", + ["pe"]="تنظیم‌راست", + ["ro"]="aliniatdreapta", + }, + ["rightedgedistance"]={ + ["cs"]="vzdalenostpravehookraje", + ["de"]="abstandrechterrand", + ["en"]="rightedgedistance", + ["fr"]="distanceborddroit", + ["it"]="distanzabordodestro", + ["nl"]="rechterrandafstand", + ["pe"]="فاصله‌لبه‌راست", + ["ro"]="distantacoltdreapta", + }, + ["rightedgewidth"]={ + ["cs"]="sirkapravehookraje", + ["de"]="breiterechterrand", + ["en"]="rightedgewidth", + ["fr"]="largeurborddroit", + ["it"]="ampiezzabordodestro", + ["nl"]="rechterrandbreedte", + ["pe"]="عرض‌لبه‌راست", + ["ro"]="latimecoltdreapta", + }, + ["rightmargindistance"]={ + ["cs"]="vzdalenostpravemarginalie", + ["de"]="rechtemarginalafstand", + ["en"]="rightmargindistance", + ["fr"]="distancemargedroite", + ["it"]="distanzamarginedestro", + ["nl"]="rechtermargeafstand", + ["pe"]="فاصله‌حاشیه‌راست", + ["ro"]="distantamarginedreapta", + }, + ["rightmarginwidth"]={ + ["cs"]="sirkapravemarginalie", + ["de"]="rechtemarginalbreite", + ["en"]="rightmarginwidth", + ["fr"]="largeurmargedroite", + ["it"]="ampiezzamarginedestro", + ["nl"]="rechtermargebreedte", + ["pe"]="عرض‌حاشیه‌راست", + ["ro"]="latimemarginedreapta", + }, + ["romannumerals"]={ + ["cs"]="rimskecislice", + ["de"]="roemischezahlen", + ["en"]="romannumerals", + ["fr"]="chiffresromains", + ["it"]="numeriromani", + ["nl"]="romeins", + ["pe"]="اعدادلاتین", + ["ro"]="numereromane", + }, + ["rotate"]={ + ["cs"]="otocit", + ["de"]="drehen", + ["en"]="rotate", + ["fr"]="oriente", + ["it"]="ruota", + ["nl"]="roteer", + ["pe"]="دوران", + ["ro"]="roteste", + }, + ["scale"]={ + ["cs"]="meritko", + ["de"]="format", + ["en"]="scale", + ["fr"]="echelle", + ["it"]="scala", + ["nl"]="schaal", + ["pe"]="مقیاس", + ["ro"]="scala", + }, + ["screen"]={ + ["cs"]="obrazovka", + ["de"]="bildschirm", + ["en"]="screen", + ["fr"]="ecran", + ["it"]="schermo", + ["nl"]="scherm", + ["pe"]="پرده", + ["ro"]="ecran", + }, + ["selectblocks"]={ + ["cs"]="vyberbloky", + ["de"]="waehlebloeckeaus", + ["en"]="selectblocks", + ["fr"]="selectionneblocs", + ["it"]="selezionablocchi", + ["nl"]="selecteerblokken", + ["pe"]="انتخاب‌بلوکها", + ["ro"]="selecteazablocuri", + }, + ["selectpaper"]={ + ["cs"]="vyberpapir", + ["de"]="waehlepapieraus", + ["en"]="selectpaper", + ["fr"]="selectionnepapier", + ["it"]="selezionacarta", + ["nl"]="selecteerpapier", + ["pe"]="انتخاب‌برگ", + ["ro"]="selecteazahartie", + }, + ["selectversion"]={ + ["cs"]="vyberverzi", + ["de"]="waehleversionaus", + ["en"]="selectversion", + ["fr"]="selectionneversion", + ["it"]="selezionaversione", + ["nl"]="selecteerversie", + ["pe"]="انتخاب‌نسخه", + ["ro"]="selecteazaversiune", + }, + ["setnumber"]={ + ["cs"]="setnumber", + ["de"]="setnumber", + ["en"]="setnumber", + ["fr"]="affectenumero", + ["it"]="setnumber", + ["nl"]="setnummer", + ["pe"]="تعیین‌شماره", + ["ro"]="setnumber", + }, + ["settextcontent"]={ + ["cs"]="settextcontent", + ["de"]="settext", + ["en"]="settextcontent", + ["fr"]="settext", + ["it"]="settext", + ["nl"]="steltekstinhoudin", + ["pe"]="تعیین‌محتوای‌متن", + ["ro"]="settextcontent", + }, + ["settextvariable"]={ + ["cs"]="settextvariable", + ["de"]="settextvariable", + ["en"]="settextvariable", + ["fr"]="affectevariabletexte", + ["it"]="setvariabiletesto", + ["nl"]="kentekstvariabeletoe", + ["pe"]="تعیین‌متغیر‌متن", + ["ro"]="setvariabilatext", + }, + ["setupalign"]={ + ["cs"]="nastavzarovnani", + ["de"]="stelleausrichtungein", + ["en"]="setupalign", + ["fr"]="reglealignement", + ["it"]="impostaallineamento", + ["nl"]="steluitlijnenin", + ["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", + ["en"]="setuparranging", + ["fr"]="reglearrangement", + ["it"]="impostaparranging", + ["nl"]="stelarrangerenin", + ["pe"]="بارگذاری‌ترتیب", + ["ro"]="seteazaaranjareapag", + }, + ["setupbackground"]={ + ["cs"]="nastavpozadi", + ["de"]="stellehintergrundein", + ["en"]="setupbackground", + ["fr"]="reglearriereplan", + ["it"]="impostasfondo", + ["nl"]="stelachtergrondin", + ["pe"]="بارگذاری‌پس‌زمینه", + ["ro"]="seteazafundal", + }, + ["setupbackgrounds"]={ + ["cs"]="nastavpozadi", + ["de"]="stellehintergruendeein", + ["en"]="setupbackgrounds", + ["fr"]="reglearriereplans", + ["it"]="impostasfondi", + ["nl"]="stelachtergrondenin", + ["pe"]="بارگذاری‌پس‌زمینه‌ها", + ["ro"]="seteazafundaluri", + }, + ["setupblackrules"]={ + ["cs"]="nastavcernelinky", + ["de"]="stellerechteckein", + ["en"]="setupblackrules", + ["fr"]="reglelignesnoires", + ["it"]="impostalineenere", + ["nl"]="stelblokjesin", + ["pe"]="بارگذاری‌خطهای‌سیاه", + ["ro"]="seteazaliniinegre", + }, + ["setupblank"]={ + ["cs"]="nastavpreskok", + ["de"]="stelleblankoein", + ["en"]="setupblank", + ["fr"]="definitvide", + ["it"]="impostarigovuoto", + ["nl"]="stelblankoin", + ["pe"]="بارگذاری‌خالی", + ["ro"]="seteazablanc", + }, + ["setupblock"]={ + ["cs"]="nastavblok", + ["de"]="stelleblockein", + ["en"]="setupblock", + ["fr"]="reglebloc", + ["it"]="impostablocco", + ["nl"]="stelblokin", + ["pe"]="بارگذاری‌بلوک", + ["ro"]="seteazabloc", + }, + ["setupbodyfont"]={ + ["cs"]="nastavzakladnifont", + ["de"]="stellefliesstextein", + ["en"]="setupbodyfont", + ["fr"]="reglepolicecorps", + ["it"]="impostafontdeltesto", + ["nl"]="stelkorpsin", + ["pe"]="بارگذاری‌قلم‌متن", + ["ro"]="seteazafonttext", + }, + ["setupbodyfontenvironment"]={ + ["cs"]="nastavprostredizakladnihofontu", + ["de"]="stellefliesstextumgebungein", + ["en"]="setupbodyfontenvironment", + ["fr"]="regleenvironnementpolicecorps", + ["it"]="impostaambientefontdeltesto", + ["nl"]="stelkorpsomgevingin", + ["pe"]="بارگذاری‌محیط‌قلم‌متن", + ["ro"]="seteazamediulfonttext", + }, + ["setupbottom"]={ + ["cs"]="nastavspodek", + ["de"]="stelleuntenein", + ["en"]="setupbottom", + ["fr"]="regleinf", + ["it"]="impostafondo", + ["nl"]="stelonderin", + ["pe"]="بارگذاری‌پایین", + ["ro"]="seteazajos", + }, + ["setupbottomtexts"]={ + ["cs"]="nastavdolnitexty", + ["de"]="stelletextuntenein", + ["en"]="setupbottomtexts", + ["fr"]="regletextesinf", + ["it"]="impostatestifondo", + ["nl"]="stelondertekstenin", + ["pe"]="بارگذاری‌متن‌پایین", + ["ro"]="seteazatextejos", + }, + ["setupbuffer"]={ + ["cs"]="nastavbuffer", + ["de"]="stellepufferein", + ["en"]="setupbuffer", + ["fr"]="reglebuffer", + ["it"]="impostabuffer", + ["nl"]="stelbufferin", + ["pe"]="بارگذاری‌بافر", + ["ro"]="seteazabuffer", + }, + ["setupbuttons"]={ + ["cs"]="nastavtlacitka", + ["de"]="stelleknopfein", + ["en"]="setupbuttons", + ["fr"]="regleboutons", + ["it"]="impostapulsanti", + ["nl"]="stelbuttonsin", + ["pe"]="بارگذاری‌دکمه‌ها", + ["ro"]="seteazabutoane", + }, + ["setupcapitals"]={ + ["cs"]="nastavkapitalky", + ["de"]="stelleversalienein", + ["en"]="setupcapitals", + ["fr"]="reglecapitales", + ["it"]="impostamaiuscole", + ["nl"]="stelkapitalenin", + ["pe"]="setupcapitals", + ["ro"]="seteazamajuscule", + }, + ["setupcaption"]={ + ["cs"]="nastavpopisek", + ["de"]="stellebildunterschriftein", + ["en"]="setupcaption", + ["fr"]="regleintitule", + ["it"]="impostacaption", + ["nl"]="stelblokkopjein", + ["pe"]="بارگذاری‌شرح", + ["ro"]="seteazalegenda", + }, + ["setupcaptions"]={ + ["cs"]="nastavpopisky", + ["de"]="stellebilderunterschriftein", + ["en"]="setupcaptions", + ["fr"]="regleintitules", + ["it"]="impostacaptions", + ["nl"]="stelblokkopjesin", + ["pe"]="بارگذاری‌شرحها", + ["ro"]="seteazalegendele", + }, + ["setupclipping"]={ + ["cs"]="nastavorez", + ["de"]="stelleausschnittein", + ["en"]="setupclipping", + ["fr"]="regleclipping", + ["it"]="impostaclippling", + ["nl"]="stelclipin", + ["pe"]="بارگذاری‌چیدن", + ["ro"]="seteazaclipping", + }, + ["setupcolor"]={ + ["cs"]="nastavbarvu", + ["de"]="stellefarbeein", + ["en"]="setupcolor", + ["fr"]="reglecouleur", + ["it"]="impostacolore", + ["nl"]="stelkleurin", + ["pe"]="بارگذاری‌رنگ", + ["ro"]="seteazaculoare", + }, + ["setupcolors"]={ + ["cs"]="nastavbarvy", + ["de"]="stellefarbenein", + ["en"]="setupcolors", + ["fr"]="reglecouleurs", + ["it"]="impostacolori", + ["nl"]="stelkleurenin", + ["pe"]="بارگذاری‌رنگها", + ["ro"]="seteazaculori", + }, + ["setupcolumns"]={ + ["cs"]="nastavsloupce", + ["de"]="stellespaltenein", + ["en"]="setupcolumns", + ["fr"]="reglecolonnes", + ["it"]="impostacolonne", + ["nl"]="stelkolommenin", + ["pe"]="بارگذاری‌ستونها", + ["ro"]="seteazacoloane", + }, + ["setupcolumnset"]={ + ["cs"]="setupcolumnset", + ["de"]="setupcolumnset", + ["en"]="setupcolumnset", + ["fr"]="reglejeucolonne", + ["it"]="impostagruppocolonne", + ["nl"]="stelkolomgroepin", + ["pe"]="بارگذاری‌مجموعه‌ستون", + ["ro"]="setupcolumnset", + }, + ["setupcolumnsetlines"]={ + ["cs"]="setupcolumnsetlines", + ["de"]="setupcolumnsetlines", + ["en"]="setupcolumnsetlines", + ["fr"]="setupcolumnsetlines", + ["it"]="setupcolumnsetlines", + ["nl"]="stelkolomgroepregelsin", + ["pe"]="بارگذاری‌خطهای‌مجموعه‌ستون", + ["ro"]="setupcolumnsetlines", + }, + ["setupcolumnsetstart"]={ + ["cs"]="setupcolumnsetstart", + ["de"]="setupcolumnsetstart", + ["en"]="setupcolumnsetstart", + ["fr"]="setupcolumnsetstart", + ["it"]="setupcolumnsetstart", + ["nl"]="stelkolomgroepstartin", + ["pe"]="بارگذاری‌شروع‌مجموعه‌ستون", + ["ro"]="setupcolumnsetstart", + }, + ["setupcombinations"]={ + ["cs"]="nastavspojeni", + ["de"]="stellekombinationein", + ["en"]="setupcombinations", + ["fr"]="reglecombinaisons", + ["it"]="impostacombinazioni", + ["nl"]="stelcombinatiesin", + ["pe"]="بارگذاری‌ترکیب‌ها", + ["ro"]="seteazacombinari", + }, + ["setupcombinedlist"]={ + ["cs"]="nastavkombinovanyseznam", + ["de"]="stellezusammengestelltelisteein", + ["en"]="setupcombinedlist", + ["fr"]="reglelisteimbriquee", + ["it"]="impostaelencocombinato", + ["nl"]="stelsamengesteldelijstin", + ["pe"]="بارگذاری‌لیست‌ترکیبی", + ["ro"]="seteazalistacombinata", + }, + ["setupcomment"]={ + ["cs"]="nastavkomentar", + ["de"]="stellekommentarein", + ["en"]="setupcomment", + ["fr"]="reglecommentaire", + ["it"]="impostacommento", + ["nl"]="stelcommentaarin", + ["pe"]="بارگذاری‌توضیح", + ["ro"]="seteazacomentariu", + }, + ["setupdescriptions"]={ + ["cs"]="nastavpopisy", + ["de"]="definierebeschreibungen", + ["en"]="setupdescriptions", + ["fr"]="regledescriptions", + ["it"]="impostadescrizioni", + ["nl"]="steldoordefinierenin", + ["pe"]="بارگذاری‌شرح", + ["ro"]="seteazadescriere", + }, + ["setupenumerations"]={ + ["cs"]="nastavvycty", + ["de"]="stellebeschreibungein", + ["en"]="setupenumerations", + ["fr"]="regleenumerations", + ["it"]="impostaenumerazioni", + ["nl"]="steldoornummerenin", + ["pe"]="بارگذاری‌شماره‌گذاریها", + ["ro"]="seteazaenumerare", + }, + ["setupexternalfigures"]={ + ["cs"]="nastavexterniobrazy", + ["de"]="stelleexterneabbildungenein", + ["en"]="setupexternalfigures", + ["fr"]="reglefiguresexternes", + ["it"]="impostafigureesterne", + ["nl"]="stelexternefigurenin", + ["pe"]="بارگذاری‌شکلهای‌خارجی", + ["ro"]="seteazafiguriexterne", + }, + ["setupfield"]={ + ["cs"]="nastavpole", + ["de"]="stellefeldein", + ["en"]="setupfield", + ["fr"]="reglechamp", + ["it"]="impostacampo", + ["nl"]="stelveldin", + ["pe"]="بارگذاری‌میدان", + ["ro"]="seteazacamp", + }, + ["setupfields"]={ + ["cs"]="nastavvsechnapole", + ["de"]="stellefelderin", + ["en"]="setupfields", + ["fr"]="reglechamps", + ["it"]="impostacampi", + ["nl"]="stelveldenin", + ["pe"]="بارگذاری‌میدانها", + ["ro"]="seteazacampuri", + }, + ["setupfillinlines"]={ + ["cs"]="nastavvyplnoveradky", + ["de"]="stellegefuelltezeileein", + ["en"]="setupfillinlines", + ["fr"]="regleremplitligne", + ["it"]="impostarigheriempimento", + ["nl"]="stelinvulregelsin", + ["pe"]="بارگذاری‌پرکردن‌خطها", + ["ro"]="seteazaliniiumplere", + }, + ["setupfillinrules"]={ + ["cs"]="nastavvyplnovelinky", + ["de"]="stellegefuelltesrechteckein", + ["en"]="setupfillinrules", + ["fr"]="regleremplitlignesreglees", + ["it"]="impostalineeriempimento", + ["nl"]="stelinvullijnenin", + ["pe"]="بارگذاری‌درج‌درخطها", + ["ro"]="seteazarigleumplere", + }, + ["setupfloat"]={ + ["cs"]="nastavplvouciobjekt", + ["de"]="stellegleitobjektein", + ["en"]="setupfloat", + ["fr"]="regleflottant", + ["it"]="impostaoggettomobile", + ["nl"]="stelplaatsblokin", + ["pe"]="بارگذاری‌شناور", + ["ro"]="seteazafloat", + }, + ["setupfloats"]={ + ["cs"]="nastavplvouciobjekty", + ["de"]="stellegleitobjekteein", + ["en"]="setupfloats", + ["fr"]="regleflottants", + ["it"]="impostaoggettimobili", + ["nl"]="stelplaatsblokkenin", + ["pe"]="بارگذاری‌شناورها", + ["ro"]="seteazafloats", + }, + ["setupfloatsplitting"]={ + ["cs"]="nastavdeleniplvoucichobjektu", + ["de"]="stelleplatziegeteiltegleitobjekt", + ["en"]="setupfloatsplitting", + ["fr"]="regleseparationflottant", + ["it"]="impostaspezzamentooggettomobile", + ["nl"]="stelplaatsbloksplitsenin", + ["pe"]="بارگذاری‌شکافتن‌شناورها", + ["ro"]="seteazaimpartireafloat", + }, + ["setupfooter"]={ + ["cs"]="nastavupati", + ["de"]="stellefusszeileein", + ["en"]="setupfooter", + ["fr"]="reglepdp", + ["it"]="impostapdp", + ["nl"]="stelvoetin", + ["pe"]="بارگذاری‌ته‌برگ", + ["ro"]="seteazasubsol", + }, + ["setupfootertexts"]={ + ["cs"]="nastavtextyupati", + ["de"]="stellefusszeilentextein", + ["en"]="setupfootertexts", + ["fr"]="regletextespdp", + ["it"]="impostatestipdp", + ["nl"]="stelvoettekstenin", + ["pe"]="بارگذاری‌متن‌پانوشت", + ["ro"]="seteazatextesubsol", + }, + ["setupfootnotedefinition"]={ + ["cs"]="nastavdefinicipoznamekpodcarou", + ["de"]="stellefussnotendefinitionein", + ["en"]="setupfootnotedefinition", + ["fr"]="definitnotepdp", + ["it"]="impostadefinizionenotepdp", + ["nl"]="stelvoetnootdefinitiein", + ["pe"]="بارگذاری‌تعریف‌پانوشت", + ["ro"]="seteazadefinireanotasubsol", + }, + ["setupfootnotes"]={ + ["cs"]="nastavpoznamkypodcarou", + ["de"]="stellefussnotenein", + ["en"]="setupfootnotes", + ["fr"]="reglenotepdp", + ["it"]="impostanotepdp", + ["nl"]="stelvoetnotenin", + ["pe"]="بارگذاری‌پانوشتها", + ["ro"]="seteazanotasubsol", + }, + ["setupforms"]={ + ["cs"]="setupforms", + ["de"]="setupforms", + ["en"]="setupforms", + ["fr"]="regleformulaires", + ["it"]="impostaforms", + ["nl"]="stelformulierenin", + ["pe"]="بارگذاری‌طرح", + ["ro"]="seteazaformulare", + }, + ["setupformulas"]={ + ["cs"]="nastavrovnice", + ["de"]="stelleformelnein", + ["en"]="setupformulae", + ["fr"]="regleformules", + ["it"]="impostaformule", + ["nl"]="stelformulesin", + ["pe"]="بارگذاری‌فرمولها", + ["ro"]="seteazaformule", + }, + ["setupframed"]={ + ["cs"]="nastavoramovani", + ["de"]="stelleumrahmtein", + ["en"]="setupframed", + ["fr"]="regleencadre", + ["it"]="impostaincorniciato", + ["nl"]="stelomlijndin", + ["pe"]="بارگذاری‌قالبی", + ["ro"]="seteazainconjurat", + }, + ["setupframedtexts"]={ + ["cs"]="nastavoramovanetexty", + ["de"]="stelleumrahmtetexteein", + ["en"]="setupframedtexts", + ["fr"]="setupframedtexts", + ["it"]="impostatestiincorniciati", + ["nl"]="stelkadertekstenin", + ["pe"]="بارگذاری‌متن‌قالبی", + ["ro"]="definestetexteinconjurate", + }, + ["setuphead"]={ + ["cs"]="nastavnadpis", + ["de"]="stelleueberschriftein", + ["en"]="setuphead", + ["fr"]="regletete", + ["it"]="impostatesta", + ["nl"]="stelkopin", + ["pe"]="بارگذاری‌سر", + ["ro"]="seteazatitlu", + }, + ["setupheader"]={ + ["cs"]="nastavzahlavi", + ["de"]="stellekopfzeileein", + ["en"]="setupheader", + ["fr"]="regleentete", + ["it"]="impostainstestazione", + ["nl"]="stelhoofdin", + ["pe"]="بارگذاری‌سربرگ", + ["ro"]="seteazaantet", + }, + ["setupheadertexts"]={ + ["cs"]="nastavtextyzahlavi", + ["de"]="stellekopfzeilentextein", + ["en"]="setupheadertexts", + ["fr"]="regletextesentete", + ["it"]="impostatestiintestazioni", + ["nl"]="stelhoofdtekstenin", + ["pe"]="بارگذاری‌متن‌سربرگ", + ["ro"]="seteazatexteantet", + }, + ["setupheadnumber"]={ + ["cs"]="nastavcislonadpisu", + ["de"]="stellekopfzahlein", + ["en"]="setupheadnumber", + ["fr"]="reglenumerotete", + ["it"]="impostanumerotesta", + ["nl"]="stelkopnummerin", + ["pe"]="بارگذاری‌شماره‌سر", + ["ro"]="seteazanumartitlu", + }, + ["setupheads"]={ + ["cs"]="nastavnadpisy", + ["de"]="stelleueberschriftenein", + ["en"]="setupheads", + ["fr"]="regletetes", + ["it"]="impostateste", + ["nl"]="stelkoppenin", + ["pe"]="بارگذاری‌سرها", + ["ro"]="seteazatitluri", + }, + ["setupheadtext"]={ + ["cs"]="nastavtexthlavicky", + ["de"]="stelleueberschrifttextein", + ["en"]="setupheadtext", + ["fr"]="regletextetete", + ["it"]="impostatestointestazioni", + ["nl"]="stelkoptekstin", + ["pe"]="بارگذاری‌متن‌سر", + ["ro"]="seteazatexttitlu", + }, + ["setuphyphenmark"]={ + ["cs"]="nastavdelitko", + ["de"]="stellebindestrichein", + ["en"]="setuphyphenmark", + ["fr"]="reglemarquagehyphenation", + ["it"]="impostasegnosillabazione", + ["nl"]="stelkoppeltekenin", + ["pe"]="بارگذاری‌نشانه‌شکستن", + ["ro"]="seteazaliniesilabe", + }, + ["setupindentations"]={ + ["cs"]="nastavodsazeni", + ["de"]="stelleeinzuegein", + ["en"]="setupindentations", + ["fr"]="reglealineas", + ["it"]="impostarientri", + ["nl"]="steldoorspringenin", + ["pe"]="بارگذاری‌تورفتگیها", + ["ro"]="seteazaaliniate", + }, + ["setupindenting"]={ + ["cs"]="nastavodsazovani", + ["de"]="stelleeinziehenein", + ["en"]="setupindenting", + ["fr"]="reglecomposeenalinea", + ["it"]="impostarientro", + ["nl"]="stelinspringenin", + ["pe"]="بارگذاری‌تورفتگی", + ["ro"]="seteazaaliniat", + }, + ["setupinmargin"]={ + ["cs"]="nastavmarginalie", + ["de"]="stelleinmarginalieein", + ["en"]="setupinmargin", + ["fr"]="regledansmarge", + ["it"]="impostainmargine", + ["nl"]="stelinmargein", + ["pe"]="بارگذاری‌درون‌حاشیه", + ["ro"]="seteazamarginal", + }, + ["setupinteraction"]={ + ["cs"]="nastavinterakci", + ["de"]="stelleinteraktionein", + ["en"]="setupinteraction", + ["fr"]="regleinteraction", + ["it"]="impostainterazione", + ["nl"]="stelinteractiein", + ["pe"]="بارگذاری‌پانل", + ["ro"]="seteazainteractiunea", + }, + ["setupinteractionbar"]={ + ["cs"]="nastavinterakcnilistu", + ["de"]="stelleinteraktionsbalkenein", + ["en"]="setupinteractionbar", + ["fr"]="reglebarreinteraction", + ["it"]="impostabarrainterazione", + ["nl"]="stelinteractiebalkin", + ["pe"]="بارگذاری‌میله‌پانل", + ["ro"]="seteazabarainteractiune", + }, + ["setupinteractionmenu"]={ + ["cs"]="nastavinterakcnimenu", + ["de"]="stelleinteraktionsmenueein", + ["en"]="setupinteractionmenu", + ["fr"]="reglemenuinteraction", + ["it"]="impostamenuinterazione", + ["nl"]="stelinteractiemenuin", + ["pe"]="بارگذاری‌منوی‌پانل", + ["ro"]="seteazameniuinteractiune", + }, + ["setupinteractionscreen"]={ + ["cs"]="nastavinterakcniobrazovku", + ["de"]="stelleinteraktionsbildschirmein", + ["en"]="setupinteractionscreen", + ["fr"]="regleecraninteraction", + ["it"]="impostaschermointerazione", + ["nl"]="stelinteractieschermin", + ["pe"]="بارگذاری‌پرده‌پانل", + ["ro"]="seteazaecraninteractiune", + }, + ["setupinterlinespace"]={ + ["cs"]="nastavmeziradkovoumezeru", + ["de"]="stellezeilenabstandein", + ["en"]="setupinterlinespace", + ["fr"]="regleespacementinterligne", + ["it"]="impostainterlinea", + ["nl"]="stelinterliniein", + ["pe"]="بارگذاری‌فاصله‌بین‌خط", + ["ro"]="seteazaspatiuinterliniar", + }, + ["setupitemgroup"]={ + ["cs"]="setupitemgroup", + ["de"]="setupitemgroup", + ["en"]="setupitemgroup", + ["fr"]="setupitemgroup", + ["it"]="setupitemgroup", + ["nl"]="stelitemgroepin", + ["pe"]="بارگذاری‌گروه‌آیتم", + ["ro"]="setupitemgroup", + }, + ["setupitemgroups"]={ + ["cs"]="nastavvycty", + ["de"]="stelleaufzaehlungenein", + ["en"]="setupitemizations", + ["fr"]="reglegroupeselements", + ["it"]="impostaelencazioni", + ["nl"]="stelopsommingenin", + ["pe"]="بارگذاری‌گروههای‌آیتم", + ["ro"]="setareitemization", + }, + ["setupitems"]={ + ["cs"]="nastavpolozky", + ["de"]="stellepostenein", + ["en"]="setupitems", + ["fr"]="regleelements", + ["it"]="impostaelementi", + ["nl"]="stelitemsin", + ["pe"]="بارگذاری‌آیتمها", + ["ro"]="seteazaelemente", + }, + ["setuplabeltext"]={ + ["cs"]="nastavtextpopisku", + ["de"]="stellelabeltextein", + ["en"]="setuplabeltext", + ["fr"]="reglelabeltexte", + ["it"]="impostatestoetichette", + ["nl"]="stellabeltekstin", + ["pe"]="باگذاری‌متن‌برچسب", + ["ro"]="seteazatexteticheta", + }, + ["setuplanguage"]={ + ["cs"]="nastavjazyk", + ["de"]="stellespracheein", + ["en"]="setuplanguage", + ["fr"]="reglelangue", + ["it"]="impostalingua", + ["nl"]="steltaalin", + ["pe"]="بارگذاری‌زبان", + ["ro"]="setarelimba", + }, + ["setuplayout"]={ + ["cs"]="nastavvzhled", + ["de"]="stellelayoutein", + ["en"]="setuplayout", + ["fr"]="regledisposition", + ["it"]="impostalayout", + ["nl"]="stellayoutin", + ["pe"]="بارگذاری‌طرح‌بندی", + ["ro"]="seteazaaspect", + }, + ["setuplegend"]={ + ["cs"]="nastavlegendu", + ["de"]="stellelegendeein", + ["en"]="setuplegend", + ["fr"]="reglelegende", + ["it"]="impostalegenda", + ["nl"]="stellegendain", + ["pe"]="بارگذاری‌راهنما", + ["ro"]="seteazalegenda", + }, + ["setuplinenumbering"]={ + ["cs"]="nastavcislovaniradku", + ["de"]="stellezeilennumerierungein", + ["en"]="setuplinenumbering", + ["fr"]="reglenumerotationligne", + ["it"]="impostanumerazionerighe", + ["nl"]="stelregelnummerenin", + ["pe"]="بارگذاری‌شماره‌‌گذاری‌خط", + ["ro"]="seteazanumerotarelinii", + }, + ["setuplines"]={ + ["cs"]="nastavradky", + ["de"]="stellezeilenein", + ["en"]="setuplines", + ["fr"]="reglelignes", + ["it"]="impostarighe", + ["nl"]="stelregelsin", + ["pe"]="بارگذاری‌خطها", + ["ro"]="seteazalinii", + }, + ["setuplinewidth"]={ + ["cs"]="nastavsirkucary", + ["de"]="stellelinienbreiteein", + ["en"]="setuplinewidth", + ["fr"]="regleepaisseurligne", + ["it"]="impostaampiezzariga", + ["nl"]="stellijndiktein", + ["pe"]="بارگذاری‌عرض‌خط", + ["ro"]="seteazagrosimelinie", + }, + ["setuplist"]={ + ["cs"]="nastavseznam", + ["de"]="stellelisteein", + ["en"]="setuplist", + ["fr"]="regleliste", + ["it"]="impostaelenco", + ["nl"]="stellijstin", + ["pe"]="بارگذاری‌لیست", + ["ro"]="seteazalista", + }, + ["setupmakeup"]={ + ["cs"]="nastavupravu", + ["de"]="stelleumbruchein", + ["en"]="setupmakeup", + ["fr"]="reglemakeup", + ["it"]="impostamakeup", + ["nl"]="stelopmaakin", + ["pe"]="بارگذاری‌آرایش", + ["ro"]="seteazamakeup", + }, + ["setupmarginblocks"]={ + ["cs"]="nastavmarginalniblok", + ["de"]="stellemarginalblockein", + ["en"]="setupmarginblocks", + ["fr"]="regleblocmarge", + ["it"]="impostablocchimargine", + ["nl"]="stelmargeblokkenin", + ["pe"]="بارگذاری‌بلوکهای‌حاشیه", + ["ro"]="seteazablocurimarginale", + }, + ["setupmarginrules"]={ + ["cs"]="nastavmarginalnilinky", + ["de"]="stellemarginallinieein", + ["en"]="setupmarginrules", + ["fr"]="reglemargereglee", + ["it"]="impostalineemargine", + ["nl"]="stelkantlijnin", + ["pe"]="بارگذاری‌خطهای‌حاشیه", + ["ro"]="seteazaliniimargine", + }, + ["setupmarking"]={ + ["cs"]="nastavznaceni", + ["de"]="stellebeschriftungein", + ["en"]="setupmarking", + ["fr"]="reglemarquage", + ["it"]="impostamarcatura", + ["nl"]="stelmarkeringin", + ["pe"]="بارگذاری‌نشانه‌گذاری", + ["ro"]="seteazamarcaje", + }, + ["setupmathalignment"]={ + ["cs"]="setupmathalignment", + ["de"]="setupmathalignment", + ["en"]="setupmathalignment", + ["fr"]="setupmathalignment", + ["it"]="setupmathalignment", + ["nl"]="stelwiskundeuitlijnenin", + ["pe"]="بارگذاری‌تنظیم‌ریاضی", + ["ro"]="setupmathalignment", + }, + ["setupnarrower"]={ + ["cs"]="nastavzuzeni", + ["de"]="stelleengerein", + ["en"]="setupnarrower", + ["fr"]="reglecompoetroite", + ["it"]="impostapiustretto", + ["nl"]="stelsmallerin", + ["pe"]="بارگذاری‌باریکتر", + ["ro"]="seteazaingust", + }, + ["setupnumber"]={ + ["cs"]="setupnumber", + ["de"]="setupnumber", + ["en"]="setupnumber", + ["fr"]="reglenumero", + ["it"]="impostanumerazione", + ["nl"]="stelnummerin", + ["pe"]="بارگذاری‌شماره", + ["ro"]="setupnumber", + }, + ["setupnumbering"]={ + ["cs"]="nastavcislovani", + ["de"]="stellenummerierungein", + ["en"]="setupnumbering", + ["fr"]="reglenumerotation", + ["it"]="impostanumerazione", + ["nl"]="stelnummerenin", + ["pe"]="بارگذاری‌شماره‌گذاری", + ["ro"]="seteazanumerotare", + }, + ["setupoppositeplacing"]={ + ["cs"]="nastavumisteniprotejsku", + ["de"]="stellegegenueberplatzierenein", + ["en"]="setupoppositeplacing", + ["fr"]="regleplacementopposition", + ["it"]="impostaposizionamentoopposti", + ["nl"]="stelnaastplaatsenin", + ["pe"]="بارگذاری‌درج‌مخالف", + ["ro"]="seteazaplasareaopozita", + }, + ["setupoutput"]={ + ["cs"]="nastavvystup", + ["de"]="stelleausgabeein", + ["en"]="setupoutput", + ["fr"]="reglesortie", + ["it"]="impostaoutput", + ["nl"]="steluitvoerin", + ["pe"]="بارگذاری‌خروجی", + ["ro"]="setareoutput", + }, + ["setuppagecomment"]={ + ["cs"]="nastavkomentarstrany", + ["de"]="stelleseitenkommentarein", + ["en"]="setuppagecomment", + ["fr"]="reglecommentairepage", + ["it"]="impostacommentopagina", + ["nl"]="stelpaginacommentaarin", + ["pe"]="بارگذاری‌توضیح‌صفحه", + ["ro"]="seteazacomentariupagina", + }, + ["setuppagenumber"]={ + ["cs"]="nastavcislostrany", + ["de"]="stelleseitennummerein", + ["en"]="setuppagenumber", + ["fr"]="reglenumeropage", + ["it"]="impostanumeropagina", + ["nl"]="stelpaginanummerin", + ["pe"]="بارگذاری‌شماره‌صفحه", + ["ro"]="seteazanumarpagina", + }, + ["setuppagenumbering"]={ + ["cs"]="nastavcislovanistran", + ["de"]="stelleseitennummeriernungein", + ["en"]="setuppagenumbering", + ["fr"]="reglenumerotationpage", + ["it"]="impostanumerazionepagina", + ["nl"]="stelpaginanummeringin", + ["pe"]="بارگذاری‌شماره‌گذاری‌صفحه", + ["ro"]="seteazanumerotarepagina", + }, + ["setuppagetransitions"]={ + ["cs"]="nastavprechodstrany", + ["de"]="stelleseitenuebergangein", + ["en"]="setuppagetransitions", + ["fr"]="regletransitionspage", + ["it"]="impostatransizionepagina", + ["nl"]="stelpaginaovergangenin", + ["pe"]="بارگذاری‌گذارصفحه", + ["ro"]="seteazatranzitiepagina", + }, + ["setuppalet"]={ + ["cs"]="nastavpaletu", + ["de"]="stellepaletteein", + ["en"]="setuppalet", + ["fr"]="reglepalette", + ["it"]="impostatavolozza", + ["nl"]="stelpaletin", + ["pe"]="بارگذاری‌لوح", + ["ro"]="seteazapaleta", + }, + ["setuppaper"]={ + ["cs"]="setuppaper", + ["de"]="setuppaper", + ["en"]="setuppaper", + ["fr"]="reglepapier", + ["it"]="setuppaper", + ["nl"]="stelpapierin", + ["pe"]="بارگذاری‌برگ", + ["ro"]="setuppaper", + }, + ["setuppapersize"]={ + ["cs"]="nastavvelikostpapiru", + ["de"]="stellepapierformatein", + ["en"]="setuppapersize", + ["fr"]="regletaillepapier", + ["it"]="impostadimensionicarta", + ["nl"]="stelpapierformaatin", + ["pe"]="بارگذاری‌اندازه‌برگ", + ["ro"]="seteazadimensiunihartie", + }, + ["setupparagraphnumbering"]={ + ["cs"]="nastavcislovaniodstavcu", + ["de"]="stelleabsatznummerierungein", + ["en"]="setupparagraphnumbering", + ["fr"]="reglenumerotationparagraphe", + ["it"]="impostanumerazionecapoversi", + ["nl"]="stelparagraafnummerenin", + ["pe"]="بارگذاری‌شماره‌گذاری‌پاراگراف", + ["ro"]="seteazanumerotareparagrafe", + }, + ["setupparagraphs"]={ + ["cs"]="nastavodstavce", + ["de"]="stelleabsaetzeein", + ["en"]="setupparagraphs", + ["fr"]="regleparagraphes", + ["it"]="impostacapoversi", + ["nl"]="stelalineasin", + ["pe"]="بارگذاری‌پاراگرافها", + ["ro"]="seteazaparagrafe", + }, + ["setupplacement"]={ + ["cs"]="setupplacement", + ["de"]="setupplacement", + ["en"]="setupplacement", + ["fr"]="setupplacement", + ["it"]="setupplacement", + ["nl"]="stelplaatsin", + ["pe"]="بارگذاری‌جانشانی", + ["ro"]="setupplacement", + }, + ["setuppositioning"]={ + ["cs"]="nastavumistovani", + ["de"]="stellepositionierenein", + ["en"]="setuppositioning", + ["fr"]="reglepositionnement", + ["it"]="impostaposizionamento", + ["nl"]="stelpositionerenin", + ["pe"]="بارگذاری‌مکان‌گذاری", + ["ro"]="setarepozitie", + }, + ["setupprofiles"]={ + ["cs"]="nastavprofily", + ["de"]="stelleprofilein", + ["en"]="setupprofiles", + ["fr"]="regleprofils", + ["it"]="impostaprofili", + ["nl"]="stelprofielenin", + ["pe"]="بارگذاری‌پروفایلها", + ["ro"]="seteazaprofile", + }, + ["setupprograms"]={ + ["cs"]="nastavprogramy", + ["de"]="stelleprogrammein", + ["en"]="setupprograms", + ["fr"]="regleprogrammes", + ["it"]="impostaprogrammi", + ["nl"]="stelprogrammasin", + ["pe"]="بارگذاری‌برنامه‌ها", + ["ro"]="seteazaprograme", + }, + ["setuppublications"]={ + ["cs"]="nastavpublikace", + ["de"]="stellepublikationein", + ["en"]="setuppublications", + ["fr"]="reglepublications", + ["it"]="impostapubblicazioni", + ["nl"]="stelpublicatiesin", + ["pe"]="بارگذاری‌نشرها", + ["ro"]="seteazapublicatii", + }, + ["setupquote"]={ + ["cs"]="nastavcitaci", + ["de"]="stellezitierenein", + ["en"]="setupquote", + ["fr"]="demarreciter", + ["it"]="impostamenzione", + ["nl"]="stelciterenin", + ["pe"]="بارگذاری‌نقل", + ["ro"]="seteazaminicitat", + }, + ["setupreferencelist"]={ + ["cs"]="nastavseznamodkazu", + ["de"]="stellereferenzlisteein", + ["en"]="setupreferencelist", + ["fr"]="reglelistereference", + ["it"]="impostalistariferimenti", + ["nl"]="stelreferentielijstin", + ["pe"]="بارگذاری‌لیست‌مرجع", + ["ro"]="seteazalistareferinte", + }, + ["setupreferencing"]={ + ["cs"]="nastavodkazovani", + ["de"]="stellereferenzierenein", + ["en"]="setupreferencing", + ["fr"]="reglereferencage", + ["it"]="impostariferimento", + ["nl"]="stelrefererenin", + ["pe"]="بارگذاری‌ارجاع", + ["ro"]="seteazareferinte", + }, + ["setupregister"]={ + ["cs"]="nastavrejstrik", + ["de"]="stelleregisterein", + ["en"]="setupregister", + ["fr"]="regleregistre", + ["it"]="impostaregistro", + ["nl"]="stelregisterin", + ["pe"]="بارگذاری‌ثبت", + ["ro"]="seteazaregistru", + }, + ["setuprotate"]={ + ["cs"]="nastavotoceni", + ["de"]="stelledrehenein", + ["en"]="setuprotate", + ["fr"]="regleoriente", + ["it"]="impostarotazione", + ["nl"]="stelroterenin", + ["pe"]="بارگذاری‌دوران", + ["ro"]="seteazarotare", + }, + ["setuprule"]={ + ["cs"]="setuprule", + ["de"]="setuprule", + ["en"]="setuprule", + ["fr"]="regleregle", + ["it"]="impostalinea", + ["nl"]="stellijnin", + ["pe"]="بارگذاری‌خط", + ["ro"]="seteazarigla", + }, + ["setups"]={ + ["cs"]="nastaveni", + ["de"]="einstellungen", + ["en"]="setups", + ["fr"]="reglages", + ["it"]="impostazioni", + ["nl"]="instellingen", + ["pe"]="بارگذاریها", + ["ro"]="setari", + }, + ["setupscreens"]={ + ["cs"]="nastavrastr", + ["de"]="stellerasterein", + ["en"]="setupscreens", + ["fr"]="regleecrans", + ["it"]="impostaschermi", + ["nl"]="stelrastersin", + ["pe"]="بارگذاری‌پرده‌ها", + ["ro"]="seteazaecrane", + }, + ["setupsection"]={ + ["cs"]="nastavsekci", + ["de"]="stelleabschnittein", + ["en"]="setupsection", + ["fr"]="reglesection", + ["it"]="impostasezione", + ["nl"]="stelsectiein", + ["pe"]="بارگذاری‌بخش", + ["ro"]="seteazasectiune", + }, + ["setupsectionblock"]={ + ["cs"]="nastavbloksekce", + ["de"]="stelleabschnittsblockein", + ["en"]="setupsectionblock", + ["fr"]="regleblocsection", + ["it"]="impostabloccosezione", + ["nl"]="stelsectieblokin", + ["pe"]="بارگذاری‌بلوک‌بخش", + ["ro"]="seteazablocsectiune", + }, + ["setupsorting"]={ + ["cs"]="nastavtrideni", + ["de"]="stellesortierenein", + ["en"]="setupsorting", + ["fr"]="regletri", + ["it"]="impostaordinamento", + ["nl"]="stelsorterenin", + ["pe"]="بارگذاری‌ترتیب", + ["ro"]="seteazasortare", + }, + ["setupspacing"]={ + ["cs"]="nastavradkovani", + ["de"]="stellespatiumein", + ["en"]="setupspacing", + ["fr"]="regleespacement", + ["it"]="impostaspaziatura", + ["nl"]="stelspatieringin", + ["pe"]="بارگذاری‌فضا‌گذاری", + ["ro"]="seteazaspatiu", + }, + ["setupstartstop"]={ + ["cs"]="setupstartstop", + ["de"]="setupstartstop", + ["en"]="setupstartstop", + ["fr"]="regledemarrestoppe", + ["it"]="impostainiziatermina", + ["nl"]="stelstartstopin", + ["pe"]="بارگذاری‌شروع‌پایان", + ["ro"]="setupstartstop", + }, + ["setupstrut"]={ + ["cs"]="setupstrut", + ["de"]="setupstrut", + ["en"]="setupstrut", + ["fr"]="reglestrut", + ["it"]="impostastrut", + ["nl"]="stelstrutin", + ["pe"]="بارگذاری‌بست", + ["ro"]="seteazastrut", + }, + ["setupsubpagenumber"]={ + ["cs"]="nastavpodcislostrany", + ["de"]="stelleunterseitennummerein", + ["en"]="setupsubpagenumber", + ["fr"]="reglesousnumeropage", + ["it"]="impostanumerosottopagina", + ["nl"]="stelsubpaginanummerin", + ["pe"]="بارگذاری‌شماره‌زیرصفحه", + ["ro"]="seteazanumarsubpagina", + }, + ["setupsymbolset"]={ + ["cs"]="nastavsadusymbolu", + ["de"]="stellesymbolsetein", + ["en"]="setupsymbolset", + ["fr"]="reglejeusymboles", + ["it"]="impostasetsimboli", + ["nl"]="stelsymboolsetin", + ["pe"]="بارگذاری‌مجموعه‌نماد", + ["ro"]="seteazasimbol", + }, + ["setupsynchronization"]={ + ["cs"]="nastavsynchronizaci", + ["de"]="stellesynchronisationein", + ["en"]="setupsynchronization", + ["fr"]="reglesynchronisation", + ["it"]="impostasincronizzazione", + ["nl"]="stelsynchronisatiein", + ["pe"]="بارگذاری‌تطابق", + ["ro"]="setaresincronizare", + }, + ["setupsynchronizationbar"]={ + ["cs"]="nastavsynchronizacnilistu", + ["de"]="stellesynchronisationsbalkenein", + ["en"]="setupsynchronizationbar", + ["fr"]="reglebarresynchronisation", + ["it"]="impostabarrasincronizzazione", + ["nl"]="stelsynchronisatiebalkin", + ["pe"]="بارگذاری‌میله‌تطابق", + ["ro"]="setarebarasincronizare", + }, + ["setupsynonyms"]={ + ["cs"]="nastavsynonyma", + ["de"]="stellesynonymein", + ["en"]="setupsynonyms", + ["fr"]="reglesynonymes", + ["it"]="impostasinonimi", + ["nl"]="stelsynoniemenin", + ["pe"]="بارگذاری‌مترادفها", + ["ro"]="seteazasinonime", + }, + ["setupsystem"]={ + ["cs"]="nastavsystem", + ["de"]="stellesystemein", + ["en"]="setupsystem", + ["fr"]="reglesysteme", + ["it"]="impostasistema", + ["nl"]="stelsysteemin", + ["pe"]="بارگذاری‌سیستم", + ["ro"]="seteazasistem", + }, + ["setuptab"]={ + ["cs"]="nastavtab", + ["de"]="stelletabein", + ["en"]="setuptab", + ["fr"]="regletab", + ["it"]="impostatab", + ["nl"]="steltabin", + ["pe"]="بارگذاری‌تب", + ["ro"]="seteazatab", + }, + ["setuptables"]={ + ["cs"]="nastavtabulky", + ["de"]="stelletabellenein", + ["en"]="setuptables", + ["fr"]="regletableaux", + ["it"]="impostatabelle", + ["nl"]="steltabellenin", + ["pe"]="بارگذاری‌جدولها", + ["ro"]="seteazatabele", + }, + ["setuptabulate"]={ + ["cs"]="nastavtabelaci", + ["de"]="stelletabulatorein", + ["en"]="setuptabulate", + ["fr"]="regletabulation", + ["it"]="impostatabulato", + ["nl"]="steltabulatiein", + ["pe"]="بارگذاری‌جدول‌بندی", + ["ro"]="seteazatabulatori", + }, + ["setuptext"]={ + ["cs"]="nastavtext", + ["de"]="stelletextein", + ["en"]="setuptext", + ["fr"]="regletexte", + ["it"]="impostatesto", + ["nl"]="steltekstin", + ["pe"]="بارگذاری‌متن", + ["ro"]="seteazatext", + }, + ["setuptextposition"]={ + ["cs"]="setuptextposition", + ["de"]="setuptextposition", + ["en"]="setuptextposition", + ["fr"]="reglepositiontexte", + ["it"]="impostaposizionetesto", + ["nl"]="steltekstpositiein", + ["pe"]="بارگذاری‌مکان‌متن", + ["ro"]="seteazapozitietext", + }, + ["setuptextrules"]={ + ["cs"]="nastavtextovelinky", + ["de"]="stelletextumrissein", + ["en"]="setuptextrules", + ["fr"]="reglelignesreglestexte", + ["it"]="impostalineetesto", + ["nl"]="steltekstlijnenin", + ["pe"]="بارگذاری‌خطهای‌متن", + ["ro"]="seteazarigletext", + }, + ["setuptexttexts"]={ + ["cs"]="nastavtexttexty", + ["de"]="stelletexttexteein", + ["en"]="setuptexttexts", + ["fr"]="regletextestexte", + ["it"]="impostatestotesti", + ["nl"]="stelteksttekstenin", + ["pe"]="بارگذاری‌متن‌متنها", + ["ro"]="seteazatextetext", + }, + ["setuptextvariable"]={ + ["cs"]="setuptextvariable", + ["de"]="setuptextvariable", + ["en"]="setuptextvariable", + ["fr"]="reglevariabletexte", + ["it"]="impostavariabiletesto", + ["nl"]="steltekstvariabelein", + ["pe"]="بارگذاری‌متغیر‌متن", + ["ro"]="seteazavariabilatext", + }, + ["setupthinrules"]={ + ["cs"]="nastavtenkelinky", + ["de"]="stelleduennerumrissein", + ["en"]="setupthinrules", + ["fr"]="regletraitsfins", + ["it"]="impostalineesottili", + ["nl"]="steldunnelijnenin", + ["pe"]="بارگذاری‌خطها‌ی‌نازک", + ["ro"]="seteazaliniesubtire", + }, + ["setuptolerance"]={ + ["cs"]="nastavtoleranci", + ["de"]="stelletoleranzein", + ["en"]="setuptolerance", + ["fr"]="regletolerance", + ["it"]="impostatolleranza", + ["nl"]="steltolerantiein", + ["pe"]="بارگذاری‌بردباری", + ["ro"]="seteazatoleranta", + }, + ["setuptop"]={ + ["cs"]="nastavhorejsek", + ["de"]="stellenobenein", + ["en"]="setuptop", + ["fr"]="reglesup", + ["it"]="impostacima", + ["nl"]="stelbovenin", + ["pe"]="بارگذاری‌بالا", + ["ro"]="seteazasus", + }, + ["setuptoptexts"]={ + ["cs"]="nastavhornitexty", + ["de"]="stelletextobenein", + ["en"]="setuptoptexts", + ["fr"]="regletextessup", + ["it"]="impostatesticima", + ["nl"]="stelboventekstenin", + ["pe"]="بارگذاری‌متنهای‌بالا", + ["ro"]="seteazatextesus", + }, + ["setuptype"]={ + ["cs"]="nastavtype", + ["de"]="stelletipein", + ["en"]="setuptype", + ["fr"]="regletype", + ["it"]="impostatype", + ["nl"]="steltypein", + ["pe"]="بارگذاری‌تایپ", + ["ro"]="seteazatype", + }, + ["setuptyping"]={ + ["cs"]="nastavopis", + ["de"]="stelletippenein", + ["en"]="setuptyping", + ["fr"]="regledactylo", + ["it"]="impostatyping", + ["nl"]="steltypenin", + ["pe"]="بارگذاری‌تایپ‌کردن", + ["ro"]="seteazatyping", + }, + ["setupunderbar"]={ + ["cs"]="nastavpodtrzeni", + ["de"]="stelleunterstreichenein", + ["en"]="setupunderbar", + ["fr"]="reglesouslignage", + ["it"]="impostasottolinea", + ["nl"]="stelonderstrepenin", + ["pe"]="بارگذاری‌میله‌زیر", + ["ro"]="seteazasublinie", + }, + ["setupurl"]={ + ["cs"]="nastavurl", + ["de"]="stelleurlein", + ["en"]="setupurl", + ["fr"]="regleurl", + ["it"]="impostaurl", + ["nl"]="stelurlin", + ["pe"]="setupurl", + ["ro"]="seteazaurl", + }, + ["setupversions"]={ + ["cs"]="nastavverze", + ["de"]="stelleversionein", + ["en"]="setupversions", + ["fr"]="regleversions", + ["it"]="impostaversioni", + ["nl"]="stelversiesin", + ["pe"]="بارگذاری‌نسخه‌ها", + ["ro"]="seteazaversiuni", + }, + ["setupwhitespace"]={ + ["cs"]="nastavbilamista", + ["de"]="stellezwischenraumein", + ["en"]="setupwhitespace", + ["fr"]="regleespaceblanc", + ["it"]="impostaspaziobianco", + ["nl"]="stelwitruimtein", + ["pe"]="بارگذاری‌فضای‌سفید", + ["ro"]="seteazaspatiualb", + }, + ["showbodyfont"]={ + ["cs"]="ukazzakladnifont", + ["de"]="zeigefliesstext", + ["en"]="showbodyfont", + ["fr"]="montrepolicecorps", + ["it"]="mostrafontdeltesto", + ["nl"]="toonkorps", + ["pe"]="نمایش‌قلم‌بدنه", + ["ro"]="afiseazafonttext", + }, + ["showbodyfontenvironment"]={ + ["cs"]="ukazpostredizakladnihofontu", + ["de"]="zeigefliesstextumgebung", + ["en"]="showbodyfontenvironment", + ["fr"]="montreenvironnementpolicecorps", + ["it"]="mostraambientefontdeltesto", + ["nl"]="toonkorpsomgeving", + ["pe"]="نمایش‌محیط‌قلم‌بدنه", + ["ro"]="afiseazamediufonttext", + }, + ["showcolor"]={ + ["cs"]="ukazbarvu", + ["de"]="zeigefarbe", + ["en"]="showcolor", + ["fr"]="montrecouleur", + ["it"]="mostracolore", + ["nl"]="toonkleur", + ["pe"]="نمایش‌رنگ", + ["ro"]="afiseazaculoare", + }, + ["showcolorgroup"]={ + ["cs"]="ukazskupinubarev", + ["de"]="zeigefarbengruppe", + ["en"]="showcolorgroup", + ["fr"]="montregroupecouleur", + ["it"]="mostragruppocolori", + ["nl"]="toonkleurgroep", + ["pe"]="نمایش‌گروه‌رنگ", + ["ro"]="afiseazagrupculoare", + }, + ["showexternalfigures"]={ + ["cs"]="ukazexterniobrazy", + ["de"]="zeigeexterneabbildungen", + ["en"]="showexternalfigures", + ["fr"]="montrefiguresexternes", + ["it"]="mostrafiguresterne", + ["nl"]="toonexternefiguren", + ["pe"]="نمایش‌شکلهای‌خارجی", + ["ro"]="afiseazafiguriexterne", + }, + ["showfields"]={ + ["cs"]="ukazpole", + ["de"]="zeigefelder", + ["en"]="showfields", + ["fr"]="montrechamps", + ["it"]="mostracampi", + ["nl"]="toonvelden", + ["pe"]="نمایش‌میدانها", + ["ro"]="afiseazacampuri", + }, + ["showframe"]={ + ["cs"]="ukazramecek", + ["de"]="zeigerahmen", + ["en"]="showframe", + ["fr"]="montrecadre", + ["it"]="mostracornice", + ["nl"]="toonkader", + ["pe"]="نمایش‌قالب", + ["ro"]="afiseazarama", + }, + ["showgrid"]={ + ["cs"]="ukazmrizku", + ["de"]="zeigegitter", + ["en"]="showgrid", + ["fr"]="montregrille", + ["it"]="mostragriglia", + ["nl"]="toongrid", + ["pe"]="نمایش‌توری", + ["ro"]="afiseazagrid", + }, + ["showlayout"]={ + ["cs"]="ukazvzhled", + ["de"]="zeigelayout", + ["en"]="showlayout", + ["fr"]="montredisposition", + ["it"]="mostralyout", + ["nl"]="toonlayout", + ["pe"]="نمایش‌طرح‌بندی", + ["ro"]="afiseazaaspect", + }, + ["showmakeup"]={ + ["cs"]="ukazupravu", + ["de"]="zeigeumbruch", + ["en"]="showmakeup", + ["fr"]="montremakeup", + ["it"]="mostramakeup", + ["nl"]="toonopmaak", + ["pe"]="نمایش‌آرایش", + ["ro"]="afiseazamakeup", + }, + ["showpalet"]={ + ["cs"]="ukazpaletu", + ["de"]="zeigepalette", + ["en"]="showpalet", + ["fr"]="montrepalette", + ["it"]="mostratavolozza", + ["nl"]="toonpalet", + ["pe"]="نمایش‌لوح", + ["ro"]="afiseazapaleta", + }, + ["showprint"]={ + ["cs"]="ukazvytisk", + ["de"]="zeigedruck", + ["en"]="showprint", + ["fr"]="montreedition", + ["it"]="mostrastampa", + ["nl"]="toonprint", + ["pe"]="نمایش‌چاپ", + ["ro"]="afiseazatiparire", + }, + ["showsetups"]={ + ["cs"]="ukaznastaveni", + ["de"]="zeigeeinstellungen", + ["en"]="showsetups", + ["fr"]="montrereglages", + ["it"]="mostraimpostazioni", + ["nl"]="tooninstellingen", + ["pe"]="نمایش‌بارگذاریها", + ["ro"]="afiseazasetari", + }, + ["showstruts"]={ + ["cs"]="ukazpodpery", + ["de"]="zeigestruts", + ["en"]="showstruts", + ["fr"]="montrestruts", + ["it"]="mostrastruts", + ["nl"]="toonstruts", + ["pe"]="نمایش‌بستها", + ["ro"]="afiseazastruts", + }, + ["showsymbolset"]={ + ["cs"]="ukazsadusymbolu", + ["de"]="showsymbolset", + ["en"]="showsymbolset", + ["fr"]="montrejeusymboles", + ["it"]="mostrasetsimboli", + ["nl"]="toonsymboolset", + ["pe"]="نمایش‌مجموعه‌علامت", + ["ro"]="afiseazasetsimboluri", + }, + ["smallcapped"]={ + ["cs"]="kap", + ["de"]="kap", + ["en"]="cap", + ["fr"]="cap", + ["it"]="cap", + ["nl"]="kap", + ["pe"]="cap", + ["ro"]="kap", + }, + ["someline"]={ + ["cs"]="nejakyradek", + ["de"]="einezeile", + ["en"]="someline", + ["fr"]="uneligne", + ["it"]="qualcheriga", + ["nl"]="eenregel", + ["pe"]="یک‌خط", + ["ro"]="olinie", + }, + ["somewhere"]={ + ["cs"]="nekde", + ["de"]="irgendwo", + ["en"]="somewhere", + ["fr"]="qqpart", + ["it"]="daqualcheparte", + ["nl"]="ergens", + ["pe"]="یک‌جا", + ["ro"]="undeva", + }, + ["space"]={ + ["cs"]="mezera", + ["de"]="spatium", + ["en"]="space", + ["fr"]="espace", + ["it"]="spazio", + ["nl"]="spatie", + ["pe"]="فضا", + ["ro"]="spatiu", + }, + ["splitfloat"]={ + ["cs"]="rozdelplvouciobjekt", + ["de"]="teilegleitobjekt", + ["en"]="splitfloat", + ["fr"]="separeflottant", + ["it"]="spezzaoggettomobile", + ["nl"]="splitsplaatsblok", + ["pe"]="شکافتن‌شناور", + ["ro"]="impartefloat", + }, + ["startalignment"]={ + ["cs"]="startzarovnavani", + ["de"]="startausrichtung", + ["en"]="startalignment", + ["fr"]="demarrealignement", + ["it"]="iniziaallineamento", + ["nl"]="startuitlijnen", + ["pe"]="شروع‌تنظیم", + ["ro"]="startaliniere", + }, + ["startbackground"]={ + ["cs"]="startpozadi", + ["de"]="starthintergrund", + ["en"]="startbackground", + ["fr"]="demarrearriereplan", + ["it"]="iniziasfondo", + ["nl"]="startachtergrond", + ["pe"]="شروع‌پس‌زمینه", + ["ro"]="startfundal", + }, + ["startcoding"]={ + ["cs"]="startkodovani", + ["de"]="startkodierung", + ["en"]="startcoding", + ["fr"]="demarrecodage", + ["it"]="iniziacodifica", + ["nl"]="startcodering", + ["pe"]="شروع‌کد", + ["ro"]="startcodificare", + }, + ["startcolor"]={ + ["cs"]="startbarva", + ["de"]="startfarbe", + ["en"]="startcolor", + ["fr"]="demarrecouleur", + ["it"]="iniziacolore", + ["nl"]="startkleur", + ["pe"]="شروع‌رنگ", + ["ro"]="startculoare", + }, + ["startcolumnmakeup"]={ + ["cs"]="startcolumnmakeup", + ["de"]="startcolumnmakeup", + ["en"]="startcolumnmakeup", + ["fr"]="startcolumnmakeup", + ["it"]="startcolumnmakeup", + ["nl"]="startkolomopmaak", + ["pe"]="شروع‌آرایش‌ستون", + ["ro"]="startcolumnmakeup", + }, + ["startcolumns"]={ + ["cs"]="startsloupce", + ["de"]="startspalten", + ["en"]="startcolumns", + ["fr"]="demarrecolonnes", + ["it"]="iniziacolonne", + ["nl"]="startkolommen", + ["pe"]="شروع‌ستونها", + ["ro"]="startcoloane", + }, + ["startcolumnset"]={ + ["cs"]="startcolumnset", + ["de"]="startcolumnset", + ["en"]="startcolumnset", + ["fr"]="demarrejeucolonne", + ["it"]="iniziagruppocolonne", + ["nl"]="startkolomgroep", + ["pe"]="شروع‌مجموعه‌ستون", + ["ro"]="startcolumnset", + }, + ["startcombination"]={ + ["cs"]="startspojeni", + ["de"]="startkombination", + ["en"]="startcombination", + ["fr"]="demarrecombinaison", + ["it"]="iniziacombinazione", + ["nl"]="startcombinatie", + ["pe"]="شروع‌ترکیب", + ["ro"]="startcombinare", + }, + ["startcomponent"]={ + ["cs"]="startkomponenta", + ["de"]="startkomponente", + ["en"]="startcomponent", + ["fr"]="demarrecomposant", + ["it"]="iniziacomponente", + ["nl"]="startonderdeel", + ["pe"]="شروع‌مولفه", + ["ro"]="startcomponenta", + }, + ["startdocument"]={ + ["cs"]="startdokument", + ["de"]="startdokument", + ["en"]="startdocument", + ["fr"]="demarredocument", + ["it"]="iniziadocumento", + ["nl"]="startdocument", + ["pe"]="شروع‌نوشتار", + ["ro"]="startdocument", + }, + ["startenvironment"]={ + ["cs"]="startprostredi", + ["de"]="startumgebung", + ["en"]="startenvironment", + ["fr"]="demarreenvironement", + ["it"]="iniziaambiente", + ["nl"]="startomgeving", + ["pe"]="شروع‌محیط", + ["ro"]="startmediu", + }, + ["startfigure"]={ + ["cs"]="startobraz", + ["de"]="startabbildung", + ["en"]="startfigure", + ["fr"]="demarrefigure", + ["it"]="iniziafigura", + ["nl"]="startfiguur", + ["pe"]="شروع‌شکل", + ["ro"]="startfigura", + }, + ["startglobal"]={ + ["cs"]="startglobalni", + ["de"]="startglobal", + ["en"]="startglobal", + ["fr"]="demarreglobal", + ["it"]="iniziaglobale", + ["nl"]="startglobaal", + ["pe"]="شروع‌سراسری", + ["ro"]="startglobal", + }, + ["startline"]={ + ["cs"]="startradek", + ["de"]="startzeile", + ["en"]="startline", + ["fr"]="demarreligne", + ["it"]="iniziariga", + ["nl"]="startregel", + ["pe"]="شروع‌خط", + ["ro"]="startlinie", + }, + ["startlinecorrection"]={ + ["cs"]="startkorekceradku", + ["de"]="startzeilenkorrektur", + ["en"]="startlinecorrection", + ["fr"]="demarrecorrectionligne", + ["it"]="iniziacorrezioneriga", + ["nl"]="startregelcorrectie", + ["pe"]="شروع‌تصحیح‌خط", + ["ro"]="startcorectielinie", + }, + ["startlinenumbering"]={ + ["cs"]="startcislovaniradku", + ["de"]="startzeilennumerierung", + ["en"]="startlinenumbering", + ["fr"]="demarrenumerotationligne", + ["it"]="inizianumerazionerighe", + ["nl"]="startregelnummeren", + ["pe"]="شروع‌شماره‌گذاری‌خط", + ["ro"]="startnumerotarelinii", + }, + ["startlines"]={ + ["cs"]="startradky", + ["de"]="startzeilen", + ["en"]="startlines", + ["fr"]="demarrelignes", + ["it"]="iniziarighe", + ["nl"]="startregels", + ["pe"]="شروع‌خطها", + ["ro"]="startlinii", + }, + ["startlocal"]={ + ["cs"]="startlokalni", + ["de"]="startlokal", + ["en"]="startlocal", + ["fr"]="demarrelocal", + ["it"]="inizialocale", + ["nl"]="startlokaal", + ["pe"]="شروع‌موضعی", + ["ro"]="startlocal", + }, + ["startlocalfootnotes"]={ + ["cs"]="startlokalnipoznamkypodcarou", + ["de"]="startlokalefussnoten", + ["en"]="startlocalfootnotes", + ["fr"]="demarrenotespdplocales", + ["it"]="inizianotepdplocali", + ["nl"]="startlokalevoetnoten", + ["pe"]="شروع‌پانوشتهای‌موضعی", + ["ro"]="startnotesubsollocale", + }, + ["startmakeup"]={ + ["cs"]="startuprava", + ["de"]="startumbruch", + ["en"]="startmakeup", + ["fr"]="demarremakeup", + ["it"]="iniziamakeup", + ["nl"]="startopmaak", + ["pe"]="شروع‌آرایش", + ["ro"]="startmakeup", + }, + ["startmarginblock"]={ + ["cs"]="startmarginalniblok", + ["de"]="startmarginalblock", + ["en"]="startmarginblock", + ["fr"]="demarreblocmarge", + ["it"]="iniziabloccomargine", + ["nl"]="startmargeblok", + ["pe"]="شروع‌بلوک‌حاشیه", + ["ro"]="startblocmarginal", + }, + ["startmarginrule"]={ + ["cs"]="startmarginalnilinka", + ["de"]="startmarginallinie", + ["en"]="startmarginrule", + ["fr"]="demarremargereglee", + ["it"]="inizialineamargine", + ["nl"]="startkantlijn", + ["pe"]="شروع‌خط‌حاشیه", + ["ro"]="startliniemargine", + }, + ["startnarrower"]={ + ["cs"]="startzuzeni", + ["de"]="startenger", + ["en"]="startnarrower", + ["fr"]="demarrecompoetroite", + ["it"]="iniziapiustretto", + ["nl"]="startsmaller", + ["pe"]="شروع‌باریکتر", + ["ro"]="startingust", + }, + ["startopposite"]={ + ["cs"]="startprotejsek", + ["de"]="startgegenueber", + ["en"]="startopposite", + ["fr"]="demarreopposition", + ["it"]="iniziaopposto", + ["nl"]="startnaast", + ["pe"]="شروع‌مخالف", + ["ro"]="startopozit", + }, + ["startoverlay"]={ + ["cs"]="startprekryv", + ["de"]="startoverlay", + ["en"]="startoverlay", + ["fr"]="demarrerevetement", + ["it"]="iniziasovrapposizione", + ["nl"]="startoverlay", + ["pe"]="شروع‌پوشش", + ["ro"]="startoverlay", + }, + ["startoverzicht"]={ + ["cs"]="startprehled", + ["de"]="startueberblick", + ["en"]="startoverview", + ["fr"]="demarrevuedensemble", + ["it"]="iniziaoverview", + ["nl"]="startoverzicht", + ["pe"]="شروع‌بازبینی", + ["ro"]="startoverview", + }, + ["startpacked"]={ + ["cs"]="startzhustene", + ["de"]="startkleinerdurchschuss", + ["en"]="startpacked", + ["fr"]="demarregroupe", + ["it"]="iniziaimpaccato", + ["nl"]="startopelkaar", + ["pe"]="شروع‌فشرده", + ["ro"]="startimpachetat", + }, + ["startpositioning"]={ + ["cs"]="startumistovani", + ["de"]="startpositionieren", + ["en"]="startpositioning", + ["fr"]="demarrepositionnement", + ["it"]="iniziaposizionamento", + ["nl"]="startpositioneren", + ["pe"]="شروع‌مکان‌گذاری", + ["ro"]="startpozitionare", + }, + ["startproduct"]={ + ["cs"]="startprodukt", + ["de"]="startprodukt", + ["en"]="startproduct", + ["fr"]="demarreproduit", + ["it"]="iniziaprodotto", + ["nl"]="startprodukt", + ["pe"]="شروع‌تولید", + ["ro"]="startprodus", + }, + ["startprofile"]={ + ["cs"]="startprofil", + ["de"]="startprofil", + ["en"]="startprofile", + ["fr"]="demarreprofil", + ["it"]="iniziaprofilo", + ["nl"]="startprofiel", + ["pe"]="شروع‌پروفایل", + ["ro"]="startprofil", + }, + ["startproject"]={ + ["cs"]="startprojekt", + ["de"]="startprojekt", + ["en"]="startproject", + ["fr"]="demarreprojet", + ["it"]="iniziaprogetto", + ["nl"]="startprojekt", + ["pe"]="شروع‌پروژه", + ["ro"]="startproiect", + }, + ["startquotation"]={ + ["cs"]="startcitace", + ["de"]="startzitat", + ["en"]="startquotation", + ["fr"]="demarrecitation", + ["it"]="iniziacitazione", + ["nl"]="startcitaat", + ["pe"]="شروع‌نقل‌قول", + ["ro"]="startcitat", + }, + ["startraster"]={ + ["cs"]="startrastr", + ["de"]="startraster", + ["en"]="startraster", + ["fr"]="demarreraster", + ["it"]="iniziaraster", + ["nl"]="startraster", + ["pe"]="startraster", + ["ro"]="startraster", + }, + ["startsymbolset"]={ + ["cs"]="startsadasymbolu", + ["de"]="startsymbolset", + ["en"]="startsymbolset", + ["fr"]="demarrejeusymboles", + ["it"]="iniziasetsimboli", + ["nl"]="startsymboolset", + ["pe"]="شروع‌مجموعه‌نماد", + ["ro"]="startsetsimboluri", + }, + ["startsynchronization"]={ + ["cs"]="startsynchronizace", + ["de"]="startsynchronisation", + ["en"]="startsynchronization", + ["fr"]="demarresynchronisation", + ["it"]="iniziasincronizzazione", + ["nl"]="startsynchronisatie", + ["pe"]="شروع‌تطابق", + ["ro"]="startsincronizare", + }, + ["starttable"]={ + ["cs"]="starttabulka", + ["de"]="starttabelle", + ["en"]="starttable", + ["fr"]="demarretableau", + ["it"]="iniziatabella", + ["nl"]="starttabel", + ["pe"]="شروع‌جدول", + ["ro"]="starttabel", + }, + ["starttables"]={ + ["cs"]="starttabulky", + ["de"]="starttabellen", + ["en"]="starttables", + ["fr"]="demarretableaux", + ["it"]="iniziatabelle", + ["nl"]="starttabellen", + ["pe"]="شروع‌جدولها", + ["ro"]="starttabele", + }, + ["starttext"]={ + ["cs"]="starttext", + ["de"]="starttext", + ["en"]="starttext", + ["fr"]="demarretexte", + ["it"]="iniziatesto", + ["nl"]="starttekst", + ["pe"]="شروع‌متن", + ["ro"]="starttext", + }, + ["starttextrule"]={ + ["cs"]="starttextovalinka", + ["de"]="starttextlinie", + ["en"]="starttextrule", + ["fr"]="demarreligneregleetexte", + ["it"]="inizialineatesto", + ["nl"]="starttekstlijn", + ["pe"]="شروع‌خط‌متن", + ["ro"]="startriglatext", + }, + ["startunpacked"]={ + ["cs"]="startnezhustene", + ["de"]="startgrosserdurchschuss", + ["en"]="startunpacked", + ["fr"]="demarredegroupe", + ["it"]="iniziaunpacked", + ["nl"]="startvanelkaar", + ["pe"]="شروع‌غیر‌فشرده", + ["ro"]="startneimpachetat", + }, + ["startversion"]={ + ["cs"]="startverze", + ["de"]="startversion", + ["en"]="startversion", + ["fr"]="demarreversion", + ["it"]="iniziaversione", + ["nl"]="startversie", + ["pe"]="شروع‌نسخه", + ["ro"]="startversiune", + }, + ["stopalignment"]={ + ["cs"]="stopzarovnavani", + ["de"]="stopausrichtung", + ["en"]="stopalignment", + ["fr"]="stoppealignement", + ["it"]="terminaallineamento", + ["nl"]="stopuitlijnen", + ["pe"]="پایان‌تنظیم", + ["ro"]="stopaliniere", + }, + ["stopbackground"]={ + ["cs"]="stoppozadi", + ["de"]="stophintergrund", + ["en"]="stopbackground", + ["fr"]="stoppearriereplan", + ["it"]="terminasfondo", + ["nl"]="stopachtergrond", + ["pe"]="پایان‌پس‌زمینه", + ["ro"]="stopfundal", + }, + ["stopcoding"]={ + ["cs"]="stopkodovani", + ["de"]="stopkodierung", + ["en"]="stopcoding", + ["fr"]="stoppecodage", + ["it"]="terminacodifica", + ["nl"]="stopcodering", + ["pe"]="پایان‌کد", + ["ro"]="stopcodificare", + }, + ["stopcolor"]={ + ["cs"]="stopbarva", + ["de"]="stopfarbe", + ["en"]="stopcolor", + ["fr"]="stoppecouleur", + ["it"]="terminacolore", + ["nl"]="stopkleur", + ["pe"]="پایان‌رنگ", + ["ro"]="stopculoare", + }, + ["stopcolumnmakeup"]={ + ["cs"]="stopcolumnmakeup", + ["de"]="stopcolumnmakeup", + ["en"]="stopcolumnmakeup", + ["fr"]="stopcolumnmakeup", + ["it"]="stopcolumnmakeup", + ["nl"]="stopkolomopmaak", + ["pe"]="پایان‌آرایش‌ستون", + ["ro"]="stopcolumnmakeup", + }, + ["stopcolumns"]={ + ["cs"]="stopsloupce", + ["de"]="stopspalten", + ["en"]="stopcolumns", + ["fr"]="stoppecolonnes", + ["it"]="terminacolonne", + ["nl"]="stopkolommen", + ["pe"]="پایان‌ستونها", + ["ro"]="stopcoloane", + }, + ["stopcolumnset"]={ + ["cs"]="stopcolumnset", + ["de"]="stopcolumnset", + ["en"]="stopcolumnset", + ["fr"]="stoppejeucolonne", + ["it"]="terminagruppocolonne", + ["nl"]="stopkolomgroep", + ["pe"]="پایان‌مجموعه‌ستون", + ["ro"]="stopcolumnset", + }, + ["stopcombination"]={ + ["cs"]="stopspojeni", + ["de"]="stopkombination", + ["en"]="stopcombination", + ["fr"]="stoppecombinaison", + ["it"]="terminacombinazione", + ["nl"]="stopcombinatie", + ["pe"]="پایان‌ترکیب", + ["ro"]="stopcombinare", + }, + ["stopcomponent"]={ + ["cs"]="stopkomponenta", + ["de"]="stopkomponente", + ["en"]="stopcomponent", + ["fr"]="stoppecomposant", + ["it"]="terminacomponente", + ["nl"]="stoponderdeel", + ["pe"]="پایان‌مولفه", + ["ro"]="stopcomponenta", + }, + ["stopdocument"]={ + ["cs"]="stopdokument", + ["de"]="stopdokument", + ["en"]="stopdocument", + ["fr"]="stoppedocument", + ["it"]="terminadocumento", + ["nl"]="stopdocument", + ["pe"]="پایان‌نوشتار", + ["ro"]="stopdocument", + }, + ["stopenvironment"]={ + ["cs"]="stopprostredi", + ["de"]="stopumgebung", + ["en"]="stopenvironment", + ["fr"]="stoppeenvironement", + ["it"]="terminaambiente", + ["nl"]="stopomgeving", + ["pe"]="پایان‌محیط", + ["ro"]="stopmediu", + }, + ["stopglobal"]={ + ["cs"]="stopglobalni", + ["de"]="stopglobal", + ["en"]="stopglobal", + ["fr"]="stoppeglobal", + ["it"]="terminaglobale", + ["nl"]="stopglobaal", + ["pe"]="پایان‌سراسری", + ["ro"]="stopblobal", + }, + ["stopline"]={ + ["cs"]="stopradek", + ["de"]="stopzeile", + ["en"]="stopline", + ["fr"]="stoppeligne", + ["it"]="terminariga", + ["nl"]="stopregel", + ["pe"]="پایان‌خط", + ["ro"]="stoplinie", + }, + ["stoplinecorrection"]={ + ["cs"]="stopkorekceradku", + ["de"]="stopzeilenkorrektur", + ["en"]="stoplinecorrection", + ["fr"]="stoppecorrectionligne", + ["it"]="terminacorrezioneriga", + ["nl"]="stopregelcorrectie", + ["pe"]="پایان‌تصحیح‌خط", + ["ro"]="stopcorectielinie", + }, + ["stoplinenumbering"]={ + ["cs"]="stopcislovaniradku", + ["de"]="stopzeilennumerierung", + ["en"]="stoplinenumbering", + ["fr"]="stoppenumerotationligne", + ["it"]="terminanumerazionerighe", + ["nl"]="stopregelnummeren", + ["pe"]="پایان‌شماره‌گذاری‌خط", + ["ro"]="stopnumerotarelinii", + }, + ["stoplines"]={ + ["cs"]="stopradky", + ["de"]="stopzeilen", + ["en"]="stoplines", + ["fr"]="stoppelignes", + ["it"]="terminarighe", + ["nl"]="stopregels", + ["pe"]="پایان‌خطها", + ["ro"]="stoplinii", + }, + ["stoplocal"]={ + ["cs"]="stoplokalni", + ["de"]="stoplokal", + ["en"]="stoplocal", + ["fr"]="stoppelocal", + ["it"]="terminalocale", + ["nl"]="stoplokaal", + ["pe"]="پایان‌موضعی", + ["ro"]="stoplocal", + }, + ["stoplocalfootnotes"]={ + ["cs"]="stoplokalnipoznamkypodcarou", + ["de"]="stoplokalefussnoten", + ["en"]="stoplocalfootnotes", + ["fr"]="stoppenotespdplocales", + ["it"]="terminanotepdplocali", + ["nl"]="stoplokalevoetnoten", + ["pe"]="پایان‌پانوشتهای‌موضعی", + ["ro"]="stopnotesubsollocale", + }, + ["stopmakeup"]={ + ["cs"]="stopuprava", + ["de"]="stopumbruch", + ["en"]="stopmakeup", + ["fr"]="stoppemakeup", + ["it"]="terminamakeup", + ["nl"]="stopopmaak", + ["pe"]="پایان‌آرایش", + ["ro"]="stopmakeup", + }, + ["stopmarginblock"]={ + ["cs"]="stopmarginalniblok", + ["de"]="stopmarginalblock", + ["en"]="stopmarginblock", + ["fr"]="stoppeblocmarge", + ["it"]="terminabloccomargine", + ["nl"]="stopmargeblok", + ["pe"]="پایان‌بلوک‌حاشیه", + ["ro"]="stopblocmarginal", + }, + ["stopmarginrule"]={ + ["cs"]="stopmarginalnilinka", + ["de"]="stopmarginallinie", + ["en"]="stopmarginrule", + ["fr"]="stoppemargereglee", + ["it"]="terminalineamargine", + ["nl"]="stopkantlijn", + ["pe"]="پایان‌خط‌حاشیه", + ["ro"]="stopliniemargine", + }, + ["stopnarrower"]={ + ["cs"]="stopzuzeni", + ["de"]="stopenger", + ["en"]="stopnarrower", + ["fr"]="stopcompoetroite", + ["it"]="terminapiustretto", + ["nl"]="stopsmaller", + ["pe"]="پایان‌نازکتر", + ["ro"]="stopingust", + }, + ["stopopposite"]={ + ["cs"]="stopprotejsek", + ["de"]="stopgegenueber", + ["en"]="stopopposite", + ["fr"]="stoppeopposition", + ["it"]="terminaopposto", + ["nl"]="stopnaast", + ["pe"]="پایان‌مخالف", + ["ro"]="stopopozit", + }, + ["stopoverlay"]={ + ["cs"]="stopprekryv", + ["de"]="stopoverlay", + ["en"]="stopoverlay", + ["fr"]="stopperevetement", + ["it"]="terminasovrapposizione", + ["nl"]="stopoverlay", + ["pe"]="پایان‌پوشش", + ["ro"]="stopoverlay", + }, + ["stopoverzicht"]={ + ["cs"]="stopprehled", + ["de"]="stopueberblick", + ["en"]="stopoverview", + ["fr"]="stoppevuedensemble", + ["it"]="terminaoverview", + ["nl"]="stopoverzicht", + ["pe"]="پایان‌بازبینی", + ["ro"]="stopoverview", + }, + ["stoppacked"]={ + ["cs"]="stopzhustene", + ["de"]="stopkleinerdurchschuss", + ["en"]="stoppacked", + ["fr"]="stoppegroupe", + ["it"]="terminaimpaccato", + ["nl"]="stopopelkaar", + ["pe"]="پایان‌فشرده", + ["ro"]="stopimpachetat", + }, + ["stoppositioning"]={ + ["cs"]="stopumistovani", + ["de"]="stoppositionieren", + ["en"]="stoppositioning", + ["fr"]="stoppepositionnement", + ["it"]="terminaposizionamento", + ["nl"]="stoppositioneren", + ["pe"]="پایان‌مکان‌گذاری", + ["ro"]="stoppozitionare", + }, + ["stopproduct"]={ + ["cs"]="stopprodukt", + ["de"]="stopprodukt", + ["en"]="stopproduct", + ["fr"]="stoppeproduit", + ["it"]="terminaprodotto", + ["nl"]="stopprodukt", + ["pe"]="پایان‌تولید", + ["ro"]="stopprodus", + }, + ["stopprofile"]={ + ["cs"]="stopprofil", + ["de"]="stopprofil", + ["en"]="stopprofile", + ["fr"]="stoppeprofil", + ["it"]="terminaprofili", + ["nl"]="stopprofiel", + ["pe"]="پایان‌پروفایل", + ["ro"]="stopprofil", + }, + ["stopproject"]={ + ["cs"]="stopprojekt", + ["de"]="stopprojekt", + ["en"]="stopproject", + ["fr"]="stoppeprojet", + ["it"]="terminaprogetto", + ["nl"]="stopprojekt", + ["pe"]="پایان‌پروژه", + ["ro"]="stopproiect", + }, + ["stopquotation"]={ + ["cs"]="stopcitace", + ["de"]="stopzitat", + ["en"]="stopquotation", + ["fr"]="stoppecitation", + ["it"]="terminacitazione", + ["nl"]="stopcitaat", + ["pe"]="پایان‌نقل‌قول", + ["ro"]="stopcitat", + }, + ["stopraster"]={ + ["cs"]="stoprastr", + ["de"]="stopraster", + ["en"]="stopraster", + ["fr"]="stopperaster", + ["it"]="terminaraster", + ["nl"]="stopraster", + ["pe"]="stopraster", + ["ro"]="stopraster", + }, + ["stopsynchronization"]={ + ["cs"]="stopsynchronizace", + ["de"]="stopsynchronisation", + ["en"]="stopsynchronization", + ["fr"]="stoppesynchronisation", + ["it"]="terminasincronizzazione", + ["nl"]="stopsynchronisatie", + ["pe"]="پایان‌تطابق", + ["ro"]="stopsincronizare", + }, + ["stoptable"]={ + ["cs"]="stoptabulka", + ["de"]="stoptabelle", + ["en"]="stoptable", + ["fr"]="stoppetableau", + ["it"]="terminatabella", + ["nl"]="stoptabel", + ["pe"]="پایان‌جدول", + ["ro"]="stoptabel", + }, + ["stoptables"]={ + ["cs"]="stoptabulky", + ["de"]="stoptabellen", + ["en"]="stoptables", + ["fr"]="stoppetableaux", + ["it"]="terminatabelle", + ["nl"]="stoptabellen", + ["pe"]="پایان‌جدولها", + ["ro"]="stoptabele", + }, + ["stoptext"]={ + ["cs"]="stoptext", + ["de"]="stoptext", + ["en"]="stoptext", + ["fr"]="stoppetexte", + ["it"]="terminatesto", + ["nl"]="stoptekst", + ["pe"]="پایان‌متن", + ["ro"]="stoptext", + }, + ["stoptextrule"]={ + ["cs"]="stoptextovalinka", + ["de"]="stoptextlinie", + ["en"]="stoptextrule", + ["fr"]="stoppeligneregleetexte", + ["it"]="terminalineatesto", + ["nl"]="stoptekstlijn", + ["pe"]="پایان‌خط‌متن", + ["ro"]="stopriglatext", + }, + ["stopunpacked"]={ + ["cs"]="stopnezhustene", + ["de"]="stopgrosserdurchschuss", + ["en"]="stopunpacked", + ["fr"]="stoppedegroupe", + ["it"]="terminaunpacked", + ["nl"]="stopvanelkaar", + ["pe"]="پایان‌غیرفشرده", + ["ro"]="stopneimpachetat", + }, + ["stopversion"]={ + ["cs"]="stopverze", + ["de"]="stopversion", + ["en"]="stopversion", + ["fr"]="stoppeversion", + ["it"]="terminaversioni", + ["nl"]="stopversie", + ["pe"]="پایان‌نسخه", + ["ro"]="stopversiune", + }, + ["stretched"]={ + ["cs"]="roztazene", + ["de"]="gestreckt", + ["en"]="stretched", + ["fr"]="etire", + ["it"]="stirato", + ["nl"]="uitgerekt", + ["pe"]="کشیده", + ["ro"]="intins", + }, + ["subformulanumber"]={ + ["cs"]="cislopodrovnice", + ["de"]="unterformelnummer", + ["en"]="subformulanumber", + ["fr"]="numerosousformule", + ["it"]="numerosottoformula", + ["nl"]="subformulenummer", + ["pe"]="شماره‌زیرفرمول", + ["ro"]="numarsubformula", + }, + ["subpagenumber"]={ + ["cs"]="subpagenumber", + ["de"]="subpagenumber", + ["en"]="subpagenumber", + ["fr"]="sousnumeropage", + ["it"]="subpagenumber", + ["nl"]="subpaginanummer", + ["pe"]="شماره‌زیرصفحه", + ["ro"]="subpagenumber", + }, + ["switchtobodyfont"]={ + ["cs"]="prepninazakladnifont", + ["de"]="wechselezumfliesstext", + ["en"]="switchtobodyfont", + ["fr"]="changepolicecorps", + ["it"]="cambiaafontdeltesto", + ["nl"]="switchnaarkorps", + ["pe"]="تغییربه‌قلم‌بدنه", + ["ro"]="trecilafonttext", + }, + ["switchtorawfont"]={ + ["cs"]="switchtorawfont", + ["de"]="switchtorawfont", + ["en"]="switchtorawfont", + ["fr"]="changepolicebrute", + ["it"]="passaafontgrezzo", + ["nl"]="switchtorawfont", + ["pe"]="تغییربه‌قلم‌خام", + ["ro"]="trecilafontraw", + }, + ["sym"]={ + ["cs"]="sym", + ["de"]="sym", + ["en"]="sym", + ["fr"]="sym", + ["it"]="sim", + ["nl"]="sym", + ["pe"]="نم", + ["ro"]="sim", + }, + ["symbol"]={ + ["cs"]="symbol", + ["de"]="symbol", + ["en"]="symbol", + ["fr"]="symbole", + ["it"]="simbolo", + ["nl"]="symbool", + ["pe"]="نماد", + ["ro"]="simbol", + }, + ["synchronizationbar"]={ + ["cs"]="synchronizacnilista", + ["de"]="synchronisationsbalken", + ["en"]="synchronizationbar", + ["fr"]="barresynchronisation", + ["it"]="barrasincronizzazione", + ["nl"]="synchronisatiebalk", + ["pe"]="میله‌تطابق", + ["ro"]="barasincronizare", + }, + ["synchronize"]={ + ["cs"]="synchronizovat", + ["de"]="synchronisieren", + ["en"]="synchronize", + ["fr"]="synchronise", + ["it"]="sincronizza", + ["nl"]="synchroniseer", + ["pe"]="تطابق", + ["ro"]="sincronizeaza", + }, + ["tab"]={ + ["cs"]="tab", + ["de"]="tab", + ["en"]="tab", + ["fr"]="tab", + ["it"]="tab", + ["nl"]="tab", + ["pe"]="تب", + ["ro"]="tab", + }, + ["testcolumn"]={ + ["cs"]="testcolumn", + ["de"]="testcolumn", + ["en"]="testcolumn", + ["fr"]="testcolumn", + ["it"]="testcolumn", + ["nl"]="testkolom", + ["pe"]="ستون‌امتحان", + ["ro"]="testcolumn", + }, + ["testpage"]={ + ["cs"]="testpage", + ["de"]="testpage", + ["en"]="testpage", + ["fr"]="testpage", + ["it"]="testpage", + ["nl"]="testpagina", + ["pe"]="صفحه‌تست", + ["ro"]="testpage", + }, + ["tex"]={ + ["cs"]="tex", + ["de"]="tex", + ["en"]="tex", + ["fr"]="tex", + ["it"]="tex", + ["nl"]="tex", + ["pe"]="تک", + ["ro"]="tex", + }, + ["textheight"]={ + ["cs"]="vyskatextu", + ["de"]="texthoehe", + ["en"]="textheight", + ["fr"]="hauteurtexte", + ["it"]="altezzatesto", + ["nl"]="teksthoogte", + ["pe"]="ارتفاع‌متن", + ["ro"]="inaltimetext", + }, + ["textreference"]={ + ["cs"]="odkaznatext", + ["de"]="textreferenz", + ["en"]="textreference", + ["fr"]="referencetexte", + ["it"]="riferimentotesto", + ["nl"]="tekstreferentie", + ["pe"]="مرجع‌متن", + ["ro"]="referintatext", + }, + ["textrule"]={ + ["cs"]="textovalinka", + ["de"]="textlinie", + ["en"]="textrule", + ["fr"]="ligneregleetexte", + ["it"]="lineatesto", + ["nl"]="tekstlijn", + ["pe"]="خط‌متن", + ["ro"]="riglatext", + }, + ["textvariable"]={ + ["cs"]="textvariable", + ["de"]="textvariable", + ["en"]="textvariable", + ["fr"]="variabletexte", + ["it"]="variabiletesto", + ["nl"]="tekstvariabele", + ["pe"]="متغیر متن", + ["ro"]="variabilatext", + }, + ["textwidth"]={ + ["cs"]="sirkatextu", + ["de"]="textbreite", + ["en"]="textwidth", + ["fr"]="largeurtexte", + ["it"]="ampiezzatesto", + ["nl"]="tekstbreedte", + ["pe"]="عرض‌متن", + ["ro"]="latimetext", + }, + ["thinrule"]={ + ["cs"]="tenkalinka", + ["de"]="duennelinie", + ["en"]="thinrule", + ["fr"]="traitfin", + ["it"]="lineasottile", + ["nl"]="dunnelijn", + ["pe"]="خط‌نازک", + ["ro"]="liniesubtire", + }, + ["thinrules"]={ + ["cs"]="tenkelinky", + ["de"]="duennerumriss", + ["en"]="thinrules", + ["fr"]="traitsfins", + ["it"]="lineesottili", + ["nl"]="dunnelijnen", + ["pe"]="خطهای‌نازک", + ["ro"]="liniisubtiri", + }, + ["tooltip"]={ + ["cs"]="bublinkovanapoveda", + ["de"]="tooltip", + ["en"]="tooltip", + ["fr"]="suggestion", + ["it"]="tooltip", + ["nl"]="suggestie", + ["pe"]="tooltip", + ["ro"]="tooltip", + }, + ["topdistance"]={ + ["cs"]="vzdalenosthorejsku", + ["de"]="abstandoben", + ["en"]="topdistance", + ["fr"]="distancesup", + ["it"]="distanzacima", + ["nl"]="bovenafstand", + ["pe"]="فاصله‌بالا", + ["ro"]="distantasus", + }, + ["topheight"]={ + ["cs"]="vyskahorejsku", + ["de"]="hoeheoben", + ["en"]="topheight", + ["fr"]="hauteursup", + ["it"]="altezzacima", + ["nl"]="bovenhoogte", + ["pe"]="ارتفاع‌بالا", + ["ro"]="inaltimesus", + }, + ["topspace"]={ + ["cs"]="odsazenishora", + ["de"]="kopfweite", + ["en"]="topspace", + ["fr"]="espacesup", + ["it"]="spaziocima", + ["nl"]="kopwit", + ["pe"]="فضای‌بالا", + ["ro"]="spatiusus", + }, + ["totalnumberofpages"]={ + ["cs"]="celkovypocetstran", + ["de"]="gesamtseitenanzahl", + ["en"]="totalnumberofpages", + ["fr"]="nombretotaldepages", + ["it"]="numerototaledipagine", + ["nl"]="totaalaantalpaginas", + ["pe"]="شماره‌کل‌صفحه‌ها", + ["ro"]="numartotalpagini", + }, + ["translate"]={ + ["cs"]="prelozit", + ["de"]="uebersetzten", + ["en"]="translate", + ["fr"]="traduire", + ["it"]="traduci", + ["nl"]="vertaal", + ["pe"]="ترجمه", + ["ro"]="traduce", + }, + ["txt"]={ + ["cs"]="txt", + ["de"]="txt", + ["en"]="txt", + ["fr"]="txt", + ["it"]="txt", + ["nl"]="txt", + ["pe"]="txt", + ["ro"]="txt", + }, + ["typ"]={ + ["cs"]="pis", + ["de"]="tip", + ["en"]="typ", + ["fr"]="typ", + ["it"]="typ", + ["nl"]="typ", + ["pe"]="typ", + ["ro"]="typ", + }, + ["type"]={ + ["cs"]="opis", + ["de"]="tippen", + ["en"]="type", + ["fr"]="dactylographier", + ["it"]="type", + ["nl"]="type", + ["pe"]="تایپ", + ["ro"]="type", + }, + ["typebuffer"]={ + ["cs"]="typebuffer", + ["de"]="tippepuffer", + ["en"]="typebuffer", + ["fr"]="tapebuffer", + ["it"]="typebuffer", + ["nl"]="typebuffer", + ["pe"]="تایپ‌بافر", + ["ro"]="scriebuffer", + }, + ["typefile"]={ + ["cs"]="opissoubor", + ["de"]="tippedatei", + ["en"]="typefile", + ["fr"]="fichierdactylo", + ["it"]="typefile", + ["nl"]="typefile", + ["pe"]="تایپ‌پرونده", + ["ro"]="typefile", + }, + ["unitmeaning"]={ + ["cs"]="vyznam", + ["de"]="bedeutung", + ["en"]="unitmeaning", + ["fr"]="sensunite", + ["it"]="nomeunita", + ["nl"]="betekenis", + ["pe"]="معنی‌واحد", + ["ro"]="numeunitate", + }, + ["unknown"]={ + ["cs"]="neznamo", + ["de"]="unbekant", + ["en"]="unknown", + ["fr"]="inconnu", + ["it"]="ignoto", + ["nl"]="onbekend", + ["pe"]="ناشناس", + ["ro"]="necunoscut", + }, + ["useJSscripts"]={ + ["cs"]="uzijJSscripts", + ["de"]="verwendeJSscript", + ["en"]="useJSscripts", + ["fr"]="utiliseJSscripts", + ["it"]="usaJSscripts", + ["nl"]="gebruikJSscripts", + ["pe"]="useJSscripts", + ["ro"]="folosestescriptJS", + }, + ["useURL"]={ + ["cs"]="uzijURL", + ["de"]="verwendeURL", + ["en"]="useURL", + ["fr"]="utiliseURL", + ["it"]="usaURL", + ["nl"]="gebruikURL", + ["pe"]="useURL", + ["ro"]="folosesteURL", + }, + ["useXMLfilter"]={ + ["cs"]="useXMLfilter", + ["de"]="useXMLfilter", + ["en"]="useXMLfilter", + ["fr"]="useXMLfilter", + ["it"]="useXMLfilter", + ["nl"]="gebruikXMLfilter", + ["pe"]="useXMLfilter", + ["ro"]="useXMLfilter", + }, + ["useblocks"]={ + ["cs"]="uzijbloky", + ["de"]="verwendebloecke", + ["en"]="useblocks", + ["fr"]="utiliseblocs", + ["it"]="usablocco", + ["nl"]="gebruikblokken", + ["pe"]="استفاده‌بلوکها", + ["ro"]="folosestebloc", + }, + ["usecommands"]={ + ["cs"]="uzijprikazy", + ["de"]="verwendebefehl", + ["en"]="usecommands", + ["fr"]="utilisecommandes", + ["it"]="usacomandi", + ["nl"]="gebruikcommandos", + ["pe"]="استفاده‌فرمانها", + ["ro"]="folosestecomenzi", + }, + ["useencoding"]={ + ["cs"]="uzijkodovani", + ["de"]="benutzekodierung", + ["en"]="useencoding", + ["fr"]="utiliseencodage", + ["it"]="usacodifica", + ["nl"]="usecodering", + ["pe"]="استفاده‌رمزینه", + ["ro"]="folosestecodificarea", + }, + ["useexternaldocument"]={ + ["cs"]="uzijexternidokument", + ["de"]="verwendeexteresdokument", + ["en"]="useexternaldocument", + ["fr"]="utilisedocumentexterne", + ["it"]="usadocumentoesterno", + ["nl"]="gebruikexterndocument", + ["pe"]="استفاده‌نوشتارخارجی", + ["ro"]="folosestedocumentextern", + }, + ["useexternalfigure"]={ + ["cs"]="uzijexterniobraz", + ["de"]="verwendeexterneabbildung", + ["en"]="useexternalfigure", + ["fr"]="utilisefigureexterne", + ["it"]="usafiguraesterna", + ["nl"]="gebruikexternfiguur", + ["pe"]="استفاده‌شکل‌خارجی", + ["ro"]="folosestefiguraexterna", + }, + ["useexternalfile"]={ + ["cs"]="uzijexternisoubor", + ["de"]="verwendeexternedatei", + ["en"]="useexternalfile", + ["fr"]="utilisefichierexterne", + ["it"]="usafileesterno", + ["nl"]="gebruikexternefile", + ["pe"]="استفاده‌پرونده‌خارجی", + ["ro"]="folosestefisierextern", + }, + ["useexternalfiles"]={ + ["cs"]="uzijexternisoubory", + ["de"]="verwendeexternedateien", + ["en"]="useexternalfiles", + ["fr"]="utilisefichiersexternes", + ["it"]="usafileesterni", + ["nl"]="gebruikexternefiles", + ["pe"]="استفاده‌پرونده‌های‌خارجی", + ["ro"]="folosestefisiereexterne", + }, + ["useexternalsoundtrack"]={ + ["cs"]="uzijexternizvuk", + ["de"]="verwendeexternestonstueck", + ["en"]="useexternalsoundtrack", + ["fr"]="utilisepsiteaudioexterne", + ["it"]="usacolonnasonoraesterna", + ["nl"]="gebruikexterngeluidsfragment", + ["pe"]="استفاده‌قطعه‌موزیک‌خارجی", + ["ro"]="folosestemuzicaexterna", + }, + ["usemodule"]={ + ["cs"]="uzijmodul", + ["de"]="verwendemodul", + ["en"]="usemodule", + ["fr"]="utilisemodule", + ["it"]="usamodulo", + ["nl"]="gebruikmodule", + ["pe"]="استفاده‌مدول", + ["ro"]="folosestemodul", + }, + ["usemodules"]={ + ["cs"]="uzijmoduly", + ["de"]="verwendemodule", + ["en"]="usemodules", + ["fr"]="utilisemodules", + ["it"]="usamoduli", + ["nl"]="gebruikmodules", + ["pe"]="استفاده‌مدولها", + ["ro"]="folosestemodule", + }, + ["usepath"]={ + ["cs"]="uzijadresar", + ["de"]="benutzeverzeichnis", + ["en"]="usedirectory", + ["fr"]="utilisechemin", + ["it"]="usacartella", + ["nl"]="gebruikgebied", + ["pe"]="استفاده‌مسیر", + ["ro"]="folosestedirector", + }, + ["usereferences"]={ + ["cs"]="uzijodkazy", + ["de"]="verwendereferenzen", + ["en"]="usereferences", + ["fr"]="utilisereferences", + ["it"]="usariferimenti", + ["nl"]="gebruikreferenties", + ["pe"]="استفاده‌مرجعها", + ["ro"]="folosestereferinte", + }, + ["usespecials"]={ + ["cs"]="uzijspeciality", + ["de"]="benutzespezielles", + ["en"]="usespecials", + ["fr"]="utilisespecialites", + ["it"]="usaspecialita", + ["nl"]="gebruikspecials", + ["pe"]="استفاده‌ویژگیها", + ["ro"]="folosestespeciale", + }, + ["usesymbols"]={ + ["cs"]="uzijsymbol", + ["de"]="verwendesymbole", + ["en"]="usesymbols", + ["fr"]="utilisesymboles", + ["it"]="usasimboli", + ["nl"]="gebruiksymbolen", + ["pe"]="استفاده‌نمادها", + ["ro"]="folosestesimboluri", + }, + ["usetypescript"]={ + ["cs"]="usetypescript", + ["de"]="usetypescript", + ["en"]="usetypescript", + ["fr"]="usetypescript", + ["it"]="usetypescript", + ["nl"]="gebruiktypescript", + ["pe"]="استفاده‌دستخط‌تایپ", + ["ro"]="usetypescript", + }, + ["usetypescriptfile"]={ + ["cs"]="usetypescriptfile", + ["de"]="usetypescriptfile", + ["en"]="usetypescriptfile", + ["it"]="usetypescriptfile", + ["nl"]="gebruiktypescriptfile", + ["pe"]="استفاده‌پرونده‌دستخط‌تایپ", + ["ro"]="usetypescriptfile", + }, + ["useurl"]={ + ["cs"]="uzijurl", + ["de"]="verwendeurl", + ["en"]="useurl", + ["fr"]="utiliseurl", + ["it"]="usaurl", + ["nl"]="gebruikurl", + ["pe"]="useurl", + ["ro"]="folosesteurl", + }, + ["version"]={ + ["cs"]="verze", + ["de"]="version", + ["en"]="version", + ["fr"]="version", + ["it"]="versione", + ["nl"]="versie", + ["pe"]="نسخه", + ["ro"]="versiune", + }, + ["vl"]={ + ["cs"]="vl", + ["de"]="vl", + ["en"]="vl", + ["fr"]="vl", + ["it"]="vl", + ["nl"]="vl", + ["pe"]="خ‌ع", + ["ro"]="vl", + }, + ["weekday"]={ + ["cs"]="vsedniden", + ["de"]="wochentag", + ["en"]="weekday", + ["fr"]="joursemaine", + ["it"]="giornosettimana", + ["nl"]="weekdag", + ["pe"]="روزهفته", + ["ro"]="zidinsaptamana", + }, + ["whitespace"]={ + ["cs"]="bilemisto", + ["de"]="zwischenraum", + ["en"]="whitespace", + ["fr"]="espaceblanc", + ["it"]="spaziobianco", + ["nl"]="witruimte", + ["pe"]="فضای‌سفید", + ["ro"]="spatiualb", + }, + ["wordright"]={ + ["cs"]="slovovpravo", + ["de"]="wortrechts", + ["en"]="wordright", + ["fr"]="motdroit", + ["it"]="paroladestra", + ["nl"]="woordrechts", + ["pe"]="کلمه‌راست", + ["ro"]="cuvantdreapta", + }, + ["writebetweenlist"]={ + ["cs"]="zapismeziseznam", + ["de"]="schreibezwischenliste", + ["en"]="writebetweenlist", + ["fr"]="ecritentreliste", + ["it"]="scrividentroelenco", + ["nl"]="schrijftussenlijst", + ["pe"]="بنویس‌بین‌لیست", + ["ro"]="scrieintreliste", + }, + ["writetolist"]={ + ["cs"]="zapisdoseznamu", + ["de"]="schreibezurliste", + ["en"]="writetolist", + ["fr"]="ecritdansliste", + ["it"]="scriviinelenco", + ["nl"]="schrijfnaarlijst", + ["pe"]="بنویس‌در‌لیست", + ["ro"]="scrieinlista", + }, + ["writetoreferencelist"]={ + ["cs"]="zapisdoseznamuodkazu", + ["de"]="schreibezurreferenzliste", + ["en"]="writetoreferencelist", + ["fr"]="ecritdanslistereference", + ["it"]="scriviinlistariferimenti", + ["nl"]="schrijfnaarreferentielijst", + ["pe"]="بنویس‌درلیست‌مرجع", + ["ro"]="scrieinlistareferinte", + }, + ["writetoregister"]={ + ["cs"]="zapisdorejstriku", + ["de"]="schreibezumregister", + ["en"]="writetoregister", + ["fr"]="ecritregistre", + ["it"]="scriviinregistro", + ["nl"]="schrijfnaarregister", + ["pe"]="بنویس‌درثبت", + ["ro"]="scrieinregistru", + }, + }, + ["constants"]={ + ["strip"]={ + ["en"]="strip", + }, + ["order"]={ + ["en"]="order", + }, + ["headalign"]={ + ["en"]="headalign", + ["nl"]="kopuitlijnen", + }, + ["alignsymbol"]={ + ["en"]="alignsymbol", + }, + ["export"]={ + ["en"]="export", + ["nl"]="exporteer", + }, + ["database"]={ + ["en"]="database", + }, + ["artauthor"]={ + ["en"]="artauthor", + }, + ["editor"]={ + ["en"]="editor", + }, + ["authoretallimit"]={ + ["en"]="authoretallimit", + }, + ["artauthoretallimit"]={ + ["en"]="artauthoretallimit", + }, + ["editoretallimit"]={ + ["en"]="editoretallimit", + }, + ["authoretaldisplay"]={ + ["en"]="authoretaldisplay", + }, + ["artauthoretaldisplay"]={ + ["en"]="artauthoretaldisplay", + }, + ["editoretaldisplay"]={ + ["en"]="editoretaldisplay", + }, + ["authoretaltext"]={ + ["en"]="authoretaltext", + }, + ["artauthoretaltext"]={ + ["en"]="artauthoretaltext", + }, + ["editoretaltext"]={ + ["en"]="editoretaltext", + }, + ["otherstext"]={ + ["en"]="otherstext", + }, + ["andtext"]={ + ["en"]="andtext", + }, + ["totalnumber"]={ + ["en"]="totalnumber", + }, + ["firstnamesep"]={ + ["en"]="firstnamesep", + }, + ["vonsep"]={ + ["en"]="vonsep", + }, + ["juniorsep"]={ + ["en"]="juniorsep", + }, + ["surnamesep"]={ + ["en"]="surnamesep", + }, + ["lastnamesep"]={ + ["en"]="lastnamesep", + }, + ["finalnamesep"]={ + ["en"]="finalnamesep", + }, + ["namesep"]={ + ["en"]="namesep", + }, + ["pubsep"]={ + ["en"]="pubsep", + }, + ["lastpubsep"]={ + ["en"]="lastpubsep", + }, + ["refcommand"]={ + ["en"]="refcommand", + }, + ["samplesize"]={ + ["en"]="samplesize", + }, + ["maybeyear"]={ + ["en"]="maybeyear", + }, + ["action"]={ + ["cs"]="akce", + ["de"]="aktion", + ["en"]="action", + ["fr"]="action", + ["it"]="azione", + ["nl"]="actie", + ["pe"]="کنش", + ["ro"]="actiune", + }, + ["address"]={ + ["cs"]="adresa", + ["de"]="adresse", + ["en"]="address", + ["fr"]="adresse", + ["it"]="indirizzo", + ["nl"]="adres", + ["pe"]="نشانی", + ["ro"]="adresa", + }, + ["after"]={ + ["cs"]="po", + ["de"]="nach", + ["en"]="after", + ["fr"]="apres", + ["it"]="dopo", + ["nl"]="na", + ["pe"]="بعداز", + ["ro"]="dupa", + }, + ["afterhead"]={ + ["cs"]="pohlavicce", + ["de"]="nachkopf", + ["en"]="afterhead", + ["fr"]="aprestete", + ["it"]="dopotesta", + ["nl"]="kopna", + ["pe"]="بعدازسر", + ["ro"]="dupatitlu", + }, + ["afterkey"]={ + ["cs"]="klavesapo", + ["de"]="nachtaste", + ["en"]="afterkey", + ["fr"]="aprescle", + ["it"]="dopotasto", + ["nl"]="natoets", + ["pe"]="بعدازکلید", + ["ro"]="dupatasta", + }, + ["align"]={ + ["cs"]="zarovnani", + ["de"]="ausrichtung", + ["en"]="align", + ["fr"]="alignement", + ["it"]="allinea", + ["nl"]="uitlijnen", + ["pe"]="تنظیم", + ["ro"]="aliniere", + }, + ["aligncharacter"]={ + ["cs"]="aligncharacter", + ["de"]="aligncharacter", + ["en"]="aligncharacter", + ["fr"]="caracterealigne", + ["it"]="allineacarattere", + ["nl"]="karakteruitlijnen", + ["pe"]="حرف‌تنظیم", + ["ro"]="aliniazacaracter", + }, + ["alignmentcharacter"]={ + ["cs"]="alignmentcharacter", + ["de"]="alignmentcharacter", + ["en"]="alignmentcharacter", + ["fr"]="alignementcaractere", + ["it"]="carattereallineamento", + ["nl"]="uitlijnkarakter", + ["pe"]="حرف‌تنظیم‌کردن", + ["ro"]="alierecaracter", + }, + ["aligntitle"]={ + ["cs"]="zarovnejtitul", + ["de"]="titelausrichten", + ["en"]="aligntitle", + ["fr"]="alignementtitre", + ["it"]="allineatitolo", + ["nl"]="titeluitlijnen", + ["pe"]="عنوان‌تنظیم", + ["ro"]="alinieretitlu", + }, + ["alternative"]={ + ["cs"]="alternativa", + ["de"]="alternative", + ["en"]="alternative", + ["fr"]="alternative", + ["it"]="alternativa", + ["nl"]="variant", + ["pe"]="جایگزین", + ["ro"]="alternativ", + }, + ["apa"]={ + ["cs"]="apa", + ["de"]="apa", + ["en"]="apa", + ["fr"]="apa", + ["it"]="apa", + ["nl"]="apa", + ["pe"]="apa", + ["ro"]="apa", + }, + ["arrow"]={ + ["cs"]="sipka", + ["de"]="pfeil", + ["en"]="arrow", + ["fr"]="fleche", + ["it"]="freccia", + ["nl"]="pijl", + ["pe"]="پیکان", + ["ro"]="sageata", + }, + ["at"]={ + ["cs"]="u", + ["de"]="bei", + ["en"]="at", + ["fr"]="a", + ["it"]="ad", + ["nl"]="op", + ["pe"]="در", + ["ro"]="la", + }, + ["author"]={ + ["cs"]="autor", + ["de"]="autor", + ["en"]="author", + ["fr"]="auteur", + ["it"]="autore", + ["nl"]="auteur", + ["pe"]="نویسنده", + ["ro"]="autor", + }, + ["auto"]={ + ["cs"]="auto", + ["de"]="auto", + ["en"]="auto", + ["fr"]="auto", + ["it"]="auto", + ["nl"]="auto", + ["pe"]="خودکار", + ["ro"]="auto", + }, + ["autofile"]={ + ["cs"]="autofile", + ["de"]="autofile", + ["en"]="autofile", + ["fr"]="autofile", + ["it"]="autofile", + ["nl"]="autofile", + ["pe"]="پرونده‌خودکار", + ["ro"]="autofile", + }, + ["autofocus"]={ + ["cs"]="autoostreni", + ["de"]="autofocus", + ["en"]="autofocus", + ["fr"]="autofocus", + ["it"]="autofocus", + ["nl"]="autofocus", + ["pe"]="تمرکز‌خودکار", + ["ro"]="autofocus", + }, + ["autohang"]={ + ["cs"]="autohang", + ["de"]="autohang", + ["en"]="autohang", + ["fr"]="autohang", + ["it"]="autohang", + ["nl"]="autohang", + ["pe"]="آویزان‌خودکار", + ["ro"]="autohang", + }, + ["autostrut"]={ + ["cs"]="autostrut", + ["de"]="autostrut", + ["en"]="autostrut", + ["fr"]="autostrut", + ["it"]="autostrut", + ["nl"]="autostrut", + ["pe"]="بست‌خودکار", + ["ro"]="autostrut", + }, + ["autowidth"]={ + ["cs"]="autosirka", + ["de"]="autobreite", + ["en"]="autowidth", + ["fr"]="autolargeur", + ["it"]="autoampiezza", + ["nl"]="autobreedte", + ["pe"]="عرض‌خودکار", + ["ro"]="autolatime", + }, + ["axis"]={ + ["cs"]="osa", + ["de"]="achsen", + ["en"]="axis", + ["fr"]="axe", + ["it"]="asse", + ["nl"]="assenstelsel", + ["pe"]="محورها", + ["ro"]="axa", + }, + ["background"]={ + ["cs"]="pozadi", + ["de"]="hintergrund", + ["en"]="background", + ["fr"]="arriereplan", + ["it"]="sfondo", + ["nl"]="achtergrond", + ["pe"]="پس‌زمینه", + ["ro"]="fundal", + }, + ["backgroundcolor"]={ + ["cs"]="barvapozadi", + ["de"]="hintergrundfarbe", + ["en"]="backgroundcolor", + ["fr"]="couleurarriereplan", + ["it"]="coloresfondo", + ["nl"]="achtergrondkleur", + ["pe"]="رنگ‌پس‌زمینه", + ["ro"]="culoarefundal", + }, + ["backgroundcorner"]={ + ["cs"]="rohpozadi", + ["de"]="hintergrundwinkel", + ["en"]="backgroundcorner", + ["fr"]="coinarriereplan", + ["it"]="angolosfondo", + ["nl"]="achtergrondhoek", + ["pe"]="گوشه‌پس‌زمینه", + ["ro"]="coltfundal", + }, + ["backgrounddepth"]={ + ["cs"]="hloubkapozadi", + ["de"]="hintergrundtiefe", + ["en"]="backgrounddepth", + ["fr"]="profondeurarriereplan", + ["it"]="profonditasfondo", + ["nl"]="achtergronddiepte", + ["pe"]="عمق‌پس‌زمینه", + ["ro"]="adancimefundal", + }, + ["backgroundoffset"]={ + ["cs"]="offsetpozadi", + ["de"]="hintergrundoffset", + ["en"]="backgroundoffset", + ["fr"]="decalagearriereplan", + ["it"]="offsetsfondo", + ["nl"]="achtergrondoffset", + ["pe"]="آفست‌پس‌زمینه", + ["ro"]="offsetfundal", + }, + ["backgroundradius"]={ + ["cs"]="polomerpozadi", + ["de"]="hintergrundradius", + ["en"]="backgroundradius", + ["fr"]="rayonarriereplan", + ["it"]="raggiosfondo", + ["nl"]="achtergrondstraal", + ["pe"]="شعاع‌پس‌زمینه", + ["ro"]="razafundal", + }, + ["backgroundscreen"]={ + ["cs"]="rastrpozadi", + ["de"]="hintergrundraster", + ["en"]="backgroundscreen", + ["fr"]="ecranarriereplan", + ["it"]="schermosfondo", + ["nl"]="achtergrondraster", + ["pe"]="پرده‌پس‌زمینه", + ["ro"]="ecranfundal", + }, + ["backspace"]={ + ["cs"]="zpetnamezera", + ["de"]="rumpfspatium", + ["en"]="backspace", + ["fr"]="retour", + ["it"]="backspace", + ["nl"]="rugwit", + ["pe"]="فضای‌پس", + ["ro"]="spatiuspate", + }, + ["balance"]={ + ["cs"]="rovnovaha", + ["de"]="ausgleichen", + ["en"]="balance", + ["fr"]="equilibre", + ["it"]="bilanciamento", + ["nl"]="balanceren", + ["pe"]="تعادل", + ["ro"]="balanta", + }, + ["before"]={ + ["cs"]="pred", + ["de"]="vor", + ["en"]="before", + ["fr"]="avant", + ["it"]="prima", + ["nl"]="voor", + ["pe"]="قبل‌از", + ["ro"]="inainte", + }, + ["beforehead"]={ + ["cs"]="predhlavickou", + ["de"]="vorkopf", + ["en"]="beforehead", + ["fr"]="avanttete", + ["it"]="primaditesta", + ["nl"]="kopvoor", + ["pe"]="قبل‌ازسر", + ["ro"]="inaintetitlu", + }, + ["bet"]={ + ["cs"]="bet", + ["de"]="bet", + ["en"]="bet", + ["fr"]="bet", + ["it"]="bet", + ["nl"]="bet", + ["pe"]="bet", + ["ro"]="bet", + }, + ["big"]={ + ["cs"]="velky", + ["de"]="gross", + ["en"]="big", + ["fr"]="grand", + ["it"]="grande", + ["nl"]="groot", + ["pe"]="بزرگ", + ["ro"]="mare", + }, + ["blank"]={ + ["cs"]="prazdny", + ["de"]="blanko", + ["en"]="blank", + ["fr"]="vide", + ["it"]="rigovuoto", + ["nl"]="blanko", + ["pe"]="خالی", + ["ro"]="blanc", + }, + ["blockway"]={ + ["cs"]="dobloku", + ["de"]="blockauf", + ["en"]="blockway", + ["fr"]="blockway", + ["it"]="blockway", + ["nl"]="blokwijze", + ["pe"]="راه‌بلوک", + ["ro"]="blockway", + }, + ["bodyfont"]={ + ["cs"]="zakladnifont", + ["de"]="fliesstext", + ["en"]="bodyfont", + ["fr"]="policecorps", + ["it"]="fonttesto", + ["nl"]="korps", + ["pe"]="قلم‌بدنه", + ["ro"]="fonttext", + }, + ["bookmark"]={ + ["cs"]="zalozka", + ["de"]="bookmark", + ["en"]="bookmark", + ["fr"]="marquepage", + ["it"]="segnalibro", + ["nl"]="bookmark", + ["pe"]="چوبخط", + ["ro"]="semncarte", + }, + ["bottom"]={ + ["cs"]="spodek", + ["de"]="unten", + ["en"]="bottom", + ["fr"]="inf", + ["it"]="fondo", + ["nl"]="onder", + ["pe"]="پایین", + ["ro"]="jos", + }, + ["bottomafter"]={ + ["en"]="bottomafter", + }, + ["bottombefore"]={ + ["en"]="bottombefore", + }, + ["bottomdistance"]={ + ["cs"]="vzdalenostspodku", + ["de"]="abstandunten", + ["en"]="bottomdistance", + ["fr"]="distanceinf", + ["it"]="distanzafondo", + ["nl"]="onderafstand", + ["pe"]="فاصله‌پایین", + ["ro"]="distantajos", + }, + ["bottomframe"]={ + ["cs"]="ramecekdole", + ["de"]="untenrahmen", + ["en"]="bottomframe", + ["fr"]="cadreinf", + ["it"]="cornicefondo", + ["nl"]="onderkader", + ["pe"]="قالب‌پایین", + ["ro"]="framejos", + }, + ["bottomoffset"]={ + ["cs"]="offsetspodku", + ["de"]="untenoffset", + ["en"]="bottomoffset", + ["fr"]="decalageinf", + ["it"]="offsetfondo", + ["nl"]="onderoffset", + ["pe"]="آفست‌پایین", + ["ro"]="offsetjos", + }, + ["bottomspace"]={ + ["cs"]="bottomspace", + ["de"]="bottomspace", + ["en"]="bottomspace", + ["fr"]="espaceinf", + ["it"]="spaziofondo", + ["nl"]="bodemwit", + ["pe"]="فضای‌پایین", + ["ro"]="spatiujos", + }, + ["bottomstate"]={ + ["cs"]="statusspodku", + ["de"]="untenstatus", + ["en"]="bottomstate", + ["fr"]="etatinf", + ["it"]="statofondo", + ["nl"]="onderstatus", + ["pe"]="وضعیت‌پایین", + ["ro"]="starejos", + }, + ["cache"]={ + ["cs"]="cache", + ["de"]="cache", + ["en"]="cache", + ["fr"]="cache", + ["it"]="cache", + ["nl"]="cache", + ["pe"]="میانگیر", + ["ro"]="cache", + }, + ["calculate"]={ + ["cs"]="pocitat", + ["de"]="berechnen", + ["en"]="calculate", + ["fr"]="calculer", + ["it"]="calcola", + ["nl"]="bereken", + ["pe"]="محاسبه", + ["ro"]="calculeaza", + }, + ["ccommand"]={ + ["cs"]="cprikaz", + ["de"]="cbefehl", + ["en"]="ccommand", + ["fr"]="ccommande", + ["it"]="ccomando", + ["nl"]="ccommando", + ["pe"]="فرمان", + ["ro"]="comandac", + }, + ["click"]={ + ["cs"]="klik", + ["de"]="klick", + ["en"]="click", + ["fr"]="clic", + ["it"]="click", + ["nl"]="klik", + ["pe"]="فشردن", + ["ro"]="click", + }, + ["clickin"]={ + ["cs"]="klikuvnitr", + ["de"]="klickin", + ["en"]="clickin", + ["fr"]="clicinterieur", + ["it"]="clickdentro", + ["nl"]="klikin", + ["pe"]="فشردن‌داخل", + ["ro"]="clickintru", + }, + ["clickout"]={ + ["cs"]="klikvne", + ["de"]="klickaus", + ["en"]="clickout", + ["fr"]="clicexterieur", + ["it"]="clickfuori", + ["nl"]="klikuit", + ["pe"]="فشردن‌خارج", + ["ro"]="clickies", + }, + ["clipoffset"]={ + ["cs"]="clipoffset", + ["de"]="clipoffset", + ["en"]="clipoffset", + ["fr"]="clipoffset", + ["it"]="clipoffset", + ["nl"]="clipoffset", + ["pe"]="آفست‌کلیپ", + ["ro"]="clipoffset", + }, + ["closeaction"]={ + ["cs"]="zavriakci", + ["de"]="schliessenaktion", + ["en"]="closeaction", + ["fr"]="actionfermeture", + ["it"]="azionechiudi", + ["nl"]="sluitactie", + ["pe"]="بستن‌کنش", + ["ro"]="actiuneinchidere", + }, + ["closecommand"]={ + ["cs"]="closecommand", + ["de"]="closecommand", + ["en"]="closecommand", + ["fr"]="closecommand", + ["it"]="closecommand", + ["nl"]="sluitcommando", + ["pe"]="بستن‌فرمان", + ["ro"]="closecommand", + }, + ["closepageaction"]={ + ["cs"]="akcezavrenistranky", + ["de"]="closepageaction", + ["en"]="closepageaction", + ["fr"]="actionfermeturepage", + ["it"]="azionechiudipagina", + ["nl"]="sluitpaginaactie", + ["pe"]="بستن‌عمل‌صفحه", + ["ro"]="actiuneinchiderepagina", + }, + ["closesymbol"]={ + ["cs"]="closesymbol", + ["de"]="closesymbol", + ["en"]="closesymbol", + ["fr"]="closesymbol", + ["it"]="closesymbol", + ["nl"]="sluitsymbool", + ["pe"]="بستن‌نماد", + ["ro"]="closesymbol", + }, + ["color"]={ + ["cs"]="barva", + ["de"]="farbe", + ["en"]="color", + ["fr"]="couleur", + ["it"]="colore", + ["nl"]="kleur", + ["pe"]="رنگ", + ["ro"]="culoare", + }, + ["intent"]={ + ["en"]="intent", + }, + ["column"]={ + ["cs"]="sloupec", + ["de"]="spalte", + ["en"]="column", + ["fr"]="colonne", + ["it"]="colonna", + ["nl"]="kolom", + ["pe"]="ستون", + ["ro"]="coloana", + }, + ["columndistance"]={ + ["cs"]="vzdalenostsloupcu", + ["de"]="spaltenabstand", + ["en"]="columndistance", + ["fr"]="distancecolonne", + ["it"]="distanzacolonne", + ["nl"]="kolomafstand", + ["pe"]="فاصله‌ستون", + ["ro"]="distantacoloane", + }, + ["columns"]={ + ["cs"]="sloupce", + ["de"]="spalten", + ["en"]="columns", + ["fr"]="colonnes", + ["it"]="colonne", + ["nl"]="kolommen", + ["pe"]="ستونها", + ["ro"]="coloane", + }, + ["command"]={ + ["cs"]="prikaz", + ["de"]="befehl", + ["en"]="command", + ["fr"]="commande", + ["it"]="comando", + ["nl"]="commando", + ["pe"]="فرمان", + ["ro"]="comanda", + }, + ["commandafter"]={ + ["cs"]="prikazpo", + ["de"]="zumbefehl", + ["en"]="commandafter", + ["fr"]="commandeapres", + ["it"]="comdandodopo", + ["nl"]="nacommando", + ["pe"]="فرمان‌بعداز", + ["ro"]="comandadupa", + }, + ["commandbefore"]={ + ["cs"]="predchoziprikaz", + ["de"]="vorbefehl", + ["en"]="commandbefore", + ["fr"]="commandeavant", + ["it"]="comandoprima", + ["nl"]="voorcommando", + ["pe"]="فرمان‌قبل‌از", + ["ro"]="comandainainte", + }, + ["commands"]={ + ["cs"]="prikazy", + ["de"]="befehle", + ["en"]="commands", + ["fr"]="commandes", + ["it"]="comandi", + ["nl"]="commandos", + ["pe"]="فرمانها", + ["ro"]="comenzi", + }, + ["component"]={ + ["cs"]="component", + ["de"]="component", + ["en"]="component", + ["fr"]="composant", + ["it"]="component", + ["nl"]="component", + ["pe"]="مولفه", + ["ro"]="component", + }, + ["compoundhyphen"]={ + ["cs"]="compoundhyphen", + ["de"]="compoundhyphen", + ["en"]="compoundhyphen", + ["fr"]="compoundhyphen", + ["it"]="compoundhyphen", + ["nl"]="koppelteken", + ["pe"]="compoundhyphen", + ["ro"]="compoundhyphen", + }, + ["compress"]={ + ["cs"]="compress", + ["de"]="compress", + ["en"]="compress", + ["fr"]="compress", + ["it"]="compress", + ["nl"]="comprimeren", + ["pe"]="فشردن", + ["ro"]="compress", + }, + ["connector"]={ + ["en"]="connector", + }, + ["continue"]={ + ["cs"]="pokracovat", + ["de"]="fortsetzen", + ["en"]="continue", + ["fr"]="continue", + ["it"]="continua", + ["nl"]="doorgaan", + ["pe"]="ادامه", + ["ro"]="continua", + }, + ["contrastcolor"]={ + ["cs"]="kontrastnibarva", + ["de"]="kontrastfarbe", + ["en"]="contrastcolor", + ["fr"]="coleurcontraste", + ["it"]="colorecontrasto", + ["nl"]="contrastkleur", + ["pe"]="contrastcolor", + ["ro"]="culoarecontrast", + }, + ["controls"]={ + ["cs"]="controls", + ["de"]="controls", + ["en"]="controls", + ["fr"]="controles", + ["it"]="controlli", + ["nl"]="sturing", + ["pe"]="کنترلها", + ["ro"]="controale", + }, + ["conversion"]={ + ["cs"]="konverze", + ["de"]="konversion", + ["en"]="conversion", + ["fr"]="conversion", + ["it"]="conversione", + ["nl"]="conversie", + ["pe"]="تبدیل", + ["ro"]="conversie", + }, + ["convertfile"]={ + ["cs"]="konverzesouboru", + ["de"]="konvertieredatei", + ["en"]="convertfile", + ["fr"]="conversionfichier", + ["it"]="convertifile", + ["nl"]="converteerfile", + ["pe"]="پرونده‌تبدیل", + ["ro"]="convertestefisier", + }, + ["corner"]={ + ["cs"]="roh", + ["de"]="winkel", + ["en"]="corner", + ["fr"]="coin", + ["it"]="angolo", + ["nl"]="hoek", + ["pe"]="گوشه", + ["ro"]="colt", + }, + ["coupling"]={ + ["cs"]="propojeni", + ["de"]="verknuepfung", + ["en"]="coupling", + ["fr"]="couplage", + ["it"]="accoppiamento", + ["nl"]="koppeling", + ["pe"]="تزویج", + ["ro"]="cuplare", + }, + ["couplingway"]={ + ["cs"]="zpusobpropojeni", + ["de"]="verkopplungsart", + ["en"]="couplingway", + ["fr"]="modecouplage", + ["it"]="modoaccoppiamento", + ["nl"]="koppelwijze", + ["pe"]="روش‌تزویج", + ["ro"]="modcuplare", + }, + ["criterium"]={ + ["cs"]="kriterium", + ["de"]="kriterium", + ["en"]="criterium", + ["fr"]="critere", + ["it"]="criterio", + ["nl"]="criterium", + ["pe"]="criterium", + ["ro"]="criteriu", + }, + ["current"]={ + ["cs"]="aktualni", + ["de"]="aktuell", + ["en"]="current", + ["fr"]="courant", + ["it"]="corrente", + ["nl"]="huidige", + ["pe"]="جاری", + ["ro"]="curent", + }, + ["cutspace"]={ + ["cs"]="cutspace", + ["de"]="cutspace", + ["en"]="cutspace", + ["fr"]="cutspace", + ["it"]="cutspace", + ["nl"]="snijwit", + ["pe"]="فضای‌برش", + ["ro"]="cutspace", + }, + ["dash"]={ + ["cs"]="pomlcka", + ["de"]="strich", + ["en"]="dash", + ["fr"]="pointille", + ["it"]="dash", + ["nl"]="streep", + ["pe"]="دش", + ["ro"]="dash", + }, + ["dat"]={ + ["cs"]="dat", + ["de"]="dat", + ["en"]="dat", + ["fr"]="dat", + ["it"]="dat", + ["nl"]="dat", + ["pe"]="dat", + ["ro"]="dat", + }, + ["date"]={ + ["cs"]="datum", + ["de"]="datum", + ["en"]="date", + ["fr"]="date", + ["it"]="data", + ["nl"]="datum", + ["pe"]="تاریخ", + ["ro"]="data", + }, + ["deepnumbercommand"]={ + ["cs"]="deepnumbercommand", + ["de"]="deepnumbercommand", + ["en"]="deepnumbercommand", + ["fr"]="deepnumbercommand", + ["it"]="deepnumbercommand", + ["nl"]="diepnummercommando", + ["pe"]="فرمان‌شماره‌عمیق", + ["ro"]="deepnumbercommand", + }, + ["deeptextcommand"]={ + ["cs"]="deeptextcommand", + ["de"]="deeptextcommand", + ["en"]="deeptextcommand", + ["fr"]="deeptextcommand", + ["it"]="deeptextcommand", + ["nl"]="dieptekstcommando", + ["pe"]="فرمان‌متن‌عمیق", + ["ro"]="deeptextcommand", + }, + ["default"]={ + ["cs"]="implicitni", + ["de"]="default", + ["en"]="default", + ["fr"]="defaut", + ["it"]="implicito", + ["nl"]="default", + ["pe"]="پیش‌فرض", + ["ro"]="implicit", + }, + ["delay"]={ + ["cs"]="prodleva", + ["de"]="wartezeit", + ["en"]="delay", + ["fr"]="delai", + ["it"]="attesa", + ["nl"]="wachttijd", + ["pe"]="تاخیر", + ["ro"]="intarziere", + }, + ["depth"]={ + ["cs"]="hloubka", + ["de"]="tiefe", + ["en"]="depth", + ["fr"]="profondeur", + ["it"]="profondita", + ["nl"]="diepte", + ["pe"]="عمق", + ["ro"]="inaltime", + }, + ["depthcorrection"]={ + ["cs"]="korekcehloubky", + ["de"]="tiefekorrektur", + ["en"]="depthcorrection", + ["fr"]="correctionprofondeur", + ["it"]="correzioneprofondita", + ["nl"]="dieptecorrectie", + ["pe"]="تصحیح‌عمق", + ["ro"]="corectieadancime", + }, + ["direction"]={ + ["cs"]="smer", + ["de"]="richtung", + ["en"]="direction", + ["fr"]="direction", + ["it"]="direzione", + ["nl"]="richting", + ["pe"]="جهت", + ["ro"]="directie", + }, + ["directory"]={ + ["cs"]="adresar", + ["de"]="verzeichnis", + ["en"]="directory", + ["fr"]="repertoire", + ["it"]="directory", + ["nl"]="gebied", + ["pe"]="پوشه", + ["ro"]="director", + }, + ["display"]={ + ["cs"]="obrazovka", + ["de"]="bildschirm", + ["en"]="display", + ["fr"]="affichage", + ["it"]="display", + ["nl"]="scherm", + ["pe"]="نمایش", + ["ro"]="display", + }, + ["distance"]={ + ["cs"]="vzdalenost", + ["de"]="abstand", + ["en"]="distance", + ["fr"]="distance", + ["it"]="distanza", + ["nl"]="afstand", + ["pe"]="فاصله", + ["ro"]="distanta", + }, + ["dot"]={ + ["cs"]="tecka", + ["de"]="punkt", + ["en"]="dot", + ["fr"]="point", + ["it"]="punto", + ["nl"]="punt", + ["pe"]="نقطه", + ["ro"]="punct", + }, + ["doublesided"]={ + ["cs"]="oboustranne", + ["de"]="doppelseitig", + ["en"]="doublesided", + ["fr"]="rectoverso", + ["it"]="doppiafaccia", + ["nl"]="dubbelzijdig", + ["pe"]="دورو", + ["ro"]="douafete", + }, + ["dummy"]={ + ["cs"]="dummy", + ["de"]="dummy", + ["en"]="dummy", + ["fr"]="dummy", + ["it"]="dummy", + ["nl"]="dummy", + ["pe"]="مصنوعی", + ["ro"]="dummy", + }, + ["dx"]={ + ["cs"]="dx", + ["de"]="dx", + ["en"]="dx", + ["fr"]="dx", + ["it"]="dx", + ["nl"]="dx", + ["pe"]="dx", + ["ro"]="dx", + }, + ["dy"]={ + ["cs"]="dy", + ["de"]="dy", + ["en"]="dy", + ["fr"]="dy", + ["it"]="dy", + ["nl"]="dy", + ["pe"]="dy", + ["ro"]="dy", + }, + ["edge"]={ + ["cs"]="hrana", + ["de"]="kante", + ["en"]="edge", + ["fr"]="bord", + ["it"]="bordo", + ["nl"]="rand", + ["pe"]="لبه", + ["ro"]="bordura", + }, + ["edgedistance"]={ + ["cs"]="vzdalenosthrany", + ["de"]="kantenabstand", + ["en"]="edgedistance", + ["fr"]="distancebord", + ["it"]="distanzabordo", + ["nl"]="randafstand", + ["pe"]="فاصله‌لبه", + ["ro"]="distantabordura", + }, + ["empty"]={ + ["cs"]="prazdne", + ["de"]="leer", + ["en"]="empty", + ["fr"]="vide", + ["it"]="vuoto", + ["nl"]="leeg", + ["pe"]="تهی", + ["ro"]="gol", + }, + ["equalheight"]={ + ["cs"]="equalheight", + ["de"]="equalheight", + ["en"]="equalheight", + ["fr"]="equalheight", + ["it"]="equalheight", + ["nl"]="equalheight", + ["pe"]="ارتفاع‌یکسان", + ["ro"]="equalheight", + }, + ["equalwidth"]={ + ["cs"]="equalwidth", + ["de"]="equalwidth", + ["en"]="equalwidth", + ["fr"]="equalwidth", + ["it"]="equalwidth", + ["nl"]="equalwidth", + ["pe"]="عرض‌یکسان", + ["ro"]="equalwidth", + }, + ["escape"]={ + ["cs"]="escape", + ["de"]="escape", + ["en"]="escape", + ["fr"]="escape", + ["it"]="escape", + ["nl"]="escape", + ["pe"]="فرار", + ["ro"]="escape", + }, + ["evenmargin"]={ + ["cs"]="sudamarginalie", + ["de"]="geraderand", + ["en"]="evenmargin", + ["fr"]="margepaire", + ["it"]="marginepari", + ["nl"]="evenmarge", + ["pe"]="حاشیه‌زوج", + ["ro"]="marginepara", + }, + ["expansion"]={ + ["cs"]="expanzen", + ["de"]="expansion", + ["en"]="expansion", + ["fr"]="expansion", + ["it"]="espansione", + ["nl"]="expansie", + ["pe"]="گسترش", + ["ro"]="expansiune", + }, + ["extras"]={ + ["cs"]="extras", + ["de"]="extras", + ["en"]="extras", + ["fr"]="extras", + ["it"]="extras", + ["nl"]="extras", + ["pe"]="extras", + ["ro"]="extras", + }, + ["factor"]={ + ["cs"]="faktor", + ["de"]="faktor", + ["en"]="factor", + ["fr"]="facteur", + ["it"]="fattore", + ["nl"]="factor", + ["pe"]="عامل", + ["ro"]="factor", + }, + ["fallback"]={ + ["cs"]="fallback", + ["de"]="fallback", + ["en"]="fallback", + ["fr"]="fallback", + ["it"]="fallback", + ["nl"]="terugval", + ["pe"]="عقب‌ریختن", + ["ro"]="fallback", + }, + ["family"]={ + ["cs"]="rodina", + ["de"]="familie", + ["en"]="family", + ["fr"]="famille", + ["it"]="famiglia", + ["nl"]="soort", + ["pe"]="خانواده", + ["ro"]="familie", + }, + ["fieldbackgroundcolor"]={ + ["cs"]="barvapozadipole", + ["de"]="feldhintergrundfarbe", + ["en"]="fieldbackgroundcolor", + ["fr"]="couleurarrierreplanchamp", + ["it"]="coloresfondocampo", + ["nl"]="veldachtergrondkleur", + ["pe"]="رنگ‌پس‌زمینه‌میدان", + ["ro"]="culoarefundalcamp", + }, + ["fieldframecolor"]={ + ["cs"]="barvarameckupole", + ["de"]="feldrahmenfarbe", + ["en"]="fieldframecolor", + ["fr"]="couleurcadrechamp", + ["it"]="colorecornicecampo", + ["nl"]="veldkaderkleur", + ["pe"]="رنگ‌قالب‌میدان", + ["ro"]="culoareframecamp", + }, + ["fieldlayer"]={ + ["cs"]="fieldlayer", + ["de"]="fieldlayer", + ["en"]="fieldlayer", + ["fr"]="calquechamp", + ["it"]="fieldlayer", + ["nl"]="veldlaag", + ["pe"]="لایه‌میدان", + ["ro"]="fieldlayer", + }, + ["fieldoffset"]={ + ["cs"]="offsetpole", + ["de"]="feldoffset", + ["en"]="fieldoffset", + ["fr"]="offsetchamp", + ["it"]="offsetcampo", + ["nl"]="veldoffset", + ["pe"]="آفست‌میدان", + ["ro"]="offsetcamp", + }, + ["file"]={ + ["cs"]="soubor", + ["de"]="datei", + ["en"]="file", + ["fr"]="fichier", + ["it"]="file", + ["nl"]="file", + ["pe"]="پرونده", + ["ro"]="fisier", + }, + ["filtercommand"]={ + ["en"]="filtercommand", + }, + ["focus"]={ + ["cs"]="zaostreni", + ["de"]="focus", + ["en"]="focus", + ["fr"]="focus", + ["it"]="focus", + ["nl"]="focus", + ["pe"]="تمرکز", + ["ro"]="focus", + }, + ["focusin"]={ + ["cs"]="focusin", + ["de"]="focusin", + ["en"]="focusin", + ["fr"]="focusin", + ["it"]="focusin", + ["nl"]="focusin", + ["pe"]="تمرکزدرون", + ["ro"]="focusin", + }, + ["focusout"]={ + ["cs"]="focusout", + ["de"]="focusout", + ["en"]="focusout", + ["fr"]="focusout", + ["it"]="focusout", + ["nl"]="focusuit", + ["pe"]="تمرکزبیرون", + ["ro"]="focusout", + }, + ["footer"]={ + ["cs"]="upati", + ["de"]="fusszeile", + ["en"]="footer", + ["fr"]="pdp", + ["it"]="piedipagina", + ["nl"]="voet", + ["pe"]="ته‌برگ", + ["ro"]="subsol", + }, + ["footerdistance"]={ + ["cs"]="vzdalenostupati", + ["de"]="fusszeilenabstand", + ["en"]="footerdistance", + ["fr"]="dsitancepdp", + ["it"]="distanzapdp", + ["nl"]="voetafstand", + ["pe"]="فاصله‌ته‌برگ", + ["ro"]="distantasubsol", + }, + ["footerstate"]={ + ["cs"]="statusupati", + ["de"]="fusszeilenstatus", + ["en"]="footerstate", + ["fr"]="etatpdp", + ["it"]="statopdp", + ["nl"]="voetstatus", + ["pe"]="وضعیت‌ته‌برگ", + ["ro"]="staresubsol", + }, + ["foregroundcolor"]={ + ["cs"]="foregroundcolor", + ["de"]="foregroundcolor", + ["en"]="foregroundcolor", + ["fr"]="couleurpremierplan", + ["it"]="coloreprimopiano", + ["nl"]="voorgrondkleur", + ["pe"]="رنگ‌پیش‌زمینه", + ["ro"]="foregroundcolor", + }, + ["foregroundstyle"]={ + ["cs"]="foregroundstyle", + ["de"]="foregroundstyle", + ["en"]="foregroundstyle", + ["fr"]="stylepremierplan", + ["it"]="foregroundstyle", + ["nl"]="voorgrondletter", + ["pe"]="سبک‌پیش‌زمینه", + ["ro"]="foregroundstyle", + }, + ["format"]={ + ["cs"]="formatovat", + ["de"]="formatieren", + ["en"]="format", + ["fr"]="formatter", + ["it"]="format", + ["nl"]="formatteer", + ["pe"]="شمایل", + ["ro"]="format", + }, + ["frame"]={ + ["cs"]="ramecek", + ["de"]="rahmen", + ["en"]="frame", + ["fr"]="cadre", + ["it"]="cornice", + ["nl"]="kader", + ["pe"]="قالب", + ["ro"]="frame", + }, + ["framecolor"]={ + ["cs"]="barvaramecku", + ["de"]="rahmenfarbe", + ["en"]="framecolor", + ["fr"]="couleurcadre", + ["it"]="colorecornice", + ["nl"]="kaderkleur", + ["pe"]="رنگ‌قالب", + ["ro"]="culoareframe", + }, + ["framecorner"]={ + ["cs"]="rohramecku", + ["de"]="rahmenwinkel", + ["en"]="framecorner", + ["fr"]="coincadre", + ["it"]="angolocornice", + ["nl"]="kaderhoek", + ["pe"]="گوشه‌قالب", + ["ro"]="coltframe", + }, + ["framedepth"]={ + ["cs"]="hloubkaramecku", + ["de"]="rahmentiefe", + ["en"]="framedepth", + ["fr"]="profondeurcadre", + ["it"]="profonditacornice", + ["nl"]="kaderdiepte", + ["pe"]="عمق‌قالب", + ["ro"]="adancimeframe", + }, + ["frameoffset"]={ + ["cs"]="offsetramecku", + ["de"]="rahmenoffset", + ["en"]="frameoffset", + ["fr"]="decalagecadre", + ["it"]="offsetcornice", + ["nl"]="kaderoffset", + ["pe"]="آفست‌قالب", + ["ro"]="offsetframe", + }, + ["frameradius"]={ + ["cs"]="polomerramecku", + ["de"]="rahmenradius", + ["en"]="frameradius", + ["fr"]="rayoncadre", + ["it"]="raggiocornice", + ["nl"]="kaderstraal", + ["pe"]="شعاع‌قالب", + ["ro"]="razaframe", + }, + ["frames"]={ + ["cs"]="ramecky", + ["de"]="umrahmen", + ["en"]="frames", + ["fr"]="cadres", + ["it"]="cornici", + ["nl"]="hokjes", + ["pe"]="قالبها", + ["ro"]="frames", + }, + ["from"]={ + ["cs"]="z", + ["de"]="von", + ["en"]="from", + ["fr"]="de", + ["it"]="da", + ["nl"]="van", + ["pe"]="از", + ["ro"]="dela", + }, + ["get"]={ + ["cs"]="ziskat", + ["de"]="hole", + ["en"]="get", + ["fr"]="obtient", + ["it"]="prendi", + ["nl"]="haal", + ["pe"]="بگیر", + ["ro"]="adu", + }, + ["global"]={ + ["cs"]="globalne", + ["de"]="global", + ["en"]="global", + ["fr"]="global", + ["it"]="globale", + ["nl"]="globaal", + ["pe"]="سراسری", + ["ro"]="global", + }, + ["grid"]={ + ["cs"]="mrizka", + ["de"]="gritter", + ["en"]="grid", + ["fr"]="grille", + ["it"]="griglia", + ["nl"]="grid", + ["pe"]="توری", + ["ro"]="grid", + }, + ["hang"]={ + ["cs"]="zaveseni", + ["de"]="haengend", + ["en"]="hang", + ["fr"]="suspend", + ["it"]="sospendi", + ["nl"]="hang", + ["pe"]="بیاویز", + ["ro"]="suspenda", + }, + ["headcolor"]={ + ["cs"]="barvahlavicky", + ["de"]="kopffarbe", + ["en"]="headcolor", + ["fr"]="couleurtete", + ["it"]="coloretesta", + ["nl"]="kopkleur", + ["pe"]="رنگ‌سر", + ["ro"]="culoaretitlu", + }, + ["headcommand"]={ + ["cs"]="headcommand", + ["de"]="headcommand", + ["en"]="headcommand", + ["fr"]="commandetete", + ["it"]="headcommand", + ["nl"]="kopcommando", + ["pe"]="فرمان‌سر", + ["ro"]="headcommand", + }, + ["headconversion"]={ + ["cs"]="konverzehlavicky", + ["de"]="headconversion", + ["en"]="headconversion", + ["fr"]="conversiontete", + ["it"]="conversionetesta", + ["nl"]="kopconversie", + ["pe"]="تبدیل‌سر", + ["ro"]="conversietitlu", + }, + ["header"]={ + ["cs"]="zahlavi", + ["de"]="kopfzeile", + ["en"]="header", + ["fr"]="entete", + ["it"]="intestazione", + ["nl"]="hoofd", + ["pe"]="سربرگ", + ["ro"]="antet", + }, + ["headerdistance"]={ + ["cs"]="vzdalenostzahlavi", + ["de"]="kopfzeilenabstand", + ["en"]="headerdistance", + ["fr"]="distanceentete", + ["it"]="distanzaintestazione", + ["nl"]="hoofdafstand", + ["pe"]="فاصله‌سربرگ", + ["ro"]="distantaantet", + }, + ["headerstate"]={ + ["cs"]="statuszahlavi", + ["de"]="kopfzeilenstatus", + ["en"]="headerstate", + ["fr"]="etatentete", + ["it"]="statointestazione", + ["nl"]="hoofdstatus", + ["pe"]="وضعیت‌سربرگ", + ["ro"]="stareantet", + }, + ["headlabel"]={ + ["cs"]="popisekhlavicky", + ["de"]="headlabel", + ["en"]="headlabel", + ["fr"]="etiquettetete", + ["it"]="etichettatesta", + ["nl"]="koplabel", + ["pe"]="برچسب‌سر", + ["ro"]="etichetatitlu", + }, + ["headnumber"]={ + ["cs"]="cislonadpisu", + ["de"]="kopfnummer", + ["en"]="headnumber", + ["fr"]="numerotete", + ["it"]="numerotesta", + ["nl"]="kopnummer", + ["pe"]="شماره‌سر", + ["ro"]="numartitlu", + }, + ["headstyle"]={ + ["cs"]="stylhlavicky", + ["de"]="kopfstil", + ["en"]="headstyle", + ["fr"]="styletete", + ["it"]="stiletesta", + ["nl"]="kopletter", + ["pe"]="سبک‌سر", + ["ro"]="stiltitlu", + }, + ["height"]={ + ["cs"]="vyska", + ["de"]="hoehe", + ["en"]="height", + ["fr"]="hauteur", + ["it"]="altezza", + ["nl"]="hoogte", + ["pe"]="ارتفاع", + ["ro"]="inaltime", + }, + ["hfactor"]={ + ["cs"]="vfaktor", + ["de"]="hfaktor", + ["en"]="hfactor", + ["fr"]="facteurhauteur", + ["it"]="hfactor", + ["nl"]="hfactor", + ["pe"]="عامل‌ارتفاع", + ["ro"]="hfactor", + }, + ["hfil"]={ + ["cs"]="hfil", + ["de"]="hfil", + ["en"]="hfil", + ["fr"]="hfil", + ["it"]="hfil", + ["nl"]="hfil", + ["pe"]="پرکردن‌ارتفاع", + ["ro"]="hfil", + }, + ["hidenumber"]={ + ["en"]="hidenumber", + }, + ["hoffset"]={ + ["cs"]="hoffset", + ["de"]="hoffset", + ["en"]="hoffset", + ["fr"]="decalagehauteur", + ["it"]="hoffset", + ["nl"]="hoffset", + ["pe"]="آفست‌ا", + ["ro"]="hoffset", + }, + ["horoffset"]={ + ["cs"]="horoffset", + ["de"]="rumpfabstand", + ["en"]="horoffset", + ["fr"]="horoffset", + ["it"]="horoffset", + ["nl"]="rugoffset", + ["pe"]="آفست‌افق", + ["ro"]="offsetoriz", + }, + ["hyphen"]={ + ["cs"]="hyphen", + ["de"]="hyphen", + ["en"]="hyphen", + ["fr"]="hyphen", + ["it"]="hyphen", + ["nl"]="hyphen", + ["pe"]="شکستن", + ["ro"]="hyphen", + }, + ["icommand"]={ + ["cs"]="iprikaz", + ["de"]="ibefehl", + ["en"]="icommand", + ["fr"]="icommande", + ["it"]="icomando", + ["nl"]="icommando", + ["pe"]="icommand", + ["ro"]="comandai", + }, + ["in"]={ + ["cs"]="v", + ["de"]="in", + ["en"]="in", + ["fr"]="in", + ["it"]="in", + ["nl"]="in", + ["pe"]="درون", + ["ro"]="in", + }, + ["inbetween"]={ + ["cs"]="mezi", + ["de"]="zwischen", + ["en"]="inbetween", + ["fr"]="entre", + ["it"]="tra", + ["nl"]="tussen", + ["pe"]="دربین", + ["ro"]="intre", + }, + ["increment"]={ + ["cs"]="zvysit", + ["de"]="erhoehen", + ["en"]="increment", + ["fr"]="incremente", + ["it"]="incremento", + ["nl"]="verhoog", + ["pe"]="افزایش", + ["ro"]="increment", + }, + ["incrementnumber"]={ + ["cs"]="zvysujicicislo", + ["de"]="nummererhoehen", + ["en"]="incrementnumber", + ["fr"]="incrementenumero", + ["it"]="incrementanumero", + ["nl"]="verhoognummer", + ["pe"]="شماره‌افزایش", + ["ro"]="numarincrement", + }, + ["indenting"]={ + ["cs"]="odsazovani", + ["de"]="einziehen", + ["en"]="indenting", + ["fr"]="composeenalinea", + ["it"]="rientro", + ["nl"]="inspringen", + ["pe"]="تورفتگی", + ["ro"]="aliniat", + }, + ["indentnext"]={ + ["cs"]="odsadpristi", + ["de"]="ziehefolgendeein", + ["en"]="indentnext", + ["fr"]="indentesuivant", + ["it"]="rientrasuccessivo", + ["nl"]="springvolgendein", + ["pe"]="متن‌تورفته", + ["ro"]="aliniaturmator", + }, + ["indicator"]={ + ["cs"]="indikator", + ["de"]="indikator", + ["en"]="indicator", + ["fr"]="indicateur", + ["it"]="indicatore", + ["nl"]="aanduiding", + ["pe"]="اندیکاتور", + ["ro"]="indicator", + }, + ["inner"]={ + ["cs"]="vnitrni", + ["de"]="innen", + ["en"]="inner", + ["fr"]="interieur", + ["it"]="interno", + ["nl"]="binnen", + ["pe"]="داخلی", + ["ro"]="intern", + }, + ["innermargin"]={ + ["cs"]="innermargin", + ["de"]="innermargin", + ["en"]="innermargin", + ["fr"]="margeinterieure", + ["it"]="margineinterno", + ["nl"]="binnenmarge", + ["pe"]="حاشیه‌داخلی", + ["ro"]="innermargin", + }, + ["inputfile"]={ + ["cs"]="inputfile", + ["de"]="inputfile", + ["en"]="inputfile", + ["fr"]="fichierentree", + ["it"]="inputfile", + ["nl"]="inputfile", + ["pe"]="پرونده‌ورودی", + ["ro"]="inputfile", + }, + ["interaction"]={ + ["cs"]="interakce", + ["de"]="interaktion", + ["en"]="interaction", + ["fr"]="interaction", + ["it"]="interazione", + ["nl"]="interactie", + ["pe"]="پانل", + ["ro"]="interactiune", + }, + ["interlinespace"]={ + ["cs"]="meziradkovamezera", + ["de"]="zeilenabstande", + ["en"]="interlinespace", + ["fr"]="espaceinterligne", + ["it"]="interlinea", + ["nl"]="interlinie", + ["pe"]="فضای‌بین‌خط", + ["ro"]="spatiereinterliniara", + }, + ["itemalign"]={ + ["cs"]="itemalign", + ["de"]="itemalign", + ["en"]="itemalign", + ["fr"]="itemalign", + ["it"]="itemalign", + ["nl"]="itemuitlijnen", + ["pe"]="تنظیم‌آیتم", + ["ro"]="itemalign", + }, + ["items"]={ + ["cs"]="polozky", + ["de"]="posten", + ["en"]="items", + ["fr"]="elements", + ["it"]="elementi", + ["nl"]="items", + ["pe"]="آیتمها", + ["ro"]="elemente", + }, + ["ken"]={ + ["cs"]="ken", + ["de"]="ken", + ["en"]="ken", + ["fr"]="ken", + ["it"]="ken", + ["nl"]="ken", + ["pe"]="ken", + ["ro"]="ken", + }, + ["keyexpansion"]={ + ["cs"]="keyexpansion", + ["de"]="keyexpansion", + ["en"]="keyexpansion", + ["fr"]="keyexpansion", + ["it"]="keyexpansion", + ["nl"]="sleutelexpansie", + ["pe"]="گسترش‌کلید", + ["ro"]="keyexpansion", + }, + ["keyword"]={ + ["cs"]="keyword", + ["de"]="keyword", + ["en"]="keyword", + ["fr"]="motcle", + ["it"]="parolachiave", + ["nl"]="trefwoord", + ["pe"]="کلید‌واژه", + ["ro"]="keyword", + }, + ["label"]={ + ["cs"]="popisek", + ["de"]="label", + ["en"]="label", + ["fr"]="etiquette", + ["it"]="etichetta", + ["nl"]="label", + ["pe"]="برچسب", + ["ro"]="eticheta", + }, + ["left"]={ + ["cs"]="vlevo", + ["de"]="links", + ["en"]="left", + ["fr"]="gauche", + ["it"]="sinistra", + ["nl"]="links", + ["pe"]="چپ", + ["ro"]="stanga", + }, + ["leftcolor"]={ + ["cs"]="barvavlevo", + ["de"]="linkerfarbe", + ["en"]="leftcolor", + ["fr"]="couleurgauche", + ["it"]="coloresinistra", + ["nl"]="linkerkleur", + ["pe"]="رنگ‌چپ", + ["ro"]="culoarestanga", + }, + ["leftcompoundhyphen"]={ + ["cs"]="leftcompoundhyphen", + ["de"]="leftcompoundhyphen", + ["en"]="leftcompoundhyphen", + ["fr"]="leftcompoundhyphen", + ["it"]="leftcompoundhyphen", + ["nl"]="linkerkoppelteken", + ["pe"]="leftcompoundhyphen", + ["ro"]="leftcompoundhyphen", + }, + ["leftedge"]={ + ["cs"]="levahrana", + ["de"]="linkekante", + ["en"]="leftedge", + ["fr"]="bordgauche", + ["it"]="bordosinistro", + ["nl"]="linkerrand", + ["pe"]="لبه‌چپ", + ["ro"]="bordurastanga", + }, + ["leftedgedistance"]={ + ["cs"]="vzdalenostlevehrany", + ["de"]="linkerkantenabstand", + ["en"]="leftedgedistance", + ["fr"]="distancebordgauche", + ["it"]="distanzabordosinistro", + ["nl"]="linkerrandafstand", + ["pe"]="فاصله‌لبه‌چپ", + ["ro"]="distantabordurastanga", + }, + ["leftframe"]={ + ["cs"]="ramecekvlevo", + ["de"]="linkerrahmen", + ["en"]="leftframe", + ["fr"]="cadregauche", + ["it"]="cornicesinistra", + ["nl"]="linkerkader", + ["pe"]="قالب‌چپ", + ["ro"]="framestanga", + }, + ["lefthyphen"]={ + ["cs"]="lefthyphen", + ["de"]="lefthyphen", + ["en"]="lefthyphen", + ["fr"]="lefthyphen", + ["it"]="lefthyphen", + ["nl"]="lefthyphen", + ["pe"]="شکست‌چپ", + ["ro"]="lefthyphen", + }, + ["leftmargin"]={ + ["cs"]="levyokraj", + ["de"]="linkerrand", + ["en"]="leftmargin", + ["fr"]="margegauche", + ["it"]="marginesinistro", + ["nl"]="linkermarge", + ["pe"]="حاشیه‌چپ", + ["ro"]="marginestanga", + }, + ["leftmargindistance"]={ + ["cs"]="vzdalenostlevehookraje", + ["de"]="linkerrandabstand", + ["en"]="leftmargindistance", + ["fr"]="distancemargegauche", + ["it"]="distanzamarginesinistro", + ["nl"]="linkermargeafstand", + ["pe"]="فاصله‌حاشیه‌چپ", + ["ro"]="distantamarginestanga", + }, + ["leftoffset"]={ + ["cs"]="levyoffset", + ["de"]="linkeroffset", + ["en"]="leftoffset", + ["fr"]="decalagegauche", + ["it"]="offsetsinistro", + ["nl"]="linkeroffset", + ["pe"]="آفست‌چپ", + ["ro"]="offsetstanga", + }, + ["leftquotation"]={ + ["cs"]="citacevlevo", + ["de"]="linkerzitat", + ["en"]="leftquotation", + ["fr"]="citationgauche", + ["it"]="citazionesinistra", + ["nl"]="linkercitaat", + ["pe"]="نقل‌قول‌چپ", + ["ro"]="citatstanga", + }, + ["leftquote"]={ + ["cs"]="citovatvlevo", + ["de"]="linkerzitieren", + ["en"]="leftquote", + ["fr"]="citergauche", + ["it"]="menzionesinistra", + ["nl"]="linkerciteer", + ["pe"]="نقل‌چپ", + ["ro"]="minicitatstanga", + }, + ["leftsentence"]={ + ["cs"]="vetavlevo", + ["de"]="linkersatz", + ["en"]="leftsentence", + ["fr"]="phrasegauche", + ["it"]="frasesinistra", + ["nl"]="linkerzin", + ["pe"]="جمله‌چپ", + ["ro"]="propozitiestanga", + }, + ["leftspeech"]={ + ["cs"]="leftspeech", + ["de"]="leftspeech", + ["en"]="leftspeech", + ["fr"]="leftspeech", + ["it"]="leftspeech", + ["nl"]="linkeruitspraak", + ["pe"]="سخنرانی‌چپ", + ["ro"]="leftspeech", + }, + ["leftstyle"]={ + ["cs"]="stylvlevo", + ["de"]="linkerstil", + ["en"]="leftstyle", + ["fr"]="leftstyle", + ["it"]="stilesinistra", + ["nl"]="linkerletter", + ["pe"]="سبک‌چپ", + ["ro"]="stilstanga", + }, + ["leftsubsentence"]={ + ["cs"]="podvetavlevo", + ["de"]="linkersubsatz", + ["en"]="leftsubsentence", + ["fr"]="sousphrasegauche", + ["it"]="sottofrasesinistra", + ["nl"]="linkersubzin", + ["pe"]="زیرجمله‌چپ", + ["ro"]="subpropozitiestanga", + }, + ["lefttext"]={ + ["cs"]="textvlevo", + ["de"]="linkertext", + ["en"]="lefttext", + ["fr"]="textegauche", + ["it"]="testosinistro", + ["nl"]="linkertekst", + ["pe"]="متن‌چپ", + ["ro"]="textstanga", + }, + ["leftwidth"]={ + ["cs"]="sirkavlevo", + ["de"]="linkerbreite", + ["en"]="leftwidth", + ["fr"]="largeurgauche", + ["it"]="ampiezzasinistra", + ["nl"]="linkerbreedte", + ["pe"]="عرض‌خط", + ["ro"]="latimestanga", + }, + ["level"]={ + ["cs"]="uroven", + ["de"]="niveau", + ["en"]="level", + ["fr"]="niveau", + ["it"]="livello", + ["nl"]="niveau", + ["pe"]="مرحله", + ["ro"]="nivel", + }, + ["levels"]={ + ["cs"]="urovne", + ["de"]="niveaus", + ["en"]="levels", + ["fr"]="niveaux", + ["it"]="livelli", + ["nl"]="niveaus", + ["pe"]="مرحله‌ها", + ["ro"]="nivele", + }, + ["limittext"]={ + ["cs"]="limittext", + ["de"]="limittext", + ["en"]="limittext", + ["fr"]="limittext", + ["it"]="limittext", + ["nl"]="limiettekst", + ["pe"]="مرزمتن", + ["ro"]="limittext", + }, + ["line"]={ + ["cs"]="radek", + ["de"]="zeile", + ["en"]="line", + ["fr"]="ligne", + ["it"]="riga", + ["nl"]="regel", + ["pe"]="خط", + ["ro"]="linie", + }, + ["linecorrection"]={ + ["cs"]="korekceradku", + ["de"]="zeilekorrektur", + ["en"]="linecorrection", + ["fr"]="correctionligne", + ["it"]="correzioneriga", + ["nl"]="regelcorrectie", + ["pe"]="تصحیح‌خط", + ["ro"]="corectielinie", + }, + ["lines"]={ + ["cs"]="radky", + ["de"]="zeilen", + ["en"]="lines", + ["fr"]="lignes", + ["it"]="righe", + ["nl"]="regels", + ["pe"]="خطها", + ["ro"]="linii", + }, + ["list"]={ + ["cs"]="seznam", + ["de"]="liste", + ["en"]="list", + ["fr"]="liste", + ["it"]="elenco", + ["nl"]="lijst", + ["pe"]="لیست", + ["ro"]="lista", + }, + ["listtext"]={ + ["cs"]="listtext", + ["de"]="listtext", + ["en"]="listtext", + ["fr"]="texteliste", + ["it"]="listtext", + ["nl"]="lijsttekst", + ["pe"]="متن‌لیست", + ["ro"]="listtext", + }, + ["local"]={ + ["cs"]="lokalne", + ["de"]="lokal", + ["en"]="local", + ["fr"]="local", + ["it"]="locale", + ["nl"]="lokaal", + ["pe"]="موضعی", + ["ro"]="local", + }, + ["location"]={ + ["cs"]="misto", + ["de"]="platz", + ["en"]="location", + ["fr"]="emplacement", + ["it"]="luogo", + ["nl"]="plaats", + ["pe"]="مکان", + ["ro"]="locatie", + }, + ["logo"]={ + ["cs"]="logo", + ["de"]="logo", + ["en"]="logo", + ["fr"]="logo", + ["it"]="logo", + ["nl"]="logo", + ["pe"]="آرم", + ["ro"]="logo", + }, + ["logos"]={ + ["cs"]="loga", + ["de"]="logos", + ["en"]="logos", + ["fr"]="logos", + ["it"]="loghi", + ["nl"]="logos", + ["pe"]="آرمها", + ["ro"]="logos", + }, + ["marcolor"]={ + ["cs"]="barvaznacky", + ["de"]="beschrfarbe", + ["en"]="marcolor", + ["fr"]="couleurmarquage", + ["it"]="coloremarcatura", + ["nl"]="markleur", + ["pe"]="رنگ‌حاش", + ["ro"]="culoaremarcaj", + }, + ["margin"]={ + ["cs"]="marginalie", + ["de"]="marginalie", + ["en"]="margin", + ["fr"]="marge", + ["it"]="margine", + ["nl"]="marge", + ["pe"]="حاشیه", + ["ro"]="margine", + }, + ["margindistance"]={ + ["cs"]="vzdalenostokraje", + ["de"]="marginalabstand", + ["en"]="margindistance", + ["fr"]="distancemarge", + ["it"]="distanzamargine", + ["nl"]="margeafstand", + ["pe"]="فاصله‌حاشیه", + ["ro"]="distantamargine", + }, + ["marginedge"]={ + ["cs"]="textovahrana", + ["de"]="marginalkante", + ["en"]="marginedge", + ["fr"]="bordmarge", + ["it"]="bordomargine", + ["nl"]="kantlijn", + ["pe"]="لبه‌حاشیه", + ["ro"]="coltbordura", + }, + ["marginedgetext"]={ + ["cs"]="textmarginalnihookraje", + ["de"]="marginalkantetext", + ["en"]="marginedgetext", + ["fr"]="textebordmarge", + ["it"]="testobordomargine", + ["nl"]="kantlijntekst", + ["pe"]="متن‌لبه‌حاشیه", + ["ro"]="textcoltbordura", + }, + ["margintext"]={ + ["cs"]="textmarginalie", + ["de"]="marginaltext", + ["en"]="margintext", + ["fr"]="textemarge", + ["it"]="testomargine", + ["nl"]="margetekst", + ["pe"]="متن‌حاشیه", + ["ro"]="textmargine", + }, + ["marking"]={ + ["cs"]="znaceni", + ["de"]="beschriftung", + ["en"]="marking", + ["fr"]="marquage", + ["it"]="marcatura", + ["nl"]="markering", + ["pe"]="نشانه‌گذاری", + ["ro"]="marcaje", + }, + ["marstyle"]={ + ["cs"]="stylsnacky", + ["de"]="beschrstil", + ["en"]="marstyle", + ["fr"]="stylemarquage", + ["it"]="stilemarcatura", + ["nl"]="marletter", + ["pe"]="سبک‌حاش", + ["ro"]="stilmarcaj", + }, + ["max"]={ + ["cs"]="max", + ["de"]="max", + ["en"]="max", + ["fr"]="max", + ["it"]="max", + ["nl"]="max", + ["pe"]="بیشترین", + ["ro"]="max", + }, + ["maxheight"]={ + ["cs"]="maxvyska", + ["de"]="maxhoehe", + ["en"]="maxheight", + ["fr"]="hauteurmax", + ["it"]="altezzamax", + ["nl"]="maxhoogte", + ["pe"]="بیشترین‌ارتفاع", + ["ro"]="inaltimemaxima", + }, + ["maxdepth"]={ + ["en"]="maxdepth", + }, + ["maxwidth"]={ + ["cs"]="maxsirka", + ["de"]="maxbreite", + ["en"]="maxwidth", + ["fr"]="largeurmax", + ["it"]="ampiezzamax", + ["nl"]="maxbreedte", + ["pe"]="بیشترین‌عرض", + ["ro"]="latimemaxima", + }, + ["menu"]={ + ["cs"]="menu", + ["de"]="menue", + ["en"]="menu", + ["fr"]="menu", + ["it"]="menu", + ["nl"]="menu", + ["pe"]="منو", + ["ro"]="meniu", + }, + ["method"]={ + ["cs"]="metoda", + ["de"]="methode", + ["en"]="method", + ["fr"]="methode", + ["it"]="metodo", + ["nl"]="methode", + ["pe"]="روش", + ["ro"]="metoda", + }, + ["middle"]={ + ["cs"]="stredni", + ["de"]="mittig", + ["en"]="middle", + ["fr"]="milieu", + ["it"]="centro", + ["nl"]="midden", + ["pe"]="میان", + ["ro"]="mijloc", + }, + ["middlespeech"]={ + ["cs"]="middlespeech", + ["de"]="middlespeech", + ["en"]="middlespeech", + ["fr"]="middlespeech", + ["it"]="middlespeech", + ["nl"]="middenuitspraak", + ["pe"]="سخنرانی‌میانی", + ["ro"]="middlespeech", + }, + ["middletext"]={ + ["cs"]="strednitext", + ["de"]="mittigertext", + ["en"]="middletext", + ["fr"]="textecentre", + ["it"]="testocentro", + ["nl"]="middentekst", + ["pe"]="متن‌میانی", + ["ro"]="textmijloc", + }, + ["midsentence"]={ + ["cs"]="midsentence", + ["de"]="midsentence", + ["en"]="midsentence", + ["fr"]="midsentence", + ["it"]="midsentence", + ["nl"]="middenzin", + ["pe"]="جمله‌میانی", + ["ro"]="midsentence", + }, + ["min"]={ + ["cs"]="min", + ["de"]="min", + ["en"]="min", + ["fr"]="min", + ["it"]="min", + ["nl"]="min", + ["pe"]="کمترین", + ["ro"]="min", + }, + ["mindepth"]={ + ["cs"]="mindepth", + ["de"]="mindepth", + ["en"]="mindepth", + ["fr"]="profondeurmin", + ["it"]="mindeoth", + ["nl"]="mindiepte", + ["pe"]="کمترین‌عمق", + ["ro"]="mindepth", + }, + ["minheight"]={ + ["cs"]="minvyska", + ["de"]="minhoehe", + ["en"]="minheight", + ["fr"]="hauteurmin", + ["it"]="altezzamin", + ["nl"]="minhoogte", + ["pe"]="کمترین‌ارتفاع", + ["ro"]="inaltimeminima", + }, + ["minwidth"]={ + ["cs"]="minsirka", + ["de"]="minbreite", + ["en"]="minwidth", + ["fr"]="largeurmin", + ["it"]="ampiezzamin", + ["nl"]="minbreedte", + ["pe"]="کمترین‌عرض", + ["ro"]="latimeminima", + }, + ["monthconversion"]={ + ["en"]="monthconversion", + ["nl"]="maandconversie", + }, + ["n"]={ + ["cs"]="n", + ["de"]="n", + ["en"]="n", + ["fr"]="n", + ["it"]="n", + ["nl"]="n", + ["pe"]="n", + ["ro"]="n", + }, + ["name"]={ + ["cs"]="jmeno", + ["de"]="name", + ["en"]="name", + ["fr"]="nom", + ["it"]="nome", + ["nl"]="naam", + ["pe"]="نام", + ["ro"]="nume", + }, + ["nbottom"]={ + ["cs"]="nspodek", + ["de"]="nunten", + ["en"]="nbottom", + ["fr"]="ninf", + ["it"]="nfondo", + ["nl"]="nonder", + ["pe"]="nbottom", + ["ro"]="njos", + }, + ["nc"]={ + ["cs"]="nc", + ["de"]="nc", + ["en"]="nc", + ["fr"]="nc", + ["it"]="nc", + ["nl"]="nc", + ["pe"]="nc", + ["ro"]="nc", + }, + ["next"]={ + ["cs"]="dalsi", + ["de"]="folgende", + ["en"]="next", + ["fr"]="suivant", + ["it"]="successivo", + ["nl"]="volgende", + ["pe"]="بعدی", + ["ro"]="urmatorul", + }, + ["nl"]={ + ["cs"]="nl", + ["de"]="nl", + ["en"]="nl", + ["fr"]="nl", + ["it"]="nl", + ["nl"]="nl", + ["pe"]="nl", + ["ro"]="nl", + }, + ["nleft"]={ + ["cs"]="nvlevo", + ["de"]="nlinks", + ["en"]="nleft", + ["fr"]="ngauche", + ["it"]="nsinistra", + ["nl"]="nlinks", + ["pe"]="nleft", + ["ro"]="nstanga", + }, + ["nlines"]={ + ["cs"]="nradky", + ["de"]="zzeile", + ["en"]="nlines", + ["fr"]="nlignes", + ["it"]="nrighe", + ["nl"]="nregels", + ["pe"]="nlines", + ["ro"]="nlinii", + }, + ["norm"]={ + ["cs"]="norm", + ["de"]="norm", + ["en"]="norm", + ["fr"]="norme", + ["it"]="norma", + ["nl"]="norm", + ["pe"]="norm", + ["ro"]="norm", + }, + ["nr"]={ + ["cs"]="nr", + ["de"]="nr", + ["en"]="nr", + ["fr"]="nr", + ["it"]="nr", + ["nl"]="nr", + ["pe"]="nr", + ["ro"]="nr", + }, + ["nright"]={ + ["cs"]="nvpravo", + ["de"]="nrechts", + ["en"]="nright", + ["fr"]="ndroite", + ["it"]="ndestra", + ["nl"]="nrechts", + ["pe"]="nright", + ["ro"]="ndreapta", + }, + ["ntop"]={ + ["cs"]="nvrsek", + ["de"]="noben", + ["en"]="ntop", + ["fr"]="nsup", + ["it"]="ncima", + ["nl"]="nboven", + ["pe"]="ntop", + ["ro"]="nsus", + }, + ["number"]={ + ["cs"]="cislo", + ["de"]="nummer", + ["en"]="number", + ["fr"]="numero", + ["it"]="numero", + ["nl"]="nummer", + ["pe"]="شماره", + ["ro"]="numar", + }, + ["numbercolor"]={ + ["cs"]="barvacisla", + ["de"]="nummernfarbe", + ["en"]="numbercolor", + ["fr"]="couleurnumero", + ["it"]="colorenumero", + ["nl"]="nummerkleur", + ["pe"]="رنگ‌شماره", + ["ro"]="culoarenumar", + }, + ["numbercommand"]={ + ["cs"]="ciselnyprikaz", + ["de"]="nummerbefehl", + ["en"]="numbercommand", + ["fr"]="commandenumero", + ["it"]="comandonumero", + ["nl"]="nummercommando", + ["pe"]="فرمان‌شماره", + ["ro"]="comandanumar", + }, + ["numberconversion"]={ + ["en"]="numberconversion", + }, + ["numberconversionset"]={ + ["en"]="numberconversionset", + }, + ["numberdistance"]={ + ["cs"]="numberdistance", + ["de"]="numberdistance", + ["en"]="numberdistance", + ["fr"]="numberdistance", + ["it"]="numberdistance", + ["nl"]="nummerafstand", + ["pe"]="فاصله‌شماره", + ["ro"]="numberdistance", + }, + ["numbering"]={ + ["cs"]="cislovani", + ["de"]="nummerierung", + ["en"]="numbering", + ["fr"]="numerotation", + ["it"]="numerazione", + ["nl"]="nummeren", + ["pe"]="شماره‌گذاری", + ["ro"]="numerotare", + }, + ["numberorder"]={ + ["en"]="numberorder", + }, + ["numberprefix"]={ + ["en"]="numberprefix", + }, + ["numbersegments"]={ + ["en"]="numbersegments", + }, + ["numberseparator"]={ + ["cs"]="oddelovaccisla", + ["de"]="nummernseperator", + ["en"]="numberseparator", + ["fr"]="separateurnumbero", + ["it"]="separatorenumero", + ["nl"]="nummerscheider", + ["pe"]="جداکننده‌شماره", + ["ro"]="separatornumar", + }, + ["numberseparatorset"]={ + ["en"]="numberseparatorset", + }, + ["numberset"]={ + ["en"]="numberset", + }, + ["numberstopper"]={ + ["en"]="numberstopper", + }, + ["numberstarter"]={ + ["en"]="numberstarter", + }, + ["numberstyle"]={ + ["cs"]="stylcisla", + ["de"]="nummernstil", + ["en"]="numberstyle", + ["fr"]="stylenumero", + ["it"]="stilenumero", + ["nl"]="nummerletter", + ["pe"]="سبک‌شماره", + ["ro"]="stilnumar", + }, + ["numberwidth"]={ + ["cs"]="numberwidth", + ["de"]="numberwidth", + ["en"]="numberwidth", + ["fr"]="numberwidth", + ["it"]="numberwidth", + ["nl"]="nummerbreedte", + ["pe"]="عرض‌شماره", + ["ro"]="numberwidth", + }, + ["nx"]={ + ["cs"]="nx", + ["de"]="nx", + ["en"]="nx", + ["fr"]="nx", + ["it"]="nx", + ["nl"]="nx", + ["pe"]="nx", + ["ro"]="nx", + }, + ["ny"]={ + ["cs"]="ny", + ["de"]="ny", + ["en"]="ny", + ["fr"]="ny", + ["it"]="ny", + ["nl"]="ny", + ["pe"]="ny", + ["ro"]="ny", + }, + ["object"]={ + ["cs"]="objekt", + ["de"]="objekt", + ["en"]="object", + ["fr"]="objet", + ["it"]="oggetto", + ["nl"]="object", + ["pe"]="شیئ", + ["ro"]="obiect", + }, + ["obstruction"]={ + ["cs"]="prekazka", + ["de"]="gesperrt", + ["en"]="obstruction", + ["fr"]="obstruction", + ["it"]="ostruzione", + ["nl"]="blokkade", + ["pe"]="انسداد", + ["ro"]="obstructie", + }, + ["oddmargin"]={ + ["cs"]="lichyokraj", + ["de"]="ungeraderand", + ["en"]="oddmargin", + ["fr"]="margepaire", + ["it"]="marginedispari", + ["nl"]="onevenmarge", + ["pe"]="حاشیه‌فرد", + ["ro"]="margineimpara", + }, + ["offset"]={ + ["cs"]="offset", + ["de"]="offset", + ["en"]="offset", + ["fr"]="offset", + ["it"]="offset", + ["nl"]="offset", + ["pe"]="آفست", + ["ro"]="offset", + }, + ["openaction"]={ + ["cs"]="otevriakci", + ["de"]="oeffenaktion", + ["en"]="openaction", + ["fr"]="actionouverture", + ["it"]="azioneapri", + ["nl"]="openactie", + ["pe"]="عمل‌باز", + ["ro"]="actiunedeschidere", + }, + ["openpageaction"]={ + ["cs"]="akceotevrenistranky", + ["de"]="openpageaction", + ["en"]="openpageaction", + ["fr"]="actionouverturepage", + ["it"]="azioneapripagina", + ["nl"]="openpaginaactie", + ["pe"]="عمل‌صفحه‌باز", + ["ro"]="actiunedeschiderepagina", + }, + ["option"]={ + ["cs"]="volba", + ["de"]="option", + ["en"]="option", + ["fr"]="option", + ["it"]="opzione", + ["nl"]="optie", + ["pe"]="گزینه", + ["ro"]="optiune", + }, + ["orientation"]={ + ["cs"]="orientation", + ["de"]="orientation", + ["en"]="orientation", + ["fr"]="orientation", + ["it"]="orientation", + ["nl"]="orientatie", + ["pe"]="جهت‌دهی", + ["ro"]="orientation", + }, + ["outermargin"]={ + ["cs"]="outermargin", + ["de"]="outermargin", + ["en"]="outermargin", + ["fr"]="margeexterieure", + ["it"]="margineesterno", + ["nl"]="buitenmarge", + ["pe"]="حاشیه‌خارجی", + ["ro"]="outermargin", + }, + ["overprint"]={ + ["cs"]="overprint", + ["de"]="overprint", + ["en"]="overprint", + ["fr"]="overprint", + ["it"]="overprint", + ["nl"]="overprint", + ["pe"]="overprint", + ["ro"]="overprint", + }, + ["ownnumber"]={ + ["cs"]="vlastnicislo", + ["de"]="eigenenummer", + ["en"]="ownnumber", + ["fr"]="numeroproprio", + ["it"]="numeroproprio", + ["nl"]="eigennummer", + ["pe"]="شماره‌خود", + ["ro"]="numarpropriu", + }, + ["page"]={ + ["cs"]="stranka", + ["de"]="seite", + ["en"]="page", + ["fr"]="page", + ["it"]="pagina", + ["nl"]="pagina", + ["pe"]="صفحه", + ["ro"]="pagina", + }, + ["pageboundaries"]={ + ["cs"]="hranicestranky", + ["de"]="seitenbegrenzung", + ["en"]="pageboundaries", + ["fr"]="limitespage", + ["it"]="limitipagina", + ["nl"]="paginaovergangen", + ["pe"]="مرزهای‌صفحه", + ["ro"]="marginipagina", + }, + ["pagecolor"]={ + ["cs"]="barvastranky", + ["de"]="seitenfarbe", + ["en"]="pagecolor", + ["fr"]="couleurpage", + ["it"]="colorepagina", + ["nl"]="paginakleur", + ["pe"]="رنگ‌صفحه", + ["ro"]="culoarepagina", + }, + ["pagecommand"]={ + ["cs"]="strankovyprikaz", + ["de"]="seitenbefehl", + ["en"]="pagecommand", + ["fr"]="commandepage", + ["it"]="comandopagina", + ["nl"]="paginacommando", + ["pe"]="فرمان‌صفحه", + ["ro"]="comandapagina", + }, + ["pageconversion"]={ + ["en"]="pageconversion", + }, + ["pageconversionset"]={ + ["en"]="pageconversionset", + }, + ["pagenumber"]={ + ["cs"]="cislostranky", + ["de"]="seitennummer", + ["en"]="pagenumber", + ["fr"]="numeropage", + ["it"]="numeropagina", + ["nl"]="paginanummer", + ["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", + }, + ["pageprefixstarter"]={ + ["en"]="pageprefixstarter", + }, + ["pagesegments"]={ + ["en"]="pagesegments", + }, + ["pageseparatorset"]={ + ["en"]="pageseparatorset", + }, + ["pageset"]={ + ["en"]="pageset", + }, + ["pagestate"]={ + ["cs"]="pagestate", + ["de"]="pagestate", + ["en"]="pagestate", + ["fr"]="etatpage", + ["it"]="statopagina", + ["nl"]="paginastatus", + ["pe"]="وضعیت‌صفحه", + ["ro"]="pagestate", + }, + ["pagestopper"]={ + ["en"]="pagestopper", + }, + ["pagestarter"]={ + ["en"]="pagestarter", + }, + ["pagestyle"]={ + ["cs"]="stylstranky", + ["de"]="seitenstil", + ["en"]="pagestyle", + ["fr"]="stylepage", + ["it"]="stilepagina", + ["nl"]="paginaletter", + ["pe"]="سبک‌صفحه", + ["ro"]="stilpagina", + }, + ["palet"]={ + ["cs"]="paleta", + ["de"]="palette", + ["en"]="palet", + ["fr"]="palette", + ["it"]="tavolozza", + ["nl"]="palet", + ["pe"]="لوح", + ["ro"]="paleta", + }, + ["paper"]={ + ["cs"]="papir", + ["de"]="papier", + ["en"]="paper", + ["fr"]="papier", + ["it"]="carta", + ["nl"]="papier", + ["pe"]="برگ", + ["ro"]="hartie", + }, + ["paragraph"]={ + ["cs"]="odstavec", + ["de"]="absatz", + ["en"]="paragraph", + ["fr"]="paragraphe", + ["it"]="capoverso", + ["nl"]="alinea", + ["pe"]="پاراگراف", + ["ro"]="paragraf", + }, + ["place"]={ + ["cs"]="umistit", + ["de"]="platziere", + ["en"]="place", + ["fr"]="place", + ["it"]="metti", + ["nl"]="plaatsen", + ["pe"]="بگذار", + ["ro"]="pune", + }, + ["placehead"]={ + ["cs"]="umistihlavicku", + ["de"]="setzekopf", + ["en"]="placehead", + ["fr"]="placetete", + ["it"]="mettitesta", + ["nl"]="plaatskop", + ["pe"]="بگذارسر", + ["ro"]="punetitlu", + }, + ["placestopper"]={ + ["cs"]="predelmista", + ["de"]="setzetrenner", + ["en"]="placestopper", + ["fr"]="emplacementstopper", + ["it"]="mettistopper", + ["nl"]="plaatsafsluiter", + ["pe"]="بگذارایست", + ["ro"]="punestopper", + }, + ["position"]={ + ["cs"]="position", + ["de"]="position", + ["en"]="position", + ["fr"]="position", + ["it"]="posizione", + ["nl"]="positie", + ["pe"]="موقعیت", + ["ro"]="pozitie", + }, + ["prefix"]={ + ["cs"]="prefix", + ["de"]="prefix", + ["en"]="prefix", + ["fr"]="prefixe", + ["it"]="prefisso", + ["nl"]="prefix", + ["pe"]="پیشوند", + ["ro"]="prefix", + }, + ["prefixconnector"]={ + ["en"]="prefixconnector", + }, + ["prefixconversion"]={ + ["en"]="prefixconversion", + }, + ["prefixconversionset"]={ + ["en"]="prefixconversionset", + }, + ["prefixsegments"]={ + ["en"]="prefixsegments", + }, + ["prefixseparatorset"]={ + ["en"]="prefixseparatorset", + }, + ["prefixset"]={ + ["en"]="prefixset", + }, + ["prefixstopper"]={ + ["en"]="prefixstopper", + }, + ["prefixstarter"]={ + ["en"]="prefixstarter", + }, + ["preset"]={ + ["cs"]="prednastaveni", + ["de"]="voreinstellung", + ["en"]="preset", + ["fr"]="prereglage", + ["it"]="preimpostato", + ["nl"]="preset", + ["pe"]="preset", + ["ro"]="preset", + }, + ["preview"]={ + ["cs"]="nahled", + ["de"]="vorschau", + ["en"]="preview", + ["fr"]="previsualisation", + ["it"]="anteprima", + ["nl"]="preview", + ["pe"]="پیش‌دید", + ["ro"]="previzualizare", + }, + ["previous"]={ + ["cs"]="predchozi", + ["de"]="vorige", + ["en"]="previous", + ["fr"]="precedent", + ["it"]="precedente", + ["nl"]="vorige", + ["pe"]="قبلی", + ["ro"]="precendent", + }, + ["previousnumber"]={ + ["cs"]="predchozicislo", + ["de"]="vorigenummer", + ["en"]="previousnumber", + ["fr"]="numeroprecedent", + ["it"]="numeroprecedente", + ["nl"]="vorigenummer", + ["pe"]="شماره‌قبلی", + ["ro"]="numarprecedent", + }, + ["process"]={ + ["cs"]="process", + ["de"]="process", + ["en"]="process", + ["fr"]="process", + ["it"]="process", + ["nl"]="proces", + ["pe"]="پردازش", + ["ro"]="process", + }, + ["radius"]={ + ["cs"]="polomer", + ["de"]="radius", + ["en"]="radius", + ["fr"]="rayon", + ["it"]="raggio", + ["nl"]="straal", + ["pe"]="شعاع", + ["ro"]="raza", + }, + ["random"]={ + ["cs"]="nahodne", + ["de"]="zufaellig", + ["en"]="random", + ["fr"]="aleatoire", + ["it"]="casuale", + ["nl"]="willekeur", + ["pe"]="تصادفی", + ["ro"]="aleator", + }, + ["range"]={ + ["en"]="range", + ["nl"]="bereik", + }, + ["reduction"]={ + ["cs"]="redukce", + ["de"]="reduktion", + ["en"]="reduction", + ["fr"]="reduction", + ["it"]="riduzione", + ["nl"]="reductie", + ["pe"]="کاهش", + ["ro"]="reducere", + }, + ["ref"]={ + ["cs"]="ref", + ["de"]="ref", + ["en"]="ref", + ["fr"]="ref", + ["it"]="ref", + ["nl"]="ref", + ["pe"]="رج", + ["ro"]="ref", + }, + ["reference"]={ + ["cs"]="odkaz", + ["de"]="referenz", + ["en"]="reference", + ["fr"]="reference", + ["it"]="riferimento", + ["nl"]="verwijzing", + ["pe"]="مرجع", + ["ro"]="referinta", + }, + ["referenceprefix"]={ + ["en"]="referenceprefix", + }, + ["referencing"]={ + ["cs"]="odkazujici", + ["de"]="referieren", + ["en"]="referencing", + ["fr"]="referencing", + ["it"]="referencing", + ["nl"]="refereren", + ["pe"]="مراجعه", + ["ro"]="referinta", + }, + ["regionin"]={ + ["cs"]="oblastuvnitr", + ["de"]="regionin", + ["en"]="regionin", + ["fr"]="entreregion", + ["it"]="entraregione", + ["nl"]="gebiedin", + ["pe"]="ناحیه‌درون", + ["ro"]="regiuneintrare", + }, + ["regionout"]={ + ["cs"]="oblastvne", + ["de"]="regionaus", + ["en"]="regionout", + ["fr"]="regionexterieure", + ["it"]="esciregione", + ["nl"]="gebieduit", + ["pe"]="ناحیه‌بیرون", + ["ro"]="regiuneiesire", + }, + ["repeat"]={ + ["cs"]="opakovat", + ["de"]="wiederholen", + ["en"]="repeat", + ["fr"]="repete", + ["it"]="ripeti", + ["nl"]="herhaal", + ["pe"]="تکرار", + ["ro"]="repeta", + }, + ["reset"]={ + ["cs"]="reset", + ["de"]="reset", + ["en"]="reset", + ["fr"]="reset", + ["it"]="reset", + ["nl"]="reset", + ["pe"]="بازنشانی", + ["ro"]="reset", + }, + ["resetnumber"]={ + ["cs"]="resetnumber", + ["de"]="resetnumber", + ["en"]="resetnumber", + ["fr"]="raznumero", + ["it"]="resetnumber", + ["nl"]="resetnummer", + ["pe"]="بازنشانی‌شماره", + ["ro"]="resetnumber", + }, + ["resolution"]={ + ["cs"]="rozliseni", + ["de"]="aufloesung", + ["en"]="resolution", + ["fr"]="resolution", + ["it"]="risoluzione", + ["nl"]="resolutie", + ["pe"]="کیفیت", + ["ro"]="rezolutie", + }, + ["right"]={ + ["cs"]="vpravo", + ["de"]="rechts", + ["en"]="right", + ["fr"]="droite", + ["it"]="destra", + ["nl"]="rechts", + ["pe"]="راست", + ["ro"]="dreapta", + }, + ["rightcolor"]={ + ["cs"]="barvavpravo", + ["de"]="rechterfarbe", + ["en"]="rightcolor", + ["fr"]="couleurdroite", + ["it"]="coloredestra", + ["nl"]="rechterkleur", + ["pe"]="رنگ‌راست", + ["ro"]="culoaredreapta", + }, + ["rightcompoundhyphen"]={ + ["cs"]="rightcompoundhyphen", + ["de"]="rightcompoundhyphen", + ["en"]="rightcompoundhyphen", + ["fr"]="rightcompoundhyphen", + ["it"]="rightcompoundhyphen", + ["nl"]="rechterkoppelteken", + ["pe"]="rightcompoundhyphen", + ["ro"]="rightcompoundhyphen", + }, + ["rightedge"]={ + ["cs"]="pravahrana", + ["de"]="rechtekante", + ["en"]="rightedge", + ["fr"]="borddroit", + ["it"]="bordodestro", + ["nl"]="rechterrand", + ["pe"]="لبه‌راست", + ["ro"]="borduradreapta", + }, + ["rightedgedistance"]={ + ["cs"]="vzdalenostpravehrany", + ["de"]="rechterkantenabstand", + ["en"]="rightedgedistance", + ["fr"]="distanceborddroit", + ["it"]="distanzabordodestro", + ["nl"]="rechterrandafstand", + ["pe"]="فاصله‌لبه‌راست", + ["ro"]="distantacoltdreapta", + }, + ["rightframe"]={ + ["cs"]="ramecekvpravo", + ["de"]="rechterrahmen", + ["en"]="rightframe", + ["fr"]="cadredroit", + ["it"]="cornicedestra", + ["nl"]="rechterkader", + ["pe"]="قالب‌راست", + ["ro"]="framedreapta", + }, + ["righthyphen"]={ + ["cs"]="righthyphen", + ["de"]="righthyphen", + ["en"]="righthyphen", + ["fr"]="righthyphen", + ["it"]="righthyphen", + ["nl"]="righthyphen", + ["pe"]="righthyphen", + ["ro"]="righthyphen", + }, + ["rightmargin"]={ + ["cs"]="pravyokraj", + ["de"]="rechterrand", + ["en"]="rightmargin", + ["fr"]="margedroite", + ["it"]="marginedestro", + ["nl"]="rechtermarge", + ["pe"]="حاشیه‌راست", + ["ro"]="marginedreapta", + }, + ["rightmargindistance"]={ + ["cs"]="vzdalenostpravehookraje", + ["de"]="rechterrandabstand", + ["en"]="rightmargindistance", + ["fr"]="distancemargedroite", + ["it"]="distanzamarginedestro", + ["nl"]="rechtermargeafstand", + ["pe"]="فاصله‌حاشیه‌راست", + ["ro"]="distantamarginedreapta", + }, + ["rightoffset"]={ + ["cs"]="pravyoffset", + ["de"]="rechterabstand", + ["en"]="rightoffset", + ["fr"]="rightoffset", + ["it"]="offsetdestro", + ["nl"]="rechteroffset", + ["pe"]="آفست‌راست", + ["ro"]="offsetdreapta", + }, + ["rightquotation"]={ + ["cs"]="citacevpravo", + ["de"]="rechterzitat", + ["en"]="rightquotation", + ["fr"]="citationdroite", + ["it"]="citazionedestra", + ["nl"]="rechtercitaat", + ["pe"]="نقل‌قول‌راست", + ["ro"]="citatdreapta", + }, + ["rightquote"]={ + ["cs"]="citovatvpravo", + ["de"]="rechterzitieren", + ["en"]="rightquote", + ["fr"]="citerdroite", + ["it"]="menzionedestra", + ["nl"]="rechterciteer", + ["pe"]="نقل‌راست", + ["ro"]="minicitatdreapta", + }, + ["rightsentence"]={ + ["cs"]="vetavpravo", + ["de"]="rechtersatz", + ["en"]="rightsentence", + ["fr"]="phrasedroite", + ["it"]="frasedestra", + ["nl"]="rechterzin", + ["pe"]="جمله‌راست", + ["ro"]="propozitiedreapta", + }, + ["rightspeech"]={ + ["cs"]="rightspeech", + ["de"]="rightspeech", + ["en"]="rightspeech", + ["fr"]="rightspeech", + ["it"]="rightspeech", + ["nl"]="rechteruitspraak", + ["pe"]="سخنرانی‌راست", + ["ro"]="rightspeech", + }, + ["rightstyle"]={ + ["cs"]="stylvpravo", + ["de"]="rechterstil", + ["en"]="rightstyle", + ["fr"]="styledroit", + ["it"]="stiledestra", + ["nl"]="rechterletter", + ["pe"]="سبک‌راست", + ["ro"]="stildreapta", + }, + ["rightsubsentence"]={ + ["cs"]="podvetavpravo", + ["de"]="rechtersubsatz", + ["en"]="rightsubsentence", + ["fr"]="sousphrasedroite", + ["it"]="sottofrasedestra", + ["nl"]="rechtersubzin", + ["pe"]="زیرجمله‌راست", + ["ro"]="subpropozitiedreapta", + }, + ["righttext"]={ + ["cs"]="textvpravo", + ["de"]="rechtertext", + ["en"]="righttext", + ["fr"]="textedroit", + ["it"]="testodestro", + ["nl"]="rechtertekst", + ["pe"]="متن‌راست", + ["ro"]="textdreapta", + }, + ["rightwidth"]={ + ["cs"]="sirkavpravo", + ["de"]="rechterbreite", + ["en"]="rightwidth", + ["fr"]="largeurdroite", + ["it"]="ampiezzadestra", + ["nl"]="rechterbreedte", + ["pe"]="عرض‌راست", + ["ro"]="marginedreapta", + }, + ["rotation"]={ + ["cs"]="rotace", + ["de"]="rotation", + ["en"]="rotation", + ["fr"]="rotation", + ["it"]="rotazione", + ["nl"]="rotatie", + ["pe"]="دوران", + ["ro"]="rotatie", + }, + ["rule"]={ + ["cs"]="linka", + ["de"]="linie", + ["en"]="rule", + ["fr"]="ligne", + ["it"]="linea", + ["nl"]="lijn", + ["pe"]="خط", + ["ro"]="rigla", + }, + ["rulecolor"]={ + ["cs"]="barvalinky", + ["de"]="linienfarbe", + ["en"]="rulecolor", + ["fr"]="couleurligne", + ["it"]="colorelinea", + ["nl"]="lijnkleur", + ["pe"]="رنگ‌خط", + ["ro"]="culoarerigla", + }, + ["rulethickness"]={ + ["cs"]="tloustkalinky", + ["de"]="liniendicke", + ["en"]="rulethickness", + ["fr"]="epaisseurligne", + ["it"]="spessorelinea", + ["nl"]="lijndikte", + ["pe"]="ضخامت‌خط", + ["ro"]="grosimerigla", + }, + ["samepage"]={ + ["cs"]="stejnastranka", + ["de"]="selbeseite", + ["en"]="samepage", + ["fr"]="memepage", + ["it"]="stessapagina", + ["nl"]="zelfdepagina", + ["pe"]="همان‌صفحه", + ["ro"]="aceeasipagina", + }, + ["sample"]={ + ["cs"]="vzor", + ["de"]="muster", + ["en"]="sample", + ["fr"]="echantillon", + ["it"]="campione", + ["nl"]="monster", + ["pe"]="نمونه", + ["ro"]="exemplu", + }, + ["saveinlist"]={ + ["en"]="saveinlist", + }, + ["scale"]={ + ["cs"]="meritko", + ["de"]="format", + ["en"]="scale", + ["fr"]="echelle", + ["it"]="scala", + ["nl"]="schaal", + ["pe"]="مقیاس", + ["ro"]="scala", + }, + ["scope"]={ + ["cs"]="rozsah", + ["de"]="bereich", + ["en"]="scope", + ["fr"]="scope", + ["it"]="scope", + ["nl"]="scope", + ["pe"]="طرح", + ["ro"]="scop", + }, + ["screen"]={ + ["cs"]="rastr", + ["de"]="raster", + ["en"]="screen", + ["fr"]="ecran", + ["it"]="schermo", + ["nl"]="raster", + ["pe"]="پرده", + ["ro"]="ecran", + }, + ["section"]={ + ["cs"]="oddil", + ["de"]="abschnitt", + ["en"]="section", + ["fr"]="section", + ["it"]="sezione", + ["nl"]="sectie", + ["pe"]="بخش", + ["ro"]="sectiune", + }, + ["sectionconversion"]={ + ["en"]="sectionconversion", + }, + ["sectionconversionset"]={ + ["en"]="sectionconversionset", + }, + ["sectionnumber"]={ + ["cs"]="cislooddilu", + ["de"]="abschnittsnummer", + ["en"]="sectionnumber", + ["fr"]="numerosection", + ["it"]="numerosezione", + ["nl"]="sectienummer", + ["pe"]="شماره‌بخش", + ["ro"]="numarsectiune", + }, + ["sectionresetset"]={ + ["en"]="sectionresetset", + }, + ["sectionsegments"]={ + ["en"]="sectionsegments", + }, + ["sectionseparatorset"]={ + ["en"]="sectionseparatorset", + }, + ["sectionset"]={ + ["en"]="sectionset", + }, + ["sectionstopper"]={ + ["en"]="sectionstopper", + }, + ["sectionstarter"]={ + ["en"]="sectionstarter", + }, + ["separator"]={ + ["cs"]="oddelovac", + ["de"]="seperator", + ["en"]="separator", + ["fr"]="separateur", + ["it"]="separatore", + ["nl"]="scheider", + ["pe"]="جداکننده", + ["ro"]="separator", + }, + ["set"]={ + ["cs"]="set", + ["de"]="set", + ["en"]="set", + ["fr"]="set", + ["it"]="set", + ["nl"]="set", + ["pe"]="قراربده", + ["ro"]="set", + }, + ["setups"]={ + ["cs"]="setups", + ["de"]="setups", + ["en"]="setups", + ["fr"]="reglages", + ["it"]="setups", + ["nl"]="setups", + ["pe"]="بارگذاریها", + ["ro"]="setups", + }, + ["side"]={ + ["cs"]="pocitat", + ["de"]="objektabstand", + ["en"]="side", + ["fr"]="cote", + ["it"]="lato", + ["nl"]="zij", + ["pe"]="کنار", + ["ro"]="parte", + }, + ["sidealign"]={ + ["cs"]="sidealign", + ["de"]="sidealign", + ["en"]="sidealign", + ["fr"]="sidealign", + ["it"]="sidealign", + ["nl"]="zijuitlijnen", + ["pe"]="تنظیم‌کنار", + ["ro"]="sidealign", + }, + ["sidemethod"]={ + ["cs"]="sidemethod", + ["de"]="sidemethod", + ["en"]="sidemethod", + ["fr"]="sidemethod", + ["it"]="sidemethod", + ["nl"]="zijmethode", + ["pe"]="روش‌کنار", + ["ro"]="sidemethod", + }, + ["sidespaceafter"]={ + ["cs"]="bocnimezeraza", + ["de"]="nebennachspatium", + ["en"]="sidespaceafter", + ["fr"]="espacelateralapres", + ["it"]="spaziolateraledopo", + ["nl"]="zijnawit", + ["pe"]="فضای‌کناری‌بعد", + ["ro"]="spatiulateraldupa", + }, + ["sidespacebefore"]={ + ["cs"]="bocnimezerapred", + ["de"]="nebenvorspatium", + ["en"]="sidespacebefore", + ["fr"]="espacelateralavant", + ["it"]="spaziolateraleprima", + ["nl"]="zijvoorwit", + ["pe"]="فضای‌کناری‌قبل", + ["ro"]="spatiulateralinainte", + }, + ["sign"]={ + ["cs"]="znak", + ["de"]="zeichen", + ["en"]="sign", + ["fr"]="signe", + ["it"]="segno", + ["nl"]="teken", + ["pe"]="علامت", + ["ro"]="semn", + }, + ["size"]={ + ["cs"]="velikost", + ["de"]="groesse", + ["en"]="size", + ["fr"]="dimension", + ["it"]="dimensione", + ["nl"]="formaat", + ["pe"]="اندازه", + ["ro"]="dimensiune", + }, + ["small"]={ + ["cs"]="male", + ["de"]="klein", + ["en"]="small", + ["fr"]="petit", + ["it"]="piccolo", + ["nl"]="klein", + ["pe"]="کوچک", + ["ro"]="mic", + }, + ["sort"]={ + ["en"]="sort", + }, + ["sorttype"]={ + ["cs"]="sorttype", + ["de"]="sorttype", + ["en"]="sorttype", + ["fr"]="sorttype", + ["it"]="sorttype", + ["nl"]="sortering", + ["pe"]="ترتیب‌تایپ", + ["ro"]="sorttype", + }, + ["source"]={ + ["cs"]="zdroj", + ["de"]="quelle", + ["en"]="source", + ["fr"]="origine", + ["it"]="origine", + ["nl"]="bron", + ["pe"]="منبع", + ["ro"]="sursa", + }, + ["space"]={ + ["cs"]="mezera", + ["de"]="spatium", + ["en"]="space", + ["fr"]="espace", + ["it"]="spazio", + ["nl"]="spatie", + ["pe"]="فضا", + ["ro"]="spatiu", + }, + ["spaceafter"]={ + ["cs"]="mezeraza", + ["de"]="nachspatium", + ["en"]="spaceafter", + ["fr"]="espaceapres", + ["it"]="spaziodopo", + ["nl"]="nawit", + ["pe"]="فضا‌بعداز", + ["ro"]="spatiudupa", + }, + ["spacebefore"]={ + ["cs"]="mezerapred", + ["de"]="vorspatium", + ["en"]="spacebefore", + ["fr"]="espaceavant", + ["it"]="spazioprima", + ["nl"]="voorwit", + ["pe"]="فضا‌قبل‌از", + ["ro"]="spatiuinainte", + }, + ["spaceinbetween"]={ + ["cs"]="spaceinbetween", + ["de"]="spaceinbetween", + ["en"]="spaceinbetween", + ["fr"]="spaceinbetween", + ["it"]="spaceinbetween", + ["nl"]="tussenwit", + ["pe"]="فضا‌دربین", + ["ro"]="spaceinbetween", + }, + ["spacing"]={ + ["cs"]="mezerovani", + ["de"]="spatiumausgleich", + ["en"]="spacing", + ["fr"]="espacement", + ["it"]="spaziatura", + ["nl"]="spatiering", + ["pe"]="فضاگذاری", + ["ro"]="spatiere", + }, + ["split"]={ + ["cs"]="split", + ["de"]="split", + ["en"]="split", + ["fr"]="split", + ["it"]="separa", + ["nl"]="splitsen", + ["pe"]="شکافتن", + ["ro"]="split", + }, + ["splitcolor"]={ + ["cs"]="splitcolor", + ["de"]="splitcolor", + ["en"]="splitcolor", + ["fr"]="splitcolor", + ["it"]="splitcolor", + ["nl"]="splitskleur", + ["pe"]="شکافتن‌رنگ", + ["ro"]="splitcolor", + }, + ["splitmethod"]={ + ["cs"]="splitmethod", + ["de"]="splitmethod", + ["en"]="splitmethod", + ["fr"]="splitmethod", + ["it"]="splitmethod", + ["nl"]="splitsmethode", + ["pe"]="روش‌شکافتن", + ["ro"]="splitmethod", + }, + ["splitoffset"]={ + ["cs"]="splitoffset", + ["de"]="splitoffset", + ["en"]="splitoffset", + ["fr"]="splitoffset", + ["it"]="splitoffset", + ["nl"]="splitsoffset", + ["pe"]="شکافتن‌آفست", + ["ro"]="splitoffset", + }, + ["spot"]={ + ["cs"]="spot", + ["de"]="spot", + ["en"]="spot", + ["fr"]="spot", + ["it"]="spot", + ["nl"]="spot", + ["pe"]="لکه", + ["ro"]="spot", + }, + ["stack"]={ + ["cs"]="stack", + ["de"]="stack", + ["en"]="stack", + ["fr"]="stack", + ["it"]="stack", + ["nl"]="stapel", + ["pe"]="توده", + ["ro"]="stack", + }, + ["start"]={ + ["cs"]="start", + ["de"]="start", + ["en"]="start", + ["fr"]="demarre", + ["it"]="inizia", + ["nl"]="start", + ["pe"]="شروع", + ["ro"]="start", + }, + ["state"]={ + ["cs"]="status", + ["de"]="status", + ["en"]="state", + ["fr"]="etat", + ["it"]="stato", + ["nl"]="status", + ["pe"]="وضعیت", + ["ro"]="stare", + }, + ["step"]={ + ["cs"]="krok", + ["de"]="schritt", + ["en"]="step", + ["fr"]="pas", + ["it"]="passo", + ["nl"]="stap", + ["pe"]="گام", + ["ro"]="pas", + }, + ["stop"]={ + ["cs"]="stop", + ["de"]="stop", + ["en"]="stop", + ["fr"]="stoppe", + ["it"]="termina", + ["nl"]="stop", + ["pe"]="پایان", + ["ro"]="stop", + }, + ["stopper"]={ + ["cs"]="predel", + ["de"]="abschnitttrenner", + ["en"]="stopper", + ["fr"]="taquet", + ["it"]="stopper", + ["nl"]="afsluiter", + ["pe"]="ایست", + ["ro"]="stopper", + }, + ["starter"]={ + ["en"]="starter", + ["nl"]="opener", + }, + ["stretch"]={ + ["cs"]="natahnout", + ["de"]="strecken", + ["en"]="stretch", + ["fr"]="etire", + ["it"]="dilata", + ["nl"]="rek", + ["pe"]="کشیدن", + ["ro"]="dilatat", + }, + ["strut"]={ + ["cs"]="strut", + ["de"]="strut", + ["en"]="strut", + ["fr"]="strut", + ["it"]="strut", + ["nl"]="strut", + ["pe"]="بست", + ["ro"]="strut", + }, + ["style"]={ + ["cs"]="pismeno", + ["de"]="stil", + ["en"]="style", + ["fr"]="style", + ["it"]="stile", + ["nl"]="letter", + ["pe"]="سبک", + ["ro"]="stil", + }, + ["sub"]={ + ["cs"]="pod", + ["de"]="unter", + ["en"]="sub", + ["fr"]="sous", + ["it"]="sotto", + ["nl"]="sub", + ["pe"]="زیر", + ["ro"]="sub", + }, + ["subtitle"]={ + ["cs"]="podtitulek", + ["de"]="untertitel", + ["en"]="subtitle", + ["fr"]="soustitre", + ["it"]="sottotitolo", + ["nl"]="subtitel", + ["pe"]="زیرعنوان", + ["ro"]="subtitlu", + }, + ["suffix"]={ + ["cs"]="suffix", + ["de"]="suffix", + ["en"]="suffix", + ["fr"]="suffix", + ["it"]="suffix", + ["nl"]="suffix", + ["pe"]="پسوند", + ["ro"]="suffix", + }, + ["sx"]={ + ["cs"]="sx", + ["de"]="sx", + ["en"]="sx", + ["fr"]="sx", + ["it"]="sx", + ["nl"]="sx", + ["pe"]="sx", + ["ro"]="sx", + }, + ["sy"]={ + ["cs"]="sy", + ["de"]="sy", + ["en"]="sy", + ["fr"]="sy", + ["it"]="sy", + ["nl"]="sy", + ["pe"]="sy", + ["ro"]="sy", + }, + ["symalign"]={ + ["cs"]="symzarovnani", + ["de"]="symausrichtung", + ["en"]="symalign", + ["fr"]="symalignement", + ["it"]="symallinea", + ["nl"]="symuitlijnen", + ["pe"]="تنظیم‌نماد", + ["ro"]="symaliniere", + }, + ["symbol"]={ + ["cs"]="symbol", + ["de"]="symbol", + ["en"]="symbol", + ["fr"]="symbole", + ["it"]="simbolo", + ["nl"]="symbool", + ["pe"]="نماد", + ["ro"]="simbol", + }, + ["symbolset"]={ + ["cs"]="sadasymbolu", + ["de"]="symbolset", + ["en"]="symbolset", + ["fr"]="jeusymbole", + ["it"]="setsimboli", + ["nl"]="symboolset", + ["pe"]="مجموعه‌نماد", + ["ro"]="setsimbol", + }, + ["symcolor"]={ + ["cs"]="barvasymbolu", + ["de"]="symfarbe", + ["en"]="symcolor", + ["fr"]="couleursym", + ["it"]="coloresimbolo", + ["nl"]="symkleur", + ["pe"]="رنگ‌نماد", + ["ro"]="culoaresimbol", + }, + ["symstyle"]={ + ["cs"]="stylsymboly", + ["de"]="symstil", + ["en"]="symstyle", + ["fr"]="stylesym", + ["it"]="stilesimbolo", + ["nl"]="symletter", + ["pe"]="سبک‌نماد", + ["ro"]="stilsimbol", + }, + ["synonym"]={ + ["cs"]="synonymum", + ["de"]="synonym", + ["en"]="synonym", + ["fr"]="synonyme", + ["it"]="sinonimo", + ["nl"]="synoniem", + ["pe"]="مترادف", + ["ro"]="sinonim", + }, + ["synonymcolor"]={ + ["cs"]="barvasynonyma", + ["de"]="synonymfarbe", + ["en"]="synonymcolor", + ["fr"]="couleursynonyme", + ["it"]="coloresinonimi", + ["nl"]="synoniemkleur", + ["pe"]="رنگ‌مترادف", + ["ro"]="culoaresinonim", + }, + ["synonymcommand"]={ + ["cs"]="synonymcommand", + ["de"]="synonymbefehl", + ["en"]="synonymcommand", + ["fr"]="synonymcommand", + ["it"]="synonymcommand", + ["nl"]="synoniemcommando", + ["pe"]="synonymcommand", + ["ro"]="synonymcommand", + }, + ["synonymstyle"]={ + ["cs"]="stylsynonyma", + ["de"]="synonymstil", + ["en"]="synonymstyle", + ["fr"]="stylesynonyme", + ["it"]="stilesinonimi", + ["nl"]="synoniemletter", + ["pe"]="سبک‌مترادف", + ["ro"]="stilsinonim", + }, + ["tab"]={ + ["cs"]="tab", + ["de"]="tab", + ["en"]="tab", + ["fr"]="tab", + ["it"]="tab", + ["nl"]="tab", + ["pe"]="تب", + ["ro"]="tab", + }, + ["text"]={ + ["cs"]="text", + ["de"]="text", + ["en"]="text", + ["fr"]="texte", + ["it"]="testo", + ["nl"]="tekst", + ["pe"]="متن", + ["ro"]="text", + }, + ["textcolor"]={ + ["cs"]="barvatextu", + ["de"]="textfarbe", + ["en"]="textcolor", + ["fr"]="couleurtexte", + ["it"]="coloretesto", + ["nl"]="tekstkleur", + ["pe"]="رنگ‌متن", + ["ro"]="culoaretext", + }, + ["textcommand"]={ + ["cs"]="textovyprikaz", + ["de"]="textbefehl", + ["en"]="textcommand", + ["fr"]="commandetexte", + ["it"]="comandotesto", + ["nl"]="tekstcommando", + ["pe"]="فرمان‌متن", + ["ro"]="comandatext", + }, + ["textdistance"]={ + ["cs"]="textdistance", + ["de"]="textdistance", + ["en"]="textdistance", + ["fr"]="distancetexte", + ["it"]="distanzatesto", + ["nl"]="tekstafstand", + ["pe"]="فاصله‌متن", + ["ro"]="textdistance", + }, + ["textlayer"]={ + ["cs"]="textlayer", + ["de"]="textlayer", + ["en"]="textlayer", + ["fr"]="calquetexte", + ["it"]="textlayer", + ["nl"]="tekstlaag", + ["pe"]="لایه‌متن", + ["ro"]="textlayer", + }, + ["textmargin"]={ + ["cs"]="textmargin", + ["de"]="textmargin", + ["en"]="textmargin", + ["fr"]="margetexte", + ["it"]="textmargin", + ["nl"]="tekstmarge", + ["pe"]="حاشیه‌متن", + ["ro"]="textmargin", + }, + ["textmethod"]={ + ["cs"]="textmethod", + ["de"]="textmethod", + ["en"]="textmethod", + ["fr"]="textmethod", + ["it"]="textmethod", + ["nl"]="tekstmethode", + ["pe"]="روش‌متن", + ["ro"]="textmethod", + }, + ["textseparator"]={ + ["cs"]="oddelovactextu", + ["de"]="textseparator", + ["en"]="textseparator", + ["fr"]="separateurtexte", + ["it"]="separatoretesto", + ["nl"]="tekstscheider", + ["pe"]="جداکننده‌متن", + ["ro"]="separatortext", + }, + ["textsize"]={ + ["cs"]="velikosttextu", + ["de"]="textgroesse", + ["en"]="textsize", + ["fr"]="tailletexte", + ["it"]="dimensionetesto", + ["nl"]="tekstformaat", + ["pe"]="اندازه‌متن", + ["ro"]="dimensiunetext", + }, + ["textstate"]={ + ["cs"]="statustextu", + ["de"]="textstatus", + ["en"]="textstate", + ["fr"]="etattexte", + ["it"]="statotesto", + ["nl"]="tekststatus", + ["pe"]="وضعیت‌متن", + ["ro"]="staretext", + }, + ["textstyle"]={ + ["cs"]="styltextu", + ["de"]="textstil", + ["en"]="textstyle", + ["fr"]="styletexte", + ["it"]="stiletesto", + ["nl"]="tekstletter", + ["pe"]="سبک‌متن", + ["ro"]="stiltext", + }, + ["textwidth"]={ + ["cs"]="sirkatextu", + ["de"]="textbreite", + ["en"]="textwidth", + ["fr"]="largeurtexte", + ["it"]="ampiezzatesto", + ["nl"]="tekstbreedte", + ["pe"]="عرض‌متن", + ["ro"]="latimetext", + }, + ["title"]={ + ["cs"]="titul", + ["de"]="titel", + ["en"]="title", + ["fr"]="titre", + ["it"]="titolo", + ["nl"]="titel", + ["pe"]="عنوان", + ["ro"]="titlu", + }, + ["titlecolor"]={ + ["cs"]="barvatitulek", + ["de"]="titelfarbe", + ["en"]="titlecolor", + ["fr"]="couleurtitre", + ["it"]="coloretitolo", + ["nl"]="titelkleur", + ["pe"]="رنگ‌عنوان", + ["ro"]="culoaretitlu", + }, + ["titlecommand"]={ + ["cs"]="titlecommand", + ["de"]="titlecommand", + ["en"]="titlecommand", + ["fr"]="titlecommand", + ["it"]="titlecommand", + ["nl"]="titelcommando", + ["pe"]="فرمان‌عنوان", + ["ro"]="titlecommand", + }, + ["titledistance"]={ + ["cs"]="vzdalenosttitulek", + ["de"]="titelabstand", + ["en"]="titledistance", + ["fr"]="distancetitre", + ["it"]="distanzatitolo", + ["nl"]="titelafstand", + ["pe"]="فاصله‌عنوان", + ["ro"]="distantatitlu", + }, + ["titleleft"]={ + ["cs"]="titleleft", + ["de"]="titleleft", + ["en"]="titleleft", + ["fr"]="titleleft", + ["it"]="titleleft", + ["nl"]="titellinks", + ["pe"]="عنوان‌چپ", + ["ro"]="titleleft", + }, + ["titleright"]={ + ["cs"]="titleright", + ["de"]="titleright", + ["en"]="titleright", + ["fr"]="titleright", + ["it"]="titleright", + ["nl"]="titelrechts", + ["pe"]="عنوان‌راست", + ["ro"]="titleright", + }, + ["titlestyle"]={ + ["cs"]="styltitulek", + ["de"]="titelstil", + ["en"]="titlestyle", + ["fr"]="styletitre", + ["it"]="stiletitolo", + ["nl"]="titelletter", + ["pe"]="سبک‌عنوان", + ["ro"]="stiltitlu", + }, + ["to"]={ + ["cs"]="na", + ["de"]="zu", + ["en"]="to", + ["fr"]="vers", + ["it"]="verso", + ["nl"]="aan", + ["pe"]="به", + ["ro"]="catre", + }, + ["tolerance"]={ + ["cs"]="tolerance", + ["de"]="toleranz", + ["en"]="tolerance", + ["fr"]="tolerance", + ["it"]="tolleranza", + ["nl"]="tolerantie", + ["pe"]="بردباری", + ["ro"]="toleranta", + }, + ["top"]={ + ["cs"]="vrsek", + ["de"]="oben", + ["en"]="top", + ["fr"]="sup", + ["it"]="cima", + ["nl"]="boven", + ["pe"]="بالا", + ["ro"]="sus", + }, + ["topdistance"]={ + ["cs"]="vzdalenostvrsku", + ["de"]="obenabstand", + ["en"]="topdistance", + ["fr"]="distancesup", + ["it"]="distanzacima", + ["nl"]="bovenafstand", + ["pe"]="فاصله‌بالا", + ["ro"]="distantasus", + }, + ["topframe"]={ + ["cs"]="rameceknahore", + ["de"]="obenrahmen", + ["en"]="topframe", + ["fr"]="cadresup", + ["it"]="cornicecima", + ["nl"]="bovenkader", + ["pe"]="قالب‌راست", + ["ro"]="framesus", + }, + ["topoffset"]={ + ["cs"]="offsetvrsku", + ["de"]="obenoffset", + ["en"]="topoffset", + ["fr"]="decalagesup", + ["it"]="offsetcima", + ["nl"]="bovenoffset", + ["pe"]="آفست‌بالا", + ["ro"]="offsetsus", + }, + ["topspace"]={ + ["cs"]="svrchnimezera", + ["de"]="kopfspatium", + ["en"]="topspace", + ["fr"]="espacesup", + ["it"]="spaziocima", + ["nl"]="kopwit", + ["pe"]="فضای‌بالا", + ["ro"]="spatiusus", + }, + ["topstate"]={ + ["cs"]="statusvrsku", + ["de"]="statusoben", + ["en"]="topstate", + ["fr"]="etatsup", + ["it"]="statocima", + ["nl"]="bovenstatus", + ["pe"]="وضعیت‌بالا", + ["ro"]="staresus", + }, + ["type"]={ + ["cs"]="typ", + ["de"]="typ", + ["en"]="type", + ["fr"]="type", + ["it"]="type", + ["nl"]="type", + ["pe"]="تایپ", + ["ro"]="type", + }, + ["unit"]={ + ["cs"]="jednotka", + ["de"]="einheit", + ["en"]="unit", + ["fr"]="unite", + ["it"]="unita", + ["nl"]="eenheid", + ["pe"]="واحد", + ["ro"]="unitate", + }, + ["unknownreference"]={ + ["cs"]="neznamyodkaz", + ["de"]="unbekantereferenz", + ["en"]="unknownreference", + ["fr"]="referenceinconnue", + ["it"]="riferimentoingoto", + ["nl"]="onbekendeverwijzing", + ["pe"]="مرجع‌ناشناس", + ["ro"]="referintanecunoscuta", + }, + ["urlalternative"]={ + ["cs"]="urlalternativa", + ["de"]="urlalternative", + ["en"]="urlalternative", + ["fr"]="alternativeurl", + ["it"]="alternativaurl", + ["nl"]="urlvariant", + ["pe"]="urlalternative", + ["ro"]="urlalternativ", + }, + ["urlspace"]={ + ["cs"]="prostorurl", + ["de"]="urlspatium", + ["en"]="urlspace", + ["fr"]="espaceurl", + ["it"]="spaziourl", + ["nl"]="urlspatie", + ["pe"]="urlspace", + ["ro"]="spatiuurl", + }, + ["validate"]={ + ["cs"]="validovat", + ["de"]="validieren", + ["en"]="validate", + ["fr"]="valider", + ["it"]="verifica", + ["nl"]="valideer", + ["pe"]="تاییداعتبار", + ["ro"]="verifica", + }, + ["vcommand"]={ + ["cs"]="vprikaz", + ["de"]="vbefehl", + ["en"]="vcommand", + ["fr"]="vcommande", + ["it"]="vcomando", + ["nl"]="vcommando", + ["pe"]="vcommand", + ["ro"]="comandav", + }, + ["veroffset"]={ + ["cs"]="offsethlavicky", + ["de"]="kopfoffset", + ["en"]="veroffset", + ["fr"]="veroffset", + ["it"]="veroffset", + ["nl"]="kopoffset", + ["pe"]="آفست‌عم", + ["ro"]="veroffset", + }, + ["vfil"]={ + ["cs"]="vfil", + ["de"]="vfil", + ["en"]="vfil", + ["fr"]="vfil", + ["it"]="vfil", + ["nl"]="vfil", + ["pe"]="vfil", + ["ro"]="vfil", + }, + ["voffset"]={ + ["cs"]="voffset", + ["de"]="voffset", + ["en"]="voffset", + ["fr"]="voffset", + ["it"]="voffset", + ["nl"]="voffset", + ["pe"]="آفست‌ع", + ["ro"]="voffset", + }, + ["way"]={ + ["cs"]="zpusob", + ["de"]="art", + ["en"]="way", + ["fr"]="mode", + ["it"]="modo", + ["nl"]="wijze", + ["pe"]="راه", + ["ro"]="mod", + }, + ["wfactor"]={ + ["cs"]="sfaktor", + ["de"]="bfaktor", + ["en"]="wfactor", + ["fr"]="facteurlargeur", + ["it"]="wfactor", + ["nl"]="bfactor", + ["pe"]="wfactor", + ["ro"]="factorw", + }, + ["white"]={ + ["cs"]="bily", + ["de"]="weiss", + ["en"]="white", + ["fr"]="blanc", + ["it"]="bianco", + ["nl"]="wit", + ["pe"]="سفید", + ["ro"]="alb", + }, + ["width"]={ + ["cs"]="sirka", + ["de"]="breite", + ["en"]="width", + ["fr"]="largeur", + ["it"]="ampiezza", + ["nl"]="breedte", + ["pe"]="عرض", + ["ro"]="latime", + }, + ["xfactor"]={ + ["cs"]="xfaktor", + ["de"]="xfaktor", + ["en"]="xfactor", + ["fr"]="xfactor", + ["it"]="xfactor", + ["nl"]="xfactor", + ["pe"]="فاکتورایکس", + ["ro"]="xfactor", + }, + ["xmax"]={ + ["cs"]="xmax", + ["de"]="xmax", + ["en"]="xmax", + ["fr"]="xmax", + ["it"]="xmax", + ["nl"]="xmax", + ["pe"]="xmax", + ["ro"]="xmax", + }, + ["xoffset"]={ + ["cs"]="xoffset", + ["de"]="xoffset", + ["en"]="xoffset", + ["fr"]="xoffset", + ["it"]="xoffset", + ["nl"]="xoffset", + ["pe"]="آفست‌ایکس", + ["ro"]="xoffset", + }, + ["xscale"]={ + ["cs"]="xmeritko", + ["de"]="xformat", + ["en"]="xscale", + ["fr"]="xscale", + ["it"]="xscale", + ["nl"]="xschaal", + ["pe"]="مقیاس‌ایکس", + ["ro"]="xscala", + }, + ["xstep"]={ + ["cs"]="xkrok", + ["de"]="xschritt", + ["en"]="xstep", + ["fr"]="xstep", + ["it"]="xstep", + ["nl"]="xstap", + ["pe"]="گام‌ایکس", + ["ro"]="xstep", + }, + ["yfactor"]={ + ["cs"]="yfaktor", + ["de"]="yfaktor", + ["en"]="yfactor", + ["fr"]="yfactor", + ["it"]="yfactor", + ["nl"]="yfactor", + ["pe"]="فاکتوروای", + ["ro"]="yfactor", + }, + ["ymax"]={ + ["cs"]="ymax", + ["de"]="ymax", + ["en"]="ymax", + ["fr"]="ymax", + ["it"]="ymax", + ["nl"]="ymax", + ["pe"]="ymax", + ["ro"]="ymax", + }, + ["yoffset"]={ + ["cs"]="yoffset", + ["de"]="yoffset", + ["en"]="yoffset", + ["fr"]="yoffset", + ["it"]="yoffset", + ["nl"]="yoffset", + ["pe"]="آفست‌وای", + ["ro"]="yoffset", + }, + ["yscale"]={ + ["cs"]="ymeritko", + ["de"]="yformat", + ["en"]="yscale", + ["fr"]="yscale", + ["it"]="yscale", + ["nl"]="yschaal", + ["pe"]="مقیاس‌وای", + ["ro"]="yscala", + }, + ["ystep"]={ + ["cs"]="ykrok", + ["de"]="yschritt", + ["en"]="ystep", + ["fr"]="ystep", + ["it"]="ystep", + ["nl"]="ystap", + ["pe"]="گام‌وای", + ["ro"]="ystep", + }, + }, + ["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", + ["en"]="begin", + ["fr"]="debut", + ["it"]="inizio", + ["nl"]="beginvan", + ["pe"]="عنصرها", + ["ro"]="inceput", + }, + ["complete"]={ + ["cs"]="uplny", + ["de"]="vollende", + ["en"]="complete", + ["fr"]="complete", + ["it"]="completo", + ["nl"]="volledige", + ["pe"]="کامل", + ["ro"]="complet", + }, + ["coupled"]={ + ["cs"]="propojene", + ["de"]="verknuepft", + ["en"]="coupled", + ["fr"]="couple", + ["it"]="accoppiato", + ["nl"]="gekoppelde", + ["pe"]="مزدوج", + ["ro"]="cuplat", + }, + ["currentlocal"]={ + ["cs"]="aktualnelokalni", + ["de"]="aktuelllokal", + ["en"]="currentlocal", + ["fr"]="localcourant", + ["it"]="correntelocale", + ["nl"]="huidigelokale", + ["pe"]="موضعی‌جاری", + ["ro"]="localcurent", + }, + ["emptyone"]={ + ["cs"]="leer", + ["de"]="vuoto", + ["en"]="empty", + ["fr"]="vide", + ["it"]="prazdne", + ["nl"]="leeg", + ["pe"]="یک‌خالی", + ["ro"]="gol", + }, + ["emptytwo"]={ + ["cs"]="prazdne", + ["de"]="leer", + ["en"]="empty", + ["fr"]="vide", + ["it"]="vuoti", + ["nl"]="lege", + ["pe"]="دوخالی", + ["ro"]="gol", + }, + ["end"]={ + ["cs"]="konec", + ["de"]="ende", + ["en"]="end", + ["fr"]="fin", + ["it"]="fine", + ["nl"]="eindvan", + ["pe"]="انتها", + ["ro"]="sfarsit", + }, + ["endsetup"]={ + ["cs"]="", + ["de"]="ein", + ["en"]="", + ["fr"]="", + ["it"]="", + ["nl"]="in", + ["pe"]="انتهای‌بارگذاری", + ["ro"]="", + }, + ["get"]={ + ["cs"]="ziskat", + ["de"]="get", + ["en"]="get", + ["fr"]="obtient", + ["it"]="prendi", + ["nl"]="haal", + ["pe"]="بگیر", + ["ro"]="get", + }, + ["increment"]={ + ["cs"]="zvysit", + ["de"]="erhoehen", + ["en"]="increment", + ["fr"]="incremente", + ["it"]="incrementa", + ["nl"]="verhoog", + ["pe"]="افزایش", + ["ro"]="increment", + }, + ["list"]={ + ["cs"]="seznam", + ["de"]="auflisten", + ["en"]="list", + ["fr"]="liste", + ["it"]="elenco", + ["nl"]="lijst", + ["pe"]="لیست", + ["ro"]="lista", + }, + ["listof"]={ + ["cs"]="seznam", + ["de"]="auflistenvon", + ["en"]="listof", + ["fr"]="listede", + ["it"]="elencodi", + ["nl"]="lijstmet", + ["pe"]="لیست‌از", + ["ro"]="listade", + }, + ["load"]={ + ["cs"]="nacist", + ["de"]="laden", + ["en"]="load", + ["fr"]="charge", + ["it"]="carica", + ["nl"]="laad", + ["pe"]="بارگذاشتن", + ["ro"]="incarca", + }, + ["local"]={ + ["cs"]="lokalne", + ["de"]="lokal", + ["en"]="local", + ["fr"]="local", + ["it"]="locale", + ["nl"]="lokale", + ["pe"]="موضعی", + ["ro"]="local", + }, + ["makeup"]={ + ["cs"]="zlom", + ["de"]="umbruch", + ["en"]="makeup", + ["fr"]="makeup", + ["it"]="makeup", + ["nl"]="opmaak", + ["pe"]="آرایش", + ["ro"]="makeup", + }, + ["next"]={ + ["cs"]="dalsi", + ["de"]="folgende", + ["en"]="next", + ["fr"]="suivant", + ["it"]="successivo", + ["nl"]="volgende", + ["pe"]="بعدی", + ["ro"]="urmatorul", + }, + ["place"]={ + ["cs"]="umisti", + ["de"]="platziere", + ["en"]="place", + ["fr"]="place", + ["it"]="metti", + ["nl"]="plaats", + ["pe"]="مکان", + ["ro"]="pune", + }, + ["previous"]={ + ["cs"]="predchozi", + ["de"]="vorige", + ["en"]="previous", + ["fr"]="precedent", + ["it"]="precedente", + ["nl"]="vorige", + ["pe"]="قبلی", + ["ro"]="precedent", + }, + ["previouslocal"]={ + ["cs"]="predchozilokalni", + ["de"]="voriglokal", + ["en"]="previouslocal", + ["fr"]="localprecedent", + ["it"]="precedentelocale", + ["nl"]="vorigelokale", + ["pe"]="موضع‌قبلی", + ["ro"]="precedentlocal", + }, + ["reserve"]={ + ["cs"]="rezervovat", + ["de"]="reservieren", + ["en"]="reserve", + ["fr"]="reserver", + ["it"]="riserva", + ["nl"]="reserveer", + ["pe"]="رزرو", + ["ro"]="rezervat", + }, + ["see"]={ + ["cs"]="viz", + ["de"]="sieh", + ["en"]="see", + ["fr"]="voit", + ["it"]="vedi", + ["nl"]="zie", + ["pe"]="ببینید", + ["ro"]="vezi", + }, + ["setup"]={ + ["cs"]="nastaveni", + ["de"]="stelle", + ["en"]="setup", + ["fr"]="regle", + ["it"]="imposta", + ["nl"]="stel", + ["pe"]="بارگذاری", + ["ro"]="setare", + }, + ["start"]={ + ["cs"]="start", + ["de"]="start", + ["en"]="start", + ["fr"]="demarre", + ["it"]="inizia", + ["nl"]="start", + ["pe"]="شروع", + ["ro"]="start", + }, + ["stop"]={ + ["cs"]="stop", + ["de"]="stop", + ["en"]="stop", + ["fr"]="stoppe", + ["it"]="termina", + ["nl"]="stop", + ["pe"]="پایان", + ["ro"]="stop", + }, + ["text"]={ + ["cs"]="text", + ["de"]="text", + ["en"]="text", + ["fr"]="texte", + ["it"]="testo", + ["nl"]="tekst", + ["pe"]="متن", + ["ro"]="text", + }, + ["type"]={ + ["cs"]="opis", + ["de"]="type", + ["en"]="type", + ["fr"]="type", + ["it"]="type", + ["nl"]="type", + ["pe"]="تایپ", + ["ro"]="type", + }, + }, + ["variables"]={ + ["end"]={ + ["en"]="end", + ["nl"]="eind", + }, + ["begin"]={ + ["en"]="begin", + ["nl"]="begin", + }, + ["down"]={ + ["en"]="down", + ["nl"]="omlaag", + }, + ["up"]={ + ["en"]="up", + ["nl"]="omhoog", + }, + ["underbar"]={ + ["cs"]="podtrzeno", + ["de"]="unterstrichen", + ["en"]="underbar", + ["fr"]="souslignetout", + ["it"]="sottolinea", + ["nl"]="onderstreep", + ["pe"]="میله‌زیر", + ["ro"]="sublinie", + }, + ["underbars"]={ + ["cs"]="podtrzeni", + ["de"]="unterstreichen", + ["en"]="underbars", + ["fr"]="sousligne", + ["it"]="sottolinee", + ["nl"]="onderstrepen", + ["pe"]="میله‌‌های‌زیر", + ["ro"]="sublinii", + }, + ["overbar"]={ + ["cs"]="nadtrzeno", + ["de"]="ueberstrichen", + ["en"]="overbar", + ["fr"]="overbar", + ["it"]="sopralinea", + ["nl"]="overstreep", + ["pe"]="میله‌رو", + ["ro"]="barasus", + }, + ["overbars"]={ + ["cs"]="nadtrzeni", + ["de"]="ueberstreichen", + ["en"]="overbars", + ["fr"]="overbars", + ["it"]="sopralinee", + ["nl"]="overstrepen", + ["pe"]="میله‌ها‌رو", + ["ro"]="supralinie", + }, + ["overstrike"]={ + ["cs"]="preskrtnuto", + ["de"]="durchgestrichen", + ["en"]="overstrike", + ["fr"]="surlignetout", + ["it"]="sbarrato", + ["nl"]="doorstreep", + ["pe"]="خط‌زدن", + ["ro"]="liniepeste", + }, + ["overstrikes"]={ + ["cs"]="preskrtnuti", + ["de"]="durchstreichen", + ["en"]="overstrikes", + ["fr"]="surligne", + ["it"]="sbarrati", + ["nl"]="doorstrepen", + ["pe"]="خط‌زدنها", + ["ro"]="liniipeste", + }, + ["maxheight"]={ + ["en"]="maxheight", + }, + ["maxdepth"]={ + ["en"]="maxdepth", + }, + ["maxwidth"]={ + ["en"]="maxwidth", + }, + ["minheight"]={ + ["en"]="minheight", + }, + ["mindepth"]={ + ["en"]="mindepth", + }, + ["minwidth"]={ + ["en"]="minwidth", + }, + ["short"]={ + ["nl"]="kort", + ["en"]="short", + ["de"]="kurz", + ["cs"]="short", + ["it"]="short", + ["ro"]="short", + ["fr"]="short", + }, + ["cite"]={ + ["en"]="cite", + }, + ["bbl"]={ + ["en"]="bbl", + }, + ["bib"]={ + ["en"]="bib", + }, + ["author"]={ + ["nl"]="auteur", + ["en"]="author", + ["de"]="autor", + ["cs"]="autor", + ["it"]="autore", + ["ro"]="autor", + ["fr"]="auteur", + }, + ["Addition"]={ + ["cs"]="Pridavek", + ["de"]="Zusatz", + ["en"]="Addition", + ["fr"]="Ajout", + ["it"]="Aggiunta", + ["nl"]="Toevoeging", + ["pe"]="جمع", + ["ro"]="Adaugare", + }, + ["Balloon"]={ + ["cs"]="Bublinka", + ["de"]="Ballon", + ["en"]="Balloon", + ["fr"]="Ballon", + ["it"]="Pallone", + ["nl"]="Ballon", + ["pe"]="بادکنک", + ["ro"]="Balon", + }, + ["Character"]={ + ["cs"]="Pismeno", + ["de"]="Buchstabe", + ["en"]="Character", + ["fr"]="Caratere", + ["it"]="Lettera", + ["nl"]="Letter", + ["pe"]="Character", + ["ro"]="Caracter", + }, + ["Characters"]={ + ["cs"]="Pismena", + ["de"]="Buchstaben", + ["en"]="Characters", + ["fr"]="Caracteres", + ["it"]="Lettere", + ["nl"]="Letters", + ["pe"]="Characters", + ["ro"]="Caractere", + }, + ["CloseDocument"]={ + ["cs"]="ZavritDokument", + ["de"]="SchliesseDokument", + ["en"]="CloseDocument", + ["fr"]="FermeDocument", + ["it"]="ChiudiDocumento", + ["nl"]="SluitDocument", + ["pe"]="بستن‌نوشتار", + ["ro"]="InchideDocument", + }, + ["ExitViewer"]={ + ["cs"]="UkoncitProhlizec", + ["de"]="BeendeViewer", + ["en"]="ExitViewer", + ["fr"]="SortVisualisateur", + ["it"]="EsciVisualizzatore", + ["nl"]="VerlaatViewer", + ["pe"]="خروج‌نمایشگر", + ["ro"]="IesireVizualizator", + }, + ["FirstPage"]={ + ["cs"]="PrvniStrana", + ["de"]="ErsteSeite", + ["en"]="FirstPage", + ["fr"]="PremierePage", + ["it"]="PrimaPagina", + ["nl"]="EerstePagina", + ["pe"]="صفحه‌اول", + ["ro"]="PrimaPagina", + }, + ["FitHeight"]={ + ["cs"]="FitHeight", + ["de"]="HoehePassend", + ["en"]="FitHeight", + ["fr"]="AjusteHauteur", + ["it"]="FitHeight", + ["nl"]="HoogtePassend", + ["pe"]="پرکردن‌ارتفاع", + ["ro"]="AjustatInaltime", + }, + ["FitWidth"]={ + ["cs"]="FitWidth", + ["de"]="BreitePassend", + ["en"]="FitWidth", + ["fr"]="AjusteLargeur", + ["it"]="FitWidth", + ["nl"]="BreedtePassend", + ["pe"]="پرکردن‌عرض", + ["ro"]="AjustatLatime", + }, + ["GotoPage"]={ + ["cs"]="JdiNaStranku", + ["de"]="GotoPage", + ["en"]="GotoPage", + ["fr"]="VaalaPage", + ["it"]="VaiAPagina", + ["nl"]="GaNaarPagina", + ["pe"]="برو‌به‌صفحه", + ["ro"]="LaPagina", + }, + ["Greek"]={ + ["cs"]="Recky", + ["de"]="Griechisch", + ["en"]="Greek", + ["fr"]="Grec", + ["it"]="Greco", + ["nl"]="Grieks", + ["pe"]="یونانی", + ["ro"]="Grec", + }, + ["Help"]={ + ["cs"]="Napoveda", + ["de"]="Hilfe", + ["en"]="Help", + ["fr"]="Aide", + ["it"]="Aiuto", + ["nl"]="Help", + ["pe"]="کمک", + ["ro"]="Ajutor", + }, + ["HideField"]={ + ["cs"]="SkryjPole", + ["de"]="VerbergeFeld", + ["en"]="HideField", + ["fr"]="CacheChamp", + ["it"]="NascondiCampo", + ["nl"]="VerbergVeld", + ["pe"]="پنهان‌میدان", + ["ro"]="AscundeCamp", + }, + ["HideLayer"]={ + ["cs"]="HideLayer", + ["de"]="HideLayer", + ["en"]="HideLayer", + ["fr"]="CacheCalque", + ["it"]="HideLayer", + ["nl"]="VerbergLaag", + ["pe"]="پنهان‌لایه", + ["ro"]="HideLayer", + }, + ["Key"]={ + ["cs"]="Klavesa", + ["de"]="Schluessel", + ["en"]="Key", + ["fr"]="Cle", + ["it"]="Tasto", + ["nl"]="Sleutel", + ["pe"]="کلید", + ["ro"]="Cheie", + }, + ["LastPage"]={ + ["cs"]="PosledniStrana", + ["de"]="LetzteSeite", + ["en"]="LastPage", + ["fr"]="DernierePage", + ["it"]="UltimaPagina", + ["nl"]="LaatstePagina", + ["pe"]="صفحه‌آخر", + ["ro"]="UltimaPagina", + }, + ["LoadForm"]={ + ["cs"]="NacistFormular", + ["de"]="LadeFormular", + ["en"]="LoadForm", + ["fr"]="ChargeForm", + ["it"]="CaricaForm", + ["nl"]="LaadFormulier", + ["pe"]="بارگذاشتن‌فرم", + ["ro"]="IncarcaFormular", + }, + ["MONTH"]={ + ["cs"]="MESIC", + ["de"]="MONAT", + ["en"]="MONTH", + ["fr"]="MOIS", + ["it"]="MESE", + ["nl"]="MAAND", + ["pe"]="ماه", + ["ro"]="LUNA", + }, + ["New"]={ + ["cs"]="Novy", + ["de"]="Neu", + ["en"]="New", + ["fr"]="Nouveau", + ["it"]="Nuovo", + ["nl"]="Nieuw", + ["pe"]="جدید", + ["ro"]="Nou", + }, + ["NextJump"]={ + ["cs"]="NasledujiciSkok", + ["de"]="NaechsterSprung", + ["en"]="NextJump", + ["fr"]="SautSuivant", + ["it"]="SaltoSuccessivo", + ["nl"]="VolgendeSprong", + ["pe"]="پرش‌بعدی", + ["ro"]="SaltUrmator", + }, + ["NextPage"]={ + ["cs"]="DalsiStrana", + ["de"]="FolgendeSeite", + ["en"]="NextPage", + ["fr"]="PageSuivante", + ["it"]="PaginaSuccessiva", + ["nl"]="VolgendePagina", + ["pe"]="صفحه‌بعدی", + ["ro"]="PaginaUrmatoare", + }, + ["Numbers"]={ + ["cs"]="Cisla", + ["de"]="Ziffern", + ["en"]="Numbers", + ["fr"]="Numeros", + ["it"]="Numeri", + ["nl"]="Cijfers", + ["pe"]="شماره‌ها", + ["ro"]="Numere", + }, + ["OpenNamedDocument"]={ + ["cs"]="OpenNamedDocument", + ["de"]="OpenNamedDocument", + ["en"]="OpenNamedDocument", + ["fr"]="OuvreDocumentNomme", + ["it"]="OpenNamedDocument", + ["nl"]="OpenDocumentOpNaam", + ["pe"]="بازکردن‌نوشتار‌ذخیره‌شده", + ["ro"]="OpenNamedDocument", + }, + ["Paragraph"]={ + ["cs"]="Odstavec", + ["de"]="Absatz", + ["en"]="Paragraph", + ["fr"]="Paragraphe", + ["it"]="Capoverso", + ["nl"]="Paragraaf", + ["pe"]="پاراگراف", + ["ro"]="Paragraf", + }, + ["PauseMovie"]={ + ["cs"]="PozastavitFilm", + ["de"]="PauseFilm", + ["en"]="PauseMovie", + ["fr"]="PauseFilm", + ["it"]="PausaFilm", + ["nl"]="PauzeerFilm", + ["pe"]="ایست‌فیلم", + ["ro"]="PauzaFilm", + }, + ["PauseRendering"]={ + ["cs"]="PauseRendering", + ["de"]="PauseRendering", + ["en"]="PauseRendering", + ["fr"]="PauseRendering", + ["it"]="PauseRendering", + ["nl"]="PauzeerRendering", + ["pe"]="توقف‌تعبیر", + ["ro"]="PauseRendering", + }, + ["PauseSound"]={ + ["cs"]="PozastavitZvuk", + ["de"]="PauseSound", + ["en"]="PauseSound", + ["fr"]="PauseSon", + ["it"]="PausaSuono", + ["nl"]="PauzeerGeluid", + ["pe"]="ایست‌صدا", + ["ro"]="PauzaSunet", + }, + ["PreviousJump"]={ + ["cs"]="PredchoziSkok", + ["de"]="VorigerSprung", + ["en"]="PreviousJump", + ["fr"]="SautPrecedent", + ["it"]="SaltoPrecedente", + ["nl"]="VorigeSprong", + ["pe"]="پرش‌قبلی", + ["ro"]="SaltPrecedent", + }, + ["PreviousPage"]={ + ["cs"]="PredchoziStrana", + ["de"]="VorigeSeite", + ["en"]="PreviousPage", + ["fr"]="PagePrecedente", + ["it"]="PaginaPrecedente", + ["nl"]="VorigePagina", + ["pe"]="صفحه‌قبلی", + ["ro"]="PaginaPrecedenta", + }, + ["PrintDocument"]={ + ["cs"]="VytisknoutDokument", + ["de"]="DruckeDokument", + ["en"]="PrintDocument", + ["fr"]="ImprimeDocument", + ["it"]="StampaDocumento", + ["nl"]="PrintDocument", + ["pe"]="چاپ‌نوشتار", + ["ro"]="TiparesteDocument", + }, + ["Query"]={ + ["cs"]="Query", + ["de"]="Query", + ["en"]="Query", + ["fr"]="Query", + ["it"]="Richiesta", + ["nl"]="RaadpleegDocument", + ["pe"]="پرسش", + ["ro"]="Query", + }, + ["QueryAgain"]={ + ["cs"]="QueryAgain", + ["de"]="QueryAgain", + ["en"]="QueryAgain", + ["fr"]="QueryAgain", + ["it"]="RinnovaRichiesta", + ["nl"]="HerhaalRaadplegen", + ["pe"]="پرسش‌دوباره", + ["ro"]="QueryAgain", + }, + ["ResetForm"]={ + ["cs"]="ResetFormulare", + ["de"]="ZuruecksetzenFormular", + ["en"]="ResetForm", + ["fr"]="RazForm", + ["it"]="ReimpostaForm", + ["nl"]="ResetFormulier", + ["pe"]="دوباره‌نشانی‌فرم", + ["ro"]="ResetareFormular", + }, + ["ResumeMovie"]={ + ["cs"]="PokracovatFilm", + ["de"]="FortsetzenFilm", + ["en"]="ResumeMovie", + ["fr"]="ReprendFilm", + ["it"]="RiprendiFilm", + ["nl"]="HervatFilm", + ["pe"]="ادامه‌فیلم", + ["ro"]="RepornesteFilm", + }, + ["ResumeRendering"]={ + ["cs"]="ResumeRendering", + ["de"]="ResumeRendering", + ["en"]="ResumeRendering", + ["fr"]="ResumeRendering", + ["it"]="ResumeRendering", + ["nl"]="HervatRendering", + ["pe"]="ادامه‌تعبیر", + ["ro"]="ResumeRendering", + }, + ["ResumeSound"]={ + ["cs"]="PokracovatZvuk", + ["de"]="ResumeSound", + ["en"]="ResumeSound", + ["fr"]="ReprendSon", + ["it"]="RiprendiSuono", + ["nl"]="HervatGeluid", + ["pe"]="ادامه‌صدا", + ["ro"]="RepornesteSunet", + }, + ["Romannumerals"]={ + ["cs"]="Rimskecislice", + ["de"]="Roemischezahlen", + ["en"]="Romannumerals", + ["fr"]="Chiffresromains", + ["it"]="Numeriromani", + ["nl"]="Romeins", + ["pe"]="اعداد‌بزرگ‌لاتین", + ["ro"]="Numereromane", + }, + ["SaveDocument"]={ + ["cs"]="UlozitDokument", + ["de"]="SpeichereDokument", + ["en"]="SaveDocument", + ["fr"]="SauvegardeDocument", + ["it"]="SalvaDocumento", + ["nl"]="BewaarDocument", + ["pe"]="ذخیره‌نوشتار", + ["ro"]="SalvareDocument", + }, + ["SaveForm"]={ + ["cs"]="UlozitFormular", + ["de"]="SpeicheFormular", + ["en"]="SaveForm", + ["fr"]="SauvegardeForm", + ["it"]="SalvaForm", + ["nl"]="BewaarFormulier", + ["pe"]="ذخیره‌فرم", + ["ro"]="SalveazaFormular", + }, + ["SaveNamedDocument"]={ + ["cs"]="SaveNamedDocument", + ["de"]="SaveNamedDocument", + ["en"]="SaveNamedDocument", + ["fr"]="SauvegardeDocumentNomme", + ["it"]="SaveNamedDocument", + ["nl"]="BewaarDocumentOpNaam", + ["pe"]="ذخیره‌نوشتار‌بانام", + ["ro"]="SaveNamedDocument", + }, + ["SearchAgain"]={ + ["cs"]="HledatZnovu", + ["de"]="WeiterSuchen", + ["en"]="SearchAgain", + ["fr"]="RechercheSuivant", + ["it"]="CercaAncora", + ["nl"]="HerhaalZoeken", + ["pe"]="جستجوی‌دوباره", + ["ro"]="CautaDinNou", + }, + ["SearchDocument"]={ + ["cs"]="ProhledatDokument", + ["de"]="DokumentDurchsuchen", + ["en"]="SearchDocument", + ["fr"]="RechercheDocument", + ["it"]="CercaDocumento", + ["nl"]="DoorzoekDocument", + ["pe"]="جستجوی‌نوشتار", + ["ro"]="CautaDocument", + }, + ["ShowBookmarks"]={ + ["cs"]="UkazZalozky", + ["de"]="ShowBookmarks", + ["en"]="ShowBookmarks", + ["fr"]="ShowBookmarks", + ["it"]="MostraSegnalibro", + ["nl"]="ShowBookmarks", + ["pe"]="نمایش‌چوبخط", + ["ro"]="ShowBookmarks", + }, + ["ShowField"]={ + ["cs"]="UkazPole", + ["de"]="ZeigeFeld", + ["en"]="ShowField", + ["fr"]="MontreChamp", + ["it"]="MostraCampo", + ["nl"]="ToonVeld", + ["pe"]="نمایش‌میدان", + ["ro"]="AfiseazaCamp", + }, + ["ShowThumbs"]={ + ["cs"]="UkazNahledy", + ["de"]="ShowThumbs", + ["en"]="ShowThumbs", + ["fr"]="ShowThumbs", + ["it"]="MostraThumbs", + ["nl"]="ShowThumbs", + ["pe"]="نمایش‌شصت", + ["ro"]="ShowThumbs", + }, + ["StartMovie"]={ + ["cs"]="SpustitFilm", + ["de"]="StartFilm", + ["en"]="StartMovie", + ["fr"]="DemarreFilm", + ["it"]="IniziaFilm", + ["nl"]="StartFilm", + ["pe"]="شروع‌فیلم", + ["ro"]="StartFilm", + }, + ["StartRendering"]={ + ["cs"]="StartRendering", + ["de"]="StartRendering", + ["en"]="StartRendering", + ["fr"]="StartRendering", + ["it"]="StartRendering", + ["nl"]="StartRendering", + ["pe"]="شروع‌تعبیر", + ["ro"]="StartRendering", + }, + ["StartSound"]={ + ["cs"]="StartZvuk", + ["de"]="StartSound", + ["en"]="StartSound", + ["fr"]="DemarreSon", + ["it"]="IniziaSuono", + ["nl"]="StartGeluid", + ["pe"]="شروع‌صدا", + ["ro"]="StartSunet", + }, + ["StopMovie"]={ + ["cs"]="ZastavitFilm", + ["de"]="StopFilm", + ["en"]="StopMovie", + ["fr"]="StoppeFilm", + ["it"]="FermaFilm", + ["nl"]="StopFilm", + ["pe"]="پایان‌فیلم", + ["ro"]="StopFilm", + }, + ["StopRendering"]={ + ["cs"]="StopRendering", + ["de"]="StopRendering", + ["en"]="StopRendering", + ["fr"]="StopRendering", + ["it"]="StopRendering", + ["nl"]="StopRendering", + ["pe"]="پایان‌تعبیر", + ["ro"]="StopRendering", + }, + ["StopSound"]={ + ["cs"]="StopZvuk", + ["de"]="StopSound", + ["en"]="StopSound", + ["fr"]="StoppeSon", + ["it"]="FermaSuono", + ["nl"]="StopGeluid", + ["pe"]="پایان‌صدا", + ["ro"]="StopSunet", + }, + ["SubmitForm"]={ + ["cs"]="PoslatFormular", + ["de"]="VersendeFormular", + ["en"]="SubmitForm", + ["fr"]="SoumettreForm", + ["it"]="MandaForm", + ["nl"]="VerzendFormulier", + ["pe"]="تسلیم‌فرم", + ["ro"]="TrimiteFormular", + }, + ["ToggleLayer"]={ + ["cs"]="ToggleLayer", + ["de"]="ToggleLayer", + ["en"]="ToggleLayer", + ["fr"]="ToggleLayer", + ["it"]="ToggleLayer", + ["nl"]="WisselLaag", + ["pe"]="تغییرلایه", + ["ro"]="ToggleLayer", + }, + ["ToggleViewer"]={ + ["cs"]="ZmenitProhlizec", + ["de"]="WechseleViewer", + ["en"]="ToggleViewer", + ["fr"]="ChangeVisualisateur", + ["it"]="ScambiaVisualizzatore", + ["nl"]="WisselViewer", + ["pe"]="تغییرنمایشگر", + ["ro"]="SchimbaVizualizator", + }, + ["URL"]={ + ["cs"]="URL", + ["de"]="URL", + ["en"]="URL", + ["fr"]="URL", + ["it"]="URL", + ["nl"]="URL", + ["pe"]="URL", + ["ro"]="URL", + }, + ["VideLayer"]={ + ["cs"]="VideLayer", + ["de"]="VideLayer", + ["en"]="VideLayer", + ["fr"]="VideLayer", + ["it"]="VideLayer", + ["nl"]="ToonLaag", + ["pe"]="VideLayer", + ["ro"]="VideLayer", + }, + ["ViewerHelp"]={ + ["cs"]="NapovedaProhlizece", + ["de"]="ViewerHilfe", + ["en"]="ViewerHelp", + ["fr"]="AideVisualisateur", + ["it"]="AiutoVisualizzatore", + ["nl"]="ViewerHelp", + ["pe"]="کمک‌نمایشگر", + ["ro"]="AjutorVizualizator", + }, + ["WEEKDAY"]={ + ["cs"]="VSEDNIDEN", + ["de"]="WOCHENTAG", + ["en"]="WEEKDAY", + ["fr"]="JOURSEMAINE", + ["it"]="GIORNOSETTIMANA", + ["nl"]="WEEKDAG", + ["pe"]="روزهفته", + ["ro"]="ZISAPTAMANA", + }, + ["WORD"]={ + ["cs"]="SLOVO", + ["de"]="WORT", + ["en"]="WORD", + ["fr"]="MOT", + ["it"]="PAROLA", + ["nl"]="WOORD", + ["pe"]="کلمه", + ["ro"]="CUVANT", + }, + ["abbreviation"]={ + ["cs"]="zkratka", + ["de"]="abkuerzung", + ["en"]="abbreviation", + ["fr"]="abreviation", + ["it"]="abbreviazione", + ["nl"]="afkorting", + ["pe"]="اختصار", + ["ro"]="abreviere", + }, + ["abbreviations"]={ + ["cs"]="zkratky", + ["de"]="abkuerzungen", + ["en"]="abbreviations", + ["fr"]="abreviations", + ["it"]="abbreviazioni", + ["nl"]="afkortingen", + ["pe"]="اختصارات", + ["ro"]="abrevieri", + }, + ["absolute"]={ + ["cs"]="absolutni", + ["de"]="absolut", + ["en"]="absolute", + ["fr"]="absolute", + ["it"]="assoluto", + ["nl"]="absoluut", + ["pe"]="قطعی", + ["ro"]="absolut", + }, + ["action"]={ + ["cs"]="akce", + ["de"]="aktion", + ["en"]="action", + ["fr"]="action", + ["it"]="azione", + ["nl"]="actie", + ["pe"]="کنش", + ["ro"]="actiune", + }, + ["after"]={ + ["cs"]="po", + ["de"]="nach", + ["en"]="after", + ["fr"]="apres", + ["it"]="dopo", + ["nl"]="na", + ["pe"]="بعداز", + ["ro"]="dupa", + }, + ["all"]={ + ["cs"]="vse", + ["de"]="alles", + ["en"]="all", + ["fr"]="tout", + ["it"]="tutti", + ["nl"]="alles", + ["pe"]="همه", + ["ro"]="tot", + }, + ["always"]={ + ["cs"]="vzdy", + ["de"]="immer", + ["en"]="always", + ["fr"]="toujours", + ["it"]="sempre", + ["nl"]="altijd", + ["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", + ["en"]="appendices", + ["fr"]="annexes", + ["it"]="appendici", + ["nl"]="bijlagen", + ["pe"]="پیوستها", + ["ro"]="apendixuri", + }, + ["appendix"]={ + ["cs"]="dodatek", + ["de"]="anhang", + ["en"]="appendix", + ["fr"]="annexe", + ["it"]="appendice", + ["nl"]="bijlage", + ["pe"]="پیوست", + ["ro"]="apendix", + }, + ["april"]={ + ["cs"]="duben", + ["de"]="April", + ["en"]="April", + ["fr"]="avril", + ["it"]="aprile", + ["nl"]="april", + ["pe"]="آوریل", + ["ro"]="aprilie", + }, + ["atmargin"]={ + ["cs"]="naokraji", + ["de"]="amrand", + ["en"]="atmargin", + ["fr"]="alamarge", + ["it"]="almargine", + ["nl"]="opmarge", + ["pe"]="درحاشیه", + ["ro"]="lamargine", + }, + ["atpage"]={ + ["cs"]="nastrance", + ["de"]="aufseite", + ["en"]="atpage", + ["fr"]="alapage", + ["it"]="apagina", + ["nl"]="oppagina", + ["pe"]="درصفحه", + ["ro"]="lapagina", + }, + ["august"]={ + ["cs"]="srpen", + ["de"]="August", + ["en"]="August", + ["fr"]="aout", + ["it"]="agosto", + ["nl"]="augustus", + ["pe"]="آگوست", + ["ro"]="august", + }, + ["auto"]={ + ["cs"]="auto", + ["de"]="auto", + ["en"]="auto", + ["fr"]="auto", + ["it"]="auto", + ["nl"]="auto", + ["pe"]="خودکار", + ["ro"]="auto", + }, + ["autointro"]={ + ["cs"]="autouvod", + ["de"]="autointro", + ["en"]="autointro", + ["fr"]="autointro", + ["it"]="autointro", + ["nl"]="autointro", + ["pe"]="پیشگفتارخودکار", + ["ro"]="autointro", + }, + ["back"]={ + ["cs"]="zpet", + ["de"]="zurueck", + ["en"]="back", + ["fr"]="retour", + ["it"]="dietro", + ["nl"]="terug", + ["pe"]="پشت", + ["ro"]="inapot", + }, + ["background"]={ + ["cs"]="pozadi", + ["de"]="hintergrund", + ["en"]="background", + ["fr"]="arriereplan", + ["it"]="sfondo", + ["nl"]="achtergrond", + ["pe"]="پس‌زمینه", + ["ro"]="fundal", + }, + ["backmatter"]={ + ["cs"]="epilogy", + ["de"]="epiloge", + ["en"]="backmatter", + ["fr"]="epilogue", + ["it"]="postambolo", + ["nl"]="uitleidingen", + ["pe"]="پس‌مطلب", + ["ro"]="epilogul", + }, + ["backpart"]={ + ["cs"]="epilog", + ["de"]="epilog", + ["en"]="backpart", + ["fr"]="postface", + ["it"]="postfazione", + ["nl"]="uitleiding", + ["pe"]="پس‌قسمت", + ["ro"]="epilog", + }, + ["backspace"]={ + ["cs"]="zpetnamezera", + ["de"]="rumpfspatium", + ["en"]="backspace", + ["fr"]="retourarriere", + ["it"]="backspace", + ["nl"]="rugwit", + ["pe"]="فضای‌پشت", + ["ro"]="spatiuspate", + }, + ["backward"]={ + ["cs"]="zpet", + ["de"]="rueckwaerts", + ["en"]="backward", + ["fr"]="retourarriere", + ["it"]="indietro", + ["nl"]="achteruit", + ["pe"]="عقب‌گرد", + ["ro"]="inapoi", + }, + ["before"]={ + ["cs"]="pred", + ["de"]="vor", + ["en"]="before", + ["fr"]="avant", + ["it"]="prima", + ["nl"]="voor", + ["pe"]="قبل‌از", + ["ro"]="inainte", + }, + ["big"]={ + ["cs"]="velke", + ["de"]="gross", + ["en"]="big", + ["fr"]="grand", + ["it"]="grande", + ["nl"]="groot", + ["pe"]="بزرگ", + ["ro"]="mare", + }, + ["bigbodyfont"]={ + ["cs"]="bigbodyfont", + ["de"]="bigbodyfont", + ["en"]="bigbodyfont", + ["fr"]="grandepolicecorp", + ["it"]="grossofontdeltesto", + ["nl"]="grootkorps", + ["pe"]="قلم‌بدنه‌بزرگ", + ["ro"]="bigbodyfont", + }, + ["bigpreference"]={ + ["cs"]="vysokapriorita", + ["de"]="grosszuegig", + ["en"]="bigpreference", + ["fr"]="grandepreference", + ["it"]="grandepreferenza", + ["nl"]="grotevoorkeur", + ["pe"]="اولویت‌بزرگ", + ["ro"]="preferintamare", + }, + ["blank"]={ + ["cs"]="prazdny", + ["de"]="blanko", + ["en"]="blank", + ["fr"]="vide", + ["it"]="rigovuoto", + ["nl"]="blanko", + ["pe"]="خالی", + ["ro"]="blank", + }, + ["blockquote"]={ + ["cs"]="blockquote", + ["de"]="blockquote", + ["en"]="blockquote", + ["fr"]="blockquote", + ["it"]="blockquote", + ["nl"]="blokcitaat", + ["pe"]="نقل‌بلوک", + ["ro"]="blockquote", + }, + ["bodymatter"]={ + ["cs"]="hlavnicasti", + ["de"]="haupttexte", + ["en"]="bodymatter", + ["fr"]="texteprincipal", + ["it"]="testiprincipali", + ["nl"]="hoofdteksten", + ["pe"]="مطلب‌بدنه", + ["ro"]="principalul", + }, + ["bodypart"]={ + ["cs"]="hlavnicast", + ["de"]="haupttext", + ["en"]="bodypart", + ["fr"]="corpsdetexte", + ["it"]="testoprincipale", + ["nl"]="hoofdtekst", + ["pe"]="قسمت‌بدنه", + ["ro"]="principal", + }, + ["bold"]={ + ["cs"]="tucne", + ["de"]="fett", + ["en"]="bold", + ["fr"]="gras", + ["it"]="grassetto", + ["nl"]="vet", + ["pe"]="مشکی", + ["ro"]="aldin", + }, + ["bolditalic"]={ + ["cs"]="tucnekurzivni", + ["de"]="fettitalic", + ["en"]="bolditalic", + ["fr"]="italiquegras", + ["it"]="grassettocorsivo", + ["nl"]="vetitalic", + ["pe"]="ایتالیک‌مشکی", + ["ro"]="aldinitalic", + }, + ["boldslanted"]={ + ["cs"]="tucnesklonene", + ["de"]="fettgeneigt", + ["en"]="boldslanted", + ["fr"]="inclinegras", + ["it"]="grassettoinclinato", + ["nl"]="vetschuin", + ["pe"]="خوابیده‌مشکی", + ["ro"]="aldininclinat", + }, + ["bookmark"]={ + ["cs"]="zalozka", + ["de"]="bookmark", + ["en"]="bookmark", + ["fr"]="marquepage", + ["it"]="segnalibro", + ["nl"]="bookmark", + ["pe"]="چوبخط", + ["ro"]="semncarte", + }, + ["both"]={ + ["cs"]="obe", + ["de"]="beide", + ["en"]="both", + ["fr"]="lesdeux", + ["it"]="entrambi", + ["nl"]="beide", + ["pe"]="هردو", + ["ro"]="ambele", + }, + ["bottom"]={ + ["cs"]="spodek", + ["de"]="unten", + ["en"]="bottom", + ["fr"]="inf", + ["it"]="fondo", + ["nl"]="onder", + ["pe"]="پایین", + ["ro"]="subsol", + }, + ["brief"]={ + ["cs"]="brief", + ["de"]="brief", + ["en"]="brief", + ["fr"]="brief", + ["it"]="brief", + ["nl"]="brief", + ["pe"]="مختصر", + ["ro"]="brief", + }, + ["broad"]={ + ["cs"]="siroky", + ["de"]="breit", + ["en"]="broad", + ["fr"]="large", + ["it"]="ampio", + ["nl"]="ruim", + ["pe"]="گسترده", + ["ro"]="broad", + }, + ["buffer"]={ + ["cs"]="buffer", + ["de"]="puffer", + ["en"]="buffer", + ["fr"]="buffer", + ["it"]="buffer", + ["nl"]="buffer", + ["pe"]="بافر", + ["ro"]="buffer", + }, + ["by"]={ + ["cs"]="skrz", + ["de"]="pro", + ["en"]="by", + ["fr"]="par", + ["it"]="da", + ["nl"]="per", + ["pe"]="بوسیله", + ["ro"]="de", + }, + ["calligraphic"]={ + ["cs"]="kaligraficke", + ["de"]="kalligraphie", + ["en"]="calligraphic", + ["fr"]="calligraphique", + ["it"]="calligrafico", + ["nl"]="calligrafie", + ["pe"]="خوشنویسی", + ["ro"]="caligrafic", + }, + ["cap"]={ + ["cs"]="kap", + ["de"]="kap", + ["en"]="cap", + ["fr"]="cap", + ["it"]="cap", + ["nl"]="kap", + ["pe"]="cap", + ["ro"]="cap", + }, + ["capital"]={ + ["cs"]="kapitalky", + ["de"]="versalien", + ["en"]="capital", + ["fr"]="capitale", + ["it"]="maiuscolo", + ["nl"]="kapitaal", + ["pe"]="capital", + ["ro"]="majuscula", + }, + ["center"]={ + ["cs"]="center", + ["de"]="center", + ["en"]="center", + ["fr"]="center", + ["it"]="center", + ["nl"]="centreer", + ["pe"]="مرکز", + ["ro"]="center", + }, + ["chapter"]={ + ["cs"]="kapitola", + ["de"]="kapitel", + ["en"]="chapter", + ["fr"]="chapitre", + ["it"]="capitolo", + ["nl"]="hoofdstuk", + ["pe"]="فصل", + ["ro"]="capitol", + }, + ["character"]={ + ["cs"]="pismeno", + ["de"]="buchstabe", + ["en"]="character", + ["fr"]="caractere", + ["it"]="lettera", + ["nl"]="letter", + ["pe"]="حرف", + ["ro"]="caracter", + }, + ["characters"]={ + ["cs"]="pismena", + ["de"]="buchstaben", + ["en"]="characters", + ["fr"]="caracteres", + ["it"]="lettere", + ["nl"]="letters", + ["pe"]="حرفها", + ["ro"]="caractere", + }, + ["color"]={ + ["cs"]="barevne", + ["de"]="farbe", + ["en"]="color", + ["fr"]="couleur", + ["it"]="colore", + ["nl"]="kleur", + ["pe"]="رنگ", + ["ro"]="culoare", + }, + ["column"]={ + ["cs"]="column", + ["de"]="column", + ["en"]="column", + ["fr"]="colonne", + ["it"]="colonna", + ["nl"]="kolom", + ["pe"]="ستون", + ["ro"]="coloana", + }, + ["columns"]={ + ["cs"]="sloupce", + ["de"]="spalten", + ["en"]="columns", + ["fr"]="colonnes", + ["it"]="colonne", + ["nl"]="kolommen", + ["pe"]="ستونها", + ["ro"]="coloane", + }, + ["command"]={ + ["cs"]="prikaz", + ["de"]="befehl", + ["en"]="command", + ["fr"]="commande", + ["it"]="comando", + ["nl"]="commando", + ["pe"]="فرمان", + ["ro"]="comanda", + }, + ["commands"]={ + ["cs"]="prikazy", + ["de"]="befehle", + ["en"]="commands", + ["fr"]="commandes", + ["it"]="comandi", + ["nl"]="commandos", + ["pe"]="فرمانها", + ["ro"]="comenzi", + }, + ["comment"]={ + ["cs"]="komentar", + ["de"]="kommentar", + ["en"]="comment", + ["fr"]="commentaire", + ["it"]="commento", + ["nl"]="commentaar", + ["pe"]="توضیح", + ["ro"]="comentariu", + }, + ["component"]={ + ["cs"]="komponenta", + ["de"]="komponente", + ["en"]="component", + ["fr"]="composant", + ["it"]="componente", + ["nl"]="onderdeel", + ["pe"]="مولفه", + ["ro"]="componenta", + }, + ["concept"]={ + ["cs"]="koncept", + ["de"]="konzept", + ["en"]="concept", + ["fr"]="concept", + ["it"]="concetto", + ["nl"]="concept", + ["pe"]="مفهوم", + ["ro"]="concept", + }, + ["content"]={ + ["cs"]="obsah", + ["de"]="inhalt", + ["en"]="content", + ["fr"]="contenu", + ["it"]="indice", + ["nl"]="inhoud", + ["pe"]="محتوا", + ["ro"]="cuprins", + }, + ["contents"]={ + ["cs"]="obsah", + ["de"]="inhalte", + ["en"]="contents", + ["fr"]="contenus", + ["it"]="indici", + ["nl"]="inhouden", + ["pe"]="محتویات", + ["ro"]="cuprinsuri", + }, + ["continue"]={ + ["cs"]="pokracovat", + ["de"]="fortsetzten", + ["en"]="continue", + ["fr"]="continue", + ["it"]="continua", + ["nl"]="verder", + ["pe"]="ادامه", + ["ro"]="continuu", + }, + ["controls"]={ + ["cs"]="controls", + ["de"]="controls", + ["en"]="controls", + ["fr"]="controles", + ["it"]="controlli", + ["nl"]="sturing", + ["pe"]="کنترلها", + ["ro"]="controale", + }, + ["conversion"]={ + ["cs"]="konverze", + ["de"]="konversion", + ["en"]="conversion", + ["fr"]="conversion", + ["it"]="coversione", + ["nl"]="conversie", + ["pe"]="تبدیل", + ["ro"]="conversie", + }, + ["current"]={ + ["cs"]="aktualni", + ["de"]="aktuell", + ["en"]="current", + ["fr"]="courant", + ["it"]="corrente", + ["nl"]="huidige", + ["pe"]="جاری", + ["ro"]="curent", + }, + ["cutspace"]={ + ["cs"]="cutspace", + ["de"]="cutspace", + ["en"]="cutspace", + ["fr"]="cutspace", + ["it"]="cutspace", + ["nl"]="snijwit", + ["pe"]="فضای‌برش", + ["ro"]="cutspace", + }, + ["date"]={ + ["cs"]="datum", + ["de"]="datum", + ["en"]="date", + ["fr"]="date", + ["it"]="data", + ["nl"]="datum", + ["pe"]="تاریخ", + ["ro"]="data", + }, + ["day"]={ + ["cs"]="den", + ["de"]="tag", + ["en"]="day", + ["fr"]="jour", + ["it"]="giorno", + ["nl"]="dag", + ["pe"]="روز", + ["ro"]="zi", + }, + ["december"]={ + ["cs"]="prosinec", + ["de"]="Dezember", + ["en"]="December", + ["fr"]="decembre", + ["it"]="dicembre", + ["nl"]="december", + ["pe"]="دسامبر", + ["ro"]="decembrie", + }, + ["default"]={ + ["cs"]="implicitni", + ["de"]="default", + ["en"]="default", + ["fr"]="defaut", + ["it"]="implicito", + ["nl"]="default", + ["pe"]="پیش‌فرض", + ["ro"]="implicit", + }, + ["depth"]={ + ["cs"]="podlehloubky", + ["de"]="tiefe", + ["en"]="depth", + ["fr"]="profondeur", + ["it"]="profondita", + ["nl"]="diepte", + ["pe"]="عمق", + ["ro"]="adancime", + }, + ["description"]={ + ["cs"]="popis", + ["de"]="beschreibung", + ["en"]="description", + ["fr"]="description", + ["it"]="descrizione", + ["nl"]="doordefinitie", + ["pe"]="شرح", + ["ro"]="descriere", + }, + ["disable"]={ + ["cs"]="zablokovat", + ["de"]="sperren", + ["en"]="disable", + ["fr"]="desactiver", + ["it"]="disattiva", + ["nl"]="blokkeer", + ["pe"]="ناتوان", + ["ro"]="dezactivat", + }, + ["display"]={ + ["cs"]="obrazovka", + ["de"]="bildschirm", + ["en"]="display", + ["fr"]="affichage", + ["it"]="schermo", + ["nl"]="scherm", + ["pe"]="نمایش", + ["ro"]="display", + }, + ["dot"]={ + ["cs"]="tecka", + ["de"]="punkt", + ["en"]="dot", + ["fr"]="point", + ["it"]="punto", + ["nl"]="punt", + ["pe"]="نقطه", + ["ro"]="punct", + }, + ["doublesided"]={ + ["cs"]="dvoustranny", + ["de"]="doppelseitig", + ["en"]="doublesided", + ["fr"]="rectoverso", + ["it"]="doppiafaccia", + ["nl"]="dubbelzijdig", + ["pe"]="دورو", + ["ro"]="douafete", + }, + ["each"]={ + ["cs"]="kazdy", + ["de"]="jede", + ["en"]="each", + ["fr"]="chaque", + ["it"]="ogni", + ["nl"]="elk", + ["pe"]="هر", + ["ro"]="fiecare", + }, + ["edge"]={ + ["cs"]="hrana", + ["de"]="kante", + ["en"]="edge", + ["fr"]="bord", + ["it"]="bordo", + ["nl"]="rand", + ["pe"]="لبه", + ["ro"]="bordura", + }, + ["empty"]={ + ["cs"]="prazdne", + ["de"]="leer", + ["en"]="empty", + ["fr"]="vide", + ["it"]="vuoto", + ["nl"]="leeg", + ["pe"]="تهی", + ["ro"]="gol", + }, + ["endnote"]={ + ["cs"]="endnote", + ["de"]="endnote", + ["en"]="endnote", + ["fr"]="notefin", + ["it"]="endnote", + ["nl"]="eindnoot", + ["pe"]="ته‌نوشت", + ["ro"]="endnote", + }, + ["enumeration"]={ + ["cs"]="vycet", + ["de"]="nummerierung", + ["en"]="enumeration", + ["fr"]="enumeration", + ["it"]="enumerazione", + ["nl"]="doornummering", + ["pe"]="شماره‌بندی", + ["ro"]="enumerare", + }, + ["environment"]={ + ["cs"]="prostredi", + ["de"]="umgebung", + ["en"]="environment", + ["fr"]="environement", + ["it"]="ambiente", + ["nl"]="omgeving", + ["pe"]="محیط", + ["ro"]="mediu", + }, + ["even"]={ + ["cs"]="sude", + ["de"]="gerade", + ["en"]="even", + ["fr"]="paire", + ["it"]="pari", + ["nl"]="even", + ["pe"]="زوج", + ["ro"]="par", + }, + ["external"]={ + ["cs"]="externi", + ["de"]="extern", + ["en"]="external", + ["fr"]="external", + ["it"]="esterno", + ["nl"]="extern", + ["pe"]="خارجی", + ["ro"]="extern", + }, + ["fact"]={ + ["cs"]="fakt", + ["de"]="gegeben", + ["en"]="fact", + ["fr"]="fait", + ["it"]="fatto", + ["nl"]="gegeven", + ["pe"]="fact", + ["ro"]="fapt", + }, + ["february"]={ + ["cs"]="unor", + ["de"]="Februar", + ["en"]="February", + ["fr"]="fevrier", + ["it"]="febbraio", + ["nl"]="februari", + ["pe"]="فوریه", + ["ro"]="februarie", + }, + ["figure"]={ + ["cs"]="obrazek", + ["de"]="abbildung", + ["en"]="figure", + ["fr"]="figure", + ["it"]="figura", + ["nl"]="figuur", + ["pe"]="شکل", + ["ro"]="figura", + }, + ["figures"]={ + ["cs"]="obrazky", + ["de"]="abbildungen", + ["en"]="figures", + ["fr"]="figures", + ["it"]="figure", + ["nl"]="figuren", + ["pe"]="شکلها", + ["ro"]="figure", + }, + ["file"]={ + ["cs"]="soubor", + ["de"]="datei", + ["en"]="file", + ["fr"]="fichier", + ["it"]="file", + ["nl"]="file", + ["pe"]="پرونده", + ["ro"]="fisier", + }, + ["final"]={ + ["cs"]="finalni", + ["de"]="endfassung", + ["en"]="final", + ["fr"]="final", + ["it"]="finale", + ["nl"]="definitief", + ["pe"]="نهایی", + ["ro"]="final", + }, + ["first"]={ + ["cs"]="prvni", + ["de"]="erste", + ["en"]="first", + ["fr"]="premier", + ["it"]="primo", + ["nl"]="eerste", + ["pe"]="اولی", + ["ro"]="primul", + }, + ["firstcolumn"]={ + ["cs"]="firstcolumn", + ["de"]="firstcolumn", + ["en"]="firstcolumn", + ["fr"]="premierecolonne", + ["it"]="firstcolumn", + ["nl"]="eerstekolom", + ["pe"]="ستون‌اول", + ["ro"]="firstcolumn", + }, + ["firstpage"]={ + ["cs"]="prvnistranka", + ["de"]="ersteseite", + ["en"]="firstpage", + ["fr"]="premierepage", + ["it"]="primapagina", + ["nl"]="eerstepagina", + ["pe"]="صفحه‌اول", + ["ro"]="primapagina", + }, + ["firstsubpage"]={ + ["cs"]="prvnipodstranka", + ["de"]="ersteunterseite", + ["en"]="firstsubpage", + ["fr"]="premieresouspage", + ["it"]="primasottopagina", + ["nl"]="eerstesubpagina", + ["pe"]="زیرصفحه‌اول", + ["ro"]="primasubpagina", + }, + ["fit"]={ + ["cs"]="prizpusobive", + ["de"]="passend", + ["en"]="fit", + ["fr"]="adapte", + ["it"]="adatta", + ["nl"]="passend", + ["pe"]="پرکردن", + ["ro"]="ajustat", + }, + ["five"]={ + ["cs"]="pet", + ["de"]="fuenf", + ["en"]="five", + ["fr"]="cinq", + ["it"]="cinque", + ["nl"]="vijf", + ["pe"]="پنج", + ["ro"]="cinci", + }, + ["fix"]={ + ["cs"]="fixuj", + ["de"]="stellewiederher", + ["en"]="fix", + ["fr"]="fixe", + ["it"]="fisso", + ["nl"]="herstel", + ["pe"]="ثابت‌کن", + ["ro"]="fix", + }, + ["fixed"]={ + ["cs"]="fixne", + ["de"]="fest", + ["en"]="fixed", + ["fr"]="fixe", + ["it"]="fisso", + ["nl"]="vast", + ["pe"]="ثابت", + ["ro"]="fixat", + }, + ["flexible"]={ + ["cs"]="prizpusobive", + ["de"]="flexibel", + ["en"]="flexible", + ["fr"]="flexible", + ["it"]="flessibile", + ["nl"]="flexibel", + ["pe"]="انعطافپذیر", + ["ro"]="flexibil", + }, + ["float"]={ + ["cs"]="plvouciobjekt", + ["de"]="gleitobjekt", + ["en"]="float", + ["fr"]="flottant", + ["it"]="oggettomobile", + ["nl"]="blok", + ["pe"]="شناور", + ["ro"]="obiectmobil", + }, + ["flushinner"]={ + ["cs"]="flushinner", + ["de"]="flushinner", + ["en"]="flushinner", + ["fr"]="flushinner", + ["it"]="flushinner", + ["nl"]="lijnbinnen", + ["pe"]="پمپ‌داخلی", + ["ro"]="flushinner", + }, + ["flushleft"]={ + ["cs"]="flushleft", + ["de"]="flushleft", + ["en"]="flushleft", + ["fr"]="flushleft", + ["it"]="flushleft", + ["nl"]="lijnlinks", + ["pe"]="پمپ‌چپ", + ["ro"]="flushleft", + }, + ["flushouter"]={ + ["cs"]="flushouter", + ["de"]="flushouter", + ["en"]="flushouter", + ["fr"]="flushouter", + ["it"]="flushouter", + ["nl"]="lijnbuiten", + ["pe"]="پمپ‌خارجی", + ["ro"]="flushouter", + }, + ["flushright"]={ + ["cs"]="flushright", + ["de"]="flushright", + ["en"]="flushright", + ["fr"]="flushright", + ["it"]="flushright", + ["nl"]="lijnrechts", + ["pe"]="پمپ‌راست", + ["ro"]="flushright", + }, + ["footer"]={ + ["cs"]="upati", + ["de"]="fusszeile", + ["en"]="footer", + ["fr"]="pdp", + ["it"]="piedipagina", + ["nl"]="voet", + ["pe"]="ته‌برگ", + ["ro"]="subsol", + }, + ["footnote"]={ + ["cs"]="poznamkapodcarou", + ["de"]="fussnote", + ["en"]="footnote", + ["fr"]="notepdp", + ["it"]="notapdp", + ["nl"]="voetnoot", + ["pe"]="پانوشت", + ["ro"]="notasubsol", + }, + ["force"]={ + ["cs"]="sila", + ["de"]="zwinge", + ["en"]="force", + ["fr"]="force", + ["it"]="forza", + ["nl"]="forceer", + ["pe"]="اجبار", + ["ro"]="fortat", + }, + ["foreground"]={ + ["cs"]="popredi", + ["de"]="vordergrund", + ["en"]="foreground", + ["fr"]="premierplan", + ["it"]="foreground", + ["nl"]="voorgrond", + ["pe"]="پیش‌زمینه", + ["ro"]="primplan", + }, + ["formeel"]={ + ["cs"]="formeel", + ["de"]="formeel", + ["en"]="formeel", + ["fr"]="formeel", + ["it"]="formeel", + ["nl"]="formeel", + ["pe"]="formeel", + ["ro"]="formeel", + }, + ["formula"]={ + ["cs"]="rovnice", + ["de"]="formel", + ["en"]="formula", + ["fr"]="formule", + ["it"]="formula", + ["nl"]="formule", + ["pe"]="فرمول", + ["ro"]="formula", + }, + ["formulae"]={ + ["cs"]="rovnice", + ["de"]="formeln", + ["en"]="formulae", + ["fr"]="formules", + ["it"]="formule", + ["nl"]="formules", + ["pe"]="فرمولها", + ["ro"]="formule", + }, + ["forward"]={ + ["cs"]="vpred", + ["de"]="vorwaerts", + ["en"]="forward", + ["fr"]="avance", + ["it"]="avanti", + ["nl"]="vooruit", + ["pe"]="به‌جلو", + ["ro"]="avans", + }, + ["four"]={ + ["cs"]="ctyri", + ["de"]="vier", + ["en"]="four", + ["fr"]="quatre", + ["it"]="quattro", + ["nl"]="vier", + ["pe"]="چهار", + ["ro"]="patru", + }, + ["frame"]={ + ["cs"]="ramecek", + ["de"]="rahmen", + ["en"]="frame", + ["fr"]="cadre", + ["it"]="cornice", + ["nl"]="kader", + ["pe"]="قالب", + ["ro"]="incadrat", + }, + ["framedtext"]={ + ["cs"]="oramovanytext", + ["de"]="umrahmtertext", + ["en"]="framedtext", + ["fr"]="texteencadre", + ["it"]="testoincorniciato", + ["nl"]="kadertekst", + ["pe"]="متن‌قالبی", + ["ro"]="textinconjurat", + }, + ["friday"]={ + ["cs"]="patek", + ["de"]="freitag", + ["en"]="friday", + ["fr"]="vendredi", + ["it"]="venerdi", + ["nl"]="vrijdag", + ["pe"]="جمعه", + ["ro"]="vineri", + }, + ["frontmatter"]={ + ["cs"]="prednicasti", + ["de"]="einleitungen", + ["en"]="frontmatter", + ["fr"]="preambule", + ["it"]="preambolo", + ["nl"]="inleidingen", + ["pe"]="پیش‌مطلب", + ["ro"]="prologul", + }, + ["frontpart"]={ + ["cs"]="prednicast", + ["de"]="einleitung", + ["en"]="frontpart", + ["fr"]="preface", + ["it"]="prefazione", + ["nl"]="inleiding", + ["pe"]="پیش‌قسمت", + ["ro"]="prolog", + }, + ["global"]={ + ["cs"]="globalne", + ["de"]="global", + ["en"]="global", + ["fr"]="global", + ["it"]="globale", + ["nl"]="globaal", + ["pe"]="سراسری", + ["ro"]="global", + }, + ["graphic"]={ + ["cs"]="graf", + ["de"]="grafik", + ["en"]="graphic", + ["fr"]="graphique", + ["it"]="grafico", + ["nl"]="grafiek", + ["pe"]="گرافیک", + ["ro"]="graficul", + }, + ["graphics"]={ + ["cs"]="grafy", + ["de"]="grafiken", + ["en"]="graphics", + ["fr"]="graphiques", + ["it"]="grafici", + ["nl"]="grafieken", + ["pe"]="گرافیکها", + ["ro"]="graficele", + }, + ["gray"]={ + ["cs"]="seda", + ["de"]="grau", + ["en"]="gray", + ["fr"]="gris", + ["it"]="grigio", + ["nl"]="grijs", + ["pe"]="خاکستری", + ["ro"]="gri", + }, + ["greek"]={ + ["cs"]="recky", + ["de"]="griechisch", + ["en"]="greek", + ["fr"]="grec", + ["it"]="greco", + ["nl"]="grieks", + ["pe"]="یونانی", + ["ro"]="grec", + }, + ["grid"]={ + ["cs"]="mrizka", + ["de"]="gritter", + ["en"]="grid", + ["fr"]="grille", + ["it"]="griglia", + ["nl"]="grid", + ["pe"]="توری", + ["ro"]="grila", + }, + ["halfline"]={ + ["cs"]="pulradku", + ["de"]="halbezeile", + ["en"]="halfline", + ["fr"]="demiligne", + ["it"]="mezzariga", + ["nl"]="halveregel", + ["pe"]="نیم‌خط", + ["ro"]="jumatatelinie", + }, + ["handwritten"]={ + ["cs"]="rukopisne", + ["de"]="handschrift", + ["en"]="handwritten", + ["fr"]="manuscript", + ["it"]="grafiamanuale", + ["nl"]="handschrift", + ["pe"]="دست‌نوشته", + ["ro"]="scrismanual", + }, + ["hang"]={ + ["cs"]="zaveseni", + ["de"]="haengend", + ["en"]="hang", + ["fr"]="suspend", + ["it"]="sospendi", + ["nl"]="hang", + ["pe"]="بیاویز", + ["ro"]="suspenda", + }, + ["hanging"]={ + ["cs"]="visici", + ["de"]="haengend", + ["en"]="hanging", + ["fr"]="suspend", + ["it"]="sospeso", + ["nl"]="hangend", + ["pe"]="آویزان", + ["ro"]="suspendat", + }, + ["head"]={ + ["cs"]="hlavicka", + ["de"]="kopf", + ["en"]="head", + ["fr"]="tete", + ["it"]="testa", + ["nl"]="kop", + ["pe"]="سر", + ["ro"]="antet", + }, + ["header"]={ + ["cs"]="zahlavi", + ["de"]="kopfzeile", + ["en"]="header", + ["fr"]="entete", + ["it"]="intestazione", + ["nl"]="hoofd", + ["pe"]="سربرگ", + ["ro"]="antet", + }, + ["height"]={ + ["cs"]="vyska", + ["de"]="hoehe", + ["en"]="height", + ["fr"]="hauteur", + ["it"]="altezza", + ["nl"]="hoogte", + ["pe"]="ارتفاع", + ["ro"]="inaltime", + }, + ["helptext"]={ + ["cs"]="textnapovedy", + ["de"]="hilfetext", + ["en"]="helptext", + ["fr"]="texteaide", + ["it"]="testoaiuto", + ["nl"]="helptekst", + ["pe"]="متن‌کمکی", + ["ro"]="textajutator", + }, + ["hencefore"]={ + ["cs"]="vyse", + ["de"]="vorher", + ["en"]="hencefore", + ["fr"]="precedent", + ["it"]="precedente", + ["nl"]="hierboven", + ["pe"]="hencefore", + ["ro"]="precedent", + }, + ["here"]={ + ["cs"]="zde", + ["de"]="hier", + ["en"]="here", + ["fr"]="ici", + ["it"]="qui", + ["nl"]="hier", + ["pe"]="اینجا", + ["ro"]="aici", + }, + ["hereafter"]={ + ["cs"]="nize", + ["de"]="nachher", + ["en"]="hereafter", + ["fr"]="suivant", + ["it"]="seguente", + ["nl"]="hieronder", + ["pe"]="ازاین‌به‌بعد", + ["ro"]="urmator", + }, + ["hidden"]={ + ["cs"]="skryte", + ["de"]="versteckt", + ["en"]="hidden", + ["fr"]="cache", + ["it"]="nascosto", + ["nl"]="verborgen", + ["pe"]="پنهانی", + ["ro"]="ascuns", + }, + ["hiding"]={ + ["cs"]="skryt", + ["de"]="verbergen", + ["en"]="hiding", + ["fr"]="cache", + ["it"]="nascondere", + ["nl"]="verbergen", + ["pe"]="پنهان‌کردن", + ["ro"]="ascundere", + }, + ["high"]={ + ["cs"]="vysoko", + ["de"]="hoch", + ["en"]="high", + ["fr"]="haut", + ["it"]="alto", + ["nl"]="hoog", + ["pe"]="بلند", + ["ro"]="inalt", + }, + ["horizontal"]={ + ["cs"]="horizontalne", + ["de"]="horizontal", + ["en"]="horizontal", + ["fr"]="horizontale", + ["it"]="orizzontale", + ["nl"]="horizontaal", + ["pe"]="افقی", + ["ro"]="orizontal", + }, + ["hyphenated"]={ + ["cs"]="hyphenated", + ["de"]="hyphenate", + ["en"]="hyphenated", + ["fr"]="hyphenated", + ["it"]="sillabato", + ["nl"]="afgebroken", + ["pe"]="شکسته", + ["ro"]="despsilabe", + }, + ["hz"]={ + ["cs"]="hz", + ["de"]="hz", + ["en"]="hz", + ["fr"]="hz", + ["it"]="hz", + ["nl"]="hz", + ["pe"]="hz", + ["ro"]="hz", + }, + ["inbetween"]={ + ["cs"]="mezi", + ["de"]="zwischen", + ["en"]="inbetween", + ["fr"]="entre", + ["it"]="tra", + ["nl"]="tussen", + ["pe"]="دربین", + ["ro"]="intre", + }, + ["index"]={ + ["cs"]="rejstrik", + ["de"]="index", + ["en"]="index", + ["fr"]="index", + ["it"]="indiceanalitico", + ["nl"]="index", + ["pe"]="نمایه", + ["ro"]="index", + }, + ["indices"]={ + ["cs"]="rejstriky", + ["de"]="indizies", + ["en"]="indices", + ["fr"]="indices", + ["it"]="indicianalitici", + ["nl"]="indices", + ["pe"]="نمایه‌ها", + ["ro"]="indexuri", + }, + ["informeel"]={ + ["cs"]="informeel", + ["de"]="informeel", + ["en"]="informeel", + ["fr"]="informeel", + ["it"]="informeel", + ["nl"]="informeel", + ["pe"]="informeel", + ["ro"]="informeel", + }, + ["inherit"]={ + ["cs"]="inherit", + ["de"]="inherit", + ["en"]="inherit", + ["fr"]="herite", + ["it"]="inherit", + ["nl"]="erf", + ["pe"]="ارث‌بردن", + ["ro"]="inherit", + }, + ["inleft"]={ + ["cs"]="vlevo", + ["de"]="imlinken", + ["en"]="inleft", + ["fr"]="dansgauche", + ["it"]="insinistra", + ["nl"]="inlinker", + ["pe"]="درون‌چپ", + ["ro"]="instanga", + }, + ["inmargin"]={ + ["cs"]="naokraji", + ["de"]="imrand", + ["en"]="inmargin", + ["fr"]="dansmarge", + ["it"]="inmargine", + ["nl"]="inmarge", + ["pe"]="درون‌حاشیه", + ["ro"]="inmargine", + }, + ["inner"]={ + ["cs"]="uvnitr", + ["de"]="innen", + ["en"]="inner", + ["fr"]="interieur", + ["it"]="interno", + ["nl"]="binnen", + ["pe"]="داخلی", + ["ro"]="intern", + }, + ["inneredge"]={ + ["cs"]="inneredge", + ["de"]="inneredge", + ["en"]="inneredge", + ["fr"]="bordinterieur", + ["it"]="bordointerno", + ["nl"]="binnenrand", + ["pe"]="لبه‌داخلی", + ["ro"]="inneredge", + }, + ["innermargin"]={ + ["cs"]="innermargin", + ["de"]="innermargin", + ["en"]="innermargin", + ["fr"]="margeinterieure", + ["it"]="margineinterno", + ["nl"]="binnenmarge", + ["pe"]="حاشیه‌داخلی", + ["ro"]="innermargin", + }, + ["inright"]={ + ["cs"]="vpravo", + ["de"]="imrechten", + ["en"]="inright", + ["fr"]="dansdroit", + ["it"]="indestra", + ["nl"]="inrechter", + ["pe"]="درون‌راست", + ["ro"]="indreapta", + }, + ["interaction"]={ + ["cs"]="interakce", + ["de"]="interaktion", + ["en"]="interaction", + ["fr"]="interaction", + ["it"]="interazione", + ["nl"]="interactie", + ["pe"]="پانل", + ["ro"]="interactiune", + }, + ["interactionmenu"]={ + ["cs"]="interaktivnimenu", + ["de"]="interaktionsmenue", + ["en"]="interactionmenu", + ["fr"]="menuinteraction", + ["it"]="menuinterattivo", + ["nl"]="interactiemenu", + ["pe"]="منوی‌پانل", + ["ro"]="meniuinteractiune", + }, + ["intermezzi"]={ + ["cs"]="intermezzi", + ["de"]="intermezzi", + ["en"]="intermezzi", + ["fr"]="intermezzi", + ["it"]="intermezzi", + ["nl"]="intermezzos", + ["pe"]="میان‌پرده‌ها", + ["ro"]="intermezzi", + }, + ["intermezzo"]={ + ["cs"]="intermezzo", + ["de"]="intermezzo", + ["en"]="intermezzo", + ["fr"]="intermezzo", + ["it"]="intermezzo", + ["nl"]="intermezzo", + ["pe"]="میان‌پرده", + ["ro"]="intermezzo", + }, + ["intext"]={ + ["cs"]="dotextu", + ["de"]="imtext", + ["en"]="intext", + ["fr"]="danstexte", + ["it"]="intesto", + ["nl"]="intekst", + ["pe"]="درون‌متن", + ["ro"]="intext", + }, + ["intro"]={ + ["cs"]="uvod", + ["de"]="intro", + ["en"]="intro", + ["fr"]="intro", + ["it"]="intro", + ["nl"]="intro", + ["pe"]="پیشگفتار", + ["ro"]="intro", + }, + ["italic"]={ + ["cs"]="kurziva", + ["de"]="italic", + ["en"]="italic", + ["fr"]="italique", + ["it"]="corsivo", + ["nl"]="italic", + ["pe"]="ایتالیک", + ["ro"]="italic", + }, + ["italicbold"]={ + ["cs"]="kurzivnitucne", + ["de"]="italicfett", + ["en"]="italicbold", + ["fr"]="grasitalique", + ["it"]="corsivograssetto", + ["nl"]="italicvet", + ["pe"]="مشکی‌ایتالیک", + ["ro"]="italicaldin", + }, + ["item"]={ + ["cs"]="polozka", + ["de"]="pos", + ["en"]="item", + ["fr"]="element", + ["it"]="elemento", + ["nl"]="som", + ["pe"]="آیتم", + ["ro"]="element", + }, + ["itemize"]={ + ["cs"]="vycet", + ["de"]="aufzaehlung", + ["en"]="itemize", + ["fr"]="lister", + ["it"]="elenco", + ["nl"]="opsomming", + ["pe"]="آیتم‌بندی", + ["ro"]="enumerare", + }, + ["its"]={ + ["cs"]="pol", + ["de"]="its", + ["en"]="its", + ["fr"]="its", + ["it"]="its", + ["nl"]="its", + ["pe"]="آیم", + ["ro"]="propriu", + }, + ["january"]={ + ["cs"]="leden", + ["de"]="Januar", + ["en"]="January", + ["fr"]="janvier", + ["it"]="gennaio", + ["nl"]="januari", + ["pe"]="ژانویه", + ["ro"]="ianuarie", + }, + ["joinedup"]={ + ["cs"]="spojeno", + ["de"]="keinabstand", + ["en"]="joinedup", + ["fr"]="joinedup", + ["it"]="unito", + ["nl"]="aansluitend", + ["pe"]="متصل‌بالا", + ["ro"]="unit", + }, + ["july"]={ + ["cs"]="cervenec", + ["de"]="Juli", + ["en"]="July", + ["fr"]="juillet", + ["it"]="luglio", + ["nl"]="juli", + ["pe"]="ژولای", + ["ro"]="iulie", + }, + ["june"]={ + ["cs"]="cerven", + ["de"]="Juni", + ["en"]="June", + ["fr"]="juin", + ["it"]="giugno", + ["nl"]="juni", + ["pe"]="ژوئن", + ["ro"]="iunie", + }, + ["keep"]={ + ["cs"]="drzet", + ["de"]="behalte", + ["en"]="keep", + ["fr"]="maintient", + ["it"]="mantieni", + ["nl"]="handhaaf", + ["pe"]="نگهدار", + ["ro"]="mentine", + }, + ["knockout"]={ + ["cs"]="knockout", + ["de"]="knockout", + ["en"]="knockout", + ["fr"]="knockout", + ["it"]="knockout", + ["nl"]="knockout", + ["pe"]="knockout", + ["ro"]="knockout", + }, + ["label"]={ + ["cs"]="popisek", + ["de"]="label", + ["en"]="label", + ["fr"]="etiquette", + ["it"]="etichetta", + ["nl"]="label", + ["pe"]="برچسب", + ["ro"]="eticheta", + }, + ["landscape"]={ + ["cs"]="nasirku", + ["de"]="querformat", + ["en"]="landscape", + ["fr"]="paysage", + ["it"]="orizzontale", + ["nl"]="liggend", + ["pe"]="صفحه‌گسترده", + ["ro"]="vedere", + }, + ["last"]={ + ["cs"]="posledni", + ["de"]="letzte", + ["en"]="last", + ["fr"]="dernier", + ["it"]="ultimo", + ["nl"]="laatste", + ["pe"]="آخرین", + ["ro"]="ultim", + }, + ["lastcolumn"]={ + ["cs"]="lastcolumn", + ["de"]="lastcolumn", + ["en"]="lastcolumn", + ["fr"]="dernierecolonne", + ["it"]="lastcolumn", + ["nl"]="laatstekolom", + ["pe"]="آخرین‌ستون", + ["ro"]="lastcolumn", + }, + ["lastpage"]={ + ["cs"]="poslednistrana", + ["de"]="letzteseite", + ["en"]="lastpage", + ["fr"]="dernierepage", + ["it"]="ultimapagina", + ["nl"]="laatstepagina", + ["pe"]="صفحه‌آخر", + ["ro"]="ultimapagina", + }, + ["lastpagenumber"]={ + ["cs"]="lastpagenumber", + ["de"]="lastpagenumber", + ["en"]="lastpagenumber", + ["fr"]="derniernumeropage", + ["it"]="lastpagenumber", + ["nl"]="laatstepaginanummer", + ["pe"]="شماه‌صفحه‌آخر", + ["ro"]="lastpagenumber", + }, + ["lastsubpage"]={ + ["cs"]="poslaednipodstranka", + ["de"]="letzteunterseite", + ["en"]="lastsubpage", + ["fr"]="dernieresouspage", + ["it"]="ultimasottopagina", + ["nl"]="laatstesubpagina", + ["pe"]="زیرصفحه‌آخر", + ["ro"]="ultimasubpagina", + }, + ["layer"]={ + ["cs"]="layer", + ["de"]="layer", + ["en"]="layer", + ["fr"]="layer", + ["it"]="layer", + ["nl"]="layer", + ["pe"]="layer", + ["ro"]="layer", + }, + ["left"]={ + ["cs"]="vlevo", + ["de"]="links", + ["en"]="left", + ["fr"]="gauche", + ["it"]="sinistra", + ["nl"]="links", + ["pe"]="چپ", + ["ro"]="stanga", + }, + ["leftedge"]={ + ["cs"]="levahrana", + ["de"]="linkekante", + ["en"]="leftedge", + ["fr"]="bordgauche", + ["it"]="bordosinistro", + ["nl"]="linkerrand", + ["pe"]="لبه‌چپ", + ["ro"]="bordurastanga", + }, + ["lefthanging"]={ + ["cs"]="lefthanging", + ["de"]="lefthanging", + ["en"]="lefthanging", + ["fr"]="lefthanging", + ["it"]="lefthanging", + ["nl"]="linkshangend", + ["pe"]="آویزان‌چپ", + ["ro"]="lefthanging", + }, + ["leftmargin"]={ + ["cs"]="levyokraj", + ["de"]="linkerrand", + ["en"]="leftmargin", + ["fr"]="margegauche", + ["it"]="marginesinistro", + ["nl"]="linkermarge", + ["pe"]="حاشیه‌چپ", + ["ro"]="marginestanga", + }, + ["leftpage"]={ + ["cs"]="levastranka", + ["de"]="linkerseite", + ["en"]="leftpage", + ["fr"]="pagegauche", + ["it"]="paginasinistra", + ["nl"]="linkerpagina", + ["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", + ["en"]="legend", + ["fr"]="legende", + ["it"]="legenda", + ["nl"]="legenda", + ["pe"]="راهنما", + ["ro"]="legenda", + }, + ["lesshyphenation"]={ + ["cs"]="lesshyphenation", + ["de"]="lesshyphenation", + ["en"]="lesshyphenation", + ["fr"]="lesshyphenation", + ["it"]="lesshyphenation", + ["nl"]="lesshyphenation", + ["pe"]="شکست‌کلمات‌کمتر", + ["ro"]="lesshyphenation", + }, + ["line"]={ + ["cs"]="radek", + ["de"]="zeile", + ["en"]="line", + ["fr"]="ligne", + ["it"]="riga", + ["nl"]="regel", + ["pe"]="خط", + ["ro"]="linie", + }, + ["linenote"]={ + ["cs"]="linenote", + ["de"]="linenote", + ["en"]="linenote", + ["fr"]="noteligne", + ["it"]="linenote", + ["nl"]="regelnoot", + ["pe"]="خط‌نوشت", + ["ro"]="linenote", + }, + ["lines"]={ + ["cs"]="radky", + ["de"]="zeilen", + ["en"]="lines", + ["fr"]="lignes", + ["it"]="righe", + ["nl"]="regels", + ["pe"]="خطها", + ["ro"]="linii", + }, + ["list"]={ + ["cs"]="seznam", + ["de"]="liste", + ["en"]="list", + ["fr"]="liste", + ["it"]="elenco", + ["nl"]="lijst", + ["pe"]="لیست", + ["ro"]="lista", + }, + ["local"]={ + ["cs"]="lokalne", + ["de"]="lokal", + ["en"]="local", + ["fr"]="local", + ["it"]="locale", + ["nl"]="lokaal", + ["pe"]="موضعی", + ["ro"]="local", + }, + ["localenvironment"]={ + ["cs"]="lokalnihoprostredi", + ["de"]="lokaleumgebung", + ["en"]="localenvironment", + ["fr"]="environementlocal", + ["it"]="ambientelocale", + ["nl"]="deelomgeving", + ["pe"]="محیط‌موضعی", + ["ro"]="mediulocal", + }, + ["logo"]={ + ["cs"]="logo", + ["de"]="logo", + ["en"]="logo", + ["fr"]="logo", + ["it"]="logo", + ["nl"]="logo", + ["pe"]="آرم", + ["ro"]="logo", + }, + ["logos"]={ + ["cs"]="loga", + ["de"]="logos", + ["en"]="logos", + ["fr"]="logos", + ["it"]="loghi", + ["nl"]="logos", + ["pe"]="آرمها", + ["ro"]="logos", + }, + ["lohi"]={ + ["cs"]="nivy", + ["de"]="hoti", + ["en"]="lohi", + ["fr"]="baha", + ["it"]="pedap", + ["nl"]="laho", + ["pe"]="پابا", + ["ro"]="lohi", + }, + ["loose"]={ + ["cs"]="uvolnene", + ["de"]="lose", + ["en"]="loose", + ["fr"]="perte", + ["it"]="lento", + ["nl"]="los", + ["pe"]="شل", + ["ro"]="larg", + }, + ["low"]={ + ["cs"]="nizko", + ["de"]="tief", + ["en"]="low", + ["fr"]="bas", + ["it"]="basso", + ["nl"]="laag", + ["pe"]="پایین", + ["ro"]="jos", + }, + ["ls"]={ + ["cs"]="ls", + ["de"]="ls", + ["en"]="ls", + ["fr"]="ls", + ["it"]="ls", + ["nl"]="ls", + ["pe"]="ls", + ["ro"]="ls", + }, + ["makeup"]={ + ["cs"]="zlom", + ["de"]="umbruch", + ["en"]="makeup", + ["fr"]="makeup", + ["it"]="makeup", + ["nl"]="opmaak", + ["pe"]="آرایش", + ["ro"]="marcaj", + }, + ["mar"]={ + ["cs"]="mar", + ["de"]="mar", + ["en"]="mar", + ["fr"]="mar", + ["it"]="mar", + ["nl"]="mar", + ["pe"]="حاش", + ["ro"]="mar", + }, + ["march"]={ + ["cs"]="brezen", + ["de"]="Maerz", + ["en"]="March", + ["fr"]="mars", + ["it"]="marzo", + ["nl"]="maart", + ["pe"]="مارس", + ["ro"]="martie", + }, + ["margin"]={ + ["cs"]="marginalie", + ["de"]="marginalie", + ["en"]="margin", + ["fr"]="marge", + ["it"]="margine", + ["nl"]="marge", + ["pe"]="حاشیه", + ["ro"]="margine", + }, + ["marginedge"]={ + ["cs"]="textovahrana", + ["de"]="marginalkante", + ["en"]="marginedge", + ["fr"]="bordmarge", + ["it"]="bordomargine", + ["nl"]="kantlijn", + ["pe"]="لبه‌حاشیه", + ["ro"]="marginebordura", + }, + ["margintitle"]={ + ["cs"]="titulmarginalie", + ["de"]="marginaltitel", + ["en"]="margintitle", + ["fr"]="titremarge", + ["it"]="titoloinmargine", + ["nl"]="margetitel", + ["pe"]="عنوان‌حاشیه", + ["ro"]="titlumarginal", + }, + ["marking"]={ + ["cs"]="znaceni", + ["de"]="beschriftung", + ["en"]="marking", + ["fr"]="marquage", + ["it"]="marcatura", + ["nl"]="markering", + ["pe"]="نشانه‌گذاری", + ["ro"]="marcaje", + }, + ["mathalignment"]={ + ["cs"]="mathalignment", + ["de"]="mathalignment", + ["en"]="mathalignment", + ["fr"]="mathalignment", + ["it"]="mathalignment", + ["nl"]="wiskundeuitlijnen", + ["pe"]="تنظیم‌ریاضی", + ["ro"]="mathalignment", + }, + ["mathcases"]={ + ["cs"]="mathcases", + ["de"]="mathcases", + ["en"]="mathcases", + ["fr"]="mathcases", + ["it"]="mathcases", + ["nl"]="mathcases", + ["pe"]="حالتهای‌ریاضی", + ["ro"]="mathcases", + }, + ["mathmatrix"]={ + ["cs"]="mathmatrix", + ["de"]="mathmatrix", + ["en"]="mathmatrix", + ["fr"]="mathmatrix", + ["it"]="mathmatrix", + ["nl"]="wiskundematrix", + ["pe"]="ماتریش‌ریاضی", + ["ro"]="mathmatrix", + }, + ["max"]={ + ["cs"]="max", + ["de"]="max", + ["en"]="max", + ["fr"]="max", + ["it"]="max", + ["nl"]="max", + ["pe"]="بیشترین", + ["ro"]="max", + }, + ["may"]={ + ["cs"]="kveten", + ["de"]="Mai", + ["en"]="May", + ["fr"]="mai", + ["it"]="maggio", + ["nl"]="mei", + ["pe"]="مه", + ["ro"]="mai", + }, + ["mediaeval"]={ + ["cs"]="stredoveky", + ["de"]="mittelalterlich", + ["en"]="mediaeval", + ["fr"]="medieval", + ["it"]="medievale", + ["nl"]="mediaeval", + ["pe"]="mediaeval", + ["ro"]="medieval", + }, + ["medium"]={ + ["cs"]="stredni", + ["de"]="mittel", + ["en"]="medium", + ["fr"]="moyen", + ["it"]="medio", + ["nl"]="middel", + ["pe"]="متوسط", + ["ro"]="mediu", + }, + ["middle"]={ + ["cs"]="nastred", + ["de"]="mittig", + ["en"]="middle", + ["fr"]="milieu", + ["it"]="centro", + ["nl"]="midden", + ["pe"]="میان", + ["ro"]="centru", + }, + ["min"]={ + ["cs"]="min", + ["de"]="min", + ["en"]="min", + ["fr"]="min", + ["it"]="min", + ["nl"]="min", + ["pe"]="کمترین", + ["ro"]="min", + }, + ["minheight"]={ + ["cs"]="minvyska", + ["de"]="minhoehe", + ["en"]="minheight", + ["fr"]="hauteurmin", + ["it"]="altezzamin", + ["nl"]="minhoogte", + ["pe"]="کمترین‌ارتفاع", + ["ro"]="inaltimeminima", + }, + ["minwidth"]={ + ["cs"]="minsirka", + ["de"]="minbreite", + ["en"]="minwidth", + ["fr"]="largeurmin", + ["it"]="ampiezzamin", + ["nl"]="minbreedte", + ["pe"]="کمترین‌عرض", + ["ro"]="latimeminima", + }, + ["mirrored"]={ + ["cs"]="zrcadleno", + ["de"]="gespiegelt", + ["en"]="mirrored", + ["fr"]="reflete", + ["it"]="riflesso", + ["nl"]="gespiegeld", + ["pe"]="منعکس", + ["ro"]="oglindit", + }, + ["monday"]={ + ["cs"]="pondeli", + ["de"]="montag", + ["en"]="monday", + ["fr"]="lundi", + ["it"]="lunedi", + ["nl"]="maandag", + ["pe"]="دوشنبه", + ["ro"]="luni", + }, + ["mono"]={ + ["cs"]="mono", + ["de"]="mono", + ["en"]="mono", + ["fr"]="mono", + ["it"]="mono", + ["nl"]="mono", + ["pe"]="مونو", + ["ro"]="mono", + }, + ["month"]={ + ["cs"]="mesic", + ["de"]="monat", + ["en"]="month", + ["fr"]="mois", + ["it"]="mese", + ["nl"]="maand", + ["pe"]="ماه", + ["ro"]="luna", + }, + ["morehyphenation"]={ + ["cs"]="morehyphenation", + ["de"]="morehyphenation", + ["en"]="morehyphenation", + ["fr"]="morehyphenation", + ["it"]="morehyphenation", + ["nl"]="morehyphenation", + ["pe"]="شکست‌کلمات‌بیشتر", + ["ro"]="morehyphenation", + }, + ["name"]={ + ["cs"]="jmeno", + ["de"]="name", + ["en"]="name", + ["fr"]="nom", + ["it"]="nome", + ["nl"]="naam", + ["pe"]="نام", + ["ro"]="nume", + }, + ["narrow"]={ + ["cs"]="uzky", + ["de"]="schmall", + ["en"]="narrow", + ["fr"]="etroit", + ["it"]="stretto", + ["nl"]="smal", + ["pe"]="نازک", + ["ro"]="ingust", + }, + ["negative"]={ + ["cs"]="negativ", + ["de"]="negativ", + ["en"]="negative", + ["fr"]="negatif", + ["it"]="negativo", + ["nl"]="negatief", + ["pe"]="منفی", + ["ro"]="negativ", + }, + ["never"]={ + ["cs"]="nikdy", + ["de"]="nie", + ["en"]="never", + ["fr"]="jamais", + ["it"]="mai", + ["nl"]="nooit", + ["pe"]="هیچگاه", + ["ro"]="niciodata", + }, + ["new"]={ + ["cs"]="novy", + ["de"]="neu", + ["en"]="new", + ["fr"]="nouveau", + ["it"]="nuovo", + ["nl"]="nieuw", + ["pe"]="جدید", + ["ro"]="nou", + }, + ["next"]={ + ["cs"]="dalsi", + ["de"]="folgende", + ["en"]="next", + ["fr"]="prochain", + ["it"]="successivo", + ["nl"]="volgende", + ["pe"]="بعدی", + ["ro"]="urmatorul", + }, + ["nextevenpage"]={ + ["cs"]="dalsisudastranka", + ["de"]="naechstegeradeseite", + ["en"]="nextevenpage", + ["fr"]="pagepairesuivante", + ["it"]="paginaparisuccessiva", + ["nl"]="volgendeevenpagina", + ["pe"]="صفحه‌زوج‌بعدی", + ["ro"]="paginaparaurmatoarea", + }, + ["nextoddpage"]={ + ["cs"]="dalsilichastranka", + ["de"]="naechsteungeradeseite", + ["en"]="nextoddpage", + ["fr"]="pageimpairesuivante", + ["it"]="paginadisparisuccessiva", + ["nl"]="volgendeonevenpagina", + ["pe"]="صفحه‌فردبعدی", + ["ro"]="paginaimparaurmatoarea", + }, + ["nextpage"]={ + ["cs"]="dalsistranka", + ["de"]="folgendeseite", + ["en"]="nextpage", + ["fr"]="pagesuivante", + ["it"]="paginasuccessiva", + ["nl"]="volgendepagina", + ["pe"]="صفحه‌بعدی", + ["ro"]="paginaurmatoare", + }, + ["nextsubpage"]={ + ["cs"]="dalsipodstranka", + ["de"]="folgendeunterseite", + ["en"]="nextsubpage", + ["fr"]="souspagesuivante", + ["it"]="sottopaginasuccessiva", + ["nl"]="volgendesubpagina", + ["pe"]="زیرصفحه‌بعدی", + ["ro"]="urmatoareasubpagina", + }, + ["no"]={ + ["cs"]="ne", + ["de"]="nein", + ["en"]="no", + ["fr"]="non", + ["it"]="no", + ["nl"]="nee", + ["pe"]="نه", + ["ro"]="nu", + }, + ["nocheck"]={ + ["cs"]="nocheck", + ["de"]="nocheck", + ["en"]="nocheck", + ["fr"]="nonverifie", + ["it"]="nocheck", + ["nl"]="geencontrole", + ["pe"]="بدون‌بررسی", + ["ro"]="nocheck", + }, + ["nofit"]={ + ["cs"]="nofit", + ["de"]="nofit", + ["en"]="nofit", + ["fr"]="nofit", + ["it"]="nofit", + ["nl"]="nietpassend", + ["pe"]="بدون‌پرکردن", + ["ro"]="nofit", + }, + ["nogrid"]={ + ["cs"]="nogrid", + ["de"]="nogrid", + ["en"]="nogrid", + ["fr"]="nogrid", + ["it"]="nogrid", + ["nl"]="geengrid", + ["pe"]="بدون‌توری", + ["ro"]="nogrid", + }, + ["nohz"]={ + ["cs"]="nohz", + ["de"]="nohz", + ["en"]="nohz", + ["fr"]="nohz", + ["it"]="nohz", + ["nl"]="geenhz", + ["pe"]="nohz", + ["ro"]="nohz", + }, + ["nomarking"]={ + ["cs"]="zadneznaceni", + ["de"]="keinebeschriftung", + ["en"]="nomarking", + ["fr"]="sansmarquage", + ["it"]="nomarcature", + ["nl"]="geenmarkering", + ["pe"]="بدون‌نشانه‌گذاری", + ["ro"]="faramarcare", + }, + ["none"]={ + ["cs"]="zadny", + ["de"]="kein", + ["en"]="none", + ["fr"]="rien", + ["it"]="nessuno", + ["nl"]="geen", + ["pe"]="هیچکدام", + ["ro"]="niciunul", + }, + ["nonumber"]={ + ["cs"]="nonumber", + ["de"]="nonumber", + ["en"]="nonumber", + ["fr"]="sansnumero", + ["it"]="nonumber", + ["nl"]="geennummer", + ["pe"]="بدون‌شماره", + ["ro"]="nonumber", + }, + ["normal"]={ + ["cs"]="normalni", + ["de"]="normal", + ["en"]="normal", + ["fr"]="normal", + ["it"]="normale", + ["nl"]="normaal", + ["pe"]="نرمال", + ["ro"]="normal", + }, + ["nospacing"]={ + ["cs"]="nospacing", + ["de"]="nospacing", + ["en"]="nospacing", + ["fr"]="sansespacement", + ["it"]="nospacing", + ["nl"]="geenspatiering", + ["pe"]="بدون‌فضاگذاری", + ["ro"]="nospacing", + }, + ["not"]={ + ["cs"]="ne", + ["de"]="nicht", + ["en"]="not", + ["fr"]="pas", + ["it"]="non", + ["nl"]="niet", + ["pe"]="بدون", + ["ro"]="nu", + }, + ["note"]={ + ["en"]="note", + }, + ["nothanging"]={ + ["cs"]="nothanging", + ["de"]="nothanging", + ["en"]="nothanging", + ["fr"]="nonsuspendu", + ["it"]="nonsospeso", + ["nl"]="niethangend", + ["pe"]="بدون‌آویزان‌کردن", + ["ro"]="nothanging", + }, + ["nothyphenated"]={ + ["cs"]="nothyphenated", + ["de"]="nothyphenated", + ["en"]="nothyphenated", + ["fr"]="nothyphenated", + ["it"]="nonsillabato", + ["nl"]="nietafgebroken", + ["pe"]="بدون‌شکست", + ["ro"]="nedespsilabe", + }, + ["november"]={ + ["cs"]="listopad", + ["de"]="November", + ["en"]="November", + ["fr"]="novembre", + ["it"]="novembre", + ["nl"]="november", + ["pe"]="نوامبر", + ["ro"]="noiembrie", + }, + ["nowhere"]={ + ["cs"]="nikde", + ["de"]="nirgens", + ["en"]="nowhere", + ["fr"]="nulpart", + ["it"]="danessunaparte", + ["nl"]="nergens", + ["pe"]="هیچ‌حا", + ["ro"]="niciunde", + }, + ["nowhite"]={ + ["cs"]="zadnabila", + ["de"]="keinweiss", + ["en"]="nowhite", + ["fr"]="sansblanc", + ["it"]="nobianco", + ["nl"]="geenwit", + ["pe"]="سفید‌نه", + ["ro"]="faraalb", + }, + ["number"]={ + ["cs"]="cislo", + ["de"]="nummer", + ["en"]="number", + ["fr"]="numero", + ["it"]="numero", + ["nl"]="nummer", + ["pe"]="شماره", + ["ro"]="numar", + }, + ["numbers"]={ + ["cs"]="cisla", + ["de"]="ziffern", + ["en"]="numbers", + ["fr"]="numeros", + ["it"]="numeri", + ["nl"]="cijfers", + ["pe"]="شماره‌ها", + ["ro"]="numere", + }, + ["october"]={ + ["cs"]="rijen", + ["de"]="Oktober", + ["en"]="October", + ["fr"]="octobre", + ["it"]="ottobre", + ["nl"]="oktober", + ["pe"]="اکتبر", + ["ro"]="octombrie", + }, + ["odd"]={ + ["cs"]="liche", + ["de"]="ungerade", + ["en"]="odd", + ["fr"]="impair", + ["it"]="dispari", + ["nl"]="oneven", + ["pe"]="فرد", + ["ro"]="impar", + }, + ["off"]={ + ["cs"]="vyp", + ["de"]="aus", + ["en"]="off", + ["fr"]="desactive", + ["it"]="disattivo", + ["nl"]="uit", + ["pe"]="خاموش", + ["ro"]="dezactivat", + }, + ["offset"]={ + ["cs"]="offset", + ["de"]="offset", + ["en"]="offset", + ["fr"]="offset", + ["it"]="offset", + ["nl"]="offset", + ["pe"]="آفست", + ["ro"]="offset", + }, + ["old"]={ + ["cs"]="old", + ["de"]="old", + ["en"]="old", + ["fr"]="old", + ["it"]="old", + ["nl"]="oud", + ["pe"]="قدیمی", + ["ro"]="old", + }, + ["on"]={ + ["cs"]="zap", + ["de"]="an", + ["en"]="on", + ["fr"]="actif", + ["it"]="attivo", + ["nl"]="aan", + ["pe"]="روی", + ["ro"]="on", + }, + ["one"]={ + ["cs"]="jedna", + ["de"]="eins", + ["en"]="one", + ["fr"]="un", + ["it"]="uno", + ["nl"]="een", + ["pe"]="یک", + ["ro"]="unu", + }, + ["opposite"]={ + ["cs"]="naproti", + ["de"]="gegenueber", + ["en"]="opposite", + ["fr"]="opposition", + ["it"]="opposto", + ["nl"]="naast", + ["pe"]="مخالف", + ["ro"]="opus", + }, + ["outer"]={ + ["cs"]="vnejsi", + ["de"]="aussen", + ["en"]="outer", + ["fr"]="exterieur", + ["it"]="esterno", + ["nl"]="buiten", + ["pe"]="خارجی", + ["ro"]="extern", + }, + ["outeredge"]={ + ["cs"]="outeredge", + ["de"]="outeredge", + ["en"]="outeredge", + ["fr"]="bordexterieur", + ["it"]="bordoesterno", + ["nl"]="buitenrand", + ["pe"]="لبه‌خارجی", + ["ro"]="outeredge", + }, + ["outermargin"]={ + ["cs"]="outermargin", + ["de"]="outermargin", + ["en"]="outermargin", + ["fr"]="margeexterieure", + ["it"]="margineesterno", + ["nl"]="buitenmarge", + ["pe"]="حاشیه‌خارجی", + ["ro"]="outermargin", + }, + ["overlay"]={ + ["cs"]="prekryv", + ["de"]="overlay", + ["en"]="overlay", + ["fr"]="revetement", + ["it"]="sovrapponi", + ["nl"]="overlay", + ["pe"]="پوشش", + ["ro"]="overlay", + }, + ["overprint"]={ + ["cs"]="overprint", + ["de"]="overprint", + ["en"]="overprint", + ["fr"]="overprint", + ["it"]="overprint", + ["nl"]="overprint", + ["pe"]="overprint", + ["ro"]="overprint", + }, + ["packed"]={ + ["cs"]="zhustene", + ["de"]="gepackt", + ["en"]="packed", + ["fr"]="groupe", + ["it"]="impaccato", + ["nl"]="opelkaar", + ["pe"]="فشرده", + ["ro"]="impachetat", + }, + ["page"]={ + ["cs"]="stranka", + ["de"]="seite", + ["en"]="page", + ["fr"]="page", + ["it"]="pagina", + ["nl"]="pagina", + ["pe"]="صفحه", + ["ro"]="pagina", + }, + ["pagecomment"]={ + ["cs"]="komentarstranky", + ["de"]="pagecomment", + ["en"]="pagecomment", + ["fr"]="commentairepage", + ["it"]="commentopagina", + ["nl"]="paginacommentaar", + ["pe"]="توضیح‌صفحه", + ["ro"]="comentariupagina", + }, + ["pagenumber"]={ + ["cs"]="cislostranky", + ["de"]="seitennummer", + ["en"]="pagenumber", + ["fr"]="numeropage", + ["it"]="numeropagina", + ["nl"]="paginanummer", + ["pe"]="شماره‌صفحه", + ["ro"]="numarpagina", + }, + ["paper"]={ + ["cs"]="papir", + ["de"]="papier", + ["en"]="paper", + ["fr"]="papier", + ["it"]="carta", + ["nl"]="papier", + ["pe"]="برگ", + ["ro"]="foaie", + }, + ["paragraph"]={ + ["cs"]="odstavec", + ["de"]="absatz", + ["en"]="paragraph", + ["fr"]="paragraphe", + ["it"]="capoverso", + ["nl"]="alinea", + ["pe"]="پاراگراف", + ["ro"]="paragraf", + }, + ["part"]={ + ["cs"]="cast", + ["de"]="teil", + ["en"]="part", + ["fr"]="partie", + ["it"]="parte", + ["nl"]="deel", + ["pe"]="قسمت", + ["ro"]="parte", + }, + ["positive"]={ + ["cs"]="positiv", + ["de"]="positiv", + ["en"]="positive", + ["fr"]="positif", + ["it"]="positivo", + ["nl"]="positief", + ["pe"]="مثبت", + ["ro"]="positiv", + }, + ["postponing"]={ + ["cs"]="odlozit", + ["de"]="verschieben", + ["en"]="postponing", + ["fr"]="postponing", + ["it"]="posporre", + ["nl"]="uitstellen", + ["pe"]="تاخیر", + ["ro"]="postponing", + }, + ["postscript"]={ + ["cs"]="postscript", + ["de"]="postscript", + ["en"]="postscript", + ["fr"]="postscript", + ["it"]="postscript", + ["nl"]="postscript", + ["pe"]="پست‌اسکریپت", + ["ro"]="postscript", + }, + ["preference"]={ + ["cs"]="nastaveni", + ["de"]="einstellung", + ["en"]="preference", + ["fr"]="preference", + ["it"]="preferenza", + ["nl"]="voorkeur", + ["pe"]="ترجیح", + ["ro"]="preferinta", + }, + ["preview"]={ + ["cs"]="nahled", + ["de"]="vorschau", + ["en"]="preview", + ["fr"]="previsualisation", + ["it"]="anteprima", + ["nl"]="preview", + ["pe"]="پیش‌دید", + ["ro"]="previzualizare", + }, + ["previous"]={ + ["cs"]="predchozi", + ["de"]="vorig", + ["en"]="previous", + ["fr"]="precedent", + ["it"]="precedente", + ["nl"]="vorige", + ["pe"]="قبلی", + ["ro"]="precedent", + }, + ["previousevenpage"]={ + ["cs"]="predchozisudastranka", + ["de"]="vorigegeradeseite", + ["en"]="previousevenpage", + ["fr"]="pagepaireprecedente", + ["it"]="paginapariprecedente", + ["nl"]="vorigeevenpagina", + ["pe"]="صفحه‌زوج‌قبلی", + ["ro"]="paginaparaprecedenta", + }, + ["previousoddpage"]={ + ["cs"]="predchozilichastranka", + ["de"]="vorigeungeradeseite", + ["en"]="previousoddpage", + ["fr"]="pageimpaireprecedente", + ["it"]="paginadispariprecedente", + ["nl"]="vorigeonevenpagina", + ["pe"]="صفحه‌فردقبلی", + ["ro"]="paginaimparaprecedenta", + }, + ["previouspage"]={ + ["cs"]="predchozistranka", + ["de"]="vorigeseite", + ["en"]="previouspage", + ["fr"]="pageprecedente", + ["it"]="paginaprecedente", + ["nl"]="vorigepagina", + ["pe"]="صفحه‌قبلی", + ["ro"]="paginaanterioara", + }, + ["previoussubpage"]={ + ["cs"]="predchozipodstranka", + ["de"]="vorigeunterseite", + ["en"]="previoussubpage", + ["fr"]="souspageprecedente", + ["it"]="sottopaginaprecedente", + ["nl"]="vorigesubpagina", + ["pe"]="زیرصفحه‌قبلی", + ["ro"]="subpaginaanterioara", + }, + ["printable"]={ + ["cs"]="tisknutelne", + ["de"]="druckbar", + ["en"]="printable", + ["fr"]="editable", + ["it"]="stampabile", + ["nl"]="printbaar", + ["pe"]="قابل‌چاپ", + ["ro"]="tiparibil", + }, + ["process"]={ + ["cs"]="process", + ["de"]="process", + ["en"]="process", + ["fr"]="process", + ["it"]="process", + ["nl"]="proces", + ["pe"]="پردازش", + ["ro"]="process", + }, + ["product"]={ + ["cs"]="produkt", + ["de"]="produkt", + ["en"]="product", + ["fr"]="produit", + ["it"]="prodotto", + ["nl"]="produkt", + ["pe"]="محصول", + ["ro"]="produs", + }, + ["program"]={ + ["cs"]="program", + ["de"]="programm", + ["en"]="program", + ["fr"]="programme", + ["it"]="programma", + ["nl"]="programma", + ["pe"]="برنامه", + ["ro"]="program", + }, + ["project"]={ + ["cs"]="projekt", + ["de"]="projekt", + ["en"]="project", + ["fr"]="projet", + ["it"]="progetto", + ["nl"]="project", + ["pe"]="پروژه", + ["ro"]="proiect", + }, + ["protected"]={ + ["cs"]="chranene", + ["de"]="geschuetzt", + ["en"]="protected", + ["fr"]="protege", + ["it"]="protetto", + ["nl"]="beschermd", + ["pe"]="حفاظت‌شده", + ["ro"]="protejat", + }, + ["quadruple"]={ + ["cs"]="ctyrnasobny", + ["de"]="viertel", + ["en"]="quadruple", + ["fr"]="quadruple", + ["it"]="quadruplo", + ["nl"]="viertal", + ["pe"]="quadruple", + ["ro"]="cvadrupul", + }, + ["quotation"]={ + ["cs"]="citace", + ["de"]="zitat", + ["en"]="quotation", + ["fr"]="citation", + ["it"]="citazione", + ["nl"]="citaat", + ["pe"]="نقل‌قول", + ["ro"]="citat", + }, + ["quote"]={ + ["cs"]="citovat", + ["de"]="zitieren", + ["en"]="quote", + ["fr"]="citer", + ["it"]="menzione", + ["nl"]="citeer", + ["pe"]="نقل", + ["ro"]="minicitat", + }, + ["ran"]={ + ["cs"]="rozsah", + ["de"]="ran", + ["en"]="ran", + ["fr"]="cours", + ["it"]="corse", + ["nl"]="ran", + ["pe"]="برد", + ["ro"]="rulat", + }, + ["random"]={ + ["cs"]="nahodny", + ["de"]="zufaellig", + ["en"]="random", + ["fr"]="aleatoire", + ["it"]="casuale", + ["nl"]="willekeurig", + ["pe"]="تصادفی", + ["ro"]="aleator", + }, + ["readonly"]={ + ["cs"]="pouzeprocteni", + ["de"]="nurlesbar", + ["en"]="readonly", + ["fr"]="lectureseule", + ["it"]="solalettura", + ["nl"]="alleenleesbaar", + ["pe"]="تنهاخواندنی", + ["ro"]="readonly", + }, + ["rectangular"]={ + ["cs"]="pravouhly", + ["de"]="rechteckig", + ["en"]="rectangular", + ["fr"]="rectangulaire", + ["it"]="rettangolare", + ["nl"]="recht", + ["pe"]="چهارگوشه", + ["ro"]="rectangular", + }, + ["referral"]={ + ["cs"]="znacka", + ["de"]="merkmal", + ["en"]="referral", + ["fr"]="referral", + ["it"]="referral", + ["nl"]="kenmerk", + ["pe"]="مراجعه", + ["ro"]="referinta", + }, + ["register"]={ + ["cs"]="rejstrik", + ["de"]="register", + ["en"]="register", + ["fr"]="registre", + ["it"]="registro", + ["nl"]="register", + ["pe"]="ثبت", + ["ro"]="registru", + }, + ["regular"]={ + ["cs"]="pravidelne", + ["de"]="regular", + ["en"]="regular", + ["fr"]="regulier", + ["it"]="regolare", + ["nl"]="regular", + ["pe"]="منظم", + ["ro"]="regular", + }, + ["rekening"]={ + ["cs"]="rekening", + ["de"]="rekening", + ["en"]="rekening", + ["fr"]="rekening", + ["it"]="rekening", + ["nl"]="rekening", + ["pe"]="rekening", + ["ro"]="rekening", + }, + ["relative"]={ + ["cs"]="relativni", + ["de"]="relativ", + ["en"]="relative", + ["fr"]="relatif", + ["it"]="relativo", + ["nl"]="relatief", + ["pe"]="نسبی", + ["ro"]="relativ", + }, + ["repeat"]={ + ["cs"]="opakovat", + ["de"]="wiederholen", + ["en"]="repeat", + ["fr"]="repete", + ["it"]="ripeti", + ["nl"]="herhaal", + ["pe"]="تکرار", + ["ro"]="repetat", + }, + ["required"]={ + ["cs"]="pozadovane", + ["de"]="obligatorisch", + ["en"]="required", + ["fr"]="recquis", + ["it"]="richiestp", + ["nl"]="verplicht", + ["pe"]="موردنیاز", + ["ro"]="obligatoriu", + }, + ["reset"]={ + ["cs"]="reset", + ["de"]="zuruecksetzten", + ["en"]="reset", + ["fr"]="raz", + ["it"]="reimposta", + ["nl"]="reset", + ["pe"]="بازنشانی", + ["ro"]="reset", + }, + ["reverse"]={ + ["cs"]="reverse", + ["de"]="reverse", + ["en"]="reverse", + ["fr"]="inverse", + ["it"]="invertito", + ["nl"]="omgekeerd", + ["pe"]="برعکس", + ["ro"]="reverse", + }, + ["right"]={ + ["cs"]="vpravo", + ["de"]="rechts", + ["en"]="right", + ["fr"]="droite", + ["it"]="destra", + ["nl"]="rechts", + ["pe"]="راست", + ["ro"]="dreapta", + }, + ["rightedge"]={ + ["cs"]="pravahrana", + ["de"]="rechterkante", + ["en"]="rightedge", + ["fr"]="borddroit", + ["it"]="bordodestro", + ["nl"]="rechterrand", + ["pe"]="لبه‌راست", + ["ro"]="borduradreapta", + }, + ["righthanging"]={ + ["cs"]="righthanging", + ["de"]="righthanging", + ["en"]="righthanging", + ["fr"]="righthanging", + ["it"]="righthanging", + ["nl"]="rechtshangend", + ["pe"]="آویزان‌کردن‌راست", + ["ro"]="righthanging", + }, + ["rightmargin"]={ + ["cs"]="pravyokraj", + ["de"]="rechterrand", + ["en"]="rightmargin", + ["fr"]="margedroite", + ["it"]="marginedestro", + ["nl"]="rechtermarge", + ["pe"]="حاشیه‌راست", + ["ro"]="marginedreapta", + }, + ["rightpage"]={ + ["cs"]="pravastranka", + ["de"]="rechterseite", + ["en"]="rightpage", + ["fr"]="pagedroite", + ["it"]="paginadestra", + ["nl"]="rechterpagina", + ["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", + ["en"]="roman", + ["fr"]="roman", + ["it"]="roman", + ["nl"]="romaan", + ["pe"]="رومن", + ["ro"]="roman", + }, + ["romannumerals"]={ + ["cs"]="rimskecislice", + ["de"]="roemischezahlen", + ["en"]="romannumerals", + ["fr"]="chiffresromains", + ["it"]="numeriromani", + ["nl"]="romeins", + ["pe"]="شماره‌لاتین", + ["ro"]="numereromane", + }, + ["rotate"]={ + ["cs"]="otoc", + ["de"]="drehe", + ["en"]="rotate", + ["fr"]="oriente", + ["it"]="ruota", + ["nl"]="roteer", + ["pe"]="دوران", + ["ro"]="rotit", + }, + ["rotated"]={ + ["cs"]="otoceno", + ["de"]="gedreht", + ["en"]="rotated", + ["fr"]="tourne", + ["it"]="ruotato", + ["nl"]="geroteerd", + ["pe"]="دوران‌یافته", + ["ro"]="rotat", + }, + ["round"]={ + ["cs"]="zaobleny", + ["de"]="rund", + ["en"]="round", + ["fr"]="rond", + ["it"]="rotondo", + ["nl"]="rond", + ["pe"]="گرد", + ["ro"]="rotund", + }, + ["row"]={ + ["cs"]="row", + ["de"]="row", + ["en"]="row", + ["fr"]="rang", + ["it"]="row", + ["nl"]="rij", + ["pe"]="سطر", + ["ro"]="rand", + }, + ["rule"]={ + ["cs"]="linka", + ["de"]="linie", + ["en"]="rule", + ["fr"]="regle", + ["it"]="linea", + ["nl"]="lijn", + ["pe"]="خط", + ["ro"]="rigla", + }, + ["samepage"]={ + ["cs"]="stejnastranka", + ["de"]="selbeseite", + ["en"]="samepage", + ["fr"]="memepage", + ["it"]="stessapagina", + ["nl"]="zelfdepagina", + ["pe"]="همان‌صفحه", + ["ro"]="aceeasipagina", + }, + ["sans"]={ + ["cs"]="sans", + ["de"]="sans", + ["en"]="sans", + ["fr"]="sans", + ["it"]="sans", + ["nl"]="sans", + ["pe"]="سانز", + ["ro"]="sans", + }, + ["sansbold"]={ + ["cs"]="sanstucne", + ["de"]="sansfett", + ["en"]="sansbold", + ["fr"]="sansgras", + ["it"]="sansgrassetto", + ["nl"]="sansvet", + ["pe"]="مشکی‌سانز", + ["ro"]="sansaldin", + }, + ["sansserif"]={ + ["cs"]="bezserifu", + ["de"]="grotesk", + ["en"]="sansserif", + ["fr"]="sansserif", + ["it"]="sansserif", + ["nl"]="schreefloos", + ["pe"]="سانزسریف", + ["ro"]="sansserif", + }, + ["saturday"]={ + ["cs"]="sobota", + ["de"]="samstag", + ["en"]="saturday", + ["fr"]="samedi", + ["it"]="sabato", + ["nl"]="zaterdag", + ["pe"]="شنبه", + ["ro"]="sambata", + }, + ["screen"]={ + ["cs"]="rastr", + ["de"]="raster", + ["en"]="screen", + ["fr"]="ecran", + ["it"]="schermo", + ["nl"]="raster", + ["pe"]="پرده", + ["ro"]="ecran", + }, + ["section"]={ + ["cs"]="sekce", + ["de"]="absatz", + ["en"]="section", + ["fr"]="section", + ["it"]="capoverso", + ["nl"]="paragraaf", + ["pe"]="بخش", + ["ro"]="sectiune", + }, + ["sectionblockenvironment"]={ + ["cs"]="sectionblockenvironment", + ["de"]="sectionblockenvironment", + ["en"]="sectionblockenvironment", + ["fr"]="environementblocsection", + ["it"]="ambientebloccosezione", + ["nl"]="sectieblokomgeving", + ["pe"]="محیط‌بلوک‌بخش", + ["ro"]="blocsectiuneambient", + }, + ["sectionnumber"]={ + ["cs"]="cislooddilu", + ["de"]="abschnittsnummer", + ["en"]="sectionnumber", + ["fr"]="numerosection", + ["it"]="numerosezione", + ["nl"]="sectienummer", + ["pe"]="شماره‌بخش", + ["ro"]="numarsetiune", + }, + ["see"]={ + ["cs"]="viz", + ["de"]="sieh", + ["en"]="see", + ["fr"]="voit", + ["it"]="vedi", + ["nl"]="zie", + ["pe"]="ببینید", + ["ro"]="vezi", + }, + ["september"]={ + ["cs"]="zari", + ["de"]="September", + ["en"]="September", + ["fr"]="septembre", + ["it"]="settembre", + ["nl"]="september", + ["pe"]="سپتامبر", + ["ro"]="septembrie", + }, + ["serif"]={ + ["cs"]="serif", + ["de"]="serif", + ["en"]="serif", + ["fr"]="serif", + ["it"]="serif", + ["nl"]="serif", + ["pe"]="سریف", + ["ro"]="serif", + }, + ["serried"]={ + ["cs"]="semknuto", + ["de"]="kleinerabstand", + ["en"]="serried", + ["fr"]="serried", + ["it"]="vicino", + ["nl"]="aanelkaar", + ["pe"]="تنگ‌هم", + ["ro"]="serried", + }, + ["setups"]={ + ["cs"]="einstellungen", + ["de"]="impostazioni", + ["en"]="setups", + ["fr"]="reglages", + ["it"]="nastaveni", + ["nl"]="instellingen", + ["pe"]="بارگذاریها", + ["ro"]="setari", + }, + ["sheet"]={ + ["cs"]="sheet", + ["de"]="sheet", + ["en"]="sheet", + ["fr"]="sheet", + ["it"]="sheet", + ["nl"]="sheet", + ["pe"]="ورقه", + ["ro"]="sheet", + }, + ["singlesided"]={ + ["cs"]="jednostranne", + ["de"]="einzelseitig", + ["en"]="singlesided", + ["fr"]="recto", + ["it"]="facciasingola", + ["nl"]="enkelzijdig", + ["pe"]="یک‌رو", + ["ro"]="ofata", + }, + ["slanted"]={ + ["cs"]="sklonene", + ["de"]="geneigt", + ["en"]="slanted", + ["fr"]="incline", + ["it"]="inclinato", + ["nl"]="schuin", + ["pe"]="خوابیده", + ["ro"]="inclinat", + }, + ["slantedbold"]={ + ["cs"]="sklonenetucne", + ["de"]="geneigtfett", + ["en"]="slantedbold", + ["fr"]="grasincline", + ["it"]="inclinatograssetto", + ["nl"]="schuinvet", + ["pe"]="مشکی‌خوابیده", + ["ro"]="inclinataldin", + }, + ["small"]={ + ["cs"]="male", + ["de"]="klein", + ["en"]="small", + ["fr"]="petit", + ["it"]="piccolo", + ["nl"]="klein", + ["pe"]="کوچک", + ["ro"]="mic", + }, + ["smallbodyfont"]={ + ["cs"]="smallbodyfont", + ["de"]="smallbodyfont", + ["en"]="smallbodyfont", + ["fr"]="petitepolicecorps", + ["it"]="piccolofontdelcorpo", + ["nl"]="kleinkorps", + ["pe"]="قلم‌بدنه‌کوچک", + ["ro"]="smallbodyfont", + }, + ["smallbold"]={ + ["cs"]="maletucne", + ["de"]="kleinfett", + ["en"]="smallbold", + ["fr"]="graspetit", + ["it"]="piccolograssetto", + ["nl"]="kleinvet", + ["pe"]="مشکی‌کوچک", + ["ro"]="micaldin", + }, + ["smallbolditalic"]={ + ["cs"]="maletucnekurzivni", + ["de"]="kleinfettitalic", + ["en"]="smallbolditalic", + ["fr"]="italiquegraspetit", + ["it"]="piccolograssettocorsivo", + ["nl"]="kleinvetitalic", + ["pe"]="ایتالیک‌مشکی‌کوچک", + ["ro"]="micaldininclinat", + }, + ["smallboldslanted"]={ + ["cs"]="maletucnesklonene", + ["de"]="kleinfettgeneigt", + ["en"]="smallboldslanted", + ["fr"]="inclinegraspetit", + ["it"]="piccolograssettoinclinato", + ["nl"]="kleinvetschuin", + ["pe"]="خوابیده‌مشکی‌کوچک", + ["ro"]="micaldininclinat", + }, + ["smallcaps"]={ + ["cs"]="kapitalky", + ["de"]="smallcaps", + ["en"]="smallcaps", + ["fr"]="petitescapitales", + ["it"]="maiuscoletto", + ["nl"]="smallcaps", + ["pe"]="smallcaps", + ["ro"]="majusculemici", + }, + ["smallitalic"]={ + ["cs"]="malekurzivni", + ["de"]="kleinitalic", + ["en"]="smallitalic", + ["fr"]="italiquepetit", + ["it"]="piccolocorsivo", + ["nl"]="kleinitalic", + ["pe"]="ایتالیک‌کوچک", + ["ro"]="micitalic", + }, + ["smallitalicbold"]={ + ["cs"]="malekurzivnitucne", + ["de"]="kleinitalicfett", + ["en"]="smallitalicbold", + ["fr"]="grasitaliquepetit", + ["it"]="piccolocorsivograssetto", + ["nl"]="kleinitalicvet", + ["pe"]="مشکی‌ایتالیک‌کوچک", + ["ro"]="micitalicaldin", + }, + ["smallnormal"]={ + ["cs"]="malenormalni", + ["de"]="kleinnormal", + ["en"]="smallnormal", + ["fr"]="normalpetit", + ["it"]="piccolonormale", + ["nl"]="kleinnormaal", + ["pe"]="نرمال‌کوچک", + ["ro"]="micnormal", + }, + ["smallslanted"]={ + ["cs"]="malesklonene", + ["de"]="kleingeneigt", + ["en"]="smallslanted", + ["fr"]="inclinepetit", + ["it"]="piccoloinclinato", + ["nl"]="kleinschuin", + ["pe"]="خوابیده‌کوچک", + ["ro"]="micinclinat", + }, + ["smallslantedbold"]={ + ["cs"]="malesklonenetucne", + ["de"]="kleingeneigtfett", + ["en"]="smallslantedbold", + ["fr"]="grasinclinepetit", + ["it"]="piccoloinclinatograssetto", + ["nl"]="kleinschuinvet", + ["pe"]="مشکی‌خوابیده‌کوچک", + ["ro"]="micinclinataldin", + }, + ["smalltype"]={ + ["cs"]="maletype", + ["de"]="kleintippen", + ["en"]="smalltype", + ["fr"]="petittype", + ["it"]="piccolotype", + ["nl"]="kleintype", + ["pe"]="تایپ‌کوچک", + ["ro"]="mictype", + }, + ["somewhere"]={ + ["cs"]="nekde", + ["de"]="irgendwo", + ["en"]="somewhere", + ["fr"]="qqpart", + ["it"]="daqualcheparte", + ["nl"]="ergens", + ["pe"]="جایی", + ["ro"]="undeva", + }, + ["sorted"]={ + ["cs"]="tridene", + ["de"]="sortiert", + ["en"]="sorted", + ["fr"]="trie", + ["it"]="ordinato", + ["nl"]="gesorteerd", + ["pe"]="مرتب", + ["ro"]="sortat", + }, + ["space"]={ + ["cs"]="mezera", + ["de"]="spatium", + ["en"]="space", + ["fr"]="espace", + ["it"]="spazio", + ["nl"]="spatie", + ["pe"]="فضا", + ["ro"]="spatiu", + }, + ["spacing"]={ + ["cs"]="mezerovani", + ["de"]="spatiumausgleich", + ["en"]="spacing", + ["fr"]="espacement", + ["it"]="spaziatura", + ["nl"]="spatiering", + ["pe"]="فضاگذاری", + ["ro"]="spatiere", + }, + ["speech"]={ + ["cs"]="speech", + ["de"]="speech", + ["en"]="speech", + ["fr"]="discours", + ["it"]="speech", + ["nl"]="spraak", + ["pe"]="سخنرانی", + ["ro"]="speech", + }, + ["split"]={ + ["cs"]="split", + ["de"]="split", + ["en"]="split", + ["fr"]="split", + ["it"]="separa", + ["nl"]="splitsen", + ["pe"]="شکافتن", + ["ro"]="split", + }, + ["spot"]={ + ["cs"]="spot", + ["de"]="spot", + ["en"]="spot", + ["fr"]="spot", + ["it"]="spot", + ["nl"]="spot", + ["pe"]="لکه", + ["ro"]="spot", + }, + ["standard"]={ + ["cs"]="standardni", + ["de"]="standard", + ["en"]="standard", + ["fr"]="standard", + ["it"]="standard", + ["nl"]="standaard", + ["pe"]="استاندارد", + ["ro"]="standard", + }, + ["start"]={ + ["cs"]="start", + ["de"]="start", + ["en"]="start", + ["fr"]="demarre", + ["it"]="inizia", + ["nl"]="start", + ["pe"]="شروع", + ["ro"]="start", + }, + ["sticker"]={ + ["cs"]="sticker", + ["de"]="sticker", + ["en"]="sticker", + ["fr"]="sticker", + ["it"]="sticker", + ["nl"]="sticker", + ["pe"]="دشنه", + ["ro"]="sticker", + }, + ["stop"]={ + ["cs"]="stop", + ["de"]="stop", + ["en"]="stop", + ["fr"]="stoppe", + ["it"]="termina", + ["nl"]="stop", + ["pe"]="پایان", + ["ro"]="stop", + }, + ["stopper"]={ + ["cs"]="predel", + ["de"]="trenner", + ["en"]="stopper", + ["fr"]="stopper", + ["it"]="stopper", + ["nl"]="afsluiter", + ["pe"]="ایست", + ["ro"]="stopper", + }, + ["starter"]={ + ["en"]="starter", + ["nl"]="opener", + }, + ["stretch"]={ + ["cs"]="natahnout", + ["de"]="strecken", + ["en"]="stretch", + ["fr"]="etire", + ["it"]="dilata", + ["nl"]="rek", + ["pe"]="بکش", + ["ro"]="dilatat", + }, + ["strict"]={ + ["cs"]="striktni", + ["de"]="streng", + ["en"]="strict", + ["fr"]="strict", + ["it"]="rigido", + ["nl"]="streng", + ["pe"]="اکید", + ["ro"]="strict", + }, + ["strong"]={ + ["cs"]="strong", + ["de"]="strong", + ["en"]="strong", + ["fr"]="strong", + ["it"]="strong", + ["nl"]="sterk", + ["pe"]="محکم", + ["ro"]="strong", + }, + ["strut"]={ + ["cs"]="strut", + ["de"]="strut", + ["en"]="strut", + ["fr"]="strut", + ["it"]="strut", + ["nl"]="strut", + ["pe"]="بست", + ["ro"]="strut", + }, + ["sub"]={ + ["cs"]="pod", + ["de"]="unter", + ["en"]="sub", + ["fr"]="sous", + ["it"]="sotto", + ["nl"]="sub", + ["pe"]="زیر", + ["ro"]="sub", + }, + ["subbackward"]={ + ["cs"]="podzpet", + ["de"]="unterrueckwaerts", + ["en"]="subbackward", + ["fr"]="sousretourarriere", + ["it"]="sottoindietro", + ["nl"]="subachteruit", + ["pe"]="زیرعقب‌گرد", + ["ro"]="subinapoi", + }, + ["subformula"]={ + ["cs"]="subrovnice", + ["de"]="subformel", + ["en"]="subformula", + ["fr"]="subformule", + ["it"]="subformula", + ["nl"]="subformule", + ["pe"]="زیرفرمول", + ["ro"]="subformula", + }, + ["subforward"]={ + ["cs"]="podvpred", + ["de"]="untervorwaerts", + ["en"]="subforward", + ["fr"]="sousavance", + ["it"]="sottoavanti", + ["nl"]="subvooruit", + ["pe"]="زیرجلوگرد", + ["ro"]="subavans", + }, + ["subject"]={ + ["cs"]="tema", + ["de"]="thema", + ["en"]="subject", + ["fr"]="sujet", + ["it"]="argomento", + ["nl"]="onderwerp", + ["pe"]="موضوع", + ["ro"]="subiect", + }, + ["subpage"]={ + ["cs"]="podstranka", + ["de"]="unterseite", + ["en"]="subpage", + ["fr"]="souspage", + ["it"]="sottopagina", + ["nl"]="subpagina", + ["pe"]="زیرصفحه", + ["ro"]="subpagina", + }, + ["subsection"]={ + ["cs"]="podsekce", + ["de"]="unterabsatz", + ["en"]="subsection", + ["fr"]="soussection", + ["it"]="sottocapoverso", + ["nl"]="subparagraaf", + ["pe"]="زیربخش", + ["ro"]="subsectiune", + }, + ["subsubject"]={ + ["cs"]="podtema", + ["de"]="unterthema", + ["en"]="subsubject", + ["fr"]="soussujet", + ["it"]="sottoargomento", + ["nl"]="subonderwerp", + ["pe"]="زیرموضوع", + ["ro"]="subsubiect", + }, + ["subsubsection"]={ + ["cs"]="podpodsekce", + ["de"]="unterunterabsatz", + ["en"]="subsubsection", + ["fr"]="soussoussection", + ["it"]="sottosottocapoverso", + ["nl"]="subsubparagraaf", + ["pe"]="زیرزیربخش", + ["ro"]="subsubsectiune", + }, + ["subsubsubject"]={ + ["cs"]="podpodtema", + ["de"]="unterunterthema", + ["en"]="subsubsubject", + ["fr"]="soussoussujet", + ["it"]="sottosottoargomento", + ["nl"]="subsubonderwerp", + ["pe"]="زیرزیرموضوع", + ["ro"]="subsubsubiect", + }, + ["subsubsubsection"]={ + ["cs"]="podpodpodsekce", + ["de"]="unterunterunterabsatz", + ["en"]="subsubsubsection", + ["fr"]="soussoussoussection", + ["it"]="sottosottosottocapoverso", + ["nl"]="subsubsubparagraaf", + ["pe"]="زیرزیرزیربخش", + ["ro"]="subsubsubsectiune", + }, + ["subsubsubsubject"]={ + ["cs"]="podpodpodtema", + ["de"]="unterunterunterthema", + ["en"]="subsubsubsubject", + ["fr"]="soussoussoussujet", + ["it"]="sottosottosottoargomento", + ["nl"]="subsubsubonderwerp", + ["pe"]="زیرزیرزیرموضوع", + ["ro"]="subsubsubsubiect", + }, + ["subsubsubsubsection"]={ + ["cs"]="podpodpodpodsekce", + ["de"]="unterunterunterunterabsatz", + ["en"]="subsubsubsubsection", + ["fr"]="soussoussoussoussection", + ["it"]="sottosottosottosottocapoverso", + ["nl"]="subsubsubsubparagraaf", + ["pe"]="زیرزیرزیرزیربخش", + ["ro"]="subsubsubsubsectiune", + }, + ["subsubsubsubsubject"]={ + ["cs"]="podpodpodpodtema", + ["de"]="unterunterunterunterthema", + ["en"]="subsubsubsubsubject", + ["fr"]="soussoussoussoussujet", + ["it"]="sottosottosottosottoargomento", + ["nl"]="subsubsubsubonderwerp", + ["pe"]="زیرزیرزیرزیرموضوع", + ["ro"]="subsubsubsubsubiect", + }, + ["subsubsubsubsubsection"]={ + ["cs"]="podpodpodpodpodsekce", + ["de"]="unterunterunterunterunterabsatz", + ["en"]="subsubsubsubsubsection", + ["fr"]="soussoussoussoussoussection", + ["it"]="sottosottosottosottosottocapoverso", + ["nl"]="subsubsubsubsubparagraaf", + ["pe"]="زیرزیرزیرزیرزیربخش", + ["ro"]="subsubsubsubsubsectiune", + }, + ["subsubsubsubsubsubject"]={ + ["cs"]="podpodpodpodpodtema", + ["de"]="unterunterunterunterunterthema", + ["en"]="subsubsubsubsubsubject", + ["fr"]="soussoussoussoussoussujet", + ["it"]="sottosottosottosottosottoargomento", + ["nl"]="subsubsubsubsubonderwerp", + ["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", + ["en"]="sunday", + ["fr"]="dimanche", + ["it"]="domenica", + ["nl"]="zondag", + ["pe"]="یک‌شنبه", + ["ro"]="duminica", + }, + ["support"]={ + ["cs"]="podpora", + ["de"]="support", + ["en"]="support", + ["fr"]="support", + ["it"]="supporto", + ["nl"]="support", + ["pe"]="حمایت", + ["ro"]="suport", + }, + ["sym"]={ + ["cs"]="sym", + ["de"]="sym", + ["en"]="sym", + ["fr"]="sym", + ["it"]="sim", + ["nl"]="sym", + ["pe"]="نم", + ["ro"]="sym", + }, + ["symbol"]={ + ["cs"]="symbol", + ["de"]="symbol", + ["en"]="symbol", + ["fr"]="symbole", + ["it"]="simbolo", + ["nl"]="symbool", + ["pe"]="نماد", + ["ro"]="simbol", + }, + ["synchronize"]={ + ["cs"]="synchronize", + ["de"]="synchronize", + ["en"]="synchronize", + ["fr"]="synchronize", + ["it"]="synchronize", + ["nl"]="synchroniseer", + ["pe"]="تطابق", + ["ro"]="synchronize", + }, + ["system"]={ + ["cs"]="system", + ["de"]="systeme", + ["en"]="system", + ["fr"]="systeme", + ["it"]="sistema", + ["nl"]="systeem", + ["pe"]="سیستم", + ["ro"]="sistem", + }, + ["table"]={ + ["cs"]="tabulka", + ["de"]="tabelle", + ["en"]="table", + ["fr"]="tableau", + ["it"]="tabella", + ["nl"]="tabel", + ["pe"]="جدول", + ["ro"]="tabelul", + }, + ["tablehead"]={ + ["cs"]="zahlavitabulky", + ["de"]="tabellenueberschrift", + ["en"]="tablehead", + ["fr"]="tetetableau", + ["it"]="testatabella", + ["nl"]="tabelkop", + ["pe"]="سرجدول", + ["ro"]="antettabel", + }, + ["tables"]={ + ["cs"]="tabulky", + ["de"]="tabellen", + ["en"]="tables", + ["fr"]="tables", + ["it"]="tabelle", + ["nl"]="tabellen", + ["pe"]="جدولها", + ["ro"]="tabelele", + }, + ["tabletail"]={ + ["cs"]="konectabulky", + ["de"]="tabellenende", + ["en"]="tabletail", + ["fr"]="queuetableau", + ["it"]="codatabella", + ["nl"]="tabelstaart", + ["pe"]="دنباله‌جدول", + ["ro"]="subsoltabel", + }, + ["tabulate"]={ + ["cs"]="tabelator", + ["de"]="tabulator", + ["en"]="tabulate", + ["fr"]="tabule", + ["it"]="tabulato", + ["nl"]="tabulatie", + ["pe"]="جدول‌بندی", + ["ro"]="tabulate", + }, + ["tabulatehead"]={ + ["cs"]="tabulatehead", + ["de"]="tabulatehead", + ["en"]="tabulatehead", + ["fr"]="tetetabule", + ["it"]="testatabulato", + ["nl"]="tabulatiekop", + ["pe"]="سرجدول‌بندی", + ["ro"]="tabulatehead", + }, + ["tabulatetail"]={ + ["cs"]="tabulatetail", + ["de"]="tabulatetail", + ["en"]="tabulatetail", + ["fr"]="queuetabule", + ["it"]="codatabulato", + ["nl"]="tabulatiestaart", + ["pe"]="دنباله‌جدول‌بندی", + ["ro"]="tabulatetail", + }, + ["tall"]={ + ["cs"]="vysoko", + ["de"]="lang", + ["en"]="tall", + ["fr"]="long", + ["it"]="alto", + ["nl"]="lang", + ["pe"]="دراز", + ["ro"]="inalt", + }, + ["teletype"]={ + ["cs"]="strojopis", + ["de"]="fernschreiber", + ["en"]="teletype", + ["fr"]="teletype", + ["it"]="teletype", + ["nl"]="teletype", + ["pe"]="دورنگاره", + ["ro"]="teletype", + }, + ["temporary"]={ + ["cs"]="docasne", + ["de"]="temporaer", + ["en"]="temporary", + ["fr"]="temporaire", + ["it"]="temporaneo", + ["nl"]="voorlopig", + ["pe"]="موقتی", + ["ro"]="temporar", + }, + ["test"]={ + ["cs"]="test", + ["de"]="test", + ["en"]="test", + ["fr"]="test", + ["it"]="test", + ["nl"]="test", + ["pe"]="تست", + ["ro"]="test", + }, + ["text"]={ + ["cs"]="text", + ["de"]="text", + ["en"]="text", + ["fr"]="texte", + ["it"]="testo", + ["nl"]="tekst", + ["pe"]="متن", + ["ro"]="text", + }, + ["three"]={ + ["cs"]="tri", + ["de"]="drei", + ["en"]="three", + ["fr"]="trois", + ["it"]="tre", + ["nl"]="drie", + ["pe"]="سه", + ["ro"]="trei", + }, + ["thursday"]={ + ["cs"]="ctvrtek", + ["de"]="donnerstag", + ["en"]="thursday", + ["fr"]="jeudi", + ["it"]="giovedi", + ["nl"]="donderdag", + ["pe"]="پنج‌شنبه", + ["ro"]="joi", + }, + ["title"]={ + ["cs"]="titul", + ["de"]="titel", + ["en"]="title", + ["fr"]="titre", + ["it"]="titolo", + ["nl"]="titel", + ["pe"]="عنوان", + ["ro"]="titlu", + }, + ["toggle"]={ + ["cs"]="toggle", + ["de"]="toggle", + ["en"]="wissel", + ["fr"]="toggle", + ["it"]="toggle", + ["nl"]="toggle", + ["pe"]="تغییر", + ["ro"]="toggle", + }, + ["tolerant"]={ + ["cs"]="tolerantni", + ["de"]="tolerant", + ["en"]="tolerant", + ["fr"]="tolerant", + ["it"]="tollerante", + ["nl"]="soepel", + ["pe"]="بردبار", + ["ro"]="tolerant", + }, + ["top"]={ + ["cs"]="vrsek", + ["de"]="oben", + ["en"]="top", + ["fr"]="sup", + ["it"]="cima", + ["nl"]="boven", + ["pe"]="بالا", + ["ro"]="sus", + }, + ["tuesday"]={ + ["cs"]="utery", + ["de"]="dienstag", + ["en"]="tuesday", + ["fr"]="mardi", + ["it"]="martedi", + ["nl"]="dinsdag", + ["pe"]="سه‌شنبه", + ["ro"]="marti", + }, + ["two"]={ + ["cs"]="dve", + ["de"]="zwei", + ["en"]="two", + ["fr"]="deux", + ["it"]="due", + ["nl"]="twee", + ["pe"]="دو", + ["ro"]="doi", + }, + ["txt"]={ + ["cs"]="txt", + ["de"]="txt", + ["en"]="txt", + ["fr"]="txt", + ["it"]="txt", + ["nl"]="txt", + ["pe"]="txt", + ["ro"]="txt", + }, + ["type"]={ + ["cs"]="opis", + ["de"]="tippen", + ["en"]="type", + ["fr"]="type", + ["it"]="type", + ["nl"]="type", + ["pe"]="تایپ", + ["ro"]="type", + }, + ["typing"]={ + ["cs"]="typing", + ["de"]="tippen", + ["en"]="typing", + ["fr"]="typing", + ["it"]="typing", + ["nl"]="typen", + ["pe"]="تایپ‌کردن", + ["ro"]="typing", + }, + ["unavailable"]={ + ["cs"]="nedostupne", + ["de"]="nichtverfuegbar", + ["en"]="unavailable", + ["fr"]="indisponible", + ["it"]="nondisponibile", + ["nl"]="nietbeschikbaar", + ["pe"]="غیرموجود", + ["ro"]="nedisponibil", + }, + ["unit"]={ + ["cs"]="jednotka", + ["de"]="einheit", + ["en"]="unit", + ["fr"]="unite", + ["it"]="unita", + ["nl"]="eenheid", + ["pe"]="واحد", + ["ro"]="unitate", + }, + ["units"]={ + ["cs"]="jednotky", + ["de"]="einheiten", + ["en"]="units", + ["fr"]="unites", + ["it"]="unita", + ["nl"]="eenheden", + ["pe"]="واحدها", + ["ro"]="unitati", + }, + ["unknown"]={ + ["cs"]="neznamy", + ["de"]="unbekannt", + ["en"]="unknown", + ["fr"]="inconnu", + ["it"]="ignoto", + ["nl"]="onbekend", + ["pe"]="ناشناس", + ["ro"]="necunoscut", + }, + ["unpacked"]={ + ["cs"]="rozbalene", + ["de"]="ungepackt", + ["en"]="unpacked", + ["fr"]="degroupe", + ["it"]="unpacked", + ["nl"]="vanelkaar", + ["pe"]="غیرفشرده", + ["ro"]="despachetat", + }, + ["url"]={ + ["cs"]="url", + ["de"]="url", + ["en"]="url", + ["fr"]="url", + ["it"]="url", + ["nl"]="url", + ["pe"]="url", + ["ro"]="url", + }, + ["used"]={ + ["cs"]="uzito", + ["de"]="verwende", + ["en"]="used", + ["fr"]="used", + ["it"]="usato", + ["nl"]="gebruikt", + ["pe"]="استفاده‌شده", + ["ro"]="folosit", + }, + ["value"]={ + ["cs"]="hodnota", + ["de"]="wert", + ["en"]="value", + ["fr"]="valeur", + ["it"]="valore", + ["nl"]="waarde", + ["pe"]="مقدار", + ["ro"]="valoare", + }, + ["vertical"]={ + ["cs"]="vertikalne", + ["de"]="vertikal", + ["en"]="vertical", + ["fr"]="verticale", + ["it"]="verticale", + ["nl"]="vertikaal", + ["pe"]="عمودی", + ["ro"]="vertical", + }, + ["very"]={ + ["cs"]="velmi", + ["de"]="sehr", + ["en"]="very", + ["fr"]="tres", + ["it"]="molto", + ["nl"]="zeer", + ["pe"]="خیلی", + ["ro"]="foarte", + }, + ["verystrict"]={ + ["cs"]="velmistriktni", + ["de"]="sehrstreng", + ["en"]="verystrict", + ["fr"]="tresstrict", + ["it"]="moltorigido", + ["nl"]="zeerstreng", + ["pe"]="خیلی‌سختگیر", + ["ro"]="foartestrict", + }, + ["verytolerant"]={ + ["cs"]="velmitolerantni", + ["de"]="sehrtolerant", + ["en"]="verytolerant", + ["fr"]="trestolerant", + ["it"]="moltotollerante", + ["nl"]="zeersoepel", + ["pe"]="خیلی‌بردبار", + ["ro"]="foartetolerant", + }, + ["weak"]={ + ["cs"]="weak", + ["de"]="weak", + ["en"]="weak", + ["fr"]="weak", + ["it"]="weak", + ["nl"]="zwak", + ["pe"]="هفته", + ["ro"]="weak", + }, + ["wednesday"]={ + ["cs"]="streda", + ["de"]="mittwoch", + ["en"]="wednesday", + ["fr"]="mercredi", + ["it"]="mercoledi", + ["nl"]="woensdag", + ["pe"]="چهارشنبه", + ["ro"]="miercuri", + }, + ["week"]={ + ["cs"]="tyden", + ["de"]="woche", + ["en"]="week", + ["fr"]="semaine", + ["it"]="settimana", + ["nl"]="week", + ["pe"]="هفته", + ["ro"]="saptamana", + }, + ["weekday"]={ + ["cs"]="vsedniden", + ["de"]="wochentag", + ["en"]="weekday", + ["fr"]="joursemaine", + ["it"]="giornosettimana", + ["nl"]="weekdag", + ["pe"]="روزهفته", + ["ro"]="zisaptamana", + }, + ["white"]={ + ["cs"]="bily", + ["de"]="weiss", + ["en"]="white", + ["fr"]="blanc", + ["it"]="bianco", + ["nl"]="wit", + ["pe"]="سفید", + ["ro"]="alb", + }, + ["wide"]={ + ["cs"]="siroce", + ["de"]="breit", + ["en"]="wide", + ["fr"]="ample", + ["it"]="ampio", + ["nl"]="breed", + ["pe"]="گسترده", + ["ro"]="larg", + }, + ["width"]={ + ["cs"]="sirka", + ["de"]="breite", + ["en"]="width", + ["fr"]="largeur", + ["it"]="ampiezza", + ["nl"]="breedte", + ["pe"]="عرض", + ["ro"]="latime", + }, + ["xml"]={ + ["cs"]="xml", + ["de"]="xml", + ["en"]="xml", + ["fr"]="xml", + ["it"]="xml", + ["nl"]="xml", + ["pe"]="xml", + ["ro"]="xml", + }, + ["year"]={ + ["cs"]="rok", + ["de"]="jahr", + ["en"]="year", + ["fr"]="annee", + ["it"]="anno", + ["nl"]="jaar", + ["pe"]="سال", + ["ro"]="an", + }, + ["yes"]={ + ["cs"]="ano", + ["de"]="ja", + ["en"]="yes", + ["fr"]="oui", + ["it"]="si", + ["nl"]="ja", + ["pe"]="بله", + ["ro"]="da", + }, + }, +} diff --git a/tex/context/base/mult-def.tex b/tex/context/base/mult-def.tex new file mode 100644 index 000000000..cff9fb074 --- /dev/null +++ b/tex/context/base/mult-def.tex @@ -0,0 +1,35 @@ +%D \module +%D [ file=mult-def, +%D version=2008.10.22, +%D title=\CONTEXT\ Multilingual 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. + +\unprotect + +\setvalue{@interface@czech@}{cs} +\setvalue{@interface@german@}{de} +\setvalue{@interface@english@}{en} +\setvalue{@interface@french@}{fr} +\setvalue{@interface@italian@}{it} +\setvalue{@interface@dutch@}{nl} +\setvalue{@interface@persian@}{pe} +\setvalue{@interface@romanian@}{ro} + +% \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 new file mode 100644 index 000000000..20917a034 --- /dev/null +++ b/tex/context/base/mult-en.tex @@ -0,0 +1,1693 @@ +% this file is auto-generated, don't edit this file +% +% definitions for interface variables for language en +% +\setinterfacevariable{Addition}{Addition} +\setinterfacevariable{Balloon}{Balloon} +\setinterfacevariable{Character}{Character} +\setinterfacevariable{Characters}{Characters} +\setinterfacevariable{CloseDocument}{CloseDocument} +\setinterfacevariable{ExitViewer}{ExitViewer} +\setinterfacevariable{FirstPage}{FirstPage} +\setinterfacevariable{FitHeight}{FitHeight} +\setinterfacevariable{FitWidth}{FitWidth} +\setinterfacevariable{GotoPage}{GotoPage} +\setinterfacevariable{Greek}{Greek} +\setinterfacevariable{Help}{Help} +\setinterfacevariable{HideField}{HideField} +\setinterfacevariable{HideLayer}{HideLayer} +\setinterfacevariable{Key}{Key} +\setinterfacevariable{LastPage}{LastPage} +\setinterfacevariable{LoadForm}{LoadForm} +\setinterfacevariable{MONTH}{MONTH} +\setinterfacevariable{New}{New} +\setinterfacevariable{NextJump}{NextJump} +\setinterfacevariable{NextPage}{NextPage} +\setinterfacevariable{Numbers}{Numbers} +\setinterfacevariable{OpenNamedDocument}{OpenNamedDocument} +\setinterfacevariable{Paragraph}{Paragraph} +\setinterfacevariable{PauseMovie}{PauseMovie} +\setinterfacevariable{PauseRendering}{PauseRendering} +\setinterfacevariable{PauseSound}{PauseSound} +\setinterfacevariable{PreviousJump}{PreviousJump} +\setinterfacevariable{PreviousPage}{PreviousPage} +\setinterfacevariable{PrintDocument}{PrintDocument} +\setinterfacevariable{Query}{Query} +\setinterfacevariable{QueryAgain}{QueryAgain} +\setinterfacevariable{ResetForm}{ResetForm} +\setinterfacevariable{ResumeMovie}{ResumeMovie} +\setinterfacevariable{ResumeRendering}{ResumeRendering} +\setinterfacevariable{ResumeSound}{ResumeSound} +\setinterfacevariable{Romannumerals}{Romannumerals} +\setinterfacevariable{SaveDocument}{SaveDocument} +\setinterfacevariable{SaveForm}{SaveForm} +\setinterfacevariable{SaveNamedDocument}{SaveNamedDocument} +\setinterfacevariable{SearchAgain}{SearchAgain} +\setinterfacevariable{SearchDocument}{SearchDocument} +\setinterfacevariable{ShowBookmarks}{ShowBookmarks} +\setinterfacevariable{ShowField}{ShowField} +\setinterfacevariable{ShowThumbs}{ShowThumbs} +\setinterfacevariable{StartMovie}{StartMovie} +\setinterfacevariable{StartRendering}{StartRendering} +\setinterfacevariable{StartSound}{StartSound} +\setinterfacevariable{StopMovie}{StopMovie} +\setinterfacevariable{StopRendering}{StopRendering} +\setinterfacevariable{StopSound}{StopSound} +\setinterfacevariable{SubmitForm}{SubmitForm} +\setinterfacevariable{ToggleLayer}{ToggleLayer} +\setinterfacevariable{ToggleViewer}{ToggleViewer} +\setinterfacevariable{URL}{URL} +\setinterfacevariable{VideLayer}{VideLayer} +\setinterfacevariable{ViewerHelp}{ViewerHelp} +\setinterfacevariable{WEEKDAY}{WEEKDAY} +\setinterfacevariable{WORD}{WORD} +\setinterfacevariable{abbreviation}{abbreviation} +\setinterfacevariable{abbreviations}{abbreviations} +\setinterfacevariable{absolute}{absolute} +\setinterfacevariable{action}{action} +\setinterfacevariable{after}{after} +\setinterfacevariable{all}{all} +\setinterfacevariable{always}{always} +\setinterfacevariable{answerarea}{answerarea} +\setinterfacevariable{appendices}{appendices} +\setinterfacevariable{appendix}{appendix} +\setinterfacevariable{april}{April} +\setinterfacevariable{atmargin}{atmargin} +\setinterfacevariable{atpage}{atpage} +\setinterfacevariable{august}{August} +\setinterfacevariable{author}{author} +\setinterfacevariable{auto}{auto} +\setinterfacevariable{autointro}{autointro} +\setinterfacevariable{back}{back} +\setinterfacevariable{background}{background} +\setinterfacevariable{backmatter}{backmatter} +\setinterfacevariable{backpart}{backpart} +\setinterfacevariable{backspace}{backspace} +\setinterfacevariable{backward}{backward} +\setinterfacevariable{bbl}{bbl} +\setinterfacevariable{before}{before} +\setinterfacevariable{begin}{begin} +\setinterfacevariable{bib}{bib} +\setinterfacevariable{big}{big} +\setinterfacevariable{bigbodyfont}{bigbodyfont} +\setinterfacevariable{bigpreference}{bigpreference} +\setinterfacevariable{blank}{blank} +\setinterfacevariable{blockquote}{blockquote} +\setinterfacevariable{bodymatter}{bodymatter} +\setinterfacevariable{bodypart}{bodypart} +\setinterfacevariable{bold}{bold} +\setinterfacevariable{bolditalic}{bolditalic} +\setinterfacevariable{boldslanted}{boldslanted} +\setinterfacevariable{bookmark}{bookmark} +\setinterfacevariable{both}{both} +\setinterfacevariable{bottom}{bottom} +\setinterfacevariable{brief}{brief} +\setinterfacevariable{broad}{broad} +\setinterfacevariable{buffer}{buffer} +\setinterfacevariable{by}{by} +\setinterfacevariable{calligraphic}{calligraphic} +\setinterfacevariable{cap}{cap} +\setinterfacevariable{capital}{capital} +\setinterfacevariable{center}{center} +\setinterfacevariable{chapter}{chapter} +\setinterfacevariable{character}{character} +\setinterfacevariable{characters}{characters} +\setinterfacevariable{cite}{cite} +\setinterfacevariable{color}{color} +\setinterfacevariable{column}{column} +\setinterfacevariable{columns}{columns} +\setinterfacevariable{command}{command} +\setinterfacevariable{commands}{commands} +\setinterfacevariable{comment}{comment} +\setinterfacevariable{component}{component} +\setinterfacevariable{concept}{concept} +\setinterfacevariable{content}{content} +\setinterfacevariable{contents}{contents} +\setinterfacevariable{continue}{continue} +\setinterfacevariable{controls}{controls} +\setinterfacevariable{conversion}{conversion} +\setinterfacevariable{current}{current} +\setinterfacevariable{cutspace}{cutspace} +\setinterfacevariable{date}{date} +\setinterfacevariable{day}{day} +\setinterfacevariable{december}{December} +\setinterfacevariable{default}{default} +\setinterfacevariable{depth}{depth} +\setinterfacevariable{description}{description} +\setinterfacevariable{disable}{disable} +\setinterfacevariable{display}{display} +\setinterfacevariable{dot}{dot} +\setinterfacevariable{doublesided}{doublesided} +\setinterfacevariable{down}{down} +\setinterfacevariable{each}{each} +\setinterfacevariable{edge}{edge} +\setinterfacevariable{empty}{empty} +\setinterfacevariable{end}{end} +\setinterfacevariable{endnote}{endnote} +\setinterfacevariable{enumeration}{enumeration} +\setinterfacevariable{environment}{environment} +\setinterfacevariable{even}{even} +\setinterfacevariable{external}{external} +\setinterfacevariable{fact}{fact} +\setinterfacevariable{february}{February} +\setinterfacevariable{figure}{figure} +\setinterfacevariable{figures}{figures} +\setinterfacevariable{file}{file} +\setinterfacevariable{final}{final} +\setinterfacevariable{first}{first} +\setinterfacevariable{firstcolumn}{firstcolumn} +\setinterfacevariable{firstpage}{firstpage} +\setinterfacevariable{firstsubpage}{firstsubpage} +\setinterfacevariable{fit}{fit} +\setinterfacevariable{five}{five} +\setinterfacevariable{fix}{fix} +\setinterfacevariable{fixed}{fixed} +\setinterfacevariable{flexible}{flexible} +\setinterfacevariable{float}{float} +\setinterfacevariable{flushinner}{flushinner} +\setinterfacevariable{flushleft}{flushleft} +\setinterfacevariable{flushouter}{flushouter} +\setinterfacevariable{flushright}{flushright} +\setinterfacevariable{footer}{footer} +\setinterfacevariable{footnote}{footnote} +\setinterfacevariable{force}{force} +\setinterfacevariable{foreground}{foreground} +\setinterfacevariable{formeel}{formeel} +\setinterfacevariable{formula}{formula} +\setinterfacevariable{formulae}{formulae} +\setinterfacevariable{forward}{forward} +\setinterfacevariable{four}{four} +\setinterfacevariable{frame}{frame} +\setinterfacevariable{framedtext}{framedtext} +\setinterfacevariable{friday}{friday} +\setinterfacevariable{frontmatter}{frontmatter} +\setinterfacevariable{frontpart}{frontpart} +\setinterfacevariable{global}{global} +\setinterfacevariable{graphic}{graphic} +\setinterfacevariable{graphics}{graphics} +\setinterfacevariable{gray}{gray} +\setinterfacevariable{greek}{greek} +\setinterfacevariable{grid}{grid} +\setinterfacevariable{halfline}{halfline} +\setinterfacevariable{handwritten}{handwritten} +\setinterfacevariable{hang}{hang} +\setinterfacevariable{hanging}{hanging} +\setinterfacevariable{head}{head} +\setinterfacevariable{header}{header} +\setinterfacevariable{height}{height} +\setinterfacevariable{helptext}{helptext} +\setinterfacevariable{hencefore}{hencefore} +\setinterfacevariable{here}{here} +\setinterfacevariable{hereafter}{hereafter} +\setinterfacevariable{hidden}{hidden} +\setinterfacevariable{hiding}{hiding} +\setinterfacevariable{high}{high} +\setinterfacevariable{horizontal}{horizontal} +\setinterfacevariable{hyphenated}{hyphenated} +\setinterfacevariable{hz}{hz} +\setinterfacevariable{inbetween}{inbetween} +\setinterfacevariable{index}{index} +\setinterfacevariable{indices}{indices} +\setinterfacevariable{informeel}{informeel} +\setinterfacevariable{inherit}{inherit} +\setinterfacevariable{inleft}{inleft} +\setinterfacevariable{inmargin}{inmargin} +\setinterfacevariable{inner}{inner} +\setinterfacevariable{inneredge}{inneredge} +\setinterfacevariable{innermargin}{innermargin} +\setinterfacevariable{inright}{inright} +\setinterfacevariable{interaction}{interaction} +\setinterfacevariable{interactionmenu}{interactionmenu} +\setinterfacevariable{intermezzi}{intermezzi} +\setinterfacevariable{intermezzo}{intermezzo} +\setinterfacevariable{intext}{intext} +\setinterfacevariable{intro}{intro} +\setinterfacevariable{italic}{italic} +\setinterfacevariable{italicbold}{italicbold} +\setinterfacevariable{item}{item} +\setinterfacevariable{itemize}{itemize} +\setinterfacevariable{its}{its} +\setinterfacevariable{january}{January} +\setinterfacevariable{joinedup}{joinedup} +\setinterfacevariable{july}{July} +\setinterfacevariable{june}{June} +\setinterfacevariable{keep}{keep} +\setinterfacevariable{knockout}{knockout} +\setinterfacevariable{label}{label} +\setinterfacevariable{landscape}{landscape} +\setinterfacevariable{last}{last} +\setinterfacevariable{lastcolumn}{lastcolumn} +\setinterfacevariable{lastpage}{lastpage} +\setinterfacevariable{lastpagenumber}{lastpagenumber} +\setinterfacevariable{lastsubpage}{lastsubpage} +\setinterfacevariable{layer}{layer} +\setinterfacevariable{left}{left} +\setinterfacevariable{leftedge}{leftedge} +\setinterfacevariable{lefthanging}{lefthanging} +\setinterfacevariable{leftmargin}{leftmargin} +\setinterfacevariable{leftpage}{leftpage} +\setinterfacevariable{lefttoright}{lefttoright} +\setinterfacevariable{legend}{legend} +\setinterfacevariable{lesshyphenation}{lesshyphenation} +\setinterfacevariable{line}{line} +\setinterfacevariable{linenote}{linenote} +\setinterfacevariable{lines}{lines} +\setinterfacevariable{list}{list} +\setinterfacevariable{local}{local} +\setinterfacevariable{localenvironment}{localenvironment} +\setinterfacevariable{logo}{logo} +\setinterfacevariable{logos}{logos} +\setinterfacevariable{lohi}{lohi} +\setinterfacevariable{loose}{loose} +\setinterfacevariable{low}{low} +\setinterfacevariable{ls}{ls} +\setinterfacevariable{makeup}{makeup} +\setinterfacevariable{mar}{mar} +\setinterfacevariable{march}{March} +\setinterfacevariable{margin}{margin} +\setinterfacevariable{marginedge}{marginedge} +\setinterfacevariable{margintitle}{margintitle} +\setinterfacevariable{marking}{marking} +\setinterfacevariable{mathalignment}{mathalignment} +\setinterfacevariable{mathcases}{mathcases} +\setinterfacevariable{mathmatrix}{mathmatrix} +\setinterfacevariable{max}{max} +\setinterfacevariable{maxdepth}{maxdepth} +\setinterfacevariable{maxheight}{maxheight} +\setinterfacevariable{maxwidth}{maxwidth} +\setinterfacevariable{may}{May} +\setinterfacevariable{mediaeval}{mediaeval} +\setinterfacevariable{medium}{medium} +\setinterfacevariable{middle}{middle} +\setinterfacevariable{min}{min} +\setinterfacevariable{mindepth}{mindepth} +\setinterfacevariable{minheight}{minheight} +\setinterfacevariable{minwidth}{minwidth} +\setinterfacevariable{mirrored}{mirrored} +\setinterfacevariable{monday}{monday} +\setinterfacevariable{mono}{mono} +\setinterfacevariable{month}{month} +\setinterfacevariable{morehyphenation}{morehyphenation} +\setinterfacevariable{name}{name} +\setinterfacevariable{narrow}{narrow} +\setinterfacevariable{negative}{negative} +\setinterfacevariable{never}{never} +\setinterfacevariable{new}{new} +\setinterfacevariable{next}{next} +\setinterfacevariable{nextevenpage}{nextevenpage} +\setinterfacevariable{nextoddpage}{nextoddpage} +\setinterfacevariable{nextpage}{nextpage} +\setinterfacevariable{nextsubpage}{nextsubpage} +\setinterfacevariable{no}{no} +\setinterfacevariable{nocheck}{nocheck} +\setinterfacevariable{nofit}{nofit} +\setinterfacevariable{nogrid}{nogrid} +\setinterfacevariable{nohz}{nohz} +\setinterfacevariable{nomarking}{nomarking} +\setinterfacevariable{none}{none} +\setinterfacevariable{nonumber}{nonumber} +\setinterfacevariable{normal}{normal} +\setinterfacevariable{nospacing}{nospacing} +\setinterfacevariable{not}{not} +\setinterfacevariable{note}{note} +\setinterfacevariable{nothanging}{nothanging} +\setinterfacevariable{nothyphenated}{nothyphenated} +\setinterfacevariable{november}{November} +\setinterfacevariable{nowhere}{nowhere} +\setinterfacevariable{nowhite}{nowhite} +\setinterfacevariable{number}{number} +\setinterfacevariable{numbers}{numbers} +\setinterfacevariable{october}{October} +\setinterfacevariable{odd}{odd} +\setinterfacevariable{off}{off} +\setinterfacevariable{offset}{offset} +\setinterfacevariable{old}{old} +\setinterfacevariable{on}{on} +\setinterfacevariable{one}{one} +\setinterfacevariable{opposite}{opposite} +\setinterfacevariable{outer}{outer} +\setinterfacevariable{outeredge}{outeredge} +\setinterfacevariable{outermargin}{outermargin} +\setinterfacevariable{overbar}{overbar} +\setinterfacevariable{overbars}{overbars} +\setinterfacevariable{overlay}{overlay} +\setinterfacevariable{overprint}{overprint} +\setinterfacevariable{overstrike}{overstrike} +\setinterfacevariable{overstrikes}{overstrikes} +\setinterfacevariable{packed}{packed} +\setinterfacevariable{page}{page} +\setinterfacevariable{pagecomment}{pagecomment} +\setinterfacevariable{pagenumber}{pagenumber} +\setinterfacevariable{paper}{paper} +\setinterfacevariable{paragraph}{paragraph} +\setinterfacevariable{part}{part} +\setinterfacevariable{positive}{positive} +\setinterfacevariable{postponing}{postponing} +\setinterfacevariable{postscript}{postscript} +\setinterfacevariable{preference}{preference} +\setinterfacevariable{preview}{preview} +\setinterfacevariable{previous}{previous} +\setinterfacevariable{previousevenpage}{previousevenpage} +\setinterfacevariable{previousoddpage}{previousoddpage} +\setinterfacevariable{previouspage}{previouspage} +\setinterfacevariable{previoussubpage}{previoussubpage} +\setinterfacevariable{printable}{printable} +\setinterfacevariable{process}{process} +\setinterfacevariable{product}{product} +\setinterfacevariable{program}{program} +\setinterfacevariable{project}{project} +\setinterfacevariable{protected}{protected} +\setinterfacevariable{quadruple}{quadruple} +\setinterfacevariable{quotation}{quotation} +\setinterfacevariable{quote}{quote} +\setinterfacevariable{ran}{ran} +\setinterfacevariable{random}{random} +\setinterfacevariable{readonly}{readonly} +\setinterfacevariable{rectangular}{rectangular} +\setinterfacevariable{referral}{referral} +\setinterfacevariable{register}{register} +\setinterfacevariable{regular}{regular} +\setinterfacevariable{rekening}{rekening} +\setinterfacevariable{relative}{relative} +\setinterfacevariable{repeat}{repeat} +\setinterfacevariable{required}{required} +\setinterfacevariable{reset}{reset} +\setinterfacevariable{reverse}{reverse} +\setinterfacevariable{right}{right} +\setinterfacevariable{rightedge}{rightedge} +\setinterfacevariable{righthanging}{righthanging} +\setinterfacevariable{rightmargin}{rightmargin} +\setinterfacevariable{rightpage}{rightpage} +\setinterfacevariable{righttoleft}{righttoleft} +\setinterfacevariable{roman}{roman} +\setinterfacevariable{romannumerals}{romannumerals} +\setinterfacevariable{rotate}{rotate} +\setinterfacevariable{rotated}{rotated} +\setinterfacevariable{round}{round} +\setinterfacevariable{row}{row} +\setinterfacevariable{rule}{rule} +\setinterfacevariable{samepage}{samepage} +\setinterfacevariable{sans}{sans} +\setinterfacevariable{sansbold}{sansbold} +\setinterfacevariable{sansserif}{sansserif} +\setinterfacevariable{saturday}{saturday} +\setinterfacevariable{screen}{screen} +\setinterfacevariable{section}{section} +\setinterfacevariable{sectionblockenvironment}{sectionblockenvironment} +\setinterfacevariable{sectionnumber}{sectionnumber} +\setinterfacevariable{see}{see} +\setinterfacevariable{september}{September} +\setinterfacevariable{serif}{serif} +\setinterfacevariable{serried}{serried} +\setinterfacevariable{setups}{setups} +\setinterfacevariable{sheet}{sheet} +\setinterfacevariable{short}{short} +\setinterfacevariable{singlesided}{singlesided} +\setinterfacevariable{slanted}{slanted} +\setinterfacevariable{slantedbold}{slantedbold} +\setinterfacevariable{small}{small} +\setinterfacevariable{smallbodyfont}{smallbodyfont} +\setinterfacevariable{smallbold}{smallbold} +\setinterfacevariable{smallbolditalic}{smallbolditalic} +\setinterfacevariable{smallboldslanted}{smallboldslanted} +\setinterfacevariable{smallcaps}{smallcaps} +\setinterfacevariable{smallitalic}{smallitalic} +\setinterfacevariable{smallitalicbold}{smallitalicbold} +\setinterfacevariable{smallnormal}{smallnormal} +\setinterfacevariable{smallslanted}{smallslanted} +\setinterfacevariable{smallslantedbold}{smallslantedbold} +\setinterfacevariable{smalltype}{smalltype} +\setinterfacevariable{somewhere}{somewhere} +\setinterfacevariable{sorted}{sorted} +\setinterfacevariable{space}{space} +\setinterfacevariable{spacing}{spacing} +\setinterfacevariable{speech}{speech} +\setinterfacevariable{split}{split} +\setinterfacevariable{spot}{spot} +\setinterfacevariable{standard}{standard} +\setinterfacevariable{start}{start} +\setinterfacevariable{starter}{starter} +\setinterfacevariable{sticker}{sticker} +\setinterfacevariable{stop}{stop} +\setinterfacevariable{stopper}{stopper} +\setinterfacevariable{stretch}{stretch} +\setinterfacevariable{strict}{strict} +\setinterfacevariable{strong}{strong} +\setinterfacevariable{strut}{strut} +\setinterfacevariable{sub}{sub} +\setinterfacevariable{subbackward}{subbackward} +\setinterfacevariable{subformula}{subformula} +\setinterfacevariable{subforward}{subforward} +\setinterfacevariable{subject}{subject} +\setinterfacevariable{subpage}{subpage} +\setinterfacevariable{subsection}{subsection} +\setinterfacevariable{subsubject}{subsubject} +\setinterfacevariable{subsubsection}{subsubsection} +\setinterfacevariable{subsubsubject}{subsubsubject} +\setinterfacevariable{subsubsubsection}{subsubsubsection} +\setinterfacevariable{subsubsubsubject}{subsubsubsubject} +\setinterfacevariable{subsubsubsubsection}{subsubsubsubsection} +\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} +\setinterfacevariable{symbol}{symbol} +\setinterfacevariable{synchronize}{synchronize} +\setinterfacevariable{system}{system} +\setinterfacevariable{table}{table} +\setinterfacevariable{tablehead}{tablehead} +\setinterfacevariable{tables}{tables} +\setinterfacevariable{tabletail}{tabletail} +\setinterfacevariable{tabulate}{tabulate} +\setinterfacevariable{tabulatehead}{tabulatehead} +\setinterfacevariable{tabulatetail}{tabulatetail} +\setinterfacevariable{tall}{tall} +\setinterfacevariable{teletype}{teletype} +\setinterfacevariable{temporary}{temporary} +\setinterfacevariable{test}{test} +\setinterfacevariable{text}{text} +\setinterfacevariable{three}{three} +\setinterfacevariable{thursday}{thursday} +\setinterfacevariable{title}{title} +\setinterfacevariable{toggle}{wissel} +\setinterfacevariable{tolerant}{tolerant} +\setinterfacevariable{top}{top} +\setinterfacevariable{tuesday}{tuesday} +\setinterfacevariable{two}{two} +\setinterfacevariable{txt}{txt} +\setinterfacevariable{type}{type} +\setinterfacevariable{typing}{typing} +\setinterfacevariable{unavailable}{unavailable} +\setinterfacevariable{underbar}{underbar} +\setinterfacevariable{underbars}{underbars} +\setinterfacevariable{unit}{unit} +\setinterfacevariable{units}{units} +\setinterfacevariable{unknown}{unknown} +\setinterfacevariable{unpacked}{unpacked} +\setinterfacevariable{up}{up} +\setinterfacevariable{url}{url} +\setinterfacevariable{used}{used} +\setinterfacevariable{value}{value} +\setinterfacevariable{vertical}{vertical} +\setinterfacevariable{very}{very} +\setinterfacevariable{verystrict}{verystrict} +\setinterfacevariable{verytolerant}{verytolerant} +\setinterfacevariable{weak}{weak} +\setinterfacevariable{wednesday}{wednesday} +\setinterfacevariable{week}{week} +\setinterfacevariable{weekday}{weekday} +\setinterfacevariable{white}{white} +\setinterfacevariable{wide}{wide} +\setinterfacevariable{width}{width} +\setinterfacevariable{xml}{xml} +\setinterfacevariable{year}{year} +\setinterfacevariable{yes}{yes} +% definitions for interface constants for language en +% +\setinterfaceconstant{action}{action} +\setinterfaceconstant{address}{address} +\setinterfaceconstant{after}{after} +\setinterfaceconstant{afterhead}{afterhead} +\setinterfaceconstant{afterkey}{afterkey} +\setinterfaceconstant{align}{align} +\setinterfaceconstant{aligncharacter}{aligncharacter} +\setinterfaceconstant{alignmentcharacter}{alignmentcharacter} +\setinterfaceconstant{alignsymbol}{alignsymbol} +\setinterfaceconstant{aligntitle}{aligntitle} +\setinterfaceconstant{alternative}{alternative} +\setinterfaceconstant{andtext}{andtext} +\setinterfaceconstant{apa}{apa} +\setinterfaceconstant{arrow}{arrow} +\setinterfaceconstant{artauthor}{artauthor} +\setinterfaceconstant{artauthoretaldisplay}{artauthoretaldisplay} +\setinterfaceconstant{artauthoretallimit}{artauthoretallimit} +\setinterfaceconstant{artauthoretaltext}{artauthoretaltext} +\setinterfaceconstant{at}{at} +\setinterfaceconstant{author}{author} +\setinterfaceconstant{authoretaldisplay}{authoretaldisplay} +\setinterfaceconstant{authoretallimit}{authoretallimit} +\setinterfaceconstant{authoretaltext}{authoretaltext} +\setinterfaceconstant{auto}{auto} +\setinterfaceconstant{autofile}{autofile} +\setinterfaceconstant{autofocus}{autofocus} +\setinterfaceconstant{autohang}{autohang} +\setinterfaceconstant{autostrut}{autostrut} +\setinterfaceconstant{autowidth}{autowidth} +\setinterfaceconstant{axis}{axis} +\setinterfaceconstant{background}{background} +\setinterfaceconstant{backgroundcolor}{backgroundcolor} +\setinterfaceconstant{backgroundcorner}{backgroundcorner} +\setinterfaceconstant{backgrounddepth}{backgrounddepth} +\setinterfaceconstant{backgroundoffset}{backgroundoffset} +\setinterfaceconstant{backgroundradius}{backgroundradius} +\setinterfaceconstant{backgroundscreen}{backgroundscreen} +\setinterfaceconstant{backspace}{backspace} +\setinterfaceconstant{balance}{balance} +\setinterfaceconstant{before}{before} +\setinterfaceconstant{beforehead}{beforehead} +\setinterfaceconstant{bet}{bet} +\setinterfaceconstant{big}{big} +\setinterfaceconstant{blank}{blank} +\setinterfaceconstant{blockway}{blockway} +\setinterfaceconstant{bodyfont}{bodyfont} +\setinterfaceconstant{bookmark}{bookmark} +\setinterfaceconstant{bottom}{bottom} +\setinterfaceconstant{bottomafter}{bottomafter} +\setinterfaceconstant{bottombefore}{bottombefore} +\setinterfaceconstant{bottomdistance}{bottomdistance} +\setinterfaceconstant{bottomframe}{bottomframe} +\setinterfaceconstant{bottomoffset}{bottomoffset} +\setinterfaceconstant{bottomspace}{bottomspace} +\setinterfaceconstant{bottomstate}{bottomstate} +\setinterfaceconstant{cache}{cache} +\setinterfaceconstant{calculate}{calculate} +\setinterfaceconstant{ccommand}{ccommand} +\setinterfaceconstant{click}{click} +\setinterfaceconstant{clickin}{clickin} +\setinterfaceconstant{clickout}{clickout} +\setinterfaceconstant{clipoffset}{clipoffset} +\setinterfaceconstant{closeaction}{closeaction} +\setinterfaceconstant{closecommand}{closecommand} +\setinterfaceconstant{closepageaction}{closepageaction} +\setinterfaceconstant{closesymbol}{closesymbol} +\setinterfaceconstant{color}{color} +\setinterfaceconstant{column}{column} +\setinterfaceconstant{columndistance}{columndistance} +\setinterfaceconstant{columns}{columns} +\setinterfaceconstant{command}{command} +\setinterfaceconstant{commandafter}{commandafter} +\setinterfaceconstant{commandbefore}{commandbefore} +\setinterfaceconstant{commands}{commands} +\setinterfaceconstant{component}{component} +\setinterfaceconstant{compoundhyphen}{compoundhyphen} +\setinterfaceconstant{compress}{compress} +\setinterfaceconstant{connector}{connector} +\setinterfaceconstant{continue}{continue} +\setinterfaceconstant{contrastcolor}{contrastcolor} +\setinterfaceconstant{controls}{controls} +\setinterfaceconstant{conversion}{conversion} +\setinterfaceconstant{convertfile}{convertfile} +\setinterfaceconstant{corner}{corner} +\setinterfaceconstant{coupling}{coupling} +\setinterfaceconstant{couplingway}{couplingway} +\setinterfaceconstant{criterium}{criterium} +\setinterfaceconstant{current}{current} +\setinterfaceconstant{cutspace}{cutspace} +\setinterfaceconstant{dash}{dash} +\setinterfaceconstant{dat}{dat} +\setinterfaceconstant{database}{database} +\setinterfaceconstant{date}{date} +\setinterfaceconstant{deepnumbercommand}{deepnumbercommand} +\setinterfaceconstant{deeptextcommand}{deeptextcommand} +\setinterfaceconstant{default}{default} +\setinterfaceconstant{delay}{delay} +\setinterfaceconstant{depth}{depth} +\setinterfaceconstant{depthcorrection}{depthcorrection} +\setinterfaceconstant{direction}{direction} +\setinterfaceconstant{directory}{directory} +\setinterfaceconstant{display}{display} +\setinterfaceconstant{distance}{distance} +\setinterfaceconstant{dot}{dot} +\setinterfaceconstant{doublesided}{doublesided} +\setinterfaceconstant{dummy}{dummy} +\setinterfaceconstant{dx}{dx} +\setinterfaceconstant{dy}{dy} +\setinterfaceconstant{edge}{edge} +\setinterfaceconstant{edgedistance}{edgedistance} +\setinterfaceconstant{editor}{editor} +\setinterfaceconstant{editoretaldisplay}{editoretaldisplay} +\setinterfaceconstant{editoretallimit}{editoretallimit} +\setinterfaceconstant{editoretaltext}{editoretaltext} +\setinterfaceconstant{empty}{empty} +\setinterfaceconstant{equalheight}{equalheight} +\setinterfaceconstant{equalwidth}{equalwidth} +\setinterfaceconstant{escape}{escape} +\setinterfaceconstant{evenmargin}{evenmargin} +\setinterfaceconstant{expansion}{expansion} +\setinterfaceconstant{export}{export} +\setinterfaceconstant{extras}{extras} +\setinterfaceconstant{factor}{factor} +\setinterfaceconstant{fallback}{fallback} +\setinterfaceconstant{family}{family} +\setinterfaceconstant{fieldbackgroundcolor}{fieldbackgroundcolor} +\setinterfaceconstant{fieldframecolor}{fieldframecolor} +\setinterfaceconstant{fieldlayer}{fieldlayer} +\setinterfaceconstant{fieldoffset}{fieldoffset} +\setinterfaceconstant{file}{file} +\setinterfaceconstant{filtercommand}{filtercommand} +\setinterfaceconstant{finalnamesep}{finalnamesep} +\setinterfaceconstant{firstnamesep}{firstnamesep} +\setinterfaceconstant{focus}{focus} +\setinterfaceconstant{focusin}{focusin} +\setinterfaceconstant{focusout}{focusout} +\setinterfaceconstant{footer}{footer} +\setinterfaceconstant{footerdistance}{footerdistance} +\setinterfaceconstant{footerstate}{footerstate} +\setinterfaceconstant{foregroundcolor}{foregroundcolor} +\setinterfaceconstant{foregroundstyle}{foregroundstyle} +\setinterfaceconstant{format}{format} +\setinterfaceconstant{frame}{frame} +\setinterfaceconstant{framecolor}{framecolor} +\setinterfaceconstant{framecorner}{framecorner} +\setinterfaceconstant{framedepth}{framedepth} +\setinterfaceconstant{frameoffset}{frameoffset} +\setinterfaceconstant{frameradius}{frameradius} +\setinterfaceconstant{frames}{frames} +\setinterfaceconstant{from}{from} +\setinterfaceconstant{get}{get} +\setinterfaceconstant{global}{global} +\setinterfaceconstant{grid}{grid} +\setinterfaceconstant{hang}{hang} +\setinterfaceconstant{headalign}{headalign} +\setinterfaceconstant{headcolor}{headcolor} +\setinterfaceconstant{headcommand}{headcommand} +\setinterfaceconstant{headconversion}{headconversion} +\setinterfaceconstant{header}{header} +\setinterfaceconstant{headerdistance}{headerdistance} +\setinterfaceconstant{headerstate}{headerstate} +\setinterfaceconstant{headlabel}{headlabel} +\setinterfaceconstant{headnumber}{headnumber} +\setinterfaceconstant{headstyle}{headstyle} +\setinterfaceconstant{height}{height} +\setinterfaceconstant{hfactor}{hfactor} +\setinterfaceconstant{hfil}{hfil} +\setinterfaceconstant{hidenumber}{hidenumber} +\setinterfaceconstant{hoffset}{hoffset} +\setinterfaceconstant{horoffset}{horoffset} +\setinterfaceconstant{hyphen}{hyphen} +\setinterfaceconstant{icommand}{icommand} +\setinterfaceconstant{in}{in} +\setinterfaceconstant{inbetween}{inbetween} +\setinterfaceconstant{increment}{increment} +\setinterfaceconstant{incrementnumber}{incrementnumber} +\setinterfaceconstant{indenting}{indenting} +\setinterfaceconstant{indentnext}{indentnext} +\setinterfaceconstant{indicator}{indicator} +\setinterfaceconstant{inner}{inner} +\setinterfaceconstant{innermargin}{innermargin} +\setinterfaceconstant{inputfile}{inputfile} +\setinterfaceconstant{intent}{intent} +\setinterfaceconstant{interaction}{interaction} +\setinterfaceconstant{interlinespace}{interlinespace} +\setinterfaceconstant{itemalign}{itemalign} +\setinterfaceconstant{items}{items} +\setinterfaceconstant{juniorsep}{juniorsep} +\setinterfaceconstant{ken}{ken} +\setinterfaceconstant{keyexpansion}{keyexpansion} +\setinterfaceconstant{keyword}{keyword} +\setinterfaceconstant{label}{label} +\setinterfaceconstant{lastnamesep}{lastnamesep} +\setinterfaceconstant{lastpubsep}{lastpubsep} +\setinterfaceconstant{left}{left} +\setinterfaceconstant{leftcolor}{leftcolor} +\setinterfaceconstant{leftcompoundhyphen}{leftcompoundhyphen} +\setinterfaceconstant{leftedge}{leftedge} +\setinterfaceconstant{leftedgedistance}{leftedgedistance} +\setinterfaceconstant{leftframe}{leftframe} +\setinterfaceconstant{lefthyphen}{lefthyphen} +\setinterfaceconstant{leftmargin}{leftmargin} +\setinterfaceconstant{leftmargindistance}{leftmargindistance} +\setinterfaceconstant{leftoffset}{leftoffset} +\setinterfaceconstant{leftquotation}{leftquotation} +\setinterfaceconstant{leftquote}{leftquote} +\setinterfaceconstant{leftsentence}{leftsentence} +\setinterfaceconstant{leftspeech}{leftspeech} +\setinterfaceconstant{leftstyle}{leftstyle} +\setinterfaceconstant{leftsubsentence}{leftsubsentence} +\setinterfaceconstant{lefttext}{lefttext} +\setinterfaceconstant{leftwidth}{leftwidth} +\setinterfaceconstant{level}{level} +\setinterfaceconstant{levels}{levels} +\setinterfaceconstant{limittext}{limittext} +\setinterfaceconstant{line}{line} +\setinterfaceconstant{linecorrection}{linecorrection} +\setinterfaceconstant{lines}{lines} +\setinterfaceconstant{list}{list} +\setinterfaceconstant{listtext}{listtext} +\setinterfaceconstant{local}{local} +\setinterfaceconstant{location}{location} +\setinterfaceconstant{logo}{logo} +\setinterfaceconstant{logos}{logos} +\setinterfaceconstant{marcolor}{marcolor} +\setinterfaceconstant{margin}{margin} +\setinterfaceconstant{margindistance}{margindistance} +\setinterfaceconstant{marginedge}{marginedge} +\setinterfaceconstant{marginedgetext}{marginedgetext} +\setinterfaceconstant{margintext}{margintext} +\setinterfaceconstant{marking}{marking} +\setinterfaceconstant{marstyle}{marstyle} +\setinterfaceconstant{max}{max} +\setinterfaceconstant{maxdepth}{maxdepth} +\setinterfaceconstant{maxheight}{maxheight} +\setinterfaceconstant{maxwidth}{maxwidth} +\setinterfaceconstant{maybeyear}{maybeyear} +\setinterfaceconstant{menu}{menu} +\setinterfaceconstant{method}{method} +\setinterfaceconstant{middle}{middle} +\setinterfaceconstant{middlespeech}{middlespeech} +\setinterfaceconstant{middletext}{middletext} +\setinterfaceconstant{midsentence}{midsentence} +\setinterfaceconstant{min}{min} +\setinterfaceconstant{mindepth}{mindepth} +\setinterfaceconstant{minheight}{minheight} +\setinterfaceconstant{minwidth}{minwidth} +\setinterfaceconstant{monthconversion}{monthconversion} +\setinterfaceconstant{n}{n} +\setinterfaceconstant{name}{name} +\setinterfaceconstant{namesep}{namesep} +\setinterfaceconstant{nbottom}{nbottom} +\setinterfaceconstant{nc}{nc} +\setinterfaceconstant{next}{next} +\setinterfaceconstant{nl}{nl} +\setinterfaceconstant{nleft}{nleft} +\setinterfaceconstant{nlines}{nlines} +\setinterfaceconstant{norm}{norm} +\setinterfaceconstant{nr}{nr} +\setinterfaceconstant{nright}{nright} +\setinterfaceconstant{ntop}{ntop} +\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{numberstarter}{numberstarter} +\setinterfaceconstant{numberstopper}{numberstopper} +\setinterfaceconstant{numberstyle}{numberstyle} +\setinterfaceconstant{numberwidth}{numberwidth} +\setinterfaceconstant{nx}{nx} +\setinterfaceconstant{ny}{ny} +\setinterfaceconstant{object}{object} +\setinterfaceconstant{obstruction}{obstruction} +\setinterfaceconstant{oddmargin}{oddmargin} +\setinterfaceconstant{offset}{offset} +\setinterfaceconstant{openaction}{openaction} +\setinterfaceconstant{openpageaction}{openpageaction} +\setinterfaceconstant{option}{option} +\setinterfaceconstant{order}{order} +\setinterfaceconstant{orientation}{orientation} +\setinterfaceconstant{otherstext}{otherstext} +\setinterfaceconstant{outermargin}{outermargin} +\setinterfaceconstant{overprint}{overprint} +\setinterfaceconstant{ownnumber}{ownnumber} +\setinterfaceconstant{page}{page} +\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{pageprefixstarter}{pageprefixstarter} +\setinterfaceconstant{pageprefixstopper}{pageprefixstopper} +\setinterfaceconstant{pagesegments}{pagesegments} +\setinterfaceconstant{pageseparatorset}{pageseparatorset} +\setinterfaceconstant{pageset}{pageset} +\setinterfaceconstant{pagestarter}{pagestarter} +\setinterfaceconstant{pagestate}{pagestate} +\setinterfaceconstant{pagestopper}{pagestopper} +\setinterfaceconstant{pagestyle}{pagestyle} +\setinterfaceconstant{palet}{palet} +\setinterfaceconstant{paper}{paper} +\setinterfaceconstant{paragraph}{paragraph} +\setinterfaceconstant{place}{place} +\setinterfaceconstant{placehead}{placehead} +\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{prefixstarter}{prefixstarter} +\setinterfaceconstant{prefixstopper}{prefixstopper} +\setinterfaceconstant{preset}{preset} +\setinterfaceconstant{preview}{preview} +\setinterfaceconstant{previous}{previous} +\setinterfaceconstant{previousnumber}{previousnumber} +\setinterfaceconstant{process}{process} +\setinterfaceconstant{pubsep}{pubsep} +\setinterfaceconstant{radius}{radius} +\setinterfaceconstant{random}{random} +\setinterfaceconstant{range}{range} +\setinterfaceconstant{reduction}{reduction} +\setinterfaceconstant{ref}{ref} +\setinterfaceconstant{refcommand}{refcommand} +\setinterfaceconstant{reference}{reference} +\setinterfaceconstant{referenceprefix}{referenceprefix} +\setinterfaceconstant{referencing}{referencing} +\setinterfaceconstant{regionin}{regionin} +\setinterfaceconstant{regionout}{regionout} +\setinterfaceconstant{repeat}{repeat} +\setinterfaceconstant{reset}{reset} +\setinterfaceconstant{resetnumber}{resetnumber} +\setinterfaceconstant{resolution}{resolution} +\setinterfaceconstant{right}{right} +\setinterfaceconstant{rightcolor}{rightcolor} +\setinterfaceconstant{rightcompoundhyphen}{rightcompoundhyphen} +\setinterfaceconstant{rightedge}{rightedge} +\setinterfaceconstant{rightedgedistance}{rightedgedistance} +\setinterfaceconstant{rightframe}{rightframe} +\setinterfaceconstant{righthyphen}{righthyphen} +\setinterfaceconstant{rightmargin}{rightmargin} +\setinterfaceconstant{rightmargindistance}{rightmargindistance} +\setinterfaceconstant{rightoffset}{rightoffset} +\setinterfaceconstant{rightquotation}{rightquotation} +\setinterfaceconstant{rightquote}{rightquote} +\setinterfaceconstant{rightsentence}{rightsentence} +\setinterfaceconstant{rightspeech}{rightspeech} +\setinterfaceconstant{rightstyle}{rightstyle} +\setinterfaceconstant{rightsubsentence}{rightsubsentence} +\setinterfaceconstant{righttext}{righttext} +\setinterfaceconstant{rightwidth}{rightwidth} +\setinterfaceconstant{rotation}{rotation} +\setinterfaceconstant{rule}{rule} +\setinterfaceconstant{rulecolor}{rulecolor} +\setinterfaceconstant{rulethickness}{rulethickness} +\setinterfaceconstant{samepage}{samepage} +\setinterfaceconstant{sample}{sample} +\setinterfaceconstant{samplesize}{samplesize} +\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{sectionresetset}{sectionresetset} +\setinterfaceconstant{sectionsegments}{sectionsegments} +\setinterfaceconstant{sectionseparatorset}{sectionseparatorset} +\setinterfaceconstant{sectionset}{sectionset} +\setinterfaceconstant{sectionstarter}{sectionstarter} +\setinterfaceconstant{sectionstopper}{sectionstopper} +\setinterfaceconstant{separator}{separator} +\setinterfaceconstant{set}{set} +\setinterfaceconstant{setups}{setups} +\setinterfaceconstant{side}{side} +\setinterfaceconstant{sidealign}{sidealign} +\setinterfaceconstant{sidemethod}{sidemethod} +\setinterfaceconstant{sidespaceafter}{sidespaceafter} +\setinterfaceconstant{sidespacebefore}{sidespacebefore} +\setinterfaceconstant{sign}{sign} +\setinterfaceconstant{size}{size} +\setinterfaceconstant{small}{small} +\setinterfaceconstant{sort}{sort} +\setinterfaceconstant{sorttype}{sorttype} +\setinterfaceconstant{source}{source} +\setinterfaceconstant{space}{space} +\setinterfaceconstant{spaceafter}{spaceafter} +\setinterfaceconstant{spacebefore}{spacebefore} +\setinterfaceconstant{spaceinbetween}{spaceinbetween} +\setinterfaceconstant{spacing}{spacing} +\setinterfaceconstant{split}{split} +\setinterfaceconstant{splitcolor}{splitcolor} +\setinterfaceconstant{splitmethod}{splitmethod} +\setinterfaceconstant{splitoffset}{splitoffset} +\setinterfaceconstant{spot}{spot} +\setinterfaceconstant{stack}{stack} +\setinterfaceconstant{start}{start} +\setinterfaceconstant{starter}{starter} +\setinterfaceconstant{state}{state} +\setinterfaceconstant{step}{step} +\setinterfaceconstant{stop}{stop} +\setinterfaceconstant{stopper}{stopper} +\setinterfaceconstant{stretch}{stretch} +\setinterfaceconstant{strip}{strip} +\setinterfaceconstant{strut}{strut} +\setinterfaceconstant{style}{style} +\setinterfaceconstant{sub}{sub} +\setinterfaceconstant{subtitle}{subtitle} +\setinterfaceconstant{suffix}{suffix} +\setinterfaceconstant{surnamesep}{surnamesep} +\setinterfaceconstant{sx}{sx} +\setinterfaceconstant{sy}{sy} +\setinterfaceconstant{symalign}{symalign} +\setinterfaceconstant{symbol}{symbol} +\setinterfaceconstant{symbolset}{symbolset} +\setinterfaceconstant{symcolor}{symcolor} +\setinterfaceconstant{symstyle}{symstyle} +\setinterfaceconstant{synonym}{synonym} +\setinterfaceconstant{synonymcolor}{synonymcolor} +\setinterfaceconstant{synonymcommand}{synonymcommand} +\setinterfaceconstant{synonymstyle}{synonymstyle} +\setinterfaceconstant{tab}{tab} +\setinterfaceconstant{text}{text} +\setinterfaceconstant{textcolor}{textcolor} +\setinterfaceconstant{textcommand}{textcommand} +\setinterfaceconstant{textdistance}{textdistance} +\setinterfaceconstant{textlayer}{textlayer} +\setinterfaceconstant{textmargin}{textmargin} +\setinterfaceconstant{textmethod}{textmethod} +\setinterfaceconstant{textseparator}{textseparator} +\setinterfaceconstant{textsize}{textsize} +\setinterfaceconstant{textstate}{textstate} +\setinterfaceconstant{textstyle}{textstyle} +\setinterfaceconstant{textwidth}{textwidth} +\setinterfaceconstant{title}{title} +\setinterfaceconstant{titlecolor}{titlecolor} +\setinterfaceconstant{titlecommand}{titlecommand} +\setinterfaceconstant{titledistance}{titledistance} +\setinterfaceconstant{titleleft}{titleleft} +\setinterfaceconstant{titleright}{titleright} +\setinterfaceconstant{titlestyle}{titlestyle} +\setinterfaceconstant{to}{to} +\setinterfaceconstant{tolerance}{tolerance} +\setinterfaceconstant{top}{top} +\setinterfaceconstant{topdistance}{topdistance} +\setinterfaceconstant{topframe}{topframe} +\setinterfaceconstant{topoffset}{topoffset} +\setinterfaceconstant{topspace}{topspace} +\setinterfaceconstant{topstate}{topstate} +\setinterfaceconstant{totalnumber}{totalnumber} +\setinterfaceconstant{type}{type} +\setinterfaceconstant{unit}{unit} +\setinterfaceconstant{unknownreference}{unknownreference} +\setinterfaceconstant{urlalternative}{urlalternative} +\setinterfaceconstant{urlspace}{urlspace} +\setinterfaceconstant{validate}{validate} +\setinterfaceconstant{vcommand}{vcommand} +\setinterfaceconstant{veroffset}{veroffset} +\setinterfaceconstant{vfil}{vfil} +\setinterfaceconstant{voffset}{voffset} +\setinterfaceconstant{vonsep}{vonsep} +\setinterfaceconstant{way}{way} +\setinterfaceconstant{wfactor}{wfactor} +\setinterfaceconstant{white}{white} +\setinterfaceconstant{width}{width} +\setinterfaceconstant{xfactor}{xfactor} +\setinterfaceconstant{xmax}{xmax} +\setinterfaceconstant{xoffset}{xoffset} +\setinterfaceconstant{xscale}{xscale} +\setinterfaceconstant{xstep}{xstep} +\setinterfaceconstant{yfactor}{yfactor} +\setinterfaceconstant{ymax}{ymax} +\setinterfaceconstant{yoffset}{yoffset} +\setinterfaceconstant{yscale}{yscale} +\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} +\setinterfaceelement{currentlocal}{currentlocal} +\setinterfaceelement{emptyone}{empty} +\setinterfaceelement{emptytwo}{empty} +\setinterfaceelement{end}{end} +\setinterfaceelement{endsetup}{} +\setinterfaceelement{get}{get} +\setinterfaceelement{increment}{increment} +\setinterfaceelement{list}{list} +\setinterfaceelement{listof}{listof} +\setinterfaceelement{load}{load} +\setinterfaceelement{local}{local} +\setinterfaceelement{makeup}{makeup} +\setinterfaceelement{next}{next} +\setinterfaceelement{place}{place} +\setinterfaceelement{previous}{previous} +\setinterfaceelement{previouslocal}{previouslocal} +\setinterfaceelement{reserve}{reserve} +\setinterfaceelement{see}{see} +\setinterfaceelement{setup}{setup} +\setinterfaceelement{start}{start} +\setinterfaceelement{stop}{stop} +\setinterfaceelement{text}{text} +\setinterfaceelement{type}{type} +% definitions for interface commands for language en +% +\setinterfacecommand{CAPPED}{CAP} +\setinterfacecommand{Character}{Character} +\setinterfacecommand{Characters}{Characters} +\setinterfacecommand{LABELTEXT}{LABELTEXT} +\setinterfacecommand{MONTH}{MONTH} +\setinterfacecommand{Numbers}{Numbers} +\setinterfacecommand{Romannumerals}{Romannumerals} +\setinterfacecommand{SmallCapped}{Cap} +\setinterfacecommand{SmallCaps}{Caps} +\setinterfacecommand{WEEKDAY}{WEEKDAY} +\setinterfacecommand{WORD}{WORD} +\setinterfacecommand{WORDS}{WORDS} +\setinterfacecommand{Word}{Word} +\setinterfacecommand{Words}{Words} +\setinterfacecommand{about}{about} +\setinterfacecommand{adaptlayout}{adaptlayout} +\setinterfacecommand{arg}{arg} +\setinterfacecommand{at}{at} +\setinterfacecommand{atleftmargin}{atleftmargin} +\setinterfacecommand{atpage}{atpage} +\setinterfacecommand{atrightmargin}{atrightmargin} +\setinterfacecommand{background}{background} +\setinterfacecommand{backspace}{backspace} +\setinterfacecommand{blackrule}{blackrule} +\setinterfacecommand{blackrules}{blackrules} +\setinterfacecommand{blank}{blank} +\setinterfacecommand{bookmark}{bookmark} +\setinterfacecommand{bottomdistance}{bottomdistance} +\setinterfacecommand{bottomheight}{bottomheight} +\setinterfacecommand{bottomspace}{bottomspace} +\setinterfacecommand{but}{but} +\setinterfacecommand{button}{button} +\setinterfacecommand{bypassblocks}{bypassblocks} +\setinterfacecommand{character}{character} +\setinterfacecommand{characters}{characters} +\setinterfacecommand{chem}{chem} +\setinterfacecommand{clip}{clip} +\setinterfacecommand{clonefield}{clonefield} +\setinterfacecommand{color}{color} +\setinterfacecommand{colorbar}{colorbar} +\setinterfacecommand{colorvalue}{colorvalue} +\setinterfacecommand{column}{column} +\setinterfacecommand{comment}{comment} +\setinterfacecommand{comparecolorgroup}{comparecolorgroup} +\setinterfacecommand{comparepalet}{comparepalet} +\setinterfacecommand{completepagenumber}{completepagenumber} +\setinterfacecommand{completeregister}{completeregister} +\setinterfacecommand{component}{component} +\setinterfacecommand{convertnumber}{convertnumber} +\setinterfacecommand{copyfield}{copyfield} +\setinterfacecommand{correctwhitespace}{correctwhitespace} +\setinterfacecommand{coupledocument}{coupledocument} +\setinterfacecommand{couplemarking}{couplemarking} +\setinterfacecommand{couplepage}{couplepage} +\setinterfacecommand{couplepaper}{couplepaper} +\setinterfacecommand{coupleregister}{coupleregister} +\setinterfacecommand{crlf}{crlf} +\setinterfacecommand{currentdate}{currentdate} +\setinterfacecommand{currentheadnumber}{currentheadnumber} +\setinterfacecommand{cutspace}{cutspace} +\setinterfacecommand{date}{date} +\setinterfacecommand{decouplemarking}{decouplemarking} +\setinterfacecommand{decrementnumber}{decrementnumber} +\setinterfacecommand{define}{define} +\setinterfacecommand{defineaccent}{defineaccent} +\setinterfacecommand{defineblank}{defineblank} +\setinterfacecommand{defineblock}{defineblock} +\setinterfacecommand{definebodyfont}{definebodyfont} +\setinterfacecommand{definebodyfontenvironment}{definebodyfontenvironment} +\setinterfacecommand{definebuffer}{definebuffer} +\setinterfacecommand{definecharacter}{definecharacter} +\setinterfacecommand{definecolor}{definecolor} +\setinterfacecommand{definecolorgroup}{definecolorgroup} +\setinterfacecommand{definecolumnbreak}{definecolumnbreak} +\setinterfacecommand{definecolumnset}{definecolumnset} +\setinterfacecommand{definecombination}{definecombination} +\setinterfacecommand{definecombinedlist}{definecombinedlist} +\setinterfacecommand{definecommand}{definecommand} +\setinterfacecommand{defineconversion}{defineconversion} +\setinterfacecommand{definedescription}{definedescription} +\setinterfacecommand{defineenumeration}{defineenumeration} +\setinterfacecommand{definefield}{definefield} +\setinterfacecommand{definefieldstack}{definefieldstack} +\setinterfacecommand{definefiguresymbol}{definefiguresymbol} +\setinterfacecommand{definefloat}{definefloat} +\setinterfacecommand{definefont}{definefont} +\setinterfacecommand{definefontstyle}{definefontstyle} +\setinterfacecommand{definefontsynonym}{definefontsynonym} +\setinterfacecommand{defineframed}{defineframed} +\setinterfacecommand{defineframedtext}{defineframedtext} +\setinterfacecommand{definehbox}{definehbox} +\setinterfacecommand{definehead}{definehead} +\setinterfacecommand{defineindenting}{defineindenting} +\setinterfacecommand{defineinmargin}{defineinmargin} +\setinterfacecommand{defineinteractionmenu}{defineinteractionmenu} +\setinterfacecommand{defineitemgroup}{defineitemgroup} +\setinterfacecommand{definelabel}{definelabel} +\setinterfacecommand{definelayer}{definelayer} +\setinterfacecommand{definelayout}{definelayout} +\setinterfacecommand{definelist}{definelist} +\setinterfacecommand{definelogo}{definelogo} +\setinterfacecommand{definemainfield}{definemainfield} +\setinterfacecommand{definemakeup}{definemakeup} +\setinterfacecommand{definemarking}{definemarking} +\setinterfacecommand{definemathalignment}{definemathalignment} +\setinterfacecommand{defineoutput}{defineoutput} +\setinterfacecommand{defineoverlay}{defineoverlay} +\setinterfacecommand{definepagebreak}{definepagebreak} +\setinterfacecommand{definepalet}{definepalet} +\setinterfacecommand{definepapersize}{definepapersize} +\setinterfacecommand{defineparagraphs}{defineparagraphs} +\setinterfacecommand{defineplacement}{defineplacement} +\setinterfacecommand{defineprofile}{defineprofile} +\setinterfacecommand{defineprogram}{defineprogram} +\setinterfacecommand{definerawfont}{definerawfont} +\setinterfacecommand{definereference}{definereference} +\setinterfacecommand{definereferenceformat}{definereferenceformat} +\setinterfacecommand{definereferencelist}{definereferencelist} +\setinterfacecommand{defineregister}{defineregister} +\setinterfacecommand{definerule}{definerule} +\setinterfacecommand{definesection}{definesection} +\setinterfacecommand{definesectionblock}{definesectionblock} +\setinterfacecommand{definesorting}{definesorting} +\setinterfacecommand{definestartstop}{definestartstop} +\setinterfacecommand{definestyle}{definestyle} +\setinterfacecommand{definesubfield}{definesubfield} +\setinterfacecommand{definesymbol}{definesymbol} +\setinterfacecommand{definesynonyms}{definesynonyms} +\setinterfacecommand{definetabletemplate}{definetabletemplate} +\setinterfacecommand{definetabulate}{definetabulate} +\setinterfacecommand{definetext}{definetext} +\setinterfacecommand{definetextposition}{definetextposition} +\setinterfacecommand{definetextvariable}{definetextvariable} +\setinterfacecommand{definetype}{definetype} +\setinterfacecommand{definetyping}{definetyping} +\setinterfacecommand{defineversion}{defineversion} +\setinterfacecommand{determineheadnumber}{determineheadnumber} +\setinterfacecommand{determinelistcharacteristics}{determinelistcharacteristics} +\setinterfacecommand{determineregistercharacteristics}{determineregistercharacteristics} +\setinterfacecommand{dimension}{dimension} +\setinterfacecommand{disableinteractionmenu}{disableinteractionmenu} +\setinterfacecommand{domicile}{domicile} +\setinterfacecommand{donttest}{donttest} +\setinterfacecommand{edgedistance}{edgedistance} +\setinterfacecommand{edgewidth}{edgewidth} +\setinterfacecommand{emptylines}{emptylines} +\setinterfacecommand{environment}{environment} +\setinterfacecommand{externalfigure}{externalfigure} +\setinterfacecommand{fact}{fact} +\setinterfacecommand{field}{field} +\setinterfacecommand{fieldstack}{fieldstack} +\setinterfacecommand{fillinfield}{fillinfield} +\setinterfacecommand{fillinline}{fillinline} +\setinterfacecommand{fillinrules}{fillinrules} +\setinterfacecommand{fillintext}{fillintext} +\setinterfacecommand{fitfield}{fitfield} +\setinterfacecommand{fixedspace}{fixedspace} +\setinterfacecommand{fixedspaces}{fixedspaces} +\setinterfacecommand{followprofile}{followprofile} +\setinterfacecommand{followprofileversion}{followprofileversion} +\setinterfacecommand{followversion}{followversion} +\setinterfacecommand{footerdistance}{footerdistance} +\setinterfacecommand{footerheight}{footerheight} +\setinterfacecommand{footnote}{footnote} +\setinterfacecommand{footnotetext}{footnotetext} +\setinterfacecommand{forceblocks}{forceblocks} +\setinterfacecommand{formulanumber}{formulanumber} +\setinterfacecommand{fraction}{fraction} +\setinterfacecommand{framed}{framed} +\setinterfacecommand{from}{from} +\setinterfacecommand{getbuffer}{getbuffer} +\setinterfacecommand{getmarking}{getmarking} +\setinterfacecommand{getnumber}{getnumber} +\setinterfacecommand{godown}{godown} +\setinterfacecommand{goto}{goto} +\setinterfacecommand{gotobox}{gotobox} +\setinterfacecommand{gotopage}{gotopage} +\setinterfacecommand{graycolor}{graycolor} +\setinterfacecommand{greyvalue}{greyvalue} +\setinterfacecommand{grid}{grid} +\setinterfacecommand{hairline}{hairline} +\setinterfacecommand{head}{head} +\setinterfacecommand{headerdistance}{headerdistance} +\setinterfacecommand{headerheight}{headerheight} +\setinterfacecommand{headlevel}{headlevel} +\setinterfacecommand{headnumber}{headnumber} +\setinterfacecommand{headsym}{headsym} +\setinterfacecommand{headtext}{headtext} +\setinterfacecommand{hideblocks}{hideblocks} +\setinterfacecommand{high}{high} +\setinterfacecommand{hl}{hl} +\setinterfacecommand{immediatebetweenlist}{immediatebetweenlist} +\setinterfacecommand{immediatetolist}{immediatetolist} +\setinterfacecommand{in}{in} +\setinterfacecommand{incrementnumber}{incrementnumber} +\setinterfacecommand{indenting}{indenting} +\setinterfacecommand{inframed}{inframed} +\setinterfacecommand{infull}{infull} +\setinterfacecommand{ininner}{ininner} +\setinterfacecommand{inleft}{inleft} +\setinterfacecommand{inleftedge}{inleftedge} +\setinterfacecommand{inleftmargin}{inleftmargin} +\setinterfacecommand{inline}{inline} +\setinterfacecommand{inmargin}{inmargin} +\setinterfacecommand{inmframed}{inmaframed} +\setinterfacecommand{inneredgedistance}{inneredgedistance} +\setinterfacecommand{inneredgewidth}{inneredgewidth} +\setinterfacecommand{innermargindistance}{innermargindistance} +\setinterfacecommand{innermarginwidth}{innermarginwidth} +\setinterfacecommand{inothermargin}{inothermargin} +\setinterfacecommand{inouter}{inouter} +\setinterfacecommand{inright}{inright} +\setinterfacecommand{inrightedge}{inrightedge} +\setinterfacecommand{inrightmargin}{inrightmargin} +\setinterfacecommand{installlanguage}{installlanguage} +\setinterfacecommand{interactionbar}{interactionbar} +\setinterfacecommand{interactionbuttons}{interactionbuttons} +\setinterfacecommand{interactionmenu}{interactionmenu} +\setinterfacecommand{item}{item} +\setinterfacecommand{items}{items} +\setinterfacecommand{its}{its} +\setinterfacecommand{keepblocks}{keepblocks} +\setinterfacecommand{label}{label} +\setinterfacecommand{labels}{labels} +\setinterfacecommand{labeltext}{labeltext} +\setinterfacecommand{language}{language} +\setinterfacecommand{leftaligned}{leftaligned} +\setinterfacecommand{leftedgedistance}{leftedgedistance} +\setinterfacecommand{leftedgewidth}{leftedgewidth} +\setinterfacecommand{leftmargindistance}{leftmargindistance} +\setinterfacecommand{leftmarginwidth}{leftmarginwidth} +\setinterfacecommand{leg}{leg} +\setinterfacecommand{linewidth}{linethickness} +\setinterfacecommand{listheight}{listheight} +\setinterfacecommand{listlength}{listlength} +\setinterfacecommand{listsymbol}{listsymbol} +\setinterfacecommand{listwidth}{listwidth} +\setinterfacecommand{logfields}{logfields} +\setinterfacecommand{lohi}{lohi} +\setinterfacecommand{low}{low} +\setinterfacecommand{macroname}{name} +\setinterfacecommand{mainlanguage}{mainlanguage} +\setinterfacecommand{makeupheight}{makeupheight} +\setinterfacecommand{makeupwidth}{makeupwidth} +\setinterfacecommand{mar}{mar} +\setinterfacecommand{margindistance}{margindistance} +\setinterfacecommand{marginrule}{marginrule} +\setinterfacecommand{margintext}{margintext} +\setinterfacecommand{margintitle}{margintitle} +\setinterfacecommand{marginwidth}{marginwidth} +\setinterfacecommand{marginword}{marginword} +\setinterfacecommand{marking}{marking} +\setinterfacecommand{markversion}{markversion} +\setinterfacecommand{mathematics}{mathematics} +\setinterfacecommand{menubutton}{menubutton} +\setinterfacecommand{mframed}{maframed} +\setinterfacecommand{midaligned}{midaligned} +\setinterfacecommand{mirror}{mirror} +\setinterfacecommand{month}{month} +\setinterfacecommand{moveformula}{moveformula} +\setinterfacecommand{moveongrid}{moveongrid} +\setinterfacecommand{movesidefloat}{movesidefloat} +\setinterfacecommand{navigating}{navigating} +\setinterfacecommand{nodimension}{nodimension} +\setinterfacecommand{noheaderandfooterlines}{noheaderandfooterlines} +\setinterfacecommand{noindenting}{noindenting} +\setinterfacecommand{nolist}{nolist} +\setinterfacecommand{nomarking}{nomarking} +\setinterfacecommand{nomoreblocks}{nomoreblocks} +\setinterfacecommand{nomorefiles}{nomorefiles} +\setinterfacecommand{nop}{nop} +\setinterfacecommand{nospace}{nospace} +\setinterfacecommand{note}{note} +\setinterfacecommand{notopandbottomlines}{notopandbottomlines} +\setinterfacecommand{notsmallcapped}{nocap} +\setinterfacecommand{nowhitespace}{nowhitespace} +\setinterfacecommand{numberofsubpages}{numberofsubpages} +\setinterfacecommand{numbers}{numbers} +\setinterfacecommand{outeredgedistance}{outeredgedistance} +\setinterfacecommand{outeredgewidth}{outeredgewidth} +\setinterfacecommand{outermargindistance}{outermargindistance} +\setinterfacecommand{outermarginwidth}{outermarginwidth} +\setinterfacecommand{packed}{packed} +\setinterfacecommand{page}{page} +\setinterfacecommand{pagedepth}{pagedepth} +\setinterfacecommand{pagenumber}{pagenumber} +\setinterfacecommand{pageoffset}{pageoffset} +\setinterfacecommand{pagereference}{pagereference} +\setinterfacecommand{pagetype}{pagetype} +\setinterfacecommand{paperheight}{paperheight} +\setinterfacecommand{paperwidth}{paperwidth} +\setinterfacecommand{periods}{periods} +\setinterfacecommand{plaatsruwelijst}{placerawlist} +\setinterfacecommand{placebookmarks}{placebookmarks} +\setinterfacecommand{placecombinedlist}{placecombinedlist} +\setinterfacecommand{placefloat}{placefloat} +\setinterfacecommand{placefootnotes}{placefootnotes} +\setinterfacecommand{placeformula}{placeformula} +\setinterfacecommand{placeheadnumber}{placeheadnumber} +\setinterfacecommand{placeheadtext}{placeheadtext} +\setinterfacecommand{placelegend}{placelegend} +\setinterfacecommand{placelist}{placelist} +\setinterfacecommand{placelocalfootnotes}{placelocalfootnotes} +\setinterfacecommand{placelogos}{placelogos} +\setinterfacecommand{placeongrid}{placeongrid} +\setinterfacecommand{placeontopofeachother}{placeontopofeachother} +\setinterfacecommand{placepagenumber}{placepagenumber} +\setinterfacecommand{placereferencelist}{placereferencelist} +\setinterfacecommand{placeregister}{placeregister} +\setinterfacecommand{placerule}{placerule} +\setinterfacecommand{placesidebyside}{placesidebyside} +\setinterfacecommand{placesubformula}{placesubformula} +\setinterfacecommand{placetextvariable}{placetextvariable} +\setinterfacecommand{position}{position} +\setinterfacecommand{positiontext}{positiontext} +\setinterfacecommand{printpaperheight}{printpaperheight} +\setinterfacecommand{printpaperwidth}{printpaperwidth} +\setinterfacecommand{processblocks}{processblocks} +\setinterfacecommand{processpage}{processpage} +\setinterfacecommand{product}{product} +\setinterfacecommand{program}{program} +\setinterfacecommand{project}{project} +\setinterfacecommand{publication}{publication} +\setinterfacecommand{quotation}{quotation} +\setinterfacecommand{quote}{quote} +\setinterfacecommand{ran}{ran} +\setinterfacecommand{redo}{redo} +\setinterfacecommand{ref}{ref} +\setinterfacecommand{reference}{reference} +\setinterfacecommand{referral}{referral} +\setinterfacecommand{referraldate}{referraldate} +\setinterfacecommand{referring}{referring} +\setinterfacecommand{remark}{remark} +\setinterfacecommand{reset}{reset} +\setinterfacecommand{resetmarking}{resetmarking} +\setinterfacecommand{resetnumber}{resetnumber} +\setinterfacecommand{resettext}{resettextcontent} +\setinterfacecommand{rightaligned}{rightaligned} +\setinterfacecommand{rightedgedistance}{rightedgedistance} +\setinterfacecommand{rightedgewidth}{rightedgewidth} +\setinterfacecommand{rightmargindistance}{rightmargindistance} +\setinterfacecommand{rightmarginwidth}{rightmarginwidth} +\setinterfacecommand{romannumerals}{romannumerals} +\setinterfacecommand{rotate}{rotate} +\setinterfacecommand{scale}{scale} +\setinterfacecommand{screen}{screen} +\setinterfacecommand{selectblocks}{selectblocks} +\setinterfacecommand{selectpaper}{selectpaper} +\setinterfacecommand{selectversion}{selectversion} +\setinterfacecommand{setnumber}{setnumber} +\setinterfacecommand{settextcontent}{settextcontent} +\setinterfacecommand{settextvariable}{settextvariable} +\setinterfacecommand{setupalign}{setupalign} +\setinterfacecommand{setupanswerarea}{setupanswerarea} +\setinterfacecommand{setuparranging}{setuparranging} +\setinterfacecommand{setupbackground}{setupbackground} +\setinterfacecommand{setupbackgrounds}{setupbackgrounds} +\setinterfacecommand{setupblackrules}{setupblackrules} +\setinterfacecommand{setupblank}{setupblank} +\setinterfacecommand{setupblock}{setupblock} +\setinterfacecommand{setupbodyfont}{setupbodyfont} +\setinterfacecommand{setupbodyfontenvironment}{setupbodyfontenvironment} +\setinterfacecommand{setupbottom}{setupbottom} +\setinterfacecommand{setupbottomtexts}{setupbottomtexts} +\setinterfacecommand{setupbuffer}{setupbuffer} +\setinterfacecommand{setupbuttons}{setupbuttons} +\setinterfacecommand{setupcapitals}{setupcapitals} +\setinterfacecommand{setupcaption}{setupcaption} +\setinterfacecommand{setupcaptions}{setupcaptions} +\setinterfacecommand{setupclipping}{setupclipping} +\setinterfacecommand{setupcolor}{setupcolor} +\setinterfacecommand{setupcolors}{setupcolors} +\setinterfacecommand{setupcolumns}{setupcolumns} +\setinterfacecommand{setupcolumnset}{setupcolumnset} +\setinterfacecommand{setupcolumnsetlines}{setupcolumnsetlines} +\setinterfacecommand{setupcolumnsetstart}{setupcolumnsetstart} +\setinterfacecommand{setupcombinations}{setupcombinations} +\setinterfacecommand{setupcombinedlist}{setupcombinedlist} +\setinterfacecommand{setupcomment}{setupcomment} +\setinterfacecommand{setupdescriptions}{setupdescriptions} +\setinterfacecommand{setupenumerations}{setupenumerations} +\setinterfacecommand{setupexternalfigures}{setupexternalfigures} +\setinterfacecommand{setupfield}{setupfield} +\setinterfacecommand{setupfields}{setupfields} +\setinterfacecommand{setupfillinlines}{setupfillinlines} +\setinterfacecommand{setupfillinrules}{setupfillinrules} +\setinterfacecommand{setupfloat}{setupfloat} +\setinterfacecommand{setupfloats}{setupfloats} +\setinterfacecommand{setupfloatsplitting}{setupfloatsplitting} +\setinterfacecommand{setupfooter}{setupfooter} +\setinterfacecommand{setupfootertexts}{setupfootertexts} +\setinterfacecommand{setupfootnotedefinition}{setupfootnotedefinition} +\setinterfacecommand{setupfootnotes}{setupfootnotes} +\setinterfacecommand{setupforms}{setupforms} +\setinterfacecommand{setupformulas}{setupformulae} +\setinterfacecommand{setupframed}{setupframed} +\setinterfacecommand{setupframedtexts}{setupframedtexts} +\setinterfacecommand{setuphead}{setuphead} +\setinterfacecommand{setupheader}{setupheader} +\setinterfacecommand{setupheadertexts}{setupheadertexts} +\setinterfacecommand{setupheadnumber}{setupheadnumber} +\setinterfacecommand{setupheads}{setupheads} +\setinterfacecommand{setupheadtext}{setupheadtext} +\setinterfacecommand{setuphyphenmark}{setuphyphenmark} +\setinterfacecommand{setupindentations}{setupindentations} +\setinterfacecommand{setupindenting}{setupindenting} +\setinterfacecommand{setupinmargin}{setupinmargin} +\setinterfacecommand{setupinteraction}{setupinteraction} +\setinterfacecommand{setupinteractionbar}{setupinteractionbar} +\setinterfacecommand{setupinteractionmenu}{setupinteractionmenu} +\setinterfacecommand{setupinteractionscreen}{setupinteractionscreen} +\setinterfacecommand{setupinterlinespace}{setupinterlinespace} +\setinterfacecommand{setupitemgroup}{setupitemgroup} +\setinterfacecommand{setupitemgroups}{setupitemizations} +\setinterfacecommand{setupitems}{setupitems} +\setinterfacecommand{setuplabeltext}{setuplabeltext} +\setinterfacecommand{setuplanguage}{setuplanguage} +\setinterfacecommand{setuplayout}{setuplayout} +\setinterfacecommand{setuplegend}{setuplegend} +\setinterfacecommand{setuplinenumbering}{setuplinenumbering} +\setinterfacecommand{setuplines}{setuplines} +\setinterfacecommand{setuplinewidth}{setuplinewidth} +\setinterfacecommand{setuplist}{setuplist} +\setinterfacecommand{setupmakeup}{setupmakeup} +\setinterfacecommand{setupmarginblocks}{setupmarginblocks} +\setinterfacecommand{setupmarginrules}{setupmarginrules} +\setinterfacecommand{setupmarking}{setupmarking} +\setinterfacecommand{setupmathalignment}{setupmathalignment} +\setinterfacecommand{setupnarrower}{setupnarrower} +\setinterfacecommand{setupnumber}{setupnumber} +\setinterfacecommand{setupnumbering}{setupnumbering} +\setinterfacecommand{setupoppositeplacing}{setupoppositeplacing} +\setinterfacecommand{setupoutput}{setupoutput} +\setinterfacecommand{setuppagecomment}{setuppagecomment} +\setinterfacecommand{setuppagenumber}{setuppagenumber} +\setinterfacecommand{setuppagenumbering}{setuppagenumbering} +\setinterfacecommand{setuppagetransitions}{setuppagetransitions} +\setinterfacecommand{setuppalet}{setuppalet} +\setinterfacecommand{setuppaper}{setuppaper} +\setinterfacecommand{setuppapersize}{setuppapersize} +\setinterfacecommand{setupparagraphnumbering}{setupparagraphnumbering} +\setinterfacecommand{setupparagraphs}{setupparagraphs} +\setinterfacecommand{setupplacement}{setupplacement} +\setinterfacecommand{setuppositioning}{setuppositioning} +\setinterfacecommand{setupprofiles}{setupprofiles} +\setinterfacecommand{setupprograms}{setupprograms} +\setinterfacecommand{setuppublications}{setuppublications} +\setinterfacecommand{setupquote}{setupquote} +\setinterfacecommand{setupreferencelist}{setupreferencelist} +\setinterfacecommand{setupreferencing}{setupreferencing} +\setinterfacecommand{setupregister}{setupregister} +\setinterfacecommand{setuprotate}{setuprotate} +\setinterfacecommand{setuprule}{setuprule} +\setinterfacecommand{setups}{setups} +\setinterfacecommand{setupscreens}{setupscreens} +\setinterfacecommand{setupsection}{setupsection} +\setinterfacecommand{setupsectionblock}{setupsectionblock} +\setinterfacecommand{setupsorting}{setupsorting} +\setinterfacecommand{setupspacing}{setupspacing} +\setinterfacecommand{setupstartstop}{setupstartstop} +\setinterfacecommand{setupstrut}{setupstrut} +\setinterfacecommand{setupsubpagenumber}{setupsubpagenumber} +\setinterfacecommand{setupsymbolset}{setupsymbolset} +\setinterfacecommand{setupsynchronization}{setupsynchronization} +\setinterfacecommand{setupsynchronizationbar}{setupsynchronizationbar} +\setinterfacecommand{setupsynonyms}{setupsynonyms} +\setinterfacecommand{setupsystem}{setupsystem} +\setinterfacecommand{setuptab}{setuptab} +\setinterfacecommand{setuptables}{setuptables} +\setinterfacecommand{setuptabulate}{setuptabulate} +\setinterfacecommand{setuptext}{setuptext} +\setinterfacecommand{setuptextposition}{setuptextposition} +\setinterfacecommand{setuptextrules}{setuptextrules} +\setinterfacecommand{setuptexttexts}{setuptexttexts} +\setinterfacecommand{setuptextvariable}{setuptextvariable} +\setinterfacecommand{setupthinrules}{setupthinrules} +\setinterfacecommand{setuptolerance}{setuptolerance} +\setinterfacecommand{setuptop}{setuptop} +\setinterfacecommand{setuptoptexts}{setuptoptexts} +\setinterfacecommand{setuptype}{setuptype} +\setinterfacecommand{setuptyping}{setuptyping} +\setinterfacecommand{setupunderbar}{setupunderbar} +\setinterfacecommand{setupurl}{setupurl} +\setinterfacecommand{setupversions}{setupversions} +\setinterfacecommand{setupwhitespace}{setupwhitespace} +\setinterfacecommand{showbodyfont}{showbodyfont} +\setinterfacecommand{showbodyfontenvironment}{showbodyfontenvironment} +\setinterfacecommand{showcolor}{showcolor} +\setinterfacecommand{showcolorgroup}{showcolorgroup} +\setinterfacecommand{showexternalfigures}{showexternalfigures} +\setinterfacecommand{showfields}{showfields} +\setinterfacecommand{showframe}{showframe} +\setinterfacecommand{showgrid}{showgrid} +\setinterfacecommand{showlayout}{showlayout} +\setinterfacecommand{showmakeup}{showmakeup} +\setinterfacecommand{showpalet}{showpalet} +\setinterfacecommand{showprint}{showprint} +\setinterfacecommand{showsetups}{showsetups} +\setinterfacecommand{showstruts}{showstruts} +\setinterfacecommand{showsymbolset}{showsymbolset} +\setinterfacecommand{smallcapped}{cap} +\setinterfacecommand{someline}{someline} +\setinterfacecommand{somewhere}{somewhere} +\setinterfacecommand{space}{space} +\setinterfacecommand{splitfloat}{splitfloat} +\setinterfacecommand{startalignment}{startalignment} +\setinterfacecommand{startbackground}{startbackground} +\setinterfacecommand{startcoding}{startcoding} +\setinterfacecommand{startcolor}{startcolor} +\setinterfacecommand{startcolumnmakeup}{startcolumnmakeup} +\setinterfacecommand{startcolumns}{startcolumns} +\setinterfacecommand{startcolumnset}{startcolumnset} +\setinterfacecommand{startcombination}{startcombination} +\setinterfacecommand{startcomponent}{startcomponent} +\setinterfacecommand{startdocument}{startdocument} +\setinterfacecommand{startenvironment}{startenvironment} +\setinterfacecommand{startfigure}{startfigure} +\setinterfacecommand{startglobal}{startglobal} +\setinterfacecommand{startline}{startline} +\setinterfacecommand{startlinecorrection}{startlinecorrection} +\setinterfacecommand{startlinenumbering}{startlinenumbering} +\setinterfacecommand{startlines}{startlines} +\setinterfacecommand{startlocal}{startlocal} +\setinterfacecommand{startlocalfootnotes}{startlocalfootnotes} +\setinterfacecommand{startmakeup}{startmakeup} +\setinterfacecommand{startmarginblock}{startmarginblock} +\setinterfacecommand{startmarginrule}{startmarginrule} +\setinterfacecommand{startnarrower}{startnarrower} +\setinterfacecommand{startopposite}{startopposite} +\setinterfacecommand{startoverlay}{startoverlay} +\setinterfacecommand{startoverzicht}{startoverview} +\setinterfacecommand{startpacked}{startpacked} +\setinterfacecommand{startpositioning}{startpositioning} +\setinterfacecommand{startproduct}{startproduct} +\setinterfacecommand{startprofile}{startprofile} +\setinterfacecommand{startproject}{startproject} +\setinterfacecommand{startquotation}{startquotation} +\setinterfacecommand{startraster}{startraster} +\setinterfacecommand{startsymbolset}{startsymbolset} +\setinterfacecommand{startsynchronization}{startsynchronization} +\setinterfacecommand{starttable}{starttable} +\setinterfacecommand{starttables}{starttables} +\setinterfacecommand{starttext}{starttext} +\setinterfacecommand{starttextrule}{starttextrule} +\setinterfacecommand{startunpacked}{startunpacked} +\setinterfacecommand{startversion}{startversion} +\setinterfacecommand{stopalignment}{stopalignment} +\setinterfacecommand{stopbackground}{stopbackground} +\setinterfacecommand{stopcoding}{stopcoding} +\setinterfacecommand{stopcolor}{stopcolor} +\setinterfacecommand{stopcolumnmakeup}{stopcolumnmakeup} +\setinterfacecommand{stopcolumns}{stopcolumns} +\setinterfacecommand{stopcolumnset}{stopcolumnset} +\setinterfacecommand{stopcombination}{stopcombination} +\setinterfacecommand{stopcomponent}{stopcomponent} +\setinterfacecommand{stopdocument}{stopdocument} +\setinterfacecommand{stopenvironment}{stopenvironment} +\setinterfacecommand{stopglobal}{stopglobal} +\setinterfacecommand{stopline}{stopline} +\setinterfacecommand{stoplinecorrection}{stoplinecorrection} +\setinterfacecommand{stoplinenumbering}{stoplinenumbering} +\setinterfacecommand{stoplines}{stoplines} +\setinterfacecommand{stoplocal}{stoplocal} +\setinterfacecommand{stoplocalfootnotes}{stoplocalfootnotes} +\setinterfacecommand{stopmakeup}{stopmakeup} +\setinterfacecommand{stopmarginblock}{stopmarginblock} +\setinterfacecommand{stopmarginrule}{stopmarginrule} +\setinterfacecommand{stopnarrower}{stopnarrower} +\setinterfacecommand{stopopposite}{stopopposite} +\setinterfacecommand{stopoverlay}{stopoverlay} +\setinterfacecommand{stopoverzicht}{stopoverview} +\setinterfacecommand{stoppacked}{stoppacked} +\setinterfacecommand{stoppositioning}{stoppositioning} +\setinterfacecommand{stopproduct}{stopproduct} +\setinterfacecommand{stopprofile}{stopprofile} +\setinterfacecommand{stopproject}{stopproject} +\setinterfacecommand{stopquotation}{stopquotation} +\setinterfacecommand{stopraster}{stopraster} +\setinterfacecommand{stopsynchronization}{stopsynchronization} +\setinterfacecommand{stoptable}{stoptable} +\setinterfacecommand{stoptables}{stoptables} +\setinterfacecommand{stoptext}{stoptext} +\setinterfacecommand{stoptextrule}{stoptextrule} +\setinterfacecommand{stopunpacked}{stopunpacked} +\setinterfacecommand{stopversion}{stopversion} +\setinterfacecommand{stretched}{stretched} +\setinterfacecommand{subformulanumber}{subformulanumber} +\setinterfacecommand{subpagenumber}{subpagenumber} +\setinterfacecommand{switchtobodyfont}{switchtobodyfont} +\setinterfacecommand{switchtorawfont}{switchtorawfont} +\setinterfacecommand{sym}{sym} +\setinterfacecommand{symbol}{symbol} +\setinterfacecommand{synchronizationbar}{synchronizationbar} +\setinterfacecommand{synchronize}{synchronize} +\setinterfacecommand{tab}{tab} +\setinterfacecommand{testcolumn}{testcolumn} +\setinterfacecommand{testpage}{testpage} +\setinterfacecommand{tex}{tex} +\setinterfacecommand{textheight}{textheight} +\setinterfacecommand{textreference}{textreference} +\setinterfacecommand{textrule}{textrule} +\setinterfacecommand{textvariable}{textvariable} +\setinterfacecommand{textwidth}{textwidth} +\setinterfacecommand{thinrule}{thinrule} +\setinterfacecommand{thinrules}{thinrules} +\setinterfacecommand{tooltip}{tooltip} +\setinterfacecommand{topdistance}{topdistance} +\setinterfacecommand{topheight}{topheight} +\setinterfacecommand{topspace}{topspace} +\setinterfacecommand{totalnumberofpages}{totalnumberofpages} +\setinterfacecommand{translate}{translate} +\setinterfacecommand{txt}{txt} +\setinterfacecommand{typ}{typ} +\setinterfacecommand{type}{type} +\setinterfacecommand{typebuffer}{typebuffer} +\setinterfacecommand{typefile}{typefile} +\setinterfacecommand{unitmeaning}{unitmeaning} +\setinterfacecommand{unknown}{unknown} +\setinterfacecommand{useJSscripts}{useJSscripts} +\setinterfacecommand{useURL}{useURL} +\setinterfacecommand{useXMLfilter}{useXMLfilter} +\setinterfacecommand{useblocks}{useblocks} +\setinterfacecommand{usecommands}{usecommands} +\setinterfacecommand{useencoding}{useencoding} +\setinterfacecommand{useexternaldocument}{useexternaldocument} +\setinterfacecommand{useexternalfigure}{useexternalfigure} +\setinterfacecommand{useexternalfile}{useexternalfile} +\setinterfacecommand{useexternalfiles}{useexternalfiles} +\setinterfacecommand{useexternalsoundtrack}{useexternalsoundtrack} +\setinterfacecommand{usemodule}{usemodule} +\setinterfacecommand{usemodules}{usemodules} +\setinterfacecommand{usepath}{usedirectory} +\setinterfacecommand{usereferences}{usereferences} +\setinterfacecommand{usespecials}{usespecials} +\setinterfacecommand{usesymbols}{usesymbols} +\setinterfacecommand{usetypescript}{usetypescript} +\setinterfacecommand{usetypescriptfile}{usetypescriptfile} +\setinterfacecommand{useurl}{useurl} +\setinterfacecommand{version}{version} +\setinterfacecommand{vl}{vl} +\setinterfacecommand{weekday}{weekday} +\setinterfacecommand{whitespace}{whitespace} +\setinterfacecommand{wordright}{wordright} +\setinterfacecommand{writebetweenlist}{writebetweenlist} +\setinterfacecommand{writetolist}{writetolist} +\setinterfacecommand{writetoreferencelist}{writetoreferencelist} +\setinterfacecommand{writetoregister}{writetoregister} +% +\endinput \ No newline at end of file diff --git a/tex/context/base/mult-fr.tex b/tex/context/base/mult-fr.tex new file mode 100644 index 000000000..5244565e9 --- /dev/null +++ b/tex/context/base/mult-fr.tex @@ -0,0 +1,1693 @@ +% this file is auto-generated, don't edit this file +% +% definitions for interface variables for language fr +% +\setinterfacevariable{Addition}{Ajout} +\setinterfacevariable{Balloon}{Ballon} +\setinterfacevariable{Character}{Caratere} +\setinterfacevariable{Characters}{Caracteres} +\setinterfacevariable{CloseDocument}{FermeDocument} +\setinterfacevariable{ExitViewer}{SortVisualisateur} +\setinterfacevariable{FirstPage}{PremierePage} +\setinterfacevariable{FitHeight}{AjusteHauteur} +\setinterfacevariable{FitWidth}{AjusteLargeur} +\setinterfacevariable{GotoPage}{VaalaPage} +\setinterfacevariable{Greek}{Grec} +\setinterfacevariable{Help}{Aide} +\setinterfacevariable{HideField}{CacheChamp} +\setinterfacevariable{HideLayer}{CacheCalque} +\setinterfacevariable{Key}{Cle} +\setinterfacevariable{LastPage}{DernierePage} +\setinterfacevariable{LoadForm}{ChargeForm} +\setinterfacevariable{MONTH}{MOIS} +\setinterfacevariable{New}{Nouveau} +\setinterfacevariable{NextJump}{SautSuivant} +\setinterfacevariable{NextPage}{PageSuivante} +\setinterfacevariable{Numbers}{Numeros} +\setinterfacevariable{OpenNamedDocument}{OuvreDocumentNomme} +\setinterfacevariable{Paragraph}{Paragraphe} +\setinterfacevariable{PauseMovie}{PauseFilm} +\setinterfacevariable{PauseRendering}{PauseRendering} +\setinterfacevariable{PauseSound}{PauseSon} +\setinterfacevariable{PreviousJump}{SautPrecedent} +\setinterfacevariable{PreviousPage}{PagePrecedente} +\setinterfacevariable{PrintDocument}{ImprimeDocument} +\setinterfacevariable{Query}{Query} +\setinterfacevariable{QueryAgain}{QueryAgain} +\setinterfacevariable{ResetForm}{RazForm} +\setinterfacevariable{ResumeMovie}{ReprendFilm} +\setinterfacevariable{ResumeRendering}{ResumeRendering} +\setinterfacevariable{ResumeSound}{ReprendSon} +\setinterfacevariable{Romannumerals}{Chiffresromains} +\setinterfacevariable{SaveDocument}{SauvegardeDocument} +\setinterfacevariable{SaveForm}{SauvegardeForm} +\setinterfacevariable{SaveNamedDocument}{SauvegardeDocumentNomme} +\setinterfacevariable{SearchAgain}{RechercheSuivant} +\setinterfacevariable{SearchDocument}{RechercheDocument} +\setinterfacevariable{ShowBookmarks}{ShowBookmarks} +\setinterfacevariable{ShowField}{MontreChamp} +\setinterfacevariable{ShowThumbs}{ShowThumbs} +\setinterfacevariable{StartMovie}{DemarreFilm} +\setinterfacevariable{StartRendering}{StartRendering} +\setinterfacevariable{StartSound}{DemarreSon} +\setinterfacevariable{StopMovie}{StoppeFilm} +\setinterfacevariable{StopRendering}{StopRendering} +\setinterfacevariable{StopSound}{StoppeSon} +\setinterfacevariable{SubmitForm}{SoumettreForm} +\setinterfacevariable{ToggleLayer}{ToggleLayer} +\setinterfacevariable{ToggleViewer}{ChangeVisualisateur} +\setinterfacevariable{URL}{URL} +\setinterfacevariable{VideLayer}{VideLayer} +\setinterfacevariable{ViewerHelp}{AideVisualisateur} +\setinterfacevariable{WEEKDAY}{JOURSEMAINE} +\setinterfacevariable{WORD}{MOT} +\setinterfacevariable{abbreviation}{abreviation} +\setinterfacevariable{abbreviations}{abreviations} +\setinterfacevariable{absolute}{absolute} +\setinterfacevariable{action}{action} +\setinterfacevariable{after}{apres} +\setinterfacevariable{all}{tout} +\setinterfacevariable{always}{toujours} +\setinterfacevariable{answerarea}{answerarea} +\setinterfacevariable{appendices}{annexes} +\setinterfacevariable{appendix}{annexe} +\setinterfacevariable{april}{avril} +\setinterfacevariable{atmargin}{alamarge} +\setinterfacevariable{atpage}{alapage} +\setinterfacevariable{august}{aout} +\setinterfacevariable{author}{auteur} +\setinterfacevariable{auto}{auto} +\setinterfacevariable{autointro}{autointro} +\setinterfacevariable{back}{retour} +\setinterfacevariable{background}{arriereplan} +\setinterfacevariable{backmatter}{epilogue} +\setinterfacevariable{backpart}{postface} +\setinterfacevariable{backspace}{retourarriere} +\setinterfacevariable{backward}{retourarriere} +\setinterfacevariable{bbl}{bbl} +\setinterfacevariable{before}{avant} +\setinterfacevariable{begin}{begin} +\setinterfacevariable{bib}{bib} +\setinterfacevariable{big}{grand} +\setinterfacevariable{bigbodyfont}{grandepolicecorp} +\setinterfacevariable{bigpreference}{grandepreference} +\setinterfacevariable{blank}{vide} +\setinterfacevariable{blockquote}{blockquote} +\setinterfacevariable{bodymatter}{texteprincipal} +\setinterfacevariable{bodypart}{corpsdetexte} +\setinterfacevariable{bold}{gras} +\setinterfacevariable{bolditalic}{italiquegras} +\setinterfacevariable{boldslanted}{inclinegras} +\setinterfacevariable{bookmark}{marquepage} +\setinterfacevariable{both}{lesdeux} +\setinterfacevariable{bottom}{inf} +\setinterfacevariable{brief}{brief} +\setinterfacevariable{broad}{large} +\setinterfacevariable{buffer}{buffer} +\setinterfacevariable{by}{par} +\setinterfacevariable{calligraphic}{calligraphique} +\setinterfacevariable{cap}{cap} +\setinterfacevariable{capital}{capitale} +\setinterfacevariable{center}{center} +\setinterfacevariable{chapter}{chapitre} +\setinterfacevariable{character}{caractere} +\setinterfacevariable{characters}{caracteres} +\setinterfacevariable{cite}{cite} +\setinterfacevariable{color}{couleur} +\setinterfacevariable{column}{colonne} +\setinterfacevariable{columns}{colonnes} +\setinterfacevariable{command}{commande} +\setinterfacevariable{commands}{commandes} +\setinterfacevariable{comment}{commentaire} +\setinterfacevariable{component}{composant} +\setinterfacevariable{concept}{concept} +\setinterfacevariable{content}{contenu} +\setinterfacevariable{contents}{contenus} +\setinterfacevariable{continue}{continue} +\setinterfacevariable{controls}{controles} +\setinterfacevariable{conversion}{conversion} +\setinterfacevariable{current}{courant} +\setinterfacevariable{cutspace}{cutspace} +\setinterfacevariable{date}{date} +\setinterfacevariable{day}{jour} +\setinterfacevariable{december}{decembre} +\setinterfacevariable{default}{defaut} +\setinterfacevariable{depth}{profondeur} +\setinterfacevariable{description}{description} +\setinterfacevariable{disable}{desactiver} +\setinterfacevariable{display}{affichage} +\setinterfacevariable{dot}{point} +\setinterfacevariable{doublesided}{rectoverso} +\setinterfacevariable{down}{down} +\setinterfacevariable{each}{chaque} +\setinterfacevariable{edge}{bord} +\setinterfacevariable{empty}{vide} +\setinterfacevariable{end}{end} +\setinterfacevariable{endnote}{notefin} +\setinterfacevariable{enumeration}{enumeration} +\setinterfacevariable{environment}{environement} +\setinterfacevariable{even}{paire} +\setinterfacevariable{external}{external} +\setinterfacevariable{fact}{fait} +\setinterfacevariable{february}{fevrier} +\setinterfacevariable{figure}{figure} +\setinterfacevariable{figures}{figures} +\setinterfacevariable{file}{fichier} +\setinterfacevariable{final}{final} +\setinterfacevariable{first}{premier} +\setinterfacevariable{firstcolumn}{premierecolonne} +\setinterfacevariable{firstpage}{premierepage} +\setinterfacevariable{firstsubpage}{premieresouspage} +\setinterfacevariable{fit}{adapte} +\setinterfacevariable{five}{cinq} +\setinterfacevariable{fix}{fixe} +\setinterfacevariable{fixed}{fixe} +\setinterfacevariable{flexible}{flexible} +\setinterfacevariable{float}{flottant} +\setinterfacevariable{flushinner}{flushinner} +\setinterfacevariable{flushleft}{flushleft} +\setinterfacevariable{flushouter}{flushouter} +\setinterfacevariable{flushright}{flushright} +\setinterfacevariable{footer}{pdp} +\setinterfacevariable{footnote}{notepdp} +\setinterfacevariable{force}{force} +\setinterfacevariable{foreground}{premierplan} +\setinterfacevariable{formeel}{formeel} +\setinterfacevariable{formula}{formule} +\setinterfacevariable{formulae}{formules} +\setinterfacevariable{forward}{avance} +\setinterfacevariable{four}{quatre} +\setinterfacevariable{frame}{cadre} +\setinterfacevariable{framedtext}{texteencadre} +\setinterfacevariable{friday}{vendredi} +\setinterfacevariable{frontmatter}{preambule} +\setinterfacevariable{frontpart}{preface} +\setinterfacevariable{global}{global} +\setinterfacevariable{graphic}{graphique} +\setinterfacevariable{graphics}{graphiques} +\setinterfacevariable{gray}{gris} +\setinterfacevariable{greek}{grec} +\setinterfacevariable{grid}{grille} +\setinterfacevariable{halfline}{demiligne} +\setinterfacevariable{handwritten}{manuscript} +\setinterfacevariable{hang}{suspend} +\setinterfacevariable{hanging}{suspend} +\setinterfacevariable{head}{tete} +\setinterfacevariable{header}{entete} +\setinterfacevariable{height}{hauteur} +\setinterfacevariable{helptext}{texteaide} +\setinterfacevariable{hencefore}{precedent} +\setinterfacevariable{here}{ici} +\setinterfacevariable{hereafter}{suivant} +\setinterfacevariable{hidden}{cache} +\setinterfacevariable{hiding}{cache} +\setinterfacevariable{high}{haut} +\setinterfacevariable{horizontal}{horizontale} +\setinterfacevariable{hyphenated}{hyphenated} +\setinterfacevariable{hz}{hz} +\setinterfacevariable{inbetween}{entre} +\setinterfacevariable{index}{index} +\setinterfacevariable{indices}{indices} +\setinterfacevariable{informeel}{informeel} +\setinterfacevariable{inherit}{herite} +\setinterfacevariable{inleft}{dansgauche} +\setinterfacevariable{inmargin}{dansmarge} +\setinterfacevariable{inner}{interieur} +\setinterfacevariable{inneredge}{bordinterieur} +\setinterfacevariable{innermargin}{margeinterieure} +\setinterfacevariable{inright}{dansdroit} +\setinterfacevariable{interaction}{interaction} +\setinterfacevariable{interactionmenu}{menuinteraction} +\setinterfacevariable{intermezzi}{intermezzi} +\setinterfacevariable{intermezzo}{intermezzo} +\setinterfacevariable{intext}{danstexte} +\setinterfacevariable{intro}{intro} +\setinterfacevariable{italic}{italique} +\setinterfacevariable{italicbold}{grasitalique} +\setinterfacevariable{item}{element} +\setinterfacevariable{itemize}{lister} +\setinterfacevariable{its}{its} +\setinterfacevariable{january}{janvier} +\setinterfacevariable{joinedup}{joinedup} +\setinterfacevariable{july}{juillet} +\setinterfacevariable{june}{juin} +\setinterfacevariable{keep}{maintient} +\setinterfacevariable{knockout}{knockout} +\setinterfacevariable{label}{etiquette} +\setinterfacevariable{landscape}{paysage} +\setinterfacevariable{last}{dernier} +\setinterfacevariable{lastcolumn}{dernierecolonne} +\setinterfacevariable{lastpage}{dernierepage} +\setinterfacevariable{lastpagenumber}{derniernumeropage} +\setinterfacevariable{lastsubpage}{dernieresouspage} +\setinterfacevariable{layer}{layer} +\setinterfacevariable{left}{gauche} +\setinterfacevariable{leftedge}{bordgauche} +\setinterfacevariable{lefthanging}{lefthanging} +\setinterfacevariable{leftmargin}{margegauche} +\setinterfacevariable{leftpage}{pagegauche} +\setinterfacevariable{lefttoright}{lefttoright} +\setinterfacevariable{legend}{legende} +\setinterfacevariable{lesshyphenation}{lesshyphenation} +\setinterfacevariable{line}{ligne} +\setinterfacevariable{linenote}{noteligne} +\setinterfacevariable{lines}{lignes} +\setinterfacevariable{list}{liste} +\setinterfacevariable{local}{local} +\setinterfacevariable{localenvironment}{environementlocal} +\setinterfacevariable{logo}{logo} +\setinterfacevariable{logos}{logos} +\setinterfacevariable{lohi}{baha} +\setinterfacevariable{loose}{perte} +\setinterfacevariable{low}{bas} +\setinterfacevariable{ls}{ls} +\setinterfacevariable{makeup}{makeup} +\setinterfacevariable{mar}{mar} +\setinterfacevariable{march}{mars} +\setinterfacevariable{margin}{marge} +\setinterfacevariable{marginedge}{bordmarge} +\setinterfacevariable{margintitle}{titremarge} +\setinterfacevariable{marking}{marquage} +\setinterfacevariable{mathalignment}{mathalignment} +\setinterfacevariable{mathcases}{mathcases} +\setinterfacevariable{mathmatrix}{mathmatrix} +\setinterfacevariable{max}{max} +\setinterfacevariable{maxdepth}{maxdepth} +\setinterfacevariable{maxheight}{maxheight} +\setinterfacevariable{maxwidth}{maxwidth} +\setinterfacevariable{may}{mai} +\setinterfacevariable{mediaeval}{medieval} +\setinterfacevariable{medium}{moyen} +\setinterfacevariable{middle}{milieu} +\setinterfacevariable{min}{min} +\setinterfacevariable{mindepth}{mindepth} +\setinterfacevariable{minheight}{hauteurmin} +\setinterfacevariable{minwidth}{largeurmin} +\setinterfacevariable{mirrored}{reflete} +\setinterfacevariable{monday}{lundi} +\setinterfacevariable{mono}{mono} +\setinterfacevariable{month}{mois} +\setinterfacevariable{morehyphenation}{morehyphenation} +\setinterfacevariable{name}{nom} +\setinterfacevariable{narrow}{etroit} +\setinterfacevariable{negative}{negatif} +\setinterfacevariable{never}{jamais} +\setinterfacevariable{new}{nouveau} +\setinterfacevariable{next}{prochain} +\setinterfacevariable{nextevenpage}{pagepairesuivante} +\setinterfacevariable{nextoddpage}{pageimpairesuivante} +\setinterfacevariable{nextpage}{pagesuivante} +\setinterfacevariable{nextsubpage}{souspagesuivante} +\setinterfacevariable{no}{non} +\setinterfacevariable{nocheck}{nonverifie} +\setinterfacevariable{nofit}{nofit} +\setinterfacevariable{nogrid}{nogrid} +\setinterfacevariable{nohz}{nohz} +\setinterfacevariable{nomarking}{sansmarquage} +\setinterfacevariable{none}{rien} +\setinterfacevariable{nonumber}{sansnumero} +\setinterfacevariable{normal}{normal} +\setinterfacevariable{nospacing}{sansespacement} +\setinterfacevariable{not}{pas} +\setinterfacevariable{note}{note} +\setinterfacevariable{nothanging}{nonsuspendu} +\setinterfacevariable{nothyphenated}{nothyphenated} +\setinterfacevariable{november}{novembre} +\setinterfacevariable{nowhere}{nulpart} +\setinterfacevariable{nowhite}{sansblanc} +\setinterfacevariable{number}{numero} +\setinterfacevariable{numbers}{numeros} +\setinterfacevariable{october}{octobre} +\setinterfacevariable{odd}{impair} +\setinterfacevariable{off}{desactive} +\setinterfacevariable{offset}{offset} +\setinterfacevariable{old}{old} +\setinterfacevariable{on}{actif} +\setinterfacevariable{one}{un} +\setinterfacevariable{opposite}{opposition} +\setinterfacevariable{outer}{exterieur} +\setinterfacevariable{outeredge}{bordexterieur} +\setinterfacevariable{outermargin}{margeexterieure} +\setinterfacevariable{overbar}{overbar} +\setinterfacevariable{overbars}{overbars} +\setinterfacevariable{overlay}{revetement} +\setinterfacevariable{overprint}{overprint} +\setinterfacevariable{overstrike}{surlignetout} +\setinterfacevariable{overstrikes}{surligne} +\setinterfacevariable{packed}{groupe} +\setinterfacevariable{page}{page} +\setinterfacevariable{pagecomment}{commentairepage} +\setinterfacevariable{pagenumber}{numeropage} +\setinterfacevariable{paper}{papier} +\setinterfacevariable{paragraph}{paragraphe} +\setinterfacevariable{part}{partie} +\setinterfacevariable{positive}{positif} +\setinterfacevariable{postponing}{postponing} +\setinterfacevariable{postscript}{postscript} +\setinterfacevariable{preference}{preference} +\setinterfacevariable{preview}{previsualisation} +\setinterfacevariable{previous}{precedent} +\setinterfacevariable{previousevenpage}{pagepaireprecedente} +\setinterfacevariable{previousoddpage}{pageimpaireprecedente} +\setinterfacevariable{previouspage}{pageprecedente} +\setinterfacevariable{previoussubpage}{souspageprecedente} +\setinterfacevariable{printable}{editable} +\setinterfacevariable{process}{process} +\setinterfacevariable{product}{produit} +\setinterfacevariable{program}{programme} +\setinterfacevariable{project}{projet} +\setinterfacevariable{protected}{protege} +\setinterfacevariable{quadruple}{quadruple} +\setinterfacevariable{quotation}{citation} +\setinterfacevariable{quote}{citer} +\setinterfacevariable{ran}{cours} +\setinterfacevariable{random}{aleatoire} +\setinterfacevariable{readonly}{lectureseule} +\setinterfacevariable{rectangular}{rectangulaire} +\setinterfacevariable{referral}{referral} +\setinterfacevariable{register}{registre} +\setinterfacevariable{regular}{regulier} +\setinterfacevariable{rekening}{rekening} +\setinterfacevariable{relative}{relatif} +\setinterfacevariable{repeat}{repete} +\setinterfacevariable{required}{recquis} +\setinterfacevariable{reset}{raz} +\setinterfacevariable{reverse}{inverse} +\setinterfacevariable{right}{droite} +\setinterfacevariable{rightedge}{borddroit} +\setinterfacevariable{righthanging}{righthanging} +\setinterfacevariable{rightmargin}{margedroite} +\setinterfacevariable{rightpage}{pagedroite} +\setinterfacevariable{righttoleft}{righttoleft} +\setinterfacevariable{roman}{roman} +\setinterfacevariable{romannumerals}{chiffresromains} +\setinterfacevariable{rotate}{oriente} +\setinterfacevariable{rotated}{tourne} +\setinterfacevariable{round}{rond} +\setinterfacevariable{row}{rang} +\setinterfacevariable{rule}{regle} +\setinterfacevariable{samepage}{memepage} +\setinterfacevariable{sans}{sans} +\setinterfacevariable{sansbold}{sansgras} +\setinterfacevariable{sansserif}{sansserif} +\setinterfacevariable{saturday}{samedi} +\setinterfacevariable{screen}{ecran} +\setinterfacevariable{section}{section} +\setinterfacevariable{sectionblockenvironment}{environementblocsection} +\setinterfacevariable{sectionnumber}{numerosection} +\setinterfacevariable{see}{voit} +\setinterfacevariable{september}{septembre} +\setinterfacevariable{serif}{serif} +\setinterfacevariable{serried}{serried} +\setinterfacevariable{setups}{reglages} +\setinterfacevariable{sheet}{sheet} +\setinterfacevariable{short}{short} +\setinterfacevariable{singlesided}{recto} +\setinterfacevariable{slanted}{incline} +\setinterfacevariable{slantedbold}{grasincline} +\setinterfacevariable{small}{petit} +\setinterfacevariable{smallbodyfont}{petitepolicecorps} +\setinterfacevariable{smallbold}{graspetit} +\setinterfacevariable{smallbolditalic}{italiquegraspetit} +\setinterfacevariable{smallboldslanted}{inclinegraspetit} +\setinterfacevariable{smallcaps}{petitescapitales} +\setinterfacevariable{smallitalic}{italiquepetit} +\setinterfacevariable{smallitalicbold}{grasitaliquepetit} +\setinterfacevariable{smallnormal}{normalpetit} +\setinterfacevariable{smallslanted}{inclinepetit} +\setinterfacevariable{smallslantedbold}{grasinclinepetit} +\setinterfacevariable{smalltype}{petittype} +\setinterfacevariable{somewhere}{qqpart} +\setinterfacevariable{sorted}{trie} +\setinterfacevariable{space}{espace} +\setinterfacevariable{spacing}{espacement} +\setinterfacevariable{speech}{discours} +\setinterfacevariable{split}{split} +\setinterfacevariable{spot}{spot} +\setinterfacevariable{standard}{standard} +\setinterfacevariable{start}{demarre} +\setinterfacevariable{starter}{starter} +\setinterfacevariable{sticker}{sticker} +\setinterfacevariable{stop}{stoppe} +\setinterfacevariable{stopper}{stopper} +\setinterfacevariable{stretch}{etire} +\setinterfacevariable{strict}{strict} +\setinterfacevariable{strong}{strong} +\setinterfacevariable{strut}{strut} +\setinterfacevariable{sub}{sous} +\setinterfacevariable{subbackward}{sousretourarriere} +\setinterfacevariable{subformula}{subformule} +\setinterfacevariable{subforward}{sousavance} +\setinterfacevariable{subject}{sujet} +\setinterfacevariable{subpage}{souspage} +\setinterfacevariable{subsection}{soussection} +\setinterfacevariable{subsubject}{soussujet} +\setinterfacevariable{subsubsection}{soussoussection} +\setinterfacevariable{subsubsubject}{soussoussujet} +\setinterfacevariable{subsubsubsection}{soussoussoussection} +\setinterfacevariable{subsubsubsubject}{soussoussoussujet} +\setinterfacevariable{subsubsubsubsection}{soussoussoussoussection} +\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} +\setinterfacevariable{symbol}{symbole} +\setinterfacevariable{synchronize}{synchronize} +\setinterfacevariable{system}{systeme} +\setinterfacevariable{table}{tableau} +\setinterfacevariable{tablehead}{tetetableau} +\setinterfacevariable{tables}{tables} +\setinterfacevariable{tabletail}{queuetableau} +\setinterfacevariable{tabulate}{tabule} +\setinterfacevariable{tabulatehead}{tetetabule} +\setinterfacevariable{tabulatetail}{queuetabule} +\setinterfacevariable{tall}{long} +\setinterfacevariable{teletype}{teletype} +\setinterfacevariable{temporary}{temporaire} +\setinterfacevariable{test}{test} +\setinterfacevariable{text}{texte} +\setinterfacevariable{three}{trois} +\setinterfacevariable{thursday}{jeudi} +\setinterfacevariable{title}{titre} +\setinterfacevariable{toggle}{toggle} +\setinterfacevariable{tolerant}{tolerant} +\setinterfacevariable{top}{sup} +\setinterfacevariable{tuesday}{mardi} +\setinterfacevariable{two}{deux} +\setinterfacevariable{txt}{txt} +\setinterfacevariable{type}{type} +\setinterfacevariable{typing}{typing} +\setinterfacevariable{unavailable}{indisponible} +\setinterfacevariable{underbar}{souslignetout} +\setinterfacevariable{underbars}{sousligne} +\setinterfacevariable{unit}{unite} +\setinterfacevariable{units}{unites} +\setinterfacevariable{unknown}{inconnu} +\setinterfacevariable{unpacked}{degroupe} +\setinterfacevariable{up}{up} +\setinterfacevariable{url}{url} +\setinterfacevariable{used}{used} +\setinterfacevariable{value}{valeur} +\setinterfacevariable{vertical}{verticale} +\setinterfacevariable{very}{tres} +\setinterfacevariable{verystrict}{tresstrict} +\setinterfacevariable{verytolerant}{trestolerant} +\setinterfacevariable{weak}{weak} +\setinterfacevariable{wednesday}{mercredi} +\setinterfacevariable{week}{semaine} +\setinterfacevariable{weekday}{joursemaine} +\setinterfacevariable{white}{blanc} +\setinterfacevariable{wide}{ample} +\setinterfacevariable{width}{largeur} +\setinterfacevariable{xml}{xml} +\setinterfacevariable{year}{annee} +\setinterfacevariable{yes}{oui} +% definitions for interface constants for language fr +% +\setinterfaceconstant{action}{action} +\setinterfaceconstant{address}{adresse} +\setinterfaceconstant{after}{apres} +\setinterfaceconstant{afterhead}{aprestete} +\setinterfaceconstant{afterkey}{aprescle} +\setinterfaceconstant{align}{alignement} +\setinterfaceconstant{aligncharacter}{caracterealigne} +\setinterfaceconstant{alignmentcharacter}{alignementcaractere} +\setinterfaceconstant{alignsymbol}{alignsymbol} +\setinterfaceconstant{aligntitle}{alignementtitre} +\setinterfaceconstant{alternative}{alternative} +\setinterfaceconstant{andtext}{andtext} +\setinterfaceconstant{apa}{apa} +\setinterfaceconstant{arrow}{fleche} +\setinterfaceconstant{artauthor}{artauthor} +\setinterfaceconstant{artauthoretaldisplay}{artauthoretaldisplay} +\setinterfaceconstant{artauthoretallimit}{artauthoretallimit} +\setinterfaceconstant{artauthoretaltext}{artauthoretaltext} +\setinterfaceconstant{at}{a} +\setinterfaceconstant{author}{auteur} +\setinterfaceconstant{authoretaldisplay}{authoretaldisplay} +\setinterfaceconstant{authoretallimit}{authoretallimit} +\setinterfaceconstant{authoretaltext}{authoretaltext} +\setinterfaceconstant{auto}{auto} +\setinterfaceconstant{autofile}{autofile} +\setinterfaceconstant{autofocus}{autofocus} +\setinterfaceconstant{autohang}{autohang} +\setinterfaceconstant{autostrut}{autostrut} +\setinterfaceconstant{autowidth}{autolargeur} +\setinterfaceconstant{axis}{axe} +\setinterfaceconstant{background}{arriereplan} +\setinterfaceconstant{backgroundcolor}{couleurarriereplan} +\setinterfaceconstant{backgroundcorner}{coinarriereplan} +\setinterfaceconstant{backgrounddepth}{profondeurarriereplan} +\setinterfaceconstant{backgroundoffset}{decalagearriereplan} +\setinterfaceconstant{backgroundradius}{rayonarriereplan} +\setinterfaceconstant{backgroundscreen}{ecranarriereplan} +\setinterfaceconstant{backspace}{retour} +\setinterfaceconstant{balance}{equilibre} +\setinterfaceconstant{before}{avant} +\setinterfaceconstant{beforehead}{avanttete} +\setinterfaceconstant{bet}{bet} +\setinterfaceconstant{big}{grand} +\setinterfaceconstant{blank}{vide} +\setinterfaceconstant{blockway}{blockway} +\setinterfaceconstant{bodyfont}{policecorps} +\setinterfaceconstant{bookmark}{marquepage} +\setinterfaceconstant{bottom}{inf} +\setinterfaceconstant{bottomafter}{bottomafter} +\setinterfaceconstant{bottombefore}{bottombefore} +\setinterfaceconstant{bottomdistance}{distanceinf} +\setinterfaceconstant{bottomframe}{cadreinf} +\setinterfaceconstant{bottomoffset}{decalageinf} +\setinterfaceconstant{bottomspace}{espaceinf} +\setinterfaceconstant{bottomstate}{etatinf} +\setinterfaceconstant{cache}{cache} +\setinterfaceconstant{calculate}{calculer} +\setinterfaceconstant{ccommand}{ccommande} +\setinterfaceconstant{click}{clic} +\setinterfaceconstant{clickin}{clicinterieur} +\setinterfaceconstant{clickout}{clicexterieur} +\setinterfaceconstant{clipoffset}{clipoffset} +\setinterfaceconstant{closeaction}{actionfermeture} +\setinterfaceconstant{closecommand}{closecommand} +\setinterfaceconstant{closepageaction}{actionfermeturepage} +\setinterfaceconstant{closesymbol}{closesymbol} +\setinterfaceconstant{color}{couleur} +\setinterfaceconstant{column}{colonne} +\setinterfaceconstant{columndistance}{distancecolonne} +\setinterfaceconstant{columns}{colonnes} +\setinterfaceconstant{command}{commande} +\setinterfaceconstant{commandafter}{commandeapres} +\setinterfaceconstant{commandbefore}{commandeavant} +\setinterfaceconstant{commands}{commandes} +\setinterfaceconstant{component}{composant} +\setinterfaceconstant{compoundhyphen}{compoundhyphen} +\setinterfaceconstant{compress}{compress} +\setinterfaceconstant{connector}{connector} +\setinterfaceconstant{continue}{continue} +\setinterfaceconstant{contrastcolor}{coleurcontraste} +\setinterfaceconstant{controls}{controles} +\setinterfaceconstant{conversion}{conversion} +\setinterfaceconstant{convertfile}{conversionfichier} +\setinterfaceconstant{corner}{coin} +\setinterfaceconstant{coupling}{couplage} +\setinterfaceconstant{couplingway}{modecouplage} +\setinterfaceconstant{criterium}{critere} +\setinterfaceconstant{current}{courant} +\setinterfaceconstant{cutspace}{cutspace} +\setinterfaceconstant{dash}{pointille} +\setinterfaceconstant{dat}{dat} +\setinterfaceconstant{database}{database} +\setinterfaceconstant{date}{date} +\setinterfaceconstant{deepnumbercommand}{deepnumbercommand} +\setinterfaceconstant{deeptextcommand}{deeptextcommand} +\setinterfaceconstant{default}{defaut} +\setinterfaceconstant{delay}{delai} +\setinterfaceconstant{depth}{profondeur} +\setinterfaceconstant{depthcorrection}{correctionprofondeur} +\setinterfaceconstant{direction}{direction} +\setinterfaceconstant{directory}{repertoire} +\setinterfaceconstant{display}{affichage} +\setinterfaceconstant{distance}{distance} +\setinterfaceconstant{dot}{point} +\setinterfaceconstant{doublesided}{rectoverso} +\setinterfaceconstant{dummy}{dummy} +\setinterfaceconstant{dx}{dx} +\setinterfaceconstant{dy}{dy} +\setinterfaceconstant{edge}{bord} +\setinterfaceconstant{edgedistance}{distancebord} +\setinterfaceconstant{editor}{editor} +\setinterfaceconstant{editoretaldisplay}{editoretaldisplay} +\setinterfaceconstant{editoretallimit}{editoretallimit} +\setinterfaceconstant{editoretaltext}{editoretaltext} +\setinterfaceconstant{empty}{vide} +\setinterfaceconstant{equalheight}{equalheight} +\setinterfaceconstant{equalwidth}{equalwidth} +\setinterfaceconstant{escape}{escape} +\setinterfaceconstant{evenmargin}{margepaire} +\setinterfaceconstant{expansion}{expansion} +\setinterfaceconstant{export}{export} +\setinterfaceconstant{extras}{extras} +\setinterfaceconstant{factor}{facteur} +\setinterfaceconstant{fallback}{fallback} +\setinterfaceconstant{family}{famille} +\setinterfaceconstant{fieldbackgroundcolor}{couleurarrierreplanchamp} +\setinterfaceconstant{fieldframecolor}{couleurcadrechamp} +\setinterfaceconstant{fieldlayer}{calquechamp} +\setinterfaceconstant{fieldoffset}{offsetchamp} +\setinterfaceconstant{file}{fichier} +\setinterfaceconstant{filtercommand}{filtercommand} +\setinterfaceconstant{finalnamesep}{finalnamesep} +\setinterfaceconstant{firstnamesep}{firstnamesep} +\setinterfaceconstant{focus}{focus} +\setinterfaceconstant{focusin}{focusin} +\setinterfaceconstant{focusout}{focusout} +\setinterfaceconstant{footer}{pdp} +\setinterfaceconstant{footerdistance}{dsitancepdp} +\setinterfaceconstant{footerstate}{etatpdp} +\setinterfaceconstant{foregroundcolor}{couleurpremierplan} +\setinterfaceconstant{foregroundstyle}{stylepremierplan} +\setinterfaceconstant{format}{formatter} +\setinterfaceconstant{frame}{cadre} +\setinterfaceconstant{framecolor}{couleurcadre} +\setinterfaceconstant{framecorner}{coincadre} +\setinterfaceconstant{framedepth}{profondeurcadre} +\setinterfaceconstant{frameoffset}{decalagecadre} +\setinterfaceconstant{frameradius}{rayoncadre} +\setinterfaceconstant{frames}{cadres} +\setinterfaceconstant{from}{de} +\setinterfaceconstant{get}{obtient} +\setinterfaceconstant{global}{global} +\setinterfaceconstant{grid}{grille} +\setinterfaceconstant{hang}{suspend} +\setinterfaceconstant{headalign}{headalign} +\setinterfaceconstant{headcolor}{couleurtete} +\setinterfaceconstant{headcommand}{commandetete} +\setinterfaceconstant{headconversion}{conversiontete} +\setinterfaceconstant{header}{entete} +\setinterfaceconstant{headerdistance}{distanceentete} +\setinterfaceconstant{headerstate}{etatentete} +\setinterfaceconstant{headlabel}{etiquettetete} +\setinterfaceconstant{headnumber}{numerotete} +\setinterfaceconstant{headstyle}{styletete} +\setinterfaceconstant{height}{hauteur} +\setinterfaceconstant{hfactor}{facteurhauteur} +\setinterfaceconstant{hfil}{hfil} +\setinterfaceconstant{hidenumber}{hidenumber} +\setinterfaceconstant{hoffset}{decalagehauteur} +\setinterfaceconstant{horoffset}{horoffset} +\setinterfaceconstant{hyphen}{hyphen} +\setinterfaceconstant{icommand}{icommande} +\setinterfaceconstant{in}{in} +\setinterfaceconstant{inbetween}{entre} +\setinterfaceconstant{increment}{incremente} +\setinterfaceconstant{incrementnumber}{incrementenumero} +\setinterfaceconstant{indenting}{composeenalinea} +\setinterfaceconstant{indentnext}{indentesuivant} +\setinterfaceconstant{indicator}{indicateur} +\setinterfaceconstant{inner}{interieur} +\setinterfaceconstant{innermargin}{margeinterieure} +\setinterfaceconstant{inputfile}{fichierentree} +\setinterfaceconstant{intent}{intent} +\setinterfaceconstant{interaction}{interaction} +\setinterfaceconstant{interlinespace}{espaceinterligne} +\setinterfaceconstant{itemalign}{itemalign} +\setinterfaceconstant{items}{elements} +\setinterfaceconstant{juniorsep}{juniorsep} +\setinterfaceconstant{ken}{ken} +\setinterfaceconstant{keyexpansion}{keyexpansion} +\setinterfaceconstant{keyword}{motcle} +\setinterfaceconstant{label}{etiquette} +\setinterfaceconstant{lastnamesep}{lastnamesep} +\setinterfaceconstant{lastpubsep}{lastpubsep} +\setinterfaceconstant{left}{gauche} +\setinterfaceconstant{leftcolor}{couleurgauche} +\setinterfaceconstant{leftcompoundhyphen}{leftcompoundhyphen} +\setinterfaceconstant{leftedge}{bordgauche} +\setinterfaceconstant{leftedgedistance}{distancebordgauche} +\setinterfaceconstant{leftframe}{cadregauche} +\setinterfaceconstant{lefthyphen}{lefthyphen} +\setinterfaceconstant{leftmargin}{margegauche} +\setinterfaceconstant{leftmargindistance}{distancemargegauche} +\setinterfaceconstant{leftoffset}{decalagegauche} +\setinterfaceconstant{leftquotation}{citationgauche} +\setinterfaceconstant{leftquote}{citergauche} +\setinterfaceconstant{leftsentence}{phrasegauche} +\setinterfaceconstant{leftspeech}{leftspeech} +\setinterfaceconstant{leftstyle}{leftstyle} +\setinterfaceconstant{leftsubsentence}{sousphrasegauche} +\setinterfaceconstant{lefttext}{textegauche} +\setinterfaceconstant{leftwidth}{largeurgauche} +\setinterfaceconstant{level}{niveau} +\setinterfaceconstant{levels}{niveaux} +\setinterfaceconstant{limittext}{limittext} +\setinterfaceconstant{line}{ligne} +\setinterfaceconstant{linecorrection}{correctionligne} +\setinterfaceconstant{lines}{lignes} +\setinterfaceconstant{list}{liste} +\setinterfaceconstant{listtext}{texteliste} +\setinterfaceconstant{local}{local} +\setinterfaceconstant{location}{emplacement} +\setinterfaceconstant{logo}{logo} +\setinterfaceconstant{logos}{logos} +\setinterfaceconstant{marcolor}{couleurmarquage} +\setinterfaceconstant{margin}{marge} +\setinterfaceconstant{margindistance}{distancemarge} +\setinterfaceconstant{marginedge}{bordmarge} +\setinterfaceconstant{marginedgetext}{textebordmarge} +\setinterfaceconstant{margintext}{textemarge} +\setinterfaceconstant{marking}{marquage} +\setinterfaceconstant{marstyle}{stylemarquage} +\setinterfaceconstant{max}{max} +\setinterfaceconstant{maxdepth}{maxdepth} +\setinterfaceconstant{maxheight}{hauteurmax} +\setinterfaceconstant{maxwidth}{largeurmax} +\setinterfaceconstant{maybeyear}{maybeyear} +\setinterfaceconstant{menu}{menu} +\setinterfaceconstant{method}{methode} +\setinterfaceconstant{middle}{milieu} +\setinterfaceconstant{middlespeech}{middlespeech} +\setinterfaceconstant{middletext}{textecentre} +\setinterfaceconstant{midsentence}{midsentence} +\setinterfaceconstant{min}{min} +\setinterfaceconstant{mindepth}{profondeurmin} +\setinterfaceconstant{minheight}{hauteurmin} +\setinterfaceconstant{minwidth}{largeurmin} +\setinterfaceconstant{monthconversion}{monthconversion} +\setinterfaceconstant{n}{n} +\setinterfaceconstant{name}{nom} +\setinterfaceconstant{namesep}{namesep} +\setinterfaceconstant{nbottom}{ninf} +\setinterfaceconstant{nc}{nc} +\setinterfaceconstant{next}{suivant} +\setinterfaceconstant{nl}{nl} +\setinterfaceconstant{nleft}{ngauche} +\setinterfaceconstant{nlines}{nlignes} +\setinterfaceconstant{norm}{norme} +\setinterfaceconstant{nr}{nr} +\setinterfaceconstant{nright}{ndroite} +\setinterfaceconstant{ntop}{nsup} +\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{numberstarter}{numberstarter} +\setinterfaceconstant{numberstopper}{numberstopper} +\setinterfaceconstant{numberstyle}{stylenumero} +\setinterfaceconstant{numberwidth}{numberwidth} +\setinterfaceconstant{nx}{nx} +\setinterfaceconstant{ny}{ny} +\setinterfaceconstant{object}{objet} +\setinterfaceconstant{obstruction}{obstruction} +\setinterfaceconstant{oddmargin}{margepaire} +\setinterfaceconstant{offset}{offset} +\setinterfaceconstant{openaction}{actionouverture} +\setinterfaceconstant{openpageaction}{actionouverturepage} +\setinterfaceconstant{option}{option} +\setinterfaceconstant{order}{order} +\setinterfaceconstant{orientation}{orientation} +\setinterfaceconstant{otherstext}{otherstext} +\setinterfaceconstant{outermargin}{margeexterieure} +\setinterfaceconstant{overprint}{overprint} +\setinterfaceconstant{ownnumber}{numeroproprio} +\setinterfaceconstant{page}{page} +\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{pageprefixstarter}{pageprefixstarter} +\setinterfaceconstant{pageprefixstopper}{pageprefixstopper} +\setinterfaceconstant{pagesegments}{pagesegments} +\setinterfaceconstant{pageseparatorset}{pageseparatorset} +\setinterfaceconstant{pageset}{pageset} +\setinterfaceconstant{pagestarter}{pagestarter} +\setinterfaceconstant{pagestate}{etatpage} +\setinterfaceconstant{pagestopper}{pagestopper} +\setinterfaceconstant{pagestyle}{stylepage} +\setinterfaceconstant{palet}{palette} +\setinterfaceconstant{paper}{papier} +\setinterfaceconstant{paragraph}{paragraphe} +\setinterfaceconstant{place}{place} +\setinterfaceconstant{placehead}{placetete} +\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{prefixstarter}{prefixstarter} +\setinterfaceconstant{prefixstopper}{prefixstopper} +\setinterfaceconstant{preset}{prereglage} +\setinterfaceconstant{preview}{previsualisation} +\setinterfaceconstant{previous}{precedent} +\setinterfaceconstant{previousnumber}{numeroprecedent} +\setinterfaceconstant{process}{process} +\setinterfaceconstant{pubsep}{pubsep} +\setinterfaceconstant{radius}{rayon} +\setinterfaceconstant{random}{aleatoire} +\setinterfaceconstant{range}{range} +\setinterfaceconstant{reduction}{reduction} +\setinterfaceconstant{ref}{ref} +\setinterfaceconstant{refcommand}{refcommand} +\setinterfaceconstant{reference}{reference} +\setinterfaceconstant{referenceprefix}{referenceprefix} +\setinterfaceconstant{referencing}{referencing} +\setinterfaceconstant{regionin}{entreregion} +\setinterfaceconstant{regionout}{regionexterieure} +\setinterfaceconstant{repeat}{repete} +\setinterfaceconstant{reset}{reset} +\setinterfaceconstant{resetnumber}{raznumero} +\setinterfaceconstant{resolution}{resolution} +\setinterfaceconstant{right}{droite} +\setinterfaceconstant{rightcolor}{couleurdroite} +\setinterfaceconstant{rightcompoundhyphen}{rightcompoundhyphen} +\setinterfaceconstant{rightedge}{borddroit} +\setinterfaceconstant{rightedgedistance}{distanceborddroit} +\setinterfaceconstant{rightframe}{cadredroit} +\setinterfaceconstant{righthyphen}{righthyphen} +\setinterfaceconstant{rightmargin}{margedroite} +\setinterfaceconstant{rightmargindistance}{distancemargedroite} +\setinterfaceconstant{rightoffset}{rightoffset} +\setinterfaceconstant{rightquotation}{citationdroite} +\setinterfaceconstant{rightquote}{citerdroite} +\setinterfaceconstant{rightsentence}{phrasedroite} +\setinterfaceconstant{rightspeech}{rightspeech} +\setinterfaceconstant{rightstyle}{styledroit} +\setinterfaceconstant{rightsubsentence}{sousphrasedroite} +\setinterfaceconstant{righttext}{textedroit} +\setinterfaceconstant{rightwidth}{largeurdroite} +\setinterfaceconstant{rotation}{rotation} +\setinterfaceconstant{rule}{ligne} +\setinterfaceconstant{rulecolor}{couleurligne} +\setinterfaceconstant{rulethickness}{epaisseurligne} +\setinterfaceconstant{samepage}{memepage} +\setinterfaceconstant{sample}{echantillon} +\setinterfaceconstant{samplesize}{samplesize} +\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{sectionresetset}{sectionresetset} +\setinterfaceconstant{sectionsegments}{sectionsegments} +\setinterfaceconstant{sectionseparatorset}{sectionseparatorset} +\setinterfaceconstant{sectionset}{sectionset} +\setinterfaceconstant{sectionstarter}{sectionstarter} +\setinterfaceconstant{sectionstopper}{sectionstopper} +\setinterfaceconstant{separator}{separateur} +\setinterfaceconstant{set}{set} +\setinterfaceconstant{setups}{reglages} +\setinterfaceconstant{side}{cote} +\setinterfaceconstant{sidealign}{sidealign} +\setinterfaceconstant{sidemethod}{sidemethod} +\setinterfaceconstant{sidespaceafter}{espacelateralapres} +\setinterfaceconstant{sidespacebefore}{espacelateralavant} +\setinterfaceconstant{sign}{signe} +\setinterfaceconstant{size}{dimension} +\setinterfaceconstant{small}{petit} +\setinterfaceconstant{sort}{sort} +\setinterfaceconstant{sorttype}{sorttype} +\setinterfaceconstant{source}{origine} +\setinterfaceconstant{space}{espace} +\setinterfaceconstant{spaceafter}{espaceapres} +\setinterfaceconstant{spacebefore}{espaceavant} +\setinterfaceconstant{spaceinbetween}{spaceinbetween} +\setinterfaceconstant{spacing}{espacement} +\setinterfaceconstant{split}{split} +\setinterfaceconstant{splitcolor}{splitcolor} +\setinterfaceconstant{splitmethod}{splitmethod} +\setinterfaceconstant{splitoffset}{splitoffset} +\setinterfaceconstant{spot}{spot} +\setinterfaceconstant{stack}{stack} +\setinterfaceconstant{start}{demarre} +\setinterfaceconstant{starter}{starter} +\setinterfaceconstant{state}{etat} +\setinterfaceconstant{step}{pas} +\setinterfaceconstant{stop}{stoppe} +\setinterfaceconstant{stopper}{taquet} +\setinterfaceconstant{stretch}{etire} +\setinterfaceconstant{strip}{strip} +\setinterfaceconstant{strut}{strut} +\setinterfaceconstant{style}{style} +\setinterfaceconstant{sub}{sous} +\setinterfaceconstant{subtitle}{soustitre} +\setinterfaceconstant{suffix}{suffix} +\setinterfaceconstant{surnamesep}{surnamesep} +\setinterfaceconstant{sx}{sx} +\setinterfaceconstant{sy}{sy} +\setinterfaceconstant{symalign}{symalignement} +\setinterfaceconstant{symbol}{symbole} +\setinterfaceconstant{symbolset}{jeusymbole} +\setinterfaceconstant{symcolor}{couleursym} +\setinterfaceconstant{symstyle}{stylesym} +\setinterfaceconstant{synonym}{synonyme} +\setinterfaceconstant{synonymcolor}{couleursynonyme} +\setinterfaceconstant{synonymcommand}{synonymcommand} +\setinterfaceconstant{synonymstyle}{stylesynonyme} +\setinterfaceconstant{tab}{tab} +\setinterfaceconstant{text}{texte} +\setinterfaceconstant{textcolor}{couleurtexte} +\setinterfaceconstant{textcommand}{commandetexte} +\setinterfaceconstant{textdistance}{distancetexte} +\setinterfaceconstant{textlayer}{calquetexte} +\setinterfaceconstant{textmargin}{margetexte} +\setinterfaceconstant{textmethod}{textmethod} +\setinterfaceconstant{textseparator}{separateurtexte} +\setinterfaceconstant{textsize}{tailletexte} +\setinterfaceconstant{textstate}{etattexte} +\setinterfaceconstant{textstyle}{styletexte} +\setinterfaceconstant{textwidth}{largeurtexte} +\setinterfaceconstant{title}{titre} +\setinterfaceconstant{titlecolor}{couleurtitre} +\setinterfaceconstant{titlecommand}{titlecommand} +\setinterfaceconstant{titledistance}{distancetitre} +\setinterfaceconstant{titleleft}{titleleft} +\setinterfaceconstant{titleright}{titleright} +\setinterfaceconstant{titlestyle}{styletitre} +\setinterfaceconstant{to}{vers} +\setinterfaceconstant{tolerance}{tolerance} +\setinterfaceconstant{top}{sup} +\setinterfaceconstant{topdistance}{distancesup} +\setinterfaceconstant{topframe}{cadresup} +\setinterfaceconstant{topoffset}{decalagesup} +\setinterfaceconstant{topspace}{espacesup} +\setinterfaceconstant{topstate}{etatsup} +\setinterfaceconstant{totalnumber}{totalnumber} +\setinterfaceconstant{type}{type} +\setinterfaceconstant{unit}{unite} +\setinterfaceconstant{unknownreference}{referenceinconnue} +\setinterfaceconstant{urlalternative}{alternativeurl} +\setinterfaceconstant{urlspace}{espaceurl} +\setinterfaceconstant{validate}{valider} +\setinterfaceconstant{vcommand}{vcommande} +\setinterfaceconstant{veroffset}{veroffset} +\setinterfaceconstant{vfil}{vfil} +\setinterfaceconstant{voffset}{voffset} +\setinterfaceconstant{vonsep}{vonsep} +\setinterfaceconstant{way}{mode} +\setinterfaceconstant{wfactor}{facteurlargeur} +\setinterfaceconstant{white}{blanc} +\setinterfaceconstant{width}{largeur} +\setinterfaceconstant{xfactor}{xfactor} +\setinterfaceconstant{xmax}{xmax} +\setinterfaceconstant{xoffset}{xoffset} +\setinterfaceconstant{xscale}{xscale} +\setinterfaceconstant{xstep}{xstep} +\setinterfaceconstant{yfactor}{yfactor} +\setinterfaceconstant{ymax}{ymax} +\setinterfaceconstant{yoffset}{yoffset} +\setinterfaceconstant{yscale}{yscale} +\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} +\setinterfaceelement{currentlocal}{localcourant} +\setinterfaceelement{emptyone}{vide} +\setinterfaceelement{emptytwo}{vide} +\setinterfaceelement{end}{fin} +\setinterfaceelement{endsetup}{} +\setinterfaceelement{get}{obtient} +\setinterfaceelement{increment}{incremente} +\setinterfaceelement{list}{liste} +\setinterfaceelement{listof}{listede} +\setinterfaceelement{load}{charge} +\setinterfaceelement{local}{local} +\setinterfaceelement{makeup}{makeup} +\setinterfaceelement{next}{suivant} +\setinterfaceelement{place}{place} +\setinterfaceelement{previous}{precedent} +\setinterfaceelement{previouslocal}{localprecedent} +\setinterfaceelement{reserve}{reserver} +\setinterfaceelement{see}{voit} +\setinterfaceelement{setup}{regle} +\setinterfaceelement{start}{demarre} +\setinterfaceelement{stop}{stoppe} +\setinterfaceelement{text}{texte} +\setinterfaceelement{type}{type} +% definitions for interface commands for language fr +% +\setinterfacecommand{CAPPED}{CAP} +\setinterfacecommand{Character}{Caractere} +\setinterfacecommand{Characters}{Caracteres} +\setinterfacecommand{LABELTEXT}{LABELTEXTE} +\setinterfacecommand{MONTH}{MOIS} +\setinterfacecommand{Numbers}{Numeros} +\setinterfacecommand{Romannumerals}{Chiffresromains} +\setinterfacecommand{SmallCapped}{Cap} +\setinterfacecommand{SmallCaps}{Caps} +\setinterfacecommand{WEEKDAY}{JOURSEMAINE} +\setinterfacecommand{WORD}{MOT} +\setinterfacecommand{WORDS}{MOTS} +\setinterfacecommand{Word}{Mot} +\setinterfacecommand{Words}{Mots} +\setinterfacecommand{about}{concernant} +\setinterfacecommand{adaptlayout}{adaptedisposition} +\setinterfacecommand{arg}{arg} +\setinterfacecommand{at}{a} +\setinterfacecommand{atleftmargin}{atleftmargin} +\setinterfacecommand{atpage}{alapage} +\setinterfacecommand{atrightmargin}{atrightmargin} +\setinterfacecommand{background}{arriereplan} +\setinterfacecommand{backspace}{retourarriere} +\setinterfacecommand{blackrule}{lignenoire} +\setinterfacecommand{blackrules}{lignesnoires} +\setinterfacecommand{blank}{vide} +\setinterfacecommand{bookmark}{marquepage} +\setinterfacecommand{bottomdistance}{distanceinf} +\setinterfacecommand{bottomheight}{hauteurinf} +\setinterfacecommand{bottomspace}{espaceinf} +\setinterfacecommand{but}{but} +\setinterfacecommand{button}{bouton} +\setinterfacecommand{bypassblocks}{sauteblocs} +\setinterfacecommand{character}{caractere} +\setinterfacecommand{characters}{caracteres} +\setinterfacecommand{chem}{chem} +\setinterfacecommand{clip}{clip} +\setinterfacecommand{clonefield}{clonechamp} +\setinterfacecommand{color}{couleur} +\setinterfacecommand{colorbar}{barrecouleur} +\setinterfacecommand{colorvalue}{valeurcouleur} +\setinterfacecommand{column}{colonne} +\setinterfacecommand{comment}{commentaire} +\setinterfacecommand{comparecolorgroup}{comparegroupecouleur} +\setinterfacecommand{comparepalet}{comparepalette} +\setinterfacecommand{completepagenumber}{completenumeropage} +\setinterfacecommand{completeregister}{completeregistre} +\setinterfacecommand{component}{composant} +\setinterfacecommand{convertnumber}{convertitnumero} +\setinterfacecommand{copyfield}{copitchamp} +\setinterfacecommand{correctwhitespace}{corrigeespaceblanc} +\setinterfacecommand{coupledocument}{coupledocument} +\setinterfacecommand{couplemarking}{couplemarquage} +\setinterfacecommand{couplepage}{pagedouble} +\setinterfacecommand{couplepaper}{couplepapier} +\setinterfacecommand{coupleregister}{coupleregistre} +\setinterfacecommand{crlf}{crlf} +\setinterfacecommand{currentdate}{datecourante} +\setinterfacecommand{currentheadnumber}{numerotetecourant} +\setinterfacecommand{cutspace}{cutspace} +\setinterfacecommand{date}{date} +\setinterfacecommand{decouplemarking}{decouplemarquage} +\setinterfacecommand{decrementnumber}{decrementenumero} +\setinterfacecommand{define}{definit} +\setinterfacecommand{defineaccent}{definitaccent} +\setinterfacecommand{defineblank}{definitvide} +\setinterfacecommand{defineblock}{definitbloc} +\setinterfacecommand{definebodyfont}{definitpolicecorps} +\setinterfacecommand{definebodyfontenvironment}{definitenvironnementpolicecorps} +\setinterfacecommand{definebuffer}{definitbuffer} +\setinterfacecommand{definecharacter}{definicaractere} +\setinterfacecommand{definecolor}{definitcouleur} +\setinterfacecommand{definecolorgroup}{definitgroupecouleur} +\setinterfacecommand{definecolumnbreak}{definitsautdecolonne} +\setinterfacecommand{definecolumnset}{definitjeucolonne} +\setinterfacecommand{definecombination}{definecombination} +\setinterfacecommand{definecombinedlist}{definitlisteimbriquee} +\setinterfacecommand{definecommand}{definitcommande} +\setinterfacecommand{defineconversion}{definitconversion} +\setinterfacecommand{definedescription}{definitdescription} +\setinterfacecommand{defineenumeration}{definitenumeration} +\setinterfacecommand{definefield}{definitchamp} +\setinterfacecommand{definefieldstack}{definitpilechamp} +\setinterfacecommand{definefiguresymbol}{definitsymbolefigure} +\setinterfacecommand{definefloat}{definitflottant} +\setinterfacecommand{definefont}{definitpolice} +\setinterfacecommand{definefontstyle}{definitstylepolice} +\setinterfacecommand{definefontsynonym}{definitsynonymepolice} +\setinterfacecommand{defineframed}{defineframed} +\setinterfacecommand{defineframedtext}{defineframedtext} +\setinterfacecommand{definehbox}{definithbox} +\setinterfacecommand{definehead}{definittete} +\setinterfacecommand{defineindenting}{definitcompoalinea} +\setinterfacecommand{defineinmargin}{definitdansmarge} +\setinterfacecommand{defineinteractionmenu}{definitmenuinteraction} +\setinterfacecommand{defineitemgroup}{defineitemgroup} +\setinterfacecommand{definelabel}{definitetiquette} +\setinterfacecommand{definelayer}{definitcalque} +\setinterfacecommand{definelayout}{definitdisposition} +\setinterfacecommand{definelist}{definitliste} +\setinterfacecommand{definelogo}{definitlogo} +\setinterfacecommand{definemainfield}{definitchampprincipal} +\setinterfacecommand{definemakeup}{definitmakeup} +\setinterfacecommand{definemarking}{definitmarquage} +\setinterfacecommand{definemathalignment}{definemathalignment} +\setinterfacecommand{defineoutput}{definitsortie} +\setinterfacecommand{defineoverlay}{definitrevetement} +\setinterfacecommand{definepagebreak}{definitsautdepage} +\setinterfacecommand{definepalet}{definitpalette} +\setinterfacecommand{definepapersize}{definittaillepapier} +\setinterfacecommand{defineparagraphs}{definitparagraphes} +\setinterfacecommand{defineplacement}{defineplacement} +\setinterfacecommand{defineprofile}{definitprofil} +\setinterfacecommand{defineprogram}{definitprogramme} +\setinterfacecommand{definerawfont}{definitpolicebrute} +\setinterfacecommand{definereference}{definitreference} +\setinterfacecommand{definereferenceformat}{definitformatreference} +\setinterfacecommand{definereferencelist}{definitlistereference} +\setinterfacecommand{defineregister}{definitregistre} +\setinterfacecommand{definerule}{definitregle} +\setinterfacecommand{definesection}{definitsection} +\setinterfacecommand{definesectionblock}{definitblocsection} +\setinterfacecommand{definesorting}{definittri} +\setinterfacecommand{definestartstop}{definitdemarrestoppe} +\setinterfacecommand{definestyle}{definitstyle} +\setinterfacecommand{definesubfield}{definitsouschamp} +\setinterfacecommand{definesymbol}{definitsymbole} +\setinterfacecommand{definesynonyms}{definitsynonymes} +\setinterfacecommand{definetabletemplate}{definittrametableau} +\setinterfacecommand{definetabulate}{definittabulation} +\setinterfacecommand{definetext}{definittexte} +\setinterfacecommand{definetextposition}{definitpositiontexte} +\setinterfacecommand{definetextvariable}{definitvariabletexte} +\setinterfacecommand{definetype}{definittype} +\setinterfacecommand{definetyping}{definitdactylo} +\setinterfacecommand{defineversion}{definitversion} +\setinterfacecommand{determineheadnumber}{determinenumerotete} +\setinterfacecommand{determinelistcharacteristics}{determinecaracteristiqueliste} +\setinterfacecommand{determineregistercharacteristics}{determinecaracteristiquesregistre} +\setinterfacecommand{dimension}{dimension} +\setinterfacecommand{disableinteractionmenu}{inhibemenuinteraction} +\setinterfacecommand{domicile}{domicile} +\setinterfacecommand{donttest}{sanstest} +\setinterfacecommand{edgedistance}{distancebord} +\setinterfacecommand{edgewidth}{largeurbord} +\setinterfacecommand{emptylines}{emptylines} +\setinterfacecommand{environment}{environement} +\setinterfacecommand{externalfigure}{figureexterne} +\setinterfacecommand{fact}{fait} +\setinterfacecommand{field}{champ} +\setinterfacecommand{fieldstack}{pilechamp} +\setinterfacecommand{fillinfield}{remplitchamp} +\setinterfacecommand{fillinline}{remplitligne} +\setinterfacecommand{fillinrules}{remplitlignesreglees} +\setinterfacecommand{fillintext}{remplittexte} +\setinterfacecommand{fitfield}{ajustechamp} +\setinterfacecommand{fixedspace}{espacefixe} +\setinterfacecommand{fixedspaces}{espacesfixes} +\setinterfacecommand{followprofile}{suivantprofil} +\setinterfacecommand{followprofileversion}{suivantversionprofil} +\setinterfacecommand{followversion}{suivantversion} +\setinterfacecommand{footerdistance}{distancepdp} +\setinterfacecommand{footerheight}{hauteurpdp} +\setinterfacecommand{footnote}{notepdp} +\setinterfacecommand{footnotetext}{textenotepdp} +\setinterfacecommand{forceblocks}{forceblocs} +\setinterfacecommand{formulanumber}{numeroformule} +\setinterfacecommand{fraction}{fraction} +\setinterfacecommand{framed}{framed} +\setinterfacecommand{from}{de} +\setinterfacecommand{getbuffer}{prendbuffer} +\setinterfacecommand{getmarking}{obtientmarquage} +\setinterfacecommand{getnumber}{getnumber} +\setinterfacecommand{godown}{vaenbas} +\setinterfacecommand{goto}{va} +\setinterfacecommand{gotobox}{vaalaboite} +\setinterfacecommand{gotopage}{vaalapage} +\setinterfacecommand{graycolor}{couleurgrise} +\setinterfacecommand{greyvalue}{valeurgris} +\setinterfacecommand{grid}{grille} +\setinterfacecommand{hairline}{ligneh} +\setinterfacecommand{head}{tete} +\setinterfacecommand{headerdistance}{distanceentete} +\setinterfacecommand{headerheight}{hauteurentete} +\setinterfacecommand{headlevel}{niveautete} +\setinterfacecommand{headnumber}{numerotete} +\setinterfacecommand{headsym}{headsym} +\setinterfacecommand{headtext}{textetete} +\setinterfacecommand{hideblocks}{cacheblocs} +\setinterfacecommand{high}{haut} +\setinterfacecommand{hl}{hl} +\setinterfacecommand{immediatebetweenlist}{immediatebetweenlist} +\setinterfacecommand{immediatetolist}{immediatetolist} +\setinterfacecommand{in}{dans} +\setinterfacecommand{incrementnumber}{incrementenumero} +\setinterfacecommand{indenting}{composeenalinea} +\setinterfacecommand{inframed}{inframed} +\setinterfacecommand{infull}{infull} +\setinterfacecommand{ininner}{ininner} +\setinterfacecommand{inleft}{dansgauche} +\setinterfacecommand{inleftedge}{dansbordgauche} +\setinterfacecommand{inleftmargin}{dansmargegauche} +\setinterfacecommand{inline}{alaligne} +\setinterfacecommand{inmargin}{dansmarge} +\setinterfacecommand{inmframed}{inmframed} +\setinterfacecommand{inneredgedistance}{inneredgedistance} +\setinterfacecommand{inneredgewidth}{inneredgewidth} +\setinterfacecommand{innermargindistance}{innermargindistance} +\setinterfacecommand{innermarginwidth}{innermarginwidth} +\setinterfacecommand{inothermargin}{dansautremarge} +\setinterfacecommand{inouter}{inouter} +\setinterfacecommand{inright}{dansdroite} +\setinterfacecommand{inrightedge}{dansborddroit} +\setinterfacecommand{inrightmargin}{dansmargedroite} +\setinterfacecommand{installlanguage}{installelangue} +\setinterfacecommand{interactionbar}{barreinteraction} +\setinterfacecommand{interactionbuttons}{boutonsinteraction} +\setinterfacecommand{interactionmenu}{menuinteraction} +\setinterfacecommand{item}{element} +\setinterfacecommand{items}{elements} +\setinterfacecommand{its}{el} +\setinterfacecommand{keepblocks}{gardeblocs} +\setinterfacecommand{label}{etiquette} +\setinterfacecommand{labels}{etiquettes} +\setinterfacecommand{labeltext}{labeltexte} +\setinterfacecommand{language}{langue} +\setinterfacecommand{leftaligned}{aligneagauche} +\setinterfacecommand{leftedgedistance}{distancebordgauche} +\setinterfacecommand{leftedgewidth}{largeurbordgauche} +\setinterfacecommand{leftmargindistance}{distancemargegauche} +\setinterfacecommand{leftmarginwidth}{largeurmargegauche} +\setinterfacecommand{leg}{leg} +\setinterfacecommand{linewidth}{largeurligne} +\setinterfacecommand{listheight}{hauteurliste} +\setinterfacecommand{listlength}{llongueurliste} +\setinterfacecommand{listsymbol}{listesymbole} +\setinterfacecommand{listwidth}{largeurliste} +\setinterfacecommand{logfields}{logchamp} +\setinterfacecommand{lohi}{baha} +\setinterfacecommand{low}{bas} +\setinterfacecommand{macroname}{nommacro} +\setinterfacecommand{mainlanguage}{langueprincipale} +\setinterfacecommand{makeupheight}{hauteurmakeup} +\setinterfacecommand{makeupwidth}{largeurmakeup} +\setinterfacecommand{mar}{mar} +\setinterfacecommand{margindistance}{distancemarge} +\setinterfacecommand{marginrule}{margereglee} +\setinterfacecommand{margintext}{textemarge} +\setinterfacecommand{margintitle}{titremarge} +\setinterfacecommand{marginwidth}{largeurmarge} +\setinterfacecommand{marginword}{motmarge} +\setinterfacecommand{marking}{marquage} +\setinterfacecommand{markversion}{marquageversion} +\setinterfacecommand{mathematics}{mathematique} +\setinterfacecommand{menubutton}{boutonmenu} +\setinterfacecommand{mframed}{mframed} +\setinterfacecommand{midaligned}{aligneaumilieu} +\setinterfacecommand{mirror}{reflete} +\setinterfacecommand{month}{mois} +\setinterfacecommand{moveformula}{deplaceformule} +\setinterfacecommand{moveongrid}{deplacesurgrille} +\setinterfacecommand{movesidefloat}{movesidefloat} +\setinterfacecommand{navigating}{navigating} +\setinterfacecommand{nodimension}{sansdimension} +\setinterfacecommand{noheaderandfooterlines}{sanslignesenteteetpdp} +\setinterfacecommand{noindenting}{sansalinea} +\setinterfacecommand{nolist}{sansliste} +\setinterfacecommand{nomarking}{sansmarquage} +\setinterfacecommand{nomoreblocks}{pasplusdeblocs} +\setinterfacecommand{nomorefiles}{pasplusdefichiers} +\setinterfacecommand{nop}{nop} +\setinterfacecommand{nospace}{sansespace} +\setinterfacecommand{note}{note} +\setinterfacecommand{notopandbottomlines}{sanslignessupetinf} +\setinterfacecommand{notsmallcapped}{nocap} +\setinterfacecommand{nowhitespace}{sansespaceblanc} +\setinterfacecommand{numberofsubpages}{nombredesouspages} +\setinterfacecommand{numbers}{numeros} +\setinterfacecommand{outeredgedistance}{outeredgedistance} +\setinterfacecommand{outeredgewidth}{outeredgewidth} +\setinterfacecommand{outermargindistance}{outermargindistance} +\setinterfacecommand{outermarginwidth}{outermarginwidth} +\setinterfacecommand{packed}{groupe} +\setinterfacecommand{page}{page} +\setinterfacecommand{pagedepth}{pagedepth} +\setinterfacecommand{pagenumber}{numeropage} +\setinterfacecommand{pageoffset}{pageoffset} +\setinterfacecommand{pagereference}{referencepage} +\setinterfacecommand{pagetype}{tapepage} +\setinterfacecommand{paperheight}{hauteurpapier} +\setinterfacecommand{paperwidth}{largeurpapier} +\setinterfacecommand{periods}{periodes} +\setinterfacecommand{plaatsruwelijst}{placerawlist} +\setinterfacecommand{placebookmarks}{placemarquespages} +\setinterfacecommand{placecombinedlist}{placelisteinmbriquee} +\setinterfacecommand{placefloat}{placeflottant} +\setinterfacecommand{placefootnotes}{placenotespdp} +\setinterfacecommand{placeformula}{placeformule} +\setinterfacecommand{placeheadnumber}{placenumerotete} +\setinterfacecommand{placeheadtext}{placetextetete} +\setinterfacecommand{placelegend}{placelegende} +\setinterfacecommand{placelist}{placeliste} +\setinterfacecommand{placelocalfootnotes}{placenotespdplocales} +\setinterfacecommand{placelogos}{placelogos} +\setinterfacecommand{placeongrid}{placesurgrille} +\setinterfacecommand{placeontopofeachother}{placelesunsaudessusdesautres} +\setinterfacecommand{placepagenumber}{placenumeropage} +\setinterfacecommand{placereferencelist}{placelistereference} +\setinterfacecommand{placeregister}{placeregistre} +\setinterfacecommand{placerule}{placeregle} +\setinterfacecommand{placesidebyside}{placecoteacote} +\setinterfacecommand{placesubformula}{placesousformule} +\setinterfacecommand{placetextvariable}{placevariabletexte} +\setinterfacecommand{position}{position} +\setinterfacecommand{positiontext}{positionnetexte} +\setinterfacecommand{printpaperheight}{hauteureditionpapier} +\setinterfacecommand{printpaperwidth}{largeureditionpapier} +\setinterfacecommand{processblocks}{traiteblocs} +\setinterfacecommand{processpage}{traitepage} +\setinterfacecommand{product}{produit} +\setinterfacecommand{program}{programme} +\setinterfacecommand{project}{projet} +\setinterfacecommand{publication}{publication} +\setinterfacecommand{quotation}{citation} +\setinterfacecommand{quote}{citer} +\setinterfacecommand{ran}{ran} +\setinterfacecommand{redo}{refait} +\setinterfacecommand{ref}{ref} +\setinterfacecommand{reference}{reference} +\setinterfacecommand{referral}{recommandation} +\setinterfacecommand{referraldate}{daterecommandation} +\setinterfacecommand{referring}{faitreference} +\setinterfacecommand{remark}{commentaire} +\setinterfacecommand{reset}{raz} +\setinterfacecommand{resetmarking}{razmarquage} +\setinterfacecommand{resetnumber}{raznumero} +\setinterfacecommand{resettext}{resettextcontent} +\setinterfacecommand{rightaligned}{aligneadroite} +\setinterfacecommand{rightedgedistance}{distanceborddroit} +\setinterfacecommand{rightedgewidth}{largeurborddroit} +\setinterfacecommand{rightmargindistance}{distancemargedroite} +\setinterfacecommand{rightmarginwidth}{largeurmargedroite} +\setinterfacecommand{romannumerals}{chiffresromains} +\setinterfacecommand{rotate}{oriente} +\setinterfacecommand{scale}{echelle} +\setinterfacecommand{screen}{ecran} +\setinterfacecommand{selectblocks}{selectionneblocs} +\setinterfacecommand{selectpaper}{selectionnepapier} +\setinterfacecommand{selectversion}{selectionneversion} +\setinterfacecommand{setnumber}{affectenumero} +\setinterfacecommand{settextcontent}{settext} +\setinterfacecommand{settextvariable}{affectevariabletexte} +\setinterfacecommand{setupalign}{reglealignement} +\setinterfacecommand{setupanswerarea}{setupanswerarea} +\setinterfacecommand{setuparranging}{reglearrangement} +\setinterfacecommand{setupbackground}{reglearriereplan} +\setinterfacecommand{setupbackgrounds}{reglearriereplans} +\setinterfacecommand{setupblackrules}{reglelignesnoires} +\setinterfacecommand{setupblank}{definitvide} +\setinterfacecommand{setupblock}{reglebloc} +\setinterfacecommand{setupbodyfont}{reglepolicecorps} +\setinterfacecommand{setupbodyfontenvironment}{regleenvironnementpolicecorps} +\setinterfacecommand{setupbottom}{regleinf} +\setinterfacecommand{setupbottomtexts}{regletextesinf} +\setinterfacecommand{setupbuffer}{reglebuffer} +\setinterfacecommand{setupbuttons}{regleboutons} +\setinterfacecommand{setupcapitals}{reglecapitales} +\setinterfacecommand{setupcaption}{regleintitule} +\setinterfacecommand{setupcaptions}{regleintitules} +\setinterfacecommand{setupclipping}{regleclipping} +\setinterfacecommand{setupcolor}{reglecouleur} +\setinterfacecommand{setupcolors}{reglecouleurs} +\setinterfacecommand{setupcolumns}{reglecolonnes} +\setinterfacecommand{setupcolumnset}{reglejeucolonne} +\setinterfacecommand{setupcolumnsetlines}{setupcolumnsetlines} +\setinterfacecommand{setupcolumnsetstart}{setupcolumnsetstart} +\setinterfacecommand{setupcombinations}{reglecombinaisons} +\setinterfacecommand{setupcombinedlist}{reglelisteimbriquee} +\setinterfacecommand{setupcomment}{reglecommentaire} +\setinterfacecommand{setupdescriptions}{regledescriptions} +\setinterfacecommand{setupenumerations}{regleenumerations} +\setinterfacecommand{setupexternalfigures}{reglefiguresexternes} +\setinterfacecommand{setupfield}{reglechamp} +\setinterfacecommand{setupfields}{reglechamps} +\setinterfacecommand{setupfillinlines}{regleremplitligne} +\setinterfacecommand{setupfillinrules}{regleremplitlignesreglees} +\setinterfacecommand{setupfloat}{regleflottant} +\setinterfacecommand{setupfloats}{regleflottants} +\setinterfacecommand{setupfloatsplitting}{regleseparationflottant} +\setinterfacecommand{setupfooter}{reglepdp} +\setinterfacecommand{setupfootertexts}{regletextespdp} +\setinterfacecommand{setupfootnotedefinition}{definitnotepdp} +\setinterfacecommand{setupfootnotes}{reglenotepdp} +\setinterfacecommand{setupforms}{regleformulaires} +\setinterfacecommand{setupformulas}{regleformules} +\setinterfacecommand{setupframed}{regleencadre} +\setinterfacecommand{setupframedtexts}{setupframedtexts} +\setinterfacecommand{setuphead}{regletete} +\setinterfacecommand{setupheader}{regleentete} +\setinterfacecommand{setupheadertexts}{regletextesentete} +\setinterfacecommand{setupheadnumber}{reglenumerotete} +\setinterfacecommand{setupheads}{regletetes} +\setinterfacecommand{setupheadtext}{regletextetete} +\setinterfacecommand{setuphyphenmark}{reglemarquagehyphenation} +\setinterfacecommand{setupindentations}{reglealineas} +\setinterfacecommand{setupindenting}{reglecomposeenalinea} +\setinterfacecommand{setupinmargin}{regledansmarge} +\setinterfacecommand{setupinteraction}{regleinteraction} +\setinterfacecommand{setupinteractionbar}{reglebarreinteraction} +\setinterfacecommand{setupinteractionmenu}{reglemenuinteraction} +\setinterfacecommand{setupinteractionscreen}{regleecraninteraction} +\setinterfacecommand{setupinterlinespace}{regleespacementinterligne} +\setinterfacecommand{setupitemgroup}{setupitemgroup} +\setinterfacecommand{setupitemgroups}{reglegroupeselements} +\setinterfacecommand{setupitems}{regleelements} +\setinterfacecommand{setuplabeltext}{reglelabeltexte} +\setinterfacecommand{setuplanguage}{reglelangue} +\setinterfacecommand{setuplayout}{regledisposition} +\setinterfacecommand{setuplegend}{reglelegende} +\setinterfacecommand{setuplinenumbering}{reglenumerotationligne} +\setinterfacecommand{setuplines}{reglelignes} +\setinterfacecommand{setuplinewidth}{regleepaisseurligne} +\setinterfacecommand{setuplist}{regleliste} +\setinterfacecommand{setupmakeup}{reglemakeup} +\setinterfacecommand{setupmarginblocks}{regleblocmarge} +\setinterfacecommand{setupmarginrules}{reglemargereglee} +\setinterfacecommand{setupmarking}{reglemarquage} +\setinterfacecommand{setupmathalignment}{setupmathalignment} +\setinterfacecommand{setupnarrower}{reglecompoetroite} +\setinterfacecommand{setupnumber}{reglenumero} +\setinterfacecommand{setupnumbering}{reglenumerotation} +\setinterfacecommand{setupoppositeplacing}{regleplacementopposition} +\setinterfacecommand{setupoutput}{reglesortie} +\setinterfacecommand{setuppagecomment}{reglecommentairepage} +\setinterfacecommand{setuppagenumber}{reglenumeropage} +\setinterfacecommand{setuppagenumbering}{reglenumerotationpage} +\setinterfacecommand{setuppagetransitions}{regletransitionspage} +\setinterfacecommand{setuppalet}{reglepalette} +\setinterfacecommand{setuppaper}{reglepapier} +\setinterfacecommand{setuppapersize}{regletaillepapier} +\setinterfacecommand{setupparagraphnumbering}{reglenumerotationparagraphe} +\setinterfacecommand{setupparagraphs}{regleparagraphes} +\setinterfacecommand{setupplacement}{setupplacement} +\setinterfacecommand{setuppositioning}{reglepositionnement} +\setinterfacecommand{setupprofiles}{regleprofils} +\setinterfacecommand{setupprograms}{regleprogrammes} +\setinterfacecommand{setuppublications}{reglepublications} +\setinterfacecommand{setupquote}{demarreciter} +\setinterfacecommand{setupreferencelist}{reglelistereference} +\setinterfacecommand{setupreferencing}{reglereferencage} +\setinterfacecommand{setupregister}{regleregistre} +\setinterfacecommand{setuprotate}{regleoriente} +\setinterfacecommand{setuprule}{regleregle} +\setinterfacecommand{setups}{reglages} +\setinterfacecommand{setupscreens}{regleecrans} +\setinterfacecommand{setupsection}{reglesection} +\setinterfacecommand{setupsectionblock}{regleblocsection} +\setinterfacecommand{setupsorting}{regletri} +\setinterfacecommand{setupspacing}{regleespacement} +\setinterfacecommand{setupstartstop}{regledemarrestoppe} +\setinterfacecommand{setupstrut}{reglestrut} +\setinterfacecommand{setupsubpagenumber}{reglesousnumeropage} +\setinterfacecommand{setupsymbolset}{reglejeusymboles} +\setinterfacecommand{setupsynchronization}{reglesynchronisation} +\setinterfacecommand{setupsynchronizationbar}{reglebarresynchronisation} +\setinterfacecommand{setupsynonyms}{reglesynonymes} +\setinterfacecommand{setupsystem}{reglesysteme} +\setinterfacecommand{setuptab}{regletab} +\setinterfacecommand{setuptables}{regletableaux} +\setinterfacecommand{setuptabulate}{regletabulation} +\setinterfacecommand{setuptext}{regletexte} +\setinterfacecommand{setuptextposition}{reglepositiontexte} +\setinterfacecommand{setuptextrules}{reglelignesreglestexte} +\setinterfacecommand{setuptexttexts}{regletextestexte} +\setinterfacecommand{setuptextvariable}{reglevariabletexte} +\setinterfacecommand{setupthinrules}{regletraitsfins} +\setinterfacecommand{setuptolerance}{regletolerance} +\setinterfacecommand{setuptop}{reglesup} +\setinterfacecommand{setuptoptexts}{regletextessup} +\setinterfacecommand{setuptype}{regletype} +\setinterfacecommand{setuptyping}{regledactylo} +\setinterfacecommand{setupunderbar}{reglesouslignage} +\setinterfacecommand{setupurl}{regleurl} +\setinterfacecommand{setupversions}{regleversions} +\setinterfacecommand{setupwhitespace}{regleespaceblanc} +\setinterfacecommand{showbodyfont}{montrepolicecorps} +\setinterfacecommand{showbodyfontenvironment}{montreenvironnementpolicecorps} +\setinterfacecommand{showcolor}{montrecouleur} +\setinterfacecommand{showcolorgroup}{montregroupecouleur} +\setinterfacecommand{showexternalfigures}{montrefiguresexternes} +\setinterfacecommand{showfields}{montrechamps} +\setinterfacecommand{showframe}{montrecadre} +\setinterfacecommand{showgrid}{montregrille} +\setinterfacecommand{showlayout}{montredisposition} +\setinterfacecommand{showmakeup}{montremakeup} +\setinterfacecommand{showpalet}{montrepalette} +\setinterfacecommand{showprint}{montreedition} +\setinterfacecommand{showsetups}{montrereglages} +\setinterfacecommand{showstruts}{montrestruts} +\setinterfacecommand{showsymbolset}{montrejeusymboles} +\setinterfacecommand{smallcapped}{cap} +\setinterfacecommand{someline}{uneligne} +\setinterfacecommand{somewhere}{qqpart} +\setinterfacecommand{space}{espace} +\setinterfacecommand{splitfloat}{separeflottant} +\setinterfacecommand{startalignment}{demarrealignement} +\setinterfacecommand{startbackground}{demarrearriereplan} +\setinterfacecommand{startcoding}{demarrecodage} +\setinterfacecommand{startcolor}{demarrecouleur} +\setinterfacecommand{startcolumnmakeup}{startcolumnmakeup} +\setinterfacecommand{startcolumns}{demarrecolonnes} +\setinterfacecommand{startcolumnset}{demarrejeucolonne} +\setinterfacecommand{startcombination}{demarrecombinaison} +\setinterfacecommand{startcomponent}{demarrecomposant} +\setinterfacecommand{startdocument}{demarredocument} +\setinterfacecommand{startenvironment}{demarreenvironement} +\setinterfacecommand{startfigure}{demarrefigure} +\setinterfacecommand{startglobal}{demarreglobal} +\setinterfacecommand{startline}{demarreligne} +\setinterfacecommand{startlinecorrection}{demarrecorrectionligne} +\setinterfacecommand{startlinenumbering}{demarrenumerotationligne} +\setinterfacecommand{startlines}{demarrelignes} +\setinterfacecommand{startlocal}{demarrelocal} +\setinterfacecommand{startlocalfootnotes}{demarrenotespdplocales} +\setinterfacecommand{startmakeup}{demarremakeup} +\setinterfacecommand{startmarginblock}{demarreblocmarge} +\setinterfacecommand{startmarginrule}{demarremargereglee} +\setinterfacecommand{startnarrower}{demarrecompoetroite} +\setinterfacecommand{startopposite}{demarreopposition} +\setinterfacecommand{startoverlay}{demarrerevetement} +\setinterfacecommand{startoverzicht}{demarrevuedensemble} +\setinterfacecommand{startpacked}{demarregroupe} +\setinterfacecommand{startpositioning}{demarrepositionnement} +\setinterfacecommand{startproduct}{demarreproduit} +\setinterfacecommand{startprofile}{demarreprofil} +\setinterfacecommand{startproject}{demarreprojet} +\setinterfacecommand{startquotation}{demarrecitation} +\setinterfacecommand{startraster}{demarreraster} +\setinterfacecommand{startsymbolset}{demarrejeusymboles} +\setinterfacecommand{startsynchronization}{demarresynchronisation} +\setinterfacecommand{starttable}{demarretableau} +\setinterfacecommand{starttables}{demarretableaux} +\setinterfacecommand{starttext}{demarretexte} +\setinterfacecommand{starttextrule}{demarreligneregleetexte} +\setinterfacecommand{startunpacked}{demarredegroupe} +\setinterfacecommand{startversion}{demarreversion} +\setinterfacecommand{stopalignment}{stoppealignement} +\setinterfacecommand{stopbackground}{stoppearriereplan} +\setinterfacecommand{stopcoding}{stoppecodage} +\setinterfacecommand{stopcolor}{stoppecouleur} +\setinterfacecommand{stopcolumnmakeup}{stopcolumnmakeup} +\setinterfacecommand{stopcolumns}{stoppecolonnes} +\setinterfacecommand{stopcolumnset}{stoppejeucolonne} +\setinterfacecommand{stopcombination}{stoppecombinaison} +\setinterfacecommand{stopcomponent}{stoppecomposant} +\setinterfacecommand{stopdocument}{stoppedocument} +\setinterfacecommand{stopenvironment}{stoppeenvironement} +\setinterfacecommand{stopglobal}{stoppeglobal} +\setinterfacecommand{stopline}{stoppeligne} +\setinterfacecommand{stoplinecorrection}{stoppecorrectionligne} +\setinterfacecommand{stoplinenumbering}{stoppenumerotationligne} +\setinterfacecommand{stoplines}{stoppelignes} +\setinterfacecommand{stoplocal}{stoppelocal} +\setinterfacecommand{stoplocalfootnotes}{stoppenotespdplocales} +\setinterfacecommand{stopmakeup}{stoppemakeup} +\setinterfacecommand{stopmarginblock}{stoppeblocmarge} +\setinterfacecommand{stopmarginrule}{stoppemargereglee} +\setinterfacecommand{stopnarrower}{stopcompoetroite} +\setinterfacecommand{stopopposite}{stoppeopposition} +\setinterfacecommand{stopoverlay}{stopperevetement} +\setinterfacecommand{stopoverzicht}{stoppevuedensemble} +\setinterfacecommand{stoppacked}{stoppegroupe} +\setinterfacecommand{stoppositioning}{stoppepositionnement} +\setinterfacecommand{stopproduct}{stoppeproduit} +\setinterfacecommand{stopprofile}{stoppeprofil} +\setinterfacecommand{stopproject}{stoppeprojet} +\setinterfacecommand{stopquotation}{stoppecitation} +\setinterfacecommand{stopraster}{stopperaster} +\setinterfacecommand{stopsynchronization}{stoppesynchronisation} +\setinterfacecommand{stoptable}{stoppetableau} +\setinterfacecommand{stoptables}{stoppetableaux} +\setinterfacecommand{stoptext}{stoppetexte} +\setinterfacecommand{stoptextrule}{stoppeligneregleetexte} +\setinterfacecommand{stopunpacked}{stoppedegroupe} +\setinterfacecommand{stopversion}{stoppeversion} +\setinterfacecommand{stretched}{etire} +\setinterfacecommand{subformulanumber}{numerosousformule} +\setinterfacecommand{subpagenumber}{sousnumeropage} +\setinterfacecommand{switchtobodyfont}{changepolicecorps} +\setinterfacecommand{switchtorawfont}{changepolicebrute} +\setinterfacecommand{sym}{sym} +\setinterfacecommand{symbol}{symbole} +\setinterfacecommand{synchronizationbar}{barresynchronisation} +\setinterfacecommand{synchronize}{synchronise} +\setinterfacecommand{tab}{tab} +\setinterfacecommand{testcolumn}{testcolumn} +\setinterfacecommand{testpage}{testpage} +\setinterfacecommand{tex}{tex} +\setinterfacecommand{textheight}{hauteurtexte} +\setinterfacecommand{textreference}{referencetexte} +\setinterfacecommand{textrule}{ligneregleetexte} +\setinterfacecommand{textvariable}{variabletexte} +\setinterfacecommand{textwidth}{largeurtexte} +\setinterfacecommand{thinrule}{traitfin} +\setinterfacecommand{thinrules}{traitsfins} +\setinterfacecommand{tooltip}{suggestion} +\setinterfacecommand{topdistance}{distancesup} +\setinterfacecommand{topheight}{hauteursup} +\setinterfacecommand{topspace}{espacesup} +\setinterfacecommand{totalnumberofpages}{nombretotaldepages} +\setinterfacecommand{translate}{traduire} +\setinterfacecommand{txt}{txt} +\setinterfacecommand{typ}{typ} +\setinterfacecommand{type}{dactylographier} +\setinterfacecommand{typebuffer}{tapebuffer} +\setinterfacecommand{typefile}{fichierdactylo} +\setinterfacecommand{unitmeaning}{sensunite} +\setinterfacecommand{unknown}{inconnu} +\setinterfacecommand{useJSscripts}{utiliseJSscripts} +\setinterfacecommand{useURL}{utiliseURL} +\setinterfacecommand{useXMLfilter}{useXMLfilter} +\setinterfacecommand{useblocks}{utiliseblocs} +\setinterfacecommand{usecommands}{utilisecommandes} +\setinterfacecommand{useencoding}{utiliseencodage} +\setinterfacecommand{useexternaldocument}{utilisedocumentexterne} +\setinterfacecommand{useexternalfigure}{utilisefigureexterne} +\setinterfacecommand{useexternalfile}{utilisefichierexterne} +\setinterfacecommand{useexternalfiles}{utilisefichiersexternes} +\setinterfacecommand{useexternalsoundtrack}{utilisepsiteaudioexterne} +\setinterfacecommand{usemodule}{utilisemodule} +\setinterfacecommand{usemodules}{utilisemodules} +\setinterfacecommand{usepath}{utilisechemin} +\setinterfacecommand{usereferences}{utilisereferences} +\setinterfacecommand{usespecials}{utilisespecialites} +\setinterfacecommand{usesymbols}{utilisesymboles} +\setinterfacecommand{usetypescript}{usetypescript} +\setinterfacecommand{usetypescriptfile}{usetypescriptfile} +\setinterfacecommand{useurl}{utiliseurl} +\setinterfacecommand{version}{version} +\setinterfacecommand{vl}{vl} +\setinterfacecommand{weekday}{joursemaine} +\setinterfacecommand{whitespace}{espaceblanc} +\setinterfacecommand{wordright}{motdroit} +\setinterfacecommand{writebetweenlist}{ecritentreliste} +\setinterfacecommand{writetolist}{ecritdansliste} +\setinterfacecommand{writetoreferencelist}{ecritdanslistereference} +\setinterfacecommand{writetoregister}{ecritregistre} +% +\endinput \ No newline at end of file diff --git a/tex/context/base/mult-fst.tex b/tex/context/base/mult-fst.tex new file mode 100644 index 000000000..c237f5743 --- /dev/null +++ b/tex/context/base/mult-fst.tex @@ -0,0 +1,53 @@ +%D \module +%D [ file=mult-fst, +%D version=2006.08.16, +%D title=\CONTEXT\ Multilingual Macros, +%D subtitle=Speed Up, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% And so, after a few years of keeping this potentially dangerous +% speedup in cont-exp, we now move it to the kernel: the next +% patch is 30\% faster on main interface (seconds) (9->7 sec on +% 1 million calls). Another speed up is still under testing. + +\unprotect + +\startinterface english + + \def\dosetvalue #1#2{\@EA\def \csname#1#2\endcsname} + \def\dosetevalue #1#2{\@EA\edef\csname#1#2\endcsname} + \def\dosetgvalue #1#2{\@EA\gdef\csname#1#2\endcsname} + \def\dosetxvalue #1#2{\@EA\gdef\csname#1#2\endcsname} + \def\docopyvalue#1#2#3{\@EA\def \csname#1#3\@EA\endcsname\@EA{\csname#2#3\endcsname}} + + \ifx\ctxlua\undefined + + \def\setinterfaceconstant#1#2% + {\setvalue{\c!prefix!#1}{#1}} + + \def\setinterfacevariable#1#2% + {\setvalue{\v!prefix!#1}{#2}} + + \else + + \def\setinterfaceconstant#1#2% + {\ctxlua{interfaces.setconstant("#1","#2")}% + \setvalue{\c!prefix!#1}{#1}} + + \def\setinterfacevariable#1#2% + {\ctxlua{interfaces.setvariable("#1","#2")}% + \setvalue{\v!prefix!#1}{#2}} + + \fi + + \def\interfaced#1{#1} + +\stopinterface + +\protect \endinput diff --git a/tex/context/base/mult-ini.lua b/tex/context/base/mult-ini.lua new file mode 100644 index 000000000..92a7bc629 --- /dev/null +++ b/tex/context/base/mult-ini.lua @@ -0,0 +1,105 @@ +if not modules then modules = { } end modules ['mult-ini'] = { + version = 1.001, + comment = "companion to mult-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format, gmatch, gsub = string.format, string.gmatch, string.gsub +local lpegmatch = lpeg.match +local serialize = table.serialize + +interfaces = interfaces or { } +interfaces.messages = interfaces.messages or { } +interfaces.constants = interfaces.constants or { } +interfaces.variables = interfaces.variables or { } + +storage.register("interfaces/messages", interfaces.messages, "interfaces.messages" ) +storage.register("interfaces/constants", interfaces.constants, "interfaces.constants") +storage.register("interfaces/variables", interfaces.variables, "interfaces.variables") + +local messages, constants, variables = interfaces.messages, interfaces.constants, interfaces.variables + +function interfaces.setmessages(category,str) + local m = messages[category] or { } + for k, v in gmatch(str,"(%S+) *: *(.-) *[\n\r]") do + m[k] = gsub(v,"%-%-","%%s") + end + messages[category] = m +end + +function interfaces.setmessage(category,tag,message) + local m = messages[category] + if not m then + m = { } + messages[category] = m + end + m[tag] = gsub(message,"%-%-","%%s") +end + +function interfaces.getmessage(category,tag,default) + local m = messages[category] + return (m and m[tag]) or default or "unknown message" +end + +function interfaces.doifelsemessage(category,tag) + local m = messages[category] + return commands.testcase(m and m[tag]) +end + +local messagesplitter = lpeg.splitat(",") + +function interfaces.makemessage(category,tag,arguments) + local m = messages[category] + m = (m and (m[tag] or m[tostring(tag)])) or format("unknown message, category '%s', tag '%s'",category,tag) + if not m then + return m .. " " .. tag + elseif not arguments then + return m + else + return format(m,lpegmatch(messagesplitter,arguments)) + end +end + +function interfaces.showmessage(category,tag,arguments) + local m = messages[category] + commands.writestatus((m and m.title) or "unknown title",interfaces.makemessage(category,tag,arguments)) +end + +function interfaces.setvariable(variable,given) +--~ variables[given] = variable + variables[variable] = given +end + +function interfaces.setconstant(constant,given) + constants[given] = constant +end + +-- it's nicer to have numbers as reference than a hash + +interfaces.cachedsetups = interfaces.cachedsetups or { } +interfaces.hashedsetups = interfaces.hashedsetups or { } + +storage.register("interfaces.cachedsetups", interfaces.cachedsetups, "interfaces.cachedsetups") +storage.register("interfaces.hashedsetups", interfaces.hashedsetups, "interfaces.hashedsetups") + +local cachedsetups = interfaces.cachedsetups +local hashedsetups = interfaces.hashedsetups + +function interfaces.cachesetup(t) + local hash = serialize(t) + local done = hashedsetups[hash] + if done then + return cachedsetups[done] + else + done = #cachedsetups + 1 + cachedsetups[done] = t + hashedsetups[hash] = done + return t + end +end + +function interfaces.is_command(str) + return (str and str ~= "" and token.csname_name(token.create(str)) ~= "") or false +end diff --git a/tex/context/base/mult-ini.mkii b/tex/context/base/mult-ini.mkii new file mode 100644 index 000000000..c2bb40861 --- /dev/null +++ b/tex/context/base/mult-ini.mkii @@ -0,0 +1,935 @@ +%D \module +%D [ file=mult-ini, +%D version=2008.10.22, % 1996.06.01, +%D title=\CONTEXT\ Multilingual 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 is a stripped down version of \type {mult-ini.tex}, +%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} + +\unprotect + +%D \macros +%D [constanten,variabelen,commands] +%D {v!,c!,k!,s!,e!,m!,l!,r!,f!,p!,x!,y!} +%D +%D In the system modules we introduced some prefixed constants, +%D variables (both macros) and registers. Apart from a +%D tremendous saving in terms of memory and a gain in speed we +%D use from now on prefixes when possible for just another +%D reason: consistency and multi||linguality. Systematically +%D using prefixed macros enables us to implement a +%D multi||lingual user interface. Redefining these next set of +%D prefixes therefore can have desastrous results. +%D +%D \startlinecorrection +%D \starttable[|c|c|c|] +%D \HL +%D \NC \bf prefix \NC \bf meaning \NC \bf application \NC\SR +%D \HL +%D \NC \type{\c!prefix!} \NC c! \NC constant (direct) \NC\FR +%D \NC \type{\e!prefix!} \NC e! \NC element \NC\MR +%D \NC \type{\f!prefix!} \NC f! \NC file \NC\MR +%D \NC \type{\k!prefix!} \NC k! \NC constant (indirect) \NC\MR +%D \NC \type{\l!prefix!} \NC l! \NC language \NC\MR +%D \NC \type{\m!prefix!} \NC m! \NC message \NC\MR +%D \NC \type{\p!prefix!} \NC p! \NC procedure \NC\MR +%D \NC \type{\r!prefix!} \NC r! \NC reference \NC\MR +%D \NC \type{\s!prefix!} \NC s! \NC system \NC\MR +%D \NC \type{\v!prefix!} \NC v! \NC variable \NC\MR +%D \HL +%D \stoptable +%D \stoplinecorrection +%D +%D In the single||lingual version we used \type{!}, \type{!!}, +%D \type{!!!} and \type{!!!!}. + +\def\c!prefix!{c!} \def\e!prefix!{e!} \def\f!prefix!{f!} +\def\k!prefix!{k!} \def\l!prefix!{l!} \def\m!prefix!{m!} +\def\p!prefix!{p!} \def\r!prefix!{r!} \def\s!prefix!{s!} +\def\v!prefix!{v!} \def\t!prefix!{t!} + +%D \macros +%D [constants,variables,commands] +%D {@@,??} +%D +%D Variables generated by the system can be recognized on their +%D prefix \type{@@}. They are composed of a command (class) +%D specific tag, which can be recognized on \type{??}, and a +%D system constant, which has the prefix \type{c!}. We'll se +%D some more of this. + +\def\??prefix {??} +\def\@@prefix {@@} + +%D Just to be complete we repeat some of the already defined +%D system constants here. Maybe their prefix \type{\s!} now +%D falls into place. + +\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} + +%D The word \type{height} takes 6~token memory cells. The +%D control sequence \type{\height} on the other hand uses only +%D one. Knowing this, we can improve the performance of \TEX, +%D both is terms of speed and memory usage, by using control +%D sequences instead of the words written in full. +%D +%D Where in the \ASCII\ file the second lines takes nine extra +%D characters, \TEX\ saves us 13~tokens. +%D +%D \starttyping +%D \hrule width 10pt height 2pt depth 1pt +%D \hrule \!!width 10pt \!!height 2pt \!!depth 1pt +%D \stoptyping +%D +%D One condition is that we have defined \type{\!!height}, +%D \type{\!!width} and \type{\!!depth} as respectively +%D \type{height}, \type{width} and \type{depth}. Using this +%D scheme therefore only makes sense when a token sequence is +%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} + +%D \macros +%D {defineinterfaceconstant, +%D defineinterfacevariable, +%D defineinterfaceelement, +%D definesystemvariable, +%D definesystemconstant, +%D definemessageconstant, +%D definereferenceconstant, +%D definefileconstant} +%D +%D The first part of this module is dedicated to dealing with +%D multi||lingual constants and variables. When \CONTEXT\ grew +%D bigger and bigger in terms of bytes and used string space, +%D we switched to predefined constants. At the cost of more +%D hash table entries, the macros not only becase more compact, +%D they became much faster too. Maybe an even bigger advantage +%D was that mispelling could no longer lead to problems. Even a +%D multi||lingual interface became possible. +%D +%D Constants --- we'll introduce the concept of variables later +%D on --- are preceded by a type specific prefix, followed by a +%D \type{!}. To force consistency, we provide a few commands +%D for defining such constants. +%D +%D \starttyping +%D \defineinterfaceconstant {name} {meaning} +%D \defineinterfacevariable {name} {meaning} +%D \defineinterfaceelement {name} {meaning} +%D \stoptyping +%D +%D Which is the same as: +%D +%D \starttyping +%D \def\c!name{meaning} +%D \def\v!name{meaning} +%D \def\e!name{meaning} +%D \stoptyping + +\def\defineinterfaceconstant #1#2{\setvalue{\c!prefix!#1}{#2}} +\def\defineinterfacevariable #1#2{\setvalue{\v!prefix!#1}{#2}} +\def\defineinterfaceelement #1#2{\setvalue{\e!prefix!#1}{#2}} + +%D Next come some interface independant constants: +%D +%D \starttyping +%D \definereferenceconstant {name} {meaning} +%D \definefileconstant {name} {meaning} +%D \stoptyping + +\def\definereferenceconstant #1#2{\setvalue{\r!prefix!#1}{#2}} +\def\definefileconstant #1#2{\setvalue{\f!prefix!#1}{#2}} + +%D A new one: + +\def\definetypescriptconstant#1#2{\setvalue{\t!prefix!#1}{#2}} + +%D And finaly we have the one argument, space saving constants +%D +%D \starttyping +%D \definesystemconstant {name} +%D \definemessageconstant {name} +%D \stoptyping + +\def\definesystemconstant #1{\setvalue{\s!prefix!#1}{#1}} +\def\definemessageconstant #1{\setvalue{\m!prefix!#1}{#1}} + +%D In a parameter driven system, some parameters are shared +%D by more system components. In \CONTEXT\ we can distinguish +%D parameters by a unique prefix. Such a prefix is defined +%D with: +%D +%D \starttyping +%D \definesystemvariable {name} +%D \stoptyping + +\def\definesystemvariable#1{\setevalue{\??prefix#1}{\@@prefix#1}} + +\definesystemvariable{ms} + +%D \macros +%D {selectinterface, +%D defaultinterface, currentinterface, currentresponses} +%D +%D With \type{\selectinterface} we specify the language we are +%D going to use. The system asks for the language wanted, and +%D defaults to \type{\currentinterface} when we just give +%D \type{enter}. By default the message system uses the +%D current interface language, but \type{\currentresponses} +%D can specify another language too. +%D +%D Because we want to generate formats directly too, we do +%D not ask for interface specifications when these are already +%D defined (like in cont-nl.tex and alike). + +\ifx\defaultinterface\undefined + + \def\defaultinterface{english} + + \def\selectinterface + {\def\docommand##1##2% + {\bgroup + \endlinechar\minusone + \global\read16 to ##1 + \egroup + \doifnothing\currentinterface{\let##1=##2}% + \doifundefined{\s!prefix!##1}{\let##1=##2}}% + \docommand\currentinterface\defaultinterface + \writestatus{interface}{defining \currentinterface\space interface}% + \writeline + \docommand\currentresponses\currentinterface + \writestatus{interface}{using \currentresponses\space messages}% + \writeline + \let\selectinterface\relax} + +\else + + \def\selectinterface + {\writestatus{interface}{defining \currentinterface\space interface}% + \writeline + \writestatus{interface}{using \currentresponses\space messages}% + \writeline + \let\selectinterface\relax} + +\fi + +\ifx\currentinterface\undefined \let\currentinterface=\defaultinterface \fi +\ifx\currentresponses\undefined \let\currentresponses=\defaultinterface \fi + +%D \macros +%D {startinterface} +%D +%D Sometimes we want to define things only for specific +%D interface languages. This can be done by means of the +%D selector: +%D +%D \starttyping +%D \startinterface language +%D +%D language specific definitions & commands +%D +%D \stopinterface +%D \stoptyping + +\def\startinterface #1 + {\doifnot{#1}{all}{\doifnotinset\currentinterface{#1}{\gobbleuntil\stopinterface}}} + +\let\stopinterface\relax + +%D \macros +%D {startmessages, +%D getmessage, +%D showmessage, +%D makemessage} +%D +%D A package as large as \CONTEXT\ can hardly function without +%D a decent message mechanism. Due to its multi||lingual +%D interface, the message subsystem has to be multi||lingual +%D too. A major drawback of this feature is that we have to +%D code messages. As a result, the source becomes less self +%D documented. On the other hand, consistency will improve. +%D +%D Because the overhead in terms of entries in the (already +%D exhausted) hash table has to be minimal, messages are packed +%D in libraries. We can extract a message from such a library +%D in three ways: +%D +%D \starttyping +%D \getmessage {library} {tag} +%D \showmessage {library} {tag} {data} +%D \makemessage {library} {tag} {data} +%D \stoptyping +%D +%D The first command gets the message \type{tag} from the +%D \type{library} specified. The other commands take an extra +%D argument: a list of items to be inserted in the message +%D text. While \type{\showmessage} shows the message at the +%D terminal, the other commands generate the message as text. +%D Before we explain the \type{data} argument, we give an +%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 \stoptyping +%D +%D The first message is a simple one and can be shown with: +%D +%D \starttyping +%D \showmessage {alfa} {1} {} +%D \stoptyping +%D +%D The second message on the other hand needs some extra data: +%D +%D \starttyping +%D \showmessage {alfa} {2} {and last,to you} +%D \stoptyping +%D +%D This message is shown as: +%D +%D \starttyping +%D something : second (and last) message to you +%D \stoptyping +%D +%D As we can see, the title entry is shown with the message. +%D The data fields are comma separated and are specified in the +%D message text by \type{--}. +%D +%D It is not required to define all messages in a library at +%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 \stoptyping +%D +%D Because such definitions can take place in different +%D modules, the system gives a warning when a tag occurs more +%D than once. The first occurrence takes preference over later +%D ones, so we had better use a save offset, as shown in the +%D example. As we can see, the title field is specified only +%D the first time! +%D +%D Because we want to check for duplicate tags, the macros +%D are a bit more complicated than neccessary. The \NEWLINE\ +%D token is used as message separator. +%D +%D For internal purposes one can use \type {\setmessagetext}, +%D which puts the message text asked for in \type +%D {\currentmessagetext}. + +\def\findinterfacemessage#1#2% + {\let#2\empty + \def\dofindinterfacemessage##1 #1: ##2\relax##3\end{\def#2{##2}}% + \edef\!!stringa{\getvalue{\??ms\currentmessagelibrary} #1: \relax}% + \expandafter\dofindinterfacemessage\!!stringa\end} + +\def\composemessagetext#1--#2--#3--#4--#5--#6--#7--#8--#9\\% + {\def\docomposemessagetext##1,##2,##3,##4,##5,##6,##7,##8,##9\\% + {\edef\currentmessagetext{#1##1#2##2#3##3#4##4#5##5#6##6#7##7#8##8}}% + \docomposemessagetext} + +\def\setmessagetext#1#2% + {\def\currentmessagelibrary{#1}% + \findinterfacemessage{#2}\currentmessagetext} + +\unexpanded\def\getmessage#1#2% + {\def\currentmessagelibrary{#1}% + \findinterfacemessage{#2}\currentmessagetext + \currentmessagetext} + +\unexpanded\def\makemessage#1#2#3% + {\def\currentmessagelibrary{#1}% + \findinterfacemessage{#2}\currentmessagetext + \@EA\composemessagetext\currentmessagetext----------------\\#3,,,,,,,,\\% + \currentmessagetext} + +\def\showmessage#1#2#3% + {\def\currentmessagelibrary{#1}% + \findinterfacemessage{#2}\currentmessagetext + \findinterfacemessage{title}\currentmessagetitle + \ifx\currentmessagetext\empty + \def\currentmessagetext{}% + \else + \@EA\composemessagetext\currentmessagetext----------------\\#3,,,,,,,,\\% + \fi + \@EA\writestatus\@EA{\currentmessagetitle}{\currentmessagetext}} + +\def\doaddinterfacemessage#1#2% + {\findinterfacemessage{#1}\currentmessagetext + \doifelsenothing\currentmessagetext + {\setxvalue{\??ms\currentmessagelibrary}% + {\getvalue{\??ms\currentmessagelibrary} #1: #2\relax}} + {\debuggerinfotrue % we consider this an important error + \debuggerinfo + {message} + {duplicate tag #1 + in library \currentmessagelibrary\space + of interface \currentresponses}}% + \futurelet\next\getinterfacemessage} + +\bgroup +\obeylines +\gdef\addinterfacemessage#1: #2 + {\doaddinterfacemessage{#1}{#2}}% +\egroup + +\def\getinterfacemessage + {\ifx\next\stopmessages + \egroup\expandafter\gobbleoneargument + \else + \expandafter\addinterfacemessage + \fi} + +\let\stopmessages\undefined % for dep checker + +\def\startmessages #1 library: #2 + {\definemessageconstant{#2}% handy for modules + \bgroup + \obeylines + \doifinsetelse{#1}{\currentresponses,all} + {\def\next + {\def\currentmessagelibrary{#2}% + \doifundefined{\??ms\currentmessagelibrary} + {\letgvalueempty{\??ms\currentmessagelibrary}}% + \futurelet\next\getinterfacemessage}} + {\long\def\next##1\stopmessages{\egroup}}% + \next} + +%D Here, the messages are stored in a way that saves hash +%D entries, i.e. they are packed in one macro per library. +%D This was important in the days when we used \TEX's with +%D hash tables of about 10.000. The next, less efficient way +%D of storing the message, makes \CONTEXT\ run upto 5\% +%D faster by storing each message in a macro. In July 2000, +%D this costs some 185 additional hash entries, and since +%D we run large \TEX's, let do it! + +\def\startmessages #1 library: #2 + {\definemessageconstant{#2}% handy for modules + \bgroup + \obeylines + \ifcsname\m!prefix!#2\endcsname\else\setgvalue{\m!prefix!#2}{#2}\fi + \doifinsetelse{#1}{\currentresponses,all} + {\def\next + {\def\currentmessagelibrary{#2}% + \futurelet\next\getinterfacemessage}} + {\long\def\next##1\stopmessages{\egroup}}% + \next} + +\def\findinterfacemessage#1#2% + {\edef#2{\getvalue{\??ms\currentmessagelibrary#1}}} + +\def\doaddinterfacemessage#1#2% + {\doifdefined{\??ms\currentmessagelibrary#1} + {\debuggerinfotrue % we consider this an important error + \debuggerinfo + {message} + {duplicate tag #1 + in library \currentmessagelibrary\space + of interface \currentresponses}}% + \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 +%D Sometimes displaying message can slow down processing +%D considerably. We therefore introduce warnings. Users can +%D turn of warnings and messages by saying: +%D +%D \starttyping +%D \showwarningstrue +%D \showmessagestrue +%D \stoptyping +%D +%D Turning off messages also turns off warnings, which is +%D quote logical because they are less important. + +% not yet mkiv + +\newif\ifshowwarnings \showwarningstrue +\newif\ifshowmessages \showmessagestrue + +\let\normalshowmessage\showmessage + +\def\showwarning + {\ifshowwarnings + \expandafter\showmessage + \else + \expandafter\gobblethreearguments + \fi} + +\def\showmessage + {\ifshowmessages + \expandafter\normalshowmessage + \else + \expandafter\gobblethreearguments + \fi} + +%D \macros +%D {dosetvalue,dosetevalue,dosetgvalue,dosetxvalue,docopyvalue,doresetvalue} % dogetvalue +%D +%D We already defined these auxiliary macros in the system +%D modules. Starting with this module however, we have to take +%D multi||linguality a bit more serious. + +\def\doresetvalue#1#2% + {\dosetvalue{#1}{#2}{}} + +\def\doignorevalue#1#2#3% + {\dosetvalue{#1}{#2}{}} + +\def\dosetvalue#1#2% + {\let\c!internal!\c!internal!n + \ifcsname\k!prefix!#2\endcsname + \let\c!internal!\c!internal!y + \@EA\def\csname#1\csname\k!prefix!#2\endcsname%\endcsname + \else + \let\c!internal!\c!internal!y + \@EA\def\csname#1#2%\endcsname + \fi\endcsname} + +\def\dosetevalue#1#2% + {\let\c!internal!\c!internal!n + \ifcsname\k!prefix!#2\endcsname + \let\c!internal!\c!internal!y + \@EA\edef\csname#1\csname\k!prefix!#2\endcsname%\endcsname + \else + \let\c!internal!\c!internal!y + \@EA\edef\csname#1#2%\endcsname + \fi\endcsname} + +\def\dosetgvalue#1#2% + {\let\c!internal!\c!internal!n + \ifcsname\k!prefix!#2\endcsname + \let\c!internal!\c!internal!y + \@EA\gdef\csname#1\csname\k!prefix!#2\endcsname%\endcsname + \else + \let\c!internal!\c!internal!y + \@EA\gdef\csname#1#2%\endcsname + \fi\endcsname} + +\def\dosetxvalue#1#2% + {\let\c!internal!\c!internal!n + \ifcsname\k!prefix!#2\endcsname + \let\c!internal!\c!internal!y + \@EA\xdef\csname#1\csname\k!prefix!#2\endcsname%\endcsname + \else + \let\c!internal!\c!internal!y + \@EA\xdef\csname#1#2%\endcsname + \fi\endcsname} + +\def\docopyvalue#1#2#3% real tricky expansion, quite unreadable + {\let\c!internal!\c!internal!n + \ifcsname\k!prefix!#3\endcsname + \let\c!internal!\c!internal!y + \@EA\def\csname#1\csname\k!prefix!#3\endcsname + \@EA\endcsname\@EA{\csname#2\csname\k!prefix!#3\endcsname\endcsname}% + \else + \let\c!internal!\c!internal!y + \@EA\def\csname#1#3\@EA\endcsname\@EA{\csname#2#3\endcsname}% + \fi} + +%D We can now redefine some messages that will be +%D introduced in the multi||lingual system module. + +\def\showassignerror #1#2{\showmessage\m!check1{#1,#2}\waitonfatalerror} +\def\showargumenterror#1#2{\showmessage\m!check2{#1,#2}\waitonfatalerror} +\def\showdefinederror #1#2{\showmessage\m!check3{#1,#2}\waitonfatalerror} + +%D \CONTEXT\ is a parameter driven package. This means that +%D users instruct the system by means of variables, values and +%D keywords. These instructions take the form: +%D +%D \starttyping +%D \setupsomething[some variable=some value, another one=a keyword] +%D \stoptyping +%D +%D or by keyword only: +%D +%D \starttyping +%D \dosomething[this way,that way,no way] +%D \stoptyping +%D +%D Because the same variables can occur in more than one setup +%D command, we have to be able to distinguish them. This is +%D achieved by assigning them a unique prefix. +%D +%D Imagine a setup command for boxed text, that enables us to +%D specify the height and width of the box. Behide the scenes +%D the command +%D +%D \starttyping +%D \setupbox [width=12cm, height=3cm] +%D \stoptyping +%D +%D results in something like +%D +%D \starttyping +%D \ {12cm} +%D \ {3cm} +%D \stoptyping +%D +%D while a similar command for specifying the page dimensions +%D of an \cap{A4} page results in: +%D +%D \starttyping +%D \ {21.0cm} +%D \ {27.9cm} +%D \stoptyping +%D +%D The prefixes \type{} and \type{} are hidden from +%D users and can therefore be language independant. Variables +%D on the other hand, differ for each language: +%D +%D \starttyping +%D \ {} +%D \ {} +%D \ {} +%D \stoptyping +%D +%D In this example we can see that the assigned values or +%D keywords are language dependant too. This will be a +%D complication when defining multi||lingual setup files. +%D +%D A third phenomena is that variables and values can have a +%D similar meaning. +%D +%D \starttyping +%D \ {} +%D \ {12cm} +%D \stoptyping +%D +%D A (minor) complication is that where in english we use +%D \type{}, in dutch we find both \type{} and +%D \type{}. This means that when we use some sort of +%D translation table, we have to distinguish between the +%D variables at the left side and the fixed values at the +%D right. +%D +%D The same goes for commands that are composed of different +%D user supplied and/or language specific elements. In english +%D we can use: +%D +%D \starttyping +%D \
+%D \ +%D \stoptyping +%D +%D But in dutch we have the following: +%D +%D \starttyping +%D \ +%D \ +%D \stoptyping +%D +%D These subtle differences automatically lead to a solution +%D where variables, values, elements and other components have +%D a similar logical name (used in macro's) but a different +%D meaning (supplied by the user). +%D +%D Our solution is one in which the whole system is programmed +%D in terms of identifiers with language specific meanings. In +%D such an implementation, each fixed variable is available as: +%D +%D \starttyping +%D \ +%D \stoptyping +%D +%D This means that for instance: +%D +%D \starttyping +%D \setupbox[width=12cm] +%D \stoptyping +%D +%D expands to something like: +%D +%D \starttyping +%D \def\boxwidth{12cm} +%D \stoptyping +%D +%D because we don't want to recode the source, a setup command +%D in another language has to expand to this variable, so: +%D +%D \starttyping +%D \setupblock[width=12cm] +%D \stoptyping +%D +%D has to result in the definition of \type{\boxwidth} too. +%D This method enables us to build compact, fast and readable +%D code. +%D +%D An alternative method, which we considered using, uses a +%D more indirect way. In this case, both calls generate a +%D different variable: +%D +%D \starttyping +%D \def\boxwidth {12cm} +%D \def\boxbreedte {12cm} +%D \stoptyping +%D +%D And because we don't want to recode those megabytes of +%D already developed code, this variable has to be called with +%D something like: +%D +%D \starttyping +%D \valueof\box\width +%D \stoptyping +%D +%D where \type{\valueof} takes care of the translation of +%D \type{width} or \type{breedte} to \type{width} and +%D combining this with \type{box} to \type{\boxwidth}. +%D +%D One advantage of this other scheme is that, within certain +%D limits, we can implement an interface that can be switched +%D to another language at will, while the current approach +%D fixes the interface at startup. There are, by the way, +%D other reasons too for not choosing this scheme. Switching +%D user generated commands is for instance impossible and a +%D dual interface would therefore give a strange mix of +%D languages. +%D +%D Now let's work out the first scheme. Although the left hand +%D of the assignment is a variable from the users point of +%D view, it is a constant in terms of the system. Both +%D \type{width} and \type{breedte} expand to \type{width} +%D because in the source we only encounter \type{width}. Such +%D system constants are presented as +%D +%D \starttyping +%D \c!width +%D \stoptyping +%D +%D This constant is always equivalent to \type{width}. As we +%D can see, we use \type{c!} to mark this one as constant. Its +%D dutch counterpart is: +%D +%D \starttyping +%D breedte +%D \stoptyping +%D +%D When we interpret a setup command each variable is +%D translated to it's \type{c!} counterpart. This means that +%D \type{breedte} and \type{width} expand to \type{breedte} +%D and \type{\c!width} which both expand to \type{width}. That +%D way user variables become system constants. +%D +%D The interpretation is done by means of a general setup +%D command \type{\getparameters} that we introduced in the +%D system module. Let us define some simple setup command: +%D +%D \starttyping +%D \def\setupbox[#1]% +%D {\getparameters[\??bx][#1]} +%D \stoptyping +%D +%D This command can be used as: +%D +%D \starttyping +%D \setupbox [width=3cm, height=1cm] +%D \stoptyping +%D +%D Afterwards we have two variables \type{\@@bxwidth} and +%D \type{\@@bxheight} which have the values \type{3cm} and +%D \type{1cm} assigned. These variables are a combinatiom of +%D the setup prefix \type{\??bx}, which expands to \type{@@bx} +%D and the translated user supplied variables \type{width} and +%D \type{height} or \type{breedte} and \type{hoogte}, +%D depending on the actual language. In dutch we just say: +%D +%D \starttyping +%D \setupblock [width=3cm, height=1cm] +%D \stoptyping +%D +%D and get ourselves \type{\@@bxwidth} and \type{\@@bxheight} +%D too. In the source of \CONTEXT, we can recognize constants +%D and variables on their leading \type{c!}, \type{v!} etc., +%D prefixes on \type{??} and composed variables on \type{@@}. +%D +%D We already saw that user supplied keywords need some +%D special treatment too. This time we don't translate the +%D keyword, but instead use in the source a variable which +%D meaning depends on the interface language. +%D +%D \starttyping +%D \v!left +%D \stoptyping +%D +%D Which can be used in macro's like: +%D +%D \starttyping +%D \processaction +%D [\@@bxlocation] +%D [ \v!left=>\dosomethingontheleft, +%D \v!middle=>\dosomthinginthemiddle, +%D \v!right=>\dosomethingontheright] +%D \stoptyping +%D +%D Because variables like \type{\@@bxlocation} can have a lot +%D of meanings, including tricky expandable tokens, we cannot +%D translate this meaning when we compare. This means that +%D \type{\@@bxlocation} can be \type{left} of \type{links} of +%D whatever meaning suits the language. But because +%D \type{\v!left} also has a meaning that suits the language, +%D we are able to compare. +%D +%D Although we know it sounds confusing we want to state two +%D important characteristics of the interface as described: +%D +%D \startnarrower \em +%D user variables become system constants +%D \stopnarrower +%D +%D and +%D +%D \startnarrower \em +%D user constants (keywords) become system variables +%D \stopnarrower +%D + +%D Anno 2003 I've forgotten why the \type {\c!internal} is +%D still in there; it's probably a left over from an experiment. + +\let\c!internal!y \string +\def\c!internal!n {-} +\let\c!internal! \c!internal!y + +\def\setinterfaceconstant#1#2% + {\setvalue{\c!prefix!#1}{\c!internal!#1}% + \setvalue{\k!prefix!#2}{#1}} + +\def\setinterfacevariable#1#2% + {\setvalue{\v!prefix!#1}{#2}} + +%D \macros +%D {defineinterfaceconstant} +%D +%D Next we redefine a previously defined macro to take care of +%D interface translation too. It's a bit redundant, because +%D in these situations we could use the c||version, but for +%D documentation purposes the x||alternative comes in handy. + +\def\defineinterfaceconstant#1#2% + {\setvalue{\c!prefix!#1}{#2}} + +%D \macros +%D {startelements} +%D +%D Due to the object oriented nature of \CONTEXT, we also need +%D to define the elements that are used to build commands. +%D +%D Such elements sometimes are the same in diferent +%D languages, but mostly they differ. Things can get even +%D confusing when we look at for instance the setup commands. +%D In english we say \type{\setup}, but in dutch we +%D have: \type{\stelin}. Such split elements are no +%D problem, because we just define two elements. When no second +%D part is needed, we use a \type{-}: + +\def\setinterfaceelement#1#2% + {\ifcsname\e!prefix!#1\endcsname + \doifnotvalue{\e!prefix!#1}{#2}{\setvalue{\e!prefix!#1}{#2}}% + \else + \setvalue{\e!prefix!#1}{#2}% + \fi} + +\def\setinterfacecommand#1#2% + {\doifnot{#1}{#2}{\@EA\def\csname#2\@EA\endcsname\@EA{\csname#1\endcsname}}}% or just \let ? + +%D We just ignore these: + +\def\startvariables{\gobbleuntil\stopvariables} +\def\startconstants{\gobbleuntil\stopconstants} +\def\startelements {\gobbleuntil\stopelements} +\def\startcommands {\gobbleuntil\stopcommands} + +%D \macros +%D {interfaced} +%D +%D The setup commands translate the constants automatically. +%D When we want to translate 'by hand' we can use the simple +%D but effective command: +%D +%D \starttyping +%D \interfaced {something} +%D \stoptyping +%D +%D Giving \type{\interfaced{breedte}} results in \type{width} +%D or, when not defined, in \type{breedte} itself. This +%D macro is used in the font switching mechanism. + +\def\interfaced#1% + {\ifcsname\k!prefix!#1\endcsname + \csname\k!prefix!#1\endcsname + \else + #1% + \fi} + +%D So much for the basic multi||lingual interface commands. The +%D macro's can be enhanced with more testing facilities, but +%D for the moment they suffice. + +%D Out of convenience we define the banners here. + +\def\contextbanner + {ConTeXt \space + ver: \contextversion \space \contextmark \space \space + fmt: \formatversion \space \space + int: \currentinterface/\currentresponses} + +\def\showcontextbanner + {\writeline\writebanner{\contextbanner}\writeline} + +\edef\formatversion + {\the\normalyear.\the\normalmonth.\the\normalday} + +\ifx\contextversion\undefined + \def\contextversion {unknown} + \def\contextversionnumber{0} +\else + \def\contextversionnumber#1.#2.#3 #4:#5\relax{#1\ifnum#2<10 0\fi#2\ifnum#3<10 0\fi#3 #4:#5} + \edef\contextversionnumber{\expandafter\contextversionnumber\contextversion\relax\space\contextmark} +\fi + +\ifx\undefined\everydump + \newtoks\everydump + \def\dump{\the\everydump\normaldump} +\fi + +\appendtoks \showcontextbanner \to \everydump + +\protect \endinput diff --git a/tex/context/base/mult-ini.mkiv b/tex/context/base/mult-ini.mkiv new file mode 100644 index 000000000..e20548f9b --- /dev/null +++ b/tex/context/base/mult-ini.mkiv @@ -0,0 +1,865 @@ +%D \module +%D [ file=mult-ini, +%D version=2008.10.22, % 1996.06.01, +%D title=\CONTEXT\ Multilingual 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 is a stripped down version of \type {mult-ini.tex}, +%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} + +\unprotect + +\registerctxluafile{mult-ini}{1.001} + +%D \macros +%D [constanten,variabelen,commands] +%D {v!,c!,k!,s!,e!,m!,l!,r!,f!,p!,x!,y!} +%D +%D In the system modules we introduced some prefixed constants, +%D variables (both macros) and registers. Apart from a +%D tremendous saving in terms of memory and a gain in speed we +%D use from now on prefixes when possible for just another +%D reason: consistency and multi||linguality. Systematically +%D using prefixed macros enables us to implement a +%D multi||lingual user interface. Redefining these next set of +%D prefixes therefore can have desastrous results. +%D +%D \startlinecorrection +%D \starttable[|c|c|c|] +%D \HL +%D \NC \bf prefix \NC \bf meaning \NC \bf application \NC\SR +%D \HL +%D \NC \type{\c!prefix!} \NC c! \NC constant (direct) \NC\FR +%D \NC \type{\e!prefix!} \NC e! \NC element \NC\MR +%D \NC \type{\f!prefix!} \NC f! \NC file \NC\MR +%D \NC \type{\k!prefix!} \NC k! \NC constant (indirect) \NC\MR +%D \NC \type{\l!prefix!} \NC l! \NC language \NC\MR +%D \NC \type{\m!prefix!} \NC m! \NC message \NC\MR +%D \NC \type{\p!prefix!} \NC p! \NC procedure \NC\MR +%D \NC \type{\r!prefix!} \NC r! \NC reference \NC\MR +%D \NC \type{\s!prefix!} \NC s! \NC system \NC\MR +%D \NC \type{\v!prefix!} \NC v! \NC variable \NC\MR +%D \HL +%D \stoptable +%D \stoplinecorrection +%D +%D In the single||lingual version we used \type{!}, \type{!!}, +%D \type{!!!} and \type{!!!!}. + +\def\c!prefix!{c!} \def\e!prefix!{e!} \def\f!prefix!{f!} +\def\k!prefix!{k!} \def\l!prefix!{l!} \def\m!prefix!{m!} +\def\p!prefix!{p!} \def\r!prefix!{r!} \def\s!prefix!{s!} +\def\v!prefix!{v!} \def\t!prefix!{t!} + +%D \macros +%D [constants,variables,commands] +%D {@@,??} +%D +%D Variables generated by the system can be recognized on their +%D prefix \type{@@}. They are composed of a command (class) +%D specific tag, which can be recognized on \type{??}, and a +%D system constant, which has the prefix \type{c!}. We'll se +%D some more of this. + +\def\??prefix {??} +\def\@@prefix {@@} + +%D Just to be complete we repeat some of the already defined +%D system constants here. Maybe their prefix \type{\s!} now +%D falls into place. + +\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!true {true} +\def\s!false {false} + +%D The word \type{height} takes 6~token memory cells. The +%D control sequence \type{\height} on the other hand uses only +%D one. Knowing this, we can improve the performance of \TEX, +%D both is terms of speed and memory usage, by using control +%D sequences instead of the words written in full. +%D +%D Where in the \ASCII\ file the second lines takes nine extra +%D characters, \TEX\ saves us 13~tokens. +%D +%D \starttyping +%D \hrule width 10pt height 2pt depth 1pt +%D \hrule \!!width 10pt \!!height 2pt \!!depth 1pt +%D \stoptyping +%D +%D One condition is that we have defined \type{\!!height}, +%D \type{\!!width} and \type{\!!depth} as respectively +%D \type{height}, \type{width} and \type{depth}. Using this +%D scheme therefore only makes sense when a token sequence is +%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\!!spread{spread} + +%D Kind of special: + +\edef\!!TLT{\detokenize{TLT}} +\edef\!!TRT{\detokenize{TRT}} + +%D \macros +%D {defineinterfaceconstant, +%D defineinterfacevariable, +%D defineinterfaceelement, +%D definesystemvariable, +%D definesystemconstant, +%D definemessageconstant, +%D definereferenceconstant, +%D definefileconstant} +%D +%D The first part of this module is dedicated to dealing with +%D multi||lingual constants and variables. When \CONTEXT\ grew +%D bigger and bigger in terms of bytes and used string space, +%D we switched to predefined constants. At the cost of more +%D hash table entries, the macros not only becase more compact, +%D they became much faster too. Maybe an even bigger advantage +%D was that mispelling could no longer lead to problems. Even a +%D multi||lingual interface became possible. +%D +%D Constants --- we'll introduce the concept of variables later +%D on --- are preceded by a type specific prefix, followed by a +%D \type{!}. To force consistency, we provide a few commands +%D for defining such constants. +%D +%D \starttyping +%D \defineinterfaceconstant {name} {meaning} +%D \defineinterfacevariable {name} {meaning} +%D \defineinterfaceelement {name} {meaning} +%D \stoptyping +%D +%D Which is the same as: +%D +%D \starttyping +%D \def\c!name{meaning} +%D \def\v!name{meaning} +%D \def\e!name{meaning} +%D \stoptyping + +\unexpanded\def\defineinterfaceconstant #1#2{\setvalue{\c!prefix!#1}{#2}} +\unexpanded\def\defineinterfacevariable #1#2{\setvalue{\v!prefix!#1}{#2}} +\unexpanded\def\defineinterfaceelement #1#2{\setvalue{\e!prefix!#1}{#2}} + +%D Next come some interface independant constants: +%D +%D \starttyping +%D \definereferenceconstant {name} {meaning} +%D \definefileconstant {name} {meaning} +%D \stoptyping + +\unexpanded\def\definereferenceconstant #1#2{\setvalue{\r!prefix!#1}{#2}} +\unexpanded\def\definefileconstant #1#2{\setvalue{\f!prefix!#1}{#2}} + +%D A new one: + +\unexpanded\def\definetypescriptconstant#1#2{\setvalue{\t!prefix!#1}{#2}} + +%D And finaly we have the one argument, space saving constants +%D +%D \starttyping +%D \definesystemconstant {name} +%D \definemessageconstant {name} +%D \stoptyping + +\unexpanded\def\definesystemconstant #1{\setvalue{\s!prefix!#1}{#1}} +\unexpanded\def\definemessageconstant #1{\setvalue{\m!prefix!#1}{#1}} + +%D In a parameter driven system, some parameters are shared +%D by more system components. In \CONTEXT\ we can distinguish +%D parameters by a unique prefix. Such a prefix is defined +%D with: +%D +%D \starttyping +%D \definesystemvariable {name} +%D \stoptyping + +\unexpanded\def\definesystemvariable#1{\setevalue{\??prefix#1}{\@@prefix#1}} + +\definesystemvariable{ms} + +%D \macros +%D {selectinterface, +%D defaultinterface, currentinterface, currentresponses} +%D +%D With \type{\selectinterface} we specify the language we are +%D going to use. The system asks for the language wanted, and +%D defaults to \type{\currentinterface} when we just give +%D \type{enter}. By default the message system uses the +%D current interface language, but \type{\currentresponses} +%D can specify another language too. +%D +%D Because we want to generate formats directly too, we do +%D not ask for interface specifications when these are already +%D defined (like in cont-nl.tex and alike). + +\ifx\defaultinterface\undefined + + \def\defaultinterface{english} + + \def\selectinterface + {\def\docommand##1##2% + {\bgroup + \endlinechar\minusone + \global\read16 to ##1 + \egroup + \doifnothing\currentinterface{\let##1=##2}% + \doifundefined{\s!prefix!##1}{\let##1=##2}}% + \docommand\currentinterface\defaultinterface + \writestatus{interface}{defining \currentinterface\space interface}% + \writeline + \docommand\currentresponses\currentinterface + \writestatus{interface}{using \currentresponses\space messages}% + \writeline + \let\selectinterface\relax} + +\else + + \def\selectinterface + {\writestatus{interface}{defining \currentinterface\space interface}% + \writeline + \writestatus{interface}{using \currentresponses\space messages}% + \writeline + \let\selectinterface\relax} + +\fi + +\ifx\currentinterface\undefined \let\currentinterface\defaultinterface \fi +\ifx\currentresponses\undefined \let\currentresponses\defaultinterface \fi + +%D \macros +%D {startinterface} +%D +%D Sometimes we want to define things only for specific +%D interface languages. This can be done by means of the +%D selector: +%D +%D \starttyping +%D \startinterface language +%D +%D language specific definitions & commands +%D +%D \stopinterface +%D \stoptyping + +\unexpanded\def\startinterface #1 + {\doifnot{#1}{all}{\doifnotinset\currentinterface{#1}{\gobbleuntil\stopinterface}}} + +\let\stopinterface\relax + +%D \macros +%D {startmessages, +%D getmessage, +%D showmessage, +%D makemessage} +%D +%D A package as large as \CONTEXT\ can hardly function without +%D a decent message mechanism. Due to its multi||lingual +%D interface, the message subsystem has to be multi||lingual +%D too. A major drawback of this feature is that we have to +%D code messages. As a result, the source becomes less self +%D documented. On the other hand, consistency will improve. +%D +%D Because the overhead in terms of entries in the (already +%D exhausted) hash table has to be minimal, messages are packed +%D in libraries. We can extract a message from such a library +%D in three ways: +%D +%D \starttyping +%D \getmessage {library} {tag} +%D \showmessage {library} {tag} {data} +%D \makemessage {library} {tag} {data} +%D \stoptyping +%D +%D The first command gets the message \type{tag} from the +%D \type{library} specified. The other commands take an extra +%D argument: a list of items to be inserted in the message +%D text. While \type{\showmessage} shows the message at the +%D terminal, the other commands generate the message as text. +%D Before we explain the \type{data} argument, we give an +%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 \stoptyping +%D +%D The first message is a simple one and can be shown with: +%D +%D \starttyping +%D \showmessage {alfa} {1} {} +%D \stoptyping +%D +%D The second message on the other hand needs some extra data: +%D +%D \starttyping +%D \showmessage {alfa} {2} {and last,to you} +%D \stoptyping +%D +%D This message is shown as: +%D +%D \starttyping +%D something : second (and last) message to you +%D \stoptyping +%D +%D As we can see, the title entry is shown with the message. +%D The data fields are comma separated and are specified in the +%D message text by \type{--}. +%D +%D It is not required to define all messages in a library at +%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 \stoptyping +%D +%D Because such definitions can take place in different +%D modules, the system gives a warning when a tag occurs more +%D than once. The first occurrence takes preference over later +%D ones, so we had better use a save offset, as shown in the +%D example. As we can see, the title field is specified only +%D the first time! +%D +%D Because we want to check for duplicate tags, the macros +%D are a bit more complicated than neccessary. The \NEWLINE\ +%D token is used as message separator. +%D +%D For internal purposes one can use \type {\setmessagetext}, +%D which puts the message text asked for in \type +%D {\currentmessagetext}. + +\unexpanded\def\startmessages #1 library: #2 % + {\bgroup + \ifcsname\m!prefix!#2\endcsname\else\setgvalue{\m!prefix!#2}{#2}\fi + \catcode13=\active + \doifinsetelse{#1}{\currentresponses,all}\dostartmessages\nostartmessages{#2}} + +\def\dostartmessages#1#2\stopmessages + {\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\doifelsemessage #1#2{\ctxlua{interfaces.doifelsemessage("#1","#2")}} +\unexpanded\def\getmessage #1#2{\ctxlua{tex.sprint(tex.ctxcatcodes,interfaces.getmessage("#1","#2"))}} +\unexpanded\def\getmessagedefault#1#2#3{\ctxlua{tex.sprint(tex.ctxcatcodes,interfaces.getmessage("#1","#2","#3"))}} +\unexpanded\def\makemessage #1#2#3{\ctxlua{tex.sprint(tex.ctxcatcodes,interfaces.makemessage("#1","#2","#3"))}} +\unexpanded\def\showmessage #1#2#3{\ctxlua{interfaces.showmessage("#1","#2","#3")}} + +%D \macros +%D {ifshowwarnings, ifshowmessages} +%D +%D Sometimes displaying message can slow down processing +%D considerably. We therefore introduce warnings. Users can +%D turn of warnings and messages by saying: +%D +%D \starttyping +%D \showwarningstrue +%D \showmessagestrue +%D \stoptyping +%D +%D Turning off messages also turns off warnings, which is +%D quote logical because they are less important. + +% not yet mkiv + +\newif\ifshowwarnings \showwarningstrue +\newif\ifshowmessages \showmessagestrue + +\let\normalshowmessage\showmessage + +\def\showwarning + {\ifshowwarnings + \expandafter\showmessage + \else + \expandafter\gobblethreearguments + \fi} + +\def\showmessage + {\ifshowmessages + \expandafter\normalshowmessage + \else + \expandafter\gobblethreearguments + \fi} + +%D \macros +%D {dosetvalue,dosetevalue,dosetgvalue,dosetxvalue,docopyvalue,doresetvalue} % dogetvalue +%D +%D We already defined these auxiliary macros in the system +%D modules. Starting with this module however, we have to take +%D multi||linguality a bit more serious. +%D +%D The additional \type {\c!internal!n} prefixing is no longer +%D needed as we now have separate interface files when dealing +%D with setups (quick ref docs) and no longer reload the whole +%D interface. (We no longer need the link back to the main +%D internal interface.) + +\def\doresetvalue#1#2% + {\dosetvalue{#1}{#2}{}} + +\def\doignorevalue#1#2#3% + {\dosetvalue{#1}{#2}{}} + +\def\dosetvalue#1#2% + {\let\c!internal!\c!internal!n + \ifcsname\k!prefix!#2\endcsname + \let\c!internal!\c!internal!y + \@EA\def\csname#1\csname\k!prefix!#2\endcsname%\endcsname + \else + \let\c!internal!\c!internal!y + \@EA\def\csname#1#2%\endcsname + \fi\endcsname} + +\def\dosetevalue#1#2% + {\let\c!internal!\c!internal!n + \ifcsname\k!prefix!#2\endcsname + \let\c!internal!\c!internal!y + \@EA\edef\csname#1\csname\k!prefix!#2\endcsname%\endcsname + \else + \let\c!internal!\c!internal!y + \@EA\edef\csname#1#2%\endcsname + \fi\endcsname} + +\def\dosetgvalue#1#2% + {\let\c!internal!\c!internal!n + \ifcsname\k!prefix!#2\endcsname + \let\c!internal!\c!internal!y + \@EA\gdef\csname#1\csname\k!prefix!#2\endcsname%\endcsname + \else + \let\c!internal!\c!internal!y + \@EA\gdef\csname#1#2%\endcsname + \fi\endcsname} + +\def\dosetxvalue#1#2% + {\let\c!internal!\c!internal!n + \ifcsname\k!prefix!#2\endcsname + \let\c!internal!\c!internal!y + \@EA\xdef\csname#1\csname\k!prefix!#2\endcsname%\endcsname + \else + \let\c!internal!\c!internal!y + \@EA\xdef\csname#1#2%\endcsname + \fi\endcsname} + +\def\docopyvalue#1#2#3% real tricky expansion, quite unreadable + {\let\c!internal!\c!internal!n + \ifcsname\k!prefix!#3\endcsname + \let\c!internal!\c!internal!y + \@EA\def\csname#1\csname\k!prefix!#3\endcsname + \@EA\endcsname\@EA{\csname#2\csname\k!prefix!#3\endcsname\endcsname}% + \else + \let\c!internal!\c!internal!y + \@EA\def\csname#1#3\@EA\endcsname\@EA{\csname#2#3\endcsname}% + \fi} + +%D We can now redefine some messages that will be +%D introduced in the multi||lingual system module. + +\def\showassignerror #1#2{\showmessage\m!check1{#1,#2}\waitonfatalerror} +\def\showargumenterror#1#2{\showmessage\m!check2{#1,#2}\waitonfatalerror} +\def\showdefinederror #1#2{\showmessage\m!check3{#1,#2}\waitonfatalerror} + +%D \CONTEXT\ is a parameter driven package. This means that +%D users instruct the system by means of variables, values and +%D keywords. These instructions take the form: +%D +%D \starttyping +%D \setupsomething[some variable=some value, another one=a keyword] +%D \stoptyping +%D +%D or by keyword only: +%D +%D \starttyping +%D \dosomething[this way,that way,no way] +%D \stoptyping +%D +%D Because the same variables can occur in more than one setup +%D command, we have to be able to distinguish them. This is +%D achieved by assigning them a unique prefix. +%D +%D Imagine a setup command for boxed text, that enables us to +%D specify the height and width of the box. Behide the scenes +%D the command +%D +%D \starttyping +%D \setupbox [width=12cm, height=3cm] +%D \stoptyping +%D +%D results in something like +%D +%D \starttyping +%D \ {12cm} +%D \ {3cm} +%D \stoptyping +%D +%D while a similar command for specifying the page dimensions +%D of an \cap{A4} page results in: +%D +%D \starttyping +%D \ {21.0cm} +%D \ {27.9cm} +%D \stoptyping +%D +%D The prefixes \type{} and \type{} are hidden from +%D users and can therefore be language independant. Variables +%D on the other hand, differ for each language: +%D +%D \starttyping +%D \ {} +%D \ {} +%D \ {} +%D \stoptyping +%D +%D In this example we can see that the assigned values or +%D keywords are language dependant too. This will be a +%D complication when defining multi||lingual setup files. +%D +%D A third phenomena is that variables and values can have a +%D similar meaning. +%D +%D \starttyping +%D \ {} +%D \ {12cm} +%D \stoptyping +%D +%D A (minor) complication is that where in english we use +%D \type{}, in dutch we find both \type{} and +%D \type{}. This means that when we use some sort of +%D translation table, we have to distinguish between the +%D variables at the left side and the fixed values at the +%D right. +%D +%D The same goes for commands that are composed of different +%D user supplied and/or language specific elements. In english +%D we can use: +%D +%D \starttyping +%D \
+%D \ +%D \stoptyping +%D +%D But in dutch we have the following: +%D +%D \starttyping +%D \ +%D \ +%D \stoptyping +%D +%D These subtle differences automatically lead to a solution +%D where variables, values, elements and other components have +%D a similar logical name (used in macro's) but a different +%D meaning (supplied by the user). +%D +%D Our solution is one in which the whole system is programmed +%D in terms of identifiers with language specific meanings. In +%D such an implementation, each fixed variable is available as: +%D +%D \starttyping +%D \ +%D \stoptyping +%D +%D This means that for instance: +%D +%D \starttyping +%D \setupbox[width=12cm] +%D \stoptyping +%D +%D expands to something like: +%D +%D \starttyping +%D \def\boxwidth{12cm} +%D \stoptyping +%D +%D because we don't want to recode the source, a setup command +%D in another language has to expand to this variable, so: +%D +%D \starttyping +%D \setupblock[width=12cm] +%D \stoptyping +%D +%D has to result in the definition of \type{\boxwidth} too. +%D This method enables us to build compact, fast and readable +%D code. +%D +%D An alternative method, which we considered using, uses a +%D more indirect way. In this case, both calls generate a +%D different variable: +%D +%D \starttyping +%D \def\boxwidth {12cm} +%D \def\boxbreedte {12cm} +%D \stoptyping +%D +%D And because we don't want to recode those megabytes of +%D already developed code, this variable has to be called with +%D something like: +%D +%D \starttyping +%D \valueof\box\width +%D \stoptyping +%D +%D where \type{\valueof} takes care of the translation of +%D \type{width} or \type{breedte} to \type{width} and +%D combining this with \type{box} to \type{\boxwidth}. +%D +%D One advantage of this other scheme is that, within certain +%D limits, we can implement an interface that can be switched +%D to another language at will, while the current approach +%D fixes the interface at startup. There are, by the way, +%D other reasons too for not choosing this scheme. Switching +%D user generated commands is for instance impossible and a +%D dual interface would therefore give a strange mix of +%D languages. +%D +%D Now let's work out the first scheme. Although the left hand +%D of the assignment is a variable from the users point of +%D view, it is a constant in terms of the system. Both +%D \type{width} and \type{breedte} expand to \type{width} +%D because in the source we only encounter \type{width}. Such +%D system constants are presented as +%D +%D \starttyping +%D \c!width +%D \stoptyping +%D +%D This constant is always equivalent to \type{width}. As we +%D can see, we use \type{c!} to mark this one as constant. Its +%D dutch counterpart is: +%D +%D \starttyping +%D breedte +%D \stoptyping +%D +%D When we interpret a setup command each variable is +%D translated to it's \type{c!} counterpart. This means that +%D \type{breedte} and \type{width} expand to \type{breedte} +%D and \type{\c!width} which both expand to \type{width}. That +%D way user variables become system constants. +%D +%D The interpretation is done by means of a general setup +%D command \type{\getparameters} that we introduced in the +%D system module. Let us define some simple setup command: +%D +%D \starttyping +%D \unexpanded\def\setupbox[#1]% +%D {\getparameters[\??bx][#1]} +%D \stoptyping +%D +%D This command can be used as: +%D +%D \starttyping +%D \setupbox [width=3cm, height=1cm] +%D \stoptyping +%D +%D Afterwards we have two variables \type{\@@bxwidth} and +%D \type{\@@bxheight} which have the values \type{3cm} and +%D \type{1cm} assigned. These variables are a combinatiom of +%D the setup prefix \type{\??bx}, which expands to \type{@@bx} +%D and the translated user supplied variables \type{width} and +%D \type{height} or \type{breedte} and \type{hoogte}, +%D depending on the actual language. In dutch we just say: +%D +%D \starttyping +%D \stelblokin [breedte=3cm,hoogte=1cm] +%D \stoptyping +%D +%D and get ourselves \type{\@@bxwidth} and \type{\@@bxheight} +%D too. In the source of \CONTEXT, we can recognize constants +%D and variables on their leading \type{c!}, \type{v!} etc., +%D prefixes on \type{??} and composed variables on \type{@@}. +%D +%D We already saw that user supplied keywords need some +%D special treatment too. This time we don't translate the +%D keyword, but instead use in the source a variable which +%D meaning depends on the interface language. +%D +%D \starttyping +%D \v!left +%D \stoptyping +%D +%D Which can be used in macro's like: +%D +%D \starttyping +%D \processaction +%D [\@@bxlocation] +%D [ \v!left=>\dosomethingontheleft, +%D \v!middle=>\dosomthinginthemiddle, +%D \v!right=>\dosomethingontheright] +%D \stoptyping +%D +%D Because variables like \type{\@@bxlocation} can have a lot +%D of meanings, including tricky expandable tokens, we cannot +%D translate this meaning when we compare. This means that +%D \type{\@@bxlocation} can be \type{left} of \type{links} of +%D whatever meaning suits the language. But because +%D \type{\v!left} also has a meaning that suits the language, +%D we are able to compare. +%D +%D Although we know it sounds confusing we want to state two +%D important characteristics of the interface as described: +%D +%D \startnarrower \em +%D user variables become system constants +%D \stopnarrower +%D +%D and +%D +%D \startnarrower \em +%D user constants (keywords) become system variables +%D \stopnarrower + +%D Anno 2003 I've forgotten why the \type {\c!internal} is +%D still in there; it's probably a left over from the time that +%D the user interface documents were not using a specification +%D alongside a keyword specification but used a shared file in +%D which case we need to go in both directions. + +\let\c!internal!y \string +\def\c!internal!n {-} +\let\c!internal! \c!internal!y + +% temporary mkiv hack (we can best just store the whole table in memory) + +\def\setinterfaceconstant#1#2% + {\ctxlua{interfaces.setconstant("#1","#2")}% + \setvalue{\c!prefix!#1}{\c!internal!#1}% + \setvalue{\k!prefix!#2}{#1}} + +\def\setinterfacevariable#1#2% + {\ctxlua{interfaces.setvariable("#1","#2")}% + \setvalue{\v!prefix!#1}{#2}} + +%D \macros +%D {defineinterfaceconstant} +%D +%D Next we redefine a previously defined macro to take care of +%D interface translation too. It's a bit redundant, because +%D in these situations we could use the c||version, but for +%D documentation purposes the x||alternative comes in handy. + +\unexpanded\def\defineinterfaceconstant#1#2% + {\setvalue{\c!prefix!#1}{#2}} + +%D \macros +%D {startelements} +%D +%D Due to the object oriented nature of \CONTEXT, we also need +%D to define the elements that are used to build commands. +%D +%D Such elements sometimes are the same in diferent +%D languages, but mostly they differ. Things can get even +%D confusing when we look at for instance the setup commands. +%D In english we say \type{\setup}, but in dutch we +%D have: \type{\stelin}. Such split elements are no +%D problem, because we just define two elements. When no second +%D part is needed, we use a \type{-}: + +\def\setinterfaceelement#1#2% + {\ifcsname\e!prefix!#1\endcsname + \doifnotvalue{\e!prefix!#1}{#2}{\setvalue{\e!prefix!#1}{#2}}% + \else + \setvalue{\e!prefix!#1}{#2}% + \fi} + +\def\setinterfacecommand#1#2% + {\doifnot{#1}{#2}{\@EA\def\csname#2\@EA\endcsname\@EA{\csname#1\endcsname}}}% or just \let ? + +%D We just ignore these: + +\unexpanded\def\startvariables{\gobbleuntil\stopvariables} +\unexpanded\def\startconstants{\gobbleuntil\stopconstants} +\unexpanded\def\startelements {\gobbleuntil\stopelements} +\unexpanded\def\startcommands {\gobbleuntil\stopcommands} + +%D \macros +%D {interfaced} +%D +%D The setup commands translate the constants automatically. +%D When we want to translate 'by hand' we can use the simple +%D but effective command: +%D +%D \starttyping +%D \interfaced {something} +%D \stoptyping +%D +%D Giving \type{\interfaced{breedte}} results in \type{width} +%D or, when not defined, in \type{breedte} itself. This +%D macro is used in the font switching mechanism. + +\def\interfaced#1% + {\ifcsname\k!prefix!#1\endcsname + \csname\k!prefix!#1\endcsname + \else + #1% + \fi} + +%D So much for the basic multi||lingual interface commands. The +%D macro's can be enhanced with more testing facilities, but +%D for the moment they suffice. + +%D Out of convenience we define the banners here. + +\def\contextbanner + {ConTeXt \space + ver: \contextversion \space \contextmark \space \space + fmt: \formatversion \space \space + int: \currentinterface/\currentresponses} + +\def\showcontextbanner + {\writeline\writebanner{\contextbanner}\writeline} + +\edef\formatversion + {\the\normalyear .\the\normalmonth.\the\normalday} + +\ifx\contextversion\undefined + \def\contextversion {unknown} + \def\contextversionnumber{0} +\else + \def\contextversionnumber#1.#2.#3 #4:#5\relax{#1\ifnum#2<10 0\fi#2\ifnum#3<10 0\fi#3 #4:#5} + \edef\contextversionnumber{\expandafter\contextversionnumber\contextversion\relax\space\contextmark} +\fi + +\ifx\undefined\everydump + \newtoks\everydump + \def\dump{\the\everydump\normaldump} +\fi + +\appendtoks \showcontextbanner \to \everydump + +\protect \endinput diff --git a/tex/context/base/mult-it.tex b/tex/context/base/mult-it.tex new file mode 100644 index 000000000..ce14800de --- /dev/null +++ b/tex/context/base/mult-it.tex @@ -0,0 +1,1693 @@ +% this file is auto-generated, don't edit this file +% +% definitions for interface variables for language it +% +\setinterfacevariable{Addition}{Aggiunta} +\setinterfacevariable{Balloon}{Pallone} +\setinterfacevariable{Character}{Lettera} +\setinterfacevariable{Characters}{Lettere} +\setinterfacevariable{CloseDocument}{ChiudiDocumento} +\setinterfacevariable{ExitViewer}{EsciVisualizzatore} +\setinterfacevariable{FirstPage}{PrimaPagina} +\setinterfacevariable{FitHeight}{FitHeight} +\setinterfacevariable{FitWidth}{FitWidth} +\setinterfacevariable{GotoPage}{VaiAPagina} +\setinterfacevariable{Greek}{Greco} +\setinterfacevariable{Help}{Aiuto} +\setinterfacevariable{HideField}{NascondiCampo} +\setinterfacevariable{HideLayer}{HideLayer} +\setinterfacevariable{Key}{Tasto} +\setinterfacevariable{LastPage}{UltimaPagina} +\setinterfacevariable{LoadForm}{CaricaForm} +\setinterfacevariable{MONTH}{MESE} +\setinterfacevariable{New}{Nuovo} +\setinterfacevariable{NextJump}{SaltoSuccessivo} +\setinterfacevariable{NextPage}{PaginaSuccessiva} +\setinterfacevariable{Numbers}{Numeri} +\setinterfacevariable{OpenNamedDocument}{OpenNamedDocument} +\setinterfacevariable{Paragraph}{Capoverso} +\setinterfacevariable{PauseMovie}{PausaFilm} +\setinterfacevariable{PauseRendering}{PauseRendering} +\setinterfacevariable{PauseSound}{PausaSuono} +\setinterfacevariable{PreviousJump}{SaltoPrecedente} +\setinterfacevariable{PreviousPage}{PaginaPrecedente} +\setinterfacevariable{PrintDocument}{StampaDocumento} +\setinterfacevariable{Query}{Richiesta} +\setinterfacevariable{QueryAgain}{RinnovaRichiesta} +\setinterfacevariable{ResetForm}{ReimpostaForm} +\setinterfacevariable{ResumeMovie}{RiprendiFilm} +\setinterfacevariable{ResumeRendering}{ResumeRendering} +\setinterfacevariable{ResumeSound}{RiprendiSuono} +\setinterfacevariable{Romannumerals}{Numeriromani} +\setinterfacevariable{SaveDocument}{SalvaDocumento} +\setinterfacevariable{SaveForm}{SalvaForm} +\setinterfacevariable{SaveNamedDocument}{SaveNamedDocument} +\setinterfacevariable{SearchAgain}{CercaAncora} +\setinterfacevariable{SearchDocument}{CercaDocumento} +\setinterfacevariable{ShowBookmarks}{MostraSegnalibro} +\setinterfacevariable{ShowField}{MostraCampo} +\setinterfacevariable{ShowThumbs}{MostraThumbs} +\setinterfacevariable{StartMovie}{IniziaFilm} +\setinterfacevariable{StartRendering}{StartRendering} +\setinterfacevariable{StartSound}{IniziaSuono} +\setinterfacevariable{StopMovie}{FermaFilm} +\setinterfacevariable{StopRendering}{StopRendering} +\setinterfacevariable{StopSound}{FermaSuono} +\setinterfacevariable{SubmitForm}{MandaForm} +\setinterfacevariable{ToggleLayer}{ToggleLayer} +\setinterfacevariable{ToggleViewer}{ScambiaVisualizzatore} +\setinterfacevariable{URL}{URL} +\setinterfacevariable{VideLayer}{VideLayer} +\setinterfacevariable{ViewerHelp}{AiutoVisualizzatore} +\setinterfacevariable{WEEKDAY}{GIORNOSETTIMANA} +\setinterfacevariable{WORD}{PAROLA} +\setinterfacevariable{abbreviation}{abbreviazione} +\setinterfacevariable{abbreviations}{abbreviazioni} +\setinterfacevariable{absolute}{assoluto} +\setinterfacevariable{action}{azione} +\setinterfacevariable{after}{dopo} +\setinterfacevariable{all}{tutti} +\setinterfacevariable{always}{sempre} +\setinterfacevariable{answerarea}{answerarea} +\setinterfacevariable{appendices}{appendici} +\setinterfacevariable{appendix}{appendice} +\setinterfacevariable{april}{aprile} +\setinterfacevariable{atmargin}{almargine} +\setinterfacevariable{atpage}{apagina} +\setinterfacevariable{august}{agosto} +\setinterfacevariable{author}{autore} +\setinterfacevariable{auto}{auto} +\setinterfacevariable{autointro}{autointro} +\setinterfacevariable{back}{dietro} +\setinterfacevariable{background}{sfondo} +\setinterfacevariable{backmatter}{postambolo} +\setinterfacevariable{backpart}{postfazione} +\setinterfacevariable{backspace}{backspace} +\setinterfacevariable{backward}{indietro} +\setinterfacevariable{bbl}{bbl} +\setinterfacevariable{before}{prima} +\setinterfacevariable{begin}{begin} +\setinterfacevariable{bib}{bib} +\setinterfacevariable{big}{grande} +\setinterfacevariable{bigbodyfont}{grossofontdeltesto} +\setinterfacevariable{bigpreference}{grandepreferenza} +\setinterfacevariable{blank}{rigovuoto} +\setinterfacevariable{blockquote}{blockquote} +\setinterfacevariable{bodymatter}{testiprincipali} +\setinterfacevariable{bodypart}{testoprincipale} +\setinterfacevariable{bold}{grassetto} +\setinterfacevariable{bolditalic}{grassettocorsivo} +\setinterfacevariable{boldslanted}{grassettoinclinato} +\setinterfacevariable{bookmark}{segnalibro} +\setinterfacevariable{both}{entrambi} +\setinterfacevariable{bottom}{fondo} +\setinterfacevariable{brief}{brief} +\setinterfacevariable{broad}{ampio} +\setinterfacevariable{buffer}{buffer} +\setinterfacevariable{by}{da} +\setinterfacevariable{calligraphic}{calligrafico} +\setinterfacevariable{cap}{cap} +\setinterfacevariable{capital}{maiuscolo} +\setinterfacevariable{center}{center} +\setinterfacevariable{chapter}{capitolo} +\setinterfacevariable{character}{lettera} +\setinterfacevariable{characters}{lettere} +\setinterfacevariable{cite}{cite} +\setinterfacevariable{color}{colore} +\setinterfacevariable{column}{colonna} +\setinterfacevariable{columns}{colonne} +\setinterfacevariable{command}{comando} +\setinterfacevariable{commands}{comandi} +\setinterfacevariable{comment}{commento} +\setinterfacevariable{component}{componente} +\setinterfacevariable{concept}{concetto} +\setinterfacevariable{content}{indice} +\setinterfacevariable{contents}{indici} +\setinterfacevariable{continue}{continua} +\setinterfacevariable{controls}{controlli} +\setinterfacevariable{conversion}{coversione} +\setinterfacevariable{current}{corrente} +\setinterfacevariable{cutspace}{cutspace} +\setinterfacevariable{date}{data} +\setinterfacevariable{day}{giorno} +\setinterfacevariable{december}{dicembre} +\setinterfacevariable{default}{implicito} +\setinterfacevariable{depth}{profondita} +\setinterfacevariable{description}{descrizione} +\setinterfacevariable{disable}{disattiva} +\setinterfacevariable{display}{schermo} +\setinterfacevariable{dot}{punto} +\setinterfacevariable{doublesided}{doppiafaccia} +\setinterfacevariable{down}{down} +\setinterfacevariable{each}{ogni} +\setinterfacevariable{edge}{bordo} +\setinterfacevariable{empty}{vuoto} +\setinterfacevariable{end}{end} +\setinterfacevariable{endnote}{endnote} +\setinterfacevariable{enumeration}{enumerazione} +\setinterfacevariable{environment}{ambiente} +\setinterfacevariable{even}{pari} +\setinterfacevariable{external}{esterno} +\setinterfacevariable{fact}{fatto} +\setinterfacevariable{february}{febbraio} +\setinterfacevariable{figure}{figura} +\setinterfacevariable{figures}{figure} +\setinterfacevariable{file}{file} +\setinterfacevariable{final}{finale} +\setinterfacevariable{first}{primo} +\setinterfacevariable{firstcolumn}{firstcolumn} +\setinterfacevariable{firstpage}{primapagina} +\setinterfacevariable{firstsubpage}{primasottopagina} +\setinterfacevariable{fit}{adatta} +\setinterfacevariable{five}{cinque} +\setinterfacevariable{fix}{fisso} +\setinterfacevariable{fixed}{fisso} +\setinterfacevariable{flexible}{flessibile} +\setinterfacevariable{float}{oggettomobile} +\setinterfacevariable{flushinner}{flushinner} +\setinterfacevariable{flushleft}{flushleft} +\setinterfacevariable{flushouter}{flushouter} +\setinterfacevariable{flushright}{flushright} +\setinterfacevariable{footer}{piedipagina} +\setinterfacevariable{footnote}{notapdp} +\setinterfacevariable{force}{forza} +\setinterfacevariable{foreground}{foreground} +\setinterfacevariable{formeel}{formeel} +\setinterfacevariable{formula}{formula} +\setinterfacevariable{formulae}{formule} +\setinterfacevariable{forward}{avanti} +\setinterfacevariable{four}{quattro} +\setinterfacevariable{frame}{cornice} +\setinterfacevariable{framedtext}{testoincorniciato} +\setinterfacevariable{friday}{venerdi} +\setinterfacevariable{frontmatter}{preambolo} +\setinterfacevariable{frontpart}{prefazione} +\setinterfacevariable{global}{globale} +\setinterfacevariable{graphic}{grafico} +\setinterfacevariable{graphics}{grafici} +\setinterfacevariable{gray}{grigio} +\setinterfacevariable{greek}{greco} +\setinterfacevariable{grid}{griglia} +\setinterfacevariable{halfline}{mezzariga} +\setinterfacevariable{handwritten}{grafiamanuale} +\setinterfacevariable{hang}{sospendi} +\setinterfacevariable{hanging}{sospeso} +\setinterfacevariable{head}{testa} +\setinterfacevariable{header}{intestazione} +\setinterfacevariable{height}{altezza} +\setinterfacevariable{helptext}{testoaiuto} +\setinterfacevariable{hencefore}{precedente} +\setinterfacevariable{here}{qui} +\setinterfacevariable{hereafter}{seguente} +\setinterfacevariable{hidden}{nascosto} +\setinterfacevariable{hiding}{nascondere} +\setinterfacevariable{high}{alto} +\setinterfacevariable{horizontal}{orizzontale} +\setinterfacevariable{hyphenated}{sillabato} +\setinterfacevariable{hz}{hz} +\setinterfacevariable{inbetween}{tra} +\setinterfacevariable{index}{indiceanalitico} +\setinterfacevariable{indices}{indicianalitici} +\setinterfacevariable{informeel}{informeel} +\setinterfacevariable{inherit}{inherit} +\setinterfacevariable{inleft}{insinistra} +\setinterfacevariable{inmargin}{inmargine} +\setinterfacevariable{inner}{interno} +\setinterfacevariable{inneredge}{bordointerno} +\setinterfacevariable{innermargin}{margineinterno} +\setinterfacevariable{inright}{indestra} +\setinterfacevariable{interaction}{interazione} +\setinterfacevariable{interactionmenu}{menuinterattivo} +\setinterfacevariable{intermezzi}{intermezzi} +\setinterfacevariable{intermezzo}{intermezzo} +\setinterfacevariable{intext}{intesto} +\setinterfacevariable{intro}{intro} +\setinterfacevariable{italic}{corsivo} +\setinterfacevariable{italicbold}{corsivograssetto} +\setinterfacevariable{item}{elemento} +\setinterfacevariable{itemize}{elenco} +\setinterfacevariable{its}{its} +\setinterfacevariable{january}{gennaio} +\setinterfacevariable{joinedup}{unito} +\setinterfacevariable{july}{luglio} +\setinterfacevariable{june}{giugno} +\setinterfacevariable{keep}{mantieni} +\setinterfacevariable{knockout}{knockout} +\setinterfacevariable{label}{etichetta} +\setinterfacevariable{landscape}{orizzontale} +\setinterfacevariable{last}{ultimo} +\setinterfacevariable{lastcolumn}{lastcolumn} +\setinterfacevariable{lastpage}{ultimapagina} +\setinterfacevariable{lastpagenumber}{lastpagenumber} +\setinterfacevariable{lastsubpage}{ultimasottopagina} +\setinterfacevariable{layer}{layer} +\setinterfacevariable{left}{sinistra} +\setinterfacevariable{leftedge}{bordosinistro} +\setinterfacevariable{lefthanging}{lefthanging} +\setinterfacevariable{leftmargin}{marginesinistro} +\setinterfacevariable{leftpage}{paginasinistra} +\setinterfacevariable{lefttoright}{lefttoright} +\setinterfacevariable{legend}{legenda} +\setinterfacevariable{lesshyphenation}{lesshyphenation} +\setinterfacevariable{line}{riga} +\setinterfacevariable{linenote}{linenote} +\setinterfacevariable{lines}{righe} +\setinterfacevariable{list}{elenco} +\setinterfacevariable{local}{locale} +\setinterfacevariable{localenvironment}{ambientelocale} +\setinterfacevariable{logo}{logo} +\setinterfacevariable{logos}{loghi} +\setinterfacevariable{lohi}{pedap} +\setinterfacevariable{loose}{lento} +\setinterfacevariable{low}{basso} +\setinterfacevariable{ls}{ls} +\setinterfacevariable{makeup}{makeup} +\setinterfacevariable{mar}{mar} +\setinterfacevariable{march}{marzo} +\setinterfacevariable{margin}{margine} +\setinterfacevariable{marginedge}{bordomargine} +\setinterfacevariable{margintitle}{titoloinmargine} +\setinterfacevariable{marking}{marcatura} +\setinterfacevariable{mathalignment}{mathalignment} +\setinterfacevariable{mathcases}{mathcases} +\setinterfacevariable{mathmatrix}{mathmatrix} +\setinterfacevariable{max}{max} +\setinterfacevariable{maxdepth}{maxdepth} +\setinterfacevariable{maxheight}{maxheight} +\setinterfacevariable{maxwidth}{maxwidth} +\setinterfacevariable{may}{maggio} +\setinterfacevariable{mediaeval}{medievale} +\setinterfacevariable{medium}{medio} +\setinterfacevariable{middle}{centro} +\setinterfacevariable{min}{min} +\setinterfacevariable{mindepth}{mindepth} +\setinterfacevariable{minheight}{altezzamin} +\setinterfacevariable{minwidth}{ampiezzamin} +\setinterfacevariable{mirrored}{riflesso} +\setinterfacevariable{monday}{lunedi} +\setinterfacevariable{mono}{mono} +\setinterfacevariable{month}{mese} +\setinterfacevariable{morehyphenation}{morehyphenation} +\setinterfacevariable{name}{nome} +\setinterfacevariable{narrow}{stretto} +\setinterfacevariable{negative}{negativo} +\setinterfacevariable{never}{mai} +\setinterfacevariable{new}{nuovo} +\setinterfacevariable{next}{successivo} +\setinterfacevariable{nextevenpage}{paginaparisuccessiva} +\setinterfacevariable{nextoddpage}{paginadisparisuccessiva} +\setinterfacevariable{nextpage}{paginasuccessiva} +\setinterfacevariable{nextsubpage}{sottopaginasuccessiva} +\setinterfacevariable{no}{no} +\setinterfacevariable{nocheck}{nocheck} +\setinterfacevariable{nofit}{nofit} +\setinterfacevariable{nogrid}{nogrid} +\setinterfacevariable{nohz}{nohz} +\setinterfacevariable{nomarking}{nomarcature} +\setinterfacevariable{none}{nessuno} +\setinterfacevariable{nonumber}{nonumber} +\setinterfacevariable{normal}{normale} +\setinterfacevariable{nospacing}{nospacing} +\setinterfacevariable{not}{non} +\setinterfacevariable{note}{note} +\setinterfacevariable{nothanging}{nonsospeso} +\setinterfacevariable{nothyphenated}{nonsillabato} +\setinterfacevariable{november}{novembre} +\setinterfacevariable{nowhere}{danessunaparte} +\setinterfacevariable{nowhite}{nobianco} +\setinterfacevariable{number}{numero} +\setinterfacevariable{numbers}{numeri} +\setinterfacevariable{october}{ottobre} +\setinterfacevariable{odd}{dispari} +\setinterfacevariable{off}{disattivo} +\setinterfacevariable{offset}{offset} +\setinterfacevariable{old}{old} +\setinterfacevariable{on}{attivo} +\setinterfacevariable{one}{uno} +\setinterfacevariable{opposite}{opposto} +\setinterfacevariable{outer}{esterno} +\setinterfacevariable{outeredge}{bordoesterno} +\setinterfacevariable{outermargin}{margineesterno} +\setinterfacevariable{overbar}{sopralinea} +\setinterfacevariable{overbars}{sopralinee} +\setinterfacevariable{overlay}{sovrapponi} +\setinterfacevariable{overprint}{overprint} +\setinterfacevariable{overstrike}{sbarrato} +\setinterfacevariable{overstrikes}{sbarrati} +\setinterfacevariable{packed}{impaccato} +\setinterfacevariable{page}{pagina} +\setinterfacevariable{pagecomment}{commentopagina} +\setinterfacevariable{pagenumber}{numeropagina} +\setinterfacevariable{paper}{carta} +\setinterfacevariable{paragraph}{capoverso} +\setinterfacevariable{part}{parte} +\setinterfacevariable{positive}{positivo} +\setinterfacevariable{postponing}{posporre} +\setinterfacevariable{postscript}{postscript} +\setinterfacevariable{preference}{preferenza} +\setinterfacevariable{preview}{anteprima} +\setinterfacevariable{previous}{precedente} +\setinterfacevariable{previousevenpage}{paginapariprecedente} +\setinterfacevariable{previousoddpage}{paginadispariprecedente} +\setinterfacevariable{previouspage}{paginaprecedente} +\setinterfacevariable{previoussubpage}{sottopaginaprecedente} +\setinterfacevariable{printable}{stampabile} +\setinterfacevariable{process}{process} +\setinterfacevariable{product}{prodotto} +\setinterfacevariable{program}{programma} +\setinterfacevariable{project}{progetto} +\setinterfacevariable{protected}{protetto} +\setinterfacevariable{quadruple}{quadruplo} +\setinterfacevariable{quotation}{citazione} +\setinterfacevariable{quote}{menzione} +\setinterfacevariable{ran}{corse} +\setinterfacevariable{random}{casuale} +\setinterfacevariable{readonly}{solalettura} +\setinterfacevariable{rectangular}{rettangolare} +\setinterfacevariable{referral}{referral} +\setinterfacevariable{register}{registro} +\setinterfacevariable{regular}{regolare} +\setinterfacevariable{rekening}{rekening} +\setinterfacevariable{relative}{relativo} +\setinterfacevariable{repeat}{ripeti} +\setinterfacevariable{required}{richiestp} +\setinterfacevariable{reset}{reimposta} +\setinterfacevariable{reverse}{invertito} +\setinterfacevariable{right}{destra} +\setinterfacevariable{rightedge}{bordodestro} +\setinterfacevariable{righthanging}{righthanging} +\setinterfacevariable{rightmargin}{marginedestro} +\setinterfacevariable{rightpage}{paginadestra} +\setinterfacevariable{righttoleft}{righttoleft} +\setinterfacevariable{roman}{roman} +\setinterfacevariable{romannumerals}{numeriromani} +\setinterfacevariable{rotate}{ruota} +\setinterfacevariable{rotated}{ruotato} +\setinterfacevariable{round}{rotondo} +\setinterfacevariable{row}{row} +\setinterfacevariable{rule}{linea} +\setinterfacevariable{samepage}{stessapagina} +\setinterfacevariable{sans}{sans} +\setinterfacevariable{sansbold}{sansgrassetto} +\setinterfacevariable{sansserif}{sansserif} +\setinterfacevariable{saturday}{sabato} +\setinterfacevariable{screen}{schermo} +\setinterfacevariable{section}{capoverso} +\setinterfacevariable{sectionblockenvironment}{ambientebloccosezione} +\setinterfacevariable{sectionnumber}{numerosezione} +\setinterfacevariable{see}{vedi} +\setinterfacevariable{september}{settembre} +\setinterfacevariable{serif}{serif} +\setinterfacevariable{serried}{vicino} +\setinterfacevariable{setups}{nastaveni} +\setinterfacevariable{sheet}{sheet} +\setinterfacevariable{short}{short} +\setinterfacevariable{singlesided}{facciasingola} +\setinterfacevariable{slanted}{inclinato} +\setinterfacevariable{slantedbold}{inclinatograssetto} +\setinterfacevariable{small}{piccolo} +\setinterfacevariable{smallbodyfont}{piccolofontdelcorpo} +\setinterfacevariable{smallbold}{piccolograssetto} +\setinterfacevariable{smallbolditalic}{piccolograssettocorsivo} +\setinterfacevariable{smallboldslanted}{piccolograssettoinclinato} +\setinterfacevariable{smallcaps}{maiuscoletto} +\setinterfacevariable{smallitalic}{piccolocorsivo} +\setinterfacevariable{smallitalicbold}{piccolocorsivograssetto} +\setinterfacevariable{smallnormal}{piccolonormale} +\setinterfacevariable{smallslanted}{piccoloinclinato} +\setinterfacevariable{smallslantedbold}{piccoloinclinatograssetto} +\setinterfacevariable{smalltype}{piccolotype} +\setinterfacevariable{somewhere}{daqualcheparte} +\setinterfacevariable{sorted}{ordinato} +\setinterfacevariable{space}{spazio} +\setinterfacevariable{spacing}{spaziatura} +\setinterfacevariable{speech}{speech} +\setinterfacevariable{split}{separa} +\setinterfacevariable{spot}{spot} +\setinterfacevariable{standard}{standard} +\setinterfacevariable{start}{inizia} +\setinterfacevariable{starter}{starter} +\setinterfacevariable{sticker}{sticker} +\setinterfacevariable{stop}{termina} +\setinterfacevariable{stopper}{stopper} +\setinterfacevariable{stretch}{dilata} +\setinterfacevariable{strict}{rigido} +\setinterfacevariable{strong}{strong} +\setinterfacevariable{strut}{strut} +\setinterfacevariable{sub}{sotto} +\setinterfacevariable{subbackward}{sottoindietro} +\setinterfacevariable{subformula}{subformula} +\setinterfacevariable{subforward}{sottoavanti} +\setinterfacevariable{subject}{argomento} +\setinterfacevariable{subpage}{sottopagina} +\setinterfacevariable{subsection}{sottocapoverso} +\setinterfacevariable{subsubject}{sottoargomento} +\setinterfacevariable{subsubsection}{sottosottocapoverso} +\setinterfacevariable{subsubsubject}{sottosottoargomento} +\setinterfacevariable{subsubsubsection}{sottosottosottocapoverso} +\setinterfacevariable{subsubsubsubject}{sottosottosottoargomento} +\setinterfacevariable{subsubsubsubsection}{sottosottosottosottocapoverso} +\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} +\setinterfacevariable{symbol}{simbolo} +\setinterfacevariable{synchronize}{synchronize} +\setinterfacevariable{system}{sistema} +\setinterfacevariable{table}{tabella} +\setinterfacevariable{tablehead}{testatabella} +\setinterfacevariable{tables}{tabelle} +\setinterfacevariable{tabletail}{codatabella} +\setinterfacevariable{tabulate}{tabulato} +\setinterfacevariable{tabulatehead}{testatabulato} +\setinterfacevariable{tabulatetail}{codatabulato} +\setinterfacevariable{tall}{alto} +\setinterfacevariable{teletype}{teletype} +\setinterfacevariable{temporary}{temporaneo} +\setinterfacevariable{test}{test} +\setinterfacevariable{text}{testo} +\setinterfacevariable{three}{tre} +\setinterfacevariable{thursday}{giovedi} +\setinterfacevariable{title}{titolo} +\setinterfacevariable{toggle}{toggle} +\setinterfacevariable{tolerant}{tollerante} +\setinterfacevariable{top}{cima} +\setinterfacevariable{tuesday}{martedi} +\setinterfacevariable{two}{due} +\setinterfacevariable{txt}{txt} +\setinterfacevariable{type}{type} +\setinterfacevariable{typing}{typing} +\setinterfacevariable{unavailable}{nondisponibile} +\setinterfacevariable{underbar}{sottolinea} +\setinterfacevariable{underbars}{sottolinee} +\setinterfacevariable{unit}{unita} +\setinterfacevariable{units}{unita} +\setinterfacevariable{unknown}{ignoto} +\setinterfacevariable{unpacked}{unpacked} +\setinterfacevariable{up}{up} +\setinterfacevariable{url}{url} +\setinterfacevariable{used}{usato} +\setinterfacevariable{value}{valore} +\setinterfacevariable{vertical}{verticale} +\setinterfacevariable{very}{molto} +\setinterfacevariable{verystrict}{moltorigido} +\setinterfacevariable{verytolerant}{moltotollerante} +\setinterfacevariable{weak}{weak} +\setinterfacevariable{wednesday}{mercoledi} +\setinterfacevariable{week}{settimana} +\setinterfacevariable{weekday}{giornosettimana} +\setinterfacevariable{white}{bianco} +\setinterfacevariable{wide}{ampio} +\setinterfacevariable{width}{ampiezza} +\setinterfacevariable{xml}{xml} +\setinterfacevariable{year}{anno} +\setinterfacevariable{yes}{si} +% definitions for interface constants for language it +% +\setinterfaceconstant{action}{azione} +\setinterfaceconstant{address}{indirizzo} +\setinterfaceconstant{after}{dopo} +\setinterfaceconstant{afterhead}{dopotesta} +\setinterfaceconstant{afterkey}{dopotasto} +\setinterfaceconstant{align}{allinea} +\setinterfaceconstant{aligncharacter}{allineacarattere} +\setinterfaceconstant{alignmentcharacter}{carattereallineamento} +\setinterfaceconstant{alignsymbol}{alignsymbol} +\setinterfaceconstant{aligntitle}{allineatitolo} +\setinterfaceconstant{alternative}{alternativa} +\setinterfaceconstant{andtext}{andtext} +\setinterfaceconstant{apa}{apa} +\setinterfaceconstant{arrow}{freccia} +\setinterfaceconstant{artauthor}{artauthor} +\setinterfaceconstant{artauthoretaldisplay}{artauthoretaldisplay} +\setinterfaceconstant{artauthoretallimit}{artauthoretallimit} +\setinterfaceconstant{artauthoretaltext}{artauthoretaltext} +\setinterfaceconstant{at}{ad} +\setinterfaceconstant{author}{autore} +\setinterfaceconstant{authoretaldisplay}{authoretaldisplay} +\setinterfaceconstant{authoretallimit}{authoretallimit} +\setinterfaceconstant{authoretaltext}{authoretaltext} +\setinterfaceconstant{auto}{auto} +\setinterfaceconstant{autofile}{autofile} +\setinterfaceconstant{autofocus}{autofocus} +\setinterfaceconstant{autohang}{autohang} +\setinterfaceconstant{autostrut}{autostrut} +\setinterfaceconstant{autowidth}{autoampiezza} +\setinterfaceconstant{axis}{asse} +\setinterfaceconstant{background}{sfondo} +\setinterfaceconstant{backgroundcolor}{coloresfondo} +\setinterfaceconstant{backgroundcorner}{angolosfondo} +\setinterfaceconstant{backgrounddepth}{profonditasfondo} +\setinterfaceconstant{backgroundoffset}{offsetsfondo} +\setinterfaceconstant{backgroundradius}{raggiosfondo} +\setinterfaceconstant{backgroundscreen}{schermosfondo} +\setinterfaceconstant{backspace}{backspace} +\setinterfaceconstant{balance}{bilanciamento} +\setinterfaceconstant{before}{prima} +\setinterfaceconstant{beforehead}{primaditesta} +\setinterfaceconstant{bet}{bet} +\setinterfaceconstant{big}{grande} +\setinterfaceconstant{blank}{rigovuoto} +\setinterfaceconstant{blockway}{blockway} +\setinterfaceconstant{bodyfont}{fonttesto} +\setinterfaceconstant{bookmark}{segnalibro} +\setinterfaceconstant{bottom}{fondo} +\setinterfaceconstant{bottomafter}{bottomafter} +\setinterfaceconstant{bottombefore}{bottombefore} +\setinterfaceconstant{bottomdistance}{distanzafondo} +\setinterfaceconstant{bottomframe}{cornicefondo} +\setinterfaceconstant{bottomoffset}{offsetfondo} +\setinterfaceconstant{bottomspace}{spaziofondo} +\setinterfaceconstant{bottomstate}{statofondo} +\setinterfaceconstant{cache}{cache} +\setinterfaceconstant{calculate}{calcola} +\setinterfaceconstant{ccommand}{ccomando} +\setinterfaceconstant{click}{click} +\setinterfaceconstant{clickin}{clickdentro} +\setinterfaceconstant{clickout}{clickfuori} +\setinterfaceconstant{clipoffset}{clipoffset} +\setinterfaceconstant{closeaction}{azionechiudi} +\setinterfaceconstant{closecommand}{closecommand} +\setinterfaceconstant{closepageaction}{azionechiudipagina} +\setinterfaceconstant{closesymbol}{closesymbol} +\setinterfaceconstant{color}{colore} +\setinterfaceconstant{column}{colonna} +\setinterfaceconstant{columndistance}{distanzacolonne} +\setinterfaceconstant{columns}{colonne} +\setinterfaceconstant{command}{comando} +\setinterfaceconstant{commandafter}{comdandodopo} +\setinterfaceconstant{commandbefore}{comandoprima} +\setinterfaceconstant{commands}{comandi} +\setinterfaceconstant{component}{component} +\setinterfaceconstant{compoundhyphen}{compoundhyphen} +\setinterfaceconstant{compress}{compress} +\setinterfaceconstant{connector}{connector} +\setinterfaceconstant{continue}{continua} +\setinterfaceconstant{contrastcolor}{colorecontrasto} +\setinterfaceconstant{controls}{controlli} +\setinterfaceconstant{conversion}{conversione} +\setinterfaceconstant{convertfile}{convertifile} +\setinterfaceconstant{corner}{angolo} +\setinterfaceconstant{coupling}{accoppiamento} +\setinterfaceconstant{couplingway}{modoaccoppiamento} +\setinterfaceconstant{criterium}{criterio} +\setinterfaceconstant{current}{corrente} +\setinterfaceconstant{cutspace}{cutspace} +\setinterfaceconstant{dash}{dash} +\setinterfaceconstant{dat}{dat} +\setinterfaceconstant{database}{database} +\setinterfaceconstant{date}{data} +\setinterfaceconstant{deepnumbercommand}{deepnumbercommand} +\setinterfaceconstant{deeptextcommand}{deeptextcommand} +\setinterfaceconstant{default}{implicito} +\setinterfaceconstant{delay}{attesa} +\setinterfaceconstant{depth}{profondita} +\setinterfaceconstant{depthcorrection}{correzioneprofondita} +\setinterfaceconstant{direction}{direzione} +\setinterfaceconstant{directory}{directory} +\setinterfaceconstant{display}{display} +\setinterfaceconstant{distance}{distanza} +\setinterfaceconstant{dot}{punto} +\setinterfaceconstant{doublesided}{doppiafaccia} +\setinterfaceconstant{dummy}{dummy} +\setinterfaceconstant{dx}{dx} +\setinterfaceconstant{dy}{dy} +\setinterfaceconstant{edge}{bordo} +\setinterfaceconstant{edgedistance}{distanzabordo} +\setinterfaceconstant{editor}{editor} +\setinterfaceconstant{editoretaldisplay}{editoretaldisplay} +\setinterfaceconstant{editoretallimit}{editoretallimit} +\setinterfaceconstant{editoretaltext}{editoretaltext} +\setinterfaceconstant{empty}{vuoto} +\setinterfaceconstant{equalheight}{equalheight} +\setinterfaceconstant{equalwidth}{equalwidth} +\setinterfaceconstant{escape}{escape} +\setinterfaceconstant{evenmargin}{marginepari} +\setinterfaceconstant{expansion}{espansione} +\setinterfaceconstant{export}{export} +\setinterfaceconstant{extras}{extras} +\setinterfaceconstant{factor}{fattore} +\setinterfaceconstant{fallback}{fallback} +\setinterfaceconstant{family}{famiglia} +\setinterfaceconstant{fieldbackgroundcolor}{coloresfondocampo} +\setinterfaceconstant{fieldframecolor}{colorecornicecampo} +\setinterfaceconstant{fieldlayer}{fieldlayer} +\setinterfaceconstant{fieldoffset}{offsetcampo} +\setinterfaceconstant{file}{file} +\setinterfaceconstant{filtercommand}{filtercommand} +\setinterfaceconstant{finalnamesep}{finalnamesep} +\setinterfaceconstant{firstnamesep}{firstnamesep} +\setinterfaceconstant{focus}{focus} +\setinterfaceconstant{focusin}{focusin} +\setinterfaceconstant{focusout}{focusout} +\setinterfaceconstant{footer}{piedipagina} +\setinterfaceconstant{footerdistance}{distanzapdp} +\setinterfaceconstant{footerstate}{statopdp} +\setinterfaceconstant{foregroundcolor}{coloreprimopiano} +\setinterfaceconstant{foregroundstyle}{foregroundstyle} +\setinterfaceconstant{format}{format} +\setinterfaceconstant{frame}{cornice} +\setinterfaceconstant{framecolor}{colorecornice} +\setinterfaceconstant{framecorner}{angolocornice} +\setinterfaceconstant{framedepth}{profonditacornice} +\setinterfaceconstant{frameoffset}{offsetcornice} +\setinterfaceconstant{frameradius}{raggiocornice} +\setinterfaceconstant{frames}{cornici} +\setinterfaceconstant{from}{da} +\setinterfaceconstant{get}{prendi} +\setinterfaceconstant{global}{globale} +\setinterfaceconstant{grid}{griglia} +\setinterfaceconstant{hang}{sospendi} +\setinterfaceconstant{headalign}{headalign} +\setinterfaceconstant{headcolor}{coloretesta} +\setinterfaceconstant{headcommand}{headcommand} +\setinterfaceconstant{headconversion}{conversionetesta} +\setinterfaceconstant{header}{intestazione} +\setinterfaceconstant{headerdistance}{distanzaintestazione} +\setinterfaceconstant{headerstate}{statointestazione} +\setinterfaceconstant{headlabel}{etichettatesta} +\setinterfaceconstant{headnumber}{numerotesta} +\setinterfaceconstant{headstyle}{stiletesta} +\setinterfaceconstant{height}{altezza} +\setinterfaceconstant{hfactor}{hfactor} +\setinterfaceconstant{hfil}{hfil} +\setinterfaceconstant{hidenumber}{hidenumber} +\setinterfaceconstant{hoffset}{hoffset} +\setinterfaceconstant{horoffset}{horoffset} +\setinterfaceconstant{hyphen}{hyphen} +\setinterfaceconstant{icommand}{icomando} +\setinterfaceconstant{in}{in} +\setinterfaceconstant{inbetween}{tra} +\setinterfaceconstant{increment}{incremento} +\setinterfaceconstant{incrementnumber}{incrementanumero} +\setinterfaceconstant{indenting}{rientro} +\setinterfaceconstant{indentnext}{rientrasuccessivo} +\setinterfaceconstant{indicator}{indicatore} +\setinterfaceconstant{inner}{interno} +\setinterfaceconstant{innermargin}{margineinterno} +\setinterfaceconstant{inputfile}{inputfile} +\setinterfaceconstant{intent}{intent} +\setinterfaceconstant{interaction}{interazione} +\setinterfaceconstant{interlinespace}{interlinea} +\setinterfaceconstant{itemalign}{itemalign} +\setinterfaceconstant{items}{elementi} +\setinterfaceconstant{juniorsep}{juniorsep} +\setinterfaceconstant{ken}{ken} +\setinterfaceconstant{keyexpansion}{keyexpansion} +\setinterfaceconstant{keyword}{parolachiave} +\setinterfaceconstant{label}{etichetta} +\setinterfaceconstant{lastnamesep}{lastnamesep} +\setinterfaceconstant{lastpubsep}{lastpubsep} +\setinterfaceconstant{left}{sinistra} +\setinterfaceconstant{leftcolor}{coloresinistra} +\setinterfaceconstant{leftcompoundhyphen}{leftcompoundhyphen} +\setinterfaceconstant{leftedge}{bordosinistro} +\setinterfaceconstant{leftedgedistance}{distanzabordosinistro} +\setinterfaceconstant{leftframe}{cornicesinistra} +\setinterfaceconstant{lefthyphen}{lefthyphen} +\setinterfaceconstant{leftmargin}{marginesinistro} +\setinterfaceconstant{leftmargindistance}{distanzamarginesinistro} +\setinterfaceconstant{leftoffset}{offsetsinistro} +\setinterfaceconstant{leftquotation}{citazionesinistra} +\setinterfaceconstant{leftquote}{menzionesinistra} +\setinterfaceconstant{leftsentence}{frasesinistra} +\setinterfaceconstant{leftspeech}{leftspeech} +\setinterfaceconstant{leftstyle}{stilesinistra} +\setinterfaceconstant{leftsubsentence}{sottofrasesinistra} +\setinterfaceconstant{lefttext}{testosinistro} +\setinterfaceconstant{leftwidth}{ampiezzasinistra} +\setinterfaceconstant{level}{livello} +\setinterfaceconstant{levels}{livelli} +\setinterfaceconstant{limittext}{limittext} +\setinterfaceconstant{line}{riga} +\setinterfaceconstant{linecorrection}{correzioneriga} +\setinterfaceconstant{lines}{righe} +\setinterfaceconstant{list}{elenco} +\setinterfaceconstant{listtext}{listtext} +\setinterfaceconstant{local}{locale} +\setinterfaceconstant{location}{luogo} +\setinterfaceconstant{logo}{logo} +\setinterfaceconstant{logos}{loghi} +\setinterfaceconstant{marcolor}{coloremarcatura} +\setinterfaceconstant{margin}{margine} +\setinterfaceconstant{margindistance}{distanzamargine} +\setinterfaceconstant{marginedge}{bordomargine} +\setinterfaceconstant{marginedgetext}{testobordomargine} +\setinterfaceconstant{margintext}{testomargine} +\setinterfaceconstant{marking}{marcatura} +\setinterfaceconstant{marstyle}{stilemarcatura} +\setinterfaceconstant{max}{max} +\setinterfaceconstant{maxdepth}{maxdepth} +\setinterfaceconstant{maxheight}{altezzamax} +\setinterfaceconstant{maxwidth}{ampiezzamax} +\setinterfaceconstant{maybeyear}{maybeyear} +\setinterfaceconstant{menu}{menu} +\setinterfaceconstant{method}{metodo} +\setinterfaceconstant{middle}{centro} +\setinterfaceconstant{middlespeech}{middlespeech} +\setinterfaceconstant{middletext}{testocentro} +\setinterfaceconstant{midsentence}{midsentence} +\setinterfaceconstant{min}{min} +\setinterfaceconstant{mindepth}{mindeoth} +\setinterfaceconstant{minheight}{altezzamin} +\setinterfaceconstant{minwidth}{ampiezzamin} +\setinterfaceconstant{monthconversion}{monthconversion} +\setinterfaceconstant{n}{n} +\setinterfaceconstant{name}{nome} +\setinterfaceconstant{namesep}{namesep} +\setinterfaceconstant{nbottom}{nfondo} +\setinterfaceconstant{nc}{nc} +\setinterfaceconstant{next}{successivo} +\setinterfaceconstant{nl}{nl} +\setinterfaceconstant{nleft}{nsinistra} +\setinterfaceconstant{nlines}{nrighe} +\setinterfaceconstant{norm}{norma} +\setinterfaceconstant{nr}{nr} +\setinterfaceconstant{nright}{ndestra} +\setinterfaceconstant{ntop}{ncima} +\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{numberstarter}{numberstarter} +\setinterfaceconstant{numberstopper}{numberstopper} +\setinterfaceconstant{numberstyle}{stilenumero} +\setinterfaceconstant{numberwidth}{numberwidth} +\setinterfaceconstant{nx}{nx} +\setinterfaceconstant{ny}{ny} +\setinterfaceconstant{object}{oggetto} +\setinterfaceconstant{obstruction}{ostruzione} +\setinterfaceconstant{oddmargin}{marginedispari} +\setinterfaceconstant{offset}{offset} +\setinterfaceconstant{openaction}{azioneapri} +\setinterfaceconstant{openpageaction}{azioneapripagina} +\setinterfaceconstant{option}{opzione} +\setinterfaceconstant{order}{order} +\setinterfaceconstant{orientation}{orientation} +\setinterfaceconstant{otherstext}{otherstext} +\setinterfaceconstant{outermargin}{margineesterno} +\setinterfaceconstant{overprint}{overprint} +\setinterfaceconstant{ownnumber}{numeroproprio} +\setinterfaceconstant{page}{pagina} +\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{pageprefixstarter}{pageprefixstarter} +\setinterfaceconstant{pageprefixstopper}{pageprefixstopper} +\setinterfaceconstant{pagesegments}{pagesegments} +\setinterfaceconstant{pageseparatorset}{pageseparatorset} +\setinterfaceconstant{pageset}{pageset} +\setinterfaceconstant{pagestarter}{pagestarter} +\setinterfaceconstant{pagestate}{statopagina} +\setinterfaceconstant{pagestopper}{pagestopper} +\setinterfaceconstant{pagestyle}{stilepagina} +\setinterfaceconstant{palet}{tavolozza} +\setinterfaceconstant{paper}{carta} +\setinterfaceconstant{paragraph}{capoverso} +\setinterfaceconstant{place}{metti} +\setinterfaceconstant{placehead}{mettitesta} +\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{prefixstarter}{prefixstarter} +\setinterfaceconstant{prefixstopper}{prefixstopper} +\setinterfaceconstant{preset}{preimpostato} +\setinterfaceconstant{preview}{anteprima} +\setinterfaceconstant{previous}{precedente} +\setinterfaceconstant{previousnumber}{numeroprecedente} +\setinterfaceconstant{process}{process} +\setinterfaceconstant{pubsep}{pubsep} +\setinterfaceconstant{radius}{raggio} +\setinterfaceconstant{random}{casuale} +\setinterfaceconstant{range}{range} +\setinterfaceconstant{reduction}{riduzione} +\setinterfaceconstant{ref}{ref} +\setinterfaceconstant{refcommand}{refcommand} +\setinterfaceconstant{reference}{riferimento} +\setinterfaceconstant{referenceprefix}{referenceprefix} +\setinterfaceconstant{referencing}{referencing} +\setinterfaceconstant{regionin}{entraregione} +\setinterfaceconstant{regionout}{esciregione} +\setinterfaceconstant{repeat}{ripeti} +\setinterfaceconstant{reset}{reset} +\setinterfaceconstant{resetnumber}{resetnumber} +\setinterfaceconstant{resolution}{risoluzione} +\setinterfaceconstant{right}{destra} +\setinterfaceconstant{rightcolor}{coloredestra} +\setinterfaceconstant{rightcompoundhyphen}{rightcompoundhyphen} +\setinterfaceconstant{rightedge}{bordodestro} +\setinterfaceconstant{rightedgedistance}{distanzabordodestro} +\setinterfaceconstant{rightframe}{cornicedestra} +\setinterfaceconstant{righthyphen}{righthyphen} +\setinterfaceconstant{rightmargin}{marginedestro} +\setinterfaceconstant{rightmargindistance}{distanzamarginedestro} +\setinterfaceconstant{rightoffset}{offsetdestro} +\setinterfaceconstant{rightquotation}{citazionedestra} +\setinterfaceconstant{rightquote}{menzionedestra} +\setinterfaceconstant{rightsentence}{frasedestra} +\setinterfaceconstant{rightspeech}{rightspeech} +\setinterfaceconstant{rightstyle}{stiledestra} +\setinterfaceconstant{rightsubsentence}{sottofrasedestra} +\setinterfaceconstant{righttext}{testodestro} +\setinterfaceconstant{rightwidth}{ampiezzadestra} +\setinterfaceconstant{rotation}{rotazione} +\setinterfaceconstant{rule}{linea} +\setinterfaceconstant{rulecolor}{colorelinea} +\setinterfaceconstant{rulethickness}{spessorelinea} +\setinterfaceconstant{samepage}{stessapagina} +\setinterfaceconstant{sample}{campione} +\setinterfaceconstant{samplesize}{samplesize} +\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{sectionresetset}{sectionresetset} +\setinterfaceconstant{sectionsegments}{sectionsegments} +\setinterfaceconstant{sectionseparatorset}{sectionseparatorset} +\setinterfaceconstant{sectionset}{sectionset} +\setinterfaceconstant{sectionstarter}{sectionstarter} +\setinterfaceconstant{sectionstopper}{sectionstopper} +\setinterfaceconstant{separator}{separatore} +\setinterfaceconstant{set}{set} +\setinterfaceconstant{setups}{setups} +\setinterfaceconstant{side}{lato} +\setinterfaceconstant{sidealign}{sidealign} +\setinterfaceconstant{sidemethod}{sidemethod} +\setinterfaceconstant{sidespaceafter}{spaziolateraledopo} +\setinterfaceconstant{sidespacebefore}{spaziolateraleprima} +\setinterfaceconstant{sign}{segno} +\setinterfaceconstant{size}{dimensione} +\setinterfaceconstant{small}{piccolo} +\setinterfaceconstant{sort}{sort} +\setinterfaceconstant{sorttype}{sorttype} +\setinterfaceconstant{source}{origine} +\setinterfaceconstant{space}{spazio} +\setinterfaceconstant{spaceafter}{spaziodopo} +\setinterfaceconstant{spacebefore}{spazioprima} +\setinterfaceconstant{spaceinbetween}{spaceinbetween} +\setinterfaceconstant{spacing}{spaziatura} +\setinterfaceconstant{split}{separa} +\setinterfaceconstant{splitcolor}{splitcolor} +\setinterfaceconstant{splitmethod}{splitmethod} +\setinterfaceconstant{splitoffset}{splitoffset} +\setinterfaceconstant{spot}{spot} +\setinterfaceconstant{stack}{stack} +\setinterfaceconstant{start}{inizia} +\setinterfaceconstant{starter}{starter} +\setinterfaceconstant{state}{stato} +\setinterfaceconstant{step}{passo} +\setinterfaceconstant{stop}{termina} +\setinterfaceconstant{stopper}{stopper} +\setinterfaceconstant{stretch}{dilata} +\setinterfaceconstant{strip}{strip} +\setinterfaceconstant{strut}{strut} +\setinterfaceconstant{style}{stile} +\setinterfaceconstant{sub}{sotto} +\setinterfaceconstant{subtitle}{sottotitolo} +\setinterfaceconstant{suffix}{suffix} +\setinterfaceconstant{surnamesep}{surnamesep} +\setinterfaceconstant{sx}{sx} +\setinterfaceconstant{sy}{sy} +\setinterfaceconstant{symalign}{symallinea} +\setinterfaceconstant{symbol}{simbolo} +\setinterfaceconstant{symbolset}{setsimboli} +\setinterfaceconstant{symcolor}{coloresimbolo} +\setinterfaceconstant{symstyle}{stilesimbolo} +\setinterfaceconstant{synonym}{sinonimo} +\setinterfaceconstant{synonymcolor}{coloresinonimi} +\setinterfaceconstant{synonymcommand}{synonymcommand} +\setinterfaceconstant{synonymstyle}{stilesinonimi} +\setinterfaceconstant{tab}{tab} +\setinterfaceconstant{text}{testo} +\setinterfaceconstant{textcolor}{coloretesto} +\setinterfaceconstant{textcommand}{comandotesto} +\setinterfaceconstant{textdistance}{distanzatesto} +\setinterfaceconstant{textlayer}{textlayer} +\setinterfaceconstant{textmargin}{textmargin} +\setinterfaceconstant{textmethod}{textmethod} +\setinterfaceconstant{textseparator}{separatoretesto} +\setinterfaceconstant{textsize}{dimensionetesto} +\setinterfaceconstant{textstate}{statotesto} +\setinterfaceconstant{textstyle}{stiletesto} +\setinterfaceconstant{textwidth}{ampiezzatesto} +\setinterfaceconstant{title}{titolo} +\setinterfaceconstant{titlecolor}{coloretitolo} +\setinterfaceconstant{titlecommand}{titlecommand} +\setinterfaceconstant{titledistance}{distanzatitolo} +\setinterfaceconstant{titleleft}{titleleft} +\setinterfaceconstant{titleright}{titleright} +\setinterfaceconstant{titlestyle}{stiletitolo} +\setinterfaceconstant{to}{verso} +\setinterfaceconstant{tolerance}{tolleranza} +\setinterfaceconstant{top}{cima} +\setinterfaceconstant{topdistance}{distanzacima} +\setinterfaceconstant{topframe}{cornicecima} +\setinterfaceconstant{topoffset}{offsetcima} +\setinterfaceconstant{topspace}{spaziocima} +\setinterfaceconstant{topstate}{statocima} +\setinterfaceconstant{totalnumber}{totalnumber} +\setinterfaceconstant{type}{type} +\setinterfaceconstant{unit}{unita} +\setinterfaceconstant{unknownreference}{riferimentoingoto} +\setinterfaceconstant{urlalternative}{alternativaurl} +\setinterfaceconstant{urlspace}{spaziourl} +\setinterfaceconstant{validate}{verifica} +\setinterfaceconstant{vcommand}{vcomando} +\setinterfaceconstant{veroffset}{veroffset} +\setinterfaceconstant{vfil}{vfil} +\setinterfaceconstant{voffset}{voffset} +\setinterfaceconstant{vonsep}{vonsep} +\setinterfaceconstant{way}{modo} +\setinterfaceconstant{wfactor}{wfactor} +\setinterfaceconstant{white}{bianco} +\setinterfaceconstant{width}{ampiezza} +\setinterfaceconstant{xfactor}{xfactor} +\setinterfaceconstant{xmax}{xmax} +\setinterfaceconstant{xoffset}{xoffset} +\setinterfaceconstant{xscale}{xscale} +\setinterfaceconstant{xstep}{xstep} +\setinterfaceconstant{yfactor}{yfactor} +\setinterfaceconstant{ymax}{ymax} +\setinterfaceconstant{yoffset}{yoffset} +\setinterfaceconstant{yscale}{yscale} +\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} +\setinterfaceelement{currentlocal}{correntelocale} +\setinterfaceelement{emptyone}{prazdne} +\setinterfaceelement{emptytwo}{vuoti} +\setinterfaceelement{end}{fine} +\setinterfaceelement{endsetup}{} +\setinterfaceelement{get}{prendi} +\setinterfaceelement{increment}{incrementa} +\setinterfaceelement{list}{elenco} +\setinterfaceelement{listof}{elencodi} +\setinterfaceelement{load}{carica} +\setinterfaceelement{local}{locale} +\setinterfaceelement{makeup}{makeup} +\setinterfaceelement{next}{successivo} +\setinterfaceelement{place}{metti} +\setinterfaceelement{previous}{precedente} +\setinterfaceelement{previouslocal}{precedentelocale} +\setinterfaceelement{reserve}{riserva} +\setinterfaceelement{see}{vedi} +\setinterfaceelement{setup}{imposta} +\setinterfaceelement{start}{inizia} +\setinterfaceelement{stop}{termina} +\setinterfaceelement{text}{testo} +\setinterfaceelement{type}{type} +% definitions for interface commands for language it +% +\setinterfacecommand{CAPPED}{CAP} +\setinterfacecommand{Character}{Lettera} +\setinterfacecommand{Characters}{Lettere} +\setinterfacecommand{LABELTEXT}{TESTOETICHETTA} +\setinterfacecommand{MONTH}{MESE} +\setinterfacecommand{Numbers}{Numeri} +\setinterfacecommand{Romannumerals}{Numeriromani} +\setinterfacecommand{SmallCapped}{Cap} +\setinterfacecommand{SmallCaps}{Caps} +\setinterfacecommand{WEEKDAY}{GIORNOSETTIMANA} +\setinterfacecommand{WORD}{PAROLA} +\setinterfacecommand{WORDS}{PAROLE} +\setinterfacecommand{Word}{Parola} +\setinterfacecommand{Words}{Parole} +\setinterfacecommand{about}{intorno} +\setinterfacecommand{adaptlayout}{adattalayout} +\setinterfacecommand{arg}{arg} +\setinterfacecommand{at}{al} +\setinterfacecommand{atleftmargin}{atleftmargin} +\setinterfacecommand{atpage}{apagina} +\setinterfacecommand{atrightmargin}{atrightmargin} +\setinterfacecommand{background}{sfondo} +\setinterfacecommand{backspace}{spaziodietro} +\setinterfacecommand{blackrule}{lineanera} +\setinterfacecommand{blackrules}{lineenere} +\setinterfacecommand{blank}{rigovuoto} +\setinterfacecommand{bookmark}{segnalibro} +\setinterfacecommand{bottomdistance}{distanzafondo} +\setinterfacecommand{bottomheight}{altezzafondo} +\setinterfacecommand{bottomspace}{spaziofondo} +\setinterfacecommand{but}{fondo} +\setinterfacecommand{button}{pulsante} +\setinterfacecommand{bypassblocks}{saltablocchi} +\setinterfacecommand{character}{lettera} +\setinterfacecommand{characters}{lettere} +\setinterfacecommand{chem}{chim} +\setinterfacecommand{clip}{clip} +\setinterfacecommand{clonefield}{clonacampo} +\setinterfacecommand{color}{colore} +\setinterfacecommand{colorbar}{barracolori} +\setinterfacecommand{colorvalue}{valorecolore} +\setinterfacecommand{column}{colonna} +\setinterfacecommand{comment}{commento} +\setinterfacecommand{comparecolorgroup}{confrontagruppocolori} +\setinterfacecommand{comparepalet}{confrontatavolozza} +\setinterfacecommand{completepagenumber}{numeropaginacompleto} +\setinterfacecommand{completeregister}{completeregister} +\setinterfacecommand{component}{componenet} +\setinterfacecommand{convertnumber}{convertinumero} +\setinterfacecommand{copyfield}{copiacampo} +\setinterfacecommand{correctwhitespace}{correggispaziobianco} +\setinterfacecommand{coupledocument}{accoppiadocumento} +\setinterfacecommand{couplemarking}{accoppiamarcatura} +\setinterfacecommand{couplepage}{accoppiapagina} +\setinterfacecommand{couplepaper}{accoppiacarta} +\setinterfacecommand{coupleregister}{accoppiaregistro} +\setinterfacecommand{crlf}{crlf} +\setinterfacecommand{currentdate}{datadioggi} +\setinterfacecommand{currentheadnumber}{numerotestacorrente} +\setinterfacecommand{cutspace}{cutspace} +\setinterfacecommand{date}{data} +\setinterfacecommand{decouplemarking}{separamarcatura} +\setinterfacecommand{decrementnumber}{decrementnumber} +\setinterfacecommand{define}{definisci} +\setinterfacecommand{defineaccent}{definisciaccento} +\setinterfacecommand{defineblank}{definiscirigovuoto} +\setinterfacecommand{defineblock}{definisciblocco} +\setinterfacecommand{definebodyfont}{definiscifontdeltesto} +\setinterfacecommand{definebodyfontenvironment}{definisciambientefontdeltesto} +\setinterfacecommand{definebuffer}{definiscibuffer} +\setinterfacecommand{definecharacter}{definiscicarattere} +\setinterfacecommand{definecolor}{definiscicolore} +\setinterfacecommand{definecolorgroup}{definiscigruppocolori} +\setinterfacecommand{definecolumnbreak}{definecolumnbreak} +\setinterfacecommand{definecolumnset}{definiscigruppocolonne} +\setinterfacecommand{definecombination}{definecombination} +\setinterfacecommand{definecombinedlist}{definiscielencocombinato} +\setinterfacecommand{definecommand}{definiscicomando} +\setinterfacecommand{defineconversion}{definisciconversione} +\setinterfacecommand{definedescription}{definiscidescrizione} +\setinterfacecommand{defineenumeration}{definiscienumerazione} +\setinterfacecommand{definefield}{definiscicampo} +\setinterfacecommand{definefieldstack}{definiscistackcampi} +\setinterfacecommand{definefiguresymbol}{definiscifigurasimbolo} +\setinterfacecommand{definefloat}{definiscioggettomobile} +\setinterfacecommand{definefont}{definiscifont} +\setinterfacecommand{definefontstyle}{definiscistilefont} +\setinterfacecommand{definefontsynonym}{definiscisinonimofont} +\setinterfacecommand{defineframed}{definisciincorniciato} +\setinterfacecommand{defineframedtext}{definiscitestoincorniciato} +\setinterfacecommand{definehbox}{definiscihbox} +\setinterfacecommand{definehead}{definiscitesta} +\setinterfacecommand{defineindenting}{definiscirientro} +\setinterfacecommand{defineinmargin}{defineinmargin} +\setinterfacecommand{defineinteractionmenu}{definiscimenuinterazione} +\setinterfacecommand{defineitemgroup}{defineitemgroup} +\setinterfacecommand{definelabel}{definiscietichetta} +\setinterfacecommand{definelayer}{definelayer} +\setinterfacecommand{definelayout}{definiscilayout} +\setinterfacecommand{definelist}{definiscielenco} +\setinterfacecommand{definelogo}{definiscilogo} +\setinterfacecommand{definemainfield}{definiscicampoprincipale} +\setinterfacecommand{definemakeup}{definiscimakeup} +\setinterfacecommand{definemarking}{definiscimarcatura} +\setinterfacecommand{definemathalignment}{definemathalignment} +\setinterfacecommand{defineoutput}{definiscioutput} +\setinterfacecommand{defineoverlay}{definiscisovrapposizione} +\setinterfacecommand{definepagebreak}{definepagebreak} +\setinterfacecommand{definepalet}{definiscitavolozza} +\setinterfacecommand{definepapersize}{definiscidimensionicarta} +\setinterfacecommand{defineparagraphs}{definiscicapoversi} +\setinterfacecommand{defineplacement}{defineplacement} +\setinterfacecommand{defineprofile}{definisciprofilo} +\setinterfacecommand{defineprogram}{definisciprogramma} +\setinterfacecommand{definerawfont}{definiscifontgrezzo} +\setinterfacecommand{definereference}{definisciriferimento} +\setinterfacecommand{definereferenceformat}{definisciformatoriferimento} +\setinterfacecommand{definereferencelist}{definiscilistariferimenti} +\setinterfacecommand{defineregister}{definisciregistro} +\setinterfacecommand{definerule}{definiscilinea} +\setinterfacecommand{definesection}{definiscisezione} +\setinterfacecommand{definesectionblock}{definiscibloccosezione} +\setinterfacecommand{definesorting}{definisciordinamento} +\setinterfacecommand{definestartstop}{definisciiniziatermina} +\setinterfacecommand{definestyle}{definiscistile} +\setinterfacecommand{definesubfield}{definiscisottocampo} +\setinterfacecommand{definesymbol}{definiscisimbolo} +\setinterfacecommand{definesynonyms}{definiscisinonimi} +\setinterfacecommand{definetabletemplate}{definiscimodellotabella} +\setinterfacecommand{definetabulate}{definiscitabulato} +\setinterfacecommand{definetext}{definiscitesto} +\setinterfacecommand{definetextposition}{definisciposizionetesto} +\setinterfacecommand{definetextvariable}{definiscivariabiletesto} +\setinterfacecommand{definetype}{definiscitype} +\setinterfacecommand{definetyping}{definiscityping} +\setinterfacecommand{defineversion}{definisciversion} +\setinterfacecommand{determineheadnumber}{determinanumerotesta} +\setinterfacecommand{determinelistcharacteristics}{determinacarattersticheelenco} +\setinterfacecommand{determineregistercharacteristics}{determinacaratteristicheregistro} +\setinterfacecommand{dimension}{dimensione} +\setinterfacecommand{disableinteractionmenu}{disabilitamenuinterazione} +\setinterfacecommand{domicile}{domicilio} +\setinterfacecommand{donttest}{notest} +\setinterfacecommand{edgedistance}{distanzabordo} +\setinterfacecommand{edgewidth}{ampiezzabordo} +\setinterfacecommand{emptylines}{emptylines} +\setinterfacecommand{environment}{ambiente} +\setinterfacecommand{externalfigure}{figuraesterna} +\setinterfacecommand{fact}{fatto} +\setinterfacecommand{field}{campi} +\setinterfacecommand{fieldstack}{stackcampi} +\setinterfacecommand{fillinfield}{camporiempimento} +\setinterfacecommand{fillinline}{rigariempimento} +\setinterfacecommand{fillinrules}{lineeriempimento} +\setinterfacecommand{fillintext}{testoriempimento} +\setinterfacecommand{fitfield}{adattacampo} +\setinterfacecommand{fixedspace}{spaziofisso} +\setinterfacecommand{fixedspaces}{spazifissi} +\setinterfacecommand{followprofile}{seguiprofilo} +\setinterfacecommand{followprofileversion}{seguiversioneprofilo} +\setinterfacecommand{followversion}{seguiversione} +\setinterfacecommand{footerdistance}{distanzapdp} +\setinterfacecommand{footerheight}{altezzapdp} +\setinterfacecommand{footnote}{notapdp} +\setinterfacecommand{footnotetext}{testonotapdp} +\setinterfacecommand{forceblocks}{forzablocchi} +\setinterfacecommand{formulanumber}{numeroformula} +\setinterfacecommand{fraction}{frazione} +\setinterfacecommand{framed}{incorniciato} +\setinterfacecommand{from}{da} +\setinterfacecommand{getbuffer}{prendibuffer} +\setinterfacecommand{getmarking}{prendimarcatura} +\setinterfacecommand{getnumber}{getnumber} +\setinterfacecommand{godown}{vaigiu} +\setinterfacecommand{goto}{vaia} +\setinterfacecommand{gotobox}{vaiabox} +\setinterfacecommand{gotopage}{vaiapagina} +\setinterfacecommand{graycolor}{coloregrigio} +\setinterfacecommand{greyvalue}{valoregrigio} +\setinterfacecommand{grid}{griglia} +\setinterfacecommand{hairline}{capello} +\setinterfacecommand{head}{testa} +\setinterfacecommand{headerdistance}{distanzaintestazione} +\setinterfacecommand{headerheight}{altezzaintestazione} +\setinterfacecommand{headlevel}{livellotesta} +\setinterfacecommand{headnumber}{numerotesta} +\setinterfacecommand{headsym}{headsym} +\setinterfacecommand{headtext}{testoinstestazioni} +\setinterfacecommand{hideblocks}{nascondiblocchi} +\setinterfacecommand{high}{ap} +\setinterfacecommand{hl}{hl} +\setinterfacecommand{immediatebetweenlist}{immediatebetweenlist} +\setinterfacecommand{immediatetolist}{immediatetolist} +\setinterfacecommand{in}{in} +\setinterfacecommand{incrementnumber}{incrementanumero} +\setinterfacecommand{indenting}{rientro} +\setinterfacecommand{inframed}{circondato} +\setinterfacecommand{infull}{perlungo} +\setinterfacecommand{ininner}{ininner} +\setinterfacecommand{inleft}{insinistra} +\setinterfacecommand{inleftedge}{inlatosinistro} +\setinterfacecommand{inleftmargin}{inmarginesinistro} +\setinterfacecommand{inline}{inriga} +\setinterfacecommand{inmargin}{inmargine} +\setinterfacecommand{inmframed}{inmaframed} +\setinterfacecommand{inneredgedistance}{inneredgedistance} +\setinterfacecommand{inneredgewidth}{inneredgewidth} +\setinterfacecommand{innermargindistance}{innermargindistance} +\setinterfacecommand{innermarginwidth}{innermarginwidth} +\setinterfacecommand{inothermargin}{inaltromargine} +\setinterfacecommand{inouter}{inouter} +\setinterfacecommand{inright}{indestra} +\setinterfacecommand{inrightedge}{inlatodestro} +\setinterfacecommand{inrightmargin}{inmarginedestro} +\setinterfacecommand{installlanguage}{installalingua} +\setinterfacecommand{interactionbar}{barrainterazione} +\setinterfacecommand{interactionbuttons}{pulsantinterazione} +\setinterfacecommand{interactionmenu}{menuinterattivo} +\setinterfacecommand{item}{elemento} +\setinterfacecommand{items}{elementi} +\setinterfacecommand{its}{el} +\setinterfacecommand{keepblocks}{tieniblocchi} +\setinterfacecommand{label}{etichetta} +\setinterfacecommand{labels}{etichette} +\setinterfacecommand{labeltext}{testoetichetta} +\setinterfacecommand{language}{lingua} +\setinterfacecommand{leftaligned}{allineasinistra} +\setinterfacecommand{leftedgedistance}{distanzabordosinistro} +\setinterfacecommand{leftedgewidth}{ampiezzabordosinistro} +\setinterfacecommand{leftmargindistance}{distanzamarginesinistro} +\setinterfacecommand{leftmarginwidth}{ampiezzamarginesinistro} +\setinterfacecommand{leg}{leg} +\setinterfacecommand{linewidth}{spessoreriga} +\setinterfacecommand{listheight}{altezzaelenco} +\setinterfacecommand{listlength}{lunghezzaelenco} +\setinterfacecommand{listsymbol}{listsymbol} +\setinterfacecommand{listwidth}{ampiezzaelenco} +\setinterfacecommand{logfields}{logcampi} +\setinterfacecommand{lohi}{pedap} +\setinterfacecommand{low}{ped} +\setinterfacecommand{macroname}{nome} +\setinterfacecommand{mainlanguage}{linguaprincipale} +\setinterfacecommand{makeupheight}{altezzamakeup} +\setinterfacecommand{makeupwidth}{ampiezzamakeup} +\setinterfacecommand{mar}{mar} +\setinterfacecommand{margindistance}{distanzamargine} +\setinterfacecommand{marginrule}{lineamargine} +\setinterfacecommand{margintext}{testoinmargine} +\setinterfacecommand{margintitle}{titoloinmargine} +\setinterfacecommand{marginwidth}{ampiezzamargine} +\setinterfacecommand{marginword}{parolainmargine} +\setinterfacecommand{marking}{marcatura} +\setinterfacecommand{markversion}{marcaversione} +\setinterfacecommand{mathematics}{matematica} +\setinterfacecommand{menubutton}{pulsantemenu} +\setinterfacecommand{mframed}{maframed} +\setinterfacecommand{midaligned}{allineacentro} +\setinterfacecommand{mirror}{riflessione} +\setinterfacecommand{month}{mese} +\setinterfacecommand{moveformula}{spostaformula} +\setinterfacecommand{moveongrid}{spostaagriglia} +\setinterfacecommand{movesidefloat}{movesidefloat} +\setinterfacecommand{navigating}{navigating} +\setinterfacecommand{nodimension}{nientedimensioni} +\setinterfacecommand{noheaderandfooterlines}{nientelineintestazionepdp} +\setinterfacecommand{noindenting}{nienterientro} +\setinterfacecommand{nolist}{nienteelenco} +\setinterfacecommand{nomarking}{nientemarcatura} +\setinterfacecommand{nomoreblocks}{bastablocchi} +\setinterfacecommand{nomorefiles}{bastafile} +\setinterfacecommand{nop}{nop} +\setinterfacecommand{nospace}{nientespazio} +\setinterfacecommand{note}{nota} +\setinterfacecommand{notopandbottomlines}{nientelineecimafondo} +\setinterfacecommand{notsmallcapped}{nocap} +\setinterfacecommand{nowhitespace}{nientespaziobianco} +\setinterfacecommand{numberofsubpages}{numberofsubpages} +\setinterfacecommand{numbers}{numeri} +\setinterfacecommand{outeredgedistance}{outeredgedistance} +\setinterfacecommand{outeredgewidth}{outeredgewidth} +\setinterfacecommand{outermargindistance}{outermargindistance} +\setinterfacecommand{outermarginwidth}{outermarginwidth} +\setinterfacecommand{packed}{impaccato} +\setinterfacecommand{page}{pagina} +\setinterfacecommand{pagedepth}{pagedepth} +\setinterfacecommand{pagenumber}{numeropagina} +\setinterfacecommand{pageoffset}{pageoffset} +\setinterfacecommand{pagereference}{riferimentopagina} +\setinterfacecommand{pagetype}{tipopagina} +\setinterfacecommand{paperheight}{altezzacarta} +\setinterfacecommand{paperwidth}{ampiezzacarta} +\setinterfacecommand{periods}{punti} +\setinterfacecommand{plaatsruwelijst}{placerawlist} +\setinterfacecommand{placebookmarks}{mettisegnalibro} +\setinterfacecommand{placecombinedlist}{mettielencocombinato} +\setinterfacecommand{placefloat}{placefloat} +\setinterfacecommand{placefootnotes}{mettinotepdp} +\setinterfacecommand{placeformula}{mettiformula} +\setinterfacecommand{placeheadnumber}{posizionanumerotesta} +\setinterfacecommand{placeheadtext}{posizionatestotesta} +\setinterfacecommand{placelegend}{mettilegenda} +\setinterfacecommand{placelist}{mettielenco} +\setinterfacecommand{placelocalfootnotes}{mettinotepdplocali} +\setinterfacecommand{placelogos}{mettiloghi} +\setinterfacecommand{placeongrid}{mettiingriglia} +\setinterfacecommand{placeontopofeachother}{mettiunosullaltro} +\setinterfacecommand{placepagenumber}{mettinumeropagina} +\setinterfacecommand{placereferencelist}{placereferencelist} +\setinterfacecommand{placeregister}{mettiregistro} +\setinterfacecommand{placerule}{mettilinea} +\setinterfacecommand{placesidebyside}{mettifiancoafianco} +\setinterfacecommand{placesubformula}{mettisottoformula} +\setinterfacecommand{placetextvariable}{mettivariabiletesto} +\setinterfacecommand{position}{posizione} +\setinterfacecommand{positiontext}{posizionatesto} +\setinterfacecommand{printpaperheight}{altezzacartastampa} +\setinterfacecommand{printpaperwidth}{ampiezzacartastampa} +\setinterfacecommand{processblocks}{elaborablocchi} +\setinterfacecommand{processpage}{elaborapagina} +\setinterfacecommand{product}{prodotto} +\setinterfacecommand{program}{programma} +\setinterfacecommand{project}{progetto} +\setinterfacecommand{publication}{pubblicazione} +\setinterfacecommand{quotation}{citazione} +\setinterfacecommand{quote}{menzione} +\setinterfacecommand{ran}{ran} +\setinterfacecommand{redo}{rifai} +\setinterfacecommand{ref}{rif} +\setinterfacecommand{reference}{riferimento} +\setinterfacecommand{referral}{referral} +\setinterfacecommand{referraldate}{datareferral} +\setinterfacecommand{referring}{referring} +\setinterfacecommand{remark}{commento} +\setinterfacecommand{reset}{reimposta} +\setinterfacecommand{resetmarking}{reimpostamarcatura} +\setinterfacecommand{resetnumber}{resetnumber} +\setinterfacecommand{resettext}{resettextcontent} +\setinterfacecommand{rightaligned}{allineadestra} +\setinterfacecommand{rightedgedistance}{distanzabordodestro} +\setinterfacecommand{rightedgewidth}{ampiezzabordodestro} +\setinterfacecommand{rightmargindistance}{distanzamarginedestro} +\setinterfacecommand{rightmarginwidth}{ampiezzamarginedestro} +\setinterfacecommand{romannumerals}{numeriromani} +\setinterfacecommand{rotate}{ruota} +\setinterfacecommand{scale}{scala} +\setinterfacecommand{screen}{schermo} +\setinterfacecommand{selectblocks}{selezionablocchi} +\setinterfacecommand{selectpaper}{selezionacarta} +\setinterfacecommand{selectversion}{selezionaversione} +\setinterfacecommand{setnumber}{setnumber} +\setinterfacecommand{settextcontent}{settext} +\setinterfacecommand{settextvariable}{setvariabiletesto} +\setinterfacecommand{setupalign}{impostaallineamento} +\setinterfacecommand{setupanswerarea}{setupanswerarea} +\setinterfacecommand{setuparranging}{impostaparranging} +\setinterfacecommand{setupbackground}{impostasfondo} +\setinterfacecommand{setupbackgrounds}{impostasfondi} +\setinterfacecommand{setupblackrules}{impostalineenere} +\setinterfacecommand{setupblank}{impostarigovuoto} +\setinterfacecommand{setupblock}{impostablocco} +\setinterfacecommand{setupbodyfont}{impostafontdeltesto} +\setinterfacecommand{setupbodyfontenvironment}{impostaambientefontdeltesto} +\setinterfacecommand{setupbottom}{impostafondo} +\setinterfacecommand{setupbottomtexts}{impostatestifondo} +\setinterfacecommand{setupbuffer}{impostabuffer} +\setinterfacecommand{setupbuttons}{impostapulsanti} +\setinterfacecommand{setupcapitals}{impostamaiuscole} +\setinterfacecommand{setupcaption}{impostacaption} +\setinterfacecommand{setupcaptions}{impostacaptions} +\setinterfacecommand{setupclipping}{impostaclippling} +\setinterfacecommand{setupcolor}{impostacolore} +\setinterfacecommand{setupcolors}{impostacolori} +\setinterfacecommand{setupcolumns}{impostacolonne} +\setinterfacecommand{setupcolumnset}{impostagruppocolonne} +\setinterfacecommand{setupcolumnsetlines}{setupcolumnsetlines} +\setinterfacecommand{setupcolumnsetstart}{setupcolumnsetstart} +\setinterfacecommand{setupcombinations}{impostacombinazioni} +\setinterfacecommand{setupcombinedlist}{impostaelencocombinato} +\setinterfacecommand{setupcomment}{impostacommento} +\setinterfacecommand{setupdescriptions}{impostadescrizioni} +\setinterfacecommand{setupenumerations}{impostaenumerazioni} +\setinterfacecommand{setupexternalfigures}{impostafigureesterne} +\setinterfacecommand{setupfield}{impostacampo} +\setinterfacecommand{setupfields}{impostacampi} +\setinterfacecommand{setupfillinlines}{impostarigheriempimento} +\setinterfacecommand{setupfillinrules}{impostalineeriempimento} +\setinterfacecommand{setupfloat}{impostaoggettomobile} +\setinterfacecommand{setupfloats}{impostaoggettimobili} +\setinterfacecommand{setupfloatsplitting}{impostaspezzamentooggettomobile} +\setinterfacecommand{setupfooter}{impostapdp} +\setinterfacecommand{setupfootertexts}{impostatestipdp} +\setinterfacecommand{setupfootnotedefinition}{impostadefinizionenotepdp} +\setinterfacecommand{setupfootnotes}{impostanotepdp} +\setinterfacecommand{setupforms}{impostaforms} +\setinterfacecommand{setupformulas}{impostaformule} +\setinterfacecommand{setupframed}{impostaincorniciato} +\setinterfacecommand{setupframedtexts}{impostatestiincorniciati} +\setinterfacecommand{setuphead}{impostatesta} +\setinterfacecommand{setupheader}{impostainstestazione} +\setinterfacecommand{setupheadertexts}{impostatestiintestazioni} +\setinterfacecommand{setupheadnumber}{impostanumerotesta} +\setinterfacecommand{setupheads}{impostateste} +\setinterfacecommand{setupheadtext}{impostatestointestazioni} +\setinterfacecommand{setuphyphenmark}{impostasegnosillabazione} +\setinterfacecommand{setupindentations}{impostarientri} +\setinterfacecommand{setupindenting}{impostarientro} +\setinterfacecommand{setupinmargin}{impostainmargine} +\setinterfacecommand{setupinteraction}{impostainterazione} +\setinterfacecommand{setupinteractionbar}{impostabarrainterazione} +\setinterfacecommand{setupinteractionmenu}{impostamenuinterazione} +\setinterfacecommand{setupinteractionscreen}{impostaschermointerazione} +\setinterfacecommand{setupinterlinespace}{impostainterlinea} +\setinterfacecommand{setupitemgroup}{setupitemgroup} +\setinterfacecommand{setupitemgroups}{impostaelencazioni} +\setinterfacecommand{setupitems}{impostaelementi} +\setinterfacecommand{setuplabeltext}{impostatestoetichette} +\setinterfacecommand{setuplanguage}{impostalingua} +\setinterfacecommand{setuplayout}{impostalayout} +\setinterfacecommand{setuplegend}{impostalegenda} +\setinterfacecommand{setuplinenumbering}{impostanumerazionerighe} +\setinterfacecommand{setuplines}{impostarighe} +\setinterfacecommand{setuplinewidth}{impostaampiezzariga} +\setinterfacecommand{setuplist}{impostaelenco} +\setinterfacecommand{setupmakeup}{impostamakeup} +\setinterfacecommand{setupmarginblocks}{impostablocchimargine} +\setinterfacecommand{setupmarginrules}{impostalineemargine} +\setinterfacecommand{setupmarking}{impostamarcatura} +\setinterfacecommand{setupmathalignment}{setupmathalignment} +\setinterfacecommand{setupnarrower}{impostapiustretto} +\setinterfacecommand{setupnumber}{impostanumerazione} +\setinterfacecommand{setupnumbering}{impostanumerazione} +\setinterfacecommand{setupoppositeplacing}{impostaposizionamentoopposti} +\setinterfacecommand{setupoutput}{impostaoutput} +\setinterfacecommand{setuppagecomment}{impostacommentopagina} +\setinterfacecommand{setuppagenumber}{impostanumeropagina} +\setinterfacecommand{setuppagenumbering}{impostanumerazionepagina} +\setinterfacecommand{setuppagetransitions}{impostatransizionepagina} +\setinterfacecommand{setuppalet}{impostatavolozza} +\setinterfacecommand{setuppaper}{setuppaper} +\setinterfacecommand{setuppapersize}{impostadimensionicarta} +\setinterfacecommand{setupparagraphnumbering}{impostanumerazionecapoversi} +\setinterfacecommand{setupparagraphs}{impostacapoversi} +\setinterfacecommand{setupplacement}{setupplacement} +\setinterfacecommand{setuppositioning}{impostaposizionamento} +\setinterfacecommand{setupprofiles}{impostaprofili} +\setinterfacecommand{setupprograms}{impostaprogrammi} +\setinterfacecommand{setuppublications}{impostapubblicazioni} +\setinterfacecommand{setupquote}{impostamenzione} +\setinterfacecommand{setupreferencelist}{impostalistariferimenti} +\setinterfacecommand{setupreferencing}{impostariferimento} +\setinterfacecommand{setupregister}{impostaregistro} +\setinterfacecommand{setuprotate}{impostarotazione} +\setinterfacecommand{setuprule}{impostalinea} +\setinterfacecommand{setups}{impostazioni} +\setinterfacecommand{setupscreens}{impostaschermi} +\setinterfacecommand{setupsection}{impostasezione} +\setinterfacecommand{setupsectionblock}{impostabloccosezione} +\setinterfacecommand{setupsorting}{impostaordinamento} +\setinterfacecommand{setupspacing}{impostaspaziatura} +\setinterfacecommand{setupstartstop}{impostainiziatermina} +\setinterfacecommand{setupstrut}{impostastrut} +\setinterfacecommand{setupsubpagenumber}{impostanumerosottopagina} +\setinterfacecommand{setupsymbolset}{impostasetsimboli} +\setinterfacecommand{setupsynchronization}{impostasincronizzazione} +\setinterfacecommand{setupsynchronizationbar}{impostabarrasincronizzazione} +\setinterfacecommand{setupsynonyms}{impostasinonimi} +\setinterfacecommand{setupsystem}{impostasistema} +\setinterfacecommand{setuptab}{impostatab} +\setinterfacecommand{setuptables}{impostatabelle} +\setinterfacecommand{setuptabulate}{impostatabulato} +\setinterfacecommand{setuptext}{impostatesto} +\setinterfacecommand{setuptextposition}{impostaposizionetesto} +\setinterfacecommand{setuptextrules}{impostalineetesto} +\setinterfacecommand{setuptexttexts}{impostatestotesti} +\setinterfacecommand{setuptextvariable}{impostavariabiletesto} +\setinterfacecommand{setupthinrules}{impostalineesottili} +\setinterfacecommand{setuptolerance}{impostatolleranza} +\setinterfacecommand{setuptop}{impostacima} +\setinterfacecommand{setuptoptexts}{impostatesticima} +\setinterfacecommand{setuptype}{impostatype} +\setinterfacecommand{setuptyping}{impostatyping} +\setinterfacecommand{setupunderbar}{impostasottolinea} +\setinterfacecommand{setupurl}{impostaurl} +\setinterfacecommand{setupversions}{impostaversioni} +\setinterfacecommand{setupwhitespace}{impostaspaziobianco} +\setinterfacecommand{showbodyfont}{mostrafontdeltesto} +\setinterfacecommand{showbodyfontenvironment}{mostraambientefontdeltesto} +\setinterfacecommand{showcolor}{mostracolore} +\setinterfacecommand{showcolorgroup}{mostragruppocolori} +\setinterfacecommand{showexternalfigures}{mostrafiguresterne} +\setinterfacecommand{showfields}{mostracampi} +\setinterfacecommand{showframe}{mostracornice} +\setinterfacecommand{showgrid}{mostragriglia} +\setinterfacecommand{showlayout}{mostralyout} +\setinterfacecommand{showmakeup}{mostramakeup} +\setinterfacecommand{showpalet}{mostratavolozza} +\setinterfacecommand{showprint}{mostrastampa} +\setinterfacecommand{showsetups}{mostraimpostazioni} +\setinterfacecommand{showstruts}{mostrastruts} +\setinterfacecommand{showsymbolset}{mostrasetsimboli} +\setinterfacecommand{smallcapped}{cap} +\setinterfacecommand{someline}{qualcheriga} +\setinterfacecommand{somewhere}{daqualcheparte} +\setinterfacecommand{space}{spazio} +\setinterfacecommand{splitfloat}{spezzaoggettomobile} +\setinterfacecommand{startalignment}{iniziaallineamento} +\setinterfacecommand{startbackground}{iniziasfondo} +\setinterfacecommand{startcoding}{iniziacodifica} +\setinterfacecommand{startcolor}{iniziacolore} +\setinterfacecommand{startcolumnmakeup}{startcolumnmakeup} +\setinterfacecommand{startcolumns}{iniziacolonne} +\setinterfacecommand{startcolumnset}{iniziagruppocolonne} +\setinterfacecommand{startcombination}{iniziacombinazione} +\setinterfacecommand{startcomponent}{iniziacomponente} +\setinterfacecommand{startdocument}{iniziadocumento} +\setinterfacecommand{startenvironment}{iniziaambiente} +\setinterfacecommand{startfigure}{iniziafigura} +\setinterfacecommand{startglobal}{iniziaglobale} +\setinterfacecommand{startline}{iniziariga} +\setinterfacecommand{startlinecorrection}{iniziacorrezioneriga} +\setinterfacecommand{startlinenumbering}{inizianumerazionerighe} +\setinterfacecommand{startlines}{iniziarighe} +\setinterfacecommand{startlocal}{inizialocale} +\setinterfacecommand{startlocalfootnotes}{inizianotepdplocali} +\setinterfacecommand{startmakeup}{iniziamakeup} +\setinterfacecommand{startmarginblock}{iniziabloccomargine} +\setinterfacecommand{startmarginrule}{inizialineamargine} +\setinterfacecommand{startnarrower}{iniziapiustretto} +\setinterfacecommand{startopposite}{iniziaopposto} +\setinterfacecommand{startoverlay}{iniziasovrapposizione} +\setinterfacecommand{startoverzicht}{iniziaoverview} +\setinterfacecommand{startpacked}{iniziaimpaccato} +\setinterfacecommand{startpositioning}{iniziaposizionamento} +\setinterfacecommand{startproduct}{iniziaprodotto} +\setinterfacecommand{startprofile}{iniziaprofilo} +\setinterfacecommand{startproject}{iniziaprogetto} +\setinterfacecommand{startquotation}{iniziacitazione} +\setinterfacecommand{startraster}{iniziaraster} +\setinterfacecommand{startsymbolset}{iniziasetsimboli} +\setinterfacecommand{startsynchronization}{iniziasincronizzazione} +\setinterfacecommand{starttable}{iniziatabella} +\setinterfacecommand{starttables}{iniziatabelle} +\setinterfacecommand{starttext}{iniziatesto} +\setinterfacecommand{starttextrule}{inizialineatesto} +\setinterfacecommand{startunpacked}{iniziaunpacked} +\setinterfacecommand{startversion}{iniziaversione} +\setinterfacecommand{stopalignment}{terminaallineamento} +\setinterfacecommand{stopbackground}{terminasfondo} +\setinterfacecommand{stopcoding}{terminacodifica} +\setinterfacecommand{stopcolor}{terminacolore} +\setinterfacecommand{stopcolumnmakeup}{stopcolumnmakeup} +\setinterfacecommand{stopcolumns}{terminacolonne} +\setinterfacecommand{stopcolumnset}{terminagruppocolonne} +\setinterfacecommand{stopcombination}{terminacombinazione} +\setinterfacecommand{stopcomponent}{terminacomponente} +\setinterfacecommand{stopdocument}{terminadocumento} +\setinterfacecommand{stopenvironment}{terminaambiente} +\setinterfacecommand{stopglobal}{terminaglobale} +\setinterfacecommand{stopline}{terminariga} +\setinterfacecommand{stoplinecorrection}{terminacorrezioneriga} +\setinterfacecommand{stoplinenumbering}{terminanumerazionerighe} +\setinterfacecommand{stoplines}{terminarighe} +\setinterfacecommand{stoplocal}{terminalocale} +\setinterfacecommand{stoplocalfootnotes}{terminanotepdplocali} +\setinterfacecommand{stopmakeup}{terminamakeup} +\setinterfacecommand{stopmarginblock}{terminabloccomargine} +\setinterfacecommand{stopmarginrule}{terminalineamargine} +\setinterfacecommand{stopnarrower}{terminapiustretto} +\setinterfacecommand{stopopposite}{terminaopposto} +\setinterfacecommand{stopoverlay}{terminasovrapposizione} +\setinterfacecommand{stopoverzicht}{terminaoverview} +\setinterfacecommand{stoppacked}{terminaimpaccato} +\setinterfacecommand{stoppositioning}{terminaposizionamento} +\setinterfacecommand{stopproduct}{terminaprodotto} +\setinterfacecommand{stopprofile}{terminaprofili} +\setinterfacecommand{stopproject}{terminaprogetto} +\setinterfacecommand{stopquotation}{terminacitazione} +\setinterfacecommand{stopraster}{terminaraster} +\setinterfacecommand{stopsynchronization}{terminasincronizzazione} +\setinterfacecommand{stoptable}{terminatabella} +\setinterfacecommand{stoptables}{terminatabelle} +\setinterfacecommand{stoptext}{terminatesto} +\setinterfacecommand{stoptextrule}{terminalineatesto} +\setinterfacecommand{stopunpacked}{terminaunpacked} +\setinterfacecommand{stopversion}{terminaversioni} +\setinterfacecommand{stretched}{stirato} +\setinterfacecommand{subformulanumber}{numerosottoformula} +\setinterfacecommand{subpagenumber}{subpagenumber} +\setinterfacecommand{switchtobodyfont}{cambiaafontdeltesto} +\setinterfacecommand{switchtorawfont}{passaafontgrezzo} +\setinterfacecommand{sym}{sim} +\setinterfacecommand{symbol}{simbolo} +\setinterfacecommand{synchronizationbar}{barrasincronizzazione} +\setinterfacecommand{synchronize}{sincronizza} +\setinterfacecommand{tab}{tab} +\setinterfacecommand{testcolumn}{testcolumn} +\setinterfacecommand{testpage}{testpage} +\setinterfacecommand{tex}{tex} +\setinterfacecommand{textheight}{altezzatesto} +\setinterfacecommand{textreference}{riferimentotesto} +\setinterfacecommand{textrule}{lineatesto} +\setinterfacecommand{textvariable}{variabiletesto} +\setinterfacecommand{textwidth}{ampiezzatesto} +\setinterfacecommand{thinrule}{lineasottile} +\setinterfacecommand{thinrules}{lineesottili} +\setinterfacecommand{tooltip}{tooltip} +\setinterfacecommand{topdistance}{distanzacima} +\setinterfacecommand{topheight}{altezzacima} +\setinterfacecommand{topspace}{spaziocima} +\setinterfacecommand{totalnumberofpages}{numerototaledipagine} +\setinterfacecommand{translate}{traduci} +\setinterfacecommand{txt}{txt} +\setinterfacecommand{typ}{typ} +\setinterfacecommand{type}{type} +\setinterfacecommand{typebuffer}{typebuffer} +\setinterfacecommand{typefile}{typefile} +\setinterfacecommand{unitmeaning}{nomeunita} +\setinterfacecommand{unknown}{ignoto} +\setinterfacecommand{useJSscripts}{usaJSscripts} +\setinterfacecommand{useURL}{usaURL} +\setinterfacecommand{useXMLfilter}{useXMLfilter} +\setinterfacecommand{useblocks}{usablocco} +\setinterfacecommand{usecommands}{usacomandi} +\setinterfacecommand{useencoding}{usacodifica} +\setinterfacecommand{useexternaldocument}{usadocumentoesterno} +\setinterfacecommand{useexternalfigure}{usafiguraesterna} +\setinterfacecommand{useexternalfile}{usafileesterno} +\setinterfacecommand{useexternalfiles}{usafileesterni} +\setinterfacecommand{useexternalsoundtrack}{usacolonnasonoraesterna} +\setinterfacecommand{usemodule}{usamodulo} +\setinterfacecommand{usemodules}{usamoduli} +\setinterfacecommand{usepath}{usacartella} +\setinterfacecommand{usereferences}{usariferimenti} +\setinterfacecommand{usespecials}{usaspecialita} +\setinterfacecommand{usesymbols}{usasimboli} +\setinterfacecommand{usetypescript}{usetypescript} +\setinterfacecommand{usetypescriptfile}{usetypescriptfile} +\setinterfacecommand{useurl}{usaurl} +\setinterfacecommand{version}{versione} +\setinterfacecommand{vl}{vl} +\setinterfacecommand{weekday}{giornosettimana} +\setinterfacecommand{whitespace}{spaziobianco} +\setinterfacecommand{wordright}{paroladestra} +\setinterfacecommand{writebetweenlist}{scrividentroelenco} +\setinterfacecommand{writetolist}{scriviinelenco} +\setinterfacecommand{writetoreferencelist}{scriviinlistariferimenti} +\setinterfacecommand{writetoregister}{scriviinregistro} +% +\endinput \ No newline at end of file diff --git a/tex/context/base/mult-mcs.tex b/tex/context/base/mult-mcs.tex new file mode 100644 index 000000000..98c392c9f --- /dev/null +++ b/tex/context/base/mult-mcs.tex @@ -0,0 +1,208 @@ +\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}{30}{neznamy objekt --} +\setinterfacemessage{references}{25}{references from document '--' are not imported (export again)} +\setinterfacemessage{references}{24}{references from document '--' are not exported} +\setinterfacemessage{references}{title}{reference} +\setinterfacemessage{references}{26}{references from document '--' are imported} +\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{regimes}{1}{kodovani --} +\setinterfacemessage{regimes}{3}{nezname kodovani --} +\setinterfacemessage{regimes}{2}{je nacteno kodovani --} +\setinterfacemessage{regimes}{title}{kodovani} +\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{verbatims}{1}{soubor -- neexistuje} +\setinterfacemessage{verbatims}{title}{verbatim} +\setinterfacemessage{filters}{1}{filter -- is loaded} +\setinterfacemessage{filters}{title}{filter} +\setinterfacemessage{filters}{2}{unknown filter --} +\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{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{symbols}{1}{nacita se soubor symbolu --} +\setinterfacemessage{symbols}{title}{symboly} +\setinterfacemessage{files}{1}{synonymum souboru -- je jiz pouzito pro --} +\setinterfacemessage{files}{title}{soubory} +\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{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{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{publications}{1}{file -- not found, unknown style ignored} +\setinterfacemessage{publications}{3}{wrote a new auxiliary file \jobname.aux} +\setinterfacemessage{publications}{title}{publications} +\setinterfacemessage{publications}{2}{file -- not found, waiting for bibtex} +\setinterfacemessage{publications}{4}{loading database from --} +\setinterfacemessage{publications}{5}{warning: cite argument -- on line \the\inputlineno} +\setinterfacemessage{publications}{6}{loading formatting style from --} +\setinterfacemessage{javascript}{1}{nacita se soubor skriptu --} +\setinterfacemessage{javascript}{title}{javascript} +\setinterfacemessage{javascript}{2}{neznama preambule --} +\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{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} +\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} +% +\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..4da89ba33 --- /dev/null +++ b/tex/context/base/mult-mde.tex @@ -0,0 +1,208 @@ +\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}{30}{unbekanntes Object --} +\setinterfacemessage{references}{25}{references from document '--' are not imported (export again)} +\setinterfacemessage{references}{24}{references from document '--' are not exported} +\setinterfacemessage{references}{title}{referenzen} +\setinterfacemessage{references}{26}{references from document '--' are imported} +\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{regimes}{1}{Kodierung --} +\setinterfacemessage{regimes}{3}{Unbekannte Kodierung --} +\setinterfacemessage{regimes}{2}{Kodierung -- ist geladen} +\setinterfacemessage{regimes}{title}{Kodierung} +\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{verbatims}{1}{Datei -- existiert nicht} +\setinterfacemessage{verbatims}{title}{verbatim} +\setinterfacemessage{filters}{1}{filter -- ist geladen} +\setinterfacemessage{filters}{title}{filter} +\setinterfacemessage{filters}{2}{unknown filter --} +\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{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{symbols}{1}{Lade Symboldatei --} +\setinterfacemessage{symbols}{title}{Symbole} +\setinterfacemessage{files}{1}{Dateisynonym -- wird bereits fuer -- benutzt} +\setinterfacemessage{files}{title}{files} +\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{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{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{publications}{1}{file -- not found, unknown style ignored} +\setinterfacemessage{publications}{3}{wrote a new auxiliary file \jobname.aux} +\setinterfacemessage{publications}{title}{publications} +\setinterfacemessage{publications}{2}{file -- not found, waiting for bibtex} +\setinterfacemessage{publications}{4}{loading database from --} +\setinterfacemessage{publications}{5}{warning: cite argument -- on line \the\inputlineno} +\setinterfacemessage{publications}{6}{loading formatting style from --} +\setinterfacemessage{javascript}{1}{Lade Scriptdatei --} +\setinterfacemessage{javascript}{title}{javascript} +\setinterfacemessage{javascript}{2}{unbekannte Preamble --} +\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{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} +\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} +% +\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..4c1bc9942 --- /dev/null +++ b/tex/context/base/mult-men.tex @@ -0,0 +1,208 @@ +\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}{30}{unknown object --} +\setinterfacemessage{references}{25}{references from document '--' are not imported (export again)} +\setinterfacemessage{references}{24}{references from document '--' are not exported} +\setinterfacemessage{references}{title}{references} +\setinterfacemessage{references}{26}{references from document '--' are imported} +\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{regimes}{1}{regime --} +\setinterfacemessage{regimes}{3}{unknown regime --} +\setinterfacemessage{regimes}{2}{regime -- is loaded} +\setinterfacemessage{regimes}{title}{regime} +\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{verbatims}{1}{file -- does not exist} +\setinterfacemessage{verbatims}{title}{verbatim} +\setinterfacemessage{filters}{1}{filter -- is loaded} +\setinterfacemessage{filters}{title}{filter} +\setinterfacemessage{filters}{2}{unknown filter --} +\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{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{symbols}{1}{loading symbolset --} +\setinterfacemessage{symbols}{title}{symbols} +\setinterfacemessage{files}{1}{file synonym -- is already used for --} +\setinterfacemessage{files}{title}{files} +\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{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{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{publications}{1}{file -- not found, unknown style ignored} +\setinterfacemessage{publications}{3}{wrote a new auxiliary file \jobname.aux} +\setinterfacemessage{publications}{title}{publications} +\setinterfacemessage{publications}{2}{file -- not found, waiting for bibtex} +\setinterfacemessage{publications}{4}{loading database from --} +\setinterfacemessage{publications}{5}{warning: cite argument -- on line \the\inputlineno} +\setinterfacemessage{publications}{6}{loading formatting style from --} +\setinterfacemessage{javascript}{1}{loading script set --} +\setinterfacemessage{javascript}{title}{javascript} +\setinterfacemessage{javascript}{2}{unknown preamble --} +\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{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} +\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} +% +\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..5c8129711 --- /dev/null +++ b/tex/context/base/mult-mes.lua @@ -0,0 +1,2046 @@ +if not modules then modules = { } end modules ['mult-mes'] = { + version = 1.001, + comment = "companion to mult-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +return { + ["publications"]={ + ["files"]={ "bibl-tra.mkiv" }, + ["title"]={ + ["en"]="publications", + }, + ["1"]={ + ["en"]="file -- not found, unknown style ignored", + }, + ["2"]={ + ["en"]="file -- not found, waiting for bibtex", + }, + ["3"]={ + ["en"]="wrote a new auxiliary file \\jobname.aux", + }, + ["4"]={ + ["en"]="loading database from --", + }, + ["5"]={ + ["en"]="warning: cite argument -- on line \\the\\inputlineno", + }, + ["6"]={ + ["en"]="loading formatting style from --", + }, + }, + ["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=--)", + }, + ["24"]={ + ["en"]="references from document '--' are not exported", + }, + ["25"]={ + ["en"]="references from document '--' are not imported (export again)", + }, + ["26"]={ + ["en"]="references from document '--' are imported", + }, + ["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", + }, + }, +} diff --git a/tex/context/base/mult-mfr.tex b/tex/context/base/mult-mfr.tex new file mode 100644 index 000000000..78e4f9f17 --- /dev/null +++ b/tex/context/base/mult-mfr.tex @@ -0,0 +1,208 @@ +\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}{30}{objet -- inconnu} +\setinterfacemessage{references}{25}{references from document '--' are not imported (export again)} +\setinterfacemessage{references}{24}{references from document '--' are not exported} +\setinterfacemessage{references}{title}{réferences} +\setinterfacemessage{references}{26}{references from document '--' are imported} +\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{regimes}{1}{encodage --} +\setinterfacemessage{regimes}{3}{encodage -- inconnu} +\setinterfacemessage{regimes}{2}{l'encodage -- est chargé} +\setinterfacemessage{regimes}{title}{encodage} +\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{verbatims}{1}{le fichier -- n'existe pas} +\setinterfacemessage{verbatims}{title}{verbatim} +\setinterfacemessage{filters}{1}{le filtre -- est chargé} +\setinterfacemessage{filters}{title}{filtre} +\setinterfacemessage{filters}{2}{filtre -- inconnu} +\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{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{symbols}{1}{chargement du jeu de symbole --} +\setinterfacemessage{symbols}{title}{symboles} +\setinterfacemessage{files}{1}{le synonyme de fichier -- est déjà utilisé pour --} +\setinterfacemessage{files}{title}{fichiers} +\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{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{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{publications}{1}{file -- not found, unknown style ignored} +\setinterfacemessage{publications}{3}{wrote a new auxiliary file \jobname.aux} +\setinterfacemessage{publications}{title}{publications} +\setinterfacemessage{publications}{2}{file -- not found, waiting for bibtex} +\setinterfacemessage{publications}{4}{loading database from --} +\setinterfacemessage{publications}{5}{warning: cite argument -- on line \the\inputlineno} +\setinterfacemessage{publications}{6}{loading formatting style from --} +\setinterfacemessage{javascript}{1}{chargement du jeu de script --} +\setinterfacemessage{javascript}{title}{javascript} +\setinterfacemessage{javascript}{2}{préambule -- inconnu} +\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{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} +\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é} +% +\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..6d2a8f516 --- /dev/null +++ b/tex/context/base/mult-mit.tex @@ -0,0 +1,208 @@ +\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}{30}{oggetto sconosciuto --} +\setinterfacemessage{references}{25}{references from document '--' are not imported (export again)} +\setinterfacemessage{references}{24}{references from document '--' are not exported} +\setinterfacemessage{references}{title}{riferimenti} +\setinterfacemessage{references}{26}{references from document '--' are imported} +\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{regimes}{1}{codifica --} +\setinterfacemessage{regimes}{3}{codifica sconosciuta --} +\setinterfacemessage{regimes}{2}{codifica -- caricata} +\setinterfacemessage{regimes}{title}{codifica} +\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{verbatims}{1}{il file -- non esiste} +\setinterfacemessage{verbatims}{title}{verbatim} +\setinterfacemessage{filters}{1}{filtro -- caricato} +\setinterfacemessage{filters}{title}{filtri} +\setinterfacemessage{filters}{2}{filtro sconosciuto --} +\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{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{symbols}{1}{caricamento gruppo di simboli --} +\setinterfacemessage{symbols}{title}{simboli} +\setinterfacemessage{files}{1}{sinonimo file -- già in uso per --} +\setinterfacemessage{files}{title}{file} +\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{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{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{publications}{1}{file -- not found, unknown style ignored} +\setinterfacemessage{publications}{3}{wrote a new auxiliary file \jobname.aux} +\setinterfacemessage{publications}{title}{publications} +\setinterfacemessage{publications}{2}{file -- not found, waiting for bibtex} +\setinterfacemessage{publications}{4}{loading database from --} +\setinterfacemessage{publications}{5}{warning: cite argument -- on line \the\inputlineno} +\setinterfacemessage{publications}{6}{loading formatting style from --} +\setinterfacemessage{javascript}{1}{caricamento dello script set --} +\setinterfacemessage{javascript}{title}{javascript} +\setinterfacemessage{javascript}{2}{preambolo sconosciuto --} +\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{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} +\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} +% +\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..b8204a40b --- /dev/null +++ b/tex/context/base/mult-mnl.tex @@ -0,0 +1,208 @@ +\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}{30}{onbekend object --} +\setinterfacemessage{references}{25}{references from document '--' are not imported (export again)} +\setinterfacemessage{references}{24}{references from document '--' are not exported} +\setinterfacemessage{references}{title}{verwijzingen} +\setinterfacemessage{references}{26}{references from document '--' are imported} +\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{regimes}{1}{regime --} +\setinterfacemessage{regimes}{3}{onbekend regime --} +\setinterfacemessage{regimes}{2}{regime -- wordt geladen} +\setinterfacemessage{regimes}{title}{regime} +\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{verbatims}{1}{file -- bestaat niet} +\setinterfacemessage{verbatims}{title}{typen} +\setinterfacemessage{filters}{1}{filter -- wordt geladen} +\setinterfacemessage{filters}{title}{filter} +\setinterfacemessage{filters}{2}{onbekend filter --} +\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{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{symbols}{1}{symboolset -- wordt geladen} +\setinterfacemessage{symbols}{title}{symbolen} +\setinterfacemessage{files}{1}{file synoniem -- is al in gebruik voor --} +\setinterfacemessage{files}{title}{files} +\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{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{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{publications}{1}{file -- not found, unknown style ignored} +\setinterfacemessage{publications}{3}{wrote a new auxiliary file \jobname.aux} +\setinterfacemessage{publications}{title}{publications} +\setinterfacemessage{publications}{2}{file -- not found, waiting for bibtex} +\setinterfacemessage{publications}{4}{loading database from --} +\setinterfacemessage{publications}{5}{warning: cite argument -- on line \the\inputlineno} +\setinterfacemessage{publications}{6}{loading formatting style from --} +\setinterfacemessage{javascript}{1}{script set -- wordt geladen} +\setinterfacemessage{javascript}{title}{javascript} +\setinterfacemessage{javascript}{2}{onbekende preamble --} +\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{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} +\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} +% +\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..ee6fd3273 --- /dev/null +++ b/tex/context/base/mult-mno.tex @@ -0,0 +1,208 @@ +\setinterfacemessage{references}{1}{ukjent referanse --} +\setinterfacemessage{references}{3}{ukjent referansetype --} +\setinterfacemessage{references}{2}{duplikat referanse -- pø side --} +\setinterfacemessage{references}{4}{ulovlig referanse --} +\setinterfacemessage{references}{30}{ukjent objekt --} +\setinterfacemessage{references}{25}{references from document '--' are not imported (export again)} +\setinterfacemessage{references}{24}{references from document '--' are not exported} +\setinterfacemessage{references}{title}{referanser} +\setinterfacemessage{references}{26}{references from document '--' are imported} +\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{regimes}{1}{koding --} +\setinterfacemessage{regimes}{3}{ukjent koding --} +\setinterfacemessage{regimes}{2}{koding -- er lest inn} +\setinterfacemessage{regimes}{title}{koding} +\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{verbatims}{1}{fil -- eksisterer ikke} +\setinterfacemessage{verbatims}{title}{verbatim} +\setinterfacemessage{filters}{1}{filter -- is loaded} +\setinterfacemessage{filters}{title}{filter} +\setinterfacemessage{filters}{2}{unknown filter --} +\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{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{symbols}{1}{leser inn symbolsett --} +\setinterfacemessage{symbols}{title}{symboler} +\setinterfacemessage{files}{1}{filesynonym -- er allerede brukt for --} +\setinterfacemessage{files}{title}{filer} +\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{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{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{publications}{1}{file -- not found, unknown style ignored} +\setinterfacemessage{publications}{3}{wrote a new auxiliary file \jobname.aux} +\setinterfacemessage{publications}{title}{publications} +\setinterfacemessage{publications}{2}{file -- not found, waiting for bibtex} +\setinterfacemessage{publications}{4}{loading database from --} +\setinterfacemessage{publications}{5}{warning: cite argument -- on line \the\inputlineno} +\setinterfacemessage{publications}{6}{loading formatting style from --} +\setinterfacemessage{javascript}{1}{leser inn scriptsett --} +\setinterfacemessage{javascript}{title}{javascript} +\setinterfacemessage{javascript}{2}{ukjent 'preamble' --} +\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{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} +\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} +% +\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..4c1bc9942 --- /dev/null +++ b/tex/context/base/mult-mpe.tex @@ -0,0 +1,208 @@ +\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}{30}{unknown object --} +\setinterfacemessage{references}{25}{references from document '--' are not imported (export again)} +\setinterfacemessage{references}{24}{references from document '--' are not exported} +\setinterfacemessage{references}{title}{references} +\setinterfacemessage{references}{26}{references from document '--' are imported} +\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{regimes}{1}{regime --} +\setinterfacemessage{regimes}{3}{unknown regime --} +\setinterfacemessage{regimes}{2}{regime -- is loaded} +\setinterfacemessage{regimes}{title}{regime} +\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{verbatims}{1}{file -- does not exist} +\setinterfacemessage{verbatims}{title}{verbatim} +\setinterfacemessage{filters}{1}{filter -- is loaded} +\setinterfacemessage{filters}{title}{filter} +\setinterfacemessage{filters}{2}{unknown filter --} +\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{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{symbols}{1}{loading symbolset --} +\setinterfacemessage{symbols}{title}{symbols} +\setinterfacemessage{files}{1}{file synonym -- is already used for --} +\setinterfacemessage{files}{title}{files} +\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{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{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{publications}{1}{file -- not found, unknown style ignored} +\setinterfacemessage{publications}{3}{wrote a new auxiliary file \jobname.aux} +\setinterfacemessage{publications}{title}{publications} +\setinterfacemessage{publications}{2}{file -- not found, waiting for bibtex} +\setinterfacemessage{publications}{4}{loading database from --} +\setinterfacemessage{publications}{5}{warning: cite argument -- on line \the\inputlineno} +\setinterfacemessage{publications}{6}{loading formatting style from --} +\setinterfacemessage{javascript}{1}{loading script set --} +\setinterfacemessage{javascript}{title}{javascript} +\setinterfacemessage{javascript}{2}{unknown preamble --} +\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{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} +\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} +% +\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..da96a23a4 --- /dev/null +++ b/tex/context/base/mult-mro.tex @@ -0,0 +1,208 @@ +\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}{30}{obiect necunoscut --} +\setinterfacemessage{references}{25}{references from document '--' are not imported (export again)} +\setinterfacemessage{references}{24}{references from document '--' are not exported} +\setinterfacemessage{references}{title}{referinte} +\setinterfacemessage{references}{26}{references from document '--' are imported} +\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{regimes}{1}{codificarea --} +\setinterfacemessage{regimes}{3}{codificarea -- este necunoscuta} +\setinterfacemessage{regimes}{2}{codificarea -- este Encarcata} +\setinterfacemessage{regimes}{title}{codificari} +\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{verbatims}{1}{fisierul -- nu exista} +\setinterfacemessage{verbatims}{title}{verbatim} +\setinterfacemessage{filters}{1}{filter -- is loaded} +\setinterfacemessage{filters}{title}{filter} +\setinterfacemessage{filters}{2}{unknown filter --} +\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{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{symbols}{1}{se incarca setul de simboluri --} +\setinterfacemessage{symbols}{title}{simboluri} +\setinterfacemessage{files}{1}{sinonimul fisierelor -- este folosit deja pentru --} +\setinterfacemessage{files}{title}{fisiere} +\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{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{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{publications}{1}{file -- not found, unknown style ignored} +\setinterfacemessage{publications}{3}{wrote a new auxiliary file \jobname.aux} +\setinterfacemessage{publications}{title}{publications} +\setinterfacemessage{publications}{2}{file -- not found, waiting for bibtex} +\setinterfacemessage{publications}{4}{loading database from --} +\setinterfacemessage{publications}{5}{warning: cite argument -- on line \the\inputlineno} +\setinterfacemessage{publications}{6}{loading formatting style from --} +\setinterfacemessage{javascript}{1}{se incarca scriptul --} +\setinterfacemessage{javascript}{title}{javascript} +\setinterfacemessage{javascript}{2}{preambul necunoscut --} +\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{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} +\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} +% +\endinput \ No newline at end of file diff --git a/tex/context/base/mult-nl.tex b/tex/context/base/mult-nl.tex new file mode 100644 index 000000000..074d5f3d5 --- /dev/null +++ b/tex/context/base/mult-nl.tex @@ -0,0 +1,1693 @@ +% this file is auto-generated, don't edit this file +% +% definitions for interface variables for language nl +% +\setinterfacevariable{Addition}{Toevoeging} +\setinterfacevariable{Balloon}{Ballon} +\setinterfacevariable{Character}{Letter} +\setinterfacevariable{Characters}{Letters} +\setinterfacevariable{CloseDocument}{SluitDocument} +\setinterfacevariable{ExitViewer}{VerlaatViewer} +\setinterfacevariable{FirstPage}{EerstePagina} +\setinterfacevariable{FitHeight}{HoogtePassend} +\setinterfacevariable{FitWidth}{BreedtePassend} +\setinterfacevariable{GotoPage}{GaNaarPagina} +\setinterfacevariable{Greek}{Grieks} +\setinterfacevariable{Help}{Help} +\setinterfacevariable{HideField}{VerbergVeld} +\setinterfacevariable{HideLayer}{VerbergLaag} +\setinterfacevariable{Key}{Sleutel} +\setinterfacevariable{LastPage}{LaatstePagina} +\setinterfacevariable{LoadForm}{LaadFormulier} +\setinterfacevariable{MONTH}{MAAND} +\setinterfacevariable{New}{Nieuw} +\setinterfacevariable{NextJump}{VolgendeSprong} +\setinterfacevariable{NextPage}{VolgendePagina} +\setinterfacevariable{Numbers}{Cijfers} +\setinterfacevariable{OpenNamedDocument}{OpenDocumentOpNaam} +\setinterfacevariable{Paragraph}{Paragraaf} +\setinterfacevariable{PauseMovie}{PauzeerFilm} +\setinterfacevariable{PauseRendering}{PauzeerRendering} +\setinterfacevariable{PauseSound}{PauzeerGeluid} +\setinterfacevariable{PreviousJump}{VorigeSprong} +\setinterfacevariable{PreviousPage}{VorigePagina} +\setinterfacevariable{PrintDocument}{PrintDocument} +\setinterfacevariable{Query}{RaadpleegDocument} +\setinterfacevariable{QueryAgain}{HerhaalRaadplegen} +\setinterfacevariable{ResetForm}{ResetFormulier} +\setinterfacevariable{ResumeMovie}{HervatFilm} +\setinterfacevariable{ResumeRendering}{HervatRendering} +\setinterfacevariable{ResumeSound}{HervatGeluid} +\setinterfacevariable{Romannumerals}{Romeins} +\setinterfacevariable{SaveDocument}{BewaarDocument} +\setinterfacevariable{SaveForm}{BewaarFormulier} +\setinterfacevariable{SaveNamedDocument}{BewaarDocumentOpNaam} +\setinterfacevariable{SearchAgain}{HerhaalZoeken} +\setinterfacevariable{SearchDocument}{DoorzoekDocument} +\setinterfacevariable{ShowBookmarks}{ShowBookmarks} +\setinterfacevariable{ShowField}{ToonVeld} +\setinterfacevariable{ShowThumbs}{ShowThumbs} +\setinterfacevariable{StartMovie}{StartFilm} +\setinterfacevariable{StartRendering}{StartRendering} +\setinterfacevariable{StartSound}{StartGeluid} +\setinterfacevariable{StopMovie}{StopFilm} +\setinterfacevariable{StopRendering}{StopRendering} +\setinterfacevariable{StopSound}{StopGeluid} +\setinterfacevariable{SubmitForm}{VerzendFormulier} +\setinterfacevariable{ToggleLayer}{WisselLaag} +\setinterfacevariable{ToggleViewer}{WisselViewer} +\setinterfacevariable{URL}{URL} +\setinterfacevariable{VideLayer}{ToonLaag} +\setinterfacevariable{ViewerHelp}{ViewerHelp} +\setinterfacevariable{WEEKDAY}{WEEKDAG} +\setinterfacevariable{WORD}{WOORD} +\setinterfacevariable{abbreviation}{afkorting} +\setinterfacevariable{abbreviations}{afkortingen} +\setinterfacevariable{absolute}{absoluut} +\setinterfacevariable{action}{actie} +\setinterfacevariable{after}{na} +\setinterfacevariable{all}{alles} +\setinterfacevariable{always}{altijd} +\setinterfacevariable{answerarea}{antwoordgebied} +\setinterfacevariable{appendices}{bijlagen} +\setinterfacevariable{appendix}{bijlage} +\setinterfacevariable{april}{april} +\setinterfacevariable{atmargin}{opmarge} +\setinterfacevariable{atpage}{oppagina} +\setinterfacevariable{august}{augustus} +\setinterfacevariable{author}{auteur} +\setinterfacevariable{auto}{auto} +\setinterfacevariable{autointro}{autointro} +\setinterfacevariable{back}{terug} +\setinterfacevariable{background}{achtergrond} +\setinterfacevariable{backmatter}{uitleidingen} +\setinterfacevariable{backpart}{uitleiding} +\setinterfacevariable{backspace}{rugwit} +\setinterfacevariable{backward}{achteruit} +\setinterfacevariable{bbl}{bbl} +\setinterfacevariable{before}{voor} +\setinterfacevariable{begin}{begin} +\setinterfacevariable{bib}{bib} +\setinterfacevariable{big}{groot} +\setinterfacevariable{bigbodyfont}{grootkorps} +\setinterfacevariable{bigpreference}{grotevoorkeur} +\setinterfacevariable{blank}{blanko} +\setinterfacevariable{blockquote}{blokcitaat} +\setinterfacevariable{bodymatter}{hoofdteksten} +\setinterfacevariable{bodypart}{hoofdtekst} +\setinterfacevariable{bold}{vet} +\setinterfacevariable{bolditalic}{vetitalic} +\setinterfacevariable{boldslanted}{vetschuin} +\setinterfacevariable{bookmark}{bookmark} +\setinterfacevariable{both}{beide} +\setinterfacevariable{bottom}{onder} +\setinterfacevariable{brief}{brief} +\setinterfacevariable{broad}{ruim} +\setinterfacevariable{buffer}{buffer} +\setinterfacevariable{by}{per} +\setinterfacevariable{calligraphic}{calligrafie} +\setinterfacevariable{cap}{kap} +\setinterfacevariable{capital}{kapitaal} +\setinterfacevariable{center}{centreer} +\setinterfacevariable{chapter}{hoofdstuk} +\setinterfacevariable{character}{letter} +\setinterfacevariable{characters}{letters} +\setinterfacevariable{cite}{cite} +\setinterfacevariable{color}{kleur} +\setinterfacevariable{column}{kolom} +\setinterfacevariable{columns}{kolommen} +\setinterfacevariable{command}{commando} +\setinterfacevariable{commands}{commandos} +\setinterfacevariable{comment}{commentaar} +\setinterfacevariable{component}{onderdeel} +\setinterfacevariable{concept}{concept} +\setinterfacevariable{content}{inhoud} +\setinterfacevariable{contents}{inhouden} +\setinterfacevariable{continue}{verder} +\setinterfacevariable{controls}{sturing} +\setinterfacevariable{conversion}{conversie} +\setinterfacevariable{current}{huidige} +\setinterfacevariable{cutspace}{snijwit} +\setinterfacevariable{date}{datum} +\setinterfacevariable{day}{dag} +\setinterfacevariable{december}{december} +\setinterfacevariable{default}{default} +\setinterfacevariable{depth}{diepte} +\setinterfacevariable{description}{doordefinitie} +\setinterfacevariable{disable}{blokkeer} +\setinterfacevariable{display}{scherm} +\setinterfacevariable{dot}{punt} +\setinterfacevariable{doublesided}{dubbelzijdig} +\setinterfacevariable{down}{omlaag} +\setinterfacevariable{each}{elk} +\setinterfacevariable{edge}{rand} +\setinterfacevariable{empty}{leeg} +\setinterfacevariable{end}{eind} +\setinterfacevariable{endnote}{eindnoot} +\setinterfacevariable{enumeration}{doornummering} +\setinterfacevariable{environment}{omgeving} +\setinterfacevariable{even}{even} +\setinterfacevariable{external}{extern} +\setinterfacevariable{fact}{gegeven} +\setinterfacevariable{february}{februari} +\setinterfacevariable{figure}{figuur} +\setinterfacevariable{figures}{figuren} +\setinterfacevariable{file}{file} +\setinterfacevariable{final}{definitief} +\setinterfacevariable{first}{eerste} +\setinterfacevariable{firstcolumn}{eerstekolom} +\setinterfacevariable{firstpage}{eerstepagina} +\setinterfacevariable{firstsubpage}{eerstesubpagina} +\setinterfacevariable{fit}{passend} +\setinterfacevariable{five}{vijf} +\setinterfacevariable{fix}{herstel} +\setinterfacevariable{fixed}{vast} +\setinterfacevariable{flexible}{flexibel} +\setinterfacevariable{float}{blok} +\setinterfacevariable{flushinner}{lijnbinnen} +\setinterfacevariable{flushleft}{lijnlinks} +\setinterfacevariable{flushouter}{lijnbuiten} +\setinterfacevariable{flushright}{lijnrechts} +\setinterfacevariable{footer}{voet} +\setinterfacevariable{footnote}{voetnoot} +\setinterfacevariable{force}{forceer} +\setinterfacevariable{foreground}{voorgrond} +\setinterfacevariable{formeel}{formeel} +\setinterfacevariable{formula}{formule} +\setinterfacevariable{formulae}{formules} +\setinterfacevariable{forward}{vooruit} +\setinterfacevariable{four}{vier} +\setinterfacevariable{frame}{kader} +\setinterfacevariable{framedtext}{kadertekst} +\setinterfacevariable{friday}{vrijdag} +\setinterfacevariable{frontmatter}{inleidingen} +\setinterfacevariable{frontpart}{inleiding} +\setinterfacevariable{global}{globaal} +\setinterfacevariable{graphic}{grafiek} +\setinterfacevariable{graphics}{grafieken} +\setinterfacevariable{gray}{grijs} +\setinterfacevariable{greek}{grieks} +\setinterfacevariable{grid}{grid} +\setinterfacevariable{halfline}{halveregel} +\setinterfacevariable{handwritten}{handschrift} +\setinterfacevariable{hang}{hang} +\setinterfacevariable{hanging}{hangend} +\setinterfacevariable{head}{kop} +\setinterfacevariable{header}{hoofd} +\setinterfacevariable{height}{hoogte} +\setinterfacevariable{helptext}{helptekst} +\setinterfacevariable{hencefore}{hierboven} +\setinterfacevariable{here}{hier} +\setinterfacevariable{hereafter}{hieronder} +\setinterfacevariable{hidden}{verborgen} +\setinterfacevariable{hiding}{verbergen} +\setinterfacevariable{high}{hoog} +\setinterfacevariable{horizontal}{horizontaal} +\setinterfacevariable{hyphenated}{afgebroken} +\setinterfacevariable{hz}{hz} +\setinterfacevariable{inbetween}{tussen} +\setinterfacevariable{index}{index} +\setinterfacevariable{indices}{indices} +\setinterfacevariable{informeel}{informeel} +\setinterfacevariable{inherit}{erf} +\setinterfacevariable{inleft}{inlinker} +\setinterfacevariable{inmargin}{inmarge} +\setinterfacevariable{inner}{binnen} +\setinterfacevariable{inneredge}{binnenrand} +\setinterfacevariable{innermargin}{binnenmarge} +\setinterfacevariable{inright}{inrechter} +\setinterfacevariable{interaction}{interactie} +\setinterfacevariable{interactionmenu}{interactiemenu} +\setinterfacevariable{intermezzi}{intermezzos} +\setinterfacevariable{intermezzo}{intermezzo} +\setinterfacevariable{intext}{intekst} +\setinterfacevariable{intro}{intro} +\setinterfacevariable{italic}{italic} +\setinterfacevariable{italicbold}{italicvet} +\setinterfacevariable{item}{som} +\setinterfacevariable{itemize}{opsomming} +\setinterfacevariable{its}{its} +\setinterfacevariable{january}{januari} +\setinterfacevariable{joinedup}{aansluitend} +\setinterfacevariable{july}{juli} +\setinterfacevariable{june}{juni} +\setinterfacevariable{keep}{handhaaf} +\setinterfacevariable{knockout}{knockout} +\setinterfacevariable{label}{label} +\setinterfacevariable{landscape}{liggend} +\setinterfacevariable{last}{laatste} +\setinterfacevariable{lastcolumn}{laatstekolom} +\setinterfacevariable{lastpage}{laatstepagina} +\setinterfacevariable{lastpagenumber}{laatstepaginanummer} +\setinterfacevariable{lastsubpage}{laatstesubpagina} +\setinterfacevariable{layer}{layer} +\setinterfacevariable{left}{links} +\setinterfacevariable{leftedge}{linkerrand} +\setinterfacevariable{lefthanging}{linkshangend} +\setinterfacevariable{leftmargin}{linkermarge} +\setinterfacevariable{leftpage}{linkerpagina} +\setinterfacevariable{lefttoright}{lefttoright} +\setinterfacevariable{legend}{legenda} +\setinterfacevariable{lesshyphenation}{lesshyphenation} +\setinterfacevariable{line}{regel} +\setinterfacevariable{linenote}{regelnoot} +\setinterfacevariable{lines}{regels} +\setinterfacevariable{list}{lijst} +\setinterfacevariable{local}{lokaal} +\setinterfacevariable{localenvironment}{deelomgeving} +\setinterfacevariable{logo}{logo} +\setinterfacevariable{logos}{logos} +\setinterfacevariable{lohi}{laho} +\setinterfacevariable{loose}{los} +\setinterfacevariable{low}{laag} +\setinterfacevariable{ls}{ls} +\setinterfacevariable{makeup}{opmaak} +\setinterfacevariable{mar}{mar} +\setinterfacevariable{march}{maart} +\setinterfacevariable{margin}{marge} +\setinterfacevariable{marginedge}{kantlijn} +\setinterfacevariable{margintitle}{margetitel} +\setinterfacevariable{marking}{markering} +\setinterfacevariable{mathalignment}{wiskundeuitlijnen} +\setinterfacevariable{mathcases}{mathcases} +\setinterfacevariable{mathmatrix}{wiskundematrix} +\setinterfacevariable{max}{max} +\setinterfacevariable{maxdepth}{maxdepth} +\setinterfacevariable{maxheight}{maxheight} +\setinterfacevariable{maxwidth}{maxwidth} +\setinterfacevariable{may}{mei} +\setinterfacevariable{mediaeval}{mediaeval} +\setinterfacevariable{medium}{middel} +\setinterfacevariable{middle}{midden} +\setinterfacevariable{min}{min} +\setinterfacevariable{mindepth}{mindepth} +\setinterfacevariable{minheight}{minhoogte} +\setinterfacevariable{minwidth}{minbreedte} +\setinterfacevariable{mirrored}{gespiegeld} +\setinterfacevariable{monday}{maandag} +\setinterfacevariable{mono}{mono} +\setinterfacevariable{month}{maand} +\setinterfacevariable{morehyphenation}{morehyphenation} +\setinterfacevariable{name}{naam} +\setinterfacevariable{narrow}{smal} +\setinterfacevariable{negative}{negatief} +\setinterfacevariable{never}{nooit} +\setinterfacevariable{new}{nieuw} +\setinterfacevariable{next}{volgende} +\setinterfacevariable{nextevenpage}{volgendeevenpagina} +\setinterfacevariable{nextoddpage}{volgendeonevenpagina} +\setinterfacevariable{nextpage}{volgendepagina} +\setinterfacevariable{nextsubpage}{volgendesubpagina} +\setinterfacevariable{no}{nee} +\setinterfacevariable{nocheck}{geencontrole} +\setinterfacevariable{nofit}{nietpassend} +\setinterfacevariable{nogrid}{geengrid} +\setinterfacevariable{nohz}{geenhz} +\setinterfacevariable{nomarking}{geenmarkering} +\setinterfacevariable{none}{geen} +\setinterfacevariable{nonumber}{geennummer} +\setinterfacevariable{normal}{normaal} +\setinterfacevariable{nospacing}{geenspatiering} +\setinterfacevariable{not}{niet} +\setinterfacevariable{note}{note} +\setinterfacevariable{nothanging}{niethangend} +\setinterfacevariable{nothyphenated}{nietafgebroken} +\setinterfacevariable{november}{november} +\setinterfacevariable{nowhere}{nergens} +\setinterfacevariable{nowhite}{geenwit} +\setinterfacevariable{number}{nummer} +\setinterfacevariable{numbers}{cijfers} +\setinterfacevariable{october}{oktober} +\setinterfacevariable{odd}{oneven} +\setinterfacevariable{off}{uit} +\setinterfacevariable{offset}{offset} +\setinterfacevariable{old}{oud} +\setinterfacevariable{on}{aan} +\setinterfacevariable{one}{een} +\setinterfacevariable{opposite}{naast} +\setinterfacevariable{outer}{buiten} +\setinterfacevariable{outeredge}{buitenrand} +\setinterfacevariable{outermargin}{buitenmarge} +\setinterfacevariable{overbar}{overstreep} +\setinterfacevariable{overbars}{overstrepen} +\setinterfacevariable{overlay}{overlay} +\setinterfacevariable{overprint}{overprint} +\setinterfacevariable{overstrike}{doorstreep} +\setinterfacevariable{overstrikes}{doorstrepen} +\setinterfacevariable{packed}{opelkaar} +\setinterfacevariable{page}{pagina} +\setinterfacevariable{pagecomment}{paginacommentaar} +\setinterfacevariable{pagenumber}{paginanummer} +\setinterfacevariable{paper}{papier} +\setinterfacevariable{paragraph}{alinea} +\setinterfacevariable{part}{deel} +\setinterfacevariable{positive}{positief} +\setinterfacevariable{postponing}{uitstellen} +\setinterfacevariable{postscript}{postscript} +\setinterfacevariable{preference}{voorkeur} +\setinterfacevariable{preview}{preview} +\setinterfacevariable{previous}{vorige} +\setinterfacevariable{previousevenpage}{vorigeevenpagina} +\setinterfacevariable{previousoddpage}{vorigeonevenpagina} +\setinterfacevariable{previouspage}{vorigepagina} +\setinterfacevariable{previoussubpage}{vorigesubpagina} +\setinterfacevariable{printable}{printbaar} +\setinterfacevariable{process}{proces} +\setinterfacevariable{product}{produkt} +\setinterfacevariable{program}{programma} +\setinterfacevariable{project}{project} +\setinterfacevariable{protected}{beschermd} +\setinterfacevariable{quadruple}{viertal} +\setinterfacevariable{quotation}{citaat} +\setinterfacevariable{quote}{citeer} +\setinterfacevariable{ran}{ran} +\setinterfacevariable{random}{willekeurig} +\setinterfacevariable{readonly}{alleenleesbaar} +\setinterfacevariable{rectangular}{recht} +\setinterfacevariable{referral}{kenmerk} +\setinterfacevariable{register}{register} +\setinterfacevariable{regular}{regular} +\setinterfacevariable{rekening}{rekening} +\setinterfacevariable{relative}{relatief} +\setinterfacevariable{repeat}{herhaal} +\setinterfacevariable{required}{verplicht} +\setinterfacevariable{reset}{reset} +\setinterfacevariable{reverse}{omgekeerd} +\setinterfacevariable{right}{rechts} +\setinterfacevariable{rightedge}{rechterrand} +\setinterfacevariable{righthanging}{rechtshangend} +\setinterfacevariable{rightmargin}{rechtermarge} +\setinterfacevariable{rightpage}{rechterpagina} +\setinterfacevariable{righttoleft}{righttoleft} +\setinterfacevariable{roman}{romaan} +\setinterfacevariable{romannumerals}{romeins} +\setinterfacevariable{rotate}{roteer} +\setinterfacevariable{rotated}{geroteerd} +\setinterfacevariable{round}{rond} +\setinterfacevariable{row}{rij} +\setinterfacevariable{rule}{lijn} +\setinterfacevariable{samepage}{zelfdepagina} +\setinterfacevariable{sans}{sans} +\setinterfacevariable{sansbold}{sansvet} +\setinterfacevariable{sansserif}{schreefloos} +\setinterfacevariable{saturday}{zaterdag} +\setinterfacevariable{screen}{raster} +\setinterfacevariable{section}{paragraaf} +\setinterfacevariable{sectionblockenvironment}{sectieblokomgeving} +\setinterfacevariable{sectionnumber}{sectienummer} +\setinterfacevariable{see}{zie} +\setinterfacevariable{september}{september} +\setinterfacevariable{serif}{serif} +\setinterfacevariable{serried}{aanelkaar} +\setinterfacevariable{setups}{instellingen} +\setinterfacevariable{sheet}{sheet} +\setinterfacevariable{short}{kort} +\setinterfacevariable{singlesided}{enkelzijdig} +\setinterfacevariable{slanted}{schuin} +\setinterfacevariable{slantedbold}{schuinvet} +\setinterfacevariable{small}{klein} +\setinterfacevariable{smallbodyfont}{kleinkorps} +\setinterfacevariable{smallbold}{kleinvet} +\setinterfacevariable{smallbolditalic}{kleinvetitalic} +\setinterfacevariable{smallboldslanted}{kleinvetschuin} +\setinterfacevariable{smallcaps}{smallcaps} +\setinterfacevariable{smallitalic}{kleinitalic} +\setinterfacevariable{smallitalicbold}{kleinitalicvet} +\setinterfacevariable{smallnormal}{kleinnormaal} +\setinterfacevariable{smallslanted}{kleinschuin} +\setinterfacevariable{smallslantedbold}{kleinschuinvet} +\setinterfacevariable{smalltype}{kleintype} +\setinterfacevariable{somewhere}{ergens} +\setinterfacevariable{sorted}{gesorteerd} +\setinterfacevariable{space}{spatie} +\setinterfacevariable{spacing}{spatiering} +\setinterfacevariable{speech}{spraak} +\setinterfacevariable{split}{splitsen} +\setinterfacevariable{spot}{spot} +\setinterfacevariable{standard}{standaard} +\setinterfacevariable{start}{start} +\setinterfacevariable{starter}{opener} +\setinterfacevariable{sticker}{sticker} +\setinterfacevariable{stop}{stop} +\setinterfacevariable{stopper}{afsluiter} +\setinterfacevariable{stretch}{rek} +\setinterfacevariable{strict}{streng} +\setinterfacevariable{strong}{sterk} +\setinterfacevariable{strut}{strut} +\setinterfacevariable{sub}{sub} +\setinterfacevariable{subbackward}{subachteruit} +\setinterfacevariable{subformula}{subformule} +\setinterfacevariable{subforward}{subvooruit} +\setinterfacevariable{subject}{onderwerp} +\setinterfacevariable{subpage}{subpagina} +\setinterfacevariable{subsection}{subparagraaf} +\setinterfacevariable{subsubject}{subonderwerp} +\setinterfacevariable{subsubsection}{subsubparagraaf} +\setinterfacevariable{subsubsubject}{subsubonderwerp} +\setinterfacevariable{subsubsubsection}{subsubsubparagraaf} +\setinterfacevariable{subsubsubsubject}{subsubsubonderwerp} +\setinterfacevariable{subsubsubsubsection}{subsubsubsubparagraaf} +\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} +\setinterfacevariable{symbol}{symbool} +\setinterfacevariable{synchronize}{synchroniseer} +\setinterfacevariable{system}{systeem} +\setinterfacevariable{table}{tabel} +\setinterfacevariable{tablehead}{tabelkop} +\setinterfacevariable{tables}{tabellen} +\setinterfacevariable{tabletail}{tabelstaart} +\setinterfacevariable{tabulate}{tabulatie} +\setinterfacevariable{tabulatehead}{tabulatiekop} +\setinterfacevariable{tabulatetail}{tabulatiestaart} +\setinterfacevariable{tall}{lang} +\setinterfacevariable{teletype}{teletype} +\setinterfacevariable{temporary}{voorlopig} +\setinterfacevariable{test}{test} +\setinterfacevariable{text}{tekst} +\setinterfacevariable{three}{drie} +\setinterfacevariable{thursday}{donderdag} +\setinterfacevariable{title}{titel} +\setinterfacevariable{toggle}{toggle} +\setinterfacevariable{tolerant}{soepel} +\setinterfacevariable{top}{boven} +\setinterfacevariable{tuesday}{dinsdag} +\setinterfacevariable{two}{twee} +\setinterfacevariable{txt}{txt} +\setinterfacevariable{type}{type} +\setinterfacevariable{typing}{typen} +\setinterfacevariable{unavailable}{nietbeschikbaar} +\setinterfacevariable{underbar}{onderstreep} +\setinterfacevariable{underbars}{onderstrepen} +\setinterfacevariable{unit}{eenheid} +\setinterfacevariable{units}{eenheden} +\setinterfacevariable{unknown}{onbekend} +\setinterfacevariable{unpacked}{vanelkaar} +\setinterfacevariable{up}{omhoog} +\setinterfacevariable{url}{url} +\setinterfacevariable{used}{gebruikt} +\setinterfacevariable{value}{waarde} +\setinterfacevariable{vertical}{vertikaal} +\setinterfacevariable{very}{zeer} +\setinterfacevariable{verystrict}{zeerstreng} +\setinterfacevariable{verytolerant}{zeersoepel} +\setinterfacevariable{weak}{zwak} +\setinterfacevariable{wednesday}{woensdag} +\setinterfacevariable{week}{week} +\setinterfacevariable{weekday}{weekdag} +\setinterfacevariable{white}{wit} +\setinterfacevariable{wide}{breed} +\setinterfacevariable{width}{breedte} +\setinterfacevariable{xml}{xml} +\setinterfacevariable{year}{jaar} +\setinterfacevariable{yes}{ja} +% definitions for interface constants for language nl +% +\setinterfaceconstant{action}{actie} +\setinterfaceconstant{address}{adres} +\setinterfaceconstant{after}{na} +\setinterfaceconstant{afterhead}{kopna} +\setinterfaceconstant{afterkey}{natoets} +\setinterfaceconstant{align}{uitlijnen} +\setinterfaceconstant{aligncharacter}{karakteruitlijnen} +\setinterfaceconstant{alignmentcharacter}{uitlijnkarakter} +\setinterfaceconstant{alignsymbol}{alignsymbol} +\setinterfaceconstant{aligntitle}{titeluitlijnen} +\setinterfaceconstant{alternative}{variant} +\setinterfaceconstant{andtext}{andtext} +\setinterfaceconstant{apa}{apa} +\setinterfaceconstant{arrow}{pijl} +\setinterfaceconstant{artauthor}{artauthor} +\setinterfaceconstant{artauthoretaldisplay}{artauthoretaldisplay} +\setinterfaceconstant{artauthoretallimit}{artauthoretallimit} +\setinterfaceconstant{artauthoretaltext}{artauthoretaltext} +\setinterfaceconstant{at}{op} +\setinterfaceconstant{author}{auteur} +\setinterfaceconstant{authoretaldisplay}{authoretaldisplay} +\setinterfaceconstant{authoretallimit}{authoretallimit} +\setinterfaceconstant{authoretaltext}{authoretaltext} +\setinterfaceconstant{auto}{auto} +\setinterfaceconstant{autofile}{autofile} +\setinterfaceconstant{autofocus}{autofocus} +\setinterfaceconstant{autohang}{autohang} +\setinterfaceconstant{autostrut}{autostrut} +\setinterfaceconstant{autowidth}{autobreedte} +\setinterfaceconstant{axis}{assenstelsel} +\setinterfaceconstant{background}{achtergrond} +\setinterfaceconstant{backgroundcolor}{achtergrondkleur} +\setinterfaceconstant{backgroundcorner}{achtergrondhoek} +\setinterfaceconstant{backgrounddepth}{achtergronddiepte} +\setinterfaceconstant{backgroundoffset}{achtergrondoffset} +\setinterfaceconstant{backgroundradius}{achtergrondstraal} +\setinterfaceconstant{backgroundscreen}{achtergrondraster} +\setinterfaceconstant{backspace}{rugwit} +\setinterfaceconstant{balance}{balanceren} +\setinterfaceconstant{before}{voor} +\setinterfaceconstant{beforehead}{kopvoor} +\setinterfaceconstant{bet}{bet} +\setinterfaceconstant{big}{groot} +\setinterfaceconstant{blank}{blanko} +\setinterfaceconstant{blockway}{blokwijze} +\setinterfaceconstant{bodyfont}{korps} +\setinterfaceconstant{bookmark}{bookmark} +\setinterfaceconstant{bottom}{onder} +\setinterfaceconstant{bottomafter}{bottomafter} +\setinterfaceconstant{bottombefore}{bottombefore} +\setinterfaceconstant{bottomdistance}{onderafstand} +\setinterfaceconstant{bottomframe}{onderkader} +\setinterfaceconstant{bottomoffset}{onderoffset} +\setinterfaceconstant{bottomspace}{bodemwit} +\setinterfaceconstant{bottomstate}{onderstatus} +\setinterfaceconstant{cache}{cache} +\setinterfaceconstant{calculate}{bereken} +\setinterfaceconstant{ccommand}{ccommando} +\setinterfaceconstant{click}{klik} +\setinterfaceconstant{clickin}{klikin} +\setinterfaceconstant{clickout}{klikuit} +\setinterfaceconstant{clipoffset}{clipoffset} +\setinterfaceconstant{closeaction}{sluitactie} +\setinterfaceconstant{closecommand}{sluitcommando} +\setinterfaceconstant{closepageaction}{sluitpaginaactie} +\setinterfaceconstant{closesymbol}{sluitsymbool} +\setinterfaceconstant{color}{kleur} +\setinterfaceconstant{column}{kolom} +\setinterfaceconstant{columndistance}{kolomafstand} +\setinterfaceconstant{columns}{kolommen} +\setinterfaceconstant{command}{commando} +\setinterfaceconstant{commandafter}{nacommando} +\setinterfaceconstant{commandbefore}{voorcommando} +\setinterfaceconstant{commands}{commandos} +\setinterfaceconstant{component}{component} +\setinterfaceconstant{compoundhyphen}{koppelteken} +\setinterfaceconstant{compress}{comprimeren} +\setinterfaceconstant{connector}{connector} +\setinterfaceconstant{continue}{doorgaan} +\setinterfaceconstant{contrastcolor}{contrastkleur} +\setinterfaceconstant{controls}{sturing} +\setinterfaceconstant{conversion}{conversie} +\setinterfaceconstant{convertfile}{converteerfile} +\setinterfaceconstant{corner}{hoek} +\setinterfaceconstant{coupling}{koppeling} +\setinterfaceconstant{couplingway}{koppelwijze} +\setinterfaceconstant{criterium}{criterium} +\setinterfaceconstant{current}{huidige} +\setinterfaceconstant{cutspace}{snijwit} +\setinterfaceconstant{dash}{streep} +\setinterfaceconstant{dat}{dat} +\setinterfaceconstant{database}{database} +\setinterfaceconstant{date}{datum} +\setinterfaceconstant{deepnumbercommand}{diepnummercommando} +\setinterfaceconstant{deeptextcommand}{dieptekstcommando} +\setinterfaceconstant{default}{default} +\setinterfaceconstant{delay}{wachttijd} +\setinterfaceconstant{depth}{diepte} +\setinterfaceconstant{depthcorrection}{dieptecorrectie} +\setinterfaceconstant{direction}{richting} +\setinterfaceconstant{directory}{gebied} +\setinterfaceconstant{display}{scherm} +\setinterfaceconstant{distance}{afstand} +\setinterfaceconstant{dot}{punt} +\setinterfaceconstant{doublesided}{dubbelzijdig} +\setinterfaceconstant{dummy}{dummy} +\setinterfaceconstant{dx}{dx} +\setinterfaceconstant{dy}{dy} +\setinterfaceconstant{edge}{rand} +\setinterfaceconstant{edgedistance}{randafstand} +\setinterfaceconstant{editor}{editor} +\setinterfaceconstant{editoretaldisplay}{editoretaldisplay} +\setinterfaceconstant{editoretallimit}{editoretallimit} +\setinterfaceconstant{editoretaltext}{editoretaltext} +\setinterfaceconstant{empty}{leeg} +\setinterfaceconstant{equalheight}{equalheight} +\setinterfaceconstant{equalwidth}{equalwidth} +\setinterfaceconstant{escape}{escape} +\setinterfaceconstant{evenmargin}{evenmarge} +\setinterfaceconstant{expansion}{expansie} +\setinterfaceconstant{export}{exporteer} +\setinterfaceconstant{extras}{extras} +\setinterfaceconstant{factor}{factor} +\setinterfaceconstant{fallback}{terugval} +\setinterfaceconstant{family}{soort} +\setinterfaceconstant{fieldbackgroundcolor}{veldachtergrondkleur} +\setinterfaceconstant{fieldframecolor}{veldkaderkleur} +\setinterfaceconstant{fieldlayer}{veldlaag} +\setinterfaceconstant{fieldoffset}{veldoffset} +\setinterfaceconstant{file}{file} +\setinterfaceconstant{filtercommand}{filtercommand} +\setinterfaceconstant{finalnamesep}{finalnamesep} +\setinterfaceconstant{firstnamesep}{firstnamesep} +\setinterfaceconstant{focus}{focus} +\setinterfaceconstant{focusin}{focusin} +\setinterfaceconstant{focusout}{focusuit} +\setinterfaceconstant{footer}{voet} +\setinterfaceconstant{footerdistance}{voetafstand} +\setinterfaceconstant{footerstate}{voetstatus} +\setinterfaceconstant{foregroundcolor}{voorgrondkleur} +\setinterfaceconstant{foregroundstyle}{voorgrondletter} +\setinterfaceconstant{format}{formatteer} +\setinterfaceconstant{frame}{kader} +\setinterfaceconstant{framecolor}{kaderkleur} +\setinterfaceconstant{framecorner}{kaderhoek} +\setinterfaceconstant{framedepth}{kaderdiepte} +\setinterfaceconstant{frameoffset}{kaderoffset} +\setinterfaceconstant{frameradius}{kaderstraal} +\setinterfaceconstant{frames}{hokjes} +\setinterfaceconstant{from}{van} +\setinterfaceconstant{get}{haal} +\setinterfaceconstant{global}{globaal} +\setinterfaceconstant{grid}{grid} +\setinterfaceconstant{hang}{hang} +\setinterfaceconstant{headalign}{kopuitlijnen} +\setinterfaceconstant{headcolor}{kopkleur} +\setinterfaceconstant{headcommand}{kopcommando} +\setinterfaceconstant{headconversion}{kopconversie} +\setinterfaceconstant{header}{hoofd} +\setinterfaceconstant{headerdistance}{hoofdafstand} +\setinterfaceconstant{headerstate}{hoofdstatus} +\setinterfaceconstant{headlabel}{koplabel} +\setinterfaceconstant{headnumber}{kopnummer} +\setinterfaceconstant{headstyle}{kopletter} +\setinterfaceconstant{height}{hoogte} +\setinterfaceconstant{hfactor}{hfactor} +\setinterfaceconstant{hfil}{hfil} +\setinterfaceconstant{hidenumber}{hidenumber} +\setinterfaceconstant{hoffset}{hoffset} +\setinterfaceconstant{horoffset}{rugoffset} +\setinterfaceconstant{hyphen}{hyphen} +\setinterfaceconstant{icommand}{icommando} +\setinterfaceconstant{in}{in} +\setinterfaceconstant{inbetween}{tussen} +\setinterfaceconstant{increment}{verhoog} +\setinterfaceconstant{incrementnumber}{verhoognummer} +\setinterfaceconstant{indenting}{inspringen} +\setinterfaceconstant{indentnext}{springvolgendein} +\setinterfaceconstant{indicator}{aanduiding} +\setinterfaceconstant{inner}{binnen} +\setinterfaceconstant{innermargin}{binnenmarge} +\setinterfaceconstant{inputfile}{inputfile} +\setinterfaceconstant{intent}{intent} +\setinterfaceconstant{interaction}{interactie} +\setinterfaceconstant{interlinespace}{interlinie} +\setinterfaceconstant{itemalign}{itemuitlijnen} +\setinterfaceconstant{items}{items} +\setinterfaceconstant{juniorsep}{juniorsep} +\setinterfaceconstant{ken}{ken} +\setinterfaceconstant{keyexpansion}{sleutelexpansie} +\setinterfaceconstant{keyword}{trefwoord} +\setinterfaceconstant{label}{label} +\setinterfaceconstant{lastnamesep}{lastnamesep} +\setinterfaceconstant{lastpubsep}{lastpubsep} +\setinterfaceconstant{left}{links} +\setinterfaceconstant{leftcolor}{linkerkleur} +\setinterfaceconstant{leftcompoundhyphen}{linkerkoppelteken} +\setinterfaceconstant{leftedge}{linkerrand} +\setinterfaceconstant{leftedgedistance}{linkerrandafstand} +\setinterfaceconstant{leftframe}{linkerkader} +\setinterfaceconstant{lefthyphen}{lefthyphen} +\setinterfaceconstant{leftmargin}{linkermarge} +\setinterfaceconstant{leftmargindistance}{linkermargeafstand} +\setinterfaceconstant{leftoffset}{linkeroffset} +\setinterfaceconstant{leftquotation}{linkercitaat} +\setinterfaceconstant{leftquote}{linkerciteer} +\setinterfaceconstant{leftsentence}{linkerzin} +\setinterfaceconstant{leftspeech}{linkeruitspraak} +\setinterfaceconstant{leftstyle}{linkerletter} +\setinterfaceconstant{leftsubsentence}{linkersubzin} +\setinterfaceconstant{lefttext}{linkertekst} +\setinterfaceconstant{leftwidth}{linkerbreedte} +\setinterfaceconstant{level}{niveau} +\setinterfaceconstant{levels}{niveaus} +\setinterfaceconstant{limittext}{limiettekst} +\setinterfaceconstant{line}{regel} +\setinterfaceconstant{linecorrection}{regelcorrectie} +\setinterfaceconstant{lines}{regels} +\setinterfaceconstant{list}{lijst} +\setinterfaceconstant{listtext}{lijsttekst} +\setinterfaceconstant{local}{lokaal} +\setinterfaceconstant{location}{plaats} +\setinterfaceconstant{logo}{logo} +\setinterfaceconstant{logos}{logos} +\setinterfaceconstant{marcolor}{markleur} +\setinterfaceconstant{margin}{marge} +\setinterfaceconstant{margindistance}{margeafstand} +\setinterfaceconstant{marginedge}{kantlijn} +\setinterfaceconstant{marginedgetext}{kantlijntekst} +\setinterfaceconstant{margintext}{margetekst} +\setinterfaceconstant{marking}{markering} +\setinterfaceconstant{marstyle}{marletter} +\setinterfaceconstant{max}{max} +\setinterfaceconstant{maxdepth}{maxdepth} +\setinterfaceconstant{maxheight}{maxhoogte} +\setinterfaceconstant{maxwidth}{maxbreedte} +\setinterfaceconstant{maybeyear}{maybeyear} +\setinterfaceconstant{menu}{menu} +\setinterfaceconstant{method}{methode} +\setinterfaceconstant{middle}{midden} +\setinterfaceconstant{middlespeech}{middenuitspraak} +\setinterfaceconstant{middletext}{middentekst} +\setinterfaceconstant{midsentence}{middenzin} +\setinterfaceconstant{min}{min} +\setinterfaceconstant{mindepth}{mindiepte} +\setinterfaceconstant{minheight}{minhoogte} +\setinterfaceconstant{minwidth}{minbreedte} +\setinterfaceconstant{monthconversion}{maandconversie} +\setinterfaceconstant{n}{n} +\setinterfaceconstant{name}{naam} +\setinterfaceconstant{namesep}{namesep} +\setinterfaceconstant{nbottom}{nonder} +\setinterfaceconstant{nc}{nc} +\setinterfaceconstant{next}{volgende} +\setinterfaceconstant{nl}{nl} +\setinterfaceconstant{nleft}{nlinks} +\setinterfaceconstant{nlines}{nregels} +\setinterfaceconstant{norm}{norm} +\setinterfaceconstant{nr}{nr} +\setinterfaceconstant{nright}{nrechts} +\setinterfaceconstant{ntop}{nboven} +\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{numberstarter}{numberstarter} +\setinterfaceconstant{numberstopper}{numberstopper} +\setinterfaceconstant{numberstyle}{nummerletter} +\setinterfaceconstant{numberwidth}{nummerbreedte} +\setinterfaceconstant{nx}{nx} +\setinterfaceconstant{ny}{ny} +\setinterfaceconstant{object}{object} +\setinterfaceconstant{obstruction}{blokkade} +\setinterfaceconstant{oddmargin}{onevenmarge} +\setinterfaceconstant{offset}{offset} +\setinterfaceconstant{openaction}{openactie} +\setinterfaceconstant{openpageaction}{openpaginaactie} +\setinterfaceconstant{option}{optie} +\setinterfaceconstant{order}{order} +\setinterfaceconstant{orientation}{orientatie} +\setinterfaceconstant{otherstext}{otherstext} +\setinterfaceconstant{outermargin}{buitenmarge} +\setinterfaceconstant{overprint}{overprint} +\setinterfaceconstant{ownnumber}{eigennummer} +\setinterfaceconstant{page}{pagina} +\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{pageprefixstarter}{pageprefixstarter} +\setinterfaceconstant{pageprefixstopper}{pageprefixstopper} +\setinterfaceconstant{pagesegments}{pagesegments} +\setinterfaceconstant{pageseparatorset}{pageseparatorset} +\setinterfaceconstant{pageset}{pageset} +\setinterfaceconstant{pagestarter}{pagestarter} +\setinterfaceconstant{pagestate}{paginastatus} +\setinterfaceconstant{pagestopper}{pagestopper} +\setinterfaceconstant{pagestyle}{paginaletter} +\setinterfaceconstant{palet}{palet} +\setinterfaceconstant{paper}{papier} +\setinterfaceconstant{paragraph}{alinea} +\setinterfaceconstant{place}{plaatsen} +\setinterfaceconstant{placehead}{plaatskop} +\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{prefixstarter}{prefixstarter} +\setinterfaceconstant{prefixstopper}{prefixstopper} +\setinterfaceconstant{preset}{preset} +\setinterfaceconstant{preview}{preview} +\setinterfaceconstant{previous}{vorige} +\setinterfaceconstant{previousnumber}{vorigenummer} +\setinterfaceconstant{process}{proces} +\setinterfaceconstant{pubsep}{pubsep} +\setinterfaceconstant{radius}{straal} +\setinterfaceconstant{random}{willekeur} +\setinterfaceconstant{range}{bereik} +\setinterfaceconstant{reduction}{reductie} +\setinterfaceconstant{ref}{ref} +\setinterfaceconstant{refcommand}{refcommand} +\setinterfaceconstant{reference}{verwijzing} +\setinterfaceconstant{referenceprefix}{referenceprefix} +\setinterfaceconstant{referencing}{refereren} +\setinterfaceconstant{regionin}{gebiedin} +\setinterfaceconstant{regionout}{gebieduit} +\setinterfaceconstant{repeat}{herhaal} +\setinterfaceconstant{reset}{reset} +\setinterfaceconstant{resetnumber}{resetnummer} +\setinterfaceconstant{resolution}{resolutie} +\setinterfaceconstant{right}{rechts} +\setinterfaceconstant{rightcolor}{rechterkleur} +\setinterfaceconstant{rightcompoundhyphen}{rechterkoppelteken} +\setinterfaceconstant{rightedge}{rechterrand} +\setinterfaceconstant{rightedgedistance}{rechterrandafstand} +\setinterfaceconstant{rightframe}{rechterkader} +\setinterfaceconstant{righthyphen}{righthyphen} +\setinterfaceconstant{rightmargin}{rechtermarge} +\setinterfaceconstant{rightmargindistance}{rechtermargeafstand} +\setinterfaceconstant{rightoffset}{rechteroffset} +\setinterfaceconstant{rightquotation}{rechtercitaat} +\setinterfaceconstant{rightquote}{rechterciteer} +\setinterfaceconstant{rightsentence}{rechterzin} +\setinterfaceconstant{rightspeech}{rechteruitspraak} +\setinterfaceconstant{rightstyle}{rechterletter} +\setinterfaceconstant{rightsubsentence}{rechtersubzin} +\setinterfaceconstant{righttext}{rechtertekst} +\setinterfaceconstant{rightwidth}{rechterbreedte} +\setinterfaceconstant{rotation}{rotatie} +\setinterfaceconstant{rule}{lijn} +\setinterfaceconstant{rulecolor}{lijnkleur} +\setinterfaceconstant{rulethickness}{lijndikte} +\setinterfaceconstant{samepage}{zelfdepagina} +\setinterfaceconstant{sample}{monster} +\setinterfaceconstant{samplesize}{samplesize} +\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{sectionresetset}{sectionresetset} +\setinterfaceconstant{sectionsegments}{sectionsegments} +\setinterfaceconstant{sectionseparatorset}{sectionseparatorset} +\setinterfaceconstant{sectionset}{sectionset} +\setinterfaceconstant{sectionstarter}{sectionstarter} +\setinterfaceconstant{sectionstopper}{sectionstopper} +\setinterfaceconstant{separator}{scheider} +\setinterfaceconstant{set}{set} +\setinterfaceconstant{setups}{setups} +\setinterfaceconstant{side}{zij} +\setinterfaceconstant{sidealign}{zijuitlijnen} +\setinterfaceconstant{sidemethod}{zijmethode} +\setinterfaceconstant{sidespaceafter}{zijnawit} +\setinterfaceconstant{sidespacebefore}{zijvoorwit} +\setinterfaceconstant{sign}{teken} +\setinterfaceconstant{size}{formaat} +\setinterfaceconstant{small}{klein} +\setinterfaceconstant{sort}{sort} +\setinterfaceconstant{sorttype}{sortering} +\setinterfaceconstant{source}{bron} +\setinterfaceconstant{space}{spatie} +\setinterfaceconstant{spaceafter}{nawit} +\setinterfaceconstant{spacebefore}{voorwit} +\setinterfaceconstant{spaceinbetween}{tussenwit} +\setinterfaceconstant{spacing}{spatiering} +\setinterfaceconstant{split}{splitsen} +\setinterfaceconstant{splitcolor}{splitskleur} +\setinterfaceconstant{splitmethod}{splitsmethode} +\setinterfaceconstant{splitoffset}{splitsoffset} +\setinterfaceconstant{spot}{spot} +\setinterfaceconstant{stack}{stapel} +\setinterfaceconstant{start}{start} +\setinterfaceconstant{starter}{opener} +\setinterfaceconstant{state}{status} +\setinterfaceconstant{step}{stap} +\setinterfaceconstant{stop}{stop} +\setinterfaceconstant{stopper}{afsluiter} +\setinterfaceconstant{stretch}{rek} +\setinterfaceconstant{strip}{strip} +\setinterfaceconstant{strut}{strut} +\setinterfaceconstant{style}{letter} +\setinterfaceconstant{sub}{sub} +\setinterfaceconstant{subtitle}{subtitel} +\setinterfaceconstant{suffix}{suffix} +\setinterfaceconstant{surnamesep}{surnamesep} +\setinterfaceconstant{sx}{sx} +\setinterfaceconstant{sy}{sy} +\setinterfaceconstant{symalign}{symuitlijnen} +\setinterfaceconstant{symbol}{symbool} +\setinterfaceconstant{symbolset}{symboolset} +\setinterfaceconstant{symcolor}{symkleur} +\setinterfaceconstant{symstyle}{symletter} +\setinterfaceconstant{synonym}{synoniem} +\setinterfaceconstant{synonymcolor}{synoniemkleur} +\setinterfaceconstant{synonymcommand}{synoniemcommando} +\setinterfaceconstant{synonymstyle}{synoniemletter} +\setinterfaceconstant{tab}{tab} +\setinterfaceconstant{text}{tekst} +\setinterfaceconstant{textcolor}{tekstkleur} +\setinterfaceconstant{textcommand}{tekstcommando} +\setinterfaceconstant{textdistance}{tekstafstand} +\setinterfaceconstant{textlayer}{tekstlaag} +\setinterfaceconstant{textmargin}{tekstmarge} +\setinterfaceconstant{textmethod}{tekstmethode} +\setinterfaceconstant{textseparator}{tekstscheider} +\setinterfaceconstant{textsize}{tekstformaat} +\setinterfaceconstant{textstate}{tekststatus} +\setinterfaceconstant{textstyle}{tekstletter} +\setinterfaceconstant{textwidth}{tekstbreedte} +\setinterfaceconstant{title}{titel} +\setinterfaceconstant{titlecolor}{titelkleur} +\setinterfaceconstant{titlecommand}{titelcommando} +\setinterfaceconstant{titledistance}{titelafstand} +\setinterfaceconstant{titleleft}{titellinks} +\setinterfaceconstant{titleright}{titelrechts} +\setinterfaceconstant{titlestyle}{titelletter} +\setinterfaceconstant{to}{aan} +\setinterfaceconstant{tolerance}{tolerantie} +\setinterfaceconstant{top}{boven} +\setinterfaceconstant{topdistance}{bovenafstand} +\setinterfaceconstant{topframe}{bovenkader} +\setinterfaceconstant{topoffset}{bovenoffset} +\setinterfaceconstant{topspace}{kopwit} +\setinterfaceconstant{topstate}{bovenstatus} +\setinterfaceconstant{totalnumber}{totalnumber} +\setinterfaceconstant{type}{type} +\setinterfaceconstant{unit}{eenheid} +\setinterfaceconstant{unknownreference}{onbekendeverwijzing} +\setinterfaceconstant{urlalternative}{urlvariant} +\setinterfaceconstant{urlspace}{urlspatie} +\setinterfaceconstant{validate}{valideer} +\setinterfaceconstant{vcommand}{vcommando} +\setinterfaceconstant{veroffset}{kopoffset} +\setinterfaceconstant{vfil}{vfil} +\setinterfaceconstant{voffset}{voffset} +\setinterfaceconstant{vonsep}{vonsep} +\setinterfaceconstant{way}{wijze} +\setinterfaceconstant{wfactor}{bfactor} +\setinterfaceconstant{white}{wit} +\setinterfaceconstant{width}{breedte} +\setinterfaceconstant{xfactor}{xfactor} +\setinterfaceconstant{xmax}{xmax} +\setinterfaceconstant{xoffset}{xoffset} +\setinterfaceconstant{xscale}{xschaal} +\setinterfaceconstant{xstep}{xstap} +\setinterfaceconstant{yfactor}{yfactor} +\setinterfaceconstant{ymax}{ymax} +\setinterfaceconstant{yoffset}{yoffset} +\setinterfaceconstant{yscale}{yschaal} +\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} +\setinterfaceelement{currentlocal}{huidigelokale} +\setinterfaceelement{emptyone}{leeg} +\setinterfaceelement{emptytwo}{lege} +\setinterfaceelement{end}{eindvan} +\setinterfaceelement{endsetup}{in} +\setinterfaceelement{get}{haal} +\setinterfaceelement{increment}{verhoog} +\setinterfaceelement{list}{lijst} +\setinterfaceelement{listof}{lijstmet} +\setinterfaceelement{load}{laad} +\setinterfaceelement{local}{lokale} +\setinterfaceelement{makeup}{opmaak} +\setinterfaceelement{next}{volgende} +\setinterfaceelement{place}{plaats} +\setinterfaceelement{previous}{vorige} +\setinterfaceelement{previouslocal}{vorigelokale} +\setinterfaceelement{reserve}{reserveer} +\setinterfaceelement{see}{zie} +\setinterfaceelement{setup}{stel} +\setinterfaceelement{start}{start} +\setinterfaceelement{stop}{stop} +\setinterfaceelement{text}{tekst} +\setinterfaceelement{type}{type} +% definitions for interface commands for language nl +% +\setinterfacecommand{CAPPED}{KAP} +\setinterfacecommand{Character}{Letter} +\setinterfacecommand{Characters}{Letters} +\setinterfacecommand{LABELTEXT}{LABELTEKST} +\setinterfacecommand{MONTH}{MAAND} +\setinterfacecommand{Numbers}{Cijfers} +\setinterfacecommand{Romannumerals}{Romeins} +\setinterfacecommand{SmallCapped}{Kap} +\setinterfacecommand{SmallCaps}{Kaps} +\setinterfacecommand{WEEKDAY}{WEEKDAG} +\setinterfacecommand{WORD}{WOORD} +\setinterfacecommand{WORDS}{WOORDEN} +\setinterfacecommand{Word}{Woord} +\setinterfacecommand{Words}{Woorden} +\setinterfacecommand{about}{about} +\setinterfacecommand{adaptlayout}{paslayoutaan} +\setinterfacecommand{arg}{arg} +\setinterfacecommand{at}{op} +\setinterfacecommand{atleftmargin}{oplinkermarge} +\setinterfacecommand{atpage}{oppagina} +\setinterfacecommand{atrightmargin}{oprechtermarge} +\setinterfacecommand{background}{achtergrond} +\setinterfacecommand{backspace}{rugwit} +\setinterfacecommand{blackrule}{blokje} +\setinterfacecommand{blackrules}{blokjes} +\setinterfacecommand{blank}{blanko} +\setinterfacecommand{bookmark}{bookmark} +\setinterfacecommand{bottomdistance}{onderafstand} +\setinterfacecommand{bottomheight}{onderhoogte} +\setinterfacecommand{bottomspace}{bodemwit} +\setinterfacecommand{but}{but} +\setinterfacecommand{button}{button} +\setinterfacecommand{bypassblocks}{passeerblokken} +\setinterfacecommand{character}{letter} +\setinterfacecommand{characters}{letters} +\setinterfacecommand{chem}{chem} +\setinterfacecommand{clip}{clip} +\setinterfacecommand{clonefield}{kloonveld} +\setinterfacecommand{color}{kleur} +\setinterfacecommand{colorbar}{kleurenbalk} +\setinterfacecommand{colorvalue}{kleurwaarde} +\setinterfacecommand{column}{kolom} +\setinterfacecommand{comment}{commentaar} +\setinterfacecommand{comparecolorgroup}{vergelijkkleurgroep} +\setinterfacecommand{comparepalet}{vergelijkpalet} +\setinterfacecommand{completepagenumber}{volledigepaginanummer} +\setinterfacecommand{completeregister}{volledigregister} +\setinterfacecommand{component}{onderdeel} +\setinterfacecommand{convertnumber}{converteernummer} +\setinterfacecommand{copyfield}{copieerveld} +\setinterfacecommand{correctwhitespace}{corrigeerwitruimte} +\setinterfacecommand{coupledocument}{koppeldocument} +\setinterfacecommand{couplemarking}{koppelmarkering} +\setinterfacecommand{couplepage}{koppelpagina} +\setinterfacecommand{couplepaper}{koppelpapier} +\setinterfacecommand{coupleregister}{koppelregister} +\setinterfacecommand{crlf}{crlf} +\setinterfacecommand{currentdate}{huidigedatum} +\setinterfacecommand{currentheadnumber}{huidigekopnummer} +\setinterfacecommand{cutspace}{snijwit} +\setinterfacecommand{date}{datum} +\setinterfacecommand{decouplemarking}{ontkoppelmarkering} +\setinterfacecommand{decrementnumber}{verlaagnummer} +\setinterfacecommand{define}{definieer} +\setinterfacecommand{defineaccent}{definieeraccent} +\setinterfacecommand{defineblank}{definieerblanko} +\setinterfacecommand{defineblock}{definieerblok} +\setinterfacecommand{definebodyfont}{definieerkorps} +\setinterfacecommand{definebodyfontenvironment}{definieerkorpsomgeving} +\setinterfacecommand{definebuffer}{definieerbuffer} +\setinterfacecommand{definecharacter}{definieerkarakter} +\setinterfacecommand{definecolor}{definieerkleur} +\setinterfacecommand{definecolorgroup}{definieerkleurgroep} +\setinterfacecommand{definecolumnbreak}{definieerkolomovergang} +\setinterfacecommand{definecolumnset}{definieerkolomgroep} +\setinterfacecommand{definecombination}{definieercombinatie} +\setinterfacecommand{definecombinedlist}{definieersamengesteldelijst} +\setinterfacecommand{definecommand}{definieercommando} +\setinterfacecommand{defineconversion}{definieerconversie} +\setinterfacecommand{definedescription}{doordefinieren} +\setinterfacecommand{defineenumeration}{doornummeren} +\setinterfacecommand{definefield}{definieerveld} +\setinterfacecommand{definefieldstack}{definieerveldstapel} +\setinterfacecommand{definefiguresymbol}{definieerfiguursymbool} +\setinterfacecommand{definefloat}{definieerplaatsblok} +\setinterfacecommand{definefont}{definieerfont} +\setinterfacecommand{definefontstyle}{definieerfontstijl} +\setinterfacecommand{definefontsynonym}{definieerfontsynoniem} +\setinterfacecommand{defineframed}{definieeromlijnd} +\setinterfacecommand{defineframedtext}{definieerkadertekst} +\setinterfacecommand{definehbox}{definieerhbox} +\setinterfacecommand{definehead}{definieerkop} +\setinterfacecommand{defineindenting}{doorspringen} +\setinterfacecommand{defineinmargin}{definieerinmarge} +\setinterfacecommand{defineinteractionmenu}{definieerinteractiemenu} +\setinterfacecommand{defineitemgroup}{definieeritemgroep} +\setinterfacecommand{definelabel}{doorlabelen} +\setinterfacecommand{definelayer}{definieerlayer} +\setinterfacecommand{definelayout}{definieerlayout} +\setinterfacecommand{definelist}{definieerlijst} +\setinterfacecommand{definelogo}{definieerbeeldmerk} +\setinterfacecommand{definemainfield}{definieerhoofdveld} +\setinterfacecommand{definemakeup}{definieeropmaak} +\setinterfacecommand{definemarking}{definieermarkering} +\setinterfacecommand{definemathalignment}{definieerwiskundeuitlijnen} +\setinterfacecommand{defineoutput}{definieeruitvoer} +\setinterfacecommand{defineoverlay}{definieeroverlay} +\setinterfacecommand{definepagebreak}{definieerpaginaovergang} +\setinterfacecommand{definepalet}{definieerpalet} +\setinterfacecommand{definepapersize}{definieerpapierformaat} +\setinterfacecommand{defineparagraphs}{definieeralineas} +\setinterfacecommand{defineplacement}{definieerplaats} +\setinterfacecommand{defineprofile}{definieerprofiel} +\setinterfacecommand{defineprogram}{definieerprogramma} +\setinterfacecommand{definerawfont}{definerawfont} +\setinterfacecommand{definereference}{definieerreferentie} +\setinterfacecommand{definereferenceformat}{definieerreferentieformaat} +\setinterfacecommand{definereferencelist}{definieerreferentielijst} +\setinterfacecommand{defineregister}{definieerregister} +\setinterfacecommand{definerule}{definieerlijn} +\setinterfacecommand{definesection}{definieersectie} +\setinterfacecommand{definesectionblock}{definieersectieblok} +\setinterfacecommand{definesorting}{definieersorteren} +\setinterfacecommand{definestartstop}{definieerstartstop} +\setinterfacecommand{definestyle}{definieerletter} +\setinterfacecommand{definesubfield}{definieersubveld} +\setinterfacecommand{definesymbol}{definieersymbool} +\setinterfacecommand{definesynonyms}{definieersynoniemen} +\setinterfacecommand{definetabletemplate}{definieertabelvorm} +\setinterfacecommand{definetabulate}{definieertabulatie} +\setinterfacecommand{definetext}{definieertekst} +\setinterfacecommand{definetextposition}{definieertekstpositie} +\setinterfacecommand{definetextvariable}{definieertekstvariabele} +\setinterfacecommand{definetype}{definieertype} +\setinterfacecommand{definetyping}{definieertypen} +\setinterfacecommand{defineversion}{definieerversie} +\setinterfacecommand{determineheadnumber}{bepaalkopnummer} +\setinterfacecommand{determinelistcharacteristics}{bepaallijstkenmerken} +\setinterfacecommand{determineregistercharacteristics}{bepaalregisterkenmerken} +\setinterfacecommand{dimension}{dimensie} +\setinterfacecommand{disableinteractionmenu}{blokkeerinteractiemenu} +\setinterfacecommand{domicile}{woonplaats} +\setinterfacecommand{donttest}{geentest} +\setinterfacecommand{edgedistance}{randafstand} +\setinterfacecommand{edgewidth}{randbreedte} +\setinterfacecommand{emptylines}{legeregels} +\setinterfacecommand{environment}{omgeving} +\setinterfacecommand{externalfigure}{externfiguur} +\setinterfacecommand{fact}{geg} +\setinterfacecommand{field}{veld} +\setinterfacecommand{fieldstack}{veldstapel} +\setinterfacecommand{fillinfield}{invulveld} +\setinterfacecommand{fillinline}{invulregel} +\setinterfacecommand{fillinrules}{invullijnen} +\setinterfacecommand{fillintext}{invultekst} +\setinterfacecommand{fitfield}{passendveld} +\setinterfacecommand{fixedspace}{vastespatie} +\setinterfacecommand{fixedspaces}{vastespaties} +\setinterfacecommand{followprofile}{volgprofiel} +\setinterfacecommand{followprofileversion}{volgprofielversie} +\setinterfacecommand{followversion}{volgversie} +\setinterfacecommand{footerdistance}{voetafstand} +\setinterfacecommand{footerheight}{voethoogte} +\setinterfacecommand{footnote}{voetnoot} +\setinterfacecommand{footnotetext}{voetnoottekst} +\setinterfacecommand{forceblocks}{forceerblokken} +\setinterfacecommand{formulanumber}{formulenummer} +\setinterfacecommand{fraction}{breuk} +\setinterfacecommand{framed}{omlijnd} +\setinterfacecommand{from}{uit} +\setinterfacecommand{getbuffer}{haalbuffer} +\setinterfacecommand{getmarking}{haalmarkering} +\setinterfacecommand{getnumber}{haalnummer} +\setinterfacecommand{godown}{omlaag} +\setinterfacecommand{goto}{naar} +\setinterfacecommand{gotobox}{naarbox} +\setinterfacecommand{gotopage}{naarpagina} +\setinterfacecommand{graycolor}{grijskleur} +\setinterfacecommand{greyvalue}{grijswaarde} +\setinterfacecommand{grid}{rooster} +\setinterfacecommand{hairline}{haarlijn} +\setinterfacecommand{head}{kop} +\setinterfacecommand{headerdistance}{hoofdafstand} +\setinterfacecommand{headerheight}{hoofdhoogte} +\setinterfacecommand{headlevel}{kopniveau} +\setinterfacecommand{headnumber}{kopnummer} +\setinterfacecommand{headsym}{kopsym} +\setinterfacecommand{headtext}{koptekst} +\setinterfacecommand{hideblocks}{verbergblokken} +\setinterfacecommand{high}{hoog} +\setinterfacecommand{hl}{hl} +\setinterfacecommand{immediatebetweenlist}{directtussenlijst} +\setinterfacecommand{immediatetolist}{directnaarlijst} +\setinterfacecommand{in}{in} +\setinterfacecommand{incrementnumber}{verhoognummer} +\setinterfacecommand{indenting}{inspringen} +\setinterfacecommand{inframed}{inlijnd} +\setinterfacecommand{infull}{voluit} +\setinterfacecommand{ininner}{inbinnen} +\setinterfacecommand{inleft}{inlinker} +\setinterfacecommand{inleftedge}{inlinkerrand} +\setinterfacecommand{inleftmargin}{inlinkermarge} +\setinterfacecommand{inline}{inregel} +\setinterfacecommand{inmargin}{inmarge} +\setinterfacecommand{inmframed}{inwilijnd} +\setinterfacecommand{inneredgedistance}{binnenrandafstand} +\setinterfacecommand{inneredgewidth}{binnenrandbreedte} +\setinterfacecommand{innermargindistance}{binnenmargeafstand} +\setinterfacecommand{innermarginwidth}{binnenmargebreedte} +\setinterfacecommand{inothermargin}{inanderemarge} +\setinterfacecommand{inouter}{inbuiten} +\setinterfacecommand{inright}{inrechter} +\setinterfacecommand{inrightedge}{inrechterrand} +\setinterfacecommand{inrightmargin}{inrechtermarge} +\setinterfacecommand{installlanguage}{installeertaal} +\setinterfacecommand{interactionbar}{interactiebalk} +\setinterfacecommand{interactionbuttons}{interactiebuttons} +\setinterfacecommand{interactionmenu}{interactiemenu} +\setinterfacecommand{item}{som} +\setinterfacecommand{items}{items} +\setinterfacecommand{its}{its} +\setinterfacecommand{keepblocks}{handhaafblokken} +\setinterfacecommand{label}{label} +\setinterfacecommand{labels}{labels} +\setinterfacecommand{labeltext}{labeltekst} +\setinterfacecommand{language}{taal} +\setinterfacecommand{leftaligned}{regellinks} +\setinterfacecommand{leftedgedistance}{linkerrandafstand} +\setinterfacecommand{leftedgewidth}{linkerrandbreedte} +\setinterfacecommand{leftmargindistance}{linkermargeafstand} +\setinterfacecommand{leftmarginwidth}{linkermargebreedte} +\setinterfacecommand{leg}{leg} +\setinterfacecommand{linewidth}{lijndikte} +\setinterfacecommand{listheight}{lijsthoogte} +\setinterfacecommand{listlength}{lijstlengte} +\setinterfacecommand{listsymbol}{lijstsymbool} +\setinterfacecommand{listwidth}{lijstbreedte} +\setinterfacecommand{logfields}{registreervelden} +\setinterfacecommand{lohi}{laho} +\setinterfacecommand{low}{laag} +\setinterfacecommand{macroname}{naam} +\setinterfacecommand{mainlanguage}{hoofdtaal} +\setinterfacecommand{makeupheight}{zethoogte} +\setinterfacecommand{makeupwidth}{zetbreedte} +\setinterfacecommand{mar}{mar} +\setinterfacecommand{margindistance}{margeafstand} +\setinterfacecommand{marginrule}{kantlijn} +\setinterfacecommand{margintext}{margetekst} +\setinterfacecommand{margintitle}{margetitel} +\setinterfacecommand{marginwidth}{margebreedte} +\setinterfacecommand{marginword}{margewoord} +\setinterfacecommand{marking}{markeer} +\setinterfacecommand{markversion}{markeerversie} +\setinterfacecommand{mathematics}{wiskunde} +\setinterfacecommand{menubutton}{menubutton} +\setinterfacecommand{mframed}{wilijnd} +\setinterfacecommand{midaligned}{regelmidden} +\setinterfacecommand{mirror}{spiegel} +\setinterfacecommand{month}{maand} +\setinterfacecommand{moveformula}{verplaatsformule} +\setinterfacecommand{moveongrid}{verplaatsopgrid} +\setinterfacecommand{movesidefloat}{verplaatszijblok} +\setinterfacecommand{navigating}{navigerend} +\setinterfacecommand{nodimension}{geendimensie} +\setinterfacecommand{noheaderandfooterlines}{geenhoofdenvoetregels} +\setinterfacecommand{noindenting}{nietinspringen} +\setinterfacecommand{nolist}{geenlijst} +\setinterfacecommand{nomarking}{geenmarkering} +\setinterfacecommand{nomoreblocks}{geenblokkenmeer} +\setinterfacecommand{nomorefiles}{geenfilesmeer} +\setinterfacecommand{nop}{nop} +\setinterfacecommand{nospace}{geenspatie} +\setinterfacecommand{note}{noot} +\setinterfacecommand{notopandbottomlines}{geenbovenenonderregels} +\setinterfacecommand{notsmallcapped}{nokap} +\setinterfacecommand{nowhitespace}{geenwitruimte} +\setinterfacecommand{numberofsubpages}{aantalsubpaginas} +\setinterfacecommand{numbers}{cijfers} +\setinterfacecommand{outeredgedistance}{buitenrandafstand} +\setinterfacecommand{outeredgewidth}{buitenrandbreedte} +\setinterfacecommand{outermargindistance}{buitenmargeafstand} +\setinterfacecommand{outermarginwidth}{buitenmargebreedte} +\setinterfacecommand{packed}{opelkaar} +\setinterfacecommand{page}{pagina} +\setinterfacecommand{pagedepth}{paginadiepte} +\setinterfacecommand{pagenumber}{paginanummer} +\setinterfacecommand{pageoffset}{paginaoffset} +\setinterfacecommand{pagereference}{paginareferentie} +\setinterfacecommand{pagetype}{soortpagina} +\setinterfacecommand{paperheight}{papierhoogte} +\setinterfacecommand{paperwidth}{papierbreedte} +\setinterfacecommand{periods}{punten} +\setinterfacecommand{plaatsruwelijst}{plaatsruwelijst} +\setinterfacecommand{placebookmarks}{plaatsbookmarks} +\setinterfacecommand{placecombinedlist}{plaatssamengesteldelijst} +\setinterfacecommand{placefloat}{plaatsplaatsblok} +\setinterfacecommand{placefootnotes}{plaatsvoetnoten} +\setinterfacecommand{placeformula}{plaatsformule} +\setinterfacecommand{placeheadnumber}{plaatskopnummer} +\setinterfacecommand{placeheadtext}{plaatskoptekst} +\setinterfacecommand{placelegend}{plaatslegenda} +\setinterfacecommand{placelist}{plaatslijst} +\setinterfacecommand{placelocalfootnotes}{plaatslokalevoetnoten} +\setinterfacecommand{placelogos}{plaatsbeeldmerken} +\setinterfacecommand{placeongrid}{plaatsopgrid} +\setinterfacecommand{placeontopofeachother}{plaatsonderelkaar} +\setinterfacecommand{placepagenumber}{plaatspaginanummer} +\setinterfacecommand{placereferencelist}{plaatsreferentielijst} +\setinterfacecommand{placeregister}{plaatsregister} +\setinterfacecommand{placerule}{plaatslijn} +\setinterfacecommand{placesidebyside}{plaatsnaastelkaar} +\setinterfacecommand{placesubformula}{plaatssubformule} +\setinterfacecommand{placetextvariable}{plaatstekstvariabele} +\setinterfacecommand{position}{positioneer} +\setinterfacecommand{positiontext}{positioneertekst} +\setinterfacecommand{printpaperheight}{printpapierhoogte} +\setinterfacecommand{printpaperwidth}{printpapierbreedte} +\setinterfacecommand{processblocks}{verwerkblokken} +\setinterfacecommand{processpage}{verwerkpagina} +\setinterfacecommand{product}{produkt} +\setinterfacecommand{program}{programma} +\setinterfacecommand{project}{projekt} +\setinterfacecommand{publication}{publicatie} +\setinterfacecommand{quotation}{citaat} +\setinterfacecommand{quote}{citeer} +\setinterfacecommand{ran}{ran} +\setinterfacecommand{redo}{herhaal} +\setinterfacecommand{ref}{ref} +\setinterfacecommand{reference}{referentie} +\setinterfacecommand{referral}{kenmerk} +\setinterfacecommand{referraldate}{kenmerkdatum} +\setinterfacecommand{referring}{refereer} +\setinterfacecommand{remark}{toelichting} +\setinterfacecommand{reset}{reset} +\setinterfacecommand{resetmarking}{resetmarkering} +\setinterfacecommand{resetnumber}{resetnummer} +\setinterfacecommand{resettext}{resettekstinhoud} +\setinterfacecommand{rightaligned}{regelrechts} +\setinterfacecommand{rightedgedistance}{rechterrandafstand} +\setinterfacecommand{rightedgewidth}{rechterrandbreedte} +\setinterfacecommand{rightmargindistance}{rechtermargeafstand} +\setinterfacecommand{rightmarginwidth}{rechtermargebreedte} +\setinterfacecommand{romannumerals}{romeins} +\setinterfacecommand{rotate}{roteer} +\setinterfacecommand{scale}{schaal} +\setinterfacecommand{screen}{scherm} +\setinterfacecommand{selectblocks}{selecteerblokken} +\setinterfacecommand{selectpaper}{selecteerpapier} +\setinterfacecommand{selectversion}{selecteerversie} +\setinterfacecommand{setnumber}{setnummer} +\setinterfacecommand{settextcontent}{steltekstinhoudin} +\setinterfacecommand{settextvariable}{kentekstvariabeletoe} +\setinterfacecommand{setupalign}{steluitlijnenin} +\setinterfacecommand{setupanswerarea}{stelantwoordgebiedin} +\setinterfacecommand{setuparranging}{stelarrangerenin} +\setinterfacecommand{setupbackground}{stelachtergrondin} +\setinterfacecommand{setupbackgrounds}{stelachtergrondenin} +\setinterfacecommand{setupblackrules}{stelblokjesin} +\setinterfacecommand{setupblank}{stelblankoin} +\setinterfacecommand{setupblock}{stelblokin} +\setinterfacecommand{setupbodyfont}{stelkorpsin} +\setinterfacecommand{setupbodyfontenvironment}{stelkorpsomgevingin} +\setinterfacecommand{setupbottom}{stelonderin} +\setinterfacecommand{setupbottomtexts}{stelondertekstenin} +\setinterfacecommand{setupbuffer}{stelbufferin} +\setinterfacecommand{setupbuttons}{stelbuttonsin} +\setinterfacecommand{setupcapitals}{stelkapitalenin} +\setinterfacecommand{setupcaption}{stelblokkopjein} +\setinterfacecommand{setupcaptions}{stelblokkopjesin} +\setinterfacecommand{setupclipping}{stelclipin} +\setinterfacecommand{setupcolor}{stelkleurin} +\setinterfacecommand{setupcolors}{stelkleurenin} +\setinterfacecommand{setupcolumns}{stelkolommenin} +\setinterfacecommand{setupcolumnset}{stelkolomgroepin} +\setinterfacecommand{setupcolumnsetlines}{stelkolomgroepregelsin} +\setinterfacecommand{setupcolumnsetstart}{stelkolomgroepstartin} +\setinterfacecommand{setupcombinations}{stelcombinatiesin} +\setinterfacecommand{setupcombinedlist}{stelsamengesteldelijstin} +\setinterfacecommand{setupcomment}{stelcommentaarin} +\setinterfacecommand{setupdescriptions}{steldoordefinierenin} +\setinterfacecommand{setupenumerations}{steldoornummerenin} +\setinterfacecommand{setupexternalfigures}{stelexternefigurenin} +\setinterfacecommand{setupfield}{stelveldin} +\setinterfacecommand{setupfields}{stelveldenin} +\setinterfacecommand{setupfillinlines}{stelinvulregelsin} +\setinterfacecommand{setupfillinrules}{stelinvullijnenin} +\setinterfacecommand{setupfloat}{stelplaatsblokin} +\setinterfacecommand{setupfloats}{stelplaatsblokkenin} +\setinterfacecommand{setupfloatsplitting}{stelplaatsbloksplitsenin} +\setinterfacecommand{setupfooter}{stelvoetin} +\setinterfacecommand{setupfootertexts}{stelvoettekstenin} +\setinterfacecommand{setupfootnotedefinition}{stelvoetnootdefinitiein} +\setinterfacecommand{setupfootnotes}{stelvoetnotenin} +\setinterfacecommand{setupforms}{stelformulierenin} +\setinterfacecommand{setupformulas}{stelformulesin} +\setinterfacecommand{setupframed}{stelomlijndin} +\setinterfacecommand{setupframedtexts}{stelkadertekstenin} +\setinterfacecommand{setuphead}{stelkopin} +\setinterfacecommand{setupheader}{stelhoofdin} +\setinterfacecommand{setupheadertexts}{stelhoofdtekstenin} +\setinterfacecommand{setupheadnumber}{stelkopnummerin} +\setinterfacecommand{setupheads}{stelkoppenin} +\setinterfacecommand{setupheadtext}{stelkoptekstin} +\setinterfacecommand{setuphyphenmark}{stelkoppeltekenin} +\setinterfacecommand{setupindentations}{steldoorspringenin} +\setinterfacecommand{setupindenting}{stelinspringenin} +\setinterfacecommand{setupinmargin}{stelinmargein} +\setinterfacecommand{setupinteraction}{stelinteractiein} +\setinterfacecommand{setupinteractionbar}{stelinteractiebalkin} +\setinterfacecommand{setupinteractionmenu}{stelinteractiemenuin} +\setinterfacecommand{setupinteractionscreen}{stelinteractieschermin} +\setinterfacecommand{setupinterlinespace}{stelinterliniein} +\setinterfacecommand{setupitemgroup}{stelitemgroepin} +\setinterfacecommand{setupitemgroups}{stelopsommingenin} +\setinterfacecommand{setupitems}{stelitemsin} +\setinterfacecommand{setuplabeltext}{stellabeltekstin} +\setinterfacecommand{setuplanguage}{steltaalin} +\setinterfacecommand{setuplayout}{stellayoutin} +\setinterfacecommand{setuplegend}{stellegendain} +\setinterfacecommand{setuplinenumbering}{stelregelnummerenin} +\setinterfacecommand{setuplines}{stelregelsin} +\setinterfacecommand{setuplinewidth}{stellijndiktein} +\setinterfacecommand{setuplist}{stellijstin} +\setinterfacecommand{setupmakeup}{stelopmaakin} +\setinterfacecommand{setupmarginblocks}{stelmargeblokkenin} +\setinterfacecommand{setupmarginrules}{stelkantlijnin} +\setinterfacecommand{setupmarking}{stelmarkeringin} +\setinterfacecommand{setupmathalignment}{stelwiskundeuitlijnenin} +\setinterfacecommand{setupnarrower}{stelsmallerin} +\setinterfacecommand{setupnumber}{stelnummerin} +\setinterfacecommand{setupnumbering}{stelnummerenin} +\setinterfacecommand{setupoppositeplacing}{stelnaastplaatsenin} +\setinterfacecommand{setupoutput}{steluitvoerin} +\setinterfacecommand{setuppagecomment}{stelpaginacommentaarin} +\setinterfacecommand{setuppagenumber}{stelpaginanummerin} +\setinterfacecommand{setuppagenumbering}{stelpaginanummeringin} +\setinterfacecommand{setuppagetransitions}{stelpaginaovergangenin} +\setinterfacecommand{setuppalet}{stelpaletin} +\setinterfacecommand{setuppaper}{stelpapierin} +\setinterfacecommand{setuppapersize}{stelpapierformaatin} +\setinterfacecommand{setupparagraphnumbering}{stelparagraafnummerenin} +\setinterfacecommand{setupparagraphs}{stelalineasin} +\setinterfacecommand{setupplacement}{stelplaatsin} +\setinterfacecommand{setuppositioning}{stelpositionerenin} +\setinterfacecommand{setupprofiles}{stelprofielenin} +\setinterfacecommand{setupprograms}{stelprogrammasin} +\setinterfacecommand{setuppublications}{stelpublicatiesin} +\setinterfacecommand{setupquote}{stelciterenin} +\setinterfacecommand{setupreferencelist}{stelreferentielijstin} +\setinterfacecommand{setupreferencing}{stelrefererenin} +\setinterfacecommand{setupregister}{stelregisterin} +\setinterfacecommand{setuprotate}{stelroterenin} +\setinterfacecommand{setuprule}{stellijnin} +\setinterfacecommand{setups}{instellingen} +\setinterfacecommand{setupscreens}{stelrastersin} +\setinterfacecommand{setupsection}{stelsectiein} +\setinterfacecommand{setupsectionblock}{stelsectieblokin} +\setinterfacecommand{setupsorting}{stelsorterenin} +\setinterfacecommand{setupspacing}{stelspatieringin} +\setinterfacecommand{setupstartstop}{stelstartstopin} +\setinterfacecommand{setupstrut}{stelstrutin} +\setinterfacecommand{setupsubpagenumber}{stelsubpaginanummerin} +\setinterfacecommand{setupsymbolset}{stelsymboolsetin} +\setinterfacecommand{setupsynchronization}{stelsynchronisatiein} +\setinterfacecommand{setupsynchronizationbar}{stelsynchronisatiebalkin} +\setinterfacecommand{setupsynonyms}{stelsynoniemenin} +\setinterfacecommand{setupsystem}{stelsysteemin} +\setinterfacecommand{setuptab}{steltabin} +\setinterfacecommand{setuptables}{steltabellenin} +\setinterfacecommand{setuptabulate}{steltabulatiein} +\setinterfacecommand{setuptext}{steltekstin} +\setinterfacecommand{setuptextposition}{steltekstpositiein} +\setinterfacecommand{setuptextrules}{steltekstlijnenin} +\setinterfacecommand{setuptexttexts}{stelteksttekstenin} +\setinterfacecommand{setuptextvariable}{steltekstvariabelein} +\setinterfacecommand{setupthinrules}{steldunnelijnenin} +\setinterfacecommand{setuptolerance}{steltolerantiein} +\setinterfacecommand{setuptop}{stelbovenin} +\setinterfacecommand{setuptoptexts}{stelboventekstenin} +\setinterfacecommand{setuptype}{steltypein} +\setinterfacecommand{setuptyping}{steltypenin} +\setinterfacecommand{setupunderbar}{stelonderstrepenin} +\setinterfacecommand{setupurl}{stelurlin} +\setinterfacecommand{setupversions}{stelversiesin} +\setinterfacecommand{setupwhitespace}{stelwitruimtein} +\setinterfacecommand{showbodyfont}{toonkorps} +\setinterfacecommand{showbodyfontenvironment}{toonkorpsomgeving} +\setinterfacecommand{showcolor}{toonkleur} +\setinterfacecommand{showcolorgroup}{toonkleurgroep} +\setinterfacecommand{showexternalfigures}{toonexternefiguren} +\setinterfacecommand{showfields}{toonvelden} +\setinterfacecommand{showframe}{toonkader} +\setinterfacecommand{showgrid}{toongrid} +\setinterfacecommand{showlayout}{toonlayout} +\setinterfacecommand{showmakeup}{toonopmaak} +\setinterfacecommand{showpalet}{toonpalet} +\setinterfacecommand{showprint}{toonprint} +\setinterfacecommand{showsetups}{tooninstellingen} +\setinterfacecommand{showstruts}{toonstruts} +\setinterfacecommand{showsymbolset}{toonsymboolset} +\setinterfacecommand{smallcapped}{kap} +\setinterfacecommand{someline}{eenregel} +\setinterfacecommand{somewhere}{ergens} +\setinterfacecommand{space}{spatie} +\setinterfacecommand{splitfloat}{splitsplaatsblok} +\setinterfacecommand{startalignment}{startuitlijnen} +\setinterfacecommand{startbackground}{startachtergrond} +\setinterfacecommand{startcoding}{startcodering} +\setinterfacecommand{startcolor}{startkleur} +\setinterfacecommand{startcolumnmakeup}{startkolomopmaak} +\setinterfacecommand{startcolumns}{startkolommen} +\setinterfacecommand{startcolumnset}{startkolomgroep} +\setinterfacecommand{startcombination}{startcombinatie} +\setinterfacecommand{startcomponent}{startonderdeel} +\setinterfacecommand{startdocument}{startdocument} +\setinterfacecommand{startenvironment}{startomgeving} +\setinterfacecommand{startfigure}{startfiguur} +\setinterfacecommand{startglobal}{startglobaal} +\setinterfacecommand{startline}{startregel} +\setinterfacecommand{startlinecorrection}{startregelcorrectie} +\setinterfacecommand{startlinenumbering}{startregelnummeren} +\setinterfacecommand{startlines}{startregels} +\setinterfacecommand{startlocal}{startlokaal} +\setinterfacecommand{startlocalfootnotes}{startlokalevoetnoten} +\setinterfacecommand{startmakeup}{startopmaak} +\setinterfacecommand{startmarginblock}{startmargeblok} +\setinterfacecommand{startmarginrule}{startkantlijn} +\setinterfacecommand{startnarrower}{startsmaller} +\setinterfacecommand{startopposite}{startnaast} +\setinterfacecommand{startoverlay}{startoverlay} +\setinterfacecommand{startoverzicht}{startoverzicht} +\setinterfacecommand{startpacked}{startopelkaar} +\setinterfacecommand{startpositioning}{startpositioneren} +\setinterfacecommand{startproduct}{startprodukt} +\setinterfacecommand{startprofile}{startprofiel} +\setinterfacecommand{startproject}{startprojekt} +\setinterfacecommand{startquotation}{startcitaat} +\setinterfacecommand{startraster}{startraster} +\setinterfacecommand{startsymbolset}{startsymboolset} +\setinterfacecommand{startsynchronization}{startsynchronisatie} +\setinterfacecommand{starttable}{starttabel} +\setinterfacecommand{starttables}{starttabellen} +\setinterfacecommand{starttext}{starttekst} +\setinterfacecommand{starttextrule}{starttekstlijn} +\setinterfacecommand{startunpacked}{startvanelkaar} +\setinterfacecommand{startversion}{startversie} +\setinterfacecommand{stopalignment}{stopuitlijnen} +\setinterfacecommand{stopbackground}{stopachtergrond} +\setinterfacecommand{stopcoding}{stopcodering} +\setinterfacecommand{stopcolor}{stopkleur} +\setinterfacecommand{stopcolumnmakeup}{stopkolomopmaak} +\setinterfacecommand{stopcolumns}{stopkolommen} +\setinterfacecommand{stopcolumnset}{stopkolomgroep} +\setinterfacecommand{stopcombination}{stopcombinatie} +\setinterfacecommand{stopcomponent}{stoponderdeel} +\setinterfacecommand{stopdocument}{stopdocument} +\setinterfacecommand{stopenvironment}{stopomgeving} +\setinterfacecommand{stopglobal}{stopglobaal} +\setinterfacecommand{stopline}{stopregel} +\setinterfacecommand{stoplinecorrection}{stopregelcorrectie} +\setinterfacecommand{stoplinenumbering}{stopregelnummeren} +\setinterfacecommand{stoplines}{stopregels} +\setinterfacecommand{stoplocal}{stoplokaal} +\setinterfacecommand{stoplocalfootnotes}{stoplokalevoetnoten} +\setinterfacecommand{stopmakeup}{stopopmaak} +\setinterfacecommand{stopmarginblock}{stopmargeblok} +\setinterfacecommand{stopmarginrule}{stopkantlijn} +\setinterfacecommand{stopnarrower}{stopsmaller} +\setinterfacecommand{stopopposite}{stopnaast} +\setinterfacecommand{stopoverlay}{stopoverlay} +\setinterfacecommand{stopoverzicht}{stopoverzicht} +\setinterfacecommand{stoppacked}{stopopelkaar} +\setinterfacecommand{stoppositioning}{stoppositioneren} +\setinterfacecommand{stopproduct}{stopprodukt} +\setinterfacecommand{stopprofile}{stopprofiel} +\setinterfacecommand{stopproject}{stopprojekt} +\setinterfacecommand{stopquotation}{stopcitaat} +\setinterfacecommand{stopraster}{stopraster} +\setinterfacecommand{stopsynchronization}{stopsynchronisatie} +\setinterfacecommand{stoptable}{stoptabel} +\setinterfacecommand{stoptables}{stoptabellen} +\setinterfacecommand{stoptext}{stoptekst} +\setinterfacecommand{stoptextrule}{stoptekstlijn} +\setinterfacecommand{stopunpacked}{stopvanelkaar} +\setinterfacecommand{stopversion}{stopversie} +\setinterfacecommand{stretched}{uitgerekt} +\setinterfacecommand{subformulanumber}{subformulenummer} +\setinterfacecommand{subpagenumber}{subpaginanummer} +\setinterfacecommand{switchtobodyfont}{switchnaarkorps} +\setinterfacecommand{switchtorawfont}{switchtorawfont} +\setinterfacecommand{sym}{sym} +\setinterfacecommand{symbol}{symbool} +\setinterfacecommand{synchronizationbar}{synchronisatiebalk} +\setinterfacecommand{synchronize}{synchroniseer} +\setinterfacecommand{tab}{tab} +\setinterfacecommand{testcolumn}{testkolom} +\setinterfacecommand{testpage}{testpagina} +\setinterfacecommand{tex}{tex} +\setinterfacecommand{textheight}{teksthoogte} +\setinterfacecommand{textreference}{tekstreferentie} +\setinterfacecommand{textrule}{tekstlijn} +\setinterfacecommand{textvariable}{tekstvariabele} +\setinterfacecommand{textwidth}{tekstbreedte} +\setinterfacecommand{thinrule}{dunnelijn} +\setinterfacecommand{thinrules}{dunnelijnen} +\setinterfacecommand{tooltip}{suggestie} +\setinterfacecommand{topdistance}{bovenafstand} +\setinterfacecommand{topheight}{bovenhoogte} +\setinterfacecommand{topspace}{kopwit} +\setinterfacecommand{totalnumberofpages}{totaalaantalpaginas} +\setinterfacecommand{translate}{vertaal} +\setinterfacecommand{txt}{txt} +\setinterfacecommand{typ}{typ} +\setinterfacecommand{type}{type} +\setinterfacecommand{typebuffer}{typebuffer} +\setinterfacecommand{typefile}{typefile} +\setinterfacecommand{unitmeaning}{betekenis} +\setinterfacecommand{unknown}{onbekend} +\setinterfacecommand{useJSscripts}{gebruikJSscripts} +\setinterfacecommand{useURL}{gebruikURL} +\setinterfacecommand{useXMLfilter}{gebruikXMLfilter} +\setinterfacecommand{useblocks}{gebruikblokken} +\setinterfacecommand{usecommands}{gebruikcommandos} +\setinterfacecommand{useencoding}{usecodering} +\setinterfacecommand{useexternaldocument}{gebruikexterndocument} +\setinterfacecommand{useexternalfigure}{gebruikexternfiguur} +\setinterfacecommand{useexternalfile}{gebruikexternefile} +\setinterfacecommand{useexternalfiles}{gebruikexternefiles} +\setinterfacecommand{useexternalsoundtrack}{gebruikexterngeluidsfragment} +\setinterfacecommand{usemodule}{gebruikmodule} +\setinterfacecommand{usemodules}{gebruikmodules} +\setinterfacecommand{usepath}{gebruikgebied} +\setinterfacecommand{usereferences}{gebruikreferenties} +\setinterfacecommand{usespecials}{gebruikspecials} +\setinterfacecommand{usesymbols}{gebruiksymbolen} +\setinterfacecommand{usetypescript}{gebruiktypescript} +\setinterfacecommand{usetypescriptfile}{gebruiktypescriptfile} +\setinterfacecommand{useurl}{gebruikurl} +\setinterfacecommand{version}{versie} +\setinterfacecommand{vl}{vl} +\setinterfacecommand{weekday}{weekdag} +\setinterfacecommand{whitespace}{witruimte} +\setinterfacecommand{wordright}{woordrechts} +\setinterfacecommand{writebetweenlist}{schrijftussenlijst} +\setinterfacecommand{writetolist}{schrijfnaarlijst} +\setinterfacecommand{writetoreferencelist}{schrijfnaarreferentielijst} +\setinterfacecommand{writetoregister}{schrijfnaarregister} +% +\endinput \ No newline at end of file diff --git a/tex/context/base/mult-ro.tex b/tex/context/base/mult-ro.tex new file mode 100644 index 000000000..738e49f72 --- /dev/null +++ b/tex/context/base/mult-ro.tex @@ -0,0 +1,1693 @@ +% this file is auto-generated, don't edit this file +% +% definitions for interface variables for language ro +% +\setinterfacevariable{Addition}{Adaugare} +\setinterfacevariable{Balloon}{Balon} +\setinterfacevariable{Character}{Caracter} +\setinterfacevariable{Characters}{Caractere} +\setinterfacevariable{CloseDocument}{InchideDocument} +\setinterfacevariable{ExitViewer}{IesireVizualizator} +\setinterfacevariable{FirstPage}{PrimaPagina} +\setinterfacevariable{FitHeight}{AjustatInaltime} +\setinterfacevariable{FitWidth}{AjustatLatime} +\setinterfacevariable{GotoPage}{LaPagina} +\setinterfacevariable{Greek}{Grec} +\setinterfacevariable{Help}{Ajutor} +\setinterfacevariable{HideField}{AscundeCamp} +\setinterfacevariable{HideLayer}{HideLayer} +\setinterfacevariable{Key}{Cheie} +\setinterfacevariable{LastPage}{UltimaPagina} +\setinterfacevariable{LoadForm}{IncarcaFormular} +\setinterfacevariable{MONTH}{LUNA} +\setinterfacevariable{New}{Nou} +\setinterfacevariable{NextJump}{SaltUrmator} +\setinterfacevariable{NextPage}{PaginaUrmatoare} +\setinterfacevariable{Numbers}{Numere} +\setinterfacevariable{OpenNamedDocument}{OpenNamedDocument} +\setinterfacevariable{Paragraph}{Paragraf} +\setinterfacevariable{PauseMovie}{PauzaFilm} +\setinterfacevariable{PauseRendering}{PauseRendering} +\setinterfacevariable{PauseSound}{PauzaSunet} +\setinterfacevariable{PreviousJump}{SaltPrecedent} +\setinterfacevariable{PreviousPage}{PaginaPrecedenta} +\setinterfacevariable{PrintDocument}{TiparesteDocument} +\setinterfacevariable{Query}{Query} +\setinterfacevariable{QueryAgain}{QueryAgain} +\setinterfacevariable{ResetForm}{ResetareFormular} +\setinterfacevariable{ResumeMovie}{RepornesteFilm} +\setinterfacevariable{ResumeRendering}{ResumeRendering} +\setinterfacevariable{ResumeSound}{RepornesteSunet} +\setinterfacevariable{Romannumerals}{Numereromane} +\setinterfacevariable{SaveDocument}{SalvareDocument} +\setinterfacevariable{SaveForm}{SalveazaFormular} +\setinterfacevariable{SaveNamedDocument}{SaveNamedDocument} +\setinterfacevariable{SearchAgain}{CautaDinNou} +\setinterfacevariable{SearchDocument}{CautaDocument} +\setinterfacevariable{ShowBookmarks}{ShowBookmarks} +\setinterfacevariable{ShowField}{AfiseazaCamp} +\setinterfacevariable{ShowThumbs}{ShowThumbs} +\setinterfacevariable{StartMovie}{StartFilm} +\setinterfacevariable{StartRendering}{StartRendering} +\setinterfacevariable{StartSound}{StartSunet} +\setinterfacevariable{StopMovie}{StopFilm} +\setinterfacevariable{StopRendering}{StopRendering} +\setinterfacevariable{StopSound}{StopSunet} +\setinterfacevariable{SubmitForm}{TrimiteFormular} +\setinterfacevariable{ToggleLayer}{ToggleLayer} +\setinterfacevariable{ToggleViewer}{SchimbaVizualizator} +\setinterfacevariable{URL}{URL} +\setinterfacevariable{VideLayer}{VideLayer} +\setinterfacevariable{ViewerHelp}{AjutorVizualizator} +\setinterfacevariable{WEEKDAY}{ZISAPTAMANA} +\setinterfacevariable{WORD}{CUVANT} +\setinterfacevariable{abbreviation}{abreviere} +\setinterfacevariable{abbreviations}{abrevieri} +\setinterfacevariable{absolute}{absolut} +\setinterfacevariable{action}{actiune} +\setinterfacevariable{after}{dupa} +\setinterfacevariable{all}{tot} +\setinterfacevariable{always}{totdeauna} +\setinterfacevariable{answerarea}{answerarea} +\setinterfacevariable{appendices}{apendixuri} +\setinterfacevariable{appendix}{apendix} +\setinterfacevariable{april}{aprilie} +\setinterfacevariable{atmargin}{lamargine} +\setinterfacevariable{atpage}{lapagina} +\setinterfacevariable{august}{august} +\setinterfacevariable{author}{autor} +\setinterfacevariable{auto}{auto} +\setinterfacevariable{autointro}{autointro} +\setinterfacevariable{back}{inapot} +\setinterfacevariable{background}{fundal} +\setinterfacevariable{backmatter}{epilogul} +\setinterfacevariable{backpart}{epilog} +\setinterfacevariable{backspace}{spatiuspate} +\setinterfacevariable{backward}{inapoi} +\setinterfacevariable{bbl}{bbl} +\setinterfacevariable{before}{inainte} +\setinterfacevariable{begin}{begin} +\setinterfacevariable{bib}{bib} +\setinterfacevariable{big}{mare} +\setinterfacevariable{bigbodyfont}{bigbodyfont} +\setinterfacevariable{bigpreference}{preferintamare} +\setinterfacevariable{blank}{blank} +\setinterfacevariable{blockquote}{blockquote} +\setinterfacevariable{bodymatter}{principalul} +\setinterfacevariable{bodypart}{principal} +\setinterfacevariable{bold}{aldin} +\setinterfacevariable{bolditalic}{aldinitalic} +\setinterfacevariable{boldslanted}{aldininclinat} +\setinterfacevariable{bookmark}{semncarte} +\setinterfacevariable{both}{ambele} +\setinterfacevariable{bottom}{subsol} +\setinterfacevariable{brief}{brief} +\setinterfacevariable{broad}{broad} +\setinterfacevariable{buffer}{buffer} +\setinterfacevariable{by}{de} +\setinterfacevariable{calligraphic}{caligrafic} +\setinterfacevariable{cap}{cap} +\setinterfacevariable{capital}{majuscula} +\setinterfacevariable{center}{center} +\setinterfacevariable{chapter}{capitol} +\setinterfacevariable{character}{caracter} +\setinterfacevariable{characters}{caractere} +\setinterfacevariable{cite}{cite} +\setinterfacevariable{color}{culoare} +\setinterfacevariable{column}{coloana} +\setinterfacevariable{columns}{coloane} +\setinterfacevariable{command}{comanda} +\setinterfacevariable{commands}{comenzi} +\setinterfacevariable{comment}{comentariu} +\setinterfacevariable{component}{componenta} +\setinterfacevariable{concept}{concept} +\setinterfacevariable{content}{cuprins} +\setinterfacevariable{contents}{cuprinsuri} +\setinterfacevariable{continue}{continuu} +\setinterfacevariable{controls}{controale} +\setinterfacevariable{conversion}{conversie} +\setinterfacevariable{current}{curent} +\setinterfacevariable{cutspace}{cutspace} +\setinterfacevariable{date}{data} +\setinterfacevariable{day}{zi} +\setinterfacevariable{december}{decembrie} +\setinterfacevariable{default}{implicit} +\setinterfacevariable{depth}{adancime} +\setinterfacevariable{description}{descriere} +\setinterfacevariable{disable}{dezactivat} +\setinterfacevariable{display}{display} +\setinterfacevariable{dot}{punct} +\setinterfacevariable{doublesided}{douafete} +\setinterfacevariable{down}{down} +\setinterfacevariable{each}{fiecare} +\setinterfacevariable{edge}{bordura} +\setinterfacevariable{empty}{gol} +\setinterfacevariable{end}{end} +\setinterfacevariable{endnote}{endnote} +\setinterfacevariable{enumeration}{enumerare} +\setinterfacevariable{environment}{mediu} +\setinterfacevariable{even}{par} +\setinterfacevariable{external}{extern} +\setinterfacevariable{fact}{fapt} +\setinterfacevariable{february}{februarie} +\setinterfacevariable{figure}{figura} +\setinterfacevariable{figures}{figure} +\setinterfacevariable{file}{fisier} +\setinterfacevariable{final}{final} +\setinterfacevariable{first}{primul} +\setinterfacevariable{firstcolumn}{firstcolumn} +\setinterfacevariable{firstpage}{primapagina} +\setinterfacevariable{firstsubpage}{primasubpagina} +\setinterfacevariable{fit}{ajustat} +\setinterfacevariable{five}{cinci} +\setinterfacevariable{fix}{fix} +\setinterfacevariable{fixed}{fixat} +\setinterfacevariable{flexible}{flexibil} +\setinterfacevariable{float}{obiectmobil} +\setinterfacevariable{flushinner}{flushinner} +\setinterfacevariable{flushleft}{flushleft} +\setinterfacevariable{flushouter}{flushouter} +\setinterfacevariable{flushright}{flushright} +\setinterfacevariable{footer}{subsol} +\setinterfacevariable{footnote}{notasubsol} +\setinterfacevariable{force}{fortat} +\setinterfacevariable{foreground}{primplan} +\setinterfacevariable{formeel}{formeel} +\setinterfacevariable{formula}{formula} +\setinterfacevariable{formulae}{formule} +\setinterfacevariable{forward}{avans} +\setinterfacevariable{four}{patru} +\setinterfacevariable{frame}{incadrat} +\setinterfacevariable{framedtext}{textinconjurat} +\setinterfacevariable{friday}{vineri} +\setinterfacevariable{frontmatter}{prologul} +\setinterfacevariable{frontpart}{prolog} +\setinterfacevariable{global}{global} +\setinterfacevariable{graphic}{graficul} +\setinterfacevariable{graphics}{graficele} +\setinterfacevariable{gray}{gri} +\setinterfacevariable{greek}{grec} +\setinterfacevariable{grid}{grila} +\setinterfacevariable{halfline}{jumatatelinie} +\setinterfacevariable{handwritten}{scrismanual} +\setinterfacevariable{hang}{suspenda} +\setinterfacevariable{hanging}{suspendat} +\setinterfacevariable{head}{antet} +\setinterfacevariable{header}{antet} +\setinterfacevariable{height}{inaltime} +\setinterfacevariable{helptext}{textajutator} +\setinterfacevariable{hencefore}{precedent} +\setinterfacevariable{here}{aici} +\setinterfacevariable{hereafter}{urmator} +\setinterfacevariable{hidden}{ascuns} +\setinterfacevariable{hiding}{ascundere} +\setinterfacevariable{high}{inalt} +\setinterfacevariable{horizontal}{orizontal} +\setinterfacevariable{hyphenated}{despsilabe} +\setinterfacevariable{hz}{hz} +\setinterfacevariable{inbetween}{intre} +\setinterfacevariable{index}{index} +\setinterfacevariable{indices}{indexuri} +\setinterfacevariable{informeel}{informeel} +\setinterfacevariable{inherit}{inherit} +\setinterfacevariable{inleft}{instanga} +\setinterfacevariable{inmargin}{inmargine} +\setinterfacevariable{inner}{intern} +\setinterfacevariable{inneredge}{inneredge} +\setinterfacevariable{innermargin}{innermargin} +\setinterfacevariable{inright}{indreapta} +\setinterfacevariable{interaction}{interactiune} +\setinterfacevariable{interactionmenu}{meniuinteractiune} +\setinterfacevariable{intermezzi}{intermezzi} +\setinterfacevariable{intermezzo}{intermezzo} +\setinterfacevariable{intext}{intext} +\setinterfacevariable{intro}{intro} +\setinterfacevariable{italic}{italic} +\setinterfacevariable{italicbold}{italicaldin} +\setinterfacevariable{item}{element} +\setinterfacevariable{itemize}{enumerare} +\setinterfacevariable{its}{propriu} +\setinterfacevariable{january}{ianuarie} +\setinterfacevariable{joinedup}{unit} +\setinterfacevariable{july}{iulie} +\setinterfacevariable{june}{iunie} +\setinterfacevariable{keep}{mentine} +\setinterfacevariable{knockout}{knockout} +\setinterfacevariable{label}{eticheta} +\setinterfacevariable{landscape}{vedere} +\setinterfacevariable{last}{ultim} +\setinterfacevariable{lastcolumn}{lastcolumn} +\setinterfacevariable{lastpage}{ultimapagina} +\setinterfacevariable{lastpagenumber}{lastpagenumber} +\setinterfacevariable{lastsubpage}{ultimasubpagina} +\setinterfacevariable{layer}{layer} +\setinterfacevariable{left}{stanga} +\setinterfacevariable{leftedge}{bordurastanga} +\setinterfacevariable{lefthanging}{lefthanging} +\setinterfacevariable{leftmargin}{marginestanga} +\setinterfacevariable{leftpage}{paginastanga} +\setinterfacevariable{lefttoright}{lefttoright} +\setinterfacevariable{legend}{legenda} +\setinterfacevariable{lesshyphenation}{lesshyphenation} +\setinterfacevariable{line}{linie} +\setinterfacevariable{linenote}{linenote} +\setinterfacevariable{lines}{linii} +\setinterfacevariable{list}{lista} +\setinterfacevariable{local}{local} +\setinterfacevariable{localenvironment}{mediulocal} +\setinterfacevariable{logo}{logo} +\setinterfacevariable{logos}{logos} +\setinterfacevariable{lohi}{lohi} +\setinterfacevariable{loose}{larg} +\setinterfacevariable{low}{jos} +\setinterfacevariable{ls}{ls} +\setinterfacevariable{makeup}{marcaj} +\setinterfacevariable{mar}{mar} +\setinterfacevariable{march}{martie} +\setinterfacevariable{margin}{margine} +\setinterfacevariable{marginedge}{marginebordura} +\setinterfacevariable{margintitle}{titlumarginal} +\setinterfacevariable{marking}{marcaje} +\setinterfacevariable{mathalignment}{mathalignment} +\setinterfacevariable{mathcases}{mathcases} +\setinterfacevariable{mathmatrix}{mathmatrix} +\setinterfacevariable{max}{max} +\setinterfacevariable{maxdepth}{maxdepth} +\setinterfacevariable{maxheight}{maxheight} +\setinterfacevariable{maxwidth}{maxwidth} +\setinterfacevariable{may}{mai} +\setinterfacevariable{mediaeval}{medieval} +\setinterfacevariable{medium}{mediu} +\setinterfacevariable{middle}{centru} +\setinterfacevariable{min}{min} +\setinterfacevariable{mindepth}{mindepth} +\setinterfacevariable{minheight}{inaltimeminima} +\setinterfacevariable{minwidth}{latimeminima} +\setinterfacevariable{mirrored}{oglindit} +\setinterfacevariable{monday}{luni} +\setinterfacevariable{mono}{mono} +\setinterfacevariable{month}{luna} +\setinterfacevariable{morehyphenation}{morehyphenation} +\setinterfacevariable{name}{nume} +\setinterfacevariable{narrow}{ingust} +\setinterfacevariable{negative}{negativ} +\setinterfacevariable{never}{niciodata} +\setinterfacevariable{new}{nou} +\setinterfacevariable{next}{urmatorul} +\setinterfacevariable{nextevenpage}{paginaparaurmatoarea} +\setinterfacevariable{nextoddpage}{paginaimparaurmatoarea} +\setinterfacevariable{nextpage}{paginaurmatoare} +\setinterfacevariable{nextsubpage}{urmatoareasubpagina} +\setinterfacevariable{no}{nu} +\setinterfacevariable{nocheck}{nocheck} +\setinterfacevariable{nofit}{nofit} +\setinterfacevariable{nogrid}{nogrid} +\setinterfacevariable{nohz}{nohz} +\setinterfacevariable{nomarking}{faramarcare} +\setinterfacevariable{none}{niciunul} +\setinterfacevariable{nonumber}{nonumber} +\setinterfacevariable{normal}{normal} +\setinterfacevariable{nospacing}{nospacing} +\setinterfacevariable{not}{nu} +\setinterfacevariable{note}{note} +\setinterfacevariable{nothanging}{nothanging} +\setinterfacevariable{nothyphenated}{nedespsilabe} +\setinterfacevariable{november}{noiembrie} +\setinterfacevariable{nowhere}{niciunde} +\setinterfacevariable{nowhite}{faraalb} +\setinterfacevariable{number}{numar} +\setinterfacevariable{numbers}{numere} +\setinterfacevariable{october}{octombrie} +\setinterfacevariable{odd}{impar} +\setinterfacevariable{off}{dezactivat} +\setinterfacevariable{offset}{offset} +\setinterfacevariable{old}{old} +\setinterfacevariable{on}{on} +\setinterfacevariable{one}{unu} +\setinterfacevariable{opposite}{opus} +\setinterfacevariable{outer}{extern} +\setinterfacevariable{outeredge}{outeredge} +\setinterfacevariable{outermargin}{outermargin} +\setinterfacevariable{overbar}{barasus} +\setinterfacevariable{overbars}{supralinie} +\setinterfacevariable{overlay}{overlay} +\setinterfacevariable{overprint}{overprint} +\setinterfacevariable{overstrike}{liniepeste} +\setinterfacevariable{overstrikes}{liniipeste} +\setinterfacevariable{packed}{impachetat} +\setinterfacevariable{page}{pagina} +\setinterfacevariable{pagecomment}{comentariupagina} +\setinterfacevariable{pagenumber}{numarpagina} +\setinterfacevariable{paper}{foaie} +\setinterfacevariable{paragraph}{paragraf} +\setinterfacevariable{part}{parte} +\setinterfacevariable{positive}{positiv} +\setinterfacevariable{postponing}{postponing} +\setinterfacevariable{postscript}{postscript} +\setinterfacevariable{preference}{preferinta} +\setinterfacevariable{preview}{previzualizare} +\setinterfacevariable{previous}{precedent} +\setinterfacevariable{previousevenpage}{paginaparaprecedenta} +\setinterfacevariable{previousoddpage}{paginaimparaprecedenta} +\setinterfacevariable{previouspage}{paginaanterioara} +\setinterfacevariable{previoussubpage}{subpaginaanterioara} +\setinterfacevariable{printable}{tiparibil} +\setinterfacevariable{process}{process} +\setinterfacevariable{product}{produs} +\setinterfacevariable{program}{program} +\setinterfacevariable{project}{proiect} +\setinterfacevariable{protected}{protejat} +\setinterfacevariable{quadruple}{cvadrupul} +\setinterfacevariable{quotation}{citat} +\setinterfacevariable{quote}{minicitat} +\setinterfacevariable{ran}{rulat} +\setinterfacevariable{random}{aleator} +\setinterfacevariable{readonly}{readonly} +\setinterfacevariable{rectangular}{rectangular} +\setinterfacevariable{referral}{referinta} +\setinterfacevariable{register}{registru} +\setinterfacevariable{regular}{regular} +\setinterfacevariable{rekening}{rekening} +\setinterfacevariable{relative}{relativ} +\setinterfacevariable{repeat}{repetat} +\setinterfacevariable{required}{obligatoriu} +\setinterfacevariable{reset}{reset} +\setinterfacevariable{reverse}{reverse} +\setinterfacevariable{right}{dreapta} +\setinterfacevariable{rightedge}{borduradreapta} +\setinterfacevariable{righthanging}{righthanging} +\setinterfacevariable{rightmargin}{marginedreapta} +\setinterfacevariable{rightpage}{paginadreapta} +\setinterfacevariable{righttoleft}{righttoleft} +\setinterfacevariable{roman}{roman} +\setinterfacevariable{romannumerals}{numereromane} +\setinterfacevariable{rotate}{rotit} +\setinterfacevariable{rotated}{rotat} +\setinterfacevariable{round}{rotund} +\setinterfacevariable{row}{rand} +\setinterfacevariable{rule}{rigla} +\setinterfacevariable{samepage}{aceeasipagina} +\setinterfacevariable{sans}{sans} +\setinterfacevariable{sansbold}{sansaldin} +\setinterfacevariable{sansserif}{sansserif} +\setinterfacevariable{saturday}{sambata} +\setinterfacevariable{screen}{ecran} +\setinterfacevariable{section}{sectiune} +\setinterfacevariable{sectionblockenvironment}{blocsectiuneambient} +\setinterfacevariable{sectionnumber}{numarsetiune} +\setinterfacevariable{see}{vezi} +\setinterfacevariable{september}{septembrie} +\setinterfacevariable{serif}{serif} +\setinterfacevariable{serried}{serried} +\setinterfacevariable{setups}{setari} +\setinterfacevariable{sheet}{sheet} +\setinterfacevariable{short}{short} +\setinterfacevariable{singlesided}{ofata} +\setinterfacevariable{slanted}{inclinat} +\setinterfacevariable{slantedbold}{inclinataldin} +\setinterfacevariable{small}{mic} +\setinterfacevariable{smallbodyfont}{smallbodyfont} +\setinterfacevariable{smallbold}{micaldin} +\setinterfacevariable{smallbolditalic}{micaldininclinat} +\setinterfacevariable{smallboldslanted}{micaldininclinat} +\setinterfacevariable{smallcaps}{majusculemici} +\setinterfacevariable{smallitalic}{micitalic} +\setinterfacevariable{smallitalicbold}{micitalicaldin} +\setinterfacevariable{smallnormal}{micnormal} +\setinterfacevariable{smallslanted}{micinclinat} +\setinterfacevariable{smallslantedbold}{micinclinataldin} +\setinterfacevariable{smalltype}{mictype} +\setinterfacevariable{somewhere}{undeva} +\setinterfacevariable{sorted}{sortat} +\setinterfacevariable{space}{spatiu} +\setinterfacevariable{spacing}{spatiere} +\setinterfacevariable{speech}{speech} +\setinterfacevariable{split}{split} +\setinterfacevariable{spot}{spot} +\setinterfacevariable{standard}{standard} +\setinterfacevariable{start}{start} +\setinterfacevariable{starter}{starter} +\setinterfacevariable{sticker}{sticker} +\setinterfacevariable{stop}{stop} +\setinterfacevariable{stopper}{stopper} +\setinterfacevariable{stretch}{dilatat} +\setinterfacevariable{strict}{strict} +\setinterfacevariable{strong}{strong} +\setinterfacevariable{strut}{strut} +\setinterfacevariable{sub}{sub} +\setinterfacevariable{subbackward}{subinapoi} +\setinterfacevariable{subformula}{subformula} +\setinterfacevariable{subforward}{subavans} +\setinterfacevariable{subject}{subiect} +\setinterfacevariable{subpage}{subpagina} +\setinterfacevariable{subsection}{subsectiune} +\setinterfacevariable{subsubject}{subsubiect} +\setinterfacevariable{subsubsection}{subsubsectiune} +\setinterfacevariable{subsubsubject}{subsubsubiect} +\setinterfacevariable{subsubsubsection}{subsubsubsectiune} +\setinterfacevariable{subsubsubsubject}{subsubsubsubiect} +\setinterfacevariable{subsubsubsubsection}{subsubsubsubsectiune} +\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} +\setinterfacevariable{symbol}{simbol} +\setinterfacevariable{synchronize}{synchronize} +\setinterfacevariable{system}{sistem} +\setinterfacevariable{table}{tabelul} +\setinterfacevariable{tablehead}{antettabel} +\setinterfacevariable{tables}{tabelele} +\setinterfacevariable{tabletail}{subsoltabel} +\setinterfacevariable{tabulate}{tabulate} +\setinterfacevariable{tabulatehead}{tabulatehead} +\setinterfacevariable{tabulatetail}{tabulatetail} +\setinterfacevariable{tall}{inalt} +\setinterfacevariable{teletype}{teletype} +\setinterfacevariable{temporary}{temporar} +\setinterfacevariable{test}{test} +\setinterfacevariable{text}{text} +\setinterfacevariable{three}{trei} +\setinterfacevariable{thursday}{joi} +\setinterfacevariable{title}{titlu} +\setinterfacevariable{toggle}{toggle} +\setinterfacevariable{tolerant}{tolerant} +\setinterfacevariable{top}{sus} +\setinterfacevariable{tuesday}{marti} +\setinterfacevariable{two}{doi} +\setinterfacevariable{txt}{txt} +\setinterfacevariable{type}{type} +\setinterfacevariable{typing}{typing} +\setinterfacevariable{unavailable}{nedisponibil} +\setinterfacevariable{underbar}{sublinie} +\setinterfacevariable{underbars}{sublinii} +\setinterfacevariable{unit}{unitate} +\setinterfacevariable{units}{unitati} +\setinterfacevariable{unknown}{necunoscut} +\setinterfacevariable{unpacked}{despachetat} +\setinterfacevariable{up}{up} +\setinterfacevariable{url}{url} +\setinterfacevariable{used}{folosit} +\setinterfacevariable{value}{valoare} +\setinterfacevariable{vertical}{vertical} +\setinterfacevariable{very}{foarte} +\setinterfacevariable{verystrict}{foartestrict} +\setinterfacevariable{verytolerant}{foartetolerant} +\setinterfacevariable{weak}{weak} +\setinterfacevariable{wednesday}{miercuri} +\setinterfacevariable{week}{saptamana} +\setinterfacevariable{weekday}{zisaptamana} +\setinterfacevariable{white}{alb} +\setinterfacevariable{wide}{larg} +\setinterfacevariable{width}{latime} +\setinterfacevariable{xml}{xml} +\setinterfacevariable{year}{an} +\setinterfacevariable{yes}{da} +% definitions for interface constants for language ro +% +\setinterfaceconstant{action}{actiune} +\setinterfaceconstant{address}{adresa} +\setinterfaceconstant{after}{dupa} +\setinterfaceconstant{afterhead}{dupatitlu} +\setinterfaceconstant{afterkey}{dupatasta} +\setinterfaceconstant{align}{aliniere} +\setinterfaceconstant{aligncharacter}{aliniazacaracter} +\setinterfaceconstant{alignmentcharacter}{alierecaracter} +\setinterfaceconstant{alignsymbol}{alignsymbol} +\setinterfaceconstant{aligntitle}{alinieretitlu} +\setinterfaceconstant{alternative}{alternativ} +\setinterfaceconstant{andtext}{andtext} +\setinterfaceconstant{apa}{apa} +\setinterfaceconstant{arrow}{sageata} +\setinterfaceconstant{artauthor}{artauthor} +\setinterfaceconstant{artauthoretaldisplay}{artauthoretaldisplay} +\setinterfaceconstant{artauthoretallimit}{artauthoretallimit} +\setinterfaceconstant{artauthoretaltext}{artauthoretaltext} +\setinterfaceconstant{at}{la} +\setinterfaceconstant{author}{autor} +\setinterfaceconstant{authoretaldisplay}{authoretaldisplay} +\setinterfaceconstant{authoretallimit}{authoretallimit} +\setinterfaceconstant{authoretaltext}{authoretaltext} +\setinterfaceconstant{auto}{auto} +\setinterfaceconstant{autofile}{autofile} +\setinterfaceconstant{autofocus}{autofocus} +\setinterfaceconstant{autohang}{autohang} +\setinterfaceconstant{autostrut}{autostrut} +\setinterfaceconstant{autowidth}{autolatime} +\setinterfaceconstant{axis}{axa} +\setinterfaceconstant{background}{fundal} +\setinterfaceconstant{backgroundcolor}{culoarefundal} +\setinterfaceconstant{backgroundcorner}{coltfundal} +\setinterfaceconstant{backgrounddepth}{adancimefundal} +\setinterfaceconstant{backgroundoffset}{offsetfundal} +\setinterfaceconstant{backgroundradius}{razafundal} +\setinterfaceconstant{backgroundscreen}{ecranfundal} +\setinterfaceconstant{backspace}{spatiuspate} +\setinterfaceconstant{balance}{balanta} +\setinterfaceconstant{before}{inainte} +\setinterfaceconstant{beforehead}{inaintetitlu} +\setinterfaceconstant{bet}{bet} +\setinterfaceconstant{big}{mare} +\setinterfaceconstant{blank}{blanc} +\setinterfaceconstant{blockway}{blockway} +\setinterfaceconstant{bodyfont}{fonttext} +\setinterfaceconstant{bookmark}{semncarte} +\setinterfaceconstant{bottom}{jos} +\setinterfaceconstant{bottomafter}{bottomafter} +\setinterfaceconstant{bottombefore}{bottombefore} +\setinterfaceconstant{bottomdistance}{distantajos} +\setinterfaceconstant{bottomframe}{framejos} +\setinterfaceconstant{bottomoffset}{offsetjos} +\setinterfaceconstant{bottomspace}{spatiujos} +\setinterfaceconstant{bottomstate}{starejos} +\setinterfaceconstant{cache}{cache} +\setinterfaceconstant{calculate}{calculeaza} +\setinterfaceconstant{ccommand}{comandac} +\setinterfaceconstant{click}{click} +\setinterfaceconstant{clickin}{clickintru} +\setinterfaceconstant{clickout}{clickies} +\setinterfaceconstant{clipoffset}{clipoffset} +\setinterfaceconstant{closeaction}{actiuneinchidere} +\setinterfaceconstant{closecommand}{closecommand} +\setinterfaceconstant{closepageaction}{actiuneinchiderepagina} +\setinterfaceconstant{closesymbol}{closesymbol} +\setinterfaceconstant{color}{culoare} +\setinterfaceconstant{column}{coloana} +\setinterfaceconstant{columndistance}{distantacoloane} +\setinterfaceconstant{columns}{coloane} +\setinterfaceconstant{command}{comanda} +\setinterfaceconstant{commandafter}{comandadupa} +\setinterfaceconstant{commandbefore}{comandainainte} +\setinterfaceconstant{commands}{comenzi} +\setinterfaceconstant{component}{component} +\setinterfaceconstant{compoundhyphen}{compoundhyphen} +\setinterfaceconstant{compress}{compress} +\setinterfaceconstant{connector}{connector} +\setinterfaceconstant{continue}{continua} +\setinterfaceconstant{contrastcolor}{culoarecontrast} +\setinterfaceconstant{controls}{controale} +\setinterfaceconstant{conversion}{conversie} +\setinterfaceconstant{convertfile}{convertestefisier} +\setinterfaceconstant{corner}{colt} +\setinterfaceconstant{coupling}{cuplare} +\setinterfaceconstant{couplingway}{modcuplare} +\setinterfaceconstant{criterium}{criteriu} +\setinterfaceconstant{current}{curent} +\setinterfaceconstant{cutspace}{cutspace} +\setinterfaceconstant{dash}{dash} +\setinterfaceconstant{dat}{dat} +\setinterfaceconstant{database}{database} +\setinterfaceconstant{date}{data} +\setinterfaceconstant{deepnumbercommand}{deepnumbercommand} +\setinterfaceconstant{deeptextcommand}{deeptextcommand} +\setinterfaceconstant{default}{implicit} +\setinterfaceconstant{delay}{intarziere} +\setinterfaceconstant{depth}{inaltime} +\setinterfaceconstant{depthcorrection}{corectieadancime} +\setinterfaceconstant{direction}{directie} +\setinterfaceconstant{directory}{director} +\setinterfaceconstant{display}{display} +\setinterfaceconstant{distance}{distanta} +\setinterfaceconstant{dot}{punct} +\setinterfaceconstant{doublesided}{douafete} +\setinterfaceconstant{dummy}{dummy} +\setinterfaceconstant{dx}{dx} +\setinterfaceconstant{dy}{dy} +\setinterfaceconstant{edge}{bordura} +\setinterfaceconstant{edgedistance}{distantabordura} +\setinterfaceconstant{editor}{editor} +\setinterfaceconstant{editoretaldisplay}{editoretaldisplay} +\setinterfaceconstant{editoretallimit}{editoretallimit} +\setinterfaceconstant{editoretaltext}{editoretaltext} +\setinterfaceconstant{empty}{gol} +\setinterfaceconstant{equalheight}{equalheight} +\setinterfaceconstant{equalwidth}{equalwidth} +\setinterfaceconstant{escape}{escape} +\setinterfaceconstant{evenmargin}{marginepara} +\setinterfaceconstant{expansion}{expansiune} +\setinterfaceconstant{export}{export} +\setinterfaceconstant{extras}{extras} +\setinterfaceconstant{factor}{factor} +\setinterfaceconstant{fallback}{fallback} +\setinterfaceconstant{family}{familie} +\setinterfaceconstant{fieldbackgroundcolor}{culoarefundalcamp} +\setinterfaceconstant{fieldframecolor}{culoareframecamp} +\setinterfaceconstant{fieldlayer}{fieldlayer} +\setinterfaceconstant{fieldoffset}{offsetcamp} +\setinterfaceconstant{file}{fisier} +\setinterfaceconstant{filtercommand}{filtercommand} +\setinterfaceconstant{finalnamesep}{finalnamesep} +\setinterfaceconstant{firstnamesep}{firstnamesep} +\setinterfaceconstant{focus}{focus} +\setinterfaceconstant{focusin}{focusin} +\setinterfaceconstant{focusout}{focusout} +\setinterfaceconstant{footer}{subsol} +\setinterfaceconstant{footerdistance}{distantasubsol} +\setinterfaceconstant{footerstate}{staresubsol} +\setinterfaceconstant{foregroundcolor}{foregroundcolor} +\setinterfaceconstant{foregroundstyle}{foregroundstyle} +\setinterfaceconstant{format}{format} +\setinterfaceconstant{frame}{frame} +\setinterfaceconstant{framecolor}{culoareframe} +\setinterfaceconstant{framecorner}{coltframe} +\setinterfaceconstant{framedepth}{adancimeframe} +\setinterfaceconstant{frameoffset}{offsetframe} +\setinterfaceconstant{frameradius}{razaframe} +\setinterfaceconstant{frames}{frames} +\setinterfaceconstant{from}{dela} +\setinterfaceconstant{get}{adu} +\setinterfaceconstant{global}{global} +\setinterfaceconstant{grid}{grid} +\setinterfaceconstant{hang}{suspenda} +\setinterfaceconstant{headalign}{headalign} +\setinterfaceconstant{headcolor}{culoaretitlu} +\setinterfaceconstant{headcommand}{headcommand} +\setinterfaceconstant{headconversion}{conversietitlu} +\setinterfaceconstant{header}{antet} +\setinterfaceconstant{headerdistance}{distantaantet} +\setinterfaceconstant{headerstate}{stareantet} +\setinterfaceconstant{headlabel}{etichetatitlu} +\setinterfaceconstant{headnumber}{numartitlu} +\setinterfaceconstant{headstyle}{stiltitlu} +\setinterfaceconstant{height}{inaltime} +\setinterfaceconstant{hfactor}{hfactor} +\setinterfaceconstant{hfil}{hfil} +\setinterfaceconstant{hidenumber}{hidenumber} +\setinterfaceconstant{hoffset}{hoffset} +\setinterfaceconstant{horoffset}{offsetoriz} +\setinterfaceconstant{hyphen}{hyphen} +\setinterfaceconstant{icommand}{comandai} +\setinterfaceconstant{in}{in} +\setinterfaceconstant{inbetween}{intre} +\setinterfaceconstant{increment}{increment} +\setinterfaceconstant{incrementnumber}{numarincrement} +\setinterfaceconstant{indenting}{aliniat} +\setinterfaceconstant{indentnext}{aliniaturmator} +\setinterfaceconstant{indicator}{indicator} +\setinterfaceconstant{inner}{intern} +\setinterfaceconstant{innermargin}{innermargin} +\setinterfaceconstant{inputfile}{inputfile} +\setinterfaceconstant{intent}{intent} +\setinterfaceconstant{interaction}{interactiune} +\setinterfaceconstant{interlinespace}{spatiereinterliniara} +\setinterfaceconstant{itemalign}{itemalign} +\setinterfaceconstant{items}{elemente} +\setinterfaceconstant{juniorsep}{juniorsep} +\setinterfaceconstant{ken}{ken} +\setinterfaceconstant{keyexpansion}{keyexpansion} +\setinterfaceconstant{keyword}{keyword} +\setinterfaceconstant{label}{eticheta} +\setinterfaceconstant{lastnamesep}{lastnamesep} +\setinterfaceconstant{lastpubsep}{lastpubsep} +\setinterfaceconstant{left}{stanga} +\setinterfaceconstant{leftcolor}{culoarestanga} +\setinterfaceconstant{leftcompoundhyphen}{leftcompoundhyphen} +\setinterfaceconstant{leftedge}{bordurastanga} +\setinterfaceconstant{leftedgedistance}{distantabordurastanga} +\setinterfaceconstant{leftframe}{framestanga} +\setinterfaceconstant{lefthyphen}{lefthyphen} +\setinterfaceconstant{leftmargin}{marginestanga} +\setinterfaceconstant{leftmargindistance}{distantamarginestanga} +\setinterfaceconstant{leftoffset}{offsetstanga} +\setinterfaceconstant{leftquotation}{citatstanga} +\setinterfaceconstant{leftquote}{minicitatstanga} +\setinterfaceconstant{leftsentence}{propozitiestanga} +\setinterfaceconstant{leftspeech}{leftspeech} +\setinterfaceconstant{leftstyle}{stilstanga} +\setinterfaceconstant{leftsubsentence}{subpropozitiestanga} +\setinterfaceconstant{lefttext}{textstanga} +\setinterfaceconstant{leftwidth}{latimestanga} +\setinterfaceconstant{level}{nivel} +\setinterfaceconstant{levels}{nivele} +\setinterfaceconstant{limittext}{limittext} +\setinterfaceconstant{line}{linie} +\setinterfaceconstant{linecorrection}{corectielinie} +\setinterfaceconstant{lines}{linii} +\setinterfaceconstant{list}{lista} +\setinterfaceconstant{listtext}{listtext} +\setinterfaceconstant{local}{local} +\setinterfaceconstant{location}{locatie} +\setinterfaceconstant{logo}{logo} +\setinterfaceconstant{logos}{logos} +\setinterfaceconstant{marcolor}{culoaremarcaj} +\setinterfaceconstant{margin}{margine} +\setinterfaceconstant{margindistance}{distantamargine} +\setinterfaceconstant{marginedge}{coltbordura} +\setinterfaceconstant{marginedgetext}{textcoltbordura} +\setinterfaceconstant{margintext}{textmargine} +\setinterfaceconstant{marking}{marcaje} +\setinterfaceconstant{marstyle}{stilmarcaj} +\setinterfaceconstant{max}{max} +\setinterfaceconstant{maxdepth}{maxdepth} +\setinterfaceconstant{maxheight}{inaltimemaxima} +\setinterfaceconstant{maxwidth}{latimemaxima} +\setinterfaceconstant{maybeyear}{maybeyear} +\setinterfaceconstant{menu}{meniu} +\setinterfaceconstant{method}{metoda} +\setinterfaceconstant{middle}{mijloc} +\setinterfaceconstant{middlespeech}{middlespeech} +\setinterfaceconstant{middletext}{textmijloc} +\setinterfaceconstant{midsentence}{midsentence} +\setinterfaceconstant{min}{min} +\setinterfaceconstant{mindepth}{mindepth} +\setinterfaceconstant{minheight}{inaltimeminima} +\setinterfaceconstant{minwidth}{latimeminima} +\setinterfaceconstant{monthconversion}{monthconversion} +\setinterfaceconstant{n}{n} +\setinterfaceconstant{name}{nume} +\setinterfaceconstant{namesep}{namesep} +\setinterfaceconstant{nbottom}{njos} +\setinterfaceconstant{nc}{nc} +\setinterfaceconstant{next}{urmatorul} +\setinterfaceconstant{nl}{nl} +\setinterfaceconstant{nleft}{nstanga} +\setinterfaceconstant{nlines}{nlinii} +\setinterfaceconstant{norm}{norm} +\setinterfaceconstant{nr}{nr} +\setinterfaceconstant{nright}{ndreapta} +\setinterfaceconstant{ntop}{nsus} +\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{numberstarter}{numberstarter} +\setinterfaceconstant{numberstopper}{numberstopper} +\setinterfaceconstant{numberstyle}{stilnumar} +\setinterfaceconstant{numberwidth}{numberwidth} +\setinterfaceconstant{nx}{nx} +\setinterfaceconstant{ny}{ny} +\setinterfaceconstant{object}{obiect} +\setinterfaceconstant{obstruction}{obstructie} +\setinterfaceconstant{oddmargin}{margineimpara} +\setinterfaceconstant{offset}{offset} +\setinterfaceconstant{openaction}{actiunedeschidere} +\setinterfaceconstant{openpageaction}{actiunedeschiderepagina} +\setinterfaceconstant{option}{optiune} +\setinterfaceconstant{order}{order} +\setinterfaceconstant{orientation}{orientation} +\setinterfaceconstant{otherstext}{otherstext} +\setinterfaceconstant{outermargin}{outermargin} +\setinterfaceconstant{overprint}{overprint} +\setinterfaceconstant{ownnumber}{numarpropriu} +\setinterfaceconstant{page}{pagina} +\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{pageprefixstarter}{pageprefixstarter} +\setinterfaceconstant{pageprefixstopper}{pageprefixstopper} +\setinterfaceconstant{pagesegments}{pagesegments} +\setinterfaceconstant{pageseparatorset}{pageseparatorset} +\setinterfaceconstant{pageset}{pageset} +\setinterfaceconstant{pagestarter}{pagestarter} +\setinterfaceconstant{pagestate}{pagestate} +\setinterfaceconstant{pagestopper}{pagestopper} +\setinterfaceconstant{pagestyle}{stilpagina} +\setinterfaceconstant{palet}{paleta} +\setinterfaceconstant{paper}{hartie} +\setinterfaceconstant{paragraph}{paragraf} +\setinterfaceconstant{place}{pune} +\setinterfaceconstant{placehead}{punetitlu} +\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{prefixstarter}{prefixstarter} +\setinterfaceconstant{prefixstopper}{prefixstopper} +\setinterfaceconstant{preset}{preset} +\setinterfaceconstant{preview}{previzualizare} +\setinterfaceconstant{previous}{precendent} +\setinterfaceconstant{previousnumber}{numarprecedent} +\setinterfaceconstant{process}{process} +\setinterfaceconstant{pubsep}{pubsep} +\setinterfaceconstant{radius}{raza} +\setinterfaceconstant{random}{aleator} +\setinterfaceconstant{range}{range} +\setinterfaceconstant{reduction}{reducere} +\setinterfaceconstant{ref}{ref} +\setinterfaceconstant{refcommand}{refcommand} +\setinterfaceconstant{reference}{referinta} +\setinterfaceconstant{referenceprefix}{referenceprefix} +\setinterfaceconstant{referencing}{referinta} +\setinterfaceconstant{regionin}{regiuneintrare} +\setinterfaceconstant{regionout}{regiuneiesire} +\setinterfaceconstant{repeat}{repeta} +\setinterfaceconstant{reset}{reset} +\setinterfaceconstant{resetnumber}{resetnumber} +\setinterfaceconstant{resolution}{rezolutie} +\setinterfaceconstant{right}{dreapta} +\setinterfaceconstant{rightcolor}{culoaredreapta} +\setinterfaceconstant{rightcompoundhyphen}{rightcompoundhyphen} +\setinterfaceconstant{rightedge}{borduradreapta} +\setinterfaceconstant{rightedgedistance}{distantacoltdreapta} +\setinterfaceconstant{rightframe}{framedreapta} +\setinterfaceconstant{righthyphen}{righthyphen} +\setinterfaceconstant{rightmargin}{marginedreapta} +\setinterfaceconstant{rightmargindistance}{distantamarginedreapta} +\setinterfaceconstant{rightoffset}{offsetdreapta} +\setinterfaceconstant{rightquotation}{citatdreapta} +\setinterfaceconstant{rightquote}{minicitatdreapta} +\setinterfaceconstant{rightsentence}{propozitiedreapta} +\setinterfaceconstant{rightspeech}{rightspeech} +\setinterfaceconstant{rightstyle}{stildreapta} +\setinterfaceconstant{rightsubsentence}{subpropozitiedreapta} +\setinterfaceconstant{righttext}{textdreapta} +\setinterfaceconstant{rightwidth}{marginedreapta} +\setinterfaceconstant{rotation}{rotatie} +\setinterfaceconstant{rule}{rigla} +\setinterfaceconstant{rulecolor}{culoarerigla} +\setinterfaceconstant{rulethickness}{grosimerigla} +\setinterfaceconstant{samepage}{aceeasipagina} +\setinterfaceconstant{sample}{exemplu} +\setinterfaceconstant{samplesize}{samplesize} +\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{sectionresetset}{sectionresetset} +\setinterfaceconstant{sectionsegments}{sectionsegments} +\setinterfaceconstant{sectionseparatorset}{sectionseparatorset} +\setinterfaceconstant{sectionset}{sectionset} +\setinterfaceconstant{sectionstarter}{sectionstarter} +\setinterfaceconstant{sectionstopper}{sectionstopper} +\setinterfaceconstant{separator}{separator} +\setinterfaceconstant{set}{set} +\setinterfaceconstant{setups}{setups} +\setinterfaceconstant{side}{parte} +\setinterfaceconstant{sidealign}{sidealign} +\setinterfaceconstant{sidemethod}{sidemethod} +\setinterfaceconstant{sidespaceafter}{spatiulateraldupa} +\setinterfaceconstant{sidespacebefore}{spatiulateralinainte} +\setinterfaceconstant{sign}{semn} +\setinterfaceconstant{size}{dimensiune} +\setinterfaceconstant{small}{mic} +\setinterfaceconstant{sort}{sort} +\setinterfaceconstant{sorttype}{sorttype} +\setinterfaceconstant{source}{sursa} +\setinterfaceconstant{space}{spatiu} +\setinterfaceconstant{spaceafter}{spatiudupa} +\setinterfaceconstant{spacebefore}{spatiuinainte} +\setinterfaceconstant{spaceinbetween}{spaceinbetween} +\setinterfaceconstant{spacing}{spatiere} +\setinterfaceconstant{split}{split} +\setinterfaceconstant{splitcolor}{splitcolor} +\setinterfaceconstant{splitmethod}{splitmethod} +\setinterfaceconstant{splitoffset}{splitoffset} +\setinterfaceconstant{spot}{spot} +\setinterfaceconstant{stack}{stack} +\setinterfaceconstant{start}{start} +\setinterfaceconstant{starter}{starter} +\setinterfaceconstant{state}{stare} +\setinterfaceconstant{step}{pas} +\setinterfaceconstant{stop}{stop} +\setinterfaceconstant{stopper}{stopper} +\setinterfaceconstant{stretch}{dilatat} +\setinterfaceconstant{strip}{strip} +\setinterfaceconstant{strut}{strut} +\setinterfaceconstant{style}{stil} +\setinterfaceconstant{sub}{sub} +\setinterfaceconstant{subtitle}{subtitlu} +\setinterfaceconstant{suffix}{suffix} +\setinterfaceconstant{surnamesep}{surnamesep} +\setinterfaceconstant{sx}{sx} +\setinterfaceconstant{sy}{sy} +\setinterfaceconstant{symalign}{symaliniere} +\setinterfaceconstant{symbol}{simbol} +\setinterfaceconstant{symbolset}{setsimbol} +\setinterfaceconstant{symcolor}{culoaresimbol} +\setinterfaceconstant{symstyle}{stilsimbol} +\setinterfaceconstant{synonym}{sinonim} +\setinterfaceconstant{synonymcolor}{culoaresinonim} +\setinterfaceconstant{synonymcommand}{synonymcommand} +\setinterfaceconstant{synonymstyle}{stilsinonim} +\setinterfaceconstant{tab}{tab} +\setinterfaceconstant{text}{text} +\setinterfaceconstant{textcolor}{culoaretext} +\setinterfaceconstant{textcommand}{comandatext} +\setinterfaceconstant{textdistance}{textdistance} +\setinterfaceconstant{textlayer}{textlayer} +\setinterfaceconstant{textmargin}{textmargin} +\setinterfaceconstant{textmethod}{textmethod} +\setinterfaceconstant{textseparator}{separatortext} +\setinterfaceconstant{textsize}{dimensiunetext} +\setinterfaceconstant{textstate}{staretext} +\setinterfaceconstant{textstyle}{stiltext} +\setinterfaceconstant{textwidth}{latimetext} +\setinterfaceconstant{title}{titlu} +\setinterfaceconstant{titlecolor}{culoaretitlu} +\setinterfaceconstant{titlecommand}{titlecommand} +\setinterfaceconstant{titledistance}{distantatitlu} +\setinterfaceconstant{titleleft}{titleleft} +\setinterfaceconstant{titleright}{titleright} +\setinterfaceconstant{titlestyle}{stiltitlu} +\setinterfaceconstant{to}{catre} +\setinterfaceconstant{tolerance}{toleranta} +\setinterfaceconstant{top}{sus} +\setinterfaceconstant{topdistance}{distantasus} +\setinterfaceconstant{topframe}{framesus} +\setinterfaceconstant{topoffset}{offsetsus} +\setinterfaceconstant{topspace}{spatiusus} +\setinterfaceconstant{topstate}{staresus} +\setinterfaceconstant{totalnumber}{totalnumber} +\setinterfaceconstant{type}{type} +\setinterfaceconstant{unit}{unitate} +\setinterfaceconstant{unknownreference}{referintanecunoscuta} +\setinterfaceconstant{urlalternative}{urlalternativ} +\setinterfaceconstant{urlspace}{spatiuurl} +\setinterfaceconstant{validate}{verifica} +\setinterfaceconstant{vcommand}{comandav} +\setinterfaceconstant{veroffset}{veroffset} +\setinterfaceconstant{vfil}{vfil} +\setinterfaceconstant{voffset}{voffset} +\setinterfaceconstant{vonsep}{vonsep} +\setinterfaceconstant{way}{mod} +\setinterfaceconstant{wfactor}{factorw} +\setinterfaceconstant{white}{alb} +\setinterfaceconstant{width}{latime} +\setinterfaceconstant{xfactor}{xfactor} +\setinterfaceconstant{xmax}{xmax} +\setinterfaceconstant{xoffset}{xoffset} +\setinterfaceconstant{xscale}{xscala} +\setinterfaceconstant{xstep}{xstep} +\setinterfaceconstant{yfactor}{yfactor} +\setinterfaceconstant{ymax}{ymax} +\setinterfaceconstant{yoffset}{yoffset} +\setinterfaceconstant{yscale}{yscala} +\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} +\setinterfaceelement{currentlocal}{localcurent} +\setinterfaceelement{emptyone}{gol} +\setinterfaceelement{emptytwo}{gol} +\setinterfaceelement{end}{sfarsit} +\setinterfaceelement{endsetup}{} +\setinterfaceelement{get}{get} +\setinterfaceelement{increment}{increment} +\setinterfaceelement{list}{lista} +\setinterfaceelement{listof}{listade} +\setinterfaceelement{load}{incarca} +\setinterfaceelement{local}{local} +\setinterfaceelement{makeup}{makeup} +\setinterfaceelement{next}{urmatorul} +\setinterfaceelement{place}{pune} +\setinterfaceelement{previous}{precedent} +\setinterfaceelement{previouslocal}{precedentlocal} +\setinterfaceelement{reserve}{rezervat} +\setinterfaceelement{see}{vezi} +\setinterfaceelement{setup}{setare} +\setinterfaceelement{start}{start} +\setinterfaceelement{stop}{stop} +\setinterfaceelement{text}{text} +\setinterfaceelement{type}{type} +% definitions for interface commands for language ro +% +\setinterfacecommand{CAPPED}{KAP} +\setinterfacecommand{Character}{Litera} +\setinterfacecommand{Characters}{Litere} +\setinterfacecommand{LABELTEXT}{TEXTETICHETA} +\setinterfacecommand{MONTH}{LUNA} +\setinterfacecommand{Numbers}{Numere} +\setinterfacecommand{Romannumerals}{Numereromane} +\setinterfacecommand{SmallCapped}{Kap} +\setinterfacecommand{SmallCaps}{Kaps} +\setinterfacecommand{WEEKDAY}{ZIDINSAPTAMANA} +\setinterfacecommand{WORD}{CUVANT} +\setinterfacecommand{WORDS}{CUVINTE} +\setinterfacecommand{Word}{Cuvant} +\setinterfacecommand{Words}{Cuvinte} +\setinterfacecommand{about}{despre} +\setinterfacecommand{adaptlayout}{adapteazaaspect} +\setinterfacecommand{arg}{arg} +\setinterfacecommand{at}{la} +\setinterfacecommand{atleftmargin}{atleftmargin} +\setinterfacecommand{atpage}{lapagina} +\setinterfacecommand{atrightmargin}{atrightmargin} +\setinterfacecommand{background}{fundal} +\setinterfacecommand{backspace}{spatiuspate} +\setinterfacecommand{blackrule}{linieneagra} +\setinterfacecommand{blackrules}{liniinegre} +\setinterfacecommand{blank}{blanc} +\setinterfacecommand{bookmark}{semncarte} +\setinterfacecommand{bottomdistance}{distantajos} +\setinterfacecommand{bottomheight}{inaltimejos} +\setinterfacecommand{bottomspace}{spatiujos} +\setinterfacecommand{but}{but} +\setinterfacecommand{button}{buton} +\setinterfacecommand{bypassblocks}{saripesteblocuri} +\setinterfacecommand{character}{litera} +\setinterfacecommand{characters}{litere} +\setinterfacecommand{chem}{chem} +\setinterfacecommand{clip}{clip} +\setinterfacecommand{clonefield}{cloneazacamp} +\setinterfacecommand{color}{culoare} +\setinterfacecommand{colorbar}{baraculoare} +\setinterfacecommand{colorvalue}{valoareculoare} +\setinterfacecommand{column}{coloana} +\setinterfacecommand{comment}{comentariu} +\setinterfacecommand{comparecolorgroup}{comparagrupculoare} +\setinterfacecommand{comparepalet}{comparapaleta} +\setinterfacecommand{completepagenumber}{completeazanumarpagina} +\setinterfacecommand{completeregister}{completeregister} +\setinterfacecommand{component}{componenta} +\setinterfacecommand{convertnumber}{convertestenumar} +\setinterfacecommand{copyfield}{copiazacamp} +\setinterfacecommand{correctwhitespace}{corecteazaspatiualb} +\setinterfacecommand{coupledocument}{cupleazadocument} +\setinterfacecommand{couplemarking}{cupleazamarcaje} +\setinterfacecommand{couplepage}{paginadubla} +\setinterfacecommand{couplepaper}{hartiedubla} +\setinterfacecommand{coupleregister}{cupleazaregistru} +\setinterfacecommand{crlf}{crlf} +\setinterfacecommand{currentdate}{datacurenta} +\setinterfacecommand{currentheadnumber}{numartitlucurent} +\setinterfacecommand{cutspace}{cutspace} +\setinterfacecommand{date}{data} +\setinterfacecommand{decouplemarking}{decupleazamarcaje} +\setinterfacecommand{decrementnumber}{decrementnumber} +\setinterfacecommand{define}{defineste} +\setinterfacecommand{defineaccent}{definesteaccent} +\setinterfacecommand{defineblank}{definesteblanc} +\setinterfacecommand{defineblock}{definestebloc} +\setinterfacecommand{definebodyfont}{definestefonttext} +\setinterfacecommand{definebodyfontenvironment}{definestemediulfonttext} +\setinterfacecommand{definebuffer}{definestebuffer} +\setinterfacecommand{definecharacter}{definestecaracter} +\setinterfacecommand{definecolor}{definesteculoare} +\setinterfacecommand{definecolorgroup}{definestegrupculori} +\setinterfacecommand{definecolumnbreak}{definecolumnbreak} +\setinterfacecommand{definecolumnset}{definecolumnset} +\setinterfacecommand{definecombination}{definecombination} +\setinterfacecommand{definecombinedlist}{definestelistacombinata} +\setinterfacecommand{definecommand}{definestecomanda} +\setinterfacecommand{defineconversion}{definesteconversie} +\setinterfacecommand{definedescription}{definestedescriere} +\setinterfacecommand{defineenumeration}{definesteenumerare} +\setinterfacecommand{definefield}{definestecamp} +\setinterfacecommand{definefieldstack}{definestestivacampuri} +\setinterfacecommand{definefiguresymbol}{definestesimbolfigura} +\setinterfacecommand{definefloat}{definestefloat} +\setinterfacecommand{definefont}{definestefont} +\setinterfacecommand{definefontstyle}{definestestilfont} +\setinterfacecommand{definefontsynonym}{definestesinonimfont} +\setinterfacecommand{defineframed}{definesteinconjurare} +\setinterfacecommand{defineframedtext}{definestetextinconjurat} +\setinterfacecommand{definehbox}{definestehbox} +\setinterfacecommand{definehead}{definesteantet} +\setinterfacecommand{defineindenting}{definestealiat} +\setinterfacecommand{defineinmargin}{defineinmargin} +\setinterfacecommand{defineinteractionmenu}{definestemeniuinteractiune} +\setinterfacecommand{defineitemgroup}{defineitemgroup} +\setinterfacecommand{definelabel}{definesteeticheta} +\setinterfacecommand{definelayer}{definelayer} +\setinterfacecommand{definelayout}{definelayout} +\setinterfacecommand{definelist}{definestelista} +\setinterfacecommand{definelogo}{definestelogo} +\setinterfacecommand{definemainfield}{definestecampprincipal} +\setinterfacecommand{definemakeup}{definestemakeup} +\setinterfacecommand{definemarking}{definestemarcaje} +\setinterfacecommand{definemathalignment}{definemathalignment} +\setinterfacecommand{defineoutput}{definesteoutput} +\setinterfacecommand{defineoverlay}{definesteoverlay} +\setinterfacecommand{definepagebreak}{definepagebreak} +\setinterfacecommand{definepalet}{definestepaleta} +\setinterfacecommand{definepapersize}{definestedimensiunehartie} +\setinterfacecommand{defineparagraphs}{definesteparagraf} +\setinterfacecommand{defineplacement}{defineplacement} +\setinterfacecommand{defineprofile}{definesteprofil} +\setinterfacecommand{defineprogram}{definesteprogram} +\setinterfacecommand{definerawfont}{definestefontraw} +\setinterfacecommand{definereference}{definestereferinte} +\setinterfacecommand{definereferenceformat}{definesteformatreferinte} +\setinterfacecommand{definereferencelist}{definestelistareferinte} +\setinterfacecommand{defineregister}{definesteregistru} +\setinterfacecommand{definerule}{definesterigla} +\setinterfacecommand{definesection}{definestesectiune} +\setinterfacecommand{definesectionblock}{definesteblocsectiune} +\setinterfacecommand{definesorting}{definestesortare} +\setinterfacecommand{definestartstop}{definestestartstop} +\setinterfacecommand{definestyle}{definestestil} +\setinterfacecommand{definesubfield}{definestesubcamp} +\setinterfacecommand{definesymbol}{definestesimbol} +\setinterfacecommand{definesynonyms}{definestesinonim} +\setinterfacecommand{definetabletemplate}{definestesablontabel} +\setinterfacecommand{definetabulate}{definestetabulatori} +\setinterfacecommand{definetext}{definestetext} +\setinterfacecommand{definetextposition}{definestepozitietext} +\setinterfacecommand{definetextvariable}{definestevariabilatext} +\setinterfacecommand{definetype}{definetype} +\setinterfacecommand{definetyping}{definestetyping} +\setinterfacecommand{defineversion}{definesteversiune} +\setinterfacecommand{determineheadnumber}{determinanumartitlu} +\setinterfacecommand{determinelistcharacteristics}{determinacaracteristicilelistei} +\setinterfacecommand{determineregistercharacteristics}{determinacaracteristiciregistru} +\setinterfacecommand{dimension}{dimensiune} +\setinterfacecommand{disableinteractionmenu}{dezactiveazameniuinteractiune} +\setinterfacecommand{domicile}{domiciliu} +\setinterfacecommand{donttest}{nutesta} +\setinterfacecommand{edgedistance}{distantacolt} +\setinterfacecommand{edgewidth}{latimecolturi} +\setinterfacecommand{emptylines}{emptylines} +\setinterfacecommand{environment}{mediu} +\setinterfacecommand{externalfigure}{figuraexterna} +\setinterfacecommand{fact}{fact} +\setinterfacecommand{field}{camp} +\setinterfacecommand{fieldstack}{stivacampuri} +\setinterfacecommand{fillinfield}{campumplere} +\setinterfacecommand{fillinline}{linieumplere} +\setinterfacecommand{fillinrules}{rigleumplere} +\setinterfacecommand{fillintext}{textumplere} +\setinterfacecommand{fitfield}{potrivestecamp} +\setinterfacecommand{fixedspace}{spatiufixat} +\setinterfacecommand{fixedspaces}{spatiifixate} +\setinterfacecommand{followprofile}{urmeazaprofil} +\setinterfacecommand{followprofileversion}{urmeazaversiuneprofil} +\setinterfacecommand{followversion}{urmeazaversiune} +\setinterfacecommand{footerdistance}{distantasubsol} +\setinterfacecommand{footerheight}{inaltimesubsol} +\setinterfacecommand{footnote}{notasubsol} +\setinterfacecommand{footnotetext}{footnotetext} +\setinterfacecommand{forceblocks}{forteazablocuri} +\setinterfacecommand{formulanumber}{numarformula} +\setinterfacecommand{fraction}{fractie} +\setinterfacecommand{framed}{framed} +\setinterfacecommand{from}{din} +\setinterfacecommand{getbuffer}{adubuffer} +\setinterfacecommand{getmarking}{adumarcaje} +\setinterfacecommand{getnumber}{getnumber} +\setinterfacecommand{godown}{injos} +\setinterfacecommand{goto}{dute} +\setinterfacecommand{gotobox}{dutebox} +\setinterfacecommand{gotopage}{dutepagina} +\setinterfacecommand{graycolor}{culoaregri} +\setinterfacecommand{greyvalue}{valoaregri} +\setinterfacecommand{grid}{grid} +\setinterfacecommand{hairline}{firdepar} +\setinterfacecommand{head}{titlu} +\setinterfacecommand{headerdistance}{distantaantet} +\setinterfacecommand{headerheight}{inaltimeantet} +\setinterfacecommand{headlevel}{niveltitlu} +\setinterfacecommand{headnumber}{numartitlu} +\setinterfacecommand{headsym}{headsym} +\setinterfacecommand{headtext}{texttitlu} +\setinterfacecommand{hideblocks}{ascundeblocuri} +\setinterfacecommand{high}{inalt} +\setinterfacecommand{hl}{hl} +\setinterfacecommand{immediatebetweenlist}{immediatebetweenlist} +\setinterfacecommand{immediatetolist}{immediatetolist} +\setinterfacecommand{in}{in} +\setinterfacecommand{incrementnumber}{numarincrement} +\setinterfacecommand{indenting}{aliniat} +\setinterfacecommand{inframed}{inframed} +\setinterfacecommand{infull}{pelung} +\setinterfacecommand{ininner}{ininner} +\setinterfacecommand{inleft}{instanga} +\setinterfacecommand{inleftedge}{inparteastanga} +\setinterfacecommand{inleftmargin}{inmargineastanga} +\setinterfacecommand{inline}{inlinie} +\setinterfacecommand{inmargin}{marginal} +\setinterfacecommand{inmframed}{inmaframed} +\setinterfacecommand{inneredgedistance}{inneredgedistance} +\setinterfacecommand{inneredgewidth}{inneredgewidth} +\setinterfacecommand{innermargindistance}{innermargindistance} +\setinterfacecommand{innermarginwidth}{innermarginwidth} +\setinterfacecommand{inothermargin}{inaltamargine} +\setinterfacecommand{inouter}{inouter} +\setinterfacecommand{inright}{indreapta} +\setinterfacecommand{inrightedge}{inparteadreapta} +\setinterfacecommand{inrightmargin}{inmargineadreapta} +\setinterfacecommand{installlanguage}{instalarelimba} +\setinterfacecommand{interactionbar}{barainteractiune} +\setinterfacecommand{interactionbuttons}{butoaneinteractiune} +\setinterfacecommand{interactionmenu}{meniuinteractiune} +\setinterfacecommand{item}{element} +\setinterfacecommand{items}{element} +\setinterfacecommand{its}{el} +\setinterfacecommand{keepblocks}{pastreazablocuri} +\setinterfacecommand{label}{eticheta} +\setinterfacecommand{labels}{etichete} +\setinterfacecommand{labeltext}{texteticheta} +\setinterfacecommand{language}{limba} +\setinterfacecommand{leftaligned}{aliniatstanga} +\setinterfacecommand{leftedgedistance}{distantacoltstanga} +\setinterfacecommand{leftedgewidth}{latimecoltstanga} +\setinterfacecommand{leftmargindistance}{distantamarginestanga} +\setinterfacecommand{leftmarginwidth}{latimemarginestanga} +\setinterfacecommand{leg}{leg} +\setinterfacecommand{linewidth}{grosimelinie} +\setinterfacecommand{listheight}{inaltimelista} +\setinterfacecommand{listlength}{lungimelista} +\setinterfacecommand{listsymbol}{listsymbol} +\setinterfacecommand{listwidth}{latimelista} +\setinterfacecommand{logfields}{logcampuri} +\setinterfacecommand{lohi}{jossus} +\setinterfacecommand{low}{jos} +\setinterfacecommand{macroname}{nume} +\setinterfacecommand{mainlanguage}{limbaprincipala} +\setinterfacecommand{makeupheight}{inaltimemakeup} +\setinterfacecommand{makeupwidth}{latimemakeup} +\setinterfacecommand{mar}{mar} +\setinterfacecommand{margindistance}{distantamargine} +\setinterfacecommand{marginrule}{liniemargine} +\setinterfacecommand{margintext}{textmarginal} +\setinterfacecommand{margintitle}{titlumarginal} +\setinterfacecommand{marginwidth}{latimemargine} +\setinterfacecommand{marginword}{cuvantmarginal} +\setinterfacecommand{marking}{marcaje} +\setinterfacecommand{markversion}{marcheazaversiune} +\setinterfacecommand{mathematics}{matematica} +\setinterfacecommand{menubutton}{butonmeniu} +\setinterfacecommand{mframed}{maframed} +\setinterfacecommand{midaligned}{aliniatcentru} +\setinterfacecommand{mirror}{reflexie} +\setinterfacecommand{month}{luna} +\setinterfacecommand{moveformula}{moveformula} +\setinterfacecommand{moveongrid}{mutapegrid} +\setinterfacecommand{movesidefloat}{movesidefloat} +\setinterfacecommand{navigating}{navigating} +\setinterfacecommand{nodimension}{faradimensiune} +\setinterfacecommand{noheaderandfooterlines}{faraliniiantetsisubsol} +\setinterfacecommand{noindenting}{faraaliniat} +\setinterfacecommand{nolist}{faralista} +\setinterfacecommand{nomarking}{faramarcaje} +\setinterfacecommand{nomoreblocks}{gatablocuri} +\setinterfacecommand{nomorefiles}{farafisiere} +\setinterfacecommand{nop}{nop} +\setinterfacecommand{nospace}{faraspatiu} +\setinterfacecommand{note}{nota} +\setinterfacecommand{notopandbottomlines}{faraliniisussijos} +\setinterfacecommand{notsmallcapped}{nokap} +\setinterfacecommand{nowhitespace}{faraspatiualb} +\setinterfacecommand{numberofsubpages}{numberofsubpages} +\setinterfacecommand{numbers}{numere} +\setinterfacecommand{outeredgedistance}{outeredgedistance} +\setinterfacecommand{outeredgewidth}{outeredgewidth} +\setinterfacecommand{outermargindistance}{outermargindistance} +\setinterfacecommand{outermarginwidth}{outermarginwidth} +\setinterfacecommand{packed}{impachetat} +\setinterfacecommand{page}{pagina} +\setinterfacecommand{pagedepth}{pagedepth} +\setinterfacecommand{pagenumber}{numarpagina} +\setinterfacecommand{pageoffset}{pageoffset} +\setinterfacecommand{pagereference}{referintapagina} +\setinterfacecommand{pagetype}{tippagina} +\setinterfacecommand{paperheight}{inaltimehartie} +\setinterfacecommand{paperwidth}{latimehartie} +\setinterfacecommand{periods}{puncte} +\setinterfacecommand{plaatsruwelijst}{placerawlist} +\setinterfacecommand{placebookmarks}{plaseazasemnecarte} +\setinterfacecommand{placecombinedlist}{punelistacombinata} +\setinterfacecommand{placefloat}{placefloat} +\setinterfacecommand{placefootnotes}{punenotesubsol} +\setinterfacecommand{placeformula}{puneformula} +\setinterfacecommand{placeheadnumber}{placeheadnumber} +\setinterfacecommand{placeheadtext}{placeheadtext} +\setinterfacecommand{placelegend}{punelegenda} +\setinterfacecommand{placelist}{punelista} +\setinterfacecommand{placelocalfootnotes}{punenotesubsollocale} +\setinterfacecommand{placelogos}{punelogouri} +\setinterfacecommand{placeongrid}{plaseazapegrid} +\setinterfacecommand{placeontopofeachother}{punedeasuprafiecareia} +\setinterfacecommand{placepagenumber}{punenumarpagina} +\setinterfacecommand{placereferencelist}{placereferencelist} +\setinterfacecommand{placeregister}{puneregistru} +\setinterfacecommand{placerule}{punerigla} +\setinterfacecommand{placesidebyside}{punefatainfata} +\setinterfacecommand{placesubformula}{punesubformula} +\setinterfacecommand{placetextvariable}{punevariabilatext} +\setinterfacecommand{position}{pozitie} +\setinterfacecommand{positiontext}{pozitietext} +\setinterfacecommand{printpaperheight}{inaltimehartieimprimanta} +\setinterfacecommand{printpaperwidth}{latimehartieimprimanta} +\setinterfacecommand{processblocks}{proceseazabloc} +\setinterfacecommand{processpage}{proceseazapagina} +\setinterfacecommand{product}{produs} +\setinterfacecommand{program}{program} +\setinterfacecommand{project}{proiect} +\setinterfacecommand{publication}{publicatie} +\setinterfacecommand{quotation}{citat} +\setinterfacecommand{quote}{minicitat} +\setinterfacecommand{ran}{ran} +\setinterfacecommand{redo}{refa} +\setinterfacecommand{ref}{ref} +\setinterfacecommand{reference}{referinta} +\setinterfacecommand{referral}{referit} +\setinterfacecommand{referraldate}{datareferit} +\setinterfacecommand{referring}{referring} +\setinterfacecommand{remark}{remarca} +\setinterfacecommand{reset}{reset} +\setinterfacecommand{resetmarking}{reseteazamarcaje} +\setinterfacecommand{resetnumber}{resetnumber} +\setinterfacecommand{resettext}{resettextcontent} +\setinterfacecommand{rightaligned}{aliniatdreapta} +\setinterfacecommand{rightedgedistance}{distantacoltdreapta} +\setinterfacecommand{rightedgewidth}{latimecoltdreapta} +\setinterfacecommand{rightmargindistance}{distantamarginedreapta} +\setinterfacecommand{rightmarginwidth}{latimemarginedreapta} +\setinterfacecommand{romannumerals}{numereromane} +\setinterfacecommand{rotate}{roteste} +\setinterfacecommand{scale}{scala} +\setinterfacecommand{screen}{ecran} +\setinterfacecommand{selectblocks}{selecteazablocuri} +\setinterfacecommand{selectpaper}{selecteazahartie} +\setinterfacecommand{selectversion}{selecteazaversiune} +\setinterfacecommand{setnumber}{setnumber} +\setinterfacecommand{settextcontent}{settextcontent} +\setinterfacecommand{settextvariable}{setvariabilatext} +\setinterfacecommand{setupalign}{seteazaalinierea} +\setinterfacecommand{setupanswerarea}{setupanswerarea} +\setinterfacecommand{setuparranging}{seteazaaranjareapag} +\setinterfacecommand{setupbackground}{seteazafundal} +\setinterfacecommand{setupbackgrounds}{seteazafundaluri} +\setinterfacecommand{setupblackrules}{seteazaliniinegre} +\setinterfacecommand{setupblank}{seteazablanc} +\setinterfacecommand{setupblock}{seteazabloc} +\setinterfacecommand{setupbodyfont}{seteazafonttext} +\setinterfacecommand{setupbodyfontenvironment}{seteazamediulfonttext} +\setinterfacecommand{setupbottom}{seteazajos} +\setinterfacecommand{setupbottomtexts}{seteazatextejos} +\setinterfacecommand{setupbuffer}{seteazabuffer} +\setinterfacecommand{setupbuttons}{seteazabutoane} +\setinterfacecommand{setupcapitals}{seteazamajuscule} +\setinterfacecommand{setupcaption}{seteazalegenda} +\setinterfacecommand{setupcaptions}{seteazalegendele} +\setinterfacecommand{setupclipping}{seteazaclipping} +\setinterfacecommand{setupcolor}{seteazaculoare} +\setinterfacecommand{setupcolors}{seteazaculori} +\setinterfacecommand{setupcolumns}{seteazacoloane} +\setinterfacecommand{setupcolumnset}{setupcolumnset} +\setinterfacecommand{setupcolumnsetlines}{setupcolumnsetlines} +\setinterfacecommand{setupcolumnsetstart}{setupcolumnsetstart} +\setinterfacecommand{setupcombinations}{seteazacombinari} +\setinterfacecommand{setupcombinedlist}{seteazalistacombinata} +\setinterfacecommand{setupcomment}{seteazacomentariu} +\setinterfacecommand{setupdescriptions}{seteazadescriere} +\setinterfacecommand{setupenumerations}{seteazaenumerare} +\setinterfacecommand{setupexternalfigures}{seteazafiguriexterne} +\setinterfacecommand{setupfield}{seteazacamp} +\setinterfacecommand{setupfields}{seteazacampuri} +\setinterfacecommand{setupfillinlines}{seteazaliniiumplere} +\setinterfacecommand{setupfillinrules}{seteazarigleumplere} +\setinterfacecommand{setupfloat}{seteazafloat} +\setinterfacecommand{setupfloats}{seteazafloats} +\setinterfacecommand{setupfloatsplitting}{seteazaimpartireafloat} +\setinterfacecommand{setupfooter}{seteazasubsol} +\setinterfacecommand{setupfootertexts}{seteazatextesubsol} +\setinterfacecommand{setupfootnotedefinition}{seteazadefinireanotasubsol} +\setinterfacecommand{setupfootnotes}{seteazanotasubsol} +\setinterfacecommand{setupforms}{seteazaformulare} +\setinterfacecommand{setupformulas}{seteazaformule} +\setinterfacecommand{setupframed}{seteazainconjurat} +\setinterfacecommand{setupframedtexts}{definestetexteinconjurate} +\setinterfacecommand{setuphead}{seteazatitlu} +\setinterfacecommand{setupheader}{seteazaantet} +\setinterfacecommand{setupheadertexts}{seteazatexteantet} +\setinterfacecommand{setupheadnumber}{seteazanumartitlu} +\setinterfacecommand{setupheads}{seteazatitluri} +\setinterfacecommand{setupheadtext}{seteazatexttitlu} +\setinterfacecommand{setuphyphenmark}{seteazaliniesilabe} +\setinterfacecommand{setupindentations}{seteazaaliniate} +\setinterfacecommand{setupindenting}{seteazaaliniat} +\setinterfacecommand{setupinmargin}{seteazamarginal} +\setinterfacecommand{setupinteraction}{seteazainteractiunea} +\setinterfacecommand{setupinteractionbar}{seteazabarainteractiune} +\setinterfacecommand{setupinteractionmenu}{seteazameniuinteractiune} +\setinterfacecommand{setupinteractionscreen}{seteazaecraninteractiune} +\setinterfacecommand{setupinterlinespace}{seteazaspatiuinterliniar} +\setinterfacecommand{setupitemgroup}{setupitemgroup} +\setinterfacecommand{setupitemgroups}{setareitemization} +\setinterfacecommand{setupitems}{seteazaelemente} +\setinterfacecommand{setuplabeltext}{seteazatexteticheta} +\setinterfacecommand{setuplanguage}{setarelimba} +\setinterfacecommand{setuplayout}{seteazaaspect} +\setinterfacecommand{setuplegend}{seteazalegenda} +\setinterfacecommand{setuplinenumbering}{seteazanumerotarelinii} +\setinterfacecommand{setuplines}{seteazalinii} +\setinterfacecommand{setuplinewidth}{seteazagrosimelinie} +\setinterfacecommand{setuplist}{seteazalista} +\setinterfacecommand{setupmakeup}{seteazamakeup} +\setinterfacecommand{setupmarginblocks}{seteazablocurimarginale} +\setinterfacecommand{setupmarginrules}{seteazaliniimargine} +\setinterfacecommand{setupmarking}{seteazamarcaje} +\setinterfacecommand{setupmathalignment}{setupmathalignment} +\setinterfacecommand{setupnarrower}{seteazaingust} +\setinterfacecommand{setupnumber}{setupnumber} +\setinterfacecommand{setupnumbering}{seteazanumerotare} +\setinterfacecommand{setupoppositeplacing}{seteazaplasareaopozita} +\setinterfacecommand{setupoutput}{setareoutput} +\setinterfacecommand{setuppagecomment}{seteazacomentariupagina} +\setinterfacecommand{setuppagenumber}{seteazanumarpagina} +\setinterfacecommand{setuppagenumbering}{seteazanumerotarepagina} +\setinterfacecommand{setuppagetransitions}{seteazatranzitiepagina} +\setinterfacecommand{setuppalet}{seteazapaleta} +\setinterfacecommand{setuppaper}{setuppaper} +\setinterfacecommand{setuppapersize}{seteazadimensiunihartie} +\setinterfacecommand{setupparagraphnumbering}{seteazanumerotareparagrafe} +\setinterfacecommand{setupparagraphs}{seteazaparagrafe} +\setinterfacecommand{setupplacement}{setupplacement} +\setinterfacecommand{setuppositioning}{setarepozitie} +\setinterfacecommand{setupprofiles}{seteazaprofile} +\setinterfacecommand{setupprograms}{seteazaprograme} +\setinterfacecommand{setuppublications}{seteazapublicatii} +\setinterfacecommand{setupquote}{seteazaminicitat} +\setinterfacecommand{setupreferencelist}{seteazalistareferinte} +\setinterfacecommand{setupreferencing}{seteazareferinte} +\setinterfacecommand{setupregister}{seteazaregistru} +\setinterfacecommand{setuprotate}{seteazarotare} +\setinterfacecommand{setuprule}{seteazarigla} +\setinterfacecommand{setups}{setari} +\setinterfacecommand{setupscreens}{seteazaecrane} +\setinterfacecommand{setupsection}{seteazasectiune} +\setinterfacecommand{setupsectionblock}{seteazablocsectiune} +\setinterfacecommand{setupsorting}{seteazasortare} +\setinterfacecommand{setupspacing}{seteazaspatiu} +\setinterfacecommand{setupstartstop}{setupstartstop} +\setinterfacecommand{setupstrut}{seteazastrut} +\setinterfacecommand{setupsubpagenumber}{seteazanumarsubpagina} +\setinterfacecommand{setupsymbolset}{seteazasimbol} +\setinterfacecommand{setupsynchronization}{setaresincronizare} +\setinterfacecommand{setupsynchronizationbar}{setarebarasincronizare} +\setinterfacecommand{setupsynonyms}{seteazasinonime} +\setinterfacecommand{setupsystem}{seteazasistem} +\setinterfacecommand{setuptab}{seteazatab} +\setinterfacecommand{setuptables}{seteazatabele} +\setinterfacecommand{setuptabulate}{seteazatabulatori} +\setinterfacecommand{setuptext}{seteazatext} +\setinterfacecommand{setuptextposition}{seteazapozitietext} +\setinterfacecommand{setuptextrules}{seteazarigletext} +\setinterfacecommand{setuptexttexts}{seteazatextetext} +\setinterfacecommand{setuptextvariable}{seteazavariabilatext} +\setinterfacecommand{setupthinrules}{seteazaliniesubtire} +\setinterfacecommand{setuptolerance}{seteazatoleranta} +\setinterfacecommand{setuptop}{seteazasus} +\setinterfacecommand{setuptoptexts}{seteazatextesus} +\setinterfacecommand{setuptype}{seteazatype} +\setinterfacecommand{setuptyping}{seteazatyping} +\setinterfacecommand{setupunderbar}{seteazasublinie} +\setinterfacecommand{setupurl}{seteazaurl} +\setinterfacecommand{setupversions}{seteazaversiuni} +\setinterfacecommand{setupwhitespace}{seteazaspatiualb} +\setinterfacecommand{showbodyfont}{afiseazafonttext} +\setinterfacecommand{showbodyfontenvironment}{afiseazamediufonttext} +\setinterfacecommand{showcolor}{afiseazaculoare} +\setinterfacecommand{showcolorgroup}{afiseazagrupculoare} +\setinterfacecommand{showexternalfigures}{afiseazafiguriexterne} +\setinterfacecommand{showfields}{afiseazacampuri} +\setinterfacecommand{showframe}{afiseazarama} +\setinterfacecommand{showgrid}{afiseazagrid} +\setinterfacecommand{showlayout}{afiseazaaspect} +\setinterfacecommand{showmakeup}{afiseazamakeup} +\setinterfacecommand{showpalet}{afiseazapaleta} +\setinterfacecommand{showprint}{afiseazatiparire} +\setinterfacecommand{showsetups}{afiseazasetari} +\setinterfacecommand{showstruts}{afiseazastruts} +\setinterfacecommand{showsymbolset}{afiseazasetsimboluri} +\setinterfacecommand{smallcapped}{kap} +\setinterfacecommand{someline}{olinie} +\setinterfacecommand{somewhere}{undeva} +\setinterfacecommand{space}{spatiu} +\setinterfacecommand{splitfloat}{impartefloat} +\setinterfacecommand{startalignment}{startaliniere} +\setinterfacecommand{startbackground}{startfundal} +\setinterfacecommand{startcoding}{startcodificare} +\setinterfacecommand{startcolor}{startculoare} +\setinterfacecommand{startcolumnmakeup}{startcolumnmakeup} +\setinterfacecommand{startcolumns}{startcoloane} +\setinterfacecommand{startcolumnset}{startcolumnset} +\setinterfacecommand{startcombination}{startcombinare} +\setinterfacecommand{startcomponent}{startcomponenta} +\setinterfacecommand{startdocument}{startdocument} +\setinterfacecommand{startenvironment}{startmediu} +\setinterfacecommand{startfigure}{startfigura} +\setinterfacecommand{startglobal}{startglobal} +\setinterfacecommand{startline}{startlinie} +\setinterfacecommand{startlinecorrection}{startcorectielinie} +\setinterfacecommand{startlinenumbering}{startnumerotarelinii} +\setinterfacecommand{startlines}{startlinii} +\setinterfacecommand{startlocal}{startlocal} +\setinterfacecommand{startlocalfootnotes}{startnotesubsollocale} +\setinterfacecommand{startmakeup}{startmakeup} +\setinterfacecommand{startmarginblock}{startblocmarginal} +\setinterfacecommand{startmarginrule}{startliniemargine} +\setinterfacecommand{startnarrower}{startingust} +\setinterfacecommand{startopposite}{startopozit} +\setinterfacecommand{startoverlay}{startoverlay} +\setinterfacecommand{startoverzicht}{startoverview} +\setinterfacecommand{startpacked}{startimpachetat} +\setinterfacecommand{startpositioning}{startpozitionare} +\setinterfacecommand{startproduct}{startprodus} +\setinterfacecommand{startprofile}{startprofil} +\setinterfacecommand{startproject}{startproiect} +\setinterfacecommand{startquotation}{startcitat} +\setinterfacecommand{startraster}{startraster} +\setinterfacecommand{startsymbolset}{startsetsimboluri} +\setinterfacecommand{startsynchronization}{startsincronizare} +\setinterfacecommand{starttable}{starttabel} +\setinterfacecommand{starttables}{starttabele} +\setinterfacecommand{starttext}{starttext} +\setinterfacecommand{starttextrule}{startriglatext} +\setinterfacecommand{startunpacked}{startneimpachetat} +\setinterfacecommand{startversion}{startversiune} +\setinterfacecommand{stopalignment}{stopaliniere} +\setinterfacecommand{stopbackground}{stopfundal} +\setinterfacecommand{stopcoding}{stopcodificare} +\setinterfacecommand{stopcolor}{stopculoare} +\setinterfacecommand{stopcolumnmakeup}{stopcolumnmakeup} +\setinterfacecommand{stopcolumns}{stopcoloane} +\setinterfacecommand{stopcolumnset}{stopcolumnset} +\setinterfacecommand{stopcombination}{stopcombinare} +\setinterfacecommand{stopcomponent}{stopcomponenta} +\setinterfacecommand{stopdocument}{stopdocument} +\setinterfacecommand{stopenvironment}{stopmediu} +\setinterfacecommand{stopglobal}{stopblobal} +\setinterfacecommand{stopline}{stoplinie} +\setinterfacecommand{stoplinecorrection}{stopcorectielinie} +\setinterfacecommand{stoplinenumbering}{stopnumerotarelinii} +\setinterfacecommand{stoplines}{stoplinii} +\setinterfacecommand{stoplocal}{stoplocal} +\setinterfacecommand{stoplocalfootnotes}{stopnotesubsollocale} +\setinterfacecommand{stopmakeup}{stopmakeup} +\setinterfacecommand{stopmarginblock}{stopblocmarginal} +\setinterfacecommand{stopmarginrule}{stopliniemargine} +\setinterfacecommand{stopnarrower}{stopingust} +\setinterfacecommand{stopopposite}{stopopozit} +\setinterfacecommand{stopoverlay}{stopoverlay} +\setinterfacecommand{stopoverzicht}{stopoverview} +\setinterfacecommand{stoppacked}{stopimpachetat} +\setinterfacecommand{stoppositioning}{stoppozitionare} +\setinterfacecommand{stopproduct}{stopprodus} +\setinterfacecommand{stopprofile}{stopprofil} +\setinterfacecommand{stopproject}{stopproiect} +\setinterfacecommand{stopquotation}{stopcitat} +\setinterfacecommand{stopraster}{stopraster} +\setinterfacecommand{stopsynchronization}{stopsincronizare} +\setinterfacecommand{stoptable}{stoptabel} +\setinterfacecommand{stoptables}{stoptabele} +\setinterfacecommand{stoptext}{stoptext} +\setinterfacecommand{stoptextrule}{stopriglatext} +\setinterfacecommand{stopunpacked}{stopneimpachetat} +\setinterfacecommand{stopversion}{stopversiune} +\setinterfacecommand{stretched}{intins} +\setinterfacecommand{subformulanumber}{numarsubformula} +\setinterfacecommand{subpagenumber}{subpagenumber} +\setinterfacecommand{switchtobodyfont}{trecilafonttext} +\setinterfacecommand{switchtorawfont}{trecilafontraw} +\setinterfacecommand{sym}{sim} +\setinterfacecommand{symbol}{simbol} +\setinterfacecommand{synchronizationbar}{barasincronizare} +\setinterfacecommand{synchronize}{sincronizeaza} +\setinterfacecommand{tab}{tab} +\setinterfacecommand{testcolumn}{testcolumn} +\setinterfacecommand{testpage}{testpage} +\setinterfacecommand{tex}{tex} +\setinterfacecommand{textheight}{inaltimetext} +\setinterfacecommand{textreference}{referintatext} +\setinterfacecommand{textrule}{riglatext} +\setinterfacecommand{textvariable}{variabilatext} +\setinterfacecommand{textwidth}{latimetext} +\setinterfacecommand{thinrule}{liniesubtire} +\setinterfacecommand{thinrules}{liniisubtiri} +\setinterfacecommand{tooltip}{tooltip} +\setinterfacecommand{topdistance}{distantasus} +\setinterfacecommand{topheight}{inaltimesus} +\setinterfacecommand{topspace}{spatiusus} +\setinterfacecommand{totalnumberofpages}{numartotalpagini} +\setinterfacecommand{translate}{traduce} +\setinterfacecommand{txt}{txt} +\setinterfacecommand{typ}{typ} +\setinterfacecommand{type}{type} +\setinterfacecommand{typebuffer}{scriebuffer} +\setinterfacecommand{typefile}{typefile} +\setinterfacecommand{unitmeaning}{numeunitate} +\setinterfacecommand{unknown}{necunoscut} +\setinterfacecommand{useJSscripts}{folosestescriptJS} +\setinterfacecommand{useURL}{folosesteURL} +\setinterfacecommand{useXMLfilter}{useXMLfilter} +\setinterfacecommand{useblocks}{folosestebloc} +\setinterfacecommand{usecommands}{folosestecomenzi} +\setinterfacecommand{useencoding}{folosestecodificarea} +\setinterfacecommand{useexternaldocument}{folosestedocumentextern} +\setinterfacecommand{useexternalfigure}{folosestefiguraexterna} +\setinterfacecommand{useexternalfile}{folosestefisierextern} +\setinterfacecommand{useexternalfiles}{folosestefisiereexterne} +\setinterfacecommand{useexternalsoundtrack}{folosestemuzicaexterna} +\setinterfacecommand{usemodule}{folosestemodul} +\setinterfacecommand{usemodules}{folosestemodule} +\setinterfacecommand{usepath}{folosestedirector} +\setinterfacecommand{usereferences}{folosestereferinte} +\setinterfacecommand{usespecials}{folosestespeciale} +\setinterfacecommand{usesymbols}{folosestesimboluri} +\setinterfacecommand{usetypescript}{usetypescript} +\setinterfacecommand{usetypescriptfile}{usetypescriptfile} +\setinterfacecommand{useurl}{folosesteurl} +\setinterfacecommand{version}{versiune} +\setinterfacecommand{vl}{vl} +\setinterfacecommand{weekday}{zidinsaptamana} +\setinterfacecommand{whitespace}{spatiualb} +\setinterfacecommand{wordright}{cuvantdreapta} +\setinterfacecommand{writebetweenlist}{scrieintreliste} +\setinterfacecommand{writetolist}{scrieinlista} +\setinterfacecommand{writetoreferencelist}{scrieinlistareferinte} +\setinterfacecommand{writetoregister}{scrieinregistru} +% +\endinput \ No newline at end of file diff --git a/tex/context/base/mult-sys.tex b/tex/context/base/mult-sys.tex new file mode 100644 index 000000000..d48ce0a94 --- /dev/null +++ b/tex/context/base/mult-sys.tex @@ -0,0 +1,882 @@ +%D \module +%D [ file=mult-sys, +%D version=1996.06.01, +%D title=\CONTEXT\ Multilingual 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. + +%D In boring module we define a lot of obscure but useful +%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} + +\unprotect + +%D The constants are grouped in such a way that there is a +%D minimal change of conflicts. +%D +%D \starttyping +%D \definesystemconstants {word} +%D \definemessageconstant {word} +%D \stoptyping +%D +%D This commands generate \type{\s!word} and \type{\m!word}. + +\definesystemconstant {hans} +\definesystemconstant {taco} + +%D First we define some system constants used for both the +%D multi||lingual interface and multi||linguag typesetting. + +\definesystemconstant {afrikaans} \definesystemconstant {af} +\definesystemconstant {arabic} \definesystemconstant {ar} +\definesystemconstant {catalan} \definesystemconstant {ca} +\definesystemconstant {chinese} \definesystemconstant {cn} +\definesystemconstant {croatian} \definesystemconstant {hr} +\definesystemconstant {czech} \definesystemconstant {cs} \definesystemconstant {cz} +\definesystemconstant {danish} \definesystemconstant {da} +\definesystemconstant {dutch} \definesystemconstant {nl} +\definesystemconstant {english} \definesystemconstant {en} +\definesystemconstant {finish} \definesystemconstant {fi} +\definesystemconstant {french} \definesystemconstant {fr} +\definesystemconstant {german} \definesystemconstant {de} +\definesystemconstant {hungarian} \definesystemconstant {hu} +\definesystemconstant {italian} \definesystemconstant {it} +\definesystemconstant {latin} \definesystemconstant {la} +\definesystemconstant {lithuanian} \definesystemconstant {lt} +\definesystemconstant {bokmal} \definesystemconstant {nb} \definesystemconstant {norwegian} \definesystemconstant {no} +\definesystemconstant {nynorsk} \definesystemconstant {nn} +\definesystemconstant {polish} \definesystemconstant {pl} +\definesystemconstant {persian} \definesystemconstant {pe} +\definesystemconstant {portuguese} \definesystemconstant {pt} +\definesystemconstant {romanian} \definesystemconstant {ro} +\definesystemconstant {russian} \definesystemconstant {ru} +\definesystemconstant {slovak} \definesystemconstant {sk} +\definesystemconstant {slovenian} \definesystemconstant {sl} +\definesystemconstant {slovene} +\definesystemconstant {spanish} \definesystemconstant {es} +\definesystemconstant {swedish} \definesystemconstant {sv} +\definesystemconstant {turkish} \definesystemconstant {tr} +\definesystemconstant {turkmen} \definesystemconstant {tk} +\definesystemconstant {gbenglish} \definesystemconstant {gb} \definesystemconstant {ukenglish} \definesystemconstant {uk} +\definesystemconstant {usenglish} \definesystemconstant {us} +\definesystemconstant {ukrainian} \definesystemconstant {ua} +\definesystemconstant {greek} \definesystemconstant {gr} +\definesystemconstant {ancientgreek} \definesystemconstant {agr} +\definesystemconstant {vietnamese} \definesystemconstant {vi} \definesystemconstant {vn} + +%D For proper \UNICODE\ support we need a few font related +%D constants. + +\definesystemconstant {BoldItalic} +\definesystemconstant {BoldSlanted} +\definesystemconstant {Bold} +\definesystemconstant {Italic} +\definesystemconstant {Regular} +\definesystemconstant {Slanted} +\definesystemconstant {Unicode} + +\definesystemconstant {Serif} \definesystemconstant {Regular} +\definesystemconstant {Sans} \definesystemconstant {Support} +\definesystemconstant {Mono} \definesystemconstant {Type} +\definesystemconstant {Math} +\definesystemconstant {Handwriting} +\definesystemconstant {Calligraphy} +\definesystemconstant {Casual} + +\definesystemconstant {SerifBold} \definesystemconstant {SansBold} \definesystemconstant {MonoBold} +\definesystemconstant {SerifItalic} \definesystemconstant {SansItalic} \definesystemconstant {MonoItalic} +\definesystemconstant {SerifBoldItalic} \definesystemconstant {SansBoldItalic} \definesystemconstant {MonoBoldItalic} +\definesystemconstant {SerifSlanted} \definesystemconstant {SansSlanted} \definesystemconstant {MonoSlanted} +\definesystemconstant {SerifBoldSlanted} \definesystemconstant {SansBoldSlanted} \definesystemconstant {MonoBoldSlanted} +\definesystemconstant {SerifCaps} \definesystemconstant {SansCaps} \definesystemconstant {MonoCaps} + +\definesystemconstant {Normal} +\definesystemconstant {Caps} + +\definesystemconstant {mnem} % kind of generic short tag + +\definesystemconstant {file} +\definesystemconstant {name} +\definesystemconstant {spec} + +\definesystemconstant {serif} +\definesystemconstant {sans} +\definesystemconstant {mono} +\definesystemconstant {math} +\definesystemconstant {handwriting} +\definesystemconstant {calligraphy} +\definesystemconstant {casual} +\definesystemconstant {fax} + +\definesystemconstant {fallback} + +\definesystemconstant {none} +\definesystemconstant {default} +\definesystemconstant {smallcaps} + +%D As the name of their define command states, the next set of +%D constants is used in the message macro's. + +\definemessageconstant {check} +\definemessageconstant {colors} +\definemessageconstant {columns} +\definemessageconstant {encodings} +\definemessageconstant {regimes} +\definemessageconstant {figures} +\definemessageconstant {fields} +\definemessageconstant {files} +\definemessageconstant {floatblocks} +\definemessageconstant {fonts} +\definemessageconstant {handlings} +\definemessageconstant {interactions} +\definemessageconstant {javascript} +\definemessageconstant {layouts} +\definemessageconstant {linguals} +\definemessageconstant {references} +\definemessageconstant {specials} +\definemessageconstant {structures} +\definemessageconstant {symbols} +\definemessageconstant {systems} +\definemessageconstant {lua} +\definemessageconstant {textblocks} +\definemessageconstant {verbatims} +\definemessageconstant {versions} +\definemessageconstant {metapost} +\definemessageconstant {chemicals} +\definemessageconstant {publications} + +%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} +\definesystemconstant {default} +\definesystemconstant {unknown} +\definesystemconstant {action} +\definesystemconstant {compare} +\definesystemconstant {do} +\definesystemconstant {dodo} +\definesystemconstant {complex} +\definesystemconstant {simple} +\definesystemconstant {start} +\definesystemconstant {stop} +\definesystemconstant {dummy} +\definesystemconstant {local} +\definesystemconstant {global} +\definesystemconstant {done} +\definesystemconstant {font} +\definesystemconstant {link} +\definesystemconstant {parent} +\definesystemconstant {clone} +\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} +\definesystemconstant {haslevel} + +\definesystemconstant {mkiv} +\definesystemconstant {mkii} +\definesystemconstant {entities} + +\definesystemconstant {normal} +\definesystemconstant {bold} +\definesystemconstant {italic} +\definesystemconstant {slanted} + +\definesystemconstant {default} +\definesystemconstant {smallcaps} + +%D A more experienced \TEX\ user will recognize the next four +%D constants. We need these because font-definitions are +%D partially english. + +\definesystemconstant {run} + +\definesystemconstant {fam} +\definesystemconstant {text} +\definesystemconstant {script} +\definesystemconstant {scriptscript} + +\definesystemconstant {lefthyphenmin} +\definesystemconstant {righthyphenmin} + +\definesystemconstant {skewchar} +\definesystemconstant {hyphenchar} +\definesystemconstant {catcodes} +\definesystemconstant {encoding} +\definesystemconstant {resource} +\definesystemconstant {mapping} +\definesystemconstant {language} +\definesystemconstant {patterns} +\definesystemconstant {rname} +\definesystemconstant {rscale} +\definesystemconstant {handling} +\definesystemconstant {features} +\definesystemconstant {fallbacks} +\definesystemconstant {background} +\definesystemconstant {ucmap} + +\definesystemconstant {property} +\definesystemconstant {overprint} +\definesystemconstant {layer} +\definesystemconstant {effect} +\definesystemconstant {negative} +\definesystemconstant {color} +\definesystemconstant {transparency} + +\definesystemconstant {black} +\definesystemconstant {white} + +\definesystemconstant {format} +\definesystemconstant {extensions} +\definesystemconstant {initializations} + +%D Just to be complete we define the standard \TEX\ units. + +\definesystemconstant {cm} +\definesystemconstant {em} +\definesystemconstant {ex} +\definesystemconstant {mm} +\definesystemconstant {pt} +\definesystemconstant {sp} +\definesystemconstant {bp} +\definesystemconstant {in} +\definesystemconstant {pc} +\definesystemconstant {cm} +\definesystemconstant {dd} +\definesystemconstant {cc} +\definesystemconstant {nd} +\definesystemconstant {nc} + +%D These constants are used for internal and utility +%D commands. + +\definesystemconstant {check} +\definesystemconstant {reset} +\definesystemconstant {set} + +\definesystemconstant {entrya} +\definesystemconstant {entryb} +\definesystemconstant {entryc} +\definesystemconstant {entryd} +\definesystemconstant {entry} +\definesystemconstant {see} +\definesystemconstant {from} +\definesystemconstant {to} +\definesystemconstant {line} +\definesystemconstant {page} +\definesystemconstant {realpage} +\definesystemconstant {userpage} +\definesystemconstant {subpage} + +\definesystemconstant {synonym} + +\definesystemconstant {reference} +\definesystemconstant {main} + +\definesystemconstant {list} + +\definesystemconstant {item} +\definesystemconstant {itemcount} + +\definesystemconstant {number} +\definesystemconstant {references} +\definesystemconstant {between} +\definesystemconstant {format} +\definesystemconstant {old} + +\definesystemconstant {thisisblock} +\definesystemconstant {thiswasblock} + +\definesystemconstant {figurepreset} + +\definesystemconstant {empty} + +%D Some \CONTEXT\ commands take a two||pass aproach to +%D optimize the typesetting. Each two||pass object has its +%D own tag. + +\definesystemconstant {pass} + +\definesystemconstant {data} +\definesystemconstant {float} +\definesystemconstant {list} +\definesystemconstant {page} +\definesystemconstant {subpage} +\definesystemconstant {margin} +\definesystemconstant {profile} +\definesystemconstant {versionbegin} +\definesystemconstant {versionend} +\definesystemconstant {cross} +\definesystemconstant {paragraph} + +%D A lot of macros use tags to distinguish between different +%D objects, e.g. lists and registers. + +\definesystemconstant {prt} % part (deel) +\definesystemconstant {chp} % chapter (hoofdstuk) +\definesystemconstant {sec} % section (paragraaf) +\definesystemconstant {tit} % title (titel) +\definesystemconstant {sub} % subject (onderwerp) +\definesystemconstant {mar} % margin (marge) +\definesystemconstant {num} % number (doornummeren) +\definesystemconstant {def} % definition (doordefinieren) +\definesystemconstant {for} % formula (formule) +\definesystemconstant {fnt} % footnote (voetnoot) +\definesystemconstant {ind} % index (register) +\definesystemconstant {lin} % linked index +\definesystemconstant {lst} % list (opsomming) +\definesystemconstant {flt} % float (plaatsblok) +\definesystemconstant {pag} % page (pagina) +\definesystemconstant {txt} % text (tekst) +\definesystemconstant {ref} % reference (verwijzing) +\definesystemconstant {lab} % label (label) +\definesystemconstant {aut} % automatic (inhoud, index) +\definesystemconstant {vwa} % automatic (illustrations) +\definesystemconstant {vwb} % automatic (illustrations) + +\definesystemconstant {kop} % kop % still dutch + +%D Reference labels can be tagged by users, for instance by +%D means of \type{tag:}. The reference mechanism itself uses +%D some tags too. These are definitely not to be used by users. +%D Here they are: + +\definereferenceconstant {cross} {:c:} % cross reference +\definereferenceconstant {view} {:v:} % view reference +\definereferenceconstant {viewa} {:a:} % view reference test a +\definereferenceconstant {viewb} {:b:} % view reference test b +\definereferenceconstant {page} {:p:} % page referece +\definereferenceconstant {list} {:l:} % list reference +\definereferenceconstant {exec} {:e:} % execution reference +\definereferenceconstant {form} {:m:} % form reference +\definereferenceconstant {syst} {:s:} % system reference + +\definereferenceconstant {from} {:f:} % from list reference +\definereferenceconstant {to} {:t:} % to list reference + +\definereferenceconstant {object} {:o:} % object reference +\definereferenceconstant {driver} {:d:} % driver object reference +\definereferenceconstant {widget} {:w:} % field chain reference + +\definereferenceconstant {java} {:j:} % java scripts + +%D When we use numbers and dimensions the same applies as +%D with the keywords like \type{width} and \type{plus} +%D mentioned earlier. + +\def\!!ten {10} +\def\!!twelve {12} +\def\!!hundred {100} +\def\!!thousand {1000} +\def\!!tenthousand {10000} +\def\!!maxcard {65536} +\def\!!medcard {32768} + +\def\!!zeropoint {0pt} +\def\!!onepoint {1pt} +\def\!!twopoint {2pt} +\def\!!threepoint {3pt} +\def\!!fourpoint {4pt} +\def\!!fivepoint {5pt} +\def\!!sixpoint {6pt} +\def\!!sevenpoint {7pt} +\def\!!eightpoint {8pt} +\def\!!ninepoint {9pt} +\def\!!tenpoint {10pt} +\def\!!elevenpoint {11pt} +\def\!!twelvepoint {12pt} +\def\!!fourteenpointfour {14.4pt} + +\let\onerealpoint\onepoint % needed for latex + +% D Another optimization is: +% +% \let\points\onepoint + +%D A rough test is: +%D +%D \starttyping +%D \def\TestMe % 7.75 sec on a P4/2G +%D {\dimen0=10\points\dimen0=10\points\dimen0=10\points\dimen0=10\points\dimen0=10\points +%D \dimen0=10\points\dimen0=10\points\dimen0=10\points\dimen0=10\points\dimen0=10\points} +%D +%D \def\TestMe % 11.5 sec on a P4/2G +%D {\dimen0=10pt\dimen0=10pt\dimen0=10pt\dimen0=10pt\dimen0=10pt% +%D \dimen0=10pt\dimen0=10pt\dimen0=10pt\dimen0=10pt\dimen0=10pt} +%D +%D \def\TestMe % 12.5 sec on a P4/2G +%D {\dimen0=10\s!pt\dimen0=10\s!pt\dimen0=10\s!pt\dimen0=10\s!pt\dimen0=10\s!pt% +%D \dimen0=10\s!pt\dimen0=10\s!pt\dimen0=10\s!pt\dimen0=10\s!pt\dimen0=10\s!pt} +%D +%D \testfeatureonce {500000}{\TestMe} +%D \stoptyping + +%D Variables are composed of a command specific tag and a user +%D supplied variable (system constant). The first tag \type{ag} +%D for instance is available as \type{\??ag} and expands to +%D \type{@@ag} in composed variables. + +% vervallen : hd hr hm vt vr vm tr tn te br bm bo on om or + +\definesystemvariable {ab} % AlignedBoxes +\definesystemvariable {ac} % ACcent +\definesystemvariable {ae} % AttributEs +\definesystemvariable {ag} % AchterGrond +\definesystemvariable {al} % ALinea's +\definesystemvariable {am} % interActieMenu +\definesystemvariable {an} % ANchor +\definesystemvariable {as} % AlignmentSwitch +\definesystemvariable {at} % ATtachments +\definesystemvariable {ba} % synchronisatieBAlk +\definesystemvariable {be} % startstop (BeginEnd) +\definesystemvariable {bj} % BlokJe +\definesystemvariable {bk} % Blokken (floats) +\definesystemvariable {bl} % BLanko +\definesystemvariable {bg} % BleedinG +\definesystemvariable {bo} % BlankO (definitions) +\definesystemvariable {bp} % BreakPoint +\definesystemvariable {br} % sideBaR +\definesystemvariable {bs} % SelecteerBlokken +\definesystemvariable {bt} % BuTton +\definesystemvariable {bu} % BUffer +\definesystemvariable {bv} % Brieven +\definesystemvariable {by} % Per +\definesystemvariable {cb} % CollectBox +\definesystemvariable {cc} % Comment +\definesystemvariable {ce} % CasEs +\definesystemvariable {ch} % CHaracterspacing +\definesystemvariable {ci} % CItaat +\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) +\definesystemvariable {cs} % kleur (ColorSeparation +\definesystemvariable {cv} % ConVersie +\definesystemvariable {cy} % CrYteria +\definesystemvariable {da} % DAte +\definesystemvariable {db} % Labels +\definesystemvariable {dc} % DroppedCaps +\definesystemvariable {dd} % DoorDefinieren +\definesystemvariable {de} % DEel +\definesystemvariable {di} % DIrections +\definesystemvariable {dl} % DunneLijnen +\definesystemvariable {dn} % DoorNummeren +\definesystemvariable {dm} % DefineMeasure +\definesystemvariable {do} % DefinieerOpmaak +\definesystemvariable {du} % DUmmy +\definesystemvariable {ds} % DoorSpringen +\definesystemvariable {ef} % ExternFiguur +\definesystemvariable {ec} % EnCoding +\definesystemvariable {en} % ENvironments +\definesystemvariable {ep} % ExternfiguurPreset +\definesystemvariable {eq} % EQalign +\definesystemvariable {er} % external resources +\definesystemvariable {ex} % ExterneFiguren +\definesystemvariable {fa} % font feature +\definesystemvariable {fc} % FramedContent +\definesystemvariable {fd} % FielD +\definesystemvariable {fe} % FoxetExtensions +\definesystemvariable {ff} % FontFile +\definesystemvariable {fg} % FiGuurmaten +\definesystemvariable {fi} % FIle +\definesystemvariable {fl} % Floats +\definesystemvariable {fm} % ForMules +\definesystemvariable {fn} % subformulas +\definesystemvariable {fo} % xml FO +\definesystemvariable {fp} % FilegroeP +\definesystemvariable {fq} % Features +\definesystemvariable {fr} % ForM +\definesystemvariable {fs} % FileSynonym +\definesystemvariable {ft} % FonTs +\definesystemvariable {fu} % FontSolution +\definesystemvariable {fv} % FontVariant +\definesystemvariable {fw} % simpleFonts by Wolfgang +\definesystemvariable {fx} % FoXet +\definesystemvariable {gr} % GRid +\definesystemvariable {ha} % HAng +\definesystemvariable {hs} % HSpace +\definesystemvariable {ht} % HiddenText +\definesystemvariable {ia} % Interactie +\definesystemvariable {ib} % InteractieBalk +\definesystemvariable {ic} % ICc profiles +\definesystemvariable {id} % Index +\definesystemvariable {ig} % ItemGroup +\definesystemvariable {ih} % InHoudsopgave +\definesystemvariable {ii} % stelIndexIn +\definesystemvariable {il} % stelInvulRegelsin +\definesystemvariable {im} % InMarge +\definesystemvariable {in} % INspringen +\definesystemvariable {ip} % InsertPages +\definesystemvariable {is} % Items +\definesystemvariable {it} % stelInTerliniein +\definesystemvariable {iv} % stelInvulLijnenin +\definesystemvariable {ka} % KAntlijn +\definesystemvariable {kd} % KaDerteksten +\definesystemvariable {kj} % KopJes (floats) +\definesystemvariable {kk} % Kapitalen +\definesystemvariable {kl} % KoLommen +\definesystemvariable {km} % KenMerk +\definesystemvariable {ko} % KOp(pen) +\definesystemvariable {kp} % KopPelteken +\definesystemvariable {kr} % KoRps +\definesystemvariable {ks} % KolomSpan +\definesystemvariable {kt} % KonTakten +\definesystemvariable {kw} % KontaktWaarde +\definesystemvariable {la} % LAnguage +\definesystemvariable {lb} % LaBels +\definesystemvariable {ld} % LegenDa +\definesystemvariable {le} % LinetablE +\definesystemvariable {lf} % LocalFigures +\definesystemvariable {lg} % taal (LanGuage) +\definesystemvariable {li} % LIjst +\definesystemvariable {lk} % LinK +\definesystemvariable {ll} % Layers +\definesystemvariable {lx} % LayerteXt +\definesystemvariable {ln} % LijNen +\definesystemvariable {lo} % LOgos +\definesystemvariable {lt} % LiTeratuur +\definesystemvariable {ls} % languageScript +\definesystemvariable {ly} % LaYout +\definesystemvariable {ma} % MargeAchtergrond +\definesystemvariable {mb} % MargeBlokken +\definesystemvariable {md} % MoDule +\definesystemvariable {mg} % Metapost paGe +\definesystemvariable {mh} % MultilingualHead +\definesystemvariable {mk} % MarKering +\definesystemvariable {ml} % MultilingualLabel +\definesystemvariable {mm} % MultilingualMath +\definesystemvariable {mt} % inline MaTh +\definesystemvariable {mo} % Math Options +\definesystemvariable {mp} % MetaPost +\definesystemvariable {mx} % MatriX +\definesystemvariable {ng} % parbuilders +\definesystemvariable {nh} % new heads (structure) +\definesystemvariable {nn} % structurenumbering +\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 +\definesystemvariable {or} % OtpfilteR +\definesystemvariable {os} % OffSet +\definesystemvariable {ot} % OTpsequence +\definesystemvariable {ov} % OVerlay +\definesystemvariable {ox} % OffsetBox +\definesystemvariable {pa} % PAlet +\definesystemvariable {pb} % PuBlication +\definesystemvariable {pc} % PageComment +\definesystemvariable {pe} % PagEhandler +\definesystemvariable {pf} % ProFiel +\definesystemvariable {pg} % KoppelPagina +\definesystemvariable {ph} % ParagrapH +\definesystemvariable {pl} % PLaats +\definesystemvariable {pn} % PaginaNummer +\definesystemvariable {po} % PrOcessor +\definesystemvariable {pp} % PaPier +\definesystemvariable {pr} % PRogrammas +\definesystemvariable {ps} % PoSitioneren +\definesystemvariable {pt} % PageshifT +\definesystemvariable {py} % PropertYs +\definesystemvariable {pv} % PublicationVariable +\definesystemvariable {ra} % RAise +\definesystemvariable {rd} % RenDering +\definesystemvariable {rf} % ReFereren +\definesystemvariable {rg} % ReGel +\definesystemvariable {rl} % ReferentieLijst +\definesystemvariable {rn} % RegelNummer +\definesystemvariable {ro} % ROteren +\definesystemvariable {rr} % linenotes +\definesystemvariable {rs} % RaSters +\definesystemvariable {rt} % RoosTers +\definesystemvariable {rv} % ReserVeerfiguur +\definesystemvariable {rw} % RenderingWindow +\definesystemvariable {sa} % ScAle +\definesystemvariable {sb} % SectieBlok +\definesystemvariable {sc} % SCherm +\definesystemvariable {sd} % SounD +\definesystemvariable {se} % SEctie +\definesystemvariable {sf} % SpeciFics +\definesystemvariable {sg} % SpacinG +\definesystemvariable {sh} % ShapeText +\definesystemvariable {si} % SplIt +\definesystemvariable {sk} % SectieKop +\definesystemvariable {sl} % SmalLer +\definesystemvariable {sm} % SynonieMen +\definesystemvariable {sn} % SubNummer +\definesystemvariable {so} % SOrteren +\definesystemvariable {sp} % SelecteerPapier +\definesystemvariable {sr} % SpacehandleR +\definesystemvariable {ss} % Symbool +\definesystemvariable {st} % STickers +\definesystemvariable {su} % SetUp +\definesystemvariable {sv} % SysteemVariabelen +\definesystemvariable {sw} % SectionWorld +\definesystemvariable {sx} % Selector +\definesystemvariable {sy} % SYnchronisatie +\definesystemvariable {ta} % TAb +\definesystemvariable {tb} % TekstBlokken +\definesystemvariable {td} % TextbackgrounDs +\definesystemvariable {te} % TEmplate +\definesystemvariable {tf} % TypeFace +\definesystemvariable {tg} % Tex paGe +\definesystemvariable {ti} % TabelInstellingen +\definesystemvariable {tk} % Teksten +\definesystemvariable {tl} % TekstLijnen +\definesystemvariable {tm} % TypesynonyM +\definesystemvariable {tp} % TyPen +\definesystemvariable {tx} % TeXtflow +\definesystemvariable {to} % TOlerance +\definesystemvariable {tr} % TRacer +\definesystemvariable {ts} % TypeScript +\definesystemvariable {tt} % TabulaTe +\definesystemvariable {ty} % TYpe +\definesystemvariable {uc} % Unicode +\definesystemvariable {ui} % UItvoer +\definesystemvariable {ur} % URl +\definesystemvariable {up} % Utility Program +\definesystemvariable {va} % VspAce +\definesystemvariable {ve} % VErsie +\definesystemvariable {vn} % VoetNoten +\definesystemvariable {vs} % VSpacing +\definesystemvariable {vt} % VerTical +\definesystemvariable {wr} % WitRuimte +\definesystemvariable {wl} % WordList +\definesystemvariable {xf} % XML File +\definesystemvariable {xl} % lxml (mkiv) +\definesystemvariable {xm} % xml (mkiv) +\definesystemvariable {xp} % XML Processing +\definesystemvariable {xy} % schaal +\definesystemvariable {za} % ZetspiegelAanpassing + +%D Next we define some language independant one letter +%D variables and keywords. + +\defineinterfaceconstant {x} {x} % x offset +\defineinterfaceconstant {y} {y} % y offset +\defineinterfaceconstant {w} {w} % width +\defineinterfaceconstant {h} {h} % height +\defineinterfaceconstant {s} {s} % size +\defineinterfaceconstant {t} {t} % title +\defineinterfaceconstant {c} {c} % creator +\defineinterfaceconstant {e} {e} % extension +\defineinterfaceconstant {f} {f} % file + +\defineinterfaceconstant {a} {a} % kunnen weg +\defineinterfaceconstant {b} {b} % kunnen weg +\defineinterfaceconstant {c} {c} % kunnen weg +\defineinterfaceconstant {d} {d} % kunnen weg +\defineinterfaceconstant {e} {e} % kunnen weg + +\defineinterfaceconstant {s} {s} +\defineinterfaceconstant {r} {r} +\defineinterfaceconstant {g} {g} +\defineinterfaceconstant {b} {b} +\defineinterfaceconstant {c} {c} +\defineinterfaceconstant {m} {m} +\defineinterfaceconstant {y} {y} +\defineinterfaceconstant {k} {k} +\defineinterfaceconstant {a} {a} % alternative +\defineinterfaceconstant {t} {t} % transparency +\defineinterfaceconstant {p} {p} % percentage + +\defineinterfaceconstant {t} {t} +\defineinterfaceconstant {h} {h} +\defineinterfaceconstant {b} {b} + +\defineinterfaceconstant {rgb} {rgb} +\defineinterfacevariable {rgb} {rgb} + +\defineinterfaceconstant {cmyk} {cmyk} +\defineinterfacevariable {cmyk} {cmyk} + +\defineinterfaceconstant {mp} {mp} +\defineinterfacevariable {mp} {mp} + +\defineinterfacevariable {s} {s} + +\defineinterfacevariable {a} {a} +\defineinterfacevariable {b} {b} +\defineinterfacevariable {c} {c} +\defineinterfacevariable {d} {d} + +%D Special purpose variables: + +\def\v!oddeven#1{\ifodd#1\v!odd\else\v!even\fi} + +%D The names of files and their extensions are fixed. +%D \CONTEXT\ uses as less files as possible. Utility files can +%D be recognized by the first two characters of the extension: +%D \type{tu}. + +\definefileconstant {utilityfilename} {texutil} + +\definefileconstant {blockextension} {tub} +\definefileconstant {figureextension} {tuf} +\definefileconstant {inputextension} {tui} +\definefileconstant {outputextension} {tuo} % tup for previous run +\definefileconstant {optionextension} {top} +\definefileconstant {temporaryextension} {tmp} +\definefileconstant {patternsextension} {pat} +\definefileconstant {hyphensextension} {hyp} +\definefileconstant {fontmapextension} {map} +\definefileconstant {bibextension} {bbl} + +%D These files are loaded at start||up. They may contain system +%D specific setups (or calls to other files), old macro's, to +%D garantee compatibility and new macro's noy yet present in +%D the format. + +\definefileconstant {errfilename} {cont-err} +\definefileconstant {sysfilename} {cont-sys} +\definefileconstant {oldfilename} {cont-old} +\definefileconstant {newfilename} {cont-new} +\definefileconstant {filfilename} {cont-fil} +\definefileconstant {modfilename} {cont-mod} + +%D Handy for typescripts (we could use s! instead: + +\definetypescriptconstant {name} {name} +\definetypescriptconstant {default} {default} +\definetypescriptconstant {map} {map} +\definetypescriptconstant {special} {special} +\definetypescriptconstant {size} {size} + +%D The next two files specify user settings as well as +%D \TEXEXEC\ settings when generating a format. + +\definefileconstant {usrfilename} {cont-usr} % .tex +\definefileconstant {fmtfilename} {cont-fmt} % .tex + +%D The setup files for the language, font, color and special +%D subsystems have a common prefix. This means that we have at +%D most three characters for unique filenames. + +\definefileconstant {colorprefix} {colo-} +\definefileconstant {encodingprefix} {enco-} +\definefileconstant {filterprefix} {filt-} +\definefileconstant {fontprefix} {font-} +\definefileconstant {handlingprefix} {hand-} +\definefileconstant {javascriptprefix} {java-} +\definefileconstant {languageprefix} {lang-} +\definefileconstant {mathprefix} {math-} +\definefileconstant {metapostprefix} {meta-} +\definefileconstant {regimeprefix} {regi-} +\definefileconstant {specialprefix} {spec-} +\definefileconstant {symbolprefix} {symb-} +\definefileconstant {typeprefix} {type-} +\definefileconstant {xtagprefix} {xtag-} +\definefileconstant {propprefix} {prop-} +\definefileconstant {unicprefix} {unic-} +\definefileconstant {sortprefix} {sort-} +\definefileconstant {prettyprefix} {pret-} + +\definefileconstant {moduleprefix} {m-} +\definefileconstant {styleprefix} {s-} +\definefileconstant {xstyleprefix} {x-} +\definefileconstant {privateprefix} {p-} +\definefileconstant {thirdprefix} {t-} + +%definefileconstant {beforeprefix} {b-} +%definefileconstant {afterprefix} {a-} + +%D \CONTEXT\ follows different strategies for finding files. +%D The macros that are responsible for this 'clever' searching +%D make use of two (very important) path specifiers. + +\definefileconstant {pathseparator} {/} +\definefileconstant {currentpath} {.} +\definefileconstant {parentpath} {..} + +%D The way fonts are defined and called upon is language +%D independant. We follow the scheme laid down by Knuth in +%D Plain \TEX. We'll explain their meaning later. + +\defineinterfaceconstant {tf} {tf} +\defineinterfaceconstant {bf} {bf} +\defineinterfaceconstant {bs} {bs} +\defineinterfaceconstant {bi} {bi} +\defineinterfaceconstant {sl} {sl} +\defineinterfaceconstant {it} {it} +\defineinterfaceconstant {sc} {sc} +\defineinterfaceconstant {rm} {rm} +\defineinterfaceconstant {ss} {ss} +\defineinterfaceconstant {tt} {tt} +\defineinterfaceconstant {hw} {hw} +\defineinterfaceconstant {cg} {cg} +\defineinterfaceconstant {os} {os} +\defineinterfaceconstant {mm} {mm} +\defineinterfaceconstant {i} {i} +\defineinterfaceconstant {nn} {nn} + +\defineinterfaceconstant {x} {x} +\defineinterfaceconstant {xx} {xx} + +\defineinterfaceconstant {em} {em} + +\defineinterfaceconstant {mi} {mi} +\defineinterfaceconstant {sy} {sy} +\defineinterfaceconstant {ex} {ex} +\defineinterfaceconstant {mr} {mr} + +\defineinterfaceconstant {ma} {ma} +\defineinterfaceconstant {mb} {mb} +\defineinterfaceconstant {mc} {mc} + +%D For figure inclusion we need: + +\defineinterfaceconstant {tif} {tif} +\defineinterfaceconstant {eps} {eps} +\defineinterfaceconstant {mps} {mps} +\defineinterfaceconstant {jpg} {jpg} +\defineinterfaceconstant {pdf} {pdf} +\defineinterfaceconstant {png} {png} +\defineinterfaceconstant {avi} {avi} +\defineinterfaceconstant {mov} {mov} +\defineinterfaceconstant {svg} {svg} +\defineinterfaceconstant {tex} {tex} +\defineinterfaceconstant {tmp} {tmp} + +%D A careful reader will have noticed that in the module +%D \type{mult-ini} we defined \type{\selectinterface}. We were +%D not yet able to actually select an interface, because we +%D still had to define the constants and variables. Now we've +%D done so, selection is permitted. + +\selectinterface + +%D Ok, here are some more, because we've got ouselves some +%D extensions to \CONTEXT. + +\definemessageconstant {addresses} +\definemessageconstant {documents} + +\protect + +\endinput diff --git a/tex/context/base/node-aux.lua b/tex/context/base/node-aux.lua new file mode 100644 index 000000000..9ed71fd72 --- /dev/null +++ b/tex/context/base/node-aux.lua @@ -0,0 +1,145 @@ +if not modules then modules = { } end modules ['node-aux'] = { + version = 1.001, + comment = "companion to node-spl.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local gsub, format = string.gsub, string.format + +local free_node = node.free +local hpack_nodes = node.hpack +local node_fields = node.fields + +function nodes.repack_hlist(list,...) + local temp, b = hpack_nodes(list,...) + list = temp.list + temp.list = nil + free_node(temp) + return list, b +end + +function nodes.merge(a,b) + if a and b then + local t = node.fields(a.id) + for i=3,#t do + local name = t[i] + a[name] = b[name] + end + end + return a, b +end + +local fields, whatsitfields = { }, { } + +for k, v in next, node.types() do + if v == "whatsit" then + fields[k], fields[v] = { }, { } + for kk, vv in next, node.whatsits() do + local f = node_fields(k,kk) + whatsitfields[kk], whatsitfields[vv] = f, f + end + else + local f = node_fields(k) + fields[k], fields[v] = f, f + end +end + +nodes.fields, nodes.whatsitfields = fields, whatsitfields + +function nodes.info(n) + local id = n.id + local tp = node.type(id) + local list = (tp == "whatsit" and whatsitfields[n.subtype]) or fields[id] + logs.report(format("%14s","type"),tp) + for k,v in next, list do + logs.report(format("%14s",v),gsub(gsub(tostring(n[v]),"%s+"," "),"node ","")) + end +end + +-- history: +-- +-- local function cp_skipable(a,id) -- skipable nodes at the margins during character protrusion +-- return ( +-- id ~= glyph_node +-- or id == ins_node +-- or id == mark_node +-- or id == adjust_node +-- or id == penalty_node +-- or (id == glue_node and a.spec.writable) +-- or (id == disc_node and a.pre == nil and a.post == nil and a.replace == nil) +-- or (id == math_node and a.surround == 0) +-- or (id == kern_node and (a.kern == 0 or a.subtype == NORMAL)) +-- or (id == hlist_node and a.width == 0 and a.height == 0 and a.depth == 0 and a.list == nil) +-- or (id == whatsit_node and a.subtype ~= pdf_refximage_node and a.subtype ~= pdf_refxform_node) +-- ) +-- end +-- +-- local function glyph_width(a) +-- local ch = chardata[a.font][a.char] +-- return (ch and ch.width) or 0 +-- end +-- +-- local function glyph_total(a) +-- local ch = chardata[a.font][a.char] +-- return (ch and (ch.height+ch.depth)) or 0 +-- end +-- +-- local function non_discardable(a) -- inline +-- return a.id < math_node -- brrrr +-- end +-- +-- local function calculate_badness(t,s) +-- if t == 0 then +-- return 0 +-- elseif s <= 0 then +-- return INF_BAD +-- else +-- local r +-- if t <= 7230584 then +-- r = t * 297 / s +-- elseif s >= 1663497 then +-- r = t / floor(s / 297) +-- else +-- r = t +-- end +-- r = floor(r) +-- if r > 1290 then +-- return INF_BAD +-- else +-- return floor((r * r * r + 0x20000) / 0x40000) -- 0400000 / 01000000 +-- end +-- end +-- end +-- +-- left-overs +-- +-- local function round_xn_over_d(x, n, d) +-- local positive -- was x >= 0 +-- if x >= 0 then +-- positive = true +-- else +-- x = -x +-- positive = false +-- end +-- local t = floor(x % 0x8000) * n -- 0100000 +-- local f = floor(t / 0x8000) -- 0100000 +-- local u = floor(x / 0x8000) * n + f -- 0100000 +-- local v = floor(u % d) * 0x8000 + f -- 0100000 +-- if floor(u / d) >= 0x8000 then -- 0100000 +-- logs.error("parbuilder",'arith_error') +-- else +-- u = 0x8000 * floor(u / d) + floor(v / d) -- 0100000 +-- end +-- v = floor(v % d) +-- if 2*v >= d then +-- u = u + 1 +-- end +-- if positive then +-- return u +-- else +-- return -u +-- end +-- end + diff --git a/tex/context/base/node-bck.lua b/tex/context/base/node-bck.lua new file mode 100644 index 000000000..94fbac85f --- /dev/null +++ b/tex/context/base/node-bck.lua @@ -0,0 +1,119 @@ +if not modules then modules = { } end modules ['node-bck'] = { + version = 1.001, + comment = "companion to node-bck.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- beware, this one takes quite some runtime, so we need a status flag +-- maybe some page related state + +local hlist = node.id("hlist") +local vlist = node.id("vlist") + +local has_attribute = node.has_attribute +local set_attribute = node.set_attribute +local traverse = node.traverse + +local new_rule = nodes.rule +local new_glue = nodes.glue + +local a_color = attributes.private('color') +local a_transparency = attributes.private('transparency') +local a_colorspace = attributes.private('colormodel') +local a_background = attributes.private('background') + +local function add_backgrounds(head) -- boxes, inline will be done too + local id = head.id + if id == vlist or id == hlist then + local current = head.list + while current do + local id = current.id + if id == hlist then -- and current.list + local background = has_attribute(current,a_background) + if background then + -- direct to hbox + -- colorspace is already set so we can omit that and stick to color + local mode = has_attribute(current,a_colorspace) + if mode then + local glue = new_glue(-current.width) + local rule = new_rule(current.width,current.height,current.depth) + local color = has_attribute(current,a_color) + local transparency = has_attribute(current,a_transparency) + set_attribute(rule,a_colorspace, mode) + if color then + set_attribute(rule,a_color, color) + end + if transparency then + set_attribute(rule,a_transparency,transparency) + end + rule.next = glue + glue.next = current.list + current.list = rule + end + else + -- temporary hack for aligments + local list, background, found = current.list, nil, nil + for l in traverse(list) do + background = has_attribute(l,a_background) + if background then + found = l + break + end + end + if background then + local mode = has_attribute(found,a_colorspace) + if mode then + local glue = new_glue(-current.width) + local rule = new_rule(current.width,current.height,current.depth) + local color = has_attribute(found,a_color) + local transparency = has_attribute(found,a_transparency) + set_attribute(rule,a_colorspace, mode) + if color then + set_attribute(rule,a_color, color) + end + if transparency then + set_attribute(rule,a_transparency,transparency) + end + rule.next = glue + glue.next = list + current.list = rule + end + else + add_backgrounds(current) + end + end + elseif id == vlist then -- and current.list + -- direct to vbox + local background = has_attribute(current,a_background) + if background then + local mode = has_attribute(current,a_colorspace) + if mode then + local glue = new_glue(-current.height-current.depth) + local rule = new_rule(current.width,current.height,current.depth) + local color = has_attribute(current,a_color) + local transparency = has_attribute(current,a_transparency) + set_attribute(rule,a_colorspace, mode) + if color then + set_attribute(rule,a_color, color) + end + if transparency then + set_attribute(rule,a_transparency,transparency) + end + rule.next = glue + glue.next = current.list + current.list = rule + end + end + add_backgrounds(current) + end + current = current.next + end + end + return head, true +end + +nodes.add_backgrounds = add_backgrounds + +tasks.appendaction("shipouts","normalizers","nodes.add_backgrounds") diff --git a/tex/context/base/node-bck.mkiv b/tex/context/base/node-bck.mkiv new file mode 100644 index 000000000..41a6da2cb --- /dev/null +++ b/tex/context/base/node-bck.mkiv @@ -0,0 +1,163 @@ +%D \module +%D [ file=node-bck, +%D version=2009.06.08, +%D title=\CONTEXT\ Node Macros, +%D subtitle=Backgrounds, +%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 Node Support / Backgrounds} + +%D This is first attempt to replacing backgrounds in a few +%D tables mechanisms. + +\unprotect + +\registerctxluafile{node-bck}{1.001} + +%D Box helpers: + +\def\doaddbackgroundtobox#1[#2]% + {\begingroup\faststartcolor[#2]% + \normalexpanded{\noexpand\faststopcolor\endgroup#1 + attr \backgroundattribute \plusone + attr \colormodelattribute \the\attribute\colormodelattribute + attr \colorattribute \the\attribute\colorattribute + attr \transparencyattribute \the\attribute\transparencyattribute}} + +\def\backgroundvbox{\doaddbackgroundtobox\vbox} +\def\backgroundvtop{\doaddbackgroundtobox\vtop} +\def\backgroundhbox{\doaddbackgroundtobox\hbox} + +\def\colorattr#1% + {\ifcsname(cs:\currentpalet#1)\endcsname + \thecolorattr{\currentpalet#1}% + \else\ifcsname(cs:#1)\endcsname + \thecolorattr{#1}% + \fi\fi} + +\def\thecolorattr#1% + {attr \colormodelattribute \attribute\colormodelattribute + attr \colorattribute \csname(cs:#1)\endcsname + attr \transparencyattribute \csname(ts:#1)\endcsname} + +\def\backgroundcolorattr#1% + {\ifcsname(cs:\currentpalet#1)\endcsname + \thebackgroundcolorattr{\currentpalet#1}% + \else\ifcsname(cs:#1)\endcsname + \thebackgroundcolorattr{#1}% + \fi\fi} + +\def\thebackgroundcolorattr#1% + {attr \backgroundattribute \plusone + attr \colormodelattribute \attribute\colormodelattribute + attr \colorattribute \csname(cs:#1)\endcsname + attr \transparencyattribute \csname(ts:#1)\endcsname} + +% \def\backgroundvbox[#1]{\vbox \backgroundcolorattr{#1}} +% \def\backgroundvtop[#1]{\vtop \backgroundcolorattr{#1}} +% \def\backgroundhbox[#1]{\hbox \backgroundcolorattr{#1}} + +%D tabulate: + +\def\tabulatenormalcolumn#1% + {\doiffastoptionalcheckelse{\tabulatenormalcolumnyes#1}{\tabulatenormalcolumnnop#1}} + +\def\tabulatenormalcolumnnop#1% overloads anch-pgr + {&\iftabulateequal\tabulateequalpos\else\tabulatenormalpos\fi&\global\chardef\tabulatetype#1&} + +\def\tabulatenormalcolumnyes#1[#2]% + {&\iftabulateequal\tabulateequalpos\else\tabulatenormalpos\fi&\global\chardef\tabulatetype#1&% + \iftrialtypesetting\else\settabulatecolor{#2}\fi\ignorespaces} + +\newcount\maxtabularcolorcolumn + +\def\settabulatecolor#1% we could store the attributes at the cost of a lua call + {\begingroup + \global\settrue\tabulatehascolors + \ifnum\tabulatecolumn>\maxtabularcolorcolumn + \global\maxtabularcolorcolumn\tabulatecolumn + \fi + \setxvalue{\??tt:c:\the\tabulatecolumn}{#1}% + \attribute\backgroundattribute\plusone + \faststartcolor[#1]\strut\char0\faststopcolor + \endgroup} + +\def\repeatsettabulatecolor + {\begingroup + \ifcsname\??tt:c:\the\tabulatecolumn\endcsname + \attribute\backgroundattribute\plusone + \faststartcolor[\csname\??tt:c:\the\tabulatecolumn\endcsname]\strut\char0\faststopcolor + \fi + \endgroup} + +\def\resettabulatecolors + {\ifcase\maxtabularcolorcolumn\else + \doresettabulatecolors + \fi} + +\def\doresettabulatecolors + {\dorecurse\maxtabularcolorcolumn{\letgvalue{\??tt:c:\recurselevel}\undefined}} % slow + +\appendtoks + \resettabulatecolors +\to \everyaftertabulaterow + +\def\splitofftabulatebox % overloads in anch-pgr + {\dontcomplain + \global\setbox\tabulatebox % % % global ? % % % + \vsplit\tablebox\tabulatecolumn to \lineheight + \setbox\tabulatebox\normalvbox + {\unvbox\tabulatebox}% + \setbox\tabulatebox\hbox to \wd\tabulatebox + {\iftrialtypesetting\else\ifconditional\tabulatehascolors\repeatsettabulatecolor\fi\fi + \hss\dotabulatehook{\box\tabulatebox}\hss}% + \ht\tabulatebox\strutht + \dp\tabulatebox\strutdp + \box\tabulatebox + \iftrialtypesetting\else\ifconditional\tablehaspositions\doflushtabulateepos\fi\fi} + +\appendtoks + \global\setfalse\tabulatehascolors +\to \everytabulate + +\protect \endinput + +% test + +\starttext + +\backgroundvbox[green] {\input tufte } \par +\backgroundvbox[blue] {\input ward } \par +\backgroundvbox[red] {\input knuth } \par +\backgroundhbox[yellow]{\rotate[rotation=45]{hello world}} \par + +\starttabulate[||p||] +\NC test \NC test \NC test \NC \NR +\NC test \NC[green] \input tufte \NC[yellow] test \NC \NR +\NC test \NC test \NC test \NC \NR +\NC test \NC test \NC test \NC \NR +\NC test \NC test \NC test \NC \NR +\NC test \NC test \NC test \NC \NR +\NC[blue] test \NC[red] test \NC test \NC \NR +\NC test \NC test \NC test \NC \NR +\NC test \NC test \NC test \NC \NR +\NC test \NC test \NC test \NC \NR +\NC test \NC test \NC[gray] test \NC \NR +\NC test \NC test \NC test \NC \NR +\NC test \NC test \NC test \NC \NR +\NC[blue] test \NC test \NC test \NC \NR +\NC test \NC test \NC test \NC \NR +\NC test \NC test \NC[magenta] test \NC \NR +\NC test \NC test \NC test \NC \NR +\NC test \NC[cyan] \dorecurse{10}{\input ward }\NC test \NC \NR +\NC test \NC test \NC test \NC \NR +\NC test \NC[yellow] test \NC test \NC \NR +\stoptabulate + +\stoptext diff --git a/tex/context/base/node-dir.lua b/tex/context/base/node-dir.lua new file mode 100644 index 000000000..05e4835e5 --- /dev/null +++ b/tex/context/base/node-dir.lua @@ -0,0 +1,308 @@ +if not modules then modules = { } end modules ['node-mir'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + author = "Taco Hoekwater and Hans Hagen", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--[[ +

In the process of cleaning up the lua variant of the parbuilder +we ran into a couple of functions (translated c macros) that were +somewhat inefficient. More convenient is to use hashes although at +the c-end still macros are used. In the process directions.h was +adapted and now has the mappings as comments. This lua file is +based on that file. +]]-- + + +nodes = nodes or { } + +nodes.is_mirrored = { + -- TLT = false, + -- TRT = false, + -- LTL = false, + -- RTT = false, +} + +nodes.is_rotated = { + -- TLT = false, + -- TRT = false, + -- LTL = false, + RTT = true, ["+RTT"] = true, +} + +nodes.textdir_is_parallel = { + TLT = { + TLT = true, ["+TLT"] = true, + TRT = true, ["+TRT"] = true, + -- LTL = false, + -- RTT = false, + }, + TRT= { + TLT = true, ["+TLT"] = true, + TRT = true, ["+TRT"] = true, + -- LTL = false, + -- RTT = false, + }, + LTL = { + -- TLT = false, + -- TRT = false, + LTL = true, ["+LTL"] = true, + RTT = true, ["+RTT"] = true, + }, + RTT = { + -- TLT = false, + -- TRT = false, + LTL = true, ["+LTL"] = true, + RTT = true, ["+RTT"] = true, + } +} + +nodes.pardir_is_parallel = { + TLT = { + TLT = true, ["+TLT"] = true, + TRT = true, ["+TRT"] = true, + -- LTL = false, + -- RTT = false, + }, + TRT = { + TLT = true, ["+TLT"] = true, + TRT = true, ["+TRT"] = true, + -- LTL = false, + -- RTT = false, + }, + LTL = { + -- TLT = false, + -- TRT = false, + LTL = true, ["+LTL"] = true, + RTT = true, ["+RTT"] = true, + }, + RTT = { + -- TLT = false, + -- TRT = false, + LTL = true, ["+LTL"] = true, + RTT = true, ["+RTT"] = true, + }, +} + +nodes.pardir_is_opposite = { + TLT = { + -- TLT = false, + -- TRT = false, + -- LTL = false, + -- RTT = false, + }, + TRT = { + -- TLT = false, + -- TRT = false, + -- LTL = false, + -- RTT = false, + }, + LTL = { + -- TLT = false, + -- TRT = false, + -- LTL = false, + RTT = true, ["+RTT"] = true, + }, + RTT = { + -- TLT = false, + -- TRT = false, + LTL = true, ["+LTL"] = true, + -- RTT = false, + }, +} + +nodes.textdir_is_opposite = { + TLT = { + -- TLT = false, + TRT = true, ["+TRT"] = true, + -- LTL = false, + -- RTT = false, + }, + TRT= { + TLT = true, ["+TLT"] = true, + -- TRT = false, + -- LTL = false, + -- RTT = false, + }, + LTL = { + -- TLT = false, + -- TRT = false, + -- LTL = false, + -- RTT = false, + }, + RTT = { + -- TLT = false, + -- TRT = false, + -- LTL = false, + -- RTT = false, + }, +} + +nodes.glyphdir_is_opposite = { + TLT = { + -- TLT = false, + -- TRT = false, + -- LTL = false, + -- RTT = false, + }, + TRT= { + -- TLT = false, + -- TRT = false, + -- LTL = false, + -- RTT = false, + }, + LTL = { + -- TLT = false, + -- TRT = false, + -- LTL = false, + -- RTT = false, + }, + RTT = { + -- TLT = false, + -- TRT = false, + -- LTL = false, + -- RTT = false, + }, +} + +nodes.pardir_is_equal = { + TLT = { + TLT = true, ["+TLT"] = true, + TRT = true, ["+TRT"] = true, + -- LTL = false, + -- RTT = false, + }, + TRT= { + TLT = true, ["+TLT"] = true, + TRT = true, ["+TRT"] = true, + -- LTL = false, + -- RTT = false, + }, + LTL= { + -- TLT = false, + -- TRT = false, + LTL = true, ["+LTL"] = true, + -- RTT = false, + }, + RTT= { + -- TLT = false, + -- TRT = false, + -- LTL = false, + RTT = true, ["+RTT"] = true, + }, +} + +nodes.textdir_is_equal = { + TLT = { + TLT = true, ["+TLT"] = true, + -- TRT = false, + -- LTL = false, + -- RTT = false, + }, + TRT= { + -- TLT = false, + TRT = true, ["+TRT"] = true, + -- LTL = false, + -- RTT = false, + }, + LTL = { + -- TLT = false, + -- TRT = false, + LTL = true, ["+LTL"] = true, + RTT = true, ["+RTT"] = true, + }, + RTT = { + -- TLT = false, + -- TRT = false, + LTL = true, ["+LTL"] = true, + RTT = true, ["+RTT"] = true, + }, +} + +nodes.glyphdir_is_equal = { + TLT = { + TLT = true, ["+TLT"] = true, + TRT = true, ["+TRT"] = true, + -- LTL = false, + RTT = true, ["+RTT"] = true, + }, + TRT= { + TLT = true, ["+TLT"] = true, + TRT = true, ["+TRT"] = true, + -- LTL = false, + RTT = true, ["+RTT"] = true, + }, + LTL = { + -- TLT = false, + -- TRT = false, + LTL = true, ["+LTL"] = true, + -- RTT = false, + }, + RTT = { + TLT = true, ["+TLT"] = true, + TRT = true, ["+TRT"] = true, + -- LTL = false, + RTT = true, ["+RTT"] = true, + }, +} + +nodes.partextdir_is_equal = { + TLT = { + -- TLT = false, + -- TRT = false, + LTL = true, ["+LTL"] = true, + RTT = true, ["+RTT"] = true, + }, + TRT= { + -- TLT = false, + -- TRT = false, + LTL = true, ["+LTL"] = true, + RTT = true, ["+RTT"] = true, + }, + LTL = { + TLT = true, ["+TLT"] = true, + -- TRT = false, + -- LTL = false, + -- RTT = false, + }, + RTT = { + -- TLT = false, + TRT = true, ["+TRT"] = true, + -- LTL = false, + -- RTT = false, + }, +} + +nodes.textdir_is_is = { + TLT = true, ["+TLT"] = true, + -- TRT = false, + -- LTL = false, + -- RTT = false, +} + +nodes.glyphdir_is_orthogonal = { + TLT = true, ["+TLT"] = true, + TRT = true, ["+TRT"] = true, + LTL = true, ["+LTL"] = true, + -- RTT = false +} + +nodes.dir_is_pop = { + ["-TRT"] = true, + ["-TLT"] = true, + ["-LTL"] = true, + ["-RTT"] = true, +} + +nodes.dir_negation = { + ["-TRT"] = "+TRT", + ["-TLT"] = "+TLT", + ["-LTL"] = "+LTL", + ["-RTT"] = "+RTT", + ["+TRT"] = "-TRT", + ["+TLT"] = "-TLT", + ["+LTL"] = "-LTL", + ["+RTT"] = "-RTT", +} diff --git a/tex/context/base/node-dum.lua b/tex/context/base/node-dum.lua new file mode 100644 index 000000000..f39a0873f --- /dev/null +++ b/tex/context/base/node-dum.lua @@ -0,0 +1,19 @@ +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_handler(head) +-- lang.hyphenate(head) + head = nodes.process_characters(head) + nodes.inject_kerns(head) + nodes.protect_glyphs(head) + head = node.ligaturing(head) + head = node.kerning(head) + 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..5c4eec8de --- /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.mkiv", + 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..c6e3be448 --- /dev/null +++ b/tex/context/base/node-fin.lua @@ -0,0 +1,442 @@ +if not modules then modules = { } end modules ['node-fin'] = { + version = 1.001, + comment = "companion to node-fin.mkiv", + 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 + +-- the following code is no longer needed due to the new backend +-- but we keep it around for a while as an example +-- +-- 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 + local namespace = plugin.namespace + if namespace.enabled ~= false then -- this test will go away + starttiming(attributes) + local done, used, ok = false, nil, false + local attribute = namespace.attribute or numbers[plugin.name] -- todo: plugin.attribute + local processor = plugin.processor + if processor then + local initializer = plugin.initializer + local resolver = plugin.resolver + local inheritance = (resolver and resolver()) or nil -- -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 + head = flusher(namespace,attribute,head,used) + end + end + end + done = true + end + end + stoptiming(attributes) + return head, done + else + return head, false + end +end + +nodes.process_attribute = process_attribute + +function nodes.install_attribute_handler(plugin) -- we need to avoid this nested function + return function(head) + return process_attribute(head,plugin) + end +end + +--~ experiment (maybe local to function makes more sense) +--~ +--~ plugindata = { } +--~ +--~ local template = [[ +--~ local plugin = plugindata["%s"] +--~ local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming +--~ local namespace = plugin.namespace +--~ local attribute = namespace.attribute +--~ local processor = plugin.processor +--~ local initializer = plugin.initializer +--~ local resolver = plugin.resolver +--~ local finalizer = plugin.finalizer +--~ local flusher = plugin.flusher +--~ return function (head) +--~ if namespace.enabled then +--~ starttiming(attributes) +--~ local done, used, ok = false, nil, false +--~ if procesxsor then +--~ local inheritance = (resolver and resolver()) or nil -- -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 +--~ if finalizer then +--~ head, ok, used = finalizer(namespace,attribute,head) +--~ if used and flusher then +--~ head = flusher(namespace,attribute,head,used) +--~ end +--~ end +--~ done = true +--~ end +--~ end +--~ stoptiming(attributes) +--~ return head, done +--~ else +--~ return head, false +--~ end +--~ end +--~ ]] +--~ +--~ function nodes.install_attribute_handler(plugin) -- we need to avoid this nested function +--~ plugindata[plugin.name] = plugin +--~ local str = format(template,plugin.name) +--~ return loadstring(str)() +--~ end + +-- the injectors + +local insert_node_before = node.insert_before +local insert_node_after = node.insert_after + +local nsdata, nsdone, nsforced, nsselector, nstrigger +local current, current_selector, done = 0, 0, false -- nb, stack has a local current ! + +function states.initialize(namespace,attribute,head) + nsdata, nsnone = namespace.data, namespace.none + nsforced, nsselector, nslistwise = namespace.forced, namespace.selector, namespace.listwise + nstrigger = triggering and namespace.triggering and trigger + current, current_selector, done = 0, 0, false -- todo: done cleanup +end + +function states.finalize(namespace,attribute,head) -- is this one ok? + if current > 0 and nsnone then + local id = head.id + if id == hlist or id == vlist then + local list = head.list + if list then + head.list = insert_node_before(list,list,copy_node(nsnone)) + end + else + head = insert_node_before(head,head,copy_node(nsnone)) + end + return head, true, true + end + return head, false, false +end + +local function process(namespace,attribute,head,inheritance,default) -- one attribute + local stack, done = head, false + 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 + head = insert_node_before(head,stack,copy_node(nsdata[default])) + current, done = default, true + end + elseif current ~= c then + head = insert_node_before(head,stack,copy_node(nsdata[c])) + current, done = c, 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 nstrigger and has_attribute(stack,nstrigger) 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 + head = insert_node_before(head,stack,copy_node(nsdata[default])) + current, done = default, true + end + elseif current > 0 then + head = insert_node_before(head,stack,copy_node(nsnone)) + current, done = 0, true + end + elseif id == hlist or id == vlist then + local content = stack.list + if content then + local ok = false + if nstrigger and has_attribute(stack,nstrigger) 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 + 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 stack, done = head, false + 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] + head = insert_node_before(head,stack,copy_node(data[nsforced or has_attribute(stack,nsselector) or nsselector])) + current, done = default, true + end + else + local s = has_attribute(stack,nsselector) + if current ~= c or current_selector ~= s then + local data = nsdata[c] + head = insert_node_before(head,stack,copy_node(data[nsforced or has_attribute(stack,nsselector) or nsselector])) + current, current_selector, done = c, s, true + end + end + elseif default and inheritance then + if current ~= default then + local data = nsdata[default] + head = insert_node_before(head,stack,copy_node(data[nsforced or has_attribute(stack,nsselector) or nsselector])) + current, done = default, true + end + elseif current > 0 then + head = insert_node_before(head,stack,copy_node(nsnone)) + current, current_selector, done = 0, 0, 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 nstrigger and has_attribute(stack,nstrigger) 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 nstrigger and has_attribute(stack,nstrigger) 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 + stack = stack.next + end + return head, done +end + +states.selective = selective + +-- Ideally the next one should be merged with the previous but keeping it separate is +-- safer. We deal with two situations: efficient boxwise (layoutareas) and mixed layers +-- (as used in the stepper). In the stepper we cannot use the box branch as it involves +-- paragraph lines and then getsmixed up. A messy business (esp since we want to be +-- efficient). + +local function stacked(namespace,attribute,head,default) -- no triggering, no inheritance, but list-wise + local stack, done = head, false + local current, depth = default or 0, 0 + while stack do + local id = stack.id + 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 current ~= c then + head = insert_node_before(head,stack,copy_node(nsdata[c])) + depth = depth + 1 + current, done = c, true + end + if id == glue then + local content = stack.leader + if content then -- unchecked + local ok = false + stack.leader, ok = stacked(namespace,attribute,content,current) + done = done or ok + end + end + elseif default then + -- + elseif current > 0 then + head = insert_node_before(head,stack,copy_node(nsnone)) + depth = depth - 1 + current, done = 0, true + end + elseif id == hlist or id == vlist then + local content = stack.list + if content then + -- the problem is that broken lines gets the attribute which can be a later one + if nslistwise then + local c = has_attribute(stack,attribute) + if c and current ~= c and nslistwise[c] then -- viewerlayer + local p = current + current, done = c, true + head = insert_node_before(head,stack,copy_node(nsdata[c])) + stack.list = stacked(namespace,attribute,content,current) + head, stack = insert_node_after(head,stack,copy_node(nsnone)) + current = p + else + local ok = false + stack.list, ok = stacked(namespace,attribute,content,current) + done = done or ok + end + else + local ok = false + stack.list, ok = stacked(namespace,attribute,content,current) + done = done or ok + end + end + end + stack = stack.next + end + while depth > 0 do + head = insert_node_after(head,stack,copy_node(nsnone)) + depth = depth -1 + end + return head, done +end + +states.stacked = stacked + +-- -- -- + +statistics.register("attribute processing time", function() + return statistics.elapsedseconds(attributes,"front- and backend") +end) diff --git a/tex/context/base/node-fin.mkiv b/tex/context/base/node-fin.mkiv new file mode 100644 index 000000000..ea9e83f16 --- /dev/null +++ b/tex/context/base/node-fin.mkiv @@ -0,0 +1,74 @@ +%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] \chardef\triggerattribute \dogetattributeid{trigger} % feature inheritance + +\def\finalizeobjectbox #1{\ctxlua{nodes.process_page(tex.box[\number#1])}} +\def\finalizeshipoutbox#1{\ctxlua{nodes.process_page(tex.box[\number#1])}} + +% tricky stuff: + +% THIS MIGHT BECOME OBSOLETE. + +\newcount\attributeboxcount + +\edef\startinheritattributes{\attribute\triggerattribute\plusone} +\edef\stopinheritattributes {\attribute\triggerattribute\attributeunsetvalue} + +\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..b0d073425 --- /dev/null +++ b/tex/context/base/node-fnt.lua @@ -0,0 +1,207 @@ +if not modules then modules = { } end modules ['node-fnt'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + 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 + +-- this will be redone and split in a generic one and a context one + +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 in context + 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,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,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 new file mode 100644 index 000000000..36e240238 --- /dev/null +++ b/tex/context/base/node-ini.lua @@ -0,0 +1,244 @@ +if not modules then modules = { } end modules ['node-ini'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + 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 free_node = node.free +local remove_node = node.remove +local insert_node_before = node.insert_before +local insert_node_after = node.insert_after + +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 = insert_node_before +nodes.after = insert_node_after + +-- we need to test this, as it might be fixed now + +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 + +-- local h, c = nodes.replace(head,current,new) +-- local c = nodes.replace(false,current,new) +-- local c = nodes.replace(current,new) + +function nodes.replace(head,current,new) -- no head returned if false + if not new then + head, current, new = false, head, current + end + local prev, next = current.prev, current.next + if next then + new.next, next.prev = next, new + end + if prev then + new.prev, prev.next = prev, new + end + if head then + if head == current then + head = new + end + free_node(current) + return head, new + else + free_node(current) + return new + end +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, will move + +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) diff --git a/tex/context/base/node-ini.mkiv b/tex/context/base/node-ini.mkiv new file mode 100644 index 000000000..787259316 --- /dev/null +++ b/tex/context/base/node-ini.mkiv @@ -0,0 +1,90 @@ +%D \module +%D [ file=node-ini, +%D version=2006.08.20, +%D title=\CONTEXT\ Node 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 Node Support / Initialization} + +\unprotect + +\newcount\filterstate \filterstate\plusone + +\registerctxluafile{node-ini}{1.001} +\registerctxluafile{node-dir}{1.001} +\registerctxluafile{node-aux}{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 +\registerctxluafile{node-typ}{1.001} % experimental + +\newtoks \attributesresetlist + +\ifdefined \v!global \else \def\v!global{global} \fi % for metatex + +\unexpanded\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}} + +\unexpanded\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} + +\newcount\shownodescounter + +\def\shownextnodes {\afterassignment\doshownodes\shownextnodescounter} +\def\showflatnodes {\afterassignment\doshownodes\showflatnodescounter} +\def\doshownextnodes {\ctxlua{texio.write_nl('log',nodes.serializebox(\number\shownodescounter,false,true))}} +\def\doshowflatnodes {\ctxlua{texio.write_nl('log',nodes.serializebox(\number\shownodescounter,true, true))}} +\def\visualizenextnodes{\dowithnextbox{\ctxlua{nodes.visualizebox(\number\nextbox,false,true)}}} +\def\visualizeflatnodes{\dowithnextbox{\ctxlua{nodes.visualizebox(\number\nextbox,true,true)}}} + +\unexpanded\def\starttracingnodes[#1]{\ctxlua{nodes.tracers.characters.start("#1")}} +\unexpanded\def\stoptracingnodes {\ctxlua{nodes.tracers.characters.stop()}} + +% \starttext +% \starttracingnodes[characters] +% \input tufte \par +% \input tufte \par +% \stoptracingnodes +% \stoptext + +\protect \endinput diff --git a/tex/context/base/node-inj.lua b/tex/context/base/node-inj.lua new file mode 100644 index 000000000..9c4612a22 --- /dev/null +++ b/tex/context/base/node-inj.lua @@ -0,0 +1,466 @@ +if not modules then modules = { } end modules ['node-inj'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + 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. Btw, future versions of luatex will have extended glyph properties +-- that can be of help. + +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 + +-- for the moment we pass the r2l key ... volt/arabtype tests + +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,r2lflag,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] + -- inefficient but singles have less, but weird anyway, needs checking + kb[2], kb[3], kb[4], kb[5] = (kb[2] or 0) + x, (kb[3] or 0) + y, (kb[4] or 0)+ w, (kb[5] or 0) + h + else + bound = #kerns + 1 + set_attribute(current,kernpair,bound) + kerns[bound] = { rlmode, x, y, w, h, r2lflag, tfmchr.width } + 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 and n<0 and "r-to-l") or (n and 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] or "?",k[3] or "?",k[4] or "?",k[5] or "?") + else + report(" kern: dir=%s, dx=%s",dir(k[1]),k[2] or "?") + 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,md or "?",m[1] or "?",m[2] or "?") + else + report(" markmark: bound=%s, missing index",mm) + end + else + m = m[1] + report(" markmark: bound=%s, dx=%s, dy=%s",mm,m[1] or "?",m[2] or "?") + 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] or "?",c[3] or "?") + 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,where,keep) + local has_marks, has_cursives, has_kerns = next(marks), next(cursives), next(kerns) + if has_marks or has_cursives then +--~ if has_marks or has_cursives or has_kerns then + if trace_injections then + nodes.trace_injection(head) + end + -- in the future variant we will not copy items but refs to tables + local done, ky, rl, valid, cx, wx, mk = false, { }, { }, { }, { }, { }, { } + if has_kerns then -- move outside loop + local nf, tm = nil, nil + for n in traverse_id(glyph,head) do + if n.subtype < 256 then + valid[#valid+1] = n + if n.font ~= nf then + nf = n.font + tm = fontdata[nf].marks + end + mk[n] = tm[n.char] + local k = has_attribute(n,kernpair) + if k then + local kk = kerns[k] + if kk then + local x, y, w, h = kk[2] or 0, kk[3] or 0, kk[4] or 0, kk[5] or 0 + 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 + else + local nf, tm = nil, nil + for n in traverse_id(glyph,head) do + if n.subtype < 256 then + valid[#valid+1] = n + if n.font ~= nf then + nf = n.font + tm = fontdata[nf].marks + end + mk[n] = tm[n.char] + 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 p_cursbase, p = 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 + local n = valid[i] + if not mk[n] then + local n_cursbase = has_attribute(n,cursbase) + if p_cursbase then + local n_curscurs = has_attribute(n,curscurs) + 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] + local ti = t[i] + ti.yoffset = ti.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] + local ti = t[i] + ti.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] + local ti = t[i] + ti.yoffset = ny + end + maxt = 0 + end + if not keep then + cursives = { } + end + end + if has_marks then + for i=1,#valid do + local p = valid[i] + local p_markbase = has_attribute(p,markbase) + if p_markbase then + local mrks = marks[p_markbase] + for n in traverse_id(glyph,p.next) do + local 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 + -- todo + -- else + local k = wx[p] + if k then + n.xoffset = p.xoffset - d[1] - k[2] + else + n.xoffset = p.xoffset - d[1] + end + -- end + if mk[p] then + n.yoffset = p.yoffset + d[2] + else + n.yoffset = 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, r2l = k[1], k[2] or 0, k[4] or 0, k[6] + local wx = w - x +--~ if rl < 0 then +--~ if r2l 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 x ~= 0 then +--~ insert_node_before(head,n,newkern(x)) +--~ end +--~ if wx ~= 0 then +--~ insert_node_after(head,n,newkern(wx)) +--~ end +--~ end +--~ else + if r2l 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 x ~= 0 then + insert_node_before(head,n,newkern(x)) + end + if wx ~= 0 then + insert_node_after(head,n,newkern(wx)) + end + 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 + if trace_injections then + nodes.trace_injection(head) + end + for n in traverse_id(glyph,head) do + local k = has_attribute(n,kernpair) + if k then + local kk = kerns[k] + if kk then + local rl, x, y, w = kk[1], kk[2] or 0, kk[3], kk[4] + if y and y ~= 0 then + n.yoffset = y -- todo: h ? + end + if w then + -- copied from above + local r2l = kk[6] + local wx = w - x +--~ if rl < 0 then +--~ if r2l then +--~ if x ~= 0 then +--~ insert_node_before(head,n,newkern(x)) +--~ end +--~ if wx ~= 0 then +--~ insert_node_after(head,n,newkern(wx)) +--~ end +--~ else +--~ if wx ~= 0 then +--~ insert_node_before(head,n,newkern(wx)) +--~ end +--~ if x ~= 0 then +--~ insert_node_after (head,n,newkern(x)) +--~ end +--~ end +--~ else + if r2l 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 x ~= 0 then + insert_node_before(head,n,newkern(x)) + end + if wx ~= 0 then + insert_node_after(head,n,newkern(wx)) + end + end +--~ end + else + -- simple (e.g. kernclass kerns) + 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 + else + -- no tracing needed + end + return head, false +end diff --git a/tex/context/base/node-mig.lua b/tex/context/base/node-mig.lua new file mode 100644 index 000000000..f9f0ad231 --- /dev/null +++ b/tex/context/base/node-mig.lua @@ -0,0 +1,120 @@ +if not modules then modules = { } end modules ['node-mig'] = { + version = 1.001, + comment = "companion to node-mig.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format = string.format + +local hlist = node.id('hlist') +local vlist = node.id('vlist') +local insert = node.id('ins') +local mark = node.id('mark') + +local has_attribute = node.has_attribute +local set_attribute = node.set_attribute +local remove_nodes = nodes.remove + +local migrated = attributes.private("migrated") + +local trace_migrations = false + +trackers.register("nodes.migrations", function(v) trace_migrations = v end) + +local migrate_inserts, migrate_marks + +local t_inserts, t_marks, t_sweeps = 0, 0, 0 + +local function locate(head,first,last,ni,nm) + local current = head + while current do + local id = current.id + if id == vlist or id == hlist then + current.list, first, last, ni, nm = locate(current.list,first,last,ni,nm) + current= current.next + elseif migrate_inserts and id == insert then + local insert + head, current, insert = remove_nodes(head,current) + insert.next = nil + if first then + insert.prev, last.next = last, insert + else + insert.prev, first = nil, insert + end + last, ni = insert, ni + 1 + elseif migrate_marks and id == mark then + local mark + head, current, mark = remove_nodes(head,current) + mark.next = nil + if first then + mark.prev, last.next = last, mark + else + mark.prev, first = nil, mark + end + last, nm = mark, nm + 1 + else + current= current.next + end + end + return head, first, last, ni, nm +end + +function nodes.migrate_outwards(head,where) + local done = false + if head then + local current = head + while current do + local id = current.id + if id == vlist or id == hlist and not has_attribute(current,migrated) then + set_attribute(current,migrated,1) + t_sweeps = t_sweeps + 1 + local h = current.list + local first, last, ni, nm + while h do + local id = h.id + if id == vlist or id == hlist then + h, first, last, ni, nm = locate(h,first,last,0,0) + end + h = h.next + end + if first then + t_inserts, t_marks = t_inserts + ni, t_marks + nm + if trace_migrations and (ni > 0 or nm > 0) then + logs.report("nodes","sweep %s, %s inserts and %s marks migrated outwards",t_sweeps,ni,nm) + end + -- inserts after head + local n = current.next + if n then + last.next, n.prev = n, last + end + current.next, first.prev = first, current + done, current = true, last + end + end + current = current.next + end + return head, done + end +end + +experiments.register("marks.migrate", function(v) + if v then + tasks.enableaction("mvlbuilders", "nodes.migrate_outwards") + end + migrate_marks = v +end) + +experiments.register("inserts.migrate", function(v) + if v then + tasks.enableaction("mvlbuilders", "nodes.migrate_outwards") + end + migrate_inserts = v +end) + +statistics.register("node migrations", function() + if trace_migrations and t_sweeps > 0 then + return format("%s sweeps, %s inserts moved, %s marks moved",t_sweeps,t_inserts,t_marks) + end +end) diff --git a/tex/context/base/node-mig.mkiv b/tex/context/base/node-mig.mkiv new file mode 100644 index 000000000..cd731b96f --- /dev/null +++ b/tex/context/base/node-mig.mkiv @@ -0,0 +1,60 @@ +%D \module +%D [ file=node-mig, +%D version=2010.01.19, +%D title=\CONTEXT\ Node Macros, +%D subtitle=Inserts, +%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 Node Support / Migrations} + +%D This is very experimental and although it is used in a +%D real project it mostly serves a testbed for Taco and me so +%D as prelude to extending the inserts mechanism. +%D +%D \starttyping +%D \automigrateinserts +%D +%D \hbox{\vbox{x\footnote{1}x\footnote{2}x\footnote{3}x}} +%D \vbox{x\footnote{4}x} +%D \hbox{\vbox{x\footnote{5}x}} +%D +%D \hbox{x} +%D \hbox{x\footnote{6}x} +%D \hbox{x} +%D +%D \starttabulate +%D \NC test \NC test \footnote{test} \input tufte \NC \NR +%D \NC test \NC test \footnote{test} \input tufte \NC \NR +%D \NC test \NC test \footnote{test} \input tufte \NC \NR +%D \NC test \NC test \footnote{test} \input tufte \NC \NR +%D \NC test \NC test \footnote{test} \input tufte \NC \NR +%D \NC test \NC test \footnote{test} \input tufte \NC \NR +%D \stoptabulate +%D \stoptyping + +\unprotect + +\registerctxluafile{node-mig}{1.001} + +\newtoks \everyautomigratefootnotes +\newtoks \everyautomigratemarks + +\def\automigrateinserts{\the\everyautomigratefootnotes} +\def\automigratemarks {\the\everyautomigratemarks} + +\appendtoks + \let\postponenotes\relax + \enableexperiments[inserts.migrate]% +\to \everyautomigratefootnotes + +\appendtoks + \enableexperiments[marks.migrate]% +\to \everyautomigratemarks + +\protect diff --git a/tex/context/base/node-pag.lua b/tex/context/base/node-pag.lua new file mode 100644 index 000000000..4bc53c6dd --- /dev/null +++ b/tex/context/base/node-pag.lua @@ -0,0 +1,30 @@ +if not modules then modules = { } end modules ['node-pag'] = { + version = 1.001, + comment = "companion to node-pag.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- this callback might disappear and come back in the same way +-- as par builders + +pagebuilders = pagebuilders or { } + +local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming + +local actions = tasks.actions("pagebuilders",5) + +local function processor(head,groupcode,size,packtype,maxdepth,direction) + starttiming(pagebuilders) + local _, done = actions(head,groupcode,size,packtype,maxdepth,direction) + stoptiming(pagebuilders) + return (done and head) or true +-- return vpack(head) +end + +--~ callbacks.register('pre_output_filter', processor, "preparing output box") + +--~ statistics.register("output preparation time", function() +--~ return statistics.elapsedseconds(pagebuilders) +--~ end) diff --git a/tex/context/base/node-pag.mkiv b/tex/context/base/node-pag.mkiv new file mode 100644 index 000000000..487901ad0 --- /dev/null +++ b/tex/context/base/node-pag.mkiv @@ -0,0 +1,20 @@ +%D \module +%D [ file=node-pag, +%D version=2008.09.30, +%D title=\CONTEXT\ Node Macros, +%D subtitle=Page Building, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 Macros / Page Building} + +\unprotect + +\registerctxluafile{node-pag}{1.001} + +\protect \endinput diff --git a/tex/context/base/node-par.lua b/tex/context/base/node-par.lua new file mode 100644 index 000000000..7be7e7917 --- /dev/null +++ b/tex/context/base/node-par.lua @@ -0,0 +1,101 @@ +if not modules then modules = { } end modules ['node-par'] = { + version = 1.001, + comment = "companion to node-par.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +parbuilders = parbuilders or { } +parbuilders.constructors = parbuilders.constructors or { } +parbuilders.names = parbuilders.names or { } +parbuilders.numbers = parbuilders.numbers or { } +parbuilders.attribute = attributes.numbers['parbuilder'] or 999 + +storage.register("parbuilders.names", parbuilders.names, "parbuilders.names") +storage.register("parbuilders.numbers", parbuilders.numbers, "parbuilders.numbers") + +local constructors, names, numbers, p_attribute = parbuilders.constructors, parbuilders.names, parbuilders.numbers, parbuilders.attribute + +local has_attribute = node.has_attribute +local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming + +local mainconstructor = nil -- not stored in format + +function parbuilders.register(name,number) + parbuilders.names[number] = name + parbuilders.numbers[name] = number +end + +function parbuilders.setmain(name) + mainconstructor = numbers[name] +end + +-- return values: +-- +-- true : tex will break itself +-- false : idem but dangerous +-- head : list of valid vmode nodes with last being hlist + +function parbuilders.constructor(head,followed_by_display) + if type(head) == "boolean" then + return head + else + local attribute = has_attribute(head,p_attribute) or mainconstructor + if attribute then + local constructor = names[attribute] + if constructor then + local handler = constructor and constructors[constructor] + if handler then + return handler(head,followed_by_display) + else + logs.report("parbuilders","handler '%s' is not defined",tostring(constructor)) + return true -- let tex break + end + end + end + return true -- let tex break + end +end + +-- just for testing + +function parbuilders.constructors.default(head,followed_by_display) + return true -- let tex break +end + +-- also for testing (no surrounding spacing done) + +function parbuilders.constructors.oneline(head,followed_by_display) + return node.hpack(head) +end + +-- It makes no sense to have a sequence here as we already have +-- pre and post hooks and only one parbuilder makes sense, so no: +-- +-- local actions = tasks.actions("parbuilders",1) + +-- todo: enable one as main + +local actions = parbuilders.constructor +local enabled = false + +function parbuilders.enable () enabled = true end +function parbuilders.disable() enabled = false end + +local function processor(head,followed_by_display) + if enabled then + starttiming(parbuilders) + local head = actions(head,followed_by_display) + stoptiming(parbuilders) + return head + else + return true -- let tex do the work + end +end + +callbacks.register('linebreak_filter', processor, "breaking paragraps into lines") + +statistics.register("linebreak processing time", function() + return statistics.elapsedseconds(parbuilders) +end) diff --git a/tex/context/base/node-par.mkiv b/tex/context/base/node-par.mkiv new file mode 100644 index 000000000..cb53e643d --- /dev/null +++ b/tex/context/base/node-par.mkiv @@ -0,0 +1,78 @@ +%D \module +%D [ file=node-par, +%D version=2008.09.30, +%D title=\CONTEXT\ Node Macros, +%D subtitle=Paragraph Building, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 Macros / Paragraph Building} + +%D This is very experimental, undocumented, subjected to changes, etc. just as +%D the underlying interfaces. + +% \enableparbuilders +% +% \startparbuilder[default] +% \input tufte \par +% \startparbuilder[oneline] +% \input tufte \par +% \stopparbuilder +% \input tufte \par +% \stopparbuilder + +\unprotect + +\registerctxluafile{node-par}{1.001} + +\definesystemattribute[parbuilder] \chardef\parbuilderattribute \dogetattributeid{parbuilder} + +% todo auto-enable + +% management (enable/disable) is global and will move to lua + +\newcount\nofparbuilders + +\unexpanded\def\defineparbuilder[#1]% + {\global\advance\nofparbuilders\plusone + \ctxlua{parbuilders.register("#1",\number\nofparbuilders)}% + \setxvalue{\??ng:#1}{\attribute\parbuilderattribute\nofparbuilders}} + +\unexpanded\def\startparbuilder[#1]% + {\edef\@@currentparbuilder{\number\attribute\parbuilderattribute}% + \globalpushmacro\@@currentparbuilder + \getvalue{\??ng:#1}% + \checkparbuilders} + +\unexpanded\def\stopparbuilder + {\ifhmode\par\fi + \globalpopmacro\@@currentparbuilder + \attribute\parbuilderattribute\@@currentparbuilder\relax + \checkparbuilders} + +\def\setmainparbuilder[#1]% + {\ctxlua{parbuilders.setmain("#1")}} + +% no high level interface, after all implementing a linebreaker is not something that +% the average user will do + +\defineparbuilder[default] % just for testing +\defineparbuilder[oneline] % just for testing +\defineparbuilder[basic] % just for testing + +\def\enableparbuilders {\ctxlua{parbuilders.enable ()}} +\def\disableparbuilders{\ctxlua{parbuilders.disable()}} + +\def\checkparbuilders % can be more efficient as we don't want to do this to often + {\ifcase\attribute\parbuilderattribute + \disableparbuilders + \else + \enableparbuilders + \fi} + +\protect \endinput diff --git a/tex/context/base/node-pro.lua b/tex/context/base/node-pro.lua new file mode 100644 index 000000000..4f5b3dcbe --- /dev/null +++ b/tex/context/base/node-pro.lua @@ -0,0 +1,149 @@ +if not modules then modules = { } end modules ['node-pro'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + 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 glyph = node.id('glyph') + +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 + +local actions = tasks.actions("processors",4) + +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 + logs.report("nodes","%s %s: %s, group: %s, nodes: %s -> %s, string: %s",what,n,state,groupcode,before,after,reconstruct(head)) + else + logs.report("nodes","%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,size,packtype,direction) + local first, found = first_character(head) + if found then + if trace_callbacks then + local before = nodes.count(head,true) + local head, done = actions(head,groupcode,size,packtype,direction) + 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, done = actions(head,groupcode,size,packtype,direction) + 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,size,packtype,direction) + local first, found = first_character(head) + if found then + if trace_callbacks then + local before = nodes.count(head,true) + local head, done = actions(head,groupcode,size,packtype,direction) + 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, done = actions(head,groupcode,size,packtype,direction) + 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 + +callbacks.register('pre_linebreak_filter', nodes.processors.pre_linebreak_filter,"all kind of horizontal manipulations (before par break)") +callbacks.register('hpack_filter' , nodes.processors.hpack_filter,"all kind of horizontal manipulations") + +local actions = tasks.actions("finalizers",1) -- head, where + +-- beware, these are packaged boxes so no first_character test +-- maybe some day a hash with valid groupcodes +-- +-- beware, much can pass twice, for instance vadjust passes two times + +function nodes.processors.post_linebreak_filter(head,groupcode) +--~ local first, found = first_character(head) +--~ if found then + if trace_callbacks then + local before = nodes.count(head,true) + local head, done = actions(head,groupcode) + 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, done = actions(head,groupcode) + 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 + +callbacks.register('post_linebreak_filter', nodes.processors.post_linebreak_filter,"all kind of horizontal manipulations (after par break)") + +statistics.register("h-node processing time", function() + return statistics.elapsedseconds(nodes,"including kernel") -- hm, ok here? +end) diff --git a/tex/context/base/node-ref.lua b/tex/context/base/node-ref.lua new file mode 100644 index 000000000..7128b1a6d --- /dev/null +++ b/tex/context/base/node-ref.lua @@ -0,0 +1,533 @@ +if not modules then modules = { } end modules ['node-bck'] = { + version = 1.001, + comment = "companion to node-bck.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- We supported pdf right from the start and in mkii this has resulted in +-- extensive control over the links. Nowadays pdftex provides a lot more +-- control over margins but as mkii supports multiple backends we stuck to +-- our own mechanisms. In mkiv again we implement our own handling. Eventually +-- we will even disable the pdf primitives. + +-- helper, will end up in luatex + +local cleanupreferences, cleanupdestinations = false, true + +local nodeinjections = backends.nodeinjections +local codeinjections = backends.codeinjections + +local hpack_list = node.hpack +local list_dimensions = node.dimensions + +-- current.glue_set current.glue_sign + +local trace_backend = false trackers.register("nodes.backend", function(v) trace_backend = v end) +local trace_references = false trackers.register("nodes.references", function(v) trace_references = v end) +local trace_destinations = false trackers.register("nodes.destinations", function(v) trace_destinations = v end) + +local hlist = node.id("hlist") +local vlist = node.id("vlist") +local glue = node.id("glue") +local whatsit = node.id("whatsit") + +local new_kern = nodes.kern + +local has_attribute = node.has_attribute +local traverse = node.traverse +local find_node_tail = node.tail or node.slide +local tosequence = nodes.tosequence + +local function dimensions(parent,start,stop) + stop = stop and stop.next + if parent then + if stop then + return list_dimensions(parent.glue_set,parent.glue_sign,parent.glue_order,start,stop) + else + return list_dimensions(parent.glue_set,parent.glue_sign,parent.glue_order,start) + end + else + if stop then + return list_dimensions(start,stop) + else + return list_dimensions(start) + end + end +end + +--~ more compact + +local function dimensions(parent,start,stop) + if parent then + return list_dimensions(parent.glue_set,parent.glue_sign,parent.glue_order,start,stop and stop.next) + else + return list_dimensions(start,stop and stop.next) + end +end + +-- is pardir important at all? + +local function inject_range(head,first,last,reference,make,stack,parent,pardir,txtdir) + local width, height, depth = dimensions(parent,first,last) + if pardir == "TRT" or txtdir == "+TRT" then + width = - width + end + local result, resolved = make(width,height,depth,reference) + if result and resolved then + if head == first then + if trace_backend then + logs.report("backend","head: %04i %s %s %s => w=%s, h=%s, d=%s, c=%s",reference,pardir or "---",txtdir or "----",tosequence(first,last,true),width,height,depth,resolved) + end + result.next = first + first.prev = result + return result, last + else + if trace_backend then + logs.report("backend","middle: %04i %s %s => w=%s, h=%s, d=%s, c=%s",reference,pardir or "---",txtdir or "----",tosequence(first,last,true),width,height,depth,resolved) + end + local prev = first.prev + if prev then + result.next = first + result.prev = prev + prev.next = result + first.prev = result + else + result.next = first + first.prev = result + end + if first == head.next then + head.next = result -- hm, weird + end + return head, last + end + else + return head, last + end +end + +local function inject_list(id,current,reference,make,stack,pardir,txtdir) + local width, height, depth, correction = current.width, current.height, current.depth, 0 + local moveright = false + local first = current.list + if id == hlist then + -- can be either an explicit hbox or a line and there is no way + -- to recognize this; anyway only if ht/dp (then inline) + -- + -- to be tested: 0=unknown, 1=linebreak, 2=hbox +--~ if id.subtype == 1 then + local sr = stack[reference] + if first then + if sr and sr[2] then + local last = find_node_tail(first) + if last.id == glue and last.subtype == 9 then + local prev = last.prev + moveright = first.id == glue and first.subtype == 8 + if prev and prev.id == glue and prev.subtype == 15 then + width = dimensions(current,first,prev.prev) -- maybe not current as we already take care of it + else + if moveright and first.writable then + width = width - first.spec.stretch*current.glue_set * current.glue_sign + end + if last.writable then + width = width - last.spec.stretch*current.glue_set * current.glue_sign + end + end + end + else + -- also weird + end +--~ else +--~ print("!!!!!!!!!!!!!!!!!") + -- simple +--~ end + else + -- ok + end + correction = width + else + correction = height + depth + height, depth = depth, height -- ugly hack, needed because pdftex backend does something funny + end + if pardir == "TRT" then + width = - width + end + local result, resolved = make(width,height,depth,reference) + if result and resolved then + if trace_backend then + logs.report("backend","box: %04i %s %s: w=%s, h=%s, d=%s, c=%s",reference,pardir or "---",txtdir or "----",width,height,depth,resolved) + end + if not first then + current.list = result + elseif moveright then -- brr no prevs done + -- result after first + local n = first.next + result.next = n + first.next = result + result.prev = first + if n then n.prev = result end + else + -- first after result + result.next = first + first.prev = result + current.list = result + end + end +end + +-- skip is somewhat messy + +local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,txtdir) -- main + if head then + local current, first, last, firstdir, reference = head, nil, nil, nil, nil + pardir = pardir or "===" + txtdir = txtdir or "===" + while current do + local id = current.id + local r = has_attribute(current,attribute) + if id == whatsit then + local subtype = current.subtype + if subtype == 6 then + pardir = current.dir + elseif subtype == 7 then + txtdir = current.dir + end + elseif id == hlist or id == vlist then + if not reference and r and (not skip or r > skip) then + inject_list(id,current,r,make,stack,pardir,txtdir) + end + if r then + done[r] = (done[r] or 0) + 1 + end + local list = current.list + if list then + local _ + current.list, _, pardir, txtdir = inject_areas(list,attribute,make,stack,done,r or skip or 0,current,pardir,txtdir) + end + if r then + done[r] = done[r] - 1 + end + elseif not r then + -- just go on, can be kerns + elseif not reference then + reference, first, last, firstdir = r, current, current, txtdir + elseif r == reference then + last = current + elseif (done[reference] or 0) == 0 then + if not skip or r > skip then + head, current = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir) + reference, first, last, firstdir = nil, nil, nil, nil + end + else + reference, first, last, firstdir = r, current, current, txtdir + end + current = current.next + end + if reference and (done[reference] or 0) == 0 then + head = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir) + end + end + return head, true, pardir, txtdir +end + +local function inject_area(head,attribute,make,stack,done,parent,pardir,txtdir) -- singular ! + if head then + pardir = pardir or "===" + txtdir = txtdir or "===" + local current = head + while current do + local id = current.id + local r = has_attribute(current,attribute) + if id == whatsit then + local subtype = current.subtype + if subtype == 6 then + pardir = current.dir + elseif subtype == 7 then + txtdir = current.dir + end + elseif id == hlist or id == vlist then + if r and not done[r] then + done[r] = true + inject_list(id,current,r,make,stack,pardir,txtdir) + end + current.list = inject_area(current.list,attribute,make,stack,done,current,pardir,txtdir) + elseif r and not done[r] then + done[r] = true + head, current = inject_range(head,current,current,r,make,stack,parent,pardir,txtdir) + end + current = current.next + end + end + return head, true +end + +-- tracing + +local new_rule = nodes.rule +local new_kern = nodes.kern +local set_attribute = node.set_attribute +local register_color = colors.register + +local a_colormodel = attributes.private('colormodel') +local a_color = attributes.private('color') +local a_transparency = attributes.private('transparency') +local u_transparency = nil +local u_colors = { } +local force_gray = true + +local function colorize(width,height,depth,n) + if force_gray then n = 0 end + u_transparency = u_transparency or transparencies.register(nil,2,.65) + local ucolor = u_colors[n] + if not ucolor then + if n == 1 then + u_color = register_color(nil,'rgb',.75,0,0) + elseif n == 2 then + u_color = register_color(nil,'rgb',0,.75,0) + elseif n == 3 then + u_color = register_color(nil,'rgb',0,0,.75) + else + n = 0 + u_color = register_color(nil,'gray',.5) + end + u_colors[n] = u_color + end + local rule = new_rule(width,height,depth) + set_attribute(rule,a_colormodel,1) -- gray color model + set_attribute(rule,a_color,u_color) + set_attribute(rule,a_transparency,u_transparency) + if width < 0 then + local kern = new_kern(width) + rule.width = -width + kern.next = rule + rule.prev = kern + return kern + else + return rule + end +end + +local new_kern = nodes.kern +local texattribute = tex.attribute +local texcount = tex.count + +-- references: + +nodes.references = { + attribute = attributes.private('reference'), + stack = { }, + done = { }, +} + +local stack, done, attribute = nodes.references.stack, nodes.references.done, nodes.references.attribute + +local nofreferences, topofstack = 0, 0 + +local function setreference(n,h,d,r) -- n is just a number, can be used for tracing + topofstack = topofstack + 1 + stack[topofstack] = { n, h, d, codeinjections.prerollreference(r) } -- the preroll permits us to determine samepage (but delayed also has some advantages) +--~ texattribute[attribute] = topofstack -- todo -> at tex end + texcount.lastreferenceattribute = topofstack +end + +nodes.setreference = setreference + +local function makereference(width,height,depth,reference) + local sr = stack[reference] + if sr then + local resolved, ht, dp, set = sr[1], sr[2], sr[3], sr[4] + if ht then + if height < ht then height = ht end + if depth < dp then depth = dp end + end + local annot = nodeinjections.reference(width,height,depth,set) + if annot then + nofreferences = nofreferences + 1 + local result, current + if trace_references then + local step = 65536 + result = hpack_list(colorize(width,height-step,depth-step,2)) -- step subtracted so that we can see seperate links + result.width = 0 + current = result + end + if current then + current.next = annot + else + result = annot + end + result = hpack_list(result,0) + result.width, result.height, result.depth = 0, 0, 0 + if cleanupreferences then stack[reference] = nil end + return result, resolved + else + logs.report("backends","unable to resolve reference annotation %s",reference) + end + else + logs.report("backends","unable to resolve reference attribute %s",reference) + end +end + +function nodes.add_references(head) + if topofstack > 0 then + return inject_areas(head,attribute,makereference,stack,done) + else + return head, false + end +end + +-- destinations (we can clean up once set!) + +nodes.destinations = { + attribute = attributes.private('destination'), + stack = { }, + done = { }, +} + +local stack, done, attribute = nodes.destinations.stack, nodes.destinations.done, nodes.destinations.attribute + +local nofdestinations, topofstack = 0, 0 + +local function setdestination(n,h,d,name,view) -- n = grouplevel, name == table + topofstack = topofstack + 1 + stack[topofstack] = { n, h, d, name, view } + return topofstack +end + +nodes.setdestination = setdestination + +local function makedestination(width,height,depth,reference) + local sr = stack[reference] + if sr then + local resolved, ht, dp, name, view = sr[1], sr[2], sr[3], sr[4], sr[5] + if ht then + if height < ht then height = ht end + if depth < dp then depth = dp end + end + local result, current + if trace_destinations then + local step = 0 + if width == 0 then + step = 4*65536 + width, height, depth = 5*step, 5*step, 0 + end + for n=1,#name do + local rule = hpack_list(colorize(width,height,depth,3)) + rule.width = 0 + if not result then + result, current = rule, rule + else + current.next = rule + rule.prev = current + current = rule + end + width, height = width - step, height - step + end + end + nofdestinations = nofdestinations + 1 + for n=1,#name do + local annot = nodeinjections.destination(width,height,depth,name[n],view) + if not result then + result, current = annot, annot + else + current.next = annot + annot.prev = current + current = annot + end + end + result = hpack_list(result,0) + result.width, result.height, result.depth = 0, 0, 0 + if cleanupdestinations then stack[reference] = nil end + return result, resolved + else + logs.report("backends","unable to resolve destination attribute %s",reference) + end +end + +function nodes.add_destinations(head) + if topofstack > 0 then + return inject_area(head,attribute,makedestination,stack,done) -- singular + else + return head, false + end +end + +-- will move + +function jobreferences.mark(reference,h,d,view) + return setdestination(tex.currentgrouplevel,h,d,reference,view) +end + +function jobreferences.inject(prefix,reference,h,d,highlight,newwindow,layer) -- todo: use currentreference is possible + local set, bug = jobreferences.identify(prefix,reference) + if bug or #set == 0 then + -- unknown ref, just don't set it and issue an error + else + -- check + set.highlight, set.newwindow,set.layer = highlight, newwindow, layer + setreference(tex.currentgrouplevel,h,d,set) -- sets attribute / todo: for set[*].error + end +end + +function jobreferences.injectcurrentset(h,d) -- used inside doifelse + local currentset = jobreferences.currentset + if currentset then + setreference(tex.currentgrouplevel,h,d,currentset) -- sets attribute / todo: for set[*].error + end +end + +-- + +local function checkboth(open,close) + if open and open ~= "" then + local set, bug = jobreferences.identify("",open) + open = not bug and #set > 0 and set + end + if close and close ~= "" then + local set, bug = jobreferences.identify("",close) + close = not bug and #set > 0 and set + end + return open, close +end + +-- expansion is temp hack + +local opendocument, closedocument, openpage, closepage + +local function check(what) + if what and what ~= "" then + local set, bug = jobreferences.identify("",what) + return not bug and #set > 0 and set + end +end + +function jobreferences.checkopendocumentactions (open) opendocument = check(open) end +function jobreferences.checkclosedocumentactions(close) closedocument = check(close) end +function jobreferences.checkopenpageactions (open) openpage = check(open) end +function jobreferences.checkclosepageactions (close) closepage = check(close) end + +function jobreferences.flushdocumentactions() + if opendocument or closedocument then + backends.codeinjections.flushdocumentactions(opendocument,closedocument) -- backend + end +end +function jobreferences.flushpageactions() + if openpage or closepage then + backends.codeinjections.flushpageactions(openpage,closepage) -- backend + end +end + +-- end temp hack + +statistics.register("interactive elements", function() + if nofreferences > 0 or nofdestinations > 0 then + return string.format("%s references, %s destinations",nofreferences,nofdestinations) + else + return nil + end +end) + +function jobreferences.enable_interaction() + tasks.enableaction("shipouts","nodes.add_references") + tasks.enableaction("shipouts","nodes.add_destinations") +end diff --git a/tex/context/base/node-res.lua b/tex/context/base/node-res.lua new file mode 100644 index 000000000..a8ea8745a --- /dev/null +++ b/tex/context/base/node-res.lua @@ -0,0 +1,302 @@ +if not modules then modules = { } end modules ['node-res'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + 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, free_list, new_node, node_type, node_id = node.copy, node.free, node.flush_list, node.new, node.type, node.id +local tonumber, round = tonumber, math.round + +local glyph_node = node_id("glyph") + +--[[ldx-- +

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

+--ldx]]-- + +nodes = nodes or { } + +nodes.whatsits = { } -- table.swapped(node.whatsits()) + +local reserved = { } +local whatsits = nodes.whatsits + +for k, v in next, node.whatsits() do + whatsits[k], whatsits[v] = v, k -- two way +end + +local function register_node(n) + reserved[#reserved+1] = n + return n +end + +nodes.register = register_node + +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 + local ri = reserved[i] + -- if not (ri.id == glue_spec and not ri.is_writable) then + free_node(reserved[i]) + -- end + 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 disc = register_node(new_node("disc")) +local kern = register_node(new_node("kern",1)) +local penalty = register_node(new_node("penalty")) +local glue = register_node(new_node("glue")) -- glue.spec = nil +local glue_spec = register_node(new_node("glue_spec")) +local glyph = register_node(new_node("glyph",0)) +local textdir = register_node(new_node("whatsit",whatsits.dir)) -- 7 (6 is local par node) +local rule = register_node(new_node("rule")) +local latelua = register_node(new_node("whatsit",whatsits.late_lua)) -- 35 +local user_n = register_node(new_node("whatsit",whatsits.user_defined)) user_n.type = 100 -- 44 +local user_l = register_node(new_node("whatsit",whatsits.user_defined)) user_l.type = 110 -- 44 +local user_s = register_node(new_node("whatsit",whatsits.user_defined)) user_s.type = 115 -- 44 +local user_t = register_node(new_node("whatsit",whatsits.user_defined)) user_t.type = 116 -- 44 +local left_margin_kern = register_node(new_node("margin_kern",0)) +local right_margin_kern = register_node(new_node("margin_kern",1)) +local lineskip = register_node(new_node("glue",1)) +local baselineskip = register_node(new_node("glue",2)) +local leftskip = register_node(new_node("glue",8)) +local rightskip = register_node(new_node("glue",9)) +local temp = register_node(new_node("temp",0)) + +function nodes.zeroglue(n) + local s = n.spec + return not writable or ( + s.width == 0 + and s.stretch == 0 + and s.shrink == 0 + and s.stretch_order == 0 + and s.shrink_order == 0 + ) +end + +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_spec(width,stretch,shrink) + local s = copy_node(glue_spec) + s.width, s.stretch, s.shrink = width, stretch, shrink + return s +end + +local function someskip(skip,width,stretch,shrink) + local n = copy_node(skip) + if not width then + -- no spec + elseif tonumber(width) then + local s = copy_node(glue_spec) + s.width, s.stretch, s.shrink = width, stretch, shrink + n.spec = s + else + -- shared + n.spec = copy_node(width) + end + return n +end + +function nodes.glue(width,stretch,shrink) + return someskip(glue,width,stretch,shrink) +end +function nodes.leftskip(width,stretch,shrink) + return someskip(leftskip,width,stretch,shrink) +end +function nodes.rightskip(width,stretch,shrink) + return someskip(rightskip,width,stretch,shrink) +end +function nodes.lineskip(width,stretch,shrink) + return someskip(lineskip,width,stretch,shrink) +end +function nodes.baselineskip(width,stretch,shrink) + return someskip(baselineskip,width,stretch,shrink) +end + +function nodes.disc() + return copy_node(disc) +end + +function nodes.textdir(dir) + local t = copy_node(textdir) + t.dir = dir + return t +end + +function nodes.rule(width,height,depth,dir) + local n = copy_node(rule) + if width then n.width = width end + if height then n.height = height end + if depth then n.depth = depth end + if dir then n.dir = dir end + return n +end + +function nodes.latelua(code) + local n = copy_node(latelua) + n.data = code + return n +end + +function nodes.leftmarginkern(glyph,width) + local n = copy_node(left_margin_kern) + if not glyph then + logs.fatal("nodes","invalid pointer to left margin glyph node") + elseif glyph.id ~= glyph_node then + logs.fatal("nodes","invalid node type %s for left margin glyph node",node_type(glyph)) + else + n.glyph = glyph + end + if width then + n.width = width + end + return n +end + +function nodes.rightmarginkern(glyph,width) + local n = copy_node(right_margin_kern) + if not glyph then + logs.fatal("nodes","invalid pointer to right margin glyph node") + elseif glyph.id ~= glyph_node then + logs.fatal("nodes","invalid node type %s for right margin glyph node",node_type(p)) + else + n.glyph = glyph + end + if width then + n.width = width + end + return n +end + +function nodes.temp() + return copy_node(temp) +end +--[[ +

At some point we ran into a problem that the glue specification +of the zeropoint dimension was overwritten when adapting a glue spec +node. This is a side effect of glue specs being shared. After a +couple of hours tracing and debugging Taco and I came to the +conclusion that it made no sense to complicate the spec allocator +and settled on a writable flag. This all is a side effect of the +fact that some glues use reserved memory slots (with the zeropoint +glue being a noticeable one). So, next we wrap this into a function +and hide it for the user. And yes, LuaTeX now gives a warning as +well.

+]]-- + +if tex.luatexversion > 51 then + + function nodes.writable_spec(n) + local spec = n.spec + if not spec then + spec = copy_node(glue_spec) + n.spec = spec + elseif not spec.writable then + spec = copy_node(spec) + n.spec = spec + end + return spec + end + +else + + function nodes.writable_spec(n) + local spec = n.spec + if not spec then + spec = copy_node(glue_spec) + else + spec = copy_node(spec) + end + n.spec = spec + return spec + end + +end + +local cache = { } + +function nodes.usernumber(num) + local n = cache[num] + if n then + return copy_node(n) + else + local n = copy_node(user_n) + if num then n.value = num end + return n + end +end + +function nodes.userlist(list) + local n = copy_node(user_l) + if list then n.value = list end + return n +end + +local cache = { } -- we could use the same cache + +function nodes.userstring(str) + local n = cache[str] + if n then + return copy_node(n) + else + local n = copy_node(user_s) + n.type = 115 + if str then n.value = str end + return n + end +end + +function nodes.usertokens(tokens) + local n = copy_node(user_t) + if tokens then n.value = tokens end + return n +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-rul.lua b/tex/context/base/node-rul.lua new file mode 100644 index 000000000..9dd89bcda --- /dev/null +++ b/tex/context/base/node-rul.lua @@ -0,0 +1,288 @@ +if not modules then modules = { } end modules ['node-rul'] = { + version = 1.001, + comment = "companion to node-rul.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- this will go to an auxiliary module +-- beware: rules now have a dir field + +local glyph = node.id("glyph") +local disc = node.id("disc") +local rule = node.id("rule") + +function nodes.strip_range(first,last) -- todo: dir + if first and last then -- just to be sure + local current = first + while current and current ~= last do + local id = current.id + if id == glyph or id == disc then + --~ if id == glyph or id == rule or id == disc then + first = current + break + else + current = current.next + end + end + local current = last + while current and current ~= first do + local id = current.id + --~ if id == glyph or id == rule or id == disc then + if id == glyph or id == disc then + last = current + break + else + current = current.prev + end + end + end + return first, last +end + +-- todo: order and maybe other dimensions + +local trace_ruled = false trackers.register("nodes.ruled", function(v) trace_ruled = v end) + +local floor = math.floor +local n_tostring, n_tosequence = nodes.ids_tostring, nodes.tosequence + +local a_ruled = attributes.private('ruled') +local a_color = attributes.private('color') +local a_transparency = attributes.private('transparency') +local a_colorspace = attributes.private('colormodel') + +local glyph = node.id("glyph") +local disc = node.id("disc") +local glue = node.id("glue") +local penalty = node.id("penalty") +local kern = node.id("kern") +local hlist = node.id("hlist") +local vlist = node.id("vlist") +local rule = node.id("rule") +local whatsit = node.id("whatsit") + +local new_rule = nodes.rule +local new_kern = nodes.kern +local new_glue = nodes.glue + +local insert_before, insert_after, strip_range = node.insert_before, node.insert_after, nodes.strip_range +local list_dimensions, has_attribute, set_attribute = node.dimensions, node.has_attribute, node.set_attribute +local hpack_nodes = node.hpack +local dimenfactor = fonts.dimenfactor +local texwrite = tex.write + +local fontdata = fonts.ids +local variables = interfaces.variables + +-- we can use this one elsewhere too +-- +-- todo: functions: word, sentence +-- +-- glyph rule unset whatsit glue margin_kern kern math disc + +local checkdir = true + +-- we assume {glyphruns} and no funny extra kerning, ok, maybe we need +-- a dummy character as start and end; anyway we only collect glyphs + +local function process_words(attribute,data,flush,head,parent) -- we have hlistdir and local dir + local n = head + if n then + local f, l, a, d, i, level + local continue, done, strip = false, false, false + while n do + local id = n.id + if id == glyph or id == rule then + local aa = has_attribute(n,attribute) + if aa then + if aa == a then + if not f then -- ? + f = n + end + l = n + else + -- possible extensions: when in same class then keep spanning + if f then + head, done = flush(head,f,l,d,level,parent,strip), true + end + f, l, a = n, n, aa + level, i = floor(a/1000), a%1000 + d = data[i] + continue = d.continue == variables.yes + end + else + if f then + head, done = flush(head,f,l,d,level,parent,strip), true + end + f, l, a = nil, nil, nil + end + elseif f and (id == disc or (id == kern and n.subtype == 0)) then + l = n + elseif id == hlist or id == vlist then + if f then + head, done = flush(head,f,l,d,level,parent,strip), true + f, l, a = nil, nil, nil + end + local list = n.list + if list then + n.list = process_words(attribute,data,flush,list,n) + end + elseif checkdir and id == whatsit and n.subtype == 7 then -- only changes in dir, we assume proper boundaries + if f and a then + l = n + end + elseif f then + if continue then + if id == penalty or id == kern then + l = n + elseif id == glue then + l = n + end + else + head, done = flush(head,f,l,d,level,parent,strip), true + f, l, a = nil, nil, nil + end + end + n = n.next + end + if f then + head, done = flush(head,f,l,d,level,parent,strip), true + end + return head, true -- todo: done + else + return head, false + end +end + +nodes.process_words = process_words + +-- + +nodes.rules = nodes.rules or { } +nodes.rules.data = nodes.rules.data or { } + +storage.register("nodes/rules/data", nodes.rules.data, "nodes.rules.data") + +local data = nodes.rules.data + +function nodes.rules.define(settings) + data[#data+1] = settings + texwrite(#data) +end + +local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but acceptable for this purpose +-- check for f and l + local r, m + if true then + f, l = strip_range(f,l) + end + local w = list_dimensions(parent.glue_set,parent.glue_sign,parent.glue_order,f,l.next) + local method, offset, continue, dy, rulethickness, unit, order, max, ma, ca, ta = + d.method, d.offset, d.continue, d.dy, d.rulethickness, d.unit, d.order, d.max, d.ma, d.ca, d.ta + local e = dimenfactor(unit,fontdata[f.font]) + local colorspace = (ma > 0 and ma) or has_attribute(f,a_colorspace) or 1 + local color = (ca > 0 and ca) or has_attribute(f,a_color) + local transparency = (ta > 0 and ta) or has_attribute(f,a_transparency) + local foreground = order == variables.foreground + rulethickness= rulethickness/2 + if level > max then + level = max + end + if method == 0 then -- center + offset = 2*offset + m = (offset+(level-1)*dy+rulethickness)*e/2 + else + m = 0 + end + for i=1,level do + local ht = (offset+(i-1)*dy+rulethickness)*e - m + local dp = -(offset+(i-1)*dy-rulethickness)*e + m + local r = new_rule(w,ht,dp) + if color then + set_attribute(r,a_colorspace,colorspace) + set_attribute(r,a_color,color) + end + if transparency then + set_attribute(r,a_transparency,transparency) + end + local k = new_kern(-w) + if foreground then + insert_after(head,l,k) + insert_after(head,k,r) + l = r + else + head, _ = insert_before(head,f,r) + insert_after(head,r,k) + end + if trace_ruled then + logs.report("ruled", "level: %s, width: %i, height: %i, depth: %i, nodes: %s, text: %s", + level,w,ht,dp,n_tostring(f,l),n_tosequence(f,l,true)) + -- level,r.width,r.height,r.depth,n_tostring(f,l),n_tosequence(f,l,true)) + end + end + return head +end + +local process = nodes.process_words + +nodes.rules.process = function(head) return process(a_ruled,data,flush_ruled,head) end + +function nodes.rules.enable() + tasks.enableaction("shipouts","nodes.rules.process") +end + +-- elsewhere: +-- +-- tasks.appendaction ("shipouts", "normalizers", "nodes.rules.process") +-- tasks.disableaction("shipouts", "nodes.rules.process") -- only kick in when used + +local trace_shifted = false trackers.register("nodes.shifted", function(v) trace_shifted = v end) + +local a_shifted = attributes.private('shifted') + +nodes.shifts = nodes.shifts or { } +nodes.shifts.data = nodes.shifts.data or { } + +storage.register("nodes/shifts/data", nodes.shifts.data, "nodes.shifts.data") + +local data = nodes.shifts.data + +function nodes.shifts.define(settings) + data[#data+1] = settings + texwrite(#data) +end + +local function flush_shifted(head,first,last,data,level,parent,strip) -- not that fast but acceptable for this purpose + if true then + first, last = strip_range(first,last) + end + local prev, next = first.prev, last.next + first.prev, last.next = nil, nil + local width, height, depth = list_dimensions(parent.glue_set,parent.glue_sign,parent.glue_order,first,next) + local list = hpack_nodes(first,width,"exactly") + if first == head then + head = list + end + if prev then + prev.next, list.prev = list, prev + end + if next then + next.prev, list.next = list, next + end + local raise = data.dy * dimenfactor(data.unit,fontdata[first.font]) + list.shift, list.height, list.depth = raise, height, depth + if trace_shifted then + logs.report("shifted", "width: %s, nodes: %s, text: %s",width,n_tostring(first,last),n_tosequence(first,last,true)) + end + return head +end + +local process = nodes.process_words + +nodes.shifts.process = function(head) return process(a_shifted,data,flush_shifted,head) end + +function nodes.shifts.enable() + tasks.enableaction("shipouts","nodes.shifts.process") +end diff --git a/tex/context/base/node-rul.mkiv b/tex/context/base/node-rul.mkiv new file mode 100644 index 000000000..1270eb81d --- /dev/null +++ b/tex/context/base/node-rul.mkiv @@ -0,0 +1,343 @@ +%D \module +%D [ file=node-rul, +%D version=2009.11.03, % 1995.10.10, +%D title=\CONTEXT\ Core Macros, +%D subtitle=Bars, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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: ex and and em traveling with attribute + +\writestatus{loading}{ConTeXt Core Macros / Bars} + +%D The name of this file might change. + +%D \macros +%D {underbar,underbars, +%D overbar,overbars, +%D overstrike,overstrikes, +%D setupbar} +%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 \showsetup{setupunderbar} + +\unprotect + +%definesystemattribute[ruled] +%definesystemattribute[shifted] + +\registerctxluafile{node-rul}{1.001} + +\newtoks\checkalldefinedbars + +\def\barparameter #1{\csname\dobarparameter\currentbar#1\endcsname} +\def\dobarparameter #1#2{\ifcsname\??on#1#2\endcsname\??on#1#2\else\expandafter\dobarparentparameter\csname\??on#1\s!parent\endcsname#2\fi} +\def\dobarparentparameter#1#2{\ifx#1\relax\s!empty\else\dobarparameter#1#2\fi} + +\unexpanded\def\definebar + {\dotripleempty\dodefinebar} + +\def\dodefinebar[#1][#2][#3]% + {\ifthirdargument + \getparameters[\??on#1][\s!parent=#2,#3]% + \else + \getparameters[\??on#1][\s!parent=,#2]% + \fi + % + %\setvalue{\??on:#1}{0}% + % + \ifcsname\??on:#1:c\endcsname + \csname\??on:#1:c\endcsname\zerocount + \else + \expandafter\newcount\csname\??on:#1:c\endcsname + \fi + \normalexpanded{\checkalldefinedbars{\noexpand\doredefinebar{#1}\the\checkalldefinedbars}}% + \dodefinebarindeed{#1}% + \setuvalue{#1}{\doruled{#1}}} + +\def\dodefinebarindeed#1% + {\bgroup + \def\currentbar{#1}% + \doifsomethingelse{\barparameter\c!color} + {\donetrue\colored[\barparameter\c!color]} + {\donefalse}% + \normalexpanded + {\egroup + \scratchcounter\ctxlua{nodes.rules.define { + method = \barparameter\c!method, + offset = \barparameter\c!offset, + continue = "\barparameter\c!continue", + dy = \barparameter\c!dy, + rulethickness = \barparameter\c!rulethickness, + unit = "\barparameter\c!unit", + order = "\barparameter\c!order", + max = \barparameter\c!max, + ma = \ifdone\the\attribute\colormodelattribute \else0\fi, + ca = \ifdone\the\attribute\colorattribute \else0\fi, + ta = \ifdone\the\attribute\transparencyattribute\else0\fi + }}}% + \setevalue{\??on#1:a}{\the\scratchcounter}} + +\let\doredefinebar\dodefinebarindeed + +\def\doruled#1% + {\groupedcommand{\dodoruled{#1}}\relax} + +\def\dodoruled + {\ctxlua{nodes.rules.enable()}% + \glet\dodoruled\dodoruledindeed + \dodoruled} + +\def\dodoruledindeed#1% + {\advance\csname\??on:#1:c\endcsname\plusone + \scratchcounter\csname\??on:#1:c\endcsname + \attribute\ruledattribute\numexpr1000*\scratchcounter + +\csname\??on#1\ifcsname\??on#1:\number\scratchcounter\s!parent\endcsname:\number\scratchcounter\fi:a\endcsname} + +% ungrouped + +\unexpanded\def\startbar[#1]% + {\begingroup + \dodoruled{#1}} + +\unexpanded\def\stopbar + {\endgroup} + +\newcount\currentbarnesting % todo: same as colors + +\unexpanded\def\pushbar[#1]% + {\global\advance\currentbarnesting\plusone + \expandafter\edef\csname\??on:s:\number\currentbarnesting\endcsname + {\attribute\ruledattribute\the\attribute\ruledattribute}% stack + \dodoruled{#1}} + +\unexpanded\def\popbar + {\csname\??on:s:\number\currentbarnesting\endcsname + \global\advance\currentbarnesting\minusone} + +\unexpanded\def\setupbars + {\dodoubleempty\dosetupbars} + +\def\dosetupbars[#1][#2]% not that efficient + {\ifsecondargument + \getparameters[\??on#1][#2]% + \dodefinebarindeed{#1}% + \else + \getparameters[\??on][#1]% + \the\checkalldefinedbars + \fi} + +\setupbars + [\c!method=0, % new: 0=center nested, 1=stack nested + \c!continue=\v!no, + \c!offset=0, % upwards, replaces: topoffset bottomoffset + \c!dy=0, + \c!max=3, + \c!rulethickness=.1, + \c!order=\v!foreground, + \c!unit=ex, % so now we are relative + \c!color=] % replaces: rulecolor + +% \definebar[touchbar] [\c!method=0,\c!dy=-0.4,\c!offset=-0.0] +% \definebar[touchbars] [touchbar] [\c!continue=\v!yes] + +\definebar[\v!overstrike] [\c!method=0,\c!dy= 0.4,\c!offset= 0.5,\c!continue=\v!yes] +\definebar[\v!underbar] [\c!method=1,\c!dy=-0.4,\c!offset=-0.3,\c!continue=\v!yes] +\definebar[\v!overbar] [\c!method=1,\c!dy= 0.4,\c!offset= 1.8,\c!continue=\v!yes] + +\definebar[\v!overstrikes] [\v!overstrike] [\c!continue=\v!no] +\definebar[\v!underbars] [\v!underbar] [\c!continue=\v!no] +\definebar[\v!overbars] [\v!overbar] [\c!continue=\v!no] + +% we want these always so ... + +\expandafter\let\expandafter\overstrike \csname\v!overstrike \endcsname +\expandafter\let\expandafter\underbar \csname\v!underbar \endcsname +\expandafter\let\expandafter\overbar \csname\v!overbar \endcsname +\expandafter\let\expandafter\overstrikes\csname\v!overstrikes\endcsname +\expandafter\let\expandafter\underbars \csname\v!underbars \endcsname +\expandafter\let\expandafter\overbars \csname\v!overbars \endcsname + +\unexpanded\def\setupunderbar[#1]% too incompatible for the moment + {} + +%D This will move: (a bit duplicated) + +\newtoks\checkalldefinedshifts + +\def\shiftparameter #1{\csname\doshiftparameter\currentshift#1\endcsname} +\def\shiftparameterhash#1{\doshiftparameterhash{\??ra\currentshift}#1} + +\def\doshiftparameter #1#2{\ifcsname\??ra#1#2\endcsname\??ra#1#2\else\expandafter\doshiftparentparameter\csname\??ra#1\s!parent\endcsname#2\fi} +\def\doshiftparameterhash#1#2{\ifcsname#1#2\endcsname#1\else\expandafter\doshiftparentparameterhash\csname#1\s!parent\endcsname#2\fi} + +\def\doshiftparentparameter #1#2{\ifx#1\relax\s!empty\else\doshiftparameter #1#2\fi} +\def\doshiftparentparameterhash#1#2{\ifx#1\relax \else\doshiftparameterhash#1#2\fi} + +\def\dosetshiftattributes#1#2% style color + {\edef\fontattributehash {\shiftparameterhash#1}% + \edef\colorattributehash{\shiftparameterhash#2}% + \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi + \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi} + +\unexpanded\def\defineshift + {\dotripleempty\dodefineshift} + +\def\dodefineshift[#1][#2][#3]% + {\ifthirdargument + \getparameters[\??ra#1][\s!parent=#2,#3]% + \else + \getparameters[\??ra#1][\s!parent=,#2]% + \fi + % + %\setvalue{\??ra:#1}{0}% + % + \ifcsname\??ra:#1:c\endcsname + \csname\??ra:#1:c\endcsname\zerocount + \else + \expandafter\newcount\csname\??ra:#1:c\endcsname + \fi + \normalexpanded{\checkalldefinedshifts{\noexpand\doredefineshift{#1}\the\checkalldefinedshifts}}% + \dodefineshiftindeed{#1}% + \setuvalue{#1}{\doshifted{#1}}} + +\def\dodefineshiftindeed#1% + {\bgroup + \def\currentshift{#1}% + \normalexpanded + {\egroup + \scratchcounter\ctxlua{nodes.shifts.define { + method = \shiftparameter\c!method, + continue = "\shiftparameter\c!continue", + dy = \shiftparameter\c!dy, + unit = "\shiftparameter\c!unit", + }}}% + \setevalue{\??ra#1:a}{\the\scratchcounter}} + +\let\doredefineshift\dodefineshiftindeed + +\def\doshifted#1% + {\groupedcommand{\dodoshifted{#1}}\relax} + +\def\dodoshifted + {\ctxlua{nodes.shifts.enable()}% + \glet\dodoshifted\dodoshiftedindeed + \dodoshifted} + +% \def\dodoshiftedindeed#1% +% {\def\currentshift{#1}% +% \advance\csname\??ra:#1:c\endcsname\plusone +% \scratchcounter\csname\??ra:#1:c\endcsname +% \attribute\shiftedattribute\numexpr1000*\scratchcounter +% +\csname\??ra#1\ifcsname\??ra#1:\number\scratchcounter\s!parent\endcsname:\number\scratchcounter\fi:a\endcsname +% \setupalign[\shiftparameter\c!align]% +% \dosetshiftattributes\c!style\c!color} + +\def\dostartisolation{\char0 } +\def\dostopisolation {\char0 } +\def\doisolator {\char0 } + +\def\doisolatedgroupedalign#1#2% + {\groupedcommand + {\begingroup\dostartisolation\begingroup#1} + {#2\endgroup\dostopisolation\endgroup}} + +\def\dosetupisolatedalign#1% + {\doisolator + \setupalign[#1]\relax} + +\def\dodoshiftedindeed#1% + {\def\currentshift{#1}% + \advance\csname\??ra:#1:c\endcsname\plusone + \scratchcounter\csname\??ra:#1:c\endcsname + \attribute\shiftedattribute\numexpr1000*\scratchcounter + +\csname\??ra#1\ifcsname\??ra#1:\number\scratchcounter\s!parent\endcsname:\number\scratchcounter\fi:a\endcsname + \dosetshiftattributes\c!style\c!color + \dosetupisolatedalign{\shiftparameter\c!align}} + +\def\doshifted#1% + {\doisolatedgroupedalign{\dodoshifted{#1}}{}} + +\unexpanded\def\startshift[#1]% + {\begingroup + \dodoshifted{#1}} + +\unexpanded\def\stopshift + {\endgroup} + +\unexpanded\def\setupshifts + {\dodoubleempty\dosetupshifts} + +\def\dosetupshifts[#1][#2]% not that efficient + {\ifsecondargument + \getparameters[\??ra#1][#2]% + \dodefineshiftindeed{#1}% + \else + \getparameters[\??ra][#1]% + \the\checkalldefinedshifts + \fi} + +\setupshifts + [\c!method=0, + \c!continue=\v!no, + \c!dy=0, + \c!unit=ex, + \c!align=, + \c!style=, + \c!color=] + +\def\v!shiftup {shiftup} +\def\v!shiftdown{shiftdown} + +\defineshift [\v!shiftup] [\c!method=0,\c!dy=-1,\c!unit=ex,\c!continue=\v!yes,\c!style=\txx,\c!color=] +\defineshift [\v!shiftdown] [\c!method=1,\c!dy=.3,\c!unit=ex,\c!continue=\v!yes,\c!style=\txx,\c!color=] + +% we want these always so ... + +\expandafter\let\expandafter\shiftup \csname\v!shiftup \endcsname +\expandafter\let\expandafter\shiftdown \csname\v!shiftdown \endcsname + +\protect \endinput + +% obsolete: + +\setupunderbar + [\c!alternative=a, + \c!rulethickness=\linewidth, + \c!bottomoffset=1.5pt, + \c!topoffset=2.5pt, + \c!rulecolor=] diff --git a/tex/context/base/node-seq.lua b/tex/context/base/node-seq.lua new file mode 100644 index 000000000..3a2cf5b6e --- /dev/null +++ b/tex/context/base/node-seq.lua @@ -0,0 +1,186 @@ +if not modules then modules = { } end modules ['node-seq'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--[[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]]-- + +-- todo: delayed: i.e. we register them in the right order already but delay usage + +local format, gsub, concat, gmatch = string.format, string.gsub, table.concat, string.gmatch +local type, loadstring = type, loadstring + +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 = { }, + order = { }, + kind = { }, + askip = { }, + gskip = { }, + } +end + +function sequencer.prependgroup(t,group,where) + local list, order = t.list, t.order + table.remove_value(order,group) + table.insert_before_value(order,where,group) + list[group] = { } +end + +function sequencer.appendgroup(t,group,where) + local list, order = t.list, t.order + table.remove_value(order,group) + table.insert_after_value(order,where,group) + list[group] = { } +end + +function sequencer.prependaction(t,group,action,where,kind,force) + local g = t.list[group] + 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,force) + local g = t.list[group] + if g and (force or validaction(action)) then + table.remove_value(g,action) + table.insert_after_value(g,where,action) + t.kind[action] = kind + end +end + +function sequencer.enableaction (t,action) t.askip[action] = false end +function sequencer.disableaction(t,action) t.askip[action] = true end +function sequencer.enablegroup (t,group) t.gskip[group] = false end +function sequencer.disablegroup (t,group) t.gskip[group] = true end + +function sequencer.setkind(t,action,kind) + t.kind[action] = kind +end + +function sequencer.removeaction(t,group,action,force) + local g = t.list[group] + if g and (force or validaction(action)) then + table.remove_value(g,action) + end +end + +function sequencer.compile(t,compiler,n) + if type(t) == "string" then + -- already compiled + elseif compiler then + t = compiler(t,n) + else + t = sequencer.tostring(t) + end + return loadstring(t)() +end + +local function localize(str) + return (gsub(str,"%.","_")) +end + +local template = [[ +%s +return function(...) +%s +end]] + +function sequencer.tostring(t) + local list, order, kind, gskip, askip = t.list, t.order, t.kind, t.gskip, t.askip + local vars, calls, args = { }, { }, nil + for i=1,#order do + local group = order[i] + if not gskip[group] then + local actions = list[group] + for i=1,#actions do + local action = actions[i] + if not askip[action] then + local localized = localize(action) + vars [#vars +1] = format("local %s = %s", localized, action) + calls[#calls+1] = format(" %s(...) -- %s %i", localized, group, i) + end + end + end + end + return format(template,concat(vars,"\n"),concat(calls,"\n")) +end + +-- we used to deal with tail as well but now that the lists are always +-- double linked and the kernel function no longer expect tail as +-- argument we stick to head and done (done can probably also go +-- as luatex deals with return values efficiently now .. in the +-- past there was some copying involved, but no longer) + +local template = [[ +%s +return function(head%s) + local ok, done = false, false +%s + return head, done +end]] + +function sequencer.nodeprocessor(t,n) + local list, order, kind, gskip, askip = t.list, t.order, t.kind, t.gskip, t.askip + local vars, calls, args = { }, { }, nil + if n == 0 then + args = "" + elseif n == 1 then + args = ",one" + elseif n == 2 then + args = ",one,two" + elseif n == 3 then + args = ",one,two,three" + elseif n == 4 then + args = ",one,two,three,four" + elseif n == 5 then + args = ",one,two,three,four,five" + else + args = ",..." + end + for i=1,#order do + local group = order[i] + if not gskip[group] then + local actions = list[group] + for i=1,#actions do + local action = actions[i] + if not askip[action] then + 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%s) done = done or ok -- %s %i",localized,args,group,i) + else + calls[#calls+1] = format(" head, ok = %s(head%s) done = done or ok -- %s %i",localized,args,group,i) + end + end + end + end + end + local processor = format(template,concat(vars,"\n"),args,concat(calls,"\n")) +--~ print(processor) + return processor +end diff --git a/tex/context/base/node-ser.lua b/tex/context/base/node-ser.lua new file mode 100644 index 000000000..e632e92da --- /dev/null +++ b/tex/context/base/node-ser.lua @@ -0,0 +1,276 @@ +if not modules then modules = { } end modules ['node-ser'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + 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 t == "boolean" then + handle(format("%s %s=%q,",depth,key(k),tostring(v))) + 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..50b16efa5 --- /dev/null +++ b/tex/context/base/node-shp.lua @@ -0,0 +1,58 @@ +if not modules then modules = { } end modules ['node-shp'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + 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 kern = node.id('kern') +local glue = node.id('glue') + +local free_node = node.free +local remove_node = node.remove + +local function cleanup_page(head) -- rough + local start = head + while start do + local id = start.id + if id == disc or (id == glue and not start.writable) or (id == kern and start.kern == 0) or id == mark then + head, start, tmp = remove_node(head,start) + free_node(tmp) + elseif id == hlist or id == vlist then + local sl = start.list + if sl then + start.list = cleanup_page(sl) + start = start.next + else + head, start, tmp = remove_node(head,start) + free_node(tmp) + end + else + start = start.next + end + end + return head +end + +nodes.cleanup_page_first = false + +function nodes.cleanup_page(head) + -- about 10% of the nodes make no sense for the backend + if nodes.cleanup_page_first then + head = cleanup_page(head) + end + return head, false +end + +local actions = tasks.actions("shipouts",0) -- no extra arguments + +function nodes.process_page(head) -- problem, attr loaded before node, todo ... + return actions(head) +end + +--~ nodes.process_page = actions diff --git a/tex/context/base/node-tex.lua b/tex/context/base/node-tex.lua new file mode 100644 index 000000000..a6eef3269 --- /dev/null +++ b/tex/context/base/node-tex.lua @@ -0,0 +1,39 @@ +if not modules then modules = { } end modules ['node-tex'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + 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) + -- starttiming(kernel) + local done = hyphenate(head) + -- stoptiming(kernel) + return head, done +end + +function kernel.ligaturing(head) + -- starttiming(kernel) + local head, tail, done = ligaturing(head) -- todo: check what is returned + -- stoptiming(kernel) + return head, done +end + +function kernel.kerning(head) + -- starttiming(kernel) + local head, tail, done = kerning(head) -- todo: check what is returned + -- stoptiming(kernel) + return head, done +end + +callbacks.register('hyphenate' , false, "normal hyphenation routine, called elsewhere") +callbacks.register('ligaturing', false, "normal ligaturing routine, called elsewhere") +callbacks.register('kerning' , false, "normal kerning routine, called elsewhere") diff --git a/tex/context/base/node-tra.lua b/tex/context/base/node-tra.lua new file mode 100644 index 000000000..5acd70baf --- /dev/null +++ b/tex/context/base/node-tra.lua @@ -0,0 +1,474 @@ +if not modules then modules = { } end modules ['node-tra'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + 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. This module will be cleaned up!

+--ldx]]-- + +local utf = unicode.utf8 +local format, match, concat, rep, utfchar = string.format, string.match, table.concat, string.rep, 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 hlist = node.id('hlist') +local vlist = node.id('vlist') +local disc = node.id('disc') +local glue = node.id('glue') +local kern = node.id('kern') +local rule = node.id('rule') +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 + local variables = { + ['title'] = 'ConTeXt Character Processing Information', + ['color-background-one'] = lmx.get('color-background-yellow'), + ['color-background-two'] = lmx.get('color-background-purple'), + } + lmx.show('context-characters.lmx',variables) + 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.sortedhash(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,"trace",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,"trace",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_nodes(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,compact) + if start then + local t = { } + while start do + local id = start.id + if id == glyph then + local c = start.char + if compact then + if start.components then + t[#t+1] = nodes.tosequence(start.components,nil,compact) + else + t[#t+1] = format("%s",utfchar(c)) + end + else + t[#t+1] = format("U+%04X:%s",c,utfchar(c)) + end + elseif id == whatsit and start.subtype == 6 or start.subtype == 7 then + t[#t+1] = "[" .. start.dir .. "]" + elseif id == rule then + if compact then + t[#t+1] = "|" + else + t[#t+1] = node_type(id) + end + else + if compact then + t[#t+1] = "[]" + else + t[#t+1] = node_type(id) + end + end + if start == stop then + break + else + start = start.next + end + end + if compact then + return concat(t) + else + return concat(t," ") + end + else + return "[empty]" + end +end + +function nodes.report(t,done) + if done then + if status.output_active then + logs.report("nodes","output, changed, %s nodes",nodes.count(t)) + else + texio.write("nodes","normal, changed, %s nodes",nodes.count(t)) + end + else + if status.output_active then + logs.report("nodes","output, unchanged, %s nodes",nodes.count(t)) + else + texio.write("nodes","normal, unchanged, %s nodes",nodes.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,tail) + local t, last_id, last_n = { }, nil, 0 + for n in traverse_nodes(head,tail) do -- hm, does not stop at tail + 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 + if n == tail then + break + 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 + +nodes.ids_tostring = nodes.ids_to_string + +local function show_simple_list(h,depth,n) + while h do + texio.write_nl(rep(" ",n) .. tostring(h)) + if not depth or n < depth then + local id = h.id + if id == hlist or id == vlist then + show_simple_list(h.list,depth,n+1) + end + end + h = h.next + end +end + +--~ \startluacode +--~ callback.register('buildpage_filter',function() nodes.show_simple_list(tex.lists.contrib_head) end) +--~ \stopluacode +--~ \vbox{b\footnote{n}a} +--~ \startluacode +--~ callback.register('buildpage_filter',nil) +--~ \stopluacode + +nodes.show_simple_list = function(h,depth) show_simple_list(h,depth,0) end + +function nodes.list_to_utf(h,joiner) + local joiner = (joiner ==true and utfchar(0x200C)) or joiner -- zwnj + local w = { } + while h do + if h.id == glyph then -- always true + w[#w+1] = utfchar(h.char) + if joiner then + w[#w+1] = joiner + end + else + w[#w+1] = "[-]" + end + h = h.next + end + return concat(w) +end diff --git a/tex/context/base/node-tsk.lua b/tex/context/base/node-tsk.lua new file mode 100644 index 000000000..206b4a266 --- /dev/null +++ b/tex/context/base/node-tsk.lua @@ -0,0 +1,315 @@ +if not modules then modules = { } end modules ['node-tsk'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- this might move to task-* + +local trace_tasks = false trackers.register("tasks.creation", 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) + local data = tasks.data[name] + if data then + data.runner = false + end +end + +function tasks.enableaction(name,action) + local data = tasks.data[name] + if data then + sequencer.enableaction(data.list,action) + data.runner = false + end +end + +function tasks.disableaction(name,action) + local data = tasks.data[name] + if data then + sequencer.disableaction(data.list,action) + data.runner = false + end +end + +function tasks.enablegroup(name,group) + local data = tasks.data[name] + if data then + sequencer.enablegroup(data.list,group) + data.runner = false + end +end + +function tasks.disablegroup(name,group) + local data = tasks.data[name] + if data then + sequencer.disablegroup(data.list,group) + 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 + +-- Optimizing for the number of arguments makes sense, but getting rid of +-- the nested call (no problem but then we also need to register the +-- callback with this mechanism so that it gets updated) does not save +-- much time (24K calls on mk.tex). + +local created, total = 0, 0 + +statistics.register("node list callback tasks", function() + if total > 0 then + return string.format("%s unique task lists, %s instances (re)created, %s calls",table.count(tasks.data),created,total) + else + return nil + end +end) + +local compile, nodeprocessor = sequencer.compile, sequencer.nodeprocessor + +function tasks.actions(name,n) -- we optimize for the number or arguments (no ...) + local data = tasks.data[name] + if data then + if n == 0 then + return function(head) + local runner = data.runner + total = total + 1 -- will go away + if not runner then + created = created + 1 + if trace_tasks then + logs.report("nodes","creating task runner '%s'",name) + end + runner = compile(data.list,nodeprocessor,0) + data.runner = runner + end + return runner(head) + end + elseif n == 1 then + return function(head,one) + total = total + 1 -- will go away + local runner = data.runner + if not runner then + created = created + 1 + if trace_tasks then + logs.report("nodes","creating task runner '%s' with 1 extra arguments",name) + end + runner = compile(data.list,nodeprocessor,1) + data.runner = runner + end + return runner(head,one) + end + elseif n == 2 then + return function(head,one,two) + total = total + 1 -- will go away + local runner = data.runner + if not runner then + created = created + 1 + if trace_tasks then + logs.report("nodes","creating task runner '%s' with 2 extra arguments",name) + end + runner = compile(data.list,nodeprocessor,2) + data.runner = runner + end + return runner(head,one,two) + end + elseif n == 3 then + return function(head,one,two,three) + total = total + 1 -- will go away + local runner = data.runner + if not runner then + created = created + 1 + if trace_tasks then + logs.report("nodes","creating task runner '%s' with 3 extra arguments",name) + end + runner = compile(data.list,nodeprocessor,3) + data.runner = runner + end + return runner(head,one,two,three) + end + elseif n == 4 then + return function(head,one,two,three,four) + total = total + 1 -- will go away + local runner = data.runner + if not runner then + created = created + 1 + if trace_tasks then + logs.report("nodes","creating task runner '%s' with 4 extra arguments",name) + end + runner = compile(data.list,nodeprocessor,4) + data.runner = runner + end + return runner(head,one,two,three,four) + end + elseif n == 5 then + return function(head,one,two,three,four,five) + total = total + 1 -- will go away + local runner = data.runner + if not runner then + created = created + 1 + if trace_tasks then + logs.report("nodes","creating task runner '%s' with 5 extra arguments",name) + end + runner = compile(data.list,nodeprocessor,5) + data.runner = runner + end + return runner(head,one,two,three,four,five) + end + else + return function(head,...) + total = total + 1 -- will go away + local runner = data.runner + if not runner then + created = created + 1 + if trace_tasks then + logs.report("nodes","creating task runner '%s' with n extra arguments",name) + end + runner = compile(data.list,nodeprocessor,"n") + data.runner = runner + end + return runner(head,...) + end + end + else + return nil + end +end + +function tasks.table(name) --maybe move this to task-deb.lua + local tsk = tasks.data[name] + local lst = tsk and tsk.list + local HL, NC, NR, bold, type = context.HL, context.NC, context.NR, context.bold, context.type + if lst then + local list, order = lst.list, lst.order + if list and order then + context.starttabulate { "|l|l|" } + NC() bold("category") NC() bold("function") NC() NR() + for i=1,#order do + HL() + local o = order[i] + local l = list[o] + if #l == 0 then + NC() type(o) NC() context("unset") NC() NR() + else + local done = false + for k, v in table.sortedhash(l) do + NC() if not done then type(o) done = true end NC() type(v) NC() NR() + end + end + end + context.stoptabulate() + end + 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 + } +) + +tasks.new ( + "mvlbuilders", + { + "before", -- for users + "normalizers", + "after", -- for users + } +) + +tasks.new ( + "vboxbuilders", + { + "before", -- for users + "normalizers", + "after", -- for users + } +) + +--~ tasks.new ( +--~ "parbuilders", +--~ { +--~ "before", -- for users +--~ "lists", +--~ "after", -- for users +--~ } +--~ ) + +--~ tasks.new ( +--~ "pagebuilders", +--~ { +--~ "before", -- for users +--~ "lists", +--~ "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..d7ea96f26 --- /dev/null +++ b/tex/context/base/node-tst.lua @@ -0,0 +1,119 @@ +if not modules then modules = { } end modules ['node-tst'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local glue = node.id("glue") +local penalty = node.id("penalty") +local kern = node.id("kern") +local glyph = node.id("glyph") +local whatsit = node.id("whatsit") +local hlist = node.id("hlist") + +local find_node_tail = node.tail or node.slide + +local chardata = characters.data + +function nodes.the_left_margin(n) -- todo: three values + while n do + local id = n.id + if id == glue then + if n.subtype == 8 then -- 7 in c/web source + return n.spec.width + 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.the_right_margin(n) + if n then + n = find_node_tail(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.width + 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/node-typ.lua b/tex/context/base/node-typ.lua new file mode 100644 index 000000000..5ab6b6975 --- /dev/null +++ b/tex/context/base/node-typ.lua @@ -0,0 +1,53 @@ +if not modules then modules = { } end modules ['node-typ'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- this will be replaced by blob-ini cum suis so typesetting will go away + +local utfvalues = string.utfvalues + +local newglyph = nodes.glyph +local newglue = nodes.glue + +local hpack, vpack = node.hpack, node.vpack + +typesetting = typesetting or { } + +local function tonodes(str,fontid,spacing) -- don't use this + local head, prev = nil, nil + for s in utfvalues(str) do + local next + if spacing and s == 32 then + next = newglue(spacing or 64*1024*10) + else + next = newglyph(fontid or 1,s) + end + if not head then + head = next + else + prev.next = next + next.prev = prev + end + prev = next + end + return head +end + +typesetting.tonodes = tonodes + +function typesetting.hpack(str,fontid,spacing) + return hpack(tonodes(str,fontid,spacing)) +end + +function typesetting.vpack(str,fontid,spacing) + -- vpack is just a hack, and a proper implentation is on the agenda + -- as it needs more info etc than currently available + return vpack(tonodes(str,fontid,spacing)) +end + +--~ node.write(typesetting.hpack("Hello World!")) +--~ node.write(typesetting.hpack("Hello World!",1,100*1024*10)) 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..a779735dd --- /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 (incomplete) + +\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..8f911d874 --- /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 % obsolete +\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 % obsolete +\let \normalpdfnames = \pdfnames +\let \normalpdfnoligatures = \pdfnoligatures +\let \normalpdfnormaldeviate = \pdfnormaldeviate +\let \normalpdfobj = \pdfobj +\let \normalpdfobjcompresslevel = \pdfobjcompresslevel +\let \normalpdfoptionalwaysusepdfpagebox = \pdfoptionalwaysusepdfpagebox % obsolete +\let \normalpdfoptionpdfinclusionerrorlevel = \pdfoptionpdfinclusionerrorlevel % obsolete +\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/pack-bar.mkiv b/tex/context/base/pack-bar.mkiv new file mode 100644 index 000000000..05afd32d0 --- /dev/null +++ b/tex/context/base/pack-bar.mkiv @@ -0,0 +1,67 @@ +%D \module +%D [ file=pack-bar, +%D version=2009.06.26, +%D title=\CONTEXT\ Packaging Macros, +%D subtitle=Bars, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 Packaging Macros / Bars} + +%D This code has been moved from scrn-int to here (was some old +%D experimental code). It could be in scrn-bar but it's static. + +\unprotect + +%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\numexpr#1-#2+\plusone\relax + \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\numexpr#1-#2+\plusone\relax + \leaders\hrule\vskip\zeropoint\!!plus\scratchcounter\!!fill + \hrule\!!width#4\!!height\zeropoint\!!depth\zeropoint + \vskip\zeropoint\!!plus #3\!!fill + \vskip\zeropoint\!!plus-#1\!!fill}} + +\protect \endinput diff --git a/tex/context/base/pack-box.mkii b/tex/context/base/pack-box.mkii new file mode 100644 index 000000000..8adeedb91 --- /dev/null +++ b/tex/context/base/pack-box.mkii @@ -0,0 +1,954 @@ +%D \module +%D [ file=pack-box, +%D version=2002.04.12, +%D title=\CONTEXT\ Packaging Macros, +%D subtitle=Boxes, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 Packaging Macros / Boxes} + +%D This module contains all kind of macros for moving content +%D around. Many macros here come from other modules, but +%D depencies made it more clear to isolate them. + +% \placeornament + +\unprotect + +% \definelayer[\v!tekst-2][\c!positie=\v!ja] +% \definelayer[\v!tekst-1][\c!positie=\v!ja] +% \definelayer[\v!tekst+1][\c!positie=\v!ja] +% \definelayer[\v!tekst+2][\c!positie=\v!ja] + +% we need to set the size, else we get dimensions depending +% on the content, which in itsel fis ok, but can lead to loops +% due to rounding errors (happened in demo-obv) + +\definelayer[\v!text-2][\c!position=\v!yes,\c!width=\overlaywidth,\c!height=\overlayheight] +\definelayer[\v!text-1][\c!position=\v!yes,\c!width=\overlaywidth,\c!height=\overlayheight] +\definelayer[\v!text+1][\c!position=\v!yes,\c!width=\overlaywidth,\c!height=\overlayheight] +\definelayer[\v!text+2][\c!position=\v!yes,\c!width=\overlaywidth,\c!height=\overlayheight] + +\def\internaltextoverlay#1% will become more generic and installable + {\startoverlay % i.e. probably an overlay by itself + {\positionoverlay{\v!text#1}} % see later + {\composedlayer {\v!text#1}} + \stopoverlay} + +%\def\internaltextoverlay#1% +% {\hbox to \zeropoint{\positionoverlay{\v!tekst#1}\hss}% +% \composedlayer{\v!tekst#1}} + +% todo: share info, so that tuo will be smaller + +\defineoverlay[\v!text-2][\internaltextoverlay{-2}] +\defineoverlay[\v!text-1][\internaltextoverlay{-1}] +\defineoverlay[\v!text+1][\internaltextoverlay{+1}] +\defineoverlay[\v!text+2][\internaltextoverlay{+2}] + +% to be documented + +\definelayer[anchor] + +\def\anchor + {\dosingleargument\doanchor} + +\def\doanchor[#1]% + {\ifundefined{\??an#1}\@EA\dodoanchor\else\@EA\nonoanchor\fi[#1]} + +\def\nonoanchor[#1]% + {\getvalue{\??an#1}} + +\def\dodoanchor[#1]% + {\dotripleempty\dododoanchor[#1]} + +\def\dododoanchor + {\ifthirdargument + \expandafter\dodoanchorT + \else + \expandafter\dodoanchorS + \fi} + +\def\dodoanchorS[#1][#2][#3]% + {\dodoanchorT[#1][#2][#2]} + +\def\dodoanchorT[#1][#2][#3]% + {\dowithnextbox + {\bgroup + \checktextbackgrounds + \setbox\scratchbox\null + \wd\scratchbox\nextboxwd + \ht\scratchbox\nextboxht + \dp\scratchbox\nextboxdp + \setlayer + [anchor] + [\c!width=\wd\scratchbox, + \c!height=\ht\scratchbox, + \c!offset=\!!zeropoint, + #2,#3] + {\setlayer[#1]{\flushnextbox}}% + \framed + [#2, + \c!background=anchor, + \c!offset=\v!overlay, + \c!frame=\v!off, + #3] + {\box\scratchbox}% + \egroup}% + \vbox} + +\def\defineanchor + {\doquadrupleempty\dodefineanchor} + +\def\dodefineanchor[#1][#2][#3][#4]% + {\setvalue{\??an#1}{\dodefinedanchor[#2][#3][#4]}} + +\def\dodefinedanchor[#1][#2][#3]% + {\def\docommand[##1][##2]% + {\ifsecondargument + \def\next{\dodoanchorT[#1][#2,##1][#3,##2]}% + \else\iffirstargument + \def\next{\dodoanchorT[#1][#2,##1][#2,##1]}% + \else + \def\next{\dodoanchorT[#1][#2][#3]}% + \fi\fi + \next}% + \dodoubleempty\docommand} + +\def\@@collectorbox{@@collectorbox} + +\def\definecollector + {\dodoubleargument\dodefinecollector} + +\def\dodefinecollector[#1][#2]% + {\ifundefined{\@@collectorbox#1}% + \expandafter\newbox\csname\@@collectorbox#1\endcsname + \fi + \resetcollector[#1]% + \setupcollector + [#1] + [\c!state=\v!start, + \c!x=\!!zeropoint,\c!y=\!!zeropoint, + \c!offset=\!!zeropoint,\c!rotation=, % geen 0 ! + \c!hoffset=\!!zeropoint,\c!voffset=\!!zeropoint, + \c!location=rb,\c!corner=,#2]} + +\def\setupcollector + {\dodoubleargument\dosetupcollector} + +\def\dosetupcollector[#1][#2]% + {\def\docommand##1{\getparameters[\??cb##1][#2]}% + \processcommalist[#1]\docommand} + +\def\setcollector + {\dodoubleargument\dosetcollector} + +\def\dosetcollector[#1][#2]% + {\bgroup + \forgetall + \dontcomplain + \dowithnextbox + {\ifundefined{\@@collectorbox#1}% + \writestatus{collector}{unknown layer #1}% + \else + \dodosetcollector[#1][#2]% + \fi + \egroup} + \hbox} + +\def\collectorparameter#1{\csname\??cb\currentcollector#1\endcsname} + +\def\dodosetcollector[#1][#2]% todo: keep reference point + {\def\currentcollector{#1}% + \mathchardef\collectorbox\csname\@@collectorbox#1\endcsname + \getparameters[\??cb#1][#2]% + \@@layerxsiz\wd\collectorbox + \@@layerysiz\ht\collectorbox + \doifvaluesomething{\??cb#1\c!rotation} + {\setbox\nextbox\hbox + {\rotate + [\c!location=\v!high, + \c!rotation=\collectorparameter\c!rotation] + {\flushnextbox}}}% + \advance\@@layerysiz\dp\collectorbox + \@@layerxpos\collectorparameter\c!x + \advance\@@layerxpos\collectorparameter\c!hoffset + \@@layerypos\collectorparameter\c!y + \advance\@@layerypos\collectorparameter\c!voffset + \doifelse\v!middle{\collectorparameter\c!corner} + {\ifdim\@@layerxsiz>\zeropoint + \advance\@@layerxpos.5\@@layerxsiz + \fi + \ifdim\@@layerysiz>\zeropoint + \advance\@@layerypos.5\@@layerysiz + \fi}% + {\ExpandBothAfter\doifinset\v!bottom{\collectorparameter\c!corner} + {\ifdim\@@layerysiz>\zeropoint + \advance\@@layerypos-\@@layerysiz + \@@layerypos-\@@layerypos + \fi}% + \ExpandBothAfter\doifinset\v!right{\collectorparameter\c!corner} + {\ifdim\@@layerxsiz>\zeropoint + \advance\@@layerxpos-\@@layerxsiz + \@@layerxpos-\@@layerxpos + \fi}}% + \setbox\nextbox\hbox + {\alignedbox[\collectorparameter\c!location]\vbox{\flushnextbox}}% + \boxmaxdepth\zeropoint % really needed, nice example + \global\advance\boxhdisplacement\@@layerxpos + \ifdim\boxhdisplacement<\zeropoint + \global\setbox\collectorbox\hbox + {\hskip-\boxhdisplacement + \box\collectorbox}% + \fi + \global\advance\boxvdisplacement\@@layerypos + \ifdim\boxvdisplacement<\zeropoint + \global\setbox\collectorbox\hbox + {\lower-\boxvdisplacement + \box\collectorbox}% + \fi + \@@layerxsiz\wd\collectorbox + \@@layerysiz\ht\collectorbox + \advance\@@layerysiz\dp\collectorbox + \global\setbox\collectorbox\hbox + {\box\collectorbox + \hskip-\@@layerxsiz + \hskip\@@layerxpos\relax + \ifdim\boxhdisplacement<\zeropoint + \hskip-\boxhdisplacement + \fi + \lower\@@layerypos\hbox + {\ifdim\boxvdisplacement<\zeropoint + \lower-\boxvdisplacement\flushnextbox + \else + \flushnextbox + \fi}}% + % combine height and depth into depth only (later flushed as height) + \global\setbox\collectorbox\hbox + {\lower\ht\collectorbox\box\collectorbox}% + % just to be sure + \ifdim\wd\collectorbox<\@@layerxsiz + \global\wd\collectorbox\@@layerxsiz + \fi} + +\def\flushcollector[#1]% + {\ifundefined{\@@collectorbox#1}% + \writestatus{collector}{unknown collector #1}% + \else + \doifnotvalue{\??cb#1\c!state}\v!stop + {\vbox + {\hbox + {\doifelsevalue{\??cb#1\c!state}\v!repeat + {\let\next\copy}{\let\next\box}% + \raise\dp\csname\@@collectorbox#1\endcsname + \next\csname\@@collectorbox#1\endcsname}}}% + \fi} + +\def\composedcollector#1{\flushcollector[#1]} + +\def\resetcollector[#1]% + {\ifundefined{\@@collectorbox#1}\else + \global\setbox\csname\@@collectorbox#1\endcsname\emptybox + \fi} + +\def\adaptcollector + {\dodoubleargument\doadaptcollector} + +\def\doadaptcollector[#1][#2]% + {\bgroup + \def\currentcollector{#1}% + \mathchardef\collectorbox\csname\@@collectorbox#1\endcsname + \getparameters + [\??cb#1][\c!voffset=\zeropoint,\c!hoffset=\zeropoint,#2]% + \scratchdimen\wd\collectorbox + \advance\scratchdimen\collectorparameter\c!hoffset + \global\wd\collectorbox\scratchdimen + \scratchdimen\ht\collectorbox + \advance\scratchdimen\collectorparameter\c!voffset + \global\ht\collectorbox\scratchdimen + \egroup} + +%\definecollector[test] +%\setcollector[test] +% [location=rb] +% {\externalfigure[koe][frame=on,width=3cm]} +%\setcollector[test] +% [corner={right,bottom},location={left,top}] +% {\framed{gans}} +%\composedcollector{test} + +\definecollector + [caption] + +\def\collectedtext + {\dodoubleempty\docollectedtext} + +\def\docollectedtext[#1][#2]#3% + {\bgroup + \dowithnextbox + {\setcollector + [caption] + {\flushnextbox}% + \setcollector + [caption][#1] + {\getparameters[\??du][#2]% + \dosetfontattribute\??du\c!style\setupinterlinespace + \framed % watch the special setting of kader/overlay + [\c!frame=\v!overlay,#2] + {\doattributes\??du\c!style\c!color{#3}}}% + \composedcollector{caption}% + \egroup}% + \hbox} + +% \collectedtext +% [corner={right,bottom},location={left,top}] +% [background=color,backgroundcolor=white,offset=0pt] +% {gans} +% {\externalfigure[koe][width=3cm]} +% +% \collectedtext +% [rotation=90,corner={right,bottom},location={right,top}] +% [frame=on,offset=0pt] +% {gans} +% {\externalfigure[koe][width=3cm]} +% +% \collectedtext +% [rotation=90,corner={left,bottom},location={left,top}] +% [frame=on,offset=0pt] +% {gans} +% {\externalfigure[koe][width=3cm]} + +\definelayer + [caption] + +\def\layeredtext + {\dodoubleempty\dolayeredtext} + +\def\dolayeredtext[#1][#2]#3% + {\bgroup + \dowithnextbox + {\!!widtha \nextboxwd + \!!heighta\nextboxht + \bgroup % preserve \nextbox + \setuplayer + [caption] + [\c!width=\!!widtha,\c!height=\!!heighta]% + \setlayer + [caption] + [#1] + {\getparameters[\??du][#2]% + \dosetfontattribute\??du\c!style\setupinterlinespace + \framed + [\c!frame=\v!overlay,,#2] + {\doattributes\??du\c!style\c!color{#3}}}% + \egroup + \framed + [\c!offset=\v!overlay, + \c!frame=\v!off, + \c!background={\v!foreground,caption}, + \c!width=\!!widtha, + \c!height=\!!heighta] + {\flushnextbox}% + \egroup}% + \hbox} + +% \layeredtext +% [corner={right,bottom},location={left,top}] +% [background=color,backgroundcolor=white,offset=0pt] +% {gans} +% {\externalfigure[koe][width=3cm]} +% +% \layeredtext +% [rotation=90,corner={right,bottom},location={right,top}] +% [frame=on,offset=0pt] +% {gans} +% {\externalfigure[koe][width=3cm]} +% +% \layeredtext +% [rotation=90,corner={left,bottom},location={left,top}] +% [frame=on,offset=0pt] +% {gans} +% {\externalfigure[koe][width=3cm]} + +\def\ornamenttext + {\dodoubleempty\doornamenttext} + +\def\doornamenttext[#1][#2]% + {\bgroup + \doifassignmentelse{#1} + {\getparameters[\s!dummy][\c!alternative=\v!a,#1]% + \doifelse\dummyalternative\v!a + {\egroup\collectedtext}% + {\egroup\layeredtext }% + [#1][#2]}% + {\egroup\getvalue{#1}}} + +\def\defineornament + {\dotripleempty\dodefineornament} + +\def\dodefineornament[#1][#2][#3]% + {\setvalue{#1}{\doornamenttext[#2][#3]}} + +% \defineornament +% [affiliation] +% [rotation=90,corner={right,bottom},location={right,top}, +% hoffset=-.25ex] +% [frame=on,background=color,backgroundcolor=red,offset=0pt] +% +% \ruledhbox{\affiliation{gans}{\externalfigure[koe][width=3cm]}} +% +% \defineornament +% [affiliation] +% [rotation=90,corner={right,bottom},location={right,top}, +% hoffset=-.25ex,alternative=b] +% [frame=on,background=color,backgroundcolor=red,offset=0pt] +% +% \ruledhbox{\affiliation{gans}{\externalfigure[koe][width=3cm]}} +% +% \defineornament +% [affiliation] +% [rotation=90,corner={right,bottom},location={left,top}, +% hoffset=.25ex,voffset=.25ex,alternative=a] +% [background=color,style=\ss\tfxx,backgroundcolor=white,offset=0pt] +% +% \affiliation{photo}{\externalfigure[molen][width=3cm]} +% +% \defineornament +% [affiliation] +% [rotation=90,corner={right,bottom},location={left,top}, +% hoffset=.25ex,voffset=.25ex,alternative=b] +% [background=color,style=\ss\tfxx,backgroundcolor=white,offset=0pt] +% +% \affiliation{drawing}{\externalfigure[hakker][width=3cm]} + +% pas op: aanpassen aan nieuwe layer hoek ankers en columnset + +\newcount\nofbleeds % per pag + +\def\setupbleeding + {\dodoubleempty\getparameters[\??bg]} + +\setupbleeding + [\c!location=l, + \c!stretch=\v!yes, + \c!width=3cm, + \c!height=3cm, + \c!offset=2mm, + \c!page=\v!no, + \c!voffset=\@@bgoffset, + \c!hoffset=\@@bgoffset] + +\def\bleed + {\dosingleempty\dobleed} + + +\def\bleedwidth {\the\hsize}% +\def\bleedheight{\the\vsize}% + +\def\dobleed[#1]#2% + {\hbox\bgroup + \xdef\bleedwidth {\the\hsize}% + \xdef\bleedheight{\the\vsize}% + \global\advance\nofbleeds\plusone + \getparameters[\??bg][#1]% + \!!doneafalse % left + \!!donebfalse % right + \!!donecfalse % top + \!!donedfalse % bottom + % replace this part ! todo: default location + \processaction + [\@@bglocation] + [ t=>\!!donectrue\let\@@bghoffset\!!zeropoint, + b=>\!!donedtrue\let\@@bghoffset\!!zeropoint, + l=>\!!doneatrue\let\@@bgvoffset\!!zeropoint, + r=>\!!donebtrue\let\@@bgvoffset\!!zeropoint, + bl=>\!!doneatrue\!!donedtrue, + lb=>\!!doneatrue\!!donedtrue, + br=>\!!donebtrue\!!donedtrue, + rb=>\!!donebtrue\!!donedtrue, + tl=>\!!doneatrue\!!donectrue, + lt=>\!!doneatrue\!!donectrue, + tr=>\!!donebtrue\!!donectrue, + rt=>\!!donebtrue\!!donectrue]% + \doifelse\@@bgstretch\v!yes\donetrue\donefalse + \scratchdimen\@@bgwidth + \ifdone + \if!!donea + \advance\scratchdimen\MPx{\??bg:\number\nofbleeds}% + \else\if!!doneb + \scratchdimen\paperwidth + \advance\scratchdimen-\MPx{\??bg:\number\nofbleeds}% + \fi\fi + \fi + \advance\scratchdimen\@@bghoffset + \xdef\bleedwidth{\the\scratchdimen}% + \scratchdimen\@@bgheight + \ifdone + \if!!donec + \scratchdimen\paperheight + \advance\scratchdimen-\MPy{\??bg:\number\nofbleeds}% + \else\if!!doned + \advance\scratchdimen\MPy{\??bg:\number\nofbleeds}% + \fi\fi + \fi + \advance\scratchdimen\@@bgvoffset + \xdef\bleedheight{\the\scratchdimen}% + \hsize\bleedwidth + \vsize\bleedheight + \setbox\scratchbox\hbox{#2}% + \doif\@@bgpage\v!yes + {\setbox\scratchbox\topskippedbox{\box\scratchbox}}% + \setbox\scratchbox\hbox to \@@bgwidth + {\if!!donea\hss\fi\box\scratchbox\if!!doneb\hss\fi}% + \if!!doned + \setbox\scratchbox\hbox + {\lower\bleedheight\hbox{\raise\@@bgheight\box\scratchbox}}% + \fi + \wd\scratchbox\@@bgwidth + \ht\scratchbox\@@bgheight + \dp\scratchbox\zeropoint + \ifdone + \hpos{\??bg:\number\nofbleeds}{\box\scratchbox}% + \else + \box\scratchbox + \fi + \egroup} + +\setupbleeding[\c!stretch=\v!yes] + +\defineexternalfigure[bleed][\c!width=\bleedwidth,\c!height=\bleedheight] + +% \placefigure[left]{none} +% {\bleed[width=5cm,height=3cm,location=lt]{\externalfigure[koe][bleed]}} +% +% \input tufte +% +% \placefigure[left]{none} +% {\bleed[width=5cm,height=3cm,location=l]{\externalfigure[koe][bleed]}} +% +% \input tufte +% +% \placefigure[right]{none} +% {\bleed[width=5cm,height=3cm,location=r]{\externalfigure[koe][bleed]}} +% +% \input tufte +% +% \placesomefloat[right]{none} +% {\bleed[width=5cm,height=3cm,location=rb]{\externalfigure[koe][bleed]}} +% +% \input tufte +% +% \placefigure +% [top,none] +% {} % no caption +% {\bleed +% [hoffset=-\backspace, +% voffset=3mm, +% width=0cm, +% height=6\lineheight, +% page=yes, % correct for topskip +% location=lt] +% {\externalfigure[koe][bleed][frame=on]}} + +% \setlayerframed[layer id][layer settings][framed setting]{data} +% \setlayerframed[layer id][combined settings]{data} + +\def\setlayerframed + {\dotripleempty\dosetlayerframed} + +\def\dosetlayerframed + {\ifthirdargument + \expandafter\dosetlayerframedT + \else + \expandafter\dosetlayerframedS + \fi} + +\def\dosetlayerframedT[#1][#2][#3]% + {\dowithnextbox{\setlayer[#1][#2]{\flushnextbox}}% + \hbox\framed[#3]} + +\def\dosetlayerframedS[#1][#2][#3]% + {\dowithnextbox + {\setlayer + [#1] + [\c!width=\nextboxwd,\c!height=\nextboxht, + \c!offset=\!!zeropoint,#2] + {\flushnextbox}}% + \hbox\framed[\c!location=\v!normal,#2]} + +\def\setlayertext + {\dotripleempty\dosetlayertext} + +\def\dosetlayertext[#1][#2][#3]% + {\bgroup + \getparameters + [\??lx] + [\c!align=, + \c!width=\hsize, + \c!color=, + \c!style=, + #3]% + \dowithnextboxcontent + {\forgetall + \hsize\@@lxwidth + \expanded{\setupalign[\@@lxalign]}% + \dosetfontattribute\??lx\c!style} + {\setlayer[#1][#2]{\strut\color[\@@lxcolor]{\flushnextbox}}% + \egroup}% + \vtop} + +% \setupbackgrounds +% [page] +% [background=pagefigures] +% +% \definelayer +% [pagefigures] +% [x=-2mm, +% y=-2mm, +% width=\paperwidth, +% height=\paperheight] +% +% \definelayerpreset [lefttop] [corner={left,top},location={right,bottom}] +% \definelayerpreset [righttop] [corner={right,top},location={left,bottom}] +% \definelayerpreset [leftbottom] [corner={left,bottom},location={right,top}] +% \definelayerpreset [rightbottom] [corner={right,bottom},location={left,top}] +% \definelayerpreset [middle] [corner=middle,location=middle] +% +% \setlayer[pagefigures][preset=lefttop] +% \setlayer[pagefigures][preset=righttop] +% \setlayer[pagefigures][preset=leftbottom] +% \setlayer[pagefigures][preset=rightbottom] + +\definelayerpreset + [\v!left\v!top] + [\c!corner={\v!left,\v!top},\c!location={\v!right,\v!bottom}] + +\definelayerpreset + [\v!right\v!top] + [\c!corner={\v!right,\v!top},\c!location={\v!left,\v!bottom}] + +\definelayerpreset + [\v!left\v!bottom] + [\c!corner={\v!left,\v!bottom},\c!location={\v!right,\v!top}] + +\definelayerpreset + [\v!right\v!bottom] + [\c!corner={\v!right,\v!bottom},\c!location={\v!left,\v!top}] + +\definelayerpreset + [\v!middle] + [\c!corner=\v!middle,\c!location=\v!middle] + +% \definelayerpreset +% [\v!middle\v!top] +% [\c!location=\v!bottom,\c!hoffset=.5\layerwidth] + +% \definelayerpreset +% [\v!middle\v!bottom] +% [\c!location=\v!top,\c!hoffset=.5\layerwidth,\c!voffset=\layerheight] + +% \definelayerpreset +% [\v!middle\v!left] +% [\c!location=\v!right,\c!voffset=.5\layerheight] + +% \definelayerpreset +% [\v!middle\v!right] +% [\c!location=\v!left,\c!hoffset=\layerwidth,\c!voffset=.5\layerheight] + +\definelayerpreset + [\v!middle\v!top] + [\c!location=\v!bottom,\c!corner=\v!top,\c!dx=.5\layerwidth] + +\definelayerpreset + [\v!middle\v!bottom] + [\c!location=\v!top,\c!corner=\v!bottom,\c!dx=.5\layerwidth] + +\definelayerpreset + [\v!middle\v!left] + [\c!location=\v!right,\c!corner=\v!left,\c!dy=.5\layerheight] + +\definelayerpreset + [\v!middle\v!right] + [\c!location=\v!left,\c!corner=\v!right,\c!dy=.5\layerheight] + +\def\alignedbox + {\dodoubleempty\doalignedbox[]} + +% \def\doalignedbox[#1][#2]% +% {\bgroup +% %\let\iftraceboxplacement\iftracelayers % ugly +% \dowithnextbox +% {\let\next\middlebox +% \processaction +% [#2] +% [ t=>\let\next\topbox , b=>\let\next\bottombox , +% l=>\let\next\leftbox , r=>\let\next\rightbox , +% bl=>\let\next\bottomleftbox,br=>\let\next\bottomrightbox, +% tl=>\let\next\topleftbox ,tr=>\let\next\toprightbox , +% lt=>\let\next\lefttopbox ,lb=>\let\next\leftbottombox , +% rt=>\let\next\righttopbox ,rb=>\let\next\rightbottombox]% +% \next{\flushnextbox}% +% \egroup}#1} + +\def\doalignedbox[#1][#2]% + {\bgroup + %\let\iftraceboxplacement\iftracelayers % ugly + \dowithnextbox + {\serializecommalist[#2]% + \executeifdefined{\??ab\??ab\serializedcommalist}\middlebox{\flushnextbox}% + \egroup}#1} + +\setvalue{\??ab\??ab }{\middlebox} +\setvalue{\??ab\??ab\v!middle }{\middlebox} +\setvalue{\??ab\??ab\v!left }{\leftbox } +\setvalue{\??ab\??ab\v!right }{\rightbox } +\setvalue{\??ab\??ab\v!bottom }{\bottombox} +\setvalue{\??ab\??ab\v!top }{\topbox } + +\setvalue{\??ab\??ab\v!middle\v!middle}{\middlebox} +\setvalue{\??ab\??ab\v!left \v!top }{\lefttopbox} +\setvalue{\??ab\??ab\v!left \v!bottom}{\leftbottombox} +\setvalue{\??ab\??ab\v!right \v!top }{\righttopbox} +\setvalue{\??ab\??ab\v!right \v!bottom}{\rightbottombox} +\setvalue{\??ab\??ab\v!top \v!left }{\topleftbox} +\setvalue{\??ab\??ab\v!bottom\v!left }{\bottomleftbox} +\setvalue{\??ab\??ab\v!top \v!right }{\toprightbox} +\setvalue{\??ab\??ab\v!bottom\v!right }{\bottomrightbox} + +\setvalue{\??ab\??ab c}{\middlebox} +\setvalue{\??ab\??ab l}{\leftbox} +\setvalue{\??ab\??ab r}{\rightbox} +\setvalue{\??ab\??ab b}{\bottombox} +\setvalue{\??ab\??ab t}{\topbox} + +\setvalue{\??ab\??ab lt}{\lefttopbox} +\setvalue{\??ab\??ab lb}{\leftbottombox} +\setvalue{\??ab\??ab rt}{\righttopbox} +\setvalue{\??ab\??ab rb}{\rightbottombox} +\setvalue{\??ab\??ab tl}{\topleftbox} +\setvalue{\??ab\??ab bl}{\bottomleftbox} +\setvalue{\??ab\??ab tr}{\toprightbox} +\setvalue{\??ab\??ab br}{\bottomrightbox} + +\setvalue{\??ab\??ab m}{\middlebox} + +% The next ones were desparately needed by Vit Zyka (see +% \type {supp-box} for definitions). + +\setvalue{\??ab\??ab g}{\baselinemiddlebox} +\setvalue{\??ab\??ab gl}{\baselineleftbox} +\setvalue{\??ab\??ab gc}{\baselinemiddlebox} +\setvalue{\??ab\??ab gr}{\baselinerightbox} + +\setvalue{\??ab\??ab \v!line }{\baselinemiddlebox} % \v!grid is taken +\setvalue{\??ab\??ab \v!line\v!left }{\baselineleftbox} +\setvalue{\??ab\??ab \v!line\v!middle}{\baselinemiddlebox} +\setvalue{\??ab\??ab \v!line\v!right }{\baselinerightbox} + +\unexpanded\def\offsetbox + {\dodoubleempty\dooffsetbox[]} + +% left/right/top/bottomoffset -> dimensions change +% x/y | method=fixed -> dimensions don't change + +\def\dooffsetbox[#1][#2]% + {\bgroup + \dowithnextbox + {\getparameters[\??ox] + [\c!x=\zeropoint, + \c!y=\zeropoint, + \c!width=\nextboxwd, + \c!height=\nextboxht, + \c!depth=\nextboxdp, + \c!location=, + \c!leftoffset=\zeropoint, + \c!rightoffset=\zeropoint, + \c!topoffset=\zeropoint, + \c!bottomoffset=\zeropoint, + \c!method=, + #2]% + \donefalse + \ifdim\@@oxleftoffset =\zeropoint\else\donetrue\fi + \ifdim\@@oxrightoffset=\zeropoint\else\donetrue\fi + \ifdim\@@oxtopoffset =\zeropoint\else\donetrue\fi + \ifdim\@@oxbottomoffset =\zeropoint\else\donetrue\fi + \ifdone + \doif\@@oxmethod\v!fixed % new + {\ifdim\@@oxleftoffset=\zeropoint + \ifdim\@@oxrightoffset=\zeropoint \else + \scratchdimen-\@@oxrightoffset + \edef\@@oxx{\the\scratchdimen}% + \let\@@oxrightoffset\zeropoint + \fi + \else + \let\@@oxx\@@oxleftoffset + \let\@@oxleftoffset\zeropoint + \fi + \ifdim\@@oxtopoffset=\zeropoint + \ifdim\@@oxbottomoffset=\zeropoint \else + \scratchdimen-\@@oxbottomoffset + \edef\@@oxy{\the\scratchdimen}% + \let\@@oxbottomoffset\zeropoint + \fi + \else + \let\@@oxy\@@oxtopoffset + \let\@@oxtopoffset\zeropoint + \fi + \donefalse}% + \fi + \ifdone + \setbox\nextbox\vbox + {\forgetall\offinterlineskip + \vskip\@@oxtopoffset + \hbox + {\hskip\@@oxleftoffset + \flushnextbox + \hskip\@@oxrightoffset}% + \vskip\@@oxbottomoffset}% + \scratchdimen\nextboxht + \advance\scratchdimen\nextboxdp + \nextboxht\scratchdimen + \nextboxdp\zeropoint + \fi + \freezedimenmacro\@@oxwidth + \freezedimenmacro\@@oxheight + \freezedimenmacro\@@oxdepth + \setbox\nextbox\hbox + {\hskip\@@oxx\lower\@@oxy\hbox + {\doifelsenothing\@@oxlocation + {\flushnextbox} + {\alignedbox[\@@oxlocation]\hbox{\flushnextbox}}}}% + \nextboxwd\@@oxwidth + \nextboxht\@@oxheight + \nextboxdp\@@oxdepth + \flushnextbox + \egroup}#1} + +% \useMPlibrary[pre] \setupbackgrounds[page][background=pagegrid] +% +% \placefigure[left,none]{}{\offset[leftoffset=1cm]{\externalfigure[koe][breedte=3cm]}} +% \input tufte +% \placefigure[left,none]{}{\offset[rightoffset=1cm]{\externalfigure[koe][breedte=3cm]}} +% \input tufte +% \placefigure[left,none]{}{\offset[topoffset=1cm]{\externalfigure[koe][breedte=3cm]}} +% \input tufte +% \placefigure[left,none]{}{\offset[bottomoffset=1cm]{\externalfigure[koe][breedte=3cm]}} +% \input tufte + +\unexpanded\def\offset {\dodoubleempty\dooffsetbox [\hbox]} % yes or no +\unexpanded\def\aligned{\dosingleempty\doalignedbox[\hbox]} % yes or no + +%\ruledhbox{\offsetbox[x=-1cm,y=-1cm,location=c] +% {\framed[width=4cm,height=4cm]{x}}} + +\def\dotabbed#1#2#3#4% + {\dontleavehmode + \bgroup + \setbox\scratchbox\hbox{#3}% + \hbox to \wd\scratchbox{#1#4#2}% + \egroup} + +\unexpanded\def\ltabbed{\dotabbed\relax\hss} +\unexpanded\def\rtabbed{\dotabbed\hss \relax} +\unexpanded\def\ctabbed{\dotabbed\hss \hss} \let\mtabbed\ctabbed + +% \ltabbed{\romeins{3}}{\romeins{1}} test \endgraf +% \ltabbed{\romeins{3}}{\romeins{2}} test \endgraf +% \ltabbed{\romeins{3}}{\romeins{3}} test \endgraf +% +% \rtabbed{\romeins{3}}{\romeins{1}} test \endgraf +% \rtabbed{\romeins{3}}{\romeins{2}} test \endgraf +% \rtabbed{\romeins{3}}{\romeins{3}} test \endgraf +% +% \ctabbed{\romeins{3}}{\romeins{1}} test \endgraf +% \ctabbed{\romeins{3}}{\romeins{2}} test \endgraf +% \ctabbed{\romeins{3}}{\romeins{3}} test \endgraf + +% alternative, if done, then other name +% +% \def\dotabbed#1#2#3#4% +% {\dontleavehmode +% \bgroup +% \scratchdimen\zeropoint +% \def\docommand##1% +% {\setbox\scratchbox\hbox{##1}% +% \ifdim\wd\scratchbox>\scratchdimen +% \scratchdimen\wd\scratchbox +% \fi}% +% \processcommalist[#3]\docommand +% \hbox to \scratchdimen{#1#4#2}% +% \egroup} +% +% \def\ltabbed{\dotabbed\relax\hss} +% \def\rtabbed{\dotabbed\hss \relax} +% \def\ctabbed{\dotabbed\hss \hss} \let\mtabbed\ctabbed +% +% \ltabbed{\romeins{10},\romeins{2000},\romeins{15}}{\romeins{10}} test \endgraf +% \ltabbed{\romeins{10},\romeins{2000},\romeins{15}}{\romeins{15}} test \endgraf +% \ltabbed{\romeins{10},\romeins{2000},\romeins{15}}{\romeins{2000}} test \endgraf +% +% \rtabbed{\romeins{10},\romeins{2000},\romeins{15}}{\romeins{10}} test \endgraf +% \rtabbed{\romeins{10},\romeins{2000},\romeins{15}}{\romeins{15}} test \endgraf +% \rtabbed{\romeins{10},\romeins{2000},\romeins{15}}{\romeins{2000}} test \endgraf +% +% \ctabbed{\romeins{10},\romeins{2000},\romeins{15}}{\romeins{10}} test \endgraf +% \ctabbed{\romeins{10},\romeins{2000},\romeins{15}}{\romeins{15}} test \endgraf +% \ctabbed{\romeins{10},\romeins{2000},\romeins{15}}{\romeins{2000}} test \endgraf + +% to be documented + +\unexpanded\def\phantombox[#1]% + {\hbox\bgroup + \getparameters + [\??ol] + [\c!width=\zeropoint,% + \c!height=\zeropoint,% + \c!depth=\zeropoint,#1]% + \setbox\scratchbox\null + \wd\scratchbox\@@olwidth + \ht\scratchbox\@@olheight + \dp\scratchbox\@@oldepth + \box\scratchbox + \egroup} + +% \backgroundimage{1}{\hsize}{\vsize}{\externalfigure[cow][\c!width=3cm]} + +\unexpanded\def\backgroundimage#1#2#3% repeat hsize vsize + {\bgroup + \forgetall + \dowithnextbox + {\offinterlineskip + \ifcase#1\relax + % just one + \else + \scratchdimen#2\divide\scratchdimen\nextboxwd\count0\scratchdimen\advance\count0\plusone + \scratchdimen#3\divide\scratchdimen\nextboxht\count2\scratchdimen\advance\count2\plusone + % to be considered, probably methods + \ifcase#1\or % x and y + \setbox\nextbox\hbox{\dorecurse{\count0}{\copy\nextbox}}% + \setbox\nextbox\vbox{\dorecurse{\count2}{\copy\nextbox\endgraf}}% + \or % x + \setbox\nextbox\hbox{\dorecurse{\count0}{\copy\nextbox}}% + \or % y + \setbox\nextbox\vbox{\dorecurse{\count2}{\copy\nextbox\endgraf}}% + \fi + \fi + \ifdim\nextboxwd>#2\relax + \setbox\nextbox\hbox to #2{\hss\flushnextbox\hss}% + \setbox\nextbox\hbox{\expanded{\clip[\c!width=#2,\c!height=\the\nextboxht]{\flushnextbox}}}% + \fi + \ifdim\nextboxht>#3\relax + \setbox\nextbox\vbox to #3{\vss\flushnextbox\vss}% + \setbox\nextbox\hbox{\expanded{\clip[\c!width=\the\nextboxwd,\c!height=#3]{\flushnextbox}}}% + \fi + \flushnextbox + \egroup}% + \hbox} + +\protect \endinput diff --git a/tex/context/base/pack-box.mkiv b/tex/context/base/pack-box.mkiv new file mode 100644 index 000000000..6cb492aa6 --- /dev/null +++ b/tex/context/base/pack-box.mkiv @@ -0,0 +1,944 @@ +%D \module +%D [ file=pack-box, +%D version=2002.04.12, +%D title=\CONTEXT\ Packaging Macros, +%D subtitle=Boxes, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 Packaging Macros / Boxes} + +%D This module contains all kind of macros for moving content +%D around. Many macros here come from other modules, but +%D depencies made it more clear to isolate them. + +% \placeornament + +\unprotect + +% \definelayer[\v!tekst-2][\c!positie=\v!ja] +% \definelayer[\v!tekst-1][\c!positie=\v!ja] +% \definelayer[\v!tekst+1][\c!positie=\v!ja] +% \definelayer[\v!tekst+2][\c!positie=\v!ja] + +% we need to set the size, else we get dimensions depending +% on the content, which in itsel fis ok, but can lead to loops +% due to rounding errors (happened in demo-obv) + +\definelayer[\v!text-2][\c!position=\v!yes,\c!width=\overlaywidth,\c!height=\overlayheight] +\definelayer[\v!text-1][\c!position=\v!yes,\c!width=\overlaywidth,\c!height=\overlayheight] +\definelayer[\v!text+1][\c!position=\v!yes,\c!width=\overlaywidth,\c!height=\overlayheight] +\definelayer[\v!text+2][\c!position=\v!yes,\c!width=\overlaywidth,\c!height=\overlayheight] + +\def\internaltextoverlay#1% will become more generic and installable + {\startoverlay % i.e. probably an overlay by itself + {\positionoverlay{\v!text#1}} % see later + {\composedlayer {\v!text#1}} + \stopoverlay} + +%\def\internaltextoverlay#1% +% {\hbox to \zeropoint{\positionoverlay{\v!tekst#1}\hss}% +% \composedlayer{\v!tekst#1}} + +% todo: share info, so that tuo will be smaller + +\defineoverlay[\v!text-2][\internaltextoverlay{-2}] +\defineoverlay[\v!text-1][\internaltextoverlay{-1}] +\defineoverlay[\v!text+1][\internaltextoverlay{+1}] +\defineoverlay[\v!text+2][\internaltextoverlay{+2}] + +% to be documented + +\definelayer[anchor] + +\def\anchor + {\dosingleargument\doanchor} + +\def\doanchor[#1]% + {\ifcsname\??an#1\endcsname\@EA\nonoanchor\else\@EA\dodoanchor\fi[#1]} + +\def\nonoanchor[#1]% + {} + +\def\dodoanchor[#1]% + {\dotripleempty\dododoanchor[#1]} + +\def\dododoanchor + {\ifthirdargument + \expandafter\dodoanchorT + \else + \expandafter\dodoanchorS + \fi} + +\def\dodoanchorS[#1][#2][#3]% + {\dodoanchorT[#1][#2][#2]} + +\def\dodoanchorT[#1][#2][#3]% + {\dowithnextbox + {\bgroup + \checktextbackgrounds + \setbox\scratchbox\null + \wd\scratchbox\nextboxwd + \ht\scratchbox\nextboxht + \dp\scratchbox\nextboxdp + \setlayer + [anchor] + [\c!width=\wd\scratchbox, + \c!height=\ht\scratchbox, + \c!offset=\!!zeropoint, + #2,#3] + {\setlayer[#1]{\flushnextbox}}% + \framed + [#2, + \c!background=anchor, + \c!offset=\v!overlay, + \c!frame=\v!off, + #3] + {\box\scratchbox}% + \egroup}% + \vbox} + +\unexpanded\def\defineanchor + {\doquadrupleempty\dodefineanchor} + +\def\dodefineanchor[#1][#2][#3][#4]% + {\setvalue{\??an#1}{\dodefinedanchor[#2][#3][#4]}} + +\def\dodefinedanchor[#1][#2][#3]% + {\def\docommand[##1][##2]% + {\ifsecondargument + \def\next{\dodoanchorT[#1][#2,##1][#3,##2]}% + \else\iffirstargument + \def\next{\dodoanchorT[#1][#2,##1][#2,##1]}% + \else + \def\next{\dodoanchorT[#1][#2][#3]}% + \fi\fi + \next}% + \dodoubleempty\docommand} + +\def\@@collectorbox{@@collectorbox} + +\unexpanded\def\definecollector + {\dodoubleargument\dodefinecollector} + +\def\dodefinecollector[#1][#2]% + {\ifcsname\@@collectorbox#1\endcsname \else + \expandafter\newbox\csname\@@collectorbox#1\endcsname + \fi + \resetcollector[#1]% + \setupcollector + [#1] + [\c!state=\v!start, + \c!x=\!!zeropoint,\c!y=\!!zeropoint, + \c!offset=\!!zeropoint,\c!rotation=, % geen 0 ! + \c!hoffset=\!!zeropoint,\c!voffset=\!!zeropoint, + \c!location=rb,\c!corner=,#2]} + +\unexpanded\def\setupcollector + {\dodoubleargument\dosetupcollector} + +\def\dosetupcollector[#1][#2]% + {\def\docommand##1{\getparameters[\??cb##1][#2]}% + \processcommalist[#1]\docommand} + +\def\setcollector + {\dodoubleargument\dosetcollector} + +\def\dosetcollector[#1][#2]% + {\bgroup + \forgetall + \dontcomplain + \dowithnextbox + {\ifcsname\@@collectorbox#1\endcsname + \dodosetcollector[#1][#2]% + \else + \writestatus{collector}{unknown layer #1}% + \fi + \egroup} + \hbox} + +\def\collectorparameter#1{\csname\??cb\currentcollector#1\endcsname} + +\def\dodosetcollector[#1][#2]% todo: keep reference point + {\def\currentcollector{#1}% + \chardef\collectorbox\csname\@@collectorbox#1\endcsname + \getparameters[\??cb#1][#2]% + \@@layerxsiz\wd\collectorbox + \@@layerysiz\ht\collectorbox + \doifvaluesomething{\??cb#1\c!rotation} + {\setbox\nextbox\hbox + {\rotate + [\c!location=\v!high, + \c!rotation=\collectorparameter\c!rotation] + {\flushnextbox}}}% + \advance\@@layerysiz\dp\collectorbox + \@@layerxpos\collectorparameter\c!x + \advance\@@layerxpos\collectorparameter\c!hoffset + \@@layerypos\collectorparameter\c!y + \advance\@@layerypos\collectorparameter\c!voffset + \doifelse\v!middle{\collectorparameter\c!corner} + {\ifdim\@@layerxsiz>\zeropoint + \advance\@@layerxpos.5\@@layerxsiz + \fi + \ifdim\@@layerysiz>\zeropoint + \advance\@@layerypos.5\@@layerysiz + \fi}% + {\normalexpanded{\noexpand\doifinset{\v!bottom}{\collectorparameter\c!corner}} + {\ifdim\@@layerysiz>\zeropoint + \advance\@@layerypos-\@@layerysiz + \@@layerypos-\@@layerypos + \fi}% + \normalexpanded{\noexpand\doifinset{\v!right}{\collectorparameter\c!corner}} + {\ifdim\@@layerxsiz>\zeropoint + \advance\@@layerxpos-\@@layerxsiz + \@@layerxpos-\@@layerxpos + \fi}}% + \setbox\nextbox\hbox + {\alignedbox[\collectorparameter\c!location]\vbox{\flushnextbox}}% + \boxmaxdepth\zeropoint % really needed, nice example + \global\advance\boxhdisplacement\@@layerxpos + \ifdim\boxhdisplacement<\zeropoint + \global\setbox\collectorbox\hbox + {\hskip-\boxhdisplacement + \box\collectorbox}% + \fi + \global\advance\boxvdisplacement\@@layerypos + \ifdim\boxvdisplacement<\zeropoint + \global\setbox\collectorbox\hbox + {\lower-\boxvdisplacement + \box\collectorbox}% + \fi + \@@layerxsiz\wd\collectorbox + \@@layerysiz\ht\collectorbox + \advance\@@layerysiz\dp\collectorbox + \global\setbox\collectorbox\hbox + {\box\collectorbox + \hskip-\@@layerxsiz + \hskip\@@layerxpos\relax + \ifdim\boxhdisplacement<\zeropoint + \hskip-\boxhdisplacement + \fi + \lower\@@layerypos\hbox + {\ifdim\boxvdisplacement<\zeropoint + \lower-\boxvdisplacement\flushnextbox + \else + \flushnextbox + \fi}}% + % combine height and depth into depth only (later flushed as height) + \global\setbox\collectorbox\hbox + {\lower\ht\collectorbox\box\collectorbox}% + % just to be sure + \ifdim\wd\collectorbox<\@@layerxsiz + \global\wd\collectorbox\@@layerxsiz + \fi} + +\def\flushcollector[#1]% + {\ifcsname\@@collectorbox#1\endcsname + \doifnotvalue{\??cb#1\c!state}\v!stop + {\vbox + {\hbox + {\doifelsevalue{\??cb#1\c!state}\v!repeat + {\let\next\copy}{\let\next\box}% + \raise\dp\csname\@@collectorbox#1\endcsname + \next\csname\@@collectorbox#1\endcsname}}}% + \else + \writestatus{collector}{unknown collector #1}% + \fi} + +\def\composedcollector#1{\flushcollector[#1]} + +\def\resetcollector[#1]% + {\ifcsname\@@collectorbox#1\endcsname + \global\setbox\csname\@@collectorbox#1\endcsname\emptybox + \fi} + +\def\adaptcollector + {\dodoubleargument\doadaptcollector} + +\def\doadaptcollector[#1][#2]% + {\bgroup + \def\currentcollector{#1}% + \chardef\collectorbox\csname\@@collectorbox#1\endcsname + \getparameters[\??cb#1][\c!voffset=\zeropoint,\c!hoffset=\zeropoint,#2]% + \scratchdimen\wd\collectorbox + \advance\scratchdimen\collectorparameter\c!hoffset + \global\wd\collectorbox\scratchdimen + \scratchdimen\ht\collectorbox + \advance\scratchdimen\collectorparameter\c!voffset + \global\ht\collectorbox\scratchdimen + \egroup} + +%\definecollector[test] +%\setcollector[test] +% [location=rb] +% {\externalfigure[koe][frame=on,width=3cm]} +%\setcollector[test] +% [corner={right,bottom},location={left,top}] +% {\framed{gans}} +%\composedcollector{test} + +\definecollector + [caption] + +\def\collectedtext + {\dodoubleempty\docollectedtext} + +\def\docollectedtext[#1][#2]#3% + {\bgroup + \dowithnextbox + {\setcollector + [caption] + {\flushnextbox}% + \setcollector + [caption][#1] + {\getparameters[\??du][#2]% + \dosetfontattribute\??du\c!style\setupinterlinespace + \framed % watch the special setting of kader/overlay + [\c!frame=\v!overlay,#2] + {\doattributes\??du\c!style\c!color{#3}}}% + \composedcollector{caption}% + \egroup}% + \hbox} + +% \collectedtext +% [corner={right,bottom},location={left,top}] +% [background=color,backgroundcolor=white,offset=0pt] +% {gans} +% {\externalfigure[koe][width=3cm]} +% +% \collectedtext +% [rotation=90,corner={right,bottom},location={right,top}] +% [frame=on,offset=0pt] +% {gans} +% {\externalfigure[koe][width=3cm]} +% +% \collectedtext +% [rotation=90,corner={left,bottom},location={left,top}] +% [frame=on,offset=0pt] +% {gans} +% {\externalfigure[koe][width=3cm]} + +\definelayer + [caption] + +\def\layeredtext + {\dodoubleempty\dolayeredtext} + +\def\dolayeredtext[#1][#2]#3% + {\bgroup + \dowithnextbox + {\!!widtha \nextboxwd + \!!heighta\nextboxht + \bgroup % preserve \nextbox + \setuplayer + [caption] + [\c!width=\!!widtha,\c!height=\!!heighta]% + \setlayer + [caption] + [#1] + {\getparameters[\??du][#2]% + \dosetfontattribute\??du\c!style\setupinterlinespace + \framed + [\c!frame=\v!overlay,,#2] + {\doattributes\??du\c!style\c!color{#3}}}% + \egroup + \framed + [\c!offset=\v!overlay, + \c!frame=\v!off, + \c!background={\v!foreground,caption}, + \c!width=\!!widtha, + \c!height=\!!heighta] + {\flushnextbox}% + \egroup}% + \hbox} + +% \layeredtext +% [corner={right,bottom},location={left,top}] +% [background=color,backgroundcolor=white,offset=0pt] +% {gans} +% {\externalfigure[koe][width=3cm]} +% +% \layeredtext +% [rotation=90,corner={right,bottom},location={right,top}] +% [frame=on,offset=0pt] +% {gans} +% {\externalfigure[koe][width=3cm]} +% +% \layeredtext +% [rotation=90,corner={left,bottom},location={left,top}] +% [frame=on,offset=0pt] +% {gans} +% {\externalfigure[koe][width=3cm]} + +\def\ornamenttext + {\dodoubleempty\doornamenttext} + +\def\doornamenttext[#1][#2]% + {\bgroup + \doifassignmentelse{#1} + {\getparameters[\s!dummy][\c!alternative=\v!a,#1]% + \doifelse\dummyalternative\v!a + {\egroup\collectedtext}% + {\egroup\layeredtext }% + [#1][#2]}% + {\egroup\getvalue{#1}}} + +\unexpanded\def\defineornament + {\dotripleempty\dodefineornament} + +\def\dodefineornament[#1][#2][#3]% + {\setvalue{#1}{\doornamenttext[#2][#3]}} + +% \defineornament +% [affiliation] +% [rotation=90,corner={right,bottom},location={right,top}, +% hoffset=-.25ex] +% [frame=on,background=color,backgroundcolor=red,offset=0pt] +% +% \ruledhbox{\affiliation{gans}{\externalfigure[koe][width=3cm]}} +% +% \defineornament +% [affiliation] +% [rotation=90,corner={right,bottom},location={right,top}, +% hoffset=-.25ex,alternative=b] +% [frame=on,background=color,backgroundcolor=red,offset=0pt] +% +% \ruledhbox{\affiliation{gans}{\externalfigure[koe][width=3cm]}} +% +% \defineornament +% [affiliation] +% [rotation=90,corner={right,bottom},location={left,top}, +% hoffset=.25ex,voffset=.25ex,alternative=a] +% [background=color,style=\ss\tfxx,backgroundcolor=white,offset=0pt] +% +% \affiliation{photo}{\externalfigure[molen][width=3cm]} +% +% \defineornament +% [affiliation] +% [rotation=90,corner={right,bottom},location={left,top}, +% hoffset=.25ex,voffset=.25ex,alternative=b] +% [background=color,style=\ss\tfxx,backgroundcolor=white,offset=0pt] +% +% \affiliation{drawing}{\externalfigure[hakker][width=3cm]} + +% pas op: aanpassen aan nieuwe layer hoek ankers en columnset + +\newcount\nofbleeds % per pag + +\unexpanded\def\setupbleeding + {\dodoubleempty\getparameters[\??bg]} + +\setupbleeding + [\c!location=l, + \c!stretch=\v!yes, + \c!width=3cm, + \c!height=3cm, + \c!offset=2mm, + \c!page=\v!no, + \c!voffset=\@@bgoffset, + \c!hoffset=\@@bgoffset] + +\def\bleed + {\dosingleempty\dobleed} + + +\def\bleedwidth {\the\hsize}% +\def\bleedheight{\the\vsize}% + +\def\dobleed[#1]#2% + {\hbox\bgroup + \xdef\bleedwidth {\the\hsize}% + \xdef\bleedheight{\the\vsize}% + \global\advance\nofbleeds\plusone + \getparameters[\??bg][#1]% + \!!doneafalse % left + \!!donebfalse % right + \!!donecfalse % top + \!!donedfalse % bottom + % replace this part ! todo: default location + \processaction + [\@@bglocation] + [ t=>\!!donectrue\let\@@bghoffset\!!zeropoint, + b=>\!!donedtrue\let\@@bghoffset\!!zeropoint, + l=>\!!doneatrue\let\@@bgvoffset\!!zeropoint, + r=>\!!donebtrue\let\@@bgvoffset\!!zeropoint, + bl=>\!!doneatrue\!!donedtrue, + lb=>\!!doneatrue\!!donedtrue, + br=>\!!donebtrue\!!donedtrue, + rb=>\!!donebtrue\!!donedtrue, + tl=>\!!doneatrue\!!donectrue, + lt=>\!!doneatrue\!!donectrue, + tr=>\!!donebtrue\!!donectrue, + rt=>\!!donebtrue\!!donectrue]% + \doifelse\@@bgstretch\v!yes\donetrue\donefalse + \scratchdimen\@@bgwidth + \ifdone + \if!!donea + \advance\scratchdimen\MPx{\??bg:\number\nofbleeds}% + \else\if!!doneb + \scratchdimen\paperwidth + \advance\scratchdimen-\MPx{\??bg:\number\nofbleeds}% + \fi\fi + \fi + \advance\scratchdimen\@@bghoffset + \xdef\bleedwidth{\the\scratchdimen}% + \scratchdimen\@@bgheight + \ifdone + \if!!donec + \scratchdimen\paperheight + \advance\scratchdimen-\MPy{\??bg:\number\nofbleeds}% + \else\if!!doned + \advance\scratchdimen\MPy{\??bg:\number\nofbleeds}% + \fi\fi + \fi + \advance\scratchdimen\@@bgvoffset + \xdef\bleedheight{\the\scratchdimen}% + \hsize\bleedwidth + \vsize\bleedheight + \setbox\scratchbox\hbox{#2}% + \doif\@@bgpage\v!yes + {\setbox\scratchbox\topskippedbox{\box\scratchbox}}% + \setbox\scratchbox\hbox to \@@bgwidth + {\if!!donea\hss\fi\box\scratchbox\if!!doneb\hss\fi}% + \if!!doned + \setbox\scratchbox\hbox + {\lower\bleedheight\hbox{\raise\@@bgheight\box\scratchbox}}% + \fi + \wd\scratchbox\@@bgwidth + \ht\scratchbox\@@bgheight + \dp\scratchbox\zeropoint + \ifdone + \hpos{\??bg:\number\nofbleeds}{\box\scratchbox}% + \else + \box\scratchbox + \fi + \egroup} + +\setupbleeding[\c!stretch=\v!yes] + +\defineexternalfigure[bleed][\c!width=\bleedwidth,\c!height=\bleedheight] + +% \placefigure[left]{none} +% {\bleed[width=5cm,height=3cm,location=lt]{\externalfigure[koe][bleed]}} +% +% \input tufte +% +% \placefigure[left]{none} +% {\bleed[width=5cm,height=3cm,location=l]{\externalfigure[koe][bleed]}} +% +% \input tufte +% +% \placefigure[right]{none} +% {\bleed[width=5cm,height=3cm,location=r]{\externalfigure[koe][bleed]}} +% +% \input tufte +% +% \placefigure +% [top,none] +% {} % no caption +% {\bleed +% [hoffset=-\backspace, +% voffset=3mm, +% width=0cm, +% height=6\lineheight, +% page=yes, % correct for topskip +% location=lt] +% {\externalfigure[koe][bleed][frame=on]}} + +% \setlayerframed[layer id][layer settings][framed setting]{data} +% \setlayerframed[layer id][combined settings]{data} + +\def\setlayerframed + {\dotripleempty\dosetlayerframed} + +\def\dosetlayerframed + {\ifthirdargument + \expandafter\dosetlayerframedT + \else + \expandafter\dosetlayerframedS + \fi} + +\def\dosetlayerframedT[#1][#2][#3]% + {\dowithnextbox{\setlayer[#1][#2]{\flushnextbox}}% + \hbox\framed[#3]} + +\def\dosetlayerframedS[#1][#2][#3]% + {\dowithnextbox % we could use a local setlayer command (no doif..empty) which also saves a nextbox + {\setlayer[#1][\c!width=\nextboxwd,\c!height=\nextboxht,\c!offset=\!!zeropoint,#2]{\flushnextbox}}% + \hbox\framed[\c!location=\v!normal,#2]} + +\def\setlayertext + {\dotripleempty\dosetlayertext} + +\def\dosetlayertext[#1][#2][#3]% + {\bgroup + \getparameters + [\??lx] + [\c!align=, + \c!width=\hsize, + \c!color=, + \c!style=, + #3]% + \dowithnextboxcontent + {\forgetall + \hsize\@@lxwidth + \expanded{\setupalign[\@@lxalign]}% + \dosetfontattribute\??lx\c!style} + {\setlayer[#1][#2]{\strut\color[\@@lxcolor]{\flushnextbox}}% + \egroup}% + \vtop} + +% \setupbackgrounds +% [page] +% [background=pagefigures] +% +% \definelayer +% [pagefigures] +% [x=-2mm, +% y=-2mm, +% width=\paperwidth, +% height=\paperheight] +% +% \definelayerpreset [lefttop] [corner={left,top},location={right,bottom}] +% \definelayerpreset [righttop] [corner={right,top},location={left,bottom}] +% \definelayerpreset [leftbottom] [corner={left,bottom},location={right,top}] +% \definelayerpreset [rightbottom] [corner={right,bottom},location={left,top}] +% \definelayerpreset [middle] [corner=middle,location=middle] +% +% \setlayer[pagefigures][preset=lefttop] +% \setlayer[pagefigures][preset=righttop] +% \setlayer[pagefigures][preset=leftbottom] +% \setlayer[pagefigures][preset=rightbottom] + +\definelayerpreset + [\v!left\v!top] + [\c!corner={\v!left,\v!top},\c!location={\v!right,\v!bottom}] + +\definelayerpreset + [\v!right\v!top] + [\c!corner={\v!right,\v!top},\c!location={\v!left,\v!bottom}] + +\definelayerpreset + [\v!left\v!bottom] + [\c!corner={\v!left,\v!bottom},\c!location={\v!right,\v!top}] + +\definelayerpreset + [\v!right\v!bottom] + [\c!corner={\v!right,\v!bottom},\c!location={\v!left,\v!top}] + +\definelayerpreset + [\v!middle] + [\c!corner=\v!middle,\c!location=\v!middle] + +% \definelayerpreset +% [\v!middle\v!top] +% [\c!location=\v!bottom,\c!hoffset=.5\layerwidth] + +% \definelayerpreset +% [\v!middle\v!bottom] +% [\c!location=\v!top,\c!hoffset=.5\layerwidth,\c!voffset=\layerheight] + +% \definelayerpreset +% [\v!middle\v!left] +% [\c!location=\v!right,\c!voffset=.5\layerheight] + +% \definelayerpreset +% [\v!middle\v!right] +% [\c!location=\v!left,\c!hoffset=\layerwidth,\c!voffset=.5\layerheight] + +\definelayerpreset + [\v!middle\v!top] + [\c!location=\v!bottom,\c!corner=\v!top,\c!dx=.5\layerwidth] + +\definelayerpreset + [\v!middle\v!bottom] + [\c!location=\v!top,\c!corner=\v!bottom,\c!dx=.5\layerwidth] + +\definelayerpreset + [\v!middle\v!left] + [\c!location=\v!right,\c!corner=\v!left,\c!dy=.5\layerheight] + +\definelayerpreset + [\v!middle\v!right] + [\c!location=\v!left,\c!corner=\v!right,\c!dy=.5\layerheight] + +\def\alignedbox + {\dodoubleempty\doalignedbox[]} + +% \def\doalignedbox[#1][#2]% +% {\bgroup +% %\let\iftraceboxplacement\iftracelayers % ugly +% \dowithnextbox +% {\let\next\middlebox +% \processaction +% [#2] +% [ t=>\let\next\topbox , b=>\let\next\bottombox , +% l=>\let\next\leftbox , r=>\let\next\rightbox , +% bl=>\let\next\bottomleftbox,br=>\let\next\bottomrightbox, +% tl=>\let\next\topleftbox ,tr=>\let\next\toprightbox , +% lt=>\let\next\lefttopbox ,lb=>\let\next\leftbottombox , +% rt=>\let\next\righttopbox ,rb=>\let\next\rightbottombox]% +% \next{\flushnextbox}% +% \egroup}#1} + +\def\doalignedbox[#1][#2]% + {\bgroup + %\let\iftraceboxplacement\iftracelayers % ugly + \dowithnextbox + {\serializecommalist[#2]% + \executeifdefined{\??ab\??ab\serializedcommalist}\middlebox{\flushnextbox}% + \egroup}#1} + +\setvalue{\??ab\??ab }{\middlebox} +\setvalue{\??ab\??ab\v!middle }{\middlebox} +\setvalue{\??ab\??ab\v!left }{\leftbox } +\setvalue{\??ab\??ab\v!right }{\rightbox } +\setvalue{\??ab\??ab\v!bottom }{\bottombox} +\setvalue{\??ab\??ab\v!top }{\topbox } + +\setvalue{\??ab\??ab\v!middle\v!middle}{\middlebox} +\setvalue{\??ab\??ab\v!left \v!top }{\lefttopbox} +\setvalue{\??ab\??ab\v!left \v!bottom}{\leftbottombox} +\setvalue{\??ab\??ab\v!right \v!top }{\righttopbox} +\setvalue{\??ab\??ab\v!right \v!bottom}{\rightbottombox} +\setvalue{\??ab\??ab\v!top \v!left }{\topleftbox} +\setvalue{\??ab\??ab\v!bottom\v!left }{\bottomleftbox} +\setvalue{\??ab\??ab\v!top \v!right }{\toprightbox} +\setvalue{\??ab\??ab\v!bottom\v!right }{\bottomrightbox} + +\setvalue{\??ab\??ab c}{\middlebox} +\setvalue{\??ab\??ab l}{\leftbox} +\setvalue{\??ab\??ab r}{\rightbox} +\setvalue{\??ab\??ab b}{\bottombox} +\setvalue{\??ab\??ab t}{\topbox} + +\setvalue{\??ab\??ab lt}{\lefttopbox} +\setvalue{\??ab\??ab lb}{\leftbottombox} +\setvalue{\??ab\??ab rt}{\righttopbox} +\setvalue{\??ab\??ab rb}{\rightbottombox} +\setvalue{\??ab\??ab tl}{\topleftbox} +\setvalue{\??ab\??ab bl}{\bottomleftbox} +\setvalue{\??ab\??ab tr}{\toprightbox} +\setvalue{\??ab\??ab br}{\bottomrightbox} + +\setvalue{\??ab\??ab m}{\middlebox} + +% The next ones were desparately needed by Vit Zyka (see +% \type {supp-box} for definitions). + +\setvalue{\??ab\??ab g}{\baselinemiddlebox} +\setvalue{\??ab\??ab gl}{\baselineleftbox} +\setvalue{\??ab\??ab gc}{\baselinemiddlebox} +\setvalue{\??ab\??ab gr}{\baselinerightbox} + +\setvalue{\??ab\??ab \v!line }{\baselinemiddlebox} % \v!grid is taken +\setvalue{\??ab\??ab \v!line\v!left }{\baselineleftbox} +\setvalue{\??ab\??ab \v!line\v!middle}{\baselinemiddlebox} +\setvalue{\??ab\??ab \v!line\v!right }{\baselinerightbox} + +\unexpanded\def\offsetbox + {\dodoubleempty\dooffsetbox[]} + +% left/right/top/bottomoffset -> dimensions change +% x/y | method=fixed -> dimensions don't change + +\def\dooffsetbox[#1][#2]% + {\bgroup + \dowithnextbox + {\getparameters[\??ox] + [\c!x=\zeropoint, + \c!y=\zeropoint, + \c!width=\nextboxwd, + \c!height=\nextboxht, + \c!depth=\nextboxdp, + \c!location=, + \c!leftoffset=\zeropoint, + \c!rightoffset=\zeropoint, + \c!topoffset=\zeropoint, + \c!bottomoffset=\zeropoint, + \c!method=, + #2]% + \donefalse + \ifdim\@@oxleftoffset =\zeropoint\else\donetrue\fi + \ifdim\@@oxrightoffset=\zeropoint\else\donetrue\fi + \ifdim\@@oxtopoffset =\zeropoint\else\donetrue\fi + \ifdim\@@oxbottomoffset =\zeropoint\else\donetrue\fi + \ifdone + \doif\@@oxmethod\v!fixed % new + {\ifdim\@@oxleftoffset=\zeropoint + \ifdim\@@oxrightoffset=\zeropoint \else + \scratchdimen-\@@oxrightoffset + \edef\@@oxx{\the\scratchdimen}% + \let\@@oxrightoffset\zeropoint + \fi + \else + \let\@@oxx\@@oxleftoffset + \let\@@oxleftoffset\zeropoint + \fi + \ifdim\@@oxtopoffset=\zeropoint + \ifdim\@@oxbottomoffset=\zeropoint \else + \scratchdimen-\@@oxbottomoffset + \edef\@@oxy{\the\scratchdimen}% + \let\@@oxbottomoffset\zeropoint + \fi + \else + \let\@@oxy\@@oxtopoffset + \let\@@oxtopoffset\zeropoint + \fi + \donefalse}% + \fi + \ifdone + \setbox\nextbox\vbox + {\forgetall\offinterlineskip + \vskip\@@oxtopoffset + \hbox + {\hskip\@@oxleftoffset + \flushnextbox + \hskip\@@oxrightoffset}% + \vskip\@@oxbottomoffset}% + \scratchdimen\nextboxht + \advance\scratchdimen\nextboxdp + \nextboxht\scratchdimen + \nextboxdp\zeropoint + \fi + \freezedimenmacro\@@oxwidth + \freezedimenmacro\@@oxheight + \freezedimenmacro\@@oxdepth + \setbox\nextbox\hbox + {\hskip\@@oxx\lower\@@oxy\hbox + {\doifelsenothing\@@oxlocation + {\flushnextbox} + {\alignedbox[\@@oxlocation]\hbox{\flushnextbox}}}}% + \nextboxwd\@@oxwidth + \nextboxht\@@oxheight + \nextboxdp\@@oxdepth + \flushnextbox + \egroup}#1} + +% \useMPlibrary[pre] \setupbackgrounds[page][background=pagegrid] +% +% \placefigure[left,none]{}{\offset[leftoffset=1cm]{\externalfigure[koe][breedte=3cm]}} +% \input tufte +% \placefigure[left,none]{}{\offset[rightoffset=1cm]{\externalfigure[koe][breedte=3cm]}} +% \input tufte +% \placefigure[left,none]{}{\offset[topoffset=1cm]{\externalfigure[koe][breedte=3cm]}} +% \input tufte +% \placefigure[left,none]{}{\offset[bottomoffset=1cm]{\externalfigure[koe][breedte=3cm]}} +% \input tufte + +\unexpanded\def\offset {\dodoubleempty\dooffsetbox [\hbox]} % yes or no +\unexpanded\def\aligned{\dosingleempty\doalignedbox[\hbox]} % yes or no + +%\ruledhbox{\offsetbox[x=-1cm,y=-1cm,location=c] +% {\framed[width=4cm,height=4cm]{x}}} + +\def\dotabbed#1#2#3#4% + {\dontleavehmode + \bgroup + \setbox\scratchbox\hbox{#3}% + \hbox to \wd\scratchbox{#1#4#2}% + \egroup} + +\unexpanded\def\ltabbed{\dotabbed\relax\hss} +\unexpanded\def\rtabbed{\dotabbed\hss \relax} +\unexpanded\def\ctabbed{\dotabbed\hss \hss} \let\mtabbed\ctabbed + +% \ltabbed{\romeins{3}}{\romeins{1}} test \endgraf +% \ltabbed{\romeins{3}}{\romeins{2}} test \endgraf +% \ltabbed{\romeins{3}}{\romeins{3}} test \endgraf +% +% \rtabbed{\romeins{3}}{\romeins{1}} test \endgraf +% \rtabbed{\romeins{3}}{\romeins{2}} test \endgraf +% \rtabbed{\romeins{3}}{\romeins{3}} test \endgraf +% +% \ctabbed{\romeins{3}}{\romeins{1}} test \endgraf +% \ctabbed{\romeins{3}}{\romeins{2}} test \endgraf +% \ctabbed{\romeins{3}}{\romeins{3}} test \endgraf + +% alternative, if done, then other name +% +% \def\dotabbed#1#2#3#4% +% {\dontleavehmode +% \bgroup +% \scratchdimen\zeropoint +% \def\docommand##1% +% {\setbox\scratchbox\hbox{##1}% +% \ifdim\wd\scratchbox>\scratchdimen +% \scratchdimen\wd\scratchbox +% \fi}% +% \processcommalist[#3]\docommand +% \hbox to \scratchdimen{#1#4#2}% +% \egroup} +% +% \def\ltabbed{\dotabbed\relax\hss} +% \def\rtabbed{\dotabbed\hss \relax} +% \def\ctabbed{\dotabbed\hss \hss} \let\mtabbed\ctabbed +% +% \ltabbed{\romeins{10},\romeins{2000},\romeins{15}}{\romeins{10}} test \endgraf +% \ltabbed{\romeins{10},\romeins{2000},\romeins{15}}{\romeins{15}} test \endgraf +% \ltabbed{\romeins{10},\romeins{2000},\romeins{15}}{\romeins{2000}} test \endgraf +% +% \rtabbed{\romeins{10},\romeins{2000},\romeins{15}}{\romeins{10}} test \endgraf +% \rtabbed{\romeins{10},\romeins{2000},\romeins{15}}{\romeins{15}} test \endgraf +% \rtabbed{\romeins{10},\romeins{2000},\romeins{15}}{\romeins{2000}} test \endgraf +% +% \ctabbed{\romeins{10},\romeins{2000},\romeins{15}}{\romeins{10}} test \endgraf +% \ctabbed{\romeins{10},\romeins{2000},\romeins{15}}{\romeins{15}} test \endgraf +% \ctabbed{\romeins{10},\romeins{2000},\romeins{15}}{\romeins{2000}} test \endgraf + +% to be documented + +\unexpanded\def\phantombox[#1]% + {\hbox\bgroup + \getparameters + [\??ol] + [\c!width=\zeropoint,% + \c!height=\zeropoint,% + \c!depth=\zeropoint,#1]% + \setbox\scratchbox\null + \wd\scratchbox\@@olwidth + \ht\scratchbox\@@olheight + \dp\scratchbox\@@oldepth + \box\scratchbox + \egroup} + +% \backgroundimage{1}{\hsize}{\vsize}{\externalfigure[cow][\c!width=3cm]} + +\unexpanded\def\backgroundimage#1#2#3% repeat hsize vsize + {\bgroup + \forgetall + \dowithnextbox + {\offinterlineskip + \ifcase#1\relax + % just one + \else + \scratchdimen#2\divide\scratchdimen\nextboxwd\count0\scratchdimen\advance\count0\plusone + \scratchdimen#3\divide\scratchdimen\nextboxht\count2\scratchdimen\advance\count2\plusone + % to be considered, probably methods + \ifcase#1\or % x and y + \setbox\nextbox\hbox{\dorecurse{\count0}{\copy\nextbox}}% + \setbox\nextbox\vbox{\dorecurse{\count2}{\copy\nextbox\endgraf}}% + \or % x + \setbox\nextbox\hbox{\dorecurse{\count0}{\copy\nextbox}}% + \or % y + \setbox\nextbox\vbox{\dorecurse{\count2}{\copy\nextbox\endgraf}}% + \fi + \fi + \ifdim\nextboxwd>#2\relax + \setbox\nextbox\hbox to #2{\hss\flushnextbox\hss}% + \setbox\nextbox\hbox{\expanded{\clip[\c!width=#2,\c!height=\the\nextboxht]{\flushnextbox}}}% + \fi + \ifdim\nextboxht>#3\relax + \setbox\nextbox\vbox to #3{\vss\flushnextbox\vss}% + \setbox\nextbox\hbox{\expanded{\clip[\c!width=\the\nextboxwd,\c!height=#3]{\flushnextbox}}}% + \fi + \flushnextbox + \egroup}% + \hbox} + +\protect \endinput diff --git a/tex/context/base/pack-lyr.mkii b/tex/context/base/pack-lyr.mkii new file mode 100644 index 000000000..85549bccb --- /dev/null +++ b/tex/context/base/pack-lyr.mkii @@ -0,0 +1,755 @@ +%D \module +%D [ file=pack-lyr, +%D version=2000.10.20, +%D title=\CONTEXT\ Packaging 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 Packaging Macros / Layers} + +%D This module is now etex dependent. + +% todo : first / last / next / +... => page key +% test on left/right box when no doublesided option given +% use \ifcsname instead of doifvalue + +\unprotect + +% When being backgrounds layers get the background offset +% displacement. Should be an option, on by default +% (compatibility). + +% positie=forceer == ja maar dan ook in status=herhaal + +%D The layering mechanism implemented here is independent of +%D the output routine, but future extensions may depend on a +%D more close cooperation. + +%D First we overload a macro from \type {core-rul}. From now on +%D we accept a (optional) argument: the specific layer it +%D will go in. This means that we can move an overlay from one +%D background to the other using the dimensions of the parent. + +%D ! ! ! ! to be documented ! ! ! ! + +\ifx\undefined\defineoverlay \message{loaded to early} \wait \fi + +\def\defineoverlay + {\dotripleempty\dodefineoverlay} + +\def\dodefineoverlay[#1][#2][#3]% overlay [layer] content + {\ifthirdargument + \writestatus{BEWARE}{This (overlay definition) has changed!}% temp + \def\docommand##1{\setvalue{\??ov##1}{\setlayer[#2]{\executedefinedoverlay{##1}{#3}}}} + \else + \def\docommand##1{\setvalue{\??ov##1}{\executedefinedoverlay{##1}{#2}}}% + \fi + \processcommalist[#1]\docommand} + +%D When tracing is turned on, a couple of boxes will +%D show up as well as the reference point. + +\newif\iftracelayers % \tracelayerstrue + +%D This handy constant saved some string memory. + +\def\@@layerbox{@@layerbox} + +%D \macros +%D {definelayer} +%D +%D Each layer gets its own (global) box. This also means that +%D the data that goes into a layer, is typeset immediately. +%D Each layer automatically gets an associated overlay, +%D which can be used in any background assignment. + +% todo : links/rechts + +\def\definelayer + {\dodoubleargument\dodefinelayer} + +\def\dodefinelayer[#1][#2]% \zeropoint ipv \!!zeropoint + {\setuplayer + [#1] + [\c!doublesided=,\c!preset=, + \c!state=\v!start,\c!direction=\v!normal,\c!option=, + \c!x=\zeropoint,\c!y=\zeropoint,\c!position=\v!no, + \c!line=0,\c!column=0, + \c!width=\nextboxwd,\c!height=\nextboxht, + \c!offset=\zeropoint,\c!rotation=, % geen 0 ! + \c!hoffset=\zeropoint,\c!voffset=\zeropoint, + \c!dx=\zeropoint,\c!dy=\zeropoint, + \c!location=rb,\c!position=\v!no,\c!page=, + \c!method=\v!overlay, + \c!sx=1,\c!sy=1,\c!corner=,#2]% + \doifvalue{\??ll#1\c!doublesided}\v!yes + {\dopresetlayerbox{\v!left #1}% + \dopresetlayerbox{\v!right#1}}% + \dopresetlayerbox{#1}% + \defineoverlay[#1][\composedlayer{#1}]} + +\def\dopresetlayerbox#1% + {\ifundefined{\@@layerbox#1}% + \expandafter\newbox\csname\@@layerbox#1\endcsname + \else + \resetlayer[#1]% + \fi} + +%D \macros +%D {setuplayer} +%D +%D After a layer is defined, you can change its +%D characteristics. + +\def\setuplayer + {\dodoubleargument\dosetuplayer} + +\def\dosetuplayer[#1][#2]% + {\def\docommand##1{\getparameters[\??ll##1][#2]}% + \processcommalist[#1]\docommand} + +%D \macros +%D {setlayer} +%D +%D Data is moved into a layer with the following macro. When +%D \type {position} is set, relative positioning is used, with +%D the current point as reference point. Otherwise the topleft +%D corner is used as reference point. +%D +%D \starttyping +%D \setlayer [identifier] [optional parameters] {data} +%D \stoptyping + +\newcount\currentlayerdata + +\let\currentlayerwidth \!!zeropoint +\let\currentlayerheight\!!zeropoint + +\def\setcurrentlayerdimensions + {\dodoubleempty\dosetcurrentlayerdimensions} + +\def\dosetcurrentlayerdimensions[#1][#2]% name left|right + {\edef\currentlayerwidth {\thelayerwidth {#2#1}}% + \edef\currentlayerheight{\thelayerheight{#2#1}}} + +\def\thelayerwidth #1{\the\wd\executeifdefined{\@@layerbox#1}\emptybox} +\def\thelayerheight#1{\the\ht\executeifdefined{\@@layerbox#1}\emptybox} + +\def\setlayer + {\dotripleempty\dosetlayer} + +\def\dosetlayer[#1][#2][#3]% #4 == box do \fi is ok + {\doifelsevalue{\??ll#1\c!state}\v!stop + {\dowithnextbox\donothing\hbox} + {\ifthirdargument + \dodosetlayer[#1][#2][#3]% + \else + \doifassignmentelse{#2} + {\dodosetlayer[#1][][#2]}% + {\dodosetlayer[#1][#2][]}% + \fi}} + +\def\dodosetlayer[#1][#2][#3]% #2 = links/rechts + {\bgroup + \recalculatebackgrounds + \recalculatelogos + \global\advance\currentlayerdata\plusone + \forgetall + \dontcomplain + \doifvalue{\??ll#1\c!option}\v!test\tracelayerstrue + \iftracelayers\traceboxplacementtrue\fi + \dowithnextbox % sneller als aparte macro + {\ifcsname\@@layerbox#1\endcsname % nb: odd/even discard, left/right not + \edef\@@layerloc{#2}% + \ifx\@@layerloc\v!even + \ifodd\realpageno + % discard nextbox + \else + \dododosetlayer[#1][\v!left][#3]% + \fi + \else\ifx\@@layerloc\v!odd + \ifodd\realpageno + \dododosetlayer[#1][\v!right][#3]% + %\else + % discard nextbox + \fi + \else + \dododosetlayer[#1][#2][#3]% + \fi\fi + \else + \writestatus{layer}{unknown layer #1}% + \fi + \egroup}% + \hbox} + +\newbox\layerbox + +\newdimen\@@layerxsiz +\newdimen\@@layerysiz +\newdimen\@@layerxoff +\newdimen\@@layeryoff +\newdimen\@@layerxpos +\newdimen\@@layerypos + +\let\lastlayerxpos\!!zeropoint +\let\lastlayerypos\!!zeropoint +\let\lastlayerwd \!!zeropoint +\let\lastlayerht \!!zeropoint +\let\lastlayerdp \!!zeropoint + +% todo left/right + +\def\setlastlayerpos#1% + {\edef\layerpage{\MPp{lyr:\the\currentlayerdata}}% + \xdef\lastlayerxpos{\the\dimexpr-\MPx{lyr:#1:\layerpage}+\MPx{lyr:\the\currentlayerdata}\relax}% + \xdef\lastlayerypos{\the\dimexpr \MPy{lyr:#1:\layerpage}-\MPy{lyr:\the\currentlayerdata}\relax}} + +\def\definelayerpreset + {\dodoubleargument\dodefinelayerpreset} + +% \def\dodefinelayerpreset[#1][#2]% +% {\setvalue{\??ll\??ll#1}{\dopresetlayer{#2}}} +% +% more fun: \definelayerpreset[whatever][lefttop] + +\def\dodefinelayerpreset[#1][#2]% + {\doifassignmentelse{#2} + {\setvalue{\??ll\??ll#1}{\dopresetlayer{#2}}} + {\setvalue{\??ll\??ll#1}{\getvalue{\??ll\??ll#2}}}} + +\def\dopresetlayer#1#2#3% #1=list #2=tag #3=list + {\getparameters[\??ll#2][#1,#3]} + +\letempty\currentlayer + +\def\layerparameter#1{\csname\??ll\currentlayer#1\endcsname} + +\newdimen\layerwidth +\newdimen\layerheight + +\chardef\@@lacome=1 % LAyerCOnstructionMEthod / temp, will be default + +\def\dododosetlayer[#1][#2][#3]% will be sped up + {% we use the global width, never change this + \def\currentlayer{#1}% + \@@layerxsiz\layerparameter\c!width + \@@layerysiz\layerparameter\c!height + \layerwidth \@@layerxsiz + \layerheight\@@layerysiz + % preroll + \getparameters[\??ll\currentlayer][#3]% + % presets and real roll +% maybe todo: +% \doif{\layerparameter\c!method}\v!fit +% {\@@layerxsiz\thelayerwidth \currentlayer +% \@@layerysiz\thelayerheight\currentlayer +% \layerwidth \@@layerxsiz +% \layerheight\@@layerysiz +% }% + % etc + \executeifdefined{\??ll\??ll\layerparameter\c!preset}\gobbletwoarguments\currentlayer{#3}% + % that was real slow + \doif{\layerparameter\c!position}\v!overlay % slow, use \dosetvalue instead + {\getparameters[\??ll\currentlayer][\c!width=\zeropoint,\c!height=\zeropoint,\c!position=\v!yes]}% + \doifsomething{\layerparameter\c!rotation} + {\setbox\nextbox\hbox + {\rotate % to be checked with new rotation + [\c!location=\v!high,\c!rotation=\layerparameter\c!rotation] + {\flushnextbox}}}% + % no, not local + % \@@layerxsiz\layerparameter\c!width + % \@@layerysiz\layerparameter\c!height + % never change that + \@@layerxpos\layerparameter\c!x + \@@layerypos\layerparameter\c!y + \doifelse{\layerparameter\c!hoffset}\v!max + {\@@layerxoff\@@layerxsiz}{\@@layerxoff\layerparameter\c!hoffset}% + \doifelse{\layerparameter\c!voffset}\v!max + {\@@layeryoff\@@layerysiz}{\@@layeryoff\layerparameter\c!voffset}% + % dx/dy are internal context ones and can be used in preset + \advance\@@layerxoff\dimexpr\layerparameter\c!offset+\layerparameter\c!dx\relax + \advance\@@layeryoff\dimexpr\layerparameter\c!offset+\layerparameter\c!dy\relax + \@@layerxpos\layerparameter\c!sx\@@layerxpos + \@@layerypos\layerparameter\c!sy\@@layerypos + \@@layerxoff\layerparameter\c!sx\@@layerxoff + \@@layeryoff\layerparameter\c!sy\@@layeryoff + \doifelse{\layerparameter\c!position}\v!yes % combine ^ + {\setlastlayerpos{#2\currentlayer}% todo l/r %%%%%%%%%%%% + \@@layerxpos\lastlayerxpos + \@@layerypos\lastlayerypos + \letgvalue{\??ll\currentlayer\layerpage\c!position}\v!yes + \letgvalue{\??ll\currentlayer\c!state}\v!start % needed ? + \setbox\layerbox\vbox to \@@layerysiz + {\hbox to \@@layerxsiz{\xypos{lyr:\the\currentlayerdata}\hss}\vss}} + {\setbox\layerbox\emptybox + \globallet\lastlayerxpos\!!zeropoint + \globallet\lastlayerypos\!!zeropoint + \ExpandBothAfter\doifinset\v!bottom{\layerparameter\c!corner} + {\ifnum\layerparameter\c!line=\zerocount\else % can be < 0 + \setevalue{\??ll\currentlayer\c!line}% + {\the\numexpr-\layerparameter\c!line+\layoutlines+\plusone\relax}% + \fi + \ifdim\@@layerysiz>\zeropoint + \advance\@@layerypos-\@@layerysiz + \@@layerypos-\@@layerypos + \@@layeryoff-\@@layeryoff + \fi}% + \ExpandBothAfter\doifinset\v!right{\layerparameter\c!corner} + {\ifnum\layerparameter\c!column=\zerocount\else % can be < 0 + \setevalue{\??ll\currentlayer\c!column}% + {\the\numexpr-\layerparameter\c!column+\layoutcolumns+\plusone\relax}% + \fi + \ifdim\@@layerxsiz>\zeropoint + \advance\@@layerxpos-\@@layerxsiz + \@@layerxpos-\@@layerxpos + \@@layerxoff-\@@layerxoff + \fi}% + \ExpandBothAfter\doif\v!middle{\layerparameter\c!corner} + {\ifdim\@@layerxsiz>\zeropoint \advance\@@layerxpos.5\@@layerxsiz \fi + \ifdim\@@layerysiz>\zeropoint \advance\@@layerypos.5\@@layerysiz \fi}% + \edef\layerpage{\layerparameter\c!page}}% + \doifsomething\layerpage + {\edef\layerpage{:\layerpage}% + \doifundefined{\@@layerbox#2\currentlayer\layerpage} + {\global\expandafter\newbox\csname\@@layerbox#2\currentlayer\layerpage\endcsname}}% + \dontcomplain % more comfortable + \mathchardef\layerpagebox\csname\@@layerbox#2\currentlayer\layerpage\endcsname + \ifvoid\layerpagebox + \gsetboxllx\layerpagebox\zeropoint + \gsetboxlly\layerpagebox\zeropoint + \fi + \global\setbox\layerpagebox\vbox %to \layerparameter\c!height % new, otherwise no negative y possible + {\offinterlineskip + %postpone, to after nextboxwd correction % \hsize\layerparameter\c!width % new, keep box small + %\ifvoid\csname\@@layerbox\currentlayer\layerpage\endcsname\else % why not #2#1 + \ifvoid\layerpagebox + \let\lastlayerwidth \zeropoint + \let\lastlayerheight\zeropoint + \else + \edef\lastlayerwidth {\the\wd\layerpagebox}% + \edef\lastlayerheight{\the\ht\layerpagebox}% + \ht\layerpagebox\zeropoint + \dp\layerpagebox\zeropoint + \wd\layerpagebox\zeropoint + \doifnot{\layerparameter\c!direction}\v!reverse{\box\layerpagebox}% + \fi + % don't move + \xdef\lastlayerwd{\the\nextboxwd}% + \xdef\lastlayerht{\the\nextboxht}% % not entirely ok when grid ! + \xdef\lastlayerdp{\the\nextboxdp}% % not entirely ok when grid ! + % this code + \doifelse{\layerparameter\c!location}\v!grid\donetrue\donefalse + \ifdone + \nextboxht\strutheight + \nextboxdp\strutdepth + \else + \setbox\nextbox\hbox{\alignedbox[\layerparameter\c!location]\vbox{\flushnextbox}}% + \fi + \ifnum\layerparameter\c!line=\zerocount\else % no \ifcase, can be negative + \advance\@@layerypos\dimexpr\layerparameter\c!line\lineheight+\topskip-\lineheight-\nextboxht\relax + \fi + \ifnum\layerparameter\c!column=\zerocount\else % no \ifcase, can be negative + \advance\@@layerxpos\layoutcolumnoffset{\layerparameter\c!column}% + \fi + \ifdone + \setbox\nextbox\hbox{\alignedbox[rb]\vbox{\flushnextbox}}% + \fi + % ll registration + \scratchdimen\@@layerxpos + \advance\scratchdimen\@@layerxoff + \ifdim\scratchdimen<\getboxllx\layerpagebox + \gsetboxllx\layerpagebox\scratchdimen + \fi + \ifcase\@@lacome\or % this test will become obsolete + \advance\scratchdimen\nextboxwd + \nextboxwd\ifdim\scratchdimen>\lastlayerwidth \scratchdimen \else \lastlayerwidth \fi + \fi + \scratchdimen\@@layerypos + \advance\scratchdimen\@@layeryoff + \ifdim\scratchdimen<\getboxlly\layerpagebox + \gsetboxlly\layerpagebox\scratchdimen + \fi + % ll compensation + \ifcase\@@lacome\or % this test will become obsolete + \advance\scratchdimen\dimexpr\nextboxht+\nextboxdp\relax + \nextboxht\ifdim\scratchdimen>\lastlayerheight \scratchdimen \else \lastlayerheight \fi + \nextboxdp\zeropoint + \fi + % placement + \hsize\layerparameter\c!width % new, keep box small + \vbox to \layerparameter\c!height \bgroup + \smashbox\nextbox + \vskip\dimexpr\@@layerypos+\@@layeryoff\relax + \hskip\dimexpr\@@layerxpos+\@@layerxoff\relax + \flushnextbox + \ifvoid\layerpagebox + % already flushed + \else + % the reverse case % check ! + \vskip-\dimexpr\@@layerypos+\@@layeryoff\relax + \box\layerpagebox + \fi + \egroup}% + % when position is true, the layerbox holds the compensation and needs + % to be placed; never change this ! + \ifvoid\layerbox\else\box\layerbox\fi} + +%D Given the task to be accomplished, the previous macro is +%D not even that complicated. It mainly comes down to skipping +%D to the right place and placing a box on top of or below the +%D existing content. In the case of position tracking, another +%D reference point is chosen. + +%D \macros +%D {doifelselayerdata} +%D + +\def\doifelselayerdata#1% + {\ifundefined{\@@layerbox#1}% + \@EA\secondoftwoarguments + \else\ifvoid\csname\@@layerbox#1\endcsname + \@EAEAEA\secondoftwoarguments + \else + \@EAEAEA\firstoftwoarguments + \fi\fi} + +%D \macros +%D {flushlayer} +%D +%D When we flush a layer, we flush both the main one and the +%D page dependent one (when defined). This feature is more +%D efficient in \ETEX\ since there testing for an undefined +%D macro does not takes hash space. + +% todo: setups before flush, handy hook + +\unexpanded\def\flushlayer[#1]% + {\doifelsevalue{\??ll#1\c!state}\v!next + {\global\letvalue{\??ll#1\c!state}\v!start} % dangerous, stack-built-up + {\doifelsevalue{\??ll#1\c!state}\v!continue + {\global\letvalue{\??ll#1\c!state}\v!repeat} % dangerous, stack-built-up + {\doifelsevalue{\??ll#1\c!doublesided}\v!yes + {\doifundefinedelse{\@@layerbox#1}% + {\dodoflushlayerA[#1]} + {\doifbothsidesoverruled + {\dodoflushlayerB\v!left [#1]}% left + {\dodoflushlayerB\v!right[#1]}% right + {\dodoflushlayerB\v!left [#1]}}}% left + {\dodoflushlayerA[#1]}}}} + +\def\dodoflushlayerA[#1]% + {\doifnotvalue{\??ll#1\c!state}\v!stop + {\startoverlay + {\dodoflushlayer1{#1}{#1}} + {\dodoflushlayer0{#1}{#1:\realfolio}} + \stopoverlay}} + +\def\dodoflushlayerB#1[#2]% + {\doifnotvalue{\??ll#2\c!state}\v!stop + {\startoverlay + {\dodoflushlayer1{#2}{#2}} + {\dodoflushlayer0{#2}{#2:\realfolio}} + {\dodoflushlayer1{#2}{#1#2}} + {\dodoflushlayer0{#2}{#1#2:\realfolio}} + \stopoverlay}} + +\def\dodoflushlayer#1#2#3% + {\ifundefined{\@@layerbox#3}% + \ifcase#1\else\writestatus{layer}{unknown layer #3}\fi + \else + \bgroup + \forgetall + \offinterlineskip + % needed because we need to handle method + \executeifdefined{\??ll\??ll\getvalue{\??ll#2\c!preset}}\gobbletwoarguments{#2}{}% + % + \doifvalue{\??ll#2\c!option}\v!test\tracelayerstrue + \iftracelayers\traceboxplacementtrue\fi + \!!doneafalse + \!!donebfalse + \doifvalue{\??ll#2\c!method}\v!overlay\!!doneatrue + \doifvalue{\??ll#2\c!method}\v!fit\!!donebtrue + \!!donectrue + \ifcase#1\else + \doifnotvalue{\??ll#2\c!position}\v!yes + {\doifvalue{\??ll#2\c!repeat}\v!yes\!!donecfalse + \doifvalue{\??ll#2\c!state}\v!repeat\!!donecfalse}% + \fi + \mathchardef\layerbox\csname\@@layerbox#3\endcsname + % we need to copy in order to retain the negative offsets for a next + % stage of additions, i.e. llx/lly accumulate in repeat mode and the + % compensation may differ each flush depending on added content + \setbox\nextbox \if!!doneb +% \vbox +% {\scratchdimen\getboxlly\layerbox +% \vskip-\scratchdimen +% \scratchdimen\getboxllx\layerbox +% \hskip-\scratchdimen +% \advance\scratchdimen-\wd\layerbox +% \hsize-\scratchdimen +% \if!!donec\box\else\copy\fi\layerbox}% + \vbox + {\vskip-\getboxlly\layerbox + \hskip-\getboxllx\layerbox + \hsize-\dimexpr\getboxllx\layerbox-\wd\layerbox\relax + \if!!donec\box\else\copy\fi\layerbox}% + \else + \if!!donec\box\else\copy\fi\layerbox % sorry for the delay due to copying + \fi + % todo: method=offset => overlayoffset right/down (handy for backgrounds with offset) + \iftracelayers \ruledvbox \else \vbox \fi \if!!donea to \overlayheight \fi + {\hbox \if!!donea to \overlaywidth \fi + {% klopt dit? #3 en niet #2 ? + \doifvalue{\??ll#3\realfolio\c!position}\v!yes{\xypos{lyr:#3:\realfolio}}% + \doifoverlayelse{#3} + {\box\nextbox} + {\startlayoutcomponent{l:#3}{layer #3}\box\nextbox\stoplayoutcomponent}% + \hss}% + \vss}% + \if!!donec + \gsetboxllx\layerbox\zeropoint + \gsetboxlly\layerbox\zeropoint + \fi + \egroup + \fi} + +% \definelayer[test][method=fit] \setupcolors[state=start] \tracelayerstrue +% +% \framed[framecolor=red,offset=overlay]{\setlayer[test]{aa}\setlayer[test][x=10pt]{g}\flushlayer[test]} +% \framed[framecolor=red,offset=overlay]{\setlayer[test]{aa}\setlayer[test][x=-10pt]{bb}\flushlayer[test]} +% \framed[framecolor=red,offset=overlay]{\setlayer[test][x=-20pt]{cccccc}\flushlayer[test]} +% \framed[framecolor=red,offset=overlay]{\setlayer[test]{dd}\setlayer[test][x=-20pt,y=-3pt]{eeeeee}\flushlayer[test]} + +%D \macros +%D {composedlayer,placelayer,tightlayer} +%D +%D This is a handy shortcut, which saves a couple of braces +%D when we use it as parameter. This name also suits better +%D to other layering commands. + +\def\composedlayer#1{\flushlayer[#1]} + +\let\placelayer\flushlayer + +\def\tightlayer[#1]% + {\hbox + {\def\currentlayer{#1}% todo: left/right + \setbox\nextbox\emptybox % hoogte/breedte are \wd\nextbox/\ht\nextbox + \hsize\layerparameter\c!width % \overlaywidth = \hsize + \vsize\layerparameter\c!height % \overlaywheight = \vsize + \composedlayer{#1}}} + +%D \macros +%D {resetlayer} +%D +%D This macro hardly needs an explanation (and is seldom +%D needed as well). + +\def\doresetlayer#1% + {\ifundefined{\@@layerbox#1}\else + \global\setbox\csname\@@layerbox#1\endcsname\emptybox + \fi} + +\def\resetlayer[#1]% + {\doresetlayer{#1}% + \doifvalue{\??ll#1\c!doublesided}\v!yes % kind of redundant test + {\doresetlayer{\v!left #1}% + \doresetlayer{\v!right#1}}% + \doresetlayer{#1:\realfolio}} + +%D \macros +%D {setMPlayer} +%D +%D The following layer macro uses the positions that are +%D registered by \METAPOST. +%D +%D \starttyping +%D \definelayer[test] +%D +%D \setMPlayer [test] [somepos-1] {Whatever we want here!} +%D \setMPlayer [test] [somepos-2] {Whatever we need there!} +%D \setMPlayer [test] [somepos-3] {\externalfigure[cow.mps][width=2cm]} +%D +%D \startuseMPgraphic{oeps} +%D draw fullcircle scaled 10cm withcolor red ; +%D register ("somepos-1",2cm,3cm,center currentpicture) ; +%D register ("somepos-2",8cm,5cm,(-1cm,-2cm)) ; +%D register ("somepos-3",0cm,0cm,(-2cm,2cm)) ; +%D \stopuseMPgraphic +%D +%D \getMPlayer[test]{\useMPgraphic{oeps}} +%D \stoptyping +%D +%D The last line is equivalent to +%D +%D \starttyping +%D \framed +%D [background={foreground,test},offset=overlay] +%D {\useMPgraphic{oeps}} +%D \stoptyping + +\def\setMPlayer + {\dotripleempty\dosetMPlayer} + +\def\MPlayerwidth {\hsize} +\def\MPlayerheight{\vsize} + +\def\dosetMPlayer[#1][#2][#3]% + {\checkpositions % new, else only support after \starttext + \edef\MPlayerwidth {\MPw{#2}}% + \edef\MPlayerheight{\MPh{#2}}% + \setlayer[#1][\c!x=\MPx{#2},\c!y=\MPy{#2},\c!position=\v!no,#3]} + +\def\getMPlayer + {\dodoubleempty\dogetMPlayer} + +\def\dogetMPlayer[#1][#2]% + {\framed + [\c!background={\v!foreground,#1}, + \c!frame=\v!off, + \c!offset=\v!overlay,#2]} + +% Some day this (old) mechanism will be combined/integrated +% in overlays + +\newskip\xposition \newskip\yposition +\newskip\xdimension \newskip\ydimension +\newskip\xoffset \newskip\yoffset + +% already defined \newbox\positionbox + +\def\startpositioning + {\bgroup + \xposition \zeropoint \yposition \zeropoint + \xdimension\zeropoint \ydimension\zeropoint + \xoffset \zeropoint \yoffset \zeropoint + \hfuzz \paperwidth \vfuzz \paperheight + \setbox\positionbox\hbox\bgroup} + +\def\stoppositioning + {\doifnot\@@psoffset\v!yes + {\global\xoffset\zeropoint + \global\yoffset\zeropoint}% + \global\advance\xdimension \xoffset + \global\advance\ydimension \yoffset + \egroup + \vbox to \ydimension + {\vskip\yoffset + \hbox to \xdimension + {\hskip\xoffset + \box\positionbox + \hfill} + \vfill}% + \egroup} + +\def\resetpositioning + {\getparameters[\??ps] + [\c!state=\v!start,% + \c!unit=\s!cm,% + \c!factor=1,% + \c!scale=1,% + \c!xfactor=\@@psfactor,% + \c!yfactor=\@@psfactor,% + \c!xscale=\@@psscale,% + \c!yscale=\@@psscale,% + \c!xstep=\v!absolute,% + \c!ystep=\v!absolute,% + \c!xoffset=\!!zeropoint,% + \c!yoffset=\!!zeropoint]} + +\def\setuppositioning + {\resetpositioning + \dodoubleargument\getparameters[\??ps]} + +\def\calculateposition#1#2#3#4#5#6#7#8#9% + {\setdimensionwithunit\scratchskip{#1}\@@psunit + \scratchskip#8\scratchskip + \scratchskip#9\scratchskip + \advance\scratchskip #4\relax + \doif{#2}\v!relative + {\advance\scratchskip #3% + \let#4\!!zeropoint}% + #3\scratchskip\relax + \doifnot\@@psstate\v!overlay + {\scratchskip#5\relax + \advance\scratchskip #3\relax + \ifdim#3<-#7\relax \global#7-#3\relax \fi + \ifdim\scratchskip>#6\relax \global#6\scratchskip\relax \fi}} + +\def\position + {\dosingleempty\doposition} + +\def\doposition[#1]#2(#3,#4)% + {\dowithnextbox + {\bgroup + \getparameters[\??ps][#1]% + \dontcomplain + \calculateposition{#3}\@@psxstep\xposition + \@@psxoffset{\nextboxwd}\xdimension\xoffset + \@@psxscale\@@psxfactor + \scratchdimen\nextboxht \advance\scratchdimen \nextboxdp + \calculateposition{#4}\@@psystep\yposition + \@@psyoffset\scratchdimen\ydimension\yoffset + \@@psyscale\@@psyfactor + \vbox to \zeropoint % kan beter. + {\vskip\yposition + \hbox to \zeropoint + {\hskip\xposition + \flushnextbox + \hss} + \vss}% + \xdef\dopoppositioning + {\xposition\the\xposition + \yposition\the\yposition + \noexpand\def\noexpand\@@psxoffset{\@@psxoffset}% + \noexpand\def\noexpand\@@psyoffset{\@@psyoffset}}% + \egroup + \dopoppositioning + \ignorespaces} + \hbox} + +\resetpositioning + +\setuppositioning + [\c!unit=\s!cm, + \c!factor=1, + \c!scale=1, + \c!xstep=\v!absolute, + \c!ystep=\v!absolute, + \c!offset=\v!yes, + \c!xoffset=\!!zeropoint, + \c!yoffset=\!!zeropoint] + +%D Watch out, a redefinition: + +\ifx\settextpagecontent\undefined \writestatus\m!systems{error in page-lyr.tex} \wait \fi + +\let\normalsettextpagecontent\settextpagecontent + +\definelayer + [OTRTEXT] + +\setuplayer + [OTRTEXT] + [\c!width=\innermakeupwidth, + \c!height=\textheight] + +% will be overloaded in page-spr + +\def\settextpagecontent#1#2#3% #2 and #3 will disappear + {\doifelselayerdata{OTRTEXT} + {\setbox#1\hbox to \makeupwidth + {\startoverlay + {\tightlayer[OTRTEXT]} % first, otherwise problems with toc + {\normalsettextpagecontent{#1}{#2}{#3}\box#1} + \stopoverlay}% + \dp#1\zeropoint}% + {\normalsettextpagecontent{#1}{#2}{#3}}} + +\protect \endinput diff --git a/tex/context/base/pack-lyr.mkiv b/tex/context/base/pack-lyr.mkiv new file mode 100644 index 000000000..0cb3ee244 --- /dev/null +++ b/tex/context/base/pack-lyr.mkiv @@ -0,0 +1,786 @@ +%D \module +%D [ file=pack-lyr, +%D version=2000.10.20, +%D title=\CONTEXT\ Packaging 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 Packaging Macros / Layers} + +% todo : first / last / next / +... => page key +% test on left/right box when no doublesided option given +% use \ifcsname instead of doifvalue + +\unprotect + +% When being backgrounds layers get the background offset +% displacement. Should be an option, on by default +% (compatibility). + +% positie=forceer == ja maar dan ook in status=herhaal + +%D The layering mechanism implemented here is independent of +%D the output routine, but future extensions may depend on a +%D more close cooperation. + +%D First we overload a macro from \type {core-rul}. From now on +%D we accept a (optional) argument: the specific layer it +%D will go in. This means that we can move an overlay from one +%D background to the other using the dimensions of the parent. + +\ifx\undefined\defineoverlay \message{loaded to early} \wait \fi + +\unexpanded\def\defineoverlay + {\dotripleempty\dodefineoverlay} + +\def\dodefineoverlay[#1][#2][#3]% overlay [layer] content + {\ifthirdargument + %\writestatus{BEWARE}{This (overlay definition) has changed!}% temp + \def\docommand##1{\setvalue{\??ov##1}{\setlayer[#2]{\executedefinedoverlay{##1}{#3}}}} + \else + \def\docommand##1{\setvalue{\??ov##1}{\executedefinedoverlay{##1}{#2}}}% + \fi + \processcommalist[#1]\docommand} + +%D When tracing is turned on, a couple of boxes will +%D show up as well as the reference point. + +\newif\iftracelayers % \tracelayerstrue + +%D This handy constant saved some string memory. + +\def\@@layerbox{@@layerbox} + +%D \macros +%D {definelayer} +%D +%D Each layer gets its own (global) box. This also means that +%D the data that goes into a layer, is typeset immediately. +%D Each layer automatically gets an associated overlay, +%D which can be used in any background assignment. + +% todo : links/rechts + +\unexpanded\def\definelayer + {\dodoubleargument\dodefinelayer} + +\def\dodefinelayer[#1][#2]% \zeropoint ipv \!!zeropoint + {\setuplayer + [#1] + [\c!doublesided=,\c!preset=, + \c!state=\v!start,\c!direction=\v!normal,\c!option=, + \c!x=\zeropoint,\c!y=\zeropoint,\c!position=\v!no, + \c!line=0,\c!column=0, + \c!width=\nextboxwd,\c!height=\nextboxht, + \c!offset=\zeropoint,\c!rotation=, % geen 0 ! + \c!hoffset=\zeropoint,\c!voffset=\zeropoint, + \c!dx=\zeropoint,\c!dy=\zeropoint, + \c!location=rb,\c!position=\v!no,\c!page=, + \c!method=\v!overlay, + \c!sx=1,\c!sy=1,\c!corner=,#2]% + \doifvalue{\??ll#1\c!doublesided}\v!yes + {\dopresetlayerbox{\v!left #1}% + \dopresetlayerbox{\v!right#1}}% + \dopresetlayerbox{#1}% + \defineoverlay[#1][\composedlayer{#1}]} + +\def\dopresetlayerbox#1% + {\ifcsname\@@layerbox#1\endcsname + \resetlayer[#1]% + \else + \expandafter\newbox\csname\@@layerbox#1\endcsname + \fi} + +%D \macros +%D {setuplayer} +%D +%D After a layer is defined, you can change its +%D characteristics. + +\unexpanded\def\setuplayer + {\dodoubleargument\dosetuplayer} + +\def\dosetuplayer[#1][#2]% + {\def\docommand##1{\getparameters[\??ll##1][#2]}% + \processcommalist[#1]\docommand} + +%D \macros +%D {setlayer} +%D +%D Data is moved into a layer with the following macro. When +%D \type {position} is set, relative positioning is used, with +%D the current point as reference point. Otherwise the topleft +%D corner is used as reference point. +%D +%D \starttyping +%D \setlayer [identifier] [optional parameters] {data} +%D \stoptyping + +\newcount\currentlayerdata + +\let\currentlayerwidth \!!zeropoint +\let\currentlayerheight\!!zeropoint + +\def\setcurrentlayerdimensions + {\dodoubleempty\dosetcurrentlayerdimensions} + +\def\dosetcurrentlayerdimensions[#1][#2]% name left|right + {\edef\currentlayerwidth {\thelayerwidth {#2#1}}% + \edef\currentlayerheight{\thelayerheight{#2#1}}} + +\def\thelayerwidth #1{\the\wd\executeifdefined{\@@layerbox#1}\emptybox} +\def\thelayerheight#1{\the\ht\executeifdefined{\@@layerbox#1}\emptybox} + +\def\setlayer + {\dotripleempty\dosetlayer} + +% \def\dosetlayer[#1][#2][#3]% #4 == box do \fi is ok +% {\doifelsevalue{\??ll#1\c!state}\v!stop +% {\dowithnextbox\donothing\hbox} +% {\ifthirdargument +% \dodosetlayer[#1][#2][#3]% +% \else +% \dodosetlayer[#1][][#2]% +% \fi}} + +\def\dosetlayer[#1][#2][#3]% #4 == box do \fi is ok + {\doifelsevalue{\??ll#1\c!state}\v!stop + {\dowithnextbox\donothing\hbox} + {\ifthirdargument + \dodosetlayer[#1][#2][#3]% + \else + \doifassignmentelse{#2} + {\dodosetlayer[#1][][#2]}% + {\dodosetlayer[#1][#2][]}% + \fi}} + +\def\dodosetlayer[#1][#2][#3]% #2 = links/rechts + {\bgroup + \recalculatebackgrounds % brrr + \global\advance\currentlayerdata\plusone + \forgetall + \dontcomplain + \doifvalue{\??ll#1\c!option}\v!test\tracelayerstrue + \iftracelayers\traceboxplacementtrue\fi + \dowithnextbox{\dodosetlayerindeed{#1}{#2}{#3}\egroup}\hbox} + +\def\dodosetlayerindeed#1#2#3% #2 = links/rechts + {\ifcsname\@@layerbox#1\endcsname % nb: odd/even discard, left/right not + \edef\@@layerloc{#2}% + \ifx\@@layerloc\v!even + \ifodd\realpageno + % discard nextbox + \else + \dododosetlayer[#1][\v!left][#3]% + \fi + \else\ifx\@@layerloc\v!odd + \ifodd\realpageno + \dododosetlayer[#1][\v!right][#3]% + %\else + % discard nextbox + \fi + \else + \dododosetlayer[#1][#2][#3]% + \fi\fi + \else + \writestatus{layer}{unknown layer #1}% + \fi} + +\newbox\layerbox + +\newdimen\@@layerxsiz +\newdimen\@@layerysiz +\newdimen\@@layerxoff +\newdimen\@@layeryoff +\newdimen\@@layerxpos +\newdimen\@@layerypos + +\let\lastlayerxpos\!!zeropoint +\let\lastlayerypos\!!zeropoint +\let\lastlayerwd \!!zeropoint +\let\lastlayerht \!!zeropoint +\let\lastlayerdp \!!zeropoint + +% todo left/right + +\def\setlastlayerpos#1% + {\edef\layerpage{\MPp{lyr:\the\currentlayerdata}}% + \xdef\lastlayerxpos{\the\dimexpr-\MPx{lyr:#1:\layerpage}+\MPx{lyr:\the\currentlayerdata}\relax}% + \xdef\lastlayerypos{\the\dimexpr \MPy{lyr:#1:\layerpage}-\MPy{lyr:\the\currentlayerdata}\relax}} + +\unexpanded\def\definelayerpreset + {\dodoubleargument\dodefinelayerpreset} + +% \def\dodefinelayerpreset[#1][#2]% +% {\setvalue{\??ll\??ll#1}{\dopresetlayer{#2}}} +% +% more fun: \definelayerpreset[whatever][lefttop] + +\def\dodefinelayerpreset[#1][#2]% + {\doifassignmentelse{#2} + {\setvalue{\??ll\??ll#1}{\dopresetlayer{#2}}} + {\setvalue{\??ll\??ll#1}{\csname\??ll\??ll#2\endcsname}}} + +\def\dopresetlayer#1#2#3% #1=list #2=tag #3=list + {\getparameters[\??ll#2][#1,#3]} + +\letempty\currentlayer + +\def\layerparameter#1{\csname\??ll\currentlayer#1\endcsname} + +\newdimen\layerwidth +\newdimen\layerheight + +\chardef\@@lacome=1 % LAyerCOnstructionMEthod / temp, will be default + +\def\dododosetlayer[#1][#2][#3]% will be sped up + {% we use the global width, never change this + \def\currentlayer{#1}% + \@@layerxsiz\layerparameter\c!width + \@@layerysiz\layerparameter\c!height + \layerwidth \@@layerxsiz + \layerheight\@@layerysiz + % preroll + \getparameters[\??ll\currentlayer][#3]% + % + % \executeifdefined{\??ll\??ll\layerparameter\c!preset}\gobbletwoarguments\currentlayer{#3}% + % + \edef\@@currentlayerpreset{\layerparameter\c!preset}% + \ifcsname\??ll\??ll\@@currentlayerpreset\endcsname\csname\??ll\??ll\@@currentlayerpreset\endcsname\currentlayer{#3}\fi + % + \doif{\layerparameter\c!position}\v!overlay % slow, use \dosetvalue instead + {\getparameters[\??ll\currentlayer][\c!width=\zeropoint,\c!height=\zeropoint,\c!position=\v!yes]}% + \doifsomething{\layerparameter\c!rotation}% todo: use direct lowlevel call + {\setbox\nextbox\hbox{\rotate[\c!location=\v!high,\c!rotation=\layerparameter\c!rotation]{\flushnextbox}}}% + % no, not local + % \@@layerxsiz\layerparameter\c!width + % \@@layerysiz\layerparameter\c!height + % never change that + \@@layerxpos\layerparameter\c!x + \@@layerypos\layerparameter\c!y + \doifelse{\layerparameter\c!hoffset}\v!max{\@@layerxoff\@@layerxsiz}{\@@layerxoff\layerparameter\c!hoffset}% + \doifelse{\layerparameter\c!voffset}\v!max{\@@layeryoff\@@layerysiz}{\@@layeryoff\layerparameter\c!voffset}% + % dx/dy are internal context ones and can be used in preset + \advance\@@layerxoff\dimexpr\layerparameter\c!offset+\layerparameter\c!dx\relax + \advance\@@layeryoff\dimexpr\layerparameter\c!offset+\layerparameter\c!dy\relax + \@@layerxpos\layerparameter\c!sx\@@layerxpos + \@@layerypos\layerparameter\c!sy\@@layerypos + \@@layerxoff\layerparameter\c!sx\@@layerxoff + \@@layeryoff\layerparameter\c!sy\@@layeryoff + \edef\@@currentlayerposition{\layerparameter\c!position}% + \ifx\@@currentlayerposition\v!yes % combine ^ + \setlastlayerpos{#2\currentlayer}% sets \layerpage; todo l/r %%%%%%%%%%%% + \@@layerxpos\lastlayerxpos + \@@layerypos\lastlayerypos + \letgvalue{\??ll\currentlayer\layerpage\c!position}\v!yes + \letgvalue{\??ll\currentlayer\c!state}\v!start % needed ? + \setbox\layerbox\vbox to \@@layerysiz{\hbox to \@@layerxsiz{\xypos{lyr:\the\currentlayerdata}\hss}\vss}% + \else + \setbox\layerbox\emptybox + \globallet\lastlayerxpos\!!zeropoint + \globallet\lastlayerypos\!!zeropoint + \normalexpanded{\noexpand\doifinset{\v!bottom}{\layerparameter\c!corner}}\dosetlayerbottompositions + \normalexpanded{\noexpand\doifinset{\v!right }{\layerparameter\c!corner}}\dosetlayerrightpositions + \normalexpanded{\noexpand\doifinset{\v!middle}{\layerparameter\c!corner}}\dosetlayermiddlepositions + \edef\layerpage{\layerparameter\c!page}% + \fi + \ifx\layerpage\empty \else % is expanded + \edef\layerpage{:\layerpage}% + \ifcsname\@@layerbox#2\currentlayer\layerpage\endcsname \else + \expandafter\newbox\csname\@@layerbox#2\currentlayer\layerpage\endcsname + \fi + \fi + \chardef\layerpagebox\csname\@@layerbox#2\currentlayer\layerpage\endcsname + \ifvoid\layerpagebox + \gsetboxllx\layerpagebox\zeropoint + \gsetboxlly\layerpagebox\zeropoint + \fi + \global\setbox\layerpagebox\vbox %to \layerparameter\c!height % new, otherwise no negative y possible + {\offinterlineskip + %postpone, to after nextboxwd correction % \hsize\layerparameter\c!width % new, keep box small + %\ifvoid\csname\@@layerbox\currentlayer\layerpage\endcsname\else % why not #2#1 + \ifvoid\layerpagebox + \let\lastlayerwidth \zeropoint + \let\lastlayerheight\zeropoint + \else + \edef\lastlayerwidth {\the\wd\layerpagebox}% + \edef\lastlayerheight{\the\ht\layerpagebox}% + \ht\layerpagebox\zeropoint + \dp\layerpagebox\zeropoint + \wd\layerpagebox\zeropoint + \doifnot{\layerparameter\c!direction}\v!reverse{\box\layerpagebox}% + \fi + % don't move + \xdef\lastlayerwd{\the\nextboxwd}% + \xdef\lastlayerht{\the\nextboxht}% % not entirely ok when grid ! + \xdef\lastlayerdp{\the\nextboxdp}% % not entirely ok when grid ! + % this code + \doifelse{\layerparameter\c!location}\v!grid\donetrue\donefalse + \ifdone + \nextboxht\strutheight + \nextboxdp\strutdepth + \else + \setbox\nextbox\hbox{\alignedbox[\layerparameter\c!location]\vbox{\flushnextbox}}% + \fi + \ifnum\layerparameter\c!line=\zerocount\else % no \ifcase, can be negative + \advance\@@layerypos\dimexpr\layerparameter\c!line\lineheight+\topskip-\lineheight-\nextboxht\relax + \fi + \ifnum\layerparameter\c!column=\zerocount\else % no \ifcase, can be negative + \advance\@@layerxpos\layoutcolumnoffset{\layerparameter\c!column}% + \fi + \ifdone + \setbox\nextbox\hbox{\alignedbox[rb]\vbox{\flushnextbox}}% + \fi + % ll registration + \scratchdimen\@@layerxpos + \advance\scratchdimen\@@layerxoff + \ifdim\scratchdimen<\getboxllx\layerpagebox + \gsetboxllx\layerpagebox\scratchdimen + \fi + \ifcase\@@lacome\or % this test will become obsolete + \advance\scratchdimen\nextboxwd + \nextboxwd\ifdim\scratchdimen>\lastlayerwidth \scratchdimen \else \lastlayerwidth \fi + \fi + \scratchdimen\dimexpr\@@layerypos+\@@layeryoff\relax + \ifdim\scratchdimen<\getboxlly\layerpagebox + \gsetboxlly\layerpagebox\scratchdimen + \fi + % ll compensation + \ifcase\@@lacome\or % this test will become obsolete + \advance\scratchdimen\dimexpr\nextboxht+\nextboxdp\relax + \nextboxht\ifdim\scratchdimen>\lastlayerheight \scratchdimen \else \lastlayerheight \fi + \nextboxdp\zeropoint + \fi + % placement + \hsize\layerparameter\c!width % new, keep box small + \vbox to \layerparameter\c!height \bgroup + \smashbox\nextbox + \vskip\dimexpr\@@layerypos+\@@layeryoff\relax + \hskip\dimexpr\@@layerxpos+\@@layerxoff\relax + \flushnextbox + \ifvoid\layerpagebox + % already flushed + \else + % the reverse case % check ! + \vskip-\dimexpr\@@layerypos+\@@layeryoff\relax + \box\layerpagebox + \fi + \egroup}% + % when position is true, the layerbox holds the compensation and needs + % to be placed; never change this ! + \ifvoid\layerbox\else\box\layerbox\fi} + +\def\dosetlayerbottompositions + {\ifnum\layerparameter\c!line=\zerocount\else % can be < 0 + \setevalue{\??ll\currentlayer\c!line}{\the\numexpr-\layerparameter\c!line+\layoutlines+\plusone\relax}% + \fi + \ifdim\@@layerysiz>\zeropoint + \advance\@@layerypos-\@@layerysiz + \@@layerypos-\@@layerypos + \@@layeryoff-\@@layeryoff + \fi} + +\def\dosetlayerrightpositions + {\ifnum\layerparameter\c!column=\zerocount\else % can be < 0 + \setevalue{\??ll\currentlayer\c!column}{\the\numexpr-\layerparameter\c!column+\layoutcolumns+\plusone\relax}% + \fi + \ifdim\@@layerxsiz>\zeropoint + \advance\@@layerxpos-\@@layerxsiz + \@@layerxpos-\@@layerxpos + \@@layerxoff-\@@layerxoff + \fi} + +\def\dosetlayermiddlepositions + {\ifdim\@@layerxsiz>\zeropoint \advance\@@layerxpos.5\@@layerxsiz \fi + \ifdim\@@layerysiz>\zeropoint \advance\@@layerypos.5\@@layerysiz \fi} + +%D Given the task to be accomplished, the previous macro is +%D not even that complicated. It mainly comes down to skipping +%D to the right place and placing a box on top of or below the +%D existing content. In the case of position tracking, another +%D reference point is chosen. + +%D \macros +%D {doifelselayerdata} + +\def\doifelselayerdata#1% + {\ifcsname\@@layerbox#1\endcsname + \ifvoid\csname\@@layerbox#1\endcsname + \@EAEAEA\secondoftwoarguments + \else + \@EAEAEA\firstoftwoarguments + \fi + \else + \@EA\secondoftwoarguments + \fi} + +%D \macros +%D {flushlayer} +%D +%D When we flush a layer, we flush both the main one and the +%D page dependent one (when defined). This feature is more +%D efficient in \ETEX\ since there testing for an undefined +%D macro does not takes hash space. + +% todo: setups before flush, handy hook + +% \unexpanded\def\flushlayer[#1]% +% {\doifelsevalue{\??ll#1\c!state}\v!next +% {\global\letvalue{\??ll#1\c!state}\v!start} % dangerous, stack-built-up +% {\doifelsevalue{\??ll#1\c!state}\v!continue +% {\global\letvalue{\??ll#1\c!state}\v!repeat} % dangerous, stack-built-up +% {\doifelsevalue{\??ll#1\c!doublesided}\v!yes +% {\doifundefinedelse{\@@layerbox#1}% +% {\dodoflushlayerA[#1]} +% {\doifbothsidesoverruled +% {\dodoflushlayerB\v!left [#1]}% left +% {\dodoflushlayerB\v!right[#1]}% right +% {\dodoflushlayerB\v!left [#1]}}}% left +% {\dodoflushlayerA[#1]}}}} + +\unexpanded\def\flushlayer[#1]% quite core, so optimized + {\begingroup + \forgetall + \edef\currentlayer{#1}% + \edef\@@currentlayerstate{\csname\??ll\currentlayer\c!state\endcsname}% + \ifx\@@currentlayerstate\v!stop + % nothing + \else\ifx\@@currentlayerstate\v!next + \global\expandafter\let\csname\??ll\currentlayer\c!state\endcsname\v!start % dangerous, stack-built-up + \else\ifx\@@currentlayerstate\v!continue + \global\expandafter\let\csname\??ll\currentlayer\c!state\endcsname\v!repeat % dangerous, stack-built-up + \else + \edef\@@currentlayerdoublesided{\csname\??ll\currentlayer\c!doublesided\endcsname}% + \ifx\@@currentlayerdoublesided\v!yes + \ifcsname\@@layerbox#1\endcsname + % we can make a dedicated one for this + \doifbothsidesoverruled{\dodoflushlayerB\v!left}{\dodoflushlayerB\v!right}{\dodoflushlayerB\v!left}% + \else + \dodoflushlayerA + \fi + \else + \dodoflushlayerA + \fi + \fi\fi\fi + \endgroup} + +% \ifcase#1\else\writestatus{layer}{unknown layer #3}\fi + +\def\dodoflushlayerA + {\startoverlay + {\ifcsname\@@layerbox\currentlayer \endcsname\dodoflushlayer\plusone \currentlayer \fi}% + {\ifcsname\@@layerbox\currentlayer:\realfolio\endcsname\dodoflushlayer\zerocount{\currentlayer:\realfolio}\fi}% + \stopoverlay} + +\def\dodoflushlayerB#1% + {\startoverlay + {\ifcsname\@@layerbox \currentlayer \endcsname\dodoflushlayer\plusone \currentlayer \fi}% + {\ifcsname\@@layerbox \currentlayer:\realfolio\endcsname\dodoflushlayer\zerocount {\currentlayer:\realfolio}\fi}% + {\ifcsname\@@layerbox#1\currentlayer \endcsname\dodoflushlayer\plusone {#1\currentlayer }\fi}% + {\ifcsname\@@layerbox#1\currentlayer:\realfolio\endcsname\dodoflushlayer\zerocount{#1\currentlayer:\realfolio}\fi}% + \stopoverlay} + +\def\dodoflushlayer#1#2% quite core, so optimized + {\begingroup % already grouped + \offinterlineskip + \edef\@@currentlayermethod{\csname\??ll\currentlayer\c!method\endcsname}% + \edef\@@currentlayeroption{\csname\??ll\currentlayer\c!option\endcsname}% + % needed because we need to handle method but we should find a way to + % speed this up + \edef\@@currentlayerpreset{\csname\??ll\currentlayer\c!preset\endcsname}% + \ifcsname\??ll\??ll\@@currentlayerpreset\endcsname\csname\??ll\??ll\@@currentlayerpreset\endcsname\currentlayer{}\fi + % + \ifx\@@currentlayeroption\v!test + \tracelayerstrue + \fi + \iftracelayers + \traceboxplacementtrue + \fi + \!!doneafalse + \!!donebfalse + \ifx\@@currentlayermethod\v!overlay\!!doneatrue\fi + \ifx\@@currentlayermethod\v!fit \!!donebtrue\fi + \!!donectrue + \ifcase#1\else + \edef\@@currentlayerposition{\csname\??ll\currentlayer\c!position\endcsname}% + \ifx\@@currentlayerposition\v!yes \else + \edef\@@currentlayerrepeat{\csname\??ll\currentlayer\c!repeat\endcsname}% + % \edef\@@currentlayerstate {\csname\??ll\currentlayer\c!state\endcsname}% actually this is already set + \ifx\@@currentlayerrepeat\v!yes + \!!donecfalse + \else\ifx\@@currentlayerstate\v!repeat + \!!donecfalse + \fi\fi + \fi + \fi + \chardef\layerbox\csname\@@layerbox#2\endcsname % \@@layerbox\currentlayer + % we need to copy in order to retain the negative offsets for a next + % stage of additions, i.e. llx/lly accumulate in repeat mode and the + % compensation may differ each flush depending on added content + \setbox\nextbox + \if!!doneb + \therepositionededlayerbox + \else + \if!!donec\box\else\copy\fi\layerbox % sorry for the delay due to copying + \fi + % todo: method=offset => overlayoffset right/down (handy for backgrounds with offset) + \doifoverlayelse{#2}{\setlayoutcomponentattribute\v!layer{#2}}\resetlayoutcomponentattribute + \iftracelayers \ruledvbox \else \vbox \fi \if!!donea to \overlayheight \fi \layoutcomponentboxattribute + {\hbox \if!!donea to \overlaywidth \fi + {\edef\@@currentlayerpageposition{\csname\??ll#2\realfolio\c!position\endcsname}% + \ifx\@@currentlayerpageposition\v!yes\xypos{lyr:#2:\realfolio}\fi + \box\nextbox + \hss}% + \vss}% + \if!!donec + \gsetboxllx\layerbox\zeropoint + \gsetboxlly\layerbox\zeropoint + \fi + \endgroup} + +\def\therepositionededlayerbox % assumes that \if!!donec is set (todo: use dedicated flags) + {\vbox + {\vskip-\getboxlly\layerbox + \hskip-\getboxllx\layerbox + \hsize-\dimexpr\getboxllx\layerbox-\wd\layerbox\relax + \if!!donec\box\else\copy\fi\layerbox}} + +% \definelayer[test][method=fit] \setupcolors[state=start] \tracelayerstrue +% +% \framed[framecolor=red,offset=overlay]{\setlayer[test]{aa}\setlayer[test][x=10pt]{g}\flushlayer[test]} +% \framed[framecolor=red,offset=overlay]{\setlayer[test]{aa}\setlayer[test][x=-10pt]{bb}\flushlayer[test]} +% \framed[framecolor=red,offset=overlay]{\setlayer[test][x=-20pt]{cccccc}\flushlayer[test]} +% \framed[framecolor=red,offset=overlay]{\setlayer[test]{dd}\setlayer[test][x=-20pt,y=-3pt]{eeeeee}\flushlayer[test]} + +%D \macros +%D {composedlayer,placelayer,tightlayer} +%D +%D This is a handy shortcut, which saves a couple of braces +%D when we use it as parameter. This name also suits better +%D to other layering commands. + +\def\composedlayer#1{\flushlayer[#1]} + +\let\placelayer\flushlayer + +\def\tightlayer[#1]% + {\hbox + {\def\currentlayer{#1}% todo: left/right + \setbox\nextbox\emptybox % hoogte/breedte are \wd\nextbox/\ht\nextbox + \hsize\layerparameter\c!width % \overlaywidth = \hsize + \vsize\layerparameter\c!height % \overlaywheight = \vsize + \composedlayer{#1}}} + +%D \macros +%D {resetlayer} +%D +%D This macro hardly needs an explanation (and is seldom +%D needed as well). + +\def\doresetlayer#1% + {\ifcsname\@@layerbox#1\endcsname + \global\setbox\csname\@@layerbox#1\endcsname\emptybox + \fi} + +\def\resetlayer[#1]% + {\doresetlayer{#1}% + \doifvalue{\??ll#1\c!doublesided}\v!yes % kind of redundant test + {\doresetlayer{\v!left #1}% + \doresetlayer{\v!right#1}}% + \doresetlayer{#1:\realfolio}} + +%D \macros +%D {setMPlayer} +%D +%D The following layer macro uses the positions that are +%D registered by \METAPOST. +%D +%D \starttyping +%D \definelayer[test] +%D +%D \setMPlayer [test] [somepos-1] {Whatever we want here!} +%D \setMPlayer [test] [somepos-2] {Whatever we need there!} +%D \setMPlayer [test] [somepos-3] {\externalfigure[cow.mps][width=2cm]} +%D +%D \startuseMPgraphic{oeps} +%D draw fullcircle scaled 10cm withcolor red ; +%D register ("somepos-1",2cm,3cm,center currentpicture) ; +%D register ("somepos-2",8cm,5cm,(-1cm,-2cm)) ; +%D register ("somepos-3",0cm,0cm,(-2cm,2cm)) ; +%D \stopuseMPgraphic +%D +%D \getMPlayer[test]{\useMPgraphic{oeps}} +%D \stoptyping +%D +%D The last line is equivalent to +%D +%D \starttyping +%D \framed +%D [background={foreground,test},offset=overlay] +%D {\useMPgraphic{oeps}} +%D \stoptyping + +\def\setMPlayer + {\dotripleempty\dosetMPlayer} + +\def\MPlayerwidth {\hsize} +\def\MPlayerheight{\vsize} + +\def\dosetMPlayer[#1][#2][#3]% + {\edef\MPlayerwidth {\MPw{#2}}% + \edef\MPlayerheight{\MPh{#2}}% + \setlayer[#1][\c!x=\MPx{#2},\c!y=\MPy{#2},\c!position=\v!no,#3]} + +\def\getMPlayer + {\dodoubleempty\dogetMPlayer} + +\def\dogetMPlayer[#1][#2]% + {\framed + [\c!background={\v!foreground,#1}, + \c!frame=\v!off, + \c!offset=\v!overlay,#2]} + +% The next mechanism is obsolete and will be removed in \MKIV\ (or move to +% the compatibility module. + +\newskip\xposition \newskip\yposition +\newskip\xdimension \newskip\ydimension +\newskip\xoffset \newskip\yoffset + +% already defined \newbox\positionbox + +\unexpanded\def\startpositioning + {\bgroup + \xposition \zeropoint \yposition \zeropoint + \xdimension\zeropoint \ydimension\zeropoint + \xoffset \zeropoint \yoffset \zeropoint + \hfuzz \paperwidth \vfuzz \paperheight + \setbox\positionbox\hbox\bgroup} + +\unexpanded\def\stoppositioning + {\doifnot\@@psoffset\v!yes + {\global\xoffset\zeropoint + \global\yoffset\zeropoint}% + \global\advance\xdimension \xoffset + \global\advance\ydimension \yoffset + \egroup + \vbox to \ydimension + {\vskip\yoffset + \hbox to \xdimension + {\hskip\xoffset + \box\positionbox + \hfill} + \vfill}% + \egroup} + +\def\resetpositioning + {\getparameters[\??ps] + [\c!state=\v!start,% + \c!unit=\s!cm,% + \c!factor=1,% + \c!scale=1,% + \c!xfactor=\@@psfactor,% + \c!yfactor=\@@psfactor,% + \c!xscale=\@@psscale,% + \c!yscale=\@@psscale,% + \c!xstep=\v!absolute,% + \c!ystep=\v!absolute,% + \c!xoffset=\!!zeropoint,% + \c!yoffset=\!!zeropoint]} + +\unexpanded\def\setuppositioning + {\resetpositioning + \dodoubleargument\getparameters[\??ps]} + +\def\calculateposition#1#2#3#4#5#6#7#8#9% + {\setdimensionwithunit\scratchskip{#1}\@@psunit + \scratchskip#8\scratchskip + \scratchskip#9\scratchskip + \advance\scratchskip #4\relax + \doif{#2}\v!relative + {\advance\scratchskip #3% + \let#4\!!zeropoint}% + #3\scratchskip\relax + \doifnot\@@psstate\v!overlay + {\scratchskip#5\relax + \advance\scratchskip #3\relax + \ifdim#3<-#7\relax \global#7-#3\relax \fi + \ifdim\scratchskip>#6\relax \global#6\scratchskip\relax \fi}} + +\def\position + {\dosingleempty\doposition} + +\def\doposition[#1]#2(#3,#4)% + {\dowithnextbox + {\bgroup + \getparameters[\??ps][#1]% + \dontcomplain + \calculateposition{#3}\@@psxstep\xposition + \@@psxoffset{\nextboxwd}\xdimension\xoffset + \@@psxscale\@@psxfactor + \scratchdimen\nextboxht \advance\scratchdimen \nextboxdp + \calculateposition{#4}\@@psystep\yposition + \@@psyoffset\scratchdimen\ydimension\yoffset + \@@psyscale\@@psyfactor + \vbox to \zeropoint % kan beter. + {\vskip\yposition + \hbox to \zeropoint + {\hskip\xposition + \flushnextbox + \hss} + \vss}% + \xdef\dopoppositioning + {\xposition\the\xposition + \yposition\the\yposition + \noexpand\def\noexpand\@@psxoffset{\@@psxoffset}% + \noexpand\def\noexpand\@@psyoffset{\@@psyoffset}}% + \egroup + \dopoppositioning + \ignorespaces} + \hbox} + +\resetpositioning + +\setuppositioning + [\c!unit=\s!cm, + \c!factor=1, + \c!scale=1, + \c!xstep=\v!absolute, + \c!ystep=\v!absolute, + \c!offset=\v!yes, + \c!xoffset=\!!zeropoint, + \c!yoffset=\!!zeropoint] + +%D Watch out, a redefinition: + +\ifx\settextpagecontent\undefined \writestatus\m!systems{error in page-lyr.tex} \wait \fi + +\let\normalsettextpagecontent\settextpagecontent + +\definelayer + [OTRTEXT] + +\setuplayer + [OTRTEXT] + [\c!width=\innermakeupwidth, + \c!height=\textheight] + +% will be overloaded in page-spr + +\def\settextpagecontent#1#2#3% #2 and #3 will disappear + {\doifelselayerdata{OTRTEXT} + {\setbox#1\hbox to \makeupwidth + {\startoverlay + {\tightlayer[OTRTEXT]} % first, otherwise problems with toc + {\normalsettextpagecontent{#1}{#2}{#3}\box#1} + \stopoverlay}% + \dp#1\zeropoint}% + {\normalsettextpagecontent{#1}{#2}{#3}}} + +\protect \endinput diff --git a/tex/context/base/pack-obj.lua b/tex/context/base/pack-obj.lua new file mode 100644 index 000000000..0ee46fc99 --- /dev/null +++ b/tex/context/base/pack-obj.lua @@ -0,0 +1,54 @@ +if not modules then modules = { } end modules ['pack-obj'] = { + version = 1.001, + comment = "companion to pack-obj.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--[[ldx-- +

We save object references in the main utility table. jobobjects are +reusable components.

+--ldx]]-- + +local texsprint, texcount = tex.sprint, tex.count + +jobobjects = jobobjects or { } +jobobjects.collected = jobobjects.collected or { } +jobobjects.tobesaved = jobobjects.tobesaved or { } + +local collected, tobesaved = jobobjects.collected, jobobjects.tobesaved + +local function initializer() + collected, tobesaved = jobobjects.collected, jobobjects.tobesaved +end + +job.register('jobobjects.collected', jobobjects.tobesaved, initializer, nil) + +function jobobjects.save(tag,number,page) + local t = { number, page } + tobesaved[tag], collected[tag] = t, t +end + +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) +end + +function jobobjects.page(tag,default) + local o = collected[tag] or tobesaved[tag] + texsprint((o and o[2]) or default) +end + +function jobobjects.doifelse(tag) + commands.testcase(collected[tag] or tobesaved[tag]) +end + diff --git a/tex/context/base/pack-obj.mkii b/tex/context/base/pack-obj.mkii new file mode 100644 index 000000000..6971ad04f --- /dev/null +++ b/tex/context/base/pack-obj.mkii @@ -0,0 +1,371 @@ +%D \module +%D [ file=pack-obj, +%D version=1998.01.15, +%D title=\CONTEXT\ Packaging Macros, +%D subtitle=Objects, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 Packaging Macros / Objects} + +\unprotect + +%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 + \doutilities{objectreferences}\jobname\empty\relax\relax + \else + % different format (will fails on \purenumber) + \fi + \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}% + \setxvalue{\r!driver##1::##2}{{##3}{##4}}% + \else + \showmessage\m!references{31}{[##1 ##2=>##3/##4]}% + \fi}} + +\def\resetobjectreferences + {\let\objectreference\gobblefourarguments} + +\resetobjectreferences + +\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\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 + \ifundefined{\r!driver#3::#4}% + \showmessage\m!references{30}{[#3 #4=>#3/#4]}% + \xdef#5{#2{#3}{#4}}% + \else + \xdef#5{\@EAEAEA#1\csname\r!driver#3::#4\endcsname}% + \fi + \elabelgroup} + +\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#1#2% + {\checkobjectreferences + \blabelgroup \ifcsname\r!driver#1::#2\endcsname + \elabelgroup \expandafter\firstoftwoarguments + \else + \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/pack-obj.mkiv b/tex/context/base/pack-obj.mkiv new file mode 100644 index 000000000..81220e324 --- /dev/null +++ b/tex/context/base/pack-obj.mkiv @@ -0,0 +1,399 @@ +%D \module +%D [ file=pack-obj, +%D version=1998.01.15, +%D title=\CONTEXT\ Packaging Macros, +%D subtitle=Objects, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 Packaging Macros / Objects} + +\unprotect + +\let\objectreference\gobblefourarguments % catch mkii tuo stuff + +\registerctxluafile{pack-obj}{1.001} + +% \startluacode +% local texbox, texdimen, texcount, texwrite = tex.box, tex.dimen, tex.count, tex.write +% local pdfxform, pdfrefxform = pdf.xform, pdf.refxform +% +% function pdf.xform (l) texbox["objectbox"] = nil return l end +% function pdf.refxform(l) return node.copy_list(l) end +% +% backends.codeinjections.register = pdf.xform +% backends.codeinjections.restore = pdf.refxform +% +% local codeinjections = backends.codeinjections +% +% objects = objects or { } +% +% local data = { } +% +% objects.data = data +% objects.n = 0 +% +% function objects.register(name) +% objects.n = objects.n + 1 +% local list = texbox.objectbox +% nodes.process_page(list) +% data[name] = { +% codeinjections.restore(list), +% texdimen.objectwd, +% texdimen.objectht, +% texdimen.objectdp, +% texdimen.objectoff, +% } +% end +% +% function objects.restore(name) +% local d = data[name] +% if d then +% texbox .objectbox = codeinjections.restore(d[1]) +% texdimen.objectwd = d[2] +% texdimen.objectht = d[3] +% texdimen.objectdp = d[4] +% texdimen.objectoff = d[5] +% else +% texbox .objectbox = nil +% texdimen.objectwd = 0 +% texdimen.objectht = 0 +% texdimen.objectdp = 0 +% texdimen.objectoff = 0 +% end +% end +% +% function objects.reference(name) +% local d = data[name] +% texwrite((d and d[1]) or 0) +% end +% +% function objects.enhance(name) +% local d = data[name] +% if d then +% d[6] = texcount.realpageno +% end +% end +% +% function objects.page(name) +% local d = data[name] +% texwrite((d and d[6]) or texcount.realpageno) +% end +% +% function objects.doifelse(name) +% commands.testcase(data[name]) +% end +% \stopluacode +% +% \newbox \objectbox +% \newtoks \everyobject +% \newif \ifinobject +% +% \newdimen\objectoff \def\objectmargin{\the\objectoff} +% \newdimen\objectwd \def\objectwidth {\the\objectwd } +% \newdimen\objectht \def\objectheight{\the\objectht } +% \newdimen\objectdp \def\objectdepth {\the\objectdp } +% +% \def\objectoffset{1cm} +% +% \everyobject{\the\everyPDFxform} +% +% \let\doresetobjects\relax +% +% \def\setobject #1#2{\begingroup\objectoff\objectoffset\inobjecttrue\the\everyobject\dowithnextbox{\dosetobject{#1}{#2}}} +% \def\settightobject#1#2{\begingroup\objectoff\zeropoint \inobjecttrue\the\everyobject\dowithnextbox{\dosetobject{#1}{#2}}} +% +% \let\objectsetvbox\vbox %\def\objectsetvbox{\ruledvbox} +% \let\objectgetvbox\vbox %\def\objectgetvbox{\ruledvbox} +% \let\objectsethbox\hbox %\def\objectsethbox{\ruledhbox} +% \let\objectgethbox\hbox %\def\objectgethbox{\ruledhbox} +% +% \def\dosetobject#1#2% +% {\objectwd\wd\nextbox +% \objectht\ht\nextbox +% \objectdp\dp\nextbox +% \ifdim\objectoff=\zeropoint\relax +% \setbox\objectbox\box\nextbox +% \else +% \setbox\objectbox\objectsetvbox spread 2\objectoff{\vss\objectsethbox spread 2\objectoff{\hss\flushnextbox\hss}\vss}% +% \fi +% \ctxlua{objects.register("#1::#2")}% +% \endgroup} +% +% \def\getobject#1#2% +% {\begingroup +% \ctxlua{objects.restore("#1::#2")}% +% \ifdim\objectoff=\zeropoint\relax \else +% \setbox\objectbox\objectgetvbox to \dimexpr\objectht+\objectdp\relax +% {\vss\objectgethbox to \objectwd{\hss\box\objectbox\hss}\vss}% +% \wd\objectbox\objectwd +% \ht\objectbox\objectht +% \dp\objectbox\objectdp +% \fi +% \box\objectbox +% \endgroup} +% +% \def\getpageobject#1#2% +% {\begingroup +% \ctxlua{objects.restore("#1::#2")}% +% \ifdim\objectoff=\zeropoint\relax +% \setbox\objectbox\objectgethbox{\ctxlatelua{objects.enhance("#1::#2")}\box\objectbox} +% \else +% \setbox\objectbox\objectgetvbox to \dimexpr\objectht+\objectdp\relax +% {\vss\objectgethbox to \objectwd{\ctxlatelua{objects.enhance("#1::#2")}\hss\box\objectbox\hss}\vss}% +% \wd\objectbox\objectwd +% \ht\objectbox\objectht +% \dp\objectbox\objectdp +% \fi +% \box\objectbox +% \endgroup} +% +% \def\setobjectdirectly #1#2{\ctxlua{objects.register("#1::#2")}} +% \def\getobjectdirectly #1#2{\ctxlua{objects.restore ("#1::#2")}} +% \def\getobjectdimensions #1#2{\ctxlua{objects.restore ("#1::#2")}} +% \def\doifobjectfoundelse #1#2{\ctxlua{objects.doifelse("#1::#2")}} +% \def\doifobjectreferencefoundelse#1#2{\ctxlua{objects.doifelse("#1::#2")}} +% +% \let\objectreferenced\relax +% \let\driverreferenced\relax +% +% \def\doregisterobjectreference{\writestatus{objects}{obsolete: register object reference}\gobblethreearguments} +% \def\dooverloadobjectreference{\writestatus{objects}{obsolete: overload object reference}\gobblethreearguments} +% \def\dosetobjectreference {\writestatus{objects}{obsolete: set object reference}\gobblethreearguments} +% \def\dosetdriverreference {\writestatus{objects}{obsolete: set driver reference}\gobblethreearguments} +% +% \def\defaultobjectreference{0} +% \def\defaultobjectpage {\realfolio} +% +% \def\dogetobjectreference #1#2#3{\xdef#3{\ctxlua{objects.reference("#1::#2)}}} +% \def\dogetobjectreferencepage#1#2#3{\xdef#3{\ctxlua{objects.page("#1::#2))}}} +% +% \protect +% +% \starttext +% test \setobject{a}{b}\ruledhbox{xxx}\getobject{a}{b} test +% \vskip3cm +% test \settightobject{a}{b}\ruledhbox{xxx}\getobject{a}{b} test +% test \settightobject{a}{c}\ruledhbox{xxx}\getobject{a}{c} test +% \dorecurse{5000}{test \setobject{a}{b}\ruledhbox{xxx}\getobject{a}{b} test } +% \stoptext + +%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 attr \viewerlayerattribute \attribute\viewerlayerattribute + {\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}}% +% \forcecolorhack % needed in order to use layers etc + \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 + \csname\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/pack-rul.lua b/tex/context/base/pack-rul.lua new file mode 100644 index 000000000..378167c97 --- /dev/null +++ b/tex/context/base/pack-rul.lua @@ -0,0 +1,53 @@ +if not modules then modules = { } end modules ['pack-rul'] = { + version = 1.001, + comment = "companion to pack-rul.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--[[ldx-- +

An explanation is given in the history document mk.

+--ldx]]-- + +local texdimen, texcount, texbox = tex.dimen, tex.count, tex.box +local hpack, free, copy, traverse_id = node.hpack, node.free, node.copy_list, node.traverse_id + +function commands.doreshapeframedbox(n) + local noflines, lastlinelength, box = 0, 0, texbox[n] + if box.width ~= 0 then + local list = box.list + if list then + local width, done = 0, false + for h in traverse_id('hlist',list) do -- no dir etc needed + local l = h.list + if l then + done = true + local p = hpack(copy(l)) + lastlinelength = p.width + if lastlinelength > width then + width = lastlinelength + end + free(p) + end + end + if done then + if width ~= 0 then + for h in traverse_id('hlist',list) do + local l = h.list + if l then + -- if h.width ~= width then -- else no display math handling (uses shift) + h.list = hpack(l,width,'exactly',h.dir) + h.shift = 0 -- needed for display math + h.width = width + -- end + end + end + end + box.width = width + end + end + end + texdimen["framedlastlength"] = lastlinelength + texcount["framednoflines"] = noflines +end diff --git a/tex/context/base/pack-rul.mkii b/tex/context/base/pack-rul.mkii new file mode 100644 index 000000000..055094547 --- /dev/null +++ b/tex/context/base/pack-rul.mkii @@ -0,0 +1,3650 @@ +%D \module +%D [ file=pack-rul, % was core-rul, +%D version=1998.10.16, +%D title=\CONTEXT\ Packaging Macros, +%D subtitle=Ruled Content, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 Packaging Macros / Ruled Content} + +\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} + +\let\framedboxwidth \!!zeropoint +\let\framedboxheight\!!zeropoint +\let\framedboxdepth \!!zeropoint + +\def\doreshapeframedbox % frozen, that is ... \shapeboxstrut added + {\ifvbox\framebox + \beginofshapebox + \unvcopy\framebox + \endofshapebox + \global\@@globalwidth\zeropoint + \edef\framedboxwidth {\the\wd\framebox}% + \edef\framedboxheight{\the\ht\framebox}% + \edef\framedboxdepth {\the\dp\framebox}% + \resetshapeframebox + \reshapebox + {\setbox0\hbox + {\strut\ifhbox\shapebox\shapeboxstrut\unhbox\else\box\fi\shapebox}% + \global\advance\framednoflines \plusone + \ifdim\framedlastlength>\zeropoint\else + \global\framedlastlength\wd0 + \fi + \ifdim\wd0>\@@globalwidth + \global\@@globalwidth\wd0 + \fi}% + \ifreshapingfailed + % no need for anothr pass or finalizer + \else + \dosetraggedcommand\localformat + \raggedcommand + \ifboxhasheight + \setbox\framebox\vbox to \localheight + {\hsize\@@globalwidth + \reshapebox{\hbox to \hsize{\ifhbox\shapebox\shapeboxstrut\unhbox\else\box\fi\shapebox}}% + \dobeforeframedbox + \innerflushshapebox + \doafterframedbox}% + \else + \setbox\framebox\vbox to \framedboxheight % \ht\framebox + {\hsize\@@globalwidth + \reshapebox{\hbox to \hsize{\ifhbox\shapebox\shapeboxstrut\unhbox\else\box\fi\shapebox}}% + \ifcase\reshapeframeboxmethod + \or \innerflushshapebox \or \innerflushshapebox + \fi}% + \ifcase\reshapeframeboxmethod \or + \dp\framebox\framedboxdepth % \strutdp otherwise problem with math + \fi + \fi + \ifdim\framedlastlength=\zeropoint\global\framedlastlength\wd\framebox\fi + \ifcase\framednoflines\global\framednoflines\plusone\fi + \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\checkframedtext % messy dependency + {\ifinsidefloat + \localhsize\hsize + \else\ifdim\sidefloatvsize>\zeropoint % will be proper handle + % \strut % rather clean way to invoke the sidefloat OTR + % \setbox0=\lastbox % and get the widths set, so from now on we + % \setlocalhsize % can have framed texts alongside sidefloats + \checksidefloat + \setlocalhsize + \else + \localhsize\hsize + \fi\fi} + +\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/pack-rul.mkiv b/tex/context/base/pack-rul.mkiv new file mode 100644 index 000000000..afacc2901 --- /dev/null +++ b/tex/context/base/pack-rul.mkiv @@ -0,0 +1,3686 @@ +%D \module +%D [ file=pack-rul, % was core-rul, +%D version=1998.10.16, +%D title=\CONTEXT\ Packaging Macros, +%D subtitle=Ruled Content, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 Packaging Macros / Ruled Content} + +%D redo framedtexts like framedcontent (parameter stuff) + +%D After a few months testing this solution is now added +%D to the core. This introduces a possible incompatibility +%D between \MKII\ and \MKIV\ but for the better. + +\registerctxluafile{pack-rul}{1.001} + +% old off new +% 4 lines oeps : 3.6 2.8 3.0 +% tufte 7.5 4.1 4.3 + +\unprotect + +%D We have removed the rather old and out dated raster methods. They +%D have not been used for ages. You can still find the old code in +%D the \MKII\ counterpart of this module. + +%D This module is rather optimized so sometimes readability has been +%D sacrisfied for speed. This is because the framing mechanism is used +%D all over the place. + +%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}} + +\unexpanded\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 \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} + +\unexpanded\def\setupscreens + {\dodoubleargument\getparameters[\??rs]} + +%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 + \edef\@@framedfilledmod{\framedparameter\c!backgroundcorner}% + \ifx\@@framedfilledmod\v!rectangular + \dofilledlinedbox + \else\ifzeropt\dimexpr\framedparameter\c!backgroundradius\relax % just in case of .x\bodyfontsize + \dofilledlinedbox + \else + \dofilledroundbox + \fi\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}% + \ifx\ovalmod\v!round + \let\ovalmod\!!zerocount + \else + \edef\ovalmod{\number\ovalmod}% + \fi + \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}% + \ifx\ovalmod\v!round + \let\ovalmod\!!zerocount + \else + \edef\ovalmod{\number\ovalmod}% + \fi + \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\dobackgroundcolorbox + {\hbox{\faststartcolor[\framedbackgroundcolor]\dofilledbox\faststopcolor}} + %{\hbox{\doactivatecolor\framedbackgroundcolor\dofilledbox}} + +\def\docolorbox % can be more of \color[] -> \faststartcolor in mkiv + {\ifincolor + \edef\framedbackgroundcolor{\framedparameter\c!backgroundcolor}% + \ifx\framedbackgroundcolor\empty + \dophantombox + \else + \doifcolorelse\framedbackgroundcolor\dobackgroundcolorbox\dophantombox + \fi + \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 + +\unexpanded\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 + \setlayoutcomponentattribute\v!overlay{#1}% + \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 \layoutcomponentboxattribute + {\hskip-.5\dimexpr\wd\scratchbox-\overlaywidth \relax + \raise-.5\dimexpr\ht\scratchbox-\frameddimenht\relax % not overlayheight ! + \box\scratchbox}% + \wd\scratchbox\frameddimenwd + \ht\scratchbox\frameddimenht + \dp\scratchbox\frameddimendp + \box\scratchbox + \egroup} + +%D The empty case is: + +\let\executeoverlay\gobblesevenarguments + +%D For testing we provide: + +\def\doifoverlayelse#1% + {\ifcsname\??ov#1\endcsname + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +%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 + {\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 % use $ instead of s!unknown + \dodobackgroundbox\expandafter\dododobackgroundbox + \fi#2} + +\let\backgroundoffset\!!zeropoint +\let\backgrounddepth \!!zeropoint +\def\backgroundwidth {\the\hsize} +\def\backgroundheight{\the\vsize} + +\def\normalforegroundbox% fuzzy but needed hack, this \vss, otherwise + {\vbox to \backgroundheight{\vss\box\framebox\vss}}% vertical shift + +\def\dobackedbox + {\setbox\framebox\vbox + {\framedforgetall + \boxmaxdepth\maxdimen + \frameddimenwd\dimexpr\wd\framebox+2\!!framedbackgroundoffset\relax + \frameddimenht\dimexpr\ht\framebox+ \!!framedbackgroundoffset\relax + \frameddimendp\dimexpr\dp\framebox+ \!!framedbackgroundoffset+\framedparameter\c!backgrounddepth\relax + \edef\backgroundoffset{\the\!!framedbackgroundoffset}% + \edef\backgroundwidth {\the\wd\framebox}% + \edef\backgroundheight{\the\ht\framebox}% + \edef\backgrounddepth {\the\dp\framebox}% + %\edef\foregroundbox{\box#1}% + \edef\component{\framedparameter\c!component}% + \ifx\component\empty + \resetlayoutcomponentattribute + \else + \setlayoutcomponentattribute\v!background\component + \fi + \let\foregroundbox\normalforegroundbox + \hbox \layoutcomponentboxattribute to \backgroundwidth % width in case 'foreground' is used as overlay + {\expandafter\dododobackgroundbox\framedbackground,\s!unknown,\relax % hm, messy .. look into it + \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. + +\def\dooutlinebox % we needed to move the color command in order to apply attributes properly + {\setbox\framebox\vbox % rules on top of box + {\frameddimenwd\dimexpr\wd\framebox+2\!!framedframeoffset\relax + \frameddimenht\dimexpr\ht\framebox+ \!!framedframeoffset\relax + \frameddimendp\dimexpr\dp\framebox+ \!!framedframeoffset+\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\!!framedframeoffset + \box\extraframebox}}% + \wd\extraframebox\wd\framebox + \ht\extraframebox\ht\framebox + \dp\extraframebox\dp\framebox + \hbox{\box\framebox\hskip-\wd\extraframebox\box\extraframebox}}} + +\def\dostrokedbox + {\edef\@@framedcornermod{\framedparameter\c!framecorner}% + \ifx\@@framedcornermod\v!rectangular + \dostrokedlinedbox + \else\ifzeropt\dimexpr\framedparameter\c!frameradius\relax % just in case of .x\bodyfontsize + \dostrokedlinedbox + \else + \dostrokedroundbox + \fi\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}} + +\let\setuplocalframed\getparameters % obsolete + +\presetlocalframed[\??ol] + +\newcount\framednesting + +\unexpanded\def\framed + {\bgroup + \advance\framednesting\plusone + \expandafter\let\csname\??ol:\the\framednesting\s!parent\endcsname\??ol + \dodoubleempty\startlocalframed[\??ol:\the\framednesting]} + +\unexpanded\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}% + \setbox\framebox\hbox{#4}% + \getparameters[\@@framed][#3]% no \expanded ! + \!!framedframeoffset\framedparameter\c!frameoffset + \edef\@@framedbackgroundoffset{\framedparameter\c!backgroundoffset}% + \ifx\@@framedbackgroundoffset\v!frame + \!!framedbackgroundoffset\!!framedframeoffset + \else + \!!framedbackgroundoffset\@@framedbackgroundoffset + \fi + % 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 Here is another fast one: + +\def\localbackgroundframed#1#2#3#4% tag box wd ht + {\setbox#2\vbox\bgroup + \inframedtrue + \edef\@@framed{\??ma#1}% + \expandafter\def\csname\??ma#1\c!component\endcsname{#1}% + \expandafter\def\csname\??ma#1\c!width \endcsname{#3}% + \expandafter\def\csname\??ma#1\c!height \endcsname{#4}% + \!!framedframeoffset\framedparameter\c!frameoffset + \edef\@@framedbackgroundoffset{\framedparameter\c!backgroundoffset}% + \ifx\@@framedbackgroundoffset\v!frame + \!!framedbackgroundoffset\!!framedframeoffset + \else + \!!framedbackgroundoffset\@@framedbackgroundoffset + \fi + \setbox\framebox\box#2% + \dp\framebox\zeropoint +% \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. + +% \def\s!root{root} % maybe configurable + +\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\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\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\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\frameddimension#1{\the\dimexpr\framedparameter{#1}\relax} + +\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 +\newdimen\!!framedframeoffset +\newdimen\!!framedbackgroundoffset + +\let\setextraframedoffsets \relax +\let\applyextraframedoffsets\relax + +% todo: protect local \framednames + +\unexpanded\def\startlocalframed[#1][#2]% + {\bgroup + \inframedtrue + \edef\@@framed{#1}% + \ifsecondargument % faster + \getparameters[\@@framed][#2]% here ! + \fi + \!!framedframeoffset\framedparameter\c!frameoffset + \edef\@@framedbackgroundoffset{\framedparameter\c!backgroundoffset}% + \ifx\@@framedbackgroundoffset\v!frame + \!!framedbackgroundoffset\!!framedframeoffset + \else + \!!framedbackgroundoffset\@@framedbackgroundoffset + \fi + % new, experimental dirty hook + \framedparameter\c!extras + % to get the right spacing + \edef\fontattributehash{\framedparameterhash\c!foregroundstyle}% + \ifx\fontattributehash\empty\else\dosetfontattribute\fontattributehash\c!foregroundstyle\fi + % 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 + \expandafter\let\csname\@@framed\c!offset\endcsname\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 + \edef\@@framedlines{\framedparameter\c!lines}% + \ifx\@@framedlines\empty\else + \ifcase\@@framedlines\else + \!!framedheight\@@framedlines\lineheight + \edef\localheight{\the\!!framedheight}% + \boxhasheighttrue + \fi + \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\framedbackground{\framedparameter\c!background}% + \ifx\framedbackground\empty + \let\framedforgetall\forgetall + \else + \let\framedforgetall\relax + \forgetall + \fi + \edef\framedwidth {\ifdim\!!framedwidth >\zeropoint\the\!!framedwidth \else\!!zeropoint\fi}% a new feature, visible for user + \edef\framedheight{\ifdim\!!framedheight>\zeropoint\the\!!framedheight\else\!!zeropoint\fi}% a new feature, visible for user + \edef\framedoffset{\the\dimexpr\ifboxhasoffset\localoffset\else\zeropoint\fi}% + \@@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 + +\unexpanded\def\stoplocalframed + {\dontshowcomposition + \@@stopframedorientation % hm, wrong place ! should rotate the result (after reshape) + \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\dosetfakedframebox + \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 + \ifx\framedbackground\empty\else\dobackedbox\fi + \handleframedlocator\c!after\@@locallocation + \box\framebox + \egroup + \egroup} + +\def\dosetfakedframebox + {\setbox\scratchbox\null + \wd\scratchbox\wd\framebox + \ht\scratchbox\ht\framebox + \dp\scratchbox\dp\framebox + \setbox\framebox\box\scratchbox} + +% test: (saves one forgetall) +% +% \edef\framedbackground{\framedparameter\c!background}% +% \ifx\framedbackground\empty +% \let\framedforgetall\forgetall +% \else +% \let\framedforgetall\relax +% \forgetall +% \fi + +\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% + {\csname\??oi:\c!location:#1:#2\endcsname} + +\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]{\Ustartmath\triggermathstyle\mframedstyle#2\Ustopmath}% + \endgroup} + +\def\funnymathstrut{\Ustartmath\triggermathstyle\mframedstyle\vphantom{(}\Ustopmath} + +\def\dodisplaymframed[#1]#2% + {\begingroup + \mframedstyle\mathstyle\relax + \let\normalstrut\funnymathstrut + \framed[#1]{\Ustartmath\triggermathstyle\mframedstyle#2\Ustopmath}% + \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 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\framedforgetall{\forgetall} + +\def\setframedforegroundcolor + {\edef\colorattributehash{\framedparameterhash\c!foregroundcolor}% + \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash\c!foregroundcolor\fi} + +\def\doformatboxSomeFormat + {\vbox to \!!framedheight + \bgroup + \let\postprocessframebox\relax + \framedforgetall + \setframedforegroundcolor + \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 + \framedforgetall + \setframedforegroundcolor + \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 + \framedforgetall + \setframedforegroundcolor + \oninterlineskip + \doframedsetups + \raggedcommand + \vss + \bgroup + \aftergroup\localendstrut + \aftergroup\vss + \aftergroup\egroup + \localbegstrut + \doformatonelinerbox} + +\def\doformatboxWidth + {\vbox + \bgroup + \let\postprocessframebox\relax + \framedforgetall + \setframedforegroundcolor + \oninterlineskip + \hsize\!!framedwidth + \doframedsetups + \raggedcommand + \dobeforeframedbox + \bgroup + \localbegstrut + \aftergroup\localendstrut + \aftergroup\doafterframedbox + \aftergroup\egroup + \doformatonelinerbox} + +\def\doformatboxVSize + {\vbox to \!!framedheight + \bgroup + \let\postprocessframebox\relax + \framedforgetall + \setframedforegroundcolor + \vsize\!!framedheight + \doframedsetups + \vss + \bgroup + \aftergroup\vss + \aftergroup\egroup + \hbox + \bgroup + \aftergroup\egroup + \localstrut + \doformatonelinerbox} + +\def\doformatboxHSize + {\hbox to \!!framedwidth + \bgroup + \let\postprocessframebox\relax + \framedforgetall + \setframedforegroundcolor + \doframedsetups + \hss + \localstrut + \bgroup + \aftergroup\hss + \aftergroup\egroup + \doformatonelinerbox} + +\def\doformatboxNoSize + {\hbox + \bgroup + \setframedforegroundcolor + \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: + +\newcount\framednoflines +\newdimen\framedlastlength + +\def\resetshapeframebox + {\framednoflines \zerocount + \framedlastlength\zeropoint} + +\let\framedboxwidth \!!zeropoint +\let\framedboxheight\!!zeropoint +\let\framedboxdepth \!!zeropoint + +\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=\the\dimexpr\framedparameter\c!backgroundoffset\relax\\ +%D frameoffset=\the\dimexpr\framedparameter\c!frameoffset\relax\\ +%D depth=\the\dimexpr\framedparameter\c!depth\relax} +%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} + +\unexpanded\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\complexblackrule[#1]% + {\hbox\bgroup\getparameters[\??bj][#1]\domakeblackrule\egroup} + +\def\simpleblackrule + {\hbox\bgroup\domakeblackrule\egroup} + +\def\domakeblackrule + {\doif\@@bjwidth \v!max{\def\@@bjwidth {1em}}% + \doif\@@bjheight\v!max{\setstrut\let\setstrut\relax\def\@@bjheight{\strutht}}% + \doif\@@bjdepth \v!max{\setstrut\def\@@bjdepth {\strutdp}}% + \startcolor[\@@bjcolor]% can be made faster, just direct attr + \vrule + \!!width \@@bjwidth + \!!height\@@bjheight + \!!depth \@@bjdepth + \stopcolor} + +\definecomplexorsimple\blackrule + +%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}% + \startcolor[\@@bjcolor]% + \dorecurse\@@bjn + {\vrule + \!!width \!!widtha + \!!height\@@bjheight + \!!depth \@@bjdepth + \hskip\!!widthb}% + \unskip + \stopcolor + \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} + +\unexpanded\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\dovlwdhtdp#1#2#3% + {\bgroup + \!!dimena#2\strutht + \!!dimenb#3\strutdp + \setbox\scratchbox\hbox + {\vrule + \!!width #1\linewidth + \!!height\!!dimena + \!!depth \!!dimenb}% + \dp\scratchbox\strutdp + \ht\scratchbox\strutht + \box\scratchbox + \egroup} + +\def\complexvl[#1]% + {\dovlwdhtdp{1}{#1}{#1}} + +\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]} + +\unexpanded\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]% + \setuvalue{\e!start#1}{\dostartframedtext[#1]}% + \setuvalue{\e!stop #1}{\dostopframedtext }% + \setuvalue {#1}{\doframedtext [#1]}} + +\unexpanded\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% todo: currentframedtext + {\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} + +\unexpanded\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\checkframedtext % messy dependency + {\ifinsidefloat + \localhsize\hsize + \else\ifdim\sidefloatvsize>\zeropoint % will be proper handle + % \strut % rather clean way to invoke the sidefloat OTR + % \setbox0=\lastbox % and get the widths set, so from now on we + % \setlocalhsize % can have framed texts alongside sidefloats + \checksidefloat + \setlocalhsize + \else + \localhsize\hsize + \fi\fi} + +\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 % brrr too often + \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} + +\unexpanded\def\defineframed + {\dodoubleempty\dodefineframed} + +\def\dodefineframed[#1][#2]% + {\iffirstargument + \setuvalue{#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. + +\unexpanded\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 + \doifsomething{#1} + {\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}}}% + \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: + +\unexpanded\def\starttextrule#1% + {\bgroup + \def\dounknowntextrule{\domiddletextrule} + \dotoptextrule{#1} + \bgroup + \doifsomething\@@tlbodyfont{\switchtobodyfont[\@@tlbodyfont]}} + +\unexpanded\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} + +\unexpanded\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} + +\unexpanded\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}} + +\unexpanded\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 + \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 + +% \unexpanded\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]} +% +% \unexpanded\def\setupframedcontent +% {\dodoubleempty\dosetupframedcontent} +% +% \def\dosetupframedcontent[#1][#2]% +% {\def\docommand##1{\getparameters[\??fc##1][#2]}% +% \processcommacommand[#1]\docommand} +% +% \unexpanded\def\startframedcontent[#1]% +% {\bgroup +% \doifelse{#1}\v!off +% {\let\stopframedcontent\egroup} +% {\ifcsname\??fc#1\c!frame\endcsname +% \dostartframedcontent{#1}% +% \fi}} +% +% \def\dostartframedcontent#1% +% {\unexpanded\def\stopframedcontent{\dostopframedcontent{#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} + +\def\framedcontentparameter #1{\csname\doframedcontentparameter{\??fc\@@framedcontent}#1\endcsname} +\def\doframedcontentparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\doframedcontentparentparameter\csname#1\s!parent\endcsname#2\fi} +\def\doframedcontentparentparameter#1#2{\ifx#1\relax\s!empty\else\doframedcontentparameter#1#2\fi} + +\presetlocalframed[\??fc] + +\getparameters + [\??fc] + [\c!leftoffset=\zeropoint, + \c!rightoffset=\framedcontentparameter\c!leftoffset, + \c!topoffset=\zeropoint, + \c!bottomoffset=\framedcontentparameter\c!topoffset, + \c!strut=\v!no, + %\c!linecorrection=\v!no, + %\c!left=, + %\c!right=, + %\c!width=\v!fit, + \c!offset=\v!overlay] + +\def\letframedcontentparameter#1% + {\letvalue{\??fc\@@framedcontent#1}} + +\unexpanded\def\defineframedcontent + {\dodoubleempty\dodefineframedcontent} + +\def\dodefineframedcontent[#1][#2]% + {\getparameters[\??fc#1][\s!parent=\??fc,#2]} + +\unexpanded\def\setupframedcontent + {\dodoubleempty\dosetupframedcontent} + +\def\dosetupframedcontent[#1][#2]% + {\def\docommand##1{\getparameters[\??fc##1][#2]}% + \processcommacommand[#1]\docommand} + +\unexpanded\def\startframedcontent + {\dosingleempty\dostartframedcontent} + +\def\dostartframedcontent[#1]% + {\bgroup + \edef\@@framedcontent{#1}% + \let\stopframedcontent\egroup + \doifnot{#1}\v!off{\dodostartframedcontent{#1}}} + +\def\dodostartframedcontent#1% + {\unexpanded\def\stopframedcontent{\dostopframedcontent{#1}}% + \setbox\framebox\hbox\bgroup + \setlocalhsize + \hsize\localhsize + \advance\hsize\dimexpr-\framedcontentparameter\c!leftoffset-\framedcontentparameter\c!rightoffset \relax + \advance\vsize\dimexpr-\framedcontentparameter\c!topoffset -\framedcontentparameter\c!bottomoffset\relax + \hskip\framedcontentparameter\c!leftoffset + \vbox\bgroup + \vskip\framedcontentparameter\c!topoffset + \vbox\bgroup + \forgetall + \blank[\v!disable]} + +\def\dostopframedcontent#1% + {\removelastskip + \egroup + \vskip\framedcontentparameter\c!bottomoffset + \egroup + \hskip\framedcontentparameter\c!rightoffset + \egroup + \doif{\framedcontentparameter\c!width}\v!fit + {\letframedcontentparameter\c!width\v!fixed}% no shapebox + \ifinsidefloat + \donefalse + \else + \doifelse{\framedcontentparameter\c!linecorrection}\v!yes\donetrue\donefalse + \fi + % plaats ? + \ifdone\startlinecorrection\fi + \framedcontentparameter\c!left % new + \localframed[\??fc#1]{\box\framebox}% + \framedcontentparameter\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 + {\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 + \relax + \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/page-app.mkii b/tex/context/base/page-app.mkii new file mode 100644 index 000000000..e5c149aa0 --- /dev/null +++ b/tex/context/base/page-app.mkii @@ -0,0 +1,225 @@ +%D \module +%D [ file=page-app, % from meta-fig +%D version=1998.01.15, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Independent page building, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Applications} + +%D The fitting page code is moved from \type {meta-fig} to +%D here. + +\unprotect + +\definepapersize + [\??fp\s!dummy] + [\c!width=\fittingwd, + \c!height=\fittinght] + +\definelayout + [\??fp\s!dummy] + [\c!width=\fittingwd,\c!height=\fittinght,\c!location=\v!middle, + \c!topspace=\!!zeropoint,\c!backspace=\!!zeropoint, + \c!cutspace=\!!zeropoint,\c!bottomspace=\!!zeropoint, + \c!textdistance=\!!zeropoint,\c!lines=0,\c!grid=\v!no, + \c!top=\!!zeropoint,\c!bottom=\!!zeropoint, + \c!margin=\!!zeropoint,\c!edge=\!!zeropoint, + \c!leftmargin=\!!zeropoint,\c!leftedge=\!!zeropoint, + \c!rightmargin=\!!zeropoint,\c!rightedge=\!!zeropoint, + \c!header=\!!zeropoint,\c!footer=\!!zeropoint] + + +\def\dostartfittingpage[#1][#2]% + {\page % this is kind of tricky! there can be preceding page refs + \autostarttext + \bgroup % resulting in a zero height page; test fig-make ! + \def\currentfittingpage{#1}% + \dontcomplain + % runs under current page regime, i.e. page variables passed to mp + \getparameters[\currentfittingpage][\c!paper=,#2]% auto or size or nothing + \setbox\scratchbox\hbox + \bgroup + % needed later \getparameters[\currentfittingpage][\c!paper=,#2]% auto or size or nothing + \doifvalue{\currentfittingpage\c!margin}\v!page % undocumented + {\offsetbox + [\c!leftoffset=\backspace, + \c!rightoffset=\cutspace, + \c!topoffset=\topspace, + \c!bottomoffset=\bottomspace]\hbox}% + \bgroup + \scale[\c!scale=\getvalue{\currentfittingpage\c!scale}]% + \bgroup\localframed[\currentfittingpage]% + \bgroup} + +\def\dostopfittingpage + {\egroup % localframed + \egroup % scale + \egroup % offsetbox + \egroup % scratchbox + \edef\fittingwd{\the\wd\scratchbox}% + \edef\fittinght{\the\ht\scratchbox}% + \startlocallayout + \ifdim\fittinght<\lineheight + % write status : too small + \setbox\scratchbox\vbox to \lineheight{\vss\box\scratchbox\vss}% + \edef\fittinght{\the\lineheight}% + \fi + \let\checkcurrentlayout\relax % else interference with odd/even layout + \processaction + [\getvalue{\currentfittingpage\c!paper}] + [ \v!auto=>\let\fittingpapersize\printpapersize, + \s!unknown=>\let\fittingpapersize\commalistelement, + \s!default=>\def\fittingpapersize{\??fp\s!dummy}]% + \expanded{\setuppapersize[\??fp\s!dummy][\fittingpapersize]}% + \definelayout + [\v!page]% + [\c!location=\v!middle, + \c!width=\fittingwd, + \c!height=\fittinght]% + \setuplayout + [\v!page]% + \startmakeup[\v!standard][\c!textstate=\v!empty,\c!doublesided=\v!no,\c!page=]% + \centerbox{\box\scratchbox}% + \stopmakeup + \stoplocallayout + \egroup + \autostoptext} + +%D \TEX\ pages (for \METAPOST\ pages, see \type {meta-fig}): + +\presetlocalframed[\??tg] + +\def\setupTEXpage + {\dodoubleargument\getparameters[\??tg]} + +\def\startTEXpage + {\dosingleempty\dostartTEXpage} + +\def\dostartTEXpage[#1]% + {\dostartfittingpage[\??tg][#1]\gobblespacetokens} + +\def\stopTEXpage + {\removelastspace + \dostopfittingpage} + +\setupTEXpage + [\c!scale=1000, + \c!strut=\v!no, + \c!align=\v!normal, % needed, else problems ! + \c!offset=\v!overlay, + \c!width=\v!fit, + \c!height=\v!fit, + \c!frame=\v!off] + +%D For Mojca: +%D +%D \starttyping +%D \startTEXstream \chapter{Bla} Hello world!\crlf Hello world! \stopTEXstream +%D \startTEXpage \chapter{Bla} Hello world!\crlf Hello world! \stopTEXpage +%D \stoptyping +%D +%D maybe I should support stream=yes in framed. + +\def\startTEXstream + {\dosingleempty\dostartTEXstream} + +\def\dostartTEXstream[#1]% + {\page + \defineoutputstream[tex]% + \enableoutputstream[tex]% + \def\stopTEXstream + {\disableoutputstream + \startTEXpage + \outputstreamunvbox[tex]% + \stopTEXpage}} + +%D Application pages (for an example, see \type {m-pstric}): + +\def\@@texapp{texapp} +\def\@@texdim{texdim} + +\def\saveTEXapplication#1#2% + {\immediate\openout\scratchwrite=\bufferprefix\@@texdim.tmp + \immediate\write\scratchwrite{\dimen#1=\the\ht\scratchbox}% + \immediate\write\scratchwrite{\dimen#2=\the\wd\scratchbox}% + \immediate\closeout\scratchwrite} + +\def\restoreTEXapplication + {\readlocfile{\bufferprefix\@@texdim.tmp}\donothing\donothing} + +\def\startTEXapplication + {\dosingleempty\dostartTEXapplication} + +\long\def\dostartTEXapplication[#1]#2#3\stopTEXapplication + {\bgroup + \bgroup + \let\f!temporaryextension\c!tex + \setbuffer[\@@texapp]% + \starttext + #2% preamble + \startTEXpage[#1]% + \topskip\zeropoint + \setbox\scratchbox\hbox{#3}% + \saveTEXapplication02% dimensions + \box\scratchbox + \stopTEXpage + \stoptext + \endbuffer + \egroup + \doifelse\jobsuffix{dvi}\donetrue\donefalse + \executesystemcommand{texexec \bufferprefix\@@texapp.tex --once --batch}% + \ifdone % eps + \executesystemcommand{dvips -E* -o \@@texapp.eps \@@texapp}% + \else % pdf + \executesystemcommand{dvips \bufferprefix\@@texapp}% + \executesystemcommand{ps2pdf \bufferprefix\@@texapp.ps \bufferprefix\@@texapp.pdf}% +% \executesystemcommand{texmfstart pstopdf \bufferprefix\@@texapp.ps \bufferprefix\@@texapp.pdf}% + \fi + \restoreTEXapplication % dimensions + \doifelse\jobsuffix{dvi}\donetrue\donefalse + \setbox\scratchbox\hbox + {\expanded{\externalfigure + [\bufferprefix\@@texapp.\ifdone eps\else pdf\fi] + [\c!object=\v!no]}}% + \setbox\scratchbox\hbox + {\lower\ht\scratchbox\hbox{\raise\dimen2\box\scratchbox}}% + \wd\scratchbox\dimen0 + \ht\scratchbox\dimen2 + \dp\scratchbox\zeropoint + \box\scratchbox + \egroup} + +%D \macros +%D {startpagefigure} +%D +%D \starttyping +%D \starttext \pagefigure[two.1] \stoptext +%D \stoptyping + +\def\startpagefigure + {\dodoubleempty\dostartpagefigure} + +\def\dostartpagefigure[#1][#2]% + {\bgroup + \getparameters[\??ex][\c!offset=\v!overlay,#2]% + \startTEXpage[\c!offset=\@@exoffset]% + \externalfigure[#1][#2]\ignorespaces} % so we can put some text below the graphic + +\def\stoppagefigure + {\stopTEXpage + \egroup} + +\def\pagefigure + {\dodoubleempty\dopagefigure} + +\def\dopagefigure[#1][#2]% + {\dostartpagefigure[#1][#2]\stoppagefigure} + +\protect \endinput diff --git a/tex/context/base/page-app.mkiv b/tex/context/base/page-app.mkiv new file mode 100644 index 000000000..7dd71cf2a --- /dev/null +++ b/tex/context/base/page-app.mkiv @@ -0,0 +1,225 @@ +%D \module +%D [ file=page-app, % from meta-fig +%D version=1998.01.15, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Independent page building, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Applications} + +%D The fitting page code is moved from \type {meta-fig} to +%D here. + +\unprotect + +\definepapersize + [\??fp\s!dummy] + [\c!width=\fittingwd, + \c!height=\fittinght] + +\definelayout + [\??fp\s!dummy] + [\c!width=\fittingwd,\c!height=\fittinght,\c!location=\v!middle, + \c!topspace=\!!zeropoint,\c!backspace=\!!zeropoint, + \c!cutspace=\!!zeropoint,\c!bottomspace=\!!zeropoint, + \c!textdistance=\!!zeropoint,\c!lines=0,\c!grid=\v!no, + \c!top=\!!zeropoint,\c!bottom=\!!zeropoint, + \c!margin=\!!zeropoint,\c!edge=\!!zeropoint, + \c!leftmargin=\!!zeropoint,\c!leftedge=\!!zeropoint, + \c!rightmargin=\!!zeropoint,\c!rightedge=\!!zeropoint, + \c!header=\!!zeropoint,\c!footer=\!!zeropoint] + + +\def\dostartfittingpage[#1][#2]% + {\page % this is kind of tricky! there can be preceding page refs + \autostarttext + \bgroup % resulting in a zero height page; test fig-make ! + \def\currentfittingpage{#1}% + \dontcomplain + % runs under current page regime, i.e. page variables passed to mp + \getparameters[\currentfittingpage][\c!paper=,#2]% auto or size or nothing + \setbox\scratchbox\hbox + \bgroup + % needed later \getparameters[\currentfittingpage][\c!paper=,#2]% auto or size or nothing + \doifvalue{\currentfittingpage\c!margin}\v!page % undocumented + {\offsetbox + [\c!leftoffset=\backspace, + \c!rightoffset=\cutspace, + \c!topoffset=\topspace, + \c!bottomoffset=\bottomspace]\hbox}% + \bgroup + \scale[\c!scale=\getvalue{\currentfittingpage\c!scale}]% + \bgroup\localframed[\currentfittingpage]% + \bgroup} + +\def\dostopfittingpage + {\egroup % localframed + \egroup % scale + \egroup % offsetbox + \egroup % scratchbox + \edef\fittingwd{\the\wd\scratchbox}% + \edef\fittinght{\the\ht\scratchbox}% + \startlocallayout + \ifdim\fittinght<\lineheight + % write status : too small + \setbox\scratchbox\vbox to \lineheight{\vss\box\scratchbox\vss}% + \edef\fittinght{\the\lineheight}% + \fi + \let\checkcurrentlayout\relax % else interference with odd/even layout + \processaction + [\getvalue{\currentfittingpage\c!paper}] + [ \v!auto=>\let\fittingpapersize\printpapersize, + \s!unknown=>\let\fittingpapersize\commalistelement, + \s!default=>\def\fittingpapersize{\??fp\s!dummy}]% + \expanded{\setuppapersize[\??fp\s!dummy][\fittingpapersize]}% + \definelayout + [\v!page]% + [\c!location=\v!middle, + \c!width=\fittingwd, + \c!height=\fittinght]% + \setuplayout + [\v!page]% + \startmakeup[\v!standard][\c!textstate=\v!empty,\c!doublesided=\v!no,\c!page=]% + \centerbox{\box\scratchbox}% + \stopmakeup + \stoplocallayout + \egroup + \autostoptext} + +%D \TEX\ pages (for \METAPOST\ pages, see \type {meta-fig}): + +\presetlocalframed[\??tg] + +\unexpanded\def\setupTEXpage + {\dodoubleargument\getparameters[\??tg]} + +\unexpanded\def\startTEXpage + {\dosingleempty\dostartTEXpage} + +\def\dostartTEXpage[#1]% + {\dostartfittingpage[\??tg][#1]\gobblespacetokens} + +\unexpanded\def\stopTEXpage + {\removelastspace + \dostopfittingpage} + +\setupTEXpage + [\c!scale=1000, + \c!strut=\v!no, + \c!align=\v!normal, % needed, else problems ! + \c!offset=\v!overlay, + \c!width=\v!fit, + \c!height=\v!fit, + \c!frame=\v!off] + +%D For Mojca: +%D +%D \starttyping +%D \startTEXstream \chapter{Bla} Hello world!\crlf Hello world! \stopTEXstream +%D \startTEXpage \chapter{Bla} Hello world!\crlf Hello world! \stopTEXpage +%D \stoptyping +%D +%D maybe I should support stream=yes in framed. + +\unexpanded\def\startTEXstream + {\dosingleempty\dostartTEXstream} + +\def\dostartTEXstream[#1]% + {\page + \defineoutputstream[tex]% + \enableoutputstream[tex]% + \unexpanded\def\stopTEXstream + {\disableoutputstream + \startTEXpage + \outputstreamunvbox[tex]% + \stopTEXpage}} + +%D Application pages (for an example, see \type {m-pstric}): + +\def\@@texapp{texapp} +\def\@@texdim{texdim} + +\def\saveTEXapplication#1#2% + {\immediate\openout\scratchwrite=\bufferprefix\@@texdim.tmp + \immediate\write\scratchwrite{\dimen#1=\the\ht\scratchbox}% + \immediate\write\scratchwrite{\dimen#2=\the\wd\scratchbox}% + \immediate\closeout\scratchwrite} + +\def\restoreTEXapplication + {\readlocfile{\bufferprefix\@@texdim.tmp}\donothing\donothing} + +\def\startTEXapplication + {\dosingleempty\dostartTEXapplication} + +\long\def\dostartTEXapplication[#1]#2#3\stopTEXapplication + {\bgroup + \bgroup + \let\f!temporaryextension\c!tex + \setbuffer[\@@texapp]% + \starttext + #2% preamble + \startTEXpage[#1]% + \topskip\zeropoint + \setbox\scratchbox\hbox{#3}% + \saveTEXapplication02% dimensions + \box\scratchbox + \stopTEXpage + \stoptext + \endbuffer + \egroup + \doifelse\jobsuffix{dvi}\donetrue\donefalse + \executesystemcommand{texexec \bufferprefix\@@texapp.tex --once --batch}% + \ifdone % eps + \executesystemcommand{dvips -E* -o \@@texapp.eps \@@texapp}% + \else % pdf + \executesystemcommand{dvips \bufferprefix\@@texapp}% + \executesystemcommand{ps2pdf \bufferprefix\@@texapp.ps \bufferprefix\@@texapp.pdf}% +% \executesystemcommand{texmfstart pstopdf \bufferprefix\@@texapp.ps \bufferprefix\@@texapp.pdf}% + \fi + \restoreTEXapplication % dimensions + \doifelse\jobsuffix{dvi}\donetrue\donefalse + \setbox\scratchbox\hbox + {\expanded{\externalfigure + [\bufferprefix\@@texapp.\ifdone eps\else pdf\fi] + [\c!object=\v!no]}}% + \setbox\scratchbox\hbox + {\lower\ht\scratchbox\hbox{\raise\dimen2\box\scratchbox}}% + \wd\scratchbox\dimen0 + \ht\scratchbox\dimen2 + \dp\scratchbox\zeropoint + \box\scratchbox + \egroup} + +%D \macros +%D {startpagefigure} +%D +%D \starttyping +%D \starttext \pagefigure[two.1] \stoptext +%D \stoptyping + +\unexpanded\def\startpagefigure + {\dodoubleempty\dostartpagefigure} + +\def\dostartpagefigure[#1][#2]% + {\bgroup + \getparameters[\??ex][\c!offset=\v!overlay,#2]% + \startTEXpage[\c!offset=\@@exoffset]% + \externalfigure[#1][#2]\ignorespaces} % so we can put some text below the graphic + +\unexpanded\def\stoppagefigure + {\stopTEXpage + \egroup} + +\def\pagefigure + {\dodoubleempty\dopagefigure} + +\def\dopagefigure[#1][#2]% + {\dostartpagefigure[#1][#2]\stoppagefigure} + +\protect \endinput 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..93400943d --- /dev/null +++ b/tex/context/base/page-bck.mkiv @@ -0,0 +1,563 @@ +%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 + +% todo \fastlocalframed -> \localbackgroundframed + +\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} + +\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% here we need an \ifempty primitive + {\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\expandafter\let\csname\currentotrbackground\endcsname\relax + \else + \endgroup\expandafter\let\csname\currentotrbackground\endcsname\undefined + \fi} + +\def\ifsomebackgroundfound#1% + {\ifcsname\??ma#1\endcsname} + +\def\doifsomebackgroundelse#1% + {\ifcsname\??ma#1\endcsname + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +\def\doifsomebackground#1% + {\ifcsname\??ma#1\endcsname + \expandafter\firstofoneargument + \else + \expandafter\gobbleoneargument + \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 +% \doprocesslocalsetups{\csname\??ma#1\c!setups\endcsname}% should not produce funny spaces ! +% \fi +% \setbox#2\vbox\fastlocalframed % maybe \superfastlocalframed{tag}{w}{h} +% [\??ma#1]% +% [\c!component=#1,\c!width=#3,\c!height=#4]% are width and height used? +% {\dp#2\zeropoint\box#2}% +% \fi\fi\fi} + +\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 + \doprocesslocalsetups{\csname\??ma#1\c!setups\endcsname}% should not produce funny spaces ! + \fi + \localbackgroundframed{#1}{#2}{#3}{#4}% + \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 + +% \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 + \dosetbackgroundboxesr + \fi + \doifbothsides\dosetbackgroundboxesa\dosetbackgroundboxesb\dosetbackgroundboxesc + \ifx\@@mastate\v!repeat\else\global\newbackgroundfalse\fi} + +\def\dosetbackgroundboxesr + {\global\chardef\newrightbackground\plusone + \global\chardef\newleftbackground\plusone + \global\setbox\leftbackground\emptybox + \global\setbox\rightbackground\emptybox} +\def\dosetbackgroundboxesa + {\ifcase\newleftbackground \else + % \showmessage\m!layouts8\empty + \setbackgroundbox\leftbackground\relax + \global\chardef\newleftbackground\zerocount + \global\chardef\newrightbackground\zerocount + \fi} +\def\dosetbackgroundboxesb + {\ifcase\newleftbackground \else + % \showmessage\m!layouts8\empty + \setbackgroundbox\leftbackground\relax + \global\chardef\newleftbackground\zerocount + \fi} +\def\dosetbackgroundboxesc + {\ifcase\newrightbackground \else + % \showmessage\m!layouts8\empty + \setbackgroundbox\rightbackground\doswapmargins + \global\chardef\newrightbackground\zerocount + \fi} + +\def\addmainbackground#1% todo: dimension spec + {\ifsomebackground + \setbackgroundboxes + \setbox#1\vbox + {\offinterlineskip + \doifmarginswapelse{\copy\leftbackground}{\copy\rightbackground}% + \box#1}% + \fi} + +\newdimen\pagebackgroundhoffset +\newdimen\pagebackgroundvoffset +\newdimen\pagebackgrounddepth +\newdimen\pagebackgroundoffset + +\def\setbackgroundoffsets % used in menus (we can use ifcsname's here) + {\ifsomebackground \ifnewbackground + \global\pagebackgroundhoffset\zeropoint + \global\pagebackgroundvoffset\zeropoint + \global\pagebackgrounddepth \zeropoint + \doifsomebackgroundelse{\v!text\v!text}\donetrue\donefalse + \ifdone\else\doifsomebackgroundelse\v!text\donetrue\donothing\fi + \ifdone + \begingroup + \scratchdimen\csname\??ma\v!page\c!offset\endcsname + \doifsomebackgroundelse{\v!top\v!text}\donothing + {\doifsomebackgroundelse{\v!bottom\v!text}\donothing + {\global\pagebackgroundhoffset\scratchdimen}}% + \doifsomebackgroundelse{\v!text\v!rightedge}\donothing + {\doifsomebackgroundelse{\v!text\v!leftedge}\donothing + {\global\pagebackgroundvoffset\scratchdimen + \global\pagebackgrounddepth\csname\??ma\v!page\c!depth\endcsname}}% + \endgroup + \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% maybe helper + {\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 % maybe helper + {\ifsomebackgroundfound{#3#4}% + \ifdim#2>\zeropoint\relax + \ifdim#1>\zeropoint\relax + \ifcsname\??ma#3#4\c!setups\endcsname % to be done + \doprocesslocalsetups{\csname\??ma#3#4\c!setups\endcsname}% should not produce funny spaces ! + \fi + \fastlocalframed + [\??ma#3#4]% + [\c!component=#3-#4]% + {\vbox to #2{\vss\hbox to#1{\hss\csname\??ma#3#4\c!command\endcsname\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. + +\unexpanded\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\csname\??ma\v!page\c!offset\endcsname}% + \global\pagedepth\csname\??ma\v!page\c!depth\endcsname + \global\pagebackgroundoffset\pageoffset + \global\pagebackgrounddepth\pagedepth + \doifelse\@@mastate\v!stop + {\global\newbackgroundfalse} + {\global\newbackgroundtrue }} + +%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 diff --git a/tex/context/base/page-flt.lua b/tex/context/base/page-flt.lua new file mode 100644 index 000000000..74d1e4e8c --- /dev/null +++ b/tex/context/base/page-flt.lua @@ -0,0 +1,227 @@ +if not modules then modules = { } end modules ['page-flt'] = { + version = 1.001, + comment = "companion to page-flt.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local setdimen, setbox, setcount, texbox = tex.setdimen, tex.setbox, tex.setcount, tex.box +local insert, remove = table.insert, table.remove +local texwrite, texsprint, ctxcatcodes = tex.write, tex.sprint, tex.ctxcatcodes + +local copy_node_list = node.copy_list + +local trace_floats = false trackers.register("graphics.floats", function(v) trace_floats = v end) -- name might change + +-- we use floatbox, floatwidth, floatheight +-- text page leftpage rightpage (todo: top, bottom, margin, order) + +floats = floats or { } + +local noffloats, last, default, pushed = 0, nil, "text", { } + +local function initialize() + return { + text = { }, + page = { }, + leftpage = { }, + rightpage = { }, + } +end + +local stacks = initialize() + +-- list location + +function floats.stacked(which) -- floats.thenofstacked + return #stacks[which or default] +end + +function floats.thestacked(which) + return texwrite(#stacks[which or default]) +end + +function floats.push() + insert(pushed,stacks) + stacks = initialize() + setcount("global","savednoffloats",0) +end + +function floats.pop() + local popped = remove(pushed) + if popped then + for which, stack in next, stacks do + for i=1,#stack do + insert(popped[which],stack[i]) + end + end + stacks = popped + setcount("global","savednoffloats",#stacks[default]) + end +end + +local function setdimensions(b) + local w, h, d = 0, 0, 0 + if b then + w, h, d = b.width, b.height, b.depth + end + setdimen("global","floatwidth", w) + setdimen("global","floatheight", h+d) + return w, h, d +end + +local function get(stack,n) + n = n or #stack + if n > 0 then + local t = stack[n] + if t then + return t, t.box, n + end + end +end + +function floats.save(which,data) + which = which or default + local stack = stacks[which] + noffloats = noffloats + 1 + local b = texbox.floatbox + local w, h, d = b.width, b.height, b.depth + local t = { + n = noffloats, + data = data or { }, + box = copy_node_list(b), + } + texbox.floatbox = nil + insert(stack,t) + setcount("global","savednoffloats",#stacks[default]) + if trace_floats then + logs.report("floats","saving %s float %s in slot %s (%i,%i,%i)",which,noffloats,#stack,w,h,d) + else + interfaces.showmessage("floatblocks",2,noffloats) + end +end + +function floats.resave(which) + if last then + which = which or default + local stack = stacks[which] + local b = texbox.floatbox + local w, h, d = b.width, b.height, b.depth + last.box = copy_node_list(b) + texbox.floatbox = nil + insert(stack,1,last) + setcount("global","savednoffloats",#stacks[default]) + if trace_floats then + logs.report("floats","resaving %s float %s in slot %s (%i,%i,%i)",which,noffloats,#stack,w,h,d) + else + interfaces.showmessage("floatblocks",2,noffloats) + end + else + logs.report("floats","unable to resave float") + end +end + +function floats.flush(which,n) + which = which or default + local stack = stacks[which] + local t, b, n = get(stack,n or 1) + if t then + local w, h, d = setdimensions(b) + if trace_floats then + logs.report("floats","flushing %s float %s from slot %s (%i,%i,%i)",which,t.n,n,w,h,d) + else + interfaces.showmessage("floatblocks",3,t.n) + end + texbox.floatbox = b + last = remove(stack,n) + last.box = nil + setcount("global","savednoffloats",#stacks[default]) + else + setdimensions() + end +end + +function floats.thevar(name,default) + local value = last and last.data[name] or default + if value and value ~= "" then + texsprint(ctxcatcodes,value) + end +end + +function floats.consult(which,n) + which = which or default + local stack = stacks[which] + local t, b, n = get(stack,n) + if t then + local w, h, d = setdimensions(b) + if trace_floats then + logs.report("floats","consulting %s float %s in slot %s (%i,%i,%i)",which,t.n,n,w,h,d) + end + return t, b, n + else + if trace_floats then + logs.report("floats","nothing to consult") + end + setdimensions() + end +end + +function floats.collect(which,maxwidth,distance) + which = which or default + local stack = stacks[which] + local n, m = #stack, 0 + for i=1,n do + local t, b, n = get(stack,i) + if t then + local w, h, d = setdimensions(b) + if w + distance < maxwidth then + m = m + 1 + maxwidth = maxwidth - w - distance + else + break + end + else + break + end + end + if m == 0 then + m = 1 + end + setcount("global","nofcollectedfloats",m) +end + +function commands.doifsavedfloatelse(which) + local stack = stacks[which or default] + commands.doifelse(#stack>0) +end + +function floats.thecheckedpagefloat(packed) + local result = "" + if structure.pages.is_odd() then + if #stacks.rightpage > 0 then + result = "rightpage" + elseif #stacks.page > 0 then + result = "page" + elseif #stacks.leftpage > 0 then + if packed then + result = "leftpage" + else + result = "empty" + end + end + else + if #stacks.leftpage > 0 then + result = "leftpage" + elseif #stacks.page > 0 then + result = "page" + elseif #stacks.rightpage > 0 then + if packed then + result = "rightpage" + else + result = "empty" + end + end + end + texsprint(ctxcatcodes,result) +end diff --git a/tex/context/base/page-flt.mkiv b/tex/context/base/page-flt.mkiv new file mode 100644 index 000000000..944626b8e --- /dev/null +++ b/tex/context/base/page-flt.mkiv @@ -0,0 +1,233 @@ +%D \module +%D [ file=page-flt, +%D version=2010.04,08, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Float 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. + +\writestatus{loading}{ConTeXt Page Macros / Float Management} + +%D This module has code that previously was in other modules. There is +%D also float related code in \type {strc-flt.mkiv}. + +\registerctxluafile{page-flt}{1.001} + +\unprotect + +%D To be checked and removed + +%def\dosavefloatinfo {\showmessage\m!floatblocks2{\the\totalnoffloats}} +\def\doinsertfloatinfo {\showmessage\m!floatblocks4{\the\totalnoffloats}} +\def\dofloatflushedinfo{\showmessage\m!floatblocks3{\the\numexpr\totalnoffloats-\savednoffloats\relax}} + +%D Extra float registers. + +\newif\ifsomefloatwaiting \somefloatwaitingfalse +\newif\ifroomforfloat \roomforfloattrue +\newif\ifnofloatpermitted \nofloatpermittedfalse +\newif\ifcenterfloatbox \centerfloatboxtrue +\newif\iflocalcenterfloatbox \localcenterfloatboxfalse +\newif\ifglobalcenterfloatbox \globalcenterfloatboxfalse +\newif\ifflushingfloats \flushingfloatsfalse +\newif\ifpackflushedfloats \packflushedfloatstrue % for the moment +\newif\ifpackcolumnfloats \packcolumnfloatstrue + +\newcount\totalnoffloats +\newcount\savednoffloats +\newcount\noffloatinserts +\newcount\nofcollectedfloats % communication channel + +\newbox \floatlist +\newbox \savedfloatlist +\newbox \floattext + +\newdimen\floatwidth +\newdimen\floatheight +\newdimen\floatdepth +\newdimen\floattextwidth +\newdimen\floattextheight + +\newbox \floatbox +\newbox \savedfloatbox + +%D From now on we manage the float stack at the \LUA\ end instead of packing +%D them in a box and splitting off stacked floats. It's not so much less code +%D but it's cleaner this way. It also opens op some posibilities as we can now +%D more conveniently cary additional information around. + +\newtoks \everyfloatscheck + +\appendtoks + \ifcase\savednoffloats + \global\somefloatwaitingfalse + \else + \global\somefloatwaitingtrue + \fi +\to \everyfloatscheck + +\def\dofloatsflush#1#2% + {\ctxlua{floats.flush("#1",\number#2)}% + \the\everyfloatscheck} + +\def\dofloatssave#1% + {\ctxlua{floats.save("#1")}% + \the\everyfloatscheck} + +\def\dofloatsresave#1% + {\ctxlua{floats.resave("#1")}% + \the\everyfloatscheck} + +\def\dopushsavedfloats + {\ctxlua{floats.push()}% + \the\everyfloatscheck} + +\def\dopopsavedfloats + {\ctxlua{floats.pop()}% + \the\everyfloatscheck} + +\def\dofloatsgetinfo#1% + {\ctxlua{floats.consult("#1")}} + +\def\doifsavedfloatelse#1% + {\ctxlua{commands.doifsavedfloatelse("#1")}} + +\def\dofloatscollect#1#2#3% + {\ctxlua{floats.collect("#1",\number\dimexpr#2,\number\dimexpr#3)}} + +\def\dofloatsnofstacked#1% + {\ctxlua{floats.thestacked("#1")}} + +\def\dofloatsgetvariable#1% + {\ctxlua{floats.thevar("specification")}} + +\let\dopushcolumnfloats\dopushsavedfloats +\let\dopopcolumnfloats \dopopsavedfloats + +\def\dofloatssavepagefloat#1#2% + {\ctxlua{floats.save("#1", { specification = "#2" })}} + +%D The following code is in transition as we don't want to break the +%D current single column, multi column, and columnset mechanism. +%D +%D First we reimplement some helpers. + +\def\dogetfloat + {\ifsomefloatwaiting + \dofloatsflush{text}{1}% + \ifcenterfloatbox + \ifdim\wd\globalscratchbox<\hsize + \global\setbox\floatbox\hbox to \hsize{\hss\box\floatbox\hss}% + \else + % retain special alignments + \ifinsidecolumns + \ifdim\wd\floatbox>\makeupwidth + \global\wd\floatbox\makeupwidth + \fi + \fi + \fi + \fi + \else + \global\savednoffloats\zerocount + \global\setbox\floatbox\emptybox + \fi} + +\def\dosavefloat + {\dofloatssave{text}% + \nonoindentation} % brrr nonoindentation here + +\def\doresavefloat + {\dofloatsresave{text}} + +\def\doreversesavefloat + {\dofloatsresave{text}} + +\def\doflushsavedfloats % simplified \OTRONEdodoflushfloats + {\doloop + {\ifsomefloatwaiting + \docheckiffloatfits + \ifroomforfloat + \dogetfloat + \doplacefloatbox + \else + \exitloop + \fi + \else + \exitloop + \fi}} + +%D Page floats use different stacks. + +\newtoks \everybeforeflushedpagefloat + +\def\doflushsomepagefloat#1% future releases can do more clever things + {\dofloatsflush{#1}{1}% + \edef\floatspecification{\dofloatsgetvariable{specification}}% + \the\everybeforeflushedpagefloat + \vbox to \textheight + {\doifnotinset\v!high\floatspecification\vfill + \box\floatbox + \doifnotinset\v!low\floatspecification\vfill}% + \vfill\eject} + +% \def\doflushpagefloats +% {\doifoddpageelse +% {\ifnum\dofloatsnofstacked{rightpage}>\zerocount +% \doflushsomepagefloat{rightpage}% +% \else\ifnum\dofloatsnofstacked{page}>\zerocount +% \doflushsomepagefloat{page} +% \else\ifnum\dofloatsnofstacked{leftpage}>\zerocount +% \null\vfill\eject +% %\doflushsomepagefloat{leftpage}% +% \fi\fi\fi} +% {\ifnum\dofloatsnofstacked{leftpage}>\zerocount +% \doflushsomepagefloat{leftpage}% +% \else\ifnum\dofloatsnofstacked{page}>\zerocount +% \doflushsomepagefloat{page} +% \else\ifnum\dofloatsnofstacked{rightpage}>\zerocount +% \null\vfill\eject +% %\doflushsomepagefloat{rightpage}% +% \fi\fi\fi}} + +\def\doflushpagefloats + {\edef\checkedpagefloat{\ctxlua{floats.thecheckedpagefloat()}}% (true) for packed + \ifx\checkedpagefloat\empty + % nothing + \else\ifx\checkedpagefloat\v!empty + \null\vfill\eject + \else + \doflushsomepagefloat\checkedpagefloat + \fi\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} + +\ifdefined\doflushfloats\else \let\doflushfloats\relax \fi +\ifdefined\flushfloatbox\else \let\flushfloatbox\relax \fi + +\protect \endinput diff --git a/tex/context/base/page-flw.mkii b/tex/context/base/page-flw.mkii new file mode 100644 index 000000000..3eb867a78 --- /dev/null +++ b/tex/context/base/page-flw.mkii @@ -0,0 +1,107 @@ +%D \module +%D [ file=page-flw, +%D version=2003.04.19, % from test-002 (1997) profile experiment +%D title=\CONTEXT\ Page Macros, +%D subtitle=Text Flows, +%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 Page Macros / Text Flows} + +%D This is high experimental and especially flushing may change (proper +%D spacing is the driving force here). + +\unprotect + +\def\definetextflow + {\dodoubleempty\dodefinetextflow} + +\def\dodefinetextflow[#1][#2]% flow settings + {\iffirstargument + \doiftextflowcollectorelse{#1} + {\setbox\textflowcollector{#1}\emptybox} + {\@EA\newbox\csname\??tx:c:#1\endcsname}% + \getparameters[\??tx:p:#1] + [\c!width=\hsize,\c!style=,#2]% + \fi} + +\def\textflowparameter#1#2{\csname\??tx:p:#1#2\endcsname} +\def\textflowcollector #1{\csname\??tx:c:#1\endcsname} + +\def\doiftextflowcollectorelse#1{\doifdefinedelse{\??tx:c:#1}} + +\def\doiftextflowelse#1% + {\doiftextflowcollectorelse{#1} + {\ifvoid\textflowcollector{#1}% + \expandafter\secondoftwoarguments + \else + \expandafter\firstoftwoarguments + \fi} + {\secondoftwoarguments}} + +\def\doiftextflow#1% + {\doiftextflowelse{#1}\firstofoneargument\gobbleoneargument} + +\def\starttextflow[#1]% + {\doiftextflowcollectorelse{#1} + {\global\setbox\textflowcollector{#1}\vbox + \bgroup + \unvbox\textflowcollector{#1}% + \hsize\textflowparameter{#1}\c!width + \doifsomething{\textflowparameter{#1}\c!style}% + {\doconvertfont{\textflowparameter{#1}\c!style}}% + \def\stoptextflow{\endgraf\egroup}} + {\let\stoptextflow\relax}} + +\def\flushtextflow#1% + {\doiftextflow{#1} + {\ifdim\ht\textflowcollector{#1}>\vsize + \setbox\scratchbox\vsplit\textflowcollector{#1} to \vsize + \unvbox\scratchbox + \else + \unvbox\textflowcollector{#1}% + \fi}} + +\protect \endinput + +% Example (dutch) +% +% \stelpapierformaatin [S6] +% \steltolerantiein [soepel,rek] +% \stelkleurenin [status=start] +% \stelvoetin [strut=nee] +% \stelwitruimtein [groot] +% +% \stellayoutin +% [rechterrand=5cm,breedte=passend,marge=0pt,randafstand=1cm, +% voet=4cm,voetafstand=1cm,hoofd=0cm] +% +% \stelteksttekstenin[rand][][\vbox{\flushtextflow{alpha}}] +% \stelvoettekstenin [rand][][\vbox{\flushtextflow{beta}}] +% \stelvoettekstenin [\vbox{\flushtextflow{gamma}}][] +% +% \definetextflow [alfa] [breedte=\rechterrandbreedte] +% \definetextflow [beta] [breedte=\rechterrandbreedte] +% \definetextflow [gamma] [breedte=\voethoogte] +% +% \starttekst +% +% \dorecurse{50} +% {\getrandomnumber{\funny}{0}{8} +% \ifcase\funny \starttextflow[alfa] \input tufte.tex \stoptextflow +% \or \starttextflow[beta] \input knuth.tex \stoptextflow +% \or \starttextflow[gamma] \input materie.tex \stoptextflow +% \or {\bf TUFTE}\quad \input tufte \par +% \or {\bf TUFTE}\quad \input tufte \par +% \or {\bf KNUTH}\quad \input knuth \par +% \or {\bf KNUTH}\quad \input knuth \par +% \or {\bf MATERIE}\quad \input materie \par +% \else {\bf MATERIE}\quad \input materie \par +% \fi} +% +% \stoptekst diff --git a/tex/context/base/page-flw.mkiv b/tex/context/base/page-flw.mkiv new file mode 100644 index 000000000..81b4fedcb --- /dev/null +++ b/tex/context/base/page-flw.mkiv @@ -0,0 +1,107 @@ +%D \module +%D [ file=page-flw, +%D version=2003.04.19, % from test-002 (1997) profile experiment +%D title=\CONTEXT\ Page Macros, +%D subtitle=Text Flows, +%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 Page Macros / Text Flows} + +%D This is high experimental and especially flushing may change (proper +%D spacing is the driving force here). + +\unprotect + +\unexpanded\def\definetextflow + {\dodoubleempty\dodefinetextflow} + +\def\dodefinetextflow[#1][#2]% flow settings + {\iffirstargument + \doiftextflowcollectorelse{#1} + {\setbox\textflowcollector{#1}\emptybox} + {\@EA\newbox\csname\??tx:c:#1\endcsname}% + \getparameters[\??tx:p:#1] + [\c!width=\hsize,\c!style=,#2]% + \fi} + +\def\textflowparameter#1#2{\csname\??tx:p:#1#2\endcsname} +\def\textflowcollector #1{\csname\??tx:c:#1\endcsname} + +\def\doiftextflowcollectorelse#1{\doifdefinedelse{\??tx:c:#1}} + +\def\doiftextflowelse#1% + {\doiftextflowcollectorelse{#1} + {\ifvoid\textflowcollector{#1}% + \expandafter\secondoftwoarguments + \else + \expandafter\firstoftwoarguments + \fi} + {\secondoftwoarguments}} + +\def\doiftextflow#1% + {\doiftextflowelse{#1}\firstofoneargument\gobbleoneargument} + +\unexpanded\def\starttextflow[#1]% + {\doiftextflowcollectorelse{#1} + {\global\setbox\textflowcollector{#1}\vbox + \bgroup + \unvbox\textflowcollector{#1}% + \hsize\textflowparameter{#1}\c!width + \doifsomething{\textflowparameter{#1}\c!style}% + {\doconvertfont{\textflowparameter{#1}\c!style}}% + \unexpanded\def\stoptextflow{\endgraf\egroup}} + {\let\stoptextflow\relax}} + +\def\flushtextflow#1% + {\doiftextflow{#1} + {\ifdim\ht\textflowcollector{#1}>\vsize + \setbox\scratchbox\vsplit\textflowcollector{#1} to \vsize + \unvbox\scratchbox + \else + \unvbox\textflowcollector{#1}% + \fi}} + +\protect \endinput + +% Example (dutch) +% +% \stelpapierformaatin [S6] +% \steltolerantiein [soepel,rek] +% \stelkleurenin [status=start] +% \stelvoetin [strut=nee] +% \stelwitruimtein [groot] +% +% \stellayoutin +% [rechterrand=5cm,breedte=passend,marge=0pt,randafstand=1cm, +% voet=4cm,voetafstand=1cm,hoofd=0cm] +% +% \stelteksttekstenin[rand][][\vbox{\flushtextflow{alpha}}] +% \stelvoettekstenin [rand][][\vbox{\flushtextflow{beta}}] +% \stelvoettekstenin [\vbox{\flushtextflow{gamma}}][] +% +% \definetextflow [alfa] [breedte=\rechterrandbreedte] +% \definetextflow [beta] [breedte=\rechterrandbreedte] +% \definetextflow [gamma] [breedte=\voethoogte] +% +% \starttekst +% +% \dorecurse{50} +% {\getrandomnumber{\funny}{0}{8} +% \ifcase\funny \starttextflow[alfa] \input tufte.tex \stoptextflow +% \or \starttextflow[beta] \input knuth.tex \stoptextflow +% \or \starttextflow[gamma] \input materie.tex \stoptextflow +% \or {\bf TUFTE}\quad \input tufte \par +% \or {\bf TUFTE}\quad \input tufte \par +% \or {\bf KNUTH}\quad \input knuth \par +% \or {\bf KNUTH}\quad \input knuth \par +% \or {\bf MATERIE}\quad \input materie \par +% \else {\bf MATERIE}\quad \input materie \par +% \fi} +% +% \stoptekst diff --git a/tex/context/base/page-imp.mkii b/tex/context/base/page-imp.mkii new file mode 100644 index 000000000..e4ece04a6 --- /dev/null +++ b/tex/context/base/page-imp.mkii @@ -0,0 +1,1314 @@ +%D \module +%D [ file=page-imp, % was: core-pag, +%D version=1998.01.15, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Pagebody Building (Imposition), +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% much of this can more to run time loading ! + +\writestatus{loading}{ConTeXt Page Macros / Pagebody Building} + +\unprotect + +% sizing bug: +% +% \setuppapersize[A4][A4,landscape] \setuparranging[2UP] \showframe +% +% \starttext \dorecurse{10}{\input tufte \par} \stoptext + +% to be moved code: + +\newif\ifclipprintbox \clipprintboxtrue +%newif\ifclippagebox \clippageboxtrue + +\def\clippedprintbox#1#2% can be made more efficient, see other clipper + {\ifclipprintbox + \!!widthc \pagebackgroundoffset + \!!widtha \dimexpr\paperwidth + \!!widthc\relax + \!!heighta\dimexpr\paperheight+2\!!widthc\relax + \setbox#2\vbox to \paperheight{\vfill\box#2}% + \ht#2\paperheight + \wd#2\paperwidth + \setbox#2\vbox + {\framed + [\c!offset=\!!widthc,\c!strut=\v!no,\c!frame=\v!off] + {\box#2}}% + \setbox#2\hbox to \paperwidth + {\ifcase#1\relax + \!!widthb\zeropoint + \hskip-\!!widthc + \else + \!!widthb\!!widthc + \fi + \lower\!!widthc\hbox + {\clip + [\c!width=\!!widtha,\c!height=\!!heighta, + \c!hoffset=\!!widthb,\c!voffset=\zeropoint] + {\box#2}}}% + \wd#2\paperwidth + \ht#2\paperheight + \fi + \box#2\relax} + +\let\clippagebox \gobbleoneargument +\let\clipprintbox\gobbleoneargument + +% \setuppagenumbering[alternative=doublesided] +% \setupcolors[state=start] +% \setuppapersize[A4][A4,oversized] +% \setuplayout[location=middle,clipoffset=5mm] +% \setupbackgrounds +% [page] +% [frame=on,rulethickness=1mm, +% backgroundoffset=10mm,background=color,backgroundcolor=red] +% \starttext \dorecurse{10}{\input tufte \par} \stoptext + +\def\clippagebox#1% + {\ifdim\@@lyclipoffset>\zeropoint + \!!widtha \wd#1% + \!!heighta\ht#1% + \!!deptha \dp#1% + \setbox#1\hbox + {\!!widthb \@@lyclipoffset + \advance\!!heighta\dimexpr\!!deptha+2\!!widthb\relax + \advance\!!widtha \!!widthb + \doifbothsides + {\advance\!!widtha\!!widthb \!!widthc-\!!widthb \hskip\!!widthc}% + {\!!widthc\zeropoint} + {\!!widthc-\!!widthb \hskip\!!widthc}% + \lower\!!widthb\hbox + {\clip + [\c!hoffset=\!!widthc, + \c!voffset=-\!!widthb, + \c!width=\!!widtha, + \c!height=\!!heighta]% + {\box#1}}}% + \wd#1\!!widtha + \ht#1\!!heighta + \dp#1\!!deptha + \fi} + +%D \macros +%D {starttextdata} +%D +%D This is a user macro (appending to every last shipout is not +%D really user friendly. + +\newtoks \collectedtextdata + +\long\def\starttextdata#1\stoptextdata + {\doglobal\appendtoks#1\to\collectedtextdata} + +\def\flushtextdata + {\vsmashed{\the\collectedtextdata}% all dimensions zero + \global\collectedtextdata\emptytoks + \globallet\flushtextdata\donothing} + +\prependtoks \flushtextdata \to \everylastshipout + +% 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 + \executeifdefined{\??pp:\c!method:\@@ppmethod}\gobbleoneargument{\thisisrealpage\realfolio#1}% + \gotonextrealpage + \aftershipout} + +\newbox\postponedcontent + +% \def\flushatshipout +% {\dowithnextbox +% {\global\setbox\postponedcontent\hbox to \zeropoint +% {%\hskip-\maxdimen % niet hier, gaat mis in acrobat (clipt) +% \box\postponedcontent\flushnextbox}% +% \global\ht\postponedcontent\zeropoint +% \global\dp\postponedcontent\zeropoint +% \global\wd\postponedcontent\zeropoint}% +% \hbox} + +\def\flushatshipout + {\dowithnextbox + {\global\setbox\postponedcontent\hbox to \zeropoint + {%\hskip-\maxdimen % niet hier, gaat mis in acrobat (clipt) + \unhbox\postponedcontent\unhbox\nextbox}% + \global\ht\postponedcontent\zeropoint + \global\dp\postponedcontent\zeropoint + \global\wd\postponedcontent\zeropoint}% + \hbox} + +% \starttypen +% \def\pagestoshipout{1,3,5} +% \stoptypen + +\newcount\shippedoutpages + +\let\pagestoshipout\empty % {1,3,6} +\chardef\whichpagetoshipout=0 % 0=all 1=odd 2=even + +\ifx\finalizeshipoutbox\undefined \let\finalizeshipoutbox\firstofoneargument \fi + +\def\actualshipout#1% + {\global\advance\shippedoutpages\plusone + % this is not resource safe! + \ifx\pagestoshipout\empty + \ifcase\whichpagetoshipout\relax + \donetrue + \or % 1 + \ifodd\shippedoutpages\relax\donetrue\else\donefalse\fi + \or % 2 + \ifodd\shippedoutpages\relax\donefalse\else\donetrue\fi + \else + \donetrue + \fi + \else % testen, aangepast / expanded nodig ? + \expanded{\doifinsetelse{\the\shippedoutpages}{\pagestoshipout}}% + \donetrue\donefalse + \fi + \ifdone + \shipout\vbox + {\forgetall + \offinterlineskip + \dontcomplain + \scratchdimen-1in + \vskip\scratchdimen + \hskip\scratchdimen + \hbox % \setbox0=\box.. is nicer + {\setbox0\hbox{\finalizeshipoutbox{#1}}% just in case there are objects there, hook for testing + \setbox\scratchbox\hbox + {% before the main one ! + \ifcase\realfolio \or + \the\everyfirstshipout + \global\everyfirstshipout\emptytoks + \fi + % the main one + \the\everyshipout\relax + % always last (and after the main one) + \ifnum\realpageno=\lastpage\relax + \the\everylastshipout + \global\everylastshipout\emptytoks + \fi}% + \smashbox\scratchbox + \box\scratchbox + \box\postponedcontent % evt ver naar links ! + \box0}}% + \else + \message + {[\ifarrangingpages arranged \fi page + \ifarrangingpages\the\arrangeno\else\the\realpageno\fi\normalspace + not flushed]}% + \setbox0\hbox{#1}% + \deadcycles\zerocount + \fi} + +\def\actualarrange#1% + {\setbox0\hbox{\thisisrealpage{\realfolio}#1}% + \pusharrangedpage0% + \deadcycles\zerocount} + +%D We need a couple of boxes for duplex printing \unknown + +\newbox\arrangedpageA \newbox\arrangedpageB + +%D \unknown\ and some for simulating big sheets. + +\newbox\arrangedpageC \newbox\arrangedpageD +\newbox\arrangedpageE \newbox\arrangedpageF +\newbox\arrangedpageG \newbox\arrangedpageH + +\newif\ifswaparranged +\newif\ifnegatearranged +\newif\ifmirrorarranged +\newif\ifdoublearranged + +\newif\ifarrangingdisabled + +\def\arrangedrotationO{0} +\def\arrangedrotationE{0} + +\newcounter\arrangedpageN +\newcounter\arrangedpageM + +\chardef\arrangedpageT=1 +\chardef\arrangedpageX=1 +\chardef\arrangedpageY=1 + +\def\calculatepaperoffsets#1% + {\scratchdimen\getvalue{\??pp#1\c!offset}% + \divide\scratchdimen \arrangedpageX + \global\advance\paperwidth -2\scratchdimen + \scratchdimen\getvalue{\??pp#1\c!offset}% + \divide\scratchdimen \arrangedpageY + \global\advance\paperheight-2\scratchdimen} + +\newconditional\arrangedbackgroundokay % more ifs -> conditionals + +\def\setuparranging[#1]% + {\ifarrangingdisabled \else + \doifelse{#1}\v!disable + {\global\arrangingdisabledtrue} + {\global\arrangingdisabledfalse}% + \global\arrangingpagestrue + \global\negatearrangedfalse + \global\mirrorarrangedfalse + \global\doublearrangedfalse + \gdef\arrangedrotationO{0}% + \gdef\arrangedrotationE{180}% + \processallactionsinset + [#1] + [ \v!mirrored=>\global\mirrorarrangedtrue, + \v!doublesided=>\global\doublearrangedtrue, + \v!negative=>\global\negatearrangedtrue, + \v!rotated=>\gdef\arrangedrotationO {90}\gdef\arrangedrotationE{270}, + 90=>\gdef\arrangedrotationO {90}\gdef\arrangedrotationE{270}, + 180=>\gdef\arrangedrotationO{180}\gdef\arrangedrotationE{0}, + 270=>\gdef\arrangedrotationO{270}\gdef\arrangedrotationE{90}, + \s!reset=>\global\arrangingpagesfalse, + \v!background=>\global\settrue\arrangedbackgroundokay, + \s!unknown=>\checkinstalledpagearrangement\commalistelement]% + % no \s!default=> we can have aaa,,bbb + \ifx\handlearrangedpage\undefined + \global\arrangingpagesfalse + \fi + \doifcommonelse{#1}{90,270,\v!rotated} + {\swapmacros\horizontalcutmarks\verticalcutmarks}{}% ugly solution + \setuppapersize + \ifarrangingpages + \abortutilitygeneration + \fi + \fi} + +\def\installpagearrangement #1 % + {\setgvalue{\??pp\??pp#1}} + +\def\checkinstalledpagearrangement#1% can be empty: aaa,,bbb + {\executeifdefined{\??pp\??pp#1}\donothing} + +\def\dosetuparrangement#1#2#3#4#5#6#7#8% + {\global\chardef\arrangedpageX #1% + \global\chardef\arrangedpageY #2% + \global\chardef\arrangedpageT #3% + \global\chardef\horizontalcutmarks#4% + \global\chardef\verticalcutmarks #5% + \global\let \pusharrangedpage #6% + \global\let \poparrangedpages #7% + \global\let \handlearrangedpage#8} + +\installpagearrangement {\v!normal} + {\global\arrangingpagesfalse} + +\installpagearrangement 2*16 + {\dosetuparrangement{4}{4}{16}{5}{5}% + \pusharrangedpageTHIRTYTWO\poparrangedpagesAB\relax} + +\installpagearrangement 2*8 + {\dosetuparrangement{4}{2}{8}{5}{3}% + \pusharrangedpageSIXTEEN\poparrangedpagesAB\relax} + +\installpagearrangement 2*4 + {\dosetuparrangement{2}{2}{4}{3}{3}% + \pusharrangedpageEIGHT\poparrangedpagesAB\relax} + +\installpagearrangement 2*2 + {\dosetuparrangement{2}{1}{2}{3}{2}% + \pusharrangedpageFOURA\poparrangedpagesAB\relax} + +\installpagearrangement 2**2 + {\dosetuparrangement{2}{1}{2}{3}{2}% + \pusharrangedpageFOURB\poparrangedpagesAB\relax} + +\installpagearrangement 2SIDE + {\dosetuparrangement{2}{1}{2}{3}{2}% + \pusharrangedpageSIDETOP\poparrangedpagesTWO\handlearrangedpageSIDE} + +\installpagearrangement 2TOP + {\dosetuparrangement{1}{2}{2}{2}{3}% + \pusharrangedpageSIDETOP\poparrangedpagesTWO\handlearrangedpageTOP} + +\installpagearrangement 2UP + {\dosetuparrangement{2}{1}{4}{3}{2}% + \pusharrangedpageTWO\poparrangedpagesTWO\handlearrangedpageTWOUP} + +\installpagearrangement 2DOWN + {\dosetuparrangement{1}{2}{4}{2}{3}% + \pusharrangedpageTWO\poparrangedpagesTWO\handlearrangedpageTWODOWN} + +\installpagearrangement 2*4*2 % one defined by Willy Egger: + {\dosetuparrangement{2}{2}{4}{3}{2}% + \pusharrangedpageSIXTEENTWO\poparrangedpagesAtoD\relax} + +\installpagearrangement 2*2*4 % onother one of Willy Egger + {\dosetuparrangement{2}{1}{8}{3}{2}% + \pusharrangedpageSIXTEENFOUR\poparrangedpagesAtoH\relax} + +\installpagearrangement 2TOPSIDE + {\dosetuparrangement{1}{2}{4}{2}{3}% + \pusharrangedpageTWOTOPSIDE\poparrangedpagesTWOTOPSIDE\handlearrangedpageTOP} + +% \def\filluparrangedpages % beware: \realpageno is 1 ahead +% {\ifarrangingpages +% \scratchcounter-\realpageno +% \divide\scratchcounter \arrangedpageT +% \multiply\scratchcounter \arrangedpageT +% \advance\scratchcounter \realpageno +% \advance\scratchcounter \minusone +% \dorecurse\scratchcounter{\noheaderandfooterlines\ejectdummypage}% +% \fi} + +\def\filluparrangedpages % beware: \realpageno is 1 ahead + {\ifarrangingpages + \scratchcounter\numexpr\realpageno-\plusone\relax + \dosetmodulo\scratchcounter\arrangedpageT\scratchcounter + \ifcase\scratchcounter\else + \advance\scratchcounter \plusone + \dostepwiserecurse\scratchcounter\arrangedpageT\plusone + {\noheaderandfooterlines\ejectdummypage}% + \fi + \fi} + +\def\handlearrangedpageXandY#1#2#3#4#5% + {\global\setbox#5\hbox to \arrangedpageX\paperwidth + {\setbox\scratchbox\vbox to \arrangedpageY\paperheight + {\forgetall + \offinterlineskip + \dontcomplain + \vskip#4\paperheight + \hskip#3\paperwidth + \dorotatebox{\ifcase#2 0\else180\fi}\hbox{\box#1}% + \vfill}% + \wd\scratchbox\zeropoint + \box\scratchbox\box#5\hss}} + +\def\gotonextarrangepage + {\global\advance\arrangeno \plusone + \def\pagecutmarksymbol{\the\arrangeno}} + +\def\outputarrangedbox#1% + {\bgroup + \gotonextarrangepage + \ifnum\arrangedrotationO\arrangedrotationE>\zerocount + \setbox#1\vbox + {\ifdoublearranged + \ifodd\arrangeno + \dorotatebox\arrangedrotationO\hbox{\box#1}% + \else + \dorotatebox\arrangedrotationE\hbox{\box#1}% + \fi + \else + \dorotatebox\arrangedrotationO\hbox{\box#1}% + \fi}% + \fi + \ifmirrorarranged + \setbox#1\vbox{\domirrorbox\vbox{\box#1}}% + \fi + \ifnegatearranged + \negatecolorbox{#1}% + \fi + \finishpagebox#1% + \ifconditional\arrangedbackgroundokay\addprintbackground#1\fi + \actualshipout{\box#1}% + \egroup} + +%D The format file can be 16K smaller when we postpone the +%D real arrangments. Some day ... + +% TOP + +% 32/16/8/4/SIDE + +\def\poparrangedpagesAB + {\ifnum\arrangedpageN>\zerocount + \dontcomplain + \paperwidth\arrangedpageX\paperwidth + \paperheight\arrangedpageY\paperheight + \outputarrangedbox\arrangedpageA + \outputarrangedbox\arrangedpageB + \doglobal\newcounter\arrangedpageN + \fi} + +\def\pusharrangedpageTHIRTYTWO#1% taco's challenge + {\doglobal\increment\arrangedpageN + \reportarrangedpage\arrangedpageN + \ifcase\arrangedpageN + \or \handlearrangedpageXandY{#1}033\arrangedpageA % 1 + \or \handlearrangedpageXandY{#1}003\arrangedpageB % 2 + \or \handlearrangedpageXandY{#1}100\arrangedpageB % 3 + \or \handlearrangedpageXandY{#1}130\arrangedpageA % 4 + \or \handlearrangedpageXandY{#1}100\arrangedpageA % 5 + \or \handlearrangedpageXandY{#1}130\arrangedpageB % 6 + \or \handlearrangedpageXandY{#1}033\arrangedpageB % 7 + \or \handlearrangedpageXandY{#1}003\arrangedpageA % 8 + \or \handlearrangedpageXandY{#1}102\arrangedpageA % 9 + \or \handlearrangedpageXandY{#1}132\arrangedpageB % 10 + \or \handlearrangedpageXandY{#1}031\arrangedpageB % 11 + \or \handlearrangedpageXandY{#1}001\arrangedpageA % 12 + \or \handlearrangedpageXandY{#1}031\arrangedpageA % 13 + \or \handlearrangedpageXandY{#1}001\arrangedpageB % 14 + \or \handlearrangedpageXandY{#1}102\arrangedpageB % 15 + \or \handlearrangedpageXandY{#1}132\arrangedpageA % 16 + \or \handlearrangedpageXandY{#1}122\arrangedpageA % 17 + \or \handlearrangedpageXandY{#1}112\arrangedpageB % 18 + \or \handlearrangedpageXandY{#1}011\arrangedpageB % 19 + \or \handlearrangedpageXandY{#1}021\arrangedpageA % 20 + \or \handlearrangedpageXandY{#1}011\arrangedpageA % 21 + \or \handlearrangedpageXandY{#1}021\arrangedpageB % 22 + \or \handlearrangedpageXandY{#1}122\arrangedpageB % 23 + \or \handlearrangedpageXandY{#1}112\arrangedpageA % 24 + \or \handlearrangedpageXandY{#1}013\arrangedpageA % 25 + \or \handlearrangedpageXandY{#1}023\arrangedpageB % 26 + \or \handlearrangedpageXandY{#1}120\arrangedpageB % 27 + \or \handlearrangedpageXandY{#1}110\arrangedpageA % 28 + \or \handlearrangedpageXandY{#1}120\arrangedpageA % 29 + \or \handlearrangedpageXandY{#1}110\arrangedpageB % 30 + \or \handlearrangedpageXandY{#1}013\arrangedpageB % 31 + \or \handlearrangedpageXandY{#1}023\arrangedpageA % 32 + \poparrangedpages + \fi} + +\def\pusharrangedpageSIXTEEN#1% changed to match the official way of doing + {\doglobal\increment\arrangedpageN + \reportarrangedpage\arrangedpageN + \ifcase\arrangedpageN + \or \handlearrangedpageXandY{#1}031\arrangedpageA % 1 + \or \handlearrangedpageXandY{#1}001\arrangedpageB % 2 + \or \handlearrangedpageXandY{#1}031\arrangedpageB % 3 + \or \handlearrangedpageXandY{#1}001\arrangedpageA % 4 + \or \handlearrangedpageXandY{#1}100\arrangedpageA % 5 + \or \handlearrangedpageXandY{#1}130\arrangedpageB % 6 + \or \handlearrangedpageXandY{#1}100\arrangedpageB % 7 + \or \handlearrangedpageXandY{#1}130\arrangedpageA % 8 + \or \handlearrangedpageXandY{#1}120\arrangedpageA % 9 + \or \handlearrangedpageXandY{#1}110\arrangedpageB % 10 + \or \handlearrangedpageXandY{#1}120\arrangedpageB % 11 + \or \handlearrangedpageXandY{#1}110\arrangedpageA % 12 + \or \handlearrangedpageXandY{#1}011\arrangedpageA % 13 + \or \handlearrangedpageXandY{#1}021\arrangedpageB % 14 + \or \handlearrangedpageXandY{#1}011\arrangedpageB % 15 + \or \handlearrangedpageXandY{#1}021\arrangedpageA % 16 + \poparrangedpages + \fi} + +\def\pusharrangedpageEIGHT#1% changed to match the official way of doing + {\doglobal\increment\arrangedpageN + \reportarrangedpage\arrangedpageN + \ifcase\arrangedpageN + \or \handlearrangedpageXandY{#1}011\arrangedpageA % 1 + \or \handlearrangedpageXandY{#1}001\arrangedpageB % 2 + \or \handlearrangedpageXandY{#1}100\arrangedpageB % 3 + \or \handlearrangedpageXandY{#1}110\arrangedpageA % 4 + \or \handlearrangedpageXandY{#1}100\arrangedpageA % 5 + \or \handlearrangedpageXandY{#1}110\arrangedpageB % 6 + \or \handlearrangedpageXandY{#1}011\arrangedpageB % 7 + \or \handlearrangedpageXandY{#1}001\arrangedpageA % 8 + \poparrangedpages + \fi} + +\def\pusharrangedpageFOURA{\pusharrangedpageFOURdo01} +\def\pusharrangedpageFOURB{\pusharrangedpageFOURdo10} + +\def\pusharrangedpageFOURdo#1#2#3% + {\doglobal\increment\arrangedpageN + \reportarrangedpage\arrangedpageN + \ifcase\arrangedpageN + \or \handlearrangedpageXandY{#3}010\arrangedpageA % 1 + \or \handlearrangedpageXandY{#3}0{#1}0\arrangedpageB % 2/3 not {1} + \or \handlearrangedpageXandY{#3}0{#2}0\arrangedpageB % 3/2 not {1} + \or \handlearrangedpageXandY{#3}000\arrangedpageA % 4 + \poparrangedpages + \fi} + +\def\pusharrangedpageSIDETOP#1% + {\doglobal\increment\arrangedpageN + \reportarrangedpage\arrangedpageN + \ifcase\arrangedpageN + \or \handlearrangedpageXandY{#1}000\arrangedpageA % 1 + \or \handlearrangedpageXandY{#1}000\arrangedpageB % 2 + \poparrangedpages + \fi} + +\def\handlearrangedpageSIDE + {\global\wd\arrangedpageA\paperwidth + \global\wd\arrangedpageB\paperwidth + \global\setbox\arrangedpageA\hbox + {\box\arrangedpageA\box\arrangedpageB}% + \global\ht\arrangedpageA\paperheight} + +\def\handlearrangedpageTOP + {\global\ht\arrangedpageA\paperheight + \global\ht\arrangedpageB\paperheight + \global\setbox\arrangedpageA\vbox + {\forgetall\offinterlineskip\vskip\paperheight + \box\arrangedpageA\box\arrangedpageB}% + \global\setbox\arrangedpageB\box\scratchbox} % ? + +% 2UP/2DOWN / 1pt prevents overflow + +\def\splitoffarrangedpagesTWO + {\splittopskip\zeropoint + \global\setbox\arrangedpageA\vsplit\arrangedpageB to \onepoint + \scratchdimen\dimexpr\ht\arrangedpageB-\onepoint\relax + \ifdim\scratchdimen>\onepoint + \setbox\scratchbox\vsplit\arrangedpageB to \scratchdimen + \fi} + +\def\handlearrangedpageTWOUP + {\splitoffarrangedpagesTWO + \ifswaparranged + \global\setbox\arrangedpageA\hbox + {\clippedprintbox0\arrangedpageA + \clippedprintbox1\arrangedpageB}% + \swaparrangedfalse + \else + \global\setbox\arrangedpageA\hbox + {\clippedprintbox0\arrangedpageB + \clippedprintbox1\arrangedpageA}% + \swaparrangedtrue + \fi + \global\ht\arrangedpageA\paperheight + \global\setbox\arrangedpageB\box\scratchbox} + +\def\handlearrangedpageTWODOWN + {\splitoffarrangedpagesTWO + \global\ht\arrangedpageA\paperheight + \global\ht\arrangedpageB\paperheight + \ifswaparranged + \global\setbox\arrangedpageA\vbox + {\forgetall\offinterlineskip\vskip\paperheight + \box\arrangedpageA\box\arrangedpageB}% + \swaparrangedfalse + \else + \global\setbox\arrangedpageA\vbox + {\forgetall\offinterlineskip\vskip\paperheight + \box\arrangedpageB\box\arrangedpageA}% + \swaparrangedtrue + \fi + \global\setbox\arrangedpageB\box\scratchbox} + +\def\poparrangedpagesTWO + {\ifnum\arrangedpageN>\zerocount + \dontcomplain + \swaparrangedfalse + \doloop + {\handlearrangedpage + \bgroup + \paperwidth\arrangedpageX\paperwidth + \paperheight\arrangedpageY\paperheight + \ht\arrangedpageA\paperheight + \wd\arrangedpageA\paperwidth + \outputarrangedbox\arrangedpageA + \egroup + \ifdim\ht\arrangedpageB=\zeropoint + \exitloop + \fi}% + \doglobal\newcounter\arrangedpageN + \fi} + +\def\pusharrangedpageTWO#1% + {\doglobal\increment\arrangedpageN + \reportarrangedpage\arrangedpageN + \global\setbox\arrangedpageB\vbox + {\forgetall + \offinterlineskip + \unvbox\arrangedpageB + \allowbreak + \ht#1\onepoint + \dp#1\zeropoint + \vbox{\box#1}}} + +\def\poparrangedpagesTWOTOPSIDE + {\ifnum\arrangedpageN>\zerocount + \bgroup + \gdef\arrangedpageN{2}\poparrangedpagesTWO + \let\arrangedpageA\arrangedpageC + \let\arrangedpageB\arrangedpageD + \gdef\arrangedpageN{2}\poparrangedpagesTWO + \doglobal\newcounter\arrangedpageN + \egroup + \fi} + +\def\pusharrangedpageTWOTOPSIDE#1% + {\doglobal\increment\arrangedpageN + \reportarrangedpage\arrangedpageN + \ifcase\arrangedpageN + \or \handlearrangedpageXandY{#1}000\arrangedpageA % 1 + \or \handlearrangedpageXandY{#1}000\arrangedpageC % 2 + \or \handlearrangedpageXandY{#1}000\arrangedpageB % 1 + \or \handlearrangedpageXandY{#1}000\arrangedpageD % 2 + \poparrangedpages + \fi} + +%D Willy Egger's sheet simulations: + +\def\poparrangedpagesAtoH + {\ifnum\arrangedpageN>\zerocount + \dontcomplain + \paperwidth\arrangedpageX\paperwidth + \paperheight\arrangedpageY\paperheight + \outputarrangedbox\arrangedpageA + \outputarrangedbox\arrangedpageB + \outputarrangedbox\arrangedpageC + \outputarrangedbox\arrangedpageD + \outputarrangedbox\arrangedpageE + \outputarrangedbox\arrangedpageF + \outputarrangedbox\arrangedpageG + \outputarrangedbox\arrangedpageH + \doglobal\newcounter\arrangedpageN + \fi} + +% to arrange 16 pages on 2 sheets to form one booklet + +\def\poparrangedpagesAtoD + {\ifnum\arrangedpageN>\zerocount + \dontcomplain + \paperwidth\arrangedpageX\paperwidth + \paperheight\arrangedpageY\paperheight + \outputarrangedbox\arrangedpageA + \outputarrangedbox\arrangedpageB + \outputarrangedbox\arrangedpageC + \outputarrangedbox\arrangedpageD + \doglobal\newcounter\arrangedpageN + \fi} + +% to arrange 16 pages on 4 sheets to form one booklet + +\def\pusharrangedpageSIXTEENFOUR#1% + {\doglobal\increment\arrangedpageN + \reportarrangedpage\arrangedpageN + \ifcase\arrangedpageN + \or \handlearrangedpageXandY{#1}010\arrangedpageA % 1 + \or \handlearrangedpageXandY{#1}000\arrangedpageB % 2 + \or \handlearrangedpageXandY{#1}010\arrangedpageC % 3 + \or \handlearrangedpageXandY{#1}000\arrangedpageD % 4 + \or \handlearrangedpageXandY{#1}010\arrangedpageE % 5 + \or \handlearrangedpageXandY{#1}000\arrangedpageF % 6 + \or \handlearrangedpageXandY{#1}010\arrangedpageG % 7 + \or \handlearrangedpageXandY{#1}000\arrangedpageH % 8 + \or \handlearrangedpageXandY{#1}010\arrangedpageH % 9 + \or \handlearrangedpageXandY{#1}000\arrangedpageG % 10 + \or \handlearrangedpageXandY{#1}010\arrangedpageF % 11 + \or \handlearrangedpageXandY{#1}000\arrangedpageE % 12 + \or \handlearrangedpageXandY{#1}010\arrangedpageD % 13 + \or \handlearrangedpageXandY{#1}000\arrangedpageC % 14 + \or \handlearrangedpageXandY{#1}010\arrangedpageB % 15 + \or \handlearrangedpageXandY{#1}000\arrangedpageA % 16 + \poparrangedpages + \fi} + +% to arrange 16 pages on 2 sheets to form one booklet + +\def\pusharrangedpageSIXTEENTWO#1% + {\doglobal\increment\arrangedpageN + \reportarrangedpage\arrangedpageN + \ifcase\arrangedpageN + \or \handlearrangedpageXandY{#1}011\arrangedpageA % 1 + \or \handlearrangedpageXandY{#1}001\arrangedpageB % 2 + \or \handlearrangedpageXandY{#1}011\arrangedpageC % 3 + \or \handlearrangedpageXandY{#1}001\arrangedpageD % 4 + \or \handlearrangedpageXandY{#1}100\arrangedpageD % 5 + \or \handlearrangedpageXandY{#1}110\arrangedpageC % 6 + \or \handlearrangedpageXandY{#1}100\arrangedpageB % 7 + \or \handlearrangedpageXandY{#1}110\arrangedpageA % 8 + \or \handlearrangedpageXandY{#1}100\arrangedpageA % 9 + \or \handlearrangedpageXandY{#1}110\arrangedpageB % 10 + \or \handlearrangedpageXandY{#1}100\arrangedpageC % 11 + \or \handlearrangedpageXandY{#1}110\arrangedpageD % 12 + \or \handlearrangedpageXandY{#1}011\arrangedpageD % 13 + \or \handlearrangedpageXandY{#1}001\arrangedpageC % 14 + \or \handlearrangedpageXandY{#1}011\arrangedpageB % 15 + \or \handlearrangedpageXandY{#1}001\arrangedpageA % 16 + \poparrangedpages + \fi} + +% % handy for stickers etc, this way we can treat them as page +% +% \setuppapersize [XY][A4] +% \setuppaper [topspace=5mm,backspace=5mm,dx=1mm,dy=1mm,nx=2,ny=6] +% \setuplayout [page] [topspace=5mm,backspace=5mm] +% \setuplayout [page] +% \setuplayout [location=middle] +% \setuparranging [XY] +% \showframe +% +% \starttext \dorecurse{30}{test \recurselevel \page} \stoptext + +\def\pusharrangedpageXY#1% + {\doglobal\increment\arrangedpageN + \reportarrangedpage\arrangedpageN + \doglobal\increment\arrangedpageM + \global\setbox\arrangedpageB\hbox + \ifdim\@@ppwidth>\zeropoint to \@@ppwidth \fi + {\ifvoid\arrangedpageB\else + \unhbox\arrangedpageB + \ifdim\@@ppdx>\zeropoint \else \hss\fi + \hskip\@@ppdx + \ifdim\@@ppdx>\zeropoint \else \hss\fi + \fi + \box#1}% + \ifnum\arrangedpageM<\arrangedpageX\else + \global\setbox\arrangedpageA\vbox + \ifdim\@@ppheight>\zeropoint to \@@ppheight \fi + {\offinterlineskip + \ifvoid\arrangedpageA\else + \unvbox\arrangedpageA + \ifdim\@@ppdy>\zeropoint \else \vss\fi + \vskip\@@ppdy + \ifdim\@@ppdy>\zeropoint \else \vss\fi + \fi + \box\arrangedpageB}% + \doglobal\newcounter\arrangedpageM + \fi + \ifnum\arrangedpageN<\arrangedpageT\else + \poparrangedpages + \fi} + +\def\poparrangedpagesXY + {\ifnum\arrangedpageN>\zerocount + \dontcomplain + \paperwidth\arrangedpageX\paperwidth + \paperheight \arrangedpageY\paperheight + \outputarrangedbox\arrangedpageA + \doglobal\newcounter\arrangedpageN + \doglobal\newcounter\arrangedpageM + \fi} + +\installpagearrangement XY + {\dosetuparrangement\@@ppnx\@@ppny\@@ppxy\!!zerocount\!!zerocount + \pusharrangedpageXY\poparrangedpagesXY\relax} + +%D A crazy definition, don't guess who pushed me for the landscape option. + +\definepapersize + [XY] + [\c!height=\dimexpr\dimexpr\@@ppheight-\numexpr\@@ppny-1\relax\dimexpr\@@ppdy\relax\relax/\@@ppny\relax, + \c!width =\dimexpr\dimexpr\@@ppwidth -\numexpr\@@ppnx-1\relax\dimexpr\@@ppdx\relax\relax/\@@ppnx\relax] + +\setuppaper + [\c!width =\dimexpr\printpaperwidth -2\dimexpr\@@ppbackspace\relax\relax, + \c!height=\dimexpr\printpaperheight-2\dimexpr\@@pptopspace \relax\relax] + +% \definepageshift[test][horizontal][10pt,20pt,30pt,40pt,50pt] +% \definepageshift[test][vertical] [10pt,20pt,30pt,40pt,50pt] +% +% \setuppageshift[test] +% \setuppageshift[test][test] +% \setuppageshift[test][none] +% \setuppageshift[none][test] +% \setuppageshift[paper][test][test] % arrange only +% \setuppageshift[paper][test] % arrange only +% \setuppageshift[print][test][test] +% +% \showframe \dorecurse{100}{\input tufte \par} + +% #1=name #2=horizontal|vertical #3=shiftlist + +\def\definepageshift + {\dotripleargument\dodefinepageshift} + +\def\dodefinepageshift[#1][#2][#3]% + {\setvalue{\??pt#2:#1}{#3}} + +\letempty \hpageshifts \newcounter\nofhpageshifts +\letempty \vpageshifts \newcounter\nofvpageshifts + +% \let\shiftprintpagebox\gobbleoneargument +% \let\shiftpaperpagebox\gobbleoneargument + +\def\dogetpageshift#1#2#3% #1=\dimenx #2=\xpageshifts #3=\nofxpageshifts + {\ifx#2\empty + #1\zeropoint + \else + \doglobal\increment#3% + \getfromcommacommand[#2][#3]% + \ifx\commalistelement\empty + \globallet#3\!!plusone + \getfromcommacommand[#2][#3]% + \fi + \ifx\commalistelement\empty + #1\zeropoint + \else + #1=\commalistelement + \donetrue + \fi + \fi} + +\def\shiftpagebox#1% + {\donefalse + \dogetpageshift{\dimen0}\hpageshifts\nofhpageshifts + \dogetpageshift{\dimen2}\vpageshifts\nofvpageshifts + \ifdone % see also layout offsets, maybe \movebox + \edef\next{\wd#1\the\wd#1\ht#1\the\ht#1\dp#1\the\dp#1}% + \setbox#1\vbox % \forgetall already done + {\offinterlineskip\vskip\dimen2\hskip\dimen0\box#1}% + \next + \fi} + +\def\setuppageshift + {\dotripleempty\dosetuppageshift} + +\def\dosetuppageshift[#1][#2][#3]% page|paper horizontal vertical + {\ifthirdargument % paper=arrange + \let\hpageshifts\empty + \let\vpageshifts\empty + \let\shiftprintpagebox\gobbleoneargument + \let\shiftpaperpagebox\gobbleoneargument + \doifdefined{\??pt\v!horizontal:#2} + {\edef\hpageshifts{\getvalue{\??pt\v!horizontal:#2}}}% + \doifdefined{\??pt\v!vertical :#3} + {\edef\vpageshifts{\getvalue{\??pt\v!vertical :#3}}}% + \doif{#1}\v!page{\let\shiftprintpagebox\shiftpagebox}% + \doif{#1}\v!paper{\let\shiftpaperpagebox\shiftpagebox}% + \else\ifsecondargument + \doifinsetelse{#1}{\v!page,\v!paper} + {\setuppageshift[#1][#2][#2]} + {\setuppageshift[\v!page][#1][#2]}% + \else\iffirstargument + \setuppageshift[\v!page][#1][#1]% + \fi\fi\fi} + +%D One can (mis)use this mechanism, in close cooperation +%D with \PDFTEX\ to arrange pages of already produced files. +%D +%D \starttyping +%D \insertpages[file.pdf][1,3][n=30,width=18cm] +%D \stoptyping +%D +%D The pages are inserted in the text area, and even pages +%D are repositioned according to the width. In this example +%D empty pages are added after page 1 and 3. +%D +%D Selecting pages can be accomplished by: +%D +%D \starttyping +%D \filterpages[file.pdf][1,3,5][n=30,width=18cm] +%D \stoptyping +%D +%D One may pass \type {odd} or \type {even} instead of a +%D comma separated list. A third alternative is: +%D +%D \starttyping +%D \copypages[file.pdf][n=30,scale=950] +%D \stoptyping +%D +%D This macros inserts the page, according to the settings +%D provided. + +\def\insertpages + {\dotripleempty\doinsertpages} + +\def\doinsertpages[#1][#2][#3]% + {\doifassignmentelse{#2} + {\dodoinsertpages[#1][][#2]} + {\dodoinsertpages[#1][#2][#3]}} + +\def\dodoinsertpages[#1][#2][#3]% + {\bgroup + \dontcomplain + \getfiguredimensions[#1]% + \getparameters[\??ip][\c!n=\noffigurepages,\c!width=\!!zeropoint,#3]% + \doifinset0{#2}{\null\page}% + \dorecurse\@@ipn + {\dofilterpage{#1}\recurselevel + \doifinset\recurselevel{#2}{\null\page}}% + \egroup} + +\def\filterpages + {\dotripleempty\dofilterpages} + +\def\dofilterpages[#1][#2][#3]% % \noffigurepages not yet supported + {\bgroup + \dontcomplain + \getfiguredimensions[#1]% + \getparameters[\??ip][\c!n=\noffigurepages,\c!width=\!!zeropoint,#3]% + \doifelse{#2}\v!even + {\dorecurse\@@ipn + {\ifodd\recurselevel\relax\else\dofilterpage{#1}\recurselevel\fi}} + {\doifelse{#2}\v!odd + {\dorecurse\@@ipn + {\ifodd\recurselevel\relax\dofilterpage{#1}\recurselevel\fi}} + {\def\dodocommand##1% + {\ifnum##1>\@@ipn\else\dofilterpage{#1}{##1}\fi}% + \def\docommand##1% + {\dowithrange{##1}\dodocommand}% + \processcommalist[#2]\docommand}}% + \egroup} + +\def\dofilterpage#1#2% + {\hbox to \textwidth + {\ifdoublesided\ifdim\@@ipwidth>\zeropoint\relax\ifodd\realpageno\else + \hfill + \def\dowithfigure{\hskip-\@@ipwidth}% + \fi\fi\fi + \setbox0\hbox + {\externalfigure[#1][\c!page=#2,\c!height=\textheight]}% + \wd0\zeropoint + \box0} + \page} + +\def\copypages + {\dodoubleempty\docopypages} + +\def\docopypages[#1][#2]% + {\bgroup + \getfiguredimensions[#1]% + \getparameters[\??ip] + [\c!n=\noffigurepages, + \c!marking=\v!off, + \c!scale=\!!thousand, + \c!offset=\!!zeropoint, + #2]% + \dorecurse\@@ipn + {\vbox to \textheight + {\hsize\textwidth + \scratchdimen\@@ipoffset + \centeredbox + {\doifelse\@@ipmarking\v!on\cuthbox\hbox + {\ifdim\scratchdimen>\zeropoint\relax + \advance\vsize -2\scratchdimen + \advance\hsize -2\scratchdimen + \externalfigure[#1][\c!page=\recurselevel,#2,\c!scale=,\c!factor=\v!max,\c!offset=\v!overlay]% + \else + \externalfigure[#1][\c!page=\recurselevel,#2,\c!offset=\v!overlay]% + \fi}}} + \page} + \egroup} + +%D \macros +%D {combinepages} +%D +%D Yet another way of postprocessing is handles by \type +%D {\combinepages}. This macro builds a matrix of pages from a +%D file, for example: +%D +%D \starttyping +%D \setuppapersize +%D [A4][A4] % or [A4,landscape][A4,landscape] +%D +%D \setuplayout +%D [header=0pt,footer=1cm, +%D backspace=1cm,topspace=1cm, +%D width=middle,height=middle] +%D +%D \setupfootertexts +%D [presentation---\currentdate\space---\space\pagenumber] +%D +%D \starttext +%D \combinepages[slides][nx=2,ny=3,frame=on] +%D \stoptext +%D \stoptyping +%D +%D One can influence the way the pages are combined. (This +%D will be explained some time.) + +\def\combinepages + {\dodoubleempty\docombinepages} + +\def\docombinepages[#1][#2]% a=perpag b=free + {\bgroup + \dontcomplain + \getfiguredimensions[#1]% + \getparameters + [\??ip] + [\c!alternative=\v!a, + \c!n=\noffigurepages,\c!nx=2,\c!ny=2,\c!start=1,\c!stop=\!!maxcard, + \c!distance=\bodyfontsize, + \c!bottom=\vfill,\c!top=\vss, + \c!left=\hss,\c!right=\hss, + \c!before=\page,\c!after=\page,\c!inbetween=\blank, + \c!frame=,\c!background=,\c!backgroundcolor=, + #2]% + \def\@@ipname{#1}% + \@@ipbefore + \executeifdefined{\strippedcsname\docombinepages\@@ipalternative}\docombinepagesb + \@@ipafter + \egroup} + +\def\docombinepagesa + {\globallet\combinedpagescounter\@@ipstart + \doloop + {\vbox to \textheight + {\hsize\textwidth % ? ? + \scratchdimen\@@ipdistance + \!!widtha \dimexpr(\hsize-\@@ipnx\scratchdimen+\scratchdimen)/\@@ipnx\relax + \!!heighta\dimexpr(\vsize-\@@ipny\scratchdimen+\scratchdimen)/\@@ipny\relax + \dorecurse\@@ipny + {\hbox to \hsize + {\dorecurse\@@ipnx + {\vbox to \!!heighta + {\hsize\!!widtha + \vsize\!!heighta + \@@iptop + \hbox to \hsize + {\@@ipleft + \ifnum\combinedpagescounter>\@@ipstop\relax + \globallet\@@ipn\!!zerocount + \else\ifnum\combinedpagescounter>\@@ipn \else + \externalfigure[\@@ipname] + [\c!object=\v!no, + \c!page=\combinedpagescounter, + \c!factor=\v!max, + \c!background=\@@ipbackground, + \c!backgroundcolor=\@@ipbackgroundcolor, + \c!frame=\@@ipframe]% + \fi\fi + \@@ipright} + \@@ipbottom}% + \doglobal\increment\combinedpagescounter + \hfil}% + \hfilneg} + \vfil}% + \vfilneg}% + \page + \ifnum\combinedpagescounter>\@@ipn \exitloop\fi}} + +\def\docombinepagesc + {\globallet\combinedpagescounter\@@ipstart + \doloop + {\vbox to \textheight + {\hsize\textwidth % ? ? + \scratchdimen\@@ipdistance + \!!widtha \dimexpr(\hsize-\@@ipnx\scratchdimen+\scratchdimen)/\@@ipnx\relax + \!!heighta\dimexpr(\vsize-\@@ipny\scratchdimen+\scratchdimen)/\@@ipny\relax + \hbox to \hsize + {\dorecurse\@@ipnx + {\@@ipleft + \vbox to \textheight + {\hsize\!!widtha + {\dorecurse\@@ipny + {\@@iptop + \hbox to \hsize + {\vbox to \!!heighta + {\hsize\!!widtha + \vsize\!!heighta + \ifnum\combinedpagescounter>\@@ipstop\relax + \globallet\@@ipn\!!zerocount + \else\ifnum\combinedpagescounter>\@@ipn \else + \externalfigure[\@@ipname] + [\c!object=\v!no, + \c!page=\combinedpagescounter, + \c!factor=\v!max, + \c!background=\@@ipbackground, + \c!backgroundcolor=\@@ipbackgroundcolor, + \c!frame=\@@ipframe]% + \fi\fi}} + \doglobal\increment\combinedpagescounter + \@@ipbottom}% + \vfil}% + \vfilneg} + \hfil}% + \hfilneg}} + \page + \ifnum\combinedpagescounter>\@@ipn \exitloop\fi}} + +\let\docombinepageshorizontal\docombinepagesa +\let\docombinepagesvertical \docombinepagesc + +\def\docombinepagesb + {\globallet\combinedpagescounter\@@ipstart + \doloop + {\startbaselinecorrection + \scratchdimen\@@ipdistance + \!!widtha\dimexpr(\hsize-\@@ipnx\scratchdimen+\scratchdimen)/\@@ipnx\relax + \hbox to \hsize + {\dorecurse\@@ipnx + {\doglobal\increment\combinedpagescounter + \ifnum\combinedpagescounter>\@@ipn \else + \expanded{\externalfigure[\@@ipname] + [\c!page=\combinedpagescounter, + \c!width=\the\!!widtha,% todo \freezedimenmacro + \c!background=\@@ipbackground, + \c!backgroundcolor=\@@ipbackgroundcolor, + \c!frame=\@@ipframe]}% + \hfill + \fi}\hfillneg}% + \stopbaselinecorrection + \ifnum\combinedpagescounter<\@@ipn\relax + \@@ipinbetween + \else + \exitloop + \fi}} + +%D \macros +%D {setuppagecomment,startpagecomment} +%D +%D This command is not yet documented. Usage: +%D +%D \starttyping +%D \setuppagecomment[state=start,location=right] +%D +%D \startpagecomment +%D \input knuth +%D \stoppagecomment +%D \stoptyping + +\def\setuppagecomment + {\dosingleempty\dosetuppagecomment} + +\def\dosetuppagecomment[#1]% + {\getparameters[\??pc][#1]% + \doifelse\@@pcstate\v!start + {\doifinsetelse\@@pclocation{\v!bottom,\v!top} + {\setuppapersize[\c!left=\hskip\@@pcoffset]% + \edef\@@pcpaperheight{\the\dimexpr\paperheight+\@@pcoffset+\@@pcoffset+\@@pcdistance+\@@pcheight\relax}% + \edef\@@pcpaperwidth {\the\dimexpr\paperwidth+\@@pcoffset+\@@pcoffset\relax}% + \defineoverlay[\v!pagecomment][\placepagecommentTB]} + {\setuppapersize[\c!top=\vskip\@@pcoffset]% + \edef\@@pcpaperheight{\the\dimexpr\paperheight+\@@pcoffset+\@@pcoffset\relax}% + \edef\@@pcpaperwidth {\the\dimexpr\paperwidth+\@@pcoffset+\@@pcoffset+\@@pcdistance+\@@pcwidth\relax}% + \defineoverlay[\v!pagecomment][\placepagecommentLR]}% + \processaction + [\@@pclocation] + [ \v!bottom=>{\setuppapersize[\c!bottom =\vss,\c!top =\vskip\@@pcoffset]}, + \v!top=>{\setuppapersize[\c!top =\vss,\c!bottom =\vskip\@@pcoffset]}, + \v!left=>{\setuppapersize[\c!left =\hss,\c!right=\hskip\@@pcoffset]}, + \v!right=>{\setuppapersize[\c!right=\hss,\c!left =\hskip\@@pcoffset]}]% + \definepapersize + [\v!pagecomment] + [\c!height=\@@pcpaperheight, + \c!width=\@@pcpaperwidth]% + \let\@@pcprintpapersize\printpapersize + \setuppapersize[\papersize][\v!pagecomment]% + \setupbackgrounds[\v!paper][\c!background=\v!pagecomment]} + {\doif\@@pcstate\v!stop % else initialization invokes backgrounds + {% this should be tested first + % \expanded{\setuppapersize[\papersize][\@@pcprintpapersize]}% + \setupbackgrounds[\v!paper][\c!background=]}}} + +\def\@@pcprintpapersize{\printpapersize} + +\def\placepagecommentTB + {\vbox to \printpaperheight + {\forgetall + \hsize\printpaperwidth + \vskip\@@pcoffset + \doifelse\@@pclocation\v!bottom{\vskip\dimexpr\paperheight+\@@pcdistance\relax}\vss + \hskip\@@pcoffset + \vbox to \@@pcheight + {\forgetall + \hsize\paperwidth + \ifpagecomment + \getbuffer[\v!pagecomment]% + \global\pagecommentfalse + \fi}% + \hfill + \doifelse\@@pclocation\v!bottom\vss{\vskip\dimexpr\paperheight+\@@pcdistance\relax}% + \vskip\@@pcoffset}} + +\def\placepagecommentLR + {\hbox to \printpaperwidth + {\hskip\@@pcoffset + \doifelse\@@pclocation\v!right{\hskip\paperwidth\hskip\@@pcdistance}\hss + \vbox to \printpaperheight + {\forgetall + \vskip\@@pcoffset + \hsize\@@pcwidth + \ifpagecomment + \getbuffer[\v!pagecomment]% + \global\pagecommentfalse + \fi + \vss}% + \doifelse\@@pclocation\v!right\hss{\hskip\paperwidth\hskip\@@pcdistance}% + \hskip\@@pcoffset}} + +\newif\ifpagecomment + +\setvalue{\e!start\v!pagecomment}% + {\global\pagecommenttrue + \dostartbuffer[\v!pagecomment][\e!start\v!pagecomment][\e!stop\v!pagecomment]} + +\setuppagecomment + [\c!state=, % \v!stop would invoke background calculation + \c!location=\v!bottom, + \c!offset=.5cm, + \c!distance=.5cm, + \c!height=5cm, + \c!width=10cm] + +% This macro cuts a page into n parts that can be pasted +% together. + +\def\slicepages + {\dotripleempty\doslicepages} + +\def\doslicepages[#1][#2][#3]% + {\ifthirdargument + \dodoslicepages[#1][#2][#3]% + \else + \dodoslicepages[#1][#2][#2]% + \fi} + +\newcounter\slicedpagenumber + +\def\dodoslicepages[#1][#2][#3]% + {\bgroup + \dontcomplain + \globallet\slicedpagenumber\!!zerocount + \getfiguredimensions[#1] + \getparameters + [\??ip] + [\c!n=1, + \c!offset=\!!zeropoint, + \c!hoffset=\!!zeropoint,\c!voffset=\!!zeropoint, + \c!width=\figurewidth,\c!height=\figureheight,#2] + \ifnum\@@ipn>\zerocount + \definepapersize + [\s!dummy][\c!height=\@@ipheight,\c!width=\@@ipwidth] + \setuppapersize + [\s!dummy][\s!dummy] + \setuplayout + [\c!backspace=\!!zeropoint,\c!topspace=\!!zeropoint, + \c!height=\v!middle,\c!width=\v!middle, + \c!textdistance=\!!zeropoint, + \c!header=\!!zeropoint,\c!footer=\!!zeropoint] + \fi + \dorecurse\noffigurepages + {\global\let\slicedpagenumber\recurselevel + \ifnum\@@ipn>\plusone + \dorecurse\@@ipn + {\let\xslice\recurselevel + \dorecurse\@@ipn + {\let\yslice\recurselevel + \clip + [\c!nx=\@@ipn,\c!ny=\@@ipn,\c!x=\xslice,\c!y=\yslice] + {\scale + [\c!scale=\@@ipn000] + {\externalfigure[#1][\c!page=\slicedpagenumber]}} + \page}} + \else + \ifodd\slicedpagenumber\relax + \getparameters[\??ip][#2] + \else + \getparameters[\??ip][#3] + \fi + \hskip\@@ipoffset + \clip + [\c!hoffset=\@@iphoffset,\c!voffset=\@@ipvoffset, + \c!height=\@@ipheight,\c!width=\@@ipwidth] + {\externalfigure[#1][\c!page=\slicedpagenumber]} + \page + \fi} + \egroup} + +% \starttext \slicepages[slice1.pdf][n=3] \stoptext + +\protect \endinput diff --git a/tex/context/base/page-imp.mkiv b/tex/context/base/page-imp.mkiv new file mode 100644 index 000000000..a0f32ef86 --- /dev/null +++ b/tex/context/base/page-imp.mkiv @@ -0,0 +1,1299 @@ +%D \module +%D [ file=page-imp, % was: core-pag, +%D version=1998.01.15, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Pagebody Building (Imposition), +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% much of this can more to run time loading ! + +\writestatus{loading}{ConTeXt Page Macros / Pagebody Building} + +\unprotect + +% sizing bug: +% +% \setuppapersize[A4][A4,landscape] \setuparranging[2UP] \showframe +% +% \starttext \dorecurse{10}{\input tufte \par} \stoptext + +% to be moved code: + +\newif\ifclipprintbox \clipprintboxtrue +%newif\ifclippagebox \clippageboxtrue + +\def\clippedprintbox#1#2% can be made more efficient, see other clipper + {\ifclipprintbox + \!!widthc \pagebackgroundoffset + \!!widtha \dimexpr\paperwidth + \!!widthc\relax + \!!heighta\dimexpr\paperheight+2\!!widthc\relax + \setbox#2\vbox to \paperheight{\vfill\box#2}% + \ht#2\paperheight + \wd#2\paperwidth + \setbox#2\vbox + {\framed + [\c!offset=\!!widthc,\c!strut=\v!no,\c!frame=\v!off] + {\box#2}}% + \setbox#2\hbox to \paperwidth + {\ifcase#1\relax + \!!widthb\zeropoint + \hskip-\!!widthc + \else + \!!widthb\!!widthc + \fi + \lower\!!widthc\hbox + {\clip + [\c!width=\!!widtha,\c!height=\!!heighta, + \c!hoffset=\!!widthb,\c!voffset=\zeropoint] + {\box#2}}}% + \wd#2\paperwidth + \ht#2\paperheight + \fi + \box#2\relax} + +\let\clippagebox \gobbleoneargument +\let\clipprintbox\gobbleoneargument + +% \setuppagenumbering[alternative=doublesided] +% \setupcolors[state=start] +% \setuppapersize[A4][A4,oversized] +% \setuplayout[location=middle,clipoffset=5mm] +% \setupbackgrounds +% [page] +% [frame=on,rulethickness=1mm, +% backgroundoffset=10mm,background=color,backgroundcolor=red] +% \starttext \dorecurse{10}{\input tufte \par} \stoptext + +\def\clippagebox % skip fast over false + {\ifdim\@@lyclipoffset>\zeropoint + \expandafter\doclippagebox + \else + \expandafter\gobbleoneargument + \fi} + +\def\doclippagebox#1% + {\!!widtha \wd#1% + \!!heighta\ht#1% + \!!deptha \dp#1% + \setbox#1\hbox + {\!!widthb \@@lyclipoffset + \advance\!!heighta\dimexpr\!!deptha+2\!!widthb\relax + \advance\!!widtha \!!widthb + \doifbothsides + {\advance\!!widtha\!!widthb \!!widthc-\!!widthb \hskip\!!widthc}% + {\!!widthc\zeropoint} + {\!!widthc-\!!widthb \hskip\!!widthc}% + \lower\!!widthb\hbox + {\clip + [\c!hoffset=\!!widthc, + \c!voffset=-\!!widthb, + \c!width=\!!widtha, + \c!height=\!!heighta]% + {\box#1}}}% + \wd#1\!!widtha + \ht#1\!!heighta + \dp#1\!!deptha} + +%D \macros +%D {starttextdata} +%D +%D This is a user macro (appending to every last shipout is not +%D really user friendly. + +\newtoks \collectedtextdata + +\long\unexpanded\def\starttextdata#1\stoptextdata + {\doglobal\appendtoks#1\to\collectedtextdata} + +\def\flushtextdata + {\vsmashed{\the\collectedtextdata}% all dimensions zero + \global\collectedtextdata\emptytoks + \globallet\flushtextdata\donothing} + +\prependtoks \flushtextdata \to \everylastshipout + +\def\installpagehandler#1#2% % a handler takes one argument: something to be boxed + {\setgvalue{\??pp:\c!method:#1}##1{#2{##1}}} % 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 + \executeifdefined{\??pp:\c!method:\@@ppmethod}\gobbleoneargument{#1}% + \setnextrealpageno + \aftershipout} + +\newbox\postponedcontent + +\def\flushatshipout + {\dowithnextbox + {\global\setbox\postponedcontent\hbox to \zeropoint + {%\hskip-\maxdimen % niet hier, gaat mis in acrobat (clipt) + \unhbox\postponedcontent\unhbox\nextbox}% was \box + \global\ht\postponedcontent\zeropoint + \global\dp\postponedcontent\zeropoint + \global\wd\postponedcontent\zeropoint}% + \hbox} + +% \starttypen +% \def\pagestoshipout{1,3,5} +% \stoptypen + +\newcount\shippedoutpages + +\let\pagestoshipout\empty % {1,3,6} +\chardef\whichpagetoshipout=0 % 0=all 1=odd 2=even + +\def\actualshipout#1% + {\global\advance\shippedoutpages\plusone + % this is not resource safe! + \ifx\pagestoshipout\empty + \ifcase\whichpagetoshipout\relax + \donetrue + \or % 1 + \ifodd\shippedoutpages\relax\donetrue\else\donefalse\fi + \or % 2 + \ifodd\shippedoutpages\relax\donefalse\else\donetrue\fi + \else + \donetrue + \fi + \else % testen, aangepast / expanded nodig ? + \normalexpanded{\noexpand\doifinsetelse{\the\shippedoutpages}{\pagestoshipout}}% + \donetrue\donefalse + \fi + \ifdone + \shipout\vbox + {%\forgetall + \offinterlineskip + \dontcomplain + \scratchdimen-1in + \vskip\scratchdimen + \hskip\scratchdimen + \setbox0\hbox{#1}% just in case there are objects there, hook for testing + \finalizeshipoutbox0% + \setbox\scratchbox\hbox + {% before the main one ! + \ifcase\realfolio \or + \the\everyfirstshipout + \global\everyfirstshipout\emptytoks + \fi + % the main one + \the\everyshipout\relax + % always last (and after the main one) + \ifnum\realpageno=\lastpage\relax + \the\everylastshipout + \global\everylastshipout\emptytoks + \fi}% + \smashbox\scratchbox + \hbox % \setbox0=\box.. is nicer + {\box\scratchbox + \ifvoid\postponedcontent\else\box\postponedcontent\fi % evt ver naar links ! + \box0}}% + \else + \message + {[\ifarrangingpages arranged \fi page + \ifarrangingpages\the\arrangeno\else\the\realpageno\fi\normalspace + not flushed]}% + \setbox0\hbox{#1}% + \deadcycles\zerocount + \fi} + +\def\actualarrange#1% + {\setbox0\hbox{#1}% + \pusharrangedpage0% + \deadcycles\zerocount} + +%D We need a couple of boxes for duplex printing \unknown + +\newbox\arrangedpageA \newbox\arrangedpageB + +%D \unknown\ and some for simulating big sheets. + +\newbox\arrangedpageC \newbox\arrangedpageD +\newbox\arrangedpageE \newbox\arrangedpageF +\newbox\arrangedpageG \newbox\arrangedpageH + +\newif\ifswaparranged +\newif\ifnegatearranged +\newif\ifmirrorarranged +\newif\ifdoublearranged + +\newif\ifarrangingdisabled + +\def\arrangedrotationO{0} +\def\arrangedrotationE{0} + +\newcounter\arrangedpageN +\newcounter\arrangedpageM + +\chardef\arrangedpageT=1 +\chardef\arrangedpageX=1 +\chardef\arrangedpageY=1 + +\def\calculatepaperoffsets#1% + {\scratchdimen\getvalue{\??pp#1\c!offset}% + \divide\scratchdimen \arrangedpageX + \global\advance\paperwidth -2\scratchdimen + \scratchdimen\getvalue{\??pp#1\c!offset}% + \divide\scratchdimen \arrangedpageY + \global\advance\paperheight-2\scratchdimen} + +\newconditional\arrangedbackgroundokay % more ifs -> conditionals + +\unexpanded\def\setuparranging[#1]% + {\ifarrangingdisabled \else + \doifelse{#1}\v!disable + {\global\arrangingdisabledtrue} + {\global\arrangingdisabledfalse}% + \global\arrangingpagestrue + \global\negatearrangedfalse + \global\mirrorarrangedfalse + \global\doublearrangedfalse + \gdef\arrangedrotationO{0}% + \gdef\arrangedrotationE{180}% + \processallactionsinset + [#1] + [ \v!mirrored=>\global\mirrorarrangedtrue, + \v!doublesided=>\global\doublearrangedtrue, + \v!negative=>\global\negatearrangedtrue, + \v!rotated=>\gdef\arrangedrotationO {90}\gdef\arrangedrotationE{270}, + 90=>\gdef\arrangedrotationO {90}\gdef\arrangedrotationE{270}, + 180=>\gdef\arrangedrotationO{180}\gdef\arrangedrotationE{0}, + 270=>\gdef\arrangedrotationO{270}\gdef\arrangedrotationE{90}, + \s!reset=>\global\arrangingpagesfalse, + \v!background=>\global\settrue\arrangedbackgroundokay, + \s!unknown=>\checkinstalledpagearrangement\commalistelement]% + % no \s!default=> we can have aaa,,bbb + \ifx\handlearrangedpage\undefined + \global\arrangingpagesfalse + \fi + \doifcommonelse{#1}{90,270,\v!rotated} + {\swapmacros\horizontalcutmarks\verticalcutmarks}{}% ugly solution + \setuppapersize + \fi} + +\def\installpagearrangement #1 % + {\setgvalue{\??pp\??pp#1}} + +\def\checkinstalledpagearrangement#1% can be empty: aaa,,bbb + {\executeifdefined{\??pp\??pp#1}\donothing} + +\def\dosetuparrangement#1#2#3#4#5#6#7#8% + {\global\chardef\arrangedpageX #1% + \global\chardef\arrangedpageY #2% + \global\chardef\arrangedpageT #3% + \global\chardef\horizontalcutmarks#4% + \global\chardef\verticalcutmarks #5% + \global\let \pusharrangedpage #6% + \global\let \poparrangedpages #7% + \global\let \handlearrangedpage#8} + +\installpagearrangement {\v!normal} + {\global\arrangingpagesfalse} + +\installpagearrangement 2*16 + {\dosetuparrangement{4}{4}{16}{5}{5}% + \pusharrangedpageTHIRTYTWO\poparrangedpagesAB\relax} + +\installpagearrangement 2*8 + {\dosetuparrangement{4}{2}{8}{5}{3}% + \pusharrangedpageSIXTEEN\poparrangedpagesAB\relax} + +\installpagearrangement 2*4 + {\dosetuparrangement{2}{2}{4}{3}{3}% + \pusharrangedpageEIGHT\poparrangedpagesAB\relax} + +\installpagearrangement 2*2 + {\dosetuparrangement{2}{1}{2}{3}{2}% + \pusharrangedpageFOURA\poparrangedpagesAB\relax} + +\installpagearrangement 2**2 + {\dosetuparrangement{2}{1}{2}{3}{2}% + \pusharrangedpageFOURB\poparrangedpagesAB\relax} + +\installpagearrangement 2SIDE + {\dosetuparrangement{2}{1}{2}{3}{2}% + \pusharrangedpageSIDETOP\poparrangedpagesTWO\handlearrangedpageSIDE} + +\installpagearrangement 2TOP + {\dosetuparrangement{1}{2}{2}{2}{3}% + \pusharrangedpageSIDETOP\poparrangedpagesTWO\handlearrangedpageTOP} + +\installpagearrangement 2UP + {\dosetuparrangement{2}{1}{4}{3}{2}% + \pusharrangedpageTWO\poparrangedpagesTWO\handlearrangedpageTWOUP} + +\installpagearrangement 2DOWN + {\dosetuparrangement{1}{2}{4}{2}{3}% + \pusharrangedpageTWO\poparrangedpagesTWO\handlearrangedpageTWODOWN} + +\installpagearrangement 2*4*2 % one defined by Willy Egger: + {\dosetuparrangement{2}{2}{4}{3}{2}% + \pusharrangedpageSIXTEENTWO\poparrangedpagesAtoD\relax} + +\installpagearrangement 2*2*4 % onother one of Willy Egger + {\dosetuparrangement{2}{1}{8}{3}{2}% + \pusharrangedpageSIXTEENFOUR\poparrangedpagesAtoH\relax} + +\installpagearrangement 2TOPSIDE + {\dosetuparrangement{1}{2}{4}{2}{3}% + \pusharrangedpageTWOTOPSIDE\poparrangedpagesTWOTOPSIDE\handlearrangedpageTOP} + +% \def\filluparrangedpages % beware: \realpageno is 1 ahead +% {\ifarrangingpages +% \scratchcounter-\realpageno +% \divide\scratchcounter \arrangedpageT +% \multiply\scratchcounter \arrangedpageT +% \advance\scratchcounter \realpageno +% \advance\scratchcounter \minusone +% \dorecurse\scratchcounter{\noheaderandfooterlines\ejectdummypage}% +% \fi} + +\def\filluparrangedpages % beware: \realpageno is 1 ahead + {\ifarrangingpages + \scratchcounter\numexpr\realpageno-\plusone\relax + \dosetmodulo\scratchcounter\arrangedpageT\scratchcounter + \ifcase\scratchcounter\else + \advance\scratchcounter \plusone + \dostepwiserecurse\scratchcounter\arrangedpageT\plusone + {\noheaderandfooterlines\ejectdummypage}% + \fi + \fi} + +\def\handlearrangedpageXandY#1#2#3#4#5% + {\global\setbox#5\hbox to \arrangedpageX\paperwidth + {\setbox\scratchbox\vbox to \arrangedpageY\paperheight + {%\forgetall + \offinterlineskip + \dontcomplain + \vskip#4\paperheight + \hskip#3\paperwidth + \dorotatebox{\ifcase#2 0\else180\fi}\hbox{\box#1}% + \vfill}% + \wd\scratchbox\zeropoint + \box\scratchbox\box#5\hss}} + +\def\gotonextarrangepage + {\global\advance\arrangeno \plusone + \def\pagecutmarksymbol{\the\arrangeno}} + +\def\outputarrangedbox#1% + {\bgroup + \forgetall % somehow we're back and need to redo this + \gotonextarrangepage + \ifnum\arrangedrotationO\arrangedrotationE>\zerocount + \setbox#1\vbox + {\ifdoublearranged + \ifodd\arrangeno + \dorotatebox\arrangedrotationO\hbox{\box#1}% + \else + \dorotatebox\arrangedrotationE\hbox{\box#1}% + \fi + \else + \dorotatebox\arrangedrotationO\hbox{\box#1}% + \fi}% + \fi + \ifmirrorarranged + \setbox#1\vbox{\domirrorbox\vbox{\box#1}}% + \fi + \ifnegatearranged + \negatecolorbox{#1}% + \fi + \finishpagebox#1% + \ifconditional\arrangedbackgroundokay\addprintbackground#1\fi + \actualshipout{\box#1}% + \egroup} + +%D The format file can be 16K smaller when we postpone the +%D real arrangments. Some day ... + +% TOP + +% 32/16/8/4/SIDE + +\def\poparrangedpagesAB + {\ifnum\arrangedpageN>\zerocount + \dontcomplain + \paperwidth\arrangedpageX\paperwidth + \paperheight\arrangedpageY\paperheight + \outputarrangedbox\arrangedpageA + \outputarrangedbox\arrangedpageB + \doglobal\newcounter\arrangedpageN + \fi} + +\def\pusharrangedpageTHIRTYTWO#1% taco's challenge + {\doglobal\increment\arrangedpageN + \reportarrangedpage\arrangedpageN + \ifcase\arrangedpageN + \or \handlearrangedpageXandY{#1}033\arrangedpageA % 1 + \or \handlearrangedpageXandY{#1}003\arrangedpageB % 2 + \or \handlearrangedpageXandY{#1}100\arrangedpageB % 3 + \or \handlearrangedpageXandY{#1}130\arrangedpageA % 4 + \or \handlearrangedpageXandY{#1}100\arrangedpageA % 5 + \or \handlearrangedpageXandY{#1}130\arrangedpageB % 6 + \or \handlearrangedpageXandY{#1}033\arrangedpageB % 7 + \or \handlearrangedpageXandY{#1}003\arrangedpageA % 8 + \or \handlearrangedpageXandY{#1}102\arrangedpageA % 9 + \or \handlearrangedpageXandY{#1}132\arrangedpageB % 10 + \or \handlearrangedpageXandY{#1}031\arrangedpageB % 11 + \or \handlearrangedpageXandY{#1}001\arrangedpageA % 12 + \or \handlearrangedpageXandY{#1}031\arrangedpageA % 13 + \or \handlearrangedpageXandY{#1}001\arrangedpageB % 14 + \or \handlearrangedpageXandY{#1}102\arrangedpageB % 15 + \or \handlearrangedpageXandY{#1}132\arrangedpageA % 16 + \or \handlearrangedpageXandY{#1}122\arrangedpageA % 17 + \or \handlearrangedpageXandY{#1}112\arrangedpageB % 18 + \or \handlearrangedpageXandY{#1}011\arrangedpageB % 19 + \or \handlearrangedpageXandY{#1}021\arrangedpageA % 20 + \or \handlearrangedpageXandY{#1}011\arrangedpageA % 21 + \or \handlearrangedpageXandY{#1}021\arrangedpageB % 22 + \or \handlearrangedpageXandY{#1}122\arrangedpageB % 23 + \or \handlearrangedpageXandY{#1}112\arrangedpageA % 24 + \or \handlearrangedpageXandY{#1}013\arrangedpageA % 25 + \or \handlearrangedpageXandY{#1}023\arrangedpageB % 26 + \or \handlearrangedpageXandY{#1}120\arrangedpageB % 27 + \or \handlearrangedpageXandY{#1}110\arrangedpageA % 28 + \or \handlearrangedpageXandY{#1}120\arrangedpageA % 29 + \or \handlearrangedpageXandY{#1}110\arrangedpageB % 30 + \or \handlearrangedpageXandY{#1}013\arrangedpageB % 31 + \or \handlearrangedpageXandY{#1}023\arrangedpageA % 32 + \poparrangedpages + \fi} + +\def\pusharrangedpageSIXTEEN#1% changed to match the official way of doing + {\doglobal\increment\arrangedpageN + \reportarrangedpage\arrangedpageN + \ifcase\arrangedpageN + \or \handlearrangedpageXandY{#1}031\arrangedpageA % 1 + \or \handlearrangedpageXandY{#1}001\arrangedpageB % 2 + \or \handlearrangedpageXandY{#1}031\arrangedpageB % 3 + \or \handlearrangedpageXandY{#1}001\arrangedpageA % 4 + \or \handlearrangedpageXandY{#1}100\arrangedpageA % 5 + \or \handlearrangedpageXandY{#1}130\arrangedpageB % 6 + \or \handlearrangedpageXandY{#1}100\arrangedpageB % 7 + \or \handlearrangedpageXandY{#1}130\arrangedpageA % 8 + \or \handlearrangedpageXandY{#1}120\arrangedpageA % 9 + \or \handlearrangedpageXandY{#1}110\arrangedpageB % 10 + \or \handlearrangedpageXandY{#1}120\arrangedpageB % 11 + \or \handlearrangedpageXandY{#1}110\arrangedpageA % 12 + \or \handlearrangedpageXandY{#1}011\arrangedpageA % 13 + \or \handlearrangedpageXandY{#1}021\arrangedpageB % 14 + \or \handlearrangedpageXandY{#1}011\arrangedpageB % 15 + \or \handlearrangedpageXandY{#1}021\arrangedpageA % 16 + \poparrangedpages + \fi} + +\def\pusharrangedpageEIGHT#1% changed to match the official way of doing + {\doglobal\increment\arrangedpageN + \reportarrangedpage\arrangedpageN + \ifcase\arrangedpageN + \or \handlearrangedpageXandY{#1}011\arrangedpageA % 1 + \or \handlearrangedpageXandY{#1}001\arrangedpageB % 2 + \or \handlearrangedpageXandY{#1}100\arrangedpageB % 3 + \or \handlearrangedpageXandY{#1}110\arrangedpageA % 4 + \or \handlearrangedpageXandY{#1}100\arrangedpageA % 5 + \or \handlearrangedpageXandY{#1}110\arrangedpageB % 6 + \or \handlearrangedpageXandY{#1}011\arrangedpageB % 7 + \or \handlearrangedpageXandY{#1}001\arrangedpageA % 8 + \poparrangedpages + \fi} + +\def\pusharrangedpageFOURA{\pusharrangedpageFOURdo01} +\def\pusharrangedpageFOURB{\pusharrangedpageFOURdo10} + +\def\pusharrangedpageFOURdo#1#2#3% + {\doglobal\increment\arrangedpageN + \reportarrangedpage\arrangedpageN + \ifcase\arrangedpageN + \or \handlearrangedpageXandY{#3}010\arrangedpageA % 1 + \or \handlearrangedpageXandY{#3}0{#1}0\arrangedpageB % 2/3 not {1} + \or \handlearrangedpageXandY{#3}0{#2}0\arrangedpageB % 3/2 not {1} + \or \handlearrangedpageXandY{#3}000\arrangedpageA % 4 + \poparrangedpages + \fi} + +\def\pusharrangedpageSIDETOP#1% + {\doglobal\increment\arrangedpageN + \reportarrangedpage\arrangedpageN + \ifcase\arrangedpageN + \or \handlearrangedpageXandY{#1}000\arrangedpageA % 1 + \or \handlearrangedpageXandY{#1}000\arrangedpageB % 2 + \poparrangedpages + \fi} + +\def\handlearrangedpageSIDE + {\global\wd\arrangedpageA\paperwidth + \global\wd\arrangedpageB\paperwidth + \global\setbox\arrangedpageA\hbox + {\box\arrangedpageA\box\arrangedpageB}% + \global\ht\arrangedpageA\paperheight} + +\def\handlearrangedpageTOP + {\global\ht\arrangedpageA\paperheight + \global\ht\arrangedpageB\paperheight + \global\setbox\arrangedpageA\vbox + {%\forgetall + \offinterlineskip\vskip\paperheight + \box\arrangedpageA\box\arrangedpageB}% + \global\setbox\arrangedpageB\box\scratchbox} % ? + +% 2UP/2DOWN / 1pt prevents overflow + +\def\splitoffarrangedpagesTWO + {\splittopskip\zeropoint + \global\setbox\arrangedpageA\vsplit\arrangedpageB to \onepoint + \scratchdimen\dimexpr\ht\arrangedpageB-\onepoint\relax + \ifdim\scratchdimen>\onepoint + \setbox\scratchbox\vsplit\arrangedpageB to \scratchdimen + \fi} + +\def\handlearrangedpageTWOUP + {\splitoffarrangedpagesTWO + \ifswaparranged + \global\setbox\arrangedpageA\hbox + {\clippedprintbox0\arrangedpageA + \clippedprintbox1\arrangedpageB}% + \swaparrangedfalse + \else + \global\setbox\arrangedpageA\hbox + {\clippedprintbox0\arrangedpageB + \clippedprintbox1\arrangedpageA}% + \swaparrangedtrue + \fi + \global\ht\arrangedpageA\paperheight + \global\setbox\arrangedpageB\box\scratchbox} + +\def\handlearrangedpageTWODOWN + {\splitoffarrangedpagesTWO + \global\ht\arrangedpageA\paperheight + \global\ht\arrangedpageB\paperheight + \ifswaparranged + \global\setbox\arrangedpageA\vbox + {%\forgetall + \offinterlineskip\vskip\paperheight + \box\arrangedpageA\box\arrangedpageB}% + \swaparrangedfalse + \else + \global\setbox\arrangedpageA\vbox + {%\forgetall + \offinterlineskip\vskip\paperheight + \box\arrangedpageB\box\arrangedpageA}% + \swaparrangedtrue + \fi + \global\setbox\arrangedpageB\box\scratchbox} + +\def\poparrangedpagesTWO + {\ifnum\arrangedpageN>\zerocount + \dontcomplain + \swaparrangedfalse + \doloop + {\handlearrangedpage + \bgroup + \paperwidth\arrangedpageX\paperwidth + \paperheight\arrangedpageY\paperheight + \ht\arrangedpageA\paperheight + \wd\arrangedpageA\paperwidth + \outputarrangedbox\arrangedpageA + \egroup + \ifdim\ht\arrangedpageB=\zeropoint + \exitloop + \fi}% + \doglobal\newcounter\arrangedpageN + \fi} + +\def\pusharrangedpageTWO#1% + {\doglobal\increment\arrangedpageN + \reportarrangedpage\arrangedpageN + \global\setbox\arrangedpageB\vbox + {%\forgetall + \offinterlineskip + \unvbox\arrangedpageB + \allowbreak + \ht#1\onepoint + \dp#1\zeropoint + \vbox{\box#1}}} + +\def\poparrangedpagesTWOTOPSIDE + {\ifnum\arrangedpageN>\zerocount + \bgroup + \gdef\arrangedpageN{2}\poparrangedpagesTWO + \let\arrangedpageA\arrangedpageC + \let\arrangedpageB\arrangedpageD + \gdef\arrangedpageN{2}\poparrangedpagesTWO + \doglobal\newcounter\arrangedpageN + \egroup + \fi} + +\def\pusharrangedpageTWOTOPSIDE#1% + {\doglobal\increment\arrangedpageN + \reportarrangedpage\arrangedpageN + \ifcase\arrangedpageN + \or \handlearrangedpageXandY{#1}000\arrangedpageA % 1 + \or \handlearrangedpageXandY{#1}000\arrangedpageC % 2 + \or \handlearrangedpageXandY{#1}000\arrangedpageB % 1 + \or \handlearrangedpageXandY{#1}000\arrangedpageD % 2 + \poparrangedpages + \fi} + +%D Willy Egger's sheet simulations: + +\def\poparrangedpagesAtoH + {\ifnum\arrangedpageN>\zerocount + \dontcomplain + \paperwidth\arrangedpageX\paperwidth + \paperheight\arrangedpageY\paperheight + \outputarrangedbox\arrangedpageA + \outputarrangedbox\arrangedpageB + \outputarrangedbox\arrangedpageC + \outputarrangedbox\arrangedpageD + \outputarrangedbox\arrangedpageE + \outputarrangedbox\arrangedpageF + \outputarrangedbox\arrangedpageG + \outputarrangedbox\arrangedpageH + \doglobal\newcounter\arrangedpageN + \fi} + +% to arrange 16 pages on 2 sheets to form one booklet + +\def\poparrangedpagesAtoD + {\ifnum\arrangedpageN>\zerocount + \dontcomplain + \paperwidth\arrangedpageX\paperwidth + \paperheight\arrangedpageY\paperheight + \outputarrangedbox\arrangedpageA + \outputarrangedbox\arrangedpageB + \outputarrangedbox\arrangedpageC + \outputarrangedbox\arrangedpageD + \doglobal\newcounter\arrangedpageN + \fi} + +% to arrange 16 pages on 4 sheets to form one booklet + +\def\pusharrangedpageSIXTEENFOUR#1% + {\doglobal\increment\arrangedpageN + \reportarrangedpage\arrangedpageN + \ifcase\arrangedpageN + \or \handlearrangedpageXandY{#1}010\arrangedpageA % 1 + \or \handlearrangedpageXandY{#1}000\arrangedpageB % 2 + \or \handlearrangedpageXandY{#1}010\arrangedpageC % 3 + \or \handlearrangedpageXandY{#1}000\arrangedpageD % 4 + \or \handlearrangedpageXandY{#1}010\arrangedpageE % 5 + \or \handlearrangedpageXandY{#1}000\arrangedpageF % 6 + \or \handlearrangedpageXandY{#1}010\arrangedpageG % 7 + \or \handlearrangedpageXandY{#1}000\arrangedpageH % 8 + \or \handlearrangedpageXandY{#1}010\arrangedpageH % 9 + \or \handlearrangedpageXandY{#1}000\arrangedpageG % 10 + \or \handlearrangedpageXandY{#1}010\arrangedpageF % 11 + \or \handlearrangedpageXandY{#1}000\arrangedpageE % 12 + \or \handlearrangedpageXandY{#1}010\arrangedpageD % 13 + \or \handlearrangedpageXandY{#1}000\arrangedpageC % 14 + \or \handlearrangedpageXandY{#1}010\arrangedpageB % 15 + \or \handlearrangedpageXandY{#1}000\arrangedpageA % 16 + \poparrangedpages + \fi} + +% to arrange 16 pages on 2 sheets to form one booklet + +\def\pusharrangedpageSIXTEENTWO#1% + {\doglobal\increment\arrangedpageN + \reportarrangedpage\arrangedpageN + \ifcase\arrangedpageN + \or \handlearrangedpageXandY{#1}011\arrangedpageA % 1 + \or \handlearrangedpageXandY{#1}001\arrangedpageB % 2 + \or \handlearrangedpageXandY{#1}011\arrangedpageC % 3 + \or \handlearrangedpageXandY{#1}001\arrangedpageD % 4 + \or \handlearrangedpageXandY{#1}100\arrangedpageD % 5 + \or \handlearrangedpageXandY{#1}110\arrangedpageC % 6 + \or \handlearrangedpageXandY{#1}100\arrangedpageB % 7 + \or \handlearrangedpageXandY{#1}110\arrangedpageA % 8 + \or \handlearrangedpageXandY{#1}100\arrangedpageA % 9 + \or \handlearrangedpageXandY{#1}110\arrangedpageB % 10 + \or \handlearrangedpageXandY{#1}100\arrangedpageC % 11 + \or \handlearrangedpageXandY{#1}110\arrangedpageD % 12 + \or \handlearrangedpageXandY{#1}011\arrangedpageD % 13 + \or \handlearrangedpageXandY{#1}001\arrangedpageC % 14 + \or \handlearrangedpageXandY{#1}011\arrangedpageB % 15 + \or \handlearrangedpageXandY{#1}001\arrangedpageA % 16 + \poparrangedpages + \fi} + +% % handy for stickers etc, this way we can treat them as page +% +% \setuppapersize [XY][A4] +% \setuppaper [topspace=5mm,backspace=5mm,dx=1mm,dy=1mm,nx=2,ny=6] +% \setuplayout [page] [topspace=5mm,backspace=5mm] +% \setuplayout [page] +% \setuplayout [location=middle] +% \setuparranging [XY] +% \showframe +% +% \starttext \dorecurse{30}{test \recurselevel \page} \stoptext + +\def\pusharrangedpageXY#1% + {\doglobal\increment\arrangedpageN + \reportarrangedpage\arrangedpageN + \doglobal\increment\arrangedpageM + \global\setbox\arrangedpageB\hbox + \ifdim\@@ppwidth>\zeropoint to \@@ppwidth \fi + {\ifvoid\arrangedpageB\else + \unhbox\arrangedpageB + \ifdim\@@ppdx>\zeropoint \else \hss\fi + \hskip\@@ppdx + \ifdim\@@ppdx>\zeropoint \else \hss\fi + \fi + \box#1}% + \ifnum\arrangedpageM<\arrangedpageX\else + \global\setbox\arrangedpageA\vbox + \ifdim\@@ppheight>\zeropoint to \@@ppheight \fi + {\offinterlineskip + \ifvoid\arrangedpageA\else + \unvbox\arrangedpageA + \ifdim\@@ppdy>\zeropoint \else \vss\fi + \vskip\@@ppdy + \ifdim\@@ppdy>\zeropoint \else \vss\fi + \fi + \box\arrangedpageB}% + \doglobal\newcounter\arrangedpageM + \fi + \ifnum\arrangedpageN<\arrangedpageT\else + \poparrangedpages + \fi} + +\def\poparrangedpagesXY + {\ifnum\arrangedpageN>\zerocount + \dontcomplain + \paperwidth\arrangedpageX\paperwidth + \paperheight \arrangedpageY\paperheight + \outputarrangedbox\arrangedpageA + \doglobal\newcounter\arrangedpageN + \doglobal\newcounter\arrangedpageM + \fi} + +\installpagearrangement XY + {\dosetuparrangement\@@ppnx\@@ppny\@@ppxy\!!zerocount\!!zerocount + \pusharrangedpageXY\poparrangedpagesXY\relax} + +%D A crazy definition, don't guess who pushed me for the landscape option. + +\definepapersize + [XY] + [\c!height=\dimexpr\dimexpr\@@ppheight-\numexpr\@@ppny-1\relax\dimexpr\@@ppdy\relax\relax/\@@ppny\relax, + \c!width =\dimexpr\dimexpr\@@ppwidth -\numexpr\@@ppnx-1\relax\dimexpr\@@ppdx\relax\relax/\@@ppnx\relax] + +\setuppaper + [\c!width =\dimexpr\printpaperwidth -2\dimexpr\@@ppbackspace\relax\relax, + \c!height=\dimexpr\printpaperheight-2\dimexpr\@@pptopspace \relax\relax] + +% \definepageshift[test][horizontal][10pt,20pt,30pt,40pt,50pt] +% \definepageshift[test][vertical] [10pt,20pt,30pt,40pt,50pt] +% +% \setuppageshift[test] +% \setuppageshift[test][test] +% \setuppageshift[test][none] +% \setuppageshift[none][test] +% \setuppageshift[paper][test][test] % arrange only +% \setuppageshift[paper][test] % arrange only +% \setuppageshift[print][test][test] +% +% \showframe \dorecurse{100}{\input tufte \par} + +% #1=name #2=horizontal|vertical #3=shiftlist + +\unexpanded\def\definepageshift + {\dotripleargument\dodefinepageshift} + +\def\dodefinepageshift[#1][#2][#3]% + {\setvalue{\??pt#2:#1}{#3}} + +\letempty \hpageshifts \newcounter\nofhpageshifts +\letempty \vpageshifts \newcounter\nofvpageshifts + +% \let\shiftprintpagebox\gobbleoneargument +% \let\shiftpaperpagebox\gobbleoneargument + +\def\dogetpageshift#1#2#3% #1=\dimenx #2=\xpageshifts #3=\nofxpageshifts + {\ifx#2\empty + #1\zeropoint + \else + \doglobal\increment#3% + \getfromcommacommand[#2][#3]% + \ifx\commalistelement\empty + \globallet#3\!!plusone + \getfromcommacommand[#2][#3]% + \fi + \ifx\commalistelement\empty + #1\zeropoint + \else + #1=\commalistelement + \donetrue + \fi + \fi} + +\def\shiftpagebox#1% + {\donefalse + \dogetpageshift{\dimen0}\hpageshifts\nofhpageshifts + \dogetpageshift{\dimen2}\vpageshifts\nofvpageshifts + \ifdone % see also layout offsets, maybe \movebox + \edef\next{\wd#1\the\wd#1\ht#1\the\ht#1\dp#1\the\dp#1}% + \setbox#1\vbox + {\offinterlineskip\vskip\dimen2\hskip\dimen0\box#1}% + \next + \fi} + +\unexpanded\def\setuppageshift + {\dotripleempty\dosetuppageshift} + +\def\dosetuppageshift[#1][#2][#3]% page|paper horizontal vertical + {\ifthirdargument % paper=arrange + \let\hpageshifts\empty + \let\vpageshifts\empty + \let\shiftprintpagebox\gobbleoneargument + \let\shiftpaperpagebox\gobbleoneargument + \doifdefined{\??pt\v!horizontal:#2} + {\edef\hpageshifts{\getvalue{\??pt\v!horizontal:#2}}}% + \doifdefined{\??pt\v!vertical :#3} + {\edef\vpageshifts{\getvalue{\??pt\v!vertical :#3}}}% + \doif{#1}\v!page{\let\shiftprintpagebox\shiftpagebox}% + \doif{#1}\v!paper{\let\shiftpaperpagebox\shiftpagebox}% + \else\ifsecondargument + \doifinsetelse{#1}{\v!page,\v!paper} + {\setuppageshift[#1][#2][#2]} + {\setuppageshift[\v!page][#1][#2]}% + \else\iffirstargument + \setuppageshift[\v!page][#1][#1]% + \fi\fi\fi} + +%D One can (mis)use this mechanism, in close cooperation +%D with \PDFTEX\ to arrange pages of already produced files. +%D +%D \starttyping +%D \insertpages[file.pdf][1,3][n=30,width=18cm] +%D \stoptyping +%D +%D The pages are inserted in the text area, and even pages +%D are repositioned according to the width. In this example +%D empty pages are added after page 1 and 3. +%D +%D Selecting pages can be accomplished by: +%D +%D \starttyping +%D \filterpages[file.pdf][1,3,5][n=30,width=18cm] +%D \stoptyping +%D +%D One may pass \type {odd} or \type {even} instead of a +%D comma separated list. A third alternative is: +%D +%D \starttyping +%D \copypages[file.pdf][n=30,scale=950] +%D \stoptyping +%D +%D This macros inserts the page, according to the settings +%D provided. + +\def\insertpages + {\dotripleempty\doinsertpages} + +\def\doinsertpages[#1][#2][#3]% + {\doifassignmentelse{#2} + {\dodoinsertpages[#1][][#2]} + {\dodoinsertpages[#1][#2][#3]}} + +\def\dodoinsertpages[#1][#2][#3]% + {\bgroup + \dontcomplain + \getfiguredimensions[#1]% + \getparameters[\??ip][\c!n=\noffigurepages,\c!width=\!!zeropoint,#3]% + \doifinset0{#2}{\null\page}% + \dorecurse\@@ipn + {\dofilterpage{#1}\recurselevel + \doifinset\recurselevel{#2}{\null\page}}% + \egroup} + +\def\filterpages + {\dotripleempty\dofilterpages} + +\def\dofilterpages[#1][#2][#3]% % \noffigurepages not yet supported + {\bgroup + \dontcomplain + \getfiguredimensions[#1]% + \getparameters[\??ip][\c!n=\noffigurepages,\c!width=\!!zeropoint,#3]% + \doifelse{#2}\v!even + {\dorecurse\@@ipn + {\ifodd\recurselevel\relax\else\dofilterpage{#1}\recurselevel\fi}} + {\doifelse{#2}\v!odd + {\dorecurse\@@ipn + {\ifodd\recurselevel\relax\dofilterpage{#1}\recurselevel\fi}} + {\def\dodocommand##1% + {\ifnum##1>\@@ipn\else\dofilterpage{#1}{##1}\fi}% + \def\docommand##1% + {\dowithrange{##1}\dodocommand}% + \processcommalist[#2]\docommand}}% + \egroup} + +\def\dofilterpage#1#2% + {\hbox to \textwidth + {\ifdoublesided\ifdim\@@ipwidth>\zeropoint\relax\ifodd\realpageno\else + \hfill + \def\dowithfigure{\hskip-\@@ipwidth}% + \fi\fi\fi + \setbox0\hbox + {\externalfigure[#1][\c!page=#2,\c!height=\textheight]}% + \wd0\zeropoint + \box0} + \page} + +\def\copypages + {\dodoubleempty\docopypages} + +\def\docopypages[#1][#2]% + {\bgroup + \getfiguredimensions[#1]% + \getparameters[\??ip] + [\c!n=\noffigurepages, + \c!marking=\v!off, + \c!scale=\!!thousand, + \c!offset=\!!zeropoint, + #2]% + \dorecurse\@@ipn + {\vbox to \textheight + {\hsize\textwidth + \scratchdimen\@@ipoffset + \centeredbox + {\doifelse\@@ipmarking\v!on\cuthbox\hbox + {\ifdim\scratchdimen>\zeropoint\relax + \advance\vsize -2\scratchdimen + \advance\hsize -2\scratchdimen + \externalfigure[#1][\c!page=\recurselevel,#2,\c!scale=,\c!factor=\v!max,\c!offset=\v!overlay]% + \else + \externalfigure[#1][\c!page=\recurselevel,#2,\c!offset=\v!overlay]% + \fi}}} + \page} + \egroup} + +%D \macros +%D {combinepages} +%D +%D Yet another way of postprocessing is handles by \type +%D {\combinepages}. This macro builds a matrix of pages from a +%D file, for example: +%D +%D \starttyping +%D \setuppapersize +%D [A4][A4] % or [A4,landscape][A4,landscape] +%D +%D \setuplayout +%D [header=0pt,footer=1cm, +%D backspace=1cm,topspace=1cm, +%D width=middle,height=middle] +%D +%D \setupfootertexts +%D [presentation---\currentdate\space---\space\pagenumber] +%D +%D \starttext +%D \combinepages[slides][nx=2,ny=3,frame=on] +%D \stoptext +%D \stoptyping +%D +%D One can influence the way the pages are combined. (This +%D will be explained some time.) + +\def\combinepages + {\dodoubleempty\docombinepages} + +\def\docombinepages[#1][#2]% a=perpag b=free + {\bgroup + \dontcomplain + \getfiguredimensions[#1]% + \getparameters + [\??ip] + [\c!alternative=\v!a, + \c!n=\noffigurepages,\c!nx=2,\c!ny=2,\c!start=1,\c!stop=\!!maxcard, + \c!distance=\bodyfontsize, + \c!bottom=\vfill,\c!top=\vss, + \c!left=\hss,\c!right=\hss, + \c!before=\page,\c!after=\page,\c!inbetween=\blank, + \c!frame=,\c!background=,\c!backgroundcolor=, + #2]% + \def\@@ipname{#1}% + \@@ipbefore + \expandcheckedcsname{\??ip::\c!alternative:}\@@ipalternative\v!b + \@@ipafter + \egroup} + +\setvalue{\??ip::\c!alternative:\v!a}% + {\globallet\combinedpagescounter\@@ipstart + \doloop + {\vbox to \textheight + {\hsize\textwidth % ? ? + \scratchdimen\@@ipdistance + \!!widtha \dimexpr(\hsize-\@@ipnx\scratchdimen+\scratchdimen)/\@@ipnx\relax + \!!heighta\dimexpr(\vsize-\@@ipny\scratchdimen+\scratchdimen)/\@@ipny\relax + \dorecurse\@@ipny + {\hbox to \hsize + {\dorecurse\@@ipnx + {\vbox to \!!heighta + {\hsize\!!widtha + \vsize\!!heighta + \@@iptop + \hbox to \hsize + {\@@ipleft + \ifnum\combinedpagescounter>\@@ipstop\relax + \globallet\@@ipn\!!zerocount + \else\ifnum\combinedpagescounter>\@@ipn \else + \externalfigure[\@@ipname] + [\c!object=\v!no, + \c!page=\combinedpagescounter, + \c!factor=\v!max, + \c!background=\@@ipbackground, + \c!backgroundcolor=\@@ipbackgroundcolor, + \c!frame=\@@ipframe]% + \fi\fi + \@@ipright} + \@@ipbottom}% + \doglobal\increment\combinedpagescounter + \hfil}% + \hfilneg} + \vfil}% + \vfilneg}% + \page + \ifnum\combinedpagescounter>\@@ipn \exitloop\fi}} + +\setvalue{\??ip::\c!alternative:\v!c}% + {\globallet\combinedpagescounter\@@ipstart + \doloop + {\vbox to \textheight + {\hsize\textwidth % ? ? + \scratchdimen\@@ipdistance + \!!widtha \dimexpr(\hsize-\@@ipnx\scratchdimen+\scratchdimen)/\@@ipnx\relax + \!!heighta\dimexpr(\vsize-\@@ipny\scratchdimen+\scratchdimen)/\@@ipny\relax + \hbox to \hsize + {\dorecurse\@@ipnx + {\@@ipleft + \vbox to \textheight + {\hsize\!!widtha + {\dorecurse\@@ipny + {\@@iptop + \hbox to \hsize + {\vbox to \!!heighta + {\hsize\!!widtha + \vsize\!!heighta + \ifnum\combinedpagescounter>\@@ipstop\relax + \globallet\@@ipn\!!zerocount + \else\ifnum\combinedpagescounter>\@@ipn \else + \externalfigure[\@@ipname] + [\c!object=\v!no, + \c!page=\combinedpagescounter, + \c!factor=\v!max, + \c!background=\@@ipbackground, + \c!backgroundcolor=\@@ipbackgroundcolor, + \c!frame=\@@ipframe]% + \fi\fi}} + \doglobal\increment\combinedpagescounter + \@@ipbottom}% + \vfil}% + \vfilneg} + \hfil}% + \hfilneg}} + \page + \ifnum\combinedpagescounter>\@@ipn \exitloop\fi}} + +\setvalue{\??ip::\c!alternative:\v!horizontal}{\getvalue{\??ip::\c!alternative:\v!a}} +\setvalue{\??ip::\c!alternative:\v!vertical }{\getvalue{\??ip::\c!alternative:\v!c}} + +\setvalue{\??ip::\c!alternative:\v!b}% + {\globallet\combinedpagescounter\@@ipstart + \doloop + {\startbaselinecorrection + \scratchdimen\@@ipdistance + \!!widtha\dimexpr(\hsize-\@@ipnx\scratchdimen+\scratchdimen)/\@@ipnx\relax + \hbox to \hsize + {\dorecurse\@@ipnx + {\doglobal\increment\combinedpagescounter + \ifnum\combinedpagescounter>\@@ipn \else + \normalexpanded{\noexpand\externalfigure[\@@ipname] + [\c!page=\combinedpagescounter, + \c!width=\the\!!widtha,% todo \freezedimenmacro + \c!background=\@@ipbackground, + \c!backgroundcolor=\@@ipbackgroundcolor, + \c!frame=\@@ipframe]}% + \hfill + \fi}\hfillneg}% + \stopbaselinecorrection + \ifnum\combinedpagescounter<\@@ipn\relax + \@@ipinbetween + \else + \exitloop + \fi}} + +%D \macros +%D {setuppagecomment,startpagecomment} +%D +%D This command is not yet documented. Usage: +%D +%D \starttyping +%D \setuppagecomment[state=start,location=right] +%D +%D \startpagecomment +%D \input knuth +%D \stoppagecomment +%D \stoptyping + +\unexpanded\def\setuppagecomment + {\dosingleempty\dosetuppagecomment} + +\def\dosetuppagecomment[#1]% + {\getparameters[\??pc][#1]% + \doifelse\@@pcstate\v!start + {\doifinsetelse\@@pclocation{\v!bottom,\v!top} + {\setuppapersize[\c!left=\hskip\@@pcoffset]% + \edef\@@pcpaperheight{\the\dimexpr\paperheight+\@@pcoffset+\@@pcoffset+\@@pcdistance+\@@pcheight\relax}% + \edef\@@pcpaperwidth {\the\dimexpr\paperwidth+\@@pcoffset+\@@pcoffset\relax}% + \defineoverlay[\v!pagecomment][\placepagecommentTB]} + {\setuppapersize[\c!top=\vskip\@@pcoffset]% + \edef\@@pcpaperheight{\the\dimexpr\paperheight+\@@pcoffset+\@@pcoffset\relax}% + \edef\@@pcpaperwidth {\the\dimexpr\paperwidth+\@@pcoffset+\@@pcoffset+\@@pcdistance+\@@pcwidth\relax}% + \defineoverlay[\v!pagecomment][\placepagecommentLR]}% + \processaction + [\@@pclocation] + [ \v!bottom=>{\setuppapersize[\c!bottom =\vss,\c!top =\vskip\@@pcoffset]}, + \v!top=>{\setuppapersize[\c!top =\vss,\c!bottom =\vskip\@@pcoffset]}, + \v!left=>{\setuppapersize[\c!left =\hss,\c!right=\hskip\@@pcoffset]}, + \v!right=>{\setuppapersize[\c!right=\hss,\c!left =\hskip\@@pcoffset]}]% + \definepapersize + [\v!pagecomment] + [\c!height=\@@pcpaperheight, + \c!width=\@@pcpaperwidth]% + \let\@@pcprintpapersize\printpapersize + \setuppapersize[\papersize][\v!pagecomment]% + \setupbackgrounds[\v!paper][\c!background=\v!pagecomment]} + {\doif\@@pcstate\v!stop % else initialization invokes backgrounds + {% this should be tested first + % \normalexpanded{\noexpand\setuppapersize[\papersize][\@@pcprintpapersize]}% + \setupbackgrounds[\v!paper][\c!background=]}}} + +\def\@@pcprintpapersize{\printpapersize} + +\unexpanded\def\placepagecommentTB + {\vbox to \printpaperheight + {%\forgetall + \hsize\printpaperwidth + \vskip\@@pcoffset + \doifelse\@@pclocation\v!bottom{\vskip\dimexpr\paperheight+\@@pcdistance\relax}\vss + \hskip\@@pcoffset + \vbox to \@@pcheight + {%\forgetall + \hsize\paperwidth + \ifpagecomment + \getbuffer[\v!pagecomment]% + \global\pagecommentfalse + \fi}% + \hfill + \doifelse\@@pclocation\v!bottom\vss{\vskip\dimexpr\paperheight+\@@pcdistance\relax}% + \vskip\@@pcoffset}} + +\unexpanded\def\placepagecommentLR + {\hbox to \printpaperwidth + {\hskip\@@pcoffset + \doifelse\@@pclocation\v!right{\hskip\paperwidth\hskip\@@pcdistance}\hss + \vbox to \printpaperheight + {%\forgetall + \vskip\@@pcoffset + \hsize\@@pcwidth + \ifpagecomment + \getbuffer[\v!pagecomment]% + \global\pagecommentfalse + \fi + \vss}% + \doifelse\@@pclocation\v!right\hss{\hskip\paperwidth\hskip\@@pcdistance}% + \hskip\@@pcoffset}} + +\newif\ifpagecomment + +\setvalue{\e!start\v!pagecomment}% + {\global\pagecommenttrue + \dostartbuffer[\v!pagecomment][\e!start\v!pagecomment][\e!stop\v!pagecomment]} + +\setuppagecomment + [\c!state=, % \v!stop would invoke background calculation + \c!location=\v!bottom, + \c!offset=.5cm, + \c!distance=.5cm, + \c!height=5cm, + \c!width=10cm] + +% This macro cuts a page into n parts that can be pasted +% together. + +\def\slicepages + {\dotripleempty\doslicepages} + +\def\doslicepages[#1][#2][#3]% + {\ifthirdargument + \dodoslicepages[#1][#2][#3]% + \else + \dodoslicepages[#1][#2][#2]% + \fi} + +\newcounter\slicedpagenumber + +\def\dodoslicepages[#1][#2][#3]% + {\bgroup + \dontcomplain + \globallet\slicedpagenumber\!!zerocount + \getfiguredimensions[#1] + \getparameters + [\??ip] + [\c!n=1, + \c!offset=\!!zeropoint, + \c!hoffset=\!!zeropoint,\c!voffset=\!!zeropoint, + \c!width=\figurewidth,\c!height=\figureheight,#2] + \ifnum\@@ipn>\zerocount + \definepapersize + [\s!dummy][\c!height=\@@ipheight,\c!width=\@@ipwidth] + \setuppapersize + [\s!dummy][\s!dummy] + \setuplayout + [\c!backspace=\!!zeropoint,\c!topspace=\!!zeropoint, + \c!height=\v!middle,\c!width=\v!middle, + \c!textdistance=\!!zeropoint, + \c!header=\!!zeropoint,\c!footer=\!!zeropoint] + \fi + \dorecurse\noffigurepages + {\global\let\slicedpagenumber\recurselevel + \ifnum\@@ipn>\plusone + \dorecurse\@@ipn + {\let\xslice\recurselevel + \dorecurse\@@ipn + {\let\yslice\recurselevel + \clip + [\c!nx=\@@ipn,\c!ny=\@@ipn,\c!x=\xslice,\c!y=\yslice] + {\scale + [\c!scale=\@@ipn000] + {\externalfigure[#1][\c!page=\slicedpagenumber]}} + \page}} + \else + \ifodd\slicedpagenumber\relax + \getparameters[\??ip][#2] + \else + \getparameters[\??ip][#3] + \fi + \hskip\@@ipoffset + \clip + [\c!hoffset=\@@iphoffset,\c!voffset=\@@ipvoffset, + \c!height=\@@ipheight,\c!width=\@@ipwidth] + {\externalfigure[#1][\c!page=\slicedpagenumber]} + \page + \fi} + \egroup} + +% \starttext \slicepages[slice1.pdf][n=3] \stoptext + +\protect \endinput diff --git a/tex/context/base/page-ini.mkii b/tex/context/base/page-ini.mkii new file mode 100644 index 000000000..816b7d944 --- /dev/null +++ b/tex/context/base/page-ini.mkii @@ -0,0 +1,1558 @@ + %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 + \doifelse\@@lymarking\v!page + {\replicatepagebox \pagebox + \addpagecutmarks \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..07d342282 --- /dev/null +++ b/tex/context/base/page-ini.mkiv @@ -0,0 +1,1512 @@ +%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\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 + +\ifx\dosetuplayout\undefined % overloaded in page-lay ! + + \unexpanded\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 + +% obsolete + +\def\installotr#1% andere naam, beter \connectotr of zo + {\def\OTRidentifier{#1}} + +% \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} +% +% maybe faster but at least less tracing: + +\def\OTRcommand#1% + {\csname\@@OTR + \ifcsname\@@OTR\OTRidentifier\expandafter\gobbleoneargument\string#1\endcsname + \OTRidentifier + \else\ifcsname\@@OTR\OTRdefault\expandafter\gobbleoneargument\string#1\endcsname % fallback + \OTRdefault + \fi\fi + \expandafter\gobbleoneargument\string#1\endcsname} + +\def\activateotr#1#2% + {\def\OTRidentifier{#1}% + \def\OTRdefault {#2}} + +% variant that does a preset: + +\newtoks\registeredotrcommands + +\def\registerotrcommand#1% + {\appendtoks\dowithotrcommand#1\to\registeredotrcommands} + +\def\dopresetotrcommand#1% + {\expandafter\let\expandafter#1\csname\@@OTR + \ifcsname\@@OTR\OTRidentifier\expandafter\gobbleoneargument\string#1\endcsname + \OTRidentifier + \else\ifcsname\@@OTR\OTRdefault\expandafter\gobbleoneargument\string#1\endcsname % fallback + \OTRdefault + \fi\fi + \expandafter\gobbleoneargument\string#1\endcsname} + +\def\activateotr#1#2% + {\def\OTRidentifier{#1}% + \def\OTRdefault {#2}% + \let\dowithotrcommand\dopresetotrcommand + \the\registeredotrcommands} + +\appendtoks + \activateotr{ONE}{}% +\to\everydump + +%D The initialization of the \type {\hsize} and \type {\vsize} +%D depends on the OTR used. + +% todo: \registerotrcommand\output, is a toks + +\registerotrcommand\setvsize % \def\setvsize {\OTRcommand\setvsize} +\registerotrcommand\sethsize % \def\sethsize {\OTRcommand\sethsize} +\registerotrcommand\finalsidefloatoutput % \def\finalsidefloatoutput {\OTRcommand\finalsidefloatoutput} +\registerotrcommand\dopagecontents % \def\dopagecontents {\OTRcommand\dopagecontents} +\registerotrcommand\dosettopinserts % \def\dosettopinserts {\OTRcommand\dosettopinserts} +\registerotrcommand\dosetbotinserts % \def\dosetbotinserts {\OTRcommand\dosetbotinserts} +\registerotrcommand\dotopinsertions % \def\dotopinsertions {\OTRcommand\dotopinsertions} +\registerotrcommand\dobotinsertions % \def\dobotinsertions {\OTRcommand\dobotinsertions} +\registerotrcommand\dosetbothinserts % \def\dosetbothinserts {\OTRcommand\dosetbothinserts} +\registerotrcommand\doflushfloats % \def\doflushfloats {\OTRcommand\doflushfloats} +\registerotrcommand\flushfloatbox % \def\flushfloatbox {\OTRcommand\flushfloatbox} +\registerotrcommand\docheckiffloatfits % \def\docheckiffloatfits {\OTRcommand\docheckiffloatfits} +\registerotrcommand\flushsavedfloats % \def\flushsavedfloats {\OTRcommand\flushsavedfloats} +\registerotrcommand\synchronizehsize % \def\synchronizehsize {\OTRcommand\synchronizehsize} +\registerotrcommand\gotonextpage % \def\gotonextpage {\OTRcommand\gotonextpage } +\registerotrcommand\gotonextpageX % \def\gotonextpageX {\OTRcommand\gotonextpageX} % will become obsolete + +% wrong, will be redone +% +% \registerotrcommand\someherefloat % \def\someherefloat {\OTRcommand\someherefloat} +% \registerotrcommand\somefixdfloat % \def\somefixdfloat {\OTRcommand\somefixdfloat} +% \registerotrcommand\somepagefloat % \def\somepagefloat {\OTRcommand\somepagefloat} +% \registerotrcommand\sometopsfloat % \def\sometopsfloat {\OTRcommand\sometopsfloat} +% \registerotrcommand\somebotsfloat % \def\somebotsfloat {\OTRcommand\somebotsfloat} +% \registerotrcommand\somesidefloat % \def\somesidefloat {\OTRcommand\somesidefloat} + +% 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? + +\newcount\outputcounter \outputcounter=-100010 % -10010 + +\def\doinvokeoutput + {\iftraceotr + \expandafter\dodotracedoutput + \else + \expandafter\dodoinvokeoutput + \fi} + +\def\doshowoutputmessage#1#2#3% + {\writestatus\m!otr{#1 #2 \number#3}} + +\def\dodoinvokeoutput#1% + {\bgroup\par\penalty#1\egroup} + +\def\dodotracedoutput#1% + {\doshowoutputmessage+{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}% + \doshowoutputmessage-{traced}{#1/\the\outputpenalty}} + +\def\installoutput#1#2% \invoke \action + {\global\advance\outputcounter\minusone + \edef#1{\noexpand\doinvokeoutput{\number\outputcounter}}% + \setvalue{\@@OTR\number\outputcounter}{#2}} + +\def\invoketracedoutputroutine + {\doshowoutputmessage+{trying}\outputpenalty + \ifcsname\@@OTR\the\outputpenalty\endcsname + \doshowoutputmessage+{special}\outputpenalty + \csname\@@OTR\the\outputpenalty\endcsname + \doshowoutputmessage-{special}\outputpenalty + \else + \doshowoutputmessage+{normal}\outputpenalty + \the\OTRcommand\output + \doshowoutputmessage-{normal}\outputpenalty + \fi + \doshowoutputmessage-{trying}\outputpenalty} + +\def\invokenormaloutputroutine + {\ifcsname\@@OTR\the\outputpenalty\endcsname + \csname\@@OTR\the\outputpenalty\endcsname + \else + \the\OTRcommand\output + \fi} + +\def\invokeoutputroutine + {\iftraceotr + \expandafter\invoketracedoutputroutine + \else + \expandafter\invokenormaloutputroutine + \fi} + +\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 + +\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 already done + \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 + \fixedspace + \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 + +\def\dofinaloutput#1#2% \vbox: prevents spurious spaces in every..pagebody + {\forgetall + \beforefinaloutput + \the\everybeforeshipout % brrr not in shipout + \the\pageboundsettings + \myshipout{\hbox{\vbox{\dopagebody#1#2}}}% is this hbox needed + \the\everyaftershipout + \afterfinaloutput} + +\def\donofinaloutput#1#2% + {\forgetall + \beforefinaloutput + \the\everybeforeshipout + \message{[-\the\realpageno]}% + \setbox\scratchbox\hbox{\dopagebody#1#2}% + \deadcycles\zerocount + \setnextrealpageno + \the\everyaftershipout + \afterfinaloutput} + +% beware: \ifprocessingpages is in use + +\ifdefined\doflushspread\else \let\doflushspread\relax \fi % todo + +\def\finaloutput#1#2% + {\ifprocessingpages + \ifpageselected + \@EAEAEA\dofinaloutput + \else + \@EAEAEA\donofinaloutput + \fi + \else + \ifpageselected + \@EAEAEA\donofinaloutput + \else + \@EAEAEA\dofinaloutput + \fi + \fi#1#2% + \resetselectiepagina + \incrementpagenumber + \incrementsubpagenumber + \checkpagedimensions + \ifnum\outputpenalty>\superpenalty \else + \dosupereject + \fi + \doflushspread + \doflushpostponedcontent} + +\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}} + +\unexpanded\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 % obsolete + \settexthoffset\hskip\texthoffset % brrrr + \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} + +\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, + \v!outer=>\chardef\gridboxlinenomode\plusthree]% + \ifcase\showgridstate + \let\addtextgridlayer\gobbleoneargument + \else % 1=bottom 2=top + \let\addtextgridlayer\doaddtextgridlayer + \fi} + +\definepalet + [layout] + [grid=red, + page=green] + +% if really needed for speed we can cache the grid + +\let\addtextgridlayer\gobbleoneargument + +\def\doaddtextgridlayer#1% to be checked for color and layer + {\startcolor[layout:grid]% + \setgridbox\scratchbox\makeupwidth\textheight % todo: check color + \global\setbox#1\hbox + {\ifcase\showgridstate\or\or\box#1\hskip-\makeupwidth\fi + \bgroup % color + \ifcase\layoutcolumns\else + \gray + \setlayoutcomponentattribute\v!grid\v!columns + \hbox \layoutcomponentboxattribute to \makeupwidth + {\dorecurse\layoutcolumns + {\hskip\layoutcolumnwidth + \ifnum\recurselevel<\layoutcolumns + \vrule + \!!height\ht\scratchbox + \!!depth\dp\scratchbox + \!!width\layoutcolumndistance + \fi}}% + \hskip-\makeupwidth + \fi + \setlayoutcomponentattribute\v!grid\v!lines + \hbox \layoutcomponentboxattribute{\box\scratchbox}% + \egroup + \ifcase\showgridstate\or\hskip-\makeupwidth\box#1\fi}% + \stopcolor} + +\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 + \doifelse\@@lymarking\v!page + {\replicatepagebox \pagebox + \addpagecutmarks \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 + \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 \restoreouterspacing \to \everybeforepagebody +\appendtoks \restoreglobalbodyfont \to \everybeforepagebody +%appendtoks \restoreouterspacing \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 +% \setnextsubpageno % nog eens: als in pagina (tbv standaard opmaak) + \dontshowboxes % dan hier blokkeren en verderop resetten +% \shipoutfacingpage + \checkmarginblocks + \the\beforeeverypage + \normalexpanded{\global\beforepage\emptytoks\the\beforepage}% \scratchtoks\beforepage\global\beforepage\emptytoks\the\scratchtoks % was \flushtoks\beforepage + \inpagebodytrue\buildpagebody#1#2% + \normalexpanded{\global\afterpage \emptytoks\the\afterpage }% \scratchtoks\afterpage \global\afterpage \emptytoks\the\scratchtoks % was \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 \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}% + \ifcsname\??pe:\@@pagespecification\endcsname + \csname\??pe:\@@pagespecification\endcsname + \else\ifcsname\??pe::\@@pagespecification\endcsname + \executepagebreakhandlers{\csname\??pe::\@@pagespecification\endcsname}% + \else + \csname\??pe:\s!unknown\endcsname + \fi\fi} + +\long\def\installpagebreakhandler#1#2% + {\long\setvalue{\??pe:#1}{#2}} + +\unexpanded\def\pagebreak + {\dosingleempty\dopagebreak} + +\def\dopagebreak[#1]% so, page ornaments are reset after a pagebreak command, unless set + {\bgroup + \flushnotes + \edef\prevrealpageno{\the\realpageno}% + \ifcase\pageornamentstate \or + % disable reset after shipout + \global\chardef\pageornamentstate\plustwo + \fi + \iffirstargument % or if empty i.e. [] + \executepagebreakhandlers{#1}% + \else % so, no pagebreak when \pagebreak[] ! ! ! + \executepagebreakhandler\v!yes + \fi + \ifnum\prevrealpageno<\realpageno + % there must have been a reason why i added the ifcase + % but it fails on tests/mkiv/pages/ornaments-001.tex + % as WS found out so we have to wait till the next side + % effect shows up + % \ifcase\pageornamentstate\or + \global\chardef\pageornamentstate\zerocount + % \fi + \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] + +\unexpanded\def\definepagebreak + {\dodoubleargument\dodefinepagebreak} + +\def\dodefinepagebreak[#1][#2]% non recursive, meant for simple mappings + {\setvalue{\??pe::#1}{#2}} + +% 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}} + +\unexpanded\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 + \csname\??pg#1\c!before\endcsname} + +\def\dobeforeshipout + {\doifsomething\currentpageselection + {\processcommacommand[\currentpageselection]\dodobeforeshipout}} + +\def\dododoaftershipout#1% + {\global\let\aftershipout\relax + \global\let\currentpageselection\empty + \csname\??pg#1\c!after\endcsname} + +\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 + +\unexpanded\def\setupoppositeplacing + {\dodoubleargument\getparameters[\??np]} + +\unexpanded\def\startopposite + {\dowithnextboxcontent + {\hsize\makeupwidth}% + {\global\setbox\facingpage\vbox + {\ifvoid\facingpage + \@@npbefore + \else + \@@npinbetween + \unvbox\facingpage + \fi + \box\nextbox}}% + \vbox\bgroup} + +\unexpanded\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-ins.mkii b/tex/context/base/page-ins.mkii new file mode 100644 index 000000000..069153434 --- /dev/null +++ b/tex/context/base/page-ins.mkii @@ -0,0 +1,103 @@ +%D \module +%D [ file=core-ins, +%D version=2002.04.16, +%D title=\CONTEXT\ Insertion Macros, +%D subtitle=Insertions, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / 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. + +\unprotect + +\newtoks\@@insertionlist + +\def\processinsertions{\the\@@insertionlist} + +\let\doprocessinsert\gobbleoneargument + +%\def\installinsertion#1% +% {\ifx#1\undefined +% \newinsert#1% +% \count#1\plusthousand +% \skip #1\zeropoint +% \dimen#1\maxdimen +% \appendtoks\doprocessinsert#1\to\@@insertionlist +% \fi} + +\def\installinsertion#1% + {\ifx#1\undefined + \let#1\relax + \fi + \ifx#1\relax % permits \csname...\endcsname + \newinsert#1% + \count#1\plusthousand + \skip #1\zeropoint + \dimen#1\maxdimen + \appendtoks\doprocessinsert#1\to\@@insertionlist + \fi} + + +\def\synchronizeinsertions + {\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 The box content is only restores when non||void. + +\def\backupinsertion#1% + {\csname\string#1\endcsname} + +\def\installbackupinsertion#1% + {\expandafter\newinsert\csname\string#1\endcsname + \count\backupinsertion#1\zerocount + \skip \backupinsertion#1\zeropoint + \dimen\backupinsertion#1\maxdimen} + +\def\saveinsertionbox#1% + {\ifdim\ht#1>\zeropoint % hm, actually unknown + \global\setbox\backupinsertion#1\box#1% + \else + \global\setbox\backupinsertion#1\emptybox + \fi} + +\def\restoreinsertionbox#1% + {\ifvoid\backupinsertion#1\else % if void, we keep the content + \global\setbox#1\box\backupinsertion#1% + \fi} + +\def\eraseinsertionbackup#1% + {\global\setbox\backupinsertion#1\emptybox} + +\def\saveinsertiondata#1% + {\global\skip \backupinsertion#1\skip #1% + \global\count\backupinsertion#1\count#1% + \global\dimen\backupinsertion#1\dimen#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: + +\def\addinsertionheight#1\to#2% + {\ifvoid#1\else + \advance#2 1\skip#1\relax + \advance#2 \ht #1\relax + \fi} + +\protect \endinput diff --git a/tex/context/base/page-ins.mkiv b/tex/context/base/page-ins.mkiv new file mode 100644 index 000000000..3e12bfcf0 --- /dev/null +++ b/tex/context/base/page-ins.mkiv @@ -0,0 +1,94 @@ +%D \module +%D [ file=core-ins, +%D version=2002.04.16, +%D title=\CONTEXT\ Insertion Macros, +%D subtitle=Insertions, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / 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. + +\unprotect + +\newtoks\@@insertionlist + +\def\processinsertions{\the\@@insertionlist} + +\let\doprocessinsert\gobbleoneargument + +\def\installinsertion#1% + {\ifdefined#1\else + \let#1\relax + \fi + \ifx#1\relax % permits \csname...\endcsname + \newinsert#1% + \count#1\plusthousand + \skip #1\zeropoint + \dimen#1\maxdimen + \appendtoks\doprocessinsert#1\to\@@insertionlist + \fi} + + +\def\synchronizeinsertions + {\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 The box content is only restores when non||void. + +\def\backupinsertion#1% + {\csname\string#1\endcsname} + +\def\installbackupinsertion#1% + {\expandafter\newinsert\csname\string#1\endcsname + \count\backupinsertion#1\zerocount + \skip \backupinsertion#1\zeropoint + \dimen\backupinsertion#1\maxdimen} + +\def\saveinsertionbox#1% + {\ifdim\ht#1>\zeropoint % hm, actually unknown + \global\setbox\backupinsertion#1\box#1% + \else + \global\setbox\backupinsertion#1\emptybox + \fi} + +\def\restoreinsertionbox#1% + {\ifvoid\backupinsertion#1\else % if void, we keep the content + \global\setbox#1\box\backupinsertion#1% + \fi} + +\def\eraseinsertionbackup#1% + {\global\setbox\backupinsertion#1\emptybox} + +\def\saveinsertiondata#1% + {\global\skip \backupinsertion#1\skip #1% + \global\count\backupinsertion#1\count#1% + \global\dimen\backupinsertion#1\dimen#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: + +\def\addinsertionheight#1\to#2% + {\ifvoid#1\else + \advance#2 1\skip#1\relax + \advance#2 \ht #1\relax + \fi} + +\protect \endinput diff --git a/tex/context/base/page-lay.mkii b/tex/context/base/page-lay.mkii new file mode 100644 index 000000000..de1194c2a --- /dev/null +++ b/tex/context/base/page-lay.mkii @@ -0,0 +1,1429 @@ +%D \module +%D [ file=page-lay, +%D version=2000.10.20, % copied from main-001 +%D title=\CONTEXT\ Page Macros, +%D subtitle=Layout Specification, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Layout Specification} + +%D This module is now etex dependent. + +% to be translated into english + +% hoofdhoogte wordt bij status=hoog niet aangepast op outer +% level, wel binnen bepaalde berekeningen + +%D Before you start wondering why some of the page related +%D modules skip upward or left in order to place elements, you +%D must realize that the reference point is the top left +%D corner of the main typesetting area. One reason for this +%D choice is that it suited some viewers that displayed page +%D areas. Another reason is that margins, edges and top and +%D bottom areas are kind of virtual, while the header, text +%D and footer areas normally determine the text flow. + +\unprotect + +%D First we get rid of the funny \TEX\ offset defaults of one +%D inch by setting them to zero. + +\voffset = 0pt % setting this to -1in let's go metapost crazy +\hoffset = 0pt % setting this to -1in let's go metapost crazy + +%D The dimensions related to layout areas are represented by +%D real dimensions. + +\newdimen\paperheight \paperheight = 297mm +\newdimen\paperwidth \paperwidth = 210mm + +\newdimen\printpaperheight \printpaperheight = \paperheight +\newdimen\printpaperwidth \printpaperwidth = \paperwidth + +\newdimen\makeupheight % calculated +\newdimen\makeupwidth % calculated + +\newdimen\textheight % calculated +\newdimen\textwidth % calculated + +\newdimen\topspace \topspace = 2cm +\newdimen\backspace \backspace = \topspace +\newdimen\cutspace \cutspace = 0pt +\newdimen\bottomspace \bottomspace = 0pt + +\newdimen\headerheight \headerheight = 2cm +\newdimen\footerheight \footerheight = \headerheight + +\newdimen\topoffset \topoffset = 0pt +\newdimen\backoffset \backoffset = \topoffset + +\newdimen\leftmarginwidth \leftmarginwidth = 3cm +\newdimen\rightmarginwidth \rightmarginwidth = \leftmarginwidth + +\newdimen\leftedgewidth \leftedgewidth = 3cm +\newdimen\rightedgewidth \rightedgewidth = \leftedgewidth + +\newdimen\topheight \topheight = 0cm +\newdimen\bottomheight \bottomheight = \topheight + +\newcount\layoutlines \layoutlines = 0 +\newcount\layoutcolumns \layoutcolumns = 0 +\newdimen\layoutcolumndistance \layoutcolumndistance = 0pt +\newdimen\layoutcolumnwidth \layoutcolumnwidth = 0pt + +%D We can save some tokens and fuzzy parameters by using a +%D symbolic name for the current set of layout parameters. + +\let\currentlayout\empty + +\def\layoutparameter#1% + {\csname\??ly\ifcsname + \??ly\currentlayout#1\endcsname\currentlayout + \fi#1\endcsname} + +\def\namedlayoutparameter#1#2% + {\csname\??ly\ifcsname\??ly #1#2\endcsname#1\else + \ifcsname\??ly\currentlayout#2\endcsname\currentlayout + \fi\fi#2\endcsname} + +%D Beause normal \TEX\ has at most 256 dimensions (of which a +%D substantial part is already in use), we provide a way to +%D generate a format with macro based alternatives. For a long +%D time, this used to be the default case. Beware: only fixed +%D dimensions can be used in calculations! By the way, the +%D gain in speed can hardly be called impressive and is roughly +%D 1 second on a 35 second run of 850 empty pages with a +%D couple of backgrounds only (which is far less than one +%D percent on a normal document). + +%D The next series of dimensions are complemented by left +%D and rights ones. + +\newdimen \margindistance +\newdimen \edgedistance +\newdimen \marginwidth +\newdimen \edgewidth + +%D Because a distance does not really makes sense when there +%D is no area, we use a zero distance in case there is no +%D area. + +\def\layoutdistance#1#2% + {\ifdim\zeropoint<#1\layoutparameter#2\else\zeropoint\fi} + +%D The horizontal distances are: + +\newdimen \leftedgedistance +\newdimen \rightedgedistance +\newdimen \leftmargindistance +\newdimen \rightmargindistance + +%D The vertical distances are: + +\newdimen \topdistance +\newdimen \headerdistance +\newdimen \footerdistance +\newdimen \bottomdistance + +%D We need to calculate the extra distances: + +\def\setlayoutdimensions + {\global\marginwidth \layoutparameter\c!margin + \global\edgewidth \layoutparameter\c!edge + \global\margindistance \layoutparameter\c!margindistance + \global\edgedistance \layoutparameter\c!edgedistance + \global\leftedgedistance \layoutdistance \leftedgewidth \c!leftedgedistance + \global\rightedgedistance \layoutdistance \rightedgewidth \c!rightedgedistance + \global\leftmargindistance \layoutdistance \leftmarginwidth \c!leftmargindistance + \global\rightmargindistance\layoutdistance \rightmarginwidth \c!rightmargindistance + \global\topdistance \layoutdistance \topheight \c!topdistance + \global\headerdistance \layoutdistance \headerheight \c!headerdistance + \global\footerdistance \layoutdistance \footerheight \c!footerdistance + \global\bottomdistance \layoutdistance \bottomheight \c!bottomdistance} + +\def\setlayoutdistances % local in \setreducedvsize + {\headerdistance\layoutdistance\headerheight\c!headerdistance + \footerdistance\layoutdistance\footerheight\c!footerdistance} + +% these are wrong in the running text, assumes some swapping, needs a cleanup + +\def\outermarginwidth {\rightorleftpageaction\rightmarginwidth \leftmarginwidth } +\def\innermarginwidth {\rightorleftpageaction\leftmarginwidth \rightmarginwidth} +\def\outermargindistance{\rightorleftpageaction\rightmargindistance\leftmargindistance } +\def\innermargindistance{\rightorleftpageaction\leftmargindistance \rightmargindistance} + +\def\outeredgewidth {\rightorleftpageaction\rightedgewidth \leftedgewidth } +\def\inneredgewidth {\rightorleftpageaction\leftedgewidth \rightedgewidth} +\def\outeredgedistance {\rightorleftpageaction\rightedgedistance\leftedgedistance } +\def\inneredgedistance {\rightorleftpageaction\leftedgedistance \rightedgedistance} + +\def\outerspacewidth {\rightorleftpageaction\cutspace\backspace} +\def\innerspacewidth {\rightorleftpageaction\backspace\cutspace} + +\newtoks\extralayoutcalculations \def\calculatelayoutextras{\the\extralayoutcalculations} + +% \appendtoks +% non etex calculations used to go here +% \to \extralayoutcalculations + +\newtoks\everyswapmargins % watch the order ! + +\appendtoks + \swapdimens\leftmargindistance\rightmargindistance + \swapdimens\leftedgedistance \rightedgedistance + \swapdimens\leftmarginwidth \rightmarginwidth + \swapdimens\leftedgewidth \rightedgewidth +\to \everyswapmargins + +\appendtoks + \swapmacros\leftmargintotal \rightmargintotal + \swapmacros\leftedgetotal \rightedgetotal + \swapmacros\leftsidetotal \rightsidetotal + \swapmacros\leftcombitotal \rightcombitotal + \swapmacros\innermargintotal\outermargintotal + \swapmacros\inneredgetotal \outeredgetotal + \swapmacros\innercombitotal \outercombitotal + \swapmacros\innersidetotal \outersidetotal +\to \everyswapmargins + +%D \macros +%D {definepapersize} +%D +%D Before we start calculating layout dimensions, we will +%D first take care of paper sizes. The first argument can be +%D either an assignment (for defaults) or an identifier, in +%D which case the second argument is an assignment. +%D +%D \showsetup{definepapersize} + +\def\definepapersize + {\dodoubleempty\dodefinepapersize} + +\def\definepapersize + {\dotripleempty\dodefinepapersize} + +\def\dodefinepapersize[#1][#2][#3]% + {\ifsecondargument + \doifsomething{#1} % to be sure + {\doifassignmentelse{#2} + {\getparameters + [\??pp#1] % geen \c!scale, scheelt hash ruimte + [\c!width=\@@ppwidth,\c!height=\@@ppheight,\c!offset=\@@ppoffset,#2]} + {\setvalue{\??pp:1:#1}{#2}% + \setvalue{\??pp:2:#1}{#3}}}% + \else + \getparameters[\??pp][#1]% + \setuppapersize % hm. this will freeze ! + \fi} + +%D For the moment we need to fake this macro. + +\ifx\setuppapersize\undefined + \let\setuppapersize\relax +\fi + +%D We set the defaults to the dimensions of an A4 sheet of +%D paper. + +\definepapersize + [\c!width=210mm,\c!height=297mm,\c!offset=\!!zeropoint] + +%D Yet undocumented, let's see if it gets noticed. +%D +%D \starttyping +%D \definepapersize[main] [A4] [A4] +%D \definepapersize[extra][A4,landscape][A4,landscape] +%D +%D \starttext +%D \setuppapersize[main] +%D Page 1. \page +%D Page 2. \page +%D \setuppapersize[extra] +%D Page 2 \page +%D \setuppapersize[main] +%D Page 3. \page +%D Page 4. \page +%D \adaptpapersize[extra] +%D Page 5. \page +%D Page 6. \page +%D \stoptext +%D \stoptyping + +%D \macros +%D {setuppaper,setuppapersize} +%D +%D When setting up the papersize on which to typeset and +%D print, we can also determine some more characteristics. +%D +%D \showsetup{setuppapersize} +%D +%D We keep track of these features with the following +%D variables. + +\chardef\papermirror =0 \chardef\printmirror =0 +\chardef\paperorientation=0 \chardef\printorientation=0 % beware: later no chardef +\chardef\paperreverse =0 \chardef\printreverse =0 +\chardef\paperlandscape =0 \chardef\printlandscape =0 + +\let\papersize\empty \let\printpapersize\empty + +\def\paperscale{1} \newif\ifnegateprintbox + +\def\setuppaper[#1]% + {\getparameters[\??pp][\c!paper=,\c!page=,#1]% + \edef\@@ppxy{\the\numexpr\@@ppnx*\@@ppny\relax}% + \doifelsenothing\@@pppage + {\doifelsenothing\@@pppaper + {} % {\setuppapersize} % added, removed, no need for, too tricky, mag-01 (fixed by freezing pp's) + {\dodosetuppapersize[\papersize][\@@pppaper]}} + {\doifelsenothing\@@pppaper + {\dodosetuppapersize[\@@pppage][\printpapersize]} + {\dodosetuppapersize[\@@pppage][\@@pppaper]}}} + +\def\setuppapersize + {\dodoubleempty\dosetuppapersize} + +\def\dosetuppapersize[#1][#2]% + {\doifassignmentelse{#1} + {\setuppaper[#1]} + {\doifelsenothing{#2} + {\expanded{\dodosetuppapersize + [\executeifdefined{\??pp:1:#1}{#1}]% + [\executeifdefined{\??pp:2:#1}{}]}} + {\doifassignmentelse{#2} + {\getparameters[\??pp\executeifdefined{\??pp:1:#1}{#1}][#2]} + {\expanded{\dodosetuppapersize + [\executeifdefined{\??pp:1:#1}{#1}]% + [\executeifdefined{\??pp:1:#2}{#2}]}}}}} + +\let\reinstatepapersize\relax + +\def\adaptpapersize + {\global\let\reinstatepapersize\restorepapersize + \setuppapersize} + +\appendtoks + \reinstatepapersize + \global\let\reinstatepapersize\relax +\to \everyaftershipout + +\def\dodosetuppapersize[#1][#2]% + {\ifsecondargument + \expanded{\dododosetuppapersize[#1][#2]}% + \calculatehsizes + \calculatevsizes + \recalculatelogos + \recalculatebackgrounds + \recalculatelayout + \else\iffirstargument + \setuppapersize[#1][#2]% + \else\ifx\papersize\undefined\else + \restorepapersize + \fi\fi\fi} + +% dimen freeze is a bit tricky, but catches local redundant calls +% with values where e.g width is defined in terms of \paperwidth + +\def\dododosetuppapersize[#1][#2]% + {\xdef\restorepapersize{\noexpand\setuppapersize[#1][#2]}% + \dosetuppaperorientation{#1}\paperlandscape\paperorientation\paperreverse\papermirror + \dosetuppaperorientation{#2}\printlandscape\printorientation\printreverse\printmirror + \def\docommand##1% + {\doifsomething{##1}{\doifdefined{\??pp##1\c!width} + {\global\paperwidth \getvalue{\??pp##1\c!width}% + \global\paperheight\getvalue{\??pp##1\c!height}% +\ifinpagebody + \setevalue{\??pp##1\c!height}{\the\paperheight}% + \setevalue{\??pp##1\c!width }{\the\paperwidth }% +\fi + \calculatepaperoffsets{##1}% + \xdef\papersize{##1}}}}% + \processcommacommand[#1]\docommand + \doifdefinedelse{\??pp#1\c!scale} + {\edef\paperscale{\getvalue{\??pp#1\c!scale}}} + {\edef\paperscale{1}}% + \def\docommand##1% + {\doifsomething{##1}{\doifdefined{\??pp##1\c!width} + {\global\printpaperwidth \getvalue{\??pp##1\c!width}% + \global\printpaperheight\getvalue{\??pp##1\c!height}% +\ifinpagebody + \setevalue{\??pp##1\c!height}{\the\printpaperheight}% + \setevalue{\??pp##1\c!width }{\the\printpaperwidth}% +\fi + \xdef\printpapersize{##1}}}}% + \processcommacommand[#2]\docommand + \global\setdimentoatleast\paperwidth \onepoint + \global\setdimentoatleast\paperheight \onepoint + \global\setdimentoatleast\printpaperwidth \onepoint + \global\setdimentoatleast\printpaperheight\onepoint + \ifcase\paperlandscape\else + \doglobal\swapdimens\paperwidth\paperheight + \fi + \ifcase\printlandscape\else + \doglobal\swapdimens\printpaperwidth\printpaperheight + \fi + % this check can be confusing, so we've added the possibility + % to bypass this test: \setuppapersize[option=fit] + \doif\@@ppoption\v!max % \v!fit is + {\bgroup + % we need to pre-swap else we get the wrong paper size + \ifcase\paperorientation\else + \doifinset\paperorientation{90,270}{\swapdimens\paperwidth\paperheight}% + \fi + \ifcase\printorientation\else + \doifinset\printorientation{90,270}{\swapdimens\printpaperwidth\printpaperheight}% + \fi + \ifdim\paperheight>\printpaperheight + \global\printpaperheight\paperheight + \writestatus\m!systems{print height forced to paper height}% + \fi + \ifdim\paperwidth>\printpaperwidth + \global\printpaperwidth\paperwidth + \writestatus\m!systems{print width forced to paper width}% + \fi + \egroup}} + +\def\dosetuppaperorientation#1#2#3#4#5% + {\global\chardef#2\zerocount + \global\chardef#5\zerocount + \globallet#3\!!zerocount + \globallet#4\!!zerocount + \global\negateprintboxfalse + \processallactionsinset + [#1] + [ \v!landscape=>\global\chardef#2\plusone, + \v!mirrored=>\global\chardef#5\plusone, + \v!rotated=>\gdef#3{90}\gdef#4{270}, + \v!negative=>\global\negateprintboxtrue, + 90=>\gdef#3{90}\gdef#4{270}, + 180=>\gdef#3{180}\gdef#4{0}, + 270=>\gdef#3{270}\gdef#4{90}]} + +\ifx\calculatepaperoffsets\undefined + + \def\calculatepaperoffsets#1% + {\scratchdimen\getvalue{\??pp#1\c!offset}% + \global\advance\paperwidth -2\scratchdimen + \global\advance\paperheight-2\scratchdimen} + +\fi + +\let\restorepapersize\relax + +\def\checkforems[#1]% + {\def\docommand##1% + {\beforesplitstring##1\at em\to\asciia + \doifnot\asciia{##1} + {\aftersplitstring\asciia\at=\to\asciia + \doifsomething\asciia + {\showmessage\m!systems{10}{##1}}}}% + \processcommalist[#1]\docommand} + +\ifx\setups\undefined \def\setups[#1]{\setdefaultpenalties} \fi + +% \newtoks \everybeforelayout \relax +% \newtoks \everyafterlayout \relax + +\def\recalculatelayout + {\doifsomething{\layoutparameter\c!page\layoutparameter\c!paper} + {\expanded{\dododosetuppapersize[\layoutparameter\c!page][\layoutparameter\c!paper]}}% + \dorecalculatelayout} + +\def\dorecalculatelayout + {%\the\everybeforelayout + \setups[\layoutparameter\c!preset]% + \global\leftmarginwidth \layoutparameter\c!leftmargin + \global\rightmarginwidth\layoutparameter\c!rightmargin + \global\leftedgewidth \layoutparameter\c!leftedge + \global\rightedgewidth \layoutparameter\c!rightedge + \global\headerheight \layoutparameter\c!header + \global\footerheight \layoutparameter\c!footer + \global\bottomheight \layoutparameter\c!bottom + \global\topheight \layoutparameter\c!top + \global\backspace \layoutparameter\c!backspace + \global\topspace \layoutparameter\c!topspace + \setlayoutdimensions % the rest of the `dimensions' + \doifelse\@@lygrid\v!yes\gridsnappingtrue\gridsnappingfalse + \ifgridsnapping + \setsystemmode\v!grid + \else + \resetsystemmode\v!grid + \fi + \setups[\layoutparameter\c!setups]% depends on gridsnapping ! + \simplesetupwhitespace + \simplesetupblank + \global\cutspace\layoutparameter\c!cutspace + \relax + \doifelse{\layoutparameter\c!width}\v!middle + {\ifdim\cutspace=\zeropoint + \global\cutspace\backspace + \fi + \global\makeupwidth\dimexpr\paperwidth-\backspace-\cutspace\relax} + {\doifelse{\layoutparameter\c!width}\v!fit + {\ifdim\cutspace=\zeropoint + \global\cutspace\backspace + \fi + \global\makeupwidth\dimexpr\paperwidth-\cutspace\relax + \scratchdimen\dimexpr\backspace + -\leftedgewidth -\leftedgedistance + -\leftmarginwidth-\leftmargindistance\relax + \ifdim\scratchdimen<\zeropoint + \scratchdimen\zeropoint + \fi + \global\advance\makeupwidth\dimexpr + -\rightmargindistance-\rightmarginwidth + -\rightedgedistance -\rightedgewidth + -\scratchdimen\relax} + {\global\makeupwidth\layoutparameter\c!width\relax + \ifdim\cutspace=\zeropoint + \global\cutspace\dimexpr\paperwidth-\makeupwidth-\backspace\relax + % \else + % A kind of inconsistent specification, but used + % in for instance s-pre-19.tex; the cutspace is + % used only for determining some kind of right + % margin; don't use this in doublesided mode + \fi}}% + \scratchdimen\layoutparameter\c!bottomspace\relax + %\ifdim\scratchdimen=\zeropoint + % \scratchdimen\topspace + %\fi + \global\bottomspace\layoutparameter\c!bottomspace\relax + \global\layoutlines0\number\layoutparameter\c!lines\relax % may be empty + \ifcase\layoutlines + \doifelse{\layoutparameter\c!height}\v!middle + {\ifdim\bottomspace=\zeropoint + \global\bottomspace\topspace + \fi + \global\makeupheight\dimexpr\paperheight-\topspace-\bottomspace\relax} + {\doifelse{\layoutparameter\c!height}\v!fit + {\ifdim\bottomspace=\zeropoint + \global\bottomspace\topspace + \fi + \global\makeupheight\dimexpr\paperheight-\bottomspace\relax + \scratchdimen\dimexpr\topspace-\topheight-\topdistance\relax + \ifdim\scratchdimen<\zeropoint + \scratchdimen\zeropoint + \fi + \global\advance\makeupheight\dimexpr-\bottomdistance-\bottomheight-\scratchdimen\relax} + {\global\makeupheight\layoutparameter\c!height\relax + \ifdim\bottomspace=\zeropoint + \global\bottomspace\dimexpr\paperheight-\makeupheight-\topspace\relax + \else + % inconsistent specification + \fi}}% + \else + % beware, when the bodyfont changes (switched) this will change as well; implementing + % a global lineheight is tricky: should we take the bodyfont interlinespace or the one set + % independent of the bodyfont (before or after a layout spec); way too fuzzy, so we + % stick to the current method (after a night of experimenting ...2003/10/13) + \global\makeupheight\dimexpr + \layoutparameter\c!lines\lineheight-\strutheight+\topskip+ + \headerdistance+\headerheight+\footerdistance+\footerheight\relax + \fi + \backoffset\layoutparameter\c!horoffset + \topoffset \layoutparameter\c!veroffset + \global\setdimentoatleast\makeupwidth\onepoint + \global\setdimentoatleast\makeupheight \onepoint + % \checkcurrentlayout % here ? + % \the\everyafterlayout + \calculatelayoutextras + \calculatehsizes + \calculatevsizes + \calculatepseudocolumns + \checkgridsnapping + \recalculatelogos + \recalculatebackgrounds} + +\def\calculatepseudocolumns + {\global\layoutcolumns\layoutparameter\c!columns + \global\layoutcolumndistance\layoutparameter\c!columndistance + \global\layoutcolumnwidth\dimexpr\makeupwidth-\layoutcolumns\layoutcolumndistance+\layoutcolumndistance\relax + \global\divide\layoutcolumnwidth\layoutcolumns + \dorecurse\layoutcolumns + {\setxvalue{\??ly:c:\recurselevel}% + {\the\numexpr\recurselevel-\plusone\relax\dimexpr\layoutcolumnwidth+\layoutcolumndistance\relax}}} + +%\dorecurse\layoutcolumns +% {\setxvalue{\??ly:c:\recurselevel}{\the\dimexpr +% (\numexpr(\recurselevel-1)\dimexpr(\layoutcolumnwidth+\layoutcolumndistance))}} + +\def\layoutcolumnoffset#1% + {\executeifdefined{\??ly:c:#1}\!!zeropoint} + +\def\checklayout + {\ifdim\makeupheight=\layoutlines\lineheight \else \recalculatelayout \fi} + +\appendtoks \checklayout \to \everystarttext + +% document: +% +% \setuplayout[odd][state=stop] \setuplayout[even][state=stop] \setuplayout[page] +% +% \startstandardmakeup[page=blank] ... \stopstandardmakeup + +\def\changetolayout#1% + {%\writestatus\m!layouts{changing to layout #1}% + \xdef\currentlayout{#1}\recalculatelayout} + +\def\checkcurrentoddlayout + {\ifcsname\??ly\v!odd\c!state\endcsname + \doifvalue{\??ly\v!odd\c!state}\v!start{\changetolayout\v!odd}% + \fi} + +\def\checkcurrentevenlayout + {\ifcsname\??ly\v!even\c!state\endcsname + \doifvalue{\??ly\v!even\c!state}\v!start{\changetolayout\v!even}% + \fi} + +\ifx\lastpage\undefined \def\lastpage{1} \fi + +\def\reverserealfolio + {\ifnum\lastpage>\plusone + \ifnum\lastpage=\realfolio + \v!last + \else\ifnum\plusone=\realfolio + \v!first + \else + \the\numexpr\realfolio-\lastpage\relax + \fi\fi + \else + \!!zerocount + \fi} + +\def\checkcurrentlayout % public and used in naw, so keep this name + {\ifcsname\??ly\realfolio\c!state\endcsname + \doifvalue{\??ly\realfolio\c!state}\v!start{\changetolayout\realfolio}% + \else\ifcsname\??ly\reverserealfolio\c!state\endcsname + \doifvalue{\??ly\reverserealfolio\c!state}\v!start{\changetolayout\reverserealfolio}% + \else\ifcsname\??ly\v!current\c!state\endcsname + \changetolayout\v!current % no start test ? + \else + \doifoddpageelse\checkcurrentoddlayout\checkcurrentevenlayout + \fi\fi\fi} + +% testcase +% +% \setuppagenumbering[alternative=doublesided] +% +% \setuplayout [width=11cm] +% \definelayout [odd] [backspace=1cm] +% \definelayout [even] [backspace=4cm] +% \definelayout [5] [backspace=5cm] +% \definelayout [6] [backspace=5cm] +% \definelayout [-2] [backspace=0cm,cutspace=0cm] +% \definelayout [last] [backspace=0cm,cutspace=0cm] +% +% \checkcurrentlayout \showframe +% +% \starttext +% \dorecurse{20} {\input knuth \endgraf \input tufte \endgraf} +% \stoptext + +%appendtoks \checkcurrentlayout \to \everyaftershipout % no +\appendtoks \checkcurrentlayout \to \everystarttext + +\appendtoks + \dochecknextlayout +\to \everyaftershipout + +% \def\dochecknextlayout +% {\ifx\currentlayout\v!current +% % prevent redundant calculations +% \else +% \globallet\currentlayout\empty +% \global\letbeundefined{\??ly\v!current\c!state}% +% \checkcurrentlayout +% \fi} +% +% this breaks after a standardmakeup + +\def\dochecknextlayout{\checkcurrentlayout} + +\newif\ifdoublesidedprint + +\def\presetcenterpagebox % in \setuplayout !!!!!!!!!!!!!!!! + {\doublesidedprintfalse + \ExpandFirstAfter\processallactionsinset + [\@@lylocation] + [ \v!middle=>{\setuppapersize[\c!left=\hss,\c!right=\hss,\c!top=\vss,\c!bottom=\vss]}, + \v!left=>{\setuppapersize[\c!left=,\c!right=\hss]}, + \v!right=>{\setuppapersize[\c!left=\hss,\c!right=]}, + \v!bottom=>{\setuppapersize[\c!top=\vss,\c!bottom=]}, + \v!top=>{\setuppapersize[\c!top=,\c!bottom=\vss]},% + \v!doublesided=>\doublesidedprinttrue, + \v!singlesided=>\doublesidedprintfalse]} + +\def\definelayout + {\dodoubleargument\dodefinelayout} + +\def\dodefinelayout[#1][#2]% + {\getparameters[\??ly#1][\c!state=\v!start,#2]} + +\def\dodosetuplayout[#1][#2]% + {\ConvertToConstant\doifnot{#2}\v!reset % #2 ? + {\getparameters[\??ly#1][#2]% + \checkforems[#2]}} + +% global needed for non-doublesided standardmakeup + +\def\dosetuplayout[#1][#2]% + {\globallet\currentlayout\empty % new, global + \ifsecondargument + \dodosetuplayout[#1][#2]% + \else\iffirstargument + \doifassignmentelse{#1} + {\dodosetuplayout[][#1]} + {\doifnot{#1}\v!reset{\xdef\currentlayout{#1}}}% new, global + \fi\fi + \recalculatelayout + \checkcurrentlayout % here ? + \presetcenterpagebox} + +\def\setuplayout + {\dodoubleempty\dosetuplayout} + +\let\@@zaheight=\!!zeropoint + +\def\dopushpagedimensions + {\xdef\oldtextheight {\the\textheight }% + \xdef\oldfooterheight{\the\footerheight}% + \global\let\@@zaheight\@@zaheight} + +\def\dopoppagedimensions + {\global\textheight \oldtextheight + \global\footerheight\oldfooterheight + \recalculatelayout + \global\let\pushpagedimensions\dopushpagedimensions + \global\let\poppagedimensions\relax} + +\let\poppagedimensions = \relax +\let\pushpagedimensions = \dopushpagedimensions + +% Elke \csname ... \endcsname wordt ook aangemaakt, dus ook +% in een test met \doifdefined. Bij veel bladzijden kan dit +% te veel macro's kosten. Vandaar de set \adaptedpages. Het +% kost tijd, maar scheelt macro's. + +\let\adaptedpages\empty + +\def\adaptpagedimensions + {\ifx\adaptedpages\empty\else + \rawdoifinsetelse\realfolio\adaptedpages + {\getvalue{\??za\realfolio}% + \letbeundefined{\??za\realfolio}} + \donothing + \fi} + +\def\checkpagedimensions + {\poppagedimensions + \adaptpagedimensions} + +\def\reportpagedimensions + {\ifx\poppagedimensions\relax \else + \space\the\dimexpr\@@zaheight\relax\space-\space + \fi + \realfolio} + +\def\dodoadaptlayout[#1]% + {\getparameters[\??za][\c!height=,\c!lines=0,#1]% + \pushpagedimensions + \ifcase\@@zalines\relax + \showmessage\m!layouts1{\@@zaheight,\realfolio}% + \else + \showmessage\m!layouts1{\@@zalines\space\v!lines,\realfolio}% + \def\@@zaheight{\@@zalines\openlineheight}% + \fi + \doifelse\@@zaheight\v!max + {\balancedimensions\textheight\footerheight\footerheight} + {\balancedimensions\textheight\footerheight\@@zaheight}% + \ifdim\footerheight<\zeropoint + \global\advance\textheight \footerheight + \global\footerheight\zeropoint + \global\xdef\@@zaheight{\layoutparameter\c!footer\space(\v!max)}% + \fi + \setvsize + \global\pagegoal\vsize % nog corrigeren voor insertions ? + \recalculatelogos + \recalculatebackgrounds + \global\let\pushpagedimensions\relax + \global\let\poppagedimensions\dopoppagedimensions} + +\def\doadaptlayout[#1][#2]% + {\doifelsenothing{#2} + {\dodoadaptlayout[#1]} + {\def\docommand##1% + {\addtocommalist{##1}\adaptedpages + \setgvalue{\??za##1}{\dodoadaptlayout[#2]}}% + \processcommalist[#1]\docommand + \adaptpagedimensions}} + +\def\adaptlayout + {\dodoubleempty\doadaptlayout} + +% describe interface + +%D Centering the paper area on the print area is determined +%D by the \type {top}, \type {bottom}, \type {left} and \type +%D {right} parameters. + +\def\centerpagebox#1% + {\printpaperwidth \paperscale\printpaperwidth + \printpaperheight\paperscale\printpaperheight + \setbox#1\vbox to \printpaperheight + {\@@pptop + \hbox to \printpaperwidth + {\ifdoublesidedprint + \doifbothsides + {\@@ppleft \box#1\@@ppright} + {\@@ppleft \box#1\@@ppright} + {\@@ppright\box#1\@@ppleft }% + \else + \@@ppleft \box#1\@@ppright + \fi}% + \par + \@@ppbottom}} + +\def\offsetprintbox#1% + {\ifdim\topoffset=\zeropoint % \relax + \ifdim\backoffset=\zeropoint + \donefalse + \else + \donetrue + \fi + \else + \donetrue + \fi + \ifdone + \edef\next{\wd#1\the\wd#1\ht#1\the\ht#1\dp#1\the\dp#1}% + \setbox#1\vbox + {%\forgetall + \offinterlineskip + \vskip\topoffset + \doifbothsides{\hskip\backoffset}{\hskip\backoffset}{\hskip-\backoffset}% + \box#1}% + \next + \fi} + +\def\replicatepagebox#1% + {\ifnum\@@lynx>\plusone + \donetrue + \else\ifnum\@@lyny>\plusone + \donetrue + \else + \donefalse + \fi\fi + \ifdone + \setbox#1\vbox + {%\forgetall + \offinterlineskip + \dorecurse\@@lyny + {\hbox{\dorecurse\@@lynx{\copy#1\hskip\@@lydx}\unskip}% + \vskip\@@lydy} + \unskip}% + \fi} + +\def\orientpagebodybox#1#2#3% + {\ifnum#2#3>\zerocount + \setbox#1\vbox + {\edef\somerotation{\ifdoublesided\ifodd\realpageno#2\else#3\fi\else#2\fi}% + \dorotatebox\somerotation\hbox{\box#1}}% + \fi} + +\def\orientpaperbox#1% + {\orientpagebodybox{#1}\paperorientation\paperreverse} + +\def\orientprintbox#1% + {\orientpagebodybox{#1}\printorientation\printreverse} + +\def\mirrorpagebodybox#1#2% + {\ifcase#2\or + \setbox#1\vbox + {\domirrorbox\vbox{\box#1}}% + \fi} + +\def\mirrorpaperbox#1% + {\mirrorpagebodybox{#1}\papermirror} + +\def\mirrorprintbox#1% + {\mirrorpagebodybox{#1}\printmirror} + +\def\scalepagebox#1% + {\ifdim\@@lyscale\points=\onepoint \else + \setbox#1\vbox + {\scale[\c!sx=\@@lyscale,\c!sy=\@@lyscale]{\box#1}}% + \paperwidth\@@lyscale\paperwidth + \paperheight \@@lyscale\paperheight + \fi} + +\def\negateprintbox#1% + {\ifnegateprintbox + \negatecolorbox{#1}% + \fi} + +\def\pagecutmarksymbol {\the\realpageno} +\def\pagecutmarklength {.5cm} +\let\pagecutmarktoptext \empty +\let\pagecutmarkbottomtext \empty + +\def\extrapagecutmarkbottomtext + {\rlap{\jobname}\hfill\currentdate\space-\space\currenttime\hfill\llap{\realfolio}} + +\def\makepagecutbox % #1 + {\let\cutmarksymbol \pagecutmarksymbol + \let\cutmarklength \pagecutmarklength + \let\cutmarktoptext \pagecutmarktoptext + \let\cutmarkbottomtext\pagecutmarkbottomtext + \makecutbox} + +\setvalue{\??ly:n:\c!marking:\v!on}% + {\makepagecutbox} + +\setvalue{\??ly:n:\c!marking:\v!page}% only at outer when nx/ny > 0 + {\makepagecutbox} + +\setvalue{\??ly:n:\c!marking:\v!empty}% + {\let\pagecutmarksymbol\empty + \let\pagecutmarktoptext\empty + \let\pagecutmarkbottomtext\empty + \makepagecutbox} + +\setvalue{\??ly:n:\c!marking:\v!text}% + {\let\pagecutmarksymbol\empty + \let\pagecutmarkbottomtext\extrapagecutmarkbottomtext + \makepagecutbox} + +\setvalue{\??ly:c:\c!marking:\v!color}% + {\doaddpagecolormarks\colormarkbox} + +\setvalue{\??ly:c:\c!marking:\v!screen}% + {\doaddpagecolormarks\rastermarkbox} + +\def\addpagecutmarks % #1 + {\executeifdefined{\??ly:n:\c!marking:\@@lymarking}\gobbleoneargument} + +\def\addpagecolormarks % #1 + {\executeifdefined{\??ly:c:\c!marking:\@@lymarking}\gobbleoneargument} + +\def\doaddpagecolormarks#1#2% + {\makepagecutbox{#2}% + \ifnum\horizontalcutmarks>2 \chardef\colormarkoffset4 \fi + \ifnum\verticalcutmarks >2 \chardef\colormarkoffset4 \fi + #1{#2}} + +% NOG EENS NAGAAN WANNEER NU GLOBAL EN WANNEER NIET + +\ifx\doifelselayoutsomeline\undefined % defined in page-txt + \let\doifelselayoutsomeline\secondofthreearguments +\fi + +\def\calculatevsizes % global needed in \recalculatelayoutregel + {\redoglobal\textheight\makeupheight + \doifelselayoutsomeline \v!header + {\redoglobal\advance\textheight-\dimexpr\headerheight+\headerdistance\relax}% + \donothing + \doifelselayoutsomeline \v!footer + {\redoglobal\advance\textheight-\dimexpr\footerheight+\footerdistance\relax}% + \donothing + \ifzeropt\headerheight + \resetsystemmode\v!header + \else + \setsystemmode\v!header + \fi + \ifzeropt\footerheight + \resetsystemmode\v!footer + \else + \setsystemmode\v!footer + \fi + \resetglobal + \setvsize} + +\def\calculatereducedvsizes + {\textheight\makeupheight + \doifelselayoutsomeline \v!header + {\advance\textheight-\dimexpr\headerheight+\headerdistance\relax}% + {\headerheight\zeropoint + \setlayoutdistances}% + \doifelselayoutsomeline \v!footer + {\advance\textheight-\dimexpr\footerheight+\footerdistance\relax}% + {\footerheight\zeropoint + \setlayoutdistances}} + +\newdimen\innermakeupwidth % special purpose +\newdimen\innermakeupmargin % special purpose + +\chardef\innermakeupcompensation\plusone + +\def\compensatedinnermakeupmargin + {\dimexpr\ifnum\innermakeupcompensation=\plusone+\innermakeupmargin\else\zeropoint\fi\relax} + +\def\freezetextwidth % \makeupwidth may be set to \textwidth + {\textwidth\makeupwidth % which is a tricky but valid value + \doifsomething{\layoutparameter\c!textwidth} + {\textwidth\layoutparameter\c!textwidth}% % local + \global\innermakeupwidth\textwidth + \doifelsenothing{\layoutparameter\c!textmargin} + {\global\innermakeupmargin\zeropoint} + {\global\innermakeupmargin\layoutparameter\c!textmargin}% + \global\advance\innermakeupwidth-\dimexpr\innermakeupmargin+\innermakeupmargin\relax + \advance\textwidth-\dimexpr\innermakeupmargin+\innermakeupmargin\relax} % local + +\def\calculatehsizes + {\freezetextwidth + \sethsize} + +% De onderstaande macro voert commando's uit, afhankelijk van +% het karakter van het paginanummer. +% +% \doifoddpageelse{then-commando}{else-commando} + +%D When we start at an even page, we need to swap the layout +%D differently. We cannot adapt the real page number, since +%D it is used in cross referencing. The next switch is set +%D when we start at an even page. + +\newif\ifshiftedrealpageno + +% \def\doifoddpageelse#1#2% +% {\ifshiftedrealpageno +% \ifodd\realpageno#2\else#1\fi +% \else +% \ifodd\realpageno#1\else#2\fi +% \fi} + +\def\doifoddpageelse + {\ifshiftedrealpageno + \ifodd\realpageno + \@EAEAEA\secondoftwoarguments + \else + \@EAEAEA\firstoftwoarguments + \fi + \else + \ifodd\realpageno + \@EAEAEA\firstoftwoarguments + \else + \@EAEAEA\secondoftwoarguments + \fi + \fi} + +\let\doifonevenpaginaelse\doifoddpageelse + +% what are those \relax'es doing there? + +% \def\doifbothsidesoverruled#1#2#3% +% {\ifdoublesided +% \doifoddpageelse{#2}{#3}\relax +% \else +% #1\relax +% \fi} + +% \def\doifbothsides#1#2#3% +% {\ifdoublesided +% \ifsinglesided +% #1\relax +% \else +% \doifoddpageelse{#2}{#3}\relax +% \fi +% \else +% #1\relax +% \fi} + +\def\redoifoddpageelse#1{\doifoddpageelse} + +\def\doifbothsidesoverruled + {\ifdoublesided + \@EA\redoifoddpageelse + \else + \@EA\firstofthreearguments + \fi} + +\def\doifbothsides + {\ifdoublesided + \ifsinglesided + \@EAEAEA\firstofthreearguments + \else + \@EAEAEA\redoifoddpageelse + \fi + \else + \@EA\firstofthreearguments + \fi} + +\newdimen\texthoffset + +\def\settexthoffset + {\doifbothsides + {\texthoffset\backspace} + {\texthoffset\backspace} + {\texthoffset\dimexpr\paperwidth-\backspace-\makeupwidth\relax}} + +\def\goleftonpage + {\hskip-\dimexpr\leftmargindistance+\leftmarginwidth+\leftedgedistance+\leftedgewidth\relax} + +\def\doifmarginswapelse#1#2% + {\doifbothsides{#1}{#1}{#2}} + +\def\swapmargins + {\doifmarginswapelse\relax\doswapmargins} + +\def\doswapmargins + {\let\swapmargins \relax % to prevent local swapping + \let\doswapmargins\relax % to prevent local swapping + \the\everyswapmargins} + +\def\rightorleftpageaction + {\ifdoublesided + \ifsinglesided + \@EAEAEA\firstoftwoarguments + \else + \@EAEAEA\doifoddpageelse + \fi + \else + \@EA\firstoftwoarguments + \fi} + +\def\outermarginwidth {\rightorleftpageaction\rightmarginwidth \leftmarginwidth } +\def\innermarginwidth {\rightorleftpageaction\leftmarginwidth \rightmarginwidth} +\def\outermargindistance{\rightorleftpageaction\rightmargindistance\leftmargindistance } +\def\innermargindistance{\rightorleftpageaction\leftmargindistance \rightmargindistance} + +\def\outeredgewidth {\rightorleftpageaction\rightedgewidth \leftedgewidth } +\def\inneredgewidth {\rightorleftpageaction\leftedgewidth \rightedgewidth} +\def\outeredgedistance {\rightorleftpageaction\rightedgedistance\leftedgedistance } +\def\inneredgedistance {\rightorleftpageaction\leftedgedistance \rightedgedistance} + +\def\outerspacewidth {\rightorleftpageaction\cutspace \backspace } +\def\innerspacewidth {\rightorleftpageaction\backspace\cutspace} + +\def\leftmargintotal {\dimexpr\leftmarginwidth +\leftmargindistance \relax} +\def\rightmargintotal {\dimexpr\rightmarginwidth+\rightmargindistance\relax} +\def\leftedgetotal {\dimexpr\leftedgewidth +\leftedgedistance \relax} +\def\rightedgetotal {\dimexpr\rightedgewidth +\rightedgedistance \relax} + +\def\leftsidetotal {\dimexpr\leftmarginwidth +\leftedgetotal \relax} +\def\rightsidetotal {\dimexpr\rightmarginwidth+\rightedgetotal\relax} +\def\leftcombitotal {\dimexpr\leftmargintotal +\leftedgetotal \relax} +\def\rightcombitotal {\dimexpr\rightmargintotal+\rightedgetotal\relax} + +\def\innermargintotal {\dimexpr\innermarginwidth+\innermargindistance\relax} +\def\outermargintotal {\dimexpr\outermarginwidth+\outermargindistance\relax} +\def\inneredgetotal {\dimexpr\inneredgewidth +\inneredgedistance \relax} +\def\outeredgetotal {\dimexpr\outeredgewidth +\outeredgedistance \relax} + +\def\innercombitotal {\dimexpr\innermargintotal+\inneredgetotal\relax} +\def\outercombitotal {\dimexpr\outermargintotal+\outeredgetotal\relax} +\def\innersidetotal {\dimexpr\innermarginwidth+\inneredgetotal\relax} +\def\outersidetotal {\dimexpr\outermarginwidth+\outeredgetotal\relax} + +%D \macros +%D {startlocallayout} +%D +%D These macros should be used with care. They permit local +%D layouts (as used in fitting pages, see \type {page-app.tex}). + +%D This is kind of obsolete now that we have \type +%D {\definelayout}, so this hack will disappear in future +%D versions. + +\def\startlocallayout + {\globalpushmacro\restorepapersize + \globalpushmacro\currentlayout} + +\def\stoplocallayout + {\globalpopmacro\currentlayout + \globalpopmacro\restorepapersize + \restorepapersize + \setuplayout} + +%D \macros +%D {showprint, showframe, showlayout, showsetups} +%D +%D We predefine a couple of tracing macros. +%D +%D \showsetup{showprint} +%D \showsetup{showframe} +%D \showsetup{showlayout} +%D \showsetup{showsetups} +%D %showsetup{showmargins} + +\fetchruntimecommand \showprint {page-run.mkii} +\fetchruntimecommand \showframe {page-run.mkii} +\fetchruntimecommand \showlayout {page-run.mkii} +\fetchruntimecommand \showsetups {page-run.mkii} +\fetchruntimecommand \showmargins {page-run.mkii} + +%D The default dimensions are quite old and will not change. +%D The funny fractions were introduced when we went from fixed +%D dimensions to relative ones. Since \CONTEXT\ is a dutch +%D package, the dimensions are based on the metric system. The +%D asymmetrical layout is kind of handy for short +%D quick||and||dirty stapled documents. +%D +%D Although valid, it is not a real good idea to use +%D dimensions based on the \type {em} unit. First of all, +%D since there are no fonts loaded yet, this dimension makes +%D no sense, and second, you would loose track of values, +%D since they could change while going to a new page, +%D depending on the current font setting. + +\setuplayout + [ \c!topspace=.08417508418\paperheight, % 2.5cm + \c!top=\!!zeropoint, + \c!topdistance=\!!zeropoint, + \c!header=.06734006734\paperheight, % 2.0cm + \c!headerdistance=\!!zeropoint, + \c!height=.84175084175\paperheight, % 25.0cm + \c!footerdistance=\layoutparameter\c!headerdistance, + \c!footer=.06734006734\paperheight, % 2.0cm + \c!bottomdistance=\layoutparameter\c!topdistance, + \c!bottom=\!!zeropoint, + \c!backspace=.11904761905\paperwidth, % 2.5cm + \c!edge=\!!zeropoint, + \c!edgedistance=\layoutparameter\c!margindistance, + \c!margin=.12649983170\paperwidth, % snijwit-2*afstand + \c!margindistance=.02008341748\paperwidth, % 12.0pt + \c!leftedge=\layoutparameter\c!edge, + \c!leftedgedistance=\layoutparameter\c!edgedistance, + \c!leftmargin=\layoutparameter\c!margin, + \c!leftmargindistance=\layoutparameter\c!margindistance, + \c!width=.71428571429\paperwidth, % 15.0cm + \c!rightmargindistance=\layoutparameter\c!margindistance, + \c!rightmargin=\layoutparameter\c!margin, + \c!rightedgedistance=\layoutparameter\c!edgedistance, + \c!rightedge=\layoutparameter\c!edge, + \c!veroffset=\!!zeropoint, + \c!bottomspace=\!!zeropoint, + \c!horoffset=\!!zeropoint, + \c!cutspace=\!!zeropoint, + \c!textwidth=, % dangerous option -> centered / local + \c!textmargin=, % dangerous option -> both sides + \c!textdistance=\!!zeropoint, % shift down on grid + \c!style=, + \c!color=, + \c!marking=\v!off, + \c!location=, % \v!singlesided, but empty is signal + \c!scale=1, + \c!nx=1, + \c!ny=1, + \c!dx=\!!zeropoint, + \c!dy=\!!zeropoint, + \c!grid=\v!no, + \c!preset=, + \c!setups=\systemsetupsprefix\s!default, + \c!clipoffset=\!!zeropoint, + \c!lines=0, + \c!paper=, % for foxet + \c!page=, % for foxet + \c!columns=1, + \c!columndistance=\!!zeropoint] + +%D First we define a whole range of (DIN) papersizes, +%D of which the A-series makes most sense. We enable checking. + +%D We also set some of the parameters that will be used when +%D positioning the typeset paper onto the print paper. + +\setuppaper % (size) % only used in XY imposition + [\c!width=\zeropoint, + \c!height=\zeropoint, + \c!topspace=\zeropoint, + \c!backspace=\zeropoint, + \c!dx=\zeropoint, + \c!dy=\zeropoint, + \c!nx=1, + \c!ny=1, + \c!method=\v!normal] + +\setuppapersize + [\c!option=\v!max, + \c!top=, + \c!bottom=\vss, + \c!left=, + \c!right=\hss] + +\definepapersize [A0] [\c!width=841mm,\c!height=1189mm] +\definepapersize [A1] [\c!width=594mm,\c!height=841mm] +\definepapersize [A2] [\c!width=420mm,\c!height=594mm] +\definepapersize [A3] [\c!width=297mm,\c!height=420mm] +\definepapersize [A4] [\c!width=210mm,\c!height=297mm] +\definepapersize [A5] [\c!width=148mm,\c!height=210mm] +\definepapersize [A6] [\c!width=105mm,\c!height=148mm] +\definepapersize [A7] [\c!width=74mm,\c!height=105mm] +\definepapersize [A8] [\c!width=52mm,\c!height=74mm] +\definepapersize [A9] [\c!width=37mm,\c!height=52mm] +\definepapersize [A10] [\c!width=26mm,\c!height=37mm] + +\definepapersize [B0] [\c!width=1000mm,\c!height=1414mm] +\definepapersize [B1] [\c!width=707mm,\c!height=1000mm] +\definepapersize [B2] [\c!width=500mm,\c!height=707mm] +\definepapersize [B3] [\c!width=353mm,\c!height=500mm] % [\c!width=354mm,\c!height=500mm] +\definepapersize [B4] [\c!width=250mm,\c!height=353mm] % [\c!width=250mm,\c!height=354mm] +\definepapersize [B5] [\c!width=176mm,\c!height=250mm] % [\c!width=177mm,\c!height=250mm] +\definepapersize [B6] [\c!width=125mm,\c!height=176mm] % [\c!width=125mm,\c!height=177mm] +\definepapersize [B7] [\c!width=88mm,\c!height=125mm] +\definepapersize [B8] [\c!width=62mm,\c!height=88mm] % [\c!width=63mm,\c!height=88mm] +\definepapersize [B9] [\c!width=44mm,\c!height=62mm] % [\c!width=44mm,\c!height=63mm] +\definepapersize [B10] [\c!width=31mm,\c!height=44mm] + +\definepapersize [C0] [\c!width=917mm,\c!height=1297mm] +\definepapersize [C1] [\c!width=648mm,\c!height=917mm] % [\c!width=649mm,\c!height=917mm] +\definepapersize [C2] [\c!width=458mm,\c!height=648mm] % [\c!width=459mm,\c!height=649mm] +\definepapersize [C3] [\c!width=324mm,\c!height=458mm] % [\c!width=324mm,\c!height=459mm] +\definepapersize [C4] [\c!width=229mm,\c!height=324mm] +\definepapersize [C5] [\c!width=162mm,\c!height=229mm] +\definepapersize [C6] [\c!width=114mm,\c!height=162mm] % [\c!width=115mm,\c!height=162mm] +\definepapersize [C7] [\c!width=81mm,\c!height=114mm] % [\c!width=81mm,\c!height=115mm] +\definepapersize [C8] [\c!width=57mm,\c!height=81mm] +\definepapersize [C9] [\c!width=40mm,\c!height=57mm] +\definepapersize [C10] [\c!width=28mm,\c!height=40mm] + +%D Per August 2004 the rounding of some (seldom used) sizes +%D were corrected top the latest DIN specifications. Peter +%D Rolf came up with these and a few more missing sizes. +%D Watch out: spaces and slashes! + +\definepapersize [4 A0] [\c!width=1682mm,\c!height=2378mm] +\definepapersize [2 A0] [\c!width=1189mm,\c!height=1682mm] +\definepapersize [C6/C5] [\c!width=114mm,\c!height=229mm] + +%D Because there are no standardized screen sizes, we define +%D a bunch of sizes with $4:3$ ratios. The \type {S6} size is +%D nearly as wide as a sheet of \type {A4} paper. + +\definepapersize [S3] [\c!width=300pt,\c!height=225pt] +\definepapersize [S4] [\c!width=400pt,\c!height=300pt] +\definepapersize [S5] [\c!width=500pt,\c!height=375pt] +\definepapersize [S6] [\c!width=600pt,\c!height=450pt] +\definepapersize [S8] [\c!width=800pt,\c!height=600pt] +\definepapersize [SW] [\c!width=800pt,\c!height=450pt] +\definepapersize [SM] [\c!width=720pt,\c!height=450pt] + +%D These are handy too: + +\definepapersize [S33] [\c!width=300pt,\c!height=300pt] +\definepapersize [S44] [\c!width=400pt,\c!height=400pt] +\definepapersize [S55] [\c!width=500pt,\c!height=500pt] +\definepapersize [S66] [\c!width=600pt,\c!height=600pt] + +%D One may wonder if \TEX\ should be used for typesetting +%D \CDROM\ covers, but it does not hurt to have the paper size +%D ready. + +\definepapersize [CD] [\c!width=120mm,\c!height=120mm] + +%D The next series is for our English speaking friends who +%D decided to stick to non metric values. Thanks to Nelson +%D Beebe for completing the inch based list. + +\definepapersize [letter] [\c!width=8.5in,\c!height=11in] +\definepapersize [ledger] [\c!width=11in,\c!height=17in] +\definepapersize [tabloid] [\c!width=17in,\c!height=11in] + +\definepapersize [legal] [\c!width=8.5in,\c!height=14in] +\definepapersize [folio] [\c!width=8.5in,\c!height=13in] +\definepapersize [executive] [\c!width=7.25in,\c!height=10.5in] + +\definepapersize [A] [\c!width=8.5in,\c!height=11in] % 1 sheet +\definepapersize [B] [\c!width=11in,\c!height=17in] % 2 sheets +\definepapersize [C] [\c!width=17in,\c!height=22in] % 4 sheets + +%D The next set is for Tobias Burnus, who gave me the sizes. + +\definepapersize [envelope 9] [\c!width=8.88in,\c!height=3.88in] +\definepapersize [envelope 10] [\c!width=9.5in,\c!height=4.13in] +\definepapersize [envelope 11] [\c!width=10.38in,\c!height=4.5in] +\definepapersize [envelope 12] [\c!width=11.0in,\c!height=4.75in] +\definepapersize [envelope 14] [\c!width=11.5in,\c!height=5.0in] +\definepapersize [monarch] [\c!width=7.5in,\c!height=3.88in] +\definepapersize [check] [\c!width=8.58in,\c!height=3.88in] +\definepapersize [DL] [\c!width=110mm,\c!height=220mm] % [\c!width=220mm,\c!height=110mm] +\definepapersize [E4] [\c!width=280mm,\c!height=400mm] + +%D The next three sets are supplied by Taco: + +\definepapersize [RA0] [\c!width=860mm,\c!height=1220mm] +\definepapersize [RA1] [\c!width=610mm,\c!height=860mm] +\definepapersize [RA2] [\c!width=430mm,\c!height=610mm] +\definepapersize [RA3] [\c!width=305mm,\c!height=430mm] +\definepapersize [RA4] [\c!width=215mm,\c!height=305mm] + +%D ISO SRA (supplementary raw A) sizes: + +\definepapersize [SRA0] [\c!width=900mm,\c!height=1280mm] +\definepapersize [SRA1] [\c!width=640mm,\c!height=900mm] +\definepapersize [SRA2] [\c!width=450mm,\c!height=640mm] +\definepapersize [SRA3] [\c!width=320mm,\c!height=450mm] +\definepapersize [SRA4] [\c!width=225mm,\c!height=320mm] + +%D Swedish thesis formats: + +\definepapersize [G5] [\c!width=169mm,\c!height=239mm] +\definepapersize [E5] [\c!width=155mm,\c!height=220mm] + +%D Industry invention: + +\definepapersize [A3plus] [\c!width=329mm,\c!height=483mm] + +%D We can now default to a reasonable size. We match the print +%D paper size with the typeset paper size. This setting should +%D come after the first layout specification (already done). + +\setuppapersize + [A4][A4] + +%D A few goodies: + +\definepapersize + [oversized] + [ \c!width=\dimexpr\paperwidth +1.5cm\relax, + \c!height=\dimexpr\paperheight+1.5cm\relax] + +\definepapersize + [doublesized] + [ \c!width=\dimexpr \paperwidth \relax, + \c!height=\dimexpr2\paperheight\relax] + +\definepapersize + [doubleoversized] + [ \c!width=\dimexpr \paperheight+1.5cm\relax, + \c!height=\dimexpr2\paperwidth +1.5cm\relax] + +%D For orthogonality: + +\definepapersize + [undersized] + [ \c!width=\dimexpr\paperwidth -1.5cm\relax, + \c!height=\dimexpr\paperheight-1.5cm\relax] + +\definelayout + [\v!page] + [\c!backspace=\zeropoint, + \c!cutspace=\zeropoint, + \c!topspace=\zeropoint, + \c!bottomspace=\zeropoint, + \c!margin=\zeropoint, + \c!edge=\zeropoint, + \c!header=\zeropoint, + \c!footer=\zeropoint, + \c!top=\zeropoint, + \c!bottom=\zeropoint, + \c!leftmargin=\zeropoint, + \c!rightmargin=\zeropoint, + \c!leftedge=\zeropoint, + \c!rightedge=\zeropoint, + \c!textdistance=\zeropoint, + \c!width=\v!middle, + \c!height=\v!middle, + \c!lines=0, + \c!grid=\v!no] + +\definelayout + [\v!middle] + [\c!width=\v!middle, + \c!height=\v!middle] + +\protect \endinput diff --git a/tex/context/base/page-lay.mkiv b/tex/context/base/page-lay.mkiv new file mode 100644 index 000000000..28f9be594 --- /dev/null +++ b/tex/context/base/page-lay.mkiv @@ -0,0 +1,1425 @@ +%D \module +%D [ file=page-lay, +%D version=2000.10.20, % copied from main-001 +%D title=\CONTEXT\ Page Macros, +%D subtitle=Layout Specification, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Layout Specification} + +%D This module is now etex dependent. + +% to be translated into english + +% hoofdhoogte wordt bij status=hoog niet aangepast op outer +% level, wel binnen bepaalde berekeningen + +%D Before you start wondering why some of the page related +%D modules skip upward or left in order to place elements, you +%D must realize that the reference point is the top left +%D corner of the main typesetting area. One reason for this +%D choice is that it suited some viewers that displayed page +%D areas. Another reason is that margins, edges and top and +%D bottom areas are kind of virtual, while the header, text +%D and footer areas normally determine the text flow. + +\unprotect + +%D First we get rid of the funny \TEX\ offset defaults of one +%D inch by setting them to zero. + +\voffset = 0pt % setting this to -1in let's go metapost crazy +\hoffset = 0pt % setting this to -1in let's go metapost crazy + +%D The dimensions related to layout areas are represented by +%D real dimensions. + +\newdimen\paperheight \paperheight = 297mm +\newdimen\paperwidth \paperwidth = 210mm + +\newdimen\printpaperheight \printpaperheight = \paperheight +\newdimen\printpaperwidth \printpaperwidth = \paperwidth + +\newdimen\makeupheight % calculated +\newdimen\makeupwidth % calculated + +\newdimen\textheight % calculated +\newdimen\textwidth % calculated + +\newdimen\topspace \topspace = 2cm +\newdimen\backspace \backspace = \topspace +\newdimen\cutspace \cutspace = 0pt +\newdimen\bottomspace \bottomspace = 0pt + +\newdimen\headerheight \headerheight = 2cm +\newdimen\footerheight \footerheight = \headerheight + +\newdimen\topoffset \topoffset = 0pt +\newdimen\backoffset \backoffset = \topoffset + +\newdimen\leftmarginwidth \leftmarginwidth = 3cm +\newdimen\rightmarginwidth \rightmarginwidth = \leftmarginwidth + +\newdimen\leftedgewidth \leftedgewidth = 3cm +\newdimen\rightedgewidth \rightedgewidth = \leftedgewidth + +\newdimen\topheight \topheight = 0cm +\newdimen\bottomheight \bottomheight = \topheight + +\newcount\layoutlines \layoutlines = 0 +\newcount\layoutcolumns \layoutcolumns = 0 +\newdimen\layoutcolumndistance \layoutcolumndistance = 0pt +\newdimen\layoutcolumnwidth \layoutcolumnwidth = 0pt + +%D We can save some tokens and fuzzy parameters by using a +%D symbolic name for the current set of layout parameters. + +\let\currentlayout\empty + +\def\layoutparameter#1% + {\csname\??ly\ifcsname + \??ly\currentlayout#1\endcsname\currentlayout + \fi#1\endcsname} + +\def\namedlayoutparameter#1#2% + {\csname\??ly\ifcsname\??ly #1#2\endcsname#1\else + \ifcsname\??ly\currentlayout#2\endcsname\currentlayout + \fi\fi#2\endcsname} + +%D Beause normal \TEX\ has at most 256 dimensions (of which a +%D substantial part is already in use), we provide a way to +%D generate a format with macro based alternatives. For a long +%D time, this used to be the default case. Beware: only fixed +%D dimensions can be used in calculations! By the way, the +%D gain in speed can hardly be called impressive and is roughly +%D 1 second on a 35 second run of 850 empty pages with a +%D couple of backgrounds only (which is far less than one +%D percent on a normal document). + +%D The next series of dimensions are complemented by left +%D and rights ones. + +\newdimen \margindistance +\newdimen \edgedistance +\newdimen \marginwidth +\newdimen \edgewidth + +%D Because a distance does not really makes sense when there +%D is no area, we use a zero distance in case there is no +%D area. + +\def\layoutdistance#1#2% + {\ifdim\zeropoint<#1\layoutparameter#2\else\zeropoint\fi} + +%D The horizontal distances are: + +\newdimen \leftedgedistance +\newdimen \rightedgedistance +\newdimen \leftmargindistance +\newdimen \rightmargindistance + +%D The vertical distances are: + +\newdimen \topdistance +\newdimen \headerdistance +\newdimen \footerdistance +\newdimen \bottomdistance + +%D We need to calculate the extra distances: + +\def\setlayoutdimensions + {\global\marginwidth \layoutparameter\c!margin + \global\edgewidth \layoutparameter\c!edge + \global\margindistance \layoutparameter\c!margindistance + \global\edgedistance \layoutparameter\c!edgedistance + \global\leftedgedistance \layoutdistance \leftedgewidth \c!leftedgedistance + \global\rightedgedistance \layoutdistance \rightedgewidth \c!rightedgedistance + \global\leftmargindistance \layoutdistance \leftmarginwidth \c!leftmargindistance + \global\rightmargindistance\layoutdistance \rightmarginwidth \c!rightmargindistance + \global\topdistance \layoutdistance \topheight \c!topdistance + \global\headerdistance \layoutdistance \headerheight \c!headerdistance + \global\footerdistance \layoutdistance \footerheight \c!footerdistance + \global\bottomdistance \layoutdistance \bottomheight \c!bottomdistance} + +\def\setlayoutdistances % local in \setreducedvsize + {\headerdistance\layoutdistance\headerheight\c!headerdistance + \footerdistance\layoutdistance\footerheight\c!footerdistance} + +% these are wrong in the running text, assumes some swapping, needs a cleanup + +\def\outermarginwidth {\rightorleftpageaction\rightmarginwidth \leftmarginwidth } +\def\innermarginwidth {\rightorleftpageaction\leftmarginwidth \rightmarginwidth} +\def\outermargindistance{\rightorleftpageaction\rightmargindistance\leftmargindistance } +\def\innermargindistance{\rightorleftpageaction\leftmargindistance \rightmargindistance} + +\def\outeredgewidth {\rightorleftpageaction\rightedgewidth \leftedgewidth } +\def\inneredgewidth {\rightorleftpageaction\leftedgewidth \rightedgewidth} +\def\outeredgedistance {\rightorleftpageaction\rightedgedistance\leftedgedistance } +\def\inneredgedistance {\rightorleftpageaction\leftedgedistance \rightedgedistance} + +\def\outerspacewidth {\rightorleftpageaction\cutspace\backspace} +\def\innerspacewidth {\rightorleftpageaction\backspace\cutspace} + +\newtoks\extralayoutcalculations \def\calculatelayoutextras{\the\extralayoutcalculations} + +% \appendtoks +% non etex calculations used to go here +% \to \extralayoutcalculations + +\newtoks\everyswapmargins % watch the order ! + +\appendtoks + \swapdimens\leftmargindistance\rightmargindistance + \swapdimens\leftedgedistance \rightedgedistance + \swapdimens\leftmarginwidth \rightmarginwidth + \swapdimens\leftedgewidth \rightedgewidth +\to \everyswapmargins + +\appendtoks + \swapmacros\leftmargintotal \rightmargintotal + \swapmacros\leftedgetotal \rightedgetotal + \swapmacros\leftsidetotal \rightsidetotal + \swapmacros\leftcombitotal \rightcombitotal + \swapmacros\innermargintotal\outermargintotal + \swapmacros\inneredgetotal \outeredgetotal + \swapmacros\innercombitotal \outercombitotal + \swapmacros\innersidetotal \outersidetotal +\to \everyswapmargins + +%D \macros +%D {definepapersize} +%D +%D Before we start calculating layout dimensions, we will +%D first take care of paper sizes. The first argument can be +%D either an assignment (for defaults) or an identifier, in +%D which case the second argument is an assignment. +%D +%D \showsetup{definepapersize} + +\unexpanded\def\definepapersize + {\dodoubleempty\dodefinepapersize} + +\unexpanded\def\definepapersize + {\dotripleempty\dodefinepapersize} + +\def\dodefinepapersize[#1][#2][#3]% + {\ifsecondargument + \doifsomething{#1} % to be sure + {\doifassignmentelse{#2} + {\getparameters + [\??pp#1] % geen \c!scale, scheelt hash ruimte + [\c!width=\@@ppwidth,\c!height=\@@ppheight,\c!offset=\@@ppoffset,#2]} + {\setvalue{\??pp:1:#1}{#2}% + \setvalue{\??pp:2:#1}{#3}}}% + \else + \getparameters[\??pp][#1]% + \setuppapersize % hm. this will freeze ! + \fi} + +%D For the moment we need to fake this macro. + +\ifx\setuppapersize\undefined + \let\setuppapersize\relax +\fi + +%D We set the defaults to the dimensions of an A4 sheet of +%D paper. + +\definepapersize + [\c!width=210mm,\c!height=297mm,\c!offset=\zeropoint] + +%D Yet undocumented, let's see if it gets noticed. +%D +%D \starttyping +%D \definepapersize[main] [A4] [A4] +%D \definepapersize[extra][A4,landscape][A4,landscape] +%D +%D \starttext +%D \setuppapersize[main] +%D Page 1. \page +%D Page 2. \page +%D \setuppapersize[extra] +%D Page 2 \page +%D \setuppapersize[main] +%D Page 3. \page +%D Page 4. \page +%D \adaptpapersize[extra] +%D Page 5. \page +%D Page 6. \page +%D \stoptext +%D \stoptyping + +%D \macros +%D {setuppaper,setuppapersize} +%D +%D When setting up the papersize on which to typeset and +%D print, we can also determine some more characteristics. +%D +%D \showsetup{setuppapersize} +%D +%D We keep track of these features with the following +%D variables. + +\chardef\papermirror =0 \chardef\printmirror =0 +\chardef\paperorientation=0 \chardef\printorientation=0 % beware: later no chardef +\chardef\paperreverse =0 \chardef\printreverse =0 +\chardef\paperlandscape =0 \chardef\printlandscape =0 + +\let\papersize\empty \let\printpapersize\empty + +\def\paperscale{1} \newif\ifnegateprintbox + +\unexpanded\def\setuppaper[#1]% + {\getparameters[\??pp][\c!paper=,\c!page=,#1]% + \edef\@@ppxy{\the\numexpr\@@ppnx*\@@ppny\relax}% + \doifelsenothing\@@pppage + {\doifelsenothing\@@pppaper + {} % {\setuppapersize} % added, removed, no need for, too tricky, mag-01 (fixed by freezing pp's) + {\dodosetuppapersize[\papersize][\@@pppaper]}} + {\doifelsenothing\@@pppaper + {\dodosetuppapersize[\@@pppage][\printpapersize]} + {\dodosetuppapersize[\@@pppage][\@@pppaper]}}} + +\unexpanded\def\setuppapersize + {\dodoubleempty\dosetuppapersize} + +\def\dosetuppapersize[#1][#2]% + {\doifassignmentelse{#1} + {\setuppaper[#1]} + {\doifelsenothing{#2} + {\expanded{\dodosetuppapersize + [\executeifdefined{\??pp:1:#1}{#1}]% + [\executeifdefined{\??pp:2:#1}{}]}} + {\doifassignmentelse{#2} + {\getparameters[\??pp\executeifdefined{\??pp:1:#1}{#1}][#2]} + {\expanded{\dodosetuppapersize + [\executeifdefined{\??pp:1:#1}{#1}]% + [\executeifdefined{\??pp:1:#2}{#2}]}}}}} + +\let\reinstatepapersize\relax + +\def\adaptpapersize + {\global\let\reinstatepapersize\restorepapersize + \setuppapersize} + +\appendtoks + \reinstatepapersize + \global\let\reinstatepapersize\relax +\to \everyaftershipout + +\def\dodosetuppapersize[#1][#2]% + {\ifsecondargument + \expanded{\dododosetuppapersize[#1][#2]}% + \calculatehsizes + \calculatevsizes + \recalculatebackgrounds + \recalculatelayout + \else\iffirstargument + \setuppapersize[#1][#2]% + \else\ifx\papersize\undefined\else + \restorepapersize + \fi\fi\fi} + +% dimen freeze is a bit tricky, but catches local redundant calls +% with values where e.g width is defined in terms of \paperwidth + +\def\dododosetuppapersize[#1][#2]% + {\xdef\restorepapersize{\noexpand\setuppapersize[#1][#2]}% + \dosetuppaperorientation{#1}\paperlandscape\paperorientation\paperreverse\papermirror + \dosetuppaperorientation{#2}\printlandscape\printorientation\printreverse\printmirror + \def\docommand##1% + {\doifsomething{##1}{\doifdefined{\??pp##1\c!width} + {\global\paperwidth \getvalue{\??pp##1\c!width}% + \global\paperheight\getvalue{\??pp##1\c!height}% + \ifinpagebody + \setevalue{\??pp##1\c!height}{\the\paperheight}% + \setevalue{\??pp##1\c!width }{\the\paperwidth }% + \fi + \calculatepaperoffsets{##1}% + \xdef\papersize{##1}}}}% + \processcommacommand[#1]\docommand + \doifdefinedelse{\??pp#1\c!scale} + {\edef\paperscale{\getvalue{\??pp#1\c!scale}}} + {\edef\paperscale{1}}% + \def\docommand##1% + {\doifsomething{##1}{\doifdefined{\??pp##1\c!width} + {\global\printpaperwidth \getvalue{\??pp##1\c!width}% + \global\printpaperheight\getvalue{\??pp##1\c!height}% + \ifinpagebody + \setevalue{\??pp##1\c!height}{\the\printpaperheight}% + \setevalue{\??pp##1\c!width }{\the\printpaperwidth}% + \fi + \xdef\printpapersize{##1}}}}% + \processcommacommand[#2]\docommand + \global\setdimentoatleast\paperwidth \onepoint + \global\setdimentoatleast\paperheight \onepoint + \global\setdimentoatleast\printpaperwidth \onepoint + \global\setdimentoatleast\printpaperheight\onepoint + \ifcase\paperlandscape\else + \doglobal\swapdimens\paperwidth\paperheight + \fi + \ifcase\printlandscape\else + \doglobal\swapdimens\printpaperwidth\printpaperheight + \fi + % this check can be confusing, so we've added the possibility + % to bypass this test: \setuppapersize[option=fit] + \doif\@@ppoption\v!max % \v!fit is + {\bgroup + % we need to pre-swap else we get the wrong paper size + \ifcase\paperorientation\else + \doifinset\paperorientation{90,270}{\swapdimens\paperwidth\paperheight}% + \fi + \ifcase\printorientation\else + \doifinset\printorientation{90,270}{\swapdimens\printpaperwidth\printpaperheight}% + \fi + \ifdim\paperheight>\printpaperheight + \global\printpaperheight\paperheight + \writestatus\m!systems{print height forced to paper height}% + \fi + \ifdim\paperwidth>\printpaperwidth + \global\printpaperwidth\paperwidth + \writestatus\m!systems{print width forced to paper width}% + \fi + \egroup}} + +\def\dosetuppaperorientation#1#2#3#4#5% + {\global\chardef#2\zerocount + \global\chardef#5\zerocount + \globallet#3\!!zerocount + \globallet#4\!!zerocount + \global\negateprintboxfalse + \processallactionsinset + [#1] + [ \v!landscape=>\global\chardef#2\plusone, + \v!mirrored=>\global\chardef#5\plusone, + \v!rotated=>\gdef#3{90}\gdef#4{270}, + \v!negative=>\global\negateprintboxtrue, + 90=>\gdef#3{90}\gdef#4{270}, + 180=>\gdef#3{180}\gdef#4{0}, + 270=>\gdef#3{270}\gdef#4{90}]} + +\ifx\calculatepaperoffsets\undefined + + \def\calculatepaperoffsets#1% + {\scratchdimen\getvalue{\??pp#1\c!offset}% + \global\advance\paperwidth -2\scratchdimen + \global\advance\paperheight-2\scratchdimen} + +\fi + +\let\restorepapersize\relax + +% \def\docheckforems#1% +% {\beforesplitstring#1\at em\to\asciia +% \doifnot\asciia{#1} +% {\aftersplitstring\asciia\at=\to\asciia +% \doifsomething\asciia{\showmessage\m!systems{10}{#1}}}} +% +% \def\checkforems[#1]% +% {\processcommalist[#1]\docheckforems} + +\ifx\setups\undefined \unexpanded\def\setups[#1]{\setdefaultpenalties} \fi + +% \newtoks \everybeforelayout \relax +% \newtoks \everyafterlayout \relax + +\def\recalculatelayout + {\doifsomething{\layoutparameter\c!page\layoutparameter\c!paper} + {\expanded{\dododosetuppapersize[\layoutparameter\c!page][\layoutparameter\c!paper]}}% + \dorecalculatelayout} + +\ifdefined\docheckgridsnapping \else \let\docheckgridsnapping\relax \fi + +\def\dorecalculatelayout + {%\the\everybeforelayout + \setups[\layoutparameter\c!preset]% + \global\leftmarginwidth \layoutparameter\c!leftmargin + \global\rightmarginwidth\layoutparameter\c!rightmargin + \global\leftedgewidth \layoutparameter\c!leftedge + \global\rightedgewidth \layoutparameter\c!rightedge + \global\headerheight \layoutparameter\c!header + \global\footerheight \layoutparameter\c!footer + \global\bottomheight \layoutparameter\c!bottom + \global\topheight \layoutparameter\c!top + \global\backspace \layoutparameter\c!backspace + \global\topspace \layoutparameter\c!topspace + \setlayoutdimensions % the rest of the `dimensions' + \docheckgridsnapping + \doprocesslocalsetups{\layoutparameter\c!setups}% depends on gridsnapping ! + \simplesetupwhitespace + \simplesetupblank + \setupinterlinespace[\v!reset]% \synchronizegloballinespecs + \global\cutspace\layoutparameter\c!cutspace + \relax + \doifelse{\layoutparameter\c!width}\v!middle + {\ifdim\cutspace=\zeropoint + \global\cutspace\backspace + \fi + \global\makeupwidth\dimexpr\paperwidth-\backspace-\cutspace\relax} + {\doifelse{\layoutparameter\c!width}\v!fit + {\ifdim\cutspace=\zeropoint + \global\cutspace\backspace + \fi + \global\makeupwidth\dimexpr\paperwidth-\cutspace\relax + \scratchdimen\dimexpr\backspace + -\leftedgewidth -\leftedgedistance + -\leftmarginwidth-\leftmargindistance\relax + \ifdim\scratchdimen<\zeropoint + \scratchdimen\zeropoint + \fi + \global\advance\makeupwidth\dimexpr + -\rightmargindistance-\rightmarginwidth + -\rightedgedistance -\rightedgewidth + -\scratchdimen\relax} + {\global\makeupwidth\layoutparameter\c!width\relax + \ifdim\cutspace=\zeropoint + \global\cutspace\dimexpr\paperwidth-\makeupwidth-\backspace\relax + % \else + % A kind of inconsistent specification, but used + % in for instance s-pre-19.tex; the cutspace is + % used only for determining some kind of right + % margin; don't use this in doublesided mode + \fi}}% + \scratchdimen\layoutparameter\c!bottomspace\relax + %\ifdim\scratchdimen=\zeropoint + % \scratchdimen\topspace + %\fi + \global\bottomspace\layoutparameter\c!bottomspace\relax + \global\layoutlines0\number\layoutparameter\c!lines\relax % may be empty + \ifcase\layoutlines + \doifelse{\layoutparameter\c!height}\v!middle + {\ifdim\bottomspace=\zeropoint + \global\bottomspace\topspace + \fi + \global\makeupheight\dimexpr\paperheight-\topspace-\bottomspace\relax} + {\doifelse{\layoutparameter\c!height}\v!fit + {\ifdim\bottomspace=\zeropoint + \global\bottomspace\topspace + \fi + \global\makeupheight\dimexpr\paperheight-\bottomspace\relax + \scratchdimen\dimexpr\topspace-\topheight-\topdistance\relax + \ifdim\scratchdimen<\zeropoint + \scratchdimen\zeropoint + \fi + \global\advance\makeupheight\dimexpr-\bottomdistance-\bottomheight-\scratchdimen\relax} + {\global\makeupheight\layoutparameter\c!height\relax + \ifdim\bottomspace=\zeropoint + \global\bottomspace\dimexpr\paperheight-\makeupheight-\topspace\relax + \else + % inconsistent specification + \fi}}% + \else + % beware, when the bodyfont changes (switched) this will change as well; implementing + % a global lineheight is tricky: should we take the bodyfont interlinespace or the one set + % independent of the bodyfont (before or after a layout spec); way too fuzzy, so we + % stick to the current method (after a night of experimenting ...2003/10/13) + \global\makeupheight\dimexpr + \layoutparameter\c!lines\lineheight-\strutheight+\topskip+ + \headerdistance+\headerheight+\footerdistance+\footerheight\relax + \fi + \backoffset\layoutparameter\c!horoffset + \topoffset \layoutparameter\c!veroffset + \global\setdimentoatleast\makeupwidth\onepoint + \global\setdimentoatleast\makeupheight \onepoint + % \checkcurrentlayout % here ? + % \the\everyafterlayout + \calculatelayoutextras + \calculatehsizes + \calculatevsizes + \calculatepseudocolumns + \recalculatebackgrounds} + +\def\calculatepseudocolumns + {\global\layoutcolumns\layoutparameter\c!columns + \global\layoutcolumndistance\layoutparameter\c!columndistance + \global\layoutcolumnwidth\dimexpr\makeupwidth-\layoutcolumns\layoutcolumndistance+\layoutcolumndistance\relax + \global\divide\layoutcolumnwidth\layoutcolumns + \dorecurse\layoutcolumns + {\setxvalue{\??ly:c:\recurselevel}% + {\the\numexpr\recurselevel-\plusone\relax\dimexpr\layoutcolumnwidth+\layoutcolumndistance\relax}}} + +%\dorecurse\layoutcolumns +% {\setxvalue{\??ly:c:\recurselevel}{\the\dimexpr +% (\numexpr(\recurselevel-1)\dimexpr(\layoutcolumnwidth+\layoutcolumndistance))}} + +\def\layoutcolumnoffset#1% + {\executeifdefined{\??ly:c:#1}\zeropoint} + +\def\checklayout + {\ifdim\makeupheight=\layoutlines\lineheight \else \recalculatelayout \fi} + +\appendtoks \checklayout \to \everystarttext + +% document: +% +% \setuplayout[odd][state=stop] \setuplayout[even][state=stop] \setuplayout[page] +% +% \startstandardmakeup[page=blank] ... \stopstandardmakeup + +\def\changetolayout#1% + {%\writestatus\m!layouts{changing to layout #1}% + \xdef\currentlayout{#1}\recalculatelayout} + +\def\checkcurrentoddlayout + {\ifcsname\??ly\v!odd\c!state\endcsname + \doifvalue{\??ly\v!odd\c!state}\v!start{\changetolayout\v!odd}% + \fi} + +\def\checkcurrentevenlayout + {\ifcsname\??ly\v!even\c!state\endcsname + \doifvalue{\??ly\v!even\c!state}\v!start{\changetolayout\v!even}% + \fi} + +\ifx\lastpage\undefined \def\lastpage{1} \fi + +\def\reverserealfolio + {\ifnum\lastpage>\plusone + \ifnum\lastpage=\realfolio + \v!last + \else\ifnum\plusone=\realfolio + \v!first + \else + \the\numexpr\realfolio-\lastpage\relax + \fi\fi + \else + \!!zerocount + \fi} + +\def\checkcurrentlayout % public and used in naw, so keep this name + {\ifcsname\??ly\realfolio\c!state\endcsname + \doifvalue{\??ly\realfolio\c!state}\v!start{\changetolayout\realfolio}% + \else\ifcsname\??ly\reverserealfolio\c!state\endcsname + \doifvalue{\??ly\reverserealfolio\c!state}\v!start{\changetolayout\reverserealfolio}% + \else\ifcsname\??ly\v!current\c!state\endcsname + \changetolayout\v!current % no start test ? + \else + \doifoddpageelse\checkcurrentoddlayout\checkcurrentevenlayout + \fi\fi\fi} + +% testcase +% +% \setuppagenumbering[alternative=doublesided] +% +% \setuplayout [width=11cm] +% \definelayout [odd] [backspace=1cm] +% \definelayout [even] [backspace=4cm] +% \definelayout [5] [backspace=5cm] +% \definelayout [6] [backspace=5cm] +% \definelayout [-2] [backspace=0cm,cutspace=0cm] +% \definelayout [last] [backspace=0cm,cutspace=0cm] +% +% \checkcurrentlayout \showframe +% +% \starttext +% \dorecurse{20} {\input knuth \endgraf \input tufte \endgraf} +% \stoptext + +%appendtoks \checkcurrentlayout \to \everyaftershipout % no +\appendtoks \checkcurrentlayout \to \everystarttext + +\appendtoks + \dochecknextlayout +\to \everyaftershipout + +% \def\dochecknextlayout +% {\ifx\currentlayout\v!current +% % prevent redundant calculations +% \else +% \globallet\currentlayout\empty +% \global\letbeundefined{\??ly\v!current\c!state}% +% \checkcurrentlayout +% \fi} +% +% this breaks after a standardmakeup + +\def\dochecknextlayout{\checkcurrentlayout} + +\newif\ifdoublesidedprint + +\def\presetcenterpagebox % in \setuplayout !!!!!!!!!!!!!!!! + {\doublesidedprintfalse + \normalexpanded{\noexpand\processallactionsinset[\@@lylocation]} + [ \v!middle=>{\setuppapersize[\c!left=\hss,\c!right=\hss,\c!top=\vss,\c!bottom=\vss]}, + \v!left=>{\setuppapersize[\c!left=,\c!right=\hss]}, + \v!right=>{\setuppapersize[\c!left=\hss,\c!right=]}, + \v!bottom=>{\setuppapersize[\c!top=\vss,\c!bottom=]}, + \v!top=>{\setuppapersize[\c!top=,\c!bottom=\vss]},% + \v!doublesided=>\doublesidedprinttrue, + \v!singlesided=>\doublesidedprintfalse]} + +\unexpanded\def\definelayout + {\dodoubleargument\dodefinelayout} + +\def\dodefinelayout[#1][#2]% + {\getparameters[\??ly#1][\c!state=\v!start,#2]} + +% \def\dodosetuplayout[#1][#2]% +% {\ConvertToConstant\doifnot{#2}\v!reset % #2 ? +% {\getparameters[\??ly#1][#2]% +% \checkforems[#2]}} + +\def\dodosetuplayout[#1][#2]% + {\doifnot{#2}\v!reset{\getparameters[\??ly#1][#2]}} + +% global needed for non-doublesided standardmakeup + +\def\dosetuplayout[#1][#2]% + {\globallet\currentlayout\empty % new, global + \ifsecondargument + \dodosetuplayout[#1][#2]% + \else\iffirstargument + \doifassignmentelse{#1} + {\dodosetuplayout[][#1]} + {\doifnot{#1}\v!reset{\xdef\currentlayout{#1}}}% new, global + \fi\fi + \recalculatelayout + \checkcurrentlayout % here ? + \presetcenterpagebox} + +\unexpanded\def\setuplayout + {\dodoubleempty\dosetuplayout} + +\let\@@zaheight\!!zeropoint + +\def\dopushpagedimensions + {\xdef\oldtextheight {\the\textheight }% + \xdef\oldfooterheight{\the\footerheight}% + \global\let\@@zaheight\@@zaheight} + +\def\dopoppagedimensions + {\global\textheight \oldtextheight + \global\footerheight\oldfooterheight + \recalculatelayout + \global\let\pushpagedimensions\dopushpagedimensions + \global\let\poppagedimensions\relax} + +\let\poppagedimensions \relax +\let\pushpagedimensions\dopushpagedimensions + +% Elke \csname ... \endcsname wordt ook aangemaakt, dus ook +% in een test met \doifdefined. Bij veel bladzijden kan dit +% te veel macro's kosten. Vandaar de set \adaptedpages. Het +% kost tijd, maar scheelt macro's. + +\let\adaptedpages\empty + +\def\adaptpagedimensions + {\ifx\adaptedpages\empty\else + \adaptpagedimensionsindeed + \fi} + +\def\adaptpagedimensionsindeed + {\rawdoifinset\realfolio\adaptedpages + {\removefromcommalist\realfolio\adaptedpages + \getvalue{\??za\realfolio}% + \letbeundefined{\??za\realfolio}}} + +\def\checkpagedimensions + {\poppagedimensions + \adaptpagedimensions} + +\def\reportpagedimensions + {\ifx\poppagedimensions\relax \else + \space\the\dimexpr\@@zaheight\relax\space-\space + \fi + \realfolio} + +\def\dodoadaptlayout[#1]% + {\getparameters[\??za][\c!height=,\c!lines=0,#1]% + \pushpagedimensions + \ifcase\@@zalines\relax + \showmessage\m!layouts1{\@@zaheight,\realfolio}% + \else + \showmessage\m!layouts1{\@@zalines\space\v!lines,\realfolio}% + \def\@@zaheight{\@@zalines\openlineheight}% + \fi + \doifelse\@@zaheight\v!max + {\balancedimensions\textheight\footerheight\footerheight} + {\balancedimensions\textheight\footerheight\@@zaheight}% + \ifdim\footerheight<\zeropoint + \global\advance\textheight \footerheight + \global\footerheight\zeropoint + \global\xdef\@@zaheight{\layoutparameter\c!footer\space(\v!max)}% + \fi + \setvsize + \global\pagegoal\vsize % nog corrigeren voor insertions ? + \recalculatebackgrounds + \global\let\pushpagedimensions\relax + \global\let\poppagedimensions\dopoppagedimensions} + +\def\doadaptlayout[#1][#2]% + {\doifelsenothing{#2} + {\dodoadaptlayout[#1]} + {\def\docommand##1% + {\addtocommalist{##1}\adaptedpages + \setgvalue{\??za##1}{\dodoadaptlayout[#2]}}% + \processcommalist[#1]\docommand + \adaptpagedimensions}} + +\def\adaptlayout + {\dodoubleempty\doadaptlayout} + +% describe interface + +%D Centering the paper area on the print area is determined +%D by the \type {top}, \type {bottom}, \type {left} and \type +%D {right} parameters. + +\def\centerpagebox#1% + {\printpaperwidth \paperscale\printpaperwidth + \printpaperheight\paperscale\printpaperheight + \setbox#1\vbox to \printpaperheight + {\@@pptop + \hbox to \printpaperwidth + {\ifdoublesidedprint + \doifbothsides + {\@@ppleft \box#1\@@ppright} + {\@@ppleft \box#1\@@ppright} + {\@@ppright\box#1\@@ppleft }% + \else + \@@ppleft \box#1\@@ppright + \fi}% + \par + \@@ppbottom}} + +\def\offsetprintbox#1% + {\ifdim\topoffset=\zeropoint % \relax + \ifdim\backoffset=\zeropoint + \donefalse + \else + \donetrue + \fi + \else + \donetrue + \fi + \ifdone + \edef\next{\wd#1\the\wd#1\ht#1\the\ht#1\dp#1\the\dp#1}% + \setbox#1\vbox + {\offinterlineskip + \vskip\topoffset + \hskip\doifbothsides\backoffset\backoffset{-\backoffset}% + \box#1}% + \next + \fi} + +\def\replicatepagebox#1% + {\ifnum\@@lynx>\plusone + \donetrue + \else\ifnum\@@lyny>\plusone + \donetrue + \else + \donefalse + \fi\fi + \ifdone + \setbox#1\vbox + {\offinterlineskip + \dorecurse\@@lyny + {\hbox{\dorecurse\@@lynx{\copy#1\hskip\@@lydx}\unskip}% + \vskip\@@lydy} + \unskip}% + \fi} + +\def\orientpagebodybox#1#2#3% + {\ifnum#2#3>\zerocount + \setbox#1\vbox + {\edef\somerotation{\ifdoublesided\ifodd\realpageno#2\else#3\fi\else#2\fi}% + \dorotatebox\somerotation\hbox{\box#1}}% + \fi} + +\def\orientpaperbox#1% + {\orientpagebodybox{#1}\paperorientation\paperreverse} + +\def\orientprintbox#1% + {\orientpagebodybox{#1}\printorientation\printreverse} + +\def\mirrorpagebodybox#1#2% + {\ifcase#2\or + \setbox#1\vbox{\domirrorbox\vbox{\box#1}}% + \fi} + +\def\mirrorpaperbox#1% + {\mirrorpagebodybox{#1}\papermirror} + +\def\mirrorprintbox#1% + {\mirrorpagebodybox{#1}\printmirror} + +\def\scalepagebox#1% + {\ifdim\@@lyscale\points=\onepoint \else + \setbox#1\vbox{\scale[\c!sx=\@@lyscale,\c!sy=\@@lyscale]{\box#1}}% + \paperwidth \@@lyscale\paperwidth + \paperheight\@@lyscale\paperheight + \fi} + +\def\negateprintbox#1% + {\ifnegateprintbox + \negatecolorbox{#1}% + \fi} + +\def\pagecutmarksymbol {\the\realpageno} +\def\pagecutmarklength {.5cm} +\let\pagecutmarktoptext \empty +\let\pagecutmarkbottomtext \empty + +\def\extrapagecutmarkbottomtext + {\rlap{\jobname}\hfill\currentdate\space-\space\currenttime\hfill\llap{\realfolio}} + +\def\makepagecutbox % #1 + {\let\cutmarksymbol \pagecutmarksymbol + \let\cutmarklength \pagecutmarklength + \let\cutmarktoptext \pagecutmarktoptext + \let\cutmarkbottomtext\pagecutmarkbottomtext + \makecutbox} + +\setvalue{\??ly:n:\c!marking:\v!on}% + {\makepagecutbox} + +\setvalue{\??ly:n:\c!marking:\v!page}% only at outer when nx/ny > 0 + {\makepagecutbox} + +\setvalue{\??ly:n:\c!marking:\v!empty}% + {\let\pagecutmarksymbol\empty + \let\pagecutmarktoptext\empty + \let\pagecutmarkbottomtext\empty + \makepagecutbox} + +\setvalue{\??ly:n:\c!marking:\v!text}% + {\let\pagecutmarksymbol\empty + \let\pagecutmarkbottomtext\extrapagecutmarkbottomtext + \makepagecutbox} + +\setvalue{\??ly:c:\c!marking:\v!color}% + {\doaddpagecolormarks\colormarkbox} + +\setvalue{\??ly:c:\c!marking:\v!screen}% + {\doaddpagecolormarks\rastermarkbox} + +\letvalue{\??ly:c:\c!marking:\v!unknown}\gobbleoneargument +\letvalue{\??ly:n:\c!marking:\v!unknown}\gobbleoneargument + +% \def\addpagecutmarks {\executeifdefined{\??ly:n:\c!marking:\@@lymarking}\gobbleoneargument} +% \def\addpagecolormarks{\executeifdefined{\??ly:c:\c!marking:\@@lymarking}\gobbleoneargument} + +\def\addpagecutmarks {\expandcheckedcsname{\??ly:n:\c!marking:}\@@lymarking\s!unknown} +\def\addpagecolormarks{\expandcheckedcsname{\??ly:c:\c!marking:}\@@lymarking\s!unknown} + +\def\doaddpagecolormarks#1#2% + {\makepagecutbox{#2}% + \ifnum\horizontalcutmarks>\plustwo \chardef\colormarkoffset\plusfour \fi + \ifnum\verticalcutmarks >\plustwo \chardef\colormarkoffset\plusfour \fi + #1{#2}} + +% NOG EENS NAGAAN WANNEER NU GLOBAL EN WANNEER NIET + +\ifx\doifelselayoutsomeline\undefined % defined in page-txt + \let\doifelselayoutsomeline\secondofthreearguments +\fi + +\def\compensatevsizeheader {\advance\textheight-\dimexpr\headerheight+\headerdistance\relax} +\def\compensatevsizefooter {\advance\textheight-\dimexpr\footerheight+\footerdistance\relax} +\def\globalcompensatevsizeheader{\global\advance\textheight-\dimexpr\headerheight+\headerdistance\relax} +\def\globalcompensatevsizefooter{\global\advance\textheight-\dimexpr\footerheight+\footerdistance\relax} + +\def\compensatevsizeheaderzero{\headerheight\zeropoint\setlayoutdistances} +\def\compensatevsizefooterzero{\footerheight\zeropoint\setlayoutdistances} + +\def\calculatevsizes + {\textheight\makeupheight + \doifelselayoutsomeline\v!header\compensatevsizeheader\donothing + \doifelselayoutsomeline\v!footer\compensatevsizefooter\donothing + \setvsizemodes + \resetglobal + \setvsize} + +\def\calculateglobalvsizes + {\global\textheight\makeupheight + \doifelselayoutsomeline\v!header\globalcompensatevsizeheader\donothing + \doifelselayoutsomeline\v!footer\globalcompensatevsizefooter\donothing + \setvsizemodes + \setvsize} + +\def\setvsizemodes + {\ifzeropt\headerheight + \resetsystemmode\v!header + \else + \setsystemmode\v!header + \fi + \ifzeropt\footerheight + \resetsystemmode\v!footer + \else + \setsystemmode\v!footer + \fi} + +\def\calculatereducedvsizes + {\textheight\makeupheight + \doifelselayoutsomeline\v!header\compensatevsizeheader\compensatevsizeheaderzero + \doifelselayoutsomeline\v!footer\compensatevsizefooter\compensatevsizefooterzero} + +\newdimen\innermakeupwidth % special purpose +\newdimen\innermakeupmargin % special purpose + +\chardef\innermakeupcompensation\plusone + +\def\compensatedinnermakeupmargin + {\dimexpr\ifnum\innermakeupcompensation=\plusone+\innermakeupmargin\else\zeropoint\fi\relax} + +\def\freezetextwidth % \makeupwidth may be set to \textwidth + {\textwidth\makeupwidth % which is a tricky but valid value + \doifsomething{\layoutparameter\c!textwidth} + {\textwidth\layoutparameter\c!textwidth}% % local + \global\innermakeupwidth\textwidth + \doifelsenothing{\layoutparameter\c!textmargin} + {\global\innermakeupmargin\zeropoint} + {\global\innermakeupmargin\layoutparameter\c!textmargin}% + \global\advance\innermakeupwidth-\dimexpr\innermakeupmargin+\innermakeupmargin\relax + \advance\textwidth-\dimexpr\innermakeupmargin+\innermakeupmargin\relax} % local + +\def\calculatehsizes + {\freezetextwidth + \sethsize} + +% De onderstaande macro voert commando's uit, afhankelijk van +% het karakter van het paginanummer. +% +% \doifoddpageelse{then-commando}{else-commando} + +%D When we start at an even page, we need to swap the layout +%D differently. We cannot adapt the real page number, since +%D it is used in cross referencing. The next switch is set +%D when we start at an even page. + +% We could use nested if here plus some \@EAEAEA's but but the +% next variant has less expansion which is nicer in tracing. + +\def\doifoddpageelse {\ifodd\pagenoshift\expandafter\doifoddpageelseyes \else\expandafter\doifoddpageelsenop \fi} +\def\doifoddpageelseyes{\ifodd\realpageno \expandafter\secondoftwoarguments\else\expandafter\firstoftwoarguments \fi} +\def\doifoddpageelsenop{\ifodd\realpageno \expandafter\firstoftwoarguments \else\expandafter\secondoftwoarguments\fi} + +\let\doifonevenpaginaelse\doifoddpageelse + +\def\redoifoddpageelse#1{\doifoddpageelse} + +\def\doifbothsidesoverruled + {\ifdoublesided + \expandafter\redoifoddpageelse + \else + \expandafter\firstofthreearguments + \fi} + +\def\doifbothsides% #1 #2 #3 + {\ifdoublesided + \expandafter\doifbothsidesindeed + \else + \expandafter\firstofthreearguments + \fi} + +\def\doifbothsidesindeed + {\ifsinglesided + \expandafter\firstofthreearguments + \else + \expandafter\redoifoddpageelse + \fi} + +\newdimen\texthoffset + +\def\settexthoffset + {\texthoffset\doifbothsides\backspace\backspace{\dimexpr\paperwidth-\backspace-\makeupwidth\relax}} + +% The next hack is too tricky as we may shipout more pages: +% +% \def\freezepagestatechecks +% {\the\everyfreezepagestatechecks} +% +% \newtoks \everyfreezepagestatechecks +% +% \appendtoks +% \doifbothsides +% {\let\doifbothsides\firstofthreearguments}% +% {\let\doifbothsides\secondofthreearguments}% +% {\let\doifbothsides\thirdofthreearguments}% +% \rightorleftpageaction +% {\let\rightorleftpageaction\firstoftwoarguments}% +% {\let\rightorleftpageaction\secondoftwoarguments}% +% \doifmarginswapelse +% {\let\doifmarginswapelse\firstoftwoarguments}% +% {\let\doifmarginswapelse\secondoftwoarguments}% +% \to \everyfreezepagestatechecks +% +% \prependtoks +% \freezepagestatechecks +% \to \everybeforeshipout + +\def\goleftonpage + {\hskip-\dimexpr\leftmargindistance+\leftmarginwidth+\leftedgedistance+\leftedgewidth\relax} + +\def\doifmarginswapelse#1#2% + {\doifbothsides{#1}{#1}{#2}} + +\def\swapmargins + {\doifmarginswapelse\relax\doswapmargins} + +\def\doswapmargins + {\let\swapmargins \relax % to prevent local swapping + \let\doswapmargins\relax % to prevent local swapping + \the\everyswapmargins} + +\def\rightorleftpageaction + {\ifdoublesided + \expandafter\rightorleftpageactionindeed + \else + \expandafter\firstoftwoarguments + \fi} + +\def\rightorleftpageactionindeed + {\ifsinglesided + \expandafter\firstoftwoarguments + \else + \expandafter\doifoddpageelse + \fi} + +\def\outermarginwidth {\rightorleftpageaction\rightmarginwidth \leftmarginwidth } +\def\innermarginwidth {\rightorleftpageaction\leftmarginwidth \rightmarginwidth} +\def\outermargindistance{\rightorleftpageaction\rightmargindistance\leftmargindistance } +\def\innermargindistance{\rightorleftpageaction\leftmargindistance \rightmargindistance} + +\def\outeredgewidth {\rightorleftpageaction\rightedgewidth \leftedgewidth } +\def\inneredgewidth {\rightorleftpageaction\leftedgewidth \rightedgewidth} +\def\outeredgedistance {\rightorleftpageaction\rightedgedistance\leftedgedistance } +\def\inneredgedistance {\rightorleftpageaction\leftedgedistance \rightedgedistance} + +\def\outerspacewidth {\rightorleftpageaction\cutspace \backspace} +\def\innerspacewidth {\rightorleftpageaction\backspace\cutspace } + +\def\leftmargintotal {\dimexpr\leftmarginwidth +\leftmargindistance \relax} +\def\rightmargintotal {\dimexpr\rightmarginwidth+\rightmargindistance\relax} +\def\leftedgetotal {\dimexpr\leftedgewidth +\leftedgedistance \relax} +\def\rightedgetotal {\dimexpr\rightedgewidth +\rightedgedistance \relax} + +\def\leftsidetotal {\dimexpr\leftmarginwidth +\leftedgetotal \relax} +\def\rightsidetotal {\dimexpr\rightmarginwidth+\rightedgetotal\relax} +\def\leftcombitotal {\dimexpr\leftmargintotal +\leftedgetotal \relax} +\def\rightcombitotal {\dimexpr\rightmargintotal+\rightedgetotal\relax} + +\def\innermargintotal {\dimexpr\innermarginwidth+\innermargindistance\relax} +\def\outermargintotal {\dimexpr\outermarginwidth+\outermargindistance\relax} +\def\inneredgetotal {\dimexpr\inneredgewidth +\inneredgedistance \relax} +\def\outeredgetotal {\dimexpr\outeredgewidth +\outeredgedistance \relax} + +\def\innercombitotal {\dimexpr\innermargintotal+\inneredgetotal\relax} +\def\outercombitotal {\dimexpr\outermargintotal+\outeredgetotal\relax} +\def\innersidetotal {\dimexpr\innermarginwidth+\inneredgetotal\relax} +\def\outersidetotal {\dimexpr\outermarginwidth+\outeredgetotal\relax} + +%D \macros +%D {startlocallayout} +%D +%D These macros should be used with care. They permit local +%D layouts (as used in fitting pages, see \type {page-app.tex}). + +%D This is kind of obsolete now that we have \type +%D {\definelayout}, so this hack will disappear in future +%D versions. + +\unexpanded\def\startlocallayout + {\globalpushmacro\restorepapersize + \globalpushmacro\currentlayout} + +\unexpanded\def\stoplocallayout + {\globalpopmacro\currentlayout + \globalpopmacro\restorepapersize + \restorepapersize + \setuplayout} + +%D \macros +%D {showprint, showframe, showlayout, showsetups} +%D +%D We predefine a couple of tracing macros. +%D +%D \showsetup{showprint} +%D \showsetup{showframe} +%D \showsetup{showlayout} +%D \showsetup{showsetups} +%D %showsetup{showmargins} + +\fetchruntimecommand \showprint {page-run.mkii} +\fetchruntimecommand \showframe {page-run.mkii} +\fetchruntimecommand \showlayout {page-run.mkii} +\fetchruntimecommand \showsetups {page-run.mkii} +\fetchruntimecommand \showmargins {page-run.mkii} + +%D The default dimensions are quite old and will not change. +%D The funny fractions were introduced when we went from fixed +%D dimensions to relative ones. Since \CONTEXT\ is a dutch +%D package, the dimensions are based on the metric system. The +%D asymmetrical layout is kind of handy for short +%D quick||and||dirty stapled documents. +%D +%D Although valid, it is not a real good idea to use +%D dimensions based on the \type {em} unit. First of all, +%D since there are no fonts loaded yet, this dimension makes +%D no sense, and second, you would loose track of values, +%D since they could change while going to a new page, +%D depending on the current font setting. + +\setuplayout + [ \c!topspace=.08417508418\paperheight, % 2.5cm + \c!top=\zeropoint, + \c!topdistance=\zeropoint, + \c!header=.06734006734\paperheight, % 2.0cm + \c!headerdistance=\zeropoint, + \c!height=.84175084175\paperheight, % 25.0cm + \c!footerdistance=\layoutparameter\c!headerdistance, + \c!footer=.06734006734\paperheight, % 2.0cm + \c!bottomdistance=\layoutparameter\c!topdistance, + \c!bottom=\zeropoint, + \c!backspace=.11904761905\paperwidth, % 2.5cm + \c!edge=\zeropoint, + \c!edgedistance=\layoutparameter\c!margindistance, + \c!margin=.12649983170\paperwidth, % snijwit-2*afstand + \c!margindistance=.02008341748\paperwidth, % 12.0pt + \c!leftedge=\layoutparameter\c!edge, + \c!leftedgedistance=\layoutparameter\c!edgedistance, + \c!leftmargin=\layoutparameter\c!margin, + \c!leftmargindistance=\layoutparameter\c!margindistance, + \c!width=.71428571429\paperwidth, % 15.0cm \dimexpr\ + \c!rightmargindistance=\layoutparameter\c!margindistance, + \c!rightmargin=\layoutparameter\c!margin, + \c!rightedgedistance=\layoutparameter\c!edgedistance, + \c!rightedge=\layoutparameter\c!edge, + \c!veroffset=\zeropoint, + \c!bottomspace=\zeropoint, + \c!horoffset=\zeropoint, + \c!cutspace=\zeropoint, + \c!textwidth=, % dangerous option -> centered / local + \c!textmargin=, % dangerous option -> both sides + \c!textdistance=\zeropoint, % shift down on grid + \c!style=, + \c!color=, + \c!marking=\v!off, + \c!location=, % \v!singlesided, but empty is signal + \c!scale=1, + \c!nx=1, + \c!ny=1, + \c!dx=\zeropoint, + \c!dy=\zeropoint, + \c!grid=\v!no, + \c!preset=, + \c!setups=\systemsetupsprefix\s!default, + \c!clipoffset=\zeropoint, + \c!lines=0, + \c!paper=, % for foxet + \c!page=, % for foxet + \c!columns=1, + \c!columndistance=\zeropoint] + +%D First we define a whole range of (DIN) papersizes, +%D of which the A-series makes most sense. We enable checking. + +%D We also set some of the parameters that will be used when +%D positioning the typeset paper onto the print paper. + +\setuppaper % (size) % only used in XY imposition + [\c!width=\zeropoint, + \c!height=\zeropoint, + \c!topspace=\zeropoint, + \c!backspace=\zeropoint, + \c!dx=\zeropoint, + \c!dy=\zeropoint, + \c!nx=1, + \c!ny=1, + \c!method=\v!normal] + +\setuppapersize + [\c!option=\v!max, + \c!top=, + \c!bottom=\vss, + \c!left=, + \c!right=\hss] + +\definepapersize [A0] [\c!width=841mm,\c!height=1189mm] +\definepapersize [A1] [\c!width=594mm,\c!height=841mm] +\definepapersize [A2] [\c!width=420mm,\c!height=594mm] +\definepapersize [A3] [\c!width=297mm,\c!height=420mm] +\definepapersize [A4] [\c!width=210mm,\c!height=297mm] +\definepapersize [A5] [\c!width=148mm,\c!height=210mm] +\definepapersize [A6] [\c!width=105mm,\c!height=148mm] +\definepapersize [A7] [\c!width=74mm,\c!height=105mm] +\definepapersize [A8] [\c!width=52mm,\c!height=74mm] +\definepapersize [A9] [\c!width=37mm,\c!height=52mm] +\definepapersize [A10] [\c!width=26mm,\c!height=37mm] + +\definepapersize [B0] [\c!width=1000mm,\c!height=1414mm] +\definepapersize [B1] [\c!width=707mm,\c!height=1000mm] +\definepapersize [B2] [\c!width=500mm,\c!height=707mm] +\definepapersize [B3] [\c!width=353mm,\c!height=500mm] % [\c!width=354mm,\c!height=500mm] +\definepapersize [B4] [\c!width=250mm,\c!height=353mm] % [\c!width=250mm,\c!height=354mm] +\definepapersize [B5] [\c!width=176mm,\c!height=250mm] % [\c!width=177mm,\c!height=250mm] +\definepapersize [B6] [\c!width=125mm,\c!height=176mm] % [\c!width=125mm,\c!height=177mm] +\definepapersize [B7] [\c!width=88mm,\c!height=125mm] +\definepapersize [B8] [\c!width=62mm,\c!height=88mm] % [\c!width=63mm,\c!height=88mm] +\definepapersize [B9] [\c!width=44mm,\c!height=62mm] % [\c!width=44mm,\c!height=63mm] +\definepapersize [B10] [\c!width=31mm,\c!height=44mm] + +\definepapersize [C0] [\c!width=917mm,\c!height=1297mm] +\definepapersize [C1] [\c!width=648mm,\c!height=917mm] % [\c!width=649mm,\c!height=917mm] +\definepapersize [C2] [\c!width=458mm,\c!height=648mm] % [\c!width=459mm,\c!height=649mm] +\definepapersize [C3] [\c!width=324mm,\c!height=458mm] % [\c!width=324mm,\c!height=459mm] +\definepapersize [C4] [\c!width=229mm,\c!height=324mm] +\definepapersize [C5] [\c!width=162mm,\c!height=229mm] +\definepapersize [C6] [\c!width=114mm,\c!height=162mm] % [\c!width=115mm,\c!height=162mm] +\definepapersize [C7] [\c!width=81mm,\c!height=114mm] % [\c!width=81mm,\c!height=115mm] +\definepapersize [C8] [\c!width=57mm,\c!height=81mm] +\definepapersize [C9] [\c!width=40mm,\c!height=57mm] +\definepapersize [C10] [\c!width=28mm,\c!height=40mm] + +%D Per August 2004 the rounding of some (seldom used) sizes +%D were corrected top the latest DIN specifications. Peter +%D Rolf came up with these and a few more missing sizes. +%D Watch out: spaces and slashes! + +\definepapersize [4 A0] [\c!width=1682mm,\c!height=2378mm] +\definepapersize [2 A0] [\c!width=1189mm,\c!height=1682mm] +\definepapersize [C6/C5] [\c!width=114mm,\c!height=229mm] + +%D Because there are no standardized screen sizes, we define +%D a bunch of sizes with $4:3$ ratios. The \type {S6} size is +%D nearly as wide as a sheet of \type {A4} paper. + +\definepapersize [S3] [\c!width=300pt,\c!height=225pt] +\definepapersize [S4] [\c!width=400pt,\c!height=300pt] +\definepapersize [S5] [\c!width=500pt,\c!height=375pt] +\definepapersize [S6] [\c!width=600pt,\c!height=450pt] +\definepapersize [S8] [\c!width=800pt,\c!height=600pt] +\definepapersize [SW] [\c!width=800pt,\c!height=450pt] +\definepapersize [SM] [\c!width=720pt,\c!height=450pt] + +%D These are handy too: + +\definepapersize [S33] [\c!width=300pt,\c!height=300pt] +\definepapersize [S44] [\c!width=400pt,\c!height=400pt] +\definepapersize [S55] [\c!width=500pt,\c!height=500pt] +\definepapersize [S66] [\c!width=600pt,\c!height=600pt] + +%D One may wonder if \TEX\ should be used for typesetting +%D \CDROM\ covers, but it does not hurt to have the paper size +%D ready. + +\definepapersize [CD] [\c!width=120mm,\c!height=120mm] + +%D The next series is for our English speaking friends who +%D decided to stick to non metric values. Thanks to Nelson +%D Beebe for completing the inch based list. + +\definepapersize [letter] [\c!width=8.5in,\c!height=11in] +\definepapersize [ledger] [\c!width=11in,\c!height=17in] +\definepapersize [tabloid] [\c!width=17in,\c!height=11in] + +\definepapersize [legal] [\c!width=8.5in,\c!height=14in] +\definepapersize [folio] [\c!width=8.5in,\c!height=13in] +\definepapersize [executive] [\c!width=7.25in,\c!height=10.5in] + +\definepapersize [A] [\c!width=8.5in,\c!height=11in] % 1 sheet +\definepapersize [B] [\c!width=11in,\c!height=17in] % 2 sheets +\definepapersize [C] [\c!width=17in,\c!height=22in] % 4 sheets + +%D The next set is for Tobias Burnus, who gave me the sizes. + +\definepapersize [envelope 9] [\c!width=8.88in,\c!height=3.88in] +\definepapersize [envelope 10] [\c!width=9.5in,\c!height=4.13in] +\definepapersize [envelope 11] [\c!width=10.38in,\c!height=4.5in] +\definepapersize [envelope 12] [\c!width=11.0in,\c!height=4.75in] +\definepapersize [envelope 14] [\c!width=11.5in,\c!height=5.0in] +\definepapersize [monarch] [\c!width=7.5in,\c!height=3.88in] +\definepapersize [check] [\c!width=8.58in,\c!height=3.88in] +\definepapersize [DL] [\c!width=110mm,\c!height=220mm] % [\c!width=220mm,\c!height=110mm] +\definepapersize [E4] [\c!width=280mm,\c!height=400mm] + +%D The next three sets are supplied by Taco: + +\definepapersize [RA0] [\c!width=860mm,\c!height=1220mm] +\definepapersize [RA1] [\c!width=610mm,\c!height=860mm] +\definepapersize [RA2] [\c!width=430mm,\c!height=610mm] +\definepapersize [RA3] [\c!width=305mm,\c!height=430mm] +\definepapersize [RA4] [\c!width=215mm,\c!height=305mm] + +%D ISO SRA (supplementary raw A) sizes: + +\definepapersize [SRA0] [\c!width=900mm,\c!height=1280mm] +\definepapersize [SRA1] [\c!width=640mm,\c!height=900mm] +\definepapersize [SRA2] [\c!width=450mm,\c!height=640mm] +\definepapersize [SRA3] [\c!width=320mm,\c!height=450mm] +\definepapersize [SRA4] [\c!width=225mm,\c!height=320mm] + +%D Swedish thesis formats: + +\definepapersize [G5] [\c!width=169mm,\c!height=239mm] +\definepapersize [E5] [\c!width=155mm,\c!height=220mm] + +%D Industry invention: + +\definepapersize [A3plus] [\c!width=329mm,\c!height=483mm] + +%D We can now default to a reasonable size. We match the print +%D paper size with the typeset paper size. This setting should +%D come after the first layout specification (already done). + +\setuppapersize + [A4][A4] + +%D A few goodies: + +\definepapersize + [oversized] + [ \c!width=\dimexpr\paperwidth +1.5cm\relax, + \c!height=\dimexpr\paperheight+1.5cm\relax] + +\definepapersize + [doublesized] + [ \c!width=\dimexpr \paperwidth \relax, + \c!height=\dimexpr2\paperheight\relax] + +\definepapersize + [doubleoversized] + [ \c!width=\dimexpr \paperheight+1.5cm\relax, + \c!height=\dimexpr2\paperwidth +1.5cm\relax] + +%D For orthogonality: + +\definepapersize + [undersized] + [ \c!width=\dimexpr\paperwidth -1.5cm\relax, + \c!height=\dimexpr\paperheight-1.5cm\relax] + +\definelayout + [\v!page] + [\c!backspace=\zeropoint, + \c!cutspace=\zeropoint, + \c!topspace=\zeropoint, + \c!bottomspace=\zeropoint, + \c!margin=\zeropoint, + \c!edge=\zeropoint, + \c!header=\zeropoint, + \c!footer=\zeropoint, + \c!top=\zeropoint, + \c!bottom=\zeropoint, + \c!leftmargin=\zeropoint, + \c!rightmargin=\zeropoint, + \c!leftedge=\zeropoint, + \c!rightedge=\zeropoint, + \c!textdistance=\zeropoint, + \c!width=\v!middle, + \c!height=\v!middle, + \c!lines=0, + \c!grid=\v!no] + +\definelayout + [\v!middle] + [\c!width=\v!middle, + \c!height=\v!middle] + +\protect \endinput diff --git a/tex/context/base/page-lin.lua b/tex/context/base/page-lin.lua new file mode 100644 index 000000000..1f2c96251 --- /dev/null +++ b/tex/context/base/page-lin.lua @@ -0,0 +1,215 @@ +if not modules then modules = { } end modules ['page-lin'] = { + version = 1.001, + comment = "companion to page-lin.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- experimental + +local trace_numbers = false trackers.register("lines.numbers", function(v) trace_numbers = v end) + +local format = string.format +local texsprint, texwrite, texbox = tex.sprint, tex.write, tex.box + +local ctxcatcodes = tex.ctxcatcodes +local variables = interfaces.variables + +nodes = nodes or { } +nodes.lines = nodes.lines or { } +nodes.lines.data = nodes.lines.data or { } -- start step tag + +storage.register("lines/data", nodes.lines.data, "nodes.lines.data") + +-- 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 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 has_attribute = node.has_attribute +local traverse_id = node.traverse_id +local traverse = node.traverse +local copy_node = node.copy +local hpack_node = node.hpack +local insert_node_after = node.insert_after +local insert_node_before = node.insert_before + +local whatsit = node.id("whatsit") + +local data = nodes.lines.data +local last = #data + +nodes.lines.scratchbox = nodes.lines.scratchbox or 0 + +-- cross referencing + +function nodes.lines.number(n) + n = tonumber(n) + local cr = cross_references[n] or 0 + cross_references[n] = nil + return cr +end + +local function resolve(n,m) -- we can now check the 'line' flag (todo) + while n do + local id = n.id + if id == whatsit then -- why whatsit + 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) + end + n = n.next + end +end + +function nodes.lines.finalize(t) + local getnumber = nodes.lines.number + for _,p in next, t do + for _,r in next, p do + if r.metadata.kind == "line" then + local e = r.entries + local u = r.userdata + e.linenumber = getnumber(e.text or 0) -- we can nil e.text + e.conversion = u and u.conversion + r.userdata = nil -- hack + end + end + end +end + +local filters = jobreferences.filters +local helpers = structure.helpers + +jobreferences.registerfinalizer(nodes.lines.finalize) + +filters.line = filters.line or { } + +function filters.line.default(data) +-- helpers.title(data.entries.linenumber or "?",data.metadata) + texsprint(ctxcatcodes,format("\\convertnumber{%s}{%s}",data.entries.conversion or "numbers",data.entries.linenumber or "0")) +end + +function filters.line.page(data,prefixspec,pagespec) -- redundant + helpers.prefixpage(data,prefixspec,pagespec) +end + +function filters.line.linenumber(data) -- raw + texwrite(data.entries.linenumber or "0") +end + +-- boxed variant, todo: use number mechanism + +nodes.lines.boxed = { } + +-- todo: cache setups, and free id no longer used +-- use interfaces.cachesetup(t) + +function nodes.lines.boxed.register(configuration) + last = last + 1 + data[last] = configuration + if trace_numbers then + logs.report("lines","registering setup %s",last) + end + return last +end + +function nodes.lines.boxed.setup(n,configuration) + local d = data[n] + if d then + if trace_numbers then + logs.report("lines","updating setup %s",n) + end + for k,v in next, configuration do + d[k] = v + end + else + if trace_numbers then + logs.report("lines","registering setup %s (br)",n) + end + data[n] = configuration + end + return n +end + +local the_left_margin = nodes.the_left_margin + +local function check_number(n,a,skip) -- move inline + local d = data[a] + if d then + local s = d.start or 1 + current_list[#current_list+1] = { n, s } + if not skip and s % d.step == 0 then + local tag = d.tag or "" + texsprint(ctxcatcodes, format("\\makenumber{%s}{%s}{%s}{%s}{%s}{%s}\\endgraf",tag,s,n.shift,n.width,the_left_margin(n.list),n.dir)) + if trace_numbers then + logs.report("numbers","making number %s for setup %s: %s (%s)",#current_list,a,s,d.continue or "no") + end + else + texsprint(ctxcatcodes, "\\skipnumber\\endgraf") + end + d.start = s + 1 -- (d.step or 1) + end +end + +function nodes.lines.boxed.stage_one(n) + current_list = { } + local head = texbox[n] + if head then + local list = head.list + local last_a, skip = nil, false + 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 + local a = has_attribute(n.list,line_number) + if a and a > 0 then + if last_a ~= a then + if data[a].method == variables.next then + skip = true + end + last_a = a + end + if has_attribute(n,display_math) then + if nodes.is_display_math(n) then + check_number(n,a,skip) + end + else + -- the following test fails somehow (change in luatex?) + -- if node.first_character(n.list) then + check_number(n,a,skip) + -- end + end + skip = false + end + end + end + end +end + +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,texbox[m].list) do + t[#t+1] = copy_node(l) + end + for i=1,#current_list do + local li = current_list[i] + local n, m, ti = li[1], li[2], t[i] + ti.next, n.list = n.list, ti + resolve(n,m) + end + end +end diff --git a/tex/context/base/page-lin.mkii b/tex/context/base/page-lin.mkii new file mode 100644 index 000000000..a04804ce6 --- /dev/null +++ b/tex/context/base/page-lin.mkii @@ -0,0 +1,312 @@ +%D \module +%D [ file=page-lin, % copied from main-001 +%D version=1997.03.31, +%D title=\CONTEXT\ Core Macros, +%D subtitle=Line Numbering, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Line Numbering} + +\unprotect + +\newif\ifnumberinglines +\newif\iftypesettinglines + +\newcount\linenumber +\newcount\linestepper + +\chardef\linenumberlocation=0 + +\newtoks\beforeeverylinenumbering +\newtoks\aftereverylinenumbering + +% het gebruik van \setlocalreference scheelt een hash entry + +\def\dodoshowlinenumber % for use elsewhere, to be extended + {\doplacelinenumber + \global\advance\linenumber \plusone} + +\def\completelinenumber + {\@@rnleft\convertnumber\@@rnconversion\linenumber\@@rnright} + +\def\dosetuplinenumbering[#1]% + {\getparameters[\??rn][\c!start=1,\c!step=1,#1]% + \global\linenumber\plusone} + +\def\setuplinenumbering + {\dosingleargument\dosetuplinenumbering} + +\def\dostartnummerenLINE + {\EveryPar{\placelinenumber}} % why not append to everypar ? better + +\def\dostopnummerenLINE + {\the\aftereverylinenumbering + \egroup} + +\def\dostartnummerenVERB + {\EveryLine{\placelinenumber}} + +\def\dostopnummerenVERB + {\the\aftereverylinenumbering + \egroup} + +\newevery \everylinenumber \relax + +\def\dodoplacelinenumber + {% beware of em's, the font is already switched ! + \setbox\scratchbox\hbox + {\setbox0\hbox{\@@rncommand{\completelinenumber}}\vsmashbox0% + \ifcase\linenumberlocation + \iftypesettinglines % hack + \expandafter\llap + \else + \expandafter\rlap + \fi{\hbox to \@@rnwidth{\box0\hss}}% was \llap, nog testen !! + \or + \inleftmargin + {\forgetall + \doifelse\@@rnwidth\v!margin + {\hsize\leftmarginwidth}{\hsize\@@rnwidth}% + \alignedline\@@rnalign\v!right{\box0\hskip\@@rndistance}}% + \else + \inrightmargin + {\forgetall + \doifelse\@@rnwidth\v!margin + {\hsize\rightmarginwidth}{\hsize\@@rnwidth}% + \alignedline\@@rnalign\v!left{\hskip\@@rndistance\box0}}% + \fi}% + \vsmashbox\scratchbox + \box\scratchbox + \the\everylinenumber} + +\def\complexstartlinenumbering[#1]% + {\doifnot{#1}\v!continue + {\doifnumberelse{#1} + {\global\linenumber#1\relax} + {\doifelsenothing\@@rnstart + {\global\linenumber\plusone} + {\global\linenumber\@@rnstart}}}% + \chardef\linenumberlocation\zerocount + \processaction + [\@@rnlocation] + [ \v!inmargin=>\chardef\linenumberlocation\plusone, + \v!inleft=>\chardef\linenumberlocation\plusone, + \v!inright=>\chardef\linenumberlocation\plustwo, + \v!margin=>\chardef\linenumberlocation\plusone]% + % \v!text=>\chardef\linenumberlocation\zerocount, + %\s!unknown=>\chardef\linenumberlocation\zerocount, + %\s!default=>\chardef\linenumberlocation\zerocount]% + \doifnot\@@rnwidth\v!margin + {\freezedimenmacro\@@rnwidth + \ifcase\linenumberlocation % text + \advance\leftskip\@@rnwidth\relax + \fi}% + \freezedimenmacro\@@rndistance + \chardef\@@rn@@rnmethod + \ifprocessingverbatim\zerocount\else\iftypesettinglines\plusone\else\plustwo\fi\fi + \processaction + [\@@rnmethod] + [ \v!type=>\chardef\@@rn@@rnmethod\zerocount, + \v!line=>\chardef\@@rn@@rnmethod\plusone, + \v!text=>\chardef\@@rn@@rnmethod\plustwo, + \v!file=>\chardef\@@rn@@rnmethod\plusthree]% + \ifcase\@@rn@@rnmethod % verbatim, line by line + \typesettinglinestrue + \let\dostartnummeren\dostartnummerenVERB + \let\stoplinenumbering\dostopnummerenVERB + \def\placelinenumber + {\doplacelinenumber + \global\advance\linenumber \plusone}% + \or % text, line by line + \let\dostartnummeren\dostartnummerenLINE + \let\stoplinenumbering\dostopnummerenLINE + \def\placelinenumber + {\doplacelinenumber + \global\advance\linenumber \plusone}% + \or % text, whole lot + \let\dostartnummeren\dostartnummerenPAR + \let\stoplinenumbering\dostopnummerenPAR + \def\placelinenumber + {\global\advance\linenumber \minusone + \doplacelinenumber}% + \or % verbatim, selective line by line + \typesettinglinestrue + \let\dostartnummeren\dostartnummerenVERB + \let\stoplinenumbering\dostopnummerenVERB + \def\placelinenumber + {\global\linenumber\verbatimlinenumber + \global\advance\linenumber \minusone + \doplacelinenumber}% + \fi + \dostartnummeren} + +\def\startlinenumbering + {\bgroup + \the\beforeeverylinenumbering + \numberinglinestrue + \complexorsimpleempty\startlinenumbering} + +\def\donoplacelinenumber + {\the\everylinenumber} + +\def\doplacelinenumber + {\ifnum\linenumber<\@@rnstart\relax + \donoplacelinenumber + \else + \ifnum\numexpr(\linenumber/\@@rnstep)*\@@rnstep\relax=\linenumber + \doattributes\??rn\c!style\c!color\dodoplacelinenumber + \else + \donoplacelinenumber + \fi + \fi} + +\def\someline[#1]% + {\dolinereference0[#1]\ignorespaces} + +\def\startline[#1]% + {\dolinereference1[#1]\ignorespaces} + +\def\stopline[#1]% + {\removelastspace\dolinereference2[#1]} + +\def\inline#1[#2]% + {\doifelsenothing{#1} + {\doifinstringelse{--}\currenttextreference + {\in{\leftlabeltext\v!lines}{\rightlabeltext\v!lines}[\@@rnprefix#2]} + {\in{\leftlabeltext\v!line }{\rightlabeltext\v!line }[\@@rnprefix#2]}} + {\in{#1}[\@@rnprefix#2]}} + +\def\dostartnummerenPAR + {\beginofshapebox + \doglobal\newcounter\linereference} + +% localcrossref heroverwegen + +\def\setlinereference#1#2#3#4% + {\setxvalue{lrf:#1}{\noexpand\dogetlinereference{#2}{#3}{#4}}} + +\def\getlinereference#1% + {\getvalue{lrf:#1}} + +\def\dogetlinereference#1#2#3% + {\edef\linereferencename{#1}% + \edef\linereferenceline{#2}% + \edef\linereferenceplus{#3}} + +% 1 xxx xxx xxx xxx xxx xxx xxx +% 2 xxx yyy yyy yyy yyy yyy yyy <= start y +% 3 yyy yyy yyy yyy yyy yyy yyy +% 4 yyy yyy yyy yyy yyy xxx xxx <= stop y +% 5 xxx xxx xxx xxx xxx xxx xxx + +\def\dolinereference#1[#2]% + {\bgroup + \dimen0=\strutdp + \doif\@@rnreferencing\v!on + {\doglobal\increment\linereference + % start 1=>(n=y,l=0,p=1) + % stop 2=>(n=y,l=0,p=2) + \setlinereference{\linereference}{\@@rnprefix#2}{0}{#1}% + \advance\dimen0 \linereference sp}% + \prewordbreak + \vrule \!!width \zeropoint \!!depth \dimen0 \!!height \zeropoint + \prewordbreak + \egroup} + +\def\dostopnummerenPAR % dp's -> openstrutdepth + {\endofshapebox + \checkreferences + \linestepper\zerocount + \reshapebox{\global\advance\linestepper \plusone}% + \global\advance\linenumber \linestepper + \doifelse\@@rnreferencing\v!on + {\reshapebox % We are going back! + {\global\advance\linenumber \minusone + \dimen0=\dp\shapebox + \advance\dimen0 -\strutdp\relax + \ifdim\dimen0>\zeropoint + % 1=>4 | 2=>4 1=>2 + % start 1=>(n=y,l=2,p=1) + % stop 2=>(n=y,l=4,p=2) + \dostepwiserecurse\plusone{\number\dimen0}\plusone + {\getlinereference\recurselevel + \setlinereference\recurselevel + {\linereferencename}{\the\linenumber}{\linereferenceplus}}% + \fi}% + \global\advance\linenumber \linestepper + \ifnum\linereference>\zerocount % anders vreemde loop in paragraphs+recurse + \dorecurse\linereference + {\getlinereference\recurselevel + \ifnum\linereferenceplus=2 % stop + % ref y: text = 4 / Kan dit buiten referentie mechanisme om? + \expanded{\setlocalcrossreference + {\referenceprefix\linereferencename}{}{}{\linereferenceline}}% + \fi}% + \dorecurse\linereference + {\getlinereference\recurselevel + \ifnum\linereferenceplus<2 % start / lone + \ifnum\linereferenceplus=1 % start + \getreferenceelements\linereferencename % text = 4 + \ifnum\linereferenceline<0\currenttextreference\relax % 0 prevents error + \edef\linereferenceline{\linereferenceline--\currenttextreference}% + \fi + \fi + \expanded{\setlocalcrossreference + {\referenceprefix\linereferencename}{}{}{\linereferenceline}}% + \fi}% + \global\let\scratchline\linenumber % We are going back! + \reshapebox + {\doglobal\decrement\scratchline + \hbox + {\dorecurse\linereference + {\getlinereference\recurselevel + \getreferenceelements\linereferencename + \beforesplitstring\currenttextreference--\at--\to\firstline + \ifnum\firstline=\scratchline\relax + % beter een rawtextreference, i.e. expanded + % \textreference[\linereferencename]{\currenttextreference}% + \rawtextreference\s!lin\linereferencename\currenttextreference + \expanded{\setlocalcrossreference + {\referenceprefix\linereferencename}{}{}{0}}% ==done + \fi}% + \dimen0\dp\shapebox + \advance\dimen0 -\strutdp\relax + \ifdim\dimen0>\zeropoint + \dp\shapebox\strutdp + \fi + \placelinenumber\box\shapebox}}% no \strut ! + \else + \reshapebox{\hbox{\placelinenumber\box\shapebox}}% no \strut ! + \fi} + {\reshapebox{\global\advance\linenumber \minusone}% + \global\advance\linenumber \linestepper + \reshapebox{\hbox{\placelinenumber\box\shapebox}}}% no \strut ! + \global\advance\linenumber \linestepper + \flushshapebox + \the\aftereverylinenumbering + \egroup} + +\setuplinenumbering + [\c!method=, + \c!conversion=\v!numbers, + \c!start=1, + \c!step=1, + \c!location=\v!margin, + \c!style=, + \c!color=, + \c!prefix=, + \c!referencing=\v!on, + \c!width=\ifcase\linenumberlocation2em\else\v!margin\fi, + \c!left=, + \c!right=, + \c!command=, + \c!distance=\zeropoint, + \c!align=\ifcase\linenumberlocation\v!right\or\v!right\or\v!left\fi] + +\protect \endinput diff --git a/tex/context/base/page-lin.mkiv b/tex/context/base/page-lin.mkiv new file mode 100644 index 000000000..51f027639 --- /dev/null +++ b/tex/context/base/page-lin.mkiv @@ -0,0 +1,498 @@ +%D \module +%D [ file=page-lin, +%D version=2007.11.29, +%D title=\CONTEXT\ Core Macros, +%D subtitle=Line Numbering, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% generic or not ... maybe not bother too much and simplify to mkiv only + +\writestatus{loading}{ConTeXt Core Macros / Line Numbering} + +\unprotect + +% todo: save settings + +% low level interface + +\registerctxluafile{page-lin}{1.001} + +\definesystemattribute[line-number] \chardef\linenumberattribute \dogetattributeid{line-number} +\definesystemattribute[line-reference] \chardef\linereferenceattribute \dogetattributeid{line-reference} + +\appendtoksonce \attribute\linenumberattribute \attributeunsetvalue \to \everyforgetall +\appendtoksonce \attribute\displaymathattribute\plusone \to \everybeforedisplayformula + +\newcount\linenumber +\newbox \linenumberscratchbox +\newcount\linenumberchunk +\newcount\linerefcounter + +\newconditional\tracelinenumbering + +\def\mkprocesstextlinenumbers#1% + {\setbox\linenumberscratchbox\vbox{\forgetall\offinterlineskip\ctxlua{nodes.lines.boxed.stage_one(\number#1)}}% + \ctxlua{nodes.lines.boxed.stage_two(\number#1,\number\linenumberscratchbox)}}% can move to lua code + +% id nr shift width leftskip dir + +% \def\mkskiplinenumber #1#2#3#4#6#5{} +% \def\mkleftlinenumber #1#2#3#4#5#6{\hbox{\llap{#2\quad\hskip#3\scaledpoint}}} +% \def\mkrightlinenumber#1#2#3#4#5#6{\hbox{\rlap{\hskip#4\scaledpoint\hskip#3\scaledpoint\quad#2}}} + +\let\makenumber\gobblesixarguments + +\newconditional\boxcontentneedsprocessing + +\def\mkdoprocesspagecontents #1{\mkaddtextlinenumbers{#1}\plusone \plusone} +\def\mkdoprocessboxcontents #1{\mkaddtextlinenumbers{#1}\plusone \plusone} +\def\mkdoprocesscolumncontents#1{\mkaddtextlinenumbers{#1}\currentcolumn\nofcolumns} + +\def\mklinenumberparameters + {continue = "\linenumberparameter\c!continue", + start = \linenumberparameter\c!start, + step = \linenumberparameter\c!step, + method = "\linenumberparameter\c!method", + tag = "\currentlinenumbering"} + +\def\mklinenumberupdateparameters + {continue = "\linenumberparameter\c!continue"} + +\def\mkdefinetextlinenumbering + {\setxvalue{ln:c:\currentlinenumbering}{\number\ctxlua{tex.sprint(nodes.lines.boxed.register({\mklinenumberparameters}))}}} + +\def\mkupdatetextlinenumbering + {\ctxlua{nodes.lines.boxed.setup(\getvalue{ln:c:\currentlinenumbering},{\mklinenumberupdateparameters})}} + +\def\mkstarttextlinenumbering#1#2% always when assignment + {\globallet\mkprocesspagecontents \mkdoprocesspagecontents + \globallet\mkprocesscolumncontents\mkdoprocesscolumncontents + \global\settrue\boxcontentneedsprocessing % see core-rul.mkiv + \edef\currentlinenumbering{#1}% + \ifcase#2\relax + \mkupdatetextlinenumbering % continue + \or + \mkdefinetextlinenumbering % only when assignment + \fi + \attribute\linenumberattribute\getvalue{ln:c:\currentlinenumbering}\relax} + +\def\mksetuptextlinenumbering + {\ifcsname ln:c:\currentlinenumbering\endcsname + \ctxlua{nodes.lines.boxed.setup(\getvalue{ln:c:\currentlinenumbering},{\mklinenumberparameters})}% + \fi} + +\def\mkstoptextlinenumbering + {\attribute\linenumberattribute\attributeunsetvalue} + +% we could make this a bit more efficient by putting the end reference +% in the same table as the start one but why make things complex ... + +\let\dofinishlinereference\dofinishfullreference + +\def\mksomelinereference#1#2#3% + {\dontleavehmode\begingroup + \global\advance\linerefcounter\plusone + \attribute\linereferenceattribute\linerefcounter + #3% + % for the moment we use a simple system i.e. no prefixes etc .. todo: store as number + \expanded{\dodosetreference{line}{#2}{conversion=\linenumberparameter\c!conversion}{\the\linerefcounter}}% kind labels userdata text + \endgroup} + +\def\mkstartlinereference#1{\mksomelinereference{#1}{lr:b:#1}{}\ignorespaces} +\def\mkstoplinereference #1{\removeunwantedspaces\mksomelinereference{#1}{lr:e:#1}{}} + +\def\mklinestartreference#1[#2]{\in{#1}[lr:b:#2]} % not interfaced +\def\mklinestopreference #1[#2]{\in{#1}[lr:e:#2]} % not interfaced + +% high level interface + +\newif\ifnumberinglines +\newif\iftypesettinglines + +\let\currentlinenumbering\empty + +\chardef\linenumbermode = 1 % 0=continue, 1=restart +\chardef\linenumberlocation = 1 % 0=middle, 1=left, 2=right, 3=inner, 4=outer, 5=text, 6=begin, 7=end +\chardef\linenumberalignment = 5 % 0=middle, 1=left, 2=right, 5=auto + +\newevery \beforeeverylinenumbering \relax +\newevery \aftereverylinenumbering \relax +\newevery \everylinenumber \relax + +\newdimen\linenumberwidth +\newdimen\linenumberdistance + +\unexpanded\def\definelinenumbering + {\dosingleempty\dodefinelinenumbering} + +\def\dodefinelinenumbering[#1]% + {\edef\currentlinenumbering{#1}% + \mkdefinetextlinenumbering} + +\unexpanded\def\setuplinenumbering + {\dodoubleempty\dosetuplinenumbering} + +\def\dosetuplinenumbering[#1][#2]% + {\ifsecondargument + \def\currentlinenumbering{#1}% + \getparameters[\??rn#1][#2]% + \else + \let\currentlinenumbering\empty + \getparameters[\??rn][#1]% + \fi + \mksetuptextlinenumbering} + +\def\linenumberparameter#1% + {\csname\??rn\ifcsname\??rn\currentlinenumbering#1\endcsname\currentlinenumbering\fi#1\endcsname} + +\def\linenumberattributes + {\doattributes{\??rn\ifcsname\??rn\currentlinenumbering\c!style\endcsname\currentlinenumbering\fi}} + +\setuplinenumbering + [\c!conversion=\v!numbers, + \c!start=1, + \c!step=1, + \c!method=\v!first, + \c!continue=\v!no, + \c!location=\v!left, + \c!style=, + \c!color=, + \c!width=2em, + \c!left=, + \c!right=, + \c!command=, + \c!distance=\zeropoint, + \c!align=\v!auto] + +\definelinenumbering + +\unexpanded\def\startlinenumbering + {\dodoubleempty\dostartlinenumbering} + +% no intermediate changes in values, define a class, otherwise each range +% would need a number + +% todo: text + +\expandafter\chardef\csname\??rn:l:\v!middle \endcsname \zerocount +\expandafter\chardef\csname\??rn:l:\v!left \endcsname \plusone +\expandafter\chardef\csname\??rn:l:\v!margin \endcsname \plusone +\expandafter\chardef\csname\??rn:l:\v!inmargin\endcsname \plusone +\expandafter\chardef\csname\??rn:l:\v!inleft \endcsname \plusone +\expandafter\chardef\csname\??rn:l:\v!right \endcsname \plustwo +\expandafter\chardef\csname\??rn:l:\v!inright \endcsname \plustwo +\expandafter\chardef\csname\??rn:l:\v!inner \endcsname \plusthree +\expandafter\chardef\csname\??rn:l:\v!outer \endcsname \plusfour +\expandafter\chardef\csname\??rn:l:\v!text \endcsname \plusfive +\expandafter\chardef\csname\??rn:l:\v!begin \endcsname \plussix +\expandafter\chardef\csname\??rn:l:\v!end \endcsname \plusseven + +\expandafter\chardef\csname\??rn:a:\v!middle \endcsname \zerocount +\expandafter\chardef\csname\??rn:a:\v!right \endcsname \plusone +\expandafter\chardef\csname\??rn:a:\v!flushleft \endcsname \plusone +\expandafter\chardef\csname\??rn:a:\v!left \endcsname \plustwo +\expandafter\chardef\csname\??rn:a:\v!flushright\endcsname \plustwo +\expandafter\chardef\csname\??rn:a:\v!auto \endcsname \plusfive + +\def\dostartlinenumbering[#1][#2]% todo: c!continue + {\begingroup + \chardef\linenumbermode\plusone + \ifsecondargument + \def\currentlinenumbering{#1}% + \doifassignmentelse{#2} + {\getparameters[\??rn\currentlinenumbering][#2]} + {\doifnumberelse{#2}% downward compatible + {\setvalue{\??rn#1\c!start}{#2}}% + {\doif{#2}\v!continue + {\getparameters[\??rn\currentlinenumbering][\c!continue=\v!yes]% + \chardef\linenumbermode\zerocount}}}% + \else\iffirstargument + \doifnumberelse{#1}% downward compatible + {\let\currentlinenumbering\empty + \setvalue{\??rn\c!start}{#1}}% + {\doifelse{#1}\v!continue + {\let\currentlinenumbering\empty + \getparameters[\??rn\currentlinenumbering][\c!continue=\v!yes]% + \chardef\linenumbermode\zerocount} + {\def\currentlinenumbering{#1}}}% + \fi\fi + \doif{\linenumberparameter\c!continue}\v!yes + {\chardef\linenumbermode\zerocount}% + \numberinglinestrue + \the\beforeeverylinenumbering + \mkstarttextlinenumbering\currentlinenumbering\linenumbermode} + +\unexpanded\def\stoplinenumbering + {\mkstoptextlinenumbering + \the\aftereverylinenumbering + \endgroup} + +% number placement + +\let\mkskiplinenumber \gobblesixarguments + +\def\mkdoinnerlinenumber{\doifoddpageelse\mkdoleftlinenumber\mkdorightlinenumber} +\def\mkdoouterlinenumber{\doifoddpageelse\mkdorightlinenumber\mkdoleftlinenumber} + +\def\mkleftlinenumber + {\ifcase\linenumberlocation + \expandafter\mkdoleftlinenumber + \or + \expandafter\mkdoleftlinenumber + \or + \expandafter\mkdoleftlinenumber + \or + \expandafter\mkdoinnerlinenumber + \or + \expandafter\mkdoouterlinenumber + \or + \expandafter\mkdotextlinenumber + \or + \expandafter\mkdobeginlinenumber + \or + \expandafter\mkdoendlinenumber + \fi} + +\def\mkrightlinenumber + {\ifcase\linenumberlocation + \expandafter\mkdorightlinenumber + \or + \expandafter\mkdorightlinenumber + \or + \expandafter\mkdorightlinenumber + \or + \expandafter\mkdoouterlinenumber + \or + \expandafter\mkdoinnerlinenumber + \or + \expandafter\mkdotextlinenumber + \or + \expandafter\mkdoendlinenumber + \or + \expandafter\mkdobeginlinenumber + \fi} + +\def\mkaddtextlinenumbers#1#2#3% box col max + {\bgroup + \chardef\linenumberbox #1\relax + \chardef\linenumbercolumn #2\relax + \chardef\linenumberlastcolumn#3\relax + \fullrestoreglobalbodyfont + \def\skipnumber{\hbox{}}% + \let\makenumber\maketextlinenumber + \mkprocesstextlinenumbers\linenumberbox + \egroup} + +\def\maketextlinenumber#1% + {\edef\currentlinenumbering{#1}% + \chardef\linenumberlocation \executeifdefined{\??rn:l:\linenumberparameter\c!location}\plusone % left + \chardef\linenumberalignment\executeifdefined{\??rn:a:\linenumberparameter\c!align }\plusfive % auto + \ifcase\linenumberlastcolumn\relax + \let\domakenumber\mkskiplinenumber + \or + % one column + \ifcase\linenumberlocation + \let\domakenumber\mkskiplinenumber + % hm + \or + \let\domakenumber\mkleftlinenumber + \or + \let\domakenumber\mkrightlinenumber + \or % inner + \let\domakenumber\mkdoinnerlinenumber + \or % outer + \let\domakenumber\mkdoouterlinenumber + \or % text + \let\domakenumber\mkdotextlinenumber + \or + \let\domakenumber\mkdobeginlinenumber + \or + \let\domakenumber\mkdoendlinenumber + \fi + \else\ifcase\linenumbercolumn\relax + \let\domakenumber\mkskiplinenumber + \or + \let\domakenumber\mkleftlinenumber + \ifcase\linenumberlocation\or + \chardef\linenumberlocation\plusone + \or + \chardef\linenumberlocation\plustwo + \else + \chardef\linenumberlocation\plusone + \or + \chardef\linenumberlocation\plusone + \or + \chardef\linenumberlocation\plusone + \or + \chardef\linenumberlocation\plusone % todo + \or + \chardef\linenumberlocation\plusone % todo + \fi + \else + \let\domakenumber\mkrightlinenumber + \ifcase\linenumberlocation\or + \chardef\linenumberlocation\plustwo + \or + \chardef\linenumberlocation\plusone + \or + \chardef\linenumberlocation\plustwo + \or + \chardef\linenumberlocation\plustwo + \or + \chardef\linenumberlocation\plustwo % todo + \or + \chardef\linenumberlocation\plustwo % todo + \fi + \fi\fi + \domakenumber{#1}} + +\def\mkdotextlinenumber #1#2#3#4#5#6% beware, one needs so compensate for this in the width ! + {\hbox{\dosomelinenumber{#1}{2}{#2}{#5}\hskip#3\scaledpoint}} + +\def\mkdotextlinenumber #1#2#3#4#5#6% beware, one needs so compensate for this in the width ! + {\hbox{\dosomelinenumber{#1}{2}{#2}{#5}\hskip#3\scaledpoint}} + +\def\mkdoleftlinenumber #1#2#3#4#5#6% + {\naturalhbox to \zeropoint + {\ifcase\istltdir#6\else \hskip-#4\scaledpoint \fi + \llap{\dosomelinenumber{#1}{2}{#2}{#5}\kern#3\scaledpoint}}} + +\def\mkdorightlinenumber#1#2#3#4#5#6% + {\naturalhbox to \zeropoint + {\ifcase\istltdir#6\else \hskip-#4\scaledpoint \fi + \rlap{\hskip#4\scaledpoint\hskip#3\scaledpoint\dosomelinenumber{#1}{1}{#2}{#5}}}} + +\def\mkdobeginlinenumber #1#2#3#4#5#6% + {\ifcase\istltdir#6\relax + \chardef\linenumberlocation\plusone + \expandafter\mkdoleftlinenumber + \else + \chardef\linenumberlocation\plustwo + \expandafter\mkdorightlinenumber + \fi{#1}{#2}{#3}{#4}{#5}{#6}} + +\def\mkdoendlinenumber#1#2#3#4#5#6% + {\ifcase\istltdir#6\relax + \chardef\linenumberlocation\plustwo + \expandafter\mkdorightlinenumber + \else + \chardef\linenumberlocation\plusone + \expandafter\mkdoleftlinenumber + \fi{#1}{#2}{#3}{#4}{#5}{#6}} + +\def\dosomelinenumber#1#2#3#4% tag 1=left|2=right linenumber leftskip + {\begingroup + \def\currentlinenumbering{#1}% + \def\linenumber{#3}% unsafe + \doifelse{\linenumberparameter\c!width}\v!margin + {\linenumberwidth\leftmarginwidth} + {\linenumberwidth\linenumberparameter\c!width}% + \linenumberdistance\linenumberparameter\c!distance\relax + \ifcase#2\relax\or\hskip\linenumberdistance\fi\relax + \ifnum\linenumberlocation=\plusfive + \scratchdimen\dimexpr#4\scaledpoint-\linenumberdistance\relax + \chardef\linenumberlocation\plusone + \else + \scratchdimen\zeropoint + \fi + \ifcase\linenumberalignment + \chardef\linenumberlocation\zerocount % middle + \or + \chardef\linenumberlocation\plusone % left + \or + \chardef\linenumberlocation\plustwo % right + \fi + \ifconditional\tracelinenumbering\ruledhbox\else\hbox\fi to \linenumberwidth + {\ifcase\linenumberlocation + \hss % middle + \or + % left + \or + \hss % right + \or + \doifoddpageelse\relax\hss % inner + \or + \doifoddpageelse\hss\relax % outer + \fi + \linenumberattributes\c!style\c!color + {\linenumberparameter\c!command + {\linenumberparameter\c!left + \convertnumber{\linenumberparameter\c!conversion}{#3}% + \linenumberparameter\c!right}}% + \ifcase\linenumberlocation + \hss % middle + \or + \hss % left + \or + % right + \or + \doifoddpageelse\hss\relax % inner + \or + \doifoddpageelse\relax\hss % outer + \fi}% + \ifcase#2\relax\or\or\hskip\linenumberdistance\fi\relax + \hskip-\scratchdimen + \the\everylinenumber + \endgroup} + +% left right inner outer + +% align: \alignedline\@@rnalign\v!right{\box0\hskip\@@rndistance} + +% referencing + +\def\someline [#1]{\mkstartlinereference{#1}\mkstoplinereference{#1}} +\unexpanded\def\startline[#1]{\mkstartlinereference{#1}} +\unexpanded\def\stopline [#1]{\mkstoplinereference {#1}} + +\def\mkshowstartlinereference#1% + {\ifconditional\tracelinenumbering + \setbox\scratchbox\hbox{\llap + {\vrule\!!width\onepoint\!!depth\strutdp\!!height.8\strutht\raise.85\strutht\hbox{\llap{\tt\txx#1}}}}% + \smashbox\scratchbox\box\scratchbox + \fi} +\def\mkshowstoplinereference#1% + {\ifconditional\tracelinenumbering + \setbox\scratchbox\hbox{\rlap + {\raise.85\strutht\hbox{\rlap{\tt\txx#1}}\vrule\!!width\onepoint\!!depth\strutdp\!!height.8\strutht}}% + \smashbox\scratchbox\box\scratchbox + \fi} + +\def\mkstartlinereference#1{\mksomelinereference{#1}{lr:b:#1}{\mkshowstartlinereference{#1}}\ignorespaces} +\def\mkstoplinereference #1{\removeunwantedspaces\mksomelinereference{#1}{lr:e:#1}{\mkshowstoplinereference{#1}}} + +% eventually we will do this in lua + +\def\currentreferencelinenumber{\ctxlua{jobreferences.filter("linenumber")}} + +\def\doifelsesamelinereference#1#2#3% + {\doifreferencefoundelse{lr:b:#1} + {\edef\fline{\currentreferencelinenumber}% + \doifreferencefoundelse{lr:e:#1} + {\edef\tline{\currentreferencelinenumber}% + %[\fline,\tline] + \ifx\fline\tline#2\else#3\fi} + {\unknownreference{#1}#2}} + {\unknownreference{#1}#2}} + +\def\inline#1[#2]% + {\doifelsenothing{#1} + {\doifelsesamelinereference{#2} + {\in{\leftlabeltext\v!line}{\rightlabeltext\v!line}[lr:b:#2]} + {\in{\leftlabeltext\v!lines}{}[lr:b:#2]--\in{}{\rightlabeltext\v!lines}[lr:e:#2]}} + {\doifelsesamelinereference{#2} + {\in{#1}[lr:b:#2]} + {\in{#1}[lr:b:#2]--\in[lr:e:#2]}}} + +\def\inlinerange[#1]% + {\doifelsesamelinereference{#1} + {\in[lr:b:#1]} + {\in[lr:b:#1]--\in[lr:e:#1]}} + +\protect \endinput diff --git a/tex/context/base/page-log.mkii b/tex/context/base/page-log.mkii new file mode 100644 index 000000000..18c7991b1 --- /dev/null +++ b/tex/context/base/page-log.mkii @@ -0,0 +1,202 @@ +%D \module +%D [ file=page-log, % moved here from main-001 +%D version=1997.03.31, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Logos, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Logos} + +\unprotect + +%D Although logos can conveniently be implemented on top of +%D background and text areas, we provide a dedicated mechanism +%D here. One reason is that such a separate mechanism cannot +%D interfere with the other ones, but an even more important +%D reason is that logos are kind of special in the sense that +%D they have a short life span and may change after the first +%D page. + +%D \macros +%D {recalculatelogos,addlogobackground} +%D +%D The interface to the other low level page building routines +%D is provided by a macro that signals changes in layout +%D specifications: +%D +%D \starttyping +%D \recalculatelogos +%D \stoptyping +%D +%D as well as a simple placement macro: +%D +%D \starttyping +%D \addlogobackground +%D \stoptyping +%D +%D In no way the following boolean switch should be used +%D directly. + +\newif\ifnewlogos + +\def\recalculatelogos + {\global\newlogostrue} + +%D The current state of logos is registered in a status +%D variable \type {\logostatus}. +%D +%D \starttabulate[|l|l|l|] +%D \NC 0 \NC don't place \NC remains 0 \NC \NR +%D \NC 1 \NC place now \NC remains 1 \NC \NR +%D \NC 2 \NC calulate and place \NC becomes 1 \NC \NR +%D \NC 3 \NC calculate and place once \NC becomes 2 \NC \NR +%D \stoptabulate + +\chardef\logostatus=0 + +\def\addlogobackground#1% todo: dimension spec + {\ifcase\logostatus \else + \ifcase\logostatus + % no logos to take care of + \or % 1 + \ifnewlogos + \chardef\logostatus2 + \setlogoboxes + \chardef\logostatus1 + \global\newlogosfalse + \fi + \or % 2 + \setlogoboxes + \chardef\logostatus1 + \or % 3 + \setlogoboxes + \global\chardef\logostatus2 + \fi + \setbox#1\vbox + {\offinterlineskip + \doifmarginswapelse + {\copy\leftlogos} + {\copy\rightlogos} + \box#1}% + \fi} + +%D For efficiency reasons (and since logos seldom change inside +%D a document) we can save the left and right hand (or first +%D and following page) logos in boxes. The areas are slightly +%D different from the ones used in backgrounds and text +%D placement, but still related to the page layout. The {\em +%D left} and {\em right edge}, as well as {\em top} and {\em +%D bottom} touch the bounding box of the paper and are +%D therefore not the sams as their background adn text +%D counterparts. In addition there are {\em left}, {\em right} +%D and {\em middle} areas as well as a {\em page} one. + +\newbox\leftlogos +\newbox\rightlogos + +\def\setlogoboxes + {\showmessage\m!layouts7\empty + \dosetlogobox\leftlogos\relax + \ifdoublesided + \dosetlogobox\rightlogos\doswapmargins + \fi} + +\def\dosetlogobox#1#2% + {\global\setbox#1\vbox to \paperheight + {\dontcomplain % needed here ? + \calculatereducedvsizes % needed here ? + \offinterlineskip + #2\relax + \vskip-\topspace + \dodosetlogobox\v!top\blap + \vskip\topspace + \dodosetlogobox\v!header\blap + \vskip\dimexpr\headerheight+\headerdistance\relax + \dodosetlogobox\v!text\blap + \vskip\dimexpr\textheight+\footerdistance+\footerheight\relax + \dodosetlogobox\v!footer \tlap + \vfilll + \dodosetlogobox\v!bottom\tlap + \vskip\topspace} + \smashbox#1} + +\def\dodosetlogobox#1#2% + {\hbox % width equals \makeupwidth + {\def\docommand##1% + {\donefalse + \ifnum\logostatus=3 \ExpandBothAfter + \doifinset{\getvalue{\??lo#1##1}}\requestedlogos\donetrue + \else + \doifvalue{\??lo#1##1\c!state}\v!start\donetrue + \fi + \ifdone + #2{\hbox{\getvalue{\??lo#1##1\c!command}}}% + \fi}% + \def\dodocommand##1##2##3##4##5##6% + {\hsmash + {\hskip-\texthoffset + \hbox to \paperwidth + {\rlap{\docommand##1}\hss\llap{\docommand##6}}% + \hskip-\paperwidth + \hbox to \paperwidth + {\hskip\texthoffset + \hskip-\leftmarginwidth + \hskip-\leftmargindistance + \hbox to \leftmarginwidth{\docommand##2\hss}% + \hskip\leftmargindistance + \hbox to \makeupwidth{\docommand##3\hss\docommand##4}% + \hskip\rightmargindistance + \hbox to \rightmarginwidth{\hss\docommand##5}% + \hfill}}}% + \normalbaselines + \settexthoffset + \hsmash + {\hbox to \makeupwidth{\hss\docommand\c!middle\hss}}% + \hsmash + {\hskip-\texthoffset + \hbox to \paperwidth{\docommand\v!page\hss}}% + \swapmargins + \doifbothsidesoverruled + {\dodocommand + \v!leftedge \v!leftmargin \v!left + \v!right \v!rightmargin \v!rightedge} + {\dodocommand + \v!leftedge \v!leftmargin \v!left + \v!right \v!rightmargin \v!rightedge} + {\dodocommand + \v!rightedge \v!rightmargin \v!right + \v!left \v!leftmargin \v!leftedge}}} + +%D The user interface is relatively simple and provides +%D macros for assigning logos to logo areas as well as +%D forcing placement. +%D +%D \showsetup{definelogo} +%D \showsetup{placelogos} + +\let\definedlogos \empty +\let\requestedlogos\empty + +\long\def\dodefinelogo[#1][#2][#3][#4]% + {\addtocommalist{#1}\definedlogos + \long\setvalue{\??lo#2#3}{#1}% + \getparameters[\??lo#2#3][#4]% + \global\chardef\logostatus2 } + +\def\definelogo + {\doquadrupleargument\dodefinelogo} + +\def\placelogos + {\dosingleempty\doplacelogos} + +\def\doplacelogos[#1]% + {\xdef\requestedlogos{\iffirstargument#1\else\definedlogos\fi}% + \global\chardef\logostatus3 } + +\protect \endinput diff --git a/tex/context/base/page-mak.mkii b/tex/context/base/page-mak.mkii new file mode 100644 index 000000000..040feb1d2 --- /dev/null +++ b/tex/context/base/page-mak.mkii @@ -0,0 +1,234 @@ +%D \module +%D [ file=page-mak, % copied from main-001, +%D version=1997.03.31, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Simple MakeUp, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / MakeUp} + +\unprotect + +%D \macros +%D {definemakeup, setupmakeup, startmakeup} +%D +%D A makeup is a separate page, like a title page or colofon. +%D There is one standard makeup page, but you can define more +%D if needed. +%D +%D \starttyping +%D \startstandardmakeup +%D My Fancy Title +%D \stopstandardmakeup +%D \stoptyping +%D +%D The associated commands are: +%D +%D \showsetup{definemakeup} +%D \showsetup{setupmakeup} +%D \showsetup{startmakeup} + +\def\definemakeup + {\dodoubleargument\dodefinemakeup} + +\def\dodefinemakeup[#1][#2]% + {\getparameters + [\??do#1]% + [\c!width=\innermakeupwidth, % example in manual / was \makeupwidth + \c!height=\textheight, % example in manual + \c!voffset=\!!zeropoint, % example in manual + \c!hoffset=\!!zeropoint, % example in manual + \c!commands=, + \c!setups=, + \c!page=\v!right, + \c!doublesided=\v!empty, + \c!before=, + \c!top=\vss, + \c!bottom=\vss, + \c!after=, + \c!bottomstate=\v!normal, + \c!topstate=\v!normal, + \c!textstate=\v!normal, + \c!headerstate=\v!stop, + \c!footerstate=\v!stop, + \c!pagestate=\v!stop, % in manual ! ! ! + \c!color=, + \c!align=, + #2]% + \setvalue{\e!start#1\e!makeup}{\startmakeup[#1]}% + \setvalue{\e!stop #1\e!makeup}{\stopmakeup}} + +\def\setupmakeup + {\dodoubleargument\dosetupmakeup} + +\def\dosetupmakeup[#1]% + {\getparameters[\??do#1]} + +%D This will save us some 375 bytes in the format file. + +\def\makeupparameter#1{\getvalue{\??do\currentmakeup#1}} + +%D The \type{\start}||\type{\stop} macros are used for both +%D the direct and indirect way. The parameterless call will +%D build a simple box. + +\newtoks\everymakeup + +\appendtoks \postponemarks \to \everymakeup + +\let\currentmakeup\empty + +\def\startmakeup + {\dodoubleempty\dostartmakeup} + +\def\dostartmakeup[#1][#2]% + {\bgroup + \edef\currentmakeup{#1}% + \the\everymakeup + \iffirstargument + \setupmakeup[\currentmakeup][#2]% + \let\stopmakeup\dodostopmakeup + \expandafter \dodostartmakeup + \else + \let\stopmakeup\donostopmakeup + \expandafter \donostartmakeup + \fi} + +%D The simple case: + +\def\donostartmakeup % textwidth ? + {\page + \setupheader[\c!state=\v!empty]% + \setupfooter[\c!state=\v!empty]% + \setsystemmode\v!makeup + \vbox to \textheight\bgroup\hsize\textwidth} + +\def\donostopmakeup + {\egroup + \flushmarks % new, here, else empty pages + \page + \egroup} + +%D The normal one: + +\newbox\makeupbox + +\def\dodostartmakeup + {\doifvaluesomething{\??do\currentmakeup\c!page} + {\ExpandFirstAfter\page[\makeupparameter\c!page]}% + \pagetype[\currentmakeup]% + \setsystemmode\v!makeup + \setupmakeuplayout + \makeupparameter\c!commands % hm, what is this one doing here ? + \startregistercolor[\makeupparameter\c!color]% + \forgetall % else indented flush + \global\setbox\makeupbox\vbox to \makeupparameter\c!height + \bgroup +% \forgetall + \setups[\makeupparameter\c!setups]% + \hsize\makeupparameter\c!width + \doifsomething{\makeupparameter\c!align} + {\setupalign[\makeupparameter\c!align]}% + \makeupparameter\c!top} + +\def\dodostopmakeup + {\endgraf + \makeupparameter\c!bottom + \egroup + \flushmarks % new, here, else empty pages + \stopregistercolor + \doflushmakeup + \egroup + \calculatehsizes + \calculatevsizes} + +%D Selective page processing is handled here. (Why?) + +\def\doflushmakeup + {\ifprocessingpages + \ifpageselected + \doshipoutmakeup + \fi + \else + \ifpageselected \else + \doshipoutmakeup + \fi + \fi + \ifselectingpages + \global\pageselectedfalse + \fi} + +% \def\pushpagestate{\globalpushmacro\@@pnstate} +% \def\poppagestate {\globalpopmacro \@@pnstate} + +\def\doshipoutmakeup + {\pushpagestate % new + \makeupparameter\c!before + \setbox\makeupbox\vbox{\hbox{\color[\makeupparameter\c!color]{\box\makeupbox}}}% + % \ifgridsnapping + % new per 22/6/2006 + \ifdim\ht\makeupbox>\vsize + \ht\makeupbox\vsize + \fi + % \fi + \box\makeupbox + \setuppagenumber[\c!state=\makeupparameter\c!pagestate]% + \setupmakeuplayout + \page + \makeupparameter\c!after + \relax % voor fi + \ifdoublesided \ifodd\realpageno\else + \processaction + [\makeupparameter\c!doublesided] + [ \v!yes=>\null + \page, + \v!empty=>{\setupmakeuplayout + \page[\v!blank]% + \null + \page}]% + \fi \fi + \poppagestate} % new + +%D The text surrounding the main body text can be influenced +%D by setting their associated status variables. The +%D connection between them is made by the following macro + +\def\setupmakeuplayout + {\setupfooter[\c!state=\makeupparameter\c!footerstate]% + \setupheader[\c!state=\makeupparameter\c!headerstate]% + \setuptext [\c!state=\makeupparameter\c!textstate]% + \setupbottom[\c!state=\makeupparameter\c!bottomstate]% + \setuptop [\c!state=\makeupparameter\c!topstate]% + % this is needed, but no \setuplayout here; fails in texexec --fig=c + \recalculatelayout} + +%D The standard page template is defined as follows: + +\definemakeup + [\v!standard] + [\c!width=\innermakeupwidth, + \c!height=\textheight, + \c!voffset=\!!zeropoint, + \c!hoffset=\!!zeropoint, + \c!page=\v!right, + \c!doublesided=\v!empty] + +\definemakeup + [\v!text] + [\c!topstate=\v!start, + \c!headerstate=\v!start, + \c!textstate=\v!start, + \c!footerstate=\v!start, + \c!bottomstate=\v!start, + \c!doublesided=\v!no, + \c!page=\v!yes, + \c!top=\pseudostrut\ignorespaces, + \c!bottom=\obeydepth\vss] + +\protect \endinput diff --git a/tex/context/base/page-mak.mkiv b/tex/context/base/page-mak.mkiv new file mode 100644 index 000000000..fd89a45ff --- /dev/null +++ b/tex/context/base/page-mak.mkiv @@ -0,0 +1,233 @@ +%D \module +%D [ file=page-mak, % copied from main-001, +%D version=1997.03.31, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Simple MakeUp, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / MakeUp} + +\unprotect + +%D \macros +%D {definemakeup, setupmakeup, startmakeup} +%D +%D A makeup is a separate page, like a title page or colofon. +%D There is one standard makeup page, but you can define more +%D if needed. +%D +%D \starttyping +%D \startstandardmakeup +%D My Fancy Title +%D \stopstandardmakeup +%D \stoptyping +%D +%D The associated commands are: +%D +%D \showsetup{definemakeup} +%D \showsetup{setupmakeup} +%D \showsetup{startmakeup} + +\unexpanded\def\definemakeup + {\dodoubleargument\dodefinemakeup} + +\def\dodefinemakeup[#1][#2]% + {\getparameters + [\??do#1]% + [\c!width=\innermakeupwidth, % example in manual / was \makeupwidth + \c!height=\textheight, % example in manual + \c!voffset=\!!zeropoint, % example in manual + \c!hoffset=\!!zeropoint, % example in manual + \c!commands=, + \c!setups=, + \c!page=\v!right, + \c!doublesided=\v!empty, + \c!before=, + \c!top=\vss, + \c!bottom=\vss, + \c!after=, + \c!bottomstate=\v!normal, + \c!topstate=\v!normal, + \c!textstate=\v!normal, + \c!headerstate=\v!stop, + \c!footerstate=\v!stop, + \c!pagestate=\v!stop, % in manual ! ! ! + \c!color=, + \c!align=, + #2]% + \setvalue{\e!start#1\e!makeup}{\startmakeup[#1]}% + \setvalue{\e!stop #1\e!makeup}{\stopmakeup}} + +\unexpanded\def\setupmakeup + {\dodoubleargument\dosetupmakeup} + +\def\dosetupmakeup[#1]% + {\getparameters[\??do#1]} + +%D This will save us some 375 bytes in the format file. + +\def\makeupparameter#1{\getvalue{\??do\currentmakeup#1}} + +%D The \type{\start}||\type{\stop} macros are used for both +%D the direct and indirect way. The parameterless call will +%D build a simple box. + +\newtoks\everymakeup + +\appendtoks \postponemarks \to \everymakeup + +\let\currentmakeup\empty + +\unexpanded\def\startmakeup + {\dodoubleempty\dostartmakeup} + +\def\dostartmakeup[#1][#2]% + {\bgroup + \edef\currentmakeup{#1}% + \the\everymakeup + \iffirstargument + \setupmakeup[\currentmakeup][#2]% + \let\stopmakeup\dodostopmakeup + \expandafter \dodostartmakeup + \else + \let\stopmakeup\donostopmakeup + \expandafter \donostartmakeup + \fi} + +%D The simple case: + +\def\donostartmakeup % textwidth ? + {\page + \setupheader[\c!state=\v!empty]% + \setupfooter[\c!state=\v!empty]% + \setsystemmode\v!makeup + \vbox to \textheight\bgroup\hsize\textwidth} + +\def\donostopmakeup + {\egroup + \flushmarks % new, here, else empty pages + \page + \egroup} + +%D The normal one: + +\newbox\makeupbox + +\def\dodostartmakeup + {\doifvaluesomething{\??do\currentmakeup\c!page} + {\ExpandFirstAfter\page[\makeupparameter\c!page]}% + \pagetype[\currentmakeup]% + \setsystemmode\v!makeup + \setupmakeuplayout + \makeupparameter\c!commands % hm, what is this one doing here ? + \forgetall % else indented flush + \global\setbox\makeupbox\vbox to \makeupparameter\c!height + \bgroup + \doifsomething{\makeupparameter\c!color}{\startcolor[\makeupparameter\c!color]}% can be made faster + \doprocesslocalsetups{\makeupparameter\c!setups}% + \hsize\makeupparameter\c!width + \doifsomething{\makeupparameter\c!align} + {\setupalign[\makeupparameter\c!align]}% + \makeupparameter\c!top} + +\def\dodostopmakeup + {\endgraf + \makeupparameter\c!bottom + \doifsomething{\makeupparameter\c!color}{\stopcolor}% + \egroup + \flushmarks % new, here, else empty pages + \doflushmakeup + \egroup + \calculatehsizes + \calculatevsizes} + +%D Selective page processing is handled here. (Why?) + +\def\doflushmakeup + {\ifprocessingpages + \ifpageselected + \doshipoutmakeup + \fi + \else + \ifpageselected \else + \doshipoutmakeup + \fi + \fi + \ifselectingpages + \global\pageselectedfalse + \fi} + +% \def\pushpagestate{\globalpushmacro\@@pnstate} +% \def\poppagestate {\globalpopmacro \@@pnstate} + +\def\doshipoutmakeup + {\pushpagestate % new + \makeupparameter\c!before + \setbox\makeupbox\vbox{\hbox{\color[\makeupparameter\c!color]{\box\makeupbox}}}% + % \ifgridsnapping + % new per 22/6/2006 + \ifdim\ht\makeupbox>\vsize + \ht\makeupbox\vsize + \fi + % \fi + \box\makeupbox + \setuppagenumber[\c!state=\makeupparameter\c!pagestate]% + \setupmakeuplayout + \page + \makeupparameter\c!after + \relax % voor fi + \ifdoublesided \ifodd\realpageno\else + \processaction + [\makeupparameter\c!doublesided] + [ \v!yes=>\null + \page, + \v!empty=>{\setupmakeuplayout + \page[\v!blank]% + \null + \page}]% + \fi \fi + \poppagestate} % new + +%D The text surrounding the main body text can be influenced +%D by setting their associated status variables. The +%D connection between them is made by the following macro + +\unexpanded\def\setupmakeuplayout + {\setupfooter[\c!state=\makeupparameter\c!footerstate]% + \setupheader[\c!state=\makeupparameter\c!headerstate]% + \setuptext [\c!state=\makeupparameter\c!textstate]% + \setupbottom[\c!state=\makeupparameter\c!bottomstate]% + \setuptop [\c!state=\makeupparameter\c!topstate]% + % this is needed, but no \setuplayout here; fails in texexec --fig=c + \recalculatelayout} + +%D The standard page template is defined as follows: + +\definemakeup + [\v!standard] + [\c!width=\innermakeupwidth, + \c!height=\textheight, + \c!voffset=\!!zeropoint, + \c!hoffset=\!!zeropoint, + \c!page=\v!right, + \c!doublesided=\v!empty] + +\definemakeup + [\v!text] + [\c!topstate=\v!start, + \c!headerstate=\v!start, + \c!textstate=\v!start, + \c!footerstate=\v!start, + \c!bottomstate=\v!start, + \c!doublesided=\v!no, + \c!page=\v!yes, + \c!top=\pseudostrut\ignorespaces, + \c!bottom=\obeydepth\vss] + +\protect \endinput diff --git a/tex/context/base/page-mar.mkii b/tex/context/base/page-mar.mkii new file mode 100644 index 000000000..96223bafe --- /dev/null +++ b/tex/context/base/page-mar.mkii @@ -0,0 +1,867 @@ +%D \module +%D [ file=page-mar, % moved here from main-001 +%D version=1997.03.31, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Marginal 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 Support for margin words is one of the reasons for writing +%D \CONTEXT. Over time support for marginal content has been +%D extended en enhanced. Therefore it's always good to watch +%D out for unexpected side effects. + +\writestatus{loading}{ConTeXt Page Macros / Maginal Things} + +\unprotect + +%D There are three categories and their historically grown meaning is +%D as follows: +%D +%D marginlines: these are flushed relative to the start of a line and +%D need to be invoked there. +%D +%D marginwords: these can be issued in the text flow and will migrate +%D sidewards; in spite of the name, it can be a paragraph of text as +%D well, but normally it's words. +%D +%D margintexts: these can be set beforehand and are flushed at the +%D next paragraph of text (of header) +%D +%D While these mechanisms were rather separated, they now are slightly +%D more integrated. Instead of low level instances we now have a mechanism +%D for defining additional ones. + +%D \macros +%D {inleftedge,inleftmargin,inrightmargin,inrightedge} +%D +%D The fast and clean way of putting things in the margin is +%D using \type{\rlap} or \type{\llap}. Unfortunately these +%D macro's don't handle indentation, left and right skips. We +%D therefore embed them in some macro's that (force and) +%D remove the indentation and restore it afterwards. + +\def\definemarginline + {\dodoubleargument\dodefinemarginline} + +\def\dodefinemarginline[#1][#2]% + {\getparameters + [\??im\??im#1] + [\c!location=\v!left, + \c!distance=\zeropoint, + \c!width=\leftmarginwidth, + \c!hoffset=\leftmargindistance, + \c!command=, + #2]% + \unexpanded\setvalue{#1}{\dohandlemarginline{#1}}} + +\def\marginlineparameter #1{\csname\??im\??im\currentmarginline#1\endcsname} +\def\marginlineexecuter #1#2{\executeifdefined{\??im\??im\currentmarginline#1}{#2}} + +\def\dohandlemarginline#1% #2 + {\def\currentmarginline{#1}% + \csname\s!do\??im\??im\executeifdefined{\??im\??im#1\c!location}\v!left\endcsname{#1}} % {#2} + +\def\doleftmarginline#1#2% #1 is redundant (we can remove it when we group dohandlemarginline; maybe ... + {\pushindentation + \llap + {\def\currentmarginline{#1}% + \postsignalrightpage + \hsize\marginlineparameter\c!width\relax + \marginlineexecuter\c!command\firstofoneargument{#2}\relax + \hskip\dimexpr + +\leftskip + +\compensatedinnermakeupmargin + +\marginlineparameter\c!hoffset + +\marginlineparameter\c!distance + \relax}% + \popindentation + \ignorespaces} + +\def\dorightmarginline#1#2% #1 is redundant + {\pushindentation + \rlap + {\def\currentmarginline{#1}% + \postsignalrightpage + \hskip\dimexpr + +\hsize + -\rightskip + +\compensatedinnermakeupmargin + +\marginlineparameter\c!hoffset + +\marginlineparameter\c!distance + \relax + \hsize\marginlineparameter\c!width + \marginlineexecuter\c!command\firstofoneargument{#2}}% + \popindentation + \ignorespaces} + +\long\def\installmarginlinehandler#1#2{\setvalue{\s!do\??im\??im#1}{#2}} + +\installmarginlinehandler \v!left {\doleftmarginline} +\installmarginlinehandler \v!right {\dorightmarginline} +\installmarginlinehandler \v!inner {\presignalrightpage\doifrightpageelse\doleftmarginline \dorightmarginline} +\installmarginlinehandler \v!outer {\presignalrightpage\doifrightpageelse\dorightmarginline\doleftmarginline } + +\definemarginline[inleftmargin] [\c!location=\v!left, \c!width=\leftmarginwidth, \c!distance=\leftmargindistance, \c!hoffset=\zeropoint] +\definemarginline[inrightmargin][\c!location=\v!right,\c!width=\rightmarginwidth,\c!distance=\rightmargindistance,\c!hoffset=\zeropoint] +\definemarginline[inleftedge] [\c!location=\v!left, \c!width=\leftedgewidth, \c!distance=\leftedgedistance, \c!hoffset=\leftmargintotal] +\definemarginline[inrightedge] [\c!location=\v!right,\c!width=\rightedgewidth, \c!distance=\rightedgedistance, \c!hoffset=\rightmargintotal] + +\definemarginline[inoutermargin][\c!location=\v!outer,\c!width=\outermarginwidth,\c!distance=\outermargindistance,\c!hoffset=\zeropoint] +\definemarginline[ininnermargin][\c!location=\v!inner,\c!width=\innermarginwidth,\c!distance=\innermargindistance,\c!hoffset=\zeropoint] +\definemarginline[inouteredge] [\c!location=\v!outer,\c!width=\outeredgewidth, \c!distance=\outeredgedistance, \c!hoffset=\outermargintotal] +\definemarginline[ininneredge] [\c!location=\v!inner,\c!width=\inneredgewidth, \c!distance=\inneredgedistance, \c!hoffset=\innermargintotal] + +\definemarginline[atleftmargin] [\c!location=\v!left, \c!command=\lrlap,\c!width=\zeropoint,\c!distance=\zeropoint,\c!hoffset=\zeropoint] +\definemarginline[atrightmargin][\c!location=\v!right,\c!command=\rllap,\c!width=\zeropoint,\c!distance=\zeropoint,\c!hoffset=\zeropoint] + +\ifx\lrlap\undefined \def\lrlap#1{\llap{\rlap{#1}}} \fi +\ifx\rllap\undefined \def\rllap#1{\rlap{\llap{#1}}} \fi + +\def\lrlap#1{\llap{\rlap{#1}}} +\def\rllap#1{\rlap{\hskip\hsize\llap{#1}}} + +%D We want to keep things efficient and therefore only handle +%D situations like: +%D +%D \startbuffer +%D \inleftedge {fine} some text \par +%D \strut \inleftmargin {fine} some text \par +%D \noindent \inrightmargin {fine} some text \par +%D \noindent \strut \inrightedge {fine} some text \par +%D \stopbuffer +%D +%D \typebuffer +%D +%D which looks like: +%D +%D \bgroup +%D \getbuffer +%D \parindent 30pt +%D \getbuffer +%D \egroup +%D +%D A torture test: +%D +%D \starttyping +%D \def\TestLine#1#2{\backgroundline[#1]{\strut\white\tttf#2~\recurselevel}} +%D +%D \startbuffer +%D \inleftmargin {\TestLine{red} {lm}} test test test \par +%D \inrightmargin{\TestLine{green} {rm}} test test test \par +%D \inleftedge {\TestLine{red} {le}} test test test \par +%D \inrightedge {\TestLine{green} {re}} test test test \par +%D \inoutermargin{\TestLine{blue} {om}} test test test \par +%D \ininnermargin{\TestLine{yellow}{im}} test test test \par +%D \inouteredge {\TestLine{blue} {oe}} test test test \par +%D \ininneredge {\TestLine{yellow}{ie}} test test test \par +%D \atleftmargin {\TestLine{red} {alm}} \hfill test \par +%D \atrightmargin{\TestLine{green} {arm}} test \hfill \par +%D \stopbuffer +%D +%D \dorecurse{40}\getbuffer \page +%D \stoptyping + +%D New, yet undocumented: +%D +%D used for pascal: +%D +%D \starttyping +%D \index {test} test \index {west} west \index {rest} rest +%D +%D \startnarrower +%D \placeregister[index][alternative=b,command=\atleftmargin] +%D \stopnarrower +%D \stoptyping + +% todo: compensate distance when setuplayout[textwidth=..] +% todo: generalize margin/edge model, now too much duplication + +%D The next bunch of macros looks messy which is due to its +%D multi-purpose character. + +\chardef\margincontentdisplacement \zerocount +\let \margincontentdistance \!!zeropoint +\let \margincontenthoffset \!!zeropoint +\def \margincontentlines {1} +\def \margincontenttag {0} +\let \margincontentseparator \empty +\def \margincontentstrutheight {\strutht} + +\newcount\margincontentlevel +\newdimen\margincontentheight + +\def\setupinmargin + {\dodoubleempty\dosetupinmargin} + +\def\dosetupinmargin[#1][#2]% + {\ifsecondargument + \processcommalist[#1]{\dodosetupinmargin[#2]}% becomes [#2]{##1} + \else + \getparameters[\??im][#1]% + \fi} + +% \def\dodosetupinmargin[#1]#2% [settings]{class} +% {\checkinmargin[#2]% +% \getparameters[\??im#2][#1]} + +\def\dodosetupinmargin[#1]#2% [settings]{class} + {\checkinmargin[#2]% + \getparameters[\??im#2][#1]% + % will become an \everyinmarginsetup thing + \ifcase\executeifdefined{\??im#2\c!sidemethod}{0}\else + \enableparpositions + \fi} + +\def\checkinmargin[#1]% + {\ifundefined{\??im#1\c!offset}% this offset is related to framed ! + \addtocommalist{#1}\inmargintaglist + \presetmargintext[#1]% + \fi} + +\def\presetmargintext[#1]% + {\presetlocalframed + [\??im#1]% + \getparameters + [\??im#1] + [\c!frame=\v!off, + \c!offset=\v!overlay, + \c!line=1, + \c!separator=, + \c!width=\v!broad, + \c!distance=, % empty = signal + \c!hoffset=\zeropoint, + \c!style=\@@imstyle, + \c!color=\@@imcolor, + \c!strut=\@@imstrut, + \c!location=\@@imlocation, + \c!align=\@@imalign, + \c!before=\@@imbefore, + \c!after=\@@imafter]} + +\newdimen\naturalmargincontentheight + +\def\makemargintextblock#1#2#3% width l r content + {\bgroup + \forgetall % added, else problems with 'center' and nested itemize + \dontcomplain + \hsize\getvalue{\??im#1\c!width}\relax + \doifnumberelse\margincontenttag + {\ifcase\margincontenttag\relax + \edef\margincontenttag{#1}% first one is setups id as well + \fi} + \donothing + \doifnumberelse\margincontenttag + {\ifnum\margincontenttag>25 % to be translated + \writestatus\m!systems{potential margin stack overflow (\margincontenttag)}% + \fi} + \donothing + % we need to preserve {a,b,c} kind of settings + \let\margincontentalign#1% + \processallactionsinset + [\getvalue{\??im\margincontenttag\c!align}] + [ \v!yes=>\let\margincontentalign#1, + \v!no=>\let\margincontentalign\v!normal, + \v!inner=>\let\margincontentalign#1, + \v!outer=>\let\margincontentalign#2, + \v!left=>\let\margincontentalign\v!left, + \v!middle=>\let\margincontentalign\v!middle, + \v!right=>\let\margincontentalign\v!right]% + \doifvaluesomething{\??im\margincontenttag\c!align} % watch {} around set + {\edef\margincontentalign{{\getvalue{\??im\margincontenttag\c!align},\margincontentalign}}}% + % + \expanded{\getparameters[\??im\margincontenttag][\c!align=\margincontentalign]}% + % + \edef\margincontentstrut{\getvalue{\??im\margincontenttag\c!strut}}% + \savestrut % + \setbox\scratchbox\vbox\localframed + [\??im\margincontenttag] + [\c!strut=\v!no,\c!offset=\v!overlay] % strut handled internally + {\decrement\margincontentlines + \dorecurse\margincontentlines{\savedstrut\endgraf\nointerlineskip}% ! savedstrut + \@@imbefore + \dostartattributes{\??im\margincontenttag}\c!style\c!color\empty + \dosetupstrut[\margincontentstrut]% was: \setstrut % yes or no + \begstrut#3\endstrut\endgraf + \xdef\margincontentstrutheight{\the\strutht}% so that it's known outside the framed + \dostopattributes + \@@imafter}% + \global \naturalmargincontentheight\ht\scratchbox + \global\advance\naturalmargincontentheight\dp\scratchbox + \doif\@@imstack\v!yes + {\def\overlappingmargin{-20\scaledpoint}% test value, maybe .25\strutboxdp, maybe configurable + \setbox\scratchbox\vbox{\stackeddown\vbox{\box\scratchbox}}}% new + \ht\scratchbox\strutht + \dp\scratchbox\strutdp % nieuw + \box\scratchbox + \egroup} + +%D The stacker permits constructs like: +%D +%D \starttyping +%D \setupinmargin[stack=yes] +%D +%D \inleft{test 1}test\break +%D \inleft{test 2}test\break +%D \inleft{test 1} +%D \input tufte +%D \inleft{test 1} +%D \inleft{test 2} +%D \inleft{test 3} +%D \input tufte +%D \inleft{test 1} +%D \inleft{test 2\endgraf test 3} +%D \inleft{test 4} +%D \input tufte +%D \inleft{test 1} +%D \inleft{test 2\endgraf test 3} +%D \inleft{test 4\endgraf test 5\endgraf test 6} +%D \inleft{test 7\endgraf test 8\endgraf test 9} +%D \input tufte +%D \stoptyping + +%D This approach permits us to implement a better mechanism +%D later. We need the \type {\graphicvadjust} in order to +%D handle: +%D +%D \starttyping +%D \inleft{test} {\red \dorecurse{40}{test }\par} +%D {\red \inleft{test} \dorecurse{40}{test }\par} +%D \stoptyping +%D +%D The outer margin color is either black or color set as +%D main text color. + +\newif\ifrightmargin % documenteren + +\ifx\dopositionmarginbox\undefined + \def\dopositionmarginbox#1{\graphicvadjust{\box#1}} +\fi + +% watch out, margin dimensions are swapped locally (\swapmargins) + +% with \margincontentmethod one can control pagebreaks +% +% 0 no break +% 1 each entry is one line +% 2 only natural height +% 3 also stack height + +\chardef\margincontentmethod \plusthree % beware: 1 = old method +\chardef\marginpagecheckmethod\plusone + +\def\margincontentextralines{1} % old method, play safe +\def\nofmargincontentlines {0} + +\def\doplacemargintext#1#2#3#4% + {\dontcomplain + \strut + \doifsomething{#1} + {\def\margincontenttag{#1}}% + \doifinsetelse{\margincontenttag}{\v!left,\v!right} % ugly hack + {\let \margincontentdistance \empty % signal + \let \margincontenthoffset \zeropoint} + {\edef\margincontentdistance{\executeifdefined{\??im\margincontenttag\c!distance }\empty }% signal + \edef\margincontenthoffset {\executeifdefined{\??im\margincontenttag\c!hoffset }\zeropoint}}% + \edef\margincontentlines {\executeifdefined{\??im\margincontenttag\c!line }\plusone }% + \edef\margincontentseparator {\executeifdefined{\??im\margincontenttag\c!separator}\donothing}% + \setbox\scratchbox\hbox{#4}% % todo: make sure that color stack works + \ifcase\margincontentmethod + \scratchdimen\zeropoint + \or % old method + \scratchdimen\ht\scratchbox + \advance\scratchdimen\dp\scratchbox + \or + \scratchdimen\naturalmargincontentheight + \or + \scratchdimen\naturalmargincontentheight + \ifx\laststackvmove\undefined\else\global\advance\scratchdimen\laststackvmove\fi + \fi + \ifdim\scratchdimen>\margincontentheight + \global\margincontentheight\scratchdimen + \fi + \setbox\scratchbox\hbox + {#2{\hskip#3\strut + \ifcase\margincontentdisplacement + % normal, move strutheight up + \scratchdimen\strutdp + \advance\scratchdimen \margincontentstrutheight + \advance\scratchdimen -\strutht + \raise\scratchdimen + \or + % low, obey vadjust + \fi + \box\scratchbox}}% + \ht\scratchbox\zeropoint + \dp\scratchbox\zeropoint + \gdef\margincontentstrutheight{\the\strutht}% + %\graphicvadjust{\box\scratchbox}} % fails in high math lines, let it be + %\hbox{\lower\strutdp\box\scratchbox}} % alas, wrong lapping, therefore useless + \dopositionmarginbox\scratchbox} + +% \def\domarginblockskip#1% +% {\hskip\margincontenthoffset +% \hskip\compensatedinnermakeupmargin\relax +% \doifelsenothing\margincontentdistance +% {\hskip\getvalue{\??im#1\c!distance}} +% {\hskip\margincontentdistance}% +% \relax} + +\def\domarginblockskip#1% + {\doifelsenothing\margincontentdistance + {\hskip\dimexpr + +\margincontenthoffset + +\compensatedinnermakeupmargin + +\csname\??im#1\c!distance\endcsname + \relax} + {\dimexpr + +\margincontenthoffset + +\compensatedinnermakeupmargin + +\margincontentdistance + \relax}% + \relax} + +\def\doleftmarginblock#1#2% + {\doplacemargintext{#1}\llap\zeropoint + {\llap{\placemargincontentseparator}% + \makemargintextblock\v!left\v!right{#2}% + \domarginblockskip\v!left}} + +\def\dorightmarginblock#1#2% + {\doplacemargintext{#1}\rlap\hsize + {\hskip\textwidth\hskip-\hsize % new: hsize correction + \domarginblockskip\v!right + \makemargintextblock\v!right\v!left{#2}% + \rlap{\placemargincontentseparator}}} + +\def\placemargincontentseparator + {\ifnum\margincontentlevel>\zerocount + \ifx\margincontentseparator\empty\else + \bgroup + \scratchdimen\margincontentlines\lineheight + \advance\scratchdimen -\lineheight + \lower\scratchdimen\hbox{\margincontentseparator}% + \egroup + \fi + \fi} + +\newbox\marginconstructbox + +\def\doinmarginswapped#1#2#3#4% + {\iffirstsidefloatparagraph\nowhitespace\fi % zo laat mogelijk + \setbox\marginconstructbox\hbox\bgroup % prevents page break in the middle of construction + \startsignalrightpage + \doifswappedrightpageelse + {\rightmargintrue #2} + {\rightmarginfalse#1} + {#3}% setups + {#4}% content + \stopsignalrightpage + \egroup + \unhbox\marginconstructbox} + +% history made this a bit complicated, the +/- was needed before +% we had enough mem/hash to do the page correction + +\edef\inmargintaglist{+,-,\v!low,\v!left,\v!right,\v!inner,\v!outer} + +% the old one: +% +% \def\doinmargin[#1][#2][#3][#4][#5]% #6 #7 +% {\doifcommonelse{+,-,\v!laag}{#4} +% {\dodoinmargin[#1][#2][#3][#4][#5]} +% {\dodoinmargin[#1][#2][#3][][#4]}} +% +% an alternative: +% +% \letvalue{\??im\v!laag\c!offset}\empty +% \letvalue{\??im +\c!offset}\empty +% \letvalue{\??im -\c!offset}\empty +% +% \def\doinmargin[#1][#2][#3][#4][#5]% #6 #7 +% {\doifnumberelse{#4} +% {\dodoinmargin[#1][#2][#3][#4][#5]} +% {\doifdefinedelse{\??im#4\c!offset} +% {\dodoinmargin[#1][#2][#3][#4][#5]} +% {\dodoinmargin[#1][#2][#3][][#4]}}} +% +% the problem is that we need to keep downward compatibility +% with respect to the first argument thing a reference or a +% directive; the alternative is to force users to pass a +% directive along with a reference; anyhow, as long as one +% does not use references that have the same name as a +% directive we can use the (slow) alternative + +\def\doinmargin[#1][#2][#3][#4][#5]% #6 #7 + {\expanded{\doifinsetelse{#4}{\inmargintaglist}} + {\dodoinmargin[#1][#2][#3][#4][#5]} + {\dodoinmargin[#1][#2][#3][][#4]}} + +\def\defineinmargin + {\doquadrupleempty\dodefineinmargin} + +\def\dodefineinmargin[#1][#2][#3][#4]% + {\doifassignmentelse{#4} + {\setupinmargin[#1][#4]% + \setvalue{#1}{\indentation\doquintupleempty\doinmargin[#2][#3][#1]}} + {\setvalue{#1}{\indentation\doquintupleempty\doinmargin[#2][#3][#4]}}} + +\defineinmargin [inleft] [\v!left] [\v!normal] % takes left settings +\defineinmargin [inright] [\v!right] [\v!normal] % takes right settings +\defineinmargin [ininner] [\v!inner] [\v!normal] % takes left/right settings +\defineinmargin [inouter] [\v!outer] [\v!normal] % takes left/right settings +\defineinmargin [inmargin] [\@@imlocation] [\v!normal] % takes left/right settings +\defineinmargin [inother] [\@@imlocation] [\v!reverse] % takes left/right settings + +\def\inothermargin{\inother} + +%D This permits definitions like: +%D +%D \starttyping +%D \defineinmargin [SomePlace] [inner] [normal] [distance=1cm] +%D \defineinmargin [SomePlace] [inner] [normal] [SomePlace] \setupinmargin[SomePlace][distance=1cm] +%D \defineinmargin [MyPlace] [inner] [normal] [SomePlace] +%D \defineinmargin [YourPlace] [inner] [normal] [SomePlace] +%D \stoptyping +%D +%D A torture test: +%D +%D \starttyping +%D \startbuffer +%D \inleft {\TestLine{red} {l}} test test test \par +%D \inright {\TestLine{green} {r}} test test test \par +%D \inmargin {\TestLine{blue} {m}} test test test \par +%D \inothermargin{\TestLine{yellow} {x}} test test test \par +%D \ininner {\TestLine{cyan} {i}} test test test \par +%D \inouter {\TestLine{magenta}{o}} test test test \par +%D \stopbuffer +%D +%D \dorecurse{80}\getbuffer \page +%D \stoptyping +%D +%D and +%D +%D \starttyping +%D \defineinmargin [InOuterA] [outer] [normal] [distance=0cm] +%D \defineinmargin [InOuterB] [outer] [normal] [distance=1cm] +%D \defineinmargin [InOuterC] [outer] [normal] [distance=2cm,line=2] +%D +%D \startbuffer +%D \InOuterA{\TestLine{red} {A}} test test test \par +%D \InOuterB{\TestLine{green}{B}} test test test \par +%D \InOuterC{\TestLine{blue} {C}} test test test \par +%D \stopbuffer +%D +%D \dorecurse{80}\getbuffer \page +%D +%D \dorecurse{10}{\inleft {one} test \inleft {two} test } \page +%D +%D \start +%D \margintext {one} \margintext {two} \input thuan \par +%D \setupinmargin[1][line=3,distance=1cm] +%D \margintext [1]{one} +%D \margintext [2]{two} +%D \input thuan \page +%D \stop +%D +%D \setupinmargin[3][location=inner,distance=1cm] +%D \setupinmargin[4][location=outer,distance=2cm] +%D +%D % \setupinmargin[left] [line=2] +%D % \setupinmargin[right][line=2] +%D +%D \dorecurse +%D {10} +%D {\margintext {\kern3cm\TestLine{blue}{none}} +%D \margintext[3] {\TestLine{darkgray}{3}} +%D \margintext[4] {\TestLine{darkgray}{4}} +%D \margintext[left] {\TestLine{red} {left}} +%D \margintext[right]{\TestLine{green} {right}} +%D \margintext[inner]{\TestLine{cyan} {inner}} +%D \margintext[outer]{\TestLine{magenta} {outer}} +%D \input thuan \endgraf} +%D +%D \dorecurse{10}{\margintext{test\\test\\test} \input thuan \endgraf} +%D \stoptyping + +% Test case: +% +% \setuppagenumbering[alternative=doublesided] \setupwhitespace[medium] +% +% \placefigure[right]{}{\externalfigure[dummy][width=2cm]} +% \input tufte \inothermargin{test} \input tufte + +% \def\dodoinmargin[#1][#2][#3][#4][#5]#6% +% {\bgroup +% \forgetall % otherwise sidefloat problems, added 2005/07/20, maybe dangerous +% \postponenotes % group is (somehow) needed +% \doifinsetelse\v!low{#4} +% {\chardef\margincontentdisplacement\plusone} +% {\chardef\margincontentdisplacement\zerocount}% +% \doif\v!reverse{#2} +% {\swapmacros\dorightmarginblock\doleftmarginblock}% +% \processaction +% [#1] +% [ \v!left=>\let\next\doleftmarginblock, % no swapping +% \v!right=>\let\next\dorightmarginblock, % no swapping +% \v!inner=>\def\next{\doinmarginswapped\dorightmarginblock\doleftmarginblock }, +% \v!outer=>\def\next{\doinmarginswapped\doleftmarginblock \dorightmarginblock}, +% \s!unknown=>\ifdoublesided +% \doifcommonelse{+,-}{#4} +% {\def\next{\doinmarginswapped\dorightmarginblock\doleftmarginblock }} +% {\def\next{\doinmarginswapped\doleftmarginblock \dorightmarginblock}}% +% \else +% \let\next\doleftmarginblock +% \fi]% +% \next{#3}{#6}% +% \rawpagereference\s!mar{#5}% naar binnen ! ! ! ! +% \flushnotes +% \egroup % don't forget the group +% \ignorespaces} + +% test first +% +% setupsystem[random=1235] +% +% \setupinmargin[left][sidemethod=3] +% \dorecurse{10}{test \fakewords{20}{40} test \inleft{test\\test} test \fakewords{20}{40} \par} +% \page +% \setupinmargin[left][sidemethod=4] +% \dorecurse{40}{test \fakewords{50}{80} test \inleft{test\\test} \par} +% \page + +\def\dodoinmargin[#1][#2][#3][#4][#5]#6% + {\bgroup +% \tracingall + % old stuff, a bit tricky, but now interfaced + \edef\currentmargincontent{#1}% + \chardef\marginrepositionmethod\executeifdefined{\??im\currentmargincontent\c!sidemethod }\plusone + \chardef\margincontentmethod \executeifdefined{\??im\currentmargincontent\c!textmethod }\plusthree + \chardef\marginpagecheckmethod \executeifdefined{\??im\currentmargincontent\c!splitmethod}\plusone + % so far + \forgetall % otherwise sidefloat problems, added 2005/07/20, maybe dangerous + \postponenotes % group is (somehow) needed + \doifinsetelse\v!low{#4} + {\chardef\margincontentdisplacement\plusone} + {\chardef\margincontentdisplacement\zerocount}% + \doif\v!reverse{#2} + {\swapmacros\dorightmarginblock\doleftmarginblock}% + \processaction + [#1] + [ \v!left=>\let\next\doleftmarginblock, % no swapping + \v!right=>\let\next\dorightmarginblock, % no swapping + \v!inner=>\def\next{\doinmarginswapped\dorightmarginblock\doleftmarginblock }, + \v!outer=>\def\next{\doinmarginswapped\doleftmarginblock \dorightmarginblock}, + \s!unknown=>\ifdoublesided + \doifcommonelse{+,-}{#4} + {\def\next{\doinmarginswapped\dorightmarginblock\doleftmarginblock }} + {\def\next{\doinmarginswapped\doleftmarginblock \dorightmarginblock}}% + \else + \let\next\doleftmarginblock + \fi]% + \next{#3}{#6}% + \rawpagereference\s!mar{#5}% naar binnen ! ! ! ! + \flushnotes + \egroup % don't forget the group + \ignorespaces} + +% dit zijn voorlopig lokale commando's / vervallen +% +% \def\woordinmarge {\indentation\doquintupleempty\doinmargin[\@@implaats][\inleftmargin][\inrightmarge]} +% +% \def\woordinlinker {\inleftmargin } % vervallen +% \def\woordinrechter{\inrechtermarge} % vervallen + +% Some day: \definemarking[\v!margetitel] + +%D Now come the margin text collectors. The collected content is +%D flushed at every paragraph by the following macro. Note for +%D myself: here the location (plaats) is no longer a tag (number). + +% gone: \def\doflushmargincontent{\doinmargin[\@@implaats][\v!normaal][]} % + [#1][#2]{#3}} + +%D These are now all the same (long ago they had different +%D implementations, somewhere in Sork time if I remember +%D right). + +\def\margintext {\dodoubleempty\domargincontent} +\def\marginword {\margintext} +\def\margintitle{\margintext} % txt mark as well + +\newtoks\collectedmargintexts % so .. delayed! +\chardef\margintextcollected \zerocount + +\def\domargincontent[#1][#2]#3% we used to check for #2/#1 being number, no longer now + {\global\chardef\margintextcollected\plusone + \edef\margincontenttag{#1}% + \ifx\margincontenttag\empty + \global\advance\margincontentlevel\plusone + \edef\margincontenttag{\number\margincontentlevel}% + \fi + \checkinmargin[\margincontenttag]% + \doglobal \appendetoks + \noexpand \checkinmargin[\margincontenttag]% + \noexpand \doinmargin[\executeifdefined{\??im\margincontenttag\c!location}\@@imlocation][\v!normal][\margincontenttag][\margincontenttag][#2]% + \to \collectedmargintexts + \doglobal \appendtoks + {#3}% + \to \collectedmargintexts} + +\let\restoreinterlinepenalty\relax + +\def\flushmargincontents % plural + {\restoreinterlinepenalty % here? + \ifcase\margintextcollected\else % called quite often, so we + \expandafter\doflushmargincontents % speed up the \fi scan by + \fi} % using a \do.. + +\def\doflushmargincontents % links + rechts + {\bgroup + \forgetall + \global\margincontentheight\zeropoint + \startsignalrightpage + \the\collectedmargintexts + \signalrightpage + \stopsignalrightpage + \resetmargincontent + % dirty tricks + \ifcase\margincontentmethod + \donefalse + \else\ifinsidecolumns % brrrr + \donetrue % how fuzzy + \else\ifdim\margincontentheight>\lineheight\relax + \donetrue % how dirty + \else + \donefalse % how needed + \fi\fi\fi + \savemargincontentlines + \ifdone + \advance\margincontentheight \margincontentextralines\lineheight + \ifdim\pagegoal>\pagetotal + \bgroup % preserve \margincontentheight + \advance\margincontentheight \pagetotal + \ifdim\margincontentheight>\pagegoal + \egroup + \ifcase\marginpagecheckmethod + % disabled + \or + \setmargincontentpenalties + \or + % potentially dangerous, maybe better a \goodbreak; the problem is that + % there can be a penalty there, which we then overload and we also introduce + % nasty side effects, so, we drop this option + % \vadjust pre {\page}% + \fi + \else + \egroup + \fi + \fi + \else % We need the above because interlinepenalties overrule vadjusted \nobreaks. + % a bit dangerous + \vadjust{\nobreak}% + \fi + \egroup} + +\def\setmargincontentpenalties + {\getnoflines\margincontentheight + \keeplinestogether\noflines} + +\def\savemargincontentlines + {\bgroup + \advance\margincontentheight \margincontentextralines\lineheight % 1 by default + \getnoflines\margincontentheight + \xdef\nofmargincontentlines{\the\noflines}% + \egroup} + +\def\fillupmargincontentlines % etex ! ! ! + {\endgraf + \begingroup + \scratchcounter\numexpr\nofmargincontentlines-\prevgraf\relax\relax + \ifnum\scratchcounter>\zerocount + \forgetall\dorecurse\scratchcounter{\nobreak\crlf}% + \fi + \endgroup} + +% Yet undocumented, for a manual flush in for instance headers. + +\def\resetmargincontent + {\global\margincontentlevel\zerocount + \global\chardef\margintextcollected\zerocount + \global\collectedmargintexts\emptytoks} + +% \def\placemargincontent +% {\ifcase\margintextcollected\else +% \bgroup +% \chardef\graphicvadjustmode\zerocount +% \doflushmargincontents +% \egroup +% \fi} +% +% font fix: + +\def\placemargincontent + {\ifcase\margintextcollected\else % was level check + \bgroup + \redoconvertfont % !! + \chardef\graphicvadjustmode\zerocount + \doflushmargincontents + \egroup + \fi} + +% For old times sake (i use it in project styles) we provide + +\def\placemargintexts {\placemargincontent} +\def\resetmargetitels {\resetmargincontent} +\def\margewoordpositie{\margewoord} % obsolete, now no longer range + +% but never use them yourself since they may disappear. + +\def\oplinker#1% + {\strut + \graphicvadjust + {\dontcomplain + \setbox\scratchbox\vtop{\forgetall\strut#1}% + \getboxheight\scratchdimen\of\box\scratchbox + \vskip-\scratchdimen % waarom stond hier een \ ? + \box\scratchbox}} + +\setupinmargin + [\c!style=\v!bold, + \c!color=, + \c!strut=\v!auto, + \c!location=\v!both, + \c!align=\v!inner, + \c!stack=\v!no, + \c!before=, + \c!after=] + +\setupinmargin + [\v!left] + [\c!distance=\leftmargindistance, + \c!width=\leftmarginwidth, + %\c!align=\v!left, % no + \c!location=\v!left] + +\setupinmargin + [\v!right] + [\c!distance=\rightmargindistance, + \c!width=\rightmarginwidth, + %\c!align=\v!right, % no + \c!location=\v!right] + +% bonus needed when [inner/outer] is used as tag + +\setupinmargin[\v!inner][\c!location=\v!inner,\c!align=\v!inner] +\setupinmargin[\v!outer][\c!location=\v!outer,\c!align=\v!inner] + +% more efficient (5K less fotmat file) +% +% \letvalue{\??im\v!inner\c!location}\v!inner \letvalue{\??im\v!inner\c!align}\v!inner +% \letvalue{\??im\v!outer\c!location}\v!outer \letvalue{\??im\v!outer\c!align}\v!inner + +\protect \endinput diff --git a/tex/context/base/page-mar.mkiv b/tex/context/base/page-mar.mkiv new file mode 100644 index 000000000..464b4f9bb --- /dev/null +++ b/tex/context/base/page-mar.mkiv @@ -0,0 +1,824 @@ +%D \module +%D [ file=page-mar, % moved here from main-001 +%D version=1997.03.31, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Marginal 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 Support for margin words is one of the reasons for writing +%D \CONTEXT. Over time support for marginal content has been +%D extended en enhanced. Therefore it's always good to watch +%D out for unexpected side effects. + +\writestatus{loading}{ConTeXt Page Macros / Maginal Things} + +\unprotect + +%D There are three categories and their historically grown meaning is +%D as follows: +%D +%D marginlines: these are flushed relative to the start of a line and +%D need to be invoked there. +%D +%D marginwords: these can be issued in the text flow and will migrate +%D sidewards; in spite of the name, it can be a paragraph of text as +%D well, but normally it's words. +%D +%D margintexts: these can be set beforehand and are flushed at the +%D next paragraph of text (of header) +%D +%D While these mechanisms were rather separated, they now are slightly +%D more integrated. Instead of low level instances we now have a mechanism +%D for defining additional ones. + +%D \macros +%D {inleftedge,inleftmargin,inrightmargin,inrightedge} +%D +%D The fast and clean way of putting things in the margin is +%D using \type{\rlap} or \type{\llap}. Unfortunately these +%D macro's don't handle indentation, left and right skips. We +%D therefore embed them in some macro's that (force and) +%D remove the indentation and restore it afterwards. + +\unexpanded\def\definemarginline + {\dodoubleargument\dodefinemarginline} + +\def\dodefinemarginline[#1][#2]% + {\getparameters + [\??im\??im#1] + [\c!location=\v!left, + \c!distance=\zeropoint, + \c!width=\leftmarginwidth, + \c!hoffset=\leftmargindistance, + \c!command=, + #2]% + \setuvalue{#1}{\dohandlemarginline{#1}}} + +\def\marginlineparameter #1{\csname\??im\??im\currentmarginline#1\endcsname} +\def\marginlineexecuter #1#2{\executeifdefined{\??im\??im\currentmarginline#1}{#2}} + +\def\dohandlemarginline#1% #2 + {\def\currentmarginline{#1}% + \csname\s!do\??im\??im\executeifdefined{\??im\??im#1\c!location}\v!left\endcsname{#1}} % {#2} + +\def\doleftmarginline#1#2% #1 is redundant (we can remove it when we group dohandlemarginline; maybe ... + {\pushindentation + \llap + {\def\currentmarginline{#1}% + \postsignalrightpage + \hsize\marginlineparameter\c!width\relax + \marginlineexecuter\c!command\firstofoneargument{#2}\relax + \hskip\dimexpr + +\leftskip + +\compensatedinnermakeupmargin + +\marginlineparameter\c!hoffset + +\marginlineparameter\c!distance + \relax}% + \popindentation + \ignorespaces} + +\def\dorightmarginline#1#2% #1 is redundant + {\pushindentation + \rlap + {\def\currentmarginline{#1}% + \postsignalrightpage + \hskip\dimexpr + +\hsize + -\rightskip + +\compensatedinnermakeupmargin + +\marginlineparameter\c!hoffset + +\marginlineparameter\c!distance + \relax + \hsize\marginlineparameter\c!width + \marginlineexecuter\c!command\firstofoneargument{#2}}% + \popindentation + \ignorespaces} + +\long\def\installmarginlinehandler#1#2{\setvalue{\s!do\??im\??im#1}{#2}} + +\installmarginlinehandler \v!left {\doleftmarginline} +\installmarginlinehandler \v!right {\dorightmarginline} +\installmarginlinehandler \v!inner {\presignalrightpage\doifrightpageelse\doleftmarginline \dorightmarginline} +\installmarginlinehandler \v!outer {\presignalrightpage\doifrightpageelse\dorightmarginline\doleftmarginline } + +\definemarginline[inleftmargin] [\c!location=\v!left, \c!width=\leftmarginwidth, \c!distance=\leftmargindistance, \c!hoffset=\zeropoint] +\definemarginline[inrightmargin][\c!location=\v!right,\c!width=\rightmarginwidth,\c!distance=\rightmargindistance,\c!hoffset=\zeropoint] +\definemarginline[inleftedge] [\c!location=\v!left, \c!width=\leftedgewidth, \c!distance=\leftedgedistance, \c!hoffset=\leftmargintotal] +\definemarginline[inrightedge] [\c!location=\v!right,\c!width=\rightedgewidth, \c!distance=\rightedgedistance, \c!hoffset=\rightmargintotal] + +\definemarginline[inoutermargin][\c!location=\v!outer,\c!width=\outermarginwidth,\c!distance=\outermargindistance,\c!hoffset=\zeropoint] +\definemarginline[ininnermargin][\c!location=\v!inner,\c!width=\innermarginwidth,\c!distance=\innermargindistance,\c!hoffset=\zeropoint] +\definemarginline[inouteredge] [\c!location=\v!outer,\c!width=\outeredgewidth, \c!distance=\outeredgedistance, \c!hoffset=\outermargintotal] +\definemarginline[ininneredge] [\c!location=\v!inner,\c!width=\inneredgewidth, \c!distance=\inneredgedistance, \c!hoffset=\innermargintotal] + +\definemarginline[atleftmargin] [\c!location=\v!left, \c!command=\lrlap,\c!width=\zeropoint,\c!distance=\zeropoint,\c!hoffset=\zeropoint] +\definemarginline[atrightmargin][\c!location=\v!right,\c!command=\rllap,\c!width=\zeropoint,\c!distance=\zeropoint,\c!hoffset=\zeropoint] + +\def\lrlap#1{\llap{\rlap{#1}}} +\def\rllap#1{\rlap{\hskip\hsize\llap{#1}}} + +%D We want to keep things efficient and therefore only handle +%D situations like: +%D +%D \startbuffer +%D \inleftedge {fine} some text \par +%D \strut \inleftmargin {fine} some text \par +%D \noindent \inrightmargin {fine} some text \par +%D \noindent \strut \inrightedge {fine} some text \par +%D \stopbuffer +%D +%D \typebuffer +%D +%D which looks like: +%D +%D \bgroup +%D \getbuffer +%D \parindent 30pt +%D \getbuffer +%D \egroup +%D +%D A torture test: +%D +%D \starttyping +%D \def\TestLine#1#2{\backgroundline[#1]{\strut\white\tttf#2~\recurselevel}} +%D +%D \startbuffer +%D \inleftmargin {\TestLine{red} {lm}} test test test \par +%D \inrightmargin{\TestLine{green} {rm}} test test test \par +%D \inleftedge {\TestLine{red} {le}} test test test \par +%D \inrightedge {\TestLine{green} {re}} test test test \par +%D \inoutermargin{\TestLine{blue} {om}} test test test \par +%D \ininnermargin{\TestLine{yellow}{im}} test test test \par +%D \inouteredge {\TestLine{blue} {oe}} test test test \par +%D \ininneredge {\TestLine{yellow}{ie}} test test test \par +%D \atleftmargin {\TestLine{red} {alm}} \hfill test \par +%D \atrightmargin{\TestLine{green} {arm}} test \hfill \par +%D \stopbuffer +%D +%D \dorecurse{40}\getbuffer \page +%D \stoptyping + +%D New, yet undocumented: +%D +%D used for pascal: +%D +%D \starttyping +%D \index {test} test \index {west} west \index {rest} rest +%D +%D \startnarrower +%D \placeregister[index][alternative=b,command=\atleftmargin] +%D \stopnarrower +%D \stoptyping + +% todo: compensate distance when setuplayout[textwidth=..] +% todo: generalize margin/edge model, now too much duplication + +%D The next bunch of macros looks messy which is due to its +%D multi-purpose character. + +\chardef\margincontentdisplacement \zerocount +\let \margincontentdistance \!!zeropoint +\let \margincontenthoffset \!!zeropoint +\def \margincontentlines {1} +\def \margincontenttag {0} +\let \margincontentseparator \empty +\def \margincontentstrutheight {\strutht} + +\newcount\margincontentlevel +\newdimen\margincontentheight + +\unexpanded\def\setupinmargin + {\dodoubleempty\dosetupinmargin} + +\def\dosetupinmargin[#1][#2]% + {\ifsecondargument + \processcommalist[#1]{\dodosetupinmargin[#2]}% becomes [#2]{##1} + \else + \getparameters[\??im][#1]% + \fi} + +% \def\dodosetupinmargin[#1]#2% [settings]{class} +% {\checkinmargin[#2]% +% \getparameters[\??im#2][#1]} + +\def\dodosetupinmargin[#1]#2% [settings]{class} + {\checkinmargin[#2]% + \getparameters[\??im#2][#1]% + % will become an \everyinmarginsetup thing + \ifcase\executeifdefined{\??im#2\c!sidemethod}{0}\else + \enableparpositions + \fi} + +\def\checkinmargin[#1]% + {\ifcsname\??im#1\c!offset\endcsname\else % this offset is related to framed ! + \addtocommalist{#1}\inmargintaglist + \presetmargintext[#1]% + \fi} + +\def\presetmargintext[#1]% + {\presetlocalframed + [\??im#1]% + \getparameters + [\??im#1] + [\c!frame=\v!off, + \c!offset=\v!overlay, + \c!line=1, + \c!separator=, + \c!width=\v!broad, + \c!distance=, % empty = signal + \c!hoffset=\zeropoint, + \c!style=\@@imstyle, + \c!color=\@@imcolor, + \c!strut=\@@imstrut, + \c!location=\@@imlocation, + \c!align=\@@imalign, + \c!before=\@@imbefore, + \c!after=\@@imafter]} + +\newdimen\naturalmargincontentheight + +\def\makemargintextblock#1#2#3% width l r content + {\bgroup + \forgetall % added, else problems with 'center' and nested itemize + \dontcomplain + \hsize\getvalue{\??im#1\c!width}\relax + \doifnumberelse\margincontenttag + {\ifcase\margincontenttag\relax + \edef\margincontenttag{#1}% first one is setups id as well + \fi} + \donothing + \doifnumberelse\margincontenttag + {\ifnum\margincontenttag>25 % to be translated + \writestatus\m!systems{potential margin stack overflow (\margincontenttag)}% + \fi} + \donothing + % we need to preserve {a,b,c} kind of settings + \let\margincontentalign#1% + \processallactionsinset + [\getvalue{\??im\margincontenttag\c!align}] + [ \v!yes=>\let\margincontentalign#1, + \v!no=>\let\margincontentalign\v!normal, + \v!inner=>\let\margincontentalign#1, + \v!outer=>\let\margincontentalign#2, + \v!left=>\let\margincontentalign\v!left, + \v!middle=>\let\margincontentalign\v!middle, + \v!right=>\let\margincontentalign\v!right]% + \doifvaluesomething{\??im\margincontenttag\c!align} % watch {} around set + {\edef\margincontentalign{{\getvalue{\??im\margincontenttag\c!align},\margincontentalign}}}% + % + \expanded{\getparameters[\??im\margincontenttag][\c!align=\margincontentalign]}% + % + \edef\margincontentstrut{\getvalue{\??im\margincontenttag\c!strut}}% + \savestrut % + \setbox\scratchbox\vbox\localframed + [\??im\margincontenttag] + [\c!strut=\v!no,\c!offset=\v!overlay] % strut handled internally + {\decrement\margincontentlines + \dorecurse\margincontentlines{\savedstrut\endgraf\nointerlineskip}% ! savedstrut + \@@imbefore + \dostartattributes{\??im\margincontenttag}\c!style\c!color\empty + \dosetupstrut[\margincontentstrut]% was: \setstrut % yes or no + \begstrut#3\endstrut\endgraf + \xdef\margincontentstrutheight{\the\strutht}% so that it's known outside the framed + \dostopattributes + \@@imafter}% + \global \naturalmargincontentheight\ht\scratchbox + \global\advance\naturalmargincontentheight\dp\scratchbox + \doif\@@imstack\v!yes + {\def\overlappingmargin{-20\scaledpoint}% test value, maybe .25\strutboxdp, maybe configurable + \setbox\scratchbox\vbox{\stackeddown\vbox{\box\scratchbox}}}% new + \ht\scratchbox\strutht + \dp\scratchbox\strutdp % nieuw + \box\scratchbox + \egroup} + +%D The stacker permits constructs like: +%D +%D \starttyping +%D \setupinmargin[stack=yes] +%D +%D \inleft{test 1}test\break +%D \inleft{test 2}test\break +%D \inleft{test 1} +%D \input tufte +%D \inleft{test 1} +%D \inleft{test 2} +%D \inleft{test 3} +%D \input tufte +%D \inleft{test 1} +%D \inleft{test 2\endgraf test 3} +%D \inleft{test 4} +%D \input tufte +%D \inleft{test 1} +%D \inleft{test 2\endgraf test 3} +%D \inleft{test 4\endgraf test 5\endgraf test 6} +%D \inleft{test 7\endgraf test 8\endgraf test 9} +%D \input tufte +%D \stoptyping + +%D This approach permits us to implement a better mechanism +%D later. We need the \type {\graphicvadjust} in order to +%D handle: +%D +%D \starttyping +%D \inleft{test} {\red \dorecurse{40}{test }\par} +%D {\red \inleft{test} \dorecurse{40}{test }\par} +%D \stoptyping +%D +%D The outer margin color is either black or color set as +%D main text color. + +\newif\ifrightmargin % documenteren + +\ifx\dopositionmarginbox\undefined + \def\dopositionmarginbox#1{\graphicvadjust{\box#1}} +\fi + +% watch out, margin dimensions are swapped locally (\swapmargins) + +% with \margincontentmethod one can control pagebreaks +% +% 0 no break +% 1 each entry is one line +% 2 only natural height +% 3 also stack height + +\chardef\margincontentmethod \plusthree % beware: 1 = old method +\chardef\marginpagecheckmethod\plusone + +\def\margincontentextralines{1} % old method, play safe +\def\nofmargincontentlines {0} + +\def\doplacemargintext#1#2#3#4% + {\dontcomplain + \strut + \doifsomething{#1} + {\def\margincontenttag{#1}}% + \doifinsetelse{\margincontenttag}{\v!left,\v!right} % ugly hack + {\let \margincontentdistance \empty % signal + \let \margincontenthoffset \zeropoint} + {\edef\margincontentdistance{\executeifdefined{\??im\margincontenttag\c!distance }\empty }% signal + \edef\margincontenthoffset {\executeifdefined{\??im\margincontenttag\c!hoffset }\zeropoint}}% + \edef\margincontentlines {\executeifdefined{\??im\margincontenttag\c!line }\plusone }% + \edef\margincontentseparator {\executeifdefined{\??im\margincontenttag\c!separator}\donothing}% + \setbox\scratchbox\hbox{#4}% % todo: make sure that color stack works + \ifcase\margincontentmethod + \scratchdimen\zeropoint + \or % old method + \scratchdimen\ht\scratchbox + \advance\scratchdimen\dp\scratchbox + \or + \scratchdimen\naturalmargincontentheight + \or + \scratchdimen\naturalmargincontentheight + \ifx\laststackvmove\undefined\else\global\advance\scratchdimen\laststackvmove\fi + \fi + \ifdim\scratchdimen>\margincontentheight + \global\margincontentheight\scratchdimen + \fi + \setbox\scratchbox\hbox + {#2{\hskip#3\strut + \ifcase\margincontentdisplacement + % normal, move strutheight up + \scratchdimen\strutdp + \advance\scratchdimen \margincontentstrutheight + \advance\scratchdimen -\strutht + \raise\scratchdimen + \or + % low, obey vadjust + \fi + \box\scratchbox}}% + \ht\scratchbox\zeropoint + \dp\scratchbox\zeropoint + \gdef\margincontentstrutheight{\the\strutht}% + %\graphicvadjust{\box\scratchbox}} % fails in high math lines, let it be + %\hbox{\lower\strutdp\box\scratchbox}} % alas, wrong lapping, therefore useless + \dopositionmarginbox\scratchbox} + +% \def\domarginblockskip#1% +% {\hskip\margincontenthoffset +% \hskip\compensatedinnermakeupmargin\relax +% \doifelsenothing\margincontentdistance +% {\hskip\getvalue{\??im#1\c!distance}} +% {\hskip\margincontentdistance}% +% \relax} + +\def\domarginblockskip#1% + {\doifelsenothing\margincontentdistance + {\hskip\dimexpr + +\margincontenthoffset + +\compensatedinnermakeupmargin + +\csname\??im#1\c!distance\endcsname + \relax} + {\dimexpr + +\margincontenthoffset + +\compensatedinnermakeupmargin + +\margincontentdistance + \relax}% + \relax} + +\def\doleftmarginblock#1#2% + {\doplacemargintext{#1}\llap\zeropoint + {\llap{\placemargincontentseparator}% + \makemargintextblock\v!left\v!right{#2}% + \domarginblockskip\v!left}} + +\def\dorightmarginblock#1#2% + {\doplacemargintext{#1}\rlap\hsize + {\hskip\textwidth\hskip-\hsize % new: hsize correction + \domarginblockskip\v!right + \makemargintextblock\v!right\v!left{#2}% + \rlap{\placemargincontentseparator}}} + +\unexpanded\def\placemargincontentseparator + {\ifnum\margincontentlevel>\zerocount + \ifx\margincontentseparator\empty\else + \bgroup + \scratchdimen\margincontentlines\lineheight + \advance\scratchdimen -\lineheight + \lower\scratchdimen\hbox{\margincontentseparator}% + \egroup + \fi + \fi} + +\newbox\marginconstructbox + +\def\doinmarginswapped#1#2#3#4% + {\iffirstsidefloatparagraph\nowhitespace\fi % zo laat mogelijk + \setbox\marginconstructbox\hbox\bgroup % prevents page break in the middle of construction + \startsignalrightpage + \doifswappedrightpageelse + {\rightmargintrue #2} + {\rightmarginfalse#1} + {#3}% setups + {#4}% content + \stopsignalrightpage + \egroup + \unhbox\marginconstructbox} + +% history made this a bit complicated, the +/- was needed before +% we had enough mem/hash to do the page correction + +\edef\inmargintaglist{+,-,\v!low,\v!left,\v!right,\v!inner,\v!outer} + +% the old one: +% +% \def\doinmargin[#1][#2][#3][#4][#5]% #6 #7 +% {\doifcommonelse{+,-,\v!laag}{#4} +% {\dodoinmargin[#1][#2][#3][#4][#5]} +% {\dodoinmargin[#1][#2][#3][][#4]}} +% +% an alternative: +% +% \letvalue{\??im\v!laag\c!offset}\empty +% \letvalue{\??im +\c!offset}\empty +% \letvalue{\??im -\c!offset}\empty +% +% \def\doinmargin[#1][#2][#3][#4][#5]% #6 #7 +% {\doifnumberelse{#4} +% {\dodoinmargin[#1][#2][#3][#4][#5]} +% {\doifdefinedelse{\??im#4\c!offset} +% {\dodoinmargin[#1][#2][#3][#4][#5]} +% {\dodoinmargin[#1][#2][#3][][#4]}}} +% +% the problem is that we need to keep downward compatibility +% with respect to the first argument thing a reference or a +% directive; the alternative is to force users to pass a +% directive along with a reference; anyhow, as long as one +% does not use references that have the same name as a +% directive we can use the (slow) alternative + +\def\doinmargin[#1][#2][#3][#4][#5]% #6 #7 + {\expanded{\doifinsetelse{#4}{\inmargintaglist}} + {\dodoinmargin[#1][#2][#3][#4][#5]} + {\dodoinmargin[#1][#2][#3][][#4]}} + +\unexpanded\def\defineinmargin + {\doquadrupleempty\dodefineinmargin} + +\def\dodefineinmargin[#1][#2][#3][#4]% + {\doifassignmentelse{#4} + {\setupinmargin[#1][#4]% + \setvalue{#1}{\indentation\doquintupleempty\doinmargin[#2][#3][#1]}} + {\setvalue{#1}{\indentation\doquintupleempty\doinmargin[#2][#3][#4]}}} + +\defineinmargin [inleft] [\v!left] [\v!normal] % takes left settings +\defineinmargin [inright] [\v!right] [\v!normal] % takes right settings +\defineinmargin [ininner] [\v!inner] [\v!normal] % takes left/right settings +\defineinmargin [inouter] [\v!outer] [\v!normal] % takes left/right settings +\defineinmargin [inmargin] [\@@imlocation] [\v!normal] % takes left/right settings +\defineinmargin [inother] [\@@imlocation] [\v!reverse] % takes left/right settings + +\def\inothermargin{\inother} + +%D This permits definitions like: +%D +%D \starttyping +%D \defineinmargin [SomePlace] [inner] [normal] [distance=1cm] +%D \defineinmargin [SomePlace] [inner] [normal] [SomePlace] \setupinmargin[SomePlace][distance=1cm] +%D \defineinmargin [MyPlace] [inner] [normal] [SomePlace] +%D \defineinmargin [YourPlace] [inner] [normal] [SomePlace] +%D \stoptyping +%D +%D A torture test: +%D +%D \starttyping +%D \startbuffer +%D \inleft {\TestLine{red} {l}} test test test \par +%D \inright {\TestLine{green} {r}} test test test \par +%D \inmargin {\TestLine{blue} {m}} test test test \par +%D \inothermargin{\TestLine{yellow} {x}} test test test \par +%D \ininner {\TestLine{cyan} {i}} test test test \par +%D \inouter {\TestLine{magenta}{o}} test test test \par +%D \stopbuffer +%D +%D \dorecurse{80}\getbuffer \page +%D \stoptyping +%D +%D and +%D +%D \starttyping +%D \defineinmargin [InOuterA] [outer] [normal] [distance=0cm] +%D \defineinmargin [InOuterB] [outer] [normal] [distance=1cm] +%D \defineinmargin [InOuterC] [outer] [normal] [distance=2cm,line=2] +%D +%D \startbuffer +%D \InOuterA{\TestLine{red} {A}} test test test \par +%D \InOuterB{\TestLine{green}{B}} test test test \par +%D \InOuterC{\TestLine{blue} {C}} test test test \par +%D \stopbuffer +%D +%D \dorecurse{80}\getbuffer \page +%D +%D \dorecurse{10}{\inleft {one} test \inleft {two} test } \page +%D +%D \start +%D \margintext {one} \margintext {two} \input thuan \par +%D \setupinmargin[1][line=3,distance=1cm] +%D \margintext [1]{one} +%D \margintext [2]{two} +%D \input thuan \page +%D \stop +%D +%D \setupinmargin[3][location=inner,distance=1cm] +%D \setupinmargin[4][location=outer,distance=2cm] +%D +%D % \setupinmargin[left] [line=2] +%D % \setupinmargin[right][line=2] +%D +%D \dorecurse +%D {10} +%D {\margintext {\kern3cm\TestLine{blue}{none}} +%D \margintext[3] {\TestLine{darkgray}{3}} +%D \margintext[4] {\TestLine{darkgray}{4}} +%D \margintext[left] {\TestLine{red} {left}} +%D \margintext[right]{\TestLine{green} {right}} +%D \margintext[inner]{\TestLine{cyan} {inner}} +%D \margintext[outer]{\TestLine{magenta} {outer}} +%D \input thuan \endgraf} +%D +%D \dorecurse{10}{\margintext{test\\test\\test} \input thuan \endgraf} +%D \stoptyping + +% Test case: +% +% \setuppagenumbering[alternative=doublesided] \setupwhitespace[medium] +% +% \placefigure[right]{}{\externalfigure[dummy][width=2cm]} +% \input tufte \inothermargin{test} \input tufte + +% test first +% +% setupsystem[random=1235] +% +% \setupinmargin[left][sidemethod=3] +% \dorecurse{10}{test \fakewords{20}{40} test \inleft{test\\test} test \fakewords{20}{40} \par} +% \page +% \setupinmargin[left][sidemethod=4] +% \dorecurse{40}{test \fakewords{50}{80} test \inleft{test\\test} \par} +% \page + +\def\dodoinmargin[#1][#2][#3][#4][#5]#6% + {\bgroup + % old stuff, a bit tricky, but now interfaced + \edef\currentmargincontent{#1}% + \chardef\marginrepositionmethod\executeifdefined{\??im\currentmargincontent\c!sidemethod }\plusone + \chardef\margincontentmethod \executeifdefined{\??im\currentmargincontent\c!textmethod }\plusthree + \chardef\marginpagecheckmethod \executeifdefined{\??im\currentmargincontent\c!splitmethod}\plusone + % so far + \forgetall % otherwise sidefloat problems, added 2005/07/20, maybe dangerous + \postponenotes % group is (somehow) needed + \doifinsetelse\v!low{#4} + {\chardef\margincontentdisplacement\plusone} + {\chardef\margincontentdisplacement\zerocount}% + \doif\v!reverse{#2} + {\swapmacros\dorightmarginblock\doleftmarginblock}% + \processaction + [#1] + [ \v!left=>\let\next\doleftmarginblock, % no swapping + \v!right=>\let\next\dorightmarginblock, % no swapping + \v!inner=>\def\next{\doinmarginswapped\dorightmarginblock\doleftmarginblock }, + \v!outer=>\def\next{\doinmarginswapped\doleftmarginblock \dorightmarginblock}, + \s!unknown=>\ifdoublesided + \doifcommonelse{+,-}{#4} + {\def\next{\doinmarginswapped\dorightmarginblock\doleftmarginblock }} + {\def\next{\doinmarginswapped\doleftmarginblock \dorightmarginblock}}% + \else + \let\next\doleftmarginblock + \fi]% + \next{#3}{#6}% + \pagereference[#5]% naar binnen ! ! ! ! + \flushnotes + \egroup % don't forget the group + \ignorespaces} + +% dit zijn voorlopig lokale commando's / vervallen +% +% \def\woordinmarge {\indentation\doquintupleempty\doinmargin[\@@implaats][\inleftmargin][\inrightmarge]} +% +% \def\woordinlinker {\inleftmargin } % vervallen +% \def\woordinrechter{\inrechtermarge} % vervallen + +% Some day: \definemarking[\v!margetitel] + +%D Now come the margin text collectors. The collected content is +%D flushed at every paragraph by the following macro. Note for +%D myself: here the location (plaats) is no longer a tag (number). + +%D These are now all the same (long ago they had different +%D implementations, somewhere in Sork time if I remember +%D right). + +\def\margintext {\dodoubleempty\domargincontent} +\def\marginword {\margintext} +\def\margintitle{\margintext} % txt mark as well + +\newtoks\collectedmargintexts % so .. delayed! +\chardef\margintextcollected \zerocount + +\def\domargincontent[#1][#2]#3% we used to check for #2/#1 being number, no longer now + {\global\chardef\margintextcollected\plusone + \global\let\flushmargincontents\doflushmargincontents + \edef\margincontenttag{#1}% + \ifx\margincontenttag\empty + \global\advance\margincontentlevel\plusone + \edef\margincontenttag{\number\margincontentlevel}% + \fi + \checkinmargin[\margincontenttag]% + \doglobal \appendetoks + \noexpand \checkinmargin[\margincontenttag]% + \noexpand \doinmargin[\executeifdefined{\??im\margincontenttag\c!location}\@@imlocation][\v!normal][\margincontenttag][\margincontenttag][#2]% + \to \collectedmargintexts + \doglobal \appendtoks + {#3}% + \to \collectedmargintexts} + +\def\doflushmargincontents % plural + {\ifcase\margintextcollected\else + \expandafter\flushmargincontentsindeed + \fi} + +\let\flushmargincontents\relax + +\def\flushmargincontentsindeed % links + rechts + {\bgroup + \forgetall + \global\margincontentheight\zeropoint + \startsignalrightpage + \the\collectedmargintexts + \signalrightpage + \stopsignalrightpage + \resetmargincontent + % dirty tricks + \ifcase\margincontentmethod + \donefalse + \else\ifinsidecolumns % brrrr + \donetrue % how fuzzy + \else\ifdim\margincontentheight>\lineheight\relax + \donetrue % how dirty + \else + \donefalse % how needed + \fi\fi\fi + \savemargincontentlines + \ifdone + \advance\margincontentheight \margincontentextralines\lineheight + \ifdim\pagegoal>\pagetotal + \bgroup % preserve \margincontentheight + \advance\margincontentheight \pagetotal + \ifdim\margincontentheight>\pagegoal + \egroup + \ifcase\marginpagecheckmethod + % disabled + \or + \setmargincontentpenalties + \or + % potentially dangerous, maybe better a \goodbreak; the problem is that + % there can be a penalty there, which we then overload and we also introduce + % nasty side effects, so, we drop this option + % \vadjust pre {\page}% + \fi + \else + \egroup + \fi + \fi + \else % We need the above because interlinepenalties overrule vadjusted \nobreaks. + % a bit dangerous + \vadjust{\nobreak}% + \fi + \global\let\flushmargincontents\relax + \egroup} + +\def\setmargincontentpenalties + {\getnoflines\margincontentheight + \keeplinestogether\noflines} + +\def\savemargincontentlines + {\bgroup + \advance\margincontentheight \margincontentextralines\lineheight % 1 by default + \getnoflines\margincontentheight + \xdef\nofmargincontentlines{\the\noflines}% + \egroup} + +\def\fillupmargincontentlines % etex ! ! ! + {\endgraf + \begingroup + \scratchcounter\numexpr\nofmargincontentlines-\prevgraf\relax\relax + \ifnum\scratchcounter>\zerocount + \forgetall\dorecurse\scratchcounter{\nobreak\crlf}% + \fi + \endgroup} + +% Yet undocumented, for a manual flush in for instance headers. + +\def\resetmargincontent + {\global\margincontentlevel\zerocount + \global\chardef\margintextcollected\zerocount + \global\collectedmargintexts\emptytoks} + +\unexpanded\def\placemargincontent + {\ifcase\margintextcollected\else % was level check + \bgroup + \redoconvertfont % !! + \chardef\graphicvadjustmode\zerocount + \flushmargincontentsindeed + \egroup + \fi} + +% For old times sake (i use it in project styles) we provide + +\unexpanded\def\placemargintexts {\placemargincontent} +\def\resetmargetitels {\resetmargincontent} +\def\margewoordpositie{\margewoord} % obsolete, now no longer range + +% but never use them yourself since they may disappear. + +\def\oplinker#1% + {\strut + \graphicvadjust + {\dontcomplain + \setbox\scratchbox\vtop{\forgetall\strut#1}% + \getboxheight\scratchdimen\of\box\scratchbox + \vskip-\scratchdimen % waarom stond hier een \ ? + \box\scratchbox}} + +\setupinmargin + [\c!style=\v!bold, + \c!color=, + \c!strut=\v!auto, + \c!location=\v!both, + \c!align=\v!inner, + \c!stack=\v!no, + \c!before=, + \c!after=] + +\setupinmargin + [\v!left] + [\c!distance=\leftmargindistance, + \c!width=\leftmarginwidth, + %\c!align=\v!left, % no + \c!location=\v!left] + +\setupinmargin + [\v!right] + [\c!distance=\rightmargindistance, + \c!width=\rightmarginwidth, + %\c!align=\v!right, % no + \c!location=\v!right] + +% bonus needed when [inner/outer] is used as tag + +\setupinmargin[\v!inner][\c!location=\v!inner,\c!align=\v!inner] +\setupinmargin[\v!outer][\c!location=\v!outer,\c!align=\v!inner] + +% more efficient (5K less fotmat file) +% +% \letvalue{\??im\v!inner\c!location}\v!inner \letvalue{\??im\v!inner\c!align}\v!inner +% \letvalue{\??im\v!outer\c!location}\v!outer \letvalue{\??im\v!outer\c!align}\v!inner + +\protect \endinput diff --git a/tex/context/base/page-mis.mkii b/tex/context/base/page-mis.mkii new file mode 100644 index 000000000..bd029f896 --- /dev/null +++ b/tex/context/base/page-mis.mkii @@ -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-mis.mkiv b/tex/context/base/page-mis.mkiv new file mode 100644 index 000000000..f7c3d529d --- /dev/null +++ b/tex/context/base/page-mis.mkiv @@ -0,0 +1,239 @@ +%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\ifmarginblocks + +\def\dosetupmarginblocks[#1]% + {\getparameters[\??mb][#1]% + \doifelse\@@mbstate\v!start + {\showmessage\m!layouts4\empty + \marginblockstrue + \let\somenextfloat\dosomenextfloat + \let\startmarginblock\dostartmarginblock + \let\stopmarginblock\dostopmarginblock}% + {\showmessage\m!layouts5\empty + \marginblocksfalse + \def\somenextfloat[##1]% + {\someelsefloat[##1,\v!here]}% + \let\startmarginblock\dontstartmargeblok + \let\stopmarginblock\dontstopmargeblok}} + +\unexpanded\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} + +\unexpanded\def\placerightmarginblock + {\hskip\rightmarginwidth} + +\unexpanded\def\placeleftmarginblock + {\hskip\leftmarginwidth} + +\def\checkmarginblocks + {\ifvoid\marginbox\else\docheckmarginblocks\fi} + +\def\docheckmarginblocks % 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 + {\unexpanded\def\placerightmarginblock + {\setbox\preparedmarginbox\hbox to \rightmarginwidth + {\@@mbleft\box\preparedmarginbox\@@mbright}% + \vsmashbox\preparedmarginbox + \box\preparedmarginbox}}% + \def\leftmarginbox + {\unexpanded\def\placeleftmarginblock + {\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} + +\newcount\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 +\newcount \nofpostponedpageblocks + +% \ifinpostponing: handhaven, want gebruikt in stijlen ! ! ! ! ! + +\def\dodoflushpostponedblocks + {\bgroup % we need the font switch, else problems inside split verbatim + \setnormalcatcodes % postponing in verbatim + \restoreglobalbodyfont + \global\pagetotal\zeropoint + \global\inpostponingtrue + \the\postponedpageblocks + \dorecurse\nofpostponedblocks + {\getbuffer[pbuf-\recurselevel]}% + \doflushfloats % new but potential dangerous + \global\nofpostponedblocks\zerocount + \global\inpostponingfalse + \egroup} + +\def\doflushpostponedblocks + {\ifinpostponing \else + \ifcase\nofpostponedblocks \else \dodoflushpostponedblocks \fi + \ifcase\nofpostponedpageblocks \else \dodoflushpostponedblocks \fi + \fi} + +\def\doflushpostponedcontent + {\bgroup + \setsystemmode\v!postponing + \the\everytopofpage + %\flushrestfloats + \doflushpagefloats + \doflushpostponedblocks + \egroup} + +\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]% + {\global\advance\nofpostponedpageblocks\plusone % hm, never reset? + \bgroup % a little bit of misusing grouping + \doifinstring{+}{#1}\advance \realpageno#1\relax % ugly but efficient + \doglobal\appendetoks\noexpand\getpostponedblock + {\realfolio}{\number\nofpostponedpageblocks}\to\postponedpageblocks + \egroup + \showmessage\m!layouts3{\number\nofpostponedpageblocks}% + \dostartbuffer[rbuf-\number\nofpostponedpageblocks]% + [\e!start\v!postponing][\e!stop\v!postponing]} + +\def\dodostartpostponing + {\global\advance\nofpostponedblocks\plusone + \showmessage\m!layouts3{\number\nofpostponedblocks}% + \expanded{\dostartbuffer[pbuf-\number\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.mkii b/tex/context/base/page-mul.mkii new file mode 100644 index 000000000..c78af074a --- /dev/null +++ b/tex/context/base/page-mul.mkii @@ -0,0 +1,1773 @@ +%D \module +%D [ file=page-mul, % was: core-mul +%D version=1998.03.15, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Multi Column Output, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / 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 +%D OTR macro's were isolated in modules and column sets were +%D introduced, this module became part of the OTR modules. As +%D a result this module is no longer generic. It also needs +%D an overhaul. + +\unprotect + +% TO DO ! + +\let\OTRMULsetvsize \OTRONEsetvsize +\let\OTRMULsethsize \OTRONEsethsize +\let\OTRMULdopagecontents \OTRONEdopagecontents +\let\OTRMULfinalsidefloatoutput\OTRONEfinalsidefloatoutput % ??? +\let\OTRMULflushfloatbox \OTRONEflushfloatbox + +\let\OTRMULdosettopinserts \relax +\let\OTRMULdosetbotinserts \relax +\let\OTRMULdotopinsertions \relax +\let\OTRMULdobotinsertions \relax +\let\OTRMULdosetbothinserts \relax +\let\OTRMULflushsavedfloats \relax + +\let\OTRMULflushsidefloats \forgetsidefloats % \relax +\let\OTRMULsynchronizesidefloats\forgetsidefloats % \relax + +\newtoks \OTRMULoutput + +\def\OTRMULgotonextpage + {\ejectpage} + +\def\OTRMULgotonextpageX % will become obsolete + {\superejectpage} + +% check \count multiplications + +% some day try this in balancing routine +% +% \ifdim\pagetotal>\pagegoal +% \eject +% \else +% \goodbreak +% \fi + +%D The following macro's implement a multi||column output +%D routine. The original implementation was based on Donald +%D Knuth's implementation, which was adapted by Craig Platt to +%D support balancing of the last page. I gradually adapted +%D Platt's version to our needs but under certain +%D circumstances things still went wrong. I considered all +%D calls to Platt's \type{\balancingerror} as undesirable. + +%D This completely new implementation can handle enough +%D situations for everyday documents, but is still far from +%D perfect. While at the moment the routine doesn't support +%D all kind of floats, it does support: +%D +%D \startitemize[packed] +%D \item an unlimitted number of columns +%D \item ragged or not ragged bottoms +%D \item optional balancing without \type{\balancingerrors} +%D \item different \type{\baselineskips}, \type{\spacing}, +%D \type{\topskip} and \type{\maxdepth} +%D \item left- and right indentation, e.g. within lists +%D \item moving columns floats to the next column or page +%D \item handling of floats that are to wide for a columns +%D \stopitemize +%D +%D One could wonder why single and multi||columns modes are +%D still separated. One reason for this is that \TeX\ is not +%D suited well for handling multi||columns. As a result, the +%D single columns routines are more robust. Handling one +%D column as a special case of multi||columns is posible but at +%D the cost of worse float handling, worse page breaking, +%D worse etc. Complicated multi||column page handling should +%D be done in \cap{DTP}||systems anyway. +%D +%D There are three commands provided for entering and leaving +%D multi||column mode and for going to the next column: +%D +%D \interface \type{\beginmulticolumns} \\ \\ +%D \interface \type{\endmulticolumns} \\ \\ +%D \interface \type{\ejectcolumn} \\ \\ +%D +%D This routines are sort of stand||alone. They communicate +%D with the rest of \CONTEXT\ by means of some interface +%D macro's, which we only mention. +%D +%D \interface \type{\nofcolumns} \\ +%D the number of columns \\ +%D \interface \type{\minbalancetoplines} \\ +%D the minimum number op balanced top lines \\ +%D \interface \type{\betweencolumns} \\ +%D the stuff between columns \\ +%D \interface \type{\finaloutput{action}{box}} \\ +%D some kind of \type{\pagebody} and \type{\shipout} \\ +%D +%D \interface \type{\ifbalancecolumns} \\ +%D balancing the colums or not \\ +%D \interface \type{\ifstretchcolumns} \\ +%D ragging the bottom or not \\ +%D +%D \interface \type{\ifheightencolumns} \\ +%D fix the heigh tor not \\ +%D \interface \type{\fixedcolumnheight} \\ +%D the optional fixed height \\ +%D +%D \interface \type{\ifinheritcolumns} \\ +%D handle ragging or not \\ +%D \interface \type{\ifr@ggedbottom} \\ +%D use ragged bottoms \\ +%D \interface \type{\ifb@selinebottom} \\ +%D put the bottom line on the baseline \\ +%D \interface \type{\ifnormalbottom} \\ +%D put the bottom line at the baseline \\ +%D +%D \interface \type{\ifreversecolumns} \\ +%D reverse the order in wich columns are flushed \\ +%D +%D \interface \type{\usercolumnwidth} \\ +%D the calculated width of a column \\ +%D \interface \type{\columntextwidth} \\ +%D the maximum width of a column \\ +%D \interface \type{\columntextheight} \\ +%D the minimum width of a column \\ +%D +%D \interface \type{\spacingfactor} \\ +%D the spacing factor \\ +%D \interface \type{\bodyfontsize} \\ +%D the (local) bodyfontsize \\ +%D \interface \type{\openlineheight} \\ +%D the lineheight (including \type{\spacing}) \\ +%D +%D \interface \type{\EveryBodyFont} \\ +%D communication channel to font switching routines \\ +%D +%D \interface \type{\global\settopskip} \\ +%D set \type{\topskip} \\ +%D \interface \type{\setvsize} \\ +%D set \type{\vsize} and \type{\pagegoal} \\ +%D \interface \type{\sethsize} \\ +%D set \type{\hsize} \\ +%D +%D \interface \type{\flushcolumnfloats} \\ +%D push saved column floats (next page) \\ +%D \interface \type{\flushcolumnfloat} \\ +%D push saved column floats (next column) \\ +%D \interface \type{\setcolumnfloats} \\ +%D initialize column floats \\ +%D +%D \interface \type{\finishcolumnbox} \\ +%D do something special (a hook) \\ +%D \interface \type{\postprocesscolumnpagebox} \\ +%D do something with each columnbox (also a hook) \\ +%D \interface \type{\postprocesscolumnbox} \\ +%D do something with each columnbox (also a hook) \\ +%D \interface \type{\postprocesscolumnline} \\ +%D do something with each columnline (also a hook) \\ +%D \interface \type{\currentcolumn} \\ +%D the current column \\ +%D +%D These interface macro's are called upon or initialized +%D by the multi||column macro's. + +%D A lot of footnote stuff added! + +\def\finalcolumntextwidth {\makeupwidth} +\def\finalcolumntextheight {\textheight} +\def\columntextwidth {\makeupwidth} +\def\columntextheight {\textheight} +\def\usercolumnwidth {\textwidth} +\def\columntextoffset {\!!zeropoint} + +\def\fixedcolumnheight {\textheight} +\def\betweencolumns {\hskip\bodyfontsize} + +\let\setcolumnfloats \relax % in CONTEXT used for floats +\let\flushcolumnfloats \relax % in CONTEXT used for floats +\let\flushcolumnfloat \relax % in CONTEXT used for floats +\let\finishcolumnbox \relax % in CONTEXT used for backgrounds + +% %D In fact, the column height and width are set by means of +% %D two macro's. One can change their meaning if needed: +% +% \def\setcolumntextheight +% {\def\columntextheight{\teksthoogte}} +% +% \def\setcolumntextwidth +% {\def\columntextwidth{\zetbreedte}} + +%D Both macros are redefined in \CONTEXT\ when backgrounds +%D are applied to columns. The final values are used when +%D flushing the columns. + +\newtoks\singlecolumnout % remove that one + +%D It's more convenient to use \type {\columnwidth} instead +%D of messing around with boxes each time. + +\newdimen\columnwidth +\newdimen\gutterwidth + +\def\determinecolumnwidth + {\bgroup + \setbox\scratchbox\hbox + {\setcolumnhsize + \global\columnwidth\usercolumnwidth + \global\gutterwidth\intercolumnwidth}% + \egroup} + +%D Going to a new columns is done by means of a +%D \type{\ejectcolumn}. The following definition does not +%D always work. + +\def\ejectcolumn + {\goodbreak\showmessage\m!columns2\empty} + +%D The next macro should never be called so let's deal with it. +%D There were several solutions to these kind of errors. First +%D we check for a good breakpoint before firing up the +%D multi||column routine (\type{\break} or \type{\allowbreak}). +%D We do the same at the end of the routine +%D (\type{\allowbreak}). These allowances are definitely +%D needed! +%D +%D Some on first sight redundant calls to for instance +%D \type{\setvsize} in the flushing, splitting and balancing +%D macro's can definitely not be omitted! Some are just there +%D to handle situations that only few times arise. One of +%D those can be that the output routine is invoked before +%D everything is taken care of. This happens when we +%D flush (part of) the current page with an \type{\unvbox} +%D with a \type{\pagetotal}~$\approx$ \type{\pagegoal}. One +%D simply cannot balance columns that are just balanced. +%D +%D I hope one never sees the following message. Because it +%D took me a lot of time to develop the multi||columns +%D routines, every (although seldom) warning gives me the +%D creeps! + +\def\balancingerror + {\showmessage\m!columns3\empty + \finaloutput\unvbox\normalpagebox} + +\def\OTRMULsometopsfloat{\showmessage\m!columns4\empty \someherefloat} +\def\OTRMULsomebotsfloat{\showmessage\m!columns5\empty \someherefloat} + +\def\OTRMULsomeherefloat{\OTRONEsomeherefloat} + +%D The local column width is available in the dimension +%D register \type{\localcolumnwidth}, which is calculated as: + +\def\setcolumnhsize % beware, this one is available for use in macros + {\setbox\scratchbox\hbox{\parindent\zeropoint\betweencolumns}% + \intercolumnwidth\wd\scratchbox + \localcolumnwidth\columntextwidth + \advance\localcolumnwidth -\leftskip + \advance\localcolumnwidth -\rightskip + % new + \advance\localcolumnwidth -\colleftskip + \advance\localcolumnwidth -\colrightskip + % + \advance\localcolumnwidth -\nofcolumns\intercolumnwidth + \advance\localcolumnwidth \intercolumnwidth + \divide \localcolumnwidth \nofcolumns + \scratchdimen\columntextoffset + \multiply\scratchdimen \plustwo + \advance\localcolumnwidth -\scratchdimen + \usercolumnwidth\localcolumnwidth + \hsize\localcolumnwidth} % we don't do it \global + +%D Torture test: +%D +%D \startbuffer +%D \startbuffer[b] +%D \startcolumns +%D \input tufte +%D \stopcolumns +%D \stopbuffer +%D \typebuffer[b] \getbuffer[b] +%D +%D \startbuffer[b] +%D \startnarrower +%D \input tufte +%D \stopnarrower +%D \stopbuffer +%D \typebuffer[b] \getbuffer[b] +%D +%D \startbuffer[b] +%D \startcolumns \startnarrower +%D \input tufte +%D \stopnarrower \stopcolumns +%D \stopbuffer +%D \typebuffer[b] \getbuffer[b] +%D +%D \startbuffer[b] +%D \startnarrower \startcolumns +%D \input tufte +%D \stopcolumns \stopnarrower +%D \stopbuffer +%D \typebuffer[b] \getbuffer[b] +%D +%D \startbuffer[b] +%D \startcolumns \startnarrower[left] +%D \input tufte +%D \stopnarrower \stopcolumns +%D \stopbuffer +%D \typebuffer[b] \getbuffer[b] +%D +%D \startbuffer[b] +%D \startnarrower[left] \startcolumns +%D \input tufte +%D \stopcolumns \stopnarrower +%D \stopbuffer +%D \typebuffer[b] \getbuffer[b] +%D +%D \startbuffer[b] +%D \startnarrower \startcolumns \startnarrower +%D \input tufte +%D \stopnarrower\stopcolumns \stopnarrower +%D \stopbuffer +%D \typebuffer[b] \getbuffer[b] +%D +%D \startbuffer[b] +%D \startnarrower[left] \startcolumns \startnarrower +%D \input tufte +%D \stopnarrower\stopcolumns \stopnarrower +%D \stopbuffer +%D \typebuffer[b] \getbuffer[b] +%D \stopbuffer +%D +%D \start +%D \def\postprocesscolumnline#1{\ruledhbox{\strut\box#1}\hss} +%D \getbuffer +%D \stop + +%D One should be aware that when font related dimensions are +%D used in typesetting the in||between material, these +%D dimensions are influenced by bodyfont switches inside +%D multi||column mode. + +\newdimen\mcscratchdimen +\newcount\nofcolumnlines + +\chardef\multicolumnlinemethod\zerocount % 0: overshoot (old default), 1: tight +% \chardef\multicolumnlinemethod\plusone + +\def\getmulticolumnlines + {\mcscratchdimen-\columntextoffset + \multiply\mcscratchdimen \plustwo + \advance\mcscratchdimen \columntextheight + \ifdim\precolumnboxheight>\zeropoint + \advance\mcscratchdimen -\precolumnboxheight + \fi + \settotalinsertionheight + \advance\mcscratchdimen -\totalinsertionheight + \ifcase\multicolumnlinemethod \getnoflines\mcscratchdimen + \or \getrawnoflines\mcscratchdimen + \else \getrawnoflines\mcscratchdimen + \fi + % added 30/7/2004 + \ifnum\layoutlines>\zerocount \ifnum\noflines>\layoutlines + \noflines\layoutlines + \fi \fi + \nofcolumnlines\noflines} + +\def\multicolumnovershootratio{.5} % {\ifgridsnapping0\else.5\fi} + +\def\setcolumnvsize + {\getmulticolumnlines + \mcscratchdimen\nofcolumnlines\openlineheight + \advance\mcscratchdimen \multicolumnovershootratio\openlineheight % collect enough data + \global\vsize\nofcolumns\mcscratchdimen + \global\pagegoal\vsize} % let's do it only here + +%D It really starts here. After some checks and initializations +%D we change the output routine to continous multi||column +%D mode. This mode handles columns that fill the current and +%D next full pages. The method used is (more or less) +%D multiplying \type{\vsize} and dividing \type{\hsize} by +%D \type{\nofcolumns}. More on this can be found in the +%D \TeX book. We save the top of the current page in box +%D \type{\precolumnbox}. +%D +%D We manipulate \type{\topskip} a bit, just to be shure that +%D is has no flexibility. This has te be done every time a +%D font switch takles place, because \type{\topskip} can depend +%D on this. +%D +%D Watch the trick with the \type{\vbox}. This way we get the +%D right interlining and white space. + +\def\beginmulticolumns + {\par + \flushnotes + \xdef\precolumndepth{\the\prevdepth}% + \begingroup + % new + \leftskip1\leftskip + \rightskip1\rightskip + \edef\colleftskip {\the\leftskip}% + \edef\colrightskip{\the\rightskip}% + \leftskip\zeropoint + \rightskip\zeropoint + % + \dontshowcomposition + %\setcolumntextwidth\relax + %\setcolumntextheight\relax + \widowpenalty\zerocount % is gewoon beter + \clubpenalty \zerocount % zeker bij grids + \ifsomefloatwaiting + \showmessage\m!columns6{\the\savednoffloats}% + \global\setbox\savedfloatlist\box\floatlist + \xdef\restoresavedfloats + {\global\savednoffloats\the\savednoffloats + \global\setbox\floatlist\box\savedfloatlist + \global\noexpand\somefloatwaitingtrue}% + \global\savednoffloats\zerocount + \global\somefloatwaitingfalse + \else + \global\let\restoresavedfloats\relax + \fi + \dimen0\pagetotal + \advance\dimen0 \parskip + \advance\dimen0 \openlineheight + \ifdim\dimen0<\pagegoal + \allowbreak + \else + \break % Sometimes fails + \fi + \appendtoks\topskip1\topskip\to\everybodyfont + \the\everybodyfont % ugly here + \saveinterlinespace % ugly here + \initializecolumns\nofcolumns + \hangafter\zerocount + \hangindent\zeropoint + \everypar\emptytoks + \ifdim\pagetotal=\zeropoint \else + \verticalstrut + \vskip-\struttotal + \fi + \global\savedpagetotal\pagetotal + \global\singlecolumnout\output + %\global\output{\global\setbox\precolumnbox\vbox{\unvbox\normalpagebox}}% + \global\output{\global\setbox\precolumnbox\vbox{\dotopinsertions\unvbox\normalpagebox}}% + \eject % no \holdinginserts=1, can make footnote disappear ! + \global\precolumnboxheight\ht\precolumnbox + \global\output{\continuousmulticolumnsout}% + \setcolumnfloats + \dohandleallcolumns + {\global\setbox\currenttopcolumnbox\emptybox}% + \checkbegincolumnfootnotes + \activateotr{MUL}{ONE}% todo ! ! ! ! + \let\sethsize\setcolumnhsize + \let\setvsize\setcolumnvsize + \sethsize + \setvsize + \showcomposition} + +%D When we leave the multi||column mode, we have to process the +%D not yet shipped out part of the columns. When we don't +%D balance, we simply force a continuous output, but a balanced +%D output is more tricky. + +%D First we try to fill up the page and when all or something +%D is left we try to balance things. This is another useful +%D adaption of the ancesters of these macro's. It takes some +%D reasoning to find out what happens and maybe I'm making +%D some mistake, but it works. +%D +%D Voiding box \type{\precolumnbox} is sometimes necessary, +%D e.g. when there is no text given between \type{\begin..} +%D and \type{\end..}. The \type{\par} is needed! + +\chardef\multicolumnendsyncmethod\plusone % 1: old sync 2: new sync (cont-loc/project) / may fail ! ! ! ! + +\def\endmulticolumns + {%\par + \ifnum\multicolumnendsyncmethod=\plustwo + \synchronizeoutput + \else + % don't combine these + \vskip\lineheight + \vskip-\lineheight % take footnotes into account + \fi + \dontshowcomposition + \doflushcolumnfloat % added recently + %\doflushcolumnfloats % no, since it results in wrong top floats + \flushnotes % before start of columns + \par + \ifbalancecolumns + \ifnum\multicolumnendsyncmethod=\plusone + \global\output{\continuousmulticolumnsout}% + \goodbreak + \fi + \global\output{\balancedmulticolumnsout}% + \else + \goodbreak + \fi + \eject % the prevdepth is important, try e.g. toclist in + \prevdepth\zeropoint % columns before some noncolumned text text + \global\output\singlecolumnout + \global\output{\the\mainoutput}% % % % % todo + \ifvoid\precolumnbox\else + \unvbox\precolumnbox + \fi + \global\precolumnboxheight\zeropoint + \endgroup % here + \nofcolumns\plusone + \setvsize % the outer one! + \synchronizeoutput % new may 2004 / we need to: \pagegoal\vsize + \checkendcolumnfootnotes + \dosomebreak\allowbreak + \restoresavedfloats} + +%D Because some initializations happen three times, we +%D defined a macro for them. Erasing \type{\everypar} is +%D needed because we don't want anything to interfere. + +\def\setmulticolumnsout + {\everypar\emptytoks + \dontcomplain + \settopskip + \setmaxdepth + \topskip1\topskip + \splittopskip\topskip + \splitmaxdepth\maxdepth + \boxmaxdepth\maxdepth % dangerous + \emergencystretch\zeropoint\relax} % sometimes needed ! + +%D Flushing the page comes to pasting the columns together and +%D appending the result to box \type{\precolumnbox}, if not +%D void. I've seen a lot of implementations in which some skip +%D was put between normal text and multi||column text. When we +%D don't want this, the baselines can be messed up. I hope the +%D seemingly complicated calculation of a correction +%D \type{\kern} is adequate to overcome this. Although not +%D watertight, spacing is taken into account and even multiple +%D mode changes on one page go well. But cross your fingers and +%D don't blame me. +%D +%D One of the complications of flushing out the boxes is that +%D \type{\precolumnbox} needs to be \type{\unvbox}'ed, otherwise +%D there is too less flexibility in the page when using +%D \type{\r@ggedbottom}. It took a lot of time before these +%D kind of problems were overcome. Using \type{\unvbox} at the +%D wrong moment can generate \type{\balancingerror}'s. +%D +%D One can use the macros \type {\maxcolumnheight} and \type +%D {\maxcolumndepth} when generating material between columns +%D as well as postprocessing column lines. + +\let\maxcolumnheight=\zeropoint +\let\maxcolumndepth =\zeropoint + +\newbox\columnpagebox + +\def\setmaxcolumndimensions + {\let\maxcolumnheight\!!zeropoint + \let\maxcolumndepth \!!zeropoint + \dohandleallcolumns + {\ifdim\ht\currentcolumnbox>\maxcolumnheight + \edef\maxcolumnheight{\the\ht\currentcolumnbox}% + \fi + \ifdim\dp\currentcolumnbox>\maxcolumndepth + \edef\maxcolumndepth{\the\dp\currentcolumnbox}% + \fi}} + +\chardef\multicolumntopflushmethod\plusone % 0: no correction, 1: correction when topstuff, 2: correction, 3: correction++ +\chardef\multicolumntopalignmethod\plustwo % 0: nothing, 1: force grid, 2: follow grid + +\def\flushprecolumnboxnogrid + {\unvbox\precolumnbox} + +\def\flushprecolumnboxongrid + {\scratchdimen\savedpagetotal + \advance\scratchdimen -\ht\precolumnbox + \advance\scratchdimen -\dp\precolumnbox + \advance\scratchdimen -\topskip + \box\precolumnbox + \kern\scratchdimen} + +\newconditional\someprecolumncontent + +\def\flushcolumnedpage#1% + {\bgroup + \ifvoid\precolumnbox + \setfalse\someprecolumncontent % will be set elsewhere + \else + \settrue\someprecolumncontent +\mkprocessboxcontents\precolumnbox + \fi + \forgetall + \setmulticolumnsout + \showcomposition + \setmaxcolumndimensions + \dohandleallcolumns + {\mkprocesscolumncontents\currentcolumnbox}% + \postprocesscolumns + \dohandleallcolumns % \hbox i.v.m. \showcomposition + {\global\setbox\currentcolumnbox\hbox to \localcolumnwidth + {\box\currentcolumnbox + \global\wd\currentcolumnbox\localcolumnwidth + \ifheightencolumns + \global\ht\currentcolumnbox\fixedcolumnheight + \fi}}% + \setmaxcolumndimensions + \overlaycolumnfootnotes + \setbox\columnpagebox\vbox + {\hbox to \finalcolumntextwidth + {\hskip\colleftskip\relax % new, \relax needed + \ifreversecolumns + \popsplitproperties % else wrong color stack + \@EA\dohandlerevcolumns + \else + \@EA\dohandleallcolumns + \fi + {\finishcolumnbox{\hbox + {\ifx\finishcolumnbox\relax\else\strut\fi + \box\currentcolumnbox}}% + \hfil}% + \unskip + \hskip\colrightskip}}% new + \scratchdimen\zeropoint + \dohandleallcolumns + {\ifdim-\ht\currenttopcolumnbox<\scratchdimen + \scratchdimen-\ht\currenttopcolumnbox + \fi + \global\setbox\currenttopcolumnbox\emptybox}% + \advance\scratchdimen \ht\columnpagebox + \setbox\scratchbox\hbox to \columntextwidth + {\vrule + \!!width\zeropoint + \!!height\scratchdimen + \!!depth\dp\columnpagebox + \dostepwiserecurse2\nofcolumns1{\hfil\betweencolumns}\hfil}% + \setbox\columnpagebox\hbox + {\box\columnpagebox + \hskip-\columntextwidth + \restoretextcolor{\box\scratchbox}}% + \postprocesscolumnpagebox % new, acts upon \box\columnpagebox + \ifconditional\someprecolumncontent + \settrue\someprecolumncontent + % next some incredible crappy code + \ifcase\multicolumntopalignmethod + \flushprecolumnboxnogrid % not on grid + \or + \flushprecolumnboxongrid % force on grid + \else\ifgridsnapping % somehow this junk fails in pascal + \flushprecolumnboxongrid % obey grid settings, force on grid + \else + \flushprecolumnboxnogrid % ignore grid settings, not on grid + \fi \fi + \fi + \global\precolumnboxheight\zeropoint + \setvsize + \dosomebreak\nobreak % hm, only needed when topstuff + \ifgridsnapping + \else + \ifcase\multicolumntopflushmethod + % sometimes method 1 goes wrong, so we need a way out; best sort this out + % when we run into it again + \or + % \input tufte \startcolumns \showbaselines \input tufte \stopcolumns \input tufte + \ifconditional\someprecolumncontent +% \scratchdimen\topskip +% \advance\scratchdimen -\openstrutheight +% \nointerlineskip +% \vskip-\scratchdimen + \nointerlineskip + \vskip\dimexpr\openstrutheight-\topskip\relax + \fi + \or +% \scratchdimen\topskip +% \advance\scratchdimen -\openstrutheight +% \nointerlineskip +% \vskip-\scratchdimen + \nointerlineskip + \vskip\dimexpr\openstrutheight-\topskip\relax + \or + % untested but maybe handy +% \scratchdimen\topskip +% \advance\scratchdimen -\openstrutheight +% \nointerlineskip +% \vskip-\scratchdimen +% \vskip-\lineheight +% \vbox{\strut}% + \nointerlineskip + \vskip\dimexpr\openstrutheight-\topskip-\lineheight\relax + \vbox{\strut}% + \fi + \fi + \prevdepth\openstrutdepth + \nointerlineskip + \dp\columnpagebox\zeropoint + \global\finalcolumnheights\ht\columnpagebox + \getnoflines\finalcolumnheights + \global\finalcolumnlines\noflines + \ifcase#1\else + % messy correction, we need to rewrite this module (newcolumns) + \setbox\columnpagebox\vbox + {\offinterlineskip + \scratchdimen\ht\columnpagebox + \advance\scratchdimen\dp\columnpagebox % we probably lost that one already + \box\columnpagebox + \vskip-\scratchdimen}% + \scratchdimen\noflines\openlineheight + \advance\scratchdimen-\openstrutdepth + \advance\scratchdimen-\openlineheight + \advance\scratchdimen\topskip + \ht\columnpagebox\scratchdimen + \dp\columnpagebox\openstrutdepth + % end of mess + \fi + \box\columnpagebox + \egroup} + +%D In case one didn't notice, finaly \type{\finishcolumnbox} is +%D applied to all boxes. One can use these hooks for special +%D purposes. +%D +%D Once upon a time I wanted to manipulate the individual lines +%D in a column. This feature is demonstrated in the two examples +%D below. +%D +%D \startbuffer +%D \def\postprocesscolumnline#1% or \postprocesscolumnbox +%D {\ruledhbox{\box#1}\hss} +%D +%D \startcolumns[n=4] +%D \dorecurse{25}{line: \recurselevel\par} +%D \stopcolumns +%D \stopbuffer +%D +%D \typebuffer +%D +%D Here we show the natural width of the lines: +%D +%D {\getbuffer} +%D +%D The next example does a bit more advanced manipulation: +%D +%D \startbuffer +%D \def\postprocesscolumnline#1% +%D {\ifodd\currentcolumn +%D \hfill\unhbox#1\relax +%D \else +%D \relax\unhbox#1\hfill +%D \fi} +%D +%D \startcolumns[n=4] +%D \dorecurse{25}{line \recurselevel\par} +%D \stopcolumns +%D \stopbuffer +%D +%D \typebuffer +%D +%D Here we also see an application of \type{\currentcolumn}: +%D +%D {\getbuffer} +%D +%D This feature is implemented using the reshape macros +%D presented in \type{supp-box}. + +\def\postprocesscolumns + {\ifx\postprocesscolumnline\undefined \else + \dohandleallcolumns + {\global\setbox\currentcolumnbox\vtop + {\beginofshapebox + \unvbox\currentcolumnbox + \unskip\unskip + \endofshapebox + \reshapebox + {\dimen0\ht\shapebox + \dimen2\dp\shapebox + \setbox\shapebox\hbox to \hsize + {\postprocesscolumnline\shapebox}% + \ht\shapebox\dimen0 + \dp\shapebox\dimen2 + \box\shapebox}% + \flushshapebox + \everypar\emptytoks + \parskip\zeropoint % = \forgetall + \verticalstrut + \vskip-\struttotal + \vfil}}% + \fi + \ifx\postprocesscolumnbox\undefined \else + \dohandleallcolumns + {\global\setbox\currentcolumnbox\hbox + {\postprocesscolumnbox\currentcolumnbox}} + \fi} + +%D We default to doing nothing! + +\let\postprocesscolumnline =\undefined +\let\postprocesscolumnbox =\undefined +\let\postprocesscolumnpagebox=\relax + +%D \macros +%D {reversecolumnstrue} +%D +%D We can force the macro that takes care of combining +%D the columns, to flush them in the revere order. Of +%D course, by default we don't reverse. + +\newif\ifreversecolumns + +%D Here comes the simple splitting routine. It's a bit +%D longer than expected because of ragging bottoms or not. +%D This part can be a bit shorter but I suppose that I will +%D forget what happens. The splitting takes some already +%D present material (think of floats) into account! +%D +%D First we present some auxiliary routines. Any material, +%D like for instance floats, that is already present in the +%D boxes is preserved. + +\def\splitcolumn#1from \box#2to \dimen#3 top \box#4% + {\bgroup + \ifdim\ht#4>\zeropoint + \dimen0\dimen#3\relax + \dimen2\dimen0 + \advance\dimen0 -\ht#4% + \columnfootnotecorrection{#1}{\dimen0}% + \setbox0\vsplit#2 to \dimen0 + \global\setbox#1\vbox to \dimen2 + {\ifgridsnapping + \dimen0-\openstrutheight + \advance\dimen0 \topskip + \vskip\dimen0\copy#4\vskip-\dimen0 + \else + \unvcopy#4% + \fi + \fuzzysnappedbox\unvbox0 + \fakecolumnfootnotes{#1}}% + \else + \ifcase\clevernotes + \global\setbox#1\vsplit#2 to \dimen#3% + \global\setbox#1\vbox + {\fuzzysnappedbox\unvbox{#1}}% % or \box ? + \else + \columnfootnotecorrection{#1}{\dimen#3}% + \setbox0\vsplit#2 to \dimen#3% + \global\setbox#1\vbox to \dimen#3% + {\fuzzysnappedbox\unvbox0 + \fakecolumnfootnotes{#1}}% + \fi + \fi + \egroup} + +\def\splitcurrentcolumn from \box#1to \dimen#2% + {\splitcolumn\currentcolumnbox from \box#1 to \dimen#2 top \box\currenttopcolumnbox} + +\def\splitfirstcolumn from \box#1to \dimen#2% + {\splitcolumn\firstcolumnbox from \box#1 to \dimen#2 top \box\firsttopcolumnbox} + +\def\splitlastcolumn from \box#1to \dimen#2% + {\global\setbox\lastcolumnbox\vbox + {\unvcopy\lasttopcolumnbox + \fuzzysnappedbox\unvbox{#1}% + \fakecolumnfootnotes\lastcolumnbox}} + +%D NEW: still to be documented. + +\def\fakecolumnfootnotes#1% + {\relax + \ifcase\clevernotes\else + \ifnum#1=\lastcolumnbox + \fakenotes + \fi + \fi} + +\def\columnfootnotecorrection#1#2% + {\relax + \ifcase\clevernotes + % page notes + \or + \ifnum#1=\firstcolumnbox\relax + \calculatetotalclevernoteheight + \advance#2 -\totalnoteheight + \fi + \else + \ifnum#1=\lastcolumnbox\relax + \calculatetotalclevernoteheight + \advance#2 -\totalnoteheight + \fi + \fi} + +\def\overlaycolumnfootnotes + {\relax + \ifcase\clevernotes + % page notes + \else + \checknotepresence + \ifnotespresent + % the note box has the depth of the notefont + % because a column (i.e. first column has no depth, + % we need to anchor top down) + \bgroup + \ifcase\clevernotes\or + \getmulticolumnlines + \advance\nofcolumnlines \minustwo + \scratchdimen\nofcolumnlines\lineheight + \advance\scratchdimen \topskip + \setbox0\hbox + {\lower\scratchdimen\vbox{\placenoteinserts}}% + \ht0=\openstrutheight % \strutht + \dp0=\openstrutdepth % \strutdp + \scratchdimen\ht\firstcolumnbox + \global\setbox\firstcolumnbox\vbox to \scratchdimen + {\box\firstcolumnbox + \vskip-\scratchdimen + \restoretextcolor{\box0}}% + \else + % maybe here also \getmulticolumnlines + \scratchdimen\ht\firstcolumnbox + \advance\scratchdimen -\openstrutdepth % \strutdp + \getnoflines\scratchdimen + \advance\noflines \minustwo + \scratchdimen\noflines\lineheight + \advance\scratchdimen \topskip + \setbox0\hbox + {\lower\scratchdimen\vbox{\placenoteinserts}}% + \ht0=\openstrutheight % \strutht + \dp0=\openstrutdepth % \strutdp + \scratchdimen\ht\lastcolumnbox + \global\setbox\lastcolumnbox\vbox to \scratchdimen + {\box\lastcolumnbox + \vskip-\scratchdimen + \restoretextcolor{\box0}}% + \fi + \egroup + \fi + \fi} + +%D Here comes the routine that splits the long box in columns. +%D The macro \type{\flushcolumnfloats} can be used to flush +%D either floats that were present before the multi||column +%D mode was entered, or floats that migrate to next columns. +%D Flushing floats is a delicate process. + +\def\continuousmulticolumnsout + {\bgroup + \forgetall + \setmulticolumnsout + \dontshowcomposition +% \dimen0=\columntextheight +% \advance\dimen0 -\precolumnboxheight +% \settotalinsertionheight +% \advance\dimen0 -\totalinsertionheight +% \ifgridsnapping % evt altijd, nog testen +% \getnoflines{\dimen0} +% \dimen0=\noflines\openlineheight +% \fi + \getmulticolumnlines + \dimen0=\nofcolumnlines\openlineheight + \dohandleallcolumns + {\splitcurrentcolumn from \box\normalpagebox to \dimen0}% + \setbox\restofpage\vbox{\unvbox\normalpagebox}% + \ifinheritcolumns + \ifr@ggedbottom % vreemd + \dohandleallcolumns + {\global\setbox\currentcolumnbox\vbox to \ht\firstcolumnbox + {\dimen0\dp\currentcolumnbox + \unvbox\currentcolumnbox + \vskip-\dimen0 + \vskip\openstrutdepth % \strutdp + \prevdepth\openstrutdepth % \strutdp + \vfill}}% + \ifbottomnotes \else + \dimen0\ht\firstcolumnbox + \fi + \fi + \ifn@rmalbottom + \advance\dimen0 \maxdepth + \dohandleallcolumns + {\global\setbox\currentcolumnbox\vbox to \dimen0 + {\unvbox\currentcolumnbox}}% + \fi + \ifb@selinebottom + % the columns are on top of the baseline + \fi + \else + \dohandleallcolumns + {\global\setbox\currentcolumnbox\vbox to \dimen0 + {\ifstretchcolumns + \unvbox\currentcolumnbox + \else + \unvbox\currentcolumnbox % wel of niet \unvbox ? + \vfill + \fi}}% + \dohandleallcolumns + {\global\ht\currentcolumnbox\dimen0}% + \fi + \setbox\precolumnbox\vbox{\flushcolumnedpage\zerocount}% + \finaloutput\box\precolumnbox + \sethsize + \setvsize + \flushcolumnfloats + \unvbox\restofpage + % \penalty\outputpenalty % gaat gruwelijk mis in opsommingen + \egroup} + +%D And this is the balancing stuff. Again, part of the routine +%D is dedicated to handling ragged bottoms, but here we also +%D see some handling concerning the stretching of columns. +%D We set \type{\widowpenalty} at~0, which enables us to +%D balance columns with few lines. The use of \type{\box2} and +%D \type{\box4} garantees a more robust check when skips are +%D used. + +\def\multicolumnsbalancemax{250} % 100 is too small when floats are involved + +\def\balancedmulticolumnsout + {\bgroup + \setmulticolumnsout + \dontshowcomposition + \widowpenalty\zerocount + \setbox0\vbox{\unvbox\normalpagebox}% +\ifdim\ht0>\openlineheight % at least one line + \ifnum\minbalancetoplines<2 % balance anyway + \donetrue + \else % check criterium to available lines + \getnoflines{\ht0}% + \divide\noflines \nofcolumns \relax + \ifnum\noflines<\minbalancetoplines \relax + \dimen0\ht0 + \advance\dimen0 \ht\firsttopcolumnbox + \advance\dimen0 \openlineheight \relax % let's play safe + \ifdim\dimen0>\columntextheight % column exceeding text height + \donetrue + \else % it seems to fit + \donefalse + \fi + \else % balance indeed + \donetrue + \fi + \fi +\else % balancing does not make sense + \donefalse +\fi +\ifdone % start balancing + %\ifdim\ht0>\openlineheight + \dimen0\ht0 + \advance\dimen0 \topskip + \advance\dimen0 -\baselineskip + \dohandleallcolumns + {\advance\dimen0 \ht\currenttopcolumnbox}% + \divide\dimen0 \nofcolumns + \vbadness\!!tenthousand\relax + \count255=\zerocount + \bgroup + \ifgridsnapping + \dimen2\lineheight + \else + \dimen2=\onepoint % RUBISH + \dimen2=\spacingfactor\dimen2 + \fi + \doloop + {\advance\count255 \plusone + \global\setbox\restofpage\copy0\relax + \splitfirstcolumn from \box\restofpage to \dimen0 + \dohandlemidcolumns + {\splitcurrentcolumn from \box\restofpage to \dimen0}% + \splitlastcolumn from \box\restofpage to \dimen0 + \setbox2\vbox{\unvcopy\firstcolumnbox}% + \dimen4\zeropoint + \dohandleallcolumns + {\setbox4\vbox + {\unvcopy\currentcolumnbox + %rather new, test this on pdftex-z.tex + \unpenalty\unskip\unpenalty\unskip}% maybe better in main splitter + %\writestatus{balance}{\the\currentcolumnbox: \the\ht4}% +% \dimen6\ht4 \ifdim\dimen6>\dimen4 \dimen4=\dimen6 \fi}% + \ifdim\ht4>\dimen4 \dimen4=\ht4 \fi}% + \advance\dimen4 -.0005pt % get rid of accurracy problem, pretty new + \ifnum\count255>\multicolumnsbalancemax\relax + \exitloop + \else\ifdim\dimen4>\ht2 + \advance\dimen0 \dimen2\relax + \else + \exitloop + \fi\fi}% + \dohandleallcolumns + {\global\setbox\currentcolumnbox\vbox{\unvcopy\currentcolumnbox}}% NIEUW + \ifnum\count255>\multicolumnsbalancemax\relax + \showmessage\m!columns7\empty + \else + \showmessage\m!columns8{\the\count255\space}% + \fi + \egroup + \ifinheritcolumns + % We cannot assume that the first column is the tallest, if + % only because we may have an aborted balance (one line in the + % first column and a graphic in the second one). + % + % \dimen0\ht\firstcolumnbox + % \dimen2\ht\firstcolumnbox + % + \dimen0=\zeropoint + \dohandleallcolumns + {\ifdim\ht\currentcolumnbox>\dimen0 + \dimen0=\ht\currentcolumnbox + \fi}% + \dimen2\dimen0 + % so far + \advance\dimen2 -\openlineheight + \dohandleallcolumns + {\dimen4\ht\currentcolumnbox + \dimen6=10\openlineheight % funny value + \global\setbox\currentcolumnbox\vbox to \dimen0 + {\unvbox\currentcolumnbox + \ifdim\dimen4>\dimen6 + \ifdim\dimen4<\dimen0 + \ifdim\dimen4>\dimen2 + \vskip\zeropoint % !! + \else + \vskip\openlineheight + \vfill + \fi + \else + \vskip\zeropoint + \fi + \else + \vskip\openlineheight + \vfill + \fi}}% + \else + \bgroup + \ifstretchcolumns + \dimen0\ht\firstcolumnbox + \dimen2=\bottomtolerance\ht\firstcolumnbox + \setbox0\vbox{\unvcopy\lastcolumnbox}% + \advance\dimen0 -\ht0\relax + \advance\dimen0 -\dp0\relax + \ifdim\dimen0>\openlineheight\relax + \ifdim\dimen0>\dimen2\relax + % \stretchcolumnsfalse % beter goed slecht dan slecht goed + \showmessage\m!columns9\empty + \fi + \fi + \fi + \dohandleallcolumns + {\global\setbox\currentcolumnbox\vbox to \ht\firstcolumnbox + {\ifstretchcolumns + \unvbox\currentcolumnbox + \else + \box\currentcolumnbox + \vfill + \fi}}% + \egroup + \fi + \else + % a one liner is not properly handled here, so best rewrite the text then + \showmessage\m!columns{10}\empty + \global\setbox\firstcolumnbox\vbox{\unvbox0}% + \fi + \global\output{\balancingerror}% + \b@selinebottomtrue % forces depth in separation rule + \flushcolumnedpage\plusone + \multicolumnseject + \egroup} + +\def\multicolumnseject + {\ifdim\pagetotal>\textheight + \eject % new + \else + \allowbreak + \fi} + +%D The multicolumn mechanism is incorporated in a \CONTEXT\ +%D interface, which acts like: +%D +%D \starttyping +%D \startcolumns[n=4,balance=no] +%D some text +%D \stopcolumns +%D \stoptyping +%D +%D The setup is optional. The default behaviour of columns +%D can be set up with: +%D +%D \starttyping +%D \setupcolumns +%D [n=2, +%D balance=yes] +%D \stoptyping +%D +%D In this case, stretching is according to the way it's +%D done outside columns (\type{\inheritcolumnstrue}). Also +%D we can setup the \type{tolerance} within a column, the +%D \type{distance} between columns and the fixed +%D \type{height} of a column. + +%D Multi||column output: the float routines +%D +%D Here come the routines that handle the placement of column +%D floats. Floats that are to big migrate to the next +%D column. Floats that are too wide, migrate to the top of the +%D next page, where they span as much columns as needed. +%D Floats that are left over from outside the multi||column +%D mode are flushed first. In macro \type{\finaloutput} the +%D topfloats that are left from previous text should be set. +%D +%D When there are some floats in the queue, we inhibit the +%D flushing of floats on top of columns. The number of +%D waiting floats is preswent in \type{\savednoftopfloats} and +%D is saved. As long as there are floats waiting, the topfloats +%D are places as if we are outside multi||column mode. This is +%D neccessary for e.g. multicolumn lists. +%D +%D When all those floats are flushed, we switch to the local +%D flushing routine. + +\def\setcolumnfloats + {\xdef\globalsavednoffloats{\the\savednoffloats}% + \ifnum\globalsavednoffloats>\zerocount + \setglobalcolumnfloats + \else + \setlocalcolumnfloats + \fi} + +\def\setglobalcolumnfloats + {\everypar\emptytoks + \let\flushcolumnfloat\relax + %\let\doroomfloat\relax + \let\docheckiffloatfits\relax + \let\flushcolumnfloats\noflushcolumnfloats} + +\def\setlocalcolumnfloats + {\everypar{\flushnotes\flushcolumnfloat\flushmargincontents\checkindentation}% + \let\flushcolumnfloat\doflushcolumnfloat + %\let\doroomfloat\docolumnroomfloat + \let\docheckiffloatfits\docolumnroomfloat + \let\flushcolumnfloats\doflushcolumnfloats + \let\doflushfloats\doflushcolumnfloats % new + \let\dosetbothinserts\relax + \let\dotopinsertions\relax} + +\def\noflushcolumnfloats + {\bgroup + \xdef\localsavednoffloats{\the\savednoffloats}% + \global\savednoffloats\globalsavednoffloats + \dotopinsertions + \xdef\globalsavenoffloats{\the\savednoffloats}% + \ifnum\globalsavednoffloats=\zerocount + \setlocalcolumnfloats + \fi + \global\savednoffloats\localsavednoffloats + \egroup} + +%D We need to calculate the amount of free space in a columns. +%D When there is not enough room, we migrate the float to the +%D next column. These macro's are alternatives (and +%D look||alikes) of \type{\doroomfloat}. When a float is to +%D wide, for one column, it is moved to the top of the next +%D page. Of course such moved floats have to be taken into +%D account when we calculate the available space. It's a pitty +%D that such things are no integral part of \TEX. + +\def\getcolumnstatus\column#1\total#2\goal#3\\% + {\dimen0=\ifdim\pagegoal<\maxdimen \pagetotal \else \zeropoint \fi + \dimen2=\zeropoint + \count255=\zerocount + \dimen8=\columntextheight + \advance\dimen8 -\precolumnboxheight + \def\dogetcolumnstatus + {\advance\count255 \plusone + \advance\dimen2 \ht\currenttopcolumnbox + \advance\dimen2 \dp\currenttopcolumnbox + \dimen4\dimen2 + \advance\dimen4 \dimen0 + \dimen6=\count255\dimen8 + \ifdim\dimen4>\dimen6 + \else + \let\dogetcolumnstatus\relax + \fi}% + \dohandleallcolumns{\dogetcolumnstatus}% + \ifnum\count255=0 \count255=1 \fi + #1=\count255 + #2=\dimen4 + #3=\dimen6 } + +\def\getinsertionheight + {\ifdim\pagegoal<\maxdimen + \bgroup + \dimen0=\columntextheight + \advance\dimen0 -\pagegoal + \xdef\insertionheight{\the\dimen0}% + \egroup + \else + \global\let\insertionheight\zeropoint + \fi} + +\def\docolumnroomfloat + {\ifpostponecolumnfloats + \global\roomforfloatfalse + \else\ifnofloatpermitted + \global\roomforfloatfalse + \else + \bgroup + \getcolumnstatus\column\count255\total\dimen0\goal\dimen2\\% + \advance\dimen0 2\openlineheight % nog nodig ? + %\ifnum\count255=\nofcolumns + % \getinsertionheight + % %\message{\insertionheight}\wait + % \advance\dimen0 \insertionheight + %\fi + \setbox\scratchbox\vbox % tricky met objecten ? + {\blank[\@@bkspacebefore] + \snaptogrid\vbox{\copy\floatbox}}% + \advance\dimen0 \ht\scratchbox + \advance\dimen0 .5\lineheight % needed because goal a bit higher + %\message{column: \the\count255; total: \the\dimen0; goal: \the\dimen2}\wait + \ifdim\dimen0>\dimen2 + \global\roomforfloatfalse + \else + \global\roomforfloattrue + \fi + \ifdim\wd\floatbox>\hsize + \showmessage\m!columns{11}\empty + \global\roomforfloatfalse + \fi + \egroup + \fi\fi} + +%D Flushing one float is done as soon as possible, i.e. +%D \type{\everypar}. This means that (at the moment) +%D sidefloats are not supported (overulled)! + +\newif\ifflushingcolumnfloats \flushingcolumnfloatstrue + +\def\doflushcolumnfloat + {\ifpostponecolumnfloats\else\ifflushingcolumnfloats\ifprocessingverbatim\else\ifsomefloatwaiting + \bgroup + \forgetall + \let\doflushcolumnfloat\relax + \getcolumnstatus\column\mofcolumns\total\dimen0\goal\dimen2\\% + \ifdim\dimen0>\zeropoint + \dogetfloat + \ifdim\wd\floatbox>\hsize + \doresavefloat + \else + %\setbox2=\vbox + % {\blank[\@@bkspacebefore] + % \snaptogrid\vbox{\copy\floatbox}% + % \blank[\@@bkspaceafter] + \setbox2=\vbox + {\blank[\@@bkspacebefore] + \snaptogrid\vbox{\copy\floatbox}}% + \advance\dimen0 \ht2 + \ifdim\dimen0>\dimen2 + \ifnum\mofcolumns<\nofcolumns + \advance\mofcolumns \plusone +%% bug %% \edef\currenttopcolumnbox{\getvalue{\@@topcol\the\count255}}% + \ifdim\ht\currenttopcolumnbox=\zeropoint + \global\setbox\currenttopcolumnbox\vbox + {\snaptogrid\vbox{\copy\floatbox} + \whitespace % nodig ? + \blank[\@@bkspaceafter]}% + \dimen4=\ht\currenttopcolumnbox + \advance\dimen4 \dp\currenttopcolumnbox + \global\advance\vsize -\dimen4 + \advance\dimen4 -\pagegoal + \global\pagegoal-\dimen4 + \showmessage\m!columns{12}a% + \else + \showmessage\m!columns{12}b% + \doresavefloat + \fi + \else + \showmessage\m!columns{12}c% + \doresavefloat + \fi + \else + \ifhmode{\setbox0\lastbox}\fi% waar is die er in geslopen + \par + \ifdim\prevdepth<\zeropoint \else % anders bovenaan kolom witruimte + \nobreak + \blank[\@@bkspacebefore] + \nobreak + \fi + \flushfloatbox + \blank[\@@bkspaceafter] + \fi + \fi + \fi + \egroup + \fi\fi\fi\fi} + +%D This one looks complicated. Upto \type{\nofcolumns} floats +%D are placed, taking the width of a float into account. This +%D routine can be improved on different ways: +%D +%D \startitemize[intro,packed] +%D \item taking into account some imaginary baseline, just to +%D get the captions in line +%D \item multipass flushing until as many floats are displaced +%D as possible +%D \stopitemize +%D +%D When handling lots of (small) floats spacing can get worse +%D because of lining out the columns. + +\def\doflushcolumnfloats + {\ifpostponecolumnfloats\else + \bgroup + \forgetall + \ifsomefloatwaiting + \dimen8\zeropoint + \dimen4\zeropoint + \count0\zerocount % count0 can be used local + \count2\nofcolumns % count2 can be used local + \dohandleallcolumns + {\ifnum\count0>\zerocount % the wide one's reserved space + \global\setbox\currenttopcolumnbox\vbox + {\snaptogrid\vbox + {\copy\currenttopcolumnbox + \hbox{\vphantom{\copy\floatbox}}} + \whitespace % nodig ? + \blank[\@@bkspaceafter]}% + \else + \dogetfloat + \ifdim\wd\floatbox>\finalcolumntextwidth % better somewhere else too + \global\setbox\floatbox\hbox to \finalcolumntextwidth{\hss\box\floatbox\hss}% + \fi % otherwise the graphic may disappear + \ifdim\wd\floatbox>\hsize + \dimen0\wd\floatbox + \advance\dimen0 \intercolumnwidth + \dimen2\hsize + \advance\dimen2 \intercolumnwidth + \advance\dimen0 .5pt % hm, why 1 + \advance\dimen2 .5pt % hm, why 2 + \divide\dimen0 \dimen2 + \count0\dimen0 + \advance\count0 \plusone + \ifnum\count0>\count2 + \doresavefloat + \count0\zerocount + \else + \dimen0=\count0\hsize + \advance\dimen0 \count0\intercolumnwidth + \advance\dimen0 -\intercolumnwidth + \global\setbox\floatbox\hbox to \dimen0 + %{\hss\hbox{\copy\floatbox}\hss}% + {\processaction[\@@bklocation] % how easy to forget + [ \v!left=>\copy\floatbox\hss, + \v!right=>\hss\copy\floatbox, + \s!default=>\hss\copy\floatbox\hss, + \s!unknown=>\hss\copy\floatbox\hss]}% + \fi + \showmessage\m!columns{13}\empty + \else + % \showmessage\m!columns{13}\empty + \fi + \ifdim\ht\floatbox>\zeropoint\relax + \global\setbox\currenttopcolumnbox\vbox + {\snaptogrid\vbox + {\copy\currenttopcolumnbox + \copy\floatbox} + \whitespace % nodig ? + \blank[\@@bkspaceafter]}% + \fi + \dimen6\ht\currenttopcolumnbox + \advance\dimen6 \dp\currenttopcolumnbox + \fi + \ifdim\dimen4<\ht\currenttopcolumnbox + \dimen4\ht\currenttopcolumnbox + \fi + \advance\dimen8 \dimen6 + \advance\count2 \minusone + \advance\count0 \minusone }% + \setvsize + \global\advance\vsize -\dimen8 + \global\pagegoal\vsize + \else + %\doflushfloats % does not snap! + \fi + \egroup + \fi} + +%D The next macro can be used to flush floats in the current +%D stream. No width checking is (yet) done. + +\def\insertcolumnfloats + {\doloop + {\ifsomefloatwaiting + \bgroup + \forgetall + % no check for width + \dogetfloat + \blank[\@@bkspacebefore] + \snaptogrid\vbox{\copy\floatbox} + \blank[\@@bkspaceafter] + \egroup + \else + \exitloop + \fi}} + +%D This were the multi||column routines. They can and need to +%D be improved but at the moment their behaviour is acceptable. +%D +%D One inprovement can be to normalize the height of floats +%D to $n\times$\type{\lineheight} with a macro like: +%D +%D \starttyping +%D \normalizevbox{...} +%D \stoptyping + +% border case, should fit on one page +% +% \startcolumns +% +% 1 \input tufte \par \plaatsfiguur{}{\omlijnd[breedte=\hsize,hoogte=3cm]{1}} +% 2 \input tufte \par \plaatsfiguur{}{\omlijnd[breedte=\hsize,hoogte=3cm]{2}} +% 3 \input tufte \par \plaatsfiguur{}{\omlijnd[breedte=\hsize,hoogte=3cm]{3}} +% +% \stopcolumns + +\def\setupcolumns + {\dosingleempty\dosetupcolumns} + +\def\dosetupcolumns[#1]% + {\getparameters[\??kl][#1]% + \nofcolumns\@@kln\relax + \processaction + [\@@klrule] + [ \v!on=>\let\betweencolumns\linebetweencolumns, + \v!off=>\let\betweencolumns\spacebetweencolumns, + \s!default=>\let\betweencolumns\spacebetweencolumns, + \s!unknown=>\let\betweencolumns\@@klrule]} + +\def\linebetweencolumns + {\bgroup + \starttextproperties + \ifdim\@@kldistance>\zeropoint + \dimen0=\@@kldistance + \else + \dimen0=\linewidth + \fi + \advance\dimen0 -\linewidth + \hskip.5\dimen0 + \vrule + \!!width\linewidth + \ifb@selinebottom\!!depth\strutdepth\fi + \hskip.5\dimen0\relax + \stoptextproperties + \egroup} + +\def\spacebetweencolumns + {\hskip\@@kldistance} + +\presetlocalframed[\??kl] + +\def\backgroundfinishcolumnbox + {\doifinsetelse\@@kloffset{\v!none,\v!overlay} + {\let\@@kloffset\!!zeropoint} + {\scratchdimen\@@kloffset + \advance\scratchdimen -\@@klrulethickness + \edef\@@kloffset{\the\scratchdimen}}% + \localframed + [\??kl] + [\c!strut=\v!no, + \c!width=\v!fit, + \c!height=\v!fit, + \c!align=]} + +\let\restorecolumnsettings\relax + +\definecomplexorsimpleempty\startcolumns + +\def\complexstartcolumns[#1]% %% \startcolumns + {\bgroup + \let\stopcolumns\egroup + \ifinsidecolumns + \else + \setupcolumns[#1]% + \ifnum\@@kln>1\relax + \whitespace + \begingroup + \doif\@@kloption\v!background + {\let\finishcolumnbox\backgroundfinishcolumnbox + \let\columntextoffset\@@kloffset}% + \ifx\@@klcommand\empty\else + \let\postprocesscolumnline\@@klcommand + \fi + \doifelsenothing\@@klheight + \heightencolumnsfalse + \heightencolumnstrue + \doifelse\@@kldirection\v!right + \reversecolumnsfalse + \reversecolumnstrue + \doifelse\@@klbalance\v!yes + \balancecolumnstrue + \balancecolumnsfalse +\installalign\v!yes {\stretchcolumnstrue \inheritcolumnsfalse}% todo: new key +\installalign\v!no {\stretchcolumnsfalse\inheritcolumnsfalse}% todo: new key +\installalign\v!text{\stretchcolumnsfalse\inheritcolumnstrue }% +\stretchcolumnsfalse +\inheritcolumnstrue +\doifsomething\@@klalign{\expanded{\setupalign[\@@klalign]}}% +% \processaction +% [\@@klalign] +% [ \v!yes=>\stretchcolumnstrue +% \inheritcolumnsfalse, +% \v!no=>\stretchcolumnsfalse +% \inheritcolumnsfalse, +% \v!text=>\stretchcolumnsfalse +% \inheritcolumnstrue]% + \nofcolumns=\@@kln + % + % probably more is needed, and how about nesting save's + % + \savecurrentblank + \savecurrentwhitespace + \def\restorecolumnsettings + {\boxmaxdepth\maxdimen % done elsewhere + \restorecurrentblank + \restorecurrentwhitespace}% + % + \edef\fixedcolumnheight{\@@klheight}% + \edef\minbalancetoplines{\@@klntop}% + \setuptolerance[\@@kltolerance]% %% \startcolumns + \setupblank[\@@klblank]% + \ifdim\ctxparskip>\zeropoint\relax + \setupwhitespace[\@@klblank]% + \fi + \def\stopcolumns + {\endmulticolumns + \global\insidecolumnsfalse + \endgroup + \egroup}% + \global\insidecolumnstrue + \beginmulticolumns + \fi + \fi} + +\installcolumnbreakhandler {MUL} \v!preference + {\goodbreak} + +\installcolumnbreakhandler {MUL} \v!yes + {\par % todo: since + {\testrulewidth\zeropoint\ruledvskip\textheight} % we misuse a + \penalty-200 % side effect + \vskip-\textheight + }% bugged : \prevdepth-\thousandpoint} % signals top of column to \blank + +%D New: only at start of columns; may change ! Rather +%D interwoven and therefore to be integrated when the multi +%D column modules are merged. (moved from cont-new.tex) + +\def\setupcolumnspan[#1]% + {\getparameters[\??ks][#1]} + +\presetlocalframed + [\??ks] + +\setupcolumnspan + [\c!n=2, + \c!offset=\v!overlay, + \c!frame=\v!off] + +\newbox\columnspanbox \let\postprocesscolumnspanbox\gobbleoneargument + +\def\dostartcolumnspan[#1]% + {\bgroup + \setupcolumnspan[#1]% + \forgetall + \ifinsidecolumns + \advance\hsize \intercolumnwidth + \hsize\@@ksn\hsize + \advance\hsize -\intercolumnwidth + \fi + \dowithnextbox + {\setbox\columnspanbox\flushnextbox + \ifinsidecolumns\wd\columnspanbox\hsize\fi + \postprocesscolumnspanbox\columnspanbox + \scratchdimen\ht\columnspanbox + \setbox\columnspanbox\hbox % depth to be checked, probably option! + {\localframed[\??ks][\c!offset=\v!overlay]{\box\columnspanbox}}% + \ht\columnspanbox\scratchdimen + \dp\columnspanbox\strutdp + \wd\columnspanbox\hsize + \ifinsidecolumns + \ifnum\@@ksn>1 + \setvsize + \dohandleallcolumns + {\ifnum\currentcolumn>\@@ksn\else + \global\setbox\currenttopcolumnbox=\vbox + {\ifnum\currentcolumn=1 + \snaptogrid\vbox{\copy\columnspanbox} + \else + \snaptogrid\vbox{\vphantom{\copy\columnspanbox}} + \fi}% + \wd\currenttopcolumnbox\hsize + \global\advance\vsize -\ht\currenttopcolumnbox + \fi} + \global\pagegoal\vsize + \else + \snaptogrid\vbox{\box\columnspanbox} + \fi + \else + \snaptogrid\vbox{\box\columnspanbox} + \fi + \endgraf + \ifvmode\prevdepth\strutdp\fi + \egroup} + \vbox\bgroup + %\topskipcorrection % becomes an option ! + \EveryPar{\begstrut\EveryPar{}}} % also ! + +\def\startcolumnspan + {\dosingleempty\dostartcolumnspan} + +\def\stopcolumnspan + {\egroup} + +\setupcolumns + [\c!n=2, + \c!ntop=1, + \c!command=, + \c!direction=\v!right, + \c!rule=\v!off, + \c!tolerance=\v!tolerant, + \c!distance=1.5\bodyfontsize, % influenced by switching + \c!height=, + \c!balance=\v!yes, + \c!align=\v!text, + \c!blank={\v!line,\v!fixed}, + \c!option=, + \c!rulethickness=\linewidth, + \c!offset=.5\bodyfontsize] + +%D Undocumented and still under development. + +\def\startsimplecolumns + {\dosingleempty\dostartsimplecolumns} + +\def\dostartsimplecolumns[#1]% + {\bgroup + \nopenalties + \getparameters[\??kl] + [\c!width=\hsize,\c!distance=1.5\bodyfontsize,% + \c!n=2,\c!lines=0,#1]% + \let\rigidcolumnlines\@@kllines + \setrigidcolumnhsize\@@klwidth\@@kldistance\@@kln + \setbox\scratchbox\vbox\bgroup + \forgetall} % \blank[\v!disable] + +\def\stopsimplecolumns + {\removebottomthings + \egroup + \rigidcolumnbalance\scratchbox + \egroup} + +\protect \endinput diff --git a/tex/context/base/page-mul.mkiv b/tex/context/base/page-mul.mkiv new file mode 100644 index 000000000..88ec7a5e7 --- /dev/null +++ b/tex/context/base/page-mul.mkiv @@ -0,0 +1,1751 @@ +%D \module +%D [ file=page-mul, % was: core-mul +%D version=1998.03.15, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Multi Column Output, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / 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 +%D OTR macro's were isolated in modules and column sets were +%D introduced, this module became part of the OTR modules. As +%D a result this module is no longer generic. It also needs +%D an overhaul. + +\unprotect + +% TO DO ! + +\let\OTRMULsetvsize \OTRONEsetvsize +\let\OTRMULsethsize \OTRONEsethsize +\let\OTRMULdopagecontents \OTRONEdopagecontents +\let\OTRMULfinalsidefloatoutput\OTRONEfinalsidefloatoutput % ??? +\let\OTRMULflushfloatbox \OTRONEflushfloatbox + +\let\OTRMULdosettopinserts \relax +\let\OTRMULdosetbotinserts \relax +\let\OTRMULdotopinsertions \relax +\let\OTRMULdobotinsertions \relax +\let\OTRMULdosetbothinserts \relax +\let\OTRMULflushsavedfloats \relax + +\let\OTRMULflushsidefloats \forgetsidefloats % \relax +\let\OTRMULsynchronizesidefloats\forgetsidefloats % \relax + +\newtoks \OTRMULoutput + +\def\OTRMULgotonextpage + {\ejectpage} + +\def\OTRMULgotonextpageX % will become obsolete + {\superejectpage} + +% check \count multiplications + +% some day try this in balancing routine +% +% \ifdim\pagetotal>\pagegoal +% \eject +% \else +% \goodbreak +% \fi + +%D The following macro's implement a multi||column output +%D routine. The original implementation was based on Donald +%D Knuth's implementation, which was adapted by Craig Platt to +%D support balancing of the last page. I gradually adapted +%D Platt's version to our needs but under certain +%D circumstances things still went wrong. I considered all +%D calls to Platt's \type{\balancingerror} as undesirable. + +%D This completely new implementation can handle enough +%D situations for everyday documents, but is still far from +%D perfect. While at the moment the routine doesn't support +%D all kind of floats, it does support: +%D +%D \startitemize[packed] +%D \item an unlimitted number of columns +%D \item ragged or not ragged bottoms +%D \item optional balancing without \type{\balancingerrors} +%D \item different \type{\baselineskips}, \type{\spacing}, +%D \type{\topskip} and \type{\maxdepth} +%D \item left- and right indentation, e.g. within lists +%D \item moving columns floats to the next column or page +%D \item handling of floats that are to wide for a columns +%D \stopitemize +%D +%D One could wonder why single and multi||columns modes are +%D still separated. One reason for this is that \TeX\ is not +%D suited well for handling multi||columns. As a result, the +%D single columns routines are more robust. Handling one +%D column as a special case of multi||columns is posible but at +%D the cost of worse float handling, worse page breaking, +%D worse etc. Complicated multi||column page handling should +%D be done in \cap{DTP}||systems anyway. +%D +%D There are three commands provided for entering and leaving +%D multi||column mode and for going to the next column: +%D +%D \interface \type{\beginmulticolumns} \\ \\ +%D \interface \type{\endmulticolumns} \\ \\ +%D \interface \type{\ejectcolumn} \\ \\ +%D +%D This routines are sort of stand||alone. They communicate +%D with the rest of \CONTEXT\ by means of some interface +%D macro's, which we only mention. +%D +%D \interface \type{\nofcolumns} \\ +%D the number of columns \\ +%D \interface \type{\minbalancetoplines} \\ +%D the minimum number op balanced top lines \\ +%D \interface \type{\betweencolumns} \\ +%D the stuff between columns \\ +%D \interface \type{\finaloutput{action}{box}} \\ +%D some kind of \type{\pagebody} and \type{\shipout} \\ +%D +%D \interface \type{\ifbalancecolumns} \\ +%D balancing the colums or not \\ +%D \interface \type{\ifstretchcolumns} \\ +%D ragging the bottom or not \\ +%D +%D \interface \type{\ifheightencolumns} \\ +%D fix the heigh tor not \\ +%D \interface \type{\fixedcolumnheight} \\ +%D the optional fixed height \\ +%D +%D \interface \type{\ifinheritcolumns} \\ +%D handle ragging or not \\ +%D \interface \type{\ifr@ggedbottom} \\ +%D use ragged bottoms \\ +%D \interface \type{\ifb@selinebottom} \\ +%D put the bottom line on the baseline \\ +%D \interface \type{\ifnormalbottom} \\ +%D put the bottom line at the baseline \\ +%D +%D \interface \type{\ifreversecolumns} \\ +%D reverse the order in wich columns are flushed \\ +%D +%D \interface \type{\usercolumnwidth} \\ +%D the calculated width of a column \\ +%D \interface \type{\columntextwidth} \\ +%D the maximum width of a column \\ +%D \interface \type{\columntextheight} \\ +%D the minimum width of a column \\ +%D +%D \interface \type{\spacingfactor} \\ +%D the spacing factor \\ +%D \interface \type{\bodyfontsize} \\ +%D the (local) bodyfontsize \\ +%D \interface \type{\openlineheight} \\ +%D the lineheight (including \type{\spacing}) \\ +%D +%D \interface \type{\EveryBodyFont} \\ +%D communication channel to font switching routines \\ +%D +%D \interface \type{\global\settopskip} \\ +%D set \type{\topskip} \\ +%D \interface \type{\setvsize} \\ +%D set \type{\vsize} and \type{\pagegoal} \\ +%D \interface \type{\sethsize} \\ +%D set \type{\hsize} \\ +%D +%D \interface \type{\flushcolumnfloats} \\ +%D push saved column floats (next page) \\ +%D \interface \type{\flushcolumnfloat} \\ +%D push saved column floats (next column) \\ +%D \interface \type{\setcolumnfloats} \\ +%D initialize column floats \\ +%D +%D \interface \type{\finishcolumnbox} \\ +%D do something special (a hook) \\ +%D \interface \type{\postprocesscolumnpagebox} \\ +%D do something with each columnbox (also a hook) \\ +%D \interface \type{\postprocesscolumnbox} \\ +%D do something with each columnbox (also a hook) \\ +%D \interface \type{\postprocesscolumnline} \\ +%D do something with each columnline (also a hook) \\ +%D \interface \type{\currentcolumn} \\ +%D the current column \\ +%D +%D These interface macro's are called upon or initialized +%D by the multi||column macro's. + +%D A lot of footnote stuff added! + +\def\finalcolumntextwidth {\makeupwidth} +\def\finalcolumntextheight {\textheight} +\def\columntextwidth {\makeupwidth} +\def\columntextheight {\textheight} +\def\usercolumnwidth {\textwidth} +\def\columntextoffset {\!!zeropoint} + +\def\fixedcolumnheight {\textheight} +\def\betweencolumns {\hskip\bodyfontsize} + +\let\setcolumnfloats \relax % in CONTEXT used for floats +\let\flushcolumnfloats \relax % in CONTEXT used for floats +\let\flushcolumnfloat \relax % in CONTEXT used for floats +\let\finishcolumnbox \relax % in CONTEXT used for backgrounds + +% %D In fact, the column height and width are set by means of +% %D two macro's. One can change their meaning if needed: +% +% \def\setcolumntextheight +% {\def\columntextheight{\teksthoogte}} +% +% \def\setcolumntextwidth +% {\def\columntextwidth{\zetbreedte}} + +%D Both macros are redefined in \CONTEXT\ when backgrounds +%D are applied to columns. The final values are used when +%D flushing the columns. + +\newtoks\singlecolumnout % remove that one + +%D It's more convenient to use \type {\columnwidth} instead +%D of messing around with boxes each time. + +\newdimen\columnwidth +\newdimen\gutterwidth + +\def\determinecolumnwidth + {\bgroup + \setbox\scratchbox\hbox + {\setcolumnhsize + \global\columnwidth\usercolumnwidth + \global\gutterwidth\intercolumnwidth}% + \egroup} + +%D Going to a new columns is done by means of a +%D \type{\ejectcolumn}. The following definition does not +%D always work. + +\def\ejectcolumn + {\goodbreak\showmessage\m!columns2\empty} + +%D The next macro should never be called so let's deal with it. +%D There were several solutions to these kind of errors. First +%D we check for a good breakpoint before firing up the +%D multi||column routine (\type{\break} or \type{\allowbreak}). +%D We do the same at the end of the routine +%D (\type{\allowbreak}). These allowances are definitely +%D needed! +%D +%D Some on first sight redundant calls to for instance +%D \type{\setvsize} in the flushing, splitting and balancing +%D macro's can definitely not be omitted! Some are just there +%D to handle situations that only few times arise. One of +%D those can be that the output routine is invoked before +%D everything is taken care of. This happens when we +%D flush (part of) the current page with an \type{\unvbox} +%D with a \type{\pagetotal}~$\approx$ \type{\pagegoal}. One +%D simply cannot balance columns that are just balanced. +%D +%D I hope one never sees the following message. Because it +%D took me a lot of time to develop the multi||columns +%D routines, every (although seldom) warning gives me the +%D creeps! + +\def\balancingerror + {\showmessage\m!columns3\empty + \finaloutput\unvbox\normalpagebox} + +\def\OTRMULsometopsfloat{\showmessage\m!columns4\empty \someherefloat} +\def\OTRMULsomebotsfloat{\showmessage\m!columns5\empty \someherefloat} + +\def\OTRMULsomeherefloat{\OTRONEsomeherefloat} + +%D The local column width is available in the dimension +%D register \type{\localcolumnwidth}, which is calculated as: + +\def\setcolumnhsize % beware, this one is available for use in macros + {\setbox\scratchbox\hbox{\parindent\zeropoint\betweencolumns}% + \intercolumnwidth\wd\scratchbox + \localcolumnwidth\columntextwidth + \advance\localcolumnwidth -\leftskip + \advance\localcolumnwidth -\rightskip + % new + \advance\localcolumnwidth -\colleftskip + \advance\localcolumnwidth -\colrightskip + % + \advance\localcolumnwidth -\nofcolumns\intercolumnwidth + \advance\localcolumnwidth \intercolumnwidth + \divide \localcolumnwidth \nofcolumns + \scratchdimen\columntextoffset + \multiply\scratchdimen \plustwo + \advance\localcolumnwidth -\scratchdimen + \usercolumnwidth\localcolumnwidth + \hsize\localcolumnwidth} % we don't do it \global + +%D Torture test: +%D +%D \startbuffer +%D \startbuffer[b] +%D \startcolumns +%D \input tufte +%D \stopcolumns +%D \stopbuffer +%D \typebuffer[b] \getbuffer[b] +%D +%D \startbuffer[b] +%D \startnarrower +%D \input tufte +%D \stopnarrower +%D \stopbuffer +%D \typebuffer[b] \getbuffer[b] +%D +%D \startbuffer[b] +%D \startcolumns \startnarrower +%D \input tufte +%D \stopnarrower \stopcolumns +%D \stopbuffer +%D \typebuffer[b] \getbuffer[b] +%D +%D \startbuffer[b] +%D \startnarrower \startcolumns +%D \input tufte +%D \stopcolumns \stopnarrower +%D \stopbuffer +%D \typebuffer[b] \getbuffer[b] +%D +%D \startbuffer[b] +%D \startcolumns \startnarrower[left] +%D \input tufte +%D \stopnarrower \stopcolumns +%D \stopbuffer +%D \typebuffer[b] \getbuffer[b] +%D +%D \startbuffer[b] +%D \startnarrower[left] \startcolumns +%D \input tufte +%D \stopcolumns \stopnarrower +%D \stopbuffer +%D \typebuffer[b] \getbuffer[b] +%D +%D \startbuffer[b] +%D \startnarrower \startcolumns \startnarrower +%D \input tufte +%D \stopnarrower\stopcolumns \stopnarrower +%D \stopbuffer +%D \typebuffer[b] \getbuffer[b] +%D +%D \startbuffer[b] +%D \startnarrower[left] \startcolumns \startnarrower +%D \input tufte +%D \stopnarrower\stopcolumns \stopnarrower +%D \stopbuffer +%D \typebuffer[b] \getbuffer[b] +%D \stopbuffer +%D +%D \start +%D \def\postprocesscolumnline#1{\ruledhbox{\strut\box#1}\hss} +%D \getbuffer +%D \stop + +%D One should be aware that when font related dimensions are +%D used in typesetting the in||between material, these +%D dimensions are influenced by bodyfont switches inside +%D multi||column mode. + +\newdimen\mcscratchdimen +\newcount\nofcolumnlines + +\chardef\multicolumnlinemethod\zerocount % 0: overshoot (old default), 1: tight +% \chardef\multicolumnlinemethod\plusone + +\def\getmulticolumnlines + {\mcscratchdimen-\columntextoffset + \multiply\mcscratchdimen \plustwo + \advance\mcscratchdimen \columntextheight + \ifdim\precolumnboxheight>\zeropoint + \advance\mcscratchdimen -\precolumnboxheight + \fi + \settotalinsertionheight + \advance\mcscratchdimen -\totalinsertionheight + \ifcase\multicolumnlinemethod \getnoflines\mcscratchdimen + \or \getrawnoflines\mcscratchdimen + \else \getrawnoflines\mcscratchdimen + \fi + % added 30/7/2004 + \ifnum\layoutlines>\zerocount \ifnum\noflines>\layoutlines + \noflines\layoutlines + \fi \fi + \nofcolumnlines\noflines} + +\def\multicolumnovershootratio{.5} % {\ifgridsnapping0\else.5\fi} + +\def\setcolumnvsize + {\getmulticolumnlines + \mcscratchdimen\nofcolumnlines\openlineheight + \advance\mcscratchdimen \multicolumnovershootratio\openlineheight % collect enough data + \global\vsize\nofcolumns\mcscratchdimen + \global\pagegoal\vsize} % let's do it only here + +%D It really starts here. After some checks and initializations +%D we change the output routine to continous multi||column +%D mode. This mode handles columns that fill the current and +%D next full pages. The method used is (more or less) +%D multiplying \type{\vsize} and dividing \type{\hsize} by +%D \type{\nofcolumns}. More on this can be found in the +%D \TeX book. We save the top of the current page in box +%D \type{\precolumnbox}. +%D +%D We manipulate \type{\topskip} a bit, just to be shure that +%D is has no flexibility. This has te be done every time a +%D font switch takles place, because \type{\topskip} can depend +%D on this. +%D +%D Watch the trick with the \type{\vbox}. This way we get the +%D right interlining and white space. + +\def\beginmulticolumns + {\par + \flushnotes + \xdef\precolumndepth{\the\prevdepth}% + \begingroup + % new + \leftskip1\leftskip + \rightskip1\rightskip + \edef\colleftskip {\the\leftskip}% + \edef\colrightskip{\the\rightskip}% + \leftskip\zeropoint + \rightskip\zeropoint + % + \dontshowcomposition + %\setcolumntextwidth\relax + %\setcolumntextheight\relax + \widowpenalty\zerocount % is gewoon beter + \clubpenalty \zerocount % zeker bij grids + \dopushcolumnfloats + \dimen0\dimexpr\pagetotal+\parskip+\openlineheight\relax + \ifdim\dimen0<\pagegoal + \allowbreak + \else + \break % Sometimes fails + \fi + \appendtoks\topskip1\topskip\to\everybodyfont + \the\everybodyfont % ugly here + \saveinterlinespace % ugly here + \initializecolumns\nofcolumns + \hangafter\zerocount + \hangindent\zeropoint + \everypar\emptytoks + \ifdim\pagetotal=\zeropoint \else + \verticalstrut + \vskip-\struttotal + \fi + \global\savedpagetotal\pagetotal + \global\singlecolumnout\output + %\global\output{\global\setbox\precolumnbox\vbox{\unvbox\normalpagebox}}% + \global\output{\global\setbox\precolumnbox\vbox{\dotopinsertions\unvbox\normalpagebox}}% + \eject % no \holdinginserts=1, can make footnote disappear ! + \global\precolumnboxheight\ht\precolumnbox + \global\output{\continuousmulticolumnsout}% + \setcolumnfloats + \dohandleallcolumns + {\global\setbox\currenttopcolumnbox\emptybox}% + \checkbegincolumnfootnotes + \activateotr{MUL}{ONE}% todo ! ! ! ! + \let\sethsize\setcolumnhsize + \let\setvsize\setcolumnvsize + \sethsize + \setvsize + \showcomposition} + +%D When we leave the multi||column mode, we have to process the +%D not yet shipped out part of the columns. When we don't +%D balance, we simply force a continuous output, but a balanced +%D output is more tricky. + +%D First we try to fill up the page and when all or something +%D is left we try to balance things. This is another useful +%D adaption of the ancesters of these macro's. It takes some +%D reasoning to find out what happens and maybe I'm making +%D some mistake, but it works. +%D +%D Voiding box \type{\precolumnbox} is sometimes necessary, +%D e.g. when there is no text given between \type{\begin..} +%D and \type{\end..}. The \type{\par} is needed! + +\chardef\multicolumnendsyncmethod\plusone % 1: old sync 2: new sync (cont-loc/project) / may fail ! ! ! ! + +\def\endmulticolumns + {%\par + \ifnum\multicolumnendsyncmethod=\plustwo + \synchronizeoutput + \else + % don't combine these + \vskip\lineheight + \vskip-\lineheight % take footnotes into account + \fi + \dontshowcomposition + \doflushcolumnfloat % added recently + %\doflushcolumnfloats % no, since it results in wrong top floats + \flushnotes % before start of columns + \par + \ifbalancecolumns + \ifnum\multicolumnendsyncmethod=\plusone + \global\output{\continuousmulticolumnsout}% + \goodbreak + \fi + \global\output{\balancedmulticolumnsout}% + \else + \goodbreak + \fi + \eject % the prevdepth is important, try e.g. toclist in + \prevdepth\zeropoint % columns before some noncolumned text text + \global\output\singlecolumnout + \global\output{\the\mainoutput}% % % % % todo + \ifvoid\precolumnbox\else + \unvbox\precolumnbox + \fi + \global\precolumnboxheight\zeropoint + \endgroup % here + \nofcolumns\plusone + \setvsize % the outer one! + \synchronizeoutput % new may 2004 / we need to: \pagegoal\vsize + \checkendcolumnfootnotes + \dosomebreak\allowbreak + \dopopcolumnfloats} + +%D Because some initializations happen three times, we +%D defined a macro for them. Erasing \type{\everypar} is +%D needed because we don't want anything to interfere. + +\def\setmulticolumnsout + {\everypar\emptytoks + \dontcomplain + \settopskip + \setmaxdepth + \topskip1\topskip + \splittopskip\topskip + \splitmaxdepth\maxdepth + \boxmaxdepth\maxdepth % dangerous + \emergencystretch\zeropoint\relax} % sometimes needed ! + +%D Flushing the page comes to pasting the columns together and +%D appending the result to box \type{\precolumnbox}, if not +%D void. I've seen a lot of implementations in which some skip +%D was put between normal text and multi||column text. When we +%D don't want this, the baselines can be messed up. I hope the +%D seemingly complicated calculation of a correction +%D \type{\kern} is adequate to overcome this. Although not +%D watertight, spacing is taken into account and even multiple +%D mode changes on one page go well. But cross your fingers and +%D don't blame me. +%D +%D One of the complications of flushing out the boxes is that +%D \type{\precolumnbox} needs to be \type{\unvbox}'ed, otherwise +%D there is too less flexibility in the page when using +%D \type{\r@ggedbottom}. It took a lot of time before these +%D kind of problems were overcome. Using \type{\unvbox} at the +%D wrong moment can generate \type{\balancingerror}'s. +%D +%D One can use the macros \type {\maxcolumnheight} and \type +%D {\maxcolumndepth} when generating material between columns +%D as well as postprocessing column lines. + +\let\maxcolumnheight=\zeropoint +\let\maxcolumndepth =\zeropoint + +\newbox\columnpagebox + +\def\setmaxcolumndimensions + {\let\maxcolumnheight\!!zeropoint + \let\maxcolumndepth \!!zeropoint + \dohandleallcolumns + {\ifdim\ht\currentcolumnbox>\maxcolumnheight + \edef\maxcolumnheight{\the\ht\currentcolumnbox}% + \fi + \ifdim\dp\currentcolumnbox>\maxcolumndepth + \edef\maxcolumndepth{\the\dp\currentcolumnbox}% + \fi}} + +\chardef\multicolumntopflushmethod\plusone % 0: no correction, 1: correction when topstuff, 2: correction, 3: correction++ +\chardef\multicolumntopalignmethod\plustwo % 0: nothing, 1: force grid, 2: follow grid + +\def\flushprecolumnboxnogrid + {\unvbox\precolumnbox} + +\def\flushprecolumnboxongrid + {\scratchdimen\savedpagetotal + \advance\scratchdimen -\ht\precolumnbox + \advance\scratchdimen -\dp\precolumnbox + \advance\scratchdimen -\topskip + \box\precolumnbox + \kern\scratchdimen} + +\newconditional\someprecolumncontent + +\def\flushcolumnedpage#1% + {\bgroup + \ifvoid\precolumnbox + \setfalse\someprecolumncontent % will be set elsewhere + \else + \settrue\someprecolumncontent + \mkprocessboxcontents\precolumnbox + \fi + \forgetall + \setmulticolumnsout + \showcomposition + \setmaxcolumndimensions + \dohandleallcolumns + {\mkprocesscolumncontents\currentcolumnbox}% + \postprocesscolumns + \dohandleallcolumns % \hbox i.v.m. \showcomposition + {\global\setbox\currentcolumnbox\hbox to \localcolumnwidth + {\box\currentcolumnbox + \global\wd\currentcolumnbox\localcolumnwidth + \ifheightencolumns + \global\ht\currentcolumnbox\fixedcolumnheight + \fi}}% + \setmaxcolumndimensions + \overlaycolumnfootnotes + \setbox\columnpagebox\vbox + {\hbox to \finalcolumntextwidth + {\hskip\colleftskip\relax % new, \relax needed + \ifreversecolumns + \@EA\dohandlerevcolumns + \else + \@EA\dohandleallcolumns + \fi + {\finishcolumnbox{\hbox + {\ifx\finishcolumnbox\relax\else\strut\fi + \box\currentcolumnbox}}% + \hfil}% + \unskip + \hskip\colrightskip}}% new + \scratchdimen\zeropoint + \dohandleallcolumns + {\ifdim-\ht\currenttopcolumnbox<\scratchdimen + \scratchdimen-\ht\currenttopcolumnbox + \fi + \global\setbox\currenttopcolumnbox\emptybox}% + \advance\scratchdimen \ht\columnpagebox + \setbox\scratchbox\hbox to \columntextwidth + {\vrule + \!!width\zeropoint + \!!height\scratchdimen + \!!depth\dp\columnpagebox + \dostepwiserecurse2\nofcolumns1{\hfil\betweencolumns}\hfil}% + \setbox\columnpagebox\hbox + {\box\columnpagebox + \hskip-\columntextwidth + \box\scratchbox}% + \postprocesscolumnpagebox % new, acts upon \box\columnpagebox + \ifconditional\someprecolumncontent + \settrue\someprecolumncontent + % next some incredible crappy code + \ifcase\multicolumntopalignmethod + \flushprecolumnboxnogrid % not on grid + \or + \flushprecolumnboxongrid % force on grid + \else\ifgridsnapping % somehow this junk fails in pascal + \flushprecolumnboxongrid % obey grid settings, force on grid + \else + \flushprecolumnboxnogrid % ignore grid settings, not on grid + \fi \fi + \fi + \global\precolumnboxheight\zeropoint + \setvsize + \dosomebreak\nobreak % hm, only needed when topstuff + \ifgridsnapping + \else + \ifcase\multicolumntopflushmethod + % sometimes method 1 goes wrong, so we need a way out; best sort this out + % when we run into it again + \or + % \input tufte \startcolumns \showbaselines \input tufte \stopcolumns \input tufte + \ifconditional\someprecolumncontent +% \scratchdimen\topskip +% \advance\scratchdimen -\openstrutheight +% \nointerlineskip +% \vskip-\scratchdimen + \nointerlineskip + \vskip\dimexpr\openstrutheight-\topskip\relax + \fi + \or +% \scratchdimen\topskip +% \advance\scratchdimen -\openstrutheight +% \nointerlineskip +% \vskip-\scratchdimen + \nointerlineskip + \vskip\dimexpr\openstrutheight-\topskip\relax + \or + % untested but maybe handy +% \scratchdimen\topskip +% \advance\scratchdimen -\openstrutheight +% \nointerlineskip +% \vskip-\scratchdimen +% \vskip-\lineheight +% \vbox{\strut}% + \nointerlineskip + \vskip\dimexpr\openstrutheight-\topskip-\lineheight\relax + \vbox{\strut}% + \fi + \fi + \prevdepth\openstrutdepth + \nointerlineskip + \dp\columnpagebox\zeropoint + \global\finalcolumnheights\ht\columnpagebox + \getnoflines\finalcolumnheights + \global\finalcolumnlines\noflines + \ifcase#1\else + % messy correction, we need to rewrite this module (newcolumns) + \setbox\columnpagebox\vbox + {\offinterlineskip + \scratchdimen\ht\columnpagebox + \advance\scratchdimen\dp\columnpagebox % we probably lost that one already + \box\columnpagebox + \vskip-\scratchdimen}% + \scratchdimen\noflines\openlineheight + \advance\scratchdimen-\openstrutdepth + \advance\scratchdimen-\openlineheight + \advance\scratchdimen\topskip + \ht\columnpagebox\scratchdimen + \dp\columnpagebox\openstrutdepth + % end of mess + \fi + \box\columnpagebox + \egroup} + +%D In case one didn't notice, finaly \type{\finishcolumnbox} is +%D applied to all boxes. One can use these hooks for special +%D purposes. +%D +%D Once upon a time I wanted to manipulate the individual lines +%D in a column. This feature is demonstrated in the two examples +%D below. +%D +%D \startbuffer +%D \def\postprocesscolumnline#1% or \postprocesscolumnbox +%D {\ruledhbox{\box#1}\hss} +%D +%D \startcolumns[n=4] +%D \dorecurse{25}{line: \recurselevel\par} +%D \stopcolumns +%D \stopbuffer +%D +%D \typebuffer +%D +%D Here we show the natural width of the lines: +%D +%D {\getbuffer} +%D +%D The next example does a bit more advanced manipulation: +%D +%D \startbuffer +%D \def\postprocesscolumnline#1% +%D {\ifodd\currentcolumn +%D \hfill\unhbox#1\relax +%D \else +%D \relax\unhbox#1\hfill +%D \fi} +%D +%D \startcolumns[n=4] +%D \dorecurse{25}{line \recurselevel\par} +%D \stopcolumns +%D \stopbuffer +%D +%D \typebuffer +%D +%D Here we also see an application of \type{\currentcolumn}: +%D +%D {\getbuffer} +%D +%D This feature is implemented using the reshape macros +%D presented in \type{supp-box}. + +\def\postprocesscolumns + {\ifx\postprocesscolumnline\undefined \else + \dohandleallcolumns + {\global\setbox\currentcolumnbox\vtop + {\beginofshapebox + \unvbox\currentcolumnbox + \unskip\unskip + \endofshapebox + \reshapebox + {\dimen0\ht\shapebox + \dimen2\dp\shapebox + \setbox\shapebox\hbox to \hsize + {\postprocesscolumnline\shapebox}% + \ht\shapebox\dimen0 + \dp\shapebox\dimen2 + \box\shapebox}% + \flushshapebox + \everypar\emptytoks + \parskip\zeropoint % = \forgetall + \verticalstrut + \vskip-\struttotal + \vfil}}% + \fi + \ifx\postprocesscolumnbox\undefined \else + \dohandleallcolumns + {\global\setbox\currentcolumnbox\hbox + {\postprocesscolumnbox\currentcolumnbox}} + \fi} + +%D We default to doing nothing! + +\let\postprocesscolumnline =\undefined +\let\postprocesscolumnbox =\undefined +\let\postprocesscolumnpagebox=\relax + +%D \macros +%D {reversecolumnstrue} +%D +%D We can force the macro that takes care of combining +%D the columns, to flush them in the revere order. Of +%D course, by default we don't reverse. + +\newif\ifreversecolumns + +%D Here comes the simple splitting routine. It's a bit +%D longer than expected because of ragging bottoms or not. +%D This part can be a bit shorter but I suppose that I will +%D forget what happens. The splitting takes some already +%D present material (think of floats) into account! +%D +%D First we present some auxiliary routines. Any material, +%D like for instance floats, that is already present in the +%D boxes is preserved. + +\def\splitcolumn#1from \box#2to \dimen#3 top \box#4% + {\bgroup + \ifdim\ht#4>\zeropoint + \dimen0\dimen#3\relax + \dimen2\dimen0 + \advance\dimen0 -\ht#4% + \columnfootnotecorrection{#1}{\dimen0}% + \setbox0\vsplit#2 to \dimen0 + \global\setbox#1\vbox to \dimen2 + {\ifgridsnapping + \dimen0-\openstrutheight + \advance\dimen0 \topskip + \vskip\dimen0\copy#4\vskip-\dimen0 + \else + \unvcopy#4% + \fi + \fuzzysnappedbox\unvbox0 + \fakecolumnfootnotes{#1}}% + \else + \ifcase\clevernotes + \global\setbox#1\vsplit#2 to \dimen#3% + \global\setbox#1\vbox + {\fuzzysnappedbox\unvbox{#1}}% % or \box ? + \else + \columnfootnotecorrection{#1}{\dimen#3}% + \setbox0\vsplit#2 to \dimen#3% + \global\setbox#1\vbox to \dimen#3% + {\fuzzysnappedbox\unvbox0 + \fakecolumnfootnotes{#1}}% + \fi + \fi + \egroup} + +\def\splitcurrentcolumn from \box#1to \dimen#2% + {\splitcolumn\currentcolumnbox from \box#1 to \dimen#2 top \box\currenttopcolumnbox} + +\def\splitfirstcolumn from \box#1to \dimen#2% + {\splitcolumn\firstcolumnbox from \box#1 to \dimen#2 top \box\firsttopcolumnbox} + +\def\splitlastcolumn from \box#1to \dimen#2% + {\global\setbox\lastcolumnbox\vbox + {\unvcopy\lasttopcolumnbox + \fuzzysnappedbox\unvbox{#1}% + \fakecolumnfootnotes\lastcolumnbox}} + +%D NEW: still to be documented. + +\def\fakecolumnfootnotes#1% + {\relax + \ifcase\clevernotes\else + \ifnum#1=\lastcolumnbox + \fakenotes + \fi + \fi} + +\def\columnfootnotecorrection#1#2% + {\relax + \ifcase\clevernotes + % page notes + \or + \ifnum#1=\firstcolumnbox\relax + \calculatetotalclevernoteheight + \advance#2 -\totalnoteheight + \fi + \else + \ifnum#1=\lastcolumnbox\relax + \calculatetotalclevernoteheight + \advance#2 -\totalnoteheight + \fi + \fi} + +\def\overlaycolumnfootnotes + {\relax + \ifcase\clevernotes + % page notes + \else + \checknotepresence + \ifnotespresent + % the note box has the depth of the notefont + % because a column (i.e. first column has no depth, + % we need to anchor top down) + \bgroup + \ifcase\clevernotes\or + \getmulticolumnlines + \advance\nofcolumnlines \minustwo + \scratchdimen\nofcolumnlines\lineheight + \advance\scratchdimen \topskip + \setbox0\hbox + {\lower\scratchdimen\vbox{\placenoteinserts}}% + \ht0=\openstrutheight % \strutht + \dp0=\openstrutdepth % \strutdp + \wd0=\zeropoint + \scratchdimen\ht\firstcolumnbox + \global\setbox\firstcolumnbox\vbox to \scratchdimen + {\box\firstcolumnbox + \vskip-\scratchdimen + \box0}% + \else + % maybe here also \getmulticolumnlines + \scratchdimen\ht\firstcolumnbox + \advance\scratchdimen -\openstrutdepth % \strutdp + \getnoflines\scratchdimen + \advance\noflines \minustwo + \scratchdimen\noflines\lineheight + \advance\scratchdimen \topskip + \setbox0\hbox + {\lower\scratchdimen\vbox{\placenoteinserts}}% + \ht0=\openstrutheight % \strutht + \dp0=\openstrutdepth % \strutdp + \wd0=\zeropoint + \scratchdimen\ht\lastcolumnbox + \global\setbox\lastcolumnbox\vbox to \scratchdimen + {\box\lastcolumnbox + \vskip-\scratchdimen + \box0}% + \fi + \egroup + \fi + \fi} + +%D Here comes the routine that splits the long box in columns. +%D The macro \type{\flushcolumnfloats} can be used to flush +%D either floats that were present before the multi||column +%D mode was entered, or floats that migrate to next columns. +%D Flushing floats is a delicate process. + +\def\continuousmulticolumnsout + {\bgroup + \forgetall + \setmulticolumnsout + \dontshowcomposition +% \dimen0=\columntextheight +% \advance\dimen0 -\precolumnboxheight +% \settotalinsertionheight +% \advance\dimen0 -\totalinsertionheight +% \ifgridsnapping % evt altijd, nog testen +% \getnoflines{\dimen0} +% \dimen0=\noflines\openlineheight +% \fi + \getmulticolumnlines + \dimen0=\nofcolumnlines\openlineheight + \dohandleallcolumns + {\splitcurrentcolumn from \box\normalpagebox to \dimen0}% + \setbox\restofpage\vbox{\unvbox\normalpagebox}% + \ifinheritcolumns + \ifr@ggedbottom % vreemd + \dohandleallcolumns + {\global\setbox\currentcolumnbox\vbox to \ht\firstcolumnbox + {\dimen0\dp\currentcolumnbox + \unvbox\currentcolumnbox + \vskip-\dimen0 + \vskip\openstrutdepth % \strutdp + \prevdepth\openstrutdepth % \strutdp + \vfill}}% + \ifbottomnotes \else + \dimen0\ht\firstcolumnbox + \fi + \fi + \ifn@rmalbottom + \advance\dimen0 \maxdepth + \dohandleallcolumns + {\global\setbox\currentcolumnbox\vbox to \dimen0 + {\unvbox\currentcolumnbox}}% + \fi + \ifb@selinebottom + % the columns are on top of the baseline + \fi + \else + \dohandleallcolumns + {\global\setbox\currentcolumnbox\vbox to \dimen0 + {\ifstretchcolumns + \unvbox\currentcolumnbox + \else + \unvbox\currentcolumnbox % wel of niet \unvbox ? + \vfill + \fi}}% + \dohandleallcolumns + {\global\ht\currentcolumnbox\dimen0}% + \fi + \setbox\precolumnbox\vbox{\flushcolumnedpage\zerocount}% + \finaloutput\box\precolumnbox + \sethsize + \setvsize + \flushcolumnfloats + \unvbox\restofpage + % \penalty\outputpenalty % gaat gruwelijk mis in opsommingen + \egroup} + +%D And this is the balancing stuff. Again, part of the routine +%D is dedicated to handling ragged bottoms, but here we also +%D see some handling concerning the stretching of columns. +%D We set \type{\widowpenalty} at~0, which enables us to +%D balance columns with few lines. The use of \type{\box2} and +%D \type{\box4} garantees a more robust check when skips are +%D used. + +\def\multicolumnsbalancemax{250} % 100 is too small when floats are involved + +\def\balancedmulticolumnsout + {\bgroup + \setmulticolumnsout + \dontshowcomposition + \widowpenalty\zerocount + \setbox0\vbox{\unvbox\normalpagebox}% +\ifdim\ht0>\openlineheight % at least one line + \ifnum\minbalancetoplines<2 % balance anyway + \donetrue + \else % check criterium to available lines + \getnoflines{\ht0}% + \divide\noflines \nofcolumns \relax + \ifnum\noflines<\minbalancetoplines \relax + \dimen0\ht0 + \advance\dimen0 \ht\firsttopcolumnbox + \advance\dimen0 \openlineheight \relax % let's play safe + \ifdim\dimen0>\columntextheight % column exceeding text height + \donetrue + \else % it seems to fit + \donefalse + \fi + \else % balance indeed + \donetrue + \fi + \fi +\else % balancing does not make sense + \donefalse +\fi +\ifdone % start balancing + %\ifdim\ht0>\openlineheight + \dimen0\ht0 + \advance\dimen0 \topskip + \advance\dimen0 -\baselineskip + \dohandleallcolumns + {\advance\dimen0 \ht\currenttopcolumnbox}% + \divide\dimen0 \nofcolumns + \vbadness\!!tenthousand\relax + \count255=\zerocount + \bgroup + \ifgridsnapping + \dimen2\lineheight + \else + \dimen2=\onepoint % RUBISH + \dimen2=\spacingfactor\dimen2 + \fi + \doloop + {\advance\count255 \plusone + \global\setbox\restofpage\copy0\relax + \splitfirstcolumn from \box\restofpage to \dimen0 + \dohandlemidcolumns + {\splitcurrentcolumn from \box\restofpage to \dimen0}% + \splitlastcolumn from \box\restofpage to \dimen0 + \setbox2\vbox{\unvcopy\firstcolumnbox}% + \dimen4\zeropoint + \dohandleallcolumns + {\setbox4\vbox + {\unvcopy\currentcolumnbox + %rather new, test this on pdftex-z.tex + \unpenalty\unskip\unpenalty\unskip}% maybe better in main splitter + %\writestatus{balance}{\the\currentcolumnbox: \the\ht4}% +% \dimen6\ht4 \ifdim\dimen6>\dimen4 \dimen4=\dimen6 \fi}% + \ifdim\ht4>\dimen4 \dimen4=\ht4 \fi}% + \advance\dimen4 -.0005pt % get rid of accurracy problem, pretty new + \ifnum\count255>\multicolumnsbalancemax\relax + \exitloop + \else\ifdim\dimen4>\ht2 + \advance\dimen0 \dimen2\relax + \else + \exitloop + \fi\fi}% + \dohandleallcolumns + {\global\setbox\currentcolumnbox\vbox{\unvcopy\currentcolumnbox}}% NIEUW + \ifnum\count255>\multicolumnsbalancemax\relax + \showmessage\m!columns7\empty + \else + \showmessage\m!columns8{\the\count255\space}% + \fi + \egroup + \ifinheritcolumns + % We cannot assume that the first column is the tallest, if + % only because we may have an aborted balance (one line in the + % first column and a graphic in the second one). + % + % \dimen0\ht\firstcolumnbox + % \dimen2\ht\firstcolumnbox + % + \dimen0=\zeropoint + \dohandleallcolumns + {\ifdim\ht\currentcolumnbox>\dimen0 + \dimen0=\ht\currentcolumnbox + \fi}% + \dimen2\dimen0 + % so far + \advance\dimen2 -\openlineheight + \dohandleallcolumns + {\dimen4\ht\currentcolumnbox + \dimen6=10\openlineheight % funny value + \global\setbox\currentcolumnbox\vbox to \dimen0 + {\unvbox\currentcolumnbox + \ifdim\dimen4>\dimen6 + \ifdim\dimen4<\dimen0 + \ifdim\dimen4>\dimen2 + \vskip\zeropoint % !! + \else + \vskip\openlineheight + \vfill + \fi + \else + \vskip\zeropoint + \fi + \else + \vskip\openlineheight + \vfill + \fi}}% + \else + \bgroup + \ifstretchcolumns + \dimen0\ht\firstcolumnbox + \dimen2=\bottomtolerance\ht\firstcolumnbox + \setbox0\vbox{\unvcopy\lastcolumnbox}% + \advance\dimen0 -\ht0\relax + \advance\dimen0 -\dp0\relax + \ifdim\dimen0>\openlineheight\relax + \ifdim\dimen0>\dimen2\relax + % \stretchcolumnsfalse % beter goed slecht dan slecht goed + \showmessage\m!columns9\empty + \fi + \fi + \fi + \dohandleallcolumns + {\global\setbox\currentcolumnbox\vbox to \ht\firstcolumnbox + {\ifstretchcolumns + \unvbox\currentcolumnbox + \else + \box\currentcolumnbox + \vfill + \fi}}% + \egroup + \fi + \else + % a one liner is not properly handled here, so best rewrite the text then + \showmessage\m!columns{10}\empty + \global\setbox\firstcolumnbox\vbox{\unvbox0}% + \fi + \global\output{\balancingerror}% + \b@selinebottomtrue % forces depth in separation rule + \flushcolumnedpage\plusone + \multicolumnseject + \egroup} + +\def\multicolumnseject + {\ifdim\pagetotal>\textheight + \eject % new + \else + \allowbreak + \fi} + +%D The multicolumn mechanism is incorporated in a \CONTEXT\ +%D interface, which acts like: +%D +%D \starttyping +%D \startcolumns[n=4,balance=no] +%D some text +%D \stopcolumns +%D \stoptyping +%D +%D The setup is optional. The default behaviour of columns +%D can be set up with: +%D +%D \starttyping +%D \setupcolumns +%D [n=2, +%D balance=yes] +%D \stoptyping +%D +%D In this case, stretching is according to the way it's +%D done outside columns (\type{\inheritcolumnstrue}). Also +%D we can setup the \type{tolerance} within a column, the +%D \type{distance} between columns and the fixed +%D \type{height} of a column. + +%D Multi||column output: the float routines +%D +%D Here come the routines that handle the placement of column +%D floats. Floats that are to big migrate to the next +%D column. Floats that are too wide, migrate to the top of the +%D next page, where they span as much columns as needed. +%D Floats that are left over from outside the multi||column +%D mode are flushed first. In macro \type{\finaloutput} the +%D topfloats that are left from previous text should be set. +%D +%D When there are some floats in the queue, we inhibit the +%D flushing of floats on top of columns. The number of +%D waiting floats is preswent in \type{\savednoftopfloats} and +%D is saved. As long as there are floats waiting, the topfloats +%D are places as if we are outside multi||column mode. This is +%D neccessary for e.g. multicolumn lists. +%D +%D When all those floats are flushed, we switch to the local +%D flushing routine. + +\def\dopushcolumnfloats + {\ifsomefloatwaiting + \showmessage\m!columns6{\the\savednoffloats}% + \global\setbox\savedfloatlist\box\floatlist + \xdef\dopopcolumnfloats + {\global\savednoffloats\the\savednoffloats + \global\setbox\floatlist\box\savedfloatlist + \global\noexpand\somefloatwaitingtrue}% + \global\savednoffloats\zerocount + \global\somefloatwaitingfalse + \else + \global\let\dopopcolumnfloats\relax + \fi} + +\let\dopopcolumnfloats\relax + +% \def\setcolumnfloats % messy as it adapts everypar +% {\xdef\globalsavednoffloats{\the\savednoffloats}% +% \ifnum\globalsavednoffloats>\zerocount +% \setglobalcolumnfloats % hm, we always push so this never happens +% \else +% \setlocalcolumnfloats +% \fi} + +\def\setcolumnfloats % messy as it adapts everypar, we need to adapt this + {\setlocalcolumnfloats} + +\newconditional\onlylocalcolumnfloats % temp hack as we will redo floats (grid snapping is also messy now) + +\def\OTRMULdocheckiffloatfits{\ifconditional\onlylocalcolumnfloats\docolumnroomfloat \else\relax \fi} +\def\OTRMULdosetbothinserts {\ifconditional\onlylocalcolumnfloats\relax \else\OTRONEdosetbothinserts\fi} +\def\OTRMULdotopinsertions {\ifconditional\onlylocalcolumnfloats\relax \else\OTRONEdotopinsertions \fi} +\def\OTRMULdoflushfloats {\ifconditional\onlylocalcolumnfloats\doflushcolumnfloats\else\OTRONEdoflushfloats \fi} + +\def\setlocalcolumnfloats + {\settrue\onlylocalcolumnfloats + \everypar{\flushnotes\flushcolumnfloat\flushmargincontents\checkindentation}% + \let\flushcolumnfloat\doflushcolumnfloat + \let\flushcolumnfloats\doflushcolumnfloats} + +\def\setglobalcolumnfloats + {\setfalse\onlylocalcolumnfloats + \everypar\emptytoks + \let\flushcolumnfloat\relax + \let\flushcolumnfloats\noflushcolumnfloats} + +\def\noflushcolumnfloats + {\bgroup + \xdef\localsavednoffloats{\the\savednoffloats}% + \global\savednoffloats\globalsavednoffloats + \dotopinsertions + \xdef\globalsavenoffloats{\the\savednoffloats}% + \ifnum\globalsavednoffloats=\zerocount + \setlocalcolumnfloats + \fi + \global\savednoffloats\localsavednoffloats + \egroup} + +%D We need to calculate the amount of free space in a columns. +%D When there is not enough room, we migrate the float to the +%D next column. These macro's are alternatives (and +%D look||alikes) of \type{\doroomfloat}. When a float is to +%D wide, for one column, it is moved to the top of the next +%D page. Of course such moved floats have to be taken into +%D account when we calculate the available space. It's a pitty +%D that such things are no integral part of \TEX. + +\def\getcolumnstatus\column#1\total#2\goal#3\\% + {\dimen0=\ifdim\pagegoal<\maxdimen \pagetotal \else \zeropoint \fi + \dimen2=\zeropoint + \count255=\zerocount + \dimen8=\columntextheight + \advance\dimen8 -\precolumnboxheight + \def\dogetcolumnstatus + {\advance\count255 \plusone + \advance\dimen2 \ht\currenttopcolumnbox + \advance\dimen2 \dp\currenttopcolumnbox + \dimen4\dimen2 + \advance\dimen4 \dimen0 + \dimen6=\count255\dimen8 + \ifdim\dimen4>\dimen6 + \else + \let\dogetcolumnstatus\relax + \fi}% + \dohandleallcolumns{\dogetcolumnstatus}% + \ifnum\count255=0 \count255=1 \fi + #1=\count255 + #2=\dimen4 + #3=\dimen6 } + +\def\getinsertionheight + {\ifdim\pagegoal<\maxdimen + \bgroup + \dimen0=\columntextheight + \advance\dimen0 -\pagegoal + \xdef\insertionheight{\the\dimen0}% + \egroup + \else + \global\let\insertionheight\zeropoint + \fi} + +\def\docolumnroomfloat + {\ifpostponecolumnfloats + \global\roomforfloatfalse + \else\ifnofloatpermitted + \global\roomforfloatfalse + \else + \bgroup + \getcolumnstatus\column\count255\total\dimen0\goal\dimen2\\% + \dofloatsgetinfo{text}% + \setbox\scratchbox\vbox % tricky met objecten ? + {\blank[\@@bkspacebefore] + \snaptogrid\vbox{\vskip\floatheight}}% copy? + \advance\dimen0\dimexpr\ht\scratchbox+2\openlineheight+.5\lineheight\relax\relax % needed because goal a bit higher + \ifdim\dimen0>\dimen2 + \global\roomforfloatfalse + \else + \global\roomforfloattrue + \fi + \ifdim\floatwidth>\hsize + \showmessage\m!columns{11}\empty + \global\roomforfloatfalse + \fi + \egroup + \fi\fi} + +%D Flushing one float is done as soon as possible, i.e. +%D \type{\everypar}. This means that (at the moment) +%D sidefloats are not supported (overulled)! + +\newif\ifflushingcolumnfloats \flushingcolumnfloatstrue + +\def\doflushcolumnfloat + {\ifpostponecolumnfloats\else\ifflushingcolumnfloats\ifprocessingverbatim\else\ifsomefloatwaiting + \bgroup + \forgetall + \let\doflushcolumnfloat\relax + \getcolumnstatus\column\mofcolumns\total\dimen0\goal\dimen2\\% + \ifdim\dimen0>\zeropoint + \dofloatsgetinfo{text}% + \ifdim\floatwidth>\hsize + % dropped ? + \else + \setbox2\vbox + {\blank[\@@bkspacebefore] + \snaptogrid\vbox{\vskip\floatheight}}% + \advance\dimen0 \ht2 + \ifdim\dimen0>\dimen2 + \ifnum\mofcolumns<\nofcolumns + \advance\mofcolumns \plusone + \ifdim\ht\currenttopcolumnbox=\zeropoint + \dofloatsflush{text}{1}% + \global\setbox\currenttopcolumnbox\vbox + {\snaptogrid\vbox{\box\floatbox} + \whitespace % nodig ? + \blank[\@@bkspaceafter]}% + \dimen4=\htdp\currenttopcolumnbox + \global\advance\vsize -\dimen4 + \advance\dimen4 -\pagegoal + \global\pagegoal-\dimen4 + \showmessage\m!columns{12}a% + \else + \showmessage\m!columns{12}b% + \fi + \else + \showmessage\m!columns{12}c% + \fi + \else + \ifhmode{\setbox0\lastbox}\fi% waar is die er in geslopen + \par + \ifdim\prevdepth<\zeropoint \else % anders bovenaan kolom witruimte + \nobreak + \blank[\@@bkspacebefore] + \nobreak + \fi + \dofloatsflush{text}{1}% + \flushfloatbox + \blank[\@@bkspaceafter] + \fi + \fi + \fi + \egroup + \fi\fi\fi\fi} + +%D This one looks complicated. Upto \type{\nofcolumns} floats +%D are placed, taking the width of a float into account. This +%D routine can be improved on different ways: +%D +%D \startitemize[intro,packed] +%D \item taking into account some imaginary baseline, just to +%D get the captions in line +%D \item multipass flushing until as many floats are displaced +%D as possible +%D \stopitemize +%D +%D When handling lots of (small) floats spacing can get worse +%D because of lining out the columns. + + +\def\doflushcolumnfloats + {\ifpostponecolumnfloats\else + \bgroup + \forgetall + \ifsomefloatwaiting + \dimen8\zeropoint + \dimen4\zeropoint + \count0\zerocount % count0 can be used local + \count2\nofcolumns % count2 can be used local + \dohandleallcolumns + {\ifnum\count0>\zerocount % the wide one's reserved space + \global\setbox\currenttopcolumnbox\vbox + {\snaptogrid\vbox + {\copy\currenttopcolumnbox + \hbox{\vphantom{\vskip\floatheight}}}% known from previous + \whitespace % nodig ? + \blank[\@@bkspaceafter]}% + \else + \dofloatsgetinfo{text}% + \ifdim\floatwidth>\hsize + \dimen0\dimexpr\floatwidth+\intercolumnwidth+.5pt\relax + \dimen2\dimexpr\hsize +\intercolumnwidth+.5pt\relax + \divide\dimen0 \dimen2 + \count0\dimen0 + \advance\count0 \plusone + \ifnum\count0>\count2 + \count0\zerocount + \else + \dimen0\dimexpr\count0\hsize+\count0\intercolumnwidth-\intercolumnwidth\relax + \dofloatsflush{text}{1}% + \ifdim\floatwidth>\finalcolumntextwidth % better somewhere else too + \global\setbox\floatbox\hbox to \finalcolumntextwidth{\hss\box\floatbox\hss}% + \fi % otherwise the graphic may disappear + \global\setbox\floatbox\hbox to \dimen0 + {\processaction[\@@bklocation] % how easy to forget + [ \v!left=>\box\floatbox\hss, + \v!right=>\hss\box\floatbox, + \s!default=>\hss\box\floatbox\hss, + \s!unknown=>\hss\box\floatbox\hss]}% + \fi + \showmessage\m!columns{13}\empty + \else + \dofloatsflush{text}{1}% + \ifdim\floatwidth>\finalcolumntextwidth % better somewhere else too + \global\setbox\floatbox\hbox to \finalcolumntextwidth{\hss\box\floatbox\hss}% + \fi % otherwise the graphic may disappear + % \showmessage\m!columns{13}\empty + \fi + \ifdim\ht\floatbox>\zeropoint\relax + \global\setbox\currenttopcolumnbox\vbox + {\snaptogrid\vbox + {\box\currenttopcolumnbox % was copy + \box\floatbox} + \whitespace % nodig ? + \blank[\@@bkspaceafter]}% + \fi + \dimen6\htdp\currenttopcolumnbox + \fi + \ifdim\dimen4<\ht\currenttopcolumnbox + \dimen4\ht\currenttopcolumnbox + \fi + \advance\dimen8 \dimen6 + \advance\count2 \minusone + \advance\count0 \minusone }% + \setvsize + \global\advance\vsize -\dimen8 + \global\pagegoal\vsize + \else + %\doflushfloats % does not snap! + \fi + \egroup + \fi} + +%D The next macro can be used to flush floats in the current +%D stream. No width checking is (yet) done. + +\def\insertcolumnfloats + {\doloop + {\ifsomefloatwaiting + \bgroup + \forgetall + % no check for width + \dogetfloat + \blank[\@@bkspacebefore] + \snaptogrid\vbox{\copy\floatbox} + \blank[\@@bkspaceafter] + \egroup + \else + \exitloop + \fi}} + +%D This were the multi||column routines. They can and need to +%D be improved but at the moment their behaviour is acceptable. +%D +%D One inprovement can be to normalize the height of floats +%D to $n\times$\type{\lineheight} with a macro like: +%D +%D \starttyping +%D \normalizevbox{...} +%D \stoptyping + +% border case, should fit on one page +% +% \startcolumns +% +% 1 \input tufte \par \plaatsfiguur{}{\omlijnd[breedte=\hsize,hoogte=3cm]{1}} +% 2 \input tufte \par \plaatsfiguur{}{\omlijnd[breedte=\hsize,hoogte=3cm]{2}} +% 3 \input tufte \par \plaatsfiguur{}{\omlijnd[breedte=\hsize,hoogte=3cm]{3}} +% +% \stopcolumns + +\unexpanded\def\setupcolumns + {\dosingleempty\dosetupcolumns} + +\def\dosetupcolumns[#1]% + {\getparameters[\??kl][#1]% + \nofcolumns\@@kln\relax + \processaction + [\@@klrule] + [ \v!on=>\let\betweencolumns\linebetweencolumns, + \v!off=>\let\betweencolumns\spacebetweencolumns, + \s!default=>\let\betweencolumns\spacebetweencolumns, + \s!unknown=>\let\betweencolumns\@@klrule]} + +\def\linebetweencolumns + {\bgroup + \starttextproperties + \ifdim\@@kldistance>\zeropoint + \dimen0=\@@kldistance + \else + \dimen0=\linewidth + \fi + \advance\dimen0 -\linewidth + \hskip.5\dimen0 + \vrule + \!!width\linewidth + \ifb@selinebottom\!!depth\strutdepth\fi + \hskip.5\dimen0\relax + \stoptextproperties + \egroup} + +\def\spacebetweencolumns + {\hskip\@@kldistance} + +\presetlocalframed[\??kl] + +\def\backgroundfinishcolumnbox + {\doifinsetelse\@@kloffset{\v!none,\v!overlay} + {\let\@@kloffset\!!zeropoint} + {\scratchdimen\@@kloffset + \advance\scratchdimen -\@@klrulethickness + \edef\@@kloffset{\the\scratchdimen}}% + \localframed + [\??kl] + [\c!strut=\v!no, + \c!width=\v!fit, + \c!height=\v!fit, + \c!align=]} + +\definecomplexorsimpleempty\startcolumns + +\def\complexstartcolumns[#1]% %% \startcolumns + {\bgroup + \let\stopcolumns\egroup + \ifinsidecolumns + \else + \setupcolumns[#1]% + \ifnum\@@kln>1\relax + \whitespace + \begingroup + \doif\@@kloption\v!background + {\let\finishcolumnbox\backgroundfinishcolumnbox + \let\columntextoffset\@@kloffset}% + \ifx\@@klcommand\empty\else + \let\postprocesscolumnline\@@klcommand + \fi + \doifelsenothing\@@klheight + \heightencolumnsfalse + \heightencolumnstrue + \doifelse\@@kldirection\v!right + \reversecolumnsfalse + \reversecolumnstrue + \doifelse\@@klbalance\v!yes + \balancecolumnstrue + \balancecolumnsfalse + \installalign\v!yes {\stretchcolumnstrue \inheritcolumnsfalse}% todo: new key + \installalign\v!no {\stretchcolumnsfalse\inheritcolumnsfalse}% todo: new key + \installalign\v!text{\stretchcolumnsfalse\inheritcolumnstrue }% + \stretchcolumnsfalse + \inheritcolumnstrue + \doifsomething\@@klalign{\expanded{\setupalign[\@@klalign]}}% + \nofcolumns=\@@kln + % + % probably more is needed, and how about nesting save's + % + \saveouterspacing + % + \edef\fixedcolumnheight{\@@klheight}% + \edef\minbalancetoplines{\@@klntop}% + \setuptolerance[\@@kltolerance]% %% \startcolumns + \setupblank[\@@klblank]% + \ifdim\ctxparskip>\zeropoint\relax + \setupwhitespace[\@@klblank]% + \fi + \unexpanded\def\stopcolumns + {\endmulticolumns + \global\insidecolumnsfalse + \endgroup + \egroup}% + \global\insidecolumnstrue + \beginmulticolumns + \fi + \fi} + +\installcolumnbreakhandler {MUL} \v!preference + {\goodbreak} + +\installcolumnbreakhandler {MUL} \v!yes + {\par % todo: since + {\testrulewidth\zeropoint\ruledvskip\textheight} % we misuse a + \penalty-200 % side effect + \vskip-\textheight + }% bugged : \prevdepth-\thousandpoint} % signals top of column to \blank + +%D New: only at start of columns; may change ! Rather +%D interwoven and therefore to be integrated when the multi +%D column modules are merged. (moved from cont-new.tex) + +\unexpanded\def\setupcolumnspan[#1]% + {\getparameters[\??ks][#1]} + +\presetlocalframed + [\??ks] + +\setupcolumnspan + [\c!n=2, + \c!offset=\v!overlay, + \c!frame=\v!off] + +\newbox\columnspanbox \let\postprocesscolumnspanbox\gobbleoneargument + +\def\dostartcolumnspan[#1]% + {\bgroup + \setupcolumnspan[#1]% + \forgetall + \ifinsidecolumns + \advance\hsize \intercolumnwidth + \hsize\@@ksn\hsize + \advance\hsize -\intercolumnwidth + \fi + \dowithnextbox + {\setbox\columnspanbox\flushnextbox + \ifinsidecolumns\wd\columnspanbox\hsize\fi + \postprocesscolumnspanbox\columnspanbox + \scratchdimen\ht\columnspanbox + \setbox\columnspanbox\hbox % depth to be checked, probably option! + {\localframed[\??ks][\c!offset=\v!overlay]{\box\columnspanbox}}% + \ht\columnspanbox\scratchdimen + \dp\columnspanbox\strutdp + \wd\columnspanbox\hsize + \ifinsidecolumns + \ifnum\@@ksn>1 + \setvsize + \dohandleallcolumns + {\ifnum\currentcolumn>\@@ksn\else + \global\setbox\currenttopcolumnbox=\vbox + {\ifnum\currentcolumn=1 + \snaptogrid\vbox{\copy\columnspanbox} + \else + \snaptogrid\vbox{\vphantom{\copy\columnspanbox}} + \fi}% + \wd\currenttopcolumnbox\hsize + \global\advance\vsize -\ht\currenttopcolumnbox + \fi} + \global\pagegoal\vsize + \else + \snaptogrid\vbox{\box\columnspanbox} + \fi + \else + \snaptogrid\vbox{\box\columnspanbox} + \fi + \endgraf + \ifvmode\prevdepth\strutdp\fi + \egroup} + \vbox\bgroup + %\topskipcorrection % becomes an option ! + \EveryPar{\begstrut\EveryPar{}}} % also ! + +\unexpanded\def\startcolumnspan + {\dosingleempty\dostartcolumnspan} + +\unexpanded\def\stopcolumnspan + {\egroup} + +\setupcolumns + [\c!n=2, + \c!ntop=1, + \c!command=, + \c!direction=\v!right, + \c!rule=\v!off, + \c!tolerance=\v!tolerant, + \c!distance=1.5\bodyfontsize, % influenced by switching + \c!height=, + \c!balance=\v!yes, + \c!align=\v!text, + \c!blank={\v!line,\v!fixed}, + \c!option=, + \c!rulethickness=\linewidth, + \c!offset=.5\bodyfontsize] + +%D Undocumented and still under development. + +\unexpanded\def\startsimplecolumns + {\dosingleempty\dostartsimplecolumns} + +\def\dostartsimplecolumns[#1]% + {\bgroup + \nopenalties + \getparameters[\??kl] + [\c!width=\hsize,\c!distance=1.5\bodyfontsize,% + \c!n=2,\c!lines=0,#1]% + \let\rigidcolumnlines\@@kllines + \setrigidcolumnhsize\@@klwidth\@@kldistance\@@kln + \setbox\scratchbox\vbox\bgroup + \forgetall} % \blank[\v!disable] + +\unexpanded\def\stopsimplecolumns + {\removebottomthings + \egroup + \rigidcolumnbalance\scratchbox + \egroup} + +\protect \endinput diff --git a/tex/context/base/page-not.mkii b/tex/context/base/page-not.mkii new file mode 100644 index 000000000..9c67f18f1 --- /dev/null +++ b/tex/context/base/page-not.mkii @@ -0,0 +1,72 @@ +%D \module +%D [ file=page-nnt, +%D version=2002.04.16, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Footnotes, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Footnotes} + +%D Terrible hacks: we need to share save/restore + +%D We've moved some footnote handling to a separate page +%D module. The macros below are used in the single and multi +%D column page handlers and permit mixed usage of column and +%D page notes. + +\unprotect + +\def\checkbegincolumnfootnotes % should happen inside otr + {\ifcase\clevernotes + \erasenotebackup + \else + \doflushnotes + \savenotecontent + \fi + \savenotedata + \checknotes} + +\def\checkendcolumnfootnotes + {\restorenotedata % maybe better just \checknotes + \ifcase\clevernotes\else + \restorenotecontent + \fi} + +\def\checksinglecolumnfootnotes + {\checknotes} % njet : \restorenotedata + +\newdimen\totalinsertionheight + +\def\settotalinsertionheight + {\calculatetotalnoteheight + \totalinsertionheight\totalnoteheight + \addinsertionheight\topins\to\totalinsertionheight + \addinsertionheight\botins\to\totalinsertionheight} + +% hm + +\def\checkbegincolumnfootnotes % should happen inside otr + {\ifcase\clevernotes + \erasenotebackup + \else + \doflushnotes + \savenotecontent + \fi + \savenotedata + \checknotes} + +\def\checkendcolumnfootnotes + {\restorenotedata + \ifinsidecolumns + \ifcase\clevernotes\else + \restorenotecontent + \fi + \fi} + +\protect \endinput diff --git a/tex/context/base/page-not.mkiv b/tex/context/base/page-not.mkiv new file mode 100644 index 000000000..95229f9d0 --- /dev/null +++ b/tex/context/base/page-not.mkiv @@ -0,0 +1,69 @@ +%D \module +%D [ file=page-nnt, +%D version=2002.04.16, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Footnotes, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Footnotes} + +%D Terrible hacks: we need to share save/restore + +%D We've moved some footnote handling to a separate page +%D module. The macros below are used in the single and multi +%D column page handlers and permit mixed usage of column and +%D page notes. + +\unprotect + +\def\checkbegincolumnfootnotes % should happen inside otr + {\ifcase\clevernotes + \erasenotebackup + \else + \flushnotes + \savenotecontent + \fi + \savenotedata} + +\def\checkendcolumnfootnotes + {\restorenotedata + \ifcase\clevernotes\else + \restorenotecontent + \fi} + +\let\checksinglecolumnfootnotes\relax + +\newdimen\totalinsertionheight + +\def\settotalinsertionheight + {\calculatetotalnoteheight + \totalinsertionheight\totalnoteheight + \addinsertionheight\topins\to\totalinsertionheight + \addinsertionheight\botins\to\totalinsertionheight} + +% hm + +\def\checkbegincolumnfootnotes % should happen inside otr + {\ifcase\clevernotes + \erasenotebackup + \else + \flushnotes + \savenotecontent + \fi + \savenotedata} + +\def\checkendcolumnfootnotes + {\restorenotedata + \ifinsidecolumns + \ifcase\clevernotes\else + \restorenotecontent + \fi + \fi} + +\protect \endinput 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..bbd35181e --- /dev/null +++ b/tex/context/base/page-one.mkiv @@ -0,0 +1,532 @@ +%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} + +\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) + +% can we avoind the extra vboxing here? + +\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\dimexpr\MPy{pbd:\realfolio:b}-\MPy{pbd:\realfolio:e}\relax + \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 + \prevdepth\openstrutdepth + \dobotinsertions + \vfil + \else\ifr@ggedbottom + \OTRONEregisteredtextareaA{#1#2}% + \vskip-\currentpagedepth\vskip\openstrutdepth + \prevdepth\openstrutdepth + \dobotinsertions + \vfil + \else\ifb@selinebottom + \OTRONEregisteredtextareaA{#1#2}% + \kern-\currentpagedepth\kern\maxdepth + \dobotinsertions + \else + \OTRONEregisteredtextareaA{#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 + \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 + \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} + +\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 + \global\setbox\floatbox\hbox to \hsize{\hss\box\floatbox\hss}% + \fi \fi + \snaptogrid\hbox{\iftestfloatbox\ruledhbox\fi{\box\floatbox}}} % was copy + +\def\OTRONEdodoflushfloats % much in common with OTRSET + {\ifsomefloatwaiting + \ifpackflushedfloats + \centerfloatboxfalse % not needed as we do call directly + \dofloatscollect{text}{\hsize}{1em}% + \OTRONEsetvsize + \global\setbox\floatbox\hbox to \hsize + {\hfil + \dorecurse\nofcollectedfloats + {\ifcase\columndirection % nog document wide + \dofloatsflush{text}{1}% + \else + \dofloatsflushn{text}{\the\numexpr\nofcollectedfloats-\recurselevel+1\relax}% + \fi + \ifdim\wd\floatbox>\makeupwidth % \hsize + \hbox to \makeupwidth{\hss\box\floatbox\hss}% + \else + \box\floatbox + \fi + \ifnum\recurselevel<\nofcollectedfloats + \hfil + \fi}% + \hfil}% + \else + \dogetfloat + \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+\floatheight+\floattopskip-\pageshrink\relax + \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\OTRONEsomepagefloat [#1]{\dofloatssavepagefloat{page} {#1}} +\def\OTRONEsomeleftpagefloat [#1]{\dofloatssavepagefloat{leftpage} {#1}} +\def\OTRONEsomerightpagefloat[#1]{\dofloatssavepagefloat{rightpage}{#1}} + +\def\OTRONEsometopsfloat[#1]% + {\ifdim\topinserted=\zeropoint + \topofinserttrue + \else + \topofinsertfalse + \fi + \global\advance\topinserted\dimexpr\ht\floatbox+\dp\floatbox+\floatbottomskip\relax + \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\dimexpr\ht\floatbox+\dp\floatbox+\floattopskip\relax + \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.mkii b/tex/context/base/page-par.mkii new file mode 100644 index 000000000..a5dea2e63 --- /dev/null +++ b/tex/context/base/page-par.mkii @@ -0,0 +1,58 @@ +%D \module +%D [ file=page-par, % copied from page-lin +%D version=1997.03.31, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Line Numbering, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Paragraph Numbering} + +\unprotect + +\newcount\internalparagraphnumber + +\def\setupparagraphnumbering + {\dosingleempty\dosetupparagraphnumbering} + +\def\dosetupparagraphnumbering[#1]% + {\getparameters + [\??ph][#1]% + \processaction + [\@@phstate] + [\v!start=>\let\showparagraphnumber\doshowparagraphnumberA, + \v!stop=>\let\showparagraphnumber\relax, + \v!line=>\let\showparagraphnumber\doshowparagraphnumberB, + \v!reset=>\global\internalparagraphnumber\zerocount + \let\showparagraphnumber\doshowparagraphnumberA]} + +\def\dodoshowparagraphnumber + {\global\advance\internalparagraphnumber \plusone + \inleftmargin % \tf normalizes em + {\tf{\doattributes\??ph\c!style\c!color{\the\internalparagraphnumber}}% + \kern\@@phdistance}} + +\def\doshowparagraphnumberA + {\ifprocessingverbatim + \iflinepar\dodoshowparagraphnumber\fi + \else + \dodoshowparagraphnumber + \fi} + +\def\doshowparagraphnumberB + {\ifnumberinglines + \doshowparagraphnumberA + \fi} + +\setupparagraphnumbering + [\c!state=\v!stop, + \c!style=, + \c!color=, + \c!distance=\ifcase\linenumberlocation2em\else\!!zeropoint\fi] % will change + +\protect \endinput diff --git a/tex/context/base/page-par.mkiv b/tex/context/base/page-par.mkiv new file mode 100644 index 000000000..fb8631eec --- /dev/null +++ b/tex/context/base/page-par.mkiv @@ -0,0 +1,58 @@ +%D \module +%D [ file=page-par, % copied from page-lin +%D version=1997.03.31, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Line Numbering, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Paragraph Numbering} + +\unprotect + +\newcount\internalparagraphnumber + +\unexpanded\def\setupparagraphnumbering + {\dosingleempty\dosetupparagraphnumbering} + +\def\dosetupparagraphnumbering[#1]% + {\getparameters + [\??ph][#1]% + \processaction + [\@@phstate] + [\v!start=>\let\showparagraphnumber\doshowparagraphnumberA, + \v!stop=>\let\showparagraphnumber\relax, + \v!line=>\let\showparagraphnumber\doshowparagraphnumberB, + \v!reset=>\global\internalparagraphnumber\zerocount + \let\showparagraphnumber\doshowparagraphnumberA]} + +\def\dodoshowparagraphnumber + {\global\advance\internalparagraphnumber \plusone + \inleftmargin % \tf normalizes em + {\tf{\doattributes\??ph\c!style\c!color{\the\internalparagraphnumber}}% + \kern\@@phdistance}} + +\def\doshowparagraphnumberA + {\ifprocessingverbatim + \iflinepar\dodoshowparagraphnumber\fi + \else + \dodoshowparagraphnumber + \fi} + +\def\doshowparagraphnumberB + {\ifnumberinglines + \doshowparagraphnumberA + \fi} + +\setupparagraphnumbering + [\c!state=\v!stop, + \c!style=, + \c!color=, + \c!distance=\ifcase\linenumberlocation2em\else\!!zeropoint\fi] % will change + +\protect \endinput diff --git a/tex/context/base/page-plg.mkii b/tex/context/base/page-plg.mkii new file mode 100644 index 000000000..3203b923c --- /dev/null +++ b/tex/context/base/page-plg.mkii @@ -0,0 +1,202 @@ +%D \module +%D [ file=page-pls, +%D version=2003.03.16, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Page Setup, +%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. + +\ifx\pageareabox\undefined \else \endinput \fi + +\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 +%D demonstrates the application of one such a plug-in. This variant +%D support \type {page}, \type {leftpage} and \type {rightpage} +%D definitions where specific areas are placed with the \type +%D {\pagearea} command. +%D +%D \starttyping +%D \setupheadertexts[the header text] +%D \setupfootertexts[a pretty long left footer text][something right] +%D \setupbottomtexts[a not so long bottom text][another right thing] +%D \setuptexttexts [margin][something marginal][indeed] +%D +%D \startpagelayout[leftpage] +%D \setupTABLE[offset=overlay] +%D \setupTABLE[c][1][width=\leftmarginwidth] +%D \bTABLE +%D \bTR +%D \bTD[nx=3,background=color,backgroundcolor=green] +%D \pagearea[header][text][middle] +%D \eTD +%D \eTR +%D \bTR +%D \bTD \pagearea[text][margin][left] \eTD +%D \bTD[nx=2] \pagearea[text] \eTD +%D \eTR +%D \bTR +%D \bTD[nx=3,offset=overlay] +%D {\bTABLE[width=.5\hsize] +%D \bTR +%D \bTD \pagearea[footer][text][left] \eTD +%D \bTD \pagearea[bottom][text][left] \eTD +%D \eTR +%D \eTABLE} +%D \eTD +%D \eTR +%D \eTABLE +%D \stoppagelayout +%D +%D \startpagelayout[rightpage] +%D \setupTABLE[offset=overlay] +%D \setupTABLE[c][1][width=\rightmarginwidth] +%D \bTABLE +%D \bTR +%D \bTD[nx=3] \pagearea[header][text][middle] \eTD +%D \eTR +%D \bTR +%D \bTD \pagearea[text][margin][left] \eTD +%D \bTD[nx=2] \pagearea[text] \eTD +%D \eTR +%D \bTR +%D \bTD[nx=3,offset=overlay] +%D {\bTABLE[width=.5\hsize] +%D \bTR +%D \bTD \pagearea[bottom][text][right] \eTD +%D \bTD \pagearea[footer][text][right] \eTD +%D \eTR +%D \eTABLE} +%D \eTD +%D \eTR +%D \eTABLE +%D \stoppagelayout +%D +%D \setupcolors[state=start] +%D +%D \setupbackgrounds[text][background=color,backgroundcolor=blue] +%D \setupbackgrounds[header][text][background=color,backgroundcolor=red] +%D +%D \setuppagenumbering[alternative=doublesided,location=] +%D +%D \setuplayout[method=makeup] +%D +%D \definetextbackground +%D [test] +%D [state=start, +%D background=color, +%D backgroundcolor=yellow] +%D +%D \starttext +%D +%D \dorecurse{10}{\input tufte \par} +%D +%D \input tufte \starttest \input tufte \stoptest \input tufte +%D +%D \starttabulate +%D \NC test \NC \starttest \input tufte \stoptest \NC \NR +%D \stoptabulate +%D +%D \dorecurse{10}{\input tufte \par} +%D +%D \stoptext +%D \stoptyping + +\unprotect + +\setvalue{\??ly\c!method\v!makeup}#1#2% + {\setbox\pagebox\hbox + {\vbox to \textheight + {\offinterlineskip + % optie + \vskip\dimexpr-1\topskip+\strutheight\relax + % + \textwidth\makeupwidth + \hsize\textwidth + \boxmaxdepth\maxdepth + \noindent + \dopagecontents#1#2}}% + \wd\pagebox\makeupwidth + \ht\pagebox\textheight + \dp\pagebox\zeropoint + \hsize\paperwidth + \vsize\paperheight + \setbox\pagebox\vbox + {\doifbothsidesoverruled + {\let\!!stringa\v!page} + {\let\!!stringa\v!rightpage} + {\let\!!stringa\v!leftpage}% + \getvalue{\??ly\c!method:\!!stringa}}% + \wd\pagebox\paperwidth + \ht\pagebox\paperheight + \dp\pagebox\zeropoint} + +\newbox\pageareabox + +\def\pagearea + {\dotripleempty\dopagearea} + +\def\dopagearea[#1][#2][#3]% + {\ifthirdargument + \doifelse{#3}\v!left + {\dodopagearea{#1}{#2}\c!lefttext} + {\doifelse{#3}\v!right + {\dodopagearea{#1}{#2}\c!righttext} + {\dodopagearea{#1}{#2}\c!middletext}}% + \else\ifsecondargument + \doifbothsidesoverruled + {\dodopagearea{#1}{#2}\c!righttext} + {\dodopagearea{#1}{#2}\c!righttext} + {\dodopagearea{#1}{#2}\c!lefttext }% + \else + \doif{#1}\v!text % copy due to trial runs in TABLE + {\iftrialtypesetting + \copy\pagebox + \else + \setbox\pagebox\vbox + {\localstarttextcolor + \box\pagebox + \localstoptextcolor}% + \localpositioningfalse + \addtextbackground\pagebox + \addtextgridlayer\pagebox + \box\pagebox + \fi}% + \fi\fi} + +\def\dodopagearea#1#2#3% + {\setbox\pageareabox\vbox{\getvalue{\??tk#1#2#3}}% + \ifsomebackgroundfound{#1#2}% + \iftrialtypesetting + \box\pageareabox + \else + \localframed + [\??ma#1#2] + [\c!width=\wd\pageareabox, + \c!height=\ht\pageareabox, + \c!offset=\v!overlay] + {\box\pageareabox}% + \fi + \else + \box\pageareabox + \fi} + +\setvalue{\??ly\c!method:\v!leftpage }{\getvalue{\??ly\c!method:\v!page}} +\setvalue{\??ly\c!method:\v!rightpage}{\getvalue{\??ly\c!method:\v!page}} + +% \long\def\startpagelayout[#1]#2\stoppagelayout +% {\long\setvalue{\??ly\c!method:#1}{#2}} + +\long\def\startpagelayout + {\bgroup\catcode`\^^M=\@@ignore\dostartpagelayout} + +\long\def\dostartpagelayout[#1]#2\stoppagelayout + {\egroup\long\setvalue{\??ly\c!method:#1}{#2}} + +\protect \endinput diff --git a/tex/context/base/page-plg.mkiv b/tex/context/base/page-plg.mkiv new file mode 100644 index 000000000..7d7612153 --- /dev/null +++ b/tex/context/base/page-plg.mkiv @@ -0,0 +1,198 @@ +%D \module +%D [ file=page-pls, +%D version=2003.03.16, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Page Setup, +%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. + +\ifx\pageareabox\undefined \else \endinput \fi + +\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 +%D demonstrates the application of one such a plug-in. This variant +%D support \type {page}, \type {leftpage} and \type {rightpage} +%D definitions where specific areas are placed with the \type +%D {\pagearea} command. +%D +%D \starttyping +%D \setupheadertexts[the header text] +%D \setupfootertexts[a pretty long left footer text][something right] +%D \setupbottomtexts[a not so long bottom text][another right thing] +%D \setuptexttexts [margin][something marginal][indeed] +%D +%D \startpagelayout[leftpage] +%D \setupTABLE[offset=overlay] +%D \setupTABLE[c][1][width=\leftmarginwidth] +%D \bTABLE +%D \bTR +%D \bTD[nx=3,background=color,backgroundcolor=green] +%D \pagearea[header][text][middle] +%D \eTD +%D \eTR +%D \bTR +%D \bTD \pagearea[text][margin][left] \eTD +%D \bTD[nx=2] \pagearea[text] \eTD +%D \eTR +%D \bTR +%D \bTD[nx=3,offset=overlay] +%D {\bTABLE[width=.5\hsize] +%D \bTR +%D \bTD \pagearea[footer][text][left] \eTD +%D \bTD \pagearea[bottom][text][left] \eTD +%D \eTR +%D \eTABLE} +%D \eTD +%D \eTR +%D \eTABLE +%D \stoppagelayout +%D +%D \startpagelayout[rightpage] +%D \setupTABLE[offset=overlay] +%D \setupTABLE[c][1][width=\rightmarginwidth] +%D \bTABLE +%D \bTR +%D \bTD[nx=3] \pagearea[header][text][middle] \eTD +%D \eTR +%D \bTR +%D \bTD \pagearea[text][margin][left] \eTD +%D \bTD[nx=2] \pagearea[text] \eTD +%D \eTR +%D \bTR +%D \bTD[nx=3,offset=overlay] +%D {\bTABLE[width=.5\hsize] +%D \bTR +%D \bTD \pagearea[bottom][text][right] \eTD +%D \bTD \pagearea[footer][text][right] \eTD +%D \eTR +%D \eTABLE} +%D \eTD +%D \eTR +%D \eTABLE +%D \stoppagelayout +%D +%D \setupcolors[state=start] +%D +%D \setupbackgrounds[text][background=color,backgroundcolor=blue] +%D \setupbackgrounds[header][text][background=color,backgroundcolor=red] +%D +%D \setuppagenumbering[alternative=doublesided,location=] +%D +%D \setuplayout[method=makeup] +%D +%D \definetextbackground +%D [test] +%D [state=start, +%D background=color, +%D backgroundcolor=yellow] +%D +%D \starttext +%D +%D \dorecurse{10}{\input tufte \par} +%D +%D \input tufte \starttest \input tufte \stoptest \input tufte +%D +%D \starttabulate +%D \NC test \NC \starttest \input tufte \stoptest \NC \NR +%D \stoptabulate +%D +%D \dorecurse{10}{\input tufte \par} +%D +%D \stoptext +%D \stoptyping + +\unprotect + +\setvalue{\??ly\c!method\v!makeup}#1#2% + {\setbox\pagebox\hbox + {\vbox to \textheight + {\offinterlineskip + % optie + \vskip\dimexpr-1\topskip+\strutheight\relax + % + \textwidth\makeupwidth + \hsize\textwidth + \boxmaxdepth\maxdepth + \noindent + \dopagecontents#1#2}}% + \wd\pagebox\makeupwidth + \ht\pagebox\textheight + \dp\pagebox\zeropoint + \hsize\paperwidth + \vsize\paperheight + \setbox\pagebox\vbox + {\doifbothsidesoverruled + {\let\!!stringa\v!page} + {\let\!!stringa\v!rightpage} + {\let\!!stringa\v!leftpage}% + \getvalue{\??ly\c!method:\!!stringa}}% + \wd\pagebox\paperwidth + \ht\pagebox\paperheight + \dp\pagebox\zeropoint} + +\newbox\pageareabox + +\def\pagearea + {\dotripleempty\dopagearea} + +\def\dopagearea[#1][#2][#3]% + {\ifthirdargument + \doifelse{#3}\v!left + {\dodopagearea{#1}{#2}\c!lefttext} + {\doifelse{#3}\v!right + {\dodopagearea{#1}{#2}\c!righttext} + {\dodopagearea{#1}{#2}\c!middletext}}% + \else\ifsecondargument + \doifbothsidesoverruled + {\dodopagearea{#1}{#2}\c!righttext} + {\dodopagearea{#1}{#2}\c!righttext} + {\dodopagearea{#1}{#2}\c!lefttext }% + \else + \doif{#1}\v!text % copy due to trial runs in TABLE + {\iftrialtypesetting + \copy\pagebox + \else + \localpositioningfalse + \addtextbackground\pagebox + \addtextgridlayer\pagebox + \box\pagebox + \fi}% + \fi\fi} + +\def\dodopagearea#1#2#3% + {\setbox\pageareabox\vbox{\getvalue{\??tk#1#2#3}}% + \ifsomebackgroundfound{#1#2}% + \iftrialtypesetting + \box\pageareabox + \else + \localframed + [\??ma#1#2] + [\c!width=\wd\pageareabox, + \c!height=\ht\pageareabox, + \c!offset=\v!overlay] + {\box\pageareabox}% + \fi + \else + \box\pageareabox + \fi} + +\setvalue{\??ly\c!method:\v!leftpage }{\getvalue{\??ly\c!method:\v!page}} +\setvalue{\??ly\c!method:\v!rightpage}{\getvalue{\??ly\c!method:\v!page}} + +% \long\unexpanded\def\startpagelayout[#1]#2\stoppagelayout +% {\long\setvalue{\??ly\c!method:#1}{#2}} + +\long\unexpanded\def\startpagelayout + {\bgroup\catcode`\^^M=\@@ignore\dostartpagelayout} + +\long\def\dostartpagelayout[#1]#2\stoppagelayout + {\egroup\long\setvalue{\??ly\c!method:#1}{#2}} + +\protect \endinput diff --git a/tex/context/base/page-run.mkii b/tex/context/base/page-run.mkii new file mode 100644 index 000000000..ae5af81e9 --- /dev/null +++ b/tex/context/base/page-run.mkii @@ -0,0 +1,382 @@ +%D \module +%D [ file=page-run, +%D version=2000.10.20, +%D title=\CONTEXT\ Page 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. + +\writestatus{loading}{ConTeXt Page Macros / Runtime Macros} + +\unprotect + +\gdef\doshowprint[#1][#2][#3]% + {\framed + [\c!offset=\v!overlay, + \c!strut=\v!no] + {\forgetall + \dontcomplain + \globaldefs\minusone + \dimen0\pagegoal + \definepapersize[X][\c!width=4em, \c!height=6em]% + \definepapersize[Y][\c!width=12em,\c!height=14em]% + \setuppapersize[#1,X][#2,Y]% + \setuplayout[#3]% + \setbox0\vbox + {\framed + [\c!offset=\v!overlay,\c!strut=\v!no, + \c!width=\paperwidth,\c!height=\paperheight] + {\ss ABC\par DEF}}% + \doublesidedfalse + \def\cutmarklength{.5em}% + \addpagecutmarks0% + \replicatepagebox0% + \scalepagebox0% + \mirrorpaperbox0% + \orientpaperbox0% + \centerpagebox0% + \mirrorprintbox0% + \orientprintbox0% + \offsetprintbox0% + \pagegoal\dimen0 + \box0}} + +\gdef\showprint + {\dotripleempty\doshowprint} + +% \switchnaarkorps[8pt] +% +% \startcombinatie[4*4] +% {\toonprint} {\strut} +% {\toonprint[][][plaats=midden]} {\type{plaats=midden}} +% {\toonprint[][][plaats=midden,markering=aan]} {\type{markering=aan}\break +% \type{plaats=midden}} +% {\toonprint[][][plaats=midden,markering=aan,nx=2]} {\type{markering=aan}\break +% \type{plaats=midden}\break +% \type{nx=2}} +% {\toonprint[][][plaats=links]} {\type{plaats=links}} +% {\toonprint[][][plaats=rechts]} {\type{plaats=rechts}} +% {\toonprint[][][plaats={links,onder}]} {\type{plaats={links,onder}}} +% {\toonprint[][][plaats={rechts,onder}]} {\type{plaats={rechts,onder}}} +% {\toonprint[][][nx=2,ny=1]} {\type{nx=2,ny=1}} +% {\toonprint[][][nx=1,ny=2]} {\type{nx=1,ny=2}} +% {\toonprint[][][nx=2,ny=2]} {\type{nx=2,ny=2}} +% {\toonprint[][][nx=2,ny=2,plaats=midden]} {\type{nx=2,ny=2}\break +% \type{plaats=midden}} +% {\toonprint[][][rugoffset=3pt]} {\type{rugoffset=.5cm}} +% {\toonprint[][][kopoffset=3pt]} {\type{kopoffset=.5cm}} +% {\toonprint[][][schaal=1.5]} {\type{schaal=1.5}} +% {\toonprint[][][schaal=0.8]} {\type{schaal=0.8}} +% \stopcombinatie +% +% \startcombinatie[3*4] +% {\toonprint[liggend][][plaats=midden]} {\type{liggend}} +% {\toonprint[][liggend][plaats=midden]} {\strut\break\type{liggend}} +% {\toonprint[liggend][liggend][plaats=midden]} {\type{liggend}\break\type{liggend}} +% {\toonprint[90][][plaats=midden]} {\type{90}} +% {\toonprint[][90][plaats=midden]} {\strut\break\type{90}} +% {\toonprint[90][90][plaats=midden]} {\type{90}\break\type{90}} +% {\toonprint[180][][plaats=midden]} {\type{180}} +% {\toonprint[][180][plaats=midden]} {\strut\break\type{180}} +% {\toonprint[180][180][plaats=midden]} {\type{180}\break\type{180}} +% {\toonprint[gespiegeld][][plaats=midden]} {\type{gespiegeld}} +% {\toonprint[][gespiegeld][plaats=midden]} {\strut\break\type{gespiegeld}} +% {\toonprint[gespiegeld][gespiegeld][plaats=midden]} {\type{gespiegeld}\break\type{gespiegeld}} +% \stopcombinatie + +\gdef\doshowframe[#1][#2]% + {\ifsecondargument + \setupbackgrounds + [\v!page] + [\c!frame=\v!on, + \c!corner=\v!rectangular, + \c!frameoffset=\!!zeropoint, + \c!framedepth=\!!zeropoint, + \c!framecolor=layout:page] + \setupbackgrounds + [#1][#2] + [\c!background=, + \c!frame=\v!on, + \c!corner=\v!rectangular, + \c!frameoffset=\!!zeropoint, + \c!framedepth=\!!zeropoint, + \c!framecolor=] + \else\iffirstargument + \showframe + [\v!header,\v!text,\v!footer] + [#1] + \else + \showframe + [\v!header,\v!text,\v!footer] + [\v!leftedge,\v!leftmargin, + \v!text, + \v!rightmargin,\v!rightedge] + \fi\fi + \setupbackgrounds + [\c!state=\v!repeat]} + +\gdef\showframe{\dodoubleempty\doshowframe} + +\gdef\showsetupA#1#2% + {#1&\PtToCm{\the#2}&\the#2&\tttf\string#2\cr} + +\gdef\showsetupB#1#2#3% + {#1&#3&\tttf\string#3\cr} + +% \startinterface english % english is fallback + +\gdef\showsetups + {\noindent + \vbox + {\forgetall + \dontcomplain + \switchtobodyfont[\v!small] + \tabskip\zeropoint + \halign + {\strut##\quad\hss&##\quad\hss&##\quad\hss&##\hss\cr + \showsetupA{paperheight} \paperheight + \showsetupA{paperwidth} \paperwidth + \showsetupA{printpaperheight} \printpaperheight + \showsetupA{printpaperwidth} \printpaperwidth + \showsetupA{topspace} \topspace + \showsetupA{backspace} \backspace + \showsetupA{height} \makeupheight + \showsetupA{width} \makeupwidth + \showsetupA{top} \topheight + \showsetupA{topdistance} \topdistance + \showsetupA{header} \headerheight + \showsetupA{headerdistance} \headerdistance + \showsetupA{textheight} \textheight + \showsetupA{footerdistance} \footerdistance + \showsetupA{footer} \footerheight + \showsetupA{bottomdistance} \bottomdistance + \showsetupA{bottom} \bottomheight + \showsetupA{leftedge} \leftedgewidth + \showsetupA{leftedgedistance} \leftedgedistance + \showsetupA{leftmargin} \leftmarginwidth + \showsetupA{leftmargindistance} \leftmargindistance + \showsetupA{textwidth} \textwidth + \showsetupA{rightmargindistance}\rightmargindistance + \showsetupA{rightmargin} \rightmarginwidth + \showsetupA{rightedgedistance} \rightedgedistance + \showsetupA{rightedge} \rightedgewidth + \showsetupB{bodyfontsize} \the \globalbodyfontsize + \showsetupB{line} \relax \normallineheight + \showsetupB{height} \relax \strutheightfactor + \showsetupB{depth} \relax \strutdepthfactor + \showsetupB{topskip} \relax \topskipfactor + \showsetupB{maxdepth} \relax \maxdepthfactor}}} + +% \stopinterface + +\startinterface dutch + +\gdef\showsetups + {\noindent + \vbox + {\forgetall + \dontcomplain + \switchtobodyfont[\v!small] + \tabskip\zeropoint + \halign + {\strut##\quad\hss&##\quad\hss&##\quad\hss&##\hss\cr + \showsetupA{papierhoogte} \papierhoogte + \showsetupA{papierbreedte} \papierbreedte + \showsetupA{printpapierhoogte} \printpapierhoogte + \showsetupA{printpapierbreedte} \printpapierbreedte + \showsetupA{kopwit} \kopwit + \showsetupA{rugwit} \rugwit + \showsetupA{snijwit} \snijwit + \showsetupA{hoogte} \zethoogte + \showsetupA{breedte} \zetbreedte + \showsetupA{boven} \bovenhoogte + \showsetupA{bovenafstand} \bovenafstand + \showsetupA{hoofd} \hoofdhoogte + \showsetupA{hoofdafstand} \hoofdafstand + \showsetupA{teksthoogte} \teksthoogte + \showsetupA{voetafstand} \voetafstand + \showsetupA{voet} \voethoogte + \showsetupA{onderafstand} \onderafstand + \showsetupA{onder} \onderhoogte + \showsetupA{linkerrand} \linkerrandbreedte + \showsetupA{linkerrandafstand} \linkerrandafstand + \showsetupA{linkermarge} \linkermargebreedte + \showsetupA{linkermargeafstand} \linkermargeafstand + \showsetupA{tekstbreedte} \tekstbreedte + \showsetupA{rechtermargeafstand}\rechtermargeafstand + \showsetupA{rechtermarge} \rechtermargebreedte + \showsetupA{rechterrandafstand} \rechterrandafstand + \showsetupA{rechterrand} \rechterrandbreedte + \showsetupB{korps} \the \globalbodyfontsize + \showsetupB{regel} \relax \normallineheight + \showsetupB{hoogte} \relax \strutheightfactor + \showsetupB{diepte} \relax \strutdepthfactor + \showsetupB{boven} \relax \topskipfactor + \showsetupB{onder} \relax \maxdepthfactor}}} + +\stopinterface + +% todo: \showsetupA{rugwit} \rugwit + +\startinterface german + +\gdef\showsetups% + {\noindent + \vbox + {\forgetall + \dontcomplain + \switchtobodyfont[\v!small] + \tabskip\zeropoint + \halign + {\strut##\quad\hss&##\quad\hss&##\quad\hss&##\hss\cr + \showsetupA{papierhoehe} \papierhoehe + \showsetupA{papierbreite} \papierbreite + \showsetupA{printpapierhoehe} \printpapierhoehe + \showsetupA{printpapierbreite} \printpapierbreite + \showsetupA{kopfweite} \kopfweite + \showsetupA{rumpfweite} \rumpfweite + \showsetupA{hoehe} \satzhoehe + \showsetupA{breite} \satzbreite + \showsetupA{oben} \hoeheoben + \showsetupA{abstandoben} \abstandoben + \showsetupA{kopfzeile} \kopfzeilenhoehe + \showsetupA{kopfzeilenabstand} \kopfzeilenabstand + \showsetupA{texthoehe} \texthoehe + \showsetupA{fusszeileabstand} \fusszeileabstand + \showsetupA{fusszeilen} \fusszeilenhoehe + \showsetupA{abstandunten} \abstandunten + \showsetupA{hoeheunten} \hoeheunten + \showsetupA{linkerrand} \breitelinkerrand + \showsetupA{abstandlinkerrand} \abstandlinkerrand + \showsetupA{linkemarginal} \linkemarginalbreite + \showsetupA{linkemarginalafstand} \linkemarginalafstand + \showsetupA{textbreite} \textbreite + \showsetupA{rechtemarginalafstand}\rechtemarginalafstand + \showsetupA{rechtemarginal} \rechtemarginalbreite + \showsetupA{abstandrechterrand} \abstandrechterrand + \showsetupA{rechterrand} \breiterechterrand + \showsetupB{fliesstext} \the \globalbodyfontsize + \showsetupB{linie} \relax \normallineheight + \showsetupB{hoehe} \relax \strutheightfactor + \showsetupB{tiefe} \relax \strutdepthfactor + \showsetupB{topskip} \relax \topskipfactor + \showsetupB{maxdepth} \relax \maxdepthfactor}}} + +\stopinterface + +\startinterface czech + +\gdef\showsetups% + {\noindent + \vbox + {\forgetall + \dontcomplain + \switchtobodyfont[\v!small] + \tabskip\zeropoint + \halign + {\strut##\quad\hss&##\quad\hss&##\quad\hss&##\hss\cr + \showsetupA{vyskapapiru} \vyskapapiru + \showsetupA{sirkapapiru} \sirkapapiru + \showsetupA{vyskatiskpapiru} \vyskatiskpapiru + \showsetupA{sirkatiskpapiru} \sirkatiskpapiru + \showsetupA{hornimezera} \hornimezera + \showsetupA{spodnimezera} \spodnimezera + \showsetupA{vyska} \vyskasazby + \showsetupA{breite} \sirkasazby + \showsetupA{vyskatextu} \vyskatextu + \showsetupA{sirkatextu} \sirkatextu + \showsetupA{horejsek} \vyskahorejsku + \showsetupA{vzdalenosthorejsku} \vzdalenosthorejsku + \showsetupA{zahlavi} \vyskazahlavi + \showsetupA{vzdalenostzahlavi} \vzdalenostzahlavi + \showsetupA{fusszeileabstand} \vzdalenostupati + \showsetupA{upati} \vyskaupati + \showsetupA{vzdalenostspodku} \vzdalenostspodku + \showsetupA{spodek} \vyakaspodku + \showsetupA{levyokraj} \sirkalevehookraje + \showsetupA{vzdalenostlevehookraje} \vzdalenostlevehookraje + \showsetupA{levamarginalie} \sirkalevemarginalie + \showsetupA{vzdalenostlevemarginalie} \vzdalenostlevemarginalie + \showsetupA{vzdalenostpravemarginalie}\vzdalenostpravemarginalie + \showsetupA{pravamarginalie} \sirkapravemarginalie + \showsetupA{vzdalenostpravehookraje} \vzdalenostpravehookraje + \showsetupA{pravyokraj} \sirkapravehookraje + \showsetupB{zakladnivelikost} \the \globalbodyfontsize + \showsetupB{linka} \relax \normallineheight + \showsetupB{vyska} \relax \strutheightfactor + \showsetupB{hloubka} \relax \strutdepthfactor + \showsetupB{topskip} \relax \topskipfactor + \showsetupB{maxdepth} \relax \maxdepthfactor}}} + +\stopinterface + +\startinterface romanian + +\gdef\showsetups% + {\noindent + \vbox + {\forgetall + \dontcomplain + \switchtobodyfont[\v!small] + \tabskip\zeropoint + \halign + {\strut##\quad\hss&##\quad\hss&##\quad\hss&##\hss\cr + \showsetupA{paperheight} \paperheight + \showsetupA{paperwidth} \paperwidth + \showsetupA{printpaperheight} \printpaperheight + \showsetupA{printpaperwidth} \printpaperwidth + \showsetupA{topspace} \topspace + \showsetupA{backspace} \backspace + \showsetupA{height} \makeupheight + \showsetupA{width} \makeupwidth + \showsetupA{top} \topheight + \showsetupA{topdistance} \topdistance + \showsetupA{header} \headerheight + \showsetupA{headerdistance} \headerdistance + \showsetupA{textheight} \textheight + \showsetupA{footerdistance} \footerdistance + \showsetupA{footer} \footerheight + \showsetupA{bottomdistance} \bottomdistance + \showsetupA{bottom} \bottomheight + \showsetupA{leftedge} \leftedgewidth + \showsetupA{leftedgedistance} \leftedgedistance + \showsetupA{leftmargin} \leftmarginwidth + \showsetupA{leftmargindistance} \leftmargindistance + \showsetupA{textwidth} \textwidth + \showsetupA{rightmargindistance}\rightmargindistance + \showsetupA{rightmargin} \rightmarginwidth + \showsetupA{rightedgedistance} \rightedgedistance + \showsetupA{rightedge} \rightedgewidth + \showsetupB{bodyfontsize} \the \globalbodyfontsize + \showsetupB{line} \relax \normallineheight + \showsetupB{height} \relax \strutheightfactor + \showsetupB{depth} \relax \strutdepthfactor + \showsetupB{topskip} \relax \topskipfactor + \showsetupB{maxdepth} \relax \maxdepthfactor}}} + +\stopinterface + +\gdef\showlayout % interfereert lelijk met een \typefile er na + {\bgroup + \page + \showframe + \setuplayout[\c!marking=\v!on] + \dorecurse{4}{\showsetups\page} + \egroup} + +\gdef\showmargins + {\starttabulate + \NC asynchrone \NC \doifoddpageelse {odd} {even} \NC \NR + \NC synchrone \NC \doifrightpageelse {right} {left} \NC \NR + \NC right margin \NC \the\rightmarginwidth \NC \NR + \NC left margin \NC \the\leftmarginwidth \NC \NR + \NC outer margin \NC \the\outermarginwidth \NC \NR + \NC inner margin \NC \the\innermarginwidth \NC \NR + \stoptabulate} + +\protect \endinput diff --git a/tex/context/base/page-run.mkiv b/tex/context/base/page-run.mkiv new file mode 100644 index 000000000..ae5af81e9 --- /dev/null +++ b/tex/context/base/page-run.mkiv @@ -0,0 +1,382 @@ +%D \module +%D [ file=page-run, +%D version=2000.10.20, +%D title=\CONTEXT\ Page 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. + +\writestatus{loading}{ConTeXt Page Macros / Runtime Macros} + +\unprotect + +\gdef\doshowprint[#1][#2][#3]% + {\framed + [\c!offset=\v!overlay, + \c!strut=\v!no] + {\forgetall + \dontcomplain + \globaldefs\minusone + \dimen0\pagegoal + \definepapersize[X][\c!width=4em, \c!height=6em]% + \definepapersize[Y][\c!width=12em,\c!height=14em]% + \setuppapersize[#1,X][#2,Y]% + \setuplayout[#3]% + \setbox0\vbox + {\framed + [\c!offset=\v!overlay,\c!strut=\v!no, + \c!width=\paperwidth,\c!height=\paperheight] + {\ss ABC\par DEF}}% + \doublesidedfalse + \def\cutmarklength{.5em}% + \addpagecutmarks0% + \replicatepagebox0% + \scalepagebox0% + \mirrorpaperbox0% + \orientpaperbox0% + \centerpagebox0% + \mirrorprintbox0% + \orientprintbox0% + \offsetprintbox0% + \pagegoal\dimen0 + \box0}} + +\gdef\showprint + {\dotripleempty\doshowprint} + +% \switchnaarkorps[8pt] +% +% \startcombinatie[4*4] +% {\toonprint} {\strut} +% {\toonprint[][][plaats=midden]} {\type{plaats=midden}} +% {\toonprint[][][plaats=midden,markering=aan]} {\type{markering=aan}\break +% \type{plaats=midden}} +% {\toonprint[][][plaats=midden,markering=aan,nx=2]} {\type{markering=aan}\break +% \type{plaats=midden}\break +% \type{nx=2}} +% {\toonprint[][][plaats=links]} {\type{plaats=links}} +% {\toonprint[][][plaats=rechts]} {\type{plaats=rechts}} +% {\toonprint[][][plaats={links,onder}]} {\type{plaats={links,onder}}} +% {\toonprint[][][plaats={rechts,onder}]} {\type{plaats={rechts,onder}}} +% {\toonprint[][][nx=2,ny=1]} {\type{nx=2,ny=1}} +% {\toonprint[][][nx=1,ny=2]} {\type{nx=1,ny=2}} +% {\toonprint[][][nx=2,ny=2]} {\type{nx=2,ny=2}} +% {\toonprint[][][nx=2,ny=2,plaats=midden]} {\type{nx=2,ny=2}\break +% \type{plaats=midden}} +% {\toonprint[][][rugoffset=3pt]} {\type{rugoffset=.5cm}} +% {\toonprint[][][kopoffset=3pt]} {\type{kopoffset=.5cm}} +% {\toonprint[][][schaal=1.5]} {\type{schaal=1.5}} +% {\toonprint[][][schaal=0.8]} {\type{schaal=0.8}} +% \stopcombinatie +% +% \startcombinatie[3*4] +% {\toonprint[liggend][][plaats=midden]} {\type{liggend}} +% {\toonprint[][liggend][plaats=midden]} {\strut\break\type{liggend}} +% {\toonprint[liggend][liggend][plaats=midden]} {\type{liggend}\break\type{liggend}} +% {\toonprint[90][][plaats=midden]} {\type{90}} +% {\toonprint[][90][plaats=midden]} {\strut\break\type{90}} +% {\toonprint[90][90][plaats=midden]} {\type{90}\break\type{90}} +% {\toonprint[180][][plaats=midden]} {\type{180}} +% {\toonprint[][180][plaats=midden]} {\strut\break\type{180}} +% {\toonprint[180][180][plaats=midden]} {\type{180}\break\type{180}} +% {\toonprint[gespiegeld][][plaats=midden]} {\type{gespiegeld}} +% {\toonprint[][gespiegeld][plaats=midden]} {\strut\break\type{gespiegeld}} +% {\toonprint[gespiegeld][gespiegeld][plaats=midden]} {\type{gespiegeld}\break\type{gespiegeld}} +% \stopcombinatie + +\gdef\doshowframe[#1][#2]% + {\ifsecondargument + \setupbackgrounds + [\v!page] + [\c!frame=\v!on, + \c!corner=\v!rectangular, + \c!frameoffset=\!!zeropoint, + \c!framedepth=\!!zeropoint, + \c!framecolor=layout:page] + \setupbackgrounds + [#1][#2] + [\c!background=, + \c!frame=\v!on, + \c!corner=\v!rectangular, + \c!frameoffset=\!!zeropoint, + \c!framedepth=\!!zeropoint, + \c!framecolor=] + \else\iffirstargument + \showframe + [\v!header,\v!text,\v!footer] + [#1] + \else + \showframe + [\v!header,\v!text,\v!footer] + [\v!leftedge,\v!leftmargin, + \v!text, + \v!rightmargin,\v!rightedge] + \fi\fi + \setupbackgrounds + [\c!state=\v!repeat]} + +\gdef\showframe{\dodoubleempty\doshowframe} + +\gdef\showsetupA#1#2% + {#1&\PtToCm{\the#2}&\the#2&\tttf\string#2\cr} + +\gdef\showsetupB#1#2#3% + {#1&#3&\tttf\string#3\cr} + +% \startinterface english % english is fallback + +\gdef\showsetups + {\noindent + \vbox + {\forgetall + \dontcomplain + \switchtobodyfont[\v!small] + \tabskip\zeropoint + \halign + {\strut##\quad\hss&##\quad\hss&##\quad\hss&##\hss\cr + \showsetupA{paperheight} \paperheight + \showsetupA{paperwidth} \paperwidth + \showsetupA{printpaperheight} \printpaperheight + \showsetupA{printpaperwidth} \printpaperwidth + \showsetupA{topspace} \topspace + \showsetupA{backspace} \backspace + \showsetupA{height} \makeupheight + \showsetupA{width} \makeupwidth + \showsetupA{top} \topheight + \showsetupA{topdistance} \topdistance + \showsetupA{header} \headerheight + \showsetupA{headerdistance} \headerdistance + \showsetupA{textheight} \textheight + \showsetupA{footerdistance} \footerdistance + \showsetupA{footer} \footerheight + \showsetupA{bottomdistance} \bottomdistance + \showsetupA{bottom} \bottomheight + \showsetupA{leftedge} \leftedgewidth + \showsetupA{leftedgedistance} \leftedgedistance + \showsetupA{leftmargin} \leftmarginwidth + \showsetupA{leftmargindistance} \leftmargindistance + \showsetupA{textwidth} \textwidth + \showsetupA{rightmargindistance}\rightmargindistance + \showsetupA{rightmargin} \rightmarginwidth + \showsetupA{rightedgedistance} \rightedgedistance + \showsetupA{rightedge} \rightedgewidth + \showsetupB{bodyfontsize} \the \globalbodyfontsize + \showsetupB{line} \relax \normallineheight + \showsetupB{height} \relax \strutheightfactor + \showsetupB{depth} \relax \strutdepthfactor + \showsetupB{topskip} \relax \topskipfactor + \showsetupB{maxdepth} \relax \maxdepthfactor}}} + +% \stopinterface + +\startinterface dutch + +\gdef\showsetups + {\noindent + \vbox + {\forgetall + \dontcomplain + \switchtobodyfont[\v!small] + \tabskip\zeropoint + \halign + {\strut##\quad\hss&##\quad\hss&##\quad\hss&##\hss\cr + \showsetupA{papierhoogte} \papierhoogte + \showsetupA{papierbreedte} \papierbreedte + \showsetupA{printpapierhoogte} \printpapierhoogte + \showsetupA{printpapierbreedte} \printpapierbreedte + \showsetupA{kopwit} \kopwit + \showsetupA{rugwit} \rugwit + \showsetupA{snijwit} \snijwit + \showsetupA{hoogte} \zethoogte + \showsetupA{breedte} \zetbreedte + \showsetupA{boven} \bovenhoogte + \showsetupA{bovenafstand} \bovenafstand + \showsetupA{hoofd} \hoofdhoogte + \showsetupA{hoofdafstand} \hoofdafstand + \showsetupA{teksthoogte} \teksthoogte + \showsetupA{voetafstand} \voetafstand + \showsetupA{voet} \voethoogte + \showsetupA{onderafstand} \onderafstand + \showsetupA{onder} \onderhoogte + \showsetupA{linkerrand} \linkerrandbreedte + \showsetupA{linkerrandafstand} \linkerrandafstand + \showsetupA{linkermarge} \linkermargebreedte + \showsetupA{linkermargeafstand} \linkermargeafstand + \showsetupA{tekstbreedte} \tekstbreedte + \showsetupA{rechtermargeafstand}\rechtermargeafstand + \showsetupA{rechtermarge} \rechtermargebreedte + \showsetupA{rechterrandafstand} \rechterrandafstand + \showsetupA{rechterrand} \rechterrandbreedte + \showsetupB{korps} \the \globalbodyfontsize + \showsetupB{regel} \relax \normallineheight + \showsetupB{hoogte} \relax \strutheightfactor + \showsetupB{diepte} \relax \strutdepthfactor + \showsetupB{boven} \relax \topskipfactor + \showsetupB{onder} \relax \maxdepthfactor}}} + +\stopinterface + +% todo: \showsetupA{rugwit} \rugwit + +\startinterface german + +\gdef\showsetups% + {\noindent + \vbox + {\forgetall + \dontcomplain + \switchtobodyfont[\v!small] + \tabskip\zeropoint + \halign + {\strut##\quad\hss&##\quad\hss&##\quad\hss&##\hss\cr + \showsetupA{papierhoehe} \papierhoehe + \showsetupA{papierbreite} \papierbreite + \showsetupA{printpapierhoehe} \printpapierhoehe + \showsetupA{printpapierbreite} \printpapierbreite + \showsetupA{kopfweite} \kopfweite + \showsetupA{rumpfweite} \rumpfweite + \showsetupA{hoehe} \satzhoehe + \showsetupA{breite} \satzbreite + \showsetupA{oben} \hoeheoben + \showsetupA{abstandoben} \abstandoben + \showsetupA{kopfzeile} \kopfzeilenhoehe + \showsetupA{kopfzeilenabstand} \kopfzeilenabstand + \showsetupA{texthoehe} \texthoehe + \showsetupA{fusszeileabstand} \fusszeileabstand + \showsetupA{fusszeilen} \fusszeilenhoehe + \showsetupA{abstandunten} \abstandunten + \showsetupA{hoeheunten} \hoeheunten + \showsetupA{linkerrand} \breitelinkerrand + \showsetupA{abstandlinkerrand} \abstandlinkerrand + \showsetupA{linkemarginal} \linkemarginalbreite + \showsetupA{linkemarginalafstand} \linkemarginalafstand + \showsetupA{textbreite} \textbreite + \showsetupA{rechtemarginalafstand}\rechtemarginalafstand + \showsetupA{rechtemarginal} \rechtemarginalbreite + \showsetupA{abstandrechterrand} \abstandrechterrand + \showsetupA{rechterrand} \breiterechterrand + \showsetupB{fliesstext} \the \globalbodyfontsize + \showsetupB{linie} \relax \normallineheight + \showsetupB{hoehe} \relax \strutheightfactor + \showsetupB{tiefe} \relax \strutdepthfactor + \showsetupB{topskip} \relax \topskipfactor + \showsetupB{maxdepth} \relax \maxdepthfactor}}} + +\stopinterface + +\startinterface czech + +\gdef\showsetups% + {\noindent + \vbox + {\forgetall + \dontcomplain + \switchtobodyfont[\v!small] + \tabskip\zeropoint + \halign + {\strut##\quad\hss&##\quad\hss&##\quad\hss&##\hss\cr + \showsetupA{vyskapapiru} \vyskapapiru + \showsetupA{sirkapapiru} \sirkapapiru + \showsetupA{vyskatiskpapiru} \vyskatiskpapiru + \showsetupA{sirkatiskpapiru} \sirkatiskpapiru + \showsetupA{hornimezera} \hornimezera + \showsetupA{spodnimezera} \spodnimezera + \showsetupA{vyska} \vyskasazby + \showsetupA{breite} \sirkasazby + \showsetupA{vyskatextu} \vyskatextu + \showsetupA{sirkatextu} \sirkatextu + \showsetupA{horejsek} \vyskahorejsku + \showsetupA{vzdalenosthorejsku} \vzdalenosthorejsku + \showsetupA{zahlavi} \vyskazahlavi + \showsetupA{vzdalenostzahlavi} \vzdalenostzahlavi + \showsetupA{fusszeileabstand} \vzdalenostupati + \showsetupA{upati} \vyskaupati + \showsetupA{vzdalenostspodku} \vzdalenostspodku + \showsetupA{spodek} \vyakaspodku + \showsetupA{levyokraj} \sirkalevehookraje + \showsetupA{vzdalenostlevehookraje} \vzdalenostlevehookraje + \showsetupA{levamarginalie} \sirkalevemarginalie + \showsetupA{vzdalenostlevemarginalie} \vzdalenostlevemarginalie + \showsetupA{vzdalenostpravemarginalie}\vzdalenostpravemarginalie + \showsetupA{pravamarginalie} \sirkapravemarginalie + \showsetupA{vzdalenostpravehookraje} \vzdalenostpravehookraje + \showsetupA{pravyokraj} \sirkapravehookraje + \showsetupB{zakladnivelikost} \the \globalbodyfontsize + \showsetupB{linka} \relax \normallineheight + \showsetupB{vyska} \relax \strutheightfactor + \showsetupB{hloubka} \relax \strutdepthfactor + \showsetupB{topskip} \relax \topskipfactor + \showsetupB{maxdepth} \relax \maxdepthfactor}}} + +\stopinterface + +\startinterface romanian + +\gdef\showsetups% + {\noindent + \vbox + {\forgetall + \dontcomplain + \switchtobodyfont[\v!small] + \tabskip\zeropoint + \halign + {\strut##\quad\hss&##\quad\hss&##\quad\hss&##\hss\cr + \showsetupA{paperheight} \paperheight + \showsetupA{paperwidth} \paperwidth + \showsetupA{printpaperheight} \printpaperheight + \showsetupA{printpaperwidth} \printpaperwidth + \showsetupA{topspace} \topspace + \showsetupA{backspace} \backspace + \showsetupA{height} \makeupheight + \showsetupA{width} \makeupwidth + \showsetupA{top} \topheight + \showsetupA{topdistance} \topdistance + \showsetupA{header} \headerheight + \showsetupA{headerdistance} \headerdistance + \showsetupA{textheight} \textheight + \showsetupA{footerdistance} \footerdistance + \showsetupA{footer} \footerheight + \showsetupA{bottomdistance} \bottomdistance + \showsetupA{bottom} \bottomheight + \showsetupA{leftedge} \leftedgewidth + \showsetupA{leftedgedistance} \leftedgedistance + \showsetupA{leftmargin} \leftmarginwidth + \showsetupA{leftmargindistance} \leftmargindistance + \showsetupA{textwidth} \textwidth + \showsetupA{rightmargindistance}\rightmargindistance + \showsetupA{rightmargin} \rightmarginwidth + \showsetupA{rightedgedistance} \rightedgedistance + \showsetupA{rightedge} \rightedgewidth + \showsetupB{bodyfontsize} \the \globalbodyfontsize + \showsetupB{line} \relax \normallineheight + \showsetupB{height} \relax \strutheightfactor + \showsetupB{depth} \relax \strutdepthfactor + \showsetupB{topskip} \relax \topskipfactor + \showsetupB{maxdepth} \relax \maxdepthfactor}}} + +\stopinterface + +\gdef\showlayout % interfereert lelijk met een \typefile er na + {\bgroup + \page + \showframe + \setuplayout[\c!marking=\v!on] + \dorecurse{4}{\showsetups\page} + \egroup} + +\gdef\showmargins + {\starttabulate + \NC asynchrone \NC \doifoddpageelse {odd} {even} \NC \NR + \NC synchrone \NC \doifrightpageelse {right} {left} \NC \NR + \NC right margin \NC \the\rightmarginwidth \NC \NR + \NC left margin \NC \the\leftmarginwidth \NC \NR + \NC outer margin \NC \the\outermarginwidth \NC \NR + \NC inner margin \NC \the\innermarginwidth \NC \NR + \stoptabulate} + +\protect \endinput diff --git a/tex/context/base/page-set.mkii b/tex/context/base/page-set.mkii new file mode 100644 index 000000000..eb01799ae --- /dev/null +++ b/tex/context/base/page-set.mkii @@ -0,0 +1,2766 @@ +%D \module +%D [ file=page-set, +%D version=2000.10.20, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Column Sets, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% getnoflines vs getrawnoflines + +% some day: cleanup and go etex + +\writestatus{loading}{ConTeXt Page Macros / Column Sets} + +% todo : last longer than previous +% todo : block span over last column if footnotes +% todo : diagnosis balancing run +% todo : separate footnote placement +% todo : go on on same page with colset +% todo : test page areas per page +% todo : leftmargin/rightmargin (better than afstand(1)) + +% use the OTRSET layer for more purposes, like the footnotes ! + +\unprotect + +\newcount\tofcolumns % total +\newcount\lofcolumns % left +\newcount\rofcolumns % right + +\newcount\columnfirstcell \columnfirstcell=1 +\newcount\columnlastcell +\newcount\columnfreecells +\newcount\currenthcell +\newcount\currentvcell +\newcount\columnhcells +\newcount\columnvcells + +\newif\ifenoughcolumncells +\newif\ifsomefreecolumncells +\newif\ifcolumnspread +\newif\iftracecolumnset % \tracecolumnsettrue + +\def\columnmaxcells {75} % runtime +\def\columnmaxfreecells {0} % runtime +\def\columngaplimit {0} % {5} + +\def\@otr@{otr} + +\def\OTRSETmakeupwidth{\innermakeupwidth} + +\let\OTRSETflushsidefloats \forgetsidefloats % \relax +\let\OTRSETsynchronizesidefloats\forgetsidefloats % \relax + +\def\OTRSETgridcell #1#2{\csname \@otr@:\number#1:\number#2\endcsname} +\def\OTRSETgetgridcell#1#2{\box\csname \@otr@:\number#1:\number#2\endcsname} +\def\OTRSETsetgridcell#1#2{\global\setbox\csname\@otr@:\number#1:\number#2\endcsname} + +\long\def\OTRSETdoifcellelse#1#2% + {\relax\ifvoid\csname\@otr@:\number#1:\number#2\endcsname + \@EA\secondoftwoarguments\else\@EA\firstoftwoarguments + \fi} + +% The following two macros are used to compensate for a switch in body fonts +% as in: +% +% \definecolumnset [two] [n=2,balancing=yes] +% \definecolumnset [three] [n=3,balancing=yes] +% +% \setupcolumnsetlines[two][1][1][7] +% \setupcolumnsetlines[two][1][2][10] +% +% \setupcolumnsetlines[three][1][1][40] +% \setupcolumnsetlines[three][1][2][40] +% \setupcolumnsetlines[three][1][3][40] +% +% \setupcolumnsetstart[three][1][1][15] +% \setupcolumnsetstart[three][1][2][20] +% \setupcolumnsetstart[three][1][3][20] +% +% \starttext +% \startcolumnset [two] \dorecurse {1}{\input tufte \par} \stopcolumnset +% \switchtobodyfont[small] +% \startcolumnset [three] \dorecurse {1}{\input tufte \par} \stopcolumnset +% \stoptext + +%D Marks in columnsets: +%D +%D \starttyping +%D \definemarking[M] +%D \setupheadertexts[\setups{show-M-marks}] +%D \definecolumnset[test][n=3] +%D +%D \startsetups show-M-marks +%D \getmarking[M][1][previous]/\getmarking[M][1][first]/\getmarking[M][1][last]\quad +%D \getmarking[M][2][previous]/\getmarking[M][2][first]/\getmarking[M][2][last]\quad +%D \getmarking[M][3][previous]/\getmarking[M][3][first]/\getmarking[M][3][last]\quad +%D \getmarking[M][1][previous]/\getmarking[M][1][first]/\getmarking[M][last]\quad +%D \getsavedmarking[M][previous]/\getsavedmarking[M][first]/\getsavedmarking[M][last] +%D \stopsetups +%D +%D \startbuffer +%D \section{Knuth} [K1]\marking[M]{k1} [K2]\marking[M]{k2} \input knuth +%D \section{Zapf} [Z]\marking[M]{z} \input zapf +%D \stopbuffer +%D +%D \startbuffer +%D \section{Ward} [W]\marking[M]{w} \input ward +%D \placefigure[here]{none}{\externalfigure[a][height=2cm]} +%D \section{Davis} [D]\marking[M]{d} \input davis +%D \section{Zapf} [Z]\marking[M]{z} \input zapf +%D \stopbuffer +%D +%D \startbuffer +%D \section{Ward} [W]\marking[M]{w} \input ward +%D \placefigure[here]{none}{\externalfigure[a][height=2cm]} +%D \section{Davis} [D]\marking[M]{d} \input davis +%D \section{Zapf} [Z]\marking[M]{z} \input zapf +%D \section{Douglas} [O]\marking[M]{o} \input douglas +%D \stopbuffer +%D +%D \starttext +%D \startcolumnset[test] +%D \dorecurse{5}{\getbuffer} +%D \placefigure[here]{none}{\externalfigure[a][height=2cm]} +%D % \column % sometimes needed +%D \stopcolumnset +%D \stoptext +%D \stoptyping + +% not ok yet, for column sets we need a special case: within a column we +% need to bubble-up the marks; the indirectness permits overloading here + +\let\saveOTRSETmark \refreshsavedmark +\let\bubbleOTRSETmark\bubblesavedmark +\let\resetOTRSETmark \resetsavedmark +\let\presetOTRSETmark\presetsavedmark + +\def\doregisterOTRSETmarks#1{\saveOTRSETmark [#1][\number\mofcolumns]} +\def\dobubbleOTRSETmarks #1{\bubbleOTRSETmark[#1][\number\mofcolumns]} +\def\doresetOTRSETmarks #1{\resetOTRSETmark [#1][\recurselevel]} +\def\dopresetOTRSETmarks #1{\presetOTRSETmark[#1][\recurselevel]} + +\def\registerOTRSETmarks + {\processcommacommand[\alldefinedmarks]\doregisterOTRSETmarks} +\def\bubbleOTRSETmarks + {\processcommacommand[\alldefinedmarks]\dobubbleOTRSETmarks} +\def\resetOTRSETmarks + {\dorecurse\nofcolumns{\processcommacommand[\alldefinedmarks]\doresetOTRSETmarks}} +\def\presetOTRSETmarks + {\dorecurse\nofcolumns{\processcommacommand[\alldefinedmarks]\dopresetOTRSETmarks}} + +%D test case of Vit Zika (context list): +%D +%D \starttyping +%D \setuplayout[height=middle,width=middle,grid=yes] +%D +%D \starttext +%D \startcolumnset +%D \dorecurse{10} +%D {\input thuan \endgraf +%D \bgroup +%D \ss\restoreinterlinespace +%D \dorecurse{3}{\input hawking \endgraf} +%D \egroup +%D \input bryson \endgraf} +%D \stopcolumnset +%D \stoptext +%D \stoptyping + +\def\OTRSETsetcorrectnofcells#1% + {\bgroup + \!!counta#1\relax + \ifdim\globalbodyfontsize=\localbodyfontsize + \restoreinterlinespace + \else + \!!dimena-\!!counta\lineheight + \restoreglobalbodyfont % slow, we need a fast one + \advance\!!dimena\!!counta\lineheight + \getnoflines\!!dimena + \advance\!!counta\noflines + \ifnum\!!counta<#1\else + \!!counta#1\relax + \fi + \fi + \relax % needed ! ! ! ! else lookahead over \fi and \@EA + \@EA\egroup\@EA\scratchcounter\the\!!counta\relax} + +\def\OTRSETsetcorrectcellht + {\bgroup + \!!dimena-\strutht\relax + \ifdim\globalbodyfontsize=\localbodyfontsize + \restoreinterlinespace + \else + \restoreglobalbodyfont + \fi + \advance\!!dimena\strutht + \relax % needed ! ! ! ! else lookahead over \fi and \@EA + \@EA\egroup\@EA\scratchdimen\the\!!dimena\relax} + +\def\columnerasegridboxes % maybe dedicated loops + {\bgroup + \increment\columnmaxcells\relax + \ifodd\realpageno + \else % we are on the other page + \columnspreadfalse + \fi + \ifcolumnspread + \dorecurse\nofcolumns + {\let\!!stringa\recurselevel + \scratchcounter\recurselevel \advance\scratchcounter\lofcolumns + \edef\!!stringb{\the\scratchcounter}% + \dostepwiserecurse \zerocount \columnmaxcells \plusone + {\ifcsname\@otr@:\!!stringa:\recurselevel\endcsname + \global\setbox\csname\@otr@:\!!stringa:\recurselevel\endcsname + \ifcsname\@otr@:\!!stringb:\recurselevel\endcsname + \box\csname\@otr@:\!!stringb:\recurselevel\endcsname + %\global\setbox\csname\@otr@:\!!stringa:\recurselevel\endcsname\box\csname\@otr@:\!!stringb:\recurselevel\endcsname + \else + \emptybox + %\global\setbox\csname\@otr@:\!!stringa:\recurselevel\endcsname\emptybox + \expandafter\newbox\csname\@otr@:\!!stringb:\recurselevel\endcsname + \fi + \else + \expandafter\newbox\csname\@otr@:\!!stringa:\recurselevel\endcsname + \ifcsname\@otr@:\!!stringb:\recurselevel\endcsname + \global\setbox\csname\@otr@:\!!stringa:\recurselevel\endcsname\box\csname\@otr@:\!!stringb:\recurselevel\endcsname + \else + \expandafter\newbox\csname\@otr@:\!!stringb:\recurselevel\endcsname + \fi + \fi}}% + \else + \dorecurse \tofcolumns + {\let\!!stringa\recurselevel + \dostepwiserecurse \zerocount \columnmaxcells \plusone + {\ifcsname\@otr@:\!!stringa:\recurselevel\endcsname + \global\setbox\csname\@otr@:\!!stringa:\recurselevel\endcsname\emptybox + \else + \expandafter\newbox\csname\@otr@:\!!stringa:\recurselevel\endcsname + \fi}}% + \fi + \dorecurse\tofcolumns + {\global\setbox\csname\@otr@:\recurselevel:\columnmaxcells\endcsname\copy\placeholderboxa}% + \global\columnfirstcell\zerocount + \global\columnlastcell\columnfirstcell + \global\columnfreecells\columnfirstcell + \egroup} + +\def\doOTRSETsetgridcells#1#2#3#4#5#6% placeholder col row wid hei {data} + {\!!countd#2\advance\!!countd#4\advance\!!countd\minusone + \!!counte#3\advance\!!counte#5\advance\!!counte\minusone + \dostepwiserecurse{#2}\!!countd\plusone + {\!!countf\recurselevel + \dostepwiserecurse{#3}\!!counte\plusone + {\OTRSETsetgridcell\!!countf\recurselevel#1}}% + \dostepwiserecurse{#3}\!!counte\plusone + {\global\wd\OTRSETgridcell{#2}\recurselevel\hsize}% + \OTRSETsetgridcell{#2}\!!counte#6} + +\def\OTRSETsetgridcells + {\doOTRSETsetgridcells{\copy\placeholderboxb}} + +\def\OTRSETerasegridcells#1#2#3#4% + {\doOTRSETsetgridcells{\emptybox}{#1}{#2}{#3}{#4}{\emptybox}} + +\def\setupcolumnsetlines{\doquintupleempty\dosetupcolumnsettrick[l]} +\def\setupcolumnsetstart{\doquintupleempty\dosetupcolumnsettrick[s]} + +\def\dosetupcolumnsettrick[#1][#2][#3][#4][#5]% tag id page col value + {% not needed, is already relative + % \doifinstringelse{+}{#3}{\scratchcounter\realpageno}{\scratchcounter\zerocount}% + % \advance\scratchcounter#3\relax % \relax needed + % \setevalue{\??mc:#1:#2:\the\scratchcounter:\number#4}{\number#5}} + \iffifthargument + \setevalue{\??mc:#1:#2:\number#3:\number#4}{\number#5}% + \else + \setevalue{\??mc:#1:#2:\number#3:0}{\number#4}% + \fi} + +\def\currentcolumnmaxcellstag #1{\??mc:l:\OTRSETidentifier:\columnsetpage:\number#1} +\def\currentcolumnstartcelltag#1{\??mc:s:\OTRSETidentifier:\columnsetpage:\number#1} + +\def\doresetcolumnsetlines#1% + {\ifcsname\currentcolumnmaxcellstag{#1}\endcsname + \letgvalue{\currentcolumnmaxcellstag{#1}}\zerocount + \fi + \ifcsname\currentcolumnmaxcellstag{#1}\endcsname + \letgvalue{\currentcolumnmaxcellstag{#1}}\zerocount + \fi} + +\def\currentcolumnsomecells#1#2% + {\ifcsname#1\mofcolumns\endcsname + \ifnum\csname#1\mofcolumns\endcsname=\zerocount + #2% + \else + \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\relax + \fi + \else + #2% + \fi\fi} + +\def\currentcolumnmaxcells {\currentcolumnsomecells\currentcolumnmaxcellstag \columnmaxcells} +\def\currentcolumnstartcell{\currentcolumnsomecells\currentcolumnstartcelltag\plusone} + +\def\OTRSETsetfreecells#1#2% col start + {\bgroup + \global\columnfirstcell\ifnum#2=0 1\else#2\fi\relax + \OTRSETsetcorrectnofcells\currentcolumnmaxcells % sets \scratchcounter + \edef\columnmaxcells{\the\scratchcounter}% + \ifnum\columnfirstcell>\columnmaxcells + \global\columnfreecells\zerocount + \global\columnfirstcell\plusone + \global\columnlastcell \zerocount + \global\somefreecolumncellsfalse + %\message{no cells a}% + \else + \doloop + {\ifnum\columnfirstcell>\columnmaxcells\relax + \exitloop + \else + \OTRSETdoifcellelse{#1}\columnfirstcell + {\global\advance\columnfirstcell\plusone}\exitloop + \fi}% + \global\columnlastcell\columnfirstcell + \doloop + {\ifnum\columnlastcell>\columnmaxcells\relax + \exitloop + \else + \OTRSETdoifcellelse{#1}\columnlastcell + {\global\advance\columnlastcell \minusone \exitloop} + {\global\advance\columnlastcell \plusone }% + \fi}% + \ifnum\columnfirstcell>\columnmaxcells + \global\columnfreecells\zerocount + \global\columnfirstcell\plusone + \global\columnlastcell \zerocount + \global\somefreecolumncellsfalse + %\message{no cells b}% + \else + \ifnum\columnlastcell>\columnmaxcells + \global\columnlastcell\columnmaxcells + \fi + \global\columnfreecells\columnlastcell + \global\advance\columnfreecells -\columnfirstcell + \global\advance\columnfreecells \plusone + \global\somefreecolumncellstrue + %\message{\number\columnfirstcell-\number\columnlastcell=\number\columnfreecells}% + \fi + \fi + \egroup} + +\def\OTRSETgetmaxfreecells#1#2% col start + {\let\columnmaxfreecells\!!zerocount + \let\columnfrmfreecells\!!zerocount + \pushmacro \columnmaxcells +\OTRSETsetcorrectnofcells\currentcolumnmaxcells % sets \scratchcounter +\edef\columnmaxcells{\the\scratchcounter}% + \scratchcounter\zerocount + \dostepwiserecurse{#2}\columnmaxcells\plusone + {\OTRSETdoifcellelse{#1}\recurselevel + {\ifnum\columnmaxfreecells<\scratchcounter + \edef\columnmaxfreecells{\the\scratchcounter}% + \let\columnfrmfreecells\recurselevel + \fi + \scratchcounter\zerocount} + {\advance\scratchcounter\plusone}}% + \popmacro\columnmaxcells} + +\long\def\OTRSETrecurseRL#1% + {\dostepwiserecurse\nofcolumns\plusone\minusone + {#1\hskip\OTRSETgetparameter\c!distance\recurselevel}} + +\def\OTRSETmakegridbox + {\ifcase\columndirection + \OTRSETdomakegridbox\plusone\nofcolumns\plusone + \else + \OTRSETdomakegridbox\nofcolumns\plusone\minusone + \fi} + +\def\OTRSETmakeupwidth{\makeupwidth} % temporary indirectness + +\def\OTRSETdomakegridbox#1#2#3% + {\hbox\bgroup + \dontcomplain + \forgetall % can go once in \flush + \!!heighta \textheight + % test first ! + \hbox to \OTRSETmakeupwidth + {\dostepwiserecurse{#1}{#2}{#3} + {\mofcolumns\recurselevel + \localcolumnwidth\OTRSETlocalwidth\mofcolumns + \setbox\scratchbox\hbox\localframed + [\??mc\OTRSETidentifier\number\mofcolumns]% + [\c!width=\localcolumnwidth,\c!height=\!!heighta,\c!lines=]% + {}% + \wd\scratchbox\localcolumnwidth + \ht\scratchbox\!!heighta + \ifcase\columndirection + \hskip\OTRSETgetparameter\c!distance\recurselevel + \box\scratchbox + \else + \box\scratchbox + \hskip\OTRSETgetparameter\c!distance\recurselevel + \fi}}% + \hskip-\OTRSETmakeupwidth + % main text + \hbox to \OTRSETmakeupwidth + {\dostepwiserecurse{#1}{#2}{#3} + {\mofcolumns\recurselevel + \localcolumnwidth\OTRSETlocalwidth\mofcolumns + \offinterlineskip + \setbox\scratchbox\vbox to \!!heighta + {\topskipcorrection % not needed + \ifcase\OTRSETbalancemethod + % no + \or + % yes + \doifelselayerdata{OTRTEXT}\vfill\relax % temp hack + \or + % top + \or + % bottom + \vfill + \fi + \dorecurse\columnmaxcells + {\setbox\scratchbox\hbox{\OTRSETgetgridcell\mofcolumns\recurselevel}% +% {\setbox\scratchbox\hbox +% {\localstarttextcolor +% \OTRSETgetgridcell\mofcolumns\recurselevel +% \localstoptextcolor}% + \ht\scratchbox\strutht + \dp\scratchbox\strutdp + \ifcase\columndirection + \box\scratchbox + \else + \hbox to \localcolumnwidth + {\hskip\localcolumnwidth\llap{\box\scratchbox}}% + \fi + \par}% + \ifcase\OTRSETbalancemethod + % no + \else + % yes, top, bottom + \ifdim\globalbodyfontsize=\localbodyfontsize + \removedepth + \restoreglobalbodyfont + \vskip\strutdepth + \fi + \kern\zeropoint + \vss + \fi}% + \wd\scratchbox\localcolumnwidth % \textwidth + \ifcase\columndirection + \hskip\OTRSETgetparameter\c!distance\recurselevel\box\scratchbox + \else + \box\scratchbox\hskip\OTRSETgetparameter\c!distance\recurselevel + \fi}}% + \egroup} + +\let\OTRSETbalht\zeropoint + +\def\OTRSETreducegridbox % for the moment no difference between methods + {\globallet\OTRSETbalht\zeropoint + \ifcase\OTRSETbalancemethod + % no balancing + \else + \bgroup + \!!counta\columnmaxcells + \donetrue + \doloop + {\dorecurse\nofcolumns{\OTRSETdoifcellelse\recurselevel\!!counta\donefalse\donothing}% + \ifdone + \ifnum\!!counta>\plusone\advance\!!counta\minusone\else\exitloop\fi + \else + \exitloop + \fi}% + \ifnum\!!counta>\plusone + \!!heighta\lineheight + \multiply\!!heighta \!!counta + \advance\!!heighta \topskip + \advance\!!heighta -\lineheight + \else + \!!heighta\zeropoint + \fi + \xdef\OTRSETbalht{\the\!!heighta}% + \egroup + \fi} + +\def\OTRSETflushfinalfootnotes + {\ifcase\lastcolumnlastcell \else + \setbox\scratchbox\hbox + {\placebottomnotes}% + \ifdim\ht\scratchbox>\zeropoint + \setbox\scratchbox\hbox + {\hbox to \zeropoint{\OTRSETgetgridcell\nofcolumns\lastcolumnlastcell}% + \box\scratchbox}% + \ht\scratchbox\strutht + \dp\scratchbox\strutdp + \OTRSETsetgridcell\nofcolumns\lastcolumnlastcell\box\scratchbox + \fi + \global\lastcolumnlastcell\zerocount + \fi} + +\def\OTRSETdoflush + {\ifcollectingcontent + \registerOTRSETmarks + \global\mofcolumns\plusone + \else + \OTRSETdofinalflush + \OTRSETdofinaloutput + \ifnum\columnsetpage>0 + \dorecurse\nofcolumns{\doresetcolumnsetlines\recurselevel}% + \fi + \doglobal\increment\columnsetpage + \OTRSETinitializecolumns + %\OTRSETdoflushfloats + \OTRSETstartnextpage +\presetOTRSETmarks + \initializecolumntextareas + \fi} + +\newbox\OTRfinalpagebox + +\def\OTRSETdofinalflush % see \OTRSETdoflush + {\OTRSETflushfinalfootnotes + \placecolumntextareas + \OTRSETcentergridcells + \bgroup % we want to keep the reduction local + \OTRSETreducegridbox + \global\setbox\OTRfinalpagebox\OTRSETmakegridbox + \egroup % otherwise we get the wrong number of free cells + %\gdef\localcolumnmaxcells{0}% here ? + \global\mofcolumns\nofcolumns} % otherwise problems in finaloutput + +\def\OTRSETdofinaloutput + {\ifdim\ht\OTRfinalpagebox=\textheight + \bgroup % \let\OTRSETsetvsize\relax % prevents useless search for gap + \ifcase\OTRSETbalancemethod + \finaloutput\box\OTRfinalpagebox + \else\ifdim\OTRSETbalht>\zeropoint + % catch a bordercase + \scratchdimen\OTRSETbalht + \advance\scratchdimen\lineheight\relax + \ifdim\scratchdimen>\textheight + % full page + \finaloutput\box\OTRfinalpagebox + \else + % same page + \global\setbox\OTRfinalpagebox \iftracecolumnset\ruledvbox\else\vbox\fi to \OTRSETbalht + {\box\OTRfinalpagebox\vss}% + \setlayer[OTRTEXT]{\box\OTRfinalpagebox}% + \snaptogrid\vbox{\vskip\OTRSETbalht}% hack + \fi + \else + \finaloutput\box\OTRfinalpagebox + \fi \fi + \globallet\OTRSETbalht\zeropoint + \egroup + \fi} + +\definesystemvariable {mc} +\definesystemvariable {mt} +\definesystemconstant {colset} + +\definetwopasslist\s!colset + +\newdimen \OTRSETtextswidth +\newdimen \OTRSETtextsheight +\let \OTRSETidentifier=\empty + +\newtoks \OTRSEToutput + +\def\OTRSETgetparameter#1#2{\csname\??mc\OTRSETidentifier\number#2#1\endcsname} +\def\OTRSETsetparameter#1#2{\setvalue{\??mc\OTRSETidentifier\number#2#1}} + +\def\OTRSETskipstart + {\scratchcounter\executeifdefined{\??mc\OTRSETidentifier\c!start}\zerocount + \relax % needed ! + \ifcase\scratchcounter\else + \advance\scratchcounter\plusone + \doOTRSETsetgridcells + {\copy\placeholderboxe} + \plusone\plusone\nofcolumns\scratchcounter + \null + \fi} + +\def\OTRSETsetvsize % snap per sectie (gap here?) + {\ifcollectingcontent \else % can be assigndimen +\OTRSETskipstart % not that well tested + \OTRSETcheckinsert % added + \OTRSETsetfreecells\mofcolumns\columnfirstcell + \ifsomefreecolumncells + \global\vsize\columnfreecells\lineheight + \ifinotr % else problems with floats, see extreme + \global\pagegoal\vsize % niet nodig, tenzij binnen otr + \fi + \synchronizeoutput % fails on example + % \allowbreak % hm + \fi + \synchronizenotes + \fi} + +\def\OTRSETsethsize % of course this does not migrate outside the otr + {\localcolumnwidth\OTRSETlocalwidth\mofcolumns + \textwidth\localcolumnwidth + \hsize\localcolumnwidth} + +\def\OTRSETsynchronizehsize + {\ifcase0\getvalue{\??mc\??mc\c!width}\else % some width set + \bgroup + \scratchdimen\OTRSETlocalwidth\mofcolumns + \ifdim\scratchdimen=\textwidth + \egroup + \else + % only if change in width and \column/\break + \egroup \OTRSETsethsize + \fi + \fi} + +\def\OTRSETcheckfreelines + {\OTRSETsetvsize} + +\def\doOTRSETcolumnseparator + {\hbox to \zeropoint{\hss\red\vl\hss}} + +\let\OTRSETcolumnseparator\relax + +\def\showbreaks + {\let\OTRSETcolumnseparator\doOTRSETcolumnseparator} + +% \installcolumnbreakhandler {SET} \v!ja +% {% hmmm: +% \ifhmode +% \bgroup +% \removeunwantedspaces +% \parfillskip\zeropoint +% \OTRSETcolumnseparator +% \par +% \egroup +% \fi +% % brrr: +% \ejectinsert +% \ejectpage +% \OTRSETsynchronizehsize} % no \OTRSETsethsize, can be mid smaller (like tabulate) +% +% \installcolumnbreakhandler {SET} \v!forceer +% {\OTRSETgotocolumn[\v!forceer]} +% \installcolumnbreakhandler {SET} \v!eerste +% {\OTRSETgotocolumn[\v!eerste]} +% \installcolumnbreakhandler {SET} \v!laatste +% {\OTRSETgotocolumn[\v!laatste]} +% +% \installcolumnbreakhandler {SET} \v!pagina +% {\simplepagebreak % \flushnotes \executepagebreakhandler\v!ja +% \ifnum\mofcolumns>\plusone +% \OTRSETgotocolumn[\v!laatste,\v!forceer]% +% \fi} + +\def\OTRSETcolumnhbreak + {\ifhmode + \bgroup + \removeunwantedspaces + \parfillskip\zeropoint + \OTRSETcolumnseparator + \par + \egroup + \fi} + +\installcolumnbreakhandler {SET} \v!local + {\OTRSETcolumnhbreak + \ejectinsert + \ejectpage % brrr + % no \OTRSETsethsize, can be mid smaller (like tabulate) + % also, this one should be executed at the outer level + % (setting hsize inside otr does not work) + \OTRSETsynchronizehsize} + +% We need to make sure that we really leave the column; mid +% column we may end up in an empty gap, and we don't want to +% stay there (basically such a gap is a small empty page +% then). + +\installcolumnbreakhandler {SET} \v!yes + {\OTRSETcolumnhbreak + \edef\savedmofcolumns{\the\mofcolumns}% + \edef\savedrealpageno{\the\realpageno}% + \ejectinsert + \ejectpage % brrr + \doloop + {\ifnum\savedmofcolumns=\mofcolumns + \ifnum\savedrealpageno=\realpageno + \OTRSETdummycolumn + \else + \exitloop + \fi + \else + \exitloop + \fi}% + \OTRSETsynchronizehsize} + +\installcolumnbreakhandler {SET} \s!unknown + {\expanded{\OTRSETgotocolumn[\@@columnspecification]}} + +\installcolumnbreakhandler {SET} \v!page + {\vfill\eject % \doejectpage\eject + \OTRSETgotonextpage} + +\newtoks\OTRSETeverystartofcolumn + +\newbox\OTRSETsavedfootnotes + +% \installoutput\OTRSETflushtextsofar % spacing goes wrong + +%\def\OTRSETflushtextsofar +% {\ifvoid\normalpagebox \else +% \setbox\scratchbox\vbox{\unvbox\normalpagebox}% +% \OTRSETsavenotes +% \OTRSEThandleflushedtext0 +% \fi} + +% The complication is in the fact that when the HERE float +% is placed, the otr is not invoked when there is not yet +% enough content; this can lead to a change in order (turning +% on the tracer with option 0 is very instructive, watch the +% small numbers in the margin) +% +% 0 = no flushing, so no interference but user should handle +% border cases of placement +% 1 = the normal otr, rather untested +% 2 = a solution that works ok, is experimental and above +% all messy + +\chardef\OTRSETflushtextmode=0 + +\def\OTRSETflushtextsofar + {\ifcase\OTRSETflushtextmode + % don't mess around + \or + % the normal one + \ifvoid\normalpagebox\else + \OTRSETnaturalflush + \OTRSETcheckfreelines + \fi + \or + % way to complicated, but kind of ok + \doOTRSETflushtextsofar + \fi} + +\newskip\lastskipinotr + +\installoutput\doOTRSETflushtextsofar % experimental + {\ifvoid\normalpagebox\else + \scratchdimen\dp\normalpagebox + \setbox\scratchbox\vbox + {\forgetall + \unvbox\normalpagebox + \global\lastskipinotr\lastskip\relax + \ifdim\lastskipinotr>\zeropoint\relax + \removelastskip + \else + \kern-\scratchdimen % handle depth + \fi}% + \ifdim\lastskipinotr>\zeropoint + \scratchskip\ht\scratchbox + \setbox\scratchbox\hbox + {\lower\strutdepth\box\scratchbox}% + \dp\scratchbox\scratchdimen + \ht\scratchbox\scratchskip + \fi + \OTRSETsavenotes + \OTRSEThandleflushedtext\zerocount + \ifdim\lastskipinotr>\zeropoint + %\vskip \lastskipinotr % hm, gets lost anyway + \else + % we should not discard skips after here; tricky + \fi + \OTRSETsetvsize + \fi} + +\def\OTRSETplacebottomnotes + {\iflastcolumnfootnotes + \ifnum\nofcolumns=\mofcolumns + \ifintermediatefootnotes \placebottomnotes \fi + \fi + \else + \placebottomnotes + \fi} + +\def\OTRSETflushsavednotes + {\iflastcolumnfootnotes + \ifnum\nofcolumns=\mofcolumns + \flushsavednotes + \fi + \else + \flushsavednotes + \fi} + +\def\OTRSETsavenotes + {\iflastcolumnfootnotes + \ifnum\nofcolumns=\mofcolumns \else + \savenotes + \fi + \fi} + +\appendtoks \OTRSETflushsavednotes \to \OTRSETeverystartofcolumn + +\def\OTRSETnaturalflush + {\bgroup + \forgetall % new, needed ! + \setbox0\vbox to \columnfreecells\lineheight + {\vskip-\topskip + \vskip\lineheight + \prevdepth\strutdp + \unvbox\normalpagebox + \vfill}% + \setbox2\hbox + {\OTRSETplacebottomnotes}% + \setbox\scratchbox\hbox + {\wd0\zeropoint\box0\box2}% + \dp\scratchbox\strutdp + \OTRSEThandleflushedtext\plusone + \egroup} + +\newcount\lastcolumnlastcell + +\def\OTRSEThandleflushedtext#1% + {\getnoflines{\ht\scratchbox}% + %\wd\scratchbox\textwidth % geen \hsize kan < zijn in bv split tabulate + \wd\scratchbox\OTRSETlocalwidth\mofcolumns + \doOTRSETsetgridcells + {\copy\placeholderboxf} + \mofcolumns\columnfirstcell\plusone\noflines + {\registeredtextarea1\columnfirstcell\scratchbox}% == \hbox / tricky htcorr == \columnfirstcell + \global\columnlastcell\columnfirstcell + \global\advance\columnlastcell \noflines + \global\lastcolumnlastcell\columnlastcell + \global\advance\lastcolumnlastcell \minusone + % find next (acceptable) gap, todo: deadcycle + \ifcase#1\else + \OTRSETfillgapsbetweencells\mofcolumns\columnlastcell + \fi + \OTRSETfindnextgap + % \message{\the\mofcolumns,\the\columnfirstcell,\the\columnfreecells}% + % \wait + % we cannot adapt the hsize since it may have changed (like + % inside a tabulate) so we only change it when there is a + % reason to do so + \OTRSETsynchronizehsize + \OTRSETsetvsize} + +\def\OTRSETfindnextgap + {\OTRSETsetfreecells\mofcolumns\columnlastcell + \ifsomefreecolumncells + % okay + \bubbleOTRSETmarks % not robust because we reenter + \else + \registerOTRSETmarks % not robust because we reenter + \global\advance\mofcolumns \plusone + \ifnum\mofcolumns>\nofcolumns + \OTRSETdoflush + \global\columnlastcell\plusone + \global\columnfirstcell\zerocount + \OTRSETdoflushfloats + \else + \the\OTRSETeverystartofcolumn + \global\columnlastcell\plusone + \global\columnfirstcell\zerocount + \fi + \fi} + +\let\OTRSETcheckfreelines\donothing + +\def\OTRSETfillgapsbetweencells#1#2% col + {\ifnum\columngaplimit>\zerocount + \donefalse + \dostepwiserecurse{#2}\columnmaxcells\plusone + {\OTRSETdoifcellelse{#1}\recurselevel + {\ifdone + \!!countb\recurselevel \advance\!!countb -\!!counta\relax + \ifnum\!!countb>\plusone + \advance\!!countb \minusone + \ifnum\!!countb<\columngaplimit\relax + \!!countb\recurselevel \advance\!!countb \minusone + \dostepwiserecurse\!!counta\!!countb\plusone + {\OTRSETsetgridcell{#1}\recurselevel\copy\placeholderboxc}% + %\message{[gap]}% + \fi + \fi + \fi + \donefalse} + {\ifdone \else + \donetrue + \!!counta\recurselevel + \fi}}% + \fi} + +\appendtoks + \OTRSETfillgapsbetweencells\mofcolumns\plusone +\to \OTRSETeverystartofcolumn + +%\def\OTRSETfreezeminimumgap#1% +% {\OTRSETgetmaxfreecells{#1}{1}% +% \ifnum\columnmaxfreecells>0 +% \!!countb=\columnfrmfreecells +% \!!counta=\!!counta \advance\!!counta -\columnmaxfreecells +% \dorecurse{\columnmaxcells} +% {\ifnum\recurselevel<\!!counta\relax +% \donetrue +% \else\ifnum\recurselevel>\!!countb +% \donetrue +% \else +% \donefalse +% \fi\fi +% \ifdone +% \OTRSETdoifcellelse{#1}{\recurselevel} +% {}{\OTRSETsetgridcell{#1}\recurselevel\copy\placeholderboxc}% +% \fi}% +% \fi} +% +%\def\OTRSETfillgaps#1#2#3% col from to +% {\dostepwiserecurse{#2}{#3}{1} +% {\OTRSETdoifcellelse{#1}{\recurselevel} +% {}{\OTRSETsetgridcell{#1}\recurselevel\copy\placeholderboxc}}} +% +%\def\OTRSETfillbotgaps#1#2% col first +% {\OTRSETfillgaps{#1}{#2}{\columnmaxcells}} +% +%\def\OTRSETfilltopgaps#1#2% col last +% {\OTRSETfillgaps{#1}{1}{#2}} + +\newif\ifspancolumnslots \spancolumnslotstrue +\newif\ifcheckcolumnspan \checkcolumnspantrue + +\def\OTRSETcheckwidthgap#1#2% box size + {\ifcheckcolumnspan + \bgroup + \scratchdimen#2% + \advance\scratchdimen-\wd#1\relax + \ifdim-10\scaledpoint>\scratchdimen + \egroup + \else\ifdim10\scaledpoint<\scratchdimen + \egroup + \else + \egroup + \wd#1=#2% + \fi\fi + \fi} + +\def\OTRSETcheckcolumnslot#1% + {\enoughcolumncellstrue + \ifspancolumnslots\else + \OTRSETcheckwidthgap#1\hsize + \ifdim\wd#1>\hsize + \enoughcolumncellsfalse + \fi + \fi + \ifenoughcolumncells + \getnoflines\pagetotal + \scratchcounter\noflines + \getnoflines{\ht#1}% + \columnvcells\noflines + \columnhcells\plusone + \advance\scratchcounter \columnvcells \relax + \ifnum\scratchcounter>\columnfreecells + \enoughcolumncellsfalse + \fi + \fi} + +\def\OTRSETstoreincolumnslotPAGE#1% + {\ifenoughcolumncells + % to do + \OTRSETsavebox{#1}% + \else + \OTRSETsavebox{#1}% + \fi} + +\def\OTRSETstoreincolumnslotTOPS#1% + {\OTRSETprepareforcolumnslot1{#1}% + \OTRSETcheckcolumnslot{#1}% + \ifenoughcolumncells + \OTRSETcheckcolumnspace\mofcolumns\columnfirstcell{#1}% + \fi + \ifenoughcolumncells + \OTRSETsetgridcells\mofcolumns\columnfirstcell\columnhcells\columnvcells + {\hbox{\copy#1}}% + \OTRSETsetvsize + \else + \OTRSETsavebox{#1}% + \fi} + +\def\OTRSETstoreincolumnslotBOTS#1% + {\OTRSETprepareforcolumnslot3{#1}% + \edef\savedcolumnlastcell{\the\columnlastcell}% + \OTRSETcheckcolumnslot{#1}% + \ifenoughcolumncells + \advance\columnlastcell -\columnvcells \advance\columnlastcell \plusone +% \OTRSETcheckcolumnspace\mofcolumns\columnfirstcell{#1}% + \OTRSETcheckcolumnspace\mofcolumns\columnlastcell{#1}% + \fi + \ifenoughcolumncells + \OTRSETsetgridcells\mofcolumns\columnlastcell\columnhcells\columnvcells{\copy#1}% + \OTRSETfillgapsbetweencells\mofcolumns\savedcolumnlastcell % -) + \OTRSETsetvsize + \else + \columnlastcell\savedcolumnlastcell + \OTRSETsavebox{#1}% + \fi} + +\newdimen\totalcolumnspace + +\def\columnspacetopoffset{0} +\def\columnspacebotoffset{0} + +\def\OTRSETcheckcolumnspace#1#2#3% col row box + {\columnhcells\plusone + \totalcolumnspace\zeropoint + \scratchcounter#1% + \enoughcolumncellstrue + \doloop + {\advance\totalcolumnspace \OTRSETlocalwidth\scratchcounter\relax % needed +\OTRSETcheckwidthgap#3\totalcolumnspace + \ifnum\wd#3>\totalcolumnspace\relax + \ifnum\scratchcounter=\nofcolumns + \enoughcolumncellsfalse + \exitloop + \else + \advance\columnhcells \plusone + \advance\scratchcounter \plusone + \advance\totalcolumnspace \OTRSETgetparameter\c!distance\scratchcounter + \fi + \else + \exitloop + \fi}% + \ifenoughcolumncells + \getnoflines{\ht#3}% + \columnvcells\noflines + \OTRSETcheckcolumncells{#1}{#2}\columnhcells\columnvcells + \fi} + +\def\OTRSETcheckcolumncells#1#2#3#4% col row wid hei + {\!!countd#1\advance\!!countd#3\advance\!!countd\minusone + \!!counte#2\advance\!!counte#4\advance\!!counte\minusone + \ifnum\!!counte>\columnmaxcells\relax + \enoughcolumncellsfalse + \else + \enoughcolumncellstrue +%\let\columnspacetopoffset\zerocount +%\scratchcounter#2\advance\scratchcounter\minusone +%\ifnum\scratchcounter>0 +% \dostepwiserecurse{#1}\!!countd\plusone +% {\ifdim\wd\OTRSETgridcell\recurselevel\scratchcounter>\zeropoint +% \let\columnspacetopoffset\plusone +% \else\ifdim\dp\OTRSETgridcell\recurselevel\scratchcounter>\zeropoint +% \let\columnspacetopoffset\plusone +% \fi\fi}% +% \advance\!!counte \columnspacetopoffset \relax +% \advance\columnvcells \columnspacetopoffset \relax +%\fi +%\let\columnspacebotoffset\zerocount +%\scratchcounter\!!counte +%\advance\scratchcounter \columnvcells \relax +%\ifnum\scratchcounter>\columnmaxcells\else +% \dostepwiserecurse{#1}\!!countd\plusone +% {\ifdim\wd\OTRSETgridcell\recurselevel\scratchcounter>\zeropoint +% \let\columnspacebotoffset\plusone +% \else\ifdim\dp\OTRSETgridcell\recurselevel\scratchcounter>\zeropoint +% \let\columnspacebotoffset\plusone +% \fi\fi}% +% \advance\!!counte \columnspacebotoffset \relax +% \advance\columnvcells \columnspacebotoffset \relax +%\fi + \dostepwiserecurse{#1}\!!countd\plusone % cols + {\ifenoughcolumncells + \!!countf\recurselevel\relax + \dostepwiserecurse{#2}\!!counte\plusone % rows + {\ifenoughcolumncells + \OTRSETdoifcellelse\!!countf\recurselevel + {\enoughcolumncellsfalse}{}% + \fi}% + \fi}% + \fi} + +\def\OTRSETsetpreferedcolumnslot#1#2% + {\doifsomething{#1}{\edef\preferedcolumn{#1}}% + \doifsomething{#2}{\edef\preferedrow {#2}}} + +\OTRSETsetpreferedcolumnslot{\nofcolumns}{1} % default ? + +\let\pofcolumns\mofcolumns +\let\qofcolumns\mofcolumns + +\newif\ifquitincurrentcolumn + +\def\OTRSETstoreincolumnslotLRTB#1% + {\OTRSETprepareforcolumnslot1{#1}% + \OTRSETflushtextsofar + \OTRSETstoreincolumnslotindeed + \mofcolumns\nofcolumns+\currenthcell + \plusone\columnmaxcells+\currentvcell{#1}} + +\def\OTRSETstoreincolumnslotLRBT#1% + {\OTRSETprepareforcolumnslot3{#1}% + \OTRSETflushtextsofar + \OTRSETstoreincolumnslotindeed + \mofcolumns\nofcolumns+\currenthcell + \columnmaxcells\plusone-\currentvcell{#1}} + +\def\OTRSETstoreincolumnslotRLTB#1% + {\OTRSETprepareforcolumnslot1{#1}% + \OTRSETflushtextsofar + \OTRSETcheckprefered + \OTRSETstoreincolumnslotindeed + \nofcolumns\qofcolumns-\currenthcell + \plusone\columnmaxcells+\currentvcell{#1}} + +\def\OTRSETstoreincolumnslotRLBT#1% + {\OTRSETprepareforcolumnslot3{#1}% + \OTRSETflushtextsofar + \OTRSETcheckprefered + \OTRSETstoreincolumnslotindeed + \nofcolumns\qofcolumns-\currenthcell + \columnmaxcells\plusone-\currentvcell{#1}} + +\def\OTRSETstoreincolumnslotTBLR#1% + {\OTRSETprepareforcolumnslot1{#1}% + \OTRSETflushtextsofar + \OTRSETstoreincolumnslotindeed + \plusone\columnmaxcells+\currentvcell + \mofcolumns\nofcolumns+\currenthcell{#1}} + +\def\OTRSETstoreincolumnslotTBRL#1% + {\OTRSETprepareforcolumnslot1{#1}% + \OTRSETflushtextsofar + \OTRSETcheckprefered + \OTRSETstoreincolumnslotindeed + \plusone\columnmaxcells+\currentvcell + \nofcolumns\qofcolumns-\currenthcell{#1}} + +\def\OTRSETstoreincolumnslotBTLR#1% + {\OTRSETprepareforcolumnslot3{#1}% + \OTRSETflushtextsofar + \OTRSETstoreincolumnslotindeed + \columnmaxcells\plusone-\currentvcell + \mofcolumns\nofcolumns+\currenthcell{#1}} + +\def\OTRSETstoreincolumnslotBTRL#1% + {\OTRSETprepareforcolumnslot3{#1}% + \OTRSETflushtextsofar + \OTRSETcheckprefered + \OTRSETstoreincolumnslotindeed + \columnmaxcells\plusone-\currentvcell + \nofcolumns\qofcolumns-\currenthcell{#1}} + +\def\OTRSETstoreincolumnslotFXTB#1% fixed column + {\OTRSETcheckprefered + \OTRSETdoifcellelse\pofcolumns\plusone + {\OTRSETprepareforcolumnslot2}{\OTRSETprepareforcolumnslot1}{#1}% % 1/2 dependent of place, todo + \OTRSETflushtextsofar + \OTRSETstoreincolumnslotindeed + \pofcolumns \pofcolumns +\currenthcell + \preferedrow\columnmaxcells+\currentvcell{#1}} + +\def\OTRSETstoreincolumnslotFXBT#1% fixed column + {\OTRSETcheckprefered + \OTRSETdoifcellelse\pofcolumns\columnmaxcells + {\OTRSETprepareforcolumnslot2}{\OTRSETprepareforcolumnslot3}{#1}% % 3/2 dependent of place, todo + \OTRSETflushtextsofar + \OTRSETstoreincolumnslotindeed + \pofcolumns \pofcolumns +\currenthcell + \columnmaxcells\preferedrow-\currentvcell{#1}} + +% \def\OTRSETstoreincolumnslotHERE#1% fixed column +% {\OTRSETprepareforcolumnslot2{#1}% +% \OTRSETflushtextsofar +% \getnoflines\pagetotal \advance\noflines\columnfirstcell +% \OTRSETstoreincolumnslotindeed +% \mofcolumns\mofcolumns+\currenthcell +% \noflines\columnmaxcells+\currentvcell{#1}% +% \OTRSETsetvsize} + +\chardef\OTRSETforcefixedfloats=0 + +\def\OTRSETstoreincolumnslotHERE#1% fixed column + {\ifcase\OTRSETforcefixedfloats + \OTRSETstoreincolumnslotSOMEWHERE2{#1}% + \else + \OTRSETstoreincolumnslotFIXD{#1}% + \fi} + +% this one looses too wide graphics +% +% \def\OTRSETstoreincolumnslotFIXD#1% fixed column +% {\OTRSETprepareforcolumnslot2{#1}% +% % no flush text sofar here, beware: no width test +% \snaptogrid\vbox{\box#1}} +% +% still imperfect + +\def\OTRSETstoreincolumnslotFIXD#1% fixed column + {\OTRSETflushtextsofar + \ifdim\wd#1>\textwidth + \OTRSETstoreincolumnslotSOMEWHERE2{#1}% + \else + % crappy test / needed for o-pbu-f / will be replaced + \getnoflines{\ht#1}% + \scratchdimen\noflines\lineheight + \advance\scratchdimen\lineheight + \advance\scratchdimen\pagetotal\relax + \ifdim\scratchdimen<\pagegoal + %OTRSETprepareforcolumnslot3{#1}% + %ruledvskip\columnslotspacing\lineheight + \blank[\columnslotspacing*\v!line]% + \snaptogrid\hbox to \hsize{\hss\box#1\hss}% strange, why the centering + \blank[\columnslotspacing*\v!line]% + \else + \OTRSETstoreincolumnslotSOMEWHERE2{#1}% + \fi + \fi} + +\def\OTRSETstoreincolumnslotSOMEWHERE#1#2% + {\OTRSETprepareforcolumnslot{#1}{#2}% + \OTRSETflushtextsofar + \getnoflines\pagetotal \advance\noflines\columnfirstcell + \OTRSETstoreincolumnslotindeed + \mofcolumns\mofcolumns+\currenthcell + \noflines\columnmaxcells+\currentvcell{#2}% + \OTRSETsetvsize} + +\def\OTRSETcheckprefered + {\ifnum\preferedcolumn<\mofcolumns + \let\pofcolumns\mofcolumns + \else + \let\pofcolumns\preferedcolumn + \fi + \ifquitincurrentcolumn + \ifnum\mofcolumns=\nofcolumns + \def\qofcolumns{\mofcolumns}% + \else + \scratchcounter\mofcolumns + \advance\scratchcounter \plusone + \edef\qofcolumns{\the\scratchcounter}% + \fi + \else + \let\qofcolumns\mofcolumns + \fi} + +\def\OTRSETstoreincolumnslotindeed#1#2#3#4#5#6#7#8#9% + {\OTRSETcheckprefered + \enoughcolumncellsfalse + \donefalse + \dostepwiserecurse{#1}{#2}{#31} + {\ifdone + \exitloop + \else + #4=\recurselevel + \dostepwiserecurse{#5}{#6}{#71} + {\ifdone + \exitloop + \else + #8=\recurselevel + \OTRSETcheckcolumnspace\currenthcell\currentvcell{#9}% + \ifenoughcolumncells \donetrue \fi + \fi}% + \fi}% + \ifdone + \enoughcolumncellstrue + \else + \enoughcolumncellsfalse + \fi + \ifenoughcolumncells +% \ifnum\columnspacetopoffset>0\message{[+++]}\fi +% \ifnum\columnspacebotoffset>0\message{[---]}\fi +% \OTRSETsetgridcells\currenthcell\currentvcell\columnhcells\columnvcells +% {\vbox +% {\ifcase\columnspacetopoffset\else\ruledvskip\columnspacetopoffset\lineheight\fi +% \copy#9 +% \ifcase\columnspacebotoffset\else\ruledvskip\columnspacebotoffset\lineheight\fi}}% + \OTRSETsetgridcells\currenthcell\currentvcell\columnhcells\columnvcells + {\copy#9}% + \ifnum\currenthcell=\mofcolumns\relax + \ifdim\ht\OTRSETsavedfootnotes>\zeropoint + \OTRSETsetfreecells\mofcolumns\columnfirstcell + \ifsomefreecolumncells + \getnoflines{\ht\OTRSETsavedfootnotes}\relax + \ifnum\columnfreecells<\noflines + \global\somefreecolumncellsfalse + \else + %\message{[flt]}% float + \fi + \fi + \ifsomefreecolumncells + % ok, enough room for notes + %\message{[flt]}% float + \else % ? + \OTRSETsavebox{#9}% + \OTRSETerasegridcells\currenthcell\currentvcell\columnhcells\columnvcells + %\message{[clr]}% save box + \fi + \else + %\message{[flt]}% float + \fi + \else + %\message{[flt]}% float + \fi + \OTRSETsetvsize + %\message{[fnt]}% float + \else + %\message{[rej]}% save box + \OTRSETsavebox{#9}% + \fi} + +\chardef\columnslotspacing \plusone + +\def\OTRSETstoreincolumnslot#1% #2 % {method} {box} % alleen last + {% no messing around here + % \dp#2=\zeropoint + % \ifcase\columnslotspacing\else + % \setbox#2=\vbox spread \columnslotspacing\lineheight + % {\vss\box#2\vss}% + % \fi + % and don't change this any more +% \doifdefinedelse{\strippedcsname\OTRSETstoreincolumnslot#1} +% {\getvalue{\strippedcsname\OTRSETstoreincolumnslot#1}{#2}} +% {\OTRSETstoreincolumnslotUNKNOWN{#2}}} + \executeifdefined{\strippedcsname\OTRSETstoreincolumnslot#1} + \OTRSETstoreincolumnslotUNKNOWN} % {#2}} + +\def\OTRSETstoreincolumnslotUNKNOWN#1% + {\OTRSETprepareforcolumnslot2{#1}\copy#1} % {} ? + +% \def\OTRSETprepareforcolumnslot#1#2% 1=hoog 2=midden 3=laag +% {\dp#2\zeropoint +% \ifcase\columnslotspacing\else +% \scratchdimen\columnslotspacing\lineheight +% \ifnum#1=2 \scratchdimen2\scratchdimen \fi +% \setbox#2\vbox spread \scratchdimen +% {\ifnum#1>1\vss\fi\box#2\relax\ifnum#1<3\vss\fi}% +% \fi} + +\def\OTRSETprepareforcolumnslot#1#2% 1=hoog 2=midden 3=laag + {\dp#2\zeropoint + \ifcase\columnslotspacing\else + \scratchdimen\columnslotspacing\lineheight + \ifnum#1=2 \scratchdimen2\scratchdimen \fi + \begingroup + \advance\scratchdimen\ht#2\relax + \ifdim\scratchdimen<\columnmaxcells\lineheight + \endgroup \setbox#2\vbox spread \scratchdimen \bgroup + \else + \endgroup \setbox#2\vbox to \columnmaxcells\lineheight \bgroup + \vskip\strutdepth + \fi + \ifnum#1>1\vss\fi + \box#2\relax + \ifnum#1<3\vss\fi + \egroup + \fi} + +\def\OTRSETdocheckiffloatfits % eigenlijk moet else float anders + {\global\ifnofloatpermitted\roomforfloatfalse\else\roomforfloattrue\fi} + +\def\OTRSETunpreparebox#1% + {\ifhbox#1% spans and so + \global\setbox\floatbox\vbox{\box#1}% + \else + \setbox\scratchbox\vbox + {\unvbox#1\unskip\unskip\unskip + \global\setbox\floatbox\lastbox}% + \fi} + +\def\OTRSETsavebox#1% clean up the skips + {\OTRSETunpreparebox{#1}% + \dosavefloat} + +\def\OTRSETresavebox#1% clean up the skips + {\OTRSETunpreparebox{#1}% + \doresavefloat} + +\def\OTRSETflushfloatbox % nog verder doorvoeren en meer info in marge + {\iftestfloatbox\ruledhbox\fi{\box\floatbox}} + +\def\OTRSETdoflushfloats + {\bgroup + \def\OTRSETsavebox##1{\!!doneafalse}% + \doloop + {\ifsomefloatwaiting +\OTRSETskipstart + \dogetfloat + \ifdim\wd\floatbox>\zeropoint + \!!doneatrue + \dp\floatbox\zeropoint + \OTRSETstoreincolumnslot{TBLR}\floatbox + \if!!donea + %\message{[flu]}% + \else + \OTRSETresavebox\floatbox + \exitloop + \fi + \else + %\message{[err]}% happens but why? + \fi + \else + \exitloop + \fi} + \egroup} + +\newif\ifcentergridcells \centergridcellstrue + +\newif\ifcentergridcellonly \centergridcellonlyfalse +\newif\ifautocentergridcellonly \autocentergridcellonlytrue + +\def\OTRSETcentergridcells + {\ifcentergridcells + \dorecurse\nofcolumns + {\currenthcell\recurselevel + \ifautocentergridcellonly + % we prevent centering when the next column is empty + % to be checked ! ! ! ! + \advance\currenthcell \plusone + \centergridcellonlytrue + \ifnum\currenthcell>\nofcolumns + % ok already + \else + % only span if there is a next column with content + \dorecurse\columnmaxcells + {\ifdim\ht\OTRSETgridcell\currenthcell\currentvcell>\zeropoint + \centergridcellonlyfalse + \else\ifdim\dp\OTRSETgridcell\currenthcell\currentvcell>\zeropoint + \centergridcellonlyfalse + \fi\fi}% + \fi + \fi + \currenthcell\recurselevel + \dorecurse\columnmaxcells + {\currentvcell\recurselevel\relax + \ifdim\ht\OTRSETgridcell\currenthcell\currentvcell>\zeropoint + \ifdim\dp\OTRSETgridcell\currenthcell\currentvcell=\zeropoint + \bgroup + \setbox\scratchbox\OTRSETgetgridcell\currenthcell\currentvcell + \getnoflines{\ht\scratchbox}% + \!!counta\currentvcell + \advance\!!counta -\noflines + \advance\!!counta \plusone + % first col always ok + \!!countb\currenthcell + \!!countc\currenthcell + \advance\!!countc \plusone + \!!donebtrue + \ifcentergridcellonly + \!!countc\maxdimen + \fi + \dostepwiserecurse\!!countc\nofcolumns\plusone + {\if!!doneb + \let\xrecurselevel\recurselevel + \dostepwiserecurse\!!counta\currentvcell\plusone + {\ifdim\ht\OTRSETgridcell\xrecurselevel\recurselevel>\zeropoint + \!!donebfalse + \else\ifdim\wd\OTRSETgridcell\xrecurselevel\recurselevel>\zeropoint + \!!donebfalse + \fi\fi}% + \if!!doneb + \!!countb\xrecurselevel + \fi + \fi}% + \totalcolumnspace\OTRSETlocalwidth\currenthcell + \dostepwiserecurse\!!countc\!!countb\plusone + {\advance\totalcolumnspace \OTRSETlocalwidth\recurselevel + \advance\totalcolumnspace \OTRSETgetparameter\c!distance\recurselevel}% + \ifdim\totalcolumnspace>\wd\scratchbox + \setbox\scratchbox\hbox to \totalcolumnspace{\hss\box\scratchbox\hss}% + \fi + \OTRSETsetgridcell\currenthcell\currentvcell\box\scratchbox + \egroup + \fi + \fi}}% + \fi} + +\def\OTRSETinitializecolumns% once per page + {\columnspreadtrue % todo + \ifcolumnspread + \global\rofcolumns\getvalue{\??mc\OTRSETidentifier\c!nright}% + \global\lofcolumns\getvalue{\??mc\OTRSETidentifier\c!nleft}% + \global\tofcolumns\rofcolumns \relax + \ifodd\realpageno\relax + \global\nofcolumns\rofcolumns + \else + \global\advance\tofcolumns\lofcolumns + \global\nofcolumns\lofcolumns + \fi + \else + \global\nofcolumns\getvalue{\??mc\OTRSETidentifier\c!n}% + \global\rofcolumns\nofcolumns + \global\lofcolumns\nofcolumns + \global\tofcolumns\nofcolumns + \fi + \OTRSETassignwidths + \global\mofcolumns\plusone + \columnerasegridboxes} + +% vanaf hier: + +\def\definecolumnset + {\dodoubleargument\dodefinecolumnset} + +\def\dodefinecolumnset[#1][#2]% + {\getparameters[\??mc#1] + [\c!direction=\v!right, + \c!balance=\v!no, + \c!distance=1.5\bodyfontsize, % controleren + \c!n=2, + \c!nleft=\getvalue{\??mc#1\c!n}, + \c!nright=\getvalue{\??mc#1\c!n}, + \c!width=\v!fit, + \c!lines=0, + \c!start=0, + #2]% + \dorecurse{\getvalue{\??mc#1\c!nleft}} % todo + {\dododefinecolumnset[#1][\recurselevel]}% + \dorecurse{\getvalue{\??mc#1\c!nright}} % todo + {\dododefinecolumnset[#1][\recurselevel]}% + % redo framed settings + \setupcolumnset[#1][1][\c!distance=\!!zeropoint]} + +\def\dododefinecolumnset[#1][#2]% + {\presetlocalframed + [\??mc#1#2]% + \setupcolumnset + [#1][#2] + [\c!offset=\v!overlay, + \c!frame=\v!off, + \c!align=, + \c!lines=0,% really needed since c!regels is now part of framed + \c!width=\getvalue{\??mc#1\c!width}, + \c!distance=\getvalue{\??mc#1\c!distance}]} + +\def\setupcolumnset + {\dotripleargument\dosetupcolumnset} + +\def\dosetupcolumnset[#1][#2][#3]% + {\ifthirdargument + \def\docommand##1% + {\doifelse{##1}\v!each + {\dorecurse{\getvalue{\??mc#1\c!n}}{\docommand\recurselevel}} + {\getparameters[\??mc#1##1][#3]}}% + \processcommalist[#2]\docommand + \else + \getparameters[\??mc#1][#2]% + \fi} + +\definecolumnset[\s!default][\c!n=2] % fallback + +\def\OTRSETgotonextpage + {\vfill\eject + \relax\ifnum\mofcolumns>\plusone + \OTRSETgotocolumn[\v!last]% + \ifnum\mofcolumns>\plusone + \OTRSETgotocolumn[\v!force]% + \fi + \fi} + +\let\OTRSETgotonextpageX\OTRSETgotonextpage % will become obsolete + +\def\OTRSETgotocolumn + {\dosingleempty\doOTRSETgotocolumn} + +\def\doOTRSETgotoCOLROW#1% |* + {\bgroup % really needed + \splitstring#1\at*\to\column\and\row + \bgroup + \ifx\column\empty\else\expanded{\doOTRSETgotoCOLUMN{\column}}\fi + \egroup + \bgroup + \ifx\row \empty\else\expanded{\doOTRSETgotoROW {\row }}\fi + \egroup + \egroup} + +\def\doOTRSETgotoCOLUMN#1% + {\ifnum\mofcolumns=#1\else + \vfill\eject % \doejectpage\eject + \doloop + {\ifnum\mofcolumns=#1\relax + \exitloop \else \OTRSETdummycolumn + \fi}% + \fi} + +\def\doOTRSETgotoROW#1% + {\ifnum#1>1 + \scratchcounter\zerocount + \currenthcell\mofcolumns + \currentvcell#1\advance\currentvcell \minusone + \dorecurse\currentvcell + {\OTRSETdoifcellelse\mofcolumns\recurselevel\donothing + {\advance\scratchcounter\plusone}} + \getnoflines\pagetotal + \advance\scratchcounter-\noflines + \ifnum\scratchcounter>\zerocount + \dorecurse\scratchcounter{\line{\strut}}% + \fi + \fi + \OTRSETsetvsize} + +\def\doOTRSETgotocolumn[#1]% yes|force|first|last||* + {\processallactionsinset + [#1] + [ \v!yes=>\OTRSETdummycolumn, + \v!no=>,% not supported + \v!force=>\OTRSETdummycolumn, + \v!first=>\expanded{\doOTRSETgotoCOLUMN{1}}, + \v!last=>\expanded{\doOTRSETgotoCOLUMN{\the\nofcolumns}}, + \s!default=>\OTRSETdummycolumn, + \s!unknown=>\expanded{\doOTRSETgotoCOLROW{\commalistelement}}]} + +% to be documented and tested, not yet that robust + +% \def\OTRSETgotocell#1#2% +% {\endgraf +% \gdef\gotocellcounter{0}% +% \doloop +% {\ifnum\mofcolumns<#1\relax +% \doglobal\increment\gotocellcounter\relax +% \ifnum\gotocellcounter>#1\relax +% \line{\strut}\crlf +% \line{\strut}\crlf +% \column +% \writestatus{columnset}{quitting goto cell}% +% \exitloop +% \else +% \column +% \fi +% \else +% \exitloop +% \fi}% +% \ifnum\mofcolumns=#1\relax +% \ifnum#2>1 +% \scratchcounter\zerocount +% \currenthcell\mofcolumns +% \currentvcell#2\advance\currentvcell \minusone +% \dorecurse\currentvcell +% {\OTRSETdoifcellelse\mofcolumns\recurselevel\donothing +% {\advance\scratchcounter\plusone}} +% \getnoflines\pagetotal +% \advance\scratchcounter-\noflines +% \ifnum\scratchcounter>\zerocount +% \dorecurse\scratchcounter{\line{\strut}}% +% \fi +% \fi +% \fi +% \OTRSETsetvsize} + +\def\OTRSETgotocell#1#2% obsolete: now \column[#1*#2] + {\endgraf + \doOTRSETgotoCOLUMN{#1}% + \doOTRSETgotoROW {#2}} + +\def\OTRSETdummycolumn + {\verticalstrut + \vskip-\struttotal + \vfill + \eject} + +\newcounter\columnsetlevel +\let\currentcolumnset\empty +\chardef\OTRSETfinish\zerocount + +\def\startcolumnset + {\dodoubleempty\dostartcolumnset} + +\def\dostartcolumnset[#1][#2]% + {\increment\columnsetlevel\relax + \globallet\localcolumnmaxcells\!!zerocount + \global\chardef\OTRSETfinish\zerocount + \resetOTRSETmarks + \ifnum\columnsetlevel=\plusone + \bgroup + \saveinterlinespace + \globallet\columnsetpage\!!plusone + \def\currentcolumnset{#2}% + \insidecolumnstrue % will be different flag in addition + \activateotr{SET}{ONE}% andere naam, activate or so + \doifelsenothing{#1} + {\globallet\OTRSETlist\s!default} + {\xdef\OTRSETlist{#1}}% + \OTRSETstartnextpage + \OTRSETassignwidths + \OTRSETsethsize + \else + \bgroup + \fi} + +% \setuplayout[grid=yes] \definecolumnset[example] \showgrid + +% \starttext +% \startcolumnset[example] +% \input knuth \endgraf \input knuth +% \placetable{table}{\framed[width=\makeupwidth,height=4cm]{Hello}} +% \input knuth \endgraf \input knuth +% \stopcolumnset +% \input knuth \endgraf \input knuth +% \stoptext + + +\def\OTRSETflushleftovers % new per 13/4/2006 + {\OTRSETdoifcellelse{1}{1} + {\bgroup + \OTRSETcentergridcells + \chardef\OTRSETbalancemethod\plusone + \OTRSETreducegridbox + \global\setbox\OTRfinalpagebox\OTRSETmakegridbox + \global\ht\OTRfinalpagebox\textheight % signals output that there is content + \OTRSETdofinaloutput + \globallet\OTRSETbalht\zeropoint + \egroup} + {}} + +\def\stopcolumnset + {\relax + \ifnum\columnsetlevel=\plusone + \endgraf % needed, else wrong vsize in one par case + \global\chardef\OTRSETfinish\plusone + % no, extra page \pagebreak % (test on pascal toc) + \dostopcolumnset + \egroup + \global\notelimittrue % brrr, untested and fuzzy + \setvsize + \sethsize + \ifvoid\OTRfinalpagebox\else + % probably balanced + \ifdim\ht\OTRfinalpagebox<\textheight + \snaptogrid[\v!page]\hbox{\box\OTRfinalpagebox}% + \else + \box\OTRfinalpagebox + \fi + \fi + \global\chardef\OTRSETfinish\zerocount + \ifsomefloatwaiting \setvsize \pagebreak \setvsize \fi + \OTRSETflushleftovers + \else + \egroup + \fi + \decrement\columnsetlevel\relax} + +\chardef\OTRSETbalancemethod\zerocount + +\def\dostopcolumnset + {%\OTRSETdofinalflushfloats % yes/no + \ifcase\OTRSETbalancemethod + \OTRSETnobalance + \else + \OTRSETdobalance + \fi} + +\def\OTRSETdobalance + {\OTRSETnobalance} + +\def\localcolumnmaxcells{0} + +% don't loose empty 1page/1column with area (example **) +% +% \definecolumntextarea[title][x=1,y=4,nx=2,ny=7,state=start] +% \setupcolumntextareatext[title][\vtop to 5cm{a\\b\\b\\d}] +% +% \starttext +% \startcolumnset \dorecurse{1}{\input tufte \par} \stopcolumnset +% \stoptext + +% better: + +\def\definecolumnsetarea {\definecolumntextarea} +\def\setupcolumnsetarea {\setupcolumntextarea} +\def\setupcolumnsetareatext{\setupcolumntextareatext} + +\def\OTRSETnobalance + {\iflastcolumnfootnotes % testen ! optie + % inhibit flush of floats ! + % todo: nothing if no footnotes, else empty page + \dostepwiserecurse\mofcolumns\nofcolumns\plusone + {\vskip-\struttotal\verticalstrut\vfill\eject}% + \else + \ifnum\mofcolumns>\plusone + \donetrue + \else\ifdim\pagetotal>\zeropoint % too dangerous, we loose data + \donetrue + \else + \donefalse + \fi\fi + \ifdone + \ifnum\mofcolumns=\nofcolumns + \OTRSETflushfinalfootnotes + \else + % probably todo + \fi + \vfill + \eject +\registerOTRSETmarks + % brr, may result in empty page after nicely fit text + % or if left, then lost of first column only text + \ifnum\mofcolumns>\plusone + \OTRSETdofinalflush + \OTRSETdofinaloutput + \fi + \fi + \fi} + +\def\OTRSETstartnextpage + {\doifsomething\OTRSETlist + {\getfromcommacommand[\OTRSETlist][1]% + \global\let\OTRSETidentifier\commalistelement + \doifundefined{\??mc\OTRSETidentifier\c!n} + {\globallet\OTRSETidentifier\s!default}% + \let\newcommalistelement\empty + \doglobal\replaceincommalist\OTRSETlist1% + \OTRSETrestart}} + +\def\OTRSETrestart % weed + {\OTRSETinitializefeatures + \OTRSETflushpreposttext + \OTRSETinitializecolumns + \OTRSETcheckinsert + \OTRSETcheckgrid + \OTRSETsetvsize + \OTRSETsethsize % or local ? + \OTRSETsetplaceholders + \OTRSEThandlepreposttext + \initializecolumntextareas % name ! + \OTRSETcheckstartcells + \OTRSETsetvsize} + +% \def\OTRSETcheckstartcells +% {\dorecurse\nofcolumns +% {\bgroup +% \mofcolumns\recurselevel +% \scratchcounter\currentcolumnstartcell % uses \mofcolumns, returns 1 or more +% \advance\scratchcounter \minusone +% \dorecurse\scratchcounter +% {\OTRSETdoifcellelse\mofcolumns\recurselevel +% \donothing{\OTRSETsetgridcell\mofcolumns\recurselevel\copy\placeholderboxe}}% +% \egroup}} + +\def\OTRSETcheckstartcells + {\dorecurse\nofcolumns + {\bgroup + \mofcolumns\recurselevel +\OTRSETsetcorrectnofcells\currentcolumnstartcell +\advance\scratchcounter \minusone + \dorecurse\scratchcounter + {\OTRSETdoifcellelse\mofcolumns\recurselevel + \donothing{\OTRSETsetgridcell\mofcolumns\recurselevel\copy\placeholderboxe}}% + \egroup}} + +% \OTRSEToutput +% {\dontcomplain % new, get rid of overfull message (to be sorted out) +% \OTRSETnaturalflush +% %\OTRSETstartnextpage +% \OTRSETdoflushfloats % actually belongs in \flushsavedfloats (but goes wrong) +% \OTRSETcheckfreelines +% \OTRSETchecksidefloat} + +\OTRSEToutput + {\dontcomplain % new, get rid of overfull message (to be sorted out) + \doloop + {\OTRSETnaturalflush + %\OTRSETstartnextpage % no + \OTRSETdoflushfloats % actually belongs in \flushsavedfloats (but goes wrong) + \OTRSETcheckfreelines + \ifsomefreecolumncells + \exitloop + \else + % flush page and get rid of more floats if present + \fi}% + \OTRSETchecksidefloat} + +\def\OTRSETinitializefeatures + {% number of lines + % new: raw + \getrawnoflines\textheight\xdef\columnmaxcells{\the\noflines}% + % direction + \doifelsevalue{\??mc\OTRSETidentifier\c!direction}\v!right + {\chardef\columndirection\zerocount} + {\chardef\columndirection\plusone}% + % balancing + \chardef\OTRSETbalancemethod\zerocount + \processaction + [\getvalue{\??mc\OTRSETidentifier\c!balance}] + [ \v!yes=>\chardef\OTRSETbalancemethod\plusone, + \v!top=>\chardef\OTRSETbalancemethod\plustwo, + \v!bottom=>\chardef\OTRSETbalancemethod\plusthree]} + +% keep 'm for a while +% +% \installoutput\OTRSETflushpreposttext +% {\global\setbox\precolumnbox\vbox{\unvbox\normalpagebox}% +% \ifcarryoverfootnotes \else +% \global\setbox\postcolumnbox\vbox{\placebottomnotes}% +% \fi} +% +% to be tested on 'boekinhoud' in 'pascal/demo-bbi' +% +% junk ! ! ! ! ! +% +%\installoutput\OTRSETflushpreposttext +% {\global\setbox\precolumnbox\vbox +% {\unvbox\normalpagebox +% \strut\vskip-2\lineheight\strut}% we want a proper depth +% \ifcarryoverfootnotes \else +% \global\setbox\postcolumnbox\vbox{\placebottomnotes}% +% \fi} +% +% \starttext +% \definecolumnset[two][n=2] +% \startcolumnset[two] \dorecurse{4}{\input tufte } \stopcolumnset +% \input tufte +% \startcolumnset[two] \input tufte \stopcolumnset +% \stoptext +% +% \installoutput\OTRSETflushpreposttext +% {\global\setbox\precolumnbox\vbox{\unvbox\normalpagebox}% +% \global\dp\precolumnbox\strutdepth +% \ifcarryoverfootnotes \else +% \global\setbox\postcolumnbox\vbox{\placebottomnotes}% +% \fi} + +% test: +% +% \setupcolumnset [test-1] [balance=yes] +% \setupcolumnset [test-2] [balance=yes] +% \setupcolumnsetlines[test-1][1][1] [8] +% \setupcolumnsetlines[test-1][1][2][10] +% \startcolumnset [test-1] \dorecurse {1}{\input tufte \par} \stopcolumnset +% \startcolumnset [test-2] \dorecurse {2}{\input ward \par} \stopcolumnset + +\ifx\lastskipinotr\undefined \newskip\lastskipinotr \fi + +\installoutput\OTRSETflushpreposttext + {\global\setbox\precolumnbox\vbox + {\unvbox\normalpagebox + \global\lastskipinotr\lastskip}% + \ifdim\lastskipinotr>\zeropoint + \global\setbox\precolumnbox\hbox + {\lower\strutdepth\box\precolumnbox}% + \fi + \global\dp\precolumnbox\strutdepth + \ifcarryoverfootnotes \else + \global\setbox\postcolumnbox\vbox{\placebottomnotes}% + \fi} + +\let\precolumnlines \!!zerocount +\let\postcolumnlines\!!zerocount + +\def\OTRSEThandlepreposttext + {\ifdim\ht\precolumnbox>\zeropoint % new + \getnoflines{\ht\precolumnbox}% + \edef\precolumnlines{\the\noflines}% + \doOTRSETsetgridcells + {\copy\placeholderboxe} + \plusone\plusone\nofcolumns\noflines + % normal version (single column set) + % {\box\precolumnbox}% + % compensated for bodyfont change + {\hbox + {\OTRSETsetcorrectcellht + \raise\scratchdimen\box\precolumnbox}}% + \else + \let\precolumnlines\!!zerocount + \fi + \ifdim\ht\postcolumnbox>\zeropoint % new, otherwise empty bottom line + \getnoflines{\ht\postcolumnbox}% + \edef\postcolumnlines{\the\noflines}% + \advance\columnfreecells -\noflines + \advance\columnfreecells \plusone + \doOTRSETsetgridcells + {\copy\placeholderboxe} + \plusone\columnfreecells\nofcolumns\noflines + {\box\postcolumnbox}% + \else + \let\postcolumnlines\!!zerocount + \fi} + +\def\OTRSETchecksidefloat + {} % {\sidefloatoutput} + +\def\OTRSETfinalsidefloatoutput + {} + +\def\OTRSETcheckgrid + {\topskip1\topskip + \ifforcecolumngrid + \widowpenalty\zerocount + \clubpenalty\zerocount + \brokenpenalty\zerocount + \fi} + +\def\OTRSETcheckinsert + {\iflastcolumnfootnotes + \ifnum\nofcolumns=\mofcolumns + \OTRSETforceinserts + \else + \OTRSETinhibitinserts + \fi + \else + \OTRSETforceinserts + \fi} + +\def\OTRSETforceinserts + {\enablenotes} + +\def\OTRSETinhibitinserts + {\disablenotes} + +% interface to footnotes + +\def\OTRSETassignwidths + {%\scratchdimen\makeupwidth + \freezetextwidth \scratchdimen\textwidth + % + \scratchcounter\zerocount + \dorecurse\nofcolumns + {\doifelsevalue{\??mc\OTRSETidentifier\recurselevel\c!width}\v!fit + {\advance\scratchcounter \plusone } + {\advance\scratchdimen -\getvalue{\??mc\OTRSETidentifier\recurselevel\c!width}}% + \advance\scratchdimen -\getvalue{\??mc\OTRSETidentifier\recurselevel\c!distance}}% + \ifcase\scratchcounter\else + \divide\scratchdimen \scratchcounter + \fi + \setgvalue{\??mc\??mc\c!width}{0}% + \dorecurse\nofcolumns + {\doifelsevalue{\??mc\OTRSETidentifier\recurselevel\c!width}\v!fit + {\dimen0=\scratchdimen} + {\setgvalue{\??mc\??mc\c!width}{1}% + \dimen0=\getvalue{\??mc\OTRSETidentifier\recurselevel\c!width}}% + \setxvalue{\??mc\recurselevel\??mc\c!width}{\the\dimen0}}} + +\def\OTRSETlocalwidth#1% + {\getvalue{\??mc\number#1\??mc\c!width}} + +\newbox\placeholderboxa +\newbox\placeholderboxb +\newbox\placeholderboxc +\newbox\placeholderboxd +\newbox\placeholderboxe +\newbox\placeholderboxf + +\def\columnplaceholder#1#2% + {\hbox + {\localcolortrue + \setbox\scratchbox\hbox to \hsize + {\iftracecolumnset \incolortrue \localcolortrue + \hskip-.5ex% + \startcolor[columnset:#2]\vrule\!!width1ex\!!height.5ex\!!depth.5ex\stopcolor + \fi + \hss}% + \ifcase#1\relax + \ht\scratchbox\zeropoint + \dp\scratchbox\zeropoint + \wd\scratchbox\zeropoint + \else + \wd\scratchbox\hsize + \ht\scratchbox\strutht + \dp\scratchbox\strutdp + \fi + \box\scratchbox}} + +\definepalet + [columnset] + [a=cyan,b=green,c=blue,d=red,e=magenta,f=darkgray] + +\def\OTRSETsetplaceholders + {\global\setbox\placeholderboxa\columnplaceholder0a% + \global\setbox\placeholderboxb\columnplaceholder0b% + \global\setbox\placeholderboxc\columnplaceholder0c% + \global\setbox\placeholderboxd\columnplaceholder0d% + \global\setbox\placeholderboxe\columnplaceholder0e% + \global\setbox\placeholderboxf\columnplaceholder1f} + +\def\doOTRSETshowstatus + {\llap{\incolortrue \localcolortrue \tt\tfxx + \startcolor[blue](\the\vsize->\number\columnfirstcell\#\number\columnfreecells)\stopcolor + \hskip\leftskip}} + +\def\OTRSETshowstatus + {\iftracecolumnset \doOTRSETshowstatus \fi} + +% \appendtoks \OTRSETshowstatus \to \everypar + +% page contents + +\def\OTRSETdopagecontents#1#2% takes two args: \box \unvbox + {\vbox to \textheight{\forgetall#1#2\pushproperties}} + +\def\OTRSETsomepagefloat {\def\floatmethod{PAGE}\OTRSETsomeslotfloat} % check +\def\OTRSETsomeherefloat {\def\floatmethod{HERE}\OTRSETsomeslotfloat} % check +\def\OTRSETsomeelsefloat {\def\floatmethod{HERE}\OTRSETsomeslotfloat} % check +\def\OTRSETsomefixdfloat {\def\floatmethod{FIXD}\OTRSETsomeslotfloat} % check +\def\OTRSETsometopfloat {\def\floatmethod{TOPS}\OTRSETsomeslotfloat} % check +\def\OTRSETsomebottomfloat{\def\floatmethod{BOTS}\OTRSETsomeslotfloat} % check + +\def\OTRSETflushfloatbox % nog verder doorvoeren en meer info in marge + {\iftestfloatbox\ruledhbox\fi{\box\floatbox}} + +\def\OTRSETsomeslotfloat[#1]% + {\setbox\floatbox\vbox{\flushfloatbox}% + \dp\floatbox\strutdp + \@EA\uppercasestring\floatmethod\to\floatmethod + \OTRSETstoreincolumnslot\floatmethod\floatbox + \doinsertfloatinfo} + +% kind of new, looks much like OTRONE, but not entirely + +\def\OTRSETdosettopinserts + {\bgroup + \ifsomefloatwaiting + \noffloatinserts\zerocount + \let\totaltopinserted\!!zeropoint + \OTRSETdodosettopinserts + \ifnum\@@bknbottom=\zerocount + \ifnum\@@bknlines>\zerocount + \ifdim\totaltopinserted>\zeropoint\relax + \dimen0\lineheight + \dimen0=\@@bknlines\dimen0 + \advance\dimen0 \totaltopinserted\relax + \ifdim\dimen0>\textheight % \vsize %%%%%%%%% \textheight + \showmessage\m!floatblocks8{\@@bknlines}% + \vfilll\eject + \fi + \fi + \fi + \fi + \fi + \egroup} + +\def\OTRSETdodosettopinserts + {\ifnum\noffloatinserts<\noftopfloats + \dogetfloat + \ifdim\topinserted=\zeropoint\relax + \topofinserttrue + \else + \topofinsertfalse + \fi + \setbox\scratchbox\vbox % kan beter ! + {\forgetall + \iftopofinsert + \ifdim\OTRSETtopoffset=\zeropoint + \moveongrid[\v!top] + \fi + \else + \betweenfloatblanko % inserts can't look back + \fi + \flushfloatbox + \blank[\@@bkspaceafter]}% + \global\advance\topinserted \ht\scratchbox\relax + \ifdim\topinserted>\vsize % was \textheight\relax + \OTRSETresavebox\floatbox + \noffloatinserts\noftopfloats\relax + \global\advance\topinserted -\ht\scratchbox + \let\OTRSETdodosettopinserts\relax % to be tested + \else + \xdef\totaltopinserted{\the\topinserted}% + \insert\topins{\forgetall\box\scratchbox}% interlineskip ? + \ifsomefloatwaiting + \advance\noffloatinserts \plusone + \else + \noffloatinserts\noftopfloats\relax + \fi + \dofloatflushedinfo + \fi + \else + \ifsomefloatwaiting + \showmessage\m!floatblocks6{\the\noftopfloats}% + \fi + \let\OTRSETdodosettopinserts\relax + \fi + \OTRSETdodosettopinserts} + +\def\OTRSETdosetbotinserts + {\bgroup + \ifsomefloatwaiting + \noffloatinserts\zerocount + \OTRSETdodosetbotinserts + \fi + \egroup} + +\def\OTRSETdodosetbotinserts + {\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 + \OTRSETresavebox\floatbox + \noffloatinserts\nofbotfloats\relax + \fi + \global\nofloatpermittedtrue % vgl topfloats s! + \else + \ifsomefloatwaiting + \showmessage\m!floatblocks7{\the\nofbotfloats}% + \fi + \let\OTRSETdodosetbotinserts\relax + \fi + \OTRSETdodosetbotinserts} + +\let\OTRSETdosetbothinserts\relax + +\def\OTRSETdotopinsertions + {\ifvoid\topins\else + \ifvoid\columntopbox\mofcolumns + \columnsettopbox\mofcolumns\box\topins + \else + \columnsettopbox\mofcolumns\vbox % temp, must be better + {\forgetall + \offinterlineskip + \box\columntopbox\mofcolumns + \box\topins} + \fi + \fi + \global\topinserted\zeropoint\relax} % goes away + +\def\OTRSETdobotinsertions + {\ifvoid\botins \else + \columnsetbotbox\mofcolumns\box\botins +% \else +% \columnsetbotbox\mofcolumns\vbox % temp, must be better +% {\forgetall +% \offinterlineskip +% \box\botins +% \box\columnbotbox\mofcolumns} + \fi + \global\botinserted\zeropoint\relax} % goes away + +% set ipv text + +% left right 1 2 3 +1 +2 +3 + +\let\columnleftareas \empty +\let\columnrightareas\empty + +% links rechts => odd, even, n, named + +\def\definecolumntextarea + {\dotripleempty\dodefinecolumntextarea} + +\def\dodefinecolumntextarea[#1][#2][#3]% y=0 is mogelijke en handig ! + {\ifthirdargument + \doifinsetelse{#2}{\v!both,\v!fixed} + {\definecolumntextarea[#1][\v!left ][\c!type=#2,#3]% + \definecolumntextarea[#1][\v!right][\c!type=#2,#3]} + {\doifelse{#2}\v!next + {\doifoddpageelse + {\definecolumntextarea[#1][\v!right][\c!type=#2,#3]} + {\definecolumntextarea[#1][\v!left ][\c!type=#2,#3]}} + {\presetlocalframed + [\??mt#1#2]% + \processaction[#2] % \doglobal voorkomt stack build up + [ \v!left=>\doglobal\addtocommalist{#1}\columnleftareas, + \v!right=>\doglobal\addtocommalist{#1}\columnrightareas]% + \getparameters[\??mt#1#2] + [\c!x=1,\c!y=1,\c!nx=1,\c!ny=1,\c!clipoffset=2\lineheight, + \c!leftoffset=\zeropoint,\c!rightoffset=\zeropoint, + \c!offset=\v!overlay,\c!strut=\v!no,\c!frame=\v!off, + \c!type=#2,\c!page=1,\c!state=\v!stop,#3]}}% + \else + \definecolumntextarea[#1][\v!next][#2]% + \fi} + +\def\setupcolumntextarea + {\dotripleempty\dosetupcolumntextarea} + +\def\dosetupcolumntextarea[#1][#2][#3]% + {\ifthirdargument + \doifelse{#2}\v!both + {\setupcolumntextarea[#1][\v!left ][#3]% + \setupcolumntextarea[#1][\v!right][#3]} + {\doifelse{#2}\v!next + {\doifoddpageelse + {\setupcolumntextarea[#1][\v!right][#3]} + {\setupcolumntextarea[#1][\v!left][#3]}} + {\getparameters[\??mt#1#2][#3]}}% + \else + \setupcolumntextarea[#1][\v!next][#2]% + \fi} + +\def\docheckcolumnsetareapage#1#2% + {\ifnum\getvalue{\??mt#1\c!page}>\plusone + \doifelsevalue{\??mt#1\c!type}\v!fixed + {\ifnum\columnsetpage=\getvalue{\??mt#1\c!page}\relax + \donetrue\else\donefalse + \fi} + {\ifnum\columnsetpage<\getvalue{\??mt#1\c!page}\relax + \donefalse\else\donetrue + \fi}% + \else + \donetrue + \fi} + +\def\initializecolumntextareas + {\ifodd\realpageno + \doinitializecolumntextareas\columnrightareas\v!right + \else + \doinitializecolumntextareas\columnleftareas\v!left + \fi} + +\def\doinitializecolumntextareas#1#2% + {\def\docommand##1% + {\docheckcolumnsetareapage{##1#2}\plusone + \ifdone + \donefalse + \processaction + [\getvalue{\??mt##1#2\c!state}] + [ \v!start=>\donetrue, + \v!repeat=>\donetrue, + \s!unknown=>\doperformtest\commalistelement\donetrue\donefalse]% + \ifdone\dodoinitializecolumntextareas{##1}{#2}\fi + \fi}% + \processcommacommand[#1]\docommand} + +\def\dodoinitializecolumntextareas#1#2% + {\doOTRSETsetgridcells + {\copy\placeholderboxd} + {\getvalue{\??mt#1#2\c!x }}{\getvalue{\??mt#1#2\c!y }} + {\getvalue{\??mt#1#2\c!nx}}{\getvalue{\??mt#1#2\c!ny}} + {\copy\placeholderboxd}} + +\def\placecolumntextareas + {\ifodd\realpageno + \doplacecolumntextareas\columnrightareas\v!right + \else + \doplacecolumntextareas\columnleftareas\v!left + \fi} + +\def\doplacecolumntextareas#1#2% global ? + {\bgroup + \forgetall + \def\docommand##1% + {\docheckcolumnsetareapage{##1#2}\zerocount + \ifdone + \donefalse + \processaction + [\getvalue{\??mt##1#2\c!state}] + [ \v!start=>\donetrue\doglobal\removefromcommalist{##1}#1, + \v!repeat=>\donetrue, + \s!unknown=>\doperformtest\commalistelement\donetrue\donefalse]% + \ifdone + \dodoplacecolumntextareas{##1}{#2}% + \else + \doglobal\removefromcommalist{##1}#1% + \fi + \fi}% + \processcommacommand[#1]\docommand + \egroup} + +% \page[left] +% \definecolumntextarea[intro][left][x=1,y=1,nx=4,ny=20,state=start,background=introlayer] +% \setupcolumntextareatext[intro][left][\setups{intro}] +% \flushcolumntextareas + +\def\flushcolumntextareas + {\initializecolumntextareas + \setvsize} + +\def\columntextlastbackspace{\backspace} + +% beware, we have clipping offsets of 2\lineheight by default + +\def\columntextareaparameter#1% + {\csname\??mt\currentcolumntestarea#1\endcsname} + +\def\dodoplacecolumntextareas#1#2% + {\def\currentcolumntestarea{#1#2}% + \!!counta\columntextareaparameter\c!x + \!!countb\columntextareaparameter\c!nx + \docalculatecolumnsetspan + \!!heighta\columntextareaparameter\c!ny\lineheight + % wrong + % \ifnum\columntextareaparameter\c!y=\zerocount + % \advance\!!heighta -\lineheight + % \advance\!!heighta \topskip + % \fi + % \advance\!!heighta -\lineheight % option + \ifnum\columntextareaparameter\c!y=\plusone + \advance\!!heighta -\lineheight + \advance\!!heighta \topskip + \fi + % + \setbox\scratchbox\vbox + {\donetrue\localframed + [\??mt\currentcolumntestarea] + [\c!location=,% new (*) + \c!width=\!!widtha,\c!height=\!!heighta,\c!lines=] + {\columntextareaparameter\empty}}% + \!!counta\columntextareaparameter\c!x + \!!countb\columntextareaparameter\c!y + \advance\!!countb \columntextareaparameter\c!ny + \advance\!!countb \minusone + % new (*) + \doif{\columntextareaparameter\c!location}\v!depth + {\setbox\scratchbox\hbox{\lower\strutdepth\box\scratchbox}% + \dp\scratchbox\zeropoint + \ht\scratchbox\!!heighta}% + % + \setbox0\hbox + {\ifcase\!!countc + \copy\scratchbox % \box + \else + \clip + [ %\c!topoffset=\columntextareaparameter\c!clipoffset,% + %\c!bottomoffset=\columntextareaparameter\c!clipoffset,% + %\c!leftoffset=\columntextareaparameter\c!clipoffset,% + \c!offset=\columntextareaparameter\c!clipoffset,% + \c!offset=\columntextareaparameter\c!clipoffset,% + \c!rightoffset=\columntextareaparameter\c!rightoffset,% + \c!width=\!!widthb,% + \c!height=\!!heighta]% + {\copy\scratchbox}% + \fi}% + \OTRSETsetgridcell\!!counta\!!countb\box0 + \ifcase\!!countc\else + \advance\!!counta \columntextareaparameter\c!nx + \advance\!!counta -\!!countc + \advance\!!widtha -\!!widthb + \setbox0\hbox + {\hskip-\namedlayoutparameter\v!odd\c!backspace + \clip + [ %\c!topoffset=\columntextareaparameter\c!clipoffset,% + %\c!bottomoffset=\columntextareaparameter\c!clipoffset,% + %\c!rightoffset=\columntextareaparameter\c!clipoffset,% + \c!offset=\columntextareaparameter\c!clipoffset,% + \c!offset=\columntextareaparameter\c!clipoffset,% + \c!leftoffset=\columntextareaparameter\c!leftoffset,% + \c!width=\!!widtha,% + \c!height=\!!heighta,% + \c!hoffset=\!!widthb]% + {\copy\scratchbox}}% + \OTRSETsetgridcell\!!counta\!!countb\box0% + \fi} + +\def\setupcolumntextareatext + {\dotripleempty\dosetupcolumntextareatext} + +\long\def\dosetupcolumntextareatext[#1][#2][#3]% + {\ifthirdargument + \doifelse{#2}\v!both + {\setvalue{\??mt#1\v!left }{#3}% + \setvalue{\??mt#1\v!right}{#3}} + {\doifelse{#2}\v!next + {\doifoddpageelse + {\setvalue{\??mt#1\v!right}{#3}}% + {\setvalue{\??mt#1\v!left }{#3}}}% + {\setvalue{\??mt#1#2}{#3}}}% + \else + \setupcolumntextareatext[#1][\v!next][{#2}]% + \fi} + +\def\docalculatecolumnsetspan + {% \!!counta <= x + % \!!countb <= nx + % \!!widtha => total width + % \!!widthb => left width + % \!!countc => left cols + \!!widtha\!!countb\textwidth % we assume equal widths + \advance\!!countb \!!counta + \advance\!!countb \minusone + \ifnum\!!countb>\nofcolumns + \!!countc\!!countb + \advance\!!countc -\nofcolumns + \!!countb\nofcolumns + \else + \!!countc\zerocount + \fi + \advance\!!counta \plusone + \dostepwiserecurse\!!counta\!!countb\plusone + {\advance\!!widtha\OTRSETgetparameter\c!distance\recurselevel}% + \!!widthb\!!widtha + \advance\!!widthb -\!!countc\textwidth + \ifodd\realpageno \else % tricky, assumes that we keep there + \ifcase\!!countc\else + % nog niet ok voor enkel/doublesided + \advance\!!widtha \namedlayoutparameter\v!even\c!backspace + \advance\!!widtha \namedlayoutparameter\v!odd \c!backspace + \advance\!!widthb \namedlayoutparameter\v!even\c!backspace + \dorecurse\!!countc + {\advance\!!widtha\OTRSETgetparameter\c!distance\recurselevel}% + \fi + \fi} + +\def\columnsetspanhsize{\textwidth} + +\def\setcolumnsetspanhsize#1#2% x nx / uses counta/b + {\!!counta#1\!!countb#2\docalculatecolumnsetspan + \edef\columnsetspanhsize{\the\!!widtha}} + +\def\definecolumnsetspan + {\dodoubleempty\dodefinecolumnsetspan} + +\def\dodefinecolumnsetspan[#1][#2]% + {%\ifsecondargument + \defineframedtext + [cs:#1] + [\c!frame=\v!off, + \c!before=, + \c!after=, + \c!offset=\v!overlay, + \c!location=\v!left, + \c!linecorrection=\v!off, + \c!depthcorrection=\v!off, + \c!n=2, + \c!nlines=0, + \c!indenting=, + \c!indentnext=\v!yes, + \c!default=HERE, + \c!alternative=\v!a, + #2]% + %\else + % \definecolumnspan[][#1]% + }%\fi} + +\definecolumnsetspan[\s!default] + +\def\setupcolumnsetspan + {\dodoubleempty\dosetupcolumnsetspan} + +\def\dosetupcolumnsetspan[#1][#2]% + {\ifsecondargument + \setupframedtexts[cs:#1][#2]% + \else + \setupcolumnsetspan[\s!default][#1]% + \fi} + +\def\startcolumnsetspan + {\dotripleempty\dostartcolumnsetspan} + +%%%%%%%%%%%%%%%% TODO + +\def\dostartcolumnsetspan[#1][#2][#3]% [#3] gobbles space + {\endgraf % else rubish output if forgotten + \vskip \zeropoint % make sure otr is done, otherwise last line problems + \bgroup + \forgetall + \ifnum\columnsetlevel>\zerocount\else + % of course we needed a one-column fall back for tm + \columnsetspanhsize\hsize + \nofcolumns\plusone + \mofcolumns\plusone + \fi + \setupframedtexts[cs:#1] + [\c!width=\columnsetspanhsize, + \c!linecorrection=\v!off, + \c!depthcorrection=\v!off, + #2]% + % determine widths + \!!countc\framedtextparameter{cs:#1}\c!n + % \!!countd\numexpr(\nofcolumns-\mofcolumns+\plusone)% + \!!countd\nofcolumns + % n <= n of columns + \ifnum\!!countc>\!!countd \!!countc\!!countd \fi + \advance\!!countd -\mofcolumns + \advance\!!countd \plusone + % n <= n of available columns (alternative a) + \doif{\framedtextparameter{cs:#1}\c!alternative}\v!a + {\ifnum\!!countc>\!!countd \!!countc\!!countd \fi}% + % here it all starts + \setcolumnsetspanhsize\mofcolumns\!!countc % a/b used + \hsize\columnsetspanhsize + \setbox\scratchbox\vbox\bgroup + \dostartframedtext[cs:#1][\v!none]% geen nils placement + % spoils spacing : \vskip-\struttotal\par\verticalstrut\par + \ifnum\columnsetlevel>\zerocount + \framedtextparameter{cs:#1}\c!before + \fi + \def\stopcolumnsetspan{\dostopcolumnsetspan{#1}}} + +\def\dostopcolumnsetspan#1% + {\par + \verticalstrut + \kern-2\struttotal + \verticalstrut + \ifnum\columnsetlevel>\zerocount + \doifsomething{\framedtextparameter{cs:#1}\c!after} + {\framedtextparameter{cs:#1}\c!after + \kern\zeropoint}% otherwise blanks disappear, better be a switch + \else + \endgraf + \fi + \dostopframedtext + \egroup + \setbox\scratchbox\frozenhbox to \hsize + {\dontcomplain + \alignedline{\framedtextparameter{cs:#1}\c!location}\v!middle + {\lower\strutdepth\box\scratchbox}}% + \dp\scratchbox\zeropoint % else wrong snap insidefloat +% +% to be tested first (strange in grid mode) +% +% \setbox\scratchbox\frozenhbox to \hsize +% {\dontcomplain +% \chardef\alignstrutmode\zerocount +% \alignedline{\framedtextparameter{cs:#1}\c!plaats}\v!midden +% {\box\scratchbox}}% +% + \ifinsidefloat + \box\scratchbox + \else\ifnum\columnsetlevel>\zerocount + % we only set \columnsetspacing when asked for, else bottom problems + % don't change this any more (test naw) + \chardef\columnslotspacing\framedtextparameter{cs:#1}\c!nlines\relax + % todo: nboven/onder & \chardef\columnslotlocation2 + %\OTRSETstoreincolumnslotHERE\scratchbox + \edef\floatmethod{\framedtextparameter{cs:#1}\c!default}% + \@EA\uppercasestring\floatmethod\to\floatmethod + % todo : \v!here -> here enzovoorts + \OTRSETstoreincolumnslot\floatmethod\scratchbox + % watch out: no \dochecknextindentation{tag} + \checknextindentation[\framedtextparameter{cs:#1}\c!indentnext]% + \else + % of course we needed a one-column fall back for tm; brrr, the box has now too + % much height (try \ruledvbox); don't change this without testing techniek + \scratchdimen\ht\scratchbox + \advance\scratchdimen-\strutdp + \ht\scratchbox\scratchdimen + \framedtextparameter{cs:#1}\c!before + \snaptogrid\vbox{\box\scratchbox}% + \framedtextparameter{cs:#1}\c!after + \fi\fi + \egroup + \endgraf} + +% \startcolumnset[two] +% \input tufte +% \startcolumnsetspan[two][width=20cm,location=middle] \input tufte \stopcolumnsetspan +% \startcolumnsetspan[two][default=btlr] \input tufte \stopcolumnsetspan +% \input tufte \par +% \input tufte \par +% \startcolumnsetspan[two] \emptylines[5] \stopcolumnsetspan +% \startcolumnsetspan[two] \input tufte \stopcolumnsetspan +% \stopcolumnset + +\protect \endinput + +% extreme examples (1) +% +% \setupfloats[numbering=nocheck] +% +% \definecolumnset [first] [n=2,start=0] +% \definecolumnset [next] [n=2,start=3] +% +% \setuptexttexts[\vbox to \textheight{\topskipcorrection \hsize\makeupwidth left \hfill right\vfill}] +% +% \setuphead[chapter][text=empty] +% +% \starttext +% +% \startcolumnset[first,next] +% \placefigure[btrl]{}{} +% \placefigure[tblr]{}{} +% \chapter{thuan} \dorecurse{25}{\recurselevel: \input thuan \endgraf} +% \stopcolumnset +% +% \startcolumnset[first,next] +% \chapter{thuan} \dorecurse{25}{\input thuan \endgraf\placefigure{}{}} +% \stopcolumnset + +\unprotect + +% only in columnsets + +% \def\cornerfigure +% {\dotripleempty\docornerfigure} +% +% \def\docornerfigure[#1][#2][#3]% [layer] [location] [settings] +% {\bgroup +% \dowithnextbox +% {\!!doneafalse +% \!!donebfalse +% \processallactionsinset +% [\v!left,\v!bottom,#2] +% [ \v!left=>\!!doneatrue , +% \v!right=>\!!doneafalse, +% \v!top=>\!!donebtrue , +% \v!bottom=>\!!donebfalse]% +% \!!widtha\nextboxwd +% \if!!donea +% % unchecked +% \advance\!!widtha-\backspace +% \else +% % unchecked +% \advance\!!widtha-\backspace +% \fi +% \!!widtha\textwidth % could be an option +% \!!heighta\nextboxht +% % zou een macro moeten zijn \getnoflayoutlines +% \ifnum\layoutparameter\c!lines=\zerocount +% \getnoflines\textheight +% \else +% \noflines\layoutparameter\c!lines +% \fi +% % +% \advance\noflines \plusone % wordt default, instelbaar +% \!!heightb\noflines\lineheight\relax +% \if!!doneb % boven +% % unchecked +% \advance\!!heighta-\topspace +% \advance\!!heighta-\headerheight +% \advance\!!heighta-\headerdistance +% \else % onder +% % checked +% \advance\!!heighta-\paperheight +% \advance\!!heighta+\!!heightb +% \advance\!!heighta+\topspace +% \advance\!!heighta+\headerheight +% \advance\!!heighta+\headerdistance +% \advance\!!heighta-\footerdistance +% \advance\!!heighta-\footerheight +% \fi +% \getnoflines\!!heighta +% \!!heighta\noflines\lineheight\relax +% \def\docornerfigure[####1]% +% {\expanded{\plaatsfiguur[####1,\v!none]{} +% {\noexpand\phantombox[\c!width=\the\!!widtha,\c!height=\the\!!heighta]}}}% +% \if!!donea +% \if!!doneb % links boven / rb +% \setlayer[#1] +% [\c!corner={\v!left,\v!top},\c!location=rb,#3] +% {\flushnextbox}% +% \docornerfigure[tblr]% +% \else % links onder / rt +% \setlayer[#1] +% [\c!corner={\v!left,\v!bottom},\c!location=rt,#3] +% {\flushnextbox}% +% \docornerfigure[btlr]% +% \fi +% \else +% \if!!doneb % rechts boven / lt +% \setlayer[#1] +% [\c!corner={\v!right,\v!top},\c!location=lb,#3] +% {\flushnextbox}% +% \docornerfigure[tbrl]% +% \else % rechts onder / lb +% \setlayer[#1] +% [\c!corner={\v!right,\v!bottom},\c!location=lt,#3] +% {\flushnextbox}% +% \docornerfigure[btrl]% +% \fi +% \fi +% \egroup} +% \vbox} diff --git a/tex/context/base/page-set.mkiv b/tex/context/base/page-set.mkiv new file mode 100644 index 000000000..cc6fbb5e6 --- /dev/null +++ b/tex/context/base/page-set.mkiv @@ -0,0 +1,2674 @@ +%D \module +%D [ file=page-set, +%D version=2000.10.20, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Column Sets, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% getnoflines vs getrawnoflines + +% some day: cleanup and go etex + +\writestatus{loading}{ConTeXt Page Macros / Column Sets} + +% todo : last longer than previous +% todo : block span over last column if footnotes +% todo : diagnosis balancing run +% todo : separate footnote placement +% todo : go on on same page with colset +% todo : test page areas per page +% todo : leftmargin/rightmargin (better than afstand(1)) + +% use the OTRSET layer for more purposes, like the footnotes ! + +\unprotect + +\newcount\tofcolumns % total +\newcount\lofcolumns % left +\newcount\rofcolumns % right + +\newcount\columnfirstcell \columnfirstcell=1 +\newcount\columnlastcell +\newcount\columnfreecells +\newcount\currenthcell +\newcount\currentvcell +\newcount\columnhcells +\newcount\columnvcells + +\newif\ifenoughcolumncells +\newif\ifsomefreecolumncells +\newif\ifcolumnspread +\newif\iftracecolumnset % \tracecolumnsettrue + +\def\columnmaxcells {75} % runtime +\def\columnmaxfreecells {0} % runtime +\def\columngaplimit {0} % {5} + +\def\@otr@{otr} + +\def\OTRSETmakeupwidth{\innermakeupwidth} + +\let\OTRSETflushsidefloats \forgetsidefloats % \relax +\let\OTRSETsynchronizesidefloats\forgetsidefloats % \relax + +\def\OTRSETgridcell #1#2{\csname \@otr@:\number#1:\number#2\endcsname} +\def\OTRSETgetgridcell#1#2{\box\csname \@otr@:\number#1:\number#2\endcsname} +\def\OTRSETsetgridcell#1#2{\global\setbox\csname\@otr@:\number#1:\number#2\endcsname} + +\long\def\OTRSETdoifcellelse#1#2% + {\relax\ifvoid\csname\@otr@:\number#1:\number#2\endcsname + \@EA\secondoftwoarguments\else\@EA\firstoftwoarguments + \fi} + +% The following two macros are used to compensate for a switch in body fonts +% as in: +% +% \definecolumnset [two] [n=2,balancing=yes] +% \definecolumnset [three] [n=3,balancing=yes] +% +% \setupcolumnsetlines[two][1][1][7] +% \setupcolumnsetlines[two][1][2][10] +% +% \setupcolumnsetlines[three][1][1][40] +% \setupcolumnsetlines[three][1][2][40] +% \setupcolumnsetlines[three][1][3][40] +% +% \setupcolumnsetstart[three][1][1][15] +% \setupcolumnsetstart[three][1][2][20] +% \setupcolumnsetstart[three][1][3][20] +% +% \starttext +% \startcolumnset [two] \dorecurse {1}{\input tufte \par} \stopcolumnset +% \switchtobodyfont[small] +% \startcolumnset [three] \dorecurse {1}{\input tufte \par} \stopcolumnset +% \stoptext + +%D Marks in columnsets: +%D +%D \starttyping +%D \definemarking[M] +%D \setupheadertexts[\setups{show-M-marks}] +%D \definecolumnset[test][n=3] +%D +%D \startsetups show-M-marks +%D \getmarking[M][1][previous]/\getmarking[M][1][first]/\getmarking[M][1][last]\quad +%D \getmarking[M][2][previous]/\getmarking[M][2][first]/\getmarking[M][2][last]\quad +%D \getmarking[M][3][previous]/\getmarking[M][3][first]/\getmarking[M][3][last]\quad +%D \getmarking[M][1][previous]/\getmarking[M][1][first]/\getmarking[M][last]\quad +%D \getsavedmarking[M][previous]/\getsavedmarking[M][first]/\getsavedmarking[M][last] +%D \stopsetups +%D +%D \startbuffer +%D \section{Knuth} [K1]\marking[M]{k1} [K2]\marking[M]{k2} \input knuth +%D \section{Zapf} [Z]\marking[M]{z} \input zapf +%D \stopbuffer +%D +%D \startbuffer +%D \section{Ward} [W]\marking[M]{w} \input ward +%D \placefigure[here]{none}{\externalfigure[a][height=2cm]} +%D \section{Davis} [D]\marking[M]{d} \input davis +%D \section{Zapf} [Z]\marking[M]{z} \input zapf +%D \stopbuffer +%D +%D \startbuffer +%D \section{Ward} [W]\marking[M]{w} \input ward +%D \placefigure[here]{none}{\externalfigure[a][height=2cm]} +%D \section{Davis} [D]\marking[M]{d} \input davis +%D \section{Zapf} [Z]\marking[M]{z} \input zapf +%D \section{Douglas} [O]\marking[M]{o} \input douglas +%D \stopbuffer +%D +%D \starttext +%D \startcolumnset[test] +%D \dorecurse{5}{\getbuffer} +%D \placefigure[here]{none}{\externalfigure[a][height=2cm]} +%D % \column % sometimes needed +%D \stopcolumnset +%D \stoptext +%D \stoptyping + +% not ok yet, for column sets we need a special case: within a column we +% need to bubble-up the marks; the indirectness permits overloading here + +\let\saveOTRSETmark \refreshsavedmark +\let\bubbleOTRSETmark\bubblesavedmark +\let\resetOTRSETmark \resetsavedmark +\let\presetOTRSETmark\presetsavedmark + +\def\doregisterOTRSETmarks#1{\saveOTRSETmark [#1][\number\mofcolumns]} +\def\dobubbleOTRSETmarks #1{\bubbleOTRSETmark[#1][\number\mofcolumns]} +\def\doresetOTRSETmarks #1{\resetOTRSETmark [#1][\recurselevel]} +\def\dopresetOTRSETmarks #1{\presetOTRSETmark[#1][\recurselevel]} + +\def\registerOTRSETmarks + {\processcommacommand[\alldefinedmarks]\doregisterOTRSETmarks} +\def\bubbleOTRSETmarks + {\processcommacommand[\alldefinedmarks]\dobubbleOTRSETmarks} +\def\resetOTRSETmarks + {\dorecurse\nofcolumns{\processcommacommand[\alldefinedmarks]\doresetOTRSETmarks}} +\def\presetOTRSETmarks + {\dorecurse\nofcolumns{\processcommacommand[\alldefinedmarks]\dopresetOTRSETmarks}} + +%D test case of Vit Zika (context list): +%D +%D \starttyping +%D \setuplayout[height=middle,width=middle,grid=yes] +%D +%D \starttext +%D \startcolumnset +%D \dorecurse{10} +%D {\input thuan \endgraf +%D \bgroup +%D \ss\restoreinterlinespace +%D \dorecurse{3}{\input hawking \endgraf} +%D \egroup +%D \input bryson \endgraf} +%D \stopcolumnset +%D \stoptext +%D \stoptyping + +\def\OTRSETsetcorrectnofcells#1% + {\bgroup + \!!counta#1\relax + \ifdim\globalbodyfontsize=\localbodyfontsize + \restoreinterlinespace + \else + \!!dimena-\!!counta\lineheight + \restoreglobalbodyfont % slow, we need a fast one + \advance\!!dimena\!!counta\lineheight + \getnoflines\!!dimena + \advance\!!counta\noflines + \ifnum\!!counta<#1\else + \!!counta#1\relax + \fi + \fi + \relax % needed ! ! ! ! else lookahead over \fi and \@EA + \@EA\egroup\@EA\scratchcounter\the\!!counta\relax} + +\def\OTRSETsetcorrectcellht + {\bgroup + \!!dimena-\strutht\relax + \ifdim\globalbodyfontsize=\localbodyfontsize + \restoreinterlinespace + \else + \restoreglobalbodyfont + \fi + \advance\!!dimena\strutht + \relax % needed ! ! ! ! else lookahead over \fi and \@EA + \@EA\egroup\@EA\scratchdimen\the\!!dimena\relax} + +\def\columnerasegridboxes % maybe dedicated loops + {\bgroup + \increment\columnmaxcells\relax + \ifodd\realpageno + \else % we are on the other page + \columnspreadfalse + \fi + \ifcolumnspread + \dorecurse\nofcolumns + {\let\!!stringa\recurselevel + \scratchcounter\recurselevel \advance\scratchcounter\lofcolumns + \edef\!!stringb{\the\scratchcounter}% + \dostepwiserecurse \zerocount \columnmaxcells \plusone + {\ifcsname\@otr@:\!!stringa:\recurselevel\endcsname + \global\setbox\csname\@otr@:\!!stringa:\recurselevel\endcsname + \ifcsname\@otr@:\!!stringb:\recurselevel\endcsname + \box\csname\@otr@:\!!stringb:\recurselevel\endcsname + %\global\setbox\csname\@otr@:\!!stringa:\recurselevel\endcsname\box\csname\@otr@:\!!stringb:\recurselevel\endcsname + \else + \emptybox + %\global\setbox\csname\@otr@:\!!stringa:\recurselevel\endcsname\emptybox + \expandafter\newbox\csname\@otr@:\!!stringb:\recurselevel\endcsname + \fi + \else + \expandafter\newbox\csname\@otr@:\!!stringa:\recurselevel\endcsname + \ifcsname\@otr@:\!!stringb:\recurselevel\endcsname + \global\setbox\csname\@otr@:\!!stringa:\recurselevel\endcsname\box\csname\@otr@:\!!stringb:\recurselevel\endcsname + \else + \expandafter\newbox\csname\@otr@:\!!stringb:\recurselevel\endcsname + \fi + \fi}}% + \else + \dorecurse \tofcolumns + {\let\!!stringa\recurselevel + \dostepwiserecurse \zerocount \columnmaxcells \plusone + {\ifcsname\@otr@:\!!stringa:\recurselevel\endcsname + \global\setbox\csname\@otr@:\!!stringa:\recurselevel\endcsname\emptybox + \else + \expandafter\newbox\csname\@otr@:\!!stringa:\recurselevel\endcsname + \fi}}% + \fi + \dorecurse\tofcolumns + {\global\setbox\csname\@otr@:\recurselevel:\columnmaxcells\endcsname\copy\placeholderboxa}% + \global\columnfirstcell\zerocount + \global\columnlastcell\columnfirstcell + \global\columnfreecells\columnfirstcell + \egroup} + +\def\doOTRSETsetgridcells#1#2#3#4#5#6% placeholder col row wid hei {data} + {\!!countd#2\advance\!!countd#4\advance\!!countd\minusone + \!!counte#3\advance\!!counte#5\advance\!!counte\minusone + \dostepwiserecurse{#2}\!!countd\plusone + {\!!countf\recurselevel + \dostepwiserecurse{#3}\!!counte\plusone + {\OTRSETsetgridcell\!!countf\recurselevel#1}}% + \dostepwiserecurse{#3}\!!counte\plusone + {\global\wd\OTRSETgridcell{#2}\recurselevel\hsize}% + \OTRSETsetgridcell{#2}\!!counte#6} + +\def\OTRSETsetgridcells + {\doOTRSETsetgridcells{\copy\placeholderboxb}} + +\def\OTRSETerasegridcells#1#2#3#4% + {\doOTRSETsetgridcells{\emptybox}{#1}{#2}{#3}{#4}{\emptybox}} + +\unexpanded\def\setupcolumnsetlines{\doquintupleempty\dosetupcolumnsettrick[l]} +\unexpanded\def\setupcolumnsetstart{\doquintupleempty\dosetupcolumnsettrick[s]} + +\def\dosetupcolumnsettrick[#1][#2][#3][#4][#5]% tag id page col value + {% not needed, is already relative + % \doifinstringelse{+}{#3}{\scratchcounter\realpageno}{\scratchcounter\zerocount}% + % \advance\scratchcounter#3\relax % \relax needed + % \setevalue{\??mc:#1:#2:\the\scratchcounter:\number#4}{\number#5}} + \iffifthargument + \setevalue{\??mc:#1:#2:\number#3:\number#4}{\number#5}% + \else + \setevalue{\??mc:#1:#2:\number#3:0}{\number#4}% + \fi} + +\def\currentcolumnmaxcellstag #1{\??mc:l:\OTRSETidentifier:\columnsetpage:\number#1} +\def\currentcolumnstartcelltag#1{\??mc:s:\OTRSETidentifier:\columnsetpage:\number#1} + +\def\doresetcolumnsetlines#1% + {\ifcsname\currentcolumnmaxcellstag{#1}\endcsname + \letgvalue{\currentcolumnmaxcellstag{#1}}\zerocount + \fi + \ifcsname\currentcolumnmaxcellstag{#1}\endcsname + \letgvalue{\currentcolumnmaxcellstag{#1}}\zerocount + \fi} + +\def\currentcolumnsomecells#1#2% + {\ifcsname#1\mofcolumns\endcsname + \ifnum\csname#1\mofcolumns\endcsname=\zerocount + #2% + \else + \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\relax + \fi + \else + #2% + \fi\fi} + +\def\currentcolumnmaxcells {\currentcolumnsomecells\currentcolumnmaxcellstag \columnmaxcells} +\def\currentcolumnstartcell{\currentcolumnsomecells\currentcolumnstartcelltag\plusone} + +\def\OTRSETsetfreecells#1#2% col start + {\bgroup + \global\columnfirstcell\ifnum#2=0 1\else#2\fi\relax + \OTRSETsetcorrectnofcells\currentcolumnmaxcells % sets \scratchcounter + \edef\columnmaxcells{\the\scratchcounter}% + \ifnum\columnfirstcell>\columnmaxcells + \global\columnfreecells\zerocount + \global\columnfirstcell\plusone + \global\columnlastcell \zerocount + \global\somefreecolumncellsfalse + %\message{no cells a}% + \else + \doloop + {\ifnum\columnfirstcell>\columnmaxcells\relax + \exitloop + \else + \OTRSETdoifcellelse{#1}\columnfirstcell + {\global\advance\columnfirstcell\plusone}\exitloop + \fi}% + \global\columnlastcell\columnfirstcell + \doloop + {\ifnum\columnlastcell>\columnmaxcells\relax + \exitloop + \else + \OTRSETdoifcellelse{#1}\columnlastcell + {\global\advance\columnlastcell \minusone \exitloop} + {\global\advance\columnlastcell \plusone }% + \fi}% + \ifnum\columnfirstcell>\columnmaxcells + \global\columnfreecells\zerocount + \global\columnfirstcell\plusone + \global\columnlastcell \zerocount + \global\somefreecolumncellsfalse + %\message{no cells b}% + \else + \ifnum\columnlastcell>\columnmaxcells + \global\columnlastcell\columnmaxcells + \fi + \global\columnfreecells\columnlastcell + \global\advance\columnfreecells -\columnfirstcell + \global\advance\columnfreecells \plusone + \global\somefreecolumncellstrue + %\message{\number\columnfirstcell-\number\columnlastcell=\number\columnfreecells}% + \fi + \fi + \egroup} + +\def\OTRSETgetmaxfreecells#1#2% col start + {\let\columnmaxfreecells\!!zerocount + \let\columnfrmfreecells\!!zerocount + \pushmacro \columnmaxcells +\OTRSETsetcorrectnofcells\currentcolumnmaxcells % sets \scratchcounter +\edef\columnmaxcells{\the\scratchcounter}% + \scratchcounter\zerocount + \dostepwiserecurse{#2}\columnmaxcells\plusone + {\OTRSETdoifcellelse{#1}\recurselevel + {\ifnum\columnmaxfreecells<\scratchcounter + \edef\columnmaxfreecells{\the\scratchcounter}% + \let\columnfrmfreecells\recurselevel + \fi + \scratchcounter\zerocount} + {\advance\scratchcounter\plusone}}% + \popmacro\columnmaxcells} + +\long\def\OTRSETrecurseRL#1% + {\dostepwiserecurse\nofcolumns\plusone\minusone + {#1\hskip\OTRSETgetparameter\c!distance\recurselevel}} + +\def\OTRSETmakegridbox + {\ifcase\columndirection + \OTRSETdomakegridbox\plusone\nofcolumns\plusone + \else + \OTRSETdomakegridbox\nofcolumns\plusone\minusone + \fi} + +\def\OTRSETmakeupwidth{\makeupwidth} % temporary indirectness + +\def\OTRSETdomakegridbox#1#2#3% + {\hbox\bgroup + \dontcomplain + \forgetall % can go once in \flush + \!!heighta \textheight + % test first ! + \hbox to \OTRSETmakeupwidth + {\dostepwiserecurse{#1}{#2}{#3} + {\mofcolumns\recurselevel + \localcolumnwidth\OTRSETlocalwidth\mofcolumns + \setbox\scratchbox\hbox\localframed + [\??mc\OTRSETidentifier\number\mofcolumns]% + [\c!width=\localcolumnwidth,\c!height=\!!heighta,\c!lines=]% + {}% + \wd\scratchbox\localcolumnwidth + \ht\scratchbox\!!heighta + \ifcase\columndirection + \hskip\OTRSETgetparameter\c!distance\recurselevel + \box\scratchbox + \else + \box\scratchbox + \hskip\OTRSETgetparameter\c!distance\recurselevel + \fi}}% + \hskip-\OTRSETmakeupwidth + % main text + \hbox to \OTRSETmakeupwidth + {\dostepwiserecurse{#1}{#2}{#3} + {\mofcolumns\recurselevel + \localcolumnwidth\OTRSETlocalwidth\mofcolumns + \offinterlineskip + \setbox\scratchbox\vbox to \!!heighta + {%\topskipcorrection % not needed + \ifcase\OTRSETbalancemethod + % no + \or + % yes + \doifelselayerdata{OTRTEXT}\vfill\relax % temp hack + \or + % top + \or + % bottom + \vfill + \fi + \dorecurse\columnmaxcells + {\setbox\scratchbox\hbox{\OTRSETgetgridcell\mofcolumns\recurselevel}% + \ht\scratchbox\strutht + \dp\scratchbox\strutdp + \ifcase\columndirection + \box\scratchbox + \else + \hbox to \localcolumnwidth + {\hskip\localcolumnwidth\llap{\box\scratchbox}}% + \fi + \par}% + \ifcase\OTRSETbalancemethod + % no + \else + % yes, top, bottom + \ifdim\globalbodyfontsize=\localbodyfontsize + \removedepth + \restoreglobalbodyfont + \vskip\strutdepth + \fi + \kern\zeropoint + \vss + \fi}% + \wd\scratchbox\localcolumnwidth % \textwidth + \ifcase\columndirection + \hskip\OTRSETgetparameter\c!distance\recurselevel\box\scratchbox + \else + \box\scratchbox\hskip\OTRSETgetparameter\c!distance\recurselevel + \fi}}% + \egroup} + +\let\OTRSETbalht\zeropoint + +\def\OTRSETreducegridbox % for the moment no difference between methods + {\globallet\OTRSETbalht\zeropoint + \ifcase\OTRSETbalancemethod + % no balancing + \else + \bgroup + \!!counta\columnmaxcells + \donetrue + \doloop + {\dorecurse\nofcolumns{\OTRSETdoifcellelse\recurselevel\!!counta\donefalse\donothing}% + \ifdone + \ifnum\!!counta>\plusone\advance\!!counta\minusone\else\exitloop\fi + \else + \exitloop + \fi}% + \ifnum\!!counta>\plusone + \!!heighta\lineheight + \multiply\!!heighta \!!counta + \advance\!!heighta \topskip + \advance\!!heighta -\lineheight + \else + \!!heighta\zeropoint + \fi + \xdef\OTRSETbalht{\the\!!heighta}% + \egroup + \fi} + +\def\OTRSETflushfinalfootnotes + {\ifcase\lastcolumnlastcell \else + \setbox\scratchbox\hbox + {\placebottomnotes}% + \ifdim\ht\scratchbox>\zeropoint + \setbox\scratchbox\hbox + {\hbox to \zeropoint{\OTRSETgetgridcell\nofcolumns\lastcolumnlastcell}% + \box\scratchbox}% + \ht\scratchbox\strutht + \dp\scratchbox\strutdp + \OTRSETsetgridcell\nofcolumns\lastcolumnlastcell\box\scratchbox + \fi + \global\lastcolumnlastcell\zerocount + \fi} + +\def\OTRSETdoflush + {\ifcollectingcontent + \registerOTRSETmarks + \global\mofcolumns\plusone + \else + \OTRSETdofinalflush + \OTRSETdofinaloutput + \ifnum\columnsetpage>0 + \dorecurse\nofcolumns{\doresetcolumnsetlines\recurselevel}% + \fi + \doglobal\increment\columnsetpage + \OTRSETinitializecolumns + %\OTRSETdoflushfloats + \OTRSETstartnextpage +\presetOTRSETmarks + \initializecolumntextareas + \fi} + +\newbox\OTRfinalpagebox + +\def\OTRSETdofinalflush % see \OTRSETdoflush + {\OTRSETflushfinalfootnotes + \placecolumntextareas + \OTRSETcentergridcells + \bgroup % we want to keep the reduction local + \OTRSETreducegridbox + \global\setbox\OTRfinalpagebox\OTRSETmakegridbox + \egroup % otherwise we get the wrong number of free cells + %\gdef\localcolumnmaxcells{0}% here ? + \global\mofcolumns\nofcolumns} % otherwise problems in finaloutput + +\def\OTRSETdofinaloutput + {\ifdim\ht\OTRfinalpagebox=\textheight + \bgroup % \let\OTRSETsetvsize\relax % prevents useless search for gap + \ifcase\OTRSETbalancemethod + \finaloutput\box\OTRfinalpagebox + \else\ifdim\OTRSETbalht>\zeropoint + % catch a bordercase + \scratchdimen\OTRSETbalht + \advance\scratchdimen\lineheight\relax + \ifdim\scratchdimen>\textheight + % full page + \finaloutput\box\OTRfinalpagebox + \else + % same page + \global\setbox\OTRfinalpagebox \iftracecolumnset\ruledvbox\else\vbox\fi to \OTRSETbalht + {\box\OTRfinalpagebox\vss}% + \setlayer[OTRTEXT]{\box\OTRfinalpagebox}% + \snaptogrid\vbox{\vskip\OTRSETbalht}% hack + \fi + \else + \finaloutput\box\OTRfinalpagebox + \fi \fi + \globallet\OTRSETbalht\zeropoint + \egroup + \fi} + +\definesystemvariable {mc} +\definesystemvariable {mt} +\definesystemconstant {colset} + +\definetwopasslist\s!colset + +\newdimen \OTRSETtextswidth +\newdimen \OTRSETtextsheight +\let \OTRSETidentifier=\empty + +\newtoks \OTRSEToutput + +\def\OTRSETgetparameter#1#2{\csname\??mc\OTRSETidentifier\number#2#1\endcsname} +\def\OTRSETsetparameter#1#2{\setvalue{\??mc\OTRSETidentifier\number#2#1}} + +\def\OTRSETskipstart + {\scratchcounter\executeifdefined{\??mc\OTRSETidentifier\c!start}\zerocount + \relax % needed ! + \ifcase\scratchcounter\else + \advance\scratchcounter\plusone + \doOTRSETsetgridcells + {\copy\placeholderboxe} + \plusone\plusone\nofcolumns\scratchcounter + \null + \fi} + +\def\OTRSETsetvsize % snap per sectie (gap here?) + {\ifcollectingcontent \else % can be assigndimen +\OTRSETskipstart % not that well tested + \OTRSETcheckinsert % added + \OTRSETsetfreecells\mofcolumns\columnfirstcell + \ifsomefreecolumncells + \global\vsize\columnfreecells\lineheight + \ifinotr % else problems with floats, see extreme + \global\pagegoal\vsize % niet nodig, tenzij binnen otr + \fi + \synchronizeoutput % fails on example + % \allowbreak % hm + \fi + \synchronizenotes + \fi} + +\def\OTRSETsethsize % of course this does not migrate outside the otr + {\localcolumnwidth\OTRSETlocalwidth\mofcolumns + \textwidth\localcolumnwidth + \hsize\localcolumnwidth} + +\def\OTRSETsynchronizehsize + {\ifcase0\getvalue{\??mc\??mc\c!width}\else % some width set + \bgroup + \scratchdimen\OTRSETlocalwidth\mofcolumns + \ifdim\scratchdimen=\textwidth + \egroup + \else + % only if change in width and \column/\break + \egroup \OTRSETsethsize + \fi + \fi} + +\def\OTRSETcheckfreelines + {\OTRSETsetvsize} + +\def\doOTRSETcolumnseparator + {\hbox to \zeropoint{\hss\red\vl\hss}} + +\let\OTRSETcolumnseparator\relax + +\def\showbreaks + {\let\OTRSETcolumnseparator\doOTRSETcolumnseparator} + +% \installcolumnbreakhandler {SET} \v!ja +% {% hmmm: +% \ifhmode +% \bgroup +% \removeunwantedspaces +% \parfillskip\zeropoint +% \OTRSETcolumnseparator +% \par +% \egroup +% \fi +% % brrr: +% \ejectinsert +% \ejectpage +% \OTRSETsynchronizehsize} % no \OTRSETsethsize, can be mid smaller (like tabulate) +% +% \installcolumnbreakhandler {SET} \v!forceer +% {\OTRSETgotocolumn[\v!forceer]} +% \installcolumnbreakhandler {SET} \v!eerste +% {\OTRSETgotocolumn[\v!eerste]} +% \installcolumnbreakhandler {SET} \v!laatste +% {\OTRSETgotocolumn[\v!laatste]} +% +% \installcolumnbreakhandler {SET} \v!pagina +% {\simplepagebreak % \flushnotes \executepagebreakhandler\v!ja +% \ifnum\mofcolumns>\plusone +% \OTRSETgotocolumn[\v!laatste,\v!forceer]% +% \fi} + +\def\OTRSETcolumnhbreak + {\ifhmode + \bgroup + \removeunwantedspaces + \parfillskip\zeropoint + \OTRSETcolumnseparator + \par + \egroup + \fi} + +\installcolumnbreakhandler {SET} \v!local + {\OTRSETcolumnhbreak + \ejectinsert + \ejectpage % brrr + % no \OTRSETsethsize, can be mid smaller (like tabulate) + % also, this one should be executed at the outer level + % (setting hsize inside otr does not work) + \OTRSETsynchronizehsize} + +% We need to make sure that we really leave the column; mid +% column we may end up in an empty gap, and we don't want to +% stay there (basically such a gap is a small empty page +% then). + +\installcolumnbreakhandler {SET} \v!yes + {\OTRSETcolumnhbreak + \edef\savedmofcolumns{\the\mofcolumns}% + \edef\savedrealpageno{\the\realpageno}% + \ejectinsert + \ejectpage % brrr + \doloop + {\ifnum\savedmofcolumns=\mofcolumns + \ifnum\savedrealpageno=\realpageno + \OTRSETdummycolumn + \else + \exitloop + \fi + \else + \exitloop + \fi}% + \OTRSETsynchronizehsize} + +\installcolumnbreakhandler {SET} \s!unknown + {\expanded{\OTRSETgotocolumn[\@@columnspecification]}} + +\installcolumnbreakhandler {SET} \v!page + {\vfill\eject % \doejectpage\eject + \OTRSETgotonextpage} + +\newtoks\OTRSETeverystartofcolumn + +\newbox\OTRSETsavedfootnotes + +% \installoutput\OTRSETflushtextsofar % spacing goes wrong + +%\def\OTRSETflushtextsofar +% {\ifvoid\normalpagebox \else +% \setbox\scratchbox\vbox{\unvbox\normalpagebox}% +% \OTRSETsavenotes +% \OTRSEThandleflushedtext0 +% \fi} + +% The complication is in the fact that when the HERE float +% is placed, the otr is not invoked when there is not yet +% enough content; this can lead to a change in order (turning +% on the tracer with option 0 is very instructive, watch the +% small numbers in the margin) +% +% 0 = no flushing, so no interference but user should handle +% border cases of placement +% 1 = the normal otr, rather untested +% 2 = a solution that works ok, is experimental and above +% all messy + +\chardef\OTRSETflushtextmode=0 + +\def\OTRSETflushtextsofar + {\ifcase\OTRSETflushtextmode + % don't mess around + \or + % the normal one + \ifvoid\normalpagebox\else + \OTRSETnaturalflush + \OTRSETcheckfreelines + \fi + \or + % way to complicated, but kind of ok + \doOTRSETflushtextsofar + \fi} + +\newskip\lastskipinotr + +\installoutput\doOTRSETflushtextsofar % experimental + {\ifvoid\normalpagebox\else + \scratchdimen\dp\normalpagebox + \setbox\scratchbox\vbox + {\forgetall + \unvbox\normalpagebox + \global\lastskipinotr\lastskip\relax + \ifdim\lastskipinotr>\zeropoint\relax + \removelastskip + \else + \kern-\scratchdimen % handle depth + \fi}% + \ifdim\lastskipinotr>\zeropoint + \scratchskip\ht\scratchbox + \setbox\scratchbox\hbox + {\lower\strutdepth\box\scratchbox}% + \dp\scratchbox\scratchdimen + \ht\scratchbox\scratchskip + \fi + \OTRSETsavenotes + \OTRSEThandleflushedtext\zerocount + \ifdim\lastskipinotr>\zeropoint + %\vskip \lastskipinotr % hm, gets lost anyway + \else + % we should not discard skips after here; tricky + \fi + \OTRSETsetvsize + \fi} + +\def\OTRSETplacebottomnotes + {\iflastcolumnfootnotes + \ifnum\nofcolumns=\mofcolumns + \ifintermediatefootnotes \placebottomnotes \fi + \fi + \else + \placebottomnotes + \fi} + +\def\OTRSETflushsavednotes + {\iflastcolumnfootnotes + \ifnum\nofcolumns=\mofcolumns + \flushsavednotes + \fi + \else + \flushsavednotes + \fi} + +\def\OTRSETsavenotes + {\iflastcolumnfootnotes + \ifnum\nofcolumns=\mofcolumns \else + \savenotes + \fi + \fi} + +\appendtoks \OTRSETflushsavednotes \to \OTRSETeverystartofcolumn + +\def\OTRSETnaturalflush + {\bgroup + \forgetall % new, needed ! + \setbox0\vbox to \columnfreecells\lineheight + {\vskip-\topskip + \vskip\lineheight + \prevdepth\strutdp + \unvbox\normalpagebox + \vfill}% + \setbox2\hbox + {\OTRSETplacebottomnotes}% + \setbox\scratchbox\hbox + {\wd0\zeropoint\box0\box2}% + \dp\scratchbox\strutdp + \OTRSEThandleflushedtext\plusone + \egroup} + +\newcount\lastcolumnlastcell + +\def\OTRSEThandleflushedtext#1% + {\getnoflines{\ht\scratchbox}% + %\wd\scratchbox\textwidth % geen \hsize kan < zijn in bv split tabulate + \wd\scratchbox\OTRSETlocalwidth\mofcolumns + \doOTRSETsetgridcells + {\copy\placeholderboxf} + \mofcolumns\columnfirstcell\plusone\noflines + {\registeredtextarea1\columnfirstcell\scratchbox}% == \hbox / tricky htcorr == \columnfirstcell + \global\columnlastcell\columnfirstcell + \global\advance\columnlastcell \noflines + \global\lastcolumnlastcell\columnlastcell + \global\advance\lastcolumnlastcell \minusone + % find next (acceptable) gap, todo: deadcycle + \ifcase#1\else + \OTRSETfillgapsbetweencells\mofcolumns\columnlastcell + \fi + \OTRSETfindnextgap + % \message{\the\mofcolumns,\the\columnfirstcell,\the\columnfreecells}% + % \wait + % we cannot adapt the hsize since it may have changed (like + % inside a tabulate) so we only change it when there is a + % reason to do so + \OTRSETsynchronizehsize + \OTRSETsetvsize} + +\def\OTRSETfindnextgap + {\OTRSETsetfreecells\mofcolumns\columnlastcell + \ifsomefreecolumncells + % okay + \bubbleOTRSETmarks % not robust because we reenter + \else + \registerOTRSETmarks % not robust because we reenter + \global\advance\mofcolumns \plusone + \ifnum\mofcolumns>\nofcolumns + \OTRSETdoflush + \global\columnlastcell\plusone + \global\columnfirstcell\zerocount + \OTRSETdoflushfloats + \else + \the\OTRSETeverystartofcolumn + \global\columnlastcell\plusone + \global\columnfirstcell\zerocount + \fi + \fi} + +\let\OTRSETcheckfreelines\donothing + +\def\OTRSETfillgapsbetweencells#1#2% col + {\ifnum\columngaplimit>\zerocount + \donefalse + \dostepwiserecurse{#2}\columnmaxcells\plusone + {\OTRSETdoifcellelse{#1}\recurselevel + {\ifdone + \!!countb\recurselevel \advance\!!countb -\!!counta\relax + \ifnum\!!countb>\plusone + \advance\!!countb \minusone + \ifnum\!!countb<\columngaplimit\relax + \!!countb\recurselevel \advance\!!countb \minusone + \dostepwiserecurse\!!counta\!!countb\plusone + {\OTRSETsetgridcell{#1}\recurselevel\copy\placeholderboxc}% + %\message{[gap]}% + \fi + \fi + \fi + \donefalse} + {\ifdone \else + \donetrue + \!!counta\recurselevel + \fi}}% + \fi} + +\appendtoks + \OTRSETfillgapsbetweencells\mofcolumns\plusone +\to \OTRSETeverystartofcolumn + +\newif\ifspancolumnslots \spancolumnslotstrue +\newif\ifcheckcolumnspan \checkcolumnspantrue + +\def\OTRSETcheckwidthgap#1#2% box size + {\ifcheckcolumnspan + \bgroup + \scratchdimen#2% + \advance\scratchdimen-\wd#1\relax + \ifdim-10\scaledpoint>\scratchdimen + \egroup + \else\ifdim10\scaledpoint<\scratchdimen + \egroup + \else + \egroup + \wd#1=#2% + \fi\fi + \fi} + +\def\OTRSETcheckcolumnslot#1% + {\enoughcolumncellstrue + \ifspancolumnslots\else + \OTRSETcheckwidthgap#1\hsize + \ifdim\wd#1>\hsize + \enoughcolumncellsfalse + \fi + \fi + \ifenoughcolumncells + \getnoflines\pagetotal + \scratchcounter\noflines + \getnoflines{\ht#1}% + \columnvcells\noflines + \columnhcells\plusone + \advance\scratchcounter \columnvcells \relax + \ifnum\scratchcounter>\columnfreecells + \enoughcolumncellsfalse + \fi + \fi} + +\def\OTRSETstoreincolumnslotPAGE#1% + {\ifenoughcolumncells + % to do + \OTRSETsavebox{#1}% + \else + \OTRSETsavebox{#1}% + \fi} + +\def\OTRSETstoreincolumnslotTOPS#1% + {\OTRSETprepareforcolumnslot1{#1}% + \OTRSETcheckcolumnslot{#1}% + \ifenoughcolumncells + \OTRSETcheckcolumnspace\mofcolumns\columnfirstcell{#1}% + \fi + \ifenoughcolumncells + \OTRSETsetgridcells\mofcolumns\columnfirstcell\columnhcells\columnvcells + {\hbox{\copy#1}}% + \OTRSETsetvsize + \else + \OTRSETsavebox{#1}% + \fi} + +\def\OTRSETstoreincolumnslotBOTS#1% + {\OTRSETprepareforcolumnslot3{#1}% + \edef\savedcolumnlastcell{\the\columnlastcell}% + \OTRSETcheckcolumnslot{#1}% + \ifenoughcolumncells + \advance\columnlastcell -\columnvcells \advance\columnlastcell \plusone +% \OTRSETcheckcolumnspace\mofcolumns\columnfirstcell{#1}% + \OTRSETcheckcolumnspace\mofcolumns\columnlastcell{#1}% + \fi + \ifenoughcolumncells + \OTRSETsetgridcells\mofcolumns\columnlastcell\columnhcells\columnvcells{\copy#1}% + \OTRSETfillgapsbetweencells\mofcolumns\savedcolumnlastcell % -) + \OTRSETsetvsize + \else + \columnlastcell\savedcolumnlastcell + \OTRSETsavebox{#1}% + \fi} + +\newdimen\totalcolumnspace + +\def\columnspacetopoffset{0} +\def\columnspacebotoffset{0} + +\def\OTRSETcheckcolumnspace#1#2#3% col row box + {\columnhcells\plusone + \totalcolumnspace\zeropoint + \scratchcounter#1% + \enoughcolumncellstrue + \doloop + {\advance\totalcolumnspace \OTRSETlocalwidth\scratchcounter\relax % needed +\OTRSETcheckwidthgap#3\totalcolumnspace + \ifnum\wd#3>\totalcolumnspace\relax + \ifnum\scratchcounter=\nofcolumns + \enoughcolumncellsfalse + \exitloop + \else + \advance\columnhcells \plusone + \advance\scratchcounter \plusone + \advance\totalcolumnspace \OTRSETgetparameter\c!distance\scratchcounter + \fi + \else + \exitloop + \fi}% + \ifenoughcolumncells + \getnoflines{\ht#3}% + \columnvcells\noflines + \OTRSETcheckcolumncells{#1}{#2}\columnhcells\columnvcells + \fi} + +\def\OTRSETcheckcolumncells#1#2#3#4% col row wid hei + {\!!countd#1\advance\!!countd#3\advance\!!countd\minusone + \!!counte#2\advance\!!counte#4\advance\!!counte\minusone + \ifnum\!!counte>\columnmaxcells\relax + \enoughcolumncellsfalse + \else + \enoughcolumncellstrue +%\let\columnspacetopoffset\zerocount +%\scratchcounter#2\advance\scratchcounter\minusone +%\ifnum\scratchcounter>0 +% \dostepwiserecurse{#1}\!!countd\plusone +% {\ifdim\wd\OTRSETgridcell\recurselevel\scratchcounter>\zeropoint +% \let\columnspacetopoffset\plusone +% \else\ifdim\dp\OTRSETgridcell\recurselevel\scratchcounter>\zeropoint +% \let\columnspacetopoffset\plusone +% \fi\fi}% +% \advance\!!counte \columnspacetopoffset \relax +% \advance\columnvcells \columnspacetopoffset \relax +%\fi +%\let\columnspacebotoffset\zerocount +%\scratchcounter\!!counte +%\advance\scratchcounter \columnvcells \relax +%\ifnum\scratchcounter>\columnmaxcells\else +% \dostepwiserecurse{#1}\!!countd\plusone +% {\ifdim\wd\OTRSETgridcell\recurselevel\scratchcounter>\zeropoint +% \let\columnspacebotoffset\plusone +% \else\ifdim\dp\OTRSETgridcell\recurselevel\scratchcounter>\zeropoint +% \let\columnspacebotoffset\plusone +% \fi\fi}% +% \advance\!!counte \columnspacebotoffset \relax +% \advance\columnvcells \columnspacebotoffset \relax +%\fi + \dostepwiserecurse{#1}\!!countd\plusone % cols + {\ifenoughcolumncells + \!!countf\recurselevel\relax + \dostepwiserecurse{#2}\!!counte\plusone % rows + {\ifenoughcolumncells + \OTRSETdoifcellelse\!!countf\recurselevel + {\enoughcolumncellsfalse}{}% + \fi}% + \fi}% + \fi} + +\def\OTRSETsetpreferedcolumnslot#1#2% + {\doifsomething{#1}{\edef\preferedcolumn{#1}}% + \doifsomething{#2}{\edef\preferedrow {#2}}} + +\OTRSETsetpreferedcolumnslot{\nofcolumns}{1} % default ? + +\let\pofcolumns\mofcolumns +\let\qofcolumns\mofcolumns + +\newif\ifquitincurrentcolumn + +\def\OTRSETstoreincolumnslotLRTB#1% + {\OTRSETprepareforcolumnslot1{#1}% + \OTRSETflushtextsofar + \OTRSETstoreincolumnslotindeed + \mofcolumns\nofcolumns+\currenthcell + \plusone\columnmaxcells+\currentvcell{#1}} + +\def\OTRSETstoreincolumnslotLRBT#1% + {\OTRSETprepareforcolumnslot3{#1}% + \OTRSETflushtextsofar + \OTRSETstoreincolumnslotindeed + \mofcolumns\nofcolumns+\currenthcell + \columnmaxcells\plusone-\currentvcell{#1}} + +\def\OTRSETstoreincolumnslotRLTB#1% + {\OTRSETprepareforcolumnslot1{#1}% + \OTRSETflushtextsofar + \OTRSETcheckprefered + \OTRSETstoreincolumnslotindeed + \nofcolumns\qofcolumns-\currenthcell + \plusone\columnmaxcells+\currentvcell{#1}} + +\def\OTRSETstoreincolumnslotRLBT#1% + {\OTRSETprepareforcolumnslot3{#1}% + \OTRSETflushtextsofar + \OTRSETcheckprefered + \OTRSETstoreincolumnslotindeed + \nofcolumns\qofcolumns-\currenthcell + \columnmaxcells\plusone-\currentvcell{#1}} + +\def\OTRSETstoreincolumnslotTBLR#1% + {\OTRSETprepareforcolumnslot1{#1}% + \OTRSETflushtextsofar + \OTRSETstoreincolumnslotindeed + \plusone\columnmaxcells+\currentvcell + \mofcolumns\nofcolumns+\currenthcell{#1}} + +\def\OTRSETstoreincolumnslotTBRL#1% + {\OTRSETprepareforcolumnslot1{#1}% + \OTRSETflushtextsofar + \OTRSETcheckprefered + \OTRSETstoreincolumnslotindeed + \plusone\columnmaxcells+\currentvcell + \nofcolumns\qofcolumns-\currenthcell{#1}} + +\def\OTRSETstoreincolumnslotBTLR#1% + {\OTRSETprepareforcolumnslot3{#1}% + \OTRSETflushtextsofar + \OTRSETstoreincolumnslotindeed + \columnmaxcells\plusone-\currentvcell + \mofcolumns\nofcolumns+\currenthcell{#1}} + +\def\OTRSETstoreincolumnslotBTRL#1% + {\OTRSETprepareforcolumnslot3{#1}% + \OTRSETflushtextsofar + \OTRSETcheckprefered + \OTRSETstoreincolumnslotindeed + \columnmaxcells\plusone-\currentvcell + \nofcolumns\qofcolumns-\currenthcell{#1}} + +\def\OTRSETstoreincolumnslotFXTB#1% fixed column + {\OTRSETcheckprefered + \OTRSETdoifcellelse\pofcolumns\plusone + {\OTRSETprepareforcolumnslot2}{\OTRSETprepareforcolumnslot1}{#1}% % 1/2 dependent of place, todo + \OTRSETflushtextsofar + \OTRSETstoreincolumnslotindeed + \pofcolumns \pofcolumns +\currenthcell + \preferedrow\columnmaxcells+\currentvcell{#1}} + +\def\OTRSETstoreincolumnslotFXBT#1% fixed column + {\OTRSETcheckprefered + \OTRSETdoifcellelse\pofcolumns\columnmaxcells + {\OTRSETprepareforcolumnslot2}{\OTRSETprepareforcolumnslot3}{#1}% % 3/2 dependent of place, todo + \OTRSETflushtextsofar + \OTRSETstoreincolumnslotindeed + \pofcolumns \pofcolumns +\currenthcell + \columnmaxcells\preferedrow-\currentvcell{#1}} + +\chardef\OTRSETforcefixedfloats=0 + +\def\OTRSETstoreincolumnslotHERE#1% fixed column + {\ifcase\OTRSETforcefixedfloats + \OTRSETstoreincolumnslotSOMEWHERE2{#1}% + \else + \OTRSETstoreincolumnslotFIXD{#1}% + \fi} + +% this one looses too wide graphics +% +% \def\OTRSETstoreincolumnslotFIXD#1% fixed column +% {\OTRSETprepareforcolumnslot2{#1}% +% % no flush text sofar here, beware: no width test +% \snaptogrid\vbox{\box#1}} +% +% still imperfect + +\def\OTRSETstoreincolumnslotFIXD#1% fixed column + {\OTRSETflushtextsofar + \ifdim\wd#1>\textwidth + \OTRSETstoreincolumnslotSOMEWHERE2{#1}% + \else + % crappy test / needed for o-pbu-f / will be replaced + \getnoflines{\ht#1}% + \scratchdimen\noflines\lineheight + \advance\scratchdimen\lineheight + \advance\scratchdimen\pagetotal\relax + \ifdim\scratchdimen<\pagegoal + %OTRSETprepareforcolumnslot3{#1}% + %ruledvskip\columnslotspacing\lineheight + \blank[\columnslotspacing*\v!line]% + \snaptogrid\hbox to \hsize{\hss\box#1\hss}% strange, why the centering + \blank[\columnslotspacing*\v!line]% + \else + \OTRSETstoreincolumnslotSOMEWHERE2{#1}% + \fi + \fi} + +\def\OTRSETstoreincolumnslotSOMEWHERE#1#2% + {\OTRSETprepareforcolumnslot{#1}{#2}% + \OTRSETflushtextsofar + \getnoflines\pagetotal \advance\noflines\columnfirstcell + \OTRSETstoreincolumnslotindeed + \mofcolumns\mofcolumns+\currenthcell + \noflines\columnmaxcells+\currentvcell{#2}% + \OTRSETsetvsize} + +\def\OTRSETcheckprefered + {\ifnum\preferedcolumn<\mofcolumns + \let\pofcolumns\mofcolumns + \else + \let\pofcolumns\preferedcolumn + \fi + \ifquitincurrentcolumn + \ifnum\mofcolumns=\nofcolumns + \def\qofcolumns{\mofcolumns}% + \else + \scratchcounter\mofcolumns + \advance\scratchcounter \plusone + \edef\qofcolumns{\the\scratchcounter}% + \fi + \else + \let\qofcolumns\mofcolumns + \fi} + +\def\OTRSETstoreincolumnslotindeed#1#2#3#4#5#6#7#8#9% + {\OTRSETcheckprefered + \enoughcolumncellsfalse + \donefalse + \dostepwiserecurse{#1}{#2}{#31} + {\ifdone + \exitloop + \else + #4=\recurselevel + \dostepwiserecurse{#5}{#6}{#71} + {\ifdone + \exitloop + \else + #8=\recurselevel + \OTRSETcheckcolumnspace\currenthcell\currentvcell{#9}% + \ifenoughcolumncells \donetrue \fi + \fi}% + \fi}% + \ifdone + \enoughcolumncellstrue + \else + \enoughcolumncellsfalse + \fi + \ifenoughcolumncells +% \ifnum\columnspacetopoffset>0\message{[+++]}\fi +% \ifnum\columnspacebotoffset>0\message{[---]}\fi +% \OTRSETsetgridcells\currenthcell\currentvcell\columnhcells\columnvcells +% {\vbox +% {\ifcase\columnspacetopoffset\else\ruledvskip\columnspacetopoffset\lineheight\fi +% \copy#9 +% \ifcase\columnspacebotoffset\else\ruledvskip\columnspacebotoffset\lineheight\fi}}% + \OTRSETsetgridcells\currenthcell\currentvcell\columnhcells\columnvcells + {\copy#9}% + \ifnum\currenthcell=\mofcolumns\relax + \ifdim\ht\OTRSETsavedfootnotes>\zeropoint + \OTRSETsetfreecells\mofcolumns\columnfirstcell + \ifsomefreecolumncells + \getnoflines{\ht\OTRSETsavedfootnotes}\relax + \ifnum\columnfreecells<\noflines + \global\somefreecolumncellsfalse + \else + %\message{[flt]}% float + \fi + \fi + \ifsomefreecolumncells + % ok, enough room for notes + %\message{[flt]}% float + \else % ? + \OTRSETsavebox{#9}% + \OTRSETerasegridcells\currenthcell\currentvcell\columnhcells\columnvcells + %\message{[clr]}% save box + \fi + \else + %\message{[flt]}% float + \fi + \else + %\message{[flt]}% float + \fi + \OTRSETsetvsize + %\message{[fnt]}% float + \else + %\message{[rej]}% save box + \OTRSETsavebox{#9}% + \fi} + +\chardef\columnslotspacing \plusone + +\def\OTRSETstoreincolumnslot#1% #2 % {method} {box} % alleen last + {% no messing around here + % \dp#2=\zeropoint + % \ifcase\columnslotspacing\else + % \setbox#2=\vbox spread \columnslotspacing\lineheight + % {\vss\box#2\vss}% + % \fi + % and don't change this any more +% \doifdefinedelse{\strippedcsname\OTRSETstoreincolumnslot#1} +% {\getvalue{\strippedcsname\OTRSETstoreincolumnslot#1}{#2}} +% {\OTRSETstoreincolumnslotUNKNOWN{#2}}} + \executeifdefined{\strippedcsname\OTRSETstoreincolumnslot#1} + \OTRSETstoreincolumnslotUNKNOWN} % {#2}} + +\def\OTRSETstoreincolumnslotUNKNOWN#1% + {\OTRSETprepareforcolumnslot2{#1}\copy#1} % {} ? + +\def\OTRSETprepareforcolumnslot#1#2% 1=hoog 2=midden 3=laag + {\dp#2\zeropoint + \ifcase\columnslotspacing\else + \scratchdimen\columnslotspacing\lineheight + \ifnum#1=2 \scratchdimen2\scratchdimen \fi + \begingroup + \advance\scratchdimen\ht#2\relax + \ifdim\scratchdimen<\columnmaxcells\lineheight + \endgroup \setbox#2\vbox spread \scratchdimen \bgroup + \else + \endgroup \setbox#2\vbox to \columnmaxcells\lineheight \bgroup + \vskip\strutdepth + \fi + \ifnum#1>1\vss\fi + \box#2\relax + \ifnum#1<3\vss\fi + \egroup + \fi} + +\def\OTRSETdocheckiffloatfits % eigenlijk moet else float anders + {\global\ifnofloatpermitted\roomforfloatfalse\else\roomforfloattrue\fi} + +\def\OTRSETunpreparebox#1% + {\ifhbox#1% spans and so + \global\setbox\floatbox\vbox{\box#1}% + \else + \setbox\scratchbox\vbox + {\unvbox#1\unskip\unskip\unskip + \global\setbox\floatbox\lastbox}% + \fi} + +% for the moment resave is still needed here + +\def\OTRSETsavebox#1% clean up the skips + {\OTRSETunpreparebox{#1}% + \dofloatssave{text}} + +\def\OTRSETresavebox#1% clean up the skips + {\OTRSETunpreparebox{#1}% + \dofloatsresave{text}} + +\def\OTRSETflushfloatbox % nog verder doorvoeren en meer info in marge + {\iftestfloatbox\ruledhbox\fi{\box\floatbox}} + +\def\OTRSETdoflushfloats + {\bgroup + \def\OTRSETsavebox##1{\!!doneafalse}% + \doloop + {\ifsomefloatwaiting + \OTRSETskipstart + \dofloatsgetinfo{text}% + \ifdim\floatwidth>\zeropoint + \!!doneatrue + \dofloatsflush{text}{1}% + \dp\floatbox\zeropoint + \OTRSETstoreincolumnslot{TBLR}\floatbox + \if!!donea + %\message{[flu]}% + \else + \OTRSETresavebox\floatbox + \exitloop + \fi + \else + %\message{[err]}% happens but why? + \fi + \else + \exitloop + \fi} + \egroup} + +\newif\ifcentergridcells \centergridcellstrue + +\newif\ifcentergridcellonly \centergridcellonlyfalse +\newif\ifautocentergridcellonly \autocentergridcellonlytrue + +\def\OTRSETcentergridcells + {\ifcentergridcells + \dorecurse\nofcolumns + {\currenthcell\recurselevel + \ifautocentergridcellonly + % we prevent centering when the next column is empty + % to be checked ! ! ! ! + \advance\currenthcell \plusone + \centergridcellonlytrue + \ifnum\currenthcell>\nofcolumns + % ok already + \else + % only span if there is a next column with content + \dorecurse\columnmaxcells + {\ifdim\ht\OTRSETgridcell\currenthcell\currentvcell>\zeropoint + \centergridcellonlyfalse + \else\ifdim\dp\OTRSETgridcell\currenthcell\currentvcell>\zeropoint + \centergridcellonlyfalse + \fi\fi}% + \fi + \fi + \currenthcell\recurselevel + \dorecurse\columnmaxcells + {\currentvcell\recurselevel\relax + \ifdim\ht\OTRSETgridcell\currenthcell\currentvcell>\zeropoint + \ifdim\dp\OTRSETgridcell\currenthcell\currentvcell=\zeropoint + \bgroup + \setbox\scratchbox\OTRSETgetgridcell\currenthcell\currentvcell + \getnoflines{\ht\scratchbox}% + \!!counta\currentvcell + \advance\!!counta -\noflines + \advance\!!counta \plusone + % first col always ok + \!!countb\currenthcell + \!!countc\currenthcell + \advance\!!countc \plusone + \!!donebtrue + \ifcentergridcellonly + \!!countc\maxdimen + \fi + \dostepwiserecurse\!!countc\nofcolumns\plusone + {\if!!doneb + \let\xrecurselevel\recurselevel + \dostepwiserecurse\!!counta\currentvcell\plusone + {\ifdim\ht\OTRSETgridcell\xrecurselevel\recurselevel>\zeropoint + \!!donebfalse + \else\ifdim\wd\OTRSETgridcell\xrecurselevel\recurselevel>\zeropoint + \!!donebfalse + \fi\fi}% + \if!!doneb + \!!countb\xrecurselevel + \fi + \fi}% + \totalcolumnspace\OTRSETlocalwidth\currenthcell + \dostepwiserecurse\!!countc\!!countb\plusone + {\advance\totalcolumnspace \OTRSETlocalwidth\recurselevel + \advance\totalcolumnspace \OTRSETgetparameter\c!distance\recurselevel}% + \ifdim\totalcolumnspace>\wd\scratchbox + \setbox\scratchbox\hbox to \totalcolumnspace{\hss\box\scratchbox\hss}% + \fi + \OTRSETsetgridcell\currenthcell\currentvcell\box\scratchbox + \egroup + \fi + \fi}}% + \fi} + +\def\OTRSETinitializecolumns% once per page + {\columnspreadtrue % todo + \ifcolumnspread + \global\rofcolumns\getvalue{\??mc\OTRSETidentifier\c!nright}% + \global\lofcolumns\getvalue{\??mc\OTRSETidentifier\c!nleft}% + \global\tofcolumns\rofcolumns \relax + \ifodd\realpageno\relax + \global\nofcolumns\rofcolumns + \else + \global\advance\tofcolumns\lofcolumns + \global\nofcolumns\lofcolumns + \fi + \else + \global\nofcolumns\getvalue{\??mc\OTRSETidentifier\c!n}% + \global\rofcolumns\nofcolumns + \global\lofcolumns\nofcolumns + \global\tofcolumns\nofcolumns + \fi + \OTRSETassignwidths + \global\mofcolumns\plusone + \columnerasegridboxes} + +% vanaf hier: + +\unexpanded\def\definecolumnset + {\dodoubleargument\dodefinecolumnset} + +\def\dodefinecolumnset[#1][#2]% + {\getparameters[\??mc#1] + [\c!direction=\v!right, + \c!balance=\v!no, + \c!distance=1.5\bodyfontsize, % controleren + \c!n=2, + \c!nleft=\getvalue{\??mc#1\c!n}, + \c!nright=\getvalue{\??mc#1\c!n}, + \c!width=\v!fit, + \c!lines=0, + \c!start=0, + #2]% + \dorecurse{\getvalue{\??mc#1\c!nleft}} % todo + {\dododefinecolumnset[#1][\recurselevel]}% + \dorecurse{\getvalue{\??mc#1\c!nright}} % todo + {\dododefinecolumnset[#1][\recurselevel]}% + % redo framed settings + \setupcolumnset[#1][1][\c!distance=\!!zeropoint]} + +\def\dododefinecolumnset[#1][#2]% + {\presetlocalframed + [\??mc#1#2]% + \setupcolumnset + [#1][#2] + [\c!offset=\v!overlay, + \c!frame=\v!off, + \c!align=, + \c!lines=0,% really needed since c!regels is now part of framed + \c!width=\getvalue{\??mc#1\c!width}, + \c!distance=\getvalue{\??mc#1\c!distance}]} + +\unexpanded\def\setupcolumnset + {\dotripleargument\dosetupcolumnset} + +\def\dosetupcolumnset[#1][#2][#3]% + {\ifthirdargument + \def\docommand##1% + {\doifelse{##1}\v!each + {\dorecurse{\getvalue{\??mc#1\c!n}}{\docommand\recurselevel}} + {\getparameters[\??mc#1##1][#3]}}% + \processcommalist[#2]\docommand + \else + \getparameters[\??mc#1][#2]% + \fi} + +\definecolumnset[\s!default][\c!n=2] % fallback + +\def\OTRSETgotonextpage + {\vfill\eject + \relax\ifnum\mofcolumns>\plusone + \OTRSETgotocolumn[\v!last]% + \ifnum\mofcolumns>\plusone + \OTRSETgotocolumn[\v!force]% + \fi + \fi} + +\let\OTRSETgotonextpageX\OTRSETgotonextpage % will become obsolete + +\def\OTRSETgotocolumn + {\dosingleempty\doOTRSETgotocolumn} + +\def\doOTRSETgotoCOLROW#1% |* + {\bgroup % really needed + \splitstring#1\at*\to\column\and\row + \bgroup + \ifx\column\empty\else\expanded{\doOTRSETgotoCOLUMN{\column}}\fi + \egroup + \bgroup + \ifx\row \empty\else\expanded{\doOTRSETgotoROW {\row }}\fi + \egroup + \egroup} + +\def\doOTRSETgotoCOLUMN#1% + {\ifnum\mofcolumns=#1\else + \vfill\eject % \doejectpage\eject + \doloop + {\ifnum\mofcolumns=#1\relax + \exitloop \else \OTRSETdummycolumn + \fi}% + \fi} + +\def\doOTRSETgotoROW#1% + {\ifnum#1>1 + \scratchcounter\zerocount + \currenthcell\mofcolumns + \currentvcell#1\advance\currentvcell \minusone + \dorecurse\currentvcell + {\OTRSETdoifcellelse\mofcolumns\recurselevel\donothing + {\advance\scratchcounter\plusone}} + \getnoflines\pagetotal + \advance\scratchcounter-\noflines + \ifnum\scratchcounter>\zerocount + \dorecurse\scratchcounter{\line{\strut}}% + \fi + \fi + \OTRSETsetvsize} + +\def\doOTRSETgotocolumn[#1]% yes|force|first|last||* + {\processallactionsinset + [#1] + [ \v!yes=>\OTRSETdummycolumn, + \v!no=>,% not supported + \v!force=>\OTRSETdummycolumn, + \v!first=>\expanded{\doOTRSETgotoCOLUMN{1}}, + \v!last=>\expanded{\doOTRSETgotoCOLUMN{\the\nofcolumns}}, + \s!default=>\OTRSETdummycolumn, + \s!unknown=>\expanded{\doOTRSETgotoCOLROW{\commalistelement}}]} + +% to be documented and tested, not yet that robust + +% \def\OTRSETgotocell#1#2% +% {\endgraf +% \gdef\gotocellcounter{0}% +% \doloop +% {\ifnum\mofcolumns<#1\relax +% \doglobal\increment\gotocellcounter\relax +% \ifnum\gotocellcounter>#1\relax +% \line{\strut}\crlf +% \line{\strut}\crlf +% \column +% \writestatus{columnset}{quitting goto cell}% +% \exitloop +% \else +% \column +% \fi +% \else +% \exitloop +% \fi}% +% \ifnum\mofcolumns=#1\relax +% \ifnum#2>1 +% \scratchcounter\zerocount +% \currenthcell\mofcolumns +% \currentvcell#2\advance\currentvcell \minusone +% \dorecurse\currentvcell +% {\OTRSETdoifcellelse\mofcolumns\recurselevel\donothing +% {\advance\scratchcounter\plusone}} +% \getnoflines\pagetotal +% \advance\scratchcounter-\noflines +% \ifnum\scratchcounter>\zerocount +% \dorecurse\scratchcounter{\line{\strut}}% +% \fi +% \fi +% \fi +% \OTRSETsetvsize} + +\def\OTRSETgotocell#1#2% obsolete: now \column[#1*#2] + {\endgraf + \doOTRSETgotoCOLUMN{#1}% + \doOTRSETgotoROW {#2}} + +\def\OTRSETdummycolumn + {\verticalstrut + \vskip-\struttotal + \vfill + \eject} + +\newcounter\columnsetlevel +\let\currentcolumnset\empty +\chardef\OTRSETfinish\zerocount + +\unexpanded\def\startcolumnset + {\dodoubleempty\dostartcolumnset} + +\def\dostartcolumnset[#1][#2]% + {\increment\columnsetlevel\relax + \globallet\localcolumnmaxcells\!!zerocount + \global\chardef\OTRSETfinish\zerocount + \resetOTRSETmarks + \ifnum\columnsetlevel=\plusone + \bgroup + \saveinterlinespace + \globallet\columnsetpage\!!plusone + \def\currentcolumnset{#2}% + \insidecolumnstrue % will be different flag in addition + \activateotr{SET}{ONE}% andere naam, activate or so + \doifelsenothing{#1} + {\globallet\OTRSETlist\s!default} + {\xdef\OTRSETlist{#1}}% + \OTRSETstartnextpage + \OTRSETassignwidths + \OTRSETsethsize + \else + \bgroup + \fi} + +% \setuplayout[grid=yes] \definecolumnset[example] \showgrid + +% \starttext +% \startcolumnset[example] +% \input knuth \endgraf \input knuth +% \placetable{table}{\framed[width=\makeupwidth,height=4cm]{Hello}} +% \input knuth \endgraf \input knuth +% \stopcolumnset +% \input knuth \endgraf \input knuth +% \stoptext + +\def\OTRSETflushleftovers % new per 13/4/2006 + {\OTRSETdoifcellelse{1}{1} + {\bgroup + \OTRSETcentergridcells + \chardef\OTRSETbalancemethod\plusone + \OTRSETreducegridbox + \global\setbox\OTRfinalpagebox\OTRSETmakegridbox + \global\ht\OTRfinalpagebox\textheight % signals output that there is content + \OTRSETdofinaloutput + \globallet\OTRSETbalht\zeropoint + \egroup} + {}} + +\unexpanded\def\stopcolumnset + {\relax + \ifnum\columnsetlevel=\plusone + \endgraf % needed, else wrong vsize in one par case + \global\chardef\OTRSETfinish\plusone + % no, extra page \pagebreak % (test on pascal toc) + \dostopcolumnset + \egroup + \global\notelimittrue % brrr, untested and fuzzy + \setvsize + \sethsize + \ifvoid\OTRfinalpagebox\else + % probably balanced + \ifdim\ht\OTRfinalpagebox<\textheight + \snaptogrid[\v!page]\hbox{\box\OTRfinalpagebox}% + \else + \box\OTRfinalpagebox + \fi + \fi + \global\chardef\OTRSETfinish\zerocount + \ifsomefloatwaiting \setvsize \pagebreak \setvsize \fi + \OTRSETflushleftovers + \else + \egroup + \fi + \decrement\columnsetlevel\relax} + +\chardef\OTRSETbalancemethod\zerocount + +\def\dostopcolumnset + {%\OTRSETdofinalflushfloats % yes/no + \ifcase\OTRSETbalancemethod + \OTRSETnobalance + \else + \OTRSETdobalance + \fi} + +\def\OTRSETdobalance + {\OTRSETnobalance} + +\def\localcolumnmaxcells{0} + +% currently line represents real line, i.e. on the grid, and +% not something noflines (also, watch out for switching from +% 2-3 columns on one page with both sets balanced: the +% second set does not see the first set + +% don't loose empty 1page/1column with area (example **) +% +% \definecolumntextarea[title][x=1,y=4,nx=2,ny=7,state=start] +% \setupcolumntextareatext[title][\vtop to 5cm{a\\b\\b\\d}] +% +% \starttext +% \startcolumnset \dorecurse{1}{\input tufte \par} \stopcolumnset +% \stoptext + +% better: + +\unexpanded\def\definecolumnsetarea {\definecolumntextarea} +\unexpanded\def\setupcolumnsetarea {\setupcolumntextarea} +\unexpanded\def\setupcolumnsetareatext{\setupcolumntextareatext} + +% so this will be changed + +\def\OTRSETnobalance + {\iflastcolumnfootnotes % testen ! optie + % inhibit flush of floats ! + % todo: nothing if no footnotes, else empty page + \dostepwiserecurse\mofcolumns\nofcolumns\plusone + {\vskip-\struttotal\verticalstrut\vfill\eject}% + \else + \ifnum\mofcolumns>\plusone + \donetrue + \else\ifdim\pagetotal>\zeropoint % too dangerous, we loose data + \donetrue + \else + \donefalse + \fi\fi + \ifdone + \ifnum\mofcolumns=\nofcolumns + \OTRSETflushfinalfootnotes + \else + % probably todo + \fi + \vfill + \eject +\registerOTRSETmarks + % brr, may result in empty page after nicely fit text + % or if left, then lost of first column only text + \ifnum\mofcolumns>\plusone + \OTRSETdofinalflush + \OTRSETdofinaloutput + \fi + \fi + \fi} + +\def\OTRSETstartnextpage + {\doifsomething\OTRSETlist + {\getfromcommacommand[\OTRSETlist][1]% + \global\let\OTRSETidentifier\commalistelement + \doifundefined{\??mc\OTRSETidentifier\c!n} + {\globallet\OTRSETidentifier\s!default}% + \let\newcommalistelement\empty + \doglobal\replaceincommalist\OTRSETlist1% + \OTRSETrestart}} + +\def\OTRSETrestart % weed + {\OTRSETinitializefeatures + \OTRSETflushpreposttext + \OTRSETinitializecolumns + \OTRSETcheckinsert + \OTRSETcheckgrid + \OTRSETsetvsize + \OTRSETsethsize % or local ? + \OTRSETsetplaceholders + \OTRSEThandlepreposttext + \initializecolumntextareas % name ! + \OTRSETcheckstartcells + \OTRSETsetvsize} + +\def\OTRSETcheckstartcells + {\dorecurse\nofcolumns + {\bgroup + \mofcolumns\recurselevel +\OTRSETsetcorrectnofcells\currentcolumnstartcell +\advance\scratchcounter \minusone + \dorecurse\scratchcounter + {\OTRSETdoifcellelse\mofcolumns\recurselevel + \donothing{\OTRSETsetgridcell\mofcolumns\recurselevel\copy\placeholderboxe}}% + \egroup}} + +\OTRSEToutput + {\dontcomplain % new, get rid of overfull message (to be sorted out) + \doloop + {\OTRSETnaturalflush + %\OTRSETstartnextpage % no + \OTRSETdoflushfloats % actually belongs in \flushsavedfloats (but goes wrong) + \OTRSETcheckfreelines + \ifsomefreecolumncells + \exitloop + \else + % flush page and get rid of more floats if present + \fi}% + \OTRSETchecksidefloat} + +\def\OTRSETinitializefeatures + {% number of lines + % new: raw + \getrawnoflines\textheight\xdef\columnmaxcells{\the\noflines}% + % direction + \doifelsevalue{\??mc\OTRSETidentifier\c!direction}\v!right + {\chardef\columndirection\zerocount} + {\chardef\columndirection\plusone}% + % balancing + \chardef\OTRSETbalancemethod\zerocount + \processaction + [\getvalue{\??mc\OTRSETidentifier\c!balance}] + [ \v!yes=>\chardef\OTRSETbalancemethod\plusone, + \v!top=>\chardef\OTRSETbalancemethod\plustwo, + \v!bottom=>\chardef\OTRSETbalancemethod\plusthree]} + +% test: +% +% \definecolumnset[test-1] %[balance=yes] +% \definecolumnset[test-2] %[balance=yes] +% +% \setupcolumnsetlines[test-1][1][1] [4] +% \setupcolumnsetlines[test-1][1][2][10] +% +% \startcolumnset [test-1] \dorecurse {1}{\input tufte \par} \stopcolumnset +% \startcolumnset [test-2] \dorecurse {2}{\input ward \par} \stopcolumnset + +\ifx\lastskipinotr\undefined \newskip\lastskipinotr \fi + +\installoutput\OTRSETflushpreposttext + {\global\setbox\precolumnbox\vbox + {\unvbox\normalpagebox + \global\lastskipinotr\lastskip}% + \ifdim\lastskipinotr>\zeropoint + \global\setbox\precolumnbox\hbox + {\lower\strutdepth\box\precolumnbox}% + \fi + \global\dp\precolumnbox\strutdepth + \ifcarryoverfootnotes \else + \global\setbox\postcolumnbox\vbox{\placebottomnotes}% + \fi} + +\let\precolumnlines \!!zerocount +\let\postcolumnlines\!!zerocount + +\def\OTRSEThandlepreposttext + {\ifdim\ht\precolumnbox>\zeropoint % new + \getnoflines{\ht\precolumnbox}% + \edef\precolumnlines{\the\noflines}% + \doOTRSETsetgridcells + {\copy\placeholderboxe} + \plusone\plusone\nofcolumns\noflines + % normal version (single column set) + % {\box\precolumnbox}% + % compensated for bodyfont change + {\hbox + {\OTRSETsetcorrectcellht + \raise\scratchdimen\box\precolumnbox}}% + \else + \let\precolumnlines\!!zerocount + \fi + \ifdim\ht\postcolumnbox>\zeropoint % new, otherwise empty bottom line + \getnoflines{\ht\postcolumnbox}% + \edef\postcolumnlines{\the\noflines}% + \advance\columnfreecells -\noflines + \advance\columnfreecells \plusone + \doOTRSETsetgridcells + {\copy\placeholderboxe} + \plusone\columnfreecells\nofcolumns\noflines + {\box\postcolumnbox}% + \else + \let\postcolumnlines\!!zerocount + \fi} + +\def\OTRSETchecksidefloat + {} % {\sidefloatoutput} + +\def\OTRSETfinalsidefloatoutput + {} + +\def\OTRSETcheckgrid + {\topskip1\topskip + \ifforcecolumngrid + \widowpenalty\zerocount + \clubpenalty\zerocount + \brokenpenalty\zerocount + \fi} + +\def\OTRSETcheckinsert + {\iflastcolumnfootnotes + \ifnum\nofcolumns=\mofcolumns + \OTRSETforceinserts + \else + \OTRSETinhibitinserts + \fi + \else + \OTRSETforceinserts + \fi} + +\def\OTRSETforceinserts + {\enablenotes} + +\def\OTRSETinhibitinserts + {\disablenotes} + +% interface to footnotes + +\def\OTRSETassignwidths + {%\scratchdimen\makeupwidth + \freezetextwidth \scratchdimen\textwidth + % + \scratchcounter\zerocount + \dorecurse\nofcolumns + {\doifelsevalue{\??mc\OTRSETidentifier\recurselevel\c!width}\v!fit + {\advance\scratchcounter \plusone } + {\advance\scratchdimen -\getvalue{\??mc\OTRSETidentifier\recurselevel\c!width}}% + \advance\scratchdimen -\getvalue{\??mc\OTRSETidentifier\recurselevel\c!distance}}% + \ifcase\scratchcounter\else + \divide\scratchdimen \scratchcounter + \fi + \setgvalue{\??mc\??mc\c!width}{0}% + \dorecurse\nofcolumns + {\doifelsevalue{\??mc\OTRSETidentifier\recurselevel\c!width}\v!fit + {\dimen0=\scratchdimen} + {\setgvalue{\??mc\??mc\c!width}{1}% + \dimen0=\getvalue{\??mc\OTRSETidentifier\recurselevel\c!width}}% + \setxvalue{\??mc\recurselevel\??mc\c!width}{\the\dimen0}}} + +\def\OTRSETlocalwidth#1% + {\getvalue{\??mc\number#1\??mc\c!width}} + +\newbox\placeholderboxa +\newbox\placeholderboxb +\newbox\placeholderboxc +\newbox\placeholderboxd +\newbox\placeholderboxe +\newbox\placeholderboxf + +\def\columnplaceholder#1#2% + {\hbox + {\setbox\scratchbox\hbox to \hsize + {\iftracecolumnset + \hskip-.5ex% + \startcolor[columnset:#2]\vrule\!!width1ex\!!height.5ex\!!depth.5ex\stopcolor + \fi + \hss}% + \ifcase#1\relax + \ht\scratchbox\zeropoint + \dp\scratchbox\zeropoint + \wd\scratchbox\zeropoint + \else + \wd\scratchbox\hsize + \ht\scratchbox\strutht + \dp\scratchbox\strutdp + \fi + \box\scratchbox}} + +\definepalet + [columnset] + [a=cyan,b=green,c=blue,d=red,e=magenta,f=darkgray] + +\def\OTRSETsetplaceholders + {\global\setbox\placeholderboxa\columnplaceholder0a% + \global\setbox\placeholderboxb\columnplaceholder0b% + \global\setbox\placeholderboxc\columnplaceholder0c% + \global\setbox\placeholderboxd\columnplaceholder0d% + \global\setbox\placeholderboxe\columnplaceholder0e% + \global\setbox\placeholderboxf\columnplaceholder1f} + +\def\doOTRSETshowstatus + {\llap{\tt\tfxx + \startcolor[blue](\the\vsize->\number\columnfirstcell\#\number\columnfreecells)\stopcolor + \hskip\leftskip}} + +\installtextracer{OTRSET} % low level + +\def\enabletextracerOTRSET {\tracecolumnsettrue \let\OTRSETshowstatus\doOTRSETshowstatus} +\def\disabletextracerOTRSET{\tracecolumnsetfalse\let\OTRSETshowstatus\relax} + +\disabletextracerOTRSET + +% \appendtoks \OTRSETshowstatus \to \everypar + +% page contents + +\def\OTRSETdopagecontents#1#2% takes two args: \box \unvbox + {\vbox to \textheight{\forgetall#1#2}} + +\def\OTRSETsomepagefloat {\def\floatmethod{PAGE}\OTRSETsomeslotfloat} % check +\def\OTRSETsomeherefloat {\def\floatmethod{HERE}\OTRSETsomeslotfloat} % check +\def\OTRSETsomeelsefloat {\def\floatmethod{HERE}\OTRSETsomeslotfloat} % check +\def\OTRSETsomefixdfloat {\def\floatmethod{FIXD}\OTRSETsomeslotfloat} % check +\def\OTRSETsometopfloat {\def\floatmethod{TOPS}\OTRSETsomeslotfloat} % check +\def\OTRSETsomebottomfloat{\def\floatmethod{BOTS}\OTRSETsomeslotfloat} % check + +\def\OTRSETflushfloatbox % nog verder doorvoeren en meer info in marge + {\iftestfloatbox\ruledhbox\fi{\box\floatbox}} + +\def\OTRSETsomeslotfloat[#1]% + {\setbox\floatbox\vbox{\flushfloatbox}% + \dp\floatbox\strutdp + \@EA\uppercasestring\floatmethod\to\floatmethod + \OTRSETstoreincolumnslot\floatmethod\floatbox + \doinsertfloatinfo} + +% kind of new, looks much like OTRONE, but not entirely + +\def\OTRSETdosettopinserts + {\bgroup + \ifsomefloatwaiting + \noffloatinserts\zerocount + \let\totaltopinserted\!!zeropoint + \OTRSETdodosettopinserts + \ifnum\@@bknbottom=\zerocount + \ifnum\@@bknlines>\zerocount + \ifdim\totaltopinserted>\zeropoint\relax + \dimen0\lineheight + \dimen0=\@@bknlines\dimen0 + \advance\dimen0 \totaltopinserted\relax + \ifdim\dimen0>\textheight % \vsize %%%%%%%%% \textheight + \showmessage\m!floatblocks8{\@@bknlines}% + \vfilll\eject + \fi + \fi + \fi + \fi + \fi + \egroup} + +\def\OTRSETdodosettopinserts + {\ifnum\noffloatinserts<\noftopfloats + \dogetfloat + \ifdim\topinserted=\zeropoint\relax + \topofinserttrue + \else + \topofinsertfalse + \fi + \setbox\scratchbox\vbox % kan beter ! + {\forgetall + \iftopofinsert + \ifdim\OTRSETtopoffset=\zeropoint + \moveongrid[\v!top] + \fi + \else + \betweenfloatblanko % inserts can't look back + \fi + \flushfloatbox + \blank[\@@bkspaceafter]}% + \global\advance\topinserted \ht\scratchbox\relax + \ifdim\topinserted>\vsize % was \textheight\relax + \OTRSETresavebox\floatbox + \noffloatinserts\noftopfloats\relax + \global\advance\topinserted -\ht\scratchbox + \let\OTRSETdodosettopinserts\relax % to be tested + \else + \xdef\totaltopinserted{\the\topinserted}% + \insert\topins{\forgetall\box\scratchbox}% interlineskip ? + \ifsomefloatwaiting + \advance\noffloatinserts \plusone + \else + \noffloatinserts\noftopfloats\relax + \fi + \dofloatflushedinfo + \fi + \else + \ifsomefloatwaiting + \showmessage\m!floatblocks6{\the\noftopfloats}% + \fi + \let\OTRSETdodosettopinserts\relax + \fi + \OTRSETdodosettopinserts} + +\def\OTRSETdosetbotinserts + {\bgroup + \ifsomefloatwaiting + \noffloatinserts\zerocount + \OTRSETdodosetbotinserts + \fi + \egroup} + +\def\OTRSETdodosetbotinserts + {\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 + \OTRSETresavebox\floatbox + \noffloatinserts\nofbotfloats\relax + \fi + \global\nofloatpermittedtrue % vgl topfloats s! + \else + \ifsomefloatwaiting + \showmessage\m!floatblocks7{\the\nofbotfloats}% + \fi + \let\OTRSETdodosetbotinserts\relax + \fi + \OTRSETdodosetbotinserts} + +\let\OTRSETdosetbothinserts\relax + +\def\OTRSETdotopinsertions + {\ifvoid\topins\else + \ifvoid\columntopbox\mofcolumns + \columnsettopbox\mofcolumns\box\topins + \else + \columnsettopbox\mofcolumns\vbox % temp, must be better + {\forgetall + \offinterlineskip + \box\columntopbox\mofcolumns + \box\topins} + \fi + \fi + \global\topinserted\zeropoint\relax} % goes away + +\def\OTRSETdobotinsertions + {\ifvoid\botins \else + \columnsetbotbox\mofcolumns\box\botins +% \else +% \columnsetbotbox\mofcolumns\vbox % temp, must be better +% {\forgetall +% \offinterlineskip +% \box\botins +% \box\columnbotbox\mofcolumns} + \fi + \global\botinserted\zeropoint\relax} % goes away + +% set ipv text + +% left right 1 2 3 +1 +2 +3 + +\let\columnleftareas \empty +\let\columnrightareas\empty + +% links rechts => odd, even, n, named + +\unexpanded\def\definecolumntextarea + {\dotripleempty\dodefinecolumntextarea} + +\def\dodefinecolumntextarea[#1][#2][#3]% y=0 is mogelijke en handig ! + {\ifthirdargument + \doifinsetelse{#2}{\v!both,\v!fixed} + {\definecolumntextarea[#1][\v!left ][\c!type=#2,#3]% + \definecolumntextarea[#1][\v!right][\c!type=#2,#3]} + {\doifelse{#2}\v!next + {\doifoddpageelse + {\definecolumntextarea[#1][\v!right][\c!type=#2,#3]} + {\definecolumntextarea[#1][\v!left ][\c!type=#2,#3]}} + {\presetlocalframed + [\??mt#1#2]% + \processaction[#2] % \doglobal voorkomt stack build up + [ \v!left=>\doglobal\addtocommalist{#1}\columnleftareas, + \v!right=>\doglobal\addtocommalist{#1}\columnrightareas]% + \getparameters[\??mt#1#2] + [\c!x=1,\c!y=1,\c!nx=1,\c!ny=1,\c!clipoffset=2\lineheight, + \c!leftoffset=\zeropoint,\c!rightoffset=\zeropoint, + \c!offset=\v!overlay,\c!strut=\v!no,\c!frame=\v!off, + \c!type=#2,\c!page=1,\c!state=\v!stop,#3]}}% + \else + \definecolumntextarea[#1][\v!next][#2]% + \fi} + +\unexpanded\def\setupcolumntextarea + {\dotripleempty\dosetupcolumntextarea} + +\def\dosetupcolumntextarea[#1][#2][#3]% + {\ifthirdargument + \doifelse{#2}\v!both + {\setupcolumntextarea[#1][\v!left ][#3]% + \setupcolumntextarea[#1][\v!right][#3]} + {\doifelse{#2}\v!next + {\doifoddpageelse + {\setupcolumntextarea[#1][\v!right][#3]} + {\setupcolumntextarea[#1][\v!left][#3]}} + {\getparameters[\??mt#1#2][#3]}}% + \else + \setupcolumntextarea[#1][\v!next][#2]% + \fi} + +\def\docheckcolumnsetareapage#1#2% + {\ifnum\getvalue{\??mt#1\c!page}>\plusone + \doifelsevalue{\??mt#1\c!type}\v!fixed + {\ifnum\columnsetpage=\getvalue{\??mt#1\c!page}\relax + \donetrue\else\donefalse + \fi} + {\ifnum\columnsetpage<\getvalue{\??mt#1\c!page}\relax + \donefalse\else\donetrue + \fi}% + \else + \donetrue + \fi} + +\def\initializecolumntextareas + {\ifodd\realpageno + \doinitializecolumntextareas\columnrightareas\v!right + \else + \doinitializecolumntextareas\columnleftareas\v!left + \fi} + +\def\doinitializecolumntextareas#1#2% + {\def\docommand##1% + {\docheckcolumnsetareapage{##1#2}\plusone + \ifdone + \donefalse + \processaction + [\getvalue{\??mt##1#2\c!state}] + [ \v!start=>\donetrue, + \v!repeat=>\donetrue, + \s!unknown=>\doperformtest\commalistelement\donetrue\donefalse]% + \ifdone\dodoinitializecolumntextareas{##1}{#2}\fi + \fi}% + \processcommacommand[#1]\docommand} + +\def\dodoinitializecolumntextareas#1#2% + {\doOTRSETsetgridcells + {\copy\placeholderboxd} + {\getvalue{\??mt#1#2\c!x }}{\getvalue{\??mt#1#2\c!y }} + {\getvalue{\??mt#1#2\c!nx}}{\getvalue{\??mt#1#2\c!ny}} + {\copy\placeholderboxd}} + +\unexpanded\def\placecolumntextareas + {\ifodd\realpageno + \doplacecolumntextareas\columnrightareas\v!right + \else + \doplacecolumntextareas\columnleftareas\v!left + \fi} + +\def\doplacecolumntextareas#1#2% global ? + {\bgroup + \forgetall + \def\docommand##1% + {\docheckcolumnsetareapage{##1#2}\zerocount + \ifdone + \donefalse + \processaction + [\getvalue{\??mt##1#2\c!state}] + [ \v!start=>\donetrue\doglobal\removefromcommalist{##1}#1, + \v!repeat=>\donetrue, + \s!unknown=>\doperformtest\commalistelement\donetrue\donefalse]% + \ifdone + \dodoplacecolumntextareas{##1}{#2}% + \else + \doglobal\removefromcommalist{##1}#1% + \fi + \fi}% + \processcommacommand[#1]\docommand + \egroup} + +% \page[left] +% \definecolumntextarea[intro][left][x=1,y=1,nx=4,ny=20,state=start,background=introlayer] +% \setupcolumntextareatext[intro][left][\setups{intro}] +% \flushcolumntextareas + +\def\flushcolumntextareas + {\initializecolumntextareas + \setvsize} + +\def\columntextlastbackspace{\backspace} + +% beware, we have clipping offsets of 2\lineheight by default + +\def\columntextareaparameter#1% + {\csname\??mt\currentcolumntestarea#1\endcsname} + +\def\dodoplacecolumntextareas#1#2% + {\def\currentcolumntestarea{#1#2}% + \!!counta\columntextareaparameter\c!x + \!!countb\columntextareaparameter\c!nx + \docalculatecolumnsetspan + \!!heighta\columntextareaparameter\c!ny\lineheight + % wrong + % \ifnum\columntextareaparameter\c!y=\zerocount + % \advance\!!heighta -\lineheight + % \advance\!!heighta \topskip + % \fi + % \advance\!!heighta -\lineheight % option + \ifnum\columntextareaparameter\c!y=\plusone + \advance\!!heighta -\lineheight + \advance\!!heighta \topskip + \fi + % + \setbox\scratchbox\vbox + {\donetrue\localframed + [\??mt\currentcolumntestarea] + [\c!location=,% new (*) + \c!width=\!!widtha,\c!height=\!!heighta,\c!lines=] + {\columntextareaparameter\empty}}% + \!!counta\columntextareaparameter\c!x + \!!countb\columntextareaparameter\c!y + \advance\!!countb \columntextareaparameter\c!ny + \advance\!!countb \minusone + % new (*) + \doif{\columntextareaparameter\c!location}\v!depth + {\setbox\scratchbox\hbox{\lower\strutdepth\box\scratchbox}% + \dp\scratchbox\zeropoint + \ht\scratchbox\!!heighta}% + % + \setbox0\hbox + {\ifcase\!!countc + \copy\scratchbox % \box + \else + \clip + [ %\c!topoffset=\columntextareaparameter\c!clipoffset,% + %\c!bottomoffset=\columntextareaparameter\c!clipoffset,% + %\c!leftoffset=\columntextareaparameter\c!clipoffset,% + \c!offset=\columntextareaparameter\c!clipoffset,% + \c!offset=\columntextareaparameter\c!clipoffset,% + \c!rightoffset=\columntextareaparameter\c!rightoffset,% + \c!width=\!!widthb,% + \c!height=\!!heighta]% + {\copy\scratchbox}% + \fi}% + \OTRSETsetgridcell\!!counta\!!countb\box0 + \ifcase\!!countc\else + \advance\!!counta \columntextareaparameter\c!nx + \advance\!!counta -\!!countc + \advance\!!widtha -\!!widthb + \setbox0\hbox + {\hskip-\namedlayoutparameter\v!odd\c!backspace + \clip + [ %\c!topoffset=\columntextareaparameter\c!clipoffset,% + %\c!bottomoffset=\columntextareaparameter\c!clipoffset,% + %\c!rightoffset=\columntextareaparameter\c!clipoffset,% + \c!offset=\columntextareaparameter\c!clipoffset,% + \c!leftoffset=\columntextareaparameter\c!leftoffset,% + \c!width=\!!widtha,% + \c!height=\!!heighta,% + \c!hoffset=\!!widthb]% + {\copy\scratchbox}}% + \OTRSETsetgridcell\!!counta\!!countb\box0% + \fi} + +\unexpanded\def\setupcolumntextareatext + {\dotripleempty\dosetupcolumntextareatext} + +\long\def\dosetupcolumntextareatext[#1][#2][#3]% + {\ifthirdargument + \doifelse{#2}\v!both + {\setvalue{\??mt#1\v!left }{#3}% + \setvalue{\??mt#1\v!right}{#3}} + {\doifelse{#2}\v!next + {\doifoddpageelse + {\setvalue{\??mt#1\v!right}{#3}}% + {\setvalue{\??mt#1\v!left }{#3}}}% + {\setvalue{\??mt#1#2}{#3}}}% + \else + \setupcolumntextareatext[#1][\v!next][{#2}]% + \fi} + +\def\docalculatecolumnsetspan + {% \!!counta <= x + % \!!countb <= nx + % \!!widtha => total width + % \!!widthb => left width + % \!!countc => left cols + \!!widtha\!!countb\textwidth % we assume equal widths + \advance\!!countb \!!counta + \advance\!!countb \minusone + \ifnum\!!countb>\nofcolumns + \!!countc\!!countb + \advance\!!countc -\nofcolumns + \!!countb\nofcolumns + \else + \!!countc\zerocount + \fi + \advance\!!counta \plusone + \dostepwiserecurse\!!counta\!!countb\plusone + {\advance\!!widtha\OTRSETgetparameter\c!distance\recurselevel}% + \!!widthb\!!widtha + \advance\!!widthb -\!!countc\textwidth + \ifodd\realpageno \else % tricky, assumes that we keep there + \ifcase\!!countc\else + % nog niet ok voor enkel/doublesided + \advance\!!widtha \namedlayoutparameter\v!even\c!backspace + \advance\!!widtha \namedlayoutparameter\v!odd \c!backspace + \advance\!!widthb \namedlayoutparameter\v!even\c!backspace + \dorecurse\!!countc + {\advance\!!widtha\OTRSETgetparameter\c!distance\recurselevel}% + \fi + \fi} + +\def\columnsetspanhsize{\textwidth} + +\def\setcolumnsetspanhsize#1#2% x nx / uses counta/b + {\!!counta#1\!!countb#2\docalculatecolumnsetspan + \edef\columnsetspanhsize{\the\!!widtha}} + +\unexpanded\def\definecolumnsetspan + {\dodoubleempty\dodefinecolumnsetspan} + +\def\dodefinecolumnsetspan[#1][#2]% + {%\ifsecondargument + \defineframedtext + [cs:#1] + [\c!frame=\v!off, + \c!before=, + \c!after=, + \c!offset=\v!overlay, + \c!location=\v!left, + \c!linecorrection=\v!off, + \c!depthcorrection=\v!off, + \c!n=2, + \c!nlines=0, + \c!indenting=, + \c!indentnext=\v!yes, + \c!default=HERE, + \c!alternative=\v!a, + #2]% + %\else + % \definecolumnspan[][#1]% + }%\fi} + +\definecolumnsetspan[\s!default] + +\unexpanded\def\setupcolumnsetspan + {\dodoubleempty\dosetupcolumnsetspan} + +\def\dosetupcolumnsetspan[#1][#2]% + {\ifsecondargument + \setupframedtexts[cs:#1][#2]% + \else + \setupcolumnsetspan[\s!default][#1]% + \fi} + +\unexpanded\def\startcolumnsetspan + {\dotripleempty\dostartcolumnsetspan} + +%%%%%%%%%%%%%%%% TODO + +\def\dostartcolumnsetspan[#1][#2][#3]% [#3] gobbles space + {\endgraf % else rubish output if forgotten + \vskip \zeropoint % make sure otr is done, otherwise last line problems + \bgroup + \forgetall + \ifnum\columnsetlevel>\zerocount\else + % of course we needed a one-column fall back for tm + \columnsetspanhsize\hsize + \nofcolumns\plusone + \mofcolumns\plusone + \fi + \setupframedtexts[cs:#1] + [\c!width=\columnsetspanhsize, + \c!linecorrection=\v!off, + \c!depthcorrection=\v!off, + #2]% + % determine widths + \!!countc\framedtextparameter{cs:#1}\c!n + % \!!countd\numexpr(\nofcolumns-\mofcolumns+\plusone)% + \!!countd\nofcolumns + % n <= n of columns + \ifnum\!!countc>\!!countd \!!countc\!!countd \fi + \advance\!!countd -\mofcolumns + \advance\!!countd \plusone + % n <= n of available columns (alternative a) + \doif{\framedtextparameter{cs:#1}\c!alternative}\v!a + {\ifnum\!!countc>\!!countd \!!countc\!!countd \fi}% + % here it all starts + \setcolumnsetspanhsize\mofcolumns\!!countc % a/b used + \hsize\columnsetspanhsize + \setbox\scratchbox\vbox\bgroup + \dostartframedtext[cs:#1][\v!none]% geen nils placement + % spoils spacing : \vskip-\struttotal\par\verticalstrut\par + \ifnum\columnsetlevel>\zerocount + \framedtextparameter{cs:#1}\c!before + \fi + \unexpanded\def\stopcolumnsetspan{\dostopcolumnsetspan{#1}}} + +\def\dostopcolumnsetspan#1% + {\par + \verticalstrut + \kern-2\struttotal + \verticalstrut + \ifnum\columnsetlevel>\zerocount + \doifsomething{\framedtextparameter{cs:#1}\c!after} + {\framedtextparameter{cs:#1}\c!after + \kern\zeropoint}% otherwise blanks disappear, better be a switch + \else + \endgraf + \fi + \dostopframedtext + \egroup + \setbox\scratchbox\frozenhbox to \hsize + {\dontcomplain + \alignedline{\framedtextparameter{cs:#1}\c!location}\v!middle + {\lower\strutdepth\box\scratchbox}}% + \dp\scratchbox\zeropoint % else wrong snap insidefloat +% +% to be tested first (strange in grid mode) +% +% \setbox\scratchbox\frozenhbox to \hsize +% {\dontcomplain +% \chardef\alignstrutmode\zerocount +% \alignedline{\framedtextparameter{cs:#1}\c!plaats}\v!midden +% {\box\scratchbox}}% +% + \ifinsidefloat + \box\scratchbox + \else\ifnum\columnsetlevel>\zerocount + % we only set \columnsetspacing when asked for, else bottom problems + % don't change this any more (test naw) + \chardef\columnslotspacing\framedtextparameter{cs:#1}\c!nlines\relax + % todo: nboven/onder & \chardef\columnslotlocation2 + %\OTRSETstoreincolumnslotHERE\scratchbox + \edef\floatmethod{\framedtextparameter{cs:#1}\c!default}% + \@EA\uppercasestring\floatmethod\to\floatmethod + % todo : \v!here -> here enzovoorts + \OTRSETstoreincolumnslot\floatmethod\scratchbox + % watch out: no \dochecknextindentation{tag} + \checknextindentation[\framedtextparameter{cs:#1}\c!indentnext]% + \else + % of course we needed a one-column fall back for tm; brrr, the box has now too + % much height (try \ruledvbox); don't change this without testing techniek + \scratchdimen\ht\scratchbox + \advance\scratchdimen-\strutdp + \ht\scratchbox\scratchdimen + \framedtextparameter{cs:#1}\c!before + \snaptogrid\vbox{\box\scratchbox}% + \framedtextparameter{cs:#1}\c!after + \fi\fi + \egroup + \endgraf} + +% \startcolumnset[two] +% \input tufte +% \startcolumnsetspan[two][width=20cm,location=middle] \input tufte \stopcolumnsetspan +% \startcolumnsetspan[two][default=btlr] \input tufte \stopcolumnsetspan +% \input tufte \par +% \input tufte \par +% \startcolumnsetspan[two] \emptylines[5] \stopcolumnsetspan +% \startcolumnsetspan[two] \input tufte \stopcolumnsetspan +% \stopcolumnset + +\protect \endinput + +% extreme examples (1) +% +% \setupfloats[numbering=nocheck] +% +% \definecolumnset [first] [n=2,start=0] +% \definecolumnset [next] [n=2,start=3] +% +% \setuptexttexts[\vbox to \textheight{\topskipcorrection \hsize\makeupwidth left \hfill right\vfill}] +% +% \setuphead[chapter][text=empty] +% +% \starttext +% +% \startcolumnset[first,next] +% \placefigure[btrl]{}{} +% \placefigure[tblr]{}{} +% \chapter{thuan} \dorecurse{25}{\recurselevel: \input thuan \endgraf} +% \stopcolumnset +% +% \startcolumnset[first,next] +% \chapter{thuan} \dorecurse{25}{\input thuan \endgraf\placefigure{}{}} +% \stopcolumnset + +\unprotect + +% only in columnsets + +% \def\cornerfigure +% {\dotripleempty\docornerfigure} +% +% \def\docornerfigure[#1][#2][#3]% [layer] [location] [settings] +% {\bgroup +% \dowithnextbox +% {\!!doneafalse +% \!!donebfalse +% \processallactionsinset +% [\v!left,\v!bottom,#2] +% [ \v!left=>\!!doneatrue , +% \v!right=>\!!doneafalse, +% \v!top=>\!!donebtrue , +% \v!bottom=>\!!donebfalse]% +% \!!widtha\nextboxwd +% \if!!donea +% % unchecked +% \advance\!!widtha-\backspace +% \else +% % unchecked +% \advance\!!widtha-\backspace +% \fi +% \!!widtha\textwidth % could be an option +% \!!heighta\nextboxht +% % zou een macro moeten zijn \getnoflayoutlines +% \ifnum\layoutparameter\c!lines=\zerocount +% \getnoflines\textheight +% \else +% \noflines\layoutparameter\c!lines +% \fi +% % +% \advance\noflines \plusone % wordt default, instelbaar +% \!!heightb\noflines\lineheight\relax +% \if!!doneb % boven +% % unchecked +% \advance\!!heighta-\topspace +% \advance\!!heighta-\headerheight +% \advance\!!heighta-\headerdistance +% \else % onder +% % checked +% \advance\!!heighta-\paperheight +% \advance\!!heighta+\!!heightb +% \advance\!!heighta+\topspace +% \advance\!!heighta+\headerheight +% \advance\!!heighta+\headerdistance +% \advance\!!heighta-\footerdistance +% \advance\!!heighta-\footerheight +% \fi +% \getnoflines\!!heighta +% \!!heighta\noflines\lineheight\relax +% \def\docornerfigure[####1]% +% {\expanded{\plaatsfiguur[####1,\v!none]{} +% {\noexpand\phantombox[\c!width=\the\!!widtha,\c!height=\the\!!heighta]}}}% +% \if!!donea +% \if!!doneb % links boven / rb +% \setlayer[#1] +% [\c!corner={\v!left,\v!top},\c!location=rb,#3] +% {\flushnextbox}% +% \docornerfigure[tblr]% +% \else % links onder / rt +% \setlayer[#1] +% [\c!corner={\v!left,\v!bottom},\c!location=rt,#3] +% {\flushnextbox}% +% \docornerfigure[btlr]% +% \fi +% \else +% \if!!doneb % rechts boven / lt +% \setlayer[#1] +% [\c!corner={\v!right,\v!top},\c!location=lb,#3] +% {\flushnextbox}% +% \docornerfigure[tbrl]% +% \else % rechts onder / lb +% \setlayer[#1] +% [\c!corner={\v!right,\v!bottom},\c!location=lt,#3] +% {\flushnextbox}% +% \docornerfigure[btrl]% +% \fi +% \fi +% \egroup} +% \vbox} diff --git a/tex/context/base/page-sid.mkii b/tex/context/base/page-sid.mkii new file mode 100644 index 000000000..0848c9d8c --- /dev/null +++ b/tex/context/base/page-sid.mkii @@ -0,0 +1,931 @@ +%D \module +%D [ file=page-sid, +%D version=2000.10.20, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Side Floats, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Side Floats} + +\unprotect + +% problem: when too small, side effects; we need to determine the +% shift earlier so that we can act when shift < size +% +% \definefloat[edgefigure] +% \setupfloat +% [edgefigure] +% [rightmargindistance=-\rightmargintotal, +% leftmargindistance=-\rightmargintotal, +% default=outer] +% \starttext +% \placeedgefigure{}{\framed[width=12cm]{}} \input tufte +% \placeedgefigure{}{\framed[width=5cm]{}} \input tufte +% \placeedgefigure{}{\framed[width=4cm]{}} \input tufte +% \placeedgefigure{}{\framed[width=2cm]{}} \input tufte +% \stoptext + +% todo: dimexpr an dnumexpr + +% These macro deal with side floats. We started with Daniel +% Comenetz macros as published in TUGBoat Volume 14 (1993), +% No.\ 1: Anchored Figures at Either Margin. I extended and +% patched the macros to suite our needs which results in a +% messy module. Therefore, this module badly needs an update +% because it's now a mixture of old and new macros. + +% afhankelijke variabelen +% +% \overgap vervangen door \floatsidetopskip +% \sidegap vervangen door \floatsideskip +% \undergap vervangen door \floatsidebottomskip +% +% \prskp vervangen door \ctxparskip + +% toegevoegde macro's/aanroepen +% +% \logsidefloat : loginformatie +% \flushsidefloats : nodig voor koppen + +% recente wijzigingen: +% +% namen aangepast: \float... enz. i.p.v. \pic + +% Pas op: \EveryPar{\EveryPar{}\margetitel{whatever}} +% \plaatsfiguur[links]{}{} moet goed gaan. In dat geval +% begint de tekst terecht wat lager. + +\newdimen\sidefloatheight % includes the topskip +\newdimen\sidefloatwidth +\newdimen\sidefloathsize +\newdimen\sidefloatshift +\newdimen\sidefloatextrashift +\newdimen\sidefloatvsize \def\nofloatvsize{-1pt } +\newdimen\sidefloatprogress +\newdimen\sidefloatpagetotal + +\newbox\floatbottom + +\newcount\sidefloatsidelines +\newcount\sidefloatlinesdone + +% 1 = backspace +% 2 = leftedge +% 3 = leftmargin +% 4 = leftside +% 5 = rightside +% 6 = rightmargin +% 7 = rightedge +% 8 = cutspace + +\chardef\sidefloattype\zerocount + +\def\backspacefloat {\global\chardef\sidefloattype1 \putsidefloat} +\def\leftedgefloat {\global\chardef\sidefloattype2 \putsidefloat} +\def\leftmarginfloat {\global\chardef\sidefloattype3 \putsidefloat} +\def\leftfloat {\global\chardef\sidefloattype4 \putsidefloat} +\def\rightfloat {\global\chardef\sidefloattype5 \putsidefloat} +\def\rightmarginfloat {\global\chardef\sidefloattype6 \putsidefloat} +\def\rightedgefloat {\global\chardef\sidefloattype7 \putsidefloat} +\def\cutspacefloat {\global\chardef\sidefloattype8 \putsidefloat} + +\let\marginfloat \cutspacefloat + +\newif\ifroomforfloat +\newif\iffloatshort +\newif\iffloatflag +\newif\iffloatrighteqo +\newif\iffloatlefteqo + +\newdimen\sidefloatleftskip +\newdimen\sidefloatrightskip +\newdimen\sidefloatmaximum + +% \def\checksidefloatshift +% {\ifdim\sidefloatmaximum>\zeropoint +% \ifcase\sidefloattype +% % invalid +% \or +% % backspace +% \or +% \global\sidefloatshift-\sidefloatmaximum +% \global\advance\sidefloatshift-\rightorleftpageaction \leftedgedistance \rightedgedistance +% \global\advance\sidefloatshift-\rightorleftpageaction \leftmarginwidth \rightmarginwidth +% \global\advance\sidefloatshift-\rightorleftpageaction \leftmargindistance \rightmargindistance +% \or +% \global\sidefloatshift-\sidefloatmaximum +% \global\advance\sidefloatshift-\rightorleftpageaction \leftmargindistance \rightmargindistance +% \or +% % left +% \or +% % right +% \or +% \global\sidefloatshift-\sidefloatmaximum +% \global\advance\sidefloatshift-\rightorleftpageaction \leftmargindistance \rightmargindistance +% \or +% \global\sidefloatshift-\sidefloatmaximum +% \global\advance\sidefloatshift-\rightorleftpageaction \leftedgedistance \rightedgedistance +% \global\advance\sidefloatshift-\rightorleftpageaction \leftmarginwidth \rightmarginwidth +% \global\advance\sidefloatshift-\rightorleftpageaction \leftmargindistance \rightmargindistance +% \or +% % cutspace +% \fi +% \fi} + +\def\checksidefloatshift + {\ifdim\sidefloatmaximum>\zeropoint + \ifcase\sidefloattype + % invalid + \or + % backspace + \or + \global\sidefloatshift\dimexpr + -\sidefloatmaximum + -\rightorleftpageaction \leftedgedistance \rightedgedistance + -\rightorleftpageaction \leftmarginwidth \rightmarginwidth + -\rightorleftpageaction \leftmargindistance \rightmargindistance + -\compensatedinnermakeupmargin + \relax + \or + \global\sidefloatshift\dimexpr + -\sidefloatmaximum + -\rightorleftpageaction \leftmargindistance \rightmargindistance + -\compensatedinnermakeupmargin + \relax + \or + % left + \or + % right + \or + \global\sidefloatshift\dimexpr + -\sidefloatmaximum + -\rightorleftpageaction \leftmargindistance \rightmargindistance + -\compensatedinnermakeupmargin + \relax + \or + \global\sidefloatshift\dimexpr + -\sidefloatmaximum + -\rightorleftpageaction \leftedgedistance \rightedgedistance + -\rightorleftpageaction \leftmarginwidth \rightmarginwidth + -\rightorleftpageaction \leftmargindistance \rightmargindistance + -\compensatedinnermakeupmargin + \relax + \or + % cutspace + \fi + \fi} + +% \def\setsidefloatskips +% {\global\sidefloatrightskip\zeropoint +% \global\sidefloatleftskip \zeropoint +% \ifcase\sidefloattype +% \or % backspace +% \global \sidefloatleftskip \rightorleftpageaction \backspace \cutspace +% \or % leftedge +% \global \sidefloatleftskip \rightorleftpageaction \leftmargindistance\rightmargindistance +% \global\advance\sidefloatleftskip \rightorleftpageaction \leftmarginwidth\rightmarginwidth +% \global\advance\sidefloatleftskip \rightorleftpageaction \leftedgedistance\rightedgedistance +% \or % leftmargin +% \global \sidefloatleftskip \rightorleftpageaction \leftmargindistance\rightmargindistance +% \or % leftside +% \or % rightside +% \or % rightmargin +% \global \sidefloatrightskip\rightorleftpageaction \rightmargindistance\leftmargindistance +% \or % rightedge +% \global \sidefloatrightskip\rightorleftpageaction \rightmargindistance\leftmargindistance +% \global\advance\sidefloatrightskip\rightorleftpageaction \rightmarginwidth\leftmarginwidth +% \global\advance\sidefloatrightskip\rightorleftpageaction \rightedgedistance\leftedgedistance +% \or % cutspace +% \global \sidefloatrightskip\rightorleftpageaction \cutspace\backspace +% \fi +% \ifdim\sidefloatrightskip>\zeropoint +% \doglobal\advance\sidefloatrightskip\rightskip +% \fi +% \ifdim\sidefloatleftskip>\zeropoint +% \doglobal\advance\sidefloatleftskip\leftskip +% \fi} + + +% use \outermarginwidth etc here + +\def\setsidefloatskips + {\global\sidefloatrightskip\zeropoint + \global\sidefloatleftskip \zeropoint + \ifcase\sidefloattype + \or % backspace + \global\sidefloatleftskip\dimexpr + +\rightorleftpageaction \backspace \cutspace + +\compensatedinnermakeupmargin + \relax + \or % leftedge + \global\sidefloatleftskip\dimexpr + +\rightorleftpageaction \leftmargindistance \rightmargindistance + +\rightorleftpageaction \leftmarginwidth \rightmarginwidth + +\rightorleftpageaction \leftedgedistance \rightedgedistance + +\compensatedinnermakeupmargin + \relax + \or % leftmargin + \global\sidefloatleftskip\dimexpr + +\rightorleftpageaction \leftmargindistance \rightmargindistance + +\compensatedinnermakeupmargin + \relax + \or % leftside + \or % rightside + \or % rightmargin + \global\sidefloatrightskip\dimexpr + +\rightorleftpageaction \rightmargindistance \leftmargindistance + +\compensatedinnermakeupmargin + \relax + \or % rightedge + \global\sidefloatrightskip\dimexpr + +\rightorleftpageaction \rightmargindistance \leftmargindistance + +\rightorleftpageaction \rightmarginwidth \leftmarginwidth + +\rightorleftpageaction \rightedgedistance \leftedgedistance + +\compensatedinnermakeupmargin + \relax + \or % cutspace + \global\sidefloatrightskip\dimexpr + +\rightorleftpageaction \cutspace \backspace + +\compensatedinnermakeupmargin + \relax + \fi + \ifdim\sidefloatrightskip>\zeropoint \doglobal\advance\sidefloatrightskip\rightskip \fi + \ifdim\sidefloatleftskip >\zeropoint \doglobal\advance\sidefloatleftskip \leftskip \fi} + +% eq is still crap + +\ifx\normalleqno\undefined + + \let\floatrighteqo=\eqno + \let\floatleftleqo=\leqno + +\else + + \let\floatrighteqo=\normaleqno + \let\floatleftleqo=\normalleqno + +\fi + +% Watch it even more! In inner, gaat't mis omdat daar +% pagetotal enz niet zijn aangepast. Inner kan overigens niet +% betrouwbaar worden getest! + +% \def\flushsidefloats% +% {\par +% \sidefloatprogress=\sidefloatvsize +% \advance\sidefloatprogress by -\pagetotal +% \ifdim\sidefloatprogress>\zeropoint +% \witruimte % nog checken op interferentie +% \kern\sidefloatprogress +% \fi +% \global\sidefloatvsize=\nofloatvsize +% \global\floatflagfalse} +% +% no, too buggy, leads to top of page crap +% +%\def\flushsidefloats +% {\par +% \dochecksidefloat +% \scratchcounter=-\hangafter +% \dorecurse{\scratchcounter}{\strut\hfill\strut\par}} +% +%\def\flushsidefloats +% {\par +% \!!heighta\sidefloatvsize +% \advance\!!heighta -\pagetotal +% \ifdim\!!heighta>\zeropoint +% % to be checked for interference +% \witruimte +% % will be option +% \getnoflines\!!heighta +% \!!heighta\noflines\lineheight +% % so far for option +% \kern\!!heighta +% \fi +% % == \forgetsidefloats +% \global\sidefloatvsize\nofloatvsize +% \global\floatshortfalse +% \global\floatflagfalse} + +% \def\flushsidefloats +% {\par +% \!!heighta\sidefloatvsize +% \advance\!!heighta -\pagetotal +% \ifdim\!!heighta>\zeropoint +% % to be checked for interference +% \witruimte +% % will be option +% \getnoflines\!!heighta +% \!!heighta\noflines\lineheight +% % so far for option +% \ifdim\sidefloatbottomskip>\zeropoint\relax +% \ifdim\!!heighta>\sidefloatbottomskip +% \advance\!!heighta-\sidefloatbottomskip +% \kern\!!heighta +% \vskip\sidefloatbottomskip +% \else +% \kern\!!heighta +% \fi +% \else +% \kern\!!heighta +% \fi +% \fi +% % == \forgetsidefloats +% \global\sidefloatvsize\nofloatvsize +% \global\floatshortfalse +% \global\floatflagfalse} + +\newif\iftracesidefloats + +\def\flushsidefloats + {\par + \!!heighta\sidefloatvsize + \advance\!!heighta -\pagetotal + \ifnum\!!heighta>\zeropoint + \global\advance\sidefloatvsize -\sidefloatbottomskip + \ifdim\!!heighta>\zeropoint + \bgroup + \let\flushsidefloats\relax + \forgetall + \doloop + {\strut + \iftracesidefloats + \color[darkgray]% + {\baselinerulefalse + \boxrulewidth.5\points + \ruledhbox{\strut\kern\sidefloatwidth}}% + \fi + \par + \!!heighta\sidefloatvsize + \advance\!!heighta -\pagetotal + \ifdim\!!heighta>\zeropoint + \ifnum\recurselevel>\plushundred + \exitloop + \fi + \else + \exitloop + \fi}% + \egroup + \ifdim\parskip>\zeropoint + \ifdim\sidefloatbottomskip>\parskip + \nowhitespace + \vskip\sidefloatbottomskip + \fi + \fi + \else\ifdim\sidefloatbottomskip>\parskip + \vskip\sidefloatbottomskip + \fi\fi + \fi + % not entirely the same as \forgetsidefloats + \global\sidefloatvsize\nofloatvsize + % \global\sidefloatsidelines\zerocount % no, we flush before a side float + \global\floatshortfalse % so this will get lost + % also here if used at all \global\holdinginserts\zerocount + \global\floatflagfalse} + +\def\flushsidefloatsafterpar + {\xdef\oldpagetotal{\the\pagetotal}% + \gdef\checksidefloat + {\dochecksidefloat + \ifdim\oldpagetotal=\pagetotal \else + \global\let\checksidefloat\dochecksidefloat + \flushsidefloats + \global\sidefloatsidelines\zerocount % here ! + \fi}} + +\def\forgetsidefloats + {\global\sidefloatvsize\nofloatvsize + \global\sidefloatsidelines\zerocount + % also here if used at all \global\holdinginserts\zerocount + \global\floatshortfalse + \global\floatflagfalse} + +\let\logsidefloat=\relax + +\def\pushpenalties % needed ? and right + {\widowpenalty\plusone + \clubpenalty\plustwo + \brokenpenalty\plusone + \let\pushpenalties\relax + \edef\poppenalties + {\widowpenalty \the\widowpenalty + \clubpenalty \the\clubpenalty + \brokenpenalty\the\brokenpenalty + \let\poppenalties\relax}} + +% shouldn;t that be: +% +% \def\pushpenalties % needed? +% {\let\pushpenalties\relax +% \edef\poppenalties +% {\widowpenalty \the\widowpenalty +% \clubpenalty \the\clubpenalty +% \brokenpenalty\the\brokenpenalty +% \let\poppenalties\relax}% +% \widowpenalty\plusone +% \clubpenalty\plustwo +% \brokenpenalty\plusone} + +\let\poppenalties=\relax + +\def\restorepenalties + {\ifnum\outputpenalty=\!!tenthousand\else + \penalty\outputpenalty + \fi} + +\def\sidefloatoutput + {\iffloatshort + \unvbox\normalpagebox + \setbox\floatbottom\lastbox + \ifdim\wd\floatbottom>\sidefloathsize + \penalty-201 + \box\floatbottom + \else + \ifvoid\floatbottom + \else + \restoreleftindent + \ifdim\wd\floatbottom<\sidefloathsize + \parskip\zeropoint + %\noindent + \ifinner\else\vadjust{\penalty\minusone}\fi + \iffloatlefteqo + \global\floatlefteqofalse + \else + \global\advance\sidefloathsize -\wd\floatbottom + \iffloatrighteqo + \global\floatrighteqofalse + \else + \global\divide\sidefloathsize \plustwo + \fi + \hskip\sidefloathsize + \fi + \fi + \box\floatbottom + \restorepenalties + \fi + \fi + % why was this \global\holdinginserts\zerocount + \global\floatshortfalse + \else + \finalsidefloatoutput % new + \global\sidefloatvsize\nofloatvsize + \global\sidefloatsidelines\zerocount + % we can end up in fig lock, so \global\holdinginserts\zerocount here too ? + \poppenalties + \fi} + +\def\finalsidefloatoutput% new + {\finaloutput\unvbox\normalpagebox} + +\def\restoreleftindent + {\relax \ifnum\sidefloattype>4 \else + \parskip\zeropoint % here ? + \ifdim\sidefloatwidth>\zeropoint % new, see prikkels + \noindent + \ifinner\else\vadjust{\penalty\minusone}\fi + \hskip\sidefloatwidth + %\else + % we have a margin or edge float + \fi + \fi} + +\ifx\normaleqno\undefined + + \def\normaleqno + {\iffloatshort + \global\floatrighteqotrue + \fi + \floatrighteqo} + +\else + + \def\eqno + {\iffloatshort + \global\floatrighteqotrue + \fi + \floatrighteqo} + +\fi + +% externfiguur -> grid =ja|hoogte|diepte|halveregel|passend -> helemaal in details +% stelplaatsblokin -> zijuitlijnen=hoogte|diepte|regel|halveregel|grid -> halveregel in 'details' + +% replacement for below +% +% \global\setbox\floatbox\hbox % no \hskip, but \kern here +% {\ifcase\sidefloattype +% \vbox{#1}% +% \or % 1 +% \hskip\sidefloatleftshift +% \hskip\sidefloatshift +% \vbox{#1}% +% \kern-\sidefloatextrashift +% \or % 2 +% \hskip\sidefloatshift +% \vbox{#1}% +% \kern-\sidefloatextrashift +% \or % 3 +% \hskip\sidefloatshift +% \vbox{#1}% +% \kern-\sidefloatextrashift +% \or % 4 +% \hskip\sidefloatleftshift +% \hskip\sidefloatshift +% \vbox{#1\removedepth}% +% \kern-\sidefloatextrashift +% \or % 5 +% \hskip-\sidefloatextrashift +% \vbox{#1}% +% \kern\sidefloatshift +% \kern\sidefloatrightshift +% \or % 6 +% \hskip-\sidefloatextrashift +% \vbox{#1}% +% \kern\sidefloatshift +% \or % 7 +% \hskip-\sidefloatextrashift +% \vbox{#1}% +% \kern\sidefloatshift +% \or % 8 +% \hskip-\sidefloatextrashift +% \vbox{#1}% +% \kern\sidefloatshift +% \kern\sidefloatrightshift +% \fi}% +% +% keep this ^ + +\def\putsidefloat#1% grid (4) is rather experimental + {\par + \whitespace + % moved here dec 2001 + {\everypar\emptytoks\forgetall\verticalstrut\vskip-\struttotal}% moved + \checksidefloatshift + \ifdim\sidefloatshift=\zeropoint \relax + \ifnum\sidefloattype=4 + \global\advance\sidefloatshift\sidefloatextrashift + \global\sidefloatextrashift\zeropoint + \else\ifnum\sidefloattype=5 + \global\advance\sidefloatshift\sidefloatextrashift + \global\sidefloatextrashift\zeropoint + \fi\fi + \else + \ifnum\sidefloattype<4 + \global\chardef\sidefloattype4 + \else\ifnum\sidefloattype>5 + \global\chardef\sidefloattype5 + \fi\fi + \fi + \previoussidefloat + \stallsidefloat + %\global\setbox\floatbox\hbox + % {\ifmarginfloat\else\ifrightfloat\else\kern\sidefloatleftshift\fi\fi + % \hskip\ifrightfloat-\sidefloatextrashift\else\sidefloatshift\fi + % \vbox{#1\ifnum\sidefloatalign=4 \removedepth\fi}% + % \kern\ifrightfloat\sidefloatshift\else-\sidefloatextrashift\fi + % \ifmarginfloat\else\ifrightfloat\kern\sidefloatrightshift\fi\fi}% + \global\setbox\floatbox\hbox % no \hskip, but \kern here + {\ifnum\sidefloattype=4 + \hskip\sidefloatleftshift + \else\ifnum\sidefloattype=1 + \hskip\sidefloatleftshift + \fi\fi + \ifnum\sidefloattype>4 + \hskip-\sidefloatextrashift + \else + \hskip\sidefloatshift + \fi + \vbox{#1\ifnum\sidefloatalign=4 \removedepth\fi}% + \ifnum\sidefloattype>4 + \kern\sidefloatshift + \else + \kern-\sidefloatextrashift + \fi + \ifnum\sidefloattype=8 + \kern\sidefloatrightshift + \else\ifnum\sidefloattype=5 + \kern\sidefloatrightshift + \fi\fi}% + \ifnum\sidefloatalign=4 + \getnoflines{\ht\floatbox}% + \scratchdimen\noflines\lineheight + \advance\scratchdimen-\strutdepth + \getrawnoflines\sidefloattopskip + \advance\scratchdimen\noflines\lineheight + % todo: maybe rounding problem here + % \global\setbox\floatbox\hbox{\lower\lineheight\box\floatbox}% + \global\setbox\floatbox\hbox{\lower\strutdepth\box\floatbox}% + \global\ht\floatbox\scratchdimen + \global\dp\floatbox\zeropoint + \fi + \ifcase\sidefloatalign \else + \global\sidefloattopskip\zeropoint + \fi + \scratchdimen + \ifnum\sidefloattype<4 + \sidefloattopskip + \else\ifnum\sidefloattype>5 + \sidefloattopskip + \else + \zeropoint + \fi\fi + % the top of the box is at the previous baseline + \ifcase\sidefloatalign + % 0 normal + \advance\scratchdimen\strutdepth % == \sidefloattopoffset + \or % 1 height + \advance\scratchdimen\strutdepth % == \sidefloattopoffset + \or % 2 line + \or % 3 depth + \advance\scratchdimen\lineheight + \advance\scratchdimen\strutdepth + \or % 4 grid + \scratchdimen\zeropoint + \or + \advance\scratchdimen\strutheight + \fi + % new + \global\sidefloatlinesdone\zerocount + \ifnum\sidefloatsidelines>\zerocount + \advance\scratchdimen\sidefloatsidelines\lineheight + \fi + % new + \global\setbox\floatbox\hbox + {\vbox + {\vskip\scratchdimen + \nointerlineskip + \box\floatbox + \ifnum\sidefloatalign=5 \vskip-\lineheight \fi}}% + \ifnum\sidefloattype<4 + \global\sidefloattopskip\zeropoint + \else\ifnum\sidefloattype>5 + \global\sidefloattopskip\zeropoint + \fi\fi + \global\sidefloatdownshift\zeropoint + \measuresidefloat + \ifroomforfloat \else + \tosssidefloat + \measuresidefloat + \stallsidefloat + \fi + \setsidefloat} + +\def\progresssidefloat + {\sidefloatprogress\sidefloatvsize + \iffloatflag + \advance\sidefloatprogress -\sidefloatpagetotal + \global\floatflagfalse + \else + \advance\sidefloatprogress -\pagetotal + \fi} + +\def\tosssidefloat + {\vfill\eject} + +\def\measuresidefloat + {\global\floatflagtrue + \global\sidefloatpagetotal \pagetotal % global + \ifnum\sidefloattype<4 + \global \sidefloatwidth \zeropoint + \else\ifnum\sidefloattype>5 + \global \sidefloatwidth \zeropoint + \else + \global \sidefloatwidth \wd\floatbox + \global\advance\sidefloatwidth \floatsideskip + \fi\fi + \ifdim\sidefloatwidth<\zeropoint + \global\sidefloatwidth\zeropoint + \fi + \global \sidefloathsize \hsize + \global\advance\sidefloathsize -\sidefloatwidth + \global \sidefloatheight \ht\floatbox + \global\advance\sidefloatheight \dp\floatbox + \global\advance\sidefloatheight \sidefloattopskip + \global \sidefloatvsize \sidefloatheight + \global\advance\sidefloatvsize \sidefloatpagetotal + \dimen0\sidefloatvsize + \dimen2\pagegoal + \relax + \ifcase\sidefloatmethod + % 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 + \dimen0=\pagegoal + \advance\dimen0 -\sidefloatvsize + \ifdim\dimen0<\sidefloatbottomskip + \global\advance\sidefloatvsize \dimen0 + \global\floatshorttrue + \pushpenalties + % why was this \global\holdinginserts\plusone + \else + \global\advance\sidefloatvsize \sidefloatbottomskip + \global\floatshortfalse + \fi + \global\roomforfloattrue + \fi} + +\def\setsidefloat% nilling everypar saves time and redudant pos's + {% removed here dec 2001 + % {\everypar\emptytoks\forgetall\verticalstrut\vskip-\struttotal}% + \ifnum\sidefloattype=4 \kern\sidefloattopskip \fi + \ifnum\sidefloattype=5 \kern\sidefloattopskip \fi + \edef\presidefloatdepth{\the\prevdepth}% + \nointerlineskip + \bgroup + \everypar\emptytoks + \parskip\zeropoint + %\checksidefloatshift + \setsidefloatskips + \logsidefloat + \relax + \ifcase\sidefloattype + % invalid + \or % backspace + \noindent\llap{\rlap{\box\floatbox}\hskip\sidefloatleftskip}\hfill + \or % leftedge + \noindent\llap{\box\floatbox\hskip\sidefloatleftskip}\hfill + \or % leftmargin + \noindent\llap{\box\floatbox\hskip\sidefloatleftskip}\hfill + \or % leftside + \noindent\box\floatbox\hfill + \or % rightside + \hfill\box\floatbox + \or % rightmargin + \hfill\rlap{\hskip\sidefloatrightskip\box\floatbox}% + \or % rightedge + \hfill\rlap{\hskip\sidefloatrightskip\box\floatbox}% + \or % cutspace + \hfill\rlap{\hskip\sidefloatrightskip\llap{\box\floatbox}}% + \fi + \egroup + \par + \kern-\sidefloatheight + \penalty10001 % oeps, this will change + \normalbaselines + \prevdepth\presidefloatdepth + % \noindent + \resetsidefloatparagraph + \ignorespaces} % not really needed + +\newcount\sidefloatparagraph + +\def\iffirstsidefloatparagraph + {\ifcase\sidefloatparagraph\or} + +% without sidefloat lines +% +% \def\setsidefloatparagraph +% {%\advance\sidefloatprogress \sidefloatbottomskip +% %\!!counta\sidefloatprogress +% \scratchdimen\sidefloatprogress +% \advance\scratchdimen \strutht +% \advance\scratchdimen -\roundingeps % new, needed in prikkels, prevent rounding errors +% \!!counta\scratchdimen +% \divide\!!counta \baselineskip +% \ifnum\!!counta>0 +% \hangindent \ifnum\sidefloattype>4 -\fi\sidefloatwidth +% \hangafter-\!!counta +% \fi +% \global\advance\sidefloatparagraph \plusone +% \iftracesidefloats +% \hskip-\sidefloatwidth +% \color[darkgray]% +% {\vrule\!!height.5\points\!!depth.5\points\!!width\sidefloatwidth +% %\hskip-.25\bodyfontsize\showstruts\strut\hskip.25\bodyfontsize}% +% \llap{\showstruts\strut\hskip.25\bodyfontsize}}% +% \fi} + +\def\setsidefloatparagraph + {%\advance\sidefloatprogress \sidefloatbottomskip + %\!!counta\sidefloatprogress + \scratchdimen\sidefloatprogress + \advance\scratchdimen \strutht + \advance\scratchdimen -\roundingeps % new, needed in prikkels, prevent rounding errors + \!!counta\scratchdimen + \divide\!!counta \baselineskip\relax + \ifnum\!!counta>0 + % new from here + \ifcase\sidefloatsidelines\else + \ifcase\sidefloatlinesdone + \global\sidefloatlinesdone\!!counta + \else + \scratchcounter\sidefloatlinesdone + \advance\scratchcounter-\!!counta + \global\advance\sidefloatsidelines-\scratchcounter + \fi + \fi + \ifnum\sidefloatsidelines>\zerocount + \scratchtoks\emptytoks + \scratchcounter\sidefloatsidelines + \scratchdimen\hsize + \advance\scratchdimen-\sidefloatwidth + \dorecurse\sidefloatsidelines + {\appendtoks \zeropoint \hsize \to \scratchtoks}% + \ifnum\!!counta>\sidefloatsidelines + \advance\!!counta -\sidefloatsidelines\relax + \advance\scratchcounter\!!counta + \dorecurse\!!counta + {\ifnum\sidefloattype>4 + \appendtoks \zeropoint \scratchdimen \to \scratchtoks + \else + \appendtoks \sidefloatwidth \scratchdimen \to \scratchtoks + \fi}% + \fi + \advance\scratchcounter \plusone + \parshape \scratchcounter \the\scratchtoks \zeropoint \hsize\relax + \else + % new till here + \hangindent \ifnum\sidefloattype>4 -\fi\sidefloatwidth + \hangafter-\!!counta + \fi + \fi + \global\advance\sidefloatparagraph \plusone + \iftracesidefloats + \hskip-\sidefloatwidth + \color[darkgray]% + {\vrule\!!height.5\points\!!depth.5\points\!!width\sidefloatwidth + %\hskip-.25\bodyfontsize\showstruts\strut\hskip.25\bodyfontsize}% + \llap{\showstruts\strut\hskip.25\bodyfontsize}}% + \fi} + +\def\resetsidefloatparagraph + {\global\sidefloatparagraph\zerocount } + +\def\dochecksidefloat + {\progresssidefloat + \ifdim\sidefloatprogress>\zeropoint + \setsidefloatparagraph + \else + \resetsidefloatparagraph + \fi + \parskip\ctxparskip} + +\def\checksidefloat + {\dochecksidefloat} + +\def\synchronizesidefloats + {\ifinner \else \checksidefloat \fi} + +\def\doadjustsidefloatdisplaylines + {\par + \vskip-\parskip + \noindent + \ignorespaces} + +\def\adjustsidefloatdisplaylines + {\aftergroup\doadjustsidefloatdisplaylines} + +\def\previoussidefloat + {\progresssidefloat + \ifdim\sidefloatprogress>\zeropoint \relax + \iffloatshort + \global\floatshortfalse + \tosssidefloat + \else + \kern\sidefloatprogress + \fi + \fi} + +\def\stallsidefloat + {\!!counta\pageshrink + \divide\!!counta \baselineskip + \advance\!!counta \plusone + \parskip\zeropoint + \dorecurse\!!counta{\line{}} + \kern-\!!counta\baselineskip + \penalty\zerocount } + +% We need to hook it into the other otr's. This code will move. + +\let\OTRONEflushsidefloats \flushsidefloats +\let\OTRONEsynchronizesidefloats\synchronizesidefloats + +% page-set +% +% \let\OTRSETflushsidefloats \forgetsidefloats +% \let\OTRSETsynchronizesidefloats\forgetsidefloats + +% page-mul +% +% \let\OTRMULflushsidefloats \forgetsidefloats +% \let\OTRMULsynchronizesidefloats\forgetsidefloats + +\def\synchronizesidefloats{\OTRcommand\synchronizesidefloats} +\def\flushsidefloats {\OTRcommand\flushsidefloats} + +\protect \endinput diff --git a/tex/context/base/page-sid.mkiv b/tex/context/base/page-sid.mkiv new file mode 100644 index 000000000..c30204a4e --- /dev/null +++ b/tex/context/base/page-sid.mkiv @@ -0,0 +1,795 @@ +%D \module +%D [ file=page-sid, +%D version=2000.10.20, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Side Floats, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Side Floats} + +\unprotect + +% problem: when too small, side effects; we need to determine the +% shift earlier so that we can act when shift < size +% +% \definefloat[edgefigure] +% \setupfloat +% [edgefigure] +% [rightmargindistance=-\rightmargintotal, +% leftmargindistance=-\rightmargintotal, +% default=outer] +% \starttext +% \placeedgefigure{}{\framed[width=12cm]{}} \input tufte +% \placeedgefigure{}{\framed[width=5cm]{}} \input tufte +% \placeedgefigure{}{\framed[width=4cm]{}} \input tufte +% \placeedgefigure{}{\framed[width=2cm]{}} \input tufte +% \stoptext + +% todo: dimexpr an dnumexpr + +% These macro deal with side floats. We started with Daniel +% Comenetz macros as published in TUGBoat Volume 14 (1993), +% No.\ 1: Anchored Figures at Either Margin. I extended and +% patched the macros to suite our needs which results in a +% messy module. Therefore, this module badly needs an update +% because it's now a mixture of old and new macros. + +% afhankelijke variabelen +% +% \overgap vervangen door \floatsidetopskip +% \sidegap vervangen door \floatsideskip +% \undergap vervangen door \floatsidebottomskip +% +% \prskp vervangen door \ctxparskip + +% toegevoegde macro's/aanroepen +% +% \logsidefloat : loginformatie +% \flushsidefloats : nodig voor koppen + +% recente wijzigingen: +% +% namen aangepast: \float... enz. i.p.v. \pic + +% Pas op: \EveryPar{\EveryPar{}\margetitel{whatever}} +% \plaatsfiguur[links]{}{} moet goed gaan. In dat geval +% begint de tekst terecht wat lager. + +\newdimen\sidefloatheight % includes the topskip +\newdimen\sidefloatwidth +\newdimen\sidefloathsize +\newdimen\sidefloatshift +\newdimen\sidefloatextrashift +\newdimen\sidefloatvsize \def\nofloatvsize{-1pt } +\newdimen\sidefloatprogress +\newdimen\sidefloatpagetotal + +\newbox\floatbottom + +\newcount\sidefloatsidelines +\newcount\sidefloatlinesdone + +% 1 = backspace +% 2 = leftedge +% 3 = leftmargin +% 4 = leftside +% 5 = rightside +% 6 = rightmargin +% 7 = rightedge +% 8 = cutspace + +\chardef\sidefloattype\zerocount + +\def\backspacefloat {\global\chardef\sidefloattype1 \putsidefloat} +\def\leftedgefloat {\global\chardef\sidefloattype2 \putsidefloat} +\def\leftmarginfloat {\global\chardef\sidefloattype3 \putsidefloat} +\def\leftfloat {\global\chardef\sidefloattype4 \putsidefloat} +\def\rightfloat {\global\chardef\sidefloattype5 \putsidefloat} +\def\rightmarginfloat {\global\chardef\sidefloattype6 \putsidefloat} +\def\rightedgefloat {\global\chardef\sidefloattype7 \putsidefloat} +\def\cutspacefloat {\global\chardef\sidefloattype8 \putsidefloat} + +\let\marginfloat \cutspacefloat + +\newif\ifroomforfloat +\newif\iffloatshort +\newif\iffloatflag +\newif\iffloatrighteqo +\newif\iffloatlefteqo + +\newdimen\sidefloatleftskip +\newdimen\sidefloatrightskip +\newdimen\sidefloatmaximum + +\def\checksidefloatshift + {\ifdim\sidefloatmaximum>\zeropoint + \ifcase\sidefloattype + % invalid + \or + % backspace + \or + \global\sidefloatshift\dimexpr + -\sidefloatmaximum + -\rightorleftpageaction \leftedgedistance \rightedgedistance + -\rightorleftpageaction \leftmarginwidth \rightmarginwidth + -\rightorleftpageaction \leftmargindistance \rightmargindistance + -\compensatedinnermakeupmargin + \relax + \or + \global\sidefloatshift\dimexpr + -\sidefloatmaximum + -\rightorleftpageaction \leftmargindistance \rightmargindistance + -\compensatedinnermakeupmargin + \relax + \or + % left + \or + % right + \or + \global\sidefloatshift\dimexpr + -\sidefloatmaximum + -\rightorleftpageaction \leftmargindistance \rightmargindistance + -\compensatedinnermakeupmargin + \relax + \or + \global\sidefloatshift\dimexpr + -\sidefloatmaximum + -\rightorleftpageaction \leftedgedistance \rightedgedistance + -\rightorleftpageaction \leftmarginwidth \rightmarginwidth + -\rightorleftpageaction \leftmargindistance \rightmargindistance + -\compensatedinnermakeupmargin + \relax + \or + % cutspace + \fi + \fi} + +\def\setsidefloatskips + {\global\sidefloatrightskip\zeropoint + \global\sidefloatleftskip \zeropoint + \ifcase\sidefloattype + \or % backspace + \global\sidefloatleftskip\dimexpr + +\rightorleftpageaction \backspace \cutspace + +\compensatedinnermakeupmargin + \relax + \or % leftedge + \global\sidefloatleftskip\dimexpr + +\rightorleftpageaction \leftmargindistance \rightmargindistance + +\rightorleftpageaction \leftmarginwidth \rightmarginwidth + +\rightorleftpageaction \leftedgedistance \rightedgedistance + +\compensatedinnermakeupmargin + \relax + \or % leftmargin + \global\sidefloatleftskip\dimexpr + +\rightorleftpageaction \leftmargindistance \rightmargindistance + +\compensatedinnermakeupmargin + \relax + \or % leftside + \or % rightside + \or % rightmargin + \global\sidefloatrightskip\dimexpr + +\rightorleftpageaction \rightmargindistance \leftmargindistance + +\compensatedinnermakeupmargin + \relax + \or % rightedge + \global\sidefloatrightskip\dimexpr + +\rightorleftpageaction \rightmargindistance \leftmargindistance + +\rightorleftpageaction \rightmarginwidth \leftmarginwidth + +\rightorleftpageaction \rightedgedistance \leftedgedistance + +\compensatedinnermakeupmargin + \relax + \or % cutspace + \global\sidefloatrightskip\dimexpr + +\rightorleftpageaction \cutspace \backspace + +\compensatedinnermakeupmargin + \relax + \fi + \ifdim\sidefloatrightskip>\zeropoint \doglobal\advance\sidefloatrightskip\rightskip \fi + \ifdim\sidefloatleftskip >\zeropoint \doglobal\advance\sidefloatleftskip \leftskip \fi} + +% eq is still crap + +\ifx\normalleqno\undefined + + \let\floatrighteqo=\eqno + \let\floatleftleqo=\leqno + +\else + + \let\floatrighteqo=\normaleqno + \let\floatleftleqo=\normalleqno + +\fi + +% Watch it even more! In inner, gaat't mis omdat daar +% pagetotal enz niet zijn aangepast. Inner kan overigens niet +% betrouwbaar worden getest! + +\newif\iftracesidefloats + +\def\flushsidefloats + {\par + \!!heighta\sidefloatvsize + \advance\!!heighta -\pagetotal + \ifnum\!!heighta>\zeropoint + \global\advance\sidefloatvsize -\sidefloatbottomskip + \ifdim\!!heighta>\zeropoint + \bgroup + \let\flushsidefloats\relax + \forgetall + \doloop + {\strut + \iftracesidefloats + \color[darkgray]% + {\baselinerulefalse + \boxrulewidth.5\points + \ruledhbox{\strut\kern\sidefloatwidth}}% + \fi + \par + \!!heighta\sidefloatvsize + \advance\!!heighta -\pagetotal + \ifdim\!!heighta>\zeropoint + \ifnum\recurselevel>\plushundred + \exitloop + \fi + \else + \exitloop + \fi}% + \egroup + \ifdim\parskip>\zeropoint + \ifdim\sidefloatbottomskip>\parskip + \nowhitespace + \vskip\sidefloatbottomskip + \fi + \fi + \else\ifdim\sidefloatbottomskip>\parskip + \vskip\sidefloatbottomskip + \fi\fi + \fi + % not entirely the same as \forgetsidefloats + \global\sidefloatvsize\nofloatvsize + % \global\sidefloatsidelines\zerocount % no, we flush before a side float + \global\floatshortfalse % so this will get lost + % also here if used at all \global\holdinginserts\zerocount + \global\floatflagfalse} + +\def\dochecksidefloatafterpar + {\dochecksidefloat + \ifdim\oldpagetotal=\pagetotal \else + \global\let\checksidefloat\dochecksidefloat + \flushsidefloats + \global\sidefloatsidelines\zerocount % here ! + \fi} + +\def\flushsidefloatsafterpar + {\xdef\oldpagetotal{\the\pagetotal}% + \global\let\checksidefloat\dochecksidefloatafterpar} + +\def\forgetsidefloats + {\global\sidefloatvsize\nofloatvsize + \global\sidefloatsidelines\zerocount + % also here if used at all \global\holdinginserts\zerocount + \global\floatshortfalse + \global\floatflagfalse} + +\let\logsidefloat=\relax + +\def\pushpenalties % needed ? and right + {\widowpenalty\plusone + \clubpenalty\plustwo + \brokenpenalty\plusone + \let\pushpenalties\relax + \edef\poppenalties + {\widowpenalty \the\widowpenalty + \clubpenalty \the\clubpenalty + \brokenpenalty\the\brokenpenalty + \let\poppenalties\relax}} + +% shouldn;t that be: +% +% \def\pushpenalties % needed? +% {\let\pushpenalties\relax +% \edef\poppenalties +% {\widowpenalty \the\widowpenalty +% \clubpenalty \the\clubpenalty +% \brokenpenalty\the\brokenpenalty +% \let\poppenalties\relax}% +% \widowpenalty\plusone +% \clubpenalty\plustwo +% \brokenpenalty\plusone} + +\let\poppenalties=\relax + +\def\restorepenalties + {\ifnum\outputpenalty=\!!tenthousand\else + \penalty\outputpenalty + \fi} + +\def\sidefloatoutput + {\iffloatshort + \unvbox\normalpagebox + \setbox\floatbottom\lastbox + \ifdim\wd\floatbottom>\sidefloathsize + \penalty-201 + \box\floatbottom + \else + \ifvoid\floatbottom + \else + \restoreleftindent + \ifdim\wd\floatbottom<\sidefloathsize + \parskip\zeropoint + %\noindent + \ifinner\else\vadjust{\penalty\minusone}\fi + \iffloatlefteqo + \global\floatlefteqofalse + \else + \global\advance\sidefloathsize -\wd\floatbottom + \iffloatrighteqo + \global\floatrighteqofalse + \else + \global\divide\sidefloathsize \plustwo + \fi + \hskip\sidefloathsize + \fi + \fi + \box\floatbottom + \restorepenalties + \fi + \fi + % why was this \global\holdinginserts\zerocount + \global\floatshortfalse + \else + \finalsidefloatoutput % new + \global\sidefloatvsize\nofloatvsize + \global\sidefloatsidelines\zerocount + % we can end up in fig lock, so \global\holdinginserts\zerocount here too ? + \poppenalties + \fi} + +\def\finalsidefloatoutput% new + {\finaloutput\unvbox\normalpagebox} + +\def\restoreleftindent + {\relax \ifnum\sidefloattype>4 \else + \parskip\zeropoint % here ? + \ifdim\sidefloatwidth>\zeropoint % new, see prikkels + \noindent + \ifinner\else\vadjust{\penalty\minusone}\fi + \hskip\sidefloatwidth\relax + %\else + % we have a margin or edge float + \fi + \fi} + +\ifx\normaleqno\undefined + + \def\normaleqno + {\iffloatshort + \global\floatrighteqotrue + \fi + \floatrighteqo} + +\else + + \def\eqno + {\iffloatshort + \global\floatrighteqotrue + \fi + \floatrighteqo} + +\fi + +% externfiguur -> grid =ja|hoogte|diepte|halveregel|passend -> helemaal in details +% stelplaatsblokin -> zijuitlijnen=hoogte|diepte|regel|halveregel|grid -> halveregel in 'details' + +% replacement for below +% +% \global\setbox\floatbox\hbox % no \hskip, but \kern here +% {\ifcase\sidefloattype +% \vbox{#1}% +% \or % 1 +% \hskip\sidefloatleftshift +% \hskip\sidefloatshift +% \vbox{#1}% +% \kern-\sidefloatextrashift +% \or % 2 +% \hskip\sidefloatshift +% \vbox{#1}% +% \kern-\sidefloatextrashift +% \or % 3 +% \hskip\sidefloatshift +% \vbox{#1}% +% \kern-\sidefloatextrashift +% \or % 4 +% \hskip\sidefloatleftshift +% \hskip\sidefloatshift +% \vbox{#1\removedepth}% +% \kern-\sidefloatextrashift +% \or % 5 +% \hskip-\sidefloatextrashift +% \vbox{#1}% +% \kern\sidefloatshift +% \kern\sidefloatrightshift +% \or % 6 +% \hskip-\sidefloatextrashift +% \vbox{#1}% +% \kern\sidefloatshift +% \or % 7 +% \hskip-\sidefloatextrashift +% \vbox{#1}% +% \kern\sidefloatshift +% \or % 8 +% \hskip-\sidefloatextrashift +% \vbox{#1}% +% \kern\sidefloatshift +% \kern\sidefloatrightshift +% \fi}% +% +% keep this ^ + +\def\repositionsidefloat#1% + {\global\setbox\floatbox\hbox % no \hskip, but \kern here + {\ifnum\sidefloattype=\plusfour + \hskip\sidefloatleftshift + \else\ifnum\sidefloattype=\plusone + \hskip\sidefloatleftshift + \fi\fi + \ifnum\sidefloattype>\plusfour + \hskip-\sidefloatextrashift + \else + \hskip\sidefloatshift + \fi + \vbox{#1\ifnum\sidefloatalign=\plusfour \removedepth\fi}% + \ifnum\sidefloattype>\plusfour + \kern\sidefloatshift + \else + \kern-\sidefloatextrashift + \fi + \ifnum\sidefloattype=8 + \kern\sidefloatrightshift + \else\ifnum\sidefloattype=\plusfive + \kern\sidefloatrightshift + \fi\fi}} + +\def\putsidefloat#1% grid (4) is rather experimental + {\par + \whitespace + % moved here dec 2001 + {\everypar\emptytoks\forgetall\verticalstrut\vskip-\struttotal}% moved + \checksidefloatshift + \ifdim\sidefloatshift=\zeropoint \relax + \ifnum\sidefloattype=\plusfour + \global\advance\sidefloatshift\sidefloatextrashift + \global\sidefloatextrashift\zeropoint + \else\ifnum\sidefloattype=\plusfive + \global\advance\sidefloatshift\sidefloatextrashift + \global\sidefloatextrashift\zeropoint + \fi\fi + \else + \ifnum\sidefloattype<\plusfour + \global\chardef\sidefloattype\plusfour + \else\ifnum\sidefloattype>\plusfive + \global\chardef\sidefloattype\plusfive + \fi\fi + \fi + \previoussidefloat + \stallsidefloat + \repositionsidefloat{#1}% + \ifnum\sidefloatalign=\plusfour + \getnoflines{\ht\floatbox}% + \scratchdimen\noflines\lineheight + \advance\scratchdimen-\strutdepth + \getrawnoflines\sidefloattopskip + \advance\scratchdimen\noflines\lineheight + % todo: maybe rounding problem here + % \global\setbox\floatbox\hbox{\lower\lineheight\box\floatbox}% + \global\setbox\floatbox\hbox{\lower\strutdepth\box\floatbox}% + \global\ht\floatbox\scratchdimen + \global\dp\floatbox\zeropoint + \fi + \ifcase\sidefloatalign \else + \global\sidefloattopskip\zeropoint + \fi + \scratchdimen + \ifnum\sidefloattype<\plusfour + \sidefloattopskip + \else\ifnum\sidefloattype>\plusfive + \sidefloattopskip + \else + \zeropoint + \fi\fi + % the top of the box is at the previous baseline + \ifcase\sidefloatalign + % 0 normal + \advance\scratchdimen\strutdepth % == \sidefloattopoffset + \or % 1 height + \advance\scratchdimen\strutdepth % == \sidefloattopoffset + \or % 2 line + \or % 3 depth + \advance\scratchdimen\lineheight + \advance\scratchdimen\strutdepth + \or % 4 grid + \scratchdimen\zeropoint + \or + \advance\scratchdimen\strutheight + \fi + % new + \global\sidefloatlinesdone\zerocount + \ifnum\sidefloatsidelines>\zerocount + \advance\scratchdimen\sidefloatsidelines\lineheight + \fi + % new + \global\setbox\floatbox\hbox + {\vbox + {\vskip\scratchdimen + \nointerlineskip + \box\floatbox + \ifnum\sidefloatalign=\plusfive \vskip-\lineheight \fi}}% + \ifnum\sidefloattype<\plusfour + \global\sidefloattopskip\zeropoint + \else\ifnum\sidefloattype>\plusfive + \global\sidefloattopskip\zeropoint + \fi\fi + \global\sidefloatdownshift\zeropoint + \measuresidefloat + \ifroomforfloat \else + \vfill\eject % inline \tosssidefloat + \measuresidefloat + \stallsidefloat + \fi + \setsidefloat} + +\def\progresssidefloat + {\sidefloatprogress\sidefloatvsize + \advance\sidefloatprogress-\iffloatflag\sidefloatpagetotal\global\floatflagfalse\else\pagetotal\fi} + +\def\measuresidefloat + {\global\floatflagtrue + \global\sidefloatpagetotal \pagetotal % global + \ifnum\sidefloattype<\plusfour + \global \sidefloatwidth \zeropoint + \else\ifnum\sidefloattype>\plusfive + \global \sidefloatwidth \zeropoint + \else + \global \sidefloatwidth \wd\floatbox + \global\advance\sidefloatwidth \floatsideskip + \fi\fi + \ifdim\sidefloatwidth<\zeropoint + \global\sidefloatwidth\zeropoint + \fi + \global \sidefloathsize \hsize + \global\advance\sidefloathsize -\sidefloatwidth + \global \sidefloatheight \ht\floatbox + \global\advance\sidefloatheight \dp\floatbox + \global\advance\sidefloatheight \sidefloattopskip + \global \sidefloatvsize \sidefloatheight + \global\advance\sidefloatvsize \sidefloatpagetotal + \dimen0\sidefloatvsize + \dimen2\pagegoal + \relax + \ifcase\sidefloatmethod + % 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 + \dimen0=\pagegoal + \advance\dimen0 -\sidefloatvsize + \ifdim\dimen0<\sidefloatbottomskip + \global\advance\sidefloatvsize \dimen0 + \global\floatshorttrue + \pushpenalties + % why was this \global\holdinginserts\plusone + \else + \global\advance\sidefloatvsize \sidefloatbottomskip + \global\floatshortfalse + \fi + \global\roomforfloattrue + \fi} + +\def\setsidefloat% nilling everypar saves time and redudant pos's + {% removed here dec 2001 + % {\everypar\emptytoks\forgetall\verticalstrut\vskip-\struttotal}% + \ifnum\sidefloattype=\plusfour \kern\sidefloattopskip \fi + \ifnum\sidefloattype=\plusfive \kern\sidefloattopskip \fi + \edef\presidefloatdepth{\the\prevdepth}% + \nointerlineskip + \bgroup + \everypar\emptytoks + \parskip\zeropoint + \setsidefloatskips + \logsidefloat + \relax + \ifcase\sidefloattype + % invalid + \or % backspace + \noindent\llap{\rlap{\box\floatbox}\hskip\sidefloatleftskip}\hfill + \or % leftedge + \noindent\llap{\box\floatbox\hskip\sidefloatleftskip}\hfill + \or % leftmargin + \noindent\llap{\box\floatbox\hskip\sidefloatleftskip}\hfill + \or % leftside + \noindent\box\floatbox\hfill + \or % rightside + \hfill\box\floatbox + \or % rightmargin + \hfill\rlap{\hskip\sidefloatrightskip\box\floatbox}% + \or % rightedge + \hfill\rlap{\hskip\sidefloatrightskip\box\floatbox}% + \or % cutspace + \hfill\rlap{\hskip\sidefloatrightskip\llap{\box\floatbox}}% + \fi + \egroup + \par +\ifgridsnapping + \getrawnoflines\sidefloatheight + \sidefloatheight=\noflines\lineheight +\fi + \kern-\sidefloatheight + \penalty10001 % oeps, this will change + \normalbaselines + \prevdepth\presidefloatdepth + % \noindent + \resetsidefloatparagraph + \ignorespaces} % not really needed + +\newcount\sidefloatparagraph + +\def\iffirstsidefloatparagraph + {\ifcase\sidefloatparagraph\or} + +% without sidefloat lines +% +% \def\setsidefloatparagraph +% {%\advance\sidefloatprogress \sidefloatbottomskip +% %\!!counta\sidefloatprogress +% \scratchdimen\sidefloatprogress +% \advance\scratchdimen \strutht +% \advance\scratchdimen -\roundingeps % new, needed in prikkels, prevent rounding errors +% \!!counta\scratchdimen +% \divide\!!counta \baselineskip +% \ifnum\!!counta>0 +% \hangindent \ifnum\sidefloattype>4 -\fi\sidefloatwidth +% \hangafter-\!!counta +% \fi +% \global\advance\sidefloatparagraph \plusone +% \iftracesidefloats +% \hskip-\sidefloatwidth +% \color[darkgray]% +% {\vrule\!!height.5\points\!!depth.5\points\!!width\sidefloatwidth +% %\hskip-.25\bodyfontsize\showstruts\strut\hskip.25\bodyfontsize}% +% \llap{\showstruts\strut\hskip.25\bodyfontsize}}% +% \fi} + +\def\setsidefloatparagraph + {%\advance\sidefloatprogress \sidefloatbottomskip + %\!!counta\sidefloatprogress + \scratchdimen\sidefloatprogress + \advance\scratchdimen \strutht + \advance\scratchdimen -\roundingeps % new, needed in prikkels, prevent rounding errors + \!!counta\scratchdimen + \divide\!!counta \baselineskip\relax + \ifnum\!!counta>0 + % new from here + \ifcase\sidefloatsidelines\else + \ifcase\sidefloatlinesdone + \global\sidefloatlinesdone\!!counta + \else + \scratchcounter\sidefloatlinesdone + \advance\scratchcounter-\!!counta + \global\advance\sidefloatsidelines-\scratchcounter + \fi + \fi + \ifnum\sidefloatsidelines>\zerocount + \scratchtoks\emptytoks + \scratchcounter\sidefloatsidelines + \scratchdimen\hsize + \advance\scratchdimen-\sidefloatwidth + \dorecurse\sidefloatsidelines + {\appendtoks \zeropoint \hsize \to \scratchtoks}% + \ifnum\!!counta>\sidefloatsidelines + \advance\!!counta -\sidefloatsidelines\relax + \advance\scratchcounter\!!counta + \dorecurse\!!counta + {\ifnum\sidefloattype>\plusfour + \appendtoks \zeropoint \scratchdimen \to \scratchtoks + \else + \appendtoks \sidefloatwidth \scratchdimen \to \scratchtoks + \fi}% + \fi + \advance\scratchcounter \plusone + \parshape \scratchcounter \the\scratchtoks \zeropoint \hsize\relax + \else + % new till here + \hangindent \ifnum\sidefloattype>\plusfour -\fi\sidefloatwidth + \hangafter-\!!counta + \fi + \fi + \global\advance\sidefloatparagraph \plusone + \iftracesidefloats + \hskip-\sidefloatwidth + \color[darkgray]% + {\vrule\!!height.5\points\!!depth.5\points\!!width\sidefloatwidth + %\hskip-.25\bodyfontsize\showstruts\strut\hskip.25\bodyfontsize}% + \llap{\showstruts\strut\hskip.25\bodyfontsize}}% + \fi} + +\def\resetsidefloatparagraph + {\global\sidefloatparagraph\zerocount} + +\def\dochecksidefloat + {\progresssidefloat + \ifdim\sidefloatprogress>\zeropoint + \setsidefloatparagraph + \else + \resetsidefloatparagraph + \fi + \parskip\ctxparskip} + +\let\checksidefloat\dochecksidefloat + +\def\synchronizesidefloats + {\ifinner \else \checksidefloat \fi} + +\def\doadjustsidefloatdisplaylines + {\par + % not in mkiv: \vskip-\parskip + \noindent + \ignorespaces} + +\def\adjustsidefloatdisplaylines + {\aftergroup\doadjustsidefloatdisplaylines} + +\def\previoussidefloat + {\progresssidefloat + \ifdim\sidefloatprogress>\zeropoint \relax + \iffloatshort + \global\floatshortfalse + \vfill\eject % inline \tosssidefloat + \else + \kern\sidefloatprogress + \fi + \fi} + +\def\stallsidefloat + {\!!counta\pageshrink + \divide\!!counta \baselineskip + \advance\!!counta \plusone + \parskip\zeropoint + \dorecurse\!!counta{\line{}} + \kern-\!!counta\baselineskip + \penalty\zerocount } + +% We need to hook it into the other otr's. This code will move. + +\let\OTRONEflushsidefloats \flushsidefloats +\let\OTRONEsynchronizesidefloats\synchronizesidefloats + +% page-set +% +% \let\OTRSETflushsidefloats \forgetsidefloats +% \let\OTRSETsynchronizesidefloats\forgetsidefloats + +% page-mul +% +% \let\OTRMULflushsidefloats \forgetsidefloats +% \let\OTRMULsynchronizesidefloats\forgetsidefloats + +\registerotrcommand\synchronizesidefloats % \def\synchronizesidefloats{\OTRcommand\synchronizesidefloats} +\registerotrcommand\flushsidefloats % \def\flushsidefloats {\OTRcommand\flushsidefloats} + +\protect \endinput diff --git a/tex/context/base/page-spr.mkii b/tex/context/base/page-spr.mkii new file mode 100644 index 000000000..06947a36a --- /dev/null +++ b/tex/context/base/page-spr.mkii @@ -0,0 +1,104 @@ +%D \module +%D [ file=page-spr, +%D version=2002.11.11, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Spreading, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Spreading} + +% This module is experimental and not yet official! + +\unprotect + +\newbox\spreadbox +\newif \ifinspread + +\chardef\showspreadmode=1 + +% beware, ugly overload, to be redone + +\def\normalsettextpagecontent#1#2#3% #2 and #3 will disappear + {\setbox#1\hbox + {\vbox to \textheight + {\offinterlineskip + \freezetextwidth + \hsize\textwidth % local variant of \sethsize + \boxmaxdepth\maxdepth + \noindent % content can be < \hsize + \dopagecontents#2#3}}% + \dp#1\zeropoint + \setbox#1\hbox to \makeupwidth + {\ifinspread + \ifvoid\spreadbox + \global\setbox\spreadbox\box#1% + \copy\spreadbox\hss % left page + \else + % prevent duplicate writes in normal run + \ifarrangingpages \else \ifcase\showspreadmode + \global\setbox\spreadbox\null + \wd\spreadbox\makeupwidth + \ht\spreadbox\textheight + \fi \fi + \hss\box\spreadbox % right page + \fi + \else + \hss\box#1\hss % never change the \hss's + \fi}} + +\def\doflushspread + {\ifinspread \ifvoid\spreadbox\else + % this page will be discarded later + \null \page + \fi \fi } + +\def\startspread + {\bgroup + \ifdoublesided + \page[\v!left]% + %\setsystemmode{spread}% + \inspreadtrue + \scratchdimen2\textwidth + \advance\scratchdimen2\backspace + \expanded{\setuplayout[\c!textwidth=\the\scratchdimen]}% + \def\startspread{\bgroup\let\stopspread\egroup}% + \let\stopspread\dostopspread + \else + \let\stopspread\egroup + \fi} + +\let\stopspread\relax + +\def\dostopspread + {\kern\zeropoint\page + \inspreadfalse + \setuplayout[\c!textwidth=\textwidth] + \page[\v!left] + \egroup} + +\protect \endinput + +% texexec --arr --pdf test +% +% \setuplayout[width=middle] +% \setuppapersize[A4][A3,landscape] +% \setuppagenumbering[alternative=doublesided] +% \setuparranging[2UP] +% +% \starttext +% +% \dorecurse{3}{\input tufte } +% +% \startspread +% \dorecurse{10}{\input tufte } +% \stopspread +% +% \dorecurse{3}{\input tufte } +% +% \stoptext diff --git a/tex/context/base/page-spr.mkiv b/tex/context/base/page-spr.mkiv new file mode 100644 index 000000000..75b91dff7 --- /dev/null +++ b/tex/context/base/page-spr.mkiv @@ -0,0 +1,103 @@ +%D \module +%D [ file=page-spr, +%D version=2002.11.11, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Spreading, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Spreading} + +% This module is experimental and not yet official! + +\unprotect + +\newbox\spreadbox +\newif \ifinspread + +\chardef\showspreadmode\plusone + +% beware, ugly overload, to be redone + +\def\normalsettextpagecontent#1#2#3% #2 and #3 will disappear + {\setbox#1\hbox + {\setlayoutcomponentattribute\v!page\v!text + \vbox \layoutcomponentboxattribute to \textheight + {\offinterlineskip + \freezetextwidth + \hsize\textwidth % local variant of \sethsize + \boxmaxdepth\maxdepth + \noindent % content can be < \hsize + \dopagecontents#2#3}}% + \dp#1\zeropoint + \setbox#1\hbox to \makeupwidth + {\ifinspread + \ifvoid\spreadbox + \global\setbox\spreadbox\box#1% + \copy\spreadbox\hss % left page + \else + % prevent duplicate writes in normal run + \ifarrangingpages \else \ifcase\showspreadmode + \global\setbox\spreadbox\null + \wd\spreadbox\makeupwidth + \ht\spreadbox\textheight + \fi \fi + \hss\box\spreadbox % right page + \fi + \else + \hss\box#1\hss % never change the \hss's + \fi}} + +\def\doflushspread + {\ifinspread \ifvoid\spreadbox\else + % this page will be discarded later + \null \page + \fi \fi } + +\unexpanded\def\startspread + {\bgroup + \ifdoublesided + \page[\v!left]% + %\setsystemmode{spread}% + \inspreadtrue + \expanded{\setuplayout[\c!textwidth=\the\dimexpr2\textwidth+2\backspace\relax]}% + \unexpanded\def\startspread{\bgroup\let\stopspread\egroup}% + \let\stopspread\dostopspread + \else + \let\stopspread\egroup + \fi} + +\let\stopspread\relax + +\def\dostopspread + {\kern\zeropoint\page + \inspreadfalse + \setuplayout[\c!textwidth=\textwidth] + \page[\v!left] + \egroup} + +\protect \endinput + +% texexec --arr --pdf test +% +% \setuplayout[width=middle] +% \setuppapersize[A4][A3,landscape] +% \setuppagenumbering[alternative=doublesided] +% \setuparranging[2UP] +% +% \starttext +% +% \dorecurse{3}{\input tufte } +% +% \startspread +% \dorecurse{10}{\input tufte } +% \stopspread +% +% \dorecurse{3}{\input tufte } +% +% \stoptext diff --git a/tex/context/base/page-str.lua b/tex/context/base/page-str.lua new file mode 100644 index 000000000..c4d1957c3 --- /dev/null +++ b/tex/context/base/page-str.lua @@ -0,0 +1,221 @@ +if not modules then modules = { } end modules ['page-str'] = { + version = 1.001, + comment = "companion to page-str.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- work in progresss .. unfinished + +local concat = table.concat + +local find_tail, write_node, free_node, copy_nodelist = node.slide, node.write, node.free, node.copy_list +local vpack_nodelist, hpack_nodelist = node.vpack, node.hpack +local texdimen, texbox = tex.dimen, tex.box + +local new_kern = nodes.kern +local new_glyph = nodes.glyph + +local trace_collecting = false trackers.register("streams.collecting", function(v) trace_collecting = v end) +local trace_flushing = false trackers.register("streams.flushing", function(v) trace_flushing = v end) + +streams = streams or { } + +local data, name, stack = { }, nil, { } + +function streams.enable(newname) + if newname == "default" then + name = nil + else + name = newname + end +end + +function streams.disable() + name = stack[#stack] +end + +function streams.start(newname) + table.insert(stack,name) + name = newname +end + +function streams.stop(newname) + name = table.remove(stack) +end + +function streams.collect(head,where) + if name and head and name ~= "default" then + local tail = node.slide(head) + local dana = data[name] + if not dana then + dana = { } + data[name] = dana + end + local last = dana[#dana] + if last then + local tail = find_tail(last) + tail.next, head.prev = head, tail + elseif last == false then + dana[#dana] = head + else + dana[1] = head + end + if trace_collecting then + logs.report("streams","appending snippet '%s' to slot %s",name,#dana) + end + return nil, true + else + return head, false + end +end + +function streams.push(thename) + if not thename or thename == "" then + thename = name + end + if thename and thename ~= "" then + local dana = data[thename] + if dana then + dana[#dana+1] = false + if trace_collecting then + logs.report("streams","pushing snippet '%s'",thename) + end + end + end +end + +function streams.flush(name,copy) -- problem: we need to migrate afterwards + local dana = data[name] + if dana then + local dn = #dana + if dn == 0 then + -- nothing to flush + elseif copy then + if trace_flushing then + logs.report("streams","flushing copies of %s slots of '%s'",dn,name) + end + for i=1,dn do + local di = dana[i] + if di then + write_node(copy_nodelist(di.list)) -- list, will be option + end + end + if copy then + data[name] = nil + end + else + if trace_flushing then + logs.report("streams","flushing %s slots of '%s'",dn,name) + end + for i=1,dn do + local di = dana[i] + if di then + write_node(di.list) -- list, will be option + di.list = nil + free_node(di) + end + end + end + end +end + +function streams.synchronize(list) -- this is an experiment ! + -- we don't optimize this as we want to trace in detail + list = aux.settings_to_array(list) + local max = 0 + if trace_flushing then + logs.report("streams","synchronizing list: %s",concat(list," ")) + end + for i=1,#list do + local dana = data[list[i]] + if dana then + local n = #dana + if n > max then + max = n + end + end + end + if trace_flushing then + logs.report("streams","maximum number of slots: %s",max) + end + for m=1,max do + local height, depth = 0, 0 + for i=1,#list do + local name = list[i] + local dana = data[name] + local slot = dana[m] + if slot then + local vbox = vpack_nodelist(slot) + local ht, dp = vbox.height, vbox.depth + if ht > height then + height = ht + end + if dp > depth then + depth = dp + end + dana[m] = vbox + if trace_flushing then + logs.report("streams","slot %s of '%s' is packed to height %s and depth %s",m,name,ht,dp) + end + end + end + if trace_flushing then + logs.report("streams","slot %s has max height %s and max depth %s",m,height,depth) + end + local strutht, strutdp = texdimen.globalbodyfontstrutheight, texdimen.globalbodyfontstrutdepth + local struthtdp = strutht + strutdp + for i=1,#list do + local name = list[i] + local dana = data[name] + local vbox = dana[m] + if vbox then + local delta_height = height - vbox.height + local delta_depth = depth - vbox.depth + if delta_height > 0 or delta_depth > 0 then + if false then + -- actually we need to add glue and repack + vbox.height, vbox.depth = height, depth + if trace_flushing then + logs.report("streams","slot %s of '%s' with delta (%s,%s) is compensated",m,i,delta_height,delta_depth) + end + else + -- this is not yet ok as we also need to keep an eye on vertical spacing + -- so we might need to do some splitting or whatever + local tail = vbox.list and find_tail(vbox.list) + local n, delta = 0, delta_height -- for tracing + while delta > 0 do + -- we need to add some interline penalties + local line = copy_nodelist(tex.box.strutbox) + line.height, line.depth = strutht, strutdp + if tail then + tail.next, line.prev = line, tail + end + tail = line + n, delta = n +1, delta - struthtdp + end + dana[m] = vpack_nodelist(vbox.list) + vbox.list = nil + free_node(vbox) + if trace_flushing then + logs.report("streams","slot %s:%s with delta (%s,%s) is compensated by %s lines",m,i,delta_height,delta_depth,n) + end + end + end + else + -- make dummy + end + end + end +end + +tasks.appendaction("mvlbuilders", "normalizers", "streams.collect") + +tasks.disableaction("mvlbuilders", "streams.collect") + +function streams.initialize() + tasks.enableaction ("mvlbuilders", "streams.collect") +end + +-- todo: remove empty last { }'s diff --git a/tex/context/base/page-str.mkii b/tex/context/base/page-str.mkii new file mode 100644 index 000000000..cfaebe398 --- /dev/null +++ b/tex/context/base/page-str.mkii @@ -0,0 +1,376 @@ +%D \module +%D [ file=page-str, +%D version=2006.03.21, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Page Streams, +%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 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 +%D playing with the code, I decided to make it into a component +%D that can be used to construct all kind of stream related +%D mechanisms. Because I could apply this feature in a project, +%D there is some additional code here (related to graphics). +%D +%D These macros were written while listening to and watching the DVD +%D \quotation {Rush In Rio}. + +% not yet ok in mkiv ... marknotes + +\unprotect + +% taco, what is the best way to append a otr chunk (insert pagediscards?) + +\let\currentoutputstream\s!default + +\newtoks\defaultstreamoutput \defaultstreamoutput=\OTRONEoutput + +\newtoks\normalstreamoutput \normalstreamoutput={\saveoutputstream[\currentoutputstream]} + +\newcount\streampenalty \streampenalty=-101010101 + +\ifx\multicolumnseject\undefined \else + \let\normalmulticolumnseject\multicolumnseject + \def\multicolumnseject{\ifinoutputstream\else\normalmulticolumnseject\fi} +\fi + +\newif\ifinoutputstream + +\newtoks \everyenableoutputstream + +\appendtoks + \flushsidefloats +\to \everyenableoutputstream + +\def\enableoutputstream[#1]% + {\the\everyenableoutputstream + \finishoutputstream + \writestatus{otr}{switching to output stream #1}% + \inoutputstreamtrue + \xdef\currentoutputstream{#1}} + +\def\disableoutputstream + {\finishoutputstream + \writestatus{otr}{switching to default output stream}% + \inoutputstreamfalse + \global\let\currentoutputstream\s!default} + +\def\useoutputstream[#1]% + {\writestatus{otr}{using output stream #1}% + \xdef\currentoutputstream{#1}} + +\def\handlestreamoutput + {\doifelse\currentoutputstream\s!default + {\ifnum\outputpenalty=\streampenalty + \ifvoid\normalpagebox \else + \unvbox\normalpagebox + \fi + \else + \the\defaultstreamoutput + \fi} + {\the\normalstreamoutput}} + +\OTRONEoutput{\handlestreamoutput} + +\def\defineoutputstream[#1]% + {\doifundefined{otrs:#1}{\expandafter\newbox\csname otrs:#1\endcsname}} + +\def\outputstreamtag#1% + {\csname otrs:#1\endcsname} + +\def\finishoutputstream % todo: installoutput + {\endgraf + \penalty\streampenalty + \endgraf} + +\def\saveoutputstream[#1]% + {\writestatus{otr}{saving otr stream #1}% + \ifvoid\normalpagebox + \global\setbox\outputstreamtag{#1}\emptybox + \else + \global\setbox\outputstreamtag{#1}\vbox + {\presetoutputstream + \ifvoid\outputstreamtag{#1}\else\unvbox\outputstreamtag{#1}\fi + \scratchdimen\dp\normalpagebox + \unvbox\normalpagebox + \vskip-\scratchdimen + \kern\strutdepth}% + \fi} + +% \def\presetoutputstream +% {\pdffirstlineheight\strutheight +% \pdflastlinedepth \strutdepth +% \pdfeachlineheight \strutheight +% \pdfeachlinedepth \strutdepth} + +\let\presetoutputstream\relax + +\def\outputstreamht [#1]{\ht\outputstreamtag{#1}} +\def\outputstreamdp [#1]{\dp\outputstreamtag{#1}} +\def\outputstreamwd [#1]{\wd\outputstreamtag{#1}} + +%def\outputstreambox [#1]{\ifvoid\outputstreamtag{#1}\else\box \outputstreamtag{#1}\fi} +%def\outputstreamcopy[#1]{\ifvoid\outputstreamtag{#1}\else\copy\outputstreamtag{#1}\fi} + +\def\dowithoutputstreambox#1[#2]{\ifvoid\outputstreamtag{#2}\else#1\outputstreamtag{#2}\fi} + +\def\outputstreamcopy {\dowithoutputstreambox\copy } +\def\outputstreambox {\dowithoutputstreambox\box } +\def\outputstreamunvcopy{\dowithoutputstreambox\unvcopy} +\def\outputstreamunvbox {\dowithoutputstreambox\unvbox } + +%D Footnotes don't go along with streams, simply because there is no +%D way to re-split inserts. A dirty way out is to use marks and store +%D notes that way. + +\def\definemarknote + {\dodoubleempty\dodefinemarknote} + +\def\dodefinemarknote[#1][#2]% + {\definemarking[mn:#1]% + \setvalue{mn:#1:n}{0}% + \getparameters + [mn:#1] + [\c!before=, + \c!after=, + \c!inbetween=\endgraf, + \c!command=\firstofoneargument, + #2]} + +\def\setmarknote[#1]#2% + {\doglobal\incrementvalue{mn:#1:n}% + \setgvalue{mn:#1:t:\getvalue{mn:#1:n}}{#2}% + \expanded{\marking[mn:#1]{\getvalue{mn:#1:n}}}} + +\def\flushmarknotes[#1]% assumes split + {\begingroup +% \edef\firstmarknote{0\fetchmark[mn:#1][column:first]}% +% \edef\lastmarknote {0\fetchmark[mn:#1][column:last]}% +% \ifnum\firstmarknote<\lastmarknote\relax +% \getvalue{mn:#1\c!before}% +% \dostepwiserecurse\firstmarknote\lastmarknote\plusone +% {\ifnum\recurselevel>\firstmarknote\relax +% \ifnum\recurselevel<\lastmarknote\relax +% \getvalue{mn:#1\c!inbetween}% +% \fi +% \fi +% \getvalue{mn:#1\c!command}{\getvalue{mn:#1:t:\recurselevel}}}% +% \getvalue{mn:#1\c!after}% +% \fi + \endgroup} + +\def\erasemarknotes[#1]% + {\begingroup + \edef\firstmarknote{0\fetchmark[mn:#1][column:first]}% + \edef\lastmarknote {0\fetchmark[mn:#1][column:last]}% + \dostepwiserecurse\firstmarknote\lastmarknote\plusone + {\global\letvalue{mn:#1:t:\recurselevel}\empty}% + \endgroup} + +%D The next section implements synchronization of (currently +%D two) output streams. In due time we will implement both a +%D vertical and horizontal system, as well as alternative +%D splitters (firstpagevsize, succesivevsize etc). + +\def\synchronizeoutputstreams[#1]% [one,two] [left,right] + {\bgroup + \getfromcommalist[#1][\plusone]\let\firstoutputstream \commalistelement + \getfromcommalist[#1][\plustwo]\let\secondoutputstream\commalistelement + \forgeteverypar + \def\roundingeps{50sp}% + \getboxheight\dimen0\of\box\outputstreamtag\firstoutputstream + \getboxheight\dimen2\of\box\outputstreamtag\secondoutputstream + \scratchdimen\dimexpr\dimen0-\dimen2\relax + \ifdim\scratchdimen<-\roundingeps\relax + \scratchdimen-\scratchdimen + \writestatus{sync}{compensating first stream: \the\scratchdimen/\number\scratchdimen}% + \getroundednoflines\scratchdimen + \global\setbox\outputstreamtag\firstoutputstream\vbox + {\presetoutputstream + \unvbox\outputstreamtag\firstoutputstream\dorecurse\noflines\crlf}% + \else\ifdim\scratchdimen>\roundingeps\relax + \writestatus{sync}{compensating second stream: \the\scratchdimen/\number\scratchdimen}% + \getroundednoflines\scratchdimen + \global\setbox\outputstreamtag\secondoutputstream\vbox + {\presetoutputstream + \unvbox\outputstreamtag\secondoutputstream\dorecurse\noflines\crlf}% + \else + \writestatus{sync}{no need to compensate streams: \the\scratchdimen/\number\scratchdimen}% + \fi\fi + \egroup} + +\def\nofoutputstreamsplitlines {\v!auto} % {40} +\def\outputstreamsplittolerance {-5} + +\def\flushoutputstreampages[#1]% + {\bgroup + \getfromcommalist[#1][\plusone]\let\firstoutputstream \commalistelement + \getfromcommalist[#1][\plustwo]\let\secondoutputstream\commalistelement + \doloop + {\flushoutputstreams[#1]% + \ifvoid\outputstreamtag\firstoutputstream + \ifvoid\outputstreamtag\secondoutputstream + \exitloop + \else + \global\setbox\outputstreamtag\firstoutputstream\vbox{\strut}% + \fi + \else + \ifvoid\outputstreamtag\secondoutputstream + \global\setbox\outputstreamtag\secondoutputstream\vbox{\strut}% + \else + % okay + \fi + \fi}% + \egroup} + +\def\flushoutputstreams[#1]% + {\bgroup + \getfromcommalist[#1][\plusone]\let\firstoutputstream \commalistelement + \getfromcommalist[#1][\plustwo]\let\secondoutputstream\commalistelement + \doif\nofoutputstreamsplitlines\v!auto + {\getrawnoflines\textheight + \edef\nofoutputstreamsplitlines{\the\noflines}}% + \splittopskip\strutheight + \scratchdimen\nofoutputstreamsplitlines\lineheight\relax + \unless\iffalse + \dimen0\scratchdimen + \doloop + {\setbox4\copy\outputstreamtag\firstoutputstream + \setbox0\vsplit4 to \dimen0 + \setbox0\vbox + {\directsetup{stream:\firstoutputstream:top}% + \unvbox0 + \directsetup{stream:\firstoutputstream:bottom}}% + \ifdim\ht0>\scratchdimen + \advance\dimen0-\lineheight + \else + \exitloop + \fi}% + \scratchdimen\dimen0 + \dimen2\scratchdimen + \doloop + {\setbox6\copy\outputstreamtag\secondoutputstream + \setbox2\vsplit6 to \dimen2 + \setbox2\vbox + {\directsetup{stream:\secondoutputstream:top}% + \unvbox0 + \directsetup{stream:\secondoutputstream:bottom}}% + \ifdim\ht2>\scratchdimen + \advance\dimen2-\lineheight + \else + \exitloop + \fi}% + \scratchdimen\dimen2 + \fi + \setbox4\copy\outputstreamtag\firstoutputstream + \setbox6\copy\outputstreamtag\secondoutputstream + \scratchcounter\zerocount + \doloop + {\setbox0\vsplit4 to \scratchdimen + \setbox0\vbox{\unvbox0}% + \setbox2\vsplit6 to \scratchdimen + \setbox2\vbox{\unvbox2}% + \ifvoid4 + \exitloop + \else\ifvoid6 + \exitloop + \else + \dimen8=\dimexpr\ht4-\ht6\relax + \ifdim\dimen8<\zeropoint\dimen8=-\dimen8\relax\fi + \advance\scratchcounter\plusone + \ifdim\dimen8<.5\lineheight + \exitloop + \else\ifnum\outputstreamsplittolerance>\zeropoint + \ifnum\scratchcounter>\outputstreamsplittolerance\relax + \exitloop + \else + \advance\scratchdimen\lineheight + \fi + \else\ifnum\outputstreamsplittolerance<\zeropoint + \ifnum-\scratchcounter<\outputstreamsplittolerance\relax + \exitloop + \else + \advance\scratchdimen-\lineheight + \fi + \else\ifnum\outputstreamsplittolerance=\zeropoint + \exitloop + \fi\fi\fi\fi + \fi\fi}% + \setbox0\vsplit\outputstreamtag\firstoutputstream to \scratchdimen + \setbox0\vbox to \textheight + {\presetoutputstream + \directsetup{stream:\firstoutputstream:top}% + \unvbox0 + \vfill + \directsetup{stream:\firstoutputstream:bottom}}% + \setbox2\vsplit\outputstreamtag\secondoutputstream to \scratchdimen + \setbox2\vbox to \textheight + {\presetoutputstream + \directsetup{stream:\secondoutputstream:top}% + \unvbox2 + \vfill + \directsetup{stream:\secondoutputstream:bottom}}% + \directsetup{stream:\firstoutputstream:reset}% + \directsetup{stream:\secondoutputstream:reset}% + \page[even] + \box0\vfill\page + \box2\vfill\page + \egroup} + + %D Although one can put floats in a stream, it sometimes makes sense + %D to keep them apart and this is what local floats do. + + \def\setuplocalfloats + {\getparameters[\??lf]} + + \setuplocalfloats + [%before=\blank, + %after=\blank, + inbetween=\blank] + + \installfloathandler \v!local \somelocalfloat + + \initializeboxstack{localfloats} + + \newcounter\noflocalfloats + + \def\resetlocalfloats + {\doglobal\newcounter\noflocalfloats + \initializeboxstack{localfloats}} + + \def\somelocalfloat[#1]% + {\doglobal\increment\noflocalfloats + \savebox{localfloats}{\noflocalfloats}{\box\floatbox}} + + \def\getlocalfloats + {\dorecurse\noflocalfloats + {\ifnum\recurselevel=\plusone % 1\relax + \getvalue{\??lf\c!before}% + \else + \getvalue{\??lf\c!inbetween}% + \fi + \dontleavehmode\hbox{\foundbox{localfloats}\recurselevel}% + \ifnum\recurselevel=\noflocalfloats\relax + \getvalue{\??lf\c!after}% + \fi}} + + \def\flushlocalfloats + {\getlocalfloats + \resetlocalfloats} + + \def\getlocalfloat#1{\expanded{\foundbox{localfloats}{\number#1}}} + + \def\forcelocalfloats{\let\forcedfloatmethod\v!local} + +%D Because many arrangements are possible, we will implement +%D some examples in a runtime loadable module \type {m-streams}. + +\protect \endinput diff --git a/tex/context/base/page-str.mkiv b/tex/context/base/page-str.mkiv new file mode 100644 index 000000000..d73643cbe --- /dev/null +++ b/tex/context/base/page-str.mkiv @@ -0,0 +1,144 @@ +%D \module +%D [ file=page-str, +%D version=2010.03.13, % 2006.03.21, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Page Streams, +%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 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 +%D playing with the code, I decided to make it into a component +%D that can be used to construct all kind of stream related +%D mechanisms. Because I could apply this feature in a project, +%D there is some additional code here (related to graphics). +%D +%D These macros were written while listening to and watching the DVD +%D \quotation {Rush In Rio}. +%D +%D The reimplementation (or rather experimenting with the complete +%D rewrite) was done while looping over \quotation {Wende Snijders +%D No.9}. +%D +%D Remark: marknotes are gone, at least for a while. + +\writestatus{loading}{ConTeXt Page Macros / Page Streams} + +\registerctxluafile{page-str}{1.001} + +\unprotect + +\let \currentoutputstream \empty +\newif \ifinoutputstream +\newtoks \everyenableoutputstream + +\appendtoks + \flushsidefloats +\to \everyenableoutputstream + +\def\initializeoutputstreams + {\ctxlua{streams.initialize()}% + \glet\initializeoutputstreams\relax} + +\def\enableoutputstream[#1]% + {\initializeoutputstreams + \the\everyenableoutputstream + \inoutputstreamtrue + \xdef\currentoutputstream{#1}% + \ctxlua{streams.enable("#1")}} + +\def\disableoutputstream + {\inoutputstreamfalse + \global\let\currentoutputstream\s!default + \ctxlua{streams.disable()}} + +\unexpanded\def\startoutputstream[#1]% + {\begingroup + \initializeoutputstreams + \the\everyenableoutputstream + \inoutputstreamtrue + \xdef\currentoutputstream{#1}% + \ctxlua{streams.start("#1")}} + +\unexpanded\def\stopoutputstream + {\ctxlua{streams.stop()}% + \endgroup} + +\def\flushoutputstream [#1]{\ctxlua{streams.flush("#1")}} +\def\outputstreamcopy [#1]{\vbox{\ctxlua{streams.flush("#1",true)}}} +\def\outputstreambox [#1]{\vbox{\ctxlua{streams.flush("#1")}}} +\def\outputstreamunvcopy[#1]{\ctxlua{streams.flush("#1",true)}} +\def\outputstreamunvbox [#1]{\ctxlua{streams.flush("#1")}} +\def\synchronizestreams [#1]{\ctxlua{streams.synchronize("#1")}} +\def\dopushoutputstream [#1]{\ctxlua{streams.push("#1")}} + +\def\pushoutputstream {\dosingleempty\dopushoutputstream} + +% \unexpanded\def\defineoutputstream[#1]% +% {\doifundefined{otrs:#1}{\expandafter\newbox\csname otrs:#1\endcsname}} +% +% \def\useoutputstream[#1]% +% {\writestatus{otr}{using output stream #1}% +% \xdef\currentoutputstream{#1}} +% +% \directsetup{stream:\firstoutputstream:set} +% \directsetup{stream:\firstoutputstream:top} +% \directsetup{stream:\firstoutputstream:bottom} +% \directsetup{stream:\firstoutputstream:reset} + +%D Obsolete in \MKIV: + +\unexpanded\def\definemarknote {\dodoubleempty\dodefinemarknote} +\def\dodefinemarknote[#1][#2]{} +\def\setmarknote [#1]{\gobbleoneargument} +\def\flushmarknotes [#1]{} +\def\erasemarknotes [#1]{} + +\protect \endinput + +% \enabletrackers[streams.flushing] +% +% \setuplayout[grid=yes] \showgrid +% +% \starttext +% +% \input tufte +% +% \startoutputstream[nl] +% +% Wat doen we hier? +% +% \enableoutputstream[en] +% +% Are you sleeping, brother John?\footnote{xxx} +% +% \dorecurse{4}{x \footnote{note \recurselevel}\input tufte \par \pushoutputstream} +% +% \enableoutputstream[de] +% +% Bruder Jakob, schläfst du noch?\footnote{yyy} +% +% \dorecurse{4}{x \footnote{note \recurselevel}\input ward \par \pushoutputstream} +% +% \disableoutputstream +% +% \stopoutputstream +% +% Vader Jacob, slaap je nog?\footnote{zzz} +% +% \input tufte +% +% \synchronizestreams[en,de,nl] +% +% \page \flushoutputstream[en] \input knuth +% \page \flushoutputstream[de] \input knuth +% \page \flushoutputstream[nl] \input knuth +% +% \stoptext 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..bdc7c1bb6 --- /dev/null +++ b/tex/context/base/page-txt.mkiv @@ -0,0 +1,850 @@ +%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 + +%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} + +\unexpanded\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{\csname\??tk#1\c!state\endcsname}% + \getparameters[\??tk#1][#2]% + \edef\currenttextstate{\csname\??tk#1\c!state\endcsname}% + \ifx\currenttextstate\previoustextstate + % no change in state + \else + %\checkcurrentlayout % no + % speed optimization (calculating backgrounds takes time) + \doifcommon{\previoustextstate,\currenttextstate}{\v!high,\v!none} + {\calculatevsizes + \recalculatebackgrounds}% + \fi + \fi} + +\unexpanded\def\setuptop {\dotripleempty\dosetuplayouttext[\v!top]} +\unexpanded\def\setupheader {\dotripleempty\dosetuplayouttext[\v!header]} +\unexpanded\def\setuptext {\dotripleempty\dosetuplayouttext[\v!text]} +\unexpanded\def\setupfooter {\dotripleempty\dosetuplayouttext[\v!footer]} +\unexpanded\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} + +\unexpanded\def\setuptoptexts {\dosixtupleempty\dosetuptexts[\v!top ]} +\unexpanded\def\setupheadertexts {\dosixtupleempty\dosetuptexts[\v!header ]} +\unexpanded\def\setuptexttexts {\dosixtupleempty\dosetuptexts[\v!text ]} +\unexpanded\def\setupfootertexts {\dosixtupleempty\dosetuptexts[\v!footer ]} +\unexpanded\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{#1}{#2}% + {\c!leftstyle \c!leftcolor \c!leftwidth }{#3}% + {\c!rightstyle\c!rightcolor\c!rightwidth}{#6}}% + \setvalue{\??tk#1#2\c!righttext}% + {\dodoubletexts{#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{#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{#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{#1}{#2} + {\c!leftstyle\c!leftcolor\c!leftwidth}{#3}% + {\c!leftstyle\c!leftcolor\c!leftwidth}{#3}}% + \setvalue{\??tk#1#2\c!righttext}% + {\dodoubletexts{#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{#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{#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{#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{\doifoddpageelse\dodoubletextsodd\dodoubletextseven} + +\def\dodoubletextsodd #1#2#3#4#5#6{\dosingletexts{#1}{#2}#3{#4}} % #3 => provides three arguments +\def\dodoubletextseven#1#2#3#4#5#6{\dosingletexts{#1}{#2}#5{#6}} % #5 => provides three arguments + +%D The next macro will be cleaned up and made less messy and +%D dependent. + +\unexpanded\def\placetextlinestrut#1% + {\doifvalue{#1\c!strut}\v!yes{\setstrut\strut}} + +\def\dosingletexts#1#2#3#4#5#6% + {\bgroup + \defconvertedargument\ascii{#6}% no longer \defconvertedargument, this also does not permit \v!pagenumber (i.e. v!) + \ifx\ascii\empty\else + \dostartattributes{\??tk#1#2}#3#4\empty + \placetextlinestrut{\??tk#1}% here ! + \doifelsemarking\ascii + {\dolimitatetexts{\??tk#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{\??tk#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}{\csname#1\endcsname}{\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\settextlinestatus#1% + {\ifcase0\csname\??tk#1\c!n\endcsname\relax + \edef\textlinestatus{\csname\??tk#1\c!state\endcsname}% + \else + \setxvalue{\??tk#1\c!n}{\the\numexpr\csname\??tk#1\c!n\endcsname-1}% + \let\textlinestatus\v!stop + \fi} + +\appendtoks + \doifinset\v!header\floatspecification{\setxvalue{\??tk\v!header\c!n}{1}}% + \doifinset\v!footer\floatspecification{\setxvalue{\??tk\v!footer\c!n}{1}}% +\to \everybeforeflushedpagefloat + +\def\resettextlinestatus#1% postpone + {\expandafter\gdef\csname\??tk#1\s!reset\endcsname{\global\expandafter\let\csname\??tk#1\c!state\endcsname\v!normal}} + +\unexpanded\def\placelayouttextline#1% #2 + {\settextlinestatus#1% + \csname\??tk::\ifcsname\??tk::\textlinestatus\endcsname\textlinestatus\else\s!unknown\fi\endcsname#1} % {#2} + +\def\doifelselayouttextline#1% shown or not + {\edef\!!stringa{\csname\??tk#1\c!state\endcsname}% + \ifx\!!stringa\v!normal + \@EA\firstoftwoarguments + \else\ifx\!!stringa\v!start + \@EAEAEA\firstoftwoarguments + \else + \@EAEAEA\secondoftwoarguments + \fi\fi} + +\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 + +% there is no need for {#1} etc since we use symbolic names + +\setvalue{\??tk::\v!normal}{\doplacelayouttextline} +\setvalue{\??tk::\empty }{\doplacelayouttextline} + +\setvalue{\??tk::\v!none }#1#2{} +\setvalue{\??tk::\v!stop }#1#2{} + +\setvalue{\??tk::\v!high}#1#2% + {\global\settrue\resyncaftertextline + \resettextlinestatus#1} + +\setvalue{\??tk::\v!empty}#1#2% + {\resettextlinestatus#1} + +\setvalue{\??tk::\v!start}#1#2% + {\resettextlinestatus#1% + \doplacelayouttextline#1#2} + +\setvalue{\??tk::\v!nomarking}#1#2% + {\bgroup + \resettextlinestatus#1% + \let\dogetmarking\nogetmarking + \doplacelayouttextline#1#2% + \egroup} + +\setvalue{\??tk::\s!unknown}#1#2% + {\global\settrue\resyncaftertextline + \bgroup % new + \resettextlinestatus#1% + \csname\??tk#1\textlinestatus\endcsname + \csname\??tk#1\v!text \textlinestatus\endcsname + \csname\??tk#1\v!margin\textlinestatus\endcsname + \csname\??tk#1\v!edge \textlinestatus\endcsname + \doplacelayouttextline#1#2% + \egroup} + +%D The following macro has to be called after a page +%D is flushed. + +\def\resetlayouttextline#1% + {\csname\??tk#1\s!reset\endcsname + \global\expandafter\let\csname\??tk#1\s!reset\endcsname\relax} + +\def\resetlayouttextlines + {\resetlayouttextline\v!top + \resetlayouttextline\v!header + \resetlayouttextline\v!text + \resetlayouttextline\v!footer + \resetlayouttextline\v!bottom + \ifconditional\resyncaftertextline + \calculateglobalvsizes + \recalculatebackgrounds + \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}% + \addtextbackground\scratchpagebox + \addtextgridlayer\scratchpagebox + \box\scratchpagebox + \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 stored as normal and overloaded in page-lyr and later in +% page-spr we overload the the stored version .. evenatually i will +% clear up the experimental mess + +\def\settextpagecontent#1#2#3% #2 and #3 will disappear + {\setbox#1\hbox to \makeupwidth + {\hss % so don't change this + \setlayoutcomponentattribute\v!page\v!text + \vbox \layoutcomponentboxattribute to \textheight + {\offinterlineskip + \freezetextwidth + \hsize\textwidth % local variant of \sethsize + \boxmaxdepth\maxdepth + \noindent % content can be < \hsize + \dopagecontents#2#3}% + \hss}% + \dp#1\zeropoint} + +%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 +% {\vsize#2\relax +% \normalbaselines +% \let\\\ignoredlinebreak +% \let\crlf\ignoredlinebreak +% \csname\??tk#1\c!before\endcsname +% \doifbothsidesoverruled +% {\dodoplacelayouttextline#1\c!lefttext \c!middletext\c!righttext\zerocount\plusone} +% {\dodoplacelayouttextline#1\c!lefttext \c!middletext\c!righttext\zerocount\plusone} +% {\dodoplacelayouttextline#1\c!righttext\c!middletext\c!lefttext \plusone\zerocount}% +% \csname\??tk#1\c!after\endcsname +% \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\csname\??tk#1\v!edge#2\endcsname}% +% \hskip\leftedgedistance +% \fi +% \ifdim\leftmarginwidth>\zeropoint +% \dododoplacelayouttextline\leftmarginwidth#1\v!margin +% {\hbox to \leftmarginwidth +% {\hss\csname\??tk#1\v!margin#2\endcsname}% +% \hskip-\leftmarginwidth +% \hbox to \leftmarginwidth +% {\hss\ifcase#5\or\csname\??tk#1\v!margin\c!margintext\endcsname\fi}}% +% \hskip\leftmargindistance +% \fi +% \ifdim\makeupwidth>\zeropoint +% \dododoplacelayouttextline\makeupwidth{#1}\v!text +% {\hbox to \makeupwidth +% {\ifcase#5\or\@@nmpre{\csname\??tk#1\v!text\c!marginedgetext\endcsname}\fi +% \csname\??tk#1\v!text#2\endcsname\hss}% +% \hskip-\makeupwidth +% \hbox to \makeupwidth +% {\hss\csname\??tk#1\v!text#3\endcsname\hss}% +% \hskip-\makeupwidth +% \hbox to \makeupwidth +% {\hss\csname\??tk#1\v!text#4\endcsname +% \ifcase#6\or\@@nmpos{\csname\??tk#1\v!text\c!marginedgetext\endcsname}\fi}}% +% \fi +% \ifdim\rightmarginwidth>\zeropoint +% \hskip\rightmargindistance +% \dododoplacelayouttextline\rightmarginwidth{#1}\v!margin +% {\hbox to \rightmarginwidth +% {\csname\??tk#1\v!margin#4\endcsname\hss}% +% \hskip-\rightmarginwidth +% \hbox to \rightmarginwidth +% {\ifcase#6\or\csname\??tk#1\v!margin\c!margintext\endcsname\fi\hss}}% +% \fi +% \ifdim\rightedgewidth>\zeropoint +% \hskip\rightedgedistance +% \dododoplacelayouttextline\rightedgewidth{#1}\v!edge +% {\csname\??tk#1\v!edge#4\endcsname\hss}% +% \fi}} +% +% \def\dododoplacelayouttextline#1#2#3#4% +% {\vbox % to \vsize +% {\hsize#1\relax +% \csname\??tk#2#3\c!before\endcsname +% \setlayoutcomponentattribute#2#3% +% \hbox \layoutcomponentboxattribute to #1{#4}% +% \csname\??tk#2#3\c!after\endcsname}} + +\def\doplacelayouttextline#1#2% + {\let\currentlayouttextline#1% + \ifdim#2>\zeropoint\relax % prevents pagenumbers when zero height + \doplacelayouttextlineindeed{#2}% + \fi} + +\def\doplacelayouttextlineindeed#1% + {\goleftonpage + \hbox + {\setbox\scratchpagebox\vbox to #1 + {\vsize#1\relax + \normalbaselines + \let\\\ignoredlinebreak + \let\crlf\ignoredlinebreak + \csname\??tk\currentlayouttextline\c!before\endcsname + \doifbothsidesoverruled\dodoplacelayouttextlineright\dodoplacelayouttextlineright\dodoplacelayouttextlineleft + \csname\??tk\currentlayouttextline\c!after\endcsname + \kern\zeropoint}% keep the \dp, beware of \vtops, never change this! + \dp\scratchpagebox\zeropoint + \box\scratchpagebox}% + \vskip-#1\relax} + +\def\dodoplacelayouttextlineright{\dodoplacelayouttextline\c!lefttext \c!middletext\c!righttext\zerocount\plusone} +\def\dodoplacelayouttextlineleft {\dodoplacelayouttextline\c!righttext\c!middletext\c!lefttext \plusone\zerocount} + +\def\dodoplacelayouttextline#1#2#3#4#5% \hsize toegevoegd, \hss's niet meer wijzigen + {\hbox + {\ifdim\leftedgewidth>\zeropoint + \dododoplacelayouttextline\leftedgewidth\currentlayouttextline\v!edge{\thelayoutleftedgeline#1}% + \hskip\leftedgedistance + \fi + \ifdim\leftmarginwidth>\zeropoint + \dododoplacelayouttextline\leftmarginwidth\currentlayouttextline\v!margin{\thelayoutleftmarginline#1#4}% + \hskip\leftmargindistance + \fi + \ifdim\makeupwidth>\zeropoint + \dododoplacelayouttextline\makeupwidth\currentlayouttextline\v!text{\thelayouttextline#1#2#3#4#5}% + \fi + \ifdim\rightmarginwidth>\zeropoint + \hskip\rightmargindistance + \dododoplacelayouttextline\rightmarginwidth\currentlayouttextline\v!margin{\thelayoutrightmarginline#3#5}% + \fi + \ifdim\rightedgewidth>\zeropoint + \hskip\rightedgedistance + \dododoplacelayouttextline\rightedgewidth\currentlayouttextline\v!edge{\thelayoutrightedgeline#3}% + \fi}} + +\def\thelayoutleftedgeline#1% + {\hss\csname\??tk\currentlayouttextline\v!edge#1\endcsname}% + +\def\thelayoutrightedgeline#1% + {\csname\??tk\currentlayouttextline\v!edge#1\endcsname\hss} + +\def\thelayoutleftmarginline#1#2% + {\hbox to \leftmarginwidth{\hss\csname\??tk\currentlayouttextline\v!margin#1\endcsname}% + \hskip-\leftmarginwidth + \hbox to \leftmarginwidth{\hss\ifcase#2\or\csname\??tk\currentlayouttextline\v!margin\c!margintext\endcsname\fi}} + +\def\thelayoutrightmarginline#1#2% + {\hbox to \rightmarginwidth{\csname\??tk\currentlayouttextline\v!margin#1\endcsname\hss}% + \hskip-\rightmarginwidth + \hbox to \rightmarginwidth{\ifcase#2\or\csname\??tk\currentlayouttextline\v!margin\c!margintext\endcsname\fi\hss}} + +\def\thelayoutedgetextline{\csname\??tk\currentlayouttextline\v!text\c!marginedgetext\endcsname} + +\def\thelayouttextline#1#2#3#4#5% + {\hbox to \makeupwidth{\ifcase#4\or\@@nmpre\thelayoutedgetextline\fi\csname\??tk\currentlayouttextline\v!text#1\endcsname\hss}% + \hskip-\makeupwidth + \hbox to \makeupwidth{\hss\csname\??tk\currentlayouttextline\v!text#2\endcsname\hss}% + \hskip-\makeupwidth + \hbox to \makeupwidth{\hss\csname\??tk\currentlayouttextline\v!text#3\endcsname\ifcase#5\or\@@nmpos\thelayoutedgetextline\fi}} + +\def\dododoplacelayouttextline#1#2#3#4% + {\vbox % to \vsize + {\hsize#1\relax + \csname\??tk#2#3\c!before\endcsname + \setlayoutcomponentattribute#2#3% + \hbox \layoutcomponentboxattribute to #1{#4}% + \csname\??tk#2#3\c!after\endcsname}} + +%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} +% +% faster + +\def\@@nmpre#1% + {\begingroup + \setbox\scratchbox\normalhbox{\trialtypesettingtrue\ignorespaces#1\removeunwantedspaces}% + \ifzeropt\wd\scratchbox\else + \doifelsenothing\@@nmwidth + {\box\scratchbox\tfskip} + {\hbox to \@@nmwidth{\box\scratchbox\hss}}% + \fi + \endgroup} + +\def\@@nmpos#1% + {\begingroup + \setbox\scratchbox\normalhbox{\trialtypesettingtrue\ignorespaces#1\removeunwantedspaces}% + \ifzeropt\wd\scratchbox\else + \doifelsenothing\@@nmwidth + {\tfskip\box\scratchbox} + {\hbox to \@@nmwidth{\hss\box\scratchbox}}% + \fi + \endgroup} + +%D This code will move to \type {page-flt.tex}. + +\appendtoks \placerightmarginblock \hskip-\rightmarginwidth \to \rightmargintextcontent +\appendtoks \placeleftmarginblock \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 + \unexpanded\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 + +\unexpanded\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=\csname\??tk#1\c!style\endcsname,% hm, got lost + \c!color=\csname\??tk#1\c!color\endcsname,% 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!n=0,\c!before=\vss,\c!after=\vss,\c!strut=] +\setupheader[\c!state=\v!normal,\c!n=0,\c!before=, \c!after=\vss,\c!strut=\v!yes] +\setuptext [\c!state=\v!normal,\c!n=0,\c!before=\vss,\c!after=\vss,\c!strut=] +\setupfooter[\c!state=\v!normal,\c!n=0,\c!before=\vss,\c!after=, \c!strut=\v!yes] +\setupbottom[\c!state=\v!normal,\c!n=0,\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/pdfr-def.mkii b/tex/context/base/pdfr-def.mkii new file mode 100644 index 000000000..7554bda9e --- /dev/null +++ b/tex/context/base/pdfr-def.mkii @@ -0,0 +1,843 @@ +% filename : pdfr-def.tex +% comment : generated by mtxrun --script chars --pdf +% author : Hans Hagen, PRAGMA-ADE, Hasselt NL +% copyright: PRAGMA ADE / ConTeXt Development Team +% license : see context related readme files +% +\pdfglyphtounicode{space}{0020}% +\pdfglyphtounicode{exclam}{0021}% +\pdfglyphtounicode{quotedbl}{0022}% +\pdfglyphtounicode{numbersign}{0023}% +\pdfglyphtounicode{dollar}{0024}% +\pdfglyphtounicode{percent}{0025}% +\pdfglyphtounicode{ampersand}{0026}% +\pdfglyphtounicode{quotesingle}{0027}% +\pdfglyphtounicode{parenleft}{0028}% +\pdfglyphtounicode{parenright}{0029}% +\pdfglyphtounicode{asterisk}{002A}% +\pdfglyphtounicode{plus}{002B}% +\pdfglyphtounicode{comma}{002C}% +\pdfglyphtounicode{hyphen}{002D}% +\pdfglyphtounicode{period}{002E}% +\pdfglyphtounicode{slash}{002F}% +\pdfglyphtounicode{zero}{0030}% +\pdfglyphtounicode{one}{0031}% +\pdfglyphtounicode{two}{0032}% +\pdfglyphtounicode{three}{0033}% +\pdfglyphtounicode{four}{0034}% +\pdfglyphtounicode{five}{0035}% +\pdfglyphtounicode{six}{0036}% +\pdfglyphtounicode{seven}{0037}% +\pdfglyphtounicode{eight}{0038}% +\pdfglyphtounicode{nine}{0039}% +\pdfglyphtounicode{colon}{003A}% +\pdfglyphtounicode{semicolon}{003B}% +\pdfglyphtounicode{less}{003C}% +\pdfglyphtounicode{equal}{003D}% +\pdfglyphtounicode{greater}{003E}% +\pdfglyphtounicode{question}{003F}% +\pdfglyphtounicode{at}{0040}% +\pdfglyphtounicode{A}{0041}% +\pdfglyphtounicode{B}{0042}% +\pdfglyphtounicode{C}{0043}% +\pdfglyphtounicode{D}{0044}% +\pdfglyphtounicode{E}{0045}% +\pdfglyphtounicode{F}{0046}% +\pdfglyphtounicode{G}{0047}% +\pdfglyphtounicode{H}{0048}% +\pdfglyphtounicode{I}{0049}% +\pdfglyphtounicode{J}{004A}% +\pdfglyphtounicode{K}{004B}% +\pdfglyphtounicode{L}{004C}% +\pdfglyphtounicode{M}{004D}% +\pdfglyphtounicode{N}{004E}% +\pdfglyphtounicode{O}{004F}% +\pdfglyphtounicode{P}{0050}% +\pdfglyphtounicode{Q}{0051}% +\pdfglyphtounicode{R}{0052}% +\pdfglyphtounicode{S}{0053}% +\pdfglyphtounicode{T}{0054}% +\pdfglyphtounicode{U}{0055}% +\pdfglyphtounicode{V}{0056}% +\pdfglyphtounicode{W}{0057}% +\pdfglyphtounicode{X}{0058}% +\pdfglyphtounicode{Y}{0059}% +\pdfglyphtounicode{Z}{005A}% +\pdfglyphtounicode{bracketleft}{005B}% +\pdfglyphtounicode{backslash}{005C}% +\pdfglyphtounicode{bracketright}{005D}% +\pdfglyphtounicode{asciicircum}{005E}% +\pdfglyphtounicode{underscore}{005F}% +\pdfglyphtounicode{grave}{0060}% +\pdfglyphtounicode{a}{0061}% +\pdfglyphtounicode{b}{0062}% +\pdfglyphtounicode{c}{0063}% +\pdfglyphtounicode{d}{0064}% +\pdfglyphtounicode{e}{0065}% +\pdfglyphtounicode{f}{0066}% +\pdfglyphtounicode{g}{0067}% +\pdfglyphtounicode{h}{0068}% +\pdfglyphtounicode{i}{0069}% +\pdfglyphtounicode{j}{006A}% +\pdfglyphtounicode{k}{006B}% +\pdfglyphtounicode{l}{006C}% +\pdfglyphtounicode{m}{006D}% +\pdfglyphtounicode{n}{006E}% +\pdfglyphtounicode{o}{006F}% +\pdfglyphtounicode{p}{0070}% +\pdfglyphtounicode{q}{0071}% +\pdfglyphtounicode{r}{0072}% +\pdfglyphtounicode{s}{0073}% +\pdfglyphtounicode{t}{0074}% +\pdfglyphtounicode{u}{0075}% +\pdfglyphtounicode{v}{0076}% +\pdfglyphtounicode{w}{0077}% +\pdfglyphtounicode{x}{0078}% +\pdfglyphtounicode{y}{0079}% +\pdfglyphtounicode{z}{007A}% +\pdfglyphtounicode{braceleft}{007B}% +\pdfglyphtounicode{bar}{007C}% +\pdfglyphtounicode{braceright}{007D}% +\pdfglyphtounicode{asciitilde}{007E}% +\pdfglyphtounicode{exclamdown}{00A1}% +\pdfglyphtounicode{cent}{00A2}% +\pdfglyphtounicode{sterling}{00A3}% +\pdfglyphtounicode{currency}{00A4}% +\pdfglyphtounicode{yen}{00A5}% +\pdfglyphtounicode{brokenbar}{00A6}% +\pdfglyphtounicode{section}{00A7}% +\pdfglyphtounicode{dieresis}{00A8}% +\pdfglyphtounicode{copyright}{00A9}% +\pdfglyphtounicode{ordfeminine}{00AA}% +\pdfglyphtounicode{guillemotleft}{00AB}% +\pdfglyphtounicode{logicalnot}{00AC}% +\pdfglyphtounicode{registered}{00AE}% +\pdfglyphtounicode{macron}{00AF}% +\pdfglyphtounicode{degree}{00B0}% +\pdfglyphtounicode{plusminus}{00B1}% +\pdfglyphtounicode{acute}{00B4}% +\pdfglyphtounicode{mu}{00B5}% +\pdfglyphtounicode{paragraph}{00B6}% +\pdfglyphtounicode{periodcentered}{00B7}% +\pdfglyphtounicode{cedilla}{00B8}% +\pdfglyphtounicode{ordmasculine}{00BA}% +\pdfglyphtounicode{guillemotright}{00BB}% +\pdfglyphtounicode{onequarter}{00BC}% +\pdfglyphtounicode{onehalf}{00BD}% +\pdfglyphtounicode{threequarters}{00BE}% +\pdfglyphtounicode{questiondown}{00BF}% +\pdfglyphtounicode{Agrave}{00C0}% +\pdfglyphtounicode{Aacute}{00C1}% +\pdfglyphtounicode{Acircumflex}{00C2}% +\pdfglyphtounicode{Atilde}{00C3}% +\pdfglyphtounicode{Adieresis}{00C4}% +\pdfglyphtounicode{Aring}{00C5}% +\pdfglyphtounicode{AE}{00C6}% +\pdfglyphtounicode{Ccedilla}{00C7}% +\pdfglyphtounicode{Egrave}{00C8}% +\pdfglyphtounicode{Eacute}{00C9}% +\pdfglyphtounicode{Ecircumflex}{00CA}% +\pdfglyphtounicode{Edieresis}{00CB}% +\pdfglyphtounicode{Igrave}{00CC}% +\pdfglyphtounicode{Iacute}{00CD}% +\pdfglyphtounicode{Icircumflex}{00CE}% +\pdfglyphtounicode{Idieresis}{00CF}% +\pdfglyphtounicode{Eth}{00D0}% +\pdfglyphtounicode{Ntilde}{00D1}% +\pdfglyphtounicode{Ograve}{00D2}% +\pdfglyphtounicode{Oacute}{00D3}% +\pdfglyphtounicode{Ocircumflex}{00D4}% +\pdfglyphtounicode{Otilde}{00D5}% +\pdfglyphtounicode{Odieresis}{00D6}% +\pdfglyphtounicode{multiply}{00D7}% +\pdfglyphtounicode{Oslash}{00D8}% +\pdfglyphtounicode{Ugrave}{00D9}% +\pdfglyphtounicode{Uacute}{00DA}% +\pdfglyphtounicode{Ucircumflex}{00DB}% +\pdfglyphtounicode{Udieresis}{00DC}% +\pdfglyphtounicode{Yacute}{00DD}% +\pdfglyphtounicode{Thorn}{00DE}% +\pdfglyphtounicode{germandbls}{00DF}% +\pdfglyphtounicode{agrave}{00E0}% +\pdfglyphtounicode{aacute}{00E1}% +\pdfglyphtounicode{acircumflex}{00E2}% +\pdfglyphtounicode{atilde}{00E3}% +\pdfglyphtounicode{adieresis}{00E4}% +\pdfglyphtounicode{aring}{00E5}% +\pdfglyphtounicode{ae}{00E6}% +\pdfglyphtounicode{ccedilla}{00E7}% +\pdfglyphtounicode{egrave}{00E8}% +\pdfglyphtounicode{eacute}{00E9}% +\pdfglyphtounicode{ecircumflex}{00EA}% +\pdfglyphtounicode{edieresis}{00EB}% +\pdfglyphtounicode{igrave}{00EC}% +\pdfglyphtounicode{iacute}{00ED}% +\pdfglyphtounicode{icircumflex}{00EE}% +\pdfglyphtounicode{idieresis}{00EF}% +\pdfglyphtounicode{eth}{00F0}% +\pdfglyphtounicode{ntilde}{00F1}% +\pdfglyphtounicode{ograve}{00F2}% +\pdfglyphtounicode{oacute}{00F3}% +\pdfglyphtounicode{ocircumflex}{00F4}% +\pdfglyphtounicode{otilde}{00F5}% +\pdfglyphtounicode{odieresis}{00F6}% +\pdfglyphtounicode{divide}{00F7}% +\pdfglyphtounicode{oslash}{00F8}% +\pdfglyphtounicode{ugrave}{00F9}% +\pdfglyphtounicode{uacute}{00FA}% +\pdfglyphtounicode{ucircumflex}{00FB}% +\pdfglyphtounicode{udieresis}{00FC}% +\pdfglyphtounicode{yacute}{00FD}% +\pdfglyphtounicode{thorn}{00FE}% +\pdfglyphtounicode{ydieresis}{00FF}% +\pdfglyphtounicode{Amacron}{0100}% +\pdfglyphtounicode{amacron}{0101}% +\pdfglyphtounicode{Abreve}{0102}% +\pdfglyphtounicode{abreve}{0103}% +\pdfglyphtounicode{Aogonek}{0104}% +\pdfglyphtounicode{aogonek}{0105}% +\pdfglyphtounicode{Cacute}{0106}% +\pdfglyphtounicode{cacute}{0107}% +\pdfglyphtounicode{Ccircumflex}{0108}% +\pdfglyphtounicode{ccircumflex}{0109}% +\pdfglyphtounicode{Cdotaccent}{010A}% +\pdfglyphtounicode{cdotaccent}{010B}% +\pdfglyphtounicode{Ccaron}{010C}% +\pdfglyphtounicode{ccaron}{010D}% +\pdfglyphtounicode{Dcaron}{010E}% +\pdfglyphtounicode{dcaron}{010F}% +\pdfglyphtounicode{Dcroat}{0110}% +\pdfglyphtounicode{dcroat}{0111}% +\pdfglyphtounicode{Emacron}{0112}% +\pdfglyphtounicode{emacron}{0113}% +\pdfglyphtounicode{Ebreve}{0114}% +\pdfglyphtounicode{ebreve}{0115}% +\pdfglyphtounicode{Edotaccent}{0116}% +\pdfglyphtounicode{edotaccent}{0117}% +\pdfglyphtounicode{Eogonek}{0118}% +\pdfglyphtounicode{eogonek}{0119}% +\pdfglyphtounicode{Ecaron}{011A}% +\pdfglyphtounicode{ecaron}{011B}% +\pdfglyphtounicode{Gcircumflex}{011C}% +\pdfglyphtounicode{gcircumflex}{011D}% +\pdfglyphtounicode{Gbreve}{011E}% +\pdfglyphtounicode{gbreve}{011F}% +\pdfglyphtounicode{Gdotaccent}{0120}% +\pdfglyphtounicode{gdotaccent}{0121}% +\pdfglyphtounicode{Gcommaaccent}{0122}% +\pdfglyphtounicode{gcommaaccent}{0123}% +\pdfglyphtounicode{Hcircumflex}{0124}% +\pdfglyphtounicode{hcircumflex}{0125}% +\pdfglyphtounicode{Hbar}{0126}% +\pdfglyphtounicode{hbar}{0127}% +\pdfglyphtounicode{Itilde}{0128}% +\pdfglyphtounicode{itilde}{0129}% +\pdfglyphtounicode{Imacron}{012A}% +\pdfglyphtounicode{imacron}{012B}% +\pdfglyphtounicode{Ibreve}{012C}% +\pdfglyphtounicode{ibreve}{012D}% +\pdfglyphtounicode{Iogonek}{012E}% +\pdfglyphtounicode{iogonek}{012F}% +\pdfglyphtounicode{Idotaccent}{0130}% +\pdfglyphtounicode{dotlessi}{0131}% +\pdfglyphtounicode{IJ}{0132}% +\pdfglyphtounicode{ij}{0133}% +\pdfglyphtounicode{Jcircumflex}{0134}% +\pdfglyphtounicode{jcircumflex}{0135}% +\pdfglyphtounicode{Kcommaaccent}{0136}% +\pdfglyphtounicode{kcommaaccent}{0137}% +\pdfglyphtounicode{kgreenlandic}{0138}% +\pdfglyphtounicode{Lacute}{0139}% +\pdfglyphtounicode{lacute}{013A}% +\pdfglyphtounicode{Lcommaaccent}{013B}% +\pdfglyphtounicode{lcommaaccent}{013C}% +\pdfglyphtounicode{Lcaron}{013D}% +\pdfglyphtounicode{lcaron}{013E}% +\pdfglyphtounicode{Ldot}{013F}% +\pdfglyphtounicode{ldot}{0140}% +\pdfglyphtounicode{Lslash}{0141}% +\pdfglyphtounicode{lslash}{0142}% +\pdfglyphtounicode{Nacute}{0143}% +\pdfglyphtounicode{nacute}{0144}% +\pdfglyphtounicode{Ncommaaccent}{0145}% +\pdfglyphtounicode{ncommaaccent}{0146}% +\pdfglyphtounicode{Ncaron}{0147}% +\pdfglyphtounicode{ncaron}{0148}% +\pdfglyphtounicode{napostrophe}{0149}% +\pdfglyphtounicode{Eng}{014A}% +\pdfglyphtounicode{eng}{014B}% +\pdfglyphtounicode{Omacron}{014C}% +\pdfglyphtounicode{omacron}{014D}% +\pdfglyphtounicode{Obreve}{014E}% +\pdfglyphtounicode{obreve}{014F}% +\pdfglyphtounicode{Ohungarumlaut}{0150}% +\pdfglyphtounicode{ohungarumlaut}{0151}% +\pdfglyphtounicode{OE}{0152}% +\pdfglyphtounicode{oe}{0153}% +\pdfglyphtounicode{Racute}{0154}% +\pdfglyphtounicode{racute}{0155}% +\pdfglyphtounicode{Rcommaaccent}{0156}% +\pdfglyphtounicode{rcommaaccent}{0157}% +\pdfglyphtounicode{Rcaron}{0158}% +\pdfglyphtounicode{rcaron}{0159}% +\pdfglyphtounicode{Sacute}{015A}% +\pdfglyphtounicode{sacute}{015B}% +\pdfglyphtounicode{Scircumflex}{015C}% +\pdfglyphtounicode{scircumflex}{015D}% +\pdfglyphtounicode{Scedilla}{015E}% +\pdfglyphtounicode{scedilla}{015F}% +\pdfglyphtounicode{Scaron}{0160}% +\pdfglyphtounicode{scaron}{0161}% +\pdfglyphtounicode{Tcommaaccent}{0162}% +\pdfglyphtounicode{tcommaaccent}{0163}% +\pdfglyphtounicode{Tcaron}{0164}% +\pdfglyphtounicode{tcaron}{0165}% +\pdfglyphtounicode{Tbar}{0166}% +\pdfglyphtounicode{tbar}{0167}% +\pdfglyphtounicode{Utilde}{0168}% +\pdfglyphtounicode{utilde}{0169}% +\pdfglyphtounicode{Umacron}{016A}% +\pdfglyphtounicode{umacron}{016B}% +\pdfglyphtounicode{Ubreve}{016C}% +\pdfglyphtounicode{ubreve}{016D}% +\pdfglyphtounicode{Uring}{016E}% +\pdfglyphtounicode{uring}{016F}% +\pdfglyphtounicode{Uhungarumlaut}{0170}% +\pdfglyphtounicode{uhungarumlaut}{0171}% +\pdfglyphtounicode{Uogonek}{0172}% +\pdfglyphtounicode{uogonek}{0173}% +\pdfglyphtounicode{Wcircumflex}{0174}% +\pdfglyphtounicode{wcircumflex}{0175}% +\pdfglyphtounicode{Ycircumflex}{0176}% +\pdfglyphtounicode{ycircumflex}{0177}% +\pdfglyphtounicode{Ydieresis}{0178}% +\pdfglyphtounicode{Zacute}{0179}% +\pdfglyphtounicode{zacute}{017A}% +\pdfglyphtounicode{Zdotaccent}{017B}% +\pdfglyphtounicode{zdotaccent}{017C}% +\pdfglyphtounicode{Zcaron}{017D}% +\pdfglyphtounicode{zcaron}{017E}% +\pdfglyphtounicode{longs}{017F}% +\pdfglyphtounicode{florin}{0192}% +\pdfglyphtounicode{Ohorn}{01A0}% +\pdfglyphtounicode{ohorn}{01A1}% +\pdfglyphtounicode{Uhorn}{01AF}% +\pdfglyphtounicode{uhorn}{01B0}% +\pdfglyphtounicode{Gcaron}{01E6}% +\pdfglyphtounicode{gcaron}{01E7}% +\pdfglyphtounicode{Aringacute}{01FA}% +\pdfglyphtounicode{aringacute}{01FB}% +\pdfglyphtounicode{AEacute}{01FC}% +\pdfglyphtounicode{aeacute}{01FD}% +\pdfglyphtounicode{Oslashacute}{01FE}% +\pdfglyphtounicode{oslashacute}{01FF}% +\pdfglyphtounicode{Scommaaccent}{0218}% +\pdfglyphtounicode{scommaaccent}{0219}% +\pdfglyphtounicode{afii57929}{02BC}% +\pdfglyphtounicode{afii64937}{02BD}% +\pdfglyphtounicode{circumflex}{02C6}% +\pdfglyphtounicode{caron}{02C7}% +\pdfglyphtounicode{breve}{02D8}% +\pdfglyphtounicode{dotaccent}{02D9}% +\pdfglyphtounicode{ring}{02DA}% +\pdfglyphtounicode{ogonek}{02DB}% +\pdfglyphtounicode{tilde}{02DC}% +\pdfglyphtounicode{hungarumlaut}{02DD}% +\pdfglyphtounicode{gravecomb}{0300}% +\pdfglyphtounicode{acutecomb}{0301}% +\pdfglyphtounicode{tildecomb}{0303}% +\pdfglyphtounicode{hookabovecomb}{0309}% +\pdfglyphtounicode{dotbelowcomb}{0323}% +\pdfglyphtounicode{tonos}{0384}% +\pdfglyphtounicode{dieresistonos}{0385}% +\pdfglyphtounicode{Alphatonos}{0386}% +\pdfglyphtounicode{anoteleia}{0387}% +\pdfglyphtounicode{Epsilontonos}{0388}% +\pdfglyphtounicode{Etatonos}{0389}% +\pdfglyphtounicode{Iotatonos}{038A}% +\pdfglyphtounicode{Omicrontonos}{038C}% +\pdfglyphtounicode{Upsilontonos}{038E}% +\pdfglyphtounicode{Omegatonos}{038F}% +\pdfglyphtounicode{iotadieresistonos}{0390}% +\pdfglyphtounicode{Alpha}{0391}% +\pdfglyphtounicode{Beta}{0392}% +\pdfglyphtounicode{Gamma}{0393}% +\pdfglyphtounicode{Epsilon}{0395}% +\pdfglyphtounicode{Zeta}{0396}% +\pdfglyphtounicode{Eta}{0397}% +\pdfglyphtounicode{Theta}{0398}% +\pdfglyphtounicode{Iota}{0399}% +\pdfglyphtounicode{Kappa}{039A}% +\pdfglyphtounicode{Lambda}{039B}% +\pdfglyphtounicode{Mu}{039C}% +\pdfglyphtounicode{Nu}{039D}% +\pdfglyphtounicode{Xi}{039E}% +\pdfglyphtounicode{Omicron}{039F}% +\pdfglyphtounicode{Pi}{03A0}% +\pdfglyphtounicode{Rho}{03A1}% +\pdfglyphtounicode{Sigma}{03A3}% +\pdfglyphtounicode{Tau}{03A4}% +\pdfglyphtounicode{Upsilon}{03A5}% +\pdfglyphtounicode{Phi}{03A6}% +\pdfglyphtounicode{Chi}{03A7}% +\pdfglyphtounicode{Psi}{03A8}% +\pdfglyphtounicode{Iotadieresis}{03AA}% +\pdfglyphtounicode{Upsilondieresis}{03AB}% +\pdfglyphtounicode{alphatonos}{03AC}% +\pdfglyphtounicode{epsilontonos}{03AD}% +\pdfglyphtounicode{etatonos}{03AE}% +\pdfglyphtounicode{iotatonos}{03AF}% +\pdfglyphtounicode{upsilondieresistonos}{03B0}% +\pdfglyphtounicode{alpha}{03B1}% +\pdfglyphtounicode{beta}{03B2}% +\pdfglyphtounicode{gamma}{03B3}% +\pdfglyphtounicode{delta}{03B4}% +\pdfglyphtounicode{epsilon}{03B5}% +\pdfglyphtounicode{zeta}{03B6}% +\pdfglyphtounicode{eta}{03B7}% +\pdfglyphtounicode{theta}{03B8}% +\pdfglyphtounicode{iota}{03B9}% +\pdfglyphtounicode{kappa}{03BA}% +\pdfglyphtounicode{lambda}{03BB}% +\pdfglyphtounicode{nu}{03BD}% +\pdfglyphtounicode{xi}{03BE}% +\pdfglyphtounicode{omicron}{03BF}% +\pdfglyphtounicode{pi}{03C0}% +\pdfglyphtounicode{rho}{03C1}% +\pdfglyphtounicode{sigma1}{03C2}% +\pdfglyphtounicode{sigma}{03C3}% +\pdfglyphtounicode{tau}{03C4}% +\pdfglyphtounicode{upsilon}{03C5}% +\pdfglyphtounicode{phi}{03C6}% +\pdfglyphtounicode{chi}{03C7}% +\pdfglyphtounicode{psi}{03C8}% +\pdfglyphtounicode{omega}{03C9}% +\pdfglyphtounicode{iotadieresis}{03CA}% +\pdfglyphtounicode{upsilondieresis}{03CB}% +\pdfglyphtounicode{omicrontonos}{03CC}% +\pdfglyphtounicode{upsilontonos}{03CD}% +\pdfglyphtounicode{omegatonos}{03CE}% +\pdfglyphtounicode{theta1}{03D1}% +\pdfglyphtounicode{Upsilon1}{03D2}% +\pdfglyphtounicode{phi1}{03D5}% +\pdfglyphtounicode{omega1}{03D6}% +\pdfglyphtounicode{afii10023}{0401}% +\pdfglyphtounicode{afii10051}{0402}% +\pdfglyphtounicode{afii10052}{0403}% +\pdfglyphtounicode{afii10053}{0404}% +\pdfglyphtounicode{afii10054}{0405}% +\pdfglyphtounicode{afii10055}{0406}% +\pdfglyphtounicode{afii10056}{0407}% +\pdfglyphtounicode{afii10057}{0408}% +\pdfglyphtounicode{afii10058}{0409}% +\pdfglyphtounicode{afii10059}{040A}% +\pdfglyphtounicode{afii10060}{040B}% +\pdfglyphtounicode{afii10061}{040C}% +\pdfglyphtounicode{afii10062}{040E}% +\pdfglyphtounicode{afii10145}{040F}% +\pdfglyphtounicode{afii10017}{0410}% +\pdfglyphtounicode{afii10018}{0411}% +\pdfglyphtounicode{afii10019}{0412}% +\pdfglyphtounicode{afii10020}{0413}% +\pdfglyphtounicode{afii10021}{0414}% +\pdfglyphtounicode{afii10022}{0415}% +\pdfglyphtounicode{afii10024}{0416}% +\pdfglyphtounicode{afii10025}{0417}% +\pdfglyphtounicode{afii10026}{0418}% +\pdfglyphtounicode{afii10027}{0419}% +\pdfglyphtounicode{afii10028}{041A}% +\pdfglyphtounicode{afii10029}{041B}% +\pdfglyphtounicode{afii10030}{041C}% +\pdfglyphtounicode{afii10031}{041D}% +\pdfglyphtounicode{afii10032}{041E}% +\pdfglyphtounicode{afii10033}{041F}% +\pdfglyphtounicode{afii10034}{0420}% +\pdfglyphtounicode{afii10035}{0421}% +\pdfglyphtounicode{afii10036}{0422}% +\pdfglyphtounicode{afii10037}{0423}% +\pdfglyphtounicode{afii10038}{0424}% +\pdfglyphtounicode{afii10039}{0425}% +\pdfglyphtounicode{afii10040}{0426}% +\pdfglyphtounicode{afii10041}{0427}% +\pdfglyphtounicode{afii10042}{0428}% +\pdfglyphtounicode{afii10043}{0429}% +\pdfglyphtounicode{afii10044}{042A}% +\pdfglyphtounicode{afii10045}{042B}% +\pdfglyphtounicode{afii10046}{042C}% +\pdfglyphtounicode{afii10047}{042D}% +\pdfglyphtounicode{afii10048}{042E}% +\pdfglyphtounicode{afii10049}{042F}% +\pdfglyphtounicode{afii10065}{0430}% +\pdfglyphtounicode{afii10066}{0431}% +\pdfglyphtounicode{afii10067}{0432}% +\pdfglyphtounicode{afii10068}{0433}% +\pdfglyphtounicode{afii10069}{0434}% +\pdfglyphtounicode{afii10070}{0435}% +\pdfglyphtounicode{afii10072}{0436}% +\pdfglyphtounicode{afii10073}{0437}% +\pdfglyphtounicode{afii10074}{0438}% +\pdfglyphtounicode{afii10075}{0439}% +\pdfglyphtounicode{afii10076}{043A}% +\pdfglyphtounicode{afii10077}{043B}% +\pdfglyphtounicode{afii10078}{043C}% +\pdfglyphtounicode{afii10079}{043D}% +\pdfglyphtounicode{afii10080}{043E}% +\pdfglyphtounicode{afii10081}{043F}% +\pdfglyphtounicode{afii10082}{0440}% +\pdfglyphtounicode{afii10083}{0441}% +\pdfglyphtounicode{afii10084}{0442}% +\pdfglyphtounicode{afii10085}{0443}% +\pdfglyphtounicode{afii10086}{0444}% +\pdfglyphtounicode{afii10087}{0445}% +\pdfglyphtounicode{afii10088}{0446}% +\pdfglyphtounicode{afii10089}{0447}% +\pdfglyphtounicode{afii10090}{0448}% +\pdfglyphtounicode{afii10091}{0449}% +\pdfglyphtounicode{afii10092}{044A}% +\pdfglyphtounicode{afii10093}{044B}% +\pdfglyphtounicode{afii10094}{044C}% +\pdfglyphtounicode{afii10095}{044D}% +\pdfglyphtounicode{afii10096}{044E}% +\pdfglyphtounicode{afii10097}{044F}% +\pdfglyphtounicode{afii10071}{0451}% +\pdfglyphtounicode{afii10099}{0452}% +\pdfglyphtounicode{afii10100}{0453}% +\pdfglyphtounicode{afii10101}{0454}% +\pdfglyphtounicode{afii10102}{0455}% +\pdfglyphtounicode{afii10103}{0456}% +\pdfglyphtounicode{afii10104}{0457}% +\pdfglyphtounicode{afii10105}{0458}% +\pdfglyphtounicode{afii10106}{0459}% +\pdfglyphtounicode{afii10107}{045A}% +\pdfglyphtounicode{afii10108}{045B}% +\pdfglyphtounicode{afii10109}{045C}% +\pdfglyphtounicode{afii10110}{045E}% +\pdfglyphtounicode{afii10193}{045F}% +\pdfglyphtounicode{afii10146}{0462}% +\pdfglyphtounicode{afii10194}{0463}% +\pdfglyphtounicode{afii10147}{0472}% +\pdfglyphtounicode{afii10195}{0473}% +\pdfglyphtounicode{afii10148}{0474}% +\pdfglyphtounicode{afii10196}{0475}% +\pdfglyphtounicode{afii10050}{0490}% +\pdfglyphtounicode{afii10098}{0491}% +\pdfglyphtounicode{afii10846}{04D9}% +\pdfglyphtounicode{afii57799}{05B0}% +\pdfglyphtounicode{afii57801}{05B1}% +\pdfglyphtounicode{afii57800}{05B2}% +\pdfglyphtounicode{afii57802}{05B3}% +\pdfglyphtounicode{afii57793}{05B4}% +\pdfglyphtounicode{afii57794}{05B5}% +\pdfglyphtounicode{afii57795}{05B6}% +\pdfglyphtounicode{afii57798}{05B7}% +\pdfglyphtounicode{afii57797}{05B8}% +\pdfglyphtounicode{afii57806}{05B9}% +\pdfglyphtounicode{afii57796}{05BB}% +\pdfglyphtounicode{afii57807}{05BC}% +\pdfglyphtounicode{afii57839}{05BD}% +\pdfglyphtounicode{afii57645}{05BE}% +\pdfglyphtounicode{afii57841}{05BF}% +\pdfglyphtounicode{afii57842}{05C0}% +\pdfglyphtounicode{afii57804}{05C1}% +\pdfglyphtounicode{afii57803}{05C2}% +\pdfglyphtounicode{afii57658}{05C3}% +\pdfglyphtounicode{afii57664}{05D0}% +\pdfglyphtounicode{afii57665}{05D1}% +\pdfglyphtounicode{afii57666}{05D2}% +\pdfglyphtounicode{afii57667}{05D3}% +\pdfglyphtounicode{afii57668}{05D4}% +\pdfglyphtounicode{afii57669}{05D5}% +\pdfglyphtounicode{afii57670}{05D6}% +\pdfglyphtounicode{afii57671}{05D7}% +\pdfglyphtounicode{afii57672}{05D8}% +\pdfglyphtounicode{afii57673}{05D9}% +\pdfglyphtounicode{afii57674}{05DA}% +\pdfglyphtounicode{afii57675}{05DB}% +\pdfglyphtounicode{afii57676}{05DC}% +\pdfglyphtounicode{afii57677}{05DD}% +\pdfglyphtounicode{afii57678}{05DE}% +\pdfglyphtounicode{afii57679}{05DF}% +\pdfglyphtounicode{afii57680}{05E0}% +\pdfglyphtounicode{afii57681}{05E1}% +\pdfglyphtounicode{afii57682}{05E2}% +\pdfglyphtounicode{afii57683}{05E3}% +\pdfglyphtounicode{afii57684}{05E4}% +\pdfglyphtounicode{afii57685}{05E5}% +\pdfglyphtounicode{afii57686}{05E6}% +\pdfglyphtounicode{afii57687}{05E7}% +\pdfglyphtounicode{afii57688}{05E8}% +\pdfglyphtounicode{afii57689}{05E9}% +\pdfglyphtounicode{afii57690}{05EA}% +\pdfglyphtounicode{afii57716}{05F0}% +\pdfglyphtounicode{afii57717}{05F1}% +\pdfglyphtounicode{afii57718}{05F2}% +\pdfglyphtounicode{afii57388}{060C}% +\pdfglyphtounicode{afii57403}{061B}% +\pdfglyphtounicode{afii57407}{061F}% +\pdfglyphtounicode{afii57409}{0621}% +\pdfglyphtounicode{afii57410}{0622}% +\pdfglyphtounicode{afii57411}{0623}% +\pdfglyphtounicode{afii57412}{0624}% +\pdfglyphtounicode{afii57413}{0625}% +\pdfglyphtounicode{afii57414}{0626}% +\pdfglyphtounicode{afii57415}{0627}% +\pdfglyphtounicode{afii57416}{0628}% +\pdfglyphtounicode{afii57417}{0629}% +\pdfglyphtounicode{afii57418}{062A}% +\pdfglyphtounicode{afii57419}{062B}% +\pdfglyphtounicode{afii57420}{062C}% +\pdfglyphtounicode{afii57421}{062D}% +\pdfglyphtounicode{afii57422}{062E}% +\pdfglyphtounicode{afii57423}{062F}% +\pdfglyphtounicode{afii57424}{0630}% +\pdfglyphtounicode{afii57425}{0631}% +\pdfglyphtounicode{afii57426}{0632}% +\pdfglyphtounicode{afii57427}{0633}% +\pdfglyphtounicode{afii57428}{0634}% +\pdfglyphtounicode{afii57429}{0635}% +\pdfglyphtounicode{afii57430}{0636}% +\pdfglyphtounicode{afii57431}{0637}% +\pdfglyphtounicode{afii57432}{0638}% +\pdfglyphtounicode{afii57433}{0639}% +\pdfglyphtounicode{afii57434}{063A}% +\pdfglyphtounicode{afii57440}{0640}% +\pdfglyphtounicode{afii57441}{0641}% +\pdfglyphtounicode{afii57442}{0642}% +\pdfglyphtounicode{afii57443}{0643}% +\pdfglyphtounicode{afii57444}{0644}% +\pdfglyphtounicode{afii57445}{0645}% +\pdfglyphtounicode{afii57446}{0646}% +\pdfglyphtounicode{afii57470}{0647}% +\pdfglyphtounicode{afii57448}{0648}% +\pdfglyphtounicode{afii57449}{0649}% +\pdfglyphtounicode{afii57450}{064A}% +\pdfglyphtounicode{afii57451}{064B}% +\pdfglyphtounicode{afii57452}{064C}% +\pdfglyphtounicode{afii57453}{064D}% +\pdfglyphtounicode{afii57454}{064E}% +\pdfglyphtounicode{afii57455}{064F}% +\pdfglyphtounicode{afii57456}{0650}% +\pdfglyphtounicode{afii57457}{0651}% +\pdfglyphtounicode{afii57458}{0652}% +\pdfglyphtounicode{afii57392}{0660}% +\pdfglyphtounicode{afii57393}{0661}% +\pdfglyphtounicode{afii57394}{0662}% +\pdfglyphtounicode{afii57395}{0663}% +\pdfglyphtounicode{afii57396}{0664}% +\pdfglyphtounicode{afii57397}{0665}% +\pdfglyphtounicode{afii57398}{0666}% +\pdfglyphtounicode{afii57399}{0667}% +\pdfglyphtounicode{afii57400}{0668}% +\pdfglyphtounicode{afii57401}{0669}% +\pdfglyphtounicode{afii57381}{066A}% +\pdfglyphtounicode{afii63167}{066D}% +\pdfglyphtounicode{afii57511}{0679}% +\pdfglyphtounicode{afii57506}{067E}% +\pdfglyphtounicode{afii57507}{0686}% +\pdfglyphtounicode{afii57512}{0688}% +\pdfglyphtounicode{afii57513}{0691}% +\pdfglyphtounicode{afii57508}{0698}% +\pdfglyphtounicode{afii57505}{06A4}% +\pdfglyphtounicode{afii57509}{06AF}% +\pdfglyphtounicode{afii57514}{06BA}% +\pdfglyphtounicode{afii57519}{06D2}% +\pdfglyphtounicode{afii57534}{06D5}% +\pdfglyphtounicode{Wgrave}{1E80}% +\pdfglyphtounicode{wgrave}{1E81}% +\pdfglyphtounicode{Wacute}{1E82}% +\pdfglyphtounicode{wacute}{1E83}% +\pdfglyphtounicode{Wdieresis}{1E84}% +\pdfglyphtounicode{wdieresis}{1E85}% +\pdfglyphtounicode{Ygrave}{1EF2}% +\pdfglyphtounicode{ygrave}{1EF3}% +\pdfglyphtounicode{afii61664}{200C}% +\pdfglyphtounicode{afii301}{200D}% +\pdfglyphtounicode{afii299}{200E}% +\pdfglyphtounicode{afii300}{200F}% +\pdfglyphtounicode{figuredash}{2012}% +\pdfglyphtounicode{endash}{2013}% +\pdfglyphtounicode{emdash}{2014}% +\pdfglyphtounicode{afii208}{2015}% +\pdfglyphtounicode{underscoredbl}{2017}% +\pdfglyphtounicode{quoteleft}{2018}% +\pdfglyphtounicode{quoteright}{2019}% +\pdfglyphtounicode{quotesinglbase}{201A}% +\pdfglyphtounicode{quotereversed}{201B}% +\pdfglyphtounicode{quotedblleft}{201C}% +\pdfglyphtounicode{quotedblright}{201D}% +\pdfglyphtounicode{quotedblbase}{201E}% +\pdfglyphtounicode{dagger}{2020}% +\pdfglyphtounicode{daggerdbl}{2021}% +\pdfglyphtounicode{bullet}{2022}% +\pdfglyphtounicode{onedotenleader}{2024}% +\pdfglyphtounicode{twodotenleader}{2025}% +\pdfglyphtounicode{ellipsis}{2026}% +\pdfglyphtounicode{afii61573}{202C}% +\pdfglyphtounicode{afii61574}{202D}% +\pdfglyphtounicode{afii61575}{202E}% +\pdfglyphtounicode{perthousand}{2030}% +\pdfglyphtounicode{minute}{2032}% +\pdfglyphtounicode{second}{2033}% +\pdfglyphtounicode{guilsinglleft}{2039}% +\pdfglyphtounicode{guilsinglright}{203A}% +\pdfglyphtounicode{exclamdbl}{203C}% +\pdfglyphtounicode{fraction}{2044}% +\pdfglyphtounicode{colonmonetary}{20A1}% +\pdfglyphtounicode{franc}{20A3}% +\pdfglyphtounicode{lira}{20A4}% +\pdfglyphtounicode{peseta}{20A7}% +\pdfglyphtounicode{afii57636}{20AA}% +\pdfglyphtounicode{dong}{20AB}% +\pdfglyphtounicode{Euro}{20AC}% +\pdfglyphtounicode{afii61248}{2105}% +\pdfglyphtounicode{Ifraktur}{2111}% +\pdfglyphtounicode{afii61289}{2113}% +\pdfglyphtounicode{afii61352}{2116}% +\pdfglyphtounicode{weierstrass}{2118}% +\pdfglyphtounicode{Rfraktur}{211C}% +\pdfglyphtounicode{prescription}{211E}% +\pdfglyphtounicode{trademark}{2122}% +\pdfglyphtounicode{Omega}{2126}% +\pdfglyphtounicode{estimated}{212E}% +\pdfglyphtounicode{aleph}{2135}% +\pdfglyphtounicode{onethird}{2153}% +\pdfglyphtounicode{twothirds}{2154}% +\pdfglyphtounicode{oneeighth}{215B}% +\pdfglyphtounicode{threeeighths}{215C}% +\pdfglyphtounicode{fiveeighths}{215D}% +\pdfglyphtounicode{seveneighths}{215E}% +\pdfglyphtounicode{arrowleft}{2190}% +\pdfglyphtounicode{arrowup}{2191}% +\pdfglyphtounicode{arrowright}{2192}% +\pdfglyphtounicode{arrowdown}{2193}% +\pdfglyphtounicode{arrowboth}{2194}% +\pdfglyphtounicode{arrowupdn}{2195}% +\pdfglyphtounicode{arrowupdnbse}{21A8}% +\pdfglyphtounicode{carriagereturn}{21B5}% +\pdfglyphtounicode{arrowdblleft}{21D0}% +\pdfglyphtounicode{arrowdblup}{21D1}% +\pdfglyphtounicode{arrowdblright}{21D2}% +\pdfglyphtounicode{arrowdbldown}{21D3}% +\pdfglyphtounicode{arrowdblboth}{21D4}% +\pdfglyphtounicode{universal}{2200}% +\pdfglyphtounicode{partialdiff}{2202}% +\pdfglyphtounicode{existential}{2203}% +\pdfglyphtounicode{emptyset}{2205}% +\pdfglyphtounicode{Delta}{2206}% +\pdfglyphtounicode{gradient}{2207}% +\pdfglyphtounicode{element}{2208}% +\pdfglyphtounicode{notelement}{2209}% +\pdfglyphtounicode{suchthat}{220B}% +\pdfglyphtounicode{product}{220F}% +\pdfglyphtounicode{summation}{2211}% +\pdfglyphtounicode{minus}{2212}% +\pdfglyphtounicode{asteriskmath}{2217}% +\pdfglyphtounicode{radical}{221A}% +\pdfglyphtounicode{proportional}{221D}% +\pdfglyphtounicode{infinity}{221E}% +\pdfglyphtounicode{orthogonal}{221F}% +\pdfglyphtounicode{angle}{2220}% +\pdfglyphtounicode{logicaland}{2227}% +\pdfglyphtounicode{logicalor}{2228}% +\pdfglyphtounicode{intersection}{2229}% +\pdfglyphtounicode{union}{222A}% +\pdfglyphtounicode{integral}{222B}% +\pdfglyphtounicode{therefore}{2234}% +\pdfglyphtounicode{similar}{223C}% +\pdfglyphtounicode{congruent}{2245}% +\pdfglyphtounicode{approxequal}{2248}% +\pdfglyphtounicode{notequal}{2260}% +\pdfglyphtounicode{equivalence}{2261}% +\pdfglyphtounicode{lessequal}{2264}% +\pdfglyphtounicode{greaterequal}{2265}% +\pdfglyphtounicode{propersubset}{2282}% +\pdfglyphtounicode{propersuperset}{2283}% +\pdfglyphtounicode{notsubset}{2284}% +\pdfglyphtounicode{reflexsubset}{2286}% +\pdfglyphtounicode{reflexsuperset}{2287}% +\pdfglyphtounicode{circleplus}{2295}% +\pdfglyphtounicode{circlemultiply}{2297}% +\pdfglyphtounicode{perpendicular}{22A5}% +\pdfglyphtounicode{dotmath}{22C5}% +\pdfglyphtounicode{house}{2302}% +\pdfglyphtounicode{revlogicalnot}{2310}% +\pdfglyphtounicode{integraltp}{2320}% +\pdfglyphtounicode{integralbt}{2321}% +\pdfglyphtounicode{angleleft}{2329}% +\pdfglyphtounicode{angleright}{232A}% +\pdfglyphtounicode{SF100000}{2500}% +\pdfglyphtounicode{SF110000}{2502}% +\pdfglyphtounicode{SF10000}{250C}% +\pdfglyphtounicode{SF30000}{2510}% +\pdfglyphtounicode{SF20000}{2514}% +\pdfglyphtounicode{SF40000}{2518}% +\pdfglyphtounicode{SF80000}{251C}% +\pdfglyphtounicode{SF90000}{2524}% +\pdfglyphtounicode{SF60000}{252C}% +\pdfglyphtounicode{SF70000}{2534}% +\pdfglyphtounicode{SF50000}{253C}% +\pdfglyphtounicode{SF430000}{2550}% +\pdfglyphtounicode{SF240000}{2551}% +\pdfglyphtounicode{SF510000}{2552}% +\pdfglyphtounicode{SF520000}{2553}% +\pdfglyphtounicode{SF390000}{2554}% +\pdfglyphtounicode{SF220000}{2555}% +\pdfglyphtounicode{SF210000}{2556}% +\pdfglyphtounicode{SF250000}{2557}% +\pdfglyphtounicode{SF500000}{2558}% +\pdfglyphtounicode{SF490000}{2559}% +\pdfglyphtounicode{SF380000}{255A}% +\pdfglyphtounicode{SF280000}{255B}% +\pdfglyphtounicode{SF270000}{255C}% +\pdfglyphtounicode{SF260000}{255D}% +\pdfglyphtounicode{SF360000}{255E}% +\pdfglyphtounicode{SF370000}{255F}% +\pdfglyphtounicode{SF420000}{2560}% +\pdfglyphtounicode{SF190000}{2561}% +\pdfglyphtounicode{SF200000}{2562}% +\pdfglyphtounicode{SF230000}{2563}% +\pdfglyphtounicode{SF470000}{2564}% +\pdfglyphtounicode{SF480000}{2565}% +\pdfglyphtounicode{SF410000}{2566}% +\pdfglyphtounicode{SF450000}{2567}% +\pdfglyphtounicode{SF460000}{2568}% +\pdfglyphtounicode{SF400000}{2569}% +\pdfglyphtounicode{SF540000}{256A}% +\pdfglyphtounicode{SF530000}{256B}% +\pdfglyphtounicode{SF440000}{256C}% +\pdfglyphtounicode{upblock}{2580}% +\pdfglyphtounicode{dnblock}{2584}% +\pdfglyphtounicode{block}{2588}% +\pdfglyphtounicode{lfblock}{258C}% +\pdfglyphtounicode{rtblock}{2590}% +\pdfglyphtounicode{ltshade}{2591}% +\pdfglyphtounicode{shade}{2592}% +\pdfglyphtounicode{dkshade}{2593}% +\pdfglyphtounicode{filledbox}{25A0}% +\pdfglyphtounicode{H22073}{25A1}% +\pdfglyphtounicode{H18543}{25AA}% +\pdfglyphtounicode{H18551}{25AB}% +\pdfglyphtounicode{filledrect}{25AC}% +\pdfglyphtounicode{triagup}{25B2}% +\pdfglyphtounicode{triagrt}{25BA}% +\pdfglyphtounicode{triagdn}{25BC}% +\pdfglyphtounicode{triaglf}{25C4}% +\pdfglyphtounicode{lozenge}{25CA}% +\pdfglyphtounicode{circle}{25CB}% +\pdfglyphtounicode{H18533}{25CF}% +\pdfglyphtounicode{invbullet}{25D8}% +\pdfglyphtounicode{invcircle}{25D9}% +\pdfglyphtounicode{openbullet}{25E6}% +\pdfglyphtounicode{smileface}{263A}% +\pdfglyphtounicode{invsmileface}{263B}% +\pdfglyphtounicode{sun}{263C}% +\pdfglyphtounicode{female}{2640}% +\pdfglyphtounicode{male}{2642}% +\pdfglyphtounicode{spade}{2660}% +\pdfglyphtounicode{club}{2663}% +\pdfglyphtounicode{heart}{2665}% +\pdfglyphtounicode{diamond}{2666}% +\pdfglyphtounicode{musicalnote}{266A}% +\pdfglyphtounicode{musicalnotedbl}{266B}% +% +\endinput diff --git a/tex/context/base/pdfr-ec.mkii b/tex/context/base/pdfr-ec.mkii new file mode 100644 index 000000000..b6604984c --- /dev/null +++ b/tex/context/base/pdfr-ec.mkii @@ -0,0 +1,145 @@ +%D \module +%D [ file=pdfr-ec, +%D version=2005.07.27, +%D title=\CONTEXT\ PDF Font Resources, +%D subtitle=EC encoding, +%D author={Vladimir Volovich / 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. + +%D This vector is derived (but reformatted a bit) from +%D the one in \LaTeX's CMap package + +\startpdffontresource[ec] +/CIDInit /ProcSet findresource begin +12 dict begin + begincmap + /CIDSystemInfo + << /Registry (TeX) + /Ordering (T1) + /Supplement 0 + >> def + /CMapName /TeX-T1-0 def + /CMapType 2 def + 1 begincodespacerange + <00> + endcodespacerange + 10 beginbfrange + <0E> <0F> <2039> + <10> <12> <201C> + <15> <16> <2013> + <21> <26> <0021> + <28> <5F> <0028> + <61> <7E> <0061> + <00C0> + <00D8> + <00E0> + <00F8> + endbfrange + 95 beginbfchar + <00> <0060> + <01> <00B4> + <02> <02C6> + <03> <02DC> + <04> <00A8> + <05> <02DD> + <06> <02DA> + <07> <02C7> + <08> <02D8> + <09> <00AF> + <0A> <02D9> + <0B> <00B8> + <0C> <02DB> + <0D> <201A> + <13> <00AB> + <14> <00BB> + <17> <200C> + <19> <0131> + <1B> <00660066> + <1C> <00660069> + <1D> <0066006C> + <1E> <006600660069> + <1F> <00660066006C> + <20> <2423> + <27> <2019> + <60> <2018> + <7F> <002D> + <80> <0102> + <81> <0104> + <82> <0106> + <83> <010C> + <84> <010E> + <85> <011A> + <86> <0118> + <87> <011E> + <88> <0139> + <89> <013D> + <8A> <0141> + <8B> <0143> + <8C> <0147> + <8D> <014A> + <8E> <0150> + <8F> <0154> + <90> <0158> + <91> <015A> + <92> <0160> + <93> <015E> + <94> <0164> + <95> <021A> + <96> <0170> + <97> <016E> + <98> <0178> + <99> <0179> + <9A> <017D> + <9B> <017B> + <9C> <0132> + <9D> <0130> + <9E> <0111> + <9F> <00A7> + <0103> + <0105> + <0107> + <010D> + <010F> + <011B> + <0119> + <011F> + <013A> + <013E> + <0142> + <0144> + <0148> + <014B> + <0151> + <0155> + <0159> + <015B> + <0161> + <015F> + <0165> + <021B> + <0171> + <016F> + <00FF> + <017A> + <017E> + <017C> + <0133> + <00A1> + <00BF> + <00A3> + <0152> + <00530053> + <0153> + <00DF> + endbfchar + endcmap +CMapName currentdict /CMap defineresource pop end +end +\stoppdffontresource + +\endinput diff --git a/tex/context/base/pdfr-il2.mkii b/tex/context/base/pdfr-il2.mkii new file mode 100644 index 000000000..70bcb25da --- /dev/null +++ b/tex/context/base/pdfr-il2.mkii @@ -0,0 +1,233 @@ +%D \module +%D [ file=pdfr-il2, +%D version=2000.12.10, +%D title=\CONTEXT\ PDF Font Resources, +%D subtitle=ISO Latin 2, +%D author={Ondrej Koala Vacha, Hans Hagen}, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 vector is derived (but reformatted a bit) from a +%D sample send to me by Petr Ferdus. There was some Czech +%D comment in which I could recognize the name of Ondrej +%D Koala Vacha. More information on setting up such a vector +%D can be found in the \PDF\ reference manual. + +\startpdffontresource[il2] +/CIDInit /ProcSet findresource begin +12 dict begin + begincmap + /CIDSystemInfo + << /Registry (Adobe) + /Ordering (T1UV) + /Supplement 0 + >> def + /CMapName /Adobe-Identity-UCS def + /CMapType 1 def + 1 begincodespacerange + <00> + endcodespacerange + %%FontSpecificEncoding + 191 beginbfrange + <20> <20> <0020> % space dec: 32 oct:040 hex:20 + <21> <21> <0021> % exclam dec: 33 oct:041 hex:21 + <22> <22> <0022> % quotedbl dec: 34 oct:042 hex:22 + <23> <23> <0023> % numbersign dec: 35 oct:043 hex:23 + <24> <24> <0024> % dollar dec: 36 oct:044 hex:24 + <25> <25> <0025> % percent dec: 37 oct:045 hex:25 + <26> <26> <0026> % ampersand dec: 38 oct:046 hex:26 + <27> <27> <0027> % quotesingle dec: 39 oct:047 hex:27 + <28> <28> <0028> % parenleft dec: 40 oct:050 hex:28 + <29> <29> <0029> % parenright dec: 41 oct:051 hex:29 + <2a> <2a> <002a> % asterisk dec: 42 oct:052 hex:2a + <2b> <2b> <002b> % plus dec: 43 oct:053 hex:2b + <2c> <2c> <002c> % comma dec: 44 oct:054 hex:2c + <2d> <2d> <002d> % hyphen dec: 45 oct:055 hex:2d + <2e> <2e> <002e> % period dec: 46 oct:056 hex:2e + <2f> <2f> <002f> % slash dec: 47 oct:057 hex:2f + <30> <30> <0030> % zero dec: 48 oct:060 hex:30 + <31> <31> <0031> % one dec: 49 oct:061 hex:31 + <32> <32> <0032> % two dec: 50 oct:062 hex:32 + <33> <33> <0033> % three dec: 51 oct:063 hex:33 + <34> <34> <0034> % four dec: 52 oct:064 hex:34 + <35> <35> <0035> % five dec: 53 oct:065 hex:35 + <36> <36> <0036> % six dec: 54 oct:066 hex:36 + <37> <37> <0037> % seven dec: 55 oct:067 hex:37 + <38> <38> <0038> % eight dec: 56 oct:070 hex:38 + <39> <39> <0039> % nine dec: 57 oct:071 hex:39 + <3a> <3a> <003a> % colon dec: 58 oct:072 hex:3a + <3b> <3b> <003b> % semicolon dec: 59 oct:073 hex:3b + <3c> <3c> <003c> % less dec: 60 oct:074 hex:3c + <3d> <3d> <003d> % equal dec: 61 oct:075 hex:3d + <3e> <3e> <003e> % greater dec: 62 oct:076 hex:3e + <3f> <3f> <003f> % question dec: 63 oct:077 hex:3f + <40> <40> <0040> % at dec: 64 oct:100 hex:40 + <41> <41> <0041> % A dec: 65 oct:101 hex:41 + <42> <42> <0042> % B dec: 66 oct:102 hex:42 + <43> <43> <0043> % C dec: 67 oct:103 hex:43 + <44> <44> <0044> % D dec: 68 oct:104 hex:44 + <45> <45> <0045> % E dec: 69 oct:105 hex:45 + <46> <46> <0046> % F dec: 70 oct:106 hex:46 + <47> <47> <0047> % G dec: 71 oct:107 hex:47 + <48> <48> <0048> % H dec: 72 oct:110 hex:48 + <49> <49> <0049> % I dec: 73 oct:111 hex:49 + <4a> <4a> <004a> % J dec: 74 oct:112 hex:4a + <4b> <4b> <004b> % K dec: 75 oct:113 hex:4b + <4c> <4c> <004c> % L dec: 76 oct:114 hex:4c + <4d> <4d> <004d> % M dec: 77 oct:115 hex:4d + <4e> <4e> <004e> % N dec: 78 oct:116 hex:4e + <4f> <4f> <004f> % O dec: 79 oct:117 hex:4f + <50> <50> <0050> % P dec: 80 oct:120 hex:50 + <51> <51> <0051> % Q dec: 81 oct:121 hex:51 + <52> <52> <0052> % R dec: 82 oct:122 hex:52 + <53> <53> <0053> % S dec: 83 oct:123 hex:53 + <54> <54> <0054> % T dec: 84 oct:124 hex:54 + <55> <55> <0055> % U dec: 85 oct:125 hex:55 + <56> <56> <0056> % V dec: 86 oct:126 hex:56 + <57> <57> <0057> % W dec: 87 oct:127 hex:57 + <58> <58> <0058> % X dec: 88 oct:130 hex:58 + <59> <59> <0059> % Y dec: 89 oct:131 hex:59 + <5a> <5a> <005a> % Z dec: 90 oct:132 hex:5a + <5b> <5b> <005b> % bracketleft dec: 91 oct:133 hex:5b + <5c> <5c> <005c> % backslash dec: 92 oct:134 hex:5c + <5d> <5d> <005d> % bracketright dec: 93 oct:135 hex:5d + <5e> <5e> <005e> % asciicircum dec: 94 oct:136 hex:5e + <5f> <5f> <005f> % underscore dec: 95 oct:137 hex:5f + <60> <60> <0060> % grave dec: 96 oct:140 hex:60 + <61> <61> <0061> % a dec: 97 oct:141 hex:61 + <62> <62> <0062> % b dec: 98 oct:142 hex:62 + <63> <63> <0063> % c dec: 99 oct:143 hex:63 + <64> <64> <0064> % d dec:100 oct:144 hex:64 + <65> <65> <0065> % e dec:101 oct:145 hex:65 + <66> <66> <0066> % f dec:102 oct:146 hex:66 + <67> <67> <0067> % g dec:103 oct:147 hex:67 + <68> <68> <0068> % h dec:104 oct:150 hex:68 + <69> <69> <0069> % i dec:105 oct:151 hex:69 + <6a> <6a> <006a> % j dec:106 oct:152 hex:6a + <6b> <6b> <006b> % k dec:107 oct:153 hex:6b + <6c> <6c> <006c> % l dec:108 oct:154 hex:6c + <6d> <6d> <006d> % m dec:109 oct:155 hex:6d + <6e> <6e> <006e> % n dec:110 oct:156 hex:6e + <6f> <6f> <006f> % o dec:111 oct:157 hex:6f + <70> <70> <0070> % p dec:112 oct:160 hex:70 + <71> <71> <0071> % q dec:113 oct:161 hex:71 + <72> <72> <0072> % r dec:114 oct:162 hex:72 + <73> <73> <0073> % s dec:115 oct:163 hex:73 + <74> <74> <0074> % t dec:116 oct:164 hex:74 + <75> <75> <0075> % u dec:117 oct:165 hex:75 + <76> <76> <0076> % v dec:118 oct:166 hex:76 + <77> <77> <0077> % w dec:119 oct:167 hex:77 + <78> <78> <0078> % x dec:120 oct:170 hex:78 + <79> <79> <0079> % y dec:121 oct:171 hex:79 + <7a> <7a> <007a> % z dec:122 oct:172 hex:7a + <7b> <7b> <007b> % braceleft dec:123 oct:173 hex:7b + <7c> <7c> <007c> % bar dec:124 oct:174 hex:7c + <7d> <7d> <007d> % braceright dec:125 oct:175 hex:7d + <7e> <7e> <007e> % asciitilde dec:126 oct:176 hex:7e + <00a0> % nbspace dec:160 oct:240 hex:a0 + <0104> % Aogonek dec:161 oct:241 hex:a1 + <00a2> % breve dec:162 oct:242 hex:a2 + <00a3> % Lslash dec:163 oct:243 hex:a3 + <00a4> % currency dec:164 oct:244 hex:a4 + <013d> % Lcaron dec:165 oct:245 hex:a5 + <015a> % Sacute dec:166 oct:246 hex:a6 + <00a7> % section dec:167 oct:247 hex:a7 + <00a8> % dieresis dec:168 oct:250 hex:a8 + <0160> % Scaron dec:169 oct:251 hex:a9 + <015e> % Scedilla dec:170 oct:252 hex:aa + <0164> % Tcaron dec:171 oct:253 hex:ab + <0179> % Zacute dec:172 oct:254 hex:ac + <00ad> % sfthyphen dec:173 oct:255 hex:ad + <017d> % Zcaron dec:174 oct:256 hex:ae + <00af> % Zdotaccent dec:175 oct:257 hex:af + <00b0> % ring dec:176 oct:260 hex:b0 + <0105> % aogonek dec:177 oct:261 hex:b1 + <00b2> % ogonek dec:178 oct:262 hex:b2 + <00b3> % lslash dec:179 oct:263 hex:b3 + <00b4> % acute dec:180 oct:264 hex:b4 + <013e> % lcaron dec:181 oct:265 hex:b5 + <015b> % sacute dec:182 oct:266 hex:b6 + <00b7> % caron dec:183 oct:267 hex:b7 + <00b8> % cedilla dec:184 oct:270 hex:b8 + <0161> % scaron dec:185 oct:271 hex:b9 + <015f> % scedilla dec:186 oct:272 hex:ba + <0165> % tcaron dec:187 oct:273 hex:bb + <017a> % zacute dec:188 oct:274 hex:bc + <00bd> % hungarumlaut dec:189 oct:275 hex:bd + <017e> % zcaron dec:190 oct:276 hex:be + <00bf> % zdotaccent dec:191 oct:277 hex:bf + <0154> % Racute dec:192 oct:300 hex:c0 + <00c1> % Aacute dec:193 oct:301 hex:c1 + <00c2> % Acircumflex dec:194 oct:302 hex:c2 + <0102> % Abreve dec:195 oct:303 hex:c3 + <00c4> % Adieresis dec:196 oct:304 hex:c4 + <0139> % Lacute dec:197 oct:305 hex:c5 + <0106> % Cacute dec:198 oct:306 hex:c6 + <00c7> % Ccedilla dec:199 oct:307 hex:c7 + <010c> % Ccaron dec:200 oct:310 hex:c8 + <00c9> % Eacute dec:201 oct:311 hex:c9 + <0118> % Eogonek dec:202 oct:312 hex:ca + <00cb> % Edieresis dec:203 oct:313 hex:cb + <011a> % Ecaron dec:204 oct:314 hex:cc + <00cd> % Iacute dec:205 oct:315 hex:cd + <00ce> % Icircumflex dec:206 oct:316 hex:ce + <010e> % Dcaron dec:207 oct:317 hex:cf + <00d0> % Dslash dec:208 oct:320 hex:d0 + <0143> % Nacute dec:209 oct:321 hex:d1 + <0147> % Ncaron dec:210 oct:322 hex:d2 + <00d3> % Oacute dec:211 oct:323 hex:d3 + <00d4> % Ocircumflex dec:212 oct:324 hex:d4 + <00d5> % Ohungarumlaut dec:213 oct:325 hex:d5 + <00d6> % Odieresis dec:214 oct:326 hex:d6 + <00d7> % multiply dec:215 oct:327 hex:d7 + <0158> % Rcaron dec:216 oct:330 hex:d8 + <016e> % Uring dec:217 oct:331 hex:d9 + <00da> % Uacute dec:218 oct:332 hex:da + <00db> % Uhungarumlaut dec:219 oct:333 hex:db + <00dc> % Udieresis dec:220 oct:334 hex:dc +
<00dd> % Yacute dec:221 oct:335 hex:dd + <00de> % Tcommaaccent dec:222 oct:336 hex:de + <00df> % germandbls dec:223 oct:337 hex:df + <0155> % racute dec:224 oct:340 hex:e0 + <00e1> % aacute dec:225 oct:341 hex:e1 + <00e2> % acircumflex dec:226 oct:342 hex:e2 + <0103> % abreve dec:227 oct:343 hex:e3 + <00e4> % adieresis dec:228 oct:344 hex:e4 + <013a> % lacute dec:229 oct:345 hex:e5 + <0107> % cacute dec:230 oct:346 hex:e6 + <00e7> % ccedilla dec:231 oct:347 hex:e7 + <010d> % ccaron dec:232 oct:350 hex:e8 + <00e9> % eacute dec:233 oct:351 hex:e9 + <0119> % eogonek dec:234 oct:352 hex:ea + <00eb> % edieresis dec:235 oct:353 hex:eb + <011b> % ecaron dec:236 oct:354 hex:ec + <00ed> % iacute dec:237 oct:355 hex:ed + <00ee> % icircumflex dec:238 oct:356 hex:ee + <010f> % dcaron dec:239 oct:357 hex:ef + <00f0> % dmacron dec:240 oct:360 hex:f0 + <0144> % nacute dec:241 oct:361 hex:f1 + <0148> % ncaron dec:242 oct:362 hex:f2 + <00f3> % oacute dec:243 oct:363 hex:f3 + <00f4> % ocircumflex dec:244 oct:364 hex:f4 + <00f5> % ohungarumlaut dec:245 oct:365 hex:f5 + <00f6> % odieresis dec:246 oct:366 hex:f6 + <00f7> % divide dec:247 oct:367 hex:f7 + <0159> % rcaron dec:248 oct:370 hex:f8 + <016f> % uring dec:249 oct:371 hex:f9 + <00fa> % uacute dec:250 oct:372 hex:fa + <00fb> % uhungarumlaut dec:251 oct:373 hex:fb + <00fc> % udieresis dec:252 oct:374 hex:fc + <00fd> % yacute dec:253 oct:375 hex:fd + <00fe> % tcommaaccent dec:254 oct:376 hex:fe + <00ff> % dotaccent dec:255 oct:377 hex:ff + endbfrange + endcmap +CMapName currentdict /CMap defineresource pop end +end +\stoppdffontresource + +\endinput diff --git a/tex/context/base/ppchtex.mkii b/tex/context/base/ppchtex.mkii new file mode 100644 index 000000000..045e9808b --- /dev/null +++ b/tex/context/base/ppchtex.mkii @@ -0,0 +1,3554 @@ +%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\plotchemicaldasheddeltaline#1#2#3#4% + {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax + \ifnum\chemicaldrawingmode=2 + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + x0 := \MPdivten[\chemicalxoffset]u ; + y0 := \MPdivten[\chemicalyoffset]u ; + x1 := \MPdivten[\the\!!counta]u ; + y1 := \MPdivten[\the\!!countb]u ; + x2 := \MPdivten[\the\!!countc]u ; + y2 := \MPdivten[\the\!!countd]u ; + z20 = z2 rotatedaround(z1,+5) ; + z21 = z2 rotatedaround(z1,-5) ; + draw (z1 rotatedaround(origin,-\chemicalangle)) shifted z0 ; + save n ; n := 5 ; + for i=1 upto n : + draw ((((z20--z21) shifted -z2) shifted (i/n)[z2,z1]) + rotatedaround(origin,-\chemicalangle)) shifted z0 ; + endfor + \stopMPdrawing + \account{#1}{#2}% + \account{#3}{#4}% + \else + \doplotchemicalline + \advance\!!countc by 16 \advance\!!countd by -21 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -8 \advance\!!countd by 14 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \fi} + +\def\plotchemicalwavyline#1#2#3#4% + {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax + \ifnum\chemicaldrawingmode=2 + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + x0 := \MPdivten[\chemicalxoffset]u ; + y0 := \MPdivten[\chemicalyoffset]u ; + x1 := \MPdivten[\the\!!counta]u ; + y1 := \MPdivten[\the\!!countb]u ; + x2 := \MPdivten[\the\!!countc]u ; + y2 := \MPdivten[\the\!!countd]u ; + save d ; pair d ; + d := z2 rotatedaround(z1,+5) shifted -z2 ; + save n ; n := 4 ; + draw ((for i=0 upto n-1 : + ((i)/n)[z1,z2] .. + ((i+.25)/n)[z1,z2] shifted d .. + ((i+.50)/n)[z1,z2] .. + ((i+.75)/n)[z1,z2] shifted -d .. + endfor + z2) rotatedaround(origin,-\chemicalangle)) shifted z0 ; + \stopMPdrawing + \account{#1}{#2}% + \account{#3}{#4}% + \else + \doplotchemicalline + \advance\!!countc by 16 \advance\!!countd by -21 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -8 \advance\!!countd by 14 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \fi} + +\def\processchemicaldasheddeltalinesegment#1#2% + {\bgroup + \def\plotchemicalline{\plotchemicaldasheddeltaline}% + \doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}% + \egroup} + +\def\processchemicalwavylinesegment#1#2% + {\bgroup + \def\plotchemicalline{\plotchemicalwavyline}% + \doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}% + \egroup} + +\def\processchemicalopenend#1#2% + {\doprocesschemicallinesegment0c\doprocesschemicalopenend{#1}{#2}} + +\def\doprocesschemicalopenend[#1][#2]% + {\chemicalrotate[#1]% + \dochemicaloffset{#1}% + \ifcase\chemicaldrawingmode + \beginpicture + \setquadratic\plot + 300 0 400 0 + 500 0 550 75 + 600 0 650 -75 + 700 0 750 75 + 800 0 850 -75 + 900 0 950 0 + 1050 0 / + \endpicture + \or + \rput{-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\psline(300,0)(500,0)% + \rput(500,0){\psplot[yunit=75,plotstyle=curve]{0}{720}{x sin}}% + \psline(950,0)(1050,0)}% + \or + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + x0 := \MPdivten[\chemicalxoffset]u ; + y0 := \MPdivten[\chemicalyoffset]u ; + draw + (((30.0u,0)--(50.0u,0){up}..(55.0u,7.5u).. + (60.0u,0)..(65.0u,-7.5u)..(70.0u,0).. + (75.0u,7.5u)..(80.0u,0)..(85.0u,-7.5u)..{up} + (90.0u,0)--(105.0u,0)) rotatedaround(origin,-\chemicalangle)) + shifted z0 ; + \stopMPdrawing + \fi + \undochemicaloffset} + +% \plotchemicalcircle{#1}{#2}{#3}{#4} +% +% #1: lengte van de boog in graden +% #2: x-coordinaat eindpunt +% #3: y-coordinaat eindpunt + +\newif\ifchemicaldotted + +\def\plotchemicalcircle#1#2#3#4#5#6% + {\bgroup + \ifcase\chemicaldrawingmode + \ifchemicaldotted + \findlength{\circulararc {#4} degrees from {#5} {#6} center at {0} {0} }% + \divide\totalarclength by 6 + \def\b{\the\totalarclength}% + \divide\totalarclength by 2 + \def\a{\the\totalarclength}% + \setdashpattern <\a,\b,\b,\b,\b,\b,\a> + \fi + \circulararc {#4} degrees from {#5} {#6} center at {0} {0} % + \or + \ifchemicaldotted + \psset{linestyle=dashed}% + \fi + \rput + {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\psarc(0,0){#3}{#1}{#2}}% + \or + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + r := \MPdivten[#3]*2u; + x0 := \MPdivten[\chemicalxoffset]u ; + y0 := \MPdivten[\chemicalyoffset]u ; + draw ((subpath (#1/45,#2/45) of (fullcircle scaled (r))) + rotatedaround (origin,\chemicalangle+150)) + shifted z0 \ifchemicaldotted dashed withdots \fi ; + \stopMPdrawing + \fi + \egroup} + +\def\setchemicalcircsegment #1 #2 #3 #4 #5 #6 #7 + {\setvalue{\s!chemicalcircsegment#1}{\plotchemicalcircle{#2}{#3}{#4}{#5}{#6}{#7}}} + +\def\getchemicalcircsegment[#1][#2]% + {\chemicalrotate[#1]% + \getvalue{\s!chemicalcircsegment#2}} + +\def\doprocesschemicalcircsegment#1#2% + {\def\doprocess[##1##2##3##4##5]% + {\doifelse{##1}{?} + {\doprocess[1..\maxchemical ????]} + {\doifchemicalnumber{##1}{#1#2} + {\doifelse{##2##3}{..} + {\doifchemicalnumber{##4}{#1#2} + {\getchemicalcircsegment[##1][#1]% + \doifnot{##1}{##4} + {\!!counta=##1\relax + \advance\!!counta by 1 + \edef\nextsegment{\the\!!counta}% + \doprocess[\nextsegment..##4##5]}}} + {\getchemicalcircsegment[##1][#1]% + \doifnot{##2}{?} + {\doprocess[##2##3##4##5]}}}}}% + \doprocess[#2]} + +\def\processchemicalcircsegment% + {\chemicaldottedfalse\doprocesschemicalcircsegment} + +\def\processchemicaldottsegment% + {\chemicaldottedtrue\doprocesschemicalcircsegment} + +\let\endchemicalpicture = \relax +\let\checkchemicalpicture = \relax +\let\nomoreaccounting = \relax + +\newif\ifchemicalpicture + +\def\beginchemicalpicture#1% NO PSTRICKS SUPPORT YET + {\checkchemicalpicture + \bgroup % DOES NOT HANDLE AUTOWIDTH/HEIGHT + \chemicalpicturetrue + \processchemical[#1]} + +\def\setchemicalpicture#1#2% + {\chemicalpicturefalse + \def\endchemicalpicture% + {\@@endchemicallocalpicture{#1}{#2}% + \egroup + \ifnum\chemicaldrawingmode=1 + \rput + {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\expanded{\rput[\chemicalloca]{\chemicalangle}(#1,#2){\box\nextbox}}}% + \else + \expanded{\put{\box\nextbox}[\chemicalloca] at {#1} {#2} } + \fi + \egroup}% + \def\checkchemicalpicture% + {\ifx\endchemicalpicture\relax \else + \writestatus{ppchtex}{missing end of picture (PE)}% + \endchemicalpicture + \fi}% + \setbox\nextbox=\hbox\bgroup + \@@beginchemicallocalpicture + % alternatief: gewoon accounting, en zelf l,r afhandelen + \ifnum\chemicaldrawingmode=1 + % njet + \else + \accountingon + \let\nomoreaccounting=\accountingoff + \fi} + +\def\doskipchemical[#1][#2]% + {{\tt[ppchtex]}} + +\def\skipchemical% + {\dodoubleargument\doskipchemical} + +\def\complexchemical% met \expandafter + {\ifinchemical + \expandafter\dochemical + \else + \writestatus{ppchtex}{the [][]-alternative is not permitted here}% + \expandafter\skipchemical + \fi} + +\newif\ifinnerchemical + +\def\dosimplechemical#1#2#3% + {\doifdefinedelse{\??chemical\c!location} + {\writestatus{ppchtex}{the {}{}-alternative is not permitted here}} + {\ifinnerchemical + \let\chemicalsign = \chemicalinnersign + \let\chemicalmolecule = \chemicalinnermolecule + \let\chemicalsinglearrow = \chemicalsingleinnerarrow + \let\chemicaldoublearrow = \chemicaldoubleinnerarrow + \let\chemicaltwintiparrow = \chemicaltwintipinnerarrow + \else + \let\chemicalsign = \chemicaloutersign + \let\chemicalmolecule = \chemicaloutermolecule + \let\chemicalsinglearrow = \chemicalsingleouterarrow + \let\chemicaldoublearrow = \chemicaldoubleouterarrow + \let\chemicaltwintiparrow = \chemicaltwintipouterarrow + \fi + \disablechemicalspecials + \unexpandedprocessallactionsinset + [#1] + [ HIGH=>\sethighsubscripts, + LOW=>\setlowsubscripts, + PLUS=>\chemicalsign{+}, + GIVES=>\chemicalsinglearrow{#2}{#3}, + EQUILIBRIUM=>\chemicaldoublearrow{#2}{#3}, + MESOMERIC=>\chemicaltwintiparrow{#2}{#3}, + SINGLE=>\singlechemicalbond, + DOUBLE=>\doublechemicalbond, + TRIPLE=>\triplechemicalbond, + +=>\chemicalsign{+}, + ->=>\chemicalsinglearrow{#2}{#3}, + <->=>\chemicaldoublearrow{#2}{#3}, + <>=>\chemicaltwintiparrow{#2}{#3}, + -=>\singlechemicalbond, + --=>\doublechemicalbond, + ---=>\triplechemicalbond, + \s!unknown=>\enablechemicalspecials + \chemicalmolecule{\commalistelement}{#2}{#3}]}} + +%\def\dosimplechemicalA#1#2#3% +% {\let\chemicalspace=\relax +% \def\dodosimplechemical##1% +% {\dosimplechemical{##1}{}{}}% +% \@EA\processcommalist\@EA[\@@chemicalchemicaloffset,#1]\dodosimplechemical +% \egroup} + +\def\dosimplechemicalA#1#2#3% % evt: {#1,\relax} + {\let\chemicalspace=\relax + \@EA\dosimplechemical\@EA{\@@chemicalchemicaloffset,#1}{#2}{#3}% + \egroup} + +\def\dosimplechemicalB#1#2#3% + {\dosimplechemical{#1}{#2}{#3}% + \egroup} + +\def\dosimplechemicalC#1#2#3% + {$\simplechemical{#1}{#2}{#3}$% + \egroup} % erbij + +\def\simplechemical + {\ifinner + \innerchemicaltrue + \else + \innerchemicalfalse + \fi + \bgroup + \catcode`\^=\@@superscript % t.b.v. \enableduplication + \catcode`\_=\@@subscript % t.b.v. de zekerheid + \ifmmode + \ifinnerchemical + \def\next{\dotriplegroupempty\dosimplechemicalA}% + \else + \def\next{\dotriplegroupempty\dosimplechemicalB}% + \fi + \else + \def\next{\dotriplegroupempty\dosimplechemicalC}% + \fi + \next} + +\definecomplexorsimple\chemical + +\def\dogotochemical#1#2% + {\def\dowithchemical% % experiment + {\localgotochemical{#1}}% % experiment + \chemical} % experiment + +\def\gotochemical% % experiment + {\dosingleargument\dogotochemical} % experiment + +\def\dododochemical#1[#2][#3]% % experiment + {\def\simpledododochemical% % experiment + {#1[#2][#3]}% % experiment + \def\complexdododochemical[##1]% % experiment + {\def\dowithchemical% % experiment + {\localthisischemical{#2}}% % experiment + #1[#3][##1]}% % experiment + \complexorsimple\dododochemical} % experiment + +\def\dodochemical[#1][#2]% + {\ignorespaces + \ifinchemical + \drawchemical[#1][#2]% + \ignorespaces + \else + \startchemical[\c!location=\v!intext]% + \drawchemical[#1][#2]% + \expandafter\stopchemical + \fi + \ignorespaces} + +\def\dochemical[#1]% + {\def\simpledochemical% + {\@@writechemicalstate{ppchtex}{[#1][]}% + \dodochemical[#1][]}% + % + \def\complexdochemical[##1]% + {\@@writechemicalstate{ppchtex}{[#1][##1]}% + \txtchemical=0% + \dodochemical[#1][##1]}% + % + \def\complexdochemical[##1]% % experiment + {\@@writechemicalstate{ppchtex}{[#1][##1]}% % experiment + \txtchemical=0% % experiment + \dododochemical\dodochemical[#1][##1]}% % experiment + % + \complexorsimple\dochemical} + +% \processlocalchemicals{#1} +% +% #1: commando's + +\def\dodoprocesschemical#1% + {\processchemical[#1????]} + +\def\processlocalchemicals#1% + {\processcommalist[#1]\dodoprocesschemical} + +% \drawchemical[#1][#2] +% +% #1: bindingen enz. +% #2: atomen enz. + +\def\localdodochemical[#1][#2]% + {\@@writechemicalstate{ppchtex}{[#1][#2]}% + %\bgroup % koppelen en afmetingen gaat fout, vandaar: + \advance\levchemical 1 + \letvalue{\??chemical\s!unknown\the\levchemical}\unknownchemical + \setevalue{\??chemical\c!text\the\levchemical}{\the\txtchemical}% + \txtchemical=0 + \dodochemical[#1][#2]% + % \@EA\txtchemical\@EA\csname\??chemical\c!text\the\levchemical\endcsname + \txtchemical\csname\??chemical\c!text\the\levchemical\endcsname + \@EA\let\@EA\unknownchemical\csname\??chemical\s!unknown\the\levchemical\endcsname + \advance\levchemical -1 + %\egroup + \ignorespaces} + +\def\drawchemical[#1][#2]% + {\ignorespaces + \def\dodochemical[##1][##2]% + {\drawchemical[##1][##2]% + \ignorespaces}% + \def\dochemical[##1]% + {\def\simpledochemical% + {\@@writechemicalstate{ppchtex}{[##1][#2]}% + \dodochemical[##1][#2]% + \ignorespaces}% + \def\complexdochemical[####1]% + {\dododochemical\localdodochemical[##1][####1,#2]}% + \complexorsimple\dochemical}% + \doif\@@chemicalstate\v!start + {\doifelse\chemicalname\s!unknown + {\getvalue{\s!executechemical\defaultchemical}[#2]} + {\getvalue{\s!executechemical\chemicalname}[#2]}% + \def\unknownchemical##1% + {\processunknownchemical[##1][#2]}% + \processcommalist[\@@chemicaloffset,#1]\dodoprocesschemical}% + \ignorespaces} + +\unexpanded\def\chemicaloxidation#1#2#3% + {\chemicaltop + {\ifnum#20=0 + 0% + \else + #1\expandafter\uppercase\expandafter{\romannumeral#2}% + \fi} + {#3}} + +\def\chemicaltfraction{\ifinchemical.60\else.8\fi} +\def\chemicalbfraction{\ifinchemical.45\else.6\fi} +\def\chemicallfraction{\ifinchemical.1\else.1\fi} +\def\chemicalrfraction{\ifinchemical.1\else.1\fi} + +\def\chemicaltighttext + {\def\chemicaltfraction{\ifinchemical.3\else.6\fi}% + \def\chemicalbfraction{\ifinchemical.2\else.4\fi}% + \def\chemicallfraction{\ifinchemical 0\else 0\fi}% + \def\chemicalrfraction{\ifinchemical 0\else 0\fi}} + +\def\dochemicaltop#1#2#3#4% + {\vbox + {\@@dochemicalcolor + \baselineskip=\chemicaltfraction\baselineskip \lineskip0pt + \halign + {#1###2\cr + $\@@dochemicalstyle{\scriptscriptstyle#3}$\cr + $\@@dochemicalstyle{\@@currentchemicalformat#4}$\cr}}} + +\def\dochemicalbottom#1#2#3#4% + {\vtop + {\@@dochemicalcolor + \baselineskip=\chemicalbfraction\baselineskip \lineskip0pt + \halign + {#1###2\cr + $\@@dochemicalstyle{\@@currentchemicalformat#4}$\cr + $\@@dochemicalstyle{\scriptscriptstyle#3}$\cr}}} + +\def\chemicalleft#1#2% + {\hbox + {\@@dochemicalcolor + $\@@dochemicalstyle{\scriptscriptstyle#1}$% + $\@@dochemicalstyle{\@@currentchemicalformat\hskip\chemicallfraction em#2}$}} + +\def\chemicalright#1#2% + {\hbox + {\@@dochemicalcolor + $\@@dochemicalstyle{\@@currentchemicalformat#2\hskip\chemicalrfraction em}$% + $\@@dochemicalstyle{\scriptscriptstyle#1}$}} + +\def\chemicalcentered#1% + {\setbox0=\hbox{$\@@dochemicalstyle{\scriptscriptstyle#1}$}% + \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}% + \dimen0=.5\ht2 + \advance\dimen0 by -.5\ht0 + \advance\dimen0 by \dp0 + \hbox{\@@dochemicalcolor\raise\dimen0\box0}} + +\def\chemicalleftcentered#1#2% + {\hbox + {\@@dochemicalcolor + \chemicalcentered{#1}% + $\@@dochemicalstyle{\@@currentchemicalformat\hskip\chemicallfraction em#2}$}} + +\def\chemicalrightcentered#1#2% + {\hbox + {\@@dochemicalcolor + $\@@dochemicalstyle{\@@currentchemicalformat#2\hskip\chemicalrfraction em}$% + \chemicalcentered{#1}}} + +\def\chemicaltop {\dochemicaltop \hss \hss } +\def\chemicallefttop {\dochemicaltop \relax \hss } +\def\chemicalrighttop {\dochemicaltop \hss \relax} +\def\chemicalbottom {\dochemicalbottom \hss \hss } +\def\chemicalleftbottom {\dochemicalbottom \relax \hss } +\def\chemicalrightbottom {\dochemicalbottom \hss \relax} + +\def\chemicaltopleft #1{\chemicalleft {\chemicallefttop {#1}{}}} +\def\chemicalbottomleft #1{\chemicalleft {\chemicalleftbottom{#1}{}}} +\def\chemicaltopright #1{\chemicalright{\chemicallefttop {#1}{}}} +\def\chemicalbottomright#1{\chemicalright{\chemicalleftbottom{#1}{}}} + +\def\chemicalsmashedleft#1% + {\hbox\bgroup + \@@dochemicalcolor + \setbox0=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}% + \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat#1}$}% + \wd2=\wd0 + \box2 + \egroup} + +\def\chemicalsmashedmiddle#1% + {\hbox\bgroup + \@@dochemicalcolor + \setbox0=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}% + \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat#1}$}% + \hbox{\hskip-.5\wd2\hskip.5\wd0\box2} + \egroup} + +\def\chemicalsmashedright#1% + {\hbox\bgroup + \@@dochemicalcolor + \setbox0=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}% + \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat#1}$}% + \hbox to \wd0{\hskip-\wd2\hskip\wd0\box2}% + \egroup} + +\def\+{\tabalign} % is \long in Plain + +\def\chemicalforever#1#2% + {\bgroup + \setbox0=\hbox + {\@@dochemicalcolor + $\@@dochemicalstyle{\scriptscriptstyle\hskip-.15em#2}$}% + \wd0=0pt + \big#1_{\hskip.1em\box0}% + \egroup} + +\def\disablechemicalspecials% + {\def\+##1{##1}\def\-##1{##1}% + \def\[{[}\def\]{]}% + \def\1{}\def\2{}\def\3{}\def\4{}\def\5{}\def\6{}\def\7{}% + \def\X{}% + \def\T{}\def\B{}\def\L{}\def\R{}\def\LC{}\def\RC{}% + \def\TL{}\def\BL{}\def\TR{}\def\BR{}% + \def\LT{}\def\LB{}\def\RT{}\def\RB{}% + \def\SL{}\def\SM{}\def\SR{}} + +\def\enablechemicalspecials% + {\def\+{\dodoublegroupempty\chemicaloxidation{+}}% {} needed! + \def\-{\dodoublegroupempty\chemicaloxidation{-}}% {} needed! + \def\[{\dodoublegroupempty\chemicalforever {[}}% {} needed! + \def\]{\dodoublegroupempty\chemicalforever {]}}% {} needed! + \def\1{\chemicaloxidation\relax1}% + \def\2{\chemicaloxidation\relax2}% + \def\3{\chemicaloxidation\relax3}% + \def\4{\chemicaloxidation\relax4}% + \def\5{\chemicaloxidation\relax5}% + \def\6{\chemicaloxidation\relax6}% + \def\7{\chemicaloxidation\relax7}% + \def\X{\chemicaltighttext}% + \def\T{\chemicaltop}% + \def\B{\chemicalbottom}% + \def\L{\chemicalleft}% + \def\LC{\chemicalleftcentered}% + \def\R{\chemicalright}% + \def\RC{\chemicalrightcentered}% + \def\TL{\chemicaltopleft}% + \def\BL{\chemicalbottomleft}% + \def\TR{\chemicaltopright}% + \def\BR{\chemicalbottomright}% + \def\LT{\chemicallefttop}% + \def\LB{\chemicalleftbottom}% + \def\RT{\chemicalrighttop}% + \def\RB{\chemicalrightbottom}% + \def\SL{\chemicalsmashedleft}% + \def\SM{\chemicalsmashedmiddle}% + \def\SR{\chemicalsmashedright}} + +% \reversechemical#1#2#3 +% +% #1: prefix +% #2: volgnummer enz +% #3: tegengestelde volgnummers + +\def\reversechemical#1#2#3% + {\def\doprocess[##1##2]% + {\doifchemicalnumber{##1}{#1#2}% + {\getfromcommalist[#3][##1]% + \let\reversechemicalaction=\commalistelement + \processchemical[#1\reversechemicalaction##2]}}% + \doprocess[#2]} + +% \processunknownchemical[#1????][#2] +% +% #1: bindingen enz. +% #2: atomen enz. + +\def\defaultchemical% + {SIX} + +\def\processunknownchemical[#1????][#2]% + {\processaction + [#1] + [ SAVE=>\executechemicalSAVE, + RESTORE=>\executechemicalRESTORE, + HIGH=>\sethighsubscripts, + LOW=>\setlowsubscripts, + \s!default=>, + \s!unknown=>\doifdefinedelse{\s!executechemical#1} + {\def\chemicalrotation{1}% + \def\chemicaloffset{0}% + \doifdefined{\s!executechemical#1} + {\getvalue{\s!executechemical#1}[#2]}% + \@@chemicalpostponed} + {\getpredefinedchemical{#1}}]} + +\newcount\chemicalstack % tzt \newwounter + +\setvalue{\s!chemical\c!x1}{0} +\setvalue{\s!chemical\c!y1}{0} + +\def\executechemicalSAVE + {%\writestatus{ppchtex}{saving \the\horchemical,\the\verchemical}% + \advance\chemicalstack by 1 + \letvalue {\s!chemical n\the\chemicalstack}=\chemicalname + %\letvalue {\s!chemical p\the\chemicalstack}=\@@chemicalpostponed + \setevalue{\s!chemical x\the\chemicalstack}{\the\horchemical}% + \setevalue{\s!chemical y\the\chemicalstack}{\the\verchemical}} + +\def\restorechemicalvalues#1% + {\let\oldprocesschemical=\processchemical + \doifdefined{\s!executechemical#1}{\getvalue{\s!executechemical#1}[]}% + \let\processchemical=\oldprocesschemical} + +\def\executechemicalRESTORE + {\ifnum\chemicalstack=0\relax + \horchemical=\getvalue{\s!chemical x1}\relax + \verchemical=\getvalue{\s!chemical y1}\relax + \else + \restorechemicalvalues{\getvalue{\s!chemical n\the\chemicalstack}}% + %\@EA\let\@EA\@@chemicalpostponed\@EA=\csname\s!chemical p\the\chemicalstack\endcsname + \let\@@chemicalpostponed=\relax + \horchemical=\getvalue{\s!chemical x\the\chemicalstack}\relax + \verchemical=\getvalue{\s!chemical y\the\chemicalstack}\relax + \advance\chemicalstack by -1 + \fi + \restorechemicalcoordinates} + +% De onderstaande macro's zijn verantwoordelijk voor het zetten +% van de + en pijlen. De +, en dus ook de pijlen, worden omhoog +% gehaald. Dit oogt m.i. fraaier. + +\def\chemicalinnerclip#1% + {{\setbox0=\hbox{#1}\ht0\ht\strutbox\dp0\dp\strutbox\box0}} + +\def\chemicalraise#1#2% + {\chemicalinnerclip + {\setbox0=\hbox{$#1+$}% + \raise\dp0\hbox{$#1#2$}}} + +\def\chemicalinnersign#1% todo: \@@chemicaltextcolor + {\chemicalraise{\@@localchemicalstyle}{#1}} + +\def\chemicaloutersign#1% + {\chemicalraise{}{\@@dochemicalcolor#1}} + +\def\chemicalsingleinnerarrow#1#2% + {\chemicalraise{\@@localchemicalstyle}{\longrightarrow}} + +\def\chemicaldoubleinnerarrow#1#2% todo: \@@chemicaltextcolor + {\chemicalinnerclip + {\lower.2ex\hbox + {\setbox0=\hbox{$\@@localchemicalstyle\longrightarrow$}% + \setbox2=\hbox{$\@@localchemicalstyle\longleftarrow$}% + \wd0=0pt\raise\ht0\box0\box2}}} + +\def\chemicaltwintipinnerarrow#1#2% todo: \@@chemicaltextcolor + {\chemicalinnerclip + {\setbox0=\hbox{\chemicalraise{\@@localchemicalstyle}{\longrightarrow}}% + \setbox2=\hbox{\chemicalraise{\@@localchemicalstyle}{\longleftarrow}}% + \wd0=0pt\box0\box2}} + +\def\dochemicalouterarrow#1#2#3% + {\bgroup + \setbox0=\hbox{$\longrightarrow$}% + \setbox2=\hbox{$\@@dochemicalstyle{\scriptstyle\quad#2\quad}$}% + \setbox4=\hbox{$\@@dochemicalstyle{\scriptstyle\quad#3\quad}$}% + \dimen2=\wd0 % \dimen0 is used elsewhere + \ifdim\wd2>\dimen2 \dimen0=\wd2 \fi + \ifdim\wd4>\dimen2 \dimen0=\wd4 \fi + \chemicaloutermolecule + {#1} + {\ifdim\ht2>\!!zeropoint\box2\fi} % expands to \empty in test + {\ifdim\ht4>\!!zeropoint\box4\fi}% % expands to \empty in test + \egroup} + +\def\chemicalsingleouterarrow + {\dochemicalouterarrow + {\hbox to \dimen2{\rightarrowfill}}} + +\def\chemicaldoubleouterarrow + {\dochemicalouterarrow + {\lower.5\ht0\vbox + {\offinterlineskip + \hbox to \dimen2{\rightarrowfill} + \hbox to \dimen2{\leftarrowfill}}}} + +\def\chemicaltwintipouterarrow + {\dochemicalouterarrow + {\hbox + {\hbox to \dimen2{\rightarrowfill}% + \hskip-\dimen2 + \hbox to \dimen2{\leftarrowfill}}}} + +\def\chemicalinnermolecule#1#2#3% no mathop here, can generate space + {\chemicalspace % todo: \@@chemicaltextcolor + \chemicalinnerclip + {\dosetsubscripts + $\@@dochemicalstyle{\@@localchemicalstyle\strut#1}$% + \doresetsubscripts}% + \chemicalspace} + +\def\chemicaloutermolecule#1#2#3% + {\chemicalspace + \bgroup + \@@dochemicalcolor + \setbox0=\hbox % else the font is reset + {\dosetsubscripts + \hbox{$\@@dochemicalstyle{\strut#1}$}% + \doresetsubscripts}% + \mathop{\box0}% + \ifthirdargument + \doifnot{#2}{} + {^{\@@dochemicalstyle{\strut#2}}}% + \doifnot{#3}{} + {_{\@@dochemicalstyle{\strut#3}}}% + \else + \doifnot{#2}{} + {_{\@@dochemicalstyle{\strut#2}}}% + \fi + \egroup + \chemicalspace} + +\def\chemicalsinglepicturearrow#1% + {\lower.5ex\hbox + {\@@dochemicalstyle + $\chemicalspace + \buildrel + \@@dochemicalstyle{\scriptstyle\quad#1\quad}% + \over{\overrightarrow + {\hphantom{\@chemicalstyle{\scriptstyle\quad#1\quad}}}}% + \chemicalspace$}} + +\def\chemicaldoublepicturearrow#1% + {\lower.5ex\hbox + {\@@dochemicalstyle + $\chemicalspace + \buildrel + \@@dochemicalstyle{\scriptstyle\quad#1\quad}% + \over{\overrightarrow{\overleftarrow + {\hphantom{\@@dochemicalstyle{\scriptstyle\quad#1\quad}}}}}% + \chemicalspace$}} + +% Bij de in-line bindingen wordt gebruik gemaakt van +% een \hrule. De maatvoering wordt bepaald door een +% kunstmatige em (\wd0). + +\def\somechemicalbond% + {\hrule width \wd0 height .4pt} + +\def\dochemicalbonds#1#2#3% todo: \@@chemicaltextstyle + {{\setbox0=\hbox + {${\@@localchemicalstyle M}$}% + \vbox to \ht0 + {\@@dochemicalcolor + \hsize\wd0 + \vskip.1\wd0#1\vfill#2\vfill#3\vskip.1\wd0}}} + +\def\singlechemicalbond% + {\dochemicalbonds{}{\somechemicalbond}{}} + +\def\doublechemicalbond% + {\dochemicalbonds{\somechemicalbond}{}{\somechemicalbond}} + +\def\triplechemicalbond% + {\dochemicalbonds{\somechemicalbond}{\somechemicalbond}{\somechemicalbond}} + +% In plaats van \def\naam{\chemie[...]...} kan beter gebruik +% worden gemaakt van het commando +% +% \definieerchemie[naam]{commando's} +% +% De naam krijgt, om problemen met bestaande macro's te +% voorkomen, een prefix. Bij het ophalen van een commando +% worden beide definities afgehandeld. + +\def\dodefinechemical[#1]#2% + {\doifdefined{\??chemical#1} + {\writestatus{ppchtex}{chemical definition #1 is redefined}}% + \setvalue{\??chemical#1}{#2}} + +\def\definechemical% + {\dosingleargument\dodefinechemical} + +\def\getpredefinedchemical#1% + {\doifdefinedelse{\??chemical#1} + {\getvalue{\??chemical#1}} + {\doifdefinedelse{#1} + {\getvalue{#1}} + {\writestatus{ppchtex}{unknown chemical definition #1}}}} + +% Hieronder zijn de definities van de structuren opgenomen. De +% naam van de structuur is als volgt opgebouwd: +% +% \executechemicalNUMBER[#1] +% +% waarbij [#1] betrekking heeft op de tekstelementen van \chemie, +% de [tweede lijst] dus. +% +% De aan \chemie[#1][#2] meegegeven lijst van segmenten wordt +% deels door de in \execute gedefinieerde macro's afgehandeld, +% deels door algemene macro's. Segmenten hebben de vorm: +% +% [+|-|]identifier[X|XYZ|X..Y] +% +% Voorbeelden van segmenten zijn: +% +% R1 +% R1..4 +% R135 +% -R1 +% +R35 + +\setchemicalmaximum 0 + +\def\processchemical[#1]% + {\unknownchemical{#1}} + +\def\setchemicalname#1 % + {\def\chemicalname{#1}} + +\let\chemicalname=\s!unknown + +% Vooruitlopend op een gedetailleerde documentatie, zijn hier +% vast enkele gebruikte afmetingen: +% +% lengte radikalen : 500 +% afstand radikalen : 100 +% afstand dubbele radikalen : 260 +% afstand substituenten : +125 + +\def\executechemicalONE[#1]% + {\setchemicalname ONE + % + \setchemicalmaximum 8 + \setchemicaldistance 0 + \setchemicalsubstitute 625 + \setchemicaldirection 303 + % + \setchemicalrotation 1 1 0 1 0 1 0 1 0 + \setchemicalrotation 2 0.707 -0.707 0.707 -0.707 0.707 -0.707 0.707 -0.707 + \setchemicalrotation 3 0 -1 0 -1 0 -1 0 -1 + \setchemicalrotation 4 -0.707 -0.707 -0.707 -0.707 -0.707 -0.707 -0.707 -0.707 + \setchemicalrotation 5 -1 0 -1 0 -1 0 -1 0 + \setchemicalrotation 6 -0.707 0.707 -0.707 0.707 -0.707 0.707 -0.707 0.707 + \setchemicalrotation 7 0 1 0 1 0 1 0 1 + \setchemicalrotation 8 0.707 0.707 0.707 0.707 0.707 0.707 0.707 0.707 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 45 135 225 315 + \setchemicalangle 3 90 180 270 0 + \setchemicalangle 4 135 225 315 45 + \setchemicalangle 5 180 270 0 90 + \setchemicalangle 6 225 315 45 135 + \setchemicalangle 7 270 0 90 180 + \setchemicalangle 8 315 45 135 225 + % + \setchemicaltranslate 1 -1000 0 + \setchemicaltranslate 2 -1000 1000 + \setchemicaltranslate 3 0 1000 + \setchemicaltranslate 4 1000 1000 + \setchemicaltranslate 5 1000 0 + \setchemicaltranslate 6 1000 -1000 + \setchemicaltranslate 7 0 -1000 + \setchemicaltranslate 8 -1000 -1000 + % + \setchemicallinesegment SB 300 0 700 0 + \setchemicallinesegment DB1 300 50 700 50 + \setchemicallinesegment DB2 300 -50 700 -50 + % + %setchemicallinesegment EP 200 125 200 -125 + \setchemicalfactorlinesegment EP 200 125 200 -125 + % + \setchemicaltextelement ES 200 0 + \setchemicaltextelement ED1 200 50 + \setchemicaltextelement ED2 200 -50 + \setchemicaltextelement ET1 200 75 + \setchemicaltextelement ET2 200 0 + \setchemicaltextelement ET3 200 -75 + \setchemicaltextelement HB1 300 0 + \setchemicaltextelement HB2 475 0 + \setchemicaltextelement HB3 650 0 + % + \setchemicaltextelement Z 800 0 + \setchemicaltextelement RZ 950 0 + \setchemicaltextelement ZN 500 0 + \setchemicaltextelement ZTN 500 150 + \setchemicaltextelement ZBN 500 -150 + % + \def\processchemical[##1##2##3##4##5]% + {\doprocesschemical[##1##2##3##4##5] + {\processaction + [##1##2##3##4##5] + [ PB:##4##5=>\beginchemicalpicture{##4##5}, + PE????=>\endchemicalpicture, + SUB##4##5=>\processchemicalsubstitute{##4##5}, + ADJ##4##5=>\processchemicaldistance{##4##5}, + MOV##4##5=>\processchemicaltranslate{##4##5}, + DIR##4##5=>\processchemicaldirection{##4##5}, + OFF##4##5=>\processchemicaloffset{##4##5}, + CCD##4##5=>\processchemicaldottsegment{CC}{##4##5}, + LDD##4##5=>\processchemicaldashedlinesegment{DB1}{##4##5}% + \processchemicallinesegment{DB2}{##4##5}, + RDD##4##5=>\processchemicallinesegment{DB1}{##4##5}% + \processchemicaldashedlinesegment{DB2}{##4##5}, + OF##3:##5=>\processchemicalphantom{##3}{##5}, + OE##3##4##5=>\processchemicalopenend{OE}{##3##4##5}, + EP##3##4##5=>\processchemicallinesegment{EP}{##3##4##5}, + ES##3##4##5=>\processchemicaltextconstant{ES}{##3##4##5}{\hbox{$\cdot$}}{0}, + ED##3##4##5=>\processchemicaltextconstant{ED}{##3##4##5}{\hbox{$\cdot$}}{0}, + ET##3##4##5=>\processchemicaltextconstant{ET}{##3##4##5}{\hbox{$\cdot$}}{0}, + HB##3##4##5=>\processchemicaltextconstant{HB}{##3##4##5}{\hbox{$\cdot$}}{0}, + SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, + DB##3##4##5=>\processchemicallinesegment{DB}{##3##4##5}, + SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, + BB##3##4##5=>\processchemicaldeltalinesegment{SB}{##3##4##5}, + BD##3##4##5=>\processchemicaldasheddeltalinesegment{SB}{##3##4##5}, + BW##3##4##5=>\processchemicalwavylinesegment{SB}{##3##4##5}, + SD##3##4##5=>\processchemicaldashedlinesegment{SB}{##3##4##5}, + TB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}% + \processchemicallinesegment{DB}{##3##4##5}, + CZ##3##4##5=>\processchemicaltextelement{RZ}{##3##4##5}{#1}{0}{}, + ZTN##4##5=>\processchemicalsmalltextconstant{ZTN}{##4##5}{\chemicaltextelementnumber}{0}, + ZTT##4##5=>\processchemicalsmalltextelement{ZTN}{##4##5}{#1}{0}{}, + ZBN##4##5=>\processchemicalsmalltextconstant{ZBN}{##4##5}{\chemicaltextelementnumber}{0}, + ZBT##4##5=>\processchemicalsmalltextelement{ZBN}{##4##5}{#1}{0}{}, + ZN##3##4##5=>\processchemicaltextconstant{ZN}{##3##4##5}{\chemicaltextelementnumber}{0}, + ZT##3##4##5=>\processchemicaltextelement{ZN}{##3##4##5}{#1}{0}{}, + Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0} + {l,l,t,r,r,r,b,l}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}}} + +\def\executechemicalTHREE[#1]% + {\setchemicalname THREE + % + \setchemicalmaximum 3 + \setchemicaldistance 289 + \setchemicalsubstitute 952 + % + \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 + \setchemicalrotation 2 -0.5 -0.866 -0.866 0.5 0.5 0.866 0.866 -0.5 + \setchemicalrotation 3 -0.5 0.866 0.866 0.5 0.5 -0.866 -0.866 -0.5 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 120 210 300 30 + \setchemicalangle 3 240 330 60 150 + % + \setchemicaltranslate 1 -1000 0 + \setchemicaltranslate 2 0 1000 + \setchemicaltranslate 3 1000 0 + \setchemicaltranslate 4 0 -1000 + % + \setchemicallinesegment B 577 0 -289 -500 + \setchemicallinesegment SB 352 -130 -64 -370 + \setchemicallinesegment -SB 352 -130 -289 -500 + \setchemicallinesegment +SB 577 0 -64 -370 + \setchemicallinesegment DB1 327 -87 -89 -327 + \setchemicallinesegment DB2 377 -172 -39 -413 + \setchemicallinesegment R 577 0 1077 0 + \setchemicallinesegment -R 577 0 1010 250 + \setchemicallinesegment +R 577 0 1010 -250 + \setchemicallinesegment ER1 577 50 1077 50 + \setchemicallinesegment ER2 577 -50 1077 -50 + \setchemicallinesegment SR 837 0 1077 0 + \setchemicallinesegment -SR 802 130 1010 250 + \setchemicallinesegment +SR 802 -130 1010 -250 + \setchemicallinesegment DR1 837 50 1077 50 + \setchemicallinesegment DR2 837 -50 1077 -50 + % + \setchemicaltextelement Z 577 0 + \setchemicaltextelement RZ 1177 0 + \setchemicaltextelement -RZ 1097 300 + \setchemicaltextelement +RZ 1097 -300 + \setchemicaltextelement CRZ 1077 0 + % + \def\processchemical[##1##2##3##4]% + {\processaction + [##1##2##3##4] + [ ROT##4=>\processchemicalrotation{##4}, + MOV##4=>\processchemicaltranslate{##4}, + SUB##4=>\processchemicalsubstitute{##4}, + ADJ##4=>\processchemicaldistance{##4}, + -RZ##4=>\processchemicaltextelement{-RZ}{##4}{#1}{3} + {l,t,r, l,r,l, r,b,l, r,l,r}, + +RZ##4=>\processchemicaltextelement{+RZ}{##4}{#1}{3} + {l,r,b, r,r,l, r,l,t, l,l,r}, + -SB##4=>\processchemicallinesegment{-SB}{##4}, + +SB##4=>\processchemicallinesegment{+SB}{##4}, + -SR##4=>\processchemicallinesegment{-SR}{##4}, + +SR##4=>\processchemicallinesegment{+SR}{##4}, + CRZ##4=>\processchemicaltextelement{CRZ}{##4}{#1}{0} + {}, + DB##3##4=>\processchemicallinesegment{DB}{##3##4}, + DR##3##4=>\processchemicallinesegment{DR}{##3##4}, + RZ##3##4=>\processchemicaltextelement{RZ}{##3##4}{#1}{3} + {l,r,r, t,r,l, r,l,l, b,l,r}, + ER##3##4=>\processchemicallinesegment{ER}{##3##4}, + SB##3##4=>\processchemicallinesegment{SB}{##3##4}, + SR##3##4=>\processchemicallinesegment{SR}{##3##4}, + -R##3##4=>\processchemicallinesegment{-R}{##3##4}, + +R##3##4=>\processchemicallinesegment{+R}{##3##4}, + B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, + R##2##3##4=>\processchemicallinesegment{R}{##2##3##4}, + Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +\def\executechemicalFOUR[#1]% + {\setchemicalname FOUR + % + \setchemicalmaximum 4 + \setchemicaldistance 500 + \setchemicalsubstitute 0 + % + \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 + \setchemicalrotation 2 0 -1 -1 0 0 1 1 0 + \setchemicalrotation 3 -1 0 0 1 1 0 0 -1 + \setchemicalrotation 4 0 1 1 0 0 -1 -1 0 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 90 180 270 0 + \setchemicalangle 3 180 270 0 90 + \setchemicalangle 4 270 0 90 180 + % + \setchemicaltranslate 1 -1000 0 + \setchemicaltranslate 2 0 1000 + \setchemicaltranslate 3 1000 0 + \setchemicaltranslate 4 0 -1000 + % + \setchemicallinesegment B 500 500 500 -500 + \setchemicallinesegment SB 500 240 500 -240 + \setchemicallinesegment -SB 500 240 500 -500 + \setchemicallinesegment +SB 500 500 500 -240 + \setchemicallinesegment DB1 450 240 450 -240 + \setchemicallinesegment DB2 550 240 550 -240 + \setchemicallinesegment EB 360 300 360 -300 + \setchemicallinesegment R 500 500 854 854 + \setchemicallinesegment -R 500 500 500 1000 + \setchemicallinesegment +R 500 500 1000 500 + \setchemicallinesegment ER1 465 535 819 889 + \setchemicallinesegment ER2 535 465 889 819 + \setchemicallinesegment SR 684 684 854 854 + \setchemicallinesegment -SR 500 760 500 1000 + \setchemicallinesegment +SR 760 500 1000 500 + \setchemicallinesegment DR1 649 719 819 889 + \setchemicallinesegment DR2 719 649 889 819 + % + \setchemicaltextelement Z 500 500 + \setchemicaltextelement RZ 925 925 + \setchemicaltextelement -RZ 500 1100 + \setchemicaltextelement +RZ 1100 500 + \setchemicaltextelement CRZ 1038 1038 + % + \setchemicaltextelement ZN 350 350 + % + \def\processchemical[##1##2##3##4]% + {\processaction + [##1##2##3##4] + [ PB:##4=>\beginchemicalpicture{##4}, + PE????=>\endchemicalpicture, + ROT##4=>\processchemicalrotation{##4}, + SUB##4=>\processchemicalsubstitute{##4}, + ADJ##4=>\processchemicaldistance{##4}, + MOV##4=>\processchemicaltranslate{##4}, + -RZ##4=>\processchemicaltextelement{-RZ}{##4}{#1}{4} + {b,l,t,r, l,t,r,b, t,r,b,l, r,b,l,t}, + +RZ##4=>\processchemicaltextelement{+RZ}{##4}{#1}{4} + {l,t,r,b, t,r,b,l, r,b,l,t, b,l,t,r}, + -SB##4=>\processchemicallinesegment{-SB}{##4}, + +SB##4=>\processchemicallinesegment{+SB}{##4}, + -SR##4=>\processchemicallinesegment{-SR}{##4}, + +SR##4=>\processchemicallinesegment{+SR}{##4}, + CRZ##4=>\processchemicaltextelement{CRZ}{##4}{#1}{0}{}, + ZN##3##4=>\processchemicaltextconstant{ZN}{##3##4}{\chemicaltextelementnumber}{0}, + ZT##3##4=>\processchemicaltextelement{ZN}{##3##4}{#1}{0}{}, + DB##3##4=>\processchemicallinesegment{DB}{##3##4}, + DR##3##4=>\processchemicallinesegment{DR}{##3##4}, + EB##3##4=>\processchemicallinesegment{EB}{##3##4}, + ER##3##4=>\processchemicallinesegment{ER}{##3##4}, + RZ##3##4=>\processchemicaltextelement{RZ}{##3##4}{#1}{4} + {lb,lt,rt,rb, lt,rt,rb,lb, rt,rb,lb,lt, rb,lb,lt,rt}, + SB##3##4=>\processchemicallinesegment{SB}{##3##4}, + SR##3##4=>\processchemicallinesegment{SR}{##3##4}, + -R##3##4=>\processchemicallinesegment{-R}{##3##4}, + +R##3##4=>\processchemicallinesegment{+R}{##3##4}, + B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, + R##2##3##4=>\processchemicallinesegment{R}{##2##3##4}, + Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +\def\executechemicalFIVE[#1]% + {\setchemicalname FIVE + % + \setchemicalmaximum 5 + \setchemicaldistance 688 + \setchemicalsubstitute 1226 + % + \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 + \setchemicalrotation 2 0.309 -0.951 -0.951 -0.309 -0.309 0.940 0.951 0.309 + \setchemicalrotation 3 -0.809 -0.588 -0.588 0.809 0.809 0.588 0.588 -0.809 + \setchemicalrotation 4 -0.809 0.588 0.588 0.809 0.809 -0.588 -0.588 -0.809 + \setchemicalrotation 5 0.309 0.951 0.951 -0.309 -0.309 -0.951 -0.951 0.309 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 72 162 252 342 + \setchemicalangle 3 144 234 324 54 + \setchemicalangle 4 216 306 36 126 + \setchemicalangle 5 288 18 108 198 + % + \setchemicaltranslate 1 -1376 0 + \setchemicaltranslate 2 -425 1304 + \setchemicaltranslate 3 1113 809 + \setchemicaltranslate 4 1113 -809 + \setchemicaltranslate 5 -425 -1304 + % + \setchemicallinesegment A 1188 500 1188 -500 + \setchemicallinesegment B 688 500 688 -500 + \setchemicallinesegment S -263 808 688 -500 + \setchemicallinesegment SS -116 606 541 -298 + \setchemicallinesegment -SS -263 808 541 -298 + \setchemicallinesegment +SS -116 606 688 -500 + \setchemicallinesegment SB 688 240 688 -240 + \setchemicallinesegment -SB 688 240 688 -500 + \setchemicallinesegment +SB 688 500 688 -240 + \setchemicallinesegment DB1 638 240 638 -240 + \setchemicallinesegment DB2 738 240 738 -240 + \setchemicallinesegment EB 548 340 548 -340 + \setchemicallinesegment R 688 500 1093 794 + \setchemicallinesegment -R 688 500 688 1000 + \setchemicallinesegment +R 688 500 1163 345 + \setchemicallinesegment ER1 659 540 1064 834 + \setchemicallinesegment ER2 727 460 1122 754 + \setchemicallinesegment SR 898 653 1093 794 + \setchemicallinesegment -SR 688 760 688 1000 + \setchemicallinesegment +SR 935 420 1163 345 + \setchemicallinesegment DR1 869 693 1064 834 + \setchemicallinesegment DR2 927 613 1122 754 + % + \setchemicaltextelement Z 688 500 + \setchemicaltextelement RZ 1188 863 + \setchemicaltextelement -RZ 688 1100 + \setchemicaltextelement +RZ 1258 315 + \setchemicaltextelement CRZ 1323 947 + % + \setchemicalcircsegment C -36 36 590 72 475 -345 + \setchemicalcircsegment CC -72 0 590 72 182 -561 + % + \setchemicaltextelement ZN 468 350 + \setchemicaltextelement RN 860 625 % 1.25 Z + \setchemicaltextelement RTN 785 728 % .12 / 103 75 + \setchemicaltextelement RBN 935 522 + % + \def\processchemical[##1##2##3##4]% + {\processaction + [##1##2##3##4] + [ FRONT????=>{\executechemicalFIVEFRONT[#1]}, + PB:##4=>\beginchemicalpicture{##4}, + PE????=>\endchemicalpicture, + ROT##4=>\processchemicalrotation{##4}, + SUB##4=>\processchemicalsubstitute{##4}, + ADJ##4=>\processchemicaldistance{##4}, + MOV##4=>\processchemicaltranslate{##4}, + -RZ##4=>\processchemicaltextelement{-RZ}{##4}{#1}{5} + {b,l,t,r,r, l,t,r,r,l, t,r,r,l,l, r,b,l,t,r}, + +RZ##4=>\processchemicaltextelement{+RZ}{##4}{#1}{5} + {l,t,r,r,b, t,r,r,l,l, r,r,l,l,r, b,l,l,r,r}, + -SB##4=>\processchemicallinesegment{-SB}{##4}, + +SB##4=>\processchemicallinesegment{+SB}{##4}, + -SR##4=>\processchemicallinesegment{-SR}{##4}, + +SR##4=>\processchemicallinesegment{+SR}{##4}, + -RD##4=>\processchemicaldashedlinesegment{-R}{##4}, + +RD##4=>\processchemicaldashedlinesegment{+R}{##4}, + -RB##4=>\processchemicaldeltalinesegment{-R}{##4}, + +RB##4=>\processchemicaldeltalinesegment{+R}{##4}, + CRZ##4=>\processchemicaltextelement{CRZ}{##4}{#1}{0}{}, + RTN##4=>\processchemicaltextconstant{RTN}{##4}{\chemicaltextelementnumber}{0}, + RTT##4=>\processchemicaltextelement{RTN}{##4}{#1}{0}{}, + RBN##4=>\processchemicaltextconstant{RBN}{##4}{\chemicaltextelementnumber}{0}, + RBT##4=>\processchemicaltextelement{RBN}{##4}{#1}{0}{}, + -SS##4=>\processchemicallinesegment{-SS}{##4}, + +SS##4=>\processchemicallinesegment{+SS}{##4}, + CCD##4=>\processchemicaldottsegment{CC}{##4}, + SS##3##4=>\processchemicallinesegment{SS}{##3##4}, + RD##3##4=>\processchemicaldashedlinesegment{R}{##3##4}, + RB##3##4=>\processchemicaldeltalinesegment{R}{##3##4}, + ZN##3##4=>\processchemicaltextconstant{ZN}{##3##4}{\chemicaltextelementnumber}{0}, + ZT##3##4=>\processchemicaltextelement{ZN}{##3##4}{#1}{0}{}, + RN##3##4=>\processchemicaltextconstant{RN}{##3##4}{\chemicaltextelementnumber}{0}, + RT##3##4=>\processchemicaltextelement{RN}{##3##4}{#1}{0}{}, + AU##3##4=>\processchemicaluparrowsegment{A}{##3##4}, + AD##3##4=>\processchemicaldownarrowsegment{A}{##3##4}, + CC##3##4=>\processchemicalcircsegment{CC}{##3##4}, + CD##3##4=>\processchemicaldottsegment{C}{##3##4}, + DB##3##4=>\processchemicallinesegment{DB}{##3##4}, + DR##3##4=>\processchemicallinesegment{DR}{##3##4}, + EB##3##4=>\processchemicallinesegment{EB}{##3##4}, + ER##3##4=>\processchemicallinesegment{ER}{##3##4}, + RZ##3##4=>\processchemicaltextelement{RZ}{##3##4}{#1}{5} + {l,l,r,r,r, l,r,r,b,l, r,r,b,l,t, r,l,l,t,r}, + SB##3##4=>\processchemicallinesegment{SB}{##3##4}, + SR##3##4=>\processchemicallinesegment{SR}{##3##4}, + -R##3##4=>\processchemicallinesegment{-R}{##3##4}, + +R##3##4=>\processchemicallinesegment{+R}{##3##4}, + B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, + C##2##3##4=>\processchemicalcircsegment{C}{##2##3##4}, + R##2##3##4=>\processchemicallinesegment{R}{##2##3##4}, + S##2##3##4=>\processchemicallinesegment{S}{##2##3##4}, + Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +\def\executechemicalSIX[#1]% + {\setchemicalname SIX + % + \setchemicalmaximum 6 + \setchemicalsubstitute 1375 + \setchemicaldistance 866 + % + \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 + \setchemicalrotation 2 0.5 -0.866 -0.866 -0.5 -0.5 0.866 0.866 0.5 + \setchemicalrotation 3 -0.5 -0.866 -0.866 0.5 0.5 0.866 0.866 -0.5 + \setchemicalrotation 4 -1 0 0 1 1 0 0 -1 + \setchemicalrotation 5 -0.5 0.866 0.866 0.5 0.5 -0.866 -0.866 -0.5 + \setchemicalrotation 6 0.5 0.866 0.866 -0.5 -0.5 -0.866 -0.866 0.5 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 60 150 240 330 + \setchemicalangle 3 120 210 300 30 + \setchemicalangle 4 180 270 0 90 + \setchemicalangle 5 240 330 60 150 + \setchemicalangle 6 300 30 120 210 + % + \setchemicaltranslate 1 -1732 0 + \setchemicaltranslate 2 -866 1500 + \setchemicaltranslate 3 866 1500 + \setchemicaltranslate 4 1732 0 + \setchemicaltranslate 5 866 -1500 + \setchemicaltranslate 6 -866 -1500 + % + \setchemicallinesegment A 1386 500 1386 -500 + \setchemicallinesegment S 0 1000 866 -500 + \setchemicallinesegment SS 125 783 741 -283 + \setchemicallinesegment -SS 0 1000 741 -283 + \setchemicallinesegment +SS 125 783 866 -500 + \setchemicallinesegment B 866 500 866 -500 + \setchemicallinesegment SB 866 240 866 -240 + \setchemicallinesegment -SB 866 240 866 -500 + \setchemicallinesegment +SB 866 500 866 -240 + \setchemicallinesegment DB1 816 240 816 -240 + \setchemicallinesegment DB2 916 240 916 -240 + \setchemicallinesegment EB 726 340 726 -340 + \setchemicallinesegment R 866 500 1299 750 + \setchemicallinesegment -R 866 500 866 1000 + \setchemicallinesegment +R 866 500 1299 250 + \setchemicallinesegment ER1 841 543 1274 793 + \setchemicallinesegment ER2 891 457 1324 707 + \setchemicallinesegment SR 1091 630 1299 750 + \setchemicallinesegment -SR 866 740 866 1000 + \setchemicallinesegment +SR 1091 370 1299 250 + \setchemicallinesegment DR1 1066 673 1274 793 + \setchemicallinesegment DR2 1116 588 1324 707 + \setchemicallinesegment MID1 0 1000 -150 200 + \setchemicallinesegment MID2 0 -1000 -150 -200 + \setchemicallinesegment MIDS1 0 1000 -180 0 + \setchemicallinesegment MIDS2 0 -1000 -180 0 + % + \setchemicalcircsegment C -30 30 700 60 600 -346 + \setchemicalcircsegment CC -60 0 700 60 350 -606 + % + \setchemicaltextelement Z 866 500 + \setchemicaltextelement RZ 1386 800 + \setchemicaltextelement -RZ 866 1100 + \setchemicaltextelement +RZ 1386 200 + \setchemicaltextelement CRZ 1524 880 + \setchemicaltextelement MIDZ -150 0 + % + \setchemicaltextelement ZN 589 350 + \setchemicaltextelement RN 1083 625 % 1.25 Z + \setchemicaltextelement RTN 1008 755 % .12 / 130 75 + \setchemicaltextelement RBN 1158 495 + % + \def\processchemical[##1##2##3##4##5]% + {\processaction + [##1##2##3##4##5] + [ FRONT????=>{\executechemicalSIXFRONT[#1]}, + MID????=>\processchemicallinesegment{MID}{1????}, + MIDS????=>\processchemicallinesegment{MIDS}{1????}, + MIDZ????=>\processchemicaltextelement{MIDZ}{1????}{#1}{0}{}, + PB:##4##5=>\beginchemicalpicture{##4##5}, + PE????=>\endchemicalpicture, + ROT##4##5=>\processchemicalrotation{##4##5}, + SUB##4##5=>\processchemicalsubstitute{##4##5}, + ADJ##4##5=>\processchemicaldistance{##4##5}, + MOV##4##5=>\processchemicaltranslate{##4##5}, + -RZ##4##5=>\processchemicaltextelement{-RZ}{##4##5}{#1}{6} + {b,l,l,t,r,r, l,l,r,r,r,l, t,r,r,b,l,l, r,r,l,l,l,r}, + +RZ##4##5=>\processchemicaltextelement{+RZ}{##4##5}{#1}{6} + {l,t,r,r,b,l, r,r,r,l,l,l, r,b,l,l,t,r, l,l,l,r,r,r}, + -SB##4##5=>\processchemicallinesegment{-SB}{##4##5}, + +SB##4##5=>\processchemicallinesegment{+SB}{##4##5}, + -SR##4##5=>\processchemicallinesegment{-SR}{##4##5}, + +SR##4##5=>\processchemicallinesegment{+SR}{##4##5}, + -RD##4##5=>\processchemicaldashedlinesegment{-R}{##4##5}, + +RD##4##5=>\processchemicaldashedlinesegment{+R}{##4##5}, + -RB##4##5=>\processchemicaldeltalinesegment{-R}{##4##5}, + +RB##4##5=>\processchemicaldeltalinesegment{+R}{##4##5}, + CRZ##4##5=>\processchemicaltextelement{CRZ}{##4##5}{#1}{0}{}, + -SS##4##5=>\processchemicallinesegment{-SS}{##4##5}, + +SS##4##5=>\processchemicallinesegment{+SS}{##4##5}, + CCD##4##5=>\processchemicaldottsegment{CC}{##4##5}, +RTN##4##5=>\processchemicaltextconstant{RTN}{##4##5}{\chemicaltextelementnumber}{0}, +RTT##4##5=>\processchemicaltextelement{RTN}{##4##5}{#1}{0}{}, +RBN##4##5=>\processchemicaltextconstant{RBN}{##4##5}{\chemicaltextelementnumber}{0}, +RBT##4##5=>\processchemicaltextelement{RBN}{##4##5}{#1}{0}{}, + SS##3##4##5=>\processchemicallinesegment{SS}{##3##4##5}, + RD##3##4##5=>\processchemicaldashedlinesegment{R}{##3##4##5}, + RB##3##4##5=>\processchemicaldeltalinesegment{R}{##3##4##5}, + ZN##3##4##5=>\processchemicaltextconstant{ZN}{##3##4##5}{\chemicaltextelementnumber}{0}, + ZT##3##4##5=>\processchemicaltextelement{ZN}{##3##4##5}{#1}{0}{}, +RN##3##4##5=>\processchemicaltextconstant{RN}{##3##4##5}{\chemicaltextelementnumber}{0}, +RT##3##4##5=>\processchemicaltextelement{RN}{##3##4##5}{#1}{0}{}, + AU##3##4##5=>\processchemicaluparrowsegment{A}{##3##4##5}, + AD##3##4##5=>\processchemicaldownarrowsegment{A}{##3##4##5}, + CD##3##4##5=>\processchemicaldottsegment{C}{##3##4##5}, + CC##3##4##5=>\processchemicalcircsegment{CC}{##3##4##5}, + DB##3##4##5=>\processchemicallinesegment{DB}{##3##4##5}, + EB##3##4##5=>\processchemicallinesegment{EB}{##3##4##5}, + ER##3##4##5=>\processchemicallinesegment{ER}{##3##4##5}, + RZ##3##4##5=>\processchemicaltextelement{RZ}{##3##4##5}{#1}{6} + {l,l,t,r,r,b, l,r,r,r,l,l, r,r,b,l,l,t, r,l,l,l,r,r}, + SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, + SR##3##4##5=>\processchemicallinesegment{SR}{##3##4##5}, + DR##3##4##5=>\processchemicallinesegment{DR}{##3##4##5}, + -R##3##4##5=>\processchemicallinesegment{-R}{##3##4##5}, + +R##3##4##5=>\processchemicallinesegment{+R}{##3##4##5}, + B##2##3##4##5=>\processchemicallinesegment{B}{##2##3##4##5}, + C##2##3##4##5=>\processchemicalcircsegment{C}{##2##3##4##5}, + R##2##3##4##5=>\processchemicallinesegment{R}{##2##3##4##5}, + S##2##3##4##5=>\processchemicallinesegment{S}{##2##3##4##5}, + Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} + +\def\executechemicalSEVEN[#1]% incomplete ! + {\setchemicalname SEVEN + % + \setchemicalmaximum 7 + \setchemicalsubstitute - + \setchemicaldistance 1038 + % + \setchemicalrotation 1 .623 .782 - - - - - - + \setchemicalrotation 2 -.223 .975 - - - - - - + \setchemicalrotation 3 -.901 .434 - - - - - - + \setchemicalrotation 4 -.901 -.434 - - - - - - + \setchemicalrotation 5 -.223 -.975 - - - - - - + \setchemicalrotation 6 .623 -.782 - - - - - - + \setchemicalrotation 7 1 0 - - - - - - + % + \setchemicalangle 1 0 - - - + \setchemicalangle 2 51.429 - - - + \setchemicalangle 3 102.857 - - - + \setchemicalangle 4 154.286 - - - + \setchemicalangle 5 205.714 - - - + \setchemicalangle 6 257.143 - - - + \setchemicalangle 7 308.571 - - - + % + \setchemicaltranslate 1 - - + \setchemicaltranslate 2 - - + \setchemicaltranslate 3 - - + \setchemicaltranslate 4 - - + \setchemicaltranslate 5 - - + \setchemicaltranslate 6 - - + \setchemicaltranslate 7 - - + % + \setchemicallinesegment B 1038 500 1038 -500 + \setchemicallinesegment SB 1038 240 1038 -240 + \setchemicallinesegment -SB 1038 240 1038 -500 + \setchemicallinesegment +SB 1038 500 1038 -240 + % + \setchemicaltextelement Z 1038 500 + % + \def\processchemical[##1##2##3##4##5]% + {\processaction + [##1##2##3##4##5] + [ PB:##4##5=>\beginchemicalpicture{##4##5}, + PE????=>\endchemicalpicture, + %ROT##4##5=>\processchemicalrotation{##4}, + %SUB##4##5=>\processchemicalsubstitute{##4##5}, + %ADJ##4##5=>\processchemicaldistance{##4##5}, + %MOV##4##5=>\processchemicaltranslate{##4##5}, + -SB##4##5=>\processchemicallinesegment{-SB}{##4##5}, + +SB##4##5=>\processchemicallinesegment{+SB}{##4##5}, + SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, + B##2##3##4##5=>\processchemicallinesegment{B}{##2##3##4##5}, + Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} + +\def\executechemicalEIGHT[#1]% incomplete ! + {\setchemicalname EIGHT + % + \setchemicalmaximum 8 + %\setchemicalsubstitute 1307 + \setchemicaldistance 1207 + % + \setchemicalrotation 1 .707 .707 - - - - - - + \setchemicalrotation 2 0 1 - - - - - - + \setchemicalrotation 3 -.707 .707 - - - - - - + \setchemicalrotation 4 -1 0 - - - - - - + \setchemicalrotation 5 -.707 -.707 - - - - - - + \setchemicalrotation 6 0 -1 - - - - - - + \setchemicalrotation 7 .707 -.707 - - - - - - + \setchemicalrotation 8 1 0 - - - - - - + % + \setchemicalangle 1 45 - - - + \setchemicalangle 2 90 - - - + \setchemicalangle 3 135 - - - + \setchemicalangle 4 180 - - - + \setchemicalangle 5 225 - - - + \setchemicalangle 6 270 - - - + \setchemicalangle 7 315 - - - + \setchemicalangle 8 0 - - - + % + \setchemicaltranslate 1 -2414 0 + \setchemicaltranslate 2 -1706 1706 + \setchemicaltranslate 3 0 2414 + \setchemicaltranslate 4 1706 1706 + \setchemicaltranslate 5 2414 0 + \setchemicaltranslate 6 1706 -1706 + \setchemicaltranslate 7 0 -2414 + \setchemicaltranslate 8 -1706 -1706 + % + \setchemicallinesegment B 1207 500 1207 -500 + \setchemicallinesegment SB 1207 240 1207 -240 + \setchemicallinesegment -SB 1207 240 1207 -500 + \setchemicallinesegment +SB 1207 500 1207 -240 + % + \setchemicaltextelement Z 1207 500 + % + \def\processchemical[##1##2##3##4##5]% + {\processaction + [##1##2##3##4##5] + [ PB:##4##5=>\beginchemicalpicture{##4##5}, + PE????=>\endchemicalpicture, + %SUB##4##5=>\processchemicalsubstitute{##4##5}, + ADJ##4##5=>\processchemicaldistance{##4##5}, + MOV##4##5=>\processchemicaltranslate{##4##5}, + -SB##4##5=>\processchemicallinesegment{-SB}{##4##5}, + +SB##4##5=>\processchemicallinesegment{+SB}{##4##5}, + SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, + B##2##3##4##5=>\processchemicallinesegment{B}{##2##3##4##5}, + Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} + +\def\executechemicalFIVEFRONT[#1]% + {\executechemicalFIVE[]% + % + \setchemicalname FIVEFRONT + % + \setchemicallinesegment -R 688 500 688 100 + \setchemicallinesegment +R 688 500 688 900 + % + \setchemicaltextelement -RZ 0 -1300 + \setchemicaltextelement +RZ 0 1300 + % + \def\processchemical[##1##2##3##4]% + {\def\chemicalrotation{2}% + \processaction + [##1##2##3##4] + [ -RZ##4=>\processchemicalunrotatedtextelement{Z}{-RZ}{##4}{#1}{5} + {,,,,, t,t,t,t,t}, + +RZ##4=>\processchemicalunrotatedtextelement{Z}{+RZ}{##4}{#1}{5} + {,,,,, b,b,b,b,b}, + -SB##4=>\processchemicallinesegment{-SB}{##4}, + +SB##4=>\processchemicallinesegment{+SB}{##4}, + SB##3##4=>\processchemicallinesegment{SB}{##3##4}, + -R##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##3##4}, + +R##3##4=>\processchemicalunrotatedlinesegment{b}{+R}{##3##4}, + BB##3##4=>\processchemicalzlinesegment{B}{##3##4}, + R##2##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##2##3##4}% + \processchemicalunrotatedlinesegment{b}{+R}{##2##3##4}, + B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, + Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +\def\executechemicalSIXFRONT[#1]% + {\executechemicalSIX[]% + % + \setchemicalname SIXFRONT + % + \setchemicallinesegment -R 866 500 866 100 + \setchemicallinesegment +R 866 500 866 900 + % + \setchemicaltextelement -RZ 0 -1300 + \setchemicaltextelement +RZ 0 1300 + % + \def\processchemical[##1##2##3##4]% + {\def\chemicalrotation{2}% + \processaction + [##1##2##3##4] + [ -RZ##4=>\processchemicalunrotatedtextelement{Z}{-RZ}{##4}{#1}{6} + {,,,,,, t,t,t,t,t,t}, + +RZ##4=>\processchemicalunrotatedtextelement{Z}{+RZ}{##4}{#1}{6} + {,,,,,, b,b,b,b,b,b}, + -SB##4=>\processchemicallinesegment{-SB}{##4}, + +SB##4=>\processchemicallinesegment{+SB}{##4}, + SB##3##4=>\processchemicallinesegment{SB}{##3##4}, + -R##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##3##4}, + +R##3##4=>\processchemicalunrotatedlinesegment{b}{+R}{##3##4}, + BB##3##4=>\processchemicalzlinesegment{B}{##3##4}, + R##2##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##2##3##4}% + \processchemicalunrotatedlinesegment{b}{+R}{##2##3##4}, + B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, + Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +% 1 : 0 +% 2 : -115 +% 3* : -195 +% 3 : -165 +% 4 : -245 + +\def\executechemicalCARBON[#1]% + {\setchemicalname CARBON + % + \setchemicalmaximum 4 + \setchemicaldistance 0 + \setchemicalsubstitute 0 + % + \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 + \setchemicalrotation 2 -0.423 -0.906 -0.906 0.423 0.423 0.906 0.906 -0.423 + \setchemicalrotation 3 -0.966 -0.259 -0.259 0.966 0.966 0.259 0.259 -0.966 + \setchemicalrotation 3* -0.966 0.259 0.259 0.966 0.966 -0.259 -0.259 -0.966 + \setchemicalrotation 4 -0.423 0.906 0.906 0.423 0.423 -0.906 -0.906 -0.423 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 115 205 295 25 + \setchemicalangle 3 165 255 345 75 + \setchemicalangle 3* 195 285 15 105 + \setchemicalangle 4 245 335 65 155 + % + \setchemicaltranslate 1 -1500 0 + \setchemicaltranslate 2 0 1500 + \setchemicaltranslate 3 1500 0 + \setchemicaltranslate 4 0 -1500 + % + \setchemicallinesegment B1 500 0 1000 0 + \setchemicallinesegment B2 300 0 1000 0 + \setchemicallinesegment B3 500 0 1000 0 + \setchemicallinesegment B4 300 0 1000 0 + % + \setchemicaltextelement Z 1100 0 + % + \setchemicalcircsegment C 0 360 500 360 0 -500 + % + \def\processchemical[##1##2##3##4##5]% + {\processaction + [##1##2##3##4##5] + [ MIR????=>\setchemicalmirror{3}, + -MIR????=>\resetchemicalmirror{3}, + *MIR????=>\togglechemicalmirror{3}, + CB????=>\processlocalchemicals{B,C,Z}, + C????=>\processchemicalcircsegment{C}{1????}, + -ROT##5=>\reversechemical{ROT}{##5}{3,4,1,2}, + ROT##4##5=>\processchemicalrotation{##4##5}, + MOV##4##5=>\processchemicaltranslate{##4##5}, + CB##3##4##5=>\processlocalchemicals + {ROT##3,C,B,Z2..4, + MOV##3,*MIR,-ROT##3,C,B,Z2..4}, + B##2##3##4##5=>\processprivatechemicallinesegment{B}{##2##3##4##5}, + Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{4} + {l,t,r,b, t,r,b,l, r,b,l,t, b,l,t,r}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} + +% 1: 45 2: -90 3: -225 +% 4: -45 5: -135 6: -270 + +\newif\ifNEWMANstagger \NEWMANstaggertrue + +\def\executechemicalNEWMANSTAGGER% + {\NEWMANstaggertrue\executechemicalNEWMAN} + +\def\executechemicalNEWMANECLIPSE% + {\NEWMANstaggerfalse\executechemicalNEWMAN} + +\def\executechemicalNEWMAN[#1]% + {\setchemicalname NEWMAN + % + \setchemicalmaximum 6 + \setchemicaldistance 0 + \setchemicalsubstitute 0 + % + \ifNEWMANstagger + \setchemicalrotation 1 0.707 0.707 0.707 -0.707 -0.707 -0.707 -0.707 0.707 + \setchemicalrotation 2 0 -1 -1 0 0 1 1 0 + \setchemicalrotation 3 -0.707 0.707 0.707 0.707 0.707 -0.707 -0.707 -0.707 + \else + \setchemicalrotation 1 .866 -.5 -.5 -.866 -.866 .5 .5 .866 + \setchemicalrotation 2 -.259 .966 .966 .259 .259 -.966 -.966 -.259 + \setchemicalrotation 3 -.5 -.866 -.866 .5 .5 .866 .866 -.5 + \fi + \setchemicalrotation 4 0.707 -0.707 -0.707 -0.707 -0.707 0.707 0.707 0.707 + \setchemicalrotation 5 -0.707 -0.707 -0.707 0.707 0.707 0.707 0.707 -0.707 + \setchemicalrotation 6 0 1 1 0 0 -1 -1 0 + % + \ifNEWMANstagger + \setchemicalangle 1 315 45 135 225 + \setchemicalangle 2 90 180 270 0 + \setchemicalangle 3 225 315 45 135 + \else + \setchemicalangle 1 30 120 210 300 + \setchemicalangle 2 255 345 75 165 + \setchemicalangle 3 120 210 300 30 + \fi + \setchemicalangle 4 45 135 225 315 + \setchemicalangle 5 135 225 315 45 + \setchemicalangle 6 270 0 90 180 + % + \setchemicaltranslate 1 -1500 0 + \setchemicaltranslate 2 0 1500 + \setchemicaltranslate 3 1500 0 + \setchemicaltranslate 4 0 -1500 + % + \setchemicallinesegment B1 0 0 1000 0 + \setchemicallinesegment B2 0 0 1000 0 + \setchemicallinesegment B3 0 0 1000 0 + \setchemicallinesegment B4 500 0 1000 0 + \setchemicallinesegment B5 500 0 1000 0 + \setchemicallinesegment B6 500 0 1000 0 + % + \setchemicaltextelement Z 1100 0 + % + \setchemicalcircsegment C 0 360 500 360 0 -500 + % + \def\processchemical[##1##2##3##4]% + {\processaction + [##1##2##3##4] + [STAGGER????=>{\executechemicalNEWMANSTAGGER[#1]}, + ECLIPSE????=>{\executechemicalNEWMANECLIPSE[#1]}, + B????=>\processlocalchemicals{B1..6}, + CB????=>\processlocalchemicals{B1..6,C,Z1..6}, + C????=>\processchemicalcircsegment{C}{1????}, + ROT##4=>\processchemicalrotation{##4}, + MOV##4=>\processchemicaltranslate{##4}, + B##2##3##4=>\processprivatechemicallinesegment{B}{##2##3##4}, + Z##2##3##4=>\ifNEWMANstagger + \processchemicaltextelement{Z}{##2##3##4}{#1}{6} + {l,t,r,l,r,b, l,r,l,r,r,l, r,b,l,r,l,t, r,l,r,l,l,r}% + \else + \processchemicaltextelement{Z}{##2##3##4}{#1}{6} + {l,r,t,t,r,b, t,b,r,r,b,l, r,l,b,b,l,t, b,t,l,l,t,r}% + \fi, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +\def\executechemicalCHAIR[#1]% smaller + {\setchemicalname CHAIR + % + \setchemicalmaximum 6 + % + \setchemicallinesegment B1 1600 800 2800 -800 + \setchemicallinesegment B2 2800 -800 800 0 + \setchemicallinesegment B3 800 0 -1600 -800 + \setchemicallinesegment B4 -1600 -800 -2800 800 + \setchemicallinesegment B5 -2800 800 -800 0 + \setchemicallinesegment B6 -800 0 1600 800 + % + \setchemicallinesegment +R1 1600 800 1600 1600 + \setchemicallinesegment +R2 2800 -800 2800 -1600 + \setchemicallinesegment +R3 800 0 800 800 + \setchemicallinesegment +R4 -1600 -800 -1600 -1600 + \setchemicallinesegment +R5 -2800 800 -2800 1600 + \setchemicallinesegment +R6 -800 0 -800 -800 + % + \setchemicallinesegment -R1 1600 800 2350 522 % 750 278 + \setchemicallinesegment -R2 2800 -800 3493 -400 + \setchemicallinesegment -R3 800 0 1329 -600 % 528 600 + \setchemicallinesegment -R4 -1600 -800 -2350 -522 % 750 278 + \setchemicallinesegment -R5 -2800 800 -3493 400 + \setchemicallinesegment -R6 -800 0 -1329 600 % 528 600 + % + \setchemicaltextelement +RZ1 1600 1800 + \setchemicaltextelement +RZ2 2800 -1800 + \setchemicaltextelement +RZ3 800 1000 + \setchemicaltextelement +RZ4 -1600 -1800 + \setchemicaltextelement +RZ5 -2800 1800 + \setchemicaltextelement +RZ6 -800 -1000 + % + \setchemicaltextelement -RZ1 2538 453 % 200 lang + \setchemicaltextelement -RZ2 3666 -300 + \setchemicaltextelement -RZ3 1460 -750 + \setchemicaltextelement -RZ4 -2538 -453 + \setchemicaltextelement -RZ5 -3666 300 + \setchemicaltextelement -RZ6 -1460 750 + % + \def\processchemical[##1##2##3##4##5]% + {\def\chemicalrotation{1}% + \processaction + [##1##2##3##4##5] + [ B????=>\processlocalchemicals{B1,B2,B3,B4,B5,B6}, + -R????=>\processlocalchemicals{-R1,-R2,-R3,-R4,-R5,-R6}, + +R????=>\processlocalchemicals{+R1,+R2,+R3,+R4,+R5,+R6}, + B##2????=>{\getchemicallinesegment[0][B##2]}, + -RZ##4????=>{\getchemicalfixedtextelement[-RZ##4][1][##4][l,l,tc,r,r,bc][#1]}, + +RZ##4????=>{\getchemicalfixedtextelement[+RZ##4][1][##4][c][#1]}, + -R##3????=>{\getchemicallinesegment[0][-R##3]}, + +R##3????=>{\getchemicallinesegment[0][+R##3]}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} + +\def\executechemicalarrow#1#2[#3]% + {\dogetcommalistelement1\from#3\to\toptext + \dogetcommalistelement2\from#3\to\bottext + \def\dochemicaltext##1% + {\dosetsubscripts% + $\@@dochemicalstyle{\@@localchemicalformat\strut##1}$% + \doresetsubscripts}% + \doifelse\@@chemicallocation\v!intext + {#1{\dochemicaltext\toptext}}% + {\setbox\chemicalsymbols=\hbox + {\box\chemicalsymbols + \vbox{\halign{##\cr + \hbox to 3em{\hss\dochemicaltext{\toptext}\hss}\cr + #2% + \hbox to 3em{\hss\dochemicaltext{\bottext}\hss}\cr}}}}} + +\def\executechemicalGIVES + {\executechemicalarrow + {\chemicalsinglepicturearrow}% nodig + {\rightarrowfill\cr}} + +\def\executechemicalEQUILIBRIUM + {\executechemicalarrow + {\chemicaldoublepicturearrow}% nodig + {\rightarrowfill\cr\leftarrowfill\cr}} + +\def\executechemicalMESOMERIC + {\executechemicalarrow + {\chemicalsinglepicturearrow}% nodig + {$\leftarrow\hskip-1em$\rightarrowfill\cr}} + +\def\executechemicalsign#1[#2]% + {\doifelse\@@chemicallocation\v!intext + {\dosetsubscripts + $\@@dochemicalstyle{\@@localchemicalformat#1}$% + \doresetsubscripts} + {\setbox\chemicalsymbols\hbox + {\box\chemicalsymbols + \dosetsubscripts + $\@@dochemicalstyle{\@@localchemicalformat#1}$% + \doresetsubscripts}}} + +\def\executechemicalPLUS + {\executechemicalsign{+}} + +\def\executechemicalMINUS + {\executechemicalsign{-}} + +\def\executechemicalEQUAL + {\executechemicalsign{=}} + +\def\executechemicalSPACE[#1]% + {\doifnot\@@chemicallocation\v!intext + {\setbox\chemicalsymbols\hbox + {\box\chemicalsymbols + \quad}}} + +\def\executechemicalCHEM[#1]% + {\doifnot\@@chemicallocation\v!intext + {\setbox\chemicalsymbols\hbox + {\box\chemicalsymbols + $\@@dochemicalstyle{\@@localchemicalformat#1}$}}} + +\def\executechemicalTEXT[#1]% + {\doifnot\@@chemicallocation\v!intext + {\setbox\chemicalsymbols\hbox + {\box\chemicalsymbols#1}}} + +%\def\executechemicalLOW[#1]% +% {\setlowsubscripts} +% +%\def\executechemicalHIGH[#1]% +% {\sethighsubscripts} + +\def\putchemicalrule#1#2#3#4% + {\ifcase\chemicaldrawingmode + \putrule from {#1} {#2} to {#3} {#4} + \or + \psline(#1,#2)(#3,#4)% + \or + \bgroup + \!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + x1 := \MPdivten[\the\!!counta]u ; + y1 := \MPdivten[\the\!!countb]u ; + x2 := \MPdivten[\the\!!countc]u ; + y2 := \MPdivten[\the\!!countd]u ; + draw z1--z2 ; + \stopMPdrawing + \egroup + \fi} + +\def\executechemicalcomplex#1% + {\bgroup + \putchemicalrule {0} {-\@@chemicalbottom} {0} {\@@chemicaltop}% + \putchemicalrule {0} {\@@chemicaltop} {#1150} {\@@chemicaltop}% + \putchemicalrule {0} {-\@@chemicalbottom} {#1150} {-\@@chemicalbottom}% + \egroup} + +\def\executechemicalOPENCOMPLEX[#1]% + {\executechemicalcomplex+\ignorespaces + \executechemicalSPACE[]} + +\def\executechemicalCLOSECOMPLEX[#1]% + {\executechemicalSPACE[]% + \executechemicalcomplex-\ignorespaces} + +% nog niet door midden as! + +\def\executechemicalverticalsymbol#1#2% + {\executechemicalTEXT + [$\left#1\relax + \dimen0=\@@chemicalunit + \scratchcounter=\@@chemicaltop + \advance\scratchcounter by \@@chemicalbottom + \dimen0=\scratchcounter\dimen0 + \vcenter to \dimen0{} + \dimen2=\@@chemicalunit + \dimen2=\@@chemicalright\dimen0 + \vcenter{\leftskip1em\hsize\dimen2\relax\strut#2\strut}% + \right.$]}% + +\def\executechemicalUPARROW[#1]% + {\executechemicalverticalsymbol\uparrow{#1}} + +\def\executechemicalDOWNARROW[#1]% + {\executechemicalverticalsymbol\downarrow{#1}} + +\def\executechemicalUPDOWNARROW[#1]% + {\executechemicalverticalsymbol\updownarrow{#1}} + +\let\setchemicalattributes\relax + +\setupchemical + [\c!width=0, + \c!height=0, + \c!left=0, + \c!right=0, + \c!top=0, + \c!bottom=0, + \c!bodyfont=\the\bodyfontsize, + \c!resolution=\outputresolution, + \c!scale=\v!medium, + \c!size=\v!medium, + \c!textsize=\v!big, + \c!frame=\v!off, + \c!axis=\v!off, + \c!state=\v!start, + \c!style=\rm, + \c!location=, + \c!option=, + \c!offset=LOW, + \c!alternative=1, + \c!color=, + \c!rulethickness=, + \c!rulecolor=, + \c!factor=1] + +% Tijdelijk plaatsen we deze extra macro's hier. +% +% mathontop: \mtop {} {} +% textontop: \ttop {} {} + +\def\putontop#1#2% + {\vbox + {\halign + {\strut\hss##\hss\cr + #1\cr + #2\cr}}} + +\def\ttop#1#2% + {\putontop{\tx#1}{#2}} + +\def\mtop#1#2% + {\vbox + {\offinterlineskip + \halign + {\hss##\hss\cr + $\scriptscriptstyle#1$\cr + \noalign{\vskip.5ex}% + $#2$\cr}}} + +\def\ctop#1#2% + {\vbox + {\offinterlineskip + \halign + {\hss##\hss\cr + $\@@dochemicalstyle{\@@localchemicalformat\scriptscriptstyle#1}$\cr + \noalign{\vskip.5ex}% + $\@@dochemicalstyle{\@@localchemicalformat#2}$\cr}}} + +%D Here are a couple of \CONTEXT\ goodies: +%D +%D \startitemize +%D \item styles hooked into \CONTEXT\ style mechanism +%D \item support for color and rulethickness (mp mode only) +%D \item position tracking +%D \stopitemize + +\ifCONTEXT \else \protect \endinput \fi + +\let\@@chemicalrulecolor\empty +\let\@@chemicalcolor \empty + +% \def\setchemicalattributes +% {\scratchdimen\@@chemicalchemicalrulethickness +% \def\chemicalattributes +% {withpen pencircle scaled \the\scratchdimen\space +% withcolor }% +% \doifelsenothing\@@chemicalchemicalrulecolor +% {\edef\chemicalattributes{\chemicalattributes black}} +% {\edef\chemicalattributes{\chemicalattributes \MPcolor{\@@chemicalchemicalrulecolor}}}% +% \startMPdrawing +% drawoptions (\chemicalattributes) ; +% \stopMPdrawing} + +\def\setchemicalattributes + {\scratchdimen\@@chemicalrulethickness + \def\chemicalattributes + {withpen pencircle scaled \the\scratchdimen\space + withcolor }% + \doifelsenothing\@@chemicalrulecolor + {\edef\chemicalattributes{\chemicalattributes black}} + {\edef\chemicalattributes{\chemicalattributes \MPcolor{\@@chemicalrulecolor}}}% + \startMPdrawing + drawoptions (\chemicalattributes) ; + \stopMPdrawing} + +\def\@@dochemicalcolor + {\doifsomething\@@chemicalcolor{\color[\@@chemicalcolor]}} + +\def\@@dochemicalstyle + {\doconvertfont\@@chemicalstyle} + +\setupchemical + [\c!rulethickness=\linewidth, + \c!rulecolor=, + \c!color=] + +\def\cpos#1#2% + {\iftrialtypesetting + #2% + \else + \bgroup + \globalpushmacro\dowithchemical + \gdef\dowithchemical##1{\hpos{#1}{##1}\globalpopmacro\dowithchemical}% + #2% + \egroup + \fi} + +\protect \endinput + +% \startchemical[axis=on,frame=yes] +% \chemical[SIX,ROT2,B,R36,RZ6][CH_3] +% \chemical[PB:RZ3,ONE,Z05,SB5,EP37,PE][O,H] +% \stopchemical + +% \startchemical[size=big,scale=small,axis=on,frame=yes,factor=1.5] +% \chemical[SIX,ROT2,B,R36,RZ6][CH_3] +% \chemical[PB:RZ3,ONE,Z05,SB5,EP37,PE][O,H] +% \stopchemical + +% \startchemical[size=big,scale=medium,axis=on,frame=yes,factor=1.5] +% \chemical[SIX,ROT2,B,R36,RZ6][CH_3] +% \chemical[PB:RZ3,ONE,Z05,SB5,EP37,PE][O,H] +% \stopchemical + +% \startchemical[size=big,scale=big,axis=on,frame=yes,factor=1.5] +% \chemical[SIX,ROT2,B,R36,RZ6][CH_3] +% \chemical[PB:RZ3,ONE,Z05,SB5,EP37,PE][O,H] +% \stopchemical + diff --git a/tex/context/base/ppchtex.mkiv b/tex/context/base/ppchtex.mkiv new file mode 100644 index 000000000..e81551eea --- /dev/null +++ b/tex/context/base/ppchtex.mkiv @@ -0,0 +1,3460 @@ +%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 + +\unexpanded\def\setupchemicalformat[#1]% + {\processaction + [\getvalue{#1\c!size}] + [ \v!small=>\def\@@localchemicalformat{\scriptscriptstyle}, + \v!medium=>\def\@@localchemicalformat{\ifsmallchemicaltext\scriptscriptstyle\else\scriptstyle\fi}, + \v!big=>\def\@@localchemicalformat{\ifsmallchemicaltext\scriptstyle\else\textstyle\fi}, + \s!unknown=>\def\@@localchemicalformat{\getvalue{#1\c!size}}]% + \processaction + [\getvalue{#1\c!textsize}] + [ \v!small=>\def\@@localchemicalstyle{\scriptscriptstyle}, + \v!medium=>\def\@@localchemicalstyle{\ifsmallchemicaltext\scriptscriptstyle\else\scriptstyle\fi}, + \v!big=>\def\@@localchemicalstyle{\ifsmallchemicaltext\scriptstyle\else\textstyle\fi}, + \s!unknown=>\def\@@localchemicalstyle{\getvalue{#1\c!textsize}}]% + \processaction + [\getvalue{#1\c!scale}] + [ \v!small=>\def\@@localchemicalscale{500}, + \v!medium=>\def\@@localchemicalscale{625}, + \v!big=>\def\@@localchemicalscale{750}, + \s!unknown=>\def\@@localchemicalscale{\getvalue{#1\c!scale}}]} + +\def\@@currentchemicalformat + {\ifinchemical + \@@localchemicalformat + \else + \@@localchemicalstyle + \fi} + +\def\dosetupchemical[#1]% + {\getparameters[\??chemical\s!chemical][#1]% + \doifelse{\@@chemicalchemicaloffset}{LOW} + {\setlowsubscripts} + {\sethighsubscripts}% + \setupchemicalformat[\??chemical\s!chemical]% + \ignorespaces} + +\unexpanded\def\setupchemical + {\dosingleargument\dosetupchemical} + +\def\@@dochemicalstyle% % default mapping + {\@@chemicalstyle} + +\def\@@dochemicalcolor% % no mapping yet + {} + +\def\@@chemicalstyle % $inner-style$ % (overloaded) + {\@@chemicalchemicalstyle} % $$outer-style$$ + +\def\@@writechemicalstate#1#2% + {} + +\def\@@beginchemicallocalpicture + {\ifcase\chemicaldrawingmode + \beginpicture + \or + \pspicture(0,0)(0,0) % is this permitted ? + \or + \pushMPdrawing + \startMPdrawing + %prologues := 1 ; + %input mp-tool ; + u := 10*\@@chemicalunit; + bboxmargin := 0pt ; + pickup pencircle scaled 2u ; % ??? + \stopMPdrawing + \beginpicture + \fi} + +\def\@@endchemicallocalpicture#1#2% + {\ifcase\chemicaldrawingmode + \endpicture + \or + \endpspicture + \or + \resetchemicalcoordinates + \setbox2\hbox{\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} + +\unexpanded\def\startchemical + {\bgroup % t.b.v. ungrouped floats + \dostartchemical} + +\unexpanded\def\stopchemical + {\checkchemicalpicture + \@@endchemicalpicture + \egroup + \ifnum\chemicaldrawingmode=1 + \dimen0=\@@chemicalunit + \setbox0=\hbox{\lower\@@chemdepth\dimen0\box0}% + \ht0=\@@chemheight\dimen0 + \dp0=\@@chemdepth\dimen0 + \fi + \dimen0=\ht0 + \advance\dimen0 by \dp0 + \inchemicalfalse % enables \chemie{} in text + \setbox4=\alignedchemical\themidtext + \setbox6=\alignedchemical\thetoptext + \setbox8=\alignedchemical\thebottext + \setbox4=\hbox to \wd0 + {\strut\hss$\vcenter{\box4}$\hss}% + \setbox2=\vbox to \dimen0 + {\hbox to \wd0{\strut\hss\box6\hss} + \vfill + \hbox to \wd0{\strut\hss\box8\hss} + \vss}% disables the depth + \wd0=0pt \wd4=0pt + \ht2=\ht0 \dp2=\dp0 + \ht4=\ht0 \dp4=\dp0 + \@@chemicalborder{\box0\box4\box2}% text on top of chemicals + \endgroup + \ignorespaces + \egroup} % t.b.v. ungrouped floats + +\def\alignedchemical#1% + {\vtop + {\def\par{\egroup\hbox\bgroup\strut}% + \let\\=\par + \let\endgraf=\par + \hbox\bgroup\strut#1\egroup}} + +% \setchemicalcoordinates{#1}{#2} +% +% #1: verplaatsing in x-richting +% #2: verplaatsing in y-richting + +\newif\ifchemicaldirection + +\def\checkchemicaldirection#1#2% + {\ifchemicaldirection + \ifnum#1>0 \advance\horchemical -\chemicaldirection \fi + \ifnum#1<0 \advance\horchemical +\chemicaldirection \fi + \ifnum#2>0 \advance\verchemical -\chemicaldirection \fi + \ifnum#2<0 \advance\verchemical +\chemicaldirection \fi + \chemicaldirectionfalse + \fi} + +\def\processchemicaldirection% + {\chemicaldirectiontrue\processchemicaltranslate} + +\def\setchemicalcoordinates#1#2% + {\advance\horchemical #1\relax + \advance\verchemical #2\relax + \checkchemicaldirection{#1}{#2}% + \!!counta=-\horchemical\edef\chemicalxoffset{\the\!!counta}% + \!!countb=-\verchemical\edef\chemicalyoffset{\the\!!countb}% + \ifnum\chemicaldrawingmode=1 + % njet + \else + \setcoordinatesystem point at {\the\horchemical} {\the\verchemical} + \fi} + +\def\resetchemicalcoordinates + {\horchemical=0 + \verchemical=0 + \edef\chemicalxoffset{0}% + \edef\chemicalyoffset{0}% + \ifnum\chemicaldrawingmode=1 + % njet + \else + \setcoordinatesystem point at 0 0 + \fi} + +\def\restorechemicalcoordinates + {%\writestatus{ppchtex}{restoring \the\horchemical,\the\verchemical}% + \edef\chemicalxoffset{\the\horchemical}% + \edef\chemicalyoffset{\the\verchemical}% + \ifnum\chemicaldrawingmode=1 + % njet + \else + \setcoordinatesystem point at {\the\horchemical} {\the\verchemical} + \fi} + +\def\setchemicaltranslate #1 #2 #3 + {\setvalue{\s!translate#1}{\setchemicalcoordinates{#2}{#3}}} + +\def\processchemicaltranslate#1% + {\def\doprocess[##1##2]% + {\doifchemicalnumber{##1}{MOV#1} + {\ifnum##1=0 + \def\chemicaloffset{0}% incompatible change + \resetchemicalcoordinates + \else + \getvalue{\s!translate##1}% + \dochemicaloffset{##1}% + \def\chemicaloffset{0}% + \fi}}% + \doprocess[#1]} + +\def\setchemicaldistance #1 + {\setvalue{\s!distance1}{\setchemicalcoordinates{-#1}{ 0}}% + \setvalue{\s!distance2}{\setchemicalcoordinates{ 0}{ #1}}% + \setvalue{\s!distance3}{\setchemicalcoordinates{ #1}{ 0}}% + \setvalue{\s!distance4}{\setchemicalcoordinates{ 0}{-#1}}} + +\def\setchemicaldirection #1 + {\def\chemicaldirection{#1}} + +\def\processchemicaldistance#1% + {\def\doprocess[##1##2]% + {\doifchemicalnumber{##1}{ADJ#1} + {\ifnum##1=0 + \resetchemicalcoordinates + \else + \def\@@chemicalpostponed{\getvalue{\s!distance##1}}% + \@@chemicalpostponed + \fi}}% + \doprocess[#1]} + +\def\setchemicalsubstitute #1 + {\setvalue{\s!substitute1}{\setchemicalcoordinates{-#1}{ 0}}% + \setvalue{\s!substitute2}{\setchemicalcoordinates{ 0}{ #1}}% + \setvalue{\s!substitute3}{\setchemicalcoordinates{ #1}{ 0}}% + \setvalue{\s!substitute4}{\setchemicalcoordinates{ 0}{-#1}}} + +\def\processchemicalsubstitute#1% + {\def\doprocess[##1##2]% + {\doifchemicalnumber{##1}{SUB#1} + {\ifnum##1=0 + \resetchemicalcoordinates + \else + \def\@@chemicalpostponed{\getvalue{\s!substitute##1}}% + \@@chemicalpostponed + \fi}}% + \doprocess[#1]} + +% Het is mogelijk een offset of move meerdere malen uit te +% voeren, door een nummer voor het commando te plaatsen. + +\def\chemicalrepeat {1} + +\def\redoprocesschemical[#1#2]% + {\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\plotchemicaldasheddeltaline#1#2#3#4% + {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax + \ifnum\chemicaldrawingmode=2 + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + x0 := \MPdivten[\chemicalxoffset]u ; + y0 := \MPdivten[\chemicalyoffset]u ; + x1 := \MPdivten[\the\!!counta]u ; + y1 := \MPdivten[\the\!!countb]u ; + x2 := \MPdivten[\the\!!countc]u ; + y2 := \MPdivten[\the\!!countd]u ; + z20 = z2 rotatedaround(z1,+5) ; + z21 = z2 rotatedaround(z1,-5) ; + draw (z1 rotatedaround(origin,-\chemicalangle)) shifted z0 ; + save n ; n := 5 ; + for i=1 upto n : + draw ((((z20--z21) shifted -z2) shifted (i/n)[z2,z1]) + rotatedaround(origin,-\chemicalangle)) shifted z0 ; + endfor + \stopMPdrawing + \account{#1}{#2}% + \account{#3}{#4}% + \else + \doplotchemicalline + \advance\!!countc by 16 \advance\!!countd by -21 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -8 \advance\!!countd by 14 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \fi} + +\def\plotchemicalwavyline#1#2#3#4% + {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax + \ifnum\chemicaldrawingmode=2 + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + x0 := \MPdivten[\chemicalxoffset]u ; + y0 := \MPdivten[\chemicalyoffset]u ; + x1 := \MPdivten[\the\!!counta]u ; + y1 := \MPdivten[\the\!!countb]u ; + x2 := \MPdivten[\the\!!countc]u ; + y2 := \MPdivten[\the\!!countd]u ; + save d ; pair d ; + d := z2 rotatedaround(z1,+5) shifted -z2 ; + save n ; n := 4 ; + draw ((for i=0 upto n-1 : + ((i)/n)[z1,z2] .. + ((i+.25)/n)[z1,z2] shifted d .. + ((i+.50)/n)[z1,z2] .. + ((i+.75)/n)[z1,z2] shifted -d .. + endfor + z2) rotatedaround(origin,-\chemicalangle)) shifted z0 ; + \stopMPdrawing + \account{#1}{#2}% + \account{#3}{#4}% + \else + \doplotchemicalline + \advance\!!countc by 16 \advance\!!countd by -21 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -8 \advance\!!countd by 14 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \fi} + +\def\processchemicaldasheddeltalinesegment#1#2% + {\bgroup + \def\plotchemicalline{\plotchemicaldasheddeltaline}% + \doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}% + \egroup} + +\def\processchemicalwavylinesegment#1#2% + {\bgroup + \def\plotchemicalline{\plotchemicalwavyline}% + \doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}% + \egroup} + +\def\processchemicalopenend#1#2% + {\doprocesschemicallinesegment0c\doprocesschemicalopenend{#1}{#2}} + +\def\doprocesschemicalopenend[#1][#2]% + {\chemicalrotate[#1]% + \dochemicaloffset{#1}% + \ifcase\chemicaldrawingmode + \beginpicture + \setquadratic\plot + 300 0 400 0 + 500 0 550 75 + 600 0 650 -75 + 700 0 750 75 + 800 0 850 -75 + 900 0 950 0 + 1050 0 / + \endpicture + \or + \rput{-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\psline(300,0)(500,0)% + \rput(500,0){\psplot[yunit=75,plotstyle=curve]{0}{720}{x sin}}% + \psline(950,0)(1050,0)}% + \or + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + x0 := \MPdivten[\chemicalxoffset]u ; + y0 := \MPdivten[\chemicalyoffset]u ; + draw + (((30.0u,0)--(50.0u,0){up}..(55.0u,7.5u).. + (60.0u,0)..(65.0u,-7.5u)..(70.0u,0).. + (75.0u,7.5u)..(80.0u,0)..(85.0u,-7.5u)..{up} + (90.0u,0)--(105.0u,0)) rotatedaround(origin,-\chemicalangle)) + shifted z0 ; + \stopMPdrawing + \fi + \undochemicaloffset} + +% \plotchemicalcircle{#1}{#2}{#3}{#4} +% +% #1: lengte van de boog in graden +% #2: x-coordinaat eindpunt +% #3: y-coordinaat eindpunt + +\newif\ifchemicaldotted + +\def\plotchemicalcircle#1#2#3#4#5#6% + {\bgroup + \ifcase\chemicaldrawingmode + \ifchemicaldotted + \findlength{\circulararc {#4} degrees from {#5} {#6} center at {0} {0} }% + \divide\totalarclength by 6 + \def\b{\the\totalarclength}% + \divide\totalarclength by 2 + \def\a{\the\totalarclength}% + \setdashpattern <\a,\b,\b,\b,\b,\b,\a> + \fi + \circulararc {#4} degrees from {#5} {#6} center at {0} {0} % + \or + \ifchemicaldotted + \psset{linestyle=dashed}% + \fi + \rput + {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\psarc(0,0){#3}{#1}{#2}}% + \or + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + r := \MPdivten[#3]*2u; + x0 := \MPdivten[\chemicalxoffset]u ; + y0 := \MPdivten[\chemicalyoffset]u ; + draw ((subpath (#1/45,#2/45) of (fullcircle scaled (r))) + rotatedaround (origin,\chemicalangle+150)) + shifted z0 \ifchemicaldotted dashed withdots \fi ; + \stopMPdrawing + \fi + \egroup} + +\def\setchemicalcircsegment #1 #2 #3 #4 #5 #6 #7 + {\setvalue{\s!chemicalcircsegment#1}{\plotchemicalcircle{#2}{#3}{#4}{#5}{#6}{#7}}} + +\def\getchemicalcircsegment[#1][#2]% + {\chemicalrotate[#1]% + \getvalue{\s!chemicalcircsegment#2}} + +\def\doprocesschemicalcircsegment#1#2% + {\def\doprocess[##1##2##3##4##5]% + {\doifelse{##1}{?} + {\doprocess[1..\maxchemical ????]} + {\doifchemicalnumber{##1}{#1#2} + {\doifelse{##2##3}{..} + {\doifchemicalnumber{##4}{#1#2} + {\getchemicalcircsegment[##1][#1]% + \doifnot{##1}{##4} + {\!!counta=##1\relax + \advance\!!counta by 1 + \edef\nextsegment{\the\!!counta}% + \doprocess[\nextsegment..##4##5]}}} + {\getchemicalcircsegment[##1][#1]% + \doifnot{##2}{?} + {\doprocess[##2##3##4##5]}}}}}% + \doprocess[#2]} + +\def\processchemicalcircsegment% + {\chemicaldottedfalse\doprocesschemicalcircsegment} + +\def\processchemicaldottsegment% + {\chemicaldottedtrue\doprocesschemicalcircsegment} + +\let\endchemicalpicture = \relax +\let\checkchemicalpicture = \relax +\let\nomoreaccounting = \relax + +\newif\ifchemicalpicture + +\def\beginchemicalpicture#1% NO PSTRICKS SUPPORT YET + {\checkchemicalpicture + \bgroup % DOES NOT HANDLE AUTOWIDTH/HEIGHT + \chemicalpicturetrue + \processchemical[#1]} + +\def\setchemicalpicture#1#2% + {\chemicalpicturefalse + \def\endchemicalpicture% + {\@@endchemicallocalpicture{#1}{#2}% + \egroup + \ifnum\chemicaldrawingmode=1 + \rput + {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\expanded{\rput[\chemicalloca]{\chemicalangle}(#1,#2){\box\nextbox}}}% + \else + \expanded{\put{\box\nextbox}[\chemicalloca] at {#1} {#2} } + \fi + \egroup}% + \def\checkchemicalpicture% + {\ifx\endchemicalpicture\relax \else + \writestatus{ppchtex}{missing end of picture (PE)}% + \endchemicalpicture + \fi}% + \setbox\nextbox=\hbox\bgroup + \@@beginchemicallocalpicture + % alternatief: gewoon accounting, en zelf l,r afhandelen + \ifnum\chemicaldrawingmode=1 + % njet + \else + \accountingon + \let\nomoreaccounting=\accountingoff + \fi} + +\def\doskipchemical[#1][#2]% + {{\tt[ppchtex]}} + +\def\skipchemical% + {\dodoubleargument\doskipchemical} + +\def\complexchemical% met \expandafter + {\ifinchemical + \expandafter\dochemical + \else + \writestatus{ppchtex}{the [][]-alternative is not permitted here}% + \expandafter\skipchemical + \fi} + +\newif\ifinnerchemical + +\def\dosimplechemical#1#2#3% + {\doifdefinedelse{\??chemical\c!location} + {\writestatus{ppchtex}{the {}{}-alternative is not permitted here}} + {\ifinnerchemical + \let\chemicalsign = \chemicalinnersign + \let\chemicalmolecule = \chemicalinnermolecule + \let\chemicalsinglearrow = \chemicalsingleinnerarrow + \let\chemicaldoublearrow = \chemicaldoubleinnerarrow + \let\chemicaltwintiparrow = \chemicaltwintipinnerarrow + \else + \let\chemicalsign = \chemicaloutersign + \let\chemicalmolecule = \chemicaloutermolecule + \let\chemicalsinglearrow = \chemicalsingleouterarrow + \let\chemicaldoublearrow = \chemicaldoubleouterarrow + \let\chemicaltwintiparrow = \chemicaltwintipouterarrow + \fi + \disablechemicalspecials + \unexpandedprocessallactionsinset + [#1] + [ HIGH=>\sethighsubscripts, + LOW=>\setlowsubscripts, + PLUS=>\chemicalsign{+}, + GIVES=>\chemicalsinglearrow{#2}{#3}, + EQUILIBRIUM=>\chemicaldoublearrow{#2}{#3}, + MESOMERIC=>\chemicaltwintiparrow{#2}{#3}, + SINGLE=>\singlechemicalbond, + DOUBLE=>\doublechemicalbond, + TRIPLE=>\triplechemicalbond, + +=>\chemicalsign{+}, + ->=>\chemicalsinglearrow{#2}{#3}, + <->=>\chemicaldoublearrow{#2}{#3}, + <>=>\chemicaltwintiparrow{#2}{#3}, + -=>\singlechemicalbond, + --=>\doublechemicalbond, + ---=>\triplechemicalbond, + \s!unknown=>\enablechemicalspecials + \chemicalmolecule{\commalistelement}{#2}{#3}]}} + +\def\dosimplechemicalA#1#2#3% % 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}} + +\unexpanded\def\definechemical% + {\dosingleargument\dodefinechemical} + +\def\getpredefinedchemical#1% + {\doifdefinedelse{\??chemical#1} + {\getvalue{\??chemical#1}} + {\doifdefinedelse{#1} + {\getvalue{#1}} + {\writestatus{ppchtex}{unknown chemical definition #1}}}} + +% Hieronder zijn de definities van de structuren opgenomen. De +% naam van de structuur is als volgt opgebouwd: +% +% \executechemicalNUMBER[#1] +% +% waarbij [#1] betrekking heeft op de tekstelementen van \chemie, +% de [tweede lijst] dus. +% +% De aan \chemie[#1][#2] meegegeven lijst van segmenten wordt +% deels door de in \execute gedefinieerde macro's afgehandeld, +% deels door algemene macro's. Segmenten hebben de vorm: +% +% [+|-|]identifier[X|XYZ|X..Y] +% +% Voorbeelden van segmenten zijn: +% +% R1 +% R1..4 +% R135 +% -R1 +% +R35 + +\setchemicalmaximum 0 + +\def\processchemical[#1]% + {\unknownchemical{#1}} + +\def\setchemicalname#1 % + {\def\chemicalname{#1}} + +\let\chemicalname=\s!unknown + +% Vooruitlopend op een gedetailleerde documentatie, zijn hier +% vast enkele gebruikte afmetingen: +% +% lengte radikalen : 500 +% afstand radikalen : 100 +% afstand dubbele radikalen : 260 +% afstand substituenten : +125 + + + + +\def\executechemicalONE[#1]% + {\setchemicalname ONE + % + \setchemicalmaximum 8 + \setchemicaldistance 0 + \setchemicalsubstitute 625 + \setchemicaldirection 303 + % + \setchemicalrotation 1 1 0 1 0 1 0 1 0 + \setchemicalrotation 2 0.707 -0.707 0.707 -0.707 0.707 -0.707 0.707 -0.707 + \setchemicalrotation 3 0 -1 0 -1 0 -1 0 -1 + \setchemicalrotation 4 -0.707 -0.707 -0.707 -0.707 -0.707 -0.707 -0.707 -0.707 + \setchemicalrotation 5 -1 0 -1 0 -1 0 -1 0 + \setchemicalrotation 6 -0.707 0.707 -0.707 0.707 -0.707 0.707 -0.707 0.707 + \setchemicalrotation 7 0 1 0 1 0 1 0 1 + \setchemicalrotation 8 0.707 0.707 0.707 0.707 0.707 0.707 0.707 0.707 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 45 135 225 315 + \setchemicalangle 3 90 180 270 0 + \setchemicalangle 4 135 225 315 45 + \setchemicalangle 5 180 270 0 90 + \setchemicalangle 6 225 315 45 135 + \setchemicalangle 7 270 0 90 180 + \setchemicalangle 8 315 45 135 225 + % + \setchemicaltranslate 1 -1000 0 + \setchemicaltranslate 2 -1000 1000 + \setchemicaltranslate 3 0 1000 + \setchemicaltranslate 4 1000 1000 + \setchemicaltranslate 5 1000 0 + \setchemicaltranslate 6 1000 -1000 + \setchemicaltranslate 7 0 -1000 + \setchemicaltranslate 8 -1000 -1000 + % + \setchemicallinesegment SB 300 0 700 0 + \setchemicallinesegment DB1 300 50 700 50 + \setchemicallinesegment DB2 300 -50 700 -50 + % + %setchemicallinesegment EP 200 125 200 -125 + \setchemicalfactorlinesegment EP 200 125 200 -125 + % + \setchemicaltextelement ES 200 0 + \setchemicaltextelement ED1 200 50 + \setchemicaltextelement ED2 200 -50 + \setchemicaltextelement ET1 200 75 + \setchemicaltextelement ET2 200 0 + \setchemicaltextelement ET3 200 -75 + \setchemicaltextelement HB1 300 0 + \setchemicaltextelement HB2 475 0 + \setchemicaltextelement HB3 650 0 + % + \setchemicaltextelement Z 800 0 + \setchemicaltextelement RZ 950 0 + \setchemicaltextelement ZN 500 0 + \setchemicaltextelement ZTN 500 150 + \setchemicaltextelement ZBN 500 -150 + % + \def\processchemical[##1##2##3##4##5]% + {\doprocesschemical[##1##2##3##4##5] + {\processaction + [##1##2##3##4##5] + [ PB:##4##5=>\beginchemicalpicture{##4##5}, + PE????=>\endchemicalpicture, + SUB##4##5=>\processchemicalsubstitute{##4##5}, + ADJ##4##5=>\processchemicaldistance{##4##5}, + MOV##4##5=>\processchemicaltranslate{##4##5}, + DIR##4##5=>\processchemicaldirection{##4##5}, + OFF##4##5=>\processchemicaloffset{##4##5}, + CCD##4##5=>\processchemicaldottsegment{CC}{##4##5}, + LDD##4##5=>\processchemicaldashedlinesegment{DB1}{##4##5}% + \processchemicallinesegment{DB2}{##4##5}, + RDD##4##5=>\processchemicallinesegment{DB1}{##4##5}% + \processchemicaldashedlinesegment{DB2}{##4##5}, + OF##3:##5=>\processchemicalphantom{##3}{##5}, + OE##3##4##5=>\processchemicalopenend{OE}{##3##4##5}, + EP##3##4##5=>\processchemicallinesegment{EP}{##3##4##5}, + ES##3##4##5=>\processchemicaltextconstant{ES}{##3##4##5}{\hbox{$\cdot$}}{0}, + ED##3##4##5=>\processchemicaltextconstant{ED}{##3##4##5}{\hbox{$\cdot$}}{0}, + ET##3##4##5=>\processchemicaltextconstant{ET}{##3##4##5}{\hbox{$\cdot$}}{0}, + HB##3##4##5=>\processchemicaltextconstant{HB}{##3##4##5}{\hbox{$\cdot$}}{0}, + SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, + DB##3##4##5=>\processchemicallinesegment{DB}{##3##4##5}, + SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, + BB##3##4##5=>\processchemicaldeltalinesegment{SB}{##3##4##5}, + BD##3##4##5=>\processchemicaldasheddeltalinesegment{SB}{##3##4##5}, + BW##3##4##5=>\processchemicalwavylinesegment{SB}{##3##4##5}, + SD##3##4##5=>\processchemicaldashedlinesegment{SB}{##3##4##5}, + TB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}% + \processchemicallinesegment{DB}{##3##4##5}, + CZ##3##4##5=>\processchemicaltextelement{RZ}{##3##4##5}{#1}{0}{}, + ZTN##4##5=>\processchemicalsmalltextconstant{ZTN}{##4##5}{\chemicaltextelementnumber}{0}, + ZTT##4##5=>\processchemicalsmalltextelement{ZTN}{##4##5}{#1}{0}{}, + ZBN##4##5=>\processchemicalsmalltextconstant{ZBN}{##4##5}{\chemicaltextelementnumber}{0}, + ZBT##4##5=>\processchemicalsmalltextelement{ZBN}{##4##5}{#1}{0}{}, + ZN##3##4##5=>\processchemicaltextconstant{ZN}{##3##4##5}{\chemicaltextelementnumber}{0}, + ZT##3##4##5=>\processchemicaltextelement{ZN}{##3##4##5}{#1}{0}{}, + Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0} + {l,l,t,r,r,r,b,l}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}}} + +\def\executechemicalTHREE[#1]% + {\setchemicalname THREE + % + \setchemicalmaximum 3 + \setchemicaldistance 289 + \setchemicalsubstitute 952 + % + \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 + \setchemicalrotation 2 -0.5 -0.866 -0.866 0.5 0.5 0.866 0.866 -0.5 + \setchemicalrotation 3 -0.5 0.866 0.866 0.5 0.5 -0.866 -0.866 -0.5 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 120 210 300 30 + \setchemicalangle 3 240 330 60 150 + % + \setchemicaltranslate 1 -1000 0 + \setchemicaltranslate 2 0 1000 + \setchemicaltranslate 3 1000 0 + \setchemicaltranslate 4 0 -1000 + % + \setchemicallinesegment B 577 0 -289 -500 + \setchemicallinesegment SB 352 -130 -64 -370 + \setchemicallinesegment -SB 352 -130 -289 -500 + \setchemicallinesegment +SB 577 0 -64 -370 + \setchemicallinesegment DB1 327 -87 -89 -327 + \setchemicallinesegment DB2 377 -172 -39 -413 + \setchemicallinesegment R 577 0 1077 0 + \setchemicallinesegment -R 577 0 1010 250 + \setchemicallinesegment +R 577 0 1010 -250 + \setchemicallinesegment ER1 577 50 1077 50 + \setchemicallinesegment ER2 577 -50 1077 -50 + \setchemicallinesegment SR 837 0 1077 0 + \setchemicallinesegment -SR 802 130 1010 250 + \setchemicallinesegment +SR 802 -130 1010 -250 + \setchemicallinesegment DR1 837 50 1077 50 + \setchemicallinesegment DR2 837 -50 1077 -50 + % + \setchemicaltextelement Z 577 0 + \setchemicaltextelement RZ 1177 0 + \setchemicaltextelement -RZ 1097 300 + \setchemicaltextelement +RZ 1097 -300 + \setchemicaltextelement CRZ 1077 0 + % + \def\processchemical[##1##2##3##4]% + {\processaction + [##1##2##3##4] + [ ROT##4=>\processchemicalrotation{##4}, + MOV##4=>\processchemicaltranslate{##4}, + SUB##4=>\processchemicalsubstitute{##4}, + ADJ##4=>\processchemicaldistance{##4}, + -RZ##4=>\processchemicaltextelement{-RZ}{##4}{#1}{3} + {l,t,r, l,r,l, r,b,l, r,l,r}, + +RZ##4=>\processchemicaltextelement{+RZ}{##4}{#1}{3} + {l,r,b, r,r,l, r,l,t, l,l,r}, + -SB##4=>\processchemicallinesegment{-SB}{##4}, + +SB##4=>\processchemicallinesegment{+SB}{##4}, + -SR##4=>\processchemicallinesegment{-SR}{##4}, + +SR##4=>\processchemicallinesegment{+SR}{##4}, + CRZ##4=>\processchemicaltextelement{CRZ}{##4}{#1}{0} + {}, + DB##3##4=>\processchemicallinesegment{DB}{##3##4}, + DR##3##4=>\processchemicallinesegment{DR}{##3##4}, + RZ##3##4=>\processchemicaltextelement{RZ}{##3##4}{#1}{3} + {l,r,r, t,r,l, r,l,l, b,l,r}, + ER##3##4=>\processchemicallinesegment{ER}{##3##4}, + SB##3##4=>\processchemicallinesegment{SB}{##3##4}, + SR##3##4=>\processchemicallinesegment{SR}{##3##4}, + -R##3##4=>\processchemicallinesegment{-R}{##3##4}, + +R##3##4=>\processchemicallinesegment{+R}{##3##4}, + B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, + R##2##3##4=>\processchemicallinesegment{R}{##2##3##4}, + Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +\def\executechemicalFOUR[#1]% + {\setchemicalname FOUR + % + \setchemicalmaximum 4 + \setchemicaldistance 500 + \setchemicalsubstitute 0 + % + \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 + \setchemicalrotation 2 0 -1 -1 0 0 1 1 0 + \setchemicalrotation 3 -1 0 0 1 1 0 0 -1 + \setchemicalrotation 4 0 1 1 0 0 -1 -1 0 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 90 180 270 0 + \setchemicalangle 3 180 270 0 90 + \setchemicalangle 4 270 0 90 180 + % + \setchemicaltranslate 1 -1000 0 + \setchemicaltranslate 2 0 1000 + \setchemicaltranslate 3 1000 0 + \setchemicaltranslate 4 0 -1000 + % + \setchemicallinesegment B 500 500 500 -500 + \setchemicallinesegment SB 500 240 500 -240 + \setchemicallinesegment -SB 500 240 500 -500 + \setchemicallinesegment +SB 500 500 500 -240 + \setchemicallinesegment DB1 450 240 450 -240 + \setchemicallinesegment DB2 550 240 550 -240 + \setchemicallinesegment EB 360 300 360 -300 + \setchemicallinesegment R 500 500 854 854 + \setchemicallinesegment -R 500 500 500 1000 + \setchemicallinesegment +R 500 500 1000 500 + \setchemicallinesegment ER1 465 535 819 889 + \setchemicallinesegment ER2 535 465 889 819 + \setchemicallinesegment SR 684 684 854 854 + \setchemicallinesegment -SR 500 760 500 1000 + \setchemicallinesegment +SR 760 500 1000 500 + \setchemicallinesegment DR1 649 719 819 889 + \setchemicallinesegment DR2 719 649 889 819 + % + \setchemicaltextelement Z 500 500 + \setchemicaltextelement RZ 925 925 + \setchemicaltextelement -RZ 500 1100 + \setchemicaltextelement +RZ 1100 500 + \setchemicaltextelement CRZ 1038 1038 + % + \setchemicaltextelement ZN 350 350 + % + \def\processchemical[##1##2##3##4]% + {\processaction + [##1##2##3##4] + [ PB:##4=>\beginchemicalpicture{##4}, + PE????=>\endchemicalpicture, + ROT##4=>\processchemicalrotation{##4}, + SUB##4=>\processchemicalsubstitute{##4}, + ADJ##4=>\processchemicaldistance{##4}, + MOV##4=>\processchemicaltranslate{##4}, + -RZ##4=>\processchemicaltextelement{-RZ}{##4}{#1}{4} + {b,l,t,r, l,t,r,b, t,r,b,l, r,b,l,t}, + +RZ##4=>\processchemicaltextelement{+RZ}{##4}{#1}{4} + {l,t,r,b, t,r,b,l, r,b,l,t, b,l,t,r}, + -SB##4=>\processchemicallinesegment{-SB}{##4}, + +SB##4=>\processchemicallinesegment{+SB}{##4}, + -SR##4=>\processchemicallinesegment{-SR}{##4}, + +SR##4=>\processchemicallinesegment{+SR}{##4}, + CRZ##4=>\processchemicaltextelement{CRZ}{##4}{#1}{0}{}, + ZN##3##4=>\processchemicaltextconstant{ZN}{##3##4}{\chemicaltextelementnumber}{0}, + ZT##3##4=>\processchemicaltextelement{ZN}{##3##4}{#1}{0}{}, + DB##3##4=>\processchemicallinesegment{DB}{##3##4}, + DR##3##4=>\processchemicallinesegment{DR}{##3##4}, + EB##3##4=>\processchemicallinesegment{EB}{##3##4}, + ER##3##4=>\processchemicallinesegment{ER}{##3##4}, + RZ##3##4=>\processchemicaltextelement{RZ}{##3##4}{#1}{4} + {lb,lt,rt,rb, lt,rt,rb,lb, rt,rb,lb,lt, rb,lb,lt,rt}, + SB##3##4=>\processchemicallinesegment{SB}{##3##4}, + SR##3##4=>\processchemicallinesegment{SR}{##3##4}, + -R##3##4=>\processchemicallinesegment{-R}{##3##4}, + +R##3##4=>\processchemicallinesegment{+R}{##3##4}, + B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, + R##2##3##4=>\processchemicallinesegment{R}{##2##3##4}, + Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +\def\executechemicalFIVE[#1]% + {\setchemicalname FIVE + % + \setchemicalmaximum 5 + \setchemicaldistance 688 + \setchemicalsubstitute 1226 + % + \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 + \setchemicalrotation 2 0.309 -0.951 -0.951 -0.309 -0.309 0.940 0.951 0.309 + \setchemicalrotation 3 -0.809 -0.588 -0.588 0.809 0.809 0.588 0.588 -0.809 + \setchemicalrotation 4 -0.809 0.588 0.588 0.809 0.809 -0.588 -0.588 -0.809 + \setchemicalrotation 5 0.309 0.951 0.951 -0.309 -0.309 -0.951 -0.951 0.309 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 72 162 252 342 + \setchemicalangle 3 144 234 324 54 + \setchemicalangle 4 216 306 36 126 + \setchemicalangle 5 288 18 108 198 + % + \setchemicaltranslate 1 -1376 0 + \setchemicaltranslate 2 -425 1304 + \setchemicaltranslate 3 1113 809 + \setchemicaltranslate 4 1113 -809 + \setchemicaltranslate 5 -425 -1304 + % + \setchemicallinesegment A 1188 500 1188 -500 + \setchemicallinesegment B 688 500 688 -500 + \setchemicallinesegment S -263 808 688 -500 + \setchemicallinesegment SS -116 606 541 -298 + \setchemicallinesegment -SS -263 808 541 -298 + \setchemicallinesegment +SS -116 606 688 -500 + \setchemicallinesegment SB 688 240 688 -240 + \setchemicallinesegment -SB 688 240 688 -500 + \setchemicallinesegment +SB 688 500 688 -240 + \setchemicallinesegment DB1 638 240 638 -240 + \setchemicallinesegment DB2 738 240 738 -240 + \setchemicallinesegment EB 548 340 548 -340 + \setchemicallinesegment R 688 500 1093 794 + \setchemicallinesegment -R 688 500 688 1000 + \setchemicallinesegment +R 688 500 1163 345 + \setchemicallinesegment ER1 659 540 1064 834 + \setchemicallinesegment ER2 727 460 1122 754 + \setchemicallinesegment SR 898 653 1093 794 + \setchemicallinesegment -SR 688 760 688 1000 + \setchemicallinesegment +SR 935 420 1163 345 + \setchemicallinesegment DR1 869 693 1064 834 + \setchemicallinesegment DR2 927 613 1122 754 + % + \setchemicaltextelement Z 688 500 + \setchemicaltextelement RZ 1188 863 + \setchemicaltextelement -RZ 688 1100 + \setchemicaltextelement +RZ 1258 315 + \setchemicaltextelement CRZ 1323 947 + % + \setchemicalcircsegment C -36 36 590 72 475 -345 + \setchemicalcircsegment CC -72 0 590 72 182 -561 + % + \setchemicaltextelement ZN 468 350 + \setchemicaltextelement RN 860 625 % 1.25 Z + \setchemicaltextelement RTN 785 728 % .12 / 103 75 + \setchemicaltextelement RBN 935 522 + % + \def\processchemical[##1##2##3##4]% + {\processaction + [##1##2##3##4] + [ FRONT????=>{\executechemicalFIVEFRONT[#1]}, + PB:##4=>\beginchemicalpicture{##4}, + PE????=>\endchemicalpicture, + ROT##4=>\processchemicalrotation{##4}, + SUB##4=>\processchemicalsubstitute{##4}, + ADJ##4=>\processchemicaldistance{##4}, + MOV##4=>\processchemicaltranslate{##4}, + -RZ##4=>\processchemicaltextelement{-RZ}{##4}{#1}{5} + {b,l,t,r,r, l,t,r,r,l, t,r,r,l,l, r,b,l,t,r}, + +RZ##4=>\processchemicaltextelement{+RZ}{##4}{#1}{5} + {l,t,r,r,b, t,r,r,l,l, r,r,l,l,r, b,l,l,r,r}, + -SB##4=>\processchemicallinesegment{-SB}{##4}, + +SB##4=>\processchemicallinesegment{+SB}{##4}, + -SR##4=>\processchemicallinesegment{-SR}{##4}, + +SR##4=>\processchemicallinesegment{+SR}{##4}, + -RD##4=>\processchemicaldashedlinesegment{-R}{##4}, + +RD##4=>\processchemicaldashedlinesegment{+R}{##4}, + -RB##4=>\processchemicaldeltalinesegment{-R}{##4}, + +RB##4=>\processchemicaldeltalinesegment{+R}{##4}, + CRZ##4=>\processchemicaltextelement{CRZ}{##4}{#1}{0}{}, + RTN##4=>\processchemicaltextconstant{RTN}{##4}{\chemicaltextelementnumber}{0}, + RTT##4=>\processchemicaltextelement{RTN}{##4}{#1}{0}{}, + RBN##4=>\processchemicaltextconstant{RBN}{##4}{\chemicaltextelementnumber}{0}, + RBT##4=>\processchemicaltextelement{RBN}{##4}{#1}{0}{}, + -SS##4=>\processchemicallinesegment{-SS}{##4}, + +SS##4=>\processchemicallinesegment{+SS}{##4}, + CCD##4=>\processchemicaldottsegment{CC}{##4}, + SS##3##4=>\processchemicallinesegment{SS}{##3##4}, + RD##3##4=>\processchemicaldashedlinesegment{R}{##3##4}, + RB##3##4=>\processchemicaldeltalinesegment{R}{##3##4}, + ZN##3##4=>\processchemicaltextconstant{ZN}{##3##4}{\chemicaltextelementnumber}{0}, + ZT##3##4=>\processchemicaltextelement{ZN}{##3##4}{#1}{0}{}, + RN##3##4=>\processchemicaltextconstant{RN}{##3##4}{\chemicaltextelementnumber}{0}, + RT##3##4=>\processchemicaltextelement{RN}{##3##4}{#1}{0}{}, + AU##3##4=>\processchemicaluparrowsegment{A}{##3##4}, + AD##3##4=>\processchemicaldownarrowsegment{A}{##3##4}, + CC##3##4=>\processchemicalcircsegment{CC}{##3##4}, + CD##3##4=>\processchemicaldottsegment{C}{##3##4}, + DB##3##4=>\processchemicallinesegment{DB}{##3##4}, + DR##3##4=>\processchemicallinesegment{DR}{##3##4}, + EB##3##4=>\processchemicallinesegment{EB}{##3##4}, + ER##3##4=>\processchemicallinesegment{ER}{##3##4}, + RZ##3##4=>\processchemicaltextelement{RZ}{##3##4}{#1}{5} + {l,l,r,r,r, l,r,r,b,l, r,r,b,l,t, r,l,l,t,r}, + SB##3##4=>\processchemicallinesegment{SB}{##3##4}, + SR##3##4=>\processchemicallinesegment{SR}{##3##4}, + -R##3##4=>\processchemicallinesegment{-R}{##3##4}, + +R##3##4=>\processchemicallinesegment{+R}{##3##4}, + B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, + C##2##3##4=>\processchemicalcircsegment{C}{##2##3##4}, + R##2##3##4=>\processchemicallinesegment{R}{##2##3##4}, + S##2##3##4=>\processchemicallinesegment{S}{##2##3##4}, + Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +\def\executechemicalSIX[#1]% + {\setchemicalname SIX + % + \setchemicalmaximum 6 + \setchemicalsubstitute 1375 + \setchemicaldistance 866 + % + \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 + \setchemicalrotation 2 0.5 -0.866 -0.866 -0.5 -0.5 0.866 0.866 0.5 + \setchemicalrotation 3 -0.5 -0.866 -0.866 0.5 0.5 0.866 0.866 -0.5 + \setchemicalrotation 4 -1 0 0 1 1 0 0 -1 + \setchemicalrotation 5 -0.5 0.866 0.866 0.5 0.5 -0.866 -0.866 -0.5 + \setchemicalrotation 6 0.5 0.866 0.866 -0.5 -0.5 -0.866 -0.866 0.5 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 60 150 240 330 + \setchemicalangle 3 120 210 300 30 + \setchemicalangle 4 180 270 0 90 + \setchemicalangle 5 240 330 60 150 + \setchemicalangle 6 300 30 120 210 + % + \setchemicaltranslate 1 -1732 0 + \setchemicaltranslate 2 -866 1500 + \setchemicaltranslate 3 866 1500 + \setchemicaltranslate 4 1732 0 + \setchemicaltranslate 5 866 -1500 + \setchemicaltranslate 6 -866 -1500 + % + \setchemicallinesegment A 1386 500 1386 -500 + \setchemicallinesegment S 0 1000 866 -500 + \setchemicallinesegment SS 125 783 741 -283 + \setchemicallinesegment -SS 0 1000 741 -283 + \setchemicallinesegment +SS 125 783 866 -500 + \setchemicallinesegment B 866 500 866 -500 + \setchemicallinesegment SB 866 240 866 -240 + \setchemicallinesegment -SB 866 240 866 -500 + \setchemicallinesegment +SB 866 500 866 -240 + \setchemicallinesegment DB1 816 240 816 -240 + \setchemicallinesegment DB2 916 240 916 -240 + \setchemicallinesegment EB 726 340 726 -340 + \setchemicallinesegment R 866 500 1299 750 + \setchemicallinesegment -R 866 500 866 1000 + \setchemicallinesegment +R 866 500 1299 250 + \setchemicallinesegment ER1 841 543 1274 793 + \setchemicallinesegment ER2 891 457 1324 707 + \setchemicallinesegment SR 1091 630 1299 750 + \setchemicallinesegment -SR 866 740 866 1000 + \setchemicallinesegment +SR 1091 370 1299 250 + \setchemicallinesegment DR1 1066 673 1274 793 + \setchemicallinesegment DR2 1116 588 1324 707 + \setchemicallinesegment MID1 0 1000 -150 200 + \setchemicallinesegment MID2 0 -1000 -150 -200 + \setchemicallinesegment MIDS1 0 1000 -180 0 + \setchemicallinesegment MIDS2 0 -1000 -180 0 + % + \setchemicalcircsegment C -30 30 700 60 600 -346 + \setchemicalcircsegment CC -60 0 700 60 350 -606 + % + \setchemicaltextelement Z 866 500 + \setchemicaltextelement RZ 1386 800 + \setchemicaltextelement -RZ 866 1100 + \setchemicaltextelement +RZ 1386 200 + \setchemicaltextelement CRZ 1524 880 + \setchemicaltextelement MIDZ -150 0 + % + \setchemicaltextelement ZN 589 350 + \setchemicaltextelement RN 1083 625 % 1.25 Z + \setchemicaltextelement RTN 1008 755 % .12 / 130 75 + \setchemicaltextelement RBN 1158 495 + % + \def\processchemical[##1##2##3##4##5]% + {\processaction + [##1##2##3##4##5] + [ FRONT????=>{\executechemicalSIXFRONT[#1]}, + MID????=>\processchemicallinesegment{MID}{1????}, + MIDS????=>\processchemicallinesegment{MIDS}{1????}, + MIDZ????=>\processchemicaltextelement{MIDZ}{1????}{#1}{0}{}, + PB:##4##5=>\beginchemicalpicture{##4##5}, + PE????=>\endchemicalpicture, + ROT##4##5=>\processchemicalrotation{##4##5}, + SUB##4##5=>\processchemicalsubstitute{##4##5}, + ADJ##4##5=>\processchemicaldistance{##4##5}, + MOV##4##5=>\processchemicaltranslate{##4##5}, + -RZ##4##5=>\processchemicaltextelement{-RZ}{##4##5}{#1}{6} + {b,l,l,t,r,r, l,l,r,r,r,l, t,r,r,b,l,l, r,r,l,l,l,r}, + +RZ##4##5=>\processchemicaltextelement{+RZ}{##4##5}{#1}{6} + {l,t,r,r,b,l, r,r,r,l,l,l, r,b,l,l,t,r, l,l,l,r,r,r}, + -SB##4##5=>\processchemicallinesegment{-SB}{##4##5}, + +SB##4##5=>\processchemicallinesegment{+SB}{##4##5}, + -SR##4##5=>\processchemicallinesegment{-SR}{##4##5}, + +SR##4##5=>\processchemicallinesegment{+SR}{##4##5}, + -RD##4##5=>\processchemicaldashedlinesegment{-R}{##4##5}, + +RD##4##5=>\processchemicaldashedlinesegment{+R}{##4##5}, + -RB##4##5=>\processchemicaldeltalinesegment{-R}{##4##5}, + +RB##4##5=>\processchemicaldeltalinesegment{+R}{##4##5}, + CRZ##4##5=>\processchemicaltextelement{CRZ}{##4##5}{#1}{0}{}, + -SS##4##5=>\processchemicallinesegment{-SS}{##4##5}, + +SS##4##5=>\processchemicallinesegment{+SS}{##4##5}, + CCD##4##5=>\processchemicaldottsegment{CC}{##4##5}, +RTN##4##5=>\processchemicaltextconstant{RTN}{##4##5}{\chemicaltextelementnumber}{0}, +RTT##4##5=>\processchemicaltextelement{RTN}{##4##5}{#1}{0}{}, +RBN##4##5=>\processchemicaltextconstant{RBN}{##4##5}{\chemicaltextelementnumber}{0}, +RBT##4##5=>\processchemicaltextelement{RBN}{##4##5}{#1}{0}{}, + SS##3##4##5=>\processchemicallinesegment{SS}{##3##4##5}, + RD##3##4##5=>\processchemicaldashedlinesegment{R}{##3##4##5}, + RB##3##4##5=>\processchemicaldeltalinesegment{R}{##3##4##5}, + ZN##3##4##5=>\processchemicaltextconstant{ZN}{##3##4##5}{\chemicaltextelementnumber}{0}, + ZT##3##4##5=>\processchemicaltextelement{ZN}{##3##4##5}{#1}{0}{}, +RN##3##4##5=>\processchemicaltextconstant{RN}{##3##4##5}{\chemicaltextelementnumber}{0}, +RT##3##4##5=>\processchemicaltextelement{RN}{##3##4##5}{#1}{0}{}, + AU##3##4##5=>\processchemicaluparrowsegment{A}{##3##4##5}, + AD##3##4##5=>\processchemicaldownarrowsegment{A}{##3##4##5}, + CD##3##4##5=>\processchemicaldottsegment{C}{##3##4##5}, + CC##3##4##5=>\processchemicalcircsegment{CC}{##3##4##5}, + DB##3##4##5=>\processchemicallinesegment{DB}{##3##4##5}, + EB##3##4##5=>\processchemicallinesegment{EB}{##3##4##5}, + ER##3##4##5=>\processchemicallinesegment{ER}{##3##4##5}, + RZ##3##4##5=>\processchemicaltextelement{RZ}{##3##4##5}{#1}{6} + {l,l,t,r,r,b, l,r,r,r,l,l, r,r,b,l,l,t, r,l,l,l,r,r}, + SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, + SR##3##4##5=>\processchemicallinesegment{SR}{##3##4##5}, + DR##3##4##5=>\processchemicallinesegment{DR}{##3##4##5}, + -R##3##4##5=>\processchemicallinesegment{-R}{##3##4##5}, + +R##3##4##5=>\processchemicallinesegment{+R}{##3##4##5}, + B##2##3##4##5=>\processchemicallinesegment{B}{##2##3##4##5}, + C##2##3##4##5=>\processchemicalcircsegment{C}{##2##3##4##5}, + R##2##3##4##5=>\processchemicallinesegment{R}{##2##3##4##5}, + S##2##3##4##5=>\processchemicallinesegment{S}{##2##3##4##5}, + Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} + +\def\executechemicalSEVEN[#1]% incomplete ! + {\setchemicalname SEVEN + % + \setchemicalmaximum 7 + \setchemicalsubstitute - + \setchemicaldistance 1038 + % + \setchemicalrotation 1 .623 .782 - - - - - - + \setchemicalrotation 2 -.223 .975 - - - - - - + \setchemicalrotation 3 -.901 .434 - - - - - - + \setchemicalrotation 4 -.901 -.434 - - - - - - + \setchemicalrotation 5 -.223 -.975 - - - - - - + \setchemicalrotation 6 .623 -.782 - - - - - - + \setchemicalrotation 7 1 0 - - - - - - + % + \setchemicalangle 1 0 - - - + \setchemicalangle 2 51.429 - - - + \setchemicalangle 3 102.857 - - - + \setchemicalangle 4 154.286 - - - + \setchemicalangle 5 205.714 - - - + \setchemicalangle 6 257.143 - - - + \setchemicalangle 7 308.571 - - - + % + \setchemicaltranslate 1 - - + \setchemicaltranslate 2 - - + \setchemicaltranslate 3 - - + \setchemicaltranslate 4 - - + \setchemicaltranslate 5 - - + \setchemicaltranslate 6 - - + \setchemicaltranslate 7 - - + % + \setchemicallinesegment B 1038 500 1038 -500 + \setchemicallinesegment SB 1038 240 1038 -240 + \setchemicallinesegment -SB 1038 240 1038 -500 + \setchemicallinesegment +SB 1038 500 1038 -240 + % + \setchemicaltextelement Z 1038 500 + % + \def\processchemical[##1##2##3##4##5]% + {\processaction + [##1##2##3##4##5] + [ PB:##4##5=>\beginchemicalpicture{##4##5}, + PE????=>\endchemicalpicture, + %ROT##4##5=>\processchemicalrotation{##4}, + %SUB##4##5=>\processchemicalsubstitute{##4##5}, + %ADJ##4##5=>\processchemicaldistance{##4##5}, + %MOV##4##5=>\processchemicaltranslate{##4##5}, + -SB##4##5=>\processchemicallinesegment{-SB}{##4##5}, + +SB##4##5=>\processchemicallinesegment{+SB}{##4##5}, + SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, + B##2##3##4##5=>\processchemicallinesegment{B}{##2##3##4##5}, + Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} + +\def\executechemicalEIGHT[#1]% incomplete ! + {\setchemicalname EIGHT + % + \setchemicalmaximum 8 + %\setchemicalsubstitute 1307 + \setchemicaldistance 1207 + % + \setchemicalrotation 1 .707 .707 - - - - - - + \setchemicalrotation 2 0 1 - - - - - - + \setchemicalrotation 3 -.707 .707 - - - - - - + \setchemicalrotation 4 -1 0 - - - - - - + \setchemicalrotation 5 -.707 -.707 - - - - - - + \setchemicalrotation 6 0 -1 - - - - - - + \setchemicalrotation 7 .707 -.707 - - - - - - + \setchemicalrotation 8 1 0 - - - - - - + % + \setchemicalangle 1 45 - - - + \setchemicalangle 2 90 - - - + \setchemicalangle 3 135 - - - + \setchemicalangle 4 180 - - - + \setchemicalangle 5 225 - - - + \setchemicalangle 6 270 - - - + \setchemicalangle 7 315 - - - + \setchemicalangle 8 0 - - - + % + \setchemicaltranslate 1 -2414 0 + \setchemicaltranslate 2 -1706 1706 + \setchemicaltranslate 3 0 2414 + \setchemicaltranslate 4 1706 1706 + \setchemicaltranslate 5 2414 0 + \setchemicaltranslate 6 1706 -1706 + \setchemicaltranslate 7 0 -2414 + \setchemicaltranslate 8 -1706 -1706 + % + \setchemicallinesegment B 1207 500 1207 -500 + \setchemicallinesegment SB 1207 240 1207 -240 + \setchemicallinesegment -SB 1207 240 1207 -500 + \setchemicallinesegment +SB 1207 500 1207 -240 + % + \setchemicaltextelement Z 1207 500 + % + \def\processchemical[##1##2##3##4##5]% + {\processaction + [##1##2##3##4##5] + [ PB:##4##5=>\beginchemicalpicture{##4##5}, + PE????=>\endchemicalpicture, + %SUB##4##5=>\processchemicalsubstitute{##4##5}, + ADJ##4##5=>\processchemicaldistance{##4##5}, + MOV##4##5=>\processchemicaltranslate{##4##5}, + -SB##4##5=>\processchemicallinesegment{-SB}{##4##5}, + +SB##4##5=>\processchemicallinesegment{+SB}{##4##5}, + SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, + B##2##3##4##5=>\processchemicallinesegment{B}{##2##3##4##5}, + Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} + +\def\executechemicalFIVEFRONT[#1]% + {\executechemicalFIVE[]% + % + \setchemicalname FIVEFRONT + % + \setchemicallinesegment -R 688 500 688 100 + \setchemicallinesegment +R 688 500 688 900 + % + \setchemicaltextelement -RZ 0 -1300 + \setchemicaltextelement +RZ 0 1300 + % + \def\processchemical[##1##2##3##4]% + {\def\chemicalrotation{2}% + \processaction + [##1##2##3##4] + [ -RZ##4=>\processchemicalunrotatedtextelement{Z}{-RZ}{##4}{#1}{5} + {,,,,, t,t,t,t,t}, + +RZ##4=>\processchemicalunrotatedtextelement{Z}{+RZ}{##4}{#1}{5} + {,,,,, b,b,b,b,b}, + -SB##4=>\processchemicallinesegment{-SB}{##4}, + +SB##4=>\processchemicallinesegment{+SB}{##4}, + SB##3##4=>\processchemicallinesegment{SB}{##3##4}, + -R##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##3##4}, + +R##3##4=>\processchemicalunrotatedlinesegment{b}{+R}{##3##4}, + BB##3##4=>\processchemicalzlinesegment{B}{##3##4}, + R##2##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##2##3##4}% + \processchemicalunrotatedlinesegment{b}{+R}{##2##3##4}, + B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, + Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +\def\executechemicalSIXFRONT[#1]% + {\executechemicalSIX[]% + % + \setchemicalname SIXFRONT + % + \setchemicallinesegment -R 866 500 866 100 + \setchemicallinesegment +R 866 500 866 900 + % + \setchemicaltextelement -RZ 0 -1300 + \setchemicaltextelement +RZ 0 1300 + % + \def\processchemical[##1##2##3##4]% + {\def\chemicalrotation{2}% + \processaction + [##1##2##3##4] + [ -RZ##4=>\processchemicalunrotatedtextelement{Z}{-RZ}{##4}{#1}{6} + {,,,,,, t,t,t,t,t,t}, + +RZ##4=>\processchemicalunrotatedtextelement{Z}{+RZ}{##4}{#1}{6} + {,,,,,, b,b,b,b,b,b}, + -SB##4=>\processchemicallinesegment{-SB}{##4}, + +SB##4=>\processchemicallinesegment{+SB}{##4}, + SB##3##4=>\processchemicallinesegment{SB}{##3##4}, + -R##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##3##4}, + +R##3##4=>\processchemicalunrotatedlinesegment{b}{+R}{##3##4}, + BB##3##4=>\processchemicalzlinesegment{B}{##3##4}, + R##2##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##2##3##4}% + \processchemicalunrotatedlinesegment{b}{+R}{##2##3##4}, + B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, + Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +% 1 : 0 +% 2 : -115 +% 3* : -195 +% 3 : -165 +% 4 : -245 + +\def\executechemicalCARBON[#1]% + {\setchemicalname CARBON + % + \setchemicalmaximum 4 + \setchemicaldistance 0 + \setchemicalsubstitute 0 + % + \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 + \setchemicalrotation 2 -0.423 -0.906 -0.906 0.423 0.423 0.906 0.906 -0.423 + \setchemicalrotation 3 -0.966 -0.259 -0.259 0.966 0.966 0.259 0.259 -0.966 + \setchemicalrotation 3* -0.966 0.259 0.259 0.966 0.966 -0.259 -0.259 -0.966 + \setchemicalrotation 4 -0.423 0.906 0.906 0.423 0.423 -0.906 -0.906 -0.423 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 115 205 295 25 + \setchemicalangle 3 165 255 345 75 + \setchemicalangle 3* 195 285 15 105 + \setchemicalangle 4 245 335 65 155 + % + \setchemicaltranslate 1 -1500 0 + \setchemicaltranslate 2 0 1500 + \setchemicaltranslate 3 1500 0 + \setchemicaltranslate 4 0 -1500 + % + \setchemicallinesegment B1 500 0 1000 0 + \setchemicallinesegment B2 300 0 1000 0 + \setchemicallinesegment B3 500 0 1000 0 + \setchemicallinesegment B4 300 0 1000 0 + % + \setchemicaltextelement Z 1100 0 + % + \setchemicalcircsegment C 0 360 500 360 0 -500 + % + \def\processchemical[##1##2##3##4##5]% + {\processaction + [##1##2##3##4##5] + [ MIR????=>\setchemicalmirror{3}, + -MIR????=>\resetchemicalmirror{3}, + *MIR????=>\togglechemicalmirror{3}, + CB????=>\processlocalchemicals{B,C,Z}, + C????=>\processchemicalcircsegment{C}{1????}, + -ROT##5=>\reversechemical{ROT}{##5}{3,4,1,2}, + ROT##4##5=>\processchemicalrotation{##4##5}, + MOV##4##5=>\processchemicaltranslate{##4##5}, + CB##3##4##5=>\processlocalchemicals + {ROT##3,C,B,Z2..4, + MOV##3,*MIR,-ROT##3,C,B,Z2..4}, + B##2##3##4##5=>\processprivatechemicallinesegment{B}{##2##3##4##5}, + Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{4} + {l,t,r,b, t,r,b,l, r,b,l,t, b,l,t,r}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} + +% 1: 45 2: -90 3: -225 +% 4: -45 5: -135 6: -270 + +\newif\ifNEWMANstagger \NEWMANstaggertrue + +\def\executechemicalNEWMANSTAGGER% + {\NEWMANstaggertrue\executechemicalNEWMAN} + +\def\executechemicalNEWMANECLIPSE% + {\NEWMANstaggerfalse\executechemicalNEWMAN} + +\def\executechemicalNEWMAN[#1]% + {\setchemicalname NEWMAN + % + \setchemicalmaximum 6 + \setchemicaldistance 0 + \setchemicalsubstitute 0 + % + \ifNEWMANstagger + \setchemicalrotation 1 0.707 0.707 0.707 -0.707 -0.707 -0.707 -0.707 0.707 + \setchemicalrotation 2 0 -1 -1 0 0 1 1 0 + \setchemicalrotation 3 -0.707 0.707 0.707 0.707 0.707 -0.707 -0.707 -0.707 + \else + \setchemicalrotation 1 .866 -.5 -.5 -.866 -.866 .5 .5 .866 + \setchemicalrotation 2 -.259 .966 .966 .259 .259 -.966 -.966 -.259 + \setchemicalrotation 3 -.5 -.866 -.866 .5 .5 .866 .866 -.5 + \fi + \setchemicalrotation 4 0.707 -0.707 -0.707 -0.707 -0.707 0.707 0.707 0.707 + \setchemicalrotation 5 -0.707 -0.707 -0.707 0.707 0.707 0.707 0.707 -0.707 + \setchemicalrotation 6 0 1 1 0 0 -1 -1 0 + % + \ifNEWMANstagger + \setchemicalangle 1 315 45 135 225 + \setchemicalangle 2 90 180 270 0 + \setchemicalangle 3 225 315 45 135 + \else + \setchemicalangle 1 30 120 210 300 + \setchemicalangle 2 255 345 75 165 + \setchemicalangle 3 120 210 300 30 + \fi + \setchemicalangle 4 45 135 225 315 + \setchemicalangle 5 135 225 315 45 + \setchemicalangle 6 270 0 90 180 + % + \setchemicaltranslate 1 -1500 0 + \setchemicaltranslate 2 0 1500 + \setchemicaltranslate 3 1500 0 + \setchemicaltranslate 4 0 -1500 + % + \setchemicallinesegment B1 0 0 1000 0 + \setchemicallinesegment B2 0 0 1000 0 + \setchemicallinesegment B3 0 0 1000 0 + \setchemicallinesegment B4 500 0 1000 0 + \setchemicallinesegment B5 500 0 1000 0 + \setchemicallinesegment B6 500 0 1000 0 + % + \setchemicaltextelement Z 1100 0 + % + \setchemicalcircsegment C 0 360 500 360 0 -500 + % + \def\processchemical[##1##2##3##4]% + {\processaction + [##1##2##3##4] + [STAGGER????=>{\executechemicalNEWMANSTAGGER[#1]}, + ECLIPSE????=>{\executechemicalNEWMANECLIPSE[#1]}, + B????=>\processlocalchemicals{B1..6}, + CB????=>\processlocalchemicals{B1..6,C,Z1..6}, + C????=>\processchemicalcircsegment{C}{1????}, + ROT##4=>\processchemicalrotation{##4}, + MOV##4=>\processchemicaltranslate{##4}, + B##2##3##4=>\processprivatechemicallinesegment{B}{##2##3##4}, + Z##2##3##4=>\ifNEWMANstagger + \processchemicaltextelement{Z}{##2##3##4}{#1}{6} + {l,t,r,l,r,b, l,r,l,r,r,l, r,b,l,r,l,t, r,l,r,l,l,r}% + \else + \processchemicaltextelement{Z}{##2##3##4}{#1}{6} + {l,r,t,t,r,b, t,b,r,r,b,l, r,l,b,b,l,t, b,t,l,l,t,r}% + \fi, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +\def\executechemicalCHAIR[#1]% smaller + {\setchemicalname CHAIR + % + \setchemicalmaximum 6 + % + \setchemicallinesegment B1 1600 800 2800 -800 + \setchemicallinesegment B2 2800 -800 800 0 + \setchemicallinesegment B3 800 0 -1600 -800 + \setchemicallinesegment B4 -1600 -800 -2800 800 + \setchemicallinesegment B5 -2800 800 -800 0 + \setchemicallinesegment B6 -800 0 1600 800 + % + \setchemicallinesegment +R1 1600 800 1600 1600 + \setchemicallinesegment +R2 2800 -800 2800 -1600 + \setchemicallinesegment +R3 800 0 800 800 + \setchemicallinesegment +R4 -1600 -800 -1600 -1600 + \setchemicallinesegment +R5 -2800 800 -2800 1600 + \setchemicallinesegment +R6 -800 0 -800 -800 + % + \setchemicallinesegment -R1 1600 800 2350 522 % 750 278 + \setchemicallinesegment -R2 2800 -800 3493 -400 + \setchemicallinesegment -R3 800 0 1329 -600 % 528 600 + \setchemicallinesegment -R4 -1600 -800 -2350 -522 % 750 278 + \setchemicallinesegment -R5 -2800 800 -3493 400 + \setchemicallinesegment -R6 -800 0 -1329 600 % 528 600 + % + \setchemicaltextelement +RZ1 1600 1800 + \setchemicaltextelement +RZ2 2800 -1800 + \setchemicaltextelement +RZ3 800 1000 + \setchemicaltextelement +RZ4 -1600 -1800 + \setchemicaltextelement +RZ5 -2800 1800 + \setchemicaltextelement +RZ6 -800 -1000 + % + \setchemicaltextelement -RZ1 2538 453 % 200 lang + \setchemicaltextelement -RZ2 3666 -300 + \setchemicaltextelement -RZ3 1460 -750 + \setchemicaltextelement -RZ4 -2538 -453 + \setchemicaltextelement -RZ5 -3666 300 + \setchemicaltextelement -RZ6 -1460 750 + % + \def\processchemical[##1##2##3##4##5]% + {\def\chemicalrotation{1}% + \processaction + [##1##2##3##4##5] + [ B????=>\processlocalchemicals{B1,B2,B3,B4,B5,B6}, + -R????=>\processlocalchemicals{-R1,-R2,-R3,-R4,-R5,-R6}, + +R????=>\processlocalchemicals{+R1,+R2,+R3,+R4,+R5,+R6}, + B##2????=>{\getchemicallinesegment[0][B##2]}, + -RZ##4????=>{\getchemicalfixedtextelement[-RZ##4][1][##4][l,l,tc,r,r,bc][#1]}, + +RZ##4????=>{\getchemicalfixedtextelement[+RZ##4][1][##4][c][#1]}, + -R##3????=>{\getchemicallinesegment[0][-R##3]}, + +R##3????=>{\getchemicallinesegment[0][+R##3]}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} + +\def\executechemicalarrow#1#2[#3]% + {\dogetcommalistelement1\from#3\to\toptext + \dogetcommalistelement2\from#3\to\bottext + \def\dochemicaltext##1% + {\dosetsubscripts% + $\@@dochemicalstyle{\@@localchemicalformat\strut##1}$% + \doresetsubscripts}% + \doifelse\@@chemicallocation\v!intext + {#1{\dochemicaltext\toptext}}% + {\setbox\chemicalsymbols=\hbox + {\box\chemicalsymbols + \vbox{\halign{##\cr + \hbox to 3em{\hss\dochemicaltext{\toptext}\hss}\cr + #2% + \hbox to 3em{\hss\dochemicaltext{\bottext}\hss}\cr}}}}} + +\def\executechemicalGIVES + {\executechemicalarrow + {\chemicalsinglepicturearrow}% nodig + {\rightarrowfill\cr}} + +\def\executechemicalEQUILIBRIUM + {\executechemicalarrow + {\chemicaldoublepicturearrow}% nodig + {\rightarrowfill\cr\leftarrowfill\cr}} + +\def\executechemicalMESOMERIC + {\executechemicalarrow + {\chemicalsinglepicturearrow}% nodig + {$\leftarrow\hskip-1em$\rightarrowfill\cr}} + +\def\executechemicalsign#1[#2]% + {\doifelse\@@chemicallocation\v!intext + {\dosetsubscripts + $\@@dochemicalstyle{\@@localchemicalformat#1}$% + \doresetsubscripts} + {\setbox\chemicalsymbols\hbox + {\box\chemicalsymbols + \dosetsubscripts + $\@@dochemicalstyle{\@@localchemicalformat#1}$% + \doresetsubscripts}}} + +\def\executechemicalPLUS + {\executechemicalsign{+}} + +\def\executechemicalMINUS + {\executechemicalsign{-}} + +\def\executechemicalEQUAL + {\executechemicalsign{=}} + +\def\executechemicalSPACE[#1]% + {\doifnot\@@chemicallocation\v!intext + {\setbox\chemicalsymbols\hbox + {\box\chemicalsymbols + \quad}}} + +\def\executechemicalCHEM[#1]% + {\doifnot\@@chemicallocation\v!intext + {\setbox\chemicalsymbols\hbox + {\box\chemicalsymbols + $\@@dochemicalstyle{\@@localchemicalformat#1}$}}} + +\def\executechemicalTEXT[#1]% + {\doifnot\@@chemicallocation\v!intext + {\setbox\chemicalsymbols\hbox + {\box\chemicalsymbols#1}}} + +%\def\executechemicalLOW[#1]% +% {\setlowsubscripts} +% +%\def\executechemicalHIGH[#1]% +% {\sethighsubscripts} + +\def\putchemicalrule#1#2#3#4% + {\ifcase\chemicaldrawingmode + \putrule from {#1} {#2} to {#3} {#4} + \or + \psline(#1,#2)(#3,#4)% + \or + \bgroup + \!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + x1 := \MPdivten[\the\!!counta]u ; + y1 := \MPdivten[\the\!!countb]u ; + x2 := \MPdivten[\the\!!countc]u ; + y2 := \MPdivten[\the\!!countd]u ; + draw z1--z2 ; + \stopMPdrawing + \egroup + \fi} + +\def\executechemicalcomplex#1% + {\bgroup + \putchemicalrule {0} {-\@@chemicalbottom} {0} {\@@chemicaltop}% + \putchemicalrule {0} {\@@chemicaltop} {#1150} {\@@chemicaltop}% + \putchemicalrule {0} {-\@@chemicalbottom} {#1150} {-\@@chemicalbottom}% + \egroup} + +\def\executechemicalOPENCOMPLEX[#1]% + {\executechemicalcomplex+\ignorespaces + \executechemicalSPACE[]} + +\def\executechemicalCLOSECOMPLEX[#1]% + {\executechemicalSPACE[]% + \executechemicalcomplex-\ignorespaces} + +% nog niet door midden as! + +\def\executechemicalverticalsymbol#1#2% + {\executechemicalTEXT + [$\left#1\relax + \dimen0=\@@chemicalunit + \scratchcounter=\@@chemicaltop + \advance\scratchcounter by \@@chemicalbottom + \dimen0=\scratchcounter\dimen0 + \vcenter to \dimen0{} + \dimen2=\@@chemicalunit + \dimen2=\@@chemicalright\dimen0 + \vcenter{\leftskip1em\hsize\dimen2\relax\strut#2\strut}% + \right.$]}% + +\def\executechemicalUPARROW[#1]% + {\executechemicalverticalsymbol\uparrow{#1}} + +\def\executechemicalDOWNARROW[#1]% + {\executechemicalverticalsymbol\downarrow{#1}} + +\def\executechemicalUPDOWNARROW[#1]% + {\executechemicalverticalsymbol\updownarrow{#1}} + +\let\setchemicalattributes\relax + +\setupchemical + [\c!width=0, + \c!height=0, + \c!left=0, + \c!right=0, + \c!top=0, + \c!bottom=0, + \c!bodyfont=\the\bodyfontsize, + \c!resolution=\outputresolution, + \c!scale=\v!medium, + \c!size=\v!medium, + \c!textsize=\v!big, + \c!frame=\v!off, + \c!axis=\v!off, + \c!state=\v!start, + \c!style=\rm, + \c!location=, + \c!option=, + \c!offset=LOW, + \c!alternative=1, + \c!color=, + \c!rulethickness=, + \c!rulecolor=, + \c!factor=1] + +% Tijdelijk plaatsen we deze extra macro's hier. +% +% mathontop: \mtop {} {} +% textontop: \ttop {} {} + +\def\putontop#1#2% + {\vbox + {\halign + {\strut\hss##\hss\cr + #1\cr + #2\cr}}} + +\def\ttop#1#2% + {\putontop{\tx#1}{#2}} + +\def\mtop#1#2% + {\vbox + {\offinterlineskip + \halign + {\hss##\hss\cr + $\scriptscriptstyle#1$\cr + \noalign{\vskip.5ex}% + $#2$\cr}}} + +\def\ctop#1#2% + {\vbox + {\offinterlineskip + \halign + {\hss##\hss\cr + $\@@dochemicalstyle{\@@localchemicalformat\scriptscriptstyle#1}$\cr + \noalign{\vskip.5ex}% + $\@@dochemicalstyle{\@@localchemicalformat#2}$\cr}}} + +%D Here are a couple of 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/pret-lua.lua b/tex/context/base/pret-lua.lua new file mode 100644 index 000000000..8803971f3 --- /dev/null +++ b/tex/context/base/pret-lua.lua @@ -0,0 +1,319 @@ +if not modules then modules = { } end modules ['pret-lua'] = { + version = 1.001, + comment = "companion to buff-ver.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- this is not a real parser as we also want to typeset wrong output +-- and a real parser would choke on that + +local utf = unicode.utf8 + +local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues +local utfbyte, utffind = utf.byte, utf.find +local byte, sub, find, match = string.byte, string.sub, string.find, string.match +local texsprint, texwrite = tex.sprint, tex.write +local ctxcatcodes = tex.ctxcatcodes + +local visualizer = buffers.newvisualizer("lua") + +visualizer.identifiers = { } + +-- borrowed from scite +-- +-- depricated: +-- +-- gcinfo unpack getfenv setfenv loadlib +-- table.maxn table.getn table.setn +-- math.log10 math.mod math.modf math.fmod + +visualizer.identifiers.core = { + "and", "break", "do", "else", "elseif", "end", "false", "for", "function", + "if", "in", "local", "nil", "not", "or", "repeat", "return", "then", + "true", "until", "while" +} + +visualizer.identifiers.base = { + "assert", "collectgarbage", "dofile", "error", "loadfile", + "loadstring", "print", "rawget", "rawset", "require", "tonumber", + "tostring", "type", +} + +visualizer.identifiers.five = { + "_G", "getmetatable", "ipairs", "next", "pairs", + "pcall", "rawequal", "setmetatable", "xpcall", "string", "table", + "math", "coroutine", "io", "os", "debug", "load", "module", "select", +} + +visualizer.identifiers.libs = { + -- coroutine + "coroutine.create", "coroutine.resume", "coroutine.status", "coroutine.wrap", + "coroutine.yield", "coroutine.running", + -- package + "package.cpath", "package.loaded", "package.loadlib", "package.path", "package.config", + -- io + "io.close", "io.flush", "io.input", "io.lines", "io.open", "io.output", + "io.read", "io.tmpfile", "io.type", "io.write", "io.stdin", "io.stdout", + "io.stderr", "io.popen", + -- math + "math.abs", "math.acos", "math.asin", "math.atan", "math.atan2", "math.ceil", + "math.cos", "math.deg", "math.exp", "math.floor math.", "math.ldexp", + "math.log", "math.max", "math.min", "math.pi", "math.pow", + "math.rad", "math.random", "math.randomseed", "math.sin", "math.sqrt", + "math.tan", "math.cosh", "math.sinh", "math.tanh", + "math.huge", + -- string + "string.byte", "string.char", "string.dump", "string.find", "string.len", + "string.lower", "string.rep", "string.sub", "string.upper", "string.format", + "string.gfind", "string.gsub", "string.gmatch", "string.match", "string.reverse", + -- table + "table.concat", "table.foreach", "table.foreachi", + "table.sort", "table.insert", "table.remove", + "table.pack", "table.unpack", + -- os + "os.clock", "os.date", "os.difftime", "os.execute", "os.exit", "os.getenv", + "os.remove", "os.rename", "os.setlocale", "os.time", "os.tmpname", + -- package + "package.preload", "package.seeall", + -- bit + -- ... todo ... +} + +local known_words = { } + +for k,v in next, visualizer.identifiers do + for _,w in next, v do + known_words[w] = k + end +end + +visualizer.styles = { + core = "", + base = "\\sl ", + five = "\\sl ", + libs = "\\sl ", +} + +local styles = visualizer.styles + +local colors = { + "prettyone", + "prettytwo", + "prettythree", + "prettyfour", +} + +local states = { + ['"']=1, ["'"]=1, ["[["] = 1, ["]]"] = 1, + ['+']=1, ['-']=1, ['*']=1, ['/']=1, ['%']=1, ['^']=1, + ["("] = 3, [")"] = 3, ["["] = 3, ["]"] = 3, + ['--']=4, +} + +local change_state, finish_state = buffers.change_state, buffers.finish_state + +local function flush_lua_word(state, word) + if word then + local id = known_words[word] + if id then + state = change_state(2,state) + if styles[id] then + texsprint(ctxcatcodes,styles[id]) + end + texwrite(word) + state = finish_state(state) + else + state = finish_state(state) -- ? + texwrite(word) + end + else + state = finish_state(state) + end + return state +end + +local incomment, inlongstring = false, false + +function visualizer.reset() + incomment, inlongstring = false, false -- needs to be hooked into flusher +end + +-- we will also provide a proper parser based pretty printer although normaly +-- a pretty printer should handle faulty code too (educational purposes) + +local function written(state,c,i) + if c == " " then + state = finish_state(state) + texsprint(ctxcatcodes,"\\obs") + elseif c == "\t" then + state = finish_state(state) + texsprint(ctxcatcodes,"\\obs") + if buffers.visualizers.enabletab then + texsprint(ctxcatcodes,rep("\\obs ",i%buffers.visualizers.tablength)) + end + else + texwrite(c) + end + return state, 0 +end + +function visualizer.flush_line(str, nested) + local state, instr, inesc, word = 0, false, false, nil + buffers.currentcolors = colors + local code, comment = match(str,"^(.-)%-%-%[%[(.*)$") + if comment then + -- process the code and then flush the comment + elseif incomment then + comment, code = match(str,"^(.-)%]%](.*)$") + if comment then + -- flush the comment and then process the code + for c in utfcharacters(comment) do + if c == " " then texsprint(ctxcatcodes,"\\obs") else texwrite(c) end + end + state = change_state(states['--'], state) + texwrite("]]") + state = finish_state(state) + incomment = false + else + for c in utfcharacters(str) do + if c == " " then texsprint(ctxcatcodes,"\\obs") else texwrite(c) end + end + end + comment = nil + else + code = str + end + if code and code ~= "" then + local pre, post = match(code,"^(.-)%-%-(.*)$") + if pre then + code = pre + end + local p, s, i = nil, nil, 0 + for c in utfcharacters(code) do + i = i + 1 + if instr then + if p then + texwrite(p) + p = nil + end + if c == s then + if inesc then + texwrite(c) + inesc = false + else + state = change_state(states[c],state) + instr = false + texwrite(c) + state = finish_state(state) + end + s = nil + else + if c == "\\" then + inesc = not inesc + else + inesc = false + end + state, i = written(state,c,i) + end + elseif c == "[" then + if word then + texwrite(word) + word = nil + end + if p == "[" then + inlongstring = true + state = change_state(states["[["],state) + texwrite(p,c) + state = finish_state(state) + p = nil + else + if p then + state, i = written(state,p,i) + end + p = c + end + elseif c == "]" then + if word then + texwrite(word) + word = nil + end + if p == "]" then + inlongstring = false + state = change_state(states["]]"],state) + texwrite(p,c) + state = finish_state(state) + p = nil + else + if p then + state, i = written(state,p,i) + end + p = c + end + else + if p then + state = change_state(states[p],state) + texwrite(p) + state = finish_state(state) + p = nil + end + if c == " " or c == "\t" then + if word then + state = flush_lua_word(state,word) + word = nil + end + state, i = written(state,c,i) + elseif inlongstring then + state, i = written(state,c,i) + elseif c == '"' or c == "'" then +if word then + state = flush_lua_word(state,word) + word = nil +end + instr = true + state = change_state(states[c],state) + state, i = written(state,c,i) + state = finish_state(state) + s = c + elseif find(c,"^[%a]$") then + state = finish_state(state) + if word then word = word .. c else word = c end + elseif word and (#word > 1) and find(c,"^[%d%.%_]$") then + if word then word = word .. c else word = c end + else + state = flush_lua_word(state,word) + word = nil + state = change_state(states[c],state) + texwrite(c) + instr = (c == '"') + end + end + end + if p then + texwrite(p) + -- state, i = written(state,p,i) + p = nil + end + state = flush_lua_word(state,word) + if post then + state = change_state(states['--'], state) + texwrite("--") + state = finish_state(state) + for c in utfcharacters(post) do + state, i = written(state,c,i) + end + end + end + if comment then + incomment = true + state = change_state(states['--'], state) + texwrite("[[") + state = finish_state(state) + -- texwrite(comment) -- maybe also split and + for c in utfcharacters(comment) do + state, i = written(state,c,i) + end + end + state = finish_state(state) +end diff --git a/tex/context/base/pret-mp.lua b/tex/context/base/pret-mp.lua new file mode 100644 index 000000000..782adf5f5 --- /dev/null +++ b/tex/context/base/pret-mp.lua @@ -0,0 +1,236 @@ +if not modules then modules = { } end modules ['pret-mp'] = { + version = 1.001, + comment = "companion to buff-ver.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local utf = unicode.utf8 + +local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues +local utfbyte, utffind = utf.byte, utf.find +local texsprint, texwrite = tex.sprint, tex.write +local ctxcatcodes = tex.ctxcatcodes + +local visualizer = buffers.newvisualizer("mp") + +visualizer.identifiers = { } + +visualizer.identifiers.primitives = { + 'charcode', 'day', 'linecap', 'linejoin', 'miterlimit', 'month', 'pausing', + 'prologues', 'showstopping', 'time', 'tracingcapsules', 'tracingchoices', + 'tracingcommands', 'tracingequations', 'tracinglostchars', + 'tracingmacros', 'tracingonline', 'tracingoutput', 'tracingrestores', + 'tracingspecs', 'tracingstats', 'tracingtitles', 'truecorners', + 'warningcheck', 'year', 'mpprocset', + 'false', 'nullpicture', 'pencircle', 'true', + 'and', 'angle', 'arclength', 'arctime', 'ASCII', 'bluepart', 'boolean', 'bot', + 'char', 'color', 'cosd', 'cycle', 'decimal', 'directiontime', 'floor', 'fontsize', + 'greenpart', 'hex', 'infont', 'intersectiontimes', 'known', 'length', 'llcorner', + 'lrcorner', 'makepath', 'makepen', 'mexp', 'mlog', 'normaldeviate', 'not', + 'numeric', 'oct', 'odd', 'or', 'path', 'pair', 'pen', 'penoffset', 'picture', 'point', + 'postcontrol', 'precontrol', 'redpart', 'reverse', 'rotated', 'scaled', + 'shifted', 'sind', 'slanted', 'sqrt', 'str', 'string', 'subpath', 'substring', + 'transform', 'transformed', 'ulcorner', 'uniformdeviate', 'unknown', + 'urcorner', 'xpart', 'xscaled', 'xxpart', 'xypart', 'ypart', 'yscaled', 'yxpart', + 'yypart', 'zscaled', + 'addto', 'clip', 'input', 'interim', 'let', 'newinternal', 'save', 'setbounds', + 'shipout', 'show', 'showdependencies', 'showtoken', 'showvariable', + 'special', + 'begingroup', 'endgroup', 'of', 'curl', 'tension', 'and', 'controls', + 'reflectedabout', 'rotatedaround', 'interpath', 'on', 'off', 'beginfig', + 'endfig', 'def', 'vardef', 'enddef', 'epxr', 'suffix', 'text', 'primary', 'secondary', + 'tertiary', 'primarydef', 'secondarydef', 'tertiarydef', 'top', 'bottom', + 'ulft', 'urt', 'llft', 'lrt', 'randomseed', 'also', 'contour', 'doublepath', + 'withcolor', 'withpen', 'dashed', 'if', 'else', 'elseif', 'fi', 'for', 'endfor', 'forever', 'exitif', + 'forsuffixes', 'downto', 'upto', 'step', 'until', + 'charlist', 'extensible', 'fontdimen', 'headerbyte', 'kern', 'ligtable', + 'boundarychar', 'chardp', 'charext', 'charht', 'charic', 'charwd', 'designsize', + 'fontmaking', 'charexists', + 'cullit', 'currenttransform', 'gfcorners', 'grayfont', 'hround', + 'imagerules', 'lowres_fix', 'nodisplays', 'notransforms', 'openit', + 'displaying', 'currentwindow', 'screen_rows', 'screen_cols', + 'pixels_per_inch', 'cull', 'display', 'openwindow', 'numspecial', + 'totalweight', 'autorounding', 'fillin', 'proofing', 'tracingpens', + 'xoffset', 'chardx', 'granularity', 'smoothing', 'turningcheck', 'yoffset', + 'chardy', 'hppp', 'tracingedges', 'vppp', + 'extra_beginfig', 'extra_endfig', 'mpxbreak', + 'end', 'btex', 'etex', 'verbatimtex' +} + +visualizer.identifiers.plain = { + 'ahangle', 'ahlength', 'bboxmargin', 'defaultpen', 'defaultscale', + 'labeloffset', 'background', 'currentpen', 'currentpicture', 'cuttings', + 'defaultfont', 'extra_beginfig', 'extra_endfig', + 'beveled', 'black', 'blue', 'bp', 'butt', 'cc', 'cm', 'dd', 'ditto', 'down', 'epsilon', + 'evenly', 'fullcircle', 'green', 'halfcircle', 'identity', 'in', 'infinity', 'left', + 'mitered', 'mm', 'origin', 'pensquare', 'pt', 'quartercircle', 'red', 'right', + 'rounded', 'squared', 'unitsquare', 'up', 'white', 'withdots', + 'abs', 'bbox', 'ceiling', 'center', 'cutafter', 'cutbefore', 'dir', + 'directionpoint', 'div', 'dotprod', 'intersectionpoint', 'inverse', 'mod', 'lft', + 'round', 'rt', 'unitvector', 'whatever', + 'cutdraw', 'draw', 'drawarrow', 'drawdblarrow', 'fill', 'filldraw', 'drawdot', + 'loggingall', 'pickup', 'tracingall', 'tracingnone', 'undraw', 'unfill', + 'unfilldraw', + 'buildcycle', 'dashpattern', 'decr', 'dotlabel', 'dotlabels', 'drawoptions', + 'incr', 'label', 'labels', 'max', 'min', 'thelabel', 'z', + 'beginchar', 'blacker', 'capsule_end', 'change_width', + 'define_blacker_pixels', 'define_corrected_pixels', + 'define_good_x_pixels', 'define_good_y_pixels', + 'define_horizontal_corrected_pixels', 'define_pixels', + 'define_whole_blacker_pixels', 'define_whole_pixels', + 'define_whole_vertical_blacker_pixels', + 'define_whole_vertical_pixels', 'endchar', 'extra_beginchar', + 'extra_endchar', 'extra_setup', 'font_coding_scheme', + 'font_extra_space' +} + +visualizer.identifiers.metafun = { + 'unitcircle', 'fulldiamond', 'unitdiamond', + 'halfcircle', 'quartercircle', + 'llcircle', 'lrcircle', 'urcircle', 'ulcircle', + 'tcircle', 'bcircle', 'lcircle', 'rcircle', + 'lltriangle', 'lrtriangle', 'urtriangle', 'ultriangle', + 'smoothed', 'cornered', 'superellipsed', 'randomized', 'squeezed', + 'punked', 'curved', 'unspiked', 'simplified', 'blownup', 'stretched', + 'paralled', 'enlonged', 'shortened', + 'enlarged', 'leftenlarged', 'topenlarged', 'rightenlarged', 'bottomenlarged', + 'llenlarged', 'lrenlarged', 'urenlarged', 'ulenlarged', + 'llmoved', 'lrmoved', 'urmoved', 'ulmoved', + 'boundingbox', 'innerboundingbox', 'outerboundingbox', + 'bottomboundary', 'leftboundary', 'topboundary', 'rightboundary', + 'xsized', 'ysized', 'xysized', + 'cmyk', 'transparent', 'withshade', 'spotcolor', + 'drawfill', 'undrawfill', + 'inverted', 'uncolored', 'softened', 'grayed', + 'textext', 'graphictext', + 'loadfigure', 'externalfigure' +} + +visualizer.styles = { + primitives = "", + plain = "\\sl", + metafun = "\\sl", +} + +local styles = visualizer.styles + +-- btex .. etex + +local colors = { + "prettyone", + "prettytwo", + "prettythree", + "prettyfour", +} + +local states = { + [';']=1, ['$']=1, ['@']=1, ['#']=1, + ['\\']=2, + ['(']=3, [')']=3, ['[']=3, [']']=3, [':']=3, ['=']=3, ['<']=3, ['>']=3, ['"']=3, + ['-']=4, ['+']=4, ['/']=4, ['*']=4, ['|']=4, ['`']=4, ['!']=4, ['?']=4, ['^']=4, ['&']=4, ['%']=4, + ['%']=4, ['.']=4, [',']=4 +} + +local known_words = { } + +for k,v in next, visualizer.identifiers do + for _,w in next, v do + known_words[w] = k + end +end + +local change_state, finish_state = buffers.change_state, buffers.finish_state + +local function flush_mp_word(state, word, intex) + if word then + if intex then + if word == 'etex' then + state = change_state(2,state) + texwrite(word) + state = finish_state(state) + return state, false + else + texwrite(word) + return state, true + end + else + local id = known_words[word] + if id then + state = change_state(2,state) + if styles[id] then + texsprint(ctxcatcodes,styles[id]) + end + texwrite(word) + state = finish_state(state) + return state, (word == 'btex') or (word == 'verbatimtex') + else + state = finish_state(state) + texwrite(word) + return state, intex + end + end + else + state = finish_state(state) + return state, intex + end +end + +-- todo: split string in code and comment, and escape comment fast +-- could be generic + +-- to be considered: visualizer => table [result, instr, incomment, word] + +function visualizer.flush_line(str,nested) + local state, word, instr, intex, incomment = 0, nil, false, false, false + buffers.currentcolors = colors + for c in utfcharacters(str) do + if c == " " then + state, intex = flush_mp_word(state, word, intex) + word = nil + texsprint(ctxcatcodes,"\\obs") + elseif incomment then + texwrite(c) + elseif c == '%' then + state = change_state(states[c], state) + incomment = true + texwrite(c) + state = finish_state(state) + elseif instr then + if c == '"' then + state = change_state(states[c],state) + instr = false + texwrite(c) + state = finish_state(state) + else + texwrite(c) + end + elseif intex then + if utffind(c,"^[%a]$") then + if word then word = word .. c else word = c end + else + state, intex = flush_mp_word(state, word, intex) + word = nil + if intex then + texwrite(c) + else + state = change_state(states[c], state) + texwrite(c) + end + end + elseif utffind(c,"^[%a]$") then + state = finish_state(state) + if word then word = word .. c else word = c end + else + state, intex = flush_mp_word(state, word, intex) + word = nil + state = change_state(states[c], state) + texwrite(c) + state = finish_state(state) + instr = (c == '"') + end + end + state, intex = flush_mp_word(state, word, intex) + state = finish_state(state) +end diff --git a/tex/context/base/pret-tex.lua b/tex/context/base/pret-tex.lua new file mode 100644 index 000000000..5d128fa3b --- /dev/null +++ b/tex/context/base/pret-tex.lua @@ -0,0 +1,87 @@ +if not modules then modules = { } end modules ['pret-tex'] = { + version = 1.001, + comment = "companion to buff-ver.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local utf = unicode.utf8 + +local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues +local utfbyte, utffind = utf.byte, utf.find +local rep = string.rep +local texsprint, texwrite = tex.sprint, tex.write +local ctxcatcodes, vrbcatcodes = tex.ctxcatcodes, tex.vrbcatcodes + +local visualizer = buffers.newvisualizer("tex") + +local colors = { + "prettytwo", + "prettyone", + "prettythree", + "prettyfour" +} + +local states = { + ['$']=2, ['{']=2, ['}']=2, + ['[']=3, [']']=3, ['(']=3, [')']=3, ['<']=3, ['>']=3, ['#']=3, ['=']=3, ['"']=3, + ['/']=4, ['^']=4, ['_']=4, ['-']=4, ['&']=4, ['+']=4, ["'"]=4, ['`']=4, ['|']=4, ['%']=4 +} + +-- some day I'll make an lpeg + +local change_state, finish_state = buffers.change_state, buffers.finish_state + +local chardata = characters.data +local is_letter = characters.is_letter + +function visualizer.flush_line(str,nested) + local state, first, i = 0, false, 0 + buffers.currentcolors = colors + for c in utfcharacters(str) do + i = i + 1 + if c == " " then + state = finish_state(state) + texsprint(ctxcatcodes,"\\obs") + first = false + elseif c == "\t" then + state = finish_state(state) + texsprint(ctxcatcodes,"\\obs") + if buffers.visualizers.enabletab then + texsprint(ctxcatcodes,rep("\\obs ",i%buffers.visualizers.tablength)) + i = 0 + end + first = false + elseif first then + state = 1 + texwrite(c) + if not utffind(c,"^[%a%!%?%@]$") then + state = finish_state(state) + end + first = false + elseif state == 1 then + if utffind(c,"^[%a%!%?%@]$") then + texwrite(c) + first = false + elseif c == "\\" then + state = change_state(1, state) + texwrite(c) + first = true + else + state = change_state(states[c], state) + texwrite(c) + first = false + end + elseif c == "\\" then + first = true + state = change_state(1, state) + texwrite(c) + else + state = change_state(states[c], state) + texwrite(c) + first = false + end + end + state = finish_state(state) +end diff --git a/tex/context/base/pret-xml.lua b/tex/context/base/pret-xml.lua new file mode 100644 index 000000000..b11dccb99 --- /dev/null +++ b/tex/context/base/pret-xml.lua @@ -0,0 +1,136 @@ +if not modules then modules = { } end modules ['pret-xml'] = { + version = 1.001, + comment = "companion to buff-ver.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- line by line, no check because can be snippet (educational) and +-- a somewhat simplified view on xml; we forget about dtd's and +-- cdata (some day i'll make a visualizer for valid xml using the +-- built in parser) + +local utf = unicode.utf8 + +local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues +local utfbyte, utffind = utf.byte, utf.find +local rep = string.rep +local texsprint, texwrite = tex.sprint, tex.write +local ctxcatcodes = tex.ctxcatcodes + +local visualizer = buffers.newvisualizer("xml") + +local colors = { + "prettytwo", + "prettyone", + "prettythree", + "prettyfour" +} + +local states = { + ['"']=2, ["'"]=2, + ["-"]=1, ["?"]=1, ["!"]=1, [":"]=1, ["_"]=1, ["/"]=1, +} + +local change_state, finish_state = buffers.change_state, buffers.finish_state + +local state, intag, dotag, inentity, inquote + +function visualizer.reset() + state, intag, dotag, inentity, inquote = 0, false, false, false, false +end + +function visualizer.flush_line(str,nested) + buffers.currentcolors = colors + for c in utfcharacters(str) do + if c == "&" then + inentity = true -- no further checking + state = change_state(3, state) + texwrite(c) + elseif c == ";" then + if inentity then + inentity = false + state = change_state(3, state) + texwrite(c) + state = finish_state(state) + else + texwrite(c) + end + elseif inentity then + state = change_state(3, state) + texwrite(c) + elseif c == " " then + state = finish_state(state) + texsprint(ctxcatcodes,"\\obs") + intag = false + elseif c == "\t" then + state = finish_state(state) + texsprint(ctxcatcodes,"\\obs") + if buffers.visualizers.enabletab then + texsprint(ctxcatcodes,rep("\\obs ",i%buffers.visualizers.tablength)) + end + intag = false + elseif c == "<" then + if intag then + state = finish_state(state) + -- error + else + intag = 1 + dotag = true + state = change_state(1, state) + end + texwrite(c) + elseif c == ">" then + if intag then + texwrite(c) + state = finish_state(state) + intag, dotag = false, false + elseif dotag then + state = change_state(1, state) + texwrite(c) + state = finish_state(state) + intag, dotag = false, false + else + state = finish_state(state) + texwrite(c) + end + elseif intag then + if utffind(c,"^[%S]$") then + state = change_state(1, state) + texwrite(c) + intag = intag + 1 + else + intag = false + state = finish_state(state) + texwrite(c) + end + elseif dotag then + if c == "'" or c == '"' then + if inquote then + if c == inquote then + state = change_state(states[c], state) -- 2 + texwrite(c) + state = finish_state(state) + inquote = false + else + texwrite(c) + end + else + inquote = c + state = change_state(states[c], state) + texwrite(c) + state = finish_state(state) + end + elseif inquote then + texwrite(c) + else + state = change_state(states[c], state) + texwrite(c) + end + else + texwrite(c) + end + end + state = finish_state(state) +end 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..97d72582e --- /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} + +\unexpanded\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\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 + {\setugvalue{\e!start#1}{\dostartproperty{#1}}% + \setugvalue{\e!stop #1}{\dostopproperty}}% + {\setugvalue{\e!start#1}{\dostartgproperty{#1}}% + \setugvalue{\e!stop #1}{\dostopgproperty}}}% + {\doifelsevalue{\??py#1\c!global}\v!yes + {\setugvalue{\e!start#2}[##1]{\dostartproperty{##1}}% + \setugvalue{\e!stop #2}{\dostopproperty}}% + {\setugvalue{\e!start#2}[##1]{\dostartgproperty{##1}}% + \setugvalue{\e!stop #2}{\dostopgproperty}}}} + +\def\nododefineproperty[#1][#2][#3]% + {} + +\def\doifelseproperty#1{\doifdefinedelse{\??py#1\c!global}} + +\unexpanded\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 + {\ifcsname\??py\currentproperty#1\endcsname\csname\??py\currentproperty#1\endcsname\fi} + +\unexpanded\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 new file mode 100644 index 000000000..aeec94bb2 --- /dev/null +++ b/tex/context/base/prop-lay.mkii @@ -0,0 +1,143 @@ +%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 + +\let\currentlayerproperty\empty + +\def\checklayerproperty + {\doifelse{\checkedpropertyparameter\v!printable\currentproperty}\v!no + {\def\printviewerlayer{0}} + {\def\printviewerlayer{1}}% + \dodefineviewerlayer + \currentproperty % tag + {\checkedpropertyparameter\c!title\currentproperty}% + {\checkedpropertyparameter\c!state\v!start}% visible or hidden + {0}% type (1=frozen) + {\printviewerlayer}}% 1=printable + +\def\startlayerproperty + {\let\currentlayerproperty\currentproperty + \dostartviewerlayer\currentproperty} + +\def\stoplayerproperty + {\dostopviewerlayer + \let\currentlayerproperty\previousproperty} + +\def\domakelayerpropertylist + {\iflocation + \expandafter\domakeviewerlayerlist + \else + \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 new file mode 100644 index 000000000..7711dae52 --- /dev/null +++ b/tex/context/base/prop-lay.mkiv @@ -0,0 +1,140 @@ +%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. + +% test, nesting is somewhat special with layers +% +% \defineproperty[hans][layer] +% \defineproperty[ton] [layer] +% \setupheadertexts[no layer] +% 1\startproperty[hans]2\startproperty[ton]3\stopproperty4\stopproperty5 + +\unprotect + +% will be redone ... no longer using property mechanism (less clashes) + +\let\currentviewerlayer\empty + +\appendtoks + \let\currentviewerlayer\empty +\to \everypagebody + +\unexpanded\def\startlayerproperty + {\pushmacro\currentviewerlayer % grouped (used in interaction) + \let\currentlayerproperty\currentproperty % can be cross group + \dotriggerviewerlayer\currentlayerproperty} + +\unexpanded\def\stoplayerproperty + {\popmacro\currentviewerlayer % grouped (used in interaction) + \let\currentlayerproperty\previousproperty % can be cross group + \dotriggerviewerlayer\currentlayerproperty} + +\def\checklayerproperty % could be made more clever + {\registerviewerlayer\currentproperty\currentproperty + \ctxlua{backends.codeinjections.defineviewerlayer{ + tag = "\currentproperty", + title = "\checkedpropertyparameter\c!title\currentproperty", + visible = "\checkedpropertyparameter\c!state\v!start", + kind = 0, % 1 == frozen + printable = "\checkedpropertyparameter\v!printable\v!yes" % v! looks wrong + }}} + +%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 + +\def\doinitializelayoutcomponent#1#2% + {\ctxlua{backends.codeinjections.defineviewerlayer{% this will move to the lua end i.e be merged with register + tag = "#1:#2", + title = "#1 #2", + visible = "\v!start", + kind = 0, % 1 == frozen + printable = "\v!yes" + }}% + \edef\layoutcomponentboxattribute{attr \viewerlayerattribute \ctxlua{tex.write(viewerlayers.register('#1:#2',true))}\relax}% + \expandafter\glet\csname\??ly>#1:#2\endcsname\layoutcomponentboxattribute} + +\def\dosetlayoutcomponentattribute#1#2% make this faster + {\expandafter\let\expandafter\layoutcomponentboxattribute\csname\??ly>#1:#2\endcsname + \ifx\layoutcomponentboxattribute\relax + \doinitializelayoutcomponent{#1}{#2}% get rid of { } + \fi} + +\def\doresetlayoutcomponentattribute + {\let\layoutcomponentboxattribute\empty} + +\let\setlayoutcomponentattribute \gobbletwoarguments +\let\resetlayoutcomponentattribute\relax +\let\layoutcomponentboxattribute \empty + +\def\showlayoutcomponents + {\ctxlua{viewerlayers.enable()}% + \let\setlayoutcomponentattribute \dosetlayoutcomponentattribute + \let\resetlayoutcomponentattribute\doresetlayoutcomponentattribute} + +\protect \endinput + +% \starttext +% \showlayoutcomponents +% \setupinteraction[state=start] +% \setupheadertexts[{\goto{page 1}[page(2)]}] +% test \setlayoutcomponentattribute{test}{aap}\hbox \layoutcomponentboxattribute \bgroup aap +% \setlayoutcomponentattribute{test}{noot}\hbox \layoutcomponentboxattribute \bgroup noot +% \setlayoutcomponentattribute{test}{mies}\hbox \layoutcomponentboxattribute \bgroup mies +% \egroup noot \egroup aap \egroup +% test \setlayoutcomponentattribute{test}{hans}\hbox \layoutcomponentboxattribute \bgroup aap \hbox{!} aap\egroup +% test \page test \page +% \stoptext + diff --git a/tex/context/base/prop-mis.mkii b/tex/context/base/prop-mis.mkii new file mode 100644 index 000000000..d8e9ab173 --- /dev/null +++ b/tex/context/base/prop-mis.mkii @@ -0,0 +1,189 @@ +%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 / 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} +\definepropertyhandler \v!knockout {\dostopoverprint } + +\def\startoverprintproperty + {\ifincolor + \propertyhandler\currentproperty + \dooverprintmark\currentproperty + \fi} + +\def\stopoverprintproperty + {\ifincolor + \ifcase\currentpropertylevel\or + \dostopoverprint + \dooverprintmark\empty + \else + \propertyhandler\previousproperty + \dooverprintmark\previousproperty + \fi + \fi} + +\rawnewmark\overprintmark + +\def\dooverprintmark#1% + {\ifinpagebody \else \ifinframed \else + \expanded{\rawsetmark\noexpand\overprintmark{#1}}% + \fi \fi} + +\def\pushoverprintproperty + {\doifsomething{\rawgetbotmark\overprintmark}\dostopoverprint} + +\def\popoverprintproperty + {\doifsomething{\rawgetbotmark\overprintmark}% + {\propertyhandler{\rawgetbotmark\overprintmark}}} + +\def\popsplitoverprintproperty + {\getsplitmarks\overprintmark % hier wel + \doifsomething{\rawgetsplitbotmark\overprintmark}% + {\propertyhandler{\rawgetsplitbotmark\overprintmark}}} + +\appendtoks \pushoverprintproperty \to \everypushproperties +\appendtoks \popoverprintproperty \to \everypopproperties +\appendtoks \popsplitoverprintproperty \to \everypopsplitproperties + +%D Negative cum suis. + +\definepropertyhandler \v!negative {\dostartnegative} +\definepropertyhandler \v!positive {\dostopnegative } + +\def\startnegativeproperty + {\ifincolor + \propertyhandler\currentproperty + \donegativemark\currentproperty + \fi} + +\def\stopnegativeproperty + {\ifincolor + \ifcase\currentpropertylevel\or + \dostopnegative + \donegativemark\empty + \else + \propertyhandler\previousproperty + \donegativemark\previousproperty + \fi + \fi} + +\rawnewmark\negativemark + +\def\donegativemark#1% + {\ifinpagebody \else \ifinframed \else + \expanded{\rawsetmark\noexpand\negativemark{#1}}% + \fi \fi} + +\def\pushnegativeproperty + {\doifsomething{\rawgetbotmark\negativemark}\dostopnegative} + +\def\popnegativeproperty + {\doifsomething{\rawgetbotmark\overprintmark}% + {\propertyhandler{\rawgetbotmark\negativemark}}} + +\def\popsplitnegativeproperty + {\getsplitmarks\negativemark % hier wel + \doifsomething{\rawgetsplitbotmark\negativemark}% + {\propertyhandler{\rawgetsplitbotmark\negativemark}}} + +\appendtoks \pushnegativeproperty \to \everypushproperties +\appendtoks \popnegativeproperty \to \everypopproperties +\appendtoks \popsplitnegativeproperty \to \everypopsplitproperties + +%D Effects. + +\definepropertyhandler \v!normal {0} +\definepropertyhandler \v!inner {0} +\definepropertyhandler \v!outer {1} +\definepropertyhandler \v!both {2} +\definepropertyhandler \v!hidden {3} +\definepropertyhandler \v!stretch{0} + +\def\effectpropertydata#1% + {{\propertyhandler{#1}}% + {\propertyparameter{#1}\c!rulethickness}% + {\propertyparameter{#1}\c!stretch}} + +\def\starteffectproperty + {\expanded{\dostartfonteffect\effectpropertydata\currentproperty}% + \doeffectmark{\effectpropertydata\currentproperty}} + +\def\stopeffectproperty + {\dostopfonteffect + \ifcase\currentpropertylevel\or + \doeffectmark\empty + \else + \expanded{\dostartfonteffect\effectpropertydata\previousproperty}% + \doeffectmark{\effectpropertydata\previousproperty}% + \fi} + +\rawnewmark\effectmark + +\def\doeffectmark#1% + {\ifinpagebody \else \ifinframed \else + \expanded{\rawsetmark\noexpand\effectmark{#1}}% could be number + \fi \fi} + +\def\pusheffectproperty + {\doifsomething{\rawgetbotmark\effectmark}\dostopfonteffect} + +\def\popeffectproperty + {\doifsomething{\rawgetbotmark\effectmark}% + {\expanded{\dostartfonteffect\rawgetbotmark\effectmark}}} + +\def\popspliteffectproperty + {\getsplitmarks\effectmark + \doifsomething{\rawgetsplitbotmark\effectmark}% + {\expanded{\dostartfonteffect\rawgetsplitbotmark\effectmark}}} + +\appendtoks \pusheffectproperty \to \everypushproperties +\appendtoks \popeffectproperty \to \everypopproperties +\appendtoks \popspliteffectproperty \to \everypopsplitproperties + +\protect \endinput diff --git a/tex/context/base/prop-mis.mkiv b/tex/context/base/prop-mis.mkiv new file mode 100644 index 000000000..37c1d7973 --- /dev/null +++ b/tex/context/base/prop-mis.mkiv @@ -0,0 +1,74 @@ +%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 / 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 Overprint cum suis. +% +% \defineproperty[\v!overprint][\s!overprint] [\c!method=\v!command] +% \defineproperty[\v!knockout] [\s!overprint] [\c!method=\v!command] +% +% \definepropertyhandler \v!overprint {\dotriggeroverprint\v!overprint} +% \definepropertyhandler \v!knockout {\dotriggeroverprint\v!knockout } +% +% \unexpanded\def\startoverprintproperty{\dotriggeroverprint\v!overprint} +% \unexpanded\def\stopoverprintproperty {\dotriggeroverprint\v!knockout } + +%D Negative cum suis. + +\defineproperty [\v!negative] [\s!negative] [\c!method=\v!command] +\defineproperty [\v!positive] [\s!negative] [\c!method=\v!command] + +\definepropertyhandler \v!negative {\dotriggernegative\v!negative} +\definepropertyhandler \v!positive {\dotriggernegative\v!positive} + +\unexpanded\def\startnegativeproperty{\dotriggernegative\v!negative} +\unexpanded\def\stopnegativeproperty {\dotriggernegative\v!positive} + +%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] + +\def\mktriggereffect#1% + {\dotriggereffect{#1}{\propertyparameter{#1}\c!stretch}{\propertyparameter{#1}\c!rulethickness}} + +\definepropertyhandler \v!normal {\mktriggereffect\v!normal} +\definepropertyhandler \v!inner {\mktriggereffect\v!inner } +\definepropertyhandler \v!outer {\mktriggereffect\v!outer } +\definepropertyhandler \v!both {\mktriggereffect\v!both } +\definepropertyhandler \v!hidden {\mktriggereffect\v!hidden} +\definepropertyhandler \v!stretch{\mktriggereffect\v!normal} + +\unexpanded\def\starteffectproperty{\mktriggereffect\currentproperty} +\unexpanded\def\stopeffectproperty {\mktriggereffect\v!normal } + +\protect \endinput diff --git a/tex/context/base/regi-8859-1.lua b/tex/context/base/regi-8859-1.lua new file mode 100644 index 000000000..b8f0a8573 --- /dev/null +++ b/tex/context/base/regi-8859-1.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-8859-1'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["8859-1"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF +} diff --git a/tex/context/base/regi-8859-1.mkii b/tex/context/base/regi-8859-1.mkii new file mode 100644 index 000000000..c291b029a --- /dev/null +++ b/tex/context/base/regi-8859-1.mkii @@ -0,0 +1,154 @@ +%D \module +%D [ file=regi-8859-1, +%D version=2005.12.26, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=iso-8859-1 (West European), +%D author=script-generated, +%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. + +%D Support for iso-8859-1/Latin1 input encoding (regime) for West European languages, +%D see also cp1252 and iso-8859-15 (includes Euro). +%D +%D (Contributors to the original file: Daniel Flipo, Hans Hagen \& Denis Roegel.) +%D +%D Usage: \type{\enableregime[8859-1]} (see \type {regi-syn} for +%D alternatives calls). + +\startregime[8859-1] + +\defineactivetoken 128 {\unknownchar} % 0080 +\defineactivetoken 129 {\unknownchar} % 0081 +\defineactivetoken 130 {\unknownchar} % 0082 +\defineactivetoken 131 {\unknownchar} % 0083 +\defineactivetoken 132 {\unknownchar} % 0084 +\defineactivetoken 133 {\unknownchar} % 0085 +\defineactivetoken 134 {\unknownchar} % 0086 +\defineactivetoken 135 {\unknownchar} % 0087 +\defineactivetoken 136 {\unknownchar} % 0088 +\defineactivetoken 137 {\unknownchar} % 0089 +\defineactivetoken 138 {\unknownchar} % 008A +\defineactivetoken 139 {\unknownchar} % 008B +\defineactivetoken 140 {\unknownchar} % 008C +\defineactivetoken 141 {\unknownchar} % 008D +\defineactivetoken 142 {\unknownchar} % 008E +\defineactivetoken 143 {\unknownchar} % 008F +\defineactivetoken 144 {\unknownchar} % 0090 +\defineactivetoken 145 {\unknownchar} % 0091 +\defineactivetoken 146 {\unknownchar} % 0092 +\defineactivetoken 147 {\unknownchar} % 0093 +\defineactivetoken 148 {\unknownchar} % 0094 +\defineactivetoken 149 {\unknownchar} % 0095 +\defineactivetoken 150 {\unknownchar} % 0096 +\defineactivetoken 151 {\unknownchar} % 0097 +\defineactivetoken 152 {\unknownchar} % 0098 +\defineactivetoken 153 {\unknownchar} % 0099 +\defineactivetoken 154 {\unknownchar} % 009A +\defineactivetoken 155 {\unknownchar} % 009B +\defineactivetoken 156 {\unknownchar} % 009C +\defineactivetoken 157 {\unknownchar} % 009D +\defineactivetoken 158 {\unknownchar} % 009E +\defineactivetoken 159 {\unknownchar} % 009F +\defineactivetoken 160 {\nonbreakablespace} % 00A0 NO-BREAK SPACE +\defineactivetoken 161 {\exclamdown} % 00A1 INVERTED EXCLAMATION MARK +\defineactivetoken 162 {\textcent} % 00A2 CENT SIGN +\defineactivetoken 163 {\textsterling} % 00A3 POUND SIGN +\defineactivetoken 164 {\textcurrency} % 00A4 CURRENCY SIGN +\defineactivetoken 165 {\textyen} % 00A5 YEN SIGN +\defineactivetoken 166 {\textbrokenbar} % 00A6 BROKEN BAR +\defineactivetoken 167 {\sectionmark} % 00A7 SECTION SIGN +\defineactivetoken 168 {\textdiaeresis} % 00A8 DIAERESIS +\defineactivetoken 169 {\copyright} % 00A9 COPYRIGHT SIGN +\defineactivetoken 170 {\ordfeminine} % 00AA FEMININE ORDINAL INDICATOR +\defineactivetoken 171 {\leftguillemot} % 00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 172 {\textlognot} % 00AC NOT SIGN +\defineactivetoken 173 {\softhyphen} % 00AD SOFT HYPHEN +\defineactivetoken 174 {\registered} % 00AE REGISTERED SIGN +\defineactivetoken 175 {\textmacron} % 00AF MACRON +\defineactivetoken 176 {\textdegree} % 00B0 DEGREE SIGN +\defineactivetoken 177 {\textpm} % 00B1 PLUS-MINUS SIGN +\defineactivetoken 178 {\twosuperior} % 00B2 SUPERSCRIPT TWO +\defineactivetoken 179 {\threesuperior} % 00B3 SUPERSCRIPT THREE +\defineactivetoken 180 {\textacute} % 00B4 ACUTE ACCENT +\defineactivetoken 181 {\textmu} % 00B5 MICRO SIGN +\defineactivetoken 182 {\paragraphmark} % 00B6 PILCROW SIGN +\defineactivetoken 183 {\periodcentered} % 00B7 MIDDLE DOT +\defineactivetoken 184 {\textcedilla} % 00B8 CEDILLA +\defineactivetoken 185 {\onesuperior} % 00B9 SUPERSCRIPT ONE +\defineactivetoken 186 {\ordmasculine} % 00BA MASCULINE ORDINAL INDICATOR +\defineactivetoken 187 {\rightguillemot} % 00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 188 {\onequarter} % 00BC VULGAR FRACTION ONE QUARTER +\defineactivetoken 189 {\onehalf} % 00BD VULGAR FRACTION ONE HALF +\defineactivetoken 190 {\threequarter} % 00BE VULGAR FRACTION THREE QUARTERS +\defineactivetoken 191 {\questiondown} % 00BF INVERTED QUESTION MARK +\defineactivetoken 192 {\Agrave} % 00C0 LATIN CAPITAL LETTER A WITH GRAVE +\defineactivetoken 193 {\Aacute} % 00C1 LATIN CAPITAL LETTER A WITH ACUTE +\defineactivetoken 194 {\Acircumflex} % 00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX +\defineactivetoken 195 {\Atilde} % 00C3 LATIN CAPITAL LETTER A WITH TILDE +\defineactivetoken 196 {\Adiaeresis} % 00C4 LATIN CAPITAL LETTER A WITH DIAERESIS +\defineactivetoken 197 {\Aring} % 00C5 LATIN CAPITAL LETTER A WITH RING ABOVE +\defineactivetoken 198 {\AEligature} % 00C6 LATIN CAPITAL LETTER AE +\defineactivetoken 199 {\Ccedilla} % 00C7 LATIN CAPITAL LETTER C WITH CEDILLA +\defineactivetoken 200 {\Egrave} % 00C8 LATIN CAPITAL LETTER E WITH GRAVE +\defineactivetoken 201 {\Eacute} % 00C9 LATIN CAPITAL LETTER E WITH ACUTE +\defineactivetoken 202 {\Ecircumflex} % 00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX +\defineactivetoken 203 {\Ediaeresis} % 00CB LATIN CAPITAL LETTER E WITH DIAERESIS +\defineactivetoken 204 {\Igrave} % 00CC LATIN CAPITAL LETTER I WITH GRAVE +\defineactivetoken 205 {\Iacute} % 00CD LATIN CAPITAL LETTER I WITH ACUTE +\defineactivetoken 206 {\Icircumflex} % 00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX +\defineactivetoken 207 {\Idiaeresis} % 00CF LATIN CAPITAL LETTER I WITH DIAERESIS +\defineactivetoken 208 {\Eth} % 00D0 LATIN CAPITAL LETTER ETH +\defineactivetoken 209 {\Ntilde} % 00D1 LATIN CAPITAL LETTER N WITH TILDE +\defineactivetoken 210 {\Ograve} % 00D2 LATIN CAPITAL LETTER O WITH GRAVE +\defineactivetoken 211 {\Oacute} % 00D3 LATIN CAPITAL LETTER O WITH ACUTE +\defineactivetoken 212 {\Ocircumflex} % 00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX +\defineactivetoken 213 {\Otilde} % 00D5 LATIN CAPITAL LETTER O WITH TILDE +\defineactivetoken 214 {\Odiaeresis} % 00D6 LATIN CAPITAL LETTER O WITH DIAERESIS +\defineactivetoken 215 {\textmultiply} % 00D7 MULTIPLICATION SIGN +\defineactivetoken 216 {\Ostroke} % 00D8 LATIN CAPITAL LETTER O WITH STROKE +\defineactivetoken 217 {\Ugrave} % 00D9 LATIN CAPITAL LETTER U WITH GRAVE +\defineactivetoken 218 {\Uacute} % 00DA LATIN CAPITAL LETTER U WITH ACUTE +\defineactivetoken 219 {\Ucircumflex} % 00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX +\defineactivetoken 220 {\Udiaeresis} % 00DC LATIN CAPITAL LETTER U WITH DIAERESIS +\defineactivetoken 221 {\Yacute} % 00DD LATIN CAPITAL LETTER Y WITH ACUTE +\defineactivetoken 222 {\Thorn} % 00DE LATIN CAPITAL LETTER THORN +\defineactivetoken 223 {\ssharp} % 00DF LATIN SMALL LETTER SHARP S +\defineactivetoken 224 {\agrave} % 00E0 LATIN SMALL LETTER A WITH GRAVE +\defineactivetoken 225 {\aacute} % 00E1 LATIN SMALL LETTER A WITH ACUTE +\defineactivetoken 226 {\acircumflex} % 00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX +\defineactivetoken 227 {\atilde} % 00E3 LATIN SMALL LETTER A WITH TILDE +\defineactivetoken 228 {\adiaeresis} % 00E4 LATIN SMALL LETTER A WITH DIAERESIS +\defineactivetoken 229 {\aring} % 00E5 LATIN SMALL LETTER A WITH RING ABOVE +\defineactivetoken 230 {\aeligature} % 00E6 LATIN SMALL LETTER AE +\defineactivetoken 231 {\ccedilla} % 00E7 LATIN SMALL LETTER C WITH CEDILLA +\defineactivetoken 232 {\egrave} % 00E8 LATIN SMALL LETTER E WITH GRAVE +\defineactivetoken 233 {\eacute} % 00E9 LATIN SMALL LETTER E WITH ACUTE +\defineactivetoken 234 {\ecircumflex} % 00EA LATIN SMALL LETTER E WITH CIRCUMFLEX +\defineactivetoken 235 {\ediaeresis} % 00EB LATIN SMALL LETTER E WITH DIAERESIS +\defineactivetoken 236 {\igrave} % 00EC LATIN SMALL LETTER I WITH GRAVE +\defineactivetoken 237 {\iacute} % 00ED LATIN SMALL LETTER I WITH ACUTE +\defineactivetoken 238 {\icircumflex} % 00EE LATIN SMALL LETTER I WITH CIRCUMFLEX +\defineactivetoken 239 {\idiaeresis} % 00EF LATIN SMALL LETTER I WITH DIAERESIS +\defineactivetoken 240 {\eth} % 00F0 LATIN SMALL LETTER ETH +\defineactivetoken 241 {\ntilde} % 00F1 LATIN SMALL LETTER N WITH TILDE +\defineactivetoken 242 {\ograve} % 00F2 LATIN SMALL LETTER O WITH GRAVE +\defineactivetoken 243 {\oacute} % 00F3 LATIN SMALL LETTER O WITH ACUTE +\defineactivetoken 244 {\ocircumflex} % 00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX +\defineactivetoken 245 {\otilde} % 00F5 LATIN SMALL LETTER O WITH TILDE +\defineactivetoken 246 {\odiaeresis} % 00F6 LATIN SMALL LETTER O WITH DIAERESIS +\defineactivetoken 247 {\textdiv} % 00F7 DIVISION SIGN +\defineactivetoken 248 {\ostroke} % 00F8 LATIN SMALL LETTER O WITH STROKE +\defineactivetoken 249 {\ugrave} % 00F9 LATIN SMALL LETTER U WITH GRAVE +\defineactivetoken 250 {\uacute} % 00FA LATIN SMALL LETTER U WITH ACUTE +\defineactivetoken 251 {\ucircumflex} % 00FB LATIN SMALL LETTER U WITH CIRCUMFLEX +\defineactivetoken 252 {\udiaeresis} % 00FC LATIN SMALL LETTER U WITH DIAERESIS +\defineactivetoken 253 {\yacute} % 00FD LATIN SMALL LETTER Y WITH ACUTE +\defineactivetoken 254 {\thorn} % 00FE LATIN SMALL LETTER THORN +\defineactivetoken 255 {\ydiaeresis} % 00FF LATIN SMALL LETTER Y WITH DIAERESIS + +\stopregime + diff --git a/tex/context/base/regi-8859-10.lua b/tex/context/base/regi-8859-10.lua new file mode 100644 index 000000000..574d4ac50 --- /dev/null +++ b/tex/context/base/regi-8859-10.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-8859-10'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["8859-10"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x0104, 0x0112, 0x0122, 0x012A, 0x0128, 0x0136, 0x00A7, 0x013B, 0x0110, 0x0160, 0x0166, 0x017D, 0x00AD, 0x016A, 0x014A, + 0x00B0, 0x0105, 0x0113, 0x0123, 0x012B, 0x0129, 0x0137, 0x00B7, 0x013C, 0x0111, 0x0161, 0x0167, 0x017E, 0x2015, 0x016B, 0x014B, + 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E, 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x00CF, + 0x00D0, 0x0145, 0x014C, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x0168, 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, + 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F, 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x00EF, + 0x00F0, 0x0146, 0x014D, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x0169, 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x0138 +} diff --git a/tex/context/base/regi-8859-10.mkii b/tex/context/base/regi-8859-10.mkii new file mode 100644 index 000000000..79d74d952 --- /dev/null +++ b/tex/context/base/regi-8859-10.mkii @@ -0,0 +1,152 @@ +%D \module +%D [ file=regi-8859-10, +%D version=2005.12.26, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=iso-8859-10 (Nordic), +%D author=script-generated, +%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. + +%D Support for iso-8859-10/Latin6 input encoding (regime) for Nordic languages. +%D +%D Usage: \type{\enableregime[8859-10]} (see \type {regi-syn} for +%D alternatives calls). + + +\startregime[iso-8859-10] + +\defineactivetoken 128 {\unknownchar} % 0080 +\defineactivetoken 129 {\unknownchar} % 0081 +\defineactivetoken 130 {\unknownchar} % 0082 +\defineactivetoken 131 {\unknownchar} % 0083 +\defineactivetoken 132 {\unknownchar} % 0084 +\defineactivetoken 133 {\unknownchar} % 0085 +\defineactivetoken 134 {\unknownchar} % 0086 +\defineactivetoken 135 {\unknownchar} % 0087 +\defineactivetoken 136 {\unknownchar} % 0088 +\defineactivetoken 137 {\unknownchar} % 0089 +\defineactivetoken 138 {\unknownchar} % 008A +\defineactivetoken 139 {\unknownchar} % 008B +\defineactivetoken 140 {\unknownchar} % 008C +\defineactivetoken 141 {\unknownchar} % 008D +\defineactivetoken 142 {\unknownchar} % 008E +\defineactivetoken 143 {\unknownchar} % 008F +\defineactivetoken 144 {\unknownchar} % 0090 +\defineactivetoken 145 {\unknownchar} % 0091 +\defineactivetoken 146 {\unknownchar} % 0092 +\defineactivetoken 147 {\unknownchar} % 0093 +\defineactivetoken 148 {\unknownchar} % 0094 +\defineactivetoken 149 {\unknownchar} % 0095 +\defineactivetoken 150 {\unknownchar} % 0096 +\defineactivetoken 151 {\unknownchar} % 0097 +\defineactivetoken 152 {\unknownchar} % 0098 +\defineactivetoken 153 {\unknownchar} % 0099 +\defineactivetoken 154 {\unknownchar} % 009A +\defineactivetoken 155 {\unknownchar} % 009B +\defineactivetoken 156 {\unknownchar} % 009C +\defineactivetoken 157 {\unknownchar} % 009D +\defineactivetoken 158 {\unknownchar} % 009E +\defineactivetoken 159 {\unknownchar} % 009F +\defineactivetoken 160 {\nonbreakablespace} % 00A0 NO-BREAK SPACE +\defineactivetoken 161 {\Aogonek} % 0104 LATIN CAPITAL LETTER A WITH OGONEK +\defineactivetoken 162 {\Emacron} % 0112 LATIN CAPITAL LETTER E WITH MACRON +\defineactivetoken 163 {\Gcommaaccent} % 0122 LATIN CAPITAL LETTER G WITH CEDILLA +\defineactivetoken 164 {\Imacron} % 012A LATIN CAPITAL LETTER I WITH MACRON +\defineactivetoken 165 {\Itilde} % 0128 LATIN CAPITAL LETTER I WITH TILDE +\defineactivetoken 166 {\Kcommaaccent} % 0136 LATIN CAPITAL LETTER K WITH CEDILLA +\defineactivetoken 167 {\sectionmark} % 00A7 SECTION SIGN +\defineactivetoken 168 {\Lcommaaccent} % 013B LATIN CAPITAL LETTER L WITH CEDILLA +\defineactivetoken 169 {\Dstroke} % 0110 LATIN CAPITAL LETTER D WITH STROKE +\defineactivetoken 170 {\Scaron} % 0160 LATIN CAPITAL LETTER S WITH CARON +\defineactivetoken 171 {\Tstroke} % 0166 LATIN CAPITAL LETTER T WITH STROKE +\defineactivetoken 172 {\Zcaron} % 017D LATIN CAPITAL LETTER Z WITH CARON +\defineactivetoken 173 {\softhyphen} % 00AD SOFT HYPHEN +\defineactivetoken 174 {\Umacron} % 016A LATIN CAPITAL LETTER U WITH MACRON +\defineactivetoken 175 {\Neng} % 014A LATIN CAPITAL LETTER ENG +\defineactivetoken 176 {\textdegree} % 00B0 DEGREE SIGN +\defineactivetoken 177 {\aogonek} % 0105 LATIN SMALL LETTER A WITH OGONEK +\defineactivetoken 178 {\emacron} % 0113 LATIN SMALL LETTER E WITH MACRON +\defineactivetoken 179 {\gcommaaccent} % 0123 LATIN SMALL LETTER G WITH CEDILLA +\defineactivetoken 180 {\imacron} % 012B LATIN SMALL LETTER I WITH MACRON +\defineactivetoken 181 {\itilde} % 0129 LATIN SMALL LETTER I WITH TILDE +\defineactivetoken 182 {\kcommaaccent} % 0137 LATIN SMALL LETTER K WITH CEDILLA +\defineactivetoken 183 {\periodcentered} % 00B7 MIDDLE DOT +\defineactivetoken 184 {\lcommaaccent} % 013C LATIN SMALL LETTER L WITH CEDILLA +\defineactivetoken 185 {\dstroke} % 0111 LATIN SMALL LETTER D WITH STROKE +\defineactivetoken 186 {\scaron} % 0161 LATIN SMALL LETTER S WITH CARON +\defineactivetoken 187 {\tstroke} % 0167 LATIN SMALL LETTER T WITH STROKE +\defineactivetoken 188 {\zcaron} % 017E LATIN SMALL LETTER Z WITH CARON +\defineactivetoken 189 {\texthorizontalbar} % 2015 HORIZONTAL BAR +\defineactivetoken 190 {\umacron} % 016B LATIN SMALL LETTER U WITH MACRON +\defineactivetoken 191 {\neng} % 014B LATIN SMALL LETTER ENG +\defineactivetoken 192 {\Amacron} % 0100 LATIN CAPITAL LETTER A WITH MACRON +\defineactivetoken 193 {\Aacute} % 00C1 LATIN CAPITAL LETTER A WITH ACUTE +\defineactivetoken 194 {\Acircumflex} % 00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX +\defineactivetoken 195 {\Atilde} % 00C3 LATIN CAPITAL LETTER A WITH TILDE +\defineactivetoken 196 {\Adiaeresis} % 00C4 LATIN CAPITAL LETTER A WITH DIAERESIS +\defineactivetoken 197 {\Aring} % 00C5 LATIN CAPITAL LETTER A WITH RING ABOVE +\defineactivetoken 198 {\AEligature} % 00C6 LATIN CAPITAL LETTER AE +\defineactivetoken 199 {\Iogonek} % 012E LATIN CAPITAL LETTER I WITH OGONEK +\defineactivetoken 200 {\Ccaron} % 010C LATIN CAPITAL LETTER C WITH CARON +\defineactivetoken 201 {\Eacute} % 00C9 LATIN CAPITAL LETTER E WITH ACUTE +\defineactivetoken 202 {\Eogonek} % 0118 LATIN CAPITAL LETTER E WITH OGONEK +\defineactivetoken 203 {\Ediaeresis} % 00CB LATIN CAPITAL LETTER E WITH DIAERESIS +\defineactivetoken 204 {\Edotaccent} % 0116 LATIN CAPITAL LETTER E WITH DOT ABOVE +\defineactivetoken 205 {\Iacute} % 00CD LATIN CAPITAL LETTER I WITH ACUTE +\defineactivetoken 206 {\Icircumflex} % 00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX +\defineactivetoken 207 {\Idiaeresis} % 00CF LATIN CAPITAL LETTER I WITH DIAERESIS +\defineactivetoken 208 {\Eth} % 00D0 LATIN CAPITAL LETTER ETH +\defineactivetoken 209 {\Ncommaaccent} % 0145 LATIN CAPITAL LETTER N WITH CEDILLA +\defineactivetoken 210 {\Omacron} % 014C LATIN CAPITAL LETTER O WITH MACRON +\defineactivetoken 211 {\Oacute} % 00D3 LATIN CAPITAL LETTER O WITH ACUTE +\defineactivetoken 212 {\Ocircumflex} % 00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX +\defineactivetoken 213 {\Otilde} % 00D5 LATIN CAPITAL LETTER O WITH TILDE +\defineactivetoken 214 {\Odiaeresis} % 00D6 LATIN CAPITAL LETTER O WITH DIAERESIS +\defineactivetoken 215 {\Utilde} % 0168 LATIN CAPITAL LETTER U WITH TILDE +\defineactivetoken 216 {\Ostroke} % 00D8 LATIN CAPITAL LETTER O WITH STROKE +\defineactivetoken 217 {\Uogonek} % 0172 LATIN CAPITAL LETTER U WITH OGONEK +\defineactivetoken 218 {\Uacute} % 00DA LATIN CAPITAL LETTER U WITH ACUTE +\defineactivetoken 219 {\Ucircumflex} % 00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX +\defineactivetoken 220 {\Udiaeresis} % 00DC LATIN CAPITAL LETTER U WITH DIAERESIS +\defineactivetoken 221 {\Yacute} % 00DD LATIN CAPITAL LETTER Y WITH ACUTE +\defineactivetoken 222 {\Thorn} % 00DE LATIN CAPITAL LETTER THORN +\defineactivetoken 223 {\ssharp} % 00DF LATIN SMALL LETTER SHARP S +\defineactivetoken 224 {\amacron} % 0101 LATIN SMALL LETTER A WITH MACRON +\defineactivetoken 225 {\aacute} % 00E1 LATIN SMALL LETTER A WITH ACUTE +\defineactivetoken 226 {\acircumflex} % 00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX +\defineactivetoken 227 {\atilde} % 00E3 LATIN SMALL LETTER A WITH TILDE +\defineactivetoken 228 {\adiaeresis} % 00E4 LATIN SMALL LETTER A WITH DIAERESIS +\defineactivetoken 229 {\aring} % 00E5 LATIN SMALL LETTER A WITH RING ABOVE +\defineactivetoken 230 {\aeligature} % 00E6 LATIN SMALL LETTER AE +\defineactivetoken 231 {\iogonek} % 012F LATIN SMALL LETTER I WITH OGONEK +\defineactivetoken 232 {\ccaron} % 010D LATIN SMALL LETTER C WITH CARON +\defineactivetoken 233 {\eacute} % 00E9 LATIN SMALL LETTER E WITH ACUTE +\defineactivetoken 234 {\eogonek} % 0119 LATIN SMALL LETTER E WITH OGONEK +\defineactivetoken 235 {\ediaeresis} % 00EB LATIN SMALL LETTER E WITH DIAERESIS +\defineactivetoken 236 {\edotaccent} % 0117 LATIN SMALL LETTER E WITH DOT ABOVE +\defineactivetoken 237 {\iacute} % 00ED LATIN SMALL LETTER I WITH ACUTE +\defineactivetoken 238 {\icircumflex} % 00EE LATIN SMALL LETTER I WITH CIRCUMFLEX +\defineactivetoken 239 {\idiaeresis} % 00EF LATIN SMALL LETTER I WITH DIAERESIS +\defineactivetoken 240 {\eth} % 00F0 LATIN SMALL LETTER ETH +\defineactivetoken 241 {\ncommaaccent} % 0146 LATIN SMALL LETTER N WITH CEDILLA +\defineactivetoken 242 {\omacron} % 014D LATIN SMALL LETTER O WITH MACRON +\defineactivetoken 243 {\oacute} % 00F3 LATIN SMALL LETTER O WITH ACUTE +\defineactivetoken 244 {\ocircumflex} % 00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX +\defineactivetoken 245 {\otilde} % 00F5 LATIN SMALL LETTER O WITH TILDE +\defineactivetoken 246 {\odiaeresis} % 00F6 LATIN SMALL LETTER O WITH DIAERESIS +\defineactivetoken 247 {\utilde} % 0169 LATIN SMALL LETTER U WITH TILDE +\defineactivetoken 248 {\ostroke} % 00F8 LATIN SMALL LETTER O WITH STROKE +\defineactivetoken 249 {\uogonek} % 0173 LATIN SMALL LETTER U WITH OGONEK +\defineactivetoken 250 {\uacute} % 00FA LATIN SMALL LETTER U WITH ACUTE +\defineactivetoken 251 {\ucircumflex} % 00FB LATIN SMALL LETTER U WITH CIRCUMFLEX +\defineactivetoken 252 {\udiaeresis} % 00FC LATIN SMALL LETTER U WITH DIAERESIS +\defineactivetoken 253 {\yacute} % 00FD LATIN SMALL LETTER Y WITH ACUTE +\defineactivetoken 254 {\thorn} % 00FE LATIN SMALL LETTER THORN +\defineactivetoken 255 {\kkra} % 0138 LATIN SMALL LETTER KRA + +\stopregime + diff --git a/tex/context/base/regi-8859-11.lua b/tex/context/base/regi-8859-11.lua new file mode 100644 index 000000000..1910bbb5d --- /dev/null +++ b/tex/context/base/regi-8859-11.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-8859-11'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["8859-11"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07, 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F, + 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17, 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F, + 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27, 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F, + 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37, 0x0E38, 0x0E39, 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F, + 0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47, 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F, + 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57, 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000, 0x0000, 0x0000 +} diff --git a/tex/context/base/regi-8859-13.lua b/tex/context/base/regi-8859-13.lua new file mode 100644 index 000000000..a6f71cb78 --- /dev/null +++ b/tex/context/base/regi-8859-13.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-8859-13'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["8859-13"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x201D, 0x00A2, 0x00A3, 0x00A4, 0x201E, 0x00A6, 0x00A7, 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00C6, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x201C, 0x00B5, 0x00B6, 0x00B7, 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6, + 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112, 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B, + 0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7, 0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF, + 0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113, 0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C, + 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7, 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x2019 +} diff --git a/tex/context/base/regi-8859-13.mkii b/tex/context/base/regi-8859-13.mkii new file mode 100644 index 000000000..a6dbe376f --- /dev/null +++ b/tex/context/base/regi-8859-13.mkii @@ -0,0 +1,152 @@ +%D \module +%D [ file=regi-8859-13, +%D version=2005.12.26, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=iso-8859-13 (Baltic), +%D author=script-generated, +%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. + +%D Support for iso-8859-13/Latin7 input encoding (regime) for Baltic languages, +%D see also iso-8859-4 and cp1257. +%D +%D Usage: \type{\enableregime[8859-13]} (see \type {regi-syn} for +%D alternatives calls). + +\startregime[iso-8859-13] + +\defineactivetoken 128 {\unknownchar} % 0080 +\defineactivetoken 129 {\unknownchar} % 0081 +\defineactivetoken 130 {\unknownchar} % 0082 +\defineactivetoken 131 {\unknownchar} % 0083 +\defineactivetoken 132 {\unknownchar} % 0084 +\defineactivetoken 133 {\unknownchar} % 0085 +\defineactivetoken 134 {\unknownchar} % 0086 +\defineactivetoken 135 {\unknownchar} % 0087 +\defineactivetoken 136 {\unknownchar} % 0088 +\defineactivetoken 137 {\unknownchar} % 0089 +\defineactivetoken 138 {\unknownchar} % 008A +\defineactivetoken 139 {\unknownchar} % 008B +\defineactivetoken 140 {\unknownchar} % 008C +\defineactivetoken 141 {\unknownchar} % 008D +\defineactivetoken 142 {\unknownchar} % 008E +\defineactivetoken 143 {\unknownchar} % 008F +\defineactivetoken 144 {\unknownchar} % 0090 +\defineactivetoken 145 {\unknownchar} % 0091 +\defineactivetoken 146 {\unknownchar} % 0092 +\defineactivetoken 147 {\unknownchar} % 0093 +\defineactivetoken 148 {\unknownchar} % 0094 +\defineactivetoken 149 {\unknownchar} % 0095 +\defineactivetoken 150 {\unknownchar} % 0096 +\defineactivetoken 151 {\unknownchar} % 0097 +\defineactivetoken 152 {\unknownchar} % 0098 +\defineactivetoken 153 {\unknownchar} % 0099 +\defineactivetoken 154 {\unknownchar} % 009A +\defineactivetoken 155 {\unknownchar} % 009B +\defineactivetoken 156 {\unknownchar} % 009C +\defineactivetoken 157 {\unknownchar} % 009D +\defineactivetoken 158 {\unknownchar} % 009E +\defineactivetoken 159 {\unknownchar} % 009F +\defineactivetoken 160 {\nonbreakablespace} % 00A0 NO-BREAK SPACE +\defineactivetoken 161 {\quotedblright} % 201D RIGHT DOUBLE QUOTATION MARK +\defineactivetoken 162 {\textcent} % 00A2 CENT SIGN +\defineactivetoken 163 {\textsterling} % 00A3 POUND SIGN +\defineactivetoken 164 {\textcurrency} % 00A4 CURRENCY SIGN +\defineactivetoken 165 {\quotedblbase} % 201E DOUBLE LOW-9 QUOTATION MARK +\defineactivetoken 166 {\textbrokenbar} % 00A6 BROKEN BAR +\defineactivetoken 167 {\sectionmark} % 00A7 SECTION SIGN +\defineactivetoken 168 {\Ostroke} % 00D8 LATIN CAPITAL LETTER O WITH STROKE +\defineactivetoken 169 {\copyright} % 00A9 COPYRIGHT SIGN +\defineactivetoken 170 {\Rcommaaccent} % 0156 LATIN CAPITAL LETTER R WITH CEDILLA +\defineactivetoken 171 {\leftguillemot} % 00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 172 {\textlognot} % 00AC NOT SIGN +\defineactivetoken 173 {\softhyphen} % 00AD SOFT HYPHEN +\defineactivetoken 174 {\registered} % 00AE REGISTERED SIGN +\defineactivetoken 175 {\AEligature} % 00C6 LATIN CAPITAL LETTER AE +\defineactivetoken 176 {\textdegree} % 00B0 DEGREE SIGN +\defineactivetoken 177 {\textpm} % 00B1 PLUS-MINUS SIGN +\defineactivetoken 178 {\twosuperior} % 00B2 SUPERSCRIPT TWO +\defineactivetoken 179 {\threesuperior} % 00B3 SUPERSCRIPT THREE +\defineactivetoken 180 {\quotedblleft} % 201C LEFT DOUBLE QUOTATION MARK +\defineactivetoken 181 {\textmu} % 00B5 MICRO SIGN +\defineactivetoken 182 {\paragraphmark} % 00B6 PILCROW SIGN +\defineactivetoken 183 {\periodcentered} % 00B7 MIDDLE DOT +\defineactivetoken 184 {\ostroke} % 00F8 LATIN SMALL LETTER O WITH STROKE +\defineactivetoken 185 {\onesuperior} % 00B9 SUPERSCRIPT ONE +\defineactivetoken 186 {\rcommaaccent} % 0157 LATIN SMALL LETTER R WITH CEDILLA +\defineactivetoken 187 {\rightguillemot} % 00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 188 {\onequarter} % 00BC VULGAR FRACTION ONE QUARTER +\defineactivetoken 189 {\onehalf} % 00BD VULGAR FRACTION ONE HALF +\defineactivetoken 190 {\threequarter} % 00BE VULGAR FRACTION THREE QUARTERS +\defineactivetoken 191 {\aeligature} % 00E6 LATIN SMALL LETTER AE +\defineactivetoken 192 {\Aogonek} % 0104 LATIN CAPITAL LETTER A WITH OGONEK +\defineactivetoken 193 {\Iogonek} % 012E LATIN CAPITAL LETTER I WITH OGONEK +\defineactivetoken 194 {\Amacron} % 0100 LATIN CAPITAL LETTER A WITH MACRON +\defineactivetoken 195 {\Cacute} % 0106 LATIN CAPITAL LETTER C WITH ACUTE +\defineactivetoken 196 {\Adiaeresis} % 00C4 LATIN CAPITAL LETTER A WITH DIAERESIS +\defineactivetoken 197 {\Aring} % 00C5 LATIN CAPITAL LETTER A WITH RING ABOVE +\defineactivetoken 198 {\Eogonek} % 0118 LATIN CAPITAL LETTER E WITH OGONEK +\defineactivetoken 199 {\Emacron} % 0112 LATIN CAPITAL LETTER E WITH MACRON +\defineactivetoken 200 {\Ccaron} % 010C LATIN CAPITAL LETTER C WITH CARON +\defineactivetoken 201 {\Eacute} % 00C9 LATIN CAPITAL LETTER E WITH ACUTE +\defineactivetoken 202 {\Zacute} % 0179 LATIN CAPITAL LETTER Z WITH ACUTE +\defineactivetoken 203 {\Edotaccent} % 0116 LATIN CAPITAL LETTER E WITH DOT ABOVE +\defineactivetoken 204 {\Gcommaaccent} % 0122 LATIN CAPITAL LETTER G WITH CEDILLA +\defineactivetoken 205 {\Kcommaaccent} % 0136 LATIN CAPITAL LETTER K WITH CEDILLA +\defineactivetoken 206 {\Imacron} % 012A LATIN CAPITAL LETTER I WITH MACRON +\defineactivetoken 207 {\Lcommaaccent} % 013B LATIN CAPITAL LETTER L WITH CEDILLA +\defineactivetoken 208 {\Scaron} % 0160 LATIN CAPITAL LETTER S WITH CARON +\defineactivetoken 209 {\Nacute} % 0143 LATIN CAPITAL LETTER N WITH ACUTE +\defineactivetoken 210 {\Ncommaaccent} % 0145 LATIN CAPITAL LETTER N WITH CEDILLA +\defineactivetoken 211 {\Oacute} % 00D3 LATIN CAPITAL LETTER O WITH ACUTE +\defineactivetoken 212 {\Omacron} % 014C LATIN CAPITAL LETTER O WITH MACRON +\defineactivetoken 213 {\Otilde} % 00D5 LATIN CAPITAL LETTER O WITH TILDE +\defineactivetoken 214 {\Odiaeresis} % 00D6 LATIN CAPITAL LETTER O WITH DIAERESIS +\defineactivetoken 215 {\textmultiply} % 00D7 MULTIPLICATION SIGN +\defineactivetoken 216 {\Uogonek} % 0172 LATIN CAPITAL LETTER U WITH OGONEK +\defineactivetoken 217 {\Lstroke} % 0141 LATIN CAPITAL LETTER L WITH STROKE +\defineactivetoken 218 {\Sacute} % 015A LATIN CAPITAL LETTER S WITH ACUTE +\defineactivetoken 219 {\Umacron} % 016A LATIN CAPITAL LETTER U WITH MACRON +\defineactivetoken 220 {\Udiaeresis} % 00DC LATIN CAPITAL LETTER U WITH DIAERESIS +\defineactivetoken 221 {\Zdotaccent} % 017B LATIN CAPITAL LETTER Z WITH DOT ABOVE +\defineactivetoken 222 {\Zcaron} % 017D LATIN CAPITAL LETTER Z WITH CARON +\defineactivetoken 223 {\ssharp} % 00DF LATIN SMALL LETTER SHARP S +\defineactivetoken 224 {\aogonek} % 0105 LATIN SMALL LETTER A WITH OGONEK +\defineactivetoken 225 {\iogonek} % 012F LATIN SMALL LETTER I WITH OGONEK +\defineactivetoken 226 {\amacron} % 0101 LATIN SMALL LETTER A WITH MACRON +\defineactivetoken 227 {\cacute} % 0107 LATIN SMALL LETTER C WITH ACUTE +\defineactivetoken 228 {\adiaeresis} % 00E4 LATIN SMALL LETTER A WITH DIAERESIS +\defineactivetoken 229 {\aring} % 00E5 LATIN SMALL LETTER A WITH RING ABOVE +\defineactivetoken 230 {\eogonek} % 0119 LATIN SMALL LETTER E WITH OGONEK +\defineactivetoken 231 {\emacron} % 0113 LATIN SMALL LETTER E WITH MACRON +\defineactivetoken 232 {\ccaron} % 010D LATIN SMALL LETTER C WITH CARON +\defineactivetoken 233 {\eacute} % 00E9 LATIN SMALL LETTER E WITH ACUTE +\defineactivetoken 234 {\zacute} % 017A LATIN SMALL LETTER Z WITH ACUTE +\defineactivetoken 235 {\edotaccent} % 0117 LATIN SMALL LETTER E WITH DOT ABOVE +\defineactivetoken 236 {\gcommaaccent} % 0123 LATIN SMALL LETTER G WITH CEDILLA +\defineactivetoken 237 {\kcommaaccent} % 0137 LATIN SMALL LETTER K WITH CEDILLA +\defineactivetoken 238 {\imacron} % 012B LATIN SMALL LETTER I WITH MACRON +\defineactivetoken 239 {\lcommaaccent} % 013C LATIN SMALL LETTER L WITH CEDILLA +\defineactivetoken 240 {\scaron} % 0161 LATIN SMALL LETTER S WITH CARON +\defineactivetoken 241 {\nacute} % 0144 LATIN SMALL LETTER N WITH ACUTE +\defineactivetoken 242 {\ncommaaccent} % 0146 LATIN SMALL LETTER N WITH CEDILLA +\defineactivetoken 243 {\oacute} % 00F3 LATIN SMALL LETTER O WITH ACUTE +\defineactivetoken 244 {\omacron} % 014D LATIN SMALL LETTER O WITH MACRON +\defineactivetoken 245 {\otilde} % 00F5 LATIN SMALL LETTER O WITH TILDE +\defineactivetoken 246 {\odiaeresis} % 00F6 LATIN SMALL LETTER O WITH DIAERESIS +\defineactivetoken 247 {\textdiv} % 00F7 DIVISION SIGN +\defineactivetoken 248 {\uogonek} % 0173 LATIN SMALL LETTER U WITH OGONEK +\defineactivetoken 249 {\lstroke} % 0142 LATIN SMALL LETTER L WITH STROKE +\defineactivetoken 250 {\sacute} % 015B LATIN SMALL LETTER S WITH ACUTE +\defineactivetoken 251 {\umacron} % 016B LATIN SMALL LETTER U WITH MACRON +\defineactivetoken 252 {\udiaeresis} % 00FC LATIN SMALL LETTER U WITH DIAERESIS +\defineactivetoken 253 {\zdotaccent} % 017C LATIN SMALL LETTER Z WITH DOT ABOVE +\defineactivetoken 254 {\zcaron} % 017E LATIN SMALL LETTER Z WITH CARON +\defineactivetoken 255 {\quoteright} % 2019 RIGHT SINGLE QUOTATION MARK + +\stopregime + diff --git a/tex/context/base/regi-8859-14.lua b/tex/context/base/regi-8859-14.lua new file mode 100644 index 000000000..0c3474865 --- /dev/null +++ b/tex/context/base/regi-8859-14.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-8859-14'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["8859-14"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x1E02, 0x1E03, 0x00A3, 0x010A, 0x010B, 0x1E0A, 0x00A7, 0x1E80, 0x00A9, 0x1E82, 0x1E0B, 0x1EF2, 0x00AD, 0x00AE, 0x0178, + 0x1E1E, 0x1E1F, 0x0120, 0x0121, 0x1E40, 0x1E41, 0x00B6, 0x1E56, 0x1E81, 0x1E57, 0x1E83, 0x1E60, 0x1EF3, 0x1E84, 0x1E85, 0x1E61, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x0174, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x1E6A, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x0176, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x0175, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x1E6B, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x0177, 0x00FF +} diff --git a/tex/context/base/regi-8859-15.lua b/tex/context/base/regi-8859-15.lua new file mode 100644 index 000000000..a5626d653 --- /dev/null +++ b/tex/context/base/regi-8859-15.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-8859-15'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["8859-15"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AC, 0x00A5, 0x0160, 0x00A7, 0x0161, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x017D, 0x00B5, 0x00B6, 0x00B7, 0x017E, 0x00B9, 0x00BA, 0x00BB, 0x0152, 0x0153, 0x0178, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF +} diff --git a/tex/context/base/regi-8859-15.mkii b/tex/context/base/regi-8859-15.mkii new file mode 100644 index 000000000..cf788d3f3 --- /dev/null +++ b/tex/context/base/regi-8859-15.mkii @@ -0,0 +1,154 @@ +%D \module +%D [ file=regi-8859-15, +%D version=2005.12.26, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=iso-8859-15 (West European), +%D author=script-generated, +%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. + +%D Support for iso-8859-15/Latin9 input encoding (regime) for +%D West European languages, almost the same as iso-8859-1 with rarely +%D used symbols (currency symbol,%D fractions, accents) replaced by +%D Euro and some additional letters,%D see also cp1252. +%D +%D Usage: \type{\enableregime[8859-15]} (see \type {regi-syn} for +%D alternatives calls). + +\startregime[8859-15] + +\defineactivetoken 128 {\unknownchar} % 0080 +\defineactivetoken 129 {\unknownchar} % 0081 +\defineactivetoken 130 {\unknownchar} % 0082 +\defineactivetoken 131 {\unknownchar} % 0083 +\defineactivetoken 132 {\unknownchar} % 0084 +\defineactivetoken 133 {\unknownchar} % 0085 +\defineactivetoken 134 {\unknownchar} % 0086 +\defineactivetoken 135 {\unknownchar} % 0087 +\defineactivetoken 136 {\unknownchar} % 0088 +\defineactivetoken 137 {\unknownchar} % 0089 +\defineactivetoken 138 {\unknownchar} % 008A +\defineactivetoken 139 {\unknownchar} % 008B +\defineactivetoken 140 {\unknownchar} % 008C +\defineactivetoken 141 {\unknownchar} % 008D +\defineactivetoken 142 {\unknownchar} % 008E +\defineactivetoken 143 {\unknownchar} % 008F +\defineactivetoken 144 {\unknownchar} % 0090 +\defineactivetoken 145 {\unknownchar} % 0091 +\defineactivetoken 146 {\unknownchar} % 0092 +\defineactivetoken 147 {\unknownchar} % 0093 +\defineactivetoken 148 {\unknownchar} % 0094 +\defineactivetoken 149 {\unknownchar} % 0095 +\defineactivetoken 150 {\unknownchar} % 0096 +\defineactivetoken 151 {\unknownchar} % 0097 +\defineactivetoken 152 {\unknownchar} % 0098 +\defineactivetoken 153 {\unknownchar} % 0099 +\defineactivetoken 154 {\unknownchar} % 009A +\defineactivetoken 155 {\unknownchar} % 009B +\defineactivetoken 156 {\unknownchar} % 009C +\defineactivetoken 157 {\unknownchar} % 009D +\defineactivetoken 158 {\unknownchar} % 009E +\defineactivetoken 159 {\unknownchar} % 009F +\defineactivetoken 160 {\nonbreakablespace} % 00A0 NO-BREAK SPACE +\defineactivetoken 161 {\exclamdown} % 00A1 INVERTED EXCLAMATION MARK +\defineactivetoken 162 {\textcent} % 00A2 CENT SIGN +\defineactivetoken 163 {\textsterling} % 00A3 POUND SIGN +\defineactivetoken 164 {\texteuro} % 20AC EURO SIGN +\defineactivetoken 165 {\textyen} % 00A5 YEN SIGN +\defineactivetoken 166 {\Scaron} % 0160 LATIN CAPITAL LETTER S WITH CARON +\defineactivetoken 167 {\sectionmark} % 00A7 SECTION SIGN +\defineactivetoken 168 {\scaron} % 0161 LATIN SMALL LETTER S WITH CARON +\defineactivetoken 169 {\copyright} % 00A9 COPYRIGHT SIGN +\defineactivetoken 170 {\ordfeminine} % 00AA FEMININE ORDINAL INDICATOR +\defineactivetoken 171 {\leftguillemot} % 00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 172 {\textlognot} % 00AC NOT SIGN +\defineactivetoken 173 {\softhyphen} % 00AD SOFT HYPHEN +\defineactivetoken 174 {\registered} % 00AE REGISTERED SIGN +\defineactivetoken 175 {\textmacron} % 00AF MACRON +\defineactivetoken 176 {\textdegree} % 00B0 DEGREE SIGN +\defineactivetoken 177 {\textpm} % 00B1 PLUS-MINUS SIGN +\defineactivetoken 178 {\twosuperior} % 00B2 SUPERSCRIPT TWO +\defineactivetoken 179 {\threesuperior} % 00B3 SUPERSCRIPT THREE +\defineactivetoken 180 {\Zcaron} % 017D LATIN CAPITAL LETTER Z WITH CARON +\defineactivetoken 181 {\textmu} % 00B5 MICRO SIGN +\defineactivetoken 182 {\paragraphmark} % 00B6 PILCROW SIGN +\defineactivetoken 183 {\periodcentered} % 00B7 MIDDLE DOT +\defineactivetoken 184 {\zcaron} % 017E LATIN SMALL LETTER Z WITH CARON +\defineactivetoken 185 {\onesuperior} % 00B9 SUPERSCRIPT ONE +\defineactivetoken 186 {\ordmasculine} % 00BA MASCULINE ORDINAL INDICATOR +\defineactivetoken 187 {\rightguillemot} % 00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 188 {\OEligature} % 0152 LATIN CAPITAL LIGATURE OE +\defineactivetoken 189 {\oeligature} % 0153 LATIN SMALL LIGATURE OE +\defineactivetoken 190 {\Ydiaeresis} % 0178 LATIN CAPITAL LETTER Y WITH DIAERESIS +\defineactivetoken 191 {\questiondown} % 00BF INVERTED QUESTION MARK +\defineactivetoken 192 {\Agrave} % 00C0 LATIN CAPITAL LETTER A WITH GRAVE +\defineactivetoken 193 {\Aacute} % 00C1 LATIN CAPITAL LETTER A WITH ACUTE +\defineactivetoken 194 {\Acircumflex} % 00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX +\defineactivetoken 195 {\Atilde} % 00C3 LATIN CAPITAL LETTER A WITH TILDE +\defineactivetoken 196 {\Adiaeresis} % 00C4 LATIN CAPITAL LETTER A WITH DIAERESIS +\defineactivetoken 197 {\Aring} % 00C5 LATIN CAPITAL LETTER A WITH RING ABOVE +\defineactivetoken 198 {\AEligature} % 00C6 LATIN CAPITAL LETTER AE +\defineactivetoken 199 {\Ccedilla} % 00C7 LATIN CAPITAL LETTER C WITH CEDILLA +\defineactivetoken 200 {\Egrave} % 00C8 LATIN CAPITAL LETTER E WITH GRAVE +\defineactivetoken 201 {\Eacute} % 00C9 LATIN CAPITAL LETTER E WITH ACUTE +\defineactivetoken 202 {\Ecircumflex} % 00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX +\defineactivetoken 203 {\Ediaeresis} % 00CB LATIN CAPITAL LETTER E WITH DIAERESIS +\defineactivetoken 204 {\Igrave} % 00CC LATIN CAPITAL LETTER I WITH GRAVE +\defineactivetoken 205 {\Iacute} % 00CD LATIN CAPITAL LETTER I WITH ACUTE +\defineactivetoken 206 {\Icircumflex} % 00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX +\defineactivetoken 207 {\Idiaeresis} % 00CF LATIN CAPITAL LETTER I WITH DIAERESIS +\defineactivetoken 208 {\Eth} % 00D0 LATIN CAPITAL LETTER ETH +\defineactivetoken 209 {\Ntilde} % 00D1 LATIN CAPITAL LETTER N WITH TILDE +\defineactivetoken 210 {\Ograve} % 00D2 LATIN CAPITAL LETTER O WITH GRAVE +\defineactivetoken 211 {\Oacute} % 00D3 LATIN CAPITAL LETTER O WITH ACUTE +\defineactivetoken 212 {\Ocircumflex} % 00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX +\defineactivetoken 213 {\Otilde} % 00D5 LATIN CAPITAL LETTER O WITH TILDE +\defineactivetoken 214 {\Odiaeresis} % 00D6 LATIN CAPITAL LETTER O WITH DIAERESIS +\defineactivetoken 215 {\textmultiply} % 00D7 MULTIPLICATION SIGN +\defineactivetoken 216 {\Ostroke} % 00D8 LATIN CAPITAL LETTER O WITH STROKE +\defineactivetoken 217 {\Ugrave} % 00D9 LATIN CAPITAL LETTER U WITH GRAVE +\defineactivetoken 218 {\Uacute} % 00DA LATIN CAPITAL LETTER U WITH ACUTE +\defineactivetoken 219 {\Ucircumflex} % 00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX +\defineactivetoken 220 {\Udiaeresis} % 00DC LATIN CAPITAL LETTER U WITH DIAERESIS +\defineactivetoken 221 {\Yacute} % 00DD LATIN CAPITAL LETTER Y WITH ACUTE +\defineactivetoken 222 {\Thorn} % 00DE LATIN CAPITAL LETTER THORN +\defineactivetoken 223 {\ssharp} % 00DF LATIN SMALL LETTER SHARP S +\defineactivetoken 224 {\agrave} % 00E0 LATIN SMALL LETTER A WITH GRAVE +\defineactivetoken 225 {\aacute} % 00E1 LATIN SMALL LETTER A WITH ACUTE +\defineactivetoken 226 {\acircumflex} % 00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX +\defineactivetoken 227 {\atilde} % 00E3 LATIN SMALL LETTER A WITH TILDE +\defineactivetoken 228 {\adiaeresis} % 00E4 LATIN SMALL LETTER A WITH DIAERESIS +\defineactivetoken 229 {\aring} % 00E5 LATIN SMALL LETTER A WITH RING ABOVE +\defineactivetoken 230 {\aeligature} % 00E6 LATIN SMALL LETTER AE +\defineactivetoken 231 {\ccedilla} % 00E7 LATIN SMALL LETTER C WITH CEDILLA +\defineactivetoken 232 {\egrave} % 00E8 LATIN SMALL LETTER E WITH GRAVE +\defineactivetoken 233 {\eacute} % 00E9 LATIN SMALL LETTER E WITH ACUTE +\defineactivetoken 234 {\ecircumflex} % 00EA LATIN SMALL LETTER E WITH CIRCUMFLEX +\defineactivetoken 235 {\ediaeresis} % 00EB LATIN SMALL LETTER E WITH DIAERESIS +\defineactivetoken 236 {\igrave} % 00EC LATIN SMALL LETTER I WITH GRAVE +\defineactivetoken 237 {\iacute} % 00ED LATIN SMALL LETTER I WITH ACUTE +\defineactivetoken 238 {\icircumflex} % 00EE LATIN SMALL LETTER I WITH CIRCUMFLEX +\defineactivetoken 239 {\idiaeresis} % 00EF LATIN SMALL LETTER I WITH DIAERESIS +\defineactivetoken 240 {\eth} % 00F0 LATIN SMALL LETTER ETH +\defineactivetoken 241 {\ntilde} % 00F1 LATIN SMALL LETTER N WITH TILDE +\defineactivetoken 242 {\ograve} % 00F2 LATIN SMALL LETTER O WITH GRAVE +\defineactivetoken 243 {\oacute} % 00F3 LATIN SMALL LETTER O WITH ACUTE +\defineactivetoken 244 {\ocircumflex} % 00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX +\defineactivetoken 245 {\otilde} % 00F5 LATIN SMALL LETTER O WITH TILDE +\defineactivetoken 246 {\odiaeresis} % 00F6 LATIN SMALL LETTER O WITH DIAERESIS +\defineactivetoken 247 {\textdiv} % 00F7 DIVISION SIGN +\defineactivetoken 248 {\ostroke} % 00F8 LATIN SMALL LETTER O WITH STROKE +\defineactivetoken 249 {\ugrave} % 00F9 LATIN SMALL LETTER U WITH GRAVE +\defineactivetoken 250 {\uacute} % 00FA LATIN SMALL LETTER U WITH ACUTE +\defineactivetoken 251 {\ucircumflex} % 00FB LATIN SMALL LETTER U WITH CIRCUMFLEX +\defineactivetoken 252 {\udiaeresis} % 00FC LATIN SMALL LETTER U WITH DIAERESIS +\defineactivetoken 253 {\yacute} % 00FD LATIN SMALL LETTER Y WITH ACUTE +\defineactivetoken 254 {\thorn} % 00FE LATIN SMALL LETTER THORN +\defineactivetoken 255 {\ydiaeresis} % 00FF LATIN SMALL LETTER Y WITH DIAERESIS + +\stopregime + diff --git a/tex/context/base/regi-8859-16.lua b/tex/context/base/regi-8859-16.lua new file mode 100644 index 000000000..817b41db2 --- /dev/null +++ b/tex/context/base/regi-8859-16.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-8859-16'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["8859-16"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x0104, 0x0105, 0x0141, 0x20AC, 0x201E, 0x0160, 0x00A7, 0x0161, 0x00A9, 0x0218, 0x00AB, 0x0179, 0x00AD, 0x017A, 0x017B, + 0x00B0, 0x00B1, 0x010C, 0x0142, 0x017D, 0x201D, 0x00B6, 0x00B7, 0x017E, 0x010D, 0x0219, 0x00BB, 0x0152, 0x0153, 0x0178, 0x017C, + 0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0106, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x0110, 0x0143, 0x00D2, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x015A, 0x0170, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0118, 0x021A, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x0107, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x0111, 0x0144, 0x00F2, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x015B, 0x0171, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0119, 0x021B, 0x00FF +} diff --git a/tex/context/base/regi-8859-16.mkii b/tex/context/base/regi-8859-16.mkii new file mode 100644 index 000000000..96f0a15d4 --- /dev/null +++ b/tex/context/base/regi-8859-16.mkii @@ -0,0 +1,151 @@ +%D \module +%D [ file=regi-8859-16, +%D version=2005.12.26, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=iso-8859-16 (Romanian), +%D author=script-generated, +%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. + +%D Support for iso-8859-16/Latin10 input encoding (regime) for Romanian. +%D +%D Usage: \type{\enableregime[8859-16]} (see \type {regi-syn} for +%D alternatives calls). + +\startregime[8859-16] + +\defineactivetoken 128 {\unknownchar} % 0080 +\defineactivetoken 129 {\unknownchar} % 0081 +\defineactivetoken 130 {\unknownchar} % 0082 +\defineactivetoken 131 {\unknownchar} % 0083 +\defineactivetoken 132 {\unknownchar} % 0084 +\defineactivetoken 133 {\unknownchar} % 0085 +\defineactivetoken 134 {\unknownchar} % 0086 +\defineactivetoken 135 {\unknownchar} % 0087 +\defineactivetoken 136 {\unknownchar} % 0088 +\defineactivetoken 137 {\unknownchar} % 0089 +\defineactivetoken 138 {\unknownchar} % 008A +\defineactivetoken 139 {\unknownchar} % 008B +\defineactivetoken 140 {\unknownchar} % 008C +\defineactivetoken 141 {\unknownchar} % 008D +\defineactivetoken 142 {\unknownchar} % 008E +\defineactivetoken 143 {\unknownchar} % 008F +\defineactivetoken 144 {\unknownchar} % 0090 +\defineactivetoken 145 {\unknownchar} % 0091 +\defineactivetoken 146 {\unknownchar} % 0092 +\defineactivetoken 147 {\unknownchar} % 0093 +\defineactivetoken 148 {\unknownchar} % 0094 +\defineactivetoken 149 {\unknownchar} % 0095 +\defineactivetoken 150 {\unknownchar} % 0096 +\defineactivetoken 151 {\unknownchar} % 0097 +\defineactivetoken 152 {\unknownchar} % 0098 +\defineactivetoken 153 {\unknownchar} % 0099 +\defineactivetoken 154 {\unknownchar} % 009A +\defineactivetoken 155 {\unknownchar} % 009B +\defineactivetoken 156 {\unknownchar} % 009C +\defineactivetoken 157 {\unknownchar} % 009D +\defineactivetoken 158 {\unknownchar} % 009E +\defineactivetoken 159 {\unknownchar} % 009F +\defineactivetoken 160 {\nonbreakablespace} % 00A0 NO-BREAK SPACE +\defineactivetoken 161 {\Aogonek} % 0104 LATIN CAPITAL LETTER A WITH OGONEK +\defineactivetoken 162 {\aogonek} % 0105 LATIN SMALL LETTER A WITH OGONEK +\defineactivetoken 163 {\Lstroke} % 0141 LATIN CAPITAL LETTER L WITH STROKE +\defineactivetoken 164 {\texteuro} % 20AC EURO SIGN +\defineactivetoken 165 {\quotedblbase} % 201E DOUBLE LOW-9 QUOTATION MARK +\defineactivetoken 166 {\Scaron} % 0160 LATIN CAPITAL LETTER S WITH CARON +\defineactivetoken 167 {\sectionmark} % 00A7 SECTION SIGN +\defineactivetoken 168 {\scaron} % 0161 LATIN SMALL LETTER S WITH CARON +\defineactivetoken 169 {\copyright} % 00A9 COPYRIGHT SIGN +\defineactivetoken 170 {\Scommaaccent} % 0218 LATIN CAPITAL LETTER S WITH COMMA BELOW +\defineactivetoken 171 {\leftguillemot} % 00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 172 {\Zacute} % 0179 LATIN CAPITAL LETTER Z WITH ACUTE +\defineactivetoken 173 {\softhyphen} % 00AD SOFT HYPHEN +\defineactivetoken 174 {\zacute} % 017A LATIN SMALL LETTER Z WITH ACUTE +\defineactivetoken 175 {\Zdotaccent} % 017B LATIN CAPITAL LETTER Z WITH DOT ABOVE +\defineactivetoken 176 {\textdegree} % 00B0 DEGREE SIGN +\defineactivetoken 177 {\textpm} % 00B1 PLUS-MINUS SIGN +\defineactivetoken 178 {\Ccaron} % 010C LATIN CAPITAL LETTER C WITH CARON +\defineactivetoken 179 {\lstroke} % 0142 LATIN SMALL LETTER L WITH STROKE +\defineactivetoken 180 {\Zcaron} % 017D LATIN CAPITAL LETTER Z WITH CARON +\defineactivetoken 181 {\quotedblright} % 201D RIGHT DOUBLE QUOTATION MARK +\defineactivetoken 182 {\paragraphmark} % 00B6 PILCROW SIGN +\defineactivetoken 183 {\periodcentered} % 00B7 MIDDLE DOT +\defineactivetoken 184 {\zcaron} % 017E LATIN SMALL LETTER Z WITH CARON +\defineactivetoken 185 {\ccaron} % 010D LATIN SMALL LETTER C WITH CARON +\defineactivetoken 186 {\scommaaccent} % 0219 LATIN SMALL LETTER S WITH COMMA BELOW +\defineactivetoken 187 {\rightguillemot} % 00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 188 {\OEligature} % 0152 LATIN CAPITAL LIGATURE OE +\defineactivetoken 189 {\oeligature} % 0153 LATIN SMALL LIGATURE OE +\defineactivetoken 190 {\Ydiaeresis} % 0178 LATIN CAPITAL LETTER Y WITH DIAERESIS +\defineactivetoken 191 {\zdotaccent} % 017C LATIN SMALL LETTER Z WITH DOT ABOVE +\defineactivetoken 192 {\Agrave} % 00C0 LATIN CAPITAL LETTER A WITH GRAVE +\defineactivetoken 193 {\Aacute} % 00C1 LATIN CAPITAL LETTER A WITH ACUTE +\defineactivetoken 194 {\Acircumflex} % 00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX +\defineactivetoken 195 {\Abreve} % 0102 LATIN CAPITAL LETTER A WITH BREVE +\defineactivetoken 196 {\Adiaeresis} % 00C4 LATIN CAPITAL LETTER A WITH DIAERESIS +\defineactivetoken 197 {\Cacute} % 0106 LATIN CAPITAL LETTER C WITH ACUTE +\defineactivetoken 198 {\AEligature} % 00C6 LATIN CAPITAL LETTER AE +\defineactivetoken 199 {\Ccedilla} % 00C7 LATIN CAPITAL LETTER C WITH CEDILLA +\defineactivetoken 200 {\Egrave} % 00C8 LATIN CAPITAL LETTER E WITH GRAVE +\defineactivetoken 201 {\Eacute} % 00C9 LATIN CAPITAL LETTER E WITH ACUTE +\defineactivetoken 202 {\Ecircumflex} % 00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX +\defineactivetoken 203 {\Ediaeresis} % 00CB LATIN CAPITAL LETTER E WITH DIAERESIS +\defineactivetoken 204 {\Igrave} % 00CC LATIN CAPITAL LETTER I WITH GRAVE +\defineactivetoken 205 {\Iacute} % 00CD LATIN CAPITAL LETTER I WITH ACUTE +\defineactivetoken 206 {\Icircumflex} % 00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX +\defineactivetoken 207 {\Idiaeresis} % 00CF LATIN CAPITAL LETTER I WITH DIAERESIS +\defineactivetoken 208 {\Dstroke} % 0110 LATIN CAPITAL LETTER D WITH STROKE +\defineactivetoken 209 {\Nacute} % 0143 LATIN CAPITAL LETTER N WITH ACUTE +\defineactivetoken 210 {\Ograve} % 00D2 LATIN CAPITAL LETTER O WITH GRAVE +\defineactivetoken 211 {\Oacute} % 00D3 LATIN CAPITAL LETTER O WITH ACUTE +\defineactivetoken 212 {\Ocircumflex} % 00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX +\defineactivetoken 213 {\Ohungarumlaut} % 0150 LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +\defineactivetoken 214 {\Odiaeresis} % 00D6 LATIN CAPITAL LETTER O WITH DIAERESIS +\defineactivetoken 215 {\Sacute} % 015A LATIN CAPITAL LETTER S WITH ACUTE +\defineactivetoken 216 {\Uhungarumlaut} % 0170 LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +\defineactivetoken 217 {\Ugrave} % 00D9 LATIN CAPITAL LETTER U WITH GRAVE +\defineactivetoken 218 {\Uacute} % 00DA LATIN CAPITAL LETTER U WITH ACUTE +\defineactivetoken 219 {\Ucircumflex} % 00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX +\defineactivetoken 220 {\Udiaeresis} % 00DC LATIN CAPITAL LETTER U WITH DIAERESIS +\defineactivetoken 221 {\Eogonek} % 0118 LATIN CAPITAL LETTER E WITH OGONEK +\defineactivetoken 222 {\Tcommaaccent} % 021A LATIN CAPITAL LETTER T WITH COMMA BELOW +\defineactivetoken 223 {\ssharp} % 00DF LATIN SMALL LETTER SHARP S +\defineactivetoken 224 {\agrave} % 00E0 LATIN SMALL LETTER A WITH GRAVE +\defineactivetoken 225 {\aacute} % 00E1 LATIN SMALL LETTER A WITH ACUTE +\defineactivetoken 226 {\acircumflex} % 00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX +\defineactivetoken 227 {\abreve} % 0103 LATIN SMALL LETTER A WITH BREVE +\defineactivetoken 228 {\adiaeresis} % 00E4 LATIN SMALL LETTER A WITH DIAERESIS +\defineactivetoken 229 {\cacute} % 0107 LATIN SMALL LETTER C WITH ACUTE +\defineactivetoken 230 {\aeligature} % 00E6 LATIN SMALL LETTER AE +\defineactivetoken 231 {\ccedilla} % 00E7 LATIN SMALL LETTER C WITH CEDILLA +\defineactivetoken 232 {\egrave} % 00E8 LATIN SMALL LETTER E WITH GRAVE +\defineactivetoken 233 {\eacute} % 00E9 LATIN SMALL LETTER E WITH ACUTE +\defineactivetoken 234 {\ecircumflex} % 00EA LATIN SMALL LETTER E WITH CIRCUMFLEX +\defineactivetoken 235 {\ediaeresis} % 00EB LATIN SMALL LETTER E WITH DIAERESIS +\defineactivetoken 236 {\igrave} % 00EC LATIN SMALL LETTER I WITH GRAVE +\defineactivetoken 237 {\iacute} % 00ED LATIN SMALL LETTER I WITH ACUTE +\defineactivetoken 238 {\icircumflex} % 00EE LATIN SMALL LETTER I WITH CIRCUMFLEX +\defineactivetoken 239 {\idiaeresis} % 00EF LATIN SMALL LETTER I WITH DIAERESIS +\defineactivetoken 240 {\dstroke} % 0111 LATIN SMALL LETTER D WITH STROKE +\defineactivetoken 241 {\nacute} % 0144 LATIN SMALL LETTER N WITH ACUTE +\defineactivetoken 242 {\ograve} % 00F2 LATIN SMALL LETTER O WITH GRAVE +\defineactivetoken 243 {\oacute} % 00F3 LATIN SMALL LETTER O WITH ACUTE +\defineactivetoken 244 {\ocircumflex} % 00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX +\defineactivetoken 245 {\ohungarumlaut} % 0151 LATIN SMALL LETTER O WITH DOUBLE ACUTE +\defineactivetoken 246 {\odiaeresis} % 00F6 LATIN SMALL LETTER O WITH DIAERESIS +\defineactivetoken 247 {\sacute} % 015B LATIN SMALL LETTER S WITH ACUTE +\defineactivetoken 248 {\uhungarumlaut} % 0171 LATIN SMALL LETTER U WITH DOUBLE ACUTE +\defineactivetoken 249 {\ugrave} % 00F9 LATIN SMALL LETTER U WITH GRAVE +\defineactivetoken 250 {\uacute} % 00FA LATIN SMALL LETTER U WITH ACUTE +\defineactivetoken 251 {\ucircumflex} % 00FB LATIN SMALL LETTER U WITH CIRCUMFLEX +\defineactivetoken 252 {\udiaeresis} % 00FC LATIN SMALL LETTER U WITH DIAERESIS +\defineactivetoken 253 {\eogonek} % 0119 LATIN SMALL LETTER E WITH OGONEK +\defineactivetoken 254 {\tcommaaccent} % 021B LATIN SMALL LETTER T WITH COMMA BELOW +\defineactivetoken 255 {\ydiaeresis} % 00FF LATIN SMALL LETTER Y WITH DIAERESIS + +\stopregime + diff --git a/tex/context/base/regi-8859-2.lua b/tex/context/base/regi-8859-2.lua new file mode 100644 index 000000000..7ae59d0fa --- /dev/null +++ b/tex/context/base/regi-8859-2.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-8859-2'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["8859-2"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7, 0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B, + 0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7, 0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C, + 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, + 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, + 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F, + 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9 +} diff --git a/tex/context/base/regi-8859-2.mkii b/tex/context/base/regi-8859-2.mkii new file mode 100644 index 000000000..81fe8419e --- /dev/null +++ b/tex/context/base/regi-8859-2.mkii @@ -0,0 +1,152 @@ +%D \module +%D [ file=regi-8859-2, +%D version=2005.12.26, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=iso-8859-2 (East European), +%D author=script-generated, +%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. + +%D Support for iso-8859-2/Latin2 input encoding (regime) for +%D Central European languages, see also cp1250. +%D +%D Usage: \type{\enableregime[8859-2]} (see \type {regi-syn} for +%D alternatives calls). + +\startregime[8859-2] + +\defineactivetoken 128 {\unknownchar} % 0080 +\defineactivetoken 129 {\unknownchar} % 0081 +\defineactivetoken 130 {\unknownchar} % 0082 +\defineactivetoken 131 {\unknownchar} % 0083 +\defineactivetoken 132 {\unknownchar} % 0084 +\defineactivetoken 133 {\unknownchar} % 0085 +\defineactivetoken 134 {\unknownchar} % 0086 +\defineactivetoken 135 {\unknownchar} % 0087 +\defineactivetoken 136 {\unknownchar} % 0088 +\defineactivetoken 137 {\unknownchar} % 0089 +\defineactivetoken 138 {\unknownchar} % 008A +\defineactivetoken 139 {\unknownchar} % 008B +\defineactivetoken 140 {\unknownchar} % 008C +\defineactivetoken 141 {\unknownchar} % 008D +\defineactivetoken 142 {\unknownchar} % 008E +\defineactivetoken 143 {\unknownchar} % 008F +\defineactivetoken 144 {\unknownchar} % 0090 +\defineactivetoken 145 {\unknownchar} % 0091 +\defineactivetoken 146 {\unknownchar} % 0092 +\defineactivetoken 147 {\unknownchar} % 0093 +\defineactivetoken 148 {\unknownchar} % 0094 +\defineactivetoken 149 {\unknownchar} % 0095 +\defineactivetoken 150 {\unknownchar} % 0096 +\defineactivetoken 151 {\unknownchar} % 0097 +\defineactivetoken 152 {\unknownchar} % 0098 +\defineactivetoken 153 {\unknownchar} % 0099 +\defineactivetoken 154 {\unknownchar} % 009A +\defineactivetoken 155 {\unknownchar} % 009B +\defineactivetoken 156 {\unknownchar} % 009C +\defineactivetoken 157 {\unknownchar} % 009D +\defineactivetoken 158 {\unknownchar} % 009E +\defineactivetoken 159 {\unknownchar} % 009F +\defineactivetoken 160 {\nonbreakablespace} % 00A0 NO-BREAK SPACE +\defineactivetoken 161 {\Aogonek} % 0104 LATIN CAPITAL LETTER A WITH OGONEK +\defineactivetoken 162 {\textbreve} % 02D8 BREVE +\defineactivetoken 163 {\Lstroke} % 0141 LATIN CAPITAL LETTER L WITH STROKE +\defineactivetoken 164 {\textcurrency} % 00A4 CURRENCY SIGN +\defineactivetoken 165 {\Lcaron} % 013D LATIN CAPITAL LETTER L WITH CARON +\defineactivetoken 166 {\Sacute} % 015A LATIN CAPITAL LETTER S WITH ACUTE +\defineactivetoken 167 {\sectionmark} % 00A7 SECTION SIGN +\defineactivetoken 168 {\textdiaeresis} % 00A8 DIAERESIS +\defineactivetoken 169 {\Scaron} % 0160 LATIN CAPITAL LETTER S WITH CARON +\defineactivetoken 170 {\Scedilla} % 015E LATIN CAPITAL LETTER S WITH CEDILLA +\defineactivetoken 171 {\Tcaron} % 0164 LATIN CAPITAL LETTER T WITH CARON +\defineactivetoken 172 {\Zacute} % 0179 LATIN CAPITAL LETTER Z WITH ACUTE +\defineactivetoken 173 {\softhyphen} % 00AD SOFT HYPHEN +\defineactivetoken 174 {\Zcaron} % 017D LATIN CAPITAL LETTER Z WITH CARON +\defineactivetoken 175 {\Zdotaccent} % 017B LATIN CAPITAL LETTER Z WITH DOT ABOVE +\defineactivetoken 176 {\textdegree} % 00B0 DEGREE SIGN +\defineactivetoken 177 {\aogonek} % 0105 LATIN SMALL LETTER A WITH OGONEK +\defineactivetoken 178 {\textogonek} % 02DB OGONEK +\defineactivetoken 179 {\lstroke} % 0142 LATIN SMALL LETTER L WITH STROKE +\defineactivetoken 180 {\textacute} % 00B4 ACUTE ACCENT +\defineactivetoken 181 {\lcaron} % 013E LATIN SMALL LETTER L WITH CARON +\defineactivetoken 182 {\sacute} % 015B LATIN SMALL LETTER S WITH ACUTE +\defineactivetoken 183 {\textcaron} % 02C7 CARON +\defineactivetoken 184 {\textcedilla} % 00B8 CEDILLA +\defineactivetoken 185 {\scaron} % 0161 LATIN SMALL LETTER S WITH CARON +\defineactivetoken 186 {\scedilla} % 015F LATIN SMALL LETTER S WITH CEDILLA +\defineactivetoken 187 {\tcaron} % 0165 LATIN SMALL LETTER T WITH CARON +\defineactivetoken 188 {\zacute} % 017A LATIN SMALL LETTER Z WITH ACUTE +\defineactivetoken 189 {\texthungarumlaut} % 02DD DOUBLE ACUTE ACCENT +\defineactivetoken 190 {\zcaron} % 017E LATIN SMALL LETTER Z WITH CARON +\defineactivetoken 191 {\zdotaccent} % 017C LATIN SMALL LETTER Z WITH DOT ABOVE +\defineactivetoken 192 {\Racute} % 0154 LATIN CAPITAL LETTER R WITH ACUTE +\defineactivetoken 193 {\Aacute} % 00C1 LATIN CAPITAL LETTER A WITH ACUTE +\defineactivetoken 194 {\Acircumflex} % 00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX +\defineactivetoken 195 {\Abreve} % 0102 LATIN CAPITAL LETTER A WITH BREVE +\defineactivetoken 196 {\Adiaeresis} % 00C4 LATIN CAPITAL LETTER A WITH DIAERESIS +\defineactivetoken 197 {\Lacute} % 0139 LATIN CAPITAL LETTER L WITH ACUTE +\defineactivetoken 198 {\Cacute} % 0106 LATIN CAPITAL LETTER C WITH ACUTE +\defineactivetoken 199 {\Ccedilla} % 00C7 LATIN CAPITAL LETTER C WITH CEDILLA +\defineactivetoken 200 {\Ccaron} % 010C LATIN CAPITAL LETTER C WITH CARON +\defineactivetoken 201 {\Eacute} % 00C9 LATIN CAPITAL LETTER E WITH ACUTE +\defineactivetoken 202 {\Eogonek} % 0118 LATIN CAPITAL LETTER E WITH OGONEK +\defineactivetoken 203 {\Ediaeresis} % 00CB LATIN CAPITAL LETTER E WITH DIAERESIS +\defineactivetoken 204 {\Ecaron} % 011A LATIN CAPITAL LETTER E WITH CARON +\defineactivetoken 205 {\Iacute} % 00CD LATIN CAPITAL LETTER I WITH ACUTE +\defineactivetoken 206 {\Icircumflex} % 00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX +\defineactivetoken 207 {\Dcaron} % 010E LATIN CAPITAL LETTER D WITH CARON +\defineactivetoken 208 {\Dstroke} % 0110 LATIN CAPITAL LETTER D WITH STROKE +\defineactivetoken 209 {\Nacute} % 0143 LATIN CAPITAL LETTER N WITH ACUTE +\defineactivetoken 210 {\Ncaron} % 0147 LATIN CAPITAL LETTER N WITH CARON +\defineactivetoken 211 {\Oacute} % 00D3 LATIN CAPITAL LETTER O WITH ACUTE +\defineactivetoken 212 {\Ocircumflex} % 00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX +\defineactivetoken 213 {\Ohungarumlaut} % 0150 LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +\defineactivetoken 214 {\Odiaeresis} % 00D6 LATIN CAPITAL LETTER O WITH DIAERESIS +\defineactivetoken 215 {\textmultiply} % 00D7 MULTIPLICATION SIGN +\defineactivetoken 216 {\Rcaron} % 0158 LATIN CAPITAL LETTER R WITH CARON +\defineactivetoken 217 {\Uring} % 016E LATIN CAPITAL LETTER U WITH RING ABOVE +\defineactivetoken 218 {\Uacute} % 00DA LATIN CAPITAL LETTER U WITH ACUTE +\defineactivetoken 219 {\Uhungarumlaut} % 0170 LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +\defineactivetoken 220 {\Udiaeresis} % 00DC LATIN CAPITAL LETTER U WITH DIAERESIS +\defineactivetoken 221 {\Yacute} % 00DD LATIN CAPITAL LETTER Y WITH ACUTE +\defineactivetoken 222 {\Tcedilla} % 0162 LATIN CAPITAL LETTER T WITH CEDILLA +\defineactivetoken 223 {\ssharp} % 00DF LATIN SMALL LETTER SHARP S +\defineactivetoken 224 {\racute} % 0155 LATIN SMALL LETTER R WITH ACUTE +\defineactivetoken 225 {\aacute} % 00E1 LATIN SMALL LETTER A WITH ACUTE +\defineactivetoken 226 {\acircumflex} % 00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX +\defineactivetoken 227 {\abreve} % 0103 LATIN SMALL LETTER A WITH BREVE +\defineactivetoken 228 {\adiaeresis} % 00E4 LATIN SMALL LETTER A WITH DIAERESIS +\defineactivetoken 229 {\lacute} % 013A LATIN SMALL LETTER L WITH ACUTE +\defineactivetoken 230 {\cacute} % 0107 LATIN SMALL LETTER C WITH ACUTE +\defineactivetoken 231 {\ccedilla} % 00E7 LATIN SMALL LETTER C WITH CEDILLA +\defineactivetoken 232 {\ccaron} % 010D LATIN SMALL LETTER C WITH CARON +\defineactivetoken 233 {\eacute} % 00E9 LATIN SMALL LETTER E WITH ACUTE +\defineactivetoken 234 {\eogonek} % 0119 LATIN SMALL LETTER E WITH OGONEK +\defineactivetoken 235 {\ediaeresis} % 00EB LATIN SMALL LETTER E WITH DIAERESIS +\defineactivetoken 236 {\ecaron} % 011B LATIN SMALL LETTER E WITH CARON +\defineactivetoken 237 {\iacute} % 00ED LATIN SMALL LETTER I WITH ACUTE +\defineactivetoken 238 {\icircumflex} % 00EE LATIN SMALL LETTER I WITH CIRCUMFLEX +\defineactivetoken 239 {\dcaron} % 010F LATIN SMALL LETTER D WITH CARON +\defineactivetoken 240 {\dstroke} % 0111 LATIN SMALL LETTER D WITH STROKE +\defineactivetoken 241 {\nacute} % 0144 LATIN SMALL LETTER N WITH ACUTE +\defineactivetoken 242 {\ncaron} % 0148 LATIN SMALL LETTER N WITH CARON +\defineactivetoken 243 {\oacute} % 00F3 LATIN SMALL LETTER O WITH ACUTE +\defineactivetoken 244 {\ocircumflex} % 00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX +\defineactivetoken 245 {\ohungarumlaut} % 0151 LATIN SMALL LETTER O WITH DOUBLE ACUTE +\defineactivetoken 246 {\odiaeresis} % 00F6 LATIN SMALL LETTER O WITH DIAERESIS +\defineactivetoken 247 {\textdiv} % 00F7 DIVISION SIGN +\defineactivetoken 248 {\rcaron} % 0159 LATIN SMALL LETTER R WITH CARON +\defineactivetoken 249 {\uring} % 016F LATIN SMALL LETTER U WITH RING ABOVE +\defineactivetoken 250 {\uacute} % 00FA LATIN SMALL LETTER U WITH ACUTE +\defineactivetoken 251 {\uhungarumlaut} % 0171 LATIN SMALL LETTER U WITH DOUBLE ACUTE +\defineactivetoken 252 {\udiaeresis} % 00FC LATIN SMALL LETTER U WITH DIAERESIS +\defineactivetoken 253 {\yacute} % 00FD LATIN SMALL LETTER Y WITH ACUTE +\defineactivetoken 254 {\tcedilla} % 0163 LATIN SMALL LETTER T WITH CEDILLA +\defineactivetoken 255 {\textdotaccent} % 02D9 DOT ABOVE + +\stopregime + diff --git a/tex/context/base/regi-8859-3.lua b/tex/context/base/regi-8859-3.lua new file mode 100644 index 000000000..a83d63bac --- /dev/null +++ b/tex/context/base/regi-8859-3.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-8859-3'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["8859-3"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x0126, 0x02D8, 0x00A3, 0x00A4, 0x0000, 0x0124, 0x00A7, 0x00A8, 0x0130, 0x015E, 0x011E, 0x0134, 0x00AD, 0x0000, 0x017B, + 0x00B0, 0x0127, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x0125, 0x00B7, 0x00B8, 0x0131, 0x015F, 0x011F, 0x0135, 0x00BD, 0x0000, 0x017C, + 0x00C0, 0x00C1, 0x00C2, 0x0000, 0x00C4, 0x010A, 0x0108, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x0000, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x0120, 0x00D6, 0x00D7, 0x011C, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x016C, 0x015C, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x0000, 0x00E4, 0x010B, 0x0109, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x0000, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x0121, 0x00F6, 0x00F7, 0x011D, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x016D, 0x015D, 0x02D9 +} diff --git a/tex/context/base/regi-8859-3.mkii b/tex/context/base/regi-8859-3.mkii new file mode 100644 index 000000000..dcb8be67f --- /dev/null +++ b/tex/context/base/regi-8859-3.mkii @@ -0,0 +1,145 @@ +%D \module +%D [ file=regi-8859-3, +%D version=2005.12.26, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=iso-8859-3 (South European), +%D author=script-generated, +%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. + +%D Support for iso-8859-3/Latin3 input encoding (regime) for South +%D European languages, esp. for Esperanto and Maltese. +%D +%D Usage: \type{\enableregime[8859-3]} (see \type {regi-syn} for +%D alternatives calls). + +\startregime[8859-3] + +\defineactivetoken 128 {\unknownchar} % 0080 +\defineactivetoken 129 {\unknownchar} % 0081 +\defineactivetoken 130 {\unknownchar} % 0082 +\defineactivetoken 131 {\unknownchar} % 0083 +\defineactivetoken 132 {\unknownchar} % 0084 +\defineactivetoken 133 {\unknownchar} % 0085 +\defineactivetoken 134 {\unknownchar} % 0086 +\defineactivetoken 135 {\unknownchar} % 0087 +\defineactivetoken 136 {\unknownchar} % 0088 +\defineactivetoken 137 {\unknownchar} % 0089 +\defineactivetoken 138 {\unknownchar} % 008A +\defineactivetoken 139 {\unknownchar} % 008B +\defineactivetoken 140 {\unknownchar} % 008C +\defineactivetoken 141 {\unknownchar} % 008D +\defineactivetoken 142 {\unknownchar} % 008E +\defineactivetoken 143 {\unknownchar} % 008F +\defineactivetoken 144 {\unknownchar} % 0090 +\defineactivetoken 145 {\unknownchar} % 0091 +\defineactivetoken 146 {\unknownchar} % 0092 +\defineactivetoken 147 {\unknownchar} % 0093 +\defineactivetoken 148 {\unknownchar} % 0094 +\defineactivetoken 149 {\unknownchar} % 0095 +\defineactivetoken 150 {\unknownchar} % 0096 +\defineactivetoken 151 {\unknownchar} % 0097 +\defineactivetoken 152 {\unknownchar} % 0098 +\defineactivetoken 153 {\unknownchar} % 0099 +\defineactivetoken 154 {\unknownchar} % 009A +\defineactivetoken 155 {\unknownchar} % 009B +\defineactivetoken 156 {\unknownchar} % 009C +\defineactivetoken 157 {\unknownchar} % 009D +\defineactivetoken 158 {\unknownchar} % 009E +\defineactivetoken 159 {\unknownchar} % 009F +\defineactivetoken 160 {\nonbreakablespace} % 00A0 NO-BREAK SPACE +\defineactivetoken 161 {\Hstroke} % 0126 LATIN CAPITAL LETTER H WITH STROKE +\defineactivetoken 162 {\textbreve} % 02D8 BREVE +\defineactivetoken 163 {\textsterling} % 00A3 POUND SIGN +\defineactivetoken 164 {\textcurrency} % 00A4 CURRENCY SIGN +\defineactivetoken 166 {\Hcircumflex} % 0124 LATIN CAPITAL LETTER H WITH CIRCUMFLEX +\defineactivetoken 167 {\sectionmark} % 00A7 SECTION SIGN +\defineactivetoken 168 {\textdiaeresis} % 00A8 DIAERESIS +\defineactivetoken 169 {\Idotaccent} % 0130 LATIN CAPITAL LETTER I WITH DOT ABOVE +\defineactivetoken 170 {\Scedilla} % 015E LATIN CAPITAL LETTER S WITH CEDILLA +\defineactivetoken 171 {\Gbreve} % 011E LATIN CAPITAL LETTER G WITH BREVE +\defineactivetoken 172 {\Jcircumflex} % 0134 LATIN CAPITAL LETTER J WITH CIRCUMFLEX +\defineactivetoken 173 {\softhyphen} % 00AD SOFT HYPHEN +\defineactivetoken 175 {\Zdotaccent} % 017B LATIN CAPITAL LETTER Z WITH DOT ABOVE +\defineactivetoken 176 {\textdegree} % 00B0 DEGREE SIGN +\defineactivetoken 177 {\hstroke} % 0127 LATIN SMALL LETTER H WITH STROKE +\defineactivetoken 178 {\twosuperior} % 00B2 SUPERSCRIPT TWO +\defineactivetoken 179 {\threesuperior} % 00B3 SUPERSCRIPT THREE +\defineactivetoken 180 {\textacute} % 00B4 ACUTE ACCENT +\defineactivetoken 181 {\textmu} % 00B5 MICRO SIGN +\defineactivetoken 182 {\hcircumflex} % 0125 LATIN SMALL LETTER H WITH CIRCUMFLEX +\defineactivetoken 183 {\periodcentered} % 00B7 MIDDLE DOT +\defineactivetoken 184 {\textcedilla} % 00B8 CEDILLA +\defineactivetoken 185 {\dotlessi} % 0131 LATIN SMALL LETTER DOTLESS I +\defineactivetoken 186 {\scedilla} % 015F LATIN SMALL LETTER S WITH CEDILLA +\defineactivetoken 187 {\gbreve} % 011F LATIN SMALL LETTER G WITH BREVE +\defineactivetoken 188 {\jcircumflex} % 0135 LATIN SMALL LETTER J WITH CIRCUMFLEX +\defineactivetoken 189 {\onehalf} % 00BD VULGAR FRACTION ONE HALF +\defineactivetoken 191 {\zdotaccent} % 017C LATIN SMALL LETTER Z WITH DOT ABOVE +\defineactivetoken 192 {\Agrave} % 00C0 LATIN CAPITAL LETTER A WITH GRAVE +\defineactivetoken 193 {\Aacute} % 00C1 LATIN CAPITAL LETTER A WITH ACUTE +\defineactivetoken 194 {\Acircumflex} % 00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX +\defineactivetoken 196 {\Adiaeresis} % 00C4 LATIN CAPITAL LETTER A WITH DIAERESIS +\defineactivetoken 197 {\Cdotaccent} % 010A LATIN CAPITAL LETTER C WITH DOT ABOVE +\defineactivetoken 198 {\Ccircumflex} % 0108 LATIN CAPITAL LETTER C WITH CIRCUMFLEX +\defineactivetoken 199 {\Ccedilla} % 00C7 LATIN CAPITAL LETTER C WITH CEDILLA +\defineactivetoken 200 {\Egrave} % 00C8 LATIN CAPITAL LETTER E WITH GRAVE +\defineactivetoken 201 {\Eacute} % 00C9 LATIN CAPITAL LETTER E WITH ACUTE +\defineactivetoken 202 {\Ecircumflex} % 00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX +\defineactivetoken 203 {\Ediaeresis} % 00CB LATIN CAPITAL LETTER E WITH DIAERESIS +\defineactivetoken 204 {\Igrave} % 00CC LATIN CAPITAL LETTER I WITH GRAVE +\defineactivetoken 205 {\Iacute} % 00CD LATIN CAPITAL LETTER I WITH ACUTE +\defineactivetoken 206 {\Icircumflex} % 00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX +\defineactivetoken 207 {\Idiaeresis} % 00CF LATIN CAPITAL LETTER I WITH DIAERESIS +\defineactivetoken 209 {\Ntilde} % 00D1 LATIN CAPITAL LETTER N WITH TILDE +\defineactivetoken 210 {\Ograve} % 00D2 LATIN CAPITAL LETTER O WITH GRAVE +\defineactivetoken 211 {\Oacute} % 00D3 LATIN CAPITAL LETTER O WITH ACUTE +\defineactivetoken 212 {\Ocircumflex} % 00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX +\defineactivetoken 213 {\Gdotaccent} % 0120 LATIN CAPITAL LETTER G WITH DOT ABOVE +\defineactivetoken 214 {\Odiaeresis} % 00D6 LATIN CAPITAL LETTER O WITH DIAERESIS +\defineactivetoken 215 {\textmultiply} % 00D7 MULTIPLICATION SIGN +\defineactivetoken 216 {\Gcircumflex} % 011C LATIN CAPITAL LETTER G WITH CIRCUMFLEX +\defineactivetoken 217 {\Ugrave} % 00D9 LATIN CAPITAL LETTER U WITH GRAVE +\defineactivetoken 218 {\Uacute} % 00DA LATIN CAPITAL LETTER U WITH ACUTE +\defineactivetoken 219 {\Ucircumflex} % 00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX +\defineactivetoken 220 {\Udiaeresis} % 00DC LATIN CAPITAL LETTER U WITH DIAERESIS +\defineactivetoken 221 {\Ubreve} % 016C LATIN CAPITAL LETTER U WITH BREVE +\defineactivetoken 222 {\Scircumflex} % 015C LATIN CAPITAL LETTER S WITH CIRCUMFLEX +\defineactivetoken 223 {\ssharp} % 00DF LATIN SMALL LETTER SHARP S +\defineactivetoken 224 {\agrave} % 00E0 LATIN SMALL LETTER A WITH GRAVE +\defineactivetoken 225 {\aacute} % 00E1 LATIN SMALL LETTER A WITH ACUTE +\defineactivetoken 226 {\acircumflex} % 00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX +\defineactivetoken 228 {\adiaeresis} % 00E4 LATIN SMALL LETTER A WITH DIAERESIS +\defineactivetoken 229 {\cdotaccent} % 010B LATIN SMALL LETTER C WITH DOT ABOVE +\defineactivetoken 230 {\ccircumflex} % 0109 LATIN SMALL LETTER C WITH CIRCUMFLEX +\defineactivetoken 231 {\ccedilla} % 00E7 LATIN SMALL LETTER C WITH CEDILLA +\defineactivetoken 232 {\egrave} % 00E8 LATIN SMALL LETTER E WITH GRAVE +\defineactivetoken 233 {\eacute} % 00E9 LATIN SMALL LETTER E WITH ACUTE +\defineactivetoken 234 {\ecircumflex} % 00EA LATIN SMALL LETTER E WITH CIRCUMFLEX +\defineactivetoken 235 {\ediaeresis} % 00EB LATIN SMALL LETTER E WITH DIAERESIS +\defineactivetoken 236 {\igrave} % 00EC LATIN SMALL LETTER I WITH GRAVE +\defineactivetoken 237 {\iacute} % 00ED LATIN SMALL LETTER I WITH ACUTE +\defineactivetoken 238 {\icircumflex} % 00EE LATIN SMALL LETTER I WITH CIRCUMFLEX +\defineactivetoken 239 {\idiaeresis} % 00EF LATIN SMALL LETTER I WITH DIAERESIS +\defineactivetoken 241 {\ntilde} % 00F1 LATIN SMALL LETTER N WITH TILDE +\defineactivetoken 242 {\ograve} % 00F2 LATIN SMALL LETTER O WITH GRAVE +\defineactivetoken 243 {\oacute} % 00F3 LATIN SMALL LETTER O WITH ACUTE +\defineactivetoken 244 {\ocircumflex} % 00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX +\defineactivetoken 245 {\gdotaccent} % 0121 LATIN SMALL LETTER G WITH DOT ABOVE +\defineactivetoken 246 {\odiaeresis} % 00F6 LATIN SMALL LETTER O WITH DIAERESIS +\defineactivetoken 247 {\textdiv} % 00F7 DIVISION SIGN +\defineactivetoken 248 {\gcircumflex} % 011D LATIN SMALL LETTER G WITH CIRCUMFLEX +\defineactivetoken 249 {\ugrave} % 00F9 LATIN SMALL LETTER U WITH GRAVE +\defineactivetoken 250 {\uacute} % 00FA LATIN SMALL LETTER U WITH ACUTE +\defineactivetoken 251 {\ucircumflex} % 00FB LATIN SMALL LETTER U WITH CIRCUMFLEX +\defineactivetoken 252 {\udiaeresis} % 00FC LATIN SMALL LETTER U WITH DIAERESIS +\defineactivetoken 253 {\ubreve} % 016D LATIN SMALL LETTER U WITH BREVE +\defineactivetoken 254 {\scircumflex} % 015D LATIN SMALL LETTER S WITH CIRCUMFLEX +\defineactivetoken 255 {\textdotaccent} % 02D9 DOT ABOVE + +\stopregime + diff --git a/tex/context/base/regi-8859-4.lua b/tex/context/base/regi-8859-4.lua new file mode 100644 index 000000000..939d55026 --- /dev/null +++ b/tex/context/base/regi-8859-4.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-8859-4'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["8859-4"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x0104, 0x0138, 0x0156, 0x00A4, 0x0128, 0x013B, 0x00A7, 0x00A8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00AD, 0x017D, 0x00AF, + 0x00B0, 0x0105, 0x02DB, 0x0157, 0x00B4, 0x0129, 0x013C, 0x02C7, 0x00B8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014A, 0x017E, 0x014B, + 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E, 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x012A, + 0x0110, 0x0145, 0x014C, 0x0136, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x0168, 0x016A, 0x00DF, + 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F, 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x012B, + 0x0111, 0x0146, 0x014D, 0x0137, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x0169, 0x016B, 0x02D9 +} diff --git a/tex/context/base/regi-8859-4.mkii b/tex/context/base/regi-8859-4.mkii new file mode 100644 index 000000000..3ebe66a13 --- /dev/null +++ b/tex/context/base/regi-8859-4.mkii @@ -0,0 +1,152 @@ +%D \module +%D [ file=regi-8859-4, +%D version=2005.12.26, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=iso-8859-4 (North European), +%D author=script-generated, +%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. + +%D Support for iso-8859-4/Latin4 input encoding (regime) for West +%D European languages, see also cp1257 and iso-8859-13. +%D +%D Usage: \type{\enableregime[8859-4]} (see \type {regi-syn} for +%D alternatives calls). + +\startregime[8859-4] + +\defineactivetoken 128 {\unknownchar} % 0080 +\defineactivetoken 129 {\unknownchar} % 0081 +\defineactivetoken 130 {\unknownchar} % 0082 +\defineactivetoken 131 {\unknownchar} % 0083 +\defineactivetoken 132 {\unknownchar} % 0084 +\defineactivetoken 133 {\unknownchar} % 0085 +\defineactivetoken 134 {\unknownchar} % 0086 +\defineactivetoken 135 {\unknownchar} % 0087 +\defineactivetoken 136 {\unknownchar} % 0088 +\defineactivetoken 137 {\unknownchar} % 0089 +\defineactivetoken 138 {\unknownchar} % 008A +\defineactivetoken 139 {\unknownchar} % 008B +\defineactivetoken 140 {\unknownchar} % 008C +\defineactivetoken 141 {\unknownchar} % 008D +\defineactivetoken 142 {\unknownchar} % 008E +\defineactivetoken 143 {\unknownchar} % 008F +\defineactivetoken 144 {\unknownchar} % 0090 +\defineactivetoken 145 {\unknownchar} % 0091 +\defineactivetoken 146 {\unknownchar} % 0092 +\defineactivetoken 147 {\unknownchar} % 0093 +\defineactivetoken 148 {\unknownchar} % 0094 +\defineactivetoken 149 {\unknownchar} % 0095 +\defineactivetoken 150 {\unknownchar} % 0096 +\defineactivetoken 151 {\unknownchar} % 0097 +\defineactivetoken 152 {\unknownchar} % 0098 +\defineactivetoken 153 {\unknownchar} % 0099 +\defineactivetoken 154 {\unknownchar} % 009A +\defineactivetoken 155 {\unknownchar} % 009B +\defineactivetoken 156 {\unknownchar} % 009C +\defineactivetoken 157 {\unknownchar} % 009D +\defineactivetoken 158 {\unknownchar} % 009E +\defineactivetoken 159 {\unknownchar} % 009F +\defineactivetoken 160 {\nonbreakablespace} % 00A0 NO-BREAK SPACE +\defineactivetoken 161 {\Aogonek} % 0104 LATIN CAPITAL LETTER A WITH OGONEK +\defineactivetoken 162 {\kkra} % 0138 LATIN SMALL LETTER KRA +\defineactivetoken 163 {\Rcommaaccent} % 0156 LATIN CAPITAL LETTER R WITH CEDILLA +\defineactivetoken 164 {\textcurrency} % 00A4 CURRENCY SIGN +\defineactivetoken 165 {\Itilde} % 0128 LATIN CAPITAL LETTER I WITH TILDE +\defineactivetoken 166 {\Lcommaaccent} % 013B LATIN CAPITAL LETTER L WITH CEDILLA +\defineactivetoken 167 {\sectionmark} % 00A7 SECTION SIGN +\defineactivetoken 168 {\textdiaeresis} % 00A8 DIAERESIS +\defineactivetoken 169 {\Scaron} % 0160 LATIN CAPITAL LETTER S WITH CARON +\defineactivetoken 170 {\Emacron} % 0112 LATIN CAPITAL LETTER E WITH MACRON +\defineactivetoken 171 {\Gcommaaccent} % 0122 LATIN CAPITAL LETTER G WITH CEDILLA +\defineactivetoken 172 {\Tstroke} % 0166 LATIN CAPITAL LETTER T WITH STROKE +\defineactivetoken 173 {\softhyphen} % 00AD SOFT HYPHEN +\defineactivetoken 174 {\Zcaron} % 017D LATIN CAPITAL LETTER Z WITH CARON +\defineactivetoken 175 {\textmacron} % 00AF MACRON +\defineactivetoken 176 {\textdegree} % 00B0 DEGREE SIGN +\defineactivetoken 177 {\aogonek} % 0105 LATIN SMALL LETTER A WITH OGONEK +\defineactivetoken 178 {\textogonek} % 02DB OGONEK +\defineactivetoken 179 {\rcommaaccent} % 0157 LATIN SMALL LETTER R WITH CEDILLA +\defineactivetoken 180 {\textacute} % 00B4 ACUTE ACCENT +\defineactivetoken 181 {\itilde} % 0129 LATIN SMALL LETTER I WITH TILDE +\defineactivetoken 182 {\lcommaaccent} % 013C LATIN SMALL LETTER L WITH CEDILLA +\defineactivetoken 183 {\textcaron} % 02C7 CARON +\defineactivetoken 184 {\textcedilla} % 00B8 CEDILLA +\defineactivetoken 185 {\scaron} % 0161 LATIN SMALL LETTER S WITH CARON +\defineactivetoken 186 {\emacron} % 0113 LATIN SMALL LETTER E WITH MACRON +\defineactivetoken 187 {\gcommaaccent} % 0123 LATIN SMALL LETTER G WITH CEDILLA +\defineactivetoken 188 {\tstroke} % 0167 LATIN SMALL LETTER T WITH STROKE +\defineactivetoken 189 {\Neng} % 014A LATIN CAPITAL LETTER ENG +\defineactivetoken 190 {\zcaron} % 017E LATIN SMALL LETTER Z WITH CARON +\defineactivetoken 191 {\neng} % 014B LATIN SMALL LETTER ENG +\defineactivetoken 192 {\Amacron} % 0100 LATIN CAPITAL LETTER A WITH MACRON +\defineactivetoken 193 {\Aacute} % 00C1 LATIN CAPITAL LETTER A WITH ACUTE +\defineactivetoken 194 {\Acircumflex} % 00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX +\defineactivetoken 195 {\Atilde} % 00C3 LATIN CAPITAL LETTER A WITH TILDE +\defineactivetoken 196 {\Adiaeresis} % 00C4 LATIN CAPITAL LETTER A WITH DIAERESIS +\defineactivetoken 197 {\Aring} % 00C5 LATIN CAPITAL LETTER A WITH RING ABOVE +\defineactivetoken 198 {\AEligature} % 00C6 LATIN CAPITAL LETTER AE +\defineactivetoken 199 {\Iogonek} % 012E LATIN CAPITAL LETTER I WITH OGONEK +\defineactivetoken 200 {\Ccaron} % 010C LATIN CAPITAL LETTER C WITH CARON +\defineactivetoken 201 {\Eacute} % 00C9 LATIN CAPITAL LETTER E WITH ACUTE +\defineactivetoken 202 {\Eogonek} % 0118 LATIN CAPITAL LETTER E WITH OGONEK +\defineactivetoken 203 {\Ediaeresis} % 00CB LATIN CAPITAL LETTER E WITH DIAERESIS +\defineactivetoken 204 {\Edotaccent} % 0116 LATIN CAPITAL LETTER E WITH DOT ABOVE +\defineactivetoken 205 {\Iacute} % 00CD LATIN CAPITAL LETTER I WITH ACUTE +\defineactivetoken 206 {\Icircumflex} % 00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX +\defineactivetoken 207 {\Imacron} % 012A LATIN CAPITAL LETTER I WITH MACRON +\defineactivetoken 208 {\Dstroke} % 0110 LATIN CAPITAL LETTER D WITH STROKE +\defineactivetoken 209 {\Ncommaaccent} % 0145 LATIN CAPITAL LETTER N WITH CEDILLA +\defineactivetoken 210 {\Omacron} % 014C LATIN CAPITAL LETTER O WITH MACRON +\defineactivetoken 211 {\Kcommaaccent} % 0136 LATIN CAPITAL LETTER K WITH CEDILLA +\defineactivetoken 212 {\Ocircumflex} % 00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX +\defineactivetoken 213 {\Otilde} % 00D5 LATIN CAPITAL LETTER O WITH TILDE +\defineactivetoken 214 {\Odiaeresis} % 00D6 LATIN CAPITAL LETTER O WITH DIAERESIS +\defineactivetoken 215 {\textmultiply} % 00D7 MULTIPLICATION SIGN +\defineactivetoken 216 {\Ostroke} % 00D8 LATIN CAPITAL LETTER O WITH STROKE +\defineactivetoken 217 {\Uogonek} % 0172 LATIN CAPITAL LETTER U WITH OGONEK +\defineactivetoken 218 {\Uacute} % 00DA LATIN CAPITAL LETTER U WITH ACUTE +\defineactivetoken 219 {\Ucircumflex} % 00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX +\defineactivetoken 220 {\Udiaeresis} % 00DC LATIN CAPITAL LETTER U WITH DIAERESIS +\defineactivetoken 221 {\Utilde} % 0168 LATIN CAPITAL LETTER U WITH TILDE +\defineactivetoken 222 {\Umacron} % 016A LATIN CAPITAL LETTER U WITH MACRON +\defineactivetoken 223 {\ssharp} % 00DF LATIN SMALL LETTER SHARP S +\defineactivetoken 224 {\amacron} % 0101 LATIN SMALL LETTER A WITH MACRON +\defineactivetoken 225 {\aacute} % 00E1 LATIN SMALL LETTER A WITH ACUTE +\defineactivetoken 226 {\acircumflex} % 00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX +\defineactivetoken 227 {\atilde} % 00E3 LATIN SMALL LETTER A WITH TILDE +\defineactivetoken 228 {\adiaeresis} % 00E4 LATIN SMALL LETTER A WITH DIAERESIS +\defineactivetoken 229 {\aring} % 00E5 LATIN SMALL LETTER A WITH RING ABOVE +\defineactivetoken 230 {\aeligature} % 00E6 LATIN SMALL LETTER AE +\defineactivetoken 231 {\iogonek} % 012F LATIN SMALL LETTER I WITH OGONEK +\defineactivetoken 232 {\ccaron} % 010D LATIN SMALL LETTER C WITH CARON +\defineactivetoken 233 {\eacute} % 00E9 LATIN SMALL LETTER E WITH ACUTE +\defineactivetoken 234 {\eogonek} % 0119 LATIN SMALL LETTER E WITH OGONEK +\defineactivetoken 235 {\ediaeresis} % 00EB LATIN SMALL LETTER E WITH DIAERESIS +\defineactivetoken 236 {\edotaccent} % 0117 LATIN SMALL LETTER E WITH DOT ABOVE +\defineactivetoken 237 {\iacute} % 00ED LATIN SMALL LETTER I WITH ACUTE +\defineactivetoken 238 {\icircumflex} % 00EE LATIN SMALL LETTER I WITH CIRCUMFLEX +\defineactivetoken 239 {\imacron} % 012B LATIN SMALL LETTER I WITH MACRON +\defineactivetoken 240 {\dstroke} % 0111 LATIN SMALL LETTER D WITH STROKE +\defineactivetoken 241 {\ncommaaccent} % 0146 LATIN SMALL LETTER N WITH CEDILLA +\defineactivetoken 242 {\omacron} % 014D LATIN SMALL LETTER O WITH MACRON +\defineactivetoken 243 {\kcommaaccent} % 0137 LATIN SMALL LETTER K WITH CEDILLA +\defineactivetoken 244 {\ocircumflex} % 00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX +\defineactivetoken 245 {\otilde} % 00F5 LATIN SMALL LETTER O WITH TILDE +\defineactivetoken 246 {\odiaeresis} % 00F6 LATIN SMALL LETTER O WITH DIAERESIS +\defineactivetoken 247 {\textdiv} % 00F7 DIVISION SIGN +\defineactivetoken 248 {\ostroke} % 00F8 LATIN SMALL LETTER O WITH STROKE +\defineactivetoken 249 {\uogonek} % 0173 LATIN SMALL LETTER U WITH OGONEK +\defineactivetoken 250 {\uacute} % 00FA LATIN SMALL LETTER U WITH ACUTE +\defineactivetoken 251 {\ucircumflex} % 00FB LATIN SMALL LETTER U WITH CIRCUMFLEX +\defineactivetoken 252 {\udiaeresis} % 00FC LATIN SMALL LETTER U WITH DIAERESIS +\defineactivetoken 253 {\utilde} % 0169 LATIN SMALL LETTER U WITH TILDE +\defineactivetoken 254 {\umacron} % 016B LATIN SMALL LETTER U WITH MACRON +\defineactivetoken 255 {\textdotaccent} % 02D9 DOT ABOVE + +\stopregime + diff --git a/tex/context/base/regi-8859-5.lua b/tex/context/base/regi-8859-5.lua new file mode 100644 index 000000000..ab093d139 --- /dev/null +++ b/tex/context/base/regi-8859-5.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-8859-5'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["8859-5"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00AD, 0x040E, 0x040F, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, + 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00A7, 0x045E, 0x045F +} diff --git a/tex/context/base/regi-8859-5.mkii b/tex/context/base/regi-8859-5.mkii new file mode 100644 index 000000000..531226433 --- /dev/null +++ b/tex/context/base/regi-8859-5.mkii @@ -0,0 +1,152 @@ +%D \module +%D [ file=regi-8859-5, +%D version=2005.12.26, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=iso-8859-5 (Cyrillic), +%D author=script-generated, +%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. + +%D Support for iso-8859-5 input encoding (regime) for Cyrillic, +%D see also regi-cyr and regi-cyp. +%D +%D Usage: \type{\enableregime[8859-5]} (see \type {regi-syn} for +%D alternatives calls). + +\startregime[8859-5] + +\defineactivetoken 128 {\unknownchar} % 0080 +\defineactivetoken 129 {\unknownchar} % 0081 +\defineactivetoken 130 {\unknownchar} % 0082 +\defineactivetoken 131 {\unknownchar} % 0083 +\defineactivetoken 132 {\unknownchar} % 0084 +\defineactivetoken 133 {\unknownchar} % 0085 +\defineactivetoken 134 {\unknownchar} % 0086 +\defineactivetoken 135 {\unknownchar} % 0087 +\defineactivetoken 136 {\unknownchar} % 0088 +\defineactivetoken 137 {\unknownchar} % 0089 +\defineactivetoken 138 {\unknownchar} % 008A +\defineactivetoken 139 {\unknownchar} % 008B +\defineactivetoken 140 {\unknownchar} % 008C +\defineactivetoken 141 {\unknownchar} % 008D +\defineactivetoken 142 {\unknownchar} % 008E +\defineactivetoken 143 {\unknownchar} % 008F +\defineactivetoken 144 {\unknownchar} % 0090 +\defineactivetoken 145 {\unknownchar} % 0091 +\defineactivetoken 146 {\unknownchar} % 0092 +\defineactivetoken 147 {\unknownchar} % 0093 +\defineactivetoken 148 {\unknownchar} % 0094 +\defineactivetoken 149 {\unknownchar} % 0095 +\defineactivetoken 150 {\unknownchar} % 0096 +\defineactivetoken 151 {\unknownchar} % 0097 +\defineactivetoken 152 {\unknownchar} % 0098 +\defineactivetoken 153 {\unknownchar} % 0099 +\defineactivetoken 154 {\unknownchar} % 009A +\defineactivetoken 155 {\unknownchar} % 009B +\defineactivetoken 156 {\unknownchar} % 009C +\defineactivetoken 157 {\unknownchar} % 009D +\defineactivetoken 158 {\unknownchar} % 009E +\defineactivetoken 159 {\unknownchar} % 009F +\defineactivetoken 160 {\nonbreakablespace} % 00A0 NO-BREAK SPACE +\defineactivetoken 161 {\cyrillicYO} % 0401 CYRILLIC CAPITAL LETTER IO +\defineactivetoken 162 {\cyrillicDJE} % 0402 CYRILLIC CAPITAL LETTER DJE +\defineactivetoken 163 {\cyrillicGJE} % 0403 CYRILLIC CAPITAL LETTER GJE +\defineactivetoken 164 {\cyrillicIE} % 0404 CYRILLIC CAPITAL LETTER UKRAINIAN IE +\defineactivetoken 165 {\cyrillicDZE} % 0405 CYRILLIC CAPITAL LETTER DZE +\defineactivetoken 166 {\cyrillicII} % 0406 CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I +\defineactivetoken 167 {\cyrillicYI} % 0407 CYRILLIC CAPITAL LETTER YI +\defineactivetoken 168 {\cyrillicJE} % 0408 CYRILLIC CAPITAL LETTER JE +\defineactivetoken 169 {\cyrillicLJE} % 0409 CYRILLIC CAPITAL LETTER LJE +\defineactivetoken 170 {\cyrillicNJE} % 040A CYRILLIC CAPITAL LETTER NJE +\defineactivetoken 171 {\cyrillicTSHE} % 040B CYRILLIC CAPITAL LETTER TSHE +\defineactivetoken 172 {\cyrillicKJE} % 040C CYRILLIC CAPITAL LETTER KJE +\defineactivetoken 173 {\softhyphen} % 00AD SOFT HYPHEN +\defineactivetoken 174 {\cyrillicUSHRT} % 040E CYRILLIC CAPITAL LETTER SHORT U +\defineactivetoken 175 {\cyrillicDZHE} % 040F CYRILLIC CAPITAL LETTER DZHE +\defineactivetoken 176 {\cyrillicA} % 0410 CYRILLIC CAPITAL LETTER A +\defineactivetoken 177 {\cyrillicB} % 0411 CYRILLIC CAPITAL LETTER BE +\defineactivetoken 178 {\cyrillicV} % 0412 CYRILLIC CAPITAL LETTER VE +\defineactivetoken 179 {\cyrillicG} % 0413 CYRILLIC CAPITAL LETTER GHE +\defineactivetoken 180 {\cyrillicD} % 0414 CYRILLIC CAPITAL LETTER DE +\defineactivetoken 181 {\cyrillicE} % 0415 CYRILLIC CAPITAL LETTER IE +\defineactivetoken 182 {\cyrillicZH} % 0416 CYRILLIC CAPITAL LETTER ZHE +\defineactivetoken 183 {\cyrillicZ} % 0417 CYRILLIC CAPITAL LETTER ZE +\defineactivetoken 184 {\cyrillicI} % 0418 CYRILLIC CAPITAL LETTER I +\defineactivetoken 185 {\cyrillicISHRT} % 0419 CYRILLIC CAPITAL LETTER SHORT I +\defineactivetoken 186 {\cyrillicK} % 041A CYRILLIC CAPITAL LETTER KA +\defineactivetoken 187 {\cyrillicL} % 041B CYRILLIC CAPITAL LETTER EL +\defineactivetoken 188 {\cyrillicM} % 041C CYRILLIC CAPITAL LETTER EM +\defineactivetoken 189 {\cyrillicN} % 041D CYRILLIC CAPITAL LETTER EN +\defineactivetoken 190 {\cyrillicO} % 041E CYRILLIC CAPITAL LETTER O +\defineactivetoken 191 {\cyrillicP} % 041F CYRILLIC CAPITAL LETTER PE +\defineactivetoken 192 {\cyrillicR} % 0420 CYRILLIC CAPITAL LETTER ER +\defineactivetoken 193 {\cyrillicS} % 0421 CYRILLIC CAPITAL LETTER ES +\defineactivetoken 194 {\cyrillicT} % 0422 CYRILLIC CAPITAL LETTER TE +\defineactivetoken 195 {\cyrillicU} % 0423 CYRILLIC CAPITAL LETTER U +\defineactivetoken 196 {\cyrillicF} % 0424 CYRILLIC CAPITAL LETTER EF +\defineactivetoken 197 {\cyrillicH} % 0425 CYRILLIC CAPITAL LETTER HA +\defineactivetoken 198 {\cyrillicC} % 0426 CYRILLIC CAPITAL LETTER TSE +\defineactivetoken 199 {\cyrillicCH} % 0427 CYRILLIC CAPITAL LETTER CHE +\defineactivetoken 200 {\cyrillicSH} % 0428 CYRILLIC CAPITAL LETTER SHA +\defineactivetoken 201 {\cyrillicSHCH} % 0429 CYRILLIC CAPITAL LETTER SHCHA +\defineactivetoken 202 {\cyrillicHRDSN} % 042A CYRILLIC CAPITAL LETTER HARD SIGN +\defineactivetoken 203 {\cyrillicERY} % 042B CYRILLIC CAPITAL LETTER YERU +\defineactivetoken 204 {\cyrillicSFTSN} % 042C CYRILLIC CAPITAL LETTER SOFT SIGN +\defineactivetoken 205 {\cyrillicEREV} % 042D CYRILLIC CAPITAL LETTER E +\defineactivetoken 206 {\cyrillicYU} % 042E CYRILLIC CAPITAL LETTER YU +\defineactivetoken 207 {\cyrillicYA} % 042F CYRILLIC CAPITAL LETTER YA +\defineactivetoken 208 {\cyrillica} % 0430 CYRILLIC SMALL LETTER A +\defineactivetoken 209 {\cyrillicb} % 0431 CYRILLIC SMALL LETTER BE +\defineactivetoken 210 {\cyrillicv} % 0432 CYRILLIC SMALL LETTER VE +\defineactivetoken 211 {\cyrillicg} % 0433 CYRILLIC SMALL LETTER GHE +\defineactivetoken 212 {\cyrillicd} % 0434 CYRILLIC SMALL LETTER DE +\defineactivetoken 213 {\cyrillice} % 0435 CYRILLIC SMALL LETTER IE +\defineactivetoken 214 {\cyrilliczh} % 0436 CYRILLIC SMALL LETTER ZHE +\defineactivetoken 215 {\cyrillicz} % 0437 CYRILLIC SMALL LETTER ZE +\defineactivetoken 216 {\cyrillici} % 0438 CYRILLIC SMALL LETTER I +\defineactivetoken 217 {\cyrillicishrt} % 0439 CYRILLIC SMALL LETTER SHORT I +\defineactivetoken 218 {\cyrillick} % 043A CYRILLIC SMALL LETTER KA +\defineactivetoken 219 {\cyrillicl} % 043B CYRILLIC SMALL LETTER EL +\defineactivetoken 220 {\cyrillicm} % 043C CYRILLIC SMALL LETTER EM +\defineactivetoken 221 {\cyrillicn} % 043D CYRILLIC SMALL LETTER EN +\defineactivetoken 222 {\cyrillico} % 043E CYRILLIC SMALL LETTER O +\defineactivetoken 223 {\cyrillicp} % 043F CYRILLIC SMALL LETTER PE +\defineactivetoken 224 {\cyrillicr} % 0440 CYRILLIC SMALL LETTER ER +\defineactivetoken 225 {\cyrillics} % 0441 CYRILLIC SMALL LETTER ES +\defineactivetoken 226 {\cyrillict} % 0442 CYRILLIC SMALL LETTER TE +\defineactivetoken 227 {\cyrillicu} % 0443 CYRILLIC SMALL LETTER U +\defineactivetoken 228 {\cyrillicf} % 0444 CYRILLIC SMALL LETTER EF +\defineactivetoken 229 {\cyrillich} % 0445 CYRILLIC SMALL LETTER HA +\defineactivetoken 230 {\cyrillicc} % 0446 CYRILLIC SMALL LETTER TSE +\defineactivetoken 231 {\cyrillicch} % 0447 CYRILLIC SMALL LETTER CHE +\defineactivetoken 232 {\cyrillicsh} % 0448 CYRILLIC SMALL LETTER SHA +\defineactivetoken 233 {\cyrillicshch} % 0449 CYRILLIC SMALL LETTER SHCHA +\defineactivetoken 234 {\cyrillichrdsn} % 044A CYRILLIC SMALL LETTER HARD SIGN +\defineactivetoken 235 {\cyrillicery} % 044B CYRILLIC SMALL LETTER YERU +\defineactivetoken 236 {\cyrillicsftsn} % 044C CYRILLIC SMALL LETTER SOFT SIGN +\defineactivetoken 237 {\cyrillicerev} % 044D CYRILLIC SMALL LETTER E +\defineactivetoken 238 {\cyrillicyu} % 044E CYRILLIC SMALL LETTER YU +\defineactivetoken 239 {\cyrillicya} % 044F CYRILLIC SMALL LETTER YA +\defineactivetoken 240 {\textnumero} % 2116 NUMERO SIGN +\defineactivetoken 241 {\cyrillicyo} % 0451 CYRILLIC SMALL LETTER IO +\defineactivetoken 242 {\cyrillicdje} % 0452 CYRILLIC SMALL LETTER DJE +\defineactivetoken 243 {\cyrillicgje} % 0453 CYRILLIC SMALL LETTER GJE +\defineactivetoken 244 {\cyrillicie} % 0454 CYRILLIC SMALL LETTER UKRAINIAN IE +\defineactivetoken 245 {\cyrillicdze} % 0455 CYRILLIC SMALL LETTER DZE +\defineactivetoken 246 {\cyrillicii} % 0456 CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I +\defineactivetoken 247 {\cyrillicyi} % 0457 CYRILLIC SMALL LETTER YI +\defineactivetoken 248 {\cyrillicje} % 0458 CYRILLIC SMALL LETTER JE +\defineactivetoken 249 {\cyrilliclje} % 0459 CYRILLIC SMALL LETTER LJE +\defineactivetoken 250 {\cyrillicnje} % 045A CYRILLIC SMALL LETTER NJE +\defineactivetoken 251 {\cyrillictshe} % 045B CYRILLIC SMALL LETTER TSHE +\defineactivetoken 252 {\cyrillickje} % 045C CYRILLIC SMALL LETTER KJE +\defineactivetoken 253 {\sectionmark} % 00A7 SECTION SIGN +\defineactivetoken 254 {\cyrillicushrt} % 045E CYRILLIC SMALL LETTER SHORT U +\defineactivetoken 255 {\cyrillicdzhe} % 045F CYRILLIC SMALL LETTER DZHE + +\stopregime + diff --git a/tex/context/base/regi-8859-6.lua b/tex/context/base/regi-8859-6.lua new file mode 100644 index 000000000..e094129f2 --- /dev/null +++ b/tex/context/base/regi-8859-6.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-8859-6'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["8859-6"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x0000, 0x0000, 0x0000, 0x00A4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x060C, 0x00AD, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x061B, 0x0000, 0x0000, 0x0000, 0x061F, + 0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, + 0x0650, 0x0651, 0x0652, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 +} diff --git a/tex/context/base/regi-8859-7.lua b/tex/context/base/regi-8859-7.lua new file mode 100644 index 000000000..cee253582 --- /dev/null +++ b/tex/context/base/regi-8859-7.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-8859-7'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["8859-7"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x2018, 0x2019, 0x00A3, 0x20AC, 0x20AF, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x037A, 0x00AB, 0x00AC, 0x00AD, 0x0000, 0x2015, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x0385, 0x0386, 0x00B7, 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F, + 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, + 0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF, + 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, + 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000 +} diff --git a/tex/context/base/regi-8859-7.mkii b/tex/context/base/regi-8859-7.mkii new file mode 100644 index 000000000..80259be65 --- /dev/null +++ b/tex/context/base/regi-8859-7.mkii @@ -0,0 +1,153 @@ +%D \module +%D [ file=regi-8859-7, +%D version=2005.12.26, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=iso-8859-7 (Greek), +%D author=script-generated, +%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. + +%D Support for iso-8859-7 input encoding (regime) for Greek, +%D see also cp1253. +%D +%D (Contributor to the original file: Apostolos Syropoulos.) +%D +%D Usage: \type{\enableregime[8859-7]} (see \type {regi-syn} for +%D alternatives calls). + +\startregime[8859-7] + +\defineactivetoken 128 {\unknownchar} % 0080 +\defineactivetoken 129 {\unknownchar} % 0081 +\defineactivetoken 130 {\unknownchar} % 0082 +\defineactivetoken 131 {\unknownchar} % 0083 +\defineactivetoken 132 {\unknownchar} % 0084 +\defineactivetoken 133 {\unknownchar} % 0085 +\defineactivetoken 134 {\unknownchar} % 0086 +\defineactivetoken 135 {\unknownchar} % 0087 +\defineactivetoken 136 {\unknownchar} % 0088 +\defineactivetoken 137 {\unknownchar} % 0089 +\defineactivetoken 138 {\unknownchar} % 008A +\defineactivetoken 139 {\unknownchar} % 008B +\defineactivetoken 140 {\unknownchar} % 008C +\defineactivetoken 141 {\unknownchar} % 008D +\defineactivetoken 142 {\unknownchar} % 008E +\defineactivetoken 143 {\unknownchar} % 008F +\defineactivetoken 144 {\unknownchar} % 0090 +\defineactivetoken 145 {\unknownchar} % 0091 +\defineactivetoken 146 {\unknownchar} % 0092 +\defineactivetoken 147 {\unknownchar} % 0093 +\defineactivetoken 148 {\unknownchar} % 0094 +\defineactivetoken 149 {\unknownchar} % 0095 +\defineactivetoken 150 {\unknownchar} % 0096 +\defineactivetoken 151 {\unknownchar} % 0097 +\defineactivetoken 152 {\unknownchar} % 0098 +\defineactivetoken 153 {\unknownchar} % 0099 +\defineactivetoken 154 {\unknownchar} % 009A +\defineactivetoken 155 {\unknownchar} % 009B +\defineactivetoken 156 {\unknownchar} % 009C +\defineactivetoken 157 {\unknownchar} % 009D +\defineactivetoken 158 {\unknownchar} % 009E +\defineactivetoken 159 {\unknownchar} % 009F +\defineactivetoken 160 {\nonbreakablespace} % 00A0 NO-BREAK SPACE +\defineactivetoken 161 {\quoteleft} % 2018 LEFT SINGLE QUOTATION MARK +\defineactivetoken 162 {\quoteright} % 2019 RIGHT SINGLE QUOTATION MARK +\defineactivetoken 163 {\textsterling} % 00A3 POUND SIGN +\defineactivetoken 164 {\texteuro} % 20AC EURO SIGN +\defineactivetoken 165 {\unknownchar} % 20AF DRACHMA SIGN (TODO) +\defineactivetoken 166 {\textbrokenbar} % 00A6 BROKEN BAR +\defineactivetoken 167 {\sectionmark} % 00A7 SECTION SIGN +\defineactivetoken 168 {\textdiaeresis} % 00A8 DIAERESIS +\defineactivetoken 169 {\copyright} % 00A9 COPYRIGHT SIGN +\defineactivetoken 170 {\unknownchar} % 037A GREEK YPOGEGRAMMENI (TODO) +\defineactivetoken 171 {\leftguillemot} % 00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 172 {\textlognot} % 00AC NOT SIGN +\defineactivetoken 173 {\softhyphen} % 00AD SOFT HYPHEN +\defineactivetoken 175 {\texthorizontalbar} % 2015 HORIZONTAL BAR +\defineactivetoken 176 {\textdegree} % 00B0 DEGREE SIGN +\defineactivetoken 177 {\textpm} % 00B1 PLUS-MINUS SIGN +\defineactivetoken 178 {\twosuperior} % 00B2 SUPERSCRIPT TWO +\defineactivetoken 179 {\threesuperior} % 00B3 SUPERSCRIPT THREE +\defineactivetoken 180 {\greektonos} % 0384 GREEK TONOS +\defineactivetoken 181 {\greekdialytikatonos} % 0385 GREEK DIALYTIKA TONOS +\defineactivetoken 182 {\greekAlphatonos} % 0386 GREEK CAPITAL LETTER ALPHA WITH TONOS +\defineactivetoken 183 {\periodcentered} % 00B7 MIDDLE DOT +\defineactivetoken 184 {\greekEpsilontonos} % 0388 GREEK CAPITAL LETTER EPSILON WITH TONOS +\defineactivetoken 185 {\greekEtatonos} % 0389 GREEK CAPITAL LETTER ETA WITH TONOS +\defineactivetoken 186 {\greekIotatonos} % 038A GREEK CAPITAL LETTER IOTA WITH TONOS +\defineactivetoken 187 {\rightguillemot} % 00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 188 {\greekOmicrontonos} % 038C GREEK CAPITAL LETTER OMICRON WITH TONOS +\defineactivetoken 189 {\onehalf} % 00BD VULGAR FRACTION ONE HALF +\defineactivetoken 190 {\greekUpsilontonos} % 038E GREEK CAPITAL LETTER UPSILON WITH TONOS +\defineactivetoken 191 {\greekOmegatonos} % 038F GREEK CAPITAL LETTER OMEGA WITH TONOS +\defineactivetoken 192 {\greekiotadialytikatonos} % 0390 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS +\defineactivetoken 193 {\greekAlpha} % 0391 GREEK CAPITAL LETTER ALPHA +\defineactivetoken 194 {\greekBeta} % 0392 GREEK CAPITAL LETTER BETA +\defineactivetoken 195 {\greekGamma} % 0393 GREEK CAPITAL LETTER GAMMA +\defineactivetoken 196 {\greekDelta} % 0394 GREEK CAPITAL LETTER DELTA +\defineactivetoken 197 {\greekEpsilon} % 0395 GREEK CAPITAL LETTER EPSILON +\defineactivetoken 198 {\greekZeta} % 0396 GREEK CAPITAL LETTER ZETA +\defineactivetoken 199 {\greekEta} % 0397 GREEK CAPITAL LETTER ETA +\defineactivetoken 200 {\greekTheta} % 0398 GREEK CAPITAL LETTER THETA +\defineactivetoken 201 {\greekIota} % 0399 GREEK CAPITAL LETTER IOTA +\defineactivetoken 202 {\greekKappa} % 039A GREEK CAPITAL LETTER KAPPA +\defineactivetoken 203 {\greekLambda} % 039B GREEK CAPITAL LETTER LAMDA +\defineactivetoken 204 {\greekMu} % 039C GREEK CAPITAL LETTER MU +\defineactivetoken 205 {\greekNu} % 039D GREEK CAPITAL LETTER NU +\defineactivetoken 206 {\greekXi} % 039E GREEK CAPITAL LETTER XI +\defineactivetoken 207 {\greekOmicron} % 039F GREEK CAPITAL LETTER OMICRON +\defineactivetoken 208 {\greekPi} % 03A0 GREEK CAPITAL LETTER PI +\defineactivetoken 209 {\greekRho} % 03A1 GREEK CAPITAL LETTER RHO +\defineactivetoken 210 {\unknownchar} % +\defineactivetoken 211 {\greekSigma} % 03A3 GREEK CAPITAL LETTER SIGMA +\defineactivetoken 212 {\greekTau} % 03A4 GREEK CAPITAL LETTER TAU +\defineactivetoken 213 {\greekUpsilon} % 03A5 GREEK CAPITAL LETTER UPSILON +\defineactivetoken 214 {\greekPhi} % 03A6 GREEK CAPITAL LETTER PHI +\defineactivetoken 215 {\greekChi} % 03A7 GREEK CAPITAL LETTER CHI +\defineactivetoken 216 {\greekPsi} % 03A8 GREEK CAPITAL LETTER PSI +\defineactivetoken 217 {\greekOmega} % 03A9 GREEK CAPITAL LETTER OMEGA +\defineactivetoken 218 {\greekIotadialytika} % 03AA GREEK CAPITAL LETTER IOTA WITH DIALYTIKA +\defineactivetoken 219 {\greekUpsilondialytika} % 03AB GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA +\defineactivetoken 220 {\greekalphatonos} % 03AC GREEK SMALL LETTER ALPHA WITH TONOS +\defineactivetoken 221 {\greekepsilontonos} % 03AD GREEK SMALL LETTER EPSILON WITH TONOS +\defineactivetoken 222 {\greeketatonos} % 03AE GREEK SMALL LETTER ETA WITH TONOS +\defineactivetoken 223 {\greekiotatonos} % 03AF GREEK SMALL LETTER IOTA WITH TONOS +\defineactivetoken 224 {\greekupsilondialytikatonos} % 03B0 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS +\defineactivetoken 225 {\greekalpha} % 03B1 GREEK SMALL LETTER ALPHA +\defineactivetoken 226 {\greekbeta} % 03B2 GREEK SMALL LETTER BETA +\defineactivetoken 227 {\greekgamma} % 03B3 GREEK SMALL LETTER GAMMA +\defineactivetoken 228 {\greekdelta} % 03B4 GREEK SMALL LETTER DELTA +\defineactivetoken 229 {\greekepsilon} % 03B5 GREEK SMALL LETTER EPSILON +\defineactivetoken 230 {\greekzeta} % 03B6 GREEK SMALL LETTER ZETA +\defineactivetoken 231 {\greeketa} % 03B7 GREEK SMALL LETTER ETA +\defineactivetoken 232 {\greektheta} % 03B8 GREEK SMALL LETTER THETA +\defineactivetoken 233 {\greekiota} % 03B9 GREEK SMALL LETTER IOTA +\defineactivetoken 234 {\greekkappa} % 03BA GREEK SMALL LETTER KAPPA +\defineactivetoken 235 {\greeklambda} % 03BB GREEK SMALL LETTER LAMDA +\defineactivetoken 236 {\greekmu} % 03BC GREEK SMALL LETTER MU +\defineactivetoken 237 {\greeknu} % 03BD GREEK SMALL LETTER NU +\defineactivetoken 238 {\greekxi} % 03BE GREEK SMALL LETTER XI +\defineactivetoken 239 {\greekomicron} % 03BF GREEK SMALL LETTER OMICRON +\defineactivetoken 240 {\greekpi} % 03C0 GREEK SMALL LETTER PI +\defineactivetoken 241 {\greekrho} % 03C1 GREEK SMALL LETTER RHO +\defineactivetoken 242 {\greekfinalsigma} % 03C2 GREEK SMALL LETTER FINAL SIGMA +\defineactivetoken 243 {\greeksigma} % 03C3 GREEK SMALL LETTER SIGMA +\defineactivetoken 244 {\greektau} % 03C4 GREEK SMALL LETTER TAU +\defineactivetoken 245 {\greekupsilon} % 03C5 GREEK SMALL LETTER UPSILON +\defineactivetoken 246 {\greekphi} % 03C6 GREEK SMALL LETTER PHI +\defineactivetoken 247 {\greekchi} % 03C7 GREEK SMALL LETTER CHI +\defineactivetoken 248 {\greekpsi} % 03C8 GREEK SMALL LETTER PSI +\defineactivetoken 249 {\greekomega} % 03C9 GREEK SMALL LETTER OMEGA +\defineactivetoken 250 {\greekiotadialytika} % 03CA GREEK SMALL LETTER IOTA WITH DIALYTIKA +\defineactivetoken 251 {\greekupsilondiaeresis} % 03CB GREEK SMALL LETTER UPSILON WITH DIALYTIKA +\defineactivetoken 252 {\greekomicrontonos} % 03CC GREEK SMALL LETTER OMICRON WITH TONOS +\defineactivetoken 253 {\greekupsilontonos} % 03CD GREEK SMALL LETTER UPSILON WITH TONOS +\defineactivetoken 254 {\greekomegatonos} % 03CE GREEK SMALL LETTER OMEGA WITH TONOS +\defineactivetoken 255 {\unknownchar} % + +\stopregime + diff --git a/tex/context/base/regi-8859-8.lua b/tex/context/base/regi-8859-8.lua new file mode 100644 index 000000000..062b080ad --- /dev/null +++ b/tex/context/base/regi-8859-8.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-8859-8'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["8859-8"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2017, + 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, + 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, 0x0000 +} diff --git a/tex/context/base/regi-8859-9.lua b/tex/context/base/regi-8859-9.lua new file mode 100644 index 000000000..2af118a8c --- /dev/null +++ b/tex/context/base/regi-8859-9.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-8859-9'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["8859-9"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF +} diff --git a/tex/context/base/regi-8859-9.mkii b/tex/context/base/regi-8859-9.mkii new file mode 100644 index 000000000..8460d739b --- /dev/null +++ b/tex/context/base/regi-8859-9.mkii @@ -0,0 +1,152 @@ +%D \module +%D [ file=regi-8859-9, +%D version=2005.12.26, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=iso-8859-9 (Turkish), +%D author=script-generated, +%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. + +%D Support for iso-8859-9/Latin5 input encoding (regime) for Turkish, +%D see also cp1254. +%D +%D Usage: \type{\enableregime[8859-9]} (see \type {regi-syn} for +%D alternatives calls). + +\startregime[8859-9] + +\defineactivetoken 128 {\unknownchar} % 0080 +\defineactivetoken 129 {\unknownchar} % 0081 +\defineactivetoken 130 {\unknownchar} % 0082 +\defineactivetoken 131 {\unknownchar} % 0083 +\defineactivetoken 132 {\unknownchar} % 0084 +\defineactivetoken 133 {\unknownchar} % 0085 +\defineactivetoken 134 {\unknownchar} % 0086 +\defineactivetoken 135 {\unknownchar} % 0087 +\defineactivetoken 136 {\unknownchar} % 0088 +\defineactivetoken 137 {\unknownchar} % 0089 +\defineactivetoken 138 {\unknownchar} % 008A +\defineactivetoken 139 {\unknownchar} % 008B +\defineactivetoken 140 {\unknownchar} % 008C +\defineactivetoken 141 {\unknownchar} % 008D +\defineactivetoken 142 {\unknownchar} % 008E +\defineactivetoken 143 {\unknownchar} % 008F +\defineactivetoken 144 {\unknownchar} % 0090 +\defineactivetoken 145 {\unknownchar} % 0091 +\defineactivetoken 146 {\unknownchar} % 0092 +\defineactivetoken 147 {\unknownchar} % 0093 +\defineactivetoken 148 {\unknownchar} % 0094 +\defineactivetoken 149 {\unknownchar} % 0095 +\defineactivetoken 150 {\unknownchar} % 0096 +\defineactivetoken 151 {\unknownchar} % 0097 +\defineactivetoken 152 {\unknownchar} % 0098 +\defineactivetoken 153 {\unknownchar} % 0099 +\defineactivetoken 154 {\unknownchar} % 009A +\defineactivetoken 155 {\unknownchar} % 009B +\defineactivetoken 156 {\unknownchar} % 009C +\defineactivetoken 157 {\unknownchar} % 009D +\defineactivetoken 158 {\unknownchar} % 009E +\defineactivetoken 159 {\unknownchar} % 009F +\defineactivetoken 160 {\nonbreakablespace} % 00A0 NO-BREAK SPACE +\defineactivetoken 161 {\exclamdown} % 00A1 INVERTED EXCLAMATION MARK +\defineactivetoken 162 {\textcent} % 00A2 CENT SIGN +\defineactivetoken 163 {\textsterling} % 00A3 POUND SIGN +\defineactivetoken 164 {\textcurrency} % 00A4 CURRENCY SIGN +\defineactivetoken 165 {\textyen} % 00A5 YEN SIGN +\defineactivetoken 166 {\textbrokenbar} % 00A6 BROKEN BAR +\defineactivetoken 167 {\sectionmark} % 00A7 SECTION SIGN +\defineactivetoken 168 {\textdiaeresis} % 00A8 DIAERESIS +\defineactivetoken 169 {\copyright} % 00A9 COPYRIGHT SIGN +\defineactivetoken 170 {\ordfeminine} % 00AA FEMININE ORDINAL INDICATOR +\defineactivetoken 171 {\leftguillemot} % 00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 172 {\textlognot} % 00AC NOT SIGN +\defineactivetoken 173 {\softhyphen} % 00AD SOFT HYPHEN +\defineactivetoken 174 {\registered} % 00AE REGISTERED SIGN +\defineactivetoken 175 {\textmacron} % 00AF MACRON +\defineactivetoken 176 {\textdegree} % 00B0 DEGREE SIGN +\defineactivetoken 177 {\textpm} % 00B1 PLUS-MINUS SIGN +\defineactivetoken 178 {\twosuperior} % 00B2 SUPERSCRIPT TWO +\defineactivetoken 179 {\threesuperior} % 00B3 SUPERSCRIPT THREE +\defineactivetoken 180 {\textacute} % 00B4 ACUTE ACCENT +\defineactivetoken 181 {\textmu} % 00B5 MICRO SIGN +\defineactivetoken 182 {\paragraphmark} % 00B6 PILCROW SIGN +\defineactivetoken 183 {\periodcentered} % 00B7 MIDDLE DOT +\defineactivetoken 184 {\textcedilla} % 00B8 CEDILLA +\defineactivetoken 185 {\onesuperior} % 00B9 SUPERSCRIPT ONE +\defineactivetoken 186 {\ordmasculine} % 00BA MASCULINE ORDINAL INDICATOR +\defineactivetoken 187 {\rightguillemot} % 00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 188 {\onequarter} % 00BC VULGAR FRACTION ONE QUARTER +\defineactivetoken 189 {\onehalf} % 00BD VULGAR FRACTION ONE HALF +\defineactivetoken 190 {\threequarter} % 00BE VULGAR FRACTION THREE QUARTERS +\defineactivetoken 191 {\questiondown} % 00BF INVERTED QUESTION MARK +\defineactivetoken 192 {\Agrave} % 00C0 LATIN CAPITAL LETTER A WITH GRAVE +\defineactivetoken 193 {\Aacute} % 00C1 LATIN CAPITAL LETTER A WITH ACUTE +\defineactivetoken 194 {\Acircumflex} % 00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX +\defineactivetoken 195 {\Atilde} % 00C3 LATIN CAPITAL LETTER A WITH TILDE +\defineactivetoken 196 {\Adiaeresis} % 00C4 LATIN CAPITAL LETTER A WITH DIAERESIS +\defineactivetoken 197 {\Aring} % 00C5 LATIN CAPITAL LETTER A WITH RING ABOVE +\defineactivetoken 198 {\AEligature} % 00C6 LATIN CAPITAL LETTER AE +\defineactivetoken 199 {\Ccedilla} % 00C7 LATIN CAPITAL LETTER C WITH CEDILLA +\defineactivetoken 200 {\Egrave} % 00C8 LATIN CAPITAL LETTER E WITH GRAVE +\defineactivetoken 201 {\Eacute} % 00C9 LATIN CAPITAL LETTER E WITH ACUTE +\defineactivetoken 202 {\Ecircumflex} % 00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX +\defineactivetoken 203 {\Ediaeresis} % 00CB LATIN CAPITAL LETTER E WITH DIAERESIS +\defineactivetoken 204 {\Igrave} % 00CC LATIN CAPITAL LETTER I WITH GRAVE +\defineactivetoken 205 {\Iacute} % 00CD LATIN CAPITAL LETTER I WITH ACUTE +\defineactivetoken 206 {\Icircumflex} % 00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX +\defineactivetoken 207 {\Idiaeresis} % 00CF LATIN CAPITAL LETTER I WITH DIAERESIS +\defineactivetoken 208 {\Gbreve} % 011E LATIN CAPITAL LETTER G WITH BREVE +\defineactivetoken 209 {\Ntilde} % 00D1 LATIN CAPITAL LETTER N WITH TILDE +\defineactivetoken 210 {\Ograve} % 00D2 LATIN CAPITAL LETTER O WITH GRAVE +\defineactivetoken 211 {\Oacute} % 00D3 LATIN CAPITAL LETTER O WITH ACUTE +\defineactivetoken 212 {\Ocircumflex} % 00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX +\defineactivetoken 213 {\Otilde} % 00D5 LATIN CAPITAL LETTER O WITH TILDE +\defineactivetoken 214 {\Odiaeresis} % 00D6 LATIN CAPITAL LETTER O WITH DIAERESIS +\defineactivetoken 215 {\textmultiply} % 00D7 MULTIPLICATION SIGN +\defineactivetoken 216 {\Ostroke} % 00D8 LATIN CAPITAL LETTER O WITH STROKE +\defineactivetoken 217 {\Ugrave} % 00D9 LATIN CAPITAL LETTER U WITH GRAVE +\defineactivetoken 218 {\Uacute} % 00DA LATIN CAPITAL LETTER U WITH ACUTE +\defineactivetoken 219 {\Ucircumflex} % 00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX +\defineactivetoken 220 {\Udiaeresis} % 00DC LATIN CAPITAL LETTER U WITH DIAERESIS +\defineactivetoken 221 {\Idotaccent} % 0130 LATIN CAPITAL LETTER I WITH DOT ABOVE +\defineactivetoken 222 {\Scedilla} % 015E LATIN CAPITAL LETTER S WITH CEDILLA +\defineactivetoken 223 {\ssharp} % 00DF LATIN SMALL LETTER SHARP S +\defineactivetoken 224 {\agrave} % 00E0 LATIN SMALL LETTER A WITH GRAVE +\defineactivetoken 225 {\aacute} % 00E1 LATIN SMALL LETTER A WITH ACUTE +\defineactivetoken 226 {\acircumflex} % 00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX +\defineactivetoken 227 {\atilde} % 00E3 LATIN SMALL LETTER A WITH TILDE +\defineactivetoken 228 {\adiaeresis} % 00E4 LATIN SMALL LETTER A WITH DIAERESIS +\defineactivetoken 229 {\aring} % 00E5 LATIN SMALL LETTER A WITH RING ABOVE +\defineactivetoken 230 {\aeligature} % 00E6 LATIN SMALL LETTER AE +\defineactivetoken 231 {\ccedilla} % 00E7 LATIN SMALL LETTER C WITH CEDILLA +\defineactivetoken 232 {\egrave} % 00E8 LATIN SMALL LETTER E WITH GRAVE +\defineactivetoken 233 {\eacute} % 00E9 LATIN SMALL LETTER E WITH ACUTE +\defineactivetoken 234 {\ecircumflex} % 00EA LATIN SMALL LETTER E WITH CIRCUMFLEX +\defineactivetoken 235 {\ediaeresis} % 00EB LATIN SMALL LETTER E WITH DIAERESIS +\defineactivetoken 236 {\igrave} % 00EC LATIN SMALL LETTER I WITH GRAVE +\defineactivetoken 237 {\iacute} % 00ED LATIN SMALL LETTER I WITH ACUTE +\defineactivetoken 238 {\icircumflex} % 00EE LATIN SMALL LETTER I WITH CIRCUMFLEX +\defineactivetoken 239 {\idiaeresis} % 00EF LATIN SMALL LETTER I WITH DIAERESIS +\defineactivetoken 240 {\gbreve} % 011F LATIN SMALL LETTER G WITH BREVE +\defineactivetoken 241 {\ntilde} % 00F1 LATIN SMALL LETTER N WITH TILDE +\defineactivetoken 242 {\ograve} % 00F2 LATIN SMALL LETTER O WITH GRAVE +\defineactivetoken 243 {\oacute} % 00F3 LATIN SMALL LETTER O WITH ACUTE +\defineactivetoken 244 {\ocircumflex} % 00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX +\defineactivetoken 245 {\otilde} % 00F5 LATIN SMALL LETTER O WITH TILDE +\defineactivetoken 246 {\odiaeresis} % 00F6 LATIN SMALL LETTER O WITH DIAERESIS +\defineactivetoken 247 {\textdiv} % 00F7 DIVISION SIGN +\defineactivetoken 248 {\ostroke} % 00F8 LATIN SMALL LETTER O WITH STROKE +\defineactivetoken 249 {\ugrave} % 00F9 LATIN SMALL LETTER U WITH GRAVE +\defineactivetoken 250 {\uacute} % 00FA LATIN SMALL LETTER U WITH ACUTE +\defineactivetoken 251 {\ucircumflex} % 00FB LATIN SMALL LETTER U WITH CIRCUMFLEX +\defineactivetoken 252 {\udiaeresis} % 00FC LATIN SMALL LETTER U WITH DIAERESIS +\defineactivetoken 253 {\dotlessi} % 0131 LATIN SMALL LETTER DOTLESS I +\defineactivetoken 254 {\scedilla} % 015F LATIN SMALL LETTER S WITH CEDILLA +\defineactivetoken 255 {\ydiaeresis} % 00FF LATIN SMALL LETTER Y WITH DIAERESIS + +\stopregime + diff --git a/tex/context/base/regi-cp1250.lua b/tex/context/base/regi-cp1250.lua new file mode 100644 index 000000000..a37ca46b4 --- /dev/null +++ b/tex/context/base/regi-cp1250.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-cp1250'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["cp1250"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021, 0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A, + 0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B, + 0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C, + 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, + 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, + 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F, + 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9 +} diff --git a/tex/context/base/regi-cp1250.mkii b/tex/context/base/regi-cp1250.mkii new file mode 100644 index 000000000..b92eb5e31 --- /dev/null +++ b/tex/context/base/regi-cp1250.mkii @@ -0,0 +1,153 @@ +%D \module +%D [ file=regi-cp1250, +%D version=2005.12.26, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=cp1250 (East European), +%D author=script-generated, +%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. + +%D Support for cp1250 input encoding (regime) for Central European languages, +%D see also iso-8859-2. +%D +%D Usage: +%D \type{\enableregime[cp1250]} or \type{\enablereregime[windows-1250]} + + +\startregime[cp1250] + +\defineactivetoken 128 {\texteuro} % 20AC EURO SIGN +\defineactivetoken 129 {\unknownchar} % +\defineactivetoken 130 {\quotesinglebase} % 201A SINGLE LOW-9 QUOTATION MARK +\defineactivetoken 131 {\unknownchar} % +\defineactivetoken 132 {\quotedblbase} % 201E DOUBLE LOW-9 QUOTATION MARK +\defineactivetoken 133 {\textellipsis} % 2026 HORIZONTAL ELLIPSIS +\defineactivetoken 134 {\textdag} % 2020 DAGGER +\defineactivetoken 135 {\textddag} % 2021 DOUBLE DAGGER +\defineactivetoken 136 {\unknownchar} % +\defineactivetoken 137 {\perthousand} % 2030 PER MILLE SIGN +\defineactivetoken 138 {\Scaron} % 0160 LATIN CAPITAL LETTER S WITH CARON +\defineactivetoken 139 {\guilsingleleft} % 2039 SINGLE LEFT-POINTING ANGLE QUOTATION MARK +\defineactivetoken 140 {\Sacute} % 015A LATIN CAPITAL LETTER S WITH ACUTE +\defineactivetoken 141 {\Tcaron} % 0164 LATIN CAPITAL LETTER T WITH CARON +\defineactivetoken 142 {\Zcaron} % 017D LATIN CAPITAL LETTER Z WITH CARON +\defineactivetoken 143 {\Zacute} % 0179 LATIN CAPITAL LETTER Z WITH ACUTE +\defineactivetoken 144 {\unknownchar} % +\defineactivetoken 145 {\quoteleft} % 2018 LEFT SINGLE QUOTATION MARK +\defineactivetoken 146 {\quoteright} % 2019 RIGHT SINGLE QUOTATION MARK +\defineactivetoken 147 {\quotedblleft} % 201C LEFT DOUBLE QUOTATION MARK +\defineactivetoken 148 {\quotedblright} % 201D RIGHT DOUBLE QUOTATION MARK +\defineactivetoken 149 {\textbullet} % 2022 BULLET +\defineactivetoken 150 {\endash} % 2013 EN DASH +\defineactivetoken 151 {\emdash} % 2014 EM DASH +\defineactivetoken 152 {\unknownchar} % +\defineactivetoken 153 {\trademark} % 2122 TRADE MARK SIGN +\defineactivetoken 154 {\scaron} % 0161 LATIN SMALL LETTER S WITH CARON +\defineactivetoken 155 {\guilsingleright} % 203A SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +\defineactivetoken 156 {\sacute} % 015B LATIN SMALL LETTER S WITH ACUTE +\defineactivetoken 157 {\tcaron} % 0165 LATIN SMALL LETTER T WITH CARON +\defineactivetoken 158 {\zcaron} % 017E LATIN SMALL LETTER Z WITH CARON +\defineactivetoken 159 {\zacute} % 017A LATIN SMALL LETTER Z WITH ACUTE +\defineactivetoken 160 {\nonbreakablespace} % 00A0 NO-BREAK SPACE +\defineactivetoken 161 {\textcaron} % 02C7 CARON +\defineactivetoken 162 {\textbreve} % 02D8 BREVE +\defineactivetoken 163 {\Lstroke} % 0141 LATIN CAPITAL LETTER L WITH STROKE +\defineactivetoken 164 {\textcurrency} % 00A4 CURRENCY SIGN +\defineactivetoken 165 {\Aogonek} % 0104 LATIN CAPITAL LETTER A WITH OGONEK +\defineactivetoken 166 {\textbrokenbar} % 00A6 BROKEN BAR +\defineactivetoken 167 {\sectionmark} % 00A7 SECTION SIGN +\defineactivetoken 168 {\textdiaeresis} % 00A8 DIAERESIS +\defineactivetoken 169 {\copyright} % 00A9 COPYRIGHT SIGN +\defineactivetoken 170 {\Scedilla} % 015E LATIN CAPITAL LETTER S WITH CEDILLA +\defineactivetoken 171 {\leftguillemot} % 00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 172 {\textlognot} % 00AC NOT SIGN +\defineactivetoken 173 {\softhyphen} % 00AD SOFT HYPHEN +\defineactivetoken 174 {\registered} % 00AE REGISTERED SIGN +\defineactivetoken 175 {\Zdotaccent} % 017B LATIN CAPITAL LETTER Z WITH DOT ABOVE +\defineactivetoken 176 {\textdegree} % 00B0 DEGREE SIGN +\defineactivetoken 177 {\textpm} % 00B1 PLUS-MINUS SIGN +\defineactivetoken 178 {\textogonek} % 02DB OGONEK +\defineactivetoken 179 {\lstroke} % 0142 LATIN SMALL LETTER L WITH STROKE +\defineactivetoken 180 {\textacute} % 00B4 ACUTE ACCENT +\defineactivetoken 181 {\textmu} % 00B5 MICRO SIGN +\defineactivetoken 182 {\paragraphmark} % 00B6 PILCROW SIGN +\defineactivetoken 183 {\periodcentered} % 00B7 MIDDLE DOT +\defineactivetoken 184 {\textcedilla} % 00B8 CEDILLA +\defineactivetoken 185 {\aogonek} % 0105 LATIN SMALL LETTER A WITH OGONEK +\defineactivetoken 186 {\scedilla} % 015F LATIN SMALL LETTER S WITH CEDILLA +\defineactivetoken 187 {\rightguillemot} % 00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 188 {\Lcaron} % 013D LATIN CAPITAL LETTER L WITH CARON +\defineactivetoken 189 {\texthungarumlaut} % 02DD DOUBLE ACUTE ACCENT +\defineactivetoken 190 {\lcaron} % 013E LATIN SMALL LETTER L WITH CARON +\defineactivetoken 191 {\zdotaccent} % 017C LATIN SMALL LETTER Z WITH DOT ABOVE +\defineactivetoken 192 {\Racute} % 0154 LATIN CAPITAL LETTER R WITH ACUTE +\defineactivetoken 193 {\Aacute} % 00C1 LATIN CAPITAL LETTER A WITH ACUTE +\defineactivetoken 194 {\Acircumflex} % 00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX +\defineactivetoken 195 {\Abreve} % 0102 LATIN CAPITAL LETTER A WITH BREVE +\defineactivetoken 196 {\Adiaeresis} % 00C4 LATIN CAPITAL LETTER A WITH DIAERESIS +\defineactivetoken 197 {\Lacute} % 0139 LATIN CAPITAL LETTER L WITH ACUTE +\defineactivetoken 198 {\Cacute} % 0106 LATIN CAPITAL LETTER C WITH ACUTE +\defineactivetoken 199 {\Ccedilla} % 00C7 LATIN CAPITAL LETTER C WITH CEDILLA +\defineactivetoken 200 {\Ccaron} % 010C LATIN CAPITAL LETTER C WITH CARON +\defineactivetoken 201 {\Eacute} % 00C9 LATIN CAPITAL LETTER E WITH ACUTE +\defineactivetoken 202 {\Eogonek} % 0118 LATIN CAPITAL LETTER E WITH OGONEK +\defineactivetoken 203 {\Ediaeresis} % 00CB LATIN CAPITAL LETTER E WITH DIAERESIS +\defineactivetoken 204 {\Ecaron} % 011A LATIN CAPITAL LETTER E WITH CARON +\defineactivetoken 205 {\Iacute} % 00CD LATIN CAPITAL LETTER I WITH ACUTE +\defineactivetoken 206 {\Icircumflex} % 00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX +\defineactivetoken 207 {\Dcaron} % 010E LATIN CAPITAL LETTER D WITH CARON +\defineactivetoken 208 {\Dstroke} % 0110 LATIN CAPITAL LETTER D WITH STROKE +\defineactivetoken 209 {\Nacute} % 0143 LATIN CAPITAL LETTER N WITH ACUTE +\defineactivetoken 210 {\Ncaron} % 0147 LATIN CAPITAL LETTER N WITH CARON +\defineactivetoken 211 {\Oacute} % 00D3 LATIN CAPITAL LETTER O WITH ACUTE +\defineactivetoken 212 {\Ocircumflex} % 00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX +\defineactivetoken 213 {\Ohungarumlaut} % 0150 LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +\defineactivetoken 214 {\Odiaeresis} % 00D6 LATIN CAPITAL LETTER O WITH DIAERESIS +\defineactivetoken 215 {\textmultiply} % 00D7 MULTIPLICATION SIGN +\defineactivetoken 216 {\Rcaron} % 0158 LATIN CAPITAL LETTER R WITH CARON +\defineactivetoken 217 {\Uring} % 016E LATIN CAPITAL LETTER U WITH RING ABOVE +\defineactivetoken 218 {\Uacute} % 00DA LATIN CAPITAL LETTER U WITH ACUTE +\defineactivetoken 219 {\Uhungarumlaut} % 0170 LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +\defineactivetoken 220 {\Udiaeresis} % 00DC LATIN CAPITAL LETTER U WITH DIAERESIS +\defineactivetoken 221 {\Yacute} % 00DD LATIN CAPITAL LETTER Y WITH ACUTE +\defineactivetoken 222 {\Tcedilla} % 0162 LATIN CAPITAL LETTER T WITH CEDILLA +\defineactivetoken 223 {\ssharp} % 00DF LATIN SMALL LETTER SHARP S +\defineactivetoken 224 {\racute} % 0155 LATIN SMALL LETTER R WITH ACUTE +\defineactivetoken 225 {\aacute} % 00E1 LATIN SMALL LETTER A WITH ACUTE +\defineactivetoken 226 {\acircumflex} % 00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX +\defineactivetoken 227 {\abreve} % 0103 LATIN SMALL LETTER A WITH BREVE +\defineactivetoken 228 {\adiaeresis} % 00E4 LATIN SMALL LETTER A WITH DIAERESIS +\defineactivetoken 229 {\lacute} % 013A LATIN SMALL LETTER L WITH ACUTE +\defineactivetoken 230 {\cacute} % 0107 LATIN SMALL LETTER C WITH ACUTE +\defineactivetoken 231 {\ccedilla} % 00E7 LATIN SMALL LETTER C WITH CEDILLA +\defineactivetoken 232 {\ccaron} % 010D LATIN SMALL LETTER C WITH CARON +\defineactivetoken 233 {\eacute} % 00E9 LATIN SMALL LETTER E WITH ACUTE +\defineactivetoken 234 {\eogonek} % 0119 LATIN SMALL LETTER E WITH OGONEK +\defineactivetoken 235 {\ediaeresis} % 00EB LATIN SMALL LETTER E WITH DIAERESIS +\defineactivetoken 236 {\ecaron} % 011B LATIN SMALL LETTER E WITH CARON +\defineactivetoken 237 {\iacute} % 00ED LATIN SMALL LETTER I WITH ACUTE +\defineactivetoken 238 {\icircumflex} % 00EE LATIN SMALL LETTER I WITH CIRCUMFLEX +\defineactivetoken 239 {\dcaron} % 010F LATIN SMALL LETTER D WITH CARON +\defineactivetoken 240 {\dstroke} % 0111 LATIN SMALL LETTER D WITH STROKE +\defineactivetoken 241 {\nacute} % 0144 LATIN SMALL LETTER N WITH ACUTE +\defineactivetoken 242 {\ncaron} % 0148 LATIN SMALL LETTER N WITH CARON +\defineactivetoken 243 {\oacute} % 00F3 LATIN SMALL LETTER O WITH ACUTE +\defineactivetoken 244 {\ocircumflex} % 00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX +\defineactivetoken 245 {\ohungarumlaut} % 0151 LATIN SMALL LETTER O WITH DOUBLE ACUTE +\defineactivetoken 246 {\odiaeresis} % 00F6 LATIN SMALL LETTER O WITH DIAERESIS +\defineactivetoken 247 {\textdiv} % 00F7 DIVISION SIGN +\defineactivetoken 248 {\rcaron} % 0159 LATIN SMALL LETTER R WITH CARON +\defineactivetoken 249 {\uring} % 016F LATIN SMALL LETTER U WITH RING ABOVE +\defineactivetoken 250 {\uacute} % 00FA LATIN SMALL LETTER U WITH ACUTE +\defineactivetoken 251 {\uhungarumlaut} % 0171 LATIN SMALL LETTER U WITH DOUBLE ACUTE +\defineactivetoken 252 {\udiaeresis} % 00FC LATIN SMALL LETTER U WITH DIAERESIS +\defineactivetoken 253 {\yacute} % 00FD LATIN SMALL LETTER Y WITH ACUTE +\defineactivetoken 254 {\tcedilla} % 0163 LATIN SMALL LETTER T WITH CEDILLA +\defineactivetoken 255 {\textdotaccent} % 02D9 DOT ABOVE + +\stopregime + diff --git a/tex/context/base/regi-cp1251.lua b/tex/context/base/regi-cp1251.lua new file mode 100644 index 000000000..42fe0b340 --- /dev/null +++ b/tex/context/base/regi-cp1251.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-cp1251'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["cp1251"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F, + 0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F, + 0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7, 0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407, + 0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7, 0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F +} diff --git a/tex/context/base/regi-cp1251.mkii b/tex/context/base/regi-cp1251.mkii new file mode 100644 index 000000000..60f04170b --- /dev/null +++ b/tex/context/base/regi-cp1251.mkii @@ -0,0 +1,152 @@ +%D \module +%D [ file=regi-cp1251, +%D version=2005.12.26, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=cp1251 (Cyrillic), +%D author=script-generated, +%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. + +%D Support for cp1251 input encoding (regime) for Cyrillic. +%D +%D Usage: +%D \type{\enableregime[cp1251]} or \type{\enablereregime[windows-1251]} + + +\startregime[cp1251] + +\defineactivetoken 128 {\cyrillicDJE} % 0402 CYRILLIC CAPITAL LETTER DJE +\defineactivetoken 129 {\cyrillicGJE} % 0403 CYRILLIC CAPITAL LETTER GJE +\defineactivetoken 130 {\quotesinglebase} % 201A SINGLE LOW-9 QUOTATION MARK +\defineactivetoken 131 {\cyrillicgje} % 0453 CYRILLIC SMALL LETTER GJE +\defineactivetoken 132 {\quotedblbase} % 201E DOUBLE LOW-9 QUOTATION MARK +\defineactivetoken 133 {\textellipsis} % 2026 HORIZONTAL ELLIPSIS +\defineactivetoken 134 {\textdag} % 2020 DAGGER +\defineactivetoken 135 {\textddag} % 2021 DOUBLE DAGGER +\defineactivetoken 136 {\texteuro} % 20AC EURO SIGN +\defineactivetoken 137 {\perthousand} % 2030 PER MILLE SIGN +\defineactivetoken 138 {\cyrillicLJE} % 0409 CYRILLIC CAPITAL LETTER LJE +\defineactivetoken 139 {\guilsingleleft} % 2039 SINGLE LEFT-POINTING ANGLE QUOTATION MARK +\defineactivetoken 140 {\cyrillicNJE} % 040A CYRILLIC CAPITAL LETTER NJE +\defineactivetoken 141 {\cyrillicKJE} % 040C CYRILLIC CAPITAL LETTER KJE +\defineactivetoken 142 {\cyrillicTSHE} % 040B CYRILLIC CAPITAL LETTER TSHE +\defineactivetoken 143 {\cyrillicDZHE} % 040F CYRILLIC CAPITAL LETTER DZHE +\defineactivetoken 144 {\cyrillicdje} % 0452 CYRILLIC SMALL LETTER DJE +\defineactivetoken 145 {\quoteleft} % 2018 LEFT SINGLE QUOTATION MARK +\defineactivetoken 146 {\quoteright} % 2019 RIGHT SINGLE QUOTATION MARK +\defineactivetoken 147 {\quotedblleft} % 201C LEFT DOUBLE QUOTATION MARK +\defineactivetoken 148 {\quotedblright} % 201D RIGHT DOUBLE QUOTATION MARK +\defineactivetoken 149 {\textbullet} % 2022 BULLET +\defineactivetoken 150 {\endash} % 2013 EN DASH +\defineactivetoken 151 {\emdash} % 2014 EM DASH +\defineactivetoken 152 {\unknownchar} % +\defineactivetoken 153 {\trademark} % 2122 TRADE MARK SIGN +\defineactivetoken 154 {\cyrilliclje} % 0459 CYRILLIC SMALL LETTER LJE +\defineactivetoken 155 {\guilsingleright} % 203A SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +\defineactivetoken 156 {\cyrillicnje} % 045A CYRILLIC SMALL LETTER NJE +\defineactivetoken 157 {\cyrillickje} % 045C CYRILLIC SMALL LETTER KJE +\defineactivetoken 158 {\cyrillictshe} % 045B CYRILLIC SMALL LETTER TSHE +\defineactivetoken 159 {\cyrillicdzhe} % 045F CYRILLIC SMALL LETTER DZHE +\defineactivetoken 160 {\nonbreakablespace} % 00A0 NO-BREAK SPACE +\defineactivetoken 161 {\cyrillicUSHRT} % 040E CYRILLIC CAPITAL LETTER SHORT U +\defineactivetoken 162 {\cyrillicushrt} % 045E CYRILLIC SMALL LETTER SHORT U +\defineactivetoken 163 {\cyrillicJE} % 0408 CYRILLIC CAPITAL LETTER JE +\defineactivetoken 164 {\textcurrency} % 00A4 CURRENCY SIGN +\defineactivetoken 165 {\cyrillicGHEupturn} % 0490 CYRILLIC CAPITAL LETTER GHE WITH UPTURN +\defineactivetoken 166 {\textbrokenbar} % 00A6 BROKEN BAR +\defineactivetoken 167 {\sectionmark} % 00A7 SECTION SIGN +\defineactivetoken 168 {\cyrillicYO} % 0401 CYRILLIC CAPITAL LETTER IO +\defineactivetoken 169 {\copyright} % 00A9 COPYRIGHT SIGN +\defineactivetoken 170 {\cyrillicIE} % 0404 CYRILLIC CAPITAL LETTER UKRAINIAN IE +\defineactivetoken 171 {\leftguillemot} % 00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 172 {\textlognot} % 00AC NOT SIGN +\defineactivetoken 173 {\softhyphen} % 00AD SOFT HYPHEN +\defineactivetoken 174 {\registered} % 00AE REGISTERED SIGN +\defineactivetoken 175 {\cyrillicYI} % 0407 CYRILLIC CAPITAL LETTER YI +\defineactivetoken 176 {\textdegree} % 00B0 DEGREE SIGN +\defineactivetoken 177 {\textpm} % 00B1 PLUS-MINUS SIGN +\defineactivetoken 178 {\cyrillicII} % 0406 CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I +\defineactivetoken 179 {\cyrillicii} % 0456 CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I +\defineactivetoken 180 {\cyrillicgheupturn} % 0491 CYRILLIC SMALL LETTER GHE WITH UPTURN +\defineactivetoken 181 {\textmu} % 00B5 MICRO SIGN +\defineactivetoken 182 {\paragraphmark} % 00B6 PILCROW SIGN +\defineactivetoken 183 {\periodcentered} % 00B7 MIDDLE DOT +\defineactivetoken 184 {\cyrillicyo} % 0451 CYRILLIC SMALL LETTER IO +\defineactivetoken 185 {\textnumero} % 2116 NUMERO SIGN +\defineactivetoken 186 {\cyrillicie} % 0454 CYRILLIC SMALL LETTER UKRAINIAN IE +\defineactivetoken 187 {\rightguillemot} % 00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 188 {\cyrillicje} % 0458 CYRILLIC SMALL LETTER JE +\defineactivetoken 189 {\cyrillicDZE} % 0405 CYRILLIC CAPITAL LETTER DZE +\defineactivetoken 190 {\cyrillicdze} % 0455 CYRILLIC SMALL LETTER DZE +\defineactivetoken 191 {\cyrillicyi} % 0457 CYRILLIC SMALL LETTER YI +\defineactivetoken 192 {\cyrillicA} % 0410 CYRILLIC CAPITAL LETTER A +\defineactivetoken 193 {\cyrillicB} % 0411 CYRILLIC CAPITAL LETTER BE +\defineactivetoken 194 {\cyrillicV} % 0412 CYRILLIC CAPITAL LETTER VE +\defineactivetoken 195 {\cyrillicG} % 0413 CYRILLIC CAPITAL LETTER GHE +\defineactivetoken 196 {\cyrillicD} % 0414 CYRILLIC CAPITAL LETTER DE +\defineactivetoken 197 {\cyrillicE} % 0415 CYRILLIC CAPITAL LETTER IE +\defineactivetoken 198 {\cyrillicZH} % 0416 CYRILLIC CAPITAL LETTER ZHE +\defineactivetoken 199 {\cyrillicZ} % 0417 CYRILLIC CAPITAL LETTER ZE +\defineactivetoken 200 {\cyrillicI} % 0418 CYRILLIC CAPITAL LETTER I +\defineactivetoken 201 {\cyrillicISHRT} % 0419 CYRILLIC CAPITAL LETTER SHORT I +\defineactivetoken 202 {\cyrillicK} % 041A CYRILLIC CAPITAL LETTER KA +\defineactivetoken 203 {\cyrillicL} % 041B CYRILLIC CAPITAL LETTER EL +\defineactivetoken 204 {\cyrillicM} % 041C CYRILLIC CAPITAL LETTER EM +\defineactivetoken 205 {\cyrillicN} % 041D CYRILLIC CAPITAL LETTER EN +\defineactivetoken 206 {\cyrillicO} % 041E CYRILLIC CAPITAL LETTER O +\defineactivetoken 207 {\cyrillicP} % 041F CYRILLIC CAPITAL LETTER PE +\defineactivetoken 208 {\cyrillicR} % 0420 CYRILLIC CAPITAL LETTER ER +\defineactivetoken 209 {\cyrillicS} % 0421 CYRILLIC CAPITAL LETTER ES +\defineactivetoken 210 {\cyrillicT} % 0422 CYRILLIC CAPITAL LETTER TE +\defineactivetoken 211 {\cyrillicU} % 0423 CYRILLIC CAPITAL LETTER U +\defineactivetoken 212 {\cyrillicF} % 0424 CYRILLIC CAPITAL LETTER EF +\defineactivetoken 213 {\cyrillicH} % 0425 CYRILLIC CAPITAL LETTER HA +\defineactivetoken 214 {\cyrillicC} % 0426 CYRILLIC CAPITAL LETTER TSE +\defineactivetoken 215 {\cyrillicCH} % 0427 CYRILLIC CAPITAL LETTER CHE +\defineactivetoken 216 {\cyrillicSH} % 0428 CYRILLIC CAPITAL LETTER SHA +\defineactivetoken 217 {\cyrillicSHCH} % 0429 CYRILLIC CAPITAL LETTER SHCHA +\defineactivetoken 218 {\cyrillicHRDSN} % 042A CYRILLIC CAPITAL LETTER HARD SIGN +\defineactivetoken 219 {\cyrillicERY} % 042B CYRILLIC CAPITAL LETTER YERU +\defineactivetoken 220 {\cyrillicSFTSN} % 042C CYRILLIC CAPITAL LETTER SOFT SIGN +\defineactivetoken 221 {\cyrillicEREV} % 042D CYRILLIC CAPITAL LETTER E +\defineactivetoken 222 {\cyrillicYU} % 042E CYRILLIC CAPITAL LETTER YU +\defineactivetoken 223 {\cyrillicYA} % 042F CYRILLIC CAPITAL LETTER YA +\defineactivetoken 224 {\cyrillica} % 0430 CYRILLIC SMALL LETTER A +\defineactivetoken 225 {\cyrillicb} % 0431 CYRILLIC SMALL LETTER BE +\defineactivetoken 226 {\cyrillicv} % 0432 CYRILLIC SMALL LETTER VE +\defineactivetoken 227 {\cyrillicg} % 0433 CYRILLIC SMALL LETTER GHE +\defineactivetoken 228 {\cyrillicd} % 0434 CYRILLIC SMALL LETTER DE +\defineactivetoken 229 {\cyrillice} % 0435 CYRILLIC SMALL LETTER IE +\defineactivetoken 230 {\cyrilliczh} % 0436 CYRILLIC SMALL LETTER ZHE +\defineactivetoken 231 {\cyrillicz} % 0437 CYRILLIC SMALL LETTER ZE +\defineactivetoken 232 {\cyrillici} % 0438 CYRILLIC SMALL LETTER I +\defineactivetoken 233 {\cyrillicishrt} % 0439 CYRILLIC SMALL LETTER SHORT I +\defineactivetoken 234 {\cyrillick} % 043A CYRILLIC SMALL LETTER KA +\defineactivetoken 235 {\cyrillicl} % 043B CYRILLIC SMALL LETTER EL +\defineactivetoken 236 {\cyrillicm} % 043C CYRILLIC SMALL LETTER EM +\defineactivetoken 237 {\cyrillicn} % 043D CYRILLIC SMALL LETTER EN +\defineactivetoken 238 {\cyrillico} % 043E CYRILLIC SMALL LETTER O +\defineactivetoken 239 {\cyrillicp} % 043F CYRILLIC SMALL LETTER PE +\defineactivetoken 240 {\cyrillicr} % 0440 CYRILLIC SMALL LETTER ER +\defineactivetoken 241 {\cyrillics} % 0441 CYRILLIC SMALL LETTER ES +\defineactivetoken 242 {\cyrillict} % 0442 CYRILLIC SMALL LETTER TE +\defineactivetoken 243 {\cyrillicu} % 0443 CYRILLIC SMALL LETTER U +\defineactivetoken 244 {\cyrillicf} % 0444 CYRILLIC SMALL LETTER EF +\defineactivetoken 245 {\cyrillich} % 0445 CYRILLIC SMALL LETTER HA +\defineactivetoken 246 {\cyrillicc} % 0446 CYRILLIC SMALL LETTER TSE +\defineactivetoken 247 {\cyrillicch} % 0447 CYRILLIC SMALL LETTER CHE +\defineactivetoken 248 {\cyrillicsh} % 0448 CYRILLIC SMALL LETTER SHA +\defineactivetoken 249 {\cyrillicshch} % 0449 CYRILLIC SMALL LETTER SHCHA +\defineactivetoken 250 {\cyrillichrdsn} % 044A CYRILLIC SMALL LETTER HARD SIGN +\defineactivetoken 251 {\cyrillicery} % 044B CYRILLIC SMALL LETTER YERU +\defineactivetoken 252 {\cyrillicsftsn} % 044C CYRILLIC SMALL LETTER SOFT SIGN +\defineactivetoken 253 {\cyrillicerev} % 044D CYRILLIC SMALL LETTER E +\defineactivetoken 254 {\cyrillicyu} % 044E CYRILLIC SMALL LETTER YU +\defineactivetoken 255 {\cyrillicya} % 044F CYRILLIC SMALL LETTER YA + +\stopregime + diff --git a/tex/context/base/regi-cp1252.lua b/tex/context/base/regi-cp1252.lua new file mode 100644 index 000000000..74b2f3761 --- /dev/null +++ b/tex/context/base/regi-cp1252.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-cp1252'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["cp1252"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF +} diff --git a/tex/context/base/regi-cp1252.mkii b/tex/context/base/regi-cp1252.mkii new file mode 100644 index 000000000..9a54f178f --- /dev/null +++ b/tex/context/base/regi-cp1252.mkii @@ -0,0 +1,156 @@ +%D \module +%D [ file=regi-cp1252, +%D version=2005.12.26, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=cp1252 (West European), +%D author=script-generated, +%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. + +%D Support for cp1252 input encoding (regime) for West European languages, +%D see also iso-8859-1 and iso-8859-15. +%D +%D (Contributors to the original file: Tobias Burnus, Hans Hagen \& Victor Figurnov.) +%D +%D Usage: +%D \type{\enableregime[cp1252]} or \type{\enablereregime[windows-1252]} +%D % and \enableregime[win] for backward-compatibility + + +\startregime[cp1252] + +\defineactivetoken 128 {\texteuro} % 20AC EURO SIGN +\defineactivetoken 129 {\unknownchar} % +\defineactivetoken 130 {\quotesinglebase} % 201A SINGLE LOW-9 QUOTATION MARK +\defineactivetoken 131 {\fhook} % 0192 LATIN SMALL LETTER F WITH HOOK +\defineactivetoken 132 {\quotedblbase} % 201E DOUBLE LOW-9 QUOTATION MARK +\defineactivetoken 133 {\textellipsis} % 2026 HORIZONTAL ELLIPSIS +\defineactivetoken 134 {\textdag} % 2020 DAGGER +\defineactivetoken 135 {\textddag} % 2021 DOUBLE DAGGER +\defineactivetoken 136 {\textcircumflex} % 02C6 MODIFIER LETTER CIRCUMFLEX ACCENT +\defineactivetoken 137 {\perthousand} % 2030 PER MILLE SIGN +\defineactivetoken 138 {\Scaron} % 0160 LATIN CAPITAL LETTER S WITH CARON +\defineactivetoken 139 {\guilsingleleft} % 2039 SINGLE LEFT-POINTING ANGLE QUOTATION MARK +\defineactivetoken 140 {\OEligature} % 0152 LATIN CAPITAL LIGATURE OE +\defineactivetoken 141 {\unknownchar} % +\defineactivetoken 142 {\Zcaron} % 017D LATIN CAPITAL LETTER Z WITH CARON +\defineactivetoken 143 {\unknownchar} % +\defineactivetoken 144 {\unknownchar} % +\defineactivetoken 145 {\quoteleft} % 2018 LEFT SINGLE QUOTATION MARK +\defineactivetoken 146 {\quoteright} % 2019 RIGHT SINGLE QUOTATION MARK +\defineactivetoken 147 {\quotedblleft} % 201C LEFT DOUBLE QUOTATION MARK +\defineactivetoken 148 {\quotedblright} % 201D RIGHT DOUBLE QUOTATION MARK +\defineactivetoken 149 {\textbullet} % 2022 BULLET +\defineactivetoken 150 {\endash} % 2013 EN DASH +\defineactivetoken 151 {\emdash} % 2014 EM DASH +\defineactivetoken 152 {\texttilde} % 02DC SMALL TILDE +\defineactivetoken 153 {\trademark} % 2122 TRADE MARK SIGN +\defineactivetoken 154 {\scaron} % 0161 LATIN SMALL LETTER S WITH CARON +\defineactivetoken 155 {\guilsingleright} % 203A SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +\defineactivetoken 156 {\oeligature} % 0153 LATIN SMALL LIGATURE OE +\defineactivetoken 157 {\unknownchar} % +\defineactivetoken 158 {\zcaron} % 017E LATIN SMALL LETTER Z WITH CARON +\defineactivetoken 159 {\Ydiaeresis} % 0178 LATIN CAPITAL LETTER Y WITH DIAERESIS +\defineactivetoken 160 {\nonbreakablespace} % 00A0 NO-BREAK SPACE +\defineactivetoken 161 {\exclamdown} % 00A1 INVERTED EXCLAMATION MARK +\defineactivetoken 162 {\textcent} % 00A2 CENT SIGN +\defineactivetoken 163 {\textsterling} % 00A3 POUND SIGN +\defineactivetoken 164 {\textcurrency} % 00A4 CURRENCY SIGN +\defineactivetoken 165 {\textyen} % 00A5 YEN SIGN +\defineactivetoken 166 {\textbrokenbar} % 00A6 BROKEN BAR +\defineactivetoken 167 {\sectionmark} % 00A7 SECTION SIGN +\defineactivetoken 168 {\textdiaeresis} % 00A8 DIAERESIS +\defineactivetoken 169 {\copyright} % 00A9 COPYRIGHT SIGN +\defineactivetoken 170 {\ordfeminine} % 00AA FEMININE ORDINAL INDICATOR +\defineactivetoken 171 {\leftguillemot} % 00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 172 {\textlognot} % 00AC NOT SIGN +\defineactivetoken 173 {\softhyphen} % 00AD SOFT HYPHEN +\defineactivetoken 174 {\registered} % 00AE REGISTERED SIGN +\defineactivetoken 175 {\textmacron} % 00AF MACRON +\defineactivetoken 176 {\textdegree} % 00B0 DEGREE SIGN +\defineactivetoken 177 {\textpm} % 00B1 PLUS-MINUS SIGN +\defineactivetoken 178 {\twosuperior} % 00B2 SUPERSCRIPT TWO +\defineactivetoken 179 {\threesuperior} % 00B3 SUPERSCRIPT THREE +\defineactivetoken 180 {\textacute} % 00B4 ACUTE ACCENT +\defineactivetoken 181 {\textmu} % 00B5 MICRO SIGN +\defineactivetoken 182 {\paragraphmark} % 00B6 PILCROW SIGN +\defineactivetoken 183 {\periodcentered} % 00B7 MIDDLE DOT +\defineactivetoken 184 {\textcedilla} % 00B8 CEDILLA +\defineactivetoken 185 {\onesuperior} % 00B9 SUPERSCRIPT ONE +\defineactivetoken 186 {\ordmasculine} % 00BA MASCULINE ORDINAL INDICATOR +\defineactivetoken 187 {\rightguillemot} % 00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 188 {\onequarter} % 00BC VULGAR FRACTION ONE QUARTER +\defineactivetoken 189 {\onehalf} % 00BD VULGAR FRACTION ONE HALF +\defineactivetoken 190 {\threequarter} % 00BE VULGAR FRACTION THREE QUARTERS +\defineactivetoken 191 {\questiondown} % 00BF INVERTED QUESTION MARK +\defineactivetoken 192 {\Agrave} % 00C0 LATIN CAPITAL LETTER A WITH GRAVE +\defineactivetoken 193 {\Aacute} % 00C1 LATIN CAPITAL LETTER A WITH ACUTE +\defineactivetoken 194 {\Acircumflex} % 00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX +\defineactivetoken 195 {\Atilde} % 00C3 LATIN CAPITAL LETTER A WITH TILDE +\defineactivetoken 196 {\Adiaeresis} % 00C4 LATIN CAPITAL LETTER A WITH DIAERESIS +\defineactivetoken 197 {\Aring} % 00C5 LATIN CAPITAL LETTER A WITH RING ABOVE +\defineactivetoken 198 {\AEligature} % 00C6 LATIN CAPITAL LETTER AE +\defineactivetoken 199 {\Ccedilla} % 00C7 LATIN CAPITAL LETTER C WITH CEDILLA +\defineactivetoken 200 {\Egrave} % 00C8 LATIN CAPITAL LETTER E WITH GRAVE +\defineactivetoken 201 {\Eacute} % 00C9 LATIN CAPITAL LETTER E WITH ACUTE +\defineactivetoken 202 {\Ecircumflex} % 00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX +\defineactivetoken 203 {\Ediaeresis} % 00CB LATIN CAPITAL LETTER E WITH DIAERESIS +\defineactivetoken 204 {\Igrave} % 00CC LATIN CAPITAL LETTER I WITH GRAVE +\defineactivetoken 205 {\Iacute} % 00CD LATIN CAPITAL LETTER I WITH ACUTE +\defineactivetoken 206 {\Icircumflex} % 00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX +\defineactivetoken 207 {\Idiaeresis} % 00CF LATIN CAPITAL LETTER I WITH DIAERESIS +\defineactivetoken 208 {\Eth} % 00D0 LATIN CAPITAL LETTER ETH +\defineactivetoken 209 {\Ntilde} % 00D1 LATIN CAPITAL LETTER N WITH TILDE +\defineactivetoken 210 {\Ograve} % 00D2 LATIN CAPITAL LETTER O WITH GRAVE +\defineactivetoken 211 {\Oacute} % 00D3 LATIN CAPITAL LETTER O WITH ACUTE +\defineactivetoken 212 {\Ocircumflex} % 00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX +\defineactivetoken 213 {\Otilde} % 00D5 LATIN CAPITAL LETTER O WITH TILDE +\defineactivetoken 214 {\Odiaeresis} % 00D6 LATIN CAPITAL LETTER O WITH DIAERESIS +\defineactivetoken 215 {\textmultiply} % 00D7 MULTIPLICATION SIGN +\defineactivetoken 216 {\Ostroke} % 00D8 LATIN CAPITAL LETTER O WITH STROKE +\defineactivetoken 217 {\Ugrave} % 00D9 LATIN CAPITAL LETTER U WITH GRAVE +\defineactivetoken 218 {\Uacute} % 00DA LATIN CAPITAL LETTER U WITH ACUTE +\defineactivetoken 219 {\Ucircumflex} % 00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX +\defineactivetoken 220 {\Udiaeresis} % 00DC LATIN CAPITAL LETTER U WITH DIAERESIS +\defineactivetoken 221 {\Yacute} % 00DD LATIN CAPITAL LETTER Y WITH ACUTE +\defineactivetoken 222 {\Thorn} % 00DE LATIN CAPITAL LETTER THORN +\defineactivetoken 223 {\ssharp} % 00DF LATIN SMALL LETTER SHARP S +\defineactivetoken 224 {\agrave} % 00E0 LATIN SMALL LETTER A WITH GRAVE +\defineactivetoken 225 {\aacute} % 00E1 LATIN SMALL LETTER A WITH ACUTE +\defineactivetoken 226 {\acircumflex} % 00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX +\defineactivetoken 227 {\atilde} % 00E3 LATIN SMALL LETTER A WITH TILDE +\defineactivetoken 228 {\adiaeresis} % 00E4 LATIN SMALL LETTER A WITH DIAERESIS +\defineactivetoken 229 {\aring} % 00E5 LATIN SMALL LETTER A WITH RING ABOVE +\defineactivetoken 230 {\aeligature} % 00E6 LATIN SMALL LETTER AE +\defineactivetoken 231 {\ccedilla} % 00E7 LATIN SMALL LETTER C WITH CEDILLA +\defineactivetoken 232 {\egrave} % 00E8 LATIN SMALL LETTER E WITH GRAVE +\defineactivetoken 233 {\eacute} % 00E9 LATIN SMALL LETTER E WITH ACUTE +\defineactivetoken 234 {\ecircumflex} % 00EA LATIN SMALL LETTER E WITH CIRCUMFLEX +\defineactivetoken 235 {\ediaeresis} % 00EB LATIN SMALL LETTER E WITH DIAERESIS +\defineactivetoken 236 {\igrave} % 00EC LATIN SMALL LETTER I WITH GRAVE +\defineactivetoken 237 {\iacute} % 00ED LATIN SMALL LETTER I WITH ACUTE +\defineactivetoken 238 {\icircumflex} % 00EE LATIN SMALL LETTER I WITH CIRCUMFLEX +\defineactivetoken 239 {\idiaeresis} % 00EF LATIN SMALL LETTER I WITH DIAERESIS +\defineactivetoken 240 {\eth} % 00F0 LATIN SMALL LETTER ETH +\defineactivetoken 241 {\ntilde} % 00F1 LATIN SMALL LETTER N WITH TILDE +\defineactivetoken 242 {\ograve} % 00F2 LATIN SMALL LETTER O WITH GRAVE +\defineactivetoken 243 {\oacute} % 00F3 LATIN SMALL LETTER O WITH ACUTE +\defineactivetoken 244 {\ocircumflex} % 00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX +\defineactivetoken 245 {\otilde} % 00F5 LATIN SMALL LETTER O WITH TILDE +\defineactivetoken 246 {\odiaeresis} % 00F6 LATIN SMALL LETTER O WITH DIAERESIS +\defineactivetoken 247 {\textdiv} % 00F7 DIVISION SIGN +\defineactivetoken 248 {\ostroke} % 00F8 LATIN SMALL LETTER O WITH STROKE +\defineactivetoken 249 {\ugrave} % 00F9 LATIN SMALL LETTER U WITH GRAVE +\defineactivetoken 250 {\uacute} % 00FA LATIN SMALL LETTER U WITH ACUTE +\defineactivetoken 251 {\ucircumflex} % 00FB LATIN SMALL LETTER U WITH CIRCUMFLEX +\defineactivetoken 252 {\udiaeresis} % 00FC LATIN SMALL LETTER U WITH DIAERESIS +\defineactivetoken 253 {\yacute} % 00FD LATIN SMALL LETTER Y WITH ACUTE +\defineactivetoken 254 {\thorn} % 00FE LATIN SMALL LETTER THORN +\defineactivetoken 255 {\ydiaeresis} % 00FF LATIN SMALL LETTER Y WITH DIAERESIS + +\stopregime + diff --git a/tex/context/base/regi-cp1253.lua b/tex/context/base/regi-cp1253.lua new file mode 100644 index 000000000..f14a186bb --- /dev/null +++ b/tex/context/base/regi-cp1253.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-cp1253'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["cp1253"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7, 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F, + 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, + 0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF, + 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, + 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000 +} diff --git a/tex/context/base/regi-cp1253.mkii b/tex/context/base/regi-cp1253.mkii new file mode 100644 index 000000000..24ec45eac --- /dev/null +++ b/tex/context/base/regi-cp1253.mkii @@ -0,0 +1,153 @@ +%D \module +%D [ file=regi-cp1253, +%D version=2005.12.26, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=cp1253 (Greek), +%D author=script-generated, +%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. + +%D Support for cp1253 input encoding (regime) for Greek, +%D see also iso-8859-7. +%D +%D Usage: +%D \type{\enableregime[cp1253]} or \type{\enablereregime[windows-1253]} + + +\startregime[cp1253] + +\defineactivetoken 128 {\texteuro} % 20AC EURO SIGN +\defineactivetoken 129 {\unknownchar} % +\defineactivetoken 130 {\quotesinglebase} % 201A SINGLE LOW-9 QUOTATION MARK +\defineactivetoken 131 {\fhook} % 0192 LATIN SMALL LETTER F WITH HOOK +\defineactivetoken 132 {\quotedblbase} % 201E DOUBLE LOW-9 QUOTATION MARK +\defineactivetoken 133 {\textellipsis} % 2026 HORIZONTAL ELLIPSIS +\defineactivetoken 134 {\textdag} % 2020 DAGGER +\defineactivetoken 135 {\textddag} % 2021 DOUBLE DAGGER +\defineactivetoken 136 {\unknownchar} % +\defineactivetoken 137 {\perthousand} % 2030 PER MILLE SIGN +\defineactivetoken 138 {\unknownchar} % +\defineactivetoken 139 {\guilsingleleft} % 2039 SINGLE LEFT-POINTING ANGLE QUOTATION MARK +\defineactivetoken 140 {\unknownchar} % +\defineactivetoken 141 {\unknownchar} % +\defineactivetoken 142 {\unknownchar} % +\defineactivetoken 143 {\unknownchar} % +\defineactivetoken 144 {\unknownchar} % +\defineactivetoken 145 {\quoteleft} % 2018 LEFT SINGLE QUOTATION MARK +\defineactivetoken 146 {\quoteright} % 2019 RIGHT SINGLE QUOTATION MARK +\defineactivetoken 147 {\quotedblleft} % 201C LEFT DOUBLE QUOTATION MARK +\defineactivetoken 148 {\quotedblright} % 201D RIGHT DOUBLE QUOTATION MARK +\defineactivetoken 149 {\textbullet} % 2022 BULLET +\defineactivetoken 150 {\endash} % 2013 EN DASH +\defineactivetoken 151 {\emdash} % 2014 EM DASH +\defineactivetoken 152 {\unknownchar} % +\defineactivetoken 153 {\trademark} % 2122 TRADE MARK SIGN +\defineactivetoken 154 {\unknownchar} % +\defineactivetoken 155 {\guilsingleright} % 203A SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +\defineactivetoken 156 {\unknownchar} % +\defineactivetoken 157 {\unknownchar} % +\defineactivetoken 158 {\unknownchar} % +\defineactivetoken 159 {\unknownchar} % +\defineactivetoken 160 {\nonbreakablespace} % 00A0 NO-BREAK SPACE +\defineactivetoken 161 {\greekdialytikatonos} % 0385 GREEK DIALYTIKA TONOS +\defineactivetoken 162 {\greekAlphatonos} % 0386 GREEK CAPITAL LETTER ALPHA WITH TONOS +\defineactivetoken 163 {\textsterling} % 00A3 POUND SIGN +\defineactivetoken 164 {\textcurrency} % 00A4 CURRENCY SIGN +\defineactivetoken 165 {\textyen} % 00A5 YEN SIGN +\defineactivetoken 166 {\textbrokenbar} % 00A6 BROKEN BAR +\defineactivetoken 167 {\sectionmark} % 00A7 SECTION SIGN +\defineactivetoken 168 {\textdiaeresis} % 00A8 DIAERESIS +\defineactivetoken 169 {\copyright} % 00A9 COPYRIGHT SIGN +\defineactivetoken 170 {\unknownchar} % +\defineactivetoken 171 {\leftguillemot} % 00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 172 {\textlognot} % 00AC NOT SIGN +\defineactivetoken 173 {\softhyphen} % 00AD SOFT HYPHEN +\defineactivetoken 174 {\registered} % 00AE REGISTERED SIGN +\defineactivetoken 175 {\texthorizontalbar} % 2015 HORIZONTAL BAR +\defineactivetoken 176 {\textdegree} % 00B0 DEGREE SIGN +\defineactivetoken 177 {\textpm} % 00B1 PLUS-MINUS SIGN +\defineactivetoken 178 {\twosuperior} % 00B2 SUPERSCRIPT TWO +\defineactivetoken 179 {\threesuperior} % 00B3 SUPERSCRIPT THREE +\defineactivetoken 180 {\greektonos} % 0384 GREEK TONOS +\defineactivetoken 181 {\textmu} % 00B5 MICRO SIGN +\defineactivetoken 182 {\paragraphmark} % 00B6 PILCROW SIGN +\defineactivetoken 183 {\periodcentered} % 00B7 MIDDLE DOT +\defineactivetoken 184 {\greekEpsilontonos} % 0388 GREEK CAPITAL LETTER EPSILON WITH TONOS +\defineactivetoken 185 {\greekEtatonos} % 0389 GREEK CAPITAL LETTER ETA WITH TONOS +\defineactivetoken 186 {\greekIotatonos} % 038A GREEK CAPITAL LETTER IOTA WITH TONOS +\defineactivetoken 187 {\rightguillemot} % 00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 188 {\greekOmicrontonos} % 038C GREEK CAPITAL LETTER OMICRON WITH TONOS +\defineactivetoken 189 {\onehalf} % 00BD VULGAR FRACTION ONE HALF +\defineactivetoken 190 {\greekUpsilontonos} % 038E GREEK CAPITAL LETTER UPSILON WITH TONOS +\defineactivetoken 191 {\greekOmegatonos} % 038F GREEK CAPITAL LETTER OMEGA WITH TONOS +\defineactivetoken 192 {\greekiotadialytikatonos} % 0390 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS +\defineactivetoken 193 {\greekAlpha} % 0391 GREEK CAPITAL LETTER ALPHA +\defineactivetoken 194 {\greekBeta} % 0392 GREEK CAPITAL LETTER BETA +\defineactivetoken 195 {\greekGamma} % 0393 GREEK CAPITAL LETTER GAMMA +\defineactivetoken 196 {\greekDelta} % 0394 GREEK CAPITAL LETTER DELTA +\defineactivetoken 197 {\greekEpsilon} % 0395 GREEK CAPITAL LETTER EPSILON +\defineactivetoken 198 {\greekZeta} % 0396 GREEK CAPITAL LETTER ZETA +\defineactivetoken 199 {\greekEta} % 0397 GREEK CAPITAL LETTER ETA +\defineactivetoken 200 {\greekTheta} % 0398 GREEK CAPITAL LETTER THETA +\defineactivetoken 201 {\greekIota} % 0399 GREEK CAPITAL LETTER IOTA +\defineactivetoken 202 {\greekKappa} % 039A GREEK CAPITAL LETTER KAPPA +\defineactivetoken 203 {\greekLambda} % 039B GREEK CAPITAL LETTER LAMDA +\defineactivetoken 204 {\greekMu} % 039C GREEK CAPITAL LETTER MU +\defineactivetoken 205 {\greekNu} % 039D GREEK CAPITAL LETTER NU +\defineactivetoken 206 {\greekXi} % 039E GREEK CAPITAL LETTER XI +\defineactivetoken 207 {\greekOmicron} % 039F GREEK CAPITAL LETTER OMICRON +\defineactivetoken 208 {\greekPi} % 03A0 GREEK CAPITAL LETTER PI +\defineactivetoken 209 {\greekRho} % 03A1 GREEK CAPITAL LETTER RHO +\defineactivetoken 210 {\unknownchar} % +\defineactivetoken 211 {\greekSigma} % 03A3 GREEK CAPITAL LETTER SIGMA +\defineactivetoken 212 {\greekTau} % 03A4 GREEK CAPITAL LETTER TAU +\defineactivetoken 213 {\greekUpsilon} % 03A5 GREEK CAPITAL LETTER UPSILON +\defineactivetoken 214 {\greekPhi} % 03A6 GREEK CAPITAL LETTER PHI +\defineactivetoken 215 {\greekChi} % 03A7 GREEK CAPITAL LETTER CHI +\defineactivetoken 216 {\greekPsi} % 03A8 GREEK CAPITAL LETTER PSI +\defineactivetoken 217 {\greekOmega} % 03A9 GREEK CAPITAL LETTER OMEGA +\defineactivetoken 218 {\greekIotadialytika} % 03AA GREEK CAPITAL LETTER IOTA WITH DIALYTIKA +\defineactivetoken 219 {\greekUpsilondialytika} % 03AB GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA +\defineactivetoken 220 {\greekalphatonos} % 03AC GREEK SMALL LETTER ALPHA WITH TONOS +\defineactivetoken 221 {\greekepsilontonos} % 03AD GREEK SMALL LETTER EPSILON WITH TONOS +\defineactivetoken 222 {\greeketatonos} % 03AE GREEK SMALL LETTER ETA WITH TONOS +\defineactivetoken 223 {\greekiotatonos} % 03AF GREEK SMALL LETTER IOTA WITH TONOS +\defineactivetoken 224 {\greekupsilondialytikatonos} % 03B0 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS +\defineactivetoken 225 {\greekalpha} % 03B1 GREEK SMALL LETTER ALPHA +\defineactivetoken 226 {\greekbeta} % 03B2 GREEK SMALL LETTER BETA +\defineactivetoken 227 {\greekgamma} % 03B3 GREEK SMALL LETTER GAMMA +\defineactivetoken 228 {\greekdelta} % 03B4 GREEK SMALL LETTER DELTA +\defineactivetoken 229 {\greekepsilon} % 03B5 GREEK SMALL LETTER EPSILON +\defineactivetoken 230 {\greekzeta} % 03B6 GREEK SMALL LETTER ZETA +\defineactivetoken 231 {\greeketa} % 03B7 GREEK SMALL LETTER ETA +\defineactivetoken 232 {\greektheta} % 03B8 GREEK SMALL LETTER THETA +\defineactivetoken 233 {\greekiota} % 03B9 GREEK SMALL LETTER IOTA +\defineactivetoken 234 {\greekkappa} % 03BA GREEK SMALL LETTER KAPPA +\defineactivetoken 235 {\greeklambda} % 03BB GREEK SMALL LETTER LAMDA +\defineactivetoken 236 {\greekmu} % 03BC GREEK SMALL LETTER MU +\defineactivetoken 237 {\greeknu} % 03BD GREEK SMALL LETTER NU +\defineactivetoken 238 {\greekxi} % 03BE GREEK SMALL LETTER XI +\defineactivetoken 239 {\greekomicron} % 03BF GREEK SMALL LETTER OMICRON +\defineactivetoken 240 {\greekpi} % 03C0 GREEK SMALL LETTER PI +\defineactivetoken 241 {\greekrho} % 03C1 GREEK SMALL LETTER RHO +\defineactivetoken 242 {\greekfinalsigma} % 03C2 GREEK SMALL LETTER FINAL SIGMA +\defineactivetoken 243 {\greeksigma} % 03C3 GREEK SMALL LETTER SIGMA +\defineactivetoken 244 {\greektau} % 03C4 GREEK SMALL LETTER TAU +\defineactivetoken 245 {\greekupsilon} % 03C5 GREEK SMALL LETTER UPSILON +\defineactivetoken 246 {\greekphi} % 03C6 GREEK SMALL LETTER PHI +\defineactivetoken 247 {\greekchi} % 03C7 GREEK SMALL LETTER CHI +\defineactivetoken 248 {\greekpsi} % 03C8 GREEK SMALL LETTER PSI +\defineactivetoken 249 {\greekomega} % 03C9 GREEK SMALL LETTER OMEGA +\defineactivetoken 250 {\greekiotadialytika} % 03CA GREEK SMALL LETTER IOTA WITH DIALYTIKA +\defineactivetoken 251 {\greekupsilondiaeresis} % 03CB GREEK SMALL LETTER UPSILON WITH DIALYTIKA +\defineactivetoken 252 {\greekomicrontonos} % 03CC GREEK SMALL LETTER OMICRON WITH TONOS +\defineactivetoken 253 {\greekupsilontonos} % 03CD GREEK SMALL LETTER UPSILON WITH TONOS +\defineactivetoken 254 {\greekomegatonos} % 03CE GREEK SMALL LETTER OMEGA WITH TONOS +\defineactivetoken 255 {\unknownchar} % + +\stopregime + diff --git a/tex/context/base/regi-cp1254.lua b/tex/context/base/regi-cp1254.lua new file mode 100644 index 000000000..76fbe9c49 --- /dev/null +++ b/tex/context/base/regi-cp1254.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-cp1254'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["cp1254"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF +} diff --git a/tex/context/base/regi-cp1254.mkii b/tex/context/base/regi-cp1254.mkii new file mode 100644 index 000000000..4dd509b9d --- /dev/null +++ b/tex/context/base/regi-cp1254.mkii @@ -0,0 +1,153 @@ +%D \module +%D [ file=regi-cp1254, +%D version=2005.12.26, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=cp1254 (Turkish), +%D author=script-generated, +%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. + +%D Support for cp1254 input encoding (regime) for Turkish, +%D see also iso-8859-9. +%D +%D Usage: +%D \type{\enableregime[cp1254]} or \type{\enablereregime[windows-1254]} + + +\startregime[cp1254] + +\defineactivetoken 128 {\texteuro} % 20AC EURO SIGN +\defineactivetoken 129 {\unknownchar} % +\defineactivetoken 130 {\quotesinglebase} % 201A SINGLE LOW-9 QUOTATION MARK +\defineactivetoken 131 {\fhook} % 0192 LATIN SMALL LETTER F WITH HOOK +\defineactivetoken 132 {\quotedblbase} % 201E DOUBLE LOW-9 QUOTATION MARK +\defineactivetoken 133 {\textellipsis} % 2026 HORIZONTAL ELLIPSIS +\defineactivetoken 134 {\textdag} % 2020 DAGGER +\defineactivetoken 135 {\textddag} % 2021 DOUBLE DAGGER +\defineactivetoken 136 {\textcircumflex} % 02C6 MODIFIER LETTER CIRCUMFLEX ACCENT +\defineactivetoken 137 {\perthousand} % 2030 PER MILLE SIGN +\defineactivetoken 138 {\Scaron} % 0160 LATIN CAPITAL LETTER S WITH CARON +\defineactivetoken 139 {\guilsingleleft} % 2039 SINGLE LEFT-POINTING ANGLE QUOTATION MARK +\defineactivetoken 140 {\OEligature} % 0152 LATIN CAPITAL LIGATURE OE +\defineactivetoken 141 {\unknownchar} % +\defineactivetoken 142 {\unknownchar} % +\defineactivetoken 143 {\unknownchar} % +\defineactivetoken 144 {\unknownchar} % +\defineactivetoken 145 {\quoteleft} % 2018 LEFT SINGLE QUOTATION MARK +\defineactivetoken 146 {\quoteright} % 2019 RIGHT SINGLE QUOTATION MARK +\defineactivetoken 147 {\quotedblleft} % 201C LEFT DOUBLE QUOTATION MARK +\defineactivetoken 148 {\quotedblright} % 201D RIGHT DOUBLE QUOTATION MARK +\defineactivetoken 149 {\textbullet} % 2022 BULLET +\defineactivetoken 150 {\endash} % 2013 EN DASH +\defineactivetoken 151 {\emdash} % 2014 EM DASH +\defineactivetoken 152 {\texttilde} % 02DC SMALL TILDE +\defineactivetoken 153 {\trademark} % 2122 TRADE MARK SIGN +\defineactivetoken 154 {\scaron} % 0161 LATIN SMALL LETTER S WITH CARON +\defineactivetoken 155 {\guilsingleright} % 203A SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +\defineactivetoken 156 {\oeligature} % 0153 LATIN SMALL LIGATURE OE +\defineactivetoken 157 {\unknownchar} % +\defineactivetoken 158 {\unknownchar} % +\defineactivetoken 159 {\Ydiaeresis} % 0178 LATIN CAPITAL LETTER Y WITH DIAERESIS +\defineactivetoken 160 {\nonbreakablespace} % 00A0 NO-BREAK SPACE +\defineactivetoken 161 {\exclamdown} % 00A1 INVERTED EXCLAMATION MARK +\defineactivetoken 162 {\textcent} % 00A2 CENT SIGN +\defineactivetoken 163 {\textsterling} % 00A3 POUND SIGN +\defineactivetoken 164 {\textcurrency} % 00A4 CURRENCY SIGN +\defineactivetoken 165 {\textyen} % 00A5 YEN SIGN +\defineactivetoken 166 {\textbrokenbar} % 00A6 BROKEN BAR +\defineactivetoken 167 {\sectionmark} % 00A7 SECTION SIGN +\defineactivetoken 168 {\textdiaeresis} % 00A8 DIAERESIS +\defineactivetoken 169 {\copyright} % 00A9 COPYRIGHT SIGN +\defineactivetoken 170 {\ordfeminine} % 00AA FEMININE ORDINAL INDICATOR +\defineactivetoken 171 {\leftguillemot} % 00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 172 {\textlognot} % 00AC NOT SIGN +\defineactivetoken 173 {\softhyphen} % 00AD SOFT HYPHEN +\defineactivetoken 174 {\registered} % 00AE REGISTERED SIGN +\defineactivetoken 175 {\textmacron} % 00AF MACRON +\defineactivetoken 176 {\textdegree} % 00B0 DEGREE SIGN +\defineactivetoken 177 {\textpm} % 00B1 PLUS-MINUS SIGN +\defineactivetoken 178 {\twosuperior} % 00B2 SUPERSCRIPT TWO +\defineactivetoken 179 {\threesuperior} % 00B3 SUPERSCRIPT THREE +\defineactivetoken 180 {\textacute} % 00B4 ACUTE ACCENT +\defineactivetoken 181 {\textmu} % 00B5 MICRO SIGN +\defineactivetoken 182 {\paragraphmark} % 00B6 PILCROW SIGN +\defineactivetoken 183 {\periodcentered} % 00B7 MIDDLE DOT +\defineactivetoken 184 {\textcedilla} % 00B8 CEDILLA +\defineactivetoken 185 {\onesuperior} % 00B9 SUPERSCRIPT ONE +\defineactivetoken 186 {\ordmasculine} % 00BA MASCULINE ORDINAL INDICATOR +\defineactivetoken 187 {\rightguillemot} % 00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 188 {\onequarter} % 00BC VULGAR FRACTION ONE QUARTER +\defineactivetoken 189 {\onehalf} % 00BD VULGAR FRACTION ONE HALF +\defineactivetoken 190 {\threequarter} % 00BE VULGAR FRACTION THREE QUARTERS +\defineactivetoken 191 {\questiondown} % 00BF INVERTED QUESTION MARK +\defineactivetoken 192 {\Agrave} % 00C0 LATIN CAPITAL LETTER A WITH GRAVE +\defineactivetoken 193 {\Aacute} % 00C1 LATIN CAPITAL LETTER A WITH ACUTE +\defineactivetoken 194 {\Acircumflex} % 00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX +\defineactivetoken 195 {\Atilde} % 00C3 LATIN CAPITAL LETTER A WITH TILDE +\defineactivetoken 196 {\Adiaeresis} % 00C4 LATIN CAPITAL LETTER A WITH DIAERESIS +\defineactivetoken 197 {\Aring} % 00C5 LATIN CAPITAL LETTER A WITH RING ABOVE +\defineactivetoken 198 {\AEligature} % 00C6 LATIN CAPITAL LETTER AE +\defineactivetoken 199 {\Ccedilla} % 00C7 LATIN CAPITAL LETTER C WITH CEDILLA +\defineactivetoken 200 {\Egrave} % 00C8 LATIN CAPITAL LETTER E WITH GRAVE +\defineactivetoken 201 {\Eacute} % 00C9 LATIN CAPITAL LETTER E WITH ACUTE +\defineactivetoken 202 {\Ecircumflex} % 00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX +\defineactivetoken 203 {\Ediaeresis} % 00CB LATIN CAPITAL LETTER E WITH DIAERESIS +\defineactivetoken 204 {\Igrave} % 00CC LATIN CAPITAL LETTER I WITH GRAVE +\defineactivetoken 205 {\Iacute} % 00CD LATIN CAPITAL LETTER I WITH ACUTE +\defineactivetoken 206 {\Icircumflex} % 00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX +\defineactivetoken 207 {\Idiaeresis} % 00CF LATIN CAPITAL LETTER I WITH DIAERESIS +\defineactivetoken 208 {\Gbreve} % 011E LATIN CAPITAL LETTER G WITH BREVE +\defineactivetoken 209 {\Ntilde} % 00D1 LATIN CAPITAL LETTER N WITH TILDE +\defineactivetoken 210 {\Ograve} % 00D2 LATIN CAPITAL LETTER O WITH GRAVE +\defineactivetoken 211 {\Oacute} % 00D3 LATIN CAPITAL LETTER O WITH ACUTE +\defineactivetoken 212 {\Ocircumflex} % 00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX +\defineactivetoken 213 {\Otilde} % 00D5 LATIN CAPITAL LETTER O WITH TILDE +\defineactivetoken 214 {\Odiaeresis} % 00D6 LATIN CAPITAL LETTER O WITH DIAERESIS +\defineactivetoken 215 {\textmultiply} % 00D7 MULTIPLICATION SIGN +\defineactivetoken 216 {\Ostroke} % 00D8 LATIN CAPITAL LETTER O WITH STROKE +\defineactivetoken 217 {\Ugrave} % 00D9 LATIN CAPITAL LETTER U WITH GRAVE +\defineactivetoken 218 {\Uacute} % 00DA LATIN CAPITAL LETTER U WITH ACUTE +\defineactivetoken 219 {\Ucircumflex} % 00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX +\defineactivetoken 220 {\Udiaeresis} % 00DC LATIN CAPITAL LETTER U WITH DIAERESIS +\defineactivetoken 221 {\Idotaccent} % 0130 LATIN CAPITAL LETTER I WITH DOT ABOVE +\defineactivetoken 222 {\Scedilla} % 015E LATIN CAPITAL LETTER S WITH CEDILLA +\defineactivetoken 223 {\ssharp} % 00DF LATIN SMALL LETTER SHARP S +\defineactivetoken 224 {\agrave} % 00E0 LATIN SMALL LETTER A WITH GRAVE +\defineactivetoken 225 {\aacute} % 00E1 LATIN SMALL LETTER A WITH ACUTE +\defineactivetoken 226 {\acircumflex} % 00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX +\defineactivetoken 227 {\atilde} % 00E3 LATIN SMALL LETTER A WITH TILDE +\defineactivetoken 228 {\adiaeresis} % 00E4 LATIN SMALL LETTER A WITH DIAERESIS +\defineactivetoken 229 {\aring} % 00E5 LATIN SMALL LETTER A WITH RING ABOVE +\defineactivetoken 230 {\aeligature} % 00E6 LATIN SMALL LETTER AE +\defineactivetoken 231 {\ccedilla} % 00E7 LATIN SMALL LETTER C WITH CEDILLA +\defineactivetoken 232 {\egrave} % 00E8 LATIN SMALL LETTER E WITH GRAVE +\defineactivetoken 233 {\eacute} % 00E9 LATIN SMALL LETTER E WITH ACUTE +\defineactivetoken 234 {\ecircumflex} % 00EA LATIN SMALL LETTER E WITH CIRCUMFLEX +\defineactivetoken 235 {\ediaeresis} % 00EB LATIN SMALL LETTER E WITH DIAERESIS +\defineactivetoken 236 {\igrave} % 00EC LATIN SMALL LETTER I WITH GRAVE +\defineactivetoken 237 {\iacute} % 00ED LATIN SMALL LETTER I WITH ACUTE +\defineactivetoken 238 {\icircumflex} % 00EE LATIN SMALL LETTER I WITH CIRCUMFLEX +\defineactivetoken 239 {\idiaeresis} % 00EF LATIN SMALL LETTER I WITH DIAERESIS +\defineactivetoken 240 {\gbreve} % 011F LATIN SMALL LETTER G WITH BREVE +\defineactivetoken 241 {\ntilde} % 00F1 LATIN SMALL LETTER N WITH TILDE +\defineactivetoken 242 {\ograve} % 00F2 LATIN SMALL LETTER O WITH GRAVE +\defineactivetoken 243 {\oacute} % 00F3 LATIN SMALL LETTER O WITH ACUTE +\defineactivetoken 244 {\ocircumflex} % 00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX +\defineactivetoken 245 {\otilde} % 00F5 LATIN SMALL LETTER O WITH TILDE +\defineactivetoken 246 {\odiaeresis} % 00F6 LATIN SMALL LETTER O WITH DIAERESIS +\defineactivetoken 247 {\textdiv} % 00F7 DIVISION SIGN +\defineactivetoken 248 {\ostroke} % 00F8 LATIN SMALL LETTER O WITH STROKE +\defineactivetoken 249 {\ugrave} % 00F9 LATIN SMALL LETTER U WITH GRAVE +\defineactivetoken 250 {\uacute} % 00FA LATIN SMALL LETTER U WITH ACUTE +\defineactivetoken 251 {\ucircumflex} % 00FB LATIN SMALL LETTER U WITH CIRCUMFLEX +\defineactivetoken 252 {\udiaeresis} % 00FC LATIN SMALL LETTER U WITH DIAERESIS +\defineactivetoken 253 {\dotlessi} % 0131 LATIN SMALL LETTER DOTLESS I +\defineactivetoken 254 {\scedilla} % 015F LATIN SMALL LETTER S WITH CEDILLA +\defineactivetoken 255 {\ydiaeresis} % 00FF LATIN SMALL LETTER Y WITH DIAERESIS + +\stopregime + diff --git a/tex/context/base/regi-cp1255.lua b/tex/context/base/regi-cp1255.lua new file mode 100644 index 000000000..9ea807fbd --- /dev/null +++ b/tex/context/base/regi-cp1255.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-cp1255'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["cp1255"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AA, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7, 0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF, + 0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3, 0x05F4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, + 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, 0x0000 +} diff --git a/tex/context/base/regi-cp1256.lua b/tex/context/base/regi-cp1256.lua new file mode 100644 index 000000000..e77525bcf --- /dev/null +++ b/tex/context/base/regi-cp1256.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-cp1256'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["cp1256"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688, + 0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA, + 0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F, + 0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7, 0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0641, 0x0642, 0x0643, + 0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF, + 0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7, 0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2 +} diff --git a/tex/context/base/regi-cp1257.lua b/tex/context/base/regi-cp1257.lua new file mode 100644 index 000000000..1b5d53379 --- /dev/null +++ b/tex/context/base/regi-cp1257.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-cp1257'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["cp1257"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021, 0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000, + 0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x0000, 0x00A6, 0x00A7, 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00C6, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6, + 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112, 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B, + 0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7, 0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF, + 0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113, 0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C, + 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7, 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9 +} diff --git a/tex/context/base/regi-cp1257.mkii b/tex/context/base/regi-cp1257.mkii new file mode 100644 index 000000000..0790ef734 --- /dev/null +++ b/tex/context/base/regi-cp1257.mkii @@ -0,0 +1,153 @@ +%D \module +%D [ file=regi-cp1257, +%D version=2005.12.26, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=cp1257 (Windows Baltic), +%D author=script-generated, +%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. + +%D Support for cp1257 input encoding (regime) for Baltic languages, +%D see also iso-8859-4 and iso-8859-13. +%D +%D Usage: +%D \type{\enableregime[cp1257]} or \type{\enablereregime[windows-1257]} + + +\startregime[cp1257] + +\defineactivetoken 128 {\texteuro} % 20AC EURO SIGN +\defineactivetoken 129 {\unknownchar} % +\defineactivetoken 130 {\quotesinglebase} % 201A SINGLE LOW-9 QUOTATION MARK +\defineactivetoken 131 {\unknownchar} % +\defineactivetoken 132 {\quotedblbase} % 201E DOUBLE LOW-9 QUOTATION MARK +\defineactivetoken 133 {\textellipsis} % 2026 HORIZONTAL ELLIPSIS +\defineactivetoken 134 {\textdag} % 2020 DAGGER +\defineactivetoken 135 {\textddag} % 2021 DOUBLE DAGGER +\defineactivetoken 136 {\unknownchar} % +\defineactivetoken 137 {\perthousand} % 2030 PER MILLE SIGN +\defineactivetoken 138 {\unknownchar} % +\defineactivetoken 139 {\guilsingleleft} % 2039 SINGLE LEFT-POINTING ANGLE QUOTATION MARK +\defineactivetoken 140 {\unknownchar} % +\defineactivetoken 141 {\textdiaeresis} % 00A8 DIAERESIS +\defineactivetoken 142 {\textcaron} % 02C7 CARON +\defineactivetoken 143 {\textcedilla} % 00B8 CEDILLA +\defineactivetoken 144 {\unknownchar} % +\defineactivetoken 145 {\quoteleft} % 2018 LEFT SINGLE QUOTATION MARK +\defineactivetoken 146 {\quoteright} % 2019 RIGHT SINGLE QUOTATION MARK +\defineactivetoken 147 {\quotedblleft} % 201C LEFT DOUBLE QUOTATION MARK +\defineactivetoken 148 {\quotedblright} % 201D RIGHT DOUBLE QUOTATION MARK +\defineactivetoken 149 {\textbullet} % 2022 BULLET +\defineactivetoken 150 {\endash} % 2013 EN DASH +\defineactivetoken 151 {\emdash} % 2014 EM DASH +\defineactivetoken 152 {\unknownchar} % +\defineactivetoken 153 {\trademark} % 2122 TRADE MARK SIGN +\defineactivetoken 154 {\unknownchar} % +\defineactivetoken 155 {\guilsingleright} % 203A SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +\defineactivetoken 156 {\unknownchar} % +\defineactivetoken 157 {\textmacron} % 00AF MACRON +\defineactivetoken 158 {\textogonek} % 02DB OGONEK +\defineactivetoken 159 {\unknownchar} % +\defineactivetoken 160 {\nonbreakablespace} % 00A0 NO-BREAK SPACE +\defineactivetoken 161 {\unknownchar} % +\defineactivetoken 162 {\textcent} % 00A2 CENT SIGN +\defineactivetoken 163 {\textsterling} % 00A3 POUND SIGN +\defineactivetoken 164 {\textcurrency} % 00A4 CURRENCY SIGN +\defineactivetoken 165 {\unknownchar} % +\defineactivetoken 166 {\textbrokenbar} % 00A6 BROKEN BAR +\defineactivetoken 167 {\sectionmark} % 00A7 SECTION SIGN +\defineactivetoken 168 {\Ostroke} % 00D8 LATIN CAPITAL LETTER O WITH STROKE +\defineactivetoken 169 {\copyright} % 00A9 COPYRIGHT SIGN +\defineactivetoken 170 {\Rcommaaccent} % 0156 LATIN CAPITAL LETTER R WITH CEDILLA +\defineactivetoken 171 {\leftguillemot} % 00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 172 {\textlognot} % 00AC NOT SIGN +\defineactivetoken 173 {\softhyphen} % 00AD SOFT HYPHEN +\defineactivetoken 174 {\registered} % 00AE REGISTERED SIGN +\defineactivetoken 175 {\AEligature} % 00C6 LATIN CAPITAL LETTER AE +\defineactivetoken 176 {\textdegree} % 00B0 DEGREE SIGN +\defineactivetoken 177 {\textpm} % 00B1 PLUS-MINUS SIGN +\defineactivetoken 178 {\twosuperior} % 00B2 SUPERSCRIPT TWO +\defineactivetoken 179 {\threesuperior} % 00B3 SUPERSCRIPT THREE +\defineactivetoken 180 {\textacute} % 00B4 ACUTE ACCENT +\defineactivetoken 181 {\textmu} % 00B5 MICRO SIGN +\defineactivetoken 182 {\paragraphmark} % 00B6 PILCROW SIGN +\defineactivetoken 183 {\periodcentered} % 00B7 MIDDLE DOT +\defineactivetoken 184 {\ostroke} % 00F8 LATIN SMALL LETTER O WITH STROKE +\defineactivetoken 185 {\onesuperior} % 00B9 SUPERSCRIPT ONE +\defineactivetoken 186 {\rcommaaccent} % 0157 LATIN SMALL LETTER R WITH CEDILLA +\defineactivetoken 187 {\rightguillemot} % 00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +\defineactivetoken 188 {\onequarter} % 00BC VULGAR FRACTION ONE QUARTER +\defineactivetoken 189 {\onehalf} % 00BD VULGAR FRACTION ONE HALF +\defineactivetoken 190 {\threequarter} % 00BE VULGAR FRACTION THREE QUARTERS +\defineactivetoken 191 {\aeligature} % 00E6 LATIN SMALL LETTER AE +\defineactivetoken 192 {\Aogonek} % 0104 LATIN CAPITAL LETTER A WITH OGONEK +\defineactivetoken 193 {\Iogonek} % 012E LATIN CAPITAL LETTER I WITH OGONEK +\defineactivetoken 194 {\Amacron} % 0100 LATIN CAPITAL LETTER A WITH MACRON +\defineactivetoken 195 {\Cacute} % 0106 LATIN CAPITAL LETTER C WITH ACUTE +\defineactivetoken 196 {\Adiaeresis} % 00C4 LATIN CAPITAL LETTER A WITH DIAERESIS +\defineactivetoken 197 {\Aring} % 00C5 LATIN CAPITAL LETTER A WITH RING ABOVE +\defineactivetoken 198 {\Eogonek} % 0118 LATIN CAPITAL LETTER E WITH OGONEK +\defineactivetoken 199 {\Emacron} % 0112 LATIN CAPITAL LETTER E WITH MACRON +\defineactivetoken 200 {\Ccaron} % 010C LATIN CAPITAL LETTER C WITH CARON +\defineactivetoken 201 {\Eacute} % 00C9 LATIN CAPITAL LETTER E WITH ACUTE +\defineactivetoken 202 {\Zacute} % 0179 LATIN CAPITAL LETTER Z WITH ACUTE +\defineactivetoken 203 {\Edotaccent} % 0116 LATIN CAPITAL LETTER E WITH DOT ABOVE +\defineactivetoken 204 {\Gcommaaccent} % 0122 LATIN CAPITAL LETTER G WITH CEDILLA +\defineactivetoken 205 {\Kcommaaccent} % 0136 LATIN CAPITAL LETTER K WITH CEDILLA +\defineactivetoken 206 {\Imacron} % 012A LATIN CAPITAL LETTER I WITH MACRON +\defineactivetoken 207 {\Lcommaaccent} % 013B LATIN CAPITAL LETTER L WITH CEDILLA +\defineactivetoken 208 {\Scaron} % 0160 LATIN CAPITAL LETTER S WITH CARON +\defineactivetoken 209 {\Nacute} % 0143 LATIN CAPITAL LETTER N WITH ACUTE +\defineactivetoken 210 {\Ncommaaccent} % 0145 LATIN CAPITAL LETTER N WITH CEDILLA +\defineactivetoken 211 {\Oacute} % 00D3 LATIN CAPITAL LETTER O WITH ACUTE +\defineactivetoken 212 {\Omacron} % 014C LATIN CAPITAL LETTER O WITH MACRON +\defineactivetoken 213 {\Otilde} % 00D5 LATIN CAPITAL LETTER O WITH TILDE +\defineactivetoken 214 {\Odiaeresis} % 00D6 LATIN CAPITAL LETTER O WITH DIAERESIS +\defineactivetoken 215 {\textmultiply} % 00D7 MULTIPLICATION SIGN +\defineactivetoken 216 {\Uogonek} % 0172 LATIN CAPITAL LETTER U WITH OGONEK +\defineactivetoken 217 {\Lstroke} % 0141 LATIN CAPITAL LETTER L WITH STROKE +\defineactivetoken 218 {\Sacute} % 015A LATIN CAPITAL LETTER S WITH ACUTE +\defineactivetoken 219 {\Umacron} % 016A LATIN CAPITAL LETTER U WITH MACRON +\defineactivetoken 220 {\Udiaeresis} % 00DC LATIN CAPITAL LETTER U WITH DIAERESIS +\defineactivetoken 221 {\Zdotaccent} % 017B LATIN CAPITAL LETTER Z WITH DOT ABOVE +\defineactivetoken 222 {\Zcaron} % 017D LATIN CAPITAL LETTER Z WITH CARON +\defineactivetoken 223 {\ssharp} % 00DF LATIN SMALL LETTER SHARP S +\defineactivetoken 224 {\aogonek} % 0105 LATIN SMALL LETTER A WITH OGONEK +\defineactivetoken 225 {\iogonek} % 012F LATIN SMALL LETTER I WITH OGONEK +\defineactivetoken 226 {\amacron} % 0101 LATIN SMALL LETTER A WITH MACRON +\defineactivetoken 227 {\cacute} % 0107 LATIN SMALL LETTER C WITH ACUTE +\defineactivetoken 228 {\adiaeresis} % 00E4 LATIN SMALL LETTER A WITH DIAERESIS +\defineactivetoken 229 {\aring} % 00E5 LATIN SMALL LETTER A WITH RING ABOVE +\defineactivetoken 230 {\eogonek} % 0119 LATIN SMALL LETTER E WITH OGONEK +\defineactivetoken 231 {\emacron} % 0113 LATIN SMALL LETTER E WITH MACRON +\defineactivetoken 232 {\ccaron} % 010D LATIN SMALL LETTER C WITH CARON +\defineactivetoken 233 {\eacute} % 00E9 LATIN SMALL LETTER E WITH ACUTE +\defineactivetoken 234 {\zacute} % 017A LATIN SMALL LETTER Z WITH ACUTE +\defineactivetoken 235 {\edotaccent} % 0117 LATIN SMALL LETTER E WITH DOT ABOVE +\defineactivetoken 236 {\gcommaaccent} % 0123 LATIN SMALL LETTER G WITH CEDILLA +\defineactivetoken 237 {\kcommaaccent} % 0137 LATIN SMALL LETTER K WITH CEDILLA +\defineactivetoken 238 {\imacron} % 012B LATIN SMALL LETTER I WITH MACRON +\defineactivetoken 239 {\lcommaaccent} % 013C LATIN SMALL LETTER L WITH CEDILLA +\defineactivetoken 240 {\scaron} % 0161 LATIN SMALL LETTER S WITH CARON +\defineactivetoken 241 {\nacute} % 0144 LATIN SMALL LETTER N WITH ACUTE +\defineactivetoken 242 {\ncommaaccent} % 0146 LATIN SMALL LETTER N WITH CEDILLA +\defineactivetoken 243 {\oacute} % 00F3 LATIN SMALL LETTER O WITH ACUTE +\defineactivetoken 244 {\omacron} % 014D LATIN SMALL LETTER O WITH MACRON +\defineactivetoken 245 {\otilde} % 00F5 LATIN SMALL LETTER O WITH TILDE +\defineactivetoken 246 {\odiaeresis} % 00F6 LATIN SMALL LETTER O WITH DIAERESIS +\defineactivetoken 247 {\textdiv} % 00F7 DIVISION SIGN +\defineactivetoken 248 {\uogonek} % 0173 LATIN SMALL LETTER U WITH OGONEK +\defineactivetoken 249 {\lstroke} % 0142 LATIN SMALL LETTER L WITH STROKE +\defineactivetoken 250 {\sacute} % 015B LATIN SMALL LETTER S WITH ACUTE +\defineactivetoken 251 {\umacron} % 016B LATIN SMALL LETTER U WITH MACRON +\defineactivetoken 252 {\udiaeresis} % 00FC LATIN SMALL LETTER U WITH DIAERESIS +\defineactivetoken 253 {\zdotaccent} % 017C LATIN SMALL LETTER Z WITH DOT ABOVE +\defineactivetoken 254 {\zcaron} % 017E LATIN SMALL LETTER Z WITH CARON +\defineactivetoken 255 {\textdotaccent} % 02D9 DOT ABOVE + +\stopregime + diff --git a/tex/context/base/regi-cp1258.lua b/tex/context/base/regi-cp1258.lua new file mode 100644 index 000000000..271db3009 --- /dev/null +++ b/tex/context/base/regi-cp1258.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-cp1258'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +regimes.data["cp1258"] = { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0000, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF, + 0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF, + 0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF +} diff --git a/tex/context/base/regi-cyp.mkii b/tex/context/base/regi-cyp.mkii new file mode 100644 index 000000000..7d134df50 --- /dev/null +++ b/tex/context/base/regi-cyp.mkii @@ -0,0 +1,1169 @@ +%D \module +%D [ file=regi-cyp, +%D version=2003.01.24, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=Cyrillic Plus, +%D author=..., +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 this file several rarely user cyrillic input regimes +%D are defined. + +\startregime[cp855] + +\defineactivetoken 128 {\cyrillicdje} +\defineactivetoken 129 {\cyrillicDJE} +\defineactivetoken 130 {\'\cyrillicg} +\defineactivetoken 131 {\'\cyrillicG} +\defineactivetoken 132 {\cyrillicyo} +\defineactivetoken 133 {\cyrillicYO} +\defineactivetoken 134 {\cyrillicie} +\defineactivetoken 135 {\cyrillicIE} +\defineactivetoken 136 {\cyrillicdze} +\defineactivetoken 137 {\cyrillicDZE} +\defineactivetoken 138 {\cyrillicii} +\defineactivetoken 139 {\cyrillicII} +\defineactivetoken 140 {\cyrillicyi} +\defineactivetoken 141 {\cyrillicYI} +\defineactivetoken 142 {\cyrillicje} +\defineactivetoken 143 {\cyrillicJE} +\defineactivetoken 144 {\cyrilliclje} +\defineactivetoken 145 {\cyrillicLJE} +\defineactivetoken 146 {\cyrillicnje} +\defineactivetoken 147 {\cyrillicNJE} +\defineactivetoken 148 {\cyrillictshe} +\defineactivetoken 149 {\cyrillicTSHE} +\defineactivetoken 150 {\'\cyrillick} +\defineactivetoken 151 {\'\cyrillicK} +\defineactivetoken 152 {\cyrillicushrt} +\defineactivetoken 153 {\cyrillicUSHRT} +\defineactivetoken 154 {\cyrillicdzhe} +\defineactivetoken 155 {\cyrillicDZHE} +\defineactivetoken 156 {\cyrillicyu} +\defineactivetoken 157 {\cyrillicYU} +\defineactivetoken 158 {\cyrillichrdsn} +\defineactivetoken 159 {\cyrillicHRDSN} +\defineactivetoken 160 {\cyrillica} +\defineactivetoken 161 {\cyrillicA} +\defineactivetoken 162 {\cyrillicb} +\defineactivetoken 163 {\cyrillicB} +\defineactivetoken 164 {\cyrillicc} +\defineactivetoken 165 {\cyrillicC} +\defineactivetoken 166 {\cyrillicd} +\defineactivetoken 167 {\cyrillicD} +\defineactivetoken 168 {\cyrillice} +\defineactivetoken 169 {\cyrillicE} +\defineactivetoken 170 {\cyrillicf} +\defineactivetoken 171 {\cyrillicF} +\defineactivetoken 172 {\cyrillicg} +\defineactivetoken 173 {\cyrillicG} +\defineactivetoken 174 {\leftguillemot} +\defineactivetoken 175 {\rightguillemot} +\defineactivetoken 181 {\cyrillich} +\defineactivetoken 182 {\cyrillicH} +\defineactivetoken 183 {\cyrillici} +\defineactivetoken 184 {\cyrillicI} +\defineactivetoken 189 {\cyrillicishrt} +\defineactivetoken 190 {\cyrillicISHRT} +\defineactivetoken 198 {\cyrillick} +\defineactivetoken 199 {\cyrillicK} +\defineactivetoken 207 {\textcurrency} +\defineactivetoken 208 {\cyrillicl} +\defineactivetoken 209 {\cyrillicL} +\defineactivetoken 210 {\cyrillicm} +\defineactivetoken 211 {\cyrillicM} +\defineactivetoken 212 {\cyrillicn} +\defineactivetoken 213 {\cyrillicN} +\defineactivetoken 214 {\cyrillico} +\defineactivetoken 215 {\cyrillicO} +\defineactivetoken 216 {\cyrillicp} +\defineactivetoken 221 {\cyrillicP} +\defineactivetoken 222 {\cyrillicya} +\defineactivetoken 224 {\cyrillicYA} +\defineactivetoken 225 {\cyrillicr} +\defineactivetoken 226 {\cyrillicR} +\defineactivetoken 227 {\cyrillics} +\defineactivetoken 228 {\cyrillicS} +\defineactivetoken 229 {\cyrillict} +\defineactivetoken 230 {\cyrillicT} +\defineactivetoken 231 {\cyrillicu} +\defineactivetoken 232 {\cyrillicU} +\defineactivetoken 233 {\cyrilliczh} +\defineactivetoken 234 {\cyrillicZH} +\defineactivetoken 235 {\cyrillicv} +\defineactivetoken 236 {\cyrillicV} +\defineactivetoken 237 {\cyrillicsftsn} +\defineactivetoken 238 {\cyrillicSFTSN} +\defineactivetoken 239 {\textnumero} +\defineactivetoken 240 {\-} +\defineactivetoken 241 {\cyrillicery} +\defineactivetoken 242 {\cyrillicERY} +\defineactivetoken 243 {\cyrillicz} +\defineactivetoken 244 {\cyrillicZ} +\defineactivetoken 245 {\cyrillicsh} +\defineactivetoken 246 {\cyrillicSH} +\defineactivetoken 247 {\cyrillicerev} +\defineactivetoken 248 {\cyrillicEREV} +\defineactivetoken 249 {\cyrillicshch} +\defineactivetoken 250 {\cyrillicSHCH} +\defineactivetoken 251 {\cyrillicch} +\defineactivetoken 252 {\cyrillicCH} +\defineactivetoken 253 {\sectionmark} +\defineactivetoken 254 {\textblacksquare} +\defineactivetoken 255 {\nonbreakablespace} + +\stopregime + +\startregime[cp866av] + +\defineactivetoken 128 {\cyrillicA} +\defineactivetoken 129 {\cyrillicB} +\defineactivetoken 130 {\cyrillicV} +\defineactivetoken 131 {\cyrillicG} +\defineactivetoken 132 {\cyrillicD} +\defineactivetoken 133 {\cyrillicE} +\defineactivetoken 134 {\cyrillicZH} +\defineactivetoken 135 {\cyrillicZ} +\defineactivetoken 136 {\cyrillicI} +\defineactivetoken 137 {\cyrillicISHRT} +\defineactivetoken 138 {\cyrillicK} +\defineactivetoken 139 {\cyrillicL} +\defineactivetoken 140 {\cyrillicM} +\defineactivetoken 141 {\cyrillicN} +\defineactivetoken 142 {\cyrillicO} +\defineactivetoken 143 {\cyrillicP} +\defineactivetoken 144 {\cyrillicR} +\defineactivetoken 145 {\cyrillicS} +\defineactivetoken 146 {\cyrillicT} +\defineactivetoken 147 {\cyrillicU} +\defineactivetoken 148 {\cyrillicF} +\defineactivetoken 149 {\cyrillicH} +\defineactivetoken 150 {\cyrillicC} +\defineactivetoken 151 {\cyrillicCH} +\defineactivetoken 152 {\cyrillicSH} +\defineactivetoken 153 {\cyrillicSHCH} +\defineactivetoken 154 {\cyrillicHRDSN} +\defineactivetoken 155 {\cyrillicERY} +\defineactivetoken 156 {\cyrillicSFTSN} +\defineactivetoken 157 {\cyrillicEREV} +\defineactivetoken 158 {\cyrillicYU} +\defineactivetoken 159 {\cyrillicYA} +\defineactivetoken 160 {\cyrillica} +\defineactivetoken 161 {\cyrillicb} +\defineactivetoken 162 {\cyrillicv} +\defineactivetoken 163 {\cyrillicg} +\defineactivetoken 164 {\cyrillicd} +\defineactivetoken 165 {\cyrillice} +\defineactivetoken 166 {\cyrilliczh} +\defineactivetoken 167 {\cyrillicz} +\defineactivetoken 168 {\cyrillici} +\defineactivetoken 169 {\cyrillicishrt} +\defineactivetoken 170 {\cyrillick} +\defineactivetoken 171 {\cyrillicl} +\defineactivetoken 172 {\cyrillicm} +\defineactivetoken 173 {\cyrillicn} +\defineactivetoken 174 {\cyrillico} +\defineactivetoken 175 {\cyrillicp} +\defineactivetoken 224 {\cyrillicr} +\defineactivetoken 225 {\cyrillics} +\defineactivetoken 226 {\cyrillict} +\defineactivetoken 227 {\cyrillicu} +\defineactivetoken 228 {\cyrillicf} +\defineactivetoken 229 {\cyrillich} +\defineactivetoken 230 {\cyrillicc} +\defineactivetoken 231 {\cyrillicch} +\defineactivetoken 232 {\cyrillicsh} +\defineactivetoken 233 {\cyrillicshch} +\defineactivetoken 234 {\cyrillichrdsn} +\defineactivetoken 235 {\cyrillicery} +\defineactivetoken 236 {\cyrillicsftsn} +\defineactivetoken 237 {\cyrillicerev} +\defineactivetoken 238 {\cyrillicyu} +\defineactivetoken 239 {\cyrillicya} +\defineactivetoken 240 {\cyrillicYO} +\defineactivetoken 241 {\cyrillicyo} +\defineactivetoken 252 {\textnumero} +\defineactivetoken 253 {\textcurrency} +\defineactivetoken 254 {\textblacksquare} +\defineactivetoken 255 {\nonbreakablespace} +\defineactivetoken 246 {\mathematics\rightarrow} +\defineactivetoken 247 {\mathematics\leftarrow} +\defineactivetoken 248 {\mathematics\downarrow} +\defineactivetoken 249 {\mathematics\uparrow} +\defineactivetoken 250 {\textdiv} +\defineactivetoken 251 {\textpm} + +\stopregime + +\startregime[cp866mav] + +\defineactivetoken 128 {\cyrillicA} +\defineactivetoken 129 {\cyrillicB} +\defineactivetoken 130 {\cyrillicV} +\defineactivetoken 131 {\cyrillicG} +\defineactivetoken 132 {\cyrillicD} +\defineactivetoken 133 {\cyrillicE} +\defineactivetoken 134 {\cyrillicZH} +\defineactivetoken 135 {\cyrillicZ} +\defineactivetoken 136 {\cyrillicI} +\defineactivetoken 137 {\cyrillicISHRT} +\defineactivetoken 138 {\cyrillicK} +\defineactivetoken 139 {\cyrillicL} +\defineactivetoken 140 {\cyrillicM} +\defineactivetoken 141 {\cyrillicN} +\defineactivetoken 142 {\cyrillicO} +\defineactivetoken 143 {\cyrillicP} +\defineactivetoken 144 {\cyrillicR} +\defineactivetoken 145 {\cyrillicS} +\defineactivetoken 146 {\cyrillicT} +\defineactivetoken 147 {\cyrillicU} +\defineactivetoken 148 {\cyrillicF} +\defineactivetoken 149 {\cyrillicH} +\defineactivetoken 150 {\cyrillicC} +\defineactivetoken 151 {\cyrillicCH} +\defineactivetoken 152 {\cyrillicSH} +\defineactivetoken 153 {\cyrillicSHCH} +\defineactivetoken 154 {\cyrillicHRDSN} +\defineactivetoken 155 {\cyrillicERY} +\defineactivetoken 156 {\cyrillicSFTSN} +\defineactivetoken 157 {\cyrillicEREV} +\defineactivetoken 158 {\cyrillicYU} +\defineactivetoken 159 {\cyrillicYA} +\defineactivetoken 160 {\cyrillica} +\defineactivetoken 161 {\cyrillicb} +\defineactivetoken 162 {\cyrillicv} +\defineactivetoken 163 {\cyrillicg} +\defineactivetoken 164 {\cyrillicd} +\defineactivetoken 165 {\cyrillice} +\defineactivetoken 166 {\cyrilliczh} +\defineactivetoken 167 {\cyrillicz} +\defineactivetoken 168 {\cyrillici} +\defineactivetoken 169 {\cyrillicishrt} +\defineactivetoken 170 {\cyrillick} +\defineactivetoken 171 {\cyrillicl} +\defineactivetoken 172 {\cyrillicm} +\defineactivetoken 173 {\cyrillicn} +\defineactivetoken 174 {\cyrillico} +\defineactivetoken 175 {\cyrillicp} +\defineactivetoken 224 {\cyrillicr} +\defineactivetoken 225 {\cyrillics} +\defineactivetoken 226 {\cyrillict} +\defineactivetoken 227 {\cyrillicu} +\defineactivetoken 228 {\cyrillicf} +\defineactivetoken 229 {\cyrillich} +\defineactivetoken 230 {\cyrillicc} +\defineactivetoken 231 {\cyrillicch} +\defineactivetoken 232 {\cyrillicsh} +\defineactivetoken 233 {\cyrillicshch} +\defineactivetoken 234 {\cyrillichrdsn} +\defineactivetoken 235 {\cyrillicery} +\defineactivetoken 236 {\cyrillicsftsn} +\defineactivetoken 237 {\cyrillicerev} +\defineactivetoken 238 {\cyrillicyu} +\defineactivetoken 239 {\cyrillicya} +\defineactivetoken 240 {\cyrillicYO} +\defineactivetoken 241 {\cyrillicyo} +\defineactivetoken 248 {\textdegree} +\defineactivetoken 249 {\textbullet} +\defineactivetoken 250 {\periodcentered} +\defineactivetoken 254 {\textblacksquare} +\defineactivetoken 255 {\nonbreakablespace} +\defineactivetoken 242 {\mathematics\geq} +\defineactivetoken 243 {\mathematics\leq} +\defineactivetoken 246 {\textdiv} +\defineactivetoken 247 {\mathematics\sim} +\defineactivetoken 251 {\textsurd} +\defineactivetoken 252 {\high{\txx n}} +\defineactivetoken 253 {\twosuperior} + +\stopregime + +\startregime[cp866tat] + +\defineactivetoken 128 {\cyrillicA} +\defineactivetoken 129 {\cyrillicB} +\defineactivetoken 130 {\cyrillicV} +\defineactivetoken 131 {\cyrillicG} +\defineactivetoken 132 {\cyrillicD} +\defineactivetoken 133 {\cyrillicE} +\defineactivetoken 134 {\cyrillicZH} +\defineactivetoken 135 {\cyrillicZ} +\defineactivetoken 136 {\cyrillicI} +\defineactivetoken 137 {\cyrillicISHRT} +\defineactivetoken 138 {\cyrillicK} +\defineactivetoken 139 {\cyrillicL} +\defineactivetoken 140 {\cyrillicM} +\defineactivetoken 141 {\cyrillicN} +\defineactivetoken 142 {\cyrillicO} +\defineactivetoken 143 {\cyrillicP} +\defineactivetoken 144 {\cyrillicR} +\defineactivetoken 145 {\cyrillicS} +\defineactivetoken 146 {\cyrillicT} +\defineactivetoken 147 {\cyrillicU} +\defineactivetoken 148 {\cyrillicF} +\defineactivetoken 149 {\cyrillicH} +\defineactivetoken 150 {\cyrillicC} +\defineactivetoken 151 {\cyrillicCH} +\defineactivetoken 152 {\cyrillicSH} +\defineactivetoken 153 {\cyrillicSHCH} +\defineactivetoken 154 {\cyrillicHRDSN} +\defineactivetoken 155 {\cyrillicERY} +\defineactivetoken 156 {\cyrillicSFTSN} +\defineactivetoken 157 {\cyrillicEREV} +\defineactivetoken 158 {\cyrillicYU} +\defineactivetoken 159 {\cyrillicYA} +\defineactivetoken 160 {\cyrillica} +\defineactivetoken 161 {\cyrillicb} +\defineactivetoken 162 {\cyrillicv} +\defineactivetoken 163 {\cyrillicg} +\defineactivetoken 164 {\cyrillicd} +\defineactivetoken 165 {\cyrillice} +\defineactivetoken 166 {\cyrilliczh} +\defineactivetoken 167 {\cyrillicz} +\defineactivetoken 168 {\cyrillici} +\defineactivetoken 169 {\cyrillicishrt} +\defineactivetoken 170 {\cyrillick} +\defineactivetoken 171 {\cyrillicl} +\defineactivetoken 172 {\cyrillicm} +\defineactivetoken 173 {\cyrillicn} +\defineactivetoken 174 {\cyrillico} +\defineactivetoken 175 {\cyrillicp} +\defineactivetoken 224 {\cyrillicr} +\defineactivetoken 225 {\cyrillics} +\defineactivetoken 226 {\cyrillict} +\defineactivetoken 227 {\cyrillicu} +\defineactivetoken 228 {\cyrillicf} +\defineactivetoken 229 {\cyrillich} +\defineactivetoken 230 {\cyrillicc} +\defineactivetoken 231 {\cyrillicch} +\defineactivetoken 232 {\cyrillicsh} +\defineactivetoken 233 {\cyrillicshch} +\defineactivetoken 234 {\cyrillichrdsn} +\defineactivetoken 235 {\cyrillicery} +\defineactivetoken 236 {\cyrillicsftsn} +\defineactivetoken 237 {\cyrillicerev} +\defineactivetoken 238 {\cyrillicyu} +\defineactivetoken 239 {\cyrillicya} +\defineactivetoken 240 {\cyrillicYO} +\defineactivetoken 241 {\cyrillicyo} +\defineactivetoken 242 {\cyrillicSCHWA} +\defineactivetoken 243 {\cyrillicschwa} +\defineactivetoken 244 {\cyrillicOTLD} +\defineactivetoken 245 {\cyrillicotld} +\defineactivetoken 246 {\cyrillicY} +\defineactivetoken 247 {\cyrillicy} +\defineactivetoken 248 {\cyrillicZHDSC} +\defineactivetoken 249 {\cyrilliczhdsc} +\defineactivetoken 250 {\cyrillicNDSC} +\defineactivetoken 251 {\cyrillicndsc} +\defineactivetoken 252 {\cyrillicSHHA} +\defineactivetoken 253 {\cyrillicshha} +\defineactivetoken 254 {\textblacksquare} +\defineactivetoken 255 {\nonbreakablespace} + +\stopregime + +\startregime[ctt] + +\defineactivetoken 171 {\leftguillemot} +\defineactivetoken 187 {\rightguillemot} +\defineactivetoken 192 {\cyrillicA} +\defineactivetoken 193 {\cyrillicB} +\defineactivetoken 194 {\cyrillicV} +\defineactivetoken 195 {\cyrillicG} +\defineactivetoken 196 {\cyrillicD} +\defineactivetoken 197 {\cyrillicE} +\defineactivetoken 168 {\cyrillicYO} +\defineactivetoken 198 {\cyrillicZH} +\defineactivetoken 199 {\cyrillicZ} +\defineactivetoken 200 {\cyrillicI} +\defineactivetoken 201 {\cyrillicISHRT} +\defineactivetoken 202 {\cyrillicK} +\defineactivetoken 203 {\cyrillicL} +\defineactivetoken 204 {\cyrillicM} +\defineactivetoken 205 {\cyrillicN} +\defineactivetoken 206 {\cyrillicO} +\defineactivetoken 170 {\cyrillicOTLD} +\defineactivetoken 207 {\cyrillicP} +\defineactivetoken 208 {\cyrillicR} +\defineactivetoken 209 {\cyrillicS} +\defineactivetoken 210 {\cyrillicT} +\defineactivetoken 211 {\cyrillicU} +\defineactivetoken 175 {\cyrillicY} +\defineactivetoken 212 {\cyrillicF} +\defineactivetoken 213 {\cyrillicH} +\defineactivetoken 214 {\cyrillicC} +\defineactivetoken 215 {\cyrillicCH} +\defineactivetoken 216 {\cyrillicSH} +\defineactivetoken 217 {\cyrillicSHCH} +\defineactivetoken 218 {\cyrillicHRDSN} +\defineactivetoken 219 {\cyrillicERY} +\defineactivetoken 220 {\cyrillicSFTSN} +\defineactivetoken 221 {\cyrillicEREV} +\defineactivetoken 222 {\cyrillicYU} +\defineactivetoken 223 {\cyrillicYA} +\defineactivetoken 224 {\cyrillica} +\defineactivetoken 225 {\cyrillicb} +\defineactivetoken 226 {\cyrillicv} +\defineactivetoken 227 {\cyrillicg} +\defineactivetoken 228 {\cyrillicd} +\defineactivetoken 229 {\cyrillice} +\defineactivetoken 184 {\cyrillicyo} +\defineactivetoken 230 {\cyrilliczh} +\defineactivetoken 231 {\cyrillicz} +\defineactivetoken 232 {\cyrillici} +\defineactivetoken 233 {\cyrillicishrt} +\defineactivetoken 234 {\cyrillick} +\defineactivetoken 235 {\cyrillicl} +\defineactivetoken 236 {\cyrillicm} +\defineactivetoken 237 {\cyrillicn} +\defineactivetoken 238 {\cyrillico} +\defineactivetoken 186 {\cyrillicotld} +\defineactivetoken 239 {\cyrillicp} +\defineactivetoken 240 {\cyrillicr} +\defineactivetoken 241 {\cyrillics} +\defineactivetoken 242 {\cyrillict} +\defineactivetoken 243 {\cyrillicu} +\defineactivetoken 191 {\cyrillicy} +\defineactivetoken 244 {\cyrillicf} +\defineactivetoken 245 {\cyrillich} +\defineactivetoken 246 {\cyrillicc} +\defineactivetoken 247 {\cyrillicch} +\defineactivetoken 248 {\cyrillicsh} +\defineactivetoken 249 {\cyrillicshch} +\defineactivetoken 250 {\cyrillichrdsn} +\defineactivetoken 251 {\cyrillicery} +\defineactivetoken 252 {\cyrillicsftsn} +\defineactivetoken 253 {\cyrillicerev} +\defineactivetoken 254 {\cyrillicyu} +\defineactivetoken 255 {\cyrillicya} + +\stopregime + +\startregime[dbk] + +\defineactivetoken 128 {\cyrillicA} +\defineactivetoken 129 {\cyrillicB} +\defineactivetoken 130 {\cyrillicV} +\defineactivetoken 131 {\cyrillicG} +\defineactivetoken 132 {\cyrillicD} +\defineactivetoken 133 {\cyrillicE} +\defineactivetoken 134 {\cyrillicYO} +\defineactivetoken 135 {\cyrillicZH} +\defineactivetoken 136 {\cyrillicZ} +\defineactivetoken 137 {\cyrillicI} +\defineactivetoken 139 {\cyrillicISHRT} +\defineactivetoken 140 {\cyrillicK} +\defineactivetoken 142 {\cyrillicL} +\defineactivetoken 143 {\cyrillicM} +\defineactivetoken 144 {\cyrillicN} +\defineactivetoken 145 {\cyrillicO} +\defineactivetoken 146 {\cyrillicOTLD} +\defineactivetoken 147 {\cyrillicP} +\defineactivetoken 148 {\cyrillicR} +\defineactivetoken 149 {\cyrillicS} +\defineactivetoken 150 {\cyrillicT} +\defineactivetoken 151 {\cyrillicU} +\defineactivetoken 152 {\cyrillicY} +\defineactivetoken 153 {\cyrillicF} +\defineactivetoken 154 {\cyrillicH} +\defineactivetoken 155 {\cyrillicC} +\defineactivetoken 156 {\cyrillicCH} +\defineactivetoken 157 {\cyrillicSH} +\defineactivetoken 158 {\cyrillicSHCH} +\defineactivetoken 159 {\cyrillicHRDSN} +\defineactivetoken 160 {\cyrillicERY} +\defineactivetoken 161 {\cyrillicSFTSN} +\defineactivetoken 162 {\cyrillicEREV} +\defineactivetoken 163 {\cyrillicYU} +\defineactivetoken 164 {\cyrillicYA} +\defineactivetoken 165 {\cyrillica} +\defineactivetoken 166 {\cyrillicb} +\defineactivetoken 167 {\cyrillicv} +\defineactivetoken 168 {\cyrillicg} +\defineactivetoken 169 {\cyrillicd} +\defineactivetoken 170 {\cyrillice} +\defineactivetoken 171 {\cyrillicyo} +\defineactivetoken 172 {\cyrilliczh} +\defineactivetoken 173 {\cyrillicz} +\defineactivetoken 174 {\cyrillici} +\defineactivetoken 175 {\cyrillicishrt} +\defineactivetoken 225 {\cyrillick} +\defineactivetoken 226 {\cyrillicl} +\defineactivetoken 227 {\cyrillicm} +\defineactivetoken 228 {\cyrillicn} +\defineactivetoken 229 {\cyrillico} +\defineactivetoken 230 {\cyrillicotld} +\defineactivetoken 231 {\cyrillicp} +\defineactivetoken 232 {\cyrillicr} +\defineactivetoken 233 {\cyrillics} +\defineactivetoken 234 {\cyrillict} +\defineactivetoken 235 {\cyrillicu} +\defineactivetoken 236 {\cyrillicy} +\defineactivetoken 237 {\cyrillicf} +\defineactivetoken 238 {\cyrillich} +\defineactivetoken 239 {\cyrillicc} +\defineactivetoken 241 {\cyrillicch} +\defineactivetoken 242 {\cyrillicsh} +\defineactivetoken 243 {\cyrillicshch} +\defineactivetoken 244 {\cyrillichrdsn} +\defineactivetoken 245 {\cyrillicery} +\defineactivetoken 246 {\cyrillicsftsn} +\defineactivetoken 247 {\cyrillicerev} +\defineactivetoken 248 {\cyrillicyu} +\defineactivetoken 249 {\cyrillicya} + +\stopregime + +\startregime[iso88595] + +\defineactivetoken 160 {\nonbreakablespace} +\defineactivetoken 161 {\cyrillicYO} +\defineactivetoken 162 {\cyrillicDJE} +\defineactivetoken 163 {\'\cyrillicG} +\defineactivetoken 164 {\cyrillicIE} +\defineactivetoken 165 {\cyrillicDZE} +\defineactivetoken 166 {\cyrillicII} +\defineactivetoken 167 {\cyrillicYI} +\defineactivetoken 168 {\cyrillicJE} +\defineactivetoken 169 {\cyrillicLJE} +\defineactivetoken 170 {\cyrillicNJE} +\defineactivetoken 171 {\cyrillicTSHE} +\defineactivetoken 172 {\'\cyrillicK} +\defineactivetoken 173 {\-} +\defineactivetoken 174 {\cyrillicUSHRT} +\defineactivetoken 175 {\cyrillicDZHE} +\defineactivetoken 176 {\cyrillicA} +\defineactivetoken 177 {\cyrillicB} +\defineactivetoken 178 {\cyrillicV} +\defineactivetoken 179 {\cyrillicG} +\defineactivetoken 180 {\cyrillicD} +\defineactivetoken 181 {\cyrillicE} +\defineactivetoken 182 {\cyrillicZH} +\defineactivetoken 183 {\cyrillicZ} +\defineactivetoken 184 {\cyrillicI} +\defineactivetoken 185 {\cyrillicISHRT} +\defineactivetoken 186 {\cyrillicK} +\defineactivetoken 187 {\cyrillicL} +\defineactivetoken 188 {\cyrillicM} +\defineactivetoken 189 {\cyrillicN} +\defineactivetoken 190 {\cyrillicO} +\defineactivetoken 191 {\cyrillicP} +\defineactivetoken 192 {\cyrillicR} +\defineactivetoken 193 {\cyrillicS} +\defineactivetoken 194 {\cyrillicT} +\defineactivetoken 195 {\cyrillicU} +\defineactivetoken 196 {\cyrillicF} +\defineactivetoken 197 {\cyrillicH} +\defineactivetoken 198 {\cyrillicC} +\defineactivetoken 199 {\cyrillicCH} +\defineactivetoken 200 {\cyrillicSH} +\defineactivetoken 201 {\cyrillicSHCH} +\defineactivetoken 202 {\cyrillicHRDSN} +\defineactivetoken 203 {\cyrillicERY} +\defineactivetoken 204 {\cyrillicSFTSN} +\defineactivetoken 205 {\cyrillicEREV} +\defineactivetoken 206 {\cyrillicYU} +\defineactivetoken 207 {\cyrillicYA} +\defineactivetoken 208 {\cyrillica} +\defineactivetoken 209 {\cyrillicb} +\defineactivetoken 210 {\cyrillicv} +\defineactivetoken 211 {\cyrillicg} +\defineactivetoken 212 {\cyrillicd} +\defineactivetoken 213 {\cyrillice} +\defineactivetoken 214 {\cyrilliczh} +\defineactivetoken 215 {\cyrillicz} +\defineactivetoken 216 {\cyrillici} +\defineactivetoken 217 {\cyrillicishrt} +\defineactivetoken 218 {\cyrillick} +\defineactivetoken 219 {\cyrillicl} +\defineactivetoken 220 {\cyrillicm} +\defineactivetoken 221 {\cyrillicn} +\defineactivetoken 222 {\cyrillico} +\defineactivetoken 223 {\cyrillicp} +\defineactivetoken 224 {\cyrillicr} +\defineactivetoken 225 {\cyrillics} +\defineactivetoken 226 {\cyrillict} +\defineactivetoken 227 {\cyrillicu} +\defineactivetoken 228 {\cyrillicf} +\defineactivetoken 229 {\cyrillich} +\defineactivetoken 230 {\cyrillicc} +\defineactivetoken 231 {\cyrillicch} +\defineactivetoken 232 {\cyrillicsh} +\defineactivetoken 233 {\cyrillicshch} +\defineactivetoken 234 {\cyrillichrdsn} +\defineactivetoken 235 {\cyrillicery} +\defineactivetoken 236 {\cyrillicsftsn} +\defineactivetoken 237 {\cyrillicerev} +\defineactivetoken 238 {\cyrillicyu} +\defineactivetoken 239 {\cyrillicya} +\defineactivetoken 240 {\textnumero} +\defineactivetoken 241 {\cyrillicyo} +\defineactivetoken 242 {\cyrillicdje} +\defineactivetoken 243 {\'\cyrillicg} +\defineactivetoken 244 {\cyrillicie} +\defineactivetoken 245 {\cyrillicdze} +\defineactivetoken 246 {\cyrillicii} +\defineactivetoken 247 {\cyrillicyi} +\defineactivetoken 248 {\cyrillicje} +\defineactivetoken 249 {\cyrilliclje} +\defineactivetoken 250 {\cyrillicnje} +\defineactivetoken 251 {\cyrillictshe} +\defineactivetoken 252 {\'\cyrillick} +\defineactivetoken 253 {\sectionmark} +\defineactivetoken 254 {\cyrillicushrt} +\defineactivetoken 255 {\cyrillicdzhe} + +\stopregime + +\startregime[isoir111] + +\defineactivetoken 225 {\cyrillicA} +\defineactivetoken 226 {\cyrillicB} +\defineactivetoken 247 {\cyrillicV} +\defineactivetoken 231 {\cyrillicG} +\defineactivetoken 228 {\cyrillicD} +\defineactivetoken 229 {\cyrillicE} +\defineactivetoken 179 {\cyrillicYO} +\defineactivetoken 246 {\cyrillicZH} +\defineactivetoken 250 {\cyrillicZ} +\defineactivetoken 233 {\cyrillicI} +\defineactivetoken 234 {\cyrillicISHRT} +\defineactivetoken 235 {\cyrillicK} +\defineactivetoken 236 {\cyrillicL} +\defineactivetoken 237 {\cyrillicM} +\defineactivetoken 238 {\cyrillicN} +\defineactivetoken 239 {\cyrillicO} +\defineactivetoken 240 {\cyrillicP} +\defineactivetoken 242 {\cyrillicR} +\defineactivetoken 243 {\cyrillicS} +\defineactivetoken 244 {\cyrillicT} +\defineactivetoken 245 {\cyrillicU} +\defineactivetoken 230 {\cyrillicF} +\defineactivetoken 232 {\cyrillicH} +\defineactivetoken 227 {\cyrillicC} +\defineactivetoken 254 {\cyrillicCH} +\defineactivetoken 251 {\cyrillicSH} +\defineactivetoken 253 {\cyrillicSHCH} +\defineactivetoken 255 {\cyrillicHRDSN} +\defineactivetoken 249 {\cyrillicERY} +\defineactivetoken 248 {\cyrillicSFTSN} +\defineactivetoken 252 {\cyrillicEREV} +\defineactivetoken 224 {\cyrillicYU} +\defineactivetoken 241 {\cyrillicYA} +\defineactivetoken 193 {\cyrillica} +\defineactivetoken 194 {\cyrillicb} +\defineactivetoken 215 {\cyrillicv} +\defineactivetoken 199 {\cyrillicg} +\defineactivetoken 196 {\cyrillicd} +\defineactivetoken 197 {\cyrillice} +\defineactivetoken 163 {\cyrillicyo} +\defineactivetoken 214 {\cyrilliczh} +\defineactivetoken 218 {\cyrillicz} +\defineactivetoken 201 {\cyrillici} +\defineactivetoken 202 {\cyrillicishrt} +\defineactivetoken 203 {\cyrillick} +\defineactivetoken 204 {\cyrillicl} +\defineactivetoken 205 {\cyrillicm} +\defineactivetoken 206 {\cyrillicn} +\defineactivetoken 207 {\cyrillico} +\defineactivetoken 208 {\cyrillicp} +\defineactivetoken 210 {\cyrillicr} +\defineactivetoken 211 {\cyrillics} +\defineactivetoken 212 {\cyrillict} +\defineactivetoken 213 {\cyrillicu} +\defineactivetoken 198 {\cyrillicf} +\defineactivetoken 200 {\cyrillich} +\defineactivetoken 195 {\cyrillicc} +\defineactivetoken 222 {\cyrillicch} +\defineactivetoken 219 {\cyrillicsh} +\defineactivetoken 221 {\cyrillicshch} +\defineactivetoken 223 {\cyrillichrdsn} +\defineactivetoken 217 {\cyrillicery} +\defineactivetoken 216 {\cyrillicsftsn} +\defineactivetoken 220 {\cyrillicerev} +\defineactivetoken 192 {\cyrillicyu} +\defineactivetoken 209 {\cyrillicya} +\defineactivetoken 160 {\nonbreakablespace} +\defineactivetoken 161 {\cyrillicdje} +\defineactivetoken 162 {\'\cyrillicg} +\defineactivetoken 164 {\cyrillicie} +\defineactivetoken 165 {\cyrillicdze} +\defineactivetoken 166 {\cyrillicii} +\defineactivetoken 167 {\cyrillicyi} +\defineactivetoken 168 {\cyrillicje} +\defineactivetoken 169 {\cyrilliclje} +\defineactivetoken 170 {\cyrillicnje} +\defineactivetoken 171 {\cyrillictshe} +\defineactivetoken 172 {\'\cyrillick} +\defineactivetoken 173 {\-} +\defineactivetoken 174 {\cyrillicushrt} +\defineactivetoken 175 {\cyrillicdzhe} +\defineactivetoken 176 {\textnumero} +\defineactivetoken 177 {\cyrillicDJE} +\defineactivetoken 178 {\'\cyrillicG} +\defineactivetoken 180 {\cyrillicIE} +\defineactivetoken 181 {\cyrillicDZE} +\defineactivetoken 182 {\cyrillicII} +\defineactivetoken 183 {\cyrillicYI} +\defineactivetoken 184 {\cyrillicJE} +\defineactivetoken 185 {\cyrillicLJE} +\defineactivetoken 186 {\cyrillicNJE} +\defineactivetoken 187 {\cyrillicTSHE} +\defineactivetoken 188 {\'\cyrillicK} +\defineactivetoken 189 {\textcurrency} +\defineactivetoken 190 {\cyrillicUSHRT} +\defineactivetoken 191 {\cyrillicDZHE} + +\stopregime + +\startregime[mik] + +\defineactivetoken 128 {\cyrillicA} +\defineactivetoken 129 {\cyrillicB} +\defineactivetoken 130 {\cyrillicV} +\defineactivetoken 131 {\cyrillicG} +\defineactivetoken 132 {\cyrillicD} +\defineactivetoken 133 {\cyrillicE} +\defineactivetoken 134 {\cyrillicZH} +\defineactivetoken 135 {\cyrillicZ} +\defineactivetoken 136 {\cyrillicI} +\defineactivetoken 137 {\cyrillicISHRT} +\defineactivetoken 138 {\cyrillicK} +\defineactivetoken 139 {\cyrillicL} +\defineactivetoken 140 {\cyrillicM} +\defineactivetoken 141 {\cyrillicN} +\defineactivetoken 142 {\cyrillicO} +\defineactivetoken 143 {\cyrillicP} +\defineactivetoken 144 {\cyrillicR} +\defineactivetoken 145 {\cyrillicS} +\defineactivetoken 146 {\cyrillicT} +\defineactivetoken 147 {\cyrillicU} +\defineactivetoken 148 {\cyrillicF} +\defineactivetoken 149 {\cyrillicH} +\defineactivetoken 150 {\cyrillicC} +\defineactivetoken 151 {\cyrillicCH} +\defineactivetoken 152 {\cyrillicSH} +\defineactivetoken 153 {\cyrillicSHCH} +\defineactivetoken 154 {\cyrillicHRDSN} +\defineactivetoken 155 {\cyrillicERY} +\defineactivetoken 156 {\cyrillicSFTSN} +\defineactivetoken 157 {\cyrillicEREV} +\defineactivetoken 158 {\cyrillicYU} +\defineactivetoken 159 {\cyrillicYA} +\defineactivetoken 160 {\cyrillica} +\defineactivetoken 161 {\cyrillicb} +\defineactivetoken 162 {\cyrillicv} +\defineactivetoken 163 {\cyrillicg} +\defineactivetoken 164 {\cyrillicd} +\defineactivetoken 165 {\cyrillice} +\defineactivetoken 166 {\cyrilliczh} +\defineactivetoken 167 {\cyrillicz} +\defineactivetoken 168 {\cyrillici} +\defineactivetoken 169 {\cyrillicishrt} +\defineactivetoken 170 {\cyrillick} +\defineactivetoken 171 {\cyrillicl} +\defineactivetoken 172 {\cyrillicm} +\defineactivetoken 173 {\cyrillicn} +\defineactivetoken 174 {\cyrillico} +\defineactivetoken 175 {\cyrillicp} +\defineactivetoken 176 {\cyrillicr} +\defineactivetoken 177 {\cyrillics} +\defineactivetoken 178 {\cyrillict} +\defineactivetoken 179 {\cyrillicu} +\defineactivetoken 180 {\cyrillicf} +\defineactivetoken 181 {\cyrillich} +\defineactivetoken 182 {\cyrillicc} +\defineactivetoken 183 {\cyrillicch} +\defineactivetoken 184 {\cyrillicsh} +\defineactivetoken 185 {\cyrillicshch} +\defineactivetoken 186 {\cyrillichrdsn} +\defineactivetoken 187 {\cyrillicery} +\defineactivetoken 188 {\cyrillicsftsn} +\defineactivetoken 189 {\cyrillicerev} +\defineactivetoken 190 {\cyrillicyu} +\defineactivetoken 191 {\cyrillicya} +\defineactivetoken 213 {\textnumero} +\defineactivetoken 214 {\sectionmark} +\defineactivetoken 248 {\textdegree} +\defineactivetoken 249 {\textbullet} +\defineactivetoken 250 {\periodcentered} +\defineactivetoken 254 {\textblacksquare} +\defineactivetoken 255 {\nonbreakablespace} +\defineactivetoken 224 {\mathematics\alpha} +\defineactivetoken 225 {\mathematics\beta} +\defineactivetoken 226 {\mathematics\Gamma} +\defineactivetoken 227 {\mathematics\pi} +\defineactivetoken 228 {\mathematics\Sigma} +\defineactivetoken 229 {\mathematics\sigma} +\defineactivetoken 230 {\textmu} +\defineactivetoken 231 {\mathematics\tau} +\defineactivetoken 232 {\mathematics\Phi} +\defineactivetoken 233 {\mathematics\Theta} +\defineactivetoken 234 {\mathematics\Omega} +\defineactivetoken 235 {\mathematics\delta} +\defineactivetoken 236 {\mathematics\infty} +\defineactivetoken 237 {\mathematics\emptyset} +\defineactivetoken 238 {\mathematics\in} +\defineactivetoken 239 {\mathematics\cap} +\defineactivetoken 240 {\mathematics\equiv} +\defineactivetoken 241 {\textpm} +\defineactivetoken 242 {\mathematics\geq} +\defineactivetoken 243 {\mathematics\leq} +\defineactivetoken 246 {\textdiv} +\defineactivetoken 247 {\mathematics\sim} +\defineactivetoken 251 {\textsurd} +\defineactivetoken 252 {\high{\txx n}} +\defineactivetoken 253 {\twosuperior} + +\stopregime + +\startregime[mls] + +% The symbols 194 to 253 are defined in Mongolian fonts in +% the Mon\TeX\ package (?) + +\defineactivetoken 128 {\cyrillicB} +\defineactivetoken 129 {\cyrillicy} +\defineactivetoken 130 {\cyrillicD} +\defineactivetoken 131 {\cyrillicYO} +\defineactivetoken 132 {\cyrillicerev} +\defineactivetoken 133 {\cyrillicZH} +\defineactivetoken 134 {\cyrillicZ} +\defineactivetoken 135 {\cyrillicI} +\defineactivetoken 136 {\cyrillicISHRT} +\defineactivetoken 137 {\cyrillicyo} +\defineactivetoken 138 {\cyrillicL} +\defineactivetoken 139 {\cyrillicishrt} +\defineactivetoken 140 {\cyrillicOTLD} +\defineactivetoken 141 {\cyrillicP} +\defineactivetoken 142 {\cyrillicEREV} +\defineactivetoken 143 {\cyrillicU} +\defineactivetoken 144 {\cyrillicF} +\defineactivetoken 145 {\cyrillicC} +\defineactivetoken 146 {\cyrillicCH} +\defineactivetoken 147 {\cyrillicSH} +\defineactivetoken 148 {\cyrillicotld} +\defineactivetoken 149 {\cyrillicSHCH} +\defineactivetoken 150 {\cyrillicHRDSN} +\defineactivetoken 151 {\cyrillicERY} +\defineactivetoken 152 {\cyrillicSFTSN} +\defineactivetoken 153 {\cyrillicOTLD} +\defineactivetoken 154 {\cyrillicY} +\defineactivetoken 155 {\cyrillicEREV} +\defineactivetoken 156 {\cyrillicYU} +\defineactivetoken 157 {\cyrillicYA} +\defineactivetoken 158 {\cyrillicb} +\defineactivetoken 159 {\cyrillicv} +\defineactivetoken 160 {\cyrillicg} +\defineactivetoken 161 {\cyrillicd} +\defineactivetoken 162 {\cyrilliczh} +\defineactivetoken 163 {\cyrillicz} +\defineactivetoken 164 {\cyrillici} +\defineactivetoken 165 {\cyrillicishrt} +\defineactivetoken 166 {\cyrillick} +\defineactivetoken 167 {\cyrillicl} +\defineactivetoken 168 {\cyrillicm} +\defineactivetoken 169 {\cyrillicn} +\defineactivetoken 170 {\cyrillicotld} +\defineactivetoken 171 {\cyrillicp} +\defineactivetoken 172 {\cyrillict} +\defineactivetoken 173 {\cyrillicy} +\defineactivetoken 174 {\leftguillemot} +\defineactivetoken 175 {\rightguillemot} +\defineactivetoken 176 {\cyrillicf} +\defineactivetoken 177 {\cyrillicc} +\defineactivetoken 178 {\cyrillicch} +\defineactivetoken 180 {\cyrillicsh} +\defineactivetoken 181 {\cyrillicshch} +\defineactivetoken 182 {\cyrillichrdsn} +\defineactivetoken 183 {\cyrillicery} +\defineactivetoken 184 {\cyrillicsftsn} +\defineactivetoken 189 {\cyrillicerev} +\defineactivetoken 190 {\cyrillicyu} +\defineactivetoken 193 {\cyrillicya} +\defineactivetoken 226 {\cyrillicG} +\defineactivetoken 225 {\ss} +\defineactivetoken 231 {\mathematics{\gamma}} +\defineactivetoken 255 {\nonbreakablespace} +\defineactivetoken 194 {\titem} +\defineactivetoken 195 {\shud} +\defineactivetoken 197 {\secondaryshud} +\defineactivetoken 198 {\shilbe} +\defineactivetoken 199 {\gedes} +\defineactivetoken 207 {\secondarygedes} +\defineactivetoken 208 {\cegteishud} +\defineactivetoken 209 {\lewer} +\defineactivetoken 210 {\suuliinlewer} +\defineactivetoken 211 {\tertiarylewer} +\defineactivetoken 212 {\mewer} +\defineactivetoken 213 {\suuliinmewer} +\defineactivetoken 214 {\xewteeqix} +\defineactivetoken 215 {\dawxarcegtxewteeqix} +\defineactivetoken 216 {\halfnum} +\defineactivetoken 219 {\num} +\defineactivetoken 220 {\halfnumtgedes} +\defineactivetoken 221 {\numtaigedes} +\defineactivetoken 222 {\buruuxarsangedes} +\defineactivetoken 223 {\gedesteishilbe} +\defineactivetoken 224 {\erweeljinshilbe} +\defineactivetoken 227 {\secerweeljin} +\defineactivetoken 228 {\bosooshilbe} +\defineactivetoken 229 {\etgershilbe} +\defineactivetoken 230 {\zawj} +\defineactivetoken 232 {\suuliinzawj} +\defineactivetoken 233 {\dawxarcegtzawj} +\defineactivetoken 234 {\sereeewer} +\defineactivetoken 235 {\matgarshilbe} +\defineactivetoken 236 {\bituushilbe} +\defineactivetoken 237 {\secondaryqagt} +\defineactivetoken 238 {\qagt} +\defineactivetoken 239 {\secnumtdelbenqix} +\defineactivetoken 240 {\numtdelbenqix} +\defineactivetoken 241 {\secsertenqixtnum} +\defineactivetoken 242 {\sertenqixtnum} +\defineactivetoken 243 {\zadgaizardigt} +\defineactivetoken 244 {\bituuzardigt} +\defineactivetoken 245 {\malgaitaititem} +\defineactivetoken 246 {\suul} +\defineactivetoken 247 {\orxic} +\defineactivetoken 248 {\biodoisuul} +\defineactivetoken 249 {\bagodoisuul} +\defineactivetoken 250 {\nceg} +\defineactivetoken 251 {\gceg} +\defineactivetoken 252 {\ceg} +\defineactivetoken 253 {\dorwoljin} + +\stopregime + +\startregime[mnk] + +\defineactivetoken 128 {\cyrillicA} +\defineactivetoken 129 {\cyrillicB} +\defineactivetoken 130 {\cyrillicV} +\defineactivetoken 131 {\cyrillicG} +\defineactivetoken 132 {\cyrillicD} +\defineactivetoken 133 {\cyrillicE} +\defineactivetoken 134 {\cyrillicYO} +\defineactivetoken 135 {\cyrillicZH} +\defineactivetoken 136 {\cyrillicZ} +\defineactivetoken 137 {\cyrillicI} +\defineactivetoken 138 {\cyrillicISHRT} +\defineactivetoken 139 {\cyrillicK} +\defineactivetoken 140 {\cyrillicL} +\defineactivetoken 141 {\cyrillicM} +\defineactivetoken 142 {\cyrillicN} +\defineactivetoken 143 {\cyrillicO} +\defineactivetoken 144 {\cyrillicOTLD} +\defineactivetoken 145 {\cyrillicP} +\defineactivetoken 146 {\cyrillicR} +\defineactivetoken 147 {\cyrillicS} +\defineactivetoken 148 {\cyrillicT} +\defineactivetoken 149 {\cyrillicU} +\defineactivetoken 150 {\cyrillicY} +\defineactivetoken 151 {\cyrillicF} +\defineactivetoken 152 {\cyrillicH} +\defineactivetoken 153 {\cyrillicC} +\defineactivetoken 154 {\cyrillicCH} +\defineactivetoken 155 {\cyrillicSH} +\defineactivetoken 156 {\cyrillicSHCH} +\defineactivetoken 157 {\cyrillicHRDSN} +\defineactivetoken 158 {\cyrillicERY} +\defineactivetoken 159 {\cyrillicSFTSN} +\defineactivetoken 160 {\cyrillicEREV} +\defineactivetoken 161 {\cyrillicYU} +\defineactivetoken 162 {\cyrillicYA} +\defineactivetoken 163 {\cyrillica} +\defineactivetoken 164 {\cyrillicb} +\defineactivetoken 165 {\cyrillicv} +\defineactivetoken 166 {\cyrillicg} +\defineactivetoken 167 {\cyrillicd} +\defineactivetoken 168 {\cyrillice} +\defineactivetoken 169 {\cyrillicyo} +\defineactivetoken 170 {\cyrilliczh} +\defineactivetoken 173 {\cyrillicz} +\defineactivetoken 224 {\cyrillici} +\defineactivetoken 225 {\cyrillicishrt} +\defineactivetoken 226 {\cyrillick} +\defineactivetoken 227 {\cyrillicl} +\defineactivetoken 228 {\cyrillicm} +\defineactivetoken 229 {\cyrillicn} +\defineactivetoken 230 {\cyrillico} +\defineactivetoken 231 {\cyrillicotld} +\defineactivetoken 232 {\cyrillicp} +\defineactivetoken 233 {\cyrillicr} +\defineactivetoken 234 {\cyrillics} +\defineactivetoken 235 {\cyrillict} +\defineactivetoken 236 {\cyrillicu} +\defineactivetoken 237 {\cyrillicy} +\defineactivetoken 238 {\cyrillicf} +\defineactivetoken 239 {\cyrillich} +\defineactivetoken 240 {\cyrillicc} +\defineactivetoken 241 {\cyrillicch} +\defineactivetoken 242 {\cyrillicsh} +\defineactivetoken 243 {\cyrillicshch} +\defineactivetoken 244 {\cyrillichrdsn} +\defineactivetoken 245 {\cyrillicery} +\defineactivetoken 248 {\cyrillicsftsn} +\defineactivetoken 252 {\cyrillicerev} +\defineactivetoken 253 {\cyrillicyu} +\defineactivetoken 254 {\cyrillicya} + +\stopregime + +\startregime[mos] + +\defineactivetoken 128 {\cyrillicA} +\defineactivetoken 129 {\cyrillicB} +\defineactivetoken 130 {\cyrillicV} +\defineactivetoken 131 {\cyrillicG} +\defineactivetoken 132 {\cyrillicD} +\defineactivetoken 133 {\cyrillicE} +\defineactivetoken 160 {\cyrillicYO} +\defineactivetoken 134 {\cyrillicZH} +\defineactivetoken 135 {\cyrillicZ} +\defineactivetoken 136 {\cyrillicI} +\defineactivetoken 137 {\cyrillicISHRT} +\defineactivetoken 138 {\cyrillicK} +\defineactivetoken 139 {\cyrillicL} +\defineactivetoken 140 {\cyrillicM} +\defineactivetoken 141 {\cyrillicN} +\defineactivetoken 142 {\cyrillicO} +\defineactivetoken 153 {\cyrillicOTLD} +\defineactivetoken 143 {\cyrillicP} +\defineactivetoken 144 {\cyrillicR} +\defineactivetoken 145 {\cyrillicS} +\defineactivetoken 146 {\cyrillicT} +\defineactivetoken 147 {\cyrillicU} +\defineactivetoken 154 {\cyrillicY} +\defineactivetoken 148 {\cyrillicF} +\defineactivetoken 149 {\cyrillicH} +\defineactivetoken 150 {\cyrillicC} +\defineactivetoken 151 {\cyrillicCH} +\defineactivetoken 152 {\cyrillicSH} +\defineactivetoken 164 {\cyrillicSHCH} +\defineactivetoken 162 {\cyrillicHRDSN} +\defineactivetoken 155 {\cyrillicERY} +\defineactivetoken 156 {\cyrillicSFTSN} +\defineactivetoken 157 {\cyrillicEREV} +\defineactivetoken 158 {\cyrillicYU} +\defineactivetoken 159 {\cyrillicYA} +\defineactivetoken 224 {\cyrillica} +\defineactivetoken 225 {\cyrillicb} +\defineactivetoken 226 {\cyrillicv} +\defineactivetoken 227 {\cyrillicg} +\defineactivetoken 228 {\cyrillicd} +\defineactivetoken 229 {\cyrillice} +\defineactivetoken 161 {\cyrillicyo} +\defineactivetoken 230 {\cyrilliczh} +\defineactivetoken 231 {\cyrillicz} +\defineactivetoken 232 {\cyrillici} +\defineactivetoken 233 {\cyrillicishrt} +\defineactivetoken 234 {\cyrillick} +\defineactivetoken 235 {\cyrillicl} +\defineactivetoken 236 {\cyrillicm} +\defineactivetoken 237 {\cyrillicn} +\defineactivetoken 238 {\cyrillico} +\defineactivetoken 249 {\cyrillicotld} +\defineactivetoken 239 {\cyrillicp} +\defineactivetoken 240 {\cyrillicr} +\defineactivetoken 241 {\cyrillics} +\defineactivetoken 242 {\cyrillict} +\defineactivetoken 243 {\cyrillicu} +\defineactivetoken 250 {\cyrillicy} +\defineactivetoken 244 {\cyrillicf} +\defineactivetoken 245 {\cyrillich} +\defineactivetoken 246 {\cyrillicc} +\defineactivetoken 247 {\cyrillicch} +\defineactivetoken 248 {\cyrillicsh} +\defineactivetoken 165 {\cyrillicshch} +\defineactivetoken 163 {\cyrillichrdsn} +\defineactivetoken 251 {\cyrillicery} +\defineactivetoken 252 {\cyrillicsftsn} +\defineactivetoken 253 {\cyrillicerev} +\defineactivetoken 254 {\cyrillicyu} +\defineactivetoken 168 {\cyrillicya} + +\stopregime + +\startregime[ncc] + +\defineactivetoken 128 {\cyrillicA} +\defineactivetoken 129 {\cyrillicB} +\defineactivetoken 130 {\cyrillicV} +\defineactivetoken 131 {\cyrillicG} +\defineactivetoken 132 {\cyrillicD} +\defineactivetoken 133 {\cyrillicE} +\defineactivetoken 134 {\cyrillicYO} +\defineactivetoken 135 {\cyrillicZH} +\defineactivetoken 136 {\cyrillicZ} +\defineactivetoken 137 {\cyrillicI} +\defineactivetoken 139 {\cyrillicISHRT} +\defineactivetoken 140 {\cyrillicK} +\defineactivetoken 142 {\cyrillicL} +\defineactivetoken 143 {\cyrillicM} +\defineactivetoken 144 {\cyrillicN} +\defineactivetoken 145 {\cyrillicO} +\defineactivetoken 146 {\cyrillicOTLD} +\defineactivetoken 147 {\cyrillicP} +\defineactivetoken 148 {\cyrillicR} +\defineactivetoken 149 {\cyrillicS} +\defineactivetoken 150 {\cyrillicT} +\defineactivetoken 151 {\cyrillicU} +\defineactivetoken 152 {\cyrillicY} +\defineactivetoken 153 {\cyrillicF} +\defineactivetoken 154 {\cyrillicH} +\defineactivetoken 155 {\cyrillicC} +\defineactivetoken 156 {\cyrillicCH} +\defineactivetoken 157 {\cyrillicSH} +\defineactivetoken 158 {\cyrillicSHCH} +\defineactivetoken 159 {\cyrillicHRDSN} +\defineactivetoken 160 {\cyrillicERY} +\defineactivetoken 161 {\cyrillicSFTSN} +\defineactivetoken 162 {\cyrillicEREV} +\defineactivetoken 163 {\cyrillicYU} +\defineactivetoken 164 {\cyrillicYA} +\defineactivetoken 165 {\cyrillica} +\defineactivetoken 166 {\cyrillicb} +\defineactivetoken 167 {\cyrillicv} +\defineactivetoken 168 {\cyrillicg} +\defineactivetoken 169 {\cyrillicd} +\defineactivetoken 170 {\cyrillice} +\defineactivetoken 171 {\cyrillicyo} +\defineactivetoken 172 {\cyrilliczh} +\defineactivetoken 173 {\cyrillicz} +\defineactivetoken 225 {\cyrillici} +\defineactivetoken 226 {\cyrillicishrt} +\defineactivetoken 227 {\cyrillick} +\defineactivetoken 228 {\cyrillicl} +\defineactivetoken 229 {\cyrillicm} +\defineactivetoken 230 {\cyrillicn} +\defineactivetoken 231 {\cyrillico} +\defineactivetoken 232 {\cyrillicotld} +\defineactivetoken 233 {\cyrillicp} +\defineactivetoken 234 {\cyrillicr} +\defineactivetoken 235 {\cyrillics} +\defineactivetoken 236 {\cyrillict} +\defineactivetoken 237 {\cyrillicu} +\defineactivetoken 238 {\cyrillicy} +\defineactivetoken 239 {\cyrillicf} +\defineactivetoken 240 {\cyrillich} +\defineactivetoken 241 {\cyrillicc} +\defineactivetoken 242 {\cyrillicch} +\defineactivetoken 243 {\cyrillicsh} +\defineactivetoken 244 {\cyrillicshch} +\defineactivetoken 245 {\cyrillichrdsn} +\defineactivetoken 246 {\cyrillicery} +\defineactivetoken 247 {\cyrillicsftsn} +\defineactivetoken 248 {\cyrillicerev} +\defineactivetoken 249 {\cyrillicyu} +\defineactivetoken 251 {\cyrillicya} + +\stopregime + +\endinput diff --git a/tex/context/base/regi-cyr.mkii b/tex/context/base/regi-cyr.mkii new file mode 100644 index 000000000..1e84b9cba --- /dev/null +++ b/tex/context/base/regi-cyr.mkii @@ -0,0 +1,722 @@ +%D \module +%D [ file=regi-cyr, +%D version=2003.01.24, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=Cyrillic, +%D author=..., +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Here are additional input regimes for cyrillic encodings others than cp1251 +%D and iso-8859-5: +%D +%D \startitemize +%D \item two variants of dos +%D \item three variants of koi-8 for *nix: russian, +%D ukrainian and mixed +%D \item two variants for the mac +%D \stopitemize +%D +%D Other, not so popular regimes, can be found in \type +%D {regi-cy2}. + +\startregime[cp866] + +\defineactivetoken 128 {\cyrillicA} +\defineactivetoken 129 {\cyrillicB} +\defineactivetoken 130 {\cyrillicV} +\defineactivetoken 131 {\cyrillicG} +\defineactivetoken 132 {\cyrillicD} +\defineactivetoken 133 {\cyrillicE} +\defineactivetoken 134 {\cyrillicZH} +\defineactivetoken 135 {\cyrillicZ} +\defineactivetoken 136 {\cyrillicI} +\defineactivetoken 137 {\cyrillicISHRT} +\defineactivetoken 138 {\cyrillicK} +\defineactivetoken 139 {\cyrillicL} +\defineactivetoken 140 {\cyrillicM} +\defineactivetoken 141 {\cyrillicN} +\defineactivetoken 142 {\cyrillicO} +\defineactivetoken 143 {\cyrillicP} +\defineactivetoken 144 {\cyrillicR} +\defineactivetoken 145 {\cyrillicS} +\defineactivetoken 146 {\cyrillicT} +\defineactivetoken 147 {\cyrillicU} +\defineactivetoken 148 {\cyrillicF} +\defineactivetoken 149 {\cyrillicH} +\defineactivetoken 150 {\cyrillicC} +\defineactivetoken 151 {\cyrillicCH} +\defineactivetoken 152 {\cyrillicSH} +\defineactivetoken 153 {\cyrillicSHCH} +\defineactivetoken 154 {\cyrillicHRDSN} +\defineactivetoken 155 {\cyrillicERY} +\defineactivetoken 156 {\cyrillicSFTSN} +\defineactivetoken 157 {\cyrillicEREV} +\defineactivetoken 158 {\cyrillicYU} +\defineactivetoken 159 {\cyrillicYA} +\defineactivetoken 160 {\cyrillica} +\defineactivetoken 161 {\cyrillicb} +\defineactivetoken 162 {\cyrillicv} +\defineactivetoken 163 {\cyrillicg} +\defineactivetoken 164 {\cyrillicd} +\defineactivetoken 165 {\cyrillice} +\defineactivetoken 166 {\cyrilliczh} +\defineactivetoken 167 {\cyrillicz} +\defineactivetoken 168 {\cyrillici} +\defineactivetoken 169 {\cyrillicishrt} +\defineactivetoken 170 {\cyrillick} +\defineactivetoken 171 {\cyrillicl} +\defineactivetoken 172 {\cyrillicm} +\defineactivetoken 173 {\cyrillicn} +\defineactivetoken 174 {\cyrillico} +\defineactivetoken 175 {\cyrillicp} +\defineactivetoken 224 {\cyrillicr} +\defineactivetoken 225 {\cyrillics} +\defineactivetoken 226 {\cyrillict} +\defineactivetoken 227 {\cyrillicu} +\defineactivetoken 228 {\cyrillicf} +\defineactivetoken 229 {\cyrillich} +\defineactivetoken 230 {\cyrillicc} +\defineactivetoken 231 {\cyrillicch} +\defineactivetoken 232 {\cyrillicsh} +\defineactivetoken 233 {\cyrillicshch} +\defineactivetoken 234 {\cyrillichrdsn} +\defineactivetoken 235 {\cyrillicery} +\defineactivetoken 236 {\cyrillicsftsn} +\defineactivetoken 237 {\cyrillicerev} +\defineactivetoken 238 {\cyrillicyu} +\defineactivetoken 239 {\cyrillicya} +\defineactivetoken 240 {\cyrillicYO} +\defineactivetoken 241 {\cyrillicyo} +\defineactivetoken 242 {\cyrillicIE} +\defineactivetoken 243 {\cyrillicie} +\defineactivetoken 244 {\cyrillicYI} +\defineactivetoken 245 {\cyrillicyi} +\defineactivetoken 246 {\cyrillicUSHRT} +\defineactivetoken 247 {\cyrillicushrt} +\defineactivetoken 248 {\textdegree} +\defineactivetoken 249 {\bullet} +\defineactivetoken 250 {\periodcentered} +\defineactivetoken 252 {\textnumero} +\defineactivetoken 253 {\textcurrency} +\defineactivetoken 254 {\textblacksquare} +\defineactivetoken 255 {\nonbreakablespace} +\defineactivetoken 251 {\textsurd} + +\stopregime + +\startregime[cp866nav] + +\defineactivetoken 128 {\cyrillicA} +\defineactivetoken 129 {\cyrillicB} +\defineactivetoken 130 {\cyrillicV} +\defineactivetoken 131 {\cyrillicG} +\defineactivetoken 132 {\cyrillicD} +\defineactivetoken 133 {\cyrillicE} +\defineactivetoken 134 {\cyrillicZH} +\defineactivetoken 135 {\cyrillicZ} +\defineactivetoken 136 {\cyrillicI} +\defineactivetoken 137 {\cyrillicISHRT} +\defineactivetoken 138 {\cyrillicK} +\defineactivetoken 139 {\cyrillicL} +\defineactivetoken 140 {\cyrillicM} +\defineactivetoken 141 {\cyrillicN} +\defineactivetoken 142 {\cyrillicO} +\defineactivetoken 143 {\cyrillicP} +\defineactivetoken 144 {\cyrillicR} +\defineactivetoken 145 {\cyrillicS} +\defineactivetoken 146 {\cyrillicT} +\defineactivetoken 147 {\cyrillicU} +\defineactivetoken 148 {\cyrillicF} +\defineactivetoken 149 {\cyrillicH} +\defineactivetoken 150 {\cyrillicC} +\defineactivetoken 151 {\cyrillicCH} +\defineactivetoken 152 {\cyrillicSH} +\defineactivetoken 153 {\cyrillicSHCH} +\defineactivetoken 154 {\cyrillicHRDSN} +\defineactivetoken 155 {\cyrillicERY} +\defineactivetoken 156 {\cyrillicSFTSN} +\defineactivetoken 157 {\cyrillicEREV} +\defineactivetoken 158 {\cyrillicYU} +\defineactivetoken 159 {\cyrillicYA} +\defineactivetoken 160 {\cyrillica} +\defineactivetoken 161 {\cyrillicb} +\defineactivetoken 162 {\cyrillicv} +\defineactivetoken 163 {\cyrillicg} +\defineactivetoken 164 {\cyrillicd} +\defineactivetoken 165 {\cyrillice} +\defineactivetoken 166 {\cyrilliczh} +\defineactivetoken 167 {\cyrillicz} +\defineactivetoken 168 {\cyrillici} +\defineactivetoken 169 {\cyrillicishrt} +\defineactivetoken 170 {\cyrillick} +\defineactivetoken 171 {\cyrillicl} +\defineactivetoken 172 {\cyrillicm} +\defineactivetoken 173 {\cyrillicn} +\defineactivetoken 174 {\cyrillico} +\defineactivetoken 175 {\cyrillicp} +\defineactivetoken 224 {\cyrillicr} +\defineactivetoken 225 {\cyrillics} +\defineactivetoken 226 {\cyrillict} +\defineactivetoken 227 {\cyrillicu} +\defineactivetoken 228 {\cyrillicf} +\defineactivetoken 229 {\cyrillich} +\defineactivetoken 230 {\cyrillicc} +\defineactivetoken 231 {\cyrillicch} +\defineactivetoken 232 {\cyrillicsh} +\defineactivetoken 233 {\cyrillicshch} +\defineactivetoken 234 {\cyrillichrdsn} +\defineactivetoken 235 {\cyrillicery} +\defineactivetoken 236 {\cyrillicsftsn} +\defineactivetoken 237 {\cyrillicerev} +\defineactivetoken 238 {\cyrillicyu} +\defineactivetoken 239 {\cyrillicya} +\defineactivetoken 240 {\cyrillicYO} +\defineactivetoken 241 {\cyrillicyo} +\defineactivetoken 242 {\cyrillicGUP} +\defineactivetoken 243 {\cyrillicgup} +\defineactivetoken 244 {\cyrillicIE} +\defineactivetoken 245 {\cyrillicie} +\defineactivetoken 246 {\cyrillicII} +\defineactivetoken 247 {\cyrillicii} +\defineactivetoken 248 {\cyrillicYI} +\defineactivetoken 249 {\cyrillicyi} +\defineactivetoken 250 {\cyrillicUSHRT} +\defineactivetoken 251 {\cyrillicushrt} +\defineactivetoken 252 {\textnumero} +\defineactivetoken 253 {\leftguillemot} +\defineactivetoken 254 {\rightguillemot} +\defineactivetoken 255 {\nonbreakablespace} + +\stopregime + +\startregime[koi8-r] + +\defineactivetoken 225 {\cyrillicA} +\defineactivetoken 226 {\cyrillicB} +\defineactivetoken 247 {\cyrillicV} +\defineactivetoken 231 {\cyrillicG} +\defineactivetoken 228 {\cyrillicD} +\defineactivetoken 229 {\cyrillicE} +\defineactivetoken 179 {\cyrillicYO} +\defineactivetoken 246 {\cyrillicZH} +\defineactivetoken 250 {\cyrillicZ} +\defineactivetoken 233 {\cyrillicI} +\defineactivetoken 234 {\cyrillicISHRT} +\defineactivetoken 235 {\cyrillicK} +\defineactivetoken 236 {\cyrillicL} +\defineactivetoken 237 {\cyrillicM} +\defineactivetoken 238 {\cyrillicN} +\defineactivetoken 239 {\cyrillicO} +\defineactivetoken 240 {\cyrillicP} +\defineactivetoken 242 {\cyrillicR} +\defineactivetoken 243 {\cyrillicS} +\defineactivetoken 244 {\cyrillicT} +\defineactivetoken 245 {\cyrillicU} +\defineactivetoken 230 {\cyrillicF} +\defineactivetoken 232 {\cyrillicH} +\defineactivetoken 227 {\cyrillicC} +\defineactivetoken 254 {\cyrillicCH} +\defineactivetoken 251 {\cyrillicSH} +\defineactivetoken 253 {\cyrillicSHCH} +\defineactivetoken 255 {\cyrillicHRDSN} +\defineactivetoken 249 {\cyrillicERY} +\defineactivetoken 248 {\cyrillicSFTSN} +\defineactivetoken 252 {\cyrillicEREV} +\defineactivetoken 224 {\cyrillicYU} +\defineactivetoken 241 {\cyrillicYA} +\defineactivetoken 193 {\cyrillica} +\defineactivetoken 194 {\cyrillicb} +\defineactivetoken 215 {\cyrillicv} +\defineactivetoken 199 {\cyrillicg} +\defineactivetoken 196 {\cyrillicd} +\defineactivetoken 197 {\cyrillice} +\defineactivetoken 163 {\cyrillicyo} +\defineactivetoken 214 {\cyrilliczh} +\defineactivetoken 218 {\cyrillicz} +\defineactivetoken 201 {\cyrillici} +\defineactivetoken 202 {\cyrillicishrt} +\defineactivetoken 203 {\cyrillick} +\defineactivetoken 204 {\cyrillicl} +\defineactivetoken 205 {\cyrillicm} +\defineactivetoken 206 {\cyrillicn} +\defineactivetoken 207 {\cyrillico} +\defineactivetoken 208 {\cyrillicp} +\defineactivetoken 210 {\cyrillicr} +\defineactivetoken 211 {\cyrillics} +\defineactivetoken 212 {\cyrillict} +\defineactivetoken 213 {\cyrillicu} +\defineactivetoken 198 {\cyrillicf} +\defineactivetoken 200 {\cyrillich} +\defineactivetoken 195 {\cyrillicc} +\defineactivetoken 222 {\cyrillicch} +\defineactivetoken 219 {\cyrillicsh} +\defineactivetoken 221 {\cyrillicshch} +\defineactivetoken 223 {\cyrillichrdsn} +\defineactivetoken 217 {\cyrillicery} +\defineactivetoken 216 {\cyrillicsftsn} +\defineactivetoken 220 {\cyrillicerev} +\defineactivetoken 192 {\cyrillicyu} +\defineactivetoken 209 {\cyrillicya} +\defineactivetoken 148 {\textblacksquare} +\defineactivetoken 149 {\textbullet} +\defineactivetoken 154 {\nonbreakablespace} +\defineactivetoken 156 {\textdegree} +\defineactivetoken 158 {\periodcentered} +\defineactivetoken 191 {\copyright} +\defineactivetoken 150 {\textsurd} +\defineactivetoken 151 {\mathematics\sim} +\defineactivetoken 152 {\mathematics\leq} +\defineactivetoken 153 {\mathematics\geq} +\defineactivetoken 157 {\twosuperior} +\defineactivetoken 159 {\textdiv} + +\stopregime + +\startregime[koi8-ru] + +\defineactivetoken 225 {\cyrillicA} +\defineactivetoken 226 {\cyrillicB} +\defineactivetoken 247 {\cyrillicV} +\defineactivetoken 231 {\cyrillicG} +\defineactivetoken 228 {\cyrillicD} +\defineactivetoken 229 {\cyrillicE} +\defineactivetoken 179 {\cyrillicYO} +\defineactivetoken 246 {\cyrillicZH} +\defineactivetoken 250 {\cyrillicZ} +\defineactivetoken 233 {\cyrillicI} +\defineactivetoken 234 {\cyrillicISHRT} +\defineactivetoken 235 {\cyrillicK} +\defineactivetoken 236 {\cyrillicL} +\defineactivetoken 237 {\cyrillicM} +\defineactivetoken 238 {\cyrillicN} +\defineactivetoken 239 {\cyrillicO} +\defineactivetoken 240 {\cyrillicP} +\defineactivetoken 242 {\cyrillicR} +\defineactivetoken 243 {\cyrillicS} +\defineactivetoken 244 {\cyrillicT} +\defineactivetoken 245 {\cyrillicU} +\defineactivetoken 230 {\cyrillicF} +\defineactivetoken 232 {\cyrillicH} +\defineactivetoken 227 {\cyrillicC} +\defineactivetoken 254 {\cyrillicCH} +\defineactivetoken 251 {\cyrillicSH} +\defineactivetoken 253 {\cyrillicSHCH} +\defineactivetoken 255 {\cyrillicHRDSN} +\defineactivetoken 249 {\cyrillicERY} +\defineactivetoken 248 {\cyrillicSFTSN} +\defineactivetoken 252 {\cyrillicEREV} +\defineactivetoken 224 {\cyrillicYU} +\defineactivetoken 241 {\cyrillicYA} +\defineactivetoken 193 {\cyrillica} +\defineactivetoken 194 {\cyrillicb} +\defineactivetoken 215 {\cyrillicv} +\defineactivetoken 199 {\cyrillicg} +\defineactivetoken 196 {\cyrillicd} +\defineactivetoken 197 {\cyrillice} +\defineactivetoken 163 {\cyrillicyo} +\defineactivetoken 214 {\cyrilliczh} +\defineactivetoken 218 {\cyrillicz} +\defineactivetoken 201 {\cyrillici} +\defineactivetoken 202 {\cyrillicishrt} +\defineactivetoken 203 {\cyrillick} +\defineactivetoken 204 {\cyrillicl} +\defineactivetoken 205 {\cyrillicm} +\defineactivetoken 206 {\cyrillicn} +\defineactivetoken 207 {\cyrillico} +\defineactivetoken 208 {\cyrillicp} +\defineactivetoken 210 {\cyrillicr} +\defineactivetoken 211 {\cyrillics} +\defineactivetoken 212 {\cyrillict} +\defineactivetoken 213 {\cyrillicu} +\defineactivetoken 198 {\cyrillicf} +\defineactivetoken 200 {\cyrillich} +\defineactivetoken 195 {\cyrillicc} +\defineactivetoken 222 {\cyrillicch} +\defineactivetoken 219 {\cyrillicsh} +\defineactivetoken 221 {\cyrillicshch} +\defineactivetoken 223 {\cyrillichrdsn} +\defineactivetoken 217 {\cyrillicery} +\defineactivetoken 216 {\cyrillicsftsn} +\defineactivetoken 220 {\cyrillicerev} +\defineactivetoken 192 {\cyrillicyu} +\defineactivetoken 209 {\cyrillicya} +\defineactivetoken 147 {\upperleftsinglesixquote} +\defineactivetoken 148 {\textblacksquare} +\defineactivetoken 149 {\textbullet} % Changed by V.F. 07/02/2003 (was: \bullet) +\defineactivetoken 150 {\upperrightdoubleninequote} +\defineactivetoken 151 {\emdash} +\defineactivetoken 152 {\textnumero} +\defineactivetoken 153 {\trademark} % Changed by V.F. 07/02/2003 (was: \texttrademark) +\defineactivetoken 154 {\nonbreakablespace} +\defineactivetoken 155 {\rightguillemot} +\defineactivetoken 156 {\registered} +\defineactivetoken 157 {\leftguillemot} +\defineactivetoken 158 {\periodcentered} % Changed by V.F. 07/02/2003 (was: \textperiodcentered) +\defineactivetoken 159 {\textcurrency} +\defineactivetoken 164 {\cyrillicie} +\defineactivetoken 166 {\cyrillicii} +\defineactivetoken 167 {\cyrillicyi} +\defineactivetoken 173 {\cyrillicgup} +\defineactivetoken 174 {\cyrillicushrt} +\defineactivetoken 180 {\cyrillicIE} +\defineactivetoken 182 {\cyrillicII} +\defineactivetoken 183 {\cyrillicYI} +\defineactivetoken 189 {\cyrillicGUP} +\defineactivetoken 190 {\cyrillicUSHRT} +\defineactivetoken 191 {\copyright} + +\stopregime + +\startregime[koi8-u] + +\defineactivetoken 225 {\cyrillicA} +\defineactivetoken 226 {\cyrillicB} +\defineactivetoken 247 {\cyrillicV} +\defineactivetoken 231 {\cyrillicG} +\defineactivetoken 228 {\cyrillicD} +\defineactivetoken 229 {\cyrillicE} +\defineactivetoken 179 {\cyrillicYO} +\defineactivetoken 246 {\cyrillicZH} +\defineactivetoken 250 {\cyrillicZ} +\defineactivetoken 233 {\cyrillicI} +\defineactivetoken 234 {\cyrillicISHRT} +\defineactivetoken 235 {\cyrillicK} +\defineactivetoken 236 {\cyrillicL} +\defineactivetoken 237 {\cyrillicM} +\defineactivetoken 238 {\cyrillicN} +\defineactivetoken 239 {\cyrillicO} +\defineactivetoken 240 {\cyrillicP} +\defineactivetoken 242 {\cyrillicR} +\defineactivetoken 243 {\cyrillicS} +\defineactivetoken 244 {\cyrillicT} +\defineactivetoken 245 {\cyrillicU} +\defineactivetoken 230 {\cyrillicF} +\defineactivetoken 232 {\cyrillicH} +\defineactivetoken 227 {\cyrillicC} +\defineactivetoken 254 {\cyrillicCH} +\defineactivetoken 251 {\cyrillicSH} +\defineactivetoken 253 {\cyrillicSHCH} +\defineactivetoken 255 {\cyrillicHRDSN} +\defineactivetoken 249 {\cyrillicERY} +\defineactivetoken 248 {\cyrillicSFTSN} +\defineactivetoken 252 {\cyrillicEREV} +\defineactivetoken 224 {\cyrillicYU} +\defineactivetoken 241 {\cyrillicYA} +\defineactivetoken 193 {\cyrillica} +\defineactivetoken 194 {\cyrillicb} +\defineactivetoken 215 {\cyrillicv} +\defineactivetoken 199 {\cyrillicg} +\defineactivetoken 196 {\cyrillicd} +\defineactivetoken 197 {\cyrillice} +\defineactivetoken 163 {\cyrillicyo} +\defineactivetoken 214 {\cyrilliczh} +\defineactivetoken 218 {\cyrillicz} +\defineactivetoken 201 {\cyrillici} +\defineactivetoken 202 {\cyrillicishrt} +\defineactivetoken 203 {\cyrillick} +\defineactivetoken 204 {\cyrillicl} +\defineactivetoken 205 {\cyrillicm} +\defineactivetoken 206 {\cyrillicn} +\defineactivetoken 207 {\cyrillico} +\defineactivetoken 208 {\cyrillicp} +\defineactivetoken 210 {\cyrillicr} +\defineactivetoken 211 {\cyrillics} +\defineactivetoken 212 {\cyrillict} +\defineactivetoken 213 {\cyrillicu} +\defineactivetoken 198 {\cyrillicf} +\defineactivetoken 200 {\cyrillich} +\defineactivetoken 195 {\cyrillicc} +\defineactivetoken 222 {\cyrillicch} +\defineactivetoken 219 {\cyrillicsh} +\defineactivetoken 221 {\cyrillicshch} +\defineactivetoken 223 {\cyrillichrdsn} +\defineactivetoken 217 {\cyrillicery} +\defineactivetoken 216 {\cyrillicsftsn} +\defineactivetoken 220 {\cyrillicerev} +\defineactivetoken 192 {\cyrillicyu} +\defineactivetoken 209 {\cyrillicya} +\defineactivetoken 164 {\cyrillicie} +\defineactivetoken 166 {\cyrillicii} +\defineactivetoken 167 {\cyrillicyi} +\defineactivetoken 173 {\cyrillicgup} +\defineactivetoken 180 {\cyrillicIE} +\defineactivetoken 182 {\cyrillicII} +\defineactivetoken 183 {\cyrillicYI} +\defineactivetoken 189 {\cyrillicGUP} + +\stopregime + +\startregime[maccyr] + +\defineactivetoken 128 {\cyrillicA} +\defineactivetoken 129 {\cyrillicB} +\defineactivetoken 130 {\cyrillicV} +\defineactivetoken 131 {\cyrillicG} +\defineactivetoken 132 {\cyrillicD} +\defineactivetoken 133 {\cyrillicE} +\defineactivetoken 134 {\cyrillicZH} +\defineactivetoken 135 {\cyrillicZ} +\defineactivetoken 136 {\cyrillicI} +\defineactivetoken 137 {\cyrillicISHRT} +\defineactivetoken 138 {\cyrillicK} +\defineactivetoken 139 {\cyrillicL} +\defineactivetoken 140 {\cyrillicM} +\defineactivetoken 141 {\cyrillicN} +\defineactivetoken 142 {\cyrillicO} +\defineactivetoken 143 {\cyrillicP} +\defineactivetoken 144 {\cyrillicR} +\defineactivetoken 145 {\cyrillicS} +\defineactivetoken 146 {\cyrillicT} +\defineactivetoken 147 {\cyrillicU} +\defineactivetoken 148 {\cyrillicF} +\defineactivetoken 149 {\cyrillicH} +\defineactivetoken 150 {\cyrillicC} +\defineactivetoken 151 {\cyrillicCH} +\defineactivetoken 152 {\cyrillicSH} +\defineactivetoken 153 {\cyrillicSHCH} +\defineactivetoken 154 {\cyrillicHRDSN} +\defineactivetoken 155 {\cyrillicERY} +\defineactivetoken 156 {\cyrillicSFTSN} +\defineactivetoken 157 {\cyrillicEREV} +\defineactivetoken 158 {\cyrillicYU} +\defineactivetoken 159 {\cyrillicYA} +\defineactivetoken 160 {\textdag} % Changed by V.F. 07/02/2003 (was: dag) +\defineactivetoken 161 {\textdegree} +\defineactivetoken 162 {\textcent} +\defineactivetoken 163 {\textsterling} % Changed by V.F. 07/02/2003 (was: \sterling) +\defineactivetoken 164 {\sectionmark} % Changed by V.F. 07/02/2003 (was: \S) +\defineactivetoken 165 {\textbullet} % Changed by V.F. 07/02/2003 (was: \bullet} +\defineactivetoken 166 {\paragraphmark} % Changed by V.F. 07/02/2003 (was: \P) +\defineactivetoken 167 {\cyrillicII} +\defineactivetoken 168 {\registered} +\defineactivetoken 169 {\copyright} +\defineactivetoken 170 {\trademark} % Changed by V.F. 07/02/2003 (was: \texttrademark} +\defineactivetoken 171 {\cyrillicDJE} +\defineactivetoken 172 {\cyrillicdje} +\defineactivetoken 174 {\'\cyrillicG} +\defineactivetoken 175 {\'\cyrillicg} +\defineactivetoken 180 {\cyrillicii} +\defineactivetoken 183 {\cyrillicJE} +\defineactivetoken 184 {\cyrillicIE} +\defineactivetoken 185 {\cyrillicie} +\defineactivetoken 186 {\cyrillicYI} +\defineactivetoken 187 {\cyrillicyi} +\defineactivetoken 188 {\cyrillicLJE} +\defineactivetoken 189 {\cyrilliclje} +\defineactivetoken 190 {\cyrillicNJE} +\defineactivetoken 191 {\cyrillicnje} +\defineactivetoken 192 {\cyrillicje} +\defineactivetoken 193 {\cyrillicDZE} +\defineactivetoken 196 {\textflorin} % Changed by V.F. 07/02/2003 (was: \florijn) +\defineactivetoken 199 {\leftguillemot} +\defineactivetoken 200 {\rightguillemot} +\defineactivetoken 201 {\textellipsis} % Changed by V.F. 07/02/2003 (was: \dots) +\defineactivetoken 202 {\nonbreakablespace} +\defineactivetoken 203 {\cyrillicTSHE} +\defineactivetoken 204 {\cyrillictshe} +\defineactivetoken 205 {\'\cyrillicK} +\defineactivetoken 206 {\'\cyrillick} +\defineactivetoken 207 {\cyrillicdze} +\defineactivetoken 208 {\endash} +\defineactivetoken 209 {\emdash} +\defineactivetoken 210 {\upperleftdoublesixquote} % Changed by V.F. 07/02/2003 + % (was: \upperleftsinglesixquote) +\defineactivetoken 211 {\upperrightdoubleninequote} +\defineactivetoken 212 {\upperleftsinglesixquote} +\defineactivetoken 213 {\upperrightsingleninequote} +\defineactivetoken 215 {\lowerleftdoubleninequote} +\defineactivetoken 216 {\cyrillicUSHRT} +\defineactivetoken 217 {\cyrillicushrt} +\defineactivetoken 218 {\cyrillicDZHE} +\defineactivetoken 219 {\cyrillicdzhe} +\defineactivetoken 220 {\textnumero} +\defineactivetoken 221 {\cyrillicYO} +\defineactivetoken 222 {\cyrillicyo} +\defineactivetoken 223 {\cyrillicya} +\defineactivetoken 224 {\cyrillica} +\defineactivetoken 225 {\cyrillicb} +\defineactivetoken 226 {\cyrillicv} +\defineactivetoken 227 {\cyrillicg} +\defineactivetoken 228 {\cyrillicd} +\defineactivetoken 229 {\cyrillice} +\defineactivetoken 230 {\cyrilliczh} +\defineactivetoken 231 {\cyrillicz} +\defineactivetoken 232 {\cyrillici} +\defineactivetoken 233 {\cyrillicishrt} +\defineactivetoken 234 {\cyrillick} +\defineactivetoken 235 {\cyrillicl} +\defineactivetoken 236 {\cyrillicm} +\defineactivetoken 237 {\cyrillicn} +\defineactivetoken 238 {\cyrillico} +\defineactivetoken 239 {\cyrillicp} +\defineactivetoken 240 {\cyrillicr} +\defineactivetoken 241 {\cyrillics} +\defineactivetoken 242 {\cyrillict} +\defineactivetoken 243 {\cyrillicu} +\defineactivetoken 244 {\cyrillicf} +\defineactivetoken 245 {\cyrillich} +\defineactivetoken 246 {\cyrillicc} +\defineactivetoken 247 {\cyrillicch} +\defineactivetoken 248 {\cyrillicsh} +\defineactivetoken 249 {\cyrillicshch} +\defineactivetoken 250 {\cyrillichrdsn} +\defineactivetoken 251 {\cyrillicery} +\defineactivetoken 252 {\cyrillicsftsn} +\defineactivetoken 253 {\cyrillicerev} +\defineactivetoken 254 {\cyrillicyu} +\defineactivetoken 255 {\textcurrency} +\defineactivetoken 173 {\mathematics{\neq}} % Added by V.F. 07/02/2003 +\defineactivetoken 176 {\mathematics{\infty}} % Added by V.F. 07/02/2003 +\defineactivetoken 177 {\textpm} % Added by V.F. 07/02/2003 +\defineactivetoken 178 {\mathematics{\leq}} % Added by V.F. 07/02/2003 +\defineactivetoken 179 {\mathematics{\geq}} % Added by V.F. 07/02/2003 +\defineactivetoken 181 {\textmu} % Added by V.F. 07/02/2003 +\defineactivetoken 182 {\mathematics{\partial}} % Added by V.F. 07/02/2003 +\defineactivetoken 194 {\textlognot} % Added by V.F. 07/02/2003 +\defineactivetoken 195 {\textsurd} % Added by V.F. 07/02/2003 +\defineactivetoken 197 {\mathematics{\approx}} % Added by V.F. 07/02/2003 +\defineactivetoken 198 {\mathematics{\Delta}} % Added by V.F. 07/02/2003 +\defineactivetoken 214 {\textdiv} % Added by V.F. 07/02/2003 + +\stopregime + +\startregime[macukr] + +\defineactivetoken 128 {\cyrillicA} +\defineactivetoken 129 {\cyrillicB} +\defineactivetoken 130 {\cyrillicV} +\defineactivetoken 131 {\cyrillicG} +\defineactivetoken 132 {\cyrillicD} +\defineactivetoken 133 {\cyrillicE} +\defineactivetoken 134 {\cyrillicZH} +\defineactivetoken 135 {\cyrillicZ} +\defineactivetoken 136 {\cyrillicI} +\defineactivetoken 137 {\cyrillicISHRT} +\defineactivetoken 138 {\cyrillicK} +\defineactivetoken 139 {\cyrillicL} +\defineactivetoken 140 {\cyrillicM} +\defineactivetoken 141 {\cyrillicN} +\defineactivetoken 142 {\cyrillicO} +\defineactivetoken 143 {\cyrillicP} +\defineactivetoken 144 {\cyrillicR} +\defineactivetoken 145 {\cyrillicS} +\defineactivetoken 146 {\cyrillicT} +\defineactivetoken 147 {\cyrillicU} +\defineactivetoken 148 {\cyrillicF} +\defineactivetoken 149 {\cyrillicH} +\defineactivetoken 150 {\cyrillicC} +\defineactivetoken 151 {\cyrillicCH} +\defineactivetoken 152 {\cyrillicSH} +\defineactivetoken 153 {\cyrillicSHCH} +\defineactivetoken 154 {\cyrillicHRDSN} +\defineactivetoken 155 {\cyrillicERY} +\defineactivetoken 156 {\cyrillicSFTSN} +\defineactivetoken 157 {\cyrillicEREV} +\defineactivetoken 158 {\cyrillicYU} +\defineactivetoken 159 {\cyrillicYA} +\defineactivetoken 160 {\textdag} % Changed by V.F. 07/02/2003 (was: \dag) +\defineactivetoken 161 {\textdegree} +\defineactivetoken 162 {\cyrillicGUP} +\defineactivetoken 163 {\textsterling} % Changed by V.F. 07/02/2003 (was: \sterling) +\defineactivetoken 164 {\sectionmark} % Changed by V.F. 07/02/2003 (was: \S) +\defineactivetoken 165 {\textbullet} % Changed by V.F. 07/02/2003 (was: \bullet} +\defineactivetoken 166 {\paragraphmark} % Changed by V.F. 07/02/2003 (was: \P) +\defineactivetoken 167 {\cyrillicII} +\defineactivetoken 168 {\registered} +\defineactivetoken 169 {\copyright} +\defineactivetoken 170 {\trademark} % Changed by V.F. 07/02/2003 (was: \texttrademark} +\defineactivetoken 171 {\cyrillicDJE} +\defineactivetoken 172 {\cyrillicdje} +\defineactivetoken 174 {\'\cyrillicG} +\defineactivetoken 175 {\'\cyrillicg} +\defineactivetoken 180 {\cyrillicii} +\defineactivetoken 182 {\cyrillicgup} +\defineactivetoken 183 {\cyrillicJE} +\defineactivetoken 184 {\cyrillicIE} +\defineactivetoken 185 {\cyrillicie} +\defineactivetoken 186 {\cyrillicYI} +\defineactivetoken 187 {\cyrillicyi} +\defineactivetoken 188 {\cyrillicLJE} +\defineactivetoken 189 {\cyrilliclje} +\defineactivetoken 190 {\cyrillicNJE} +\defineactivetoken 191 {\cyrillicnje} +\defineactivetoken 192 {\cyrillicje} +\defineactivetoken 193 {\cyrillicDZE} +\defineactivetoken 196 {\textflorin} % Changed by V.F. 07/02/2003 (was: \florijn) +\defineactivetoken 199 {\leftguillemot} +\defineactivetoken 200 {\rightguillemot} +\defineactivetoken 201 {\textellipsis} % Changed by V.F. 07/02/2003 (was: \dots) +\defineactivetoken 202 {\nonbreakablespace} +\defineactivetoken 203 {\cyrillicTSHE} +\defineactivetoken 204 {\cyrillictshe} +\defineactivetoken 205 {\'\cyrillicK} +\defineactivetoken 206 {\'\cyrillick} +\defineactivetoken 207 {\cyrillicdze} +\defineactivetoken 208 {\endash} +\defineactivetoken 209 {\emdash} +\defineactivetoken 210 {\upperleftdoublesixquote} % Changed by V.F. 07/02/2003 + % (was: \upperleftsinglesixquote) +\defineactivetoken 211 {\upperrightdoubleninequote} +\defineactivetoken 212 {\upperleftsinglesixquote} +\defineactivetoken 213 {\upperrightsingleninequote} +\defineactivetoken 215 {\lowerleftdoubleninequote} +\defineactivetoken 216 {\cyrillicUSHRT} +\defineactivetoken 217 {\cyrillicushrt} +\defineactivetoken 218 {\cyrillicDZHE} +\defineactivetoken 219 {\cyrillicdzhe} +\defineactivetoken 220 {\textnumero} +\defineactivetoken 221 {\cyrillicYO} +\defineactivetoken 222 {\cyrillicyo} +\defineactivetoken 223 {\cyrillicya} +\defineactivetoken 224 {\cyrillica} +\defineactivetoken 225 {\cyrillicb} +\defineactivetoken 226 {\cyrillicv} +\defineactivetoken 227 {\cyrillicg} +\defineactivetoken 228 {\cyrillicd} +\defineactivetoken 229 {\cyrillice} +\defineactivetoken 230 {\cyrilliczh} +\defineactivetoken 231 {\cyrillicz} +\defineactivetoken 232 {\cyrillici} +\defineactivetoken 233 {\cyrillicishrt} +\defineactivetoken 234 {\cyrillick} +\defineactivetoken 235 {\cyrillicl} +\defineactivetoken 236 {\cyrillicm} +\defineactivetoken 237 {\cyrillicn} +\defineactivetoken 238 {\cyrillico} +\defineactivetoken 239 {\cyrillicp} +\defineactivetoken 240 {\cyrillicr} +\defineactivetoken 241 {\cyrillics} +\defineactivetoken 242 {\cyrillict} +\defineactivetoken 243 {\cyrillicu} +\defineactivetoken 244 {\cyrillicf} +\defineactivetoken 245 {\cyrillich} +\defineactivetoken 246 {\cyrillicc} +\defineactivetoken 247 {\cyrillicch} +\defineactivetoken 248 {\cyrillicsh} +\defineactivetoken 249 {\cyrillicshch} +\defineactivetoken 250 {\cyrillichrdsn} +\defineactivetoken 251 {\cyrillicery} +\defineactivetoken 252 {\cyrillicsftsn} +\defineactivetoken 253 {\cyrillicerev} +\defineactivetoken 254 {\cyrillicyu} +\defineactivetoken 255 {\textcurrency} +\defineactivetoken 173 {\mathematics{\neq}} % Added by V.F. 07/02/2003 +\defineactivetoken 176 {\mathematics{\infty}} % Added by V.F. 07/02/2003 +\defineactivetoken 177 {\textpm} % Added by V.F. 07/02/2003 +\defineactivetoken 178 {\mathematics{\leq}} % Added by V.F. 07/02/2003 +\defineactivetoken 179 {\mathematics{\geq}} % Added by V.F. 07/02/2003 +\defineactivetoken 181 {\textmu} % Added by V.F. 07/02/2003 +\defineactivetoken 194 {\textlognot} % Added by V.F. 07/02/2003 +\defineactivetoken 195 {\textsurd} % Added by V.F. 07/02/2003 +\defineactivetoken 197 {\mathematics{\approx}} % Added by V.F. 07/02/2003 +\defineactivetoken 198 {\mathematics{\Delta}} % Added by V.F. 07/02/2003 +\defineactivetoken 214 {\textdiv} % Added by V.F. 07/02/2003 + +\stopregime + +\endinput diff --git a/tex/context/base/regi-def.mkii b/tex/context/base/regi-def.mkii new file mode 100644 index 000000000..e26709c77 --- /dev/null +++ b/tex/context/base/regi-def.mkii @@ -0,0 +1,21 @@ +%D \module +%D [ file=regi-def, +%D version=2000.20.12, % split from less verbose base file +%D title=\CONTEXT\ Regime Macros, +%D subtitle=Default Character Definitions, +%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. + +\startregime[default] + +\dostepwiserecurse{128}{255}{1} + {\expanded{\defineactivetoken\recurselevel\space{\rawcharacter\recurselevel}}}% + +\stopregime + +\endinput diff --git a/tex/context/base/regi-ibm.mkii b/tex/context/base/regi-ibm.mkii new file mode 100644 index 000000000..1fad9545a --- /dev/null +++ b/tex/context/base/regi-ibm.mkii @@ -0,0 +1,73 @@ +%D \module +%D [ file=regi-ibm, +%D version=1995.01.01, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=The Good Old MSDOS IBM codepage, +%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. + +%D This module activates the \cap{IBM PC} high \ASCII\ +%D characters, such as and . + +\startregime [ibm] + +\defineactivetoken 145 {\aeligature} % +\defineactivetoken 146 {\AEligature} % +\defineactivetoken 152 {\ijligature} % + +\defineactivetoken 225 {\ssharp} % + +\defineactivetoken 160 {\aacute} % +\defineactivetoken 130 {\eacute} % +\defineactivetoken 144 {\Eacute} % +\defineactivetoken 161 {\iacute} % +\defineactivetoken 162 {\oacute} % +\defineactivetoken 163 {\uacute} % + +\defineactivetoken 135 {\ccedilla} % +\defineactivetoken 128 {\Ccedilla} % + +\defineactivetoken 132 {\adiaeresis} % +\defineactivetoken 142 {\Adiaeresis} % +\defineactivetoken 137 {\ediaeresis} % +\defineactivetoken 139 {\idiaeresis} % +\defineactivetoken 148 {\odiaeresis} % +\defineactivetoken 153 {\Odiaeresis} % +\defineactivetoken 129 {\udiaeresis} % +\defineactivetoken 154 {\Udiaeresis} % + +\defineactivetoken 164 {\ntilde} % +\defineactivetoken 165 {\Ntilde} % + +\defineactivetoken 134 {\aring} % +\defineactivetoken 143 {\Aring} % + +\defineactivetoken 131 {\acircumflex} % +\defineactivetoken 136 {\ecircumflex} % +\defineactivetoken 140 {\icircumflex} % +\defineactivetoken 147 {\ocircumflex} % +\defineactivetoken 150 {\ucircumflex} % + +\defineactivetoken 133 {\agrave} % +\defineactivetoken 138 {\egrave} % +\defineactivetoken 141 {\igrave} % +\defineactivetoken 149 {\ograve} % +\defineactivetoken 151 {\ugrave} % + +\stopregime + +% todo + +\startregime [ibm] + +\defineactivetoken {\ifvmode\leavevmode\fi\leftguillemot\prewordbreak} +\defineactivetoken {\prewordbreak\rightguillemot} + +\stopregime + +\endinput diff --git a/tex/context/base/regi-ini.lua b/tex/context/base/regi-ini.lua new file mode 100644 index 000000000..837397607 --- /dev/null +++ b/tex/context/base/regi-ini.lua @@ -0,0 +1,88 @@ +if not modules then modules = { } end modules ['regi-ini'] = { + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local utf = unicode.utf8 +local char, utfchar, gsub = string.char, utf.char, string.gsub +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.synonyms = regimes.synonyms or { } + +storage.register("regimes/synonyms", regimes.synonyms, "regimes.synonyms") + +-- setmetatable(regimes.data,_empty_table_) + +regimes.currentregime = "utf" + +--[[ldx-- +

We will hook regime handling code into the input methods.

+--ldx]]-- + +function regimes.number(n) + if type(n) == "string" then return tonumber(n,16) else return n end +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) + 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 next, 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 + return (gsub(line,"(.)",rur)) -- () redundant + end + end + return line +end + +function regimes.enable(regime) + regime = regimes.synonyms[regime] or regime + if regimes.data[regime] then + regimes.currentregime = regime + local translate = regimes.translate + resolvers.install_text_filter('input',function(s) + return translate(s,regime) + end) + else + regimes.disable() + end +end + +function regimes.disable() + 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 new file mode 100644 index 000000000..3cdfe2763 --- /dev/null +++ b/tex/context/base/regi-ini.mkii @@ -0,0 +1,248 @@ +%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 Remark: regimes accumulate, so there is no explicit reset in +%D mkii mode. + +%D Variables. + +\def\@reg@{@r@eg@} % regime prefix + +%D \macros +%D {currentregime} + +\let\currentregime\empty +\let\defaultregime\s!default + +%D Some low level inheritance stuff (mkii). + +\def\doautosetregime#1#2% + {\ifnum#2>127 + \expanded{\defineactivetoken #2 \@EA\noexpand\csname#1\endcsname}% + \fi} + +%D \macros +%D {startregime} +%D +%D Sometimes it makes sense to activate the characters in the +%D upper half of the character table. Such a bundle of +%D characters can be packages in a regime. Later we will see +%D encodings (that links characters slots to glyphs) and +%D mappings (that take care of hyphenation and case changes). +%D +%D When character~231 is of category code letter, it +%D directly maps to glyph~231 (unless of course some virtual +%D font is used). By making character~231 active, we can map +%D it onto for instance the glyph in slot 233. This mapping +%D can in itself be indirect, in the sense that it is for +%D instance handled by an accent command. +%D +%D Regimes are implemented roughly the same as mappings, but +%D enabled under different circumstances. In the future, the +%D low level implementation may change. + +\def\startregime[#1]% + {\pushmacro\currentregime + \edef\currentregime{#1}% + \checkregimetoks} + +\def\checkregimetoks + {\doifundefined{\@reg@\currentregime} + {\@EA\newtoks\csname\@reg@\currentregime\endcsname}} + +\def\stopregime + {\popmacro\currentregime} + +\def\setregimetoks + {\checkregimetoks + \@EA\let\@EA\regimetoks\csname\@reg@\currentregime\endcsname} + +%D \macros +%D {defineactivedecimal, defineactivedecimals, defineactivetoken} +%D +%D The following commands are rather ugly ones. It makes a +%D character active and assigns it a value. When expanded, +%D the decimal number of the character is passed as first +%D argument. +%D +%D \starttyping +%D \def\decimalcharacter#1{\message{#1 is now active}} +%D +%D \defineactivedecimal 122 {\decimalcharacter} +%D +%D \defineactivedecimals 128 to 255 as {\decimalcharacter} +%D \stoptyping +%D +%D This command is typically used in coding definitions, +%D like the \UNICODE\ one. + +\def\dodefineactivedecimal#1#2% \unexpanded ? pdfdoc encoding + {\catcode#1\active + \scratchcounter\uccode\activehackcode + \uccode\activehackcode#1\relax + \uppercase{\unexpanded\edef~{\noexpand#2{\number#1}}}% + \uccode\activehackcode\scratchcounter} + +\long\def\defineactivedecimal#1 #2 % + {\setregimetoks + \regimetoks\expandafter{\the\regimetoks\dodefineactivedecimal{#1}{#2}}} + +\long\def\defineactivedecimals#1 to #2 as #3 % + {\setregimetoks + \dostepwiserecurse{#1}{#2}\plusone + {\regimetoks\@EA\@EA\@EA{\@EA\the\@EA\regimetoks\@EA\dodefineactivedecimal\@EA{\recurselevel}{#3}}}} + +\def\doexpandactivedecimal#1% + {\ifnum#1>\scratchcounter + \expandafter\gobbletwoarguments + \else + \noexpand\dodefineactivedecimal{#1}{\the\scratchtoks}% + \expandafter\expandafter\expandafter\doexpandactivedecimal\expandafter + \fi\expandafter{\the\numexpr#1+\plusone\relax}} + +\long\def\defineactivedecimals#1 to #2 as #3 % + {\setregimetoks + \scratchcounter#2\relax + \scratchtoks{#3}% + \expanded{\regimetoks{\the\regimetoks\doexpandactivedecimal{#1}}}% + \ignorespaces} + +\long\def\defineactivetoken #1 #2% no {} after #2, else no kern + {\setregimetoks + \regimetoks\expandafter{\the\regimetoks\defineactivecharacter#1 {#2}}} + +\long\def\defineactiveinspector #1 #2% watch the missing {} + {\setregimetoks + \regimetoks\expandafter{\the\regimetoks\defineactivecharacter#1 {#2}}} + +%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.mkii} + {\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 Goodie: + +\def\showregime[#1]% + {\doifnot{#1}{utf} + {\bgroup + \enableregime[#1]% + \starttabulate[|l|l|l|] + \dostepwiserecurse{128}{255}{1} + {\expanded + {\scantokens + {\NC \recurselevel + \NC \rawcharacter\recurselevel + \NC \noexpand\tttf + \noexpand\meaning\rawcharacter\recurselevel \NC \NR}}}% + \stoptabulate + \unskip + \egroup}} + +%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 + +\fi + +\protect \endinput diff --git a/tex/context/base/regi-ini.mkiv b/tex/context/base/regi-ini.mkiv new file mode 100644 index 000000000..db7a224ac --- /dev/null +++ b/tex/context/base/regi-ini.mkiv @@ -0,0 +1,55 @@ +%D \module +%D [ file=regi-ini, +%D version=2005.04.25, +%D title=\CONTEXT\ Regime Macros, +%D subtitle=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. + +\unprotect + +%D First some initialization code: + +\registerctxluafile{regi-ini}{1.001} + +%D \macros +%D {currentregime} + +\def\currentregime{utf} + +%D \macros +%D {defineregimesynonym,trueregimename} + +\unexpanded\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} + +\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-mac.mkii b/tex/context/base/regi-mac.mkii new file mode 100644 index 000000000..b3c281ec0 --- /dev/null +++ b/tex/context/base/regi-mac.mkii @@ -0,0 +1,147 @@ +%D \module +%D [ file=regi-mac, +%D version=2001.03.18, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=Mac Encoding, +%D author={Michel Bovani \& Adam Lindsay \& 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. + +\startregime [mac] + +\defineactivetoken 128 {\Adiaeresis} +\defineactivetoken 129 {\Aring} +\defineactivetoken 130 {\Ccedilla} +\defineactivetoken 131 {\Eacute} +\defineactivetoken 132 {\Ntilde} +\defineactivetoken 133 {\Odiaeresis} +\defineactivetoken 134 {\Udiaeresis} +\defineactivetoken 135 {\aacute} +\defineactivetoken 136 {\agrave} +\defineactivetoken 137 {\acircumflex} +\defineactivetoken 138 {\adiaeresis} +\defineactivetoken 139 {\atilde} +\defineactivetoken 140 {\aring} +\defineactivetoken 141 {\ccedilla} +\defineactivetoken 142 {\eacute} +\defineactivetoken 143 {\egrave} +\defineactivetoken 144 {\ecircumflex} +\defineactivetoken 145 {\ediaeresis} +\defineactivetoken 146 {\iacute} +\defineactivetoken 147 {\igrave} +\defineactivetoken 148 {\icircumflex} +\defineactivetoken 149 {\idiaeresis} +\defineactivetoken 150 {\ntilde} +\defineactivetoken 151 {\oacute} +\defineactivetoken 152 {\ograve} +\defineactivetoken 153 {\ocircumflex} +\defineactivetoken 154 {\odiaeresis} +\defineactivetoken 155 {\otilde} +\defineactivetoken 156 {\uacute} +\defineactivetoken 157 {\ugrave} +\defineactivetoken 158 {\ucircumflex} +\defineactivetoken 159 {\udiaeresis} +\defineactivetoken 160 {\textdag} +\defineactivetoken 161 {\textdegree} +\defineactivetoken 162 {\textcent} +\defineactivetoken 163 {\textsterling} +\defineactivetoken 164 {\sectionmark} +\defineactivetoken 165 {\textbullet} +\defineactivetoken 166 {\paragraphmark} +\defineactivetoken 167 {\ssharp} +\defineactivetoken 168 {\registered} +\defineactivetoken 169 {\copyright} +\defineactivetoken 170 {\trademark} +\defineactivetoken 171 {\textacute} +\defineactivetoken 172 {\textdiaeresis} +\defineactivetoken 173 {\mathematics\neq} +\defineactivetoken 174 {\AEligature} +\defineactivetoken 175 {\Ostroke} +\defineactivetoken 176 {\mathematics\infty} +\defineactivetoken 177 {\textpm} +\defineactivetoken 178 {\mathematics\leq} +\defineactivetoken 179 {\mathematics\geq} +\defineactivetoken 180 {\textyen} +\defineactivetoken 181 {\textmu} +\defineactivetoken 182 {\mathematics\partial} +\defineactivetoken 183 {\mathematics\Sigma} +\defineactivetoken 184 {\mathematics\Pi} +\defineactivetoken 185 {\mathematics\pi} +\defineactivetoken 186 {\mathematics\smallint} +\defineactivetoken 187 {\ordfeminine} +\defineactivetoken 188 {\ordmasculine} +\defineactivetoken 189 {\mathematics\Omega} +\defineactivetoken 190 {\aeligature} +\defineactivetoken 191 {\ostroke} +\defineactivetoken 192 {\questiondown} +\defineactivetoken 193 {\exclamdown} +\defineactivetoken 194 {\textlognot} +\defineactivetoken 195 {\mathematics{\sqrt{}}} +\defineactivetoken 196 {\textflorin} +\defineactivetoken 197 {\mathematics\approx} +\defineactivetoken 198 {\mathematics\Delta} +\defineactivetoken 199 {\leftguillemot} +\defineactivetoken 200 {\rightguillemot} +\defineactivetoken 201 {\dots} +\defineactivetoken 202 {\nonbreakablespace} +\defineactivetoken 203 {\Agrave} +\defineactivetoken 204 {\Atilde} +\defineactivetoken 205 {\Otilde} +\defineactivetoken 206 {\OEligature} +\defineactivetoken 207 {\oeligature} +\defineactivetoken 208 {\endash} +\defineactivetoken 209 {\emdash} +\defineactivetoken 210 {\quotedblleft} +\defineactivetoken 211 {\quotedblright} +\defineactivetoken 212 {\quoteleft} +\defineactivetoken 213 {\quoteright} +\defineactivetoken 214 {\textdiv} +\defineactivetoken 215 {\mathematics\diamond} +\defineactivetoken 216 {\ydiaeresis} +\defineactivetoken 217 {\Ydiaeresis} +\defineactivetoken 218 {\textfraction} +\defineactivetoken 219 {\texteuro} +\defineactivetoken 220 {\guilsingleleft} +\defineactivetoken 221 {\guilsingleright} +\defineactivetoken 222 {fi} +\defineactivetoken 223 {fl} +\defineactivetoken 224 {\textddag} +\defineactivetoken 225 {\periodcentered} +\defineactivetoken 226 {\quotesinglebase} +\defineactivetoken 227 {\quotedblbase } +\defineactivetoken 228 {\perthousand} +\defineactivetoken 229 {\Acircumflex} +\defineactivetoken 230 {\Ecircumflex} +\defineactivetoken 231 {\Aacute} +\defineactivetoken 232 {\Ediaeresis} +\defineactivetoken 233 {\Egrave} +\defineactivetoken 234 {\Iacute} +\defineactivetoken 235 {\Icircumflex} +\defineactivetoken 236 {\Idiaeresis} +\defineactivetoken 237 {\Igrave} +\defineactivetoken 238 {\Oacute} +\defineactivetoken 239 {\Ocircumflex} +%defineactivetoken 240 % No definition for Apple logo glyph yet. +\defineactivetoken 241 {\Ograve} +\defineactivetoken 242 {\Uacute} +\defineactivetoken 243 {\Ucircumflex} +\defineactivetoken 244 {\Ugrave} +\defineactivetoken 245 {\dotlessi} +\defineactivetoken 246 {\textcircumflex} +\defineactivetoken 247 {\texttilde} +\defineactivetoken 248 {\textmacron} +\defineactivetoken 249 {\textbreve} +\defineactivetoken 250 {\textdotaccent} +\defineactivetoken 251 {\textring} +\defineactivetoken 252 {\textcedilla} +\defineactivetoken 253 {\texthungarumlaut} +\defineactivetoken 254 {\textogonek} +\defineactivetoken 255 {\textcaron} + +\stopregime + +\endinput diff --git a/tex/context/base/regi-syn.tex b/tex/context/base/regi-syn.tex new file mode 100644 index 000000000..7a8a9c146 --- /dev/null +++ b/tex/context/base/regi-syn.tex @@ -0,0 +1,73 @@ +%D \module +%D [ file=regi-syn, +%D version=2006.04.04, +%D title=\CONTEXT\ Regime Macros, +%D subtitle=Synonyms, +%D author=Mojca Miklavec \& 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 Regime Macros / Synonyms} + +\unprotect + +\defineregimesynonym [windows-1250] [cp1250] +\defineregimesynonym [windows-1251] [cp1251] +\defineregimesynonym [windows-1252] [cp1252] +\defineregimesynonym [windows-1253] [cp1253] +\defineregimesynonym [windows-1254] [cp1254] +%defineregimesynonym [windows-1255] [cp1255] % not supported yet (Hebrew) +%defineregimesynonym [windows-1256] [cp1256] % not supported yet (Arabic) +\defineregimesynonym [windows-1257] [cp1257] +%defineregimesynonym [windows-1258] [cp1258] % not supported yet (Vietnamese) + +\defineregimesynonym [il1] [8859-1] +\defineregimesynonym [il2] [8859-2] +\defineregimesynonym [il3] [8859-3] +\defineregimesynonym [il4] [8859-4] +\defineregimesynonym [il5] [8859-9] +\defineregimesynonym [il6] [8859-10] +\defineregimesynonym [il7] [8859-13] +%defineregimesynonym [il8] [8859-14] +\defineregimesynonym [il9] [8859-15] +\defineregimesynonym [il10] [8859-16] + +\defineregimesynonym [iso-8859-1] [8859-1] +\defineregimesynonym [iso-8859-2] [8859-2] +\defineregimesynonym [iso-8859-3] [8859-3] +\defineregimesynonym [iso-8859-4] [8859-4] +\defineregimesynonym [iso-8859-9] [8859-9] +\defineregimesynonym [iso-8859-10] [8859-10] +\defineregimesynonym [iso-8859-13] [8859-13] +%defineregimesynonym [iso-8859-14] [8859-14] +\defineregimesynonym [iso-8859-15] [8859-15] +\defineregimesynonym [iso-8859-16] [8859-16] + +\defineregimesynonym [latin1] [8859-1] +\defineregimesynonym [latin2] [8859-2] +\defineregimesynonym [latin3] [8859-3] +\defineregimesynonym [latin4] [8859-4] +\defineregimesynonym [latin5] [8859-9] +\defineregimesynonym [latin6] [8859-10] +\defineregimesynonym [latin7] [8859-13] +%defineregimesynonym [latin8] [8859-14] +\defineregimesynonym [latin9] [8859-15] +\defineregimesynonym [latin10] [8859-16] + +% kind of special + +\defineregimesynonym [utf-8] [utf] +\defineregimesynonym [utf8] [utf] + +% for historical reasons / compatibility + +\defineregimesynonym [windows] [cp1252] +\defineregimesynonym [grk] [8859-7] +\defineregimesynonym [iso88595] [8859-5] + +\protect \endinput + diff --git a/tex/context/base/regi-uni.mkii b/tex/context/base/regi-uni.mkii new file mode 100644 index 000000000..c4d9521e9 --- /dev/null +++ b/tex/context/base/regi-uni.mkii @@ -0,0 +1,24 @@ +%D \module +%D [ file=enco-uni, +%D version=1998.10.18, +%D title=\CONTEXT\ Encoding 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. + +%D This module activates all characters in the upper range +%D and sets them to the basic unicodehandler. Beware, this is +%D a special purpose handler (esp for chinese encodings). + +\startregime[unicode] + +\defineactivedecimals 128 to 255 as {\handleunicodeflowglyph} + +\stopregime + +\endinput diff --git a/tex/context/base/regi-utf.mkii b/tex/context/base/regi-utf.mkii new file mode 100644 index 000000000..b3423b15a --- /dev/null +++ b/tex/context/base/regi-utf.mkii @@ -0,0 +1,52 @@ +%D \module +%D [ file=regi-utf, +%D version=2002.12.03, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=UTF-8, +%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. + +\ifnum\texengine>\pdftexengine + \expandafter \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 +%D instead of a active token handler because here we don't want +%D the \type {{}}. We only support this in \ETEX. + +% ÀÁÂÃÄÅàáâãäå +% ÆÇæç +% ÈÉÊËèéêë +% ÌÍÎÏÞìíîïþ +% Ðð +% Ññ +% ÒÓÔÕÖòóôõö +% Øø +% ÙÚÛÜùúû +% Ýýÿ +% ß +% Ţţ + +\unprotect + +\startregime[utf] + +\dostepwiserecurse{192}{223}{1} + {\expanded{\defineactiveinspector{\recurselevel} {\noexpand\utftwouniglph {\recurselevel}}}} % space delimited + +\dostepwiserecurse{224}{239}{1} + {\expanded{\defineactiveinspector{\recurselevel} {\noexpand\utfthreeuniglph{\recurselevel}}}} % space delimited + +\dostepwiserecurse{240}{247}{1} + {\expanded{\defineactiveinspector{\recurselevel} {\noexpand\utffouruniglph {\recurselevel}}}} % space delimited + +\stopregime + +\protect \endinput diff --git a/tex/context/base/regi-vis.mkii b/tex/context/base/regi-vis.mkii new file mode 100644 index 000000000..d1071354f --- /dev/null +++ b/tex/context/base/regi-vis.mkii @@ -0,0 +1,158 @@ +%D \module +%D [ file=regi-vis, +%D version=2005.12.26, +%D title=\CONTEXT\ Encoding Macros, +%D subtitle=viscii, +%D author=script-generated, +%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. + +%D Support for VISCII input encoding (regime) for Vietnamese. +%D +%D Usage: +%D \type{\enableregime[vis]} + + +\startregime[viscii] + +\defineactivetoken 2 {\Abrevehook} % 1EB2 LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE +\defineactivetoken 5 {\Abrevetilde} % 1EB4 LATIN CAPITAL LETTER A WITH BREVE AND TILDE +\defineactivetoken 6 {\Acircumflextilde} % 1EAA LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE +\defineactivetoken 20 {\Yhook} % 1EF6 LATIN CAPITAL LETTER Y WITH HOOK ABOVE +\defineactivetoken 25 {\Ytilde} % 1EF8 LATIN CAPITAL LETTER Y WITH TILDE +\defineactivetoken 30 {\Ydotbelow} % 1EF4 LATIN CAPITAL LETTER Y WITH DOT BELOW +\defineactivetoken 128 {\Adotbelow} % 1EA0 LATIN CAPITAL LETTER A WITH DOT BELOW +\defineactivetoken 129 {\Abreveacute} % 1EAE LATIN CAPITAL LETTER A WITH BREVE AND ACUTE +\defineactivetoken 130 {\Abrevegrave} % 1EB0 LATIN CAPITAL LETTER A WITH BREVE AND GRAVE +\defineactivetoken 131 {\Abrevedotbelow} % 1EB6 LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW +\defineactivetoken 132 {\Acircumflexacute} % 1EA4 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE +\defineactivetoken 133 {\Acircumflexgrave} % 1EA6 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE +\defineactivetoken 134 {\Acircumflexhook} % 1EA8 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE +\defineactivetoken 135 {\Acircumflexdotbelow} % 1EAC LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW +\defineactivetoken 136 {\Etilde} % 1EBC LATIN CAPITAL LETTER E WITH TILDE +\defineactivetoken 137 {\Edotbelow} % 1EB8 LATIN CAPITAL LETTER E WITH DOT BELOW +\defineactivetoken 138 {\Ecircumflexacute} % 1EBE LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE +\defineactivetoken 139 {\Ecircumflexgrave} % 1EC0 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE +\defineactivetoken 140 {\Ecircumflexhook} % 1EC2 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE +\defineactivetoken 141 {\Ecircumflextilde} % 1EC4 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE +\defineactivetoken 142 {\Ecircumflexdotbelow} % 1EC6 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW +\defineactivetoken 143 {\Ocircumflexacute} % 1ED0 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE +\defineactivetoken 144 {\Ocircumflexgrave} % 1ED2 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE +\defineactivetoken 145 {\Ocircumflexhook} % 1ED4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE +\defineactivetoken 146 {\Ocircumflextilde} % 1ED6 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE +\defineactivetoken 147 {\Ocircumflexdotbelow} % 1ED8 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW +\defineactivetoken 148 {\Ohorndotbelow} % 1EE2 LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW +\defineactivetoken 149 {\Ohornacute} % 1EDA LATIN CAPITAL LETTER O WITH HORN AND ACUTE +\defineactivetoken 150 {\Ohorngrave} % 1EDC LATIN CAPITAL LETTER O WITH HORN AND GRAVE +\defineactivetoken 151 {\Ohornhook} % 1EDE LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE +\defineactivetoken 152 {\Idotbelow} % 1ECA LATIN CAPITAL LETTER I WITH DOT BELOW +\defineactivetoken 153 {\Ohook} % 1ECE LATIN CAPITAL LETTER O WITH HOOK ABOVE +\defineactivetoken 154 {\Odotbelow} % 1ECC LATIN CAPITAL LETTER O WITH DOT BELOW +\defineactivetoken 155 {\Ihook} % 1EC8 LATIN CAPITAL LETTER I WITH HOOK ABOVE +\defineactivetoken 156 {\Uhook} % 1EE6 LATIN CAPITAL LETTER U WITH HOOK ABOVE +\defineactivetoken 157 {\Utilde} % 0168 LATIN CAPITAL LETTER U WITH TILDE +\defineactivetoken 158 {\Udotbelow} % 1EE4 LATIN CAPITAL LETTER U WITH DOT BELOW +\defineactivetoken 159 {\Ygrave} % 1EF2 LATIN CAPITAL LETTER Y WITH GRAVE +\defineactivetoken 160 {\Otilde} % 00D5 LATIN CAPITAL LETTER O WITH TILDE +\defineactivetoken 161 {\abreveacute} % 1EAF LATIN SMALL LETTER A WITH BREVE AND ACUTE +\defineactivetoken 162 {\abrevegrave} % 1EB1 LATIN SMALL LETTER A WITH BREVE AND GRAVE +\defineactivetoken 163 {\abrevedotbelow} % 1EB7 LATIN SMALL LETTER A WITH BREVE AND DOT BELOW +\defineactivetoken 164 {\acircumflexacute} % 1EA5 LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE +\defineactivetoken 165 {\acircumflexgrave} % 1EA7 LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE +\defineactivetoken 166 {\Acircumflexhook} % 1EA8 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE +\defineactivetoken 167 {\acircumflexdotbelow} % 1EAD LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW +\defineactivetoken 168 {\etilde} % 1EBD LATIN SMALL LETTER E WITH TILDE +\defineactivetoken 169 {\edotbelow} % 1EB9 LATIN SMALL LETTER E WITH DOT BELOW +\defineactivetoken 170 {\ecircumflexacute} % 1EBF LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE +\defineactivetoken 171 {\ecircumflexgrave} % 1EC1 LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE +\defineactivetoken 172 {\ecircumflexhook} % 1EC3 LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE +\defineactivetoken 173 {\ecircumflextilde} % 1EC5 LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE +\defineactivetoken 174 {\ecircumflexdotbelow} % 1EC7 LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW +\defineactivetoken 175 {\ocircumflexacute} % 1ED1 LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE +\defineactivetoken 176 {\ocircumflexgrave} % 1ED3 LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE +\defineactivetoken 177 {\ocircumflexhook} % 1ED5 LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE +\defineactivetoken 178 {\ocircumflextilde} % 1ED7 LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE +\defineactivetoken 179 {\Ohorntilde} % 1EE0 LATIN CAPITAL LETTER O WITH HORN AND TILDE +\defineactivetoken 180 {\Ohorn} % 01A0 LATIN CAPITAL LETTER O WITH HORN +\defineactivetoken 181 {\ocircumflexdotbelow} % 1ED9 LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW +\defineactivetoken 182 {\ohorngrave} % 1EDD LATIN SMALL LETTER O WITH HORN AND GRAVE +\defineactivetoken 183 {\ohornhook} % 1EDF LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE +\defineactivetoken 184 {\idotbelow} % 1ECB LATIN SMALL LETTER I WITH DOT BELOW +\defineactivetoken 185 {\Uhorndotbelow} % 1EF0 LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW +\defineactivetoken 186 {\Uhornacute} % 1EE8 LATIN CAPITAL LETTER U WITH HORN AND ACUTE +\defineactivetoken 187 {\Uhorngrave} % 1EEA LATIN CAPITAL LETTER U WITH HORN AND GRAVE +\defineactivetoken 188 {\Uhornhook} % 1EEC LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE +\defineactivetoken 189 {\ohorn} % 01A1 LATIN SMALL LETTER O WITH HORN +\defineactivetoken 190 {\ohornacute} % 1EDB LATIN SMALL LETTER O WITH HORN AND ACUTE +\defineactivetoken 191 {\Uhorn} % 01AF LATIN CAPITAL LETTER U WITH HORN +\defineactivetoken 192 {\Agrave} % 00C0 LATIN CAPITAL LETTER A WITH GRAVE +\defineactivetoken 193 {\Aacute} % 00C1 LATIN CAPITAL LETTER A WITH ACUTE +\defineactivetoken 194 {\Acircumflex} % 00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX +\defineactivetoken 195 {\Atilde} % 00C3 LATIN CAPITAL LETTER A WITH TILDE +\defineactivetoken 196 {\Ahook} % 1EA2 LATIN CAPITAL LETTER A WITH HOOK ABOVE +\defineactivetoken 197 {\Abreve} % 0102 LATIN CAPITAL LETTER A WITH BREVE +\defineactivetoken 198 {\abrevehook} % 1EB3 LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE +\defineactivetoken 199 {\abrevetilde} % 1EB5 LATIN SMALL LETTER A WITH BREVE AND TILDE +\defineactivetoken 200 {\Egrave} % 00C8 LATIN CAPITAL LETTER E WITH GRAVE +\defineactivetoken 201 {\Eacute} % 00C9 LATIN CAPITAL LETTER E WITH ACUTE +\defineactivetoken 202 {\Ecircumflex} % 00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX +\defineactivetoken 203 {\Ehook} % 1EBA LATIN CAPITAL LETTER E WITH HOOK ABOVE +\defineactivetoken 204 {\Igrave} % 00CC LATIN CAPITAL LETTER I WITH GRAVE +\defineactivetoken 205 {\Iacute} % 00CD LATIN CAPITAL LETTER I WITH ACUTE +\defineactivetoken 206 {\Itilde} % 0128 LATIN CAPITAL LETTER I WITH TILDE +\defineactivetoken 207 {\ygrave} % 1EF3 LATIN SMALL LETTER Y WITH GRAVE +\defineactivetoken 208 {\Dstroke} % 0110 LATIN CAPITAL LETTER D WITH STROKE +\defineactivetoken 209 {\uhornacute} % 1EE9 LATIN SMALL LETTER U WITH HORN AND ACUTE +\defineactivetoken 210 {\Ograve} % 00D2 LATIN CAPITAL LETTER O WITH GRAVE +\defineactivetoken 211 {\Oacute} % 00D3 LATIN CAPITAL LETTER O WITH ACUTE +\defineactivetoken 212 {\Ocircumflex} % 00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX +\defineactivetoken 213 {\adotbelow} % 1EA1 LATIN SMALL LETTER A WITH DOT BELOW +\defineactivetoken 214 {\yhook} % 1EF7 LATIN SMALL LETTER Y WITH HOOK ABOVE +\defineactivetoken 215 {\uhorngrave} % 1EEB LATIN SMALL LETTER U WITH HORN AND GRAVE +\defineactivetoken 216 {\uhornhook} % 1EED LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE +\defineactivetoken 217 {\Ugrave} % 00D9 LATIN CAPITAL LETTER U WITH GRAVE +\defineactivetoken 218 {\Uacute} % 00DA LATIN CAPITAL LETTER U WITH ACUTE +\defineactivetoken 219 {\ytilde} % 1EF9 LATIN SMALL LETTER Y WITH TILDE +\defineactivetoken 220 {\ydotbelow} % 1EF5 LATIN SMALL LETTER Y WITH DOT BELOW +\defineactivetoken 221 {\Yacute} % 00DD LATIN CAPITAL LETTER Y WITH ACUTE +\defineactivetoken 222 {\ohorntilde} % 1EE1 LATIN SMALL LETTER O WITH HORN AND TILDE +\defineactivetoken 223 {\uhorn} % 01B0 LATIN SMALL LETTER U WITH HORN +\defineactivetoken 224 {\agrave} % 00E0 LATIN SMALL LETTER A WITH GRAVE +\defineactivetoken 225 {\aacute} % 00E1 LATIN SMALL LETTER A WITH ACUTE +\defineactivetoken 226 {\acircumflex} % 00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX +\defineactivetoken 227 {\atilde} % 00E3 LATIN SMALL LETTER A WITH TILDE +\defineactivetoken 228 {\ahook} % 1EA3 LATIN SMALL LETTER A WITH HOOK ABOVE +\defineactivetoken 229 {\abreve} % 0103 LATIN SMALL LETTER A WITH BREVE +\defineactivetoken 230 {\uhorntilde} % 1EEF LATIN SMALL LETTER U WITH HORN AND TILDE +\defineactivetoken 231 {\acircumflextilde} % 1EAB LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE +\defineactivetoken 232 {\egrave} % 00E8 LATIN SMALL LETTER E WITH GRAVE +\defineactivetoken 233 {\eacute} % 00E9 LATIN SMALL LETTER E WITH ACUTE +\defineactivetoken 234 {\ecircumflex} % 00EA LATIN SMALL LETTER E WITH CIRCUMFLEX +\defineactivetoken 235 {\ehook} % 1EBB LATIN SMALL LETTER E WITH HOOK ABOVE +\defineactivetoken 236 {\igrave} % 00EC LATIN SMALL LETTER I WITH GRAVE +\defineactivetoken 237 {\iacute} % 00ED LATIN SMALL LETTER I WITH ACUTE +\defineactivetoken 238 {\itilde} % 0129 LATIN SMALL LETTER I WITH TILDE +\defineactivetoken 239 {\ihook} % 1EC9 LATIN SMALL LETTER I WITH HOOK ABOVE +\defineactivetoken 240 {\dstroke} % 0111 LATIN SMALL LETTER D WITH STROKE +\defineactivetoken 241 {\uhorndotbelow} % 1EF1 LATIN SMALL LETTER U WITH HORN AND DOT BELOW +\defineactivetoken 242 {\ograve} % 00F2 LATIN SMALL LETTER O WITH GRAVE +\defineactivetoken 243 {\oacute} % 00F3 LATIN SMALL LETTER O WITH ACUTE +\defineactivetoken 244 {\ocircumflex} % 00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX +\defineactivetoken 245 {\otilde} % 00F5 LATIN SMALL LETTER O WITH TILDE +\defineactivetoken 246 {\ohook} % 1ECF LATIN SMALL LETTER O WITH HOOK ABOVE +\defineactivetoken 247 {\odotbelow} % 1ECD LATIN SMALL LETTER O WITH DOT BELOW +\defineactivetoken 248 {\udotbelow} % 1EE5 LATIN SMALL LETTER U WITH DOT BELOW +\defineactivetoken 249 {\ugrave} % 00F9 LATIN SMALL LETTER U WITH GRAVE +\defineactivetoken 250 {\uacute} % 00FA LATIN SMALL LETTER U WITH ACUTE +\defineactivetoken 251 {\utilde} % 0169 LATIN SMALL LETTER U WITH TILDE +\defineactivetoken 252 {\uhook} % 1EE7 LATIN SMALL LETTER U WITH HOOK ABOVE +\defineactivetoken 253 {\yacute} % 00FD LATIN SMALL LETTER Y WITH ACUTE +\defineactivetoken 254 {\ohorndotbelow} % 1EE3 LATIN SMALL LETTER O WITH HORN AND DOT BELOW +\defineactivetoken 255 {\Uhorntilde} % 1EEE LATIN CAPITAL LETTER U WITH HORN AND TILDE + +\stopregime + diff --git a/tex/context/base/rlxcache.rlx b/tex/context/base/rlxcache.rlx new file mode 100644 index 000000000..006e5feac --- /dev/null +++ b/tex/context/base/rlxcache.rlx @@ -0,0 +1,71 @@ + + + + + + /.eps + /.pdf + + texmfstart pstopdf --convert + --inputpath="" + --outputpath="" + ".eps" + + + + + /.svg + /.pdf + + texmfstart pstopdf --convert + --inputpath="" + --outputpath="" + ".svg" + + + + + /.svgz + /.pdf + + texmfstart pstopdf --convert + --inputpath="" + --outputpath="" + ".svgz" + + + + + /.gif + /.pdf + + texmfstart pstopdf --convert + --inputpath="" + --outputpath="" + ".gif" + + + + + /.tif + /.pdf + + texmfstart pstopdf --convert + --inputpath="" + --outputpath="" + ".tif" + + + + + /.tiff + /.pdf + + texmfstart pstopdf --convert + --inputpath="" + --outputpath="" + ".tiff" + + + + diff --git a/tex/context/base/rlxtools.rlx b/tex/context/base/rlxtools.rlx new file mode 100644 index 000000000..b230c6d5b --- /dev/null +++ b/tex/context/base/rlxtools.rlx @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + /.eps + /.pdf + + texmfstart pstopdf --convert + + + + + + /.svg + /.pdf + + texmfstart pstopdf --convert + + + + + + + /.svgz + /.pdf + + texmfstart pstopdf --convert + + + + + + + / + / + + texmfstart pstopdf --convert --method=4 + --inputpath= + --outputpath=/ + + + + + + / + / + + texmfstart pstopdf --convert --method=4 + --inputpath= + --outputpath=/ + + + + + + /.gif + /.pdf + + texmfstart pstopdf --convert + --inputpath= + --outputpath= + .gif + + + + + /.tif + /.pdf + + texmfstart pstopdf --convert + --inputpath= + --outputpath= + .tif + + + + + /.tiff + /.pdf + + texmfstart pstopdf --convert + --inputpath= + --outputpath= + .tiff + + + + + / + / + + texmfstart pstopdf --convert --method=3 + --inputpath= + --outputpath=/ + + + + + diff --git a/tex/context/base/s-abr-01.tex b/tex/context/base/s-abr-01.tex new file mode 100644 index 000000000..a55eb95f1 --- /dev/null +++ b/tex/context/base/s-abr-01.tex @@ -0,0 +1,324 @@ +%D \module +%D [ file=s-abr-01, +%D version=1996.01.01, +%D title=\CONTEXT\ Style File, +%D subtitle=General Abbreviations 1, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\unprotect + +\setupsorting[logo][\c!style=\v!capital] + +\setupcapitals[\c!title=\v!no] + +\protect + +\logo [MKI] {MkI} +\logo [MKII] {MkII} +\logo [MKIII] {MkIII} +\logo [MKIV] {MkIV} + +%logo [FGA] {fga} +%logo [FGBBS] {fgbbs} +\logo [ACROBAT] {Acro\-bat} +\logo [AFM] {afm} +\logo [API] {api} +\logo [ALEPH] {Aleph} % {\mathematics{\aleph}} +\logo [ALGOL] {ALGOL} +\logo [AMS] {ams} +\logo [AMSLATEX] {\AmSLaTeX} +\logo [AMSTEX] {\AmSTeX} +\logo [ANSI] {ansi} +\logo [ARABTEX] {Arab\TeX} +\logo [ASCII] {ascii} +\logo [ASCIITEX] {ascii\TeX} +\logo [BACHOTEX] {Bacho\TeX} +\logo [BIBTEX] {bib\TeX} +\logo [BLUESKY] {BlueSky} +\logo [BMP] {bmp} +\logo [BSD] {bsd} +\logo [CCODE] {C} +\logo [CALCMATH] {CalcMath} +\logo [CD] {cd} +\logo [CPU] {cpu} +\logo [CDROM] {cdrom} +\logo [CID] {cid} +\logo [CJK] {cjk} +\logo [CMR] {cmr} +\logo [CMYK] {cmyk} +\logo [CODHOST] {CodHost} +\logo [CONTEXT] {\ConTeXt} +\logo [CSS] {css} +\logo [CTAN] {ctan} +\logo [CTXTOOLS] {ctxtools} +\logo [CWEB] {cweb} +\logo [DANTE] {Dante} +\logo [DISTILLER] {distiller} +\logo [DRATEX] {Dra\TeX} +\logo [DSC] {dsc} +\logo [DTD] {dtd} +\logo [DTK] {dtk} +\logo [DTP] {dtp} +\logo [DVD] {dvd} +\logo [DVI] {dvi} +\logo [DVIPDFM] {dvipdfm} +\logo [DVIPDFMX] {dvipdfmx} +\logo [DVIPOS] {dvipos} +\logo [DVIPS] {dvips} +\logo [DVIPSONE] {dvipsone} +\logo [DVISCR] {dviscr} +\logo [DVIWINDO] {dviwindo} +\logo [EC] {ec} +\logo [EIFFEL] {Eiffel} +\logo [EMACS] {emacs} +\logo [EMTEX] {em\TeX} +\logo [ENCODING] {enc} +\logo [ENCTEX] {enc\TeX} +\logo [EPS] {eps} +\logo [ETEX] {\eTeX} +\logo [EUROBACHOTEX] {EuroBacho\TeX} +\logo [EUROMATH] {EuroMath} +\logo [EUROTEX] {Euro\TeX} +\logo [EXAMPLE] {eXaMpLe} +\logo [EXAMPLED] {exampled} +\logo [EXAMPLEQ] {exampleq} +\logo [EXAMPLER] {exampler} +\logo [EXAMPLET] {examplet} +\logo [EXAMPLEX] {examplex} +\logo [EXIMPLE] {eXiMpLe} +\logo [FAQ] {faq} +\logo [FDF] {fdf} +\logo [FONTFORGE] {FontForge} +\logo [FOXET] {foXet} +\logo [FPTEX] {fp\TeX} +\logo [FREEBSD] {FreeBSD} +\logo [FTP] {ftp} +\logo [GHOSTSCRIPT]{Ghost\-script} +\logo [GHOSTVIEW] {Ghost\-view} +\logo [GIF] {gif} +\logo [GNU] {gnu} +\logo [GNUPLOT] {gnuplot} +\logo [GS] {Ghost\-Script} +\logo [GUST] {Gust} +\logo [GWTEX] {gw\TeX} +\logo [HSB] {hsb} +\logo [HTML] {html} +\logo [HTTP] {http} +\logo [HZ] {hz} +\logo [IBM] {ibm} +\logo [IMAGEMAGICK]{ImageMagick} +\logo [INITEX] {ini\TeX} +\logo [INRSTEX] {inrs\TeX} +\logo [IO] {io} +\logo [IRCNET] {IRCnet} +\logo [ISO] {iso} +\logo [JAVA] {Java} +\logo [JAVASCRIPT] {Java\-Script} +\logo [JPEG] {jpeg} +\logo [JPG] {jpg} +\logo [KPATHSEA] {kpathsea} +\logo [KPSE] {kpse} +\logo [KPSEWHICH] {kpsewhich} +\logo [MKTEXLSR] {mktexlsr} +\logo [LAMSTEX] {\LamSTeX} +\logo [LATEX] {\LaTeX} +\logo [LATEXTE] {\LaTeX2e} +\logo [LATEXTN] {\LaTeX2.09} +\logo [LINUX] {linux} +\logo [LISP] {Lisp} +\logo [LPEG] {lpeg} +\logo [LUA] {Lua} +\logo [LUAJIT] {LuaJIT} +\logo [LUATEX] {Lua\TeX} +\logo [LUATOOLS] {luatools} +\logo [MACOSX] {MacOSX} +\logo [MACROTEX] {Macro\TeX} +\logo [MAKEMPY] {MakeMPY} +\logo [MAPPING] {map} +\logo [MAPS] {Maps} +\logo [MATHML] {MathML} +\logo [METAFONT] {\MetaFont} +\logo [METAPOST] {\MetaPost} +\logo [METATEX] {Meta\TeX} +\logo [MIKTEX] {Mik\TeX} +\logo [MLTEX] {ml\TeX} +\logo [METATYPE] {MetaType1} +\logo [MODULA] {Modula} +\logo [MOV] {mov} +\logo [MPS] {mps} +\logo [MPTOPDF] {mptopdf} +\logo [MPLIB] {mplib} +\logo [MSDOS] {msdos} +\logo [MSWINDOWS] {MS~Windows} +\logo [MTXRUN] {mtxrun} +\logo [MTXTOOLS] {mtxtools} +\logo [NETPBM] {NetPBM} +\logo [NTG] {ntg} +\logo [NTS] {nts} +\logo [OFM] {ofm} +\logo [OMEGA] {Omega} +\logo [OPENMATH] {OpenMath} +\logo [OPENTYPE] {OpenType} +\logo [OPI] {opi} +\logo [OTF] {otf} +\logo [OTP] {otp} +\logo [OVF] {ovf} +\logo [PASCAL] {Pascal} +\logo [PCTEX] {pc\TeX} +\logo [PDF] {pdf} +\logo [PDFETEX] {pdfe\TeX} +\logo [PDFTEX] {pdf\TeX} +\logo [PDFTOOLS] {pdftools} +\logo [PDFTOPS] {pdftops} +\logo [PERL] {Perl} +\logo [PERLTK] {Perl/Tk} +\logo [PICTEX] {\PiCTeX} +\logo [PK] {pk} +\logo [PLAIN] {Plain} +\logo [PNG] {png} +\logo [POSIX] {posix} +\logo [POSTSCRIPT] {Post\-Script} +\logo [PPCHTEX] {\PPCHTeX} +\logo [PRAGMA] {Pragma ADE} +\logo [PRESS] {press} +\logo [PRIFIL] {prifil} +\logo [PS] {Post\-Script} +\logo [PSCHECK] {pscheck} +\logo [PSTOEDIT] {pstoedit} +\logo [PSTOPAGE] {pstopage} +\logo [PSTOPDF] {pstopdf} +\logo [PSTRICKS] {pstricks} +\logo [RAM] {ram} +\logo [READER] {Acro\-bat Reader} +\logo [RELAXNG] {Relax\kern.125emNG} +\logo [RGB] {rgb} +\logo [RLXTOOLS] {rlxtools} +\logo [RUBY] {Ruby} +\logo [SCITE] {SciTE} +\logo [SGML] {sgml} +\logo [SI] {si} +\logo [SQL] {sql} +\logo [SVG] {svg} +\logo [TABLE] {\TaBlE} +\logo [TCPIP] {tcp/ip} +\logo [TDS] {tds} % no sc te +\logo [TETEX] {te\TeX} % no sc te +\logo [TEX] {\TeX} +\logo [TEXADRES] {\TeX adress} +\logo [TEXBASE] {\TeX base} +\logo [TEXEDIT] {\TeX edit} +\logo [TEXEXEC] {\TeX exec} +\logo [TEXFONT] {\TeX font} +\logo [TEXFORM] {\TeX form} +\logo [TEXLIVE] {\TeX Live} +\logo [TEXLUA] {\TeX Lua} +\logo [TEXMF] {texmf} +\logo [TEXMFSTART] {texmfstart} +\logo [TEXNL] {tex-nl} +\logo [TEXSHOW] {\TeX show} +\logo [TEXSPELL] {\TeX spell} +\logo [TEXGYRE] {\TeX\ Gyre} +\logo [TEXSYNC] {texsync} +\logo [TEXTMATE] {TextMate} +\logo [TEXTOOLS] {\TeX tools} +\logo [TEXUTIL] {\TeX util} +\logo [TEXWORK] {\TeX work} +\logo [TEXXET] {\TeX\XeT} \def\XeT{XeT} +\logo [TFM] {tfm} +\logo [TIF] {tif} +\logo [TIFF] {tiff} +\logo [TIFFINFO] {tiffinfo} +\logo [TIFFTAGS] {tifftags} +\logo [TMFTOOLS] {tmftools} +\logo [TPIC] {tpic} +\logo [TPM] {tpm} +\logo [TRUETYPE] {TrueType} +\logo [TTF] {ttf} +\logo [TUG] {tug} +\logo [TUGBOAT] {Tug\-Boat} +\logo [TUGNEWS] {Tug\-News} +\logo [TYPEONE] {Type1} +\logo [UCS] {ucs} +\logo [UNICODE] {Uni\-code} +\logo [UNIX] {Unix} +\logo [URI] {uri} +\logo [URL] {url} +\logo [USA] {usa} +\logo [USENET] {usenet} +\logo [UTF] {utf} +\logo [UTF] {utf} +\logo [VF] {vf} +\logo [WDT] {wdt} +\logo [WEB] {web} +\logo [WEBC] {web2c} +\logo [WIKI] {Wiki} +\logo [WINDOWS] {Windows} +\logo [WINNT] {WinNT} +\logo [WINNX] {Win9x} +\logo [WWW] {www} +\logo [WYSIWYG] {wysiwyg} +\logo [XDVI] {Xdvi} +\logo [XETEX] {\XeTeX} +\logo [XFDF] {xfdf} +\logo [XHTML] {xhtml} +\logo [XINDY] {Xindy} +\logo [XML] {xml} +\logo [XPATH] {xpath} +\logo [XMLTOOLS] {xmltools} +\logo [XPDFETEX] {xpdfe\TeX} +\logo [XSL] {xsl} +\logo [XSLFO] {xsl-fo} +\logo [XSLT] {xslt} +\logo [XSLTPROC] {xsltproc} +\logo [XYPIC] {XYPIC} % wrong logo +\logo [YandY] {y\&y} +\logo [ZIP] {zip} + +\def\METAFUN {\MetaFun} + +\logo [METAFUN] {\MetaFun} + +\def\SystemSpecialA#1{$\langle\it#1\rangle$} +\def\SystemSpecialB#1{{\tttf<#1>}} + +\def\CATCODE {\SystemSpecialA{catcode}} +\def\CATCODES {\SystemSpecialA{catcodes}} +\def\DIMENSION {\SystemSpecialA{dimension}} +\def\DIMENSIONS {\SystemSpecialA{dimensions}} +\def\COUNTER {\SystemSpecialA{counter}} +\def\COUNTERS {\SystemSpecialA{counters}} +\def\HBOX {\SystemSpecialA{hbox}} +\def\HBOXES {\SystemSpecialA{hboxes}} +\def\VBOX {\SystemSpecialA{vbox}} +\def\VBOXES {\SystemSpecialA{vboxes}} +\def\BOX {\SystemSpecialA{box}} +\def\BOXES {\SystemSpecialA{boxes}} +\def\TOKENLIST {\SystemSpecialA{token list}} +\def\TOKENLISTS {\SystemSpecialA{token lists}} +\def\NEWLINE {\SystemSpecialA{newline}} +\def\SKIP {\SystemSpecialA{skip}} +\def\SKIPS {\SystemSpecialA{skips}} +\def\MUSKIP {\SystemSpecialA{muskip}} +\def\MUSKIPS {\SystemSpecialA{muskips}} +\def\MARK {\SystemSpecialA{mark}} +\def\MARKS {\SystemSpecialA{marks}} + +\def\SPACE {\SystemSpecialB{space}} +\def\EOF {\SystemSpecialB{eof}} +\def\TAB {\SystemSpecialB{tab}} +\def\NEWPAGE {\SystemSpecialB{newpage}} +\def\NEWLINE {\SystemSpecialB{newline}} + +\doifmodeelse {mkiv} { + \unexpanded\def\THANH{H\agrave n Th\ecircumflexacute\ Th\agrave nh} +} { + \unexpanded\def\THANH{H\`an Th\^e\llap{\raise 0.5ex\hbox{\'{}}} Th\`anh} +} + +\endinput diff --git a/tex/context/base/s-abr-02.tex b/tex/context/base/s-abr-02.tex new file mode 100644 index 000000000..005559ef3 --- /dev/null +++ b/tex/context/base/s-abr-02.tex @@ -0,0 +1,22 @@ +%D \module +%D [ file=s-abr-02, +%D version=1996.01.01, +%D title=\CONTEXT\ Style File, +%D subtitle=General Abbreviations 2, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\usemodule[abr-01] + +\unprotect + +\setupsorting[logo][\c!style=\v!smallcaps] + +\setupcapitals[\c!title=\v!no] + +\protect \endinput diff --git a/tex/context/base/s-abr-03.tex b/tex/context/base/s-abr-03.tex new file mode 100644 index 000000000..43068b9a5 --- /dev/null +++ b/tex/context/base/s-abr-03.tex @@ -0,0 +1,22 @@ +%D \module +%D [ file=s-abr-03, +%D version=1998.08.10, +%D title=\CONTEXT\ Style File, +%D subtitle=General Abbreviations 3, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\usemodule[abr-01] + +\unprotect + +\setupsorting[logo][\c!style=\v!WORD] + +\protect + +\endinput diff --git a/tex/context/base/s-cdr-01.tex b/tex/context/base/s-cdr-01.tex new file mode 100644 index 000000000..80103936d --- /dev/null +++ b/tex/context/base/s-cdr-01.tex @@ -0,0 +1,131 @@ +%D \module +%D [ file=s-cdr-01, +%D version=2001.2.07, % maybe earlier +%D title=\CONTEXT\ Style File, +%D subtitle=CDROM Cover, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=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. + +\def\PDFMPformoffset{20cm} + +\definepapersize + [CDcover] + [width=12.5cm, + height=12.4cm] + +\definelayout + [CDcover] + [topspace=5mm, + backspace=5mm, + header=0pt, + footer=0pt, + width=middle, + height=middle] + +\setuparranging + [2SIDE] + +\setuppapersize + [CDcover] + [A4,landscape] + +\setuplayout + [CDcover] + +\setuplayout + [location=middle] + +\setupcolors + [state=start] + +\setupbackgrounds + [leftpage] + [background=leftcover] + +\setupbackgrounds + [rightpage] + [background=rightcover] + +\setuppagenumbering + [alternative=doublesided] + +\defineoverlay[leftcover] [\useMPgraphic{leftcover}] +\defineoverlay[rightcover][\useMPgraphic{rightcover}] + +\startuseMPgraphic{leftcover} + StartPage ; + pickup pencircle scaled .5pt ; + draw + bottomboundary Page & + rightboundary Page & + topboundary Page ; + draw + bottomboundary (Page enlarged 3mm) & + rightboundary (Page enlarged 3mm) & + topboundary (Page enlarged 3mm) dashed evenly ; + StopPage ; +\stopuseMPgraphic + +\startuseMPgraphic{rightcover} + StartPage ; + pickup pencircle scaled .5pt ; + draw + topboundary Page & + leftboundary Page & + bottomboundary Page ; + draw + topboundary (Page enlarged 3mm) & + leftboundary (Page enlarged 3mm) & + bottomboundary (Page enlarged 3mm) dashed evenly ; + draw + bottomboundary Page -- + lrcorner Page shifted (-5mm,-1cm) -- + llcorner Page shifted ( 5mm,-1cm) -- cycle ; + draw + topboundary Page -- + ulcorner Page shifted ( 5mm, 1cm) -- + urcorner Page shifted (-5mm, 1cm) -- cycle ; + StopPage ; + setbounds currentpicture to Page ; +\stopuseMPgraphic + +\setupmakeup + [standard] + [doublesided=no,page=] + +\setuplayout + [topspace=5mm, + backspace=5mm, + header=0pt, + footer=0pt, + width=middle, + height=middle] + +\defineframedtext + [maintext] + [background={foreground,color}, + backgroundcolor=a-bit-white, + frame=off, + before=, + after=, + align=right, + strut=no, + height=fit, + width=\textheight] + +\doifnotmode{demo}{\endinput} + +\starttext + \startstandardmakeup + page 1 + \stopstandardmakeup + + \startstandardmakeup + page 2 + \stopstandardmakeup +\stoptext diff --git a/tex/context/base/s-chi-00.tex b/tex/context/base/s-chi-00.tex new file mode 100644 index 000000000..bec86f6d2 --- /dev/null +++ b/tex/context/base/s-chi-00.tex @@ -0,0 +1,76 @@ +%D \module +%D [ file=s-chi-00, +%D version=1999.12.21, +%D title=\CONTEXT\ Style File, +%D subtitle=Basic Chinese Style, +%D author=Hans Hagen, +%D date=\currentdate, +%D suggestions=Wang Lei, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\input font-chi.mkii % faster than \setupbodyfont[chi] + +\mainlanguage [cn] + +\unprotect + +\setupsection [\s!section-1] [\c!headconversion=\s!chinese] +\setupsection [\s!section-2] [\c!headconversion=\s!chinese] +\setupsection [\s!section-3] [\c!headconversion=\s!chinese] + +\setupsection [\s!section-2] [\v!appendix\c!conversion=] + +\setuphead [\v!chapter] [\c!distance=1.25em] +\setuphead [\v!section] [\c!distance=1.25em] +\setuphead [\v!subsection] [\c!distance=1.00em] + +\setuplist [\v!chapter] [\c!headlabel=\v!yes,\c!headconversion=\v!yes,\c!width=5em] +\setuplist [\v!section] [\c!headlabel=\v!yes,\c!headconversion=\v!yes,\c!width=5em] + +\setupmarking [\v!chapter\v!number] [\c!headlabel=\v!yes,\c!headconversion=\v!yes] +\setupmarking [\v!section\v!number] [\c!headlabel=\v!yes,\c!headconversion=\v!yes] + +\setuplabeltext [cn] [\v!subsection={\symbol[S]\kern.25em}] +\setuplabeltext [cn] [\v!subsubsection={\symbol[S]\kern.25em}] +\setuplabeltext [cn] [\v!subsubsubsection={\symbol[S]\kern.25em}] +\setuplabeltext [cn] [\v!subsubsubsubsection={\symbol[S]\kern.25em}] + +% nog taalonafhankelijk maken -> \e!tabel enz + +\definereferenceformat [intable] [\c!label=\v!table] +\definereferenceformat [infigure] [\c!label=\v!figure] +\definereferenceformat [inchapter] [\c!label=\v!chapter] +\definereferenceformat [insection] [\c!label=\v!section] + +% important + +\setuptyping[\c!tab=\v!no] + +%D This module (and font support) adapts to the \UTF\ regime, but you +%D need to enable \UTF\ first! +%D +%D \starttyping +%D \enableregime[utf] \usemodule[chi-00] +%D +%D \starttext +%D +%D 兡也包因沘氓侷柵苗孫孫財 +%D 崧淫設弼琶跑愍窟榜蒸奭稽 +%D 霄瓢館縲擻鼕孃魔釁佉沎岠 +%D 狋垚柛胅娭涘罞偟惈牻荺傒 +%D 焱菏酡廅滘絺赩塴榗箂踃嬁 +%D 澕蓴醊獧螗餟燱螬駸礑鎞瀧 +%D 鄿瀯騬醹躕鱕 +%D +%D \blank +%D +%D Wang Lei is written as: 王磊 +%D +%D \stoptext +%D \stoptyping + +\protect \endinput diff --git a/tex/context/base/s-faq-00.tex b/tex/context/base/s-faq-00.tex new file mode 100644 index 000000000..11859936c --- /dev/null +++ b/tex/context/base/s-faq-00.tex @@ -0,0 +1,93 @@ +%D \module +%D [ file=s-faq-00, +%D version=1997.21.08, +%D title=\CONTEXT\ Style File, +%D subtitle=FAQ Common Macros, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\usemodule[abr-01] + +\defineblock[question] +\defineblock[answer] + +\def\ScreenFAQ {fs-\TagOfFAQ-\LanguageOfFAQ} +\def\PaperFAQ {fp-\TagOfFAQ-\LanguageOfFAQ} +\def\FileNameOfFAQ {fa-\TagOfFAQ-\LanguageOfFAQ} + +\language + [\HyphenationOfFAQ] + +\setupwhitespace + [big] + +\setupbodyfont + [ams] + +\setuptolerance + [tolerant] + +\setupregister + [index] + [indicator=no] + +\setupframedtexts + [width=\hsize] + +\setupblock + [question] + [before=\startframedtext, + after=\stopframedtext] + +\setupblock + [answer] + [after=\EndAnswer] + +\def\EndAnswer {} + +\def\AuthorOfFAQ {} +\def\IndexOfFAQ {} + +\def\FrequentlyAskedQuestion#1#2% + {\page + \doglobal\increment\CurrentNOfFAQ + \pagereference[faq:\CurrentNOfFAQ] + \gdef\IndexOfFAQ{#1} + \gdef\AuthorOfFAQ{#2}} + +\newcounter\CurrentNOfFAQ + +\setuplabeltext [nl] [FAQ=Vaak gestelde vragen] +\setuplabeltext [du] [FAQ=Oft gestellte Fragen] +\setuplabeltext [en] [FAQ=Frequently Asked Questions] + +\setuplabeltext [nl] [about=over] +\setuplabeltext [du] [about=zu] +\setuplabeltext [en] [about=about] + +\setuplabeltext [nl] [version=Versie] +\setuplabeltext [du] [version=Version] +\setuplabeltext [en] [version=Version] + +\setuplabeltext [nl] [goback=terug] +\setuplabeltext [du] [goback=zur\"uck] +\setuplabeltext [en] [goback=go back] + +\setuplabeltext [nl] [paper=papier] +\setuplabeltext [du] [paper=Papier] +\setuplabeltext [en] [paper=paper] + +\setuplabeltext [nl] [faqs=FAQ's] +\setuplabeltext [du] [faqs=FAQs] +\setuplabeltext [en] [faqs=FAQ's] + +\setuplabeltext [nl] [index=index] +\setuplabeltext [du] [index=Index] +\setuplabeltext [en] [index=index] + +\endinput diff --git a/tex/context/base/s-faq-01.tex b/tex/context/base/s-faq-01.tex new file mode 100644 index 000000000..8c116e0f7 --- /dev/null +++ b/tex/context/base/s-faq-01.tex @@ -0,0 +1,215 @@ +%D \module +%D [ file=s-faq-01, +%D version=1997.21.08, +%D title=\CONTEXT\ Style File, +%D subtitle=FAQ Interactive Version, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\usemodule[faq-00] + +\setuppapersize + [S6][S6] + +\setuplayout + [topspace=.5cm, + backspace=.5cm, + margin=0pt, + height=fit, + header=0pt, + width=fit, + footer=0pt, + bottomdistance=12pt, + bottom=18pt] + +\setupinteractionscreen + [width=fit, + height=fit, + option=max] + +\setupinteraction + [state=start, + page=yes, + color=darkred, + contrastcolor=black, + menu=on] + +\setupcolors + [state=start] + +\setupbackgrounds + [state=repeat] + +\setupbackgrounds + [page] + [offset=3pt] + +\setupbackgrounds + [text] + [text] + [background={screen,go-on}] + +\setupbackgrounds + [bottom] + [text] + [background=screen] + +\setupframedtexts + [background=MyFrame, + backgroundcolor=white, + framecolor=darkred, + frame=overlay] + +\defineoverlay[go-on][\overlaybutton{forward}] + +\useexternaldocument + [paperfaq] + [\PaperFAQ] + [] + +\setupregister + [index] + [coupling=yes, + unknownreference=none, + interaction=text] + +\coupleregister + [index] + +\defineinteractionmenu [bottom 1] [bottom] [state=stop] +\defineinteractionmenu [bottom 2] [bottom] [state=stop] + +\setupinteractionmenu + [bottom, bottom 1, bottom 2] + [background=MyFrame, + backgroundcolor=white, + color=black, + contrastcolor=black, + frame=overlay, + framecolor=darkred, + dummy=yes, + middle=\hskip1em, + height=\bottomheight, + distance=overlay] + +\setupinteractionmenu + [bottom 1] + [{\hfill}, + {\labeltext{paper}[paperfaq::]}, + {\labeltext{goback}[PreviousJump]}, + {\labeltext{faqs}[faqs]}, + {\labeltext{index}[index]}, + {\gobackwardcharacter[previouspage]}, + {\goforwardcharacter[nextpage]}] + +\setupinteractionmenu + [bottom 2] + [{\CurrentIndexOfFAQ}, + {\hfill}, + {\labeltext{paper}[paperfaq::faq:\CurrentNOfFAQ]}, + {\labeltext{goback}[PreviousJump]}, + {\labeltext{faqs}[faqs]}, + {\labeltext{index}[index]}, + {\gobackwardcharacter[previouspage]}, + {\goforwardcharacter[nextpage]}] + +\def\CurrentIndexOfFAQ% + {\bgroup + \setupinteraction[color=]% + \menubox[bottom]% + {\hskip-.5em\def\index{\hskip.5em\coupledindex}\IndexOfFAQ}% + \egroup} + +\setupinteractionmenu + [bottom 1] + [state=start] + +\def\EndAnswer + {\vfill + \bgroup + \tfx\setstrut + \framed + [frame=overlay, + framecolor=darkred, + background=MyFrame, + backgroundcolor=white] + {\AuthorOfFAQ} + \egroup} + +\def\TitlePage + {\startstandardmakeup + \blank[3*big] + \midaligned{\bfd \labeltext{FAQ}} + \blank[3*big] + \midaligned{\bfd \labeltext{about} \NameOfFAQ} + \blank[3*big] + \midaligned{\bfb \labeltext{version}: \currentdate} + \blank[3*big] + \midaligned{\tta \ListOfFAQ} + \vfill + \midaligned{\tta pragma@wxs.nl} + \blank[3*big] + \stopstandardmakeup} + +\def\StartReadingFAQ + {\setupinteractionmenu[bottom 1][state=stop] + \setupinteractionmenu[bottom 2][state=start] + \page} + +\def\StopReadingFAQ + {\page + \setupinteractionmenu[bottom 2][state=stop] + \setupinteractionmenu[bottom 1][state=start]} + +\def\FileWithFAQs + {\StartReadingFAQ + \input \FileNameOfFAQ \relax + \StopReadingFAQ} + +\def\IndexPage + {\page + \def\CurrentIndexOfFAQ{} + \def\NameOfFAQ{} + \pagereference[index] + \placeregister[index] + \page} + +\def\BeginFAQ + {\doglobal\increment\CurrentNOfFAQ + \setbox0=\vbox\bgroup + \setupframedtexts[before=,after=,linecorrection=off] + \startframedtext} + +\def\EndFAQ + {\stopframedtext + \egroup + \button + [color=,contrastcolor=,frame=overlay,offset=overlay] + {\copy0} + [faq:\CurrentNOfFAQ] + \vskip6pt} + +\def\AllFAQs + {\page + \def\CurrentIndexOfFAQ{} + \def\NameOfFAQ{} + \newcounter\CurrentNOfFAQ + \setupblock[question][before=\BeginFAQ,after=\EndFAQ] + \pagereference[faqs] + \useblocks[question]} + +\startuniqueMPgraphic{Frame} + path p ; p := unitsquare xscaled \overlaywidth yscaled \overlayheight ; + pickup pencircle scaled 2pt ; + fill p withcolor \MPcolor{\overlaycolor} ; + draw p withcolor \MPcolor{\overlaylinecolor} ; +\stopuniqueMPgraphic + +\defineoverlay[MyFrame][\uniqueMPgraphic{Frame}] + +\endinput diff --git a/tex/context/base/s-faq-02.tex b/tex/context/base/s-faq-02.tex new file mode 100644 index 000000000..02287bde4 --- /dev/null +++ b/tex/context/base/s-faq-02.tex @@ -0,0 +1,63 @@ +%D \module +%D [ file=s-faq-02, +%D version=1997.21.08, +%D title=\CONTEXT\ Style File, +%D subtitle=FAQ Paper Version, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\usemodule[faq-00] + +\setuplayout + [header=0pt] + +\setuppagenumbering + [location=] + +\setupfootertexts + [\labeltext{FAQ}: \NameOfFAQ\IndexOfFAQ][pagenumber] + +\def\EndAnswer% + {\blank[2*big] + \page[no] + (\AuthorOfFAQ)} + +\def\TitlePage% + {\startstandardmakeup + \midaligned{\bfd \labeltext{FAQ}} + \blank[3*big] + \midaligned{\bfd \labeltext{about} \NameOfFAQ} + \blank[3*big] + \midaligned{\bfb \labeltext{version}: \currentdate} + \blank[3*big] + \midaligned{\tta \ListOfFAQ} + \vfill + \midaligned{\tta pragma@wxs.nl} + \blank[3*big] + \stopstandardmakeup} + +\def\StartReadingFAQ + {\page} + +\def\StopReadingFAQ + {\page} + +\def\FileWithFAQs + {\StartReadingFAQ + \input \FileNameOfFAQ \relax + \StopReadingFAQ} + +\def\IndexPage + {\page + \setupfootertexts[\labeltext{index}][] + \placeregister[index]} + +\def\AllFAQs + {} + +\endinput diff --git a/tex/context/base/s-faq-03.tex b/tex/context/base/s-faq-03.tex new file mode 100644 index 000000000..4f556f713 --- /dev/null +++ b/tex/context/base/s-faq-03.tex @@ -0,0 +1,70 @@ +%D \module +%D [ file=s-faq-03, +%D version=1997.21.08, +%D title=\CONTEXT\ Style File, +%D subtitle=FAQ General Framework, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\def\StartFAQ[#1]% + {\getrawparameters[FAQ][name=,label=,language=,hyphenation=,url=,#1] + \let\NameOfFAQ \FAQname + \let\TagOfFAQ \FAQlabel + \let\LanguageOfFAQ \FAQlanguage + \let\HyphenationOfFAQ \FAQhyphenation + \let\ListOfFAQ \FAQurl + \doifmodeelse{screen} + {\usemodule[faq-01]} + {\usemodule[faq-02]} + \starttext + \TitlePage + \StartReadingFAQ} + +\def\StopFAQ + {\StopReadingFAQ + \IndexPage + \AllFAQs + \stoptext} + +\def\ProcessFAQ[#1]% + {\StartFAQ[#1] + \input \FileNameOfFAQ \relax + \StopFAQ} + +% for old times sake: + +\def\PDFscreenFAQ \name #1 \tag #2 \language #3 \hyphenation #4 \list #5 + {\def\NameOfFAQ {#1} + \def\TagOfFAQ {#2} + \def\LanguageOfFAQ {#3} + \def\HyphenationOfFAQ {#4} + \def\ListOfFAQ {#5} + \usemodule[faq-01] + \starttext + \TitlePage + \FileWithFAQs + \IndexPage + \AllFAQs + \stoptext} + +\def\PDFpaperFAQ \name #1 \tag #2 \language #3 \hyphenation #4 \list #5 + {\def\NameOfFAQ {#1} + \def\TagOfFAQ {#2} + \def\LanguageOfFAQ {#3} + \def\HyphenationOfFAQ {#4} + \def\ListOfFAQ {#5} + \usemodule[faq-02] + \starttext + \TitlePage + \FileWithFAQs + \IndexPage + \stoptext} + +\let\DVIpaperFAQ\PDFscreenFAQ + +\endinput diff --git a/tex/context/base/s-fnt-01.tex b/tex/context/base/s-fnt-01.tex new file mode 100644 index 000000000..69c8efab9 --- /dev/null +++ b/tex/context/base/s-fnt-01.tex @@ -0,0 +1,61 @@ +%D \module +%D [ file=s-fnt-01, +%D version=2001.08.22, +%D title=\CONTEXT\ Style File, +%D subtitle=Font Environment 1, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This file is used by the \type {texfont.pl} installation +%D script. It is of no use for \MKIV. + +%D Modes: compact + +\dontcomplain + +\setupbodyfont + [10pt] + +\setuplayout + [backspace=30pt, + topspace=30pt, + footer=0pt, + header=36pt, + width=middle, + height=middle] + +\setupcolors + [state=start] + +\def\ShowFont + {\dotripleempty\doShowFont} + +\def\doShowFont[#1][#2][#3]% + {\doifsomething{#1} + {\bgroup + \ifthirdargument + \definefontsynonym[WhateverName][#2][encoding=#3] + \definefont[WhateverFont][WhateverName] + \setupheadertexts[\tttf#2\quad#1\quad#3] + \WhateverFont + \setupinterlinespace + \showfont[WhateverName] + \showligatures[WhateverName] + \doifnotmode{compact}{\showaccents\showcharacters} + \else + \definefontsynonym[WhateverName][#2] + \definefont[WhateverFont][WhateverName] + \setupheadertexts[\tttf#2\quad#1\quad(special font)] + \WhateverFont + \setupinterlinespace + \showfont[WhateverName] + \fi + \page + \egroup}} + +\endinput diff --git a/tex/context/base/s-fnt-02.tex b/tex/context/base/s-fnt-02.tex new file mode 100644 index 000000000..69f976102 --- /dev/null +++ b/tex/context/base/s-fnt-02.tex @@ -0,0 +1,133 @@ +% output=pdftex modes=demo + +% nice example: +% +% \usemodule[s-fnt-02] +% +% \usetypescriptfile[type-ghz.tex] +% +% \usetypescript [sans] [optima,optima-nova] [texnansi] +% +% \setvariables +% [glyphs] +% [name-1=OptimaLT, +% name-2=OptimaNovaLT-Regular] +% +% \starttext +% +% \setups[show-glyphs] +% +% \stoptext +% +% see end, for other example (or run texexec s-fnt-02 --mode=demo) + +\setvariables + [glyphs] + [frame=on, + name-1=cmr10, + name-2=cmtt10, + map-1=, + map-2=] + +\setuppapersize[S4][S4] + +\setupcolors[state=start] + +\setuplayout[page] + +\definecolor[Gray] [s=.2] +\definecolor[ColorNone][s=1,t=.5,a=1] +\definecolor[ColorOne] [r=1,t=.5,a=1] +\definecolor[ColorTwo] [g=1,t=.5,a=1] +\definecolor[BackOne] [b=1,t=.5,a=1] +\definecolor[BackTwo] [r=1,g=1,t=.5,a=1] + +\setupbackgrounds + [page] + [background=color, + backgroundcolor=Gray] + +\startsetups[show-glyphs] + + \doifnothing{\getvariable{glyphs}{name-1}}{\endinput} + \doifnothing{\getvariable{glyphs}{name-2}}{\endinput} + + \doifsomething{\getvariable{glyphs}{map-1}}{\loadmapfile[\getvariable{glyphs}{map-1}]} + \doifsomething{\getvariable{glyphs}{map-2}}{\loadmapfile[\getvariable{glyphs}{map-2}]} + + \definefont[FontOne][\getvariable{glyphs}{name-1} at 280pt] + \definefont[FontTwo][\getvariable{glyphs}{name-2} at 280pt] + +% \dostepwiserecurse{0}{255}{1} +% {\doiffontcharelse{\getvariable{glyphs}{name-1}}{\recurselevel} +% {\doiffontcharelse{\getvariable{glyphs}{name-2}}{\recurselevel} +% {\startstandardmakeup +% \doifelse{\getvariable{glyphs}{frame}}{on} % too many box calculations when off, but who cares +% {\boxrulewidth=2pt} +% {\boxrulewidth=0pt} +% \setbox 0=\hbox{\white\ruledhbox{\FontOne \char\recurselevel}} +% \setbox 2=\hbox{\white\ruledhbox{\FontTwo \char\recurselevel}} +% \setbox 4=\hbox{\FontOne \ColorOne \char\recurselevel} +% \setbox 6=\hbox{\FontTwo \ColorTwo \char\recurselevel} +% \setbox 8=\hbox{\BackOne \ruledhbox{\FontOne \phantom{\char\recurselevel}}} +% \setbox10=\hbox{\BackTwo \ruledhbox{\FontTwo \phantom{\char\recurselevel}}} +% \vfill +% \hbox{\dostepwiserecurse{0}{10}{2}{\hbox to \hsize{\hss\box\recurselevel\hss}\hskip-\hsize}} +% \vfill +% \tttf +% \setstrut +% \hbox to \hsize{\strut\hss +% {\ColorOne \getvariable{glyphs}{name-1}}\quad +% {\ColorTwo \getvariable{glyphs}{name-2}}\quad +% {\ColorNone char \recurselevel }\hss} +% \stopstandardmakeup} +% {}} +% {}} + + \dostepwiserecurse{0}{255}{1} + {\donefalse + \doiffontcharelse{\getvariable{glyphs}{name-1}}{\recurselevel}{\donetrue}{}% + \doiffontcharelse{\getvariable{glyphs}{name-2}}{\recurselevel}{\donetrue}{}% + \ifdone + \startstandardmakeup + \doifelse{\getvariable{glyphs}{frame}}{on} % too many box calculations when off, but who cares + {\boxrulewidth=2pt} + {\boxrulewidth=0pt} + \setbox 0=\hbox{\white\ruledhbox{\FontOne \char\recurselevel}} + \setbox 2=\hbox{\white\ruledhbox{\FontTwo \char\recurselevel}} + \setbox 4=\hbox{\FontOne \ColorOne \char\recurselevel} + \setbox 6=\hbox{\FontTwo \ColorTwo \char\recurselevel} + \setbox 8=\hbox{\BackOne \ruledhbox{\FontOne \phantom{\char\recurselevel}}} + \setbox10=\hbox{\BackTwo \ruledhbox{\FontTwo \phantom{\char\recurselevel}}} + \vfill + \hbox{\dostepwiserecurse{0}{10}{2}{\hbox to \hsize{\hss\box\recurselevel\hss}\hskip-\hsize}} + \vfill + \tttf + \setstrut + \hbox to \hsize{\strut\hss + {\ColorOne \getvariable{glyphs}{name-1}}\quad + {\ColorTwo \getvariable{glyphs}{name-2}}\quad + {\ColorNone char \recurselevel }\hss} + \stopstandardmakeup + \fi} + +\stopsetups + +\doifnotmode{demo}{\endinput} + +\starttext + + \setupencoding[default=ec] + + \loadmapline [=][aer10 = 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 +-- for unicode, _ in table.sortedpairs(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 + \page + \font\TestFont=#1 at #2 + \setuplayout[style=\TestFont] + \setupheadertexts[] + \setupfootertexts[#1 -- \pagenumber] + \setupfootertexts[pagenumber] + \setuplayout[width=middle,height=middle,topspace=1cm,backspace=1cm] + \TestFont + \nonknuthmode + \startcolumns[n=#3] + \TestFont + \ctxlua { fonts.show_all() } + \stopcolumns + \page + \egroup} + +\def\ShowAllGlyphs#1#2#3% + {\bgroup + \page + \font\TestFontA=#1 at 12pt + \font\TestFontB=#1 at #2 + \setuplayout[style=\TestFontA] + \setupheadertexts[] + \setupfootertexts[#1 -- \pagenumber] + \setuplayout[width=middle,height=middle,topspace=1cm,backspace=1cm,header=1cm,footer=2cm] + \TestFontB \setupinterlinespace[line=1.2\dimexpr#2\relax] \raggedcenter + \nonknuthmode + \startcolumns[n=#3] + \TestFontB + \ctxlua { fonts.show_glyphs() } + \stopcolumns + \page + \egroup} + +\endinput + +\starttext + +% \ShowCompleteFont{name:dejavusansmono}{10pt}{2} +% \ShowCompleteFont{name:dejavuserif}{10pt}{2} +% \ShowCompleteFont{name:officinasansbookitcregular}{10pt}{2} +% \ShowCompleteFont{name:officinaserifbookitcregular}{10pt}{2} +% \ShowCompleteFont{name:serpentineserifeflight}{10pt}{2} +% \ShowCompleteFont{name:lmtypewriter10-regular}{10pt}{2} +% \ShowCompleteFont{lt55485}{10pt}{2} +% \ShowCompleteFont{lmr10}{10pt}{2} +% \ShowCompleteFont{lbr}{10pt}{2} +% \ShowCompleteFont{name:Cambria}{10pt}{2} +% \ShowCompleteFont{name:CambriaMath}{10pt}{2} +% \ShowCompleteFont{name:texgyrepagella-regular}{10pt}{2} +% \ShowCompleteFont{name:texgyrechorus-mediumitalic}{10pt}{2} +% \ShowAllGlyphs {name:texgyrepagella-regular} {48pt}{2} +% \ShowAllGlyphs {name:texgyrechorus-mediumitalic}{48pt}{2} +% \ShowCompleteFont{name:euler10-regular}{10pt}{2} + +% \ShowCompleteFont{name:palatinosansinformalcombold}{20pt}{2} +% \ShowCompleteFont{name:palatinonovaregular}{11pt}{2} +% \ShowCompleteFont{name:optimanovaltregular}{11pt}{2} + +\stoptext 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..a8b398716 --- /dev/null +++ b/tex/context/base/s-fnt-25.tex @@ -0,0 +1,194 @@ +%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\enableshowmathfontvirtual + {\ctxlua{fonts.tfm.auto_cleanup=false}} + +\def\showmathfontcharacters + {\dodoubleempty\doshowmathfontcharacters} + +\def\doshowmathfontcharacters[#1][#2]% + {\begingroup + \dontcomplain + \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: \char#2\enspace\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\mathfontlistentryresource#1% + {virtual: #1\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 + local virtual, names = tfmdata.type == "virtual", { } + if virtual then + for k, v in ipairs(tfmdata.fonts) do + local name = fonts.ids[v.id].name + names[k] = (name and file.basename(name)) or v.id + end + end + local round = math.round +-- print(table.serialize(names)) + 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}",round(char.width or 0),round(char.height or 0),round(char.depth or 0),round(char.italic or 0)) + if virtual then + local commands = char.commands + if commands then + local t = { } + for i=1,#commands do + local ci = commands[i] + if ci[1] == "slot" then + local fnt, idx = ci[2], ci[3] + t[#t+1] = string.format("%s/%0X",names[fnt] or fnt,idx) + end + end + if #t > 0 then + report("\\mathfontlistentryresource{%s}",table.concat(t,", ")) + end + end + end + 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{U+%05X}{%s}",v.glyph,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-26.tex b/tex/context/base/s-fnt-26.tex new file mode 100644 index 000000000..026abf29b --- /dev/null +++ b/tex/context/base/s-fnt-26.tex @@ -0,0 +1,73 @@ +%D \module +%D [ file=s-fnt-26, +%D version=2009.10.26, +%D title=\CONTEXT\ Style File, +%D subtitle=Goodies Tables, +%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. + +\startluacode + + function document.show_goodies_stylistics(name) + local goodies = fonts.goodies.get(name) + local stylistics = goodies and goodies.stylistics + if stylistics then + local col, row, type = context.NC, context.NR, context.type + context.starttabulate { "|l|pl|" } + col() context("feature") col() context("meaning") col() row() + for feature, meaning in table.sortedpairs(stylistics) do + col() type(feature) col() type(meaning) col() row() + end + context.stoptabulate() + end + end + + function document.show_goodies_featuresets(name) + local goodies = fonts.goodies.get(name) + local featuresets = goodies and goodies.featuresets + if featuresets then + local col, row, type = context.NC, context.NR, context.type + context.starttabulate { "|l|pl|" } + col() context("featureset") col() context("definitions") col() row() + for featureset, definitions in table.sortedpairs(featuresets) do + col() type(featureset) col() + for k, v in table.sortedpairs(definitions) do + type(string.format("%s=%s",k,tostring(v))) + context.quad() + end + col() row() + end + context.stoptabulate() + end + end + + function document.show_goodies_colorschemes(name) + local goodies = fonts.goodies.get(name) + local colorschemes = goodies and goodies.colorschemes + if colorschemes then + local col, row, type = context.NC, context.NR, context.type + context.starttabulate { "|l|pl|" } + col() context("colorscheme") col() context("numbers") col() row() + for colorscheme, numbers in table.sortedpairs(colorschemes) do + col() type(colorscheme) col() + for i=1,#numbers do + type(i) + context.quad() + end + col() row() + end + context.stoptabulate() + end + +\stopluacode + +\def\showgoodiesstylistics #1{\ctxlua{document.show_goodies_stylistics ("#1")}} +\def\showgoodiesfeaturesets #1{\ctxlua{document.show_goodies_featuresets ("#1")}} +\def\showgoodiescolorschemes#1{\ctxlua{document.show_goodies_colorschemes("#1")}} + +\endinput 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-grk-00.tex b/tex/context/base/s-grk-00.tex new file mode 100644 index 000000000..ec5ddf1f7 --- /dev/null +++ b/tex/context/base/s-grk-00.tex @@ -0,0 +1,77 @@ +%D \module +%D [ file=s-grk-00, +%D version=2004.08.23, +%D title=\CONTEXT\ Style File, +%D subtitle=CB Greek Support, +%D author=Hans Hagen, +%D date=\currentdate, +%D suggestions=Giuseppe Bilotta, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\usetypescriptfile[type-cbg] + +\usetypescript [all] [cbgreek-medium] + +\startsetups [cbgreek] + + \catcode`~=\other + \catcode`|=\other + + \language[greek] + \switchtobodyfont[cbgreek] + +\stopsetups + +\definestartstop + [greek] + [commands=\directsetup{cbgreek}] + +\doifnotmode{demo}{\endinput} + +% The following sample file was submitted to the \CONTEXT\ +% mailing list by Giuseppe Bilotta, along with the right +% typescripts. + +% already loaded: \usemodule[greek] + +\mainlanguage[english] + +\starttext + +We can easily use plain English for normal text, and then switch +to greek when we want; as a first try we type the lower and +upper case 26 letters of the latin alphabet and see how they come +out in greek: + +\startgreek +a b c d e f g h i j k l m n o p q r s t u v w x y z \par +A B C D E F G H I J K L M N O P Q R S T U V W X Y Z +\stopgreek + +As it can be observed, some uppercase letters have strange +outcomes; also, j gives \greek{j} and c gives the +end-of-word sigma \greek{c}; interestingly, s gives either the +normal sigma or the end-of-word one, depending on whether it's at +the end of the word or not: \greek{satrapws}. + +Of course we can use the various diacritical signs: accents +(\greek{`a, 'a, ~a}), breathings (\greek{w, a"}) and +subscribed iotas (\greek{a|, h|, w|}) (these last are pretty ugly in my +opinion); observe how they automatically get the correct position +with uppercase letters: (\greek{`A, 'A, ~A, A, A|}). + +Can the thing be used for serious work? + +\startgreek +>>'Andra moi >'ennepe, Mo~usa, pol'utropon, >'os m'ala poll`a\hfill\break +pl'agqjh, >epe`i Tro'ihs 'eperse;\hfill\break +poll~wn d" >anjr'wpwn >'iden >'astea ka`i n'oon >'egnw,\hfill\break +poll`a d" <'o g" >en p'ontw| p'ajen >'algea <`on kat`a jum'on,\hfill\break +>>arn'umenos <'hn te yuq`hn ka`i n'oston max then max = v[i] end end + end + return max, what, function(n) return n/max end + end + + function document.context_state_1(what) + local max, what, norm = prepare(what) + texsprint(ctxcatcodes,"\\starttabulate[|Tc|T|T|T|T|]") + texsprint(ctxcatcodes,"\\NC category\\NC") + for i, t in ipairs(types) do + local n, m = 0, 0 + for k, v in pairs(list) do + local nn, mm = what[k][i], what[k][i+4] + n = n + nn + m = m + (mm or nn) + end + texsprint(ctxcatcodes,format("\\Top{%s}{%s}{%s}{%s}\\NC",t,norm(max),n,m)) + end + texsprint(ctxcatcodes,"\\NC\\NR\\HL") + for k, v in table.sortedpairs(what) do + local c = (what == size and comp[k]) or nope + local cat = format("%s~%s~~%s",(used.mkii[k] and "ii") or "~~",(used.mkiv[k] and "iv") or "~~",k) + texsprint(ctxcatcodes,"\\NC",cat,"\\NC") + for i, t in ipairs(types) do + texsprint(ctxcatcodes,format("\\Bar{%s}{%s}{%s}{%s}\\NC",t,v[i],c[i],norm(v[i]))) + end + texsprint(ctxcatcodes,"\\NR") + end + texsprint(ctxcatcodes,"\\stoptabulate") + end + + function document.context_state_2(what) + local max, what, norm = prepare(what) + for k, v in table.sortedpairs(what) do + local c = (what == size and comp[k]) or nope + texsprint(ctxcatcodes,format("\\StartUp{%s}",k)) + for i, t in ipairs(types) do + texsprint(ctxcatcodes,format("\\Up{%s}{%s}",t,norm(v[i]))) + end + texsprint(ctxcatcodes,"\\StopUp") + end + end + +\stopluacode + +\definecolor[bar:tex] [middlegreen] +\definecolor[bar:mkii][middleblue] +\definecolor[bar:mkiv][middlered] +\definecolor[bar:lua] [middlegray] + +\def\Top#1#2#3#4% + {\hbox to 5em{\hss#3}% + \enspace + \hbox to #2\dimexpr 20em\relax{#1\ifnum#3=#4\else~#4\rlap{~+}\fi\hss}} + +\def\Bar#1#2#3#4% + {\ifcase#2\else + \hbox to 5em{\hss\ifcase#3\else\llap{-~}\fi#2}% + \enspace + \blackrule[color=bar:#1,width=#4\dimexpr 20em\relax,height=.8\strutht]% + \fi} + +\newcount\UpCounter + +\def\StartUp#1% + {\dontleavehmode\framed[frame=off,align={middle,low},height=18em]\bgroup + \def\StopUp + {\par\nointerlineskip\blackrule[height=1pt,width=4em,depth=0pt,color=darkgray]% + \par\tttf\strut#1\par + \egroup + \ifnum\UpCounter=17 \par \UpCounter\zerocount\else \kern1em \advance\UpCounter\plusone \fi}} + +\def\Up#1#2% + {\scratchdimen#2\dimexpr 16em\relax + \ifdim\scratchdimen=\zeropoint + \kern1em + \else + \ifdim\scratchdimen<\onepoint \scratchdimen\onepoint \fi + \blackrule[color=bar:#1,height=\scratchdimen,width=1em]% + \fi} + +\def\Show#1#2#3% + {\startTEXpage[offset=1em,width=fit] + \hbox{\tttf\strut\currentdate~-~#1} + \ctxlua{document.context_state_\number#2("#3")} + \stopTEXpage} + +% \doifnotmode{demo}{\endinput} + +\starttext + \Show + {The number of files used in ConTeXt (modules and styles are excluded).} + {1}{number} + \Show + {The size of (core) files used in ConTeXt (- indicates exclusion of large data files; + indicates inclusion of large data files; comment and spaces removed.)} + {1}{size} + \Show + {The relative number of files used in ConTeXt (tex, mkii, mkiv, lua).} + {2}{number} + \Show + {The relative size of files used in ConTeXt (tex, mkii, mkiv, lua).} + {2}{size} +\stoptext diff --git a/tex/context/base/s-inf-02.tex b/tex/context/base/s-inf-02.tex new file mode 100644 index 000000000..77a3f650c --- /dev/null +++ b/tex/context/base/s-inf-02.tex @@ -0,0 +1,27 @@ +%D \module +%D [ file=s-inf-02, +%D version=2009.11.25, +%D title=\CONTEXT\ Style File, +%D subtitle=Information 2 (filenames), +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\starttext + +\starttabulate [|T|T|] + \NC \type{\jobname} \NC \jobname \NC \NR + \NC \type{\jobfilename} \NC \jobfilename \NC \NR + \NC \type{\jobfilesuffix} \NC \jobfilesuffix \NC \NR + \NC \type{\inputfilename} \NC \inputfilename \NC \NR + \NC \type{\inputfilebarename} \NC \inputfilebarename \NC \NR + \NC \type{\inputfilesuffix} \NC \inputfilesuffix \NC \NR + \NC \type{\outputfilename} \NC \outputfilename \NC \NR + \NC \type{\operatingsystem} \NC \operatingsystem \NC \NR +\stoptabulate + +\stoptext diff --git a/tex/context/base/s-jap-00.tex b/tex/context/base/s-jap-00.tex new file mode 100644 index 000000000..28cb6c241 --- /dev/null +++ b/tex/context/base/s-jap-00.tex @@ -0,0 +1,23 @@ +%D \module +%D [ file=s-jap-00, +%D version=2006.01.19, +%D title=\CONTEXT\ Style File, +%D subtitle=Basic Japanese Style, +%D author=Hans Hagen, +%D date=\currentdate, +%D suggestions=Richard Gabriel, +%D copyright=\PRAGMA] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\input font-jap.tex % faster than \setupbodyfont[jap] + +\mainlanguage [ja] + +\unprotect + +\setuptyping[\c!tab=\v!no] + +\protect \endinput diff --git a/tex/context/base/s-mag-01.tex b/tex/context/base/s-mag-01.tex new file mode 100644 index 000000000..da4e027f4 --- /dev/null +++ b/tex/context/base/s-mag-01.tex @@ -0,0 +1,406 @@ +%D \module +%D [ file=s-mag-01, +%D version=2002.12.14, +%D title=\CONTEXT\ Style File, +%D subtitle=\CONTEXT\ Magazine Base Style, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% This style is used for producing explanationary documents. +% Don't misuse it for other purposes, since it may confuse +% users. Don't change the title either, since it provides a +% way to categorize documents. Numbers are disabled in +% instances produced outside PRAGMA ADE. +% +% The layout setup is such that one has several text areas +% available: headers and footers, margins and edges as well +% as the main text area. The surrounding (gray) makes the +% main page stand out and is suitable for viewing in spread +% mode. +% +% Since this style is under constant construction, messing +% around with settings will produce unwanted side effects. +% So, if some feature or settings is needed, let me know. + +% todo: mp frames + +\setvariables[magazine][number=0] +\setvariables[magazine][author=] +\setvariables[magazine][title={Zero Issue}] +\setvariables[magazine][date=\currentdate] + +% These are reserved for PRAGMA-ADE, don't use them yourself! + +% \setvariables[magazine][main=Tricky] +% \setvariables[magazine][main=Update] +% \setvariables[magazine][main=HOWTO] + +% \setvariables[magazine][main=This Way] % preludes to a/the manual +% \setvariables[magazine][main=A Better Way] % dirty versus clean +% \setvariables[magazine][main=No Way] % how users should not do it +% \setvariables[magazine][main=Your Way] % how users do it +% \setvariables[magazine][main=My Way] % how users do it +% \setvariables[magazine][main=Our Way] % how we do things at pragma +% \setvariables[magazine][main=Their Way] % how to do latex things in context + +\setvariables[magazine][main=My Way] + +\startmode[atpragma] + \setvariables[magazine][main=This Way] +\stopmode + +\definepapersize + [magazine] + [width=\dimexpr\paperwidth-.1\paperwidth\relax, + height=\dimexpr\paperheight-.1\paperheight\relax] + +\setuppapersize + [magazine] + [A4] + +\setupinteractionscreen + [option=doublesided] + +\definecolor[OuterColor][s=.3] +\definecolor[InnerColor][s=.8] +\definecolor[MainColor] [s=.2] +\definecolor[TitleColor][s=.7] + +\definecolor[MyRed] [r=.6] +\definecolor[MyGreen][g=.6] +\definecolor[MyBlue] [b=.6] + +\startuseMPgraphic{paper} + sh := define_circular_shade(a,a,0,bbheight(OverlayBox), + \MPcolor{InnerColor},\MPcolor{OuterColor}) ; + fill OverlayBox withshade sh ; +\stopuseMPgraphic + +\startreusableMPgraphic{middlepaper} + pair a ; a := center OverlayBox ; + \includeMPgraphic{paper} +\stopreusableMPgraphic + +\startreusableMPgraphic{rightpaper} + pair a ; a := .5[urcorner OverlayBox,lrcorner OverlayBox] ; + \includeMPgraphic{paper} +\stopreusableMPgraphic + +\startreusableMPgraphic{leftpaper} + pair a ; a := .5[ulcorner OverlayBox,llcorner OverlayBox] ; + \includeMPgraphic{paper} +\stopreusableMPgraphic + +\startreusableMPgraphic{page} + fill OverlayBox withcolor white ; +\stopreusableMPgraphic + +\startusableMPgraphic{text} + StartPage ; + for i = Header,Text,Footer : + for j = LeftEdge, LeftMargin, Text, RightMargin, RightEdge : + draw Field[i][j] withpen pencircle scaled .5pt ; + endfor ; + endfor ; + StopPage ; + setbounds currentpicture to Field[Text][Text] ; +\stopusableMPgraphic + +\startsetups[paper] + + \doifmodeelse{*makeup} + {\reuseMPgraphic{middlepaper}} + {\doifoddpageelse + {\reuseMPgraphic{rightpaper}} + {\reuseMPgraphic{leftpaper}}} + +\stopsetups + +\defineoverlay[paper] [\setups{paper}] +\defineoverlay[page] [\reuseMPgraphic{page}] +\defineoverlay[text] [\doifmode{frame}{\useMPgraphic{text}}] + +\setupbackgrounds [paper] [background=paper] +\setupbackgrounds [page] [background={page,title}] +\setupbackgrounds [text] [background=text] + +\definelayer + [title] + [state=repeat, + hoffset=-1cm, + voffset=1cm, + width=\paperwidth, + height=\paperheight] + +\setupoutput + [pdftex] + +\setuplayout + [width=middle, + topspace=1.5cm, + height=middle, + header=1.5cm, + footer=1cm, + %grid=yes, + headerdistance=.25cm, + footerdistance=.5cm, + backspace=3cm, + margin=1.5cm, + margindistance=.25cm, + edge=.75cm, + edgedistance=.25cm, + bottomdistance=1.5cm, + bottom=.1\printpaperheight] + +\definelayout + [makeup] + [topspace=1cm, + backspace=1cm, + header=0pt, + footer=0pt, + bottom=0pt] + +\setuppagenumbering + [alternative=doublesided] + +\setupcolors + [state=start] + +\usetypescript + [palatino][\defaultencoding] + +\setupbodyfont + [palatino,10pt] + +\setuptolerance + [verytolerant] + +\appendtoks\setups[papershift]\to\beforeeverypage + +\startsetups[papershift] + + \setuppapersize[top=\vskip.5cm,bottom=\vss] + + \doifmodeelse{*makeup} + {\setuppapersize[left=\hfill,right=\hfill]} + {\doifoddpageelse + {\setuppapersize[right=\hfill]} + {\setuppapersize[left=\hfill]}} + +\stopsetups + +\setupbottomtexts + [\setups{rightbanner}] [] + [] [\setups{leftbanner}] + +\startsetups [leftbanner] + + \definedfont[Regular at \the\bottomheight] + \setbox\scratchbox\hbox{\TitleColor\getvariable{magazine}{main}} + \ht\scratchbox1ex + \dp\scratchbox\zeropoint + \MainColor + \definedfont[Regular sa 2] + \doifsomething{\getvariable{magazine}{number}} + {\doifnot{\getvariable{magazine}{number}}{0} + {\#\getvariable{magazine}{number}}} + \quad + \currentdate + \quad + \scale[height=.25\bottomheight]{\box\scratchbox} + \quad + \hbox to 1.5em{\hss\pagenumber\hss} + \quad + \hskip-\backspace + +\stopsetups + +\startsetups [rightbanner] + + \definedfont[Regular at \the\bottomheight] + \setbox\scratchbox\hbox{\TitleColor\getvariable{magazine}{main}} + \ht\scratchbox1ex + \dp\scratchbox\zeropoint + \MainColor + \hskip-\backspace + \definedfont[Regular sa 2] + \quad + \hbox to 1.5em{\hss\pagenumber\hss} + \quad + \scale[height=.25\bottomheight]{\box\scratchbox} + \quad + \currentdate + \quad + \doifmode{atpragma}{\#\getvariable{magazine}{number}} + +\stopsetups + +\startsetups[titlepage] + + \disablemode[frame] + + \setuplayout[makeup] + + \startstandardmakeup[doublesided=no] + + \definelayer + [makeup] + [width=\textwidth, + height=\textheight] + + \setlayerframed + [makeup] + [corner={left,top},location={right,bottom}] + [frame=off, + foregroundcolor=MainColor] + {\scale + [width=\makeupwidth] + {\definedfont[Regular sa 10]% + \getvariable{magazine}{main}}} + + \setlayerframed + [makeup] + [corner={right,top},location={left},y=.4\textheight] + [frame=off, + foregroundcolor=MainColor, + width=\textwidth, + align=left] + {\definedfont[Regular sa 2.5]\setupinterlinespace + \startmode[atpragma] + \strut \ConTeXt\ magazine \#\getvariable{magazine}{number}\endgraf + \stopmode + \strut \getvariable{magazine}{date} \endgraf + \blank + \strut \getvariable{magazine}{title}\endgraf + \doifsomething{\getvariable{magazine}{author}} + {\strut \getvariable{magazine}{author}\endgraf} + \doifsomething{\getvariable{magazine}{affiliation}} + {\strut \getvariable{magazine}{affiliation}\endgraf}} + + \setlayerframed + [makeup] + [corner={right,bottom},location={left,top}] + [frame=off, + align=normal, % left, + width=.8\textwidth, + foregroundcolor=MainColor] + {\getbuffer[abstract]} + + \flushlayer[makeup] + + \stopstandardmakeup + + \setuplayout[reset] + +\stopsetups + +\startsetups[listing] + + \page \disablemode[frame] + + \setuptexttexts [][] \setuptexttexts [] + \setupheadertexts[][] \setupheadertexts[source code of this document] + \setupfootertexts[][] \setupfootertexts[] + + \typefile[TEX]{\inputfilename} % \jobname + +\stopsetups + +\startsetups[lastpage] + + \page \disablemode[frame] \page[even] + + \doifoddpageelse + {} + {\setuplayout[makeup] + \startstandardmakeup[doublesided=no,page=] + \stopstandardmakeup + \setuplayout[reset]} + +\stopsetups + +\startsetups[title] + + \disablemode[frame] + + \setlayerframed + [title] + [corner={left,top},location={left,bottom}, + rotation=90] + [frame=off, + foregroundcolor=MainColor] + {\definedfont[RegularBold sa 2]\strut\getvariable{magazine}{title}} + + \setlayerframed + [title] + [corner={right,top}, + rotation=270] + [frame=off, + foregroundcolor=MainColor] + {\definedfont[RegularBold sa 2]\strut\getvariable{magazine}{title}} + +\stopsetups + +\startbuffer[abstract] + % no abstract +\stopbuffer + +\setuphead + [chapter] + [page=yes, + after={\blank[2*big]}, + color=MainColor, + style=\bfc] + +\setuphead + [section] + [before={\blank[2*big]}, + after=\blank, + color=MainColor, + style=\bfb] + +\setuphead + [subsection] + [before=\blank, + after=, + color=MainColor, + style=\bf] + +\setupwhitespace + [big] + +\definetyping[xtyping] [style=\ttx] +\definetyping[xxtyping][style=\ttxx] + +\definetypeface + [narrowtt] [tt] + [mono] [modern-cond] [default] [encoding=\defaultencoding] + +\definetyping[ntyping] \setuptyping[ntyping][style=\narrowtt] +\definetype [ntype] \setuptype [ntype] [style=\narrowtt] + +\doifnotmode{demo}{\endinput} + +\startbuffer[abstract] + \input tufte +\stopbuffer + +\starttext + + % \showframe + + \setups[titlepage] \setups[title] + + \chapter{E.R. Tufte} \input tufte \page + \chapter{D.E.K. Knuth} \input knuth \page + \chapter{H. Zapf} \input zapf \page + \chapter{D. Hofstadter} \input douglas \page + + \setups[lastpage] + +\stoptext diff --git a/tex/context/base/s-map-10.tex b/tex/context/base/s-map-10.tex new file mode 100644 index 000000000..865132f97 --- /dev/null +++ b/tex/context/base/s-map-10.tex @@ -0,0 +1,488 @@ +%\module [ +% file=s-map-se, +% version=2005.02.03, +% title=\CONTEXT\ Style File, +% subtitle=\MAPS\ basis stijl, +% author={Hans Hagen, Taco Hoekwater and Siep Kroonenberg}, +% date=\currentdate, +% copyright={NTG / MAPS}% +%] + +% This module re-implements the MAPS style for use with the Context +% macro package. The original MAPS layout was designed and +% implemented in LaTeX by Taco Hoekwater and Siep Kroonenberg. + +% This style will be cleaned up as soon as we have time for it. + +% - three layouts: +% 1. two columns +% 2. one column, with wide outer margins (option onecolumn) +% 3. one column, with wide left margin (option asym) +% - font sizes deviate from TeX's usual geometric progression +% - use of sans-serif for headers and various details +% - option realfonts uses Bitstream Charter, Euler Math and Latin Modern. +% This is used for final typesetting. +% The default font setup, intended for authors, uses Computer +% Modern. + +% A mode nosubsub defines only two levels of sectioning. If you +% don't need more and use the two-column layout, then this option +% will probably improve the looks of your paper. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% pdftex support + +\newif\ifMapsInColumns +\doifmode{asym}{\enablemode[onecolumn]} % implies onecolumn +\doifnotmode{onecolumn}{\MapsInColumnstrue} + +\enablemode[realfonts] + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% fonts + +%%%%%%%%% first, font sizes +\definebodyfontenvironment [7pt][% LaTeX: scriptsize + interlinespace=8pt, + big=8pt, + small=6pt% +] + +\definebodyfontenvironment [8pt][% LaTeX: footnotesize + interlinespace=9pt, + big=9pt, + small=7pt, + x=6pt% +] + +\definebodyfontenvironment [9pt][% LaTeX: small + interlinespace=10pt, + big=10pt, + small=7pt,% + x=7pt,% + script=7pt% +] + +\definebodyfontenvironment [10pt][% LaTeX: normalsize + interlinespace=11pt, + big=11pt, + small=9pt,% + x=8pt,% + script=7pt% +] + +\definebodyfontenvironment [11pt][% LaTeX: large + interlinespace=11pt, + big=11pt, + small=10pt,% + x=9pt,% + script=8pt% +] + +\definebodyfontenvironment [14pt][% + interlinespace=14pt, + big=24pt, + small=11pt, + x=10pt% +] + +\definebodyfontenvironment [24pt][% + interlinespace=24pt, + big=24pt, + small=14pt, + x=11pt% +] + +%%% font families + +\starttypescript [map] [texnansi] + + \definetypeface[map][ss][sans] [map] [default][encoding=\typescripttwo] + \definetypeface[map][rm][serif][charter] [default][encoding=\typescripttwo,rscale=0.95] + \definetypeface[map][tt][mono] [modern] [default][encoding=\typescripttwo] + \definetypeface[map][mm][math] [euler] [default][encoding=\typescripttwo] + +% \usemathcollection[eul] + +\stoptypescript + +% activate protruding + +\setupinterlinespace[line=11pt] + +\setupfontsynonym[handling=pure] + +\setupalign[hanging] + +\usetypescript[map][texnansi] + +\setupbodyfont [map,10pt] + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% additional general typographic details + +\setupindenting [yes,next,11pt] % indenting after enumerations etc. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% 3 versions of layout with matching headers + +% I would like to move the entire layout slightly toward the spine, +% but Context seems to provide no good handle for that. +% So instead, I'll use a two-column layout centered on the page and +% matching single-column layouts. + +% It is easy to do the shift toward the spine when assembling the +% volume with LaTeX pdfpages. + +\definepapersize [maps][% + width=595.3bp, % 21cm + height=756bp% 10.5in +] + +\setuppapersize [maps][maps] + +% parameters: +% margin -> latex marginparwith + +\setuplayout[% + topspace=40pt, + height=692pt, + header=33pt, + margin=106pt, + leftmargindistance=11pt, + rightmargindistance=11pt% +] + + +\setupblank[5.5pt] + +\setuppagenumbering [location=] + +\definetyping [widetyping] + +\setupheader [style=\ss] +\setupfooter [style=\ss] + +\def\AuHead{% + %\ifnum\pageno=\MapsPage \hbox{}\else + \MapsRunningAuthor%\fi +} +\def\TiHead{% + \ifnum\pageno=\MapsPage \relax \MapsRunningAuthor %\hbox{} + \else \MapsRunningTitle\fi} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% sectioning + +\setupheads[sectionnumber=no, align=right] + +\def\hfonti{\bfa} +\def\hfontii{\bf} +\def\hfontiii{\rm\bi} +\def\runin#1#2{#2.} + +\doifmodeelse{nosubsub}{% +\setuphead [section][% + style=\hfontii, + before={\blank[halfline]}, + after={}% +] +\setuphead [subsection][% + style=\hfontiii, + command=\runin, + alternative=text, + before={\blank[halfline]}% +]}{% +\setuphead [section][% + style=\hfonti, + before={\blank[13pt]}, + after={\blank[6pt]}% +] +\setuphead [subsection][% + style=\hfontii, + before={\blank[6pt]}, + after={}% +] +\setuphead [subsubsection][% + style=\hfontiii, + command=\runin, + alternative=text, + before={\blank[halfline]}% +]} + +\doifmodeelse{nosubsub}{% +\setuphead [subject][% + style=\hfontii, + before={\blank[halfline]}, + after={}% +] +\setuphead [subsubject][% + style=\hfontiii, + command=\runin, + alternative=text, + before={\blank[halfline]}% +]}{% +\setuphead [subject][% + style=\hfonti, + before={\blank}, + after={\blank[halfline]}% +] +\setuphead [subsubject][% + style=\hfontii, + before={\blank[halfline]}, + after={}% +] +\setuphead [subsubsubject][% + style=\hfontiii, + command=\runin, + alternative=text, + before={\blank[halfline]}% +]} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% floats + +\setupfloats [location=left, before={\ss}] +\setupcaptions [style={\ss}, + stopper=., + inbetween={\blank[halfline]}] + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% various document elements + +%\startnotmode[realfonts] +\def\ChkBox{% + \hbox {\boxrulewidth=.4pt \raise.2ex\ruledvbox + {\phantom{\vrule width .85ex height .85ex% +}}}} +%\stopnotmode +%\startmode[realfonts] +%\def\ChkBox{\raise.12ex\hbox{\ws \char50}} +%\stopmode +\definesymbol [1][\ChkBox] + +\setupitemize[1][packed] + +\setupitemize [each][% + indentnext=no, + align=right, + width=1em, + distance=0pt% +] + +% an outer form of itemize that does not indent +% the paragraph. + +\definecomplexorsimpleempty\startouteritemize +\def\complexstartouteritemize[#1]{\begingroup + \startitemize[width=1sp,#1] + \let\doitem\item + \def\item{\doitem[]\hbox{}\kern12pt\rightskip=0pt}% +} + +\def\stopouteritemize{\stopitemize\endgroup} + + +\setupenumerations [indentnext=no] + +\setupdescriptions [indentnext=no] + +\unexpanded\def\smalltyping{% + \switchtobodyfont[tt,9pt]% + \setuplocalinterlinespace[line=11pt]% + \parindent=0pt +} + +% typing: +% - prettyverbatim is NOT the default +% - smaller size + +\setuptyping [% + style={\smalltyping}, + option=none, + indentnext=no% +] + +\def\footnum#1{#1.} + +\setupfootnotes + [location=none, + width=\textwidth, + bodyfont=9pt, + before=, + numbercommand=\footnum] + +\setupfootnotedefinition + [location=serried, + before=, + after=, + distance=0.5em] + +\setuptabulate + [before=\blank, + inner=\ss, + after=\blank] + +\def\startIntroEntry#1% + {\blank[line] + \startbaselinecorrection + \bgroup + \setupalign[right] + \setuptolerance[verytolerant] + \setupindenting[no] + \switchtobodyfont[9pt]% + \hyphenpenalty10000 + \parfillskip 0pt plus 1fill + \rightskip6pt plus 1fill + \ss + \bgroup\bf #1\par\egroup + \ignorespaces } + +\def\stopIntroEntry + {\par\egroup \stopbaselinecorrection} + +\def\defineIntroEntry[#1][#2][#3]% + {\setvalue{start#1}{\startIntroEntry{#2}}% + \setvalue {stop#1}{\stopIntroEntry#3}} + +\defineIntroEntry[Keywords][Keywords][] +\defineIntroEntry[Abstract][Abstract][] + +% article parameters (other fields and defaults) +\def\MapsBibData[#1]% + {\getparameters [Maps] + [SubTitle=, + RunningAuthor=, + RunningTitle=, + Email=, + Address=, + Page=1, + Title=No Title given, + Author=No Author given, + Period=, + Number=99, + Year=2006, + #1]% + \doifnothing\MapsRunningAuthor + {\global\let\MapsRunningAuthor\MapsAuthor}% + \doifnothing\MapsRunningTitle + {\global\let\MapsRunningTitle\MapsTitle}}% + +\def\dostartArticle[#1]{% + \MapsBibData[#1] + \pageno=\MapsPage + \count0=\MapsPage + \setuppagenumber[number=\MapsPage] + \bgroup + \hsize = 457pt + \let\\\crlf + \blank[29pt,force] + \switchtobodyfont[rm,24pt] + \setupalign[right] + {\bf\noindent\MapsTitle\par\blank[6pt]} + \ifx\MapsSubTitle\empty \else + { \switchtobodyfont[ss,24pt]\sl\noindent + \advance \rightskip 0pt plus 2em + \MapsSubTitle\par} + \fi + \doifmodeelse{newstyle} + {\blank[22pt]} + {\blank[30pt]} + \egroup + \switchtobodyfont[rm,10pt] + \doifmode{newstyle} + {\noindent\MapsAuthor\blank[line]} + \setupalign[width] + \ifMapsInColumns + \startcolumns\hyphenpenalty1000 + \else + \clubpenalty10000 + \widowpenalty10000 + \fi +} + +\definecolumnset[mapsset][n=2,grid=on] + +\def\startArticle{\dosingleempty\dostartArticle} + +\def\stopArticle{% + {\blank\let\\\crlf + \noindent\switchtobodyfont[ss,9pt]% + \MapsAuthor + \doifsomething{\MapsAddress}{\\\MapsAddress}% + \doifsomething{\MapsEmail}{\\\MapsEmail}}% + \ifMapsInColumns \stopcolumns \fi + \page +} + +\installpagebreakhandler{last}{} + +%%% `logos' %%%%%%%%%%%%%%%%%%%%%%%%%% + +\def\LATEX{La\TeX} +\def\LaTeX{La\TeX} +\def\TEX{\TeX} +\def\CONTEXT{Con{\TeX}t} +\def\ConTeXt{Con{\TeX}t} +\def\METAFONT{Metafont} +\def\METAPOST{MetaPost} +\def\POSTSCRIPT{PostScript} + + +%%%%%%%%%%% + +\doifmodeelse{onecolumn}{% + \setuplayout[width=340pt] + \doifmodeelse{asym}{% one col, asymmetric + \setuplayout[backspace=187.3pt]% + \setuptyping [widetyping][oddmargin=-117pt] + \setuppagenumbering [alternative={singlesided,doublesided}] + \setupheadertexts + [{\hbox{}\hskip-117pt\TiHead}] + [{{\tfx\MapsPeriod~}\MapsYear\quad\bf\pagenumber\hskip-30pt\hbox{}}] + [{\hbox{}\hskip-147pt{\bf\pagenumber}\quad {\tfx MAPS~}\MapsNumber}] + [\AuHead] + \setupfootertexts + }{% one col, symmetric + \setuplayout[backspace=70.3pt] + \setuppagenumbering [alternative=doublesided] + \setuptyping[blank=halfline] + \setupheadertexts + [\TiHead] + [{{\tfx\MapsPeriod~}\MapsYear\quad\bf\pagenumber\hskip-147pt\hbox{}}] + [{\hbox{}\hskip-147pt{\bf\pagenumber}\quad {\tfx MAPS~}\MapsNumber}] + [\AuHead] + \setupfootertexts +}}{% two col + \setuplayout[width=457pt] + \setupcolumns[n=2,tolerance=verytolerant,distance=11pt] + \setuplayout[backspace=70.3pt,grid=yes] + \setuppagenumbering [alternative=doublesided] + \setuptyping[blank=halfline] + \setupheadertexts + [\TiHead] + [{{\tfx\MapsPeriod~}\MapsYear\quad\bf\pagenumber\hskip-30pt\hbox{}}] + [{\hbox{}\hskip-30pt{\bf\pagenumber}\quad {\tfx MAPS~}\MapsNumber}] + [\AuHead] + \setupfootertexts +} + +%\MapsBibData +% [] + +%\abovedisplayskip = 12pt +%\abovedisplayshortskip = 6pt + +\newdimen\iabovedisplayskip +\newdimen\iabovedisplayshortskip +%\let\abovedisplayskip\iabovedisplayskip +%\let\abovedisplayshortskip\iabovedisplayshortskip + +\setuplanguage + [nl] + [\c!leftquote=\upperleftsinglesixquote, + \c!leftquotation=\upperleftdoublesixquote] + +%\protect +\endinput diff --git a/tex/context/base/s-mod-00.tex b/tex/context/base/s-mod-00.tex new file mode 100644 index 000000000..270f7a9b4 --- /dev/null +++ b/tex/context/base/s-mod-00.tex @@ -0,0 +1,512 @@ +%D \module +%D [ file=s-mod-00, +%D version=very-old, +%D title=\CONTEXT\ Style File, +%D subtitle=Documentation Base Environment, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This module looks like crap, is not documented, will +%D change, and used to be called modu-*.tex. + +% todo: +% +% file inclusions -> hyperlinks + +\mainlanguage[en] % better not here + +\usemodule[units] + +\doifnotmode{mkiv}{ + \enableactivediscretionaries + \newprettytrue +} + +\unprotect + +% beter: +% +% group -> title +% title -> category +% subtitle -> subtitle + +% herzien ivm fonts + +% nog eens \interface \\ \\ verder doorvoeren + +\def\resetmodule + {\getrawparameters + [Module] + [ file=\jobname, + version={\currentdate[\v!year,{.},\v!month,{.},\v!day]}, + system=\CONTEXT, + title=, + subtitle=, + author=Hans Hagen, + date=\currentdate, + copyright={PRAGMA / Hans Hagen \& Ton Otten}, + suggestions=]} + +\resetmodule + +\def\dostartmodule[#1]% + {\newcounter\ParagraphNumber + \resetmodule + \getrawparameters[Module][type=tex,#1]} + +\def\startmodule + {\starttext + \dosingleempty\dostartmodule} + +\def\complexmodule[#1]% + {\startglobal % i.v.m. \bgroup in \startdocumentation + \getrawparameters[Module][#1] + \stopglobal % i.v.m. \bgroup in \startdocumentation + \moduletitle} + +\def\stopmodule + {\page + \placeregister + [\v!index] + [\c!balance=\v!yes, + \c!indicator=\v!no, + \c!criterium=\v!text] + \stoptext} + +\def\simplemodule#1% + {\type{#1}} + +\definecomplexorsimple\module + +% \startmode[atpragma] +% +% \def\TitlePage#1% can be done more efficient +% {\startMPrun +% mpgraph := #1 ; +% input mp-cont ; +% \stopMPrun +% \externalfigure +% [\bufferprefix mprun.#1] +% [\c!height=\vsize, +% \c!width=\hsize]} +% +% \defineoverlay[titlepage][\TitlePage{512}] +% +% \stopmode + +\startuseMPgraphic{titlepage} + + width := PaperWidth ; + height := PaperHeight ; + + color local_red, local_white, local_blue ; + + local_white := white ; + + local_blue := local_white randomized (.6,.8) ; + local_red := local_white randomized (.3,.4) ; + + u := width/400 ; + + def a_module (expr dx, dy) = + picture p ; p := image + ( ddy := 0 ; sx := 60u ; + for i=1 upto (4 randomized 2) : + sy := 7u randomized 3u ; + fill unitsquare xyscaled(sx,sy) shifted (0,ddy) + withcolor local_red ; + ddy := ddy + sy + 4u ; + endfor ) ; + p := p shifted (dx,dy) shifted - center p ; + fill boundingbox p enlarged 8u withcolor local_white ; + fill boundingbox p enlarged 4u withcolor local_blue ; + draw p ; + enddef ; + + set_grid(width, height, width/15, height/15) ; + forever: + if new_on_grid(uniformdeviate width,uniformdeviate height): + a_module(dx,dy) ; + fi ; + exitif grid_full ; + endfor ; + + clip currentpicture to unitsquare xyscaled(width,height) ; +\stopuseMPgraphic + +\defineoverlay + [titlepage] + [\useMPgraphic{titlepage}] + +\doifmode{atpragma}{\readfile{s-mod-04.tex}{}{}} + +\defineframed + [TitleFrame] + [\c!background=\v!color, + \c!backgroundcolor=white, + \c!align=\v!right, + \c!offset=12pt, + \c!strut=\v!no, + \c!frame=\v!off, + \c!bottom=] + +\definelayout + [titlepage] + [\c!backspace=0pt, + \c!topspace=0pt, + \c!header=0pt, + \c!footer=0pt, + \c!height=\v!middle, + \c!width=\v!middle] + +\def\moduletitle + {\setuplayout[titlepage] + \ifx\ModuleNumber\undefined \else + \ifnum\ModuleNumber<10 + \edef\ModuleNumber{00\ModuleNumber} + \else\ifnum\ModuleNumber<100 + \edef\ModuleNumber{0\ModuleNumber} + \fi\fi + \setupbackgrounds + [\v!page] + [\c!background=titlepage] + \fi + \startmakeup[\v!standard][\c!headerstate=\v!none,\c!footerstate=\v!none] + \switchtobodyfont[14.4pt,ss] + \bgroup + \def\CONTEXT {Con\kern-.15em\TeX t} + \def\TEXUTIL {\TeX Util} + \def\PPCHTEX {PPCH\TeX} + \def\METAPOST{MetaPost} + \hfill + {\definedfont[SansBold at 96pt]\setstrut + \TitleFrame{\Modulesystem}} + \vfill + \definetabulate[temp][|l|l|]% + \switchtobodyfont[17.3pt,ss] + \hfill + {\bf\setstrut + \TitleFrame + {\insidefloattrue\setuptabulate[\c!before=,\c!after=]% + \starttemp + \doifsomething{\Moduletitle} + {\NC title \EQ \Moduletitle \NC\NR}% + \doifsomething{\Modulesubtitle} + {\NC subtitle \EQ \Modulesubtitle \NC\NR}% + \doifsomething{\Moduleauthor} + {\NC author \EQ \Moduleauthor \NC\NR}% + \NC date \EQ \currentdate \NC\NR + %\doifsomething{\Modulesuggestions} % todo: generates space + % {\NC suggestions \NC \Modulesuggestions \NC\NR}% + \stoptemp}} + \egroup + \stopmakeup + \ifx\ModuleNumber\undefined \else + \setupbackgrounds + [\v!page] + [\c!background=] + \fi + \setuplayout} + +\let\stopdocumentation=\relax + +\def\startdocumentation + {\bgroup + \doglobal\newcounter\NOfMarginLines + \def\stopdocumentation{\par\egroup}} + +\newif\ifcompressdefinitions + +\def\startcompressdefinitions {\global\compressdefinitionstrue} +\def\stopcompressdefinitions {\global\compressdefinitionsfalse} + +\gdef\CompressDefinitions% + {\ifcompressdefinitions + \switchtobodyfont[\v!small]% + \fi} + +\startnotmode[nocode] + + \definetyping + [definition] + + \setuptyping + [definition] + [\c!before={\page[\v!preference]}\blank\PresetParagraphNumber\CompressDefinitions, + \c!after=\ResetParagraphNumber\blank, + \c!option=\Moduletype] + +\stopnotmode + +\startmode[nocode] + +% \definieerbuffer[definition] % ignore + + \long\def\startdefinition#1\stopdefinition{} + +\stopmode + +\definetyping [PL] [\c!option=PL, \c!margin=\v!standard] +\definetyping [JV] [\c!option=JV, \c!margin=\v!standard] +\definetyping [MP] [\c!option=MP, \c!margin=\v!standard] +\definetyping [TEX] [\c!option=TEX,\c!margin=\v!standard] + +\setuptyping [\v!typing] [\c!margin=\v!standard] +\setuptyping [\v!file] [\c!margin=\v!standard] +\setuptyping [definition] [\c!margin=0pt] + +\newcounter\NOfMarginLines +\newcounter\ParagraphNumber + +\def\ResetParagraphNumber + {\egroup} + +\def\PresetParagraphNumber + {\bgroup + \xdef\NOfTextLines% + {\the\prevgraf}% + \doglobal\decrement\NOfMarginLines + \doglobal\increment\ParagraphNumber + \message{.}% + \gdef\ShowParagraphNumber% + {\llap{\slx\ParagraphNumber\hskip\leftmargindistance}}% + \gdef\ShowParagraphNumberA% + {\ifnum\NOfMarginLines>\NOfTextLines\relax + \doglobal\increment\NOfTextLines + \else + \ShowParagraphNumber + \global\let\ShowParagraphNumberA=\relax + \global\let\ShowParagraphNumberB=\ShowParagraphNumber + \doglobal\newcounter\NOfMarginLines + \fi}% + \gdef\ShowParagraphNumberB% + {}% + \EveryLine + {\ShowParagraphNumberA}% + \EveryPar + {\vadjust{\nobreak}% + \ShowParagraphNumberB}} + +\EveryPar % skip one + {\EveryPar + {\doglobal\newcounter\NOfMarginLines}} + +\def\dodomargeaanduidingen[#1]#2% + {\def\docommand##1% + {\indent\hbox + {\ifx#2\relax + \index{##1}% + \else + \index{#2{##1}}% + \fi + #2{\doboundtext{##1}{\leftmarginwidth}{..}}}% + \doglobal\increment\NOfMarginLines + \endgraf}% + \processcommalist[#1]\docommand} + +\def\margeaanduidingen#1[#2]% + {\def\domargeaanduidingen##1##2% + {\margintitle[#2]% + {\switchtobodyfont[\v!small]% + \doglobal\newcounter\NOfMarginLines + \dodomargeaanduidingen[##1]#1% + \scratchcounter=\NOfMarginLines + \multiply\scratchcounter by 10 + \divide\scratchcounter by 12 + \advance\scratchcounter by 1 + \xdef\NOfMarginLines{\the\scratchcounter}% + \processcommalist[##2]\index}}% + \dodoublegroupempty\domargeaanduidingen} + +\def\complexmacros{\margeaanduidingen\tex } +\def\complexextras{\margeaanduidingen\relax} + +\def\complexelements + {\margeaanduidingen\someelement} + +\def\someelement#1{\type{<#1>}} + +\definecomplexorsimpleempty\macros +\definecomplexorsimpleempty\extras +\definecomplexorsimpleempty\elements + +\def\showelements{\dodoubleempty\doshowelements} + +\def\doshowelements[#1][#2] + {\bgroup + \processXMLbuffer + \typebuffer + \setupcolors[\c!state=\v!stop] + \showXSDcomponent[#1][#2] + \egroup} + +% \macros{a,b} +% \macros{a,b}{b} +% \macros[a]{a,b}{b} + +% weg ermee + +\defineparagraphs [interface] [\c!n=2] +\setupparagraphs [interface] [1] [\c!width=4cm] + +\def\startexample{\par\startnarrower} \let\startvoorbeeld\startexample +\def\stopexample {\stopnarrower} \let\stopvoorbeeld \stopexample + +\gdef\VisualizeLastSpace{\ifdim\lastskip>0pt\unskip\tttf\char32\fi} + +\gdef\ShowHeadText #1{\tttf#1\VL\mainlanguage[\currentlanguage]\headtext {#1}\VisualizeLastSpace} +\gdef\ShowLabelText#1{\tttf#1\VL\mainlanguage[\currentlanguage]\labeltext{#1}\VisualizeLastSpace} + +\startbuffer[lang-a] +\starttable[|l|l|] + \HL + \VL \bf head key \VL \bf current value \VL\SR + \HL + \VL \ShowHeadText \v!abbreviations \VL\FR + \VL \ShowHeadText \v!units \VL\MR + \VL \ShowHeadText \v!figures \VL\MR + \VL \ShowHeadText \v!graphics \VL\MR + \VL \ShowHeadText \v!index \VL\MR + \VL \ShowHeadText \v!content \VL\MR + \VL \ShowHeadText \v!intermezzi \VL\MR + \VL \ShowHeadText \v!logos \VL\MR + \VL \ShowHeadText \v!tables \VL\LR + \HL +\stoptable +\stopbuffer + +\startbuffer[lang-b] +\starttable[|l|l|] + \HL + \VL \bf label key \VL \bf current value \VL\SR + \HL + \VL \ShowLabelText \v!table \VL\FR + \VL \ShowLabelText \v!figure \VL\MR + \VL \ShowLabelText \v!intermezzo \VL\MR + \VL \ShowLabelText \v!graphic \VL\MR + \VL \ShowLabelText \v!chapter \VL\MR + \VL \ShowLabelText \v!section \VL\MR + \VL \ShowLabelText \v!subsection \VL\MR + \VL \ShowLabelText \v!subsubsection \VL\MR + \VL \ShowLabelText \v!appendix \VL\MR + \VL \ShowLabelText \v!part \VL\MR + \VL \ShowLabelText \v!line \VL\MR + \VL \ShowLabelText \v!lines \VL\LR + \HL +\stoptable +\stopbuffer + +\startbuffer[lang-c] +\starttable[|l|l|] + \HL + \VL \bf label key \VL \bf current value \VL\SR + \HL + \VL \ShowLabelText \v!january \VL\FR + \VL \ShowLabelText \v!february \VL\MR + \VL \ShowLabelText \v!march \VL\MR + \VL \ShowLabelText \v!april \VL\MR + \VL \ShowLabelText \v!may \VL\MR + \VL \ShowLabelText \v!june \VL\MR + \VL \ShowLabelText \v!july \VL\MR + \VL \ShowLabelText \v!august \VL\MR + \VL \ShowLabelText \v!september \VL\MR + \VL \ShowLabelText \v!october \VL\MR + \VL \ShowLabelText \v!november \VL\MR + \VL \ShowLabelText \v!december \VL\LR + \HL +\stoptable +\stopbuffer + +\startbuffer[lang-d] +\starttable[|l|l|] + \HL + \VL \bf label key \VL \bf current value \VL\SR + \HL + \VL \ShowLabelText \v!sunday \VL\FR + \VL \ShowLabelText \v!monday \VL\MR + \VL \ShowLabelText \v!tuesday \VL\MR + \VL \ShowLabelText \v!wednesday \VL\MR + \VL \ShowLabelText \v!thursday \VL\MR + \VL \ShowLabelText \v!friday \VL\MR + \VL \ShowLabelText \v!saturday \VL\LR + \HL +\stoptable +\stopbuffer + +\gdef\ShowTextsValues[#1][#2]% + {\vbox\bgroup + \language[#1]% + \setbox\scratchbox\hbox to \hsize{\hss\bfb#2 language defaults\hss} + \dp\scratchbox\zeropoint + \box\scratchbox + \vskip1em + \hrule + \vskip2em + \halign + {\hss##\hss&##\hskip1em&\hss##\hss\cr + $\vcenter{\getbuffer[lang-a]}$&&$\vcenter{\getbuffer[lang-b]}$\cr + \noalign{\vskip1em} + $\vcenter{\getbuffer[lang-c]}$&&$\vcenter{\getbuffer[lang-d]}$\cr}% + \egroup} + +\gdef\ShowLanguageValues[#1][#2]#3#4% + {\hbox to \hsize + {\hss + \vbox + \bgroup + \language[#1]% + \let\normalbar=| + \starttable[||||] + \HL + \VL \THREE{\bf subsentence symbol and quotes} \VL\SR + \HL + \VL \quotation{#3 #4} \VL \quote{#2} \VL \let|=\normalbar |<||<|#3|>|#4|>| \VL\FR + \VL \quotation{#3 #4} \VL \quote{#2} \VL |<||<|#3|>|#4|>| \VL\LR + \HL + \stoptable + \egroup + \hss}} + +\gdef\doShowAllLanguageValues[#1][#2]#3#4% + {\vbox + {\ShowTextsValues[#1][#2] + \vskip2em + \ShowLanguageValues[#1][#2]{#3}{#4}} + \protect + \page} + +\gdef\ShowAllLanguageValues + {\page + \unprotect + \dodoubleargument\doShowAllLanguageValues} + +\protect + +%D Command references: + +% \input setupa +% \input setupb + +\usemodule[int-load] \loadsetups + +\unprotect + +% \def\showsetup +% {\doglobal\newcounter\CurrentArgument +% \setup} + +\def\showsetup#1% + {{\def\y##1{\writestatus{setups}{warning: remove y! from #1}}% + \setup{#1}}} + +\setupframedtexts + [setuptext] + [\c!background=\v!screen, + \c!frame=\v!off] + +\protect \endinput diff --git a/tex/context/base/s-mod-01.tex b/tex/context/base/s-mod-01.tex new file mode 100644 index 000000000..4454986ce --- /dev/null +++ b/tex/context/base/s-mod-01.tex @@ -0,0 +1,157 @@ +%D \module +%D [ file=s-mod-01, +%D version=very-old, +%D title=\CONTEXT\ Style File, +%D subtitle=Documentation Paper Environment, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This module looks like crap, is not documented, will +%D change, and used to be called modu-*.tex. + +\usemodule[mod-00,abr-01] + +\dontcomplain + +\unprotect + +\setupbodyfont + [10pt] + +\definetypeface + [narrowtt] [tt] + [mono] [modern-cond] [default] [encoding=\defaultencoding] + +\setuptyping[\v!typing][\c!style=\narrowtt] +\setuptype [\v!type] [\c!style=\narrowtt] + +\mainlanguage + [en] + +\setupwhitespace + [\v!big] + +\setuptolerance + [\v!tolerant] + +\emergencystretch=5em + +\setuplayout + [\c!backspace=3.5cm, + \c!leftmargin=1.75cm, + \c!rightmargin=0cm, + \c!margindistance=.5cm, + \c!leftedgedistance=.25cm, + \c!rightedgedistance=.5cm, + \c!edge=1.5cm, + \c!width=15.55333cm, % 13.998cm at 9pt => 15.55333 at 10pt + \c!topspace=2cm, + \c!header=1.25cm, + \c!footer=1.25cm, + \c!height=middle, + \c!style=\ss] + +\setupsetup + [\c!reference=1] + +\startnotmode[single] + + \setuppagenumbering + [\c!alternative={\v!doublesided,\v!singlesided}] + +\stopnotmode + +\setuppagenumbering + [\c!location=] + +\expanded{\setupfootertexts + [\v!edge] + [][\v!pagenumber]} + +\startmode[single] + + \setupfootertexts + [\v!margin] + [\filename{\Modulefile}][] + +\stopmode + +\startnotmode[single] + + \setupfootertexts + [\v!margin] + [\filename{\Modulefile}][] + [\filename{\Modulefile}][] + +\stopnotmode + +\setupfootertexts + [\v!text] + [\CONTEXT] + [\Moduletitle] + +\setupheadertexts + [\v!text] + [] + [\Modulesubtitle] + +\setupinmargin + [\c!location=\v!left] + +\setupheads + [\c!alternative=\v!inmargin] + +\setuphead + [\v!chapter] + [\c!style=\ssc, + \c!page=\v!right, + \c!header=\v!empty] + +\setuphead + [\v!section] + [\c!style=\ssb, + \c!page=\v!right] + +\setuplist + [\v!chapter] + [\c!style=\v!bold, + \c!after=\blank] + +\setupcombinedlist + [\v!content] + [\c!width=3em, + \c!aligntitle=\v!yes] + +\setupregister + [\v!index] + [\c!balance=\v!yes, + \c!indicator=\v!no] + +\startnotmode[nocolor] + +\setupcolors + [\c!state=\v!start] + +\stopnotmode + +\startnotmode[color] + + \setupcolors + [\c!conversion=\v!always] + + \setuptyping + [\c!palet=graypretty] + +\stopnotmode + +\setupinteraction + [\c!state=\v!start, + \c!color=, + \c!style=] + +\protect \endinput diff --git a/tex/context/base/s-mod-02.tex b/tex/context/base/s-mod-02.tex new file mode 100644 index 000000000..9dae3ecc0 --- /dev/null +++ b/tex/context/base/s-mod-02.tex @@ -0,0 +1,420 @@ +%D \module +%D [ file=s-mod-02, +%D version=very-old, +%D title=\CONTEXT\ Style File, +%D subtitle=Documentation Screen Environment, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This module looks like crap, is not documented, will +%D change, and used to be called modu-*.tex. + +% Macro's + +\usemodule[mod-00] + +% todo: internationalize + setups + +\setuphead[paragraaf][expansion=command] +\setuphead[section][expansion=command] + +\def\complexmodule[#1]% redefined + {\startglobal % i.v.m. \bgroup in \startdocumentation + \getparameters[Module][#1] + \stopglobal % i.v.m. \bgroup in \startdocumentation + %%\section{\Modulesubtitle} + \xdef\Temp{\Modulesubtitle}%%Modulesubtitle:\framed{BEGIN \Modulesubtitle END} :#1 !} + \@EA\section\@EA{\Temp} + \WriteLists} + +\def\stopmodule % redefined + {\page + \determineregistercharacteristics + [index] + [criterium=section] + \ifutilitydone + \pagereference + [index] + \placeregister + [index] + [balance=yes, + indicator=no, + criterium=section] + \fi} + +\let\ComposeLists=\relax + +\newcounter\ModuleNumber + +\newwrite\BatchFile \openout\BatchFile=\jobname.bat + +\def\WriteBatchFile + {\doglobal\increment\ModuleNumber +% \immediate\write\BatchFile{call modu-run \FileName\space \ModuleNumber}} +% \immediate\write\BatchFile{texmfstart texutil --modu \FileName}} + \immediate\write\BatchFile{texmfstart texexec --pdf --modu --batch \FileName }} + +\newif\ifProcessingPublic + +\def\WriteLists + {\writetolist[FileNames] {}{\FileName} + \writetolist[GroupItems]{}{\GroupItem}} + +\def\moduletitle{} + +\def\TypeZeroModule#1% + {\section{[to be extracted: #1]} + {\em This module is not yet split off.} + \WriteLists} + +\def\TypeOneModule#1% + {\section{[to be documented: #1]} + {\em This module is not yet fully documented.} + \WriteLists} + +\def\TypeTwoModule#1% + {\ifProcessingPublic + \readfile{#1.ted}{}{}% + \WriteBatchFile + \else + \section{[not yet public: #1]} + {\em This module is documented but not yet public.} + \WriteLists + \fi} + +\def\TypeThreeModule#1% + {\readfile{#1.ted}{}{}% + \WriteBatchFile} + +\def\processmodule#1#2% + {\page + \bgroup + \def\FileName{#1} + \setupreferencing[prefix=#1] + \useexternaldocument[PaperVersion][#1][] + \aftersplitstring#1\at-\to\GroupItem + \ComposeLists + \ifcase#2 + \TypeZeroModule{#1} + \or + \TypeOneModule{#1} + \or + \TypeTwoModule{#1} + \or + \TypeThreeModule{#1} + \fi + \page + \setupreferencing[prefix=] + \egroup} + +\def\ModuleGroup#1#2% + {\page + \let\Modulefile=\empty + \setupreferencing[prefix=#1] + \def\FileGroup{#1} + \writetolist[FileGroups]{}{\FileGroup} + \chapter[content]{#2} + \MakeListOfItems + \MakeListOfNames + \MakeListOfGroups + \placecontent[criterium=chapter,level=section]} + +% Layout + +\setupbodyfont + [9pt] + +\setuppapersize + [S6][S6] + +\setuplayout + [backspace=72.5pt, + leftmargin=50pt, + leftmargindistance=12.5pt, + rightmargin=0pt, + rightedge=80pt, + rightedgedistance=10pt, + leftedge=0pt, + width=430pt, + topspace=10pt, + header=0pt, + footer=30pt, + bottomdistance=10pt, + bottom=15pt, + height=410pt, + style=\ss] + +\setuptyping + [palet=colorpretty] + +\setupsetup + [reference=3] + +\definecolor [AchtergrondKleur] [s=.6] +\definecolor [ButtonKleur] [r=.2,g=.2,b=.6] +\definecolor [TekstKleur] [r=.6,g=.2,b=.2] + +\definecolor [colorprettyone] [r=.6,g=.0,b=.0] % red +\definecolor [colorprettytwo] [r=.0,g=.6,b=.0] % green +\definecolor [colorprettythree] [r=.0,g=.0,b=.6] % blue +\definecolor [colorprettyfour] [r=.6,g=.6,b=.0] % yellow + +\setupinteraction + [state=start, + page=yes, + contrastcolor=, + menu=on, + color=] + +\setupbackgrounds + [page] + [background=color, + backgroundcolor=AchtergrondKleur, + offset=2.5pt] % this offset influences the menus! + +\setupbackgrounds + [text,footer] + [text,leftmargin] + [background=color, + backgroundcolor=white] + +\setupsubpagenumber + [way=bysection, + state=start] + +\setupinteractionbar + [frame=off, + offset=0pt, + height=fit] + +\setupwhitespace + [big] + +\setuptyping + [typing] + [option=color] + +\setuptyping + [definition] + [option=color] + +\setuptyping + [file] + [option=color] + +\setuppagenumbering + [alternative=singlesided, + way=bysection, + state=none] + +\setupinmargin + [location=left] + +\setupheads + [alternative=inmargin] + +\setuphead + [chapter] + [style=\ssc, + page=right] + +\setuphead + [section] + [style=\ssb, + page=right] + +\setuplist + [chapter] + [style=bold, + after=\blank] + +\setupcontent + [width=2em] + +\setupindex + [balance=yes, + indicator=no] + +\setupcolors + [state=start] + +\def\TitelBlad#1% + {\startstandardmakeup + \definefont[GrootFont] [SansBold at 72pt] + \definefont[MiddelFont][Sans at 32pt] + \definefont[KleinFont] [Sans at 24pt] + \startcolor[AchtergrondKleur] + \vskip12pt + \midaligned{\GrootFont\setstrut\strut Con\TeX t} + \vskip24pt + \midaligned{\MiddelFont\setstrut\strut #1} + \vskip24pt + \midaligned{\KleinFont\setstrut\strut Hans Hagen} + \vfilll + \midaligned{\KleinFont\setstrut\strut PRAGMA ADE} + \vskip24pt + \midaligned{\KleinFont\setstrut\strut www.pragma-ade.com --- \currentdate} + \vskip12pt + \stopcolor + \stopstandardmakeup} + +\def\ColofonBlad + {\startmode[atpragma] + \page + \bgroup + \def\PragmaHoogte {\makeupheight} + \def\PragmaBreedte{\textwidth} + \def\PragmaKopwit {\topspace} + \def\PragmaRugwit {\backspace} + \def\PragmaMarge {0pt} + \PragmaLijnentrue + \PlaatsPragmaLogo[ADE] + \vfill + todo: colofon + \startnarrower[3*middle] + This is the official documentation of \CONTEXT\ version + \referraldate, a \TEX\ macropackage developed by J.~Hagen + \& A.F.~Otten, who both hold the copyrights. + \stopnarrower + \vfill + \page + \egroup + \stopmode} + +\def\ColofonBlad + {} + +\newbox\ListOfItems +\newbox\ListOfGroups +\newbox\ListOfNames + +\definelist[FileNames] \def\FileName {} +\definelist[FileGroups] \def\FileGroup {} +\definelist[GroupItems] \def\GroupItem {} + +\setuplist + [FileNames,FileGroups,FileGroups] + [expansion=yes, + pagenumber=no, + style=\ss\bf] + +\setuplist + [FileNames] + [command=\FileNameEntry, + after=\endgraf, + alternative=none] % horizontal + +\setuplist + [FileGroups] + [command=\FileGroupEntry, + after=\hss, + alternative=horizontal] + +\def\FileNameEntry#1#2#3% + {\strut\hbox{#2}\endgraf} + +\def\FileGroupEntry#1#2#3% + {\strut\hbox{#2}\endgraf} + +\def\MakeListOfItems + {\setbox\ListOfItems=\vbox + {\ss\bf + \placelist[GroupItems][color=ButtonKleur,contrastcolor=white,criterium=chapter]}} + +\def\MakeListOfNames + {\setbox\ListOfNames=\vbox + {\hsize\rightedgewidth + \ss\bf\setupinterlinespace + \startsimplecolumns[distance=10pt] + \placelist[FileNames][color=ButtonKleur,contrastcolor=white,criterium=chapter] + \stopsimplecolumns}} + +\def\MakeListOfGroups + {\setbox\ListOfGroups=\hbox to \textwidth + {\ss\bf + \setupinteraction[color=ButtonKleur]% + \placelist[FileGroups][color=ButtonKleur,contrastcolor=white,criterium=all]\unskip\unskip}} + +\setbox\ListOfGroups=\hbox{} + +%\setupfootertexts +% [rand] +% [] +% [{\interactiebalk[variant=g]}] + +\setupinteractionmenu + [right,bottom] + [state=start, + frame=off, + color=AchtergrondKleur, + contrastcolor=white, + style=\ss\bf, + height=15pt, + offset=0pt, + inbetween=\vskip5pt, + background=color, + backgroundcolor=ButtonKleur] + +\startinteractionmenu[right] + \boxofsize \vbox \textheight \footerdistance \footerheight 5pt + \bgroup + \copy\ListOfNames + \vfill + \but [\FileGroup:content] local contents \\ + \but [\FileName:index] local register \\ + \but [PaperVersion::begin] paper version \\ + \but [content] main contents \\ + \but [index] main register \\ + \but [PreviousJump] previous jump \\ + \but [CloseDocument] close document \\ + \unskip + \egroup +\stopinteractionmenu + +\startinteractionmenu[bottom] + \unhcopy\ListOfGroups +\stopinteractionmenu + +\def\placemoduleregister + {\startbackmatter + \setupsubpagenumber[reset] + \title[-:index]{Register} + \placeregister[index] + \stopbackmatter} + +\def\placemodulecontent + {\startfrontmatter + \title[-:content]{Contents} + \setupinteractionbar[state=stop] + \placecontent[criterium=text,level=chapter] + \stopfrontmatter} + +\setupcontent + [pagenumber=no, + level=chapter, + interaction=all, + style=, + before=, + after=] + +\setupfootertexts + [margin] + [\tt\Modulefile] + [] + +\setupfootertexts + [text] + [chapter][chapter] + +\setupindex + [symbol=1] + +\setuptolerance + [verytolerant] + +\endinput diff --git a/tex/context/base/s-mod.ctx b/tex/context/base/s-mod.ctx new file mode 100644 index 000000000..a85c991a5 --- /dev/null +++ b/tex/context/base/s-mod.ctx @@ -0,0 +1,24 @@ + + + + TeX Documentation Generator + + + mtxrun --script modules --convert --prep + + + + + + + + global + prep + + + + mod-01 + + + + diff --git a/tex/context/base/s-pre-00.tex b/tex/context/base/s-pre-00.tex new file mode 100644 index 000000000..7b22e2fd9 --- /dev/null +++ b/tex/context/base/s-pre-00.tex @@ -0,0 +1,202 @@ +%D \module +%D [ file=s-pre-00, +%D version=1997.07.22, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 0, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This module provides some non core functionality that can +%D be used in the presentations styles. This module contains +%D experimental macros. +%D +%D The presentation environments are independent of each other. +%D Although they have much in common, and in many cases can be +%D exchanged, the common components are not collected in this +%D file. That way they can serve as examples of style +%D definitions. + +\unprotect + +\newbox \presentationstack +\newcounter \presentationcounter +\newdimen \presentationheight + +\appendtoks\doglobal\newcounter\presentationcounter\to\everyshipout + +\defineframedtext + [presentationshield] + +\setupframedtexts + [presentationshield] + [\c!background=\v!color, + \c!backgroundcolor=StepColor, + \c!offset=\v!overlay, + \c!frame=\v!off] + +\definecolor[StepColor][white] + +\def\enablepresentationstep% + {\let\enablepresentationstep\relax + \useJSpreamblenow{presentation}% + \setuptexttexts + [\vbox to \textheight + {\dopresentationstep1\box\presentationstack\vfill}]} + +\def\presentationstep + {\dopresentationstep0} + +\def\dopresentationstep#1% not ok yet + {\global\setbox\presentationstack=\vbox + {\ifnum\presentationcounter=0 + \global\presentationheight=\!!zeropoint + \fi + \ifcase#1\relax + \scratchdimen=\pagetotal + \else + \scratchdimen=\textheight + \fi + \advance\scratchdimen by -\presentationheight + \edef\presentationstepheight{\the\scratchdimen} + \global\presentationheight=\pagetotal + \forgetall + \offinterlineskip + \dontcomplain + \box\presentationstack + \doglobal\increment\presentationcounter + \scratchcounter=\realpageno \multiply\scratchcounter by 100 + \advance\scratchcounter by \presentationcounter + \edef\presentationtag{presentation:\the\scratchcounter} + \setupfield + [presentation] + [\c!width=\v!fit,\c!height=\v!fit,\c!offset=\v!overlay, + \c!strut=\v!no,\c!frame=\v!off,\c!option=\v!readonly] + \definesymbol + [\presentationtag] + [\presentationshade] + \def\presentationshade + {\presentationshield + [\c!width=\textwidth,\c!height=\presentationstepheight]{}} + \definefield[\presentationtag][check][presentation][\presentationtag,\v!none][\presentationtag] + \fitfield[\presentationtag]}} + +\startJSpreamble {presentation} used later + var presentation = new Array() ; + for (i=1;i<=\lastpage;i++) + { presentation[i] = 0 } + this.dirty = false ; + function NextPresentation (pagenumber) + { % ++presentation[pagenumber] ; + presentation[pagenumber] = presentation[pagenumber] + 1 ; + var dummy = 100*pagenumber + presentation[pagenumber] ; + var v = this.getField("presentation:"+dummy) ; + if (v) + { v.hidden = true } + % { v.display = display.hidden } + else + { ++pagenumber ; + if (pagenumber<=\lastpage) + { presentation[pagenumber] = presentation[pagenumber] + 1 ; + dummy = 100*(pagenumber) + presentation[pagenumber] ; + v = this.getField("presentation:"+dummy) ; + if (v) { v.hidden = true } + % if (v) { v.display = display.hidden } + ++this.pageNum } } + this.dirty = false } +\stopJSpreamble + +\definereference[NextStep][JS(NextPresentation{\realfolio})] + +%D \macros +%D {presentationstep} +%D +%D The macro \type {\presentationstep} provides a basic slide +%D show functionality. It sort of records pieces of the page +%D that will show up stepwise. It can be used like: +%D +%D \starttyping +%D \startitemize +%D \item eerste +%D \item tweede +%D \stopitemize +%D +%D \presentationstep +%D +%D \startformula +%D ax^2+bx+c +%D \stopformula +%D +%D \presentationstep +%D \stoptyping +%D +%D When the document is opened, the two text fragments are +%D covered by a shield. Each page has its own shield stack. The +%D logical reference \type {NextStep} can be used to hide the +%D shield. +%D +%D \starttyping +%D \setupfootertexts[{\button{Show Up}[NextStep]}] +%D \stoptyping +%D +%D In case of presentation style 2, you can say: +%D +%D \starttyping +%D \definereference[Whatever][JS(NextPresentation{\realfolio})] +%D \stoptyping +%D +%D Depending of the viewer, you need to reset the fields at +%D startup: +%D +%D \starttyping +%D \setupinteraction[openaction=ResetForm] +%D \stoptyping +%D +%D Fixed spacing give you the best results: +%D +%D \starttyping +%D \setupwhitespace[fixed] +%D \setupblank[fixed] +%D \stoptyping +%D +%D Sometimes you need to set the color of the background, as +%D with style 2: +%D +%D \starttyping +%D \definecolor[StepColor][Page] +%D \stoptyping +%D +%D Special effects can be reached with: +%D +%D \starttyping +%D \setupframedtexts +%D [presentationshield] +%D [background=color,backgroundcolor=red] +%D \stoptyping +%D +%D There is also: +%D +%D \starttyping +%D \autopresentationsteptrue +%D \stoptyping +%D +%D One can enable this feature as \type {step} mode. + +\newif\ifautopresentationstep + +\appendtoks \ifautopresentationstep\presentationstep\fi \to \everypar + +\doifmode{step} {\enablepresentationstep} +\doifmode{autostep}{\autopresentationsteptrue\enablepresentationstep} + +%D When in \type {comment} mode, embedded page comments are +%D processed and put below the page. The default space of +%D 5cm should be adequate but can of course be changed. + +\doifmode{comment}{\setuppagecomment[state=start,location=bottom]} + +\protect \endinput diff --git a/tex/context/base/s-pre-01.tex b/tex/context/base/s-pre-01.tex new file mode 100644 index 000000000..b86133fa6 --- /dev/null +++ b/tex/context/base/s-pre-01.tex @@ -0,0 +1,404 @@ +%D \module +%D [ file=s-pre-01, +%D version=1997.07.22, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 1, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This environment can be used to typeset interactive +%D presentations. This module was first used at the 1997 \TUG\ +%D meeting. + +\usemodule[pre-general] + +%D \macros +%D {language} +%D +%D Because this module is defined in english, we default to the +%D english hyphenation patterns and labels too. + +\language + [en] + +%D \macros +%D {setupbodyfont,setuplayout} +%D +%D For screen reading, a Lucida Bright font looks nice. We use +%D a 14.4 point bodyfont for the main text, but switch back to +%D 12 points for ornaments. + +\startmode[asintended] \setupbodyfont[lbr] \stopmode + +\setupbodyfont[14.4pt] + +\setuplayout + [style=smallbodyfont] + +%D \macros +%D {setupcolors,definecolor} +%D +%D Screen presentations without color just look dull, so we +%D enable color support. We define ourselves a yellowish +%D backgroundcolor and a not too dark blue interactioncolor. + +\setupcolors + [state=start] + +\definecolor [BackgroundColor] [r=1, g=1, b=.7] +\definecolor [InteractionColor] [r=.1, g=.5, b=.8] +\definecolor [ContrastColor] [r=.9, g=.5, b=.2] + +%D \macros +%D {setuppapersize,setuplayout,setupinteractionscreen} +%D +%D +%D We use a nice large screen, and dedicate the right edge and +%D bottom part to navigational tools. We automatically set +%D the width and height of the page and start up full screen. + +\setuppapersize + [S6][S6] + +\setuplayout + [topspace=12pt, + header=0pt, + footer=0pt, + height=402pt, % 450 - 12 - 15 - 12 - 12 + 3 + bottomdistance=15pt, + bottom=12pt, + backspace=12pt, + margin=0pt, + width=fit, + edgedistance=12pt, + rightedge=96pt] + +\setupinteractionscreen + [option=max] + +%D \macros +%D {setupbackgrounds} +%D +%D We set the pagecolor to yellow except the part of the screen +%D that is used to display the running text. By seting the +%D offset to 3pt the text will not touch the yellow parts. We +%D do not set the depth. + +\setupbackgrounds + [page] + [background=color, + backgroundcolor=BackgroundColor, + offset=3pt] + +\setupbackgrounds + [text][text] + [background=color, + backgroundcolor=white] + +%D I considered the next setup too, but finaly decided to +%D comment it out. +%D +%D \starttyping +%D \setupbackgrounds +%D [bottom][text] +%D [frame=on, +%D framecolor=white] +%D \stoptyping + +%D \macros +%D {setupinteraction} +%D +%D We did not enable interactive text support yet, so let's do +%D that now. We force page reference to circumvent problems +%D with named destinations in buggy viewers. + +\setupinteraction + [page=yes, + color=InteractionColor, + contrastcolor=ContrastColor, + menu=on, + state=start] + +%D \macros +%D {setupinteractionmenu,startinteractionmenu} +%D +%D At the bottom of the screen we show two navigational bars. +%D At the left we show the subpage bar, at the right we use a +%D non default backward|/|forward bar. + +\setupinteractionmenu + [bottom] + [leftoffset=-3pt, + rightoffset=-3pt] + +\startinteractionmenu[bottom] + \txt \InteractionBar \\ + \txt \InteractionButtons \\ +\stopinteractionmenu + +%D \macros +%D {interactionbar} +%D +%D The left bar gets a white border (on the yellow background). +%D Because we don't want to typeset an empty frame when no +%D subpage bar is shown, we check for the number of subpages. + +\def\InteractionBar% + {\ifnum\nofsubpages>1 + \framed + [framecolor=white,rulethickness=1pt, + height=\bottomheight,strut=no] + {\interactionbar[alternative=f,width=.5\makeupwidth,height=1ex]} + \fi} + +%D \macros +%D {setupinteractionbar, interactionbuttons} +%D +%D The right hand buttons enable us to jump backward and forward, +%D as well as to the previous and next jump. We also enable to +%D close the presentation. + +\setupinteractionbar + [framecolor=white,rulethickness=1pt, + height=\bottomheight,strut=no] + +\def\InteractionButtons% + {\interactionbuttons + [width=15em] + [PreviousJump,NextJump, + firstpage, + firstsubpage,previouspage,nextpage,lastsubpage, + lastpage, + CloseDocument]} + +%D \macros +%D {StartTitlePage, TitlePage} +%D +%D The titlepage is rather simple and can be typeset in two +%D ways: +%D +%D \starttyping +%D \StartTitlePage +%D text \\ text \\ text +%D \StopTitlepage +%D \stoptyping +%D +%D or more straightforward: +%D +%D \starttyping +%D \TitlePage{text\\text\\text} +%D \stoptyping +%D +%D The first alternative can be used for more complicated +%D title pages. + +\def\StartTitlePage% + {\startstandardmakeup + \bfd\setupinterlinespace + \setupalign[middle] + \vfil + \let\\=\vfil} + +\def\StopTitlePage% + {\vfil\vfil\vfil + \stopstandardmakeup} + +\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +%D \macros +%D {TitlePage, Topics, Topic, Subject} +%D +%D A presentation after loading this module looks like: +%D +%D \starttyping +%D \TitlePage {About Whatever\\Topics} +%D +%D \Topics {Todays Talk} +%D +%D \Topic {Some topic} +%D +%D \Subject {Alfa} +%D +%D ..... +%D +%D \Subject {Beta} +%D +%D ..... +%D \stoptyping + +%D \macros +%D {definehead} +%D +%D The commands \type{\Topic} and \type{\Subject} are defined +%D as copies of head. We use \type{\Nopic} for internal +%D purposes. + +\definehead [Topic] [chapter] +\definehead [Subject] [section] + +\definehead [Nopic] [title] + +%D \macros +%D {setuphead} +%D +%D Because chapters and sections do not make sense in +%D presentations, we use our own command for typesetting the +%D titles. Sectionnumbers are of course hidden from viewing. +%D Each topic is followed by a list of subjects that belong +%D to the topic. + +\setuphead + [Topic, Nopic, Subject] + [command=\HeadLine, + page=yes, + style=\tfb, + after=\blank, + sectionnumber=no] + +\setuphead + [Topic] + [after=\PlaceSubjectList] + +\setuphead + [Subject] + [continue=no] + +%D \macros +%D {framed, midalined} +%D +%D The command used to typeset the head lines is rather simple. +%D We just center the framed title. The frame macro optimizes +%D the alignment and at the same time enables us to typeset a +%D nice colored rule. + +\def\HeadLine#1#2% + {\midaligned + {\framed + [framecolor=BackgroundColor,rulethickness=1pt, + width=.8\hsize,align=middle,strut=no] + {#2}}} + +%D \macros +%D {setuplist} +%D +%D The subject list is automatically placed. We center each +%D subject line by using one of the default alternatives (g). We +%D could have said: +%D +%D \starttyping +%D \setuplist +%D [Subject] +%D [alternative=none, +%D command=\SubjectListLine, +%D interaction=all] +%D +%D \def\SubjectListLine#1#2#3% +%D {\midaligned{#2}} +%D \stoptyping +%D +%D But why should we complicate things when we can use +%D alternative~\type{g}. The test is only needed if one +%D does not automatically goes a new page with each subject. + +\def\PlaceSubjectList% + {\blank + \determinelistcharacteristics[Subject] + % \ifnum\utilitylistlength>0 \placelist[Subject] \fi} + \doifmode{*list}{\placelist[Subject]}} + +\setuplist + [Subject, Topic] + [alternative=g, + interaction=all, + before=, + after=] + +% %D \macros +% %D {setuptexttexts} +% %D +% %D The topics will be listed in the right edge, using: +% +% \setuptexttexts +% [edge] +% [][\TopicList] + +%D \macros +%D {setuplist, placelist,startinteractionmenu} +%D +%D The actual topic list is typeset using a \type{\vbox}. We +%D have to specify \type{criteriumcriterium=all} because otherwise no +%D list will be typeset. (By default lists are typeset +%D locally.) + +\startinteractionmenu[right] + \placelist + [Topic] + [alternative=f, % command, % none, + maxwidth=\hsize, + width=\hsize, + offset=0pt, + criterium=all, + align=left, + style=\setsmallbodyfont\bfx] +\stopinteractionmenu + +\def\Topics#1% temporary hack + {\Nopic{#1} + \placelist[Topic][criterium=all]} + +\def\Subjects% + {} + +%D \macros +%D {setuptexttexts, button} +%D +%D During a presentation, we want to use the cursor to point to +%D parts of the text. Furthermore we want to be able to jump to +%D the next page, without the need to move the cursor on buttons. +%D Therefore we make the text part of the screen into an +%D invisible button. + +\setuptexttexts + [\GotoNextPage][] + +\def\GotoNextPage + {\button[width=\hsize,height=\vsize,frame=off]{}[nextpage]} + +%D \macros +%D {setupsubpagenumber} +%D +%D The left bottom navigation bar shows the subpages, which will +%D be counted by text. One can change this in the preentation +%D itself by saying \type {[way=byTopic]}. + +\setupsubpagenumber + [way=bytext, % Topic, + state=start] + +\doifnotmode{demo}{\endinput} + +%D The (rather silly) demo section. + +\starttext + +\TitlePage{Title Page\\pre-original} + +\Topics{Some Nice Quotes} + +\Topic{A Few} + +\Subject{Knuth} \input knuth +\Subject{Tufte} \input tufte + +\Topic{Some More} + +\Subject{Zapf} \input zapf +\Subject{Bryson} \input bryson + +\stoptext diff --git a/tex/context/base/s-pre-02.tex b/tex/context/base/s-pre-02.tex new file mode 100644 index 000000000..9df1fe383 --- /dev/null +++ b/tex/context/base/s-pre-02.tex @@ -0,0 +1,381 @@ +%D \module +%D [ file=s-pre-02, +%D version=1998.04.21, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 2, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This environment can be used to typeset interactive +%D presentations. This module was first used at the 1998 +%D publishers conference of the European Portable Document +%D Association (now merged into a graphics association). + +\usemodule[pre-general] + +%D \macros +%D {setupbodyfont, switchtobodyfont, setuplayout} +%D +%D At \PRAGMA\ we prefer using the Lucida Bright fonts, but +%D one can of course load another typeface. + +\startmode[asintended] \setupbodyfont[lbr] \stopmode + +\setupbodyfont[14.4pt] + +\setuplayout + [style=smallbodyfont] + +%D \macros +%D {setuppapersize, setuplayout} +%D +%D The papersize suits the screen dimensions. The layout is +%D rather simple. We use the whole width of the screen and only +%D have navigational tools at the bottom of the screen. + +\setuppapersize + [S6][S6] + +\setuplayout + [backspace=1cm, + topspace=1cm, + margin=0pt, + header=0pt, + footer=0pt, + bottomdistance=.875cm, + bottom=1cm, + width=fit, + height=fit] + +%D \macros +%D {setupwhitespace, setuptyping} +%D +%D We don't have much height, so we use a more cramped +%D spacing. Verbatim text looks better when indented. +%D + +\setupwhitespace + [medium] + +\setuptyping + [margin=standard] + +%D \macros +%D {definecolor, setupcolors} +%D +%D Of course we enable color. We define some logical colors, +%D of which most default to the same green shade. + +\definecolor [BackgroundColor] [r=.8, g=.8, b=.8] +\definecolor [OrnamentColor] [r= 0, g=.7, b=.4] + +\setupcolors + [state=start] + +%D \macros +%D {setupinteraction, setupinteractionscreen} +%D +%D We still have to enable interaction mode. We go full +%D screen! + +\setupinteraction + [state=start, + color=OrnamentColor, + contrastcolor=OrnamentColor] + +\setupinteractionscreen + [option=max, + width=fit, + height=fit] + +%D \macros +%D {setupitemize} +%D +%D And why not bring some color in itemizations too? + +\setupitemize + [color=OrnamentColor] + +%D \macros +%D {defineoverlay, setupbackgrounds} +%D +%D The navigational elements and the backgrounds are +%D provided by \METAPOST. +%D +%D When \METAPOST\ is used, it makes sense to generate the +%D graphics at runtime. This is supported when one enables +%D system calls in the local \type {texmf.cnf} file and add the +%D switch \type {\runMPgraphicstrue} to the local file \type +%D {cont-sys.tex}. When direct processing is disabled or not +%D supported, \TEXEXEC\ will take care of graphic generation. + +\startuniqueMPgraphic{PageBackground} + fill unitsquare + xyscaled(OverlayWidth,OverlayHeight) + withcolor OverlayColor ; + draw unitsquare + xyscaled(OverlayWidth,OverlayHeight) + enlarged (-2*OverlayLineWidth) + withpen pencircle scaled OverlayLineWidth + withcolor OverlayLineColor ; +\stopuniqueMPgraphic + +\defineoverlay + [PageBackground] + [\uniqueMPgraphic{PageBackground}] + +\setupbackgrounds + [page] + [background=PageBackground, + backgroundcolor=BackgroundColor, + rulethickness=.125cm, + framecolor=OrnamentColor] + +%D \macros +%D {setuptexttexts} +%D +%D By clicking on the text area, one goes to the next page. +%D We hook this feature into the text backgrounds. + +\startuniqueMPgraphic{TextBackground} + draw unitsquare + xyscaled(OverlayWidth,OverlayHeight) + enlarged (4*OverlayLineWidth) + withpen pencircle scaled OverlayLineWidth + withcolor OverlayLineColor ; +\stopuniqueMPgraphic + +\defineoverlay + [TextBackground] + [\uniqueMPgraphic{TextBackground}] + +\defineoverlay + [NextPage] + [\overlaybutton{nextpage}] + +\setupbackgrounds + [text] + [background={TextBackground,NextPage}, + backgroundcolor=BackgroundColor, + rulethickness=.0625cm, + framecolor=OrnamentColor] + +%D \macros +%D {setupinteractionmenu,startinteractionmenu} +%D +%D At the bottom of the screen, we show three buttons. These +%D direct us to the previous or next jump or exit the document. + +\setupMPvariables[RightArrow][height=\bottomheight] +\setupMPvariables[LeftArrow] [height=\bottomheight] +\setupMPvariables[Circle] [height=\bottomheight] +\setupMPvariables[UpArrow] [height=\bottomheight] + +\startuniqueMPgraphic{RightArrow}{height} + z1=(0,0) ; z2=(\MPvar{height},.5y3) ; z3=(0,\MPvar{height}) ; + drawfill z1--z2--z3--cycle + withpen pencircle scaled (\MPvar{height}/5) + withcolor \MPcolor{OrnamentColor} ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{LeftArrow}{height} + z1=(\MPvar{height},0) ; z2=(0,.5y3) ; z3=(\MPvar{height},\MPvar{height}) ; + drawfill z1--z2--z3--cycle + withpen pencircle scaled (\MPvar{height}/5) + withcolor \MPcolor{OrnamentColor} ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{Circle}{height} + drawfill fullcircle scaled \MPvar{height} + withpen pencircle scaled (\MPvar{height}/5) + withcolor \MPcolor{OrnamentColor} ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{UpArrow}{height} + z1=(0,0) ; z2=(\MPvar{height},0) ; z3=(.5x2,\MPvar{height}) ; + drawfill z1--z2--z3--cycle + withpen pencircle scaled (\MPvar{height}/5) + withcolor \MPcolor{OrnamentColor} ; +\stopuniqueMPgraphic + +\setupinteractionmenu + [bottom] + [state=start, + frame=off, + width=.3\textwidth, + height=\bottomheight] + +\setupinteraction + [menu=on] + +\def\WhateverButton + {\doifreferencefoundelse{Whatever} + {\raw [Whatever] \uniqueMPgraphic{UpArrow} \\} + {}} + +\startinteractionmenu[bottom] + \but [Topics] \\ % secret button + \hfill + \WhateverButton % user specific + \kern2\bottomheight + \raw [previouspage] \uniqueMPgraphic{LeftArrow} \\ + \kern.5\bottomheight + \raw [CloseDocument] \uniqueMPgraphic{Circle} \\ + \kern.5\bottomheight + \raw [nextpage] \uniqueMPgraphic{RightArrow} \\ + \kern.5\bottomheight +\stopinteractionmenu + +%D \macros +%D {TitlePage, Topics, Topic, Subject} +%D +%D A presentation after loading this module looks like: +%D +%D \starttyping +%D \TitlePage {About Whatever\\Topics} +%D +%D \Topics {Todays Talk} +%D +%D \Topic {Some topic} +%D +%D ..... +%D +%D \Topic {Next Topic} +%D +%D ..... +%D \stoptyping + +%D \macros +%D {StartTitlePage, TitlePage} +%D +%D The titlepage is rather simple and can be typeset in two +%D ways: +%D +%D \starttyping +%D \StartTitlePage +%D text \\ text \\ text +%D \StopTitlepage +%D \stoptyping +%D +%D or as one||liner: +%D +%D \starttyping +%D \TitlePage{text\\text\\text} +%D \stoptyping +%D +%D The first alternative can be used for more complicated +%D title pages. + +\def\StartTitlePage% + {\startstandardmakeup + \bfd\setupinterlinespace + \setupalign[middle] + \vfil + \let\\=\vfil} + +\def\StopTitlePage% + {\vfil\vfil\vfil + \stopstandardmakeup} + +\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +%D \macros +%D {definehead} +%D +%D The commands \type{\Topic} and \type{\Subject} are defined +%D as copies of head. We use \type{\Nopic} for internal +%D purposes. + +\definehead [Topic] [chapter] +\definehead [Subject] [section] + +\definehead [Nopic] [title] + +%D \macros +%D {setuphead} +%D +%D We use our own command for typesetting the titles. We hide +%D sectionnumbers from viewing. Each topic is followed by a +%D list of subjects that belong to the topic. + +\setuphead + [Topic, Nopic] + [after={\blank[3*medium]}, + number=no, + style=\tfb, + page=yes, + alternative=middle] + +\setuphead + [Subject] + [after=\blank, + number=no, + page=yes, + continue=no, + style=\tfa] + +%D \macros +%D {setuplist} +%D +%D When found, the subject list is automatically placed +%D after the topic head. + +\setuplist + [Topic,Subject] + [alternative=g, + interaction=all, + before=, + after=] + +\setuplist + [Topic] + [criterium=all] + +\def\Topics#1% + {\determinelistcharacteristics[Topic] + \doifmode{*list} + {\Nopic[Topics]{#1} + \startcolumns + \placelist[Topic] + \stopcolumns}} + +\setuplist + [Subject] + [criterium=Topic] + +\def\Subjects% + {\determinelistcharacteristics[Subject] + \doifmode{*list} + {\placelist[Subject]}} + +\setuphead + [Topic] + [after={\blank[3*medium]\Subjects}] + +\doifnotmode{demo}{\endinput} + +%D The (rather silly) demo section. + +\starttext + +\TitlePage{Title Page\\pre-green} + +\Topics{Some Nice Quotes} + +\Topic{A Few} + +\Subject{Knuth} \input knuth +\Subject{Tufte} \input tufte + +\Topic{Some More} + +\Subject{Zapf} \input zapf +\Subject{Bryson} \input bryson + +\stoptext diff --git a/tex/context/base/s-pre-03.tex b/tex/context/base/s-pre-03.tex new file mode 100644 index 000000000..bdd7960c5 --- /dev/null +++ b/tex/context/base/s-pre-03.tex @@ -0,0 +1,257 @@ +%D \module +%D [ file=s-pre-03, +%D version=1998.09.06, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 3, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This is the third environment for typesetting interactive +%D presentations. I used this style for a talk on \TEX\ and +%D \JAVASCRIPT\ at \TUG98, mainly because I didn't want to +%D use the same style three times. Therefore this is a rather +%D simple, silly style. + +\usemodule[pre-general] + +%D \macros +%D {setupbodyfont} +%D +%D We use a large bodyfont. Combined with the fancy +%D background, this does not leave that much room for text, but +%D presentations should use much text anyway. + +\startmode[asintended] \setupbodyfont[lbr] \stopmode + +\setupbodyfont[14.4pt] + +%D \macros +%D {setuppapersize,setuplayout,setupinteractionscreen} +%D +%D The page dimensions are set to size \type {S6}, being +%D 600pt by 450pt. We use wide margins and discard headers +%D and footers. We also launch the document full screen. + +\setuppapersize + [S6][S6] + +\setuplayout + [width=middle, + height=middle, + topspace=75pt, + backspace=100pt, + header=0pt, + footer=0pt] + +\setupinteractionscreen + [option=max] + +%D \macros +%D {setupcolors,definecolor} +%D +%D Next, color support is turned on and a dark red color is +%D defined. Other red shades will be derived from this one +%D color. + +\setupcolors + [state=start] + +\definecolor [PageColor] [black] +\definecolor [BackgroundColor] [s=.85] +\definecolor [OrnamentColor] [r=.75] + +%D \macros +%D {setupinteraction} +%D +%D We turn on interaction mode and use the same color for +%D hyperlinks and redundant hyperlinks (the ones that point +%D to the current page). + +\setupinteraction + [state=start, + contrastcolor=OrnamentColor, + color=OrnamentColor] + +%D \macros +%D {defineoverlay, setupbackgrounds} +%D +%D The joke in this presentation is the elliptical shape of +%D which the bottom part includes a page indication. + +\defineoverlay + [PageShape][\useMPgraphic{PageShape}] + +% \startuseMPgraphic{PageShape} +% lin := 20pt ; off := .75lin ; +% wid := \overlaywidth ; hei := \overlayheight ; +% pos := \currentpage ; tot := \lastpage ; +% path bb; bb := unitsquare xscaled wid yscaled hei ; +% filldraw bb withcolor \MPcolor{PageColor} ; +% pickup pencircle xscaled .5lin yscaled lin rotated 45 ; +% pair r, t, l, b ; +% r := (wid-off,.5hei) ; t := (.5wid,hei-off) ; +% l := (off,.5hei) ; b := (.5wid,off) ; +% path p; p := superellipse(r,t,l,b,.8) ; +% fill p withcolor \MPcolor{Backgroundcolor} ; +% draw p withcolor \MPcolor{OrnamentColor} ; +% color contrastcolor ; contrastcolor = 2/3 * \MPcolor{OrnamentColor} ; +% if (pos>0) and (tot>0): +% pair pa ; pa := point 5 of p ; +% pair pb ; pb := point 7 of p ; +% draw pa withcolor contrastcolor ; +% draw pb withcolor contrastcolor ; +% len := 2/tot ; +% pair pa ; pa := point (5+len*pos) of p ; +% pair pb ; pb := point (5+len*(pos-1)) of p ; +% p := p cutafter pa ; +% p := p cutbefore pb ; +% draw p withcolor contrastcolor ; +% fi ; +% setbounds currentpicture to bb ; +% \stopuseMPgraphic + +\startuseMPgraphic{PageShape} + StartPage ; + path p ; pair pa, pb ; numeric len ; color contrastcolor ; + fill Page withcolor \MPcolor {PageColor} ; + pickup pencircle rotated 45 xscaled 10pt yscaled 20pt ; + p := Page enlarged (-10pt,-15pt) superellipsed .8 ; + p := p shifted (-1.5pt,0) ; % looks better + fill p withcolor \MPcolor{BackgroundColor} ; + draw p withcolor \MPcolor{OrnamentColor} ; + contrastcolor = 2/3 * \MPcolor{OrnamentColor} ; + if (PageNumber>0) and (NOfPages>0): + draw point 5 of p withcolor contrastcolor ; + draw point 7 of p withcolor contrastcolor ; + len := 2/NOfPages ; + pa := point (5+len*PageNumber) of p ; + pb := point (5+len*(PageNumber-1)) of p ; + draw (p cutafter pa) cutbefore pb + withcolor contrastcolor ; + fi ; + StopPage ; +\stopuseMPgraphic + +%D We use the viewer provided feature to go to the previous or +%D next page. + +\defineoverlay[PrevButton][\overlaybutton{PreviousPage}] +\defineoverlay[NextButton][\overlaybutton{NextPage}] + +\setupbackgrounds + [page] + [background={PageShape,PrevButton}] + +\setupbackgrounds + [text][text] + [background=NextButton] + +% or using hard coded next/prev pages: +% +% \defineoverlay[PrevButton][\overlaybutton{previouspage}] +% \defineoverlay[NextButton][\overlaybutton{nextpage}] +% +% \setupbackgrounds[state=repeat] +% \setupbackground[text][text][background=NextButton] +% +% or simply (using an repeated layer): +% +% \setupbackground[text][background=NextButton] + +%D \macros +%D {definehead, setuphead} +%D +%D Like the other presentation styles, we use \type {\Topic} +%D instead of \type {\chapters}. This time we don't provide +%D an additional sectioning. So we have: +%D +%D \starttyping +%D \TitlePage{How nice} +%D +%D \Topics{This is about ...} +%D +%D \Topic{The first one} +%D +%D \Topic{Another one} +%D \stoptyping + +\definehead [Topic] [chapter] +\definehead [Nopic] [title] + +\setuphead + [Topic,Nopic] + [after={\blank[3*medium]}, + number=no, + style=\tfb, + page=yes, + alternative=middle] + +\setuplist + [Topic] + [alternative=g, + interaction=all, + before=, + after=] + +\def\Subject + {\Topic} + +%D The tables of contents is associated with \type +%D {\Topics}. + +\def\Topics#1% + {\Nopic[Topics]{#1} + \placelist[Topic][criterium=all]} + +\def\Subjects + {} + +%D Instead of \type {\TitlePage}, one can use the pair +%D \type {\StartTitlePage} -- \type {\StopTitlePage}: +%D +%D \starttyping +%D \StartTitlePage +%D A Self Made Title +%D \StopTitlePage +%D \stoptyping + +\def\StartTitlePage% + {\startstandardmakeup + \bfd\setupinterlinespace + \setupalign[middle] + \vfil + \def\\{\vfil\bfb\setupinterlinespace}} + +\def\StopTitlePage% + {\vfil\vfil\vfil + \stopstandardmakeup} + +\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +\doifnotmode{demo}{\endinput} + +%D The (rather silly) demo section. + +\starttext + +\TitlePage{Title Page\\pre-funny} + +\Topics{Some Nice Quotes} + +\Topic{A Few} + +\Subject{Knuth} \input knuth +\Subject{Tufte} \input tufte + +\Topic{Some More} + +\Subject{Zapf} \input zapf +\Subject{Bryson} \input bryson + +\stoptext diff --git a/tex/context/base/s-pre-04.tex b/tex/context/base/s-pre-04.tex new file mode 100644 index 000000000..09cc79b72 --- /dev/null +++ b/tex/context/base/s-pre-04.tex @@ -0,0 +1,377 @@ +%D \module +%D [ file=s-pre-04, +%D version=1998.09.06, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 4, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\usemodule[pre-general] + +%D \macros +%D {setupbodyfont} +%D +%D This is just another environment for typesetting interactive +%D presentations. I wrote this module on behalf of a course I +%D gave for the United Kingdom \TeX\ users group. + +\setupbodyfont[ams,pos,14.4pt] + +%D \macros +%D {setupcolors,definecolor} +%D +%D I started using dark blue for the navigational elements. In +%D that context, dark red is a logical choice for the contrast +%D color. While playing around with the navigational elements +%D I decided to use the not so dominant color yellow for the +%D status bar. +%D +%D A few days before I wrote this style, the recent acquisition +%D of Mondriaans last painting by the Dutch governement was a +%D hot topic in the dutch news scenary. Therefore I decided to +%D replace the rather dull title page by something more +%D colorful, in mondriaan colors, but far more random than any +%D of his paintings. For consistence we remap the already +%D defined primary colors. + +\setupcolors [state=start] + +\definecolor [NoneColor] [s=.6] +\definecolor [GotoColor] [b=.6] \definecolor[blue] [GotoColor] +\definecolor [ExitColor] [r=.6] \definecolor[red] [ExitColor] +\definecolor [JumpColor] [s=.6] +\definecolor [UserColor] [g=.6] \definecolor[green] [UserColor] +\definecolor [StepColor] [r=.6,g=.6] \definecolor[yellow][StepColor] + +\definecolor [PageColor] [s=.80] \definecolor[gray] [PageColor] +\definecolor [TextColor] [s=.90] + +%D \macros +%D {setuppapersize} +%D +%D As usual, we take a screen oriented paper size: + +\setuppapersize + [S6][S6] + +%D \macros +%D {setuplayout,setupinteractionscreen} +%D +%D The layout definition fits into this $600\times450$ point +%D area, but the dimensions are somewhat diffused by the text +%D background offset. + +\setuplayout + [width=530pt, + height=400pt, + header=0pt, + footer=0pt, + backspace=15pt, + topspace=15pt, + bottomdistance=15pt, + bottom=10pt, + margin=0pt, + rightedgedistance=15pt, + rightedge=30pt] + +\setupinteractionscreen + [option=max] + +%D \macros +%D {setupbackgrounds} +%D +%D Both the page and the text area have a gray background. +%D The \type {[text,text]} area also has an offset. Later we +%D will see that we have to compensate for that in the +%D navigational areas. + +\setupbackgrounds + [page] + [background=color, + backgroundcolor=PageColor] + +\setupbackgrounds + [text][text] + [background=color, + backgroundcolor=TextColor, + backgroundoffset=5pt] + +%D \macros +%D {setupinteraction} +%D +%D For convenient navigation, we turn on interaction. + +\setupinteraction + [state=start, + menu=on, + color=UserColor, + contrastcolor=NoneColor] + +%D \macros +%D {setupsubpagenumber} +%D +%D When navigating the document, we keep the title page out +%D of sight, therefore we use sub page numbers. + +\setupsubpagenumber + [state=start, + way=bytext] + +%D \macros +%D {setupinteractionmenu} +%D +%D There is only one interaction menu, located in the right +%D edge of the screen. Both offsets enlarge the edge by the +%D same amount as the text background offset. + +\setupinteractionmenu + [right] + [state=start, + frame=off, + strut=no, + offset=0pt, + inbetween=, + bottomoffset=-5pt, + topoffset=-5pt] + +%D \macros +%D {startinteractionmenu} +%D +%D The menu itself is not that spectacular. We use the +%D start||stop alternative for setting the content. The macro +%D \type {\interactioncolor} expands into either the +%D interaction color or the contrast color, the latter only +%D when no jump is possible. + +\startinteractionmenu[right] + \setupinteraction[color=GotoColor] + \but [previoussubpage] \Triangle {90}\framedwidth\interactioncolor \\ + \vskip10pt + \but [nextsubpage] \Triangle{270}\framedwidth\interactioncolor \\ + \vfill + \but [PreviousJump] \Triangle{180}\framedwidth{NoneColor} \\ + \vskip-5pt + \but [NextJump] \Triangle {0}\framedwidth{NoneColor} \\ +\stopinteractionmenu + +%D \macros +%D {setupinteractionbar} +%D +%D The interaction bar at the bottom is also larger than the +%D normal width of the bottom area. + +\setupinteractionbar + [alternative=f, + width=\textwidth, + height=\bottomheight, + distance=10pt, + color=NoneColor, + contrastcolor=StepColor] + +%D \macros +%D {setupbottomtexts} +%D +%D The bar is centered in the middle. + +\setupbottomtexts + [\interactionbar] + +%D We can exit viewing with a close button, located on the +%D rightmost bottom area. + +\def\CloseButton + {\button + [width=\rightedgewidth,height=\bottomheight,offset=overlay, + background=color,backgroundcolor=ExitColor,frame=off] + {}% + [CloseDocument]} + +\setupbottomtexts + [edge][][\CloseButton] + +%D \macros +%D {definesymbol,setupitemize} +%D +%D Because some prominent things are rectangular or triangular, +%D we prefer some different symbols in itemizations: + +\definesymbol[1][$\blacktriangleright$] +\definesymbol[2][$\blacktriangledown$] +\definesymbol[3][$\blacktriangleright$] +\definesymbol[4][$\blacktriangledown$] + +\setupitemize[each][color=NoneColor] + +%D \macros +%D {TitlePage,defineoverlay,button,setupalign, +%D setupbackgrounds,setupinteraction,setupinteractionbar, +%D startstandardmakeup,switchtobodyfont,setupinterlinespace} +%D +%D Now the main layout and navigational definitions are +%D done, it makes sense to define and tune some structuring +%D commands. First we build the titlepage. + +\defineoverlay [TitleGraphic] [\useMPgraphic{title}] +\defineoverlay [NextPage] [\overlaybutton{nextpage}] + +\def\StartTitlePage + {\setupbackgrounds[page][background={color,TitleGraphic,NextPage}] + \setupbackgrounds[text][text][background=] + \setupinteraction[menu=off] + \setupinteractionbar[state=stop] + \startstandardmakeup + \switchtobodyfont[24pt] + \bfd\setupinterlinespace + \setupalign[middle] + \vfil + \let\\=\vfil} + +\def\StopTitlePage + {\vfil\vfil\vfil + \stopstandardmakeup + \setupinteraction[menu=on] + \setupinteractionbar[state=start] + \setupbackgrounds[page][background=color] + \setupbackgrounds[text][text][background=color] + \setupsubpagenumber[reset]} + +\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +%D \macros +%D {Topic, Nopic, Subject, +%D definehead, setuphead} +%D +%D We use \type {\Topic} and \type {\Subject} instead of +%D chapters and sections. The \type {\Nopic} alternative is +%D meant for internal use. + +\definehead [Topic] [chapter] +\definehead [Nopic] [title] +\definehead [Subject] [section] + +\setuphead + [Topic, Nopic] + [after={\blank[3*medium]}, + number=no, + style=\tfb, + page=yes, + alternative=middle] + +\setuphead + [Subject] + [after=\blank, + number=no, + page=yes, + continue=no, + style=\tfa] + +%D \macros +%D {Topics, Subjects, +%D setuplist, placelist, startcolumns} +%D +%D This style is meant for the more large presentations, and +%D therefore provided for a list of topics as well as local +%D lists of subjects. When many topics are introduces, the +%D list is typeset in columns. + +\setuplist + [Topic,Subject] + [alternative=g, + interaction=all, + before=, + after=] + +\setuplist + [Topic] + [criterium=all] + +\def\Topics#1% + {\determinelistcharacteristics[Topic] + \ifnum\utilitylistlength>0 + \Nopic[Topics]{#1} + \ifnum\utilitylistlength>12 + \startcolumns + \placelist[Topic] + \stopcolumns + \else + \placelist[Topic] + \fi + \fi} + +\def\Subjects% + {\placelist[Subject]} + +%D Last we define the overlays. Look at the way colors are +%D linked into the macros. + +\startMPinclusions + def triangle (expr wid, rot, col) = + x1 := x3 := y1 := 0 ; x2 := y3 := wid ; y2 := .5y3 ; + fill (z1--z2--z3--cycle) rotated rot withcolor col ; + currentpicture := currentpicture xysized (wid,wid) ; + enddef ; +\stopMPinclusions + +\setupMPvariables + [triangle] + [width=1cm, + rotation=0, + color=black] + +\startuniqueMPgraphic{triangle}{width,rotation,color} + triangle(\MPvar{width},\MPvar{rotation},\MPvar{color}) ; +\stopuniqueMPgraphic + +\def\Triangle#1#2#3% + {\uniqueMPgraphic{triangle}{rotation=#1,width=#2,color=#3}} + +\startuseMPgraphic{title} % can be simplified with "randomized" + color c ; path p ; + for i=1 upto 250 : + x0 := uniformdeviate \overlaywidth ; + y0 := uniformdeviate \overlayheight ; + sx := uniformdeviate 20 ; + sy := uniformdeviate 20 ; + cc := round(uniformdeviate 2) ; + if cc=0 : c := \MPcolor{GotoColor} fi ; + if cc=1 : c := \MPcolor{ExitColor} fi ; + if cc=2 : c := \MPcolor{StepColor} fi ; + qq := round(uniformdeviate 1) ; + if qq=0 : + p := unitsquare xscaled sx yscaled sy ; + else : + rr := round(uniformdeviate 3) * 90 ; + x1 := x3 := y1 := 0 ; x2 := y3 := sx; y2 := .5y3 ; + p := (z1--z2--z3--cycle) rotated rr ; + fi ; + fill p shifted z0 withcolor c ; + endfor ; +\stopuseMPgraphic + +\doifnotmode{demo}{\endinput} + +%D The (rather silly) demo section. + +\starttext + +\TitlePage{Title Page\\pre-colorfull} + +\Topics{Some Nice Quotes} + +\Topic{A Few} + +\Subject{Knuth} \input knuth +\Subject{Tufte} \input tufte + +\Topic{Some More} + +\Subject{Zapf} \input zapf +\Subject{Bryson} \input bryson + +\stoptext diff --git a/tex/context/base/s-pre-05.tex b/tex/context/base/s-pre-05.tex new file mode 100644 index 000000000..9b3ae89ff --- /dev/null +++ b/tex/context/base/s-pre-05.tex @@ -0,0 +1,240 @@ +%D \module +%D [ file=s-pre-05, +%D version=1998.12.12, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 5, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\usemodule[pre-general] + +%D As all styles sofar, this one has the same structuring +%D commands. + +\startmode[asintended] \setupbodyfont[lbr] \stopmode + +\setupbodyfont[14.4pt] + +\setupcolors [state=start] + +\definecolor [BackgroundColor] [s=.95] +\definecolor [OrnamentColor] [r=.6,g=.7,b=.8] + +\setuppapersize + [S6][S6] + +\setuplayout + [width=430pt, + height=400pt, + header=0pt, + footer=0pt, + margin=0pt, + backspace=25pt, + topspace=25pt, + rightedgedistance=20pt, + rightedge=110pt] + +\setupinteractionscreen + [option=max] + +\setupbackgrounds + [state=repeat] + +\setupbackgrounds + [page] + [backgroundcolor=white] + +\setupbackgrounds + [text][text] + [background={HashFrameA,NextPage}, + backgroundoffset=20pt] + +\defineoverlay + [HashFrameA] + [\useMPgraphic{HashFrameA}] + +\defineoverlay + [HashFrameB] + [\useMPgraphic{HashFrameB}] + +\setupinteraction + [state=start, + menu=on, + color=OrnamentColor, + contrastcolor=OrnamentColor] + +%D Watch how we use a list alternative that matches the +%D menu. + +\setupinteractionmenu + [right] + [background=HashFrameB, + style=smallbold, + frame=off, + offset=10pt, + height=35pt, + before=, + after=, + inbetween=\endgraf, + width=\rightedgewidth] + +\startinteractionmenu[right] + \placelist + [Topic] + [criterium=all, + alternative=right, + maxwidth=.8\rightedgewidth, + interaction=all, + before=, + after=] + \vfill + \setupinteractionmenu + [right] + [height=30pt] + \but [CloseDocument] Close \\ +\stopinteractionmenu + +\setupwhitespace + [big] + +\setupblank + [big] + +%D \macros +%D {TitlePage} +%D +%D Now the main layout and navigational definitions are +%D done, it makes sense to define and tune some structuring +%D commands. First we build the titlepage. + +\defineoverlay [TitleGraphic] [\useMPgraphic{TitleGraphic}] +\defineoverlay [NextPage] [\overlaybutton{forward}] + +\def\StartTitlePage% + {\setupbackgrounds[page][background={color,TitleGraphic,NextPage}] + \setupbackgrounds[text][text][background=] + \setupinteraction[menu=off] + \setupinteractionbar[state=stop] + \setuplayout[width=550pt,rightedge=0pt] + \startstandardmakeup + \switchtobodyfont[24pt] + \bfd\setupinterlinespace + \setupalign[middle] + \vfil + \let\\=\vfil} + +\def\StopTitlePage% + {\vfil\vfil\vfil + \stopstandardmakeup + \setuplayout[width=430pt,rightedge=110pt] + \setupinteraction[menu=on] + \setupinteractionbar[state=start] + \setupbackgrounds[page][background=color] + \setupbackgrounds[text][text][background={HashFrameA,NextPage}]} + +\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +%D \macros +%D {Topics,Subjects} +%D +%D Since the lists are in the menu, we don't honor list +%D placement macros. + +\def\Topics#1{} +\def\Subjects{} + +%D \macros +%D {Topic, Nopic, Subject} +%D +%D Since t his style is meant for rather flat structured +%D documents, only \type {\Topic} makes sense. + +\definehead [Topic] [chapter] +\definehead [Nopic] [title] +\definehead [Subject] [section] + +\setuphead + [Topic, Nopic] + [after={\blank[3*medium]}, + number=no, + style=\tfb, + page=yes, + alternative=middle] + +\setuphead + [Subject] + [after=\blank, + number=no, + page=yes, + continue=no, + style=\tfa] + +%D We use only one kind of base graphic, which is sligthly +%D tuned for the different usage. + +\startMPinclusions + def random_hash_frame (expr width, height, offset, linewidth ) = + + def delta = ((uniformdeviate .5offset) + .25offset) enddef ; + x1 := offset ; y1 := offset ; x2 := width-offset ; y2 := height-offset ; + + drawoptions(withpen pencircle scaled linewidth withcolor \MPcolor{BackgroundColor}) ; + fill z1--(x2,y1)--z2--(x1,y2)--cycle ; + + drawoptions(withpen pencircle scaled linewidth withcolor \MPcolor{OrnamentColor}) ; + draw (x1-delta,y1)--(x2+delta,y1) ; + draw (x2,y1-delta)--(x2,y2+delta) ; + draw (x2+delta,y2)--(x1-delta,y2) ; + draw (x1,y2+delta)--(x1,y1-delta) ; + + drawoptions(); + setbounds currentpicture to unitsquare xscaled width yscaled height ; + enddef ; +\stopMPinclusions + +\startuseMPgraphic{HashFrameA} + random_hash_frame(OverlayWidth,OverlayHeight,15pt,2pt) ; +\stopuseMPgraphic + +\startuseMPgraphic{HashFrameB} + random_hash_frame(OverlayWidth,OverlayHeight, 5pt,2pt) ; +\stopuseMPgraphic + +\startuseMPgraphic{TitleGraphic} + for i=1 upto 300 : + offset := uniformdeviate 10pt ; + width := 2*offset + 30pt + uniformdeviate 30pt ; + height := 2*offset + 10pt + uniformdeviate 10pt ; + addto currentpicture also + image(random_hash_frame(width,height,offset,1pt)) shifted + (uniformdeviate OverlayWidth, uniformdeviate OverlayHeight) ; + endfor ; +\stopuseMPgraphic + +\doifnotmode{demo}{\endinput} + +%D The (rather silly) demo section. + +\starttext + +\TitlePage{Title Page\\pre-fuzzy} + +\Topics{Some Nice Quotes} + +\Topic{A Few} + +\Subject{Knuth} \input knuth +\Subject{Tufte} \input tufte + +\Topic{Some More} + +\Subject{Zapf} \input zapf +\Subject{Bryson} \input bryson + +\stoptext diff --git a/tex/context/base/s-pre-06.tex b/tex/context/base/s-pre-06.tex new file mode 100644 index 000000000..7a84323e9 --- /dev/null +++ b/tex/context/base/s-pre-06.tex @@ -0,0 +1,325 @@ +%D \module +%D [ file=s-pre-06, +%D version=1999.04.28, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 6, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D I wrote this sixth presentation style on behalf of a +%D presentation at Bachotek~'99. The joke in this style is +%D (ab)using the Antikwa Torunska, a rather Polish font. When I +%D was first confronted with this font, the backward slant +%D stoke me as very characteristic. +%D +%D Each page has a slightly different background consisting of +%D three O's. Although \TEX\ could do the randomization, +%D scaling and placement, I prefered to use \METAPOST. The +%D backward slant is also reflected in the stepwise increasing +%D left margin. Due to this characteristic and the trick used, +%D this style is only suited for simple presentations, using +%D itemizations. + +\usemodule[pre-general] + +%D \macros +%D {setupbodyfont} +%D +%D As said, we will use the Antikwa Torunska, and because we +%D want it to show up well, we use it large. + +\setupbodyfont + [ant,14.4pt] + +%D \macros +%D {definecolor, setupcolors} +%D +%D Thus style only uses gray scales, but nevertheless we turn +%D on color. We only use a few logical color names. + +\setupcolors + [state=start] + +\definecolor [BackgroundColor] [s=.8] +\definecolor [ContrastColor] [s=.9] +\definecolor [InteractionColor] [s=.6] + +%D \macros +%D {setuppapersize} +%D +%D As (nearly) always, we use a 600 pt times 450 pt screen +%D width, mapped on ditto paper dimensions. + +\setuppapersize + [S6][S6] + +%D \macros +%D {setuplayout} +%D +%D The layout is rather symmetrical. We don't use headers and +%D footers, and thereby automatically turn off the page +%D numbering: no room, no number. We use the bottom to present +%D a rather trivial menu. + +\setuplayout + [backspace=2cm, + topspace=2cm, + width=middle, + header=0pt, + height=middle, + footer=0pt, + bottomdistance=.5cm, + bottom=1cm] + +%D \macros +%D {setupinteractionmenu,startinteractionmenu} +%D +%D This menu is slighly moved to the right because that looks +%D better. The menu itself has one goto (\type {\got}) entry, +%D which is forced to the right. + +\setupinteractionmenu + [bottom] + [rightoffset=-1cm] + +\startinteractionmenu[bottom] + \hfill \got [CloseDocument] \bfd Quit \\ +\stopinteractionmenu + +%D \macros +%D {setupbackgrounds} +%D +%D Page background are calculated at each page, opposite to the +%D other backgrounds, that are reused and only calculated when +%D \CONTEXT\ is explictly told to do so. There are three +%D overlays: a gray fill, the graphic, and a button that +%D circulates the pages. + +\setupbackgrounds + [page] + [background={color,Joke,GoAround}, + backgroundcolor=BackgroundColor] + +%D \macros +%D {defineoverlay} +%D +%D The \type {forward} reference action circulates over the +%D pages, so, at the last page, we are led back to the first. + +\defineoverlay [GoAround] [\overlaybutton{forward}] + +%D The joke is a simple \METAPOST\ routine. The picture is +%D actually larger than the screen, but is clipped of when +%D included. + +\defineoverlay [Joke] [\useMPgraphic{background}] + +\startuseMPgraphic{background} + input mp-tool ; + width := \overlaywidth ; + height := \overlayheight ; + picture p ; p := char 79 infont "\truefontname{Regular}" scaled 1 ; + pwidth := xpart urcorner bbox p - xpart llcorner bbox p ; + pheight := ypart urcorner bbox p - ypart llcorner bbox p ; + def do (expr r) = + addto currentpicture also p shifted - center p scaled r + xscaled (width/pwidth) yscaled (height/pheight) + withcolor \MPcolor{ContrastColor} ; + enddef ; + do (0.9+uniformdeviate0.1) ; + do (1.4+uniformdeviate0.1) ; + do (1.9+uniformdeviate0.1) ; +\stopuseMPgraphic + +%D \macros +%D {setupinteraction,setupinteractionscreen} +%D +%D We did not yet turn on the interaction, so let's do that +%D now. When opened, the document will fil the screen. + +\setupinteraction + [state=start, + color=InteractionColor, + contrastcolor=InteractionColor, + menu=on] + +\setupinteractionscreen + [option=max] + +%D \macros +%D {TitlePage, Topics, Topic} +%D +%D A presentation normally consists of a title page, a list of +%D topics, and the content itself. In this style, a further +%D subdivision does not make sense, but because we want to be +%D compatible with the other styles, they are added. A +%D presentation looks like: +%D +%D \starttyping +%D \usemodule[pre-antikwa] +%D +%D \startext +%D +%D \TitlePage{The Title} +%D +%D \Topics{Contents} +%D +%D \Topic{Some Topic} +%D +%D \startitemize +%D \item first +%D \item second +%D \stopitemize +%D +%D \Topic{Some Topic} +%D +%D ... +%D +%D \stoptext +%D \stoptyping + +%D \macros +%D {definehead, Topic, Subject} +%D +%D We use dedicated sectioning commands. + +\definehead [Topic] [chapter] +\definehead [Subject] [section] + +\definehead [Nopic] [title] + +%D \macros +%D {setuphead} +%D +%D We turn of numbering. The assignment to \type {after} takes +%D care of the increasing indentation. This indentation is the +%D only low level \TEX\ code needed. Including this +%D functionality in the core of \CONTEXT\ is not that useful +%D and I would forget about this feature being present anyway. + +\setuphead + [Topic, Nopic, Subject] + [number=no, + after={\blank[2*big]\ToTheLeft\everypar{\ToTheRight}}] + +%D After section titles we set the \type {\leftskip} to a value +%D that suits the Antikwa slant. + +\def\ToTheLeft% + {\gdef\LeftSkip{30}% + \rightskip0pt\relax + \leftskip30pt\relax} + +%D Each new paragraph adds to the \type {\leftskip}. + +\def\ToTheRight% + {\doglobal\increment(\LeftSkip,20)% + \leftskip=\LeftSkip pt\relax} + +%D \macros +%D {Topics} +%D +%D The \type {\Topics} command uses a bot of low level +%D \CONTEXT. We could have done with: +%D +%D \starttyping +%D \def\Topics#1% +%D {\Nopic[Topics]{#1} +%D \placelist[Topic][criteriumcriterium=all]} +%D \stoptyping +%D +%D but the next alternative sort of ignores this command when +%D no list is found. + +\def\Topics#1% + {\determinelistcharacteristics[Topic] + \ifcase\utilitylistlength\else + \Nopic[Topics]{#1} + \placelist[Topic][criterium=all] + \fi} + +%D \macros +%D {setuplist} +%D +%D We use the single item command to achieve a result similar +%D to the itemizations. + +\setuplist + [Topic] + [alternative=command, + command=\TopicListCommand] + +\def\TopicListCommand#1#2#3% + {\item#2\par} + +%D A dummy command, needed to be compatible with the other +%D presentation styles. + +\def\Subjects% + {} + +%D \macros +%D {StartTitlePage} +%D +%D We use a nested \type {\everypar}; everything in there +%D will be put in front of each paragraph. The nesting prevents +%D the first paragraph from indenting. The struts give the +%D lines a decent height, which looks better inrelation to the +%D next pages. + +\def\StartTitlePage% + {\startstandardmakeup + \bfd\setupinterlinespace + \everypar{\everypar{\advance\leftskip30pt\relax}} + \let\\=\blank + \begstrut} + +\def\StopTitlePage% + {\endstrut + \vfill + \stopstandardmakeup} + +%D \macros +%D {TitlePage} +%D +%D The title page can be generated with one command: + +\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +\doifnotmode{demo}{\endinput} + +%D The (rather silly) demo section. + +\usemodule[pre-antikwa] + +\starttext + +\TitlePage{Title Page\\pre-polish} + +\Topics{Some Nice Lists} + +\Topic{Some Lists} + +\Subject{A list} + +\startitemize +\item first +\item second +\stopitemize + +\Subject{A bigger list} + +\startitemize +\item first +\item second +\item third +\item fourth +\stopitemize + +\stoptext diff --git a/tex/context/base/s-pre-07.tex b/tex/context/base/s-pre-07.tex new file mode 100644 index 000000000..bf84971bb --- /dev/null +++ b/tex/context/base/s-pre-07.tex @@ -0,0 +1,212 @@ +%D \module +%D [ file=s-pre-07, +%D version=1999.08.20, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 7, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This style was made for the \NTS\ presentation at +%D \EUROTEX\ 1999. It's a wink to programming in a webbed way. +%D This is just one way of implementing such a style. Today +%D we have more \METAPOST\ interfacing available, and +%D thereby moore tools and alternative ways to reach such a +%D goal. I must admit that the main macro looks fuzzy. On +%D the other hand, the presentation can look quite structured. +%D +%D \starttyping +%D \Topics{...} +%D +%D \StartIdeas +%D \Topic{...} +%D \StartIdea ... \StopIdea +%D \StartIdea ... \StopIdea +%D \StopIdeas +%D \stoptyping + +\startmode[asintended] \setupbodyfont[lbr] \stopmode + +\setupbodyfont[14.4pt] + +\usemodule + [abr-02] + +\setuppapersize + [S6][S6] + +\setuplayout + [topspace=0cm, + backspace=0cm, + header=0pt, + footer=0pt, + width=middle, + height=middle] + +\setupinteractionscreen + [option=max] + +%D In order to prevent loops due to random placement, we +%D keep the random seed reasonable constant. + +\setupsystem + [random=big] + +\setupcolors + [state=start] + +\definecolor[gray] [s=.4] +\definecolor[lightgray][s=.9] + +\definecolor[red] [r=.4] \definecolor[cyan] [g=.4,b=.4] +\definecolor[green][g=.4] \definecolor[magenta][r=.4,b=.4] +\definecolor[blue] [b=.4] \definecolor[yellow] [r=.4,g=.4] + +\definecolor[PageColor][gray] +\definecolor[TextColor][lightgray] +\definecolor[LineColor][yellow] + +\definecolor[linecolor 1][red] \definecolor[linecolor 5][cyan] +\definecolor[linecolor 2][green] \definecolor[linecolor 6][magenta] +\definecolor[linecolor 3][blue] \definecolor[linecolor 4][yellow] + +\setupinteraction + [state=start, + display=new, + color=LineColor, + contrastcolor=LineColor] + +\startuseMPgraphic{shape} + path p ; color c, w ; numeric width, height ; + c := \MPcolor{LineColor} ; w := \MPcolor{TextColor} ; + width := \overlaywidth ; height := \overlayheight ; + pickup pencircle scaled .5cm ; + p := unitcircle + xscaled \MPw{\Idea} yscaled \MPh{\Idea} + shifted \MPxy{\Idea} ; + for z = (0,.5height), (width,.5height), (.5width,0), (.5width,height), + (0,0), (width,height), (0,height), (width,0) : + draw center p -- z withcolor c ; + endfor ; + fill p withcolor w ; + draw p withcolor c ; + p := unitcircle + xscaled \MPw{\Page} yscaled \MPh{\Page} + shifted \MPxy{\Page} ; + pickup pencircle scaled .25cm ; + fill p withcolor w ; + draw p withcolor c ; + draw unitsquare xscaled width yscaled height withcolor c ; +\stopuseMPgraphic + +\defineoverlay [shape] [\useMPgraphic{shape}] +\defineoverlay [nextpage] [\overlaybutton{nextpage}] +\defineoverlay [previouspage] [\overlaybutton{previouspage}] +\defineoverlay [content] [\overlaybutton{content}] +\defineoverlay [forward] [\overlaybutton{forward}] + +\setupbackgrounds + [page] + [background={color,previouspage,shape}, + backgroundcolor=PageColor] + +\def\StartIdea% + {\xdef\Idea{idea:\realfolio} + \xdef\Page{page:\realfolio} + \startstandardmakeup + \dontcomplain + \vbox to \makeupheight \bgroup + \getrandomdimen\scratchdimen{75pt}{600pt}\vskip 0pt plus \scratchdimen + \hbox to \makeupwidth \bgroup + \getrandomdimen\scratchdimen{75pt}{600pt}\hskip 0pt plus \scratchdimen + \hpos{idea:\realfolio} \bgroup + \framed + [width=.6\hsize,height=fit,offset=2cm,align=middle, + frame=off,strut=no,background=forward] + \bgroup + \setupwhitespace[big]} + +\def\StopIdea% + {\egroup + \egroup + \getrandomdimen\scratchdimen{75pt}{600pt}\hskip 0pt plus \scratchdimen + \egroup + \getrandomdimen\scratchdimen{75pt}{600pt}\vskip 0pt plus \scratchdimen + \egroup + \ifx\CurrentTopic\empty \else + \vskip-\makeupheight + \vbox to \makeupheight + {\vfill + \ifx\CurrentListTopic\empty\else + \writetolist[Topic]{}{\CurrentListTopic} + \fi + \hbox to \makeupwidth + {\hfill + \hpos{page:\realfolio} + {\framed + [offset=.5cm,frame=off,background=content] + {\bf\ignorespaces\CurrentTopic\unskip}}% + \hskip.5cm} + \vskip.5cm} + \fi + \stopstandardmakeup + \let\CurrentListTopic\empty} + +\definelist + [Topic] + +\setuplist + [Topic] + [alternative=f, + expansion=command] + +\let\CurrentTopic\empty +\let\CurrentListTopic\empty + +\long\def\StartTopic#1\StopTopic + {\long\def\CurrentTopic{#1} + \let\CurrentListTopic\CurrentTopic} + +\def\Topic#1% + {\StartTopic#1\StopTopic} + +\def\Topics#1% + {\StartIdeas + \def\CurrentTopic{#1} + \StartIdea + \pagereference[content] + \placelist[Topic][criterium=all] + \StopIdea + \StopIdeas} + +\newcounter\CurrentIdeas + +\def\StartIdeas% + {\ifnum\CurrentIdeas=6 \doglobal\newcounter\CurrentIdeas \fi + \doglobal\increment\CurrentIdeas + \definecolor[LineColor][linecolor \CurrentIdeas]} + +\def\StopIdeas% + {} + +\doifnotmode{demo}{\endinput} + +%D The (rather silly) demo section. + +\starttext + +\Topics{This is about \unknown} + +\StartIdeas + \Topic{Some topic} + \StartIdea An idea \unknown \StopIdea + \StartIdea \unknown\ and another \StopIdea +\StopIdeas + +\stoptext + + diff --git a/tex/context/base/s-pre-08.tex b/tex/context/base/s-pre-08.tex new file mode 100644 index 000000000..425310299 --- /dev/null +++ b/tex/context/base/s-pre-08.tex @@ -0,0 +1,271 @@ +%D \module +%D [ file=s-pre-08, +%D version=1999.09.01, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 8, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This is one of the 6 styles made for the \NTS\ presentation +%D at \EUROTEX\ 1999. The idea was to demonstrate a couple of +%D nasty things that one can do with \PDFTEX, being an example +%D of an extension. Afterwards it was provded that this could +%D also be done using traditional \TEX. +%D +%D This version is nearly the same as the original, although +%D since then the \METAPOST\ related macro have become more +%D smooth. The original used a couple of boxes, skipt and +%D fills, while this version uses the layer mechanism that +%D came available in fall 2000. This style is actually more a +%D demonstration gimmick than a real useful one. + +%D You may want to turn on layer tracing: +%D +%D \starttyping +%D \tracelayerstrue +%D \stoptyping + +\setuppapersize + [S6][S6] + +\setupbodyfont + [pos,10pt] + +%D We use the whole page and have no margins. + +\setuplayout + [topspace=0cm, + backspace=0cm, + header=0pt, + footer=0pt, + width=middle, + height=middle] + +\setupcolors + [state=start] + +\definecolor[TextColor][s=.9] +\definecolor[PageColor][r=.5,g=.4,b=.3] +\definecolor[LineColor][r=.7,g=.6,b=.5] + +\definecolor[ColorPage][r=.5,g=.6,b=.7] +\definecolor[ColorLine][r=.3,g=.4,b=.5] + +\setupinteraction + [state=start, + display=new] + +\setupinteractionscreen + [option=max] + +%D The page, sample text and pagenumber will have a background +%D graphic. + +\defineoverlay [page] [\uniqueMPgraphic{page}] +\defineoverlay [graphic] [\uniqueMPgraphic{graphic}] +\defineoverlay [number] [\uniqueMPgraphic{number}] + +%D Each element will also be a button. + +\defineoverlay [nextpage] [\overlaybutton{nextpage}] +\defineoverlay [previouspage] [\overlaybutton{previouspage}] +\defineoverlay [forward] [\overlaybutton{forward}] + +%D We are going to put all three elements on a layer. + +\definelayer [main] +\defineoverlay [main] [\composedlayer{main}] + +%D The page backgrounds are as follows: + +\setupbackgrounds + [page] + [background={previouspage,page}] + +%D We could have put the main layer on the page overlay, but +%D the next solution makes us independent of the back and top +%D margins. The \type {idea} layer is for user purposes. + +\setupbackgrounds + [text] + [background={main,idea}] + +%D The page number, sample text and explanation all have +%D associated framed texts. The two overlays \type {sample} +%D and \type {text} and there for special (user) purposes. + +\defineframedtext + [PageText] + [width=fit,offset=.5cm, + before=,after=,frame=off,background={number,forward}] + +\defineframedtext + [SampleText] + [width=.6\makeupwidth,height=fit,offset=2cm,align=middle, + before=,after=,frame=off,background={graphic,sample,nextpage}] + +\defineframedtext + [TextText] + [width=.6\makeupwidth,height=fit,offset=2cm,align=middle, + before=,after=,frame=off,background={text,nextpage}] + +%D Nothing goes on the page directly, since we use layers. The +%D \type {\null} command makes sure that at least something is +%D on the page so that the page is flushed. Here we also take +%D care of placing the page number. + +\def\StartIdea + {\null \dontcomplain} + +\def\StopIdea + {\setlayer + [main] + [x=\makeupwidth,y=.5cm,hoffset=-.5cm,location=lb] + {\PageText{\pagenumber}} + \page} + +%D Both texts get their position registered. + +\def\StartSample + {\setlayer + [main] + [hoffset=.75cm,voffset=.75cm] + \bgroup \hpos {SampText:\realfolio} \bgroup \startSampleText [none]} + +\def\StopSample + {\stopSampleText \egroup \egroup} + +%D Here the position of the sample text and explanationary +%D text are passed on to the graphic that concerns the latter. + +% use setlayertext instead + +\def\StartText + {\setMPpositiongraphic + {TextText:\realfolio}{text}{other=SampText:\realfolio} + \setlayer + [main] + [x=\makeupwidth,y=\makeupheight, + hoffset=-.75cm,voffset=-.75cm, + location=lt] + \bgroup \noindent \hpos {TextText:\realfolio} \bgroup \startTextText [none]} + +\def\StopText + {\stopTextText \egroup \egroup} + +%D The graphics that encircle the two texts are related to +%D their position. This is because when they overlay, a shine +%D through is shown. This only shows up when there is enough +%D text to make them overlap. + +\startuniqueMPgraphic{page} + StartPage ; + pickup pencircle scaled .5cm ; + fill Page withcolor \MPcolor{PageColor} ; + draw Page withcolor \MPcolor{LineColor} ; + StopPage ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{number} + path p ; p := fullcircle xscaled OverlayWidth yscaled OverlayHeight; + pickup pencircle scaled .25cm ; + fill p withcolor \MPcolor{TextColor} ; + draw p withcolor (white-\MPcolor{PageColor}) ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{graphic} + path p ; p := fullcircle xscaled OverlayWidth yscaled OverlayHeight; + pickup pencircle scaled .5cm ; + fill p withcolor \MPcolor{TextColor} ; + draw p withcolor \MPcolor{LineColor} ; +\stopuniqueMPgraphic + +%D This graphic is calculated when a position is flushed that +%D has this graphics as attached. The \type {self} reference +%D is provided by \CONTEXT\ itself. + +\startMPpositiongraphic{text} + initialize_box(\MPpos{\MPvar{other}}) ; + path p ; p := fullcircle xscaled wxy yscaled hxy shifted cxy ; + initialize_box(\MPpos{\MPvar{self}}) ; + path q ; q := fullcircle xscaled wxy yscaled hxy shifted cxy ; + pickup pencircle scaled .5cm ; + fill q withcolor \MPcolor{TextColor} ; + draw p withcolor (white-\MPcolor{PageColor}) ; + clip currentpicture to q ; + draw q withcolor \MPcolor{LineColor} ; + anchor_box(\MPanchor{\MPvar{self}}) ; +\stopMPpositiongraphic + +%D In order to be complete, we also define a title page. +%D Here suddenly the text background shows up. + +\def\StartTitlePage + {\startstandardmakeup + \dontcomplain + \setupframedtexts[TextText][width=fit] + \StartText + \bfd\setupinterlinespace + \def\\{\blank\bfc\setupinterlinespace\def\\{\blank}}} + +\def\StopTitlePage + {\StopText + \stopstandardmakeup} + +\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +%D For this purpose, we redefine the position graphic to +%D handle a text only case: + +\startMPpositiongraphic{text} + if box_found(\MPpos{\MPvar{other}}) : + initialize_box(\MPpos{\MPvar{other}}) ; + path p ; p := fullcircle xscaled wxy yscaled hxy shifted cxy ; + fi ; + initialize_box(\MPpos{\MPvar{self}}) ; + path q ; q := fullcircle xscaled wxy yscaled hxy shifted cxy ; + pickup pencircle scaled .5cm ; + fill q withcolor \MPcolor{TextColor} ; + if box_found(\MPpos{\MPvar{other}}) : + draw p withcolor (white-\MPcolor{PageColor}) ; + clip currentpicture to q ; + draw q withcolor \MPcolor{LineColor} ; + else : + draw q withcolor (white-\MPcolor{PageColor}) ; + fi ; + anchor_box(\MPanchor{\MPvar{self}}) ; +% setbounds currentpicture to boundingbox origin ; +\stopMPpositiongraphic + +\doifnotmode{demo}{\endinput} + +\starttext + +\TitlePage + {Fancy Styles:\\layers} + +\StartIdea + \StartSample + \input tufte + \StopSample + \StartText + \input reich + \StopText +\StopIdea + +\StartIdea + \StartSample + \input knuth + \StopSample + \StartText + \input reich + \StopText +\StopIdea + +\stoptext diff --git a/tex/context/base/s-pre-09.tex b/tex/context/base/s-pre-09.tex new file mode 100644 index 000000000..a829dd6e2 --- /dev/null +++ b/tex/context/base/s-pre-09.tex @@ -0,0 +1,380 @@ +%D \module +%D [ file=s-pre-09, +%D version=unknown, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 9, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D I made this style when I had to give a presentation on +%D the \MAPS\ bibliography production for several user group +%D meetings. This style is rather tuned for combinations of +%D examples and explanations. The colors match the \MAPS\ +%D bibliography colors. + +\startmode[asintended] \setupbodyfont[lbr] \stopmode + +\setupbodyfont[14.4pt] + +%D A couple of years later, in 2001 this style was documented +%D and made public. While documenting, I also changed box +%D building on top of overlays into the now available layer +%D positioning. So, this styles demonstrates quite some +%D tricks. + +\setuppapersize + [S6][S6] + +\setuplayout + [topspace=0cm, + backspace=0cm, + header=0pt, + footer=0pt, + width=middle, + height=middle] + +%D Local environments can be set by using the setups commands. +%D For downward compatibility, we keep supporting the \type +%D {\...Settings} hooks. Using local environments is seldom +%D needed. + +\let\TextSettings \empty +\let\SampleSettings\empty + +\startsetups [text] \TextSettings \stopsetups +\startsetups [sample] \SampleSettings \stopsetups + +%D The dimensions are kind of fixed. + +\def\FrameWidth {448pt} +\def\FrameHeight {348pt} +\def\FrameOffset {24pt} +\def\FrameSkip {12pt} + +%D But they {\em can} and {\em will} be changed. + +\def\FrameWidth {408pt} +\def\FrameHeight {318pt} + +%D The funny values come from the $3:4$ display aspect +%D ratio. + +\setupcolors + [state=start] + +\definecolor[PageColor] [s=.40] +\definecolor[TextColor] [s=.90] +\definecolor[InteractionColor][r=.40] +\definecolor[LineColor] [r=.60,g=.60] + +%D Of course we go interactive and since we will probably +%D open other documents, we make sure that the viewer opens a +%D new window. + +\setupinteraction + [color=InteractionColor, + contrastcolor=LineColor, + display=new, + state=start] + +\setupinteractionscreen + [option=max] + +%D Before we come to the real macros, we do a little bit of +%D tuning. + +\setupitemize + [1][packed] + +\setuptyping + [blank=medium] + +%D Apart from the titlepage, the page gets a simple colored +%D background. Later we will activate the background. + +\setupbackgrounds + [page] + [backgroundcolor=PageColor] + +%D Everything gets frames by a nice \METAPOST\ frame. + +\defineoverlay [background] [\uniqueMPgraphic{background}] + +\startuniqueMPgraphic{background} + path p ; color c, w, d ; + c := \MPcolor{PageColor} ; + w := \MPcolor{TextColor} ; + d := \MPcolor{LineColor} ; + p := unitsquare xscaled OverlayWidth yscaled OverlayHeight ; + pickup pencircle scaled (1.5*\FrameSkip) ; + draw p withcolor c ; + pickup pencircle scaled \FrameSkip ; + fill p withcolor w ; + draw p withcolor d ; +\stopuniqueMPgraphic + +%D We will present samples and explanation pair||wise, so +%D we need a hyperlink that skips a page. + +\defineoverlay [nextpage] [\overlaybutton{nextpage}] +\defineoverlay [previouspage] [\overlaybutton{previouspage}] +\defineoverlay [skippage] [\overlaybutton{page(+2)}] + +%D Layers are normally used to position multiple content on +%D a specific overlay. Here we will use them to position +%D only and since the samples and text will swap place, we +%D will use quite a few layers. + +\defineoverlay [text] [\composedlayer{text}] +\defineoverlay [sample] [\composedlayer{sample}] +\defineoverlay [common] [\composedlayer{common}] + +%D There are three positions. When combined, the sample and +%D text windows overlap, otherwise the lone window is +%D centered. We could have used one layer and reversed the +%D order by setting the \type {direction} parameter, but +%D this approach is more readable. + +\definelayer + [text] + [x=\makeupwidth,y=\makeupheight,location=lt, + hoffset=-\FrameSkip,voffset=-\FrameSkip] + +\definelayer + [sample] + [hoffset=\FrameSkip,voffset=\FrameSkip] + +\definelayer + [common] + [x=.5\makeupwidth,y=.5\makeupheight,location=c] + +%D The topic is put in the lower right corner of the text +%D window. + +\defineoverlay [topic] [\composedlayer{topic}] + +\definelayer + [topic] + [x=\FrameWidth,y=\FrameHeight,location=lt, + hoffset=-\FrameOffset,voffset=-\FrameSkip] + +%D The topic is put in a framed box. That way we can make +%D sure that it gets a background, which looks better when +%D it covers something else. Otherwise we could have stuct +%D to: +%D +%D \starttyping +%D \def\Topic#1% +%D {\setlayer[topic]{\color[PageColor]{\bfb\setstrut#1}}} +%D \stoptyping +%D +%D But, we go for the nice alternative: + +\def\Topic#1% + {\doifsomething{#1} + {\setlayer [topic] + {\bfb\setstrut + \inframed + [frame=off,foregroundcolor=PageColor,offset=0pt, + background=color,backgroundcolor=TextColor] + {#1}}}} + +%D The sample as well as the explanation will be collected in +%D a buffer. That way we can reuse the content. We could +%D have used a box instead, but can we be sure that the content +%D is not adapting itself? So, buffers we use. + +\resetbuffer[sample] +\resetbuffer[text] + +%D Both the sample and explanation are kind of windowed. + +\defineframedtext + [SampleText] + [width=\FrameWidth,height=\FrameHeight,offset=\FrameOffset, + frame=off,align=normal,strut=no,before=,after=, + background={background,nextpage}] + +%D We safe some keying in by combining things in one macro. + +\def\DoSampleText#1#2#3% kind layer overlays + {\setupframedtexts[SampleText][background={background,#3}] + \setlayer[#2] + {\startSampleText[none] + \setups[#1] + \getbuffer[#1] + \stopSampleText}} + +\def\StartSample{\dostartbuffer[sample][StartSample][StopSample]} +\def\StartText {\dostartbuffer[text] [StartText] [StopText]} + +%D The following definitions apply at the outer level. + +\def\StopSample + {\startstandardmakeup + \DoSampleText{sample}{common}{nextpage} + \stopstandardmakeup + \resetbuffer[sample]} + +\def\StopText + {\startstandardmakeup + \DoSampleText{text}{common}{topic,nextpage} + \stopstandardmakeup + \resetbuffer[text]} + +\setupbackgrounds[page][background={color,nextpage}] +\setupbackgrounds[text][background=common] + +%D When we combine sample and text, we get slightly +%D different definitions. As you can see we generate two +%D pages. Watch how we manipulate the order of the +%D overlays and teh nature of the buttons. Here data +%D abstraction really pays off. + +\def\StartIdea + {\bgroup + \let\StopSample\relax + \let\StopText \relax} + +\def\StopIdea% + {\setupbackgrounds[page][background={color,skippage}] + \setupbackgrounds[text][background={text,sample}] + \startstandardmakeup + \DoSampleText{sample}{sample}{previouspage} + \DoSampleText{text} {text} {topic,nextpage} + \stopstandardmakeup + \setupbackgrounds[page][background={color,nextpage}] + \setupbackgrounds[text][background={sample,text}] + \startstandardmakeup + \DoSampleText{sample}{sample}{previouspage} + \DoSampleText{text} {text} {topic,nextpage} + \stopstandardmakeup + \egroup} + +%D The rest of the definitions takes care of the title page. +%D Please don't steal this one for your own documents. + +\defineoverlay[joke] [\useMPgraphic{joke}{n=0}] % not to be changed! + +\startuseMPgraphic{joke}{n} + StartPage ; + path p, q ; numeric w ; pair xy ; + set_grid(OverlayWidth,OverlayHeight,OverlayWidth/8,OverlayHeight/8) ; + if \MPvar{n}=1 : + p := fulldiamond ; fill Page withcolor \MPcolor{TextColor} ; + else : + p := fullsquare ; fill Page withcolor \MPcolor{PageColor} ; + fi ; + forever : + xy := center Page randomized (OverlayWidth,OverlayHeight) ; + if new_on_grid(xpart xy, ypart xy) : + q := (p xyscaled (OverlayWidth/5,OverlayHeight/5)) + randomized (\FrameSkip,\FrameSkip) + shifted xy ; + w := (\FrameSkip) randomized (\FrameSkip/2) ; + draw q withcolor \MPcolor{PageColor} withpen pencircle scaled (1.5w) ; + fill q withcolor \MPcolor{TextColor} ; + draw q withcolor \MPcolor{LineColor} withpen pencircle scaled ( w) ; + fi ; + exitif grid_full ; + endfor ; + StopPage ; +\stopuseMPgraphic + +\defineoverlay[fuzzy][\useMPgraphic{fuzzy}] + +\startuseMPgraphic{fuzzy} + path p ; numeric w ; + p := (fullsquare xyscaled (OverlayWidth,OverlayHeight)) + randomized (\FrameSkip,\FrameSkip) ; + w := (\FrameSkip) randomized (\FrameSkip/2) ; + draw p withcolor \MPcolor{PageColor} withpen pencircle scaled (1.5w) ; + fill p withcolor \MPcolor{TextColor} ; + draw p withcolor \MPcolor{LineColor} withpen pencircle scaled ( w) ; +\stopuseMPgraphic + +%D This time we use a fit window, but with a slightly randomized +%D frame, our trademark so to say. + +\def\StartTitlePage + {\bgroup + \setupbackgrounds[page][background={joke,nextpage}] + \startstandardmakeup + \switchtobodyfont[big] + \setupframedtexts + [SampleText] + [background=fuzzy, + foregroundcolor=PageColor, + width=fit, + height=fit, + align=middle] + \startSampleText[middle] + \bfd\setupinterlinespace + \def\\{\bfb\setupinterlinespace\vfil\def\\{\vfil}}} + +\def\StopTitlePage + {\stopSampleText + \stopstandardmakeup + \egroup} + +\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +%D Let's nill some error prone presentation macros. + +\let\Subject \Topic +\let\Topics \gobbleoneargument +\let\Subjects \relax + +%D We will avoid \quote {overfull} messages. + +\dontcomplain + +\doifnotmode{demo}{\endinput} + +%D The (rather silly) demo section. + +\starttext + +\setupbodyfont[12pt] + +\TitlePage{Quotes, Quotes\\and more quotes} + +\StartIdea + \StartSample + \input knuth \par + \StopSample + \StartText + \Topic{Tufte} + \input tufte \par + \StopText + \StopIdea + +\StartIdea + \StartSample + \input materie \par + \StopSample + \StartText + \input reich \par + \StopText +\StopIdea + +\StartText + \input tufte \par +\StopText + +\StartIdea + \StartSample + \input knuth \par + \StopSample + \StartText + \input tufte \par + \StopText +\StopIdea + +\stoptext diff --git a/tex/context/base/s-pre-10.tex b/tex/context/base/s-pre-10.tex new file mode 100644 index 000000000..67a867ec7 --- /dev/null +++ b/tex/context/base/s-pre-10.tex @@ -0,0 +1,308 @@ +%D \module +%D [ file=s-pre-10, +%D version=unknown, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 10, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This style is derived from the ninth style, which was +%D used first at \EUROTEX\ 99 and later at \TUG\ 2000. This +%D alternative build up a page. + +\startmode [demo] + \disablemode[demo] \usemodule[pre-09] \enablemode[demo] +\stopmode + +\startnotmode [demo] + \usemodule[pre-09] +\stopnotmode + +%D We use blue colors instead of yellow ones. Since we have +%D used symbolic names, we can easily overload the existing +%D scheme. + +\definecolor[LineColor][r=.40,g=.40,b=1.00] + +%D Here we don't use fixed dimensions, but fit the sample +%D windows and derive the text windows's width from this one. + +\setupframedtexts + [SampleText] + [width=fit,height=fit, + background={background,nextpage}] + +%D The topic goes to the top right corner of the screen which +%D means that it is positioned left down to the reference +%D point. Watch how we make data on this layer (here only +%D the topic but it can be more) persistent. + +\setuplayer + [topic] + [y=0pt,x=\makeupwidth,location=lb,state=repeat, + hoffset=-\FrameSkip,voffset=\FrameSkip] + +%D Clicking on the page brings us back. + +\setupbackgrounds + [page] + [background={previouspage,color,topic}] + +%D All layers end up on the text area. This could have been +%D the page area too since these have the same dimensions. + +\setupbackgrounds + [text] + [background={common,sample,text}] + +%D Because we build up the text window step by step, we will +%D separate the entries by white space. + +\startsetups [always] + \setupwhitespace[big] + \setupblank[big] +\stopsetups + +%D The \type {\Topic} commands can be simplified to: + +\def\Topic#1% + {\resetlayer[topic] + \setlayer[topic]{\bfb\setstrut\color[TextColor]{#1}}} + +%D We also provide a way to erase the topic. + +\def\NoTopic + {\resetlayer[topic]} + +%D We have to redefine the structuring commands to support +%D the resetting of buffer counters. + +\newcounter\TextN + +\def\StartSample + {\doglobal\newcounter\TextN + \dostartbuffer[sample][StartSample][StopSample]} + +\def\StartText + {\doglobal\newcounter\TextN + \dostartbuffer[text][StartText][StopText]} + +\def\StartSubText + {\doglobal\increment\TextN + \dostartbuffer[text-\TextN][StartSubText][StopSubText]} + +\def\StopText + {\startstandardmakeup + \DoSampleText{text}{common}{nextpage} + \stopstandardmakeup} + +\def\StopSubText + {\startstandardmakeup + \DoSampleText{text}{common}{nextpage} + \stopstandardmakeup} + +%D The \type {\DoSampleText} command is adapted to support +%D addition of subtexts (each subtext goes into its own +%D buffer). + +\def\DoSampleText#1#2#3% + {\setupframedtexts[SampleText][background={background,#3}] + \bgroup + \setups[#1]% + \setups[always]% + \setbox\nextbox=\hbox + {\startSampleText[none] + \getbuffer[#1]\par + \doif{#1}{text} + {\dorecurse{\TextN}{\getbuffer[text-\recurselevel]\par}} + \stopSampleText} + \xdef\SampleTextWidth{\the\wd\nextbox} + \setlayer[#2]{\box\nextbox}% + \egroup} + +%D Since we are no longer swapping windows, we end up with a +%D much simplier \type {\Stopidea} macro. We don't reset +%D samples at the inner level. + +\def\StartIdea% + {\bgroup + \let\StopSample \relax + \let\StopText \relax + \let\StopSubText\relax + \def\StartSample{\dostartbuffer[sample][StartSample][StopSample]}} + +\def\StopIdea% + {\startstandardmakeup + \DoSampleText{sample}{sample}{nextpage} + \SetTextWidth + \DoSampleText{text} {text} {nextpage} + \stopstandardmakeup + \egroup} + +%D Here we determine the width of the text window. It is +%D derived from the width of the sample and stays the same +%D within a sequence. + +\def\SetTextWidth + {\ifnum\TextN<1 % yes or no, may change + \scratchdimen=\makeupwidth + \advance\scratchdimen by -\SampleTextWidth + \advance\scratchdimen by \FrameSkip + \xdef\SampleWidth{\the\scratchdimen}% + \fi + \setupframedtexts + [SampleText] + [width=\SampleWidth]} + +%D We use the (already implemented) second alternative of +%D the titlepage graphic. Please don't change this. + +\defineoverlay[joke] [\useMPgraphic{joke}{n=1}] % not to be changed ! + +\doifnotmode{demo}{\endinput} + +%D The demo section. The original presentation uses proper +%D graphics and has better spacing. + +\def\SomeSymbol#1#2{\definedfont[ContextNavigation at #1]\char#2} + +\setupcombinations[distance=\FrameOffset,inbetween=\vskip\FrameOffset] + +\starttext + +\TitlePage{Some Famous Symbols} + +\Topic{Symbols} + +\StartSample + \startcombination[2*2] + {\SomeSymbol{5cm}{1}} {} + {\SomeSymbol{5cm}{3}} {} + {\SomeSymbol{5cm}{2}} {} + {\SomeSymbol{5cm}{4}} {} + \stopcombination +\StopSample + +\Topic{Previous} + +\StartIdea + \StartSample + \SomeSymbol{7cm}{1} + \StopSample + \StartText + This symbol can be used to indicate a hyperlink to a + previous page. + \StopText +\StopIdea + +\StartIdea + \StartSubText + As one can expect there is also a symbol for going to + the next page. + \StopSubText +\StopIdea + +\Topic{Previous} + +\StartIdea + \StartSample + \SomeSymbol{9cm}{2} + \StopSample + \StartText + This symbol is actually just a mirrored version of the + first symbol we showed. + \StopText +\StopIdea + +\NoTopic + +\StartText + Is this nice or not? +\StopText + +\Topic{First and Last} + +\StartSample + \SomeSymbol{11cm}{3} +\StopSample + +\StartSample + \SomeSymbol{11cm}{4} +\StopSample + +\StartIdea + \StartSample + \SomeSymbol{5cm}{3} + \StopSample + \StartText + A few screens back, we saw this symbol. + \StopText +\StopIdea + +\StartIdea + \StartSubText + This symbol represents the beginning of something. + \StopSubText +\StopIdea + +\StartIdea + \StartSample + \SomeSymbol{5cm}{4} + \StopSample + \StartSubText + Just like this one represents an end. + \StopSubText +\StopIdea + +\StartIdea + \StartSubText + They look just like the symbols found on audio and + video players. + \StopSubText +\StopIdea + +\Topic{Summary} + +\StartIdea + \StartSample + \SomeSymbol{6cm}{1} + \StopSample + \StartText + So we have a symbol for previous \unknown + \StopText +\StopIdea + +\StartIdea + \StartSample + \SomeSymbol{6cm}{2} + \StopSample + \StartSubText + \unknown\ and one for next \unknown + \StopSubText +\StopIdea + +\StartIdea + \StartSample + \SomeSymbol{6cm}{3} + \StopSample + \StartSubText + \unknown\ and yet another for first \unknown + \StopSubText +\StopIdea + +\StartIdea + \StartSample + \SomeSymbol{6cm}{4} + \StopSample + \StartSubText + \unknown\ and of course for last. + \StopSubText +\StopIdea + +\stoptext + diff --git a/tex/context/base/s-pre-11.tex b/tex/context/base/s-pre-11.tex new file mode 100644 index 000000000..23bf9e223 --- /dev/null +++ b/tex/context/base/s-pre-11.tex @@ -0,0 +1,220 @@ +%D \module +%D [ file=s-pre-11, +%D version=1999.08.20, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 11, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\setuppapersize + [S6][S6] + +\setuplayout + [topspace=0cm, + backspace=0cm, + header=0pt, + footer=0pt, + width=middle, + height=middle] + +\setupbodyfont + [14.4pt,lbr] + +\setupcolors + [state=start] + +\setupinteraction + [click=no, + display=new, + state=start] + +\setupinteractionscreen + [option=max] + +\def\SomeShape% + {\resetMPdrawing + \startMPdrawing + path p[], q[] ; pair a, b ; + StartPage ; + \stopMPdrawing + \dorecurse{\CurrentTopic} + {\startMPdrawing + initialize_box(\MPpos{topic-\realfolio-\recurselevel}) ; + p[\recurselevel] := tensecircle (wxy,hxy,.25cm) shifted cxy ; + fill p[\recurselevel] withcolor .9white ; + pickup pencircle scaled .25cm ; + \ifnum\recurselevel=\CurrentTopic\space + draw p[\recurselevel] withcolor \MPcolor{ShowColor} ; + \else + draw p[\recurselevel] withcolor \MPcolor{DoneColor} ; + \fi + \stopMPdrawing}% + \dorecurse{\CurrentMaxItem} + {\startMPdrawing + initialize_box(\MPpos{item-\realfolio-\recurselevel}) ; + linewidth := .25cm ; + q[\recurselevel] := tensecircle (wxy,hxy,linewidth) shifted cxy ; + fill q[\recurselevel] withcolor .9white ; + pickup pencircle scaled linewidth ; + \ifnum\recurselevel=\CurrentMaxItem\space + draw q[\recurselevel] withcolor \MPcolor{ShowColor} ; + \else + draw q[\recurselevel] withcolor \MPcolor{DoneColor} ; + \fi + \stopMPdrawing}% + \dostepwiserecurse{2}{\CurrentTopic}{1} + {\startMPdrawing + draw + rt point 3 of p[\recurselevel-1] -- + lft point 7 of p[\recurselevel] + withcolor \MPcolor{ArrowColor} ; + \stopMPdrawing}% + \dostepwiserecurse{2}{\CurrentMaxItem}{1} + {\startMPdrawing + draw + bot point 9 of q[\recurselevel-1] -- + top point 5 of q[\recurselevel] + withcolor \MPcolor{ArrowColor} ; + \stopMPdrawing}% + \startMPdrawing + draw Page + withpen pencircle scaled .5cm + withcolor \MPcolor{EdgeColor} ; + StopPage ; + \stopMPdrawing + \MPdrawingdonetrue + \getMPdrawing} + +\def\TitlePage#1% + {\startstandardmakeup + \setupalign[middle] + \def\\{\vfil\bfb\setupinterlinespace} + \bfd\setupinterlinespace + \vfil#1\vfil\vfil + \stopstandardmakeup} + +\definecolor[PageColor][r=.5,g=.4,b=.3] +\definecolor[LineColor][r=.7,g=.6,b=.5] + +\definecolor[PageColor] [s=.60] +\definecolor[ShowColor] [r=.40] +\definecolor[EdgeColor] [g=.40] +\definecolor[DoneColor] [r=.40,g=.40] +\definecolor[ArrowColor] [b=.40] +\definecolor[LineColor] [r=.60,g=.60] +\definecolor[GotoColor] [ArrowColor] + +\setupinteraction[color=GotoColor,contrastcolor=GotoColor] + +\defineoverlay [shape] [\SomeShape] +\defineoverlay [next] [\overlaybutton{forward}] % [{nextpage}] + +\setupbackgrounds + [page] + [background={color,next,shape}, + backgroundcolor=PageColor] + +\doglobal\newcounter\CurrentMaxItem +\doglobal\newcounter\CurrentItem +\doglobal\newcounter\CurrentTopic + +\def\StartIdea% + {\doglobal\newcounter\CurrentItem} + +\def\StartTopic% + {\doglobal\increment\CurrentTopic + \dostartbuffer[topic-\CurrentTopic][StartTopic][StopTopic]} + +\def\StopIdea% + {\dorecurse{\CurrentItem} + {\let\CurrentMaxItem\recurselevel + \doStopIdea}} + +\def\doStopIdea% + {\startstandardmakeup + \dontcomplain + \vskip.875cm + \hbox to \makeupwidth + {\hfill + \dorecurse{\CurrentTopic} + {\edef\Topic{topic-\realfolio-\recurselevel}% + \hpos + {\Topic} + {\framed + [frame=off,align=middle,offset=.25cm] + {\getbuffer[topic-\recurselevel]}}% + \ifnum\recurselevel<\CurrentTopic + \hskip.875cm + \fi}% + \hfill} + \vskip.875cm + \vfilll + \dorecurse{\CurrentMaxItem} + {\edef\Item{item-\realfolio-\recurselevel} + \hbox to \makeupwidth + {\hfill + \hpos + {\Item} + {\framed + [width=.75\makeupwidth, + frame=off, + align=middle,offset=.125cm] + {\getbuffer[item-\recurselevel]}}% + \hfill} + \vskip.875cm} + \vfilll + \stopstandardmakeup} + +\def\StartItem% + {\doglobal\increment\CurrentItem + \dostartbuffer[item-\CurrentItem][StartItem][StopItem]} + +\lefthyphenmin =\maxdimen +\righthyphenmin=\maxdimen + +\doifnotmode{demo}{\endinput} + +\starttext + +\StartIdea + \StartTopic + A Nice Idea + \StopTopic + \StartItem + \input reich \relax + \StopItem + \StartItem + \input reich \relax + \StopItem + \StartItem + \input reich \relax + \StopItem +\StopIdea + +\StartIdea + \StartTopic + One More Nice Idea + \StopTopic + \StartItem + \input reich \relax + \StopItem + \StartItem + \input reich \relax + \StopItem +\StopIdea + +\StartIdea + \StartTopic + The Last Idea + \StopTopic + \StartItem + \input tufte \relax + \StopItem +\StopIdea + +\stoptext diff --git a/tex/context/base/s-pre-12.tex b/tex/context/base/s-pre-12.tex new file mode 100644 index 000000000..722d59ced --- /dev/null +++ b/tex/context/base/s-pre-12.tex @@ -0,0 +1,226 @@ +%D \module +%D [ file=s-pre-12, +%D version=1999.08.20, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 12, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\setuppapersize + [S6][S6] + +\setuplayout + [topspace=0cm, + backspace=0cm, + header=0pt, + footer=0pt, + width=middle, + height=middle] + +\setupbodyfont + [14.4pt,lbr] + +\setupcolors + [state=start] + +\setupinteraction + [click=no, + display=new, + state=start] + +\setupinteractionscreen + [option=max] + +\def\SomeShape% + {\resetMPdrawing + \startMPdrawing + path p ; pair a, b ; + ahlength := .375cm ; + StartPage ; + draw Page %unitsquare + %xscaled PaperWidth yscaled PaperHeight + withpen pencircle scaled .5cm + withcolor \MPcolor{EdgeColor} ; + \stopMPdrawing + \dorecurse{\CurrentTopic} + {\startMPdrawing + initialize_box(\MPpos{topic-\realfolio-\recurselevel}) ; + p := tensecircle (wxy,hxy,.25cm) shifted cxy ; + fill p withcolor .9white ; + pickup pencircle scaled .25cm ; + \ifnum\recurselevel=\CurrentTopic + draw p withcolor \MPcolor{ShowColor} ; + a := bot point 7 of p ; + \else + draw p withcolor \MPcolor{DoneColor} ; + \fi + \stopMPdrawing} + \dorecurse{\CurrentMaxItem} + {\startMPdrawing + initialize_box(\MPpos{item-\realfolio-\recurselevel}) ; + linewidth := .25cm ; + p := tensecircle (wxy,hxy,linewidth) shifted cxy ; + fill p withcolor .9white ; + pickup pencircle scaled linewidth ; + b := rt point 3 of p ; + \ifnum\recurselevel=\CurrentMaxItem + draw p withcolor \MPcolor{ShowColor} ; + \else + draw p withcolor \MPcolor{DoneColor} ; + \fi + dxab := xpart a-xpart b ; + dyab := ypart a-ypart b ; + sign := if dyab>0 : - fi 1 ; + drawarrow + a -- + a shifted (+2linewidth-dxab/2,0) {left} .. + if abs(dyab)>4linewidth : + a shifted (-dxab/2,+sign*2linewidth) -- + b shifted (+dxab/2,-sign*2linewidth) .. + fi + {left} b shifted (-2linewidth+dxab/2,0) -- + b + withcolor \MPcolor{ArrowColor} ; + \stopMPdrawing}% + \startMPdrawing + StopPage ; + \stopMPdrawing + \MPdrawingdonetrue + \getMPdrawing} + +\definecolor[PageColor][r=.5,g=.4,b=.3] +\definecolor[LineColor][r=.7,g=.6,b=.5] + +\definecolor[PageColor] [s=.60] +\definecolor[ShowColor] [r=.40] +\definecolor[EdgeColor] [g=.40] +\definecolor[DoneColor] [r=.40,g=.40] +\definecolor[ArrowColor] [b=.40] +\definecolor[LineColor] [r=.60,g=.60] +\definecolor[GotoColor] [ArrowColor] + +\setupinteraction[color=GotoColor,contrastcolor=GotoColor] + +\defineoverlay [shape] [\SomeShape] +\defineoverlay [next] [\overlaybutton{forward}] + +\setupbackgrounds + [page] + [background={color,next,shape}, + backgroundcolor=PageColor] + +\doglobal\newcounter\CurrentItem +\doglobal\newcounter\CurrentTopic +\doglobal\newcounter\CurrentMaxItem + +\def\StartIdea% + {\doglobal\newcounter\CurrentItem} + +\def\StartTopic% + {\doglobal\increment\CurrentTopic + \dostartbuffer[topic-\CurrentTopic][StartTopic][StopTopic]} + +\def\StopIdea% + {\dorecurse{\CurrentItem} + {\let\CurrentMaxItem\recurselevel + \doStopIdea}} + +\def\IdeaWidth {.6\makeupwidth} % .5 +\def\TopicWidth{.2\makeupwidth} % .3 + +\def\doStopIdea% + {\startstandardmakeup + \dontcomplain + \vbox to \makeupheight + {\vskip.75cm \relax % \vfill + \dorecurse{\CurrentMaxItem} + {\edef\Item{item-\realfolio-\recurselevel} + \hbox to \makeupwidth + {\hskip.75cm + \hpos + {\Item} + {\framed + [width=\IdeaWidth,frame=off, + align=middle,offset=.125cm] + {\getbuffer[item-\recurselevel]}}} + \vskip.875cm} + \vfill} + \vskip-\makeupheight + \vbox to \makeupheight + {\vskip.75cm \relax + \dorecurse{\CurrentTopic} + {\edef\Topic{topic-\realfolio-\recurselevel} + \hbox to \makeupwidth + {\hfill + \hpos + {\Topic} + {\framed + [width=\TopicWidth,frame=off, + align=middle,offset=.25cm] + {\getbuffer[topic-\recurselevel]}}% + \hskip.75cm} + \vskip.875cm} + \vfill} + \stopstandardmakeup} + +\def\StartItem% + {\doglobal\increment\CurrentItem + \dostartbuffer[item-\CurrentItem][StartItem][StopItem]} + +\lefthyphenmin =\maxdimen +\righthyphenmin=\maxdimen + +\def\TitlePage#1% + {\startstandardmakeup + \setupalign[middle] + \def\\{\vfil\bfb\setupinterlinespace} + \bfd\setupinterlinespace + \vfil#1\vfil\vfil + \stopstandardmakeup} + +\endinput + +% \starttext +% +% \StartIdea +% \StartTopic +% What a topic +% \StopTopic +% \StartItem +% \input reich \relax +% \StopItem +% \StartItem +% \input reich \relax +% \StopItem +% \StartItem +% \input reich \relax +% \StopItem +% \StopIdea +% +% \StartIdea +% \StartTopic +% One More Nice Idea +% \StopTopic +% \StartItem +% \input reich \relax +% \StopItem +% \StartItem +% \input reich \relax +% \StopItem +% \StopIdea +% +% \StartIdea +% \StartTopic +% The Last Idea +% \StopTopic +% \StartItem +% \input tufte \relax +% \StopItem +% \StopIdea +% +% \stoptext diff --git a/tex/context/base/s-pre-13.tex b/tex/context/base/s-pre-13.tex new file mode 100644 index 000000000..6032f36d2 --- /dev/null +++ b/tex/context/base/s-pre-13.tex @@ -0,0 +1,302 @@ +%D \module +%D [ file=s-pre-13, +%D version=1999.08.20, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 13, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This is again one of the \EUROTEX\ 99 styles. It's one of +%D the quick and dirty styles supporting basic structuring. + +\setuppapersize + [S6][S6] + +\setuplayout + [width=middle, + height=middle, + header=0pt, + footer=0pt, + bottomdistance=.5cm, + bottom=1cm, + topspace=2cm, + backspace=2cm] + +%D This style is meant to be used with lucida handwriting +%D fonts. If you don't have that font, you may reconsider +%D using this style. + +\startmode[asintended] \setupbodyfont[lbr,hw] \stopmode + +%D These colors will mostly be used in the graphics drawn by +%D \METAPOST. + +\setupcolors + [state=start] + +\definecolor[PageColor] [s=.6] +\definecolor[TextColor] [s=.8] +\definecolor[LineColor] [g=.4] +\definecolor[SymbolColor][r=.4] + +%D When interacting, we will use button shaped that are +%D quite random and thereby regenerated for each instance. + +\setupinteractionscreen + [option=max] + +\setupinteractionmenu + [bottom] + [state=start, + height=1cm, + middle=\hskip1cm] + +\setupinteraction + [state=start, + menu=on, + display=new, + click=no, + color=SymbolColor, + contrastcolor=SymbolColor] + +\startinteractionmenu[bottom] + \hfill + \got [previouspage] \symbol[prevmark] \\ + \got [nextpage] \symbol[nextmark] \\ + \got [CloseDocument] \symbol[stopmark] \\ + \txt \tfd \SymbolColor \pagenumber \\ +\stopinteractionmenu + +%D When not processed at runtime, the itemmark graphics can +%D result in processing loops due to funny dimensions. +%D Therefore, from now on, the itemize macros limit the height +%D and depth. + +\definesymbol[itemmark][\useMPgraphic{itemmark}] +\definesymbol[stopmark][\useMPgraphic{stopmark}] +\definesymbol[nextmark][\useMPgraphic{nextmark}] +\definesymbol[prevmark][\useMPgraphic{prevmark}] + +%D Of course we have some backgrounds. + +\defineoverlay [page] [\useMPgraphic{page}] +\defineoverlay [next] [\overlaybutton{forward}] +\defineoverlay [prev] [\overlaybutton{PreviousJump}] + +\setupbackgrounds + [page] + [background={page,prev}] + +\setupbackgrounds + [text] + [background=next] + +\setuphead + [chapter] + [alternative=middle, + number=no, + color=SymbolColor, + style=\tfc] + +%D A little bit of tweaking. + +\setupwhitespace + [big] + +\setupitemize + [1] + [symbol=itemmark, + width=3\bodyfontsize] + +\def\StartTitlePage% + {\setupinteractionmenu[bottom][state=stop] % will be named page block + \startstandardmakeup + \setupalign[middle] + \def\\% + {\stopcolor + \vfil + \bfb\setupinterlinespace + \startcolor[black]} + \bfd\setupinterlinespace + \vfil + \startcolor[SymbolColor]} + +\def\StopTitlePage + {\stopcolor + \vfil\vfil + \stopstandardmakeup + \setupinteractionmenu[bottom][state=start]} + + +\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +\definehead[Topic][chapter] +\definehead[Nopic][title] + +\setuplist + [Topic] + [criterium=all, + alternative=g, + interaction=all, + after=\blank] + +\def\Topics#1% + {\Nopic{#1} + \bgroup + \setupinteraction + [color=, + contrastcolor=] + \determinelistcharacteristics[Topic] + \ifnum\utilitylistlength>12 + \startcolumns[n=2] + \placelist[Topic] + \stopcolumns + \else + \placelist[Topic] + \fi + \egroup} + +%D We don't support another level of structuring. + +\let\Subject \Topic +\let\Subjects\relax + +%D Most of this style is \METAPOST\ definitions. We could +%D have shared some code, but it would not on forehand make +%D things more readable, so we stick to the following +%D definitions. + +\startuseMPgraphic{page} + + width := \overlaywidth ; + height := \overlayheight ; + + d := 15 ; dd := d ; dd := 10 ; + + def fuzzy (expr p,dx,dy) = + (xpart p +dx-uniformdeviate dx,ypart p+dy-uniformdeviate dy) + enddef ; + + pair ll, lr, ur, ul ; + + ll := (d,d) ; + lr := (width-d,d) ; + ur := (width-d,height-d) ; + ul := (d,height-d) ; + + path p, q, r, s ; + + p := ll.. for i=.1 step .1 until .9 : fuzzy (i[ll,lr],0,+dd).. endfor lr ; + q := lr.. for i=.1 step .1 until .9 : fuzzy (i[lr,ur],-dd,0).. endfor ur ; + r := ur.. for i=.1 step .1 until .9 : fuzzy (i[ur,ul],0,-dd).. endfor ul ; + s := ul.. for i=.1 step .1 until .9 : fuzzy (i[ul,ll],+dd,0).. endfor ll ; + + fill unitsquare xscaled width yscaled height withcolor \MPcolor{PageColor} ; + + fill p & q & r & s -- cycle withcolor \MPcolor{TextColor} ; + + color c ; c := \MPcolor{LineColor} ; + + draw p withpen pencircle xscaled 20 yscaled 5 rotated 30 withcolor c ; + draw q withpen pencircle xscaled 5 yscaled 20 rotated 30 withcolor c ; + draw r withpen pencircle xscaled 20 yscaled 5 rotated 30 withcolor c ; + draw s withpen pencircle xscaled 5 yscaled 20 rotated 30 withcolor c ; + +\stopuseMPgraphic + +\startuseMPgraphic{itemmark} + width := BodyFontSize ; height := width/4 ; + maxheight := StrutHeight ; line := 3width/2 ; + + def fuzzy = -(height/4)+uniformdeviate (height/2) enddef ; + + draw + ((0,0+fuzzy)--(width,height+fuzzy/2)) + shifted (line/2,0) + withpen pencircle + xscaled line yscaled (line/4) + rotated (25+uniformdeviate 10) withcolor \MPcolor{SymbolColor} ; + + setbounds currentpicture to unitsquare xyscaled(width,maxheight) ; +\stopuseMPgraphic + +\startuseMPgraphic{nextmark} + LoadPageState ; width := BottomHeight ; height := line := width/2 ; + + def fuzzy = -(height/8)+uniformdeviate (height/4) enddef ; + + z1 = (0,0+fuzzy) ; z2 = (width,height/2+fuzzy/2) ; z3 = (0,height+fuzzy) ; + + draw + (z1..{right}z2 & z2{left}..z3) + withpen pencircle + xscaled line yscaled (line/4) + rotated 30 withcolor \MPcolor{SymbolColor} ; + + setbounds currentpicture to unitsquare xyscaled(width,height) ; +\stopuseMPgraphic + +\startuseMPgraphic{prevmark} + LoadPageState ; width := BottomHeight ; height := line := width/2 ; + + def fuzzy = -(height/8)+uniformdeviate (height/4) enddef ; + + z1 = (width,0+fuzzy) ; z2 = (0,height/2+fuzzy/2) ; z3 = (width,height+fuzzy) ; + + draw + (z1..{left}z2 & z2{right}..z3) + withpen pencircle + xscaled line yscaled (line/4) + rotated 30 withcolor \MPcolor{SymbolColor} ; + + setbounds currentpicture to unitsquare xyscaled(width,height) ; +\stopuseMPgraphic + +\startuseMPgraphic{stopmark} + LoadPageState ; width := BottomHeight ; height := line := width/2 ; + + def fuzzy = -(height/8)+uniformdeviate (height/4) enddef ; + + z1 = (0,0+fuzzy) ; + z2 = (width,height+fuzzy) ; + z3 = (width,0+fuzzy) ; + z4 = (0,height+fuzzy) ; + z5 = (width/2,height/2) ; + + drawoptions + (withpen pencircle + xscaled line yscaled (line/4) + rotated 30 withcolor \MPcolor{SymbolColor}) ; + + draw z1..{right}z5..z2 ; draw z3..{left}z5..z4 ; + + setbounds currentpicture to unitsquare xyscaled(width,height) ; +\stopuseMPgraphic + +\doifnotmode{demo}{\endinput} + +%D The (rather silly) demo section. + +\starttext + +\TitlePage{Title Page\\pre-writing} + +\Topics{Some Nice Quotes} + +\Topic{A Few} + +\Subject{Knuth} \input knuth +\Subject{Tufte} \input tufte + +\Topic{Some More} + +\Subject{Zapf} \input zapf +\Subject{Bryson} \input bryson + +\stoptext diff --git a/tex/context/base/s-pre-14.tex b/tex/context/base/s-pre-14.tex new file mode 100644 index 000000000..f44117e7c --- /dev/null +++ b/tex/context/base/s-pre-14.tex @@ -0,0 +1,264 @@ +%D \module +%D [ file=s-pre-14, +%D version=1999.08.20, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 14, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + + +%D In the process of making a couple of simple styles for +%D \EUROTEX\ 99, I came to this one. The joke is in the +%D pagenumber. This style can be used for short presentations +%D with much text. + +\startmode[asintended] \setupbodyfont[lbr] \stopmode + +\setupbodyfont[14.4pt] + +%D Since we expect text, we can best be very tolerant. + +\setuptolerance + [verytolerant,stretch] + +%D As most styles we choose a large screen page size. + +\setuppapersize + [S6][S6] + +\setuplayout + [width=fit, + rightedge=3cm, + margin=0pt, + rightedgedistance=2cm, + height=middle, + header=0pt, + footer=0pt, + topspace=1cm, + backspace=1cm] + +%D We only use two colors, named \type {One} and \type +%D {Two}: + +\setupcolors + [state=start] + +\definecolor [One] [r=.6,g=.4,b=.4] +\definecolor [Two] [r=.4,g=.6,b=.6] + +%D If you've looked at the demo file, you will have noticed +%D that the background consists of four pieces: two filled +%D rectangles and two half numbers. These are put on th epage +%D using four overlays: + +\setupbackgrounds + [page] + [background={one,two,three,four}] + +%D When we code this in \TEX, we get the following +%D definitions. As an alternative we coudl have used layers +%D but I'm afraid that it would not have led to less code. + +\defineoverlay + [one] + [{\framed + [frame=off,background=color,backgroundcolor=Two, + width=\overlaywidth,height=\overlayheight] + {}}] + +\defineoverlay + [three] + [{\hbox to \overlaywidth + {\hfill\SetOverlayWidth + \framed + [frame=off,background=color,backgroundcolor=One, + width=\overlaywidth,height=\overlayheight] + {}}}] + +%D We could have used the main backgroundcolor instead of +%D overlay \type {one}. + +\definefont[NumberFont][RegularBold at 3cm] + +\defineoverlay + [two] + [{\framed + [frame=off,width=\overlaywidth,height=\overlayheight, + offset=overlay] + {\vfill + \NumberFont\setstrut\SetOverlayWidth + \hbox to \hsize + {\hfill + \setupinteraction[style=,color=]% + \setbox0=\hbox{\strut\One\pagenumber}% + \hbox to 0pt{\hss\gotobox{\box0}[previouspage]\hss}% + \hskip\overlaywidth}}}] + +\defineoverlay + [four] + [{\framed + [frame=off,width=\overlaywidth,height=\overlayheight,offset=overlay] + {\vfill + \hbox to \hsize + {\hfill + \SetOverlayWidth + \framed + [frame=off,width=\overlaywidth,height=\overlayheight,offset=overlay] + {\vfill\NumberFont\setstrut + \setbox0=\hbox{\strut\Two\pagenumber}% + \setbox2=\hbox{\clip[nx=2,ny=1,x=2,y=1]{\copy0}}% + \dp2=\dp0 + \hbox to \hsize{\hbox to 0pt{\hss\hskip.5\wd0\box2\hss}\hfill}}}}}] + +\def\SetOverlayWidth% + {\scratchdimen = \rightedgedistance + \divide\scratchdimen by 2 + \advance\scratchdimen by \rightedgewidth + \advance\scratchdimen by \backspace + \edef\overlaywidth{\the\scratchdimen}} + +%D A much cleaner implementation is the following. If you hate +%D \METAPOST, you can run this style in the specified mode: + +\startnotmode[no-metapost] + +\setupbackgrounds + [page] + [background={number}] + +\defineoverlay[number][\useMPgraphic{number}] + +\startuseMPgraphic{number} + StartPage ; + path Vage ; picture Left, Right ; + x1 = x2 = xpart (llcorner Field[Text][RightEdge] shifted (-RightEdgeDistance/2,0)) ; + y1 = ypart llcorner Page ; + y2 = ypart ulcorner Page ; + Vage := llcorner Page -- z1 -- z2 -- ulcorner Page -- cycle ; + fill Page withcolor \MPcolor {One} ; + fill Vage withcolor \MPcolor {Two} ; + if PageNumber>0 : + defaultfont := "\truefontname{RegularBold}" ; + Left := Right := thelabel("\folio",origin) ysized 3cm ; + clip Right to boundingbox Right shifted (bbwidth(Right)/2,0) ; + draw Left shifted z1 shifted (0,2.25cm) withcolor \MPcolor {One} ; + draw Right shifted z1 shifted (0,2.25cm) withcolor \MPcolor {Two} ; + fi ; + StopPage ; +\stopuseMPgraphic + +\stopnotmode + +%D We use the simple label typesetting present in \METAPOST\ +%D because digits are seldom kerned so real \TEX ing is not +%D needed. As in the previous method, we let the graphics +%D overlap so that we don't get white lines due to rounding +%D problems in viewers. +%D +%D We put a button behind the text (this overlay is calculated +%D each page). + +\defineoverlay + [nextpage] + [\overlaybutton{nextpage}] + +\setupbackgrounds + [text] + [backgroundoffset=.5cm, + background=nextpage] + +%D We still have to turn on interaction mode. + +\setupinteraction + [state=start, + display=new, + menu=on] + +\setupinteraction + [color=, + contrastcolor=] + +%D Next we define structuring commands. + +\definehead[Topic] [chapter] \setuphead[Topic] [style=\bfc] +\definehead[Subject][section] \setuphead[Subject][style=\bfa] + +\setuphead + [Topic, Subject] + [number=no, + after={\blank[big]}] + +%D Because we will provide a menu, we don't offer lists. + +\let\Topics \gobbleoneargument +\let\Subjects\relax + +%D The table of contents goes to the right edge. + +\startinteractionmenu[right] + \setupinteraction + [color=black, + contrastcolor=Two] + \placelist + [Topic] + [alternative=e, + frame=off, + criterium=all] + \vfill +\stopinteractionmenu + +\setuplist + [Topic] + [width=\rightedgewidth, + maxwidth=\rightedgewidth, + style=\bfa] + +%D We safe some space: + +\setupwhitespace + [medium] + +\setupblank + [medium] + +%D In the titlepage, we still use the \TEX\ overlays, +%D so that we don't have to define a second graphic. + +\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +\def\StartTitlePage% + {\bgroup + \setupbackgrounds[page][background={one,three}] + \startstandardmakeup + \setupalign[middle] + \def\\{\vfil\bfb\setupinterlinespace} + \bfd\setupinterlinespace + \vfil} + +\def\StopTitlePage% + {\vfil\vfil\vfil + \stopstandardmakeup + \egroup} + +%D This is it. + +\doifnotmode{demo}{\endinput} + +\starttext + +\TitlePage{Some Quotes\\(that you probably know by now)} + +\Topic{Tufte} \input tufte +\Topic{Knuth} \input knuth +\Topic{Reich} \input reich +\Topic{Zapf} \input zapf +\Topic{Materie} \input materie +%Topic{Stork} \input stork + +\stoptext diff --git a/tex/context/base/s-pre-15.tex b/tex/context/base/s-pre-15.tex new file mode 100644 index 000000000..c9a157abb --- /dev/null +++ b/tex/context/base/s-pre-15.tex @@ -0,0 +1,186 @@ +%D \module +%D [ file=s-pre-15, +%D version=1999.09.01, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 15, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This is one of the styles I made for the presentation on +%D the \NTS\ project at Euro\TeX\ 1998. You need balls to let +%D \TEX\ typeset graphics, but this style demonstrates that it +%D can be done. +%D +%D This presentation is meant for presentations that build up +%D an idea stepwise. +%D +%D \starttyping +%D \TitlePage{Do you know \TEX ?} +%D +%D \StartIdea +%D \StartItem We use \TEX\ for typesetting \unknown \StopItem +%D \StartItem mathematical text \unknown \StopItem +%D \StartItem but also for text that has no math \unknown \StopItem +%D \StartItem or presentations like this \unknown \StopItem +%D \StartItem and whatever you can come up with! \StopItem +%D \StopIdea +%D \stoptyping + +%D The basic layout is rather simple and used as much of the +%D screen as possible. + +\setuppapersize + [S6][S6] + +\setuplayout + [backspace=25pt, + topspace=25pt, + width=middle, + height=middle, + header=0pt, + footer=0pt] + +\setupinteraction + [state=start, + display=new, + color=LineColor, + contrastcolor=LineColor, + click=no] + +\setupinteractionscreen + [option=max] + +\startmode[asintended] \setupbodyfont[lbr] \stopmode + +\setupbodyfont[14.4pt] + +%D We use a lot of color. You can remap them if you want +%D differend ones. The ideas circulate over the colors. + +\setupcolors + [state=start] + +\definecolor[TextColor][s=.8] +\definecolor[PageColor][s=.6] +\definecolor[LineColor][s=.4] + +\definecolor[red] [r=.4] \definecolor[cyan] [g=.4,b=.4] +\definecolor[green][g=.4] \definecolor[magenta][r=.4,b=.4] +\definecolor[blue] [b=.4] \definecolor[yellow] [r=.4,g=.4] + +\definecolor[linecolor 1][red] \definecolor[linecolor 5][cyan] +\definecolor[linecolor 2][green] \definecolor[linecolor 6][magenta] +\definecolor[linecolor 3][blue] \definecolor[linecolor 4][yellow] + +%D We use variables to make sure that the graphics are reused +%D but unique. + +\setupMPvariables[pageframe][pagecolor=PageColor,linecolor=LineColor] +\setupMPvariables[textframe][textcolor=TextColor,linecolor=LineColor] + +\setupbackgrounds + [page] + [background={pageframe,nextpage}] + +\defineoverlay [pageframe] [\uniqueMPgraphic{pageframe}] +\defineoverlay [textframe] [\uniqueMPgraphic{textframe}] +\defineoverlay [nextpage] [\overlaybutton{forward}] + +\startuniqueMPgraphic{pageframe}{pagecolor,linecolor} + path p ; p := fullsquare xyscaled (\overlaywidth,\overlayheight) ; + pickup pencircle scaled 10pt ; + fill p withcolor \MPvar{pagecolor} ; + draw p withcolor \MPvar{linecolor} ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{textframe}{textcolor,linecolor} + path p ; p := fullcircle xyscaled (\overlaywidth,\overlayheight) ; + pickup pencircle scaled 10pt ; + fill p withcolor \MPvar{textcolor} ; + draw p withcolor \MPvar{linecolor} ; +\stopuniqueMPgraphic + +%D The rest of the file implements the nasty part: typesetting +%D text embedded in a graphic. The text is collected in a box +%D so that we can reuse it. + +\newbox\CollectedIdeas +\newcounter\CurrentTopic + +\def\StartItem% + {\setbox\CollectedIdeas=\hbox\bgroup + \ifdim\wd\CollectedIdeas>0pt \unhbox\CollectedIdeas\hskip25pt \fi + \setbox\scratchbox=\hbox\bgroup + \framed + [width=160pt,height=160pt,align=middle,frame=off, + background=textframe,offset=15pt,top=\vfill,bottom=\vfill] + \bgroup} + +\def\StopItem% + {\egroup + \egroup + \setbox\scratchbox=\hbox{\lower.5\ht\scratchbox\box\scratchbox}% + \ht\scratchbox=.5\ht\scratchbox + \dp\scratchbox= \ht\scratchbox + \box\scratchbox + \egroup + \startstandardmakeup + \dontcomplain + \leftskip 0pt plus 50pt + \rightskip 0pt plus 50pt + \parfillskip 0pt + \baselineskip 100pt + \unhcopy\CollectedIdeas + \stopstandardmakeup} + +\def\StartIdea% + {\ifnum\CurrentTopic=6 \doglobal\newcounter\CurrentTopic \fi + \doglobal\increment\CurrentTopic + \definecolor[LineColor][linecolor \CurrentTopic] + \setbox\CollectedIdeas=\null} + +\def\StopIdea% + {} + +\def\StartTitlePage% + {\startstandardmakeup + \setupalign[middle] + \def\\{\vfil\bfb\setupinterlinespace} + \bfd\setupinterlinespace + \vfil} + +\def\StopTitlePage% + {\vfil\vfil + \stopstandardmakeup} + +\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +\doifnotmode{demo}{\endinput} + +%D A simple test on functionality. + +\setupoutput[pdftex] + +\starttext + +\TitlePage{Do you know \TEX ?} + +\startbuffer +\StartIdea + \StartItem We use \TEX\ for typesetting \unknown \StopItem + \StartItem mathematical text \unknown \StopItem + \StartItem but also for text that has no math \unknown \StopItem + \StartItem or presentations like this \unknown \StopItem + \StartItem and whatever you can come up with! \StopItem +\StopIdea +\stopbuffer + +\dorecurse{6}{\getbuffer} + +\stoptext diff --git a/tex/context/base/s-pre-16.tex b/tex/context/base/s-pre-16.tex new file mode 100644 index 000000000..81f21ec60 --- /dev/null +++ b/tex/context/base/s-pre-16.tex @@ -0,0 +1,203 @@ +%D \module +%D [ file=s-pre-16, +%D version=1999.09.01, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 16, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D The first version of this style was made late summer 1999, +%D but its first usage was during a course I gave in BRNO. +%D It's a rather simple style with a dominating background. + +\setuppapersize + [S6][S6] + +\setupbodyfont + [pos,14.4pt] + +\setuplayout + [topspace=100pt, + backspace=120pt, + header=0pt, + footer=0pt, + width=middle, + height=middle] + +\setupbackgrounds + [text] + [backgroundoffset=80pt, + background=GoOn] + +\setupbackgrounds + [page] + [background={FuzzyCircle,Again}] + +\setupcolors + [state=start] + +\definecolor[gray] [s=.4] +\definecolor[white][s=.8] + +\definecolor[red] [r=.8] \definecolor[cyan] [g=.8,b=.8] +\definecolor[green][g=.8] \definecolor[magenta][r=.8,b=.8] +\definecolor[blue] [b=.8] \definecolor[yellow] [r=.8,g=.8] + +\definecolor[PageColor][gray] +\definecolor[TextColor][yellow] +\definecolor[LineColor][blue] + +\setupinteraction + [state=start, + color=LineColor, + contrastcolor=LineColor] + +\setupinteractionscreen + [option=max] + +\setupitemize + [each] + [color=blue, + symbol=FuzzyDot] + +\startuseMPgraphic{FuzzyCircle} + path p ; numeric w, h, l ; + w := OverlayWidth ; h := OverlayHeight ; + def dd = (1 randomized (1/5)) enddef ; + pickup pencircle xscaled 10pt yscaled 2pt rotated 30; + for i:=1 upto 50 : + p := (-dd,-dd)..(dd,-dd)..(dd,dd)..(-dd,dd)..cycle ; + p := p rotatedaround (center p, uniformdeviate 360) ; + p := p xscaled (w/2) yscaled (h/2) ; + l := length(p)/2 ; + p := p cutbefore point (uniformdeviate l) of p ; + p := p cutafter point (l+uniformdeviate l) of p ; + draw p withcolor \MPcolor{LineColor} randomized (.4,1) ; + endfor ; + picture s ; s := currentpicture xysized (w-15,h-15) ; + currentpicture := nullpicture ; + fill boundingbox s enlarged 60pt withcolor \MPcolor{PageColor} ; + addto currentpicture also s ; +\stopuseMPgraphic + +\startuseMPgraphic{FuzzyDot} + path p ; numeric w ; + w := BodyFontSize/2 ; + def dd = (w randomized (w/2)) enddef ; + pickup pencircle xscaled (w/2) yscaled (w/3) rotated 30 ; + for i=0 step 45 until 135 : + p := (-dd,0)--(dd,0) ; + p := p rotatedaround (origin,i-w+uniformdeviate w) ; + draw p withcolor \MPcolor{LineColor} randomized (.3,.8) ; + endfor ; +\stopuseMPgraphic + +\defineoverlay [FuzzyCircle] [\useMPgraphic{FuzzyCircle}] +\defineoverlay [GoOn] [{\setupinteraction[click=no]\overlaybutton{forward}}] +\defineoverlay [Again] [\overlaybutton{firstpage}] + +\definesymbol + [FuzzyDot] + [\lower\dp\strutbox\hbox{\useMPgraphic{FuzzyDot}}] + +\def\Item% + {\par\noindent\symbol[FuzzyDot]\hskip.5em\nobreak} + +\setupitemize + [all] + [packed] + [symbol=FuzzyDot] + +\def\NextIdea% + {\blank[back,medium] + \midaligned{\symbol[FuzzyDot]} + \blank[medium] + \blank[disable]} + +\definehead [Topic] [chapter] +\definehead [Nopic] [title] + +\setuphead + [Topic, Nopic] + [alternative=middle, + before=, + number=no, + style=\bfb] + +\setuplist + [Topic] + [alternative=g, + interaction=all] + +%D Since we want a colored text, and since color directive +%D can spoil the spacing, we use a foregroundcolor. + +\setupbackgrounds + [text] + [foregroundcolor=TextColor] + +%D Unfortunately this does not work when on the page colors +%D are set, so we play safe and say: + +\setupmakeup + [standard] + [color=TextColor] + +\def\StartIdea% + {\startstandardmakeup + \setupwhitespace[medium] + \setupblank[medium] + \setupalign[broad,middle]} + +\def\StopIdea% + {\stopstandardmakeup} + +\def\Topics#1% + {\Nopic{#1} + \startcolumns + \setupinteraction[color=TextColor,contrastcolor=TextColor] + \placelist[Topic] + \stopcolumns + \page} + +%D Some fakes. + +\def\Subject {\Topic} +\def\Subjects {} + +%D A bonus (copied from \type {s-pre-02} but with a different +%D vertical alignment. + +\def\StartTitlePage% + {\startstandardmakeup + \bfd\setupinterlinespace + \setupalign[middle] + \vfil + \let\\=\vfil} + +\def\StopTitlePage% + {\vfil + \stopstandardmakeup} + +\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +\doifnotmode{demo}{\endinput} + +\starttext + +\Topics{...} + +\StartIdea + \Topic{...} + ... + \NextIdea + ... +\StopIdea + +\stoptext diff --git a/tex/context/base/s-pre-17.tex b/tex/context/base/s-pre-17.tex new file mode 100644 index 000000000..798f30cf8 --- /dev/null +++ b/tex/context/base/s-pre-17.tex @@ -0,0 +1,399 @@ +%D \module +%D [ file=s-pre-17, +%D version=1999.08.20, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 17, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\setupbodyfont + [12pt,ss] + +\setupcolors + [state=start] + +\setupsystem + [random=medium] + +\setupbackgrounds + [state=repeat] + +\setupbackgrounds + [page] + [background={page,forward}] + +\setupbackgrounds + [text][text] + [background=blowup] + +\setupinteraction + [state=start, + %click=off, + color=TitleColor, + contrastcolor=TitleColor] + +\setupinteractionscreen + [option=max] + +\setuptolerance + [verytolerant,stretch] + +\definecolor [BackColor] [s=.30] +\definecolor [PageColor] [g=1] +\definecolor [FrameColor] [r=1] +\definecolor [TitleColor] [y=1] +\definecolor [ArrowColor] [b=1] + +\defineoverlay [title] [\useMPgraphic{title}] +\defineoverlay [page] [\useMPgraphic{page}] +\defineoverlay [blowup] [\overlaybutton{page(\realfolio)}] +\defineoverlay [forward] [\overlaybutton{forward}] + +\startMPpositiongraphic{mppos:connection} + path pa, pb, pc ; pair ca, cb ; + initialize_box(\MPpos{\MPvar{self}}) ; pa := pxy ; ca := cxy ; + initialize_box(\MPpos{\MPvar{prev}}) ; pb := pxy ; cb := cxy ; + pickup pencircle scaled .5pt ; + pa := pa enlarged 10pt ; + pb := pb enlarged 10pt ; + for i=1 upto 10 : + draw pa randomized 20pt withcolor \MPcolor{FrameColor} ; + endfor ; + if \MPp{\MPvar{prev}}>0 : + pair a, b, c, d ; + for i=1 upto 25 : + a := .5[ulcorner pa,urcorner pa] randomized (10pt,10pt) ; + b := .5[llcorner pb,lrcorner pb] randomized (20pt,10pt) ; + c := .5[a,b] rotatedaround(a,-25) randomized (5pt,5pt) ; + d := .5[a,b] rotatedaround(a,+25) randomized (5pt,5pt) ; + draw (a--b) withcolor \MPcolor{ArrowColor} ; + draw (d--a--c) withcolor \MPcolor{ArrowColor} ; + endfor ; + fi ; + anchor_box(\MPanchor{\MPvar{self}}) ; +\stopMPpositiongraphic + +\startuseMPgraphic{title} + pickup pencircle scaled .5pt ; + for i=1 upto 10 : + draw + fullsquare xyscaled(OverlayWidth,OverlayHeight) + enlarged 10pt randomized 20pt + withcolor \MPcolor{TitleColor} ; + endfor ; +\stopuseMPgraphic + +\startuseMPgraphic{page} + StartPage ; + pickup pencircle scaled .5pt ; + fill Page withcolor \MPcolor{BackColor} ; + for i=1 upto 20 : + draw Page enlarged -50pt randomized 50pt withcolor \MPcolor{PageColor} ; + endfor ; + StopPage ; +\stopuseMPgraphic + +\def\StartText% + {\bgroup + \getrandomdimen\scratchdimen{250pt}{350pt}% + \edef\TextWidth{\the\scratchdimen}% + \setbox\scratchbox=\hbox\bgroup + \hsize\TextWidth + \setupframedtexts + [before=,after=, + width=fit,align=right, % normal, + frame=off,foregroundcolor=white]% + \framedtext\bgroup} + +\def\BlowX{450pt} % \def\BlowX{600pt} +\def\BlowY{300pt} % \def\BlowY{450pt} +\def\BlowV {50pt} % \def\BlowV{100pt} +\def\BlowH {75pt} % \def\BlowH{100pt} +\def\BackO {50pt} % \def\BackO {50pt} + +\def\StopText% + {\egroup\egroup + \doglobal\increment\CurrentBlaBla + \let\PrevBlaBla\CurrentBlaBla \doglobal\decrement\PrevBlaBla + \let\NextBlaBla\CurrentBlaBla \doglobal\increment\NextBlaBla + \setMPpositiongraphic + {connection:\CurrentBlaBla}% + {mppos:connection}% + {seed=\CurrentBlaBla, + prev=connection:\PrevBlaBla, + next=connection:\NextBlaBla}% + \SetBlowUp{connection:\CurrentBlaBla}\BlowX\BlowY\BlowH\BlowV + \hbox to 600pt +% {\getrandomdimen\scratchdimen{50pt}{100pt}% + {\getrandomdimen\scratchdimen{50pt}{75pt}% + \hskip0pt plus \scratchdimen minus \scratchdimen + \hpos{connection:\CurrentBlaBla}% + {\framed + [frame=off, + offset=overlay, + backgroundoffset=\BackO, + background=blowup] + {\box\scratchbox}}% +% \getrandomdimen\scratchdimen{50pt}{100pt}% + \getrandomdimen\scratchdimen{50pt}{75pt}% + \hskip0pt plus \scratchdimen minus \scratchdimen}% +% \getrandomdimen\scratchdimen{100pt}{150pt}% + \getrandomdimen\scratchdimen{75pt}{125pt}% + \vskip\scratchdimen + \egroup} + +\def\xStartText + {\bgroup + \setbox\scratchbox=\hbox\bgroup + \framed + [frame=off,foregroundcolor=white] + \bgroup} + +\def\xStopText{\StopText} + +\def\SetBlowUp#1#2#3#4#5% tag width height hoffset voffset + {\scratchdimen=\MPw{#1}% + \advance\scratchdimen-#2 % + \divide\scratchdimen by 2 + \advance\scratchdimen by \MPx{#1}\relax + \ifdim\scratchdimen<0pt \scratchdimen=0pt \fi + \ScaledPointsToBigPoints{\number\scratchdimen}\TextX + \advance\scratchdimen by #2 % + \ScaledPointsToBigPoints{\number\scratchdimen}\TextW + % + \scratchdimen=\MPh{#1}% + \advance\scratchdimen-#3 % + \divide\scratchdimen by 2 + \advance\scratchdimen\MPy{#1}\relax + \ifdim\scratchdimen<0pt \scratchdimen=0pt \fi + \ScaledPointsToBigPoints{\number\scratchdimen}\TextY + \advance\scratchdimen by #3 + \ScaledPointsToBigPoints{\number\scratchdimen}\TextH + % + \def\PDFpageviewkey{ fitr \TextX\space\TextY\space\TextW\space\TextH}% + \def\PDFpageviewwrd{ /FitR \TextX\space\TextY\space\TextW\space\TextH}% + \edef\PDFpageview{/View [\PDFpageviewwrd]}} + +\def\xSetBlowUp#1#2#3#4#5% tag width height hoffset voffset + {\scratchdimen\MPx{#1}\relax + \ifdim\scratchdimen<#4 + \ScaledPointsToBigPoints{0}\TextX + \multiply\scratchdimen 2 + \else + \advance\scratchdimen-#4 + \ScaledPointsToBigPoints{\number\scratchdimen}\TextX + \advance\scratchdimen#4 + \advance\scratchdimen#4 + \fi + \advance\scratchdimen\MPw{#1}% + \ScaledPointsToBigPoints{\number\scratchdimen}\TextW + % + \scratchdimen\MPy{#1}\relax + \ifdim\scratchdimen<#5 + \ScaledPointsToBigPoints{0}\TextY + \multiply\scratchdimen 2 + \else + \advance\scratchdimen-#5 + \ScaledPointsToBigPoints{\number\scratchdimen}\TextY + \advance\scratchdimen#5 + \advance\scratchdimen#5 + \fi + \advance\scratchdimen\MPh{#1}% + \ScaledPointsToBigPoints{\number\scratchdimen}\TextH + % + \def\PDFpageviewkey{ fitr \TextX\space\TextY\space\TextW\space\TextH}% + \def\PDFpageviewwrd{ /FitR \TextX\space\TextY\space\TextW\space\TextH}% + \edef\PDFpageview{/View [\PDFpageviewwrd]}} + +\dontcomplain + +\def\StartPage#1% + {\doStartPage{1}{#1}} + +\def\doStartPage#1#2% + {\def\StopPage{\doStopPage{#1}{#2}}% + \setbox\scratchbox=\hbox\bgroup + \valign\bgroup\ignorespaces##\vss\cr} + +\def\doStopPage#1#2% + {\cr + \egroup + \egroup + \setbox\scratchbox=\vbox + {\vskip100pt + \hbox \ifcase#1 spread 200pt \else to \wd\scratchbox \fi + {\hss + \switchtobodyfont[big]% + \bfd\setupinterlinespace + \ifcase#1\else \SetBlowUp{title:\realfolio}\BlowX\BlowY\BlowH\BlowV \fi + \hpos{title:\realfolio} + {\framed + [frame=off,align=middle, + foregroundcolor=white, + background={title,blowup}] + {#2}}% + \hss} + \vskip100pt + \box\scratchbox} + \doFlushPage} + +\def\doFlushPage + {\scratchdimen=\ht\scratchbox + \advance\scratchdimen \dp\scratchbox + \advance\scratchdimen 100pt + \edef\height{\the\scratchdimen} + \scratchdimen=\wd\scratchbox + \advance\scratchdimen 100pt + \edef\width {\the\scratchdimen} + \expanded{\definepapersize[MASTER][width=\width,height=\height]} + \setuppapersize + [MASTER][MASTER] + \setuplayout + [topspace=25pt,backspace=25pt, + width=middle,header=0pt,footer=0pt,height=middle] + \centerbox{\box\scratchbox} + \page} + +\def\StartTopic#1% + {\unskip\unskip\cr + \doglobal\increment(\CurrentBlaBla,100)% + \vbox\bgroup + \vskip100pt + \bgroup + \definecolor[FrameColor][TitleColor] + \switchtobodyfont[big] + \bfd\setupinterlinespace + \xStartText#1\xStopText + \vskip25pt + \egroup} + +\def\StopTopic% + {\vskip-\lastskip + \vskip100pt + \egroup + \ignorespaces} + +\def\TitlePage#1% + {\doStartPage{0}{\def\\{\vskip1ex\bfc\def\\{\vskip1ex\bfb}}#1} + \StopPage} + +\doifnotmode{demo}{\endinput} + +\setupoutput[pdftex] + +\starttext + +\TitlePage{About Text\\Today's Talk\\Hans Hagen} + +\StartPage{The First Page} + +\StartTopic{Some Text} + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText + \StartText \input knuth \StopText +\StopTopic + +\StartTopic{Another Text} + \StartText \input tufte \StopText + \StartText \input zapf \StopText + \StartText \input knuth \StopText +\StopTopic + +\StartTopic{Some More Text} + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText + \StartText \input tufte \StopText +\StopTopic + +\StartTopic{Some Text Agian} + \StartText \input tufte \StopText + \StartText \input zapf \StopText + \StartText \input knuth \StopText + \StartText \input tufte \StopText +\StopTopic + +\StopPage + +\StartPage{The Second Page} + +\StartTopic{Some Text} + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText +\StopTopic + +\StartTopic{Another Text} + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText +\StopTopic + +\StartTopic{Some Nice Text} + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText + \StartText \input tufte \StopText + \StartText \input tufte \StopText +\StopTopic + +\StartTopic{Some Funny Text} + \StartText \input tufte \StopText + \StartText \input knuth \StopText +\StopTopic + +\StartTopic{Quite Some Text} + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText +\StopTopic + +\StartTopic{Even More Text} + \StartText \input knuth \StopText + \StartText \input zapf \StopText + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText +\StopTopic + +\StopPage + +\StartPage{The Third Page} + +\StartTopic{Some Short Text} + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText +\StopTopic + +\StartTopic{Some Minimal Text} + \StartText \input tufte \StopText + \StartText \input zapf \StopText +\StopTopic + +\StartTopic{Some More Text} + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText + \StartText \input tufte \StopText + \StartText \input tufte \StopText +\StopTopic + +\StopPage + +\stoptext diff --git a/tex/context/base/s-pre-18.tex b/tex/context/base/s-pre-18.tex new file mode 100644 index 000000000..407f30824 --- /dev/null +++ b/tex/context/base/s-pre-18.tex @@ -0,0 +1,177 @@ +%D \module +%D [ file=s-pre-18, +%D version=1999.08.20, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 18, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + + + +% output=pdftex interface=en + +% todo: met pos en dan iedere titel + +\setuppapersize + [S6][S6] + +\setupbodyfont + [loc,ppl] + +\setupcolors + [state=start] + +\definecolor [shade-1] [s=.7] +\definecolor [shade-2] [s=.1] + +\definecolor [shade-3] [s=.8] +\definecolor [shade-4] [b=.8] + +\definecolor [shade-5] [g=.6] + +\setuplayout + [topspace=1cm, + height=fit, + backspace=1cm, + width=middle, + header=0pt, + footer=0pt, + bottomdistance=1cm] + +\setupbackgrounds + [state=repeat] + +\setupbackgrounds [page] [background=page] + +\defineoverlay [page] [\useMPgraphic{page}] +\defineoverlay [text] [\useMPgraphic{text}] + +\startuseMPgraphic{page} + StartPage ; + path p ; numeric s ; pair cp ; cp := center Page ; + s := define_circular_shade(cp,cp,0,TextWidth, + \MPcolor{shade-1},\MPcolor{shade-2}) ; + fill Page withshade s ; + p := fullcircle xyscaled (TextWidth+1cm, TextHeight+1cm) shifted cp ; + s := define_circular_shade(cp,cp,0,TextWidth,\MPcolor{shade-3}, + \MPcolor{shade-4}) ; + fill p withshade s ; + StopPage +\stopuseMPgraphic + +\startuseMPgraphic{text} + StartPage ; + path p ; numeric s, t ; pair cp ; cp := center Page ; + s := define_circular_shade(cp,cp,0,TextWidth, + \MPcolor{shade-1},\MPcolor{shade-2}) ; + fill Page withshade s ; + p := llcorner Field[Text][Bottom] -- + lrcorner Field[Text][Bottom] -- + urcorner Field[Text][Text] -- + ulcorner Field[Text][Text] -- cycle ; + p := p enlarged .5cm randomized .5cm ; + t := define_circular_shade(cp,cp,0,TextWidth,\MPcolor{shade-3}, + \MPcolor{shade-4}) ; + fill p withshade t ; + + def bottom_menu_button (expr nn, rr, pp, xx, yy, ww, hh, dd) = + if (pp>0) and (rr>0) : + if nn = 1 : + p := (0,0)--(ww,hh/2)--(0,hh)--cycle ; + elseif nn = 2 : + p := (0,hh/2)--(ww,hh)--(ww,0)--cycle ; + else : + p := origin--cycle ; + fi ; + fill p randomized 2.5mm shifted (xx,yy) withshade s ; + fi ; + enddef ; + + \MPmenubuttons{bottom} + + if length \MPstring{topic} > 0 : + graphictext + \MPstring{topic} + scaled 3 + shifted ulcorner Field[Text][Text] + shifted (0,-1.5cm) + withshade s ; + fi ; + + StopPage ; +\stopuseMPgraphic + +\setupinteractionmenu + [bottom] + [state=start, + frame=off, + left=\hfill, + middle=\hskip.5cm, + width=2\bottomheight, + position=yes] + +\startinteractionmenu[bottom] + \but [previouspage] \\ + \but [nextpage] \\ +\stopinteractionmenu + +\setupinteraction + [state=start, + click=no, + color=shade-5, + contrastcolor=shade-5, + menu=on] + +\setupwhitespace + [big] + +\def\Topic#1% + {\page + \setMPtext{topic}{#1} + \vbox to 2cm{}} + +\setMPtext{topic}{} + +\def\StartTitlePage% + {\startstandardmakeup[bottomstate=none] + \setupalign[middle] + \vfill} + +\def\StopTitlePage% + {\stopstandardmakeup + \setuplayout[bottom=1.5cm] + \setupbackgrounds[page][background=text]} + +\def\TitleString#1#2% + {\indent + \startMPcode + graphictext + "#2" + scaled #1 + withdrawcolor .4white + withfillcolor .7white + withpen pencircle scaled 2pt ; + \stopMPcode + \vfill} + +\doifnotmode{demo}{\endinput} + +\starttext + +\StartTitlePage + \TitleString{8}{Welcome} + \TitleString{4}{to my favourite} + \TitleString{8}{Quotes} +\StopTitlePage + +\Topic {Douglas R. Hofstadter} \input douglas \page +\Topic {Donald E. Knuth} \input knuth \page +\Topic {Edward R. Tufte} \input tufte \page +\Topic {Hermann Zapf} \input zapf \page + +\stoptext diff --git a/tex/context/base/s-pre-19.tex b/tex/context/base/s-pre-19.tex new file mode 100644 index 000000000..3715d6ac1 --- /dev/null +++ b/tex/context/base/s-pre-19.tex @@ -0,0 +1,347 @@ +%D \module +%D [ file=s-pre-19, +%D version=2000.07.31, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 19, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This style is made in the process or writing the \METAFUN\ +%D manual. It exploits a few tricks, like graphics calculated +%D using positional information. It also uses the (at that +%D moment) new menu list placement alternative. If you forget +%D about the definition of the button shapes, which is +%D complicated in any system, this style is not even that hard +%D to follow. Watch how the left side of the buttons follow +%D the right side of the text graphic. +%D +%D While playing bit with this style, the random alternative +%D made me think of those organic building with non equal +%D windows (we have a few in The Netherlands), so I decided to +%D label this style as \type {pre-organic}. +%D +%D At the end of this file, there is a small test file, so +%D when you process this file with \TEXEXEC\ and the options +%D \type {--mode=demo} and \type {--pdf}, you will get a demo +%D document. + +%D We use one of the standard screen \quote {paper} sizes, and +%D map it onto the same size, so that we get a nicely cropped +%D page. + +\setuppapersize + [S6][S6] + +%D Like in the \METAFUN\ manual, we use the Palatino as main +%D bodyfont. This font is quite readable on even low +%D resolution screens, although I admit that this style is +%D developed using an $1400\times1050$ pixel LCD screen, so I +%D may be biased. + +%\startmode[asintended] \setupbodyfont[ppl] \stopmode + +%D The layout specification sets up a text area and a right +%D edge area where the menus will go. Watch the rather large +%D edge distance. By setting the header and footer dimensions +%D to zero, we automatically get rid of page body ornaments, +%D like the pagenumber. + +\setuplayout + [topspace=48pt, + backspace=48pt, + cutspace=12pt, + width=400pt, + margin=0cm, + rightedge=88pt, + rightedgedistance=48pt, + header=0cm, + footer=0cm, + height=middle] + +%D We use a moderate, about a line height, interparagraph +%D white space. + +\setupwhitespace + [big] + +%D Of course we use colors, since on computer displays they +%D come for free. + +\setupcolors + [state=start] + +\definecolor [red] [r=.75] +\definecolor [yellow] [r=.75,g=.75] +\definecolor [gray] [s=.50] +\definecolor [white] [s=.85] + +\definecolor [PageColor] [yellow] +\definecolor [TextColor] [white] +\definecolor [OrnamentColor] [red] +\definecolor [InteractionColor] [red] +\definecolor [ContrastColor] [gray] + +%D This is an interactive document, so we enable interaction. +%D In this style, we disable the viewer's \quote {highlight a +%D hyperlink when it's clicked on} feature. We will use a +%D menu, so we enable menus. Later we will see the contract +%D color |<|hyperlinks gets that color when we are already on +%D the location|>| in action. + +\setupinteraction + [state=start, + click=off, + color=InteractionColor, + contrastcolor=ContrastColor, + menu=on] + +%D The menu itself is set up as follows. Because we will +%D calculate menubuttons based on their position on the page, +%D we have to keep track of the positions. Therefore, we set +%D the \type {position} variable to \type {yes}. + +\setupinteractionmenu + [right] + [frame=off, + position=yes, + align=middle, + topoffset=-.75cm, + bottomoffset=-.75cm, + color=gray, + contrastcolor=gray, + style=bold, + before=, + after=] + +%D The menu content is rather sober: a list of topics (later +%D we will define the command that generates topic entries), +%D and a close button. + +\startinteractionmenu[right] + \placelist[Topic][alternative=right] + \vfill + \but [CloseDocument] close \\ +\stopinteractionmenu + +%D We have now arived at the more interesting part of the style +%D definition: the graphic that goes in the page background. +%D Because this graphic will change, we define a usable +%D \METAPOST\ graphic. Page backgrounds are recalculated each +%D page, opposite to the other backgrounds that are calculated +%D when a new background is defined, or when repetitive +%D calculation is turned on. + +\setupbackgrounds + [page] + [background=page] + +\defineoverlay + [page] + [\useMPgraphic{page}] + +\setupMPvariables + [page] + [alternative=3] + +\startuseMPgraphic{page} + + \includeMPgraphic{rightsuperbutton} + + StartPage ; + + path p, q ; pickup pencircle scaled 3pt ; + + p := Field[Text][Text] enlarged 36pt superellipsed .90 ; + + fill Page withcolor \MPcolor{PageColor} ; + fill p withcolor \MPcolor{TextColor} ; + draw p withcolor \MPcolor{OrnamentColor} ; + + p := Field[Text][Text] enlarged 48pt superellipsed .90 ; + + def right_menu_button (expr nn, rr, pp, xx, yy, ww, hh, dd) = + if (pp>0) and (rr>0) : + q := rightsuperbutton(p,xx,yy,RightEdgeWidth,hh) ; + fill q withcolor \MPcolor{TextColor} ; + draw q withcolor if rr=2 : \MPcolor{ContrastColor} + else : \MPcolor{InteractionColor} fi ; + fi ; + enddef ; + + \MPmenubuttons{right} + + StopPage ; +\stopuseMPgraphic + +\startuseMPgraphic{page} + + \includeMPgraphic{rightsuperbutton} + + StartPage ; + + numeric alternative, seed, superness, squeezeness, randomness ; + path p, q ; transform t ; + + alternative := \MPvar{alternative} ; + seed := uniformdeviate 100 ; + + if alternative > 10 : + superness := .85 + ((\realfolio-1)/\lastpage) * .15 ; + squeezeness := 12pt - ((\realfolio-1)/\lastpage) * 10pt ; + else : + superness := .90 ; + squeezeness := 12pt ; + fi ; + + randomness := squeezeness ; + + alternative := alternative mod 10 ; + + t := identity if alternative=3: shifted (9pt,-9pt) fi ; + + % first we draw the shape that surrounds the text + + randomseed := seed ; + + p := Field[Text][Text] enlarged if + alternative = 1 : 36pt superellipsed superness elseif + alternative = 2 : 36pt squeezed squeezeness elseif + alternative = 3 : 36pt randomized randomness else + : 36pt fi ; + pickup pencircle scaled 3pt ; + + fill Page withcolor \MPcolor{PageColor} ; + fill p withcolor \MPcolor{TextColor} ; + draw p withcolor \MPcolor{OrnamentColor} ; + + % we set p to the wider shape from which we will chip off pieces + + randomseed := seed ; + + p := ( Field[Text][Text] enlarged if + alternative = 1 : 48pt superellipsed superness elseif + alternative = 2 : 48pt squeezed squeezeness elseif + alternative = 3 : 36pt randomized randomness else + : 48pt fi ) transformed t ; + + % calls to *_menu_button are generated automatically ... + + vardef right_menu_button (expr nn, rr, pp, xx, yy, ww, hh, dd) = + save q ; path q ; + if (pp>0) and (rr>0) : + q := rightsuperbutton(p,xx,yy,RightEdgeWidth,hh) ; % \MPw{menu:right:\realfolio} + fill q withcolor \MPcolor{TextColor} ; + draw q withcolor if rr=2 : \MPcolor{ContrastColor} + else : \MPcolor{InteractionColor} fi ; + fi ; + enddef ; + + % ... and inserted when the graphic data is flushed here ... + + \MPmenubuttons{right} + + StopPage ; +\stopuseMPgraphic + +\startuseMPgraphic{rightsuperbutton} + +vardef rightsuperbutton (expr pat, xpos, ypos, wid, hei) = + + save p, ptop, pbot, t, b, edge, shift, width, height ; + path p, ptop, pbot ; pair t, b ; numeric edge, shift, width, height ; + + edge := xpos + wid ; shift := ypos + hei ; + + p := rightpath pat ; + + ptop := ((-infinity,shift)--(edge,shift)) ; + pbot := ((-infinity,shift-hei)--(edge,shift-hei)) ; + + t := p intersection_point ptop ; + b := p intersection_point pbot ; + + p := subpath(0,xpart (p intersectiontimes ptop)) of p ; + p := subpath(xpart (p intersectiontimes pbot),length(p)) of p ; + + (p -- t -- point 1 of ptop & + point 1 of ptop -- point 1 of pbot & + point 1 of pbot -- b + -- cycle) + +enddef ; + +\stopuseMPgraphic + +%D Topics are identified with \type {\Topic}, which is an +%D instance of chapter headings. The number is made invisible. +%D Since it still is a numbered section header, \CONTEXT\ will +%D write the header to the table of contents. + +\definehead + [Topic] + [chapter] + +\setuphead + [Topic] + [number=no] + +%D We will use a bold font in the table of contents. We also +%D force a complete list. + +\setuplist + [Topic] + [criterium=all, + style=bold, + before=, + after=] + +%D The \type {\TitlePage} macro looks horrible, because we +%D want to keep the interface simple: a list of small +%D sentences, separated by \type {\\}. + +\def\StartTitlePage + {\startstandardmakeup + \switchtobodyfont[big] + \def\\{\vfill\bfb\let\\=\par} + \bfd\setupinterlinespace\gray + \vskip.5cm} + +\def\StopTitlePage + {\\\vskip.5cm % the \\ is really needed + \stopstandardmakeup} + +\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +%D A couple of goodies: + +\def\Subject {\Topic} +\def\Topics #1{} +\def\Subjects {} + +%D For those who want to test: + +\doifnotmode{demo}{\endinput} + +\starttext + +\setupMPvariables[page][alternative=3] + +\TitlePage + {A Few Nice Quotes\\ + A Simple Style Demo\\ + Hans Hagen, August 2000} + + +\Topic {Douglas R. Hofstadter} \input douglas \page +\Topic {Donald E. Knuth} \input knuth \page +\Topic {Edward R. Tufte} \input tufte \page +\Topic {Hermann Zapf} \input zapf \page +%Topic {David F. Stork} \input stork \page + +\stoptext diff --git a/tex/context/base/s-pre-22.tex b/tex/context/base/s-pre-22.tex new file mode 100644 index 000000000..cb09816dc --- /dev/null +++ b/tex/context/base/s-pre-22.tex @@ -0,0 +1,319 @@ +%D \module +%D [ file=s-pre-22, +%D version=2000.08.07, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 22, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This style was made on behalf of the \PDFTEX\ presentation +%D at \TUG\ 2000. It cycled a summary of each talk, with name +%D and title. When documenting this style, I changed +%D reprocessing into pushing on layers. +%D +%D A \quote {problem} like this can be solved in several ways: +%D +%D \startitemize +%D \item writing a lot of semi||complex \TEX\ code as shown +%D \item keeping track of positions and draw everything on the +%D page layer +%D \item defining an overlay for each summary and changing the +%D order when flushing +%D \item maintaining a so called field stack +%D \stopitemize +%D +%D We go for the first method. We assume that summaries are +%D simple text snippets. + +\startmode[asintended] \setupbodyfont[lbr] \stopmode + +\setupbodyfont[14.4pt] + +%D We use the whole page area. + +\setuppapersize + [S6][S6] + +\setuplayout + [topspace=0cm, + backspace=0cm, + header=0pt, + footer=0pt, + width=middle, + height=middle] + +%D We define a couple of matching colors and gray scales. +%D Watch out, some are really meant to look dim. + +\setupcolors + [state=start] + +\definecolor[PageColor] [s=.50] +\definecolor[TextColor] [s=.80] +\definecolor[DoneColor] [s=.65] + +\definecolor[TopColor] [r=.5,g=.6,b=.7] +\definecolor[BotColor] [r=.6,g=.7,b=.5] +\definecolor[DotColor] [r=.7,g=.5,b=.6] + +%D We will use foreground colors. Because these can interfere +%D with the colors they overload, we can bets make sure that +%D we don't have local colors. + +\setupinteraction + [state=start, + color=, + contrastcolor=] + +%D The presentation is supposed to cycle automatically. + +\setupinteractionscreen + [option=max, + delay=5] + +\setuppagetransitions + +%D We will use random positioning of objects. + +\setupsystem + [random=medium] + +%D We have two kind of graphics: the page background and +%D the shape around the textual elements. + +\defineoverlay [shape] [\uniqueMPgraphic{shape}] +\defineoverlay [page] [\reuseMPgraphic{page}] + +\startreusableMPgraphic{page} + StartPage ; + filldraw Page withcolor \MPcolor{PageColor} ; + pickup pencircle scaled .375cm ; + for i=1 upto 200 : + drawdot center Page randomized (PaperWidth,PaperHeight) + withcolor \MPcolor {DotColor} ; + endfor ; + StopPage ; +\stopreusableMPgraphic + +\startuniqueMPgraphic{shape} + path p ; + p := unitsquare xyscaled(OverlayWidth,OverlayHeight) superellipsed .90 ; + draw p withpen pencircle scaled .50cm withcolor \MPcolor{PageColor} ; + fill p withcolor OverlayColor ; + draw p withpen pencircle scaled .25cm withcolor OverlayLineColor ; + currentpicture := currentpicture xysized(OverlayWidth,OverlayHeight) ; +\stopuniqueMPgraphic + +%D The resizing at the end is needed to get a nice inverted +%D hyperlink when we click on it in a browser. + +%D Behind the page we put a forward button: + +\defineoverlay [forward] [\overlaybutton{forward}] + +%D The content will be managed by means of two layers. + +\definelayer [main] \defineoverlay [main] [\composedlayer{main}] +\definelayer [temp] \defineoverlay [temp] [\composedlayer{temp}] + +%D The first layer will hold everything to be shown, while +%D the second one gets the data we currently focus on. +%D Therefore the first layer will not be flushed each page. + +\setuplayer + [main] + [state=repeat] + +%D All the overlays go onto the page area. + +\setupbackgrounds + [page] + [background={page,forward,main,temp}] + +%D We have to collect all data before we typeset it. Each +%D element will be typeset dim and bright. The dim +%D alternatives will be collected on the main layer, but each +%D bring one goes onto a box stack. + +\initializeboxstack{Summary} +\initializeboxstack{Subtext} + +%D The macros that take care of all this manipulations look +%D more complicated than they actually are. We use a +%D scratchbox to collect and inspect data. Also, because we +%D typeset each element twice, we need to make sure that we use +%D the same random seed for both. + +\doglobal\newcounter\CurrentSummary + +\def\StartSummary% bottom bot-title top-title + {\dodoublegroupempty\doStartSummary} + +\def\doStartSummary#1#2% + {\doglobal\increment\CurrentSummary + \setbox\scratchbox=\hbox{\strut#1} + \getrandomseed\RandomSeed + \setlayer[main] + {\RandomSubtextBox{DoneColor}{BotColor}{BotColor}} + \setrandomseed\RandomSeed + \savebox{Subtext}{\CurrentSummary} + {\RandomSubtextBox{TextColor}{BotColor}{black}} + \setbox\scratchbox=\hbox \bgroup + \setbox\scratchbox=\hbox{\bfb\setstrut\strut\quad#2\quad}% + \SetAcceptableWidth + \framed [offset=0pt,width=fit,frame=off,align=middle,strut=no] + \bgroup \setupwhitespace[big] + \doifsomething{#2}{\noindent\box\scratchbox\blank}} + +\def\StopSummary + {\egroup \egroup + \getrandomseed\RandomSeed + \setlayer[main] + {\RandomSummaryBox{DoneColor}{TopColor}{TopColor}} + \setrandomseed\RandomSeed + \savebox{Summary}{\CurrentSummary} + {\RandomSummaryBox{TextColor}{TopColor}{black}}} + +%D A \type {\doStartSummary#1#2#3\StopSummary} could have been +%D used too but this one is less sensitive for catcode changes +%D (not that we expect problems like this in this kind of +%D application). + +%D The width is either derived from the width ot the title or +%D at random. The final width of the box is detemined by the +%D content. + +\def\SetAcceptableWidth + {\scratchdimen=.5\makeupwidth + \ifdim\wd\scratchbox>.5\makeupwidth + \getrandomdimen\hsize{\wd\scratchbox}{.8\makeupwidth}% + \else + \getrandomdimen\hsize{.5\makeupwidth}{.7\makeupwidth}% + \fi} + +%D The subtext box goes at the bottom, somewhere in the right +%D corner. + +\def\RandomSubtextBox#1#2#3% + {\vbox to \makeupheight + {\vfill + \hbox to \makeupwidth + {\hfill + \button + [offset=2ex,frame=off,background=shape,strut=no, + backgroundcolor=#1,framecolor=#2,foregroundcolor=#3] + {\copy\scratchbox}% + [previouspage]% + \getrandomdimen\scratchdimen{.5cm}{2.5cm}% + \hskip\scratchdimen} + \getrandomdimen\scratchdimen{.5cm}{1.5cm} + \vskip \scratchdimen}} + +%D The main text goes in the top half of the page, not to +%D far from the center. The last \type {\vskip} makes sure +%D that we don't clash with the subtexts. + +\definereference[thispage][page(\CurrentSummary)] + +\def\RandomSummaryBox#1#2#3% + {\vbox to \makeupheight + {\getrandomdimen\scratchdimen{.5cm}\makeupheight + \vskip 0pt plus \scratchdimen + \hbox to \makeupwidth + {\getrandomdimen\scratchdimen{.5cm}\makeupwidth + \hskip 0pt plus \scratchdimen + \button + [offset=3ex,frame=off,background=shape,strut=no, + backgroundcolor=#1,framecolor=#2,foregroundcolor=#3] + {\copy\scratchbox}% + [thispage]% + \getrandomdimen\scratchdimen{.5cm}\makeupwidth + \hskip 0pt plus \scratchdimen} + \getrandomdimen\scratchdimen{.5cm}\makeupheight + \vskip 0pt plus \scratchdimen + \vskip.2\makeupheight}} + +%D Because we conly collect data, we hav eto make sure that at +%D some moment it is processed and flushed. The following loop +%D does this. + +\def\BuildPage + {\dorecurse{\CurrentSummary} + {\startstandardmakeup + \setlayer[temp]{\foundbox{Summary}\recurselevel} + \setlayer[temp]{\foundbox{Subtext}\recurselevel} + \stopstandardmakeup}} + +%D We hook this macro into the \type {\stoptext} macro. + +\appendtoks \BuildPage \to \everystoptext + +%D We still need a title page. + +\def\TitlePage% + {\dodoublegroupempty\doTitlePage} + +\long\def\doTitlePage#1#2% + {\ifsecondargument + \MakeTitlePage{#1}{#2} + \else\iffirstargument + \MakeTitlePage{\currentdate}{#1} + \else + \MakeTitlePage{\currentdate}{Welcome} + \fi\fi} + +\def\MakeTitlePage#1#2% + {\StartSummary{#1}{#2}\StopSummary} + +%D For old times sake: + +\long\def\StartTopic#1\StopTopic{\StartSummary#1\StopSummary} + +\doifnotmode{demo}{\endinput} + +%D The demo text. + +\starttext + +\TitlePage{Indeed}{The Title Page} + +\StartSummary{Alpha}{Title} + A simple and not too long text just to show the topic. + A simple and not too long text just to show the topic. + A simple and not too long text just to show the topic. +\StopSummary + +\StartSummary{Beta and Gamma}{Another Title} + A simple and not too long text just to show the topic. + A simple and not too long text just to show the topic. +\StopSummary + +\StartSummary{Delta}{Some Title} + A simple and not too long text just to show the topic. +\StopSummary + +\StartSummary{Epsilon}{What A Title} + A simple and not too long text just to show the topic. + A simple and not too long text just to show the topic. + A simple and not too long text just to show the topic. +\StopSummary + +\StartSummary{Zeta, Eta and Theta}{Eh, A Title} + A simple and not too long text just to show the topic. + A simple and not too long text just to show the topic. + A simple and not too long text just to show the topic. +\StopSummary + +\StartSummary{Omega} + A simple and not too long text just to show the topic. + A simple and not too long text just to show the topic. + A simple and not too long text just to show the topic. + A simple and not too long text just to show the topic. +\StopSummary + +\stoptext diff --git a/tex/context/base/s-pre-23.tex b/tex/context/base/s-pre-23.tex new file mode 100644 index 000000000..90ed18353 --- /dev/null +++ b/tex/context/base/s-pre-23.tex @@ -0,0 +1,109 @@ +%D \module +%D [ file=s-pre-20, +%D version=2000.08.07, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 20, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This style looks a lot like number 22. This time we don't +%D cycle but build up the page. One can click on the text go +%D to the page wanted. Clicking on the titl ebrings you to the +%D previous page. + +\startmode [demo] + \disablemode[demo] \usemodule[pre-22] \enablemode[demo] +\stopmode + +\startnotmode [demo] + \usemodule[pre-22] +\stopnotmode + +%D We use a simple two||color scheme. + +\definecolor[DotColor][r=.5,g=.6,b=.7] +\definecolor[TopColor][r=.7,g=.6,b=.5] +\definecolor[BotColor][TopColor] + +%D We will not delay page building. + +\let\BuildPage\relax + +%D Instead, we will flush a page for each summary. The main +%D layer is build up anyway, but we need to overlay the +%D current summary. + +\let\normalStartSummary\StartSummary +\let\normalStopSummary \StopSummary + +\def\StartSummary + {\startstandardmakeup + \normalStartSummary} + +\def\StopSummary + {\normalStopSummary + \setlayer[temp]{\foundbox{Summary}\CurrentSummary} + \setlayer[temp]{\foundbox{Subtext}\CurrentSummary} + \stopstandardmakeup} + +%D The title page is not added to the main layer (or +%D actually, it is, but we erase the layer before it's +%D used). + +\long\def\MakeTitlePage#1#2% + {\startstandardmakeup + \definereference[thispage][] + \switchtobodyfont[32pt] + \StartSummary{#1}{}#2\StopSummary + \resetlayer[main] + \setlayer[temp]{\foundbox{Summary}\CurrentSummary} + \setlayer[temp]{\foundbox{Subtext}\CurrentSummary} + \definereference[thispage][page(\CurrentSummary)] + \stopstandardmakeup} + +\doifnotmode{demo}{\endinput} + +\starttext + +\TitlePage{August 2000}{Something Very Important} + +\StartSummary{Alpha} + A simple and not too long text just to show the idea. + A simple and not too long text just to show the idea. + A simple and not too long text just to show the idea. +\StopSummary + +\StartSummary{Beta and Gamma} + A simple and not too long text just to show the idea. + A simple and not too long text just to show the idea. +\StopSummary + +\StartSummary{Delta} + A simple and not too long text just to show the idea. +\StopSummary + +\StartSummary{Epsilon} + A simple and not too long text just to show the idea. + A simple and not too long text just to show the idea. + A simple and not too long text just to show the idea. +\StopSummary + +\StartSummary{Zeta, Eta and Theta} + A simple and not too long text just to show the idea. + A simple and not too long text just to show the idea. + A simple and not too long text just to show the idea. +\StopSummary + +\StartSummary{Omega} + A simple and not too long text just to show the idea. + A simple and not too long text just to show the idea. + A simple and not too long text just to show the idea. + A simple and not too long text just to show the idea. +\StopSummary + +\stoptext diff --git a/tex/context/base/s-pre-26.tex b/tex/context/base/s-pre-26.tex new file mode 100644 index 000000000..a99516960 --- /dev/null +++ b/tex/context/base/s-pre-26.tex @@ -0,0 +1,255 @@ +%D \module +%D [ file=s-pre-26, +%D version=2001.02.18, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 26, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D modes: reverse + +%D This is a nice and simple style, written in februari +%D 2001. It uses a square papersize, derived from \type {S4}. +%D Because this style is meant to be used with Zapf +%D Chancery, I dedicate this style to Volker Schaa, a fan of +%D Zapf. + +\setuppapersize + [S44][S44] + +\startmode[asintended] + \definetypeface[zaphy][cg][calligraphy][chancery] + \setupbodyfont[zaphy,cg,12pt] +\stopmode + +\startnotmode[asintended] + \setupbodyfont[13pt] +\stopnotmode + +%D We use the whole page. + +\setuplayout + [backspace=0pt, + topspace=0pt, + header=0pt, + footer=0pt, + bottom=0pt, + width=middle, + height=middle] + +%D We will be very tolerant in alignment. + +\setuptolerance + [verytolerant,stretch] + +%D Of course use navigation, but we hide the in this case +%D ugly reverse video hyper spot. + +\setupinteraction + [state=start, + color=white, + contrastcolor=white, + style=\underbar, + click=no] + +%D This style looks best in a dark room, full screen. + +\setupinteractionscreen + [option=max] + +%D We use colors and remap a couple of standard colors. + +\setupcolors + [state=start] + +\definecolor[white] [s=.8] +\definecolor[red] [r=.7] +\definecolor[green] [g=.7] +\definecolor[blue] [b=.7] +\definecolor[yellow][r=.7,g=.7] + +\definecolor [PageColor][black] + +%D These colors will cyclic be assigned to \type +%D {TextColor}. + +\definecolor [TextColor 0][white] +\definecolor [TextColor 1][red] +\definecolor [TextColor 2][green] +\definecolor [TextColor 3][blue] +\definecolor [TextColor 4][yellow] + +\definecolor [TextColor] [TextColor 0] + +%D We will collect everything in a layer. + +\definelayer + [main] + [state=repeat] + +%D We have quite some overlays. + +\defineoverlay [page] [\reuseMPgraphic{page}] +\defineoverlay [text] [\useMPgraphic{text}] +\defineoverlay [next] [\overlaybutton{nextpage}] +\defineoverlay [prev] [\overlaybutton{previouspage}] +\defineoverlay [main] [\composedlayer{main}] + +%D These end up as paper, page and text backgrounds. We need +%D to locate the foreground, otherwise hyperlinks will not +%D work. + +\setupbackgrounds % otherwise in acrobat 5 rounding error + [paper] % and one pixel white line + [backgroundcolor=Pagecolor, + background=page] + +\setupbackgrounds + [page] + [background={page,prev,foreground,main}] + +\setupbackgrounds + [text] + [background=next, + backgroundoffset=-10pt] + +%D This means that clicking on the center brings you to the +%D next page, while clicking on teh page frame brings you one +%D page back. + +%D As usual, the graphics are handled by \METAPOST: + +\startuseMPgraphic{text} + path p ; p := unitsquare xyscaled (OverlayWidth,OverlayHeight) ; + color c ; c := (.7+uniformdeviate.3)*\MPcolor{TextColor} ; + p := p enlarged -1.25pt ; + filldraw p withcolor c ; + draw p withpen pencircle scaled 2.5pt withcolor .75c ; +\stopuseMPgraphic + +\startreusableMPgraphic{page} + path p ; p := unitsquare xyscaled (OverlayWidth,OverlayHeight) ; + color c ; c := \MPcolor{PageColor} ; + filldraw p enlarged 5pt withcolor c ; % bleeding +\stopreusableMPgraphic + +%D The text is typeset in a framed text. We cycle trough the +%D colors by means of a counter. This counter also determines +%D the positioning on the main layer. The width is slightly +%D random. + +\newcounter\KindOfTopic % and cycle through corners +\newdimen \TopicWidth % with randomized widths + +\defineframedtext + [TopicText] + [frame=off, + offset=10pt, + style=bold, + width=\TopicWidth, + background=text, + before=, + after=, + align=normal] + +\def\BeforeTopic + {\ifcase\KindOfTopic\relax + \TopicWidth=.7\textwidth + \definecolor[CharColor][black] + \else + \getrandomdimen\TopicWidth{.55\textwidth}{.7\textwidth} + \definecolor[CharColor][white] + \fi + \doifmode{reverse} + {\setupframedtexts[TopicText][foregroundcolor=CharColor]} + \definecolor[TextColor][TextColor \KindOfTopic] + \ifcase\KindOfTopic\relax + \setuplayer[main][x=.5\textwidth,y=.5\textheight,location=c] \or + \setuplayer[main][x=0pt, y=0pt, location=rb] \or + \setuplayer[main][x=\textwidth, y=0pt, location=lb] \or + \setuplayer[main][x=\textwidth, y=\textheight, location=lt] \or + \setuplayer[main][x=0pt, y=\textheight, location=rt] \fi} + +\def\AfterTopic + {\ifnum\KindOfTopic=4 + \gdef\KindOfTopic{1} + \else + \doglobal\increment\KindOfTopic + \fi} + +\def\StartTopic + {\BeforeTopic + \startstandardmakeup + \setlayer[main] \bgroup \startTopicText[none] + }%\setupwhitespace[big]} % generates an empty line + +\def\StopTopic + {\stopTopicText \egroup + \stopstandardmakeup + \AfterTopic} + +%D The title and colofon page are centered on the page. + +\def\StartNopic + {\doglobal\newcounter\KindOfTopic % centered at the page + \StartTopic + \bfd\setupinterlinespace + \setupinteraction[color=,contrastcolor=]% + \def\\{\blank\bfb\setupinterlinespace\def\\{\blank}}% + \raggedcenter\ignorespaces} + +\def\StopNopic + {\StopTopic} + +\let\StartTitlePage\StartNopic \let\StartColofonPage\StartNopic +\let\StopTitlePage \StopNopic \let\StopColofonPage \StopNopic + +\def\TitlePage #1{\StartTitlePage #1\StopTitlePage} +\def\ColofonPage#1{\StartColofonPage#1\StopColofonPage} + +%D We provide a minimum of title commands. + +\definehead + [Title] + [title] + +\definehead + [Subject] + [subject] + +\setuphead + [Title] + [style=\bfb, + page=, + before=, + after=\blank] + +\setuphead + [Subject] + [style=\bfa, + before=\blank, + after=\blank] + +\doifnotmode{demo}{\endinput} + +\def\Sample #1 {\input #1 \par \rightaligned{--- #1 ---}} + +\starttext + +\StartNopic The \ConTeXt\ Test Quotes \\ \currentdate \StopNopic + +\StartTopic \Sample tufte \StopTopic +\StartTopic \Sample knuth \StopTopic +\StartTopic \Sample zapf \StopTopic +\StartTopic \Sample douglas \StopTopic +\StartTopic \Sample stork \StopTopic +\StartTopic \Sample materie \StopTopic + +\StartNopic There Will Be Some More \StopNopic + +\stoptext diff --git a/tex/context/base/s-pre-27.tex b/tex/context/base/s-pre-27.tex new file mode 100644 index 000000000..eda75e8f4 --- /dev/null +++ b/tex/context/base/s-pre-27.tex @@ -0,0 +1,181 @@ +%D \module +%D [ file=s-pre-27, +%D version=1999.08.20, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 27, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\setuppapersize + [S6][S6] + +% \setupbodyfont[ppl] + +\definetypeface[main][rm][casual][informal][default] +\loadmapfile[original-micropress-informal.map] + +\setupbodyfont[main,10pt] + +\setuplayout + [footerdistance=20pt, + footer=40pt, + %footer=24pt, + %bottomdistance=10pt, + %bottom=12pt, + header=0pt, + backspace=20pt, + topspace=20pt, + width=middle, + height=fit] + +% \def\MainTitle#1{\setupfootertexts[\hfill#1]} +% \def\SubTitle #1{\setupbottomtexts[\hfill#1]} +% +% \MainTitle{a dull talk held at \currentdate} +% \SubTitle {welcome to whatever} +% +% \setupbottom +% [style=\ssbf, +% color=white] +% +% \setupfooter +% [style=\ssbfb, +% color=white] + +\setupfooter + [strut=no, + style=\bfb, + color=white] + +\setupinteraction + [state=start] + +\setupinteractionscreen + [option=max] + +\definecolor[white] [s=.8] +\definecolor[red] [r=.7] +\definecolor[green] [g=.7] +\definecolor[blue] [b=.7] +\definecolor[yellow][r=.7,g=.7] + +\setupcolors + [state=start] + +\defineoverlay [page] [\reuseMPgraphic{page}] +\defineoverlay [text] [\useMPgraphic {text}] +\defineoverlay [continue] [\overlaybutton {forward}] + +\setupbackgrounds + [page] + [background={page,continue}] + +\definecolor [PageColor] [red] +\definecolor [TextColor] [yellow] + +\defineframedtext + [TopicPage] + +\defineframedtext + [TopicText] + +\setupframedtexts + [TopicPage] + [width=\textwidth, + height=\textheight, + offset=overlay] + +\setupframedtexts + [TopicText] + [offset=10pt, + style=bold, % hm + width=\TopicWidth, + background=text, + align=normal] + +\setupframedtexts + [TopicPage,TopicText] + [frame=off, + depthcorrection=off, + before=, + after=] + +\newbox \TopicBox +\newcounter \KindOfTopic +\newdimen \TopicWidth + +\def\KindOfTopic{1} + +\def\StartTopic + {\getrandomdimen\TopicWidth{.5\textwidth}{.7\textwidth} + \ifcase\KindOfTopic\or + \setupframedtexts [TopicPage] [align={right,high}] \or + \setupframedtexts [TopicPage] [align={left,high}] \or + \setupframedtexts [TopicPage] [align={left,low}] \or + \setupframedtexts [TopicPage] [align={right,low}] \fi + \setbox\scratchbox=\vbox \bgroup \dontcomplain + \noindent \startTopicPage [none] + \noindent \startTopicText [none] + \setuptolerance [verytolerant,stretch]} + +\def\StopTopic% + {\stopTopicText + \stopTopicPage + \egroup + \global\setbox\TopicBox=\vbox + {\startoverlay + {\box\TopicBox} {\box\scratchbox} + \stopoverlay} + \copy\TopicBox + \ifnum\KindOfTopic=4 + \def\KindOfTopic{1} + \else + \increment\KindOfTopic + \fi + \page} + +\startuseMPgraphic{text} + path p ; p := unitsquare xyscaled (OverlayWidth,OverlayHeight) ; + color c ; c := (.7+uniformdeviate.3)*\MPcolor{TextColor} ; + p := p enlarged -1.25pt ; + fill p withcolor c ; + draw p withpen pencircle scaled 2.5pt withcolor .75c ; +\stopuseMPgraphic + +\startreusableMPgraphic{page} + path p ; p := unitsquare xyscaled (OverlayWidth,OverlayHeight) ; + color c ; c := \MPcolor{PageColor} ; + fill p withcolor c ; + draw p withpen pencircle scaled 2.5pt withcolor c ; +\stopreusableMPgraphic + +\def\StartNopic#1\StopNopic + {\setupfootertexts + [\vbox to \footerheight + {\vfill + \raggedleft + \def\\{\endgraf\tx\setstrut\strut} + \setstrut\strut\ignorespaces#1\unskip\endgraf\removedepth}] + \null \page} + +\def\TitlePage#1% + {\StartNopic#1\StopNopic} + +\setuphead[title] [style=\bfc,after=\blank] +\setuphead[subject][style=\bfa,before=\blank] + +\doifnotmode{demo}{\endinput} + +\starttext + +\TitlePage + {a dull talk held at \currentdate\\welcome to whatever} + +\dorecurse{10}{\StartTopic \input tufte \StopTopic} + +\stoptext diff --git a/tex/context/base/s-pre-30.tex b/tex/context/base/s-pre-30.tex new file mode 100644 index 000000000..2a3899c92 --- /dev/null +++ b/tex/context/base/s-pre-30.tex @@ -0,0 +1,258 @@ +%D \module +%D [ file=s-pre-30, +%D version=2006.04.25, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 30, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\usemodule[streams] + +\setuppapersize + [S6] [S6] + +\setupbodyfont + [12pt,tt] + +\definemeasure[bleed][6pt] + +\definecolor[maincolor-3][r=.5,g=.2,b=.2] +\definecolor[maincolor-1][r=.2,g=.5,b=.2] +\definecolor[maincolor-2][r=.2,g=.2,b=.5] + +\definecolor[pagecolor] [s=.5] +\definecolor[resultcolor][s=1,t=.85,a=1] +\definecolor[maincolor] [maincolor-3] + +\definecolorgroup + [maingroup] + [.5:.2:.2, + .2:.5:.2, + .2:.2:.5] + +\definecolorgroup + [resultgroup] + [1:.85:.85, + .85:1:.85, + .85:.85:1] + +\def\CurrentColor{1} + +\definecolor[maincolor] [maingroup:\CurrentColor] +\definecolor[resultcolor][resultgroup:\CurrentColor] + +\def\NextColor{\ifnum\CurrentColor=3 \def\CurrentColor{1}\else\doglobal\increment\CurrentColor\fi} + +\setuplayout + [backspace=\measure{bleed}, + topspace=30pt, + bottomdistance=\measure{bleed}, + bottom=\dimexpr30pt-\measure{bleed}\relax, + header=0pt, + footer=0pt, + topdistance=\measure{bleed}, + top=\dimexpr30pt-\measure{bleed}\relax, + width=middle, + height=middle] + +\setuptop + [before=\vfill, + after=\vfill, + strut=yes] + +\setupbackgrounds + [text] + [backgroundoffset=\measure{bleed}, + background=color, + backgroundcolor=maincolor] + +\setupbackgrounds + [page] + [background=color, + backgroundcolor=pagecolor] + +\setupcolors + [state=start, + textcolor=white] + +\setuphead + [chapter] + [style=\ttd] + +\setuphead + [section] + [style=\ttd] + +\defineproperty + [result] + [layer] + [state=stop] + +\definelayer + [result] + +\setuplayer + [result] + [width=\textwidth, + height=\textheight] + +\setupbackgrounds + [text] + [background={color,toggle,foreground,result}] + +\setupinteraction + [state=start, + click=no, + menu=on, + color=white, + contrastcolor=white, + closepageaction=HideLayer{result}, + openpageaction=HideLayer{result}] + +% We add a dummy color switch so that each page has at least one +% transparency; else acrobat will render the pages differently +% bug in 6 and 7). + +\startinteractionmenu[bottom] +% \color[resultcolor]{ }% + \hfill + \got [content] content \\ + \got [previouspage] previous \\ + \got [nextpage] next \\ + \got [ToggleLayer{result}] result \\ + \got [CloseDocument] close \\ +\stopinteractionmenu + +\setuphead + [section] + [placehead=no, + incrementnumber=list] + +\setuplist + [section] + [alternative=f] + +\defineoverlay + [toggle] + [\overlaybutton{ToggleLayer{result}}] + +\definestreamlayer + [resultstream] + +\startsetups streamlayer:resultstream:flush + \setlayer + [result] + [preset=middlebottom, + hoffset=\measure{bleed}, +% voffset=-\measure{bleed}] + voffset=\measure{bleed}] + {\startproperty[result]% +% \framed +% [offset=overlay, +% frame=off, +% background=color, +% backgroundoffset=1\dimexpr\measure{bleed}\relax, +% backgroundcolor=maincolor] + {\framed + [offset=overlay, + frame=off, + foregroundcolor=maincolor, + background=color, + backgroundoffset=1\dimexpr\measure{bleed}\relax, + backgroundcolor=resultcolor] + {\tightlayer[\currentstreamlayer]}} + \stopproperty} +\stopsetups + +\startsetups show-definition + \subject{definition} + \typebuffer + \getbuffer + \page +\stopsetups + +\startsetups show-result + \startstreamlayer[resultstream] + \subject{result} + \getbuffer + \stopstreamlayer + \placestreamlayer[resultstream] + \page +\stopsetups + +\startsetups show-usage + \subject{usage} + \typebuffer + \startstreamlayer[resultstream] + \subject{result} + \getbuffer + \stopstreamlayer + \placestreamlayer[resultstream] + \page +\stopsetups + +\startsetups show-usage-lines + \subject{usage} + \typebuffer + \startstreamlayer[resultstream] + \subject{result} + \startlines + \getbuffer + \stoplines + \stopstreamlayer + \placestreamlayer[resultstream] + \page +\stopsetups + +\startsetups show-contents + \startcolumns[n=3] + \placelist[section][criterium=text] + \stopcolumns + \pagereference[content] + \page + \NextColor +\stopsetups + +\def\TitlePage#1% + {\title{#1} + \setups{show-contents}} + +\def\StartSample#1% + {\starttext + \page + \section{#1} + \setuptoptexts[][\processedfile\enspace:\enspace\lowercase{#1}]} + +\def\StopSample + {\page + \setuptoptexts[][] + \stoptext + \NextColor} + +\endinput + +\usemodule[pre-30] + +% \TitlePage{Howling to the moon} + +\StartSample{Basics} + +\startbuffer +\lua{a = 1.5 ; b = 1.8 ; c = a*b ; tex.print(c) ;} + +\startlua + a = 1 + b = 2 + c = a*b + tex.print(c) +\stoplua +\stopbuffer + +\setups{show-usage} + +\StopSample diff --git a/tex/context/base/s-pre-50.tex b/tex/context/base/s-pre-50.tex new file mode 100644 index 000000000..782f6aea1 --- /dev/null +++ b/tex/context/base/s-pre-50.tex @@ -0,0 +1,101 @@ +%D \module +%D [ file=s-pre-50, +%D version=2003.01.26, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 50, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D When my mailbox started to overflow with messages about +%D problems with the presentation step mechanism, I looked up +%D old presentaton, hacked a bit and cooked up an alternative +%D that is less dependent on \PDF\ trickery. +%D +%D Consider it a cheap trick and prelude to a couple of new +%D presentation styles. (At the time of writing this, I +%D still have some 10 of those styles to clean up and +%D document.) You can give it a try: +%D +%D \starttyping +%D texexec --pdf --mode=demo s-pre-50 +%D \stoptyping + +% Basic definitions. + +\defineframedtext + [horizontal] + [width=\textwidth, + frame=off, + strut=no, + height=fit, + align={right,lohi}, + before=, + after=] + +\definecollector + [contribution] + [state=repeat, + corner={left,bottom}, + location={right,bottom}] + +%D An example of tuning: + +\startmode[demo] + + \setupcollector + [contribution] + [voffset=-.25\bodyfontsize] + + \setupframedtexts + [horizontal] + [background=color, + backgroundcolor=darkgray, + foregroundcolor=white] + +\stopmode + +%D Structure and trick. + +\def\StartSteps + {\checkutilities} + +\def\StopSteps + {\resetcollector[contribution]} + +\long\def\StartStep#1\StopStep + {\setcollector + [contribution] + {\starthorizontal[none]#1\stophorizontal} + \flushcollector[contribution] + \page} + +%D Trick. Nowadays we can use streams. + +\installoutput\FlushStep + {\StartStep\unvbox\normalpagebox\StopStep} + +%D Demo. + +\doifnotmode{demo}{\endinput} + +\setupcolors[state=start] \setuppapersize[S6][S6] \setuplayout[middle] + +\starttext + +\StartSteps + + \title[whow]{How Much?} \FlushStep + \item More \FlushStep + \item And More \FlushStep + \item And Even More \FlushStep + + \StartStep And So On \StopStep + +\StopSteps + +\stoptext diff --git a/tex/context/base/s-pre-60.tex b/tex/context/base/s-pre-60.tex new file mode 100644 index 000000000..f12b98b06 --- /dev/null +++ b/tex/context/base/s-pre-60.tex @@ -0,0 +1,159 @@ +%D \module +%D [ file=s-pre-60, +%D version=2004.03.15, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 60, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmode[paper,print] + \let\StartSteps\relax + \let\StopSteps \relax + \let\FlushStep \relax + \let\ResetStep \relax + \let\StartBusy\relax + \let\StopBusy \relax + \endinput +\stopmode + +\newcounter\StepCounter +\newcounter\StepMaximum + +\useJSscripts[stp] + +\startsetups[set-stepper] + + \ifnum\getvariable{stepper}{nofsteps}>\StepMaximum + + \dostepwiserecurse {\numexpr(\StepMaximum+1)} {\getvariable{stepper}{nofsteps}} {1} + {\doifnotmode{nosteps,nostep} + {\expanded{\defineproperty[step:\recurselevel][layer][state=stop,global=yes]}}} + + \xdef\StepMaximum{\getvariable{stepper}{nofsteps}} + + \fi + +\stopsetups + +\setvariables + [stepper] + [set=\setups{set-stepper}, + nofsteps=50] + +\defineproperty[step:busy][layer][state=start,global=no] + +\definereference [SetupStepper] [JS(SetupStepper{step,\StepMaximum})] +\definereference [ResetStepper] [JS(ResetStepper)] +\definereference [CheckStepper] [JS(CheckStepper{\StepCounter})] +\definereference [InvokeStepper] [JS(InvokeStepper)] + +\def\ResetStep {\doglobal\newcounter\StepCounter} +\def\NextStep {\doglobal\increment \StepCounter} +\def\PrevStep {\doglobal\decrement \StepCounter} + +% todo: roll back blank + +\def\StepLayer {step:\StepCounter} +\def\NextStepLayer {step:\the\numexpr\StepCounter+1\relax} +\def\FirstStepLayer{step:1} + +\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} +\def\FlushStep {\iftrialtypesetting\else\StopStep \NextStep\StartStep\fi} + +\appendtoks + \ResetStep +\to \everyaftershipout + +\def\StartBusy{\startproperty[step:busy]\ignorespaces} +\def\StopBusy {\removeunwantedspaces\stopproperty} + +\setupinteraction + [%openaction=SetupStepper, + closeaction=ResetStepper, + openpageaction=CheckStepper, + closepageaction=ResetStepper] + +\defineoverlay[invoke][\overlaybutton{InvokeStepper}] + +\setupbackgrounds + [text] + [background=invoke] + +% bonus + +\useMPlibrary[nav] + +\definepalet + [navplus] + [attach=interactioncolor, + comment=interactioncolor] + +\setupcomment + [symbol={comment-normal,comment-down}, + textlayer=\StepLayer, + option=buffer, + height=\textheight, + width=\textwidth, + margin=0pt] + +\setupattachments + [symbol={attach-normal,attach-down}, + textlayer=\StepLayer] + +%D Handy: + +\def\StartLocalSteps{\ResetStep} +\def\StopLocalSteps {} + +\def\StartLocalStep {\NextStep\StartStep} +\def\StopLocalStep {\StopStep} + +%D used as (given some definitions): +%D +%D \starttyping +%D \StartLocalSteps +%D \startcombination[both] +%D {\StartLocalStep\placestreamlayer[left]\StopLocalStep} {} +%D {\StartLocalStep\placestreamlayer[right]\StopLocalStep} {} +%D \stopcombination +%D \StopLocalSteps +%D \stoptyping + +\endinput diff --git a/tex/context/base/s-pre-61.tex b/tex/context/base/s-pre-61.tex new file mode 100644 index 000000000..fa52d158a --- /dev/null +++ b/tex/context/base/s-pre-61.tex @@ -0,0 +1,273 @@ +%D \module +%D [ file=s-pre-61, +%D version=2004.03.15, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 61, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Optima + +\usemodule[pre-60] + +\doifmodeelse {mkiv} { + \usetypescriptfile[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] + +\setuppapersize + [S6][S6] + +% \setuppapersize +% [SW][SW] + +\setuplayout + [topspace=10pt, + header=30pt, + headerdistance=20pt, + height=middle, + footerdistance=20pt, + footer=0pt, + bottomdistance=20pt, + bottom=20pt, + bottomspace=50pt, + backspace=30pt, + width=middle] + +\setupinteraction + [state=start, + click=off, + menu=on, + style=, + color=interactioncolor, + contrastcolor=interactioncolor] + +\setupinteractionscreen + [option=max] + +\setupinteractionmenu + [bottom] + [color=maincolor, + contrastcolor=maincolor, + style=\tfa, % acceptable + left=\hfill, + middle=, + right=, + height=\bottomheight, + width=2\bottomheight, + offset=overlay, + frame=off] + +\startinteractionmenu[bottom] + \but [firstpage] \symbol[firstpage] \\ + \but [previouspage] \symbol[previouspage] \\ + \but [InvokeStepper] \StartBusy\symbol[PauseRendering]\StopBusy \\ + \but [nextpage] \symbol[nextpage] \\ + \but [lastpage] \symbol[lastpage] \\ + \but [CloseDocument] \symbol[CloseDocument] \\ +\stopinteractionmenu + +% maybe in colo-sjk : \setupcolor[sjk] + +\definecolor [dark] [s=.4] +\definecolor [bright] [s=.9] + +\definecolor [red] [r=.4,g=.2,b=.2] +\definecolor [green] [r=.2,g=.4,b=.2] +\definecolor [blue] [r=.2,g=.2,b=.4] + +\definecolor [cyan] [r=.2,g=.4,b=.4] +\definecolor [magenta][r=.4,g=.2,b=.4] +\definecolor [yellow] [r=.4,g=.4,b=.2] + +\definecolor [pagecolor] [dark] +\definecolor [maincolor] [bright] +\definecolor [textcolor] [red] + +\definecolor [interactioncolor] [r=.8,g=.8,b=.6] + +\setupcolors + [state=start, + textcolor=maincolor] + +\setupbackgrounds + [page] + [background=page, + backgroundcolor=textcolor] + +\setupbackgrounds + [text]% [text] + [background={comments,text,invoke}] + +\definelayer + [text] + [width=\textwidth, + height=\textheight] + +\defineoverlay + [comments] + [{\setlayer[text][preset=middle]{\placecomments}}] + +\defineoverlay[page][\uniqueMPgraphic{page-\ifcase\realpageno\or one\else plus\fi}] + +\startuniqueMPgraphic{page-one} + StartPage ; + fill Page + enlarged 4pt + withcolor \MPcolor{pagecolor} ; + fill Field[Text][Text] + enlarged 10pt +% topenlarged (HeaderHeight+HeaderDistance) + leftenlarged (BackSpace+4pt) + rightenlarged (CutSpace +4pt) + withcolor OverlayColor ; + StopPage ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{page-plus} + StartPage ; + fill Page + enlarged 4pt + withcolor \MPcolor{pagecolor} ; + fill Field[Text][Text] + enlarged 10pt + leftenlarged (BackSpace+4pt) + rightenlarged (CutSpace+4pt) + withcolor OverlayColor ; + StopPage ; +\stopuniqueMPgraphic + +% this needs to be sorted out ! + +\appendtoks + \NormalizeFontHeight \HeadFont {\setstrut\strut\quad} {1.0\headerheight} {SansBold} + \NormalizeFontHeight \TitleFont {\setstrut\strut\quad} {2.0\headerheight} {SansBold} + \NormalizeFontHeight \SubTitleFont {\setstrut\strut\quad} {1.5\headerheight} {SansBold} + \NormalizeFontHeight \SubSubTitleFont {\setstrut\strut\quad} {1.0\headerheight} {SansBold} +\to \everystarttext +\appendtoks + \NormalizeFontHeight \HeadFont {\setstrut\strut\quad} {1.0\headerheight} {SansBold} + \NormalizeFontHeight \TitleFont {\setstrut\strut\quad} {2.0\headerheight} {SansBold} + \NormalizeFontHeight \SubTitleFont {\setstrut\strut\quad} {1.5\headerheight} {SansBold} + \NormalizeFontHeight \SubSubTitleFont {\setstrut\strut\quad} {1.0\headerheight} {SansBold} +\to \everystoptext + +\setuphead + [chapter] + [placehead=empty, + after={\blank[medium]}, + color=maincolor, + placenumber=no, + style=\HeadFont] + +\setupheadertexts + [\doiftextelse{\currentheadnumber}{\placeheadtext[Topic]}{\placeheadtext[Nopic]}] + [] + +\setuppagenumbering + [location=] + +\definesymbol + [emdash] + [\emdash] + +\setupitemize + [each] + [loose,serried,joinedup,broad] + [symbol=emdash] + +\setupalign + [broad,right] + +\def\doTitlePage#1#2#3% + {\startstandardmakeup[headerstate=high] + \def\\{\def\\{\endgraf\quad\quad}\endgraf\quad\ignorespaces#2}% + #1\setstrut\setupinterlinespace\vfil#3\vfil\vfil + \stopstandardmakeup} + +\def\TitlePage {\doTitlePage\TitleFont\relax} +\def\SubTitlePage{\doTitlePage\TitleFont\SubTitleFont} + +\definehead[Topic][chapter] +\definehead[Nopic][title] + +\def\Topics#1% + {\Nopic[topics]{#1} + \startcolumns + \placelist[Topic] + \stopcolumns} + +\setuplist + [Topic] + [alternative=f, + color=maincolor, + contrastcolor=maincolor, + criterium=all] + +\defineoverlay[topics][\overlaybutton{topics}] + +\setupbackgrounds + [bottom] [text] + [background=topics] + +% \doifnotmode{demo}{\endinput} + +\starttext + +\TitlePage{Stepwise\\Refinement} + +\Topics{Topics} + +\Topic{Female Artists} + +\StartSteps + +\startitemize +\item Tori Amos \FlushStep +\item Kate Bush \FlushStep +\item Heather Nova \FlushStep +\item Alanis Morissette \FlushStep +\item Suzanne Vega \FlushStep +\stopitemize + +\StopSteps + +\Topic{Male Composers} + +\StartSteps + +\startitemize +\item John Adams \FlushStep +\item Steve Reich \FlushStep +\item Louis Andriessen \FlushStep +\item Olivier Messiaen \FlushStep +\stopitemize + +\StopSteps + +\Topic{And Some More} + +\StartSteps + +\startitemize +\item Mark Hollis \FlushStep +\item Roger Waters \FlushStep +\item David Gilmore \FlushStep +\item Peter Gabriel \FlushStep +\item Randy Newman \FlushStep +\stopitemize + +\StopSteps + +\stoptext diff --git a/tex/context/base/s-pre-62.tex b/tex/context/base/s-pre-62.tex new file mode 100644 index 000000000..64bb3495b --- /dev/null +++ b/tex/context/base/s-pre-62.tex @@ -0,0 +1,228 @@ +%D \module +%D [ file=s-pre-62, +%D version=2005.03.04, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 62, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Melior + +\usemodule[pre-60] + +\usetypescriptfile + [type-ghz] + +\definetypeface[mainface][rm][serif][melior] [default][encoding=texnansi] +\definetypeface[mainface][tt][mono] [modern] [default][encoding=texnansi,rscale=1.05] +\definetypeface[mainface][ss][serif][melior] [default][encoding=texnansi] +\definetypeface[mainface][mm][math] [palatino][default][encoding=texnansi,rscale=0.95] + +\setupbodyfont + [mainface,14.4pt] + +\setuppapersize + [S6][S6] + +\setvariables[layout][dx=0,dy=1,nx=2,ny=2,step=64] + +\definemeasure[layoutwd][\dimexpr\paperwidth /\getvariable{layout}{step}\relax] +\definemeasure[layoutht][\dimexpr\paperheight/\getvariable{layout}{step}\relax] + +\setuplayout + [ width=middle, + height=middle, + header=0pt, + footer=0pt, + margin=0pt, + backspace=5\measure{layoutwd}, + topspace=5\measure{layoutht}] + +\setuplayout + [step] + [ backspace=\numexpr2+ \getvariable{layout}{dx}\relax\measure{layoutwd}, + cutspace=\numexpr3+\getvariable{layout}{nx}-\getvariable{layout}{dx}\relax\measure{layoutwd}, + topspace=\numexpr2+ \getvariable{layout}{dy}\relax\measure{layoutht}, + bottomspace=\numexpr3+\getvariable{layout}{ny}-\getvariable{layout}{dy}\relax\measure{layoutht}] + + +\definecolor[layout:left] [t=.5,a=1,b=1] +\definecolor[layout:right] [t=.5,a=1,r=1] +\definecolor[layout:top] [t=.5,a=1,g=1] +\definecolor[layout:bottom][t=.5,a=1,y=1] +\definecolor[layout:page] [s=.75] + +\definehspace[menu][\measure{layoutwd}] + +\setupinteraction + [state=start, + click=off, + style=, + color=interactioncolor, + contrastcolor=interactioncolor] + +\setupinteractionscreen + [option=max] + +\setupbuttons + [color=maincolor, + contrastcolor=maincolor, + style=\tf, % acceptable + height=2\measure{layoutht}, + width=2\measure{layoutwd}, + offset=overlay, + frame=off] + +\definecolor[interactioncolor][darkgray] +\definecolor[maincolor] [lightgray] + +\setuptexttexts + [] + [\vbox to \textheight{\vfill\hfill\setups{menu:content}}] + +\startsetups menu:content + + \button{\symbol[firstpage]}[firstpage] + \hspace[menu] + \button{\symbol[previouspage]}[previouspage] + \hspace[menu] + \button{\StartBusy\symbol[PauseRendering]\StopBusy}[InvokeStepper] + \hspace[menu] + \button{\symbol[nextpage]}[nextpage] + \hspace[menu] + \button{\symbol[lastpage]}[lastpage] + \hspace[menu] + \button{\symbol[CloseDocument]}[CloseDocument] + +\stopsetups + +\startuseMPgraphic{page}{step} + StartPage ; + numeric dx, dy ; dx := PaperWidth/\MPvar{step} ; dy := PaperHeight/\MPvar{step} ; + fill Page withcolor .5white ; + fill + ulcorner Page -- urcorner Page -- + urcorner Page shifted (0,-TopSpace+dy) -- ulcorner Page shifted (0,-TopSpace+dy) -- cycle + withcolor \MPcolor{layout:top} ; + fill + llcorner Page -- lrcorner Page -- + lrcorner Page shifted (0,BottomSpace-dy) -- llcorner Page shifted (0,BottomSpace-dy) -- cycle + withcolor \MPcolor{layout:bottom} ; + fill + ulcorner Page -- llcorner Page -- + llcorner Page shifted (BackSpace-dx,0) -- ulcorner Page shifted (BackSpace-dx,0) -- cycle + withcolor \MPcolor{layout:left} ; + fill + urcorner Page -- lrcorner Page -- + lrcorner Page shifted (-CutSpace+dx,0) -- urcorner Page shifted (-CutSpace+dx,0) -- cycle + withcolor \MPcolor{layout:right} ; + fill Field[Text][Text] enlarged (dx,dy) withcolor white ; + fill Field[Text][Text] enlarged (dx,dy) withcolor \MPcolor{layout:page} ; + StopPage ; +\stopuseMPgraphic + +\defineoverlay[page][\useMPgraphic{page}{step=\getvariable{layout}{step}}] + +\setupbackgrounds + [page] + [background=page] + +\setupcolors + [state=start] + +\startsetups nextstep + % pagebreak handlers are grouped, so we need to set global + \ifnum\getvariable{layout}{dx}=\getvariable{layout}{nx}\relax + \ifnum\getvariable{layout}{dy}=\getvariable{layout}{ny}\relax + \setxvariables[layout][dy=1] + \else + \setxvariables[layout][dy=\the\numexpr\getvariable{layout}{dy}+1\relax] + \fi + \setxvariables[layout][dx=1] + \else + \setxvariables[layout][dx=\the\numexpr\getvariable{layout}{dx}+1\relax] + \fi + % global anyway + \setuplayout[step] +\stopsetups + +\definefontsynonym[MainTitleFont][SerifBold] + +\definefont[ChapterTitleFont][MainTitleFont sa 2] + +\appendtoks + \NormalizeFontHeight \TitleFont {\setstrut\strut\quad} {4\lineheight} {MainTitleFont} + \NormalizeFontHeight \SubTitleFont {\setstrut\strut\quad} {3\lineheight} {MainTitleFont} + \NormalizeFontHeight \ChapterNumberFont {XVI} {4\lineheight} {MainTitleFont} +\to \everystarttext + +\setupsection + [section-2] + [bodypartconversion=Romannumerals] + +\installpagebreakhandler {step} {\setups{nextstep}} + +\definepagebreak[chapter][yes,step] + +\setuphead + [chapter] + [page=chapter, + command=\MyChapterCommand] + +\definehead[Topic][chapter] +\definehead[Nopic][title] + +\setuphead[chapter,Topic,Nopic] + [numberstyle=\ChapterNumberFont, + textstyle=\ChapterTitleFont, + numbercolor=lightgray, + textcolor=darkgray] + +\def\MyChapterCommand#1#2% + {\hbox \bgroup % we need to nil the strut added by the headplacement + \setupframed[frame=off,lines=4,offset=overlay]% + \rlap{\hskip2\lineheight\framed{\setnostrut#1}}\framed{#2}% + \egroup} + +\setupitemize + [each] + [R,broad] + [stopper=, + color=lightgray] + +\def\doTitlePage#1#2#3% + {\startstandardmakeup[headerstate=high,textstate=stop] + \setupalign[middle] + \def\\{\def\\{\endgraf}\endgraf\vfil\ignorespaces#2}% + \startcolor[darkgray] + #1\setstrut\setupinterlinespace\vfil#3\vfil + \stopcolor + \stopstandardmakeup} + +\def\TitlePage {\doTitlePage\TitleFont\relax} +\def\SubTitlePage{\doTitlePage\TitleFont\SubTitleFont} + +\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-63.tex b/tex/context/base/s-pre-63.tex new file mode 100644 index 000000000..76de8b991 --- /dev/null +++ b/tex/context/base/s-pre-63.tex @@ -0,0 +1,73 @@ +%D \module +%D [ file=s-pre-63, +%D version=2006.05.11, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 63, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\usemodule[pre-61,streams] + +\definemeasure[textgap] [\dimexpr24pt\relax] + +\definemeasure[leftwidth] [\dimexpr.25\textwidth-.5\measure{textgap}\relax] +\definemeasure[rightwidth][\dimexpr.75\textwidth-.5\measure{textgap}\relax] + +\definestreamlayer[left] [width=\measure{leftwidth}] +\definestreamlayer[right][width=\measure{rightwidth}] + +\setupbodyfont[12pt] + +\definefont[LeftFont][Normal sa 3] + +\setupheader[style=\tfc,before=\vss,after=\vss] + +\startsetups streamlayer:left:settings + \hsize\measure{leftwidth} + \LeftFont + \setupinterlinespace +\stopsetups + +\startsetups streamlayer:right:settings + \hsize\measure{rightwidth} +\stopsetups + +\definecombination[both][distance=\measure{textgap},location=top] + +\startsetups place:both + \startcombination[both] + {\StartLocalStep\placestreamlayer[left]\StopLocalStep} {} + {\StartLocalStep\placestreamlayer[right]\StopLocalStep} {} + \stopcombination +\stopsetups + +\def\StartPage {\page \StartLocalSteps} +\def\StopPage {\StopLocalSteps \page} + +\def\StartLeft {\startstreamlayer[left]} +\def\StartRight{\startstreamlayer[right]} + +\def\StopLeft {\stopstreamlayer} +\def\StopRight {\stopstreamlayer} + +\def\StartPair {} +\def\StopPair {\setups[place:both]} + +\doifnotmode {demo} {\endinput} + +\setupbodyfont[8pt] \definefont[BigFont][Normal sa 4] + +\starttext + +\StartPage + \StartPair \StartLeft ZAPF \StopLeft \StartRight \input zapf \StopRight \StopPair + \StartPair \StartLeft DAVIS \StopLeft \StartRight \input davis \StopRight \StopPair + \StartPair \StartLeft WARD \StopLeft \StartRight \input ward \StopRight \StopPair +\StopPage + +\stoptext diff --git a/tex/context/base/s-pre-64.tex b/tex/context/base/s-pre-64.tex new file mode 100644 index 000000000..b9dc10002 --- /dev/null +++ b/tex/context/base/s-pre-64.tex @@ -0,0 +1,203 @@ +%D \module +%D [ file=s-pre-64, +%D version=2006.05.11, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 64, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% To be documented, used in 2007 + +\usemodule[s][pre-60] + +\newcounter\shapesynctag +\newdimen\slantedshapedimen +\newdimen\slantedshapestep +\newdimen\slantedshapeleftskip +\newdimen\slantedshapeoffset +\newdimen\slantedshapeextra + +\positioningtrue + +\def\AdaptShape + {\doglobal\increment\shapesynctag + \getnoflines\textheight + \slantedshapestep\dimexpr\slantedshapeleftskip/\noflines\relax + \leftskip\slantedshapeleftskip + \scratchdimen\dimexpr\MPy{text:\MPp\shapesynctag}+\MPh{text:\MPp\shapesynctag}-\topskip-\MPy\shapesynctag\relax + \advance\scratchdimen\slantedshapeextra + \getnoflines\scratchdimen + \slantedshapedimen \noflines \slantedshapestep + \scratchtoks\emptytoks + \dorecurse{30} + {\appendetoks + \the\dimexpr-\slantedshapedimen+\slantedshapeoffset \relax\space + \the\dimexpr \hsize-2\slantedshapeoffset\relax\space + \to\scratchtoks + \advance\slantedshapedimen \slantedshapestep}% + \parshape 30 \the\scratchtoks + \strut\xypos\shapesynctag} + +\def\AdaptShapeX + {\doglobal\increment\shapesynctag + \getnoflines\textheight + \slantedshapestep\dimexpr\slantedshapeleftskip/\noflines\relax + \leftskip\slantedshapeleftskip + \scratchdimen\dimexpr\MPy{text:\MPp\shapesynctag}+\MPh{text:\MPp\shapesynctag}-\topskip-\MPy\shapesynctag\relax + \advance\scratchdimen\slantedshapeextra + \getnoflines\scratchdimen + \slantedshapedimen \noflines \slantedshapestep + \scratchtoks\emptytoks + \dorecurse{30} + {\appendetoks + \the\dimexpr-\slantedshapedimen+\slantedshapeoffset +5cm \relax\space + \the\dimexpr \hsize-2\slantedshapeoffset\relax\space + \to\scratchtoks + \advance\slantedshapedimen \slantedshapestep}% + \parshape 30 \the\scratchtoks + \strut\xypos\shapesynctag} + +\setuppapersize[S6][S6] + +\setupinteraction + [state=start, + click=no] + +\setupinteractionscreen + [option=max] + +\setuplayout + [backspace=12pt, + topspace=24pt, + height=middle, + width=middle, + header=0pt, + footer=0pt] + +\definecolor[maincolor][b=.5] +\definecolor[somecolor][g=.5] +\definecolor[morecolor][r=.5] + +\setupcolors + [textcolor=maincolor, + state=start] + +\setupbackgrounds + [text]% [text] + [background={base,text,invoke}] + +\definelayer + [text] + [width=\textwidth, + height=\textheight] + +\definelayer + [base] + [width=\textwidth, + height=\textheight] + +\definetype [epet] [style=,color=morecolor] +\setuptype [style=,color=somecolor] + +\slantedshapeleftskip150pt +\slantedshapeoffset12pt +\slantedshapeextra10pt + +\startreusableMPgraphic{page} + StartPage ; + fill Page withcolor \MPcolor{maincolor} ; + path p ; p := Field[Text][Text] enlarged 6pt ; + p := + llcorner p shifted (0,-12pt) -- + lrcorner p shifted (-150pt,0) -- + urcorner p shifted (0,12pt) -- + ulcorner p shifted (150pt,0) -- + cycle ; + fill p + withcolor .9white ; + StopPage ; +\stopreusableMPgraphic + +\defineoverlay[page][\reuseMPgraphic{page}] +\setupbackgrounds[page][background=page] + +\setupalign[flushleft] + +\def\StartItem + {\blank[line] + \begingroup + \EveryPar {\AdaptShape}} % beware: \ABBREV aan begin gaat fout + +\def\StopItem + {\endgraf + \endgroup + \blank[line]} + +\def\StartType + {\blank[halfline] + \begingroup + \EveryPar {\AdaptShape} + \dontleavehmode \quad} + +\def\StopType + {\endgraf + \endgroup + \blank[halfline]} + +\def\Title#1% + {\page + \setlayer + [text] + [preset=lefttop, + rotation=90] + {\color[white]{\scale[height=24pt]{\strut#1}}}} + +\def\SetBanner#1% + {\setuplayer[base][state=repeat] + \setlayer[base][preset=rightbottom]{\color[white]{\scale[height=9pt]{\strut#1}}}} + +\let\titlefont\relax + +\startmode[atpragma] + \definefontfeature[default][method=node,script=latn,language=dflt,liga=yes,onum=yes,kern=yes] + \definedfont[palatinosanscom-regular*default at 12pt] \setupinterlinespace[line=15pt] + \definefont[titlefont][palatinosanscom-bold*default at 48pt] +\stopmode + +\endinput + +% \starttext + +% \SetBanner{tug 2007 san diego} + +% \Title {hans hagen} + +% \startstandardmakeup \titlefont \setupinterlinespace[line=3ex] \vfill + +% \StartItem \dontleavehmode \quad {\morecolor zapfino, a} \StopItem +% \StartItem \dontleavehmode \quad {\morecolor torture test} \StopItem +% \StartItem \dontleavehmode \quad {\morecolor for luatex} \StopItem + +% \vfill \stopstandardmakeup + +% \Title{loading fonts} + +% \StartSteps + +% \StartItem the \OPENTYPE\ font reader is borrowed from \FONTFORGE\ \FlushStep \StopItem +% \StartItem once it was ready, we could look into such a font \FlushStep \StopItem +% \StartItem it tooks while to figure out the format due to rather fuzzy specs \FlushStep \StopItem +% \StartItem it took us even more time to find out that the loader was flawed \FlushStep \StopItem +% \StartItem one reason was that fonts themselves may have bugs or be incomplete \FlushStep \StopItem +% \StartItem then we changed to \FONTFORGE\ version 2 \FlushStep \StopItem +% \StartItem this made the missing pieces surface in more complex feature handling \FlushStep \StopItem +% \StartItem while implementing features the new table format was cleaned up \FlushStep \StopItem + +% \StopSteps + +% \stoptext diff --git a/tex/context/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-67.tex b/tex/context/base/s-pre-67.tex new file mode 100644 index 000000000..53c3260f5 --- /dev/null +++ b/tex/context/base/s-pre-67.tex @@ -0,0 +1,144 @@ +% todo: version of placement that also takes the sync node + +\usemodule[s][abr-02] +\usemodule[s][pre-60] + +\definecolor[red:fullcolor] [r=1] +\definecolor[red:lightcolor] [r=.5] +\definecolor[red:darkcolor] [r=.375] + +\definecolor[green:fullcolor] [g=1] +\definecolor[green:lightcolor] [g=.5] +\definecolor[green:darkcolor] [g=.375] + +\definecolor[blue:fullcolor] [b=1] +\definecolor[blue:lightcolor] [b=.5] +\definecolor[blue:darkcolor] [b=.375] + +\definepalet[red-scheme] [fullcolor=red:fullcolor, lightcolor=red:lightcolor, darkcolor=red:darkcolor] +\definepalet[green-scheme][fullcolor=green:fullcolor,lightcolor=green:lightcolor,darkcolor=green:darkcolor] +\definepalet[blue-scheme] [fullcolor=blue:fullcolor, lightcolor=blue:lightcolor, darkcolor=blue:darkcolor] + +\setuppalet[red-scheme] + +\setupcolors + [textcolor=darkcolor] + +\setupinteraction + [color=darkcolor, + contrastcolor=darkcolor] + +\startuseMPgraphic{bullet} + path b, p ; + p := fullsquare scaled .5LineHeight ; + b := boundingbox p ; + p := p rotatedaround(center p, 45) ; + p := p shifted (0,-.125StrutDepth) ; + fill p withcolor \MPcolor{lightcolor} ; + setbounds currentpicture to b ; +\stopuseMPgraphic + +\startuseMPgraphic{bar} + path b, p ; + p := fullsquare scaled .25LineHeight ; + b := boundingbox p ; + p := p rotatedaround(center p, 45) ; + p := p shifted (0,+.25StrutDepth) ; + fill p withcolor \MPcolor{lightcolor} ; + setbounds currentpicture to b ; +\stopuseMPgraphic + +\startuseMPgraphic{page} + StartPage ; + fill Page enlarged 5mm withcolor .1[white,\MPcolor{fullcolor}] ; + interim linecap := butt ; + numeric h ; h := bbheight(Page)/4 ; + numeric w ; w := bbwidth(Page)/4 ; + h := h randomized(h) ; + w := w randomized(w) ; + draw + ulcorner Page shifted (0,-h) -- ulcorner Page -- ulcorner Page shifted (w,0) + withpen pensquare scaled .5cm + withcolor \MPcolor{lightcolor} ; + numeric h ; h := bbheight(Page)/4 ; + numeric w ; w := bbwidth(Page)/4 ; + h := h randomized(h) ; + w := w randomized(w) ; + draw + lrcorner Page shifted (0,h) -- lrcorner Page -- lrcorner Page shifted (-w,0) + withpen pensquare scaled .5cm + withcolor \MPcolor{lightcolor} ; + setbounds currentpicture to Page ; + StopPage ; +\stopuseMPgraphic + +\defineoverlay[page][\useMPgraphic{page}] + +\definesymbol[1][\reuseMPgraphic{bullet}] +\definesymbol[2][\reuseMPgraphic{bar}] + +\setupitemgroup[itemize][2][width=1em] + +\setupinteraction + [state=start, + click=no] + +\setuppapersize + [S6][S6] + +\setuplayout + [width=middle, + height=middle, + header=0pt, + footer=0pt, + backspace=1cm, +% topspace=1cm] + topspace=.5cm] + +\setupbackgrounds + [page] + [background=page] + +\setuphead + [chapter] + [command=\MyCommand, + before=, + after={\blank[disable]}, + color=lightcolor, + style=\bfc] + +\definelayer + [title] + [width=\paperwidth, + height=\paperheight] + +\setupbackgrounds + [page] + [background={page,title}] + +\setupwhitespace + [big] + +\def\MyCommand#1#2% + {\setlayer[title][preset=rightbottom,x=.75cm,y=.5cm]{#2}} + +\def\titlepage#1#2% + {\startstandardmakeup + \definefont[LargeFont][Normal at 120pt] + \setlayerframed + [title] + [preset=lefttop,x=1cm,y=.25cm] + [align=flushleft,foregroundstyle=\LargeFont,offset=0pt,foregroundcolor=lightcolor,frame=off] + {#1} + \definefont[SmallFont][Normal at 60pt] + \setlayerframed + [title] + [preset=rightbottom,x=1cm,y=.5cm] + [align=flushright,foregroundstyle=\SmallFont,offset=0pt,foregroundcolor=lightcolor,frame=off] + {#2} + \stopstandardmakeup} + +\let\Title\title +\let\TitlePage\titlepage + +\endinput diff --git a/tex/context/base/s-pre-70.tex b/tex/context/base/s-pre-70.tex new file mode 100644 index 000000000..1a842388b --- /dev/null +++ b/tex/context/base/s-pre-70.tex @@ -0,0 +1,170 @@ +% engine=luatex + +%D \module +%D [ file=s-pre-70, +%D version=2008.04.15, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 70, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA / 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. + +\usemodule[punk] \usetypescript[punk] \setupbodyfont[punk,20pt] + +%D At the cost of more runtime and a larger output file, we +%D turn on randomization. The instances are cached in the +%D MkIV cache, so successive runs use the same shapes. + +\EnableRandomPunk + +%D We use the regular screen size paper and layout setup. + +\setuppapersize + [S6][S6] + +\setuplayout + [topspace=30pt, + backspace=30pt, + width=middle, + height=fit, + header=0pt, + footer=0pt, + bottomdistance=24pt, + bottom=30pt, + bottom=18pt, + top=0pt] + +\setupinterlinespace + [top=height, + line=1.25\bodyfontsize] + +\setupcolors + [state=start, + textcolor=white] + +\setupinteraction + [state=start, + %click=off, + menu=on] + +%D We predefine a few palets. Of course you can define more. + +\definecolor[punkblue] [r=.4,b=.8,g=.4] +\definecolor[punkgreen] [r=.4,b=.4,g=.8] +\definecolor[punkred] [r=.8,b=.4,g=.4] +\definecolor[punkyellow][r=.6,g=.6,b=.2] + +\definepalet [punk-one] [textcolor=punkblue,pagecolor=punkgreen] +\definepalet [punk-two] [textcolor=punkred,pagecolor=punkyellow] +\definepalet [punk-three] [textcolor=punkblue,pagecolor=punkyellow] +\definepalet [punk-one-reverse] [textcolor=punkgreen,pagecolor=punkblue] +\definepalet [punk-two-reverse] [textcolor=punkyellow,pagecolor=punkred] +\definepalet [punk-three-reverse] [textcolor=punkyellow,pagecolor=punkblue] + +\setuppalet[punk-one] + +%D We use a few backgrounds. The hyperlink that invokes the +%D stepper is hooked into the text background. + +\definelayer + [page] + [width=\paperwidth, + height=\paperheight] + +\setupbackgrounds + [page] + [background={color,page}, + backgroundcolor=pagecolor, + setups=pagestuff] + +\setupbackgrounds + [text] + [background={color,invoke}, + backgroundoffset=12pt, + backgroundcolor=textcolor] + +%D We need different symbols for itemized lists. + +\definesymbol[1][\hbox{\lower1ex\hbox{*}}] +\definesymbol[2][\endash] +\definesymbol[3][\letterhash] +\definesymbol[3][>] + +%D We don't want these reversed clicked areas in Acrobat. + +\setupinteraction + [click=no] + +%D We define a rather simple navigational panel at the +%D bottom + +\setupinteractionmenu + [bottom] + [color=white, % pagecolor, + contrastcolor=white, % pagecolor, + background=color, + backgroundcolor=textcolor, + frame=off, + height=24pt, + left=\hfill, + middle=\hskip12pt] + +\setupsubpagenumber + [state=start] + +\startinteractionmenu[bottom] + \txt + \interactionbar + [alternative=d, + symbol=yes, + color=white, + contrastcolor=textcolor] + \\ + \hfilll + \but [previouspage] < < < \\ + \but [nextpage] > > > \\ +\stopinteractionmenu + +%D Instead of the normal symbols we use more punky ones. + +\startsymbolset [punk] + \definesymbol[previous] [\string<\string<] + \definesymbol[somewhere] [\string^\string^] + \definesymbol[next] [\string>\string>] +\stopsymbolset + +\setupinteraction[symbolset=punk] + +%D Because the font is rather large, we use less whitespace. + +\setuphead + [chapter] + [after={\blank[big]}] + +%D Run this file with the command: \type {context --mode=demo s-pre-70} +%D in order to get an example. + +\doifnotmode{demo} {\endinput} + +\usemodule[pre-60] % use the stepper + +\starttext + +\title {Punk for dummies} + +\dorecurse{10} { + \title{Just a few dummy pages} + \StartSteps \startitemize[packed] + \startitemize + \startitem bla \FlushStep \stopitem + \startitem bla bla \FlushStep \stopitem + \startitem bla bla bla \FlushStep \stopitem + \startitem bla bla bla bla \FlushStep \stopitem + \stopitemize \StopSteps +} + +\stoptext diff --git a/tex/context/base/s-pre-71.tex b/tex/context/base/s-pre-71.tex new file mode 100644 index 000000000..91075d54d --- /dev/null +++ b/tex/context/base/s-pre-71.tex @@ -0,0 +1,210 @@ +% engine=luatex + +%D \module +%D [ file=s-pre-71, +%D version=2008.08.05, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 71, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D I might improve this module so consider it experimental. + +% \enablemode[numbers] +% \enablemode[paper] + +\usemodule[pre-60,abr-02] + +\setupinteraction[state=start,click=off] + +\definepapersize[wide][width=900pt,height=600pt] + +\setuppapersize[wide][wide] + +\setuplayout[page] + +% \setupbodyfont[15pt] + +\usetypescriptfile[type-hgz] +\usetypescript[palatino-informal] +\setupbodyfont[palatino-informal,15pt] + +\setupsorting[logo][style=] + +\startnotmode[paper] + \setupbackgrounds[page][background=color,backgroundcolor=black] +\stopnotmode + +\TransparencyHack + +\definelayer[page][width=\paperwidth,height=\paperheight] + +\definecolor[TopicColor-1][r=.3,g=.4,b=.5] +\definecolor[TopicColor-2][r=.3,g=.5,b=.4] +\definecolor[TopicColor-3][r=.4,g=.3,b=.5] +\definecolor[TopicColor-4][r=.4,g=.5,b=.3] +\definecolor[TopicColor-5][r=.5,g=.3,b=.4] +\definecolor[TopicColor-6][r=.5,g=.4,b=.3] +\definecolor[TopicColor-7][r=.35,g=.35,b=.6] +\definecolor[TopicColor-8][r=.6,g=.35,b=.35] +\definecolor[TopicColor-9][r=.35,g=.6,b=.35] + +\definecolor[TopicColor-0][t=.5,a=1,s=.5] +\definecolor[TopicColor] [s=1] + +\setupcolors[state=start] +\setupcolors[textcolor=TopicColor] + +\startluacode + local locations = { + 'lefttop', + 'middletop', + 'righttop', + 'middleleft', + 'middle', + 'middleright', + 'leftbottom', + 'middlebottom', + 'rightbottom', + } + local done, current, previous, n = table.tohash(locations,false), 0, 0, 0 + function document.reset_locations() + done, current, previous, n = table.tohash(locations,false), 0, 0, 0 + end + function document.next_location(loc) + previous = current + n = n + 1 + loc = loc and loc ~= "" and tonumber(loc) + while true do + current = loc or math.random(1,#locations) + if not done[current] then + done[current] = true + break + end + end + end + function document.current_location() + tex.print(locations[current] or "") + end + function document.previous_location() + tex.print(locations[previous] or "") + end + function document.current_n() + tex.print(tostring(current)) + end + function document.previous_n() + tex.print(tostring(previous)) + end + function document.step() + tex.print(tostring(n)) + end +\stopluacode + +\def\StartTopics + {\startstandardmakeup + \ctxlua{document.reset_locations()} + \doifnotmode{paper}{\StartLocalSteps}} + +\def\StopTopics + {\doifnotmode{paper}{\StopLocalSteps} + \flushlayer[page] + \stopstandardmakeup} + +\def\StartTopic + {\dosingleempty\doStartTopic} + +\def\doStartTopic[#1]% + {\doifnotmode{paper}{\NextStep} + \ctxlua{document.next_location("#1")} + \startnotmode[paper] + \doifnothing{#1} + {\ifcase\ctxlua{document.previous_n()}\else + \setlayer + [page] + [preset=\ctxlua{document.previous_location()}] + \bgroup + \doifnotmode{paper}{\startproperty[\StepLayer]}% + \framed + [offset=20pt, + strut=no, + align=normal, + frame=off, + height=\dimexpr\paperheight/3\relax, + width=\dimexpr\paperwidth/3\relax, + background=color, + backgroundcolor=TopicColor-0] + {}% + \doifnotmode{paper}{\stopproperty}% + \egroup + \fi} + \stopnotmode + \setlayer + [page] + [preset=\ctxlua{document.current_location()}] + \bgroup + \doifnotmode{paper}{\startproperty[\StepLayer]}% + \framed + [offset=20pt, + strut=no, + align=\expdoifelse{#1}{}{normal}{middle,lohi}, + align=\expdoifelse{#1}{}{flushleft,verytolerant}{middle,lohi}, + frame=off, + height=\dimexpr\paperheight/3\relax, + width=\dimexpr\paperwidth/3\relax, + background=color, + backgroundcolor=TopicColor-\ctxlua{document.current_n()}] + \bgroup + \ignorespaces} + +\def\StopTopic + {\removeunwantedspaces + \egroup + \doifnotmode{paper}{\stopproperty}% + \egroup + \startmode[numbers] + \setlayerframed + [page] + [preset=\ctxlua{document.current_location()}] + [height=\dimexpr\paperheight/3\relax, + width=\dimexpr\paperwidth/3\relax, + frame=off, + foregroundstyle=\bfa, + align={flushright,low}] + {\doifnotmode{paper}{\startproperty[\StepLayer]}% + \ctxlua{document.step()}\kern\strutdepth + \doifnotmode{paper}{\stopproperty}} + \stopmode} + +\logo [METAPOST] {MetaPost} + +\definefont[TitleFont][SansBold at 60pt] +\definefont[TempFont] [SansBold at 12pt] + +\doifnotmode{demo}{\endinput} + +\starttext + +\StartTopics + \StartTopic[1] A \StopTopic + \StartTopic[5] B \StopTopic + \StartTopic[9] C \StopTopic +\StopTopics + +\StartTopics + \StartTopic A \StopTopic + \StartTopic B \StopTopic + \StartTopic C \StopTopic + \StartTopic D \StopTopic + \StartTopic E \StopTopic + \StartTopic F \StopTopic + \StartTopic G \StopTopic + \StartTopic H \StopTopic + \StartTopic I \StopTopic +\StopTopics + +\stoptext diff --git a/tex/context/base/s-pre-93.tex b/tex/context/base/s-pre-93.tex new file mode 100644 index 000000000..b67645806 --- /dev/null +++ b/tex/context/base/s-pre-93.tex @@ -0,0 +1,210 @@ +%D \module +%D [ file=s-pre-20, +%D version=2000.08.07, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 20, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\setupbodyfont + [lbr,14.4pt] + +\setuppapersize + [S6][S6] + +\setuplayout + [topspace=0cm, + backspace=0cm, + header=0pt, + footer=0pt, + width=middle, + height=middle] + +\setupcolors + [state=start] + +\setupinteraction + [state=start, + click=no, + display=new, + color=LineColor, + contrastcolor=LineColor] + +\setupinteractionscreen + [option=max] + +\setupsystem + [random=big] % once per hour + +\startreusableMPgraphic{page} + StartPage ; + filldraw Page withcolor \MPcolor{PageColor} ; + pickup pencircle scaled (.25cm+uniformdeviate.25cm) ; + for i=1 upto 200 : + drawdot + (uniformdeviate PaperWidth,uniformdeviate PaperHeight) + withcolor \MPcolor {LineColor} ; + endfor ; + StopPage ; +\stopreusableMPgraphic + +\startuseMPgraphic{idea} + StartPage ; + path p ; + p := unitsquare xyscaled(\MPw{idea:\realfolio},\MPh{idea:\realfolio}) superellipsed .90 ; + p := p shifted \MPxy{idea:\realfolio} ; + draw p withpen pencircle scaled .500cm withcolor \MPcolor{PageColor} ; + fill p withcolor \MPcolor{\overlaycolor} ; + draw p withpen pencircle scaled .250cm withcolor \MPcolor{LineColor} ; + p := unitsquare xyscaled(\MPw{title:\realfolio},\MPh{title:\realfolio}) superellipsed .90 ; + p := p shifted \MPxy{title:\realfolio} ; + draw p withpen pencircle scaled .250cm withcolor \MPcolor{PageColor} ; + fill p withcolor \MPcolor{\overlaycolor} ; + draw p withpen pencircle scaled .125cm withcolor \MPcolor{LineColor} ; + StopPage ; +\stopuseMPgraphic + +\definecolor[PageColor][s=.50] +\definecolor[TextColor][s=.80] +\definecolor[DoneColor][s=.65] +\definecolor[LineColor][r=.7,g=.6,b=.5] + +\defineoverlay [idea] [\useMPgraphic {idea}] +\defineoverlay [page] [\reuseMPgraphic{page}] + +\setupbackgrounds + [page] + [background={page,forward}] + +\defineoverlay[forward][\overlaybutton{forward}] + +% alternatief: buffer en ander regime, zodat lokale kleuren +% kunnen worden genilled. Pos gebruiken om te positioneren. + +\definereference[thispage][page(\realfolio)] + +\newbox\firstideabox \setbox\firstideabox =\null +\newbox\secondideabox \setbox\secondideabox=\null +\newbox\thirdideabox \setbox\thirdideabox =\null + +\def\StartTopic% bottom title, top title + {\dodoublegroupempty\doStartTopic} + +\def\doStartTopic#1#2% the positions end up at each page -) + {\setbox\firstideabox= + \vbox to \makeupheight + \bgroup + \getrandomdimen\scratchdimen{.5cm}\makeupheight + \vskip 0cm plus \scratchdimen + \hbox to \makeupwidth + \bgroup + \getrandomdimen\scratchdimen{.5cm}\makeupwidth + \hskip 0cm plus \scratchdimen + \setbox\scratchbox=\hbox\bgroup\hpos{idea:\realfolio} + \bgroup + \getrandomdimen\hsize{.5\makeupwidth}{.7\makeupwidth}% + \framed + [offset=3ex,align=middle,strut=no,frame=off, + before=,after=] + \bgroup + \setupwhitespace[big]% + \doifsomething{#2}{\Title{#2}}% + \def\StopTopic{% + \egroup + \egroup + \egroup + \gotobox{\box\scratchbox}[thispage]% + \getrandomdimen\scratchdimen{.5cm}\makeupwidth + \hskip 0cm plus \scratchdimen + \egroup + \getrandomdimen\scratchdimen{.5cm}\makeupheight + \vskip 0cm plus \scratchdimen + \hbox to \makeupwidth + \bgroup + \hfill + \hpos{title:\realfolio} + {\button[offset=1.5ex,frame=off]{#1}[backward]}% + \getrandomdimen\scratchdimen{.5cm}{2.5cm}% + \hskip \scratchdimen + \egroup + \getrandomdimen\scratchdimen{.5cm}{1.5cm} + \vskip \scratchdimen + \egroup + \setbox\secondideabox=\vbox + {\framed + [offset=overlay,frame=off,background=idea,backgroundcolor=TextColor] + {\copy\firstideabox}} + \setbox\firstideabox=\vbox + {\framed + [offset=overlay,frame=off,background=idea,backgroundcolor=DoneColor] + {\LineColor\copy\firstideabox}} + \startstandardmakeup + \startoverlay + {\copy\thirdideabox } + {\copy\secondideabox} + \stopoverlay + \stopstandardmakeup + \setbox\thirdideabox=\vbox + {\startoverlay + {\copy\thirdideabox } + {\copy\firstideabox} + \stopoverlay}}} + +\long\def\TitlePage#1#2% + {\bgroup + \switchtobodyfont[32pt] + \StartTopic{#1}#2\StopTopic + \egroup} + +\def\Title#1{\midaligned{\bfb#1}\blank} + +\doifnotmode{demo}{\endinput} + +% \usemodule[pre-super] % super ellipse as well as superpositioned + +\starttext + +\setupoutput[pdftex] + +\TitlePage{August 2000}{Something Very Important} + +\StartTopic{Alpha} + A simple and not too long text just to show the idea. + A simple and not too long text just to show the idea. + A simple and not too long text just to show the idea. +\StopTopic + +\StartTopic{Beta and Gamma} + A simple and not too long text just to show the idea. + A simple and not too long text just to show the idea. +\StopTopic + +\StartTopic{Delta} + A simple and not too long text just to show the idea. +\StopTopic + +\StartTopic{Epsilon} + A simple and not too long text just to show the idea. + A simple and not too long text just to show the idea. + A simple and not too long text just to show the idea. +\StopTopic + +\StartTopic{Zeta, Eta and Theta} + A simple and not too long text just to show the idea. + A simple and not too long text just to show the idea. + A simple and not too long text just to show the idea. +\StopTopic + +\StartTopic{Omega} + A simple and not too long text just to show the idea. + A simple and not too long text just to show the idea. + A simple and not too long text just to show the idea. + A simple and not too long text just to show the idea. +\StopTopic + +\stoptext diff --git a/tex/context/base/s-ptj-01.tex b/tex/context/base/s-ptj-01.tex new file mode 100644 index 000000000..9990bf006 --- /dev/null +++ b/tex/context/base/s-ptj-01.tex @@ -0,0 +1,425 @@ +%D \module +%D [ file=s-ptj-01, +%D version=2009.12.18, +%D title=\CONTEXT\ Style File, +%D subtitle=PracTeX Journal Style, +%D author=Aditya Mahajan, +%D email=adityam at umich dot edu, +%D date=\currentdate, +%D copyright=2009 Aditya Mahajan] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%M % These macros are needed to compile the documentation. +%M \def\PracTeX {Prac\kern-0.07em\TeX} +%M \def\PRACTEX {\PracTeX} +%M \def\pracjourn {The \PRACTEX\ Journal} +%M \useurl[pracjourn][http://www.tug.org/pracjourn/][][\pracjourn] +%M \useurl[texgyre] [http://www.gust.org.pl/projects/e-foundry/tex-gyre/] + +\writestatus {loading} {Context Module for the PracTeX Journal} + +%D This module is for producing acticles for \from[pracjourn]. It merely copies the +%D layout of the the \LATEX\ class \filename{pracjourn.cls} available from +%D \pracjourn\ website (\url[pracjourn]). This module has a filename synonym +%D \filename{pracjourn}. So to use this module, you can write: +%D \starttyping +%D \usemodule[pracjourn] +%D \stoptyping +%D A sample document is given at the end of this file. The typeset sample can +%D be obtained by +%D \starttyping +%D texmfstart texexec --mode=demo s-ptj-01.tex +%D \stoptyping +%D The documentation is written as comments. If you want to see a \PDF\ copy +%D \starttyping +%D texmfstart texexec --module s-ptj-01.tex +%D \stoptyping + +\startmodule[pracjourn] + +\unprotect + +%D First let's setup the paper size and layout for \pracjourn. I am actually not +%D sure about the \quote{official} layout requirement for \pracjourn\ and have +%D reverse engineered the layout from the typeset \LATEX\ examples. If you +%D feel that anything is wrong here, please let me know. + +\setuppapersize + [letter][letter] + +\setuplayout + [ width=middle, + height=middle, + location=middle, + topspace=1.25in, + bottomspace=1in, + backspace=1in, + cutspace=1in, + leftmargin=0.25in, + rightmargin=0.25in, + leftmargindistance=0in, + rightmargindistance=0in, + header=1in, + footer=.5in, + headerdistace=0in, + footerdistance=.25in, + ] + +%D Next we do the font setup. \pracjourn\ uses mathpazo for roman and math faces and +%D uses latin modern for sans serif and monotype. For the main face, 12pt is +%D used with a 15.5pt baseline skip. Font protrusion is enabled, but font +%D expansion is not. We follow these conventions. \CONTEXT\ uses Pagella fonts +%D from \TEX{gyre} project, so we use them instead. + +\usetypescript [serif,sans,mono] [hanging] [pure] +\setupalign [hanging] +\usetypescript [palatino][encoding=texnansi] +\setupbodyfont [palatino,12pt] + +\definefont [titlefont] [Regular at 20pt] +\definefont [authorfont] [Regular at 14pt] + +\setupbodyfontenvironment + [12pt] + [interlinespace=15.5pt,em=italic] + +\setupbodyfontenvironment + [11pt] + [interlinespace=13.6pt,em=italic] + +%D The variables for the article are stored in the \mono{pracjourn} namespace. +%D To initialize these variables use +%D \starttyping +%D \setvariables +%D [pracjourn] +%D [ title=Tile of the Article, +%D author=Name of Author, +%D address=Write your Address, +%D revision={d=14,m=11,y=2006}, +%D copyright=Whatever you want, +%D ] +%D \stoptyping +%D \mono{title} and \mono{author} should always be entered (even though this +%D module does not make them mandatory, it makes little sense to have an +%D article without a title or author. Other variables are optional. If a +%D revision is not written, current date will be used to show the revision. +%D Other variables for the article are the author's email address and website +%D url. Due to catcode problems, it is not always possible to reliably enter +%D these using the variable mechanism. To enter these use \type|\useURL| +%D \starttyping +%D \useURL[email][mailto:address@whatever.com][][address@whatever.com] +%D \useURL[website][link to your homepage] +%D \stoptyping +%D If either of these \URL's are not present, they will be silently ignored +%D while generating the title. + +\setvariables [pracjourn] [ title=] +\setvariables [pracjourn] [ author=] +\setvariables [pracjourn] [ address=] +\setvariables [pracjourn] [copyright=] +\setvariables [pracjourn] [ revision=] + +%D We use the buffer \filename{abstract} for the abstract. So to enter the +%D abstract, write +%D \starttyping +%D \startbuffer[abstract] +%D Write your abstract +%D \stopbuffer +%D \stoptyping +%D Right now, there is no mechanism to inhibt abstracts. In case someone +%D requires it, such a mechanism is easy to implement. + +\startbuffer[abstract] +\stopbuffer + +%D The actual title with the additional information is typset by calling +%D \starttyping +%D \setups{title} +%D \stoptyping +%D Remember that the \type|\setvariables[pracjourn][...]| step must be done +%D before \type|\setups{title}|. + +\setuphead + [title] + [style=\titlefont, + after={\blank[big]}] + +%D Next we define internal frames to take care of the layout of the extra +%D material in the title. + +\defineframed + [pracjourninfotitle] + [ frame=off, + strut=yes, + width=0.1\textwidth, + height=fit, + align=left, + location=hanging, + ] + +\defineframed + [pracjourninfodetails] + [ frame=off, + strut=yes, + width=0.85\textwidth, + height=fit, + align=normal, + location=hanging, + ] + +\newif\ifpracjourntitleskipdone + +\def\pracjourninfo#1#2% + {\pracjourntitleskipdonetrue + \hbox to \textwidth + \bgroup + \hfill \pracjourninfotitle{#1} + \hfill \pracjourninfodetails{#2} + \egroup\endgraf} + +%D Now we take care of the actual layout of the title. Most of this is +%D heuristic, as I was trying to get the same visual effect as the +%D \filename{pracjourn.cls} class. If something does not match, please let me +%D know. The information is typeset as +%D \starttyping +%D \hfill \hfill +%D \stoptyping +%D at 11pt size. We also add the title and author information in the \PDF\ +%D metadata. + +\startsetups [title] +% Place the tile and the author + \title{\getvariable{pracjourn}{title}} + \blank[medium] + \bgroup\authorfont\setupinterlinespace + \getvariable{pracjourn}{author} \endgraf\egroup + \blank[2*big] +% Place the additional information + \bgroup\switchtobodyfont[11pt] + \setupindenting[no] + \doifurldefinedelse{email} + {\pracjourninfo{Email}{\tttf\from[email]\relax}} + \empty + \doifurldefinedelse{website} + {\pracjourninfo{Website}{\from[website]\relax}} + \empty + \doifsomething{\getvariable{pracjourn}{address}} + {\pracjourninfo{Address}{\getvariable{pracjourn}{address}}} + \ifpracjourntitleskipdone \blank[big] \fi + \pracjourninfo{Abstract} + {\setupindenting[yes] + \setupinterlinespace + \getbuffer[abstract] + \endgraf} + \egroup + \blank[big] + \setups{pracjourndate} + % Add information to pdfmetadata + \setupinteraction + [title={\getvariable{pracjourn}{title}}, + author={\getvariable{pracjourn}{author}}, + subtitle={The PracTeX Journal Article}] +\stopsetups + +% If revision number is present, write it to \filename{_rev.tex} +% FIXME: Do we need to ensure that the dates and month are two digits? +\startrawsetups [pracjourndate] + \doifsomething{\getvariable{pracjourn}{revision}} + {\expanded{\setvariables[pracjourn:date][y=,m=,d=,\getvariable{pracjourn}{revision}]} + \immediate\openout \scratchwrite _rev.tex + \immediate\write \scratchwrite + {\getvariable{pracjourn:date}{y}/\getvariable{pracjourn:date}{m}/\getvariable{pracjourn:date}{d}} + \immediate\closeout\scratchwrite} +\stoprawsetups + +%D Next we setup the header and footer for the first page. \pracjourn\ formats the +%D header as +%D \startlines +%D The PracTeX Journal, year, No. number +%D Article revision year/mm/dd +%D \stoplines +%D If a copyright notice is present, it is printed right aligned on the bottom +%D of first page. Otherwise the footer on the first page is empty. + +\startsetups [pracjourntitleheader] + \framed[frame=off,width=\textwidth,align=normal,location=low] + {\small\setupinterlinespace + \doifelsenothing{\pracjournissue} + {For submission to \pracjourn} + {\pracjournissue} + \endgraf + \doifelsenothing{\getvariable{pracjourn}{revision}} + {Draft of \currentdate[year,/,mm,/,dd]} + {Article revision\space + \expanded{\date[\getvariable{pracjourn}{revision}][year,/,mm,/,dd]}} + \endgraf} +\stopsetups + +\startsetups [pracjourntitlefooter] + \framed[frame=off,width=\textwidth,align=flushright,location=low] + {\small\setupinterlinespace \getvariable{pracjourn}{copyright}\endgraf} +\stopsetups + +\definetext [pracjourntitleheader] [header] [\setups{pracjourntitleheader}][] +\definetext [pracjourntitlefooter] [footer] [\setups{pracjourntitlefooter}] + +\setuphead + [title] + [header=pracjourntitleheader, + footer=pracjourntitlefooter] + +%D For rest of the pages, page number is printed on the middle of the footer. + +\setuppagenumbering [location={footer,middle}, style=mediaeval] + +%D Next we setup the formating for the sections. \pracjourn\ wants font sizes of +%D 17pt, 14pt, and 12pt respectively for section, subsection, and +%D subsubsection. By default, \tex{tfa} is 1.2, \tex{tfb} is 1.4, so the sizes +%D come out close to what is required. The section number is typset in +%D oldstyle fonts. + +\setuphead + [section,subject] + [ style=\tfb, + numberstyle=mediaeval, + before={\blank[2*big]}, + after={\blank[big]}, + ] + +\setuphead + [subsection,subsubject] + [ style=\tfa, + numberstyle=mediaeval, + before={\blank[big]}, + after={\blank[medium]}, + ] + +\setuphead + [subsubsection,subsubsubject] + [ style=\tf, + numberstyle=mediaeval, + before={\blank[medium]}, + after={\blank}, + ] + +%D Now we setup the captions. The captions head are set in normal font, and +%D the caption number is set in oldstlyle. + +\setupcaptions [headstyle=normal,stopper=:,conversion=mediaeval] + +%D Footnotes are placed in a box with a width of 1.5em. The footnote numeral +%D are set in oldstyle font. + +\setupnote + [footnote] + [margindistance=0em, + conversion=mediaeval, + command=\pracjournfootnote, + ] + +\setupnotedefinition [footnote] [location=left,hang=1] + +\def\pracjournfootnote#1{\hbox to 1.5em{#1.}} + +%D \pracjourn\ uses dash as the first level of itemize and text period as the second +%D level. The third level is left unspecified. + +\definesymbol [1] [{\symbol[dash]}] +\definesymbol [2] [\periodcentered] + +\setupitemize [each] [packed] +\setupitemize [1] [packed,autointro] [margin=1em] + +%D We enable colors, interaction and bookmarks. + +\setupinteraction [state=start,color=darkred,style=normal] +\setupurl [color=darkred] +\setupcolors [state=start] +\placebookmarks [section,subsection] [section] + +%D We setup medium indenting, whitespace and blanks. + +\setupindenting [medium,yes] +\setupwhitespace [medium] +\setupblank [medium] + +%D We define logos for \PRACTEX\ and \pracjourn. These definitions are copied from +%D \filename{pracjourn.cls} and can be accessed by \type|\PracTeX|, +%D \type|\PRACTEX| and \type|\pracjourn|. + +\def\PracTeX{Prac\kern-0.07em\TeX} +\def\PRACTEX{\PracTeX} +\def\pracjourn {The \PRACTEX\ Journal} + +%D \filename{pracjourn.cls} provides two macros \type|\ctanfile| and +%D \type|\ctanloc|. I am not sure what is the advantage of these macors. If +%D you want to use these macros, you can use the \type|\useURL| mechanism of +%D \CONTEXT. For example +%D \starttyping +%D \useURL[pracjourn][http://ctan.org/get?fn=/macros/contrib/latex/pracjourn][][\mono{CTAN:macros/contrib/latex/pracjourn}] +%D The \LATEX\ style files for \pracjourn\ is localed at \from[pracjourn] +%D \stoptyping + +%D For the final version of the paper, the string \quotation{The PracTeX +%D Journal year, No x} is written on the header. This only happens when the +%D current directory contains a file \filename{_iss.tex} which contains string +%D like \quotation{pracjourn 2006 No 04, 2006-11-15}. This step is usually taken in +%D the final production of the article. If this file is absent, \quotation{For +%D submission to the PracTeX Journal} is written instead. The next macros are +%D used to parse this file. + +\let\pracjournissue\empty + +\def\parse@iss pracjourn #1 No #2, #3-#4-#5\@nil% + {\!!counta#2\relax + \edef\pracjournissue{\pracjourn, #1, No.\,\the\!!counta}} + +%D Read the \filename{_iss.tex} file, if present to determine the current +%D issue. + +\immediate\openin\scratchread _iss.tex +\ifeof\scratchread\else + \read \scratchread to \!!stringa + \expandafter\parse@iss\!!stringa\@nil +\fi +\immediate\closein\scratchread + +\protect + +\stopmodule + +\doifnotmode{demo}{\endinput} + +\usemodule[pracjourn] + +\setvariables + [pracjourn] + [ title=\PRACTEX\ Article in \CONTEXT, + author=Aditya Mahajan, + address={Ann Arbor,\\ Michigan, USA.}, + revision={y=2006,m=11,d=14}, + copyright={Copyright \copyright\ 2006 Aditya Mahajan.} + ] + +\useURL[website][http://www.eecs.umich.edu/~adityam] +\useURL[email][mailto:adityam@umich.edu][][adityam@umich.edu] + +%D If any of the above information is not provided, the corresponding entry +%D will not apprear in the title. + +\startbuffer[abstract] +Write abstract here +\stopbuffer + +\starttext \setups[title] + +\section{Introduction} + +Write your article \unknown + +\stoptext + +\endinput diff --git a/tex/context/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/s-syn-01.tex b/tex/context/base/s-syn-01.tex new file mode 100644 index 000000000..d797be61e --- /dev/null +++ b/tex/context/base/s-syn-01.tex @@ -0,0 +1,54 @@ +%D \module +%D [ file=s-syn-01, +%D version=0000.00.00, +%D title=\CONTEXT\ Style File, +%D subtitle=Preliminary Syntax Stuff, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This is needed for the \METAFUN\ manual (this module was +%D called \type {p-syn-01} on my machine). + +\unprotect + +\def\Indent #1{\ifvmode\noindent\hbox to 2em{\hss#1}\else#1\fi} +\def\Sugar #1{\ifhmode\unskip\unskip\unskip\fi\kern.25em{#1}\kern.25em\ignorespaces} +\def\Something#1{\Sugar{\mathematics{\langle\hbox{#1}\rangle}}} +\def\Lbrace {\Sugar{\tttf\leftargument}} +\def\Rbrace {\Sugar{\tttf\rightargument}} +\def\Or {\Sugar{\mathematics{\vert}}} +\def\Optional #1{\Sugar{\mathematics{[\hbox{#1}]}}} +\def\Means {\Sugar{\mathematics{\rightarrow}}} +\def\Tex #1{\Sugar{\type{#1}}} +\def\Literal #1{\Sugar{\type{#1}}} +\def\Syntax #1{\strut\kern-.25em{#1}\kern-.25em} +\def\Next {\crlf\hbox to 2em{}\nobreak} +\def\Whatever #1{\Sugar{\mathematics{(\hbox{#1})}}} +\def\Quote #1{\Sugar{\quote{#1}}} + +\def\Or {\Sugar{\Indent{\mathematics{\vert}}}} +\def\Means {\Sugar{\Indent{\mathematics{\rightarrow}}}} + +\def\StartSyntax + {\goodbreak + \startlines + \catcode`\#=12 + \let\L \Literal + \let\S \Something + \def\FL##1{\color[darkred]{\L{##1}}} + \def\FS##1{\S{\color[darkred]{##1}}} + \let\M \Means + \let\O \Or + \let\Q \Quote + \let\LB\Lbrace + \let\RB\Rbrace} + +\def\StopSyntax + {\stoplines} + +\protect \endinput diff --git a/tex/context/base/s-sys-01.tex b/tex/context/base/s-sys-01.tex new file mode 100644 index 000000000..77d3410c4 --- /dev/null +++ b/tex/context/base/s-sys-01.tex @@ -0,0 +1,61 @@ +% engine=luatex + +%D \module +%D [ file=s-sys-01, +%D version=2008.03.32, +%D title=\CONTEXT\ Style File, +%D subtitle=Generate List of Math Symbol, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 showmath() + local slots = mathematics.slots.traditional + local escape = characters.filters.utf.private.escape + local data = characters.data + tex.sprint(tex.ctxcatcodes,"\\starttabulate[|T|c|T|T|T|T||||]") + local texsprint = tex.sprint +% -- function texsprint(a,b) print(b) end + for _, v in ipairs(table.sortedkeys(slots)) do + local t, d, u = slots[v], data[v], escape(utf.char(v)) + local class, name, description = d.mathclass or "", d.mathname or "" , d.description or "" + if class == "accent" then + u = "" + end + if t[3] and t[4] then + texsprint(tex.ctxcatcodes,string.format( + "\\NC 0x%04X\\NC $%s$\\NC %s\\NC 0x%04X\\NC %s\\NC 0x%04X\\NC %s\\NC %s\\NC %s\\NC\\NR", + v,u,t[1],t[2],t[3],t[4],class,name,description)) + else + texsprint(tex.ctxcatcodes,string.format( + "\\NC 0x%04X\\NC $%s$\\NC %s\\NC 0x%04X\\NC\\NC\\NC %s\\NC %s\\NC %s\\NC\\NR", + v,u,t[1],t[2],class,name,description)) + end + end + tex.sprint(tex.ctxcatcodes,"\\stoptabulate") +end +\stopluacode + +\setuplayout + [backspace=1cm, + topspace=1cm, + footer=1cm, + header=0cm, + height=middle, + width=middle] + +\setupbodyfont + [9pt] + +\setupfootertexts + [] + [math characters -- \pagenumber] + +\starttext +\ctxlua{showmath()} +\stoptext diff --git a/tex/context/base/scrn-bar.mkiv b/tex/context/base/scrn-bar.mkiv new file mode 100644 index 000000000..dbeaf6d7f --- /dev/null +++ b/tex/context/base/scrn-bar.mkiv @@ -0,0 +1,398 @@ +%D \module +%D [ file=scrn-bar, % was part of scrn-int +%D version=1995.01.01, +%D title=\CONTEXT\ Core Macros, +%D subtitle=Progress Bars, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 Screen Macros / Progress Bars} + +\unprotect + +%D The code is a bit upgraded to \MKIV\ but the output is mostly the same. +%D In retrospect this shoul dhave been a module. + +% todo: replace blackrule by stupid rules + +% \setupinteraction[state=start] +% \setupsubpagenumber[state=start] +% +% \startsetups bars +% \vbox +% {\hsize 5cm +% \hbox{\interactionbar[a]}\blank +% \hbox{\interactionbar[b]}\blank +% \hbox{\interactionbar[c]}\blank +% \hbox{\interactionbar[d]}\blank +% \hbox{\interactionbar[e]}\blank +% \hbox{\interactionbar[f]}\blank +% \hbox{\interactionbar[g]}\blank +% } +% \stopsetups +% +% \setupheadertexts[\setups{bars}] +% +% \starttext +% \dorecurse{10}{test \page } +% \stoptext + +\presetlocalframed[\??ib] + +%D First the usual definition code. + +\let\currentinteractionbar\empty + +\def\setinteractionbarparameter#1#2#3{\@EA\def\csname\??ib#1#2\endcsname{#3}} +\def\letinteractionbarparameter #1#2{\@EA\let\csname\??ib#1#2\endcsname} + +\def\interactionbarparameter #1{\csname\dointeractionbarparameter{\??ib\currentinteractionbar}#1\endcsname} +\def\namedinteractionbarparameter#1#2{\csname\dointeractionbarparameter{\??ib#1}#2\endcsname} +\def\interactionbarparameterhash #1{\dointeractionbarparameterhash {\??ib\currentinteractionbar}#1} + +\def\dointeractionbarparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dointeractionbarparentparameter \csname#1\s!parent\endcsname#2\fi} +\def\dointeractionbarparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\dointeractionbarparentparameterhash\csname#1\s!parent\endcsname#2\fi} + +\def\dointeractionbarparentparameter #1#2{\ifx#1\relax\s!empty\else\dointeractionbarparameter #1#2\fi} +\def\dointeractionbarparentparameterhash#1#2{\ifx#1\relax \else\dointeractionbarparameterhash#1#2\fi} + +\unexpanded\def\defineinteractionbar{\dodoubleargument\dodefineinteractionbar} +\unexpanded\def\setupinteractionbar {\dodoubleempty \dosetupinteractionbar} +\def\interactionbar {\dodoubleempty \dointeractionbar} + +\def\dosetupinteractionbar[#1][#2]% + {\ifsecondargument + \getparameters[\??ib#1][#2]% + \else + \getparameters[\??ib][#1]% + \fi} + +\def\dodefineinteractionbar[#1][#2]% + {\getparameters + [\??ib#1]% + [\s!parent=\??ib,% +% \c!foregroundcolor=\interactionbarparameter\c!color,% +% \c!foregroundstyle=\interactionbarparameter\c!style,% + #2]} + +\def\dointeractionbar[#1][#2]% + {\iflocation + \begingroup + \doifnot{#1}\v!reset % obsolete, no caching any more + {\doifassignmentelse{#1} + {\getparameters[\??ib][#2]% + \edef\currentinteractionbar{\interactionbarparameter\c!alternative}}% + {\edef\currentinteractionbar{#1}% + \ifsecondargument\getparameters[\??ib#1][#2]\fi}% + \doif{\interactionbarparameter\c!state}\v!start + {\interactionbarparameter\c!command}}% + \endgroup + \fi} + +\newdimen\interactionbarwidth +\newdimen\interactionbarheight +\newdimen\interactionbardepth +\newdimen\interactionbardistance + +%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[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. + +\def\interactionbuttons + {\dodoubleempty\dointeractionbuttons} + +\def\dointeractionbuttons[#1][#2]% er is een verdeel macro \horizontalfractions + {\iflocation + \begingroup + % beware, is already set \let\currentinteractionbar\empty + \doif{\interactionbarparameter\c!state}\v!stop\locationfalse + \iflocation + \ifsecondargument + \let\menuparameter\interactionbarparameter + \setupinteractionbar[#1]% + \interactionbarwidth\interactionbarparameter\c!width + \ifdim\interactionbarwidth=\zeropoint + \interactionbarwidth1.5\emwidth + \fi + \doifnothing\@@ibheight{\letinteractionbarparameter\c!height\v!broad}% + \doifnothing\@@ibdepth {\letinteractionbarparameter\c!depth\!!zeropoint}%%% + \setbox2\hbox{\localframed[\??ib\currentinteractionbar][\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\interactionbarwidth=\zeropoint + \!!widtha\dimexpr2\emwidth+\interactionbardistance\relax + \!!widthb\dimexpr\!!counta\!!widtha-\interactionbardistance\relax + \else + \!!widtha\interactionbarwidth + \!!widthb\dimexpr\!!counta\interactionbardistance-\interactionbardistance\relax + \advance\!!widtha -\!!widthb + \divide\!!widtha \!!counta + \!!widthb\interactionbarwidth + \fi + \hbox to \!!widthb + {\setnostrut + \processallactionsinset + [#2] + [ \v!page=>\interactionbargotox\v!firstpage \interactionbargotox\v!nextpage \interactionbargotox\v!previouspage \interactionbargotox\v!lastpage, + \v!subpage=>\interactionbargotox\v!firstsubpage\interactionbargotox\v!nextsubpage\interactionbargotox\v!previoussubpage\interactionbargotox\v!lastsubpage, + \s!unknown=>\interactionbargotox\commalistelement]% + \unskip}% + \else + \interactionbuttons[][#1]% + \fi + \fi + \endgroup + \fi} + +\def\interactionbargotox#1% + {\normalexpanded{\noexpand\dodocomplexbutton +% {\??ib\currentinteractionbar}% + {\??ib}% + [\c!height=\the\!!heighta,\c!width=\the\!!widtha]% + {\noexpand\symbol[\@@iasymbolset][#1]}% + [#1]}% + \hss} + +\def\interactionbara + {\iflocation + \interactionbarwidth \interactionbarparameter\c!width + \interactionbardistance\interactionbarparameter\c!distance + \interactionbarheight \interactionbarparameter\c!height + \interactionbardepth \interactionbarparameter\c!depth + \noindent\hbox to \interactionbarwidth \bgroup + \dontcomplain + \setupblackrules[\c!height=\v!max,\c!depth=\v!max]% + \!!widthb\dimexpr\interactionbarwidth-4\emwidth\relax + \processaction + [\interactionbarparameter\c!step] + [ \v!small=>\scratchcounter 20, + \v!medium=>\scratchcounter 10, + \v!big=>\scratchcounter 5, + \s!unknown=>\scratchcounter 10]% + \!!widtha\dimexpr\!!widthb/\scratchcounter\relax + \setupblackrules[\c!width=\!!widtha]% + \setbox\scratchbox\hbox to \interactionbarwidth + {\hskip2\emwidth + \setbox\scratchbox\hbox{\blackrule[\c!color=\interactionbarparameter\c!backgroundcolor]}% + \dorecurse\scratchcounter + {\hss\normalexpanded{\directgotodumbbox{\copy\scratchbox}[page(\the\numexpr\recurselevel*\lastpage/\scratchcounter\relax)]}}% + \hss + \hskip2\emwidth}% + \wd\scratchbox\zeropoint + \box \scratchbox + \setupblackrules[\c!width=\emwidth]% + \normalexpanded{\directgotospecbox\noexpand\interactionbarparameter{\blackrule}[\v!firstpage]}% + \hskip\emwidth + \ifnum\realpageno>\plusone + \hskip\zeropoint\!!plus\numexpr\realpageno-\plustwo\relax \s!sp\relax % cm gives overflow + \normalexpanded{\directgotospecbox\noexpand\interactionbarparameter{\blackrule}[\v!previouspage)]}% + \fi + \normalexpanded{\directgotospecbox\noexpand\interactionbarparameter{\blackrule}[page(\number\realpageno)]}% todo: \v!currentpage + \ifnum\realpageno<\lastpage\relax + \normalexpanded{\directgotospecbox\noexpand\interactionbarparameter{\blackrule}[\v!nextpage]}% + \hskip\zeropoint\!!plus\numexpr\lastpage-\realpageno-\plusone\relax \s!sp\relax % cm gives overflow + \fi + \hskip\emwidth + \normalexpanded{\directgotospecbox\noexpand\interactionbarparameter{\blackrule}[\v!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 + \interactionbarwidth\interactionbarparameter\c!width + \hbox to \interactionbarwidth + {\setupblackrules[\c!height=\interactionbarparameter\c!height,\c!depth=\interactionbarparameter\c!depth,\c!width=\emwidth]% + \scratchdimen\dimexpr(\interactionbarwidth-4\emwidth)/\numexpr\lastpage+\minusone\relax\relax + \!!widtha\numexpr\realpageno+\minusone\relax\scratchdimen + \!!widthb\numexpr\lastpage-\realpageno\relax\scratchdimen + \directgotospecbox\interactionbarparameter{\blackrule}[\v!firstpage]% + \hss + \directgotospecbox\interactionbarparameter{\blackrule[\c!width=\!!widtha]}[\v!previouspage]% + \blackrule[\c!color=\interactionbarparameter\c!contrastcolor]% + \directgotospecbox\interactionbarparameter{\blackrule[\c!width=\!!widthb]}[\v!nextpage]% + \hss + \directgotospecbox\interactionbarparameter{\blackrule}[\v!lastpage]}% + \fi \fi} + +\unexpanded\def\@@commoninteractionbargotoa#1% + {\symbol[\ifcase#1\v!previous\or\v!somewhere\or\v!next\fi]} + +\unexpanded\def\@@commoninteractionbargotob#1% + {\vrule\!!height\interactionbarheight\!!depth\interactionbardepth\!!width\!!widtha\relax} + +\unexpanded\def\@@commoninteractionbargotoc#1% + {\symbol[\ifcase#1\v!previous\or\v!somewhere\or\v!somewhere\or\v!somewhere\or\v!next\fi} + +\unexpanded\def\@@commoninteractionbargotod#1% + {\vrule \!!width\!!widtha \ifcase#1% + \!!height \interactionbarheight \!!depth \interactionbardepth \or + \!!height.5\interactionbarheight \!!depth.5\interactionbardepth \or + \!!height \interactionbarheight \!!depth \interactionbardepth \or + \!!height.5\interactionbarheight \!!depth.5\interactionbardepth \else + \!!height \interactionbarheight \!!depth \interactionbardepth \fi} + +\unexpanded\def\@@commoninteractionbarx#1% + {\doifelse{\interactionbarparameter\c!symbol}\v!yes + {\setupsymbolset[\@@iasymbolset]% + \let\dogotox\@@commoninteractionbargotoa} + {\let\dogotox\@@commoninteractionbargotob}% + \dorecurse\nofsubpages + {\scratchcounter\numexpr\recurselevel+\firstsubpage+\minusone\relax + \chardef\what + \ifnum\scratchcounter<\realpageno \zerocount \else + \ifnum\scratchcounter=\realpageno \plusone \else + \plustwo \fi\fi + \normalexpanded{\directgotospecbox\noexpand\interactionbarparameter{\dogotox\what}[page(\the\scratchcounter)]}% + #1}% + \unskip} + +\def\interactionbard + {\iflocation \ifnum\nofsubpages>\plusone \doif{\structurecounterparameter\s!subpage\c!state}\v!start{% + \interactionbarwidth \interactionbarparameter\c!width + \interactionbardistance\interactionbarparameter\c!distance + \interactionbarheight \interactionbarparameter\c!height + \interactionbardepth \interactionbarparameter\c!depth + \!!widtha\interactionbarwidth + \noindent\hbox{\@@commoninteractionbarx{\hskip\interactionbardistance}}% + }\fi \fi} + +\def\interactionbare + {\iflocation \ifnum\nofsubpages>\plusone \doif{\structurecounterparameter\s!subpage\c!state}\v!start{% + \begingroup + \interactionbarwidth \interactionbarparameter\c!width + \interactionbardistance\interactionbarparameter\c!distance + \interactionbarheight \interactionbarparameter\c!height + \interactionbardepth \interactionbarparameter\c!depth + \!!widthb\dimexpr\nofsubpages\interactionbardistance-\interactionbardistance\relax % (n-1) + \!!widtha\dimexpr(\interactionbarwidth-\!!widthb)/\nofsubpages\relax + \ifdim\!!widtha<\interactionbardistance + \interactionbarf + \else + \noindent\hbox to \interactionbarwidth{\@@commoninteractionbarx{\hss}\unskip}% + \fi + \endgroup + }\fi\fi} + +\def\interactionbarf + {\iflocation \ifnum\nofsubpages>\plusone \doif{\structurecounterparameter\s!subpage\c!state}\v!start{% + \interactionbarwidth \interactionbarparameter\c!width + \interactionbardistance\interactionbarparameter\c!distance + \interactionbarheight \interactionbarparameter\c!height + \interactionbardepth \interactionbarparameter\c!depth + \noindent \hbox to \interactionbarwidth \bgroup + \doloop + {\!!countc\numexpr(\nofsubpages/\recurselevel)+\plusone\relax % rounding + \!!widthb\interactionbardistance + \multiply\!!widthb \!!countc + \advance\!!widthb -\interactionbardistance + \!!widtha\interactionbarwidth + \advance\!!widtha -\!!widthb + \divide\!!widtha \!!countc + \ifdim\!!widtha<\interactionbardistance\else + \!!countb\recurselevel + \exitloop + \fi}% + \ifnum\!!countc>\plusone + % this is not that well tested + \advance\!!countc \minustwo + \!!widtha-\interactionbardistance + \!!widtha\!!countc\!!widtha + \advance\!!widtha \interactionbarwidth + \advance\!!countc \plusone + \divide\!!widtha \!!countc + \fi + \doifelse{\interactionbarparameter\c!symbol}\v!yes + {\setupsymbolset[\@@iasymbolset]% + \let\dogotox\@@commoninteractionbargotoc}% + {\let\dogotox\@@commoninteractionbargotod}% + \!!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 + \chardef\what \if!!donea + \ifnum\recurselevel<\realpageno \zerocount \else + \ifnum\recurselevel>\realpageno \plustwo \else + \plusfour \fi\fi + \else \ifnum\!!countf=\!!countb + \ifnum\recurselevel<\realpageno \plusone \else + \ifnum\recurselevel>\realpageno \plusthree \else + \plustwo \fi\fi + \fi \fi + \normalexpanded{\directgotospecbox\noexpand\interactionbarparameter{\dogotox\what}[page(\recurselevel)]}% + \hss + \!!countf\zerocount}% + \unskip + \egroup + }\fi\fi} + +\def\interactionbarg + {\iflocation \ifnum\lastsubpage>\firstsubpage\relax % no test for state? + \interactionbuttons[\v!firstsubpage,\v!previoussubpage,\v!nextsubpage,\v!lastsubpage]% + \fi \fi} + +\setupinteractionbar + [\c!state=\v!start, + \c!alternative=a, + \c!symbol=\v!no, + \c!width=10\emwidth, + \c!height=.5\emwidth, + \c!depth=\zeropoint, + \c!distance=.5\emwidth, + \c!step=\v!medium, + \c!foregroundcolor=\interactionbarparameter\c!color, + \c!foregroundstyle=\interactionbarparameter\c!style, + \c!color=\@@iacolor, + \c!contrastcolor=\@@iacontrastcolor, + \c!style=, + \c!frame=\v!on, + \c!background=color, + \c!backgroundcolor=gray, + \c!samepage=\v!yes, + \c!unknownreference=\v!yes] + +\defineinteractionbar[a][\c!command=\interactionbara] +\defineinteractionbar[b][\c!command=\interactionbarb,\c!height=\v!broad] +\defineinteractionbar[c][\c!command=\interactionbarc,\c!height=\v!max,\c!depth=\v!max] +\defineinteractionbar[d][\c!command=\interactionbard,\c!width=.5\emwidth] +\defineinteractionbar[e][\c!command=\interactionbare] +\defineinteractionbar[f][\c!command=\interactionbarf] +\defineinteractionbar[g][\c!command=\interactionbarg,\c!height=\v!broad] + +\protect \endinput diff --git a/tex/context/base/scrn-but.mkiv b/tex/context/base/scrn-but.mkiv new file mode 100644 index 000000000..9a72a756b --- /dev/null +++ b/tex/context/base/scrn-but.mkiv @@ -0,0 +1,127 @@ +%D \module +%D [ file=scrn-but, % moved code +%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. + +\writestatus{loading}{ConTeXt Screen Macros / Buttons} + +\unprotect + +%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} + +\unexpanded\def\setupbuttons + {\dodoubleargument\getparameters[\??bt]} + +\definecomplexorsimpleempty\button + +\def\complexbutton + {\docomplexbutton\??bt} + +\presetlocalframed[\??bt] + +\def\buttonparameter#1{\csname\??bt#1\endcsname} % simple version + +\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 + +% #3=none is obsolete, just use empty=yes + +\long\def\dodocomplexbutton#1[#2]#3[#4]% #3 can contain [] -> {#3} later + {\begingroup + \let\menuparameter\buttonparameter + \doif{\buttonparameter\c!state}\v!stop\locationfalse + \iflocation + \setlocationboxyes#1[#2]{#3}[#4]% + \fi + \endgroup} + +%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 + \gotobox{\overlayfakebox}[#1]% + \fi} + +\def\overlayfakebox + {\hbox + {\setbox\scratchbox\null + \wd\scratchbox\overlaywidth + \ht\scratchbox\overlayheight + \box\scratchbox}} + +%D Done. + +\setupbuttons + [\c!state=\v!start, + \c!width=\v!fit, + \c!height=\v!broad, + \c!offset=0.25em, + \c!frame=\v!on, + \c!background=, + \c!backgroundcolor=, + \c!foregroundstyle=\buttonparameter\c!style, + \c!foregroundcolor=\buttonparameter\c!color, + \c!style=\@@iastyle, + \c!color=\@@iacolor, + \c!contrastcolor=\@@iacontrastcolor, + \c!samepage=\v!yes, + \c!unknownreference=\v!yes, + \c!distance=\zeropoint] % for menubuttons + +\protect \endinput diff --git a/tex/context/base/scrn-fld.mkii b/tex/context/base/scrn-fld.mkii new file mode 100644 index 000000000..4e1b34fa9 --- /dev/null +++ b/tex/context/base/scrn-fld.mkii @@ -0,0 +1,1247 @@ +%D \module +%D [ file=scrn-fld, +%D version=1997.05.18, +%D title=\CONTEXT\ Screen 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 Screen 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 +%D +%D Beware, in \MKII\ we don't support autocloning for radiofields. + +\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] + +%D Goodie: + +\def\definepushbutton % name optional setup + {\dodoubleempty\dodefinepushbutton} + +\def\dodefinepushbutton[#1][#2]% name setup + {\dododefinepushbutton{#1}{n}{push}% + \dododefinepushbutton{#1}{r}{\symbol[psym:#1:n]}% + \dododefinepushbutton{#1}{d}{\symbol[psym:#1:r]}% + \setvalue{pushbutton:#1}{\dohandlepushbutton{#1}{#2}}} + +\def\dododefinepushbutton#1#2#3% + {\doifsymboldefinedelse{psym:#1:#2}% + \donothing{\definesymbol[psym:#1:#2][{#3}]}} + +\def\definepushsymbol + {\dotripleargument\dodefinepushsymbol} + +\def\dodefinepushsymbol[#1][#2]% [#3] + {\definesymbol[psym:#1:#2]} + +\def\dopushbutton[#1][#2]% + {\executeifdefined{pushbutton:#1}\gobbleoneargument{#2}} + +\def\pushbutton + {\dodoubleargument\dopushbutton} + +\def\dohandlepushbutton#1#2#3% identifier setup script + {\bgroup + \nextsystemfield + \setupfield + [pushbutton] + [\c!frame=\v!overlay, + \c!offset=\v!overlay, + \c!clickout=#3,#2]% + \definefield + [\currentsystemfield] + [push] + [pushbutton] + [psym:#1:n,psym:#1:r,psym:#1:d]% + \fitfield + [\currentsystemfield]% + \egroup} + +% \def\do@@ampsh +% {\dodoubleargument\dodo@@ampsh} +% +% \def\dodo@@ampsh[#1][#2]#3\\% +% {\txt\pushbutton[#1][#2]\\}% +% +%\appendtoks \let\psh\do@@ampsh \to \everysetmenucommands + +\def\@@ampsh{\txt\pushbutton} + +\appendtoks \let\psh\@@ampsh \to \everysetmenucommands + +% \definepushbutton [reset] +% +% \definepushsymbol [reset] [n] [\uniqueMPgraphic{whatever}{color=green}] +% \definepushsymbol [reset] [r] [\uniqueMPgraphic{whatever}{color=white}] +% +% \startinteractionmenu[bottom] +% \psh [reset] [JS(reset_something)] \\ +% \stopinteractionmenu + +%D Another goodie: + +% \definecolor[rollover:n][red] +% \definecolor[rollover:r][green] +% \definecolor[rollover:d][blue] + +\definepalet + [rollover] + [n=red, + r=green, + d=blue] + +\newcounter\nofrollovers +\newcounter\nofrollbuttons + +\def\dorollbutton[#1][#2]#3[#4]% + {\dontleavehmode + \bgroup + \doglobal\increment\nofrollovers + \doglobal\increment\nofrollbuttons + \unexpanded\def\dosetlocationbox[##1]##2[##3]% + {\getparameters[##1][##3]% + \definecolor[rollover][rollover:##2]% + \doifelse{##2}{n}{\doifelsevalue{##1\c!alternative}\v!hidden\phantom\hbox}\hbox + {\localframed[##1] + [\c!framecolor=rollover,\c!backgroundcolor=rollover,\c!color=rollover]% + {\dolocationattributes{##1}\c!style\c!color{#3}}}}% + \iffirstargument + \ifsecondargument + \def\setlocationbox##1{\dosetlocationbox[\??am#1]{##1}[#2]}% + \else + \doifassignmentelse{#1} + {\def\setlocationbox##1{\dosetlocationbox[\??bt]{##1}[#1]}} + {\def\setlocationbox##1{\dosetlocationbox[\??am#1]{##1}[]}}% + \fi + \else + \def\setlocationbox##1{\dosetlocationbox[\??bt]{##1}[]}% + \fi + % todo: share symbols, tricky since different dimensions + \definesymbol[rsym:\nofrollovers:n][\setlocationbox n]% + \definesymbol[rsym:\nofrollovers:r][\setlocationbox r]% + \definesymbol[rsym:\nofrollovers:d][\setlocationbox d]% + \setupfield + [rollbutton] + [\c!frame=\v!off, + \c!offset=\v!overlay, + \c!clickout={#4}]% + \definefield + [roll:\nofrollbuttons][push][rollbutton] + [rsym:\nofrollovers:n,% + rsym:\nofrollovers:r,% + rsym:\nofrollovers:d]% + \fitfield[roll:\nofrollbuttons]% + \egroup} + +\unexpanded\def\rollbutton + {\dodoubleempty\dorollbutton} + +\def\menu@rob[#1]#2\\% + {\txt\rollbutton[\currentmenu]{\ignorespaces#2\unskip}[#1]\\}% + +\appendtoks \let\rob\menu@rob \to \everysetmenucommands + +% calls: +% {..} [JS..] +% [left] {..} [JS..] +% [a=b] {..} [JS..] +% [left] [a=b] {..} [JS..] +% +% \setupbuttons[offset=0pt,frame=off] % alternative=hidden +% +% \rollbutton {Manuals} [JS(Goto_File{show-man.pdf})] +% \rollbutton {Articles} [JS(Goto_File{show-art.pdf})] +% \rollbutton {Papers} [JS(Goto_File{show-pap.pdf})] +% \rollbutton {Presentations} [JS(Goto_File{show-pre.pdf})] +% \rollbutton {Resources} [JS(Goto_File{show-res.pdf})] +% +% \rob [JS(...)] bla bla \\ + +\unexpanded\def\overlayrollbutton + {\dodoubleargument\dooverlayrollbutton} + +\def\dooverlayrollbutton[#1][#2]% + {\bgroup + \nextsystemfield + \setupfield + [overlayrollbutton] + [\c!frame=\v!off,\c!offset=\v!overlay,\c!regionin={#1},\c!regionout={#2}]% + \definesymbol + [\currentsystemfield] + [{\framed[\c!frame=\v!off,\c!width=\overlaywidth,\c!height=\overlayheight]{}}]% + \definefield + [\currentsystemfield][push][overlayrollbutton][\currentsystemfield][\currentsystemfield]% + \fitfield[\currentsystemfield]% + \egroup} + +% \defineoverlay +% [ShowMenu] +% [{\overlayrollbutton[VideLayer{navigation}][HideLayer{navigation}]}] + +\protect \endinput diff --git a/tex/context/base/scrn-fld.mkiv b/tex/context/base/scrn-fld.mkiv new file mode 100644 index 000000000..f895089e8 --- /dev/null +++ b/tex/context/base/scrn-fld.mkiv @@ -0,0 +1,686 @@ +%D \module +%D [ file=scrn-fld, +%D version=1997.05.18, +%D title=\CONTEXT\ Screen 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. + +\writestatus{loading}{ConTeXt Screen Macros / Fields} + +\unprotect + +%D First we hook fields into the (viewer based) layering mechanism +%D (implemented as properties). + +\appendtoks + \doif\@@iafieldlayer\v!auto{\def\@@iafieldlayer{\currentviewerlayer}}% +\to \everysetupinteraction + +\setupinteraction + [\c!fieldlayer=\v!auto] % auto by default + +%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 + +%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} + +\unexpanded\def\definedefaultsymbols + {\definesymbol[defaultyes][\mathematics{\times}]% + \definesymbol[defaultno ][\mathematics{\cdot }]} + +\def\resetfieldsymbol[#1]% for experimental usage only + {\resetobject{SYM}{#1}} + +%D The interface to the specials. DEFAULT NOG ANDERS + +\def\typesetfield + {\bgroup + \dosetfontattribute\??fd\c!style + \ctxlua{backends.codeinjections.typesetfield("\currentfieldname", { + title = "\currentfieldname", + width = \number\dimexpr\@@fdwidth\relax, + height = \number\dimexpr\@@fdheight\relax, + align = "\@@fdalign", + length = tonumber("\@@fdn") or 0, + style = "\@@fdstyle", + fontstyle = "\fontstyle", + fontalternative = "\fontalternative", + fontsize = "\currentfontbodysize", + color = "\@@fdcolor", + backgroundcolor = "\@@fdfieldbackgroundcolor", + framecolor = "\@@fdfieldframecolor", + layer = "\@@fdfieldlayer", + options = "\@@fdoption", + align = "\@@fdalign", + clickin = "\@@fdclickin", + clickout = "\@@fdclickout", + regionin = "\@@fdregionin", + regionout = "\@@fdregionout", + afterkey = "\@@fdafterkey", + format = "\@@fdformat", + validate = "\@@fdvalidate", + calculate = "\@@fdcalculate", + focusin = "\@@fdfocusin", + focusout = "\@@fdfocusout", + }) }% + \egroup} + +\unexpanded\def\definefieldset {\dodoubleargument\dodefinefieldset} +\unexpanded\def\definefield {\doquintupleempty\dodefinefield} +\unexpanded\def\definemainfield{\doquintupleempty\dodefinefield} % redundant +\unexpanded\def\definesubfield {\dotripleempty \dodefinesubfield} +\unexpanded\def\clonefield {\doquadrupleempty\doclonefield} +\unexpanded\def\copyfield {\dodoubleempty \docopyfield} +\unexpanded\def\field {\dodoubleempty \donormalfield} +\unexpanded\def\fitfield {\dodoubleempty \dofitfield} +\unexpanded\def\setupfield {\doquintupleempty\dosetupfield} +\unexpanded\def\setupfields {\doquadrupleempty\dosetupfields} + +% misc + +% \appendtoks\ctxlua{backends.codeinjections.finishfields()}\to\everylastshipout + +% testing + +\def\doiffieldelse #1{\ctxlua{backends.codeinjections.doiffieldelse("#1")}} +\def\doiffieldgroupelse#1{\ctxlua{backends.codeinjections.doiffieldgroupelse("#1")}} + +% definition + +\def\dodefinefield[#1][#2][#3][#4][#5]% [name] [kind] [group] [values] [default] | [name] [kind] [group] [default] + {\ctxlua{backends.codeinjections.definefield{ variant="normal", name="#1", kind="#2", group="#3", values=\!!bs#4\!!es, default=\!!bs#5\!!es }}} + +\def\dodefinesubfield[#1][#2][#3]% [name] [group] [values] + {\ctxlua{backends.codeinjections.definefield{ variant="normal", name="#1", kind="sub", group="#2", values=\!!bs#3\!!es }}} + +\def\doclonefield[#1][#2][#3][#4]% [parent] [children] [group] [values] + {\ctxlua{backends.codeinjections.clonefield{ variant="clone", parent="#1", children="#2", group="#3", values=\!!bs#4\!!es }}} + +\def\docopyfield[#1][#2]% [parent] [children] + {\ctxlua{backends.codeinjections.clonefield{ variant="copy", parent="#1", children="#2" }}} + +\def\dodefinefieldset[#1][#2]% + {\ctxlua{backends.codeinjections.definefieldset("#1","#2")}} + +% usage +% +% \iftrialtypesetting +% +% just a default setup + +\def\loadfieldscripts{\useJSscripts[fld]\globallet\loadfieldscripts\relax} + +\def\donormalfield{\doprocessfield\dohandlefield} +\def\dofitfield {\doprocessfield\dohandlefitfield} + +\def\dosetupfieldindeed#1#2[#3]% [#4][#5][#6][#7]% + {#1[#2]} % [#4][#5][#6][#7]} + +\def\doprocessfield#1[#2][#3]% \method [name] [label] + {\dontleavehmode + \begingroup + \loadfieldscripts + \edef\currentfieldname {#2}% + \edef\currentfieldlabel{#3}% + \edef\currentfieldgroup{\ctxlua{backends.codeinjections.getfieldgroup("#2")}}% + \ifx\currentfieldlabel\empty + \let\currentfieldlabel\currentfieldname + \fi + \ifx\currentfieldgroup\empty + #1[#2][\v!label,\v!frame,\v!horizontal][][][]% + \else + \def\dosetupfield{\dosetupfieldindeed{#1}{#2}}% + \getvalue{\??fd::\currentfieldgroup}% + \fi + \endgroup} + +% setups + +\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\normaldodosetupfield[#1][#2][#3][#4][#5]% + {\ifcsname\??fd::#1\endcsname + \pushmacro\dosetupfield + \def\dosetupfield[##1][##2][##3][##4][##5]{\setvalue{\??fd::#1}{\dosetupfield[#1][##2,#2][##3,#3][##4,#4][##5,#5]}}% + \getvalue{\??fd::#1}% + \popmacro\dosetupfield + \else + \setvalue{\??fd::#1}{\dosetupfield[#1][#2][#3][#4][#5]}% + \fi} + +\let\dodosetupfield\normaldodosetupfield + +\def\donosetupfield[#1][#2][#3][#4][#5]% + {\setvalue{\??fd::#1}{\dosetupfield[#1][#2][#3][#4][#5]}} + +\def\dosetupfields[#1][#2][#3][#4]% + {\ifsecondargument + \def\dodosetupfield[##1][##2][##3][##4][##5]% + {\ifcsname\??fd::##1\endcsname + \def\dosetupfield[####1][####2][####3][####4][####5]% + {\setvalue{\??fd::##1}{\dosetupfield[##1][#1,####2,##2][#2,####3,##3][#3,####4,##4][#4,####5,##5]}}% + \getvalue{\??fd::##1}% + \else + \setvalue{\??fd::##1}{\dosetupfield[##1][#1,##2][#2,##3][#3,##4][#4,##5]}% + \fi}% + \else\iffirstargument + \doifelse{#1}\v!reset + {\resetfields} + {\setupfields[][][][#1]}% checken + \else + \writestatus\m!fields{provide either 1 or 4 arguments}% + \fi\fi} + +\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]% + \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] + {\currentfieldlabel}}% + \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=-\framedoffset,\c!fieldbackgroundcolor=, + \c!fieldframecolor=,\c!fieldlayer=\@@iafieldlayer,#5]% + \scratchdimen\framedwidth \edef\@@fdwidth {\the\scratchdimen}% + \scratchdimen\framedheight\edef\@@fdheight{\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=] + {\edef\defaultfield{\ctxlua{backends.codeinjections.getdefaultfieldvalue("#1")}}% + % \dopresetsymbol\defaultfield + \setbox\scratchbox\hbox{\symbol[\defaultfield]}% + \edef\@@fdwidth {\the\wd\scratchbox}% + \ifcase\fitfieldmode + \edef\@@fdheight{\the\ht\scratchbox}% + \typesetfield + \or % 1 = ignore depth (original, assumed no depth, actually a bug) + \edef\@@fdheight{\the\ht\scratchbox}% + \vbox to \ht\scratchbox{\vfill\hbox to \wd\scratchbox{\typesetfield\hfill}\vss}% + \or % 2 = add depth to height, but no depth in result + \edef\@@fdheight{\the\htdp\scratchbox}% + \vbox to \ht\scratchbox{\vfill\hbox to \wd\scratchbox{\typesetfield\hfill}\vss}% + \or % 3 = add depth to height, and apply depth to result + \edef\@@fdheight{\the\htdp\scratchbox}% + \hbox to \wd\scratchbox{\lower\dp\scratchbox\hbox{\typesetfield}\hfill}% + \fi}} + +%D Common stuff + +\newcount\nofsystemfields + +\def\nextsystemfield + {\global\advance\nofsystemfields\plusone + \def\currentsystemfield{sys::\number\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=\zeropoint, + \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% + {\dontleavehmode + \begingroup + \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 + \endgroup} + +%D And one more: + +\unexpanded\def\definefieldstack + {\dotripleargument\dodefinefieldstack} + +\def\dodefinefieldstack[#1][#2][#3]% name, symbols, settings + {\ifcsname fieldstack:#1\endcsname \else + \setgvalue{fieldstack:#1}{\dodofieldstack[#1][#2][#3]}% + \fi} + +\def\fieldstack + {\dotripleempty\dofieldstack} + +\def\dofieldstack[#1][#2][#3]% + {\ifsecondargument + \dodefinefieldstack[#1][#2][#3]\fieldstack[#1]% + \else + \getvalue {fieldstack:#1}% + \setgvalue{fieldstack:#1}{[#1]}% + \fi} + +\def\dodofieldstack[#1][#2][#3]% start=n, 0 == leeg + {\dontleavehmode + \begingroup + \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,\empty][##1]% \v!empty fails + \else + \definefield[#1:\stackedfieldnumber][check][#1][##1,\empty][\empty]% \v!empty fails + \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 + \endgroup} + +%D When submitting a form, we need to tell the driver module +%D that we want \FDF\ or \HTML. + +\newtoks\everysetupforms + +\unexpanded\def\setupforms{\dosingleempty\dosetupforms} + +\def\dosetupforms[#1] + {\getparameters[\??fr][#1]% + \the\everysetupforms} + +\appendtoks + \ctxlua{backends.codeinjections.setformsmethod("@@frmethod")}% +\to \everysetupforms + +\setupforms + [\c!method=XML] % no need for everyjob initialization as this is the default + +%D Goodie: (unchecked in \MKIV) + +\unexpanded\def\definepushbutton % name optional setup + {\dodoubleempty\dodefinepushbutton} + +\def\dodefinepushbutton[#1][#2]% name setup + {\dododefinepushbutton{#1}{n}{push}% + \dododefinepushbutton{#1}{r}{\symbol[psym:#1:n]}% + \dododefinepushbutton{#1}{d}{\symbol[psym:#1:r]}% + \setvalue{pushbutton:#1}{\dohandlepushbutton{#1}{#2}}} + +\def\dododefinepushbutton#1#2#3% + {\doifsymboldefinedelse{psym:#1:#2}% + \donothing{\definesymbol[psym:#1:#2][{#3}]}} + +\unexpanded\def\definepushsymbol + {\dotripleargument\dodefinepushsymbol} + +\def\dodefinepushsymbol[#1][#2]% [#3] + {\definesymbol[psym:#1:#2]} + +\def\dopushbutton[#1][#2]% + {\executeifdefined{pushbutton:#1}\gobbleoneargument{#2}} + +\def\pushbutton + {\dodoubleargument\dopushbutton} + +\def\dohandlepushbutton#1#2#3% identifier setup script + {\bgroup + \nextsystemfield + \setupfield + [pushbutton] + [\c!frame=\v!overlay, + \c!offset=\v!overlay, + \c!clickout=#3,#2]% + \definefield + [\currentsystemfield] + [push] + [pushbutton] + [psym:#1:n,psym:#1:r,psym:#1:d]% + \fitfield + [\currentsystemfield]% + \egroup} + +% \def\menu@psh +% {\dodoubleargument\domenu@psh} +% +% \def\domenu@psh[#1][#2]#3\\% +% {\txt\pushbutton[#1][#2]\\}% +% +%\appendtoks \let\psh\do@@ampsh \to \everysetmenucommands + +\unexpanded\def\menu@psh{\txt\pushbutton} + +\appendtoks \let\psh\menu@psh \to \everysetmenucommands + +% \definepushbutton [reset] +% +% \definepushsymbol [reset] [n] [\uniqueMPgraphic{whatever}{color=green}] +% \definepushsymbol [reset] [r] [\uniqueMPgraphic{whatever}{color=white}] +% +% \startinteractionmenu[bottom] +% \psh [reset] [JS(reset_something)] \\ +% \stopinteractionmenu + +%D Another goodie: (unchecked in \MKIV) + +% \definecolor[rollover:n][red] +% \definecolor[rollover:r][green] +% \definecolor[rollover:d][blue] + +\definepalet + [rollover] + [n=red, + r=green, + d=blue] + +\newcounter\nofrollovers +\newcounter\nofrollbuttons + +\def\dorollbutton[#1][#2]#3[#4]% + {\dontleavehmode + \bgroup + \doglobal\increment\nofrollovers + \doglobal\increment\nofrollbuttons + \unexpanded\def\dosetlocationbox[##1]##2[##3]% + {\getparameters[##1][##3]% + \definecolor[rollover][rollover:##2]% + \doifelse{##2}{n}{\doifelsevalue{##1\c!alternative}\v!hidden\phantom\hbox}\hbox + {\localframed[##1] + [\c!framecolor=rollover,\c!backgroundcolor=rollover,\c!color=rollover]% + {\dolocationattributes{##1}\c!style\c!color{#3}}}}% + \iffirstargument + \ifsecondargument + \def\setlocationbox##1{\dosetlocationbox[\??am#1]{##1}[#2]}% + \else + \doifassignmentelse{#1} + {\def\setlocationbox##1{\dosetlocationbox[\??bt]{##1}[#1]}} + {\def\setlocationbox##1{\dosetlocationbox[\??am#1]{##1}[]}}% + \fi + \else + \def\setlocationbox##1{\dosetlocationbox[\??bt]{##1}[]}% + \fi + % todo: share symbols, tricky since different dimensions + \definesymbol[rsym:\nofrollovers:n][\setlocationbox n]% + \definesymbol[rsym:\nofrollovers:r][\setlocationbox r]% + \definesymbol[rsym:\nofrollovers:d][\setlocationbox d]% + \setupfield + [rollbutton] + [\c!frame=\v!off, + \c!offset=\v!overlay, + \c!clickout={#4}]% + \definefield + [roll:\nofrollbuttons][push][rollbutton] + [rsym:\nofrollovers:n,% + rsym:\nofrollovers:r,% + rsym:\nofrollovers:d]% + \fitfield[roll:\nofrollbuttons]% + \egroup} + +\unexpanded\def\rollbutton + {\dodoubleempty\dorollbutton} + +\def\menu@rob[#1]#2\\% + {\txt\rollbutton[\currentmenu]{\ignorespaces#2\unskip}[#1]\\}% + +\appendtoks \let\rob\menu@rob \to \everysetmenucommands + +% calls: +% {..} [JS..] +% [left] {..} [JS..] +% [a=b] {..} [JS..] +% [left] [a=b] {..} [JS..] +% +% \setupbuttons[offset=0pt,frame=off] % alternative=hidden +% +% \rollbutton {Manuals} [JS(Goto_File{show-man.pdf})] +% \rollbutton {Articles} [JS(Goto_File{show-art.pdf})] +% \rollbutton {Papers} [JS(Goto_File{show-pap.pdf})] +% \rollbutton {Presentations} [JS(Goto_File{show-pre.pdf})] +% \rollbutton {Resources} [JS(Goto_File{show-res.pdf})] +% +% \rob [JS(...)] bla bla \\ + +\unexpanded\def\overlayrollbutton + {\dodoubleargument\dooverlayrollbutton} + +\def\dooverlayrollbutton[#1][#2]% + {\bgroup + \nextsystemfield + \setupfield + [overlayrollbutton] + [\c!frame=\v!off,\c!offset=\v!overlay,\c!regionin={#1},\c!regionout={#2}]% + \definesymbol + [\currentsystemfield] + [{\framed[\c!frame=\v!off,\c!width=\overlaywidth,\c!height=\overlayheight]{}}]% + \definefield + [\currentsystemfield][push][overlayrollbutton][\currentsystemfield][\currentsystemfield]% + \fitfield[\currentsystemfield]% + \egroup} + +% \defineoverlay +% [ShowMenu] +% [{\overlayrollbutton[VideLayer{navigation}][HideLayer{navigation}]}] + +\protect \endinput diff --git a/tex/context/base/scrn-hlp.mkii b/tex/context/base/scrn-hlp.mkii new file mode 100644 index 000000000..c9fcbd29a --- /dev/null +++ b/tex/context/base/scrn-hlp.mkii @@ -0,0 +1,171 @@ +%D \module +%D [ file=scrn-hlp, +%D version=1998.10.10, +%D title=\CONTEXT\ Screen Macros, +%D subtitle=Help (Experimental), +%D author={Hans Hagen \& Ton Otten}, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 : dedicated vide/hide voor helps + +\writestatus{loading}{ConTeXt Screen Macros / Help popups} + +%D This is an experimental and private module, so the interface +%D and functionality can change. Pieces of code will be moved +%D to other modules. More features are possible but will be +%D interfaces later. See m-chart for an application as well +%D as the second tno-tpd manual (graphic in margin, click +%D on it, pop up big one, use menu with hides, as well as +%D background, etc. etc. + +\unprotect + +\defineframedtext + [\v!helptext] + +\setupframedtexts + [\v!helptext] + [\c!width=.75\textwidth, + \c!align=\v!normal, + \c!frame=\v!off, + \c!background=\v!screen] + +\newcounter \nofhelpdataentries +\newconditional \somehelpdatadefined + +\appendtoks \getpagehelpdata \to \beforeeverypage +\appendtoks \synchronizepagehelpdata \to \aftereverypage + +% will be proper state variable + +\let\pagehelpdata\empty + +\def\dontresetpagedata + {\let\synchronizepagehelpdata\relax} + +\def\resetpagehelpdata + {\iflocation + \let\synchronizepagehelpdata\resetpagehelpdata + \global\let\pagehelpdata\empty + \resetreference[HideHelp]% + \fi} + +\let\synchronizepagehelpdata\resetpagehelpdata + +\resetreference[HideHelp] + +\def\getpagehelpdata + {\iflocation\ifcase\nofhelpdataentries\else + \let\pagehelpdata\empty + \ifconditional\somehelpdatadefined + \definetwopasslist{hlp:\realfolio}% + \doloop + {\gettwopassdata{hlp:\realfolio}% + \iftwopassdatafound + \addtocommalist\twopassdata\pagehelpdata + \else + \exitloop + \fi}% + \fi + \ifx\pagehelpdata\empty \else + \useJSscripts[fld]% + \definereference[HideHelp][JS(Hide_Fields)]% for the moment + \fi + \fi\fi} + +\def\setpagehelpdata[#1]% + {\iflocation\expanded{\dosetpagehelpdata{#1}}\fi} + +\def\dosetpagehelpdata#1% + {\doglobal\increment\nofhelpdataentries + \savetwopassdata{hlp:\realfolio}{\nofhelpdataentries}{#1}} + +\setvalue{\e!start\v!helptext}[#1]% + {\iflocation + \global\settrue\somehelpdatadefined + \setvalue{\e!stop\v!helptext}% + %{\definesymbol[helpinfo:#1][{\doframedtext[\v!helptext]{\getbuffer[\v!helptext]}}]% + % \dopresetfieldsymbol{helpinfo:#1}}% + {\definesymbol[\v!helptext:#1][{\doframedtext[\v!helptext]{\getbuffer[\v!helptext]}}]% + \dopresetfieldsymbol{\v!helptext:#1}}% + \else + \letvalue{\e!stop\v!helptext}\relax + \fi + \dostartbuffer[\v!helptext][\e!start\v!helptext][\e!stop\v!helptext]} + +\long\def\helptext[#1]#2% + {\iflocation + \global\settrue\somehelpdatadefined + %\definesymbol[helpinfo:#1][{\doframedtext[\v!helptext]{#2}}]% + %\dopresetfieldsymbol{helpinfo:#1}% + \definesymbol[\v!helptext:#1][{\doframedtext[\v!helptext]{#2}}]% + \dopresetfieldsymbol{\v!helptext:#1}% + \fi} + +\let\definehelptext\helptext % for backward compabilities sake + +\def\dohelpdata#1% + {\setbox\scratchbox\hbox + {\startoverlay + {\box\scratchbox} + %{\definemainfield[help:#1][check][helpsetup][helpinfo:#1][helpinfo:#1]% + {\definemainfield[help:#1][check][helpsetup][\v!helptext:#1][\v!helptext:#1]% + \fitfield[help:#1]} + \stopoverlay}} + +\def\helpdata + {\iflocation + \bgroup + %\getpagehelpdata + \ifx\pagehelpdata\empty \else + \setupfields[\v!reset]% + \setupfield + [helpsetup] + [\c!width=\v!fit, + \c!height=\v!fit, + \c!frame=\v!off, + \c!clickin=JS(Hide_Fields), + \c!option={\v!readonly,\v!hidden}]% + \setbox\scratchbox\emptybox + \processcommacommand[\pagehelpdata]\dohelpdata + \box\scratchbox + \fi + \egroup + \fi} + +\def\helpbutton % also gobble spaces between [][] + {\dodoubleempty\dohelpbutton} + +\def\dohelpbutton + {\ifsecondargument + \expandafter\donohelpbutton + \else + \expandafter\dodohelpbutton + \fi} + +\def\dodohelpbutton[#1][#2]#3[#4]% #2 is space gobbling dummy + {\iflocation + \setpagehelpdata[#4]% + \useJSscripts[fld]% + \button[#1]{#3}[JS(Vide_Hide_Fields{help:#4})]% + \fi} + +\def\donohelpbutton[#1][#2]% + {\dodohelpbutton[#1][]{}[#2]} + +\def\doifhelpinfo#1#2% + {\iflocation + \doifsymboldefinedelse{helpinfo:#1}{#2}\donothing + \fi} + +\def\doifelsehelpinfo#1#2#3% + {\iflocation + \doifsymboldefinedelse{helpinfo:#1}{#2}{#3}% + \fi} + +\protect \endinput diff --git a/tex/context/base/scrn-hlp.mkiv b/tex/context/base/scrn-hlp.mkiv new file mode 100644 index 000000000..4eaa340ca --- /dev/null +++ b/tex/context/base/scrn-hlp.mkiv @@ -0,0 +1,179 @@ +%D \module +%D [ file=scrn-hlp, +%D version=1998.10.10, +%D title=\CONTEXT\ Screen Macros, +%D subtitle=Help (Experimental), +%D author={Hans Hagen \& Ton Otten}, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 : dedicated vide/hide voor helps + +\writestatus{loading}{ConTeXt Screen Macros / Help popups} + +%D This is an experimental and private module, so the interface +%D and functionality can change. Pieces of code will be moved +%D to other modules. More features are possible but will be +%D interfaces later. See m-chart for an application as well +%D as the second tno-tpd manual (graphic in margin, click +%D on it, pop up big one, use menu with hides, as well as +%D background, etc. etc. + +\unprotect + +\defineframedtext + [\v!helptext] + +\setupframedtexts + [\v!helptext] + [\c!width=.75\textwidth, + \c!align=\v!normal, + \c!frame=\v!off, + \c!background=\v!screen] + +\newcounter \nofhelpdataentries +\newconditional \somehelpdatadefined + +\let\getpagehelpdata \relax +\let\synchronizepagehelpdata\relax + +\appendtoks \getpagehelpdata \to \beforeeverypage +\appendtoks \synchronizepagehelpdata \to \aftereverypage + +% will be proper state variable + +\let\pagehelpdata\empty + +\def\dontresetpagedata + {\let\synchronizepagehelpdataindeed\relax} + +\def\resetpagehelpdata + {\iflocation + \let\synchronizepagehelpdataindeed\resetpagehelpdata + \global\let\pagehelpdata\empty + \resetreference[HideHelp]% + \fi} + +\let\synchronizepagehelpdataindeed\resetpagehelpdata + +\resetreference[HideHelp] + +\def\getpagehelpdataindeed + {\iflocation\ifcase\nofhelpdataentries\else + \dogetpagehelpdataindeed + \fi\fi} + +\def\dogetpagehelpdataindeed + {\let\pagehelpdata\empty + \ifconditional\somehelpdatadefined + \definetwopasslist{hlp:\realfolio}% + \doloop + {\gettwopassdata{hlp:\realfolio}% + \iftwopassdatafound + \addtocommalist\twopassdata\pagehelpdata + \else + \exitloop + \fi}% + \fi + \ifx\pagehelpdata\empty \else + \useJSscripts[fld]% + \definereference[HideHelp][JS(Hide_Fields)]% for the moment + \fi} + +\def\setpagehelpdata[#1]% + {\iflocation\expanded{\dosetpagehelpdata{#1}}\fi} + +\def\dosetpagehelpdata#1% + {\doglobal\increment\nofhelpdataentries + \global\let\getpagehelpdata\getpagehelpdataindeed + \global\let\synchronizepagehelpdata\synchronizepagehelpdataindeed + \savetwopassdata{hlp:\realfolio}{\nofhelpdataentries}{#1}} + +\setvalue{\e!start\v!helptext}[#1]% + {\iflocation + \global\settrue\somehelpdatadefined + \setvalue{\e!stop\v!helptext}% + %{\definesymbol[helpinfo:#1][{\doframedtext[\v!helptext]{\getbuffer[\v!helptext]}}]% + % \dopresetfieldsymbol{helpinfo:#1}}% + {\definesymbol[\v!helptext:#1][{\doframedtext[\v!helptext]{\getbuffer[\v!helptext]}}]% + \dopresetfieldsymbol{\v!helptext:#1}}% + \else + \letvalue{\e!stop\v!helptext}\relax + \fi + \dostartbuffer[\v!helptext][\e!start\v!helptext][\e!stop\v!helptext]} + +\long\def\helptext[#1]#2% + {\iflocation + \global\settrue\somehelpdatadefined + %\definesymbol[helpinfo:#1][{\doframedtext[\v!helptext]{#2}}]% + %\dopresetfieldsymbol{helpinfo:#1}% + \definesymbol[\v!helptext:#1][{\doframedtext[\v!helptext]{#2}}]% + \dopresetfieldsymbol{\v!helptext:#1}% + \fi} + +\let\definehelptext\helptext % for backward compabilities sake + +\def\dohelpdata#1% + {\setbox\scratchbox\hbox + {\startoverlay + {\box\scratchbox} + %{\definemainfield[help:#1][check][helpsetup][helpinfo:#1][helpinfo:#1]% + {\definemainfield[help:#1][check][helpsetup][\v!helptext:#1][\v!helptext:#1]% + \fitfield[help:#1]} + \stopoverlay}} + +\def\helpdata + {\iflocation + \bgroup + %\getpagehelpdata + \ifx\pagehelpdata\empty \else + \setupfields[\v!reset]% + \setupfield + [helpsetup] + [\c!width=\v!fit, + \c!height=\v!fit, + \c!frame=\v!off, + \c!clickin=JS(Hide_Fields), + \c!option={\v!readonly,\v!hidden}]% + \setbox\scratchbox\emptybox + \processcommacommand[\pagehelpdata]\dohelpdata + \box\scratchbox + \fi + \egroup + \fi} + +\def\helpbutton % also gobble spaces between [][] + {\dodoubleempty\dohelpbutton} + +\def\dohelpbutton + {\ifsecondargument + \expandafter\donohelpbutton + \else + \expandafter\dodohelpbutton + \fi} + +\def\dodohelpbutton[#1][#2]#3[#4]% #2 is space gobbling dummy + {\iflocation + \setpagehelpdata[#4]% + \useJSscripts[fld]% + \button[#1]{#3}[JS(Vide_Hide_Fields{help:#4})]% + \fi} + +\def\donohelpbutton[#1][#2]% + {\dodohelpbutton[#1][]{}[#2]} + +\def\doifhelpinfo#1#2% + {\iflocation + \doifsymboldefinedelse{helpinfo:#1}{#2}\donothing + \fi} + +\def\doifelsehelpinfo#1#2#3% + {\iflocation + \doifsymboldefinedelse{helpinfo:#1}{#2}{#3}% + \fi} + +\protect \endinput diff --git a/tex/context/base/scrn-int.lua b/tex/context/base/scrn-int.lua new file mode 100644 index 000000000..7036bbf6a --- /dev/null +++ b/tex/context/base/scrn-int.lua @@ -0,0 +1,111 @@ +if not modules then modules = { } end modules ['scrn-int'] = { + version = 1.001, + comment = "companion to scrn-int.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format = string.format +local texsprint, texcount, ctxcatcodes = tex.sprint, tex.count, tex.ctxcatcodes + +interactions = interactions or { } + +local attachments = { } + +function interactions.registerattachment(specification) + if specification.label then + specification.filename = specification.filename or specification.label + specification.newname = specification.newname or specification.filename + specification.title = specification.title or specification.filename + specification.newname = file.addsuffix(specification.newname,file.extname(specification.filename)) + attachments[specification.label] = specification + return specification + end +end + +function interactions.attachment(label) + local at = attachments[label] + if not at then + interfaces.showmessage("interactions",6,label) + return interactions.registerattachment { label = label } + else + return at + end +end + +function interactions.attachmentvar(label,key) + local at = attachments[label] + texsprint(ctxcatcodes,at and at[key] or "") +end + +local soundclips = { } + +function interactions.registersoundclip(specification) + if specification.label then + specification.filename = specification.filename or specification.label + soundclips[specification.label] = specification + return specification + end +end + +function interactions.soundclip(label) + local sc = soundclips[label] + if not sc then + -- todo: message + return interactions.registersoundclip { label = label } + else + return sc + end +end + +local renderings = { } + +function interactions.registerrendering(specification) + if specification.label then + renderings[specification.label] = specification + return specification + end +end + +function interactions.rendering(label) + local rn = renderings[label] + if not rn then + -- todo: message + return interactions.registerrendering { label = label } + else + return rn + end +end + +function interactions.renderingvar(label,key) + local rn = renderings[label] + texsprint(ctxcatcodes,rn and rn[key] or "") +end + +-- linked lists + +function interactions.definelinkedlist(name) + -- no need +end + +function interactions.addlinktolist(name) + local tobesaved = jobpasses.gettobesaved(name) + local collected = jobpasses.getcollected(name) or { } + local currentlink = #tobesaved + 1 + local noflinks = #collected + tobesaved[currentlink] = 0 + local f = collected[1] or 0 + local l = collected[noflinks] or 0 + local p = collected[currentlink-1] or f + local n = collected[currentlink+1] or l + texsprint(ctxcatcodes,format("\\setlinkproperties{%s}{%s}{%s}{%s}{%s}{%s}",currentlink,noflinks,f,p,n,l)) +end + +function interactions.enhancelinkoflist(name,n) + local ll = jobpasses.gettobesaved(name) + if ll then + ll[n] = texcount.realpageno + end +end + diff --git a/tex/context/base/scrn-int.mkii b/tex/context/base/scrn-int.mkii new file mode 100644 index 000000000..cf55f864a --- /dev/null +++ b/tex/context/base/scrn-int.mkii @@ -0,0 +1,2311 @@ +%D \module +%D [ file=scrn-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 Screen 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}% + \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 + \xdef\doplacebookmarksindeed{\noexpand\dodoplacebookmarksindeed[#1][\openbookmarklist]} + \egroup + \else + \expanded{\placebookmarks\@EA[\getvalue{\??ih\v!content\c!list}]}% + \fi + \fi} + +\def\dodoplacebookmarksindeed[#1][#2]% + {\bgroup + \edef\openbookmarklist{#2}% + \global\let\bookmarklevellist\empty + \def\bookmarklevelcount{0}% + \doprocessbookmarks[#1]\dogetbookmarkelement + \dolistelement{}{}{}{}{}{}% needed to finish the first pass + \doprocessbookmarks[#1]\doputbookmarkelement + \flushbookmark + \egroup} + +\let\doplacebookmarksindeed\relax + +\prependtoks + \doplacebookmarksindeed % new, now postponed so that halfway defined commands work out ok +\to \everystoptext + +\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]% inefficient as text can be outside box + {\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 + + +\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} + +% It took quite a while to figure this out (using the preliminary 1.5 +% spec). There are still a lot of things to be implemented. This is +% the third alternative. + +% todo: multiple instances, dus indirect + +\let\currentrendering\empty + +\definereference[StartCurrentRendering] [\v!StartRendering {\currentrendering}] +\definereference[StopCurrentRendering] [\v!StopRendering {\currentrendering}] +\definereference[PauseCurrentRendering] [\v!PauseRendering {\currentrendering}] +\definereference[ResumeCurrentRendering][\v!ResumeRendering{\currentrendering}] + +\newcounter\nofexternalrenderings + +\def\useexternalrendering{\doquadrupleempty\douseexternalrendering} +\def\setinternalrendering{\dodoubleempty \dosetinternalrendering} + +\def\douseexternalrendering[#1][#2][#3][#4]% tag mime file options + {\setgvalue{\??rd:#1}{\plusone{#1}{#2}{#3}{#4}}} + +\def\dosetinternalrendering[#1][#2]% tag options {content} + {\bgroup + \dowithnextbox + {\setgvalue{\??rd:#1}{\plustwo{#1}{IRO}{#1}{#2}}% + \let\objectoffset\zeropoint + \setobject{IRO}{#1}\hbox{\box\nextbox}% + \egroup}% + \hbox} + +\def\checkrendering#1% let's hope that \next is not used + {\iflocation + \doifsomething{#1}% + {\doifdefined{\??rd:#1}% + {\expanded{\getvalue{\??rd::\number\renderingtype{#1}}% + {\filterfromvalue{\??rd:#1}52}{\filterfromvalue{\??rd:#1}53}% + {\filterfromvalue{\??rd:#1}54}{\filterfromvalue{\??rd:#1}55}}}}% + \fi} + +\setvalue{\??rd::1}{\doinsertrendering} +\setvalue{\??rd::2}{\doinsertrenderingobject} + +\def\renderingtype #1{\filterfromvalue{\??rd:#1}51} +\def\renderingoptions#1{\filterfromvalue{\??rd:#1}55} + +\setexecutecommandcheck {startrendering} \checkrendering +\setexecutecommandcheck {stoprendering} \checkrendering +\setexecutecommandcheck {pauserendering} \checkrendering +\setexecutecommandcheck {resumerendering} \checkrendering + +% by using a nice trick (used in other places of context as well) we +% can easily overload the default size to match the opbject size + +\def\renderingwidth {8cm} +\def\renderingheight{6cm} + +\def\definerenderingwindow + {\dodoubleempty\dodefinerenderingwindow} + +\def\dodefinerenderingwindow[#1][#2]% + {\presetlocalframed[\??rw#1]% + \getparameters% + [\??rw#1]% + [\c!openpageaction=,\c!closepageaction=,% + \c!width=\renderingwidth,\c!height=\renderingheight,% + #2]} + +\def\setuprenderingwindow + {\dodoubleargument\dosetuprenderingwindow} + +\def\dosetuprenderingwindow[#1]% + {\getparameters[\??rw#1]} + +\def\placerenderingwindow + {\dodoubleempty\doplacerenderingwindow} + +\def\doplacerenderingwindow[#1][#2]% + {\bgroup + \edef\currentrendering{\ifsecondargument#2\else#1\fi}% + \ifcase\renderingtype\currentrendering\or + % a file + \or + % an object + \getobjectdimensions{IRO}\currentrendering + \scratchdimen\objectheight + \advance\scratchdimen\objectdepth + \edef\renderingheight{\the\scratchdimen}% + \edef\renderingwidth{\objectwidth}% + \fi + % create fall back if needed + \doifdefinedelse{\??rw#1\c!width} + {\def\currentrenderingwindow{#1}} + {\let\currentrenderingwindow\s!default + \definerenderingwindow[\currentrenderingwindow]}% + \checkrendering\currentrendering + \handlereferenceactions{\getvalue{\??rw\currentrenderingwindow\c!openpageaction }}\dosetuprenderingopenpageaction + \handlereferenceactions{\getvalue{\??rw\currentrenderingwindow\c!closepageaction}}\dosetuprenderingclosepageaction + \localframed + [\??rw\currentrenderingwindow][\c!offset=\v!overlay]% + {\expanded{\doinsertrenderingwindow + \noexpand\currentrendering\hsize\vsize{\renderingoptions\currentrendering}}}% + \egroup} + +% todo: +% +% \setinternalrendering[example-1][options]{} + +% test file: +% +% \definerenderingwindow +% [example] +% [width=320pt,height=150pt,frame=off, +% background=color,backgroundcolor=gray, +% openpageaction=StartCurrentRendering, +% closepageaction=NextPage]% StopCurrentRendering] +% +% \useexternalrendering[example-1][audio/mpeg] [eldorado.mp3] +% \useexternalrendering[example-2][audio/mpeg] [myst-12.mp3] +% \useexternalrendering[example-3][application/x-shockwave-flash][http://localhost/mb.swf] [auto] +% \useexternalrendering[example-4][application/x-shockwave-flash][celebration.swf] +% \useexternalrendering[example-5][video/quicktime] [p1000726.mov] +% \useexternalrendering[example-6][application/smil] [quadratic_map.smi] +% +% \def\renderingmenu[#1]% +% {\hbox +% {\setupbuttons[width=2.5em]% +% \button{\symbol[StartRendering]} [StartRendering{#1}]\enspace +% \button{\symbol[StopRendering]} [StopRendering{#1}]\enspace +% \button{\symbol[PauseRendering]} [PauseRendering{#1}]\enspace +% \button{\symbol[ResumeRendering]}[ResumeRendering{#1}]}} +% +% \renderingmenu[example-1]\blank +% \renderingmenu[example-2]\blank +% \renderingmenu[example-3]\blank +% \renderingmenu[example-4] \placefigure{A ShockWave}{\placerenderingwindow[example][example-4]} \page +% \renderingmenu[example-5] \placefigure{A Movie}{\placerenderingwindow[example][example-5]} \page +% \renderingmenu[example-6] \placefigure{A Smile}{\placerenderingwindow[example][example-6]} + +\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/scrn-int.mkiv b/tex/context/base/scrn-int.mkiv new file mode 100644 index 000000000..11734e0d7 --- /dev/null +++ b/tex/context/base/scrn-int.mkiv @@ -0,0 +1,610 @@ +%D \module +%D [ file=scrn-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. + +\writestatus{loading}{ConTeXt Screen Macros / Interaction} + +\registerctxluafile{scrn-int}{1.001} + +\unprotect + +%D This is an update of \MKII\ code. In the process profiles and versions +%D were removed as I never used them (although they were kind of cool at +%D that time). + +% a bit complex due to papercomment (see imposition code) + +\newtoks\everysetupinteractionscreen + +\unexpanded\def\setupinteractionscreen + {\dosingleempty\dosetupinteractionscreen} + +\def\dosetupinteractionscreen[#1]% + {\getparameters[\??sc][#1]% + \the\everysetupinteractionscreen} + +\def\synchronizepaperdimensionssimple % simple version + {\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 + \ctxlua{backends.codeinjections.setupcanvas { + paperwidth = \number\paperwidth, + paperheight = \number\paperheight + }}% + \else + \ctxlua{backends.codeinjections.setupcanvas { + paperwidth = \number\printpaperwidth, + paperheight = \number\printpaperheight + }}% + \fi + \egroup} + +\def\synchronizepaperdimensionscomplex % complex version + {\bgroup + \edef\@@scwidth {\@@scwidth}% + \edef\@@scheight{\@@scheight}% + \ifx\@@scwidth\v!fit + \!!widtha\leftcombitotal + \ifdim\backspace>\!!widtha\ifdim\backspace>\zeropoint\relax + \advance\backspace -\!!widtha + \fi\fi + \advance\!!widtha\dimexpr\rightcombitotal+2\dimexpr\@@scbackspace+\@@schoroffset\relax\relax + \else\ifx\@@scwidth\v!max + \!!widtha\printpaperwidth + \else + \!!widtha\@@scwidth + \fi\fi + \ifx\@@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+2\dimexpr\@@sctopspace+\@@scveroffset\relax\relax + \else\ifx\@@scheight\v!max + \!!heighta\printpaperheight + \else + \!!heighta\@@scheight + \fi\fi + \doif\@@scdelay\v!none{\let\@@scdelay\zerocountervalue}% + \ifdim\!!widtha>\paperwidth\ifdim\!!widtha>\zeropoint + \paperwidth\!!widtha + \fi\fi + \ifdim\!!heighta>\paperheight\ifdim\!!heighta>\zeropoint + \paperheight\!!heighta + \fi\fi + \ctxlua{backends.codeinjections.setupcanvas { + mode = "\@@scoption", + % doublesided = \ifsinglesided false\else\ifdoublesided true\else false\fi\fi, + singlesided = \ifsinglesided true\else false\fi, + doublesided = \ifdoublesided true\else false\fi, + leftoffset = \number\dimexpr\backoffset\relax, + topoffset = \number\dimexpr\topoffset \relax, + width = \number\dimexpr\!!widtha \relax, + height = \number\dimexpr\!!heighta \relax, + paperwidth = \number\paperwidth, + paperheight = \number\paperheight + }}% + \egroup} + +\let\synchronizepaperdimensions \synchronizepaperdimensionscomplex + +\appendtoks + \ifproductionrun + \doifelse\@@pcstate\v!start + {\let\synchronizepaperdimensions\synchronizepaperdimensionssimple} + {\let\synchronizepaperdimensions\synchronizepaperdimensionscomplex}% + \fi +\to \everysetupinteractionscreen + +\appendtoks \synchronizepaperdimensions \to \everyshipout + +%D The next mechanism, linked lists, is quite old and +%D is \MKIV'd for completeness. I will finish the +%D confuguration part when I need it. + +% todo: a kind of button that gets a tag passed (\??tk) + +% \starttext +% \setupinteraction[state=start] +% \definelinkedlist[demo] +% \dorecurse{10}{\linkedlistelement[demo]{link \recurselevel} \page} +% \stoptext + +\def\linkedlistparameter #1{\csname\dolinkedlistparameter{\??lk\currentlinkedlist}#1\endcsname} +\def\dolinkedlistparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dolinkedlistparentparameter\csname#1\s!parent\endcsname#2\fi} +\def\dolinkedlistparentparameter#1#2{\ifx#1\relax\s!empty\else\dolinkedlistparameter#1#2\fi} + +\unexpanded\def\definelinkedlist{\dodoubleargument\dodefinelinkedlist} +\unexpanded\def\setuplinkedlist {\dodoubleargument\dosetuplinkedlist } +\unexpanded\def\setuplinkedlists{\dosingleargument\dosetuplinkedlists} + +\def\dodefinelinkedlist[#1][#2]% + {\ctxlua{interactions.definelinkedlist("#1")}% + \getparameters[\??lk#1][\s!parent=\??lk,#2]} + +\def\dosetuplinkedlist[#1][#2]% + {\getparameters[\??lk#1][#2]} + +\def\dosetuplinkedlists[#1]% + {\getparameters[\??lk][#1]} + +\def\setlinkproperties#1#2#3#4#5#6% + {\def\currentlink {#1}% + \def\noflinks {#2}% + \def\firstlink {#3}% + \def\previouslink{#4}% + \def\nextlink {#5}% + \def\lastlink {#6}} + +\def\linkedlistelement[#1]#2% currently no view support + {\dontleavehmode\hbox\bgroup + #2% + \iflocation + \edef\currentlinkedlist{#1}% + \ifcsname\??lk\currentlinkedlist\s!parent\endcsname + \hskip\linkedlistparameter\c!distance + \ctxlua{interactions.addlinktolist("\currentlinkedlist")}% + \expanded{\ctxlatelua{interactions.enhancelinkoflist("\currentlinkedlist",\currentlink)}}% + \dogotosomepage {\??lk\currentlinkedlist}\gotobegincharacter \firstlink + \ifnum\noflinks>\plustwo + \dogotosomepage{\??lk\currentlinkedlist}\gobackwardcharacter\previouslink + \dogotosomepage{\??lk\currentlinkedlist}\goforwardcharacter \nextlink + \fi + \dogotosomepage {\??lk\currentlinkedlist}\gotoendcharacter \lastlink + \else + \writestatus\m!interactions{no such linked list: \currentlinkedlist}% + \fi + \fi + \egroup} + +\setuplinkedlists + [\c!distance=.25em, + \c!width=\v!fit, + \c!location=\v!low, + \c!color=\@@iacolor, + \c!frame=\v!off, + \c!background=, + \c!backgroundcolor=] + +\def\koppeling {\linkedlistelement} +\def\stelkoppelingenin {\setuplinkedlists} +\def\definieerkoppeling{\definelinkedlist} + +%D Conditional page breaks: + +\def\screen + {\dosingleempty\doscreen} + +\def\doscreen[#1]% + {\iflocation\page[#1]\fi} + +%D Page transitions: + +\let\askedpagetransitions\empty + +\unexpanded\def\setuppagetransitions + {\dosingleempty\dosetuppagetransitions} + +\def\dosetuppagetransitions[#1]% + {\edef\askedpagetransitions{#1}} + +\def\setpagetransition + {\iflocation \ifx\askedpagetransitions\empty \else + \ctxlua{backends.codeinjections.setpagetransition{ n = "\askedpagetransitions", delay = "\@@scdelay" }}% + \fi \fi} + +\prependtoks \setpagetransition \to \everyshipout + +\setuppagetransitions + [\v!reset] + +%D Comments: + +\newbox\commentcollection +\newbox\commentbox +\newbox\commentboxone +\newbox\commentboxtwo + +\def\raisedcommentanchors#1#2{#1{\hbox{\raise\strutht#2}}} + +\setvalue{\??cc:\c!location:\v!inmargin }{\raisedcommentanchors\inmargin } +\setvalue{\??cc:\c!location:\v!leftedge }{\raisedcommentanchors\inleftedge } +\setvalue{\??cc:\c!location:\v!rightedge }{\raisedcommentanchors\inrightedge } +\setvalue{\??cc:\c!location:\v!leftmargin }{\raisedcommentanchors\inleftmargin } +\setvalue{\??cc:\c!location:\v!rightmargin}{\raisedcommentanchors\inrightmargin} + +\let\flushcommentanchors\relax + +\def\doflushcommentanchors + {\global\let\flushcommentanchors\relax + \ifvoid\commentbox\else\dodoflushcommentanchors\fi} % in everypar so indirect + +\def\dodoflushcommentanchors + {\executeifdefined{\??cc:\c!location:\@@cclocation}\hbox{\box\commentbox}} + +\unexpanded\def\setupcomment + {\dodoubleargument\getparameters[\??cc]} + +\unexpanded\def\placecomments{\box\commentcollection} % when option=buffer + +\def\doinsertcomment#1% + {\begingroup + \ctxlua{backends.codeinjections.presetsymbollist("\@@ccsymbol")}% + % in between predefined symbols are dealt with + \ctxlua{backends.codeinjections.registercomment { + title = "\@@cctitle", + width = \number\dimexpr\@@ccwidth \relax, + height = \number\dimexpr\@@ccheight\relax, + colormodel = \number\currentcolormodel, + colorvalue = \thecolorattribute{\@@cccolor}, + open = \@@ccopen, + symbol = "\@@ccsymbol", + buffer = "#1", + layer = "\@@cctextlayer" + }}% + \box\commentboxone + \doif\@@ccoption\v!buffer + {\setbox\scratchbox\vbox to \@@ccheight{\forgetall\vss\box\commentboxtwo}% + \wd\scratchbox\@@ccwidth + \global\setbox\commentcollection\vbox + {\startoverlay{\box\commentcollection}{\box\scratchbox}\stopoverlay}}% + \endgroup} + +\setvalue{\e!start\v!comment}{\dotripleempty\dostartcomment}% the dummy triple gobbles trailing spaces + +\def\dostartcomment[#1][#2][#3]% + {\bgroup + \doifassignmentelse{#1}{\getparameters[\??cc][#1]}{\getparameters[\??cc][\c!title=#1,#2]}% + \doifelse\@@ccoption\v!max{\let\@@ccopen\s!true}{\let\@@ccopen\s!false}% + \setcurrentbuffer{\v!comment\v!buffer}% + \dostartbuffer[\v!comment\v!buffer][\v!comment\v!buffer][\e!start\v!comment][\e!stop\v!comment]} + +\unexpanded\def\stopcomment + {\doif\@@ccstate\v!start + {\global\let\flushcommentanchors\doflushcommentanchors + \global\setbox\commentbox\frozenhbox + {\hbox to \zeropoint{\struttedbox{\tbox{\doinsertcomment{\v!comment\v!buffer}}}\hss}% + \hskip\ifvoid\commentbox\@@ccmargin\else\@@ccdistance\fi + \box\commentbox}}% + \egroup} + +\def\comment + {\dodoubleempty\docomment} + +\def\docomment[#1][#2]#3% + {\doif\@@ccstate\v!start + {\hbox to \zeropoint + {\doifassignmentelse{#1}{\getparameters[\??cc][#1]}{\getparameters[\??cc][\c!title=#1,#2]}% + \hskip-\@@ccmargin + \ctxlua{buffers.set("\v!comment\v!buffer", \!!bs\detokenize{#3}\!!es)}% + \struttedbox{\tbox{\doinsertcomment{\v!comment\v!buffer}}\hss}}}% + \ignorespaces} + +% test +% +% \startcomment +% hello beautiful\\world +% \stopcomment +% +% test +% +% \startcomment[hello] +% hello << eerste >> +% beautiful +% world +% \stopcomment +% +% test +% +% \startcomment[hello][color=green,width=10cm,height=3cm] +% hello \leftguillemot\ \'e\'erste \rightguillemot\ +% beautiful +% world +% \stopcomment +% +% test +% +% \startcomment[hello][color=red,width=4cm,height=3cm] +% hello \leftguillemot\ \'e\'erste \rightguillemot\ test +% +% beautiful +% +% world +% \stopcomment +% +% test +% +% \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 +% +% test +% +% \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] +% +% \startcomment[hello] +% oeps +% \stopcomment +% +% test +% +% \setupcomment +% [\c!symbol=normal, +% \c!option=max,width=10cm] +% +% \startcomment[hello] +% oeps +% \stopcomment +% +% test + +\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=] + +%D Attachments: + +% \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 + +\def\useattachment + {\doquadrupleempty\douseattachment} + +\def\douseattachment[#1][#2][#3][#4]% tag title newname filename + {\iffourthargument + \ctxlua{interactions.registerattachment{ label="#1", title="#2", newname="#3", filename="#4" }}% + \else\ifthirdargument + \ctxlua{interactions.registerattachment{ label="#1", title="#2", newname="#2", filename="#3" }}% + \else\ifsecondargument + \ctxlua{interactions.registerattachment{ label="#1", title="#2", newname="#2", filename="#2" }}% + \else + \ctxlua{interactions.registerattachment{ label="#1", title="#1", newname="#1", filename="#1" }}% + \fi\fi\fi} + +\def\attachment + {\dodoubleempty\doattachment} + +\def\doattachment[#1][#2]% [tag] [settings] + {\iflocation + \doif\@@atstate\v!start + {\bgroup + \setupattachments[#2]% + \ctxlua{backends.codeinjections.presetsymbollist("\@@atsymbol")}% + % we cannot yet ask for the wd/ht/dp of an xform else we could use those + \setbox\scratchbox\hbox{\symbol[\lastpredefinedsymbol]}% + \doif\@@atwidth \v!fit{\edef\@@atwidth {\the\wd\scratchbox}}% + \doif\@@atheight\v!fit{\edef\@@atheight{\the\ht\scratchbox}}% + \doif\@@atdepth \v!fit{\edef\@@atdepth {\the\dp\scratchbox}}% + % + \setbox\scratchbox\hbox + {\getvalue{\??at:\@@atalternative}{\ctxlua{backends.codeinjections.attachfile{ + label = "#1", + width = \number\dimexpr\@@atwidth \relax, + height = \number\dimexpr\@@atheight\relax, + depth = \number\dimexpr\@@atdepth \relax, + color = "\@@atcolor", + symbol = "\@@atsymbol", + layer = "\@@attextlayer", + }}}}% + \wd\scratchbox\@@atwidth + \ht\scratchbox\@@atheight + \dp\scratchbox\@@atdepth + \box\scratchbox + \egroup}% + \fi} + +\setvalue{\??at:\v!high}#1{\struttedbox{\tbox{#1}}} + +\unexpanded\def\setupattachments + {\dodoubleempty\getparameters[\??at]} + +\setupattachments + [\c!state=\v!start, + \c!color=\@@iacolor, + \c!textlayer=, + \c!width=\v!fit, + \c!height=\v!fit, + \c!depth=\v!fit, + \c!alternative=\v!high, + \c!symbol=] + +%D Defining sound tracks: +%D +%D \starttyping +%D \useexternalsoundtrack[label][file] +%D \stoptyping +%D +%D associated actions: StartSound StopSound PauseSound ResumeSound +%D +%D Todo: like external figures, also search on path, +%D although, they need to be present ar viewing time, so ... + +\def\useexternalsoundtrack + {\dodoubleargument\douseexternalsoundtrack} + +\def\douseexternalsoundtrack[#1][#2]% + {\ctxlua{interactions.registersound{ label="#1", filename="#2" }}} + +\def\checksoundtrack#1% yet untested in mkiv (also move management to lua) + {\iflocation + \ctxlua{codeinjections.insertsound{ + label = "#1", + repeat = "\@@sdoption", % not entirely ok but works + }}% + \fi} + +\unexpanded\def\setupexternalsoundtracks + {\dodoubleargument\getparameters[\??sd]} + +\setupexternalsoundtracks + [\c!option=] + +%D Multi Media: + +% todo: multiple instances, dus indirect + +\let\currentrendering\empty + +\definereference[StartCurrentRendering] [\v!StartRendering {\currentrendering}] +\definereference[StopCurrentRendering] [\v!StopRendering {\currentrendering}] +\definereference[PauseCurrentRendering] [\v!PauseRendering {\currentrendering}] +\definereference[ResumeCurrentRendering][\v!ResumeRendering{\currentrendering}] + +\newcounter\nofexternalrenderings + +\def\useexternalrendering{\doquadrupleempty\douseexternalrendering} +\def\setinternalrendering{\dodoubleempty \dosetinternalrendering} + +\def\douseexternalrendering[#1][#2][#3][#4]% tag mime file options + {\ctxlua{interactions.registerrendering { + kind = "external", + label = "#1", + mime = "#2", + filename = "#3", + options = "#4", + }}} + +\def\dosetinternalrendering[#1][#2]% tag options {content} + {\bgroup + \dowithnextbox + {\ctxlua{interactions.registerrendering { + kind = "internal", + label = "#1", + mime = "IRO", + filename = "#1", + options = "#2", + }}% + \let\objectoffset\zeropoint + \setobject{IRO}{#1}\hbox{\box\nextbox}% + \egroup}% + \hbox} + +\def\renderingtype #1{\ctxlua{interactions.renderingvar("#1","kind")}} +\def\renderingoptions#1{\ctxlua{interactions.renderingvar("#1","options")}} + +\def\renderingwidth {8cm} +\def\renderingheight {6cm} + +\unexpanded\def\definerenderingwindow + {\dodoubleempty\dodefinerenderingwindow} + +\def\dodefinerenderingwindow[#1][#2]% + {\presetlocalframed[\??rw#1]% + \getparameters + [\??rw#1]% + [\c!openpageaction=,\c!closepageaction=,% + \c!width=\renderingwidth,\c!height=\renderingheight,% + #2]} + +\unexpanded\def\setuprenderingwindow + {\dodoubleargument\dosetuprenderingwindow} + +\def\dosetuprenderingwindow[#1]% + {\getparameters[\??rw#1]} + +\unexpanded\def\placerenderingwindow + {\dodoubleempty\doplacerenderingwindow} + +\def\doplacerenderingwindow[#1][#2]% + {\bgroup + \edef\currentrendering{\ifsecondargument#2\else#1\fi}% + \doifelse{\renderingtype\currentrendering}{internal} % an object + {\getobjectdimensions{IRO}\currentrendering + \edef\renderingheight{\the\dimexpr\objectheight+\objectdepth\relax}% + \edef\renderingwidth{\objectwidth}% + \dogetobjectreferencepage{IRO}\currentrendering\renderingpage}% + {\def\renderingheight{\vsize}% + \def\renderingwidth{\hsize}% + \def\renderingpage{\realpageno}}% + % create fall back if needed + \ifcsname\??rw#1\c!width\endcsname + \def\currentrenderingwindow{#1}% + \else + \let\currentrenderingwindow\s!default + \definerenderingwindow[\currentrenderingwindow]% + \fi +% todo +% \handlereferenceactions{\getvalue{\??rw\currentrenderingwindow\c!openpageaction }}\dosetuprenderingopenpageaction +% \handlereferenceactions{\getvalue{\??rw\currentrenderingwindow\c!closepageaction}}\dosetuprenderingclosepageaction + \localframed + [\??rw\currentrenderingwindow][\c!offset=\v!overlay]% + {\ctxlua{backends.codeinjections.insertrenderingwindow { + label = "\currentrendering", + width = \number\dimexpr\renderingwidth\relax, + height = \number\dimexpr\renderingheight\relax, + options = "\renderingoptions\currentrendering", + page = \number\renderingpage, + }}}% + \egroup} + +\setupinteractionscreen + [\c!width=\printpaperwidth, + \c!height=\printpaperheight, + \c!horoffset=\!!zeropoint, + \c!veroffset=\!!zeropoint, + \c!backspace=\backspace, + \c!topspace=\topspace, + \c!option=\v!auto, + \c!delay=\v!none] + +\protect \endinput diff --git a/tex/context/base/scrn-men.mkiv b/tex/context/base/scrn-men.mkiv new file mode 100644 index 000000000..246d31bfd --- /dev/null +++ b/tex/context/base/scrn-men.mkiv @@ -0,0 +1,615 @@ +%D \module +%D [ file=scrn-bar, % was part of scrn-int +%D version=1995.01.01, +%D title=\CONTEXT\ Core Macros, +%D subtitle=Menus, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 Screen Macros / Menus} + +\unprotect + +% \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 + +% \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 + +% 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 + +%D Define menus: + +\def\setmenuparameter#1#2#3{\@EA\def\csname\??am#1#2\endcsname{#3}} +\def\letmenuparameter #1#2{\@EA\let\csname\??am#1#2\endcsname} + +\def\menuparameter #1{\csname\domenuparameter{\??am\currentmenu}#1\endcsname} +\def\namedmenuparameter#1#2{\csname\domenuparameter{\??am #1}#2\endcsname} +\def\menuparameterhash #1{\domenuparameterhash {\??am\currentmenu}#1} + +\def\domenuparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\domenuparentparameter \csname#1\s!parent\endcsname#2\fi} +\def\domenuparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\domenuparentparameterhash\csname#1\s!parent\endcsname#2\fi} + +\def\domenuparentparameter #1#2{\ifx#1\relax\s!empty\else\domenuparameter #1#2\fi} +\def\domenuparentparameterhash#1#2{\ifx#1\relax \else\domenuparameterhash#1#2\fi} + +\unexpanded\def\defineinteractionmenu + {\dotripleempty\dodefineinteractionmenu} + +\def\dodefineinteractionmenu[#1][#2][#3]% [name] [location] [settings] + {\ifsecondargument + \ifcsname\??am:\c!list:#2\endcsname \else + \letvalue{\??am:\c!list:#2}\empty + \fi + \normalexpanded{\noexpand\addtocommalist{#1}\@EA\noexpand\csname\??am:\c!list:#2\endcsname}% + \setvalue{\@@dodolistelement#1}{\def\dosomelistelement{\dodomenulistelement{#1}}}% + \ifthirdargument + \presetlocalframed[\??am#1]% + \doifassignmentelse{#3} + {\doifelse{#1}{#2} + {\getparameters[\??am#1][\c!location=#2,\c!menu=,\s!parent=\??am,#3]} + {\getparameters[\??am#1][\c!location=#2,\c!menu=,\s!parent=\??am#2,#3]}}% + {\doifelsenothing{#3} + {\getparameters[\??am#1][\c!location=#2,\c!menu=,\s!parent=\??am]} + {\getparameters[\??am#1][\c!location=#2,\c!menu=,\s!parent=\??am#3]}}% + \else + \getparameters[\??am#1][\c!location=#2,\c!menu=,\s!parent=\??am#2]% + \fi + \else + \getparameters[\??am#1][\s!parent=\??am]% simple cloning + \fi} + +\def\currentmenulist{\ifcsname\??am:\c!list:\currentmenu\endcsname\csname\??am:\c!list:\currentmenu\endcsname\fi} + +%D Setup menus: + +\unexpanded\def\setupinteractionmenu + {\dodoubleargument\dosetupinteractionmenu} + +\def\dosetupinteractionmenu[#1][#2]% + {\def\docommand##1{\getparameters[\??am##1][#2]}% + \processcommalist[#1]\docommand} + +\unexpanded\def\setupinteractionmenus[#1]% + {\getparameters[\??am][#1]} + +%D Fill menus: + +\normalexpanded{\long\def\expandafter\noexpand\csname\e!start\v!interactionmenu\endcsname[#1]#2\expandafter\noexpand\csname\e!stop\v!interactionmenu\endcsname}% + {\long\setmenuparameter{#1}\c!menu{\dointeractionmenu{#1}{#2}}} + +\def\resetinteractionmenu[#1]% + {\letmenuparameter{#1}\c!menu\empty} + +%D Check if menus permitted: + +\newif\iflocationmenupermitted + +\def\testinteractionmenu + {\iflocation + \doifelse\@@iamenu\v!on + {\doifelse{\menuparameter\c!state}\v!start + {\global\locationmenupermittedtrue} + {\global\locationmenupermittedfalse}} + {\global\locationmenupermittedfalse}% + \else + \global\locationmenupermittedfalse + \fi} + +%D Placement of menus: + +\def\interactionmenus[#1]% location + {\iflocation + \csname\??am:\c!menu:#1\endcsname + \fi} + +% \unexpanded\def\defineinteractionmenuclass +% {\dodoubleargument\dodefineinteractionmenuclass} +% +% \def\dodefineinteractionmenuclass[#1][#2]% tag hori|veri +% {\doifelse{#2}\v!vertical +% {\setvalue{\??am:\c!menu:#1}{\verticalinteractionmenu {#1}{\getvalue{\??am#1\c!width }}}} +% {\setvalue{\??am:\c!menu:#1}{\horizontalinteractionmenu{#1}{\getvalue{\??am#1\c!height}}}}} +% +% \defineinteractionmenuclass[\v!left ][\v!horizontal] +% \defineinteractionmenuclass[\v!right ][\v!horizontal] +% \defineinteractionmenuclass[\v!top ][\v!vertical] +% \defineinteractionmenuclass[\v!bottom][\v!vertical] + +\setvalue{\??am:\c!menu :\v!left }{\horizontalinteractionmenu\v!left \leftedgewidth } +\setvalue{\??am:\c!menu :\v!right }{\horizontalinteractionmenu\v!right \rightedgewidth} +\setvalue{\??am:\c!menu :\v!top }{\verticalinteractionmenu \v!top \topheight } +\setvalue{\??am:\c!menu :\v!bottom}{\verticalinteractionmenu \v!bottom\bottomheight } + +\setvalue{\??am:\c!command:\v!right }{\@@amvbox{}\rightedgewidth} +\setvalue{\??am:\c!command:\v!left }{\@@amvbox{}\leftedgewidth } +\setvalue{\??am:\c!command:\v!top }{\@@amhbox{}\topheight } +\setvalue{\??am:\c!command:\v!bottom}{\@@amhbox{}\bottomheight } + +\def\dointeractionmenu#1#2% + {\edef\currentmenu{#1}% + \getvalue{\??am:\c!command:\menuparameter\c!location}\currentmenu{#2}} + +\unexpanded\def\interactionmenu[#1]% + {\def\currentmenu{#1}% + \menuparameter\c!menu} + +\newdimen \intermenudistance +\newdimen \finalmenuwidth +\newdimen \finalmenuheight + +\newcounter\currentamposition % better \currentmenuposition +\newtoks \everysetmenucommands + +\def\horizontalinteractionmenu#1#2% location vhsize before/after + {\ifdim#2>\zeropoint + \edef\currentmenu{#1}% + \finalmenuwidth#2\relax + \horizontalinteractionmenuindeed + \fi} + +\def\verticalinteractionmenu#1#2% + {\ifdim#2>\zeropoint + \edef\currentmenu{#1}% + \finalmenuheight#2\relax + \verticalinteractionmenuindeed + \fi} + +\def\horizontalinteractionmenuindeed + {\global\intermenudistance\zeropoint + \setbox\scratchbox\hbox + {\processcommacommand[\currentmenulist]\somehorizontalinteractionmenu}% + \wd\scratchbox\finalmenuwidth\relax + \box\scratchbox} + +\def\verticalinteractionmenuindeed + {\global\intermenudistance\zeropoint + \setbox\scratchbox\vbox + {\processcommacommand[\currentmenulist]\someverticalinteractionmenu}% + \ht\scratchbox\finalmenuheight + \dp\scratchbox\zeropoint + \box\scratchbox} + +\def\somehorizontalinteractionmenu#1% + {\begingroup + \edef\currentmenu{#1}% + \doifnot{\menuparameter\c!state}\v!none + {\hskip\intermenudistance + \setbox\scratchbox\hbox to \finalmenuwidth + {\menuparameter\c!left + \interactionmenu[#1]% + \menuparameter\c!right}% + \doifelse{\menuparameter\c!distance}\v!overlay + {\global\intermenudistance\zeropoint + \wd\scratchbox\zeropoint}% + {\global\intermenudistance\menuparameter\c!distance}% + \box\scratchbox}% + \endgroup} + +\def\someverticalinteractionmenu#1% + {\begingroup + \edef\currentmenu{#1}% + \doifnot{\menuparameter\c!state}\v!none + {\vskip\intermenudistance + \setbox\scratchbox\vbox to \finalmenuheight + {\menuparameter\c!before + \interactionmenu[#1]% + \menuparameter\c!after}% + \doifelse{\menuparameter\c!distance}\v!overlay + {\global\intermenudistance\zeropoint + \offinterlineskip + \dp\scratchbox\zeropoint + \ht\scratchbox\zeropoint}% + {\global\intermenudistance\menuparameter\c!distance}% + \box\scratchbox}% + \endgroup} + +% don't change skipping, this one works! \showcomposition removed + +\def\@@amhbox#1#2#3#4% #1 obsolete, #3 is redundant + {\edef\currentmenu{#3}% + \testinteractionmenu + \iflocationmenupermitted + \begingroup + \forgetall + \scratchdimen\dimexpr\makeupwidth+\pagebackgroundhoffset*2-\menuparameter\c!leftoffset-\menuparameter\c!rightoffset\relax + \setbox\scratchbox\hbox to \scratchdimen + {\executeamboxcommands{#3}{#4}\c!left\c!middle\c!right}% + \setbox\scratchbox\hbox{\dowholemenuposition{#3}{\box\scratchbox}}% cannot happen in previous due to align + \wd\scratchbox\makeupwidth % geen \ht=#2 setting (yet) + \hskip\dimexpr-\pagebackgroundhoffset+\menuparameter\c!leftoffset\relax + \box\scratchbox + \endgroup + \fi} + +\def\@@amvbox#1#2#3#4% #1 obsolete, #3 is redundant + {\edef\currentmenu{#3}% + \testinteractionmenu + \iflocationmenupermitted + \bgroup + \forgetall + \scratchdimen\dimexpr\textheight+\pagebackgroundvoffset*2+\pagebackgrounddepth-\menuparameter\c!topoffset-\menuparameter\c!bottomoffset\relax + \setbox\scratchbox\vbox to \scratchdimen + {\restorestandardblank % todo: vspacing + \hsize#2\relax + \executeamboxcommands{#3}{#4}\c!before\c!inbetween\c!after}% + % strange: when we mnake this a hbox the content disappears + \setbox\scratchbox\vbox{\dowholemenuposition{#3}{\box\scratchbox}}% cannot happen in previous due to align + \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 + \fi} + +\def\executeamboxcommands#1#2#3#4#5% + {\begingroup + \edef\currentmenu{#1}% + \menuparameter#3\relax + \setamboxcommands{#1}{#4}% + \ignorespaces#2\unskip + \menuparameter#5\relax + \endgroup} + +\def\setamboxcommands#1#2% + {\edef\currentmenu{#1}% + \edef\betweenmenu{#2}% + \doglobal\newcounter\currentamposition + \the\everysetmenucommands} + +\def\addsomemenuitem#1% + {\dontleavehmode + \begingroup + \ignorespaces#1\unskip\relax + \ifconditional\skippedmenuitem \else + \menuparameter\betweenmenu + \fi + \endgroup + \ignorespaces} + +%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! + {\begingroup + \edef\currentmenu{#3}% + \iflocationmenupermitted + \executeamboxcommands{#3}{#4}\c!before\c!inbetween\c!after + \fi + \endgroup} + +\def\includemenu[#1]% + {\begingroup + \edef\currentmenu{#1}% + \doif{\menuparameter\c!state}\v!local + {\letmenuparameter\currentmenu\c!state\v!start + \let\@@amvbox\local@@ambox + \let\@@amhbox\local@@ambox + \menuparameter\c!menu}% + \endgroup} + +%D The menu commands: + +% ja : kader/achtergrond met tekst +% leeg : kader/achtergrond maar geen tekst +% nee : alleen ruimte reserveren +% geen : helemaal weglaten + +\newconditional\skippedmenuitem +\newconditional\usemenuclick + +\def\dosetlocationboxcontent#1[#2]#3[#4]% to be checked + {\global\setfalse\skippedmenuitem + \setbox\locationbox\hbox{\localframed[#1][#2]{#3}}% + \ifconditional\usemenuclick + \gotobox{\box\locationbox}[#4]% + \else + \box\locationbox + \fi} + +\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\settrue\skippedmenuitem} + +% make two sub macros + +% \dosetfontattribute {#1}{#2}% +% \dosetcolorattribute{#1}{#3}% + +\def\setlocationboxyes#1[#2]#3[#4]% needs to be split as the attr is not applicable to the box + {\begingroup + \settrue\usemenuclick + \global\setfalse\skippedmenuitem + \attribute\referenceattribute\attributeunsetvalue + \doifreferencefoundelse{#4} + {\analyzecurrentreference % we need to act on the state + \ifcase\referencepagestate + % something else than a page reference + \ctxlua{jobreferences.injectcurrentset(nil,nil)}% + \hbox attr \referenceattribute \lastreferenceattribute {\localframed[#1][#2]{#3}}% + \else\ifcase\csname\??am:\c!location:\menuparameter\c!samepage\endcsname\relax + % yes: same page or not ... todo + \ctxlua{jobreferences.injectcurrentset(nil,nil)}% + \ifnum\referencepagestate=\plusone % same page + \hbox attr \referenceattribute \lastreferenceattribute {\localframed[#1][#2,\c!color=\menuparameter\c!contrastcolor]{#3}}% + \else % elsewhere + \hbox attr \referenceattribute \lastreferenceattribute {\localframed[#1][#2]{#3}}% + \fi + \or + % empty but frame: no click + \localframed[#1][\c!empty=\v!yes,#2]{#3}% + \or + % empty no frame: no + \localframed[#1][\c!empty=\v!yes,\c!frame=,\c!background=,#2]{#3}% + \or + % nothing at all + \global\settrue\skippedmenuitem + \fi\fi}% + {\unknownreference{#4}% + \ifcase\csname\??am:\c!location:\menuparameter\c!unknownreference\endcsname\relax + \localframed[#1][#2]{#3}% + \or + \localframed[#1][\c!empty=\v!yes,#2]{#3}% + \or + \localframed[#1][\c!empty=\v!yes,\c!frame=,\c!background=,#2]{#1}% + \or + \global\skippedmenuitemtrue + \fi}% + \endgroup} + +\def\setlocationboxraw#1[#2]#3[#4]% + {\localframed[#1][#2]{#3}} + +\def\setlocationnop#1[#2]#3% + {\localframed[#1][#2]{#3}} + +\def\menu@raw[#1]#2\\% + {\addsomemenuitem{\gotobox{\ignorespaces#2\unskip}[#1]}} + +\def\menu@but[#1]#2\\% + {\addsomemenuitem{\domenuitemposition\currentmenu{#1}{\setlocationboxyes{\??am\currentmenu}[]{\ignorespaces#2\unskip}[#1]}}} + +\def\menu@got[#1]#2\\% + {\addsomemenuitem{\setlocationboxyes{\??am\currentmenu}[\c!frame=\v!off,\c!background=]{\ignorespaces#2\unskip}[#1]}} + +\def\menu@nop#1\\% + {\addsomemenuitem{\setlocationboxraw{\??am\currentmenu}[\c!frame=\v!off,\c!background=,\c!empty=\v!yes]{\ignorespaces#1\unskip}[]}} + +\def\menu@txt#1\\% + {\addsomemenuitem{\localframed[\??am\currentmenu][\c!frame=\v!off,\c!background=]{\ignorespaces#1\unskip}}} + +\def\menu@rul#1\\% + {\addsomemenuitem{\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 + +\ifdefined\domenuitemposition \else \let\domenuitemposition \gobbletwoarguments \fi +\ifdefined\dowholemenuposition \else \let\dowholemenuposition\gobbleoneargument \fi + +%D We also need an explicit position control some day. I'll +%D do that when I need it. [The stacking order.] + +% [name] [location] +% [name] [location] [pars] + +\expandafter\chardef\csname\??am:\c!location:\v!yes \endcsname\zerocount +\expandafter\chardef\csname\??am:\c!location:\v!empty \endcsname\plusone +\expandafter\chardef\csname\??am:\c!location:\v!no \endcsname\plustwo +\expandafter\chardef\csname\??am:\c!location:\v!none \endcsname\plusthree + +\expandafter\chardef\csname\??am:\c!location:\v!normal \endcsname\plusone % default +\expandafter\chardef\csname\??am:\c!location:\s!default\endcsname\plusone % default +\expandafter\chardef\csname\??am:\c!location:\s!empty \endcsname\plusone % default + +\def\dodomenulistelement#1#2#3#4#5#6#7% + {\addsomemenuitem{\domenuitemposition\currentmenu{internal(#3)}% + {\setlocationboxyes{\??am\currentmenu}[]{\limitatetext{#5}{\namedlistparameter{#2}\c!maxwidth}{\unknown}}[internal(#3)]}}} + +\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]{\setlocationboxyes\??bt[]{#3}[#4]} % normal button, no parameters +\def\domenubuttonB[#1][#2]#3[#4]{\setlocationboxyes{\??am#1}[#2]{#3}[#4]} % menu button, with parameters +\def\domenubuttonC[#1][#2]#3[#4]{\setlocationboxyes\??bt[#1]{#3}[#4]} % normal button, with parameters +\def\domenubuttonD[#1][#2]#3[#4]{\setlocationboxyes{\??am#1}[]{#3}[#4]} % menu button, no parameters + +\def\menubox + {\dodoubleempty\domenubox} + +\def\domenubox[#1][#2]#3% + {\bgroup + \let\setlocationboxyes\setlocationboxraw + \domenubutton[#1][#2]#3[]% + \egroup} + +% 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} + +\defineinteractionmenu [\v!vertical] % we happen to know that this works out ok (just a setup set) +\defineinteractionmenu [\v!horizontal] % we happen to know that this works out ok (just a setup set) + +\defineinteractionmenu [\v!right ] [\v!right ] [\v!vertical ] % we share a setup set +\defineinteractionmenu [\v!left ] [\v!left ] [\v!vertical ] % we share a setup set +\defineinteractionmenu [\v!top ] [\v!top ] [\v!horizontal] % we share a setup set +\defineinteractionmenu [\v!bottom] [\v!bottom] [\v!horizontal] % we share a setup set + +\setupinteractionmenus + [\c!offset=.25em, + \c!position=\v!no, + \c!frame=\v!on, + \c!background=, + \c!backgroundcolor=, + \c!foregroundstyle=\menuparameter\c!style, + \c!foregroundcolor=\menuparameter\c!color, + \c!style=\@@iastyle, + \c!color=\@@iacolor, + \c!contrastcolor=\@@iacontrastcolor, + \c!state=\v!start, + \c!samepage=\v!yes, + \c!unknownreference=\v!empty, + \c!distance=\bodyfontsize, % 12pt + \c!topoffset=\zeropoint, + \c!bottomoffset=\zeropoint, + \c!leftoffset=\zeropoint, + \c!rightoffset=\zeropoint] + +\setupinteractionmenu + [\v!vertical] % not really a menu + [\c!before=, + \c!after=\vfil, + \c!inbetween=\blank, + \c!left=\hss, + \c!right=\hss, + \c!height=\v!broad] + +\setupinteractionmenu + [\v!horizontal] % not really a menu + [\c!before=\vss, + \c!after=\vss, + \c!middle=\hfil, + \c!width=\v!fit, + \c!height=\v!broad] + +\setupinteractionmenu[\v!left ][\c!width=\leftedgewidth ] +\setupinteractionmenu[\v!right ][\c!width=\rightedgewidth] +% \setupinteractionmenu[\v!top ] [\c!height=\topheight ] +% \setupinteractionmenu[\v!bottom] [\c!height=\bottomheight ] + +\unexpanded\def\placeleftedgetextblock % Is \hss/\hsize really needed here? (check outer level and settings) + {\hbox to \leftedgewidth{\hsize\leftedgewidth\hss\interactionmenus[\v!left]}} + +\unexpanded\def\placerightedgetextblock % Is \hss/\hsize really needed here? (check outer level and settings) + {\hbox to \rightedgewidth{\hsize\rightedgewidth\interactionmenus[\v!right]\hss}} + +\unexpanded\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}} + +\unexpanded\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}} + +\ifdefined\leftedgetextcontent + + \appendtoks \iflocation\placeleftedgetextblock \hskip-\leftedgewidth \fi\to \leftedgetextcontent + \appendtoks \iflocation\placerightedgetextblock \hskip-\rightedgewidth \fi\to \rightedgetextcontent + \appendtoks \iflocation\placetoptextblock \vskip-\topheight \fi\to \toptextcontent + \appendtoks \iflocation\placebottomtextblock \vskip-\bottomheight \fi\to \bottomtextcontent + +\fi + +%D Enable and disable menus \unknown\ obsolete: + +\def\gobbletwoparameters[#1][#2]{} + +\def\disableinteractionmenu{\dodoubleempty\gobbletwoparameters} +\def\enableinteractionmenu {\dodoubleempty\gobbletwoparameters} + +\protect \endinput diff --git a/tex/context/base/scrn-nav.mkii b/tex/context/base/scrn-nav.mkii new file mode 100644 index 000000000..591d4134c --- /dev/null +++ b/tex/context/base/scrn-nav.mkii @@ -0,0 +1,379 @@ +%D \module +%D [ file=scrn-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 Screen 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/scrn-nav.mkiv b/tex/context/base/scrn-nav.mkiv new file mode 100644 index 000000000..264e3ded2 --- /dev/null +++ b/tex/context/base/scrn-nav.mkiv @@ -0,0 +1,256 @@ +%D \module +%D [ file=scrn-nav, +%D version=1998.01.15, +%D title=\CONTEXT\ Screen 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 Screen 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 The current support in \MKIV\ is mostly the same as in +%D \MKII\ and the old files have some more detailed +%D (sometimes historic) information. + +%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} + +% use with care, no checking done + +\def\setinteractionparameter#1#2% + {\expandafter\def\csname\??ia#1\endcsname{#2}} + +\def\resetinteractionparameter#1% + {\expandafter\let\csname\??ia#1\endcsname\empty} + +\newtoks\everysetupinteraction + +\unexpanded\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 + \doifsomething\@@iacalculate + {\doregistercalculationset\@@iacalculate}% + \doifelse\@@iastrut \v!yes \settrue \setfalse \uselocationstrut + \doifelse\@@iaclick \v!yes \settrue \setfalse \highlighthyperlinks + \doifelse\@@iadisplay\v!new \settrue \setfalse \gotonewwindow + \doifelse\@@iapage \v!yes \settrue \setfalse \usepagedestinations +\to \everysetupinteraction + +\def\synchronizebackendidentity + {\ctxlua{backends.codeinjections.setupidentity{ + title = \!!bs\@@iatitle\!!es, + subject = \!!bs\@@iasubtitle\!!es, + author = \!!bs\@@iaauthor\!!es, + creator = \!!bs ConTeXt - \contextversion\!!es, + date = \!!bs\@@iadate\!!es, + keywords = \!!bs\@@iakeyword\!!es, + }}} + +\appendtoks + \synchronizebackendidentity +\to \everyfirstshipout + +%D We have to make sure of some settings: + +\def\dolocationstartup + {\iflocation + \donefalse + \ifx\@@iaopenaction\empty \else \donetrue + \ctxlua{jobreferences.checkopendocumentactions("\@@iaopenaction")}% + \ctxlua{jobreferences.expandcurrent()}% + \fi + \ifx\@@iacloseaction\empty \else \donetrue + \ctxlua{jobreferences.checkclosedocumentactions("\@@iacloseaction")}% + \ctxlua{jobreferences.expandcurrent()}% + \fi + \ifdone + \ctxlua{jobreferences.flushdocumentactions()}% + \fi + \global\let\dolocationstartup\relax + \fi} + +\def\dolocationpagecheck + {\iflocation + \donefalse + \ifx\@@iaopenpageaction\empty \else \donetrue + \ctxlua{jobreferences.checkopenpageactions("\@@iaopenpageaction")}% + \ctxlua{jobreferences.expandcurrent()}% + \fi + \ifx\@@iaclosepageaction\empty \else \donetrue + \ctxlua{jobreferences.checkclosepageactions("\@@iaclosepageaction")}% + \ctxlua{jobreferences.expandcurrent()}% + \fi + \ifdone + \ctxlua{jobreferences.flushpageactions()}% + \fi + \fi} + +\appendtoks \dolocationstartup \to \everyshipout +\appendtoks \dolocationpagecheck \to \everyshipout + +%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. + +%D When we're dealing with pure page references, contrast +%D colors are used when we are already at the page mentioned. + +\def\setlocationcolor#1% not grouped ! + {\ifnum\referencepagestate=\plusone + \edef\askedcontrastcolor{\csname#1\c!contrastcolor\endcsname}% + \ifx\askedcontrastcolor\empty + \dosetcolorattribute{#1}\c!color + \else + \dosetcolorattribute{#1}\c!contrastcolor + \fi + \else % we could just set and if > 0 set again + \dosetcolorattribute{#1}\c!color + \fi} + +\def\setlocationfont#1% + {\dosetfontattribute{#1}\c!style} + +\def\setlocationattributes#1% + {\ifnum\referencepagestate=\plusone + \edef\askedcontrastcolor{\csname#1\c!contrastcolor\endcsname}% + \ifx\askedcontrastcolor\empty + \dosetcolorattribute{#1}\c!color + \else + \dosetcolorattribute{#1}\c!contrastcolor + \fi + \else % we could just set and if > 0 set again + \dosetcolorattribute{#1}\c!color + \fi + \dosetfontattribute{#1}\c!style} + +\def\setlocationcolorspec#1% \resolver + {\ifnum\referencepagestate=\plusone + \edef\askedcontrastcolor{#1\c!contrastcolor}% + \ifx\askedcontrastcolor\empty + \doactivatecolor{#1\c!color}% + \else + \doactivatecolor\askedcontrastcolor + \fi + \else + \doactivatecolor{#1\c!color}% + \fi} + +%D delayed ... + +\def\enableinteractivereferences + {\ifproductionrun + \ctxlua{jobreferences.enable_interaction()}% + \globallet\enableinteractivereferences\relax + \fi} + +\appendtoks + \enableinteractivereferences +\to \everysetupinteraction + +%D More tokens are spend when we want both typeface and color +%D highlighting. + +\def\@@iatimestamp + {\the\normalyear + \ifnum\normalmonth<10 0\fi\the\normalmonth + \ifnum\normalday <10 0\fi\the\normalday} + +\setupinteraction % start fit page and reset form + [\c!state=\v!stop, + \c!page=\v!no, + \c!click=\v!yes, + \c!display=, + \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] + +%D XMP support: + +\setupinteraction + [xmpfile=] + +\appendtoks + % this will move as it is a backend issue + \doifsomething\@@iaxmpfile + {\ctxlua{if lpdf then lpdf.setxmpfile("\@@iaxmpfile") end}% + \globallet\@@iaxmpfile\empty}% +\to \everysetupinteraction + +\protect \endinput diff --git a/tex/context/base/scrp-cjk.lua b/tex/context/base/scrp-cjk.lua new file mode 100644 index 000000000..997baaa96 --- /dev/null +++ b/tex/context/base/scrp-cjk.lua @@ -0,0 +1,577 @@ +if not modules then modules = { } end modules ['scrp-cjk'] = { + version = 1.001, + comment = "companion to scrp-ini.mkiv", + 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.identifiers +local quaddata = fonts.quads + +-- 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 quad = quaddata[font] + 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 = stretch_break, -- 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 = stretch_break, -- 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..b28c297d0 --- /dev/null +++ b/tex/context/base/scrp-ini.lua @@ -0,0 +1,388 @@ +if not modules then modules = { } end modules ['scrp-ini'] = { + version = 1.001, + comment = "companion to scrp-ini.mkiv", + 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 +-- +-- one of the time consuming functiions: + +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.mkiv b/tex/context/base/scrp-ini.mkiv new file mode 100644 index 000000000..6e6b10610 --- /dev/null +++ b/tex/context/base/scrp-ini.mkiv @@ -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] \chardef\preprocattribute \dogetattributeid{preproc} +\definesystemattribute[prestat] \chardef\prestatattribute \dogetattributeid{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 + +\unexpanded\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}}} + +\unexpanded\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 + \attribute\preprocattribute\attributeunsetvalue + \else + \attribute\preprocattribute\currentscriptattribute\relax % we can speed this up by storing the attribute in ??ls:a:#1 + \fi} + +\def\setscript [#1]{\dosetscript{#1}} +\unexpanded\def\startscript[#1]{\begingroup\dosetscript{#1}} +\unexpanded\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 new file mode 100644 index 000000000..10dc31b14 --- /dev/null +++ b/tex/context/base/sort-def.mkii @@ -0,0 +1,450 @@ +%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-ini.lua b/tex/context/base/sort-ini.lua new file mode 100644 index 000000000..b745c9aa5 --- /dev/null +++ b/tex/context/base/sort-ini.lua @@ -0,0 +1,317 @@ +if not modules then modules = { } end modules ['sort-ini'] = { + version = 1.001, + comment = "companion to sort-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- It took a while to get there, but with Fleetwood Mac's "Don't Stop" +-- playing in the background we sort of got it done. + +-- todo: cleanup splits (in other modules) + +local utf = unicode.utf8 +local gsub, rep, sort, concat = string.gsub, string.rep, table.sort, table.concat +local utfbyte, utfchar = utf.byte, utf.char +local utfcharacters, utfvalues, strcharacters = string.utfcharacters, string.utfvalues, string.characters +local chardata = characters.data +local next, type, tonumber = next, type, tonumber + +local trace_tests = false trackers.register("sorters.tests", function(v) trace_tests = v end) + +sorters = { } +sorters.comparers = { } +sorters.splitters = { } +sorters.entries = { } +sorters.mappings = { } +sorters.replacements = { } + +sorters.ignored_offset = 0x10000 +sorters.replacement_offset = 0x10000 +sorters.digits_offset = 0x20000 +sorters.digits_maximum = 0xFFFFF + +local ignored_offset = sorters.ignored_offset +local digits_offset = sorters.digits_offset +local digits_maximum = sorters.digits_maximum + +local mappings = sorters.mappings +local entries = sorters.entries +local replacements = sorters.replacements + +local language, defaultlanguage, dummy = 'en', 'en', { } + +local currentreplacements, currentmappings, currententries + +function sorters.setlanguage(lang) + language = lang or language or defaultlanguage + currentreplacements = replacements[language] or replacements[defaultlanguage] or dummy + currentmappings = mappings [language] or mappings [defaultlanguage] or dummy + currententries = entries [language] or entries [defaultlanguage] or dummy + return currentreplacements, currentmappings, currententries +end + +sorters.setlanguage() + +-- maybe inline code if it's too slow + +local function basicsort(sort_a,sort_b) + if not sort_a or not sort_b then + return 0 + elseif #sort_a > #sort_b then + if #sort_b == 0 then + return 1 + else + for i=1,#sort_b do + local ai, bi = sort_a[i], sort_b[i] + if ai > bi then + return 1 + elseif ai < bi then + return -1 + end + end + return 1 + end + elseif #sort_a < #sort_b then + if #sort_a == 0 then + return -1 + else + for i=1,#sort_a do + local ai, bi = sort_a[i], sort_b[i] + if ai > bi then + return 1 + elseif ai < bi then + return -1 + end + end + return -1 + end + elseif #sort_a == 0 then + return 0 + else + for i=1,#sort_a do + local ai, bi = sort_a[i], sort_b[i] + if ai > bi then + return 1 + elseif ai < bi then + return -1 + end + end + return 0 + end +end + +function sorters.comparers.basic(a,b) + local ea, eb = a.split, b.split + local na, nb = #ea, #eb + if na == 0 and nb == 0 then + -- simple variant (single word) + local result = basicsort(ea.e,eb.e) + return result == 0 and result or basicsort(ea.m,eb.m) + else + -- complex variant, used in register (multiple words) + local result = 0 + for i=1,nb < na and nb or na do + local eai, ebi = ea[i], eb[i] + result = basicsort(eai.e,ebi.e) + if result == 0 then + result = basicsort(eai.m,ebi.m) -- only needed it there are m's + end + if result ~= 0 then + break + end + end + if result ~= 0 then + return result + elseif na > nb then + return 1 + elseif nb > na then + return -1 + else + return 0 + end + end +end + +local function numify(s) + return rep(" ",10-#s) .. s -- or format with padd +end + +local function numify(s) + s = digits_offset + tonumber(s) + if s > digits_maximum then + s = digits_maximum + end + return utfchar(s) +end + +function sorters.strip(str) -- todo: only letters and such utf.gsub("([^%w%d])","") + if str then + str = gsub(str,"\\%S*","") + str = gsub(str,"[%s%[%](){}%$\"\']*","") + str = gsub(str,"(%d+)",numify) -- sort numbers properly + return str + else + return "" + end +end + +local function firstofsplit(entry) + -- numbers are left padded by spaces + local split = entry.split + if #split > 0 then + split = split[1].s + else + split = split.s + end + local entry = split and split[1] or "" + return entry, currententries[entry] or "\000" +end + +sorters.firstofsplit = firstofsplit + +-- beware, numbers get spaces in front + +function sorters.splitters.utf(str) + if #currentreplacements > 0 then + for k=1,#currentreplacements do + local v = currentreplacements[k] + str = gsub(str,v[1],v[2]) + end + end + local s, e, m, n = { }, { }, { }, 0 + for sc in utfcharacters(str) do -- maybe an lpeg + local ec, mc = currententries[sc], currentmappings[sc] or utfbyte(sc) + n = n + 1 + s[n] = sc + e[n] = currentmappings[ec] or mc + m[n] = mc + end + return { s = s, e = e, m = m } +end + +-- we can use one array instead (sort of like in mkii) +-- but for the moment we do it this way as it is more +-- handy for tracing + +-- function sorters.splitters.utf(str) +-- if #currentreplacements > 0 then +-- for k=1,#currentreplacements do +-- local v = currentreplacements[k] +-- str = gsub(str,v[1],v[2]) +-- end +-- end +-- local s, e, m, n = { }, { }, { }, 0 +-- for sc in utfcharacters(str) do -- maybe an lpeg +-- local ec, mc = currententries[sc], currentmappings[sc] or utfbyte(sc) +-- n = n + 1 +-- ec = currentmappings[ec] or mc +-- s[n] = sc +-- e[n] = ec +-- if ec ~= mc then +-- n = n + 1 +-- e[n] = mc +-- end +-- end +-- return { s = s, e = e } +-- end + +function table.remap(t) + local tt = { } + for k,v in next, t do + tt[v] = k + end + return tt +end + +local function pack(entry) + local t = { } + local split = entry.split + if #split > 0 then + for i=1,#split do + local tt, li = { }, split[i].s + for j=1,#li do + local lij = li[j] + tt[j] = utfbyte(lij) > ignored_offset and "[]" or lij + end + t[i] = concat(tt) + end + return concat(t," + ") + else + local t, li = { }, split.s + for j=1,#li do + local lij = li[j] + t[j] = utfbyte(lij) > ignored_offset and "[]" or lij + end + return concat(t) + end +end + +function sorters.sort(entries,cmp) + if trace_tests then + sort(entries,function(a,b) + local r = cmp(a,b) + logs.report("sorter","%s %s %s",pack(a),(not r and "?") or (r<0 and "<") or (r>0 and ">") or "=",pack(b)) + return r == -1 + end) + local s + for i=1,#entries do + local entry = entries[i] + local letter, first = firstofsplit(entry) + if first == s then + first = " " + else + s = first + logs.report("sorter",">> %s 0x%05X (%s 0x%05X)",first,utfbyte(first),letter,utfbyte(letter)) + end + logs.report("sorter"," %s",pack(entry)) + end + else + sort(entries,function(a,b) + return cmp(a,b) == -1 + end) + end +end + +-- some day we can have a characters.upper and characters.lower + +function sorters.add_uppercase_replacements(what) + local rep, new = replacements[what], { } + for i=1,#rep do + local r = rep[i] + local u = chardata[utfbyte(r[1])].uccode + if u then + new[utfchar(u)] = r[2] + end + end + for k, v in next, new do + rep[k] = v + end +end + +function sorters.add_uppercase_entries(what) + local ent, new = entries[what], { } + for k, v in next, ent do + local u = chardata[utfbyte(k)].uccode + if u then + new[utfchar(u)] = v + end + end + for k, v in next, new do + ent[k] = v + end +end + +function sorters.add_uppercase_mappings(what,offset) + local map, new, offset = mappings[what], { }, offset or 0 + for k, v in next, map do + local u = chardata[utfbyte(k)].uccode + if u then + new[utfchar(u)] = v + offset + end + end + for k, v in next, new do + map[k] = v + end +end diff --git a/tex/context/base/sort-ini.mkii b/tex/context/base/sort-ini.mkii new file mode 100644 index 000000000..f1ed1c316 --- /dev/null +++ b/tex/context/base/sort-ini.mkii @@ -0,0 +1,161 @@ +%D \module +%D [ file=sort-ini, +%D version=2005.08.08, +%D title=\CONTEXT\ Sorting 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. + +% todo: autokeyexpansion => igv utf: \setupregister[index][keyexpansion=yes] + +%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 / 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 +%D of texutil but i've changed the interface a bit. It all boils down to +%D a bunch of substitutions. The reimplementation makes it easier to extend +%D the rules. Currently we have multipass substitution and onepass sorting, +%D but we may change this some day. Since there is a plugin mechanism, using +%D an external sorter is also possible. + +% test file: +% +% \mainlanguage[sl] \readfile{sort-ini}{}{} +% +% \starttext +% test \index {aa1} test \index {ab1} test \index {aa2} +% test \index {ab2} test \index {aa10} test \index {aa8} +% test \index {aa9} test \index {aa11} test \index {aa10} +% test \index {cccc} test \index {\ccaron ccc} test \index {\cacute ccc} +% test \index {caaa} test \index {\ccaron aaa} test \index {\cacute aaa} +% \placeindex +% \stoptext + +% definitions: +% +% \exportsortshortcut{\\\'\\i}{iacute} +% \exportsortshortcut{\\\'i} {iacute} +% \exportsortshortcut{\\\"e} {ediaeresis} +% \exportsortshortcut{\\\'o} {oacute} +% +% \exportsortexpansion{aeligature}{ae} +% \exportsortexpansion{ijligature}{y} +% \exportsortexpansion{oacute} {oz} +% \exportsortexpansion{eacute} {ezzz} % or e3 +% \exportsortexpansion{egrave} {ezz} % or e2 +% \exportsortexpansion{ediaeresis}{ez} % or e1 +% \exportsortexpansion{adiaeresis}{az} +% \exportsortreduction{ch} {c} +% \exportsortreduction{ij} {y} +% +% \exportsortexpansion{ccaron} {cz} +% \exportsortexpansion{cacute} {czz} +% \exportsortexpansion{dstroke} {dz} +% \exportsortexpansion{scaron} {sz} +% \exportsortexpansion{zcaron} {zz} +% +% \exportsortreduction{ch}{c} +% \exportsortreduction{ij}{y} +% +% \exportsortexpansion {ccaron} {c+1} +% \exportsortdivision {c+1} {ccaron} +% == +% \exportsortrule {ccaron} {c+1} + +\unprotect + +\def\savesortkeys + {\ifproductionrun + \the\everysavesortkeys + \global\everysavesortkeys\emptytoks + \fi} + +\appendtoks \savesortkeys \to \everyshipout + +\let\currentexportclass\empty + +\def\exportsortaction#1#2#3% + {\defconvertedargument\asciia{#2}% + \defconvertedargument\asciib{#3}% + \immediatewriteutility{x #1 {\currentexportclass} {\asciia} {\asciib}}} + +\def\exportsortshortcut {\exportsortaction s} +\def\exportsortexpansion{\exportsortaction e} +\def\exportsortreduction{\exportsortaction r} +\def\exportsortdivision {\exportsortaction d} + +\def\exportsortrule#1#2% + {\exportsortexpansion{#1}{#2}% + \exportsortdivision {#2}{#1}} + +\def\exportutfsortexpansion#1#2#3% + {\bgroup + \edef\utfsorta{\string\unknownchar}% + \dostepwiserecurse{#2}{#3}\plusone + {\edef\utfsortb{\@EA\string\csname\doutfunihash{#1}{\recurselevel}\endcsname}% + \ifx\utfsortb\utfsorta \else + \edef\utfsortc{\numbertoutf{\numexpr#1*256+\recurselevel\relax}}% + \expanded{\exportsortshortcut{\utfsortc}{\utfsortb\space}}% space is really needed + \fi}% + \egroup} + +\def\savesortdefinitions + {\bgroup + \doifelse \currentregime {utf} + {\exportutfsortexpansion{0}{128}{255}% + \exportutfsortexpansion{1}{0}{255}} + {\def\defineactivecharacter##1 ##2% mkii code ! + {\doifnumberelse{##1} + {\expanded{\exportsortshortcut{\rawcharacter{##1}}}{##2}}% + {\expanded{\exportsortshortcut{\rawcharacter{\number`##1}}}{##2}}}% + \doifelsenothing\currentregime + {\doifnot\characterencoding\nocharacterencoding % to be sure, autoregime + {\dowalkregime\characterencoding}}% + {\dowalkregime\characterencoding}}% + \egroup + \startnointerference + \setcatcodetable\ctxcatcodes + \readsysfile{\f!sortprefix def.mkii}\donothing\donothing % default + \stopnointerference + \global\let\savesortdefinitions\relax} + +\def\savesortlanguage#1% language specifics + {\doifsomething{#1} + {\doifundefined{\f!sortprefix::#1}% + {\startnointerference + \global\letvalue{\f!sortprefix::#1}\empty + \def\currentexportclass{#1}% + \enablemode[sortorder-#1]% + \setcatcodetable\ctxcatcodes + \readsysfile{\f!sortprefix lan.mkii}\donothing\donothing + \stopnointerference}}} + +\prependtoks + \savesortdefinitions +\to \everysavesortkeys + +% \defineregister[one] +% \defineregister[two] \setupregister[two][language=cz] +% +% \starttext +% test \one{one} test \one{two} test \one {\aacute} test \one{alpha} test \one{chow} +% test \two{one} test \two{two} test \two {\aacute} test \two{alpha} test \two{chow} +% \blank[3*big] \placeregister[one] +% \blank[3*big] \placeregister[two] +% \stoptext + +\protect \endinput diff --git a/tex/context/base/sort-ini.mkiv b/tex/context/base/sort-ini.mkiv new file mode 100644 index 000000000..a4dc2f6ba --- /dev/null +++ b/tex/context/base/sort-ini.mkiv @@ -0,0 +1,19 @@ +%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. + +\writestatus{loading}{ConTeXt Sorting Macros / Initialization} + +\registerctxluafile{sort-ini}{1.001} +\registerctxluafile{sort-lan}{1.001} + +\endinput diff --git a/tex/context/base/sort-lan.lua b/tex/context/base/sort-lan.lua new file mode 100644 index 000000000..ed7e8ba35 --- /dev/null +++ b/tex/context/base/sort-lan.lua @@ -0,0 +1,319 @@ +if not modules then modules = { } end modules ['sort-lan'] = { + version = 1.001, + comment = "companion to sort-lan.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- this is a rather preliminary and incomplete file +-- maybe we should load this kind of stuff runtime + +-- replacements are indexed as they need to be applied in sequence + +local utf = unicode.utf8 +local uc = utf.char +local ub = utf.byte + +local mappings = sorters.mappings +local entries = sorters.entries +local replacements = sorters.replacements + +local add_uppercase_replacements = sorters.add_uppercase_replacements +local add_uppercase_entries = sorters.add_uppercase_entries +local add_uppercase_mappings = sorters.add_uppercase_mappings + +local replacement_offset = sorters.replacement_offset + +-- english + +entries['en'] = { + ["a"] = "a", ["b"] = "b", ["c"] = "c", ["d"] = "d", ["e"] = "e", + ["f"] = "f", ["g"] = "g", ["h"] = "h", ["i"] = "i", ["j"] = "j", + ["k"] = "k", ["l"] = "l", ["m"] = "m", ["n"] = "n", ["o"] = "o", + ["p"] = "p", ["q"] = "q", ["r"] = "r", ["s"] = "s", ["t"] = "t", + ["u"] = "u", ["v"] = "v", ["w"] = "w", ["x"] = "x", ["y"] = "y", + ["z"] = "z", + ["A"] = "a", ["B"] = "b", ["C"] = "c", ["D"] = "d", ["E"] = "e", + ["F"] = "f", ["G"] = "g", ["H"] = "h", ["I"] = "i", ["J"] = "j", + ["K"] = "k", ["L"] = "l", ["M"] = "m", ["N"] = "n", ["O"] = "o", + ["P"] = "p", ["Q"] = "q", ["R"] = "r", ["S"] = "s", ["T"] = "t", + ["U"] = "u", ["V"] = "v", ["W"] = "w", ["X"] = "x", ["Y"] = "y", + ["Z"] = "z", +} + +mappings['en'] = { + ["a"] = 1, ["b"] = 3, ["c"] = 5, ["d"] = 7, ["e"] = 9, + ["f"] = 11, ["g"] = 13, ["h"] = 15, ["i"] = 17, ["j"] = 19, + ["k"] = 21, ["l"] = 23, ["m"] = 25, ["n"] = 27, ["o"] = 29, + ["p"] = 31, ["q"] = 33, ["r"] = 35, ["s"] = 37, ["t"] = 39, + ["u"] = 41, ["v"] = 43, ["w"] = 45, ["x"] = 47, ["y"] = 49, + ["z"] = 51, + ["A"] = 1, ["B"] = 3, ["C"] = 5, ["D"] = 7, ["E"] = 9, + ["F"] = 11, ["G"] = 13, ["H"] = 15, ["I"] = 17, ["J"] = 19, + ["K"] = 21, ["L"] = 23, ["M"] = 25, ["N"] = 27, ["O"] = 29, + ["P"] = 31, ["Q"] = 33, ["R"] = 35, ["S"] = 37, ["T"] = 39, + ["U"] = 41, ["V"] = 43, ["W"] = 45, ["X"] = 47, ["Y"] = 49, + ["Z"] = 51, + -- + -- uppercase after lowercase + -- + -- ["A"] = 2, ["B"] = 4, ["C"] = 6, ["D"] = 8, ["E"] = 10, + -- ["F"] = 12, ["G"] = 14, ["H"] = 16, ["I"] = 18, ["J"] = 20, + -- ["K"] = 22, ["L"] = 24, ["M"] = 26, ["N"] = 28, ["O"] = 30, + -- ["P"] = 32, ["Q"] = 34, ["R"] = 36, ["S"] = 38, ["T"] = 40, + -- ["U"] = 42, ["V"] = 44, ["W"] = 46, ["X"] = 48, ["Y"] = 50, + -- ["Z"] = 52, +} + +-- dutch + +replacements['nl'] = { { "ij", 'y' }, { "IJ", 'Y' } } +entries ['nl'] = entries ['en'] +mappings ['nl'] = mappings['en'] + +-- czech + +local cz_ch = uc(replacement_offset + 1) +local cz_CH = uc(replacement_offset + 2) + +replacements['cz'] = { + [1] = { "ch", cz_ch } +} + +entries['cz'] = { + ['a'] = "a", -- a + [uc(0x00E1)] = "a", -- aacute + ['b'] = "b", -- b + ['c'] = "c", -- c + [uc(0x010D)] = uc(0x010D), -- ccaron + ['d'] = "d", -- d + [uc(0x010F)] = "d", -- dcaron + ['e'] = "e", -- e + [uc(0x00E9)] = "e", -- eacute + [uc(0x011B)] = "e", -- ecaron + ['f'] = "f", -- f + ['g'] = "g", -- g + ['h'] = "h", -- h + [cz_ch] = "ch", -- ch + ['i'] = "i", -- i + [uc(0x00ED)] = "i", -- iacute + ['j'] = "j", -- j + ['k'] = "k", -- k + ['l'] = "l", -- l + ['m'] = "m", -- m + ['n'] = "n", -- n + ['ň'] = "n", -- ncaron + ['o'] = "o", -- o + ['p'] = "p", -- p + ['q'] = "q", -- q + ['r'] = "r", -- r + ['ř'] = "ř", -- rcaron + ['s'] = "s", -- s + [uc(0x0161)] = uc(0x0161), -- scaron + ['t'] = "t", -- t + [uc(0x0165)] = "t", -- tcaron + ['u'] = "u", -- u + [uc(0x00FA)] = "u", -- uacute + [uc(0x016F)] = "u", -- uring + ['v'] = "v", -- v + ['w'] = "w", -- w + ['x'] = "x", -- x + ['y'] = "y", -- y + [uc(0x00FD)] = "y", -- yacute + ['z'] = "z", -- z + [uc(0x017E)] = uc(0x017E), -- zcaron +} + +mappings['cz'] = { + ['a'] = 1, -- a + [uc(0x00E1)] = 3, -- aacute + ['b'] = 5, -- b + ['c'] = 7, -- c + [uc(0x010D)] = 9, -- ccaron + ['d'] = 11, -- d + [uc(0x010F)] = 13, -- dcaron + ['e'] = 15, -- e + [uc(0x00E9)] = 17, -- eacute + [uc(0x011B)] = 19, -- ecaron + ['f'] = 21, -- f + ['g'] = 23, -- g + ['h'] = 25, -- h + [cz_ch] = 27, -- ch + ['i'] = 29, -- i + [uc(0x00ED)] = 31, -- iacute + ['j'] = 33, -- j + ['k'] = 35, -- k + ['l'] = 37, -- l + ['m'] = 39, -- m + ['n'] = 41, -- n + ['ň'] = 43, -- ncaron + ['o'] = 45, -- o + ['p'] = 47, -- p + ['q'] = 49, -- q + ['r'] = 51, -- r + ['ř'] = 53, -- rcaron + ['s'] = 55, -- s + [uc(0x0161)] = 57, -- scaron + ['t'] = 59, -- t + [uc(0x0165)] = 61, -- tcaron + ['u'] = 63, -- u + [uc(0x00FA)] = 65, -- uacute + [uc(0x016F)] = 67, -- uring + ['v'] = 69, -- v + ['w'] = 71, -- w + ['x'] = 73, -- x + ['y'] = 75, -- y + [uc(0x00FD)] = 77, -- yacute + ['z'] = 79, -- z + [uc(0x017E)] = 81, -- zcaron +} + +add_uppercase_entries ("cz") +add_uppercase_mappings("cz") -- 1 can be option (but then we need a runtime variant) + +entries ['cz'][cz_CH] = entries ['cz'][cz_ch] +mappings['cz'][cz_CH] = mappings['cz'][cz_ch] + +replacements['cs'] = replacements['cz'] +entries ['cs'] = entries ['cz'] +mappings ['cs'] = mappings ['cz'] + +--~ print(table.serialize(mappings.cs)) + +-- French + +entries ['fr'] = entries ['en'] +mappings['fr'] = mappings['en'] + +-- German (by Wolfgang Schuster) + +-- DIN 5007-1 + +entries ['DIN 5007-1'] = entries ['en'] +mappings ['DIN 5007-1'] = mappings['en'] + +-- DIN 5007-2 + +replacements['DIN 5007-2'] = { -- todo: add_uppercase_replacements + { "ä", 'ae' }, + { "ö", 'oe' }, + { "ü", 'ue' }, + { "Ä", 'Ae' }, + { "Ö", 'Oe' }, + { "Ü", 'Ue' }, +} + +--~ add_uppercase_replacements('DIN 5007-2') + +entries ['DIN 5007-2'] = entries ['en'] +mappings ['DIN 5007-2'] = mappings['en'] + +-- Duden + +replacements['Duden'] = { { "ß", 's' } } +entries ['Duden'] = entries ['en'] +mappings ['Duden'] = mappings['en'] + +-- new german + +entries ['de'] = entries ['en'] +mappings ['de'] = mappings['en'] + +-- old german + +entries ['deo'] = entries ['de'] +mappings ['deo'] = mappings['de'] + +-- german - Germany + +entries ['de-DE'] = entries ['de'] +mappings ['de-DE'] = mappings['de'] + +-- german - Swiss + +entries ['de-CH'] = entries ['de'] +mappings ['de-CH'] = mappings['de'] + +-- german - Austria + +entries['de-AT'] = { + ["a"] = "a", ["ä"] = "ä", ["b"] = "b", ["c"] = "c", ["d"] = "d", + ["e"] = "e", ["f"] = "f", ["g"] = "g", ["h"] = "h", ["i"] = "i", + ["j"] = "j", ["k"] = "k", ["l"] = "l", ["m"] = "m", ["n"] = "n", + ["o"] = "o", ["ö"] = "ö", ["p"] = "p", ["q"] = "q", ["r"] = "r", + ["s"] = "s", ["t"] = "t", ["u"] = "u", ["ü"] = "ü", ["v"] = "v", + ["w"] = "w", ["x"] = "x", ["y"] = "y", ["z"] = "z", +-- ["A"] = "a", ["Ä"] = "ä", ["B"] = "b", ["C"] = "c", ["D"] = "d", +-- ["E"] = "e", ["F"] = "f", ["G"] = "g", ["H"] = "h", ["I"] = "i", +-- ["J"] = "j", ["K"] = "k", ["L"] = "l", ["M"] = "m", ["N"] = "n", +-- ["O"] = "o", ["Ö"] = "ö", ["P"] = "p", ["Q"] = "q", ["R"] = "r", +-- ["S"] = "s", ["T"] = "t", ["U"] = "u", ["Ü"] = "ü", ["V"] = "v", +-- ["W"] = "w", ["X"] = "x", ["Y"] = "y", ["Z"] = "z", +} + +mappings['de-AT'] = { + ["a"] = 1, ["ä"] = 3, ["b"] = 5, ["c"] = 7, ["d"] = 9, + ["e"] = 11, ["f"] = 13, ["g"] = 15, ["h"] = 17, ["i"] = 19, + ["j"] = 21, ["k"] = 23, ["l"] = 25, ["m"] = 27, ["n"] = 29, + ["o"] = 31, ["ö"] = 33, ["p"] = 35, ["q"] = 37, ["r"] = 39, + ["s"] = 41, ["t"] = 43, ["u"] = 45, ["ü"] = 47, ["v"] = 49, + ["w"] = 51, ["x"] = 53, ["y"] = 55, ["z"] = 57, +-- ["A"] = 2, ["Ä"] = 4, ["B"] = 6, ["C"] = 8, ["D"] = 10, +-- ["E"] = 12, ["F"] = 14, ["G"] = 16, ["H"] = 18, ["I"] = 20, +-- ["J"] = 22, ["K"] = 24, ["L"] = 26, ["M"] = 28, ["N"] = 30, +-- ["O"] = 32, ["Ö"] = 34, ["P"] = 36, ["Q"] = 38, ["R"] = 40, +-- ["S"] = 42, ["T"] = 44, ["U"] = 46, ["Ü"] = 48, ["V"] = 50, +-- ["W"] = 52, ["X"] = 54, ["Y"] = 56, ["Z"] = 58, +} + +add_uppercase_entries ('de-AT') +add_uppercase_mappings('de-AT',1) + +-- finish (by Wolfgang Schuster) + +entries['fi'] = { + ["a"] = "a", ["b"] = "b", ["c"] = "c", ["d"] = "d", ["e"] = "e", + ["f"] = "f", ["g"] = "g", ["h"] = "h", ["i"] = "i", ["j"] = "j", + ["k"] = "k", ["l"] = "l", ["m"] = "m", ["n"] = "n", ["o"] = "o", + ["p"] = "p", ["q"] = "q", ["r"] = "r", ["s"] = "s", ["t"] = "t", + ["u"] = "u", ["v"] = "v", ["w"] = "w", ["x"] = "x", ["y"] = "y", + ["z"] = "z", ["å"] = "å", ["ä"] = "ä", ["ö"] = "ö", +} + +mappings['fi'] = { + ["a"] = 1, ["b"] = 3, ["c"] = 5, ["d"] = 7, ["e"] = 9, + ["f"] = 11, ["g"] = 13, ["h"] = 15, ["i"] = 17, ["j"] = 19, + ["k"] = 21, ["l"] = 23, ["m"] = 25, ["n"] = 27, ["o"] = 29, + ["p"] = 31, ["q"] = 33, ["r"] = 35, ["s"] = 37, ["t"] = 39, + ["u"] = 41, ["v"] = 43, ["w"] = 45, ["x"] = 47, ["y"] = 49, + ["z"] = 51, ["å"] = 53, ["ä"] = 55, ["ö"] = 57, +} + +add_uppercase_entries ("fi") +add_uppercase_mappings("fi") + +-- slovenian +-- +-- MM: this will change since we need to add accented vowels + +entries['sl'] = { + ["a"] = "a", ["b"] = "b", ["c"] = "c", ["č"] = "č", ["ć"] = "ć", ["d"] = "d", + ["đ"] = "đ", ["e"] = "e", ["f"] = "f", ["g"] = "g", ["h"] = "h", ["i"] = "i", + ["j"] = "j", ["k"] = "k", ["l"] = "l", ["m"] = "m", ["n"] = "n", ["o"] = "o", + ["p"] = "p", ["q"] = "q", ["r"] = "r", ["s"] = "s", ["š"] = "š", ["t"] = "t", + ["u"] = "u", ["v"] = "v", ["w"] = "w", ["x"] = "x", ["y"] = "y", ["z"] = "z", + ["ž"] = "ž", +} + +mappings['sl'] = { + ["a"] = 1, ["b"] = 3, ["c"] = 5, ["č"] = 7, ["ć"] = 9, ["d"] = 11, + ["đ"] = 13, ["e"] = 15, ["f"] = 17, ["g"] = 19, ["h"] = 21, ["i"] = 23, + ["j"] = 25, ["k"] = 27, ["l"] = 29, ["m"] = 31, ["n"] = 33, ["o"] = 35, + ["p"] = 37, ["q"] = 39, ["r"] = 41, ["s"] = 43, ["š"] = 45, ["t"] = 47, + ["u"] = 49, ["v"] = 51, ["w"] = 53, ["x"] = 55, ["y"] = 57, ["z"] = 59, + ["ž"] = 61, +} + +add_uppercase_entries ("sl") +add_uppercase_mappings("sl") -- cf. MM diff --git a/tex/context/base/sort-lan.mkii b/tex/context/base/sort-lan.mkii new file mode 100644 index 000000000..db52c63fb --- /dev/null +++ b/tex/context/base/sort-lan.mkii @@ -0,0 +1,217 @@ +%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 {zcaron} {zz} + +% \exportsortdivision {cz} {ccaron} +% \exportsortdivision {czz} {cacute} +% \exportsortdivision {dz} {dstroke} +% \exportsortdivision {sz} {scaron} +% \exportsortdivision {zz} {zcaron} +% \stopmode +% +% \startmode[sortorder-sl] +% \exportsortexpansion {ccaron} {c+1} +% \exportsortexpansion {cacute} {c+2} +% \exportsortexpansion {dstroke} {d+1} +% \exportsortexpansion {scaron} {s+1} +% \exportsortexpansion {zcaron} {z+1} +% +% \exportsortdivision {c+1} {ccaron} +% \exportsortdivision {c+2} {cacute} +% \exportsortdivision {d+1} {dstroke} +% \exportsortdivision {s+1} {scaron} +% \exportsortdivision {z+1} {zcaron} +% \stopmode + +\startmode[sortorder-sl] + \exportsortrule {ccaron} {c+1} + \exportsortrule {cacute} {c+2} + \exportsortrule {dstroke} {d+1} + \exportsortrule {scaron} {s+1} + \exportsortrule {zcaron} {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} + \exportsortexpansion {Aacute} {A} + \exportsortexpansion {ccaron} {c+1} + \exportsortexpansion {Ccaron} {C+1} + \exportsortdivision {c+1} {ccaron} + \exportsortexpansion {dcaron} {d} + \exportsortexpansion {Dcaron} {D} + %\exportsortdivision {d+1} {dcaron} + \exportsortexpansion {eacute} {e} + \exportsortexpansion {Eacute} {E} + \exportsortexpansion {ecaron} {e} + \exportsortexpansion {Ecaron} {E} + \exportsortreduction {ch} {h+1} + \exportsortexpansion {ch} {h+1} + \exportsortreduction {Ch} {H+1} + \exportsortexpansion {Ch} {H+1} + \exportsortdivision {h+1} {czsortdivisionch} + \exportsortexpansion {iacute} {i} + \exportsortexpansion {Iacute} {I} + \exportsortexpansion {ncaron} {n} + \exportsortexpansion {Ncaron} {N} + %\exportsortdivision {n+1} {ncaron} + \exportsortexpansion {oacute} {o} + \exportsortexpansion {Oacute} {O} + \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} + \exportsortexpansion {Tcaron} {T} + %\exportsortdivision {t+1} {tcaron} + \exportsortexpansion {uacute} {u} + \exportsortexpansion {Uacute} {U} + \exportsortexpansion {uring} {u} + \exportsortexpansion {Uring} {U} + \exportsortexpansion {yacute} {y} + \exportsortexpansion {Yacute} {Y} + \exportsortexpansion {zcaron} {z+1} + \exportsortexpansion {Zcaron} {Z+1} + \exportsortdivision {z+1} {zcaron} +\stopmode + +% Polish: + +\startmode[sortorder-pl] + \exportsortrule {aogonek} {a+1} + \exportsortrule {cacute} {c+1} + \exportsortrule {eogonek} {e+1} + \exportsortrule {lstroke} {l+1} + \exportsortrule {nacute} {n+1} + \exportsortrule {oacute} {o+1} + \exportsortrule {sacute} {s+1} + \exportsortrule {zacute} {z+1} + \exportsortrule {zdotaccent} {z+2} +\stopmode + +\endinput diff --git a/tex/context/base/spac-ali.mkiv b/tex/context/base/spac-ali.mkiv new file mode 100644 index 000000000..b168a02be --- /dev/null +++ b/tex/context/base/spac-ali.mkiv @@ -0,0 +1,677 @@ +%D \module +%D [ file=spac-ali, +%D version=2009.10.16, % 1997.03.31, was core-spa.tex +%D title=\CONTEXT\ Spacing Macros, +%D subtitle=Alignments, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Alignments} + +\unprotect + +% We will not use bodydir and pagedir so we disable them. That way we get +% normal hyperlink support. + +\let\@@bodydir\normalbodydir +\let\@@pagedir\normalpagedir + +\unexpanded\def\bodydir{\afterassignment\do@@bodydir\@@bodydir} \let\normalbodydir\bodydir +\unexpanded\def\pagedir{\afterassignment\do@@pagedir\@@pagedir} \let\normalpagedir\pagedir + +\def\do@@bodydir{\@@bodydir TLT\relax} +\def\do@@pagedir{\@@pagedir TLT\relax} + +% This will become a more advanced layout controller soon: + +\newconditional\layoutlefttoright \settrue\layoutlefttoright +\newconditional\displaylefttoright \settrue\displaylefttoright +\newconditional\inlinelefttoright \settrue\inlinelefttoright + +\unexpanded\def\lefttoright + {\ifvmode + \settrue\displaylefttoright + \settrue\inlinelefttoright + \textdir TLT\relax + \pardir TLT\relax + \else + \settrue\inlinelefttoright + \textdir TLT\relax + \fi} + +\unexpanded\def\righttoleft + {\ifvmode + \setfalse\displaylefttoright + \setfalse\inlinelefttoright + \textdir TRT\relax + \pardir TRT\relax + \else + \textdir TRT\relax + \setfalse\inlinelefttoright + \fi} + +\def\currentdirectionparameters + {\ifconditional\inlinelefttoright \else + idir="r2l", + \fi + \ifconditional\displaylefttoright \else + ddir="r2l", + \fi} + +\def\dodefinehbox[#1][#2]% + {\setvalue{hbox#1}##1{\hbox to #2{\begstrut##1\endstrut\hss}}} + +\unexpanded\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% + {\normalexpanded{\noexpand\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} + +% More alignments: + +% \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} + +\unexpanded\def\startshowpardata + {\begingroup + \showcomposition + \showstruts\tracepositionstrue \tracingparagraphs\maxdimen + \appendtoksonce\showpardata\let\showpardata\relax\to\everypar} + +\unexpanded\def\stopshowpardata + {\endgraf + \endgroup} + +% defaults + +\def\raggedfillamount {1fil} +\def\raggedhalffillamount{.5fil} +\def\raggedspaceamount {\interwordspace} % {.3333em} +\def\raggedxspaceamount {.5em} + +\unexpanded\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 + +\unexpanded\def\raggedleft + {\setraggedness\leftraggedness + \setraggedskips1\leftraggedness\zeropoint\raggedspaceamount + \raggedxspaceamount\zeropoint\zeropoint} + +\unexpanded\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. + +\unexpanded\def\raggedright + {\setraggedness\rightraggedness + \setraggedskips3\zeropoint\rightraggedness\raggedspaceamount + \raggedxspaceamount\raggedfillamount\parindent} + +\unexpanded\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. + +\unexpanded\def\veryraggedcenter + {\setraggedskips2\raggedfillamount\raggedfillamount\raggedspaceamount + \raggedxspaceamount\zeropoint\zeropoint} + +\unexpanded\def\veryraggedright + {\setraggedskips3\zeropoint\raggedfillamount\raggedspaceamount + \raggedxspaceamount\zeropoint\parindent} + +\unexpanded\def\ttraggedright + {\tttf + \setraggedskips3\zeropoint\rightraggedness + \zeropoint\zeropoint\zeropoint\parindent} % \ctxparindent + +%D A bonus one: + +\unexpanded\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!righttoleft {\lefttoright} +\installalign \v!lefttoright {\righttoleft} +\installalign {l2r} {\lefttoright} +\installalign {r2l} {\righttoleft} + +\newcount\hyphenminoffset + +\ifx\sethyphenationvariables\undefined \let\sethyphenationvariables\relax \fi + +\unexpanded\def\lesshyphens + {\advance\hyphenminoffset\plusone + \sethyphenationvariables} + +\unexpanded\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} + +\unexpanded\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 + +\unexpanded\def\startalignment + {\bgroup + \setupalign} + +\unexpanded\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 + +\ifdefined\line \else \def\line {\hbox to\hsize} \fi +\ifdefined\leftline \else \def\leftline #1{\line{#1\hss}} \fi +\ifdefined\rightline \else \def\rightline #1{\line{\hss#1}} \fi +\ifdefined\centerline \else \def\centerline#1{\line{\hss#1\hss}} \fi + +% directe commando's + +\def\leftaligned {\doalignline \relax \hss } +\def\midaligned {\doalignline \hss \hss } +\def\rightaligned{\doalignline \hss \relax} + +\let\centeraligned\midaligned + +\def\regelbegrensd#1{\limitatetext{#1}{\hsize}{\unknown}} % to be translated + +% indirecte commando's + +\letvalue{\s!do\v!line\v!left }\leftaligned +\letvalue{\s!do\v!line\v!right }\rightaligned +\letvalue{\s!do\v!line\v!middle }\midaligned +\letvalue{\s!do\v!line\v!flushleft }\rightaligned +\letvalue{\s!do\v!line\v!flushright}\leftaligned +\letvalue{\s!do\v!line\v!center }\midaligned + +\def\doalignedline#1{\csname\s!do\v!line#1\endcsname} + +%D Experimental: + +\def\doxalignline#1#2#3#4#5#6% + {\noindentation % was \noindent + \dontleavehmode % added in marrakesch at TUG 2006\begingroup + \begingroup + \setlocalhsize + \def\\{\egroup\par\doxalignline#1#2#3#4#5#6\bgroup}% inefficient + \dowithnextbox + {%\noindent moved up + \hbox to \localhsize + {#1\hskip\ifdone#2\else#3\fi#4% + \hbox to \localhsize + {\the\everyleftofalignedline + \ifcase\alignstrutmode\or\strut\fi + \ifdone#5\unhbox\nextbox#6\else#6\unhbox\nextbox#5\fi + \the\everyrightofalignedline}% + \hss}% + \endgroup} + \hbox} + +\def\doxcheckline + {\signalrightpage\doifrightpageelse\donetrue\donefalse} + +\setvalue{\s!do\v!line\v!inner }{\doxalignline\doxcheckline++\zeropoint \relax\hss } +\setvalue{\s!do\v!line\v!outer }{\doxalignline\doxcheckline++\zeropoint \hss \relax} +\setvalue{\s!do\v!line\v!innermargin}{\doxalignline\doxcheckline-+\innermargintotal\relax\hss } +\setvalue{\s!do\v!line\v!outermargin}{\doxalignline\doxcheckline+-\outermargintotal\hss \relax} +\setvalue{\s!do\v!line\v!inneredge }{\doxalignline\doxcheckline-+\inneredgetotal \relax\hss } +\setvalue{\s!do\v!line\v!outeredge }{\doxalignline\doxcheckline+-\outeredgetotal \hss \relax} +\setvalue{\s!do\v!line\v!backspace }{\doxalignline\doxcheckline-+\backspace \relax\hss } +\setvalue{\s!do\v!line\v!cutspace }{\doxalignline\doxcheckline+-\cutspace \hss \relax} + +\setvalue{\s!do\v!line\v!leftmargin }{\doxalignline\donefalse --\leftmargintotal \hss \relax} +\setvalue{\s!do\v!line\v!rightmargin}{\doxalignline\donefalse ++\rightmargintotal\relax\hss } +\setvalue{\s!do\v!line\v!leftedge }{\doxalignline\donefalse --\leftedgetotal \hss \relax} +\setvalue{\s!do\v!line\v!rightedge }{\doxalignline\donefalse ++\rightedgetotal \relax\hss } + +% ! ! ! beware, redefining \doalignline gives the wrong results ! ! ! +% +% \def\doalignline{\doxalignline\donefalse++\zeropoint} + +%D Better: + +\def\doalignedline#1{\csname\s!do\v!line#1\endcsname} + +\def\alignedline#1#2% setting default + {\csname\s!do\v!line\ifcsname\s!do\v!line#1\endcsname#1\else#2\fi\endcsname} + +% \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 (see hyhenation/specialcases-001.tex) + \par}} + +\unexpanded\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}} + +\unexpanded\def\simplealignedbox#1{\executeifdefined{\s!simple\c!align#1}{\getvalue{\s!simple\c!align\v!right}}} + +\protect \endinput diff --git a/tex/context/base/spac-def.mkiv b/tex/context/base/spac-def.mkiv new file mode 100644 index 000000000..3aa85dda5 --- /dev/null +++ b/tex/context/base/spac-def.mkiv @@ -0,0 +1,118 @@ +%D \module +%D [ file=spac-def, +%D version=2009.10.16, % 1997.03.31, was core-spa.tex +%D title=\CONTEXT\ Spacing 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. + +\writestatus{loading}{ConTeXt Spacing Macros / Definitions} + +\unprotect + +\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! + + +\appendtoks \spacing\plusone \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 \simplesetupindenting \to \everybodyfont +\appendtoks \simplesetupblank \to \everybodyfont +\appendtoks \simplesetupwhitespace \to \everybodyfont +\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 + +\setupwhitespace + [\v!none] + +\indenting + [\v!never] + +\setupindenting + [\v!none] + +\setupvspacing + [\v!standard, + \v!big] + +\definevspacing[\v!default] [\currentblank] +\definevspacing[\v!before] [\v!default] +\definevspacing[\v!inbetween][\v!default] +\definevspacing[\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/spac-fnt.mkiv b/tex/context/base/spac-fnt.mkiv new file mode 100644 index 000000000..c268d7893 --- /dev/null +++ b/tex/context/base/spac-fnt.mkiv @@ -0,0 +1,94 @@ +%D \module +%D [ file=spac-fnt, +%D version=2009.10.16, % 1997.03.31, was core-spa.tex +%D title=\CONTEXT\ Spacing 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 Spacing Macros / Fonts} + +%D For historic reasons here, will move and/or disappear: + +\unprotect + +\let\dostopattributes\relax % in case these commands end up in an edef + +\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 + +\newconditional\fontattributeisset + +\unexpanded\def\dosetfontattribute#1#2% + {\ifcsname#1#2\endcsname + \settrue\fontattributeisset % reset is done elsewhere + \@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} + +\protect \endinput diff --git a/tex/context/base/spac-gen.mkii b/tex/context/base/spac-gen.mkii new file mode 100644 index 000000000..8274db1b9 --- /dev/null +++ b/tex/context/base/spac-gen.mkii @@ -0,0 +1,4652 @@ +%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 Core Macros / Spacing} + +% to be sorted out: dependencies, order of initialization / also some dutch code here + +\unprotect + +% 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!synchronize] {\verticalstrut\vskip-2\lineheight\verticalstrut} + +% \vtop{\blank[synchronize]\blank[line]test} + +\defineblankmethod [\v!always] {\redowhitespace} % experimental + +% happens often, so we speed this up: +% +% \defineblankmethod [2*\v!line] {\addblankskip+{2\openlineheight}{2\openlineheight}} +% \defineblankmethod [2*\v!big] {\addblankskip+{2\bigskipamount }{2\openlineheight}} +% +% no, with 2\whatever we loose the stretch and shrink! Taco's alternative: + +\defineblankmethod + [2*\v!line] + {\addblankskip+\openlineheight\openlineheight + \addblankskip+\openlineheight\openlineheight} + +\defineblankmethod + [2*\v!big] + {\addblankskip+\bigskipamount\openlineheight + \addblankskip+\bigskipamount\openlineheight} + +\def\doblank#1% + {\edefconvertedargument\ascii{#1}% + \ifx\ascii\empty\else + \ifcsname\??bo\??bo\ascii\endcsname % internal def + \csname\??bo\??bo\ascii\endcsname + \else\ifcsname\??bo\ascii\endcsname % user def / slow + \@EA\rawprocesscommalist\@EA[\csname\??bo\ascii\endcsname]\doblank\relax + \else + \dorepeatwithcommand[#1]\redoblank + \fi\fi + \fi + \relax} + +\def\redoblank#1% + {\edefconvertedargument\ascii{#1}% + \ifx\ascii\empty\else + \ifcsname\??bo\??bo\ascii\endcsname % internal def + \csname\??bo\??bo\ascii\endcsname + \else\ifcsname\??bo\ascii\endcsname % user def / slow + \@EA\rawprocesscommalist\@EA[\csname\??bo\ascii\endcsname]\doblank\relax + \else + \global\advance\blankskip#1\relax + \fi\fi + \fi + \relax} + +\unexpanded\def\blank % the \relax is definitely needed due to the many \if's + {\relax\complexorsimple\doblank} + +\def\complexdoblank + {\flushnotes + \ifmmode + \@EA\nocomplexdoblank + \else + \ifopelkaar + \ifinpagebody + \@EA\@EAEAEA\@EA\docomplexdoblank + \else + \@EA\@EAEAEA\@EA\nocomplexdoblank + \fi + \else + \@EAEAEA\docomplexdoblank + \fi + \fi} + +\def\nocomplexdoblank[#1]% + {% evt blokkeerfalse + \ifmmode\else\par\fi} + +% Overloaded in cont-new! + +\newsignal\noblanksignal + +% \def\doinhibitblank +% {\kern\noblanksignal} + +% \def\inhibitblank% the fast, local way +% {\endgraf\ifvmode\prevdepth\newprevdepth\fi} + +% \def\docomplexdoblank[#1]% pas op \relax's zijn nodig ivm volgende \if +% {\global\blankresetfalse +% \global\blankdisablefalse +% \global\blanknowhitefalse +% \global\localblankflexiblefalse +% \global\localblankfixedfalse +% \global\blankskip\zeropoint +% \global\blankforcefalse +% \global\blankgobackfalse +% \blankouterfalse +% \expanded{\rawprocesscommalist[#1]}\doblank +% \ifdim\blankskip=\zeropoint\relax +% \iflocalblankflexible +% \doglobal\advance\blankskip \currentblank +% \else\iflocalblankfixed +% \doglobal\advance\blankskip \currentblank +% \fi\fi +% \fi +% \ifblankouter +% \else +% \par +% \ifvmode +% \ifblankgoback +% \removelastskip +% \fi +% \ifblankforce +% % dit gaat mis in pos fonts +% % \ifdim\prevdepth>\zeropoint\else ... +% % -1000pt signals top of page or column (\ejectcolumn) +% \bgroup\forgeteverypar\verticalstrut\egroup\kern-\struttotal +% \fi +% \ifblankdisable +% \global\blankindeedfalse +% \ifgridsnapping +% \ifdim\prevdepth<\zeropoint +% % brrr +% \else +% % dirty trick: smaller blanks are ignored after +% % a larger one, so 10 lines is probably safe; first make +% % sure that we honor penalties +% \scratchcounter\lastpenalty +% % now comes the trick (cross our fingers that this works +% % well in multi columns; maybe an ifinner test is needed +% % \vskip-10\lineheight +% % \ifnum\scratchcounter=\zerocount \else \penalty\lastpenalty \fi +% % \vskip 10\lineheight +% % allas, this leads to overfull pages, so we try this: +% \kern-\noblanksignal +% \ifnum\scratchcounter=\zerocount +% \else +% \penalty\lastpenalty +% \fi +% \kern\noblanksignal +% % end-of-dirty-trick +% \fi +% \else +% \ifdim\prevdepth<\zeropoint +% % brrr +% \else +% % ensure at least a proper prevdepth, this should be +% % an option +% \vskip-\prevdepth +% \vskip\strutdepth +% \prevdepth\strutdepth +% \fi +% % the old crappy piece of code +% \edef\oldprevdepth{\the\prevdepth}% +% \prevdepth\newprevdepth +% \fi +% \else +% \global\blankindeedtrue +% \fi +% \ifblankreset +% \global\blankindeedtrue +% \ifgridsnapping +% % let's play safe and not fool around with the depth, if +% % only because it took a lot of effort to sort out the grid +% % stuff in the first place +% \else +% \ifdim\prevdepth=\newprevdepth +% \prevdepth\oldprevdepth +% \fi +% \fi +% \fi +% \ifblankindeed +% \ifdim1\lastskip<1\blankskip\relax +% % else when \blanko[2*groot] + \blanko[3*groot] with parskip +% % equaling 1*groot, gives a groot=\parskip so adding a small +% % value makes it distinguishable; can also be done at parskip +% % setting time (better) +% \global\advance\blankskip \mindimen\relax % = skip +% % test this on 2* + 3* and parskip groot +% \ifblanknowhite +% \global\advance\blankskip -\parskip +% \else +% \ifdim\lastskip=\parskip +% \else % force this due to previous comment +% \ifdim\parskip>\zeropoint\relax +% \ifdim\blankskip<\parskip\relax +% \global\blankskip\zeropoint +% \else +% \global\advance\blankskip -\parskip +% \fi +% \fi +% \fi +% \fi +% \ifblankflexible \else +% \blankskip1\blankskip +% \fi +% \iflocalblankfixed +% \blankskip1\blankskip +% \fi +% \iflocalblankflexible +% \blankskip1\blankskip +% \!!plus\skipgluefactor\blankskip +% \!!minus\skipgluefactor\blankskip +% \fi +% \ifdim\lastkern=\noblanksignal % controled and grid +% \global\blankindeedfalse +% \else\ifgridsnapping\else\ifdim\prevdepth=\newprevdepth +% \global\blankindeedfalse +% \fi\fi\fi +% \ifblankindeed +% \iffuzzyvskip +% \removelastfuzzyvskip +% \fuzzyvskip\blankskip\relax +% \else +% \removelastskip +% \vskip\blankskip\relax +% \fi +% \fi +% \else +% \iffuzzyvskip +% \removelastfuzzyvskip +% \fuzzyvskip\blankskip\relax +% \else +% % new, test this on pascal +% \ifdim\blankskip<\zeropoint +% \advance\blankskip-\lastskip +% \removelastskip +% \ifdim\blankskip>\zeropoint +% \vskip\blankskip +% \else +% \vskip\zeropoint +% \fi +% \else +% % also new +% \ifdim\blankskip=\zeropoint +% \ifblanknowhite +% \geenwitruimte +% \fi +% \fi +% \fi +% \fi +% \fi +% \fi +% \fi +% \fi +% \global\fuzzyvskipfalse +% \presetindentation} + +% goback was broken: + +% \def\doinhibitblank +% {\kern\noblanksignal} + +% \def\inhibitblank% the fast, local way +% {\endgraf\ifvmode\prevdepth\newprevdepth\fi} + +% problem: we cannot look back in the mvl so we need 3 kinds of signals + +\def\noblankpsignal{1010101} + +\def\inhibitgridblank % was doinhibitblank + {\ifvmode\else\endgraf\fi + \ifvmode + \ifnum\lastpenalty<10000 + \kern-\noblanksignal % new + \kern \noblanksignal + \else + \penalty\noblankpsignal + \fi + \fi} + +\def\inhibittextblank % was inhibitblank + {\endgraf + \ifvmode + \prevdepth\newprevdepth + \fi} + +% new macro +% +% \def\inhibitblank % need some work +% {\endgraf +% \ifvmode +% \ifgridsnapping +% \inhibitgridblank +% \else +% % this one spoils the grid +% \inhibittextblank +% \fi +% \fi} + +\def\doinhibitblank{\inhibitgridblank} +\def\inhibitblank {\inhibittextblank} + +% will become obsolete + +\ifx\undefined\savedlastskip \newskip \savedlastskip \fi +\ifx\undefined\savedlastpenalty \newcount\savedlastpenalty \fi + +% beware, prevdepth can have funny values (e.g. mvl value when in box) + +\def\docomplexdoblank[#1]% pas op \relax's zijn nodig ivm volgende \if + {\global\blankresetfalse + \global\blankdisablefalse + \global\blanknowhitefalse + \global\localblankflexiblefalse + \global\localblankfixedfalse + \global\blankforcefalse + \global\blankgobackfalse + \blankouterfalse + \global\blankskip\zeropoint +% +\edefconvertedargument\ascii{#1}% todo fast check for simple +\ifcsname\??bo\??bo\ascii\endcsname % internal def + \csname\??bo\??bo\ascii\endcsname +\else\ifcsname\??bo\ascii\endcsname % user def / slow + \@EA\rawprocesscommalist\@EA[\csname\??bo\ascii\endcsname]\doblank\relax +\else + \expanded{\rawprocesscommalist[#1]}\doblank +\fi\fi +% + \relax % to be sure + \ifdim\blankskip=\zeropoint\relax + \iflocalblankflexible + \doglobal\advance\blankskip \currentblank + \else\iflocalblankfixed + \doglobal\advance\blankskip \currentblank + \fi\fi + \fi + \relax % to be sure + \ifblankouter + % do nothing + \else + \par + \ifvmode + \ifblankgoback + \ifdim\lastskip>\zeropoint \vskip-\lastskip \fi + \savedlastskip\zeropoint + \else\ifdim\lastskip>\zeropoint + \savedlastskip\lastskip + \else % todo: lastnode, dan namelijk geen skip ! + \savedlastskip\zeropoint + \fi\fi + \ifblankforce + % dit gaat mis in pos fonts + % \ifdim\prevdepth>\zeropoint\else ... + % -1000pt signals top of page or column (\ejectcolumn) + \bgroup\forgeteverypar\verticalstrut\egroup\kern-\struttotal + \savedlastskip\zeropoint + \fi + \savedlastpenalty\lastpenalty % hm, now it gets lost + \ifblankdisable + \global\blankindeedfalse % keep this, i.e. disable current too + \ifgridsnapping + \ifdim\prevdepth<\zeropoint + % brrr + \else + % dirty trick: smaller blanks are ignored after a + % larger one, so 10 lines is probably safe; we need + % to make sure that we honor penalties; here comes the + % trick (cross our fingers that this works well in + % multi columns; maybe an ifinner test is needed + % \scratchcounter\lastpenalty + % \vskip-10\lineheight + % \ifnum\scratchcounter=\zerocount \else \penalty\lastpenalty \fi + % \vskip 10\lineheight + % alas, this leads to overfull pages, so we try this: + \inhibitgridblank + \fi + \else + \ifdim\prevdepth<\zeropoint + % brrr + \else + % ensure at least a proper prevdepth, this should be + % an option + \vskip-\prevdepth + \vskip\strutdepth + \prevdepth\strutdepth + \fi + % the old crappy piece of code + \edef\oldprevdepth{\the\prevdepth}% + \prevdepth\newprevdepth % == \inhibittextblank + \fi + \else + \global\blankindeedtrue + \fi + \ifblankreset + \global\blankindeedtrue + \ifgridsnapping + % let's play safe and not fool around with the depth, if + % only because it took a lot of effort to sort out the grid + % stuff in the first place + \else + \ifdim\prevdepth=\newprevdepth + \prevdepth\oldprevdepth + \fi + \fi + \fi + \ifblankindeed + \ifdim1\savedlastskip<1\blankskip\relax + % else when \blank[2*groot] + \blank[3*groot] with parskip + % equaling 1*groot, gives a groot=\parskip so adding a small + % value makes it distinguishable; can also be done at parskip + % setting time (better) + \global\advance\blankskip \mindimen\relax % = skip + % test this on 2* + 3* and parskip groot + \ifblanknowhite + \global\advance\blankskip -\parskip + \else + \ifdim\savedlastskip=\parskip + \else % force this due to previous comment + \ifdim\parskip>\zeropoint\relax + \ifdim\blankskip<\parskip\relax + \global\blankskip\zeropoint + \else + \global\advance\blankskip -\parskip + \fi + \fi + \fi + \fi + \ifblankflexible \else + \blankskip1\blankskip + \fi + \iflocalblankfixed + \blankskip1\blankskip + \fi + \iflocalblankflexible + \blankskip1\blankskip + \!!plus \skipgluefactor\blankskip + \!!minus\skipgluefactor\blankskip + \fi + \ifdim\lastkern=\noblanksignal\relax % controlled and grid + \global\blankindeedfalse + \else\ifnum\savedlastpenalty=\noblankpsignal\relax % controlled and grid + \global\blankindeedfalse + \else\ifgridsnapping\else\ifdim\prevdepth=\newprevdepth + \global\blankindeedfalse + \fi\fi\fi\fi + \ifblankindeed + \iffuzzyvskip + \removelastfuzzyvskip + \fuzzyvskip\blankskip\relax + \else + \relax\ifdim\savedlastskip=\zeropoint\else + \vskip-\savedlastskip + \fi + \vskip\blankskip\relax + \fi + \fi + \else + \iffuzzyvskip + \removelastfuzzyvskip + \fuzzyvskip\blankskip\relax + \else + % new, test this on pascal + \ifdim\blankskip<\zeropoint + \relax\ifdim\savedlastskip=\zeropoint\else + \advance\blankskip-\savedlastskip + \vskip-\savedlastskip + \fi + \ifdim\blankskip>\zeropoint + \vskip\blankskip + \else + \vskip\zeropoint + \fi + \else + % also new + \ifdim\blankskip=\zeropoint + \ifblanknowhite + \nowhitespace + \fi + \fi + \fi + \fi + \fi + \fi + \fi + \fi + \global\fuzzyvskipfalse + \presetindentation} + +%D For a long time we had: +%D +%D \starttyping +%D \def\simpledoblank% +%D {\doifelse{\currentwhitespace}{\v!geen} +%D {\blank[\currentblank]} +%D {\blank[\currentwhitespace]}} +%D \stoptyping +%D +%D But Berend de Boer wanted more control, so now we have: + +\def\simpledoblank % ... + {\doifelse\currentwhitespace\v!none + {\blank[\currentblank]} + {\blank[\s!default]}} + +%D Another useful definition would be: +%D +%D \starttyping +%D \defineblank +%D [\s!default] +%D [\v!groot] +%D \stoptyping + +\def\dosetupblank#1% amount are an plain inheritance + {\bigskipamount#1\relax + \ifblankflexible \else + \bigskipamount1\bigskipamount + \fi + \medskipamount \bigskipamount \divide\medskipamount \plustwo + \smallskipamount\bigskipamount \divide\smallskipamount\plusfour}% + +\def\complexsetupblank[#1]% more \let's -> this also wil become installable + {\ifgridsnapping + \blankflexiblefalse + \else + \ExpandFirstAfter\processallactionsinset + [#1] + [ \v!flexible=>\blankflexibletrue, + \v!fixed=>\blankflexiblefalse]% + \fi + \ExpandFirstAfter\processallactionsinset + [#1] + [ \v!flexible=>\dosetupblank\appliedblankskip, + \v!fixed=>\dosetupblank\appliedblankskip, + \v!line=>\edef\appliedblankskip{\linedistance}% + \dosetupblank\appliedblankskip, + \v!halfline=>\scratchskip.5\linedistance + \edef\appliedblankskip{\the\scratchskip}% + \dosetupblank\appliedblankskip, + \v!big=>\ifgridsnapping + \edef\appliedblankskip{\linedistance}% + \dosetupblank\appliedblankskip + \fi + \let\currentblank\v!big, + \v!medium=>\let\currentblank\v!medium, + \v!small=>\let\currentblank\v!small, + \v!global=>\let\currentblank\v!global, + \v!normal=>\dosetupblank\appliedblankskip, + \v!standard=>\edef\appliedblankskip{\skipfactor\linedistance}% + \dosetupblank\appliedblankskip, + \s!default=>\dosetupblank\appliedblankskip, + \s!unknown=>\let\appliedblankskip\commalistelement + \dosetupblank\appliedblankskip]% + \simplesetupwhitespace} + +% \definecomplexorsimpleempty\setupblank +% +% speed gain: 60 sec -> 30 sec + +\definecomplexorsimple\setupblank + +\def\simplesetupblank % == snelle \setupblank[\s!default] + {\ifgridsnapping + \blankflexiblefalse + \fi + \dosetupblank\appliedblankskip + % \let\deblanko\v!big + \simplesetupwhitespace} + +\def\restorestandardblank% \v!standard + {\edef\appliedblankskip{\skipfactor\linedistance}% + \dosetupblank\appliedblankskip + }%\let\deblanko\v!big} + +\def\dodefineblank[#1][#2]% + {\def\docommand##1{\setvalue{\??bo##1}{#2}}% + \processcommalist[#1]\docommand} + +\def\defineblank + {\dodoubleargument\dodefineblank} + +\def\savecurrentblank + {\edef\restorecurrentblank + {\bigskipamount\the\bigskipamount + \medskipamount\the\medskipamount + \smallskipamount\the\smallskipamount + \noexpand\def\noexpand\currentblank{\currentblank}% + \ifblankflexible + \noexpand\blankflexibletrue + \else + \noexpand\blankflexiblefalse + \fi}} + +%D Now. + +\defineblank [\s!default] [\v!white] +\defineblank [\v!height] [\strutheight] +\defineblank [\v!depth] [\strutdepth] + +% old implementation +% +% \let\currentindentation=\empty +% +% \newdimen\ctxparindent +% +% \newif\ifindentfirstparagraph % \indentfirstparagraphtrue +% +% \def\presetindentation +% {\doifoutervmode{\ifindentfirstparagraph\else\noindentation\fi}} +% +% \definecomplexorsimple\setupindenting +% +% \def\complexsetupindenting[#1]% +% {\processallactionsinset +% [#1] +% [ \v!first=>\indentfirstparagraphtrue, +% \v!next=>\indentfirstparagraphfalse, +% \s!default=>\simplesetupindenting, +% \s!unknown=>\edef\currentindentation{\commalistelement}% +% \simplesetupindenting]} +% +% \def\simplesetupindenting +% {\assigndimension\currentindentation\ctxparindent{1em}{1.5em}{2em}% +% \parindent\ctxparindent\relax} +% +% \def\indenting % watch out: \dodo and no \do +% {\dosingleargument\dodoindenting} +% +% \def\dodoindenting[#1]% oeps, we needed a commalist handler here! +% {\edef\currentindenting{#1}% +% \processcommacommand[#1]\dododoindenting} +% +% \def\dododoindenting#1% +% {\executeifdefined{\??in:#1}\donothing} +% +% \let\currentindenting\empty +% +% \def\defineindentingmethod[#1]#2% +% {\setvalue{\??in:#1}{#2}} +% +% \defineindentingmethod [\v!no] {\parindent\ctxparindent\noindent} +% \defineindentingmethod [\v!not] {\parindent\ctxparindent\noindent} +% +% \defineindentingmethod [\v!first] {\indentfirstparagraphtrue} +% \defineindentingmethod [\v!next] {\indentfirstparagraphfalse} +% +% \defineindentingmethod [\v!yes] {\parindent\ctxparindent\relax} % no \indent ! +% \defineindentingmethod [\v!always] {\parindent\ctxparindent\relax} % no \indent ! +% +% \defineindentingmethod [\v!never] {\parindent\zeropoint\relax} % no \indent ! +% +% \def\noindenting{\indenting[\v!no,\v!next]} % was \nietinspringen +% \def\doindenting{\indenting[\v!yes,\v!first]} % was \welinspringen +% +% \def\dochecknextindentation#1% internal one +% {\checknextindentation[\getvalue{#1\c!indentnext}]} +% +% \def\checknextindentation[#1]% +% {\processaction[#1][%\v!keep=>, +% \v!yes=>\doindentation, +% \v!no=>\noindentation, +% \v!auto=>\autoindentation]} +% +% \def\doindentation% too simple +% {\gdef\checkindentation{\global\indentationtrue}} +% +% \ifx\autoindentation\undefined +% \let\autoindentation\relax +% \fi +% +% \newif\ifindentation \indentationtrue % documenteren, naar buiten +% +% \let\checkindentation=\relax +% +% \def\donoindentation +% {\ifdim\parindent=\zeropoint \else +% \bgroup \setbox\scratchbox\lastbox \egroup +% \fi} +% +% \def\noindentation % made global +% {\ifinpagebody \else +% \global\indentationfalse +% \gdef\checkindentation +% {\donoindentation +% \gdef\checkindentation{\global\indentationtrue}}% +% \fi} +% +% \def\nonoindentation % bv bij floats +% {\ifinpagebody \else +% \global\indentationtrue +% \gdef\checkindentation{\global\indentationtrue}% +% \fi} +% +% \def\indentation +% {\ifvmode \ifdim\parindent=\zeropoint \else +% % was : \hskip\parindent +% % can be: \indent +% % but we test: +% \noindent\hskip\parindent +% \fi \fi} + +\let\currentindentation\empty % amount/keyword +% \let\normalindentation \empty % used for reinstating normal indentation +\let\currentindenting \empty % method + +\newdimen\ctxparindent + +\newif\ifindentfirstparagraph % \indentfirstparagraphtrue + +\chardef\indentingtoggle\zerocount + +%D After a blank or comparable situation (left side floats) we +%D need to check if the next paragraph has to be indented. + +\def\presetindentation + {\doifoutervmode{\ifindentfirstparagraph\else\noindentation\fi}} + +%D This sets up the (normally) global indentation behavior as well +%D as the amounts. + +\definecomplexorsimple\setupindenting + +% \def\complexsetupindenting[#1]% +% {\edef\currentindenting{#1}% +% \indentfirstparagraphtrue +% \parindent\ctxparindent +% \chardef\indentingtoggle\zerocount +% \processcommalist[#1]\docomplexsetupindenting +% \ifindentfirstparagraph\else\noindentation\fi % added +% \toggleindentation} + +\indentfirstparagraphtrue +\parindent\ctxparindent +\chardef\indentingtoggle\zerocount + +% \newtoks\savedeverypar \savedeverypar\everypar +% \def\restoreeverypar{\everypar\savedeverypar} + +% we need a better everypar model: for each option a switch, which we +% set to false with \forgetall and can enable when needed (context 4); +% that way we can control the order of execution of options + +\def\checkeverypar % currently a hack + {\ifzeropt\parindent\else + \doifsometokselse\everypar\donothing{\appendtoks\checkindentation\to\everypar}% + \fi} + +\def\complexsetupindenting[#1]% + {\edef\currentindenting{#1}% + \doifsomething\currentindenting % handy when a parameter is passed + {% not here: \indentfirstparagraphtrue + % not here: \parindent\ctxparindent + % not here: \chardef\indentingtoggle\zerocount + % we use commacommand in order to catch #1 being a command (expanded parameter) + \processcommacommand[\currentindenting]\docomplexsetupindentingA % catch small, medium, etc + \processcommacommand[\currentindenting]\docomplexsetupindentingB % catch rest + \checkeverypar % only when non-empty #1 + \ifindentfirstparagraph\else\noindentation\fi % added + \toggleindentation}} + +\def\docomplexsetupindentingA#1% + {\edefconvertedargument\!!stringa{#1}% + \doifundefined{\??in:\!!stringa}% + {\edef\currentindentation{#1}% + \let\normalindentation\currentindentation + \simplesetupindenting}} + +\def\docomplexsetupindentingB#1% + {\edefconvertedargument\!!stringa{#1}% catch #1=\somedimen + \executeifdefined{\??in:\!!stringa}\donothing} + +\def\simplesetupindenting % empty case, a it strange, needed this way? + {\assigndimension\currentindentation\ctxparindent{1em}{1.5em}{2em}} + +\def\indenting % kind of obsolete + {\dosingleargument\complexsetupindenting} + +% use \noindentation to suppress next indentation + +\def\defineindentingmethod[#1]#2% + {\setvalue{\??in:#1}{#2}} + +\defineindentingmethod [\v!no] {\parindent\zeropoint}% was: \ctxparindent\noindent} +\defineindentingmethod [\v!not] {\parindent\zeropoint}% was: \ctxparindent\noindent} + +\defineindentingmethod [\v!first] {\indentfirstparagraphtrue} +\defineindentingmethod [\v!next] {\indentfirstparagraphfalse} + +\defineindentingmethod [\v!yes] {\parindent\ctxparindent\relax} % no \indent ! +\defineindentingmethod [\v!always] {\parindent\ctxparindent\relax} % no \indent ! + +\defineindentingmethod [\v!never] {\parindent\zeropoint\relax % no \indent ! + \chardef\indentingtoggle\zerocount} + +\defineindentingmethod [\v!odd] {\chardef\indentingtoggle\plusone} +\defineindentingmethod [\v!even] {\chardef\indentingtoggle\plustwo} + +\defineindentingmethod [\v!normal] {\ifx\normalindentation\empty\else + \let\currentindentation\normalindentation + \simplesetupindenting + \fi} + +\defineindentingmethod [\v!reset] {\indentfirstparagraphtrue + \parindent\zeropoint + \chardef\indentingtoggle\zerocount} + +\def\noindenting{\indenting[\v!no, \v!next ]} +\def\doindenting{\indenting[\v!yes,\v!first]} + +%D This one sets up the local indentation behaviour (i.e. either or not +%D a next paragraph will be indented). + +\def\dochecknextindentation#1% internal one + {\checknextindentation[\getvalue{#1\c!indentnext}]} + +\def\checknextindentation[#1]% + {\processaction + [#1] + [%\v!keep=>, + \v!yes=>\doindentation, + \v!no=>\noindentation, + \v!auto=>\autoindentation]} + +%D Here come the handlers. + +\newif\ifindentation \indentationtrue % documenteren, naar buiten + +\let\checkindentation\relax + +\ifx\autoindentation\undefined \let\autoindentation\relax \fi % hook + +\def\doindentation + {\gdef\checkindentation{\global\indentationtrue}} + +\def\noindentation % made global + {\ifinpagebody \else + \global\indentationfalse + \gdef\checkindentation + {\donoindentation + \gdef\checkindentation{\global\indentationtrue}}% + \fi} + +\def\nonoindentation % bv bij floats + {\ifinpagebody \else + \global\indentationtrue + \gdef\checkindentation{\global\indentationtrue}% + \fi} + +\def\donoindentation + {\ifdim\parindent=\zeropoint \else + \bgroup \setbox\scratchbox\lastbox \egroup + \fi} + +\def\indentation + {\ifvmode \ifdim\parindent=\zeropoint \else + % was : \hskip\parindent + % can be: \indent + % but we test: + \noindent\hskip\parindent + \fi \fi} + +\def\toggleindentation + {\ifcase\indentingtoggle + % nothing + \or + \notoggleindentation + \or + \dotoggleindentation + \fi} + +\def\dokillindentation + {\gdef\checkindentation{\global\indentationfalse\donoindentation}} + +\def\dotoggleindentation + {\gdef\checkindentation{\global\indentationfalse\notoggleindentation\donoindentation}} + +\def\notoggleindentation + {\gdef\checkindentation{\global\indentationtrue\dotoggleindentation}} + +\appendtoks + \pushmacro\checkindentation + \pushmacro\ifindentation +\to \everypushsomestate + +\appendtoks + \popmacro\ifindentation + \popmacro\checkindentation +\to \everypopsomestate + +% we need to save the state if we want to adapt behaviour to empty lines +% +% \def\setlasthvmode +% {\global\chardef\savedhvmode\ifhmode\plusone\else\ifvmode\plustwo\else\zerocount\fi\fi} +% +% \def\resetlasthvmode +% {\global\chardef\savedhvmode\zerocount} +% +% \chardef\savedhvmode\zerocount + +% This is a user requested hack (using the auto-hook). + +\chardef\recheckindentationmode\zerocount + +\def\dontrechecknextindentation + {\global\chardef\recheckindentationmode\zerocount} + +\def\dorechecknextindentation + {\ifcase\recheckindentationmode + % nothing + \or + \dontrechecknextindentation + \expandafter\doautoindentation + \fi} + +\def\doautoindentation + {\doifnextcharelse\par\donothing\noindentation} + +\def\autoindentation + {\global\chardef\recheckindentationmode\plusone} + +%D An example of usage: +%D +%D \starttyping +%D \setupindenting[small,yes] +%D +%D \setupitemize [indentnext=auto] +%D \setuptyping [indentnext=auto] +%D \setupformulas[indentnext=auto] +%D +%D \input tufte +%D +%D \startitemize +%D \item itemize +%D \stopitemize +%D \input tufte +%D +%D \startitemize +%D \item itemize +%D \stopitemize +%D +%D \input tufte +%D +%D \startitemize +%D \item itemize +%D \stopitemize +%D +%D \page +%D +%D \input tufte +%D +%D \starttyping +%D verbatim +%D \stoptyping +%D \input tufte +%D +%D \starttyping +%D verbatim +%D \stoptyping +%D +%D \input tufte +%D +%D \starttyping +%D verbatim +%D \stoptyping +%D +%D \page +%D +%D \input tufte +%D +%D \startformula +%D a = b +%D \stopformula +%D \input tufte +%D +%D \startformula +%D a = b +%D \stopformula +%D +%D \input tufte +%D +%D \startformula +%D a = b +%D \stopformula + + +%D \macros +%D {frenchspacing,nonfrenchspacing} +%D +%D Smehow \type{\frenchspacing} can lead to hyphenation between +%D dashes so we now have \type {\newfrenchspacing} (moved from +%D \type {syst-chr}). + +%D Hm ... todo: + +\sfcode`\)=0 +\sfcode`\'=0 +\sfcode`\]=0 + +\def\setfrenchspacing#1% + {\sfcode`\.#1 \sfcode`\,#1\relax + \sfcode`\?#1 \sfcode`\!#1\relax + \sfcode`\:#1 \sfcode`\;#1\relax} + +\def\frenchspacing + {\setfrenchspacing{1000}} + +\def\resetfrenchspacing + {\sfcode`\.3000 \sfcode`\,1250 + \sfcode`\?3000 \sfcode`\!3000 + \sfcode`\:2000 \sfcode`\;1500 } + +\def\frenchspacing {\setfrenchspacing{1000}} +\def\newfrenchspacing{\setfrenchspacing{1050}} +\def\nonfrenchspacing{\resetfrenchspacing} + +\def\definespacingmethod[#1]#2{\setvalue{\??sg\??sg#1}{#2}} + +\definespacingmethod[\v!packed]{\newfrenchspacing} +\definespacingmethod[\v!broad ]{\nonfrenchspacing} + +\def\complexsetupspacing[#1]% + {\executeifdefined{\??sg\??sg#1}\relax + \updateraggedskips} + +\def\simplesetupspacing + {\updateraggedskips} + +\definecomplexorsimple\setupspacing + +\let\normalspaceprimitive=\ % space-comment is really needed else \ + +\unexpanded\def\nonbreakablespace{\penalty\plustenthousand\normalspaceprimitive} + +\letcatcodecommand \ctxcatcodes `\~ \nonbreakablespace + +\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 + \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 + {\doifdefinedelse{\??ws\??ws\currentwhitespace}% no ifcsname due to nested \lineheight + {\getvalue{\??ws\??ws\currentwhitespace}}% + {\processcommacommand[\currentwhitespace]\dowhitespacemethod}% + \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% \doifdefined because of \lineheight + {\doifdefinedelse{\??ws\??ws#1}{\getvalue{\??ws\??ws#1}}{\ctxparskip#1}\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!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 % == default + {\normalspaces + \let\obeyedspace\normalspace + \let\ =\normalspaceprimitive} % was \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 + \doifnot\@@rgoption\v!packed{\global\let\afterfirstobeyedline\relax}}}% + \def\obeyedline + {\par + \futurelet\next\dobetweenthelines}% + \activatespacehandler\@@rgspace + \GotoPar} + +\def\stoplines + {\endgroup + \popmacro\checkindentation + \@@rgafter} + +\def\dobetweenthelines + {\doifmeaningelse\next\obeyedline + {\@@rginbetween} + {\afterfirstobeyedline}} + +\setuplines + [\c!option=, + \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/spac-grd.mkii b/tex/context/base/spac-grd.mkii new file mode 100644 index 000000000..249e2e430 --- /dev/null +++ b/tex/context/base/spac-grd.mkii @@ -0,0 +1,1074 @@ +%D \module +%D [ file=core-grd, +%D version=1998.03.10, +%D title=\CONTEXT\ Core Macros, +%D subtitle=Grid Snapping (Experimental), +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Grid Snapping} + +\unprotect + +%D Moved from supp-box: + +%D \macros +%D {startbaselinecorrection,baselinecorrection, +%D showbaselinecorrection,offbaselinecorrection} +%D +%D Spacing around ruled boxes can get pretty messed up. The +%D next macro tries as good as possible to fix this. +%D +%D \startbuffer[1] +%D \startbaselinecorrection +%D \ruledhbox{Rule Brittanica} +%D \stopbaselinecorrection +%D \stopbuffer +%D +%D \typebuffer[1] +%D +%D The macros put some white space around the box: +%D +%D \getbuffer[1] +%D +%D A simple alternative is \type {\baselinecorrection}, which +%D only looks at the previous line. +%D +%D \startbuffer[2] +%D \baselinecorrection +%D \ruledhbox{Rule Brittanica} +%D \baselinecorrection +%D \stopbuffer +%D +%D \typebuffer[2] +%D +%D This time the last preceding line gets a correction,% +%D dependant on the depth. +%D +%D \getbuffer[2] +%D +%D One can make the correction visible by saying \type +%D {\showbaselinecorrection}. Part of the correction is +%D calculated from the dimensions of a~(. One can disble the +%D correction by calling \type {\offbaselinecorrection}. +%D +%D When visualize the first example looks like: +%D +%D {\showbaselinecorrection\getbuffer[1]} +%D +%D and the second one comes out as: +%D +%D {\showbaselinecorrection\getbuffer[2]} + +% \definecolor[GridLineColor][red] +% \definecolor[GridTextColor][blue] + +\definepalet + [grid] + [ one=red, + two=green, + three=blue, + four=gray] + +\def\setbaselinecorrections + {\setbox0\hbox{\setstrut\strut}% + \setbox2\hbox{(}% + \dimen0\ht0\advance\dimen0 -\ht2 + \ifdim\dimen0<\zeropoint\dimen0\zeropoint\fi + \dimen2\dp0\advance\dimen2 -\dp2 + \ifdim\dimen2<\zeropoint\dimen2\zeropoint\fi + \edef\thetopbaselinecorrection {\the\dimen0}\dimen0-\dimen0 + \edef\thebotbaselinecorrection {\the\dimen2}\dimen2-\dimen2 + \edef\thenegtopbaselinecorrection{\the\dimen0}% + \edef\thenegbotbaselinecorrection{\the\dimen2}} + +\def\dotopbaselinecorrection {\kern\thetopbaselinecorrection} +\def\dobotbaselinecorrection {\kern\thebotbaselinecorrection} +\def\donegtopbaselinecorrection{\kern\thenegtopbaselinecorrection} +\def\donegbotbaselinecorrection{\kern\thenegbotbaselinecorrection} + +\def\showbaselinecorrection + {\def\dobaselinecorrection % visualization is not watertight! + {\bgroup +\ifdim\prevdepth>\zeropoint\kern-\prevdepth\fi + \setbox0\null + \wd0\hsize + \dp0\strutdp + \nointerlineskip + \forgetall + \ruledvbox{\box0}% + \egroup + \prevdepth\strutdp}% + \def\dotopbaselinecorrection + {\hrule\!!height\thetopbaselinecorrection}% + \def\dobotbaselinecorrection + {\hrule\!!height\thebotbaselinecorrection}} + +\def\dobaselinecorrection + {\ifdim\prevdepth>\zeropoint\kern-\prevdepth\fi + \kern\strutdp + \prevdepth\strutdp} + +% \def\baselinecorrection +% {\endgraf +% \ifvmode +% \ifdim\prevdepth<\maxdimen +% \ifdim\prevdepth<\zeropoint \else +% \ifdim\prevdepth<\strutdp +% \dobaselinecorrection +% \fi +% \fi +% \fi +% \fi} + +\def\baselinecorrection + {\endgraf + \ifvmode + \ifdim\prevdepth<\maxdimen + \ifdim\prevdepth<\zeropoint \else + \ifdim\prevdepth<\strutdepth \relax + \pushlastnode + \dobaselinecorrection + \poplastnode + \fi + \fi + \fi + \fi} + +\def\pagebaselinecorrection + {\ifdim\pagegoal<\maxdimen + \ifdim\pagetotal>\lineheight % or \topskip + \scratchdimen\pagetotal + \advance\scratchdimen\lineheight + \ifdim\scratchdimen<\pagegoal + \baselinecorrection + \fi + \fi + \fi} + +% Beware, keep this one as it is, see for instance module +% m-steps.tex, where we apply a \localhsize to the \vbox, in +% order to follow narrower and side floats ! + +% \def\startbaselinecorrection +% {\baselinecorrection +% \ifvmode +% \bgroup +% \setbox\scratchbox\vbox\bgroup +% \ignorespaces +% \let\stopbaselinecorrection\dostopbaselinecorrection +% \else +% \let\stopbaselinecorrection\relax +% \fi} + +% \def\dostopbaselinecorrection % I have to check columns yet. +% {\endgraf +% \egroup +% \topbaselinecorrection +% \box\scratchbox +% \botbaselinecorrection +% \egroup} + +% \let\stopbaselinecorrection=\relax + +\def\startbaselinecorrection + {\bgroup + \let\stopbaselinecorrection\egroup + \ifcase\baselinecorrectionmode + \or % normal + \baselinecorrection + \ifvmode + \setbox\scratchbox\vbox\bgroup\ignorespaces + \let\stopbaselinecorrection\donormalstopbaselinecorrection + \fi + \or % off + \or % force + \baselinecorrection + \ifvmode + \setbox\scratchbox\vbox\bgroup\ignorespaces + \let\stopbaselinecorrection\doforcedstopbaselinecorrection + \fi + \fi} + +\let\stopbaselinecorrection\relax + +\def\donormalstopbaselinecorrection % I have to check columns yet. + {\egroup + \topbaselinecorrection + \box\scratchbox + \botbaselinecorrection + \egroup} + +\def\doforcedstopbaselinecorrection % I have to check columns yet. + {\egroup + \forcedtopbaselinecorrection + \box\scratchbox + \forcedbotbaselinecorrection + \egroup} + +%D We do a bit more checking than needed. The pageborder check +%D is not needed, but I want to look the visualization as good +%D as possible too. + +% \def\offbaselinecorrection % Can be used inside correction. +% {\def\startbaselinecorrection{\bgroup\let\stopbaselinecorrection\egroup}} + +\chardef\baselinecorrectionmode\plusone + +\def\onbaselinecorrection {\chardef\baselinecorrectionmode\plusone } +\def\offbaselinecorrection {\chardef\baselinecorrectionmode\plustwo } +\def\forcebaselinecorrection{\chardef\baselinecorrectionmode\plusthree} + +%D \macros +%D {topbaselinecorrection,botbaselinecorrection} +%D +%D The actual top and bottom corrections are implemented as: + +% \def\topbaselinecorrection +% {\ifvmode \ifdim\pagegoal<\maxdimen +% \bgroup +% \setbaselinecorrections +% \whitespace +% \nointerlineskip +% \dotopbaselinecorrection +% \egroup +% \fi \fi} + + +\def\topbaselinecorrection + {\ifvmode \ifdim\pagegoal<\maxdimen + \forcedtopbaselinecorrection + \fi \fi} + +\def\forcedtopbaselinecorrection + {\ifvmode + \bgroup + \setbaselinecorrections + \whitespace + \nointerlineskip + \dotopbaselinecorrection + \egroup + \fi} + +\def\botbaselinecorrection + {\ifvmode + \bgroup + \setbaselinecorrections + \dobotbaselinecorrection + \allowbreak % new, otherwise problems when many in a row + \prevdepth\strutdp + \egroup + \fi} + +\let\forcedbotbaselinecorrection\botbaselinecorrection + +%D Still very experimental and therefore undocumented. + +\newif\ifgridsnapping % UNDER DEVELOPMENT, USE WITH CARE +\newif\ifforcepresnap \forcepresnaptrue % false in mixed single/double +\newif\ifstrutsnapping \strutsnappingtrue % sometimes handy to be false + +\def\positiveextrasnap {\gdef\extrasnapsign{+}} +\def\negativeextrasnap {\gdef\extrasnapsign{-}} + +\def\extrasnapreset {\global\chardef\@@extrasnap0 + \positiveextrasnap} +\def\extrasnapbefore {\global\chardef\@@extrasnap1 } +\def\extrasnaparound {\global\chardef\@@extrasnap2 } +\def\extrasnapafter {\global\chardef\@@extrasnap3 } + +\def\enablepresnapcorrection {\global\chardef\@@presnap\zerocount} +\def\disablepresnapcorrection {\global\chardef\@@presnap\plusone} + +\extrasnapreset \enablepresnapcorrection + +\newif\iftracegridsnapping +\newif\ifshowgridboxes +\newif\ifshowfuzzyskips + +\let\showgridboxes\showgridboxestrue + +\def\showgridsnapping + {\tracegridsnappingtrue + \showgridboxestrue} + +\chardef\@@alignsnap =0 +\chardef\@@alignsnapbox =0 +\chardef\@@alignsnapmethod=0 + +\let\presnapskip \!!zeropoint \def\presnap {-} +\let\postsnapskip\!!zeropoint \let\postsnap\presnap + +\newcount\currentgridsnap + +\def\tracedsnapping + {\iftracegridsnapping + \llap + {\startlayoutcomponent{gridsnaps}{grid snaps}% + \infofont + \global\advance\currentgridsnap\plusone + \color[grid:three]{\vl\presnapskip + \vl\presnap + \vl\postsnap + \ifcase\@@alignsnapbox\relax + \vl\ifcase\@@extrasnap + 00\or + \extrasnapsign0\or + \extrasnapsign\extrasnapsign\or + 0\extrasnapsign\fi + \fi + \vl\the\currentgridsnap\vl}% + \stoplayoutcomponent}% + \fi} + +\def\snaptogrid% [#1]#2 -> #2 == \hbox|\vbox + {\dosingleempty\dosnaptogrid} + +% \def\dosnaptogrid[#1]% +% {\ifgridsnapping +% \iffirstargument\doifsomething{#1}{\verplaatsopgrid[#1]}\fi +% \expandafter\dodosnaptogrid +% \fi} + +% \def\dosnaptogrid[#1]% +% {\resetlastlinewidth % maybe in more places, otherwise spacing gets messed up +% \ifgridsnapping +% \iffirstargument\doifsomething{#1}{\moveongrid[#1]}\fi +% \expandafter\dodosnaptogrid +% \fi} + +\def\dosnaptogrid[#1]% + {\resetlastlinewidth % maybe in more places, otherwise spacing gets messed up + \doifinsetelse\v!force{#1}% + {\moveongrid[#1]% + \dodosnaptogrid} + {\ifgridsnapping + \doifsomething{#1}{\moveongrid[#1]}% + \expandafter\dodosnaptogrid + \fi}} + +% \def\forcedpresnapcorrection % test this on 'details' +% {\ifforcepresnap +% \ifvmode \else \par \fi % new +% % we don't want top of page space when 'top' option +% %\verticalstrut\nobreak\vskip-\struttotal +% %\verticalstrut\vskip-\struttotal +% % nobreak really needed +% \allowbreak\verticalstrut\nobreak\vskip-\struttotal +% %\ifdim\pagetotal>\topskip \else +% % eigenlijk signal +% %\writestatus{grid}{removing dummy at top of page}% +% %\bgroup +% %\output{\setbox\scratchbox\box255}% +% %\penalty\outputpenalty +% %\egroup +% %\fi +% \fi} + +\def\forcedpresnapcorrection % test this on 'details' + {\ifforcepresnap + \ifvmode \else \par \fi % new + % we don't want top of page space when 'top' option + % \verticalstrut\nobreak\vskip-\struttotal + % \verticalstrut\vskip-\struttotal + % \nobreak really needed + % \dosomebreak\allowbreak % no: spoils heads, so only under know situation, not in snapper + \verticalstrut + \nobreak + \vskip-\struttotal + %\ifdim\pagetotal>\topskip \else + % eigenlijk signal + %\writestatus{grid}{removing dummy at top of page}% + %\bgroup + %\output{\setbox\scratchbox\box255}% + %\penalty\outputpenalty + %\egroup + %\fi + \fi} + +\def\setgridtracebox#1[#2]% % maybe reverse the order + {\setbox\nextbox#1% + {\hbox + {\hbox to \zeropoint + {\startlayoutcomponent{gridsnaps}{grid snaps}% + \color[grid:#2]{\ruledhbox{\fakebox\nextbox}}% + \stoplayoutcomponent + \hss}% + \flushnextbox}}} + +\newif\ifboxedsnapping \boxedsnappingtrue + +\chardef\depthsnapmethod \plusone % downward compatible, minus one line +\chardef\heightsnapmethod\plusone % downward compatible, minus one line + +\def\dodosnaptogrid + {\dowithnextbox + {\bgroup + \ifcase\@@alignsnapmethod \or + % we're dealing with text with a possible big depth/height + \chardef\depthsnapmethod \plustwo + \chardef\heightsnapmethod\plustwo + \fi + \ifdim\nextboxht<\textheight % handle special case (like page fig) + \ifcase\@@alignsnapbox\relax + \ifcase\@@alignsnap\else % 1=top 2=high 3=middle 4=low + \ifshowgridboxes + \setgridtracebox\hbox[two]% + \fi + %\getnoflines{\nextboxht}% + \getnoflines\nextboxht + \setbox\nextbox\vbox to \noflines\lineheight + {\ifnum\@@alignsnap=1 \kern\lineheight\kern-\topskip\fi + \ifnum\@@alignsnap>2 \vfill\fi + \flushnextbox + \ifnum\@@alignsnap<4 \vfill\fi}% + \fi + \ifshowgridboxes + \setgridtracebox\hbox[three]% + \fi + \forgetall + \par + \ifvbox\nextbox + \setbox\nextbox\hbox{\flushnextbox}% don't ask + \fi + \scratchskip\lastskip + \edef\presnapskip{\the\lastskip}% + % mixing single/double columns sometimes goes wrong, + % check 'som' document + \ifinsidecolumns + \forcepresnaptrue + \fi + \forcedpresnapcorrection + \ifdim\nextboxht>\strutht + \scratchdimen\nextboxht + \ifcase\@@presnap\relax + \ifdim\scratchskip>\zeropoint\relax + \scratchcounter\scratchskip + \advance\scratchcounter -\openlineheight + \ifnum\scratchcounter<0 + \scratchcounter-\scratchcounter + \fi + \ifnum\scratchcounter<10 % \lastkip is about \openlineheight + \advance\scratchdimen -\openstrutdepth + \edef\presnapskip{*\presnapskip}% + \else\ifdim\scratchskip>\openlineheight + %<\openlineheight \else + \advance\scratchdimen -\openstrutdepth + \edef\presnapskip{*\presnapskip}% + \fi\fi + \fi + \fi + % \getnoflines\scratchdimen % maybe raw ? + % \advance\noflines -1 + \ifcase\heightsnapmethod + % raw + \or + \advance\scratchdimen-\lineheight % tight (default) + \or + \advance\scratchdimen-\strutheight % fit (text) + \or + \advance\scratchdimen-\strutheight % tolerant + \advance\scratchdimen-\roundingeps + \fi + \getnoflines\scratchdimen + \ifnum\noflines>0 + \scratchdimen\noflines\lineheight + \else + \scratchdimen\zeropoint + \fi + \else + \scratchdimen\zeropoint + \fi + \ifnum\@@extrasnap=1 \advance\scratchdimen \extrasnapsign \lineheight \fi + \ifnum\@@extrasnap=2 \advance\scratchdimen \extrasnapsign.5\lineheight \fi + \edef\presnap{\the\scratchdimen}% + \ifstrutsnapping + \ifboxedsnapping + \getrawnoflines\scratchdimen + \advance\scratchdimen-\noflines\lineheight + \vskip\scratchdimen % disappears at top of page + \dorecurse\noflines{\verticalstrut\nobreak}% + \else \ifdim\scratchdimen=\zeropoint + % nothing to skip + \else % disappears at top of page + \vskip\scratchdimen + \fi \fi + \fi + \ifdim\nextboxdp>\strutdp + % \getnoflines\nextboxdp + % \advance\noflines \minusone + \scratchdimen\nextboxdp\relax + \ifcase\depthsnapmethod + % raw + \or + \advance\scratchdimen-\lineheight % tight (default) + \or + \advance\scratchdimen-\strutdepth % fit (text) + \or + \advance\scratchdimen-\strutdepth % tolerant + \advance\scratchdimen-\roundingeps + \fi + \getnoflines\scratchdimen + \ifnum\noflines>0 + \scratchdimen\noflines\lineheight + \else + \scratchdimen\zeropoint + \fi + \else + \scratchdimen\zeropoint + \fi + \ifnum\@@extrasnap=2 \advance\scratchdimen \extrasnapsign.5\lineheight \fi + \ifnum\@@extrasnap=3 \advance\scratchdimen \extrasnapsign \lineheight \fi + \edef\postsnap{\the\scratchdimen}% + \ifstrutsnapping + \nextboxht\strutht + \nextboxdp\strutdp + \else + \scratchdimen\presnap + \advance\scratchdimen \strutht + \nextboxht\scratchdimen + \scratchdimen\postsnap + \advance\scratchdimen \strutdp + \nextboxdp\scratchdimen + \fi + \hbox{\tracedsnapping\flushnextbox}% + \ifstrutsnapping + \ifdim\scratchdimen=\zeropoint\else\vskip\scratchdimen\fi + \fi + \else + \scratchdimen\nextboxht\relax + \ifcase\@@alignsnapbox + % can't happen here + \or + \getrawnoflines\scratchdimen + \else + \getnoflines \scratchdimen + \fi + \scratchdimen\noflines\lineheight\relax + \advance\scratchdimen-\strutdepth + % spoils the whole game (fit/broad/line) + % \ifnum\pagetotal>\zeropoint \else % disable this as option + % \advance\scratchdimen-\strutheight + % \advance\scratchdimen+\topskip + % \fi + \dimen0=\scratchdimen + \dimen2=\strutdepth + \ifshowgridboxes + \setgridtracebox\hbox[two]% + \fi + \nextboxdp\strutdp + \dimen4=\nextboxht + \dimen6=\nextboxdp + \iftracegridsnapping + \setbox\scratchbox\hbox + {\scratchdimen\@@alignsnapamount\relax + \ifdim\scratchdimen<\zeropoint + \tracedgridamount\zeropoint{-\scratchdimen}% + \else + \tracedgridamount\scratchdimen\zeropoint + \fi}% + \smashbox\scratchbox + \setbox\nextbox\hbox{\box\scratchbox\flushnextbox}% + \fi + \setbox\nextbox\hbox + {\scratchdimen\@@alignsnapamount\relax + \ifcase\@@alignsnapdepth\or + % don't change this ever ! + \ifdim\dimen0<\lineheight + % otherwise it is ok, but ending up inside + % the next paragraph is seldom what we want, + % so we move one line up + \advance\scratchdimen-\lineheight + \advance\scratchdimen\strutheight + \else + % otherwise we can move down to the + % baseline + \advance\scratchdimen\dimen6 % == \strutdepth + \fi + \fi + \lower\scratchdimen\flushnextbox}% + \nextboxht\dimen4 + \nextboxdp\dimen6 + \ifnum\@@alignsnap<4 % 4 = regel + \setbox\nextbox\vbox to \scratchdimen + {\forgetall + \ifnum\@@alignsnap>2 \vfill\fi % 3 4 + \flushnextbox + \nointerlineskip % \offinterlineskip + \ifnum\@@alignsnap<4 \vfill\fi % 2 3 + \kern\zeropoint}% + \fi + \ifshowgridboxes + \setgridtracebox\vbox[three]% + \fi + \scratchdimen\@@alignsnapamount + \edef\presnapskip{\the\scratchdimen}% + \ifnum\@@alignsnap>2 \def\presnap {+}\fi + \ifnum\@@alignsnap<4 \def\postsnap{+}\fi + \setbox\nextbox\hbox{\tracedsnapping\flushnextbox}% + \par + \nextboxht\dimen0 + \nextboxdp\dimen2 + \forcedpresnapcorrection + \nointerlineskip + \flushnextbox + \fi + \else + \setbox\nextbox\vbox to \textheight + {\ifdim\nextboxdp=\zeropoint + \hbox{\lower\strutdepth\flushnextbox} + \else % this branch is yet untested + \vss + \hbox{\lower\nextboxdp\flushnextbox} + \vskip-\strutdepth + \fi}% + \nextboxdp\strutdepth + \flushnextbox + \fi + \extrasnapreset + \enablepresnapcorrection + \global\chardef\@@alignsnap\zerocount + \global\chardef\@@alignsnapbox\zerocount + \egroup}} + +\def\tracedgridamount#1#2% + {\startlayoutcomponent{gridsnaps}{grid snaps}% + \color[grid:four]{\vrule\!!width\nextboxwd\!!height#1\!!depth#2}% + \stoplayoutcomponent} + +\def\snaptomathgrid % probably not working ok, also kind of obsolete + {\ifgridsnapping + \dowithnextbox + {\blank[\v!line]\snaptogrid\vbox{\flushnextbox}\blank[\v!line]} + \vbox\bgroup + \forgetdisplayskips + \@EA\let\@EA\next + \fi} + +\def\topsnaptogrid + {\ifgridsnapping + \dowithnextbox + {\scratchdimen\nextboxht + \advance\scratchdimen -\strutht + \advance\scratchdimen \topskip + \nextboxht\scratchdimen + \nextboxdp\zeropoint + \flushnextbox + \kern\lineheight + \kern-\topskip + \nointerlineskip} + \hbox + \fi} + +% \def\centertogrid % meant for special situations +% {\ifgridsnapping +% \dowithnextboxcontent +% {\ignorespaces} +% {\bgroup +% \par +% \scratchdimen\nextboxht +% \advance\scratchdimen \nextboxdp +% \getnoflines\scratchdimen +% \setbox\nextbox\vbox to \noflines\lineheight +% {\forgetall +% \vskip\zeropoint \!!plus \nextboxht +% \copy\nextbox +% \kern.5\strutdp % VOORLOPIGE WAARDE +% \vskip\zeropoint \!!plus \nextboxdp}% +% \noindent\snaptogrid\vbox{\flushnextbox}% +% \egroup} +% \vbox % was \hbox +% \fi} + +% The next implementation is sub-optimal +% +% \def\centertogrid % usage: see ie pascal / stepcharts +% {\snaptogrid[\v!midden,.5\strutdp]\vbox} + +\def\centertogrid % meant for special situations + {\ifgridsnapping + \dowithnextboxcontent + {\ignorespaces} + {\bgroup + \par + \scratchdimen\nextboxht + \advance\scratchdimen \nextboxdp + \getnoflines\scratchdimen + \setbox\nextbox\vbox to \noflines\lineheight + {\forgetall + \vss + \topbaselinecorrection + \copy\nextbox + \botbaselinecorrection + \vss}% + \setbox\nextbox\hbox{\lower\strutdp\flushnextbox}% + \forgeteverypar % new per 3/4/2008, prevents duplicate pos nodes resulting in extra whitespace + \noindent\snaptogrid\vbox{\flushnextbox}% + \egroup} + \vbox % was \hbox + \fi} + +% testbed for \centertogrid +% +% \strut Bruggetje +% \startlinecorrection +% \startcombination +% {\framed{test}} {} {\framed{test}} {} +% \stopcombination +% \stoplinecorrection +% \strut Bruggetje +% \startlinecorrection +% \startcombination[2*2] +% {\framed{test}} {} {\framed{test}} {} +% {\framed{test}} {} {\framed{test}} {} +% \stopcombination +% \stoplinecorrection +% \strut Bruggetje +% \startlinecorrection[blank] +% \startcombination +% {\framed{test}} {} {\framed{test}} {} +% \stopcombination +% \stoplinecorrection +% \strut Bruggetje +% \startlinecorrection[blank] +% \startcombination[2*2] +% {\framed{test}} {} {\framed{test}} {} +% {\framed{test}} {} {\framed{test}} {} +% \stopcombination +% \stoplinecorrection +% \strut Bruggetje +% \startlinecorrection +% \startcombination +% {\framed[lines=1]{test}} {} {\framed[lines=1]{test}} {} +% \stopcombination +% \stoplinecorrection +% \strut Bruggetje +% \startlinecorrection +% \startcombination[2*2] +% {\framed[lines=1]{test}} {} {\framed[lines=1]{test}} {} +% {\framed[lines=1]{test}} {} {\framed[lines=1]{test}} {} +% \stopcombination +% \stoplinecorrection +% \strut Bruggetje +% \startlinecorrection[blank] +% \startcombination +% {\framed[lines=1]{test}} {} {\framed[lines=1]{test}} {} +% \stopcombination +% \stoplinecorrection +% \strut Bruggetje +% \startlinecorrection[blank] +% \startcombination[2*2] +% {\framed[lines=1]{test}} {} {\framed[lines=1]{test}} {} +% {\framed[lines=1]{test}} {} {\framed[lines=1]{test}} {} +% \stopcombination +% \stoplinecorrection + +\ifx\startbaselinecorrection\undefined \wait \fi % change order + +\let\normalstartbaselinecorrection=\startbaselinecorrection + +\def\startbaselinecorrection + {\ifgridsnapping + \centertogrid\bgroup + \let\stopbaselinecorrection\egroup + \else + \normalstartbaselinecorrection + \fi} + +\chardef\gridboxlinenomode\plusone +\chardef\gridboxlinemode \plusone % 0:nothing 1:all 2:lines 3:frame + +\def\gridboxvbox {\ifcase\gridboxlinemode\vbox\or\ruledvbox\or\vbox\or\ruledvbox\else\ruledvbox\fi} +\def\gridboxwidth{\ifcase\gridboxlinemode0\or.5\or.5\or0\else.5\fi\testrulewidth} + +\def\setgridbox#1#2#3% + {\setbox#1\gridboxvbox to #3 % given size + {\forgetall + \resetteststrut + \offinterlineskip + \hsize#2% + \baselinerulefalse + \gridboxvbox % calculated size + {\getrawnoflines{#3}% \getnoflines{#3}% + \vskip\topskip + \vskip-\strutht + \scratchdimen#2\advance\scratchdimen \lineheight + \dorecurse\noflines + {\strut + \hskip-.5\lineheight + \ifcase\gridboxlinenomode\or + \rlap + {\hskip.2\bodyfontsize\hskip\scratchdimen + \infofont\hbox to 1em{\hss\recurselevel}}% + \or + \llap + {\infofont\hbox to 1em{\hss\recurselevel}% + \hskip.2\bodyfontsize}% + \fi + \vrule + \!!height \gridboxwidth + \!!depth \gridboxwidth + \!!width \scratchdimen + \par}} + \vfill}} + +%D Some intervention macros: + +\def\gridwarning#1{\message{[beware of #1 extra snap]}} + +\global\let\@@alignsnapamount\!!zeropoint +\global\chardef\@@alignsnapdepth0 + +\def\@@unknowngriddisplacement + {\global\chardef\@@alignsnapbox\plusthree + \global\let\@@alignsnapamount\commalistelement} + +\def\domoveongrid[#1]% + {\ifgridsnapping\doifsomething{#1}{\dodomoveongrid[#1]}\fi} + +\def\dodomoveongrid[#1]% some day : speed up + {\global\chardef\@@alignsnap\zerocount + \global\chardef\@@alignsnapbox\zerocount + \global\chardef\@@alignsnapdepth\zerocount + \global\chardef\@@alignsnapmethod\zerocount + \global\let\@@alignsnapamount\!!zeropoint + \donefalse + \expanded{\processallactionsinset[#1]} + [\v!standard=>, + \v!normal=>, % to be sure + \v!yes=>, % to be sure + \v!top=>\gridwarning+\positiveextrasnap\extrasnapbefore, + \v!bottom=>\gridwarning+\positiveextrasnap\extrasnapafter, + \v!both=>\positiveextrasnap\extrasnaparound, + -\v!top=>\gridwarning-\negativeextrasnap\extrasnapbefore, + -\v!bottom=>\gridwarning-\negativeextrasnap\extrasnapafter, + -\v!both=>\negativeextrasnap\extrasnaparound, + \v!text=>\global\chardef\@@alignsnapmethod\plusone, % accurate calculations + \v!page=>\global\chardef\@@alignsnap\plusone, % topskip + \v!high=>\global\chardef\@@alignsnap\plustwo, + \v!middle=>\global\chardef\@@alignsnap\plusthree, + \v!low=>\global\chardef\@@alignsnap\plusfour, + \v!fit=>\global\chardef\@@alignsnapbox\plusone, % new + \v!broad=>\global\chardef\@@alignsnapbox\plustwo, % new + \v!depth=>\global\chardef\@@alignsnapdepth\plusone, % new + \v!line=>\global\chardef\@@alignsnapbox\plusthree +% \global\chardef\@@alignsnapdepth\plusone + \global\chardef\@@alignsnap\plusfour, + \v!reset=>\positiveextrasnap\extrasnapreset, + \v!none=>\global\chardef\@@alignsnap\zerocount + \global\chardef\@@alignsnapbox\zerocount, + \v!force=>, % turns on grid snapping even when not on + \s!default=>, + \s!unknown=>\@@unknowngriddisplacement]} + +\def\moveongrid + {\dosingleempty\domoveongrid} + +\def\doplaceongrid[#1]% + {\domoveongrid[#1]\snaptogrid\vbox} + +\def\placeongrid + {\dosingleempty\doplaceongrid} + +%D Snapping is rather robust as long as we use whole lines. +%D Half lines of white space can however be handled when they +%D come in pairs. The corrections needed when crossing page +%D boundaries in the middle of such a pair, are handled by +%D macros that are (named) sort of fuzzy. This fuzzy mechanism +%D was written as an extension to the grid typesetting needed +%D for typesetting (part of) the \MAPS. +%D +%D \starttyping +%D \setuptyping +%D [before={\blank[halfline]}, +%D after={\blank[halfline]}] +%D \stoptyping + +\newif \iffuzzyvskip +\newif \iffuzzysnapdone +\newif \iffuzzysnapping +\newif \iffuzzysnapped +\chardef \fuzzysnappedleft=0 % ==1 when fuzzybegin still open +\newpersistentmark\fuzzymark % (!) +\newcount \fuzzymarker +\newbox \fuzzysnapbox +\newbox \fuzzysnapsplit + +\def\dosyncfuzzyvskip + {\ifvmode\ifdim\lastskip<\lineheight\ifdim\lastskip>\zeropoint + \bgroup % - added 28/2/2003: check this, there was no - + \endgraf\forgetall\verticalstrut\nobreak\vskip-\struttotal + \egroup + \fi\fi\fi} + +\def\fuzzyvskip#1% + {\iffuzzysnapdone + \dosyncfuzzyvskip % NEWER + \endfuzzysnapping + \vskip#1\relax + \global\fuzzysnapdonefalse + \else + \vskip#1\relax + \beginfuzzysnapping + \global\fuzzysnapdonetrue + \fi} + +\def\setfuzzymark#1#2#3% #1/#2 => error recovery + {\ifgridsnapping + \global\fuzzysnappingtrue + \global\advance\fuzzymarker \ifodd\fuzzymarker#1\else#2\fi + \nobreak + \ifshowfuzzyskips + \hbox{\color[grid:three] + {\llap{\infofont#3\vl\the\fuzzymarker}\nobreak + \vrule\!!width\hsize\!!height.1\lineheight}} + \nobreak + \fi + %[\the\fuzzymarker] + %\expandafter\fuzzymark\expandafter{\the\fuzzymarker}% + \expandafter\rawsetmark\expandafter\fuzzymark\expandafter{\the\fuzzymarker}% + \nobreak + \fi} + +\def\beginfuzzysnapping{\setfuzzymark21\v!start} % odd +\def\endfuzzysnapping {\setfuzzymark12\v!stop } % even + +\def\removelastfuzzyvskip + {\ifgridsnapping + \iffuzzysnapping + \ifdim\lastskip<\openlineheight + \else + \removelastskip + \fi + \else + \removelastskip + \fi + \else + \removelastskip + \fi} + +\def\docheckfuzzysnap#1% + {\bgroup + \dontcomplain + \setbox\fuzzysnapbox\copy#1\relax + \setbox\fuzzysnapsplit\vsplit\fuzzysnapbox to 1\lineheight + \let\topfuzzymark\empty % indeed here ... no real mark + \getsplitmarks\fuzzymark +% \ifcase0\topfuzzymark + \ifcase0\rawgetsplittopmark\fuzzymark + \global\chardef\fuzzysnappedleft\zerocount + \global\fuzzysnappedfalse +% \else\ifodd\topfuzzymark + \else\ifodd\rawgetsplittopmark\fuzzymark + \global\chardef\fuzzysnappedleft\plusone + \global\fuzzysnappedtrue + \else + \global\chardef\fuzzysnappedleft=2 + \global\fuzzysnappedtrue + \fi\fi + \iffuzzysnapped \else + \doloop + {\ifvoid\fuzzysnapbox + \exitloop + \else + \setbox\fuzzysnapsplit=\vsplit\fuzzysnapbox to \lineheight + %\let\topfuzzymark=\empty % ... but not here + \getsplitmarks\fuzzymark +% \ifcase0\topfuzzymark + \ifcase0\rawgetsplittopmark\fuzzymark + % continue +% \else\ifodd\topfuzzymark + \else\ifodd\rawgetsplittopmark\fuzzymark + \exitloop + \else + \global\chardef\fuzzysnappedleft\plusone + \global\fuzzysnappedtrue + \exitloop + \fi\fi + \fi}% + \fi + \egroup} + +\def\getfuzzysnapcorrection#1% + {\global\let\presnapcorrection \relax + \global\let\postsnapcorrection\relax + \ifgridsnapping\iffuzzysnapping + \docheckfuzzysnap{#1}% + \iffuzzysnapped + \iftracegridsnapping + \gdef\presnapcorrection + {\color[grid:four]{\hrule\!!height.5\openlineheight\!!width\hsize}}% + \else + \gdef\presnapcorrection{\kern.5\openlineheight}% + \fi + \gdef\postsnapcorrection{\kern-.5\openlineheight}% get the height ok + \fi + \fi\fi} + +\def\fuzzysnappedbox#1#2% \box \unvbox + {\getfuzzysnapcorrection{#2}% + \presnapcorrection + #1#2% + \postsnapcorrection} + +\def\adaptfuzzypagegoal + {\ifgridsnapping\iffuzzysnapping\ifcase\fuzzysnappedleft\or % see dopagecontents + \scratchdimen\pagegoal + \advance\scratchdimen -.5\openlineheight + \global\pagegoal\scratchdimen + \global\advance\vsize -.5\openlineheight + \global\chardef\fuzzysnappedleft0 + \fi\fi\fi} + +%D New, experimental, used in caption snapping: +%D +%D \starttyping +%D \startcolumnset +%D +%D \setupcaption[figure][style=\tfx\setupinterlinespace,inbetween=,grid=top] +%D +%D \placefigure [lrtb] {\dorecurse{5}{green gras}} +%D {\externalfigure[dummy][width=\textwidth,height=3cm,grid=height]} +%D \placefigure [lrtb] {\dorecurse{15}{green gras}} +%D {\externalfigure[dummy][width=\textwidth,height=3cm,grid=height]} +%D +%D \setupcaption[figure][style=\tfx\setupinterlinespace,inbetween=,grid=bottom] +%D +%D \placefigure [rltb] {\dorecurse{5}{green gras}} +%D {\externalfigure[dummy][width=\textwidth,height=3cm,grid=height]} +%D \placefigure [rltb] {\dorecurse{15}{green gras}} +%D {\externalfigure[dummy][width=\textwidth,height=3cm,grid=height]} +%D +%D \input thuan +%D +%D \stopcolumnset +%D \stoptyping + +\def\moveboxontogrid#1#2#3% box method firstlineht % experimental ! ! ! + {\doifsomething{#2} + {\getnoflines{\ht#1}% no depth taken into account, depth preserved + \scratchdimen\noflines\lineheight + \advance\scratchdimen-\strutdp + \bgroup + \advance\scratchdimen-\onepoint % be a bit tolerant + \ifdim\scratchdimen>\ht#1\relax + \egroup + \doif{#2}\v!top {\setbox#1\vbox to \scratchdimen{\vskip-#3\vskip\strutht\box#1\vfill}}% + \doif{#2}\v!bottom{\setbox#1\vbox to \scratchdimen{\vfill\box#1\removedepth}}% + \dp#1\strutdp + \else + \egroup + \ht#1\scratchdimen + \dp#1\strutdp + \fi}} + +%D New: + +\let\checkgridsnapping\relax + +\protect \endinput diff --git a/tex/context/base/spac-grd.mkiv b/tex/context/base/spac-grd.mkiv new file mode 100644 index 000000000..bd5c51a85 --- /dev/null +++ b/tex/context/base/spac-grd.mkiv @@ -0,0 +1,259 @@ +%D \module +%D [ file=spac-grd, +%D version=2009.10.16, % 1998.03.10, was core-grd.tex +%D title=\CONTEXT\ Spacing Macros, +%D subtitle=Grid Snapping, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 be merged intio spac-ver.mkiv. + +\writestatus{loading}{ConTeXt Spacing Macros / Grid Snapping} + +% buff-ver.mkiv: halfline spacing +% strc-mat.mkiv: configure math grid (new code needed) +% page-one.mkiv: to be checked +% page-mul.mkiv: to be checked and redone +% page-sid.mkiv: to be checked +% page-set.mkiv: to be checked +% strc-not.mkiv: to be checked +% strc-ren.mkiv: to be checked +% strc-flt.mkiv: to be checked (captions, probably top/bottom) +% core-mis.mkiv: to be checked (placement, probbaly harmless) + +\unprotect + +%D Helpers: + +\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 Moved from supp-box: + +%D \macros +%D {startbaselinecorrection,baselinecorrection, +%D showbaselinecorrection,offbaselinecorrection} +%D +%D Spacing around ruled boxes can get pretty messed up. The +%D next macro tries as good as possible to fix this. +%D +%D \startbuffer[1] +%D \startbaselinecorrection +%D \ruledhbox{Rule Brittanica} +%D \stopbaselinecorrection +%D \stopbuffer +%D +%D \typebuffer[1] +%D +%D The macros put some white space around the box: +%D +%D \getbuffer[1] +%D +%D A simple alternative is \type {\baselinecorrection}, which +%D only looks at the previous line. +%D +%D \startbuffer[2] +%D \baselinecorrection +%D \ruledhbox{Rule Brittanica} +%D \baselinecorrection +%D \stopbuffer +%D +%D \typebuffer[2] +%D +%D This time the last preceding line gets a correction,% +%D dependant on the depth. +%D +%D \getbuffer[2] +%D +%D One can make the correction visible by saying \type +%D {\showbaselinecorrection}. Part of the correction is +%D calculated from the dimensions of a~(. One can disble the +%D correction by calling \type {\offbaselinecorrection}. +%D +%D When visualize the first example looks like: +%D +%D {\showbaselinecorrection\getbuffer[1]} +%D +%D and the second one comes out as: +%D +%D {\showbaselinecorrection\getbuffer[2]} + +% \definecolor[GridLineColor][red] +% \definecolor[GridTextColor][blue] + +\let\thetopbaselinecorrection \!!zeropoint +\let\thebotbaselinecorrection \!!zeropoint +\let\thenegtopbaselinecorrection\!!zeropoint +\let\thenegbotbaselinecorrection\!!zeropoint + +\def\setbaselinecorrections + {\setbox0\hbox{\setstrut\strut}% + \setbox2\hbox{(}% + \dimen0\ht0\advance\dimen0 -\ht2 + \ifdim\dimen0<\zeropoint\dimen0\zeropoint\fi + \dimen2\dp0\advance\dimen2 -\dp2 + \ifdim\dimen2<\zeropoint\dimen2\zeropoint\fi + \edef\thetopbaselinecorrection {\the\dimen0}\dimen0-\dimen0 + \edef\thebotbaselinecorrection {\the\dimen2}\dimen2-\dimen2 + \edef\thenegtopbaselinecorrection{\the\dimen0}% + \edef\thenegbotbaselinecorrection{\the\dimen2}} + +\def\dotopbaselinecorrection {\kern\thetopbaselinecorrection} +\def\dobotbaselinecorrection {\kern\thebotbaselinecorrection} +\def\donegtopbaselinecorrection{\kern\thenegtopbaselinecorrection} +\def\donegbotbaselinecorrection{\kern\thenegbotbaselinecorrection} + +\def\showbaselinecorrection + {\def\dobaselinecorrection % visualization is not watertight! + {\bgroup +\ifdim\prevdepth>\zeropoint\kern-\prevdepth\fi + \setbox0\null + \wd0\hsize + \dp0\strutdp + \nointerlineskip + \forgetall + \ruledvbox{\box0}% + \egroup + \prevdepth\strutdp}% + \def\dotopbaselinecorrection + {\hrule\!!height\thetopbaselinecorrection}% + \def\dobotbaselinecorrection + {\hrule\!!height\thebotbaselinecorrection}} + +\def\dobaselinecorrection + {\ifdim\prevdepth>\zeropoint\kern-\prevdepth\fi + \kern\strutdp + \prevdepth\strutdp} + +\def\baselinecorrection + {\endgraf + \ifvmode + \ifdim\prevdepth<\maxdimen + \ifdim\prevdepth<\zeropoint \else + \ifdim\prevdepth<\strutdepth \relax + \pushlastnode + \dobaselinecorrection + \poplastnode + \fi + \fi + \fi + \fi} + +\def\pagebaselinecorrection + {\ifdim\pagegoal<\maxdimen + \ifdim\pagetotal>\lineheight % or \topskip + \scratchdimen\pagetotal + \advance\scratchdimen\lineheight + \ifdim\scratchdimen<\pagegoal + \baselinecorrection + \fi + \fi + \fi} + +\unexpanded\def\startbaselinecorrection + {\bgroup + \let\stopbaselinecorrection\egroup + \ifcase\baselinecorrectionmode + \or % normal + \baselinecorrection + \ifvmode + \setbox\scratchbox\vbox\bgroup\ignorespaces + \let\stopbaselinecorrection\donormalstopbaselinecorrection + \fi + \or % off + \or % force + \baselinecorrection + \ifvmode + \setbox\scratchbox\vbox\bgroup\ignorespaces + \let\stopbaselinecorrection\doforcedstopbaselinecorrection + \fi + \fi} + +\let\stopbaselinecorrection\relax + +\def\donormalstopbaselinecorrection % I have to check columns yet. + {\egroup + \topbaselinecorrection + \box\scratchbox + \botbaselinecorrection + \egroup} + +\def\doforcedstopbaselinecorrection % I have to check columns yet. + {\egroup + \forcedtopbaselinecorrection + \box\scratchbox + \forcedbotbaselinecorrection + \egroup} + +%D We do a bit more checking than needed. The pageborder check +%D is not needed, but I want to look the visualization as good +%D as possible too. + +\chardef\baselinecorrectionmode\plusone + +\def\onbaselinecorrection {\chardef\baselinecorrectionmode\plusone } +\def\offbaselinecorrection {\chardef\baselinecorrectionmode\plustwo } +\def\forcebaselinecorrection{\chardef\baselinecorrectionmode\plusthree} + +%D \macros +%D {topbaselinecorrection,botbaselinecorrection} +%D +%D The actual top and bottom corrections are implemented as: + +\def\topbaselinecorrection + {\ifvmode \ifdim\pagegoal<\maxdimen + \forcedtopbaselinecorrection + \fi \fi} + +\def\forcedtopbaselinecorrection + {\ifvmode + \bgroup + \setbaselinecorrections + \whitespace + \nointerlineskip + \dotopbaselinecorrection + \egroup + \fi} + +\def\botbaselinecorrection + {\ifvmode + \bgroup + \setbaselinecorrections + \dobotbaselinecorrection + \allowbreak % new, otherwise problems when many in a row + \prevdepth\strutdp + \egroup + \fi} + +\let\forcedbotbaselinecorrection\botbaselinecorrection + +\let\normalstartbaselinecorrection\startbaselinecorrection + +\unexpanded\def\startbaselinecorrection + {\ifgridsnapping + \snaptogrid[v!normal]\vbox\bgroup + \let\stopbaselinecorrection\egroup + \else + \normalstartbaselinecorrection + \fi} + +\protect \endinput diff --git a/tex/context/base/spac-hor.lua b/tex/context/base/spac-hor.lua new file mode 100644 index 000000000..6cb6e3f49 --- /dev/null +++ b/tex/context/base/spac-hor.lua @@ -0,0 +1,32 @@ +if not modules then modules = { } end modules ['spac-hor'] = { + version = 1.001, + comment = "companion to spac-hor.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local match = string.match +local utfbyte = utf.byte +local chardata = characters.data + +local can_have_space = table.tohash { + "lu", "ll", "lt", "lm", "lo", -- letters + -- "mn", "mc", "me", -- marks + "nd", "nl", "no", -- numbers + "ps", "pi", -- initial + -- "pe", "pf", -- final + -- "pc", "pd", "po", -- punctuation + "sm", "sc", "sk", "so", -- symbols + -- "zs", "zl", "zp", -- separators + -- "cc", "cf", "cs", "co", "cn", -- others +} + +function commands.autonextspace(str) -- todo: use nexttoken + local ch = match(str,"the letter (.)") or match(str,"the character (.)") + ch = ch and chardata[utfbyte(ch)] + if ch and can_have_space[ch.category] then + -- texsprint(ctxcatcodes,"\\space") -- faster + context.space() + end +end diff --git a/tex/context/base/spac-hor.mkiv b/tex/context/base/spac-hor.mkiv new file mode 100644 index 000000000..9f902678a --- /dev/null +++ b/tex/context/base/spac-hor.mkiv @@ -0,0 +1,946 @@ +%D \module +%D [ file=spac-hor, +%D version=2009.10.16, % 1997.03.31, was core-spa.tex +%D title=\CONTEXT\ Spacing Macros, +%D subtitle=Horizontal, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Horizontal} + +\unprotect + +\registerctxluafile{spac-hor}{1.001} + +\let\currentindentation\empty % amount/keyword +\let\currentindenting \empty % method + +\newdimen \ctxparindent +\parindent\ctxparindent % for the show + +\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}} + +% 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} + +\definecomplexorsimple\setupindenting + +\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}% can this be done differently now? + \ifcsname\??in:\!!stringa\endcsname \else + \edef\currentindentation{#1}% + \let\normalindentation\currentindentation + \simplesetupindenting + \fi} + +\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 + +\unexpanded\def\defineindentingmethod[#1]#2% + {\setvalue{\??in:#1}{#2}} + +\defineindentingmethod [\v!no] {\parindent\zeropoint}% was: \ctxparindent\noindent} +\defineindentingmethod [\v!not] {\parindent\zeropoint}% was: \ctxparindent\noindent} + +\defineindentingmethod [\v!first] {\indentfirstparagraphtrue} +\defineindentingmethod [\v!next] {\indentfirstparagraphfalse} + +\defineindentingmethod [\v!yes] {\parindent\ctxparindent\relax} % no \indent ! +\defineindentingmethod [\v!always] {\parindent\ctxparindent\relax} % no \indent ! + +\defineindentingmethod [\v!never] {\parindent\zeropoint\relax % no \indent ! + \chardef\indentingtoggle\zerocount} + +\defineindentingmethod [\v!odd] {\chardef\indentingtoggle\plusone} +\defineindentingmethod [\v!even] {\chardef\indentingtoggle\plustwo} + +\defineindentingmethod [\v!normal] {\ifx\normalindentation\empty\else + \let\currentindentation\normalindentation + \simplesetupindenting + \fi} + +\defineindentingmethod [\v!reset] {\indentfirstparagraphtrue + \parindent\zeropoint + \chardef\indentingtoggle\zerocount} + +\def\noindenting{\indenting[\v!no, \v!next ]} +\def\doindenting{\indenting[\v!yes,\v!first]} + +%D This one sets up the local indentation behaviour (i.e. either or not +%D a next paragraph will be indented). + +\def\dochecknextindentation#1% internal one + {\checknextindentation[\csname#1\c!indentnext\endcsname]} + +\setvalue{\??in->\s!empty}{} +\setvalue{\??in->\v!yes }{\doindentation} +\setvalue{\??in->\v!no }{\noindentation} +\setvalue{\??in->\v!auto }{\autoindentation} + +\unexpanded\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 % does not play well with noindentation + {\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 \startitemize \item itemize \stopitemize +%D \input tufte \startitemize \item itemize \stopitemize +%D \input tufte \startitemize \item itemize \stopitemize +%D +%D \page +%D +%D \input tufte +%D \starttyping +%D verbatim +%D \stoptyping +%D +%D \input tufte +%D \starttyping +%D verbatim +%D \stoptyping +%D +%D \input tufte +%D \starttyping +%D verbatim +%D \stoptyping +%D +%D \page +%D +%D \input tufte \startformula a = b \stopformula +%D \input tufte \startformula a = b \stopformula +%D \input tufte \startformula a = b \stopformula +%D \stoptyping + +\def\softbreak + {\relax\ifhmode\hskip\parfillskip\break\fi} + +%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} + +\unexpanded\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 + +% hm ... + +% \unexpanded\def\normalnotobeyedspace{\mathortext\normalspaceprimitive\space} % no \dontleavehmode\space (else no frenchspacing) +% \let\ =\normalnotobeyedspace + +% Because I strip spaces at the end of lines (in the editor) we need a bit of +% a trick to define slash+newline, so \space and \ are the same + +% We need to be careful with \ and \space and the definition of ~ which uses \ as +% we need to associate unicode spacing with it. There is some messy thing that that +% I forgot to note down so I will revision the \ once I ran into it again. + +% \ruledhbox spread 10pt {\frenchspacing xx xx\ X} +% \ruledhbox spread 10pt {\nonfrenchspacing xx xx\ X} +% \ruledhbox spread 10pt {\frenchspacing xx xx X} +% \ruledhbox spread 10pt {\nonfrenchspacing xx xx X} +% \ruledhbox spread 10pt {\frenchspacing xx xx~X} +% \ruledhbox spread 10pt {\nonfrenchspacing xx xx~X} + +% \ruledhbox spread 10pt {\frenchspacing xx dr.\ X} +% \ruledhbox spread 10pt {\nonfrenchspacing xx dr.\ X} +% \ruledhbox spread 10pt {\frenchspacing xx dr. X} +% \ruledhbox spread 10pt {\nonfrenchspacing xx dr. X} +% \ruledhbox spread 10pt {\frenchspacing xx dr.~X} +% \ruledhbox spread 10pt {\nonfrenchspacing xx dr.~X} + +\unexpanded\def\nonbreakablespace{\penalty\plustenthousand\normalspaceprimitive} % no space in math + +\letcatcodecommand \ctxcatcodes `\~ \nonbreakablespace % overloaded later + +\def\space { } +\def\removelastspace{\ifhmode\unskip\fi} +\def\nospace {\removelastspace\ignorespaces} + +\ifdefined\softhyphen \else \let\softhyphen\- \fi + +\ctxlua{tex.sprint(tex.ctxcatcodes,"\string\\unexpanded\string\\def\string\\\string\n{\string\\space}")} +% \ctxlua{tex.sprint(tex.ctxcatcodes,"\string\\let\string\\\string\n=\string\\space")} + +% 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} + +\appendtoks + \let~\space + \let\ \space +\to\simplifiedcommands + +\unexpanded\def\removeunwantedspaces + {\ifhmode + \expandafter \doremoveunwantedspace + \fi} + +\def\doremoveunwantedspace + {\ifnum\lastnodetype=\@@gluenode + \unskip \expandafter\doremoveunwantedspace + \fi} + +% \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 + +%D A couple of plain macros: + +\ifx\thinspace\undefined + + \def\thinspace {\kern .16667\emwidth} + \def\negthinspace{\kern-.16667\emwidth} + \def\enspace {\kern .5\emwidth} + +\fi + +\ifx\quad\undefined + + \def\enskip{\hskip.5\emwidth} + \def\quad {\hskip \emwidth} + \def\qquad {\hskip 2\emwidth} + +\fi + +\let\emspace\quad + +% 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]\donarrowermethod} + +\unexpanded\def\definenarrowermethod[#1]#2% + {\setvalue{\??sl:#1}{#2}} + +\def\donarrowermethod#1% + {\ifcsname\??sl:#1\endcsname\csname\??sl:#1\endcsname\else\global\advance\ctxmidskip#1\relax\fi} + +\definenarrowermethod[\v!left ]{\global\advance\ctxleftskip \@@slleft \relax} +\definenarrowermethod[\v!middle ]{\global\advance\ctxmidskip \@@slmiddle\relax} +\definenarrowermethod[\v!right ]{\global\advance\ctxrightskip \@@slright \relax} +\definenarrowermethod[-\v!left ]{\global\advance\ctxleftskip -\@@slleft \relax} +\definenarrowermethod[-\v!middle]{\global\advance\ctxmidskip -\@@slmiddle\relax} +\definenarrowermethod[-\v!right ]{\global\advance\ctxrightskip-\@@slright \relax} +\definenarrowermethod[\v!reset ]{\global\ctxleftskip \zeropoint + \global\ctxmidskip \zeropoint + \global\ctxrightskip\zeropoint\relax} +\definenarrowermethod[\v!none ]{} + +% todo: definenarrower +% +% \definecomplexorsimple\startnarrower +% +% \def\simplestartnarrower +% {\startnarrower[\v!middle]} +% +% \def\complexstartnarrower[#1]% +% {\@@slbefore % was hard coded \par +% \bgroup +% \global\ctxleftskip \zeropoint +% \global\ctxrightskip\zeropoint +% \global\ctxmidskip \zeropoint +% \processcommalistwithparameters[#1]\donarrower +% \advance\leftskip \dimexpr\ctxleftskip +\ctxmidskip\relax +% \advance\rightskip \dimexpr\ctxrightskip+\ctxmidskip\relax +% \seteffectivehsize} +% +% \unexpanded\def\stopnarrower +% {\@@slafter % was hard coded \par / needed, else skips forgotten +% \egroup} +% +% \unexpanded\def\setupnarrower +% {\dodoubleargument\getparameters[\??sl]} + +%D Contrary to \MKII\ we can now define classes of narrower (generalized +%D by Wolfgang). This environment will be enhanced for bidi. + +\def\narrowerparameter #1{\csname\donarrowerparameter{\??sl\@@narrower}#1\endcsname} +\def\donarrowerparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\donarrowerparentparameter\csname#1\s!parent\endcsname#2\fi} +\def\donarrowerparentparameter#1#2{\ifx#1\relax\s!empty\else\donarrowerparameter#1#2\fi} + +\getparameters + [\??sl] + [\c!before=\endgraf, + \c!after=\endgraf, + \c!left=1.5em, + \c!right=1.5em, + \c!middle=1.5em] + +\unexpanded\def\definenarrower + {\dodoubleempty\dodefinenarrower} + +\def\dodefinenarrower[#1][#2]% + {\getparameters[\??sl#1][\s!parent=\??sl,#2]% + \setvalue{\e!start#1}{\dodoubleempty\dostartnarrower[#1]}% + \setvalue{\e!stop #1}{\dostopnarrower}} + +\unexpanded\def\setupnarrower + {\dodoubleempty\dosetupnarrower} + +\def\dosetupnarrower[#1][#2]% + {\doifelsenothing{#2} + {\getparameters[\??sl][#1]} + {\def\docommand##1{\getparameters[\??sl##1][#2]}% + \processcommacommand[#1]\docommand}} + +\definenarrowermethod[\v!left ]{\global\advance\ctxleftskip \narrowerparameter\c!left \relax} +\definenarrowermethod[\v!middle ]{\global\advance\ctxmidskip \narrowerparameter\c!middle\relax} +\definenarrowermethod[\v!right ]{\global\advance\ctxrightskip \narrowerparameter\c!right \relax} +\definenarrowermethod[-\v!left ]{\global\advance\ctxleftskip -\narrowerparameter\c!left \relax} +\definenarrowermethod[-\v!middle]{\global\advance\ctxmidskip -\narrowerparameter\c!middle\relax} +\definenarrowermethod[-\v!right ]{\global\advance\ctxrightskip-\narrowerparameter\c!right \relax} +\definenarrowermethod[\v!reset ]{\global\ctxleftskip \zeropoint + \global\ctxmidskip \zeropoint + \global\ctxrightskip\zeropoint\relax} +\definenarrowermethod[\v!none ]{} + +\def\dostartnarrower[#1][#2]% + {\bgroup + \ifsecondargument % \doifsomethingelse{#2}? + \dodostartnarrower[#1][#2]% + \else + \dodostartnarrower[#1][\v!middle]% + \fi} + +\def\dodostartnarrower[#1][#2]% + {\edef\@@narrower{#1}% + \narrowerparameter\c!before + \global\ctxleftskip \zeropoint + \global\ctxrightskip\zeropoint + \global\ctxmidskip \zeropoint + \processcommalistwithparameters[#2]\donarrower + \advance\leftskip \dimexpr\ctxleftskip +\ctxmidskip\relax + \advance\rightskip\dimexpr\ctxrightskip+\ctxmidskip\relax + \seteffectivehsize} + +\def\dostopnarrower + {\narrowerparameter\c!after + \egroup} + +\def\v!narrower{narrower} + +\definenarrower[\v!narrower] + +\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} + +\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} + +%D Tolerance: + +\unexpanded\def\definetolerancemethod + {\dodoubleargument\dodefinetolerancemethod} + +\def\dodefinetolerancemethod[#1][#2]#3% + {\setvalue{\??to:#1:#2}{#3}} + +\definetolerancemethod [\v!vertical] [\v!verystrict ] {\let\bottomtolerance\empty} +\definetolerancemethod [\v!vertical] [\v!strict ] {\def\bottomtolerance{.050}} +\definetolerancemethod [\v!vertical] [\v!tolerant ] {\def\bottomtolerance{.075}} +\definetolerancemethod [\v!vertical] [\v!verytolerant] {\def\bottomtolerance{.100}} + +\definetolerancemethod [\v!horizontal] [\v!stretch ] {\emergencystretch\bodyfontsize} +\definetolerancemethod [\v!horizontal] [\v!space ] {\spaceskip.5em\!!plus.25em\!!minus.25em\relax} +\definetolerancemethod [\v!horizontal] [\v!verystrict ] {\tolerance 200 } +\definetolerancemethod [\v!horizontal] [\v!strict ] {\tolerance1500 } +\definetolerancemethod [\v!horizontal] [\v!tolerant ] {\tolerance3000 } +\definetolerancemethod [\v!horizontal] [\v!verytolerant] {\tolerance4500 } + +\def\dotolerancencemethodvertical #1{\csname\??to:\v!vertical :#1\endcsname} +\def\dotolerancencemethodhorizontal#1{\csname\??to:\v!horizontal:#1\endcsname} + +\def\dosetuptolerance[#1]% + {\doifinsetelse\v!vertical{#1}% + {\processcommacommand[#1]\dotolerancencemethodvertical} + {\processcommacommand[#1]\dotolerancencemethodhorizontal}} + +\unexpanded\def\setuptolerance + {\dosingleargument\dosetuptolerance} + +%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 + +\unexpanded\def\justonespace{\removeunwantedspaces\space} +%unexpanded\def\justaperiod {\removeunwantedspaces.} +%unexpanded\def\justacomma {\removeunwantedspaces,} + +\def\ignorecrlf + {\let\crlf\justonespace\let\\\crlf} + +\unexpanded\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} +\unexpanded\def\breakabletextormathspace#1#2#3{\ifmmode\mskip#1#2\else\hskip#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\breakablethinspace {\breakabletextormathspace+\thinmuskip 1} + +\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 + +\def\flexiblespaceamount#1#2#3% + {#1\interwordspace + \!!plus#2\interwordstretch + \!!minus#3\interwordshrink} + +\def\fixedspaceamount#1% + {#1\interwordspace} + +% moved from page-lin +% +% the following code is used in startlines\stoplines +% +% do we need \normalspaceprimitive here? + +\def\installspacehandler#1#2% needs to set \obeyedspace + {\setvalue{\??sr#1}{#2}} + +\installspacehandler \v!on + {\obeyspaces + \unexpanded\def\obeyedspace{\mathortext\normalspace{\dontleavehmode{\tt\controlspace}}}% + \let\ =\obeyedspace} + +\installspacehandler \v!yes + {\obeyspaces + \unexpanded\def\obeyedspace{\mathortext\normalspace{\dontleavehmode\normalspace}}% + \let\ =\obeyedspace} + +\installspacehandler \v!off % == default + {\normalspaces + \let\obeyedspace\normalspace + \let\ =\normalspaceprimitive} % was \normalspace + +\installspacehandler \v!fixed + {\obeyspaces + \unexpanded\def\obeyedspace{\mathortext\normalspace{\dontleavehmode\fixedspace}}% + \let\ =\obeyedspace} + +\def\activatespacehandler#1% + {\executeifdefined{\??sr#1}{\activatespacehandler\v!off}} + +\appendtoks + \normalspaces % to be sure +\to \everybeforeoutput + +%D A more robust variant ofthe \MKII\ one: +%D +%D \startbuffer +%D bla \TEX\autoinsertnextspace bla +%D bla \TEX\autoinsertnextspace (bla) +%D bla (\TEX\autoinsertnextspace) bla +%D bla \TEX\autoinsertnextspace\ bla +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +% unexpanded is important here as it prevents premature expansion in +% e.g. \normalexpanded{\egroup\sortingparameter\c!next} + +\unexpanded\def\autoinsertnextspace + {\futurelet\nexttoken\doautoinsertnextspace} + +\def\doautoinsertnextspace + {\ctxlua{commands.autonextspace("\meaning\nexttoken")}} % todo, just consult nexttoken at the lua end + +%D Moved from bib module: + +\def\outdented#1% + {\hskip-\hangindent#1\relax} + +%D Beware: due to char-def this becomes an active character but that +%D might change sometime when we will replace all these specials to +%D node insertions. We might even expand it to utf then as it then +%D can be used in string comparison (not that much needed anyway). + +\chardef\zwnj="200C +\chardef\zwj ="200D + +\protect \endinput diff --git a/tex/context/base/spac-pag.mkiv b/tex/context/base/spac-pag.mkiv new file mode 100644 index 000000000..353afa536 --- /dev/null +++ b/tex/context/base/spac-pag.mkiv @@ -0,0 +1,199 @@ +%D \module +%D [ file=spac-pag, +%D version=2009.10.16, % 1997.03.31, was core-spa.tex +%D title=\CONTEXT\ Spacing Macros, +%D subtitle=Pages, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Pages} + +\unprotect + +%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} + +\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 + +\unexpanded\def\startsignalrightpage % one may do a \postsignalrightplace + {\advance\pagesignallevel\plusone + \presignalrightpage + \let\signalrightpage\relax + \let\presignalrightpage\relax + \let\startsignalrightpage\relax + \doifrightpageelse\donothing\donothing + \freezepagestate} + +\unexpanded\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} + +\protect \endinput diff --git a/tex/context/base/spac-par.mkiv b/tex/context/base/spac-par.mkiv new file mode 100644 index 000000000..3477b1c1b --- /dev/null +++ b/tex/context/base/spac-par.mkiv @@ -0,0 +1,192 @@ +%D \module +%D [ file=spac-par, +%D version=2009.10.16, % 1997.03.31, was core-spa.tex +%D title=\CONTEXT\ Spacing Macros, +%D subtitle=Paragraphs, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Paragraphs} + +\unprotect + +%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% + {\normalexpanded % \scratchtoks{#1}% + {\noexpand#1% \the\scratchtoks + \hangindent\the\hangindent + \hangafter \the\hangafter + \parskip \the\parskip + \leftskip \the\leftskip + \rightskip \the\rightskip}} + +\newconditional \parbasedattributes + +\def\finishparbasedattributes + {\ifconditional\parbasedattributes + \setfalse\parbasedattributes + \par + \fi} + +\def\dostopparbasedattributes + {\settrue\parbasedattributes + \dostopattributes} + +% beware, changing this will break some code (like pos/backgrounds) + +\newtoks\everyfirstparagraphintro +\newtoks\everynextparagraphintro +\newtoks\@@everyparagraphtoks + +\chardef\everyparagraphintro\zerocount + +\unexpanded\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 + \global\let\insertparagraphintro\doinsertparagraphintro} + +\def\doinsertparagraphintro % can be merged with the next + {\ifcase\everyparagraphintro\else\@EA\dodoinsertparagraphintro\fi} + +\def\dodoinsertparagraphintro + {\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 + \global\let\insertparagraphintro\relax + \endgroup} + +\let\insertparagraphintro\relax + +%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 +\let\flushpostponednodedata\relax + +\def\flushatnextpar + {\bgroup + \global\let\flushpostponednodedata\doflushpostponednodedata + \dowithnextbox{\global\setbox\postponednodedata\hbox{\box\postponednodedata\box\nextbox}\egroup}\hbox} + +\def\doflushpostponednodedata + {\ifvoid\postponednodedata\else + \hbox{\smashedbox\postponednodedata}% + \fi + \global\let\flushpostponednodedata\relax} + +% Very nasty but needed for margin stuff inside colored +% paragraphs. + +\let\normalvadjust\vadjust + +\def\graphicvadjust % nasty bidi handling + {\dowithnextboxcontent + {\forgetall} + {\vadjust{\vbox attr \graphicvadjustattribute \plusone + {\unvbox\nextbox + % corrects for one line paragraphs + \nointerlineskip + \kern-\struttotal + \nointerlineskip + \verticalstrut}}}% + \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\localvbox#1#% used? + {\vbox#1\bgroup + \forgetparskip + \setlocalhsize + \hsize\localhsize + \forgetparindent + \forgetbothskips + \forgeteverypar + \let\next=} + +\protect \endinput diff --git a/tex/context/base/spac-ver.lua b/tex/context/base/spac-ver.lua new file mode 100644 index 000000000..c75eb1baa --- /dev/null +++ b/tex/context/base/spac-ver.lua @@ -0,0 +1,1185 @@ +if not modules then modules = { } end modules ['spac-ver'] = { + version = 1.001, + comment = "companion to spac-ver.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- we also need to call the spacer for inserts! + +-- this code dates from the beginning and is kind of experimental; it +-- will be optimized and improved soon +-- +-- the collapser will be redone with user nodes; also, we might get make +-- parskip into an attribute and appy it explicitly thereby getting rid +-- of automated injections; eventually i want to get rid of the currently +-- still needed tex -> lua -> tex > lua chain (needed because we can have +-- expandable settings at the tex end + +-- todo: strip baselineskip around display math + +local next, type, tonumber = next, type, tonumber +local format, gmatch, concat, match = string.format, string.gmatch, table.concat, string.match +local ceil, floor, max, min, round = math.ceil, math.floor, math.max, math.min, math.round +local texsprint, texlists, texdimen, texbox = tex.sprint, tex.lists, tex.dimen, tex.box +local lpegmatch = lpeg.match +local unpack = unpack or table.unpack + +local ctxcatcodes = tex.ctxcatcodes +local variables = interfaces.variables + +local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming + +-- 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 trace_vsnapping = false trackers.register("nodes.vsnapping", function(v) trace_vsnapping = v end) + +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') +local snap_method = attributes.private('snap-method') +local snap_done = attributes.private('snap-done') + +local has_attribute = node.has_attribute +local unset_attribute = node.unset_attribute +local set_attribute = node.set_attribute +local find_node_tail = node.tail +local free_node = node.free +local copy_node = node.copy +local traverse_nodes = node.traverse +local traverse_nodes_id = node.traverse_id +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_kern_node = nodes.kern +local make_rule_node = nodes.rule +local count_nodes = nodes.count +local node_ids_to_string = nodes.ids_to_string +local hpack_node = node.hpack +local vpack_node = node.vpack +local writable_spec = nodes.writable_spec + +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') +local adjust = node.id('adjust') + +vspacing = vspacing or { } +vspacing.data = vspacing.data or { } + +vspacing.data.snapmethods = vspacing.data.snapmethods or { } + +storage.register("vspacing/data/snapmethods", vspacing.data.snapmethods, "vspacing.data.snapmethods") + +local snapmethods = vspacing.data.snapmethods --maybe some older code can go + +local default = { + maxheight = true, + maxdepth = true, + strut = true, + hfraction = 1, + dfraction = 1, +} + +local fractions = { + minheight = "hfraction", maxheight = "hfraction", + mindepth = "dfraction", maxdepth = "dfraction", + top = "tlines", bottom = "blines", +} + +local values = { + offset = "offset" +} + +local colonsplitter = lpeg.splitat(":") + +local function listtohash(str) + local t = { } + for s in gmatch(str,"[^, ]+") do + local key, detail = lpegmatch(colonsplitter,s) + local v = variables[key] + if v then + t[v] = true + if detail then + local k = fractions[key] + if k then + detail = tonumber("0" .. detail) + if detail then + t[k] = detail + end + else + k = values[key] + if k then + detail = string.todimen(detail) + if detail then + t[k] = detail + end + end + end + end + else + detail = tonumber("0" .. key) + if detail then + t.hfraction, t.dfraction = detail, detail + end + end + end + if next(t) then + t.hfraction = t.hfraction or 1 + t.dfraction = t.dfraction or 1 + return t + else + return default + end +end + +function vspacing.define_snap_method(name,method) + local n = #snapmethods + 1 + local t = listtohash(method) + snapmethods[n] = t + t.name, t.specification = name, method + tex.write(n) +end + +--~ local rule_id = node.id("rule") +--~ local vlist_id = node.id("vlist") +--~ function nodes.makevtop(n) +--~ if n.id == vlist_id then +--~ local list = n.list +--~ local height = (list and list.id <= rule_id and list.height) or 0 +--~ n.depth = n.depth - height + n.height +--~ n.height = height +--~ end +--~ end + +local function snap_hlist(current,method,height,depth) -- method.strut is default + local snapht, snapdp +--~ print(table.serialize(method)) + if method["local"] then + -- snapping is done immediately here + snapht, snapdp = texdimen.bodyfontstrutheight, texdimen.bodyfontstrutdepth + elseif method["global"] then + snapht, snapdp = texdimen.globalbodyfontstrutheight, texdimen.globalbodyfontstrutdepth + else + -- maybe autolocal + -- snapping might happen later in the otr + snapht, snapdp = texdimen.globalbodyfontstrutheight, texdimen.globalbodyfontstrutdepth + local lsnapht, lsnapdp = texdimen.bodyfontstrutheight, texdimen.bodyfontstrutdepth + if snapht ~= lsnapht and snapdp ~= lsnapdp then + snapht, snapdp = lsnapht, lsnapdp + end + end + local h, d = height or current.height, depth or current.depth + local hr, dr, ch, cd = method.hfraction or 1, method.dfraction or 1, h, d + local tlines, blines = method.tlines or 1, method.blines or 1 + local done, plusht, plusdp = false, snapht, snapdp + local snaphtdp = snapht + snapdp + if method.none then + plusht, plusdp = 0, 0 + end + if method.halfline then + plusht, plusdp = plusht + snaphtdp/2, plusdp + snaphtdp/2 + end + if method.line then + plusht, plusdp = plusht + snaphtdp, plusdp + snaphtdp + end + + if method.first then + if current.id == vlist then + local list, lh, ld = current.list + for n in traverse_nodes_id(hlist,list) do + lh, ld = n.height, n.depth + break + end + if lh then + local x = max(ceil((lh-hr*snapht)/snaphtdp),0)*snaphtdp + plusht + local n = make_kern_node(x-lh) + n.next, list.prev, current.list = list, n, n + ch = x + snaphtdp + cd = max(ceil((d+h-lh-dr*snapdp-hr*snapht)/snaphtdp),0)*snaphtdp + plusdp + done = true + end + end + elseif method.last then + if current.id == vlist then + local list, lh, ld = current.list + for n in traverse_nodes_id(hlist,list) do + lh, ld = n.height, n.depth + end + if lh then + local baseline_till_top = h + d - ld + local x = max(ceil((baseline_till_top-hr*snapht)/snaphtdp),0)*snaphtdp + plusht + local n = make_kern_node(x-baseline_till_top) + n.next, list.prev, current.list = list, n, n + ch = x + cd = max(ceil((ld-dr*snapdp)/snaphtdp),0)*snaphtdp + plusdp + done = true + end + end + end + + if done then + -- first or last + elseif method.minheight then + ch = max(floor((h-hr*snapht)/snaphtdp),0)*snaphtdp + plusht + elseif method.maxheight then + ch = max(ceil((h-hr*snapht)/snaphtdp),0)*snaphtdp + plusht + else + ch = plusht + end + if done then + -- first or last + elseif method.mindepth then + cd = max(floor((d-dr*snapdp)/snaphtdp),0)*snaphtdp + plusdp + elseif method.maxdepth then + cd = max(ceil((d-dr*snapdp)/snaphtdp),0)*snaphtdp + plusdp + else + cd = plusdp + end + if method.top then + ch = ch + tlines * snaphtdp + end + if method.bottom then + cd = cd + blines * snaphtdp + end + + local offset = method.offset + if offset then + -- we need to set the attr + local shifted = vpack_node(current.list) + shifted.shift = offset + current.list = shifted + end + if not height then + current.height = ch + end + if not depth then + current.depth = cd + end + -- set_attribute(current,snap_method,0) + return h, d, ch, cd, (ch+cd)/snaphtdp +end + +--~ local function snap_topskip(current,method) +--~ local spec = current.spec +--~ local w = spec.width +--~ local wd = w +--~ if spec then +--~ wd = 0 +--~ spec = writable_spec(current) +--~ spec.width = wd +--~ end +--~ return w, wd +--~ end + +local function snap_topskip(current,method) + local spec = current.spec + local w = spec.width + local wd = w + if spec.writable then + spec.width, wd = 0, 0 + end + return w, wd +end + +vspacing.categories = { + [0] = 'discard', + [1] = 'largest', + [2] = 'force' , + [3] = 'penalty', + [4] = 'add' , + [5] = 'disable', + [6] = 'nowhite', + [7] = 'goback', + [8] = 'together' +} + +local categories = vspacing.categories + +function vspacing.tocategories(str) + local t = { } + for s in gmatch(str,"[^, ]") do + local n = tonumber(s) + if n then + t[categories[n]] = true + else + t[b] = true + end + end + return t +end + +function vspacing.tocategory(str) + if type(str) == "string" then + return set.tonumber(vspacing.tocategories(str)) + else + return set.tonumber({ [categories[str]] = true }) + end +end + +vspacing.data.map = vspacing.data.map or { } +vspacing.data.skip = vspacing.data.skip or { } + +storage.register("vspacing/data/map", vspacing.data.map, "vspacing.data.map") +storage.register("vspacing/data/skip", vspacing.data.skip, "vspacing.data.skip") + +do -- todo: interface.variables + + local function logger(c,...) + logs.report("vspacing",concat {...}) + texsprint(c,...) + end + + vspacing.fixed = false + + local map = vspacing.data.map + local skip = vspacing.data.skip + + 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)) + + local k_fixed, k_flexible, k_category, k_penalty, k_order = variables.fixed, variables.flexible, "category", "penalty", "order" + + -- This will change: just node.write and we can store the values in skips which + -- then obeys grouping + + local function analyse(str,oldcategory,texsprint) -- we could use shorter names + for s in gmatch(str,"([^ ,]+)") do + local amount, keyword, detail = lpegmatch(splitter,s) + if not keyword then + logs.report("vspacing","unknown directive: %s",s) + else + local mk = map[keyword] + if mk then + category = analyse(mk,category,texsprint) + elseif keyword == k_fixed then + texsprint(ctxcatcodes,"\\fixedblankskip") + elseif keyword == k_flexible then + texsprint(ctxcatcodes,"\\flexibleblankskip") + elseif keyword == k_category then + local category = tonumber(detail) + if category then + texsprint(ctxcatcodes,"\\setblankcategory{",category,"}") + if category ~= oldcategory then + texsprint(ctxcatcodes,"\\flushblankhandling") + oldcategory = category + end + end + elseif keyword == k_order and detail then + local order = tonumber(detail) + if order then + texsprint(ctxcatcodes,"\\setblankorder{",order,"}") + end + elseif keyword == k_penalty and detail then + local penalty = tonumber(detail) + if penalty then + texsprint(ctxcatcodes,"\\setblankpenalty{",penalty,"}") + end + else + amount = tonumber(amount) or 1 + local sk = skip[keyword] + if sk then + texsprint(ctxcatcodes,"\\addpredefinedblankskip{",amount,"}{",keyword,"}") + else -- no check + texsprint(ctxcatcodes,"\\addaskedblankskip{",amount,"}{",keyword,"}") + end + end + end + end + return category + end + + function vspacing.analyse(str) + local texsprint = (trace_vspacing and logger) or texsprint + texsprint(ctxcatcodes,"\\startblankhandling") + analyse(str,1,texsprint) + texsprint(ctxcatcodes,"\\stopblankhandling") + end + + -- + + function vspacing.setmap(from,to) + map[from] = to + end + + function vspacing.setskip(key,value,grid) + if value ~= "" then + if grid == "" then grid = value end + skip[key] = { value, grid } + end + end + +end + +-- implementation + +--~ nodes.snapvalues = { } + +--~ function nodes.setsnapvalue(n,ht,dp) +--~ nodes.snapvalues[n] = { ht, dp, ht+dp } +--~ end + +local trace_list, tracing_info, before, after = { }, false, "", "" + +local function glue_to_string(glue) + local spec = glue.spec + 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 concat(t," ") +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 + t[#t+1] = format("%s:%s",ty,aux.strip_zeros(number.topoints(current.spec.width))) + 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 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", format("%s | %s | category %s | order %s | penalty %s", 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", format("%s | %s", 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 and tl[1] == "node" then + trace_list[#trace_list] = { "node", tl[2] .. " + " .. nt } + else + trace_list[#trace_list+1] = { "node", nt } + end +end + +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 + +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) + end +end + +-- 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", +} + +local free_glue_node = free_node +local discard, largest, force, penalty, add, disable, nowhite, goback, together = 0, 1, 2, 3, 4, 5, 6, 7, 8 + +--~ local function free_glue_node(n) free_node(n.spec) free_node(n) end + +function vspacing.snap_box(n,how) + local sv = snapmethods[how] + if sv then + local box = texbox[n] + local list = box.list +--~ if list and (list.id == hlist or list.id == vlist) then + if list then + local s = has_attribute(list,snap_method) + if s == 0 then + if trace_vsnapping then + -- logs.report("snapper", "hlist not snapped, already done") + end + else + local h, d, ch, cd, lines = snap_hlist(box,sv,box.height,box.depth) + box.height, box.depth = ch, cd + if trace_vsnapping then + logs.report("snapper", "hlist snapped from (%s,%s) to (%s,%s) using method '%s' (%s) for '%s' (%s lines)",h,d,ch,cd,sv.name,sv.specification,"direct",lines) + end + set_attribute(list,snap_method,0) + end + end + end +end + +local function forced_skip(head,current,width,where,trace) + if where == "after" then + head, current = insert_node_after(head,current,make_rule_node(0,0,0)) + head, current = insert_node_after(head,current,make_kern_node(width)) + head, current = insert_node_after(head,current,make_rule_node(0,0,0)) + else + local c = current + head, current = insert_node_before(head,current,make_rule_node(0,0,0)) + head, current = insert_node_before(head,current,make_kern_node(width)) + head, current = insert_node_before(head,current,make_rule_node(0,0,0)) + current = c + end + if trace then + logs.report("vspacing", "inserting forced skip of %s",width) + end + return head, current +end + +local function collapser(head,where,what,trace,snap) -- maybe also pass tail + if trace then + reset_tracing(head) + end + local current, oldhead = head, head + local glue_order, glue_data, force_glue = 0, nil, false + local penalty_order, penalty_data, natural_penalty = 0, nil, nil + local parskip, ignore_parskip, ignore_following, ignore_whitespace, keep_together = nil, false, false, false, false + -- + -- todo: keep_together: between headers + -- + local function flush(why) + if penalty_data then + local p = make_penalty_node(penalty_data) + if trace then trace_done("flushed due to " .. why,p) end + head, _ = insert_node_before(head,current,p) + end + if glue_data then + if force_glue then + if trace then trace_done("flushed due to " .. why,glue_data) end + head, _ = forced_skip(head,current,glue_data.spec.width,"before",trace) + free_glue_node(glue_data) + elseif glue_data.spec.writable then + if trace then trace_done("flushed due to " .. why,glue_data) end + head, _ = insert_node_before(head,current,glue_data) + else + free_glue_node(glue_data) + end + end + if trace then trace_node(current) end + glue_order, glue_data, force_glue = 0, nil, false + penalty_order, penalty_data, natural_penalty = 0, nil, nil + parskip, ignore_parskip, ignore_following, ignore_whitespace = nil, false, false, false + end + if trace_vsnapping then + logs.report("snapper", "global ht/dp = %s/%s, local ht/dp = %s/%s", + texdimen.globalbodyfontstrutheight, texdimen.globalbodyfontstrutdepth, + texdimen.bodyfontstrutheight, texdimen.bodyfontstrutdepth) + end + if trace then trace_info("start analyzing",where,what) end + while current do + local id, subtype = current.id, current.subtype + if id == hlist or id == vlist then +-- needs checking, why so many calls + if snap then + local s = has_attribute(current,snap_method) + if not s then + -- if trace_vsnapping then + -- logs.report("snapper", "hlist not snapped") + -- end + elseif s == 0 then + if trace_vsnapping then + -- logs.report("snapper", "hlist not snapped, already done") + end + else + local sv = snapmethods[s] + if sv then + local h, d, ch, cd, lines = snap_hlist(current,sv) + if trace_vsnapping then + logs.report("snapper", "hlist snapped from (%s,%s) to (%s,%s) using method '%s' (%s) for '%s' (%s lines)",h,d,ch,cd,sv.name,sv.specification,where,lines) + end + elseif trace_vsnapping then + logs.report("snapper", "hlist not snapped due to unknown snap specification") + end + set_attribute(current,snap_method,0) + end + else + -- + end + -- tex.prevdepth = 0 + flush("list") + current = current.next + 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 == kern then + if snap and trace_vsnapping and current.kern ~= 0 then + --~ current.kern = 0 + logs.report("snapper", "kern of %s (kept)",current.kern) + end + flush("kern") + current = current.next + elseif id ~= glue then + flush("something else") + current = current.next + elseif subtype == user_skip 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 default, no unset (yet) + if sp and sc == penalty 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 + if trace then trace_skip('penalty in skip',sc,so,sp,current) end + head, current = remove_node(head, current, true) + elseif not sc then -- 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 + current = current.next + 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.writable then + local cs = current.spec + if cs.writable 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 = writable_spec(previous) -- no writable needed here + 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",previous) end + -- current = current.next + else + if trace then trace_natural("filler",current) end + current = current.next + end + else + if trace then trace_natural("natural (no prev spec)",current) end + current = current.next + end + else + if trace then trace_natural("natural (no prev)",current) end + current = current.next + end + end + glue_order, glue_data = 0, nil + elseif sc == disable then + ignore_following = true + if trace then trace_skip("disable",sc,so,sp,current) end + head, current = remove_node(head, current, true) + elseif sc == together then + keep_together = true + if trace then trace_skip("together",sc,so,sp,current) end + head, current = remove_node(head, current, true) + elseif sc == nowhite then + ignore_whitespace = true + head, current = remove_node(head, current, true) + elseif sc == discard then + if trace then trace_skip("discard",sc,so,sp,current) end + head, current = remove_node(head, current, true) + elseif 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",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 + -- is now exclusive, maybe support goback as combi, else why a set + if sc == largest then + local cs, gs = current.spec, glue_data.spec + local cw, gw = cs.width, gs.width + 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 + elseif sc == 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 sc == force then + -- last one counts, some day we can provide an accumulator and largest etc + -- but not now + 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 sc == 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 sc == add then + if trace then trace_skip('add',sc,so,sp,current) end +--~ local old, new = glue_data.spec, current.spec + local old, new = writable_spec(glue_data), 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 + if trace then trace_skip("unknown",sc,so,sp,current) end + head, current = remove_node(head, current, true) + end + else + if trace then trace_skip("unknown",sc,so,sp,current) end + head, current = remove_node(head, current, true) + end + if sc == force then + force_glue = true + end + elseif subtype == line_skip then + if snap then + local s = has_attribute(current,snap_method) + if s and s ~= 0 then + set_attribute(current,snap_method,0) + if current.spec.writable then + local spec = writable_spec(current) + spec.width = 0 + if trace_vsnapping then + logs.report("snapper", "lineskip set to zero") + end + end + else + if trace then trace_skip("lineskip",sc,so,sp,current) end + flush("lineskip") + end + else + if trace then trace_skip("lineskip",sc,so,sp,current) end + flush("lineskip") + end + current = current.next + elseif subtype == baseline_skip then + if snap then + local s = has_attribute(current,snap_method) + if s and s ~= 0 then + set_attribute(current,snap_method,0) + if current.spec.writable then + local spec = writable_spec(current) + spec.width = 0 + if trace_vsnapping then + logs.report("snapper", "baselineskip set to zero") + end + end + else + if trace then trace_skip("baselineskip",sc,so,sp,current) end + flush("baselineskip") + end + else + if trace then trace_skip("baselineskip",sc,so,sp,current) end + flush("baselineskip") + end + current = current.next + elseif subtype == par_skip 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.writable and gs.writable and ps.width > gs.width then + 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 + elseif subtype == top_skip_code or subtype == split_top_skip_code then + if snap then + local s = has_attribute(current,snap_method) + if s and s ~= 0 then + set_attribute(current,snap_method,0) + local sv = snapmethods[s] + local w, cw = snap_topskip(current,sv) + if trace_vsnapping then + logs.report("snapper", "topskip snapped from %s to %s for '%s'",w,cw,where) + end + else + if trace then trace_skip("topskip",sc,so,sp,current) end + flush("topskip") + end + else + if trace then trace_skip("topskip",sc,so,sp,current) end + flush("topskip") + end + current = current.next + elseif subtype == above_display_skip then + -- + if trace then trace_skip("above display skip (normal)",sc,so,sp,current) end + flush("above display skip (normal)") + current = current.next + -- + elseif subtype == below_display_skip then + -- + if trace then trace_skip("below display skip (normal)",sc,so,sp,current) end + flush("below display skip (normal)") + current = current.next + -- + elseif subtype == above_display_short_skip then + -- + if trace then trace_skip("above display skip (short)",sc,so,sp,current) end + flush("above display skip (short)") + current = current.next + -- + elseif subtype == below_display_short_skip then + -- + if trace then trace_skip("below display skip (short)",sc,so,sp,current) end + flush("below display skip (short)") + current = current.next + -- + else -- other glue + if snap and trace_vsnapping and current.spec.writable and current.spec.width ~= 0 then + logs.report("snapper", "%s of %s (kept)",skips[subtype],current.spec.width) + --~ current.spec.width = 0 + end + if trace then trace_skip(format("some glue (%s)",subtype),sc,so,sp,current) end + flush("some glue") + current = current.next + end + end + 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 tail + if penalty_data then + tail = find_node_tail(head) + local p = make_penalty_node(penalty_data) + if trace then trace_done("result",p) end + head, tail = insert_node_after(head,tail,p) + end + if glue_data then + if not tail then tail = find_node_tail(head) end + if trace then trace_done("result",glue_data) end + if force_glue then + head, tail = forced_skip(head,tail,glue_data.spec.width,"after",trace) + free_glue_node(glue_data) + else + head, tail = insert_node_after(head,tail,glue_data) + end + end + if trace then + if glue_data or penalty_data then + trace_info("stop flushing",where,what) + end + show_tracing(head) + if oldhead ~= head then + trace_info("head has been changed from '%s' to '%s'",node.type(oldhead.id),node.type(head.id)) + end + 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 + +local function report(message,lst) + logs.report("vspacing",message,count_nodes(lst,true),node_ids_to_string(lst)) +end + +function nodes.handle_page_spacing(newhead,where) +--~ local newhead = texlists.contrib_head + if newhead then +--~ starttiming(vspacing) + local newtail = find_node_tail(newhead) + local flush = false + stackhack = true -- todo: only when grid snapping once enabled + for n in traverse_nodes(newhead) do -- we could just look for glue nodes + 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 + 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,true) +newhead = collapser(newhead,"page",where,trace_page_vspacing,true) + else + if trace_collect_vspacing then report("flushing %s nodes: %s",newhead) end +--~ texlists.contrib_head = newhead + end + else + 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 +newhead = nil + end +--~ stoptiming(vspacing) + end +return newhead +end + +local ignore = table.tohash { + "split_keep", + "split_off", + -- "vbox", +} + +function nodes.handle_vbox_spacing(head,where) + if head and not ignore[where] and head.next then + -- starttiming(vspacing) + head = collapser(head,"vbox",where,trace_vbox_vspacing,false) + -- stoptiming(vspacing) + end + return head +end + +function nodes.collapse_vbox(n) -- for boxes + local list = texbox[n].list + if list then + -- starttiming(vspacing) + texbox[n].list = vpack_node(collapser(list,"snapper","vbox",trace_vbox_vspacing,true)) + -- stoptiming(vspacing) + end +end + +-- we will split this module hence the locals + +local attribute = attributes.private('graphicvadjust') + +local hlist = node.id('hlist') +local vlist = node.id('vlist') + +local remove_node = nodes.remove +local hpack_node = node.hpack +local vpack_node = node.vpack +local has_attribute = node.has_attribute + +function nodes.repackage_graphicvadjust(head,groupcode) -- we can make an actionchain for mvl only + if groupcode == "" then -- mvl only + local h, p, done = head, nil, false + while h do + local id = h.id + if id == hlist or id == vlist then + local a = has_attribute(h,attribute) + if a then + if p then + local n + head, h, n = remove_node(head,h) + local pl = p.list + if n.width ~= 0 then + n = hpack_node(n,0,'exactly') -- todo: dir + end + if pl then + pl.prev = n + n.next = pl + end + p.list = n + done = true + else + -- can't happen + end + else + p = h + h = h.next + end + else + h = h.next + end + end + return head, done + else + return head, false + end +end + +--~ function nodes.repackage_graphicvadjust(head,groupcode) -- we can make an actionchain for mvl only +--~ if groupcode == "" then -- mvl only +--~ return head, false +--~ else +--~ return head, false +--~ end +--~ end + +--~ tasks.appendaction("finalizers", "lists", "nodes.repackage_graphicvadjust") + +nodes.builders = nodes.builder or { } + +local builders = nodes.builders + +local actions = tasks.actions("vboxbuilders",5) + +function nodes.builders.vpack_filter(head,groupcode,size,packtype,maxdepth,direction) + local done = false + if head then + starttiming(builders) + if trace_callbacks then + local before = nodes.count(head) + head, done = actions(head,groupcode,size,packtype,maxdepth,direction) + local after = nodes.count(head) + if done then + tracer("vpack","changed",head,groupcode,before,after,true) + else + tracer("vpack","unchanged",head,groupcode,before,after,true) + end + stoptiming(builders) + else + head, done = actions(head,groupcode) + stoptiming(builders) + end + end + return head, done +end + +-- This one is special in the sense that it has no head +-- and we operate on the mlv. Also, we need to do the +-- vspacing last as it removes items from the mvl. + +local actions = tasks.actions("mvlbuilders",1) + +function nodes.builders.buildpage_filter(groupcode) + starttiming(builders) + local head = texlists.contrib_head + local head, done = actions(head,groupcode) + texlists.contrib_head = head + stoptiming(builders) + return (done and head) or true +end + +callbacks.register('vpack_filter', nodes.builders.vpack_filter, "vertical spacing etc") +callbacks.register('buildpage_filter', nodes.builders.buildpage_filter, "vertical spacing etc (mvl)") + +statistics.register("v-node processing time", function() + return statistics.elapsedseconds(builders) +end) diff --git a/tex/context/base/spac-ver.mkiv b/tex/context/base/spac-ver.mkiv new file mode 100644 index 000000000..75af82df7 --- /dev/null +++ b/tex/context/base/spac-ver.mkiv @@ -0,0 +1,2078 @@ +%D \module +%D [ file=spac-ver, +%D version=2009.10.16, % 1997.03.31, was core-spa.tex +%D title=\CONTEXT\ Spacing Macros, +%D subtitle=Vertical, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Vertical} + +\unprotect + +\registerctxluafile{spac-ver}{1.001} + +\newskip\blankskip \blankskip=\bigskipamount + +\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 + +%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} + +% \unexpanded\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 + +\def\presetnormallineheight + {\edef\normallineheight{\interlinespaceparameter\c!line}% + %done elsewhere : \spacing\!!plusone % new per 10/08/2004, else problems in otr / !! needed + \iflocalinterlinespace \else + \doifdefined\bodyfontinterlinespecs + {\doifsomething\bodyfontinterlinespace + {\edef\normallineheight{\bodyfontinterlinespace}}}% + \fi} + +\unexpanded\def\setupspecifiedinterlinespace[#1]% + {\getparameters[\??it\currentinterlinespace][#1]% + \dosetupspecifiedinterlinespaceindeed} + +\def\dosetupspecifiedinterlinespaceindeed + {\edef\strutheightfactor {\interlinespaceparameter\c!height}% + \edef\strutdepthfactor {\interlinespaceparameter\c!depth}% + \edef\minimumstrutheight {\interlinespaceparameter\c!minheight}% + \edef\minimumstrutdepth {\interlinespaceparameter\c!mindepth}% + \edef\minimumlinedistance{\interlinespaceparameter\c!distance}% + \edef\normallineheight {\interlinespaceparameter\c!line}% + \edef\topskipfactor {\interlinespaceparameter\c!top}% + \edef\maxdepthfactor {\interlinespaceparameter\c!bottom}% + \edef\baselinegluefactor {\interlinespaceparameter\c!stretch}% + % often topskip does more bad than good, so: + \ifx\topskipfactor\v!height + \let\topskipfactor\strutheightfactor + \fi + \setfontparameters % redundant, can be \setstrut, test first + \updateraggedskips} % yes indeed + +\let\currentrelativeinterlinespace\empty + +\setvalue{\??it::\v!on }{\oninterlineskip} +\setvalue{\??it::\v!off }{\offinterlineskip} +\setvalue{\??it::\v!reset}{\let\currentrelativeinterlinespace\empty + \let\setrelativeinterlinespace\relax + \setfontparameters} +\setvalue{\??it::\v!auto }{\let\setrelativeinterlinespace\dosetrelativeinterlinespace} + +% \def\dosetspecifiedrelativeinterlinespace#1% +% {\assignvalue{#1}\currentrelativeinterlinespace{1.00}{1.25}{1.50}% +% \spacing\currentrelativeinterlinespace} + +% \def\dosetspecifiedrelativeinterlinespace#1% fragile? +% {\doifdimensionelse{#1} +% {\setupspecifiedinterlinespace[\c!line=#1]} +% {\assignvalue{#1}\currentrelativeinterlinespace{1.00}{1.25}{1.50}% +% \spacing\currentrelativeinterlinespace}} + +\def\dosetspecifiedrelativeinterlinespace#1% fragile? + {\doifdimenstringelse{#1} + {\setupspecifiedinterlinespace[\c!line=#1]} + {\assignvalue{#1}\currentrelativeinterlinespace{1.00}{1.25}{1.50}% + \spacing\currentrelativeinterlinespace}} + +\unexpanded\def\setuprelativeinterlinespace[#1]% + {\processcommalist[#1]\dosetuprelativeinterlinespace} + +\def\dosetuprelativeinterlinespace#1% + {\ifcsname\??it::#1\endcsname + \csname\??it::#1\endcsname + \else + \dosetspecifiedrelativeinterlinespace{#1}% + \fi} + +\def\dosetrelativeinterlinespace + {\ifx\currentrelativeinterlinespace\empty\else + \spacing\currentrelativeinterlinespace + \fi} + +\let\setrelativeinterlinespace\relax + +% \appendtoks \setrelativeinterlinespace \to \everybodyfont + +\newtoks \everysetupglobalinterlinespace +\newtoks \everysetuplocalinterlinespace + +% \def\complexsetupinterlinespace[#1]% \commalistelement ipv #1 +% {\doifassignmentelse{#1}\setupspecifiedinterlinespace\setuprelativeinterlinespace[#1]% +% \the\iflocalinterlinespace\everysetuplocalinterlinespace\else\everysetupglobalinterlinespace\fi} + +\def\interlinespaceparameter #1{\csname\dointerlinespaceparameter{\??it\currentinterlinespace}#1\endcsname} +\def\dointerlinespaceparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dointerlinespaceparentparameter\csname#1\s!parent\endcsname#2\fi} +\def\dointerlinespaceparentparameter#1#2{\ifx#1\relax\s!empty\else\dointerlinespaceparameter#1#2\fi} + +\newconditional\interlinespaceisset + +\let\currentinterlinespace\empty + +\unexpanded\def\defineinterlinespace + {\dodoubleempty\dodefineinterlinespace} + +\def\dodefineinterlinespace[#1][#2]% + {\getparameters[\??it#1][\s!parent=\??it,#2]} + +\unexpanded\def\setupinterlinespace + {\dodoubleempty\dosetupinterlinespace} + +\def\dosetupinterlinespace[#1][#2]% + {\settrue\interlinespaceisset % reset has to be done when needed + \ifsecondargument + \getparameters[\??it#1][#2]% + \else\iffirstargument + \edef\currentinterlinespace{\ifcsname\??it#1\s!parent\endcsname#1\fi}% + \ifx\currentinterlinespace\empty + \complexsetupinterlinespace[#1]% + \else + \dosetupspecifiedinterlinespaceindeed + \fi + \else + \let\currentinterlinespace\empty + \simplesetupinterlinespace + \fi\fi} + +\def\complexsetupinterlinespace[#1]% \commalistelement ipv #1 + {\doifassignmentelse{#1}\setupspecifiedinterlinespace\setuprelativeinterlinespace[#1]% + \the\iflocalinterlinespace\everysetuplocalinterlinespace\else\everysetupglobalinterlinespace\fi} + +\def\simplesetupinterlinespace % adapts to the font + {\localinterlinespacetrue + \setfontparameters + \updateraggedskips % funny one here + \the\everysetuplocalinterlinespace + \localinterlinespacefalse} + +% \def\dosetupcheckedinterlinespace#1% often a chain +% {\edef\askedinterlinespace{#1}% +% \ifx\askedinterlinespace\empty +% \simplesetupinterlinespace +% \else +% \normalexpanded{\noexpand\doifassignmentelse{\askedinterlinespace}% +% \noexpand\setupspecifiedinterlinespace +% \noexpand\setuprelativeinterlinespace[\askedinterlinespace]}% +% \iflocalinterlinespace +% \the\everysetuplocalinterlinespace +% \else +% \localinterlinespacetrue +% \the\everysetuplocalinterlinespace +% \localinterlinespacefalse +% \fi +% \fi} + +\def\dosetupcheckedinterlinespace#1% often a chain + {\edef\askedinterlinespace{#1}% + \ifx\askedinterlinespace\empty + \simplesetupinterlinespace + \else\ifcsname\??it\askedinterlinespace\s!parent\endcsname + \pushmacro\currentinterlinespace + \let\currentinterlinespace\askedinterlinespace + \dosetupspecifiedinterlinespaceindeed + \iflocalinterlinespace + \the\everysetuplocalinterlinespace + \else + \localinterlinespacetrue + \the\everysetuplocalinterlinespace + \localinterlinespacefalse + \fi + \popmacro\currentinterlinespace + \else + \normalexpanded{\noexpand\doifassignmentelse{\askedinterlinespace}% + \noexpand\setupspecifiedinterlinespace + \noexpand\setuprelativeinterlinespace[\askedinterlinespace]}% + \iflocalinterlinespace + \the\everysetuplocalinterlinespace + \else + \localinterlinespacetrue + \the\everysetuplocalinterlinespace + \localinterlinespacefalse + \fi + \fi\fi} + +% \unexpanded\def\setuplocalinterlinespace[#1]% +% {\localinterlinespacetrue +% \let\@@saveditheight \@@itheight +% \let\@@saveditdepth \@@itdepth +% \let\@@saveditline \@@itline +% \let\@@saveditminheight\@@itminheight +% \let\@@saveditmindepth \@@itmindepth +% \let\@@saveditdistance \@@itdistance +% \let\@@savedittop \@@ittop +% \let\@@saveditbottom \@@itbottom +% \let\@@saveditstretch \@@itstretch +% \setupinterlinespace[#1]% +% \let\@@itheight \@@saveditheight +% \let\@@itdepth \@@saveditdepth +% \let\@@itline \@@saveditline +% \let\@@itminheight\@@saveditminheight +% \let\@@itmindepth \@@saveditmindepth +% \let\@@itdistance \@@saveditdistance +% \let\@@ittop \@@savedittop +% \let\@@itbottom \@@saveditbottom +% \let\@@itstretch \@@saveditstretch +% \localinterlinespacefalse} + +\unexpanded\def\setuplocalinterlinespace[#1]% + {\localinterlinespacetrue + \pushmacro\currentinterlinespace + \setupinterlinespace[#1]% + \popmacro\currentinterlinespace + \localinterlinespacefalse} + +\let\switchtointerlinespace\setuplocalinterlinespace + +\definecomplexorsimple\setupinterlinespace + +\def\removelastskip % a redefinition of plain + {\ifvmode\ifdim\lastskip=\zeropoint\else\vskip-\lastskip\fi\fi} + +\def\doifoutervmode#1% + {\ifvmode\ifinner\else#1\fi\fi} + +\def\dosomebreak#1% + {\doifoutervmode + {\scratchskip\lastskip + \removelastskip + %\leavevmode\type{#1}% + #1\relax + \ifdim\scratchskip=\zeropoint % else interference with footnotes + \else + \vskip\scratchskip + \fi}} + +\def\packed + {\nointerlineskip} + +\def\godown[#1]% + {\relax + \ifhmode\endgraf\fi + \ifvmode\nointerlineskip\vskip#1\relax\fi} + +\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\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 + +\unexpanded\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% + {\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\whitespace +% {\par +% \ifdim\parskip>\zeropoint\relax +% %\ifdim\lastskip>\parskip \else +% % \removelastskip interferes with blanko blokkeer en klein +% \vskip\parskip +% %\fi +% \fi} + +\def\nowhitespace{\vspacing[\v!nowhite]} +\def\whitespace {\vspacing[\v!white]} + +% obsolete: +% +% \def\savedcurrentwhitespace{\currentwhitespace} +% \def\savecurrentwhitespace {\edef\savedcurrentwhitespace{\currentwhitespace}} +% \def\restorecurrentwhitespace{\edef\currentwhitespace{\savedcurrentwhitespace}} + +% 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. + +\newsignal \noparskipsignal % \def\noparskipsignal {0.00001pt} +\def\lastdoneparskip {0pt} + +\newconditional\noblankinpacked +\newcount\packeddepth + +\unexpanded\def\startpacked + {\dosingleempty\dostartpacked} + +\def\dostartpacked[#1]% nesting afvangen + {\global\advance\packeddepth\plusone + \par + \ifnum\packeddepth=\plusone \ifvmode + \bgroup + \whitespace % not combined + \blank[\v!disable]% + \doifelse{#1}\v!blank\setfalse\settrue\noblankinpacked + \setupwhitespace[\v!none]% + \fi \fi} + +\unexpanded\def\stoppacked + {\par + \ifnum\packeddepth=\plusone \ifvmode + \egroup + \fi \fi + \global\advance\packeddepth\minusone} + +\unexpanded\def\startunpacked + {\blank + \bgroup} + +\unexpanded\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. + +% \prevdepth crosses pageboundaries! +% +% todo: a version that works ok inside a box + +\let\doaroundlinecorrection\relax + +\unexpanded\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} + +\unexpanded\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 +% +% \dontleavehmode + +% 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} + +\let\spacingfactor \plusone + +\def\topskipfactor {1.0} +\def\maxdepthfactor {0.5} + +\def\systemtopskipfactor {\topskipfactor} +\def\systemmaxdepthfactor {\maxdepthfactor} + +\ifdefined\globalbodyfontsize\else + \newdimen\globalbodyfontsize + \globalbodyfontsize=12pt +\fi + +\ifdefined\normalizedbodyfontsize\else + \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 + {\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 +\ifgridsnapping + \topskip\zeropoint +\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}{\withoutpt\the\dimexpr#1\points\relax}\fi + \let\spacingfactor\plusone + \else + \edef\spacingfactor{#1}% + \fi + \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\else\unhcopy\fi\strutbox} + +\fi + +\let\normalstrut\strut + +% The double \hbox construction enables us to \backtrack +% boxes. + +\let\strutht\undefined \newdimen\strutht +\let\strutdp\undefined \newdimen\strutdp + +\unexpanded\def\setstrut + {\ifgridsnapping + \setstrutgridyes + \else + \setstrutgridnop + \fi} + +\unexpanded\def\setstrutgridyes + {\strutht\spacingfactor\dimexpr + \ifdim\minimumstrutheight>\zeropoint + \minimumstrutheight + \else + \strutheightfactor\dimexpr\normallineheight + \fi + \strutdp\dimexpr + \ifdim\minimumstrutdepth>\zeropoint + \minimumstrutdepth + \else + \normallineheight-\strutht + \fi + \dosetstrut} + +\unexpanded\def\setstrutgridnop + {\strutht\spacingfactor\dimexpr + \ifdim\minimumstrutheight>\zeropoint + \minimumstrutheight + \else + \strutheightfactor\dimexpr\normallineheight + \fi + \strutdp\spacingfactor\dimexpr + \ifdim\minimumstrutdepth>\zeropoint + \minimumstrutdepth + \else + \strutdepthfactor\dimexpr\normallineheight + \fi + \dosetstrut} + +\unexpanded\def\setcharstrut#1% + {\setbox\strutbox\normalhbox{#1}% + \strutht\ht\strutbox + \strutdp\dp\strutbox + \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 + +\newdimen\tempstrutdimen + +\def\dosetstrut + {\let\strut\normalstrut + \tempstrutdimen\dimexpr\strutht+\strutdp-\lineheight\relax + \ifabsnum\tempstrutdimen<\plustwo + % compensate rounding error /- 1sp to avoid too many + % 1sp baselineskips in for instance verbatim + \strutht\dimexpr\strutht-\tempstrutdimen\relax + \fi + \edef\strutheight{\the\strutht}% maybe better \number\strutht sp + \edef\strutdepth {\the\strutdp}% + \ifdim\strutwidth=\zeropoint + \dosetstruthide + \else + \dosetstrutvide + \fi + \struttotal\dimexpr\strutht+\strutdp\relax} + +\def\dosetstruthide + {\setbox\strutbox\normalhbox + {\vrule + \!!width \zeropoint + \!!height\strutht + \!!depth \strutdp}} + +\def\dosetstrutvide + {\setbox\strutbox\normalhbox + {\normalhbox to \zeropoint + {% \hss % new, will be option + \vrule + \!!width \strutwidth + \!!height\strutht + \!!depth \strutdp + \hss}}} + +%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. + +% experiment + +\newbox\emptystrutbox \setbox\emptystrutbox\hbox{} + +\def\dosetstruthide + {\setbox\strutbox\copy\emptystrutbox + \ht\strutbox\strutht + \dp\strutbox\strutdp} + +\def\strut{\relax\dontleavehmode\copy\strutbox} % still callbacks for \hbox{\strut} + + +\let\normalstrut\strut + +%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 + +\unexpanded\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\showstruts + {\setteststrut + \settestcrlf} + +\def\setteststrut + {\def\strutwidth{.8pt}% + \setstrut} + +\def\autostrutfactor{1.1} + +\def\setautostrut + {\begingroup + \setbox\scratchbox\copy\strutbox + \setstrut + \ifdim\strutht>\autostrutfactor\ht\scratchbox + \endgroup \setstrut + \else\ifdim\strutdp>\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 + {\def\strutwidth{\zeropoint}% no let + \setstrut} + +\ifdefined\setfontparameters\else + % 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\offinterlineskip + {\baselineskip-\thousandpoint + \lineskip\zeropoint + \lineskiplimit\maxdimen + % We also need this here now; thanks to taco for figuring that out! + \def\minimumlinedistance{\zeropoint}} + +\def\nointerlineskip + {\prevdepth-\thousandpoint} + +\let\normaloffinterlineskip=\offinterlineskip % knuth's original + +%D My own one: + +\def\dopushinterlineskip + {\edef\oninterlineskip + {\baselineskip\the\baselineskip + \lineskip\the\lineskip + \lineskiplimit\the\lineskiplimit + \noexpand\edef\noexpand\minimumlinedistance{\the\dimexpr\minimumlinedistance}% + \let\noexpand\offinterlineskip\noexpand\normaloffinterlineskip}} + +\def\nopushinterlineskip + {\let\oninterlineskip\setnormalbaselines} + +\def\offinterlineskip + {\ifdim\baselineskip>\zeropoint + \dopushinterlineskip + \else + \nopushinterlineskip + \fi + \normaloffinterlineskip} + +\let\oninterlineskip=\relax + +\def\leaveoutervmode + {\ifvmode\ifinner\else + \leavevmode + \fi\fi} + +% We stellen enkele penalties anders in dan Plain TEX: +% +% \widowpenalty=\defaultwidowpenalty\relax +% \clubpenalty =\defaultclubpenalty \relax + +\def\resetpenalties#1% + {\ifdefined#1% + #1\minusone + \fi} + +\def\setpenalties#1#2#3% + {\ifdefined#1% 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. + +% just before margintexts ... will eventually be done differently in mkiv using +% attributes + +\newcount\nofkeeplinestogether +\let\restoreinterlinepenalty\relax + +\def\dorestoreinterlinepenalty + {\global\let\restoreinterlinepenalty\relax + \global\resetpenalties\interlinepenalties + \global\nofkeeplinestogether\zerocount} + +\def\keeplinestogether#1% + {\ifnum#1>\nofkeeplinestogether + \global\nofkeeplinestogether#1% + \global\setpenalties\interlinepenalties\nofkeeplinestogether\plustenthousand + \global\let\restoreinterlinepenalty\dorestoreinterlinepenalty + \fi} + +\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 + +%D To be checked: + +\ifx\savedstrutbox\undefined \newbox\savedstrutbox \fi + +\def\savestrut {\setbox\savedstrutbox\copy\strutbox} +\def\savedstrut{\copy \savedstrutbox} + +%D Page spacing + +\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 + +%D Good old blank redone: + +\definesystemattribute[kern-chars] +\definesystemattribute[skip-category] \chardef\skipcategoryattribute \dogetattributeid{skip-category} +\definesystemattribute[skip-penalty] \chardef\skippenaltyattribute \dogetattributeid{skip-penalty} +\definesystemattribute[skip-order] \chardef\skiporderattribute \dogetattributeid{skip-order} +\definesystemattribute[display-math] \chardef\displaymathattribute \dogetattributeid{display-math} +\definesystemattribute[snap-method] \chardef\snapmethodattribute \dogetattributeid{snap-method} +\definesystemattribute[snap-done] \chardef\snapdoneattribute \dogetattributeid{snap-done} + +%definesystemattribute[snap-category] \chardef\snapcategoryattribute \dogetattributeid{snap-category} + +% TODO: NAMED SNAPPERS + +\newskip \bodyfontlineheight +\newdimen \bodyfontstrutheight +\newdimen \bodyfontstrutdepth + +\newskip \globalbodyfontlineheight +\newdimen \globalbodyfontstrutheight +\newdimen \globalbodyfontstrutdepth + +% \appendtoks +% \dosetupgridsnapping +% \to \everysetupbodyfont + +\def\installsnapvalues#1#2% todo: a proper define + {\edef\currentsnapper{#1:#2}% + \ifcsname\currentsnapper\endcsname \else + \setevalue\currentsnapper{\ctxlua{vspacing.define_snap_method("#1","#2")}}% + \fi + \setevalue{\??gr:#1}{\attribute\snapmethodattribute\csname\currentsnapper\endcsname\space}} + +\unexpanded\def\definegridsnapping + {\dodoubleargument\dodefinegridsnapping} + +\def\dodefinegridsnapping[#1][#2]% + {\installsnapvalues{#1}{#2}} + +\edef\resetsnapvalue + {%\gridsnappingfalse + \attribute\snapmethodattribute\attributeunsetvalue} + +\def\setsnapvalue#1% + {%\gridsnappingtrue + \ifcsname\??gr:#1\endcsname\csname\??gr:#1\endcsname\fi} + +\def\autosetsnapvalue#1% + {\ifcsname\??gr:#1\endcsname + \csname\??gr:#1\endcsname + \else + \installsnapvalues\s!dummy{#1}% + \csname\??gr:\s!dummy\endcsname + \fi} + +% \installsnapvalues{loose} {\v!maxdepth:0.8,\v!maxheight:0.8,\v!strut} +% \installsnapvalues{normal}{\v!maxdepth:1.0,\v!maxheight:1.0,\v!strut} +% \installsnapvalues{tight} {\v!maxdepth:1.2,\v!maxheight:1.2,\v!strut} + +% none don't enlarge +% halfline enlarge by halfline/halfline +% line enlarge by line/line +% strut enlarge by ht/dp (default) +% first align to top line +% last align to bottom line +% mindepth round depth down +% maxdepth round depth up +% minheight round height down +% maxheight round height up +% local use local interline space +% shift:-3tp vertical shift within box + +%D We're not downward compatible with \MKII ! + +\definegridsnapping[\v!normal] [\v!maxheight,\v!maxdepth,\v!strut] +\definegridsnapping[\v!standard] [\v!maxheight,\v!maxdepth,\v!strut] +\definegridsnapping[\v!yes] [\v!maxheight,\v!maxdepth,\v!strut] + +\definegridsnapping[\v!strict] [\v!maxdepth:0.8,\v!maxheight:0.8,\v!strut] +\definegridsnapping[\v!tolerant] [\v!maxdepth:1.2,\v!maxheight:1.2,\v!strut] + +\definegridsnapping[\v!top] [\v!minheight,\v!maxdepth,\v!strut] +\definegridsnapping[\v!bottom] [\v!maxheight,\v!mindepth,\v!strut] +\definegridsnapping[\v!both] [\v!minheight,\v!mindepth,\v!strut] + +\definegridsnapping[\v!broad] [\v!maxheight,\v!maxdepth,\v!strut,0.8] % maybe 0.85 +\definegridsnapping[\v!fit] [\v!maxheight,\v!maxdepth,\v!strut,1.2] % tight 0.15 + +\definegridsnapping[\v!first] [\v!first] +\definegridsnapping[\v!last] [\v!last] +\definegridsnapping[\v!high] [\v!minheight,\v!maxdepth,\v!none] +\definegridsnapping[\v!low] [\v!maxheight,\v!mindepth,\v!none] +\definegridsnapping[\v!line] [\v!line] +\definegridsnapping[\v!strut] [\v!strut] + +\definegridsnapping[\v!max] [\v!maxdepth,\v!maxheight,\v!strut] +\definegridsnapping[\v!min] [\v!mindepth,\v!minheight,\v!strut] + +\newtoks\everysetupgridsnapping % this only happens at the setuplayout level + +\def\dosetupgridsnapping{\the\everysetupgridsnapping} % not used ! + +\def\synchronizelocallinespecs + {\bodyfontlineheight \normallineheight + \bodyfontstrutheight\strutheight + \bodyfontstrutdepth \strutdepth} + +\def\synchronizegloballinespecs + {\global\globalbodyfontlineheight \normallineheight + \global\globalbodyfontstrutheight\strutheight + \global\globalbodyfontstrutdepth \strutdepth} + +% \appendtoks +% \synchronizegloballinespecs +% \synchronizelocallinespecs +% \to \everysetupgridsnapping + +\appendtoks + \synchronizegloballinespecs + \synchronizelocallinespecs +\to \everysetupglobalinterlinespace + +\appendtoks + \synchronizelocallinespecs +\to \everysetuplocalinterlinespace + +% \appendtoks +% \resetsnapvalues +% \to \everyforgetall + +%D Snapping. + +\newif\ifgridsnapping + +\let\showgridsnapping\relax + +\def\snaptogrid {\dosingleempty\dosnaptogrid} +\def\moveongrid {\dosingleempty\domoveongrid} +\unexpanded\def\placeongrid{\dosingleempty\doplaceongrid} + +\def\dodomoveongrid[#1]% + {} % gone, unless we set an attribute + +\def\doplaceongrid[#1]% + {\snaptogrid[#1]\vbox} + +\def\dosnaptogrid[#1]% list or predefined + {\ifgridsnapping + \expandafter\dodosnaptogrid + \else + \expandafter\gobbleoneargument + \fi{#1}} + +\def\dodosnaptogrid#1% + {\bgroup + \resetsnapvalue + \dowithnextbox{\dododosnaptogrid{#1}}} + +% eventually there will always be a line snap + +\def\dododosnaptogrid#1% + {\ifvbox\nextbox + \ctxlua{nodes.collapse_vbox(\number\nextbox)}% + \fi + \doifelsenothing{#1}{\setsnapvalue\v!normal}{\autosetsnapvalue{#1}}% + \ctxlua{vspacing.snap_box(\number\nextbox,\number\attribute\snapmethodattribute)}% +% \ifzeropt\ht\nextbox +% \ifzeropt\dp\nextbox +% \box\nextbox % here, else empty and zero +% \kern-\bodyfontlineheight +% \else +% \box\nextbox +% \fi +% \else + \box\nextbox +% \fi + \egroup} + +\def\docheckgridsnapping + {\edef\askedgridmode{\layoutparameter\c!grid}% needs checking by WS + \doifelse\askedgridmode\v!no + {\gridsnappingfalse + \resetsystemmode\v!grid + \resetsnapvalue} + {\gridsnappingtrue + \setsystemmode\v!grid + \autosetsnapvalue\askedgridmode}} + +%D Visualization: + +\definepalet + [grid] + [ one=red, + two=green, + three=blue, + four=gray] + +\def\setgridtracebox#1[#2]% % maybe reverse the order + {\setbox\nextbox#1% + {\hbox + {\hbox to \zeropoint + {\setlayoutcomponentattribute\v!grid\v!test + \color[grid:#2]{\ruledhbox \layoutcomponentboxattribute {\fakebox\nextbox}}% + \hss}% + \flushnextbox}}} + +\chardef\gridboxlinenomode\plusone % 0:nothing 1:all 2:lines 3:frame 4:l/r +\chardef\gridboxlinemode \plusone + +\def\gridboxvbox {\ifcase\gridboxlinemode\vbox\or\ruledvbox\or\vbox\or\ruledvbox\else\ruledvbox\fi} +\def\gridboxwidth{\ifcase\gridboxlinemode0\or.5\or.5\or0\else.5\fi\testrulewidth} + +\def\setgridbox#1#2#3% maybe ifgridsnapping at outer level + {\setbox#1\gridboxvbox to #3 % given size + {\forgetall + \resetteststrut + \offinterlineskip + \hsize#2% + \baselinerulefalse + \ifnum\gridboxlinenomode=\plusthree + \chardef\gridboxlinenomode\ifodd\realpageno\plusone\else\plustwo\fi + \fi + \gridboxvbox % calculated size + {\getrawnoflines{#3}% \getnoflines{#3}% +% \ifgridsnapping \else +% \vskip\topskip +% \vskip-\strutht +% \fi + \scratchdimen#2\advance\scratchdimen \lineheight + \dorecurse\noflines + {\strut + \hskip-.5\lineheight + \ifcase\gridboxlinenomode\or + \rlap + {\hskip.2\bodyfontsize\hskip\scratchdimen + \infofont\hbox to 1em{\hss\recurselevel}}% + \or + \llap + {\infofont\hbox to 1em{\hss\recurselevel}% + \hskip.2\bodyfontsize}% + \fi + \vrule + \!!height \gridboxwidth + \!!depth \gridboxwidth + \!!width \scratchdimen + \par}} + \vfill}} + +%D This has become obsolete: + +\def\fuzzysnappedbox#1#2% \box \unvbox + {#1#2} + +% \def\moveboxontogrid#1#2#3% will become obsolete +% {\doif{#2}\v!top {\setbox#1\hbox{\snaptogrid[\v!first]\box#1}}% +% \doif{#2}\v!bottom{\setbox#1\hbox{\snaptogrid[\v!last ]\box#1}}} + +\def\moveboxontogrid#1#2#3% will become obsolete + {} + +%D Helper: + +\def\doassignsomeskip#1\to#2% ook nog \v!halfline+fuzzysnap + {\doifelse{#1}\v!line + {#2\ifgridsnapping + \bodyfontlineheight + \else + \openlineheight + \fi} + {\ifgridsnapping + \assigndimension{#1}{#2}{.25\bodyfontlineheight}{.5\bodyfontlineheight}\bodyfontlineheight + \else + \assigndimension{#1}{#2}\smallskipamount\medskipamount\bigskipamount + \fi}% + \relax} + +% \start \dosetstretch{.25em} \setuptolerance[tolerant,stretch] \input tufte \endgraf \stop +% \start \dosetstretch{.5em} effe flink doorfietsen \stop + +% \def\dosetupgridsnapping % calls too often, only needed in gridsnapping +% {\ctxlua{nodes.setsnapvalue(1,\number\openstrutheight,\number\openstrutdepth)}} +% +% \def\doenablegridsnapping +% {\attribute\snapcategoryattribute\plusone +% \topskip\strutht +% \offinterlineskip} +% +% \def\dodisablegridsnapping +% {\attribute\snapcategoryattribute\attributeunsetvalue +% % reset topskip +% \oninterlineskip} + +% experimental code, not yet interfaced: + +% category: +% 0 == discard discard +% 1 == only if larger largest +% 2 == force even if smaller force +% 3 == only take penalty component penalty +% 4 == add to existing skip add +% 5 == disable (ignore following) disable +% 6 == kill whitespace nowhite +% 7 == discard previous back +% +% penalty: larger wins +% order: larger wins +% category:2,order:5,penalty:10000,skip:value|kw +% +% \defineblankmethod [\v!joinedup] {\ifvmode\nointerlineskip\fi} + +% todo, in grid mode: vspacing.fixed = false + +\let\saveouterspacing \relax % for old times sake +\let\restoreouterspacing\relax % for old times sake + +\newtoks\everybeforeblankhandling +\newtoks\everyafterblankhandling + +\newconditional\someblankdone + +\appendtoks + \blankskip\zeropoint + \attribute\skipcategoryattribute\plusone + \attribute\skippenaltyattribute \attributeunsetvalue + \attribute\skiporderattribute \attributeunsetvalue + \ifgridsnapping % \ifblankflexible + \setfalse\blankisfixed + \else + \settrue\blankisfixed + \fi +\to \everybeforeblankhandling + +\appendtoks + \ifconditional\blankisfixed + \blankskip1\blankskip + \else + \blankskip1\blankskip\!!plus\skipgluefactor\blankskip\!!minus\skipgluefactor\blankskip + \fi +\to \everyafterblankhandling + +% \ifgridsnapping will go + +\appendtoks + \ifgridsnapping + \settrue\blankisfixed + \else + \setfalse\blankisfixed + \fi +\to \everybeforeblankhandling + +\def\setblankcategory#1% + {\settrue\someblankdone + \attribute\skipcategoryattribute#1\relax} + +\def\setblankorder#1% + {\attribute\skiporderattribute#1\relax} + +\def\fixedblankskip + {\settrue\blankisfixed} + +\def\flexibleblankskip + {\setfalse\blankisfixed} + +\def\addblankskip#1#2#3% + {\settrue\someblankdone + \advance\blankskip#1\dimexpr\ifgridsnapping#3\else#2\fi\relax\relax} + +\def\setblankpenalty #1% + {\flushblankhandling + \settrue\someblankdone + \attribute\skipcategoryattribute \plusthree + \attribute\skippenaltyattribute #1\relax + \flushblankhandling} + +\unexpanded\def\startblankhandling + {\par + \ifvmode + \expandafter\dostartblankhandling + \else + \expandafter\nostartblankhandling + \fi} + +\def\nostartblankhandling#1\stopblankhandling + {} + +\def\dostartblankhandling + {\begingroup + \setfalse\someblankdone + \the\everybeforeblankhandling} + +\unexpanded\def\stopblankhandling + {\the\everyafterblankhandling + \ifconditional\someblankdone + \vskip\blankskip + \fi + \endgroup} + +\def\flushblankhandling + {\the\everyafterblankhandling + \ifconditional\someblankdone + \vskip\blankskip + \fi + \setfalse\someblankdone + \the\everybeforeblankhandling} + +% % % % we can move much to lua once we can expand there % % % % + +\unexpanded\def\definevspacingamount + {\dotripleempty\dodefinevspacingamount} + +% \def\dodefinevspacingamount[#1][#2][#3]% +% {\ctxlua{vspacing.setskip("#1",\!!bs\detokenize{#2}\!!es,\!!bs\detokenize{#3}\!!es)}} + +\def\dodefinevspacingamount[#1][#2][#3]% can be combined + {\setvalue{\??vs:#1}{\ifgridsnapping#3\else#2\fi}% + \ctxlua{vspacing.setskip("#1")}} + +\def\addpredefinedblankskip#1#2% + {\settrue\someblankdone + \advance\blankskip#1\dimexpr\csname\??vs:#2\endcsname\relax} + +\def\addaskedblankskip#1#2% + {\settrue\someblankdone + \advance\blankskip#1\dimexpr#2\relax} + +\unexpanded\def\definevspacing + {\dodoubleempty\dodefinevspacing} + +\def\dodefinevspacing[#1][#2]% + {\ctxlua{vspacing.setmap("#1","#2")}} + +\unexpanded\def\vspacing + {\dosingleempty\dovspacing} + +% todo: when packed blocks blank, we need to enable forced + +\def\dovspacing % blank also has a \flushnotes + {\ifinpagebody + \expandafter\dovspacingyes + \else\ifconditional\noblankinpacked % todo: better reset this conditional in pagebody + \expandafter\expandafter\expandafter\dovspacingnop + \else + \expandafter\expandafter\expandafter\dovspacingyes + \fi\fi} + +\def\dovspacingyes[#1]% + {\ifmmode\else\ctxlua{vspacing.analyse("\iffirstargument#1\else\s!default\fi")}\fi} + +\def\dovspacingnop[#1]% + {\ifmmode\else\par\fi} + +% todo: check them and make them faster: + +\definecomplexorsimple\setupvspacing + +\let\currentvspacing\empty + +\def\complexsetupvspacing[#1]% + {\edef\currentvspacing{#1}} + +\def\simplesetupvspacing + {\ifx\empty\currentvspacing\else + \let\currentvspacing\s!default + \fi + \simplesetupwhitespace} + +\def\restorestandardblank + {\let\currentvspacing\v!standard} + +% used both + +\def\doinhibitblank{\vspacing[\v!disable]} % can be made faster +\def\inhibitblank {\vspacing[\v!disable]} % can be made faster + +\let\setupblank \setupvspacing +\let\simplesetupblank\simplesetupvspacing +\let\blank \vspacing + +% category:4 is default + +% \definevspacingamount[\v!big] [\bigskipamount] [\openlineheight] +% \definevspacingamount[\v!medium] [\medskipamount] [0.50\openlineheight] +% \definevspacingamount[\v!small] [\smallskipamount] [0.25\openlineheight] +% \definevspacingamount[\v!line] [\openlineheight] [\openlineheight] +% \definevspacingamount[\v!halfline][0.50\openlineheight][0.50\openlineheight] +% \definevspacingamount[\v!formula] [\medskipamount] [0.50\openlineheight] +% \definevspacingamount[\v!white] [\parskip] [\openlineheight] +% \definevspacingamount[\v!height] [\strutheight] [\strutheight] +% \definevspacingamount[\v!depth] [\strutdepth] [\strutdepth] + +\definevspacingamount[\v!none] [\zeropoint] [\zeropoint] +\definevspacingamount[\v!big] [\bigskipamount] [\bodyfontlineheight] +\definevspacingamount[\v!medium] [\medskipamount] [0.50\bodyfontlineheight] +\definevspacingamount[\v!small] [\smallskipamount] [0.25\bodyfontlineheight] +\definevspacingamount[\v!line] [\openlineheight] [\bodyfontlineheight] +\definevspacingamount[\v!halfline][0.50\openlineheight][0.50\bodyfontlineheight] +\definevspacingamount[\v!formula] [\medskipamount] [0.50\bodyfontlineheight] +\definevspacingamount[\v!white] [\parskip] [\bodyfontwhitespace] +\definevspacingamount[\v!height] [\strutheight] [\bodyfontstrutheight] +\definevspacingamount[\v!depth] [\strutdepth] [\bodyfontstrutdepth] + +\def\bodyfontwhitespace + {\dimexpr + \ifdim\parskip=\zeropoint + \zeropoint + \else\ifgridsnapping + \bodyfontlineheight + \else + \parskip + \fi\fi + \relax} + +\definevspacing[\v!preference][penalty:-500] % goodbreak +\definevspacing[\v!samepage] [penalty:10000] % real strong +\definevspacing[\v!max] [category:1] +\definevspacing[\v!force] [category:2] +\definevspacing[\v!disable] [category:5] +\definevspacing[\v!nowhite] [category:6] +\definevspacing[\v!back] [category:7] +\definevspacing[\v!always] [category:0] +\definevspacing[\v!weak] [order:0] +\definevspacing[\v!strong] [order:100] + +\definevspacing[\s!default] [\v!white] % was big for a while + +\dorecurse{10} % todo: other values < 4000 + {\expanded{\definevspacing[\v!samepage-\recurselevel][penalty:\the\numexpr4000+250*\recurselevel\relax]}} + +% \setfalse\vspacingenabled +% +% \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\blank \vspacing +\let\defineblank \definevspacing +\let\defineblankmethod\definevspacingamount + +%D The following command is for Wolfgang. It has to be used with +%D care as it does {\em not} work in tandem with the other spacing +%D commands. + +\unexpanded\def\definevspace + {\dotripleempty\dodefinevspace} + +\def\dodefinevspace[#1][#2][#3]% + {\ifthirdargument + \setvalue{\??va#1:#2}{#3}% + \else + \setvalue{\??va:#1}{#2}% + \fi} + +\unexpanded\def\vspace + {\dodoubleempty\dovspace} + +\def\dovspace[#1][#2]% + {\ifsecondargument + \dodovspace[#1][#2]% + \else\iffirstargument + \vspace[][#1]% + \else + \vspace[][\s!default]% + \fi\fi} + +\def\dodovspace[#1][#2]% + {\par + \ifvmode + \removelastskip + \vskip\vspaceamount{#1}{#2}\relax + \fi} + +\def\vspaceamount#1#2% + {\executeifdefined{\??va#1:#2}{\executeifdefined{\??va:#2}\zeropoint}} + +%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 + +% \unexpanded\def\setuplines +% {\dodoubleargument\getparameters[\??rg]} +% +% \unexpanded\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 +% \doifnot\@@rgoption\v!packed{\global\let\afterfirstobeyedline\relax}}}% +% \def\obeyedline +% {\par +% \futurelet\next\dobetweenthelines}% +% \activatespacehandler\@@rgspace +% \GotoPar} +% +% \unexpanded\def\stoplines +% {\endgroup +% \popmacro\checkindentation +% \@@rgafter} +% +% \def\dobetweenthelines +% {\doifmeaningelse\next\obeyedline +% {\@@rginbetween} +% {\afterfirstobeyedline}} +% +% \setuplines +% [\c!option=, +% \c!before=\blank, +% \c!after=\blank, +% \c!inbetween=\blank, +% \c!indenting=\v!no, +% \c!space=\v!default] + +%D Contrary to \MKII\ we can now define classes of lines (generalized by +%D Wolfgang). I will probably rewrite bits in \LUA. + +\let\currentlines\empty + +\def\linesparameter #1{\csname\dolinesparameter{\??rg\currentlines}#1\endcsname} +\def\linesparameterhash#1{\dolinesparameterhash {\??rg\currentlines}#1} + +\def\dolinesparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dolinesparentparameter \csname#1\s!parent\endcsname#2\fi} +\def\dolinesparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\dolinesparentparameterhash\csname#1\s!parent\endcsname#2\fi} + +\def\dolinesparentparameter #1#2{\ifx#1\relax\s!empty\else\dolinesparameter #1#2\fi} +\def\dolinesparentparameterhash#1#2{\ifx#1\relax \else\dolinesparameterhash#1#2\fi} + +\def\dosetlinesattributes#1#2% style color + {\edef\fontattributehash {\linesparameterhash#1}% + \edef\colorattributehash{\linesparameterhash#2}% + \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi + \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi} + +\getparameters + [\??rg] + [\c!option=, + \c!before=\blank, + \c!after=\blank, + \c!inbetween=\blank, + \c!indenting=\v!no, + \c!space=\v!default] + +\unexpanded\def\definelines + {\dodoubleempty\dodefinelines} + +\def\dodefinelines[#1][#2]% + {\getparameters[\??rg#1][\s!parent=\??rg,#2]% + \setvalue{\e!start#1}{\dostartlines[#1]}% + \setvalue{\e!stop #1}{\dostoplines}} + +\unexpanded\def\setuplines + {\dodoubleempty\dosetuplines} + +\def\dosetuplines[#1][#2]% + {\doifelsenothing{#2} + {\getparameters[\??rg][#1]} + {\def\docommand##1{\getparameters[\??rg##1][#2]}% + \processcommacommand[#1]\docommand}} + +\def\dostartlines[#1]% + {\bgroup + \edef\currentlines{#1}% + \linesparameter\c!before + \pushmacro\checkindentation + \whitespace + \begingroup + \dosetlinesattributes\c!style\c!color + \setupindenting[\linesparameter\c!indenting]% + \setupalign[\linesparameter\c!align]% + \typesettinglinestrue + \setupwhitespace[\v!none]% + \obeylines + \ignorespaces + \gdef\afterfirstobeyedline % tzt two pass, net als opsomming + {\gdef\afterfirstobeyedline + {\nobreak + \doifnot{\linesparameter\c!option}\v!packed{\global\let\afterfirstobeyedline\relax}}}% + \def\obeyedline + {\par + \futurelet\next\dobetweenthelines}% + \activatespacehandler{\linesparameter\c!space}% + \GotoPar} + +\def\dostoplines + {\endgroup + \popmacro\checkindentation + \linesparameter\c!after + \egroup} + +\def\dobetweenthelines + {\doifmeaningelse\next\obeyedline + {\linesparameter\c!inbetween} + {\afterfirstobeyedline}} + +\definelines[\v!lines] + +\def\emptylines + {\dosingleempty\doemptylines} + +\def\doemptylines[#1]% + {\endgraf\dorecurse{\iffirstargument#1\else3\fi}\crlf} + +\protect \endinput diff --git a/tex/context/base/spec-def.mkii b/tex/context/base/spec-def.mkii new file mode 100644 index 000000000..ad1a9bb1d --- /dev/null +++ b/tex/context/base/spec-def.mkii @@ -0,0 +1,1016 @@ +%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 module used to be integrated in \type {spec-ini}, +%D but testing optimization is more convenient this way. + +\writestatus{loading}{ConTeXt Special Macros / Definitions} + +\unprotect + +%D Ok, messy, but we need this because we load drivers before +%D references. + +\newif\ifcollectreferenceactions + +%D The following libraries are defined. Two postscript +%D drivers are supported, as well as two mechanisms for +%D interactive texts. +%D +%D \startlinecorrection +%D \starttable[|l|l|l|l|l|] +%D \HL +%D \NC \bf file \NC +%D \bf name \NC +%D \bf calls \NC +%D \bf support \NC +%D \bf program / driver \NC\SR +%D \HL +%D \NC \tttf spec-tex \NC +%D \tttf tex \NC +%D \NC +%D Generic \TEX\ (\DVI) \NC +%D (default) \NC\FR +%D \NC \tttf spec-tpd \NC +%D \tttf \PDF \NC +%D \NC +%D Han The Thanh \NC +%D (pdftex) \NC\MR +%D \NC \tttf spec-ps \NC +%D \tttf postscript \NC +%D \NC +%D Adobe PostScript \NC +%D (default) \NC\MR +%D \NC \tttf spec-tr \NC +%D \tttf rokicki \NC +%D \tttf postscript \NC +%D Thomas Rokicki \NC +%D (dvips) \NC\MR +%D \NC \tttf spec-yy \NC +%D \tttf yandy \NC +%D \tttf postscript \NC +%D YandY \NC +%D (dvipsone, dviwindo) \NC\MR +%D \NC \tttf spec-pdf \NC +%D \tttf pdf \NC +%D \NC +%D Adobe PDF \NC +%D (Acrobat) \NC\MR +%D \NC \tttf spec-win \NC +%D \tttf dviwindo \NC +%D YandY \NC +%D (dviwindo) \NC\MR +%D \NC \tttf spec-htm \NC +%D \tttf html \NC +%D \NC +%D HTML V 2.0 \NC +%D (dvips) \NC\LR +%D \HL +%D \stoptable +%D \stoplinecorrection + +%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. + +\installspecial [\dostartgraymode] [or] [1] +\installspecial [\dostopgraymode] [or] [0] + +\installspecial [\dostartrgbcolormode] [or] [3] +\installspecial [\dostartcmykcolormode] [or] [4] +\installspecial [\dostartgraycolormode] [or] [1] +\installspecial [\dostopcolormode] [or] [0] + +%D New and experimental: + +\installspecial [\dostartspotcolormode] [or] [2] + +\installspecial [\doregisterrgbspotcolor] [or] [7] +\installspecial [\doregistercmykspotcolor] [or] [8] +\installspecial [\doregistergrayspotcolor] [or] [5] + +\installspecial [\doregisterrgbindexcolor] [or] [7] +\installspecial [\doregistercmykindexcolor] [or] [8] +\installspecial [\doregistergrayindexcolor] [or] [5] + +\installspecial [\doregisterspotcolorname] [or] [2] + +\installspecial [\dostartnonecolormode] [or] [0] +\installspecial [\doregisternonecolor] [or] [0] + +%D For some drivers, the stop special is of no use and can +%D simply call the start one with zero arguments. + +%D \macros +%D {dogetfiguresize,doinsertfile,doinsertMPfile} +%D +%D Probably the most problematic special is the following +%D one. Because we want to be able to support different +%D schemes, we pass a lot of data to it. +%D +%D The support of inserting files (like illustrations) comes in +%D many flavors. Some drivers use scales, some take dimensions. +%D Some need offsets and others act on stored characteristics. +%D They need one thing in common: a filename. Although separate +%D specials for different formats sometimes are more clear, we +%D decided to combine them all in one: +%D +%D \starttyping +%D \doinsertfile {type,method} {file,label} +%D {xscale} {yscale} {x} {y} {w} {h} +%D {options} +%D \stoptyping +%D +%D The scale is given percents, the other values are base +%D points. +%D +%D Per 2006 we have simplified this model. The amount of drivers +%D is not growing and all support scaling. We pass variables via +%D Driver specific macros. +%D +%D \starttyping +%D \doinsertfile +%D \stoptyping +%D +%D The special is implemented as \type{or}. Because \DVIPSONE\ +%D understands them all, a chain of alternatives would generate +%D multiple occurrences of the same illustration. +%D +%D When option 1 is passed, the viewers is asked to present a +%D preview, like the first frame of a movie. + +\installspecial [\dogetfiguresize][or] [0] % now a special +\installspecial [\doinsertfile] [or] [0] % [9] +\installspecial [\doinsertMPfile] [or] [1] % speed up + +%D No start||stop construction is needed here, because there in +%D no further interference of \TEX. All dimensions are output +%D in points and scales as a number, where 100 equal 100\%. (We +%D used to pass scaled points). + +%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 + +\installspecial [\doinsertsoundtrack] [or] [3] + +%D \macros +%D {dogetnofinsertpages} +%D +%D Some file formats support more than one page, like \PDF, +%D and for special applications, one may want to have access +%D to the total number of pages. +%D +%D \starttyping +%D \dogetnofinsertpages{filename} +%D \stoptyping +%D +%D The number is also available after the insert is placed, +%D since inclusion may take place immediate when an insert is +%D called upon. + +\def\nofinsertpages{1} % one of the few 'talk backs' + +\installspecial [\dogetnofinsertpages] [or] [1] + +%D \macros +%D {dostartrotation, +%D dostoprotation} +%D +%D We support rotation with the special: +%D +%D \starttyping +%D \dostartrotation {angle} ... \dostoprotation +%D \stoptyping +%D +%D For the moment these specials are installed as +%D category \type{or}. + +\installspecial [\dostartrotation] [or] [1] +\installspecial [\dostoprotation] [or] [0] + +%D \macros +%D {dostartscaling, +%D dostopscaling} +%D +%D Scaling is also supported: +%D +%D \starttyping +%D \dostartscaling {x} {y} ... \dostopscaling +%D \stoptyping +%D +%D Like the previous one, these specials are of category +%D \type{or}. + +\installspecial [\dostartscaling] [or] [2] +\installspecial [\dostopscaling] [or] [0] + +%D \macros +%D {dostartmirroring, +%D dostopmirroring} +%D +%D And indeed, mirroring is there too: +%D +%D \starttyping +%D \dostartmirroring {x} {y} ... \dostopmirroring +%D \stoptyping +%D +%D Again these specials are installed as category \type{or}. + +\installspecial [\dostartmirroring] [or] [0] +\installspecial [\dostopmirroring] [or] [0] + +%D \macros +%D {dostartnegative, +%D dostopnegative} +%D +%D When producing output for an image setter, negating the +%D page comes into view. Here are the tools: + +\installspecial [\dostartnegative] [or] [0] +\installspecial [\dostopnegative] [or] [0] + +%D \macros +%D {dostartoverprint, +%D dostopoverprint} +%D +%D Rudimentary overprint (knockout) control is implemented +%D using: + +\installspecial [\dostartoverprint] [or] [0] +\installspecial [\dostopoverprint] [or] [0] + +%D The following two specials are used in for instance \type +%D {\vadjust}'d margin material inside colored paragraphs. + +\installspecial [\dostartgraphicgroup] [or] [0] +\installspecial [\dostopgraphicgroup ] [or] [0] + +%D \macros +%D {doselectfirstpaperbin, +%D doselectsecondpaperbin} +%D +%D Here are some very printer||specific ones. No further +%D comment. + +\installspecial [\doselectfirstpaperbin] [or] [0] +\installspecial [\doselectsecondpaperbin] [or] [0] + +%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). + +\installspecial [\doovalbox] [or] [8] + +%D \macros +%D {dostartclipping,dostopclipping} +%D +%D Clipping is implemented in such a way that an arbitrary +%D can be fed. +%D +%D \starttyping +%D \dostartclipping {pathname}{width} {height} +%D \dostopclipping +%D \stoptyping +%D +%D + +\installspecial [\dostartclipping] [or] [3] +\installspecial [\dostopclipping] [or] [0] + +%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. + +\installspecial [\dosetupidentity] [and] [6] + +%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. + +\installspecial [\dosetuppaper] [and] [3] + +%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. + +\installspecial [\dosetupprinter] [and] [5] + +%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}. + +\installspecial [\dosetupinteraction] [and] [0] + +\installspecial [\dosetupopenaction] [and] [0] +\installspecial [\dosetupscreen] [and] [5] +\installspecial [\dosetuppageview] [and] [1] + +\installspecial [\dosetupcloseaction] [and] [0] +\installspecial [\dosetupopenpageaction] [and] [0] +\installspecial [\dosetupclosepageaction] [and] [0] +\installspecial [\dosetuprenderingopenpageaction] [and] [0] +\installspecial [\dosetuprenderingclosepageaction] [and] [0] + +% new, yet undocumented, replaces \dosetupscreen + +\installspecial [\dosetupcropbox] [and] [4] +\installspecial [\dosetuptrimbox] [and] [4] +\installspecial [\dosetupartbox] [and] [4] +\installspecial [\dosetupbleedbox] [and] [4] + +%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 +%D \dostophide +%D \stoptyping + +\installspecial [\dostarthide] [or] [0] +\installspecial [\dostophide] [or] [0] + +%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. + +\installspecial [\dostartgotolocation] [and] [6] +\installspecial [\dostopgotolocation] [and] [0] +\installspecial [\dostartgotorealpage] [and] [5] +\installspecial [\dostopgotorealpage] [and] [0] + +%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} + +\installspecial [\dostartgotoJS] [and] [3] +\installspecial [\dostopgotoJS] [and] [0] +\installspecial [\doflushJSpreamble][and] [1] + +%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. + +\installspecial [\dostartthisislocation] [and] [1] +\installspecial [\dostopthisislocation] [and] [0] +\installspecial [\dostartthisisrealpage] [and] [1] +\installspecial [\dostopthisisrealpage] [and] [0] + +%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: + +\installspecial [\doresetgotowhereever] [and] [0] + +%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. + +\installspecial [\dostartexecutecommand] [and] [4] +\installspecial [\dostopexecutecommand] [and] [0] + +%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 + +\installspecial [\dostartobject] [or] [5] +\installspecial [\dostopobject] [or] [0] +\installspecial [\doinsertobject] [or] [2] +\installspecial [\doresetobjects] [or] [0] + +%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. + +\installspecial [\doregisterfigure] [or] [2] +\installspecial [\doregisterfigurecolor][or] [1] + +% %D \macros +% %D {dogetobjectreference} +% %D +% %D For very special purposes, one can ask for the internal +% %D reference to the object. Beware! +% +% \installspecial [\dogetobjectreference] [or] [3] +% +% %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 ---} + +\installspecial [\dostartrunprogram] [and] [4] +\installspecial [\dostoprunprogram] [and] [0] +\installspecial [\dostartgotoprofile] [and] [3] +\installspecial [\dostopgotoprofile] [and] [0] +\installspecial [\dobeginofprofile] [and] [4] +\installspecial [\doendofprofile] [and] [0] + +%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. + +\installspecial [\doinsertbookmark] [and] [5] + +%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). + +\installspecial [\dosetpagetransition] [or] [2] + +%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 + +\installspecial [\dopresetlinefield] [or] [9] +\installspecial [\dopresettextfield] [or] [9] +\installspecial [\dopresetchoicefield] [or] [8] +\installspecial [\dopresetpopupfield] [or] [8] +\installspecial [\dopresetcombofield] [or] [8] +\installspecial [\dopresetpushfield] [or] [7] +\installspecial [\dopresetcheckfield] [or] [7] +\installspecial [\dopresetradiofield] [or] [8] +\installspecial [\dopresetradiorecord] [or] [5] + +%D \macros +%D {dodefinefieldset,dogetfieldset,doiffieldset} +%D +%D Field sets, used in resetting and submitting, are handled +%D by: + +\installspecial [\dodefinefieldset] [or] [2] +\installspecial [\dogetfieldset] [or] [1] +\installspecial [\doiffieldset] [or] [2] + +%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 + +\installspecial [\dosetfieldstatus] [or] [4] + +%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 + +\installspecial [\doregistercalculationset] [or] [1] + +%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 + +\installspecial[\doinsertcomment] [and] [8] +\installspecial[\doflushcomments] [and] [0] + +%D \macros +%D {dosetposition, dosetpositionwhd, dosetpositionplus, +%D dosetpositionpapersize} +%D +%D Not natural to \TEX, but available in \PDFTEX, and by +%D means of postprocessed \DVI, we can save and call upon +%D positions. +%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 This is one of the few specials where when using \PDFTEX\ +%D the driver directly deals with the utility file. + +%D Support is moved to spec-mis.tex. The whole idea originates +%D and was implemented first in \PDFTEX. Later \DVIPDFMX\ +%D supported the \CONTEXT\ specific specials and nowadays +%D \PDFTEX\ supports this feature in \DVI\ mode and \XETEX\ +%D implements it as well. This means that only \ALEPH\ is +%D still dependent on specials, but that variant of \TEX\ has +%D become obsolete anyway. + +% \installspecial [\dosetposition] [or] [1] +% \installspecial [\dosetpositionwhd] [or] [4] +% \installspecial [\dosetpositionplus] [or] [5] + +% \installspecial [\dosetpositionpapersize] [or] [2] + +%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. + +\installspecial [\dostarttransparency] [or] [2] +\installspecial [\dostoptransparency] [or] [0] + +%D \macros +%D {doattachfile} +%D +%D \starttyping +%D \doattachfile{title}{width}{height}{depth}{color}{symbol}{filename}{source} +%D \stoptyping + +\installspecial [\doattachfile] [or] [8] + +%D Experimental (properties): + +\installspecial[\dostartviewerlayer] [or] [1] +\installspecial[\dostopviewerlayer] [or] [0] +\installspecial[\dodefineviewerlayer] [or] [5] +%installspecial[\doflushviewertextlayers] [or] [0] +%installspecial[\doflushviewerpagelayers] [or] [0] +\installspecial[\domakeviewerlayerlist] [or] [1] + +\installspecial[\doinsertrenderingwindow] [or] [4] +\installspecial[\doinsertrendering] [or] [4] +\installspecial[\doinsertrenderingobject] [or] [4] +\installspecial[\doinsertrenderingobject] [or] [4] + +\installspecial[\dostartfonteffect] [or] [3] +\installspecial[\dostopfonteffect] [or] [0] + +%D From now on, mapfile loading is also a special; we assume the +%D more or less standard dvips syntax. + +\installspecial[\doresetmapfilelist] [and] [0] +\installspecial[\doloadmapfile] [and] [2] % + - = | filename +\installspecial[\doloadmapline] [and] [2] % + - = | fileline + +%D We define a couple of backends: + +\defineoutput [dvipsone] [dvi,ps,yy] +\defineoutput [dviwindo] [dvi,ps,yy,win] +\defineoutput [dvips] [dvi,ps,tr] +\defineoutput [dviview] [dvi,ps,tr,dv] +\defineoutput [pdftex] [tpd] +\defineoutput [pdf] [tpd] +\defineoutput [dvipdfm] [dpm] +\defineoutput [dpm] [dpm] +\defineoutput [dvipdfmx] [dpx] +\defineoutput [dpx] [dpx] +\defineoutput [acrobat] [pdf,ps,tr] + +\defineoutput [xetex] [dpx,xet] +\defineoutput [xtx] [dpx,xet] +\defineoutput [xdv] [dvi,xtx,xet] +\defineoutput [xdv2pdf] [dvi,xtx,xet] + +%D We don't enable \ACROBAT, because pure \POSTSCRIPT\ is not +%D that strong on objects and \PDFTEX\ does a better job. +%D Some reasonable alternatives are: +%D +%D \starttyping +%D \setupoutput [dvipsone,acrobat] +%D \setupoutput [dviwindo,acrobat] +%D \stoptyping +%D +%D Although, better is: +%D +%D \starttyping +%D \setupoutput [pdftex] +%D \stoptyping + +%D Please let me know if we need more. From now on we default +%D to: + +\appendtoks + \setupoutput[dvips]% +\to \everydump + +\protect \endinput diff --git a/tex/context/base/spec-dpm.mkii b/tex/context/base/spec-dpm.mkii new file mode 100644 index 000000000..efecd7928 --- /dev/null +++ b/tex/context/base/spec-dpm.mkii @@ -0,0 +1,446 @@ +%D \module +%D [ file=spec-dpm, +%D version=1998.11.24, +%D title=\CONTEXT\ Special Macros, +%D subtitle=DVIPDFM 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. + +\unprotect + +%D This driver is build on top of the general \PDF\ macros, +%D as defined in \type{spec-fdf}, so we inherit that one. Remark: +%D this driver is no longer actively maintained, use the dpx one +%D instead! + +\startspecials[dpm][reset,fdf] + +%D \macros +%D {jobsuffix} +%D +%D Because no intermediate output format is used, we set the +%D jobsuffix to \PDF. + +\setjobsuffix{pdf} + +%D Literal \PDF\ inclusion is implemented as: + +\def\PDFcode #1{\special{pdf: content #1}} +\def\PDFcontentcode#1{\special{pdf: content #1}} +\def\PDFdirectcode #1{\special{pdf: literal #1}} + +%D \macros +%D {dosetuppaper} +%D +%D A simple one. + +\def\doDPMsetuppaper#1#2#3% + {\bgroup + \scratchdimen#2\edef\width {\the\scratchdimen\space}% + \scratchdimen#3\edef\height{\the\scratchdimen\space}% + \special{pdf: pagesize width \width height \height}% + \global\let\doDPMsetuppaper\gobblethreearguments + \egroup} + +\definespecial\dosetuppaper#1#2#3% + {\doDPMsetuppaper{#1}{#2}{#3}} + +%D \macros +%D {doinsertfile} +%D +%D Only \METAPOST, \JPG\ and \PDF\ inclusion are supported. + +\definespecial\doinsertfile + {\dofileinsertion{dpm}\@@DriverImageType} + +\definefileinsertion{dpm}{mps}% + {\PointsToWholeBigPoints\@@DriverImageWidth \width + \PointsToWholeBigPoints\@@DriverImageHeight\height + \special + {PSfile="\@@DriverImageFile"\space + llx=\EPSllx\space lly=\EPSlly\space + urx=\EPSurx\space ury=\EPSury\space + rwi=\width0\space rhi=\height0}} + +\definefileinsertion{dpm}{pdf}% + {\special{pdf: epdf + width \@@DriverImageWidth \space + height \@@DriverImageHeight\space + (\@@DriverImageFile)}} + +\definefileinsertion{dpm}{jpg}% + {\special{pdf: image + width \@@DriverImageWidth \space + height \@@DriverImageHeight\space + (\@@DriverImageFile)}} + +\definefileinsertion{dpm}{mov}{\doPDFinsertmov} +\definefileinsertion{dpm}{avi}{\doPDFinsertmov} + +%D \macros +%D {doinsertsoundtrack} +%D +%D Sounds are supported too. + +\definespecial\doinsertsoundtrack{\doPDFinsertsoundtrack} + +%D \macros +%D {doovalbox} + +\definespecial\doovalbox{\doPDFovalbox} + +%D \macros +%D {dostartgraymode,dostopgraymode, +%D dostartrgbcolormode,dostartcmykcolormode,dostartgraycolormode, +%D dostopcolormode, +%D dostartrotation,dostoprotation, +%D dostartscaling,dostopscaling, +%D dostartmirroring,dostopmirroring, +%D dostartnegative,dostopnegative} +%D +%D Unfortunately the direct \PDF\ inclusion is not suited +%D for the next macros, which means that we cannot use the +%D \type {\doPDF..} alternatives. Since \CONTEXT\ maintains +%D its own colorstack, we use the \DVIPS\ alternatives. + +\definespecial\dostartgraymode #1{\special{color gray #1}} +\definespecial\dostopgraymode {\special{color gray 0}} +\definespecial\dostartrgbcolormode #1#2#3{\special{color rgb #1 #2 #3}} +\definespecial\dostartcmykcolormode#1#2#3#4{\special{color cmyk #1 #2 #3 #4}} +\definespecial\dostartgraycolormode #1{\special{color gray #1}} +\definespecial\dostopcolormode {\special{color gray 0}} +\definespecial\dostartrotation #1{\special{pdf: bt rotate #1}} +\definespecial\dostoprotation {\special{pdf: et}} +\definespecial\dostartscaling #1#2{\special{pdf: bt xscale #1 yscale #2}} +\definespecial\dostopscaling {\special{pdf: et}} +\definespecial\dostartmirroring {\special{pdf: bt xscale -1}} % ? +\definespecial\dostopmirroring {\special{pdf: et}} + +%D Negation is not (yet) supported: + +% \definespecial\dostartnegative {} +% \definespecial\dostopnegative {} +% \definespecial\dostarttransparency {} +% \definespecial\dostoptransparency {} + + +%D \macros +%D {dosetupinteraction, +%D dosetupopenaction,dosetupcloseaction} + +\definespecial\dosetupinteraction% + {\showmessage\m!interactions{21}{DVIPDFM}} + +\definespecial\dosetupopenaction {\doPDFsetupopenaction} +\definespecial\dosetupcloseaction{\doPDFsetupcloseaction} + +%D \macros +%D {doresetgotowhereever, +%D dostartthisisrealpage,dostartthisislocation, +%D dostartgotorealpage,dostartgotolocation,dostartgotoJS} + +\definespecial\doresetgotowhereever {\doPDFresetgotowhereever} +\definespecial\dostartthisislocation{\doPDFstartthisislocation} + +\definespecial\dostartgotolocation{\doPDFstartgotolocation} +\definespecial\dostartgotorealpage{\doPDFstartgotorealpage} +\definespecial\dostartgotoJS {\doPDFstartgotoJS} + +%D \macros +%D {doflushJSpreamble} + +\definespecial\doflushJSpreamble#1% + {\bgroup + \let\compositeJScode=\empty + \def\docommand##1% + {\edef\sanitizedJScode{\getJSpreamble{##1}}% + \@EA\doPSsanitizeJScode\sanitizedJScode\to\sanitizedJScode + \special{pdf: object @JS:#1 <>}% + \edef\compositeJScode{\compositeJScode\space (##1) @JS:#1}}% + \processcommalist[#1]\docommand + \special{pdf: object @JS:JS <>}% + \special{pdf: put @names <>}% + \egroup} + +%D \macros +%D {dostarthide,dostophide} + +\definespecial\dostarthide{} +\definespecial\dostophide {} + +%D \macros +%D {dosetupscreen} + +\definespecial\dosetupscreen {\doPDFsetupscreen \printpaperheight} + +\definespecial\dosetupartbox {\doPDFsetupartbox \printpaperheight} +\definespecial\dosetupcropbox {\doPDFsetupcropbox \printpaperheight} +\definespecial\dosetupbleedbox{\doPDFsetupbleedbox\printpaperheight} +\definespecial\dosetuptrimbox {\doPDFsetuptrimbox \printpaperheight} + +%D \macros +%D {dostartexecutecommand} + +\definespecial\dostartexecutecommand{\doPDFstartexecutecommand} + +%D \macros +%D {dosetupidentity} + +\definespecial\dosetupidentity{\doPDFsetupidentity} + +%D \macros +%D {dostartrunprogam} + +\definespecial\dostartrunprogram{\doPDFstartrunprogram} + +%D \macros +%D {dostartgotoprofile, dostopgotoprofile, +%D dobeginofprofile, doendofprofile} + +\definespecial\dostartgotoprofile{\doPDFstartgotoprofile} + +\definespecial\dobeginofprofile#1#2#3#4% + {\bgroup + \setPDFdestination{#1}% + \scratchdimen#2\edef\width {\the\scratchdimen\space}% + \scratchdimen#3\edef\height{\the\scratchdimen\space}% + \doifsomething{\PDFdestination} + {\special + {pdf: thread @ART::\PDFdestination\space + width \width height \height + <>}}% + \egroup} + +\definespecial\doendofprofile% + {} + +%D \macros +%D {doinsertbookmark} + +\definespecial\doinsertbookmark{\doPDFinsertbookmark} + +%D \macros +%D {dostartobject,dostopobject,doinsertobject} + +% \definespecial\dostartobject#1#2#3#4#5% +% {\bgroup +% \setbox\nextbox=\hbox\bgroup +% \dosetobjectreference{#1}{#2}{#1::#2}% +% \scratchdimen#3\edef\width {\the\scratchdimen\space}% +% \scratchdimen#4\edef\height{\the\scratchdimen\space}% +% \special{pdf: bxobj @#1::#2 width \width height \height}} + +% \definespecial\dostopobject% +% {\special{pdf: exobj}% +% \egroup +% \smashbox\nextbox +% \flushatshipout{\box\nextbox}% +% \egroup} + +\definespecial\dostartobject#1#2#3#4#5% + {\bgroup + \dowithnextbox + {\dosetobjectreference{#1}{#2}{#1::#2}% + \scratchdimen#3\edef\width {\the\scratchdimen\space}% + \scratchdimen#4\edef\height{\the\scratchdimen\space}% + \setbox\nextbox\vbox + {\special{pdf: bxobj @#1::#2 width \width height \height}% + % we need to compensate for the box offset (ugly, sigh) + \scratchdimen\nextboxht + \advance\scratchdimen\nextboxdp + \advance\scratchdimen-#4\relax + \nextboxdp\zeropoint + \nextboxht\zeropoint + \hbox to #3{\hss\lower.5\scratchdimen\box\nextbox\hss}% + \special{pdf: exobj}% + \global\let\currentPDFresources\empty}% + \smashbox\nextbox + \flushatshipout{\box\nextbox}% + \egroup}% + \hbox\bgroup} + +\definespecial\dostopobject + {\egroup} + + +\definespecial\doinsertobject#1#2% + {\hbox + {\dogetobjectreference{#1}{#2}\PDFobjectreference + \ifx\PDFobjectreference\empty \else + \special{pdf: usexobj @#1::#2}% + \fi}} + +%D \macros +%D {dosetpagetransition} + +\definespecial\dosetpagetransition{\doPDFsetpagetransition} + +%D \macros +%D {doinsertcomment, doflushcomments} + +\definespecial\doinsertcomment{\doPDFinsertcomment} +\definespecial\doflushcomments{\doPDFflushcomments} + +%D \macros +%D {dopresetlinefield,dopresettextfield, +%D dopresetchoicefield,dopresetpopupfield,dopresetcombofield, +%D dopresetpushfield,dopresetcheckfield, +%D dopresetradiofield,dopresetradiorecord} + +\definespecial\dopresetlinefield {\doFDFpresetlinefield} +\definespecial\dopresettextfield {\doFDFpresettextfield} +\definespecial\dopresetchoicefield{\doFDFpresetchoicefield} +\definespecial\dopresetpopupfield {\doFDFpresetpopupfield} +\definespecial\dopresetcombofield {\doFDFpresetcombofield} +\definespecial\dopresetpushfield {\doFDFpresetpushfield} +\definespecial\dopresetcheckfield {\doFDFpresetcheckfield} +\definespecial\dopresetradiofield {\doFDFpresetradiofield} +\definespecial\dopresetradiorecord{\doFDFpresetradiorecord} + +%D \macros +%D {dodefinefieldset,dogetfieldset,doiffieldset} + +\definespecial\dodefinefieldset{\doFDFdefinefieldset} +\definespecial\dogetfieldset {\doFDFgetfieldset} +\definespecial\doiffieldset {\doFDFiffieldset} + +%D \macros +%D {doregistercalculationset} + +\definespecial\doregistercalculationset{\doFDFregistercalculationset} + +%D \macros +%D {doPDFdestination} + +\def\doPDFdestination#1% + {\special{pdf: dest (#1) [@thispage /View [/Fit]]}} + +%D \macros +%D {doPDFaction,doPDFannotation,ifsharePDFactions} +%D +%D Sharing is not yet supported. + +\newif\ifsharePDFactions \sharePDFactionsfalse + +\def\dodoPDFaction#1#2#3#4% + {\ifcollectreferenceactions + \xdef\lastPDFaction{#4}% + \else + \bgroup + % this is yet untested + %\ifsharePDFactions + % \ifcase\similarreference\relax + % \xdef\lastPDFaction{<<#4>>}% + % \or + % \global\advance\nofPDFsimilar by 1 + % \special{pdf: object @PDF::sim:\the\nofPDFsimilar\space<<#4>>}% + % \xdef\lastPDFaction{@PDF::sim:\the\nofPDFsimilar}% + % \else + % % leave \lastPDFaction untouched + % \fi + %\else + \xdef\lastPDFaction{<<#4>>}% + %\fi + \scratchdimen#2\edef\width {\the\scratchdimen\space}% + \scratchdimen#3\edef\height{\the\scratchdimen\space}% + \special{pdf: ann #1 width \width height \height + <>}% + \egroup + \fi} + +\def\doPDFaction#1#2#3% + {\dodoPDFaction\empty{#1}{#2}{#3}} + +\def\doPDFannotation#1#2#3% + {\bgroup + \scratchdimen#1\edef\width {\the\scratchdimen\space}% + \scratchdimen#2\edef\height{\the\scratchdimen\space}% + \special{pdf: ann width \width height \height + <>}% + \egroup} + +%D \macros +%D {doPDFannotationobject,doPDFactionobject} + +\def\doPDFannotationobject#1#2#3#4#5% + {\bgroup + \scratchdimen#3\edef\width {\the\scratchdimen\space}% + \scratchdimen#4\edef\height{\the\scratchdimen\space}% + \special{pdf: ann @#1::#2 width \width height \height <<#5>>}% + \dosetobjectreference{#1}{#2}{@#1::#2}% + \egroup} + +\def\doPDFactionobject#1#2#3#4#5% + {\dodoPDFaction{@#1::#2}{#3}{#4}{#5}% + \dosetobjectreference{#1}{#2}{#1::#2}} + +%D \macros +%D {doPDFaddtocatalog,doPDFaddtoinfo, +%D doPDFpageattribute,doPDFpagesattribute} + +\def\doPDFaddtocatalog#1% + {\special{pdf: put @catalog <<#1>>}} + +\def\doPDFaddtoinfo#1% Is this auto appended? Not checked! + {\special{pdf: docinfo <<#1>>}} % put @docinfo <<#1>>}} + +\def\doPDFpageattribute#1% + {\special{pdf: put @thispage <<#1>>}} + +\def\doPDFpagesattribute#1% + {\special{pdf: put @pages <<#1>>}} + +\def\doPDFpageresource#1% + {\message{[skipping PDF resource]}} + +\let\doPDFresetpageresources \relax +\let\doPDFresetpageattributes\relax + +%D \macros +%D {doPDFbookmark} + +\def\doPDFbookmark#1#2#3#4#5% + {\ifcase#2\else + \scratchcounter#4\advance\scratchcounter\minusone + \special{pdf: out \ifcase#5-\fi#2 + % <>}% + % <> >>}% + <\else(#3)\fi\space /A <> >>}% + \fi} + +%D \macros +%D {doPDFdictionaryobject,doPDFarrayobject} + +\def\doPDFdictionaryobject#1#2#3% + {\special{pdf: object @#1::#2 <<#3>>}} + +\def\doPDFarrayobject#1#2#3% + {\special{pdf: object @#1::#2 [#3]}} + +%D \macros +%D {defaultobjectreference,doPDFgetobjectreference} + +\def\defaultobjectreference#1#2{#1::#2} + +\def\doPDFgetobjectreference#1#2#3% + {\dogetobjectreference{#1}{#2}#3% + \ifx#3\empty\else\edef#3{{#3}}\fi} + +% \def\doPDFgetobjectpage #1#2#3{..} +% \def\doPDFgetobjectpagereference#1#2#3{..} + +\def\doPDFgetpagereference#1#2% + {\edef#2{@page#1}} + +%D Done. + +\stopspecials + +\protect \endinput diff --git a/tex/context/base/spec-dpx.mkii b/tex/context/base/spec-dpx.mkii new file mode 100644 index 000000000..c521da8c7 --- /dev/null +++ b/tex/context/base/spec-dpx.mkii @@ -0,0 +1,794 @@ +%D \module +%D [ file=spec-dpx, +%D version=2005.08.12, +%D title=\CONTEXT\ Special Macros, +%D subtitle=DVIPDFMx support, +%D author=Jin-Hwan Cho, +%D date=\currentdate, +%D copyright={Jin-Hwan Cho \& Hans Hagen}] +%C +%C DVIPDFMx is an eXtended version of the DVIPDFM, a DVI to PDF +%C translator, still under construction by Jin-Hwan Cho and +%C Shunsaku Hirata. +%C +%C It supports multi-byte character encodings and large character +%C sets for East Asian languages by CID-keyed font technology, +%C and many features including PDF encryption, PDF bookmarks and +%C annotations with Chinese, Japanese, Korean characters, etc. +%C +%C DVIPDFMx (and information) can be downloaded from: +%C +%C http://project.ktug.or.kr/dvipdfmx/ + +\unprotect + +%D This driver is built on top of the general \PDF\ macros, +%D as defined in \type{spec-fdf}, so we inherit that one. + +\startspecials[dpx][reset,fdf] + +%D 1. Modified codes from \type{spec-dpm} + +%D \macros +%D {jobsuffix} +%D +%D Because no intermediate output format is used, we set the +%D jobsuffix to \PDF. + +\setjobsuffix{pdf} + +%D Map files (experimental) + +\definespecial\doloadmapfile#1#2% + {\flushatshipout{\special{pdf:mapfile +#2}}} + +%D DVIPDFMx supports the special command \type{pdf: literal ...} +%D since the version \type{dvipdfmx-20021028}. +%D +%D 1. \type{pdf: literal #1} puts the given PDF commands \#1 +%D after changing the text matrix with \type{"1 0 0 1 x y cm"} +%D to set the current DVI position $(x,y)$ to the origin. +%D +%D 2. \type{pdf: literal reverse #1} puts the given PDF commands \#1 +%D after changing the text matrix with \type{"1 0 0 1 -x -y cm"}. +%D +%D 3. \type{pdf: literal direct #1} puts directly the given PDF +%D commands \#1 without changing the text matrix. +%D +%D Since the version \type{dvipdfmx-20050812}, the role of the special +%D command \type{pdf:literal} is changed so that +%D +%D 1. \type{pdf:literal #1} puts the given PDF commands \#1 +%D after changing the text matrix with \type{"1 0 0 1 x y cm"} +%D to set the current DVI position $(x,y)$ to the origin. After that +%D it restores the previous setting by changing the text matrix with +%D \type{"1 0 0 1 -x -y cm"}. +%D +%D 2. \type{pdf:literal direct #1} puts directly the given PDF commands +%D \type {#1} without changing the text matrix. +%D +%D Literal \PDF\ inclusion is implemented as: + +\def\PDFcode #1{\special{pdf:literal #1}} +\def\PDFcontentcode#1{\special{pdf:content #1}} +\def\PDFdirectcode #1{\special{pdf:literal direct #1}} + +%D \type{\dosetuppaper} in \type{spec-dpm} did not work properly +%D because DVIPDFM did not permit changing the page size. +%D +%D However, DVIPDFMx permits different page size in each page +%D since the version \type{dvipdfmx-20021028}. +%D +%D \macros +%D {dosetuppaper} +%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}% + \scratchdimen#3\edef\height{\the\scratchdimen\space}% + \special{pdf:pagesize width \width height \height}% + \egroup} + +%D \macros +%D {doinsertfile} +%D +%D Only \METAPOST, \BMP\ \JPG\ \PNG\ and \PDF\ inclusion are supported. + +\definespecial\doinsertfile + {\dofileinsertion{dpx}\@@DriverImageType} + +%D Even though DVIPDFM supports \METAPOST directly, the funtionality +%D is not good. It conflicts much with \CONTEXT. +%D +%D So, \METAPOST will be treated as the same way as PDFTeX using +%D MPtoPDF in DVIPDFMx since the version \type{dvipdfmx-20021028}. + +%D DVIPDFM (and DVIPDFMx too) supports the image files with +%D the extension, \PDF, \JPG, \PNG, \BMP, and \EPS. + +% \def\handleepsimage +% {\PointsToWholeBigPoints\@@DriverImageWidth \width +% \PointsToWholeBigPoints\@@DriverImageHeight\height +% \special +% {PSfile="\@@DriverImageFile"\space +% llx=\EPSllx\space lly=\EPSlly\space +% urx=\EPSurx\space ury=\EPSury\space +% rwi=\width0\space rhi=\height0}} + +% \definefileinsertion{dpx}{mps}{\handleepsimage} + +\definefileinsertion{dpx}{mps} + {\hbox + {\convertMPtoPDF\@@DriverImageFile{1}{1}% + \global\let\PDFimagereference\empty}} + +\def\handlebmpimage + {\special{pdf: image + width \@@DriverImageWidth \space + height \@@DriverImageHeight\space + (\@@DriverImageFile)}} + +\definefileinsertion{dpx}{pdf}{\handlebmpimage} +\definefileinsertion{dpx}{jpg}{\handlebmpimage} +\definefileinsertion{dpx}{png}{\handlebmpimage} +\definefileinsertion{dpx}{bmp}{\handlebmpimage} + +\definefileinsertion{dpx}{mov}{\doPDFinsertmov} +\definefileinsertion{dpx}{avi}{\doPDFinsertmov} + +%D \macros +%D {doinsertsoundtrack} +%D +%D Sounds are supported too. + +\definespecial\doinsertsoundtrack{\doPDFinsertsoundtrack} + +%D \macros +%D {doovalbox} + +\definespecial\doovalbox{\doPDFovalbox} + +%D \macros +%D {dostartgraymode,dostopgraymode, +%D dostartrgbcolormode,dostartcmykcolormode,dostartgraycolormode, +%D dostopcolormode, +%D dostartrotation,dostoprotation, +%D dostartscaling,dostopscaling, +%D dostartmirroring,dostopmirroring, +%D dostartnegative,dostopnegative} +%D +%D Unfortunately the direct \PDF\ inclusion is not suited +%D for the next macros, which means that we cannot use the +%D \type {\doPDF..} alternatives. Since \CONTEXT\ maintains +%D its own colorstack, we use the \DVIPS\ alternatives. + +\definespecial\dostartgraymode {\doPDFstartgraymode} +\definespecial\dostopgraymode {\doPDFstopgraymode} +\definespecial\dostartrgbcolormode {\doPDFstartrgbcolormode} +\definespecial\dostartcmykcolormode{\doPDFstartcmykcolormode} +\definespecial\dostartgraycolormode{\doPDFstartgraycolormode} +\definespecial\dostartspotcolormode{\doPDFstartspotcolormode} +\definespecial\dostopcolormode {\doPDFstopcolormode} + +\definespecial\doregistercmykspotcolor{\doPDFregistercmykspotcolor} +\definespecial\doregisterrgbspotcolor {\doPDFregisterrgbspotcolor} +\definespecial\doregistergrayspotcolor{\doPDFregistergrayspotcolor} + +\definespecial\doregistercmykindexcolor{\doPDFregistercmykindexcolor} +\definespecial\doregisterrgbindexcolor {\doPDFregisterrgbindexcolor} +\definespecial\doregistergrayindexcolor{\doPDFregistergrayindexcolor} + +\definespecial\doregisterfigurecolor{\doPDFregisterfigurecolor} + +\definespecial\dostartnonecolormode{\doPDFstartnonecolormode} +\definespecial\doregisternonecolor {\doPDFregisternonecolor} + +\definespecial\dostartrotation #1{\special{pdf:btrans rotate #1}} +\definespecial\dostoprotation {\special{pdf:etrans}} +\definespecial\dostartscaling#1#2{\special{pdf:btrans xscale #1 yscale #2}} +\definespecial\dostopscaling {\special{pdf:etrans}} +\definespecial\dostartmirroring {\special{pdf:btrans xscale -1}} +\definespecial\dostopmirroring {\special{pdf:etrans}} + +%D Negation is not (yet) supported: +\definespecial\dostartnegative {\doPDFstartnegative} +\definespecial\dostopnegative {\doPDFstopnegative} +\definespecial\dostartoverprint {\doPDFstartoverprint} +\definespecial\dostopoverprint {\doPDFstopoverprint} + +\definespecial\dostarttransparency{\doPDFstarttransparency} +\definespecial\dostoptransparency {\doPDFstoptransparency} + +\PDFtransparencysupportedtrue + +\def\@@PDT{@PDT@} + +\ifx\PDFcurrenttransparency\undefined + \newcount\PDFcurrenttransparency \PDFcurrenttransparency=0 % -1 +\fi + +\def\assignPDFtransparency#1#2% + {\def\PDFtransparencyidentifier{/Tr#1}% + \def\PDFtransparencyreference{@TR:#2}} % todo: \PDFobjref{TR:#2} + +\def\presetPDFtransparency#1#2% + {\initializePDFtransparency + \executeifdefined{\@@PDT#1:#2}{\dopresetPDFtransparency{#1}{#2}}} + +\def\dopresetPDFtransparency#1#2% + {\global\advance\PDFcurrenttransparency \plusone + \doPDFreserveDPXobject{TR:\the\PDFcurrenttransparency}{<< >>}% hack + \special{pdf:\doPDFcheckedDPXobject{TR:\the\PDFcurrenttransparency}\PDFtransparancydictionary{#1}{#2}{}}% + \edef\PDFtransparencyidentifier{/Tr\the\PDFcurrenttransparency}% + \edef\PDFtransparencyreference {@TR:\the\PDFcurrenttransparency}% + \setxvalue{\@@PDT#1:#2}% + {\noexpand\assignPDFtransparency{\the\PDFcurrenttransparency}{\the\PDFcurrenttransparency}}% + \appendtoPDFdocumentextgstates + {\PDFtransparencyidentifier\space + \PDFtransparencyreference\space}} + +\def\initializePDFtransparency + {\doPDFreserveDPXobject{TR:0}{<< >>}% hack + \special{pdf:\doPDFcheckedDPXobject{TR:0}\PDFtransparancydictionary{1}{1}{/AIS false}}% + \xdef\PDFtransparencyresetidentifier{/Tr0}% + \xdef\PDFtransparencyresetreference{@TR:0}% + \setxvalue{\@@PDT0:0}% + {\noexpand\assignPDFtransparency{0}{0}}% + \appendtoPDFdocumentextgstates + {\PDFtransparencyresetidentifier\space + \PDFtransparencyresetreference\space}% + \global\let\initializePDFtransparency\relax} + +%D \macros +%D {dosetupinteraction, +%D dosetupopenaction,dosetupcloseaction} + +\definespecial\dosetupinteraction + {\showmessage\m!interactions{21}{DVIPDFMx}} + +\definespecial\dosetupopenaction {\doPDFsetupopenaction} +\definespecial\dosetupcloseaction{\doPDFsetupcloseaction} + +%D \macros +%D {doresetgotowhereever, +%D dostartthisisrealpage,dostartthisislocation, +%D dostartgotorealpage,dostartgotolocation,dostartgotoJS} + +\definespecial\doresetgotowhereever {\doPDFresetgotowhereever} +\definespecial\dostartthisislocation{\doPDFstartthisislocation} + +\definespecial\dostartgotolocation{\doPDFstartgotolocation} +\definespecial\dostartgotorealpage{\doPDFstartgotorealpage} +\definespecial\dostartgotoJS {\doPDFstartgotoJS} + +%D \macros +%D {doflushJSpreamble} + +\definespecial\doflushJSpreamble#1% + {\bgroup + \let\compositeJScode\empty + \def\docommand##1% + {\edef\sanitizedJScode{\getJSpreamble{##1}}% + \@EA\doPSsanitizeJScode\sanitizedJScode\to\sanitizedJScode + \special{pdf:object @JS:##1 <>}% + \edef\compositeJScode{\compositeJScode\space (##1) @JS:##1}}% + \processcommalist[#1]\docommand + \special{pdf:names /JavaScript [\compositeJScode]}% + \egroup} + +%D \macros +%D {dostarthide,dostophide} + +\definespecial\dostarthide{} +\definespecial\dostophide {} + +%D \macros +%D {dosetupscreen} + +\definespecial\dosetupscreen {\doPDFsetupscreen \printpaperheight} + +\definespecial\dosetupartbox {\doPDFsetupartbox \printpaperheight} +\definespecial\dosetupcropbox {\doPDFsetupcropbox \printpaperheight} +\definespecial\dosetupbleedbox{\doPDFsetupbleedbox\printpaperheight} +\definespecial\dosetuptrimbox {\doPDFsetuptrimbox \printpaperheight} + +%D \macros +%D {dostartexecutecommand} + +\definespecial\dostartexecutecommand{\doPDFstartexecutecommand} + +%D \macros +%D {dosetupidentity} + +\definespecial\dosetupidentity{\doPDFsetupidentity} + +%D \macros +%D {dostartrunprogam} + +\definespecial\dostartrunprogram{\doPDFstartrunprogram} + +%D \macros +%D {dostartgotoprofile, dostopgotoprofile, +%D dobeginofprofile, doendofprofile} + +\definespecial\dostartgotoprofile{\doPDFstartgotoprofile} + +\definespecial\dobeginofprofile#1#2#3#4% + {\bgroup + \setPDFdestination{#1}% + \scratchdimen#2\edef\width {\the\scratchdimen\space}% + \scratchdimen#3\edef\height{\the\scratchdimen\space}% + \doifsomething{\PDFdestination} + {\special + {pdf:thread @ART::\PDFdestination\space + width \width height \height + <>}}% + \egroup} + +\definespecial\doendofprofile + {} + +%D \macros +%D {doinsertbookmark} + +\definespecial\doinsertbookmark{\doPDFinsertbookmark} + +%D \macros +%D {dostartobject,dostopobject,doinsertobject} +%D +%D Modified to support the color shading feature since version +%D \type{dvipdfmx-20021128}. + +% wd nextbox > #3 ivm offset + +% \definespecial\dostartobject#1#2#3#4#5% +% {\bgroup +% \dowithnextbox +% {\dosetobjectreference{#1}{#2}{@#1::#2}% +% \scratchdimen#3\edef\width {\the\scratchdimen\space}% +% \scratchdimen#4\edef\height{\the\scratchdimen\space}% +% \setbox\nextbox\vbox +% {\special{pdf:bxobj @#1::#2 width \width height \height}% +% % we need to compensate for the box offset (ugly, sigh) +% \scratchdimen\nextboxht +% \advance\scratchdimen\nextboxdp +% \advance\scratchdimen-#4\relax +% \nextboxdp\zeropoint +% \nextboxht\zeropoint +% \hbox to #3{\hss\lower.5\scratchdimen\box\nextbox\hss}% +% \ifx\currentPDFresources\empty +% \else +% \special{pdf:put @resources <<\currentPDFresources>>}% +% \global\let\currentPDFresources\empty +% \fi +% \special{pdf:exobj}}% +% \smashbox\nextbox +% \flushatshipout{\box\nextbox}% +% \egroup}% +% \hbox\bgroup} + +% \definespecial\dostopobject +% {\egroup} + +\def\doDVIPDFMXstartobject#1#2#3#4#5#6% + {\bgroup + \dowithnextbox + {\ifcase#1\or\dosetobjectreference{#2}{#3}{@#2::#3}\fi + \scratchdimen#4\edef\width {\the\scratchdimen\space}% + \scratchdimen#5\edef\height{\the\scratchdimen\space}% + \setbox\nextbox\vbox + {\special{pdf:bxobj @#2::#3 width \width height \height}% + % we need to compensate for the box offset (ugly, sigh) + \scratchdimen\nextboxht + \advance\scratchdimen\nextboxdp + \advance\scratchdimen-#5\relax + \nextboxdp\zeropoint + \nextboxht\zeropoint + \hbox to #4{\hss\lower.5\scratchdimen\box\nextbox\hss}% + \ifx\currentPDFresources\empty + \else + \special{pdf:put @resources <<\currentPDFresources>>}% + \global\let\currentPDFresources\empty + \fi + \special{pdf:exobj}}% + \finalizeobjectbox\nextbox + \smashbox\nextbox + \flushatshipout{\box\nextbox}% + \egroup}% + \hbox\bgroup} + +\def\doDVIPDFMXstopobject + {\egroup} + +\definespecial\dostartobject#1#2#3#4#5% + {\doDVIPDFMXstartobject\plusone{#1}{#2}{#3}{#4}{#5}} + +\definespecial\dostopobject + {\doDVIPDFMXstopobject} + +\definespecial\doinsertobject#1#2% + {\hbox + {\doPDFgetobjectreference{#1}{#2}\PDFobjectreference + \ifx\PDFobjectreference\empty \else + \special{pdf:uxobj @#1::#2}% + \fi}} + +%D \macros +%D {dosetpagetransition} + +\definespecial\dosetpagetransition{\doPDFsetpagetransition} + +%D \macros +%D {doinsertcomment, doflushcomments} + +\definespecial\doinsertcomment{\doPDFinsertcomment} +\definespecial\doflushcomments{\doPDFflushcomments} + +%D \macros +%D {dopresetlinefield,dopresettextfield, +%D dopresetchoicefield,dopresetpopupfield,dopresetcombofield, +%D dopresetpushfield,dopresetcheckfield, +%D dopresetradiofield,dopresetradiorecord} + +\definespecial\dopresetlinefield {\doFDFpresetlinefield} +\definespecial\dopresettextfield {\doFDFpresettextfield} +\definespecial\dopresetchoicefield{\doFDFpresetchoicefield} +\definespecial\dopresetpopupfield {\doFDFpresetpopupfield} +\definespecial\dopresetcombofield {\doFDFpresetcombofield} +\definespecial\dopresetpushfield {\doFDFpresetpushfield} +\definespecial\dopresetcheckfield {\doFDFpresetcheckfield} +\definespecial\dopresetradiofield {\doFDFpresetradiofield} +\definespecial\dopresetradiorecord{\doFDFpresetradiorecord} + +%D \macros +%D {dodefinefieldset,dogetfieldset,doiffieldset} + +\definespecial\dodefinefieldset{\doFDFdefinefieldset} +\definespecial\dogetfieldset {\doFDFgetfieldset} +\definespecial\doiffieldset {\doFDFiffieldset} + +%D \macros +%D {doregistercalculationset} + +\definespecial\doregistercalculationset{\doFDFregistercalculationset} + +%D \type{\doPDFdestination} in \type{spec-dpm} had a bug. +%D +%D \macros +%D {doPDFdestination} + +\def\doPDFdestination#1% + {\special{pdf:names /Dests (#1) [@thispage \PDFpageviewwrd]}} + +%D \macros +%D {doPDFaction,doPDFannotation,ifsharePDFactions} +%D +%D Sharing is not yet supported. + +\newif\ifsharePDFactions \sharePDFactionsfalse + +\def\dodoPDFaction#1#2#3#4% + {\ifcollectreferenceactions + \xdef\lastPDFaction{#4}% + \else + \bgroup + % this is yet untested + %\ifsharePDFactions + % \ifcase\similarreference\relax + % \xdef\lastPDFaction{<<#4>>}% + % \or + % \global\advance\nofPDFsimilar by 1 + % \special{pdf: object @PDF::sim:\the\nofPDFsimilar\space<<#4>>}% + % \xdef\lastPDFaction{@PDF::sim:\the\nofPDFsimilar}% + % \else + % % leave \lastPDFaction untouched + % \fi + %\else + \xdef\lastPDFaction{<<#4>>}% + %\fi + \scratchdimen#2\edef\width {\the\scratchdimen\space}% + \scratchdimen#3\edef\height{\the\scratchdimen\space}% + \special{pdf:ann #1 width \width height \height + <>}% + \egroup + \fi} + +\def\doPDFaction#1#2#3% + {\dodoPDFaction\empty{#1}{#2}{#3}} + +%D \type{\doPDFannotation} in \type{spec-dpm} had a bug. +%D +%D \type{\doPDFannotation} conflicts with \type{\doPDFinsertmov}, +%D since width and height also defined in \type{\doPDFinsertmov}. + +\def\doPDFannotation#1#2#3% + {\bgroup + \edef\data{#3}% + \scratchdimen#1\edef\width {\the\scratchdimen\space}% + \scratchdimen#2\edef\height{\the\scratchdimen\space}% + \special{pdf:ann width \width height \height <<\data>>}% + \egroup} + +%D \macros +%D {doPDFannotationobject,doPDFactionobject} + +\def\doPDFannotationobject#1#2#3#4#5% + {\bgroup + \scratchdimen#3\edef\width {\the\scratchdimen\space}% + \scratchdimen#4\edef\height{\the\scratchdimen\space}% + \special{pdf:ann @#1::#2 width \width height \height <<#5>>}% + \dosetobjectreference{#1}{#2}{@#1::#2}% + \egroup} + +\def\doPDFactionobject#1#2#3#4#5% + {\dodoPDFaction{@#1::#2}{#3}{#4}{#5}% + \dosetobjectreference{#1}{#2}{@#1::#2}} + +%D \macros +%D {doPDFaddtocatalog,doPDFaddtoinfo, +%D doPDFpageattribute,doPDFpagesattribute} + +% we could move much more to spec-fdf + +% \ifx\pdfcatalog \undefined \newtoks\pdfcatalog \fi +% \ifx\pdfinfo \undefined \newtoks\pdfinfo \fi +% \ifx\pdfpageattr \undefined \newtoks\pdfpageattr \fi +% \ifx\pdfpageresources\undefined \newtoks\pdfpageresources \fi +% \ifx\pdfpagesattr \undefined \newtoks\pdfpagesattr \fi + +% \def\doPDFaddtocatalog #1{\expanded{\global\pdfcatalog {#1\the\pdfcatalog }}} +% \def\doPDFaddtoinfo #1{\expanded{\global\pdfinfo {#1\the\pdfinfo }}} +% \def\doPDFpageattribute #1{\expanded{\global\pdfpageattr {#1\the\pdfpageattr }}} +% \def\doPDFpageresource #1{\expanded{\global\pdfpageresources{#1\the\pdfpageresources}}} +% \def\doPDFpagesattribute#1{\expanded{\global\pdfpagesattr {#1\the\pdfpagesattr }}} + +% \def\doPDFresetpageattributes{\global\pdfpageattr\emptytoks} +% \def\doPDFresetpageresources {\global\pdfpageresources\emptytoks} + +% \appendtoks +% \special{pdf: put @catalog <<#1>>}% +% \special{pdf: docinfo <<#1>>}% +% \special{pdf: put @pages <<#1>>}% +% \to \everylastshipout + +% \appendtoks +% \special{pdf: put @thispage <<#1>>}% +% \to\everyshipout + +\def\doPDFaddtocatalog#1% + {\special{pdf:put @catalog <<#1>>}} + +\def\doPDFaddtoinfo#1% + {\special{pdf:put @docinfo <<#1>>}} + +\def\doPDFpageattribute#1% + {\special{pdf:put @thispage <<#1>>}} + +\def\doPDFpagesattribute#1% + {\special{pdf:put @pages <<#1>>}} + +\def\doPDFpageresource#1% + {\special{pdf:put @resources <<#1>>}} + +\let\doPDFresetpageresources \relax +\let\doPDFresetpageattributes\relax + +%D \type{\doPDFbookmark} in \type{spec-dpm} had a bug. +%D The openbookmark option \#5 is not supported yet. +%D +%D \macros +%D {doPDFbookmark} + +\def\doPDFbookmark#1#2#3#4#5% + {\ifcase#1\else + %\scratchcounter#4\advance\scratchcounter\minusone + \special{pdf:outline #1 %\ifcase#5 opened\fi + % <>>>}% + % <> >>}% + <\else(#3)\fi\space /A <> >>}% + \fi} + +%D \macros +%D {doPDFdictionaryobject,doPDFarrayobject} + +% Dvipdfmx can't handle +% +% \special{pdf:put @foo << /Bar @bar >>} +% \special{pdf:put @bar << /Foo @foo >>} +% +% Objects must be defined before they are used. +% +% \special{pdf:obj @foo << >>} +% \special{pdf:obj @bar << >>} +% \special{pdf:put @foo << /Bar @bar >>} +% \special{pdf:put @bar << /Foo @foo >>} +% +% However, this only works for dictionary and array. + +\def\doPDFreserveDPXobject#1#2% + {\ifundefined{r:pdx:d:#1}% + % we need a \flushatshipoutprep (prepended, normally appended) + \flushatshipout{\special{pdf:object @#1 #2}}% + \global\letvalue{r:pdx:d:#1}\empty + \fi} + +\def\doPDFreserveDPXobjectfirst#1#2% + {\ifundefined{r:pdx:d:#1}% + \doglobal\prependtoks\special{pdf:object @#1 #2}\to\everyfirstshipout + \global\letvalue{r:pdx:d:#1}\empty + \fi} + +\def\doPDFcheckedDPXobject#1{\ifundefined{r:pdx:d:#1}object\else put\fi\space @#1\space} + +% new, experimental, can save a run, bugged, too many xforms now +% +% \def\doreservePDFobject#1#2% +% {\dosetobjectreference{#1}{#2}{@#1::#2}} +% +% \def\doPDFreserveddictionaryobject#1#2#3% +% {\flushatshipout{\special{pdf:object @#1::#2 << #3 >>}}} +% +% \def\doPDFreservedarrayobject#1#2#3% +% {\flushatshipout{\special{pdf:object @#1::#2 [ #3 ]}}} +% +% \doreservePDFobject{FDF}{docuextgstates} +% \doreservePDFobject{FDF}{colorspaces} +% \doreservePDFobject{FDF}{docushades} + +% so this is to be checked + +\def\doPDFdictionaryobject#1#2#3% + {\flushatshipout + {\special{pdf:\doPDFcheckedDPXobject{#1::#2}<<#3>>}% + \dosetobjectreference{#1}{#2}{@#1::#2}}} + +\def\doPDFarrayobject#1#2#3% + {\flushatshipout + {\special{pdf:\doPDFcheckedDPXobject{#1::#2}[#3]}% + \dosetobjectreference{#1}{#2}{@#1::#2}}} + +%D \macros +%D {defaultobjectreference,doPDFgetobjectreference} + +\def\defaultobjectreference#1#2{@#1::#2} + +%D \type{\doPDFgetobjectreference} in \type{spec-dpm} had a bug. + +\def\doPDFgetobjectreference#1#2#3% + {\dogetobjectreference{#1}{#2}#3% + \ifx#3\empty\else\edef#3{#3}\fi} + +\def\doPDFgetpagereference#1#2% + {\edef#2{@page#1}} + +%D Done. + +% %D 2. Modified codes from \type{spec-fdf} +% +% \definespecial\dostartgraphicgroup{\special{pdf: literal direct q}} +% \definespecial\dostopgraphicgroup {\special{pdf: literal direct Q}} + +%D 3. Copied codes from \type{spec-tpd} + +%D \macros +%D {dostartclipping,dostopclipping} +%D +%D Clipping in \PDFTEX\ is rather trivial. We can even hook +%D in \METAPOST\ without problems. + +\definespecial\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}% + \PDFcode + {q 0 w \MPclippath\space W n}} + +\definespecial\dostopclipping + {\PDFcode{Q n}} + +%D 4. Modified codes from \type{supp-pdf} + +\def\dosetMPsomePDFshade#1#2% + {\global\advance\currentPDFshade \plusone + \special{pdf:object @ftn:Sh:\currentPDFshade\space + <>}% + \special{pdf:object @obj:Sh:\currentPDFshade\space + <>}% + \appendtoPDFdocumentshades{/Sh\the\currentPDFshade\space @obj:Sh:\currentPDFshade}% + \setxvalue{\@@MPSK#2}{\noexpand\dohandleMPshade{\the\currentPDFshade}}} + +\def\handleMPfigurespecial#1#2#3#4#5#6#7% toto : combine with ext fig + {\doiffileelse{#7} + {\vbox to \zeropoint + {\vss + \hbox to \zeropoint + {\special{pdf:btrans matrix #1 #2 #3 #4 #5 #6}% + \rlap{\special{pdf:image width 1bp height 1bp (#7)}} + \special{pdf:etrans}\hss}}} + {\message{[unknown figure #7]}}} + +%D 5. Modified codes from \type{supp-pdf} + +\let\handleMPfshow\dohandleMPfshow + +\newcounter\MPPDFcounter + +\newcounter\MPPDFobjectcounter + +\def\setMPPDFobject#1#2% resources boxnumber + {\doglobal\increment\MPPDFobjectcounter + \xdef\getMPPDFobject + {\vbox to \the\ht#2% + {\vss + \hbox to \the\wd#2% + {%\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% + \box#2% + \doDVIPDFMXstopobject} + +\let\getMPPDFobject\gobbletwoarguments + +\definespecial\doinsertMPfile#1% + {\doiffileelse{./#1}{\includeMPasPDF{./#1}}{\message{[MP #1]}}} + +%D Experimental (untested): + +\definespecial\dostartfonteffect#1#2#3% + {\ifdim#2>\zeropoint + \PointsToBigPoints{#2}\ascii + \PDFdirectcode{\ascii\space w}% + \fi + \ifdim#3\points=\onepoint\else + \scratchdimen#3\points + \PDFdirectcode{\withoutpt{\the\scratchdimen}\space Tc}% + \fi + \PDFdirectcode{\purenumber#1 Tr}} + +\definespecial\dostopfonteffect + {\PDFdirectcode{1 w 0 Tc 0 Tr}} + +%D 6. Modified codes from \type{core-obj} +%D +%D In the viewpoint of TeX, the special command \type{pdf:uxobj @obj} +%D generates a box with zero point width and zero point height so that +%D it must be careful to place the box at the reference point. + +\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}% + \fi\fi}}% + \box\scratchbox + \elabelgroup} + +\stopspecials + +\protect \endinput diff --git a/tex/context/base/spec-dvi.mkii b/tex/context/base/spec-dvi.mkii new file mode 100644 index 000000000..1a8f653f0 --- /dev/null +++ b/tex/context/base/spec-dvi.mkii @@ -0,0 +1,118 @@ +%D \module +%D [ file=spec-dvi, +%D version=1996.01.25, +%D title=\CONTEXT\ Special Macros, +%D subtitle=Generic \TEX\ Solutions, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 {dostartobject, +%D dostopobject, +%D doinsertobject} +%D +%D Reuse of object is not supported by the \DVI\ format. We +%D therefore just duplicate them using boxes. + +\setjobsuffix{dvi} % can be overloaded in other spec's + +\startspecials[tex] + +\newbox\DVIobjects \newcounter\DVIobjectcounter + +\definespecial\dostartobject#1#2#3#4#5% + {\setbox\nextbox\vbox\bgroup + \def\dodostopobject + {\egroup + \doglobal\increment\DVIobjectcounter + \global\setbox\DVIobjects\vbox + {\offinterlineskip + \forgetall + \unvbox\DVIobjects + \setbox\nextbox\hbox{\box\nextbox}% + \wd\nextbox\zeropoint + \dp\nextbox\zeropoint + \ht\nextbox\onepoint + \allowbreak + \box\nextbox}% + \dosetobjectreference{#1}{#2}{\DVIobjectcounter}}} + +\definespecial\dostopobject + {\dodostopobject} + +\definespecial\doinsertobject#1#2% + {\bgroup + \dogetobjectreference{#1}{#2}\DVIobjectreference + \splittopskip\zeropoint + \setbox0=\copy\DVIobjects + \dimen0=\DVIobjectreference\onepoint + \advance\dimen0 -\onepoint + \setbox2\vsplit0 to \dimen0 + \ifdim\ht0>\onepoint + \setbox0\vsplit0 to \onepoint + \fi + \unvbox0 + \setbox0\lastbox + \hbox{\unhbox0}% the \hbox is really needed! + \egroup} + +%D \macros +%D {dosetposition, +%D dosetpositionwhd, +%D dosetpositionplus} +%D +%D The next specials only identify a position. It is up to +%D a \DVI\ postprocessing utility to merge the right commands +%D into the utility file. Since in \CONTEXT, we only deal +%D with relative positions, the reference point is not so +%D important. +%D +%D The postprocessor should translate the specials into +%D commands and append these to \type {jobname.tuo} using the +%D format: +%D +%D \starttyping +%D \pospxy {identifier}{page}{x}{y} +%D \pospxywhd {identifier}{page}{x}{y}{w}{h}{d} +%D \pospxyplus{identifier}{page}{x}{y}{w}{h}{d}{list} +%D \stoptyping +%D +%D The postprocessor should, of course, provide the \type +%D {page}, \type {x}, and \type {y} values. + +%D Now in spec-mis.tex: + +% \definespecial\dosetposition#1% +% {\special{pos:pxy "#1"}} +% +% \definespecial\dosetpositionwhd#1#2#3#4% +% {\special{pos:pxywhd "#1" #2 #3 #4}} +% +% \definespecial\dosetpositionplus#1#2#3#4#5% +% {\special{pos:pxyplus "#1" #2 #3 #4 #5}} + +%D The next special tells the position postprocessor what +%D page dimensions were used. + +%D Also in spec-mis.tex: + +% \let\flushDVIpositionpapersize\relax +% +% \definespecial\dosetpositionpapersize#1#2% +% {\xdef\flushDVIpositionpapersize% +% {\special{pos:papersize \number#1 \number#2}% +% \noexpand\installprogram{dvipos -o \jobname.tuo \jobname.dvi }% +% \global\noexpand\let\noexpand\flushDVIpositionpapersize\relax}} +% +% \prependtoksonce \flushDVIpositionpapersize \to \everyshipout + +\stopspecials + +\protect \endinput diff --git a/tex/context/base/spec-fdf.mkii b/tex/context/base/spec-fdf.mkii new file mode 100644 index 000000000..30e15ff34 --- /dev/null +++ b/tex/context/base/spec-fdf.mkii @@ -0,0 +1,3531 @@ +%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. + +%D The name of this module is a bit strange but it started with fields +%D so we keep the name. + +%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 We need to check if we can use \type {\driverreferenced} +%D object in more places. + +%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. + +% to do : /IF << /SW /N >> == no scaling / clipping of widget + +\unprotect + +%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 + +\ifx\pdfpageref\undefined \else \chardef\overcomePDFpage\plusthree \fi + +%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. +%D +%D The \ACROBAT\ programs are not bug free. By setting the next +%D switches, we will at least try to prevent problems. + +\newif\ifovercomePDFbugs \overcomePDFbugsfalse % dest sort problem / 3- +\newif\ifovercomePDFspace \overcomePDFspacetrue % dest sort problem / 3- + +\let\setPDFdestination\gobbleoneargument % a MK specific definition + +%D \macros +%D {sanitizePDFstring} +%D +%D This macro at least tries to convert a arbitrary string +%D into a sequence of characters valid for \PDF\ bookmarks and +%D alike. + +\def\sanitizePDFstring#1\to#2{} + +%D \macros +%D {doPDFdestination, +%D doPDFaction, +%D doPDFannotation, +%D doPDFannotationobject, +%D doPDFdictionaryobject, +%D doPDFarrayobject, +%D doPDFaddtocatalog, +%D doPDFaddtoinfo, +%D doPDFpageattribute, +%D doPDFpageresource, +%D doPDFpagesattribute, +%D doPDFbookmark, +%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 \doPDFdestination #1 name +%D \doPDFaction #1#2#3 width height action +%D \doPDFannotation #1#2#3 width height data +%D \doPDFannotationobject #1#2#3#4#5 class name width height data +%D \doPDFdictionaryobject #1#2#3 class name data +%D \doPDFarrayobject #1#2#3 class name data +%D \doPDFaddtocatalog #1 +%D \doPDFaddtoinfo #1 +%D \doPDFpageattribute #1 +%D \doPDFpageresource #1 +%D \doPDFpagesattribute #1 +%D \doPDFbookmark #1#2#3#4#5 level n text page open +%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. + +\startspecials[fdf] + +%D Common: + +% \def\doPDFgetobjectreference#1#2#3% +% {\def#3{..}} + +\def\doPDFgetobjectpage#1#2#3% + {\dogetobjectreferencepage{#1}{#2}#3% + \ifx#3\empty\def#3{\realfolio}\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%%%%%%%%%%%%%%% +% {\def#2{...}} + +%D Due to the fact that \PDFTEX\ has a different concept of +%D page attributes, we need: + +\let\doPDFresetpageattributes\relax +\let\doPDFresetpageresources \relax + +\appendtoksonce + \doPDFresetpageattributes + \doPDFresetpageresources +\to \everyaftershipout + +\ifx\PDFcode\undefined + \ifx\pdfliteral\undefined + \def\PDFcode#1{\message{[ignored pdfliteral: #1]}} + \else + \let\PDFcode\pdfliteral + \fi +\fi + +%D For special (\METAPOST) effects, we need to build +%D resource dictionaries. Here is the framework. + +\let\docuPDFextgstates\empty +%let\pagePDFextgstates\empty + +\def\checkPDFextgstates + {\ifx\docuPDFextgstates\empty \else + \ifnum\realpageno=\lastpage\relax + %\doPDFreserveddictionaryobject{FDF}{docuextgstates}{\docuPDFextgstates}% + \doPDFdictionaryobject{FDF}{docuextgstates}{\docuPDFextgstates}% + \fi + \doPDFgetobjectreference{FDF}{docuextgstates}\PDFobjectreference + \doPDFpageresource{/ExtGState \PDFobjectreference}% + \fi} + +\appendtoksonce + \checkPDFextgstates +\to \everyshipout + +\def\appendtoPDFdocumentextgstates#1% + {\xdef\docuPDFextgstates{\docuPDFextgstates\space#1}} + +%D Patterns (for tikz) + +\let\docuPDFpatterns\empty + +\def\checkPDFpatterns + {\ifx\docuPDFpatterns\empty \else + \ifnum\realpageno=\lastpage\relax + \doPDFdictionaryobject{FDF}{docupatterns}{\docuPDFpatterns}% + \fi + \doPDFgetobjectreference{FDF}{docupatterns}\PDFobjectreference + \doPDFpageresource{/Pattern \PDFobjectreference}% + \fi} + +\appendtoksonce + \checkPDFpatterns +\to \everyshipout + +\def\appendtoPDFdocumentpatterns#1% + {\xdef\docuPDFpatterns{\docuPDFpatterns\space#1}} + +%D Another special mechanism (needed for color separation): + +\let\docuPDFcolorspaces\empty + +\def\checkPDFcolorspaces + {\ifx\docuPDFcolorspaces\empty \else + \ifnum\realpageno=\lastpage\relax + %\doPDFreserveddictionaryobject{FDF}{colorspaces}{\docuPDFcolorspaces}% + \doPDFdictionaryobject{FDF}{colorspaces}{\docuPDFcolorspaces}% + \fi + \doPDFgetobjectreference{FDF}{colorspaces}\PDFobjectreference + \doPDFpageresource{/ColorSpace \PDFobjectreference}% + \fi} + +\appendtoksonce + \checkPDFcolorspaces +\to \everyshipout + +\def\appendtoPDFdocumentcolorspaces#1% + {\xdef\docuPDFcolorspaces{\docuPDFcolorspaces\space#1}} + +%D And another one (used to be in spec-pdf) + +\let\docuPDFshades\empty + +\def\checkPDFshades + {\ifx\docuPDFshades\empty \else + \ifnum\realpageno=\lastpage\relax + %\doPDFreserveddictionaryobject{FDF}{docushades}{\docuPDFshades}% + \doPDFdictionaryobject{FDF}{docushades}{\docuPDFshades}% + \fi + \doPDFgetobjectreference{FDF}{docushades}\PDFobjectreference + \doPDFpageresource{/Shading \PDFobjectreference}% + \fi} + +\appendtoksonce + \checkPDFshades +\to \everyshipout + +\def\appendtoPDFdocumentshades#1% + {\xdef\docuPDFshades{\docuPDFshades\space#1}} + +%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). + +\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 +% \!!widtha#4% +% \advance\!!widtha#2% +% \!!heighta-#5% +% \!!heightb#1% extra argument +% \advance\!!heightb -#3% +% \advance\!!heighta \!!heightb +% % sometimes whole values give better results +% % \PointsToWholeBigPoints{#2}\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{#2}\left +% \PointsToBigPoints\!!heighta\bottom +% \PointsToBigPoints\!!widtha \width +% \PointsToBigPoints\!!heightb\height +% \xdef\currentPDFcropboxspec +% {[\left\space\bottom\space\width\space\height]}% +% \global\let\currentPDFtrimboxspec\currentPDFcropboxspec +% +% \xdef\currentPDFpagemode +% {/PageMode \ifcase#6 +% /UseNone\or/FullScreen\or/UseOutlines\else/UseNone\fi}% +% + \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} + +% not that good if we switch drivers + +\def\addPDFdocumentinfo + {\doPDFaddtocatalog{\currentPDFpagemode\currentPDFviewerprefs}% + \doPDFaddtocatalog{/Version /\PDFversion}% + \doPDFaddtoinfo{/Trapped /False}% + \doPDFaddtoinfo{/ConTeXt.Version (\contextversion)}% + \doPDFaddtoinfo{/ConTeXt.Time (\number\normalyear.\twodigits\normalmonth.\twodigits\normalday\space \twodigits\currenthour:\twodigits\currentminute)}% + \doPDFaddtoinfo{/ConTeXt.Jobname (\jobname)}% + \doPDFaddtoinfo{/ConTeXt.Url (www.pragma-ade.com)}} + +\appendtoksonce % hack to prevent duplicates + \addPDFdocumentinfo +\to \everyfirstshipout + +\ifx\pdfminorversion\undefined + \ifx\pdfoptionpdfminorversion\undefined + \newcount\pdfminorversion + \else + \let\pdfminorversion\pdfoptionpdfminorversion + \fi +\fi + +\pdfminorversion=5 + +\def\PDFversion{1.\number\pdfminorversion} + +\appendtoksonce + \def\PDFversion{1.\the\pdfminorversion}% + \let\addPDFdocumentinfo\relax +\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} + +\def\doPDFsetupartbox {\doPDFsetupwhateverbox\currentPDFartbox } +\def\doPDFsetupcropbox {\doPDFsetupwhateverbox\currentPDFcropbox } +\def\doPDFsetupbleedbox{\doPDFsetupwhateverbox\currentPDFbleedbox} +\def\doPDFsetuptrimbox {\doPDFsetupwhateverbox\currentPDFtrimbox } + +\gdef\currentPDFtrimbox{\currentPDFcropbox} % default, needed for pdf/x + +\def\flushPDFwhateverbox#1#2% + {\doifsomething{#1}{\doPDFpageattribute{/#2Box #1}}} + +\def\flushPDFpageboxes + {\flushPDFwhateverbox\currentPDFartbox {Art}% + \flushPDFwhateverbox\currentPDFcropbox {Crop}% + \flushPDFwhateverbox\currentPDFbleedbox{Bleed}% + \flushPDFwhateverbox\currentPDFtrimbox {Trim}} + +\appendtoksonce + \flushPDFpageboxes +\to \everyshipout + +% \def\doPDFsetupidentity#1#2#3#4#5#6% +% {\bgroup +% \enablePDFdocencoding +% \edef\!!stringa{#5}% +% \ifx\!!stringa\empty \ifx\pdfdate\undefined\else +% \edef\!!stringa{D:\pdfdate}% +% \fi \fi +% \expanded{\doPDFaddtoinfo +% {/Title (#1) +% /Subject (#2) +% /Author (#3) +% /Creator (#4) +% /ModDate (\!!stringa) +% /ID (\jobname.\!!stringa) % needed for pdf/x +% /Keywords (#6)}}% +% \egroup} + +\def\doPDFsetupidentity#1#2#3#4#5#6% + {\bgroup + \enablePDFdocencoding + \sanitizePDFencoding#1\to\idtitle \stripstring\idtitle + \sanitizePDFencoding#2\to\idsubject\stripstring\idsubject + \sanitizePDFencoding#3\to\idauthor \stripstring\idauthor + \sanitizePDFencoding#4\to\idcreator\stripstring\idcreator + \sanitizePDFencoding#6\to\idkeyword\stripstring\idkeyword + \expanded{\doPDFaddtoinfo + {/Title \ifPDFunicode<\idtitle >\else(\idtitle )\fi + /Subject \ifPDFunicode<\idsubject>\else(\idsubject)\fi + /Author \ifPDFunicode<\idauthor >\else(\idauthor )\fi + /Creator \ifPDFunicode<\idcreator>\else(\idcreator)\fi + /ModDate (#4) + /ID (\jobname.#5) % needed for pdf/x + /Keywords \ifPDFunicode<\idkeyword>\else(\idkeyword)\fi}}% + \egroup} + +%D \macros +%D {doPDFsetupopenaction,doPDFsetupcloseaction, +%D doPDFsetupopenpageaction,doPDFsetupclosepageaction} +%D +%D Setting the open and close actions is kind of fuzzy +%D because action chains are derived from the reference +%D mechanism. + +%D Starting with version~5 viewers, when the open actions +%D started yto give problems, for testing purposes we +%D decided use indirect actions. + +% \definespecial\dosetupopenaction {\doPDFsetupopenaction} +% \definespecial\dosetupcloseaction {\doPDFsetupcloseaction} +% \definespecial\dosetupopenpageaction {\doPDFsetupopenpageaction} +% \definespecial\dosetupclosepageaction{\doPDFsetupclosepageaction} + +\let\lastPDFaction\empty + +%D We can safe a couple of references by moving this code +%D to the specific drivers. +%D +%D The following code used to work okay, but as with any +%D update of Acrobat Viewers, upward compatibility was +%D just a dream. + +\definespecial\dosetupopenaction {\doPDFaddtocatalog{/OpenAction <<\lastPDFaction>>}} +\definespecial\dosetupcloseaction{\doPDFaddtocatalog{/CloseAction <<\lastPDFaction>>}} + +% todo: /AA << dictionary in catalog >> + +% \globalletempty\PDFdocumentclose +% \globalletempty\PDFwillsave +% \globalletempty\PDFdidsave +% \globalletempty\PDFwillprint +% \globalletempty\PDFdidprint + +% \definespecial\dosetupdocumentcloseaction {\global\let\PDFdocumentclose\lastPDFaction} +% \definespecial\dosetupwillsaveaction {\global\let\PDFwillsave \lastPDFaction} +% \definespecial\dosetupdidsaveaction {\global\let\PDFdidsave \lastPDFaction} +% \definespecial\dosetupwillprintaction {\global\let\PDFwillprint \lastPDFaction} +% \definespecial\dosetupdidprintaction {\global\let\PDFdidprint \lastPDFaction} + +% \def\checkPDFdocumentactions +% {\iflocation +% \doPDFpageattribute +% {/AA <<\ifx\PDFdocumentclose\empty \else /DC <<\PDFdocumentclose>> \fi +% \ifx\PDFwillsave \empty \else /WS <<\PDFwillsave >> \fi +% \ifx\PDFdidsave \empty \else /DS <<\PDFdidsave >> \fi +% \ifx\PDFwillprint \empty \else /WP <<\PDFwillprint >> \fi +% \ifx\PDFdidprint \empty \else /DP <<\PDFdidprint >> \fi>>}% +% % \globalletempty\PDFdocumentclose +% % \globalletempty\PDFwillsave +% % \globalletempty\PDFdidsave +% % \globalletempty\PDFwillprint +% % \globalletempty\PDFdidprint +% \global\let\checkPDFdocumentactions\relax +% \fi} + +% \appendtoksonce +% \checkPDFdocumentactions +% \to \everylastshipout + +%\def\doPDFsetupopenaction% +% {\doPDFdictionaryobject{FDF}{local:openaction}\lastPDFaction +% \doPDFgetobjectreference{FDF}{local:openaction}\PDFobjectreference +% \doPDFaddtocatalog{/OpenAction \PDFobjectreference}} +% +%\def\doPDFsetupcloseaction% +% {\doPDFdictionaryobject{FDF}{local:closeaction}\lastPDFaction +% \doPDFgetobjectreference{FDF}{local:closeaction}\PDFobjectreference +% \doPDFaddtocatalog{/CloseAction \PDFobjectreference}} + +\let\PDFopenpageaction \empty +\let\PDFclosepageaction\empty + +\definespecial\dosetupopenpageaction {\global\let\PDFopenpageaction \lastPDFaction} +\definespecial\dosetupclosepageaction{\global\let\PDFclosepageaction\lastPDFaction} + +\def\checkPDFpageactions + {\iflocation % important since direct -) + \donefalse + \ifx\PDFopenpageaction \empty\!!doneafalse\else\donetrue\!!doneatrue\fi + \ifx\PDFclosepageaction\empty\!!donebfalse\else\donetrue\!!donebtrue\fi + \ifdone + \doPDFpageattribute + {/AA <<\if!!donea/O <<\PDFopenpageaction >> \fi + \if!!doneb/C <<\PDFclosepageaction>> \fi>>}% + \fi + \global\let\PDFopenpageaction \empty + \global\let\PDFclosepageaction\empty + \fi} + +\appendtoksonce + \checkPDFpageactions +\to \everyshipout + +%D \macros +%D {doPDFstartthisislocation} +%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\doPDFstartthisislocation#1% + {\bgroup + \setPDFdestination{#1}% + \ifx\PDFdestination\empty \else + \doPDFdestination{\PDFdestination}% + \fi + \egroup} + +%D \macros +%D {doPDFstartgotolocation, +%D doPDFstartgotorealpage, +%D doPDFstartgotoJS} +%D +%D The goto macros use the switch \type{\ifsecondaryreference} +%D to determine if actions should be linked. + +\def\locationfilesuffix{pdf} + +% \def\preparePDFlocationfile#1#2% +% {\setreferencefilename#1\to#2% +% \expanded{\doifnotinstring{.\locationfilesuffix}{#2}} +% {\edef#2{#2.\locationfilesuffix}}} +% +% \def\preparePDFlocationfile#1\to#2% +% {\setreferencefilename#1\to#2% +% \expanded{\doifnotinstring{.pdf}{#2}}{\edef#2{#2.pdf}}} + +\def\doPDFstartgotolocation#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{\URLhash\PDFdestination}}}% + \edef\action{/S /URI /URI (#3\PDFfile\PDFdestination)}}% + \ifx\action\empty\else + \ifsecondaryreference + \savesecondaryPDFreference\action + \else + \getsecondaryPDFreferences + \doPDFaction{\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\doPDFstartgotorealpage#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 + \doPDFaction{\PDFswapdir#1}{#2}{\action \secondaryPDFreferences}% + \fi + \fi + \egroup} + +\let\lastfakedPDFpage\!!zerocount + +\def\fakePDFpagedestination % as in pdf, we start numbering at zero + {\iflocation \ifarrangingpages \else \ifnum\overcomePDFpage=\plustwo + \ifnum\lastfakedPDFpage<\realpageno + \bgroup + \xdef\lastfakedPDFpage{\realfolio}% + \advance\realpageno \minusone % is \expanded needed ? + \expanded{\doPDFdestination{page:\realfolio}}% + \egroup + \fi + \fi \fi \fi} + +\appendtoksonce + \fakePDFpagedestination +\to \everyshipout + +\def\doPDFstartgotoJS#1#2#3% + {\bgroup + \doPSsanitizeJScode#3\to\sanitizedJScode + \edef\action + {/S /JavaScript /JS (\sanitizedJScode)}% + \ifsecondaryreference + \savesecondaryPDFreference\action + \else + \getsecondaryPDFreferences + \doPDFaction{\PDFswapdir#1}{#2}{\action \secondaryPDFreferences}% + \fi + \egroup} + +%D \macros +%D {doPDFstartexecutecommand} +%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% + {\doFDFiffieldset{#1}{/Field [\doFDFgetfieldset{#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\doPDFstartexecutecommand#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\doPDFaction +% \else +% \edef\next{\doPDFactionobject{\PDFobjectclass}{\PDFobjectname}}% +% \globalletempty\PDFobjectclass +% \globalletempty\PDFobjectname +% \fi +% \next + \doPDFaction{\PDFswapdir#1}{#2}{\action \secondaryPDFreferences}% + \fi + \egroup}} + +%D \macros +%D {doPDFstartrunprogram} +%D +%D Running programs is possible, but is non that portable, and +%D therefore dangerous. + +\def\doPDFstartrunprogram#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 + \doPDFaction{\PDFswapdir#1}{#2}{\action \secondaryPDFreferences}% + \fi + \egroup} + +%D \macros +%D {doPDFstartgotoprofile} +%D +%D Far from perfect, but nevertheless present, is the profile +%D handler. We want to misuse article threads for reder +%D profiles. + +\def\doPDFstartgotoprofile#1#2#3% to be done: file + {\bgroup + \setPDFdestination{#3}% + \doifsomething\PDFdestination + {\edef\action + {/S /Thread /D (\PDFdestination)}% + \ifsecondaryreference + \savesecondaryPDFreference\action + \else + \getsecondaryPDFreferences + \doPDFaction{\PDFswapdir#1}{#2}{\action \secondaryPDFreferences}% + \fi}% + \egroup} + +%D \macros +%D {doPDFsetpagetransition} +%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. + +% some day, when 1.5 is on linux and apple, we will add: +% +% \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} + +\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}} + +%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\doPDFsetpagetransition#1#2% + {\let\PDFpagetransitions\empty + \processcommalist[#1]\dodoPDFsetpagetransition + \doPDFpageattribute + %{\ifnum#2>0 /Dur #2 \fi + {\ifnum0<0#2 /Dur #2 \fi + \ifx\PDFpagetransitions\empty\else/Trans <<\PDFpagetransitions>>\fi}} +% \ifx\PDFpagetransitions\empty\else/Trans <>\fi}} + +%D \macros +%D {doPDFinsertmov} +%D +%D Most of the annotations we use here are of type {\em +%D link}, but here is another one: the {\em movie} annotation. +%D The driver module must implement \type {setcurrentmovie}. + +%D Great: this will become an obsolete pdf feature; why did we have to +%D keep up with the bugs ... and by the time acrobat gets better in +%D handling it have to drop it. + +\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}% + \doPDFannotation\@@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 {doPDFinsertsoundtrack} +%D +%D In \PDF\ sounds can be embedded like movies. + +\ifx\everygoto\undefined \newtoks\everygoto \fi + +\let\currentsound\s!unknown + +\def\doPDFinsertsoundtrack#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 + {\doPDFannotation{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\doPDFattachfile#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 + \doPDFannotation{\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 + +\definespecial \doattachfile {\doPDFattachfile} + +% 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 -> <> + +% todo: embedded files (too buggy) +% +% \let\PDFattribute\empty +% % /D \PDFobjectreference +% % test one, no error, but ignored +% \doifinset\v!file{#4} +% {\doPDFembedfile{#3}{#3}{#3}% +% \doPDFgetembeddedfilestreamreference{#3}\PDFobjectreference +% \edef\PDFattribute{/EF \PDFobjectreference}}% +% % official, does not work either +% \doifinset\v!file{#4} +% {\doPDFembedfile{#3}{#3}{#3}% +% \doPDFgetembeddedfilereference{#3}\PDFobjectreference} +% % do we play the game as follows + +\definespecial\doinsertrendering#1#2#3#4% tag mime file options + {\ifundefined{PDFMR:#1}% + \doifinstringelse{://}{#3}\donetrue\donefalse % evt url as keyword + \doPDFdictionaryobject{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} + +\definespecial\doinsertrenderingobject#1#2#3#4% tag class objectname options + {\ifundefined{PDFMR:#1}% + \doPDFgetobjectreference{#2}{#3}\PDFobjectreference + \doPDFdictionaryobject{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} + +\definespecial\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 + \doPDFannotationobject{#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} + +\definespecial\dosetuprenderingopenpageaction {\global\let\PDFrenderingopenpageaction \lastPDFaction} +\definespecial\dosetuprenderingclosepageaction{\global\let\PDFrenderingclosepageaction\lastPDFaction} + +%D \macros +%D {doPDFinsertbookmark} +%D +%D Well, here is the dreadfull bookmark, rather useless because +%D only standard encoding is possible, no typography is done, +%D and a maximum of 32~characters is advized. + +\def\doPDFinsertbookmark#1#2#3#4#5% level sublevels text page open=1 + {\bgroup + \sanitizePDFencoding#3\to\bookmarktext % uses scratchcounter + \stripstring\bookmarktext + \doPDFbookmark{#1}{#2}{\bookmarktext}{#4}{#5}% + \egroup} + +%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 (not used as such) +\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\relax% mousedown + \setFDFaction U#2\relax% mouseup + \setFDFaction E#3\relax% enterregion + \setFDFaction X#4\relax% exitregion + \setFDFaction K#5\relax% afterkeystroke + \setFDFaction F#6\relax% formatresult + \setFDFaction V#7\relax% validateresult + \setFDFaction C#8\relax% calculatewhatever + \setFDFactionsmore} + +\def\setFDFactionsmore#1,#2]% + {\setFDFaction{Fo}#1\relax% focusin + \setFDFaction{Bl}#2\relax% 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\relax +% \setFDFaction{PC}\@@DriverFieldPageClose\relax +% \setFDFaction{PV}\@@DriverFieldPageVisible\relax +% \setFDFaction{PI}\@@DriverFieldPageInVisible\relax + +%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\relax% +% {\bgroup +% \global\let\sanitizedJScode\empty +% \def\setFDFaction##1% +% {\doifreferencefoundelse{##1} +% {\doifelse{\currentreferencespecial}{JS} % filter non-js +% {\presetJScode +% \currentreferenceoperation +% \currentreferencearguments +% \doPSsanitizeJScode\JScode\to\JScode +% \xdef\sanitizedJScode{\sanitizedJScode\space\JScode}} +% {\illegalreference{##1}}} +% {\unknownreference{##1}}}% +% \@EA\processcommalist\@EA[#2]\setFDFaction % one level expansion +% \ifx\sanitizedJScode\empty \else +% \xdef\FDFactions% +% {\FDFactions /#1 << /S /JavaScript /JS (\sanitizedJScode) >> }% +% \fi +% \egroup} +% +% acrobat 5 supports other that JS actions too + +\def\setFDFaction#1#2\relax% + {\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\relax% + {\doPSsanitizeJScode console.show();console.println("executing:##1"); \to\sanitizedJScode + \edef\FDFactions{\FDFactions /##1 << /S /JavaScript /JS (\sanitizedJScode) >> }}} + +%D \macros +%D {doFDFregistercalculationset} +%D +%D There is at most one calculation order list, which defines +%D the order in which fields are calculated. + +\let\PDFcalculationset\empty + +\def\doFDFregistercalculationset#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 + {\ifbuildFDFdictionary + \ifx\FDFcollection\empty\else + \ifbuildFDFencodingvector + \doPDFdictionaryobject{FDF}{local:encodingvector}{\FDFencodingvector}% + \fi + \defineFDFfonts + \doPDFarrayobject{FDF}{local:fields}{\FDFcollection}% + \doPDFgetobjectreference{FDF}{local:fields}\PDFobjectreference + % The /NeedAppearances is pretty important because + % otherwise Acrobat 5 blows up on cloned radio widgets + \doPDFdictionaryobject{FDF}{local:acroform} + {/Fields \PDFobjectreference\space + /NeedAppearances true + \doFDFiffieldset\PDFcalculationset{/CO [\doFDFgetfieldset\PDFcalculationset]} + /DR << /Font << \FDFfonts >> >> + /DA (/Helv 10 Tf 0 g)}% + \doPDFgetobjectreference{FDF}{local:acroform}\PDFobjectreference + \doPDFaddtocatalog + {/AcroForm \PDFobjectreference}% + \global\let\FDFcollection\empty + \global\let\flushFDFnames\relax + \fi + \fi} + +\let\FDFcollection\empty + +\def\registerFDFobject#1% + {\ifbuildFDFdictionary + \ifx\flushFDFnames\relax + \writestatus{FDF}{second run needed for field list (#1)}% + \fi + \doPDFgetobjectreference{FDF}{#1}\PDFobjectreference + \xdef\FDFcollection{\FDFcollection\space\PDFobjectreference}% + \fi} + +\appendtoksonce \flushFDFnames \to \everylastshipout % test \everybye / was \prependtoksonce + +%D \macros +%D {defineFDFfonts, +%D ifbuildFDFdictionary, +%D ifbuildFDFencodingvector} +%D +%D Another datastruture concerns the fonts used. We only +%D define the fonts we use. + +\newif\ifbuildFDFdictionary \buildFDFdictionarytrue +\newif\ifbuildFDFencodingvector \buildFDFencodingvectortrue + +\def\defineFDFfonts + {\let\FDFfonts\empty + \processcommacommand[\FDFusedfonts]\defineFDFfont} + +\def\defineFDFfont#1% + {\ifbuildFDFencodingvector + \doPDFgetobjectreference{FDF}{local:encodingvector}\PDFobjectreference + \fi + \doPDFdictionaryobject{FDF}{local:#1} + {/Type /Font + /Subtype /Type1 + /Name /#1 + \ifbuildFDFencodingvector /Encoding \PDFobjectreference\space\fi + /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 And a big one: (should be run time loaded (spec-run or +%D so)). + +\def\FDFencodingvector + {/Type /Encoding + /Differences + [ 24 /breve /caron /circumflex /dotaccent /hungarumlaut /ogonek + /ring /tilde + 39 /quotesingle + 96 /grave + 128 /bullet /dagger /daggerdbl /ellipsis /emdash /endash /florin + /fraction /guilsinglleft /guilsinglright /minus /perthousand + /quotedblbase /quotedblleft /quotedblright /quoteleft + /quoteright /quotesinglbase /trademark /fi /fl /Lslash /OE + /Scaron /Ydieresis /Zcaron /dotlessi /lslash /oe /scaron + /zcaron + 164 /currency + 166 /brokenbar + 168 /dieresis /copyright /ordfeminine + 172 /logicalnot /.notdef /registered /macron /degree /plusminus + /twosuperior /threesuperior /acute /mu + 183 /periodcentered /cedilla /onesuperior /ordmasculine + 188 /onequarter /onehalf /threequarters 192 /Agrave /Aacute + /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave + /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex + /Idieresis /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde + /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /germandbls /agrave /aacute + /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave + /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex + /idieresis /eth /ntilde /ograve /oacute /ocircumflex /otilde + /odieresis /divide /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /ydieresis ]} + +%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. + +\definespecial\dosetfieldstatus#1#2#3#4% + {\chardef\currentFDFmode #1% + \edef\currentFDFparent {#2}% + \edef\currentFDFkids {#3}% + \edef\currentFDFroot {#4}} + +%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] } +\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 + [#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=>\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{\ifx\PDFpageviewwrd\empty\else/View [\PDFpageviewwrd]\fi}} + +%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 +% \edef\FDFkids{/Kids [\FDFkids]}% + } + +%D \macros +%D {doFDFpresetlinefield,doFDFpresettextfield, +%D doFDFpresetchoicefield,doFDFpresetpopupfield,doFDFpresetcombofield, +%D doFDFpresetpushfield,doFDFpresetcheckfield, +%D doFDFpresetfield,doFDFpresetradiorecord} +%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\doFDFpresetlinefield#1#2#3#4#5#6#7#8#9% + {\bgroup + \setFDFlayer\@@DriverFieldLayer + \setFDFswitches[#7]% + \setFDFattributes[#6]% + \setFDFalignment[#8]% + \setFDFactions[#9]% + \expanded{\escapePSstring#4}\to\FDFtext + \ifcase\currentFDFmode + \doPDFannotationobject{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) % value added + /Ff \FDFflag\space + /F \FDFplus\space + /DA (\FDFattributes) + \FDFlayer\space + \FDFsurroundings\space + /Q \FDFalign\space + \FDFactions}% + \registerFDFobject{#1}% + \or + \setFDFkids[kids:][\currentFDFkids]% + \doPDFdictionaryobject{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) % value added + /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 + \doPDFannotationobject{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 + \doPDFannotationobject{FDF}{kids:#1}{#2}{#3} + {/Subtype /Widget + /Parent \PDFobjectreference + /F \FDFplus + \FDFactions}% + \fi + \egroup} + +\def\doFDFpresettextfield#1#2#3#4#5#6#7#8#9% + {\doFDFpresetlinefield{#1}{#2}{#3}{#4}{#5}{#6}{MultiLine,#7}{#8}{#9}} + +\def\doFDFpresetchoicefield#1#2#3#4#5#6#7#8% + {\bgroup + \setFDFlayer\@@DriverFieldLayer + \setFDFswitches[#6]% + \setFDFattributes[#5]% + \setFDFvalues[#7][#4]% + \setFDFactions[#8]% + \ifcase\currentFDFmode + \doPDFannotationobject{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]% + \doPDFdictionaryobject{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 + \doPDFannotationobject{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 + \doPDFannotationobject{FDF}{kids:#1}{#2}{#3} + {/Subtype /Widget + /Parent \PDFobjectreference + /F \FDFplus + \FDFactions}% + \fi + \egroup} + +\def\doFDFpresetpopupfield#1#2#3#4#5#6#7#8% + {\doFDFpresetchoicefield{#1}{#2}{#3}{#4}{#5}{PopUp,#6}{#7}{#8}} + +\def\doFDFpresetcombofield#1#2#3#4#5#6#7#8% + {\doFDFpresetchoicefield{#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}% + \doPDFannotationobject{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]% + \doPDFdictionaryobject{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 + \doPDFannotationobject{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 + \doPDFannotationobject{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\doFDFpresetpushfield#1#2#3#4#5#6#7% + {\doFDFpresetpushcheckfield{#1}{#2}{#3}{#4}{PushButton,#5}{#6}{#7}{0}} + +\def\doFDFpresetcheckfield#1#2#3#4#5#6#7% + {\doFDFpresetpushcheckfield{#1}{#2}{#3}{#4}{#5}{#6}{#7}{1}} + +% As pdf widgets are rather consistently upward incompatible +% especially with regards to inheritance, the following code is not +% quite okay. I've decided no longer to bother about in it in MkII +% and use a flat model in MkIV which somehow seems to work better. + +\def\doFDFpresetradiofield#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 + \doPDFannotationobject{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 + \doPDFdictionaryobject{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 + \doPDFannotationobject{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 + \doPDFannotationobject{FDF}{kids:#1}{#2}{#3} + {/Subtype /Widget + /Parent \PDFobjectreference\space + /AS /\FDFdefault\space + /F \FDFplus\space + \FDFlayer\space + \FDFappearance\space + \FDFactions}% + \fi + \egroup} + +%D \macros +%D {setFDFstrings} +%D +%D This one creates a string array. + +%\def\setFDFstrings[#1]% +% {\let\FDFstrings\empty +% \def\docommand##1{\edef\FDFstrings{\FDFstrings(##1)}}% +% \processcommacommand[#1]\docommand} + +% 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. +% +% Hm, nowadays Radio will overload RadiosInUnison so we need to use only one +% of them. + +\def\doFDFpresetradiorecord#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]% + % > pdf 1.6 + \setFDFswitches[RadiosInUnison,#3]% + %setFDFswitches[PushButton,RadiosInUnison,#3]% this is what acrobat itself does + % older, else fatal error + % \setFDFkids[#4][]% + % newer + \setFDFvalues[#4][#2]% inits kidlist + \expanded{\setFDFkids[][\FDFkidlist]}% + % + \setFDFactions[#5]% + \doPDFdictionaryobject{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 + \doPDFdictionaryobject{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% +% {\dogetcommacommandelement1\from#1,\to\commalistelement +% \dogetcommacommandelement1\from\commalistelement\to\commalistelement +% \doifelse{\commalistelement}{#2} % kan ook met \ifx +% {\def\FDFdefault{On}}{\def\FDFdefault{Off}}} + +\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 {doFDFdefinefieldset,doFDFgetfieldset,doFDFiffieldset} +%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 \doFDFiffieldset{TAG}{sequence} +%D \stoptyping + +\def\doFDFdefinefieldset#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\doFDFgetfieldset#1% + {\getvalue{FDF:set:#1}} + +\def\doFDFiffieldset#1#2% + {\ifundefined{FDF:set:#1}\else#2\fi} + +%D In the goto specials we took care of secondary references. +%D Here we define the macros used. + +\def\doPDFresetgotowhereever + {\global\let\secondaryPDFreferences\empty} + +\doPDFresetgotowhereever % 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} + +%\def\getsecondaryPDFreferences% +% {\ifcase\nofsecondaryreferences\else +% %\doifdefined{PDF-SR:\the\nofsecondaryreferences} +% \xdef\secondaryPDFreferences% +% {/Next << \csname PDF-SR:\the\nofsecondaryreferences\endcsname\space +% \secondaryPDFreferences >>}% +% \global\advance\nofsecondaryreferences \minusone +% \expandafter\getsecondaryPDFreferences +% \fi} + +% 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 {loadFDFfields, showFDFfields, +%D getFDFfield, setFDFfield} +%D +%D Once filled in, we can export or submit the field in the +%D \FDF\ file format. Such a file can be loaded by +%D +%D \starttyping +%D \loadFDFfields{fiel-ini} +%D \stoptyping +%D +%D or inspected by +%D +%D \starttyping +%D \showFDFfields{fiel-ini} +%D \stoptyping +%D +%D After both commands, one can use +%D +%D \starttyping +%D \getFDFfield{name} +%D \setFDFfield{name}{value} +%D \stoptyping +%D +%D to inspect and overrule the data. +%D +%D By default \CONTEXT\ calls the perl script \type{fdf2tex}. +%D This script reads the \type{fdf} file and produces a file +%D named \type{filename.fdt}. If one disables the call to this +%D script, by saying: +%D +%D \starttyping +%D \runFDFconverterfalse +%D \stoptyping +%D +%D or when \CONTEXT\ cannot find the \type{fdt} file, it tries +%D to interpret the \type{fdf} file directly. Both mechanisms +%D are rather crude. + +\newif\ifrunFDFconverter \runFDFconvertertrue + +%D The \PERL\ script produces a file formatted as: +%D +%D \starttyping +%D \beginFDFobject +%D \beginFDFdata +%D \beginFDFfields +%D \FDFfield[name=,value=] +%D \endFDFfields +%D \endFDFdata +%D \endFDFobject +%D \stoptyping +%D +%D One reason for using key value pairs is that we cannot be +%D sure or the order in which the name and value are given +%D (actually the reverse). + +\def\PERLloadFDFfields#1% will become obsolete soon + {\bgroup + \global\let\allFDFfields\empty + \ifrunFDFconverter + \executesystemcommand{fdf2tex #1}% + \let\beginFDFobject\relax \let\endFDFobject\relax + \let\beginFDFdata \relax \let\endFDFdata \relax + \let\beginFDFfields\relax \let\endFDFfields\relax + \def\FDFfield[##1]% + {\getparameters[FDF][##1]% + \doglobal\addtocommalist\FDFname\allFDFfields + \global\setFDFfield{\FDFname}{\FDFvalue}}% + \ReadFile{#1.fdt}% + \fi + \egroup} + +%D The next macro does the same job, but now in the \TEX\ way +%D of doing things. Easy eh? Will become obsolete! + +\bgroup + +\catcode`\/=\@@other +\global\let\normalslash=/ +\catcode`\/=\@@escape + +\gdef\TEXloadFDFfields#1% will become obsolete due to XFDF + {\bgroup + \setbox0=\hbox + {\global\let\allFDFfields\empty + \scratchcounter=0 + \escapechar=-1 + \catcode`\/=\@@escape + \catcode`\(=\@@begingroup + \catcode`\)=\@@endgroup + \catcode`\%=\@@letter + \let/A =\relax \let/AS =\relax \let/Kids=\relax \let/Fields=\relax + \let/F =\relax \let/ID =\relax \let/SetF=\relax \let/setFf =\relax + \let/Ff=\relax \let/Opt=\relax \let/ClrF=\relax \let/ClrFf =\relax + \let/AP=\relax \let/FDF=\relax \let/Root=\relax + \def/T##1{\check\Title{##1}} + \def/V{\bgroup\catcode`\/=\@@other\futurelet\next/doV} + \def/doV{\ifx\next\normalslash\@EA/doVb\else\@EA/doVa\fi} + \def/doVa##1{\egroup\check\Value{##1}} + \def/doVb##1##2 {\egroup\check\Value{##2}} % watch the space + \def\check##1##2% + {\def##1{##2} + \advance\scratchcounter\plusone\relax + \ifodd\scratchcounter \else + \defconvertedcommand\asciia\Title + \global\setFDFfield{\asciia}{\Value} + \doglobal\addtocommalist\Title\allFDFfields + \fi} + \ReadFile{#1.fdf}}% + \egroup} + +\egroup + +%D Whatever mechanism is used, the next macros can be used to +%D fetch the values. + +\def\getFDFfield #1{\getvalue {FDFfield::#1}} +\def\setFDFfield#1#2{\setevalue{FDFfield::#1}{#2}} + +%D Of course the fields are only present when the file is +%D loaded. + +\def\loadFDFfields#1% + {\PERLloadFDFfields{#1}% + \ifx\allFDFfields\empty + \TEXloadFDFfields{#1}% + \fi} + +\def\showFDFfields#1% + {\bgroup + \loadFDFfields{#1} + \def\docommand##1{\par##1 = \getFDFfield{##1}\par}% + \processcommacommand[\allFDFfields]\docommand + \egroup} + +%D \macros +%D {sanitizePDFencoding,sanitizePDFdocencoding} +%D +%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. + +%D This will be reimplemented using the mapping mechanism. + +% \def\enablePDFdocencoding +% {\reducetocoding[pdfdoc]\simplifycommands} + +\def\enablePDFdocencoding + {\enablecoding[pdfdoc]% + \enablelanguagespecifics[\currentlanguage]% redundant ? + \simplifycommands} + +\long\def\sanitizePDFdocencoding#1\to#2% + {\enablePDFcrlf + \enablePDFdocencoding + %\honorunexpanded % otherwise problems with "e etc in de + \edef#2{#1}} + +\bgroup +\catcode`\^^M=\@@active +\gdef\enablePDFcrlf% + {\def\\{\string\r}% + \def\par{\\\\}% + \def\endgraf{\\\\}% + \catcode`\^^M=\@@active% + \let^^M=\\} +\egroup + +% \let\sanitizePDFencoding\sanitizePDFdocencoding + +%D The conversions comes down to (for the sake of speed the +%D implementation combines steps): +%D +%D \startitemize +%D \item we expand the \UTF\ sequences into \type {\unicodechar}'s +%D \item spaces become character 255's (so that they are not +%D gobbled in argument fetching +%D \item normal \ASCII\ chars are unchanged +%D \item \par's and alike are converted to \type {\unicodechar}'s +%D \stopitemize +%D +%D This happens by expansion; next we convert the resulting +%D sequence by interpreting the stream. + +\long\def\sanitizePDFuniencoding#1\to#2% + {\enablePDFunicrlf + \simplifycommands % added due to Dohyun Kim + \let\unicodechar\relax % prevent further expansion + \retainlccodes\lccode32=255 % slooow + \lowercasestring\PDFunicodetrigger#1\to#2% + \edef#2{\expandafter\doPDFuni#2\empty\empty}} % slooow + +%D Handling of empty lines: + +\bgroup +\catcode`\^^M=\@@active +\gdef\enablePDFunicrlf% + {\def\\{\unicodechar{13}}% + \def\par{\\\\}% + \catcode`\^^M=\@@active% + \let^^M=\\} +\egroup + +%D Conversion to 16 bit \UNICODE: + +\def\PDFunicodechar#1% + {\@EA\lchexnumbers\@EA{\number\utfdiv{#1}}% + \@EA\lchexnumbers\@EA{\number\utfmod{#1}}} + +\def\PDFunicodetrigger + {\unicodechar{65279}} + +%D The postprocessor: + +\def\doPDFuni#1% + {\ifx#1\relax + \@EA\dodoPDFuni + \else\ifx#1\empty + % quit + \else + \@EAEAEA\nodoPDFuni + \fi\fi#1} + +\def\nodoPDFuni#1% + {\PDFunicodechar{\ifnum`#1=255 32\else`#1\fi}\doPDFuni} + +\def\dodoPDFuni#1#2% + {\PDFunicodechar{#2}\doPDFuni} + +\def\sanitizePDFencoding + {\doifelse\currentregime{utf}{\PDFunicodetrue\sanitizePDFuniencoding}\sanitizePDFdocencoding} + +%D A bit out of place, but useful: + +\ifdefined\everysetfield \else \newtoks\everysetfield \fi + +\appendtoksonce + \enablePDFdocencoding + \enablePDFcrlf +\to \everysetfield + +%D \macros +%D {doPDFinsertcomment} +%D +%D An example its use is the next special, one that deals with +%D text annotations. + +% starting point (keep this) +% +% \long\def\doPDFinsertcomment#1#2#3#4#5#6#7#8% +% {\bgroup % title width height color open symbol collect data +% \doifelsenothing{#1} +% {\let\PDFidentifier\empty} +% {\def\PDFidentifier{/T (#1)}}% +% \doifelsenothing{#4} +% {\let\PDFattributes\empty} +% {\def\PDFattributes{/C \FDFcolor{#4}}}% +% \doifundefinedelse{PDFsymbol#6} +% {\let\PDFsymbol\empty} +% {\def\PDFsymbol{/Name \getvalue{PDFsymbol#6} }}% +% \sanitizePDFencoding#8\to\PDFdata +% \setbox\scratchbox\vbox to #3 +% {\vfill +% \doPDFannotation{#2}{#3} +% {/Subtype /Text +% \ifcase#5 \else/Open true\fi +% /Contents \ifPDFunicode <\PDFdata> \else(\PDFdata) \fi +% \PDFsymbol +% \PDFidentifier +% \PDFattributes}}% +% \wd\scratchbox\zeropoint +% \ht\scratchbox\zeropoint +% \dp\scratchbox\zeropoint +% \box\scratchbox +% \egroup} + +\newcounter\nofFDFcomments + +\newif\ifPDFpopupcomments \PDFpopupcommentstrue + +\def\doPDFflushcomments + {\box\PDFsymbolbox} + +\long\def\doPDFinsertcomment#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} +% {\def\PDFidentifier{/T (#1)}}% + \doifelsenothing{#1} + {\let\PDFidentifier\empty} + {\sanitizePDFencoding#1\to\PDFcommenttitle + \def\PDFidentifier{/T \ifPDFunicode <\PDFcommenttitle>\else (\PDFcommenttitle)\fi}}% + \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 + {\doPDFannotationobject{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 + \doPDFannotationobject{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 \ifPDFunicode <\PDFdata> \else(\PDFdata) \fi + \PDFidentifier + \FDFlayer + \PDFsymbol + \PDFattributes}% + \else + \doPDFannotation{#2}{#3} + {/Subtype /Text + \ifcase#5 \else/Open true\fi + /Contents \ifPDFunicode <\PDFdata> \else(\PDFdata) \fi + \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 {doPDFovalbox} +%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% + {\dimen2=#1% + \advance\dimen2 #2\relax + \PointsToBigPoints{\dimen2}#3} + +\def\doPDFovalbox#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 {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. + +% \newif\ifPDFstrokecolor \PDFstrokecolortrue + +\def\doPDFstartgraymode#1% +% {\PDFdirectcode{#1 g\ifPDFstrokecolor\space#1 G\fi}} + {\PDFcode{#1 g\ifPDFstrokecolor\space#1 G\fi}} + +\def\doPDFstopgraymode +% {\PDFdirectcode{0 g\ifPDFstrokecolor\space0 G\fi}} + {\PDFcode{0 g\ifPDFstrokecolor\space0 G\fi}} + +\def\doPDFstartrgbcolormode#1#2#3% +% {\PDFdirectcode{#1 #2 #3 rg\ifPDFstrokecolor\space#1 #2 #3 RG\fi}} + {\PDFcode{#1 #2 #3 rg\ifPDFstrokecolor\space#1 #2 #3 RG\fi}} + +\def\doPDFstartcmykcolormode#1#2#3#4% +% {\PDFdirectcode{#1 #2 #3 #4 k\ifPDFstrokecolor\space#1 #2 #3 #4 K\fi}} + {\PDFcode{#1 #2 #3 #4 k\ifPDFstrokecolor\space#1 #2 #3 #4 K\fi}} + +\def\doPDFstartgraycolormode#1% +% {\PDFdirectcode{#1 g\ifPDFstrokecolor\space#1 G\fi}} + {\PDFcode{#1 g\ifPDFstrokecolor\space#1 G\fi}} + +\def\doPDFstartspotcolormode#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 +% \PDFdirectcode{/#1 cs /#1 CS \PDFgetspotcolorspec{#2}}} + \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\doPDFstartnonecolormode +% {\PDFdirectcode{/None CS 1 SC /None cs 1 sc}} + {\PDFcode{/None CS 1 SC /None cs 1 sc}} + +\def\doPDFstopcolormode +% {\PDFdirectcode{0 g\ifPDFstrokecolor\space0 G\fi}} + {\PDFcode{0 g\ifPDFstrokecolor\space0 G\fi}} + +%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\doPDFregisternonecolor % internal command + {\doPDFregistergrayspotcolor{None}{1}% + \globallet\doPDFregisternonecolor\relax} + +\def\doPDFregisterspotcolorname#1#2% implemented in the driver + {} + +\definespecial\doregisterspotcolorname{\doPDFregisterspotcolorname} + +\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}} + +% \let\doPDFregisterrgbspotcolor \dodoPDFregisterrgbspotcolor +% \let\doPDFregistercmykspotcolor\dodoPDFregistercmykspotcolor +% \let\doPDFregistergrayspotcolor\dodoPDFregistergrayspotcolor + +\def\doPDFregisterrgbspotcolor#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\doPDFregistercmykspotcolor#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\doPDFregistergrayspotcolor{\dodoPDFregistergrayspotcolor} + +%D New and very experimental. + +\def\doPDFregistercmykindexcolor#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\doPDFregisterrgbindexcolor#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\doPDFregistergrayindexcolor#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\doPDFregisterfigurecolor#1% always an index color + {\dogetobjectreference + {PDFIX} + {\internalspotcolorname{#1}} + \PDFimagecolorreference} + +%D \macros +%D {doPDFstartrotation,doPDFstoprotation} +%D +%D Rotating some text can be accomplished by setting the first +%D four elements of the transform matrix. We only support some +%D fixed angles. The \type{q}'s take care of grouping. + +% The original: +% +% \def\doPDFstartrotation#1% +% {\PDFcode{q}% +% \processaction +% [#1] +% [ 90=>\PDFcode{ 0 1 -1 0 0 0 cm}, +% 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}]} +% +% We cannot directly pass an angle, but have to calculate +% factors (rx and ry). As in the \METAPOST\ to \PDF\ +% converter module we need to compensate the deformation +% by setting (sx and sy). +% +% Optimized but bigger: +% +% \def\doPDFstartrotation#1% +% {\PDFcode{q}% +% \processaction +% [#1] +% [ 0=>\PDFcode{ 1 0 0 1 0 0 cm}, +% 90=>\PDFcode{ 0 1 -1 0 0 0 cm}, +% 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=>\setcalculatedcos\cos{#1}% +% \setcalculatedsin\sin{#1}% +% \PDFcode{\cos \space % cos +% \sin \space % sin +% \negated\sin\space % -sin +% \cos \space % cos +% 0 0 cm}]} +% +% Since the sine and cosine values are preset and rounded we +% can use the next alternative without running into inaccuracies. + +\def\doPDFstartrotation#1% grouped + {\setcalculatedcos\cos{#1}% + \setcalculatedsin\sin{#1}% + \forcecolorhack + \PDFcode{q \cos\space\sin\space\negated\sin\space\cos\space0 0 cm}} + +\def\doPDFstoprotation + {\PDFcode{Q}} + +%D \macros +%D {doPDFstartscaling,doPDFstopscaling} +%D +%D Scaling is rather straightforward: + +\def\@@PDFzeroscale{.0001} + +\def\doPDFstartscaling#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\doPDFstartscaling#1#2% the test is needed because acrobat is bugged! +% {\PDFcode{q\ifdim#1\points=\zeropoint\else\ifdim#2\points=\zeropoint\else +% \space#1\space 0 0 #2\space 0 0 cm\fi\fi}} + +\def\doPDFstopscaling + {\PDFcode{Q}} + +%D \macros +%D {doPDFstartmirroring,doPDFstopmirroring} +%D +%D Mirroring is implemented in a similar way: + +\def\doPDFstartmirroring + {\PDFcode{-1 0 0 1 0 0 cm}} + +\def\doPDFstopmirroring + {\PDFcode{-1 0 0 1 0 0 cm}} + +%D \macros +%D {doPDFstartnegative,doPDFstopnegative} +%D +%D When producing output for an image setter, sometimes negative +%D output is needed. + +\def\doPDFstartnegative + {\ifx\initializePDFnegative\undefined\else + \initializePDFnegative +% \PDFdirectcode{/GSnegative gs}% + \PDFcode{/GSnegative gs}% + \fi} + +\def\doPDFstopnegative + {\ifx\initializePDFnegative\undefined\else + \initializePDFnegative +% \PDFdirectcode{/GSpositive gs}% + \PDFcode{/GSpositive gs}% + \fi} + +%D \macros +%D {doPDFstartoverprint,doPDFstopoverprint} +%D +%D Some printers like overprint more than knockout. + +\def\doPDFstartoverprint + {\ifx\initializePDFoverprint\undefined\else + \initializePDFoverprint +% \PDFdirectcode{/GSoverprint gs}% + \PDFcode{/GSoverprint gs}% + \fi} + +\def\doPDFstopoverprint + {\ifx\initializePDFoverprint\undefined\else + \initializePDFoverprint +% \PDFdirectcode{/GSknockout gs}% + \PDFcode{/GSknockout gs}% wrong + \fi} + +%D Transparency support: + +\newif\ifPDFtransparencysupported + +\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\doPDFstarttransparency + {\ifPDFtransparencysupported + \global\let\doPDFstarttransparency\dodoPDFstarttransparency + \global\let\doPDFstoptransparency \dodoPDFstoptransparency + \initializetransparency + \expandafter\doPDFstarttransparency + \else + \expandafter\gobbletwoarguments + \fi} + +% \let\doPDFstoptransparency\relax +% +% 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\doPDFstoptransparency + {\ifPDFtransparencysupported + \initializetransparency + \dodoPDFstoptransparency + \fi} + +%D These use: + +\let\PDFtransparencyresetreference \empty +\let\PDFtransparencyresetidentifier\empty + +\let\PDFtransparencyreference \empty +\let\PDFtransparencyidentifier\empty + +\let\presetPDFtransparency \gobbletwoarguments +\let\initializetransparency\relax + +%D New trickery: + +\definespecial\dostartgraphicgroup{\PDFcode{q}} +\definespecial\dostopgraphicgroup {\PDFcode{Q}} + +%D Even newer trickery: + +\definespecial\dostartviewerlayer {\doPDFstartlayer} +\definespecial\dostopviewerlayer {\doPDFstoplayer} +\definespecial\dodefineviewerlayer{\doPDFdefinelayer} + +\let\PDFtextlayers\empty +\let\PDFpagelayers\empty +\let\PDFhidelayers\empty +\let\PDFvidelayers\empty + +% \def\doPDFstartlayer#1{\PDFdirectcode{/OC /#1 BDC}} +% \def\doPDFstoplayer {\PDFdirectcode {EMC}} + +\def\doPDFstartlayer#1{\PDFcode{/OC /#1 BDC}} +\def\doPDFstoplayer {\PDFcode {EMC}} + +% resource -> prop -> mc's -> OCG|OCMD (nested) + +% ocg: + +% /Intent/Design + +% ocmd + +% /P /AllOn + +% kan zelf ocmd bevatten + +\def\doPDFdefinelayer#1#2#3#4#5% tag title visible type printable + {\doPDFdictionaryobject{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}}% + \doPDFdictionaryobject{PDLD}{#1} + {/Type /OCMD + /OCGs [\PDFobjectreference]}% + \doPDFgetobjectreference{PDLD}{#1}\PDFobjectreference + \xdef\PDFpagelayers{\PDFpagelayers\space /#1 \PDFobjectreference}} + +\def\flushPDFtextlayers + {\ifx\PDFtextlayers\empty \else + \driverreferenced \doPDFarrayobject{PDF}{textlayers}{\PDFtextlayers}% + \doPDFgetobjectreference{PDF}{textlayers}\!!stringa + \ifx\PDFvidelayers\empty + \def\!!stringb{[null]}% + \else + \driverreferenced \doPDFarrayobject{PDF}{videlayers}{\PDFvidelayers}% + \doPDFgetobjectreference{PDF}{videlayers}\!!stringb + \fi + \ifx\PDFhidelayers\empty + \def\!!stringc{[null]}% + \else + \driverreferenced \doPDFarrayobject{PDF}{hidelayers}{\PDFhidelayers}% + \doPDFgetobjectreference{PDF}{hidelayers}\!!stringc + \fi + \doPDFaddtocatalog + {/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 + \doPDFpageresource{/Properties <<\PDFpagelayers>>}% + \fi} + +\prependtoksonce \flushPDFpagelayers \to \everyshipout +\prependtoksonce \flushPDFtextlayers \to \everylastshipout + +\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\doPDFstartfonteffect#1#2#3% + {\ifdim#2>\zeropoint + \PointsToBigPoints{#2}\ascii +% \PDFdirectcode{\ascii\space w}% + \PDFcode{\ascii\space w}% + \fi + \ifdim#3\points=\onepoint\else + \scratchdimen#3\points +% \PDFdirectcode{\withoutpt{\the\scratchdimen}\space Tc}% + \PDFcode{\withoutpt{\the\scratchdimen}\space Tc}% + \fi +% \PDFdirectcode{\purenumber#1 Tr}} + \PDFcode{\purenumber#1 Tr}} + +\def\doPDFstopfonteffect +% {\PDFdirectcode{1 w 0 Tc 0 Tr}} + {\PDFcode{1 w 0 Tc 0 Tr}} + +%D Handy for the \METAPOST\ to \PDF\ converter: + +\ifdefined\everyPDFximage \else \newtoks\everyPDFximage \fi +\ifdefined\everyPDFxform \else \newtoks\everyPDFxform \fi + +\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}{docupatterns} + {\doPDFgetobjectreference{FDF}{docupatterns}\PDFobjectreference + \xdef\collectedPDFresources{\collectedPDFresources/Pattern \PDFobjectreference}}\donothing + \doifobjectreferencefoundelse{FDF}{colorspaces} + {\doPDFgetobjectreference{FDF}{colorspaces}\PDFobjectreference + \xdef\collectedPDFresources{\collectedPDFresources/ColorSpace \PDFobjectreference}}\donothing + \global\let\collectPDFresources\relax} + +%D And that was about all. + +\stopspecials + +\ifx\fullytransparentcolor\undefined \else + + \def\fullytransparentcolor + {\doPDFregisternonecolor + \doPDFstartnonecolormode} + + \let\doPDFstarttransparency\gobbletwoarguments + \let\doPDFstoptransparency\relax + +\fi + +%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.mkii b/tex/context/base/spec-ini.mkii new file mode 100644 index 000000000..0229a0e3d --- /dev/null +++ b/tex/context/base/spec-ini.mkii @@ -0,0 +1,559 @@ +%D \module +%D [ file=spec-ini, +%D version=1996.01.25, +%D title=\CONTEXT\ Special 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. + +% todo: make this one more plain so that i can use it in plain jobs +% todo: no args, named vars instead +% maybe also drop multiple drivers and make simplify the default, then simplier defs + +\newif\ifsimplifyspecials \simplifyspecialstrue % see later + +%D We will forbid loading specials after the first page is +%D shipped out. + +\ifx\realpageno\undefined + \countdef\realpageno=0 \realpageno=1 +\fi + +%D Specials are \TEX's channel to the outside world. They make +%D \TEX\ even more platform independant and permit easy +%D adaption to new developments. One major drawback of specials +%D is that they have to be supported by printer drivers. We've +%D tried to overcome this problem by implementing specials as +%D a sort of drivers themselves. + +\writestatus{loading}{ConTeXt Special Macros / Initialization} + +\unprotect + +%D \TEX\ produces files in the \DVI\ format. This format is +%D well defined and stable. In this format one||byte commands +%D are used which can optionally be followed by length +%D specifiers and arguments. The \DVI||format incorporates a +%D channel to the outside world. This channel is activated by +%D the \TEX\ primitive \type {\special}. The sequence +%D +%D \starttyping +%D \special{Hello here I am.} +%D \stoptyping +%D +%D results in \DVI||codes: +%D +%D \starttyping +%D xxx1 16 Hello here I am. +%D \stoptyping +%D +%D The \type {xxx1} is represented in byte code 239 and the +%D number of following bytes in a~1, 2, 3 or~4 byte number. So +%D here we get $1+1+16$ bytes of code. +%D +%D Translating these codes is upto the \DVI\ driver. It's +%D common use to ignore specials that cannot be interpreted, so +%D the example string should have no consequences for the +%D output. + +%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}. + +\def\jobsuffix{dvi} + +\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 + \ifx\setjobsuffix\undefined\else\setjobsuffix{dvi}\fi +\to \everyresetspecials + +%D A rather fundamental difference between special and direct +%D settings is that the latter don't interfere with typesetting +%D but must be set before the first shipout, while the specials +%D must be packaged in the shipped out box in such a way that +%D they don't interfere. + +\newif\ifspecialbasedsettings \specialbasedsettingstrue + +\appendtoksonce + \specialbasedsettingstrue +\to \everyresetspecials + +%D Because there is no standardization in the use of specials, +%D more than one driver or program can be supported. The +%D specials are grouped in libraries. Some of these are +%D general, such as the \type{postscript} library, some are +%D tuned to a special kind of program, like the \type{pdf} +%D ones, and some support a specific driver, as we can see in +%D the \type{yandy} library. A library is build with the +%D commands: +%D +%D \starttyping +%D \startspecials[name][inheritance] +%D +%D \definespecial\none{...} +%D \definespecial\onlyone#1{...} +%D \definespecial\alot#1#2#3#4{...} +%D +%D \stopspecials +%D \stoptyping +%D +%D Because drivers can have overlap in low level macros, a +%D mechanism of inheritance is implemented. The libraries +%D defined as second argument are loaded first. +%D +%D Every special has to be predefined first. We do this with +%D the command: +%D +%D \starttyping +%D \installspecial [\none] [and] [0] +%D \installspecial [\onlyone] [and] [1] +%D \installspecial [\alot] [or] [4] +%D \stoptyping +%D +%D This means as much as: there is a special names +%D \type{\none} which has no arguments and has more than one +%D appearance. The special \type{\alot} on the other hand has +%D four arguments and is only defined once. Every instance in +%D the libraries of a special of category \type{and} is +%D executed when called upon, but only one special of +%D category \type{or} can be active. Most of the +%D \type{postscript}||specials are of category \type{or}, +%D because they tend to interfere with driver specific ones. +%D The interactive specials of \type{dviwindo} and \type{pdf} +%D are an example of specials that can be called both. +%D +%D A library is defined in a file with the name +%D \type{spec-...}. We load a library with the command: +%D +%D \starttyping +%D \usespecials [list] +%D \stoptyping +%D +%D where the list can contain one or more file tags, the +%D \type{...} in the filename. The keyword \type{reset} +%D resets all loaded specials. This is equivalent to +%D \type{\resetspecials}. + +%D Although a mechanism of nesting can be implemented, we +%D prefer to use a inheritance mechanism as mentioned. Calls +%D upon \type{\usespecials} within a \type{\startspecials} +%D would lead to confusion and errors. + +\newif\ifinheritspecials + +%D We define some local constants and variables. They look a +%D bit horrible but we don't want conflicts. + +\def\@@specfil@@{@@spcfil@@} +\def\@@speclst@@{@@spclst@@} +\def\@@speccat@@{@@spccat@@} +\def\@@specarg@@{@@spcarg@@} +\def\@@specexc@@{@@spcexc@@} + +% not faster +% +% \def\@@specfil@@{@sp@f@} +% \def\@@speclst@@{@sp@l@} +% \def\@@speccat@@{@sp@c@} +% \def\@@specarg@@{@sp@a@} +% \def\@@specexc@@{@sp@e@} + +\let\currentspecial \empty +\let\currentspecialfile\empty + +%D \macros +%D {startspecials} +%D +%D Every library has a unique name, which is given as the first +%D argument to \type{\startspecials}. When another library is +%D defined with the same name, previous specials can be +%D overruled. The name may differ from the file||tag. +%D +%D The optional second argument can consist of a list of +%D libraries that are to be loaded first. + +\def\dostartspecials[#1][#2]% + {\doifsomething{#2} + {\processcommalist[#2]\dousespecials}% + \doifelsenothing{#1} + {\let\currentspecial\s!unknown} + {\def\currentspecial{#1}}% + \unprotect} + +\def\startspecials + {\localpushmacro\currentspecial + \dodoubleempty\dostartspecials} + +\def\stopspecials + {\localpopmacro\currentspecial + \protect} + +%D \macros +%D {installspecial, +%D resetspecials} +%D +%D We have to install specials before we can define and use +%D them. The command itself is defined as a call to another +%D command that executes one or more user||defined specials, +%D depending of it's category: \type{or} versus \type{and}. +%D +%D The command \type{\installspecial} takes three +%D (non||optional) arguments: the name of the command, the +%D category it belongs to and the number of arguments it +%D takes. +%D +%D With \type{\resetspecials} we can unload the predefined +%D specials. Special reset actions |<|look in \type{spec-mis} +%D for an example|>| can be assigned to the token register +%D \type{\everyresetspecials}. + +\let\@@allspecials=\empty + +\def\doinstallspecial[#1][#2][#3]% + {\letvalue{\@@speclst@@\string#1}\empty + \setvalue{\@@speccat@@\string#1}{#2}% + \setvalue{\@@specarg@@\string#1}{#3}% + \addtocommalist{\string#1}\@@allspecials + \def#1{\executespecial#1}} + +\def\installspecial + {\dotripleargument\doinstallspecial} + +\def\resetspecials + {\the\everyresetspecials + \def\docommand##1% + {\letvalue{\@@speclst@@##1}\empty}% + \processcommacommand[\@@allspecials]\docommand} + +%D \macros +%D {definespecial} +%D +%D The command \type{\definespecial} take the place of +%D \type{\def} in the definition of a special. Just to be +%D sure, we first check if the command is permitted, i.e. +%D installed. If not, we give a warning and gobble the +%D illegal command in an quite elegant way. +%D +%D If the command can be combined (\type{and}) with others, +%D we append it to a list, otherwise (\type{or}) it becomes +%D the only item in the list. + +\def\definespecial#1% + {\ifx#1\undefined + \showmessage\m!specials4{\string#1}% + \def\next + {\def\@@illegalspecial@@}% + \else + \def\next + {\doifelsevalue{\@@speccat@@\string#1}{or} + {\edef\@@newspeclst@@{\currentspecial}} + {\edef\@@newspeclst@@{\getvalue{\@@speclst@@\string#1}}% + \addtocommalist\currentspecial\@@newspeclst@@}% + \setevalue{\@@speclst@@\string#1}{\@@newspeclst@@}% + \setvalue{\currentspecial\string#1}}% + \fi + \next} + +%D \macros +%D {usespecials} +%D +%D We use \type{\usespecials} to load a specific library. +%D This command is only permitted outside the definition part. + +\def\dousespecials#1% + {\doifelse{#1}\v!reset + {\resetspecials} + {\doifdefinedelse{\@@specfil@@#1} + {\edef\currentspecialfile{\getvalue{\@@specfil@@#1}}} + {\edef\currentspecialfile{#1}}% + \makeshortfilename[\truefilename{\f!specialprefix\currentspecialfile}]% + \startreadingfile + \readsysfile{\shortfilename.mkii}{\showmessage\m!specials5\currentspecialfile}\donothing + \stopreadingfile}} + +\def\usespecials[#1]% + {\ifnum\realpageno<2 + \doifelsenothing\currentspecial + {\processcommalist[#1]\dousespecials} + {\showmessage\m!specials6\empty}% + \fi} + +%D \macros +%D {executespecials} +%D +%D The command \type{\executespecials} is used to execute the +%D defined specials. Once a special is installed, the special +%D itself calls for this command, so it's not needed outside +%D this module. One can use it if wanted. +%D +%D A former implementation grouped the execution. Recent +%D additions however |<|like the specials that implement object +%D handling|>| asked for non||grouped execution. + +%D \starttyping +%D \def\executespecials#1#2% +%D {\def\doonespecial##1% +%D {\getvalue{##1\string#1}#2\relax}% +%D \processcommacommand +%D [\getvalue{\@@speclst@@\string#1}]\doonespecial} +%D +%D \def\executespecial#1% +%D {\expandafter\ifcase\getvalue{\@@specarg@@\string#1}\relax +%D \def\next% +%D {\executespecials#1{}}% +%D \or +%D \def\next##1% +%D {\executespecials#1{{##1}}}% +%D \or +%D \def\next##1##2% +%D {\executespecials#1{{##1}{##2}}}% +%D \or +%D \def\next##1##2##3% +%D {\executespecials#1{{##1}{##2}{##3}}}% +%D \or +%D \def\next##1##2##3##4% +%D {\executespecials#1{{##1}{##2}{##3}{##4}}}% +%D \or +%D \def\next##1##2##3##4##5% +%D {\executespecials#1{{##1}{##2}{##3}{##4}{##5}}}% +%D \or +%D \def\next##1##2##3##4##5##6% +%D {\executespecials#1{{##1}{##2}{##3}{##4}{##5}{##6}}}% +%D \or +%D \def\next##1##2##3##4##5##6##7% +%D {\executespecials#1{{##1}{##2}{##3}{##4}{##5}{##6}{##7}}}% +%D \or +%D \def\next##1##2##3##4##5##6##7##8% +%D {\executespecials#1{{##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}}}% +%D \or +%D \def\next##1##2##3##4##5##6##7##8##9% +%D {\executespecials#1{{##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}{##9}}}% +%D \else +%D \def\next% +%D {\message{illegal special: \string#1}}% +%D \fi +%D \next} +%D \stoptyping +%D +%D Because specials happen quite often, we will use a bit more +%D brute force. Keep in mind that we have to collect the +%D arguments because we want to support more drivers at once. +%D +%D I tested this on the next test. Where the previous alternative +%D took about 32 seconds, the new alternative takes 25 seconds. +%D +%D \starttyping +%D \testfeature{10000}{\setbox0=\hbox{test \color[red]{oeps} test}} +%D \stoptyping + +\def\@@exsp{exsp} + +\setvalue{\@@exsp0}{{}} +\setvalue{\@@exsp1}#1{{{#1}}} +\setvalue{\@@exsp2}#1#2{{{#1}{#2}}} +\setvalue{\@@exsp3}#1#2#3{{{#1}{#2}{#3}}} +\setvalue{\@@exsp4}#1#2#3#4{{{#1}{#2}{#3}{#4}}} +\setvalue{\@@exsp5}#1#2#3#4#5{{{#1}{#2}{#3}{#4}{#5}}} +\setvalue{\@@exsp6}#1#2#3#4#5#6{{{#1}{#2}{#3}{#4}{#5}{#6}}} +\setvalue{\@@exsp7}#1#2#3#4#5#6#7{{{#1}{#2}{#3}{#4}{#5}{#6}{#7}}} +\setvalue{\@@exsp8}#1#2#3#4#5#6#7#8{{{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}}} +\setvalue{\@@exsp9}#1#2#3#4#5#6#7#8#9{{{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}}} + +%D \starttyping +%D \def\executespecials#1% +%D {\def\doonespecial##1% +%D {\csname##1\xspecialcommand\endcsname#1\relax}% +%D \@EA\rawprocesscommalist\@EA +%D [\csname\@@speclst@@\xspecialcommand\endcsname]\doonespecial} +%D +%D \def\executespecial#1% +%D {\def\xspecialcommand{\string#1}% +%D \@EA\@EA\@EA\executespecials\csname\@@exsp\csname\@@specarg@@\xspecialcommand\endcsname\endcsname} +%D \stoptyping + +%D Some more speed can be gained by using a dedicated string +%D processing routine. Now we can bring down the execution +%D time to 21 seconds, one third less than the original run time. + +\def\executespecials#1% + {\@EA\let\@EA\speciallist\csname\@@speclst@@\xspecialcommand\endcsname + \ifx\speciallist\empty\else + \def\doonespecial##1% + {\csname##1\xspecialcommand\endcsname#1\relax}% + \@EA\dodoonespecial\speciallist,\end,% + \fi} + +\def\executespecial#1% + {\def\xspecialcommand{\string#1}% + \@EA\@EA\@EA\executespecials\csname\@@exsp\csname\@@specarg@@\xspecialcommand\endcsname\endcsname} + +\def\dodoonespecial#1,% + {\ifx\end#1\else + \doonespecial{#1}\expandafter\dodoonespecial + \fi} + +%D This kind of saving only shows up when making interative +%D documents with lots of color switches. In such documents +%D tens of thousands of special calls are rather normal. +%D On a 650 Mhz Pentium, the previous test takes 15 seconds +%D less (on about 65 seconds). When processing 2000 page +%D interactive documents this saving can be neglected. + +%D In the previous macros, the \type{{{...}}} are needed +%D because we pass all those arguments to the specials support +%D macro. + +\let\openspecialfile \relax +\let\closespecialfile \relax + +%D \macros +%D {doifspecialavailableelse} +%D +%D For testing purposes (this was first needed when object +%D support was implemented) we have: +%D +%D \starttyping +%D \doifspecialavailableelse\specialcommand{true}{false} +%D \stoptyping +%D +%D e.g: +%D +%D \starttyping +%D \doifspecialavailableelse\doinsertobject{...}{...} +%D \stoptyping + +\def\doifspecialavailableelse#1#2#3% + {\doifelsevaluenothing{\@@speclst@@\string#1}{#3}{#2}} + +%D So far for the macros that deal with installing specials. +%D In the file \type {spec-def} you will find the predefined +%D specials. + +%D Now that we have seen the flexible way (permitting +%D special chains) we will implement a faster and flat +%D alternative. But only if flag si set. + +\ifsimplifyspecials + + \def\doinstallspecial[#1][#2][#3]% + {\appendtoks\forgetspecial#1{#3}\to\everyresetspecials + \@EA\chardef\csname\@@speclst@@\string#1\endcsname\zerocount + \forgetspecial#1{#3}} + + \def\forgetspecial#1#2% + {\ifcase#2\relax + \let#1\relax \or + \let#1\gobbleoneargument \or + \let#1\gobbletwoarguments \or + \let#1\gobblethreearguments \or + \let#1\gobblefourarguments \or + \let#1\gobblefivearguments \or + \let#1\gobblesixarguments \or + \let#1\gobblesevenarguments \or + \let#1\gobbleeightarguments \or + \let#1\gobbleninearguments \or + \let#1\gobbletenarguments \fi} + + \def\resetspecials + {\the\everyresetspecials} + + \def\definespecial#1% + {\@EA\chardef\csname\@@speclst@@\string#1\endcsname=1 + \def#1} + + \def\doifspecialavailableelse#1% + {\ifcase\csname\@@speclst@@\string#1\endcsname + \expandafter\secondoftwoarguments + \else + \expandafter\firstoftwoarguments + \fi} + +\fi + +%D For quite some time the \CONTEXT\ way of specifying the +%D output format has been: +%D +%D \starttyping +%D \usespecials[ps,yy,win,pdf] +%D \stoptyping +%D +%D Because at \PRAGMA\ we use \DVIPSONE, this was a suitable +%D setting, but with \CONTEXT\ going public, the next sequence +%D is more suitable for \DVIPS\ users: +%D +%D \starttyping +%D \usespecials[reset,ps,tr,pdf] +%D \stoptyping +%D +%D On the other hand, for \PDFTEX\ we needed: +%D +%D \starttyping +%D \usespecials[tpd] +%D \stoptyping +%D +%D To simplify things, I decided to provide a higher level +%D command. +%D +%D \starttyping +%D \defineoutput[name][specials] +%D \setupoutput[name,...] +%D \stoptyping +%D +%D In a \type {spec-def} you can find some examples. + +\def\defineoutput + {\dodoubleargument\dodefineoutput} + +\def\dodefineoutput[#1][#2]% + {\setvalue{\??ui#1}{#2}} + +\def\dosetupoutput#1% + {\doifdefinedelse{\??ui#1} + {\processcommacommand[\getvalue{\??ui#1}]\dousespecials} + {\doifdefinedelse{\@@specfil@@#1} + {\dousespecials{#1}} + {\showmessage\m!specials7{#1}}}} + +% Beware, from now on changing the (default) driver files demands +% remaking the format (no big deal, since only i adapt the driver +% and need delayed loading). + +\let\currentoutput\empty + +\def\setupoutput[#1]% + {\doifnot{#1}{\currentoutput} + {\ifnum\realpageno<\plustwo % new + \resetspecials\processcommacommand[#1]\dosetupoutput + \edef\currentoutput{#1}% + \fi}} + +\def\preloadspecials % it's nicer to report this + {\doifsomething\currentoutput + {\showmessage\m!specials1\currentoutput}} + +\appendtoks + \savecurrentvalue\usedoutputdriver\currentoutput +\to \everyfirstshipout + +\protect \endinput diff --git a/tex/context/base/spec-mis.mkii b/tex/context/base/spec-mis.mkii new file mode 100644 index 000000000..3d263eace --- /dev/null +++ b/tex/context/base/spec-mis.mkii @@ -0,0 +1,286 @@ +%D \module +%D [ file=spec-mis, +%D version=1997.04.01, +%D title=\CONTEXT\ Special Macros, +%D subtitle=Miscellaneous 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. + +%D Quite some modules in this group are dedicated to supporting +%D \PDF\ directly by means of \PDFTEX or indirectly by using +%D Acrobat Distiller. This module implements some common +%D features. + +\writestatus{loading}{ConTeXt Special Macros / Miscellaneous Macros} + +\unprotect + +%D \macros +%D {URLhash} +%D +%D A rather trivial macro: + +\expandafter\def\expandafter\URLhash\expandafter{\string#} + +%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 {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 \macros +%D {dofileinsertion,definefileinsertion,doiffileinsertionsupported} +%D +%D File insertion depend on the driver or \TEX\ variant used. +%D All driver modules use the same scheme for file insertion, +%D and therefore have the next macro in common (stupified +%D per august 2006): + +\let\supportedfileinsertions\empty +\let\supportedfilecheckers \empty + +\def\definefileinsertion#1#2#3% + {\addtocommalist{#2}\supportedfileinsertions + \setvalue{do#1insert#2}{#3}} + +\def\definefilechecker#1#2#3% + {\addtocommalist{#2}\supportedfilecheckers + \setvalue{do#1check#2}{#3}} + +\def\dofileinsertion#1#2{\executeifdefined{do#1insert#2}\donothing} +\def\dofilechecker #1#2{\executeifdefined{do#1check#2} \donothing} + +\appendtoks \let\supportedfileinsertions\empty \to \everyresetspecials +\appendtoks \let\supportedfilecheckers \empty \to \everyresetspecials + +% \def\doiffileinsertionsupportedelse#1% +% {\expanded{\doifinstringelse{#1}{\c!tex,\c!tmp,\supportedfileinsertions}}} + +\def\doiffileinsertionsupportedelse#1% lowercasing happens at tex end + {\expanded{\doifinstringelse{\truegraphictype{#1}}{\c!tex,\c!tmp,\supportedfileinsertions}}} + +%D This macro is called with 10 arguments, where the first +%D one specifies the driver, like \type{yy} or \type{tr}. The +%D second argument is a \type{{type,method}} pair and the +%D third the filename. + +%D Just in case this one is undefined (which can happen if +%D this module is used outside \CONTEXT): + +\ifx\setreferencefilename\undefined + + \def\setreferencefilename#1\to#2{\edef#2{#1}} + +\fi + +%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 \macros +%D {escapePSstring} +%D +%D \starttyping +%D \escapePSstring(t\e\1st)))))\to\crap \crap +%D \stoptyping + +% testcase: webschrift met lege regels en unbalanced () + +\bgroup + +\catcode`\*=\@@escape +\catcode`\\=\@@letter + +*long*gdef*escapedPSstring#1% + {*aftergroup*string + *ifnum`#1=12 + *aftergroup*n% + *else*ifnum`#1=13 + *aftergroup*n% + *else*if#1(% + *aftergroup*(% + *else*if#1)% + *aftergroup*)% + *else*if#1\% + *aftergroup*\% + *else + *aftergroup#1% + *fi*fi*fi*fi*fi} + +*egroup + +\long\def\escapePSstring#1\to#2% + {\defconvertedargument#2{#1}% + \bgroup + \ifx#2\empty \else + \setverbosecscharacters + \aftergroup\edef + \aftergroup#2% + \aftergroup{% + \expandafter\handletokens#2\with\escapedPSstring + \aftergroup}% + \fi + \egroup} + +% \long\def\preservePSpar#1\to#2% +% {\bgroup +% \def\par{\rawcharacter{12}}% +% \expanded{\egroup\noexpand\def\noexpand#2{#1}}} + +\long\def\preservePSpar#1\to#2% + {\bgroup + \def\par{\rawcharacter{12}\rawcharacter{12}}% hm, should be one 13 but 12 ff is platform safe + \expanded{\egroup\noexpand\def\noexpand#2{#1}}} + +%D \macros +%D {ifPDFunicode} +%D +%D We can use this switch to signal that content streams has +%D to be unicoded. + +\newif\ifPDFunicode + +%D \macros +%D {makeMPintoPDFobject, handleMPfshow, setMPPDFobject, getMPPDFobject} +%D +%D \METAPOST\ support. + +\appendtoks + \chardef\makeMPintoPDFobject\zerocount + \def\setMPPDFobject#1#2{\def\getMPPDFobject{\box#2}}% +\to \everyresetspecials + +\appendtoks + \let\handleMPfshow\dohandleMPfshow +\to \everyresetspecials + +%D + +%D \macros +%D {dosetposition, dosetpositionwdh, dosetpositionplus} +%D +%D Opposite to its \DVI\ counterpart, the \PDFTEX\ backend +%D can provide positional information directly. Since +%D \CONTEXT\ only uses relative positions, the origin is of +%D less importance. Nowadays \XETEX\ also supports this +%D feature. + +\ifx\pdfsavepos\undefined + + % only for ancient pdftex, less old xetex and current aleph + + \def\dosetposition #1{\special{pos:pxy "#1"}} + \def\dosetpositionwhd #1#2#3#4{\special{pos:pxywhd "#1" #2 #3 #4}} + \def\dosetpositionplus#1#2#3#4#5{\special{pos:pxyplus "#1" #2 #3 #4 #5}} + + \let\flushDVIpositionpapersize\relax + + \def\dosetpositionpapersize#1#2% + {\xdef\flushDVIpositionpapersize + {\special{pos:papersize \number#1 \number#2}% + \noexpand\installprogram{dvipos -o \jobname.tuo \jobname.dvi }% + \global\noexpand\let\noexpand\flushDVIpositionpapersize\relax}} + + % 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 + +\else + + \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}} + + \let\dosetpositionpapersize\gobbletwoarguments + +\fi + +%D Handy to have this available asap: + +\ifdefined\everyPDFxform \newtoks\everyPDFxform \fi +\ifdefined\everyPDFximage \newtoks\everyPDFximage \fi + +\protect \endinput diff --git a/tex/context/base/spec-pdf.mkii b/tex/context/base/spec-pdf.mkii new file mode 100644 index 000000000..2191eaeae --- /dev/null +++ b/tex/context/base/spec-pdf.mkii @@ -0,0 +1,484 @@ +%D \module +%D [ file=spec-pdf, +%D version=1997.09.20, +%D title=\CONTEXT\ Special Macros, +%D subtitle=Adobe \ACROBAT\ version 2.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. + +% funny things: mail to yeny: "please geen auto-crlf in special" + +\unprotect + +%D This driver is build on top of the general \PDF\ macros, +%D as defined in \type{spec-fdf}, so we inherit that one. + +\startspecials[pdf][fdf] + +%D \macros +%D {dosetupinteraction, +%D doPDFsetopenaction,doPDFsetcloseaction} +%D +%D Instead of a prolog, we can put the code in the file +%D ourselve. +%D +%D \starttyping +%D \definespecial\dosetupinteraction% +%D {\special +%D {\@@insertpostscriptretain +%D /pdfmark where +%D {pop} +%D {userdict /pdfmark /cleartomark load put} +%D ifelse}} +%D \stoptyping +%D +%D We decided to use a prolog file. The following code has to +%D be put somewhere, e.g.\ in the startup directory of +%D \DISTILLER. To overcome problems, we always embed the fonts, +%D but copyrights force us always to make subsets. +%D +%D \starttyping +%D /currentdistillerparams where +%D { pop } { userdict /currentdistillerparams { 1 dict } put } ifelse +%D +%D /setdistillerparams where +%D { pop } { userdict /setdistillerparams { pop } put } ifelse +%D +%D << /AntiAliasColorImages true +%D /AntiAliasGrayImages true +%D /AntiAliasMonoImages true +%D /ConvertCMYKImagesToRGB true +%D /MaxSubsetPct 99 +%D /EmbedAllFonts true +%D /SubSetFonts true >> setdistillerparams +%D \stoptyping +%D +%D Beware, this is the PostScript Level 2 way of doing things. + +\definespecial\dosetupinteraction + {\showmessage\m!interactions{21}{acrobat}} + +\definespecial\dosetupopenaction {\doPDFsetupopenaction} +\definespecial\dosetupcloseaction{\doPDFsetupcloseaction} + +%D \macros +%D {dostartthisislocation} +%D +%D We share a lot of macros with the \PDFTEX\ driver. First +%D the one that handles named destinations. + +\definespecial\dostartthisislocation {\doPDFstartthisislocation} + +%D \macros +%D {doresetgotowhereever, +%D dostartgotolocation,dostartgotorealpage,dostartgotoJS, +%D dostartexecutecommand,dostartrunprogram,dostartgotoprofile} +%D +%D The next specials are responsible for handling references. +%D Each goto handler can handle multiple references. + +\definespecial\doresetgotowhereever {\doPDFresetgotowhereever} +\definespecial\dostartgotolocation {\doPDFstartgotolocation} +\definespecial\dostartgotorealpage {\doPDFstartgotorealpage} +\definespecial\dostartgotoJS {\doPDFstartgotoJS} +\definespecial\dostartexecutecommand{\doPDFstartexecutecommand} +\definespecial\dostartrunprogram {\doPDFstartrunprogram} +\definespecial\dostartgotoprofile {\doPDFstartgotoprofile} + +%D \macros +%D {doflushJSpreamble} +%D +%D Thanks to the fact that \DISTILLER\ cannot handle multiple +%D names entries in the document catalog, for the moment we +%D have to misuse the page attributes. Beware, the preambles +%D must be packed. + +\definespecial\doflushJSpreamble#1% + {\bgroup + \ifoneJSpreamble + \edef\sanitizedJScode{\getJSpreamble{#1}}% + \expandafter\doPSsanitizeJScode\sanitizedJScode\to\sanitizedJScode + \special % nota bene, the page starts at 1 + {\@@insertpostscriptretain + [ /_objdef{JS:#1} /type /dict /OBJ pdfmark + [ {JS:#1} << /S /JavaScript /JS (\sanitizedJScode) >> /PUT pdfmark + [ {Page1} << /AA << /O {JS:#1} >> >> /PUT pdfmark}% + \else % temporary message + \writestatus{\m!specials}{Acrobat workaround needed: please pack JS preambles}% + \fi + \egroup} + +%D \macros +%D {dostarthide,dostophide} +%D +%D Hopefully some day hiding navigational things when +%D printing \PDF\ files will be supported properly. + +\definespecial\dostarthide% + {\special + {\@@insertpostscriptretain + [ /DataSource (false \iftrue\string{\else}\fi) + /PS + pdfmark}} + +\definespecial\dostophide% + {\special + {\@@insertpostscriptretain + [ /DataSource (\iffalse{\else\string}\fi if) + /PS + pdfmark}} + +%D \macros +%D {dosetupscreen, +%D dosetupidentity} +%D +%D We can set up the page dimensions, full screen start up +%D mode and identify the file with: + +\definespecial\dosetupscreen {\doPDFsetupscreen \printpaperheight} + +\definespecial\dosetupartbox {\doPDFsetupartbox \printpaperheight} +\definespecial\dosetupcropbox {\doPDFsetupcropbox \printpaperheight} +\definespecial\dosetupbleedbox{\doPDFsetupbleedbox\printpaperheight} +\definespecial\dosetuptrimbox {\doPDFsetuptrimbox \printpaperheight} + +\definespecial\dosetupidentity{\doPDFsetupidentity} + +%D \macros +%D {dobeginofprofile,doendofprofile} +%D +%D Profile support is still far from perfect. This is +%D especially due to the fact that the specification of +%D threads are sort of fuzzy and depend on the viewer. + +\definespecial\dobeginofprofile#1#2#3#4% label width height page + {\bgroup + \setPDFdestination{#1}% + \doifsomething{\PDFdestination} + {\PointsToBigPoints{#2}\width + \PointsToBigPoints{#3}\height + \special + {\@@insertpostscriptretain + [ /Title (\PDFdestination) + /Rect [0 0 \width\space\height] + /ARTICLE + pdfmark}}% + \egroup} + +\definespecial\doendofprofile% + {} + +%D Apart from movies, graphic inclusion is handled in the +%D \POSTSCRIPT\ drivers. We just link the movie annotation +%D handled to the file inclusion system. + +\definefileinsertion{yy}{mov}{\doPDFinsertmov} +\definefileinsertion{tr}{mov}{\doPDFinsertmov} + +\definefileinsertion{yy}{avi}{\doPDFinsertmov} +\definefileinsertion{tr}{avi}{\doPDFinsertmov} + +%D \macros +%D {doinsertsoundtrack} +%D +%D Sounds look much like movies: + +\definespecial\doinsertsoundtrack{\doPDFinsertsoundtrack} + +%D \macros +%D {dostartobject,dostopobject, +%D doinsertobject} +%D +%D Objects, those nice reusable pieces of text and graphics, +%D are handled by three specials: + +\definespecial\dostartobject#1#2#3#4#5% + {\bgroup + \setbox\nextbox=\hbox\bgroup + \bgroup + \PointsToBigPoints{#3}\width + \PointsToBigPoints{#4}\height + \PointsToBigPoints{#5}\depth + \dosetobjectreference{#1}{#2}{#1::#2}% + \special + {\@@insertpostscriptretain + [ /BBox [0 -\depth\space \width\space \height] + /_objdef {#1::#2} + /BP + pdfmark}% + \egroup} + +\definespecial\dostopobject% + {\special + {\@@insertpostscriptretain + [ /EP + pdfmark}% + \egroup + \smashbox\nextbox + \flushatshipout{\box\nextbox}% + \egroup} + +\definespecial\doinsertobject#1#2% + {\hbox + {\dogetobjectreference{#1}{#2}\PDFobjectreference + \ifx\PDFobjectreference\empty \else + \special + {\@@insertpostscriptretain + [ {\PDFobjectreference} + /SP + pdfmark}% + \fi}} + +%D \macros +%D {doinsertbookmark} +%D +%D Although personally I never use bookmarks, \CONTEXT\ does +%D support them, due to user requests. + +\definespecial\doinsertbookmark {\doPDFinsertbookmark} + +%D \macros +%D {dosetpagetransition} +%D +%D Page transitions, again a user wish, is taken care of by: + +\definespecial\dosetpagetransition{\doPDFsetpagetransition} + +%D \macros +%D {doinsertcomment, doflushcomments} +%D +%D I never needed (and used) one until now, but here is the +%D text annotation special: + +\definespecial\doinsertcomment{\doPDFinsertcomment} +\definespecial\doflushcomments{\doPDFflushcomments} + +%D \macros +%D {dopresetlinefield,dopresettextfield, +%D dopresetchoicefield,dopresetpopupfield,dopresetcombofield, +%D dopresetpushfield,dopresetcheckfield, +%D dopresetradiofield,dopresetradiorecord} +%D +%D There is nothing enervating to the next few mappings. + +\definespecial\dopresetlinefield {\doFDFpresetlinefield} +\definespecial\dopresettextfield {\doFDFpresettextfield} +\definespecial\dopresetchoicefield{\doFDFpresetchoicefield} +\definespecial\dopresetpopupfield {\doFDFpresetpopupfield} +\definespecial\dopresetcombofield {\doFDFpresetcombofield} +\definespecial\dopresetpushfield {\doFDFpresetpushfield} +\definespecial\dopresetcheckfield {\doFDFpresetcheckfield} +\definespecial\dopresetradiofield {\doFDFpresetradiofield} +\definespecial\dopresetradiorecord{\doFDFpresetradiorecord} + +%D \macros +%D {dodefinefieldset,dogetfieldset,doiffieldset} +%D +%D Field sets, used in resetting and submitting, are handled +%D by: + +\definespecial\dodefinefieldset{\doFDFdefinefieldset} +\definespecial\dogetfieldset {\doFDFgetfieldset} +\definespecial\doiffieldset {\doFDFiffieldset} + +%D \macros +%D {doregistercalculationset} +%D +%D The calculation order is defined using: + +\definespecial\doregistercalculationset{\doFDFregistercalculationset} + +%D \macros +%D {doPDFdestination} +%D +%D Last we implement the low level pdfmark macros. The +%D definitions are rather verbose. First the destination +%D macro. + +\def\doPDFdestination#1% + {\special + {\@@insertpostscriptretain + [ /Dest /#1\space + \PDFpageview + /DEST + pdfmark}} + +%D \macros +%D {doPDFaction,doPDFannotation,doPDFannotationobject, +%D ifsharePDFactions} +%D +%D We have three alternative annotation macros. The first +%D handles the goto ones, the second takes care of for instance +%D movies and the third is used in fields. + +\newcount\nofPDFsimilar + +\newif\ifsharePDFactions \sharePDFactionstrue + +\def\dodoPDFaction#1#2#3#4% + {\ifcollectreferenceactions + \xdef\lastPDFaction{#4}% + \else + \bgroup + % does not work well with distiller 4 + %\ifsharePDFactions + % \ifcase\similarreference\relax + % \xdef\lastPDFaction{<<#4>>}% + % \or + % \global\advance\nofPDFsimilar by 1 + % \special + % {\@@insertpostscriptretain + % [ /_objdef {PDF::sim:\the\nofPDFsimilar} /type /dict /OBJ pdfmark + % [ {PDF::sim:\the\nofPDFsimilar} <<#4>>\space /PUT pdfmark}% + % \xdef\lastPDFaction{{PDF::sim:\the\nofPDFsimilar}}% + % \else + % % leave \lastPDFaction untouched + % \fi + %\else + \xdef\lastPDFaction{<<#4>>}% + %\fi + \PointsToBigPoints{#2}\width + \PointsToBigPoints{#1}\height + \special + {\@@insertpostscriptretain + [ #1 + /Action \lastPDFaction\space + /Rect [0 0 \width\space \height] + /Border [0 0 0] + \ifhighlighthyperlinks \else /H /N \fi + /Subtype /Link + /ANN + pdfmark}% + \egroup + \fi} + +\def\doPDFaction#1#2#3% + {\dodoPDFaction\empty{#1}{#2}{#3}} + +\def\doPDFannotation#1#2#3% + {\bgroup + \PointsToBigPoints{#1}\width + \PointsToBigPoints{#2}\height + \special + {\@@insertpostscriptretain + [ /Rect [0 0 \width\space \height] #3 + /ANN + pdfmark}% + \egroup} + +\def\doPDFannotationobject#1#2#3#4#5% + {\bgroup + \PointsToBigPoints{#3}\width + \PointsToBigPoints{#4}\height + \special + {\@@insertpostscriptretain + [ /_objdef {#1::#2} + /Rect [0 0 \width\space \height] #5 + /ANN + pdfmark}% + \egroup + \dosetobjectreference{#1}{#2}{#1::#2}} + +\def\doPDFactionobject#1#2#3#4#5% + {\dodoPDFaction{/_objdef {#1::#2}}{#3}{#4}{#5}% + \dosetobjectreference{#1}{#2}{#1::#2}} + +%D \macros +%D {doPDFdictionaryobject,doPDFarrayobject} +%D +%D These two macros are used to build low level objects. + +\def\doPDFdictionaryobject#1#2#3% + {\special + {\@@insertpostscriptretain + [ /_objdef {#1::#2} /type /dict /OBJ pdfmark + [ {#1::#2} << #3 >> /PUT pdfmark}% + \dosetobjectreference{#1}{#2}{#1::#2}} + +\def\doPDFarrayobject#1#2#3% + {\special + {\@@insertpostscriptretain + [ /_objdef {#1::#2} /type /array /OBJ pdfmark + [ {#1::#2} 0 [#3] /PUTINTERVAL pdfmark}% + \dosetobjectreference{#1}{#2}{#1::#2}} + +%D \macros +%D {doPDFaddtocatalog,doPDFaddtoinfo, +%D doPDFpageattribute,doPDFpagesattribute} +%D +%D Next come our housekeeping macros. + +\def\doPDFaddtocatalog#1% + {\doifsomething{#1} + {\special + {\@@insertpostscriptretain + [ {Catalog} << #1 >> /PUT pdfmark}}} + +\def\doPDFaddtoinfo#1% unchecked + {\special + {\@@insertpostscriptretain + [ #1 /DOCINFO pdfmark}} % [ {DocInfo} << #1 >> /PUT pdfmark}} + +\def\doPDFpageattribute#1% + {\doifsomething{#1} + {\special + {\@@insertpostscriptretain + [ {ThisPage} << #1 >> /PUT pdfmark}}} + +\def\doPDFpageresource#1% + {\message{[skipping PDF resource]}} + +\def\doPDFpagesattribute#1% + {\doifsomething{#1} + {\special + {\@@insertpostscriptretain + [ #1 /PAGES pdfmark}}} + +\let\doPDFresetpageresources \relax +\let\doPDFresetpageattributes\relax + +%D \macros +%D {doPDFbookmark} +%D +%D This is how we force bookmarks entries in the file. + +\def\doPDFbookmark#1#2#3#4#5% + {\scratchcounter#4\advance\scratchcounter\minusone + \special + {\@@insertpostscriptretain + [ /Page \the\scratchcounter\space + \ifcase#2 \else/Count \ifcase#5-\fi#2 \fi + \PDFpageview + /Title (#3) + /OUT + pdfmark}} + +%D \macros +%D {defaultobjectreference,doPDFgetobjectreference} +%D +%D The object references are \type{{named}}, that is, no hard +%D coded numbers are needed (opposite to \PDFTEX). + +\def\defaultobjectreference#1#2{#1::#2} + +\def\doPDFgetobjectreference#1#2#3% + {\dogetobjectreference{#1}{#2}#3% + \ifx#3\empty\else\edef#3{{#3}}\fi} + %\edef#3{\ifx#3\empty null\else{#3}\fi}} + +% \def\doPDFgetobjectpage #1#2#3{..} +% \def\doPDFgetobjectpagereference#1#2#3{..} + +\def\doPDFgetpagereference#1#2% + {\edef#2{{page#1}}} + +%D Done. + +\stopspecials + +\protect \endinput diff --git a/tex/context/base/spec-ps.mkii b/tex/context/base/spec-ps.mkii new file mode 100644 index 000000000..803defe02 --- /dev/null +++ b/tex/context/base/spec-ps.mkii @@ -0,0 +1,229 @@ +%D \module +%D [ file=spec-ps, +%D version=1996.01.25, +%D title=\CONTEXT\ Special Macros, +%D subtitle=Adobe PostScript, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 {dostartgraymode,dostopgraymode, +%D dostartrgbcolormode,dostartcmykcolormode,dostartgraycolormode,dostopcolormode, +%D dostartrotation,dostoprotation, +%D dostartscaling,dostopscaling, +%D dostartmirroring,dostopmirroring, +%D dostartnegative,dostopnegative, +%D dostartoverprint,dostopoverprint, +%D doselectfirstpaperbin, +%D doselectsecondpaperbin} +%D +%D This implementation is straightforward and can be used as +%D a default with postscript||drivers. We use \type{ps:} as +%D opening, because most drivers support this. + +\startspecials[postscript] + +\def\@@insertpostscriptliteral {ps: } +\def\@@insertpostscriptretain {" } + +\definespecial\dostartgraymode#1% + {\special + {\@@insertpostscriptliteral + #1\space setgray}} + +\definespecial\dostopgraymode + {\special + {\@@insertpostscriptliteral + 0 setgray}} + +\definespecial\dostartrgbcolormode#1#2#3% + {\special + {\@@insertpostscriptliteral + #1\space #2\space #3\space setrgbcolor}} + +\definespecial\dostartcmykcolormode#1#2#3#4% + {\special + {\@@insertpostscriptliteral + #1\space #2\space #3\space #4\space setcmykcolor}} + +\definespecial\dostartgraycolormode#1% + {\special + {\@@insertpostscriptliteral + #1\space setgray}} + +\definespecial\dostopcolormode + {\special + {\@@insertpostscriptliteral + 0 setgray}} + +\definespecial\doselectfirstpaperbin + {\special + {\@@insertpostscriptliteral + statusdict begin 1 setpapertray end}} % checken + +\definespecial\doselectsecondpaperbin + {\special + {\@@insertpostscriptliteral + statusdict begin 0 setpapertray end}} % checken + +\definespecial\dostartrotation#1% straight from the YandY manual + {\special + {\@@insertpostscriptliteral + gsave currentpoint currentpoint translate + \number#1\space\space rotate neg exch neg exch translate}} + +\definespecial\dostoprotation + {\special + {\@@insertpostscriptliteral + currentfont currentpoint grestore moveto setfont}} + +\definespecial\dostartscaling#1#2% conforming the YandY manual + {\special + {\@@insertpostscriptliteral + gsave currentpoint currentpoint translate + #1\space #2\space scale neg exch neg exch translate}} + +\definespecial\dostopscaling + {\special + {\@@insertpostscriptliteral + currentfont currentpoint grestore moveto setfont}} + +\definespecial\dostartmirroring % some translate and exch stuff from YandY + {\special + {\@@insertpostscriptliteral + gsave currentpoint currentpoint translate + [-1 0 0 1 0 0] concat neg exch neg exch translate}} + +\definespecial\dostopmirroring + {\special + {\@@insertpostscriptliteral + currentfont currentpoint grestore moveto setfont}} + +\definespecial\dostartnegative + {\special{\@@insertpostscriptliteral gsave {1 exch sub} settransfer}} + +\definespecial\dostopnegative + {\special{\@@insertpostscriptliteral grestore}} + +\definespecial\dostartoverprint + {\special{\@@insertpostscriptliteral true setoverprint}} + +\definespecial\dostopoverprint + {\special{\@@insertpostscriptliteral false setoverprint}} + +\definespecial\dostartgraphicgroup + {\special{\@@insertpostscriptliteral gsave}} + +\definespecial\dostopgraphicgroup + {\special{\@@insertpostscriptliteral grestore}} + +%D \macros +%D {doovalbox} +%D +%D This implementation is a mixture of several possible +%D implementations. We use some constants that may not be +%D changed. It took some time to find them, but these values +%D offer quite accurate results. The macro calls for +%D \type{\forgetall}, which resets indentation, skips and +%D \type{\everypar}. +%D +%D Because a stroke follows the line, we correct for half of +%D the linewidth. Furthermore we use scaling to overcome some +%D limitations in the precision ($<1$~sp) and to prevent +%D rounding errors. We also do some correction for large +%D values. We let PostScript compare some arguments with +%D \type{a b eq {action} fi}. +%D +%D The path is based on a macro of J.~Hefferon cs. We also +%D tried the D.~Salomon implementation, but this did not work +%D well, just like some other alternatives. + +% #1 = width #2 = height #3 = depth +% #4 = linewidth #5 = radius +% #5 = stroke (ja,nee) #7 = fill (ja,nee) + +\def\@@insertpostscriptliteral {ps: } +\def\@@insertpostscriptretain {postscript } % unknown + +\def\dosomeovalcalc#1#2#3% + {\dimen2=#1% + \advance\dimen2 #2% + \PointsToBigPoints{\dimen2}#3} + +\def\dosomeovalbox#1#2#3#4#5#6#7#8% variant not yet supported + {\bgroup + \dimen0=#4\divide\dimen0 2 + \dosomeovalcalc{0pt}{+\dimen0}\xmin + \dosomeovalcalc{#1}{-\dimen0}\xmax + \dosomeovalcalc{#2}{-\dimen0}\ymax + \dosomeovalcalc{-#3}{+\dimen0}\ymin + \dosomeovalcalc{#4}{0pt}\stroke + \dosomeovalcalc{#5}{0pt}\radius + \edef\dostroke{#6}% + \edef\dofill{#7}% + \setbox\nextbox\hbox + {\ifnum\dostroke\dofill>0 + \special + {\@@insertpostscriptretain + gsave + newpath + \xmin\space \radius\space add \ymin\space moveto + \xmax\space \ymin\space \xmax\space \ymax\space \radius\space arcto + \xmax\space \ymax\space \xmin\space \ymax\space \radius\space arcto + \xmin\space \ymax\space \xmin\space \ymin\space \radius\space arcto + \xmin\space \ymin\space \xmax\space \ymin\space \radius\space arcto + \xmin\space \radius\space add \ymin\space moveto + 16 {pop} repeat + closepath + (\dostroke) (1) eq + {\stroke\space 0 ne + {gsave + \stroke\space setlinewidth + stroke + grestore} if} if + (\dofill) (1) eq + {fill} if + grestore}% + \fi}% + \nextboxwd#1% + \nextboxht#2% + \nextboxdp#3% + \flushnextbox + \egroup} + +%D The indirect call permits a (rather) dirty hack, needed +%D for \DVIPS\ support. + +\definespecial\doovalbox + {\dosomeovalbox} + +%D \macros +%D {dostartclipping,dostopclipping} +%D +%D These two specials are not yet working as expected. + +\definespecial\dostartclipping#1#2#3% + {\PointsToBigPoints{#2}\width + \PointsToBigPoints{#3}\height + \grabMPclippath{#1}{0}{\width}{\height} + {0 0 moveto \width 0 lineto \width \height lineto 0 \height\space lineto}% + \special + {\@@insertpostscriptliteral\space + save newpath \MPclippath\space closepath clip}} + +\definespecial\dostopclipping + {\special{\@@insertpostscriptliteral\space restore}} + +%D Some MP stuff: + +\definespecial\doinsertMPfile#1% + {\doiffileelse{./#1}{\includeMPasEPS{./#1}}{\message{[MP #1]}}} + +\stopspecials + +\endinput diff --git a/tex/context/base/spec-tpd.mkii b/tex/context/base/spec-tpd.mkii new file mode 100644 index 000000000..6af3b1272 --- /dev/null +++ b/tex/context/base/spec-tpd.mkii @@ -0,0 +1,1334 @@ +%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. + +% 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 + +% layers and links don't work while the spec says they should + +% method = auto +% +% \definefileinsertion{tpd}{auto}% +% {\executesystemcommand{t:/ruby/pstopdf.rb #2}% +% \dofileinsertion{tpd}{pdf}} + +% \let\PDFdestvoffset\zeropoint +% \newbox\pdfdestbox +% +% \def\doPDFdestination#1% +% {\ifdim\PDFdestvoffset=\zeropoint\relax +% \pdfdest name {#1}\PDFpageviewkey +% \else +% \setbox\pdfdestbox\hbox to \zeropoint +% {\raise\PDFdestvoffset\hbox{\pdfdest name {#1}\PDFpageviewkey}}% +% \ht\pdfdestbox\zeropoint +% \box\pdfdestbox +% \fi} +% +% \def\PDFdestvoffset{2\lineheight} % {1.5\strutht} + +%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. + +\unprotect + +\ifx\pdftexversion\undefined + \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 + \protect\expandafter\endinput +\fi + +\ifnum\pdftexversion<14 + \writestatus\m!systems{please update your pdfTeX binaries} +\fi + +\ifnum\pdftexversion>19 + \pdfhorigin=1 true in + \pdfvorigin=1 true in +\fi + +%D We default to 300 dots per inch image resolution and 600 dpi +%D bitmap fonts (when asked for). + +\ifx\pdfimageresolution\undefined \newcount\pdfimageresolution \fi +\ifx\pdfpkresolution \undefined \newcount\pdfpkresolution \fi + +\pdfimageresolution=300 +\pdfpkresolution =600 + +%D Another downward compatible hack: + +\ifx\pdflastximagepages\undefined + \newcount\pdflastximagepages \pdflastximagepages=1 +\fi + +%D And: + +\ifx\pdfpageresources\undefined + \newtoks\pdfpageresources +\fi + +%D In order to get high quality \METAPOST\ inclusion, we set +%D the number of digits to~5 (prevents rounding errors). + +\ifx\pdfdecimaldigits\undefined + \newcount\pdfdecimaldigits +\fi + +\pdfdecimaldigits=10 + +\ifx\pdfinclusionerrorlevel\undefined + \ifx\pdfoptionpdfinclusionerrorlevel\undefined + \newcount\pdfinclusionerrorlevel + \else + \let\pdfinclusionerrorlevel\pdfoptionpdfinclusionerrorlevel + \fi +\fi + +\pdfinclusionerrorlevel=0 + +\ifx\pdfminorversion\undefined + \ifx\pdfoptionpdfminorversion\undefined + \newcount\pdfminorversion + \else + \let\pdfminorversion\pdfoptionpdfminorversion + \fi +\fi + +\pdfminorversion=5 + +\def\PDFversion{1.\number\pdfminorversion} + +% %D Why are the Acrobat viewers so buggy? To prevent font cache +% %D mismatches, we say: +% +% \ifx\pdfuniqueresname\undefined \else +% \pdfuniqueresname=1 +% \fi + +%D Once we are sure that we're indeed supporting \PDFTEX, we +%D force \PDF\ output at the highest compression. For debugging +%D purposes one can set the compresslevel to~0. We also have to +%D make sure no other specials are supported, else \PDFTEX\ +%D will keep on telling us that we're wrong. We also load the +%D general \PDF\ macros that are shared between this driver and +%D the \ACROBAT\ one. + +\startspecials[tpd][reset,fdf] + +%D This means that by saying +%D +%D \starttyping +%D \usespecials[tpd] +%D \stoptyping +%D +%D we get ourselves full \PDF\ output. + +%D For some internal testing we need to know the output +%D suffix. + +\setjobsuffix{pdf} + +%D We don't use specials here, which means that we must flush +%D settings before the page is shipped out. + +\specialbasedsettingsfalse + +%D Some more internal settings. + +\appendtoksonce + \pdfoutput\zerocount +\to \everyresetspecials + +\pdfoutput=1 % we reset that one with \everyresetspecials + +%D Just in case we mimmick specials, we have to make sure no +%D default specials end up in the process. + +\let\defaultspecial=\gobbleoneargument + +\appendtoksonce + \let\defaultspecial\normalspecial +\to \everyresetspecials + +\let\PDFcode \pdfliteral +\def\PDFcontentcode{\pdfliteral} +\def\PDFdirectcode {\pdfliteral direct} + +%D \macros +%D {everyPDFximage} +%D +%D This token register is flushed before an ximage is loaded. + +\ifdefined\everyPDFximage \else \newtoks\everyPDFximage \fi +\ifdefined\everyPDFxform \else \newtoks\everyPDFxform \fi + +%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: + +\definespecial\dosetuppaper#1#2#3% + {\global\pdfpagewidth #2\relax + \global\pdfpageheight#3\relax} + +%D \macros +%D {doloadmapfile,doloadmapline,doresetmapfilelist} + +\ifx\pdfmapfile\undefined \let\pdfmapfile\gobbletwoarguments \fi +\ifx\pdfmapline\undefined \let\pdfmapline\gobbletwoarguments \fi + +\definespecial\doresetmapfilelist + {\global\let\doresetmapfilelist\relax + \pdfmapfile{original-empty.map}} + +\ifnum\pdftexversion<120 + + \definespecial\doloadmapfile #1#2{\pdfmapfile{+#2}} + \definespecial\doloadmapline #1#2{} + +\else + + \definespecial\doloadmapfile #1#2{\pdfmapfile{#1#2}} + \definespecial\doloadmapline #1#2{\pdfmapline{#1#2}} + +\fi + +%D nasty but needed + +\appendtoksonce \loadallfontmapfiles \to \everyPDFximage +\appendtoksonce \loadallfontmapfiles \to \everyPDFxform + +%D \macros +%D {doinsertfile,dogetnofinsertpages} +%D +%D Graphics are not part of \TEX\ and therefore not part of the +%D \DVI\ standard. \PDF\ on the other hand has several graphic +%D primitives. During the multi||step process \TEX\ +%D $\rightarrow$ \DVI\ $\rightarrow$ \POSTSCRIPT\ $\rightarrow$ +%D \PDF\ one can insert graphics using specials. In \PDFTEX\ +%D however there is only one step! This means that \PDFTEX\ +%D itself has to do the inclusion. +%D +%D At the moment \PDFTEX\ supports inclusion of bitmap \PNG\ +%D graphics as well as not too complicated \PDF\ code. Using +%D this last option, we are able to include both \METAPOST\ and +%D \PDF\ output produced by \GHOSTSCRIPT. +%D +%D We fall back on the generic \CONTEXT\ module supp-pdf to +%D accomplish \PDF\ inclusion. The methods implemented there +%D are hooked into both the figure placement mechanisms of +%D \CONTEXT\ and the specials inclusion mechanism. + +\definespecial\doinsertfile + {\dofileinsertion{tpd}{\truegraphictype\@@DriverImageType}} + +%D The number of pages in (for instance an \PDF) insert +%D file, can be asked for using: + +\definespecial\dogetnofinsertpages#1% + {\xdef\nofinsertpages{1}% global + \doifvalidpdfimagefileelse{#1}% + {\pdfximage{#1}\xdef\nofinsertpages{\the\pdflastximagepages}} + {}} + +%D Currently we support \type{pdf} for \PDF\ files, \type{mps} +%D for \METAPOST\ graphics, \type{png} and \type{jpg} for +%D bitmap graphics. + +\definefileinsertion{tpd}{mps} + {\hbox + {\convertMPtoPDF\@@DriverImageFile{1}{1}% + \global\let\PDFimagereference\empty}} + +\definefileinsertion{tpd}{pdf}{\handlepdfimage} +\definefileinsertion{tpd}{png}{\handlepdfimage} +\definefileinsertion{tpd}{jpg}{\handlepdfimage} +\definefileinsertion{tpd}{jb2}{\handlepdfimage} + +% \definefileinsertion{tpd}{jpeg} {\handlepdfimage} +% \definefileinsertion{tpd}{jbig2}{\handlepdfimage} + +%D Experimental: + +%D The main file insertion macro is as follows. Because +%D \PDFTEX\ does not support arbitrary suffixes, we double +%D check on a user supplied filename, because \PDFTEX\ chokes +%D on unknown suffixes. + +\def\doifvalidpdfimagefileelse#1% todo: greedy split + {\doiffileelse{#1} + {\edef\filesuffix{#1}% + \doloop + {\@EA\aftersplitstring\filesuffix\at.\to\temp + \ifx\temp\empty + \exitloop + \else + \lowercasestring\temp\to\filesuffix % insertion check also needs lowercase + % a temporary hack + \doif\filesuffix{pdf}{\pdfimageresolution72}% + % because pdfTeX scales back + \fi}} + {\let\filesuffix\s!unknown}% + \doiffileinsertionsupportedelse\filesuffix} + +\ifx\pdflastximagepages\undefined \chardef\pdflastximagepages=1 \fi + +\def\checkpdfimagepagenumber + {\edef\pdfimagepagenumber + {\ifx\@@DriverImagePage\empty\else\ifnum\@@DriverImagePage>\zerocount + \space page\space\@@DriverImagePage\space + \fi\fi}} + +\ifnum\pdftexversion>13 + + \def\handlepdfimage + {\bgroup + \the\everyPDFximage + \doifvalidpdfimagefileelse\@@DriverImageFile + {\checkpdfimagepagenumber + \ifx\pdfimagepagenumber\empty\@EA\pdfimmediateximage\else\@EA\pdfximage\fi + \ifdim\@@DriverImageWidth >\zeropoint \!!width \@@DriverImageWidth \fi + \ifdim\@@DriverImageHeight>\zeropoint \!!height\@@DriverImageHeight\fi + \pdfimagepagenumber + \@@DriverImageBox + {\@@DriverImageFile} + \xdef\PDFimagereference{\the\pdflastximage}% + \xdef\nofinsertpages{\the\pdflastximagepages}% + \pdfrefximage\pdflastximage} + {\framed[\c!width=\@@DriverImageWidth,\c!height=\@@DriverImageHeight]{\@@DriverImageFile}}% + \egroup} + +\else + + \def\handlepdfimage + {\bgroup + \doifvalidpdfimagefileelse\@@DriverImageFile + {\pdfimage + \ifdim\@@DriverImageWidth >\zeropoint \!!width \@@DriverImageWidth \fi + \ifdim\@@DriverImageHeight>\zeropoint \!!height \@@DriverImageHeight\fi + {\@@DriverImageFile}}% + {\framed[\c!width=\@@DriverImageWidth,\c!height=\@@DriverImageHeight]{\@@DriverImageFile}}% + \egroup} + +\fi + +%D As we will see now, \PDFTEX\ not only directly supports +%D \type{mps}, \type{png}, \type{pdf}, \type{jpg} but also +%D \type{mov}. In \CONTEXT\ we support movie inserts in a way +%D similar to figure inclusion. The next macro calls the +%D general \PDF\ one. + +\definefileinsertion{tpd}{mov}{\doPDFinsertmov} +\definefileinsertion{tpd}{avi}{\doPDFinsertmov} + +%D \macros +%D {doinsertsoundtrack} +%D +%D We use numbers instead of labels to keep track of sounds. + +\definespecial\doinsertsoundtrack{\doPDFinsertsoundtrack} + +%D For the moment we don't test for alternatives that +%D themselves have alternatives, especially cylcic +%D dependencies. + +% some day we will do a proper check on bitmap depth, +% +% \pdfobj reserveobjnum\relax +% \pdfximage colorspace \pdflastobj {some file} +% ... \pdflastximagecolordepth ... +% \immediate\pdfobj useobjnum \pdflastobj {some spec} + +\ifx\@@DriverImageBox\undefined \def\@@DriverImageBox{artbox} \fi + +\def\pdfimmediateximage{\immediate\pdfximage} + +\ifnum\pdftexversion>13 + + \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} + + \def\dogetTPDfiguresize + {\doifvalidpdfimagefileelse\@@DriverImageFile + {\ifvoid\foundexternalfigure + \donetrue + \else\ifx\PDFfigurereference\empty + \donetrue + \else + % hm, is this still needed + \doifinstringelse\filesuffix{\c!png,\c!jpg}\donetrue\donefalse + \fi\fi} + {\donefalse}% + \ifdone + \the\everyPDFximage + \checkpdfimageattributes + \checkpdfimagecolorspecs + \checkpdfimagepagenumber + \global\setbox\foundexternalfigure\hbox + {\ifx\pdfimagepagenumber\empty\@EA\pdfimmediateximage\else\@EA\pdfximage\fi + \pdfimageattributes + \pdfimagecolorspecs + \pdfimagepagenumber + \@@DriverImageBox + {\@@DriverImageFile}% + \xdef\PDFimagereference{\the\pdflastximage}% + \xdef\nofinsertpages{\the\pdflastximagepages}% + \pdfrefximage\pdflastximage}% + \xdef\analyzedfigurewidth {\the\wd\foundexternalfigure}% + \xdef\analyzedfigureheight{\the\ht\foundexternalfigure}% + \global\let\PDFfigurereference\empty + \global\let\PDFimageattributes\empty + \else + \global\let\analyzedfigurewidth \!!zeropoint + \global\let\analyzedfigureheight\!!zeropoint + \fi} + +\else + + \def\dogetTPDfiguresize + {\doifvalidpdfimagefileelse\@@DriverImageFile + {\global\setbox\foundexternalfigure\vbox{\pdfimage{\@@DriverImageFile}}% + \xdef\analyzedfigurewidth {\the\wd\foundexternalfigure}% + \xdef\analyzedfigureheight{\the\ht\foundexternalfigure}} + {\global\let\analyzedfigurewidth \!!zeropoint + \global\let\analyzedfigureheight\!!zeropoint}} + +\fi + +\definefilechecker{tpd}{pdf}{\dogetTPDfiguresize} +\definefilechecker{tpd}{png}{\dogetTPDfiguresize} +\definefilechecker{tpd}{jpg}{\dogetTPDfiguresize} +\definefilechecker{tpd}{jb2}{\dogetTPDfiguresize} + +\definespecial\dogetfiguresize + {\dofilechecker{tpd}{\truegraphictype\@@DriverImageType}} + +%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). + +\ifnum\pdftexversion>13 + + \definespecial\doregisterfigure#1#2% + {\doifundefined{IM::#1::#2} + {\setxvalue{IM::#1::#2}{\the\pdflastximage}}% + \xdef\PDFfigurereference{\getvalue{IM::#1::#2}}} + +\fi + +%D \macros +%D {doovalbox} +%D +%D Drawing frames with round corners is inherited from the +%D main module. + +\definespecial\doovalbox {\doPDFovalbox} + +%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} +%D +%D These are implemented in the main \PDF\ module. + +\definespecial\dostartgraymode {\doPDFstartgraymode} +\definespecial\dostopgraymode {\doPDFstopgraymode} +\definespecial\dostartrgbcolormode {\doPDFstartrgbcolormode} +\definespecial\dostartcmykcolormode{\doPDFstartcmykcolormode} +\definespecial\dostartgraycolormode{\doPDFstartgraycolormode} +\definespecial\dostartspotcolormode{\doPDFstartspotcolormode} +\definespecial\dostopcolormode {\doPDFstopcolormode} +\definespecial\dostartrotation {\doPDFstartrotation} +\definespecial\dostoprotation {\doPDFstoprotation} +\definespecial\dostartscaling {\doPDFstartscaling} +\definespecial\dostopscaling {\doPDFstopscaling} +\definespecial\dostartmirroring {\doPDFstartmirroring} +\definespecial\dostopmirroring {\doPDFstopmirroring} +\definespecial\dostartnegative {\doPDFstartnegative} +\definespecial\dostopnegative {\doPDFstopnegative} +\definespecial\dostartoverprint {\doPDFstartoverprint} +\definespecial\dostopoverprint {\doPDFstopoverprint} + +\definespecial\doregistercmykspotcolor{\doPDFregistercmykspotcolor} +\definespecial\doregisterrgbspotcolor {\doPDFregisterrgbspotcolor} +\definespecial\doregistergrayspotcolor{\doPDFregistergrayspotcolor} + +\definespecial\doregistercmykindexcolor{\doPDFregistercmykindexcolor} +\definespecial\doregisterrgbindexcolor {\doPDFregisterrgbindexcolor} +\definespecial\doregistergrayindexcolor{\doPDFregistergrayindexcolor} + +\definespecial\doregisterfigurecolor{\doPDFregisterfigurecolor} + +\definespecial\dostartnonecolormode{\doPDFstartnonecolormode} +\definespecial\doregisternonecolor {\doPDFregisternonecolor} + +\def\doPDFregisterspotcolorname#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/\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 +% {\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 \PDFobjref\pdflastobj] % +% 255 <\PDFcolorindexvector>]}% +% \dosetobjectreference{PDFIX}{#1}{\the\pdflastobj}% +% \appendtoPDFdocumentcolorspaces{/#1_INDEXED \PDFobjref\pdflastobj}% +% \egroup} + +% we reverse the index; an alternative is to negate the graphic itself (\start/stop negative) + +\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. + +\definespecial\dostarttransparency{\doPDFstarttransparency} +\definespecial\dostoptransparency {\doPDFstoptransparency} + +\PDFtransparencysupportedtrue + +\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 \macros +%D {dostartclipping,dostopclipping} +%D +%D Clipping in \PDFTEX\ is rather trivial. We can even hook +%D in \METAPOST\ without problems. + +\definespecial\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}} + +\definespecial\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. + +\definespecial\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. + +\definespecial\doresetgotowhereever {\doPDFresetgotowhereever} +\definespecial\dostartthisislocation{\doPDFstartthisislocation} + +%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. + +\definespecial\dostartgotolocation{\doPDFstartgotolocation} +\definespecial\dostartgotorealpage{\doPDFstartgotorealpage} +\definespecial\dostartgotoJS {\doPDFstartgotoJS} + +\let\PDFpagexyzspec\empty % pdftex does not accept spec + +%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 + +\definespecial\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. + +\definespecial\dostarthide{} +\definespecial\dostophide {} + +%D \macros +%D {dosetupscreen} +%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. + +\definespecial\dosetupscreen {\doPDFsetupscreen \pdfpageheight} + +\definespecial\dosetupartbox {\doPDFsetupartbox \pdfpageheight} +\definespecial\dosetupcropbox {\doPDFsetupcropbox \pdfpageheight} +\definespecial\dosetupbleedbox{\doPDFsetupbleedbox\pdfpageheight} +\definespecial\dosetuptrimbox {\doPDFsetuptrimbox \pdfpageheight} + +%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. + +\definespecial\dostartexecutecommand{\doPDFstartexecutecommand} + +%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. + +\definespecial\dosetupidentity{\doPDFsetupidentity} + +%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. + +\definespecial\dostartrunprogram{\doPDFstartrunprogram} + +%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. + +\definespecial\dostartgotoprofile{\doPDFstartgotoprofile} + +%D Some day, I'll reimplement threading in a useful way. +%D Currently the viewers handle threads rather diffuse. + +\ifnum\pdftexversion>13 + +\definespecial\dobeginofprofile#1#2#3#4% + {\setPDFdestination{#1}% + \doifsomething\PDFdestination + {\pdfthread + width #2 height #3 + attr {/Title (\PDFdestination)} % can be omitted + name {\PDFdestination}}} + +\definespecial\doendofprofile% + {} + +\fi + +%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. + +\definespecial\doinsertbookmark{\doPDFinsertbookmark} + +%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 + +\ifnum\pdftexversion>13 + + \definespecial\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}} + + \definespecial\dostopobject + {\dodostopobject + \egroup} + + \definespecial\doresetobjects + {\global\let\PDFimagereference\empty} + + \definespecial\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} + +\else + + \definespecial\dostartobject#1#2#3#4#5% + {\bgroup + \setbox\nextbox\vbox\bgroup + \def\dodostopobject + {\egroup + \the\everyPDFxform + \pdfform\nextbox + \dosetobjectreference{#1}{#2}{\the\pdflastform}}} + + \definespecial\dostopobject + {\dodostopobject + \egroup} + + \definespecial\doinsertobject#1#2% + {\bgroup + \dogetobjectreference{#1}{#2}\PDFobjectreference + \pdfrefform\PDFobjectreference + \egroup} + +\fi + +\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. + +\definespecial\dosetpagetransition{\doPDFsetpagetransition} + +%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: + +\definespecial\doinsertcomment{\doPDFinsertcomment} +\definespecial\doflushcomments{\doPDFflushcomments} + +%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. + +\definespecial\dopresetlinefield {\doFDFpresetlinefield} +\definespecial\dopresettextfield {\doFDFpresettextfield} +\definespecial\dopresetchoicefield{\doFDFpresetchoicefield} +\definespecial\dopresetpopupfield {\doFDFpresetpopupfield} +\definespecial\dopresetcombofield {\doFDFpresetcombofield} +\definespecial\dopresetpushfield {\doFDFpresetpushfield} +\definespecial\dopresetcheckfield {\doFDFpresetcheckfield} +\definespecial\dopresetradiofield {\doFDFpresetradiofield} +\definespecial\dopresetradiorecord{\doFDFpresetradiorecord} + +%D \macros +%D {dodefinefieldset,dogetfieldset,doiffieldset} +%D +%D Field sets, needed for reset and submit handling, are +%D taken care of by: + +\definespecial\dodefinefieldset{\doFDFdefinefieldset} +\definespecial\dogetfieldset {\doFDFgetfieldset} +\definespecial\doiffieldset {\doFDFiffieldset} + +%D \macros +%D {doregistercalculationset} +%D +%D The calculation order is defined using: + +\definespecial\doregistercalculationset{\doFDFregistercalculationset} + +%D \macros +%D {doPDFdestination} +%D +%D Finally we implement some low level macros to deal with +%D flushing \PDF\ code. First we handle the named destinations. + +\def\doPDFdestination#1% + {\pdfdest name {#1}\PDFpageviewkey} + +%D \macros +%D {doPDFaction,doPDFannotation,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 + +% hm, due to some stupid optimization this feature has been +% disabled for some time, watch out \lastPDFaction is to be +% persistent + +\ifnum\pdftexversion>13 + + \def\doPDFaction#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} + +\else + + \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 + \pdfannotlink % could be \pdfannot if not the - problem was there + width #1 height #2 depth \zeropoint + user {/Subtype /Link + /Border [0 0 0] + \ifhighlighthyperlinks \else /H /N \fi + /A \lastPDFaction}% + \pdfendlink + \fi} + +\fi + +% pdftex and viewers give problems with this one (printing forms) +% +%\def\doPDFannotation#1#2#3% +% {\pdfannot width #1sp height -#2sp depth \zeropoint{#3}} +% +% This is corrected in version 14. When this version is wide +% spread, this will be cleaned up. + +\ifnum\pdftexversion>13 + + \def\doPDFannotation#1#2#3% + {\pdfannot width #1 height #2 depth \zeropoint{#3}} + +\else + + \def\doPDFannotation#1#2#3% + {\hbox{\raise#2\hbox{\pdfannot width #1 height #2 depth \zeropoint{#3}}}} + +\fi + +%D \macros +%D {doPDFannotationobject,doPDFactionobject} +%D +%D For field support we need annotation objects. Although in +%D many cases we can do without indirect references (and use +%D the last annotation object number directly), we take the +%D save route. + +\def\doPDFannotationobject#1#2#3#4#5% + {\doPDFannotation{#3}{#4}{#5}% + \dosetobjectreference{#1}{#2}{\the\pdflastannot}} + +\def\doPDFactionobject#1#2#3#4#5% + {\doPDFaction{#3}{#4}{#5}% + \dosetobjectreference{#1}{#2}{\the\pdflastannot}} + +%D \macros +%D {doPDFaddtocatalog,doPDFaddtoinfo, +%D doPDFpageattribute,doPDFpagesattribute} +%D +%D Next some simple ones. Watch the global directive and the +%D expansion in the page attribute macro. + +\def\doPDFaddtocatalog + {\pdfcatalog} + +\def\doPDFaddtoinfo + {\pdfinfo} + +\def\doPDFpageattribute#1% + {\expanded{\global\pdfpageattr{#1\the\pdfpageattr}}} + +\def\doPDFpageresource#1% + {\expanded{\global\pdfpageresources{#1\the\pdfpageresources}}} + +\def\doPDFpagesattribute#1% + {\expanded{\global\pdfpagesattr{#1\the\pdfpagesattr}}} + +\def\doPDFresetpageattributes + {\global\pdfpageattr\emptytoks} + +\def\doPDFresetpageresources + {\global\pdfpageresources\emptytoks} + +%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% + {\doPDFgetpagereference{#4}\PDFobjectreference + \pdfoutline + user {<>}% + \ifcase#2 \else count \ifcase#5-\fi#2 \fi + {\ifPDFunicode<#3>\else#3\fi}} + +%D \macros +%D {doPDFdictionaryobject,doPDFarrayobject} +%D +%D Where \PDFTEX\ has only one object primitive, optionally a +%D stream one, \ACROBAT\ has several operators. + +\def\doPDFdictionaryobject#1#2#3% + {\flushatshipout + {\immediate\pdfobj{<< #3 >>}% + \dosetobjectreference{#1}{#2}{\the\pdflastobj}}} + +\def\doPDFarrayobject#1#2#3% + {\flushatshipout + {\immediate\pdfobj{[ #3 ]}% + \dosetobjectreference{#1}{#2}{\the\pdflastobj}}} + +% tricky .. too many xforms now +% +% \def\doreservePDFobject#1#2% +% {\pdfobj reserveobjnum{}% +% \driverreferenced\dosetobjectreference{#1}{#2}{\the\pdflastobj}} +% +% \def\doPDFreserveddictionaryobject#1#2#3% +% {\doPDFgetobjectnumber{#1}{#2}\PDFobjectnumber +% \immediate\pdfobj useobjnum \PDFobjectnumber {<< #3 >>}} +% +% \def\doPDFreservedarrayobject#1#2#3% +% {\doPDFgetobjectnumber{#1}{#2}\PDFobjectnumber +% \immediate\pdfobj useobjnum \PDFobjectnumber {[ #3 ]}} + +% \doreservePDFobject{FDF}{docuextgstates} +% \doreservePDFobject{FDF}{colorspaces} +% \doreservePDFobject{FDF}{docushades} + +%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{..} +% \def\doPDFgetobjectpagereference#1#2#3{..} + +\ifx\pdfpageref\undefined + + \def\doPDFgetpagereference % number macro + {\installprogram{texutil --filter \jobname}% + \gdef\doPDFgetpagereference##1{\doPDFgetobjectreference{PDFP}{\number##1}}% {##2} + \doPDFgetpagereference} + +\else + + \def\doPDFgetpagereference#1#2% number macro + {\edef#2{\ifnum#1>\zerocount\PDFobjref{\pdfpageref#1}\else null\fi}} + +\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. + +%D Todo: move code to fdf module + +\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}% + \doPDFdictionaryobject{#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}} + +% %D We can set \METAPOST\ prologues to~1: + +\def\MPprologues{1} + +%D Experimental: + +\definespecial\dostartfonteffect{\doPDFstartfonteffect} +\definespecial\dostopfonteffect {\doPDFstopfonteffect} + +%D Some MP stuff: + +\let\handleMPfshow\dohandleMPfshow % default anyway + +\ifnum\pdftexversion<14 + + \def\setMPPDFobject#1#2% resources boxnumber + {\def\getMPPDFobject{\box#2}} + +\else + + \def\setMPPDFobject#1#2% resources boxnumber + {\the\everyPDFxform + \finalizeobjectbox{#2}% + \immediate\pdfxform resources{#1}#2% + \edef\getMPPDFobject{\noexpand\pdfrefxform\the\pdflastxform}} + +\fi + +\let\getMPPDFobject\relax + +\definespecial\doinsertMPfile#1% + {\doiffileelse{./#1}{\includeMPasPDF{./#1}}{\message{[MP #1]}}} + +%D Now we can finish this module. + +\stopspecials + +\protect \endinput diff --git a/tex/context/base/spec-tr.mkii b/tex/context/base/spec-tr.mkii new file mode 100644 index 000000000..c1f997bca --- /dev/null +++ b/tex/context/base/spec-tr.mkii @@ -0,0 +1,107 @@ +%D \module +%D [ file=spec-tr, +%D version=1996.01.25, +%D title=\CONTEXT\ Special Macros, +%D subtitle=Thomas Rokicki's \DVIPS, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 Especially the rotation proved to be incompatible with +%D the default \POSTSCRIPT\ special driver. Many thanks to +%D Gilbert van den Dobbelsteen for testing and hacking the +%D \DVIPS\ source and pinpointing the problem. + +%D \macros +%D {doinsertfile} +%D +%D We overrule the figure||insertion special. Things should +%D be more accurate, but maybe someday \unknown + +\startspecials[rokicki] + +\def\@@insertpostscriptliteral {ps: } +\def\@@insertpostscriptretain {" } + +%D Ugly but useful: + +\definefileinsertion{tr}{eps} + {\bgroup + \PointsToWholeBigPoints\@@DriverImageWidth \width + \PointsToWholeBigPoints\@@DriverImageHeight\height + \special + {PSfile="\@@DriverImageFile"\space + llx=\EPSllx\space + lly=\EPSlly\space + urx=\EPSurx\space + ury=\EPSury\space + \ifdim\@@DriverImageWidth >\zeropoint rwi=\width 0\space\fi + \ifdim\@@DriverImageHeight>\zeropoint rhi=\height0 \fi}% + \egroup} + +\definefileinsertion{tr}{mps} + {\hbox + {\convertMPcolors\@@DriverImageFile + \dofileinsertion{tr}{eps}}} + +\definespecial\doinsertfile + {\dofileinsertion{tr}\@@DriverImageType} + +%D Some MP stuff: + +\definespecial\doinsertMPfile#1% + {\doiffileelse{./#1}{\includeMPasEPS{./#1}}{\message{[MP #1]}}} + +%D \macros +%D {dostartrotation} +%D +%D Because \DVIPS\ uses a reverse rotation scheme, we have +%D to add an extra \type{neg} to the default \POSTSCRIPT\ +%D rotation definition: + +\definespecial\dostartrotation#1% straight from the YandY manual / 1st neg added + {\special + {\@@insertpostscriptliteral + gsave currentpoint currentpoint translate + \number#1\space\space neg rotate neg exch neg exch translate}} + +\definespecial\dostoprotation + {\special + {\@@insertpostscriptliteral + currentfont currentpoint grestore moveto setfont}} + +%D Drawing ovals in \DVIPS\ is complicated by the fact that +%D the colors get reset. Therefore we need a more literal +%D approach and therefore scale to local units. By redefining +%D the retain constant into a macro, we can use the already +%D present \POSTSCRIPT\ definition (see \type{spec-ps}). + +\definespecial\doovalbox#1#2#3#4#5#6#7#8% variant not yet supported + {\bgroup + \edef\@@insertpostscriptretain gsave% + {\@@insertpostscriptliteral + gsave + Resolution 72 div + VResolution 72 div neg scale currentpoint translate}% + \dosomeovalbox{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}% + \egroup} + +%D \macros +%D {dosetuppaper} +%D +%D Relatively new: + +\definespecial\dosetuppaper#1#2#3% + {\begingroup + \!!dimena#2% + \!!dimenb#3% + \special{papersize=\the\!!dimena,\the\!!dimenb}% + \endgroup} + +\stopspecials + +\endinput diff --git a/tex/context/base/spec-tst.mkii b/tex/context/base/spec-tst.mkii new file mode 100644 index 000000000..543baa647 --- /dev/null +++ b/tex/context/base/spec-tst.mkii @@ -0,0 +1,52 @@ +%D \module +%D [ file=spec-tst, +%D version=2002.12.08, +%D title=\CONTEXT\ \PDF\ Macros, +%D subtitle=Special Test Macro, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\unprotect + +%D The code is now merged into spec-*.mkii + +\protect + +\doifnotmode{demo}{\endinput} + +\mainlanguage[vn] +\enableregime[utf] +\usetypescript[all][computer-modern][t5] + +\setupinteraction + [state=start, + title={Thử tiếng Việt}, + author={Tác Văn Giả}, + keyword={Thử tiếng Việt}] + +\placebookmarks[chapter,section,subsection] + +\starttext + +\placelist[chapter,section,subsection][alternative=c] + +\chapter{Thử tiếng Việt} + +\section {Mục thứ nhất} +\subsection{Mục nhỏ thứ nhất} Thử tiếng Việt +\subsection{Mục nhỏ thứ hai} Thử tiếng Việt + +\section {Mục thứ hai} +\subsection{Mục nhỏ thứ nhất} Thử tiếng Việt +\subsection{Mục nhỏ thứ hai} Thử tiếng Việt + +\section {Mục thứ ba} +\subsection{Mục nhỏ thứ nhất} Thử tiếng Việt +\subsection{Mục nhỏ thứ hai} Thử tiếng Việt + +\stoptext diff --git a/tex/context/base/spec-var.mkii b/tex/context/base/spec-var.mkii new file mode 100644 index 000000000..8d561dc6f --- /dev/null +++ b/tex/context/base/spec-var.mkii @@ -0,0 +1,83 @@ +%D \module +%D [ file=spec-var, +%D version=2003.10.10, +%D title=\CONTEXT\ Special 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. + +%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} + +% new approach, 'global' variables, since we run out of +% arguments + +\unprotect + +% This variable holds a comma separated list of (supported) figure +% types. It may be changes by other modules. + +\let\figuretypes\empty + +\ifx\undefined\@@DriverFieldName + + \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 + +\fi + +\ifx\undefined\@@DriverCommentLayer + + \letempty \@@DriverCommentLayer + +\fi + +\ifx\undefined\@@DriverAttachmentLayer + + \letempty \@@DriverAttachmentLayer + +\fi + +\ifx\undefined\@@DriverImageBox + + \letempty \@@DriverImageBox + \letempty \@@DriverImageOptions + \letempty \@@DriverImageWidth + \letempty \@@DriverImageHeight + \letempty \@@DriverImageFile + \letempty \@@DriverImageLabel + \letempty \@@DriverImageType + \letempty \@@DriverImageMethod + \letempty \@@DriverImagePage + +\fi + +\protect \endinput diff --git a/tex/context/base/spec-win.mkii b/tex/context/base/spec-win.mkii new file mode 100644 index 000000000..73db8830e --- /dev/null +++ b/tex/context/base/spec-win.mkii @@ -0,0 +1,99 @@ +%D \module +%D [ file=spec-win, +%D version=1996.01.25, +%D title=\CONTEXT\ Special Macros, +%D subtitle=\YandY's \DVIWINDO, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 Remark: chained references are not yet implemented. + +%D \macros +%D {dosetupinteraction, +%D dostartthisislocation, +%D dostartthisisrealpage, +%D dostartgotolocation, +%D dostartgotorealpage, +%D dostartrunprogram, +%D usepagedestinations} +%D {} +%D +%D As told before, these were the first interactive specials. +%D In those days, these kind of specials were still elegant +%D and straightforward. + +\startspecials[dviwindo] + +\definespecial\dosetupinteraction% + {\showmessage\m!interactions{21}{dviwindo}} + +\definespecial\dostartgotolocation#1#2#3#4#5#6% + {\bgroup + \doifelsenothing{#3} + {\doifelsenothing{#4} + {\!!doneafalse} + {\doifparentfileelse{#4} + {\!!doneafalse} + {\!!doneatrue}}% + \setreferencefilename#4\to\DVIfile + \scratchdimen#1\edef\width {\the\scratchdimen\space}% + \scratchdimen#2\edef\height{\the\scratchdimen\space}% + \special + {button: + \width \height + \if!!donea + file: \DVIfile, + \fi + "#5"}} + {}% nog uri afhandelen + \egroup} + +\definespecial\dostartgotorealpage#1#2#3#4#5% + {\bgroup + \doifelsenothing{#3} + {\doifelsenothing{#4} + {\!!doneafalse} + {\doifparentfileelse{#4} + {\!!doneafalse} + {\!!doneatrue}}% + \setreferencefilename#4\to\DVIfile + \scratchdimen#1\edef\width {\the\scratchdimen\space}% + \scratchdimen#2\edef\height{\the\scratchdimen\space}% + \special + {button: + \width \height + \if!!donea + file: \DVIfile, + \fi + \ifnum0#5=0 \else + page: #5 + \fi}} + {}% nog uri afhandelen + \egroup} + +\definespecial\dostartthisislocation#1% + {\special{mark: "#1"}} + +\definespecial\dostartthisisrealpage#1% + {} + +\definespecial\dostartrunprogram#1#2#3#4% + {\bgroup + \scratchdimen#1\edef\width {\the\scratchdimen\space}% + \scratchdimen#2\edef\height{\the\scratchdimen\space}% + \special{button: \width \height launch: #3 #4}% + \egroup} + +\let\doyandyinsertmov = \docommoninsertmov +\let\dotrinsertmov = \docommoninsertmov + +\stopspecials + +\protect \endinput diff --git a/tex/context/base/spec-xet.mkii b/tex/context/base/spec-xet.mkii new file mode 100644 index 000000000..0cbd55ba7 --- /dev/null +++ b/tex/context/base/spec-xet.mkii @@ -0,0 +1,66 @@ +%D \module +%D [ file=spec-xtx, +%D version=2004.11.08, +%D title=\CONTEXT\ Special Macros, +%D subtitle=\XETEX\ support, +%D author={Adam Lindsay \& Hans Hagen \& \unknown}, +%D date=\currentdate, +%D copyright={Adam Lindsay \& Hans Hagen}] + +\unprotect + +\definespecial\doinsertfile + {\dofileinsertion{xtx}\@@DriverImageType} + +\definefileinsertion{xtx}{jpg}{\xtxhandleotherimage} +\definefileinsertion{xtx}{png}{\xtxhandleotherimage} +\definefileinsertion{xtx}{gif}{\xtxhandleotherimage} +\definefileinsertion{xtx}{tif}{\xtxhandleotherimage} +\definefileinsertion{xtx}{pdf}{\xtxhandlepdfimage } + +\def\checkpdfimagepagenumber + {\edef\pdfimagepagenumber + {\ifx\@@DriverImagePage\empty\else\ifnum\@@DriverImagePage>\zerocount + \space page\space\@@DriverImagePage\space + \fi\fi}} + +\def\xtxhandleotherimage + {\XeTeXpicfile "\@@DriverImageFile" + \ifdim\@@DriverImageWidth >\zeropoint \!!width \@@DriverImageWidth \space\fi + \ifdim\@@DriverImageHeight>\zeropoint \!!height \@@DriverImageHeight \fi + \relax} + +\def\xtxhandlepdfimage + {\checkpdfimagepagenumber + \XeTeXpdffile "\@@DriverImageFile" + \pdfimagepagenumber + \ifdim\@@DriverImageWidth >\zeropoint \!!width \@@DriverImageWidth \space\fi + \ifdim\@@DriverImageHeight>\zeropoint \!!height \@@DriverImageHeight \fi + \relax} + +\def\dogetXTXfiguresize + {\setbox\foundexternalfigure\vbox{\XeTeXpicfile "\@@DriverImageFile"\relax}% + \xdef\analyzedfigurewidth {\the\wd\foundexternalfigure}% + \xdef\analyzedfigureheight{\the\ht\foundexternalfigure}} + +\def\dogetXTXpdfsize + {\checkpdfimagepagenumber + \setbox\foundexternalfigure\vbox{\XeTeXpdffile "\@@DriverImageFile" \pdfimagepagenumber\relax}% + \xdef\analyzedfigurewidth {\the\wd\foundexternalfigure}% + \xdef\analyzedfigureheight{\the\ht\foundexternalfigure}} + +\definefilechecker{xtx}{png}{\dogetXTXfiguresize} +\definefilechecker{xtx}{jpg}{\dogetXTXfiguresize} +\definefilechecker{xtx}{gif}{\dogetXTXfiguresize} +\definefilechecker{xtx}{tif}{\dogetXTXfiguresize} +\definefilechecker{xtx}{pdf}{\dogetXTXpdfsize } + +\definespecial\dogetfiguresize + {\dofilechecker{xtx}\@@DriverImageType} + +%D The figure object system caused no end of headaches. They all +%D went away with this single line: + +\setupexternalfigures[\c!object=\v!no] + +\protect \endinput diff --git a/tex/context/base/spec-xtx.mkii b/tex/context/base/spec-xtx.mkii new file mode 100644 index 000000000..799c6ca8d --- /dev/null +++ b/tex/context/base/spec-xtx.mkii @@ -0,0 +1,87 @@ +%D \module +%D [ file=spec-xtx, +%D version=2004.11.08, +%D title=\CONTEXT\ Special Macros, +%D subtitle=\XETEX\ support, +%D author={Adam Lindsay \& Hans Hagen \& \unknown}, +%D date=\currentdate, +%D copyright={Adam Lindsay \& Hans Hagen}] + +\unprotect + +\startspecials[xetex][reset,dpx] + +%D Actually, there's an intermediate ``\type{xdv}'' +%D output format, but by default, it's tranparently +%D converted to \PDF\ by \XETEX. + +\setjobsuffix{pdf} + +%D Rotation looks fine. + +\definespecial\dostartrotation#1% + {\special{x:gsave}\special{x:rotate #1}} + +\definespecial\dostoprotation + {\special{x:grestore}} + +%D Scaling and mirroring are also fine. + +\definespecial\dostartscaling#1#2% + {\special{x:gsave}\special{x:scale #1 #2}} + +\definespecial\dostopscaling + {\special{x:grestore}} + +\definespecial\dostartmirroring + {\special{x:gsave}\special{x:scale -1 1}} + +\definespecial\dostopmirroring + {\special{x:grestore}} + +%D Colors are done with the \DVIPDFMX\ color model, which are +%D inherited. + +%D Although hex colors were accommodated by Hans, we'll try the +%D more familiar \DVIPDFMX\ ones. One good side-effect of the +%D previous approach was that it kept track of the color state +%D (transparency in XeTeX is accomplished setting the color to +%D an RGBA quadruple, rather than an RGB triple). So transparency +%D will need another plan. + +% \macros +% {dostarttransparency,dostoptransparency} +% +% \starttypen +% \dostarttransparency{fraction}{type} +% \dostoptransparency +% \stoptypen +% +% Although in \CONTEXT\ transparency is closely integrated +% in the color drivers, in the end it is an independent +% feature. + +%\installspecial [\dostarttransparency] [or] [2] +%\installspecial [\dostoptransparency] [or] [0] + +%D \macros +%D {doloadmapfile,doloadmapline,doresetmapfilelist} +%D +%D \XETEX\ 0.91 allows map file additions, via a special. + +\definespecial\doresetmapfilelist{\special{x:fontmapfile original-empty.map}} +\definespecial\doloadmapfile #1#2{\special{x:fontmapfile #1#2}} +\definespecial\doloadmapline #1#2{\special{x:fontmapline #1#2}} + +%D \macros +%D {dosetuppaper} + +\ifx\pdfpagewidth\undefined \else + \definespecial\dosetuppaper#1#2#3% + {\global\pdfpagewidth #2\relax + \global\pdfpageheight#3\relax} +\fi + +\stopspecials + +\protect \endinput diff --git a/tex/context/base/spec-yy.mkii b/tex/context/base/spec-yy.mkii new file mode 100644 index 000000000..beec95493 --- /dev/null +++ b/tex/context/base/spec-yy.mkii @@ -0,0 +1,90 @@ +%D \module +%D [ file=spec-yy, +%D version=1996.01.25, +%D title=\CONTEXT\ Special Macros, +%D subtitle=\YandY's \DVIPSONE\ and \DVIWINDO, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 {dostartgraymode,dostopgraymode, +%D dostartrgbcolormode,dostartcmykcolormode,dostartgraycolormode,dostopcolormode, +%D doinsertfile} +%D +%D We implement a nice and simple figure||insertion special +%D and make use of \YandY's color specials. Otherwise \DVIWINDO\ +%D would not show colors. + +\startspecials[yandy] + +\def\@@insertpostscriptliteral {ps: } +\def\@@insertpostscriptretain {" } % this was: {postscript} + +\definespecial\dostartgraymode#1% + {\special{color gray #1}} + +\definespecial\dostopgraymode% + {\special{color gray 0}} + +\definespecial\dostartrgbcolormode#1#2#3% + {\special{color rgb #1 #2 #3}} + +\definespecial\dostartcmykcolormode#1#2#3#4% + {\special{color cmyk #1 #2 #3 #4}} + +\definespecial\dostartgraycolormode#1% + {\special{color gray #1}} + +\definespecial\dostopcolormode% + {\special{color gray 0}} + +% \definefileinsertion{yy}{eps}% +% {\PointsToBigPoints\@@DriverImageWidth \width +% \PointsToBigPoints\@@DriverImageHeight\height +% \special +% {psfile=\@@DriverImageFile\space +% %hscale=100\space +% %vscale=100\space +% hoffset=\width\space +% voffset=\height}} + +\definefileinsertion{tr}{eps} + {\bgroup + \PointsToWholeBigPoints\@@DriverImageWidth \width + \PointsToWholeBigPoints\@@DriverImageHeight\height + \special + {PSfile="\@@DriverImageFile"\space + llx=\EPSllx\space + lly=\EPSlly\space + urx=\EPSurx\space + ury=\EPSury\space + \ifdim\@@DriverImageWidth >\zeropoint rwi=\width 0\space\fi + \ifdim\@@DriverImageHeight>\zeropoint rhi=\height0 \fi}% + \egroup} + +\definefileinsertion{yy}{mps} + {\hbox + {\includeMPfonts \@@DriverImageFile + \convertMPcolors\@@DriverImageFile + \dofileinsertion{yy}{eps}}} + +\definefileinsertion{yy}{tif} + {\special{insertimage: + \@@DriverImageFile \space + \@@DriverImageWidth\space + \@@DriverImageHeight}} + +\definespecial\doinsertfile + {\dofileinsertion{yy}\@@DriverImageType} + +\def\MPprologues{1} +\def\MPOSTdriver{dvipsone} + +\stopspecials + +\endinput diff --git a/tex/context/base/strc-bkm.lua b/tex/context/base/strc-bkm.lua new file mode 100644 index 000000000..f34d83ec5 --- /dev/null +++ b/tex/context/base/strc-bkm.lua @@ -0,0 +1,131 @@ +if not modules then modules = { } end modules ['strc-bkm'] = { + version = 0.200, + comment = "companion to strc-bkm.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- Future version will support adding arbitrary bookmarks with +-- associated complex actions (rather trivial to implement). + +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 +local levelmap = structure.sections.levelmap + +structure.bookmarks = structure.bookmarks or { } + +local bookmarks = structure.bookmarks + +bookmarks.method = "internal" -- or "page" + +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.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 + +local function stripped(str) -- kind of generic + str = gsub(str,"\\([A-Z]+)","%1") -- \LOGO + str = gsub(str,"\\ "," ") -- \ + str = gsub(str,"\\([A-Za-z]+) *{(.-)}","%1") -- \bla{...} + str = gsub(str," +"," ") -- spaces + return str +end + +-- todo: collect specs and collect later i.e. multiple places + +function bookmarks.place() + if names ~= "" then + local list = lists.filter(names,"all",nil,lists.collected) + local lastlevel = 1 + if #list > 0 then + local opened, levels = aux.settings_to_set(opened), { } + for i=1,#list do + local li = list[i] + local metadata = li.metadata + local name = metadata.name + if not metadata.nolist then -- and levelmap[name] then + local titledata = li.titledata + if titledata then + local structural = levelmap[name] + lastlevel = structural or lastlevel + local title = titledata.bookmark + if not title or title == "" then + if not structural then + -- placeholder, todo: bookmarklabel + title = name .. ": " .. (titledata.title or "?") + else + title = titledata.title or "?" + end + end + levels[#levels+1] = { + lastlevel, + stripped(title), + li.references, -- has internal and realpage + allopen or opened[name] + } + end + end + end + backends.codeinjections.addbookmarks(levels,bookmarks.method) + end + function bookmarks.place() end -- prevent second run + end +end + +lpdf.registerdocumentfinalizer(function() structure.bookmarks.place() end,1) + +-- bkm +--~ function nodes.toutf(list) +--~ local t= { } +--~ for n in node.traverse(list) do +--~ local id = n.id +--~ if id == node.id("glyph") then +--~ local c = n.char +--~ local f = fonts.ids[n.font] +--~ if f then +--~ local u = f.characters[c].tounicode +--~ if u then +--~ for s in string.gmatch(u,"..") do +--~ t[#t+1] = utf.char(tonumber(s,16)) +--~ end +--~ else +--~ t[#t+1] = utf.char(c) +--~ end +--~ else +--~ t[#t+1] = utf.char(c) +--~ end +--~ elseif id == node.id("glue") then +--~ t[#t+1] = " " +--~ end +--~ end +--~ return table.concat(t,"") +--~ end +--~ print(nodes.toutf(tex.box[999].list)) diff --git a/tex/context/base/strc-bkm.mkiv b/tex/context/base/strc-bkm.mkiv new file mode 100644 index 000000000..77854738d --- /dev/null +++ b/tex/context/base/strc-bkm.mkiv @@ -0,0 +1,93 @@ +%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. + +%D This might become scrn-bkm.mkiv. + +\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: + +\unexpanded\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} + +% \prependtoks\ctxlua{structure.bookmarks.place()}\to\everystoptext % too late +% \prependtoks\ctxlua{structure.bookmarks.place()}\to\everylastbackendshipout % okay but not nice + +\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..2589190eb --- /dev/null +++ b/tex/context/base/strc-blk.lua @@ -0,0 +1,146 @@ +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, find = tex.print, string.format, string.gmatch, string.find +local lpegmatch = lpeg.match + +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.patterns.textline/texprint)^0 -- can be shared + +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 + lpegmatch(printer,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 next, 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 find(tag,"=") 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 next, 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 next, 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.mkii b/tex/context/base/strc-blk.mkii new file mode 100644 index 000000000..c4e38a607 --- /dev/null +++ b/tex/context/base/strc-blk.mkii @@ -0,0 +1,548 @@ +%D \module +%D [ file=strc-blk, % split off core-buf.tex +%D version=2000.01.05, +%D title=\CONTEXT\ Structure 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. + +% investigate etex's \readline and \scantokens + +\writestatus{loading}{ConTeXt Structure Macros / Blockmoves} + +\unprotect + +\def\blockversion {1996.03.10} + +\def\@@blockerrormessage + {\showmessage\m!textblocks1\empty + \global\let\@@blockerrormessage\relax} + +\def\thisisblockversion#1% + {\doifnot\blockversion{#1}{\@@blockerrormessage\endinput}} + +\def\stopcopyingblocks + {\ifcopyingblocks + \immediate\closeout\outblocks + \copyblockfile + \global\copyingblocksfalse + \fi} + +\def\dodosetblockcounters[#1]#2% + {\expanded{\setvalue{\??se\s!old#2}{\@@filterheadpart[#1]}}% + \doifnot{#2}\lastsection + {\expanded{\dodosetblockcounters[\@@filtertailpart[#1]]}% + {\getvalue{\??se#2\c!after}}}} % ???? + +\def\dosetblockcounters[#1]% + {\ifblockpermitted + \expanded{\dodosetblockcounters[\@@filtersecondpart[#1]]}\firstsection + \expanded{\setsectiontype[\@@filterfirstpart[#1]]}% + \def\@@sectionvalue##1{\getvalue{\??se\s!old##1}}% + \let\@@sectionconversion\secondoftwoarguments + \fi} + +\let\blockstatus\empty + +\def\setblockcounters + {\ifx\blockstatus\empty \else + \@EA\dosetblockcounters\@EA[\blockstatus]% + \fi} + +\def\getblockstatus#1% + {\dosetfilterlevel{\@@bscriterium}\empty + \expanded{\doifblklevelelse[#1\sectionseparator\sectionseparator0]} + {\global\blockpermittedtrue} + {\global\blockpermittedfalse}% + \def\blockstatus{#1}} + +\def\setupblockparameters + {\dodoubleargument\dosetupblockparameters} + +\def\dosetupblockparameters[#1][#2]% + {\getparameters[\??tb#1][#2]} + +\def\blockparameter#1#2% + {\@EA\csname\ifcsname\??tb#1#2\endcsname\??tb#1#2\else\s!empty\fi\endcsname} + +\ifx\outblocks\undefined \newwrite\outblocks \fi +\ifx\inpblocks\undefined \newread \inpblocks \fi +\ifx\tmpblocks\undefined \newwrite\tmpblocks \fi +\ifx\blockbox \undefined \newbox \blockbox \fi + +\newif\ifcopyingblocks +\newif\ifblockpermitted +\newif\iftmpblockstarted +\newif\ifoldinbijlagen +\newif\ifdoingblocks + +\newcount\blocklevel + +\def\setblocklevel#1% sign + {\global\advance\blocklevel #11 + \ifcase\blocklevel\doingblocksfalse\else\doingblockstrue\fi} + +\def\opentmpblock + {\immediate\openout\tmpblocks\TEXbufferfile{\f!utilityfilename\the\blocklevel}} + +\def\closetmpblock + {\immediate\write\tmpblocks{}% een lege regel is handig voor \par commando's + \immediate\closeout\tmpblocks} + +\def\writetmpblock#1% + {\iftmpblockstarted + \immediate\write\tmpblocks{#1}% + \else + \doifsomething{#1} + {\tmpblockstartedtrue + \immediate\write\tmpblocks{\string#1}}% + \fi} + +\def\startcopyingblocks + {\global\copyingblocksfalse} + +\def\checkcopyingblocks + {\ifcopyingblocks + \else + \immediate\openout\outblocks\f!utilityfilename.\f!blockextension% + \immediate\write\outblocks{\string\thisisblockversion{\blockversion}}% + \immediate\write\outblocks{\string\thisissectionseparator{\sectionseparator}}% + \global\copyingblockstrue + \fi} + +\def\stopcopyingblocks + {\ifcopyingblocks + \immediate\closeout\outblocks + \copyblockfile + \global\copyingblocksfalse + \fi} + +\def\nomoreblocks + {\stopcopyingblocks} + +\def\copyblockfile + {\ifcopyingblocks + \begingroup + \showmessage\m!textblocks2{\jobname.\f!blockextension}% + \openlocin\inpblocks{\f!utilityfilename.\f!blockextension}% + \immediate\openout\outblocks\jobname.\f!blockextension + \setupcopyblock + \catcode`\^^M=\@@ignore\relax + \def\copynextline + {\read\inpblocks to \!!stringa + \immediate\write\outblocks{\!!stringa}% + \ifeof\inpblocks\else\expandafter\copynextline\fi}% + \copynextline + \immediate\closein\inpblocks + \immediate\closeout\outblocks + \immediate\openout\tmpblocks\f!utilityfilename.\f!blockextension + \immediate\closeout\tmpblocks + \endgroup + \fi} + +\def\loadallblocks#1% + {\beginrestorecatcodes + \catcode`\^^M=\@@endofline\relax + \readjobfile{#1.\f!blockextension} + {\showmessage\m!textblocks3{#1.\f!blockextension}} + {\showmessage\m!textblocks4\empty}% + \endrestorecatcodes} + +\def\setupcopyblock + {\setcatcodetable\vrbcatcodes + \obeylines} + +\def\writeoutblocks + {\immediate\write\outblocks} + +\long\def\processnextblocklineAB#1% #2#3% + {\defconvertedargument\next{#1 }% + \doifinstringelse\endofblockA\next + \firstoftwoarguments + {\doifinstringelse\endofblockB\next + \firstoftwoarguments\secondoftwoarguments}} + +\bgroup +\obeylines +\long\gdef\copyblocklineAB#1 + {\processnextblocklineAB{#1}\closeblock{\writeoutblocks{#1}\writetmpblock{#1}\copyblocklineAB}} +\long\gdef\skipblocklineAB#1 + {\processnextblocklineAB{#1}\closeblock\skipblocklineAB} +\egroup + +\long\def\processnextblockline#1% #2#3% + {\defconvertedargument\next{#1 }% + \ifx\next\emptybufferline + \expandafter\secondoftwoarguments% #3% + \else + \emptybufferlinefalse + \doifinstringelse\endofblock\next + {\expandafter\firstoftwoarguments }% #2} + {\expandafter\secondoftwoarguments}% #3}% + \fi} + +\bgroup +\obeylines +\long\gdef\copyblockline#1 + {\processnextblockline{#1}\closeblock{\writeoutblocks{#1}\writetmpblock{#1}\copyblockline}} +\long\gdef\skipblockline#1 + {\processnextblockline{#1}\closeblock\skipblockline} +\egroup + +\def\skipblock#1% + {\checkcopyingblocks + \defconvertedcommand\endofblock{\string\thiswasblock{#1}}% command expands once ! + \let\openblock\begingroup + \let\closeblock\endgroup + \openblock + \setupcopyblock + \skipblockline} + +\let\doafterblock \gobbletwoarguments +\let\dobeforeblock\gobbletwoarguments + +\def\thisisblock#1% + {\executeifdefined{\s!thisisblock#1}{\skipblock{#1}}} + +\def\thiswasblock#1% + {\getvalue{\s!thiswasblock#1}} + +\def\saveblock#1#2% + {\checkcopyingblocks + \obeylines + \@EA\defconvertedcommand\@EA\endofblockA\@EA{\@EA\string\csname\e!end#1\endcsname}% + \defconvertedcommand\endofblockB{\string\endblock[#1]}% % MULTI LINGUAL MAKEN + \def\openblock + {\dobeforeblock{#1}{#2}% + \opentmpblock + \begingroup + \makesectionformat + \immediate\write\outblocks{}% + \immediate\write\outblocks{\string\thisisblock{#1}{\sectionformat}[#2]}}% + \def\closeblock + {\immediate\write\outblocks{}% handig voor \par commando's + \immediate\write\outblocks{\string\thiswasblock{#1}}% + \endgroup + \closetmpblock + \doafterblock{#1}{#2}% + \egroup}% + \openblock + \setupcopyblock + \copyblocklineAB} + +\def\copyblock + {\let\opentmpblock\empty + \let\closetmpblock\empty + \let\writetmpblock\gobbleoneargument + \saveblock} + +\def\loadoneblock + {\edef\blockfilename{\TEXbufferfile{\f!utilityfilename\the\blocklevel}}% + \setblocklevel+% + \readjobfile\blockfilename\donothing\donothing + \setblocklevel-}% + +\def\dodefineblock[#1]% + {\bypassblock[#1]% + \keepblocks[#1]% + \setupblock + [#1] + [\c!before=\blank, + \c!after=\blank, + \c!inner=, + \c!style=, + \c!file=\jobname]} + +% \def\defineblock +% {\dosingleargumentwithset\dodefineblock} + +\def\defineblock + {\dosingleargument\dodefineblock} + +\def\dosetupblock[#1][#2]% + {\getparameters[\??tb#1][#2]} + +\def\setupblock + {\dodoubleargumentwithset\dosetupblock} + +\def\bypassblock[#1]% + {\setvalue{\s!thisisblock#1}##1[##2]{\skipblock{#1}}} + +\def\dohideblock[#1][#2][#3]% + {\doifassignmentelse{#3} + {\dodohideblock[#1][#2][][#3]} + {\dodohideblock[#1][#2][#3][]}} + +\def\dodohideblock[#1][#2][#3][#4]% + {\doifelsenothing{#2} + {\global\blockpermittedfalse + \edef\blocktitle{#1}} + {\doifelsenothing{#3} + {\global\blockpermittedtrue + \edef\blocktitle{#1}} + {\doifcommonelse{#2}{#3} + {\global\blockpermittedfalse + \edef\blocktitle{#1:#2}} + {\global\blockpermittedtrue + \edef\blocktitle{#1:#3}}}}% + \ifblockpermitted + \showwarning\m!textblocks5\blocktitle + \def\next + {\def\dobeforeblock####1####2% + {\begingroup}% + \def\doafterblock####1####2% + {\endgroup + \doexecuteloadedblock{#1}{#4}}% + \saveblock{#1}{#3#4}}% + \else + \doifinsetelse{+}{#3} + {\showwarning\m!textblocks6\blocktitle + \def\next + {\def\dobeforeblock####1####2% + {\begingroup + \visiblefalse}% + \def\doafterblock####1####2% + {{\setbox0\vbox + {\catcode`\^^M=\@@endofline\relax + \loadoneblock + \par}}% + \endgroup}% + \saveblock{#1}{#3#4}}}% + {\showwarning\m!textblocks7\blocktitle + \def\next + {\def\dobeforeblock####1####2% + {\begingroup + \globaldefs\minusone}% + \def\doafterblock####1####2% + {\endgroup}% + \copyblock{#1}{#3#4}}}% + \fi + \next} + +\def\dohideblocks[#1][#2]% + {\def\docommand##1% + {\setvalue{\e!begin##1}% + {\bgroup\obeylines\dotripleempty\dohideblock[##1][#2]}}% + \processcommalist[#1]\docommand} + +\def\hideblocks + {\dodoubleempty\dohideblocks} + +\def\doexecuteloadedblock#1#2% + {\blockpermittedtrue % ? + \bgroup % before \c!before (think of: \c!before=\startitemize) + \dosetupblockparameters[#1][#2]% voor 'voor'? + \getvalue{\??tb#1\c!before}% + \dostartattributes{\??tb#1}\c!style\c!color\empty + \visibletrue + \catcode`\^^M=\@@endofline\relax + \getvalue{\??tb#1\c!inner}% + \ignorespaces + \loadoneblock + % \par moved + \dostopattributes + \getvalue{\??tb#1\c!after}% + \par + \egroup} + +\def\dokeepblock[#1][#2][#3]% + {\doifassignmentelse{#3} + {\dodokeepblock[#1][#2][][#3]} + {\dodokeepblock[#1][#2][#3][]}} + +\def\dodokeepblock[#1][#2][#3][#4]% + {\doifelsenothing{#2} + {\global\blockpermittedtrue + \edef\blocktitle{#1}} + {\doifcommonelse{#2}{#3} + {\global\blockpermittedtrue + \edef\blocktitle{#1:#2}} + {\doifinsetelse\v!all{#2} + {\doifelsenothing{#3} + {\global\blockpermittedtrue + \edef\blocktitle{#1}} + {\global\blockpermittedfalse + \edef\blocktitle{#1:#3}}} + {\global\blockpermittedfalse + \doifelsenothing{#3} + {\edef\blocktitle{#1}} + {\edef\blocktitle{#1:#3}}}}}% + \ifblockpermitted + \showwarning\m!textblocks8\blocktitle + \def\dobeforeblock##1##2% + {\begingroup}% + \def\doafterblock##1##2% + {\endgroup + \doexecuteloadedblock{#1}{#4}}% + \else + \showwarning\m!textblocks9\blocktitle + \fi + \saveblock{#1}{#3#4}} + +\def\dokeepblocks[#1][#2]% + {\def\docommand##1% + {\setvalue{\e!begin##1}% + {\bgroup\obeylines\dotripleempty\dokeepblock[##1][#2]}}% + \processcommalist[#1]\docommand} + +\def\keepblocks + {\dodoubleempty\dokeepblocks} + +\newconditional\processblockstatus +\newconditional\dummyblockstatus +\newconditional\blockassignmentstatus + +\def\dodouseblock#1#2#3#4% + {\getblockstatus{#2}% + \ifblockpermitted + \setfalse\dummyblockstatus + \doifassignmentelse{#3} + {\settrue \blockassignmentstatus} + {\setfalse\blockassignmentstatus}% + \doifelsenothing{#4} + {\edef\blocktitle{#1}} + {\ifconditional\blockassignmentstatus + \edef\blocktitle{#1}% + \else + \doifnotcommon{#3}{#4} + {\ifconditional\processblockstatus + \settrue\dummyblockstatus + \else + \global\blockpermittedfalse + \fi}% + \edef\blocktitle{#1:#3}% + \fi}% + \else + \edef\blocktitle{#1}% + \fi + \ifblockpermitted + \setblocklevel+% + \ifconditional\blockassignmentstatus \else + \doifinset{-}{#3}{\settrue\dummyblockstatus}% + \fi + \ifconditional\dummyblockstatus + \showwarning\m!textblocks{10}\blocktitle + \setvalue{\s!thiswasblock#1}% + {\removeunwantedspaces + \par + \egroup + \setblocklevel-}% + \def\next + {\setbox0\vbox\bgroup + \ifconditional\blockassignmentstatus + \dosetupblockparameters[#1][#3]% + \fi}% + \else + \showwarning\m!textblocks{11}\blocktitle + \setvalue{\s!thiswasblock#1}% + {\removeunwantedspaces + % \par moved + \dostopattributes + \getvalue{\??tb#1\c!after}% + \par + \egroup + \setblocklevel-}% + \def\next + {\bgroup + \ifconditional\blockassignmentstatus + \dosetupblockparameters[#1][#3]% + \fi + \getvalue{\??tb#1\c!before}% + \dostartattributes{\??tb#1}\c!style\c!color\empty + \visibletrue + \getvalue{\??tb#1\c!inner}% + \ignorespaces}% + \fi + \else + \def\next + {\showwarning\m!textblocks{12}\blocktitle + \skipblock{#1}}% + \fi + \next} + +\def\douseblock[#1][#2]% + {\setvalue{\s!thisisblock#1}##1[##2]{\dodouseblock{#1}{##1}{##2}{#2}}} + +\def\dodouseblocks[#1][#2]% + {\def\docommand##1% + {\douseblock[##1][#2]}% + \processcommalist[#1]\docommand + \dogetcommalistelement1\from#1\to\commalistelement + \doifdefined{\??tb\commalistelement\c!file} + {\loadallblocks{\getvalue{\??tb\commalistelement\c!file}}}% + \endgroup} + +\def\douseblocks + {\begingroup + \doassign[\??bs][\c!criterium=\v!all]% + \dodoubleempty\dodouseblocks} + +\def\useblocks + {\setfalse\processblockstatus\douseblocks} + +\def\processblocks + {\settrue \processblockstatus\douseblocks} + +\def\doselectblocks[#1][#2][#3]% + {\begingroup + \doifelsenothing{#3} + {\getparameters[\??bs][\c!criterium=\v!all,#2]% + \dodouseblocks[#1][]} + {\getparameters[\??bs][\c!criterium=\v!all,#3]% + \dodouseblocks[#1][#2]}}% + +\def\selectblocks + {\dotripleempty\doselectblocks} + +\def\beginblock[#1]% % we also check \endblock[..] + {\getvalue{\e!begin#1}} + +\def\forceblocks[#1]% + {\def\docommand##1% + {\setvalue{\e!begin##1}% + {\setblocklevel+\bgroup + \dodoubleempty\doforceblock[##1]}% + \setvalue{\e!end##1}% + {\dostopattributes + \getvalue{\??tb##1\c!after}% + \egroup\setblocklevel-}}% + \processcommalist[#1]\docommand} + +\def\doforceblock[#1][#2]% + {\doifassignmentelse{#2} + {\settrue \blockassignmentstatus} + {\setfalse\blockassignmentstatus}% + \ifconditional\blockassignmentstatus + \dosetupblockparameters[#1][#2]% + \fi + \getvalue{\??tb#1\c!before}% + \dostartattributes{\??tb#1}\c!style\c!color\empty + \getvalue{\??tb#1\c!inner}% + \ignorespaces} + +\def\bypassblocks[#1]% + {\def\docommand##1% + {\setvalue{\e!begin##1}% + {\setblocklevel+\bgroup + \obeylines % here, since we look ahead + \dodoubleempty\dobypassblock[##1]}%}% + \setvalue{\e!end##1}% + {}}% + \processcommalist[#1]\docommand} + +\def\dobypassblock[#1][#2]% + {\def\closeblock + {\egroup\setblocklevel-}% + \checkcopyingblocks + \obeylines + \@EA\defconvertedcommand\@EA\endofblockA\@EA{\@EA\string\csname\e!end#1\endcsname}% + \defconvertedcommand\endofblockB{\string\endblock[#1]} % MULTI LINGUAL MAKEN + \setupcopyblock + \skipblocklineAB} + +\protect \endinput diff --git a/tex/context/base/strc-blk.mkiv b/tex/context/base/strc-blk.mkiv new file mode 100644 index 000000000..8aa856840 --- /dev/null +++ b/tex/context/base/strc-blk.mkiv @@ -0,0 +1,112 @@ +%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} + +\unexpanded\def\setupblockparameters{\dodoubleargument \dosetupblock} % fast one (for compatibility) +\unexpanded\def\setupblock {\dodoubleargumentwithset\dosetupblock} % handles set + +\def\dosetupblock[#1]{\getparameters[\??tb#1]} % [#1][#2]} + +\unexpanded\def\defineblock[#1]% + {\processcommalist[#1]\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) + +% no \endgroups + +\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 + {\bgroup + \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")}}% + \egroup} + +% 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.mkiv b/tex/context/base/strc-def.mkiv new file mode 100644 index 000000000..77793c7eb --- /dev/null +++ b/tex/context/base/strc-def.mkiv @@ -0,0 +1,309 @@ +%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!textcolor=\structureheadparameter\c!color, + \c!numberstyle=\structureheadparameter\c!style, + \c!textstyle=\structureheadparameter\c!style, + %\c!numbercommand=, + %\c!textcommand=, + \c!ownnumber=\v!no, + %\c!page=, + \c!placehead=\v!yes, + \c!sectionconversionset=\s!default, + \c!sectionnumber=\v!yes, + %\c!sectionsegments=, + \c!sectionseparatorset=\s!default, + \c!sectionset=\v!all, + \c!interlinespace=, + %\c!sectionstopper=, + %\c!sectionstarter=, + %\c!strut=, + %\c!style=, + %\c!text=, + %\c!tolerance= + ] + +% \setupstructureblock[appendix][sectionconversionset=appendix] +% \setupstructurehead[chapter][sectionconversionset=\structureblockparameter\c!sectionconversionset] % \structureblockparameter] + +% \definestructureresetset[default][0,1,1,0][1] % this will not reset parts and subsections +% \setuphead[part][sectionresetset=default] +% \starttext +% \placelist[chapter,section,subsection][criterium=all,width=3cm] +% \part{first} \chapter{alpha} \section{a} \section{b} \subsection{x} \subsection{y} \chapter{beta} +% \part{second} \chapter{gamma} \section{a} \section{b} \subsection{x} \subsection{y} \chapter{delta} +% \stoptext + +\definestructureseparatorset [\s!default] [] [.] +\definestructureconversionset [\s!default] [] [numbers] +\definestructureresetset [\s!default] [] [1] % each level +\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!none] [] [] + +\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] [] [1] % why was this 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[\v!preference,\v!big]}, % sort of mkii compatible, watch columns + \c!after=\blank, + \c!label=\v!yes, + \c!distance=1em] + +\setuplist + [\v!chapter] + [\c!before={\blank[\v!preference,\v!big]}, % sort of mkii compatible, watch columns + \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..ee5fe702b --- /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.mkiv", + 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.mkii b/tex/context/base/strc-des.mkii new file mode 100644 index 000000000..0c34e9ef9 --- /dev/null +++ b/tex/context/base/strc-des.mkii @@ -0,0 +1,921 @@ +%D \module +%D [ file=strc-des, +%D version=1997.03.31, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Descriptions, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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} + +%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 +%D flexible support for inheriting numbers was added. + +%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 + +\unprotect + +% Dit kan en moet dus anders: +% +% \start... : \vbox\bgroup +% \stop... : \egroup +% llap enz. +% geen indent! +% +% enz. enz. +% +% Op die manier is meer mogelijk en worden \par's geskipt. +% +% De macro \??dd#1\s!do\c!commando levert de koppeling tussen +% \doornumberen en \doordefinieren. Deze constructie is nodig +% omdat doornummeren geen argument heeft en omdat subnummers +% niet worden genest binnen het hogere niveau. +% +% herimplementeren met \nextbox en \unhbox\unvbox + +% list and titles are experiental +% +% \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] + +\newbox\@@descriptionbox + +\def\descriptionparameter#1{\csname\??dd\currentdescription#1\endcsname} + +\def\@@descriptionhandler{\descriptionparameter{\s!do\c!command}} + +% \def\normal@@descriptionhandler[#1]#2#3% +% {\doattributes +% {\??dd\currentdescription}\c!headstyle\c!headcolor +% {\descriptionparameter\c!command{#3}}% NAAR BUITENSTE NIVEAU ! +% \rawreference\s!def{#1}{#2}} % brrr moet in #4 + +\def\normal@@descriptionhandler[#1]#2#3% + {\doattributes + {\??dd\currentdescription}\c!headstyle\c!headcolor + {\descriptionparameter\c!command{#3}}% NAAR BUITENSTE NIVEAU ! + \doifsomething{\descriptionparameter\c!list} + {\dowritetolist + {\descriptionparameter\c!type:\descriptionparameter\c!list} + {}{#2}{\currentdescription}}% + % beware: with footnotes #2 can be something messy but then #1 is + % empty anyway, so we have an extra safeguard + \doifsomething{#1}{\rawreference\s!def{#1}{#2}}} % brrr moet in #4 + +\setvalue{@@description\v!left}% + {\@@descriptionhang\@@descriptionleftpure\@@descriptionlefthang} + +\setvalue{@@description\v!right}% + {\@@descriptionhang\@@descriptionrightpure\@@descriptionrighthang} + +\def\@@descriptionhang#1#2% + {\processaction + [\descriptionparameter\c!hang] + [ \v!none=>\let\next#1,% + 0=>\let\next#1,% + \s!unknown=>\let\next#2,% + \s!default=>\let\next#1]% + \next} + +\def\@@descriptionleftpure[#1]#2% + {\@@dostartdescription[#1]{\def\\{\crlf}}{#2}% + \noindent\ignorespaces + \leftskip\@@leftdescriptionskip + \rightskip\@@rightdescriptionskip + \advance\leftskip \!!widtha + \@@makedescriptionpurebox\raggedright + \advance\leftskip \!!widthb + \llap + {\hbox to \leftskip + {\hskip\@@leftdescriptionskip + \copy\@@descriptionbox\hss}}% + \@@dodescription} + +\def\@@descriptionrightpure[#1]#2% + {\@@dostartdescription[#1]{\def\\{\crlf}}{#2}% + \noindent\ignorespaces + \leftskip\@@leftdescriptionskip + \rightskip\@@rightdescriptionskip + \advance\rightskip \!!widtha + \@@makedescriptionpurebox\raggedleft + \rlap + {\hskip\hsize + \hskip-\leftskip + \hskip-\rightskip + \copy\@@descriptionbox + \hskip\@@rightdescriptionskip}% + \advance\rightskip \!!widthb + \@@dodescription} + +\def\@@makedescriptionpurebox#1% + {\setbox\@@descriptionbox\vtop + {\dontcomplain + \hsize\!!widtha + \leftskip\zeropoint + \rightskip\zeropoint + #1\setupalign[\descriptionparameter\c!align]% + \ifhbox\@@descriptionbox\unhcopy\else\copy\fi\@@descriptionbox}% + \ht\@@descriptionbox\strutht + \dp\@@descriptionbox\strutdp} + +\def\@@descriptionlefthang[#1]#2% + {\@@dostartdescription[#1]{\def\\{\crlf}}{#2}% + \dontcomplain + \advance\!!widtha \!!widthb + \hangindent\!!widtha + \@@makedescriptionhangbox\raggedright{\advance\rightskip \!!widthb}% + \noindent\ignorespaces + \llap + {\dontshowcomposition + \vtop to \zeropoint{\box\@@descriptionbox}}% + \@@dodescription} + +\def\@@descriptionrighthang[#1]#2% + {\@@dostartdescription[#1]{\def\\{\crlf}}{#2}% + \dontcomplain + \advance\!!widtha \!!widthb + \hangindent-\!!widtha + \@@makedescriptionhangbox\raggedleft{\advance\leftskip \!!widthb}% + \noindent\ignorespaces + \rlap + {\dontcomplain + \dontshowcomposition + \scratchdimen\hsize + \advance\scratchdimen -\leftskip + \advance\scratchdimen -\rightskip + \hbox to \scratchdimen + {\hss\vtop to \zeropoint{\box\@@descriptionbox}}}% + \@@dodescription} + +\def\@@makedescriptionhangbox#1#2% + {\setbox\@@descriptionbox\vtop % \vbox gaat fout in hang + {\forgetall + \dontcomplain + \hsize\!!widtha + #1\setupalign[\descriptionparameter\c!align]#2% + \ifhbox\@@descriptionbox\unhcopy\else\copy\fi\@@descriptionbox}% + \ht\@@descriptionbox\strutht + \dp\@@descriptionbox\strutdp + \doifsomething{\descriptionparameter\c!hang} + {\doifinsetelse{\descriptionparameter\c!hang}{\v!fit,\v!broad} + {\scratchdimen\ht\@@descriptionbox + \advance\scratchdimen \dp\@@descriptionbox + \doif{\descriptionparameter\c!hang}\v!broad + {\advance\scratchdimen .5\strutht}% + \getnoflines\scratchdimen + \hangafter-\noflines} + {\hangafter-\descriptionparameter\c!hang}}} + +\setvalue{@@description\v!top}[#1]#2% + {%\page[\v!preference]% % Weg ermee! + %\dosomebreak{\goodbreak}% % Dit is beter en nodig! + \dohandlepagebreakX\plusone % En dit moet het maar worden. + \@@dostartdescription[#1]{\let\\=\space}{#2}% + \noindent\ignorespaces + \copy\@@descriptionbox\par + \nobreak + \descriptionparameter\c!inbetween + \nobreak + \@@dodescription} + +\def\do@@description#1[#2]#3% + {\@@dostartdescription[#2]{\def\\{\crlf}}{#3}% + \noindent\ignorespaces % not needed this ignore + #1{\ifhbox\@@descriptionbox\unhcopy\else\copy\fi\@@descriptionbox}% + \@@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}[#1]#2% + {\@@dostartdescription[#1]{\def\\{\crlf}}{#2}% + \noindent\ignorespaces + \ifhbox\@@descriptionbox\unhcopy\else\copy\fi\@@descriptionbox + \hskip\!!widthb % toegevoegd + \@@dodescription} + +\setvalue{@@description\v!serried\v!broad}[#1]#2% + {\@@dostartdescription[#1]{\def\\{\crlf}}{#2}% + \noindent\ignorespaces + \ifhbox\@@descriptionbox\unhcopy\else\copy\fi\@@descriptionbox + \hskip\!!widthb \!!plus .5\!!widthb \!!minus .25\!!widthb + \@@dodescription} + +\setvalue{@@description\v!serried\v!wide}[#1]#2% + {\@@dostartdescription[#1]{\def\\{\crlf}}{#2}% + \noindent\ignorespaces + \hbox to \!!widtha + {\ifhbox\@@descriptionbox\unhcopy\else\copy\fi\@@descriptionbox\hss}% + \hskip\!!widthb + \ignorespaces + \@@dodescription} + +\setvalue{@@description\v!serried}[#1]#2% + {\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}[#1]{#2}} + +\setvalue{@@description\v!hanging}[#1]#2% + {\@@dostartdescription[#1]{\def\\{\crlf}}{#2}% % adds \c!margin to \leftskip + \noindent\ignorespaces + \advance\leftskip -\leftskipadaption \relax + \ifdim\leftskipadaption=\zeropoint + \leftskipadaption1.5em % 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\@@descriptionbox\unhcopy\else\copy\fi\@@descriptionbox + \kern\ifdim\!!widthb=\zeropoint .75em\else\!!widthb\fi + \ignorespaces + \@@dodescription} + +%D A bonus definition +%D +%D \starttyping +%D \setupfootnotedefinition[location=command,headcommand=\llap] +%D \stoptyping + +\setvalue{@@description\v!command}#1% + {\do@@description{\executeifdefined{\??dd#1\c!headcommand}\framed}{#1}} + +%D A new key 'headalign' in definitions. + +\def\resetdescriptions % to be used in e.g. footnotes + {\chardef\nesteddescriptionstate\zerocount} + +\resetdescriptions + +\let\@@leftdescriptionskip \!!zeropoint +\let\@@rightdescriptionskip\!!zeropoint + +\def\@@dostartdescription[#1]#2#3% + {\descriptionparameter\c!before + \begingroup + \doadaptleftskip{\descriptionparameter\c!margin}% + \showcomposition + \!!widthb\descriptionparameter\c!distance\relax + \ifdim\!!widthb=\zeropoint\relax + \doif{\descriptionparameter\c!width}\v!broad{\!!widthb=1em}% + \fi + % temp hack, we need to avoid this kind of preprocessing + \setbox\@@descriptionbox\hbox % preroll + {\forgetall + \trialtypesettingtrue + \dontcomplain + #2% sets \\ to space or \crlf + \@@descriptionhandler[#1]{#3}{\begstrut\descriptionparameter\c!text\ignorespaces#3\endstrut}}% + % so far + \assignwidth + \!!widtha + {\descriptionparameter\c!width}% + {\doifelsenothing{\descriptionparameter\c!sample}% + {% preroll can move here (test first) + \ifhbox\@@descriptionbox\unhcopy\else\copy\fi \@@descriptionbox}% + {\@@descriptionhandler[#1]{#3}{\descriptionparameter\c!text\descriptionparameter\c!sample}}} + \!!widthb + \setbox\@@descriptionbox\hbox + {\forgetall + \dontcomplain + #2% sets \\ to space or \crlf + \doifelse{\descriptionparameter\c!location}\v!serried + {\@@descriptionhandler[#1]{#3}{\begstrut\descriptionparameter\c!text#3\endstrut}} + {\@@descriptionhandler[#1]{#3}{\vtop{\hsize\!!widtha\advance\hsize-\!!widthb + \begstrut\descriptionparameter\c!text\ignorespaces#3\endstrut}}}}% + \doifelse{\descriptionparameter\c!aligntitle}\v!no + {\edef\@@leftdescriptionskip {\the\leftskip }% + \edef\@@rightdescriptionskip{\the\rightskip}} + {\ifcase\nesteddescriptionstate + \edef\@@leftdescriptionskip {\the\leftskip }% + \edef\@@rightdescriptionskip{\the\rightskip}% + \fi}% + \expanded{\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#1% + {\def\currentdescription{#1}% + \@@placedescriptionclosesymbol + % was \par \dostopattributes % here, else problems with interlinespace and font change + \dostopparbasedattributes % == \settrue\parbasedattributes \dostopattributes + \endgroup + \descriptionparameter\c!after %hm, which currentdescription? + \egroup % temporary hack + \def\currentdescription{#1}% + \dochecknextindentation{\??dd\currentdescription}% + \dorechecknextindentation} + +\def\@@dodescription + {\dostartattributes{\??dd\currentdescription}\c!style\c!color\empty + \ignorespaces} + +% starters: + +\def\@@startdescription[#1][#2]% + {\def\currentdescription{#1}% + \doifelse{\descriptionparameter\c!title}\v!yes + % {\dowithwargument{\@@startsomedescription{#1}[#2]}} % patched for theorems + {\permitspacesbetweengroups + \dodoublegroupempty{\@@startsomedescription{#1}[#2]}} + {\@@startsomedescription{#1}[#2]{}}} + +\def\@@description[#1][#2]% + {\def\currentdescription{#1}% + \doifelse{\descriptionparameter\c!title}\v!yes + % {\dowithwargument{\@@somedescription{#1}[#2]}} % patched for theorems + {\permitspacesbetweengroups + \dodoublegroupempty{\@@somedescription{#1}[#2]}} + {\@@somedescription{#1}[#2]{}}} + +% these call: + +\def\@@somedescription#1[#2]#3% + {\dowithpar + {\bgroup\@@makedescription{#1}[#2]{#3}}% + {\@@stopdescription{#1}}} + +\def\@@startsomedescription#1[#2]#3% + {\bgroup % temporary hack + \BeforePar{\@@makedescription{#1}[#2]{#3}}% + \GotoPar} + +% which calls: + +\def\@@makedescription#1% + {\postponenotes % new, assumes grouping + \def\currentdescription{#1}% + \executeifdefined + {@@description\descriptionparameter\c!location} + {\getvalue{@@description\v!left}}} + +% \def\@@makedescription#1% +% {\def\currentdescription{#1}% +% \ifundefined{@@description\descriptionparameter\c!location}% +% \letvalue{\??dd#1\c!location}\v!left +% \fi +% \getvalue{@@description\descriptionparameter\c!location}} + +% definitions + +\def\setupdescriptions + {\dodoubleempty\dosetupdescriptions} + +\def\dosetupdescriptions[#1][#2]% % beter: \iffirstargument + {\ConvertToConstant\doifelse{#2}{} + {\dodosetupdescriptions[][#1]} + {\dodoubleargumentwithset\dodosetupdescriptions[#1][#2]}} + +\def\dodosetupdescriptions[#1]% [#2]% + {\getparameters[\??dd#1]} % [#2]} + +\def\dodefinedescription[#1][#2]% + {\copyparameters[\??dd#1][\??dd] + [\c!location,\c!headstyle,\c!style,\c!color,\c!headcolor,\c!title, + \c!width,\c!hang,\c!sample,\c!before,\c!inbetween,\c!after,\c!margin, + \c!indenting,\c!indentnext,\c!align,\c!text,\c!distance,\c!titledistance,\c!command, + \c!titleleft,\c!titleright,\c!titlecommand,\c!closesymbol,\c!closecommand]% + \getparameters[\??dd#1] + [\c!title=\v!yes,\s!do\c!command=\normal@@descriptionhandler, + \c!type=\v!description,\c!list=,\c!listtext=, + \c!level=,#2]%AM?? Why do we have title=yes here? + %\doifvalue{\??dd#1\c!location}\v!top{\doassign[\??dd#1][\c!inbetween=\blank]}% + \doifvalue{\??dd#1\c!location}\v!top % we actually need more granularity + {\doifnotvalue{\??dd#1\c!inbetween}{\doassign[\??dd#1][\c!inbetween=\blank]}}% + \doifvaluesomething{\??dd#1\c!list} + {\definelist[\getvalue{\??dd#1\c!type}:\getvalue{\??dd#1\c!list}]}% new + \setvalue {#1}{\dodoubleempty\@@description[#1]}% + \setvalue{\e!start#1}{\dodoubleempty\@@startdescription[#1]}% + \setvalue{\e!stop #1}{\@@stopdescription{#1}}} + +\def\definedescription + {\dodoubleemptywithset\dodefinedescription} + +\def\currentdescriptionnumber {\csname\??dd\currentdescription\??dd\c!number\endcsname} +\def\directcurrentdescriptionnumber#1{\csname\??dd #1\??dd\c!number\endcsname} + +\ifx\preparednumber\undefined \let\preparednumber\empty \fi + +\def\special@@descriptionhandler[#1]#2#3% + {\strut + \doifelse{\descriptionparameter\c!number}\v!no + \!!doneafalse{\doifelse{#1}{-}\!!doneafalse\!!doneatrue}% + \chardef\descriptioncoupling\zerocount + \iflocation + \doifsomething{\descriptionparameter\c!coupling} + {\processaction % genereert > of < + [\descriptionparameter\c!couplingway] + [ \v!local=>\chardef\descriptioncoupling\plusone, % old: default + \v!global=>\chardef\descriptioncoupling\plustwo]}% new: global crosslinking + \fi + \setupnumber % the number is called indirectly + [\currentdescriptionnumber] + [\c!sectionnumber=\descriptionparameter\c!sectionnumber]% + \if!!donea + \makeprecedingsectionnumber[\currentdescriptionnumber]% + \prepareprefixnumber{\??dd\currentdescription}\precedingsectionnumber\preparednumber + \iftrialtypesetting\startlocal\fi + \getvalue{\e!next\currentdescription}% tricky but we need the preroll + \iftrialtypesetting\stoplocal\fi + % \getvalue{\e!next#2#1}% + \iflocation + \bgroup + \letvalue{\??dd\currentdescription\c!sectionnumber}\v!yes + \protectconversion + \makeprecedingsectionnumber[\currentdescriptionnumber]% + \prepareprefixnumber{\??dd\currentdescription}\precedingsectionnumber\preparednumber + \ifcase\descriptioncoupling \or + \xdef\@@internalenumber{\doshowdnnumber}% + \rawreference\s!num{#1:\@@internalenumber}{}% + \or + \xdef\@@internalenumber{\countervalue{\??dd\c!coupling\currentdescription}}% + \rawreference\s!num{\currentdescription:\@@internalenumber}{}% + \fi + \egroup + \fi + %\makeprecedingsectionnumber[\currentdescriptionnumber]% + %\prepareprefixnumber{\??dd\currentdescription}\precedingsectionnumber\preparednumber + \disablepseudocaps % sorry, uppercase causes troubles + \doattributes % \nocase primitive needed + {\??dd\currentdescription}\c!headstyle\c!headcolor % todo: sub as well + {\descriptionparameter\c!command + {\showdntext + \descriptionparameter\c!left + \strut\doshowdnnumber + \showdntitle{#2}% + \descriptionparameter\c!stopper + \descriptionparameter\c!right}}% + \doifsomething{\descriptionparameter\c!list} + {\dowritetolist + {\descriptionparameter\c!type:\descriptionparameter\c!list} + {\showdnlisttext\doshowdnnumber}{#2}{\currentdescription}}% + \iflocation\ifcase\descriptioncoupling \else + \edef\localconnection{\descriptionparameter\c!coupling:\@@internalenumber}% + \doifreferencefoundelse\localconnection + {\in[\localconnection]}\donothing % genereert > of < + \fi\fi + \doifnot{#1}{-}{\rawreference\s!num{#1}{{\doshowdnnumber}{#2}}}% + \else + \doattributes{\??dd\currentdescription}\c!headstyle\c!headcolor + {\descriptionparameter\c!command + {\showdnpuretext + \descriptionparameter\c!left + \showdntitle{#2}% + \descriptionparameter\c!stopper + \descriptionparameter\c!right}}% + \doifnot{#1}{-}{\rawreference\s!num{#1}{{}{#2}}}% + \fi} + +\def\showdntitle#1% + {\doif{\descriptionparameter\c!title}\v!yes % new, for david antos + {\doifsomething{#1} + {\doattributes{\??dd\currentdescription}\c!titlestyle\c!titlecolor + {\hskip\descriptionparameter\c!titledistance + \descriptionparameter\c!titlecommand + {\descriptionparameter\c!titleleft + \begstrut#1\endstrut + \descriptionparameter\c!titleright}}}}} + + +\def\showdnpuretext + {\strut\descriptionparameter\c!text} % geen spatie + +\def\showdnlisttext + {\descriptionparameter\c!listtext} % space in default + +\def\showdntext + {\doifelsenothing{\descriptionparameter\c!text} + {\ignorespaces} + {\strut + \descriptionparameter\c!text + \removeunwantedspaces\fixedspace}} + +\def\doshowdnnumber + {\getvalue{showdn\descriptionparameter\c!level\c!number}} + +% maybe recursive until end condition undefined + +\setvalue{showdn\c!number}% + {\preparednumber + \convertednumber[\currentdescriptionnumber]} + +\setvalue{showdn\v!sub\c!number}% + {\getvalue{showdn\c!number}% + \spr{\descriptionparameter\c!separator}% + \convertednumber[\v!sub\currentdescriptionnumber]} + +\setvalue{showdn\v!sub\v!sub\c!number}% + {\getvalue{showdn\v!sub\c!number}% + \spr{\descriptionparameter\c!separator}% + \convertednumber[\v!sub\v!sub\currentdescriptionnumber]} + +\setvalue{showdn\v!sub\v!sub\v!sub\c!number}% + {\getvalue{showdn\v!sub\v!sub\c!number}% + \spr{\descriptionparameter\c!separator}% + \convertednumber[\v!sub\v!sub\v!sub\currentdescriptionnumber]} + +\def\domakednnumber + {\descriptionparameter\c!left + \strut\doshowdnnumber + \descriptionparameter\c!stopper + \descriptionparameter\c!right} + +\setvalue{\??dd\s!set\v!sub\s!sub\s!sub\c!number}#1% + {\edef\@@descriptionnumber{\directcurrentdescriptionnumber{#1}}% + \setnumber[\v!sub\v!sub\v!sub\@@descriptionnumber]} + +\setvalue{\??dd\s!set\v!sub\s!sub\c!number}#1% + {\getvalue{\??dd\s!reset\v!sub\v!sub\v!sub\c!number}{#1}% + \setnumber[\v!sub\v!sub\@@descriptionnumber]} + +\setvalue{\??dd\s!set\v!sub\c!number}#1% + {\getvalue{\??dd\s!reset\v!sub\v!sub\c!number}{#1}% + \setnumber[\v!sub\@@descriptionnumber]} + +\setvalue{\??dd\s!set\c!number}#1% + {\getvalue{\??dd\s!reset\v!sub\c!number}{#1}% + \setnumber[\@@descriptionnumber]} + +\setvalue{\??dd\s!reset\v!sub\v!sub\v!sub\c!number}#1% + {\edef\@@descriptionnumber{\directcurrentdescriptionnumber{#1}}% + \resetnumber[\v!sub\v!sub\v!sub\@@descriptionnumber]} + +\setvalue{\??dd\s!reset\v!sub\v!sub\c!number}#1% + {\getvalue{\??dd\s!reset\v!sub\v!sub\v!sub\c!number}{#1}% + \resetnumber[\v!sub\v!sub\@@descriptionnumber]} + +\setvalue{\??dd\s!reset\v!sub\c!number}#1% + {\getvalue{\??dd\s!reset\v!sub\v!sub\c!number}{#1}% + \resetnumber[\v!sub\@@descriptionnumber]} + +\setvalue{\??dd\s!reset\c!number}#1% + {\getvalue{\??dd\s!reset\v!sub\c!number}{#1}% + \resetnumber[\@@descriptionnumber]} + +\setvalue{\??dd\e!next\v!sub\v!sub\v!sub\c!number}#1#2% + {\edef\@@descriptionnumber{\directcurrentdescriptionnumber{#1}}% + \incrementnumber[\v!sub\v!sub\v!sub\@@descriptionnumber]% + \rawreference\s!num{#2}{\getvalue{showdn\v!sub\v!sub\v!sub\c!number}}}% + +\setvalue{\??dd\e!next\v!sub\v!sub\c!number}#1#2% + {\getvalue{\??dd\s!reset\v!sub\v!sub\v!sub\c!number}{#1}% + \incrementnumber[\v!sub\v!sub\@@descriptionnumber]% + \rawreference\s!num{#2}{\getvalue{showdn\v!sub\v!sub\c!number}}}% + +\setvalue{\??dd\e!next\v!sub\c!number}#1#2% + {\getvalue{\??dd\s!reset\v!sub\v!sub\c!number}{#1}% + \incrementnumber[\v!sub\@@descriptionnumber]% + \rawreference\s!num{#2}{\getvalue{showdn\v!sub\c!number}}}% + +\setvalue{\??dd\e!next\c!number}#1#2% + {\getvalue{\??dd\s!reset\v!sub\c!number}{#1}% + \incrementnumber[\@@descriptionnumber]% + \rawreference\s!num{#2}{\getvalue{showdn\c!number}}}% + +\def\dodosetupenumerations[#1][#2]% + {\getparameters[\??dd#1][#2]% + \doifdefined{\??dd#1\c!start} + {\setupnumber[#1][\c!start=\getvalue{\??dd#1\c!start}]}% + \setupnumber[#1][\c!conversion=\getvalue{\??dd#1\c!conversion}]} + +\def\dosetupenumerations[#1][#2]% + {\ConvertToConstant\doifelse{#2}{} + {\getparameters[\??dn][#1]} + {\dodoubleargumentwithset\dodosetupenumerations[#1][#2]}} + +\def\setupenumerations + {\dodoubleempty\dosetupenumerations} + +\def\docheckenumerationnumber#1#2#3% + {\processaction + [\getvalue{\??dd#2\c!number}] + [ \v!yes=>\setvalue{\??dd#2\??dd\c!number}{#3},% + \v!no=>\setvalue{\??dd#2\??dd\c!number}{#3},% + \v!default=>\setvalue{\??dd#2\??dd\c!number}{#3},% + \v!unknown=>\letvalue{\??dd#2\??dd\c!number}\commalistelement]} + +\def\dododefineenumeration#1#2#3[#4][#5]% + {\makecounter{\??dd\c!coupling#1}% new: global cross linking + \dodefinedescription[#3#1]% + [\c!title=\v!no,\c!level=#3,\c!type=\v!enumeration,\c!list=,% + \s!do\c!command=\special@@descriptionhandler]% + \copyparameters[\??dd#3#1][\??dn] + [\c!location,\c!headstyle,\c!style,\c!color,\c!headcolor, + \c!width,\c!number,\c!distance,\c!titledistance,\c!command, + \c!sample,\c!hang,\c!align,\c!before,\c!inbetween,\c!after, + \c!levels,\c!way,\c!blockway,\c!separator,\c!margin, + \c!indenting,\c!indentnext,\c!stopper,\c!sectionnumber, + \c!title,\c!titleleft,\c!titleright,\c!titlecommand,\c!closesymbol,\c!closecommand]% + \doifassignmentelse{#4} + {\getparameters[\??dd#3#1]% + [\c!text=#1,\??dd\c!number=#1,\c!conversion=,\c!listtext=#1\space, + \c!left=,\c!right=,\c!coupling=,\c!couplingway=\v!local,#4]% + \docheckenumerationnumber{#1}{#3#1}{#1}}% + {\doifelsenothing{#4} + {\getparameters[\??dd#3#1]% + [\c!text=#1,\??dd\c!number=#1,\c!conversion=, + \c!stopper=, + \c!left=,\c!right=,\c!coupling=,\c!couplingway=,#4]% + \docheckenumerationnumber{#1}{#3#1}{#1}}% + {\copyparameters[\??dd#3#1][\??dd#3#4] + [\c!location,\c!headstyle,\c!style,\c!color,\c!headcolor, + \c!width,\c!number,\c!distance,\c!titledistance,\c!command,\c!margin, + \c!sample,\c!hang,\c!align,\c!before,\c!inbetween,\c!after, + \c!stopper,\c!indenting,\c!indentnext,\c!left,\c!right, + \c!coupling,\c!couplingway, + \c!title,\c!titleleft,\c!titleright,\c!titlecommand,\c!closesymbol,\c!closecommand]% + \getparameters[\??dd#3#1] + [\c!text=#1,\??dd\c!number=#4,\c!conversion=,#5]% + %docheckenumerationnumber{#1}{#3#1}{#4}}}% + \docheckenumerationnumber{#1}{#3#1}{\getvalue{\??dd#3#4\??dd\c!number}}}}% + \doifvalue{\??dd#3#1\??dd\c!number}{#1} + {\definenumber + [#3#1] + [\c!way=\descriptionparentparameter\c!way, + \c!blockway=\descriptionparentparameter\c!blockway, + \c!conversion=\descriptionparentparameter\c!conversion, + \c!sectionnumber=\descriptionparentparameter\c!sectionnumber]% + \doifvalue{\??dd#1\c!levels}{#2}% % for + {\doifsomething{\getvalue{\??dd#1\c!conversion}}% % old + {\setupnumber[#3#1] % times + [\c!conversion=\descriptionparameter\c!conversion]}}}% % sake + \doifvaluesomething{\??dd#3#1\c!list} + {\definelist[\getvalue{\??dd#3#1\c!type}:\getvalue{\??dd#3#1\c!list}]}% new + % should work ... + %setvalue{\s!set #3#1}{\dosetenumerationnumber[#1][#3]}% + %setvalue{\s!reset#3#1}{\doresetenumerationnumber[#1][#3]}% + %setvalue{\e!next #3#1}{\dotripleempty\donextenumerationnumber[#1][#3]}} + % but since we use \currentdescription, we need ... + \setevalue{\s!set #3#1}{\noexpand \dosetenumerationnumber [#1][#3]}% + \setevalue{\s!reset#3#1}{\noexpand \doresetenumerationnumber[#1][#3]}% + \setevalue{\e!next #3#1}{\noexpand\dotripleempty\noexpand\donextenumerationnumber [#1][#3]}} + +\def\descriptionparentparameter#1{\csname\??dd\currentdescriptionnumber#1\endcsname} + +\def\dodefineenumeration[#1][#2][#3]% + {\dododefineenumeration{#1}{1}{}[#2][#3]% + \dododefineenumeration{#1}{2}{\v!sub}[#2][#3]% + \dododefineenumeration{#1}{3}{\v!sub\v!sub}[#2][#3]% + \dododefineenumeration{#1}{4}{\v!sub\v!sub\v!sub}[#2][#3]} + +\def\defineenumeration + {\dotripleemptywithset\dodefineenumeration} + +\def\doresetenumerationnumber[#1][#2]% name level + {\getvalue{\??dd\s!reset#2\c!number}{#1}}% + +\def\dosetenumerationnumber[#1][#2]% name level + {\getvalue{\??dd\s!set#2\c!number}{#1}}% + +\def\donextenumerationnumber[#1][#2][#3]% name level reference + {\pluscounter{\??dd\c!coupling#1}% new: global crosslinking + \getvalue{\??dd\e!next#2\c!number}{#1}{#3}}% + +\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} + +% Het default-mechanisme kan mooier: leegtest, enz. +% +% Werkprocedure buiten description + +\def\dodosetupindentations[#1][#2]% + {\getparameters[\??ds#1][#2]} + +\def\dosetupindentations[#1][#2]% + {\ConvertToConstant\doifelse{#2}{} + {\dodosetupindentations[][#1]} + {\dodoubleargumentwithset\dodosetupindentations[#1][#2]}} + +\def\setupindentations + {\dodoubleempty\dosetupindentations} + +% what to do with this + +\def\startdoorspringen + {\whitespace + \@@dsbefore + \dosomebreak\goodbreak % \page[\v!preference] + \begingroup + \parskip\zeropoint\relax} + +\def\stopdoorspringen + {\endgroup + \@@dsafter} + +% + +\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 + {\!!widtha} + {\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\!!widtha \getvalue{\??ds#1\c!distance}% + \setbox2\hbox to \!!widtha + {\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\!!widtha\indent\box2% + \hangindent#3\!!widtha + \doattributes{\??ds#1}\c!style\c!color\empty + \AfterPar{\endgroup\getvalue{\??ds#1\c!after}}% must be redone + \GetPar} + +\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]% + \setvalue {#1}{\dododefineindenting{#1}{0}{1}}% + \setvalue {\v!sub#1}{\dododefineindenting{#1}{1}{2}}% + \setvalue{\v!sub\v!sub#1}{\dododefineindenting{#1}{2}{3}}} + +\def\defineindenting + {\dodoubleargumentwithset\dodefineindenting} + +\def\definelabel + {\dodoubleargumentwithset\dodefinelabel} + +\def\dodefinelabel[#1][#2]% + {\definenumber + [#1] + [\c!command=,\c!location=,#2]% + % downward compatible + \processaction + [\numberparameter{#1}\c!location] + [ \v!inmargin=>{\setupnumber[#1][\c!command=\inmargin]}, + \v!inleft=>{\setupnumber[#1][\c!command=\inleft ]}, + \v!inright=>{\setupnumber[#1][\c!command=\inright ]}, + \v!margin=>{\setupnumber[#1][\c!command=\inmargin]}]% + % generated commands (in addition to the number ones) + \setvalue {#1}{\dodoubleempty\do@@label[#1]}% + \setvalue{\s!reset #1}{\resetnumber[#1]}% + \setvalue{\e!increment#1}{\incrementnumber[#1]}% + \setvalue{\e!next #1}{\dodoubleempty\do@@nextlabel[#1]}% + \setvalue{\c!current #1}{\currentnumber[#1]}} + +\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!after}% + +\def\do@@nextlabel[#1][#2]% + {\nextnumber[#1][\s!lab][#2]} + +\def\currentnumber[#1]% kan tekst hier weg ? + {\dotextprefix{\numberparameter{#1}\c!text}\sectionnumberonly[#1]} + +\def\nextnumber[#1][#2][#3]% + {\incrementnumber[#1]% + \currentnumber[#1]% + \rawreference{#2}{#3}{\composedsectionnumber}} + +\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!headcolor=, + \c!titlestyle=\v!bold, + \c!titlecolor=, + \c!style=\v!normal, + \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!text=, + \c!levels=3, % to be upward compatible + \c!conversion=, % to be upward compatible + \c!way=\v!by\v!text, + \c!sectionnumber=\v!yes, + \c!separator=\@@koseparator, % per 2006.06.23, was . + \c!stopper=, + \c!titleleft=(, + \c!titleright=), + \c!closesymbol=, + \c!closecommand=\wordright, + \c!number=, + \c!command=, + \c!titlecommand=] + +\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-des.mkiv b/tex/context/base/strc-des.mkiv new file mode 100644 index 000000000..29e4ea36c --- /dev/null +++ b/tex/context/base/strc-des.mkiv @@ -0,0 +1,1097 @@ +%D \module +%D [ file=strc-des, +%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] % clone one +%D \defineenumeration[three] [counter=one,style=slanted] % only use counter of one +%D \defineenumeration[four] [three] % clone three +%D \defineenumeration[five] [three] [counter=five] % clone three and use own counter +%D \defineenumeration[six] [three] [counter=four] % clone tree and use counter four (undefined) +%D +%D \startone test test 6 \stopone +%D \starttwo test test 7 \stoptwo +%D \startthree test test 8 \stopthree +%D \startfour test test 9 \stopfour +%D \startfive test test 2 \stopfive +%D \startsix test test 10 \stopsix +%D \stopbuffer +%D +%D \typebuffer \start \getbuffer \stop +%D +%D \starttyping +%D \setupenumerations[one] [prefix=yes,prefixsegments=section] +%D \setupenumerations[two] [prefix=yes,prefixsegments=section] +%D \setupenumerations[three][prefix=yes,prefixsegments=section] +%D \setupenumerations[four] [prefix=yes,prefixsegments=chapter:section] +%D \setupenumerations[five] [prefix=yes,prefixsegments=chapter:section] +%D \setupenumerations[six] [prefix=yes,prefixsegments=chapter:section] +%D \stoptyping + +% 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} + +\def\descriptionlocationparameter#1{\csname\dodescriptionlocationparameter{\??dd\currentdescription}#1\endcsname} + +\def\dodescriptionlocationparameter#1#2% + {\ifcsname#1#2:\descriptionparameter\c!location\endcsname + #1#2:\descriptionparameter\c!location + \else\ifcsname#1\s!parent\endcsname + \expandafter\dodescriptionlocationparameter\csname#1\s!parent\endcsname#2% + \else + \dodescriptionparameter{\??dd\currentdescription}#2% + \fi\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 \descriptionsheadwidth{\copy\descriptionheadbox\hss}% + \hskip\descriptionsheaddistance}% + \@@dodescription} + +\def\@@descriptionrightmargin % whatever this means + {\def\\{\crlf}% + \noindent + \rlap + {\hskip\descriptionsheaddistance + \@@makedescriptionpurebox\raggedright + \hbox to \descriptionsheadwidth{\copy\descriptionheadbox\hss}}% + \@@dodescription} + +\def\@@makedescriptionpurebox#1% + {\setbox\descriptionheadbox\vtop + {\dontcomplain + \hsize\descriptionsheadwidth + \leftskip\zeropoint + \rightskip\zeropoint + #1\setupalign[\descriptionparameter\c!headalign]% + \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!headalign]#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 + [\descriptionlocationparameter\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 + \setlocalhsize % so we can use \localhsize in width assignments + \descriptionsheaddistance\descriptionlocationparameter\c!distance\relax + \ifdim\descriptionsheaddistance=\zeropoint\relax + \doif{\descriptionlocationparameter\c!width}\v!broad{\descriptionsheaddistance=1em}% + \fi + \setbox\descriptionheadbox\hbox + {\forgetall\dontcomplain + \trialtypesettingtrue + \doifelsenothing{\descriptionparameter\c!sample} + {\dodescriptionhandler\currentdescriptiontext}% + {\dodescriptionhandler\currentdescriptionsample}}% + \assignwidth + \descriptionsheadwidth + {\descriptionlocationparameter\c!width} + {\unhcopy\descriptionheadbox} + \descriptionsheaddistance + \setbox\descriptionheadbox\hbox + {\forgetall\dontcomplain + \doifelse{\descriptionparameter\c!location}\v!serried % brrr, hack + {\dodescriptionhandler\currentdescriptiontext} + {\dodescriptionhandler{\boxeddescriptionhead\currentdescriptiontext}}}% + \doifelse{\descriptionparameter\c!aligntitle}\v!no + {\leftdescriptionskip\leftskip\rightdescriptionskip\rightskip} + {\ifcase\nesteddescriptionstate\leftdescriptionskip\leftskip\rightdescriptionskip\rightskip\fi}% + \doifsomething{\descriptionparameter\c!align}{\setupalign[\descriptionparameter\c!align]}% + \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\boxeddescriptionhead#1% + {\vtop + %{\hsize\dimexpr\descriptionsheadwidth-\descriptionsheaddistance\relax + {\hsize\descriptionsheadwidth + \doifsomething{\descriptionparameter\c!headalign}{\setupalign[\descriptionparameter\c!headalign]}% + #1}} + +\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 + \edef\currentdescriptionreference{#1}% + \doenumerationcheckconditions + \dodescriptioncomponent[\c!reference=#1,\c!label={\descriptionparameter\c!text},\c!title={#2},\c!bookmark=,\c!list=][]% + \@@dostartdescriptionindeed} + +\def\dostartstoreddescription + {\@@dostartdescriptionindeed} + +\def\dostopstoreddescription + {\@@stopdescription} + +% % % % % % % % % % % % + +% helpers + +% todo: \dosetfontattributewithhash \descriptionparameterhash\c!headstyle + +% setup descriptions + +\unexpanded\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 + +\unexpanded\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% + {\setuevalue {#1}{\noexpand\dodescriptioncommand{#1}}% + \setuevalue{\e!start#1}{\noexpand\dodescriptionstart {#1}}% + \setuevalue{\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\dodescriptiontext {\csname\??dd:\descriptionparameter\s!handler:\s!handler:\s!text \endcsname} +\def\dodescriptionnumber {\csname\??dd:\descriptionparameter\s!handler:\s!handler:\s!number\endcsname} +\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} + +\def\currentdescriptiontext {\begstrut\dodescriptiontext\endstrut} +\def\currentdescriptionsample{\begstrut\descriptionparameter\c!text\descriptionparameter\c!sample\endstrut} + +% 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:\s!text }{\@@dodescriptiontext} +\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% + {\iftrialtypesetting \else + \begingroup + \currentdescriptionsynchronize + \attribute\destinationattribute\currentdescriptionattribute\relax % todo, whole text + \forcecolorhack + \endgroup + \fi#1} + +\def\@@dododescriptiontext + {\ctxlua{structure.lists.savedtitle("\currentdescriptionmain",\currentdescriptionnumberentry)}} + +\def\@@dodescriptiontext + {\begingroup + \dosetdescriptionattributes\c!headstyle\c!headcolor + \the\everydescription + \descriptionparameter\c!command{\strut\descriptionparameter\c!text\ignorespaces\@@dododescriptiontext}% probably incomplete + \endgroup} + +% setup enumerations + +\unexpanded\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 + +\unexpanded\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!parent=\??dd#2,#3]% + \let\@@subslevel\empty + \dorecurse{\descriptionparameter\c!levels} + {\normalexpanded{\noexpand\dodefineenumerationcommands{#1}{\recurselevel}{\@@subslevel}{\??dd\@@subslevel#2}}% + \edef\@@subslevel{\@@subslevel\v!sub}}% + \fi + \edef\currentdescriptioncounter{\descriptionparameter\s!counter}% + \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 % ? + %[[#1:\currentdescriptioncounter]] + \doifstructurecounterelse{\currentdescriptioncounter}{}{\dodefineenumerationcounter\currentdescriptioncounter}% + \fi\fi\fi + \dosetupenumerationcounter{#1}} % new + +\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}% + \setuevalue {#3#1}{\noexpand\doenumerationcommand{#1}{#2}{#3}}% + \setuevalue{\e!start#3#1}{\noexpand\doenumerationstart {#1}{#2}{#3}}% + \setuevalue{\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 +\def \enumerationdisablenumbersignal {-} + +\appendtoks \disablepseudocaps \to \everyenumeration % sorry, uppercase causes troubles + +\setvalue{\??dd:\v!enumeration:\s!handler:\s!number}{\@@doenumerationnumber} +\setvalue{\??dd:\v!enumeration:\s!handler:\s!text }{\@@doenumerationtext} +\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} + +\let\@@doenumerationhandler\@@dodescriptionhandler + +% \def\currentenumerationfullnumber +% {\ctxlua{structure.lists.savedprefixednumber("\currentdescriptionmain",\currentdescriptionnumberentry)}} + +\def\@@doenumerationnumber + {\ctxlua{structure.lists.savedprefixednumber("\currentdescriptionmain",\currentdescriptionnumberentry)}} + +\def\@@dodoenumerationtext + {\ctxlua{structure.lists.savedtitle("\currentdescriptionmain",\currentdescriptionnumberentry)}} + +\def\doenumerationnumber + {\descriptionparameter\c!left + \descriptionparameter\c!starter + \dodescriptionnumber + \descriptionparameter\c!stopper + \descriptionparameter\c!right} + +\def\@@doenumerationtext + {\ifconditional\enumerationnumberenabled + \iftrialtypesetting + \doenumerationfullnumber\showdntext + \doenumerationcouplingsymbol + \else + \doenumerationregistercoupling + \doenumerationfullnumber\showdntext + \doenumerationcouplingsymbol + \fi + \else + \doenumerationfullnumber\showdnpuretext + \fi} + +\def\doenumerationfullnumber#1% text, title + {\begingroup + \dosetdescriptionattributes\c!headstyle\c!headcolor + \the\everyenumeration + \descriptionparameter\c!command{\strut#1\doenumerationnumber\doenumerationextratext}% + \endgroup} + +\def\doenumerationextratext + {\doif{\descriptionparameter\c!title}\v!yes + {\begingroup + \dosetdescriptionattributes\c!titlestyle\c!titlecolor + \hskip\descriptionparameter\c!titledistance + \descriptionparameter\c!titlecommand + {\descriptionparameter\c!titleleft + \begstrut\@@dodoenumerationtext\endstrut + \descriptionparameter\c!titleright}% + \endgroup}} + +\def\doenumerationsavecounter {\savestructurecounter[\currentdescriptionnumber]} +\def\doenumerationrestorecounter {\restorestructurecounter[\currentdescriptionnumber]} +\def\doenumerationincrementcounter{\doincrementsubstructurecounter[\currentdescriptionnumber][\currentdescriptionlevel]} + +% to be used in for instance: +% +% coupling=questions .... coupling=answers +% +% we will provide some more control, like skipping etc or reference relates + +\def\doenumerationcheckconditions + {\doifelse{\descriptionparameter\c!number}\v!yes + {\ifx\currentdescriptionreference\enumerationdisablenumbersignal + \setfalse\enumerationnumberenabled \else \settrue\enumerationnumberenabled + \fi}% + {\setfalse\enumerationnumberenabled}% + \edef\currentenumerationcoupling{\descriptionparameter\c!coupling}} + +\def\doenumerationregistercoupling + {\iflocation + % no area yet, we will provide variants some day + \fi} + +\def\doenumerationcouplingsymbol + {\iflocation \ifx\currentenumerationcoupling\empty\else + \symbolreference[order(description:\currentenumerationcoupling:\nextinternalorderreference)]% + \fi \fi} + +\def\skipenumerationcoupling[#1]% e.g. for questions with no answer + {\ctxlua{jobreferences.setnextorder("description","#1")}} + +\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]% + % + \xdef\currentdescriptionexpansion {\descriptionparameter\c!expansion}% + \xdef\currentdescriptionxmlsetup {\descriptionparameter\c!xmlsetup}% + \xdef\currentdescriptioncatcodes {\descriptionparameter\s!catcodes}% + \xdef\currentdescriptionlabel {\descriptionparameter\c!label}% + \xdef\currentdescriptionreference {\descriptionparameter\c!reference}% + \xdef\currentdescriptionreferenceprefix{\descriptionparameter\c!referenceprefix}% + %xdef\currentdescriptionshownumber {\descriptionparameter\c!number}% + \xdef\currentdescriptionsaveinlist {\descriptionparameter\c!saveinlist}% + \xdef\currentdescriptionincrementnumber{\descriptionparameter\c!incrementnumber}% + % + \ifx\currentdescriptionexpansion\empty + \glet\currentdescriptionexpansion\v!no + \fi + % + \ifx\currentdescriptionexpansion\s!xml + \xmlstartraw + \xdef\currentdescriptiontitle {\descriptionparameter\c!title}% + \xdef\currentdescriptionbookmark{\descriptionparameter\c!bookmark}% + \xdef\currentdescriptionmarking {\descriptionparameter\c!marking}% + \xdef\currentdescriptionlist {\descriptionparameter\c!list}% + \xmlstopraw + \ifx\currentdescriptionlist\empty + \globallet\currentdescriptionlist\currentdescriptiontitle + \fi + \globallet\currentdescriptioncoding\s!xml + \else + \ifx\currentdescriptionexpansion\v!yes + \xdef\currentdescriptiontitle {\descriptionparameter\c!title}% + \xdef\currentdescriptionbookmark{\descriptionparameter\c!bookmark}% + \xdef\currentdescriptionmarking {\descriptionparameter\c!marking}% + \xdef\currentdescriptionlist {\descriptionparameter\c!list}% + \else + \xdef\currentdescriptiontitle {\detokenizeddescriptionparameter\c!title}% + \xdef\currentdescriptionbookmark{\detokenizeddescriptionparameter\c!bookmark}% + \xdef\currentdescriptionmarking {\detokenizeddescriptionparameter\c!marking}% + \xdef\currentdescriptionlist {\detokenizeddescriptionparameter\c!list}% + \iflocation \ifx\currentdescriptionbookmark\empty + \begingroup + \simplifycommands + \xdef\currentdescriptionbookmark{\detokenize\expandafter{\normalexpanded{\descriptionparameter\c!title}}}% + \endgroup + \fi \fi + \fi + \ifx\currentdescriptionlist\empty + \globallet\currentdescriptionlist\currentdescriptiontitle + \fi + \globallet\currentdescriptioncoding\s!tex + \fi + % + \ifx\currentdescriptiontitle\v!none % will become obsolete + \global\nodescriptioncaptiontrue\global\nodescriptionnumbertrue + \fi + % + \ifconditional\enumerationnumberenabled + \doifelsedescriptioncomponent\donothing\doenumerationincrementcounter + \fi + % + \ifnodescriptioncaption + \glet\currentdescriptionlistnumber \relax + \glet\currentdescriptionsynchronize\relax + \glet\currentdescriptionattribute \relax + \else + %\setnextinternalreference + \setnextinternalreferences{description}\currentdescriptionname % plural + \xdef\currentdescriptionnumberentry{\ctxlua{structure.lists.push{ + metadata = { + kind = "description", + name = "\currentdescriptionname", + level = structure.sections.currentlevel(), + catcodes = \the\catcodetable, + % \currentdirectionparameters + }, + references = { + internal = \nextinternalreference, + order = \nextinternalorderreference, + 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\currentdescriptionlist\currentdescriptiontitle \else % \ifx\currentdescriptionsaveinlist\v!no + list = \!!bs\detokenize\expandafter{\currentdescriptionlist }\!!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("\currentdescriptionnumber",nil,true), % ! number can be cloned + separatorset = "\descriptionparameter\c!numberseparatorset", + conversion = "\descriptionparameter\c!numberconversion", + conversionset = "\descriptionparameter\c!numberconversionset", + starter = \!!bs\descriptionparameter\c!numberstarter\!!es, + stopper = \!!bs\descriptionparameter\c!numberstopper\!!es, + segments = "\descriptionparameter\c!numbersegments", + }, + \fi + userdata = structure.helpers.touserdata(\!!bs\detokenize{#2}\!!es) + } + }}% + \xdef\currentdescriptionattribute {\ctxlua {tex.write(jobreferences.setinternalreference("\referenceprefix","\currentdescriptionreference",\nextinternalreference,"\@@iafocus"))}}% + \xdef\currentdescriptionsynchronize{\ctxlatelua{structure.lists.enhance(\currentdescriptionnumberentry)}}% + \fi + \endgroup} + +% This is not so nice, some day i'll just store the number with the entry +% and deal with all at the Lua end, but first we need to be able to set +% macros. + +\def\reinstatedescriptionnumberentry#1% + {\xdef\currentdescriptionattribute {\ctxlua {tex.write(jobreferences.getinternalreference(#1))}}% + \xdef\currentdescriptionsynchronize{\ctxlatelua{structure.lists.enhance(#1)}}} + +\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 + +\unexpanded\def\setuplabels + {\getparameters[\??db]} + +\unexpanded\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% + {\setuevalue {#1}{\noexpand\dolabelnumbercommand {#1}}% + \setuevalue{\c!reset #1}{\noexpand\doresetlabelnumber {#1}}% + %\setuevalue{\c!set #1}{\noexpand\dosetlabelnumber {#1}}% [#2] or {#2} ? + \setuevalue{\e!next #1}{\noexpand\donextlabelnumber {#1}}% + \setuevalue{\e!increment#1}{\noexpand\doincrementlabelnumber{#1}}% + \setuevalue{\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}% + \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 + +\unexpanded\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]} + +\unexpanded\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]% + \setuvalue {#1}{\dododefineindenting{#1}{0}{1}}% + \setuvalue {\v!sub#1}{\dododefineindenting{#1}{1}{2}}% + \setuvalue{\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!headalign=, + \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!text=, + \c!way=\v!by\v!text, + \c!prefix=\v!no, + \c!prefixconnector=., + \c!starter=, + \c!stopper=, + \c!number=\v!yes, % else description + \c!start=0, + \s!parent=\??dd] + +\setupdescriptions + [\c!expansion=\v!no, + \c!xmlsetup=, + \s!catcodes=, + \c!saveinlist=\v!yes] + +\setupenumerations + [\c!expansion=\v!no, + \c!xmlsetup=, + \s!catcodes=, + \c!saveinlist=\v!yes] + +\setupdescriptions + [\c!width=7em, + \c!distance=1em] + +\setupdescriptions[\c!width:\c!top=\localhsize] % undocumented, only width and distance +% \setupdescriptions[\c!width:\c!left=7em,\c!distance=1em] +% \setupdescriptions[\c!width:\c!right=7em,\c!distance=1em] + + +\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..7faf0d5b3 --- /dev/null +++ b/tex/context/base/strc-doc.lua @@ -0,0 +1,702 @@ +if not modules then modules = { } end modules ['strc-doc'] = { + version = 1.001, + comment = "companion to strc-doc.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- todo: associate counter with head + +-- we need to freeze and document this module + +local next, type = next, type +local format, gsub, find, concat, gmatch, match = string.format, string.gsub, string.find, table.concat, string.gmatch, string.match +local texsprint, texwrite = tex.sprint, tex.write +local concat = table.concat +local max, min = math.max, math.min + +local ctxcatcodes = tex.ctxcatcodes +local variables = interfaces.variables + +--~ if not trackers then trackers = { register = function() end } end + +local trace_sectioning = false trackers.register("structure.sectioning", function(v) trace_sectioning = v end) +local trace_detail = false trackers.register("structure.detail", function(v) trace_detail = 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 = { }, + forced = { }, + ownnumbers = { }, + status = { }, + checkers = { }, + depth = 0, + blocks = { }, + block = "", + } + documents.data = data +end + +function documents.reset() + data.numbers = { } + data.forced = { } + 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 + +levelmap.block = -1 + +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) + structure.counters.check(0) -- we assume sane usage of \page between blocks + 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.somelevel(given) + -- old number + local numbers, ownnumbers, forced, status, olddepth = data.numbers, data.ownnumbers, data.forced, data.status, data.depth + local givenname = given.metadata.name + local mappedlevel = levelmap[givenname] + local newdepth = tonumber(mappedlevel or (olddepth > 0 and olddepth) or 1) -- hm, levelmap only works for section-* + local directives = given.directives + local resetset = (directives and directives.resetset) or "" + -- local resetter = sets.getall("structure:resets",data.block,resetset) + -- 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) + if trace_detail then + logs.report("structure","name '%s', mapped level '%s', old depth '%s', new depth '%s', reset set '%s'",givenname,mappedlevel,olddepth,newdepth,resetset) + end + local u = given.userdata + if u then + -- kind of obsolete as we can pass them directly anyway + if u.reference and u.reference ~= "" then given.metadata.reference = u.reference ; u.reference = nil end + if u.ownnumber and u.ownnumber ~= "" then given.numberdata.ownnumber = u.ownnumber ; u.ownnumber = nil end + if u.title and u.title ~= "" then given.titledata.title = u.title ; u.title = nil end + if u.bookmark and u.bookmark ~= "" then given.titledata.bookmark = u.bookmark ; u.bookmark = nil end + if u.label and u.label ~= "" then given.titledata.label = u.label ; u.label = nil end + end + -- so far for the trick + if newdepth > olddepth then + for i=olddepth+1,newdepth do + local s = tonumber(sets.get("structure:resets",data.block,resetset,i)) + if trace_detail then + logs.report("structure","new>old (%s>%s), reset set '%s', reset value '%s', current '%s'",olddepth,newdepth,resetset,s or "?",numbers[i] or "?") + end + if not s or s == 0 then + numbers[i] = numbers[i] or 0 + ownnumbers[i] = ownnumbers[i] or "" + else + numbers[i] = s - 1 + ownnumbers[i] = "" + end + status[i] = { } + end + elseif newdepth < olddepth then + for i=olddepth,newdepth+1,-1 do + local s = tonumber(sets.get("structure:resets",data.block,resetset,i)) + if trace_detail then + logs.report("structure","new 0 then + numberdata.ownnumbers = table.fastcopy(ownnumbers) + end + if trace_detail then + logs.report("structure","name '%s', numbers '%s', own numbers '%s'",givenname,concat(numberdata.numbers, " "),concat(numberdata.ownnumbers, " ")) + end + given.references.section = sections.save(given) + -- given.numberdata = nil +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,min(depth,#numbers))) 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.setnumber(depth,n) + local forced, depth, new = data.forced, depth or data.depth, tonumber(n) + if type(n) == "string" then + if find(n,"^[%+%-]") then + forced[depth] = { "add", new } + else + forced[depth] = { "set", new } + end + else + forced[depth] = { "set", new } + end +end + +function sections.number_at_depth(depth) + return data.numbers[tonumber(depth) or sections.getlevel(depth) or 0] or 0 +end + +function sections.numbers() + return data.numbers +end + +function sections.matching_till_depth(depth,numbers,parentnumbers) + local dn = parentnumbers or data.numbers + local ok = false + for i=1,depth do + if dn[i] == numbers[i] then + ok = true + else + return false + end + end + return ok +end + +function sections.getnumber(depth) -- redefined later ... + 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.structuredata(depth,key,default,honorcatcodetable) -- todo: spec table and then also depth + if not depth or depth == 0 then depth = data.depth end + local data = data.status[depth] + local d = data + for k in gmatch(key,"([^.]+)") 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 == true or honorcatcodetable == variables.auto then + local metadata = data.metadata + texsprint((metadata and metadata.catcodes) or ctxcatcodes,d) + elseif not honorcatcodetable then + texsprint(ctxcatcodes,d) + elseif type(honorcatcodetable) == "number" then + texsprint(honorcatcodetable,d) + elseif type(honorcatcodetable) == "string" and honorcatcodetable ~= "" then + honorcatcodetable = tex[honorcatcodetable] or ctxcatcodes-- we should move ctxcatcodes to another table, ctx or so + texsprint(honorcatcodetable,d) + else + texsprint(ctxcatcodes,d) + end + return + end + end + if default then + texsprint(ctxcatcodes,default) + end +end + +function sections.userdata(depth,key,default) + if not depth or depth == 0 then depth = data.depth end + if depth > 0 then + local userdata = data.status[depth] + userdata = userdata and userdata.userdata + userdata = (userdata and userdata[key]) or default + if userdata then + texsprint(ctxcatcodes,userdata) + end + end +end + +function sections.setchecker(name,level,command) -- hm, checkers are not saved + 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} +-- } + +-- sign=all => also zero and negative +-- sign=positive => also zero +-- sign=hang => llap sign + +function sections.typesetnumber(entry,kind,...) -- kind='section','number','prefix' + if entry and entry.hidenumber ~= true then -- can be nil + local separatorset = "" + local conversionset = "" + local conversion = "" + local stopper = "" + local starter = "" + local connector = "" + local set = "" + local segments = "" + local criterium = "" + local dataset = { ... } + for d=1,#dataset do + local data = dataset[d] -- can be multiple parametersets + 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 starter == "" then starter = data.starter 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 + if criterium == "" then criterium = data.criterium or "" end + end + end + if separatorset == "" then separatorset = "default" end + if conversionset == "" then conversionset = "default" end -- not used + if conversion == "" then conversion = nil end + if stopper == "" then stopper = nil end + if starter == "" then starter = nil end + if connector == "" then connector = nil end + if set == "" then set = "default" end + if segments == "" then segments = nil end + -- + if criterium == variables.strict then + criterium = 0 + elseif criterium == variables.positive then + criterium = -1 + elseif criterium == variables.all then + criterium = -1000000 + else + criterium = 0 + end + -- + local firstprefix, lastprefix = 0, 16 + if segments then + local f, l = match(tostring(segments),"^(.-):(.+)$") + 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 + -- todo: too much (100 steps) + local number = numbers and (numbers[index] or 0) + local ownnumber = ownnumbers and ownnumbers[index] or "" + if number > criterium or (ownnumber ~= "") then + local block = (entry.block ~= "" and entry.block) or sections.currentblock() -- added + if preceding then + local separator = sets.get("structure:separators",block,separatorset,preceding,".") + if separator then + processors.sprint(ctxcatcodes,separator) + end + preceding = false + end + if ownnumber ~= "" then + processors.sprint(ctxcatcodes,ownnumber) + -- elseif conversion and conversion ~= "" then + -- texsprint(ctxcatcodes,format("\\convertnumber{%s}{%s}",conversion,number)) + elseif conversion and conversion ~= "" then + -- traditional (e.g. used in itemgroups) + texsprint(ctxcatcodes,format("\\convertnumber{%s}{%s}",conversion,number)) + else + local theconversion = sets.get("structure:conversions",block,conversionset,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 starter then + processors.sprint(ctxcatcodes,starter) + end + 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.title() + local sc = sections.current() + if sc then + helpers.title(sc.titledata.title,sc.metadata) + end +end + +function sections.findnumber(depth,what) + local data = data.status[depth or data.depth] + if data then + local index = data.references.section + local collected = jobsections.collected + local sectiondata = collected[index] + if sectiondata and sectiondata.hidenumber ~= true then -- can be nil + if what == variables.first then + for i=index,1,-1 do + local s = collected[i] + local n = s.numbers + if #n == depth and n[depth] and n[depth] ~= 0 then + sectiondata = s + elseif #n < depth then + break + end + end + elseif what == variables.last then + for i=index,#collected do + local s = collected[i] + local n = s.numbers + if #n == depth and n[depth] and n[depth] ~= 0 then + sectiondata = s + elseif #n < depth then + break + end + end + end + return sectiondata + end + end +end + +function sections.fullnumber(depth,what,raw) + local sectiondata = sections.findnumber(depth,what) + if sectiondata then + sections.typesetnumber(sectiondata,'section',sectiondata) + end +end + +function sections.getnumber(depth,what) -- redefined here + local sectiondata = sections.findnumber(depth,what) + texwrite((sectiondata and sectiondata.numbers[depth]) or 0) +end diff --git a/tex/context/base/strc-doc.mkiv b/tex/context/base/strc-doc.mkiv new file mode 100644 index 000000000..e10efb3f7 --- /dev/null +++ b/tex/context/base/strc-doc.mkiv @@ -0,0 +1,216 @@ +%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 + +\def\c!xmlsetup{xmlsetup} + +% 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!marking=,\c!list=,\c!label=,\c!coupling=,\c!ownnumber=, + \c!sectionseparatorset=\s!default,\c!sectionconversionset=\s!default, + \c!sectionstopper=,\c!sectionstarter,\c!sectionsegments=, + \c!sectionresetset=,\c!reference=, + \c!expansion=\v!no, + \c!xmlsetup=, + \s!catcodes=, + \c!saveinlist=\v!yes, + \c!command=\showstructuredata] + +% maybe flags for list, bm, mark +% +% hm messed up + +\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}% + \xdef\currentstructurexmlsetup {\structureparameter\c!xmlsetup}% + \xdef\currentstructurecatcodes {\structureparameter\s!catcodes}% + \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}% + \ifx\currentstructureexpansion\s!xml + \xmlstartraw + \xdef\currentstructuretitle {\structureparameter\c!title}% + \xdef\currentstructurebookmark{\structureparameter\c!bookmark}% + \xdef\currentstructuremarking {\structureparameter\c!marking}% + \xdef\currentstructurelist {\structureparameter\c!list}% + \xmlstopraw + \ifx\currentstructurelist\empty + \globallet\currentstructurelist\currentstructuretitle + \fi + \globallet\currentstructurecoding\s!xml + \else + \ifx\currentstructureexpansion\v!yes + \xdef\currentstructuretitle {\structureparameter\c!title}% + \xdef\currentstructurebookmark{\structureparameter\c!bookmark}% + \xdef\currentstructuremarking {\structureparameter\c!marking}% + \xdef\currentstructurelist {\structureparameter\c!list}% + \else + \xdef\currentstructuretitle {\detokenizedstructureparameter\c!title}% + \xdef\currentstructurebookmark{\detokenizedstructureparameter\c!bookmark}% + \xdef\currentstructuremarking {\detokenizedstructureparameter\c!marking}% + \xdef\currentstructurelist {\detokenizedstructureparameter\c!list}% + \iflocation \ifx\currentstructurebookmark\empty + \begingroup + \simplifycommands + \xdef\currentstructurebookmark{\detokenize\expandafter{\normalexpanded{\structureparameter\c!title}}}% + \endgroup + \fi \fi + \fi + \ifx\currentstructurelist\empty + \globallet\currentstructurelist\currentstructuretitle + \fi + \globallet\currentstructurecoding\s!tex + \fi + \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!sectionresetset", + }, + metadata = { + kind = "section", + name = "\currentstructurename", + catcodes = \the\ifx\currentstructurecatcodes\empty\catcodetable\else\csname\currentstructurecatcodes\endcsname\fi, + coding = "\currentstructurecoding", + \ifx\currentstructurecoding\s!xml + xmlroot = "\xmldocument", + \fi + \ifx\currentstructurexmlsetup\empty \else + xmlsetup = "\currentstructurexmlsetup", + \fi + \ifx\currentstructuresaveinlist\v!no + nolist = true, + \fi + \ifx\currentstructureincrementnumber\v!yes + increment = "\currentstructureincrementnumber", + \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\currentstructuremarking\currentstructuretitle \else + marking = \!!bs\detokenize\expandafter{\currentstructuremarking }\!!es, + \fi + \ifx\currentstructuresaveinlist\v!no \else + \ifx\currentstructurelist\currentstructuretitle \else + list = \!!bs\detokenize\expandafter{\currentstructurelist}\!!es, + \fi + \fi + }, + numberdata = { + % needed ? + block = "\currentstructureblock", + hidenumber = \ifx\currentstructureshownumber\v!no true\else nil\fi, % titles + % so far + separatorset = "\structureparameter\c!sectionseparatorset", + conversion = "\structureparameter\c!sectionconversion", % for good old times sake + conversionset = "\structureparameter\c!sectionconversionset", + starter = \!!bs\structureparameter\c!sectionstarter\!!es, + stopper = \!!bs\structureparameter\c!sectionstopper\!!es, + set = "\structureparameter\c!sectionset", + segments = "\structureparameter\c!sectionsegments", + ownnumber = "\currentstructureownnumber", + }, + 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\currentstructureattribute {\ctxlua {tex.write(jobreferences.setinternalreference("\currentstructurereferenceprefix","\currentstructurereference",\nextinternalreference,"\@@iafocus"))}}% + \xdef\currentstructuresynchronize{\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\begingroup + \currentstructuresynchronize + \currentstructureattribute + [\currentstructurename: \showstructurelevel: \currentstructuretitle] + \endgroup\par} + +% We can access the (stored) data with the following macros. +% +% \def\MyHeadCommand #1#2{\framed{#1}\framed{#2 / \structureuservariable{subtitle}}} +% \def\MyListCommand#1#2#3{\externalfigure[\structurelistuservariable{figure}][height=5mm]#2} +% +% \setuphead[chapter][command=\MyHeadCommand] +% \setuplist[chapter][alternative=command,command=\MyListCommand] +% +% \starttext +% \setupheadertexts[chapter] +% \setupinteraction[state=start] +% \placebookmarks[chapter] +% \placelist[chapter] +% \startchapter[ownnumber=10,title=Ton,list=Hans,marking=Kees,bookmark=Bram][figure=cow.pdf,subtitle=oeps] +% \stopchapter +% \stoptext + +\def\structurevariable #1{\ctxlua{structure.sections.structuredata(nil,"#1")}} +\def\structureuservariable #1{\ctxlua{structure.sections.userdata(nil,"#1")}} +\def\structurenumber {\ctxlua{structure.sections.fullnumber()}} +\def\structurecatcodedget #1{\ctxlua{structure.sections.structuredata(nil,"#1",nil,true)}} % bad name +\def\structuregivencatcodedget#1#2{\ctxlua{structure.sections.structuredata(nil,"#1",nil,\number#2)}} % bad name +\def\structureautocatcodedget #1#2{\ctxlua{structure.sections.structuredata(nil,"#1",nil,"#2")}} + +\protect \endinput diff --git a/tex/context/base/strc-flt.lua b/tex/context/base/strc-flt.lua new file mode 100644 index 000000000..466fd515e --- /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.mkiv", + 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.mkii b/tex/context/base/strc-flt.mkii new file mode 100644 index 000000000..e64a439ec --- /dev/null +++ b/tex/context/base/strc-flt.mkii @@ -0,0 +1,2143 @@ +%D \module +%D [ file=strc-flt, +%D version=2000.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Floating Bodies, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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} + +%D Some of the sidefloat settings should move to page-sid; now it's quite +%D fuzzy the way the variables are set/reset. + +\unprotect + +\ifx\addlocalbackgroundtobox\undefined \def\addlocalbackgroundtobox{\resetglobal\gobbleoneargument} \fi + +\def\placefloats{\doflushfloats} % keep this one + +\def\floatparameter #1{\csname\??fl\currentfloat#1\endcsname} +\def\floatcaptionparameter#1{\csname\??kj\currentfloat#1\endcsname} + +% \def\floatparameter #1{\csname \ifcsname\??fl\currentfloat#1\endcsname\??fl\currentfloat\else\??bk\fi#1\endcsname} +% \def\floatcaptionparameter#1{\csname\??kj\ifcsname\??kj\currentfloat#1\endcsname \currentfloat \fi#1\endcsname} + +% for the moment we need to define the parameters anyway, first we need to implement a +% proper parent chain (also for framed); no problem now that machines are fast (tests +% show that this may save 20 k or more in the format) +% +% \def\floatparameter #1{\executeifdefined{\??fl\currentfloat#1}{\csname\??fl#1\endcsname}} +% \def\floatcaptionparameter#1{\executeifdefined{\??kj\currentfloat#1}{\csname\??bk#1\endcsname}} + +\def\setupfloats + {\dodoubleargument\getparameters[\??bk]} % funny, why not \??fl, must be a reason + +\def\setupcaptions + {\dodoubleargument\getparameters[\??kj]} + +\def\dosetupfloat[#1][#2]% + {\def\docommand##1{\getparameters[\??fl##1][#2]}% + \processcommalist[#1]\docommand} + +\def\setupfloat + {\dodoubleargument\dosetupfloat} + +\def\dosetupcaption[#1][#2]% + {\def\docommand##1{\getparameters[\??kj##1][#2]}% + \processcommalist[#1]\docommand} + +\def\setupcaption + {\dodoubleargument\dosetupcaption} + +\def\doemptyblock#1% + {\localframed + [\??fl#1] + [\c!frame=\v!on, + \c!width=\@@bkwidth, + \c!height=\@@bkheight, + \c!location=\v!normal, + \c!offset=\@@bkoffset]% + {\getmessage\m!floatblocks{12}\empty}} + +% 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}% + \doifelsenothing\currentfloat + {\let\currentfloat\v!figure} + {}% {\doifundefined{\??fl#1\c!default}{\let\currentfloat\v!figure}}% + \doifelsenothing{#2} + {\edef\floatlocation{\floatparameter\c!default}} + {\edef\floatlocation{#2}}% + \doifinsetelse\v!split{#2} + {\expanded{\dodocomplexsplitfloat[\currentfloat][\floatlocation]}} + {\expanded{\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} + {\expanded{\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{\executeifdefined{\??fl\currentfloat\c!fallback}\v!here}% + \fi}% + \xdocompletefloat{#1}{#3}{#1}{#2}{#1}{#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\sidefloatalign4,% + \v!halfline=>\global\chardef\sidefloatalign5]% +% 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\sidefloatalign4}% + \doifinset\v!halfline{#2}{\global\chardef\sidefloatalign5}% 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}}% + \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\@@bklocal\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}} + +\def\setlocalfloathsize + {\iflocalcenterfloatbox + \seteffectivehsize + \hsize\localhsize + \fi} + +\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\expanded{\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\expanded{\dorepeatwithcommand[#1]}\docommand}% + \egroup} + +\def\hangsidefloat[#1]% + {\global\sidefloatsidelines#1\relax} + +\long\def\xdocompletefloat#1#2#3#4#5#6% + {\ifextrafloatactions + \doifinsetelse\v!text{#4} + {% fuzzy, text overloads left, since then it's a directive + \docompletefloat{#1}{#2}{#3}{#4}{#5}{#6}\nextbox} + {\let\@@extrafloat\empty + % \sidefloatdownshift will be reset afterwards, and can + % already be set at this point + \processallactionsinset + [#4] % 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}{#5}{#6}\nextbox + \else + \docompletefloat{#1}{#2}{#3}{\@@extrafloat,#4}{#5}{#6}\nextbox + \fi}% + \else % downward compatible + \docompletefloat{#1}{#2}{#3}{#4}{#5}{#6}\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} + {\letvalue{\??fl\currentfloat\c!maxwidth}\leftmarginwidth}% + {\doifcommon{\v!inright,\v!rightmargin}{#1} + {\letvalue{\??fl\currentfloat\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\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} + +% todo: \floatparameter + \currentfloat - saves many hash entries + +\def\dododefinefloat[#1][#2]% inherits from kj and not from parent + {\def\currentfloat{#1}% + \presetlocalframed[\??fl#1]% + \setupfloat + [#1] + [%\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!sidespacebefore=\@@bksidespacebefore, + \c!sidespaceafter=\@@bksidespaceafter, + \c!sidealign=\@@bksidealign, % \v!line + \c!margin=\@@bkmargin, + \c!leftmargin=\@@bkleftmargin, + \c!rightmargin=\@@bkrightmargin, + \c!innermargin=\@@bkinnermargin, + \c!outermargin=\@@bkoutermargin, + \c!leftmargindistance=\@@bkleftmargindistance, + \c!rightmargindistance=\@@bkrightmargindistance, + \c!frame=\@@bkframe, + \c!radius=\@@bkradius, + \c!corner=\@@bkcorner, + \c!location=\@@bklocation, + \c!background=\@@bkbackground, + \c!backgroundscreen=\@@bkbackgroundscreen, + \c!backgroundcolor=\@@bkbackgroundcolor, + \c!backgroundoffset=\@@bkbackgroundoffset, + \c!topframe=\@@bktopframe, + \c!bottomframe=\@@bkbottomframe, + \c!leftframe=\@@bkleftframe, + \c!rightframe=\@@bkrightframe, + \c!frameoffset=\@@bkframeoffset, + \c!framecolor=\@@bkframecolor, + %\c!local=\@@bklocal, + \c!textmethod=\@@bktextmethod, + \c!sidemethod=\@@bksidemethod, + \c!method=\@@bkmethod, + \c!pageboundaries=, + \c!default=]% + \setupcaption + [#1] + [\c!headstyle=\@@kjheadstyle, + \c!headcolor=\@@kjheadcolor, + \c!textstyle=\@@kjtextstyle, + \c!textcolor=\@@kjtextcolor, + \c!style=\@@kjstyle, + \c!color=\@@kjcolor, + \c!location=\@@kjlocation, + \c!grid=\@@kjgrid, + %\c!before=\@@kjbefore, + \c!inbetween=\@@kjinbetween, + %\c!after=\@@kjafter, + \c!spacebefore=\@@kjspacebefore, + \c!spaceinbetween=\@@kjspaceinbetween, + \c!spaceafter=\@@kjspaceafter, + \c!width=\@@kjwidth, + \c!minwidth=\@@kjminwidth, + \c!align=\@@kjalign, + \c!number=\@@kjnumber, + \c!way=\@@kjway, + \c!blockway=\@@kjblockway, + \c!sectionnumber=\@@kjsectionnumber, + \c!distance=\@@kjdistance, + \c!separator=\@@kjseparator, + \c!stopper=\@@kjstopper, + \c!suffix=\@@kjsuffix, % hook + \c!command=\@@kjcommand, + \c!conversion=\@@kjconversion, + \c!leftmargin=\@@kjleftmargin, + \c!rightmargin=\@@kjrightmargin, + \c!outermargin=\@@kjoutermargin, + \c!innermargin=\@@kjinnermargin, + \c!setups=\@@kjsetups, + ]% + \definenumber % \definelabel + [#1] + [\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]% + \presetlabeltext[#1=\Word{#1}~]% + \newnodelocation{\v!float\@@thenumber{#1}}% + \dodefinefloatcommands[#1][#2]} + +\def\dodefinefloatcommands[#1][#2]% + {\definelist[#1]% + \presetheadtext[#2=\Word{#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}{\doemptyblock{#1}}% + \setvalue {\e!emptytwo#1}{\doemptyblock{#1}}} + +% \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!leftmargin,\c!rightmargin,\c!innermargin,\c!outermargin, + \c!align,\c!number,\c!way,\c!blockway,\c!setups, + \c!sectionnumber,\c!separator,\c!stopper,\c!suffix,\c!distance,\c!conversion]% + \definenumber[#1][#3]% + \presetlabeltext[#1=\labeltext{#3}]% + \dodefinefloatcommands[#1][#2]} + +\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 + +% 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 + +\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\@@bknumbering\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\@@bknumbering\v!nocheck + {\incrementnumber[#1]% + \makesectionnumber[#1]% + \ifconditional\retainfloatnumber\decrementnumber[#1]\fi} + {\ifinsidecolumns + \chardef\nodelocationmode\zerocount + % to be perfected: + % \chardef\nodelocationmode\plustwo + \fi + \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 + +% 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 \@@bkspaceafter is present + {\bgroup + \setbox0\vbox{\strut\blank[\@@bkspacebefore]\strut}% + \setbox2\vbox{\strut\blank[\@@bkspaceafter ]\strut}% + \ifdim\ht0>\ht2 + \blank[-\@@bkspaceafter,\@@bkspacebefore]% + \fi + \egroup} + +\def\doplacefloatbox + {%\forgetall % NJET! + \whitespace + \blank[\@@bkspacebefore] + \flushfloatbox + \blank[\@@bkspaceafter]} + +\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 -\@@bkmargin\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[\@@bkspacebefore]% + \doifnotinset\v!tall{#1}% + {\dp\floatbox\openstrutdepth}% dp\strutbox}% % toegevoegd + \box\floatbox + \blank[\@@bkspaceafter]% + \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} {lijst} +% {plaats} {label1} {label2} {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 + +\newif\ifnofloatcaption +\newif\ifnofloatnumber +\newif\ifemptyfloatcaption + +\def\docalculatefloatskip#1#2% + {\doifelsenothing{#2} + {\global#1\zeropoint} + {\doifelse{#2}\v!none + {\global#1\zeropoint} + {\setbox0\vbox{\whitespace\expanded{\blank[#2]}}% + \global#1\ht0}}} + +\def\calculatefloatskips + {{\docalculatefloatskip\floattopskip \@@bkspacebefore + \docalculatefloatskip\floatbottomskip \@@bkspaceafter + \docalculatefloatskip\sidefloattopskip {\floatparameter\c!sidespacebefore}% + \docalculatefloatskip\sidefloatbottomskip{\floatparameter\c!sidespaceafter }% + \gdef \sidefloattopoffset{\openstrutdepth}% was \def + \global\floatsideskip \floatparameter\c!margin + \global\sidefloatleftshift \floatparameter\c!leftmargindistance + \global\sidefloatrightshift\floatparameter\c!rightmargindistance + \global\noftopfloats \@@bkntop \relax + \global\nofbotfloats \@@bknbottom\relax}} + +\let\floatcaptionsuffix\empty % an optional suffix +\let\floatcaptionnumber\empty % a logical counter + +% Quite experimental ! + +% 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 + +\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 + \doattributes{\??kj#1}\c!style\c!color + {\doattributes{\??kj#1}\c!headstyle\c!headcolor + {\labeltexts{#1}{\preparednumber}}% + \doattributes{\??kj#1}\c!textstyle\c!textcolor + {\dotfskip{\floatcaptionparameter\c!distance}#3}}}% + \fi} + +\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 + +\def\borderedfloatbox + {\localframed[\??fl\currentfloat][\c!location=\v!normal]{\box\floatbox}} + +\newbox\captionbox + +\long\def\putcompletecaption#1#2% + {\doifsomething{\floatcaptionparameter\c!spacebefore}{\blank[\floatcaptionparameter\c!spacebefore]}% +% \floatcaptionparameter\c!before % test for side effects first + \noindent + \xdef\lastcaptiontag{\strut#1}% + \dostartattributes{\??kj\currentfloat}\c!style\c!color\empty + \ifnofloatnumber + \else + \hbox{\doattributes{\??kj\currentfloat}\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 + \doattributes{\??kj\currentfloat}\c!textstyle\c!textcolor + {\xdef\lastcaptionht{\strutheight}% + \xdef\lastcaptiondp{\strutdepth}% + \begstrut#2\endstrut\endgraf}% + \fi + \dostopattributes +% \floatcaptionparameter\c!after % test for side effects first + \doifsomething{\floatcaptionparameter\c!spaceafter}{\blank[\floatcaptionparameter\c!spaceafter]}} + +\let\lastcaptionht\!!zeropoint +\let\lastcaptiondp\!!zeropoint + +% new + +\newbox\tempfloatbox +\newbox\tempcaptionbox + +\newif\iftracecaptions + +\def\settracedcaptionbox + {\iftracecaptions\setbox\tempcaptionbox\ruledhbox{\box\tempcaptionbox}\fi} + +%\stelblokkopjesin[\c!width=5cm] +%\stelblokkopjesin[\c!align=\v!left] +%\stelblokkopjesin[\c!align=\v!right] + + +% \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} + +% 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 + \expanded{\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-\@@bkmargin\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-\@@bkmargin\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 + \expanded{\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}% + \expanded{\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 + \expanded{\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% + {\dosetfloatbox{#1}{#2}{#3}% + \dogetfloatbox{#1}\empty} + +\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} + + +\long\def\docompletefloat#1#2#3#4#5#6#7% #7 = box number + {%\flushsidefloats % moved + \presetfloatvariables{#1}{#4}{#2}{#6}% + \bgroup + \setnaturalfloatdimensions#7% + \global\setbox\floatbox\vbox + {\executeifdefined{\??fl#1\c!command}\firstofoneargument{\box#7}}% + \setnaturalfloatdimensions\floatbox + \dimen0 \ht\floatbox + \advance\dimen0 \dp\floatbox + \ifdim\dimen0=\zeropoint + \showmessage\m!floatblocks{11}\empty + \global\setbox\floatbox\vbox{\doemptyblock{#3}}% + \fi + \ifnofloatcaption + \global\setbox\floatbox\vbox + {\unvbox\floatbox + \doifelsemainfloatbody{\rawpagereference\s!flt{#2}}\donothing + \vss}% gets rid of the depth (unless tabulate) + \egroup + \dofloat{#4}{}{#6}% + \else + \gdefconvertedargument\asciititle{#6}% \asciititle is global + \ifnofloatnumber + \global\setbox\floatbox\vbox + {\unvbox\floatbox % no \vss, keep the depth + \doifelsemainfloatbody{\rawreference\s!flt{#2}{{}{\asciititle}}}\donothing}% + \egroup + \dofloat{#4}{}{#6}% + \else + \preparefloatnumber{#1}% + \global\setbox\floatbox\vbox + {\unvbox\floatbox % no \vss, keep the depth + \doifelsemainfloatbody + {\tracefloatnumber{#1}% + \rawreference\s!flt{#2}{{\composedsectionnumber}{\asciititle}}% + \dowritetolist{#3}{\composedsectionnumber}{#6}{#3}} + \donothing + }% + \egroup + \preparefullnumber{\??kj#1}\composedsectionnumber\preparednumber + \dofloat{#4}{\labeltexts{#5}{\preparednumber}}{#6}% + \fi + \fi + \global\insidefloatfalse} + +\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] + +\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!way=\@@nrway, + \c!blockway=\@@nrblockway, + \c!sectionnumber=\@@nrsectionnumber, + \c!separator=\@@koseparator, + \c!stopper=\@@kostopper, + \c!suffix=\floatcaptionsuffix, % hook + \c!distance=1em, + \c!command=, + \c!conversion=\v!numbers] + +\setupfloats + [\c!location=\v!middle, + \c!width=8\lineheight, + \c!height=6\lineheight, + \c!offset=\v!overlay, + \c!frame=\v!off, + \c!radius=.5\bodyfontsize, + \c!corner=\v!rectangular, + \c!background=, + \c!backgroundscreen=\@@rsscreen, + \c!backgroundcolor=, + \c!backgroundoffset=\!!zeropoint, + \c!topframe=, + \c!bottomframe=, + \c!leftframe=, + \c!rightframe=, + \c!framecolor=, + \c!frameoffset=\!!zeropoint, + \c!before=, + \c!after=, + \c!spacebefore=\v!big, + \c!spaceafter=\v!big, + \c!sidespacebefore=\@@bkspacebefore, + \c!sidespaceafter=\@@bkspaceafter, + \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=\@@bkleftmargindistance, + \c!ntop=2, + \c!nbottom=0, + \c!nlines=4, + \c!local=, + \c!default=\v!figure, + \c!numbering=\v!yes] + +% 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-flt.mkiv b/tex/context/base/strc-flt.mkiv new file mode 100644 index 000000000..67023d701 --- /dev/null +++ b/tex/context/base/strc-flt.mkiv @@ -0,0 +1,1964 @@ +%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. + +\ifdefined\addlocalbackgroundtobox\else \def\addlocalbackgroundtobox{\resetglobal\gobbleoneargument} \fi + +\unexpanded\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 + +\unexpanded\def\setupfloats {\dosingleargument\dosetupfloats} % was \??bk +\unexpanded\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=\v!by\v!chapter, +% \c!prefixsegments=2:2, +% \c!way=\@@nrway, +% \c!blockway=\@@nrblockway, +% \c!sectionnumber=\@@nrsectionnumber, +% \c!separator=\@@koseparator, +% \c!starter=\@@kostarter, +% \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!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: + +\unexpanded\def\setupfloat {\dodoubleargument\dosetupfloat} +\unexpanded\def\setupcaption{\dodoubleargument\dosetupcaption} + +\newtoks\everysetupfloat +\newtoks\everysetupcaption + +\def\dosetupfloat[#1][#2]% + {\def\docommand##1{\getparameters[\??fl##1][#2]\def\currentfloat{##1}\the\everysetupfloat}% + \processcommalist[#1]\docommand} + +\def\dosetupcaption[#1][#2]% + {\def\docommand##1{\getparameters[\??kj##1][#2]\def\currentfloat{##1}\the\everysetupcaption}% + \processcommalist[#1]\docommand} + +\presetstructurecountersetup\setupcaptions\sharedstructurecounterparameter + +\appendtoks + \dostructurecountersetup\currentfloat\floatcaptionparameter + \docheckstructurecountersetup\currentfloat +\to \everysetupcaption + +%D Definitions: + +\unexpanded\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]% + {\setuvalue {\e!place\e!listof#2}{\dodoubleempty\doplacelist[#1]}% + \setuvalue {\e!complete\e!listof#2}{\dotripleempty\dodocompletelist[#1][#2]}% + \setuvalue {\e!place#1}{\dotripleempty\docomplexplacefloat[#1]}% + \setuvalue {\e!reserve#1}{\doquadrupleempty\docomplexreserveblock[#1]}% + \setuvalue {\e!start#1\e!text}{\dotripleempty\docomplexstarttextblock[#1]}% + \setuvalue {\e!stop#1\e!text}{\dostoptextfloat}% + \setuvalue{\e!start\e!reserve#1\e!text}{\doquadrupleempty\docomplexstartreservetextblock[#1]}% + \setuvalue {\e!stop\e!reserve#1\e!text}{\dostoptextfloat}% + \setuvalue {\e!emptyone#1}{\doemptyfloatblock{#1}}% + \setuvalue {\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\thecurrentfloatnumber + {\ifnofloatcaption \else \ifnofloatnumber \else + \ifx\currentfloatnumber\relax\else + \labeltexts\currentfloat{\ctxlua{structure.lists.savedprefixednumber("\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 ! ! ! ! ! + + \unexpanded\def\placefloatcaption + {\dodoubleempty\doplacefloatcaption} + + \long\def\doplacefloatcaption[#1][#2]#3% + {\setfloatcaption[#1][#2]{#3}% + \placefloatcaptiontext[#1]% + \placefloatcaptionreference[#1]} + + \unexpanded\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 + % todo + \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} + + \unexpanded\def\placefloatcaptiontext [#1]{\getvalue{@fl@t@#1}} + \unexpanded\def\placefloatcaptionnumber [#1]{\getvalue{@fl@n@#1}} + \unexpanded\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 +% +% \unexpanded\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 + {\doprocesslocalsetups{\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 ... will change in mkiv + {\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 + \ifmarginblocks + \doifinset\v!margin{#2}\endgraf + \fi + \global\insidefloattrue + \begingroup % ** + \ifmarginblocks + \doifinset\v!margin{#2}{\hsize\@@mbwidth}% + \fi + \the\everyinsidefloat + \let\@@extrafloat\empty + \presetmorefloatvariables{#2}% + \dowithnextboxcontent % better a \the\everyfloattoks + {\setlocalfloathsize + \floatparameter\c!inner + \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}{} +% \ConvertToConstant\doifelse{\detokenize{#4}}{} + {\global\emptyfloatcaptiontrue} + {\global\emptyfloatcaptionfalse}% +% \doifinsetelse\v!none{#2} +% {\global\nofloatcaptiontrue} +% {\ConvertToConstant\doifelse{#4}\v!none +% {\global\nofloatcaptiontrue} +% {\global\nofloatcaptionfalse}}% + \doifinsetelse\v!none{#2} + {\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 + +\let\currentfloatattribute\empty % to be checked + +\def\floatcaptionattribute + {\iflocation \ifnofloatnumber \else \ifnofloatcaption \else + attr \destinationattribute \currentfloatattribute + \fi \fi \fi} + +\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=\@@thestructurecounter\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\currentfloatattribute \laststructurecounterattribute + \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 \floatcaptionattribute + {\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 + +\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]} + +\unexpanded\def\placefloat + {\dotripleempty\docomplexplacefloat} + +\installinsertion\topins +\installinsertion\botins + +\newdimen\botinserted +\newdimen\topinserted + +\newif\iftopofinsert +\newif\iftestfloatbox + +\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}} + +% 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\betweenfloatblanko% assumes that spaceafter is present + {\blank[\floatsharedparameter\c!spacebefore]} % or v!back,.... + +\def\doplacefloatbox + {%\forgetall % NO + \whitespace + \blank[\floatsharedparameter\c!spacebefore] + \flushfloatbox + \blank[\floatsharedparameter\c!spaceafter]} + +\ifdefined\someherefloat\else \let\someherefloat\doplacefloatbox \fi +\ifdefined\someslotfloat\else \let\someslotfloat\doplacefloatbox \fi +\ifdefined\somefixdfloat\else \let\somefixdfloat\doplacefloatbox \fi +\ifdefined\sometopsfloat\else \let\sometopsfloat\doplacefloatbox \fi +\ifdefined\somebotsfloat\else \let\somebotsfloat\doplacefloatbox \fi +\ifdefined\somesidefloat\else \let\somesidefloat\doplacefloatbox \fi + +% 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]}}}} + +\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 + +\ifdefined\moveboxontogrid\else \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, currently messy + {\ifvisible + \par + \edef\floatcaptiondirectives{\floatparameter\c!location,\floatcaptionparameter\c!location}% + \ifparfloat\@EA\dosetparfloat\else\@EA\dosetpagfloat\fi{#1}{#2}{#3}% + \setlocalfloatdimensions{#1}% + \global\advance\totalnoffloats\plusone + \setbox\floatbox\hbox{\dosavefloatdata\box\floatbox}% still needed? we will do renumbering differently + \global\floatheight\htdp\floatbox + \global\floatwidth\wd\floatbox + \doifnotinset\v!margin{#1} % gaat namelijk nog fout + {\setbox\floatbox\vbox + {\parindent\zeropoint + \doifconcepttracing{\inleftmargin{\framed{\infofont\the\totalnoffloats}}}% + \box\floatbox}}% + \wd\floatbox\floatwidth + \ifdim\dimexpr\floatheight+\lineheight\relax<\textheight \else + \global\floatheight\dimexpr\textheight-\lineheight\relax + \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 + \ifdefined\OTRSETsetpreferedcolumnslot + \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 + +% no \registerotrcommand\placesome* here!, this has to be cleaned up: + +\def\somesidefloat{\OTRcommand\somesidefloat} + +\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]} + +\unexpanded\def\placesomeslotfloat {\OTRcommand\someslotfloat} +\unexpanded\def\placesomeherefloat {\OTRcommand\someherefloat} +\unexpanded\def\placesomefixdfloat {\OTRcommand\somefixdfloat} +\unexpanded\def\placesomepagefloat {\OTRcommand\somepagefloat} +\unexpanded\def\placesomeleftpagefloat {\OTRcommand\someleftpagefloat} +\unexpanded\def\placesomerightpagefloat{\OTRcommand\somerightpagefloat} +\unexpanded\def\placesometopsfloat {\OTRcommand\sometopsfloat} +\unexpanded\def\placesomebotsfloat {\OTRcommand\somebotsfloat} +\unexpanded\def\placesomesidefloat {\OTRcommand\somesidefloat} +\unexpanded\def\placesomefacefloat {\OTRcommand\somefacefloat} + +\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..61c26a20e --- /dev/null +++ b/tex/context/base/strc-ini.lua @@ -0,0 +1,302 @@ +if not modules then modules = { } end modules ['strc-ini'] = { + version = 1.001, + comment = "companion to strc-ini.mkiv", + 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 lpegmatch = lpeg.match + +local ctxcatcodes, xmlcatcodes, notcatcodes = tex.ctxcatcodes, tex.xmlcatcodes, tex.notcatcodes -- tricky as we're in notcatcodes + +local trace_processors = false trackers.register("structure.processors", function(v) trace_processors = v end) + +-- 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 tags = { + generic = "ctx:genericentry", + section = "ctx:sectionentry", + entry = "ctx:registerentry", +} + +function helpers.title(title,metadata) -- brrr + if title and title ~= "" then + if metadata then + if metadata.coding == "xml" then + tag = tags[metadata.kind] or tags.generic + buffers.set(tag,format("<%s>%s",tag,title,tag)) + texsprint(ctxcatcodes,format("\\xmlprocessbuffer{%s}{%s}{}",metadata.xmlroot or "main",tag)) + elseif metadata.xmlsetup then + texsprint(ctxcatcodes,format("\\xmlsetup{%s}{%s}",title,metadata.xmlsetup)) -- nasty + else + local catcodes = metadata.catcodes +--~ print(tex.ctxcatcodes,tex.xmlcatcodes,catcodes,title) + if catcodes == notcatcodes or catcodes == xmlcatcodes then + texsprint(ctxcatcodes,title) -- nasty + else + texsprint(catcodes,title) + end + 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 = lpegmatch(splitter,str) + if registered[p] then + return p, s + else + return false, str + end +end + +function processors.sprint(catcodes,str,fnc,...) + local p, s = lpegmatch(splitter,str) + local code + if registered[p] then + code = format("\\applyprocessor{%s}{%s}",p,(fnc and fnc(s,...)) or s) + else + code = (fnc and fnc(str,...)) or str + end + if trace_processors then + logs.report("processors","cct: %s, seq: %s",catcodes,code) + end + texsprint(catcodes,code) +end + +function processors.apply(str) + local p, s = lpegmatch(splitter,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) -- check if name is passed + 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 + else + if block and block ~= "" then + dn = ds[block] or ds[block..":default"] or ds.default + else + dn = 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.mkiv b/tex/context/base/strc-ini.mkiv new file mode 100644 index 000000000..5ed7b423c --- /dev/null +++ b/tex/context/base/strc-ini.mkiv @@ -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. + +\unexpanded\def\definestructureresetset {\dotripleempty\dodefinestructureresetset} +\unexpanded\def\definestructureseparatorset {\dotripleempty\dodefinestructureseparatorset} +\unexpanded\def\definestructureconversionset{\dotripleempty\dodefinestructureconversionset} +\unexpanded\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..e776f326d --- /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.mkiv", + 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.mkii b/tex/context/base/strc-itm.mkii new file mode 100644 index 000000000..1de63c7c3 --- /dev/null +++ b/tex/context/base/strc-itm.mkii @@ -0,0 +1,1335 @@ +%D \module +%D [ file=strc-itm, % updated +%D version=1997.03.31, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=itemgroups, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% new: text + lefttext=(,righttext=) +% start= + +\writestatus{loading}{ConTeXt Structure Macros / Itemgroups} + +\unprotect + +% - instellingen in macro +% - [0] voor start op 0 +% - start=2 + +\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\itemcolumndepth +\newcount\itemdepth +\newcount\maxitemdepth + +\definetwopasslist\s!list + +\let\currentitemlevel \!!zerocount +\let\currentitemgroup \empty +\let\currentnofitems \!!zerocount +\let\currentmaxnofitems\!!zerocount +\let\currentminnofitems\!!zerocount +\let\currentitemoffset \!!zerocount +\def\currentitemnumber{\countervalue{\@@itemcounter\currentitemlevel}} + +% tricky ... we cannot use trialtypesetting here because there can be +% multiple itemizes in e.g. a table, so we need something more advanced +% where counters etc are reset to pre-outertrial values + +\def\dolistreference + {\ifconditional\continuelistitems + \savetaggedtwopassdata\s!list{\number\currentnoflists}{\number\currentnoflists}% + {\currentitemlevel:\noflistelements:c:\getitemparameter\currentitemlevel\c!maxwidth}% + \else + \savetaggedtwopassdata\s!list{\number\currentnoflists}{\number\currentnoflists}% + {\currentitemlevel:\noflistelements:n:\getitemparameter\currentitemlevel\c!maxwidth}% + \fi} + +\def\splititemtwopassdata#1% + {\expanded{\findtwopassdata{\s!list}{\number#1}}% + \expandafter\dosplititemtwopassdata\twopassdata:0:0:0:0:0\relax} + +\def\dosplititemtwopassdata#1:#2:#3:#4:#5\relax + {\edef\itemdatal{#1}\edef\itemdatan{#2}\edef\itemdatat{#3}\edef\itemdataw{#4}} + +\def\checkcurrentnofitems + {\splititemtwopassdata\currentnoflists + \iftwopassdatafound + \ifcase\itemdatan\relax % \scratchcounter + \let\currentnofitems \!!zerocount + \let\currentminnofitems\!!plusone + \let\currentmaxnofitems\!!zerocount + \else + \scratchcounter\itemdatan\relax + \edef\currentnofitems{\the\scratchcounter}% + \let\currentitemtag\itemdatat + \doloop + {\splititemtwopassdata{\numexpr\currentnoflists+\recurselevel\relax}% + \iftwopassdatafound + \ifnum\itemdatal=\currentitemlevel\relax + \doifelse{c}\itemdatat + {\advance\scratchcounter\itemdatan\relax} + {\exitloop}% + \fi + \else + \exitloop + \fi}% + \edef\currentmaxnofitems{\the\scratchcounter}% + \scratchcounter\zerocount + \doif{c}\currentitemtag + {\doloop + {\splititemtwopassdata{\numexpr\currentnoflists-\recurselevel\relax}% + \iftwopassdatafound + \ifnum\itemdatal=\currentitemlevel\relax + \doifelse{c}\itemdatat + {\advance\scratchcounter\itemdatan\relax} + {\advance\scratchcounter\itemdatan\exitloop}% + \fi + \else + \exitloop + \fi}}% + \advance\scratchcounter\plusone + \edef\currentminnofitems{\the\scratchcounter}% + % [[\currentnofitems,\currentminnofitems,\currentmaxnofitems]] + \fi + \else % new, when no tuo yet + \let\currentnofitems \!!zerocount + \let\currentminnofitems\!!plusone + \let\currentmaxnofitems\!!zerocount + \fi} % [[\currentnofitems,\currentminnofitems,\currentmaxnofitems]] + +% \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\unknownitemreference{0} \let\itemreferences\unknownitemreference + +% #1=level #2=parameter + +\def\getitemparameter #1#2{\csname\??op\currentitemgroup#1#2\endcsname} +\def\setitemparameter #1#2{\@EA\def\csname\??op\currentitemgroup#1#2\endcsname} % #3 -> {#3} +\def\letitemparameter #1#2{\@EA\let\csname\??op\currentitemgroup#1#2\endcsname} + +% works ok but not needed (also possible compatibility problem) +% +% \def\getitemparameter#1#2% +% {\executeifdefined{\??op\currentitemgroup#1#2}% +% {\executeifdefined{\??op\currentitemgroup #2}% +% {\executeifdefined{\??oo #2}% +% {}}}} + +% test this: saves hash entries and is also faster +% +% \let\doinitializeitemgrouplevel\gobbleoneargument % todo ! ! ! + +\def\getitemparameter#1#2% + {\executeifdefined{\??op\currentitemgroup#1#2}% + {\executeifdefined{\??op\currentitemgroup #2}% + {\executeifdefined{\??oo #2}% + {}}}} + +\def\doitemattributes #1{\doattributes{\??op\currentitemgroup#1}} + +\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\textlistitem\else\dosomebreak#1\fi} +% +% s-pre-61 / pre-dis, test extensively, 2004/5 + +\def\doitembreak#1{\ifconditional\optimizelistitem\ifconditional\textlistitem\else\dosomebreak#1\fi\fi} + +\def\initializeitemgroupslevel#1% + {\ifundefined{\@@globalitemsymbol{#1}}% + \edef\itemreferences{\itemreferences,#1}% + \makecounter{\@@itemcounter#1}% + \setevalue{\@@globalitemsymbol{#1}}{#1}% + \fi} + +\def\initializeitemgrouplevel#1% safeguard + {\ifundefined{\??op\currentitemgroup#1\c!width}% + \doinitializeitemgrouplevel{#1}% + \fi} + +\def\doinitializeitemgrouplevel#1% + {\copyparameters + [\??op\currentitemgroup#1][\??oo] + [\c!width,\c!factor,\c!distance,\c!align,\c!symalign,\c!option,% + \c!style,\c!marstyle,\c!symstyle,\c!headstyle,% + \c!color,\c!marcolor,\c!symcolor,\c!headcolor,% + \c!beforehead,\c!afterhead,\c!before,\c!inbetween,\c!after,% + \c!stopper,\c!placestopper,\c!indenting,% + \c!n,\c!inner,\c!symbol,\c!margin,\c!items,% + \c!leftmargin,\c!rightmargin,\c!indentnext,% + \c!command,% + \c!start,\c!lefttext,\c!righttext]} + +\def\setupitemgroups + {\dosingleargument\dosetupitemgroups} + +\def\dosetupitemgroups[#1]% still undocumented + {\getparameters[\??oo][\c!levels=4,#1]% + % will change (remove) + \ifnum\@@oolevels>\maxitemdepth + \maxitemdepth\@@oolevels\relax + \dorecurse\maxitemdepth{\initializeitemgroupslevel\recurselevel}% + \fi} + +\def\doitemreference#1,#2,#3\\% + {\ifnum\currentitemlevel>#1\relax + \ifnum#1>\zerocount \tempsymbol \fi + \getvalue{\@@currentitemsymbol{#2}}% + \doitemreference#2,#3\\% + \fi} + +\def\itemreference + {\expandafter\doitemreference\itemreferences,,\\} + +\def\packitems + {\ifcase\currentitemlevel \else \settrue\packlistitem \fi} + +\def\dosetupitemgroupvariable[#1]% [#2]% niveau instellingen + {\doifelsenothing{#1} + {\getparameters[\??op\currentitemgroup\currentitemlevel]}% [#2]}% + {\getparameters[\??op\currentitemgroup#1]}}% [#2]}} + +\newconditional\inlinelistitem \setfalse\inlinelistitem + +\def\dododosetupitemgroupconstant[#1][#2#3#4]% * permits [2] + {\global\setitemparameter\currentitemlevel\c!maxwidth{0}% + \processaction + [#2#3#4] + [ \v!packed*=>\packitems, + \v!intro*=>\settrue\introlistitem, % here? not set to false +% no: \v!random*=>\settrue\randomizeitems,% here? not set to false + \v!autointro*=>\settrue\autointrolistitem, + \v!broad*=>\setitemparameter{#1}\c!factor{1}, + #2#3*\v!broad*=>\setitemparameter{#1}\c!factor{#2#3}, + #2*\v!broad*=>\setitemparameter{#1}\c!factor{#2}, + \v!text*=>\settrue\textlistitem + \settrue\inlinelistitem + \settrue\joinedlistitem % \dosetuppackeditemgroup{#1}% + \packitems, + \v!columns*=>\packitems, + \v!before*=>\settrue\beforelistitem, + \v!after*=>\settrue\afterlistitem, + \v!nowhite*=>\settrue\nowhitelistitem, % \def\packeditemspacing{\nowhitespace}, + \v!margin*=>\setitemparameter{#1}\c!width{-2em}, % signal + \v!inmargin*=>\setitemparameter{#1}\c!width{-2em}, % signal + \v!atmargin*=>\doifnot{#1}{1}{\setitemparameter{#1}\c!width{0em}}, % signal + \v!intext*=>\settrue\inlinelistitem, % new + \v!loose*=>\setfalse\optimizelistitem, + \v!fit*=>\settrue\fittinglistitems, + \v!nofit*=>\setfalse\fittinglistitems, + \v!paragraph*=>\settrue\paragraphlistitem + \packitems, + \v!joinedup*=>\settrue\joinedlistitem % \dosetuppackeditemgroup{#1}% + \packitems, + \v!serried*=>\setitemparameter{#1}\c!factor{-1}, + #2#3*\v!serried*=>\setitemparameter{#1}\c!factor{-#2#3}, + #2*\v!serried*=>\setitemparameter{#1}\c!factor{-#2}, + \v!stopper*=>\setitemparameter{#1}\c!placestopper{\v!yes}, % keep {} + \v!unpacked*=>\setfalse\packlistitem, + \v!repeat*=>\settrue\repeatlistitem, % new + \v!reverse*=>\settrue\reverselistitem, + \v!standard*=>\dosetupstandarditemgroup{#1}]} + +\def\dosetupstandarditemgroup#1% + {\getparameters + [\??op\currentitemgroup#1] + [\c!width=1.5em, + \c!factor=0, + \c!distance=.5em, + \c!beforehead=, + \c!afterhead=\blank, + \c!before=\blank, + \c!inbetween=\blank, + \c!after=\blank, + \c!inner=]} + +% \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\dosetuppackeditemgroup#1% +% {\setitemparameter{#1}\c!beforehead{\packeditemspacing}% +% \setitemparameter{#1}\c!afterhead {\packeditemspacing}% +% \setitemparameter{#1}\c!before {\packeditemspacing}% +% \setitemparameter{#1}\c!after {\packeditemspacing}% +% \setitemparameter{#1}\c!inbetween {\packeditemspacing}} + +\def\dosetupitemgroupconstant[#1][#2]% + {\def\dodosetupitemgroupconstant##1% catches empty in [a,b,] handy for xml + {\doifsomething{##1}{\dododosetupitemgroupconstant[#1][##1*]}}% + \processcommacommand[#2]\dodosetupitemgroupconstant} % expansion of #2 is handy for xml + +\def\dododododosetupitemgroup[#1][#2]% + {\doifassignmentelse{#2}% + {\dosetupitemgroupvariable[#1][#2]}% + {\setitemparameter{#1}\c!option{#2}}}% + +\def\dodododosetupitemgroup[#1][#2]% + {\ConvertToConstant\doifnot{#2}{} + {\doifelse{#1}\v!each + {\dorecurse\maxitemdepth{\ExpandFirstAfter\dododododosetupitemgroup[\recurselevel][#2]}} + {\ExpandFirstAfter\dododododosetupitemgroup[#1][#2]}}} + +\def\dododosetupitemgroup[#1][#2]% + {\ConvertToConstant\doifelse{#2}{} + {\ifcase\currentitemlevel\relax + \dodododosetupitemgroup[\v!each][#1]% + \else + \dodododosetupitemgroup[\currentitemlevel][#1]% + \fi} + {\doifelsenothing{#1} + {\dodododosetupitemgroup[\currentitemlevel][#2]} + {\dodododosetupitemgroup[#1][#2]}}} + +\def\dodosetupitemgroup[#1][#2][#3][#4]% + {\pushmacro\currentitemgroup + \def\currentitemgroup{#1}% + \dododosetupitemgroup[#2][#3]% + \ConvertToConstant\doifnot{#4}{} % anders wordt #2 overruled + {\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 + \pluscounter{\@@itemcounter\currentitemlevel}% + \fi\fi} + +\def\setitemlevel#1% + {\ifnum\currentitemlevel>\zerocount + \settrue\firstlistitem + % \expanded{\setitemparameter{\currentitemlevel}{\c!start}{1}}% *** + \doifinset{0}{#1}{\setitemparameter\currentitemlevel\c!start{0}}% *** + \setcounter{\@@itemcounter\currentitemlevel}{\the\numexpr\getitemparameter\currentitemlevel\c!start-1\relax}% *** + \doifelsenothing{\getitemparameter\currentitemlevel\c!start} + {\def\currentitemoffset{1}} + {\def\currentitemoffset{\getitemparameter\currentitemlevel\c!start}% + \letitemparameter\currentitemlevel\c!start\empty}% + \def\tempnumber + {\countervalue{\@@itemcounter\currentitemlevel}}% + \doifelse{\getitemparameter\currentitemlevel\c!placestopper}\v!yes + {\def\tempsymbol{\getitemparameter\currentitemlevel\c!stopper}} + {\let\tempsymbol\empty}% + \fi} + + +\def\actualitemnumber + {\ifconditional\reverselistitem + \convertnumber\currentitemsymbol{\numexpr\currentmaxnofitems+\currentitemoffset-\currentitemnumber+1\relax}% + \else + \convertnumber\currentitemsymbol{\numexpr\currentminnofitems+\currentitemoffset+\currentitemnumber-1\relax}% + \fi} + +% PAS OP: ook 'opelkaar' en zo worden getest, nog eens afvangen! + +\def\unknownitemsymbol{?} + +\def\setitemmark#1% % en pas op: resets \docommand + {\doifsymboldefinedelse{#1} + {\edef\currentitemsymbol{#1}% + \setxvalue{\@@globalitemsymbol\currentitemlevel}{\currentitemsymbol}% + \setgvalue{\@@localitemsymbol \currentitemlevel}{\unknownitemsymbol}% + \def\listitem{\symbol[\currentitemsymbol]}% + \let\@@opsymbol\empty}% \let\docommand\gobbleoneargument} + {\doifconversiondefinedelse{#1} + {\edef\currentitemsymbol{#1}% + \setxvalue{\@@globalitemsymbol\currentitemlevel}{\currentitemsymbol}% + \setgvalue{\@@localitemsymbol\currentitemlevel }{\actualitemnumber }% + \ifconditional\textlistitem + \doifsomething{\getitemparameter\currentitemlevel\c!lefttext} + {\let\tempsymbol\empty}% + \fi + \def\listitem + {\getitemparameter\currentitemlevel + {\ifconditional\textlistitem\c!lefttext\else\c!left\fi}% + \getvalue{\@@localitemsymbol\currentitemlevel}\tempsymbol + \getitemparameter\currentitemlevel + {\ifconditional\textlistitem\c!righttext\else\c!right\fi}}% + \let\@@opsymbol\empty}%\let\docommand\gobbleoneargument} + {}}} + +\def\calculatelistwidth#1#2% distance deals with 'broad' + {#2=\getitemparameter{#1}\c!distance\relax + \ifnum\getitemparameter{#1}\c!factor>\zerocount + \ifdim#2=\zeropoint #2=.5em\fi + \fi + \multiply#2 \getitemparameter{#1}\c!factor + \advance #2 \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 +% \def\currentitemgroup{#1}% +% \ifthirdargument +% \dodostartitemgroup[#2][#3]% +% \else +% \doifassignmentelse{#2} +% {\dodostartitemgroup[][#2]} +% {\dodostartitemgroup[#2][]}% +% \fi} + +\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}% + \initializeitemgrouplevel\currentitemlevel % safeguard + \edef\itemgroupoptions{\getitemparameter\currentitemlevel\c!option}% + \ifx\itemgroupoptions\empty + \edef\itemgroupoptions{#1}% + \else + \doifsomething{#1}{\edef\itemgroupoptions{\itemgroupoptions,#1}}% + \fi + \expanded{\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 + \newcounter\noflistelements + \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{\getitemparameter\currentitemlevel\c!symbol}% + \letgvalueempty{\@@globalitemsymbol\currentitemlevel}% + \global\letitemparameter\currentitemlevel\v!continue\empty + % \setitemmark\@@opsymbol % ** default value + \dosetupitemgroupvariable[\currentitemlevel][#2]} + {\dosetupitemgroupconstant[\currentitemlevel][#1]% + \dosetupitemgroupvariable[\currentitemlevel][#2]% + \doifinsetelse\v!continue{#1}% \noexpand, else problems in non-etex with chinese + {\edef\@@opsymbol{\noexpand\getvalue{\@@globalitemsymbol\currentitemlevel}}% + \getitemparameter\currentitemlevel\v!continue} + {\edef\@@opsymbol{\noexpand\getitemparameter{\currentitemlevel}{\c!symbol}}% + \global\setitemparameter\currentitemlevel\v!continue + {\dosetupitemgroupconstant[\currentitemlevel][#1]% + \dosetupitemgroupvariable[\currentitemlevel][#2]}}% + \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 {\getitemparameter1\c!margin}% + \doadaptleftskip {\getitemparameter1\c!leftmargin}% + \doadaptrightskip{\getitemparameter1\c!rightmargin}% + \fi + \dosetraggedcommand{\getitemparameter\currentitemlevel\c!align}\raggedcommand + \dosetsymalign{\getitemparameter\currentitemlevel\c!symalign}% + \doifsomething{\getitemparameter\currentitemlevel\c!indenting} + {% is \expanded needed? + \expanded{\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=>\!!counta1\relax, + \v!two=>\!!counta2\relax, + \v!three=>\!!counta3\relax, + \v!four=>\!!counta4\relax, + \v!five=>\!!counta5\relax, + \s!unknown=>\@EA\!!counta\getitemparameter\currentitemlevel\c!n]% + \startcolumns + [\c!n=\!!counta, % netter \??op\currentitemlevel\c!n + \c!height=, + \c!rule=\v!off, + \c!balance=\v!yes, + \c!align=\v!no]% + \fi\fi}% +\ifconditional\fittinglistitems + \splititemtwopassdata\currentnoflists + \ifdim\itemdataw sp>\zeropoint + \expanded{\setitemparameter{\currentitemlevel}{\c!width}{\itemdataw sp}}% + \fi +\fi + \calculatelistwidth\currentitemlevel{\dimen0}% + \ifdim\dimen0>\zeropoint\relax + \ifconditional\inlinelistitem\else + \advance\leftskip \dimen0\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 + \doitembreak\allowbreak % toegevoegd + \itemaftercommand % \getitemparameter\currentitemlevel\c!after + % was: \dochecknextindentation\??oo, is now: + \dochecknextindentation{\??op\currentitemgroup\currentitemlevel}% + \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{\doitemattributes\currentitemlevel\c!symstyle\c!symcolor{#1}}% + \settrue\symbollistitem + \itemgroupitem} + +\def\itemgroupedge#1% + {\itemgroupsymbol + {\calculatelistwidth\currentitemlevel{\dimen0}% + \hbox to \dimen0 + {#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 + {\doitemattributes\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{\doitemattributes\currentitemlevel\c!symstyle\c!symcolor{#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{\doitemattributes\currentitemlevel\c!headstyle\c!headcolor{#1}}% + \settrue\symbollistitem + \settrue\txtlistitem + \itemgroupitem} + +\def\itembreak % -10 + {\flushnotes\penalty-5\relax} + +\def\itemnobreak % +5 + {\flushnotes\penalty+5\ifinsidecolumns\else00\fi\relax} + +\def\dodotxtitem + {\scratchdimen\wd8 + \advance \scratchdimen \getitemparameter\currentitemlevel\c!distance\relax + \ifdim\scratchdimen>\dimen0 + \advance\scratchdimen -\dimen0 + \else + \scratchdimen\zeropoint + \fi + \llap{\hbox to \dimen0{\ifconditional\sublistitem\llap{+}\fi\box8\hss}}% was: \hfill + \hskip\scratchdimen} + +\def\optimizelistitemsbreak + {\ifcase\itemcolumndepth \ifconditional\optimizelistitem + \ifcase \currentnofitems \else + \ifnum\currentnofitems=\plusthree + \ifnum\noflistelements>\plusone + \doitembreak\itemnobreak + \fi + \else\ifnum\currentnofitems>\plusthree + \ifnum\noflistelements=\plustwo + \ifconditional\introlistitem + \doitembreak\nobreak + \else + \doitembreak\itemnobreak + \fi + \else\ifnum\currentnofitems=\noflistelements\relax + \doitembreak\itemnobreak + \else\ifnum\noflistelements>\plustwo + \doitembreak\itembreak + \else + \ifconditional\introlistitem\else\doitembreak\itembreak\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 +% \ignorespaces + \increment\noflistelements + \optimizelistitemsbreak + \noindent + \setbox8\hbox + {\ifconditional\headlistitem + \ifconditional\symbollistitem + \symsymbol + \else + \doitemattributes\currentitemlevel\c!headstyle\c!headcolor{\listitem}% + \fi + \else + \ifconditional\symbollistitem + \symsymbol % no attributes, why? + \else + \doitemattributes\currentitemlevel\c!style\c!color{\listitem}% + \fi + \fi}% +\ifconditional\fittinglistitems + \ifdim\wd8>\getitemparameter\currentitemlevel\c!maxwidth sp\relax + \expanded{\global\noexpand\setitemparameter{\currentitemlevel}{\c!maxwidth}{\number\wd8}}% + \fi + \splititemtwopassdata\currentnoflists + \ifdim\itemdataw sp>\zeropoint + \setbox8\simplealignedbox{\getitemparameter\currentitemlevel\c!itemalign}{\itemdataw sp}{\box8}% + \fi +\fi + \doifsomething\doitemdestination + {\setbox8\hbox{\goto{\box8}[\doitemdestination]}}% + \globallet\doitemdestination\empty + \dimen2=\getitemparameter\currentitemlevel\c!width\relax + % new, prevents loops when symbol is (not yet found) graphic + \ht8=\strutheight + \dp8=\strutdepth + % so that content differs per run (esp mp graphics afterwards) + \checkforrepeatedlistitem + \ifdim\dimen2<\zeropoint\relax + \llap{\ifconditional\sublistitem\llap{+}\fi\box8\hskip\leftmargindistance}% + \else + \ifdim\dimen2=\zeropoint\relax + \calculatelistwidth1{\dimen0}% + \else + \calculatelistwidth\currentitemlevel{\dimen0}% + \fi + \ifconditional\textlistitem + \hbox{\ifconditional\sublistitem+\fi\box8\hskip\interwordspace}\nobreak + \else\ifconditional\inlinelistitem + \hbox to \dimen0{\ifconditional\sublistitem\llap{+}\fi\box8\hss}% was: \hfill + \else\ifconditional\txtlistitem + \dodotxtitem + \else + % todo: align+marge binnen de hbox +% \llap{\hbox to \dimen0{\ifconditional\sublistitem\llap{+}\fi\box8\hfill}}% + \llap{\hbox to \dimen0{\ifconditional\sublistitem\llap{+}\fi + \symalignleft + \box8\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 + {\increment\noflistelements + \setbox8\hbox + {\doitemattributes\currentitemlevel\c!style\c!color{\listitem}}% + \checkforrepeatedlistitem + \ignorespaces} + +\def\doitemgroupnoitem + {\doadvanceitem\donolistitem} + +% For Frank Grieshaber and Mojca Miklavec: + +\newconditional\repeatlistitem + +\def\checkforrepeatedlistitem + {\ifnum\currentitemlevel=\plusone + \initializeboxstack{item}% + \fi + \ifconditional\repeatlistitem + \savebox{item}{\currentitemlevel}{\hbox{\copy8}}% + \setbox8\hbox to \wd8 + {\setbox\scratchbox\hbox + {\scratchcounter\currentitemlevel + \advance\scratchcounter\minusone + \dorecurse\scratchcounter{\foundbox{item}{\recurselevel}}}% + \ifnum\currentitemlevel>\plusone + \ifdim\wd\scratchbox>\zeropoint + \hskip-\dimen2 + \box\scratchbox + \fi + \fi + \box8 }% + \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]% + {\ifconditional\textlistitem + % begin of item + \else + \par + \fi +% \ignorespaces + \ifconditional\concatnextitem % new, concat + \doitembreak\nobreak % new, concat + \fi % new, concat + \doadvanceitem + \ifcase\itemcolumndepth \ifnum\noflistelements>0\relax + % wrong, but why was this here in the first place, probably some + % mistaken change when cleaning up: \doitembreak\nobreak + \fi\fi + \ifconditional\firstlistitem + \setfalse\firstlistitem + \begingroup + \ifcase\currentitemlevel + \or % 1 + \ifcase\itemcolumndepth + \ifconditional\introlistitem\doitembreak\nobreak\fi + \itembeforecommand % \getitemparameter\currentitemlevel\c!before + \ifconditional\introlistitem\doitembreak\nobreak\fi + \fi + \else % 2 en hoger + \ifconditional\paragraphlistitem \else + \let\previtemlevel\currentitemlevel + \decrement\previtemlevel + \ifcase\autoitemgroupspacing\relax % nieuw + \itembeforecommand + \or + \doifelsenothing{\itembeforecommand} + {\itembeforecommand} + {\getitemparameter\previtemlevel\c!inbetween}% + \else + \getitemparameter\previtemlevel\c!inbetween % == itemlevel-1 + \fi + \fi + \fi + \else +\ifconditional\textlistitem % was bugged: \inlinelistitem +% \removeunwantedspaces\hskip\interwordspace\!!plus\emwidth\relax % new per 2006/10/20 + \removeunwantedspaces\hskip\emwidth\!!plus\interwordstretch\!!minus\interwordshrink\relax % new per 2006/10/20 +\else + \iteminbetweencommand +\fi + \fi + \ifconditional\concatnextitem % new, concat + \vskip-\lastskip % new, concat + \vskip-\lineheight % new, concat + \nobreak % new, concat + \fi % new, concat +% \ignorespaces + \dolistitem + \relax + \ifconditional\packlistitem + \setupwhitespace[\v!none]% + \fi + \getitemparameter\currentitemlevel\c!inner + \marsymbol + \let\marsymbol\relax + \doifsomething{#1} + {\doifnot\itemreference\unknownitemreference + {\bgroup + \protectconversion + \rawreference\s!lst{#1}\itemreference + \egroup}}% + \strut % added 11-08-99 + \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} + +% \def\complexdoitemgrouphead[#1]#2\par% % beter in \complexdosom hangen met een if +% {\ifconditional\firstlistitem\else\doitembreak\allowbreak\fi +% \ifconditional\packlistitem\else\itembeforeheadcommand\fi +% \ifconditional\firstlistitem\ifconditional\introlistitem\else\ifcase\currentitemlevel % incr in \complexdosom +% \doitembreak\allowbreak +% \fi\fi\fi +% \complexdoitemgroupitem[#1]{\doitemattributes\currentitemlevel\c!headstyle\c!headcolor +% {\ignorespaces#2}}% +% \ifconditional\textlistitem +% \removeunwantedspaces\space\ignorespaces +% \else +% \par +% \fi +% \doitembreak\nobreak +% \ifconditional\packlistitem\else\itemafterheadcommand\fi +% \doitembreak\nobreak +% \noindentation} +% +% the next solution accepts \head test \type{x{x}x} test ... + +\def\dostartitemattributes#1{\dostartattributes{\??op\currentitemgroup#1}} +\def\dostopitemattributes {\dostopattributes} + +\def\complexdoitemgrouphead[#1]% beter in \complexdosom hangen met een if + {\ifconditional\firstlistitem\else\doitembreak\allowbreak\fi + \ifconditional\packlistitem\else\itembeforeheadcommand\fi + \ifconditional\firstlistitem\ifconditional\introlistitem\else\ifcase\currentitemlevel % incr in \complexdosom + \doitembreak\allowbreak + \fi\fi\fi + \complexdoitemgroupitem[#1]% + \bgroup + \dostartitemattributes\currentitemlevel\c!headstyle\c!headcolor\empty + \ignorespaces + \let\par\enditemhead} % brrrr but simple anyway + +\def\enditemhead + {\removeunwantedspaces + \dostopitemattributes + \egroup + \ifconditional\textlistitem + \space\ignorespaces + \else + \par + \fi + \doitembreak\nobreak + \ifconditional\packlistitem\else\itemafterheadcommand\fi + \doitembreak\nobreak + \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}% +% \hangindent\wd\scratchbox +% \box\scratchbox +% \endgroup +% \ignorespaces} + +\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}% + \expanded{\box\scratchbox\endgroup\hangindent\the\wd\scratchbox}% + \ignorespaces} + +\setupitemgroups % undocumented + [\c!levels=6, + \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!color=, + \c!style=, % kan tzt weg + \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!inner=, + \c!n=2, + \c!items=4, + \c!lefttext=(, + \c!righttext=), + \c!start=1, + \c!option=, + \c!command=\defaultitemcommand, + \c!symbol=\currentitemlevel] % \v!niveau + +\def\defineitemgroup + {\dodoubleempty\dodefineitemgroup} + +\def\dodefineitemgroup[#1][#2]% + {\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]}% + \getparameters[\??ig#1][\c!levels=3,#2]% + \ifnum\getvalue{\??ig#1\c!levels}<\maxitemdepth\relax + \setevalue{\??ig#1\c!levels}{\number\maxitemdepth}% + \fi + \dorecurse{\getvalue{\??ig#1\c!levels}}{\initializeitemgrouplevel\recurselevel}% + \popmacro\currentitemgroup}} + +% efficient default itemize as well as upward compatible +% definition: + +\defineitemgroup [\v!itemize] [\c!levels=6] + +% keep these, needed for styles: + +% \def\startitemize {\startitemgroup[\v!itemize]} +% \def\stopitemize {\stopitemgroup} +% \def\setupitemize {\setupitemgroup[\v!itemize]} + +\protect \endinput diff --git a/tex/context/base/strc-itm.mkiv b/tex/context/base/strc-itm.mkiv new file mode 100644 index 000000000..7207494ed --- /dev/null +++ b/tex/context/base/strc-itm.mkiv @@ -0,0 +1,1365 @@ +%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 +\newconditional\indentedfirstlistitem \setfalse\indentedfirstlistitem +\newconditional\inlinelistitem \setfalse\inlinelistitem + +\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}} + +% todo: \dodosetreference -> \dostructurecountercomponent (to be checked) + +\def\dohandleitemreference % we will make a decent number helper + {\ifx\currentitemreference \empty \else + \setnextinternalreference + \ctxlua { jobreferences.setandgetattribute("\s!full", "\referenceprefix","\currentitemreference", + { + metadata = { + kind = "item",% ? + catcodes = \the\catcodetable, + xmlroot = \ifx\currentreferencecoding\s!xml "\xmldocument" \else nil \fi, % only useful when text + }, + references = { + internal = \nextinternalreference, + section = structure.sections.currentid(), + }, + prefixdata = structure.helpers.simplify { + prefix = "\structurecounterparameter\currentitemgroupcounter\c!prefix", + separatorset = "\structurecounterparameter\currentitemgroupcounter\c!prefixseparatorset", + conversion = \!!bs\structurecounterparameter\currentitemgroupcounter\c!prefixconversion\!!es, + conversionset = "\structurecounterparameter\currentitemgroupcounter\c!prefixconversionset", + set = "\structurecounterparameter\currentitemgroupcounter\c!prefixset", + segments = "\structurecounterparameter\currentitemgroupcounter\c!prefixsegments", + % segments = "\askedprefixsegments", + connector = \!!bs\structurecounterparameter\currentitemgroupcounter\c!prefixconnector\!!es, + }, + 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", + }, + }) + }% + \xdef\currentitemattribute{\number\lastdestinationattribute}% + \begingroup\attribute\destinationattribute\currentitemattribute\kern\zeropoint\endgroup % todo + \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 + +\definevspacing[\v!item @0] [penalty:0] % allow +\definevspacing[\v!item @10000] [penalty:10000] % no +\definevspacing[\v!item @-5] [penalty:-5] +\definevspacing[\v!item @5] [penalty:5] +\definevspacing[\v!item @500] [penalty:500] + +\def\doitembreak#1{\ifconditional\optimizelistitem\ifconditional\textlistitem\else#1\fi\fi} + +\def\allowitembreak {\doitembreak\itembreakallow} +\def\noitembreak {\doitembreak\itembreakno} +\def\itembreakspecial {\doitembreak\itembreak} +\def\noitembreakspecial{\doitembreak\itemnobreak} + +\def\itembreakallow{\vspacing[\v!item @0]} +\def\itembreakno {\vspacing[\v!item @10000]} +\def\itembreak {\flushnotes\vspacing[\v!item @-5]} +\def\itemnobreak {\flushnotes\ifinsidecolumns\vspacing[\v!item @5]\else\vspacing[\v!item @500]\fi} + +% cool but wrong: +% +% \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} +% +% so we have: + +\def\initializeitemgrouplevel#1% + {\ifcsname\??op\currentitemgroup#1\s!parent\endcsname + % ok + \else + \setevalue{\??op\currentitemgroup#1\s!parent}{\??op\currentitemgroup}% + \fi} + +\unexpanded\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}} + +\newtoks\everysetupitemgroup + +\unexpanded\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 + \ifx\itemgroupsecond\empty + \let\itemgroupsecond\itemgroupfirst + \let\itemgroupfirst\!!plusone + \fi + \ifcsname\??op:::\itemgroupsecond\endcsname\csname\??op:::\itemgroupsecond\endcsname\fi + \fi} + +\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\itemgroupfirst\empty\def\itemgroupfirst{1}\fi + \letitemparameter\currentitemlevel\c!factor\itemgroupfirst} +\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!paragraph}{\settrue\paragraphlistitem + \packitems} +\setvalue{\??op:::\v!joinedup }{\settrue\joinedlistitem + \packitems} +\setvalue{\??op:::\v!serried }{\edef\itemgroupfirst{-\ifx\itemgroupfirst\empty1\else\itemgroupfirst\fi}% + \letitemparameter\currentitemlevel\c!factor\itemgroupfirst} +\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!factor=0, + \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]}% + \the\everysetupitemgroup + \popmacro\currentitemgroup} + +\def\dosetupitemgroup[#1][#2][#3][#4]% + {\def\docommand##1{\dodosetupitemgroup[##1][#2][#3][#4]}% + \processcommalist[#1]\docommand} + +\unexpanded\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!prefix=\getitemparameter\currentitemlevel\c!prefix, + \c!prefixstopper=\getitemparameter\currentitemlevel\c!prefixstopper, + \c!prefixseparatorset=\getitemparameter\currentitemlevel\c!prefixseparatorset, + \c!prefixconversion=\getitemparameter\currentitemlevel\c!prefixconversion, + \c!prefixconversionset=\getitemparameter\currentitemlevel\c!prefixseparatorset, + \c!prefixset=\getitemparameter\currentitemlevel\c!prefixset, + \c!prefixsegments=\getitemparameter\currentitemlevel\c!prefixsegments, + \c!prefixconnector=\getitemparameter\currentitemlevel\c!prefixconnector, + \c!criterium=\getitemparameter\currentitemlevel\c!criterium, + \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} + +\def\calculatelistwidth#1% + {\ifdim\currentitemmaxwidth>\zeropoint + \itemgrouplistwidth\currentitemmaxwidth + \else\ifnum\getitemparameter#1\c!factor>\zerocount + \itemgrouplistwidth\getitemparameter#1\c!step\relax + \ifdim\itemgrouplistwidth=\zeropoint \itemgrouplistwidth=.5em\fi + \multiply\itemgrouplistwidth \getitemparameter#1\c!factor + \advance\itemgrouplistwidth\getitemparameter#1\c!width\relax + \else + \itemgrouplistwidth\getitemparameter#1\c!width\relax + \fi\fi + \advance\itemgrouplistwidth\getitemparameter#1\c!distance\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 + +\unexpanded\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} + +\unexpanded\def\stopcollectitems + {\ifconditional\randomizeitems + \newcounter\itemcollectcounterdone + \ifnum\itemcollectcounter>\zerocount + \@EAEAEA\flushcollecteditems + \fi + \fi} + +\unexpanded\def\startcollectitems + {\ifconditional\randomizeitems + \newcounter\itemcollectcounter + \letvalue{\e!start\v!item}\collectitemgroupitem + \fi} + +%D End of plugin. + +\ifx\startcolumns\undefined \unexpanded\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]} + +\let\currentitemindenting\empty + +\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[\v!reset,\v!yes,\getitemparameter\currentitemlevel\c!indenting]}}% + % {\normalexpanded{\noexpand\setupindenting[\getitemparameter\currentitemlevel\c!indenting]}}% + % + \edef\currentitemindenting{\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 + +\unexpanded\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 +\newtoks\itemgroupfinalizer + +\def\itemgroupitem + {\the\itemgroupfinalizer + \doitemgroupitem} + +\def\itemgroupnoitem + {\the\itemgroupfinalizer + \doitemgroupnoitem} + +\def\itemgroupbutton[#1]% + {\the\itemgroupfinalizer + \gdef\doitemdestination{#1}% + \itemgroupitem} + +\def\itemgroupdummy + {\the\itemgroupfinalizer + \itemgroupsymbol{\strut}\strut} + +\def\itemgroupsubitem + {\the\itemgroupfinalizer + \settrue\sublistitem + \itemgroupitem} + +\def\itemgroupsymbol#1% + {\the\itemgroupfinalizer + \def\symsymbol{#1}% + \settrue\symbollistitem + \itemgroupitem} + +\def\itemgroupedge#1% + {\the\itemgroupfinalizer + \itemgroupsymbol + {\calculatelistwidth\currentitemlevel + \hbox to \itemgrouplistwidth + {#1\hskip\getitemparameter\currentitemlevel\c!distance}}} + +\def\itemgrouphead + {\the\itemgroupfinalizer + \settrue\headlistitem\doitemgrouphead} + +\def\itemgroupitems + {\the\itemgroupfinalizer + \dosingleempty\doitemgroupitems} + +\def\doitemgroupitems[#1]% + {\itemgroupedge + {\dorecurse{0\getitemparameter\currentitemlevel\c!items}{\listitem\hss}% + \unskip}} + +\def\itemgroupmargin#1% + {\the\itemgroupfinalizer + \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 +% +% beware, we don't group (yet) as we want to keep the left/right skip +% +% \startitemize +% \startitem \stopitem +% some intermediate text that will properly indent +% \startitem \stopitem +% \stopitem +% +% so we need to keep that property + +\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{+\enspace}\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\dodosubitem + {\ifconditional\sublistitem\llap{+\enspace}\fi} + +\def\dodolapitem + {\llap + {\hbox to \itemgrouplistwidth + {\dodosubitem + \symalignleft + \box\itemgroupitembox % can already have a forced widt, only factor handled here + \hfil + \hskip\getitemparameter\currentitemlevel\c!distance}}} + +\def\dolistitem % evt aantal items opslaan per niveau, scheelt zoeken + {\ifconditional\textlistitem + % begin of item + \else + \par + \fi + \advance\noflistelements\plusone + \optimizelistitemsbreak + \setfalse\indentedfirstlistitem + \ifx\currentitemindenting\empty \else + \normalexpanded{\noexpand\setupindenting[\v!reset,\v!yes,\currentitemindenting]}% + \doifnot{\getitemparameter\currentitemlevel\c!alignsymbol}\v!yes + {\ifindentfirstparagraph\settrue\indentedfirstlistitem\fi}% + \fi + \dontleavehmode + \ifconditional\indentedfirstlistitem + \hskip-\parindent + \fi + \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}% + \doifsomething\doitemdestination + {\setbox\itemgroupitembox\hbox{\directgotobox{\box\itemgroupitembox}[\doitemdestination]}}% + \itemgroupaskedwidth\getitemparameter\currentitemlevel\c!width\relax + \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} + {\dimexpr\currentitemmaxwidth+\getitemparameter\currentitemlevel\c!distance\relax} + {\box\itemgroupitembox\hskip\getitemparameter\currentitemlevel\c!distance}% + \fi + \else\ifdim\itemgroupaskedwidth>\zeropoint + \doifsomething{\getitemparameter\currentitemlevel\c!itemalign} + {\setbox\itemgroupitembox\simplealignedbox + {\getitemparameter\currentitemlevel\c!itemalign} + {\dimexpr\itemgroupaskedwidth+\getitemparameter\currentitemlevel\c!distance\relax} + {\box\itemgroupitembox\hskip\getitemparameter\currentitemlevel\c!distance}}% + \fi\fi + \globallet\doitemdestination\empty + % 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{+\enspace}\fi\box\itemgroupitembox\hskip\leftmargindistance}% + \else + \ifdim\itemgroupaskedwidth=\zeropoint\relax + \calculatelistwidth1% + \else + \calculatelistwidth\currentitemlevel + \fi + \ifconditional\textlistitem + \hbox{\ifconditional\sublistitem+\enspace\fi\box\itemgroupitembox\hskip\interwordspace}\nobreak + \else\ifconditional\inlinelistitem + \hbox to \itemgrouplistwidth{\ifconditional\sublistitem\llap{+\enspace}\fi\box\itemgroupitembox\hss}% was: \hfill + \else\ifconditional\txtlistitem + \dodotxtitem + \else + \dodolapitem + \fi\fi\fi + \fi + \setevalue{\@@currentitemsymbol\currentitemlevel}% + {\getvalue{\@@localitemsymbol\currentitemlevel}}% still problems with \uchar ? + %{\noexpand\getvalue{\@@localitemsymbol\currentitemlevel}}% no, spoils subrefs + \setfalse\headlistitem + \setfalse\sublistitem + \setfalse\symbollistitem + \EveryPar{\ignorespaces}% needed ? + \ifconditional\indentedfirstlistitem + \hskip\parindent + \fi + \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 + \let\currentrepeatstart\currentitemlevel + \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 + \ifhmode + % WS: make the distance between items customizable, think about better default values -> see itemize-1.tex + \normalexpanded{\doassigntextitemdistance{\getitemparameter\currentitemlevel\c!textdistance}}% HH: moved out and made configurable (sort of) + \removeunwantedspaces\hskip\textitemdistance\relax + \fi + \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 + \setfalse\concatnextitem % new, concat + \nobreak % else problems with intext items + \hskip\itemsignal % new, concat + \getitemparameter\currentitemlevel\c!command} % \defaultitemcommand + +% \startitemize[text][space=medium] +% \item one \item two \item three +% \stopitemize + +\setvalue{\??op:\??op:\c!textdistance:\v!none}% + {\def\textitemdistance{\zeropoint}} + +\def\doassigngiventextitemdistance#1% + {\assignvalue + {#1}% + \textitemdistance + {.5\interwordspace\!!plus.5\emwidth}% + {\interwordspace \!!plus \emwidth}% + {\emwidth \!!plus \interwordstretch\!!minus\interwordshrink}} + +\unexpanded\def\doassigntextitemdistance#1% + {\ifcsname\??op:\??op:\c!textdistance:#1\endcsname + \csname\??op:\??op:\c!textdistance:#1\endcsname + \else + \doassigngiventextitemdistance{#1}% + \fi} + +\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 ... + +\let\doenditemhead\relax + +\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 + \itemgroupfinalizer{\enditemhead}% + \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!criterium=\v!all, % permits 0 and negative numbers + %\c!option=, + \c!textdistance=\v!big, + \c!command=\defaultitemcommand, + \c!indenting=\v!next, + %\c!alignsymbol=v!no, + \c!symbol=\currentitemlevel] + +% new: + +\setupitemgroups + [\c!step=.5em, % deals with broad + \c!distance=\zeropoint] + +\setupitemgroups + [\c!prefix=\v!no, +% \c!prefixstopper=., +% \c!prefixseparatorset=, +% \c!prefixconversion=, +% \c!prefixconversionset=, +% \c!prefixset=, +% \c!prefixsegments=1:100, + \c!prefixconnector=., + % + \c!numberseparatorset=, + \c!numberconversionset=, + \c!numberstopper=., + \c!numbersegments=1] + +\defineitemgroup [\v!itemize] + +\protect \endinput diff --git a/tex/context/base/strc-lnt.mkii b/tex/context/base/strc-lnt.mkii new file mode 100644 index 000000000..ef09842cd --- /dev/null +++ b/tex/context/base/strc-lnt.mkii @@ -0,0 +1,197 @@ +%D \module +%D [ file=strc-lnt, +%D version=2002.05.10, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Line Notes, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Line Notes} + +%D This module loads on top of the footnote and line numbering macros. + +\unprotect + +\newcounter\linenotecounter +\newtoks \collectedlinenotes +\newif \iftracelinenotes + +\appendtoks + \the\collectedlinenotes +\to \everylinenumber + +\appendtoks + \global\collectedlinenotes\emptytoks +\to \beforeeverylinenumbering + +\def\dohandlelinenote#1#2#3% + {\bgroup + \expanded{\beforesplitstring#2}\at--\to\linenotelinenumber + \ifnum\linenotelinenumber=\linenumber\relax + % todo: \onlyfootnote{#2}{#3}% == configurable + % \setupnote[#1][\c!numbercommand=\gobbleoneargument]% + % \setnotetext[#1]{\rawreference\s!fnt{\s!fnt:f:\number\internalnotereference}{}#2: #3}% + \def\linenotelinenumber##1{#2}% + \setupnote[#1][\c!numbercommand=\linenotelinenumber,\c!textcommand=\gobbleoneargument]% + \setnote[#1]{#3}% + \fi + \egroup} + +\def\dotracedlinenote#1% + {\iftracelinenotes + \hbox to \zeropoint + {\forgetall + \localcolortrue + \hsize\zeropoint + \hss + \vbox to \strutheight{\llap{\red\infofont\setstrut\linenotecounter}\vss}% + {\color[blue]{\vl}}% + \vbox to \strutheight{\rlap{\red\infofont\setstrut#1}\vss}% + \hss}% + \prewordbreak + \fi} + +\def\dolinenote#1#2% + {\doglobal\increment\linenotecounter + \doifreferencefoundelse{\??rr:\linenotecounter}% + {\expanded{\doglobal\noexpand\appendtoks\noexpand\dohandlelinenote + {#1}{\currenttextreference}}{#2}\to\collectedlinenotes} + \donothing + \dotracedlinenote\empty + \expanded{\someline[\??rr:\linenotecounter]}} + +\def\dostartlinenote#1[#2]#3% + {\doifreferencefoundelse{\??rr:#2}% + {\expanded{\doglobal\noexpand\appendtoks\noexpand\dohandlelinenote + {#1}{\currenttextreference}}{#3}\to\collectedlinenotes} + \donothing + \dotracedlinenote{#2}% + \startline[\??rr:#2]} + +\def\dostoplinenote#1[#2]% + {\stopline[\??rr:#2]} + +% defining them + +\def\definelinenote + {\dodoubleempty\dodefinelinenote} + +\def\dodefinelinenote[#1][#2]% + {\definenote[#1][#2]% + \setvalue {#1}{\dolinenote {#1}}% + \setvalue{\e!start#1}{\dostartlinenote{#1}}% + \setvalue{\e!stop #1}{\dostoplinenote {#1}}} + +\def\setuplinenote % convenient + {\setupnote} + +% We predefine one, namely \type {\linenote} cum suis. + +\definelinenote[\v!linenote] + +% \startbuffer[test] +% \startlinenumbering[100] +% test \linenote {oeps} test test test test test test +% test \startlinenote [well] {oeps} test test test test test test +% test \linenote {oeps} test test test test test test +% test \linenote {oeps} test test test test test test +% test \linenote {oeps} test test test test test test +% test \linenote {oeps} test test test test test test +% test \stoplinenote [well] test test test test test test +% \stoplinenumbering +% \stopbuffer +% +% \setupnotedefinition[linenote] [location=serried,distance=.5em] +% +% {\typebuffer[test] \getbuffer[test]} \page +% +% \startbuffer[setup] +% \setuplinenumbering +% [align=left] +% \stopbuffer +% +% {\typebuffer[setup] \getbuffer[setup,test]} \page +% +% \startbuffer[setup] +% \setuplinenumbering +% [width=1em, +% align=left] +% \stopbuffer +% +% {\typebuffer[setup] \getbuffer[setup,test]} \page +% +% \startbuffer[setup] +% \setuplinenumbering +% [width=2em, +% distance=.5em, +% align=left] +% \stopbuffer +% +% {\typebuffer[setup] \getbuffer[setup,test]} \page +% +% \startbuffer[setup] +% \setuplinenumbering +% [width=2em, +% align=middle] +% \stopbuffer +% +% {\typebuffer[setup] \getbuffer[setup,test]} \page +% +% \startbuffer[setup] +% \setuplinenumbering +% [conversion=romannumerals, +% start=1, +% step=1, +% location=text, +% style=slanted, +% color=blue, +% width=1.5em] +% \stopbuffer +% +% {\typebuffer[setup] \startnarrower\getbuffer[setup,test]\stopnarrower} \page +% +% \startbuffer[setup] +% \setuplinenumbering +% [width=4em, +% left=--, +% right=--, +% align=middle] +% \stopbuffer +% +% {\typebuffer[setup] \getbuffer[setup,test]} \page +% +% \startbuffer[setup-1] +% \setuplinenumbering +% [style=\bfxx, +% command=\WatchThis] +% \stopbuffer +% +% \startbuffer[setup-2] +% \def\WatchThis#1% +% {\ifodd\linenumber +% \definecolor[linecolor][red]% +% \else +% \definecolor[linecolor][green]% +% \fi +% \inframed +% [offset=1pt,frame=off,background=color,backgroundcolor=linecolor] +% {#1}} +% \stopbuffer +% +% {\typebuffer[setup-1,setup-2] \getbuffer[setup-1,setup-2,test]} \page +% +% \startbuffer[setup-1] +% \setuplinenumbering +% [location=inright, +% style=\bfxx, +% command=\WatchThis] +% \stopbuffer +% +% {\typebuffer[setup-1] \getbuffer[setup-1,setup-2,test]} \page + +\protect \endinput diff --git a/tex/context/base/strc-lnt.mkiv b/tex/context/base/strc-lnt.mkiv new file mode 100644 index 000000000..0df44294b --- /dev/null +++ b/tex/context/base/strc-lnt.mkiv @@ -0,0 +1,173 @@ +%D \module +%D [ file=strc-lnt, +%D version=2002.05.10, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Line Notes, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Line Notes} + +%D This module loads on top of the footnote and line numbering macros. + +\unprotect + +\newcounter\linenotecounter \newif\iftracelinenotes % will be tracker + +\def\dohandlelinenote#1#2#3% + {\bgroup + \def\linenotelinenumber##1{\inlinerange[#2]}% ##1 == order + \setupnote[ln:#1][\c!numbercommand=\linenotelinenumber,\c!textcommand=\gobbleoneargument]% todo: deep hook + \setnote[ln:#1]{#3}% + \egroup} + +\def\dotracedlinenote#1% + {\iftracelinenotes + \hbox to \zeropoint + {\forgetall + \hsize\zeropoint + \hss + \vbox to \strutheight{\llap{\red\infofont\setstrut\linenotecounter}\vss}% + {\color[blue]{\vl}}% + \vbox to \strutheight{\rlap{\red\infofont\setstrut#1}\vss}% + \hss}% + \prewordbreak + \fi} + +\def\dolinenote#1#2% + {\doglobal\increment\linenotecounter + \dohandlelinenote{#1}{\linenotecounter}{#2}% + \dotracedlinenote\empty + \expanded{\someline[\linenotecounter]}} + +\def\dostartlinenote#1[#2]#3% + {\doglobal\increment\linenotecounter + \dohandlelinenote{#1}{#2}{#3}% + \dotracedlinenote{#2}% + \startline[#2]} + +\def\dostoplinenote#1[#2]% + {\stopline[#2]} + +\unexpanded\def\definelinenote + {\dodoubleempty\dodefinelinenote} + +\def\dodefinelinenote[#1][#2]% + {\definenote[ln:#1][#2]% + \setuvalue {#1}{\dolinenote {#1}}% + \setuvalue{\e!start#1}{\dostartlinenote{#1}}% + \setuvalue{\e!stop #1}{\dostoplinenote {#1}}} + +\unexpanded\def\setuplinenote[#1]% convenient + {\setupnote[ln:#1]} + +% We predefine one, namely \type {\linenote} cum suis. + +\definelinenote[\v!linenote] + +% \startbuffer[test] +% \startlinenumbering[100] +% test \linenote {oeps} test test test test test test +% test \startlinenote [well] {oeps} test test test test test test +% test \linenote {oeps} test test test test test test +% test \linenote {oeps} test test test test test test +% test \linenote {oeps} test test test test test test +% test \linenote {oeps} test test test test test test +% test \stoplinenote [well] test test test test test test +% \stoplinenumbering +% \stopbuffer +% +% \setupnotedefinition[linenote] [location=serried,distance=.5em] +% +% {\typebuffer[test] \getbuffer[test]} \page +% +% \startbuffer[setup] +% \setuplinenumbering +% [align=left] +% \stopbuffer +% +% {\typebuffer[setup] \getbuffer[setup,test]} \page +% +% \startbuffer[setup] +% \setuplinenumbering +% [width=1em, +% align=left] +% \stopbuffer +% +% {\typebuffer[setup] \getbuffer[setup,test]} \page +% +% \startbuffer[setup] +% \setuplinenumbering +% [width=2em, +% distance=.5em, +% align=left] +% \stopbuffer +% +% {\typebuffer[setup] \getbuffer[setup,test]} \page +% +% \startbuffer[setup] +% \setuplinenumbering +% [width=2em, +% align=middle] +% \stopbuffer +% +% {\typebuffer[setup] \getbuffer[setup,test]} \page +% +% \startbuffer[setup] +% \setuplinenumbering +% [conversion=romannumerals, +% start=1, +% step=1, +% location=text, +% style=slanted, +% color=blue, +% width=1.5em] +% \stopbuffer +% +% {\typebuffer[setup] \startnarrower\getbuffer[setup,test]\stopnarrower} \page +% +% \startbuffer[setup] +% \setuplinenumbering +% [width=4em, +% left=--, +% right=--, +% align=middle] +% \stopbuffer +% +% {\typebuffer[setup] \getbuffer[setup,test]} \page +% +% \startbuffer[setup-1] +% \setuplinenumbering +% [style=\bfxx, +% command=\WatchThis] +% \stopbuffer +% +% \startbuffer[setup-2] +% \def\WatchThis#1% +% {\ifodd\linenumber +% \definecolor[linecolor][red]% +% \else +% \definecolor[linecolor][green]% +% \fi +% \inframed +% [offset=1pt,frame=off,background=color,backgroundcolor=linecolor] +% {#1}} +% \stopbuffer +% +% {\typebuffer[setup-1,setup-2] \getbuffer[setup-1,setup-2,test]} \page +% +% \startbuffer[setup-1] +% \setuplinenumbering +% [location=inright, +% style=\bfxx, +% command=\WatchThis] +% \stopbuffer +% +% {\typebuffer[setup-1] \getbuffer[setup-1,setup-2,test]} \page + +\protect \endinput diff --git a/tex/context/base/strc-lst.lua b/tex/context/base/strc-lst.lua new file mode 100644 index 000000000..fefbe52ce --- /dev/null +++ b/tex/context/base/strc-lst.lua @@ -0,0 +1,486 @@ +if not modules then modules = { } end modules ['strc-lst'] = { + version = 1.001, + comment = "companion to strc-lst.mkiv", + 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, gmatch, gsub = string.format, string.gmatch, string.gsub +local tonumber = tonumber +local texsprint, texprint, texwrite, texcount = tex.sprint, tex.print, tex.write, tex.count +local concat, insert, remove = table.concat, table.insert, table.remove +local lpegmatch = lpeg.match + +local trace_lists = false trackers.register("structure.lists", function(v) trace_lists = v end) + +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 matching_till_depth, number_at_depth = sections.matching_till_depth, sections.number_at_depth + +local function initializer() + -- create a cross reference between internal references + -- and list entries + local collected = lists.collected + local internals = jobreferences.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, 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 + -- + l.directives = nil -- might change + -- save in the right order (happens at shipout) + lists.tobesaved[#lists.tobesaved+1] = l + -- default enhancer (cross referencing) + l.references.realpage = texcount.realpageno + -- 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 + +local nesting = { } + +function lists.pushnesting(i) + local r = lists.result[i] + local name = r.metadata.name + local numberdata = r and r.numberdata + local n = (numberdata and numberdata.numbers[sections.getlevel(name)]) or 0 + insert(nesting, { number = n, name = name, result = lists.result, parent = r }) +end + +function lists.popnesting() + local old = remove(nesting) + lists.result = old.result +end + +-- will be split + +local function filter_collected(names, criterium, number, collected, nested) + local numbers, depth = documents.data.numbers, documents.data.depth + local hash, result, all, detail = { }, { }, not names or names == "" or names == variables.all, nil + names, criterium = gsub(names," ",""), gsub(criterium," ","") + if trace_lists then + logs.report("lists","filtering names: %s, criterium: %s, number: %s",names,criterium,number or "-") + end + if not all then + for s in gmatch(names,"[^, ]+") do -- sort of settings to hash + hash[s] = true + end + end + if criterium == variables.intro then + -- special case, no structure yet + for i=1,#collected do + local v = collected[i] + local r = v.references + if r and r.section == 0 then + result[#result+1] = v + end + end + elseif 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 + if depth == 0 then + return filter_collected(names,variables.intro,number,collected) + else + 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 + end + elseif criterium == variables.here then + -- this is quite dirty ... as cnumbers is not sparse we can misuse #cnumbers + if depth == 0 then + return filter_collected(names,variables.intro,number,collected) + else + 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 +--~ print(#cnumbers, depth, table.concat(cnumbers)) + 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 + end + elseif criterium == variables.previous then + if depth == 0 then + return filter_collected(names,variables.intro,number,collected) + else + 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 + end + elseif criterium == variables["local"] then -- not yet ok + local nested = nesting[#nesting] + if nested then + return filter_collected(names,nested.name,nested.number,collected,nested) + elseif 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 + -- not the same as register + local depth = sections.getlevel(criterium) + local number = tonumber(number) or number_at_depth(depth) or 0 + if trace_lists then + local t = sections.numbers() + detail = format("depth: %s, number: %s, numbers: %s, startset: %s",depth,number,(#t>0 and concat(t,".",1,depth)) or "?",#collected) + end + if number > 0 then + local parent = nested and nested.parent and nested.parent.numberdata.numbers -- so local as well as nested + 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 + local metadata = v.metadata + local cnumbers = sectionnumber.numbers + if cnumbers then + if (all or hash[metadata.name or false]) and #cnumbers >= depth and matching_till_depth(depth,cnumbers,parent) then + result[#result+1] = v + end + end + end + end + end + end + end + if trace_lists then + if detail then + logs.report("lists","criterium: %s, %s, found: %s",criterium,detail,#result) + else + logs.report("lists","criterium: %s, found: %s",criterium,#result) + 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)) +--~ context.processlistofstructure(m.name,m.kind,i) + end +end + +function lists.analyze(...) + lists.result = lists.filter(...) +end + +function lists.userdata(name,r,tag) -- to tex (todo: xml) + local result = lists.result[r] + if result then + local userdata, metadata = result.userdata, result.metadata + local str = userdata and userdata[tag] + if str then + texsprint(metadata and metadata.catcodes or ctxcatcodes,str) + end + end +end + +function lists.uservalue(name,r,tag,default) -- to lua + 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(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] + -- hm, prefixnumber? + 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 + helpers.title(titledata[tag] or titledata.list or titledata.title or "",data.metadata) + end + end +end + +function lists.savedtitle(name,n,tag) + local data = cached[tonumber(n)] + if data then + local titledata = data.titledata + if titledata then + helpers.title(titledata[tag] or titledata.title or "",data.metadata) +--~ 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 +--~ print(name,n,table.serialize(numberdata)) + 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 +--~ print(table.serialize(numberspec)) + sections.typesetnumber(numberdata,"number",numberspec or false,numberdata or false) + end + end +end + +-- todo, do this in references namespace ordered instead (this is an experiment) +-- +-- also see lpdf-ano (maybe move this there) + +local splitter = lpeg.splitat(":") + +function jobreferences.specials.order(var,actions) -- jobreferences.specials ! + local operation = var.operation + if operation then + local kind, name, n = lpegmatch(splitter,operation) + local order = lists.ordered[kind] + order = order and order[name] + local v = order[tonumber(n)] + local r = v and v.references.realpage + if r then + actions.realpage = r + var.operation = r -- brrr, but test anyway + return jobreferences.specials.page(var,actions) + end + end +end diff --git a/tex/context/base/strc-lst.mkii b/tex/context/base/strc-lst.mkii new file mode 100644 index 000000000..527966354 --- /dev/null +++ b/tex/context/base/strc-lst.mkii @@ -0,0 +1,1150 @@ +%D \module +%D [ file=strc-lst, +%D version=1997.03.31, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Lists, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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} + +\unprotect + +% \getlistlevel[hoofdstuk]\test{0} \test + +% can be made faster if needed + +\def\getlistlevel[#1]#2#3% [list] \variable \default + {\doifdefinedelse{\??ko#1\c!section} + {\edef#2{\getvalue{\??ko#1\c!section}}% + \doifdefinedelse{\??se#2\c!level} + {\edef#2{\getvalue{\??se#2\c!level}}} + {\edef#2{#3}}} + {\edef#2{#3}}} + +% Auto cross document links work by either using logical or +% page references, depending on the general settings. The +% locations are stored in global references where the auto tag +% number uses the text container. We use reference mapping +% (define reference) to keep track of the current ref. + +% \@@sectie == current level + +\def\dowritetolist#1% + {\doifelsevalue{\??li#1\c!state}\v!start + \dodowritetolist\gobblefourarguments{#1}} + +\long\def\dodowritetolist#1#2#3#4% + {\begingroup + \expanded{\everylistentry\emptytoks\the\everylistentry}% \emptytoks, else loop + \def\currentlist{#1}% evt naar dowritetolist + \defconvertexpanded\asciilistentry{\getvalue{\??li\currentlist\c!expansion}}{#3}% + \makesectionformat + \doifelse\@@nmstate\v!start + {\def\dopagenummer{\noexpand\pagenumber}} + {\let\dopagenummer\!!zerocount}% + % niet waterdicht, wat te doen met figuren en zo + % first hack: scheelt rommel, second hack: alleen koppen + \doifelsevalue{\??rf\currentlist\c!state}\v!start + {\doif{\@@sectionlevel\@@sectie}{0}\autocrossdocumentfalse} + {\autocrossdocumentfalse}% + % weak and inefficient + \ifautocrossdocument + \bgroup + \thisisnextinternal\currentlist + %\thisisdestination{\currentlist::\sectionformat}% + \expanded{\setsectieenkoppeling{\currentlist}}% + \edef\currentlevel{\@@sectionlevel\@@sectie}% + \processcommacommand[\crossdocumentreferences]\dododowritetolist + \egroup + \else + \thisisnextinternal\currentlist + \fi + \expanded + {\writeutilitycommand % todo: also an immediate option + {\noexpand\listentry + {\currentlist}% + {\nextinternalreference}% + {#2}% + {\asciilistentry}% + {\sectionformat\sectionseparator\sectionseparator\dopagenummer}% + {\noexpand\realfolio}}}% + \endgroup} + +\def\dododowritetolist#1% + {\def\docommand##1% + {\doifvalue{\??rf##1\c!state}\v!start + {\setsectieenkoppeling{##1}% + \def\level{\@@sectionlevel\@@sectie}% + \ifnum\level>\currentlevel + \expanded{\definereference[#1::##1][\v!none]}% + \else\ifnum\level=\currentlevel + \expanded{\definereference[#1::##1][#1::{##1::\sectionformat}]}% + \fi\fi}}% + \processcommacommand[\crossdocumentelements]\docommand} + +% so far + +\def\dowritebetweenlist#1#2% + {\doifvalue{\??li#1\c!state}\v!start + {\begingroup + \defconvertedargument\ascii{#2}% + \makesectionformat + \doifelse{\@@nmstate}\v!start + {\def\dopagenummer{\noexpand\pagenumber}} + {\let\dopagenummer\!!zerocount}% + \expanded + {\writeutilitycommand + {\noexpand\listbetween + {#1}% + {\ascii}% + {\sectionformat\sectionseparator\sectionseparator\dopagenummer}% + {\noexpand\realfolio}}}% + \endgroup}} + +% experimental (no nodes in mvl), needed for naw + +\def\immediatetolist[#1]#2#3#4% + {\begingroup + \defconvertexpanded\asciilistentry{\getvalue{\??li#1\c!expansion}}{#3}% + \makesectionformat + \immediatewriteutilitycommand + {\listentry + {#1}{}{#2}{\asciilistentry}% + {\sectionformat\sectionseparator\sectionseparator\number#4}% + {\realfolio}}% + \endgroup} + +\def\immediatebetweenlist[#1]#2% + {\begingroup + \defconvertedargument\asciilistentry{#2}% + \makesectionformat + \immediatewriteutilitycommand + {\listbetween + {#1}{\asciilistentry}% + {\sectionformat\sectionseparator\sectionseparator0}% + {\realfolio}}% + \endgroup} + +\def\setlistentries + {\def\listentry ##1{\executeifdefined{##1\c!list }\gobblefivearguments }% + \def\listbetween##1{\executeifdefined{##1\c!inbetween}\gobblethreearguments}} + +\def\resetlistentries + {\let\listentry \gobblesixarguments + \let\listbetween\gobblefourarguments} + +\resetlistentries + +\addutilityreset{listentries} + +% old values: +% +% a: \def\listfill {\hskip 1.75em} +% b: \def\listfill {\hskip.5em\hfill} +% c: \def\listfill {\hskip.5em\listdots\hskip.5em} + +% todo: interface them + +% \setvalue{\??li\c!alternative a}% nr - tit - pag +% {\def\listfill {\hskip.25em\relax}% +% \def\listskip {0pt}% +% \def\listwidth {2em}% +% \def\liststretch{10em}} + +% \setvalue{\??li\c!alternative b}% nr - tit - fill - pag +% {\def\listfill {\hfill}% +% \def\listskip {5em}% +% \def\listwidth {2em}% +% \def\liststretch{10em}} + +% \setvalue{\??li\c!alternative c}% nr - tit - dots - pag +% {\def\listfill {\hskip.5em\listdots\hskip.5em\relax}% +% \def\listskip {5em}% +% \def\listwidth {0pt}% +% \def\liststretch{10em}} + +\def\listalternativeparameter#1% + {\csname\??li\??li\listparameter\c!alternative#1\endcsname} + +\def\setuplistalternative[#1]% + {\dodoubleargument\getparameters[\??li\??li#1]} + + % \listfill cum suis will be replaced by the direct call + +\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} + +% \starttext +% \placelist[section][alternative=c] +% \setuplistalternative[c][distance=1em,stretch=0em] +% \placelist[section][alternative=c] +% \section{test} +% \section{\readfile{tufte}{}{}} +% \stoptext + +\setvalue{\??li\c!alternative}{\getvalue{\??li\c!alternative b}} + +\getvalue{\??li\c!alternative} + +\def\setlistparameter#1#2#3{\@EA\def\csname\??li#1#2\endcsname{#3}} % often +\def\listparameter #1{\csname\??li\currentlist#1\endcsname} + +\def\dosetuplist[#1][#2]% slow -) + {\def\docommand##1% + {\getparameters[\??li##1][#2]% + \preparepageprefix{\??li##1}}% + \processcommalist[#1]\docommand} + +\def\setuplist + {\dodoubleargument\dosetuplist} + +\def\dodosetlist#1% + {\def\nolist{\splitsequence{\getvalue{\??li#1\c!limittext}}}% + \setvalue{#1\c!inbetween}{\dobetweenlist{#1}}% + \setvalue{#1\c!list }{\dolistelement{#1}}} + +% \def\dodoresetlist#1% +% {\let\nolist\empty +% \setvalue{#1\c!inbetween}{\gobblefourarguments{#1}}% +% \setvalue{#1\c!list }{\gobblesixarguments {#1}}} + +\def\dodoresetlist#1% + {\let\nolist\empty + \letvalue{#1\c!inbetween}\gobblethreearguments + \letvalue{#1\c!list }\gobblefivearguments} + +\let\nolist\empty + +\def\dodefinelist[#1][#2][#3]% + {\presetlocalframed[\??li#1]% + \getparameters + [\??li#1] + [\c!height=\v!broad, + \c!depth=\v!broad, + \c!offset=0.25em, + \c!maxwidth=, + \c!align=, + \c!state=\v!start, + \c!coupling=\v!off, + \c!criterium=\v!local, + \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, + \v!part\v!number=\v!yes, % nodig ? % v + %\c!prefix=\v!no, % we need to initialize it + \c!label=\v!no, + \c!distance=\!!zeropoint, + \c!separator=\@@koseparator, + \c!limittext=\@@kolimittext, + \c!stopper=, + \c!expansion=]% + \doifassignmentelse{#2} + {\getparameters[\??li#1][#2]} + {\ConvertToConstant\doifnot{#2}{} % not \doifsomething ivm Convert... + {\copyparameters % interactie ? + [\??li#1][\??li#2] + [\c!state,\c!width,\c!alternative,\c!style,\c!color, + \c!textstyle,\c!textcolor,\c!textcommand, + \c!pagestyle,\c!pagecommand,\c!pagecolor, + \c!numberstyle,\c!numbercolor,\c!numbercommand, + \c!headnumber, + \c!pagenumber,\c!pageboundaries,\c!margin,\c!symbol,\c!limittext, + \c!aligntitle,\c!before,\c!after,\c!inbetween,\v!part\c!number,\c!label]% + \getparameters[\??li#1][#3]}}% + \addutilityreset{#1}% + \setvalue{\s!set #1}{\dodosetlist {#1}}% + \setvalue{\s!reset#1}{\dodoresetlist{#1}}} + +\def\definelist + {\dotripleempty\dodefinelist} + +\def\iflijstgeplaatst{\ifutilitydone} % obsolete, is now a mode + +\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} + +\def\doplacerawlist[#1][#2]% + {\begingroup + \dogetcommalistelement1\from#1\to\firstlistelement + \dosetuplist[#1][#2]% + \doifvalue{\??li\firstlistelement\c!coupling}\v!on + {\startlistreferences{#1}}% + \dosettoclevel\??li\firstlistelement + \honorlocalfilterlevel + \doutilities{listentries,#1}\jobname{#1}\relax\par + \stoplistreferences + \dosetlistmode + \endgroup} + +% the simple approach: +% +% \def\dosettoclevel#1#2% +% {\dosetfilterlevel{\getvalue{#1#2\c!criterium}}\empty} +% +% but we want to to support selection by number: +% +% \starttypen +% \placelist[section][criterium=chapter,number=1] \blank +% \placelist[section][criterium=chapter,number=2] \blank +% \placelist[section][criterium=chapter,number=3] \blank +% +% \chapter{first} \section{AA} \section{BB} +% \chapter{second} \section{CC} \section{DD} +% \chapter{third} \section{EE} \section{FF} +% \stoptypen + +\def\dosettoclevel#1#2% todo: check if criterium is headid, else error + {\ifundefined{#1#2\c!number}% + \dosetfilterlevel{\getvalue{#1#2\c!criterium}}\empty + \else + % \doifnot{#2}\v!local ... + \doifelsevaluenothing{#1#2\c!number}% + {\dosetfilterlevel{\getvalue{#1#2\c!criterium}}\empty} + {\setsectieenkoppeling{\getvalue{#1#2\c!criterium}}% + \dosetfilterlevel + {\previoussection\@@sectie}% + {\getvalue{#1#2\c!number}}}% + \fi} + +\def\dosetlistmode + {\ifutilitydone + \setsystemmode \v!list + \else + \resetsystemmode\v!list + \fi} + +\def\dodocompletelist[#1][#2][#3]% enkelvoud, meervoud, instellingen + {\expanded{\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} + +% \let\dohandlelistnumber\firstofoneargument +% +% can be anything, so no \expanded{\separatednumber{#1}} ! + +\def\dohandlelistnumber#1{\separatednumber{#1}} + +\def\listsymbol[#1]#2% + {\begingroup + \def\currentlist{#1}% + \def\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 + {\doifelse{\listparameter\c!prefix}\v!no % ook nog eerste + {\edef\splitlistsymbol{\@EA\removefirstprefix\@EA{\currentlistnumber}}}% one level expansion + {\doifelse{\listparameter\c!prefix}\v!none + {\edef\splitlistsymbol{\@EA\removeallprefixes\@EA{\currentlistnumber}}}% + {\let\splitlistsymbol\currentlistnumber}}% geen \edef ivm 8 bit enz + \doif{\listparameter\c!label}\v!yes{\leftlabeltext\currentlist}% + \strut + \def\numberseparator{\listparameter\c!separator}% overloaded, todo + \@EA\dohandlelistnumber\@EA{\splitlistsymbol}% + \listparameter\c!stopper + \doif{\listparameter\c!label}\v!yes{\rightlabeltext\currentlist}} + +\def\listsymbol@unknown + {\listparameter\c!symbol} + +% so far for list symbols + +\def\@@dodolistelement{dodolistelement} + +\def\dosomelistelement#1#2#3{#1 #2 \translatednumber[#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\dolistelement#1#2#3#4#5#6% pas op: wordt ook elders gedefinieerd + {\doiftoclevelelse[#5]{\dodolistelement{#1}{#2}{#3}{#4}{#5}{#6}}{}} + +\def\dodolistelement#1#2#3#4#5#6% + {\def\currentlist{#1}% + \def\currentlistnumber{#3}% + \getvalue{\@@dodolistelement\listparameter\c!alternative}% + %\showcomposition + \let\@@iawidth\!!zeropoint % moet boolean worden + \bgroup + \edef\listelements + {\listparameter\c!pageboundaries}% + \ExpandBothAfter\doifinset{#3}\listelements + {\showmessage\m!systems{14}{#3}% + \page}% + \egroup + \dontcomplain + \setfullsectionnumber{\??li\currentlist}% + \dosomelistelement{#1}{#2}{#3}{#4}{#5}{#6}% + \global\utilitydonetrue} + +\def\donestedlistattributes#1#2% + {\doifvaluesomething{\??li\currentlist#2} % color + {\resetinteractionparameter\c!color + \resetinteractionparameter\c!contrastcolor}% + \dolistattributes{#1}{#2}} + +\def\dostartlistattributes{\dostartattributes{\??li\currentlist}} +\def\dostoplistattributes {\dostopattributes} +\def\dolistattributes {\doattributes{\??li\currentlist}} + +\def\dodocommandlistelement#1#2#3#4#5#6% + {\doifdefinedelse{\??li#1\c!command} + {\listparameter\c!command + {#3}{#4}{\pageprefix\??li\currentlist[#5]\translatednumber[#5]}} + {[\currentlist: #3 - #4 - \pageprefix\??li\currentlist[#5]\translatednumber[#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 + {\pageprefix\??li\currentlist[#5]% + \translatednumber[#5]}}} + {#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 + {\pageprefix\??li\currentlist[#5]% + \translatednumber[#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 + +% now also in abc + +\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 + \dostartlistattributes\c!style\c!color\empty + \!!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 + {\pageprefix\??li\currentlist[#5]% + \translatednumber[#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 + \dostoplistattributes}}% 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 + {\pageprefix\??li\currentlist[#5]% + \translatednumber[#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?) + \dostartlistattributes\c!style\c!color\empty + \ignorespaces\dontconvertfont\setstrut + \begstrut + \limitatedlistentry{#6}% + \endstrut + \dostoplistattributes}% + \egroup + \par + \listparameter\c!inbetween} + +% better: +% +% \def\linklisttoelement#1#2#3#4% % list location format page data +% {\ifautocrossdocument +% \gotodestination{}{}{\currentlist::\@@filterblocknumberpart[#2]}{#3}{#4}% +% \else +% \gotonextinternal\currentlist{#1}{#3}{#4}% +% \fi} +% +% but for the moment: + +\def\linklisttoelement#1#2#3#4% % list location format page data + {\gotonextinternal\currentlist{#1}{#3}{#4}} + +\def\writetolist[#1]#2#3% + {\doifsomething{#1} + {\defconvertedargument\firstlistelement{#2}% + \@EA\dowritetolist\@EA{#1}{\firstlistelement}{#3}{\v!head}}} + +\def\dobetweenlist#1#2#3#4% pas op: wordt ook elders gedefinieerd + {\doiftoclevelelse[#3]{#2}{}} + +\def\writebetweenlist[#1]#2% + {\@EA\dowritebetweenlist\@EA{#1}{#2}} % #2 weg en \expanded + +% NOG ENGELS MAKEN + +\def\listlength{\utilitylistlength} +\def\listwidth {\utilitylistwidth} +\def\listheight{\utilitylistheight} + +\def\utilitylistlength {0} +\def\utilitylistwidth {0pt} +\def\utilitylistheight {0pt} + +\def\dolistelementX#1#2#3#4#5#6% + {\doiftoclevelelse[#5] + {\doglobal\increment\utilitylistlength + \hbox + {\dolistattributes\c!textstyle\c!textcolor + {\let\\=\newlineinlist + \dontconvertfont + \listparameter\c!textcommand{#4}}}% + \global\utilitydonetrue} + {}} + +\def\dodeterminelistcharacteristics[#1][#2]% + {\begingroup + \doglobal\newcounter\utilitylistlength + \let\dolistelement\dolistelementX + \dosetuplist[#1][#2]% + \dogetcommalistelement1\from#1\to\commalistelement + \dosettoclevel\??li\commalistelement + \setbox0\vbox{\doutilities{listentries,#1}\jobname{#1}\relax\par}% + \xdef\utilitylistheight{\the\ht0}% + \xdef\utilitylistwidth {\the\wd0}% + \endgroup + \dosetlistmode} + +\def\determinelistcharacteristics + {\dodoubleempty\dodeterminelistcharacteristics} + +% \definerreferencelist +% [externalfigure] +% [command=\showbigfigure, +% before=\page, +% after=\page] +% +% \definereferencelist +% [externaltable] +% [command=\showbigtable, +% before=\page, +% after=\page] +% +% \def\showbigfigure#1% +% {\externalfigure[#1][frame=on,factor=max]} +% +% \def\showbigtable#1% +% {\switchtobodyfont[12pt]\getbuffer[#1]} +% +% \writetoreferencelist[externalfigure]{koe} {\externalfigure[koe] [width=3cm,frame=on]} +% \writetoreferencelist[externalfigure]{paard}{\externalfigure[paard][width=3cm,frame=on]} +% +% \startbuffer[kanweg] +% \starttable[|||] +% \HL +% \VL test \VL test \VL\SR +% \HL +% \VL test \VL test \VL\FR +% \VL test \VL test \VL\MR +% \VL test \VL test \VL\LR +% \HL +% \stoptable +% \stopbuffer +% +% \writetoreferencelist[externaltable]{kanweg}{\switchtbodyfont[5pt]\getbuffer[kanweg]} +% +% \placereferencelist[externalfigure,externaltable] + +% algemeen + +\def\referencebutton#1[#2]% + {\hbox\bgroup % the \hbox is needed to bypass + \let\referenceprefix\empty % \dontleavehmode in \gotobox + \setupinteraction[\c!color=,\c!contrastcolor=,\c!strut=]% + \setupreferencing[\c!prefix=]% + \gotobox{\hbox{\ignorespaces#1}}[#2]% + \egroup} + +\newcounter\referencecounter + +\def\doreferencelistelement#1#2#3#4#5% + {\doiftoclevelelse[#4] + {\getvalue{\??rl#1\c!before}% + \referencebutton + {\getvalue{\??rl#1\c!command}{#3}\pagereference[\r!to#2]}% + [\r!from#2]% + \global\utilitydonetrue + \getvalue{\??rl#1\c!after}} + {}} + +\def\doplacereferencelist[#1][#2]% + {\begingroup + \setupreferencelist[#1][#2,\c!state=\v!stop]% + \dogetcommalistelement1\from#1\to\commalistelement + \dosettoclevel\??rl\commalistelement + \doutilities{listentries,#1}\jobname{#1}\relax\par + \endgroup} + +\def\placereferencelist + {\dodoubleempty\doplacereferencelist} + +\def\dowritetoreferencelist#1#2#3% + {\doifvalue{\??rl#1\c!state}\v!start + {\begingroup + \makesectionformat + \doifelse{\@@nmstate}\v!start + {\def\dopagenummer{\noexpand\pagenumber}} + {\let\dopagenummer\!!zerocount}% + \expanded + {\writeutilitycommand% + {\noexpand\referencelistentry% + {#1}% tag + {#2}% number + {#3}% data + {\sectionformat\sectionseparator\sectionseparator\dopagenummer}% + {\noexpand\realfolio}}}% + \endgroup}} + +\def\writetoreferencelist[#1]#2% #1=class #2=data #3=visualization + {\dowithnextbox + {\doifelsevalue{\??rl#1\c!state}\v!start + {\doglobal\increment\referencecounter % must be resolved due to #2 + \referencebutton + {\flushnextbox + \pagereference[\r!from\referencecounter]% + \dowritetoreferencelist{#1}{\referencecounter}{#2}}% + [\r!to\referencecounter]} + {\flushnextbox}} + \hbox} % \vbox ? + +\def\referencelistentry#1% + {\executeifdefined{#1\c!list}\gobblefourarguments} + +\def\dodosetreferencelist#1% + {\setvalue{#1\c!list}{\doreferencelistelement{#1}}} + +\def\dodoresetreferencelist#1% + {\setvalue{#1\c!list}{\gobblefourarguments}} + +\def\dodefinereferencelist[#1][#2]% + {\setupreferencelist[#1] + [\c!command=, + \c!state=\v!start, + \c!criterium=\v!all, + \c!before=, + \c!after=, + #2]% + \resetcounter{#1}% + \addutilityreset{#1}% + \setvalue{\s!set #1}{\dodosetreferencelist {#1}}% + \setvalue{\s!reset#1}{\dodoresetreferencelist{#1}}} + +\def\definereferencelist + {\dodoubleempty\dodefinereferencelist} + +\def\dosetupreferencelist[#1][#2]% + {\getparameters[\??rl#1][#2]} + +\def\setupreferencelist + {\dodoubleempty\dosetupreferencelist} + +\def\dosetupcombinedlist[#1][#2]% + {\getparameters[\??ih#1][#2]% + \expanded{\setuplist[\getvalue{\??ih#1\c!list}]}[#2]} + +\def\setupcombinedlist + {\dodoubleargument\dosetupcombinedlist} + +\def\doplacecombinedlist[#1][#2]% + {\begingroup + \getparameters[\??ih#1][#2]% + \dosettoclevel\??ih{#1}% + \edef\combinedlist{\getvalue{\??ih#1\c!list}}% + \doifelsevalue{\??ih#1\c!level}\v!current % + {\!!counta=0\@@kolevel} % hm: \@@kolevel + {\fullexpandoneargafter\doifnumberelse{\getvalue{\??ih#1\c!level}}% in verband + {\!!counta\getvalue{\??ih#1\c!level}% met de vorige implementatie + \advance\!!counta \plusone % accepteren we ook nummers (0==deel) + \getfromcommacommand[\combinedlist][\!!counta]% + \edef\maximumlist{\commalistelement}}% + {\edef\maximumlist{\getvalue{\??ih#1\c!level}}}% + \doifdefinedelse{\??ko\maximumlist\c!section} + {\!!counta\getvalue{\??se\getvalue{\??ko\maximumlist\c!section}\c!level}}% + {\!!counta\zerocount}} + \let\!!stringa\combinedlist + \let\combinedlist\empty + \def\docommand##1% + {\doifdefinedelse{\??ko##1\c!section} + {\ifnum\getvalue{\??se\getvalue{\??ko##1\c!section}\c!level}>\!!counta\else + \addtocommalist{##1}\combinedlist + \fi}% + {\addtocommalist{##1}\combinedlist}}% + \processcommacommand[\!!stringa]\docommand + \doifvalue{\??ih#1\c!coupling}\v!on + {\startlistreferences{#1}}% + \ExpandFirstAfter\dodoplacecombinedlist[\combinedlist][#2]% + \stoplistreferences + \endgroup + \dosetlistmode} + +\def\dodoplacecombinedlist[#1][#2]% + {\dobeginoflist + \dosetuplist[#1][#2]% + \doutilities{listentries,#1}\jobname{#1}\relax\par + \doendoflist} + +\def\docompletecombinedlist[#1][#2]% + {\expanded{\systemsuppliedtitle[#1]{\noexpand\headtext{#1}}}% expansion due to v! vs french ! + \doplacecombinedlist[#1][#2]} + +\def\dodefinecombinedlist[#1][#2][#3]% + {\makerawcommalist[#2]\combinedlist % for fast processing + \letvalue{\??ih#1\c!list}\combinedlist + \getcommalistsize[#2]% + \getfromcommalist[#2][\commalistsize]% + \doeassign[\??ih#1][\c!level=\commalistelement]% + \getparameters + [\??ih#1] + [\c!criterium=\v!local,#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\definecombinedlist + {\dotripleempty\dodefinecombinedlist} + +\def\placecombinedlist + {\dodoubleempty\doplacecombinedlist} + +% new and yet undocumented (used in cocoa qa) +% +% \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]% \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} + +\setupreferencelist + [\c!style=\v!normal] + +\protect \endinput diff --git a/tex/context/base/strc-lst.mkiv b/tex/context/base/strc-lst.mkiv new file mode 100644 index 000000000..413052882 --- /dev/null +++ b/tex/context/base/strc-lst.mkiv @@ -0,0 +1,963 @@ +%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 + +% 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(\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", + starter = \!!bs\listparameter\c!pagestarter\!!es, + 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")}} + +\def\structurelistuservariable#1% + {\ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"#1")}} + +% \appendtoks +% \to \everystructurelist + +\unexpanded\def\placestructurelist#1#2#3% hm ... [][][] + {\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} + +% push pop test: +% +% \starttext +% \placelist[chapter] [after={\placelist[section][criterium=local]}] +% \chapter{One} \section{Alpha} \section{Beta} +% \chapter{Two} \section{First} \section{Second} +% \stoptext + +\def\processlistofstructure#1#2#3% name, method, n + {\ctxlua{structure.lists.pushnesting(#3)}% + \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 + \ctxlua{structure.lists.popnesting()}} + +% \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 % hm, can end up in message (volkers test) + \structurelistpagenumber + \structurelistrealpagenumber} + +% so far (todo: also recursive) + +\def\listalternativeparameter#1% + {\ifcsname\??li\??li\listparameter\c!alternative#1\endcsname + \csname\??li\??li\listparameter\c!alternative#1\endcsname + \else + \listparameter{#1}% + \fi} + +\unexpanded\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\checklistexistence#1% + {\ifcsname\??li#1\s!parent\endcsname \else + \letvalue{\??li#1\s!parent}\??li + \fi} + +\def\dosetuplist[#1][#2]% slow -) + {\checklistexistence{#1}% + \def\docommand##1{\getparameters[\??li##1][#2]}% + \processcommalist[#1]\docommand} + +\unexpanded\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]}}} + +\unexpanded\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!sectionstarter=, + %\c!sectionstopper=, + %\c!sectionset=, + %\c!sectionsegments=, + %\c!prefix=\v!no, + %\c!prefixseparatorset=, + %\c!prefixconversionset=, + %\c!prefixstarter=., + %\c!prefixstopper=., + %\c!prefixset=, + %\c!prefixsegments=, + %\c!pageseparatorset=, + %\c!pageconversionset=, + %\c!pagestarter=, + %\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] + +\unexpanded\def\definelist + {\dotripleempty\dodefinelist} + +\unexpanded\def\placelist + {\dodoubleempty\doplacelist} + +\unexpanded\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}{\number\listparameter\c!number}% + \stoplistreferences + \endgroup + \dosetlistmode} + +\def\dosetlistmode % utilitydone will disappear + {\ifcase\structurelistsize\relax + \utilitydonefalse \resetsystemmode\v!list + \else + \utilitydonetrue \setsystemmode \v!list + \fi} + +\unexpanded\def\systemsuppliedchapter {\getvalue{\v!chapter}} % brrr +\unexpanded\def\systemsuppliedtitle {\getvalue{\v!title}} % brrr + +\def\dodocompletelist[#1][#2][#3]% enkelvoud, meervoud, instellingen + {\normalexpanded{\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}% we can use the new command that does left and right + \listparameter\c!starter + \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 + \listparameter\c!starter + \currentlistnumber + \listparameter\c!stopper + \rightlabeltext\currentlist} + {\listparameter\c!starter + \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)} + +\unexpanded\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\domakelistelement#1#2#3#4% ref internal command data + {\dontleavehmode + \iflocation % we cannot tewak \iflocation as we nest + \doifelse{\listparameter\c!interaction}{#1} + {\directgoto{\setlocationcolor\??ia#4}[internal(#2)]}% was \directgotobox + {#3{#4}}% + \else + #3{#4}% + \fi} + +\def\dodofreelistelement#1#2#3#4#5#6#7#8% + {\listparameter\c!before% can be \hskip + \doifdefinedelse{\??li#1\c!command} + {\domakelistelement{\listparameter\c!interaction}{#2}\hbox + {\listparameter\c!command + {#3}% geen conversies etc + {#4}% geen conversies etc + {#5}}}% geen command + {#7% + \vbox + {\forgetall + \domakelistelement\v!all{#2}\hbox + {\doif{\listparameter\c!headnumber}\v!yes + {\domakelistelement\v!sectionnumber{#2}\hbox + {\donestedlistattributes\c!numberstyle\c!numbercolor + {\listparameter\c!numbercommand{\currentlistsymbol}}}}% + \domakelistelement\v!text{#2}\hbox + {\donestedlistattributes\c!textstyle\c!textcolor + {\let\\=\newlineinlist + \dontconvertfont + \listparameter\c!textcommand{#4}}}% + \doif{\listparameter\c!pagenumber}\v!yes + {\doifsomething{#5} + {\domakelistelement\v!pagenumber{#2}\hbox + {\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 + \noindent + \domakelistelement\v!all{#2}\hbox + {\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 + {\domakelistelement\v!sectionnumber{#2}\hbox + {\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 + \domakelistelement\v!pagenumber{#2}\hbox + {\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 +\domakelistelement\v!text{#2}\firstofoneargument{% + \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 +%% actually, the next can be supported now (will be enabled when I have time to test it) + \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}% +%% + \setbox4\hbox + {\doif{\listparameter\c!pagenumber}\v!yes + {\doifsomething{#5} + {\domakelistelement\v!pagenumber{#2}\hbox + {\donestedlistattributes\c!pagestyle\c!pagecolor + {\listparameter\c!pagecommand{#5}}}}}}% +%% \domakelistelement\v!all{#2}\firstofoneargument{% + \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 + \domakelistelement\v!sectionnumber{#2}\hbox + {\donestedlistattributes\c!numberstyle\c!numbercolor + {\listparameter\c!numbercommand{\currentlistsymbol}}}% + \listparameter\c!right + \hskip.5em}% + \nobreak + \fi}% + \tolerance3500 % niet zomaar veranderen +%% \domakelistelement\v!text{#2}\firstofoneargument{% + \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 + \domakelistelement\v!no{#4}{#2}% + {\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}{\number\listparameter\c!number}% + \xdef\utilitylistlength{\structurelistsize}% + \endgroup + \dosetlistmode} + +\def\determinelistcharacteristics + {\dodoubleempty\dodeterminelistcharacteristics} + +\def\combinedlistparameter#1{\csname\??ih\currentcombinedlist#1\endcsname} + +\unexpanded\def\setupcombinedlist + {\dodoubleargument\dosetupcombinedlist} + +\def\dosetupcombinedlist[#1][#2]% + {\getparameters[\??ih#1][#2]% + \edef\currentcombinedlist{#1}% + \normalexpanded{\noexpand\setuplist[\combinedlistparameter\c!list]}[#2]} + +\unexpanded\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]}} + +\unexpanded\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{\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", + starter = \!!bs\listparameter\c!prefixstarter\!!es, + 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", + starter = \!!bs\listparameter\c!numberstarter\!!es, + 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 +% +% \unexpanded\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..8ee814d77 --- /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.mkiv", + 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,"marking") +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.mkii b/tex/context/base/strc-mar.mkii new file mode 100644 index 000000000..62e6f4ded --- /dev/null +++ b/tex/context/base/strc-mar.mkii @@ -0,0 +1,318 @@ +%D \module +%D [ file=strc-mar, +%D version=1997.03.31, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Markings, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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} + +\unprotect + +\prependtoks \getallmarks \to \everybeforepagebody +\prependtoks \setallmarks \to \everyafterpagebody % currently \relax + +% voor 'interne' doeleinden zijn beschikbaar: +% +% \fetchmark[naam][plaats] + +\def\mainmarking#1% + {\ifcsname\??mk#1\c!coupling\endcsname + \csname\??mk#1\c!coupling\endcsname + \fi} + +\def\fastresetmarker#1% + {\ifcsname\??mk#1\c!coupling\endcsname + \@EA\resetmark\csname\??mk\csname\??mk#1\c!coupling\endcsname\endcsname + \fi} + +\def\fastresetmarkerlist[#1]% + {\expanded{\rawprocesscommalist[#1]}\fastresetmarker} + +\def\doresetmarking[#1]% + {\processcommalist[#1]\fastresetmarker} + +\def\resetmarking + {\dosingleargument\doresetmarking} + +\def\dosetupmarking[#1][#2]% + {\def\docommand##1{\getparameters[\??mk##1][#2]}% + \processcommalist[#1]\docommand} + +\def\setupmarking + {\dodoubleargument\dosetupmarking} + +% betere protectie + +\letvalue{\??mk\??mk\v!previous}\gettopmark +\letvalue{\??mk\??mk\v!first }\getfirstmark +\letvalue{\??mk\??mk\v!last }\getbotmark +\letvalue{\??mk\??mk\v!current }\getcurrentmark + +% 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}{\expanded{\marking[vers]{\recurselevel}} \recurselevel:\dorecurse{4}{\input ward } \endgraf} +% \stopcolumns +% \stoptext + +\letvalue{\??mk\??mk\v!column:\v!first}\getsplitfirstmark +\letvalue{\??mk\??mk\v!column:\v!last }\getsplitbottommark + +\ifx\decouplemarking\undefined \def\decouplemarking[#1]{} \fi + +\let\alldefinedmarks\empty + +\def\dododefinemarking[#1][#2]% + {\getparameters[\??mk#1] + [\c!expansion=\v!no, % saves a macro + \c!separator={\space\emdash\space}, + \c!limittext=\@@kolimittext, + \c!state=\v!start]% + \decouplemarking[#1]% % no coupling with sections + \setevalue{\??mk#1\c!coupling}{#2}% + \doglobal\addtocommalist{#2}\alldefinedmarks + \expandafter\newmark\csname\??mk#2\endcsname + \showmessage\m!systems{13}{#1,[#2]}} + +\def\dodefinemarking[#1][#2]% + {\doifelsenothing{#2} + {\dododefinemarking[#1][#1]} + {\dododefinemarking[#1][#2]}} + +\def\definemarking + {\dodoubleempty\dodefinemarking} + +\def\definerawmarking[#1]% global ! ! ! ! + {\getgparameters[\??mk#1] + [\c!expansion=\v!no, % saves a macro + \c!separator={ --- }, % watch the spaces + \c!limittext=, + \c!state=\v!start]% + \setxvalue{\??mk#1\c!coupling}{#1}% + \expandafter\newmark\csname\??mk#1\endcsname + \showmessage\m!systems{13}{#1}} + +\let\nomarking\empty + +\def\fetchmark[#1][#2]% % expandable / never use \unexpanded + {\ifcsname\??mk::#1\endcsname % saved mark + \csname\??mk::\??mk::#2\@EA\@EA\@EA\endcsname + \csname\??mk::#1\endcsname + \else\ifcsname\??mk#1\c!coupling\endcsname % real mark + \csname\??mk\??mk#2\@EA\endcsname + \csname\??mk\csname\??mk#1\c!coupling\endcsname\endcsname + \fi\fi} + +\letvalue{\??mk::\??mk::\v!previous}\firstoffourarguments +\letvalue{\??mk::\??mk::\v!first }\secondoffourarguments +\letvalue{\??mk::\??mk::\v!last }\thirdoffourarguments +\letvalue{\??mk::\??mk::\v!current }\fourthoffourarguments + +% 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 + +\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]}}} + +% fetching + +\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]} + {\getvalue{\??mk#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]\getvalue{\??mk#1\c!separator}}}}% + \fetchtwomarks[#1][#2]} + +% \newtoks \everymarking + +% \def\Interesting{\doifmodeelse{*\v!marking}{Interesting}{Boring}} +% \setupheadertexts[chapter] +% \starttext +% \chapter{This Is \Interesting} +% \stoptext + +\def\dogetmarking[#1][#2][#3]% + {\doifvalue{\??mk#1\c!state}\v!start + {\bgroup + \setsystemmode\v!marking + \the\everymarking + %\def\nomarking##1{\unknown\ }% + \def\nomarking{\splitsequence{\getvalue{\??mk#1\c!limittext}}}% + \setfullsectionnumber{\??mk#1}% + \ifthirdargument + \processaction % slow + [#3] + [ \v!both=>{\dofetchtwomarks[#1][#1:#2]}, + \v!all=>{\dofetchallmarks[#1][#1:#2]}, + \s!default=>{\fetchmark [#1:#2][\v!first]}, + \s!unknown=>{\fetchmark [#1:#2][#3]}]% + \else + \processaction % slow + [#2] + [ \v!both=>{\dofetchtwomarks[#1][#1]}, + \v!all=>{\dofetchallmarks[#1][#1]}, + \s!default=>{\fetchmark [#1][\v!first]}, + \s!unknown=>{\fetchmark [#1][#2]}]% + \fi + \egroup}} + +\def\nogetmarking[#1][#2][#3]% + {} + +\unexpanded\def\getmarking + {\dotripleargument\dogetmarking} + +\let\setsomemark\setmark + +\def\domarking[#1]#2% + {\ifcsname\??mk#1\c!coupling\endcsname + \bgroup + \doifelsevalue{\??mk#1\c!expansion}\v!yes + \expandmarkstrue\expandmarksfalse + \@EA\setsomemark\csname\??mk\csname\??mk#1\c!coupling\endcsname\endcsname{#2}% + \egroup + \fi} + +\def\marking + {\dosingleargument\domarking} + +%D Used in placing text lines. + +\def\doifelsemarking#1% + {\ifundefined{\??mk#1\c!coupling}% + \expandafter\secondoftwoarguments + \else + \expandafter\firstoftwoarguments + \fi} + +%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% + {%\writestatus{marks}{postponing \string#1 => #2}% + \global\setbox\collectedmarks\hbox + {\unhbox\collectedmarks\setmark{#1}{#2}}} + +\protect \endinput + +% Pseudo marks: (for Hraban) +% +% \def\RegisterPageMark#1#2% +% {\iftrialtypesetting \else +% \doglobal\increment\NameCounter +% \textreference[#1:t:\NameCounter]{#2}% +% \doifreferencefoundelse{#1:t:\NameCounter} +% {\doifundefined{#1:f:\currentrealreference}% +% {\setxvalue{#1:f:\currentrealreference}% +% {\noexpand\in[#1:t:\NameCounter]}}% +% \setxvalue{#1:l:\currentrealreference}% +% {\noexpand\in[#1:t:\NameCounter]}}% +% {}% +% \fi} +% +% \def\GetFirstOnPage#1{\getvalue{#1:f:\realfolio}} +% \def\GetLastOnPage #1{\getvalue{#1:l:\realfolio}} +% +% \setupheadertexts[\GetFirstOnPage{Name}][\GetLastOnPage{Name}] +% +% \starttext +% +% \def\Name#1{\RegisterPageMark{Name}{#1}#1} +% \def\TestLine#1{\NC test \NC \Name {test: #1} \NC \NR} +% +% \starttabulate +% \dorecurse{100}{\expanded{\TestLine{\recurselevel}}} +% \stoptabulate +% +% \stoptext diff --git a/tex/context/base/strc-mar.mkiv b/tex/context/base/strc-mar.mkiv new file mode 100644 index 000000000..bb87051e0 --- /dev/null +++ b/tex/context/base/strc-mar.mkiv @@ -0,0 +1,495 @@ +%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} + +\unexpanded\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\currentsplitfirstmarknumber\currentfirstmarknumber +\let\currentsplittopmarknumber \currenttopmarknumber +\let\currentsplitbotmarknumber \currentbotmarknumber +\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} + +\unexpanded\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 + +\unexpanded\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}} + +\unexpanded\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..291cc8845 --- /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.mkiv", + 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.mkii b/tex/context/base/strc-mat.mkii new file mode 100644 index 000000000..0d32cb298 --- /dev/null +++ b/tex/context/base/strc-mat.mkii @@ -0,0 +1,2925 @@ +%D \module +%D [ file=strc-mat, +%D version=2006.03.27, % 1998.12.07 +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Math Fundamentals, +%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. + +% engels maken + +\writestatus{loading}{ConTeXt Structure Macros / Math Fundamentals} + +\unprotect + +% \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 + +% \definemessageconstant{math} + +% % messages moved + +% \def\invalidmathcommand#1{\showmessage\m!math1{#1}} + +% \appendtoks +% \def\eqno {\invalidmathcommand{\string\eqno }}% +% \def\leqno{\invalidmathcommand{\string\leqno}}% +% \to \everydisplay + +% \appendtoks +% \let\eqno\normaleqno +% \let\leqno\normaleqno +% \to \everymath + +% \placeformula\startformula +% H(K|M,C) = H(K|C) - H(M|C)\eqno{\hbox{(\in{}[eq:keyapp])}} +% \stopformula + +\unexpanded\def\mathortext + {\ifmmode + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +% \defineactivecharacter _ {\mathortext{_}{\_}} text_text $a^2$ + +% force text mode, will be overloaded later + +\ifx\text\undefined \let\text\hbox \fi + +\newdimen\lastlinewidth + +% does not work at all +% +% \def\setlastlinewidth +% {\resetlastlinewidth +% \ifmmode\else\ifhmode\else\ifoptimizedisplayspacing +% \bgroup +% \forgetdisplayskips +% $$\global\lastlinewidth\predisplaysize$$ +% \vskip-\baselineskip +% \egroup +% \fi\fi\fi} + +% 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} + +% not here: \appendtoks \setlastlinewidth \to \everyendofpar + +%D moved from main-001 + +%\def\EveryMathPar{\EveryPar} +% +%\newevery \everymath \EveryMath + +\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\displayskipfactor {1.0} % obsolete +\def\displayshortskipfactor {0.8} % obsolete +\def\displayskipgluefactor {0.3} % obsolete +\def\displayshortskipgluefactor {0.2} % obsolete + +\def\abovedisplayskipsize% obsolete + {\displayskipsize\displayskipfactor\displayskipgluefactor} + +\def\belowdisplayskipsize% obsolete + {\displayskipsize\displayskipfactor\displayskipgluefactor} + +\def\abovedisplayshortskipsize% obsolete + {\displayskipsize\displayshortskipfactor\displayshortskipgluefactor} + +\def\belowdisplayshortskipsize% obsolete + {\displayskipsize\displayshortskipfactor\displayshortskipgluefactor} + +\def\forgetdisplayskips % to do + {\abovedisplayskip \zeropoint + \belowdisplayskip \zeropoint + \abovedisplayshortskip\zeropoint + \belowdisplayshortskip\zeropoint} + +\definenumber % \definelabel + [\v!formula] + [\c!text=\v!formula, + \c!way=\@@fmway, + \c!blockway=\@@fmblockway, + \c!location=\v!intext, + \c!conversion=\@@fmconversion] + +\def\setupformulas + {\dodoubleargument\getparameters[\??fm]} + +\newconditional\handleformulanumber +\newconditional\incrementformulanumber + +\def\formuladistance{\formulaparameter\c!distance} + +\def\doformulareference#1#2% + {\doifsomething{#1}{\doifnotinset{#1}{+,-}{\rawreference\s!for{#1}{#2}}}} + +\def\dododoformulanumber#1#2#3#4% (#1,#2)=outer(ref,sub) (#3,#4)=inner(ref,sub) + {\hbox\bgroup + \ifconditional\handleformulanumber + \ifconditional\incrementformulanumber + \incrementnumber[\v!formula]% + \fi + \makesectionnumber[\v!formula]% + \setbox0\hbox{\ignorespaces#2\unskip}% + \ifdim\wd0>\zeropoint + \edef\hetsubnummer{\@@fnseparator#2}%AM: was \edef\hetsubnummer{#2}% + \else + \let\hetsubnummer\empty + \fi + \doformulareference{#1}{\composedsectionnumber\hetsubnummer}% + \setbox0\hbox{\ignorespaces#4\unskip}% + \ifdim\wd0>\zeropoint + \edef\hetsubnummer{\@@fnseparator#4}%AM: was \edef\hetsubnummer{#4}% + \fi + \doformulareference{#3}{\composedsectionnumber\hetsubnummer}% + \doflushformulalistentry{\composedsectionnumber\hetsubnummer}% + \rm % nodig ? + \doif{\formulaparameter\c!location}\v!right{\hskip\formuladistance}% + \@@fmnumbercommand + {\dostartattributes\??fm\c!numberstyle\c!numbercolor + \strut + \@@fmleft + \preparefullnumber\??fm\composedsectionnumber\preparednumber + \labeltexts\v!formula + {\ignorespaces\preparednumber\ignorespaces\hetsubnummer\unskip}% + \@@fmright + \dostopattributes}% + \doif{\formulaparameter\c!location}\v!left{\hskip\formuladistance}% + \fi + \egroup} + +\def\dodoformulanumber[#1][#2][#3]% + {\doquadruplegroupempty\dododoformulanumber{#1}{#2}{#3}} + +\def\doformulanumber + {\dotripleempty\dodoformulanumber} + +\setvalue{\e!start\v!formula}{\dostartformula{}} +\setvalue{\e!stop \v!formula}{\dostopformula} + +\def\definieerformule + {\dodoubleempty\dodefinieerformule} + +\def\dodefinieerformule[#1][#2]% + {\doifsomething{#1} + {\copyparameters + [\??fm#1][\??fm] + [\c!spacebefore,\c!spaceafter,\c!grid, + \c!leftmargin,\c!rightmargin,\c!margin, + \c!indentnext,\c!alternative, + \c!strut,\c!align,\c!distance]% + \setupformulas[#1][#2]% + \setvalue{\e!start#1\v!formula}{\dostartformula{#1}}% + \setvalue{\e!stop #1\v!formula}{\dostopformula}}} + +\newtoks \everysetupformulas \relax % we need a hook for extensions in modules + +\def\setupformulas + {\dodoubleempty\dosetupformulas} + +\def\dosetupformulas[#1][#2]% + {\ifsecondargument + \getparameters[\??fm#1][#2]% + \else + \getparameters[\??fm][#1]% + \fi + \the\everysetupformulas} + +\def\formulaparameter#1% + {\csname\??fm\currentformula#1\endcsname} + +\setupformulas + [\c!way=\@@nrway, + \c!blockway=, + \c!sectionnumber=\@@nrsectionnumber, + \c!conversion=\v!numbers, + \c!location=\v!right, + \c!left=(, + \c!right=), + \c!spacebefore=, + \c!spaceafter=\@@fmspacebefore, + \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!distance=1em] + +\def\currentformula {} +\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-\displayindent + \advance\displaywidth-\rightdisplayskip + \advance\displaywidth-\rightdisplaymargin + \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 + \the\everybeforedisplayformula + \formulaparskip\parskip + \formulastrutdp\strutdepth + \formulastrutht\strutheight + \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 + \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 + \switchtoformulabodyfont[#1]% + % not : \def\doformula[##1]##2{\mathematics{##2}}% + \mathematics{#2}% + \endgroup} + +\let\doplaceformulanumber\empty + +\def\dostopformula + {\doplaceformulanumber + \getvalue{\e!stop\formulaparameter\c!alternative\v!formula}% + \resetlastlinewidth + \nonoindentation + \dochecknextindentation{\??fm\currentformula}% + \egroup + \hangafter\minusone % added for side floats + \hangindent\zeropoint % added for side floats + \setfalse\handleformulanumber + \dorechecknextindentation} % here ? + +\newif\ifinformula + +\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 + \ifindentfirstparagraph % tricky, probably needs more testing + \prevdepth-\maxdimen % texbook pagina 79-80 + % otherwise problems at the top of a page, don't remove: + \verticalstrut + \vskip-\struttotal + \vskip-\baselineskip + \fi + \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 + +\def\defineformulaalternative + {\dotripleargument\dodefineformulaalternative} + +\def\dodefineformulaalternative[#1][#2][#3]% + {\setvalue{\e!start#1\v!formula}{#2}% + \setvalue{\e!stop #1\v!formula}{#3}} + +\defineformulaalternative[\s!default][\startdisplaymath][\stopdisplaymath] + +% sp = single line paragraph sd = single line display +% mp = multi line paragraph md = multy line display + +\defineformulaalternative[single][\startdisplaymath][\stopdisplaymath] +\defineformulaalternative[multi] [\startdisplaymath][\stopdisplaymath] + +\definieerformule + [sp] + [\c!spacebefore=\v!none,\c!spaceafter=\v!none, + \c!indentnext=\v!no, + \c!alternative=single] + +\definieerformule + [sd] + [\c!spacebefore=\v!none,\c!spaceafter=\v!none, + \c!indentnext=\v!yes, + \c!alternative=single] + +\definieerformule + [mp] + [\c!indentnext=\v!no, + \c!alternative=multi] + +\definieerformule + [md] + [\c!indentnext=\v!yes, + \c!alternative=multi] + +% \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} + +%D \macros +%D {setupsubformulas, startsubformulas} +%D +%D New code (by Aditya Mahajan / cleaned up by HH, please check): + +% \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] + +\def\setupsubformulas + {\dodoubleargument\getparameters[\??fn]} + +\definenumber[\v!formula*] + +\def\subformulaconversion % #1 + {\getnumber[\v!formula*]\@@fnseparator\convertnumber\@@fnconversion} % #1 + +\defineconversion[\v!subformula][\subformulaconversion] + +\def\startsubformulas + {\dosingleempty\dostartsubformulas} + +\def\dostartsubformulas[#1]% + {\incrementnumber[\v!formula]% + \makesectionnumber[\v!formula]% + \doflushformulalistentry{\composedsectionnumber}% + \doformulareference{#1}\composedsectionnumber + \expanded{\setupnumber + [\v!formula*] + [\c!start={\rawnumber[\v!formula]}, + \c!way=\@@fmway, + \c!conversion=\@@fmconversion]}% + \bgroup + \savenumber[\v!formula]% + \setupformulas + [\c!conversion=\v!subformula, + \c!way=\v!by\v!text]% + \resetnumber + [\v!formula]} + +\def\stopsubformulas + {\restorenumber[\v!formula]% + \egroup + \resetlastlinewidth + \nonoindentation + \dochecknextindentation\??fn + \dorechecknextindentation} % here ? + +%D Named subformulas + +\def\startnamedsubformulas + {\dosingleempty\dostartnamedsubformulas} + +\def\dostartnamedsubformulas[#1]#2% + {\setformulalistentry{#2}% + \startsubformulas[#1]} + +\def\stopnamedsubformulas + {\stopsubformulas} + +\setupsubformulas + [\c!conversion=\v!character, + %\c!separator=\@@fmseparator, + \c!separator=,% AM: for compatibility with \placesubformula + \c!indentnext=\@@fmindentnext] + +%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 + +\definelist[\v!formula] + +\global\let\doflushformulalistentry\gobbleoneargument + +\def\setformulalistentry#1% + {\gdef\doflushformulalistentry##1% + {\expanded{\writetolist[\v!formula]{##1}}{#1}% + \global\let\doflushformulalistentry\gobbleoneargument}} + +\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 + \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} + +\let\donestedformulanumber\gobbletwoarguments + +\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\@@fmlocation\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 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 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 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} + +%D \macros +%D {big..} +%D +%D Because they are related to the bodyfontsize, we redefine +%D some \PLAIN\ macros. + +\def\@@dobig#1#2% + {{\hbox{$\left#2\vbox\!!to#1\bodyfontsize{}\right.\nulldelimiterspace\zeropoint\relax\mathsurround\zeropoint$}}} + +\def\big {\@@dobig{0.85}} +\def\Big {\@@dobig{1.15}} +\def\bigg{\@@dobig{1.45}} +\def\Bigg{\@@dobig{1.75}} + +%D \macros +%D {bordermatrix} +%D +%D We already redefined \type {\bordermatrix} in \type +%D {font-ini}. + +%D \macros +%D {setuptextformulas} +%D +%D This command sets up in||line math. Most features deals +%D with grid snapping and are experimental. + +\newevery \everysetuptextformulas \relax + +\def\setuptextformulas + {\dosingleempty\dosetuptextformulas} + +\def\dosetuptextformulas[#1]% + {\getparameters[\??mt][#1]% + \the\everysetuptextformulas} + +%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 {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 + +%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}}} + +% possible pdftex bug: +% +% \dorecurse{100}{gest \vadjust {\strut} \par} \page +% \dorecurse{100}{gest \vadjust pre {\strut} \par} \page +% +% duplicate depth compensation with pre + +\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 + +\newif\if!!donee +\newif\if!!donef + +\def\inlinemathmargin{1pt} + +\settrue\autocrazymathsnapping + +% FROM NOW ON, CHANGES AS OPTIONS + +% TODO: SKYLINE (PREV LINE POS SCAN) + +\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 + \ifx\pdftexversion\undefined + \donefalse + \else + \checktextbackgrounds % we need pos tracking, to be made less redundant + \donetrue + \fi + \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} + + +%%% top correction code +%%% +%%% correct for fuzzy top of page situations +% +% \scratchdimen\lastcrazymathprelines\lineheight +% \advance\scratchdimen\MPy\crazymathtag +% \advance\scratchdimen\lineheight +% \advance\scratchdimen\topskip +% \advance\scratchdimen-\strutheight +% \dimen0=\MPy\crazytexttag +% \advance\dimen0 \MPh\crazytexttag +% \advance\scratchdimen-\dimen0\relax +% % do we need correction at all +% \ifdim\scratchdimen>\strutdepth\relax +% \donefalse +% \else\ifdim\scratchdimen<\zeropoint +% \donefalse +% \else +% \donetrue +% \fi\fi +% % analysis done +% \donefalse +% \ifdone +% \edef\crazymathcorrection{\the\scratchdimen}% +% \advance\scratchdimen-\dp\scratchbox +% \dp\scratchbox-\scratchdimen +% \else +% \let\crazymathcorrection\zeropoint +% \fi +% +%%% +%%% keep the previous code +%%% + +\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 {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 \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}} + +%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 \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 + \expanded{\scratchtoks{\the\scratchtoks\the\!!toksa}}% + \dorecurse{\numexpr\mathalignmentparameter\c!n-\plusone\relax} + {\expanded{\scratchtoks{\the\scratchtoks\the\!!toksb}}}}% + \expanded{\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\@@fmlocation\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 + \expanded{\scratchtoks{\the\scratchtoks\the\!!toksa}}% + \dorecurse{\numexpr\scratchcounter-\plusone\relax} + {\expanded{\scratchtoks{\the\scratchtoks\the\!!toksb}}}% + \expanded{\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 {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 +%D \starttyping +%D \def\frac#1#2% +%D {\relax +%D \ifmmode +%D {{\mathstyle{#1}}\over{\mathstyle{#2}}}% +%D \else +%D $\frac{#1}{#2}$% +%D \fi} +%D \stoptyping +%D +%D Better is: +%D +%D \starttyping +%D \def\frac#1#2% +%D {\relax\mathematics{{{\mathstyle{#1}}\over{\mathstyle{#2}}}}} +%D \stoptyping +%D +%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}}}}} + +% \unexpanded\def\frac +% {\dofrac\mathstyle} +% +% \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=mathstyle, 1=displaystyle, 2=textstyle, 3=scriptstyle, 4=scriptscriptstyle + +\unexpanded\def\frac + {\ifcase\mathfracmode + \expandafter\dofrac\expandafter\mathstyle + \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. + +\ifx\mathstyle\undefined + \let\mathstyle\relax +\fi + +\unexpanded\def\ch#1% + {\ifx\@@chemicalletter\undefined + \mathstyle{\rm#1}% + \else + \dosetsubscripts + \mathstyle{\@@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 + +%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 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) + +%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$}% + \expanded + {\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}}} + +%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 + +\def\mathboldsymbol#1% + {\preparebinrel{#1}% + \currentbinrel{\mathchoice + {\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} + +%D Some encoding hackery (for Mojca. who else): +%D +%D \starttyping +%D \startmathcollection[eul:texnansi] +%D \definemathsymbol [breve] [accent] [tf] ["15] +%D \stopmathcollection +%D \startmathcollection[eul:ec] +%D \definemathsymbol [breve] [accent] [tf] ["08] +%D \stopmathcollection +%D +%D $\breve e$ +%D \stoptyping + +\let\outerencoding\empty + +\def\checkoutermathencoding + {\ifx\outerencoding\empty + \ifx\outerencoding\s!default\else + \edef\outerencoding{\currentencoding}% + \fi + \fi} + +\prependtoks + \checkoutermathencoding +\to \everymathematics + +%D More. (A temp hack, else no proper default fall back (like \type +%D {\textmultiply}); todo: sync encoding. + +\def\dealwithmathtextencoding + {\expanded{\everyhbox{\the\everyhbox\noexpand\fastenableencoding{\currentencoding}}}% + \expanded{\everyvbox{\the\everyvbox\noexpand\fastenableencoding{\currentencoding}}}% + \def\dealwithmathtextencoding{\let\characterencoding\nocharacterencoding}% + \dealwithmathtextencoding} + +\appendtoks + \dealwithmathtextencoding +\to \everymathematics + +%D How negative such a symbol looks is demonstrated in: +%D $\negative 10^{\negative 10^{\negative 10}}$. + +\setupformulas + [\c!way=\@@nrway, + \c!blockway=, + \c!sectionnumber=\@@nrsectionnumber, + \c!location=\v!right, + \c!left=(, + \c!right=), + \c!numberstyle=, + \c!numbercolor=, + \c!numbercommand=, + \c!spacebefore=\v!big, + \c!spaceafter=\@@fmspacebefore, + \c!grid=] + +\protect \endinput diff --git a/tex/context/base/strc-mat.mkiv b/tex/context/base/strc-mat.mkiv new file mode 100644 index 000000000..2064db2c5 --- /dev/null +++ b/tex/context/base/strc-mat.mkiv @@ -0,0 +1,771 @@ +%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} + +% we have potential for captions + +\unprotect + +\definestructureconversionset[\v!formula][numbers,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] + +\presetstructurecountersetup\setupformulas\sharedstructurecounterparameter + +\appendtoks +% \dostructurecountersetup\currentformula\formulaparameter +% \docheckstructurecountersetup\currentformula + \dostructurecountersetup\v!formula\formulaparameter +% \docheckstructurecountersetup\v!formula +\to \everysetupformulas + +\setupformulas + [\c!numberconversionset=\v!formula] % why forgotten + +\def\storecurrentformulanumber#1#2#3#4#5% ref, todo:str, \sync % todo: title etc (like float) + {\dostructurecountercomponent + {formula}% + \getformulaparameters \formulaparameter \detokenizedformulaparameter + \relax \relax \relax +% [\c!name=\currentformula,\s!counter=\currentformula,% + [\c!name=\v!formula,\s!counter=\v!formula,% + \s!hascaption=\v!yes,\s!hastitle=\v!yes,\s!hasnumber=\v!yes,%\s!haslevel=#6,% + \s!hasnumber=\v!no,% + \c!reference=#1,\c!title=,\c!bookmark=]% + [#2]% + \globallet#3\laststructurecounternumber + \globallet#4\laststructurecountersynchronize + \globallet#5\laststructurecounterattribute} + +\newif\ifnoformulanumber + +\newconditional\handleformulanumber +\newconditional\incrementformulanumber + +\newtoks\everyresetformulas + +\newconditional\insideplaceformula +\newconditional\insideplacesubformula +\newconditional\insideformulas +\newconditional\insidesubformulas + +% 0=unset, 1=forced, 2=none, 3=reference + +\def\handleplaceformulanumbering % place formula + {\settrue\handleformulanumber + \docheckformulareference\placeformulanumbermode\currentplaceformulareference + \glet\doplaceformulanumber \doplaceformulanumberindeed + \glet\donestedformulanumber\donestedformulanumberindeed} + +\def\handleformulasnumbering % formulas + {\docheckformulareference\formulasnumbermode\currentformularesference} + +\def\handlesubformulasnumbering % sub formulas + {\docheckformulareference\subformulasnumbermode\currentsubformulasreference + \doincrementsubstructurecounter[\v!formula][1]% always + \storecurrentformulanumber + \currentsubformulasreference + \empty + \currentsubformulasnumber + \currentsubformulassynchronize + \currentsubformulasattribute + } + +\def\tracedformulamode + {\hbox{\quad\tt\txx[\number\placeformulanumbermode,\number\formulasnumbermode,\number\subformulasnumbermode,\number\nestedformulanumbermode]}} + +\unexpanded\def\placecurrentformulanumber + {\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\doplacecurrentformulanumber\unskip}% + \formulaparameter\c!right}% + \doif{\formulaparameter\c!location}\v!left{\hskip\formulaparameter\c!distance}} + +\def\doplacecurrentformulanumber + {\dohandlecurrentformulareferences + %\currentformulasattribute % todo + %\currentformulasattribute % todo + %\currentsubformulaattribute % todo + \labeltexts\currentformula{\doconvertedstructurecounter[\v!formula][]}} + +\appendtoks + \glet\currentplaceformulasynchronize \relax + \glet\currentformulassynchronize \relax + \glet\currentsubformulassynchronize \relax + \glet\currentnestedformulasynchronize\relax + \let\currentformula\empty +\to \everyresetformulas + +\def\dohandlecurrentformulareferences + {\ifnum\placeformulanumbermode=\plusthree + \storecurrentformulanumber + \currentplaceformulareference + \empty + \currentplaceformulanumber + \currentplaceformulasynchronize + \currentplaceformulaattribute + \currentplaceformulasynchronize + \glet\currentplaceformulasynchronize\relax + \fi + \ifnum\formulasnumbermode=\plusthree + \storecurrentformulanumber + \currentformulasreference + \empty + \currentformulasnumber + \currentformulassynchronize + \currentformulasattribute + \currentformulassynchronize + \glet\currentformulassynchronize\relax + \fi + \ifnum\subformulasnumbermode=\plusthree + \currentsubformulassynchronize + \glet\currentsubformulassynchronize\relax + \fi + \ifnum\nestedformulanumbermode=\plusthree + \storecurrentformulanumber + \currentnestedformulareference + \empty + \currentnestedformulanumber + \currentnestedformulasynchronize + \currentnestedformulaattribute + \currentnestedformulasynchronize + \glet\currentnestedformulasynchronize\relax + \fi} + +\let\currentformulasreference \empty \let\currentformulassuffix \empty +\let\currentformulareference \empty \let\currentformulasuffix \empty +\let\currentsubformulareference \empty \let\currentsubformulasuffix \empty +\let\currentnestedformulareference\empty \let\currentnestedformulasuffix\empty + +\let\currentformulasynchronize \relax \let\currentformulaattribute \relax +\let\currentsubformulasynchronize\relax \let\currentsubformulaattribute\relax +\let\currentformulassynchronize \relax \let\currentformulasattribute \relax + +\def\dohandleformulanumbering + {\doincrementsubstructurecounter[\v!formula][1]% + \doiftext\currentplaceformulasuffix{\setsubstructurecounterown[\v!formula][2]{\currentplaceformulasuffix}}% + \placecurrentformulanumber} + +\def\dohandlesubformulanumbering + {\doiftextelse\currentsubformulasuffix + {\setsubstructurecounterown[\v!formula][2]{\currentsubformulasuffix}} + {\doincrementsubstructurecounter[\v!formula][2]}% + \placecurrentformulanumber} + +\def\dododoformulanumber + {\ifconditional\handleformulanumber + \hbox\bgroup + % main counter + \ifconditional\insidesubformulas + % nothing + \else + \ifcase\formulasnumbermode + \ifcase\placeformulanumbermode + \dohandleformulanumbering + \or + \dohandleformulanumbering + \or + % nothing + \or + \dohandleformulanumbering + \fi + \or + \dohandleformulanumbering + \or + % nothing + \or + \dohandleformulanumbering + \fi + \fi + % subcounter + \ifconditional\insidesubformulas + \ifcase\subformulasnumbermode + % nothing + \or + \dohandlesubformulanumbering + \or + % nothing + \or + \dohandlesubformulanumbering + \fi + \fi + %\rlap{\tracedformulamode}% + \egroup + \fi} + +\definelist[\v!formula] + +\appendtoks + \global\setfalse\insideplaceformula + \global\setfalse\insideplacesubformula +% \global\setfalse\insideformulas +% \global\setfalse\insidesubformulas +\to \everyresetformulas + +\newif\ifinformula + +%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\gobbleoneargument \let\leqno\gobbleoneargument + \let\normalreqno\gobbleoneargument \let\eqno \gobbleoneargument + \let\doplaceformulanumber\empty} + +%D + +\unexpanded\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}}} + +\unexpanded\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} + +\unexpanded\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 + +\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\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\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 +% {\predisplaysize\lastlinewidth\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 + +\def\dostartformula#1% + {\dodoubleempty\dodostartformula[#1]} + +\newskip\formulaparskip +\newskip\formulastrutht +\newskip\formulastrutdp + +%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 ! + {\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 + \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}% + \nonoindentation + \checknextindentation[\formulaparameter\c!indentnext]% + \egroup + \hangafter\minusone % added for side floats + \hangindent\zeropoint % added for side floats + \setfalse\handleformulanumber + \the\everyresetformulas + \dorechecknextindentation} % here ? + +%D \starttyping +%D % test \par % no preceding hlist +%D % $$x$$ % preceding hlist +%D % \noindent $$x$$ % no preceding hlist +%D \startformula x \stopformula % now has \noindent (in mkii we messed with baselineskip) +%D \stoptyping + +\unexpanded\def\startdisplaymath + {\bgroup + \par + \informulatrue + \beforedisplayspace + \par + \ifvmode + \prevdepth-\maxdimen % texbook pagina 79-80 + \fi + \noindent % else funny hlist with funny baselineskip + $$% \Ustartdisplaymath + \setdisplaydimensions + %\setpredisplaysize + \startinnermath} + +\unexpanded\def\stopdisplaymath + {\stopinnermath + $$% \Ustopdisplaymath + \par + \afterdisplayspace + \par + \egroup} + +\newif\ifclipdisplaymath \clipdisplaymathtrue +\def\displaymathclipfactor{1.1} + +% already defined +% +% \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} + +\unexpanded\def\startsubformulas + {\dosingleempty\dostartsubformulas} + +\def\dostartsubformulas[#1]% + {\edef\currentsubformulasreference{#1}% + \global\settrue\insidesubformulas + \handlesubformulasnumbering} + +\unexpanded\def\stopsubformulas + {\nonoindentation + \checknextindentation[\formulaparameter\c!indentnext]% + \the\everyresetformulas % to be checked + \global\setfalse\insidesubformulas + \dorechecknextindentation} % here ? + +%D Named subformulas (to be redone) + +\unexpanded\def\startnamedsubformulas + {\dosingleempty\dostartnamedsubformulas} + +\def\dostartnamedsubformulas[#1]#2% + {\setformulalistentry{#2}% + \startsubformulas[#1]} + +\unexpanded\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 + +\unexpanded\def\startformulas + {\dosingleempty\dostartformulas} + +\def\dostartformulas[#1]#2\stopformulas % new / to be internationalized + {\bgroup + \global\settrue\insideformulas + \edef\currentformulasreference{#1}% + \handleformulasnumbering + \let\currentformula\empty + \forgetdisplayskips + \startdisplaymath + \setlocalhsize + \long\unexpanded\def\startformula##1\stopformula + {\advance\scratchcounter\plusone}% + \scratchcounter\zerocount + #2% preroll + \ifcase\scratchcounter\else + \divide \hsize \scratchcounter + \fi + \hbox to \localhsize \bgroup + \hss + \def\normalstartformula{\vskip-\strutdepth\Ustartdisplaymath}% i hate this + \def\normalstopformula {\Ustopdisplaymath}% + \unexpanded\def\startformula {\Ustartmath\vcenter\bgroup\normalstartformula}% + \unexpanded\def\stopformula {\normalstopformula\egroup\Ustopmath\hss}% + #2% + \egroup + \stopdisplaymath + \global\setfalse\insideformulas + \egroup + \the\everyresetformulas + \hangafter\minusone % added for side floats + \hangindent\zeropoint} % added for side floats + +% place + +% 0=unset, 1=forced, 2=none, 3=reference + +\chardef\placeformulanumbermode \zerocount +\chardef\formulanumbermode \zerocount +\chardef\formulasnumbermode \zerocount +\chardef\subformulasnumbermode \zerocount +\chardef\nestedformulanumbermode\zerocount + +\def\inhibitformulanumberflag{-} +\def\forceformulanumberflag {+} + +\def\docheckformulareference#1#2% + {\chardef#1\ifx#2\empty + \zerocount + \else\ifx#2\forceformulanumberflag + \plusone + \else\ifx#2\inhibitformulanumberflag + \plustwo + \else + \plusthree + \fi\fi\fi} + +\def\formulanumber{\doformulanumber} % for the moment + +\def\doformulanumber + {\dosingleempty\dodoformulanumber} + +\def\dodoformulanumber[#1]% + {\def\currentformulareference{#1}% + \dosinglegroupempty\dododoformulanumber} + +\def\redoformulanumber#1% + {\def\currentformulasuffix{#1}% + \dododoformulanumber} + +\unexpanded\def\placeformula + {\doglobal\settrue\insideplaceformula + \settrue\incrementformulanumber + \dodoubleempty\doplaceformula} + +\unexpanded\def\placesubformula + {\doglobal\settrue\insideplacesubformula + \setfalse\incrementformulanumber + \dodoubleempty\doplaceformula} + +% \def\doplaceformula[#1][#2]% #2 = dummy, gobbles spaces +% {\def\currentplaceformulareference{#1}% +% \let\currentplaceformulasuffix\empty +% \futurelet\next\redoplaceformulaone} +% +% \let\mathdollarsign$ % no def +% +% \def\redoplaceformulaone % use doifnextcharelse +% {\ifx\next\bgroup +% \@EA\moreplaceformula % [ref]{} +% \else +% \@EA\redoplaceformulatwo +% \fi} +% +% \long\def\moreplaceformula#1#2% #1 dummy #1 gobbles spaces +% {\def\currentplaceformulasuffix{#1}% +% \futurelet\next\redoplaceformulatwo#2} +% +% \def\redoplaceformulatwo +% {\ifx\next\mathdollarsign +% \@EA\dispplaceformula % [ref]$$ +% \else +% \@EA\dodoplaceformula % [ref]\start +% \fi}% + +\def\doplaceformula[#1][#2]% #2 = dummy, gobbles spaces + {\def\currentplaceformulareference{#1}% + \let\currentplaceformulasuffix\empty + \doifnextbgroupelse\moreplaceformula\redoplaceformula} % [ref]{} + +\long\def\moreplaceformula#1% + {\def\currentplaceformulasuffix{#1}% + \redoplaceformula} + +\long\def\redoplaceformula + {\doifnextcharelse$\dispplaceformula\dodoplaceformula} % [ref]$$ [ref]\start + +\def\dodoplaceformula + {\handleplaceformulanumbering} + +\def\dispplaceformula$$#1$$% + {\handleplaceformulanumbering + \dostartformula{}#1\dostopformula} + +\let\startplaceformula\placeformula +\let\stopplaceformula \relax + +% to be checked + +\def\doformulanumber + {\dosingleempty\dodoformulanumber} + +\def\dodoformulanumber[#1]% + {\def\currentformulareference{#1}% + \dosinglegroupempty\dododoformulanumber} + +\def\redoformulanumber#1% + {\def\currentformulasuffix{#1}% + \dododoformulanumber} + +\glet\doplaceformulanumber \relax +\glet\donestedformulanumber\gobbletwoarguments + +\def\donestedformulanumberindeed#1#2% + {\def\currentnestedformulareference{#1}% + \def\currentnestedformulasuffix{#2}% + \glet\doplaceformulanumber\relax + \docheckformulareference\nestedformulanumbermode\currentnestedformulareference + \ifcase\nestedformulanumbermode + % nothing + \or + \doformulanumber + \or + % nothing + \or + \doformulanumber + \fi} + +\def\doplaceformulanumberindeed + {\glet\doplaceformulanumber\relax + \doifelse{\formulaparameter\c!location}\v!left + {\normalleqno{\dododoformulanumber}} + {\normalreqno{\dododoformulanumber}}} + +% todo + +\unexpanded\def\placenamedformula + {\dosingleempty\doplacenamedformula} + +\def\doplacenamedformula[#1]#2% + {\iffirstargument + \def\next{\placeformula[#1]}% + \else + \let\next\placeformula + \fi + \setformulalistentry{#2}% + \next} + +\global\let\doflushformulalistentry\gobbleoneargument + +\def\setformulalistentry#1% + {\gdef\doflushformulalistentry##1% + {\normalexpanded{\noexpand\writetolist[\v!formula]{##1}}{#1}% + \global\let\doflushformulalistentry\gobbleoneargument}} + +\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..be883af57 --- /dev/null +++ b/tex/context/base/strc-not.lua @@ -0,0 +1,338 @@ +if not modules then modules = { } end modules ['strc-not'] = { + version = 1.001, + comment = "companion to strc-not.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format = string.format +local next = next +local texsprint, texwrite, texcount = tex.sprint, tex.write, tex.count + +local ctxcatcodes = tex.ctxcatcodes + +local trace_notes = false trackers.register("structure.notes", function(v) trace_notes = v end) + +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 + local nnd = #nd+1 + nd[nnd] = n + local state = notestates[tag] + if state.kind ~= "insert" then + if trace_notes then + logs.report("notes","storing %s with state %s as %s",tag,state.kind,nnd) + end + state.start = state.start or nnd + end + texwrite(#nd) +end + +local function get(tag,n) + local nd = notedata[tag] + if nd then + n = n or #nd + nd = nd[n] + if nd then + if trace_notes then + logs.report("notes","getting %s of %s",n,tag) + end + return structure.lists.collected[nd] + end + end +end + +local function getn(tag) + local nd = notedata[tag] + return (nd and #nd) or 0 +end + +nodes.get = get +nodes.getn = getn + +-- we could make a special enhancer + +function notes.listindex(tag,n) + return notedata[tag][n] +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 + if trace_notes then + logs.report("notes","saving state of %s: %s -> %s",tag,state.kind,newkind or state.kind) + end + state.saved = notedata[tag] + state.savedkind = state.kind + state.kind = newkind or state.kind + notedata[tag] = { } + end +end + +function notes.restore(tag,forcedstate) + local state = notestates[tag] + if state and state.saved then + if trace_notes then + logs.report("notes","restoring state of %s: %s -> %s",tag,state.kind,state.savedkind) + end + state.saved = nil + state.kind = forcedstate or state.savedkind + notedata[tag] = state.saved + end +end + +function notes.setstate(tag,newkind) + local state = notestates[tag] + if trace_notes then + logs.report("notes","setting state of %s from %s to %s",tag,(state and state.kind) or "unset",newkind) + end + 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 + -- state.start can already be set and will be set when an entry is added or flushed + return state +end + +function notes.getstate(tag) + local state = notestates[tag] + texsprint(ctxcatcodes,(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 = get(tag,n) + if nd then + local r = nd.references + if r then + local i = r.internal +--~ return i and lists.internals[i] + return i and jobreferences.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 + +notes.internal = internal +notes.ordered = ordered + +function notes.doifonsamepageasprevious(tag) + local same = false + local n = getn(tag,n) + local current, previous = get(tag,n), get(tag,n-1) + if current and previous then + local cr, pr = current.references, previous.references + same = cr and pr and cr.realpage == pr.realpage + end + commands.doifelse(same) +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 texcount.realpageno > 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 + texwrite(what) +end + +function notes.postpone() + if trace_notes then + logs.report("notes","postponing all insert notes") + end + 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 = get(tag,n) + if nd then + nd.metadata.symbolpage = texcount.realpageno + end +end + +function notes.getsymbolpage(tag,n) + local nd = 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 state = notestates[tag] + local kind = state.kind + if kind == whatkind then + local nd = notedata[tag] + local ns = state.start -- first index + if kind == "postpone" then + if nd and ns then + if trace_notes then + logs.report("notes","flushing state %s of %s from %s to %s",whatkind,tag,ns,#nd) + end + for i=ns,#nd do + texsprint(ctxcatcodes,format("\\handlenoteinsert{%s}{%s}",tag,i)) + end + end + state.start = nil + state.kind = "insert" + elseif kind == "store" then + if nd and ns then + if trace_notes then + logs.report("notes","flushing state %s of %s from %s to %s",whatkind,tag,ns,#nd) + end + for i=ns,#nd do + texsprint(ctxcatcodes,format("\\handlenoteitself{%s}{%s}",tag,i)) + end + end + state.start = nil + elseif kind == "reset" then + if nd and ns then + if trace_notes then + logs.report("notes","flushing state %s of %s from %s to %s",whatkind,tag,ns,#nd) + end + end + state.start = nil + elseif trace_notes then + logs.report("notes","not flushing state %s of %s",whatkind,tag) + end + elseif trace_notes then + logs.report("notes","not flushing state %s of %s",whatkind,tag) + end +end + +function notes.flushpostponed() + if trace_notes then + logs.report("notes","flushing all postponed notes") + end + for tag, _ in next, notestates do + notes.flush(tag,"postpone") + end +end + +function notes.resetpostponed() + if trace_notes then + logs.report("notes","resetting all postponed notes") + end + for tag, state in next, notestates do + if state.kind == "postpone" then + state.start = nil + state.kind = "insert" + 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.mkii b/tex/context/base/strc-not.mkii new file mode 100644 index 000000000..f6fae3378 --- /dev/null +++ b/tex/context/base/strc-not.mkii @@ -0,0 +1,1472 @@ +%D \module +%D [ file=strc-not, +%D version=2002.05.10, % 1997.09.15 +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Note Handling, % Footnote 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 Structure Macros / Note Handling} + +%D Unfortunately we cannot force an even number of lines in +%D a two column footnote placement. + +%D There are some (still) dutch core commands used in this +%D file. + +\unprotect + +% \dochecknote in processnotes + +% splitskips setten + +%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}. + +%D \macros +%D {setupnote,setupnotedefinition} +%D +%D We can influence footnote typesetting with the setup +%D command: +%D +%D \showsetup{setupfootnotes} % ! ! +%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. +%D +%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. We definitely did not reinvent that wheel. + +\newif\ifendnotes \endnotesfalse +\newif\ifbottomnotes \bottomnotestrue + +\chardef\clevernotes=\zerocount % 0=page 1=firstcolumn 2=lastcolumn + +%D The next definitions indicate that we can frame the footnote +%D area. The footnotes themselves are treated as definitions. +%D +%D \showsetup{setupfootnotes} + +\let\currentnote\v!footnote + +\def\noteparameter #1{\csname\??vn \currentnote#1\endcsname} +\def\notedefparameter #1{\csname\??vn\??vn\currentnote#1\endcsname} +\def\footnoteparameter #1{\csname\??vn \v!footnote#1\endcsname} + +\def\startnotedef {\resetdescriptions\csname\e!start\??vn\??vn\currentnote\endcsname} +\def\stopnotedef {\csname\e!stop \??vn\??vn\currentnote\endcsname} + +\def\noteinsertion #1{\csname\??vn:#1\endcsname} +\def\currentnoteins {\csname\??vn:\currentnote\endcsname} +\def\currentsaveins {\csname\??vn-\currentnote\endcsname} +\def\localpostponednotes {\csname\??vn+\currentnote\endcsname} + +\def\backupnoteins #1{\@EA\backupinsertion\csname\??vn:#1\endcsname} +\def\currentbackupnoteins{\@EA\backupinsertion\csname\??vn:\currentnote\endcsname} + +%D The numbers that accompany a footnote are generated using +%D the standard \CONTEXT\ numbering mechanism, and thereby can +%D be assigned on a per whatever sectioning basis. + +\ifx\noteinsertions\undefined \let\noteinsertions\empty \fi % permits reload + +\def\doprocessnotes#1#2% #1 may be { ... } + {\def\currentnote{#2}#1} + +\def\doprocessnotescs#1#2% #1 == \cs that takes arg + {\def\currentnote{#2}\@EA#1\csname\??vn:\currentnote\endcsname} + +\def\processnotes #1{\processcommacommand[\noteinsertions]{\doprocessnotes {#1}}} +\def\processnotescs#1{\processcommacommand[\noteinsertions]{\doprocessnotescs#1}} + +\def\savenotecontent {\processnotescs\saveinsertionbox } +\def\erasenotebackup {\processnotescs\eraseinsertionbackup} +\def\savenotedata {\processnotescs\saveinsertiondata } +\def\restorenotecontent{\processnotescs\restoreinsertionbox } +\def\restorenotedata {\processnotescs\restoreinsertiondata} + +%D ... due to invisibility of inserts ... maybe save them twice +%D and split new part ... todo ... + +\def\doenablenotes % brrr + {\global\count\currentnoteins\plusthousand + \global\skip \currentnoteins1\baselineskip\relax} + +\def\dodisablenotes + {\global\count\currentnoteins\zerocount + \global\skip \currentnoteins\zeropoint} + +\def\enablenotes {\processnotes\doenablenotes } +\def\disablenotes{\processnotes\dodisablenotes} + +\def\dosavenotes + {\global\setbox\currentsaveins\vbox + {\ifvoid\currentsaveins\else\unvbox\currentsaveins\fi + \box\currentnoteins}} + +\def\doflushsavednotes + {\ifvoid\currentsaveins\else + \insert\currentnoteins{\unvbox\currentsaveins}% + \fi} + +\def\savenotes {\processnotes\dosavenotes } +\def\flushsavednotes{\processnotes\doflushsavednotes} + +%D Both these parameters are coupled to the setup command we +%D will implement in a moment. This means that, given a +%D suitable symbol set, symbols can be used instead of numbers, +%D by saying: +%D +%D \starttyping +%D \setupfootnotes[conversion=set 2] +%D \stoptyping + +% 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}][] + +\def\definenote + {\dodoubleempty\dodefinenote} + +% maybe we should inherit (todo) + +\def\@@defaultnotedefloc{\v!inleft} +\def\@@defaultnotedefdis{\!!zeropoint} + +\def\dodefinenote[#1][#2]% + {\def\currentnote{#1}% + \ifundefined{\??vn:\currentnote}% + \@EA\installinsertion \csname\??vn:\currentnote\endcsname\relax + \@EA\installbackupinsertion\csname\??vn:\currentnote\endcsname\relax +% \@EA\newbox\csname\??vn::\currentnote\endcsname % scratch box % needed ? + \@EA\newbox\csname\??vn+\currentnote\endcsname % local box + \@EA\newbox\csname\??vn-\currentnote\endcsname % local box + \doglobal\addtocommalist{#1}\noteinsertions + \fi + \definedescription + [\??vn\??vn\currentnote] + [\c!location=\@@defaultnotedefloc, + \c!distance=\@@defaultnotedefdis, + \c!width=\v!fit, + \c!headstyle=\noteparameter\c!style, + \c!headcolor=\noteparameter\c!color, + \c!before=, + \c!after=]% + \presetlocalframed + [\??vn\currentnote]% + \getparameters + [\??vn\currentnote] + [\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!next=\autoinsertnextspace, % new, experimental with startnotes + \c!n=1]% + \definenumber + [\currentnote] + [\c!way=\noteparameter\c!way, + \c!sectionnumber=\noteparameter\c!way, + \c!conversion=\noteparameter\c!conversion]% + \letvalue{\??vn\c!rule:\currentnote}\normalnoterule + \unexpanded\setvalue{\currentnote }{\setnote[#1]}% + \unexpanded\setvalue{\currentnote\v!text }{\setnotetext[#1]}% + \unexpanded\setvalue{\e!start\currentnote}{\dodoubleempty\dostartcurrentnote[#1]}% + \unexpanded\setvalue{\e!stop\currentnote }{\dostopcurrentnote}% + \setupnote[\currentnote][#2]} + +\def\dostartcurrentnote[#1][#2]{\setnote[#1][#2]\bgroup\ignorespaces} +\def\dostopcurrentnote {\removeunwantedspaces\egroup\noteparameter\c!next} + +\def\setupnotedefinition[#1]% + {\setupdescriptions[\??vn\??vn#1]} + +\def\setupnote + {\dodoubleempty\dosetupnote} + +\def\dosetupnote[#1][#2]% + {\edef\currentnote{#1}% + \ifsecondargument + \ifcase\localnodemode\or + \edef\localnode@n{\noteparameter\c!n}% + \edef\localnode@l{\noteparameter\c!location}% + \fi + \getparameters[\??vn\currentnote][#2]% + \ifcase\localnodemode\or + \letvalue{\??vn\currentnote\c!n }\localnode@n + \letvalue{\??vn\currentnote\c!location}\localnode@l + \fi + \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}]% + \processaction % todo + [\noteparameter\c!split] + [ \v!tolerant=>\notepenalty\zeropoint, + \v!strict=>\notepenalty9999, + \v!verystrict=>\notepenalty\maxdimen, + \s!default=>\notepenalty\zeropoint, + \s!unknown=>\notepenalty\commalistelement]% + \fi + \dochecknote} + +\def\dolocalsetupnotes#1#2% + {\ifsecondargument + \edef\noteinsertions{#1}% + \processnotes{\setupnote[\currentnote][#2]}% + \else\iffirstargument + \doifassignmentelse{#1} + {\processnotes{\setupnote[\currentnote][#1]}} + {\edef\noteinsertions{#1}}% + \fi\fi} + +% redefined: + +% so that it matches: + +% todo: make sure less calls, is quite some code + +% BEWARE, OVERLOADED IN cont-new.mkiv + +\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 (**) + \setnotedistance + \count\currentnoteins\plusthousand + \expanded{\doifcommonelse{\v!columns,\v!lastcolumn}{\noteparameter\c!location}}% ** + {\chardef\clevernotes\plustwo} + {\expanded{\doifinsetelse{\v!firstcolumn}{\noteparameter\c!location}}% ** + {\chardef\clevernotes\plusone}% + {\chardef\clevernotes\zerocount}}% + \ifcase\clevernotes\relax + % notes not in column areas + \ifnum\noteparameter\c!n=\zerocount % no ifcase + \settextnotes + \scratchcounter\plusone + \else + \setcolumnnotes + \scratchcounter\noteparameter\c!n\relax + \divide\count\currentnoteins \scratchcounter + \fi + \global\endnotesfalse + \expanded{\doifinsetelse{\v!page}{\noteparameter\c!location}}% ** + {\expanded{\doifinsetelse{\v!high}{\noteparameter\c!location}}% ** + {\global\bottomnotesfalse} + {\global\bottomnotestrue}} + {\global\endnotestrue + \global\bottomnotestrue}% not: \postponenotes, else global + \else + % notes in column areas + \ifnum\@@kln=\zerocount % no ifcase / brrr dependency on \??kl + \scratchcounter\plusone + \else + \scratchcounter\footnoteparameter\c!n\relax % ** + \fi + \global\endnotesfalse + \global\bottomnotestrue + \setclevernotes + \fi + \doifsomething{\noteparameter\c!factor} + {\ifnum\noteparameter\c!factor<\zerocount\else + \count\currentnoteins\noteparameter\c!factor + \fi}% + \ifnotelimit + \dimen\currentnoteins\noteparameter\c!height + \multiply\dimen\currentnoteins \scratchcounter + \fi + \ifendnotes + \dimen\currentnoteins\maxdimen + \count\currentnoteins\zerocount + \skip \currentnoteins\zeropoint + \fi} + +\def\checknotes + {\processnotes\dochecknote} + +% 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} + +%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 + +\def\setnotedistance + {\setbox\scratchbox\vbox + {\forgetall + \noteparameter\c!before + \placenoterule + \noteparameter\c!after}% + \global\skip\currentnoteins\ht\scratchbox + \setbox\scratchbox\emptybox} % scratchbox can be in use + +\ifx\setnotehsize\undefined + + \def\setnotehsize{\hsize\noteparameter\c!width} % can be overloaded + +\fi + +\def\setclevernotes + {\def\startpushnote {\bgroup % wellicht ooit kopuitlijnen + \setupinmargin[\c!align=\v!left]% + \startnotedef}% + \def\stoppushnote {\stopnotedef + \egroup}% + \let\startpopnotes \donothing + \let\stoppopnotes \donothing} + +\def\setcolumnnotes + {\def\startpushnote {\setnotehsize % possibly overloaded + \setrigidcolumnhsize\hsize{\noteparameter\c!columndistance}{\noteparameter\c!n}% + \bgroup + \setupinmargin[\c!align=\v!left]% + \startnotedef}% + \def\stoppushnote {\stopnotedef + \egroup}% + \def\startpopnotes {\bgroup + \setnotehsize + \setrigidcolumnhsize\hsize{\noteparameter\c!columndistance}{\noteparameter\c!n}% + \setbox0\vbox\bgroup}% + \def\stoppopnotes {\egroup + \setbox0\vbox + {\unvbox0\setbox0\lastbox + \ifvbox0\unvbox\else\box\fi0}% + \rigidcolumnbalance0\egroup}} + +% \def\settextnotes +% {\def\startpushnote {\startvboxtohbox +% \dostartattributes{\??vn\currentnote}\c!style\c!color\empty}% +% \def\stoppushnote {\hskip\noteparameter\c!columndistance % plus.5em minus.5em +% \dostopattributes +% \stopvboxtohbox}% +% \def\startpopnotes {\vbox\bgroup +% \doifnotinset{\noteparameter\c!width}{\v!fit,\v!broad}\setnotehsize +% \beginofshapebox}% +% \def\stoppopnotes {\endofshapebox +% \reshapebox{\ifhbox\shapebox\unhbox\else\box\fi\shapebox\endgraf}% +% \flushshapebox +% \egroup}} +% +% this was wrong (for ages) + +% \def\settextnotes +% {\def\startpushnote {\startvboxtohbox +% \dostartattributes{\??vn\currentnote}\c!style\c!color\empty}% +% \def\stoppushnote {\hskip\noteparameter\c!columndistance % plus.5em minus.5em +% \dostopattributes +% \stopvboxtohbox}% +% %\def\startpopnotes {\vbox\bgroup +% % \doifnotinset{\noteparameter\c!width}{\v!fit,\v!broad}\setnotehsize} +% %\def\stoppopnotes {\convertvboxtohbox +% % \egroup}% +% \def\startpopnotes {\vbox\bgroup +% \doifnotinset{\noteparameter\c!width}{\v!fit,\v!broad}\setnotehsize +% \beginofshapebox}% +% \def\stoppopnotes {\endofshapebox +% \doreshapebox{\box\shapebox}{}{}{}% get rid of penalties etc +% \innerflushshapebox +% \convertvboxtohbox +% \egroup}% +% } + +\def\settextnotes + {\def\startpushnote {\startvboxtohbox + \edef\@@defaultnotedefloc{\ifnum\noteparameter\c!n=\zerocount\v!serried\else\v!inleft \fi}% + \edef\@@defaultnotedefdis{\ifnum\noteparameter\c!n=\zerocount .5em\else\!!zeropoint\fi}% + \startnotedef}% + \def\stoppushnote {\stopnotedef + \hskip\noteparameter\c!columndistance % plus.5em minus.5em + \stopvboxtohbox}% + \def\startpopnotes {\vbox\bgroup + % here, else problems in preroll + \doifnotinset{\noteparameter\c!width}{\v!fit,\v!broad}\setnotehsize + \beginofshapebox}% + \def\stoppopnotes {\endofshapebox + \doreshapebox{\box\shapebox}{}{}{}% get rid of penalties etc + \innerflushshapebox + \convertvboxtohbox + \egroup}} + +%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. + +\newif\ifnotesymbol + +\unexpanded\def\setnote {\dotripleempty\dosetnote[1]} +\unexpanded\def\setnotetext{\dotripleempty\dosetnote[0]} + +\def\dosetnote[#1][#2][#3]% + {\unskip + \def\currentnote{#2}% + \dochecknote % sometimes needed for local notes + \ifcase#1\relax + \global\notesymbolfalse + \else + \global\notesymboltrue + \fi + \ifvisible % misty feature, make it obsolete + \ifreshapingbox + \@EAEAEA\gobbletwoarguments + \else + \@EAEAEA\dodonote + \fi + \else % todo: \iftrialtypesetting + \@EA\gobbletwoarguments + \fi{#3}} + +%D \macros +%D {notesenabled} +%D +%D Before we come to typesetting a footnote, we first check +%D if we have to typeset a number. When a \type{-} is passed +%D instead of a reference, no number is typeset. We can +%D temporary disable footnotes by saying +%D +%D \starttyping +%D \notesenabledfalse +%D \stoptyping +%D +%D which can be handy while for instance typesetting tables +%D of contents. The pagewise footnote numbering is dedicated +%D to Han The Thanh, who needed it first. + +\newif\ifnotesenabled \notesenabledtrue + +\appendtoks \notesenabledfalse \to \everymarking + +\newconditional\pagewisenotes % saves two hash entries + +\def\lastnotepage{1} + +\def\domovednote#1#2% + {\ifconditional\pagewisenotes + \doifreferencefoundelse{\s!fnt:t:\number\internalnotereference} + {\let\savedrealreference\currentrealreference + \doifreferencefoundelse{\s!fnt:f:\number\internalnotereference} + {\ifnum\savedrealreference<\currentrealreference\relax\symbol[#1]\else + \ifnum\savedrealreference>\currentrealreference\relax\symbol[#2]\fi\fi} + \donothing} + \donothing + \fi} + +% maybe some day +% +% \newconditional\tracemovednotes +% \def\domovednote#1#2% +% {\iflocation +% \doshowmovednote{#1}{#2}% +% \else\ifconditional\tracemovednotes +% \doshowtracednote{#1}{#2}% +% \fi\fi} +% \def\doshowmovednote#1#2% +% {\doifreferencefoundelse{\s!fnt:t:\number\internalnotereference} +% {\let\savedrealreference\currentrealreference +% \doifreferencefoundelse{\s!fnt:f:\number\internalnotereference} +% {\ifnum\savedrealreference<\currentrealreference\relax +% \symbol[#1]% +% \else\ifnum\savedrealreference>\currentrealreference\relax +% \symbol[#2]% +% \fi\fi} +% \donothing} +% \donothing} +% \def\doshowtracednote#1#2% +% {\doifreferencefoundelse{\s!fnt:t:\number\internalnotereference} +% {\let\savedrealreference\currentrealreference +% \doifreferencefoundelse{\s!fnt:f:\number\internalnotereference} +% {\ifnum\savedrealreference<\currentrealreference\relax +% \writestatus{NOTE}{forward note reference on real page \currentrealreference}% +% \else\ifnum\savedrealreference>\currentrealreference\relax +% \writestatus{NOTE}{backward note reference on real page \currentrealreference}% +% \fi\fi} +% \donothing} +% \donothing} + +\def\dodonote + {\ifnotesenabled + \iftrialtypesetting + \@EAEAEA\nododonote + \else + \@EAEAEA\dododonote + \fi + \else + \@EA\gobbletwoarguments + \fi} + +% \def\nododonote#1% +% {\doifnot{#1}{-}{\kern.5em}% quick hack, approximation +% \gobbleoneargument} +% +% more correct: + +\long\def\nododonote#1#2% + {\doifnot{#1}{-} + {\ifconditional\pagewisenotes + \doifreferencefoundelse{\s!fnt:t:\number\internalnotereference} + {\ifnum\currentrealreference>\lastnotepage\relax + \globallet\lastnotepage\currentrealreference + \resetnumber[\currentnote]% + \fi} + {}% + \fi + \incrementnumber[\currentnote]% + \makesectionnumber[\currentnote]% + \let\lastnotenumber\composedsectionnumber + \dolastnotesymbol + \decrementnumber[\currentnote]}} + +\def\dododonote#1% + {\global\advance\internalnotereference\plusone + \doifelse{\noteparameter\c!way}{\v!by\v!page} + {\settrue\pagewisenotes} + {\setfalse\pagewisenotes}% + \doifelse{#1}{-} + {\let\lastnotenumber\empty} + {\ifconditional\pagewisenotes + \doifreferencefoundelse{\s!fnt:t:\number\internalnotereference} + {\ifnum\currentrealreference>\lastnotepage\relax + \globallet\lastnotepage\currentrealreference + \resetnumber[\currentnote]% + \fi} + {}% + \fi + \incrementnumber[\currentnote]% + \makesectionnumber[\currentnote]% + \rawreference\s!fnt{#1}\composedsectionnumber + \let\lastnotenumber\composedsectionnumber}% + \dostartnote} + +%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. + +\def\dostartlocalnoteinsert + {\dochecknote + \ifendnotes + \global\setbox\localpostponednotes\vbox\bgroup + \ifvoid\localpostponednotes\else\unvbox\localpostponednotes\fi + \else + \insert\currentnoteins\bgroup + \fi} + +\let\startlocalnoteinsert\dostartlocalnoteinsert +\let\stoplocalnoteinsert \egroup + +%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 + +\def\footnotereferencefrom + {\rawreference\s!fnt{\s!fnt:f:\number\internalnotereference}{}} + +\def\footnotereferenceto + {\global\advance\crossreferencenumber\minusone\relax % else problem, needs further testing + \rawreference\s!fnt{\s!fnt:t:\number\internalnotereference}{}} + +\def\dostartnote% nog gobble als in pagebody + {\pushsomestates + \bgroup + \settrue\processingnote + %\restorecatcodes % to be tested first + \iftypesettinglines % otherwise problems with \type {xxx} + \ignorelines % makes footnotes work in \startlines ... \stoplines + \fi + \ifnotesymbol + \dolastnotesymbol + \else + \unskip\unskip + \globallet\lastnotesymbol\dolastnotesymbol + \fi + \startlocalnoteinsert + \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 + \startpushnote + {\ifx\lastnotenumber\empty \else + \preparefullnumber{\??vn\currentnote}\lastnotenumber\preparednumber + \doifelse{\noteparameter\c!interaction}\v!no + {\noteparameter\c!numbercommand + {\preparednumber\domovednote\v!nextpage\v!previouspage}}% + {\gotobox{\noteparameter\c!command % was \c!numbercommand, but compatible + {\preparednumber\domovednote\v!nextpage\v!previouspage}}% + [\s!fnt:f:\number\internalnotereference]}% + \fi + \doifelse{\noteparameter\c!interaction}\v!no + {\ifconditional\pagewisenotes + \footnotereferenceto + \fi}% + {\footnotereferenceto}}% + \bgroup + \postponenotes + \aftergroup\dostopnote + \begstrut + \let\next} + +\def\dostopnote + {\endstrut + \stoppushnote + \egroup + \stoplocalnoteinsert + \kern\notesignal\relax % \relax is needed to honor spaces + \popsomestates} + +\def\dolastnotesymbol + {\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 + {\dodonotesymbol{\lastnotenumber\domovednote\v!previouspage\v!nextpage}% + \ifconditional\pagewisenotes + \footnotereferencefrom + \fi} + {\gotobox + {\dodonotesymbol{\lastnotenumber\domovednote\v!previouspage\v!nextpage}}% + [\s!fnt:t:\number\internalnotereference]% + \footnotereferencefrom}% + \globallet\lastnotesymbol\relax} + +\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 +% \def\currentnote{#1}% +% \ifsecondargument +% \ifx\lastnotesymbol\relax +% \unskip +% \naarbox{\high{\tx\currenttextreference}}[#2]% +% \else +% \lastnotesymbol +% \fi +% \else +% \lastnotesymbol +% \fi +% \fi +% \egroup} + +\def\dodonotesymbol#1% + {\noteparameter\c!textcommand{\doattributes{\??vn\currentnote}\c!textstyle\c!textcolor{#1}}} + +% \def\donotesymbol[#1][#2]% +% {\bgroup +% \ifnotesenabled +% \def\currentnote{#1}% +% \ifsecondargument +% \ifx\lastnotesymbol\relax % bugged +% \unskip +% \gotobox{\dodonotesymbol\currenttextreference}[#2]% +% \else +% \lastnotesymbol +% \fi +% \else +% \lastnotesymbol +% \fi +% \fi +% \egroup} + +\def\donotesymbol[#1][#2]% + {\bgroup + \ifnotesenabled + \def\currentnote{#1}% + \ifsecondargument + \unskip + \gotobox{\dodonotesymbol\currenttextreference}[#2]% + \else + \lastnotesymbol + \fi + \fi + \egroup} + +%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. + +\let\startpopnotes = \relax +\let\stoppopnotes = \relax + +\def\placenoteinserts + {\processnotes\doplacenoteinserts} + +% testcase for split bottom alignment see (a) below +% +% \dorecurse{6}{\input tufte\footnote{\input ward \input tufte \relax}} + +\def\doplacenoteinserts + {%\ifvoid\currentnoteins \else % unsafe, strange + \relax\ifdim\ht\currentnoteins>\zeropoint\relax + \dochecknote + \ifendnotes \else + \noteparameter\c!before + \placenoterule % alleen in ..mode + \bgroup + \setnotebodyfont + \setbox0\hbox + {\startpopnotes + \setnotebodyfont +% % 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\unvcopy\else\unvbox\fi\currentnoteins +% \unvbox\currentnoteins + \or +\iftrialtypesetting\copy\else\box\fi\currentnoteins +% \box\currentnoteins + \obeydepth % (a) added , since split footnotes will not align properly + \else +\iftrialtypesetting\unvcopy\else\unvbox\fi\currentnoteins +% \unvbox\currentnoteins + \fi + % this is too ugly actually + \stoppopnotes}% + \setbox2\hbox + {\localframed + [\??vn\currentnote] + [\c!width=\v!fit, + \c!height=\v!fit, + \c!strut=\v!no, + \c!offset=\v!overlay] + {\ifdim\dp0=\zeropoint % this hack is needed because \vadjust + \hbox{\lower\strutdp\box0}% % in margin number placement + \else % hides the (always) present depth + \box0 + \fi}}% + \setbox2\hbox{\lower\strutdepth\box2}% + \dp2=\strutdepth % so we know that it has the note bodyfont depth + \box2 + \egroup + \noteparameter\c!after + \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\postponednote + +\def\autopostponenotes + {\def\startlocalnoteinsert % not global + {\ifinner + %\message{[postponed note]}% + \global\setbox\localpostponednotes\vbox\bgroup + \global\settrue\postponednote + \ifvoid\localpostponednotes\else\unvbox\localpostponednotes\fi + \else + %\message{[inserted note]}% + \expandafter\dostartlocalnoteinsert + \fi}} + +\def\postponenotes + {\let\autopostponenotes\postponenotes + \let\postponenotes\relax % prevent loops + \def\startlocalnoteinsert % not global + {%\message{[postponed note]}% + \global\setbox\localpostponednotes\vbox\bgroup + \global\settrue\postponednote +% \unvbox\localpostponednotes}} + \ifvoid\localpostponednotes\else\unvbox\localpostponednotes\fi}} + +\def\dodoflushnotes % per class, todo: handle endnotes here + {\ifdim\ht\localpostponednotes>\zeropoint + \bgroup + \dochecknote + \ifendnotes \else + % not that accurate when multiple notes + \ifdim\dimexpr\pagegoal-\pagetotal\relax<\ht\localpostponednotes + \message{[moved note \currentnote]}% + \fi + \insert\currentnoteins\bgroup\unvbox\localpostponednotes\egroup + \fi + \egroup + \fi} + +\def\doflushnotes % also called directly, \ifvoid is needed ! + {\ifconditional\processingnote \else \ifconditional\postponednote + \let\localnoteinsert\normalnoteinsert % not global + \processnotes\dodoflushnotes + \global\setfalse\postponednote + \fi \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} + +%D For old times sake: + +\def\flushfootnotes {\flushnotes} +\def\doflushfootnotes{\doflushnotes} + +%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} + +%D There are several placement alternatives. + +\def\placenotesintext#1% + {\ifdim\ht#1>\zeropoint + \endgraf + \ifvmode + \whitespace + \noteparameter\c!before + \fi + \snaptogrid\hbox + {\setnotebodyfont + \setbox0\hbox + {\startpopnotes + \unvbox#1\endgraf\relax + \stoppopnotes}% + \doif{\noteparameter\c!width}\v!fit % new, auto width + {\setbox0\hbox % uggly but ok. + {\beginofshapebox + \unhbox0\setbox0=\lastbox\unvbox0 + \endofshapebox + \reshapebox{\hbox{\unhbox\shapebox}}% + \vbox{\flushshapebox}}}% + \localframed + [\??vn\currentnote] + [ \c!width=\v!fit, + \c!height=\v!fit, + \c!strut=\v!no, + \c!offset=\v!overlay] + {\ifdim\dp0=\zeropoint % this hack is needed because \vadjust + \hbox{\lower\strutdp\box0}% % in margin number placement + \else % hides the (always) present depth + \box0 + \fi}}% + \ifvmode + \noteparameter\c!after + \fi + \fi} + +%D A stupid alternative is also provided: +%D +%D \starttyping +%D \setupfootnotes[location={text,none}] +%D \stoptyping + +\def\placenotesasnone#1% is grouped already + {\ifdim\ht#1>\zeropoint + \noteparameter\c!before + \setnotebodyfont + \startpopnotes % make sure that fake height is killed + \unvbox#1\endgraf + \stoppopnotes + % weird + \ifhmode + \setbox0=\lastbox \ifvbox0 \unvbox0\else\box0\fi % enable columns + \fi + \noteparameter\c!after + \fi} + +%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} + +\def\defaultnotewidth{\makeupwidth} + +% \def\collectlocalnotes +% {\def\localnoteinsert##1% was \gdef, but never reset! +% {%\message{[local note]}% +% \global\setbox\localpostponednotes\vbox\bgroup +% \ifvoid\localpostponednotes \else +% \unvbox\localpostponednotes +% \fi +% \let\next}} + +\def\collectlocalnotes + {\def\startlocalnoteinsert% was \gdef, but never reset! + {%\message{[local note]}% + \global\setbox\localpostponednotes\vbox\bgroup + \ifvoid\localpostponednotes\else\unvbox\localpostponednotes\fi}} + +\def\startlocalnotes + {\bgroup % here because we support \vbox\startlocalnotes + \dosingleempty\dostartlocalnotes} + +\chardef\localnodemode\zerocount + +\def\dostartlocalnotes[#1]% + {\let\autopostponenotes\postponenotes + \let\postponenotes\collectlocalnotes + \chardef\localnodemode\plusone % new + \def\defaultnotewidth{\ifdim\hsize<\makeupwidth\hsize\else\makeupwidth\fi}% + \processnotes + {\doifsomething{#1}{\setupnote[\currentnote][#1]}% + \savenumber[\currentnote]% + \resetnumber[\currentnote]}% + \collectlocalnotes} + +\def\stoplocalnotes + {\processnotes{\restorenumber[\currentnote]}% + \egroup + \checknotes} % really needed, else wrong main settings + +\def\placelocalnotes + {\dodoubleempty\doplacelocalnotes} + +\def\doplacelocalnotes[#1][#2]% + {\bgroup + \chardef\localnodemode\plusone % new + \dolocalsetupnotes{#1}{#2}% + \processnotes\dodoplacelocalnotes + \egroup + \checknotes} % probably not needed + +\def\dodoplacelocalnotes + {\dochecknote + \expanded{\doifinsetelse{\v!none}{\noteparameter\c!location}} + \placenotesasnone\placenotesintext + \localpostponednotes} + +%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\dodoplacenotes} + +% \definecomplexorsimple\placenotes + +% \def\simpleplacenotes +% {\processnotes\dodoplacenotes} + +% \def\complexplacenotes[#1]% +% {\bgroup +% \edef\noteinsertions{#1}% +% \simpleplacenotes +% \egroup} + +\def\placenotes + {\dodoubleempty\doplacenotes} + +\def\doplacenotes[#1][#2]% + {\bgroup + \dolocalsetupnotes{#1}{#2}% + \processnotes\dodoplacenotes + \egroup} + +\def\dodoplacenotes + {\dochecknote + \ifendnotes + \ifinpagebody \else \ifdim\ht\localpostponednotes>\zeropoint + \expanded{\doifinsetelse{\v!none}{\noteparameter\c!location}} + \placenotesasnone\placenotesintext\localpostponednotes + \fi \fi + \else \ifdim\ht\currentnoteins>\zeropoint + \placenoteinserts + \fi \fi} + +%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 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 + +% \definenote +% [mynote] +% [way=bypage, +% location={page,high}, +% factor=0, +% width=\leftmarginwidth, +% scope=page, +% rule=, +% before=, +% after=] +% +% \setuptexttexts +% [margin] +% [\vbox to \textheight{\placenotes[mynote]\vfill}] +% [] + +%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} + \def\stoplocalfootnotes {\stoplocalnotes } + +\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} + +%D Backward compatibility command: + +\def\footins {\noteinsertion\currentnote} +\def\postponefootnotes {\postponenotes} +\def\autopostponefootnotes{\autopostponenotes} + +%D New trickery: + +\def\ownnotesymbol#1% #1 gets number passed + {\executeifdefined{\??vn::\currentnote}\empty} + +\def\setnotesymbol[#1]#2#3% + {\prewordbreak % prevent lookback + \gdef\lastnotenumber{#2}% + \setgvalue{\??vn::#1}{#3} + \dolastnotesymbol} + +\def\ownnote[#1]#2#3#4% + {\setnotesymbol[#1]{#2}{#3}% + \setnotetext [#1]{#4}} + +\defineconversion + [ownnote] + [\ownnotesymbol] + +%D Usage: + +% maybe we should predefine this one + +% \definenote +% [glossary] +% [way=bypage, +% location={page,high}, +% factor=0, +% width=\leftmarginwidth, +% scope=page, +% conversion=ownnote, +% numbercommand=, +% textcommand=, +% textstyle=, +% rule=, +% before=, +% after=] +% +% \setupnotedefinition +% [glossary] +% [location=left, +% width=fit, +% distance=.5em, +% align={right,tolerant,stretch}, +% headstyle=bold, +% hang=1] +% +% \setuplayout +% [width=middle, +% height=middle, +% backspace=5cm, +% margin=4cm, +% margindistance=.25cm, +% cutspace=2cm] +% +% \setuptexttexts +% [margin] +% [\setups{glossary}] +% [\setups{glossary}] +% +% \startsetups glossary +% \vbox to \textheight {\placenotes[glossary]\vfill} +% \stopsetups +% +% \dorecurse{10} +% {\dorecurse{5} +% {\ownnote[glossary]{whow}{whatever needs to be glossed:~\recurselevel}% +% \input tufte \relax}} + +\protect \endinput + +% \def\myfootnote[#1]#2% let's guess that #2 is without catcode problems +% {\setgvalue{note:t:#1}% +% {\setxvalue{note:l:#1}{\getvalue{note:n:#1}}% +% \footnote[note:a:#1:\getvalue{note:l:#1}]{#2}}% +% \setgvalue{note:n:#1}% +% {1}% +% \getvalue{note:t:#1}}% + +% \def\mynote[#1]% +% {\removeunwantedspaces +% \scratchcounter\getvalue{note:n:#1}\relax +% \edef\NoteNumber{\the\scratchcounter}% +% \doglobal\incrementvalue{note:n:#1}\relax +% \doifreferencefoundelse{note:a:#1:1} +% {\edef\NotePageA{\number\currentrealreference}% +% \doifreferencefoundelse{note:a:#1:\getvalue{note:n:#1}} +% {\edef\NotePageB{\number\currentrealreference}% +% \doifreferencefoundelse{note:a:#1:\NoteNumber} +% {\ifnum\currentrealreference=\NotePageB\relax +% \pagereference[note:a:#1:\getvalue{note:n:#1}]% +% \note[note:a:#1:\getvalue{note:l:#1}]% +% \else\ifnum\NotePageA=\NotePageB\relax +% \pagereference[note:a:#1:\getvalue{note:n:#1}]% +% \note[note:a:#1:\getvalue{note:l:#1}]% +% \else +% \getvalue{note:t:#1}% +% \fi\fi} +% {\ifnum\NotePageA=\NotePageB\relax +% \pagereference[note:a:#1:\getvalue{note:n:#1}]% +% \note[note:a:#1:\getvalue{note:l:#1}]% +% \else +% \getvalue{note:t:#1}% +% \fi}} +% {\pagereference[note:a:#1:\getvalue{note:n:#1}]% +% \note[note:a:#1:\getvalue{note:l:#1}]}} +% {\pagereference[note:a:#1:\getvalue{note:n:#1}]% +% \note[note:a:#1:\getvalue{note:l:#1}]}} + +% \starttext + +% funny \myfootnote[funny]{funny} funny \mynote[funny] \page + +% funny \mynote[funny] funny \mynote[funny] funny \mynote[funny] \page +% funny \mynote[funny] funny \mynote[funny] \page +% funny \mynote[funny] funny \mynote[funny] funny \mynote[funny] \page + +% \stoptext diff --git a/tex/context/base/strc-not.mkiv b/tex/context/base/strc-not.mkiv new file mode 100644 index 000000000..45e37b276 --- /dev/null +++ b/tex/context/base/strc-not.mkiv @@ -0,0 +1,1280 @@ +%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 + +% this needs a further cleanup ... +% +% -- set breakpoin in descriptions +% -- reset after trialtypesetting +% -- that way we can trick the symbol space + +% 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 + +% better mark a note .. once flushed no more flushing + +%appendtoks \notesenabledfalse \to \everymarking +\appendtoks \notesenabledfalse \to \everypagebody +\appendtoks \notesenabledfalse \to \everystructurelist % quick hack + +%D Often we need to process the whole set of notes and to make that +%D fast, we use a token register: + +\newtoks\tobeprocessednotes + +\unexpanded\def\processnotes#1% #1: \macro that uses \currentnote + {\def\doprocesssomenote##1{\edef\currentnote{##1}\let\currentdescription\currentnote#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\namednoteparameter#1#2{\csname\donoteparameter{\??vn#1}#2\endcsname} + +\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. + +\unexpanded\def\setupnotes + {\dodoubleargument\getparameters[\??vn]} + +\setupnotes + [\c!location=\v!page, + \c!way=\v!by\v!part, + %\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!next=\autoinsertnextspace + \c!prefix=\v!no, + %\c!continue=\v!no, + \c!n=1] + +\setupnotes + [\c!expansion=\v!no, + \c!xmlsetup=, + \s!catcodes=, + \c!saveinlist=\v!yes] + +\def\@@defaultnotedefloc{\v!inleft} +\def\@@defaultnotedefdis{\!!zeropoint} + +\unexpanded\def\startnotedef{\resetdescriptions\csname\e!start\??vn\??vn\currentnote\endcsname} +\unexpanded\def\stopnotedef {\csname\e!stop \??vn\??vn\currentnote\endcsname} + +\def\currentnoteins{\csname\??vn:\currentnote\endcsname} + +\newtoks \everysetupnote + +\unexpanded\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, % hm + \c!headcolor=\noteparameter\c!color, % hm + \s!handler=\v!note, + \c!text=, + \c!before=, + \c!after=]% + \doredefinenotecommands\currentnote + \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 + \dochecknote} + +% \starttext +% text \startfootnote Test.\stopfootnote +% test \footnote{xxxx} \subfootnote{xxxx} +% test \footnote{xxxx} \subfootnote{xxxx} +% \stoptext + +\def\dodoredefinenotecommands#1#2#3% + {\unexpanded\expandafter\def\csname\e!start#3#1\expandafter\endcsname\expandafter + {\expandafter\dosingleempty\csname\s!do\e!start#3#1\endcsname}% + \unexpanded\expandafter\def\csname\s!do\e!start#3#1\expandafter\endcsname + \expandafter[\expandafter##\expandafter1\expandafter]\expandafter##\expandafter2\csname\e!stop#3#1\endcsname + {\begingroup + \doenumerationinit{#1}{#2}{#3}% + \@@notemakedescription[##1]{}{##2}% + \endgroup}} + +\def\doredefinenotecommands#1% + {\normalexpanded{\noexpand\dodoredefinenotecommands{#1}{1}{}}% + \let\@@subslevel\empty + \dostepwiserecurse{2}{\descriptionparameter\c!levels}{1} + {\normalexpanded{\noexpand\dodoredefinenotecommands{#1}{\recurselevel}{\@@subslevel\v!sub}}% + \edef\@@subslevel{\@@subslevel\v!sub}}} + +\let\setupnotedefinition\setupenumerations + +\appendtoks + \setupenumerations[\currentnote][]% +\to \everysetupnote + +% \appendtoks +% \dochecknote +% \to \everysetupnote + +\unexpanded\def\setupnote + {\dodoubleempty\dosetupnote} + +\def\dosetupnote[#1][#2]% + {\edef\currentnote{#1}% + \ifsecondargument + \getparameters[\??vn\currentnote][#2]% + \the\everysetupnote + \fi + \dochecknote} + +\appendtoks + \setvalue{\??vn\c!rule:c:\currentnote}{\normalnoterule}% hm + \letvalue{\??vn\c!rule:a:\currentnote}\v!left +\to \everysetupnote + +\appendtoks + \expanded{\processallactionsinset + [\noteparameter\c!rule]} + [ \v!on=>\setvalue{\??vn\c!rule:c:\currentnote}{\normalnoterule}, % no let as it can be changed afterwards + \v!normal=>\setvalue{\??vn\c!rule:c:\currentnote}{\normalnoterule}, + \v!left=>\setvalue{\??vn\c!rule:a:\currentnote}{l2r}, + \v!right=>\setvalue{\??vn\c!rule:a:\currentnote}{r2l}, + \v!off=>\letvalue{\??vn\c!rule:c:\currentnote}\relax, + \s!default=>\letvalue{\??vn\c!rule:c:\currentnote}\relax, + \s!unknown=>\setvalue{\??vn\c!rule:c:\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, will be redone + {\numexpr\ifcase\namednoteparameter\v!footnote\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} + +\setvalue{\??vn @\v!page }{\setnotelocation\plusone} +\setvalue{\??vn @\v!columns }{\setnotelocation\plustwo} +\setvalue{\??vn @\v!lastcolumn }{\setnotelocation\plusthree} +\setvalue{\??vn @\v!firstcolumn}{\setnotelocation\plusfour} +\setvalue{\??vn @\v!none }{\setnotelocation\plusfive} +\setvalue{\??vn @\v!text }{\setnotelocation\plusfive \setnoteformatting\plusone} % test +\setvalue{\??vn @\v!high }{\setnoteposition\plusone} +\setvalue{\??vn @\v!bottom }{\setnoteposition\plustwo} + +\def\dosetcheckednote#1{\csname\??vn @#1\endcsname} + +\def\dochecknote + {% node states + \setnotelocation\plusone + \setnoteposition\plustwo + \normalexpanded{\noexpand\rawprocesscommalist[\noteparameter\c!location]}\dosetcheckednote + % 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 -> tricky as this might depend on a font switch so we need a fast checker + \dosetnotedistance + % 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\dosetnotedistance + {\begingroup + \setbox\scratchbox\vbox + {\forgetall + \dontcomplain + \noteparameter\c!before + \placenoterule + \noteparameter\c!after}% + \global\skip\currentnoteins\ht\scratchbox + \endgroup} + +% \def\checknotes % no longer needed +% {\processnotes\dochecknote} +% +% \def\checknotedistances +% {\processnotes\dosetnotedistance} +% +% fails but not that much needed anyway: +% +% \appendtoks +% \checknotedistances +% \to \everyglobalbodyfont + +% 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. + +%D A bit messy: + +\unexpanded\def\placenoterule + {\bgroup + \setupalign[\getvalue{\??vn\c!rule:a:\currentnote}]% + \righttoleft + \getvalue{\??vn\c!rule:c:\currentnote}% + \par + \egroup} + +\unexpanded\def\normalnoterule + {\ifvmode + \dontleavehmode \blackrule + [ \c!color=\noteparameter\c!rulecolor, + \c!width=.2\hsize, + \c!height=\noteparameter\c!rulethickness, + \c!depth=\zeropoint]% + \endgraf + \kern\strutdepth + \fi} + +\ifx\setnotehsize\undefined + + \unexpanded\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). +%D +%D \starttyping +%D \setupenumerations +%D [footnote] +%D [ style=\type{(es)}, +%D headstyle=\type{(hs)}] +%D +%D \setupnote +%D [footnote] +%D [ style=\type{(s)}, +%D command=\type{(c)}, +%D textcommand=\type{(tc)}, +%D textstyle=\type{(ts)}, +%D numberstyle=\type{(ns)}, +%D numbercommand=\type{(nc)}] +%D +%D \setuplayout[backspace=6cm,marginwidth=cm,width=middle] +%D +%D \starttext +%D \dorecurse{9}{This\footnote{Hello World #1} is a test.\par } +%D \stoptext +%D \stoptyping + +% TODO: \ifnotesenabled + +\newif\ifnotesymbol \notesymboltrue + +\newconditional\skipnoteplacement + +\unexpanded\def\setnote [#1]{\getvalue{#1}} +\unexpanded\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:\s!text }{\@@donotetext} +\setvalue{\??dd:\v!note:\s!handler:\s!number}{\@@donotenumber} +\setvalue{\??dd:\v!note:\s!handler }{\@@donotehandler} +\setvalue{\??dd:\v!note:\s!handler:\s!do }{\@@somenotedescription} +\setvalue{\??dd:\v!note:\s!handler:\s!start }{\@@startsomenotedescription} + +\let\@@donotehandler\@@dodescriptionhandler + +\def\@@somenotedescription {\@@notemakedescription} +\def\@@startsomenotedescription{\@@notemakedescription} + +\def\@@notemakedescription[#1]#2#3% + {\ifnotesenabled + \edef\currentdescriptionreference{#1}% + \iftrialtypesetting + \doenumerationcheckconditions + \let\currentnote\currentdescriptionmain + \typesetdummynotesymbol + \else + \begingroup + \doenumerationcheckconditions + \let\currentnote\currentdescriptionmain + \dodescriptioncomponent[\c!reference=#1,\c!label={\descriptionparameter\c!text},\c!title={#3},\c!list=,\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 % todo: per note class + \global\settrue\postponednote + \else\ifconditional\inlocalnotes % todo: per note class + \global\settrue\postponednote + \else + \handlenoteinsert\currentnote\currentnotenumber + \fi\fi + \endgroup + \fi + \fi + \ifconditional\skipnoteplacement + \global\setfalse\skipnoteplacement + \else + \kern\notesignal\relax % \relax is needed to honor spaces + \fi} + +\def\dolastnotesymbol + {\typesetsomenotesymbol\currentnote\currentnotenumber} + +\def\dotypesetsomenotesymbol#1#2% running text + {\dodonotesymbol + {\synchronizesomenotesymbol{#1}{#2}% + \ctxlua{structure.notes.number("\currentnote",\currentnotenumber)}% \currentdescriptionnumberentry + \domovednote{#1}{#2}\v!previouspage\v!nextpage}} + +\unexpanded\def\typesetsomenotesymbol#1#2% running text + {\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}} + {\directgotobox{\dotypesetsomenotesymbol{#1}{#2}}[page(\ctxlua{structure.notes.getnumberpage("#1",\number#2)})]}% f: + \globallet\lastnotesymbol\relax} + +\unexpanded\def\typesetdummynotesymbol % temp hack + {\removeunwantedspaces + \doifitalicelse\/\donothing % Charles IV \footnote{the fourth} + \ifdim\lastkern=\notesignal + \dodonotesymbol{\kern\noteparameter\c!distance}% gets the font right, hack ! + \fi + \nobreak + \hbox to .5em{}% + \globallet\lastnotesymbol\relax} + +\def\currentnotedescriptiontext % todo: can be other number + {\ctxlua{structure.notes.title("\currentnote",\currentdescriptionnumberentry)}} + +\def\@@donotetext + {\ifconditional\enumerationnumberenabled + \iftrialtypesetting + \doenumerationfullnumber\showdntext + \doenumerationcouplingsymbol + \else + \doenumerationregistercoupling + \doenumerationfullnumber\showdntext + \doenumerationcouplingsymbol + \fi + \else + \doenumerationfullnumber\showdnpuretext + \fi} + +% \def\currentnoteenumerationfullnumber +\def\@@donotenumber + {\doifelse{\noteparameter\c!interaction}\v!no + {\docurrentnoteenumerationfullnumber}% + {\directgotobox + {\docurrentnoteenumerationfullnumber}% + [page(\ctxlua{structure.notes.getsymbolpage("\currentnote",\currentdescriptionnumberentry)})]}} + +\def\docurrentnoteenumerationfullnumber + {\noteparameter\c!numbercommand + {\dosetnoteattributes\c!numberstyle\c!numbercolor + \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 + \doprocesslocalsetups{\noteparameter\c!setups}% experimental + \handlenoteitself{#1}{#2}% + \egroup + \the\everyafternoteinsert + \endgroup} + +\def\handlenoteitself#1#2% tg, id + {\edef\currentdescription{#1}% + \edef\currentnote{#1}% + \edef\currentdescriptionnumberentry{#2}% + \edef\currentdescriptionlistentry{\ctxlua{tex.write(structure.notes.listindex("#1",#2))}}% + % as we can have collected notes (e.g. in tables) we need to recover + % \currentdescriptionattribute and \currentdescriptionsynchronize + \reinstatedescriptionnumberentry\currentdescriptionlistentry % we could store the number in the entry + % + \dontcomplain % should be done in startstoreddescription instead + \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\flushnotes\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 + +% not: \appendtoks \setnotehsize \to \everyinsidenoteinsert (spoils columns) + +\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: + +\unexpanded\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}} + +\unexpanded\def\placenoteinserts + {\processnotes\doplacenoteinserts} + +\unexpanded\def\unvboxed {\ifvmode\unvbox \else\box \fi} +\unexpanded\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 +% \bgroup +% \setupalign[\noteparameter\c!align]% + \placenoterule % alleen in ..mode +% \par +% \egroup + \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 % is this needed? + \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 + \global\let\flushnotes\doflushnotes + \ctxlua{structure.notes.postpone()}% + \fi} + +\let\flushnotes\relax + +\def\doflushnotes + {\ifconditional\postponingnotes + \begingroup + \let\flushnotes \relax + \let\postponenotes\relax + \ctxlua{structure.notes.flushpostponed()}% this also resets the states ! + \global\setfalse\postponednote + \global\setfalse\postponingnotes + \global\let\flushnotes\relax + \endgroup + \fi} + +%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\flushnotes \relax + \let\postponenotes\relax +\to \everyplacelocalnotes + +\def\defaultnotewidth{\makeupwidth} % {\ifdim\hsize<\makeupwidth\hsize\else\makeupwidth\fi} + +\newconditional\inlocalnotes + +\unexpanded\def\startlocalnotes + {\dosingleempty\dostartlocalnotes} + +\def\dostartlocalnotes[#1]% + {\def\localnoteslist{#1}% + \settrue\inlocalnotes + \processcommacommand[\localnoteslist]\dodostartlocalnotes} + +\unexpanded\def\stoplocalnotes + {\processcommacommand[\localnoteslist]\dodostoplocalnotes + \setfalse\inlocalnotes} + +\def\dodostartlocalnotes#1% + {\doifnot{\noteparameter\c!continue}\v!yes + {\savestructurecounter[#1]% + \resetstructurecounter[#1]}% + \ctxlua{structure.notes.save("#1","store")}} + +\def\dodostoplocalnotes#1% + {\doifnot{\noteparameter\c!continue}\v!yes + {\restorestructurecounter[#1]}% + \ctxlua{structure.notes.restore("#1")}} + +\unexpanded\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} + +\unexpanded\def\placebottomnotes + {\processnotes\placenoteinserts} + +\unexpanded\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("#2")}}{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} + + % is this ok? endnotes and such + + \unexpanded\def\fakenotes + {\ifhmode\endgraf\fi\ifvmode + \calculatetotalclevernoteheight + \ifdim\totalnoteheight>\zeropoint \kern\totalnoteheight \fi + \fi} + + \unexpanded\def\fakepagenotes + {\ifhmode\endgraf\fi\ifvmode + \calculatetotalpagenoteheight + \ifdim\totalnoteheight>\zeropoint \kern\totalnoteheight \fi + \fi} + + \newdimen\totalnoteheight + + \def\doaddtototalnoteheight#1% + {\ifdim\ht#1>\zeropoint + \ifcase\count#1\else + % todo: divide by count + \advance\totalnoteheight\ht #1% + \advance\totalnoteheight\skip#1% + \fi + \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: + +\unexpanded\def\setupfootnotedefinition{\setupnotedefinition [\v!footnote]} +\unexpanded\def\setupfootnotes {\setupnote [\v!footnote]} +%unexpanded\def\footnote {\setnote [\v!footnote]} +\def\footnotetext {\setnotetext [\v!footnote]} +%unexpanded\def\note {\dodoubleempty\notesymbol [\v!footnote]} % alleen footnote +\unexpanded\def\placefootnotes {\dodoubleempty\doplacefootnotes [\v!footnote]} +\unexpanded\def\placelocalfootnotes {\dodoubleempty\doplacelocalfootnotes[\v!footnote]} +\unexpanded\def\startlocalfootnotes {\startlocalnotes [\v!footnote]} % alleen footnote +\unexpanded\def\stoplocalfootnotes {\stoplocalnotes } + +\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} + +\unexpanded\def\note{\dodoubleempty\donote} + +\def\donote[#1][#2]{\ifsecondargument\donotesymbol[#1][#2]\else\secondargumenttrue\donotesymbol[\v!footnote][#1]\fi} + +%D Goodies: +%D +%D \starttyping +%D \dorecurse {100} { +%D test \footnote{\doifnoteonsamepageelse[footnote]{ibidem}{aaa}} +%D } +%D \stoptyping + +\def\doifnoteonsamepageelse[#1]{\ctxlua{structure.notes.doifonsamepageasprevious("#1")}} + +%D New trickery: + +\def\ownnotesymbol#1% #1 gets number passed + {\executeifdefined{\??vn::\currentnote}\empty} + +\unexpanded\def\setnotesymbol[#1]#2#3% + {\prewordbreak % prevent lookback + \setgvalue{\??vn::#1}{#3} + \dolastnotesymbol} + +\unexpanded\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..8165d0786 --- /dev/null +++ b/tex/context/base/strc-num.lua @@ -0,0 +1,521 @@ +if not modules then modules = { } end modules ['strc-num'] = { + version = 1.001, + comment = "companion to strc-num.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format = string.format +local next, type = next, type +local min, max = math.min, math.max +local texsprint, texcount = tex.sprint, tex.count + +local trace_counters = false trackers.register("structure.counters", function(v) trace_counters = v end) + +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 { } +structure.counters.specials = structure.counters.specials 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 +local counterspecials = counters.specials + +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.start > 0 then + return t.start -- brrr + elseif t.offset then + return t.start + t.step + 1 + else + return t.start + 1 + end + elseif s == "prev" or s == "previous" then + return max(t.first,t.number-1) -- todo: step + elseif s == "next" then + return min(t.last,t.number+1) -- todo: step + elseif s == "backward" then + if t.number - 1 < t.first then + return t.last + else + return t.previous + end + elseif s == "forward" then + if t.number + 1 > t.last then + return t.first + else + return t.next + end + 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, +--~ block = "", -- todo + numbers = nil, + state = 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 + +function counters.record(name,i) + return allocate(name,i or 1) +end + +local function savevalue(name,i) + if name then + 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 + else + return 0 + end +end + +function counters.define(name, start, counter) -- todo: step + local d = allocate(name,1) + d.start = start + if counter ~= "" then + d.counter = counter -- only for special purposes, cannot be false + 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] +--~ print(name,i,d.number) + if d.number ~= 0 then + compact[i] = (onlynumbers and d.number) or d + end + end +--~ print(table.serialize(compact)) + 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 = 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 + + +local function synchronize(name,d) + local dc = d.counter + if dc then + if trace_counters then + logs.report("counters","setting counter %s with name %s to %s",dc,name,d.number) + end + tex.setcount("global",dc,d.number) + end + local cs = counterspecials[name] + if cs then + if trace_counters then + logs.report("counters","invoking special for name %s",name) + end + cs() + end +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 + synchronize(name,d) + 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 + synchronize(name,d) + 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 + synchronize(name,d) + 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) + local level = cd.level + if not level or level == -1 then + -- -1 is signal that we reset manually + elseif level > 0 then + check(name,d,n+1) + elseif level == 0 then + -- happens elsewhere + end + synchronize(name,d) + 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 == 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) + local level = cd.level + if not level or level == -1 then + -- -1 is signal that we reset manually + elseif level > 0 then + -- within countergroup + check(name,data,n+1) + elseif level == 0 then + -- happens elsewhere + end + synchronize(name,d) + return d.number -- not needed + end + return 0 +end + +function counters.check(level) -- not used (yet) + for name, cd in next, counterdata do + -- logs.report("counters","%s %s %s",name,cd.level,level) + if cd.level == level then + if trace_counters then + logs.report("counters","resetting %s at level %s",name,level) + end + counters.reset(name) + 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 spec = spec or { } + local numbers, ownnumbers = { }, { } + local reverse = spec.order == variables.reverse + local kind = spec.type or "number" + local v_first, v_next, v_previous, v_last = variables.first, variables.next, variables.previous, variables.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 + vn = vl - vn + vf -- see testbed for test + 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.mkii b/tex/context/base/strc-num.mkii new file mode 100644 index 000000000..28f69b441 --- /dev/null +++ b/tex/context/base/strc-num.mkii @@ -0,0 +1,151 @@ +%D \module +%D [ file=strc-num, +%D version=1997.03.31, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Numbering, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Numbering} + +\unprotect + +% Commando's ten behoeve van nummeren: +% +% \definenumber[name] +% \setupnumber[name][wijze=,blok=,tekst=,plaats=,conversie=,start=] +% \setnumber[name]{value} +% \resetnumber[name] +% \incrementnumber[name] +% \decrementnumber[name] +% \convertednumber[name] % getnumber +% \savenumber[name] +% \restorenumber[name] +% \convertednumber[name] +% \rawnumber[name] + +% private (defined in core-des.tex) +% +% \nextnumber[name][tag][reference] +% \currentnumber[name] + +\def\@@thenumber#1{\s!number\csname\s!number#1\c!number\endcsname} + +% this will be the new (public) one: \let\numberparameterprefix\@@thenumber + +\def\numberparameter#1#2{\csname\@@thenumber{#1}#2\endcsname} % sort of public + +\def\dosetupnumber[#1][#2]% + {\@EA\let\@EA\savedstartnumber\csname\@@thenumber{#1}\c!start\endcsname + \getparameters[\@@thenumber{#1}][\c!start=,#2]% + \doifelsenothing{\numberparameter{#1}\c!start} + {\letvalue{\@@thenumber{#1}\c!start}\savedstartnumber} + {\setcounter{\@@thenumber{#1}}{\numberparameter{#1}\c!start}}} + +\def\setupnumber + {\dodoubleargument\dosetupnumber} + +\def\definenumber + {\dodoubleempty\dodefinenumber} + +\def\dodefinenumber[#1][#2]% ook overal class als localframed + {\doifassignmentelse{#2} + {\dododefinenumber[#1][#2]} + {\doifelsenothing{#2} % can break on not yet defined macros in #2 + {\dododefinenumber[#1][#2]} + {\setvalue{\s!number#1\c!number}{#2}}}} + +\def\dododefinenumber[#1][#2]% + {\getparameters + [\s!number#1] + [\c!number=#1, + \s!check=, + \c!way=\@@nrway, + \c!way\c!local=\numberparameter{#1}\c!way, + \c!sectionnumber=\v!yes, + \c!text=, % no longer used here, will go away + \c!location=, % no longer used here, will go away (was ooit \c!zetwijze) + \c!conversion=\v!numbers, + \c!start=0, + \c!state=\v!start, + #2]% + \makecounter{\@@thenumber{#1}}% + \setxvalue{\@@thenumber{#1}\c!n}{\countervalue{\@@thenumber{#1}}}% + \setcounter{\@@thenumber{#1}}{\numberparameter{#1}\c!start}} + +\def\setnumber[#1]#2% + {\setcounter{\@@thenumber{#1}}{#2}} + +\def\resetnumber[#1]% + {\setcounter{\@@thenumber{#1}}{0\numberparameter{#1}\c!start}} + +\def\savenumber[#1]% + {\savecounter{\@@thenumber{#1}}} + +\def\restorenumber[#1]% + {\restorecounter{\@@thenumber{#1}}} + +%D Bonus macro (we need to keep this one for downward +%D compatibility reasons). + +\def\doreset[#1]% + {\processcommalist[#1]\dodoreset} + +\def\dodoreset#1% + {\getvalue{\s!reset#1}}% + +\def\reset + {\dosingleargument\doreset} + +\def\incrementnumber[#1]% bypage tricky: needs a + {\doifelse{\numberparameter{#1}\c!way}{\v!by\v!page} + {\checkpagechange{#1}% + \ifpagechanged\resetcounter{\@@thenumber{#1}}\fi} + {\checknumber[#1]}% + \doifelse\@@nrstate\v!start % only here + {\doif{\numberparameter{#1}\c!state}\v!start{\pluscounter{\@@thenumber{#1}}}} + {\setcounter{\@@thenumber{#1}}{0\numberparameter{#1}\c!start}}} + +% \defineenumeration [test] [way=bypage,text=\lastchangedpage] +% +% \starttext \dorecurse{10}{\test \input tufte \par} \stoptext + +\def\decrementnumber[#1]% + {\minuscounter{\@@thenumber{#1}}} + +\def\convertednumber[#1]% + {\convertnumber + {\numberparameter{#1}\c!conversion} + {\countervalue{\@@thenumber{#1}}}} + +\def\rawnumber[#1]% + {\countervalue{\@@thenumber{#1}}} + +\def\accumulatednumber[#1]% + {\getvalue{\@@thenumber{#1}\c!n}} + +\let\getnumber\convertednumber + +\def\doifdefinednumber #1{\doifdefined {\csname\s!number#1\c!number\endcsname}} +\def\doifundefinednumber #1{\doifundefined {\csname\s!number#1\c!number\endcsname}} +\def\doifdefinednumberelse#1{\doifdefinedelse{\csname\s!number#1\c!number\endcsname}} + +\ifx\checknumber\undefined \def\checknumber[#1]{} \fi + +% ook de pag nummers hierheen halen ivm \@@nrwijze + +\def\setupnumbering + {\dodoubleempty\getparameters[\??nr]} + +\setupnumbering + [\c!way=\v!by\v!chapter, + \c!blockway=, + \c!sectionnumber=\v!yes, + \c!state=\v!start] + +\protect \endinput diff --git a/tex/context/base/strc-num.mkiv b/tex/context/base/strc-num.mkiv new file mode 100644 index 000000000..5b5aebe7d --- /dev/null +++ b/tex/context/base/strc-num.mkiv @@ -0,0 +1,511 @@ +%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 + +\unexpanded\def\setupstructurecountering{\dodoubleempty\getparameters[\??nn]} + +\setupstructurecountering + [\c!way=\v!by\v!chapter, +% \c!blockway=, +% \c!prefixstarter=, +% \c!prefixstopper=, + \c!prefixconnector=., + \c!prefixsegments=\thenamedstructurecounterlevel\currentstructurecounter, + \c!start=0, + \c!state=\v!start, + \c!prefix=\v!yes, + \c!state=\v!start] + +\setupstructurecountering + [\c!prefixsegments=\autostructureprefixsegments\sharedstructurecounterparameter] + +\def\autostructureprefixsegments#1% todo: \c!prefixsegments=\v!auto + {2:\thenamedstructureheadlevel{\ctxlua{structure.sections.way("#1\c!way","\v!by")}}} + +% \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\sharedstructurecounterparameter#1% + {\csname + \ifcsname\??nn#1\endcsname + \??nn#1% + \else + \s!empty + \fi + \endcsname} + +\let\numberingparameter\sharedstructurecounterparameter + +% \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} + +\unexpanded\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,"\structurecounterparameter{#1}\s!counter")}% + \docheckstructurecountersetup{#1}} + +\def\donodefinestructurecounter[#1][#2]% inherit + {\getparameters[\??nn#1][\c!number=#2]% + \docheckstructurecountersetup{#1}} + +\unexpanded\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{#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", + starter = \!!bs\structurecounterparameter{#1}\c!prefixstarter\!!es, + 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", + starter = \!!bs\structurecounterparameter{#1}\c!numberstarter\!!es, + stopper = \!!bs\structurecounterparameter{#1}\c!numberstopper\!!es, + segments = "\structurecounterparameter{#1}\c!numbersegments", + type = "\structurecounterparameter{#1}\c!type", + criterium = "\structurecounterparameter{#1}\c!criterium", % might change if we also want this with sectioning + } + )}% + \endgroup} + +\def\directconvertedstructurecounter#1#2% name, type + {\begingroup + \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", + % starter = \!!bs\structurecounterparameter{#1}\c!prefixstarter\!!es, + % 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", + starter = \!!bs\structurecounterparameter{#1}\c!numberstarter\!!es, + stopper = \!!bs\structurecounterparameter{#1}\c!numberstopper\!!es, + segments = "\structurecounterparameter{#1}\c!numbersegments", + type = "#2", + } + )}% + \endgroup} + +\unexpanded\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 + +\unexpanded\def\setupnumbering + {\dodoubleempty\getparameters[\??nr]} + +\setupnumbering + [\c!way=\v!by\v!chapter, + \c!blockway=, + \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[\s!haslevel=1,#8]% + \edef\hasstructurecountercaption{#3\s!hascaption}% + \edef\hasstructurecountertitle {#3\s!hastitle}% + \edef\hasstructurecounternumber {#3\s!hasnumber}% + \edef\hasstructurecounterlevel {#3\s!haslevel}% + % + \edef\askedprefixsegments{#3\c!prefixsegments}% + \ifx\askedprefixsegments\v!auto + \edef\askedprefixsegments{\autostructureprefixsegments#3}% + \fi + % + \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 % here due to previous test but best in callers + \doincrementsubstructurecounter[\currentcounter][\hasstructurecounterlevel]% + \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", + segments = "\askedprefixsegments", + 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", + starter = \!!bs#3\c!numberstarter\!!es, + stopper = \!!bs#3\c!numberstopper\!!es, + segments = "#3\c!numbersegments", + }, + \fi + userdata = structure.helpers.touserdata(\!!bs\detokenize{#9}\!!es) + } + }}% + \xdef\laststructurecounterattribute {\ctxlua {tex.write(jobreferences.setinternalreference(nil,nil,\nextinternalreference))}}% + \xdef\laststructurecountersynchronize{\ctxlatelua{structure.lists.enhance(\laststructurecounternumber)}}% + \else + \glet\laststructurecounternumber \relax + \glet\laststructurecounterattribute \attributeunsetvalue + \glet\laststructurecountersynchronize\relax + \fi + \endgroup} + +\let\laststructurecounternumber \relax +\let\laststructurecounterattribute \relax +\let\laststructurecountersynchronize\relax + +\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!prefixstarter=#2\c!prefixstarter, + \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!numberstarter=#2\c!numberstarter, + \c!numberstopper=#2\c!numberstopper, + \c!numbersegments=#2\c!numbersegments]} + +\def\presetstructurecountersetup#1#2% \setupcommand \someparameter + {#1% + [\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!prefixstarter =#2\c!prefixstarter, + \c!prefixstopper =#2\c!prefixstopper, + \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!numberstarter =#2\c!numberstarter, + \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..261059587 --- /dev/null +++ b/tex/context/base/strc-pag.lua @@ -0,0 +1,241 @@ +if not modules then modules = { } end modules ['strc-pag'] = { + version = 1.001, + comment = "companion to strc-pag.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local texcount, format = tex.count, string.format + +local ctxcatcodes = tex.ctxcatcodes +local texsprint, texwrite = tex.sprint, tex.write + +local trace_pages = false trackers.register("structure.pages", function(v) trace_pages = v end) + +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 = { } -- to be checked + +function pages.save(prefixdata,numberdata) + local realpage, userpage = texcount.realpageno, texcount.userpageno + if realpage > 0 then + if trace_pages then + logs.report("pages","saving page %s.%s",realpage,userpage) + end + local data = { + number = userpage, + block = sections.currentblock(), + prefixdata = prefixdata and helpers.simplify(prefixdata), + numberdata = numberdata and helpers.simplify(numberdata), + } + tobesaved[realpage] = data + if not collected[realpage] then + collected[realpage] = data + end + elseif trace_pages then + logs.report("pages","not saving page %s.%s",realpage,userpage) + end +end + +function structure.counters.specials.userpage() + local r = texcount.realpageno + if r > 0 then + local t = tobesaved[r] + if t then + t.number = texcount.userpageno + if trace_pages then + logs.report("pages","forcing pagenumber of realpage %s to %s",r,t.number) + end + end + 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 = texcount.realpageno, specification = deltaspec } +--~ else +--~ return { realpage = texcount.realpageno } +--~ end +--~ end + +local function convertnumber(str,n) + return format("\\convertnumber{%s}{%s}",str or "numbers",n) +end + +function pages.number(realdata,pagespec) + local userpage, block = realdata.number, realdata.block or "" -- sections.currentblock() + local numberspec = realdata.numberdata + local conversionset = (pagespec and pagespec.conversionset ~= "" and pagespec.conversionset) or (numberspec and numberspec.conversionset ~= "" and numberspec.conversionset) or "" + local conversion = (pagespec and pagespec.conversion ~= "" and pagespec.conversion ) or (numberspec and numberspec.conversion ~= "" and numberspec.conversion ) or "" + local starter = (pagespec and pagespec.starter ~= "" and pagespec.starter ) or (numberspec and numberspec.starter ~= "" and numberspec.starter ) or "" + local stopper = (pagespec and pagespec.stopper ~= "" and pagespec.stopper ) or (numberspec and numberspec.stopper ~= "" and numberspec.stopper ) or "" + if starter ~= "" then + processors.sprint(ctxcatcodes,starter) + end + if conversion ~= "" then + texsprint(ctxcatcodes,format("\\convertnumber{%s}{%s}",conversion,userpage)) + 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.prefixdata + 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, e = pages.analyse(data,pagespec) + if pagedata then + if prefixdata then + sections.typesetnumber(prefixdata,"prefix",prefixspec or false,prefixdata or false,pagedata.prefixdata 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 or r.section, r.lastrealpage or r.realpage + 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 yes, no = variables.yes, 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, status = helpers.analyse(data,prefixspec) + if prefixdata then + sections.typesetnumber(prefixdata,"prefix",prefixspec or false,data.prefixdata or false,prefixdata or false) + end + end +end + +function pages.is_odd(n) + n = n or texcount.realpageno + if texcount.pagenoshift % 2 == 0 then + return n % 2 == 0 + else + return n % 2 ~= 0 + end +end diff --git a/tex/context/base/strc-pag.mkii b/tex/context/base/strc-pag.mkii new file mode 100644 index 000000000..5a86a99e8 --- /dev/null +++ b/tex/context/base/strc-pag.mkii @@ -0,0 +1,534 @@ +%D \module +%D [ file=strc-num, % moved here from main-001 +%D version=1997.03.31, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Numbering, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Numbering} + +% todo: {}{}{} ipv ...--...-...-...--... in pag ref + +\unprotect + +% \gotonextsubpage : voor de pagebody +% \subpaginanummer : alleen in de voet/kopregels +% \aantalsubpaginas : alleen in de voet/kopregels + +% \firstsubpage : eerste \realpageno, voor interne doeleinden +% \prevsubpage : vorige \realpageno, voor interne doeleinden +% \nextsubpage : volgende \realpageno, voor interne doeleinden +% \lastsubpage : laatste \realpageno, voor interne doeleinden +% \nofsubpages : laatste subpage (in berekeningen) +% \subpageno : huidige subpage (in berekeningen) + +\newif\ifsubpaging +\newif\ifshowingsubpage + +\definenumber + [\s!subpage] + +\setupnumber + [\s!subpage] + [\c!way=\@@snway] + +% hard to sync +% +% \def\resetsubpagenumber +% {\resetnumber[\s!subpage]% +% \global\subpageno=\rawnumber[\s!subpage]} +% +% better sync + +\newif\ifresettingsubpagenumber + +\def\resetsubpagenumber + {\global\resettingsubpagenumbertrue} + +% so far for sync, see \gotonext... + +\def\dosetupsubpagenumber[#1]% + {\doifelse{#1}\v!reset + \resetsubpagenumber % \resetnumber[\s!subpage] + {\getparameters[\??sn][#1]% + \processaction + [\@@snstate] + [ \v!stop=>\ifsubpaging + \resetsubpagenumber % new, see sync + \else + \subpagingfalse + \fi + \showingsubpagefalse, + \v!start=>\subpagingtrue + \showingsubpagetrue, + \v!none=>\subpagingtrue + \showingsubpagefalse]}} + +\def\numberofsubpages + {\ifshowingsubpage\nofsubpages\else0\fi} + +\def\subpagenumber + {\ifshowingsubpage\the\subpageno\else0\fi} + +\def\setupsubpagenumber + {\dosingleargument\dosetupsubpagenumber} + +\def\newnofsubpages{0} +\def\nofsubpages {0} +\def\firstsubpage {1} +\def\prevsubpage {1} +\def\nextsubpage {1} +\def\lastsubpage {1} + +\def\nextpage {1} +\def\prevpage {1} + +\definetwopasslist\s!subpage + +\def\savenofsubpages + {\ifsubpaging + \showmessage\m!layouts6{\newnofsubpages,\the\subpageno}% + \immediatesavetwopassdata{\s!subpage}{\newnofsubpages}{\the\subpageno}% + \fi} + +\def\setsubpagenumbers + {\iftwopassdatafound + \bgroup + \xdef \nofsubpages {\twopassdata}% + \xdef \firstsubpage {\realfolio}% + \advance\realpageno \nofsubpages + \advance\realpageno \minusone + \xdef \lastsubpage {\realfolio}% + \egroup + \else + \xdef \nofsubpages{0}% + \fi} + +\def\gotonextsubpage % overlapt behoorlijk met realpage macro + {\global\let\checksubpages\relax + \ifresettingsubpagenumber + \resetnumber[\s!subpage]% + \global\resettingsubpagenumberfalse + \fi + \ifsubpaging + \xdef\oldsubpage{\the\subpageno}% + \incrementnumber[\s!subpage]% + \global\subpageno\rawnumber[\s!subpage]\relax + \ifnum\subpageno=\plusone + \gettwopassdata\s!subpage + \setsubpagenumbers + \ifnum\oldsubpage>\zerocount + \showmessage\m!layouts6{\newnofsubpages,\oldsubpage}% + \savetwopassdata{\s!subpage}{\newnofsubpages}{\oldsubpage}% + \fi + \doglobal\increment\newnofsubpages\relax + \fi + \setglobalsystemreference\rt!page\v!firstsubpage\firstsubpage + \setglobalsystemreference\rt!page\v!lastsubpage\lastsubpage + \bgroup + \ifnum\realpageno=\firstsubpage\relax + \global\let\prevsubpage\firstsubpage + \setglobalsystemreference\rt!page\v!subbackward\lastsubpage + \else + \xdef\prevsubpage{\realfolio}% + \doglobal\decrement\prevsubpage + \setglobalsystemreference\rt!page\v!subbackward\prevsubpage + \fi + \setglobalsystemreference\rt!page\v!previoussubpage\prevsubpage + \ifnum\realpageno=\lastsubpage\relax + \global\let\nextsubpage\lastsubpage + \setglobalsystemreference\rt!page\v!subforward\firstsubpage + \else + \xdef\nextsubpage{\realfolio}% + \doglobal\increment\nextsubpage + \setglobalsystemreference\rt!page\v!subforward\nextsubpage + \fi + \setglobalsystemreference\rt!page\v!nextsubpage\nextsubpage + \egroup + \fi} + +\def\checksubpages + {\getfromtwopassdata\s!subpage1% + \setsubpagenumbers + \global\let\checksubpages\relax} + +% Omdat \gotonextrealpage gebruik maakt van de hulpfile, +% moet het initialiseren van \realpageno plaatsvinden in +% een later stadium, namelijk zodra referenties worden +% gebruikt (anders gaat het mis op nog niet gedefinieerde +% lijstcommando's e.d.). De eerst aanroep vindt dan ook +% plaats vlak nadat de hulpfile voor de eerste maal is +% ingelezen. + +\countdef\realpageno = 0 \realpageno = 1 +\countdef\userpageno = 1 \userpageno = 1 +\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 + +\newcount\pageno \pageno = 1 + +\def\setuserpageno#1% + {\global\userpageno#1\relax + \global\pageno\userpageno} + +\def\realfolio {\the\realpageno} +\def\folio {\the\userpageno} +\def\firstpage {1} +\def\lastpage {1} +\def\currentpage {\the\realpageno} +\def\lastpagenumber{1} + +\def\gotonextrealpage + {\global\advance\realpageno \plusone\relax + \ifnum\realpageno>\lastpage + \xdef\lastpage{\realfolio}% + \fi + \setglobalsystemreference\rt!page\v!firstpage \firstpage + \setglobalsystemreference\rt!page\v!lastpage\lastpage + \bgroup + \ifnum\realpageno>\plusone + \advance\realpageno \minusone + \xdef\prevpage{\realfolio}% + \setglobalsystemreference\rt!page\v!backward\prevpage + \else + \global\let\prevpage\firstpage + \setglobalsystemreference\rt!page\v!backward\lastpage + \fi + \setglobalsystemreference\rt!page\v!previouspage\prevpage + \egroup + \bgroup + \ifnum\realpageno<\lastpage\relax + \advance\realpageno \plusone + \xdef\nextpage{\realfolio}% + \setglobalsystemreference\rt!page\v!page\nextpage + \setglobalsystemreference\rt!page\v!forward\nextpage + \bgroup + \xdef\nextnextpage{\realfolio}% + \ifodd\realpageno + \setglobalsystemreference\rt!page\v!nextoddpage\nextnextpage + \else + \setglobalsystemreference\rt!page\v!nextevenpage\nextnextpage + \fi + \advance\realpageno \plusone + \xdef\nextnextpage{\realfolio}% + \ifnum\realpageno>\lastpage\relax + %\ifodd\realpageno + % \setglobalsystemreference\rt!page\v!nextoddpage\lastpage + %\else + % \setglobalsystemreference\rt!page\v!nextevenpage\lastpage + %\fi + \else + \ifodd\realpageno + \setglobalsystemreference\rt!page\v!nextoddpage\nextnextpage + \else + \setglobalsystemreference\rt!page\v!nextevenpage\nextnextpage + \fi + \fi + \egroup + \else + \global\let\nextpage\lastpage + \setglobalsystemreference\rt!page\v!page\firstpage + \setglobalsystemreference\rt!page\v!forward\firstpage + \setglobalsystemreference\rt!page\v!nextoddpage\lastpage + \setglobalsystemreference\rt!page\v!nextevenpage\lastpage + \fi + \setglobalsystemreference\rt!page\v!nextpage\realfolio + \egroup} + +\def\checkrealpage + {\global\realpageno\zerocount + \gotonextrealpage + \global\let\checkrealpage\relax} + +\def\savenofpages + {\bgroup + \advance\realpageno \minusone + \savecurrentvalue\lastpage\realfolio + \advance\userpageno \minusone + \savecurrentvalue\lastpagenumber\folio + \egroup} + +\def\totalnumberofpages + {\lastpage} + +\def\setpagecounters + {\setuserpageno{\rawnumber[\s!page]}% + \doifelse\@@snstate\v!stop + {\global\subpageno\zerocount} + {\global\subpageno\rawnumber[\s!subpage]}\relax} + +% Standaard is \count0 in Plain TeX de paginateller. Omwille +% van de afhandeling van lokaal nummeren, definieren we +% echter een eigen nummer. + +\definenumber + [\s!page] + [\c!conversion=\@@nmconversion, + \c!way=\@@nmway, + \c!state=\@@nmstate, + \c!start=1] + +% \@@pnstatus global, but \@@nmstatus local and only start/stop + +\global\let\@@pnstate\@@pnstate % brrr + +\def\pushpagestate{\globalpushmacro\@@pnstate} +\def\poppagestate {\globalpopmacro \@@pnstate} + +\def\dosetuppagenumber[#1]% + {\getparameters[\??pn][\c!number=,#1]% + \global\let\@@pnstate\@@pnstate + \doifsomething\@@pnnumber + {\setnumber[\s!page]{\@@pnnumber}% + \setuserpageno{\rawnumber[\s!page]}}% + % this makes starting at an even page possible + \ifnum\realpageno=1 \ifodd\pageno \else + \global\shiftedrealpagenotrue + \fi \fi} + +\def\setuppagenumber + {\dosingleargument\dosetuppagenumber} + +\def\dodecrementpagenumber + {\decrementnumber[\s!page]\setuserpageno{\rawnumber[\s!page]}} + +\def\doincrementpagenumber + {\incrementnumber[\s!page]\setuserpageno{\rawnumber[\s!page]}} + +\def\dosynchronizepagenumber + {\global\let\@@pnstate\v!start} + +\def\decrementpagenumber{\getvalue{\??pn-\@@pnstate}} +\def\incrementpagenumber{\getvalue{\??pn+\@@pnstate}} + +\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 + +% so far + +\def\checkpagecounter + {\checknumber[\s!page]} + +% \getpagestatus +% \ifrightpage als odd/singlesided + +\newif\ifrightpage \rightpagetrue + +\newcounter \nofpagesets + +\definetwopasslist\s!page + +\def\dopagesetreference + {\doglobal\increment\nofpagesets\relax + \lazysavetwopassdata{\s!page}{\nofpagesets}{\noexpand\realfolio}} + +\def\getpagestatus % hierboven gebruiken + {\ifdoublesided + \gettwopassdata\s!page + \iftwopassdatafound \else + \let\twopassdata\realpageno + \fi + \ifodd\twopassdata + \global\rightpagetrue + \else + \global\rightpagefalse + \fi + \dopagesetreference + \else + \global\rightpagetrue + \fi} + +\def\@@nmin {} % kan vervallen (upward compatibility) +\def\@@nmlocation {} % mag {plaats, in} zijn + +\newcounter\@@pagenumberlocation + +\def\do@@plaatspaginanummer#1% + {\ifnum#1=\@@pagenumberlocation\@@plaatspaginanummer\fi} + +\def\dodosetpagenumberlocation#1% tricky because of ...texts + {\increment\@@pagenumberlocation + \ifx\@@nmlocation\empty\else + \def\dododosetpagenumberlocation##1% + {\donetrue + \setevalue{\??tk#1##1}{\noexpand\do@@plaatspaginanummer{\@@pagenumberlocation}}}% + \donefalse + \ExpandFirstAfter\processallactionsinset + [\@@nmlocation] + [ \v!middle=>\dododosetpagenumberlocation{\v!text\c!middletext}, + \v!left=>\dododosetpagenumberlocation{\v!text\c!lefttext}, + \v!right=>\dododosetpagenumberlocation{\v!text\c!righttext}, + \v!inleft=>\dododosetpagenumberlocation{\v!margin\c!lefttext}, + \v!inright=>\dododosetpagenumberlocation{\v!margin\c!righttext}, + \v!inmargin=>\dododosetpagenumberlocation{\v!margin\ifdoublesided\c!margintext\else\c!righttext\fi}, + \v!margin=>\dododosetpagenumberlocation{\v!margin\ifdoublesided\c!margintext\else\c!righttext\fi}, + \v!atmargin=>\dododosetpagenumberlocation{\v!text\c!marginedgetext}, + \v!marginedge=>\dododosetpagenumberlocation{\v!text\c!marginedgetext}]% + \ifdone \else + \dododosetpagenumberlocation{\v!text\c!middletext}% default + \fi + \fi} + +\def\dosetpagenumberlocation + {\ExpandBothAfter\doifinsetelse\v!header{\@@nmlocation,\@@nmin} + {\dodosetpagenumberlocation\v!header} + {\dodosetpagenumberlocation\v!footer }} + +\def\dosetuppagenumbering[#1]% + {\getparameters[\??nm][#1]% + \preparepageprefix\??nm + \singlesidedfalse + \doublesidedfalse + \ExpandFirstAfter\processallactionsinset + [\@@nmalternative] + [ \v!singlesided=>\singlesidedtrue, + \v!doublesided=>\doublesidedtrue]% + \ifx\trackingmarginnotestrue\undefined\else + \ifdoublesided + \trackingmarginnotestrue + \else + \trackingmarginnotesfalse + \fi + \fi + \dosetpagenumberlocation + \recalculatebackgrounds + \recalculatelogos} + +\def\setuppagenumbering + {\dosingleempty\dosetuppagenumbering} + +\let\stelnummeringin\setuppagenumbering + +% wrong +% +% \def\preparepageprefix#1% +% {\def\dopreparepageprefix##1% +% {\doifvalue{#1##1\c!number}{\v!yes} +% {\setvalue{#1\getvalue{\??by##1}\c!nummer}{\v!yes}}}% +% \processcommacommand[\@@kolijst]\dopreparepageprefix} +% +% more wrong +% +% \def\preparepageprefix#1% +% {\def\dopreparepageprefix##1% +% {\doifelsevalue{#1##1\v!number}{\v!yes} % v +% {\setvalue{#1\getvalue{\??by##1}\v!nummer}{\v!yes}} % v +% {\setvalue{#1\getvalue{\??by##1}\v!nummer}{\v!no}}}% % v +% \processcommacommand[\@@kolijst]\dopreparepageprefix} +% +% best, beware, chapter (yes) can be followed by title (no) + +\def\preparepageprefix#1% + {\def\dopreparepageprefix##1% + {\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 + {\ifcsname\??by##1\endcsname\letvalue{#1\csname\??by##1\endcsname\v!number}\v!yes\fi}}% + \rawprocesscommalist[\@@kolist]\dopreparepageprefix} + +\def\dodopageprefix#1% uti seperator -- + {\let\normaluchar\uchar \let\uchar\relax % ugly but needed + \doifelsevalue{\pageprefixtype#1\v!number}\v!yes % \v! and no \c! + {\edef\preprefix {\@@filterheadpart[\postprefix]}% + \edef\postprefix{\@@filtertailpart[\postprefix]}% + \let\uchar\normaluchar % ugly but needed + \ifx\preprefix\empty \else + \ifx\preprefix\zerocountervalue\else + \preprefix\@@nmnumberseparator + \fi + \fi} + {\edef\postprefix{\@@filtertailpart[\postprefix]}% + \let\uchar\normaluchar}} % ugly but needed + +\def\dopageprefix#1% + {\dodopageprefix{#1}% + \donexttracklevel{#1}} + +\chardef\pageprefixmode\plusone + +\def\pageprefix#1[#2]% + {\ifcase\pageprefixmode + % skip + \or + \bgroup + \edef\pageprefixtype{#1}% + \edef\postprefix{\@@filternumberpart[#2]}% + \let\donexttrackcommando\dopageprefix + \donexttrackcommando\firstsection + \egroup + \fi} + +%D It was Marco Kuhlmann who uncovered the missing strut. This +%D was a pretty old bug kind of covered up by the fact that non +%D oldstyle numbers are about as high as strutheight. Rather +%D interesting that it went unnoticed for so long. + +\unexpanded\def\@@plaatspaginanummer % called in empty tests + {\doif{\@@nmstate\@@pnstate}{\v!start\v!start} + {{\doif\@@nmstrut\v!yes\strut + \@@nmcommand{\doattributes\??nm\c!style\c!color{\completepagenumber}}}}} + +\def\userfolio {\convertednumber[\s!page]} % naast realfolio +\def\pagenumber{\userfolio} + +\def\pageprefixes + {\let\donexttrackcommando\dopageprefixes + \donexttrackcommando\firstsection} + +\def\dopageprefixes#1% + {\doifvalue{\??nm#1\v!number}\v!yes % v + {\ifnum\countervalue{\??se#1}>\zerocount + \getvalue{#1\c!number}\@@nmnumberseparator + \fi}% + \doifsomething\@@nmtext{\@@nmtext\@@nmnumberseparator}% strange option, what was the purpose of text? + \donexttracklevel{#1}} + +\unexpanded\def\completepagenumber + {\doif{\@@nmstate\@@pnstate}{\v!start\v!start} + {\@@nmleft\labeltexts\v!pagenumber{\pageprefixes\pagenumber}\@@nmright}} + +\unexpanded\def\placepagenumber + {\doif{\@@nmstate\@@pnstate}{\v!start\v!start} + {\labeltexts\v!pagenumber{\pagenumber}}} + +% Nog een variant; wat is een goeie naam? + +% \unexpanded\def\placexxpagenumber +% {\@@plaatspaginanummer} + +% \def\translatednumber[#1::#2::#3]{#3} + +\def\translatednumber{\@@filterpagepart} + +\unexpanded\def\referencepagenumber[#1]% + {\doifelsenothing{#1}{?}% + {\preparepageprefix\??rf + \pageprefix\??rf[#1]\translatednumber[#1]}} + +\setuppagenumber + [\c!state=\v!start, + \c!number=1] + +\setupsubpagenumber + [\c!way=\v!by\v!part, + \c!state=\v!stop] + +\protect \endinput diff --git a/tex/context/base/strc-pag.mkiv b/tex/context/base/strc-pag.mkiv new file mode 100644 index 000000000..0f3d7ba3b --- /dev/null +++ b/tex/context/base/strc-pag.mkiv @@ -0,0 +1,496 @@ +%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 + +% Allocation: + +\countdef\realpageno = 0 \realpageno = 1 +\countdef\userpageno = 1 \userpageno = 1 +\countdef\subpageno = 2 \subpageno = 0 % !! +\countdef\arrangeno = 3 \arrangeno = 0 % !! +\countdef\pagenoshift = 4 \pagenoshift = 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] + +% \definestructureconversionset[frontpart:pagenumber][][romannumerals] +% \definestructureconversionset[bodypart:pagenumber] [][numbers] +% +% \setupuserpagenumber[way=byblock] +% \setupuserpagenumber[way=bychapter] +% \setupuserpagenumber[numberconversionset=pagenumber] +% +% \starttext +% \startfrontmatter +% \completecontent[criterium=all] +% \chapter{tufte} \section{one} \input tufte \page \section{two} \input tufte \page +% \chapter{tufte} \section{one} \input tufte \page \section{two} \input tufte \page +% \stopfrontmatter +% \startbodymatter +% \chapter{knuth} \section{one} \input knuth \page \section{two} \input knuth \page \section{three} \input knuth \page +% \chapter{knuth} \section{one} \input knuth \page \section{two} \input knuth \page \section{three} \input knuth \page +% \stopbodymatter +% \stoptext + + +\definestructurecounter[\s!realpage][\c!prefix=\v!no,\c!start=1,\c!prefixsegments=,\s!counter=realpageno] +\definestructurecounter[\s!userpage][\c!prefix=\v!no,\c!start=1,\c!prefixsegments=,\s!counter=userpageno] +\definestructurecounter[\s!subpage] [\c!prefix=\v!no,\c!start=1,\c!prefixsegments=,\s!counter=subpageno] + +\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 + +\unexpanded\def\setuprealpagenumber{\dosingleargument\dosetuprealpagenumber} +\unexpanded\def\setupuserpagenumber{\dosingleargument\dosetupuserpagenumber} +\unexpanded\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 + +\def\savecurrentpagestate % \normalexpanded? + {\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", + segments = "\structurecounterparameter\s!userpage\c!prefixsegments", + connector = \!!bs\structurecounterparameter\s!userpage\c!prefixconnector\!!es, + },{ + conversion = "\structurecounterparameter\s!userpage\c!numberconversion", + conversionset = "\structurecounterparameter\s!userpage\c!numberconversionset", + starter = \!!bs\structurecounterparameter\s!userpage\c!numberstarter\!!es, + stopper = \!!bs\structurecounterparameter\s!userpage\c!numberstopper\!!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] + +% 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} + +% \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\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]} + +\def\firstrealpage{\firststructurecounter[\s!realpage]} +\def\firstuserpage{\firststructurecounter[\s!userpage]} +\def\firstsubpage {\firststructurecounter[\s!subpage ]} + +\def\prevrealpage {\prevstructurecounter [\s!realpage]} +\def\prevuserpage {\prevstructurecounter [\s!userpage]} +\def\prevsubpage {\prevstructurecounter [\s!subpage ]} + +\def\nextrealpage {\nextstructurecounter [\s!realpage]} +\def\nextuserpage {\nextstructurecounter [\s!userpage]} +\def\nextsubpage {\nextstructurecounter [\s!subpage ]} + +\def\lastrealpage {\laststructurecounter [\s!realpage]} +\def\lastuserpage {\laststructurecounter [\s!userpage]} +\def\lastsubpage {\laststructurecounter [\s!subpage ]} + +\let\firstpage\firstrealpage +\let\prevpage \prevrealpage +\let\nextpage \nextrealpage +\let\lastpage \lastrealpage + +% Compatibility counters: + +\def\nofrealpages {\lastrealpage} \def\totalnumberofpages{\lastrealpage} +\def\nofuserpages {\lastuserpage} \def\lastpagenumber {\lastuserpage} +\def\nofsubpages {\lastsubpage } + +% Renderers: + +\def\pagenumber {\rawstructurecounter[\s!userpage]} +\def\prefixedpagenumber {\directconvertedstructurecounter\s!userpage\empty} % \userpagenumber + +\def\realpagenumber {\directconvertedstructurecounter\s!realpage\empty} +\def\userpagenumber {\directconvertedstructurecounter\s!userpage\empty} +\def\subpagenumber {\directconvertedstructurecounter\s!subpage \empty} + +\def\firstrealpagenumber{\directconvertedstructurecounter\s!realpage\v!first} +\def\firstuserpagenumber{\directconvertedstructurecounter\s!userpage\v!first} +\def\firstsubpagenumber {\directconvertedstructurecounter\s!subpage \v!first} + +\def\lastrealpagenumber {\directconvertedstructurecounter\s!realpage\v!last} +\def\lastuserpagenumber {\directconvertedstructurecounter\s!userpage\v!last} +\def\lastsubpagenumber {\directconvertedstructurecounter\s!subpage \v!last} + +\def\prevrealpagenumber {\directconvertedstructurecounter\s!realpage\v!previous} +\def\prevuserpagenumber {\directconvertedstructurecounter\s!userpage\v!previous} +\def\prevsubpagenumber {\directconvertedstructurecounter\s!subpage \v!previous} + +\def\nextrealpagenumber {\directconvertedstructurecounter\s!realpage\v!next} +\def\nextuserpagenumber {\directconvertedstructurecounter\s!userpage\v!next} +\def\nextsubpagenumber {\directconvertedstructurecounter\s!subpage \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{\the\realpageno} +\def\userpage{\the\userpageno} +\def\subpage {\the\subpageno} + +% Hooks: + +\def\currentpage{\the\realpageno}% rather useless + +\appendtoks + \ifnum\realpageno>\lastpage \globallet\lastpage\lastrealpage \fi +\to \everyinitializepagecounters + +% States: + +\newif\ifrightpage \rightpagetrue +\newif\ifdoublesided +\newif\ifsinglesided + +% Realpage and subpage numbers: + +\def\setnextrealpageno{\global\realpageno\incrementedstructurecounter[\s!realpage]\relax} +\def\setnextsubpageno {\global\subpageno \incrementedstructurecounter[\s!subpage ]\relax} + +% Page numbers: (can move to lua) + +\def\dodecrementpagenumber {\global\userpageno\decrementedstructurecounter[\s!userpage]\relax} +\def\doincrementpagenumber {\global\userpageno\incrementedstructurecounter[\s!userpage]\relax} + +\def\decrementsubpagenumber{\global\subpageno \decrementedstructurecounter[\s!subpage ]\relax} +\def\incrementsubpagenumber{\global\subpageno \incrementedstructurecounter[\s!subpage ]\relax} + +\def\dosynchronizepagenumber{\global\let\@@pnstate\v!start} + +\def\decrementpagenumber{\csname\??pn-\structurecounterparameter\s!userpage\c!state\endcsname} +\def\incrementpagenumber{\csname\??pn+\structurecounterparameter\s!userpage\c!state\endcsname} + +\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 + +% Control: + +\def\getpagestatus % hierboven gebruiken + {\ifdoublesided + \global\rightpagetrue + % todo: \global\rightpagetrue or \global\rightpagefalse + \else + \global\rightpagetrue + \fi} + +% Setup general page numbering + +\newtoks\everysetuppagenumbering + +\unexpanded\def\setuppagenumbering + {\dosingleempty\dosetuppagenumbering} + +\def\dosetuppagenumbering[#1]% + {\getparameters[\??nm][#1]\the\everysetuppagenumbering} + +\appendtoks + \singlesidedfalse + \doublesidedfalse + \normalexpanded{\noexpand\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 + +\def\flushfinallayoutpage + {\doifsomething\@@nmpage{\doifnot\@@nmpage\v!no{\page[\@@nmpage]}}} + +% 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!page=\v!last, + \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=]}% + \userpageno\rawstructurecounter[\s!userpage]% + \fi +\to \everysetupuserpagenumber % todo: set state: none, start, stop, reset + +\appendtoks + \edef\askedsubpagenumber{\structurecounterparameter\s!subpage\c!number}% + \ifx\askedsubpagenumber\empty \else + \normalexpanded{\noexpand\setupsubpagenumber[\c!start=\structurecounterparameter\s!subpage\c!number,\c!number=]}% + \subpageno\rawstructurecounter[\s!subpage]% + \fi +\to \everysetupsubpagenumber % todo: set state: none, start, stop, reset + +% \setuplayout[width=300pt,backspace=4cm] +% \setuppagenumbering [alternative=doublesided] +% \setupuserpagenumber[start=2] +% \starttext \dorecurse{20}{\input knuth \par} \stoptext + +\def\checkpagenumbershift + {\userpageno\rawstructurecounter[\s!userpage]\relax + \ifnum\realpageno=\plusone + \ifodd\userpageno + \else + \global\pagenoshift\plusone + \fi + \fi} + +\appendtoks % todo: set state: none, start, stop, reset + % this makes starting at an even page possible + \checkpagenumbershift +\to \everysetupuserpagenumber + +\appendtoks % todo: set state: none, start, stop, reset + % this makes starting at an even page possible + \checkpagenumbershift +\to \everysetuppagenumbering + +\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..b1a1fb0a9 --- /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.mkiv", + 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.mkiv b/tex/context/base/strc-prc.mkiv new file mode 100644 index 000000000..2955a396b --- /dev/null +++ b/tex/context/base/strc-prc.mkiv @@ -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). + +\unexpanded\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..475ab318a --- /dev/null +++ b/tex/context/base/strc-ref.lua @@ -0,0 +1,1243 @@ +if not modules then modules = { } end modules ['strc-ref'] = { + version = 1.001, + comment = "companion to strc-ref.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format, find, gmatch, match, concat = string.format, string.find, string.gmatch, string.match, table.concat +local lpegmatch = lpeg.match +local texsprint, texwrite, texcount, texsetcount = tex.sprint, tex.write, tex.count, tex.setcount + +local trace_referencing = false trackers.register("structure.referencing", function(v) trace_referencing = v end) + +local ctxcatcodes = tex.ctxcatcodes +local variables = interfaces.variables +local constants = interfaces.constants + +-- 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 + +-- the useddata and pagedata names might change +-- todo: pack exported data + +jobreferences = jobreferences or { } +jobreferences.tobesaved = jobreferences.tobesaved or { } +jobreferences.collected = jobreferences.collected 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 { } +jobreferences.exporters = jobreferences.exporters or { } +jobreferences.imported = jobreferences.imported or { } + +storage.register("jobreferences/defined", jobreferences.defined, "jobreferences.defined") + +local tobesaved, collected = jobreferences.tobesaved, jobreferences.collected +local defined, derived, specials = jobreferences.defined, jobreferences.derived, jobreferences.specials +local exporters, runners = jobreferences.exporters, jobreferences.runners + +local currentreference = nil + +local initializers = { } +local finalizers = { } + +function jobreferences.registerinitializer(func) -- we could use a token register instead + initializers[#initializers+1] = func +end +function jobreferences.registerfinalizer(func) -- we could use a token register instead + finalizers[#finalizers+1] = func +end + +local function initializer() + tobesaved, collected = jobreferences.tobesaved, jobreferences.collected + for i=1,#initializers do + initializers[i](tobesaved,collected) + end +end +local function finalizer() + tobesaved = jobreferences.tobesaved + for i=1,#finalizers do + finalizers[i](tobesaved) + end +end + +if job then + job.register('jobreferences.collected', jobreferences.tobesaved, initializer, finalizer) +end + +-- todo: delay split till later as in destinations we split anyway + +local orders, lastorder = { }, 0 + +local function setnextorder(kind,name) + lastorder = 0 + if kind and name then + local ok = orders[kind] + if not ok then + ok = { } + orders[kind] = ok + end + lastorder = (ok[name] or 0) + 1 + ok[name] = lastorder + end + texsetcount("global","locationorder",lastorder) +end + +jobreferences.setnextorder = setnextorder + +function jobreferences.setnextinternal(kind,name) + setnextorder(kind,name) -- always incremented with internal + texsetcount("global","locationcount",texcount.locationcount + 1) +end + +function jobreferences.currentorder(kind,name) + texwrite((orders[kind] and orders[kind][name]) or lastorder) +end + +function jobreferences.set(kind,prefix,tag,data) + for ref in gmatch(tag,"[^,]+") do + local p, r = match(ref,"^(%-):(.-)$") + 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.setandgetattribute(kind,prefix,tag,data,view) -- maybe do internal automatically here + jobreferences.set(kind,prefix,tag,data) + texcount.lastdestinationattribute = jobreferences.setinternalreference(prefix,tag,nil,view) or -0x7FFFFFFF +end + +function jobreferences.enhance(prefix,tag,spec) + local l = tobesaved[prefix][tag] + if l then + l.references.realpage = texcount.realpageno + end +end + +-- this reference parser is just an lpeg version of the tex based one + +local result = { } + +local lparent, rparent, lbrace, rbrace, dcolon, backslash = lpeg.P("("), lpeg.P(")"), lpeg.P("{"), lpeg.P("}"), lpeg.P("::"), lpeg.P("\\") + +local reset = lpeg.P("") / function() result = { } end +local b_token = backslash / function(s) result.has_tex = true return s end + +local o_token = 1 - rparent - rbrace - lparent - lbrace +local a_token = 1 - rbrace +local s_token = 1 - lparent - lbrace - lparent - lbrace +local i_token = 1 - lparent - lbrace +local f_token = 1 - lparent - lbrace - dcolon + +local outer = (f_token )^1 / function (s) result.outer = s end +local operation = lpeg.Cs((b_token + o_token)^1) / function (s) result.operation = s end +local arguments = lpeg.Cs((b_token + a_token)^0) / function (s) result.arguments = s end +local special = (s_token )^1 / function (s) result.special = s end +local inner = (i_token )^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) -- overloaded +--~ return lpegmatch(scanner,str) +--~ end + +function jobreferences.split(str) + return lpegmatch(scanner,str 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)"))) + +-- -- -- 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 (vi.pagedata and vi.pagedata.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 (vi.pagedata and vi.pagedata.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 + local t = { kind, i } + for s in gmatch(reference,"%s*([^,]+)") do + if trace_referencing then + logs.report("referencing","list entry %s provides %s reference '%s' on realpage %s",i,kind,s,realpage) + end + d[s] = t -- share them + end + 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 and file ~= "" then + texsprint(ctxcatcodes,url,"/",file) + else + texsprint(ctxcatcodes,url) + end + end +end + +function commands.doifurldefinedelse(name) + commands.doifelse(urls[name]) +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 + +function commands.doiffiledefinedelse(name) + commands.doifelse(files[name]) +end + +-- helpers + +function jobreferences.checkedfile(whatever) -- return whatever if not resolved + if whatever then + local w = files[whatever] + if w then + return w[1] + else + return whatever + end + end +end + +function jobreferences.checkedurl(whatever) -- return whatever if not resolved + if whatever then + local w = urls[whatever] + if w then + local u, f = w[1], w[2] + if f and f ~= "" then + return u .. "/" .. f + else + return u + end + else + return whatever + end + end +end + +function jobreferences.checkedfileorurl(whatever,default) -- return nil, nil if not resolved + if whatever then + local w = files[whatever] + if w then + return w[1], nil + else + local w = urls[whatever] + if w then + local u, f = w[1], w[2] + if f and f ~= "" then + return nil, u .. "/" .. f + else + return nil, u + end + end + end + end + return default +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 + +function jobreferences.checkedprogram(whatever) -- return whatever if not resolved + if whatever then + local w = programs[whatever] + if w then + return w[1] + else + return whatever + end + end +end + +-- shared by urls and files + +function jobreferences.whatfrom(name) + texsprint(ctxcatcodes,(urls[name] and variables.url) or (files[name] and variables.file) or variables.unknown) +end + +--~ function jobreferences.from(name) +--~ local u = urls[name] +--~ if u then +--~ local url, file, description = u[1], u[2], u[3] +--~ if description ~= "" then +--~ texsprint(ctxcatcodes,format("\\dofromurldescription{%s}",description)) +--~ -- ok +--~ elseif file and file ~= "" then +--~ texsprint(ctxcatcodes,format("\\dofromurlliteral{%s}",url .. "/" .. file)) +--~ else +--~ texsprint(ctxcatcodes,format("\\dofromurlliteral{%s}",url)) +--~ end +--~ else +--~ local f = files[name] +--~ if f then +--~ local description, file = f[1], f[2] +--~ if description ~= "" then +--~ texsprint(ctxcatcodes,format("\\dofromfiledescription{%s}",description)) +--~ else +--~ texsprint(ctxcatcodes,format("\\dofromfileliteral{%s}",file)) +--~ end +--~ end +--~ end +--~ end + +function jobreferences.from(name) + local u = urls[name] + if u then + local url, file, description = u[1], u[2], u[3] + if description ~= "" then + context.dofromurldescription(description) + -- ok + elseif file and file ~= "" then + context.dofromurlliteral(url .. "/" .. file) + else + context.dofromurlliteral(url) + end + else + local f = files[name] + if f then + local description, file = f[1], f[2] + if description ~= "" then + context.dofromfiledescription(description) + else + context.dofromfileliteral(file) + end + end + end +end + +-- export + +exporters.references = exporters.references or { } +exporters.lists = exporters.lists or { } + +function exporters.references.generic(data) + local useddata = {} + local entries, userdata = data.entries, data.userdata + if entries then + for k, v in next, entries do + useddata[k] = v + end + end + if userdata then + for k, v in next, userdata do + useddata[k] = v + end + end + return useddata +end + +function exporters.lists.generic(data) + local useddata = { } + local titledata, numberdata = data.titledata, data.numberdata + if titledata then + useddata.title = titledata.title + end + if numberdata then + local numbers = numberdata.numbers + local t = { } + for i=1,#numbers do + local n = numbers[i] + if n ~= 0 then + t[#t+1] = n + end + end + useddata.number = concat(t,".") + end + return useddata +end + +local function referencer(data) + local references = data.references + local realpage = references.realpage + local numberdata = jobpages.tobesaved[realpage] + local specification = numberdata.specification + return { + realpage = references.realpage, + number = numberdata.number, + conversion = specification.conversion, + -- prefix = only makes sense when bywhatever + } +end + +function jobreferences.export(usedname) + local exported = { } + local e_references, e_lists = exporters.references, exporters.lists + local g_references, g_lists = e_references.generic, e_lists.generic + -- todo: pagenumbers + -- todo: some packing + for prefix, references in next, jobreferences.tobesaved do + local pe = exported[prefix] if not pe then pe = { } exported[prefix] = pe end + for key, data in next, references do + local metadata = data.metadata + local exporter = e_references[metadata.kind] or g_references + if exporter then + pe[key] = { + metadata = { + kind = metadata.kind, + catcodes = metadata.catcodes, + coding = metadata.coding, -- we can omit "tex" + }, + useddata = exporter(data), + pagedata = referencer(data), + } + end + end + end + local pe = exported[""] if not pe then pe = { } exported[""] = pe end + for n, data in next, structure.lists.tobesaved do + local metadata = data.metadata + local exporter = e_lists[metadata.kind] or g_lists + if exporter then + local result = { + metadata = { + kind = metadata.kind, + catcodes = metadata.catcodes, + coding = metadata.coding, -- we can omit "tex" + }, + useddata = exporter(data), + pagedata = referencer(data), + } + for key in gmatch(data.references.reference,"[^,]+") do + pe[key] = result + end + end + end + local e = { + references = exported, + version = 1.00, + } + io.savedata(file.replacesuffix(usedname or tex.jobname,"tue"),table.serialize(e,true)) +end + +function jobreferences.import(usedname) + if usedname then + local imported = jobreferences.imported + local jdn = imported[usedname] + if not jdn then + local filename = files[usedname] + if filename then -- only registered files + filename = filename[1] + else + filename = usedname + end + local data = io.loaddata(file.replacesuffix(filename,"tue")) or "" + if data == "" then + interfaces.showmessage("references",24,filename) + data = nil + else + data = loadstring(data) + if data then + data = data() + end + if data then + -- version check + end + if not data then + interfaces.showmessage("references",25,filename) + end + end + if data then + interfaces.showmessage("references",26,filename) + jdn = data + jdn.filename = filename + else + jdn = { filename = filename, references = { }, version = 1.00 } + end + imported[usedname] = jdn + imported[filename] = jdn + end + return jdn + else + return nil + end +end + +function jobreferences.load(usedname) + -- gone +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 + texcount.referencehastexstate = 0 + if reference and reference ~= "" then + set = set or { } + local r = settings_to_array(reference) + for i=1,#r do + local ri = r[i] + local dp = defined[prefix] or defined[""] + local d = dp[ri] + if d then + resolve(prefix,d[2],nil,set) + else + local var = lpegmatch(scanner,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 + if var.has_tex then + set.has_tex = true + end + else + -- logs.report("references","funny pattern: %s",ri or "?") + end + end + end + if set.has_tex then + texcount.referencehastexstate = 1 + end + return set + else + return { } + end +end + +-- prefix == "" is valid prefix which saves multistep lookup + +jobreferences.currentset = nil + +local b, e = "\\ctxlua{local jc = jobreferences.currentset;", "}" +local o, a = 'jc[%s].operation=[[%s]];', 'jc[%s].arguments=[[%s]];' + +function jobreferences.expandcurrent() -- todo: two booleans: o_has_tex& a_has_tex + local currentset = jobreferences.currentset + if currentset and currentset.has_tex then + local done = false + for i=1,#currentset do + local ci = currentset[i] + local operation = ci.operation + if operation then + if find(operation,"\\") then -- if o_has_tex then + if not done then + texsprint(ctxcatcodes,b) + done = true + end + texsprint(ctxcatcodes,format(o,i,operation)) + end + end + local arguments = ci.arguments + if arguments then + if find(arguments,"\\") then -- if a_has_tex then + if not done then + texsprint(ctxcatcodes,b) + done = true + end + texsprint(ctxcatcodes,format(a,i,arguments)) + end + end + end + if done then + texsprint(ctxcatcodes,e) + end + end +end + +--~ local uo = urls[outer] +--~ if uo then +--~ special, operation, argument = "url", uo[1], inner or uo[2] -- maybe more is needed +--~ else +--~ local fo = files[outer] +--~ if fo then +--~ special, operation, argument = "file", fo[1], inner -- maybe more is needed +--~ end +--~ end + +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] + 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 + var.f = outer + 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.import(outer) + if e 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 = outer + var.e = true -- external + 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 = outer + 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 = outer + else + var.error = "unknown outer with special" + end + else + -- outer:: + var.kind = "outer" + var.f = outer + end + else + if inner 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", inner } + jobreferences.resolvers.reference(var) + var.f = outer + 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 = outer + else + var.error = "unknown outer with special" + end + else + -- outer:: + var.kind = "outer" + var.f = outer + end + 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 = (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 + jobreferences.currentset = set +-- print(bug,table.serialize(set)) + return set, bug +end + +jobreferences.identify = identify + +function jobreferences.doifelse(prefix,reference,highlight,newwindow,layer) + local set, bug = identify(prefix,reference) + local unknown = bug or #set == 0 + if unknown then + currentreference = nil -- will go away + else + set.highlight, set.newwindow,set.layer = highlight, newwindow, layer + currentreference = set[1] + end + -- we can do the expansion here which saves a call + commands.doifelse(not unknown) +end + +function jobreferences.setinternalreference(prefix,tag,internal,view) + local t = { } + if tag then + if prefix and prefix ~= "" then + prefix = prefix .. ":" + for ref in gmatch(tag,"[^,]+") do + t[#t+1] = prefix .. ref + end + else + for ref in gmatch(tag,"[^,]+") do + t[#t+1] = ref + end + end + end + if internal then + t[#t+1] = "aut:" .. internal + end + local destination = jobreferences.mark(t,nil,nil,view) -- returns an attribute + texcount.lastdestinationattribute = destination + return destination +end + +function jobreferences.getinternalreference(n) -- n points into list + local l = structure.lists.collected[n] + texsprint(ctxcatcodes,(l and l.references.internal) or n) +end + + +-- + +function jobreferences.get_current_metadata(tag) + local data = currentreference and currentreference.i + data = data and data.metadata and data.metadata[tag] + if data then + texsprint(ctxcatcodes,data) + end +end +local function current_metadata(tag) + local data = currentreference and currentreference.i + return data and data.metadata and data.metadata[tag] +end +jobreferences.current_metadata = current_metadata + +function jobreferences.get_current_prefixspec(default) -- todo: message + texsprint(ctxcatcodes,"\\getreferencestructureprefix{", + current_metadata("kind") or "?", "}{", current_metadata("name") or "?", "}{", default or "?", "}") +end + +--~ function jobreferences.get_current_prefixspec(default) -- we can consider storing the data at the lua end +--~ context.getreferencestructureprefix(current_metadata("kind"),current_metadata("name"),default) +--~ 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 filter.unknown or filters.generic[name] or filters.generic.unknown) + if filter then + if trace_referencing then + logs.report("referencing","name '%s', kind '%s', using dedicated filter",name,kind) + end + filter(data,name,...) + elseif trace_referencing then + logs.report("referencing","name '%s', kind '%s', using generic filter",name,kind) + end + elseif trace_referencing then + logs.report("referencing","name '%s', unknown kind",name) + end + elseif trace_referencing then + logs.report("referencing","name '%s', no reference",name) + end +end + +filters.generic = { } + +function filters.generic.title(data) + if data then + local titledata = data.titledata or data.useddata + if titledata then + helpers.title(titledata.title or "?",data.metadata) + end + end +end + +function filters.generic.text(data) + if data then + local entries = data.entries or data.useddata + if entries then + helpers.title(entries.text or "?",data.metadata) + end + end +end + +function filters.generic.number(data,what,prefixspec) -- todo: spec and then no stopper + if data then + local numberdata = data.numberdata + if numberdata then +--~ print(table.serialize(prefixspec)) + helpers.prefix(data,prefixspec) + sections.typesetnumber(numberdata,"number",numberdata) + else + local useddata = data.useddata + if useddata and useddsta.number then + tex.sprint(tex.ctxcatcodes,useddata.number) + end + end + end +end + +filters.generic.default = filters.generic.text + +function filters.generic.page(data,prefixspec,pagespec) + local pagedata = data.pagedata + if pagedata then -- imported + local number, conversion = pagedata.number, pagedata.conversion + if not number then + -- error + elseif conversion then + tex.sprint(tex.ctxcatcodes,format("\\convertnumber{%s}{%s}",conversion,number)) + else + tex.sprint(tex.ctxcatcodes,number) + end + else + helpers.prefixpage(data,prefixspec,pagespec) + end +end + +filters.user = { } + +function filters.user.unknown(data,name) + if data then + local userdata = data.userdata + local userkind = userdata and userdata.kind + if userkind then + local filter = filters[userkind] or filters.generic + filter = filter and (filter[name] or filter.unknown) + if filter then + filter(data,name) + return + end + end + local namedata = userdata and userdata[name] + if namedata then + texsprint(ctxcatcodes,namedata) + end + end +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 = { } + +function filters.section.number(data,what,prefixspec) + if data then + local numberdata = data.numberdata + if numberdata then + sections.typesetnumber(numberdata,"number",prefixspec,numberdata) + else + local useddata = data.useddata + if useddata and useddata.number then + tex.sprint(tex.ctxcatcodes,useddata.number) + end + end + end +end + +filters.section.title = filters.generic.title +filters.section.page = filters.generic.page +filters.section.default = filters.section.number + +filters.note = { default = filters.generic.number } +filters.formula = { default = filters.generic.number } +filters.float = { default = filters.generic.number } +filters.description = { default = filters.generic.number } +filters.item = { default = filters.generic.number } + +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 + +-- analyse + +jobreferences.testrunners = jobreferences.testrunners or { } +jobreferences.testspecials = jobreferences.testspecials or { } + +local runners = jobreferences.testrunners +local specials = jobreferences.testspecials + +function jobreferences.analyse(actions) + actions = actions or jobreferences.currentset + if not actions then + actions = { realpage = 0 } + elseif actions.realpage then + -- already analysed + else + -- we store some analysis data alongside the indexed array + -- at this moment only the real reference page is analysed + -- normally such an analysis happens in the backend code + texcount.referencepagestate = 0 + local nofactions = #actions + if nofactions > 0 then + for i=1,nofactions do + local a = actions[i] + local what = runners[a.kind] + if what then + what = what(a,actions) + end + end + local realpage, p = texcount.realpageno, tonumber(actions.realpage) + if not p then + -- sorry + elseif p > realpage then + texcount.referencepagestate = 3 + elseif p < realpage then + texcount.referencepagestate = 2 + else + texcount.referencepagestate = 1 + end + end + end + return actions +end + +function jobreferences.realpage() -- special case, we always want result + local cs = jobreferences.analyse() + texwrite(cs.realpage or 0) +end + +-- + +jobreferences.pages = { + [variables.firstpage] = function() return structure.counters.record("realpage")["first"] end, + [variables.previouspage] = function() return structure.counters.record("realpage")["previous"] end, + [variables.nextpage] = function() return structure.counters.record("realpage")["next"] end, + [variables.lastpage] = function() return structure.counters.record("realpage")["last"] end, + + [variables.firstsubpage] = function() return structure.counters.record("subpage" )["first"] end, + [variables.previoussubpage] = function() return structure.counters.record("subpage" )["previous"] end, + [variables.nextsubpage] = function() return structure.counters.record("subpage" )["next"] end, + [variables.lastsubpage] = function() return structure.counters.record("subpage" )["last"] end, + + [variables.forward] = function() return structure.counters.record("realpage")["forward"] end, + [variables.backward] = function() return structure.counters.record("realpage")["backward"] end, +} + +-- maybe some day i will merge this in the backend code with a testmode (so each +-- runner then implements a branch) + +runners["inner"] = function(var,actions) + local r = var.r + if r then + actions.realpage = r + end +end + +runners["special"] = function(var,actions) + local handler = specials[var.special] + return handler and handler(var,actions) +end + +runners["special operation"] = runners["special"] +runners["special operation with arguments"] = runners["special"] + +local pages = jobreferences.pages + +function specials.internal(var,actions) + local v = jobreferences.internals[tonumber(var.operation)] + local r = v and v.references.realpage + if r then + actions.realpage = r + end +end + +specials.i = specials.internal + +function specials.page(var,actions) -- is this ok? + local p = pages[var.operation] + if type(p) == "function" then + p = p() + end + if p then + actions.realpage = p + end +end diff --git a/tex/context/base/strc-ref.mkii b/tex/context/base/strc-ref.mkii new file mode 100644 index 000000000..1df5d09d8 --- /dev/null +++ b/tex/context/base/strc-ref.mkii @@ -0,0 +1,3041 @@ +%D \module +%D [ file=strc-ref, +%D version=1998.01.15, +%D title=\CONTEXT\ Structure 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. + +% we will merge mkii code back in here + +\writestatus{loading}{ConTeXt Structure Macros / Cross Referencing} + +% todo : unknown/illegal reference no arg +% todo : +n pages check on 'samepage' (contrastcolor) + +% Makes more sense to build action data first, especially now +% openaction etc are supported. +% +% \definespecial\doexecuteactionchain w h +% \definespecial\dosetgotolocation +% \definespecial\dosetexecuteJScode +% ... +% +% complication: what when direct? Two calls! + +% I considered to change / simplify +% +% rt!page -> \definereference +% rt!list -> \definereference +% rt!exec -> \definereference +% +% but for the moment will not do so, if only because +% the current implementation permits us to determine +% the page state and is also more efficient + +% the code is rather fuzzy (and will be redone some day); this is +% due to the chaining (collect secondary and then hook that into +% the primary etc + +\unprotect + +% 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 +%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: +%D +%D \starttyping +%D \def\dotextreference[#1]{\rawtextreference\s!txt{#1}} % #2 +%D \def\dopagereference[#1]{\rawpagereference\s!pag{#1}} +%D \def\doreference [#1]{\rawreference \s!ref{#1}} % #2 +%D \stoptyping +%D +%D or without expansion problems: + +\def\dotextreference[#1]#2% + {\bgroup + \def\asciia{#1}% + \defconvertexpanded\asciib\@@rfexpansion{#2}% + \@EA\rawtextreference\@EA\s!txt\@EA\asciia\@EA{\asciib}% + \egroup} + +\def\dopagereference[#1]% + {\rawpagereference\s!pag{#1}} + +\def\doreference[#1]#2% + {\bgroup + \def\asciia{#1}% + \defconvertexpanded\asciib\@@rfexpansion{#2}% + \@EA\rawreference\@EA\s!ref\@EA\asciia\@EA{\asciib}% + \egroup} + +%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: + +\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 +%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}. + +\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 Why do we have to write down references? \TEX, and therefore +%D \CONTEXT\ is a batch processing system. During the +%D typesetting process, pages are shipped out, which means that +%D especially forward references are not yet known when the +%D page is typeset. That's why we always need a second (and +%D sometimes even a third) pass to get the cross references +%D right. The same goes for lists and other pagenumber +%D dependant data. +%D +%D Therefore, during a pass, \CONTEXT\ writes the references to +%D a the utility file. The next macro does the job and +%D generates entries like: (for mkii) +%D +%D \starttyping +%D \mainreference{prefix}{reference}{page}{realpage}{text} +%D \stoptyping +%D +%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. +%D +%D A former implementation used \type{\removesubstring} to get +%D rid of the don't||use||a||prefix signal (\type{-:}), but the +%D next one proved to be more than twice as fast. + +\let\referenceprefix=\empty +\let\lastreference =\empty + +%D When (during a second pass over the document) references are +%D loaded, they are saved in a macro, one for each reference. +%D In practice this comes to giving \type {\mainreference} a +%D appropriate meaning and loading the utility file. + +%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. The latter +%D case nills the prefix method, thereby saving some memory. +%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 + +\chardef\autocrossfilereferences=0 + +\def\setreferences% some day, filename will be stored in ref record + {\the\everyreference % we're grouped anyway + \def\mainreference##1##2##3##4##5% can be made faster by indirect calls + {\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\resetreferences + {\let\mainreference\gobblefivearguments} + +\resetreferences + +%D Here we see another kind of prefix surface: \type +%D {\fileprefix}. This prefix enables us to use references from +%D different files in one document. This is no really useful in +%D paper documents, but many interactive ones cannot do +%D without. + +\let\fileprefix=\empty + +%D Loading references is done using the normal utility file +%D handling macros. The \type{\hbox} trick prevents spaces +%D creeping in (references are set globally anyway). + +\newtoks\everycheckreferences + +%D When we load references, the file name is stored in a +%D list. + +\let\loadedreferences\empty + +%D We only load references ones. + +\newconditional\jobreferencesloaded + +%D This token list is expanded after the references are loaded. +%D This hook can be used to initialize mechanisms that depend +%D on the reference mechsnism. An example can be found in the +%D field module. + +\def\checkreferences + {\bgroup + \let\fileprefix\empty + \global\let\checkreferences\relax + \usereferences[\jobname]% + \checkrealpage + \egroup + \the\everycheckreferences} + +\def\usereferences[#1]% + {\startnointerference + \checkreferences + \doifparentfileelse{#1} + {\ifconditional\jobreferencesloaded\else + \doutilities{references}{#1}\empty\relax\relax + \global\settrue\jobreferencesloaded + \fi} + {\ExpandBothAfter\doifnotinset{#1}{\loadedreferences} + {\doutilities{references}{#1}\empty\relax\relax + \ifx\fileprefix\empty\else + \doglobal\addtocommalist{#1}\loadedreferences + \fi}} + \stopnointerference} + +%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: + +\chardef\rt!cross=0 % even means possible page reference +\chardef\rt!done =1 +\chardef\rt!page =2 % and is used in \checkrealreferencepage +\chardef\rt!exec =3 +\chardef\rt!list =4 % to determine the page state + +%D We also use the odd/even characteristic to determine the +%D page state. + +%D Here the \type{\rt!exec} tags a viewer specific navigational +%D reference, while for instance \type{\rt!page} gives fast +%D access to for instance the previous or next page. The +%D counter serves a purpose to be explained later. We use a +%D token register to prevent expansion of the text component, +%D which can contain all kind of \TEX\ commands. + +\newcount\crossreferenceorder + +% these are used often so we sped them up + +\def\setlocalcrossreference#1#2#3#4% + {\scratchtoks{#4}% + \@EA\edef\csname\r!cross\fileprefix#1\endcsname + {\rt!cross{#2}{#3}{\the\scratchtoks}{0}}} + +\def\setglobalcrossreference#1#2#3#4% + {\scratchtoks{#4}% + \global\advance\crossreferenceorder \plusone + \@EA\xdef\csname\r!cross\fileprefix#1\endcsname + {\rt!cross{#2}{#3}{\the\scratchtoks}{\the\crossreferenceorder}}} + +\def\setlocalsystemreference#1#2#3% + {\@EA\edef\csname\r!cross\fileprefix#2\endcsname{#1{#3}}} + +\def\setglobalsystemreference#1#2#3% + {\@EA\xdef\csname\r!cross\fileprefix#2\endcsname{#1{#3}}} + +\def\copycrossreference#1#2#3% file from to / slow + {\bgroup + \doifelse{#1}{} + {\let\fileprefix\empty} + {\def\fileprefix{#1::}}% + \def\rt!cross##1##2##3##4% + {\setxvalue{\r!cross\fileprefix#3}% + {\noexpand\rt!cross{##1}{##2}{##3}{##4}}}% + \getvalue{\r!cross\fileprefix#2}% + \egroup} + +%D References from other files are defined globally without +%D ordering data. The first definition, the one without +%D \type{#1}, is used as a signal that references are defined. + +\def\setoutercrossreference#1#2#3#4% + {\toks0={#4}% + \@EA\xdef\csname\r!cross\fileprefix \endcsname{\rt!cross{}{}{1}{0}}% + \@EA\xdef\csname\r!cross\fileprefix#1\endcsname{\rt!cross{#2}{#3}{\the\toks0}{0}}} + +%D In practice accessing a reference comes down to: +%D +%D \startitemize[packed] +%D \item checking the validity +%D \item determining the type +%D \item filtering the content +%D \stopitemize +%D +%D We'll deal with the last two steps first. References are +%D saved in the general format: +%D +%D \starttyping +%D {\referenceclass{realpage}{page}{text}} +%D {\referenceclass{type}{data}} +%D \stoptyping +%D +%D When we filter the content, next macros are set when we +%D meet a normal cross reference: + +\let\currentrealreference =\empty +\let\currentpagereference =\empty +\let\currenttextreference =\empty +\let\currentsubtextreference =\empty +\let\currentsubsubtextreference=\empty + +%D System references only have one component: + +\let\currentdatareference=\empty + +%D Because internally a reference comes in two disguises, one +%D with four arguments and one with only two, we need a two +%D step filter. + +\def\getreferenceelements#1% only one level expansion permitted! + {\@EA\@EA\@EA\dogetreferenceelements\csname\r!cross\referenceprefix#1\endcsname\empty\empty\empty\empty} + +%D In the following step, the \type{\ifx#1} test is needed +%D because we can access this macro directly, and therefore +%D \type{#1} can be an undefined reference (in fact, this hack +%D was needed for the line numbering mechanism). +%D +%D We already introduced a few counters. Here we see why we +%D need those. The discrepancy between the cross reference +%D definition order (determined by the utility file) and the +%D moment the reference is defined in the text, is a measure +%D for it's forward character. This enables references like +%D {\em as we will see later on}. + +\chardef\currentreferencetype=0 + +\newif\ifforwardreference + +\newif\ifrealreferencepage + +\def\docheckrealreferencepage#1% + {\doifnumberelse{#1} + {\ifnum#1=\realpageno + \realreferencepagetrue + \else + \realreferencepagefalse + \fi} + {\realreferencepagefalse}} + +\def\currentfolioreference{0} + +\let\currentlocationreference\empty + +\def\dogetreferenceelements#1#2#3#4#5% + {\chardef\currentreferencetype=\ifx#1\relax0\else#1\fi\relax + \ifnum\currentreferencetype<\plustwo + \edef\currentpagereference{#2}% + \let \currentdatareference\empty + \edef\currentlocationreference{#2}% + \ifx\currentpagereference \empty + \let\currentfolioreference\folio + \else + \def \currentpagereference {\referencepagenumber[#2]}% + \edef\currentfolioreference{\dosplitofffoliopart[#2]}% + \fi + \edef\currentrealreference{#3}% + \settextreferences#4\end + \ifnum0#5<\crossreferencenumber + \forwardreferencetrue + \else + \forwardreferencefalse + \fi + \else + \let \currentlocationreference\empty + \edef\currentrealreference {#3}% + \def \currentdatareference {#2}% + \let \currentfolioreference\folio + \settextreferences#4\end + \forwardreferencefalse + \fi + \ifodd\currentreferencetype + \realreferencepagefalse + \else + \docheckrealreferencepage\currentrealreference + \ifrealreferencepage \else + \docheckrealreferencepage\currentdatareference + \fi + \fi} + +\ifx\referencepagenumber\undefined + + \def\referencepagenumber[#1]{?} + +\fi + +%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. + +\def\settextreferences + {\futurelet\next\dosettextreferences} + +\def\dosettextreferences + {\ifx\next\bgroup + \expandafter\dotriplegroupempty\expandafter\dodosettextreferences + \else + \expandafter\donosettextreferences + \fi} + +\def\donosettextreferences#1\end + {\def\currenttextreference{#1}% + \let\currentsubtextreference\empty + \let\currentsubsubtextreference\empty} + +\def\dodosettextreferences#1#2#3#4\end + {\def\currenttextreference{#1}% + \def\currentsubtextreference{#2}% + \def\currentsubsubtextreference{#3}} + +%D When inside this testing macro we can savely use: + +\def\doifforwardreferenceelse#1#2% + {\ifforwardreference#1\else#2\fi} + +%D Duplicate references are reported while loading the utility +%D file. To prevent problems with document viewers cq. +%D preprocessors, one can enable a (bit time consuming) check. + +\newif\ifcheckduplicatereferences + +%D The next rather dirty trick is needed to preserve the +%D meaning of the original cross reference. In fact, +%D \type{\rt!cross} is toggled to \type{\rt!done}. + +\def\rt!crossdone#1#2#3#4{\rt!done{#1}{#2}{#3}{#4}} + +\def\dohandleduplicatereference#1% + {\bgroup + \let\rt!cross\rt!crossdone + \@EA\xdef\csname\r!cross\referenceprefix#1\endcsname % no let ! + {\csname\r!cross\referenceprefix#1\endcsname}% + \egroup} + +\def\checkfirstreferenceoccurance#1#2% etex + {\@EA\ifx\csname\r!cross\referenceprefix#1\endcsname\relax % no ifcsname needed here + \predefinereference{#1}% + #2% + \else + \getreferenceelements{#1}% + \ifnum\currentreferencetype=\rt!cross + \dohandleduplicatereference{#1}% + #2% + \fi + \fi} + +\def\doiffirstreferenceoccurance + {\ifcheckduplicatereferences + \@EA\checkfirstreferenceoccurance + \else + \@EA\secondoftwoarguments + \fi} + +%D We still have to test for the existence of a reference, but +%D before we come to that, we first look into the way a +%D reference can be accessed. It will be no surprise that +%D references can come in several forms. +%D +%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 +%D +%D Splitting a reference is done by: +%D +%D \starttyping +%D \splitofffullreference {reference} +%D \splitoffreference {reference} +%D \stoptyping +%D +%D The second alternative can be used in a second stage +%D splitoff and only handles \type{::}. + +\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}} + +\def\splitofffullreference#1% + {\edef\currentfullreference{#1}% + \@EA\dosplitofffullreference\currentfullreference\empty(\relax)\empty\end} + +\def\dosplitofffullreference#1(#2#3)#4#5\end + {\ifx#2)% + \let\currentreferenceoperation\empty + \let\currentreferencearguments\empty + \let\currentinnerreference \empty + \dodosplitofffullreferenceA#1::::\empty\end + \currentouterreference\currentreferencespecial + \else\ifx#2\relax + \let\currentreferencespecial \empty + \let\currentreferenceoperation\empty + \let\currentreferencearguments\empty + \dodosplitofffullreferenceA#1::::\empty\end + \currentouterreference\currentinnerreference + \else + \dosplitoffreferenceoperation#2#3{}\end + \let\currentinnerreference\empty + \dodosplitofffullreferenceB#1::::\empty\end + \currentouterreference\currentreferencespecial + \fi\fi} + +\def\dosplitoffreferenceoperation#1#% + {\def\currentreferenceoperation{#1}% + \dodosplitoffreferenceoperation} + +\def\dodosplitoffreferenceoperation#1#2\end + {\def\currentreferencearguments{#1}} + +\def\dodosplitofffullreferenceA#1::#2::#3#4\end#5#6% + {\if#3:% + \dosetfullreferenceA#5#1{}\edef#6{#2}% + \else + \dosetfullreferenceA#6#1{}\let#5\empty + \fi} + +\def\dosetfullreferenceA#1#2#% + {\edef#1{#2}% + \def\currentreferencearguments} + +\def\dodosplitofffullreferenceB#1::#2::#3#4\end#5#6% + {\if#3:% + \edef#5{#1}\edef#6{#2}% + \else + \let#5\empty\edef#6{#1}% + \fi} + +\def\splitoffreference#1% + {\expandafter\dodosplitofffullreferenceB#1::::\empty\end + \currentouterreference\currentinnerreference} + +%D Although the previous split macros have a multistep +%D character, there performance is quite reasonable. +%D +%D For debugging purposes we provide a showcase macro: + +\long\def\dodoshowcurrentreference#1\from#2\with#3% + {\defconvertedcommand\ascii{#2}% + \edef\currentreferenceshow{\currentreferenceshow/#1/\ascii/#3/}} + +\long\def\doshowcurrentreference#1% + {\edef\currentreferenceshow{/\ifreferencefound+\else-\fi/#1}% + \dodoshowcurrentreference ful\from\currentfullreference \with#1% + \dodoshowcurrentreference spe\from\currentreferencespecial \with#1% + \dodoshowcurrentreference ope\from\currentreferenceoperation\with#1% + \dodoshowcurrentreference arg\from\currentreferencearguments\with#1% + \dodoshowcurrentreference out\from\currentouterreference \with#1% + \dodoshowcurrentreference inn\from\currentinnerreference \with#1} + +\def\showcurrentreference% + {\bgroup\tttf\doshowcurrentreference\par\currentreferenceshow\egroup} + +%D We use this visualizer to demonstrate the way references are +%D split. +%D +%D \hbox{\splitofffullreference{rr}\showcurrentreference} +%D \hbox{\splitofffullreference{pp{rr}}\showcurrentreference} +%D \hbox{\splitofffullreference{pp(qq)}\showcurrentreference} +%D \hbox{\splitofffullreference{pp(qq{aa,bb})}\showcurrentreference} +%D \hbox{\splitofffullreference{ff::}\showcurrentreference} +%D \hbox{\splitofffullreference{ff::rr}\showcurrentreference} +%D \hbox{\splitofffullreference{ff::pp()}\showcurrentreference} +%D \hbox{\splitofffullreference{ff::pp(qq)}\showcurrentreference} +%D \hbox{\splitofffullreference{ff::pp(qq{aa})}\showcurrentreference} + +%D Now we've come to the promissed testing step. As we can +%D see, 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[prefixprefix=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. + +\newif\iftracereferences + +\let\tracereferences\tracereferencestrue + +\def\specialREFidentifier{REF} + +\def\dodefinereference[#1][#2]% + {\ifsecondargument + \doifelsenothing{#2} + {\resetreference[#1]}% + {\@EA\gdef\csname\specialREFidentifier#1\endcsname{#2}}% + \else\iffirstargument + \resetreference[#1]% + \fi\fi} + +\def\definereference% + {\dodoubleempty\dodefinereference} + +\def\resetreference[#1]% + {\global\letbeundefined{\specialREFidentifier#1}} + +\newcount\nofexpandedreferences + +\def\dodoexpandreferences#1REF(#2#3)#4\relax + {\ifx#2\relax + \ifcsname\specialREFidentifier#1\endcsname + \edef\expandedreference{\csname\specialREFidentifier#1\endcsname,}% + \else + \global\advance\nofexpandedreferences \plusone + \@EA\xdef\csname REF::\number\nofexpandedreferences\endcsname{#1}% + \fi + \else + \ifcsname\specialREFidentifier#2#3\endcsname + \edef\expandedreference{\csname\specialREFidentifier#2#3\endcsname,}% + \else + % not set + \fi + \fi} + +\def\doexpandreferences#1,% + {\if]#1\else + \let\expandedreference\empty + \dodoexpandreferences#1REF(\relax)\relax + \@EAEAEA\doexpandreferences\@EA\expandedreference + \fi} + +\def\expandreferences#1% + {\global\nofexpandedreferences\zerocount + \doexpandreferences#1,],} + +\def\dodoifreferencefoundelse#1% + {\@EA\splitofffullreference\@EA{#1}% + \ifx\currentreferencespecial\empty + \ifx\currentouterreference\empty + \docheckinnerreference + \ifreferencefound \else + \checkglobalfilereferences + \fi + \else + \docheckouterreference + \fi + \ifreferencefound + \ifx\currentreferencearguments\empty + \getreferenceelements\currentfullreference + \else + \getreferenceelements\currentinnerreference + \fi + \fi + \else + \docheckspecialreference + \fi + \iftracereferences + \doshowcurrentreference\space + \writestatus\m!references\currentreferenceshow + \fi} + +%D Although this can be considered a hack, we provide the +%D option to locate unknown references in other (loaded) files. +%D This can be dangerous, since there can be conflicting +%D definitions. + +\newconditional\autoglobalfilereferences + +\def\checkglobalfilereferences% sloooow + {\ifconditional\autoglobalfilereferences +% \processcommacommand[\loadedreferences]\docheckglobalfilereference + \rawprocesscommalist[\loadedreferences]\docheckglobalfilereference + \fi} + +\def\docheckglobalfilereference#1% + {\ifcsname\r!cross#1::\currentinnerreference\endcsname + \def\currentouterreference{#1}% + \edef\currentfullreference% + {\currentouterreference::\currentinnerreference}% + \global\referencefoundtrue + \quitcommalist + \fi} + +%D For most situations, we could use: +%D +%D \starttyping +%D \let\doifreferencefoundelse=\dodoifreferencefoundelse +%D \stoptyping +%D +%D But when we also want to support chained references, we need +%D some more. Such a chained reference is 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. + +%D \macros +%D {ifenablereferencechains} +%D +%D First we provide a switch to turn this mechanism off: + +\newif\ifenablereferencechains \enablereferencechainstrue + +%D We don't use the general commalist processing macros, +%D because we don't want to pay a speed penalty. + +\newif\ifsecondaryreference +\newcount\nofsecondaryreferences + +% Aanpassen: eerst alle refs scannen en componenten opslaan in +% lijst, dan de chain doorlopen. Momenteel mag alleen laatste +% laatste undefined zijn, eigenlijk moet dat overal kunnen met +% 'geen' zonder melding. Is wel trager. Dus niet. + +\def\doifreferencefoundelse#1#2#3% REF \cs / never more than one group (else \aftergroup usage problems) + {\checkreferences + % first we collect the secondary ones + \bgroup + \the\everyreference + \let\referenceprefix\empty + \expandreferences{#1}% + \egroup + \doresetgotowhereever + \global\nofsecondaryreferences \zerocount + \ifcase\nofexpandedreferences\relax % #1 can be number -) + % no ref + \or + % one ref + \or + % two refs + \ifenablereferencechains \iflocation + \global\secondaryreferencetrue + \xdef\secondaryreference{\csname REF::2\endcsname}% + % test: \global\letcscsname\secondaryreference\csname REF::2\endcsname + \bgroup + %%\let\doifreferencefoundelse\localdoifreferencefoundelse + \let\unharmedreferenceprefix\referenceprefix + \dodoifreferencefoundelse\secondaryreference + \ifreferencefound + \global\nofsecondaryreferences \plusone + #2% + \else + \dohandlenoto{#3}% + \fi + \egroup + \fi \fi + \else + % more than two refs + \ifenablereferencechains \iflocation + \global\secondaryreferencetrue + \scratchcounter\plustwo + \loop + \xdef\secondaryreference{\csname REF::\number\scratchcounter\endcsname}% + % test: \global\letcscsname\secondaryreference\csname REF::\number\scratchcounter\endcsname + \bgroup + %%\let\doifreferencefoundelse\localdoifreferencefoundelse + \let\unharmedreferenceprefix\referenceprefix + \dodoifreferencefoundelse\secondaryreference + \ifreferencefound + \global\advance\nofsecondaryreferences \plusone + #2% + \else + \dohandlenoto{#3}% + \fi + \egroup + \ifnum\scratchcounter<\nofexpandedreferences\relax + \advance\scratchcounter \plusone + \repeat + \fi \fi + \fi + \global\secondaryreferencefalse + \xdef\primaryreference{\csname REF::1\endcsname}% + % test: \global\letcscsname\secondaryreference\csname REF::1\endcsname + \bgroup + % now we handle the primary one + %%\let\doifreferencefoundelse\localdoifreferencefoundelse + \let\unharmedreferenceprefix\referenceprefix + \dodoifreferencefoundelse\primaryreference + \ifreferencefound#2\else#3\fi + \egroup + \doresetgotowhereever} % to prevent problems with direct goto's + +%D The following local redefinition permits the usage of +%D nested \type {\doifreferencefoundelse}; see for an +%D example the local test for file|/|url references. This is +%D a fuzzy part of this mechanism and a result of the choice +%D to let speed prevail over beauty in resolving chained +%D references with symbolic (defined) references. + +\def\localdoifreferencefoundelse#1% + {\dodoifreferencefoundelse{#1}% + \ifreferencefound\@EA\firstoftwoarguments\else\@EA\secondoftwoarguments\fi} + +%D Somewhere else we will properly define \type {\dohandlegoto}; +%D the noto alternative takes care of undefined references in +%D a sequence + +\ifx\dohandlenoto\undefined + + \def\dohandlenoto#1% + {\ifsecondaryreference\else{#1}\fi} + +\fi + +\ifx\dohandlegoto\undefined + + \def\dohandlegoto#1#2#3% + {\ifsecondaryreference\else{#1}\fi} + +\fi + +%D As one can see, while processing the references, the first +%D one is handled last. While scanning the second and following +%D ones, we increment a counter and set a boolean to true. + +%D The next fast one permits rather raw references with +%D \type{()}'s and is used in the object reference mechanism. + +\def\doifrawreferencefoundelse#1#2#3% + {\checkreferences + \bgroup + \edef\currentfullreference{#1}% + \ifcsname\r!cross\currentfullreference\endcsname + \getreferenceelements\currentfullreference + \global\referencefoundtrue#2% + \else + \global\referencefoundfalse#3% + \fi + \egroup} + +%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 + +\def\docheckinnerreference + {\global\let\predefinedreference\currentinnerreference + \ifx\currentreferencearguments\empty + \ifcsname\r!cross\referenceprefix\currentfullreference\endcsname + \global\referencefoundtrue + \else + \let\referenceprefix\empty + \ifcsname\r!cross\currentfullreference\endcsname + \global\referencefoundtrue + \else + \global\referencefoundfalse + \fi + \fi + \else % [SomeThing{with,me}] + \let\referenceprefix\empty + \ifcsname\r!cross\currentinnerreference\endcsname + \global\referencefoundtrue + \else + \global\referencefoundfalse + \fi + \fi + \doifpredefinedreferenceelse{\global\referencefoundfalse}\donothing} + +%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 Here we use the dummy reference \type{somefile::} set in +%D \type{\setouterreference} as a signal that indeed references +%D are defined for the outer file. + +\newif\ifstrictouterreferences \strictouterreferencesfalse + +\def\dodocheckouterreference + {\ifcsname\specialREFidentifier\currentfullreference\endcsname + \@EA\@EA\@EA\splitofffullreference\@EA\@EA\@EA % 1 level + {\csname\specialREFidentifier\currentfullreference\endcsname}% + \docheckouterreference + \else\ifstrictouterreferences + \global\referencefoundfalse + \else + % already \global\referencefoundtrue % no checking done + \fi\fi} + +\def\docheckouterreference + {\let\referenceprefix\empty + \let\unharmedreferenceprefix\empty + \xdef\predefinedreference + {\currentouterreference::\currentinnerreference}% + \ifx\innerreference\empty + \global\referencefoundtrue % no checking done + \else + \ifcsname\r!cross\currentouterreference::\endcsname + \ifcsname\r!cross\currentfullreference\endcsname + \global\referencefoundtrue + \else + \dodocheckouterreference + \fi + \else + \ifstrictouterreferences + \global\referencefoundfalse + \else + \global\referencefoundtrue % no checking done + \fi + \fi + \fi + \doifpredefinedreferenceelse{\global\referencefoundfalse}\donothing} + +%D Special references are only tested when some test routine is +%D defined. + +\def\docheckspecialreference + {\let\referenceprefix\empty + \let\unharmedreferenceprefix\empty + \xdef\predefinedreference + {\currentreferencespecial::\currentreferenceoperation}% + \executeifdefined{\s!do:\v!test:\currentreferencespecial}% + {\global\referencefoundtrue\gobbletwoarguments}% + {\global\referencefoundtrue}{\global\referencefoundfalse}% + \doifpredefinedreferenceelse{\global\referencefoundfalse}\donothing} + +%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% + {\bgroup + \the\everyreference % cleanup : etc in french + \ifinpagebody\else + \doifconcepttracing + {\doifsomething{#2} + {\inleft + {\infofont + \scratchdimen\leftmarginwidth + \advance\scratchdimen -2em + \doboundtext{#2}\scratchdimen{..}->}}}% + \fi + \doifpredefinedreferenceelse + \donothing + {\predefinereference\predefinedreference + \showmessage\m!references{#1}{[\unharmedreferenceprefix][#2]}}% + \egroup} + +\def\unknownreference{\reportreferenceerror1} +\def\illegalreference{\reportreferenceerror4} + +%D Although not actually needed, we default the unharmed +%D reference prefix to the normal one. + +\def\unharmedreferenceprefix{\referenceprefix} + +%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. + +\let\predefinedreference\s!unknown + +% we need to predefine in order to make dup checking possible (when no ref +% is defined yet) + +\def\predefinereference#1% takes now an argument + {\global\@EA\let\csname\r!cross #1\endcsname\dummypredefinedreference + \global\@EA\let\csname\r!cross\unharmedreferenceprefix#1\endcsname\dummypredefinedreference} + +\def\dummypredefinedreference{\rt!done{}{}{}{}} + +%D Testing on existance then becomes: + +\def\doifpredefinedreferenceelse % \referenceprefix added + {\@EA\ifx\csname\r!cross\referenceprefix\predefinedreference\endcsname\dummypredefinedreference + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +%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 + {\doifreferencefoundelse{#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} + +%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 + +% \def\setreferencefilename#1\to#2% +% {\doifelse{\@@converteerfile}{\v!ja} % boolean is sneller +% {\uppercasestring#1\to#2} +% {\edef#2{#1}}} + +\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\iftraceinternalreferences +\newif\ifinternalnamedreferences \internalnamedreferencestrue + +\def\nextinternalreference + {\the\locationcount} + +\def\thisisnextinternal#1% + {\global\advance\locationcount \plusone + \ifinternalnamedreferences + \thisisdestination{\s!aut\iftraceinternalreferences:#1\fi:\nextinternalreference}% + \fi} + +% beter: +% +% \def\thisisnextinternal#1% +% {\iftrialtypesetting\else +% \global\advance\locationcount \plusone +% \ifinternalnamedreferences +% \thisisdestination{\s!aut\iftraceinternalreferences:#1\fi:\nextinternalreference}% +% \fi +% \fi} + +\def\gotonextinternal#1#2#3#4% + {\ifinternalnamedreferences + \gotodestination\empty\empty{\s!aut\iftraceinternalreferences:#1\fi:#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% + {\ifx\currentreferencespecial\empty + \ifx\currentouterreference\empty + \ifnum\currentreferencetype<2 + \@EA\@EAEAEA\@EA\gotoinnerlocation + \else + \@EA\@EAEAEA\@EA\gotosystemlocation + \fi + \else + \@EAEAEA\gotoouterlocation + \fi + \else + \@EA\gotospeciallocation + \fi} % {#1}{#2} + +%D An inner reference refers to some place in the document +%D itself. + +\def\gotoinnerlocation#1% #2% + {\gotodestination\empty\empty + {\referenceprefix\currentinnerreference}\currentrealreference} % {#2} + +%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} + +%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 A system location is not always a location, but for the +%D consistency we also consider actions as such. + +\def\gotosystemlocation + {\csname\r!syst\the\currentreferencetype\endcsname} + +\def\definesystemreferencehandler#1#2% + {\setgvalue{\r!syst\the#1}{#2}} + +%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. + +\definesystemreferencehandler \rt!exec \handleexecreference +\definesystemreferencehandler \rt!page \handlepagereference +\definesystemreferencehandler \rt!list \handlelistreference + +\def\handleexecreference#1% + {\checkexecutecommand\currentdatareference\currentreferencearguments + \executecommand\currentdatareference\currentreferencearguments} + +\def\handlepagereference#1% + {\gotorealpage\empty\empty\currentdatareference} + +\def\handlelistreference#1% is deze nog echt nodig? + {\gotodestination\empty\empty\currentdatareference{\getvalue{\currentdatareference}}} + +%D \macros +%D {setexecutecommandcheck} +%D +%D In case a command action needs to do some checking in +%D advance, one can assign an check function by: +%D +%D \starttyping +%D \setexecutecommandcheck{startsound}\checksoundtrack +%D \stoptyping + +\def\setexecutecommandcheck#1#2% #2 permits \first \second + {\setvalue{\s!do:\s!do:#1}{#2}} + +\def\checkexecutecommand#1#2% evt geen #1 en #2 + {\ifx#2\empty \else \ifcsname\s!do:\s!do:#1\endcsname + \@EA\let\@EA\docheckexecutecommand\csname\s!do:\s!do:#1\endcsname + \rawprocesscommalist[#2]\docheckexecutecommand + \fi \fi } + +%D Command references (in dutch, english, german of +%D whatever interface language) are translated into a bit +%D shorter reference (\type{close}) and passed to the +%D special driver (using \type{\executecommand}). + +% better: [action(name)] and \definereference[name][action(name)] + +\setglobalsystemreference \rt!exec \v!CloseDocument {close} +\setglobalsystemreference \rt!exec \v!ExitViewer {exit} +\setglobalsystemreference \rt!exec \v!FirstPage {first} +\setglobalsystemreference \rt!exec \v!LastPage {last} +\setglobalsystemreference \rt!exec \v!NextJump {forward} +\setglobalsystemreference \rt!exec \v!NextPage {next} +\setglobalsystemreference \rt!exec \v!PauseMovie {pausemovie} +\setglobalsystemreference \rt!exec \v!PauseSound {pausesound} +\setglobalsystemreference \rt!exec \v!PauseRendering {pauserendering} +\setglobalsystemreference \rt!exec \v!PreviousJump {backward} +\setglobalsystemreference \rt!exec \v!PreviousPage {previous} +\setglobalsystemreference \rt!exec \v!PrintDocument {print} +\setglobalsystemreference \rt!exec \v!SaveForm {exportform} +\setglobalsystemreference \rt!exec \v!LoadForm {importform} +\setglobalsystemreference \rt!exec \v!ResetForm {resetform} +\setglobalsystemreference \rt!exec \v!ResumeMovie {resumemovie} +\setglobalsystemreference \rt!exec \v!ResumeSound {resumesound} +\setglobalsystemreference \rt!exec \v!ResumeRendering {resumerendering} +\setglobalsystemreference \rt!exec \v!SaveDocument {save} +\setglobalsystemreference \rt!exec \v!SaveNamedDocument{savenamed} +\setglobalsystemreference \rt!exec \v!OpenNamedDocument{opennamed} +\setglobalsystemreference \rt!exec \v!SearchDocument {search} +\setglobalsystemreference \rt!exec \v!SearchAgain {searchagain} +\setglobalsystemreference \rt!exec \v!StartMovie {startmovie} +\setglobalsystemreference \rt!exec \v!StartSound {startsound} +\setglobalsystemreference \rt!exec \v!StartRendering {startrendering} +\setglobalsystemreference \rt!exec \v!StopMovie {stopmovie} +\setglobalsystemreference \rt!exec \v!StopSound {stopsound} +\setglobalsystemreference \rt!exec \v!StopRendering {stoprendering} +\setglobalsystemreference \rt!exec \v!SubmitForm {submitform} +\setglobalsystemreference \rt!exec \v!ToggleViewer {toggle} +\setglobalsystemreference \rt!exec \v!ViewerHelp {help} +\setglobalsystemreference \rt!exec \v!HideField {hide} +\setglobalsystemreference \rt!exec \v!ShowField {show} +\setglobalsystemreference \rt!exec \v!GotoPage {gotopage} +\setglobalsystemreference \rt!exec \v!GotoPage {gotopage} +\setglobalsystemreference \rt!exec \v!Query {query} +\setglobalsystemreference \rt!exec \v!QueryAgain {queryagain} +\setglobalsystemreference \rt!exec \v!FitWidth {fitwidth} +\setglobalsystemreference \rt!exec \v!FitHeight {fitheight} + +\setglobalsystemreference \rt!exec \v!ShowThumbs {thumbnails} +\setglobalsystemreference \rt!exec \v!ShowBookmarks {bookmarks} + +%D Executing the command looks alike the previous goto macros. + +\def\executecommand#1#2#3% + {\iflocation + \dohandlegoto + {#3}% + {\dostartexecutecommand\buttonwidth\buttonheight{#1}{#2}}% + {\dostopexecutecommand}% + \else + {#3}% + \fi} + +%D We could have done without the short tags and thereby saving +%D some tokens, but the current approach leaves room for future +%D extensions. + +%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. + +% \newif\ifreferencestrut % some day an option + +\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]% + %\doifelse\@@rfstrut\v!yes % some day an option + % \referencetruttrue\referencestrutfalse + \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 + \@EA\doifreferencefoundelse\@EA{#1} + {\gotolocation{#1}{}\ifsecondaryreference\else#2\fi} + {\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 --- VANAF HIER NOG VERENGELSEN --- + +%\let\donormalin =\in +%\let\donormalover=\over % about/oppassen beter nederlands dan engels! +% +%\def\in% +% {\ifmmode +% \expandafter\donormalin +% \else +% \expandafter\doinatreference\expandafter\currenttextreference +% \fi} + +% we need to bypass math tokens + +% \let\normalover \over + +\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 + \def\thecurrentsubtextreference + {\limitatetext\currentsubtextreference\@@rfwidth\unknown}% + %\leaveoutervmode % no + \@@rfleft + \doifreferencefoundelse{#1} + {\let\crlf\space + \let\\\space + \let\dogotofixed\dogotospace + \dogotospace{\thecurrentsubtextreference}[#1]} + {\unknownreference{#1}\dummyreference}% + \@@rfright + \referenceinfo{<}{#1}% + \egroup} + +%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). + +\def\doinatreference#1% + {\doifnextoptionalelse{\dodoinatreference{#1}{}}{\dodoinatreference{#1}}} + +\def\dodoinatreference#1% + {\def\dododoinatreference{\dodododoinatreference{#1}}% + \futurelet\next\dododoinatreference} + +% overloaded +% +% \def\dodododoinatreference#1#2#3[#4]% +% {\ifx\next\bgroup +% \dododododoinatreference{#1\ignorespaces#3}{#2}[#4]% +% \else +% \dododododoinatreference{#1}{#2#3}[#4]% +% \fi} + +%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. + +% overloaded +% +% \def\dododododoinatreference#1#2[#3]% +% {\dontleavehmode +% \bgroup +% \forgetall +% %\leaveoutervmode +% \doifreferencefoundelse{#3} +% {\bgroup +% \let\ignorespaces\empty % rather dirty but ok +% \doifelsenothing{#1} +% {\egroup\dosymbolreference{#1}{#2}[#3]} +% {\egroup\dowantedreference{#1}{#2}[#3]}} +% {\dounknownreference{#1}{#2}[#3]}% +% \referenceinfo{<}{#3}% +% \egroup} + +%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]% + {\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% + {#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}. + +\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 + +\def\dodododoinatreference#1#2#3[#4]% \removeunwantedspaces added june 2004 + {\ifx\next\bgroup % but removed later, fails on metafun + \dododododoinatreference + % fails on metafun {\leftofreference#1\ignorespaces#3\removeunwantedspaces\rightofreference}{#2}[#4]% + {\leftofreference#1\ignorespaces#3\rightofreference}{#2}[#4]% + \else + \dododododoinatreference + {\leftofreference#1\rightofreference}{#2#3}[#4]% + \fi} + +\def\dododododoinatreference#1#2[#3]% + {\dontleavehmode % replaces \leaveoutervmode + \bgroup + \forgetall + \postponenotes + %\leaveoutervmode % replaced by \dontleavehmode + \doifreferencefoundelse{#3} + {\bgroup + \let\ignorespaces \empty % rather dirty trick, but ok + \let\leftofreference \empty % the same, again ok + \let\rightofreference\empty % and once more + \def\textofreference {#2}% % temporary value + \ifx\textofreference\empty % simple expansion + %\doifelsenothing{#1} + % {\egroup\dosymbolreference{#1}{\textofreference}[#3]} + % {\egroup\dowantedreference{#1}{\textofreference}[#3]}% + \doifelsenothing{#1}% + {\egroup\dosymbolreference}% + {\egroup\dowantedreference}% + {#1}{\textofreference}[#3]% + \else + %\doifelsenothing{#1} + % {\egroup\dosymbolreference{#1}{#2}[#3]} + % {\egroup\dowantedreference{#1}{#2}[#3]}% + \doifelsenothing{#1}% + {\egroup\dosymbolreference}% + {\egroup\dowantedreference}% + {#1}{#2}[#3]% + \fi} + {\dounknownreference{#1}{#2}[#3]}% + \referenceinfo<{#3}% + \global\let\leftofreference \empty + \global\let\rightofreference\empty + \global\let\textofreference \empty + \egroup} + +%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. + + +\def\dogoto#1[#2]% + {\dontleavehmode + \bgroup + \postponenotes + \doifreferencefoundelse{#2} + {\doifelsenothing{#1} + {\dosymbolreference{}{}[#2]} + {\dogotospace{#1}[#2]}} + {\unknownreference{#2}#1\relax}% \relax catches lookahead + \egroup + \referenceinfo{<}{#2}} + +\unexpanded\def\goto#1#2% + {\dogoto{#1}#2} + +\newif\ifsharesimilarreferences \sharesimilarreferencestrue +\newcount\similarreference % 0=noppes 1=create/refer 2,3,..=refer + +\def\dogotospace#1[#2]% + {\iflocationsplit + \ifsecondaryreference\setbox0\hbox\fi % due to space insertion + {\let\dogotospace\dogotofixed + \iflocation + \def\processisolatedword##1% + {\ifisolatedwords\ifsharesimilarreferences + \global\advance\similarreference \plusone + \fi\fi + \hbox{\gotolocation{#2}{##1\presetgoto}}}% + \doattributes\??ia\c!style\c!color + {\processisolatedwords{#1}\processisolatedword}% + \else + #1\relax % \relax prevents #1's next macros from gobbling \fi + \fi}% + \else + \iflocation + \doattributes\??ia\c!style\c!color + {\gotolocation{#2}{#1\presetgoto}}% + \else + #1\relax % \relax prevents #1's next macros from gobbling \fi + \fi + \fi + \global\similarreference\zerocount} + +\def\dogotofixed#1[#2]% + {{\iflocation + \hbox{\gotolocation{#2}{\doattributes\??ia\c!style\c!color + {#1\presetgoto}}}% + \else + #1% + \fi}} + +%D In case the auto split feature is not needed or even not +%D even wanted, \type{\gotobox} can be used. + +%D --- NOG IN HANDLEIDING --- + +\unexpanded\def\gotobox#1[#2]% + {\dontleavehmode + \bgroup + \locationstrutfalse + %\leaveoutervmode + \doifreferencefoundelse{#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 The macros that are responsible for handling these +%D references, use the next six variables: + +\let\otherlabel = \empty +\let\fileprefix = \empty +\def\otherfile {\jobname} +\let\otherURL = \empty +\let\otherprefix = \empty +\let\dowithdocdes = \empty + +%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. + +\def\useexternaldocument% + {\dotripleargument\douseexternaldocument} + +\def\douseexternaldocument[#1][#2][#3]% + {\bgroup + \ifsecondargument + \doifelsenothing{#1} + {\douseexternaldocument[#2][#2][#3]} + {\doifelsenothing{#3} + {\douseexternaldocument[#1][#2][#2]} + {\doifsomething{#2} + {\setgvalue{\v!file:::#1}{\doexternaldocument{}{#2}{#3}}% just \do + \doif\@@rfstate\v!start + {\doifparentfileelse{#2} + {\showmessage\m!references{21}{#2}} + {\dodouseexternaldocument{#1}{#2}}}}}}% + \else + \dodouseexternaldocument{#1}{#1}% + \fi + \egroup} + +\def\dodouseexternaldocument#1#2% + {\bgroup % prevents wrong loading of \jobname + \def\fileprefix{#1::}% + \let\setglobalcrossreference\setoutercrossreference + \usereferences[#2]% + \egroup % when called nested + \showmessage\m!references{21}{#2}} + +%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\useURL + {\bgroup + \protectlabels + \catcode`\#=\@@other\catcode`\%=\@@other\catcode`\/=\@@other + \catcode`\_=\@@other\catcode`\~=\@@other\catcode`\:=\@@other + \dodoubleempty\douseURL} + +\def\douseURL[#1][#2]% + {\egroup\doquadrupleempty\dodouseURL[#1][#2]} + +\let\useurl\useURL + +\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 + \ifthirdargument \setgvalue{\v!file:::#1}{\doexternalurl {#2}{#3}{#1}}\else + \ifsecondargument\setgvalue{\v!file:::#1}{\doexternalurl {#2}{} {#1}}\fi\fi\fi + \fi} + +\def\doexternalurl#1#2#3% + {\bgroup + \doifsomething\@@urstyle{\let\@@iastyle\@@urstyle\let\@@urstyle\empty}% + \doifsomething\@@urcolor{\let\@@iacolor\@@urcolor\let\@@urcolor\empty}% + \doexternaldocument{#1}{#2}{\url[#3]}% + \egroup} + +\def\doifurldefinedelse #1{\doifdefinedelse{\v!file:::#1}} +\def\doiffiledefinedelse#1{\doifdefinedelse{\v!file:::#1}} + +%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]% slow + {\bgroup + \processaction + [\@@uralternative] + [ \v!none=>\chardef\urlsplitmode\zerocount, + \v!both=>\chardef\urlsplitmode\plusone, + \v!after=>\chardef\urlsplitmode\plustwo, + \v!before=>\chardef\urlsplitmode\plusthree]% + \doifelse\@@urspace\v!yes + {\setbetweenisolatedwords{\scratchskip\currentspaceskip\hskip\zeropoint\!!plus.2\scratchskip}} + {\setbetweenisolatedwords\allowbreak}% + \def\doexternaldocument##1##2##3{\hyphenatedurl{##1}}% awful hack + \dostartattributes\??ur\c!style\c!color{}% + \getvalue{\v!file:::#1}% + \dostopattributes + \egroup} + +%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 Many macro definitions ago we called for the auxiliary macro +%D \type {\setouterlocation} and now is the time to define this +%D one. + +\newconditional\forceURLlocation + +\def\setouterfilelocation#1#2#3% + {\edef\otherURL{#1}% + \edef\otherfile{#2}}% + +\def\setouterlocation#1% + {\ifcsname\v!file:::#1\endcsname + \let\doexternaldocument\setouterfilelocation % will change + \let\doexternalurl \setouterfilelocation % will change + \csname\v!file:::#1\endcsname + \else + \ifconditional\forceURLlocation + \edef\otherURL{#1}% + \let\otherfile\empty + \else + \let\otherURL\empty + \edef\otherfile{#1}% + \fi + \fi + \setfalse\forceURLlocation + \doifparentfileelse\otherfile + {\let\otherURL\empty + \let\otherfile\empty + \global\let\otherlabel\empty + \let\otherprefix\empty} + {\xdef\otherlabel{#1}% + \edef\otherprefix{#1::}}} + +%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} +%D +%D As can be expected, this macro used \type{\goto} to +%D perform its task. + +\def\dospecialfrom % retest this one ! + {\dosingleempty\dodospecialfrom} + +\def\dodospecialfrom[#1]% + {\dontleavehmode % added, but probably not needed + \bgroup + \protectlabels % needed for active french :'s + \iffirstargument + \edef\!!stringa{#1}% + \doifincsnameelse{::}\!!stringa\donothing{\edef\!!stringa{#1::}}% + \expanded{\redospecialfrom[\!!stringa]}% + \else + \expanded{\nodospecialfrom[\otherlabel]}% + \fi + \egroup} + +\def\redospecialfrom[#1::#2]% + {\ifcsname\v!file:::#1\endcsname + \def\doexternaldocument##1##2##3{\goto{##3}[#1::#2]}% + \csname\v!file:::#1\endcsname + \else + \tttf[#1]% + \fi} + +\def\nodospecialfrom[#1]% + {\ifcsname\v!file:::#1\endcsname + \def\doexternaldocument##1##2##3{##3}% different than ^ + \csname\v!file:::#1\endcsname + \else + \tttf[#1]% + \fi} + +%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 +%D +%D The fastest implementation would be: + +\definespecialtest\v!file {\setfalse\forceURLlocation\handlespecialFILEandURL} +\definespecialtest\v!URL {\settrue \forceURLlocation\handlespecialFILEandURL} +\definespecialtest\v!url {\settrue \forceURLlocation\handlespecialFILEandURL} + +\definespeciallocation\v!file{\setfalse\forceURLlocation\handlespecialallocationFILEandURL} +\definespeciallocation\v!URL {\settrue \forceURLlocation\handlespecialallocationFILEandURL} +\definespeciallocation\v!url {\settrue \forceURLlocation\handlespecialallocationFILEandURL} + +\def\handlespecialFILEandURL + {\localdoifreferencefoundelse + {\currentreferenceoperation::\currentreferencearguments}} + +\def\handlespecialallocationFILEandURL + {\let\currentouterreference\currentreferenceoperation + \let\currentinnerreference\currentreferencearguments + \let\currentreferenceoperation\empty + \let\currentreferencearguments\empty + \gotoouterlocation} + +%D Now we have file references as special ones, it's rather +%D logical to have the viewer specific ones available in a dual +%D way too. At first glance we could do with: +%D +%D \starttyping +%D \definespeciallocation\v!action +%D {\getreferenceelements\currentreferenceoperation +%D \handleexecreference} +%D \stoptyping +%D +%D An better alternative, slower but error aware, is + +% \definespecialtest\v!actie +% {\localdoifreferencefoundelse\currentreferenceoperation} + +\definespecialtest\v!action % rather ugly action(whatever{argument}) + {\expanded{\localdoifreferencefoundelse{\currentreferenceoperation + \ifx\currentreferencearguments\empty\else{\currentreferencearguments}\fi}}} + +\definespeciallocation\v!action + {\handleexecreference} + +%D So now we can say: +%D +%D \starttyping +%D \goto{some action}[PreviousJump] +%D \stoptyping +%D +%D as well as: +%D +%D \starttyping +%D \goto{some text}[action(PreviousJump] +%D \stoptyping + +%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} +%D +%D The latter gives access to the description of the program, +%D being the last argument to the definition command. + +\def\setupprograms + {\dodoubleargument\getparameters[\??pr]} + +\def\dodefineprogram[#1][#2][#3]% + {\setgvalue{\v!program:::#1}{\doprogram{#2}{#3}}} + +\def\defineprogram + {\dotripleargument\dodefineprogram} + +\def\program#1[#2]% + {\bgroup + \ifcsname\v!program:::#2\endcsname + \def\doprogram##1##2{\goto{\doifelsenothing{#1}{##2}{#1}}[\v!program(#2)]}% + \csname\v!program:::#2\endcsname + \else + {\tttf[#2]}% + \fi + \egroup} + +% needs an update: program(abc{arg}) + +\definespeciallocation\v!program#1#2% + {\bgroup + \iflocation + \ifcsname\v!program:::\currentreferenceoperation\endcsname + \def\doprogram##1##2{\def\@@programfile{##1}}% + \getvalue{\v!program:::\currentreferenceoperation}% + \else + \let\@@programfile\currentreferenceoperation + \fi + \defconvertedcommand\ascii\@@programfile + \dohandlegoto + {#2}% + {\dostartrunprogram\buttonwidth\buttonheight{\@@prdirectory\ascii}\currentreferencearguments}% + {\dostoprunprogram}% + \else + {#2}% + \fi + \egroup} + +%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\dodefinepage[#1][#2]% + {\setvalue{\v!page:::#1}{#2}} + +\def\definepage + {\dodoubleargument\dodefinepage} + +\definepage [\v!firstpage] [\firstpage] +\definepage [\v!previouspage] [\prevpage] +\definepage [\v!nextpage] [\nextpage] +\definepage [\v!lastpage] [\lastpage] +\definepage [\v!firstsubpage] [\firstsubpage] +\definepage [\v!previoussubpage] [\prevsubpage] +\definepage [\v!nextsubpage] [\nextsubpage] +\definepage [\v!lastsubpage] [\lastsubpage] +\definepage [\v!first] [\firstpage] +\definepage [\v!previous] [\prevpage] +\definepage [\v!next] [\nextpage] +\definepage [\v!last] [\lastpage] +\definepage [\v!first\v!sub] [\firstsubpage] +\definepage [\v!previous\v!sub] [\prevsubpage] +\definepage [\v!next\v!sub] [\nextsubpage] +\definepage [\v!last\v!sub] [\lastsubpage] + +%D Because we combine both methods, we have to take care of +%D the \type{file::page(n)} as well as \type{page(file::n)}. + +\definespeciallocation\v!page#1#2% page(n) page(+n) page(-n) + {\iflocation + \ifx\currentouterreference\empty + \splitoffreference\currentreferenceoperation + \else + \let\currentinnerreference\currentreferenceoperation + \fi + \ifx\currentouterreference\empty + \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{\edef\currentinnerreference{\executeifdefined{\v!page:::\currentinnerreference}1}}% + \gotorealpage\otherURL\otherfile\currentinnerreference{#2}% + \fi + \else + {#2}% + \fi} + +\def\gotopage#1[#2]% + {\goto{#1}[\v!page(#2)]} + +%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. + +\unexpanded\def\somewhere#1#2#3[#4]% #3 gobbles space around #2 + {\dontleavehmode + %\leaveoutervmode + \doifreferencefoundelse{#4} + {\ifforwardreference + \doifelsenothing{#1} + {\dosymbolreference{}{}[#4]} + {\dogotospace{#1}[#4]}% + \else + \doifelsenothing{#2} + {\dosymbolreference{}{}[#4]} + {\dogotospace{#2}[#4]}% + \fi} + {\unknownreference{#4}#1/#2}% + \referenceinfo{<}{#4}} + +\unexpanded\def\atpage[#1]% + {\dontleavehmode + %\leaveoutervmode + \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. + +\let\crossdocumentreferences\empty +\let\crossdocumentelements\empty + +\newif\ifautocrossdocument + +\def\docoupledocument[#1][#2][#3][#4]% is this :/- safe ? + {\ifthirdargument + \begingroup + \def\dolistelement##1##2##3##4##5##6% 2=aut 6=pag / 2 goes into text ref slot + {\global\utilitydonetrue %{Watch the braces here below!} + \setglobalcrossreference{{##1::\@@filterblocknumberpart[##5]}}{}{##6}{##2}}% + \def\usereferences[##1]% + %{\setbox0\vbox{\doutilities{#3}{##1}{#3}\relax\relax}}% + {\startnointerference + \doutilities{#3}{##1}{#3}\relax\relax + \stopnointerference}% + \douseexternaldocument[#1][#2][#4]% + \doglobal\addtocommalist{#1}\crossdocumentreferences + \def\docommand##1% + {\letgvalue{\??rf##1\c!state}\v!start % for fast checking + \doglobal\addtocommalist{##1}\crossdocumentelements}% + \processcommalist[#3]\docommand + \ifutilitydone + \global\autocrossdocumenttrue + \fi + \endgroup + \fi} + +\def\coupledocument + {\doquadrupleempty\docoupledocument} + +%D --- STRANGE HERE, BETTER IN CORE-NAV --- + +\def\checkcontrastreference#1% + {\ifnum\currentreferencetype=\rt!page\ifnum\currentdatareference=\realpageno + \doifdefined{#1\c!contrastcolor}{\setevalue{#1\c!color}{\getvalue{#1\c!contrastcolor}}}% + \fi\fi} + +\def\checkcontrastreference#1% + {\ifnum\currentreferencetype=\rt!page\relax\ifnum\currentdatareference=\realpageno + \copycsname#1\c!color\endcsname\csname#1\c!contrastcolor\endcsname + \fi\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 + {\bgroup + \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} + {\setlocationboxyes#1[#2]{#3}[#4]} + {\unknownreference{#4}% + \setlocationboxnop#1[#2]{#3}[#4]}}}% + \fi + \egroup} + +%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}% + \expanded{\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 + \doifreferencefoundelse{#1} + {\overlayfakebox {#1}} + {\unknownreference{#1}}% + \fi} + +\def\overlayfakebox#1% + {\hbox + {\setbox\scratchbox\null + \wd\scratchbox\overlaywidth + \ht\scratchbox\overlayheight + \locationstrutfalse + \gotolocation{#1}{\box\scratchbox\presetgoto}}} + +%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% + {\bgroup + \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 + \egroup} + +%D Plugin code: + +%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!urlalternative=\v!both, + %\c!urlspace=\v!no, + %\c!urlletter=, + %\c!urlkleur=, + \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=] + +%D We cannot set up buttons (not yet, this one calls a menu macro): + +% under consideration: +% +% \setupinteraction[state=start] +% +% \unprotect +% +% \chardef\rt!extern=5 +% +% \definesystemreferencehandler \rt!extern \handleexecreference +% +% \definespecialtest\v!extern +% {\expanded{\localdoifreferencefoundelse{\currentreferenceoperation +% \ifx\currentreferencearguments\empty\else{\currentreferencearguments}\fi}}} +% +% \definespeciallocation\v!extern +% {\handleexecreference} +% +% \def\defineexternalreference[#1]% +% {\setglobalsystemreference\rt!extern{#1}{#1}} +% +% \protect +% +% \defineexternalreference[NewOne] +% +% \def\PDFexecuteNewOne{/SomeNewAction /SomeParameter (\argumentA)} +% +% \starttext +% +% \goto{test}[AVDP{../../nach-dateipfad.pdf}] +% \blank +% \goto{test}[external(AVDP{../../nach-dateipfad.pdf})] +% \blank +% \goto{test}[AVDP{../../nach-dateipfad.pdf}] +% \blank +% \goto{test}[external(AVDP{../../nach-dateipfad.pdf})] +% \blank +% \goto{test}[CloseDocument] +% \blank +% \goto{test}[action(CloseDocument)] +% +% \stoptext + +\protect \endinput diff --git a/tex/context/base/strc-ref.mkiv b/tex/context/base/strc-ref.mkiv new file mode 100644 index 000000000..8290a1b13 --- /dev/null +++ b/tex/context/base/strc-ref.mkiv @@ -0,0 +1,1851 @@ +%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. + +% todo: (1) configure references, (2) rendering => with presets +% +% \definestructureconversionset[default][Character,number,Romannumerals,Character][number] +% \definestructureseparatorset [default][.,.,--][.] +% \setupstructurehead[subsection][sectionstopper=),sectionsegments=4:4] +% \setupreferencestructureprefix[default][prefixsegments=2:4] +% \setupreferencestructureprefix[figure][default][prefixsegments=3:4] +% \chapter {One} +% \section {One} +% \subsection[sec:test]{Two} +% See \in[sec:test] and \in[fig:xx] and \in[fig:yy] +% \placefigure[here][fig:xx]{}{} +% \placefigure[here][fig:yy]{}{} + +\writestatus{loading}{ConTeXt Structure Macros / Cross Referencing} + +\registerctxluafile{strc-ref}{1.001} +\registerctxluafile{node-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!user{user} +\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 + +\unexpanded\def\textreference {\dosingleargument\dotextreference} +\unexpanded\def\pagereference {\dosingleargument\dopagereference} +\unexpanded\def\reference {\dosingleargument\doreference } +\unexpanded\def\setreference {\dodoubleargument\dosetreference } + +%D These are implemented in a low level form as: + +\def\dotextreference [#1]{\dodosetreference\s!text{#1}{}} +\def\dopagereference [#1]{\dodosetreference\s!page{#1}{}{}} +\def\doreference [#1]{\dodosetreference\s!full{#1}{}} +\def\dosetreference[#1][#2]{\dodosetreference\s!user{#1}{#2}{}} + +%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\lastreferenceattribute +\newcount\lastdestinationattribute + +\def\dofinishfullreference#1#2{\normalexpanded{\ctxlatelua{jobreferences.enhance("#1","#2")}}} +\def\dofinishtextreference#1#2{\normalexpanded{\ctxlatelua{jobreferences.enhance("#1","#2",{})}}} + +\let\dofinishpagereference\dofinishfullreference +\let\dofinishuserreference\dofinishfullreference + +\def\dodosetreference#1#2#3#4% kind labels userdata text -> todo: userdata + {\ifreferencing + \edef\currentreferencekind{#1}% + \edef\currentreferencelabels{#2}% + \edef\currentreferenceexpansion{\@@rfexpansion}% {\referenceparameter\c!expansion} + \ifx\currentreferencelabels\empty \else + \ifx\currentreferenceexpansion\s!xml + \xmlstartraw + \xdef\currentreferencedata{#4}% data, no text else conflict + \xmlstopraw + \globallet\currentreferencecoding\s!xml + \else + \ifx\currentreferenceexpansion\v!yes + \xdef\currentreferencedata{#4}% + \else + \xdef\currentreferencedata{\detokenize{#4}}% + \fi + \globallet\currentreferencecoding\s!tex + \fi + % beware, the jobreferences.set writes a + % \setnextinternalreference + \ctxlua{jobreferences.setandgetattribute("\currentreferencekind", "\referenceprefix","\currentreferencelabels", + { + references = { + % internal = \nextinternalreference, % no need for an internal as we have an explicit + 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 + }, + \ifx\currentreferencedata\empty\else + entries = { + text = \!!bs\currentreferencedata\!!es + }, + \fi + userdata = structure.helpers.touserdata(\!!bs\detokenize{#3}\!!es) + },"\@@iafocus") + }% + \xdef\currentdestinationattribute{\number\lastdestinationattribute}% + \begingroup\attribute\destinationattribute\currentdestinationattribute\hbox{}\endgroup % todo + \fi + \fi} + +\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]% not yet + {\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 + +\newcount\referencepagestate % set in backend +\newcount\referencehastexstate % set in backend + +% referencepagestate: +% +% 0 = no page ref, 1=same page, 2=before, 3=after + +%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. + +%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 + +%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}[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. + +\unexpanded\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. + +%D \macros +%D {highlighthyperlinks} +%D +%D The next switch can be used to make user hyperlinks are +%D not highlighted when clicked on. + +\newconditional\highlighthyperlinks \settrue\highlighthyperlinks + +%D \macros +%D {gotonewwindow} +%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. + +\newconditional\gotonewwindow \setfalse\gotonewwindow + +\def\expandtexincurrentreference % will happen in lua some time + {\ifcase\referencehastexstate\else\ctxlua{jobreferences.expandcurrent()}\fi} + +\def\doifreferencefoundelse#1#2#3% + {\ctxlua{jobreferences.doifelse("\referenceprefix","#1",\luaconditional\highlighthyperlinks,\luaconditional\gotonewwindow)}% + {\expandtexincurrentreference#2}% + {#3}} + +%D The tester only splits the reference in components but does +%D not look into them. The following macro does a preroll and +%D determines for instance the current real reference pagenumber. +%D The \type {\currentrealreference} macro does the same so unless +%D one wants to use the pagestate the next macro seldom needs to +%D be called. + +\def\analyzecurrentreference + {\ctxlua{jobreferences.analyse()}} + +%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 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. + +\ifx\buttonheight\undefined \newdimen\buttonheight \fi +\ifx\buttonwidth \undefined \newdimen\buttonwidth \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 + +%D We could do this in lua ... + +\newif \iflocation +\newcount\locationcount +\newcount\locationorder +\newbox \locationbox + +\def\nextinternalreference {\the\locationcount} +\def\nextinternalorderreference{\the\locationorder} + +\def\setnextinternalreference + {\global\advance\locationcount\plusone} + +\def\setnextinternalreferences#1#2% plural + {\ctxlua{jobreferences.setnextinternal("#1","#2")}} + +\def\getinternalorderreference#1#2% + {\ctxlua{jobreferences.currentorder("#1","#2")}} + +\def\thisissomeinternal#1#2% tag reference (only for old time sake) + {\begingroup\attribute\destinationattribute\ctxlua{jobreferences.mark("#1:#2")}\hbox{}\endgroup} + +\def\gotosomeinternal#1#2#3#4% + {\ifinternalnamedreferences + \directgoto{#4}[#1:#2]% + \else + \directgoto{#4}[page(#3)]% + \fi} + +\def\gotonextinternal#1#2% + {\directgoto{#1}[internal(#2)]} + +%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)]} + +\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 + +\unexpanded\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}} + +% \appendtoks\ctxlua{jobreferences.export("whatever")}\to\everystoptext +% \starttext +% \chapter[test]{test} +% test \in{IN}[more] and \in{IN}[test] or \at{AT}[more] and \at{AT}[test]\par +% test \in{IN}[whatever::more] and \in{IN}[whatever::test] or \at{AT}[whatever::more] and \at{AT}[whatever::test] \page +% reference\reference[more]{oeps} +% \stoptext + +\def\exportreferences + {\doif\@@rfexport\v!yes{\ctxlua{jobreferences.export()}}} + +\appendtoks + \exportreferences +\to \everygoodbye + +\def\incrementreferenceprefix{+} +\def\decrementreferenceprefix{-} + +\unexpanded\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 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 +%D +%D This is a cheap compatibility hack. Don't use this command +%D as there will be more advanced access to user data. + +\def\ref{\dodoubleargument\doref} + +\def\reftypep{\currentreferencepage} +\def\reftypet{\currentreferencetext} +\def\reftyper{\currentreferencepage} +\def\reftypes{\currentreferencetext} +\def\reftypee{\currentreferencetext} + +\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). + +% \unexpanded\def\in {\mathortext\donormalmathin \dospecialin} +% \unexpanded\def\at {\mathortext\donormalmathat \dospecialat} +% \unexpanded\def\about{\mathortext\donormalmathabout\dospecialabout} +% \unexpanded\def\from {\mathortext\donormalmathfrom \dospecialfrom} +% \unexpanded\def\over {\mathortext\donormalmathover \dospecialabout} + +% \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")}} +\def\currentreferencetext {\ctxlua{jobreferences.filter("text")}} +\def\currentreferencedefault {\ctxlua{jobreferences.filter("default")}} +\def\currentreferencerealpage{\ctxlua{jobreferences.realpage()}} + +\def\getreferenceentry#1{\ctxlua{jobreferences.filter("#1")}} % user entry + +\unexpanded\def\dospecialabout[#1]% + {\dontleavehmode + \begingroup + \let\crlf\space + \let\\\space + \postponenotes + \@@rfleft + \doifreferencefoundelse{#1} + {\goto{\limitatetext\currentreferencetitle\@@rfwidth\unknown}[#1]}% not so efficient (dup lookup) + {}% todo + \@@rfright + \endgroup} + +%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. + +% 1 = whatever +% 2 = forward, following page +% 3 = backward, preceding page +% 4 = forward, same page +% 5 = backward, same page + +% Yet untested: + +\unexpanded\def\somewhere#1#2#3[#4]% #3 gobbles space around #2 % todo + {\doifreferencefoundelse{#4}% kind of inefficient as \goto also analyses + {\goto{\analyzecurrentreference\ifcase\referencepagestate\relax#1/#2\or#2\or#1\or#2\fi}[#4]} + {[#1/#2]}} + +\unexpanded\def\atpage[#1]% todo + {\doifreferencefoundelse{#1}% kind of inefficient as \goto also analyses + {\goto{\analyzecurrentreference\ifcase\referencepagestate + \labeltexts\v!page\dummyreference + \or + \labeltexts\v!atpage\currentreferencepage + \or + \labeltexts\v!atpage\currentreferencepage + \or + \labeltexts\v!atpage\currentreferencepage + \or + \labeltext\v!hereafter + \or + \labeltext\v!hencefore + \fi}[#1]} + {[?]}} + +\unexpanded\def\referencesymbol + {\hbox{\strut\high + {\setupsymbolset[\@@iasymbolset]% + \symbol + [\ifcase\referencepagestate + \v!somewhere + \or % same + \v!nowhere + \or % before + \v!previous + \or % after + \v!next% + \fi]}}} + +% \def\dosymbolreference#1#2[#3]% +% {\removeunwantedspaces +% \goto{\setupsymbolset[\@@iasymbolset]\high{\symbol +% [\ifcase\referencepagestate +% \v!somewhere +% \or % same +% \v!nowhere +% \or % before +% \v!previous +% \or % after +% \v!next% +% \fi]}}[#3]} + +\def\dosymbolreference#1#2[#3]% + {\removeunwantedspaces + \goto{\referencesymbol}[#3]} + +\def\symbolreference[#1]% + {\removeunwantedspaces + \goto{\referencesymbol}[#1]} + + +%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]% + {\goto{\dotextprefix{#2}#1}[#3]} + +% \def\dolabelonlyreference#1#2[#3]% +% {\doifsomespaceelse{#2}% space? +% {\doifsomething{#2}{\goto{#2}[#3]}} +% {\goto{\dotextprefix{#2}}[#3]}} + +\def\dolabelonlyreference#1#2[#3]% + {\goto{\dotextprefix{#2}}[#3]} + +\def\dotextonlyreference#1#2[#3]% + {\dotextprefix{#2}\goto{#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; probably not yet mkiv okay + +\unexpanded\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]% + \setuvalue{#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} +% +% \def\dododododoinatreference#1#2[#3]% +% {\dontleavehmode % replaces \leaveoutervmode +% \begingroup +% \postponenotes +% \doifreferencefoundelse{#3} +% {\doifelsenothing{#1}\dosymbolreference\dowantedreference{#1}{#2}[#3]}% +% {\dounknownreference{#1}{#2}[#3]}% +% \endgroup} + +% \starttext +% \definereferenceformat[inxx] [left=(,right=),text=txt] +% \setupinteraction[state=start] +% \chapter[one]{xx} +% [\goto{state}[file(mk-last-state)]] +% [\goto{state} [file(mk-last-state)]] +% [\at{page} [one]] +% [\at{page}[one]] +% [\at{page}{okay}[one]] +% [\inxx{a}{b}[one]] +% \stoptext + +\unexpanded\def\dospecialin{\let\currentreferencecontent\currentreferencedefault\doinatreference} +\unexpanded\def\dospecialat{\let\currentreferencecontent\currentreferencepage \doinatreference} + +\newtoks\leftreferencetoks +\newtoks\rightreferencetoks + +\def\doinatreference + {\futurelet\next\doinatreferenceone} + +\def\doinatreferenceone + {\ifx\next\bgroup + \afterassignment\doinatreferenceonetwo + \expandafter\leftreferencetoks + \else + \leftreferencetoks\emptytoks + \expandafter\dodoinatreferencenone + \fi} + +\def\doinatreferenceonetwo + {\futurelet\next\doinatreferencetwo} + +\def\doinatreferencetwo + {\ifx\next\bgroup + \afterassignment\dodoinatreferenceboth + \expandafter\rightreferencetoks + \else + \rightreferencetoks\emptytoks + \expandafter\dodoinatreferenceleft + \fi} + +\def\dodoinatreferencenone + {\dodoinatreferenceindeed + {\leftofreference\currentreferencecontent\rightofreference} + {}} + +\def\dodoinatreferenceleft + {\dodoinatreferenceindeed + {\leftofreference\currentreferencecontent\rightofreference} + {\the\leftreferencetoks}} + +\def\dodoinatreferenceboth + {\dodoinatreferenceindeed + {\leftofreference\currentreferencecontent\the\rightreferencetoks\rightofreference} + {\the\leftreferencetoks}} + +\def\dodoinatreferenceindeed#1#2#3[#4]% #3 gobbles space + {\dontleavehmode % replaces \leaveoutervmode + \begingroup + \postponenotes + \doifreferencefoundelse{#4} + {\doifelsenothing{#1}\dosymbolreference\dowantedreference{#1}{#2}[#4]}% + {\dounknownreference{#1}{#2}[#4]}% + \endgroup} + +\let\dosymbolreference\dowantedreference + +%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 characteristic 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. + +% \starttext +% \setupinteraction[state=start] +% [\goto{state}[file(mk-last-state)]] +% [\goto{state} [file(mk-last-state)]] +% \stoptext + +\newconditional\uselocationstrut \settrue\uselocationstrut + +\def\extrareferencearguments{\luaconditional\highlighthyperlinks,\luaconditional\gotonewwindow,"\currentviewerlayer"} + +\unexpanded\def\directgoto{\ifconditional\uselocationstrut\expandafter\dodirectgoto\else\expandafter\directgotohtdp\fi} +\unexpanded\def\goto {\ifconditional\uselocationstrut\expandafter\dogoto \else\expandafter\gotohtdp \fi} + +% The unbox trick is needed in order to permit \par inside a reference. Otherwise +% the reference attribute migrates to the outer boxes. + +\newbox\referencebox + +\def\dodirectgoto#1[#2]% no test for valid references + {\dontleavehmode + \begingroup + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \ctxlua{jobreferences.inject("\referenceprefix","#2",\number\ht\strutbox,\number\dp\strutbox,\extrareferencearguments)}% + \setlocationattributes\??ia + \setstrut % can be option + \attribute\referenceattribute\lastreferenceattribute + \fi + #1% + \endgroup} + +\def\dodirectgotohtdp#1[#2]% no test for valid references + {\dontleavehmode + \begingroup + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \ctxlua{jobreferences.inject("\referenceprefix","#2",\number\dimexpr\@@iaheight\relax,\number\dimexpr\@@iadepth\relax,\extrareferencearguments)}% + \setlocationattributes\??ia + \attribute\referenceattribute\lastreferenceattribute + \fi + #1% + \endgroup} + +\def\dogoto#1#2[#3]% #2 gobbles spaces after #1 so that \goto{xx} [yy] works ok + {\dontleavehmode + \begingroup + %\setbox\referencebox\hbox\bgroup % experiment, might change again to non \par support + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \ctxlua{jobreferences.doifelse("\referenceprefix","#3",\extrareferencearguments)}% + {\expandtexincurrentreference + \ctxlua{jobreferences.injectcurrentset(\number\ht\strutbox,\number\dp\strutbox)}% + \setlocationattributes\??ia + \setstrut % can be option + \attribute\referenceattribute\lastreferenceattribute}% + {\unknownreference{#3}}% + \fi + #1% + %\egroup\unhbox\referencebox} + \endgroup} + +\def\dogotohtdp#1#2[#3]% #2 gobbles spaces after #1 so that \goto{xx} [yy] works ok + {\dontleavehmode + \begingroup + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \ctxlua{jobreferences.doifelse("\referenceprefix","#3",\extrareferencearguments)}% + {\expandtexincurrentreference + \ctxlua{jobreferences.injectcurrentset(\number\dimexpr\@@iaheight\relax,\number\dimexpr\@@iadepth\relax)}% + \setlocationattributes\??ia + \attribute\referenceattribute\lastreferenceattribute}% + {\unknownreference{#3}}% + \fi + #1% + \endgroup} + +\unexpanded\def\directgotobox#1[#2]% no test for valid references + {\dontleavehmode + \begingroup + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \ctxlua{jobreferences.inject("\referenceprefix","#2",nil,nil,\extrareferencearguments)}% + \setlocationattributes\??ia + \hbox attr \referenceattribute \lastreferenceattribute {#1}% + \else + #1% + \fi + \endgroup} + +\unexpanded\def\directgotospecbox#1#2[#3]% no test for valid references + {\dontleavehmode + \begingroup + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \ctxlua{jobreferences.inject("\referenceprefix","#3",nil,nil,\extrareferencearguments)}% + \setlocationcolorspec{#1}% no consequence for strut + \hbox attr \referenceattribute \lastreferenceattribute {#2}% + \else + #2% + \fi + \endgroup} + +\unexpanded\def\directgotodumbbox#1[#2]% no test for valid references + {\dontleavehmode + \begingroup + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \ctxlua{jobreferences.inject("\referenceprefix","#2",nil,nil,\extrareferencearguments)}% + \hbox attr \referenceattribute \lastreferenceattribute {#1}% + \else + #1% + \fi + \endgroup} + +\unexpanded\def\gotobox#1[#2]% no test for valid references + {\dontleavehmode + \begingroup + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \ctxlua{jobreferences.doifelse("\referenceprefix","#2",\extrareferencearguments)}% + {\expandtexincurrentreference + \ctxlua{jobreferences.injectcurrentset(nil,nil)}% + \setlocationattributes\??ia + \hbox attr \referenceattribute \lastreferenceattribute {#1}}% + {\unknownreference{#2}}% + \else + #1% + \fi + \endgroup} + +%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. + +\unexpanded\def\usefile{\dotripleargument\dousefile} % so that they can be used in expanded arguments +\unexpanded\def\useurl {\doquadrupleempty\douseurl } % so that they can be used in expanded arguments + +\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)}} + +\def\doifurldefinedelse #1{\ctxlua{commands.doifurldefinedelse ("#1")}} +\def\doiffiledefinedelse#1{\ctxlua{commands.doiffiledefinedelse("#1")}} + +%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} + +\unexpanded\def\setupurl + {\dodoubleargument\getparameters[\??ur]} + +\unexpanded\def\url[#1]% + {\dontleavehmode + \begingroup + \dosetfontattribute\??ur\c!style + \dosetcolorattribute\??ur\c!color + \hyphenatedurl{\ctxlua{jobreferences.urls.get("#1","\@@uralternative","\@@urspace")}}% + \endgroup} + +% # fails + +%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] +%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} + +%D We keep this for compatibility reasons, hence the hackery. + +\unexpanded\def\dospecialfrom + {\dosingleempty\dodospecialfrom} + +\def\dodospecialfrom[#1]% + {\dontleavehmode + \goto{\ctxlua{jobreferences.from("#1")}}[fileorurl(#1)]} + +\def\dofromurldescription#1% + {#1} + +\def\dofromurlliteral#1% + {\dosetfontattribute \??ur\c!style + \dosetcolorattribute\??ur\c!color + \hyphenatedurl{#1}} + +\let\dofromfiledescription\dofromurldescription +\let\dofromfileliteral \dofromurlliteral % maybe some day setupfile that inherits from url + +%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 + +%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 + +\unexpanded\def\setupprograms + {\dodoubleargument\getparameters[\??pr]} + +\unexpanded\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} + +%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} + +\unexpanded\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 + +% 0 = no page reference +% 1 = same page +% 2 = preceding page +% 3 = following page +% 4 = backward, same page (todo) +% 5 = forward, same page (todo) + +%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} + +\unexpanded\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 + \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} + +\setupbuttons + [\c!state=\v!start] + +%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\xgoto##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=>\xgoto\v!firstpage + \xgoto\v!nextpage + \xgoto\v!previouspage + \xgoto\v!lastpage, + \v!subpage=>\xgoto\v!firstsubpage + \xgoto\v!nextsubpage + \xgoto\v!previoussubpage + \xgoto\v!lastsubpage, + \s!unknown=>\xgoto\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 + \gotobox{\overlayfakebox}[#1]% + \fi} + +\def\overlayfakebox + {\hbox + {\setbox\scratchbox\null + \wd\scratchbox\overlaywidth + \ht\scratchbox\overlayheight + \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 + \setbox\scratchbox\hbox{#1}% to be solved some day + \ifdim\wd\scratchbox>\zeropoint + \unhbox\scratchbox + \doifsomething\@@rfseparator{\removeunwantedspaces\@@rfseparator}% remove is new + \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, + \c!export=\v!no] + +\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(previouspage)] +\definereference [\v!nextpage] [page(nextpage)] +\definereference [\v!lastpage] [page(lastpage)] +\definereference [\v!forward] [page(forward)] +\definereference [\v!backward] [page(backward)] +\definereference [\v!firstsubpage] [page(firstsubpage)] +\definereference [\v!previoussubpage] [page(previoussubpage)] +\definereference [\v!nextsubpage] [page(nextsubpage)] +\definereference [\v!lastsubpage] [page(lastsubpage)] + +% we can do this but only when later in resolve (else problems with \chapter[first]{...} +% +% \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): + +%D New (and experimental): + +% \starttext +% \chapter{test} +% \placefigure[here][xx:1]{}{\framed{one}} \placefigure[here][xx:2]{}{\framed{three}} +% \placetable [here][xx:3]{}{\framed{two}} \placetable [here][xx:4]{}{\framed{four}} +% \start +% \in{fig}[xx:1] and \in{fig}[xx:2] \in{tab}[xx:3] and \in{tab}[xx:4] +% \stop \blank \start +% \setupreferencestructureprefix[default][prefix=no] +% \in{fig}[xx:1] and \in{fig}[xx:2] \in{tab}[xx:3] and \in{tab}[xx:4] +% \stop \blank \start +% \setupreferencestructureprefix[float][default][prefix=no] +% \in{fig}[xx:1] and \in{fig}[xx:2] \in{tab}[xx:3] and \in{tab}[xx:4] +% \stop \blank \start +% \setupreferencestructureprefix[figure][default][prefix=no] +% \in{fig}[xx:1] and \in{fig}[xx:2] \in{tab}[xx:3] and \in{tab}[xx:4] +% \stop \blank +% \stoptext + +\unexpanded\def\setupreferencestructureprefix + {\dotripleargument\dosetupreferencestructureprefix} + +\def\getreferencestructureprefix#1#2#3% + {{ + prefix = "\referencestructureprefixparameter{#1}{#2}{#3}\c!prefix", + separatorset = "\referencestructureprefixparameter{#1}{#2}{#3}\c!prefixseparatorset", + conversion = "\referencestructureprefixparameter{#1}{#2}{#3}\c!prefixconversion", + conversionset = "\referencestructureprefixparameter{#1}{#2}{#3}\c!prefixconversionset", + set = "\referencestructureprefixparameter{#1}{#2}{#3}\c!prefixset", + segments = "\referencestructureprefixparameter{#1}{#2}{#3}\c!prefixsegments", + connector = \!!bs\referencestructureprefixparameter{#1}{#2}{#3}\c!prefixconnector\!!es, + }} + +\unexpanded\def\setupreferencestructureprefix + {\dotripleempty\dosetupreferencestructureprefix} + +\def\dosetupreferencestructureprefix[#1][#2][#3]% + {\ifthirdargument + \getparameters[\??rf:\c!prefix:#1:#2][#3]% + \else\ifsecondargument + \getparameters[\??rf:\c!prefix::#1][#2]% + \fi\fi} + +\def\referencestructureprefixparameter#1#2#3#4% kind name category parameter + {\ifcsname\??rf:\c!prefix:#2:#3#4\endcsname + \csname\??rf:\c!prefix:#2:#3#4\endcsname + \else\ifcsname\??rf:\c!prefix:#1:#3#4\endcsname + \csname\??rf:\c!prefix:#1:#3#4\endcsname + \else\ifcsname\??rf:\c!prefix::#3#4\endcsname + \csname\??rf:\c!prefix::#3#4\endcsname + \fi\fi\fi} + +% \def\getreferencestructureprefixspec#1% we can save one call by moving this to the lua end +% {\getreferencestructureprefix +% {\ctxlua{jobreferences.get_current_metadata("kind")}} +% {\ctxlua{jobreferences.get_current_metadata("name")}} +% {#1}} +% \def\currentreferencedefault +% {\ctxlua{jobreferences.filter("default",\getreferencestructureprefixspec\v!default)}} +% +% this is shortcut for: + +\def\currentreferencedefault + {\ctxlua{jobreferences.filter("default",\ctxlua{jobreferences.get_current_prefixspec("\v!default")})}} + +\protect \endinput + +% tricky: +% +% \enabletrackers[nodes.references] +% \setupinteraction[state=start] +% \def\KnuthTest{\input knuth } +% \def\KnuthTest{\input tufte } +% \def\TufteTest{\input tufte } +% \defineoverlay[xxx][\overlaybutton{page(3)}] +% \setupbackgrounds[text][background=xxx] +% \starttext +% test {\red \KnuthTest} test \par +% \button{test}[page(1)] \par +% \goto{page 2 \TeX}[page(2)] \goto{page 2 \TeX}[page(2)] \goto{\TufteTest}[page(2)] test \page +% test \goto{page 3}[page(3)] \goto{\TufteTest\space\par\TufteTest}[page(4)] test \page +% \goto{page 1}[page(1)] \goto{\TufteTest\space test}[page(1)] \page +% \goto{page 1}[page(1)] \goto{\KnuthTest\space test}[page(1)] \page +% test \goto{page 1}[page(1)] {\goto{\KnuthTest\space test}[page(1)]} test +% \goto{page 1}[page(1)] \goto{\TufteTest}[page(1)] test \page +% \stoptext diff --git a/tex/context/base/strc-reg.lua b/tex/context/base/strc-reg.lua new file mode 100644 index 000000000..c5b2c9374 --- /dev/null +++ b/tex/context/base/strc-reg.lua @@ -0,0 +1,735 @@ +if not modules then modules = { } end modules ['strc-reg'] = { + version = 1.001, + comment = "companion to strc-reg.mkiv", + 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, texcount = tex.write, tex.sprint, tex.count +local format, gmatch, concat = string.format, string.gmatch, table.concat +local utfchar = utf.char +local lpegmatch = lpeg.match + +local trace_registers = false trackers.register("structure.registers", function(v) trace_registers = v end) + +local ctxcatcodes = tex.ctxcatcodes + +local variables = interfaces.variables + +local helpers = structure.helpers +local sections = structure.sections +local documents = structure.documents +local pages = structure.pages +local processors = structure.processors + +local mappings = sorters.mappings +local entries = sorters.entries +local replacements = sorters.replacements + +local processor_split = processors.split + +local matching_till_depth, number_at_depth = sections.matching_till_depth, sections.number_at_depth + +-- some day we will share registers and lists (although there are some conceptual +-- differences in the application of keywords) + +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, detail = { }, { }, not names or names == "" or names == variables.all, nil + 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 + -- beware, this works ok for registers + local depth = sections.getlevel(criterium) + local number = tonumber(number) or number_at_depth(depth) or 0 + if trace_registers then + detail = format("depth: %s, number: %s, numbers: %s, startset: %s",depth,number,concat(sections.numbers(),".",1,depth),#collected) + end + if number > 0 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 + local metadata = v.metadata + local cnumbers = sectionnumber.numbers + if cnumbers then + if (all or hash[metadata.name or false]) and #cnumbers >= depth and matching_till_depth(depth,cnumbers) then + result[#result+1] = v + end + end + end + end + end + end + end + if trace_registers then + if detail then + logs.report("registers","criterium: %s, %s, found: %s",criterium,detail,#result) + else + logs.report("registers","criterium: %s, found: %s",criterium,#result) + end + end + return result +end + +jobregisters = jobregisters or { } +jobregisters.collected = jobregisters.collected or { } +jobregisters.tobesaved = jobregisters.tobesaved or { } + +jobregisters.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 + +local tobesaved, collected = jobregisters.tobesaved, jobregisters.collected + +local function initializer() + tobesaved, collected = jobregisters.tobesaved, jobregisters.collected + local internals = jobreferences.internals + for name, list in next, collected do + local entries = list.entries + for e=1,#entries do + local entry = entries[e] + local r = entry.references + if r then + local internal = r and r.internal + if internal then + internals[internal] = entry + end + end + end + end +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('+')) -- & obsolete in mkiv + +local tagged = { } + +local function preprocessentries(rawdata) + local entries = rawdata.entries + if entries then + local e, k = entries[1] or "", entries[2] or "" + local et, kt, entryproc, pageproc + if type(e) == "table" then + et = e + else + entryproc, e = processor_split(e) + et = lpegmatch(entrysplitter,e) + end + if type(k) == "table" then + kt = e + else + pageproc, k = processor_split(k) + kt = lpegmatch(entrysplitter,k) + end + entries = { } + for k=1,#et do + entries[k] = { et[k] or "", kt[k] or "" } + end + for k=#et,1,-1 do + if entries[k][1] ~= "" then + break + else + entries[k] = nil + end + end + rawdata.list = entries + if pageproc or entryproc then + rawdata.processors = { entryproc, pageproc } + end + rawdata.entries = nil + else + rawdata.list = { { "", "" } } -- br + end +end + +function jobregisters.store(rawdata) -- metadata, references, entries + local data = allocate(rawdata.metadata.name).entries + local references = rawdata.references + references.realpage = references.realpage or 0 -- just to be sure as it can be refered to + preprocessentries(rawdata) + data[#data+1] = rawdata + local label = references.label + if label and label ~= "" then tagged[label] = #data end + texwrite(#data) +end + +function jobregisters.enhance(name,n) + local r = tobesaved[name].entries[n] + if r then + r.references.realpage = texcount.realpageno + end +end + +function jobregisters.extend(name,tag,rawdata) -- maybe do lastsection internally + if type(tag) == "string" then + tag = tagged[tag] + end + if tag then + local r = tobesaved[name].entries[tag] + if r then + local rr = r.references + rr.lastrealpage = texcount.realpageno + rr.lastsection = structure.sections.currentid() + if rawdata then + preprocessentries(rawdata) + for k,v in next, rawdata do + if not r[k] then + r[k] = v + else + local rk = r[k] + for kk,vv in next, v do + if vv ~= "" then + rk[kk] = vv + end + end + end + end + end + end + end +end + +-- sorting and rendering + +local compare = sorters.comparers.basic + +function jobregisters.compare(a,b) + local result = compare(a,b) + if result ~= 0 then + return result + elseif a.metadata.kind == 'entry' then -- e/f/t + local page_a, page_b = a.references.realpage, b.references.realpage + if not page_a or not page_b then + return 0 + elseif page_a < page_b then + return -1 + elseif page_a > page_b then + return 1 + end + end + return 0 +end + +function jobregisters.filter(data,options) + data.result = jobregisters.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 + if list then + for l=1,#list do + local ll = list[l] + local word, key = ll[1], ll[2] + if not key or key == "" then + key = word + end + split[l] = splitter(strip(key)) + end + end + entry.split = split + end + end +end + +function jobregisters.sort(data,options) + sorters.sort(data.result,jobregisters.compare) +end + +function jobregisters.unique(data,options) + local result, prev, equal = { }, nil, table.are_equal + local dataresult = data.result + for k=1,#dataresult do + local v = dataresult[k] + 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, lasttag, s, d = { }, nil, nil, nil + -- maps character to index (order) + for k=1,#result do + local v = result[k] + local entry, tag = sorters.firstofsplit(v) + if tag ~= lasttag then + if trace_registers then + logs.report("registers","splitting at %s",tag) + end + d = { } + s = { tag = tag, data = d } + split[#split+1] = s + lasttag = tag + end + d[#d+1] = v + end + data.result = split +end + +function jobregisters.analysed(class,options) + local data = collected[class] + if data and data.entries then + options = options or { } + sorters.setlanguage(options.language) + 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.userdata(index,name) + local data = jobreferences.internals[tonumber(index)] + data = data and data.userdata and data.userdata[name] + if data then + texsprint(ctxcatcodes,data) + end +end + +-- proc can be wrapped + +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) + local er = entry.references + texsprint(ctxcatcodes,format("\\registeronepage{%s}{%s}{",er.internal or 0,er.realpage or 0)) -- internal realpage content + local proc = entry.processors and entry.processors[2] + if proc then + texsprint(ctxcatcodes,"\\applyprocessor{",proc,"}{") + helpers.prefixpage(entry,prefixspec,pagespec) + texsprint(ctxcatcodes,"}") + else + helpers.prefixpage(entry,prefixspec,pagespec) + end + texsprint(ctxcatcodes,"}") + end + local function pagerange(f_entry,t_entry,is_last) + local er = f_entry.references + texsprint(ctxcatcodes,format("\\registerpagerange{%s}{%s}{",er.internal or 0,er.realpage or 0)) + local proc = f_entry.processors and f_entry.processors[2] + if proc then + texsprint(ctxcatcodes,"\\applyprocessor{",proc,"}{") + helpers.prefixpage(f_entry,prefixspec,pagespec) + texsprint(ctxcatcodes,"}") + else + helpers.prefixpage(f_entry,prefixspec,pagespec) + end + local er = t_entry.references + texsprint(ctxcatcodes,format("}{%s}{%s}{",er.internal or 0,er.lastrealpage or er.realpage or 0)) + if is_last then + if proc then + texsprint(ctxcatcodes,"\\applyprocessor{",proc,"}{") + helpers.prefixlastpage(t_entry,prefixspec,pagespec) -- swaps page and realpage keys + texsprint(ctxcatcodes,"}") + else + helpers.prefixlastpage(t_entry,prefixspec,pagespec) -- swaps page and realpage keys + end + else + if proc then + texsprint(ctxcatcodes,"\\applyprocessor{",proc,"}{") + helpers.prefixpage(t_entry,prefixspec,pagespec) + texsprint(ctxcatcodes,"}") + else + helpers.prefixpage(t_entry,prefixspec,pagespec) + end + end + texsprint(ctxcatcodes,"}") + end + -- ranges need checking ! + for i=1,#result do + local sublist = result[i] + 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 } + local metadata = entry.metadata + 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 + if metadata then + texsprint(ctxcatcodes,"\\registerentry{") + local proc = entry.processors and entry.processors[1] + if proc then + texsprint(ctxcatcodes,"\\applyprocessor{",proc,"}{") + helpers.title(e[i],metadata) + texsprint(ctxcatcodes,"}") + else + helpers.title(e[i],metadata) + end + texsprint(ctxcatcodes,"}") + else + local proc = entry.processors and entry.processors[1] + if proc then + texsprint(ctxcatcodes,"\\applyprocessor{",proc,"}{") + texsprint(ctxcatcodes,format("\\registerentry{%s}",e[i])) + texsprint(ctxcatcodes,"}") + else + texsprint(ctxcatcodes,format("\\registerentry{%s}",e[i])) + end + end + else + done[i] = false + end + end + end + local kind = entry.metadata.kind + if kind == 'entry' then + texsprint(ctxcatcodes,"\\startregisterpages") + --~ collapse_ranges = true + 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 -- 1 ? + 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") + local proc = entry.processors and entry.processors[1] + if proc then + texsprint(ctxcatcodes,"\\applyprocessor{",proc,"}{") + texsprint(ctxcatcodes,format("\\registeroneword{0}{0}{%s}",entry.seeword.text)) -- todo: internal + texsprint(ctxcatcodes,"}") + else + texsprint(ctxcatcodes,format("\\registeroneword{0}{0}{%s}",entry.seeword.text)) -- todo: internal + end + 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.mkii b/tex/context/base/strc-reg.mkii new file mode 100644 index 000000000..b088246d3 --- /dev/null +++ b/tex/context/base/strc-reg.mkii @@ -0,0 +1,1243 @@ +%D \module +%D [ file=strc-reg, +%D version=1999.12.27, +%D title=\CONTEXT\ Structure 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. + +\writestatus{loading}{ConTeXt Structure Macros / Register Management} + +\newif \ifautoregisterhack % for the moment a private hack + +% new: eigennummer=ja => eerste {} ipv pag nummer + +\unprotect + +%D Isolated but still indocumented. + +% Formaat tex-utility-input-file : +% +% i e {tag} {loc} {pure} {entry+..} {p:c:p:sp:ssp=>page} {realpage} +% i s {tag} {loc} {pure} {entry+..} {other entry} +% +% 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} +% +% Deze file wordt met het Perl script TeXUtil omgezet in +% een in te lezen file met de commando's: +% +% \registerentrya {tag} {ingang} +% \registerentryb {tag} {subingang} +% \registerentryc {tag} {subsubingang} +% +% \registerpage {tag} {pag,txt} {volgnummer} {paginanummer} {volgnummer} +% +% \registersee {tag} {pag,txt} {andere ingang} +% +% \registerentry {tag} {letter} + +\def\dosetupregister[#1][#2][#3]% + {\ifthirdargument + \def\dodosetupregister##1% + {\getparameters[\??id##1#2][#3]% + \preparepageprefix{\??id##1}}% + \else + \def\dodosetupregister##1% + {\getparameters[\??id##1][#2]% + \doifvalue{\??id##1\c!coupling}\v!yes + {\appendtoks\coupleregister[##1][#2]\to\everystarttext}% + \preparepageprefix{\??id##1}}% + \fi + \processcommalist[#1]\dodosetupregister} + +\def\setupregister + {\dotripleempty\dosetupregister} + +\def\getlastregisterentry#1% + {\def\docommand##1{\def\!!stringa{##1}}% + \processseparatedlist[#1][+]\docommand + \!!stringa} + +\def\registerparameter#1{\csname\??id\currentregister#1\endcsname} + +% \enableregime[windows] \setupregister[index][keyexpansion=strict] +% +% \index[tsch]{tsch} test \index{Qtsch} test \index[ratsch]{Rtsch} test + +\newif\ifwritetoregister \writetoregistertrue + +\chardef\registerpagestatus\zerocount + +\def\doprocesspageregister[#1]#2#3% key altnum entry + {\ifwritetoregister + \begingroup + \thisisnextinternal\s!ind + \ifduplicate\getlastregisterentry{#3}\fi + \defconvertexpanded\asciiregisterentryA{\registerparameter\c!keyexpansion}{#1}% + \defconvertexpanded\asciiregisterentryB{\registerparameter\c!expansion }{#3}% + \doifsomething{\registerparameter\c!keyexpansion} + {\ifx\asciiregisterentryA\empty + \defconvertexpanded\asciiregisterentryA{\registerparameter\c!keyexpansion}{#3}% + \fi}% + \makesectionformat + \doifelse{\registerparameter\c!ownnumber}\v!yes + \donetrue\donefalse + \expanded{\writeutility{r % spaces are essential + \ifcase\registerpagestatus\space\or e\or f\or t\fi\space + {\currentregister} % + {\nextinternalreference} % + {\asciiregisterentryA} % + {\asciiregisterentryB} % + {\sectionformat\sectionseparator\sectionseparator\ifdone#2\else\noexpand\pagenumber\fi} % + {\noexpand\realfolio}}}% + \getfirstcharacter\currentregister + \registerinfo{> \firstcharacter}{#3}% + \endgroup + \fi} + +\def\doregister#1% + {\chardef\registerpagestatus\plusone + \def\currentregister{#1}% + \doifelse{\registerparameter\c!ownnumber}\v!yes + {\dosingleempty\dodoregister} + {\dosingleempty\donoregister}} + +\def\donoregister[#1]% + {\dodoregister[#1]{}} + +% \long\def\doflushatpar#1% +% %{\dogotopar{#1}} +% %{\dogotopar{\dontleavehmode#1}} % this one can introduce empty lines +% {\dogotopar{#1\ifvmode\nobreak\fi}} % while this one can mess up vertical space +% +% fails when [text] \index{test} [empty line] [text] so we now have +% Taco's test based solution: + +\def\doflushatpar + {\ifvmode + \expandafter\dogotopar + \else + \expandafter\firstofoneargument + \fi} + +\def\dodoregister[#1]#2#3% + {\doflushatpar{\doprocesspageregister[#1]{#2}{#3}}} + +\def\writetoregister[#1]% to be documented + {\doregister{#1}} + +% \def\startregister +% {\dotripleempty\dostartregister} + +% \def\dostartregister[#1][#2][#3]#4% +% {\chardef\registerpagestatus\plustwo +% \def\currentregister{#1}% +% \setgvalue{\??id#1\??id#2}{\dodostopregister[#1][#3]{#4}}% +% \dodoregister[#3]{}{#4}} + +\def\startregister + {\doquadrupleempty\dostartregister} + +\def\dostartregister[#1][#2][#3][#4]#5% % 3 args: #3 is sortkey + {\chardef\registerpagestatus\plustwo % 4 args: #3 is type, #4 is sortkey + \def\currentregister{#1}% + \iffourthargument + \setgvalue{\??id#1\??id#2}{\dodostopregister[#1][#4]{#5}}% + \dodoregister[#4]{#3}{#5}% + \else + \setgvalue{\??id#1\??id#2}{\dodostopregister[#1][#3]{#5}}% + \dodoregister[#3]{}{#5}% + \fi} + +\def\stopregister + {\dodoubleargument\dostopregister} + +\def\dostopregister[#1][#2]% + {\getvalue{\??id#1\??id#2}\letgvalue{\??id#1\??id#2}\relax} + +\def\dodostopregister[#1][#2]#3% + {\chardef\registerpagestatus\plusthree + \def\currentregister{#1}% + \dodoregister[#2]{}{#3}} % key altnum entry + +\def\doprocessseeregister[#1]#2#3% + {\ifwritetoregister + \begingroup + \thisisnextinternal\s!ind + \ifduplicate\getlastregisterentry{#2}\fi + \defconvertexpanded\asciiregisterentryA{\registerparameter\c!keyexpansion}{#1}% + \defconvertexpanded\asciiregisterentryB{\registerparameter\c!expansion }{#2}% + \defconvertexpanded\asciiregisterentryC{\registerparameter\c!expansion }{#3}% + \doifsomething{\registerparameter\c!keyexpansion} + {\ifx\asciiregisterentryA\empty + \defconvertexpanded\asciiregisterentryA{\registerparameter\c!keyexpansion}{#2}% + \fi}% + \makesectionformat + \expanded{\writeutility{r s % + {\currentregister} % + {\nextinternalreference} % + {\asciiregisterentryA} % + {\asciiregisterentryB} % + {\asciiregisterentryC} % + {\sectionformat}}}% + \endgroup + \registerinfo{> see}{#2}% + \fi} + +\def\complexdoseeregister[#1]#2#3% + {\doflushatpar{\doprocessseeregister[#1]{#2}{#3}}} + +\def\doseeregister#1% + {\def\currentregister{#1}% + \complexorsimpleempty\doseeregister} % = \dosingleempty\doseeregister + +\def\dowritetoregister[#1]% % de twee-traps-aanroep is nodig + {\edef\currentregister{#1}% % om gebruik van \ExpandBothAfter + \doprocesspageregister} % mogelijk te maken + +\def\writetoregister + {\dodoubleempty\dowritetoregister} + +\def\ifregistergeplaatst{\ifutilitydone} + +\newif\iffirstregisterpage +\newif\iffirstregisterentry + +\let\c!entrya\empty +\let\c!entryb\empty +\let\c!entryc\empty +\let\c!entryd\empty + +\def\nextregisterpage + {\iffirstregisterpage + \doglobal\newcounter\registerpagenumber + \fi + \doglobal\increment\registerpagenumber} + +\def\doregisterpagelocation#1#2% + {\nextregisterpage + \hbox to 1em{\hss\doregisterpagehowto{#1}{#2}\hss}} + +% todo: \installregisterpagehandler + +\def\setregisterpage#1% todo: currentregister gebruiken + {\let\registerpageseparator\empty + \processaction + [\getvalue{\??id#1\c!symbol}] + [ \c!n=>{\def\doregisterpage##1[##2]% + {\doregisterpagelocation{#1}{\registerpagenumber}\/}}, + \c!a=>{\def\doregisterpage##1[##2]% + {\doregisterpagelocation{#1}{\character{\registerpagenumber}\/}}}, + 1=>{\def\doregisterpage##1[##2]% + {\doregisterpagelocation{#1}{$\bullet$}}}, + 2=>{\def\doregisterpage##1[##2]% + {\doregisterpagelocation{#1}{\vrule\!!width1em\!!height1ex\!!depth\zeropoint}}}, + \v!none=>{\def\doregisterpage##1[##2]{}},% + \s!unknown=>{\def\registerpagesymbol{\getvalue{\??id#1\c!symbol}}% + \def\doregisterpage##1[##2]% + {\doregisterpagelocation{#1}{\registerpagesymbol}}}, + \s!default=>{\def\registerpageseparator{,}% + \let\doregisterpage\doregisterpagedefault}]} + +\def\doregisterpagedefault#1[#2]% + {\doregisterpagehowto{#1}{\strut\pageprefix{\??id#1}[#2]\translatednumber[#2]}} + +% test case +% +% \starttext +% \placelist[section][criterium=all] \blank[2*big] +% \placeregister[index][compress=no] \blank[2*big] +% \placeregister[index][compress=no,sectionnumber=yes] \blank[2*big] +% \placeregister[index][compress=yes] \page +% test text \index{test index} +% \section{heading} +% more test text \index{test index} +% \section{heading} +% more test text \index{test index} +% \page +% \section{heading text \index{test index}} +% more test text \index{test index} +% \page +% test text \index{test index} +% \section{heading text \index{test index}} +% more test text \index{test index} +% \stoptext + +\let\registerpagehowto\empty +\let\registertexthowto\empty + +\def\setregisterhowto[#1,#2]% + {\def\registerpagehowto{#1}% + \def\registertexthowto{#2}}% + +\def\doregistertexthowto#1#2% + {\dostartattributes{\??id#1\registertexthowto}\c!textstyle\c!textcolor\empty + \getvalue{\??id#1\c!textcommand}{#2}% + \dostopattributes} + +\def\doregisterpagehowto#1#2% + {\dostartattributes{\??id#1\registerpagehowto}\c!pagestyle\c!pagecolor\empty + \getvalue{\??id#1\c!pagecommand}{#2}% + \dostopattributes} + +\def\registerentry #1{\executeifdefined{#1\s!entry }\gobbleoneargument } +\def\registerentrya#1{\executeifdefined{#1\s!entrya}\gobbleoneargument } +\def\registerentryb#1{\executeifdefined{#1\s!entryb}\gobbleoneargument } +\def\registerentryc#1{\executeifdefined{#1\s!entryc}\gobbleoneargument } +\def\registerentryd#1{\executeifdefined{#1\s!entryd}\gobbleoneargument } +\def\registersee #1{\executeifdefined{#1\s!see }\gobblethreearguments} +\def\registerpage #1{\executeifdefined{#1\s!page }\gobblefourarguments } +\def\registerfrom #1{\executeifdefined{#1\s!from }\gobblefourarguments } +\def\registerto #1{\executeifdefined{#1\s!to }\gobblefourarguments } + +\def\doresetregister#1% + {\letvalue{#1\s!entrya}\gobbleoneargument + \letvalue{#1\s!entryb}\gobbleoneargument + \letvalue{#1\s!entryc}\gobbleoneargument + \letvalue{#1\s!entryd}\gobbleoneargument + \letvalue{#1\s!see }\gobblethreearguments + \letvalue{#1\s!page }\gobblefourarguments + \letvalue{#1\s!from }\gobblefourarguments + \letvalue{#1\s!to }\gobblefourarguments + \letvalue{#1\s!entry }\gobbleoneargument} + +\newif\iffirstsubentry +\newif\iffirstsubsubentry + +\newcounter\currententrylevel + +\let\c!entryletter =\empty +\let\c!entryreference=\empty +\let\c!entrya =\relax +\let\c!entryb =\relax +\let\c!entryc =\relax +\let\c!entryd =\relax + +\def\limitedregisterentry#1#2% + {\getvalue{\??id#1\c!textcommand}% + {\doifelsenothing{\??id#1\c!maxwidth} + {#2} + {\limitatetext{#2}{\getvalue{\??id#1\c!maxwidth}}{\unknown}}}} + +\def\dosetpageregisterpage#1#2#3#4#5#6% + {\doifreglevelelse[#5]{\dodosetpageregisterpage{#1}{#2}{#3}{#4}{#5}{#6}}{}} + +\def\dodosetpageregisterpageA#1#2#3#4#5#6% + {\global\utilitydonetrue + \c!entryletter + \setregisterhowto[#3]% + \def\dohandleregisterentry##1% + {\bgroup + \if!!donea % \strut nieuw + \hhboxindent\hangindent % maybe also left and right skip + \setbox0\hbox{\doregistertexthowto{#2}{\strut\limitedregisterentry{#2}{##1}}}% + \unhhbox0\with{\gotonextinternal\s!ind{#4}{#6}{\box\hhbox}}% + \else + \doregistertexthowto{#2}{##1}% + \fi + \egroup + \!!doneafalse}% + \!!doneafalse + \doifelsevalue{\??id#2\c!interaction}\v!text + {\ifcase\currententrylevel \or + \!!doneatrue\c!entrya\c!entryb\c!entryc\c!entryd \or + \c!entrya\!!doneatrue\c!entryb\c!entryc\c!entryd \or + \c!entrya\c!entryb\!!doneatrue\c!entryc\c!entryd \or + \c!entrya\c!entryb\c!entryc\!!doneatrue\c!entryd \fi} + {\c!entrya\c!entryb\c!entryc\c!entryd}% + \global\let\c!entrya\relax + \global\let\c!entryb\relax + \global\let\c!entryc\relax + \global\let\c!entryd\relax + \global\let\c!entryletter\relax + \global\let\c!entryreference\relax} + +% \def\dodosetpageregisterpageB#1#2#3#4#5#6% +% {\iffirstregisterpage +% \expandafter\hskip\getvalue{\??id#2\c!distance}\relax +% \else\ifnum#1=3 +% \strut|--|\relax % -- ! +% \else +% % \relax after space needed because | looks ahead +% \strut\registerpageseparator|\space|\relax +% \fi\fi +% \iftrue % \iftrue ...\fi to preserve indentation, can be folded out +% \begingroup +% % +% \doifelsevalue{\??id#2\c!prefix}\v!none % default v!both +% {\chardef\pageprefixmode\zerocount}% +% {\doifvalue{\??id#2\c!prefix}\v!first % only first in range (1.2-4) +% {\ifnum#1=3 \chardef\pageprefixmode\zerocount \fi}}% +% % +% \doifelsevalue{\??id#2\c!interaction}\v!pagenumber +% {\bgroup +% \setbox0\hbox{\showlocation{\doregisterpage{#2}[#5]\ifnum#1=2\/\fi}}% +% \gotonextinternal{\s!ind}{#4}{#6}{\box0}%{\copy0}% +% \egroup} +% {\hbox{\doregisterpage{#2}[#5]\ifnum#1=2\/\fi}}% +% \endgroup +% \ignorespaces +% \relax +% \fi +% \global\firstregisterpagefalse} + +\def\dodosetpageregisterpageB#1#2#3#4#5#6% + {\iffirstregisterpage + \expandafter\hskip\getvalue{\??id#2\c!distance}\relax + \else\ifnum#1=3 + \strut|--|\relax % -- ! + \else + % \relax after space needed because | looks ahead +% TH: next line replaced +% \strut\registerpageseparator|\space|\relax + \strut \registerpageseparator{ }% +% /TH + \fi\fi + \iftrue % \iftrue ...\fi to preserve indentation, can be folded out + \begingroup + % + \doifelsevalue{\??id#2\c!prefix}\v!none % default v!both + {\chardef\pageprefixmode\zerocount}% + {\doifvalue{\??id#2\c!prefix}\v!first % + {\ifnum#1=3 \chardef\pageprefixmode\zerocount \fi}}% + % + \doifelsevalue{\??id#2\c!interaction}\v!pagenumber + {\bgroup + \setbox0 + \hbox{\showlocation{\doregisterpage{#2}[#5]\ifnum#1=2\/\fi}}% + \gotonextinternal{\s!ind}{#4}{#6}{\box0}%{\copy0}% + \egroup} + {\hbox{\doregisterpage{#2}[#5]\ifnum#1=2\/\fi}}% + \endgroup + \ignorespaces + \relax + \fi + \global\firstregisterpagefalse} + +\def\resetseenregisterpage + {\global\let\firstseenregisterreal \relax + \global\let\currentseenregisterreal\relax + \global\let\lastseenregisterreal \relax + \global\let\firstseenregisterpage \relax + \global\let\currentseenregisterpage\relax + \global\let\lastseenregisterpage \relax} + +\resetseenregisterpage + +\def\dodosetpageregisterpageC#1#2#3#4#5#6% + {\xdef\currentseenregisterpage{#5}% + \xdef\currentseenregisterreal{#6}% + \ifx\firstseenregisterreal\relax + % no range yet + \global\let\firstseenregisterreal\currentseenregisterreal + \global\let\firstseenregisterpage\currentseenregisterpage + \global\let\lastseenregisterreal \currentseenregisterreal + \global\let\lastseenregisterpage \currentseenregisterpage + \else\ifnum\lastseenregisterreal=\currentseenregisterreal\relax + % same page (catch error) + \else\ifnum\numexpr\lastseenregisterreal+\plusone\relax=\currentseenregisterreal\relax + \global\let\lastseenregisterreal \currentseenregisterreal + \global\let\lastseenregisterpage \currentseenregisterpage + \else + \global\let\savedcurrentseenregisterreal\currentseenregisterreal + \global\let\savedcurrentseenregisterpage\currentseenregisterpage + \flushseenregisterpage + \global\let\firstseenregisterreal\savedcurrentseenregisterreal + \global\let\firstseenregisterpage\savedcurrentseenregisterpage + \global\let\lastseenregisterreal \savedcurrentseenregisterreal + \global\let\lastseenregisterpage \savedcurrentseenregisterpage + \fi\fi\fi + \gdef\flushseenregisterpage{\doflushseenregisterpage{#1}{#2}{#3}{#4}}} + +% \def\dodosetpageregisterpageC#1#2#3#4#5#6% +% {\xdef\currentseenregisterpage{#5}% +% \xdef\currentseenregisterreal{#6}% +% \firstregisterpagefalse +% \gdef\flushseenregisterpage{\doflushseenregisterpage{#1}{#2}{#3}{#4}}% +% \ifx\firstseenregisterreal\relax +% % no range yet +% \global\let\firstseenregisterreal\currentseenregisterreal +% \global\let\firstseenregisterpage\currentseenregisterpage +% \global\let\lastseenregisterreal \currentseenregisterreal +% \global\let\lastseenregisterpage \currentseenregisterpage +% \else\ifnum\firstseenregisterreal=\currentseenregisterreal\relax +% \global\let\firstseenregisterreal\currentseenregisterreal +% \global\let\firstseenregisterpage\currentseenregisterpage +% \global\let\lastseenregisterreal \currentseenregisterreal +% \global\let\lastseenregisterpage \currentseenregisterpage +% \else\ifnum\lastseenregisterreal=\currentseenregisterreal\relax +% \global\let\lastseenregisterpage \currentseenregisterpage +% \else\ifnum\numexpr\lastseenregisterreal+\plusone\relax=\currentseenregisterreal\relax +% \global\let\lastseenregisterreal \currentseenregisterreal +% \global\let\lastseenregisterpage \currentseenregisterpage +% \else +% % back up, flush, go on +% \global\let\savedcurrentseenregisterreal\currentseenregisterreal +% \global\let\savedcurrentseenregisterpage\currentseenregisterpage +% \let\currentseenregisterpage\lastseenregisterpage +% \let\currentseenregisterreal\lastseenregisterreal +% \flushseenregisterpage +% \global\let\firstseenregisterreal\savedcurrentseenregisterreal +% \global\let\firstseenregisterpage\savedcurrentseenregisterpage +% \global\let\lastseenregisterreal \savedcurrentseenregisterreal +% \global\let\lastseenregisterpage \savedcurrentseenregisterpage +% \fi\fi\fi\fi} + +\def\doflushseenregisterpage#1#2#3#4% + {\global\let\flushseenregisterpage\relax + \ifx\firstseenregisterreal\relax + % nothing in the hold + \else\ifx\firstseenregisterreal\lastseenregisterreal + \expanded{\dodosetpageregisterpageB{1}{#2}{#3}{#4}{\lastseenregisterpage}{\lastseenregisterreal}}% + \else + \expanded{\dodosetpageregisterpageB{2}{#2}{#3}{#4}{\firstseenregisterpage}{\firstseenregisterreal}}% + \expanded{\dodosetpageregisterpageB{3}{#2}{#3}{#4}{\lastseenregisterpage }{\lastseenregisterreal }}% + \fi\fi + \resetseenregisterpage} + +\let\flushseenregisterpage\relax + +\chardef\collapseregisterpages\zerocount + +\def\dodosetpageregisterpage + {\ifcase\collapseregisterpages + \expandafter\dodosetpageregisterpagenormal + \else + \expandafter\dodosetpageregisterpagecollapsed + \fi} + +\def\dodosetpageregisterpagenormal#1#2#3#4#5#6% + {\dodosetpageregisterpageA{#1}{#2}{#3}{#4}{#5}{#6}% + \dodosetpageregisterpageB{#1}{#2}{#3}{#4}{#5}{#6}} + +% \def\dodosetpageregisterpagecollapsed#1#2#3#4#5#6% +% {\dodosetpageregisterpageA{#1}{#2}{#3}{#4}{#5}{#6}% +% \dodosetpageregisterpageC{#1}{#2}{#3}{#4}{#5}{#6}} + +\def\dodosetpageregisterpagecollapsed#1#2#3#4#5#6% + {\ifx\firstseenregisterreal\relax\flushseenregisterpage\fi + \dodosetpageregisterpageA{#1}{#2}{#3}{#4}{#5}{#6}% + \dodosetpageregisterpageC{#1}{#2}{#3}{#4}{#5}{#6}} + +% test case for collapsing (experimental, for Steffen Wolfrum) +% +% \starttext +% \chardef\collapseregisterpages\zerocount \placeregister[index] \blank[2*big] +% \chardef\collapseregisterpages\plusone \placeregister[index] \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 + +\def\dosetpageregistersee#1#2#3#4% ugly separator hack + {\flushseenregisterpage + \expanded{\doifreglevelelse[#4\sectionseparator\sectionseparator0]}% + {{\global\utilitydonetrue + \setregisterhowto[#2]% + \def\dohandleregisterentry##1% dubbelop | \strut nieuw + {\doregistertexthowto{#1}{\strut\limitedregisterentry{#1}{##1}}}% + \getvalue + {#1\ifcase\currententrylevel\s!entrya\or\s!entryb\or\s!entryc\else\s!entryd\fi}% + {\doregisterpagehowto{#1}{\labeltexts\v!see{#3}}}% + \c!entryletter\c!entrya\c!entryb\c!entryc\c!entryd + \global\let\c!entrya\relax + \global\let\c!entryb\relax + \global\let\c!entryc\relax + \global\let\c!entryd\relax + \global\let\c!entryletter\relax + \global\let\c!entryreference\relax + % \global\firstregisterentrytrue + \global\firstregisterpagetrue}} + {}} + +%D Extended with variant: + +\def\doregistercharacter[#1]#2% + {\global\firstregisterentrytrue + \doifsomething{#2} + {\doifelsevalue{\??id#1\c!indicator}\v!yes + {\executeifdefined + {\strippedcsname\doregistercharacter\getvalue{\??id#1\c!alternative}}% + \doregistercharactera + [#1]{#2}} + {\noregistercharacter[#1]{#2}}}} + +\def\noregistercharacter[#1]#2% + {\getvalue{\??id#1\c!before}% + \goodbreak} + +% a = + +\def\doregistercharactera[#1]#2% + {\getvalue{\??id#1\c!before}% + \vskip\lineheight\goodbreak\vskip-\lineheight + \ifhmode\unskip\else\noindent\fi % brrr + \getvalue{\??id#1\c!command}{\doattributes{\??id#1}\c!style\c!color{\strut\ignorespaces#2}}% + \getvalue{\??id#1\c!after}% + \par\nobreak} + +% b = + +\def\doregistercharacterb[#1]#2% here no lineheight hackery ! ! ! + {\getvalue{\??id#1\c!before}% + \ifhmode\unskip\else\noindent\fi % brrr + \getvalue{\??id#1\c!command}% + {\doattributes{\??id#1}\c!style\c!color{\strut\ignorespaces#2}}% + \getvalue{\??id#1\c!after}% + \nobreak} + +\def\doregistercharacterA[#1]#2{\doregistercharactera[#1]{\WORD{#2}}} +\def\doregistercharacterB[#1]#2{\doregistercharacterb[#1]{\WORD{#2}}} + +%D Don't use \type{\string#2}; another hack is needed, since +%D \type {#2} can be \type {\string} itself. + +% \def\doregisterreference[#1]#2% +% {\doifvalue{\??id#1\c!referencing}\v!on +% {\pagereference[#1:#2]}} + +\def\doregisterreference[#1]#2% + {\doifsomething{#2} + {\doifvalue{\??id#1\c!referencing}\v!on + {\pagereference[#1:\strippedcsname#2]}}} + +\def\dosetpageregisterletter#1#2% + {\flushseenregisterpage + \gdef\c!entryreference + {\global\let\c!entryreference\relax + \doregisterreference[#1]{#2}}% + \gdef\c!entryletter + {\global\utilitydonetrue + \global\let\c!entryletter\relax + \doregistercharacter[#1]{#2}}} + +% \def\HowUgly #1{\doHowUgly#1\relax} +% \def\doHowUgly#1#2\relax{\iffirstregisterentry{\bf#1}\else#1\fi#2} % unchecked +% +% \setupregister[index][indicator=no,deeptextcommand=\HowUgly] +% +% \starttext +% \chapter{First Chapter} +% Some text...\index{word} +% \section {First Section} +% Some text...\index{word} +% Some text...\index{another entry} +% Some text...\index{ansi} +% Some text...\index{another entry} +% \page[yes] +% \completeindex +% \stoptext + +\def\dohandlepageregisterentry#1#2% + {\dohandleregisterentry{\executeifdefined{\??id#1\c!deeptextcommand}\firstofoneargument{#2}}} + +\def\dosetpageregisterentrya#1#2% + {\flushseenregisterpage + \edef\currententrylevel{1}% + \global\let\c!entryb\relax + \global\let\c!entryc\relax + \global\let\c!entryd\relax + \gdef\c!entrya + {\iffirstregisterentry\else\endgraf\fi % new + \global\firstregisterpagetrue + \hangindent1em\noindent\c!entryreference + \dohandlepageregisterentry{#1}{#2}% + \global\firstregisterentryfalse + \global\firstsubentrytrue + \global\firstsubsubentrytrue}} + +\def\dosetpageregisterentryb#1#2% + {\flushseenregisterpage % redundant + \edef\currententrylevel{2}% + \global\let\c!entryd\relax + \global\let\c!entryc\relax + \global\def\c!entryb + {\iffirstregisterentry\else\endgraf\fi % new + \global\firstregisterpagetrue + \global\let\c!entrya\relax + \iffirstsubentry\nobreak\fi + \hangindent2em\noindent\c!entryreference\hskip1em\relax + \dohandlepageregisterentry{#1}{#2}% + \global\firstregisterentryfalse + \global\firstsubentryfalse + \global\firstsubsubentrytrue}} + +\def\dosetpageregisterentryc#1#2% + {\flushseenregisterpage % redundant + \edef\currententrylevel{3}% + \gdef\c!entryc + {\iffirstregisterentry\else\endgraf\fi % new + \global\firstregisterpagetrue + \global\let\c!entrya\relax + \global\let\c!entryb\relax + \iffirstsubsubentry\nobreak\fi + \hangindent3em\noindent\c!entryreference\hskip2em\relax + \dohandlepageregisterentry{#1}{#2}% + \global\firstregisterentryfalse + \global\firstsubsubentryfalse}} + +\def\dosetpageregisterentryd#1#2% + {\flushseenregisterpage % redundant + \edef\currententrylevel{4}% + \gdef\c!entryd + {\iffirstregisterentry\else\endgraf\fi % new + \global\firstregisterpagetrue + \global\let\c!entrya\relax + \global\let\c!entryb\relax + \global\let\c!entryc\relax + \iffirstsubsubentry\nobreak\fi + \hangindent4em\noindent\c!entryreference\hskip3em\relax + \dohandlepageregisterentry{#1}{#2}% + \global\firstregisterentryfalse + \global\firstsubsubentryfalse}} + +\def\dosetpageregister#1% \currentregister gebruiken + {\dosetreglevel{#1}% + \global\let\currentregisterentry\empty + \global\firstsubentrytrue + \global\firstsubsubentrytrue + \setregisterpage{#1}% + \setvalue{#1\s!entrya}{\dosetpageregisterentrya {#1}}% + \setvalue{#1\s!entryb}{\dosetpageregisterentryb {#1}}% + \setvalue{#1\s!entryc}{\dosetpageregisterentryc {#1}}% + \setvalue{#1\s!entryd}{\dosetpageregisterentryd {#1}}% + \setvalue{#1\s!page }{\dosetpageregisterpage{1}{#1}}% + \setvalue{#1\s!from }{\dosetpageregisterpage{2}{#1}}% + \setvalue{#1\s!to }{\dosetpageregisterpage{3}{#1}}% + \setvalue{#1\s!see }{\dosetpageregistersee {#1}}% + \setvalue{#1\s!entry }{\dosetpageregisterletter {#1}}} + +\def\dosetreglevel#1% + {\dosetfilterlevel{\getvalue{\??id#1\c!criterium}}\empty} + +\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? + {\dosetreglevel{#1}% + \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}}} + +\newcounter\internallistreference + +\def\doloadregisterlinks#1% + {\dosetreglevel{#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]% + \doutilities\currentregister{\registerparameter\c!file}\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 + \expanded{\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}% + \dosetreglevel{#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 + +\setupfield + [\v!register] + [\c!width=10em, + \c!height=3ex, + \c!align=\v!middle, + \c!option=\v!readonly, + \c!location=\v!low] + +\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 + +\def\placeregister + {\dodoubleempty\doplaceregister} + +\def\doplaceregister[#1][#2]% + {\iffirstargument + \begingroup + \edef\currentregister{#1}% + \setupregister[\currentregister][#2]% + \doifelse{\registerparameter\c!compress}\v!yes % new + {\chardef\collapseregisterpages\plusone} + {\chardef\collapseregisterpages\zerocount}% +% TH: disable next line +% \raggedright +% /TH + \startcolumns + [\c!n=\registerparameter\c!n, + \c!balance=\registerparameter\c!balance, + \c!align=\registerparameter\c!align, + tolerance=stretch]% + \dontcomplain + \startpacked[\v!blank]% + \doutilities\currentregister{\registerparameter\c!file}\currentregister\dobeforeplaceregister\doafterplaceregister + \stoppacked + \stopcolumns + \endgroup + \fi} +\def\dobeforeplaceregister + {\resetseenregisterpage + \relax} + +\def\doafterplaceregister + {\flushseenregisterpage + \par} + +\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) + \expanded{\systemsuppliedchapter[\currentregister]{\noexpand\headtext{\currentregister}}}% + \placeregister[\currentregister][#2]% + \page[\v!yes]% + \endgroup + \fi} + +\def\doregisterregisterlanguage#1% + {\savesortlanguage{\getvalue{\??id#1\s!language}}% + \expanded{\immediatewriteutility{r l {#1} {\getvalue{\??id#1\s!language}}}}} + +\def\dodefineregister[#1][#2]% + {\setupregister[#1]% + [\c!n=2, + \c!balance=\v!yes, % \v!no komt niet zo vaak voor + \c!align=\v!flushleft, + \c!before=\blank, % binnen kolommen: \blank[\v!line] + \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, + \v!part\v!number=\v!yes, % v + \v!chapter\c!number=\v!no, + \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!keyexpansion=, + \c!file=\jobname, + %\c!deeptextcommand=, % undefined by default ! + \s!language=\currentmainlanguage]% + \doglobal\appendtoksonce + \doregisterregisterlanguage{#1}% + \to \everysavesortkeys + \presetheadtext[#1=\Word{#1}]% + \addutilityreset{#1}% + \setvalue{#1}{\doregister{#1}}% + \setvalue{\e!coupled#1}{\dolinkedregister{#1}}% + \setvalue{\s!set#1}{\dosetregister{#1}}% + \setvalue{\s!reset#1}{\doresetregister{#1}}% + \setvalue{\e!see#1}{\doseeregister{#1}}% + \setvalue{\e!place#1}{\placeregister[#1]}% + \setvalue{\e!complete#1}{\completeregister[#1]}% + \setvalue{\e!setup#1\e!endsetup}[##1]{\getparameters[\??id#1][##1]}} + +\def\defineregister + {\dodoubleargument\dodefineregister} + +\def\registerlengte{\utilityregisterlength} + +\def\utilityregisterlength{0} + +\def\dodetermineregistercharacteristics[#1][#2]% + {\begingroup + \def\currentregister{#1}% + \setupregister[#1][#2]% + \dosetreglevel{#1}% + \setvalue{#1\s!from}% + {\getvalue{#1\s!page}}% + \setvalue{#1\s!page}##1##2##3##4% + {\doifreglevelelse[##3] + {\doglobal\increment\utilitylistlength + \global\utilitydonetrue} + {}}% + \doglobal\newcounter\utilityregisterlength + \setbox0\vbox{\doutilities\currentregister{\registerparameter\c!file}\currentregister\dobeforeplaceregister\doafterplaceregister}% + \endgroup + \ifregistergeplaatst + \setsystemmode \v!register + \else + \resetsystemmode\v!register + \fi} + +\def\determineregistercharacteristics + {\dodoubleempty\dodetermineregistercharacteristics} + +%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-reg.mkiv b/tex/context/base/strc-reg.mkiv new file mode 100644 index 000000000..fcc37549c --- /dev/null +++ b/tex/context/base/strc-reg.mkiv @@ -0,0 +1,1137 @@ +%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 + +\def\c!keys {keys} +\def\c!entries{entries} + +% todo: tag:: becomes rendering +% todo: language, character, linked, location + +%D Helper: + +% \def\doflushatpar{\ifvmode\expandafter\dogotopar\else\expandafter\firstofoneargument\fi} + +\def\doflushatpar{\ifvmode\expandafter\flushatnextpar\else\expandafter\firstofoneargument\fi} + +% \starttext +% \placeregister[index] +% \chapter{a} \index{93} \index{456} \index{***} \index{*} \index{@} +% test \index{aa} test \startregister[index][x]{bb} test \page test \page test \page test \stopregister[index][x] +% test \index{aa} test \setregisterentry[index][label=x,entries=bb] test \page test \page test \page test \finishregisterentry[index][label=x] +% test \index{aa} test \setregisterentry[index][label=y] test \page test \page test \page test \finishregisterentry[index][label=y,entries=yy] +% \stoptext + +% 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\detokenizedregisterparameter#1{\detokenize\expandafter\expandafter\expandafter{\csname\??id#1\endcsname}} % always root + +\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 + +\unexpanded\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!xmlsetup=, + \c!pageprefixconnector=\endash, + \c!pagesegments=2:2, + \c!file=\jobname, + %\c!deeptextcommand=, % undefined by default ! + \s!language=\currentmainlanguage]% + +%D Definition: + +\unexpanded\def\defineregister + {\dodoubleargument\dodefineregister} + +\def\dodefineregister[#1][#2]% #2? + {\setupregister[#1][\s!parent=\??id]% + \ctxlua{jobregisters.define('#1')}% + \presetheadtext[#1=\Word{#1}]% + \setuvalue{#1}{\dodoubleempty\doregister[#1]}% + \setuvalue{\e!see#1}{\dodoubleempty\doseeregister[#1]}% +% \setuvalue{\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) + +\getparameters + [\??id] + [\c!label=, + \c!entries=, + \c!entries:1=,\c!entries:2=,\c!entries:3=, + \c!keys:1=,\c!keys:2=,\c!keys:3=, + \c!alternative=] + +\def\doregisterstructurepageregister + {\iftrialtypesetting + \expandafter\gobblethreearguments + \else + \expandafter\dodoregisterstructurepageregister + \fi} + +\def\dodoregisterstructurepageregister#1#2#3% register data userdata + {\begingroup + \edef\currentregister{#1}% + %getparameters[\??id][\c!entries=,\c!label=,\c!keys=,\c!alternative=,#2]% + \getparameters[\??id][#2]% + \edef\currentregisterlabel {\registerparameter\c!label}% + \edef\currentregisterexpansion{\registerparameter\c!expansion}% + \edef\currentregisterownnumber{\registerparameter\c!ownnumber}% + \xdef\currentregisterkeys {\registerparameter\c!keys}% + \xdef\currentregisterentries {\registerparameter\c!entries}% + \xdef\currentregisterxmlsetup {\registerparameter\c!xmlsetup}% + \ifx\currentregisterentries\empty + \ifx\currentregisterexpansion\s!xml + \xmlstartraw + \xdef\currentregisterentriesa{\registerparameter{\c!entries:1}}% + \xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}% + \xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}% + \xmlstopraw + \globallet\currentregistercoding\s!xml + \else + \ifx\currentregisterexpansion\v!yes + \xdef\currentregisterentriesa{\registerparameter{\c!entries:1}}% + \xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}% + \xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}% + \else + \xdef\currentregisterentriesa{\detokenizedregisterparameter{\c!entries:1}}% + \xdef\currentregisterentriesb{\detokenizedregisterparameter{\c!entries:2}}% + \xdef\currentregisterentriesc{\detokenizedregisterparameter{\c!entries:3}}% + \fi + \globallet\currentregistercoding\s!tex + \fi + \else + \ifx\currentregisterexpansion\s!xml + \xmlstartraw + \xdef\currentregisterentries{\registerparameter\c!entries}% + \xmlstopraw + \globallet\currentregistercoding\s!xml + \else + \ifx\currentregisterexpansion\v!yes + \xdef\currentregisterentries{\registerparameter\c!entries}% + \else + \xdef\currentregisterentries{\detokenizedregisterparameter\c!entries}% + \fi + \globallet\currentregistercoding\s!tex + \fi + \fi + \ifx\currentregisterkeys\empty + \ifx\currentregistercoding\s!xml + \xmlstartraw + \xdef\currentregisterkeysa{\registerparameter{\c!keys:1}}% + \xdef\currentregisterkeysb{\registerparameter{\c!keys:2}}% + \xdef\currentregisterkeysc{\registerparameter{\c!keys:3}}% + \xmlstopraw + \else + \xdef\currentregisterkeysa{\registerparameter{\c!keys:1}}% + \xdef\currentregisterkeysb{\registerparameter{\c!keys:2}}% + \xdef\currentregisterkeysc{\registerparameter{\c!keys:3}}% + \fi + \fi + \setnextinternalreference + % we could consider storing register entries in a list which we + % could then sort + \xdef\currentregisternumber{\ctxlua{ + jobregisters.store { % 'own' should not be in metadata + metadata = { + kind = "entry", + name = "\currentregister", + level = structure.sections.currentlevel(), + coding = "\currentregistercoding", + catcodes = \the\catcodetable, + \ifx\currentregisterownnumber\v!yes + own = "\registerparameter\c!alternative", % can be used instead of pagenumber + \fi + xmlroot = \ifx\currentreferencecoding\s!xml "\xmldocument" \else nil \fi, % only useful when text +\ifx\currentregisterxmlsetup\empty \else + xmlsetup = "\currentregisterxmlsetup", +\fi + }, + references = { + internal = \nextinternalreference, + section = structure.sections.currentid(), % hm, why then not also lastsection the same way + label = "\currentregisterlabel", + }, +% \ifx\currentregisterentries\empty \else + entries = { + % we need a special one for xml, this is just a single one + \ifx\currentregisterentries\empty + { \!!bs\currentregisterentriesa\!!es, \!!bs\currentregisterentriesb\!!es, \!!bs\currentregisterentriesc\!!es }, + \else + \!!bs\currentregisterentries\!!es, + \fi + \ifx\currentregisterkeys\empty + { \!!bs\currentregisterkeysa\!!es, \!!bs\currentregisterkeysb\!!es, \!!bs\currentregisterkeysc\!!es }, + \else + \!!bs\currentregisterkeys\!!es, + \fi + }, +% \fi + userdata = structure.helpers.touserdata(\!!bs\detokenize{#3}\!!es) + } + } }% + \ctxlua{jobreferences.setinternalreference(nil,nil,\nextinternalreference)}% + \ifx\currentregisterownnumber\v!yes + \glet\currentregistersynchronize\relax + \else + \xdef\currentregistersynchronize{\ctxlatelua{jobregisters.enhance("\currentregister",\currentregisternumber)}}% + \fi + \currentregistersynchronize % here? + \attribute\destinationattribute\lastdestinationattribute \forcecolorhack % no \strut as it will be removed during cleanup + \endgroup} + +\def\doregister[#1][#2]% + {\def\currentregister{#1}% + \doifelse{\registerparameter\c!ownnumber}\v!yes\dodoregister\donoregister{#1}{#2}} + +\def\donoregister #1#2#3{\doflushatpar{\doregisterstructurepageregister{#1}{\c!keys={#2},\c!entries={#3}}{}}} +\def\dodoregister#1#2#3#4{\doflushatpar{\doregisterstructurepageregister{#1}{\c!keys={#2},\c!alternative=#3,\c!entries={#4}}{}}} + +\unexpanded\def\startregister{\doquadrupleempty\dostartregister} +\unexpanded\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{\doregisterstructurepageregister{#1}{\c!label=#2,\c!alternative=#3,\c!keys={#4},\c!entries={#5}}{}}% + \else + % #1=register #2=tag #3=sortkey #5=entry + \doflushatpar{\doregisterstructurepageregister{#1}{\c!label=#2,\c!keys={#3},\c!entries={#5}}{}}% + \fi} + +\def\dostopregister[#1][#2]% + {\normalexpanded{\ctxlatelua{jobregisters.extend("#1","#2")}}} + +\def\setregisterentry {\dotripleempty\dosetregisterentry} +\def\finishregisterentry{\dotripleempty\dofinishregisterentry} + +% not yet document, not sure if this will stay: + +\def\dosetregisterentry [#1][#2][#3]{\doflushatpar{\doregisterstructurepageregister{#1}{#2}{#3}}} +\def\dofinishregisterentry[#1][#2][#3]{\dofinishregisterstructurepageregister{#1}{#2}{#3}} + +\def\dofinishregisterstructurepageregister#1#2#3% register data userdata + {\begingroup + \edef\currentregister{#1}% + \getparameters[\??id][\c!entries=,\c!label=,\c!keys=,\c!alternative=,#2]% + \edef\currentregisterlabel {\registerparameter\c!label}% + \edef\currentregisterexpansion{\registerparameter\c!expansion}% + \edef\currentregisterownnumber{\registerparameter\c!ownnumber}% + \xdef\currentregisterkeys {\registerparameter\c!keys}% + \ifx\currentregisterexpansion\s!xml + \xmlstartraw + \xdef\currentregisterentries{\registerparameter\c!entries}% + \xmlstopraw + \globallet\currentregistercoding\s!xml + \else + \ifx\currentregisterexpansion\v!yes + \xdef\currentregisterentries{\registerparameter\c!entries}% + \else + \xdef\currentregisterentries{\detokenizedregisterparameter\c!entries}% + \fi + \globallet\currentregistercoding\s!tex + \fi + \ifx\currentregisterentries\empty + \normalexpanded{\ctxlua{jobregisters.extend("\currentregister","\currentregisterlabel", { + metadata = { + \ifx\currentregisterownnumber\v!yes + own = "\registerparameter\c!alternative", % can be used instead of pagenumber + \fi + }, + userdata = structure.helpers.touserdata(\!!bs\detokenize{#3}\!!es) + })% + }}% + \else + \normalexpanded{\ctxlua{jobregisters.extend("\currentregister","\currentregisterlabel", { + metadata = { + catcodes = \the\catcodetable, + coding = "\currentregistercoding", + \ifx\currentregisterownnumber\v!yes + own = "\registerparameter\c!alternative", % can be used instead of pagenumber + \fi + }, + entries = { + % we need a special one for xml, this is just a single one + \!!bs\currentregisterentries\!!es, \!!bs\currentregisterkeys\!!es + }, + userdata = structure.helpers.touserdata(\!!bs\detokenize{#3}\!!es) + }) + }}% + \fi + \endgroup} + +% The following variants are meant for (for instance xml). There is some +% overlap with previously defined macros. +% +% \starttext +% \setstructurepageregister[index][entries=alpha]a +% \setstructurepageregister[index][entries=gamma]g +% \setstructurepageregister[index][entries=beta]b +% \setstructurepageregister[index][entries:1=alpha,keys:1=z]a +% \setstructurepageregister[index][entries:1=gamma,keys:1=x]g +% \setstructurepageregister[index][entries:1=beta, keys:1=y]b +% \index{alpha}a +% \index{gamma}g +% \index{beta}b +% \placeregister[index][n=1] +% \stoptext + +\def\setstructurepageregister{\dotripleempty\dosetstructurepageregister} + +\def\dosetstructurepageregister[#1][#2][#3]% [register][settings][userdata] + {\doflushatpar{\doregisterstructurepageregister{#1}{#2}{#3}}} + +\unexpanded\def\startstructurepageregister{\doquadrupleempty\dostartstructurepageregister} +\unexpanded\def\stopstructurepageregister {\dodoubleargument\dostopstructurepageregister} + +\let\openstructurepageregisterrange \startstructurepageregister +\let\closestructurepageregisterrange\stopstructurepageregister + +\def\dostartstructurepageregister[#1][#2][#3][#4]% [register][tag][settings][userdata] + {\doflushatpar{\doregisterstructurepageregister{#1}{\c!label=#2,#3}{#4}}} + +\def\dostopstructurepageregister[#1][#2]% + {\normalexpanded{\ctxlatelua{jobregisters.extend("#1","#2")}}} + +% So far. + +\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 + \edef\temp{\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]% + {\begingroup + \edef\currentregister{#1}% + \setupregister[\currentregister][#2]% + \normalexpanded{\endgroup\noexpand\xdef\noexpand\utilityregisterlength{\ctxlua{jobregisters.analyse('\currentregister',{ + language = "\registerparameter\s!language", + compress = "\registerparameter\c!compress", + criterium = "\registerparameter\c!criterium", + })}}}% brrr + \ifcase\utilityregisterlength\relax + \resetsystemmode\v!register + \else + \setsystemmode \v!register + \fi} + +\newtoks\everyplaceregister + +\appendtoks + \dontcomplain +\to \everyplaceregister + +\unexpanded\def\placeregister + {\dodoubleempty\doplaceregister} + +\def\doplaceregister[#1][#2]% + {\iffirstargument + \begingroup +% \forgetall + \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", + starter = \!!bs\registerparameter\c!pageprefixstarter\!!es, + 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", + starter = \!!bs\registerparameter\c!pagestarter\!!es, + 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{\systemsuppliedchapter[\currentregister]{\noexpand\headtext{\currentregister}}}% + \placeregister[\currentregister][#2]% + \page[\v!yes]% + \endgroup + \fi} + +% test case for collapsing (experimental, for Steffen Wolfrum) +% +% \starttext +% \placeregister[index][compress=no] \blank[2*big] +% \placeregister[index][compress=yes] \blank[2*big] +% \placeregister[index][compress=all] \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} + {\doifnot{#1}\s!unknown + {\doifelse{\registerparameter\c!indicator}\v!yes + {\expandcheckedcsname{\??id:\c!indicator:}{\registerparameter\c!alternative}{a}{#1}} + {\noregistercharacter{#1}}}}} + +\def\noregistercharacter#1% + {\registerparameter\c!before + \goodbreak} + +% a = + +\setvalue{\??id:\c!indicator:a}#1% + {\registerparameter\c!before + % bugged, why does leftskip gets set: \vskip\lineheight\goodbreak\vskip-\lineheight + \begingroup\dosetregisterattributes\c!style\c!color + \registerparameter\c!command{\strut#1}% + \endgroup + \registerparameter\c!after + \par\nobreak} + + +% b = + +\setvalue{\??id:\c!indicator:b}#1% + {\registerparameter\c!before + \begingroup\dosetregisterattributes\c!style\c!color + \registerparameter\c!command{\strut#1}% + \endgroup + \registerparameter\c!after + \nobreak} + +\setvalue{\??id:\c!indicator:A}#1{\getvalue{\??id:\c!indicator:a}{\WORD{#1}}} +\setvalue{\??id:\c!indicator:B}#1{\getvalue{\??id:\c!indicator:b}{\WORD{#1}}} + +%D The following macros are the interface to the rendering. These are +%D generated by \LUA. This might change. + +%D Beware, we get funny side effects when a dangling \index precedes an +%D placeindex as then flushing takes place inside the index. Took me hours +%D to notice that. + +\unexpanded\def\startregisteroutput + {\endgraf + \begingroup + \forgetparindent + \forgetparskip} + +\unexpanded\def\stopregisteroutput + {\endgraf + \endgroup} + +\unexpanded\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} + +\unexpanded\def\stopregisterentries + {\endgraf + \endgroup} + +\unexpanded\def\startregistersection#1% title + {\registercharacter{#1}\endgraf} + +\unexpanded\def\stopregistersection + {\endgraf} + +\newconditional\registerpagedone + +\unexpanded\def\startregisterpages + {\begingroup + \setfalse\registerpagedone + \dosetregisterattributes\c!pagestyle\c!pagecolor} + +\unexpanded\def\stopregisterpages + {\endgroup} + +\unexpanded\def\startregisterseewords + {\begingroup + \setfalse\registerpagedone + \dosetregisterattributes\c!pagestyle\c!pagecolor} + +\unexpanded\def\stopregisterseewords + {\endgroup} + +\def\registerpageseparator% todo: , configurable + {\ifconditional\registerpagedone + \registerpageseparatorsymbol + \else + \hskip\registerparameter\c!distance\relax + \settrue\registerpagedone + \fi} + +\def\registeronepagerangeseparator{|\endash|} + +\def\withregisterpagecommand#1#2#3% + {\def\currentregisterpageindex{#1}% + \iflocation + \goto{\registerparameter\c!pagecommand{#3}}[internal(#1)]% + \else + \registerparameter\c!pagecommand{#3}% + \fi} + +\def\registeronepage#1#2#3% content + {\registerpageseparator + \withregisterpagecommand{#1}{#2}{#3}} + +\def\registerpagerange#1#2#3#4#5#6% content, content todo: -- configurable + {\registerpageseparator + \withregisterpagecommand{#1}{#2}{#3}% + \registeronepagerangeseparator + \withregisterpagecommand{#4}{#5}{#6}} + +\def\registeroneword#1#2#3% content + {\registerpageseparator + \registerseeword{#3}} + +\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\MyRegisterPageCommand#1% +% {#1\currentregisterpageuserdata{whatever}} +% +% \starttext +% \setregisterentry[index][entries=aaa][whatever=f.] test \index{bbb} test +% \placeregister[index][n=1,pagecommand=\MyRegisterPageCommand] +% \stoptext + +\def\registerpageuserdata #1#2{\ctxlua{jobregisters.userdata(#1,"#2")}} +\def\currentregisterpageuserdata {\registerpageuserdata\currentregisterpageindex} % {#1} + +% not yet ok : new internal handler names + +\def\registerpagebuttonsymbol{\vrule\!!width1em\!!height1ex\!!depth\zeropoint\relax} + +\setvalue{\??id:\c!symbol:\c!n}% + {\def\registerpageseparatorsymbol{, }} + +\setvalue{\??id:\c!symbol:\c!a}% + {\def\registerpageseparatorsymbol{, }} % now done via conversion + +\setvalue{\??id:\c!symbol:\v!none}% + {\let\registerpageseparatorsymbol\empty + \let\registeronepage \gobblethreearguments + \let\registerpagerange \gobblesixarguments} + +\setvalue{\??id:\c!symbol:1}% + {\let\registerpageseparatorsymbol\space + \def\registeronepage {\symbol[1]\gobblethreearguments}% + \def\registerpagerange {\symbol[1]\gobblesixarguments}} + +\setvalue{\??id:\c!symbol:2}% + {\let\registerpageseparatorsymbol\space + \def\registeronepage {\registerpagebuttonsymbol\gobblethreearguments}% + \def\registerpagerange {\registerpagebuttonsymbol\gobblesixarguments}} + +\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\registeronepage {\registerparameter\c!symbol\gobblethreearguments}% + \def\registerpagerange {\registerparameter\c!symbol\gobblesixarguments}% + \fi\fi} + +\appendtoks + \setregisterpagerendering +\to \everyplaceregister + +% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % +% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % +% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % + +%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.mkiv b/tex/context/base/strc-ren.mkiv new file mode 100644 index 000000000..3a60a34a3 --- /dev/null +++ b/tex/context/base/strc-ren.mkiv @@ -0,0 +1,492 @@ +%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 + +\unexpanded\def\placeheadmargintexts + {\the\everyheadstart + \doif{\structureheadparameter\c!margintext}\v!yes\placemargincontent} + +\unexpanded\def\setupheadcomponentfont#1#2% + {\ifconditional\structureheadisdisplay + \edef\askedstructureheadinterlinespace{\structureheadparameter\c!interlinespace}% + \ifx\askedstructureheadinterlinespace\empty + % here the interline space is only set when style sets no space + \setfalse\fontattributeisset + \setfalse\interlinespaceisset + \dosetstructureheadattributes\c!style\c!color + \ifconditional\fontattributeisset \ifconditional\interlinespaceisset \else + \setupinterlinespace + \fi \fi + \setfalse\fontattributeisset \dosetstructureheadattributes#1#2% + \ifconditional\fontattributeisset \ifconditional\interlinespaceisset \else + \setupinterlinespace + \fi \fi + \else + % here the set interline space overloads any other set space in the style + \setfalse\fontattributeisset + \dosetstructureheadattributes\c!style\c!color + \ifconditional\fontattributeisset + \dosetupcheckedinterlinespace\askedstructureheadinterlinespace + \fi + \setfalse\fontattributeisset + \dosetstructureheadattributes#1#2% + \ifconditional\fontattributeisset + \dosetupcheckedinterlinespace\askedstructureheadinterlinespace + \fi + \fi + \else + \setfalse\fontattributeisset + \dosetstructureheadattributes\c!style\c!color + \ifconditional\fontattributeisset + \setupspacing + \fi + \setfalse\fontattributeisset + \dosetstructureheadattributes#1#2% + \ifconditional\fontattributeisset + \setupspacing + \fi + \fi + \dontconvertfont} + +\def\doplaceheadtextcomponent#1#2% + {\begingroup + \setupheadcomponentfont\c!textstyle\c!textcolor + % \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 + \setupheadcomponentfont\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\structureheadattribute{\iflocation attr \destinationattribute \currentstructureattribute\fi} + +\def\doplacestructureheadtext#1#2#3% nodes, text, endstuff + {\beginheadplacement + \doresettructureheadnumbercontent + \ifconditional\structureheadleaveempty + \setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi \structureheadattribute to \zeropoint {#1}% + \makestrutofbox\sectionheadbox + \else + \setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi \structureheadattribute + {\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 + \doiftextelse{#2}\dosettructureheadnumbercontent\doresettructureheadnumbercontent + \ifconditional\structureheadleaveempty + \setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi \structureheadattribute to \zeropoint{#1}% + \makestrutofbox\sectionheadbox + \else % = needed + \setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi \structureheadattribute + {\ifcase\headtimingmode\or#1\fi + \dosetfontattribute{\??nh\currentstructurehead}\c!style + \structureheadparameter\c!command{\doplaceheadnumbercomponent{#1}{#2}}{\doplaceheadtextcomponent{#1}{#3}}}% + \fi + \endheadplacement{#4}} + +\unexpanded\def\placestructureheadnumbertext + {\doplacestructureheadnumbertext\empty\getstructureheadnumber\getstructureheadtitle\getstructureheadsyncs} + +\unexpanded\def\placestructureheadtext + {\doplacestructureheadtext\empty\getstructureheadtitle\getstructureheadsyncs} + +\unexpanded\def\placestructureheadempty + {\hbox \structureheadattribute {\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 + \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} + +% \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% + {\noflines\zerocount + \ifconditional\structureheadisdisplay % \ifdisplaysectionhead + % new (todo 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 + % kind of special, we want to snap heads also according to local specs local + \ifgridsnapping + \begingroup + \edef\currentstructureheadgridsnapping{\structureheadparameter\c!grid}% + \ifconditional\structureheadisdisplay + \ifx\currentstructureheadgridsnapping\empty\else + \dosetstructureheadattributes\c!style\c!color + \setupinterlinespace + \dosetstructureheadattributes\c!textstyle\c!textcolor + \setupinterlinespace + \fi + \fi + \snaptogrid[\currentstructureheadgridsnapping]\hbox + {\hskip\localheadskip\hskip\structureheadparameter\c!margin\box\sectionheadbox}% + \endgroup + \else + \hbox + {\hskip\localheadskip\hskip\structureheadparameter\c!margin\box\sectionheadbox}% + \fi + \flushnotes % 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 + \flushnotes % new, here since we're in par mode + \unhbox\sectionheadbox + \globallet\headlastlinewidth\!!zeropoint + #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 + \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 + +\unexpanded\def\defineheadplacement + {\dodoubleargument\dodefineheadplacement} + +\def\dodefineheadplacement[#1][#2]% #3#4 + {\setvalue{\??ns:#1}{#2}% + \setvalue{\??ns::#1}} + +\def\presetnumberheadalternative + {\doifelsevalue{\??ns:\numberheadalternative}\v!horizontal\setfalse\settrue\structureheadisdisplay} + +% \def\normalplacehead +% {\executeifdefined +% {\??ns::\numberheadalternative} +% {\getvalue{\??ns::\v!normal}}} + +\def\normalplacehead + {\csname\??ns::\ifcsname\??ns::\numberheadalternative\endcsname\numberheadalternative\else\v!normal\fi\endcsname} + +\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}} + +\unexpanded\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} + +\unexpanded\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.mkiv b/tex/context/base/strc-sbe.mkiv new file mode 100644 index 000000000..206ac8a9c --- /dev/null +++ b/tex/context/base/strc-sbe.mkiv @@ -0,0 +1,141 @@ +%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} + +\unexpanded\def\definestructureblock{\dotripleargument\dodefinestructureblock} +\unexpanded\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 + +\unexpanded\def\startstructureblock[#1]% + {%\ctxlua{structure.counters.check(0)}% we assume sane usage of \page, as this is the only workable place (in push) + \begingroup + \edef\currentstructureblock{\ctxlua{structure.sections.pushblock("#1")}}% + \csname #1true\endcsname % for old times sake + \setsystemmode\currentstructureblock + \the\everybeforestructureblock\relax + \showmessage\m!structures1\currentstructureblock} + +\unexpanded\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}} + \csname\??nb\s!do#1\endcsname} + +%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}}} + \grabuntil{\e!stop\v!structureblockenvironment}{\csname\??nb\s!do#1\endcsname}} + +% 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}}} + \grabuntil{\e!stop\v!sectionblockenvironment}{\csname\??nb\s!do#1\endcsname}} + +\protect \endinput diff --git a/tex/context/base/strc-sec.mkii b/tex/context/base/strc-sec.mkii new file mode 100644 index 000000000..0698ef93c --- /dev/null +++ b/tex/context/base/strc-sec.mkii @@ -0,0 +1,2591 @@ +%D \module +%D [ file=strc-sec, +%D version=1997.03.31, +%D title=\CONTEXT\ Structure 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 Structure 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 + +% from cont-new: + +\def\expandifnonempty#1% + {\@EA\ifx\csname#1\endcsname\empty + \expandafter\secondoftwoarguments + \else + \expandafter\firstoftwoarguments + \fi + {\csname#1\endcsname}} + +\def\@@sectiekoppeling#1% + {\expandifnonempty{\??ko#1\c!coupling}{#1}} + +\def\@@sectiesectie#1% + {\expandifnonempty{\??ko#1\c!section}{\@@sectiekoppeling{#1}}} + +\def\sectioncountervalue#1% + {\@@sectionvalue{\@@sectiesectie{#1}}} + +% \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/strc-sec.mkiv b/tex/context/base/strc-sec.mkiv new file mode 100644 index 000000000..35927d98a --- /dev/null +++ b/tex/context/base/strc-sec.mkiv @@ -0,0 +1,792 @@ +%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 / names and interface might change + +\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\getsomestructurenumber #1#2{\ctxlua{structure.sections.getnumber(#1,"#2")}} % level, what +\def\getfullstructurenumber #1{\ctxlua{structure.sections.fullnumber(#1)}} % level +\def\getsomefullstructurenumber#1#2{\ctxlua{structure.sections.fullnumber(#1,"#2")}} +\def\getspecificstructuretitle #1{\ctxlua{structure.sections.structuredata(#1,"titledata.title",nil,"\structureheadparameter\s!catcodes")}}% + +% 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\structureheadparameterstrict#1{\csname\ifcsname\??nh\currentstructurehead#1\endcsname\??nh\currentstructurehead#1\else\s!empty\fi\endcsname} + +\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 + +\unexpanded\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]}% + % this is a rather practical default that we don't want to be part of the parent chain + % lookup mechanism; it's also mkii compativle; this might become \everystructureheaddefine + \getparameters[\??nh#1] + [ \c!textstyle=\structureheadparameterstrict\c!style, + \c!textcolor=\structureheadparameterstrict\c!color, + \c!numberstyle=\structureheadparameterstrict\c!style, + \c!numbercolor=\structureheadparameterstrict\c!color]% + % so far for these default inheritances + \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}}} + +\unexpanded\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}{-1}} + +\setvalue{\??nh block\c!level}{0} % -1 == manual + +% head -> structurehead + +\let\currentstructurehead\empty +\newtoks\everystructureheadsetup + +\unexpanded\def\setupstructureheads{\dosingleargument\dosetupstructureheads} +\unexpanded\def\setupstructurehead {\dodoubleempty\dosetupstructurehead} +\unexpanded\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% + {\edef\currentstructurehead{#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, parent + {\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,\c!coupling=#2]% + \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}}% + \setstructurelevel\currentstructurehead{\thenamedstructureheadlevel\currentstructurehead}% + \doifelse{\structureheadparameter\c!ownnumber}\v!yes + {\setevalue\currentstructurehead{\noexpand\dohandlestructureheadown[\currentstructurehead]}} + {\setevalue\currentstructurehead{\noexpand\dohandlestructureheadnop[\currentstructurehead]}}% + \setevalue{\e!next \currentstructurehead}{\noexpand\donextstructurehead [\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 + \xdef\currentstructurehead{#1}% recover + \the\everyafterstructurehead} + +\def\donextstructurehead[#1][#2][#3]% + {\setfalse\currentstructureown + \xdef\currentstructurehead{#1}% + \dohandlestructurehead{#1}{#2}{#3}} % name -- -- -- userdata + +% \newconditional\structurereversesectionnumbers % todo: key/val + +\newconditional\structureheadtolist +\newconditional\structureheaddoincrement +\newconditional\structureheaddoplace +\newconditional\structureheadleaveempty +\newconditional\structureheadhidden +\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 + \setfalse\structureheadhidden + \processaction + [\structureheadparameter\c!placehead] + [ \v!yes=>, + \v!empty=>\settrue\structureheadleaveempty, + \v!no=>\settrue\structureheadleaveempty\setfalse\structureheaddoplace, + \v!hidden=>\settrue\structureheadhidden\settrue\structureheadleaveempty\setfalse\structureheaddoplace]} + +\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} + +\unexpanded\def\thestructureheadsynchonization + {\pagetype[\currentstructureheadcoupling]% hm also number + \normalexpanded{\noexpand\setmarking[\currentstructureheadcoupling]{\currentstructurelistnumber}}% + \currentstructuresynchronize} + +\unexpanded\def\fullstructureheadnumber{\labeltexts{\structureheadparameter\c!label}{\structurenumber}} % todo + +% \def\fullstructureheadtitle {\structurevariable{titledata.title}} % no catcode! +% \unexpanded\def\fullstructureheadtitle{\structureautocatcodedget{titledata.title}{\structureheadparameter\s!catcodes}} + +\unexpanded\def\fullstructureheadtitle{\ctxlua{structure.sections.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\structureheaddoincrement\ifconditional\structureheadshownumber\v!yes\else\v!no\fi\else\v!no\fi, + \c!bookmark=, + \c!marking=, + \c!list=, + \c!expansion=\structureheadparameter\c!expansion, + \c!xmlsetup=\structureheadparameter\c!xmlsetup, + \s!catcodes=\structureheadparameter\s!catcodes, + \c!sectionresetset=\structureheadparameter\c!sectionresetset, + \c!sectionseparatorset=\structureheadparameter\c!sectionseparatorset, + \c!sectionconversionset=\structureheadparameter\c!sectionconversionset, + \c!sectionconversion=\structureheadparameter\c!conversion, % just for compatibility + \c!sectionstarter=\structureheadparameter\c!sectionstarter, + \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 {\dosingleempty\doplaceheadtext } % use with care +\unexpanded\def\placeheadnumber{\dosingleempty\doplaceheadnumber} % use with care + +\ifdefined\setupheadcomponentfont \else + + \unexpanded\def\setupheadcomponentfont#1#2% + {\dosetstructureheadattributes\c!style\c!color + \dosetstructureheadattributes#1#2% + \dontconvertfont + \setupinterlinespace} + +\fi + +\def\doplaceheadtext[#1]% + {\dontleavehmode + \begingroup + \edef\currentstructurehead{#1}% + \setupheadcomponentfont\c!textstyle\c!textcolor + \relax + \getspecificstructuretitle{\thenamedstructureheadlevel{#1}}% + \endgraf + \endgroup} + +\def\doplaceheadnumber[#1]% + {\dontleavehmode + \begingroup + \edef\currentstructurehead{#1}% + \setupheadcomponentfont\c!numberstyle\c!numbercolor + \relax + \getfullstructurenumber{\thenamedstructureheadlevel{#1}}% + \endgraf + \endgroup} + +\ifdefined \else \let\presetnumberheadalternative\relax \fi + +\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 + \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 + \presetnumberheadalternative + % + \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\fullstructureheadtitle + \ifconditional\structureheadshownumber + \let\getstructureheadnumber\fullstructureheadnumber + \placestructureheadnumbertext + \else + \placestructureheadtext + \fi + \dostructureheadspacingafteryes + \else\ifconditional\structureheadhidden + \doregisterstructurehead{#1}{#2}{#3}% after optional \page + \let\getstructureheadsyncs\thestructureheadsynchonization + \placestructureheadhidden % only something when tracing + \else + \dostructureheadspacingbeforenop % toegevoegd ivm subpaginanr / tug sheets + \doregisterstructurehead{#1}{#2}{#3}% after optional \page + \let\getstructureheadsyncs\thestructureheadsynchonization + \placestructureheadempty % just flush 'm + \dostructureheadspacingafternop + \fi\fi + \else + \ifconditional\structureheaddoplace + \dostructureheadspacingbeforeyes + \doregisterstructurehead{#1}{#2}{#3}% after optional \page + \let\getstructureheadsyncs\thestructureheadsynchonization + \let\getstructureheadtitle\fullstructureheadtitle + \placestructureheadtext + \dostructureheadspacingafteryes + \else\ifconditional\structureheadhidden + \doregisterstructurehead{#1}{#2}{#3}% after optional \page + \let\getstructureheadsyncs\thestructureheadsynchonization + \placestructureheadhidden % only something when tracing + \else + % do nothing / should be vbox to 0pt + \dostructureheadspacingbeforenop + \doregisterstructurehead{#1}{#2}{#3}% after optional \page + \let\getstructureheadsyncs\thestructureheadsynchonization + \placestructureheadempty % just flush 'm + \dostructureheadspacingafternop + \fi\fi + \fi + \flushingcolumnfloatstrue + \setfalse\ignorehandlepagebreak + % ignorespaces prevents spaces creeping in when after=\dontleavehmode + \ifconditional\structureheadisdisplay % \ifdisplaysectionhead + \ignorespaces + \else + \expandafter\GotoPar + \fi} + +% typesetting + +\unexpanded\def\placestructureheadnumbertext % dummy, will be overloaded + {\getstructureheadnumber/\getstructureheadtitle + \getstructureheadsyncs} + +\unexpanded\def\placestructureheadtext % dummy, will be overloaded + {\getstructureheadtitle + \getstructureheadsyncs} + +\unexpanded\def\placestructureheadempty % dummy, will be overloaded + {\getstructureheadsyncs} + +\unexpanded\def\placestructureheadhidden + {\setxvalue{\currentstructurehead:sync}% + {\noexpand\pagetype[\currentstructureheadcoupling]% hm also number + \noexpand\setmarking[\currentstructureheadcoupling]{\currentstructurelistnumber}% + \currentstructuresynchronize}} + +\def\synchronizestructurehead#1% + {\getvalue{#1:sync}} + +\unexpanded\def\placerawheaddata [#1]{\synchronizestructurehead {#1}} +\unexpanded\def\placerawheadtext [#1]{\getspecificstructuretitle{\thenamedstructureheadlevel{#1}}} +\unexpanded\def\placerawheadnumber[#1]{\getfullstructurenumber {\thenamedstructureheadlevel{#1}}} + +% \setuphead[chapter][placehead=hidden] +% \chapter {test} +% +% %(\synchronizestructurehead{chapter}) % \getstructureheadsyncs +% %(\getfullstructurenumber{\thenamedstructureheadlevel{chapter}}) +% %(\getspecificstructuretitle{\thenamedstructureheadlevel{chapter}}) +% +% (\placerawheaddata [chapter]) +% (\placerawheadnumber[chapter]) +% (\placerawheadtext [chapter]) + +% pagebreaks + +\newcount\precedingstructurelevel \precedingstructurelevel\plusone +\newconditional\ignorehandlepagebreak + +\def\dostructureheadspacingbeforeyes + {\docheckstructureheadbefore + \dohandlestructureheadpagebreak + \structureheadparameter\c!inbetween} + +\def\dostructureheadspacingbeforenop + {\docheckstructureheadbefore + \docheckstructureheadlayout + \structureheadparameter\c!inbetween} + +% \def\emptystructureheadcorrection +% {\ifconditional\structureheadleaveempty % inlined \emptyheadcorrection (with after=\blank) +% \vskip-\lineheight +% \dosomebreak\nobreak % \penalty10000 in vspacing +% \kern\zeropoint +% \prevdepth\strutdepth +% \fi} + +\def\emptystructureheadcorrection + {\ifconditional\structureheadleaveempty % inlined \emptyheadcorrection (with after=\blank) + \penalty10000 % first ... we need to adapt this all to vspacing + \vskip-\lineheight + \kern\zeropoint + \prevdepth\strutdepth + \fi} + +\def\dostructureheadspacingafteryes + {\ifconditional\structureheadisdisplay + \dosomebreak\nobreak % needs to be adapted to vspacing + \emptystructureheadcorrection + \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 +\chardef\somestructureheadbreakmethod\plusthree + +% \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} +% +% todo: \vspacing[category:8] == keep_together + +\def\dopreventbreakafterstructureheadauto % used after \c!before + {\ifcase\somestructureheadbreakmethod + % 0 = nothing + \else + \vspacing[\v!samepage-\currentstructureheadlevel]% + \fi} + +\def\dopreventbreakafterstructureheadspec#1% see enumerations etc + {\ifcase\somestructureheadbreakmethod + % 0 = nothing + \else + \vspacing[\v!samepage-\the\numexpr\currentstructureheadlevel+1\relax]% todo #1 + \fi} + +\def\dohandlepagebreakX{\dopreventbreakafterstructureheadspec} % no \let so we can redefind + +% we do support negative numbers but it can have side effects that we won't +% catch +% +% \chapter{some} \setupheadnumber[chapter][3] \chapter{more} +% \setupheadnumber[section][8] \section{b} \section{c} \setupheadnumber[section][-1] \section{d} + +% \def\thecurrentstructureheadlevel#1% +% {\getcurrentstructurelevel{#1}} + +\def\thenamedstructureheadlevel#1% + {\structuresectionlevel{\structuresectionheadsection{\structuresectionheadcoupling{#1}}}} + +\unexpanded\def\setupheadnumber + {\dodoubleargument\dosetupheadnumber} + +\def\dosetupheadnumber[#1][#2]% todo: reset if at other level + {\setstructurenumber{\thenamedstructureheadlevel{#1}}{#2}} + +\def\currentstructureheadnumber{0} % ==> \currentheadnumber + +\unexpanded\def\determineheadnumber[#1]% + {\xdef\currentstructureheadnumber{\getstructurenumber{\thenamedstructureheadlevel{#1}}}} + +% The previous macro is been replaced by the expandable: + +\def\namedheadnumber #1{\getstructurenumber {\thenamedstructureheadlevel{#1}}} +\def\somenamedheadnumber#1#2{\getsomestructurenumber{\thenamedstructureheadlevel{#1}}{#2}} + +\unexpanded\def\structureheadnumber + {\dodoubleempty\dostructureheadnumber} + +\def\dostructureheadnumber[#1][#2]% simple case is just a number + {\getsomefullstructurenumber{\iffirstargument\thenamedstructureheadlevel{#1}\fi}{#2}} + +\def\somestructureheadnumber + {\dodoubleempty\dosomestructureheadnumber} + +\def\dosomestructureheadnumber[#1][#2]% + {\dontleavehmode + \begingroup + \edef\currentstructurehead{#1}% + \getsomefullstructurenumber{\thenamedstructureheadlevel{#1}}{#2}% + \endgroup} + +% compatibility code (after all, we might offer different structure handlers as well +% but we might as well remove the 'structure' substring at some point (we needed it +% in order to test the old and new methods alongside) + +\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\sectioncountervalue\structurevalue + +\def\currentheadnumber {\currentstructureheadnumber} +\def\currentheadtext {obsolete, use marks} + +% 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-swd.mkii b/tex/context/base/strc-swd.mkii new file mode 100644 index 000000000..4a71b8781 --- /dev/null +++ b/tex/context/base/strc-swd.mkii @@ -0,0 +1,127 @@ +%D \module +%D [ file=strc-swd, +%D version=2007.08.14, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Section Worlds, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 prelude to a rewrite of sectioning. + +% options : before after setups page text number label bookmark +% dodo : listtext +% +% \startsectionworld[chapter][text={Test}] +% \stopsectionworld + +\writestatus{loading}{ConTeXt Structure Macros / Sectionworlds} + +\unprotect + +\ifx\pushvalue\undefined + + \def\pushvalue#1{\expandafter\pushmacro\csname#1\endcsname} + \def\popvalue #1{\expandafter\popmacro \csname#1\endcsname} + +\fi + +% brrr + +\def\csnameexpanded#1#2% + {\@EA\@EA\@EA\@EA\@EA\@EA\@EA#1\@EA\@EA\@EA\@EA\@EA\@EA\@EA#2\@EA\@EA\@EA\@EA\@EA\@EA\@EA} + +\def\csnameexpandedoneargument#1#2% + {\csnameexpanded\def\csexpandeda{#2}% + \@EA#1\@EA{\csexpandeda}} + +\def\csnameexpandedtwoarguments#1#2#3% + {\csnameexpanded\def\csexpandeda{#2}% + \csnameexpanded\def\csexpandedb{#3}% + \@EA\@EA\@EA#1\@EA\@EA\@EA{\@EA\csexpandeda\@EA}\@EA{\csexpandedb}} + +\def\csnameexpandedthreearguments#1#2#3#4% + {\csnameexpanded\def\csexpandeda{#2}% + \csnameexpanded\def\csexpandedb{#3}% + \csnameexpanded\def\csexpandedc{#4}% + \@EA\@EA\@EA\@EA\@EA\@EA\@EA#1\@EA\@EA\@EA\@EA\@EA\@EA\@EA{\@EA\@EA\@EA\csexpandeda\@EA\@EA\@EA}\@EA\@EA\@EA{\@EA\csexpandedb\@EA}\@EA{\csexpandedc}} + +% \def\xx{XX}\setvalue{xx:yy}{abc \xx def}\def\param#1{\csname xx:#1\endcsname} +% \def\testa #1{\defconvertedargument\ascii{#1}{\tttf\ascii}} +% \def\testb #1#2{\defconvertedargument\ascii{#1 #2}{\tttf\ascii}} +% \def\testc#1#2#3{\defconvertedargument\ascii{#1 #2 #3}{\tttf\ascii}} +% \noindent 1 \csnameexpandedoneargument \testa{\param{yy}} +% \noindent 2 \csnameexpandedtwoarguments \testb{\param{yy}}{\param{yy}} +% \noindent 3 \csnameexpandedthreearguments\testc{\param{yy}}{\param{yy}}{\param{yy}} + +% rewrite the sectioning to use the variables, a bit tricky because then +% we need a special expansion trick + +\def\sectionworldparameter #1{\csname\??sw\currentsectionworldname#1\endcsname} +\def\pushsectionworldparameter#1{\expandafter\pushmacro\csname\??sw\currentsectionworldname#1\endcsname} +\def\popsectionworldparameter #1{\expandafter\popmacro \csname\??sw\currentsectionworldname#1\endcsname} + +\def\setupsectionworld + {\dodoubleargument\dosetupsectionworld} + +\def\dosetupsectionworld[#1][#2]% + {\getparameters[\??sw#1][#2]} % maybe some extra things + +\def\dochecksectionworld#1% + {\ifcsname\??sw\currentsectionworldname\endcsname\else + \getparameters + [\??sw\currentsectionworldname] + [\c!before=, + \c!after=, + \c!setups=, + \c!page=]% + \fi} + +\def\startsectionworld + {\dodoubleargument\dostartsectionworld} + +\def\dostartsectionworld[#1][#2]% + {\pushmacro\currentsectionworldname + \def\currentsectionworldname{#1}% + \dochecksectionworld\currentsectionworldname + \pushsectionworldparameter\c!before + \pushsectionworldparameter\c!after + \pushsectionworldparameter\c!setups + \getparameters + [\??sw\currentsectionworldname] + [\c!text=,\c!number=\finalsectionnumber,\c!label=,\c!bookmark=,#2]% + \doifsomething{\sectionworldparameter\c!page} + {\setsectieenkoppeling\currentsectionworldname + %\handlepagebreak\currentsectionworldname + \checknexthead\handlepagebreak\currentsectionworldname}% + \sectionworldparameter\c!before + \begingroup + \doifsomething{\sectionworldparameter\c!page} + {\settrue\ignorehandlepagebreak}% + \doifsomething{\sectionworldparameter\c!setups} + {\setups[\sectionworldparameter\c!setups]}% + \csnameexpandedthreearguments \doconstructheadwithvars + {\sectionworldparameter\c!label }% + {\sectionworldparameter\c!number}% + {\sectionworldparameter\c!text }% + \doifsomething{\sectionworldparameter\c!bookmark} + {\expanded{\bookmark[\sectionworldparameter\c!bookmark]}}% + \ignorespaces} % for inline heads + +\def\doconstructheadwithvars#1%#2#3% + {\dodododoconstructhead\currentsectionworldname[#1]}% {#2}{#3}} + +\def\stopsectionworld + {\endgraf + \endgroup + \sectionworldparameter\c!after + \popsectionworldparameter\c!setups + \popsectionworldparameter\c!after + \popsectionworldparameter\c!before + \popmacro\currentsectionworldname} + +\protect \endinput diff --git a/tex/context/base/strc-syn.lua b/tex/context/base/strc-syn.lua new file mode 100644 index 000000000..d6f38c2c7 --- /dev/null +++ b/tex/context/base/strc-syn.lua @@ -0,0 +1,189 @@ +if not modules then modules = { } end modules ['str-syn'] = { + version = 1.001, + comment = "companion to str-syn.mkiv", + 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() + for entry, data in next, tobesaved do + data.hash = nil + end +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) + if not data.hash[spec.definition.tag or ""] then + data.entries[#data.entries+1] = spec + data.hash[spec.definition.tag or ""] = spec + end +end + +function joblists.registerused(class,tag) + local data = allocate(class) + local dht = data.hash[tag] + if dht then + dht.definition.used = true + end +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 + +joblists.compare = sorters.comparers.basic -- (a,b) + +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 = { } + for k=1,#result do + local v = result[k] + local entry, tag = sorters.firstofsplit(v) + local s = split[entry] -- keeps track of change + 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 + local sorted = table.sortedkeys(result) + for k=1,#sorted do + local letter = sorted[k] + 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}{%s}",kind,d,entry.tag,entry.synonym,entry.meaning or "")) + 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 + options = options or { } + sorters.setlanguage(options.language) + 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.mkii b/tex/context/base/strc-syn.mkii new file mode 100644 index 000000000..39acb7d91 --- /dev/null +++ b/tex/context/base/strc-syn.mkii @@ -0,0 +1,438 @@ +%D \module +%D [ file=strc-syn, +%D version=1997.03.31, +%D title=\CONTEXT\ Structure 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. + +\writestatus{loading}{ConTeXt Structure Macros / Synonyms and Sorts} + +\unprotect + +% \checkdefined kan hierheen + +% Formaat tex-utility-input-file : +% +% synonym entry {tag} {pure} {text} {synonym} +% +% Deze file wordt met het programma TeXUtil omgezet in een +% in te lezen TeXFile met de commando's: +% +% \synonymentry {tag} {pure} {text} {synonym} + +\newif\ifsynonymmeaning + +% todo: \def\synonymparameter#1{\csname\??sm\currentsynonym#1\endcsname} + +\def\dosetupsynonyms[#1][#2]% + {\getparameters[\??sm#1][#2]} + +\def\setupsynonyms + {\dodoubleargument\dosetupsynonyms} + +\def\doresetsynonym#1% + {\letvalue{#1\s!entry}\gobblethreearguments} + +\def\dohandlesynonymentry#1#2#3#4% + {\bgroup + \global\utilitydonetrue + \syndef + {\doattributes{\??sm#1}\c!textstyle\c!textcolor{#3}} + \ConvertToConstant\doifelse{#4}{}{\unknown}{#4}\par + \egroup} + +\def\synonymentry#1% + {\executeifdefined{#1\s!entry}\gobblethreearguments} + +\def\dosetsynonym#1% + {\doifdefinedelse{\??sm#1\c!command} + {\setvalue{#1\s!entry}{\getvalue{\??sm#1\c!command}}} % 3 argumenten + {\setvalue{#1\s!entry}{\dohandlesynonymentry{#1}}}} + +\def\synonymparameter#1{\csname\??sm\currentsynonym#1\endcsname} + +\def\doplacelistofsynonyms#1#2% + {\whitespace + \begingroup + \def\currentsynonym{#1}% + \definedescription % nog eens een class van maken, net als framed + [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=]% + \setupwhitespace[\v!none]% + %doutilities{#1}\jobname{#2}\relax\par % no longer \par + \doutilities{#1}\jobname{#1}\relax\relax + \endgroup + \ifutilitydone\else\nowhitespace\fi} + +\def\docompletelistofsynonyms#1#2% expansion needed to avoid v! (due to french active !) + {\expanded{\systemsuppliedchapter[#1]{\noexpand\headtext{#2}}}% + \doplacelistofsynonyms{#1}{#2}% + \page[\v!yes]} + +\def\processsynonym#1#2#3% + {\begingroup % anders in mathmode lege \hbox, zie eenheden + \ifsynonymmeaning + \synonymmeaningfalse + \doattributes{\??sm#1}\c!synonymstyle\c!synonymcolor{#3}% + \else + \dontleavehmode + \doattributes{\??sm#1}\c!textstyle\c!textcolor{#2}% + \fi + \endgroup} + +\def\getsynonymmeaning#1#2#3% + {\bgroup + \doifundefined{#2#3} + {\setgvalue{#2#3}{{\tt[#3]}}% + \showmessage\m!systems{18}{#1,#3}}% + \synonymmeaningtrue + \getvalue{#2#3}% + \egroup} + +\def\dowritesynonym#1#2#3#4% + {\begingroup % anders in mathmode lege \hbox + \defconvertexpanded\asciisynonym{\getvalue{\??sm#1\c!expansion}}{#3}% + \defconvertexpanded\asciimeaning{\getvalue{\??sm#1\c!expansion}}{#4}% + \immediatewriteutility{s e {#1} {#2} {\asciisynonym} {\asciimeaning}}% + \endgroup} + +\def\reprocesssynonym#1#2#3% + {\processsynonym{#1}{#2}{#3}% + \getvalue{\??sm#1\c!next}} % not formally documented + +\def\preexecutesynonym#1#2#3#4% + {\ifdoinpututilities \else + \dowritesynonym{#1}{#2}{#3}{#4}% + \unexpanded\setgvalue{#2}{\reprocesssynonym{#1}{#3}{#4}}% + \fi} + +\def\executesynonym#1#2#3#4% + {\preexecutesynonym{#1}{#2}{#3}{#4}% + \processsynonym{#1}{#3}{#4}% + \getvalue{\??sm#1\c!next}} % not formally documented + +\def\expandsynonym#1#2#3#4% + {{\synonymmeaningtrue + \processsynonym{#1}{#3}{#4}}} + +\def\dodoloadsynonym#1#2#3#4% + {\setgvalue{#2}{\executesynonym{#1}{#2}{#3}{#4}}} + +\def\doloadsynonym#1% + {\setvalue{#1\s!entry}##1##2##3% + {\doifelsenothing{##1} + {\dodoloadsynonym{#1}{##2}{##2}{##3}} + {\dodoloadsynonym{#1}{##1}{##2}{##3}}% + \global\utilitydonetrue}} + +\def\doloadsynonyms#1#2% + {\bgroup + \let\dosetsynonym\doloadsynonym + \showmessage\m!systems{19}{#2}% + \doutilities{#1}\jobname{#1}\relax\relax + \egroup + \setvalue{\s!check#1}##1{}} + +\def\dodocomplexsynonym[#1][#2]#3#4% + {\doifsomething{#2} + {\getvalue{\s!check#1}{#2}% + \doglobal\appendtoks\setvalue{#2}{#2}\to\simplifiedcommands + \doifelsevalue{\??sm#1\c!conversion}\v!yes + {\unexpanded\setgvalue{#2}{\expandsynonym{#1}{#2}{#3}{#4}}} + {\doifelsevalue{\??sm#1\c!state}\v!start + {\doifelsevalue{\??sm#1\c!criterium}\v!all + {\preexecutesynonym{#1}{#2}{#3}{#4}} + {\unexpanded\setgvalue{#2}{\executesynonym{#1}{#2}{#3}{#4}}}} + {\unexpanded\setgvalue{#2}{\processsynonym{#1}{#3}{#4}}}}}} + +\def\docomplexsynonym[#1][#2][#3]#4#5% + {\ifthirdargument + \dodocomplexsynonym[#2][#1#3]{#4}{#5}% + \else + \dodocomplexsynonym[#2][#1#4]{#4}{#5}% + \fi} + +\def\doregistersynonymlanguage#1% + {\savesortlanguage{\getvalue{\??sm#1\s!language}}% + \immediatewriteutility{s l {#1} {\getvalue{\??sm#1\s!language}}}} + +\def\dodefinesynonyms[#1][#2][#3][#4]% + {\iffourthargument + \unexpanded\def#4##1{\getsynonymmeaning{#1}{\??sm:#1:}{##1}}% + \ifthirdargument + \unexpanded\def#3##1{\getvalue{\??sm:#1:##1}}% + \fi + \setvalue{#1}{\dotripleempty\docomplexsynonym[\??sm:#1:][#1]}% + \else + \ifthirdargument + \unexpanded\def#3##1{\getsynonymmeaning{#1}{}{##1}}% + \fi + \setvalue{#1}{\dotripleempty\docomplexsynonym[][#1]}% + \fi + \dosetupsynonyms + [#1]% + [\c!synonymstyle=,\c!textstyle=, + \c!headstyle=,\c!headcolor=, + \c!state=\v!start,\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]% + \doglobal\appendtoksonce + \doregistersynonymlanguage{#1}% + \to \everysavesortkeys + \presetheadtext[#2=\Word{#2}]% changes the \if...argument + \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}}% + \setvalue{\s!check #1}##1{\checkdefined{synonym}{#1}{##1}}% + \setvalue{\e!load #2}{\doloadsynonyms{#1}{#2}}% + \setvalue{\e!place\e!listof #2}{\doplacelistofsynonyms{#1}{#2}}% + \setvalue{\e!complete\e!listof#2}{\docompletelistofsynonyms{#1}{#2}}} + +\def\definesynonyms + {\doquadrupleempty\dodefinesynonyms} + +% Formaat tex-utility-input-file : +% +% synonym entry {tag} {pure} {text} {} +% +% Deze file wordt met het programma TeXUtil omgezet in een +% in te lezen TeXFile met de commando's: +% +% \synonymentry {tag} {pure} {text} {} + +\def\dosetupsorting[#1][#2]% + {\getparameters[\??so#1][#2]} + +\def\setupsorting + {\dodoubleargument\dosetupsorting} + +\def\doresetsort#1% + {\letvalue{#1\s!entry}\gobblethreearguments} + +\def\dosetsort#1% + {\setvalue{#1\s!entry}##1##2##3% + {\let\dowritesort\gobblethreearguments + \global\utilitydonetrue + \bgroup + \doifdefinedelse{\??so#1\c!command} + {\getvalue{\??so#1\c!command}{##2}} % 1 argument + {\getvalue{\??so#1\c!before}% + \doattributes{\??so#1}\c!style\c!color{##2}% + \getvalue{\??so#1\c!after}}% + \egroup}} + +\def\doplacelistofsorts#1% NOG EEN RUWE VERSIE MAKEN + {\whitespace % ZONDER WITRUIMTE ETC ETC + \begingroup + \setupwhitespace[\v!none]% + \doutilities{#1}\jobname{#1}\relax\relax + \endgroup + \ifutilitydone\else\nowhitespace\fi} + +% to be tested +% +% \def\doplacelistofsorts#1% NOG EEN RUWE VERSIE MAKEN +% {\startpacked +% %doutilities{#1}\jobname{#1}\relax\par +% \doutilities{#1}\jobname{#1}\relax\relax +% \stoppacked} + +\def\docompletelistofsorts#1#2% + {\expanded{\systemsuppliedchapter[#1]{\noexpand\headtext{#2}}}% + \doplacelistofsorts{#1}% + \page[\v!yes]} + +% todo: +% +% \def\placelistofsorts[#1]% +% {\doplacelistofsorts{#1}} + +\def\processsort#1#2#3% + {\dontleavehmode + \begingroup % was \bgroup + \doattributes{\??so#1}\c!style\c!color{#2}% + \endgroup} % was \egroup + +\def\dowritesort#1#2#3% + {\bgroup + \defconvertexpanded\asciisynonym{\getvalue{\??so#1\c!expansion}}{#3}% + \immediatewriteutility{s e {#1} {#2} {\asciisynonym} {}}% + \egroup} + +\def\synonymentry#1% + {\executeifdefined{#1\s!entry}\gobblethreearguments} + +\def\reprocesssort#1#2#3% + {\processsort{#1}{#2}{#3}% + \getvalue{\??so#1\c!next}} + +\def\preexecutesort#1#2#3% + {\ifdoinpututilities \else + \dowritesort{#1}{#2}{#3}% + \unexpanded\setgvalue{#2}{\reprocesssort{#1}{#3}{#2}}% + \fi} + +\def\executesort#1#2#3% + {\begingroup + \let\executesort\thirdofthreearguments % Trick needed for nested logo's. + \preexecutesort{#1}{#2}{#3}% + \processsort{#1}{#3}{#2}% + \endgroup + \getvalue{\??so#1\c!next}} % not formally documented + +\def\doloadsort#1% + {\setvalue{#1\s!entry}##1##2##3% + {\setgvalue{##1}{##2}% + \global\utilitydonetrue}} + +\def\doloadsort#1#2% + {\bgroup + \let\dosetsort\doloadsort + \showmessage\m!systems{20}{#2}% + \doutilities{#1}\jobname{#1}\relax\relax + \egroup + \setvalue{\s!check#1}##1{}} + +\def\dodocomplexsort[#1][#2]#3% + {\doifsomething{#2} + {\getvalue{\s!check#1}{#2}% + \doglobal\appendtoks\setvalue{#2}{#2}\to\simplifiedcommands + \doifelsevalue{\??so#1\c!state}\v!start + {\doifelsevalue{\??so#1\c!criterium}\v!all + {\preexecutesort{#1}{#2}{#3}} + {\unexpanded\setgvalue{#2}{\executesort{#1}{#2}{#3}}}} + {\unexpanded\setgvalue{#2}{\processsort{#1}{#3}{#2}}}}} + +\def\docomplexsort[#1][#2][#3]#4% + {\ifthirdargument + \dodocomplexsort[#2][#1#3]{#4}% + \else + \dowritesort{#2}{#4}{#4}% + \fi} + +% if #3=\relax or \v!none, then no command but still protected + +\def\doregistersortinglanguage#1% + {\savesortlanguage{\getvalue{\??so#1\s!language}}% + \immediatewriteutility{s l {#1} {\getvalue{\??so#1\s!language}}}} + +\def\dodefinesorting[#1][#2][#3]% + {\getparameters[\??so#1] + [%\c!command=, % we test for defined ! + \c!state=\v!start, + \c!criterium=, + \c!style=, + \c!before=, + \c!after=\endgraf, + \c!expansion=, + \s!language=\currentmainlanguage]% + \doglobal\appendtoksonce + \doregistersortinglanguage{#1}% + \to \everysavesortkeys + \ifthirdargument + \ConvertConstantAfter\doifnot{#3}\v!none + {\ifx#3\relax \else + \def#3##1{\getvalue{\??so:#1:##1}} + \fi}% + \setvalue{#1}{\dotripleempty\docomplexsort[\??so:#1:][#1]}% + \else + \setvalue{#1}{\dotripleempty\docomplexsort[][#1]}% + \fi + \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}}% + \setvalue{\s!reset#1}{\doresetsort{#1}}% + \setvalue{\e!load#2}{\doloadsort{#1}{#2}}% + \setvalue{\s!check#1}##1{\checkdefined{sort}{#1}{##1}}% + \setvalue{\e!place\e!listof#2}{\doplacelistofsorts{#1}}% + \setvalue{\e!complete\e!listof#2}{\docompletelistofsorts{#1}{#2}}} + +\def\definesorting + {\dotripleempty\dodefinesorting} + +%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\processlistofsorts[#1]% + {\doutilities{#1}\jobname{#1}\relax\relax} + +\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, + \c!textcolor=, + \c!synonymstyle=, + \c!synonymcolor=, + \c!headstyle=, + \c!headcolor=, + \c!location=\v!left, + \c!width=5em, + \c!state=\v!start] + +\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-syn.mkiv b/tex/context/base/strc-syn.mkiv new file mode 100644 index 000000000..65f517437 --- /dev/null +++ b/tex/context/base/strc-syn.mkiv @@ -0,0 +1,431 @@ +%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} + +% todo: add 'define only' option to descriptions, then add sorting (also based on key) +% and call to definition -> replaces this module + +\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} + +\unexpanded\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 + +\unexpanded\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] + +\unexpanded\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 + \setuvalue{#1}{\definesynonym[\v!no][#1]}% \name + \else + \ifthirdargument + \unexpanded\def#3##1{\doinsertsynonymmeaning{#1}{##1}}% \meaning + \fi + \setuvalue{#1}{\definesynonym[\v!yes][#1]}% \name + \fi + \getparameters[\??sm#1][\s!parent=\??sm,\s!multi={#2}]% + \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}{\placelistofsynonyms[#1]}% accepts extra argument + \setvalue{\e!complete\e!listof#2}{\completelistofsynonyms[#1]}} + +\unexpanded\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{\setuxvalue\currentsynonymtag{\noexpand\doinsertsynonym{\currentsynonym}{\currentsynonymtag}}}% + \fi + \endgroup} + +\def\registersynonym + {\dodoubleargument\doregistersynonym} + +\def\registersynonym[#1][#2]% + {\ctxlua{joblists.registerused("#1","#2")}} + +\unexpanded\def\doinsertsynonymmeaning#1#2% name tag + {\begingroup + \def\currentsynonym{#1}% + \dosetsynonymattributes\c!textstyle\c!textcolor + \synonymparameter\c!textcommand{\ctxlua{joblists.meaning("#1","#2")}}% + \endgroup} + +\unexpanded\def\doinsertsynonym#1#2% name tag + {\begingroup + \def\currentsynonym{#1}% + \dosetsynonymattributes\c!synonymstyle\c!synonymcolor + \synonymparameter\c!synonymcommand{\ctxlua{joblists.synonym("#1","#2")}}% + \normalexpanded{\endgroup\synonymparameter\c!next}} + +\unexpanded\def\placelistofsynonyms + {\dodoubleempty\doplacelistofsynonyms} + +\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!headstyle=\synonymparameter\c!textstyle, + \c!headcolor=\synonymparameter\c!textcolor, + \c!style=, + \c!color=. + #2]% + \startpacked + \ctxlua{joblists.process('#1',{ criterium = "\synonymparameter\c!criterium" })}% + \stoppacked + \endgroup} + +\def\completelistofsynonyms + {\dodoubleempty\docompletelistofsynonyms} + +\def\docompletelistofsynonyms[#1][#2]% expansion needed to avoid v! (due to french active !) + {\normalexpanded{\systemsuppliedchapter[#1]{\noexpand\headtext{\synonymparameter\s!single}}}% + \doplacelistofsynonyms[#1][#2]% + \page[\v!yes]} + +\let\startsynonymoutput \relax +\let\stopsynonymoutput \relax +\let\startsynonymsection\gobbleoneargument +\let\stopsynonymsection \relax + +\unexpanded\def\synonymentry#1#2#3#4% +% {\syndef{\dosetsynonymattributes\c!textstyle\c!textcolor#2}#3\par} +% {\startsyndef{#2}#3\stopsyndef} + {\syndef{#3}#4\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 + +\unexpanded\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] + +\unexpanded\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 + \unexpanded\def#3##1{\doinsertsort{#1}{##1}}% + \fi}% + \setuvalue{#1}{\definesort[\v!no][#1]}% + \else + \setuvalue{#1}{\definesort[\v!yes][#1]}% + \fi + \getparameters[\??so#1][\s!parent=\??so,\s!multi={#2}]% + \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}{\placelistofsorts[#1]}% + \setvalue{\e!complete\e!listof#2}{\completelistofsorts[#1]}} + +\unexpanded\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{\setuxvalue\currentsortingtag{\noexpand\doinsertsort{\currentsorting}{\currentsortingtag}}}% + \fi + \endgroup} + +\unexpanded\def\doinsertsort#1#2% name tag + {\begingroup + % no kap currently, of .. we need to map cap onto WORD + \edef\currentsorting{#1}% + \dosetsynonymattributes\c!style\c!color + \ctxlua{joblists.synonym("#1","#2")}% + \normalexpanded{\endgroup\sortingparameter\c!next}} + +\def\registersort + {\dodoubleargument\doregistersort} + +\def\registersort[#1][#2]% + {\ctxlua{joblists.registerused("#1","#2")}} + +% before after +% +% maybe just 'commandset' and then combine + +\unexpanded\def\placelistofsorts + {\dodoubleempty\placelistofsorts} + +\unexpanded\def\placelistofsorts[#1][#2]% NOG EEN RUWE VERSIE MAKEN ZONDER WITRUIMTE ETC ETC + {\begingroup + \def\currentsorting{#1}% + \getparameters[\??so#1][#2]% + \startpacked + \ctxlua{joblists.process('#1',{ criterium = "\sortingparameter\c!criterium" })}% + \stoppacked + \endgroup} + +\def\completelistofsorts + {\dodoubleemptydocompletelistofsorts} + +\def\docompletelistofsorts[#1][#2]% + {\normalexpanded{\systemsuppliedchapter[#1]{\noexpand\headtext{#2}}}% + \doplacelistofsorts[#1][#2]% + \page[\v!yes]} + +\let\startsortingoutput \relax +\let\stopsortingoutput \relax +\let\startsortingsection\gobbleoneargument +\let\stopsortingsection \relax + +\def\sortingentry#1#2#3#4% #4 is meaning but empty here + {\doifelsenothing{\sortingparameter\c!command} + {\begingroup\dosetsortingattributes\c!style\c!color#3\endgroup\par} % todo + {\sortingparameter\c!command{#1}{#2}{#3}}} + +%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] + +\setupsynonyms + [\v!unit] + [\c!synonymcommand=\dimension] + +\protect \endinput diff --git a/tex/context/base/strc-xml.mkiv b/tex/context/base/strc-xml.mkiv new file mode 100644 index 000000000..7a0099585 --- /dev/null +++ b/tex/context/base/strc-xml.mkiv @@ -0,0 +1,144 @@ +%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:internal:setup + \xmlsetsetup{\xmldocument}{ctx:genericentry} {xml:ctx:genericentry} + \xmlsetsetup{\xmldocument}{ctx:sectionentry} {xml:ctx:sectionentry} + \xmlsetsetup{\xmldocument}{ctx:registerentry}{xml:ctx:registerentry} +\stopxmlsetups + +\xmlregistersetup{xml:ctx:internal:setup} + +\startxmlsetups xml:ctx:genericentry + \xmlflush{#1} +\stopxmlsetups + +\startxmlsetups xml:ctx:sectionentry + \xmlflush{#1} +\stopxmlsetups + +\startxmlsetups xml:ctx:registerentry + \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 + +% example by thomas: + +\startbuffer[test] + +
+ <emph>MyTitle</emph> + + Hello world + +
+
+\stopbuffer + +\startxmlsetups xml:mysetups + \xmlsetsetup{\xmldocument}{auth|section|title|content|emph}{xml:*} +\stopxmlsetups + +\xmlregistersetup{xml:mysetups} + +\startxmlsetups xml:auth + \xmlflush{#1} +\stopxmlsetups + +\startxmlsetups xml:section + \xmlflush{#1}\par \midaligned{\hl[5]} +\stopxmlsetups + +\startxmlsetups xml:title + \section{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups xml:content + \xmlflush{#1}\par +\stopxmlsetups + +\startxmlsetups xml:emph + {\bgroup\em \xmlflush{#1}\egroup} +\stopxmlsetups + +\setuphead + [section] + [style=normal,number=no,expansion=yes,page=yes] + +\starttext + \xmlprocessbuffer{main}{test}{} +\stoptext diff --git a/tex/context/base/supp-ali.tex b/tex/context/base/supp-ali.tex new file mode 100644 index 000000000..8727efbb2 --- /dev/null +++ b/tex/context/base/supp-ali.tex @@ -0,0 +1,173 @@ +%D \module +%D [ file=supp-ali, +%D version=2000.04.17, +%D title=\CONTEXT\ Support Macros, +%D subtitle=Alignment, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 Yet undocumented. + +% 0 = centered +% 1 = left in before +% 2 = right in before +% 3 = left in after +% 4 = right in after + +\unprotect + +% \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 100,00 \NG 100,00 \NG 10,00 \NC\NR +% \NG 10\\ \NG 10\\ \NG 0,00 \NC\NR +% \NG 10 \NG 10 \NG 0,00 \NC\NR +% \NG 10 \NG 10 \NG 0,00 \NC\NR +% \stoptabulate + +\chardef\characteralignmentmode=4 +\chardef\characteralignmentslot=1 + +\newtoks\@@characteralignlst + +\let\afterassignwidth \!!zeropoint +\let\beforeassignwidth\!!zeropoint + +\def\alignmentcharacter{.} + +\let\alignmentclass\s!default % can be used to handle multiple mixed ones + +\def\setfirstpasscharacteralign + {\popcharacteralign + \expanded{\dosetfirstpasscharacteralign{\alignmentcharacter}}} + +\def\dosetfirstpasscharacteralign#1% + {\def\checkalignment##1% + {\popcharacteralign + \let\\\empty + \setbox\scratchbox\hbox{#1}% + \edef\characterassignwidth{\the\wd\scratchbox}% + \setbox\scratchbox\null + \docheckalignment##1#1\relax\relax + \scratchdimen-\wd\scratchbox + \setbox\scratchbox\hbox{\ignorespaces##1\unskip}% + \advance\scratchdimen \wd\scratchbox + \ifdim\scratchdimen>\beforeassignwidth\relax + \edef\beforeassignwidth{\the\scratchdimen}% + \fi + \ifdim\scratchdimen=\zeropoint + \setbox\scratchbox\hbox{\ignorespaces##1\unskip}% + \scratchdimen\wd\scratchbox + \ifcase\characteralignmentmode + % do nothing + \else\ifnum\characteralignmentmode<\plusthree + \advance\scratchdimen \characterassignwidth + \ifdim\scratchdimen>\beforeassignwidth\relax + \edef\beforeassignwidth{\the\scratchdimen}% + \fi + \else + \ifdim\scratchdimen>\afterassignwidth\relax + \edef\afterassignwidth{\the\scratchdimen}% + \fi + \fi\fi + \fi + \pushcharacteralign}% + \def\docheckalignment##1#1##2##3\relax + {\ifx##2\relax + \setbox\scratchbox\hbox{\ignorespaces##1\unskip}% + \ifdim\wd\scratchbox>\afterassignwidth + \edef\afterassignwidth{\the\wd\scratchbox}% + \fi + \else + \docheckalignment##2##3\relax\relax + \fi}} + +\def\setsecondpasscharacteralign + {\popcharacteralign + \expanded{\dosetsecondpasscharacteralign{\alignmentcharacter}}} + +\def\dosetsecondpasscharacteralign#1% + {\def\checkalignment##1% + {\popcharacteralign + \let\\\empty % beware, no grouping + \setbox\scratchbox\hbox{#1}% + \edef\characterassignwidth{\the\wd\scratchbox}% + \setbox\scratchbox\null + % new 12,34 vs 10\\ where 10 aligns on 12 if #1 = , + \ifcase\characteralignmentslot + \docheckalignment##1#1\relax\relax + \scratchdimen\wd\scratchbox + \setbox\scratchbox\hbox{\ignorespaces##1\unskip}% + \else + \def\\{#1}% + \expanded{\docheckalignment##1#1\relax\relax}% + \scratchdimen\wd\scratchbox + \setbox\scratchbox\hbox{\def\\{\hphantom{#1}}\ignorespaces##1\unskip}% + \fi + \noindent + \ifdim\scratchdimen=\wd\scratchbox + \ifcase\characteralignmentmode + \box\scratchbox + \else + \hbox + {\dontcomplain + \hbox to \beforeassignwidth + {\ifcase\characteralignmentmode\or + \box\scratchbox\hss + \or + \hss\box\scratchbox\hskip\characterassignwidth + \or + \hss\rlap{\box\scratchbox}% + \or + \hss\rlap{\hbox to \afterassignwidth{\hss\box\scratchbox}}% + \fi}% + \hskip\afterassignwidth}% + \fi + \else + \hbox + {\hbox to \beforeassignwidth + {\hss\box\scratchbox\hskip-\scratchdimen}% + \hskip\afterassignwidth}% + \fi}% + \def\docheckalignment##1#1##2##3\relax + {\ifx##2\relax + \setbox\scratchbox\hbox{\ignorespaces##1\unskip}% + \else + \docheckalignment##2##3\relax\relax + \fi}} + +% provide a means to use multiple alignments mixed + +\def\pushcharacteralign + {\ifundefined{@cac@\alignmentclass}% + \doglobal\appendetoks\noexpand\do{\alignmentclass}\to\@@characteralignlst + \fi + \setxvalue{@cac@\alignmentclass}{\noexpand\do + {\afterassignwidth}{\beforeassignwidth}{\alignmentcharacter}}} + +\def\popcharacteralign + {\def\do##1##2##3% + {\def\afterassignwidth {##1}% + \def\beforeassignwidth {##2}% + \def\alignmentcharacter{##3}}% + \executeifdefined{@cac@\alignmentclass}\donothing} + +\def\resetcharacteralign % does not work well nested + {\def\do##1{\global\letbeundefined{@cac@##1}}% global ! + \the\@@characteralignlst + \global\@@characteralignlst\emptytoks} + +\long\def\startcharacteralign#1\stopcharacteralign + {\bgroup + \setfirstpasscharacteralign #1% + \setsecondpasscharacteralign#1% + \egroup} + +\protect \endinput diff --git a/tex/context/base/supp-box.tex b/tex/context/base/supp-box.tex new file mode 100644 index 000000000..4c398973e --- /dev/null +++ b/tex/context/base/supp-box.tex @@ -0,0 +1,3126 @@ +%D \module +%D [ file=supp-box, +%D version=1995.10.10, +%D title=\CONTEXT\ Support Macros, +%D subtitle=Boxes, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This module implements some box manipulation macros. Some +%D are quite simple, some are more advanced and when understood +%D well, all can be of use. + +%D No longer generic, why bother. + +\writestatus{loading}{ConTeXt Support Macros / Boxes} + +\unprotect + +%D \macros +%D {strutdp,strutht,strutwd} +%D +%D The next shortcuts save memory and keying. The width is +%D normally zero points (if not, you're in trouble). These +%D shortcuts can be used like a dimension, opposite to the +%D core macros \type {\strutdepth} and alike, which are +%D values. + +\def\strutdp{\dp\strutbox} +\def\strutht{\ht\strutbox} +\def\strutwd{\wd\strutbox} + +%D \macros +%D {resetbox, emptybox} +%D +%D Let's start with an easy one. The next macro hides the +%D ugly \type {@} in \type {\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} +%D +%D Let's start with a rather simple declaration. Sometimes we +%D need to save the \TEX\ \DIMENSION\ \type{\prevdepth} and +%D append it later on. The name \type{\nextdepth} suits +%D this purpose well. + +\newdimen\nextdepth + +%D \macros +%D {smashbox, smashedbox} +%D +%D Smashing is introduced in \PLAIN\ \TEX, and stands for +%D reducing the dimensions of a box to zero. The most resolute +%D one is presented first. + +\def\smashbox#1% + {\wd#1\zeropoint + \ht#1\zeropoint + \dp#1\zeropoint} + +\def\smashboxed#1% + {\smashbox{#1}% + \box#1\relax} + +%D \macros +%D {hsmashbox,vsmashbox} +%D +%D Smashing can be used for overlaying boxes. Depending on +%D the mode, horizontal or vertical, one can use: + +\def\hsmashbox#1% + {\wd#1\zeropoint} + +\def\vsmashbox#1% + {\ht#1\zeropoint + \dp#1\zeropoint} + +%D The next implementation is less sensitive for spurious +%D spaces. + +\newcount\registercount + +\def\smashbox + {\afterassignment\dosmashbox\registercount} + +\def\dosmashbox + {\wd\registercount\zeropoint + \ht\registercount\zeropoint + \dp\registercount\zeropoint} + +\def\smashedbox + {\afterassignment\thesmashedbox\registercount} + +\def\thesmashedbox + {\dosmashbox + \box\registercount} + +\def\hsmashbox + {\afterassignment\dohsmashbox\registercount} + +\def\dohsmashbox + {\wd\registercount\zeropoint} + +\def\vsmashbox + {\afterassignment\dovsmashbox\registercount} + +\def\dovsmashbox + {\ht\registercount\zeropoint + \dp\registercount\zeropoint} + +%D \macros +%D {hsmash,vsmash, +%D hsmashed,vsmashed} +%D +%D While the previous macros expected a \BOX, the next act on a +%D content. They are some subtle differences betreen the smash +%D and smashed alternatives. The later ones reduce all +%D dimensions to zero. + +% Ok, but inefficient and/or catcode unsafe: +% +% \def\hsmash #1{\bgroup\setbox0=\normalhbox{#1}\hsmashbox0\box0\egroup} +% \def\vsmash #1{\bgroup\setbox0=\normalvbox{#1}\vsmashbox0\box0\egroup} +% \def\hsmashed#1{\bgroup\setbox0=\normalhbox{#1}\smashbox 0\box0\egroup} +% \def\vsmashed#1{\bgroup\setbox0=\normalvbox{#1}\smashbox 0\box0\egroup} +% +% Better, but a waste of tokens: +% +% \def\hsmash {\bgroup\dowithnextbox{\hsmashbox\nextbox\flushnextbox\egroup}\normalhbox} +% \def\vsmash {\bgroup\dowithnextbox{\vsmashbox\nextbox\flushnextbox\nextbox\egroup}\normalvbox} +% \def\hsmashed{\bgroup\dowithnextbox{\smashbox \nextbox\flushnextbox\nextbox\egroup}\normalhbox} +% \def\vsmashed{\bgroup\dowithnextbox{\smashbox \nextbox\flushnextbox\nextbox\egroup}\normalvbox} +% +% The best: + +\def\dosomesmash#1% (begin|end)group ipv (b|e)group ? + {\bgroup\dowithnextbox{#1\nextbox\flushnextbox\egroup}} + +\def\hsmash {\dosomesmash\hsmashbox\normalhbox} +\def\vsmash {\dosomesmash\vsmashbox\normalvbox} +\def\hsmashed{\dosomesmash\smashbox \normalhbox} +\def\vsmashed{\dosomesmash\smashbox \normalvbox} + +%D \macros +%D {smashedhbox,smashedvbox} +%D +%D Also handy (all dimensions zeroed): +%D +%D \starttyping +%D \smashedhbox to ... {...} +%D \smashedvbox to ... {...} +%D \stoptyping + +\def\dosmashedbox#1% + %{#1\bgroup\dowithnextbox{\smashbox\nextbox\flushnextbox\egroup}#1} + {#1\bgroup\dowithnextbox{\smashedbox\nextbox\egroup}#1} + +\def\smashedhbox{\dosmashedbox\hbox} +\def\smashedvbox{\dosmashedbox\vbox} + +%D \macros +%D {smash} +%D +%D This smash alternative takes an optional arg [whdtb] as +%D well as is potentially catcode safer. It is needed by the +%D math module (although the \type {\leavevmode} is not added +%D here). + +\def\smash + {\futurelet\nexttoken\dosmash} + +\def\dosmash + {\ifx\nexttoken[\@EA\dodosmash\else\@EA\donosmash\fi} + +\def\donosmash + {\dodosmash[hd]} + +\def\dodosmash[#1]% + {\edef\@@smash{#1}\futurelet\nexttoken\dododosmash} + +\def\dododosmash % if needed we can avoid the \next + {\ifmmode + \def\next##1{\mathpalette\mathsm@sh{##1}}% + \else\ifx\nexttoken\bgroup + \let\next\finsm@sh + \else + \def\next##1{\finsm@sh{##1}}% + \fi\fi + \next} + +\def\mathsm@sh#1#2% redefined plain macro + {\finsm@sh{$\mathsurround\zeropoint#1{#2}$}} + +\def\makesm@sh#1% redefined plain macro (handles t b h d w) + {\if#1w\nextboxwd\zeropoint\else + \if#1h\nextboxht\zeropoint\else + \if#1d\nextboxdp\zeropoint\else + \if#1t\nextboxht\zeropoint\else + \if#1b\nextboxdp\zeropoint\fi\fi\fi\fi\fi} + +\def\finsm@sh % redefined plain macro + {\dowithnextbox{\@EA\handletokens\@@smash\with\makesm@sh\flushnextbox}\normalhbox} + +%D \starttabulate[|l|l|] +%D \NC w \NC \ruledhbox{\smash [w]{This is some great smashing, isn't it?}} \NC \NR +%D \NC h \NC \ruledhbox{\smash [h]{This is some great smashing, isn't it?}} \NC \NR +%D \NC d \NC \ruledhbox{\smash [d]{This is some great smashing, isn't it?}} \NC \NR +%D \NC tb \NC \ruledhbox{\smash [tb]{This is some great smashing, isn't it?}} \NC \NR +%D \NC whd \NC \ruledhbox{\smash[whd]{This is some great smashing, isn't it?}} \NC \NR +%D \stoptabulate + +%D \macros +%D {phantom, hphantom, vphantom, mathstrut} +%D +%D The next implementation of \type {\phantom} cum suis does +%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\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. +%D We also take care of non||braced arguments. + +\def\ph@nt#1#2#3% + {\def\doph@nt + {\ifmmode + \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}% + \else + \def\nextph@nt####1{\makeph@nt#1#2#3{####1}}% + \fi\fi + \nextph@nt}% + \futurelet\nextph@nt\doph@nt} + +\def\makeph@nt#1#2#3% + {\begingroup + \dowithnextbox + {\setbox\scratchbox\null + \ht\scratchbox\ht#1% + \dp\scratchbox\dp#2% + \wd\scratchbox\wd#3% + \box\scratchbox + \endgroup} + \normalhbox} + +\let\finph@nt\undefined + +%D We also define plain's \type {\mathstrut}. + +\unexpanded\def\mathstrut{\vphantom{(}} + +%D \macros +%D {getboxheight} +%D +%D Although often needed, \TEX\ does not support arithmics +%D like: +%D +%D \starttyping +%D \dimen0 = \ht0 + \dp0 +%D \stoptyping +%D +%D so we implemented: +%D +%D \starttyping +%D \getboxheight ... \of \box... +%D \stoptyping +%D +%D For instance, +%D +%D \starttyping +%D \getboxheight \dimen0 \of \box0 +%D \getboxheight \someheight \of \box \tempbox +%D \stoptyping +%D +%D The implementation is rather stupid: +%D +%D \starttyping +%D \def\getboxheight#1\of#2\box#3% +%D {#1\ht#3\advance#1\dp#3\relax} +%D \stoptyping +%D +%D The next alternative is slightly more clever, since +%D it accepts \type {{12}} as well as \type {12} as box +%D number. + +\def\getboxheight#1\of#2\box#3% + {\def\next{#1\dimexpr\ht\registercount+\dp\registercount\relax}% + \afterassignment\next\registercount=#3} + +%D For a long time the following three macros were part of +%D the grid snapping core module, but it makes more sense to +%D have them here so that users can see them. +%D +%D \macros +%D {getnoflines, getroundednoflines, getrawnoflines} +%D +%D Het commando \type{\getnoflines} converteert een hoogte +%D (dimensie) in een aantal regels en kent dit toe aan +%D \type{\noflines}. +%D +%D \starttyping +%D \getnoflines{dimensie} +%D \stoptyping +%D +%D Er wordt gedeeld door \type{\openlineheight} en een hoogte +%D van~0pt komt overeen met 0~regels. The raw alternative +%D does not round. + +%D For a long time we had: +%D +%D \starttyping +%D \newcount\noflines +%D \newdimen\noflinesheight +%D +%D \def\dogetnoflines#1#2% +%D {\noflinesheight#2\relax +%D \ifzeropt\noflinesheight % \ifdim\noflinesheight=\zeropoint +%D \noflines\zerocount +%D \else +%D \divide\noflinesheight \openlineheight +%D \noflines\noflinesheight +%D #1\ifdim\noflines\openlineheight=#2\relax \else +%D \advance\noflines\ifdim#2>\zeropoint\plusone\else\minusone\fi +%D \fi\fi +%D \fi} +%D +%D \def\getnoflines {\dogetnoflines\iftrue } % compensated +%D \def\getrawnoflines{\dogetnoflines\iffalse} % no compensation +%D \stoptyping +%D +%D A more recent variant is: + +\ifx\roundingeps\undefined \newdimen\roundingeps \roundingeps=10sp \fi + +\newcount\noflines +\newdimen\noflinesheight + +% \def\getnoflines {\xdogetnoflines\plusone } % compensated +% \def\getroundednoflines{\xdogetnoflines\plustwo } % rounded +% \def\getrawnoflines {\xdogetnoflines\plusthree} % truncated +% +% \def\xdogetnoflines#1#2% +% {\noflinesheight#2\relax +% \ifzeropt\noflinesheight +% \noflines\zerocount +% \else\ifdim\noflinesheight>\zeropoint +% \ifcase#1\or +% \advance\noflinesheight-\roundingeps +% \divide\noflinesheight\openlineheight +% \noflines\noflinesheight +% \advance\noflines\plusone +% \or +% \advance\noflinesheight\roundingeps +% \divide\noflinesheight\openlineheight +% \noflines\noflinesheight +% \or +% \advance\noflinesheight\roundingeps +% \advance\noflinesheight.5\openlineheight +% \divide\noflinesheight\openlineheight +% \noflines\noflinesheight +% \fi +% \else +% \ifcase#1\or +% \advance\noflinesheight\roundingeps +% \divide\noflinesheight\openlineheight +% \noflines\noflinesheight +% \advance\noflines\minusone +% \or +% \advance\noflinesheight-\roundingeps +% \divide\noflinesheight\openlineheight +% \noflines\noflinesheight +% \or +% \advance\noflinesheight-\roundingeps +% \advance\noflinesheight-.5\openlineheight +% \divide\noflinesheight\openlineheight +% \noflines\noflinesheight +% \fi +% \fi\fi} + +\def\getnoflines#1% + {\noflinesheight#1\relax + \ifzeropt\noflinesheight + \noflines\zerocount + \else\ifdim\noflinesheight>\zeropoint + \advance\noflinesheight-\roundingeps + \divide\noflinesheight\openlineheight + \noflines\noflinesheight + \advance\noflines\plusone + \else + \advance\noflinesheight\roundingeps + \divide\noflinesheight\openlineheight + \noflines\noflinesheight + \advance\noflines\minusone + \fi\fi} + +\def\getroundednoflines#1% + {\noflinesheight#1\relax + \ifzeropt\noflinesheight + \noflines\zerocount + \else\ifdim\noflinesheight>\zeropoint + \advance\noflinesheight\roundingeps + \divide\noflinesheight\openlineheight + \noflines\noflinesheight + \else + \advance\noflinesheight-\roundingeps + \divide\noflinesheight\openlineheight + \noflines\noflinesheight + \fi\fi} + +\def\getrawnoflines#1% + {\noflinesheight#1\relax + \ifzeropt\noflinesheight + \noflines\zerocount + \else\ifdim\noflinesheight>\zeropoint + \advance\noflinesheight\roundingeps + \advance\noflinesheight.5\openlineheight + \divide\noflinesheight\openlineheight + \noflines\noflinesheight + \else + \advance\noflinesheight-\roundingeps + \advance\noflinesheight-.5\openlineheight + \divide\noflinesheight\openlineheight + \noflines\noflinesheight + \fi\fi} + +%D Let's proof that it works: +%D +%D \startbuffer +%D \scratchdimen\dimexpr(3pt) \getnoflines\scratchdimen 1=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10\lineheight) \getnoflines\scratchdimen 10=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10.1\lineheight) \getnoflines\scratchdimen 11=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10.5\lineheight) \getnoflines\scratchdimen 11=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10.9\lineheight) \getnoflines\scratchdimen 11=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10\lineheight+3pt) \getnoflines\scratchdimen 11=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10\lineheight+3sp) \getnoflines\scratchdimen 10=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10\lineheight-3sp) \getnoflines\scratchdimen 10=\the\noflines \endgraf +%D +%D \scratchdimen\dimexpr(3pt) \getrawnoflines\scratchdimen 0=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10\lineheight) \getrawnoflines\scratchdimen 10=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10.1\lineheight) \getrawnoflines\scratchdimen 10=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10.5\lineheight) \getrawnoflines\scratchdimen 11=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10.9\lineheight) \getrawnoflines\scratchdimen 11=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10\lineheight+3pt) \getrawnoflines\scratchdimen 10=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10\lineheight+3sp) \getrawnoflines\scratchdimen 10=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10\lineheight-3sp) \getrawnoflines\scratchdimen 10=\the\noflines \endgraf +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +%D \macros +%D {determinenoflines} +%D +%D The next macro determines the number of lines and +%D returns it it \type {\noflines}. The macro works +%D reasonable well as long as the content can be unboxed. +%D +%D \starttyping +%D \determinenoflines{test\\test} +%D \determinenoflines{\bfd test\\test} +%D \determinenoflines{\definedfont[Sans at 40pt]test\\test} +%D \stoptyping + +\def\determinenoflines % can be mkiv'd + {\bgroup + \forgetall + \let\crlf\endgraf + \let\\\endgraf + \dowithnextbox + {\beginofshapebox + \unvbox\nextbox + \endofshapebox + % \global\count1\zerocount + % \reshapebox{\global\advance\count1\plusone}% + % \egroup\noflines\count1 }% + \scratchcounter\zerocount + \reshapebox{\global\advance\scratchcounter\plusone}% + \expandafter\egroup\expandafter\noflines\the\scratchcounter\relax + }\vbox} + +%D \macros +%D {doiftextelse, doiftext} +%D +%D When \type {\doifelse} cum suis hopelessly fail, for +%D instance because we pass data, we can fall back on the next +%D macro: +%D +%D \starttyping +%D \doiftextelse {data} {then branch} {else branch} +%D \doiftext {data} {then branch} +%D \stoptyping + +\newif\iftrialtypesetting + +\def\doiftextelse#1% + {\bgroup + \setbox\scratchbox\normalhbox{\trialtypesettingtrue\ignorespaces#1\removeunwantedspaces}% + \ifzeropt\wd\scratchbox + \egroup\@EA\secondoftwoarguments + \else + \egroup\@EA\firstoftwoarguments + \fi} + +\def\doiftext#1#2% + {\doiftextelse{#1}{#2}\donothing} + +%D \macros +%D {dowithnextbox,nextbox} +%D +%D Sometimes we want a macro to grab a box and do something +%D on the content. One could pass an argument to a box, but +%D this can violate the specific \CATCODES\ of its content and +%D leads to unexpected results. The next macro treats the +%D following braced text as the content of a box and +%D manipulates it afterwards in a predefined way. +%D +%D The first argument specifies what to do with the content. +%D This content is available in \type{\nextbox}. The second +%D argument is one of \type{\hbox}, \type{\vbox} or +%D \type{\vtop}. The third argument must be grouped with +%D \type{\bgroup} and \type{\egroup}, \type{{...}} or can be +%D a \type{\box} specification. +%D +%D In \CONTEXT\ this macro is used for picking up a box and +%D treating it according to earlier specifications. We use for +%D instance something like: +%D +%D \starttyping +%D \def\getfloat% +%D {\def\handlefloat{...\flushnextbox...} +%D \dowithnextbox\handlefloat\normalvbox} +%D \stoptyping +%D +%D instead of: +%D +%D \starttyping +%D \def\getfloat#1% +%D {...#1...} +%D \stoptyping +%D +%D In this implementation the \type{\aftergroup} construction +%D is needed because \type{\afterassignment} is executed inside +%D the box. + +\ifx\nextbox\undefined \newbox\nextbox \fi + +\long\def\dowithnextbox#1% + {\long\def\dodowithnextbox{#1}% + \afterassignment\dododowithnextbox + \setbox\nextbox} + +\def\dododowithnextbox + {\aftergroup\dodowithnextbox} + +\long\def\dowithnextboxcs#1% + {\let\dodowithnextbox#1% + \afterassignment\dododowithnextbox + \setbox\nextbox} + +\def\dododowithnextbox + {\aftergroup\dodowithnextbox} + +%D So in fact we get: +%D +%D \starttyping +%D \setbox\nextbox { \aftergroup\dodowithnextbox ... } +%D \stoptyping +%D +%D or +%D +%D \starttyping +%D \setbox\nextbox { ... } \dodowithnextbox +%D \stoptyping +%D +%D A slower but more versatile implementation is: +%D +%D \starttyping +%D \long\def\dowithnextbox#1#2% +%D {\long\def\dodowithnextbox{#1}% +%D \ifx#2\normalhbox +%D \afterassignment\dododowithnextbox +%D \else\ifx#2\normalvbox +%D \afterassignment\dododowithnextbox +%D \else\ifx#2\normalvtop +%D \afterassignment\dododowithnextbox +%D \else\ifx#2\normalvcenter +%D \afterassignment\dododowithnextbox +%D \else +%D \afterassignment\dodowithnextbox +%D \fi\fi\fi\fi +%D \setbox\nextbox#2} +%D \stoptyping +%D +%D This alternative also accepts \type{\box0} and alike, but +%D we don't really need this functionality now. + +%D \macros +%D {nextboxht,nextboxwd,nextboxdp,flushnextbox} +%D +%D The next couple of shortcuts saves us memory as well as +%D \type {{}}'s in passing parameters. + +\def\nextboxht{\ht\nextbox} +\def\nextboxwd{\wd\nextbox} +\def\nextboxdp{\dp\nextbox} + +\def\flushnextbox{\box\nextbox} + +%D \macros +%D {dowithnextboxcontent} +%D +%D But, occasionally we do need to pass some local settings +%D without wanting to use additional grouping. Therefore we +%D provide: +%D +%D \starttyping +%D \dowithnextboxcontent{inside}{after}{box content} +%D \stoptyping +%D +%D {\em todo: Search source for potential usage!} + +\long\def\dowithnextboxcontent#1#2% inside, after + {\long\def\dodowithnextbox{#2}% + \def\dododowithnextbox{#1\aftergroup\dodowithnextbox}% + \afterassignment\dododowithnextbox + \setbox\nextbox} + +%D Now we can redefine \type {\dowithnextbox} as follows: +%D +%D \starttyping +%D \def\dowithnextbox{\dowithnextboxcontent\empty} +%D \stoptyping +%D +%D But since this macro is used often and since this implementation +%D is slower, we will not use that definition. + +% maybe: +% +% depending on the size of the action, about 10% faster +% +% \newtoks\nextboxtoks +% +% \def\dowithnextbox {\afterassignment\redowithnextbox\nextboxtoks} +% \def\redowithnextbox {\afterassignment\dododowithnextbox\setbox\nextbox} +% \def\dododowithnextbox{\aftergroup\dodowithnextbox} +% \def\dodowithnextbox {\the\nextboxtoks} +% +% \long\def\dowithnextboxcontent#1% #2% inside, after +% {\def\dododowithnextbox{#1\aftergroup\dodowithnextbox}% +% \afterassignment\redowithnextboxcontent\nextboxtoks} +% +% \def\redowithnextboxcontent +% {\afterassignment\dododowithnextbox\setbox\nextbox} + +%D \macros +%D {llap, rlap, tlap, blap, clap} +%D +%D Some well known friends, but we implement them our own +%D way. We want the macros to work in both math and text mode. + +\def\dodorlap{\normalhbox to \zeropoint{\flushnextbox\normalhss}\endgroup} +\def\dodollap{\normalhbox to \zeropoint{\normalhss\flushnextbox}\endgroup} +\def\dodoclap{\normalhbox to \zeropoint{\normalhss\flushnextbox\normalhss}\endgroup} + +\def\dorlap{\begingroup\dowithnextboxcs\dodorlap\normalhbox} +\def\dollap{\begingroup\dowithnextboxcs\dodollap\normalhbox} +\def\doclap{\begingroup\dowithnextboxcs\dodoclap\normalhbox} + +\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} +\unexpanded\def\clap{\mathortext\domathclap\doclap} + +\def\dodotlap{\normalvbox to \zeropoint{\normalvss\flushnextbox}\endgroup} +\def\dodoblap{\normalvbox to \zeropoint{\flushnextbox\normalvss}\endgroup} + +\def\tlap{\begingroup\dowithnextboxcs\dodotlap\normalvbox} +\def\blap{\begingroup\dowithnextboxcs\dodoblap\normalvbox} + +%D \macros +%D {beginofshapebox, +%D reshapebox, doreshapebox, +%D flushshapebox, +%D innerflushshapebox, +%D shapebox, +%D ifreshapingbox} +%D +%D The next utility macro originates from some linenumbering +%D mechanism. Due to \TEX's advanced way of typesetting +%D paragraphs, it's not easy to do things on a line||by||line +%D basis. This macro is able to reprocess a given box and can +%D act upon its vertical boxed components, such as lines. The +%D unwinding sequence in this macro is inspired by a \NTG\ +%D workshop of David Salomon in June 1992. +%D +%D First we have to grab the piece of text we want to act +%D upon. This is done by means of the duo macros: +%D +%D \starttyping +%D \beginofshapebox +%D a piece of text +%D \endofshapebox +%D \stoptyping +%D +%D When all texts is collected, we can call \type{\reshapebox} +%D and do something with it's vertical components. We can make +%D as much passes as needed. When we're done, the box can be +%D unloaded with \type{\flushshapebox}. The only condition in +%D this scheme is that \type{\reshapebox} must somehow unload +%D the \BOX\ \type{\shapebox}. +%D +%D An important aspect is that the content is unrolled +%D bottom||up. The next example illustrates this maybe +%D unexpected characteristic. +%D +%D \startbuffer +%D \beginofshapebox +%D \em \input tufte +%D \endofshapebox +%D +%D \newcounter\LineNumber +%D +%D \reshapebox +%D {\doglobal\increment\LineNumber +%D \normalhbox{\llap{\LineNumber\hskip2em}\box\shapebox}} +%D +%D \flushshapebox +%D \stopbuffer +%D +%D \typebuffer +%D +%D \getbuffer +%D +%D As we can see, when some kind of numbering is done, we have +%D to add a second pass. +%D +%D \startbuffer +%D \newcounter\LineNumber +%D \newcounter\NumberOfLines +%D +%D \reshapebox +%D {\doglobal\increment\NumberOfLines +%D \box\shapebox} +%D +%D \reshapebox +%D {\doglobal\increment\LineNumber +%D \normalhbox +%D {\llap{\LineNumber\ (\NumberOfLines)\hskip2em}% +%D \box\shapebox}% +%D \doglobal\decrement\NumberOfLines} +%D +%D \flushshapebox +%D \stopbuffer +%D +%D \typebuffer +%D +%D \getbuffer +%D +%D This example shows that the content of the box is still +%D available after flushing. Another feature is that only the +%D last reshaping counts. Multiple reshaping can be done by: +%D +%D \startbuffer +%D \beginofshapebox +%D \flushshapebox +%D \endofshapebox +%D +%D \reshapebox +%D {\doglobal\increment\LineNumber +%D \normalhbox{\llap{$\star$\hskip1em}\box\shapebox}% +%D \doglobal\decrement\NumberOfLines} +%D +%D \flushshapebox +%D \stopbuffer +%D +%D \typebuffer +%D +%D \getbuffer +%D +%D The macros are surprisingly easy to follow and in fact +%D introduce no new concepts. Nearly all books on \TEX\ show +%D similar solutions for unwinding \BOXES. +%D +%D Some macros, like footnote ones, can be sensitive for +%D reshaping, which can result in an endless loop. We +%D therefore offer: +%D +%D \starttyping +%D \ifreshapingbox +%D \stoptyping +%D +%D Some \CONTEXT\ commands are protected this way. Anyhow, +%D reshaping is aborted after 100 dead cycles. +%D +%D By the way, changing the height and depth of \BOX\ +%D \type{\shapebox} results in bad spacing. This means that +%D for instance linenumbers etc. should be given zero height +%D and depth before being lapped into the margin. The +%D previous examples ignore this side effect, but beware! + +\newif \ifsomeshapeleft +\newif \ifreshapingbox + +\newbox \shapebox +\newcount \shapepenalty +\newdimen \shapekern +\newskip \shapeskip + +\newbox \newshapebox +\newbox \oldshapebox + +\newcount \shapecounter + +\newevery \everyshapebox \relax + +\def\shapesignal{.12345678pt} % or 12345sp + +% todo: in etex lastnode + +\def\reshapebox#1% + {\doreshapebox + {#1}% + {\penalty\shapepenalty}% + {\kern \shapekern }% + {\vskip \shapeskip }} + +\newbox\tmpshapebox + +\newif\ifreshapingfailed % may save redundant runs + +\def\doreshapebox#1#2#3#4% \shapebox, \shapepenalty, \shapekern, \shapeskip + {\global\reshapingfailedfalse + \ifzeropt\ht\oldshapebox % \ifdim\ht\oldshapebox=\zeropoint + \setbox\newshapebox\normalvbox{}% + \else + \setbox\newshapebox\normalvbox + {\unvcopy\oldshapebox + \resetbox\newshapebox + \shapecounter\zerocount + \doloop{\dodoreshapebox{#1}{#2}{#3}{#4}}}% + \setbox\newshapebox\box\tmpshapebox + \fi} + +\ifx\originalshapebox\undefined \let\originalshapebox\oldshapebox \fi + +% %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 % compensates for the signal + {\global\setbox\tmpshapebox\vbox{\vskip-\lineheight\unvcopy\oldshapebox}} + +\def\dodoreshapebox#1#2#3#4% \shapebox, \shapepenalty, \shapekern, \shapeskip + {\ifnum\lastnodetype=\@@gluenode + \shapeskip\lastskip + \global\setbox\tmpshapebox\normalvbox{#4\unvbox\tmpshapebox}% + \unskip + \else\ifnum\lastnodetype=\@@kernnode + \shapekern\lastkern + \global\setbox\tmpshapebox\normalvbox{#3\unvbox\tmpshapebox}% + \unkern + \else\ifnum\lastnodetype=\@@penaltynode + \shapepenalty\lastpenalty + \global\setbox\tmpshapebox\normalvbox{#2\unvbox\tmpshapebox}% + \unpenalty + \else\ifnum\lastnodetype<\zeropoint + \exitloop + \else + \setbox\shapebox\lastbox + \ifvoid\shapebox + \else\ifdim\wd\shapebox=\shapesignal\relax + \exitloop + \else + \shapecounter\zerocount + \global\setbox\tmpshapebox\normalvbox{#1\unvbox\tmpshapebox}% + \fi\fi + \fi\fi\fi\fi + \ifnum\shapecounter>100 % can be less + \global\reshapingfailedtrue + \message{!!forced exit from shapebox \the\lastnodetype !!}% + \restoreshapebox + \exitloop + \else + \advance\shapecounter \plusone + \fi} + +\def\beginofshapebox + {\setbox\oldshapebox\normalvbox + \bgroup + \reshapingboxtrue + \the\everyshapebox + \insertshapesignal} + +\def\endofshapebox + {\endgraf + \egroup} + +\let\beginshapebox\beginofshapebox +\let\endshapebox \endofshapebox + +\def\flushshapebox + {\bgroup + \ifzeropt\ht\newshapebox % \ifdim\ht\newshapebox=\zeropoint + \else + % make \prevdepth legal + % \par before the next \vskip gives far worse results + \ifdim\parskip>\zeropoint\vskip\parskip\else\par\fi + % and take a look + \ifdim\prevdepth=-\thousandpoint + \prevdepth\zeropoint + \fi + \ifdim\prevdepth<\zeropoint\relax + % something like a line or a signal or ... + \donetrue + \else\ifinner + % not watertight and not ok + \donefalse + \else\ifdim\pagegoal=\maxdimen + \donetrue + \else + % give the previous line a normal depth + \donetrue + {\forgeteverypar\verticalstrut}\nobreak + \kern-\struttotal % geen \vskip + \kern-\parskip + % \vskip-\strutdp + \fi\fi\fi + \scratchdimen\dp\newshapebox + \unvbox\newshapebox + % \prevdepth=0pt and \dp\newshapebox depend on last line + \kern-\scratchdimen % ?? + % now \prevdepth=0pt + \ifdone + \kern\strutdp + \prevdepth\strutdp + \fi + \fi + \egroup} + +%D In real inner situations we can use: +%D +%D \starttyping +%D \flushinnershapebox +%D \stoptyping +%D +%D This one is used in \type{\framed}. + +% The kern fails on for instance: +% +% \omlijnd[offset=0pt,hoogte=8mm,uitlijnen={rechts,laho}]{\bfa test} + +\def\innerflushshapebox + {\ifzeropt\ht\newshapebox \else + \unvcopy\newshapebox\relax % unvcopy ! else spacing problem + % \kern-\dp\newshapebox\relax + \fi} + +%D For absolute control, one can use \type{\doreshapebox} +%D directly. This macro takes four arguments, that take care +%D of: +%D +%D \startitemize[n,packed] +%D \item \type{\shapebox} +%D \item \type{\shapepenalty} +%D \item \type{\shapekern} +%D \item \type{\shapeskip} +%D \stopitemize + +%D \macros +%D {shapedhbox} +%D +%D When constructing a new box, using the content of \type +%D {\shapebox}, one can best use \type {\shapedhbox} instead +%D of \type {\normalhbox}, since it manages the height and depth of +%D the line. + +% \def\shapedhbox +% {\dowithnextbox +% {\nextboxht\zeropoint +% \nextboxdp\zeropoint +% \flushnextbox} +% \normalhbox} + +\def\shapedhbox % lines with non strutted dimensions have + {\expanded{\dowithnextbox % interlineskip so if we want the original + {\nextboxht\the\ht\shapebox % spacing, we need to preserve the original + \nextboxdp\the\dp\shapebox % height and depth which is definitely + \noexpand\flushnextbox}} % needed if we apply struts to the 'new' + \normalhbox} % box or do something that changed ist size + +%D \macros +%D {hyphenatedword, +%D hyphenatedpar, +%D hyphenatedfile, +%D dohyphenateword} +%D +%D The next one is a tricky one. \PLAIN\ \TEX\ provides +%D \type{\showhyphens} for showing macros on the terminal. When +%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. 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 +%D \starttyping +%D \dohyphenateword {n} {pre} {word} +%D \stoptyping +%D +%D The next examples tell more than lots of words: +%D +%D \startbuffer +%D \dohyphenateword{0} {} {dohyphenatedword} +%D \dohyphenateword{1} {...} {dohyphenatedword} +%D \dohyphenateword{2} {...} {dohyphenatedword} +%D \stopbuffer +%D +%D \typebuffer +%D +%D Here, \type{\hyphenatedword{dohyphenatedword}} is the +%D shorter alternative for the first line. +%D +%D \startvoorbeeld +%D \getbuffer +%D \stopvoorbeeld +%D +%D These macros are slow but effective and not that hard to +%D program at all. + +\ifx\scantokens\undefined \let\scantokens\firstofoneargument \fi + +\def\dohyphenateword#1#2#3% + {\bgroup + \setbox\scratchbox\normalhbox + {\dontcomplain + \nopenalties % \widowpenalty \clubpenalty \brokenpenalty \doublehyphendemerits \finalhyphendemerits \adjdemerits + \hyphenpenalty \zerocount + \exhyphenpenalty\zerocount + \setbox0\normalvbox + {\hsize\zeropoint + \hskip\zeropoint\relax % really needed + \ifnum#1<\zeropoint + \obeyspaces + \obeylines + \def\obeyedspace{\hskip\zeropoint\hbox to \onepoint{}\hskip\zeropoint}% + \let\obeyedline \obeyedspace + \ifcase-#1\or + \def\next{#3\relax}\scantokens\expandafter{\next}% relax catches lookahead problem + % also ok: \scantokens{#3}% % as in \hyphenatedword{spanish|?|} + \or + \readfile{#3}\donothing\donothing + \else + #3% + \fi + \else + #3% + \fi}% + \ifnum#1>\zerocount + \dorecurse{#1} + {\setbox2\normalhbox + {\splittopskip\openstrutheight + \vsplit0 to \baselineskip}}% + #2% + \fi + \doloop + {\setbox2\normalhbox + {\splittopskip\openstrutheight + \vsplit0 to \baselineskip}% + \setbox2\normalhbox + {\unhbox2 + \setbox2\lastbox + \normalvbox + {\unvbox2 + \setbox2\lastbox + \normalhbox{\unhbox2}}}% + \ifnum#1<\zeropoint\ifdim\wd2=\onepoint\space\else\box2\allowbreak\fi\else\box2\fi + \ifzeropt\ht0 \exitloop\fi}% % \ifdim\ht0=\zeropoint\exitloop\fi}% + \removeunwantedspaces}% + \ifnum#1>\zerocount + \ht\scratchbox\strutht + \dp\scratchbox\strutdp + \box\scratchbox + \else + \unhbox\scratchbox + \fi + \egroup} + +\def\hyphenatedword{\dohyphenateword\zerocount\empty} +\def\hyphenatedpar {\dohyphenateword\minusone \empty} +\def\hyphenatedfile{\dohyphenateword{-2}\empty} + +%D You may want to give the following call a try: +%D +%D \starttyping +%D \hyphenatedpar{\readfile{zapf}{}{}}\endgraf +%D \stoptyping + +%D \macros +%D {processtokens} +%D +%D We fully agree with (most) typographers that inter||letter +%D spacing is only permitted in fancy titles, we provide a +%D macro that can be used to do so. Because this is +%D (definitely and fortunately) no feature of \TEX, we have to +%D step through the token list ourselves. +%D +%D \starttyping +%D \processtokens {before} {between} {after} {space} {tokens} +%D \stoptyping +%D +%D An example of a call is: +%D +%D \startbuffer +%D \processtokens {[} {+} {]} {\space} {hello world} +%D \stopbuffer +%D +%D \typebuffer +%D +%D This results in: +%D +%D \getbuffer +%D +%D The list of tokens may contain spaces, while \type{\\}, +%D \type{{}} and \type{\ } are handled as space too. + +\def\dodoprocesstokens + {\ifx\nextprocessedtoken\lastcharacter + \after + \let\nextprocessedtoken\relax + \else\ifx\nextprocessedtoken\bgroup + \def\nextprocessedtoken + {\dowithnextbox + {\before{\copy\nextbox}% \before can use nextbox several times + \let\before\between + \doprocesstokens} + \hbox\bgroup}% + \else + \expandafter\if\space\nextprocessedtoken + \after\white + \let\before\savedbefore + \else + \before\nextprocessedtoken + \let\before\between + \fi + \let\nextprocessedtoken\doprocesstokens + \fi\fi + \nextprocessedtoken} + +\def\doprocesstokens% the space after = is essential + {\afterassignment\dodoprocesstokens\let\nextprocessedtoken= } + +\def\processtokens#1#2#3#4#5% + {\begingroup + \def\lastcharacter{\lastcharacter}% + \def\space{ }% + \let\\=\space + \def\before {#1}% + \def\between{#2}% + \def\after {#3}% + \def\white {#4}% + \let\savedbefore\before + \doprocesstokens#5\lastcharacter + \endgroup} + +%D \macros +%D {doboundtext} +%D +%D Sometimes there is not enough room to show the complete +%D (line of) text. In such a situation we can strip of some +%D characters by using \type{\doboundtext}. When the text is +%D wider than the given width, it's split and the third +%D argument is appended. When the text to be checked is packed +%D in a command, we'll have to use \type{\expandafter}. +%D +%D \starttyping +%D \doboundtext{a very, probably to long, text}{3cm}{...} +%D \stoptyping +%D +%D When calculating the room needed, we take the width of the +%D third argument into account, which leads to a bit more +%D complex macro than needed at first sight. + +% \def\dodoboundtext#1% +% {\setbox0=\normalhbox{\unhcopy0 #1}% +% \ifdim\wd0>\dimen0 +% \let\dodoboundtext=\gobbleoneargument +% \else +% #1\relax +% \fi} +% +% \def\doboundtext#1#2#3% +% {\normalhbox +% {\setbox0=\normalhbox{#1}% +% \dimen0=#2\relax +% \ifdim\wd0>\dimen0 +% \setbox2=\normalhbox{#3}% +% \advance\dimen0 by -\wd2 +% \setbox0=\normalhbox{}% +% \processtokens +% {\dodoboundtext} +% {\dodoboundtext} +% {} +% {\space} +% {#1}% +% \box2 +% \else +% \box0 +% \fi}} + +\def\dodoboundtext#1% + {\setbox0\normalhbox{#1}% + \advance\scratchdimen -\wd0 + \ifdim\scratchdimen>\zeropoint\relax#1\fi}% + +\def\doboundtext#1#2#3% + {\normalhbox + {\setbox\scratchbox\normalhbox{#1}% + \scratchdimen#2\relax + \ifdim\wd\scratchbox>\scratchdimen + \setbox\scratchbox\normalhbox{#3}% + \advance\scratchdimen -\wd\scratchbox + \handletokens#1\with\dodoboundtext + \fi + \box\scratchbox}} + +%D \macros +%D {limitatetext} +%D +%D A bit more beautiful alternative for the previous command is +%D the next one. This command is more robust because we let +%D \TEX\ do most of the job. The previous command works better +%D on text that cannot be hyphenated. +%D +%D \starttyping +%D \limitatetext {text} {width} {sentinel} +%D \limitatetext {text} {-width} {prelude} +%D \stoptyping +%D +%D When no width is given, the whole text comes available. The +%D sentinel is optional. This is about the third version. + +\ifx\fakecompoundhyphen\undefined \let\fakecompoundhyphen\relax \fi +\ifx\veryraggedright \undefined \def\veryraggedright{\raggedright} \fi + +%D The simple alternative is as follows: +%D +%D \starttyping +%D \unexpanded\def\limitatetext% +%D {\bgroup % evt \setstrut +%D \forgetall +%D \fakecompoundhyphen % dangerous ! ! ! ! ! ! ! ! ! +%D \dowithnextbox\dolimitatetext\normalhbox} +%D +%D \def\dolimitatetext#1#2% +%D {\doifelsenothing{#1} +%D {\unhbox\nextbox} +%D {\widowpenalty=0 +%D \clubpenalty=0 +%D \scratchdimen=#1\relax +%D \ifdim\nextboxwd>\scratchdimen +%D \setbox\scratchbox=\normalhbox{ #2}% +%D \advance\scratchdimen by -\wd\scratchbox +%D \setbox\nextbox=\normalvbox +%D {\hsize=\scratchdimen +%D \hfuzz\maxdimen +%D \veryraggedright +%D \strut\unhcopy\nextbox}% +%D \ifdim\nextboxht>\strutht \else +%D \setbox\scratchbox\null % overfull and not split +%D \fi +%D \setbox\nextbox=\normalvbox % if omitted: missing brace reported +%D {\splittopskip=\openstrutheight +%D \setbox\nextbox=\vsplit\nextbox to \strutht +%D \unvbox\nextbox +%D \setbox\nextbox=\lastbox +%D \global\setbox1=\normalhbox +%D {\unhbox\nextbox\unskip\kern\zeropoint\box\scratchbox\unskip}}% +%D \unhbox1 +%D \else +%D \unhbox\nextbox +%D \fi}% +%D \egroup} +%D \stoptyping +%D +%D The next alternative accepts a negative width. A negative +%D value crops the beginning. The macro thereby becomes less +%D readable, which is why we kept the original here too. + +\unexpanded\def\limitatetext + {\bgroup % evt \setstrut + \forgetall % otherwise indentation and so + %\def\limitatetext##1##2##3{##1}% \def ! + \let\limitatetext\firstofthreearguments + \fakecompoundhyphen % dangerous ! ! ! ! ! ! ! ! ! + \dowithnextboxcs\dolimitatetext\normalhbox} + +\def\dolimitatetext#1#2% + {\doifelsenothing{#1} + {\unhbox\nextbox} + {\nopenalties + \scratchdimen#1\relax + \ifdim\scratchdimen<\zeropoint\relax % we'll take the last line + \donefalse + \scratchdimen-\scratchdimen + \else + \donetrue + \fi + \ifdim\nextboxwd>\scratchdimen + \setbox\scratchbox\normalhbox{\ifdone\space#2\else#2\space\fi}% + \advance\scratchdimen -\wd\scratchbox + \setbox0\flushnextbox + \setbox\nextbox\normalvbox + {\hsize\scratchdimen + \hfuzz\maxdimen + \veryraggedright + \strut + \ifdone \else + \parfillskip\zeropoint + \rightskip\zeropoint + \hskip\zeropoint \!!plus 1\!!fill % \hsize + \fi + \unhcopy0}% + \ifdim\nextboxht>\strutht + \setbox\nextbox\normalvbox % if omitted: missing brace reported + {\splittopskip\openstrutheight + \ifdone + \setbox\nextbox\vsplit\nextbox to \strutht + \else + \doloop + {\setbox0\vsplit\nextbox to \strutht + \ifdim\nextboxht>\strutht \else \exitloop \fi}% + \fi + \unvbox\nextbox + \setbox\nextbox\lastbox + \global\setbox1\normalhbox + {\ifdone + \unhbox\nextbox\unskip\kern\zeropoint\box\scratchbox + \else + \box\scratchbox\unhbox\nextbox + \fi + \unskip}}% + \unhbox1 + \else + \unhbox0 + \fi + \else + \unhbox\nextbox + \fi}% + \egroup} + +%D We can also limit a text with more control: +%D +%D \startbuffer +%D \limitatetext {\input tufte } {2cm,5mm} {\unknown} +%D \limitatetext {ton en hans} {2cm,5mm} {\unknown} +%D \limitatetext {ton en hans zijn eikels} {2cm,5mm} {\unknown} +%D \limitatetext {ton} {2cm,5mm} {\unknown} +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D We build this feature on top of the previous macro. + +\let\normallimitatetext\limitatetext + +\def\speciallimitatetext#1#2#3#4% text left right placeholder + {%\dontleavehmode + \bgroup + %\def\speciallimitatetext##1##2##3##4{##1}% \def ! + \let\speciallimitatetext\firstoffourarguments + \setbox0\normalhbox + {\nohyphens + \normallimitatetext{#1}{+#2}{}#4% + \normallimitatetext{#1}{-#3}{}}% + \setbox2\normalhbox + {#1}% + \ifdim\wd2<\wd0 #1\else\unhbox0\fi + \egroup} + +\def\limitatetext#1#2#3% \expanded added 2003/01/16 + {\expanded{\beforesplitstring#2}\at,\to\leftlimit + \expanded{\aftersplitstring #2}\at,\to\rightlimit + \ifx\rightlimit\empty + \normallimitatetext {#1}\leftlimit {#3}% + \else + \speciallimitatetext{#1}\leftlimit\rightlimit{#3}% + \fi} + +%D Undocumented bonus (see wiki): +%D +%D \starttyping +%D \limitatefirstline{\input tufte\relax}{10cm}{\unknown} +%D \stoptyping + +\def\limitatefirstline#1#2#3% + {\hbox\bgroup\strut + \setbox\scratchbox\hbox{\begstrut#1\endstrut}% + \ifdim\wd\scratchbox>#2\relax + \setbox\scratchbox\hbox{#3}% + \hsize#2\relax + \advance\hsize-\wd\scratchbox + \setbox\scratchbox\vbox{\forgetall\veryraggedright#1}% + \setbox\scratchbox\vsplit\scratchbox to \lineheight + \vbox + {\unvbox\scratchbox + \global\setbox\plusone\lastbox + \global\setbox\plusone\hbox{\strut\unhbox\plusone}% + \hbox % to #2 + {\ifx\clip\undefined + \box\plusone + \else\ifdim\wd\plusone>\hsize + \lower\strutdepth\hbox{\clip[\c!width=\hsize,\c!height=\lineheight]{\hbox{\raise\strutdepth\box\plusone}}}% + \else + \box\plusone + \fi\fi + \removeunwantedspaces#3}}% \removeunwantedspaces\hss#3}}% + \else + #1% + \fi + \egroup} + +%D \macros +%D {processisolatedwords, +%D betweenisolatedwords,nothingbetweenisolatedwords} +%D +%D References are often made up of one word or a combination +%D of tightly connected words. The typeset text {\bf +%D chapter~5} is for instance the results of the character +%D sequence: +%D +%D \starttyping +%D The typeset text \in{chapter}[texniques] is for instance +%D \stoptyping +%D +%D When such words are made active in interactive texts, the +%D combination cannot longer be hyphenated. Normally this is no +%D problem, because \TEX\ tries to prevent hyphenation as best +%D as can. +%D +%D Sometimes however we need a few more words to make things +%D clear, like when we want to refer to {\bf \TEX\ by Topic}. +%D The macros that are responsible for typesetting hyperlinks, +%D take care of such sub||sentences by breaking them up in +%D words. Long ago we processed words using the space as a +%D separator, but the more advanced our interactive text became, +%D the more we needed a robust solution. Well, here it is and +%D it called as: +%D +%D \starttyping +%D \processisolatedwords{some words}\someaction +%D \stoptyping +%D +%D The second argument \type{someactions} handles the +%D individual words, like in: +%D +%D \startbuffer +%D \processisolatedwords{some more words} \ruledhbox \par +%D \processisolatedwords{and some $x + y = z$ math} \ruledhbox \par +%D \processisolatedwords{and a \normalhbox{$x + y = z$}} \ruledhbox \par +%D \stopbuffer +%D +%D \typebuffer +%D +%D which let the words turn up as: +%D +%D \startvoorbeeld +%D \getbuffer +%D \stopvoorbeeld +%D +%D The macro has been made a bit more clever than needed at +%D first sight. This is due to the fact that we don't want to +%D generate more overhead in terms of interactive commands than +%D needed. +%D +%D \startbuffer +%D \processisolatedwords{see this \ruledhskip1em} \ruledhbox +%D \processisolatedwords{and \ruledhskip1em this one} \ruledhbox +%D \stopbuffer +%D +%D \typebuffer +%D +%D becomes: +%D +%D \startvoorbeeld +%D \startlines +%D \getbuffer +%D \stoplines +%D \stopvoorbeeld +%D +%D Single word arguments are treated without further +%D processing. This was needed because this command is used in +%D the \type{\goto} command, to which we sometimes pass very +%D strange and|/|or complicated arguments or simply boxes +%D whose dimensions are to be left intact. +%D +%D First we build a \type{\normalhbox}. This enables us to save the +%D last skip. Next we fill a \type{\normalvbox} without hyphenating +%D words. After we've tested if there is more than one word, we +%D start processing the individual lines (words). We need some +%D splitting, packing and unpacking to get the spacing and +%D dimensions right. +%D +%D Normally the isolated words are separated by space, but +%D one can overrule this separator by changing the next macros. +%D +%D When needed, spacing can be suppressed by \type +%D {\nothingbetweenisolatedwords}. + +\newif\ifisolatedwords % public, e.g. used in core-ref + +\def\betweenisolatedwords + {\hskip\currentspaceskip} + +%D In order to prevent problems with nested isolated words, we +%D do process them, but only split at the outermost level. + +\newskip\isolatedlastskip + +\chardef\isolatedwordsmode=0 % no nesting + +\def\processisolatedwords#1#2% todo: vbox ipv hbox ivm afbreken! + {\bgroup % todo: doloop + \fakecompoundhyphen + \dontcomplain + \forgetall + \nopenalties + \ifcase\isolatedwordsmode + \def\processisolatedwords##1##2{##2{##1}}% we split only once + \fi + \global\let\localbetweenisolatedwords\betweenisolatedwords + \setbox0\normalhbox % we default to spaces, but from inside out + {\normallanguage\minusone % needed for mkiv + \ignorespaces#1% \localbetweenisolatedwords can be overruled + \global\isolatedlastskip\lastskip}% + \setbox2\normalvbox + {%\hyphenpenalty10000 % this one fails in \url breaking, + \lefthyphenmin\maxcard % but this trick works ok, due to them + \righthyphenmin\maxcard % total>63, when no hyphenation is done + \hsize\zeropoint + \unhcopy0}% == #1 + \ifdim\ht0=\ht2 + \isolatedwordsfalse + #2{\unhbox0}% == #2{#1} % was \unhcopy0 + \else + \isolatedwordstrue + \setbox0\normalhbox + {\ignorespaces + \loop + \setbox4\normalhbox + {\splittopskip\openstrutheight + \vsplit2 to \baselineskip}% + \normalhbox + {\unhbox4\unskip % recently added + \setbox4\lastbox + \normalvbox % outer \normalhbox needed + {\unvbox4 % for nested use + \setbox4\lastbox + \normalhbox{#2{\normalhbox + {\unhbox4 + \unskip\unpenalty % remove end of line stuff + \global\dimen1\lastkern}}}}}% + \ifdim\ht2>\zeropoint\relax + \ifdim\dimen1=\compoundbreakpoint + \allowbreak + \else + \localbetweenisolatedwords + \fi + \repeat + \unskip}% + \unhbox0\unskip + \ifzeropt\isolatedlastskip\else % added % \ifdim\isolatedlastskip=\zeropoint\else % added + \hskip\isolatedlastskip + \fi + \fi + \egroup} + +%D One can use the next macro to change the intersplit +%D material. An example can be found in the \type {\url} +%D macro. The innermost setting is used. In the url case, it +%D means that either very small spaces are used or no spaces +%D at all. So, the innermost settings are used, while the +%D outermost split takes place. + +\def\setbetweenisolatedwords#1% + {\gdef\localbetweenisolatedwords{#1}} + +%D \macros +%D {sbox} +%D +%D This is a rather strange command. It grabs some box content +%D and and limits the size to the height and depth of a +%D \type{\strut}. The resulting bottom||alligned box can be used +%D aside other ones, without disturbing the normal baseline +%D distance. +%D +%D \startbuffer +%D \ruledhbox to .5\hsize{\sbox{eerste\par tweede \par derde}} +%D \stopbuffer +%D +%D \typebuffer +%D +%D Shows up as: +%D +%D \startvoorbeeld +%D \vskip3\baselineskip +%D \getbuffer +%D \stopvoorbeeld +%D +%D Before displaying the result we added some skip, otherwise +%D the first two lines would have ended up in the text. This +%D macro can be useful when building complicated menus, headers +%D and footers and|/|or margin material. + +\def\sbox% in handleiding, voorbeeld \inleft{xx} \extern.. + {\normalvbox\bgroup % new ! ! ! + \dowithnextbox + {\setbox\scratchbox\normalhbox + {\strut + \nextboxdp\zeropoint + \lower\strutdepth\flushnextbox}% + \dp\scratchbox\strutdepth + \ht\scratchbox\strutheight + \box\scratchbox + \egroup}% + \normalvbox} + +%D \macros +%D {struttedbox} +%D +%D This boxing macro limits the height and depth to those of +%D a strut. + +\def\struttedbox + {\normalhbox\bgroup % new ! ! ! + \dowithnextbox + {\nextboxdp\strutdepth + \nextboxht\strutheight + \flushnextbox + \egroup}% + \normalhbox} + +%D \macros +%D {topskippedbox} +%D +%D This macro compensates the difference between the topskip +%D and strutheight. Watch how we preserve the depth when it +%D equals strutdepth. + +\def\topskippedbox + {\normalhbox\bgroup + \dowithnextbox + {\edef\next + {\ifdim\strutdepth=\nextboxdp\nextboxdp\the\nextboxdp\fi}% + \lower\topskip\normalhbox{\raise\strutheight\flushnextbox}% + \next + \egroup}% + \normalhbox} + +%D \macros +%D {centeredbox, centerednextbox} +%D +%D Here is another strange one. This one offers a sort of overlay +%D with positive or negative offsets. This command can be used +%D in well defined areas where no offset options are available. +%D We first used it when building a button inside the margin +%D footer, where the button should have a horizontal offset and +%D should be centered with respect to the surrounding box. The +%D last of the three examples we show below says: +%D +%D \starttyping +%D \vsize=3cm +%D \hsize=3cm +%D \ruledvbox to \vsize +%D {\centeredbox height .5cm width -1cm +%D {\vrule width \hsize height \vsize}}} +%D \stoptyping +%D +%D Here the \type{\ruledvbox} just shows the surrounding box +%D and \type{\vrule} is used to show the centered box. +%D +%D \def\AnExample#1#2% +%D {\vsize=3cm +%D \hsize=3cm +%D \ruledvbox to \vsize +%D {\centeredbox height #1 width #2 +%D {\color[green]{\vrule width \hsize height \vsize}}}} +%D +%D \startlinecorrection +%D \startcombination[3*1] +%D {\AnExample {-1cm} {.5cm}} {} +%D {\AnExample {.5cm} {-1cm}} {} +%D {\AnExample {-1cm} {-.5cm}} {} +%D \stopcombination +%D \stoplinecorrection +%D +%D This command takes two optional arguments: \type{width} and +%D \type{height}. Observing readers can see that we use \TEX's +%D own scanner for grabbing these arguments: \type{#1#} reads +%D everyting till the next brace and passes it to both rules. +%D The setting of the box dimensions at the end is needed for +%D special cases. The dimensions of the surrounding box are kept +%D intact. This commands handles positive and negative +%D dimensions (which is why we need two boxes with rules). + +\def\centeredbox#1#% height +/-dimen width +/-dimen + {\bgroup + \setbox0\normalvbox to \vsize + \bgroup + \dontcomplain + \forgetall + \setbox0\normalhbox{\vrule\!!width \zeropoint#1}% + \setbox2\normalvbox{\hrule\!!height\zeropoint#1}% + \advance\vsize \ht2 + \advance\hsize \wd0 + \normalvbox to \vsize + \bgroup + \vskip-\ht2 + \vss + \normalhbox to \hsize + \bgroup + \dowithnextbox + {\hskip-\wd0 + \hss + \flushnextbox + \hss + \egroup + \vss + \egroup + \egroup + \wd0\hsize + \ht0\vsize + \box0 + \egroup} + \normalhbox} + +%D For those who don't want to deal with \type {\hsize} +%D and \type {\vsize}, we have: +%D +%D \starttyping +%D \centerednextbox width 2bp height 2bp +%D {\framed[width=100bp,height=100bp]{}} +%D \stoptyping +%D +%D Do you see what we call this one \type {next}? + +\def\centerednextbox#1#% + {\bgroup + \dowithnextbox + {\hsize\nextboxwd + \vsize\nextboxht + \centeredbox#1{\flushnextbox}% + \egroup} + \normalhbox} + +%D \macros +%D {centerbox} +%D +%D Centering on the available space is done by: +%D +%D \starttyping +%D \centerbox {content} +%D \stoptyping +%D +%D When omitted, the current \type {\hsize} and \type +%D {\vsize} are used. Local dimensions are supported. + +\long\def\centerbox#1#% optional height +/-dimen width +/-dimen + {\bgroup + \dowithnextbox + {\setlocalhsize + \setbox0\normalhbox{\vrule\!!width \zeropoint#1}% + \setbox2\normalvbox{\hrule\!!height\zeropoint#1}% + \ifzeropt\wd0\else\hsize\wd0\fi % \hsize\ifdim\wd0=\zeropoint\hsize\else\wd0\fi + \ifzeropt\ht2\else\vsize\ht2\fi % \vsize\ifdim\ht2=\zeropoint\vsize\else\ht2\fi + \normalvbox to \vsize{\vss\normalhbox to \hsize{\hss\flushnextbox\hss}\vss}% + \egroup}% + \normalhbox} + +%D \macros +%D {setrigidcolumnhsize,rigidcolumnbalance,rigidcolumnlines} +%D +%D These macros are copied from the \TEX book, page~397, and +%D extended by a macro that sets the \type{\hsize}. +%D +%D \starttyping +%D \setrigidcolumnhsize {total width} {distance} {n} +%D \rigidcolumnbalance {box} +%D \stoptyping +%D +%D Both these macros are for instance used in typesetting +%D footnotes. +%D +%D Men kan het proces van breken enigzins beinvloeden met de +%D volgende twee switches: + +\newif\ifalignrigidcolumns +\newif\ifstretchrigidcolumns +\newif\iftightrigidcolumns % if true: just a vbox, no depth/noflines/gridsnap corrrections + +%D De eerste switch bepaald het uitlijnen, de tweede rekt de +%D individuele kolommen op naar \type{\vsize}. + +\def\setrigidcolumnhsize#1#2#3% todo: \dimexpr + {\xdef\savedrigidhsize{\the\hsize}% + \hsize#1\relax + \global\chardef\rigidcolumns#3\relax + \scratchdimen -#2\relax + \multiply\scratchdimen #3\relax + \advance\scratchdimen #2\relax + \advance\hsize \scratchdimen + \divide\hsize #3\relax} + +% == +% +% \def\setrigidcolumnhsize#1#2#3% +% {\xdef\savedrigidhsize{\the\hsize}% +% \global\chardef\rigidcolumns#3\relax +% \hsize=\dimexpr(#1-\numexpr#3-1\relax\dimexpr#2\relax)/#3\relax} + +\newbox\rigidcolumnbox + +\let\rigidcolumnlines\!!zerocount + +\def\rigidcolumnbalance#1% + {\ifnum\rigidcolumns=1 % tzt ook h/d correctie + \ifinner\ifhmode\box\else\unvbox\fi\else\unvbox\fi#1\relax + \else + \normalvbox + {\forgetall + \nopenalties + \dontcomplain + \setbox\rigidcolumnbox\normalvbox + {\line{}\goodbreak\unvbox#1\removebottomthings}% + \splittopskip\openstrutheight + \setbox\scratchbox\vsplit\rigidcolumnbox to \zeropoint + \ifcase\rigidcolumnlines\relax + % \iffalse + % % maybe some day an option + % \scratchskip\ht\rigidcolumnbox + % \advance\scratchskip\dp\rigidcolumnbox + % \getnoflines\scratchskip + % \ifodd\noflines + % \advance\noflines\plusone + % \fi + % \divide\noflines\rigidcolumns + %\else + \scratchdimen\ht\rigidcolumnbox + \divide\scratchdimen \rigidcolumns + \getnoflines\scratchdimen + %\fi + \else + \noflines\rigidcolumnlines % to be sure + \fi + \scratchdimen\noflines\lineheight + % new: we now loop so that we don't loose content + % since in practice we also use this macro for + % funny lineheights and border cases + \setbox0=\box\rigidcolumnbox + \doloop + {\setbox\rigidcolumnbox=\copy0 + \setbox\scratchbox\normalhbox to \savedrigidhsize + {\dorecurse\rigidcolumns + {\setbox\scratchbox\vsplit\rigidcolumnbox to \scratchdimen + \dp\scratchbox\openstrutdepth + \setbox\scratchbox\normalvtop + \ifalignrigidcolumns to + \ifstretchrigidcolumns\vsize\else\scratchdimen\fi + \fi + {\unvbox\scratchbox}% + \wd\scratchbox\hsize + \box\scratchbox + \hfill}% + \hfillneg}% + \ifvoid\rigidcolumnbox\exitloop\else\advance\scratchdimen\lineheight\fi}% + \iftightrigidcolumns + \setbox\scratchbox\normalhbox{\raise\dp\scratchbox\box\scratchbox}% + \else + \advance\scratchdimen -\openstrutdepth + \setbox\scratchbox\normalhbox{\raise\scratchdimen\box\scratchbox}% + \dp\scratchbox\openstrutdepth + \ht\scratchbox\scratchdimen + \fi + \box\scratchbox}% + \fi} + +%D \macros +%D {startvboxtohbox,stopvboxtohbox,convertvboxtohbox} +%D +%D Here is another of Knuth's dirty tricks, as presented on +%D pages 398 and 399 of the \TEX book. These macros can be used +%D like: +%D +%D \starttyping +%D \normalvbox +%D \bgroup +%D \startvboxtohbox ... \stopvboxtohbox +%D \startvboxtohbox ... \stopvboxtohbox +%D \startvboxtohbox ... \stopvboxtohbox +%D \egroup +%D +%D \normalvbox +%D \bgroup +%D \convertvboxtohbox +%D \egroup +%D \stoptyping +%D +%D These macros are used in reformatting footnotes, so they do +%D what they're meant for. + +\def\setvboxtohbox + {\bgroup + \ifdim\baselineskip<16pt \relax + \scratchdimen\baselineskip + \multiply\scratchdimen 1024 + \else + \message{cropping \baselineskip to 16pt}% + \scratchdimen\maxdimen + \fi + \divide\scratchdimen \hsize + \multiply\scratchdimen 64 + \xdef\normalvboxtohboxfactor{\withoutpt\the\scratchdimen}% + \egroup} + +\def\startvboxtohbox + {\bgroup + \setvboxtohbox + \setbox\scratchbox\normalhbox\bgroup} + +\def\stopvboxtohbox + {\egroup + \dp\scratchbox\zeropoint + \ht\scratchbox\normalvboxtohboxfactor\wd\scratchbox + \box\scratchbox + \egroup} + +% % to be done: start halfway a line combined with one line +% % extra to start with (skip) and one line less than counted. +% +% \def\stopvboxtohbox% +% {\egroup +% \setbox2=\normalvbox +% {\forgetall\unhcopy0\par\xdef\globalvhlines{\the\prevgraf}}% +% \setbox2=\normalvbox +% {\unvbox2 +% \setbox2=\lastbox +% \setbox2=\normalhbox{\unhbox2}% +% \xdef\globalvhwidth{\the\wd2}}% +% \decrement\globalvhlines +% \dimen0=\globalvhwidth +% \dimen0=\normalvboxtohboxfactor\dimen0 +% \advance\dimen0 by \globalvhlines\lineheight +% \dp0=\zeropoint +% \ht0=\dimen0 +% %\writestatus{guessed size} +% % {w:\the\wd0\space\space +% % b:\the\baselineskip\space +% % l:\globalvhlines\space +% % e:\globalvhwidth\space +% % h:\the\dimen0}% +% \box0 +% \egroup} + +% todo: \scratchbox + +\def\convertvboxtohbox + {\setvboxtohbox + \makehboxofhboxes + \setbox0\normalhbox{\unhbox0 \removehboxes}% + \noindent\unhbox0\par} + +\def\makehboxofhboxes + {\setbox0\normalhbox{}% + \loop % \doloop { .. \exitloop .. } + \setbox2\lastbox + \ifhbox2 + \setbox0\normalhbox{\box2\unhbox0}% + \repeat} + +% \def\makehboxofhboxes +% {\setbox0\normalhbox{}% +% \doloop % \doloop { .. \exitloop .. } +% {% \dorecurse{3}{\unskip\unpenalty}% get rid of ... (better do this in a shapeloop) +% \setbox2\lastbox +% \ifhbox2 +% \setbox0\normalhbox{\box2\unhbox0}% +% \else +% \exitloop +% \fi}} + +% \def\flushboxesonly % feed this into \makehboxofhboxes +% {\dowithnextbox +% {\beginofshapebox +% \unvbox\nextbox +% \endofshapebox +% \doreshapebox{\box\shapebox}{}{}{}% get rid of penalties etc +% \innerflushshapebox} +% \vbox} + +\def\removehboxes + {\setbox0\lastbox + \ifhbox0 + {\removehboxes}\unhbox0 + \fi} + +%D \macros +%D {unhhbox} +%D +%D The next macro is used in typesetting inline headings. +%D Let's first look at the macro and then show an example. + +\newbox \unhhedbox +\newbox \hhbox +\newdimen \lasthhboxwidth +\newskip \hhboxindent + +\def\unhhbox#1\with#2% + {\bgroup + \nopenalties + \dontcomplain + \forgetall + \setbox\unhhedbox\normalvbox{\hskip\hhboxindent\strut\unhbox#1}% => \hsize + \doloop + {\setbox\hhbox\vsplit\unhhedbox to \lineheight + \ifvoid\unhhedbox + \setbox\hhbox\normalhbox{\strut\normalhboxofvbox\hhbox}% + \fi + \ht\hhbox\strutht + \dp\hhbox\strutdp + \ifzeropt\hhboxindent\else % \ifdim\hhboxindent=\zeropoint\else + \setbox\hhbox\normalhbox{\hskip-\hhboxindent\box\hhbox}% + \hhboxindent\zeropoint + \fi + \global\lasthhboxwidth\wd\hhbox + #2\relax + \ifvoid\unhhedbox + \exitloop + \else + \hskip\zeropoint \!!plus \zeropoint + \fi}% + \egroup} + +\def\dohboxofvbox + {\setbox0\normalvbox{\unvbox\scratchcounter\global\setbox1\lastbox}% + \unhbox1 + \egroup} + +\def\normalhboxofvbox + {\bgroup + \afterassignment\dohboxofvbox + \scratchcounter=} + +%D This macro can be used to break a paragraph apart and treat +%D each line seperately, for instance, making it clickable. The +%D main complication is that we want to be able to continue the +%D paragraph, something that's needed in the in line section +%D headers. +%D +%D \startbuffer +%D \setbox0=\normalhbox{\input tufte \relax} +%D \setbox2=\normalhbox{\input knuth \relax} +%D \unhhbox0\with{\ruledhbox{\box\hhbox}} +%D \hskip1em plus 1em minus 1em +%D \hhboxindent=\lasthhboxwidth +%D \advance\hhboxindent by \lastskip +%D \unhhbox2\with{\ruledhbox{\box\hhbox}} +%D \stopbuffer +%D +%D \getbuffer +%D +%D This piece of text was typeset by saying: +%D +%D \typebuffer +%D +%D Not that nice a definition, but effective. Note the stretch +%D we've build in the line that connects the two paragraphs. + +%D \macros +%D {doifcontent} +%D +%D When processing depends on the availability of content, one +%D can give the next macro a try. +%D +%D \starttyping +%D \doifcontent{pre content}{post content}{no content}\somebox +%D \stoptyping +%D +%D Where \type{\somebox} is either a \type{\normalhbox} or +%D \type{\normalvbox}. If the dimension of this box suggest some +%D content, the resulting box is unboxed and surrounded by the +%D first two arguments, else the third arguments is executed. + +\unexpanded\def\doifcontent#1#2#3% + {\dowithnextbox + {\ifhbox\nextbox + \ifdim\nextboxwd>\zeropoint + #1\unhbox\nextbox#2\relax + \else + #3\relax + \fi + \else + \ifdim\nextboxht>\zeropoint + #1\unvbox\nextbox#2\relax + \else + #3\relax + \fi + \fi}} + +%D So when we say: +%D +%D \startbuffer +%D \doifcontent{[}{]}{}\normalhbox{content sensitive typesetting} +%D +%D \doifcontent{}{\page}{}\normalvbox{content sensitive typesetting} +%D +%D \doifcontent{}{}{\message{Didn't you forget something?}}\normalhbox{} +%D \stopbuffer +%D +%D \typebuffer +%D +%D We get: +%D +%D \getbuffer +%D +%D Where the last call of course does not show up in this +%D document, but definitely generates a confusing message. + +%D \macros +%D {processboxes} +%D +%D The next macro gobble boxes and is for instance used for +%D overlays. First we show the general handler. + +\newbox\processbox + +\def\processboxes#1% + {\bgroup + \def\doprocessbox{#1}% #1 can be redefined halfway + \resetbox\processbox + \afterassignment\dogetprocessbox\let\next=} + +\def\endprocessboxes + {\ifhmode\unskip\fi + \box\processbox + \next + \egroup} + +\def\dogetprocessbox + {\ifx\next\bgroup + \expandafter\dodogetprocessbox + \else + \expandafter\endprocessboxes + \fi} + +\def\dodogetprocessbox + {\dowithnextbox + {\ifhmode\unskip\fi\doprocessbox % takes \nextbox makes \processbox + \afterassignment\dogetprocessbox\let\next=} + \normalhbox\bgroup} + +%D \macros +%D {startoverlay} +%D +%D We can overlay boxes by saying: +%D +%D \startbuffer +%D \startoverlay +%D {\framed{hans}} +%D {\framed[width=3cm]{ton}} +%D {\framed[height=2cm]{oeps}} +%D \stopoverlay +%D \stopbuffer +%D +%D \typebuffer +%D +%D shows up as: +%D +%D \leavevmode\getbuffer + +% \def\dooverlaybox% +% {\ifhmode\unskip\fi +% \ifdim\nextboxht>\ht\processbox +% \setbox\processbox\normalvbox to \nextboxht +% {\vss\box\processbox\vss}% +% \else +% \setbox\nextbox\normalvbox to \ht\processbox +% {\vss\flushnextbox\vss}% +% \fi +% \scratchdimen=\wd +% \ifdim\nextboxwd>\wd\processbox +% \nextbox +% \else +% \processbox +% \fi +% \setbox\processbox=\normalhbox to \scratchdimen +% {\normalhbox to \scratchdimen{\hss\box\processbox\hss}% +% \hskip-\scratchdimen +% \normalhbox to \scratchdimen{\hss\flushnextbox\hss}}} +% +% \def\startoverlay% +% {\bgroup +% \let\stopoverlay\egroup +% \processboxes\dooverlaybox} + +\def\dooverlaybox + {\ifhmode\unskip\fi + \scratchdimen\dp + \ifdim\nextboxdp>\dp\processbox + \nextbox + \else + \processbox + \fi + \ifdim\nextboxht>\ht\processbox + \setbox\processbox\normalvbox to \nextboxht + {\dp\processbox\zeropoint\vss\box\processbox\vss}% + \else + \setbox\nextbox\normalvbox to \ht\processbox + {\nextboxdp\zeropoint\vss\flushnextbox\vss}% + \fi + \nextboxdp\scratchdimen + \dp\processbox\scratchdimen + \scratchdimen\wd + \ifdim\nextboxwd>\wd\processbox + \nextbox + \else + \processbox + \fi + \setbox\processbox\normalhbox to \scratchdimen + {\normalhbox to \scratchdimen{\hss\box\processbox\hss}% + \hskip-\scratchdimen + \normalhbox to \scratchdimen{\hss\flushnextbox\hss}}} + +\unexpanded\def\startoverlay + {\bgroup + \let\stopoverlay\egroup + \processboxes\dooverlaybox} + +\let\stopoverlay\relax + +% %D \macros +% %D {starthspread} +% %D +% %D In a similar way we can build a horizontal box, spread +% %D over the available width. +% %D +% %D \startbuffer +% %D \starthspread +% %D {hans} +% %D {ton} +% %D {oeps} +% %D \stophspread +% %D +% %D \stopbuffer +% %D +% %D \typebuffer +% %D +% %D shows up as: +% %D +% %D \leavevmode\getbuffer +% +% \def\dohspread +% {\flushnextbox +% \def\dohspread{\hfil\flushnextbox}} +% +% \def\starthspread +% {\normalhbox to \hsize \bgroup +% \let\stophspread\egroup +% \processboxes\dohspread} + +%D \macros +%D {fakebox} +%D +%D The next macro is a rather silly one, but saves space. +%D +%D \starttyping +%D \normalhbox{\fakebox0} +%D \stoptyping +%D +%D returns an empty box with the dimensions of the box +%D specified, here being zero. + +\def\dofakebox + {\setbox\scratchbox\null + \wd\scratchbox\wd\scratchcounter + \ht\scratchbox\ht\scratchcounter + \dp\scratchbox\dp\scratchcounter + \ifhbox\scratchcounter\normalhbox\else\normalvbox\fi{\box\scratchbox}% + \egroup} + +\def\fakebox + {\bgroup + \afterassignment\dofakebox\scratchcounter} + +%D \macros +%D {lbox,rbox,cbox,tbox,bbox} +%D +%D Here are some convenient alternative box types: +%D +%D \starttyping +%D \lbox{text ...} +%D \cbox{text ...} +%D \rbox{text ...} +%D \stoptyping +%D +%D Are similar to \type {\normalvbox}, which means that they also +%D accept something like \type{to 3cm}, but align to the left, +%D middle and right. These box types can be used to typeset +%D paragraphs. + +\def\lbox{\makelrcbox\normalvbox\raggedleft} +\def\cbox{\makelrcbox\normalvbox\raggedcenter} +\def\rbox{\makelrcbox\normalvbox\raggedright} + +\def\ltop{\makelrcbox\normalvtop\raggedleft} +\def\ctop{\makelrcbox\normalvtop\raggedcenter} +\def\rtop{\makelrcbox\normalvtop\raggedright} + +\def\makelrcbox#1#2#3#% + {#1#3\bgroup \forgetall \let\\=\endgraf #2\let\next=} + +%D The alternatives \type {\tbox} and \type {\bbox} can be used +%D to properly align boxes, like in: +%D +%D \setupexternalfigures[directory={../sample}] +%D \startbuffer +%D \starttable[|||] +%D \HL +%D \VL \tbox{\externalfigure[cow][height=3cm,frame=on]} \VL top aligned \VL\SR +%D \HL +%D \VL \bbox{\externalfigure[cow][height=3cm,frame=on]} \VL bottom aligned \VL\SR +%D \HL +%D \stoptable +%D \stopbuffer +%D +%D \typebuffer +%D +%D The positioning depends on the strut settings: +%D +%D \getbuffer + +\def\tbox{\tbbox\ht\dp} +\def\bbox{\tbbox\dp\ht} + +\def\tbbox#1#2% + {\normalhbox\bgroup + \dowithnextbox + {\scratchdimen\nextboxht + \advance\scratchdimen\nextboxdp + \advance\scratchdimen-#1\strutbox + #1\nextbox#1\strutbox + #2\nextbox\scratchdimen + \setbox\nextbox\normalhbox + {\lower\nextboxdp\flushnextbox}% + #1\nextbox#1\strutbox + #2\nextbox\scratchdimen + \flushnextbox + \egroup} + \normalhbox} + +%D \macros +%D {lhbox,mhbox,rhbox} +%D +%D A few more boxes. + +\def\dodolhbox{\normalhbox to \hsize{\flushnextbox\hss }} +\def\dodomhbox{\normalhbox to \hsize{\hss\flushnextbox\hss}} +\def\dodorhbox{\normalhbox to \hsize{\hss\flushnextbox }} + +\def\lhbox{\dowithnextboxcs\dodolhbox\normalhbox} +\def\mhbox{\dowithnextboxcs\dodomhbox\normalhbox} +\def\rhbox{\dowithnextboxcs\dodorhbox\normalhbox} + +\let\lefthbox \lhbox +\let\midhbox \mhbox +\let\righthbox\rhbox + +%D \macros +%D {boxofsize} +%D +%D Sometimes we need to construct a box with a height or +%D width made up of several dimensions. Instead of cumbersome +%D additions, we can use: +%D +%D \starttyping +%D \boxofsize \normalvbox 10cm 3cm -5cm {the text to be typeset} +%D \stoptyping +%D +%D This example demonstrates that one can use positive and +%D negative values. Dimension registers are also accepted. + +\newdimen\sizeofbox + +\def\boxofsize#1% + {\bgroup + \sizeofbox\zeropoint + \scratchdimen\zeropoint + \def\docommand + {\advance\sizeofbox\scratchdimen + \futurelet\next\dodocommand}% + \def\dodocommand + {\ifx\next\bgroup + \expanded{\egroup#1 to \the\sizeofbox}% + \else + \@EA\afterassignment\@EA\docommand\@EA\scratchdimen + \fi}% + \docommand} + +%D Some new, still undocumented features: + +% limitatetext -> beter {text} als laatste !! +% +% \limitvbox +% \limithbox + +\def\limitatelines#1#2% size sentinel + {\dowithnextbox + {\dimen0=#1\hsize + \ifdim\nextboxwd>\dimen0 + \setbox\nextbox\normalhbox + {\advance\dimen0 -.1\hsize + \limitatetext{\unhbox\nextbox}{\dimen0}{\nobreak#2}}% + \fi + \unhbox\nextbox} + \normalhbox} + +\def\fittoptobaselinegrid % weg hier + {\dowithnextbox + {\bgroup + \par + \dimen0\nextboxht + \nextboxht\strutht + \nextboxdp\strutdp + \normalhbox{\flushnextbox} + \prevdepth\strutdp + \doloop + {\advance\dimen0 -\lineheight + \ifdim\dimen0<\zeropoint + \exitloop + \else + \nobreak + \normalhbox{\strut} + \fi} + \egroup} + \normalvbox} + +%D Some more undocumented macros (used in m-chart). + +\newif\iftraceboxplacement % \traceboxplacementtrue + +\newbox\fakedboxcursor + +\setbox\fakedboxcursor\normalhbox + {\vrule\!!width\zeropoint\!!height\zeropoint\!!depth\zeropoint} + +\def\boxcursor % overloaded in core-vis + {\iftraceboxplacement + \bgroup + \scratchdimen2pt + \setbox\scratchbox\normalhbox to \zeropoint + {\hss + \vrule + \!!width \scratchdimen + \!!height\scratchdimen + \!!depth \scratchdimen + \hss}% + \smashedbox\scratchbox + \egroup + \else + \copy\fakedboxcursor + \fi} + +\def\placedbox + {\iftraceboxplacement\ruledhbox\else\normalhbox\fi} + +\newdimen\boxoffset +\newdimen\boxhdisplacement +\newdimen\boxvdisplacement + +%\def\rightbox#1% +% {\normalhbox +% {\setbox0=\placedbox{#1}% +% \dimen0=.5\ht0\advance\dimen0 -.5\dp0 +% \boxcursor\hskip\boxoffset\lower\dimen0\box0}} + +\def\rightbox#1% + {\normalhbox + {\setbox0\placedbox{#1}% + \global\boxhdisplacement\boxoffset + \global\boxvdisplacement.5\ht0 + \global\advance\boxvdisplacement-.5\dp0 + \boxcursor\hskip\boxhdisplacement\lower\boxvdisplacement\box0}} + +%\def\leftbox#1% +% {\normalhbox +% {\setbox0=\placedbox{#1}% +% \dimen0=.5\ht0\advance\dimen0 -.5\dp0 +% \boxcursor\hskip-\wd0\hskip-\boxoffset\lower\dimen0\box0}} + +\def\leftbox#1% + {\normalhbox + {\setbox0\placedbox{#1}% + \global\boxhdisplacement-\wd0 + \global\advance\boxhdisplacement-\boxoffset + \global\boxvdisplacement.5\ht0 + \global\advance\boxvdisplacement-.5\dp0 + \boxcursor\hskip\boxhdisplacement\lower\boxvdisplacement\box0}} + +%\def\topbox#1% +% {\normalhbox +% {\setbox0=\placedbox{#1}% +% \dimen0=\boxoffset\advance\dimen0 \dp0 +% \boxcursor\hskip-.5\wd0\raise\dimen0\box0}} + +\def\topbox#1% + {\normalhbox + {\setbox0\placedbox{#1}% + \global\boxhdisplacement-.5\wd0 + \global\boxvdisplacement-\dp0 + \global\advance\boxvdisplacement-\boxoffset + \boxcursor\hskip\boxhdisplacement\raise-\boxvdisplacement\box0}} + +%\def\bottombox#1% +% {\normalhbox +% {\setbox0=\placedbox{#1}% +% \dimen0=\boxoffset\advance\dimen0 \ht0 +% \boxcursor\hskip-.5\wd0\lower\dimen0\box0}} + +\def\bottombox#1% + {\normalhbox + {\setbox0\placedbox{#1}% + \global\boxhdisplacement-.5\wd0 + \global\boxvdisplacement\ht0 + \global\advance\boxvdisplacement\boxoffset + \boxcursor\hskip\boxhdisplacement\lower\boxvdisplacement\box0}} + +%\def\lefttopbox#1% +% {\normalhbox +% {\setbox0=\placedbox{#1}% +% \dimen0=\boxoffset\advance\dimen0 \dp0 +% \advance\boxoffset\wd0 +% \boxcursor\hskip-\boxoffset\raise\dimen0\box0}} + +\def\lefttopbox#1% + {\normalhbox + {\setbox0\placedbox{#1}% + \global\boxhdisplacement-\wd0 + \global\advance\boxhdisplacement-\boxoffset + \global\boxvdisplacement-\dp0 + \global\advance\boxvdisplacement-\boxoffset + \boxcursor\hskip\boxhdisplacement\raise-\boxvdisplacement\box0}} + +%\def\righttopbox#1% +% {\normalhbox +% {\setbox0=\placedbox{#1}% +% \dimen0=\boxoffset\advance\dimen0 \dp0 +% \boxcursor\hskip\boxoffset\raise\dimen0\box0}} + +\def\righttopbox#1% + {\normalhbox + {\setbox0\placedbox{#1}% + \global\boxhdisplacement\boxoffset + \global\boxvdisplacement-\dp0 + \global\advance\boxvdisplacement-\boxoffset + \boxcursor\hskip\boxhdisplacement\raise-\boxvdisplacement\box0}} + +%\def\leftbottombox#1% +% {\normalhbox +% {\setbox0=\placedbox{#1}% +% \dimen0=\boxoffset\advance\dimen0 \ht0 +% \advance\boxoffset\wd0 +% \boxcursor\hskip-\boxoffset\lower\dimen0\box0}} + +\def\leftbottombox#1% + {\normalhbox + {\setbox0\placedbox{#1}% + \global\boxhdisplacement-\wd0 + \global\advance\boxhdisplacement-\boxoffset + \global\boxvdisplacement\ht0 + \global\advance\boxvdisplacement\boxoffset + \boxcursor\hskip\boxhdisplacement\lower\boxvdisplacement\box0}} + +%\def\rightbottombox#1% +% {\normalhbox +% {\setbox0=\placedbox{#1}% +% \dimen0=\boxoffset\advance\dimen0 \ht0 +% \boxcursor\hskip\boxoffset\lower\dimen0\box0}} + +\def\rightbottombox#1% + {\normalhbox + {\setbox0\placedbox{#1}% + \global\boxhdisplacement\boxoffset + \global\boxvdisplacement\ht0 + \global\advance\boxvdisplacement\boxoffset + \boxcursor\hskip\boxhdisplacement\lower\boxvdisplacement\box0}} + +\let\topleftbox \lefttopbox +\let\toprightbox \righttopbox +\let\bottomleftbox \leftbottombox +\let\bottomrightbox\rightbottombox + +\def\middlebox#1% + {\normalhbox{\setbox0\placedbox{#1}\boxoffset=-.5\wd0\rightbox{\box0}}} + +\def\baselinemiddlebox#1% + {\normalhbox + {\setbox0\placedbox{#1}% + \global\boxhdisplacement-.5\wd0 + \global\advance\boxhdisplacement-\boxoffset + \global\boxvdisplacement-\boxoffset + \boxcursor\hskip\boxhdisplacement\raise-\boxvdisplacement\box0}} + +\def\baselineleftbox#1% + {\normalhbox + {\setbox0\placedbox{#1}% + \global\boxhdisplacement-\wd0 + \global\advance\boxhdisplacement-\boxoffset + \global\boxvdisplacement-\boxoffset + \boxcursor\hskip\boxhdisplacement\raise-\boxvdisplacement\box0}} + +\def\baselinerightbox#1% + {\normalhbox + {\setbox0\placedbox{#1}% + \global\boxhdisplacement\boxoffset + \global\boxvdisplacement-\boxoffset + \boxcursor\hskip\boxhdisplacement\raise-\boxvdisplacement\box0}} + +%D \macros +%D {obox} +%D +%D Experimental, not yet frozen: + +\def\lrtbbox#1#2#3#4% l r t b + {\bgroup + \dowithnextboxcontent + {\advance\hsize-#1\advance\hsize-#2\advance\vsize-#3\advance\vsize-#4\relax} + {\forgetall\vbox to \vsize{\vskip#3\hbox to \hsize{\hskip#1\box\nextbox\hss}\vss}\egroup} + \vbox} + +%D \macros +%D {toplinebox} +%D +%D See core-tbl.tex for an example of its usage: + +\def\toplinebox + {\dowithnextbox + {\ifdim\nextboxdp>\strutdepth + \scratchdimen\nextboxdp + \advance\scratchdimen-\strutdepth + \getnoflines\scratchdimen + \struttedbox{\flushnextbox}% + \dorecurse\noflines\verticalstrut + \else + \flushnextbox + \fi}% + \tbox} + +%D \macros +%D {initializeboxstack,savebox,foundbox} +%D +%D At the cost of some memory, but saving box registers, we +%D have implemented a box repository. +%D +%D \starttyping +%D \initializeboxstack{one} +%D +%D \savebox{one}{a}{test a} +%D \savebox{one}{p}{test p} +%D \savebox{one}{q}{test q} +%D +%D \normalhbox{a:\foundbox{one}{a}} \par +%D \normalhbox{q:\foundbox{one}{q}} \par +%D \normalhbox{p:\foundbox{one}{p}} \par +%D \normalhbox{x:\foundbox{one}{x}} \par +%D \normalhbox{y:\foundbox{two}{a}} \par +%D \stoptyping + +% 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 +% \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}} + +\def\@@stackbox{@box@} +\def\@@stacklst{@xob@} + +\def\setstackbox#1#2% + {\ifcsname\@@stackbox:#1:#2\endcsname\else + \expandafter\newbox\csname\@@stackbox:#1:#2\endcsname + \fi + \global\setbox\csname\@@stackbox:#1:#2\endcsname\normalvbox} + +\def\initializeboxstack#1% + {\def\docommand##1{\setstackbox{#1}{##1}{}}% + \ifcsname\@@stacklst#1\endcsname + \processcommacommand[\getvalue{\@@stacklst#1}]\docommand + \fi + \global\letvalue{\@@stacklst#1}\empty} + +\def\savebox#1#2% stack name + {% beware, \setxvalue defines the cs beforehand so we cannot use the + % test inside the { } + \ifcsname\@@stacklst#1\endcsname + \setxvalue{\@@stacklst#1}{\csname\@@stacklst#1\endcsname,#2}% + \else + \setxvalue{\@@stacklst#1}{#2}% + \fi + \setstackbox{#1}{#2}} + +\def\foundbox#1#2% + {\normalvbox + {\ifcsname\@@stackbox:#1:#2\endcsname + \copy\csname\@@stackbox:#1:#2\endcsname + \fi}} + +\long\def\doifboxelse#1#2#3#4% + {\ifcsname\@@stackbox:#1:#2\endcsname + \ifvoid\csname\@@stackbox:#1:#2\endcsname#4\else#3\fi + \else + #4% + \fi} + +\endETEX + +%D \macros +%D {removedepth, obeydepth} +%D +%D While \type {\removedepth} removes the preceding depth, +%D \type {\obeydepth} makes sure we have depth. Both macros +%D leave the \type {\prevdepth} untouched. + +\def\removedepth + {\ifvmode \ifdim\prevdepth>\zeropoint \kern-\prevdepth \fi \fi} + +\def\obeydepth + {\par \removedepth \ifvmode \kern\strutdp \fi} + +\def\undepthed + {\dowithnextbox{\nextboxdp\zeropoint\flushnextbox}\hbox} + +%D \macros +%D {removebottomthings, removelastskip} +%D +%D A funny (but rather stupid) one, plus a redefinition. + +\def\removebottomthings + {\dorecurse5{\unskip\unkern\unpenalty}} + +\def\removelastskip % \ifvmode the plain tex one \fi +% {\ifvmode\ifdim\lastskip=\zeropoint\else\vskip-\lastskip\fi\fi} + {\ifvmode\ifzeropt\lastskip\else\vskip-\lastskip\fi\fi} + +%D \macros +%D {makestrutofbox} +%D +%D This macro sets the dimensions of a box to those of a +%D strut. + +\def\domakestrutofbox + {\ht\registercount\strutht + \dp\registercount\strutdp + \wd\registercount\zeropoint} + +\def\makestrutofbox + {\afterassignment\domakestrutofbox\registercount} + +%D \macros +%D {raisebox,lowerbox} +%D +%D Some more box stuff, related to positioning (under +%D construction). Nice stuff for a tips and tricks maps +%D article. +%D +%D \starttyping +%D \raisebox{100pt}\normalhbox{test} +%D \raisebox50pt\normalhbox{test} +%D \hsmash{\raisebox{100pt}\normalhbox{test}} +%D \stoptyping + +\def\doraiselowerbox#1#2% a nice trick us used to accept + {\def\next % both direct and {} dimensions + {\dowithnextbox + {\setbox\nextbox\normalhbox{#1\scratchdimen\flushnextbox}% + \nextboxht\strutht + \nextboxdp\strutdp + \flushnextbox}}% + \afterassignment\next\scratchdimen=#2} + +\def\raisebox{\doraiselowerbox\raise} +\def\lowerbox{\doraiselowerbox\raise} + +% maybe some day we need this +% +% \def\appendvbox#1% % uses \box8 +% {\bgroup +% \ifdim\prevdepth<\zeropoint +% \ifdim\pagetotal=\zeropoint +% \setbox8=\normalvtop{\unvcopy#1}% +% \hrule\c!!height\zeropoint +% \kern-\ht8 +% \box#1\relax +% \else +% \box#1\relax +% \fi +% \else +% \dimen0=\prevdepth +% \hrule\c!!height\zeropoint +% \setbox8=\normalvtop{\unvcopy#1}% +% \dimen2=\baselineskip +% \advance\dimen2 by -\dimen0 +% \advance\dimen2 by -\ht8 +% \kern\dimen2 +% \box#1\relax +% \fi +% \egroup} + +% %D Also new: +% %D +% %D \startbuffer +% %D \normbox[1cm][bba]{m} % b(efore) a(fter) v(box) s(trut) f(rame) +% %D \normbox[1cm][bba]{m} +% %D \normbox[1cm][bba]{m} +% %D \stopbuffer +% %D +% %D \typebuffer +% %D \getbuffer +% +% \def\dodonormbox#1#2#3#4#5#6#7% +% {\doifnumberelse{#1} +% {\dimen0=#1}{\setbox0=#3{#1}\dimen0=#50}% +% \doifinstringelse{f}{#2} +% {\let\next#4}{\let\next#3}% +% \next to \dimen0 +% {\counttoken b\in#2\to\!!counta\dorecurse{\!!counta}{#6}#6% +% #7\nextbox +% \counttoken a\in#2\to\!!counta\dorecurse{\!!counta}{#6}#6}} +% +% \def\donormbox[#1][#2]% +% {\bgroup +% \doifinstringelse{v}{#2} +% {\let\next\normalvbox} +% {\let\next\normalhbox}% +% \dowithnextbox +% {\ifvbox\nextbox +% \let\\=\par +% \dodonormbox{#1}{#2}\normalvbox\ruledvbox\ht\vfil\unvbox +% \else +% \let\\=\space +% \dodonormbox{#1}{#2}\normalhbox\ruledhbox\wd\hfil\unhbox +% \fi +% \egroup}% +% \next} +% +% \def\normbox +% {\dodoubleempty\donormbox} + +% vcenter in text, we kunnen vcenter overloaden + +\def\halfwaybox + {\dowithnextbox + {\nextboxdp\zeropoint + \setbox\nextbox\normalhbox{\lower.5\nextboxht\flushnextbox}% + \flushnextbox} + \normalhbox} + +%D New: + +\def\setdimentoatleast#1#2% + {\ifdim#1>\zeropoint\else#1=#2\fi} + +%D And even rawer: + +\let\naturalhbox \normalhbox +\let\naturalvbox \normalvbox +\let\naturalvtop \normalvtop +\let\naturalvcenter \normalvtop + +\ifdefined\textdir + + \def\naturalhbox{\normalhbox dir TLT} + \def\naturalvbox{\normalvbox dir TLT} + %def\naturalvtop{\normalvtop dir TLT} + +\fi + +%D \macros +%D {vcenter} +%D +%D Also new: tex mode \type {\vcenter}. + +\let\verynormalvcenter \vcenter % since \vcenter can be visualized + +\def\vcenter + {\normalvbox\bgroup + \dowithnextbox{\normalhbox{$\verynormalvcenter{\flushnextbox}$}\egroup} + \normalvbox} + +% could be \everymathematics + +\prependtoks \let\vcenter\normalvcenter \to \everymath +\prependtoks \let\vcenter\normalvcenter \to \everydisplay + +%D \macros +%D {frozenhbox} +%D +%D A not so well unhboxable bxo can be made with: + +\def\frozenhbox + {\hbox\bgroup\dowithnextbox{\hbox{\hbox{\flushnextbox}}\egroup}\hbox} + +%D \macros +%D {setboxllx,setboxlly,gsetboxllx,gsetboxlly,getboxllx,getboxlly} +%D +%D A prelude to an extended \TEX: + +% \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\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}} + +\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} + +%D \macros +%D {shownextbox} +%D +%D Handy for tracing +%D +%D \starttyping +%D \shownextbox\vbox{test} +%D \shownextbox\vbox{test\endgraf} +%D \shownextbox\vbox{test\endgraf\strut\endgraf} +%D \shownextbox\vbox{test\endgraf\thinrule} +%D \shownextbox\vbox{\setupwhitespace[big]test\endgraf\thinrule} +%D \stoptyping + +\def\shownextbox + {\dowithnextbox + {\bgroup + \showboxbreadth\maxdimen + \showboxdepth \maxdimen + \scratchcounter\interactionmode + \batchmode + \showbox\nextbox + \box\nextbox + \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 but too much log for overfull boxes: +% +% \showboxbreadth\maxdimen +% \showboxdepth \maxdimen + +\protect \endinput + +% a bit of test code: + +\hbox \bgroup + \ruledvbox {\hbox{\strut gans}} + \ruledvbox to \lineheight {\hbox{\strut gans}} + \ruledvbox to \lineheight {\hbox {gans}} + \ruledvbox to \strutheight{\hbox {gans}} + \ruledvbox to \strutheight{\hbox{\strut gans}} + \ruledvbox to \strutheight{\vss\hbox{gans}} +\egroup 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..0634bd36f --- /dev/null +++ b/tex/context/base/supp-dir.mkiv @@ -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 We no longer have the \ETEX\ direction primitives. + +\unprotect + +% \expanded{\defineactivecharacter \number"2000E} {\textdir TRT\relax} +% \expanded{\defineactivecharacter \number"2000F} {\textdir TLT\relax} + +\unexpanded\def\showdirsinmargin + {\doifelse{\the\pardir}\!!TLT + {\inleft{\normalexpanded{\noexpand\hbox dir TLT{\ttxx[\the\pardir,\the\textdir]}}}} + {\inleft{\normalexpanded{\noexpand\hbox dir TLT{\ttxx[\the\pardir,\the\textdir]}}}}} + +\bgroup + \catcode`L=\othercatcode \gdef\istltdir#1#2#3{\if#2L0\else1\fi} + \catcode`R=\othercatcode \gdef\istrtdir#1#2#3{\if#2R0\else1\fi} +\egroup + +\def\istlttextdir{\expandafter\istltdir\the\textdir} +\def\istrttextdir{\expandafter\istrtdir\the\textdir} + +\def\istltpardir {\expandafter\istltdir\the\pardir } +\def\istrtpardir {\expandafter\istrtdir\the\pardir } + +% \ifcase\istlttextdir Y\else N\fi +% \ifcase\istltpardir Y\else N\fi +% \ifcase\istltdir TRT\relax Y\else N\fi + +\protect \endinput diff --git a/tex/context/base/supp-emp.mkii b/tex/context/base/supp-emp.mkii new file mode 100644 index 000000000..15489bca7 --- /dev/null +++ b/tex/context/base/supp-emp.mkii @@ -0,0 +1,398 @@ +%D \module +%D [ file=supp-emp, +%D version=2000.08.09, +%D title=\CONTEXT\ Support Macros, +%D subtitle=\EMTEX\ specials to \PDF\ conversion, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%M \input supp-emp + +%D When \THANH, the author of \PDFTEX, and I were exchanging +%D some emails on \PDFTEX\ functionality, positional +%D information popped up as potential extension. Actually, it +%D did not take that much time to cook up the basic +%D functionality and the author had implemented it before I +%D could even start to think about real advanced applications. +%D +%D I'm sure that \TEX\ programmers can spend many days on how +%D and what kind of information is needed if you want to have +%D access to positions, but since high level macros will +%D probably be used anyway, even things like multiple reference +%D points have proved to be rather unimportant at the system +%D level. +%D +%D Therefore, \PDFTEX\ provides just these three primitives: +%D +%D \starttabulate[|l|l|] +%D \NC \type {\pdfsavepos} \NC marks the current position \NC \NR +%D \NC \type {\pdflastxpos} \NC the last marked horizontal position \NC \NR +%D \NC \type {\pdflastypos} \NC the last marked vertical position \NC \NR +%D \stoptabulate +%D +%D Based on these three primitives, very advanced systems can +%D be build, and for some time now, \CONTEXT\ has such a +%D system in its core. However, not everyone uses \CONTEXT, so +%D we will demonstrate position tracking in generic applications. +%D +%D Because \PDFTEX\ produces its output directly, many of those +%D nice tricks provided by back||ends by means of \type +%D {\special} fail when producing \PDF\ code directly. Take for +%D instance \EMTEX\ specials. When someone sent me a mail +%D asking if \PDFTEX\ did support those specials, the original +%D answer was \quotation {no}, but in the last few years I have learned +%D that you must never underestimate \TEX's capabilities. +%D +%D I must admit that I never use those specials myself, but +%D from the way they were used in the macros I was sent, I +%D learned that they depend on the back||end's capability to +%D access the current position. For those who know \TEX\ this +%D may be bad news, since pure \TEX\ does not provide any +%D positional information. So in order to use those specials, +%D you must be sure that they are supported by every driver you +%D use. However, the good news is that \PDFTEX\ does support +%D position tracking, so here is our generic example. +%D +%D The two \EMTEX\ specials we need to implement are packaged +%D into the macros \type {\EMmoveto} and \type {\EMlineto}, +%D like: +%D +%D \starttyping +%D \def\EMmoveto{\special{em:moveto}} +%D \def\EMlineto{\special{em:lineto}} +%D \stoptyping +%D +%D They are used in macro packages to draw lines, and the +%D results are often boxes with content like the following: +%D +%D \startbuffer +%D \vbox to 2cm +%D {\offinterlineskip \EMmoveto +%D \hskip 7cm \EMlineto +%D \vskip 2cm \EMlineto +%D \vskip-2cm \EMlineto} +%D \stopbuffer +%D +%D \typebuffer +%D +%D This box will contain a triangle, and when typeset, it should +%D look like: +%D +%D \startlinecorrection[blank] +%D \getbuffer +%D \stoplinecorrection + +\def\EMlinewd{.4} + +\ifx\dosetpositionpt\undefined % non context part + +%D These two macros can be implemented as follows. When moving +%D to a position, we only have to register the new coordinates. +%D Once they are known, we use them to draw a line and +%D afterwards we save these end coordinates as starting point +%D for the next line segment. So, at each point specified by +%D \type {\EMlineto} we need to know the coordinates. + +\def\EMmoveto + {\EMgetposition\EMlastmovex\EMlastmovey} + +%D The primitives \type {\pdflastxpos} and \type +%D {\pdflastypos} return a number, representing the $x$ and +%D $y$ coordinate in scaled points, \TEX's smallest unit of +%D length. We need to convert this number into base points as +%D used by \POSTSCRIPT\ and \PDF. When done, we insert some +%D literal \PDF\ code into the text using \type {\pdfliteral}. +%D Here, the \type {m} means \quote {moveto}, the \type {l} +%D means \quote {lineto} and the \type {S} operator \quote +%D {strokes} (draws) the line. The macro \type {\EMlinewd} +%D holds the linewidth in basepoints. + +\def\EMlineto + {\bgroup + \EMgetposition\EMlastlinex\EMlastliney + \count0=\EMlastmovex \advance\count0 -\EMlastlinex + \count2=\EMlastmovey \advance\count2 -\EMlastliney + \divide\count0 65536 + \divide\count2 65536 + \PDFcode{\EMlinewd\space w 0 0 m \the\count0 \space\the\count2 \space l S}% + \global\let\EMlastmovex\EMlastlinex + \global\let\EMlastmovey\EMlastliney + \egroup} + +%D We need a fresh start, so we first set the current position +%D to zero. + +\def\resetEMspecials + {\gdef\EMlastmovex{0}\gdef\EMlastmovey{0}} + +%D Next comes the macro that keeps track of the position. The +%D current position is marked with \type {\pdfsavepos} and its +%D coordinates are written to a file whenever the page is +%D shipped out, since \type {\write} postpones its action +%D until that moment. The file has entries like: +%D +%D \starttyping +%D \EMsetpos 1 4661756 46651918 +%D \EMsetpos 2 5000359 46990521 +%D \EMsetpos 3 4661756 46313315 +%D \EMsetpos 4 5338962 46990521 +%D \EMsetpos 5 4661756 45974712 +%D \stoptyping +%D +%D These lines are written with the command: +%D +%D \starttyping +%D \write\EMfile +%D {\EMsetpos\number\EMcounter +%D \space\number\pdflastxpos\space\number\pdflastypos}% +%D \stoptyping +%D +%D In reality the argument to \type {\write} looks slightly +%D more complicated, because we have to make sure that the +%D number of the current position is frozen and \type +%D {\EMsetpos} is not expanded. We do so by explicitly +%D expanding the number beforehand and preventing expansion of +%D \type {\EMsetpos}. + +\def\EMgetposition#1#2% + {\bgroup + \pdfsavepos + \global\advance\EMcounter 1 + \expandafter\write\expandafter\EMfile\expandafter + {\expandafter\noexpand\expandafter\EMsetpos\number\EMcounter + \space\number\pdflastxpos\space\number\pdflastypos}% + \EMsetcounters + \xdef#1{\the\count0}% + \xdef#2{\the\count2}% + \egroup} + +%D The counter mentioned a few lines ago needs to be +%D declared before it can be used. + +\newcount\EMcounter + +%D We also need a dedicated file slot. + +\newwrite\EMfile + +%D Before we open the file for writing, we read in the data +%D written in the previous pass, but only if the file is +%D present. + +\def\EMfilename{\jobname.emp} + +\def\startEMspecials% + {\resetEMspecials + \openin\scratchread=\EMfilename \relax + \ifeof\scratchread\else \input \EMfilename \relax \fi + \closein\scratchread + \immediate\openout\EMfile=\EMfilename\relax} + +\def\stopEMspecials + {\closeout\EMfile} + +%D Just to be sure, we test if \type {\scratchread} is defined, +%D and if not, we allocate a slot. + +\ifx\undefined\scratchread \newread\scratchread \fi + +%D This leaves us two commands. The \type {\EMsetpos} command +%D that ends up in the file stores each position in a macro. +%D When this macro is expanded, it assigns the coordinates to +%D two scratch counters. + +\def\EMsetpos#1 #2 #3 % number x y + {\expandafter\xdef\csname EM:#1\endcsname{\count0=#2 \count2=#3}} + +%D This position is recalled with its companion macro. First we +%D set the counters to zero. When the position is unknown, +%D nothing happens since the \type {\csname...} will expand to +%D \type {\relax}. + +\def\EMsetcounters + {\count0=0 \count2=0 + \csname EM:\the\EMcounter\endcsname} + +%D These macros are rather independent of the macro package you +%D use. For instance, in \CONTEXT\ the following works well: +%D +%D \startbuffer[pos-en] +%D \setuppositioning[unit=ex] +%D \startpositioning +%D \dostepwiserecurse{-10}{10}{1} +%D {\position(0,\recurselevel){\EMmoveto} +%D \position(\recurselevel,0){\EMlineto}} +%D \stoppositioning +%D \stopbuffer +%D +%D \startbuffer[pos-nl] +%D \setuppositioning[uniteenheid=ex] +%D \startpositioning +%D \dostepwiserecurse{-10}{10}{1} +%D {\position(0,\recurselevel){\EMmoveto} +%D \position(\recurselevel,0){\EMlineto}} +%D \stoppositioning +%D \stopbuffer +%D +%D \typebuffer[pos-en] +%D +%D Here, we hook the \EMTEX\ macros into an existing text +%D positioning mechanism, which positions the commands +%D using \TEX's skips and kerns. +%D +%D \startlinecorrection[blank] +%D \getbuffer[pos-nl] +%D \stoplinecorrection +%D +%D Of course one should start and end the file with: +%D +%D \starttyping +%D \startEMspecials +%D \stopEMspecials +%D \stoptyping +%D +%D and, if needed, reset the begin position at each page using: +%D +%D \starttyping +%D \resetEMspecials +%D \stoptyping + +\fi % end of non context part + +\ifx\dosetpositionpt\undefined \else % context part + +% \edef\EMlinewd{\withoutpt\the\linewidth} + +%D A few pages ago, we mentioned that \CONTEXT\ has built||in +%D position tracking. This means that when we want to implement +%D this kind of trickery in this macro package, we can fall +%D back on existing functionality. In the following alternative +%D we will also use a few skips. This keeps the source readable +%D and \CONTEXT\ has plenty of unused registers to accomodate +%D this strategy. + +\newcount\EMcounter \def\EMvariable{EM:\the\EMcounter} + +\newskip \EMlastmovex \newskip \EMlastmovey +\newskip \EMlastlinex \newskip \EMlastliney + +\def\resetEMspecials + {\global\EMlastmovex=0pt \global\EMlastmovey=\EMlastmovex} + +\resetEMspecials \appendtoks\resetEMspecials\to\everyshipout + +%D Watch how we reset the specials after a page is flushed. We +%D don't have to bother about files here, because saving and +%D recalling is already implemented. Although not needed, we +%D define the start||stop macros, so that \CONTEXT\ users who +%D key them in are not confronted with error messages. + +\let\startEMspecials\relax \let\stopEMspecials\relax + +\def\EMgetposition#1#2% + {\global\advance\EMcounter 1 + \setposition\EMvariable + \global#1=\POSx\EMvariable + \global#2=\POSy\EMvariable} + +\def\EMmoveto + {\EMgetposition\EMlastmovex\EMlastmovey} + +\def\EMlineto + {\EMgetposition\EMlastlinex\EMlastliney + \global\advance\EMlastmovex -\EMlastlinex + \global\advance\EMlastmovey -\EMlastliney + \ScaledPointsToBigPoints{\number\EMlastmovex}\EMx + \ScaledPointsToBigPoints{\number\EMlastmovey}\EMy + \PDFcode{\EMlinewd\space w 0 0 m \EMx \space \EMy \space l S}% + \global\EMlastmovex\EMlastlinex + \global\EMlastmovey\EMlastliney} + +%D The command \type {\setposition} registers a position by +%D name (here \type {\EMvariable}), while \type {\POSx} and +%D \type {\POSy} give you access to the coordinates. +%D +%D These three commands are containes in a suite of low level +%D commands that can be used to register and get access to +%D positional information. The current mechanism is not yet +%D complete, but already provides enough hooks for advanced +%D embedded graphics. Its functionality is a natural extension +%D to the \METAPOST\ support already present in \CONTEXT. +%D Therefore, more advanced examples can be found in the +%D \METAFUN\ manual, since they fall beyond the scope of this +%D module. + +\fi % end of context part + +%D As a bonus, I will now provide a few macros that will make +%D this mechanism transparant to \DVI\ as well as \PDF\ +%D output. We will use \type {\pdfiteral} as trigger. + +\ifx\PDFcode\undefined + \ifx\pdfliteral\undefined + \def\PDFcode#1{\special{PDF: #1}} + \else + \let\PDFcode\pdfliteral + \fi +\fi + +\ifx\PDFcode\undefined + \def\EMpdfordvi#1#2{#2} +\else\ifx\pdfoutput\undefined + \def\EMpdfordvi#1#2{#2} +\else + \def\EMpdfordvi#1#2{\ifcase\pdfoutput#2\else#1\fi} +\fi\fi + + +%D We save some of the macros we defined previously: + +\let\pdfEMmoveto\EMmoveto \let\pdfstartEMspecials\startEMspecials +\let\pdfEMlineto\EMlineto \let\pdfstopEMspecials \stopEMspecials + +%D We now redefine them to support \DVI\ and \PDF. + +\def\EMmoveto{\EMpdfordvi\pdfEMmoveto{\special{em:moveto}}} +\def\EMlineto{\EMpdfordvi\pdfEMlineto{\special{em:lineto}}} + +\def\startEMspecials{\EMpdfordvi\pdfstartEMspecials\relax} +\def\stopEMspecials {\EMpdfordvi\pdfstopEMspecials \relax} + +%D If there is any real demand for this in \CONTEXT, I will +%D hook these macros in the special drivers, so that their +%D support becomes more natural. + +%D You may want to change the default linewidth. The following +%D macro does the job. Beware of the fact that \type +%D {\special}'s may interfere with the typesetting process. +%D +%D \starttyping +%D \setEMlinewidth{1pt} +%D \stoptyping + +\def\setEMlinewidth#1% this could be done more efficient for + {\bgroup % context alone, but it's a hack anyway + \dimen0=#1\relax + \count0=\dimen0 + \divide\count0 65536 + \pdfordvi\relax{\special{em:linewidth \the\dimen0}}% + \xdef\EMlinewd{\the\count0}% + \egroup} + +%D You may wonder to what extent positional tracking is +%D \PDFTEX\ specific. In \CONTEXT, we also support position +%D tracking in \DVI\ by using specials and analyzing the \DVI\ +%D file afterwards using \DVIPOS. Since many of the advanced +%D \TEX\ features depend on some kind of back||end, we don't +%D consider it to be a disadvantage. Of course, the \PDFTEX\ +%D way is not only cleaner, but also faster. It was more out +%D of curiosity than out of need that we provided the \DVI\ +%D methods as well. Also, it is always good to have more roads +%D to reach the same goal. + +\endinput diff --git a/tex/context/base/supp-eps.mkii b/tex/context/base/supp-eps.mkii new file mode 100644 index 000000000..5684b25dd --- /dev/null +++ b/tex/context/base/supp-eps.mkii @@ -0,0 +1,202 @@ +%D \module +%D [ file=supp-eps, +%D version=1998.05.06, +%D title=\CONTEXT\ Support Macros, +%D subtitle=\EPS\ tools, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\ifx \undefined \writestatus \input supp-mis.tex \relax \fi + +%D The macros in this module are rather old and were originally +%D part of the figure inclusion macros. When \PDFTEX\ started +%D to support \PDF\ inclusion, where some accompanying macros +%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} + +%D \macros +%D {dogetEPSboundingbox} +%D +%D The predecessors of the following macro's are derived from +%D Thomas Rockicky's macro's. They are rewritten to a more +%D compact form, made a bit more robust and also handle the +%D \type{HiResBoundingBox} and \type{ExactBoundingBox} that +%D are sometimes present. +%D +%D A bounding box has the form: +%D +%D \starttyping +%D %%BoundingBox: llx lly urx ury +%D \stoptyping +%D +%D Before we scan the file, we have to reset special +%D characters and set some others. The percentage symbol also +%D needs special treatment. When a bounding box is +%D encountered, we keep on scanning until no more directives +%D are found, i.e. a line is found that does not start with a +%D percentage symbol. We also abort scanning after finding a +%D high resolution bounding box. +%D +%D This method also works inside verbatim mode (like when we +%D are typesetting sources and putting eps coded logos into +%D a heading. Temporary restoring the \CATCODES\ is done in +%D the calling routine. +%D +%D The creator as well as external support for specials are +%D analyzed as well and their status is available in \type +%D {\EPScreator} and \type {\EPSshading}. The boundingbox +%D components are available in \type {\EPSllx} etc. + +\unprotect + +\def\EPSllx{0} \let\MPllx\EPSllx % just in case these +\def\EPSlly{0} \let\MPlly\EPSlly % are used while running +\def\EPSurx{0} \let\MPurx\EPSurx % in fast mode we set +\def\EPSury{0} \let\MPury\EPSury % them to 0. + +\chardef\EPSfound =0 +\chardef\EPScreator=0 +\chardef\EPSspecial=0 +\chardef\EPSstatus =0 + +\let\EPScreatorstring\empty + +\newtoks\extraEPSpreambleresets +\newtoks\extraEPSpreambleparsers + +\def\dofinishEPSfile{\dofinishfile} % no \let, can be overloaded + +\def\dogetEPSboundingbox#1#2#3#4#5% + {\bgroup + \global\chardef\EPSfound \zerocount + \global\chardef\EPScreator\zerocount + \global\chardef\EPSspecial\zerocount + \global\chardef\EPSstatus \zerocount + \global\let\EPScreatorstring\empty + \the\extraEPSpreambleresets + \uncatcodespecials + \catcode`\^^M=\@@ignore + \def\doprocessEPSline + {\advance\scratchcounter\plusone + \expandafter\checkEPSboundingbox\fileline\empty\empty:.:.\end}% + \scratchcounter\zerocount + \doprocessfile\scratchread{#1}\doprocessEPSline + \egroup + % Using \EPSllx bp instead of \dimen0=1bp and \EPSllx\dimen0 is more accurate (.005pt). + \ifnum\EPSfound>\zerocount + #2\dimexpr\EPSllx\onebasepoint \relax + #3\dimexpr\EPSlly\onebasepoint \relax + #4\dimexpr\EPSurx\onebasepoint-#2\relax + #5\dimexpr\EPSury\onebasepoint-#3\relax + \else + #2\zeropoint + #3\zeropoint + #4\zeropoint + #5\zeropoint + \fi + %\message{[bbox #1: \EPSllx\space\EPSurx\space\EPSlly\space\EPSury]}\wait + \global\let\MPllx\EPSllx \global\let\MPlly\EPSlly + \global\let\MPurx\EPSurx \global\let\MPury\EPSury} + +\bgroup \catcode`\%=\@@other \xdef\letterpercent{\string%} \egroup + +\def\EPSboundingboxtag {BoundingBox} +\def\EPShiresboundingboxtag{HiResBoundingBox} +\def\EPSexactboundingboxtag{ExactBoundingBox} +\def\EPScreatortag {Creator} +\def\EPSmetaposttag {MetaPost} +\def\EPSmetapostspecialtag {MetaPostSpecial} +\def\EPSmetapostspecialstag{MetaPostSpecials} +\def\EPSpagetag {Page} + +\let\EPSspecialstring \empty +\let\EPSspecialcontent\empty + +% new metapost construct (hires bb followed by creator + version) +% +%!PS +%%BoundingBox: -71 -1 651 496 +%%HiResBoundingBox: -70.9945 -0.5 650.5 495.24907 +%%Creator: MetaPost 0.901 +%%CreationDate: 2005.06.02:1633 +%%Pages: 1 + +\long\def\checkEPSboundingbox#1#2#3:#4:.#5\end + {\if\string#1\letterpercent + \if\string#2\letterpercent + \edef\EPSspecialstring{#3}% + \edef\EPSspecialcontent{#4}% + \ifx\EPSspecialstring\EPScreatortag + \getEPScreatorspec + \else\ifx\EPSspecialstring\EPSboundingboxtag + \getEPSboundingboxspec + \global\chardef\EPSfound\plusone + \else\ifx\EPSspecialstring\EPShiresboundingboxtag + \getEPSboundingboxspec + \global\chardef\EPSfound\plustwo + \scratchcounter\zerocount + \else\ifx\EPSspecialstring\EPSexactboundingboxtag + \getEPSboundingboxspec + \global\chardef\EPSfound\plustwo + \scratchcounter\zerocount + \else\ifx\EPSspecialstring\EPSmetapostspecialtag % only before finish! + \global\chardef\EPSspecial\plusone % ah, we've met some MP extensions + \else\ifx\EPSspecialstring\EPSmetapostspecialstag % only before finish! + \global\chardef\EPSspecial\plusone % ah, we've met some MP extensions + \else\ifx\EPSspecialstring\EPSpagetag + \global\chardef\EPSstatus \plusone % we passed MP font defs + \else + \the\extraEPSpreambleparsers + \fi\fi\fi\fi\fi\fi\fi + \fi + \else\ifnum\EPSfound>\zerocount + % bb found + \ifnum\EPScreator=\plusone % that is, we are dealing with MP output + \ifcase\EPSstatus + % we've run into MP fontdefs + \or + \dofinishEPSfile + \fi + \else\ifnum\scratchcounter>\plusthree + % too late for mps creator (we don't want to run into crap data) + \dofinishEPSfile + \else + \fi\fi + \fi\fi} + +\def\getEPSboundingboxspec + {\edef\EPSspecialstring{\EPSspecialcontent\space . . . . }% + \expandafter\dogetEPSboundingboxspec\EPSspecialstring\end} + +\def\dogetEPSboundingboxspec#1 #2 #3 #4 #5\end + {\gdef\EPSllx{#1}% + \ifx\EPSllx\empty + \dogetEPSboundingboxspec#2 #3 #4 #5\end + \else + \gdef\EPSlly{#2}% + \gdef\EPSurx{#3}% + \gdef\EPSury{#4}% + \fi} + +\def\getEPScreatorspec + {\edef\EPSspecialstring{\EPSspecialcontent\space . .}% + \expandafter\dogetEPScreatorspec\EPSspecialstring\end} + +\def\dogetEPScreatorspec#1#2 #3\end + {\edef\EPScreatorstring{#1#2}% + \global\chardef\EPScreator\ifx\EPScreatorstring\EPSmetaposttag\plusone\else\zerocount\fi\relax} + +\def\dogetEPSpreambledata#1% can be combined with \extraEPSpreambleparsers + {\bgroup + \let\dofinishEPSfile\relax % dirty trick, read past all bboxes + \dogetEPSboundingbox{#1}\!!widtha\!!heighta\!!widthb\!!heightb + \egroup} + +\protect \endinput diff --git a/tex/context/base/supp-fil.lua b/tex/context/base/supp-fil.lua new file mode 100644 index 000000000..8d69f64a7 --- /dev/null +++ b/tex/context/base/supp-fil.lua @@ -0,0 +1,279 @@ +if not modules then modules = { } end modules ['supp-fil'] = { + version = 1.001, + comment = "companion to supp-fil.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--[[ldx-- +

It's more convenient to manipulate filenames (paths) in + than in . These methods have counterparts +at the side.

+--ldx]]-- + +local find, gsub, match, format, concat = string.find, string.gsub, string.match, string.format, table.concat +local texsprint, texwrite, ctxcatcodes = tex.sprint, tex.write, tex.ctxcatcodes + +local trace_modules = false trackers.register("modules.loading", function(v) trace_modules = v end) + +support = support or { } +environment = environment or { } + +environment.outputfilename = environment.outputfilename or environment.jobname + +function support.checkfilename(str) -- "/whatever..." "c:..." "http://..." + commands.chardef("kindoffile",boolean.tonumber(find(str,"^/") or find(str,"[%a]:"))) +end + +function support.thesanitizedfilename(str) + texwrite((gsub(str,"\\","/"))) +end + +function support.splitfilename(fullname) + local path, name, base, suffix, kind = '', fullname, fullname, '', 0 + local p, n = match(fullname,"^(.+)/(.-)$") + if p and n then + path, name, base = p, n, n + end + local b, s = match(base,"^(.+)%.(.-)$") + if b and s then + name, suffix = b, s + end + if path == "" then + kind = 0 + elseif path == '.' then + kind = 1 + else + kind = 2 + end + 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 = match(fullname,"^(.+)%.(.-)$") + if n and s then + name, suffix = n, s + end + commands.def("splitofffull", fullname) + commands.def("splitoffpath", "") + commands.def("splitoffname", name) + commands.def("splitofftype", suffix) +end + +function support.doifparentfileelse(n) + 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 + lastexistingfile = "" + else + lastexistingfile = resolvers.findtexfile(name) or "" + end + return commands.testcase(lastexistingfile ~= "") +end + +function support.lastexistingfile() + texsprint(ctxcatcodes,lastexistingfile) +end + +-- more, we can cache matches + +local finders, loaders, openers = resolvers.finders, resolvers.loaders, resolvers.openers + +local found = { } -- can best be done in the resolver itself + +-- todo: tracing + +local function readfilename(specification,backtrack,treetoo) + local fnd = found[specification] + if not fnd then + local splitspec = resolvers.splitmethod(specification) + local filename = splitspec.path or "" + if lfs.isfile(filename) then + fnd = filename + end + if not fnd and backtrack then + local fname = filename + for i=1,backtrack,1 do + fname = "../" .. fname + if lfs.isfile(fname) then + fnd = fname + break + end + end + end + if not fnd and treetoo then +--~ fnd = resolvers.find_file(filename) + fnd = resolvers.findtexfile(filename) + end + found[specification] = fnd + end + return fnd or "" +end + +support.readfilename = readfilename + +function finders.job(filename) return readfilename(filename,nil,false) end -- current path, no backtracking +function finders.loc(filename) return readfilename(filename,2, false) end -- current path, backtracking +function finders.sys(filename) return readfilename(filename,nil,true ) end -- current path, obeys tex search +function finders.fix(filename) return readfilename(filename,2, false) end -- specified path, backtracking +function finders.set(filename) return readfilename(filename,nil,false) end -- specified path, no backtracking +function finders.any(filename) return readfilename(filename,2, true ) end -- loc job sys + +openers.job = openers.generic loaders.job = loaders.generic +openers.loc = openers.generic loaders.loc = loaders.generic +openers.sys = openers.generic loaders.sys = loaders.generic +openers.fix = openers.generic loaders.fix = loaders.generic +openers.set = openers.generic loaders.set = loaders.generic +openers.any = openers.generic loaders.any = loaders.generic + +function support.doreadfile(protocol,path,name) -- better do a split and then pass table + local specification + if url.hasscheme(name) then + specification = name + else + specification = ((path == "") and format("%s:///%s",protocol,name)) or format("%s:///%s/%s",protocol,path,name) + end + texsprint(ctxcatcodes,resolvers.findtexfile(specification)) +end + +-- modules can only have a tex or mkiv suffix or can have a specified one + +local prefixes = { "m", "p", "s", "x", "t" } +local suffixes = { "tex", "mkiv" } +local modstatus = { } + +local function usemodule(name,hassheme) + local foundname + if hasscheme then + -- no auto suffix as http will return a home page or error page + -- so we only add one if missing + local fullname = file.addsuffix(name,"tex") + if trace_modules then + logs.report("modules","checking scheme driven file '%s'",fullname) + end + foundname = resolvers.findtexfile(fullname) or "" + elseif file.extname(name) ~= "" then + if trace_modules then + logs.report("modules","checking suffix driven file '%s'",name) + end + foundname = support.readfilename(name,false,true) or "" + else + for i=1,#suffixes do + local fullname = file.addsuffix(name,suffixes[i]) + if trace_modules then + logs.report("modules","checking suffix driven file '%s'",fullname) + end + foundname = support.readfilename(fullname,false,true) or "" + if foundname ~= "" then + break + end + end + end + if foundname ~= "" then + if trace_modules then + logs.report("modules","loading '%s'",foundname) + end + context.startreadingfile() + context.input(foundname) + context.stopreadingfile() + return true + else + return false + end +end + +function support.usemodules(prefix,askedname,truename) + local hasprefix = prefix and prefix ~= "" + local hashname = ((hasprefix and prefix) or "*") .. "-" .. truename + local status = modstatus[hashname] + if status == 0 then + -- not found + elseif status == 1 then + status = status + 1 + else + if trace_modules then + logs.report("modules","locating '%s'",truename) + end + local hasscheme = url.hasscheme(truename) + if hasscheme then + -- no prefix and suffix done + if usemodule(truename,true) then + status = 1 + else + status = 0 + end + elseif hasprefix then + if usemodule(prefix .. "-" .. truename) then + status = 1 + else + status = 0 + end + else + for i=1,#prefixes do + -- todo: reconstruct name i.e. basename + local thename = prefixes[i] .. "-" .. truename + if usemodule(thename) then + status = 1 + break + end + end + if status then + -- ok, don't change + elseif usemodule(truename) then + status = 1 + else + status = 0 + end + end + end + if status == 0 then + if trace_modules then + logs.report("modules","skipping '%s' (not found)",truename) + else + interfaces.showmessage("systems",6,askedname) + end + elseif status == 1 then + if not trace_modules then + interfaces.showmessage("systems",5,askedname) + end + else + if trace_modules then + logs.report("modules","skipping '%s' (already loaded)",truename) + else + interfaces.showmessage("systems",7,askedname) + end + end + modstatus[hashname] = status +end + +statistics.register("loaded tex modules", function() + if next(modstatus) then + local t, f = { }, { } + for k, v in table.sortedhash(modstatus) do + k = file.basename(k) + if v == 0 then + f[#f+1] = k + else + t[#t+1] = k + end + end + local ts = (#t>0 and format(" (%s)",concat(t," "))) or "" + local fs = (#f>0 and format(" (%s)",concat(f," "))) or "" + return format("%s requested, %s found%s, %s missing%s",#t+#f,#t,ts,#f,fs) + else + return nil + end +end) diff --git a/tex/context/base/supp-fil.mkii b/tex/context/base/supp-fil.mkii new file mode 100644 index 000000000..fc0492442 --- /dev/null +++ b/tex/context/base/supp-fil.mkii @@ -0,0 +1,710 @@ +%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 + +\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 {/}. + +\bgroup % todo: _ cleanup + +\catcode`\/=\@@active +\catcode`\:=\@@active +\catcode`\~=\@@active +\catcode`\_=\@@active + +\gdef\sanitizefilename#1\to#2% + {\bgroup + \edef/{\string/}% + \edef:{\string:}% + \edef~{\string~}% + \edef_{\string_}% + \retainlccodes + \lccode`\\=`\/ + \lowercase{\expanded{\xdef\noexpand\sanitizedfilename{#1}}}% + \egroup + \let#2\sanitizedfilename} + +\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} + {\doifinstringelse{:/}{#1}% windows: e:/full/path or http:// + {\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} + +\ifdefined\xmlcatcodes \else \let\xmlcatcodes\xmlcatcodesn \fi + +\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 +% \ifx\splitoffbase\empty +% \let\splitoffpath\empty +% \let\splitoffbase\splitofffull +% \fi +% \greedysplitstring\splitoffbase\at.\to\splitoffname\and\splitofftype +% \chardef\splitoffkind % can be used to test if pathpart was empty +% \ifx\splitoffpath\empty \zerocount \else +% \ifx\splitoffpath\splitoffroot \plusone \else +% \plustwo \fi\fi +% \ifx\splitoffname\empty\let\splitoffname\splitoffbase\fi +% \ifx\splitoffpath\empty\let\splitoffpath\splitoffroot\fi} +% +% better, since it also handles leading /'s +% +% \splitfilename{oeps/test.pdf} [\splitoffpath\quad\splitoffname\quad\splitofftype] +% \splitfilename{/oeps/test.pdf} [\splitoffpath\quad\splitoffname\quad\splitofftype] +% \splitfilename{/test.pdf} [\splitoffpath\quad\splitoffname\quad\splitofftype] + +\def\splitfilename#1% + {\edef\splitofffull{#1}% normally outside this call: \sanitizefilename#1\to\sanitizedfilename + \greedysplitstring\splitofffull\at/\to\splitoffpath\and\splitoffbase + \ifx\splitoffpath\splitofffull + \let\splitoffpath\empty + \fi + \ifx\splitoffbase\empty + \let\splitoffpath\empty + \let\splitoffbase\splitofffull + \fi + \greedysplitstring\splitoffbase\at.\to\splitoffname\and\splitofftype + \chardef\splitoffkind % can be used to test if pathpart was empty + \ifx\splitoffpath\empty \zerocount \else + \ifx\splitoffpath\splitoffroot \plusone \else + \plustwo \fi\fi + \ifx\splitoffname\empty\let\splitoffname\splitoffbase\fi + \ifx\splitoffpath\empty\let\splitoffpath\splitoffroot\fi} + +\def\splitfiletype#1% + {\edef\splitofffull{#1}% normally outside this call: \sanitizefilename#1\to\sanitizedfilename + \let\splitoffpath\empty + \greedysplitstring\splitofffull\at.\to\splitoffname\and\splitofftype} + +\protect \endinput diff --git a/tex/context/base/supp-fil.mkiv b/tex/context/base/supp-fil.mkiv new file mode 100644 index 000000000..872612eab --- /dev/null +++ b/tex/context/base/supp-fil.mkiv @@ -0,0 +1,464 @@ +%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} + +\registerctxluafile{supp-fil}{1.001} + +\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]])}}} + +%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} +%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 (on the commandline using a directive); we default to~3. +%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 + +\def\maxreadlevel{\ctxlua{commands.maxreadlevel()}} + +% 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% protocol path filename true false + {\edef\readfilename{\ctxlua{support.doreadfile("#1","#2","#3")}}% + \ifx\readfilename\empty + \expandafter\doreadfilenop + \else + \expandafter\doreadfileyes + \fi} + +\long\def\doreadfileyes#1#2% + {#1\relax + \the\everybeforereadfile + \relax\inputgivenfile\readfilename\relax + \the\everyafterreadfile} + +\long\def\doreadfilenop#1#2% + {#2} + +%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\maxreadlevel\ directories, including the current +%D one. +%D +%D System files can be anywhere and therefore +%D \type{\readsysfile} is not bound to the current directory +%D and obeys the \TEX\ implementation. +%D +%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. +%D +%D The most liberal is \type {\readfile}. + +\unexpanded\def\readjobfile #1{\doreadfile{job} {.}{#1}} % current path, no backtracking +\unexpanded\def\readlocfile #1{\doreadfile{loc} {.}{#1}} % current path, backtracking +\unexpanded\def\readsysfile #1{\doreadfile{sys} {.}{#1}} % current path, obeys tex search +\unexpanded\def\readfixfile#1#2{\doreadfile{fix}{#1}{#2}} % specified path, backtracking +\unexpanded\def\readsetfile#1#2{\doreadfile{set}{#1}{#2}} % specified path, no backtracking +\unexpanded\def\readfile #1{\doreadfile{any} {.}{#1}} +\unexpanded\def\ReadFile #1{\doreadfile{any} {.}{#1}\donothing\donothing} + +%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 + +\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} + +%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]])}} + +\newcount\readingfilelevel + +%D We need to redo this: catcode sets and such + +\newtoks \everystartreadingfile +\newtoks \everystopreadingfile + +\unexpanded\def\startreadingfile% beter een every en \setnormalcatcodes + {\global\advance\readingfilelevel\plusone + \the\everystartreadingfile + \beginrestorecatcodes + \setcatcodetable\prtcatcodes} + +\unexpanded\def\stopreadingfile + {\endrestorecatcodes + \the\everystopreadingfile + \global\advance\readingfilelevel\minusone} + +%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-fun.tex b/tex/context/base/supp-fun.tex new file mode 100644 index 000000000..6b2643703 --- /dev/null +++ b/tex/context/base/supp-fun.tex @@ -0,0 +1,746 @@ +%D \module +%D [ file=supp-fun, +%D version=1995.10.10, +%D title=\CONTEXT\ Support Macros, +%D subtitle=Fun Stuff, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\unprotect + +%D This module implements some typographics tricks that can +%D be fun when designing document layouts. The examples use +%D macros that are typical to \CONTEXT, but non \CONTEXT\ +%D users can use the drop caps and first line treatment +%D macros without problems. This module will be extended +%D when the need for more of such tricks arises. + +\ifx \undefined \writestatus \input supp-mis.tex \relax \fi + +\writestatus{loading}{ConTeXt Support Macros / Fun Stuff} + +\ifx\definefont\undefined + \def\definedfont[#1]{\font\temp#1\relax\temp} +\fi + +%D \macros +%D {DroppedCaps, DroppedString, DroppedIndent, DroppedLines} +%D +%D \startbuffer +%D \DroppedCaps +%D {\color[green]} {cmbx12} +%D {2.2\baselineskip} {2pt} {\baselineskip} {2} +%D Let's start +%D \stopbuffer +%D +%D \getbuffer with dropped caps, those blown up first +%D characters of a paragraph. It's hard to implement a general +%D mechanism that suits all situations, but dropped caps are so +%D seldomly used that we can permit ourselves a rather user +%D unfriendly implementation. +%D +%D \typebuffer +%D +%D As we will see, there are 7 different settings involved. The +%D first argument takes a command that is used to do whatever +%D fancy things we want to do, but normally this one will be +%D empty. The second argument takes the font. Because we're +%D dealing with something very typographic, there is no real +%D reason to adopt complicated font switching schemes, a mere +%D name will do. Font encodings can bring no harm, because the +%D alphanumeric characters are nearly always located at their +%D natural position in the encoding vector. +%D +%D \startbuffer +%D \DroppedCaps +%D {\color[red]} {cmbx12} +%D {\baselineskip} {0pt} {0pt} {1} +%D This simple +%D \stopbuffer +%D +%D \getbuffer case shows us what happens when we apply minimal +%D values. Here we used: +%D +%D \typebuffer +%D +%D \startbuffer +%D \DroppedCaps +%D {\color[red]} {cmbx12} +%D {2\baselineskip} {0pt} {\baselineskip} {2} +%D Is this ugly +%D \stopbuffer +%D +%D \getbuffer example the third argument tells +%D this macro that we want a dropped capital scaled to the +%D baseline distance. The two zero point arguments are the +%D horizontal and vertical offsets and the last arguments +%D determines the hanging indentation. In this paragraph we +%D set the height to two times the baselinedistance and use +%D two hanging lines: +%D +%D \typebuffer +%D +%D Here, the first character is moved down one baseline. Here +%D we also see why the horizontal offset is important. The +%D first example (showing the~L) sets this to a few points and +%D also used a slightly larger height. +%D +%D Of course common users (typist) are not supposed to see this +%D kind of fuzzy definitions, but fortunately \TEX\ permits us +%D to hide them in macros. Using a macro also enables us to +%D garantee consistency throughout the document: +%D +%D \startbuffer +%D \def\MyDroppedCaps% +%D {\DroppedCaps +%D {\color[green]} {cmbx12} +%D {5\baselineskip} {3pt} {3\baselineskip} {4}} +%D +%D \MyDroppedCaps The implementation +%D \stopbuffer +%D +%D \typebuffer +%D +%D \getbuffer of the general macro is rather simple and only +%D depends on the arguments given and the dimensions of the +%D strut box. We explicitly load the font, which is no problem +%D because \TEX\ does not load a font twice. We could have +%D combined some arguments, like the height, vertical offset +%D and the number of lines, but the current implementation +%D proved to be the most flexible. One should be aware of the +%D fact that the offsets depend on the design of the glyphs +%D used. + +\let\DroppedIndent\!!zeropoint \def\DroppedLines{0} + +\def\DroppedString{ABCDEFGHIJKLMNOPQRSTUVWXYZ} + +\let\globaldropcaps\global % will be an option, but on by default + +\def\localdropcaps{\let\globaldropcaps\relax} + +\chardef\DroppedStatus = 0 % 0=done 1=starting 2=doing 3=error +\chardef\DropMode = 0 % 1 == marginhang + +\ifx\keeplinestogether\undefined + \let\keeplinestogether\gobbleoneargument +\fi + +\def\DroppedCaps#1#2#3#4#5#6#7% does not yet handle accented chars + {\defconvertedargument\asciia{#7}% + \defconvertedcommand \asciib{\DroppedString}% + \ExpandBothAfter\doifinstringelse\asciia\asciib + {\noindentation + \dontleavehmode + \checkindentation % redo this one + %\ifhmode\hskip-\parindent\fi % sensitive for context mechanism + \keeplinestogether{#6}% + \setbox0\hbox{\definedfont[#2 at #3]#1{#7}\hskip#4}% + \ifdim\dp0>\strutdp % one of those Q's , will be option + \setbox2\hbox{\raise\dp0\hbox{\lower\strutdp\copy0}}% + \ht2\ht0 + \dp0\strutdp + \setbox0\box2 + \fi + \setbox0\hbox + {\ifnum\DropMode=\plusone + \hskip-\wd0\wd0\zeropoint + \fi + \lower#5\box0}% + \ht0\strutht + \dp0\strutdp + \ifnum\DropMode=\plusone + \globaldropcaps\let\DroppedIndent\!!zeropoint + \globaldropcaps\edef\DroppedLines{\number\maxdimen}% + \globaldropcaps\chardef\DroppedStatus\plusthree + \else + \globaldropcaps\edef\DroppedIndent{\the\wd0}% + \globaldropcaps\edef\DroppedLines {\number#6}% + \globaldropcaps\chardef\DroppedStatus\plustwo + \globaldropcaps\hangindent\DroppedIndent + \globaldropcaps\hangafter-\DroppedLines +% \noindent + \noindentation + \checkindentation % redo this one + \hskip-\DroppedIndent + \fi + \vbox{\forgetall\box0}% + \nobreak + \let\next\ignorespaces} % Could be a one character word ! + {\globaldropcaps\let\DroppedIndent\!!zeropoint + \globaldropcaps\edef\DroppedLines{\number\maxdimen}% + \globaldropcaps\chardef\DroppedStatus\plusthree + \def\next{#7}}% + \let\globaldropcaps\global + \next} + +%D Before we go to the next topic, we summarize this command: +%D +%D \starttyping +%D \DroppedCaps +%D {command} {font} +%D {height} {hoffset} {voffset} {lines} +%D \stoptyping +%D +%D Sometimes you need to make sure that the global settings are +%D kept local, as in: +%D +% %D \startbuffer +% %D \defineparagraphs[SomePar][n=2,rule=on] +% %D \setupparagraphs [SomePar][1][width=.5\textwidth] +% %D \setupparagraphs [SomePar][2][width=.5\textwidth] +%D \startbuffer +%D \defineparagraphs[SomePar][n=2,rule=on] +%D \setupparagraphs [SomePar][1][width=.5\textwidth] +%D \setupparagraphs [SomePar][2][width=.5\textwidth] +%D +%D \startSomePar +%D \localdropcaps\NiceDroppedCaps{}{cmr12}{0pt}{2}Here we need +%D to explicitly keep the hanging indentation local, like it or +%D not. +%D \SomePar +%D \localdropcaps\NiceDroppedCaps{}{cmr12}{0pt}{2}Here we need +%D to explicitly keep the hanging indentation local, like it or +%D not. +%D \stopSomePar +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +%D \macros +%D {AutoDroppedCaps, CheckDroppedCaps} +%D +%D {\em To be documented.} + +% example usage +% +% \def\bpar{\ifvmode\CheckDroppedCaps\fi} +% \def\epar{\ifhmode\par\fi\CheckDroppedCaps} + +\newcount\lastprevgraf +\newcount\droppedlines + +\def\CheckDroppedCaps + {\global\lastprevgraf\prevgraf} + +\def\AutoDroppedCaps % will be proper core stuff since it + {\globaldropcaps\chardef\DroppedStatus\plusone + \global\lastprevgraf\zerocount + \global\droppedlines\zerocount + \EveryPar{\doAutoDroppedCaps}} + +\let\AutoDroppedNext\relax + +\ifx\AutoDroppedCapsCommand\undefined + \def\AutoDroppedCapsCommand{\NiceDroppedCaps{}{SerifBold}{.125em}{3}} +\fi + +\def\doAutoDroppedCaps + {\ifcase\DroppedStatus % done + \let\next\relax + \or % starting + % \ifnum\lastprevgraf>0 % tricky, probably a wrong par + % \globaldropcaps\chardef\DroppedStatus=3 % and inhibits dropped + % \let\next\relax % caps after titles and more than once + % \else % so let's nill this rubishly code fragment + \let\next\AutoDroppedCapsCommand + % \fi % and hope for the best + \or % doing + \global\advance\droppedlines \lastprevgraf + \ifnum\droppedlines=\zerocount + \globaldropcaps\chardef\DroppedStatus\zerocount + \let\next\relax + \else\ifnum\droppedlines>\zerocount + \ifnum\droppedlines<\DroppedLines\relax + \globaldropcaps\hangindent\DroppedIndent + \globaldropcaps\hangafter-\DroppedLines + \globaldropcaps\advance\hangafter \droppedlines + \hskip-\parindent % brrr + \let\next\AutoDroppedNext + \else + \globaldropcaps\chardef\DroppedStatus\zerocount + \let\next\relax + \fi + \else + \globaldropcaps\chardef\DroppedStatus\zerocount + \let\next\relax + \fi\fi + \or % error + \globaldropcaps\chardef\DroppedStatus\zerocount + \let\next\relax + \fi + \next} + +%D \macros +%D {LineDroppedCaps, NiceDroppedCaps} +%D +%D To save definitions, we also provide: +%D +%D \starttyping +%D \LineDroppedCaps {command} {font} {hoffset} {lines} +%D \NiceDroppedCaps {command} {font} {hoffset} {lines} +%D \stoptyping +%D +%D The first command scales the font to the exact height, while +%D the second command scales the font to a nice 2.5 times the +%D line height, a value that gives a pleasant grayness. + +\def\DoLineDroppedCaps#1#2#3#4#5% compensation command font offset lines + {\scratchcounter#5% + \advance\scratchcounter \minusone + \scratchdimen\scratchcounter\baselineskip + \advance\scratchdimen #1% + \NormalizeFontHeight\DummyFont{W}\scratchdimen{#3}% + \DroppedCaps{#2}{#3}\TheNormalizedFontSize{#4} + {\scratchcounter\baselineskip}{#5}} + +\def\LineDroppedCaps% command font offset lines + {\DoLineDroppedCaps{\strutht}} + +\def\NiceDroppedCaps% command font offset lines + {\DoLineDroppedCaps{.5\baselineskip}} + +%D \macros +%D {TreatFirstLine} +%D +%D \startbuffer +%D \TreatFirstLine {\sc} {} {} {} +%D Instead of limiting its action to one token, the next macro +%D treats the whole first line. This paragraph was typeset by +%D saying: +%D \stopbuffer +%D +%D \getbuffer +%D +%D \typebuffer +%D +%D \startbuffer +%D \TreatFirstLine {\startcolor[red]\bf} {\stopcolor} {} {} +%D The combined color and font effect is also possible, +%D although one must be careful in using macros that accumulate +%D grouping, but the commands used here are pretty save in that +%D respect. +%D \stopbuffer +%D +%D \getbuffer +%D +%D \typebuffer +%D +%D Before we explain the third and fourth argument, we show the +%D implementation. Those who know a bit about the way \TEX\ +%D treats tokens, will probably see in one glance that this +%D alternative works all right for most text||only situations +%D in which there is enough text available for the first line, +%D but that more complicated things will blow. One has to live +%D with that. A workaround is rather trivial but obscures the +%D principles used. + +\def\TreatFirstLine#1#2#3#4% before, after, first, next + {\leavevmode + \bgroup + \forgetall + \bgroup + #1% + \setbox0\emptybox + \setbox2\emptybox + \def\grabfirstline##1 % + {\setbox2\hbox + {\ifvoid0 + {#3{\ignorespaces##1}}% + \else + \unhcopy0\ {#4{##1}}% + \fi}% + \ifdim\wd2=\zeropoint + \setbox0\emptybox + \setbox2\emptybox + \@EA\grabfirstline + \else\ifdim\wd2>\hsize + \hbox to \hsize{\strut\unhbox0}#2\egroup + \break##1\ + \egroup + \else + \setbox0\box2 + \@EAEAEA\grabfirstline + \fi\fi}% + \grabfirstline} + +%D \startbuffer +%D \gdef\FunnyCommand +%D {\getrandomfloat\FunnyR{0}{1}% +%D \getrandomfloat\FunnyG{0}{1}% +%D \getrandomfloat\FunnyB{0}{1}% +%D \definecolor[FunnyColor][r=\FunnyR,g=\FunnyG,b=\FunnyB]% +%D \color[FunnyColor]} +%D +%D %\TreatFirstLine {\bf} {} {\FunnyCommand} {\FunnyCommand} +%D The third and fourth argument can be used to gain special +%D effects on the individual words. Of course one needs ... +%D \stopbuffer +%D +%D \getbuffer +%D to know a bit more about the macro package used to get real +%D nice effects, but this example probably demonstrates the +%D principles well. +%D +%D \typebuffer +%D +%D Like in dropped caps case, one can hide such treatments in a +%D macro, like: +%D +%D \starttyping +%D \def\MyTreatFirstLine% +%D {\TreatFirstLine{\bf}{}{\FunnyCommand}{\FunnyCommand}} +%D \stoptyping + +%D \macros +%D {reshapebox} +%D +%D \startbuffer +%D \beginofshapebox +%D When using \CONTEXT, one can also apply this funny command +%D to whole lines by using the reshape mechanism. Describing +%D this interesting mechanism falls outside the scope of this +%D module, so we only show the trick. This is an example of +%D low level \CONTEXT\ functionality: it's all there, and it's +%D stable, but not entirely meant for novice users. +%D \endofshapebox +%D +%D \reshapebox{\FunnyCommand{\box\shapebox}} \flushshapebox +%D \stopbuffer +%D +%D \getbuffer +%D +%D \typebuffer +%D +%D This mechanism permits hyphenation and therefore gives +%D better results than the previously discussed macro +%D \type{\TreatFirstLine}. + +%D \macros +%D {TreatFirstCharacter} +%D +%D \startbuffer +%D \TreatFirstCharacter{\bf\color[green]} Just to be +%D \stopbuffer +%D +%D \getbuffer complete we also offer a very simple one +%D character alternative, that is not that hard to understand: + +\def\TreatFirstCharacter#1#2% command, character + {{#1{#2}}} + +%D A previous paragraph started with: +%D +%D \typebuffer + +%D \macros +%D {StackCharacters} +%D +%D The next hack deals with vertical stacking. + +\def\StackCharacters#1#2#3#4% sequence vsize vskip command + {\vbox #2 + {\forgetall + \baselineskip\zeropoint + \def\StackCharacter##1{#4{##1}\cr\noalign{#3}}% + \halign + {\hss##\hss&##\cr + \handletokens#1\with\StackCharacter\cr}}} + +%D \startbuffer +%D \StackCharacters{CONTEXT}{}{\vskip.2ex}{\FunnyCommand} +%D \stopbuffer +%D +%D Such a stack looks like: +%D +%D \startlinecorrection +%D \hbox to \hsize +%D {$\hss\bfd +%D \vcenter{\StackCharacters{TEX} {}{\vskip.2ex}{\FunnyCommand}}% +%D \hss +%D \vcenter{\StackCharacters{CON} {}{\vskip.2ex}{\FunnyCommand}} +%D \hss +%D \vcenter{\StackCharacters{TEXT} {}{\vskip.2ex}{\FunnyCommand}} +%D \hss +%D \vcenter{\StackCharacters{CONTEXT}{}{\vskip.2ex}{\FunnyCommand}} +%D \hss$} +%D \stoplinecorrection +%D +%D and is typeset by saying: +%D +%D \typebuffer +%D +%D An alternative would have been +%D +%D \starttyping +%D \StackCharacters {CONTEXT} {to 5cm} {\vfill} {\FunnyCommand} +%D \stoptyping + +%D \macros +%D {processtokens} +%D +%D At a lower level horizontal and vertical manipulations are +%D already supported by: +%D +%D \starttyping +%D \processtokens {begin} {between} {end} {space} {text} +%D \stoptyping +%D +%D \startbuffer[a] +%D \processtokens +%D {\hbox to .5\hsize\bgroup} {\hfill} +%D {\egroup} {\space} {LET'S HAVE} +%D \stopbuffer +%D +%D \startbuffer[b] +%D \processtokens +%D {\vbox\bgroup\raggedcenter\hsize1em} +%D {\vskip.25ex} {\egroup} {\strut} {FUN} +%D \stopbuffer +%D +%D This macro is able to typeset: +%D +%D \leavevmode\hbox to \hsize +%D {$\hfil\hfil +%D \vcenter{\bf\getbuffer[a]}% +%D \hfil +%D \vcenter{\bfd\getbuffer[b]}% +%D \hfil\hfil$} +%D +%D which was specified as: +%D +%D \typebuffer[a] +%D \typebuffer[b] + +%D \macros +%D {NormalizeFontHeight, NormalizeFontWidth, +%D TheNormalizedFontSize} +%D +%D Next we introduce some font manipulation macros. When we +%D want to typeset some text spread in a well defined area, it +%D can be considered bad practice to manipulate character and +%D word spacing. In such situations the next few macros can be +%D of help: +%D +%D \starttyping +%D \NormalizeFontHeight \name {sample text} {height} {font} +%D \NormalizeFontWidth \name {sample text} {width} {font} +%D \stoptyping +%D +%D These are implemented using an auxilliary macro: + +\def\NormalizeFontHeight{\NormalizeFontSize\ht} +\def\NormalizeFontWidth {\NormalizeFontSize\wd} + +% \def\NormalizeFontSize#1#2#3#4#5% +% {\bgroup +% \dimen0=#4% #4 can be \ht0 or so +% \setbox0\hbox{\definedfont[#5 at 10pt]#3}% +% \ifdim\wd0>\zeropoint +% \dimen2=#10 % #1 is \wd or \ht +% \dimen4=10000pt +% \divide\dimen4 \dimen2 +% \divide\dimen0 \plusthousand +% \dimen0=\number\dimen4\dimen0 +% \xdef\TheNormalizedFontSize{\the\dimen0}% +% \else +% \dimen0\bodyfontsize +% \fi +% \definedfont[#5 at \the\dimen0]% +% \expandafter +% \egroup +% \expandafter\font\expandafter#2\fontname\font\relax} +% +% the familiar struggle with accuracy forces us to use: + +\def\NormalizeFontSize#1#2#3#4#5% + {\bgroup + \dimen0=#4% #4 can be \ht0 or so + \setbox0\hbox{\definedfont[#5 at 5pt]#3}% 10pt + \ifdim\wd0>\zeropoint + \dimen2=#10 % #1 is \wd or \ht + \dimen4=\maxdimen % 10000pt + \divide\dimen4 \dimen2 + \divide\dimen0 1638 % 1000 + \dimen0=\number\dimen4\dimen0 + \divide \dimen0 \plustwo % ... + \xdef\TheNormalizedFontSize{\the\dimen0}% + \else + \dimen0\bodyfontsize + \fi + % mkii + % \definedfont[#5 at \the\dimen0]% + % \expandafter + % \egroup + % \expandafter\font\expandafter#2\fontname\font\relax} + % mkiv safe (file: prefix etc) + \expanded{\egroup\def\noexpand#2{\definedfont[#5 at \the\dimen0]}}} + +%D Afterwards, we have access to the calculated size by: + +\let\TheNormalizedFontSize\!!zeropoint + +%D Extra: + +\def\WidthSpanningText#1#2#3% text width font + {\hbox{\NormalizeFontWidth\temp{#1}{#2}{#3}\temp\the\everydefinedfont#1}} + +%D Consider for instance: +%D +%D \startbuffer +%D \NormalizeFontHeight \tmp {X} {2\baselineskip} {cmr10} +%D +%D {\tmp To Be Or Not To Be} +%D \stopbuffer +%D +%D \typebuffer +%D +%D This shows up as (we also show the baselines): +%D +%D {\showbaselines\getbuffer} +%D +%D The horizontal counterpart is: +%D +%D \startbuffer +%D \NormalizeFontWidth \tmp {This Line Fits} {\hsize} {cmr10} +%D +%D \hbox{\tmp This Line Fits} +%D \stopbuffer +%D +%D \typebuffer +%D +%D The calculated font scale is avaliable in the macro +%D \type{\NormalizedFontSize}. +%D +%D \startlinecorrection +%D \ruledhbox{\getbuffer} +%D \stoplinecorrection +%D +%D One can of course combine these macros with the ones +%D described earlier, like in: +%D +%D \starttyping +%D \NormalizeFontHeight {text} \DroppedFont {2\baselineskip} {cmbx12} +%D +%D \def\NicelyDroppedCaps +%D {\DroppedCaps +%D {\color[green]} +%D {\DroppedFont} +%D {2pt} +%D {\baselineskip} +%D {2}} +%D \stoptyping +%D +%D It's up to the reader to test this one. + +\unexpanded\def\FirstNCharacters#1#2% \FirstNCharacters{3}{fr{\"o}beln} + {\bgroup + \scratchcounter\zerocount + \def\docommand##1% + {\ifnum\scratchcounter=#1\else + ##1\relax % catches ##1 = \"e and alike + \advance\scratchcounter\plusone + \fi} + \handletokens#2\with\docommand + \egroup} + +%D \macros +%D {FittingText} +%D +%D First used in Pascal (demo-bbv): +%D +%D \startbuffer +%D \ruledvbox{\FittingText{3cm}{1cm}{Serif}{24pt}{1pt}{1} +%D {\veryraggedright +%D \hangindent1em\hangafter1\relax +%D \begstrut \dorecurse{8}{Bram Marta }\unskip \endstrut}} +%D +%D \ruledvbox{\FittingText{3cm}{1cm}{Serif}{24pt}{1pt}{1} +%D {\raggedleft\begstrut Bram\\Marta \unskip\endstrut}} +%D \stopbuffer +%D +%D \typebuffer +%D +%D \startlinecorrection +%D \getbuffer +%D \stoplinecorrection + +% #1 width #2 height #3 font #4 size #5 step #6 interlinie #7 text + +\long\def\FittingText#1#2#3#4#5#6#7% + {\bgroup + \forgetall + \dontcomplain + \setuptolerance[\v!verytolerant]% == \tolerance4500 + \hsize#1% + \def\\{\softbreak}% + \!!heighta#4% + \!!heightb#2% + \doloop + {\ifdim\!!heighta>\onepoint + \expanded{\definefont[\s!dummy][#3 at \the\!!heighta][\c!interlinespace=#6]}% + \getvalue\s!dummy + \setbox\scratchbox\vbox{#7\endgraf}% + \ifdim\ht\scratchbox>\!!heightb + \advance\!!heighta-#5% + \else + \beginshapebox + \unvcopy\scratchbox + \endshapebox + \global\dimen1\hsize + \reshapebox + {\setbox\shapebox\hbox{\unhbox\shapebox}% + \ifdim\wd\shapebox>\dimen1 + \global\dimen1\wd\shapebox + \fi}% + \ifdim\dimen1>\hsize + \advance\!!heighta-#5% + \else + \exitloop + \fi + \fi + \else + \exitloop + \fi}% + %\writestatus{\strippedcsname\FittingText}{height: \the\!!heighta}% + \unvbox\scratchbox + \egroup} + +%D New: + +% \font width gap font spec text + +\def\NormalizeFontWidthSpread#1#2#3#4#5#6% + {\global\setfalse\NFSpread + \scratchdimen#3% + \scratchdimen-.5\scratchdimen + \advance\scratchdimen#2\relax + \NormalizeFontWidth + #1% + {\def\+{\global\settrue\NFSpread\gobbleuntil\relax}% + \def\\{\gobbleuntil\relax}% newline + \setupspacing + #6\relax}% + {\scratchdimen}% + {#4}% + \ifconditional\NFSpread + % de gap valt in de binding + \else + \definefont[\strippedcsname#1][#4 #5]% + \fi} + +\def\SpreadGapText#1#2% + {{\def\+{\kern#1}#2}} + +\def\GapText#1#2#3#4#5% width distance font spec title + {\bgroup + \NormalizeFontWidthSpread\DummyFont{#1}{#2}{#3}{#4}{#5}% + \DummyFont\setupspacing\SpreadGapText{#2}{#5}\endgraf + \egroup} + +\protect \endinput diff --git a/tex/context/base/supp-mat.mkii b/tex/context/base/supp-mat.mkii new file mode 100644 index 000000000..1a51164e6 --- /dev/null +++ b/tex/context/base/supp-mat.mkii @@ -0,0 +1,293 @@ +%D \module +%D [ file=supp-mat, +%D version=1998.09.10, +%D title=\CONTEXT\ Support Macros, +%D subtitle=Math, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D For practical reasons, I decided to move some math things to +%D a support module. There is nothing spectacular here. It may move +%D back to math-ini. + +\writestatus{loading}{ConTeXt Support Macros / Math} + +\unprotect + +%D \macros +%D {mathematics, math, nomathematics, startmathmode} +%D +%D The \type{$} can be both an begin and end math character. +%D This can lead to confusing and errorprone situations when +%D macros insert \type{$}. When for instance we have defined: +%D +%D \starttyping +%D \def\MyPlus{$\,+\,$} +%D \stoptyping +%D +%D the sequence \type{$x^2 \MyPlus y^2 = r^2$} will expand to: +%D +%D \starttyping +%D $x^2 $\,+\,$ y^2 = r^2$ +%D \stoptyping +%D +%D Here the \type{\,} are given outside math mode and \TEX\ will +%D definitely complain about this. A more save definition would +%D have been: +%D +%D \starttyping +%D \def\MyPlus{\mathematics{\,+\,}} +%D \stoptyping +%D +%D Which is implemented as: + +\long\def\mathematics#1{\relax\ifmmode#1\else $#1$\fi} % lookahead bug reported by brooks +\long\def\displaymath#1{\relax\ifmmode#1\else$$#1$$\fi} +\long\def\inlinemath #1{\dontleavehmode\relax\ifmmode#1\else $#1$\fi} + +\let\stopmathmode\relax + +\def\startmathmode % cannot be used nested + {\relax\ifmmode + \let\stopmathmode\relax + \else + $\def\stopmathmode{$}% \let\stopmathmode=$ + \fi} + +\def\startmathmode % nested variant + {\relax\ifmmode + \begingroup\let\stopmathmode\endgroup + \else + $\let\stopmathmode$% + \fi} + +\def\nomathematics#1% + {\relax\ifmmode\hbox{#1}\else#1\fi} + +\let\math\mathematics + +%D \macros +%D {displaymathematics,inlinemathematics,automathematics} +%D +%D An example of usage of the following can be found in the MathML module: + +\long\def\displaymathematics#1{\relax\ifmmode#1\else\dostartformula{}#1\dostopformula\fi} + \def\inlinemathematics {\dontleavehmode\mathematics} + \def\automathematics {\relax\ifhmode\@EA\inlinemathematics\else\@EA\displaymathematics\fi} + +% better, esp when used in bTABLE ... eTABLE + +\def\automathematics + {\relax + \ifhmode + \expandafter\inlinemathematics + \else\ifintable + \expandafter\expandafter\expandafter\inlinemathematics + \else + \expandafter\expandafter\expandafter\displaymathematics + \fi\fi} + +%D \macros +%D {dimension, nodimension} +%D +%D The next few macros are used for typesetting dimensions in +%D such a way that spacing is acceptable. I won't spend much +%D words on these macros, because they will be overloaded in +%D the units module. + +\newsignal\dimensionsignal + +\def\dimensiontypeface {\tf} +\def\dimensionhalfspace {\,} + +\unexpanded\def\dimension#1% + {\def\dodimensionsignal{\kern\dimensionsignal}% + \ifdim\lastskip=\zeropoint\relax + \ifdim\lastkern=\zeropoint\relax + \ifmmode + \mathematics{\dimensionhalfspace\dimensionhalfspace\dimensiontypeface#1}% + \else + \mathematics{\dimensiontypeface#1}% + \fi + \else\ifdim\lastkern=\dimensionsignal + \mathematics{\dimensionhalfspace\dimensiontypeface#1}% + \else + \unkern\mathematics{\dimensionhalfspace\dimensionhalfspace\dimensiontypeface#1}% + \fi\fi + \else + \unskip\mathematics{\dimensionhalfspace\dimensionhalfspace\dimensiontypeface#1}% + \fi + \dodimensionsignal} + +\unexpanded\def\nodimension#1% + {\unskip#1\global\let\dodimensionsignal\relax} + +%D \macros +%D {super, suber} +%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{\suber} (\type {\sub} is already taken). + +\global\let\normalsuper=^ +\global\let\normalsuber=_ + +\newcount\supersubmode + +\newevery\everysupersub \EverySuperSub + +\appendtoks \advance\supersubmode 1\relax \to \everysupersub + +% \def\dodosuper#1{\normalsuper{\the\everysupersub#1}} +% \def\dodosuber#1{\normalsuber{\the\everysupersub#1}} +% +% \def\dosuper{\ifx\next\bgroup\expandafter\dodosuper\else\normalsuper\fi} +% \def\dosuber{\ifx\next\bgroup\expandafter\dodosuber\else\normalsuber\fi} +% +% \def\super{\futurelet\next\dosuper} +% \def\suber{\futurelet\next\dosuber} + +\def\super#1{\normalsuper{\the\everysupersub#1}} +\def\suber#1{\normalsuber{\the\everysupersub#1}} + +%D \macros +%D {enablesupsub} +%D +%D We can let \type {^} and \type {_} act like \type {\super} +%D and \type {\suber} by saying \type {\enablesupsub}. + +\bgroup +\catcode`\^=\@@active +\catcode`\_=\@@active +\gdef\enablesupsub + {\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\supsubmode + \textstyle + \or + \scriptstyle + \else + \scriptscriptstyle + \fi + \fi} + +%D \macros +%D {cramped} +%D +%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} + +%D We force a cramped style by issuing a non||existing radical (box). +%D After that we make sure the height is correct. (Comment taken from +%D Morten Høgholm's mathtools package.) Macro suggested by AM and +%D cleaned up a bit by HH. + +% original +% +% \def\docramped#1#2% +% {\setbox\scratchbox\hbox +% {\nulldelimiterspace\zeropoint +% $\mathsurround\zeropoint#1\radical\zerocount{#2}$}% +% \ifx#1\displaystyle +% \scratchdimen\fontdimen8\textfont3 +% \advance\scratchdimen .25\fontdimen5\textfont2 +% \else +% \scratchdimen1.25\fontdimen8 +% \ifx#1\textstyle\textfont +% \else +% \ifx#1\scriptstyle\scriptfont\else\scriptscriptfont\fi +% \fi +% 3 +% \fi +% \advance\scratchdimen-\ht\scratchbox +% \ht\scratchbox-\scratchdimen +% \box\scratchbox} + +\def\docramped#1#2% + {\begingroup % added HH, made even more cramped + \setbox\scratchbox\hbox + {\nulldelimiterspace\zeropoint + $\mathsurround\zeropoint#1\radical\zerocount{#2}$}% + \ht\scratchbox-\dimexpr + \ifx#1\displaystyle + \fontdimen8\textfont3 + +.25\fontdimen5\textfont2 + \else + 1.25\fontdimen8 + \ifx#1\textstyle + \textfont + \else\ifx#1\scriptstyle + \scriptfont + \else + \scriptscriptfont + \fi \fi + \plusthree + \fi + -\ht\scratchbox + \relax + \box\scratchbox + \endgroup} + +%D \macros +%D {cramedllap, crampedrlap, crampedclap} +%D +%D In many cases, one wants to use the \tex {clap} macro in +%D math mode while using subscripts. Normally, subscripts are +%D in cramped mode, and these macros allow you to go to +%D cramped mode. For example: +%D +%D \startbuffer +%D \startformula +%D \sum_{a^2 < b^2 < c^2} \quad +%D \sum_{\clap{a^2 < b^2 < c^2}} \quad +%D \sum_{\crampedclap{a^2 < b^2 < c^2}} +%D \stopformula +%D \stopbuffer +%D +%D \start +%D \typebuffer +%D \switchtobodyfont[24pt] +%D \getbuffer +%D \stop +%D +%D Notice that \type {\clap{\cramped ... }} would also work, +%D but it requires \TEX\ to typeset it arguments 16 times. + +\def\docrampedllap#1#2{{}\dollap{\docramped #1{#2}}} +\def\docrampedrlap#1#2{{}\dorlap{\docramped #1{#2}}} +\def\docrampedclap#1#2{{}\doclap{\docramped #1{#2}}} + +\def\crampedllap{\mathpalette\docrampedllap} +\def\crampedrlap{\mathpalette\docrampedrlap} +\def\crampedclap{\mathpalette\docrampedclap} + +\protect \endinput diff --git a/tex/context/base/supp-mat.mkiv b/tex/context/base/supp-mat.mkiv new file mode 100644 index 000000000..4aebddda9 --- /dev/null +++ b/tex/context/base/supp-mat.mkiv @@ -0,0 +1,293 @@ +%D \module +%D [ file=supp-mat, +%D version=1998.09.10, +%D title=\CONTEXT\ Support Macros, +%D subtitle=Math, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D For practical reasons, I decided to move some math things to +%D a support module. There is nothing spectacular here. It may move +%D back to math-ini. + +\writestatus{loading}{ConTeXt Support Macros / Math} + +\unprotect + +%D \macros +%D {mathematics, math, nomathematics, startmathmode} +%D +%D The \type{$} can be both an begin and end math character. +%D This can lead to confusing and errorprone situations when +%D macros insert \type{$}. When for instance we have defined: +%D +%D \starttyping +%D \def\MyPlus{$\,+\,$} +%D \stoptyping +%D +%D the sequence \type{$x^2 \MyPlus y^2 = r^2$} will expand to: +%D +%D \starttyping +%D $x^2 $\,+\,$ y^2 = r^2$ +%D \stoptyping +%D +%D Here the \type{\,} are given outside math mode and \TEX\ will +%D definitely complain about this. A more save definition would +%D have been: +%D +%D \starttyping +%D \def\MyPlus{\mathematics{\,+\,}} +%D \stoptyping +%D +%D Which is implemented as: + +\long\def\mathematics#1{\relax \ifmmode#1\else\Ustartmath #1\Ustopmath \fi} +\long\def\displaymath#1{\noindent \ifmmode#1\else\Ustartdisplaymath#1\Ustopdisplaymath\fi} +\long\def\inlinemath #1{\dontleavehmode\ifmmode#1\else\Ustartmath #1\Ustopmath \fi} + +\let\stopmathmode\relax + +\unexpanded\def\startmathmode % cannot be used nested + {\relax\ifmmode + \let\stopmathmode\relax + \else + \Ustartmath\let\stopmathmode\Ustopmath + \fi} + +\unexpanded\def\startmathmode % nested variant + {\relax\ifmmode + \begingroup\let\stopmathmode\endgroup + \else + \Ustartmath\let\stopmathmode\Ustopmath + \fi} + +\def\nomathematics#1% + {\relax\ifmmode\hbox{#1}\else#1\fi} + +\let\math\mathematics + +%D \macros +%D {displaymathematics,inlinemathematics,automathematics} +%D +%D An example of usage of the following can be found in the MathML module: + +\long\def\displaymathematics#1{\relax\ifmmode#1\else\dostartformula{}#1\dostopformula\fi} + \def\inlinemathematics {\dontleavehmode\mathematics} + \def\automathematics {\relax\ifhmode\@EA\inlinemathematics\else\@EA\displaymathematics\fi} + +% better, esp when used in bTABLE ... eTABLE + +\def\automathematics + {\relax + \ifhmode + \expandafter\inlinemathematics + \else\ifintable + \expandafter\expandafter\expandafter\inlinemathematics + \else + \expandafter\expandafter\expandafter\displaymathematics + \fi\fi} + +%D \macros +%D {dimension, nodimension} +%D +%D The next few macros are used for typesetting dimensions in +%D such a way that spacing is acceptable. I won't spend much +%D words on these macros, because they will be overloaded in +%D the units module. + +\newsignal\dimensionsignal + +\def\dimensiontypeface {\tf} +\def\dimensionhalfspace {\,} + +\unexpanded\def\dimension#1% + {\def\dodimensionsignal{\kern\dimensionsignal}% + \ifdim\lastskip=\zeropoint\relax + \ifdim\lastkern=\zeropoint\relax + \ifmmode + \mathematics{\dimensionhalfspace\dimensionhalfspace\dimensiontypeface#1}% + \else + \mathematics{\dimensiontypeface#1}% + \fi + \else\ifdim\lastkern=\dimensionsignal + \mathematics{\dimensionhalfspace\dimensiontypeface#1}% + \else + \unkern\mathematics{\dimensionhalfspace\dimensionhalfspace\dimensiontypeface#1}% + \fi\fi + \else + \unskip\mathematics{\dimensionhalfspace\dimensionhalfspace\dimensiontypeface#1}% + \fi + \dodimensionsignal} + +\unexpanded\def\nodimension#1% + {\unskip#1\global\let\dodimensionsignal\relax} + +%D \macros +%D {super, suber} +%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{\suber} (\type {\sub} is already taken). + +\global\let\normalsuper=^ +\global\let\normalsuber=_ + +\newcount\supersubmode + +\newevery\everysupersub \EverySuperSub + +\appendtoks \advance\supersubmode 1\relax \to \everysupersub + +% \def\dodosuper#1{\normalsuper{\the\everysupersub#1}} +% \def\dodosuber#1{\normalsuber{\the\everysupersub#1}} +% +% \def\dosuper{\ifx\next\bgroup\expandafter\dodosuper\else\normalsuper\fi} +% \def\dosuber{\ifx\next\bgroup\expandafter\dodosuber\else\normalsuber\fi} +% +% \def\super{\futurelet\next\dosuper} +% \def\suber{\futurelet\next\dosuber} + +\def\super#1{\normalsuper{\the\everysupersub#1}} +\def\suber#1{\normalsuber{\the\everysupersub#1}} + +%D \macros +%D {enablesupsub} +%D +%D We can let \type {^} and \type {_} act like \type {\super} +%D and \type {\suber} by saying \type {\enablesupsub}. + +\bgroup +\catcode`\^=\@@active +\catcode`\_=\@@active +\gdef\enablesupsub + {\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\supsubmode + \textstyle + \or + \scriptstyle + \else + \scriptscriptstyle + \fi + \fi} + +%D \macros +%D {cramped} +%D +%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} + +%D We force a cramped style by issuing a non||existing radical (box). +%D After that we make sure the height is correct. (Comment taken from +%D Morten Høgholm's mathtools package.) Macro suggested by AM and +%D cleaned up a bit by HH. + +% original +% +% \def\docramped#1#2% +% {\setbox\scratchbox\hbox +% {\nulldelimiterspace\zeropoint +% $\mathsurround\zeropoint#1\radical\zerocount{#2}$}% +% \ifx#1\displaystyle +% \scratchdimen\fontdimen8\textfont3 +% \advance\scratchdimen .25\fontdimen5\textfont2 +% \else +% \scratchdimen1.25\fontdimen8 +% \ifx#1\textstyle\textfont +% \else +% \ifx#1\scriptstyle\scriptfont\else\scriptscriptfont\fi +% \fi +% 3 +% \fi +% \advance\scratchdimen-\ht\scratchbox +% \ht\scratchbox-\scratchdimen +% \box\scratchbox} + +\def\docramped#1#2% + {\begingroup % added HH, made even more cramped + \setbox\scratchbox\hbox + {\nulldelimiterspace\zeropoint + \Ustartmath\mathsurround\zeropoint#1\radical\zerocount{#2}\Ustopmath}% + \ht\scratchbox-\dimexpr + \ifx#1\displaystyle + \fontdimen8\textfont3 + +.25\fontdimen5\textfont2 + \else + 1.25\fontdimen8 + \ifx#1\textstyle + \textfont + \else\ifx#1\scriptstyle + \scriptfont + \else + \scriptscriptfont + \fi \fi + \plusthree + \fi + -\ht\scratchbox + \relax + \box\scratchbox + \endgroup} + +%D \macros +%D {cramedllap, crampedrlap, crampedclap} +%D +%D In many cases, one wants to use the \tex {clap} macro in +%D math mode while using subscripts. Normally, subscripts are +%D in cramped mode, and these macros allow you to go to +%D cramped mode. For example: +%D +%D \startbuffer +%D \startformula +%D \sum_{a^2 < b^2 < c^2} \quad +%D \sum_{\clap{a^2 < b^2 < c^2}} \quad +%D \sum_{\crampedclap{a^2 < b^2 < c^2}} +%D \stopformula +%D \stopbuffer +%D +%D \start +%D \typebuffer +%D \switchtobodyfont[24pt] +%D \getbuffer +%D \stop +%D +%D Notice that \type {\clap{\cramped ... }} would also work, +%D but it requires \TEX\ to typeset it arguments 16 times. + +\def\docrampedllap#1#2{{}\dollap{\docramped #1{#2}}} +\def\docrampedrlap#1#2{{}\dorlap{\docramped #1{#2}}} +\def\docrampedclap#1#2{{}\doclap{\docramped #1{#2}}} + +\def\crampedllap{\mathpalette\docrampedllap} +\def\crampedrlap{\mathpalette\docrampedrlap} +\def\crampedclap{\mathpalette\docrampedclap} + +\protect \endinput diff --git a/tex/context/base/supp-mis.mkii b/tex/context/base/supp-mis.mkii new file mode 100644 index 000000000..f3bde453b --- /dev/null +++ b/tex/context/base/supp-mis.mkii @@ -0,0 +1,733 @@ +%D \module +%D [ file=supp-mis, +%D version=2004.10.26, % 1997.01.04, +%D title=\CONTEXT\ Support Macros, +%D subtitle=Missing (For Generic Use), +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D I will clean up this module (a la supp-pdf.tex preamble). + +%D Some support modules are more or less independant. This +%D module, which is not part of plain \CONTEXT, provides the +%D missing macros and declarations of registers. + +\ifx \undefined \writestatus \else \expandafter \endinput \fi + +%D Because \LATEX\ has no safe package loading mechanism, we +%D need to take care of possible interference. + +\def\StartLatexHack % replace this by the one in supp-pdf + {\edef\StopLatexHack + {\catcode\string`\noexpand/=\the\catcode\string`/ + \catcode\string`\noexpand-=\the\catcode\string`- + \catcode\string`\noexpand:=\the\catcode\string`: + \catcode\string`\noexpand;=\the\catcode\string`; + \catcode\string`\noexpand"=\the\catcode\string`" + \catcode\string`\noexpand<=\the\catcode\string`< + \catcode\string`\noexpand>=\the\catcode\string`> + \catcode\string`\noexpand`=\the\catcode\string``}% + \catcode\string`/=12 \catcode\string`-=12 + \catcode\string`:=12 \catcode\string`;=12 + \catcode\string`"=12 \catcode\string`<=12 + \catcode\string`>=12 \catcode\string``=12 } + +%D This hack is needed especially for \LATEX\ users who use +%D the Babel package. The Germans have active \type {"}'s, the +%D Poles have \type {/}, while the French have \type {:} and +%D \type {;} defines as command (thanks to Daniel Flipo for +%D pointing that out and testing). Potentially active \type +%D {?}'s and \type {!}'s are less dangerous since they are +%D handled by the \type {\protect} and \type {\unprotect} +%D macros. + +\StartLatexHack + +%D \macros +%D {ifnocontextobject} +%D +%D First we take care of redundant defining. The next set of +%D macros are a bit complicated by the fact that Plain +%D \TEX\ defines the \type{\new}||macros as being outer. +%D Furthermore nested \type{\if}'s can get us into +%D trouble. + +\def\definecontextobject + {\iftrue} + +\def\gobblecontextobject + {\setbox0\hbox + \bgroup + \long\def\gobblecontextobject##1\fi{\egroup}% + \expandafter\gobblecontextobject\string} + +\long\def\ifnocontextobject#1\do + {\ifx#1\undefined + \expandafter\definecontextobject + \else + %\writestatus{system}{beware of conflicting \string#1}% + \expandafter\gobblecontextobject + \fi} + +%D \macros +%D {beginETEX,beginTEX} +%D +%D Outside \CONTEXT\ we will not be \ETEX||aware. + +\long\def\beginETEX #1\endETEX {} + +\let\beginTEX\relax \let\endTEX\relax + +%D \macros +%D {writestatus} +%D +%D We start each module with a message. Normally the output is +%D formatted, but here we keep things simple. + +\ifnocontextobject \writestatus \do + + \def\writestatus#1#2{\immediate\write16{#1 : #2}} + +\fi + +%D Let's see if it works. + +\writestatus{loading}{ConTeXt Support Macros / Miscellaneous (2004.10.26)} + +%D \macros +%D {protect,unprotect} +%D +%D Next we present a poor mans alternative for \type{\protect} +%D and \type{\unprotect}, two commands that enable us to use +%D the characters \type{@}, \type{!} and \type{?} in macro +%D names. + +\ifnocontextobject \protect \do + + \let\protect\relax + +\fi + +\newcount\protectiondepth + +\ifnocontextobject \unprotect \do + + \def\unprotect + {\advance\protectiondepth 1 + \ifnum\protectiondepth=1 + \let\normalprotect=\protect + \def\protect + {\ifnum\protectiondepth>0 + \advance\protectiondepth -1 + \ifnum\protectiondepth=0 + \doprotect + \let\protect=\normalprotect + \fi + \fi} + \edef\doprotect + {\catcode`\noexpand @=\the\catcode`@\relax + \catcode`\noexpand !=\the\catcode`!\relax + \catcode`\noexpand ?=\the\catcode`?\relax} + \catcode`@=11 + \catcode`!=11 + \catcode`?=11 + \fi} + +\fi + +%D We start using this one it at once. + +\unprotect + +%D \macros +%D {scratch...,if...,next...} +%D +%D We need some scratch registers. Users are free to use them, +%D but can never be sure of their value once another macro is +%D called. We only allocate things when they are yet +%D undefined. This way we can't mess up other macro packages, +%D but of course previous definitions can mess up our modules. + +\ifnocontextobject \donetrue \do \newif\ifdone \fi + +% no time now, will do a better test later (based on dimendef) + +\def\!!stringa{plain} \ifx\!!stringa\fmtname \donetrue \else +\def\!!stringa{eplain} \ifx\!!stringa\fmtname \donetrue \else +\def\!!stringa{babel-plain} \ifx\!!stringa\fmtname \donetrue \else + \donefalse \fi \fi \fi + +\ifdone + % plain defines some 15 dimens, so we need to define a few + % dummies in order to get out of the scratch area + \newdimen\scratchdimen % 16 + \newdimen\scratchdimen % 17 + \newdimen\scratchdimen % 18 + \newdimen\scratchdimen % 19 + \newdimen\scratchdimen % 20 + \newdimen\scratchdimen % 21 +\fi + +\def\stripnewabove#1% + {\ifnum10<9#1 #1\else\expandafter\stripnewabove\fi}% + +\def\newabove\csname#1\endcsname#2% \dimen \name + {\csname#1\endcsname#2% + \ifnum\expandafter\stripnewabove\meaning#2>20\else + \newabove\csname#1\endcsname#2% + \fi} + +\ifnocontextobject \scratchcounter \do \newabove \csname newcount\endcsname \scratchcounter \fi +\ifnocontextobject \scratchtoks \do \newabove \csname newtoks\endcsname \scratchtoks \fi +\ifnocontextobject \scratchdimen \do \newabove \csname newdimen\endcsname \scratchdimen \fi +\ifnocontextobject \scratchskip \do \newabove \csname newskip\endcsname \scratchskip \fi +\ifnocontextobject \scratchmuskip \do \newabove \csname newmuskip\endcsname \scratchmuskip \fi +\ifnocontextobject \scratchbox \do \csname newbox\endcsname \scratchbox \fi +\ifnocontextobject \scratchread \do \csname newread\endcsname \scratchread \fi +\ifnocontextobject \scratchwrite \do \csname newwrite\endcsname \scratchwrite \fi + +%D Watch out, in the past we ran into troubles with \type {\onepoint} +%D (and others) mening something different in \LATEX\ then here. In +%D such situations clashes are bound to happen. For this reason the +%D assignments are no inside the test. We try to catch those situations +%D but we cannot keep ahead of the future. + +\ifnocontextobject \zeropoint \do \newdimen \zeropoint \zeropoint = 0pt \fi % else problems with dimen12 +\ifnocontextobject \onepoint \do \newdimen \onepoint \onepoint = 1pt \fi +\ifnocontextobject \onebasepoint \do \newdimen \onebasepoint \onebasepoint = 1bp \fi +\ifnocontextobject \zerocount \do \chardef \zerocount = 0 \fi +\ifnocontextobject \plusone \do \chardef \plusone = 1 \fi +\ifnocontextobject \minusone \do \newcount \minusone \minusone = -1 \fi +\ifnocontextobject \thousandpoint \do \newdimen \thousandpoint \thousandpoint = 1000pt \fi +\ifnocontextobject \onerealpoint \do \newdimen \onerealpoint \onerealpoint = 1pt \fi % latex has a funny \onepoint + +\ifnocontextobject \emptytoks \do \newtoks \emptytoks \fi +\ifnocontextobject \nextbox \do \newbox \nextbox \fi +\ifnocontextobject \nextdepth \do \newdimen \nextdepth \fi + +\ifnocontextobject \CONTEXTtrue \do \newif\ifCONTEXT \fi +\ifnocontextobject \eightbitcharacterstrue \do \newif\ifeightbitcharacters \fi +\ifnocontextobject \MPdrawingdonetrue \do \newif\ifMPdrawingdone \fi + +\ifnocontextobject \ifzeropt \do \let\ifzeropt\ifcase \fi + +%D \macros +%D {@@...} +%D +%D We use symbolic name for \CATCODES. They can only be used +%D when we are in unprotected state. + +\ifnocontextobject \@@escape \do \chardef\@@escape = 0 \fi +\ifnocontextobject \@@begingroup \do \chardef\@@begingroup = 1 \fi +\ifnocontextobject \@@endgroup \do \chardef\@@endgroup = 2 \fi +\ifnocontextobject \@@endofline \do \chardef\@@endofline = 5 \fi +\ifnocontextobject \@@ignore \do \chardef\@@ignore = 9 \fi +\ifnocontextobject \@@space \do \chardef\@@space = 10 \fi +\ifnocontextobject \@@letter \do \chardef\@@letter = 11 \fi +\ifnocontextobject \@@other \do \chardef\@@other = 12 \fi +\ifnocontextobject \@@active \do \chardef\@@active = 13 \fi +\ifnocontextobject \@@comment \do \chardef\@@comment = 14 \fi + +\def\s!sp{sp} +\def\s!pt{pt} +\def\s!bp{bp} + +%D \macros +%D {@EA,expanded,expandoneargafter,expandtwoargsafter} +%D +%D Also needed: + +\let\@EA=\expandafter \let\@@expanded\empty + +\def\expanded#1% + {\long\xdef\@@expanded{\noexpand#1}\@@expanded} + +\def\expandoneargafter#1#2% + {\@EA#1\@EA{#2}} + +\def\expandtwoargsafter#1#2#3% + {\@EA\@EA\@EA#1\@EA\@EA\@EA{\@EA#2\@EA}\@EA{#3}} + +\def\@EAEAEA{\@EA\@EA\@EA} + +%D \macros +%D {everyline,EveryLine,EveryPar} +%D +%D In \CONTEXT\ we use \type{\everypar} for special purposes +%D and provide \type{\EveryPar} as an alternative. The same +%D goes for \type{\everyline} and \type{\EveryLine}. + +\ifnocontextobject \everyline \do \newtoks\everyline \fi +\ifnocontextobject \EveryPar \do \let\EveryPar =\everypar \fi +\ifnocontextobject \EveryLine \do \let\EveryLine=\everyline \fi + +%D \macros +%D {globallet} + +\def\globallet{\global\let} + +%D \macros +%D {!!...} +%D +%D We reserve ourselves some scratch strings (i.e. macros) +%D and some more counters. + +\ifnocontextobject \!!stringa \do \def\!!stringa {} \fi +\ifnocontextobject \!!stringb \do \def\!!stringb {} \fi +\ifnocontextobject \!!stringc \do \def\!!stringc {} \fi +\ifnocontextobject \!!stringd \do \def\!!stringd {} \fi + +\ifnocontextobject \!!counta \do \newcount\!!counta {} \fi +\ifnocontextobject \!!countb \do \newcount\!!countb {} \fi + +%D \macros +%D {!!...} +%D +%D The next set of definitions speed up processing a bit. +%D Furthermore it saves memory. + +\ifnocontextobject \!!zeropoint \do \def\!!zeropoint {0pt} \fi +\ifnocontextobject \!!zerocount \do \def\!!zerocount {0} \fi +\ifnocontextobject \!!tenthousand \do \def\!!tenthousand {10000} \fi + +\ifnocontextobject \!!width \do \def\!!width {width} \fi +\ifnocontextobject \!!height \do \def\!!height {height} \fi +\ifnocontextobject \!!depth \do \def\!!depth {depth} \fi + +\ifnocontextobject \!!plus \do \def\!!plus {plus} \fi +\ifnocontextobject \!!minus \do \def\!!minus {minus} \fi +\ifnocontextobject \!!to \do \def\!!to {to} \fi + +%D \macros +%D {smashbox} +%D +%D The system modules offer a range of smashing macros, of +%D which we only copied \type{\smashbox}. + +\ifnocontextobject \smashbox \do + + \def\smashbox#1% + {\wd#1\zeropoint + \ht#1\zeropoint + \dp#1\zeropoint} + +\fi + +%D \macros +%D {dowithnextbox} +%D +%D Also without further comment, we introduce a macro that +%D gets the next box and does something usefull with it. +%D Because the \type{\afterassignment} is executed inside the +%D box, we have to use a \type{\aftergroup} too. + +\ifnocontextobject \dowithnextbox \do + + \def\dowithnextbox#1% + {\def\dodowithnextbox{#1}% + \afterassignment\dododowithnextbox + \setbox\nextbox} + + \def\dododowithnextbox% + {\aftergroup\dodowithnextbox} + +\fi + +%D \macros +%D {setvalue,setevalue,setxvalue,,setgvalue, +%D getvalue, +%D letvalue,letgvalue} +%D +%D The next two macros expand their argument to +%D \type{\argument}. The first one is used to define macro's +%D the second one executes them. + +\ifnocontextobject \setvalue \do + + \def\setvalue #1{\expandafter\def\csname#1\endcsname} + \def\setevalue#1{\expandafter\edef\csname#1\endcsname} + \def\setgvalue#1{\expandafter\gdef\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} +\fi + +%D \macros +%D {unexpanded} +%D +%D The next command can be used as prefixed for commands that +%D need protection during tests and writing to files. This +%D is a very \CONTEXT\ specific one. + +\ifnocontextobject \unexpanded \do + + \let\unexpanded\relax + +\fi + +%D \macros +%D {convertargument} +%D +%D The original one offers a bit more, like global assignment, the +%D the next implementation is however a bit more byte saving. + +\ifnocontextobject \convertargument \do + + \def\doconvertargument#1>{} + + \long\def\convertargument#1\to#2% + {\long\def\@@convertedargument{#1}% + \edef#2{\expandafter\doconvertargument\meaning\@@convertedargument}} + +\fi + +%D \macros +%D {forgetall} +%D +%D Sometimes we have to disable interference of whatever kind +%D of skips and mechanisms. The next macro resets some. + +\ifnocontextobject \forgetall \do + + \def\forgetall + {\parskip\zeropoint + \leftskip\zeropoint + \parindent\zeropoint + \everypar{}} + +\fi + +%D \macros +%D {withoutpt, +%D ScaledPointsToBigPoints,ScaledPointsToWholeBigPoints} +%D +%D \TEX\ lacks some real datastructure. We can however use +%D \DIMENSIONS. This kind of trickery is needed when we want +%D \TEX\ to communicate with the outside world (by means of +%D \type{\specials}). + +\ifnocontextobject \withoutpt \do + + {\catcode`\.=\@@other + \catcode`\p=\@@other + \catcode`\t=\@@other + \gdef\WITHOUTPT#1pt{#1}} + + \def\withoutpt#1% + {\expandafter\WITHOUTPT#1} + + \def\ScaledPointsToBigPoints#1#2% + {\scratchdimen=#1sp\relax + \scratchdimen=.996264\scratchdimen + \edef#2{\withoutpt{\the\scratchdimen}}} + + \def\ScaledPointsToWholeBigPoints#1#2% + {\scratchdimen=#1sp + \scratchdimen=.996264\scratchdimen + \scratchcounter=\scratchdimen + \advance\scratchcounter by 32768 + \divide\scratchcounter by 65536 + \edef#2{\the\scratchcounter}} + +\fi + +%D \macros +%D {doprocessfile} +%D +%D This macro takes three arguments: the file number, the +%D filename and a macro that handles the content of a read +%D line. + +\newif\iffileprocessed + +\ifnocontextobject \doprocessfile \do + + \def\doprocessfile#1#2#3% + {\openin#1=#2\relax + \ifeof#1% + \fileprocessedfalse + \closein#1\relax + \else + \fileprocessedtrue + \gdef\dofinishfile% + {\closein#1\relax + \global\let\doprocessline\relax}% + \gdef\doprocessline% + {\ifeof#1% + \dofinishfile + \else + \global\read#1 to \fileline + #3\relax + \expandafter\doprocessline + \fi}% + \expandafter\doprocessline + \fi} + +\fi + +%D \macros +%D {uncatcodespecials} +%D +%D This one is taken from the \TEX\ book. The \CONTEXT\ +%D alternative is a bit different, but we hope this one works +%D here. + +\ifx\dospecials\undefined + + \def\dospecials + {\do\ \do\\\do\{\do\}\do\$% + \do\#\do\^\do\_\do\&\do\%% + \do\~\do\^^A\do\^^K} + +\fi + +\ifnocontextobject \uncatcodespecials \do + + \def\uncatcodespecials + {\def\do##1{\catcode`##1=12 }\dospecials + \catcode`\ =\@@space + \catcode`\^^L=\@@ignore + \catcode`\^^M=\@@endofline + \catcode`\^^?=\@@ignore} + +\fi + +\ifnocontextobject \setnaturalcatcodes \do + +\def\setnaturalcatcodes + {\catcode`\!=\@@other \catcode`\?=\@@other \catcode`\@=\@@other + \catcode`\#=\@@other \catcode`\&=\@@other \catcode`\|=\@@other + \catcode`\$=\@@other \catcode`\^=\@@other \catcode`\_=\@@other + \catcode`\*=\@@other \catcode`\/=\@@other + \catcode`\-=\@@other \catcode`+=\@@other + \catcode`\==\@@other \catcode`\<=\@@other \catcode`\>=\@@other + \catcode`\"=\@@other \catcode`\'=\@@other \catcode`\`=\@@other + \catcode`\:=\@@other \catcode`\;=\@@other + \catcode`\,=\@@other \catcode`\.=\@@other \catcode`\~=\@@other + \catcode`\(=\@@other \catcode`\)=\@@other + \catcode`\{=\@@other \catcode`\}=\@@other + \catcode`\\=\@@other \catcode`\%=\@@other } + +\fi + +%D \macros +%D {doglobal} +%D +%D Some \CONTEXT\ low level macros can have a \type{\doglobal} +%D prefix. Let's just forget about that here: + +\ifnocontextobject \doglobal \do \let\doglobal\relax \fi + +%D The next obscure one is needed in the generic verbatim +%D environment. When we end up with more of these, it's time +%D to load the module \type{syst-gen}. + +\ifnocontextobject \doifincsnameelse \do + + \def\dodoifincsnameelse#1#2% + {\def\dododoifincsnameelse##1#1##2##3\war% + {\csname\if##2@iffalse\else iftrue\fi\endcsname}% + \expandafter\dododoifincsnameelse#2#1@@\war} + + \long\def\doifincsnameelse#1#2#3#4% + {\edef\@@instring{#1}% + \expandafter\dodoifincsnameelse\expandafter{\@@instring}{#2}% + #3% + \else + #4% + \fi} + +\fi + +%D \macros +%D {dostepwiserecurse, dorecurse, doloop, exitloop} +%D +%D The next loop macro is a real weak one, and does not offer +%D the full \CONTEXT\ functionality, let alone nesting, but +%D for simple purposes, its behaviour is acceptable. + +\newcount\recursecounter + +\def\dostepwiserecurse#1#2#3#4% very weak and rubishly version + {\ifnum#2<#1\relax\else\dodostepwiserecurse{#1}{#2}{#3}{#4}\fi} + +\def\dodostepwiserecurse#1#2#3#4% very weak and rubishly version + {\recursecounter=#1\relax + \loop + \edef\recurselevel{\the\recursecounter}% + #4\relax + \ifnum\recursecounter<#2\relax + \advance\recursecounter by #3\relax + \repeat} + +\def\dorecurse#1% + {\dostepwiserecurse{1}{#1}{1}} + +\def\doloop + {\dostepwiserecurse{1}{\maxdimen}{1}} + +\def\exitloop + {\recursecounter=\maxdimen} + +%D \macros +%D {ifundefined,doifdefined,doifundefined, +%D doifdefinedelse,doifundefinedelse} +%D +%D These alteratives are not robust but suitable for simple +%D usage. The official ones are a bit faster. + +\ifnocontextobject \doifdefined \do + + \def\ifundefined#1% + {\expandafter\ifx\csname#1\endcsname\relax} + + \def\doifdefinedelse#1#2#3% + {\expandafter\ifx\csname#1\endcsname\relax#3\else#2\fi} + + \def\doifundefinedelse#1#2#3% + {\expandafter\ifx\csname#1\endcsname\relax#2\else#3\fi} + + \def\doifdefined#1#2% + {\expandafter\ifx\csname#1\endcsname\relax\else#2\fi} + + \def\doifundefined#1#2% + {\expandafter\ifx\csname#1\endcsname\relax#2\fi} + +\fi + +%D \macros +%D {doifinstringelse} +%D +%D It seems like we end up with more and more macros here. +%D Sigh. + +\ifnocontextobject \doifinstringelse \do + + \def\p!doifinstringelse#1#2% + {\def\pp!doifinstringelse##1#1##2##3\war% + {\csname if\if##2@fals\else tru\fi e\endcsname}% + \expanded{\pp!doifinstringelse#2#1@@\noexpand\war}} + + \long\def\doifinstringelse#1#2#3#4% + {\edef\@@@instring{#1}% + \@EA\p!doifinstringelse\@EA{\@@@instring}{#2}#3\else#4\fi} + +\fi + +%D \macros +%D {twodigitrounding} +%D +%D We don't support rounding outside \CONTEXT. Sorry. + +\def\twodigitrounding#1{#1} + +%D \macros +%D {lineheight} +%D +%D In \CONTEXT\ we have \type{\lineheight}, which in many +%D cases matches \type {\baselineskip}. + +\ifnocontextobject \lineheight \do + + \def\lineheight{\baselineskip} + +\fi + +%D \macros +%D {dohandletokens} +%D +%D The following macro is the simplified version, but good +%D enough for day to day hacks. +%D +%D \starttyping +%D \dohandletokens some text\with\somemacro +%D \stoptyping + +\ifnocontextobject \dohandletokens \do + +\def\dodohandletokens + {\ifx\next\end \else + \docommand{\next}% + \expandafter\dohandletokens + \fi} + +\def\dohandletokens + {\afterassignment\dodohandletokens\let\next= } + +\long\def\handletokens#1\with#2% + {\let\docommand=#2% + \dohandletokens#1\end} + +\fi + +%D Very reduced: + +\long\def\appendtoks#1\to#2% + {\scratchtoks{#1}\expanded{#2{\the#2\the\scratchtoks}}} + +%D Well, also handy. + +\def\doiffileelse#1#2#3% + {\immediate\openin\scratchread=#1\relax + \ifeof\scratchread + \def\next{#3}% + \else + \def\next{#2}% + \fi + \immediate\closein\scratchread + \next} + +%D New. + +\let\donothing\empty + +%D Also new: + +\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 Sigh + +\def\settrue #1{\chardef#1\zerocount} +\def\setfalse#1{\chardef#1\plusone} + +\let\newconditional = \setfalse +\let\ifconditional = \ifcase + +%D We could load \type {norm-tex} but this takes less hash space: + +\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 \normalfi = \fi +\let \normalelse = \else + +\let \normalunexpanded = \unexpanded % beware the primitive, not the context one + +%D That's it. Please forget this junk and take a look at how +%D it should be done. + +\StopLatexHack \protect \endinput diff --git a/tex/context/base/supp-mis.tex b/tex/context/base/supp-mis.tex new file mode 100644 index 000000000..bda8d4f6f --- /dev/null +++ b/tex/context/base/supp-mis.tex @@ -0,0 +1,4 @@ +% This file is not needed, for instance supp-pdf has the relevant code +% built in and ppchtex is adapted. + +\input supp-mis.mkii diff --git a/tex/context/base/supp-mpe.mkii b/tex/context/base/supp-mpe.mkii new file mode 100644 index 000000000..67b27919c --- /dev/null +++ b/tex/context/base/supp-mpe.mkii @@ -0,0 +1,1370 @@ +%D \module +%D [ file=supp-mpe, +%D version=1999.07.10, +%D title=\CONTEXT\ Support Macros, +%D subtitle=METAPOST Special Extensions, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% fuzzy and complicating is the fact that we need to support +% context as well as mptopdf, so we cannot fall back on the +% special drivers and color module (although there may be +% good reasons to use a smaller context instead); also, +% shading is handled here while it should move to the special +% driver - to do! + +%D This module is still experimental and deals with some +%D extensions to \METAPOST. When using \POSTSCRIPT\ output, +%D these extensions can be supplied by means of proper +%D preamble definitions, but when producing \PDF\ we have to +%D set up the appropriate datastructures ourselves. It acts as +%D a plug in into \type {supp-pdf}. As soon as we need more +%D extensions, we will generalize these macro. Some +%D definitions will move to the special drivers. + +%D For usage in plain \TEX, say something: +%D +%D \starttyping +%D \input supp-pdf +%D \input supp-mpe +%D +%D \MPcmykcolorstrue +%D \MPspotcolorstrue +%D \chardef\makeMPintoPDFobject\plusone +%D \stoptyping + +\ifx\writestatus\undefined + \immediate\write16{[Loading MPS to PDF extensions.]} +\else + \writestatus{loading}{ConTeXt Support Macros / MPS extensions} +\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 +%D +%D The implementation below saves the data on the stack in +%D a way similar to the macros in \type {supp-pdf.tex}, and +%D just overload a few already defined handlers. That way, +%D the existing macros are still generic. \footnote {Actually, +%D the macros here are just as generic.} +%D +%D Currently the only extension concerns shading, which is +%D accomplished by handling yet another value of \type +%D {\finiMPpath}. The recource disctionary is stored and +%D later picked up by the general \CONTEXT\ figure inclusion +%D macros. + +\unprotect + +%D The \type {%%MetaPostSpecials: version.revision signal} line +%D triggers this module into handling color specifications kind +%D of special. We need this safeguard for non||special +%D usage. + +\chardef\MPspecialversion = 0 % specials when >1 +\chardef\MPspecialrevision = 0 % specials when >1 +\chardef\MPspecialsignal = 0 % passed on by graphic + +\chardef\inlineMPspecials = 1 % only needed for stack resetting + +%D This macro handles the special definitions that are +%D passed as comment. + +\def\dohandleMPspecialcomment#1 + {\setMPargument{#1}% + \advance\scratchcounter \minusone + \ifcase\scratchcounter + \handleMPspecialcommand + \donetrue + \doresetMPstack + \let\handleMPsequence\dohandleMPsequence + \expandafter\handleMPsequence + \else + \expandafter\dohandleMPspecialcomment + \fi} + +\def\handleMPspecialcomment #1 % number of arguments + {\doresetMPstack + \scratchcounter#1\relax + \ifcase\scratchcounter % when zero, inline shading is used + \chardef\inlineMPspecials\plusone + \let\handleMPsequence\dohandleMPsequence + \expandafter\handleMPsequence + \else + \chardef\inlineMPspecials\zerocount + \expandafter\dohandleMPspecialcomment + \fi} + +%D When defined inline, we use another macro to handle the +%D definitions. Actually, this macro is called by the +%D previous ones. + +\def\handleMPspecialcommand + {\ifcase\inlineMPspecials\or + \advance\nofMParguments \minusone % pop the size + \fi + \ifundefined\MPspecial + \message{[unknown \MPspecial]}% + \else + \csname\MPspecial\endcsname + \fi + \ifcase\inlineMPspecials + \doresetMPstack % 0 + \else + \resetMPstack % 1 + \fi} + +%D This macro triggers special support. Currently, the +%D version and revision number are not used. Any version number +%D greater than zero will enable special support. + +\newconditional\manyMPspecials % \settrue\manyMPspecials + +\def\handleMPspecialscomment #1.#2 #3 % version.revision signal #4=div=1000|10000 + {\doresetMPstack + \chardef\MPspecialversion #1% + \chardef\MPspecialrevision#2% + \chardef\MPspecialsignal #3% + \let\handleMPsequence\dohandleMPsequence + \ifnum#1=\plusone + \expandafter\handleMPsequence + \else + \expandafter\handleMPspecialscommentx + \fi} + +\def\handleMPspecialscommentx #1 % version 2 +% {\doifelsedoifelse{#1}{10000}{\settrue\manyMPspecials}{\setfalse\manyMPspecials}% local + {\ifnum10000=0#1\relax + \settrue \manyMPspecials + \else + \setfalse\manyMPspecials + \fi + \setMPextensions + \handleMPsequence} + +% one can say (in meta-ini): +% +% \prependtoks +% _special_div_ := 1000\ifconditional\manyMPspecials0\fi ; +% \to \MPextensions + +%D In case of \PDF, we need to prepare resourcs. + +\newtoks\MPstartresources +\newtoks\MPstopresources + +\def\startMPresources + {\the\MPstartresources + \ifx\currentPDFresources\empty\else + \message{[unused resources]}% + \fi + \global\let\currentPDFresources\empty} + +\def\stopMPresources + {\let\currentPDFresources\empty + \the\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 + +\ifx\normalhandleMPrgbcolor\undefined % in case we reload this module + + \let\normalhandleMPrgbcolor \handleMPrgbcolor + \let\normalhandleMPcmykcolor\handleMPcmykcolor + \let\normalhandleMPgraycolor\handleMPgraycolor + \let\normalhandleMPspotcolor\handleMPspotcolor + +\fi + +%D When we are using \CONTEXT, we will fall back to the +%D better color conversion routines. This also has the advantage +%D that we don't have to parse and convert the file. In this +%D alternative, \type {\!MP} is not (yet) supported. Because +%D we can (for efficiency reasons) turn off strokecolor, +%D something we cannot do in \METAPOST\ converted code. + +\newif\ifPDFMPstrokecolor \PDFMPstrokecolortrue + +%D [This code should move to meta-ini.] + +\ifCONTEXT % we can use this for a better xgstate handling + + \def\checkPDFMPstrokecolor + {\ifPDFMPstrokecolor \PDFstrokecolortrue \fi} + + \def\normalhandleMPrgbcolor + {{\checkPDFMPstrokecolor\execcolorR\gMPa1:\gMPa2:\gMPa3:0:0\od}} + + \def\normalhandleMPcmykcolor + {{\checkPDFMPstrokecolor\execcolorC\gMPa1:\gMPa2:\gMPa3:\gMPa4:0:0\od}} + + \def\normalhandleMPgraycolor + {{\checkPDFMPstrokecolor\execcolorS\gMPa1:0:0\od}} + +% \def\normalhandleMPspotcolor +% {{\checkPDFMPstrokecolor\execcolorP\gMPa1:\gMPa2:0:0\od}} + + \def\normalhandleMPspotcolor % ??? + {{\checkPDFMPstrokecolor\execcolorP\gMPa1:\gMPa2:\gMPa3:\gMPa4:0:0\od}} + +\fi + +% In the previous macros we use the special drivers. A more +% direct approach would have been: +% +% \def\doPDFstartrgbcolormode#1#2#3% +% {\PDFcode{#1 #2 #3 rg #1 #2 #3 RG}} +% +% \def\doPDFstartcmykcolormode#1#2#3#4% +% {\PDFcode{#1 #2 #3 #4 k #1 #2 #3 #4 K}} +% +% \def\doPDFstartgraycolormode#1% +% {\PDFcode{#1 g #1 G}} +% +% \appendtoks +% \let\dostartrgbcolormode \doPDFstartrgbcolormode +% \let\dostartcmykcolormode\doPDFstartcmykcolormode +% \let\dostartgraycolormode\doPDFstartgraycolormode +% \to \everyMPtoPDFconversion + +%D Now we can handle special color signals. We only do this +%D when special are detected. + +% \def\MPrgbnumber#1{\expandafter\doMPrgbnumber#1000.0000\relax} +% \def\doMPrgbnumber#1.#2#3#4#5\relax{#2#3#4} + +%D We cannot use \type {\everyMPtoPDFconversion} because in \MPTOPDF\ +%D we don't have the \type {\appendtoks} macro available. + +\def\setMPextensions + {\ifconditional\manyMPspecials + \def\MPrgbnumber##1{\expandafter\doMPrgbnumber##10000.00000\relax}% + \def\doMPrgbnumber##1.##2##3##4##5##6\relax{##2##3##4##5}% + \else + \def\MPrgbnumber##1{\expandafter\doMPrgbnumber##1000.0000\relax}% + \def\doMPrgbnumber##1.##2##3##4##5\relax{##2##3##4}% + \fi} + +%D The naive case looks like: +%D +%D \starttyping +%D \def\handleMPrgbcolor% +%D {\setMPcolor +%D \ifcase\MPspecialversion +%D \resetMPcolor\normalhandleMPrgbcolor +%D \else\ifnum\MPrgbnumber\lastMPrvalue=\MPspecialsignal +%D % consider it to be a signal +%D \else +%D \resetMPcolor\normalhandleMPrgbcolor +%D \fi\fi} +%D \stoptyping +%D +%D However, since we want \CMYK\ support, we will use the +%D following implementation: + +% \def\setMPcolor +% {\edef\lastMPrvalue{\gMPa1}% +% \edef\lastMPgvalue{\gMPa2}% +% \edef\lastMPbvalue{\gMPa3}} +% +% speed up (hardly called, so no let is needed) + +\def\setMPcolor + {\edef\lastMPrvalue{\csname\@@MP01\endcsname}% + \edef\lastMPgvalue{\csname\@@MP02\endcsname}% + \edef\lastMPbvalue{\csname\@@MP03\endcsname}} + +\def\zeroMPrgbvalue{0.0} + +\def\resetMPcolor + {\let\lastMPrvalue\zeroMPrgbvalue + \let\lastMPgvalue\zeroMPrgbvalue + \let\lastMPbvalue\zeroMPrgbvalue} + +\resetMPcolor + +\def\@@MPSK{@MPSK@} +\def\@@MPSP{@MPSP@} + +\def\interceptMPcmykcolor % todo : \ifMPcmykcolors + {\ifcase\MPrgbnumber\lastMPgvalue + % cannot happen + \or + % 1 == cmyk color spec + \ifMPcmykcolors \dointerceptMPcmykcolor \fi + \or + % 2 == spot color + \ifMPspotcolors \dointerceptMPspotcolor \fi + \or + % 3 == rgb transparency + \invokeMPtransparencyspecial + \or + % 4 == cmyk transparency + \ifMPcmykcolors \invokeMPtransparencyspecial \fi + \or + % 5 == spot transparency + \ifMPspotcolors \invokeMPtransparencyspecial \fi + \else + % \writestatus{MPtoPDF}{unknown direct special}% + \fi} + +% ifcsname + +\def\dointerceptMPcmykcolor + {\revokeMPtransparencyspecial + \@EA\ifx\csname\@@MPSK\number\MPrgbnumber\lastMPbvalue\endcsname\relax\else + \@EA\@EA\@EA\setMPcmyk\csname\@@MPSK\number\MPrgbnumber\lastMPbvalue\endcsname + \normalhandleMPcmykcolor + \fi} + +\def\dointerceptMPspotcolor + {\revokeMPtransparencyspecial + \@EA\ifx\csname\@@MPSP\number\MPrgbnumber\lastMPbvalue\endcsname\relax\else + \@EA\@EA\@EA\setMPspot\csname\@@MPSP\number\MPrgbnumber\lastMPbvalue\endcsname + \normalhandleMPspotcolor + \fi} + +\def\handleMPrgbcolor + {\resetMPcolor + \ifcase\MPspecialversion + \normalhandleMPrgbcolor + \else + \setMPcolor + \ifnum\MPrgbnumber\lastMPrvalue=\MPspecialsignal\relax + \interceptMPcmykcolor + \else + \revokeMPtransparencyspecial + \normalhandleMPrgbcolor + \fi + \fi} + +\def\handleMPgraycolor + {\resetMPcolor + \ifcase\MPspecialversion \else \revokeMPtransparencyspecial \fi + \normalhandleMPgraycolor} + +\def\handleMPcmykcolor + {\resetMPcolor + \ifcase\MPspecialversion \else \revokeMPtransparencyspecial \fi + \normalhandleMPcmykcolor} + +%D Specials are define and recalled using: + +\def\MPspecial + {MP special \gMPs\nofMParguments} + +\def\defineMPspecial#1#2% + {\setvalue{MP special #1}{#2}} + +%D The path processing macro is slightly extended. + +\newtoks \invokeMPspecials + +\def\finishMPpath + {\PDFcode + {\ifcase\finiMPpath W n\or S\or f\or B\else W n\fi + \extraMPpathcode}} + +\def\processMPpath + {\checkMPpath % ! + \ifcase\nofMPsegments\else + \let\extraMPpathcode\empty + \ifcase\MPspecialversion\else + \ifnum\MPrgbnumber\lastMPrvalue=\MPspecialsignal + \ifnum\MPrgbnumber\lastMPgvalue>10 % really needed + \scratchcounter\MPrgbnumber\lastMPbvalue + \edef\currentMPspecial{\the\scratchcounter}% +\let\previousMPcolorspec\currentMPcolorspec +\edef\currentMPcolorspec{\lastMPrvalue\lastMPgvalue\lastMPbvalue}% +\ifx\previousMPcolorspec\currentMPcolorspec \else + \revokeMPtransparencyspecial +\fi + \ifnum\finiMPpath=2 % to outer level + \the\invokeMPspecials + \fi + \fi + \fi + \fi + \flushMPpath + \closeMPpath + \finishMPpath + \fi + \let\handleMPsequence\dohandleMPsequence + \resetMPstack + \nofMPsegments0 + \handleMPsequence} + +%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[background=demo 1]{\bfd \white Demo 1}} {} +%D {\framed[background=demo 2]{\bfd \white Demo 2}} {} +%D {\framed[background=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 +\let\currentMPshades\empty + +\def\startMPshading#1% + {\edef\currentMPspecial{\gMPs{#1}}} + +\def\stopMPshading + {\global\advance\currentPDFshade \plusone + \setxvalue{obj:Sh:\currentMPspecial}% + {/Sh\the\currentPDFshade\space\the\pdflastobj\space0 R }% + \setxvalue{mps:Sh:\currentMPspecial}% + {\the\currentPDFshade}} + +\appendtoks + \global\let\currentMPshades\empty +\to \MPstartresources + +\appendtoks + \ifx\currentMPshades\empty \else + \xdef\currentPDFresources{\currentPDFresources + /Shading <<\currentMPshades>>}% + \fi +\to \MPstopresources + +\def\invokeMPshadespecial + {\ifundefined{mps:Sh:\currentMPspecial}\else + \edef\currentMPshade{\getvalue{obj:Sh:\currentMPspecial}}% + \doifinstringelse\currentMPshade\currentMPshades \donothing + {\xdef\currentMPshades{\currentMPshades\currentMPshade}}% + \def\extraMPpathcode{/Sh\getvalue{mps:Sh:\currentMPspecial} sh Q}% + \chardef\finiMPpath\zerocount + \PDFcode{q /Pattern cs}% + \fi} + +\appendtoks \invokeMPshadespecial \to \invokeMPspecials + +%D We need to convert the \CMYK\ specials into colors, because +%D we have to do it twice, we define a macro. + +% \def\checkMPshadingcolor#1#2#3#4#5% +% {\edef\tempMPrvalue{\csname\@@MP0#1\endcsname}% +% \edef\tempMPgvalue{\csname\@@MP0#2\endcsname}% +% \edef\tempMPbvalue{\csname\@@MP0#3\endcsname}% +% \edef#5% +% {\ifx\tempMPrvalue\tempMPgvalue +% \ifx\tempMPrvalue\tempMPbvalue +% \ifx\tempMPgvalue\tempMPbvalue +% \tempMPbvalue +% \fi +% \fi +% \fi}% +% \edef#4% todo : spotcolors +% {\ifnum\MPrgbnumber\tempMPrvalue=\MPspecialsignal\space +% \ifMPcmykcolors\getvalue{\@@MPSK\number\MPrgbnumber\tempMPbvalue}\fi +% \fi}} + +\def\checkMPshadingcolor#1#2#3#4#5% + {\edef\tempMPrvalue{\csname\@@MP0#1\endcsname}% + \edef\tempMPgvalue{\csname\@@MP0#2\endcsname}% + \edef\tempMPbvalue{\csname\@@MP0#3\endcsname}% + \global\let\MPresolvedspace\MPgrayspace + \global\let\MPresolvedcolor\!!zerocount + \ifnum\MPrgbnumber\tempMPrvalue=\MPspecialsignal\relax + \ifcase\MPrgbnumber\tempMPgvalue + \or % 1 = cmyk + \ifMPcmykcolors + \expanded{\resolveMPcmykcolor\getvalue{\@@MPSK\number\MPrgbnumber\tempMPbvalue}}\end + \fi + \or % 2 = spot + \ifMPspotcolors + \expanded{\resolveMPspotcolor\getvalue{\@@MPSP\number\MPrgbnumber\tempMPbvalue}}\end + \fi + \or + % 3 = rgb transparency + % to do + \or + % 4 == cmyk transparency + % \ifMPcmykcolors + % to do + % \fi + \or + % 5 == spot transparency + % \ifMPspotcolors + % to do + % \fi + \fi + \else + \ifx\tempMPrvalue\tempMPgvalue + \ifx\tempMPrvalue\tempMPbvalue + \expanded{\resolveMPgraycolor\tempMPbvalue}\end + \else + \expanded{\resolveMPrgbcolor\tempMPrvalue\space\tempMPgvalue\space\tempMPbvalue}\end + \fi + \else + \expanded{\resolveMPrgbcolor\tempMPrvalue\space\tempMPgvalue\space\tempMPbvalue}\end + \fi + \fi + \let#4\MPresolvedcolor + \let#5\MPresolvedspace} + +%D We also need to make sure that we have two \RGB\ or +%D \CMYK colors, since we have to set the colorspace. + +\def\setMPshadingcolors#1#2#3#4#5#6% color space + {\checkMPshadingcolor{#1}{#2}{#3}\MPshadeAc\MPshadeAs + \checkMPshadingcolor{#4}{#5}{#6}\MPshadeBc\MPshadeBs + \ifx\MPshadeAs\MPshadeBs + \let\MPshadeA\MPshadeAc + \let\MPshadeB\MPshadeBc + \let\MPshadeC\MPshadeAs + \else\ifx\MPshadeAs\MPgrayspace + \ifx\MPshadeBs\MPrgbspace + \edef\MPshadeA{\MPshadeAc\space\MPshadeAc\space\MPshadeAc}% + \else + \negatecolorcomponent\MPshadeAc + \edef\MPshadeA{0 0 0 \MPshadeAc}% + \fi + \let\MPshadeB\MPshadeBc + \let\MPshadeC\MPshadeBs + \else\ifx\MPshadeBs\MPgrayspace + \let\MPshadeA\MPshadeAc + \ifx\MPshadeAs\MPrgbspace + \edef\MPshadeB{\MPshadeBc\space\MPshadeBc\space\MPshadeBc}% + \else + \negatecolorcomponent\MPshadeBc + \edef\MPshadeB{0 0 0 \MPshadeBc}% + \fi + \let\MPshadeC\MPshadeAs + \else + % different color spaces + \def\MPshadeA{1}% + \def\MPshadeB{1}% + \let\MPshadeC\MPgrayspace + \fi\fi\fi} + +\let\MPshadeA\MPcmykWhite +\let\MPshadeB\MPcmykBlack +\let\MPshadeC\MPgrayspace + +%D The reason why this macro is a bit complicates is that we +%D handle black and white situations (otherwise we would have +%D to use \CMYK\ b/w in case of a \CMYK\ shade). + +%D Here are the special handlers: + +\defineMPspecial{30} + {\startMPshading{14}% type 2 + \setMPshadingcolors{4}{5}{6}{9}{10}{11}% + \immediate\pdfobj + {<>}% + \immediate\pdfobj + {<>}% + \stopMPshading} + +\defineMPspecial{31} + {\startMPshading{16}% type 3 + \setMPshadingcolors{4}{5}{6}{10}{11}{12}% + \immediate\pdfobj + {<>}% + \immediate\pdfobj + {<>}% + \stopMPshading} + +%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. + +\def\invokeMPfigurespecial% + {\getvalue{mps:gr:\currentMPspecial}} % or \relax + +\appendtoks \invokeMPfigurespecial \to \invokeMPspecials + +\defineMPspecial{10} + {\setxvalue{mps:gr:\gMPs8}% + {\noexpand\handleMPfigurespecial + {\gMPs1}{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}% + \noexpand\setxvalue{mps:gr:\gMPs8}{}}} + +% \def\handleMPfigurespecial#1#2#3#4#5#6#7% +% {\vbox to 0pt +% {\vss +% \hbox to 0pt +% {\pdfliteral{q #1 #2 #3 #4 #5 #6 cm}% +% \pdfimage width 1bp height 1bp {#7}% maybe 10 is better +% \pdfliteral{Q}% +% \hss}}} +% +% better, since xform reuse + +\def\handleMPfigurespecial#1#2#3#4#5#6#7% todo : combine with ext fig + {\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{mps:hl:\gMPs6}% + {\noexpand\handleMPhyperlink + {\gMPs1}{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}% + \noexpand\setxvalue{mps:hl:\gMPs6}{}}} + +\def\handleMPhyperlink#1#2#3#4#5% + {%\ifcase\pdfoutput\or + \setbox\scratchbox\hbox + {\setbox\scratchbox\null + \scratchdimen#1\onebasepoint\scratchdimen-\scratchdimen + \advance\scratchdimen#3\onebasepoint + \wd\scratchbox\scratchdimen + \scratchdimen#2\onebasepoint\scratchdimen-\scratchdimen + \advance\scratchdimen#4\onebasepoint + \ht\scratchbox\scratchdimen + \incolorfalse + \gotobox{\box\scratchbox}[#5]}% + \setbox\scratchbox\hbox + {\scratchdimen\MPxoffset\onebasepoint\advance\scratchdimen#1\onebasepoint + \hskip\scratchdimen + \scratchdimen\MPyoffset\onebasepoint\advance\scratchdimen#2\onebasepoint + \raise\scratchdimen\box\scratchbox}% + \smashbox\scratchbox + \box\scratchbox + }%\fi} + +\def\invokeMPhyperlinkspecial% + {\getvalue{mps:hl:\currentMPspecial}} % or \relax + +\appendtoks \invokeMPhyperlinkspecial \to \invokeMPspecials + +%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\gMPs1}{\gMPs2 \gMPs3 \gMPs4 \gMPs5 }% + \fi} + +\def\setMPcmyk#1 #2 #3 #4 % + {\setvalue{\@@MP01}{#1}% + \setvalue{\@@MP02}{#2}% + \setvalue{\@@MP03}{#3}% + \setvalue{\@@MP04}{#4}} + +%\defineMPspecial{2} +% {\ifMPspotcolors +% \setxvalue{\@@MPSP\gMPs1}{\gMPs2 \gMPs3 }% +% \fi} + +% \defineMPspecial{2} +% {\ifMPspotcolors +% \setxvalue{\@@MPSP\gMPs1}{\gMPs2 \gMPs3 }% +% \checkMPspot{\gMPs2}{\gMPs3}% +% \fi} +% +% \def\setMPspot#1 #2 % +% {\setvalue{\@@MP01}{#1}% +% \setvalue{\@@MP02}{#2}} +% +% \def\checkMPspot#1#2% +% {\expanded{\resolveMPspotcolor#1 #2}\end +% \ifx\MPspotspace\MPresolvedspace +% \edef\MPspotspacespec{/\MPspotspace\space}% +% \doifinstringelse\MPspotspacespec\currentMPcolorspaces +% \donothing\registerMPcolorspace +% \fi} + +\defineMPspecial{2} + {\ifMPspotcolors + \setxvalue{\@@MPSP\gMPs1}{\gMPs2 \gMPs3 \gMPs4 \gMPs5 }% space is essential + \checkMPspot{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}% + \fi} + +\def\setMPspot#1 #2 #3 #4 % + {\setvalue{\@@MP01}{#1}% + \setvalue{\@@MP02}{#2}% + \setvalue{\@@MP03}{#3}% + \setvalue{\@@MP04}{#4}} + +\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} + +%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 + +\ifx\dosavepositionwhd\undefined + \let\dosavepositionwhd\gobblesevenarguments +\fi + +\defineMPspecial{50} % x y width height label + {\bgroup + \scratchdimen\MPllx\onebasepoint\scratchdimen-\scratchdimen + % \scratchdimen-\MPllx\onebasepoint % moet ook werken + \advance\scratchdimen\gMPs1\onebasepoint + \edef\x{\number\scratchdimen}% + \scratchdimen\gMPs2\onebasepoint + \scratchdimen-\scratchdimen + \advance\scratchdimen\MPury\onebasepoint + \edef\y{\number\scratchdimen}% + \scratchdimen\gMPs3\onebasepoint + \edef\w{\number\scratchdimen}% + \scratchdimen\gMPs4\onebasepoint + \edef\h{\number\scratchdimen}% + \dosavepositionwhd{\gMPs5}0\x\y\w\h0% + \egroup} + +%D Transparency support used specials 60 (rgb) and 61 +%D (cmyk). +%D +%D \startbuffer +%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\@@MPST{@MPST@} + +\def\assignMPStransparency#1#2#3% + {\edef\PDFtransparencyidentifier{#1}% + \edef\PDFtransparencyreference {#2}% + \edef\PDFtransparencycolorspecs{#3}} + +% \def\PDFtransparencyspec +% {\ifx\MPresolvedspace\MPgrayspace +% \MPresolvedcolor\space g \MPresolvedcolor\space G% +% \else\ifx\MPresolvedspace\MPrgbspace +% \MPresolvedcolor\space rg \MPresolvedcolor\space RG% +% \else\ifx\MPresolvedspace\MPcmykspace +% \MPresolvedcolor\space k \MPresolvedcolor\space K% +% \else\ifx\MPresolvedspace\empty\else +% /\MPresolvedspace\space cs \MPresolvedcolor\space sc +% /\MPresolvedspace\space CS \MPresolvedcolor\space SC% +% \fi\fi\fi\fi} + +\def\PDFtransparencyspec % todo + {\ifx\MPresolvedspace\MPgrayspace + \MPresolvedcolor\space g + \MPresolvedcolor\space G% + \else\ifx\MPresolvedspace\MPrgbspace + \MPresolvedcolor\space rg + \MPresolvedcolor\space RG% + \else\ifx\MPresolvedspace\MPcmykspace + \MPresolvedcolor\space k + \MPresolvedcolor\space K% + \else\ifx\MPresolvedspace\empty\else + /\MPresolvedspace\space cs + /\MPresolvedspace\space CS + \PDFgetspotcolorspec\MPresolvedcolor + \fi\fi\fi\fi} + +\defineMPspecial{3} % rgb + {\edef\currentMPspecial{\gMPs6}% + \presetPDFtransparency{\gMPs1}{\gMPs2}% + \expanded{\resolveMPrgbcolor\gMPs3 \gMPs4 \gMPs5}\end + \setevalue{\@@MPST\currentMPspecial}% was \setxvalue, bug ! + {\noexpand\assignMPStransparency + {\PDFtransparencyidentifier}% + {\PDFtransparencyreference}% + {\PDFtransparencyspec}}} + +\defineMPspecial{4} % cmyk + {\edef\currentMPspecial{\gMPs7}% + \presetPDFtransparency{\gMPs1}{\gMPs2}% + \expanded{\resolveMPcmykcolor\gMPs3 \gMPs4 \gMPs5 \gMPs6}\end + \setevalue{\@@MPST\currentMPspecial}% was \setxvalue, bug ! + {\noexpand\assignMPStransparency + {\PDFtransparencyidentifier}% + {\PDFtransparencyreference}% + {\PDFtransparencyspec}}} + +% \defineMPspecial{5} % spot +% {\edef\currentMPspecial{\gMPs5}% +% \presetPDFtransparency{\gMPs1}{\gMPs2}% +% \checkMPspot{\gMPs3}{\gMPs4}% +% \setevalue{\@@MPST\currentMPspecial}% was \setxvalue, bug ! +% {\noexpand\assignMPStransparency +% {\PDFtransparencyidentifier}% +% {\PDFtransparencyreference}% +% {\PDFtransparencyspec}}} + +\defineMPspecial{5} % spot + {\edef\currentMPspecial{\gMPs7}% + \presetPDFtransparency{\gMPs1}{\gMPs2}% + \checkMPspot{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}% + \setevalue{\@@MPST\currentMPspecial}% was \setxvalue, bug ! + {\noexpand\assignMPStransparency + {\PDFtransparencyidentifier}% + {\PDFtransparencyreference}% + {\PDFtransparencyspec}}} + +% beware: for the moment only supported in pdftex; needs a cleanup! + +\def\registerMPcolorspace + {\doifobjectreferencefoundelse{PDFCS}\MPspotspace + {\doPDFgetobjectreference{PDFCS}\MPspotspace\PDFobjectreference + \xdef\currentMPcolorspaces + {\currentMPcolorspaces\MPspotspacespec\PDFobjectreference\space}} + \donothing} + +%D We need to add resource specifications! + +\appendtoks + \global\let\currentMPcolorspaces\empty +\to \MPstartresources + +\appendtoks + \ifx\currentMPcolorspaces\empty \else + \xdef\currentPDFresources{\currentPDFresources + /ColorSpace <<\currentMPcolorspaces>>}% + \fi +\to \MPstopresources + +%D For efficiency reasons, we fall back on the allocation +%D mechanisms already present. For use within \MPTOPDF, we +%D provide a fall back routine. + +\let\currentMPtransparencies\empty + +% \def\invokeMPtransparencyspecial +% {\doifdefined{\@@MPST\currentMPspecial} +% {\getvalue{\@@MPST\currentMPspecial}% +% \doifinstringelse +% {\PDFtransparencyidentifier}{\currentMPtransparencies} +% {} +% {\xdef\currentMPtransparencies +% {\currentMPtransparencies +% \PDFtransparencyidentifier\space +% \PDFtransparencyreference\space}}% +% \def\extraMPpathcode{ Q}% +% \PDFcode{q +% \PDFtransparencycolorspecs\space +% \PDFtransparencyidentifier\space gs}}} + +% this one triggers a new graphic state + +\def\invokeMPtransparencyspecial + {\scratchcounter\MPrgbnumber\lastMPbvalue + \edef\currentMPspecial{\the\scratchcounter}% + \ifundefined{\@@MPST\currentMPspecial}\else + \getvalue{\@@MPST\currentMPspecial}% + \doifinstringelse\PDFtransparencyidentifier\currentMPtransparencies + \donothing\registerMPtransparencyresource % slow + \PDFcode + {\PDFtransparencycolorspecs\space + \PDFtransparencyidentifier\space gs}% + % potential optimization + % \setevalue{\@@MPST\currentMPspecial}% + % {\PDFcode + % {\PDFtransparencycolorspecs\space + % \PDFtransparencyidentifier\space gs}}% + % \getvalue{\@@MPST\currentMPspecial}% + \let\revokeMPtransparencyspecial\dorevokeMPtransparencyspecial + \fi} + +% this one does a reset + +\let\revokeMPtransparencyspecial\relax + +\appendtoks + \revokeMPtransparencyspecial +\to \MPstopresources + +\def\dorevokeMPtransparencyspecial % only called if state is set + {\ifx\PDFtransparencyresetidentifier\empty\else + \doifinstringelse\PDFtransparencyresetidentifier\currentMPtransparencies + \donothing\registerMPtransparencyresetresource + \PDFcode{\PDFtransparencyresetidentifier\space gs}% + % potential optimization + % \def\dorevokeMPtransparencyspecial + % {\PDFcode + % {\PDFtransparencycolorspecs\space + % \PDFtransparencyidentifier\space gs}}% + \let\dorevokeMPtransparencyspecial\dodorevokeMPtransparencyspecial + \let\revokeMPtransparencyspecial\relax % invoke sets it + \fi} + +% and this one a simplified reset + +% \def\dodorevokeMPtransparencyspecial % used after first invocation +% {\getvalue{\@@MPST0}% +% \PDFcode{\PDFtransparencyidentifier\space gs}} + +\def\dodorevokeMPtransparencyspecial % used after first invocation + {\PDFcode{\PDFtransparencyresetidentifier\space gs}% + \let\revokeMPtransparencyspecial\relax} % invoke sets it + +% add a resource entry + +\def\registerMPtransparencyresource + {\xdef\currentMPtransparencies + {\currentMPtransparencies + \PDFtransparencyidentifier\space + \PDFtransparencyreference\space}} + +\def\registerMPtransparencyresetresource + {\xdef\currentMPtransparencies + {\currentMPtransparencies + \PDFtransparencyresetidentifier\space + \PDFtransparencyresetreference\space}} + +\appendtoks \invokeMPtransparencyspecial \to \invokeMPspecials + +\ifCONTEXT \else + + \def\@@MPSTN{@MPSTN@} + \def\@@MPSTO{@MPSTO@} + + \newcount\PDFcurrenttransparency + + \let\PDFtransparencyresetidentifier\empty + \let\PDFtransparencyresetreference \empty + + \let\PDFtransparencyidentifier\empty + \let\PDFtransparencyreference \empty + + \def\initializePDFtransparency + {\global\let\initializePDFtransparency\relax + \presetPDFtransparency{1}{1}% + \xdef\PDFtransparencyresetidentifier{/Tr0}% + \xdef\PDFtransparencyresetreference{\the\pdflastobj\space 0 R}} + + \def\presetPDFtransparency#1#2% + {\initializePDFtransparency + \@EA\ifx\csname\@@MPSTO#1:#2\endcsname\relax + \global\advance\PDFcurrenttransparency \plusone + \immediate\pdfobj{\PDFtransparencydictionary{#1}{#2}{}}% + \setxvalue{\@@MPSTN#1:#2}{\the\PDFcurrenttransparency}% + \setxvalue{\@@MPSTO#1:#2}{\the\pdflastobj}% + \fi + \edef\PDFtransparencyidentifier{/Tr\getvalue{\@@MPSTN#1:#2}}% + \edef\PDFtransparencyreference{\getvalue{\@@MPSTO#1:#2} 0 R}} + + \def\PDFtransparencydictionary#1#2#3% type fraction extras + {<>} + +\fi + +\appendtoks + \global\let\currentMPtransparencies\empty +\to \MPstartresources + +\appendtoks + \ifx\currentMPtransparencies\empty \else + \xdef\currentPDFresources{\currentPDFresources + /ExtGState <<\currentMPtransparencies>>}% + \fi +\to \MPstopresources + +%D In all cases, we need to keep track of the resources +%D used. + +%D A few auxiliary macros: + +\def\MPgrayspace{DeviceGray} +\def\MPrgbspace {DeviceRGB} +\def\MPcmykspace{DeviceCMYK} +\let\MPspotspace\MPgrayspace + +\def\MPcmykBlack{0 0 0 0} +\def\MPcmykWhite{0 0 0 1} + +\ifCONTEXT + + \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 + \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\end + {\startMPcolorresolve + \execcolorR#1:#2:#3:0:0\od + \stopMPcolorresolve} + + \def\resolveMPcmykcolor#1 #2 #3 #4\end + {\startMPcolorresolve + \execcolorC#1:#2:#3:#4:0:0\od + \stopMPcolorresolve} + + \def\resolveMPgraycolor#1\end + {\startMPcolorresolve + \execcolorS#1:0:0\od + \stopMPcolorresolve} + +% \def\resolveMPspotcolor#1 #2\end +% {\startMPcolorresolve +% \execcolorP#1:#2:0:0\od +% \stopMPcolorresolve} + + \def\resolveMPspotcolor#1 #2 #3 #4\end + {\startMPcolorresolve + \ifnum#2>\plusone + \checkmultitonecolor{#1}% + \fi + \execcolorP#1:#2:#3:#4:0:0\od + \stopMPcolorresolve} + +\else + + \def\resolveMPspotcolor#1 #2\end + {\global\let\MPresolvedspace\MPgrayspace + \xdef\MPresolvedcolor{0}} + + \def\resolveMPrgbcolor#1 #2 #3\end + {\global\let\MPresolvedspace\MPrgbspace + \xdef\MPresolvedcolor{#1 #2 #3}} + + \def\resolveMPcmykcolor#1 #2 #3 #4\end + {\global\let\MPresolvedspace\MPcmykspace + \xdef\MPresolvedcolor{#1 #2 #3 #4}} + + \def\resolveMPgraycolor#1\end + {\global\let\MPresolvedspace\MPgrayspace + \xdef\MPresolvedcolor{#1}} % should be inverted + +\fi + +\protect \endinput diff --git a/tex/context/base/supp-mpe.tex b/tex/context/base/supp-mpe.tex new file mode 100644 index 000000000..f4438133a --- /dev/null +++ b/tex/context/base/supp-mpe.tex @@ -0,0 +1,4 @@ +% This file is not needed as I don't expect other macro packages +% to support the metafun extensions. + +\input supp-mpe.mkii diff --git a/tex/context/base/supp-mps.mkii b/tex/context/base/supp-mps.mkii new file mode 100644 index 000000000..b071ffe72 --- /dev/null +++ b/tex/context/base/supp-mps.mkii @@ -0,0 +1,2134 @@ +%D \module +%D [ file=supp-mps, +%D version=1997.07.05, +%D title=\CONTEXT\ Support Macros, +%D subtitle=\METAPOST\ 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. + +%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 +%D tracks: +%D +%D \startitemize +%D \item generating \METAPOST\ code, running this program from +%D within \TEX\ using \type{\write18}, and importing the +%D result +%D \item generating \METAPOST\ code, processing the code +%D afterward, and importing the result in a second pass +%D \stopitemize +%D +%D The first approach uses a non standard \TEX\ feature, +%D implemented in Web2c. I'm not going to discuss the pros and +%D cons of running programs from within others, but all +%D arguments against this can be overcome by implementing a +%D \TEX\ worthy primitive: +%D +%D \starttyping +%D \excuteMetaPost filename +%D \stoptyping +%D +%D Ok then, let's start: + +\writestatus{loading}{ConTeXt Support Macros / MetaPost Inclusion} + +\unprotect + +\def\@@MPG{@MPG@} + +%D First we define a handy constant: + +\bgroup \catcode`\%=\@@other \xdef\letterpercent{\string%} \egroup + +% todo : sort out ^^M, \par and ; mess + +%D \macros +%D {everyMPgraphic} +%D +%D Because some graphics interact with \TEX\ (i.e.\ \CONTEXT), we +%D provide a hook for additional actions: \type {\everyMPgraphic}. + +\newtoks\everyMPgraphic \everyMPgraphic{\everyMPgraphic\emptytoks} + +%D \macros +%D {startMPgraphic} +%D +%D From within \TEX\ one can execute \METAPOST\ code by putting +%D it between the two commands +%D +%D \starttyping +%D \startMPgraphic +%D \stopMPgraphic +%D \stoptyping +%D +%D This is implemented as: + +\let\stopMPgraphic\relax + +\long\def\startMPgraphic#1\stopMPgraphic + {\startwritingMPgraphic + \writecheckedMPgraphic{#1}% % potential speedup: pass #1 as macro + \stopwritingMPgraphic} + +%D \macros +%D {startMPrun} +%D +%D If we just want to run \METAPOST\ code, that is, not to +%D explictly generate a figure in terms of \type{beginfig} and +%D \type{endfig}, we can use: +%D +%D \starttyping +%D \startMPgraphic +%D \stopMPgraphic +%D \stoptyping +%D +%D \starttyping +%D \startMPrun +%D \stopMPrun +%D \stoptyping +%D +%D The next booleans are for internal purposes only. + +% some day a bit more more clear: +% +% run directly/run afterwards/run external defined +% insert directly/insert whenever +% use object/don't use objects + +\newif\ifMPgraphics \MPgraphicstrue +\newif\ifMPrun \MPrunfalse +\newif\ifMPwrapper \MPwrappertrue + +\let\stopMPrun\relax + +\ifCONTEXT + + \long\def\dostartMPrun#1#2\stopMPrun + {\bgroup + \MPruntrue + \doifsomething{#1}{\def\MPgraphicfile{#1}}% + \startwritingMPgraphic + \writecheckedMPgraphic{#2}% + \stopwritingMPgraphic + \egroup} + + \def\startMPrun + {\dosinglegroupempty\dostartMPrun} + +\else + + \long\def\startMPrun#1\stopMPrun + {\MPruntrue + \startwritingMPgraphic + \writecheckedMPgraphic{#1}% + \stopwritingMPgraphic + \MPrunfalse} + +\fi + +%D \macros +%D {startwritingMPgraphic, +%D writeMPgraphic, +%D stopwritingMPgraphic} +%D +%D If the writing process is divided into more steps, one can +%D use the components of this macro directly. +%D +%D \starttyping +%D \startwritingMPgraphic +%D ... +%D \writeMPgraphic{...} +%D ... +%D \writeMPgraphic{...} +%D ... +%D \stopwritingMPgraphic +%D \stoptyping + +%D \macros +%D {ifrunMPgraphics,ifrunMPTEXgraphics,ifinsertMPgraphics} +%D +%D These macros look a bit more complicated that one would +%D expect at first sight. This is due to the two ways of +%D processing these graphics, mentioned in a previous +%D paragraph. Which method is used, the direct or indirect +%D one, depends on a boolean. + +\newif\ifrunMPgraphics \runMPgraphicsfalse +\newif\ifrunMPTEXgraphics \runMPTEXgraphicsfalse +\newif\ifinsertMPgraphics \insertMPgraphicstrue + +%D If set to true, one can do with a single pass, else one must +%D process the \METAPOST\ file \type{mpgraph} between two +%D succesive \TEX\ runs. + +\ifx\MPgraphicfile\undefined + +\def\MPgraphicfile{mp\ifMPrun run\else graph\fi} +\def\MPruntimefile{mprun} + +\fi + +%D \macros +%D {MPgraphic} +%D +%D When we run \METAPOST\ from within \TEX, each graphic is +%D processed at once, which means that we reuse this file many +%D times. When however the execution is delayed, all graphics +%D are saved in a separate figure. The current graphic is +%D characterized bij a \COUNTER. This counter is available +%D in \type{\MPgraphic}. + +\newcount\nofMPgraphics +\newcount\currentMPgraphic + +\def\MPgraphic{0} + +% %D \macros +% %D {ifreuseMPgraphics} +% %D +% %D If one want to reuse grapics, one can save much redundant +% %D run time by setting the next switch to true. +% +% \newif\ifreuseMPgraphics \reuseMPgraphicstrue + +%D The three macros responsible for writing the graphic +%D implement both schemes. + +%D \macros +%D {MPinclusions, startMPinclusions, MPinitializations} +%D +%D One can include for instance common input commands by +%D passing them to \type{\MPinclusions}: +%D +%D \starttyping +%D \startMPinclusions +%D input mp-mine ; +%D \stopMPinclusions +%D \stoptyping +%D +%D \starttyping +%D \MPinclusions{input mp-mine} +%D \stoptyping +%D +%D These commands reset their content each time. You can append +%D code as follows: +%D +%D \starttyping +%D \startMPinclusions[+] +%D input mp-mine ; +%D \stopMPinclusions +%D \stoptyping +%D +%D The token register \type {\MPinitializations} is expanded +%D before all other inclusions, the extensions are expanded +%D only once per run. + +%D The next hack prevents too long lines: + +\long\def\runtimeobeyMPlines + {\catcode35=11\relax % goodie + \ifx\rawcharacter\undefined + \let\obeyedline\space + \else + \obeylines + \ifx\outputnewlinechar\undefined + \edef\obeyedline{\rawcharacter{\endlinechar}}% + \else + \let\obeyedline\outputnewlinechar + \fi + \fi} + +\long\def\obeyMPlines % anyhow, we end up with ^^M's in the input + {\obeylines + \let\obeyedline\relax} % delay expansion + +\ifx\everydump\undefined + % maybe we're not using context +\else + \appendtoks + \let\obeyMPlines\runtimeobeyMPlines + \to \everydump +\fi + +%D We use two distinguished token registers: + +\newtoks \MPextensions % once per run (can be multiple graphics) +\newtoks \MPinitializations % each graphic + +\let\stopMPextensions \relax % so that we can use it in \expanded +\let\stopMPinitializations\relax % so that we can use it in \expanded +\let\stopMPinclusions \relax % so that we can use it in \expanded + +\def\startMPextensions % no text checking done here ! + {\begingroup + \obeyMPlines + \dostartMPextensions} + +\def\dostartMPextensions#1\stopMPextensions + {\endgroup + \MPextensions\expandafter{\the\MPextensions#1}} + +\def\startMPinitializations % no text checking done here ! + {\begingroup + \obeyMPlines + \dostartMPinitializations} + +\def\dostartMPinitializations#1\stopMPinitializations + {\endgroup + \MPinitializations\expandafter{\the\MPinitializations#1}} + +\def\startMPinclusions + {\begingroup + \dosingleempty\dostartMPinclusions} + +\long\def\dostartMPinclusions + {\obeyMPlines + \dodostartMPinclusions} + +\long\def\dodostartMPinclusions[#1]#2\stopMPinclusions % document wide + {\endgroup + \doifelse{#1}{+} + {\@EA\long\@EA\def\@EA\theMPinclusions\@EA + {\theMPinclusions + \writeMPgraphic{#2}}} + {\long\def\theMPinclusions + {% \expanded ! +% \@EA\expanded\@EA{\@EA\writeMPgraphic\@EA{\the\MPextensions;}}% new + \writeMPgraphic{#2}}}} + +\def\MPinclusions + {\dosingleempty\doMPinclusions} + +\long\def\doMPinclusions[#1]#2% + {\startMPinclusions[#1]#2\stopMPinclusions} + +\def\theMPextensions + {\@EA\expanded\@EA{\@EA\writeMPgraphic\@EA{\the\MPextensions;}}} + +\def\theMPinitializations + {\@EA\expanded\@EA{\@EA\writeMPgraphic\@EA{\the\MPinitializations;}}} + +\startMPinclusions \stopMPinclusions + +%D \macros +%D {iflongMPlines} +%D +%D When grabbing a graphic deifnition, newlines are turned +%D into spaces. By default we split the graphic definition +%D at the colon, but long lines are still possible by +%D setting the next boolean to true. + +\newwrite\MPwrite +\newwrite\MPstaticwrite + +\newif\iflongMPlines \longMPlinestrue % we now have \obeyMPlines + +\ifx \overlaywidth \undefined \def \overlaywidth {4cm} \fi +\ifx \overlayheight \undefined \def \overlayheight {3cm} \fi +\ifx \overlaylinewidth \undefined \def \overlaylinewidth {0pt} \fi + +\def\presetMPdefinitions + {\edef\overlaywidth {\overlaywidth \space}% + \edef\overlayheight {\overlayheight \space}% + \edef\overlaylinewidth {\overlaylinewidth\space}% + \edef\currentwidth {\the\hsize \space}% + \edef\currentheight {\the\vsize \space}} + +%D The \type {;} aware method (the \type {\else} branch) also +%D takes care of \type {btex}||\type {etex}, \type +%D {verbatimtex}||\type {etex}. The space after \type {tex} +%D is essential, since it protects \type {text}. + +\newif\ifMPTEXgraphic + +\let\bufferedMPgraphicsline\empty + +\appendtoks + \globallet\bufferedMPgraphicsline\empty +\to \everyMPgraphic + +\chardef\MPgraphicsscanmode\plustwo % 0=no scanning, 1=simple scanning, 2=less simple, 3=even less + +% the next fails with \chardef\MPgraphicsscanmode\plusone +% +% \startMPextensions +% gp_num_points_with_tex := 3 ; +% \stopMPextensions + +\def\writeMPgraphic % no big #1 passing here + {\iflongMPlines + \ifMPTEXgraphic + \ifcase\MPgraphicsscanmode + \let\next\writeMPgraphiclongR + \else + \let\next\writeMPgraphiclongT + \fi + \else + \let\next\writeMPgraphiclongN + \fi + \else + \ifMPTEXgraphic + \ifcase\MPgraphicsscanmode + \let\next\writeMPgraphicshortN % we could \let \writeMPgraphicshortR\writeMPgraphicshortN + \else + \let\next\writeMPgraphicshortT + \fi + \else + \let\next\writeMPgraphicshortN + \fi + \fi + \next} + +\appendtoks \obeyMPlines \to \everyMPgraphic % more efficient than in each following grouped write + +\long\def\writeMPgraphiclongR#1% fast, no scanning + {\bgroup + \let\par\space + \immediate\write\MPwrite{#1}% + \egroup} + +\long\def\writeMPgraphiclongT#1% + {\bgroup + \let\par\space + \longMPflushT#1\empty\par\relax\par + \egroup} + +\long\def\writeMPgraphicshortT#1% + {\bgroup + \let\par\space + \shortMPflushT#1\empty;\relax;% + \egroup} + +\long\def\longMPflushT#1#2\par + {\ifx#1\relax \else + \dowriteMPgraphicline#1#2tex \relax etex\MPend + \expandafter\longMPflushT + \fi} + +\long\def\shortMPflushT#1#2;% + {\ifx#1\relax \else + \dowriteMPgraphicline#1#2tex \relax etex\MPend + \expandafter\shortMPflushT + \fi} + +\long\def\writeMPgraphiclongN#1% + {\bgroup + \let\par\space + \longMPflushN#1\empty\par\relax\par + \egroup} + +\long\def\writeMPgraphicshortN#1% + {\bgroup + \let\par\space + \shortMPflushN#1\empty;\relax;% + \egroup} + +\long\def\longMPflushN#1#2\par + {\ifx#1\relax \else + \nowriteMPgraphicline#1#2\MPend + \expandafter\longMPflushN + \fi} + +\long\def\shortMPflushN#1#2;% + {\ifx#1\relax \else + \nowriteMPgraphicline#1#2\MPend + \expandafter\shortMPflushN + \fi} + +\def\dowriteMPgraphicline{\futurelet\next\dodowriteMPgraphicline} +\def\nowriteMPgraphicline{\futurelet\next\nonowriteMPgraphicline} + +%D Will move (check if next is needed): + +\long\def\nonowriteMPgraphicline#1\MPend + {\ifx\next\empty\else\ifx\next\relax\else + \bgroup + \let\par\space + \iflongMPlines + %\immediate\write\MPwrite{#1;}% oeps, ; invalid + \immediate\write\MPwrite{#1}% + \else + \long\edef\ascii{#1}% + \expandafter\flushMPgraphicline\ascii\empty;\relax;% + \fi + \egroup + \fi\fi} + +%D A first version: +%D +%D \starttyping +%D \long\def\dodowriteMPgraphicline#1tex #2#3etex#4\MPend% +%D {\ifx\next\empty\else\ifx\next\relax\else +%D \bgroup +%D \let\par=\space +%D \ifx#2\relax +%D \immediate\write\MPwrite{#1;}% +%D \egroup +%D \else +%D \global\MPTEXgraphictrue +%D \convertargument#2#3\to\ascii +%D \immediate\write\MPwrite{#1tex \ascii etex}% +%D \egroup +%D \dowriteMPgraphicline#4tex \relax etex\MPend +%D \fi +%D \fi\fi} +%D \stoptyping + +%D The next alternative also handles inclusions well. + +\newtoks \everyMPTEXgraphic + +\newif\ifforceMPTEXgraphic + +%D Before we supported the graph module, we had: +%D +%D \starttyping +%D \convertargument etex\to\MPasciiB +%D \convertargument textext\to\MPasciiC % geen "text" +%D \convertargument graphictext\to\MPasciiD % geen "text" +%D +%D \long\def\checkMPTEXgraphic#1% +%D {\ifforceMPTEXgraphic +%D \global\MPTEXgraphictrue +%D \else +%D \expandafter\convertargument#1\to\MPasciia +%D \doifstringinstringelse\MPasciiB\MPasciia{\global\MPTEXgraphictrue} +%D {\doifstringinstringelse\MPasciiC\MPasciia{\global\MPTEXgraphictrue} +%D {\doifstringinstringelse\MPasciiD\MPasciia{\global\MPTEXgraphictrue} +%D {\global\MPTEXgraphicfalse}}}% +%D \fi} +%D \stoptyping +%D +%D The next alternative permits extensions in other modules +%D without the need to know the details of testing. + +\newtoks\MPTEXgraphicchecks + +\long\def\writecheckedMPgraphic#1% + {\ifforceMPTEXgraphic + \global\MPTEXgraphictrue + \else + \global\MPTEXgraphicfalse + \edef\ascii{#1}\convertcommand\ascii\to\MPascii + \the\MPTEXgraphicchecks\relax % \relax is end condition! + \fi + \flushMPTEXgraphic % verbatimtex etc + \writeMPgraphic{#1}} % potential optimization: pass \ascii + +%D We could have used a kind of array approach using a +%D counter appended to \type {MPascii}, but this is an +%D as efficient alternative. (The uglyness comes from +%D expanding after the string \type {#1}). + +\let\MPTEXchecklist\empty + +\def\forceMPTEXcheck#1% + {\addtocommalist{#1}\MPTEXchecklist + \expanded{\convertargument#1\noexpand\to + \@EA\noexpand\csname MPascii#1\endcsname}% + \@EA\appendtoks + \@EA\doifincsnameelse\csname MPascii#1\endcsname\MPascii + {\global\MPTEXgraphictrue\gobbleuntil\relax}\donothing + \to \MPTEXgraphicchecks} + +\forceMPTEXcheck{etex} +\forceMPTEXcheck{textext} +\forceMPTEXcheck{graphictext} + +%D \starttyping +%D \forceMPTEXgraphictrue +%D +%D \forceMPTEXcheck{lintext} +%D \forceMPTEXcheck{logtext} +%D +%D \startMPcode +%D draw hlintext.lft(0, 20, 5, 20cm, "@3e") ; +%D draw vlogtext.bot(0, 10, 9, 10cm, "@3e") ; +%D \stopMPcode +%D \stoptyping + +%D A goodie for Mojca (the gnuplot wizzard): +%D +%D \starttyping +%D \startMPcode +%D draw fullcircle scaled 4cm ; +%D draw \textext{$\sqrt{\frac{3}{2}^3}$} ; +%D \stopMPcode +%D \stoptyping + +\long\def\textext#1{\normalunexpanded{textext("#1")}} % or \detokenize + +\def\flushMPTEXgraphic + {\ifMPTEXgraphic + \immediate\write\MPwrite{verbatimtex \the\everyMPTEXgraphic\space etex;}% + \fi} + +\long\def\flushMPgraphicline#1#2;% + {\ifx#1\relax \else + \immediate\write\MPwrite{#1#2;}% + \expandafter\flushMPgraphicline + \fi} + +% the next one fails on btex \vbox {\hbox .. leading to \vbox \hbox +% +% \long\def\dodowriteMPgraphicline#1tex #2#3etex#4\MPend +% {\ifx\next\empty\else\ifx\next\relax\else +% \bgroup +% \let\par\space +% \ifx#2\relax +% \iflongMPlines +% \immediate\write\MPwrite{#1;}% +% \else +% \edef\ascii{#1}% +% \expandafter\flushMPgraphicline\ascii\empty;\relax;% +% \fi +% \egroup +% \else +% \convertargument#2#3\to\ascii +% \immediate\write\MPwrite{#1tex \ascii etex}% +% \egroup +% \dowriteMPgraphicline#4tex \relax etex\MPend +% \fi +% \fi\fi} +% +% so we need a two step approach + +% \long\def\dodowriteMPgraphicline#1tex % +% {\doifnextcharelse\relax +% {\nododowriteMPgraphicline{#1}} +% {\redodowriteMPgraphicline{#1}}} +% +% better and faster + +% \long\def\dodowriteMPgraphicline#1tex #2% +% {\ifx#2\relax +% \expandafter\nododowriteMPgraphicline +% \else +% \expandafter\redodowriteMPgraphicline +% \fi{#1} #2} +% +% \long\def\redodowriteMPgraphicline#1#2etex#3\MPend +% {\ifx\next\empty\else\ifx\next\relax\else +% \bgroup +% \let\par\space +% \convertargument#2\to\ascii +% \immediate\write\MPwrite{#1tex \ascii etex}% +% \egroup +% \dowriteMPgraphicline#3tex \relax etex\MPend +% \fi\fi} +% +% \long\def\nododowriteMPgraphicline#1#2\MPend +% {\ifx\next\empty\else\ifx\next\relax\else +% \bgroup +% \let\par\space +% \iflongMPlines +% \immediate\write\MPwrite{#1;}% +% \else +% \long\edef\ascii{#1}% +% \expandafter\flushMPgraphicline\ascii\empty;\relax;% +% \fi +% \egroup +% \fi\fi} + +% extra scanning + +\long\def\dodowriteMPgraphicline#1tex #2% kind of ok + {\ifx#2\relax + \expandafter\nododowriteMPgraphicline + \else + \ifcase\MPgraphicsscanmode + % can't happen + \or + \@EAEAEA\redodowriteMPgraphicline + \or + \doifinstringelse{b$} {#1$}{\@EAEAEA\redodowriteMPgraphicline}% + {\doifinstringelse{verbatim$}{#1$}{\@EAEAEA\redodowriteMPgraphicline}% + {\@EAEAEA\dododowriteMPgraphicline}}% + \else + \doifinstringelse { b$}{#1$}{\@EAEAEA\redodowriteMPgraphicline}% + {\doifinstringelse {(b$}{#1$}{\@EAEAEA\redodowriteMPgraphicline}% + {\doifinstringelse {=b$}{#1$}{\@EAEAEA\redodowriteMPgraphicline}% + {\doifinstringelse{verbatim$}{#1$}{\@EAEAEA\redodowriteMPgraphicline}% + {\@EAEAEA\dododowriteMPgraphicline}}}}% + \fi + \fi{#1} #2} + +\def\dododowriteMPgraphicline#1#2\MPend + {\doifsomething{#1}{\xdef\bufferedMPgraphicsline{\bufferedMPgraphicsline#1tex }}% + \dowriteMPgraphicline#2tex \relax etex\MPend} + +\long\def\redodowriteMPgraphicline#1#2etex#3\MPend + {\ifx\next\empty + \else\ifx\next\relax + \else + \bgroup + \let\par\space + \convertargument#2\to\ascii + \immediate\write\MPwrite{\bufferedMPgraphicsline#1tex \ascii etex}% + \globallet\bufferedMPgraphicsline\empty + \egroup + \dowriteMPgraphicline#3tex \relax etex\MPend + \fi\fi} + +\long\def\nododowriteMPgraphicline#1#2\MPend + {\ifx\next\empty + \else\ifx\next\relax + \else + \bgroup + \let\par\space + \iflongMPlines + \immediate\write\MPwrite{\bufferedMPgraphicsline#1;}% + \globallet\bufferedMPgraphicsline\empty + \else + \long\edef\ascii{\bufferedMPgraphicsline#1}% + \expandafter\flushMPgraphicline\ascii\empty;\relax;% + \fi + \egroup + \fi\fi} + +%D This stripper is suboptimal in the sense that more +%D \type{;}'s are output than feasible. Anyhow, \METAPOST\ +%D can handle this and users may consider it being a sort +%D of error prevention bonus. + +\ifx\blabelgroup\undefined + + \let\blabelgroup\bgroup + \let\elabelgroup\egroup + +\fi + +\newconditional\firstMPgraphic \settrue\firstMPgraphic + +\appendtoks + \let \# \letterhash + \let \_ \letterunderscore + \let \& \letterampersand + \let \{ \letteropenbrace + \let \} \letterclosebrace +\to \everyMPgraphic + +%D Not the best place but we need to make sure that no funny +%D active characters creep in. Some day we will move this code. + +\ifx\disablediscretionaries\undefined + \let\disablediscretionaries\relax +\fi + +\appendtoks + \disablediscretionaries +\to \everyMPgraphic + +\def\writeMPgraph + {\immediate\write\MPwrite{mpgraph:=\the\currentMPgraphic;}} + +\def\startwritingMPgraphic + {\blabelgroup + \global\advance\nofMPgraphics \plusone + \ifMPrun \else + \allocateMPslot\currentMPgraphic + \fi + \enableincludeMPgraphics + \xdef\MPgraphic{\the\currentMPgraphic}% + \the\everyMPgraphic + \presetMPdefinitions % moved to here from \writeMPgraphic + \ifrunMPgraphics + \openMPgraphicfile1{runtime}% + % no reset here ! + \theMPextensions + \theMPinclusions + \else + \openMPgraphicfile0{collected}% + % reset here ! global added (due to adding \blabelgroup) + \theMPextensions + \theMPinclusions + \global\let\theMPextensions\relax + \global\let\theMPinclusions\relax + \fi + \theMPinitializations % always + \ifMPrun + \else + \ifMPwrapper + \immediate\write\MPwrite{let mprunend = end ;}% + \immediate\write\MPwrite{beginfig(\the\currentMPgraphic);}% + \fi + \fi + \globallet\flushMPgraphics\closeMPgraphicfiles % \dodostopwritingMPgraphic + \globallet\stopwritingMPgraphic\dostopwritingMPgraphic} + +\let\MPgraphicfiles\empty + +\let\MPinputtranslation\empty + +\def\openMPgraphicfile#1#2% #1=alwaysopen #2=message + {\@EA\ifx\csname\@@MPG\@@MPG\MPgraphicfile\endcsname\relax + \donetrue + % \@EA\newwrite\csname\@@MPG\@@MPG\MPgraphicfile\endcsname + % for the sake of plain usage + \@EA\@EA\csname newwrite\endcsname\csname\@@MPG\@@MPG\MPgraphicfile\endcsname + \doglobal\addtocommalist\MPgraphicfile\MPgraphicfiles + \else + \ifcase#1\relax\donefalse\else\donetrue\fi + \fi + \@EA\let\@EA\MPwrite\csname\@@MPG\@@MPG\MPgraphicfile\endcsname + \ifdone + \immediate\openout\MPwrite\MPgraphicfile.mp\relax + \ifx\MPinputtranslation\empty\else + \immediate\write\MPwrite{\MPinputtranslation}% + \immediate\write\MPwrite{verbatimtex \MPinputtranslation etex ;}% + \fi + \immediate\write\MPwrite{\letterpercent\space #2 graphics of job "\jobname"}% + \writeMPgraph + \setMPrandomseed + \fi} + +\def\dostopwritingMPgraphic + {\ifMPrun \else + \ifMPwrapper + \immediate\write\MPwrite{endfig;}% + \immediate\write\MPwrite{let end=mprunend;}% + \fi + \fi + \ifrunMPgraphics + \dodostopwritingMPgraphic + \fi + \elabelgroup} + +\def\dodostopwritingMPgraphic + {\ifnum\currentMPgraphic>\zerocount + \donetrue + \else\ifMPrun + \donetrue + \else + \donefalse + \fi\fi + \ifdone + \finishwritingMPgraphics + \runMPgraphic\MPgraphicfile + \fi + \globallet\flushMPgraphics\relax} + +\def\finishwritingMPgraphics + {\ifMPwrapper\immediate\write\MPwrite{end.}\fi + \immediate\closeout\MPwrite} + +\def\closeMPgraphicfiles + {\ifrunMPgraphics \else \ifx\MPgraphicsfiles\empty\else + \def\docommand##1% + {\message{[flush and process ##1.mp afterwards]}% + \@EA\let\@EA\MPwrite\csname\@@MPG\@@MPG##1\endcsname + \finishwritingMPgraphics}% + \processcommacommand[\MPgraphicfiles]\docommand + \fi \fi} + +\let\stopwritingMPgraphic\relax +\let\flushMPgraphics \relax + +%D By default each graphic gets its own slot (number). Later +%D on we will define a recycle bin. + +\def \allocateMPslot#1{\global\advance#1\plusone} +\def\deallocateMPslot#1{} + +%D \macros +%D {translateMPinput} +%D +%D For my polish friends: +%D +%D \starttyping +%D % translate=il2-pl +%D +%D \translateMPinput{il2-pl} +%D +%D \startMPenvironment[global] +%D \setupbodyfont[plr] +%D \stopMPenvironment +%D +%D \TeX: ± ¶ +%D +%D \startMPcode +%D draw btex MetaPost: ± ¶ etex scaled 5 ; +%D \stopMPcode +%D \stoptyping + +\def\translateMPinput#1% +% {\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} +%D +%D Did you notice the random seed initialization? This is +%D needed because \METAPOST\ has a rather poor initialization, +%D which in some implementations depends on the time in +%D minutes. So, in quick successive runs, random is not that +%D random. + +\newif\ifsetMPrandomseed \setMPrandomseedtrue % false by default + +\def\setMPrandomseed + {\ifsetMPrandomseed \ifx\getrandomnumber\undefined \else + \getrandomnumber\localMPseed\zerocount{4095}% + \writeMPgraphic{randomseed:=\localMPseed;}% + \fi\fi} + +%D This feature has become optional. Thanks to Fabrice Popineau, +%D \METAPOST\ can now do a far better job! + +%D \macros +%D {flushMPgraphics} +%D +%D When we use the indirect method, all graphics are saved in +%D one file. This means that we cannot close this file after +%D every \type{\stopMPgraphic}. Therefore we need to say: +%D +%D \starttyping +%D \flushMPgraphics +%D \stoptyping +%D +%D else the file is closed without writing the \METAPOST\ end +%D command. One will notice this fast enough when in indirect +%D mode. When using the direct mode this command is not +%D implicitly needed, but ommiting it makes files less +%D portable. + +%D \macros +%D {loadcurrentMPgraphic, +%D placeMPgraphic} +%D +%D Once defined, we can call for this graphic by saying: +%D +%D \starttyping +%D \loadcurrentMPgraphic{setups} +%D \placeMPgraphic +%D \stoptyping +%D +%D This two stage insert permits some intermediate manipulations +%D of the graphic, which temporary saved in: + +\newbox\MPgraphicbox + +\def\doloadcurrentMPgraphic#1% + {\loadMPgraphic{\MPgraphicfile.\the\currentMPgraphic}{#1}% + \deallocateMPslot\currentMPgraphic} % added + +\ifCONTEXT + \def\loadcurrentMPgraphic{\dosinglegroupempty\doloadcurrentMPgraphic} +\else + \let\loadcurrentMPgraphic\doloadcurrentMPgraphic +\fi + +\def\loadMPgraphic#1#2% + {\setbox\MPgraphicbox\hbox{\ifinsertMPgraphics\insertMPfile{#1}{#2}\fi}} + +\def\MPllx{0} +\def\MPlly{0} + +% \def\placeMPgraphic% +% {\ifMPshiftdrawing +% \hbox{\hskip\MPllx\onebasepoint\raise\MPlly\onebasepoint\box\MPgraphicbox}% +% \else +% \box\MPgraphicbox +% \fi} +% +% experimental: + +\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 + \fi + \box\MPgraphicbox} + +%D \macros +%D {startreusableMPgraphic, reuseMPgraphic, useMPbox} +%D +%D One can use the next macro for defining graphics that are +%D to be reused. When the next switch is set, graphics are +%D cached. + +\newif\ifuseMPbox \useMPboxtrue + +%D We assume that one can set objects: +%D +%D \starttyping +%D \def\douseMPbox#1% +%D {\setobject{MP}{#1}\vbox +%D {\forgetall +%D \loadMPgraphic{\MPgraphicfile.\the\currentMPgraphic}{}% +%D \deallocateMPslot\currentMPgraphic +%D \placeMPgraphic}% +%D \setgvalue{#1}{\getobject{MP}{#1}}} +%D \stoptyping +%D +%D More safe is to use a number for \type {{MP}{#1}} which permits +%D redefinition. We also saves the boundingbox. This helps positioning +%D reused graphics in layers. + +\newcount\MPobjectcounter + +\ifx\getobject\undefined \def\setobject#1#2{\setbox\scratchbox} \fi % makes dep check happy +\ifx\getobject\undefined \def\getobject#1#2{\box \scratchbox} \fi % makes dep check happy + +\def\douseMPbox#1% + {\global\advance\MPobjectcounter\plusone + \setobject{MP}{\number\MPobjectcounter}\vbox + {\forgetall + \loadMPgraphic{\MPgraphicfile.\the\currentMPgraphic}{}% + \deallocateMPslot\currentMPgraphic + \placeMPgraphic}% + \setxvalue{#1}% + {\noexpand\dodouseMPbox{\number\MPobjectcounter}{\MPllx}{\MPlly}{\MPurx}{\MPury}}} + +\def\dodouseMPbox#1#2#3#4#5% space delimiting would save some tokens + {\xdef\MPllx{#2}% but it's not worth the effort and looks + \xdef\MPlly{#3}% ugly as well + \xdef\MPurx{#4}% + \xdef\MPury{#5}% + \getobject{MP}{#1}} + +\def\nouseMPbox#1% + {\setxvalue{#1}% + {\noexpand\forgetall + \noexpand\loadMPgraphic{\MPgraphicfile.\the\currentMPgraphic}{}% + \noexpand\deallocateMPslot{\currentMPgraphic}% + \noexpand\placeMPgraphic}} + +\ifCONTEXT \else \let\douseMPbox\nouseMPbox \fi +\ifCONTEXT \else \let\doifobjectssupportedelse\relax \fi + +\long\def\handlereusableMPgraphic#1#2% + {\blabelgroup + \enableincludeMPgraphics + \startMPgraphic#2\stopMPgraphic + \doifobjectssupportedelse\donothing\useMPboxfalse + \ifuseMPbox + \expandafter \douseMPbox + \else + \expandafter \nouseMPbox + \fi {\@@MPG#1}% + \getvalue{\@@MPG#1}% + \elabelgroup} + +% \long\def\startreusableMPgraphic#1#2\stopreusableMPgraphic +% {\ifundefined{\@@MPG#1}% +% \long\setgvalue{\@@MPG#1}{\handlereusableMPgraphic{#1}{#2}}% +% \fi} + +\long\def\dostartreusableMPgraphic#1#2\stopreusableMPgraphic + {\blabelgroup + \long\setgvalue{\@@MPG#1}{\handlereusableMPgraphic{#1}{#2}}% + \elabelgroup} + +\def\reuseMPgraphic#1% + {\blabelgroup + \getvalue{\@@MPG#1}% + \elabelgroup} + +\let\stopreusableMPgraphic \relax % so that we can use it in \expanded + +%D \macros +%D {startuseMPgraphic,useMPgraphic} +%D +%D The every||time||it's||used original one is defined below. +%D This one makes sense when the graphic uses random numbers. +%D +%D We can run (process graphic) without including them at that +%D particular place. Therefore we explicitly disable +%D inclusions (resulting in an dummy figure) when we are in MP +%D run mode (see mfun-004 for an example, we process an +%D example buffer which produced graphics). + +\long\def\handleuseMPgraphic#1#2% + {\bgroup + \enableincludeMPgraphics + \startMPgraphic#2\stopMPgraphic + \ifMPrun \else + \loadMPgraphic{\MPgraphicfile.\the\currentMPgraphic}{}% + \placeMPgraphic + \fi + \deallocateMPslot\currentMPgraphic + \egroup} + +\long\def\startuseMPgraphic + {\blabelgroup + \obeyMPlines + \dostartuseMPgraphic} + +\long\def\dostartuseMPgraphic#1#2\stopuseMPgraphic + {\long\setgvalue{\@@MPG#1}{\handleuseMPgraphic{#1}{#2}}% + \elabelgroup} + +\long\def\startusableMPgraphic + {\blabelgroup + \obeyMPlines + \dostartusableMPgraphic} + +\long\def\dostartusableMPgraphic#1#2\stopusableMPgraphic + {\long\setgvalue{\@@MPG#1}{\handleuseMPgraphic{#1}{#2}}% + \elabelgroup} + +\let\useMPgraphic\reuseMPgraphic + +\let\stopuseMPgraphic \relax % so that we can use it in \expanded +\let\stopusableMPgraphic \relax % so that we can use it in \expanded + +%D \macros +%D {doifMPgraphicelse} +%D +%D For (mainly internal) purposes we provide a test macro. + +% \def\doifMPgraphicelse#1% +% {\doifdefinedelse{\@@MPG#1}} + +\def\doifMPgraphicelse#1% + {\blabelgroup + \doifdefinedelse{\@@MPG#1}% + {\elabelgroup\firstoftwoarguments} + {\elabelgroup\secondoftwoarguments}} + +%D \macros +%D {includeMPgraphic} +%D +%D In a graphic one can call up another (predefined one) +%D like: +%D +%D \starttyping +%D \startuseMPgraphic{a} +%D fill fullcircle scaled 100 ; +%D \stopuseMPgraphic +%D +%D \startuseMPgraphic{b} +%D \includeMPgraphic{a} +%D fill fullsquare rotated 45 scaled 50 withcolor red ; +%D \stopuseMPgraphic +%D +%D \useMPgraphic{b} +%D \stoptyping + +\def\includeMPgraphic#1% + {\executeifdefined{\@@MPG#1};} % ; if not found + +\def\enableincludeMPgraphics + {\let\handleuseMPgraphic \secondoftwoarguments + \let\handlereusableMPgraphic\secondoftwoarguments} + +%D We didn't yet define the macro responsible for processing +%D the graphic from within \TEX. + +\def\runMPgraphic#1% + {\ifrunMPgraphics + \executeMETAPOST{#1}% + \else + % \message{[flush and process \MPgraphicfile.mp afterwards]}% + \fi} + +%D \macros +%D {useMETAFUNformat} +%D +%D For faster running, one can generate a format, saying +%D +%D \starttyping +%D mpost -ini context +%D \stoptyping +%D +%D (The resulting \type {mem} file should be moved to the +%D right location. Watch out for misatching \type {progname} +%D directives, since they can clutter memory. + +\newif\ifuseMETAFUNformat + +%D \macros +%D {executeMetaPost, executeMETAPOST, executesystemcommand} +%D +%D With \type{\executeMETAPOST} being defined as: + +\ifx\undefined\executeMETAPOST + \def\executeMETAPOST#1{\executesystemcommand{\executeMetaPost{#1}}} +\fi + +%D There are two system dependant definitions: + +\ifx\undefined\executesystemcommand + \def\executesystemcommand#1{\immediate\write18{#1}} +\fi + +\ifx\TEXEXECcommand \undefined \def\TEXEXECcommand{texmfstart texexec} \fi + +\ifx\undefined\executeMetaPost + + \ifx\undefined\interactionmode \chardef\interactionmode=255 \fi + + \def\MPOSTbatchswitch {-interaction=batchmode} % was -int, but newer mpost does not support partial flags + \def\MPOSTnonstopswitch {-interaction=nonstopmode} % was -int, but newer mpost does not support partial flags + \def\MPOSTformatswitch {-progname=metafun -mem=} + \def\MPOSTdriver {dvips} + + \def\executeMPOST#1% direct call + {mpost + \ifcase\interactionmode\MPOSTbatchswitch\or\MPOSTnonstopswitch\fi + \space\ifuseMETAFUNformat \MPOSTformatswitch metafun \fi #1} + + \def\executeMPTEX#1% slower, due to nested texexec call + {\TEXEXECcommand\space + --batch \ifcase\interactionmode --logfile='mptex.log' \fi + --output=\MPOSTdriver\space + \ifuseMETAFUNformat --mpformat=metafun \fi --mptex --nomp --once #1} + + \def\executeMetaPost + {\ifrunMPTEXgraphics + \ifMPTEXgraphic + \@EAEAEA\executeMPTEX + \else + \@EAEAEA\executeMPOST + \fi + \else + \@EA\executeMPOST + \fi} + +\fi + +%D The batchmode and nonstopmode (introduced in 2003 for +%D Patrick Gundlach) switches may differ per binary and are +%D supported by \TEXEXEC. + +%D \macros +%D {insertMPfile} +%D +%D One can define this command in advance or redefine it after +%D loading this module. The same goes for the forward +%D reference to the figure loading macro: + +\ifx\undefined\insertMPfile + + \def\insertMPfile#1#2% + {\ifx\undefined\externalfigure + \message{[insert file #1 here]}% + \else + \externalfigure + [#1] + [\c!type=\c!mps,\c!object=\v!no, + \c!symbol=\v!yes,\c!reset=\v!yes, + \c!maxwidth=,\c!maxheight=, + \c!frame=\v!off,\c!background=, + #2]% + \fi} + +\fi + +%D This macro takes {\em two} arguments, the second one can be +%D used to pass info to the inclusion macro. Some examples +%D of its use can be found in the modules \type{supp-tpi} and +%D \type{prag-log}. + +%D This module can be used in \PLAIN\ \TEX too. When using +%D \DVIPS, just try to process: +%D +%D \starttyping +%D \input supp-mps +%D +%D \runMPgraphicstrue +%D +%D \def\insertMPfile#1#2% +%D {\special{psfile=#1}} +%D +%D \startuseMPgraphic{1} +%D prologues := 1; +%D draw (0,0) withpen pencircle scaled 100; +%D \stopuseMPgraphic +%D +%D \useMPgraphic{1} +%D \stoptyping +%D +%D Don't forget to enable \type{\write18}. When does not say +%D \type{\runMPgraphicstrue}, the \METAPOST\ scratch file +%D must be closed by saying +%D +%D \starttyping +%D \flushMPgraphics +%D \stoptyping +%D +%D When using the indirect method, one has to process the file +%D \type{mpgraph.mp} between two successive \TEX\ runs. +%D +%D \METAPOST\ needs the public domain \DVI\ to \POSTSCRIPT\ +%D converter \DVIPS. This symbiosis originates in the need to +%D include the fonts (glyphs) that \METAPOST\ uses in the +%D \POSTSCRIPT\ file. Driver independancy was one of my +%D prerequisites for using \METAPOST, so I decided to build +%D this kind of support myself. Personally I consider driver +%D dependancy a drawback for the dissemination of such a +%D package. The second part of this module more or less +%D decouples \METAPOST\ and \DVIPS. +%D +%D The macros hereafter are copied from the module +%D \type{m-metapost}. After writing module \type{supp-pdf} I +%D added this method to the module named and after a while +%D decided to hook it into module \type{spec-yy}. Therefore +%D they made it into a support module, but in a slightly +%D different way. + +%D \macros +%D {includeMPfonts, ifincludeMPfonts} +%D +%D The method we use is both robust and simple: one can do +%D with calling the next macro with the filename as argument: +%D +%D \starttyping +%D \includeMPfonts{filename} +%D \stoptyping +%D +%D We can turn of this mechanism with: +%D +%D \starttyping +%D \includeMPfontsfalse +%D \stoptyping +%D +%D {\em Currently this method fails for situations where the +%D font definition is not on one line, which is he case when +%D unkerned fonts are used along with long lines. One solution +%D for this is to increase the value of \type {max_print_line} +%D in \type {texmf.cnf}.}} + +\newif\ifincludeMPfonts \includeMPfontstrue + +\def\includeMPfonts#1% + {\ifincludeMPfonts + \bgroup + \message{[MP fonts #1]}% + %\uncatcodespecials + \endlinechar\minusone + \setMPspecials + \obeyMPspecials + \setbox\scratchbox\hbox + {\hskip-\maxdimen + \doprocessfile\scratchread{#1}\handleMPfont}% + \smashbox\scratchbox + \box\scratchbox + \egroup + \fi} + +\def\UseMetaPostGraphic {\includeMPfonts} % upward compatible +\def\DontUseMetaPostGraphics {\includeMPfontsfalse} % upward compatible + +%D The characters are collected in a box and moved as far as +%D possible into the left margin. The resulting box has no +%D dimensions and can be prepended (appended) to the special +%D that handles the inclusion. The characters are in the file +%D but made invisible. +%D +%D In \CONTEXT\ font handling is intergrated in the figure +%D inclusion macros. A decent plain \TEX\ alternative is: +%D +%D \starttyping +%D \def\includeMPgraphic#1% +%D {\hbox\bgroup +%D \includeMPfonts{#1}% +%D \dogetEPSboundingbox{#1}{\dimen2}{\dimen4}{\dimen6}{\dimen8}% +%D \advance\dimen6 by -\dimen2 +%D \advance\dimen8 by -\dimen4 +%D \vbox to \dimen8 +%D {\forgetall +%D \vfill +%D \hsize\dimen6 +%D \special +%D {PSfile="#1"\space +%D llx=\EPSllx\space +%D lly=\EPSlly\space +%D urx=\EPSurx\space +%D ury=\EPSury\space}}% +%D \egroup} +%D \stoptyping +%D +%D This macro needs \type {supp-eps.tex} and provided no +%D scaling. For \LATEX\ users the next one will do: +%D +%D \starttyping +%D \def\includeMPgraphic#1#% +%D {\hbox\bgroup +%D \def\includeMPgraphics##1% +%D {\includeMPfonts{##1}% +%D \includegraphics[typetype=mps,#1]{##1}% or whatever type they use +%D \egroup}% +%D \includeMPgraphics} +%D \stoptyping + +%D We scan the graphics file for the \type{fshow} operator, +%D that is, lines that start with \type{(}. If found it +%D interprets the line, which looks like: +%D +%D \starttyping +%D (string ... string) font size fshow +%D \stoptyping +%D +%D Font definitions specified in the preamble are simply +%D ignored. Only lines starting with \type{(} are interpreted. + +\def\dohandleMPfont#1#2\relax + {\if#1(\expandafter\includeMPcharacters\fileline\relax\fi} + +\def\handleMPfont + {\expandafter\dohandleMPfont\fileline\relax} + +%D Before we start scanning for data, we first change some +%D \CATCODES. The first set of macro's is copied from module +%D \type{supp-pdf}. This scheme is a bit overdone for this +%D module, but using the same macros saves us some memory. + +\def\octalMPcharacter#1#2#3% + {\char'#1#2#3\relax} + +\bgroup +\catcode`\|=\@@comment +\catcode`\%=\@@active +\catcode`\[=\@@active +\catcode`\]=\@@active +\catcode`\{=\@@active +\catcode`\}=\@@active +\catcode`B=\@@begingroup +\catcode`E=\@@endgroup +\gdef\keepMPspecials| + B\let%\letterpercent| + \def[B\noexpand[E| + \def]B\noexpand]E| + \def{B\noexpand{E| + \def}B\noexpand}EE +\gdef\ignoreMPspecials| + B\let%\letterpercent| + \def[BE| + \def]BE| + \def{BE| + \def}BEE +\gdef\obeyMPspecials| + B\def%B\char 37\relax E| + \def[B\char 91\relax E| + \def]B\char 93\relax E| + \def{B\char123\relax E| + \def}B\char125\relax EE +\gdef\setMPspecials| + B\setnaturalcatcodes + \catcode`\\=\@@escape + \catcode`\%=\@@active + \catcode`\[=\@@active + \catcode`\]=\@@active + \catcode`\{=\@@active + \catcode`\}=\@@active + \lccode`\-=0 | latex sets this to `\- + \lccode`\%=`\% | otherwise it's seen as a number + \def\(B\char40\relax E| + \def\)B\char41\relax E| + \def\\B\char92\relax E| + \def\0B\octalMPcharacter0E| + \def\1B\octalMPcharacter1E| + \def\2B\octalMPcharacter2E| + \def\3B\octalMPcharacter3E| + \def\4B\octalMPcharacter4E| + \def\5B\octalMPcharacter5E| + \def\6B\octalMPcharacter6E| + \def\7B\octalMPcharacter7E| + \def\8B\octalMPcharacter8E| + \def\9B\octalMPcharacter9EE +\egroup + +%D The lines starting with \type{(} are interpreted and +%D handled by +%D +%D \starttyping +%D \def\includeMPcharacters(#1) #2 #3 #4\relax% +%D {\font\temp=#2 at #3bp\temp#1} +%D \stoptyping +%D +%D While processing some \TUG~98 proceedings, I also had to +%D deal with: +%D +%D \starttyping +%D /nfont {10 div dup scale 10} def +%D (T) ANTTB 7.13086 nfont fshow +%D \stoptyping +%D +%D which comes to rounding sizes. This is something +%D experimental. (The macro in supp-pdf.tex is more +%D advanced.) + +\def\PSnfont{nfont} + +\def\includeMPcharacters(#1) #2 #3 #4#5#6#7#8#9\relax + {\edef\temp{#4#5#6#7#8}% + \ifx\temp\PSnfont % round font size (to pt) + \scratchdimen#3\onepoint + \ifdim\scratchdimen<\onepoint + \def\size{1pt}% + \else + \advance\scratchdimen .5\onepoint + \def\size##1.##2\relax{\def\size{##1pt}}% + \expandafter\size\the\scratchdimen\relax + \fi + \else + \edef\size{#3bp}% + \fi + \font\temp=#2 at \size + \temp\if#1 \char32\else#1\fi} + +%D This method is both robust and reasonable fast. The only +%D disadvantage is that when not embedded properly in the +%D graphics inclusion macros, one has to load all graphics by +%D hand. + +%D Now let's see if things work all right and show the example +%D files that are part of the \METAPOST\ distribution: +%D +%D \setupexternalfigures[directory={../sample}] +%D \startlinecorrection +%D \setupalign[middle] +%D \leavevmode +%D \startcombination[3*3] +%D {\externalfigure[mp-exa-1][frame=on,width=.2\hsize]} {} +%D {\externalfigure[mp-exa-2][frame=on,width=.2\hsize]} {} +%D {\externalfigure[mp-exa-3][frame=on,width=.2\hsize]} {} +%D {\externalfigure[mp-exa-4][frame=on,width=.2\hsize]} {} +%D {\externalfigure[mp-exa-5][frame=on,width=.2\hsize]} {} +%D {\externalfigure[mp-exa-6][frame=on,width=.2\hsize]} {} +%D {\externalfigure[mp-exa-7][frame=on,width=.2\hsize]} {} +%D {\externalfigure[mp-exa-8][frame=on,width=.2\hsize]} {} +%D {\externalfigure[mp-exa-9][frame=on,width=.2\hsize]} {} +%D \stopcombination +%D \stoplinecorrection +%D +%D Here we used calls like: +%D +%D \starttyping +%D \externalfigure[mp-exa-1][methode-mps,frame=on,width=.2\hsize] +%D \stoptyping + +%D \macros +%D {convertMPcolors, +%D ifconvertMPcolors,ifreduceMPcolors,ifforceMPcolors} +%D +%D When I told the editors that I wanted to use colored +%D \METAPOST\ graphics in the color issue of the \MAPS, I was +%D asked to use the \cap{CMYK} colorspace instead of \cap{RGB} +%D one. However, \METAPOST\ only supports \cap{RGB} colors. I +%D decided to write a utility to convert the \type +%D {setrgbcolor} operators into \type {setcmykcolor} ones, and +%D some experiments showed me that I could best let \TEX\ do it +%D itself. Here it is: +%D +%D There are two booleans that control the conversion process. +%D These are false by default. + +\newif\ifconvertMPcolors +\newif\ifreduceMPcolors +\newif\ifforcegrayMPcolors + +%D The main macro is called as: +%D +%D \starttyping +%D \convertMPcolors{filename} +%D \stoptyping +%D +%D When active, this macro returns a message saying if indeed +%D conversion took place. The old file is overwritten! This +%D saves time in a succesive passes and can't harm, simply +%D because MP can generate them anew. + +\def\convertMPcolorpath{} +\def\convertMPcolorfile{metacmyk.tmp} + +\def\convertMPcolors#1% todo: open on local path, no copy + {\bgroup + \ifforcegrayMPcolors + \donetrue + \else\ifconvertMPcolors + \donetrue + \else + \donefalse + \fi\fi + \ifdone + \message{[MP color conversion #1}% + \endlinechar\minusone + \uncatcodespecials + \donefalse + \immediate\openout\scratchwrite\convertMPcolorpath\convertMPcolorfile\relax + \doprocessfile\scratchread{#1}\handleMPcolor + \immediate\closeout\scratchwrite + \ifdone + \immediate\openout\scratchwrite\convertMPcolorpath#1\relax + \doprocessfile\scratchread{\convertMPcolorpath \convertMPcolorfile}\handleMPcopy + \immediate\closeout\scratchwrite + \message{done]}% + \else + \message{not needed]}% + \fi + \immediate\openout\scratchwrite\convertMPcolorpath\convertMPcolorfile + \immediate\closeout\scratchwrite + \fi + \egroup} + +%D The process is rather simple: read a line, look for the +%D \type {setrgbcolor} operator, recalculate the components and +%D check for gray reduction or black removal, write the result +%D to a temporary file, and go on. Afterwards, the file is +%D copied back. We don't have to reduce to gray scales; +%D \METAPOST\ already takes care of that. + +%D The next macro is needed for forced conversion. This macro +%D is copied from \type{colo-ini}, just in case one uses this +%D module outside \CONTEXT. + +\ifx\@@cl@@s \undefined \def\@@cl@@s{0} \fi + +\ifx\convertRGBtoGRAY\undefined + +\def\convertRGBtoGRAY#1#2#3% + {\scratchdimen#1\onepoint + \scratchdimen300\scratchdimen + \scratchcounter\scratchdimen + \scratchdimen#2\onepoint + \scratchdimen590\scratchdimen + \advance\scratchcounter \scratchdimen + \scratchdimen#3\onepoint + \scratchdimen110\scratchdimen + \advance\scratchcounter \scratchdimen + \advance\scratchcounter \!!medcard + \divide\scratchcounter \!!maxcard + \edef\@@cl@@s{\realcolorvalue\scratchcounter}} + +\fi + +%D BTW, this code is quite old, and not as complete as the +%D \PDF\ converter, which also handles spot colors and so. + +\def\handleMPcolor + {\expandafter\dohandleMPcolor\fileline setrgbcolor*\\} + +\def\dohandleMPcolor#1setrgbcolor#2#3\\% + {\if#2*% + \immediate\write\scratchwrite{#1}% + \else + \dodohandleMPcolor#1setrgbcolor#2#3\\% + \fi} + +\def\dodohandleMPcolor#1 #2 #3setrgbcolor#4setrgbcolor*\\% old and maybe broke + {\bgroup + \ifdim#1pt=.123pt + \immediate\write\scratchwrite{#1 #2 #3 setrgbcolor}% + \else + \ifforcegrayMPcolors + \convertRGBtoGRAY{#1}{#2}{#3}% + \immediate\write\scratchwrite + {\@@cl@@s \space setgray #4}% + \else + \dimen0=\onepoint \advance\dimen0 -#1\points + \dimen2=\onepoint \advance\dimen2 -#2\points + \dimen4=\onepoint \advance\dimen4 -#3\points + \ifreduceMPcolors + \dimen6\dimen0 + \ifdim\dimen2<\dimen6 \dimen6\dimen2 \fi + \ifdim\dimen4<\dimen6 \dimen6\dimen4 \fi + \advance\dimen0 -\dimen6 + \advance\dimen2 -\dimen6 + \advance\dimen4 -\dimen6 + \else + \dimen6\zeropoint + \fi + \immediate\write\scratchwrite + {\withoutpt\the\dimen0 \space + \withoutpt\the\dimen2 \space + \withoutpt\the\dimen4 \space + \withoutpt\the\dimen6 \space setcmykcolor #4}% + \fi + \fi + \egroup + \donetrue} % needed for message + +\def\handleMPcopy + {\immediate\write\scratchwrite{\fileline}} + +%D The next examples show the color conversion macros in +%D action. These examples also demonstrate in||text \METAPOST\ +%D handling. As we will see, the conversion is hooked into the +%D \CONTEXT\ color mechanism. +%D +%D By setting both \type{rgb} and \type{cmyk} to off, we force +%D conversion to gray scales using: +%D +%D \placeformula[-] +%D \startformula +%D G = .30r + .59g + .11b +%D \stopformula +%D +%D By using buffers, we keep the \ASCII\ layout clean: +%D +%D \startbuffer +%D \startbuffer[rgb] +%D \setupcolors[rgb=ja,cmyk=nee,reduction=no,conversion=no] +%D \useMPgraphic{hans} +%D \stopbuffer +%D +%D \startbuffer[cmyk] +%D \setupcolors[rgb=nee,cmyk=ja,reduction=no,conversion=no] +%D \useMPgraphic{hans} +%D \stopbuffer +%D +%D \startbuffer[cmy] +%D \setupcolors[rgb=nee,cmyk=ja,reduction=yes,conversion=no] +%D \useMPgraphic{hans} +%D \stopbuffer +%D +%D \startbuffer[gray] +%D \setupcolors[rgb=nee,cmyk=nee,reduction=no,conversion=no] +%D \useMPgraphic{hans} +%D \stopbuffer +%D \stopbuffer +%D +%D \typebuffer +%D \getbuffer +%D +%D The graphic is rather simple and is generated each time +%D it's called: +%D +%D \global\runMPgraphicstrue +%D +%D \startbuffer +%D \startbuffer[graphic] +%D \startuseMPgraphic{hans} +%D width :=\the\textwidth/5; +%D height := width/4; +%D fill fullcircle +%D xscaled width +%D yscaled height +%D withcolor (\RedGreenBlue); +%D \stopuseMPgraphic +%D \stopbuffer +%D \stopbuffer +%D +%D \typebuffer +%D \getbuffer +%D +%D Next we combine the four alternative interpretations in a +%D combination: +%D +%D \startbuffer +%D \startbuffer[result] +%D \startcombination[4] +%D {\getbuffer[rgb]} {\tfxx original} +%D {\getbuffer[cmyk]} {\ttxx\string\convertMPcolorstrue} +%D {\getbuffer[cmy]} {\ttxx\string\reduceMPcolorstrue} +%D {\getbuffer[gray]} {\ttxx\string\forcegrayMPcolorstrue} +%D \stopcombination +%D \stopbuffer +%D \stopbuffer +%D +%D \typebuffer +%D \getbuffer +%D +%D Finally we call the buffers, using different setting: +%D +%D \startbuffer +%D \placefigure +%D {\METAPOST\ color conversions} +%D {\def\RedGreenBlue{.1,.4,.6}\getbuffer[graphic]\getbuffer[result]\vskip6pt +%D \def\RedGreenBlue{.1,.6,.4}\getbuffer[graphic]\getbuffer[result]\vskip6pt +%D \def\RedGreenBlue{.4,.1,.6}\getbuffer[graphic]\getbuffer[result]\vskip6pt +%D \def\RedGreenBlue{.4,.6,.1}\getbuffer[graphic]\getbuffer[result]\vskip6pt +%D \def\RedGreenBlue{.6,.1,.4}\getbuffer[graphic]\getbuffer[result]\vskip6pt +%D \def\RedGreenBlue{.6,.4,.1}\getbuffer[graphic]\getbuffer[result]} +%D \stopbuffer +%D +%D \typebuffer +%D \getbuffer +%D +%D By the way, when the \POSTSCRIPT\ file resulting from +%D this input is converted into \PDF\ and viewed in Acrobat +%D Reader, one can quite different colors from those +%D displayed in \GHOSTSCRIPT, which view equals the +%D \POSTSCRIPT\ originals. + +%D \macros +%D {experimental} +%D +%D Some experimental macros: +%D +%D \starttyping +%D \startMPdrawing +%D \stopMPdrawing +%D \pushMPdrawing +%D \popMPdrawing +%D \resetMPdrawing +%D \ifMPdrawingdone +%D \getMPdrawing +%D \MPdivten[number] +%D \stoptyping +%D +%D These macros are used in \PPCHTEX. + +\let\MPdrawingdata\empty + +\newif\ifMPdrawingdone \MPdrawingdonefalse +\newif\ifMPshiftdrawing \MPshiftdrawingfalse + +\def\resetMPdrawing + {\globallet\MPdrawingdata\empty + \global\MPdrawingdonefalse} + +% why global push/pop here? + +\def\pushMPdrawing + {\globalpushmacro\MPdrawingdata + \globallet\MPdrawingdata\empty} + +\def\popMPdrawing + {\globalpopmacro\MPdrawingdata} + +\def\getMPdrawing + {\ifMPdrawingdone + \expandafter\startMPgraphic\MPdrawingdata\stopMPgraphic + \loadcurrentMPgraphic{}% + \deallocateMPslot\currentMPgraphic + \placeMPgraphic + \fi} + +\def\startMPdrawing + {\dosingleempty\dostartMPdrawing} + +\long\def\dostartMPdrawing[#1]#2\stopMPdrawing + {\relax + \bgroup + \enableincludeMPgraphics + \presetMPdefinitions % in case #2 has measures + \doifelse{#1}{-}{\convertargument#2\to\asciia}{\long\def\asciia{#2}}% + \long\xdef\MPdrawingdata{\MPdrawingdata\asciia}% + \egroup} + +\let\stopMPdrawing\relax + +\def\MPdivten[#1]% + {\@EA\@EA\@EA\doMPdivten\@EA\@EA\@EA[\@EA#1]} + +\def\doMPdivten[#1]% + {\ifnum#1> 9999 \dodoMPdivtenB#1\else + \ifnum#1> 999 \dodoMPdivtenC#1\else + \ifnum#1> 99 \dodoMPdivtenD#1\else + \ifnum#1> 9 \dodoMPdivtenE#1\else + \ifnum#1> 0 \dodoMPdivtenF#1\else + \ifnum#1<-9999 \dodoMPdivtenA#1\else + \ifnum#1< -999 \dodoMPdivtenB#1\else + \ifnum#1< -99 \dodoMPdivtenC#1\else + \ifnum#1< -9 \dodoMPdivtenD#1\else + \ifnum#1< 0 \dodoMPdivtenE#1\else + 0 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} + +\def\dodoMPdivtenA#1#2#3#4#5#6{#1#2#3#4#5.#6} +\def\dodoMPdivtenB #1#2#3#4#5{#1#2#3#4.#5} +\def\dodoMPdivtenC #1#2#3#4{#1#2#3.#4} +\def\dodoMPdivtenD #1#2#3{#1#2.#3} +\def\dodoMPdivtenE #1#2{#1.#2} +\def\dodoMPdivtenF #1{.#1} + +% if we assume etex ... \def\MPdivten[#1]{\withoutpt\the\dimexpr#1pt/10\relax} + +%D \macros +%D {startMPclip,grabMPclippath} +%D +%D We can use \METAPOST\ to calculate arbitrary clipping +%D paths. Such a path is defined by (for instance): +%D +%D \starttyping +%D \startMPclip{window} +%D clip currentpicture to fullcircle xscaled \width yscaled \height ; +%D \stopMPclip +%D \stoptyping +%D +%D Such a path can be extracted (processed) by: +%D +%D \starttyping +%D \grabMPclippath{window}{method}{width}{height}{default path} +%D \stoptyping +%D +%D Currently only method 1 makes sense; it produces \PDF\ +%D code. This macro only makes sense when hooked into a +%D special routine. + +\let\MPclippath\empty + +\long\def\startMPclip#1#2\stopMPclip + {\blabelgroup + \long\setgvalue{MPC:#1}{\startMPgraphic#2\stopMPgraphic\dograbMPclippath}% + \elabelgroup} + +\let\stopMPclip\relax + +\def\grabMPclippath#1#2#3#4#5% + {\blabelgroup + \edef\width {#3\space}\let\overlaywidth \width + \edef\height{#4\space}\let\overlayheight\height + \doifdefinedelse{MPC:#1} + {\getvalue{MPC:#1}% + \setxvalue{MPC:#1}{\noexpand\xdef\noexpand\MPclippath{\MPclippath}}}% + {\xdef\MPclippath{#5}}% + \ifcase#2\else % method 1 : + \doglobal\stripcharacter urveto\from\MPclippath\to\MPclippath + \doglobal\stripcharacter oveto\from\MPclippath\to\MPclippath + \doglobal\stripcharacter ineto\from\MPclippath\to\MPclippath + \fi + \elabelgroup} + +%D We pose some restrictions to the \METAPOST\ code and pickup +%D the clip path from the file. +%D +%D We turn the slash into a comment. The \type {\hbox} grabs spaces +%D and the \type {%} triggers the grabber. Next we filter the +%D clipping path, or actually, the first path. + +% \bgroup +% \catcode`\%=\@@active +% \catcode`\/=\@@comment +% \gdef\dograbMPclippath/ +% {\setbox\scratchbox=\hbox\bgroup/ +% \catcode`\%=\@@active +% \obeylines\let\obeyedline\space +% \def\do##1newpath##2closepath##3\od/ +% {\xdef\MPclippath{##2}\endinput}/ +% \def%##1%%EOF/ +% {\do##1newpathclosepath\od\endinput}/ +% \readfile{\MPgraphicfile.\the\currentMPgraphic}{}{}/ +% \deallocateMPslot\currentMPgraphic / new +% \egroup} +% \egroup + +\bgroup +\catcode`\%=\@@active +\catcode`\/=\@@comment +\gdef\dograbMPclippath/ + {\setbox\scratchbox=\hbox\bgroup/ + \catcode`\%=\@@active + \obeylines\let\obeyedline\space + \def\do##1q n##2p W##3\od/ + {\xdef\MPclippath{##2}\endinput}/ + \def%##1%%EOF/ + {\do##1q np W\od\endinput}/ + \readfile{\MPgraphicfile.\the\currentMPgraphic}{}{}/ + \ifx\MPclippath\empty + \def\do##1newpath##2closepath##3\od/ + {\xdef\MPclippath{##2}\endinput}/ + \def%##1%%EOF/ + {\do##1newpathclosepath\od\endinput}/ + \readfile{\MPgraphicfile.\the\currentMPgraphic}{}{}/ + \fi + \deallocateMPslot\currentMPgraphic / new + \egroup} +\egroup + +%D \macros +%D {recycleMPslots} +%D +%D When coding and embedding many \METAPOST\ figures in a +%D document, one can save quite some disk space by using +%D \PDFTEX\ and setting the next switch: + +\newif\ifrecycleMPslots \recycleMPslotstrue + +%D When a graphic takes space in the text flow, we can run +%D into deadlock typesetting. In the first pass, the graphic +%D is not available, but in the second pass it is. The +%D placeholder that was put there in the first pass in now +%D replace by the real graphic and as a result the document +%D shrinks or grows and pages are removed or added. This in +%D turn can trigger generation of other graphics, like those +%D in the background. Graphics start swapping place and again +%D page breaks change. You can imagine the mess we en dup +%D with. +%D +%D This is why we provide was to use a dedicate range if +%D numbers for fixed graphcs. Such graphics will not en dup +%D in the text flow (at least their dimensions don't +%D contribute to the main vertical list, and thereby they +%D cannot interfere. We use a rather safe maximum of 4000 +%D graphics here and 8000 in \type {meta-ini}. + +\newcount \maxnofMPgraphics \maxnofMPgraphics = 4000 % 8000 +\newcount \minnofMPgraphics \minnofMPgraphics = 1 + +\newif \ifMPstaticgraphic \MPstaticgraphicfalse % determines slot allocation + +\def\locateMPslot#1% slightly faster on one slot, much faster on multiple slots + {\ifundefined{\number#1MP}% no \ifcsname + \letgvalueempty{\number#1MP}% + \expandafter\gobbletwoarguments + \else + \global\advance#1\plusone + \fi + \locateMPslot#1} + +\def\allocateMPslot#1% + {\ifrunMPgraphics + \ifx\pdfliteral\undefined + \recycleMPslotsfalse % quite certainly not pdftex + \else\ifcase\pdfoutput + \recycleMPslotsfalse % dvi mode or not pdftex (we need to handle dvipdfmx) + \fi\fi + \else + \recycleMPslotsfalse + \fi + \ifrecycleMPslots + % \doloop % slow but used seldom + % {\doifundefined{\recurselevel MP} + % {\letgvalueempty{\recurselevel MP}% + % \global#1\recurselevel + % \exitloop}}% + \global#1\plusone + \locateMPslot#1% + % \message{[MP slot + \number#1]% + \else\ifMPstaticgraphic % beware not the same as static graphics + \global#1\maxnofMPgraphics + \global\advance\maxnofMPgraphics \minusone + \else + \global#1\minnofMPgraphics + \global\advance\minnofMPgraphics \plusone + \fi\fi + \ifnum\minnofMPgraphics<\maxnofMPgraphics \else + \writestatus\m!systems{increase \string\maxnofMPgraphics}% + \fi} + +\def\deallocateMPslot#1% + {\ifrunMPgraphics + \ifcase\pdfoutput \recycleMPslotsfalse \fi + \else + \recycleMPslotsfalse + \fi + \ifrecycleMPslots + \global\letbeundefined{\number#1MP}% + %\message{[MP slot - \number#1]}% + \fi} + +%D Experimental and overloaded later, since we need to be +%D more clever due to \METAPOST's limit of 4~open files. + +\def\MPdatafile + {mp-\the\currentMPgraphic.mpd} + +\def\getMPdata + {\input \MPdatafile\relax} + +%D \macros +%D {MPtoks, MPbox} +%D +%D For convenience, we provide some scratch registers: + +\ifx\undefined\MPtoks \newtoks\MPtoks \fi +\ifx\undefined\MPbox \newbox \MPbox \fi + +%D \macros +%D {startMPcode} +%D +%D We can save some typing with: +%D +%D \starttyping +%D \startMPcode whatever \stopMPcode +%D \stoptyping +%D +%D this automatically places the graphic + +\long\def\startMPcode + {\begingroup + \obeyMPlines + \dostartMPcode} + +\long\def\dostartMPcode#1\stopMPcode + {\startuseMPgraphic{@@}#1\stopuseMPgraphic + \useMPgraphic{@@}% + \endgroup} + +\let\stopMPcode\relax + +%D \macros +%D {startstaticMPgraphic} +%D +%D Dedicated to Aditya Mahajan. See meta-ini for usage. + +% \long\def\startstaticMPgraphic#1#2\stopstaticMPgraphic +% {\bgroup +% \MPstaticgraphictrue +% \setMPrandomseedfalse +% \def\MPgraphicfile{#1}% no \jobname here +% \let\allocateMPslot \gobbleoneargument +% \let\deallocateMPslot\gobbleoneargument +% \let\runMPgraphic \gobbleoneargument +% \MPextensions\emptytoks +% \MPinitializations\emptytoks +% \runMPgraphicstrue +% \MPwrapperfalse +% \enableincludeMPgraphics +% \def\sometxt##1{\string\sometxt{##1}}% +% \currentMPgraphic\plusone % hack, else no close +% \startMPgraphic#2\stopMPgraphic +% \executeMPgraphicfile +% \egroup} + +% different version, less messy hooked into the rest + +\long\def\startstaticMPgraphic#1#2\stopstaticMPgraphic + {\blabelgroup + \def\MPgraphicfile{#1}% no \jobname here + \let\MPwrite\MPstaticwrite + \immediate\openout\MPwrite=\MPgraphicfile.mp + \setMPrandomseedfalse + \enableincludeMPgraphics + \def\sometxt##1{\string\sometxt{##1}}% + \the\everyMPgraphic + \presetMPdefinitions + \theMPinclusions % brrr + \writeMPgraphic{\letterpercent mpenvironment: \the\everyMPTEXgraphic}% + \writeMPgraphic{beginfig(1);}% + \writeMPgraphic{#2}% + \writeMPgraphic{endfig; end.}% + \immediate\closeout\MPwrite + \executeMPgraphicfile + \elabelgroup} + +% this will go to meta-ini + +\def\delaysystemcommand + {\ifx\installprogram\undefined + \expandafter\executesystemcommand + \else + \expandafter\installprogram + \fi} + +\def\MPgraphicfilerunner + {texmfstart --ifchanged=\MPgraphicfile.mp texexec --mpstatic \MPgraphicfile.mp} + +\ifx\doifmode\undefined + \def\executeMPgraphicfile + {\ifrunMPgraphics\@EA\executesystemcommand\else\@EA\delaysystemcommand\fi{\MPgraphicfilerunner}} +\else + \def\executeMPgraphicfile{\doifmode{*\v!first} + {\ifrunMPgraphics\@EA\executesystemcommand\else\@EA\delaysystemcommand\fi{\MPgraphicfilerunner}}} +\fi + +%D Special for \XETEX\ (problem with newlines). This will go +%D away once the version supporting \type {--8bit} is +%D widespread. + +\ifnum\texengine=\xetexengine + \let\obeyMPlines\relax + \longMPlinesfalse % alas +\fi + +\protect \endinput diff --git a/tex/context/base/supp-mrk.mkii b/tex/context/base/supp-mrk.mkii new file mode 100644 index 000000000..eb1865471 --- /dev/null +++ b/tex/context/base/supp-mrk.mkii @@ -0,0 +1,591 @@ +%D \module +%D [ file=supp-mrk, +%D version=1995.10.10, +%D title=\CONTEXT\ Support Macros, +%D subtitle=Marks, +%D author=Jim Fox / Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Remark: due to the lack of \type {\clearmark}, the \ETEX\ +%D dedicated mechanism is not yet operational. + +%D This module has deverted so much from the original that I +%D can probably rewrite it to a more efficient one now and +%D I will do so. + +%D There are 256 \COUNTERS, \DIMENSIONS, \SKIPS, \MUSKIPS\ and +%D \BOXES, 16~in- and output buffers, but there is only one +%D \MARK. In TugBoat~8 (1987, no~1) Jim Fox presents a set of +%D macros that can be used to mimmick multiple marks. We +%D gladly adopt them here. I may rewrite this module from +%D scratch some day, since some low level \CONTEXT\ commands +%D can be used. +%D +%D This module was changed on behalf of \ETEX. The main +%D extension is that \type{\get..} and alike is used instead of +%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} + +\unprotect + +%D We start with the presetting the interface macros. +%D +%D \starttabulate[|||] +%D \NC \type{\getmarks} \NC sets the marks to their values \NC \NR +%D \NC \type{\getallmarks} \NC sets all marks to their values \NC \NR +%D \NC \type{\getsplitmarks} \NC sets the splitmarks to their values\NC \NR +%D \NC \type{\getallsplitmarks} \NC sets all splitmarks to their values\NC \NR +%D \NC \type{\setmarks} \NC synchronizes topmarks (\ETEX) \NC \NR +%D \stoptabulate +%D +%D Later we will overload these, dependent of the brand of +%D \TEX\ that we use. + +\let \getmarks \gobbleoneargument +\let \getallmarks \relax +\let \getsplitmarks \gobbleoneargument +\let \getallsplitmarks \relax +\let \setallmarks \relax + +\let \newmark \gobbleoneargument +\let \newpersistentmark \gobbleoneargument +\let \resetmark \gobbleoneargument +\let \setmark \gobbletwoargument + +%D \macros +%D {expandmarks} +%D +%D We can force expansion of marks with the following switch. + +\newif\ifexpandmarks \expandmarkstrue % hm, true indeed ? + +\beginTEX + +%D This implementation is more or less compatible with the +%D other \type {\new} macros in \PLAIN\ \TEX. A mark is +%D defined by: +%D +%D \starttyping +%D \newmark\name +%D \stoptyping +%D +%D and can be called upon with: +%D +%D \starttyping +%D \gettopmark \name % or \topname +%D \getbotmark \name % or \botname +%D \getfirstmark\name % or \firstname +%D \stoptyping +%D +%D The only drawback of his approach is that the marks must be +%D preloaded in the output routine. This is accomplished by +%D means of: +%D +%D \starttyping +%D \getmarks\name +%D \stoptyping +%D +%D The macros presented here are in most aspects copies of +%D those presented by Jim Fox. We've taken the freedom to +%D change a few things for more or less obvious reasons: +%D +%D \startitemize +%D \item Because the original macros look quite complicated, +%D which is mainly due to extensive use of +%D \type{\expandafter}'s and \type{\csname}'s, we changed +%D those in favor of \type{\getvalue}. +%D \item To be more in line with the rest of \CONTEXT, we've +%D changed some of the names of macros. +%D \item Because we are already short on \COUNTERS\ we use +%D macros when possible. +%D \item We maintain a list of defined marks and use one +%D call for getting them all at once. +%D \item We have extended the mechanism to splitmarks (not +%D perfected yet). +%D \item We've introduced optional expansion of the contents +%D of marks. +%D \stopitemize +%D +%D Whatever changes we've made, the credits still go to Jim, +%D whatever goes wrong is due to me. The method is described +%D in the TugBoat mentioned before, so we won't go into +%D details. All marks belonging to a group are packed in a +%D list. In this list they are preceded by a macro that can +%D be defined at will and a number concerning the position at +%D which it was defined. +%D +%D \starttyping +%D \def\somelist{... \domark5{this} ... \domark31{that} ...} +%D \stoptyping +%D +%D The original \type{\mark} keeps track of the number and +%D \type{\topmark} and \type{\botmark} are used to extract the +%D actual marks from the list. The counting is done by +%D +%D \starttyping +%D \currentmarker +%D \stoptyping +%D +%D In \CONTEXT\ we use the mark mechanism to keep track of +%D colors. In a complicated documents with many colors per +%D page, \type{\currentmarker} can therefore get pretty high. +%D (Well, this is not completely true, because we don't +%D always have to use marks.) + +\newcount\currentmarker + +%D The original implementation used a few more \COUNTERS. Two +%D have been substituted by macros, one has been replaced by +%D our scratch counter. +%D +%D \starttyping +%D \newcount\topmarker +%D \newcount\botmarker +%D \newcount\foundmarker +%D \stoptyping +%D +%D We've also introduced some constants, one for the lists and +%D three for composing the mark commands. + +\def\@@marklist@@ {*m*} % {marklist} +\def\@@marktop@@ {*t*} % {top} +\def\@@markbot@@ {*b*} % {bot} +\def\@@markfirst@@ {*f*} % {first} +\def\@@markcurrent@@ {*c*} % {current} + +%D The next one is new too. All defined marks are packed in a +%D comma seperated list. This could of course have been a token +%D list but \CONTEXT\ has some preference for comma lists. + +\let\allmarks=\empty + +%D The next macro replaces the multiple step expansion and +%D command name constructors of Jim. This alternative leads to +%D a more readable source (we hope). + +\def\makemarknames#1% kan genest werken + {\bgroup + \escapechar=-1 + \xdef\markname{\string#1}% + \xdef\marklist{\@@marklist@@\markname}% + \egroup} + +%D \macros +%D {newmark,resetmark} +%D +%D A mark is defined by \type{\newmark}. At the same time, +%D the name of the mark is added to a commalist. The +%D three initializations were not in the original design, but +%D make calls from outside the output routine a bit more +%D robust. + +\let\domark\relax % saves a restore on the stack + +\def\definenewmark#1#2% + {\bgroup + \makemarknames{#1}% + #2% + \letgvalueempty{\@@markcurrent@@\markname}% + \letgvalueempty{\@@marktop@@ \markname}% + \letgvalueempty{\@@markfirst@@ \markname}% + \letgvalueempty{\@@markbot@@ \markname}% + \setgvalue{\marklist}{\domark0{}}% beware of halfway definitions + \long\gdef#1{\addmarker#1}% + \egroup} + +\def\newmark#1% + {\definenewmark#1{\doglobal\addtocommalist\markname\allmarks}} + +%D Don't ask me, but sometimes we need more control over +%D updating the marks, thereby we have: + +\def\newpersistentmark#1% for an example see core-grd.tex + {\definenewmark#1\relax} + +\let\setmark \empty +\let\resetmark\newmark + +%D Some more natural interfacing macros: + +\def\getcurrentmark #1{\getvalue{\@@markcurrent@@\strippedcsname#1}} +\def\gettopmark #1{\getvalue{\@@marktop@@ \strippedcsname#1}} +\def\getbottommark #1{\getvalue{\@@markbot@@ \strippedcsname#1}} +\def\getfirstmark #1{\getvalue{\@@markfirst@@ \strippedcsname#1}} +\def\getsplitbottommark#1{\getvalue{\@@markbot@@ \strippedcsname#1}} +\def\getsplitfirstmark #1{\getvalue{\@@markfirst@@ \strippedcsname#1}} + +%D \macros +%D {setmark} +%D +%D Setting a new mark and adding a mark to the designated +%D list is done by \type{\addmarker}. This is an internal +%D command, the user set a marks bij calling it's name: +%D +%D \starttyping +%D \setmark\mymark{some text} % or \mymark{some text} +%D \stoptyping +%D +%D Where \type{\mymark} is previously defined by +%D \type{\newmark}. + +\long\def\addmarker#1#2% + {\bgroup + \makemarknames{#1}% + \setgvalue{\@@markcurrent@@\markname}{#2}% + \global\advance\currentmarker \plusone + \normalmark{\the\currentmarker}% + \!!toksa\@EA\@EA\@EA{\csname\marklist\endcsname}% + \ifexpandmarks + \setxvalue\marklist + {\the\!!toksa + \noexpand\domark + \the\currentmarker{#2}}% + \else + \!!toksb\@EA{#2}% one level, why ? handy for cs + \setxvalue\marklist + {\the\!!toksa + \noexpand\domark + \the\currentmarker{\the\!!toksb}}% + \fi + \egroup} + +%D \macros +%D {getmarks,getallmarks, +%D getsplitmarks,getallsplitmarks} +%D +%D In fact, marks make only sense in the output routine. Marks +%D are derived from their list by means of \type{\getmarks}. +%D Only one call per mark is permitted in the output routine. +%D Therefore, it's far more easy to get them all at once, by +%D means of \type{\getallmarks}, which is not part of the +%D original design. +%D +%D This grabbing is done by processing the list using the +%D embedded \type{\domark} macros. When a relevant mark is +%D found, this macro is reassigned and from then on serves +%D in building the new list. + +% 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). + +\newif\ifnofirstmarker % an auxiliary switch + +\def\getmarks#1% + {\bgroup + \makemarknames{#1}% + \edef\topmarker{0\normaltopmark}% + \edef\botmarker{0\normalbotmark}% + \!!toksa\emptytoks + \!!toksb\emptytoks + \nofirstmarkertrue + % does more worse than good + \let\fi\relax + \let\or\relax + \let\else\relax + % + \let\domark\doscanmarks + \getvalue\marklist\lastmark + %\message{markstatus : [\the\!!toksa\the\!!toksb\the\!!toksc]}% + \long\setxvalue\marklist{\the\!!toksa\the\!!toksb\the\!!toksc}% + \egroup} + +\def\getsplitmarks#1% + {\bgroup + \makemarknames{#1}% + % \@EA\let\@EA\savedmarklist\@EA\csname\marklist\endcsname + \edef\topmarker{0\normalsplitfirstmark}% + \edef\botmarker{0\normalsplitbotmark}% + \!!toksa\emptytoks + \!!toksb\emptytoks + \nofirstmarkertrue + % does more worse than good + \let\fi\relax + \let\or\relax + \let\else\relax + % + \let\domark\doscanmarks + \getvalue\marklist\lastmark + % \global\@EA\let\csname\marklist\endcsname\savedmarklist + \egroup} + +\def\getallmarks {\processcommacommand[\allmarks]\getmarks} +\def\getallsplitmarks{\processcommacommand[\allmarks]\getsplitmarks} + +\def\getallmarks {\@EA\processcommalist\@EA[\allmarks]\getmarks} +\def\getallsplitmarks{\@EA\processcommalist\@EA[\allmarks]\getsplitmarks} + +\long\def\dodoscanmarks#1% + {\ifnum\scratchcounter>\topmarker\relax + \normalelse + \long\setgvalue{\@@marktop@@\markname}{#1}% + \normalfi + \ifnum\scratchcounter>\botmarker\relax + \let\domark\dorecovermarks + \!!toksb\@EA{\@EA\domark\the\scratchcounter{#1}}% + \normalelse + \ifnofirstmarker + \long\setgvalue{\@@markfirst@@\markname}{#1}% + \ifnum\scratchcounter>\topmarker\relax + \nofirstmarkerfalse + \normalfi + \normalfi + \long\setgvalue{\@@markbot@@\markname}{#1}% + \!!toksa\@EA{\@EA\domark\the\scratchcounter{#1}}% + \normalfi} + +\def\doscanmarks + {\afterassignment\dodoscanmarks\scratchcounter=} + +\long\def\dorecovermarks#1\lastmark% nice trick + {\!!toksc{\domark#1}} + +\def\lastmark% rest of trick + {\!!toksc\emptytoks} + +\endTEX + +%D The \ETEX\ way of doing things \unknown + +\beginETEX \marks cum suis + +\newtoks \listofmarks + +\def\@@prk{prk:} +\def\@@mrk{mrk:} +\def\@@trk{trk:} +\def\@@frk{frk:} +\def\@@brk{brk:} +\def\@@crk{crk:} + +%D We will use two state variables per mark, one to signal +%D that a new mark value is set, and one to trigger (on the +%D next page) the setting of the top mark. + +\def\checkedtopmarks #1{\csname\@@trk\string#1\endcsname} +\def\checkedfirstmarks#1{\csname\@@frk\string#1\endcsname} +\def\checkedbotmarks #1{\csname\@@brk\string#1\endcsname} +\def\thecurrentmarks #1{\csname\@@crk\string#1\endcsname} + +\long\def\setmark#1% + {%\writestatus{marks}{setting \string#1}\wait + \global\@EA\chardef\csname\@@mrk\string#1\endcsname\plusone + %\@EA\normalmarks\csname\@@prk\string#1\endcsname{1}% + \@EA\normalmarks\csname\@@prk\string#1\endcsname{\realfolio}% + \ifexpandmarks\@EA\setexpandedmark\else\@EA\setnormalmark\fi#1} + +\def\setexpandedmark#1#2% % marks expand anyway + {\@EA\xdef\csname\@@crk\string#1\endcsname{#2}% + \normalmarks#1{#2}} + +\def\setnormalmark#1#2% using a tok prevents unwanted expansion in mark + {\begingroup % don't ask why, but grouping is needed + \scratchtoks{#2}% in order to to mess up scratchtoks + \@EA\xdef\csname\@@crk\string#1\endcsname{\the\scratchtoks}% + \normalmarks#1{\the\scratchtoks}% one level expansion + \endgroup} + +\def\checktopmark#1% + {%\writestatus{marks}{checking \string#1}\wait + \ifcase\csname\@@mrk\string#1\endcsname\else\dochecktopmark#1\fi} + +%\def\dochecktopmark#1% +% {\ifcase0\@EA\normalfirstmarks\csname\@@prk\string#1\endcsname\else +% \@EA\ifx\csname\@@frk\string#1\endcsname\empty +% \@EA\gdef\csname\@@frk\string#1\endcsname{\normalfirstmarks#1}% +% \@EA\gdef\csname\@@brk\string#1\endcsname{\normalbotmarks #1}% +% \else +% \@EA\gdef\csname\@@trk\string#1\endcsname{\normaltopmarks #1}% +% \global\@EA\chardef\csname\@@mrk\string#1\endcsname\zerocount +% \fi +% \fi} + +\def\dochecktopmark#1% + {\ifx*\@EA\normalfirstmarks\csname\@@prk\string#1\endcsname*\else + \@EA\ifx\csname\@@frk\string#1\endcsname\empty + \@EA\gdef\csname\@@frk\string#1\endcsname{\normalfirstmarks#1}% + \@EA\gdef\csname\@@brk\string#1\endcsname{\normalbotmarks #1}% + \else + \@EA\gdef\csname\@@trk\string#1\endcsname{\normaltopmarks #1}% + \global\@EA\chardef\csname\@@mrk\string#1\endcsname\zerocount + \fi + \fi} + +%\def\resetmark#1% we cannot use \normalmarks#1{} +% {\global\@EA\chardef\csname\@@mrk\string#1\endcsname\zerocount +% \@EA\normalmarks\csname\@@prk\string#1\endcsname{0}% +% \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} + +\def\resetmark#1% we cannot use \normalmarks#1{} + {\global\@EA\chardef\csname\@@mrk\string#1\endcsname\zerocount + \@EA\normalmarks\csname\@@prk\string#1\endcsname{}% {0}% + \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} + +\def\definenewmark#1% + {\ifcsname\@@prk\string#1\endcsname\else % this is etex -) + \newmarks#1\doglobal\appendtoks\checktopmark#1\to\listofmarks + \@EA\newmarks\csname\@@prk\string#1\endcsname % status mark + \fi + \global\@EA\mathchardef\csname\@@mrk\string#1\endcsname\zerocount + \global\@EA\let\csname\@@crk\string#1\endcsname\empty + \@EA\gdef\csname\@@trk\string#1\endcsname{\normaltopmarks #1}% + \@EA\gdef\csname\@@frk\string#1\endcsname{\normalfirstmarks#1}% + \@EA\gdef\csname\@@brk\string#1\endcsname{\normalbotmarks #1}} + +\let \newmark \definenewmark +\let \newpersistentmark \newmarks % \definenewmark +\let \normalsetmark \setmark + +\def\getallmarks{\the\listofmarks} % \def\setallmarks{\the\listofmarks} + +%D In \type {page-ini} or \type {core-mar} we should say: +%D +%D \starttyping +%D \appendtoks \getallmarks \to \everybeforepagebody +%D \appendtoks \setallmarks \to \everyafterpagebody +%D \stoptyping + +\let\getcurrentmark \thecurrentmarks +\let\gettopmark \checkedtopmarks +\let\getbottommark \checkedbotmarks % \normalbotmarks +\let\getfirstmark \checkedfirstmarks % \normalfirstmarks +\let\getsplitbottommark \normalsplitbotmarks +\let\getsplitfirstmark \normalsplitfirstmarks + +\let\getbotmark \getbottommark +\let\getsplitbotmark \normalsplitbotmarks +\let\getsplittopmark \normalsplitfirstmarks + +\endETEX + +%D A couple of goodies: + +\let\getbotmark \getbottommark +\let\getsplitbotmark\getsplitbottommark +\let\getsplittopmark\getsplitfirstmark + +%D \macros +%D {noninterferingmarks} +%D +%D Marks can interfere badly with for instance postprocessing +%D paragraphs, for instance when we want to grab the last box +%D using \type {\lastbox}, when at the same time using colors. + +\let\normalsetmark\setmark + +\def\noninterferingsetmark#1#2% + {\ifhmode\prewordbreak\hbox\fi{\normalsetmark{#1}{#2}}} + +\def\noninterferingmarks + {\let\noninterferingmarks\relax + \let\setmark\noninterferingsetmark} + +%D This macro is for instance used in the inline headings +%D postprocessing, as needed when we want to make those +%D clickable. + +%D Right from the beginning, \CONTEXT\ supported more than one +%D mark, using an extended version of Jim Fox multiple mark +%D mechanism. In \ETEX\ we can however directly access more +%D marks than we will ever need. + +%D Resetting marks in not compatible with the old method. +%D Here a node is inserted, which can interfere badly. In +%D fact, a real \type {\clearmarks\name} is needed. +%D +%D \starttyping +%D \def\resetmark#1{\marks#1{}} +%D \stoptyping +%D +%D A possible macro solution is presented here. When discussing +%D \type {\clearmarks} on the \ETEX\ discussion list, Chris +%D Rowley suggested to use a reset flag. Unfortunately this +%D is not enough since we need to keep track of both set and +%D reset state then. This means that we must postpone resetting +%D to the page following the set, and as a result we need +%D another auxiliary macro. The current solution is the best +%D I could come up with so far, especially given that we +%D need a fast mechanism. + +%D For those who want to know the story behind resetting +%D marks, here are some examples of interference +%D +%D \startbuffer +%D \setbox0=\vbox{test} +%D \unvbox0\setbox0=\lastbox +%D \ruledhbox{\unhbox0} +%D \stopbuffer +%D +%D \typebuffer\blank\getbuffer\blank +%D +%D \startbuffer +%D \setbox0=\vbox{test\normalmark{}} +%D \unvbox0\setbox0=\lastbox +%D \ruledhbox{\unhbox0} +%D \stopbuffer +%D +%D \typebuffer\blank\getbuffer\blank +%D +%D \startbuffer +%D \setbox0=\vbox{test\hbox{\normalmark{}}} +%D \unvbox0\setbox0=\lastbox +%D \ruledhbox{\unhbox0} +%D \stopbuffer +%D +%D \typebuffer\blank\getbuffer\blank +%D +%D \startbuffer +%D \setbox0=\vbox{test\vbox{\normalmark{}}} +%D \unvbox0\setbox0=\lastbox +%D \ruledhbox{\unhbox0} +%D \stopbuffer +%D +%D \typebuffer\blank\getbuffer\blank + +%D One final advice. Use marks with care. When used in globally +%D assigned boxes, the list can grow quite big, and processing +%D can slow down considerably. This drawback is removed in +%D \ETEX\ mode. + +\beginTEX + +\let\rawnewmark \newmark +\let\rawdefinemark \newmark +\let\rawsetmark \setmark +\let\rawgettopmark \gettopmark +\let\rawgetfirstmark \getfirstmark +\let\rawgetbotmark \getbotmark +\let\rawgetsplitbotmark \normalsplitbotmark +\let\rawgetsplitfirstmark\normalsplitfirstmark +\let\rawgetsplittopmark \normalsplitfirstmark + +\endTEX + +\beginETEX + +\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 + +\endETEX + +\protect \endinput diff --git a/tex/context/base/supp-num.tex b/tex/context/base/supp-num.tex new file mode 100644 index 000000000..d192ab548 --- /dev/null +++ b/tex/context/base/supp-num.tex @@ -0,0 +1,443 @@ +%D \module +%D [ file=supp-num, +%D version=1998.05.15, +%D title=\CONTEXT\ Support Macros, +%D subtitle=Numbers, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Numbers} + +\unprotect + +%D \macros +%D {digits, setdigitmode, setdigitsign} +%D +%D Depending on the digit mode the command \type {\digits} +%D normalizes number patterns depending on the language set. +%D +%D \starttyping +%D This will never be a \digits{1.000.000} seller. +%D \stoptyping +%D +%D or +%D +%D \starttyping +%D I will never grow longer than \digits 1.86 \Meter. +%D \stoptyping +%D +%D The different modes are shown in: +%D +%D \startbuffer +%D \setdigitmode 1 \digits 12.345,90 \digits 12.345.000 \digits 1,23 +%D \setdigitmode 2 \digits 12.345,90 \digits 12.345.000 \digits 1,23 +%D \setdigitmode 3 \digits 12.345,90 \digits 12.345.000 \digits 1,23 +%D \setdigitmode 4 \digits 12.345,90 \digits 12.345.000 \digits 1,23 +%D \setdigitmode 5 \digits 12.345,90 \digits 12.345.000 \digits 1,23 +%D \setdigitmode 6 \digits 12.345,90 \digits 12.345.000 \digits 1,23 +%D \stopbuffer +%D +%D \typebuffer +%D +%D This is typset as: +%D +%D \startlines +%D \getbuffer +%D \stoplines +%D +%D The sign can be typeset as is or within the space of a +%D digit. +%D +%D \startbuffer +%D \setdigitsign 0 \digits +12.345,90 +%D \setdigitmode 1 \digits +12.345,90 +%D \setdigitmode 2 \digits +12.345,90 +%D \setdigitmode 3 \digits +12.345,90 +%D \stopbuffer +%D +%D \typebuffer +%D +%D This is typset as: +%D +%D \startlines +%D \getbuffer +%D \stoplines + +\chardef\digitoutputmode=1 % 0..6 +\chardef\digitsignmode =0 % 0..3 + +\def\setdigitmode{\chardef\digitoutputmode} +\def\setdigitsign{\chardef\digitsignmode} + +%D The digit modes are: +%D +%D \startitemize[packed] +%D \item periods \& comma +%D \item commas \& period +%D \item thinmuskips \& comma +%D \item thinmuskips \& period +%D \item thickmuskips \& comma +%D \item thickmuskips \& period +%D \stopitemize + +\let\collecteddigits \empty \chardef\digitinputmode =1 +\let\saveddigits \empty \chardef\skipdigit =0 +\let\savedpowerdigits\empty \chardef\powerdigits =0 + +%D The first stage of the \type {\digit} macro takes care of +%D the grouped call, the other branch handles the fuzzy +%D delimited calls. + +\ifx\mbox\undefined \let\mbox\normalhbox \fi + +% \unexpanded\def\digits +% {\bgroup\let~@\doifnextbgroupelse\dodigits\grabdigit} + +\unexpanded\def\digits + {\bgroup + \let~@% + \doifnextbgroupelse\dodigits{\doifnextcharelse\normalmathshift\domathdigits\grabdigit}} + +\def\dodigits#1% + {\grabdigit#1\relax} + +\def\domathdigits$#1$% + {\mbox{\grabdigit#1\relax}} % adding $ $ goes wrong in tabulate + +\def\grabdigit + {\futurelet\next\scandigit} + +%D Watch the test for \type {\nextobeyedline}, because the +%D endofline token can be \type {\def'd}, not \type {\let}'d, +%D we need to do an indirect test (see \type {verb-ini.tex}) +%D for details. +%D +%D \starttyping +%D \def ^^M{\obeyedline} +%D \def\nextbeyedline{\obeyedline} +%D \stoptyping + +\ifx\normalmathshift\undefined \let\normalmathshift=$ \fi + +\def\scandigit + {\ifx\next\blankspace + \let\next\handledigits + \else\ifx\next\nextobeyedline % the indirect one + \let\next\handledigits + \else\ifx\next\bgroup + \let\next\handledigits + \else\ifx\next\egroup + \let\next\handledigits + \else\ifx\next\normalmathshift + \let\next\handledigits + \else + \let\next\collectdigit + \fi\fi\fi\fi\fi + \next} + +%D We store the power||of||ten (to be signaled by \type {^}, +%D \type {e} or~\type {E}) in a seperate macro so that we can +%D typeset it in superscript. The space placeholders are +%D replaced by a \type {@}. + +\def\savedigit#1#2% + {\edef#1{#1\saveddigits#2}\let\saveddigits\empty} + +\long\def\collectdigit#1% + {\ifx#1~% + \savedigit\collecteddigits @% + \else\if#1_% + \savedigit\collecteddigits @% + \else\if\noexpand#1\relax + \let\grabdigit\handledigits + \else\ifcase\powerdigits + \if#1E% + \chardef\powerdigits\plusone + \else\if#1e% + \chardef\powerdigits\plusone + \else\if#1^% + \chardef\powerdigits\plusone + \else + \savedigit\collecteddigits#1% + %\doifnumberelse{#1} + % {\savedigit\collecteddigits#1} + % {\def\saveddigits{#1}}% + \fi\fi\fi + \else + \savedigit\savedpowerdigits#1% + %\doifnumberelse{#1} + % {\savedigit\savedpowerdigits#1} + % {\def\saveddigits{#1}}% + \fi\fi\fi\fi + \grabdigit} + +\let\handlemathdigits\firstofoneargument +\let\handletextdigits\mathematics + +\def\handledigits + {%\ifcase\powerdigits + % \edef\collecteddigits{\collecteddigits\saveddigits}% + %\else + % \edef\savedpowerdigits{\savedpowerdigits\saveddigits}% + %\fi + \ifmmode + \handlemathdigits{\dohandledigits}% + \else + \dontleavehmode\hbox{\handletextdigits{\dohandledigits}}% + \fi + \egroup} + +%D Although we could do with one pass, a second pass for +%D handling the stored sequence is more readable. + +\ifnum\texengine=\luatexengine + + \def\dohandledigits + {\mathcode`\,="002C \mathcode`\.="002E % pretty hard coded + \expandafter\handletokens\collecteddigits\with\scandigits + \ifcase\powerdigits\else\digitpowerseparator^{\savedpowerdigits}\fi} + + \chardef\mathaxisfontid\zerocount + +\else + + \def\dohandledigits + {\mathcode`\,="013B \mathcode`\.="013A % pretty hard coded + \expandafter\handletokens\collecteddigits\with\scandigits + \ifcase\powerdigits\else\digitpowerseparator^{\savedpowerdigits}\fi} + + \chardef\mathaxisfontid\plustwo + +\fi + +\def\doscandigit#1% + {\ifcase\skipdigit\@EA\hbox\else\@EA\hphantom\fi\bgroup + \mathematics % brr, needed because of stored punctuation + {\ifnum\digitinputmode=#1\relax + \ifcase\digitoutputmode + \or .% + \or ,% + \or \mskip\thinmuskip + \or \mskip\thinmuskip + \or \mskip\thickmuskip + \or \mskip\thickmuskip + \fi + \else + \ifodd\digitoutputmode,\else.\fi + \fi}% + \egroup} + +%D The signs can be made smaller and sqeezed into the width +%D of a digit. Watch the \type {\mathaxisheight} trickery (this +%D font related register stored the math axis). + +% \def\scandigits#1% +% {\if#1.\doscandigit1\chardef\skipdigit0\else +% \if#1,\doscandigit2\chardef\skipdigit0\else +% \if#1@\hphantom{0}\chardef\skipdigit1\else +% \if#1_\hphantom{0}\chardef\skipdigit1\else +% \if#1/\digitsgn{\hphantom{+}}\chardef\skipdigit0\else +% \if#1-\digitsgn-\chardef\skipdigit0\else +% \if#1+\digitsgn+\chardef\skipdigit0\else +% \if#1=\digitsgn\zeroamount\chardef\skipdigit0\else +% \if#1s\digitsgn{\hphantom{\positive}}\chardef\skipdigit0\else +% \if#1p\digitsgn\positive\chardef\skipdigit0\else +% \if#1m\digitsgn\negative\chardef\skipdigit0\else +% \if#1n\digitsgn\negative\chardef\skipdigit0\else +% #1\chardef\skipdigit0\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} + +% \def\digitsep#1% +% {\doscandigit#1\chardef\skipdigit0} +% +% \def\digitnop +% {\hphantom{0}\chardef\skipdigit1} + +% 0,= +% 0,== second = results in delta(00,=) +% 0,- is invalid, should be = +% 0,-- is invalid, should be == + +\def\digitzeroamount + {\digitsgn\zeroamount + \def\digitzeroamount + {\hphantom + {00\setbox\scratchbox\hbox{$\zeroamount$}% + \hskip-\wd\scratchbox}% + \let\digitzeroamount\empty}} + +\def\scandigits#1% + {\if#1.\digitsep1\else + \if#1,\digitsep2\else + \if#1@\digitnop \else + \if#1_\digitnop \else + \if#1/\digitsgn{\hphantom{+}}\chardef\skipdigit0\else + \if#1-\ifcase\skipdigit\digitsgn-\else + \box\digitsepbox\digitzeroamount \fi\chardef\skipdigit0\else + \if#1+\digitsgn+\chardef\skipdigit0\else + \if#1=\box\digitsepbox\digitzeroamount \chardef\skipdigit0\else + \if#1s\digitsgn{\hphantom{\positive}}\chardef\skipdigit0\else + \if#1p\digitsgn\positive\chardef\skipdigit0\else + \if#1m\digitsgn\negative\chardef\skipdigit0\else + \if#1n\digitsgn\negative\chardef\skipdigit0\else + \box\digitsepbox #1\chardef\skipdigit0\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} + +\newbox\digitsepbox \chardef\autodigitmode=1 + +\def\digitsep#1% + {\ifcase\autodigitmode + \doscandigit#1% + \else + \setbox\digitsepbox\hbox{\doscandigit#1}% + \fi + \chardef\skipdigit0\relax} + +% strange, does not work +% +% \def\digitnop +% {\hphantom{\box\digitsepbox}% +% \hphantom{0}\chardef\skipdigit1\relax} +% +% while this works + +\def\digitnop + {\hbox{\hphantom{\box\digitsepbox}}% + \hphantom{0}\chardef\skipdigit1\relax} + +% but this doesn't +% +% \def\digitnop +% {\hphantom{\box\digitsepbox0}% +% \chardef\skipdigit1\relax} + +\def\digitsgn#1% + {\ifcase\digitsignmode#1\else + \hbox + {\setbox\scratchbox\hbox{0}% + \scratchdimen\mathaxisheight\textfont\mathaxisfontid + \def\digitsgn##1##2% + {\advance\scratchdimen-\mathaxisheight##1\mathaxisfontid + \raise\scratchdimen + \hbox to \wd\scratchbox{\hss$##2#1$\hss}}% + \ifcase\digitsignmode\or + \digitsgn\textfont \textstyle \or + \digitsgn\scriptfont \scriptstyle \or + \digitsgn\scriptscriptfont\scriptscriptstyle\fi}% + \fi} + +\ifx\undefined\zeroamount \def\zeroamount{-} \fi +\ifx\undefined\positive \def\positive {+} \fi +\ifx\undefined\negative \def\negative {-} \fi + +%D The digit parser handles a bunch of special characters as +%D well as different formats. We strongly suggest you to use +%D the grouped call. +%D +%D \starttabulate[|l|l|l|] +%D \NC \type{.} \NC , . \NC comma or period \NC \NR +%D \NC \type{,} \NC , . \NC comma or period \NC \NR +%D \NC \type{@} \NC \NC invisible space \NC \NR +%D \NC \type{_} \NC \NC invisible space \NC \NR +%D \NC \type{/} \NC \NC invisible sign \NC \NR +%D \NC \type{-} \NC $-$ \NC minus sign \NC \NR +%D \NC \type{+} \NC $+$ \NC plus sign \NC \NR +%D \NC \type{s} \NC \NC invisible high sign \NC \NR +%D \NC \type{p} \NC $\positive$ \NC high plus sign \NC \NR +%D \NC \type{m} \NC $\negative$ \NC high minus sign \NC \NR +%D \NC \type{n} \NC $\negative$ \NC high minus (negative) sign \NC \NR +%D \NC \type{=} \NC $\zeroamount$ \NC zero padding \NC \NR +%D \stoptabulate +%D +%D These triggers are used in the following examples. +%D +%D \startbuffer +%D \digits 12 +%D \digits{~~~.~~~.~~~.68.712,34} +%D \digits ~~~.~~~.~~~.68.712,34 +%D \digits ___.___.111.68.712,34 +%D \digits 111.111.111.68.712,34 +%D \digits 12.345,90 +%D \digits 12.345.000 +%D \digits 12,34 +%D \digits{392.857.230.68.712,34} +%D {\digits1234} +%D \digits{1234} +%D \digits 1234\relax +%D $\digits 123.222,00$ +%D \digits 123.222,00 +%D \digits 123.222,== +%D \digits 123.222,00^10 +%D \digits 123.222,00e10 +%D \digits /123.222,00e-12 +%D \digits -123.222,00e-12 +%D \digits +123.222,00e-12 +%D \digits n123.222,00e-12 +%D \digits s123.222,00e-12 +%D \digits p123.222,00e-12 +%D \stopbuffer +%D +%D \typebuffer +%D +%D \startlines +%D \getbuffer +%D \stoplines + +%D \macros +%D {Digits} +%D +%D We also permit: + +\let\Digits\digits + +%D These macros are complicated by the fact that we also +%D have to support cases like: +%D +%D \starttyping +%D {\digits1234} +%D \digits{1234} +%D \digits 1234\whatever +%D $\digits 123.222,00$ +%D \digits 123.222,00. +%D \stoptyping +%D +%D The latter case shows us that trailing non digits are to +%D be passed untreated. +%D +%D Another interesting case is: +%D +%D \starttyping +%D \digits 123.222,00^10 +%D \stoptyping +%D +%D The separator is defined as: + +% \def\digitpowerseparator% +% {\cdot10} % {\times10} + +\def\digitpowerseparator + {\ifx\collecteddigits\empty\else\cdot\fi10} + +%D \macros +%D {digittemplate} +%D +%D Users can specify the way they enter those digits by saying +%D something like: +%D +%D \starttyping +%D \digittemplate 12.000.000,00 % \digittemplate ., +%D \stoptyping + +\def\digittemplate #1 % + {\chardef\digitinputmode\zerocount + \handletokens#1\with\scandigittemplate} + +\def\scandigittemplate#1% + {\if #1.\ifcase\digitinputmode\chardef\digitinputmode\plusone \fi% period + \else\if#1,\ifcase\digitinputmode\chardef\digitinputmode\plustwo \fi% comma + \fi\fi} + +\protect \endinput diff --git a/tex/context/base/supp-pat.mkii b/tex/context/base/supp-pat.mkii new file mode 100644 index 000000000..d91083076 --- /dev/null +++ b/tex/context/base/supp-pat.mkii @@ -0,0 +1,179 @@ +%D \module +%D [ file=supp-pat, +%D version=2005.02.12, +%D title=\CONTEXT\ Support Macros, +%D subtitle=Patterns, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 support: +%D +%D \starttyping +%D \patterns { +%D ...[namedglyphs]... +%D } +%D \stoptyping +%D +%D as well as: +%D +%D \starttyping +%D +%D ...&namedglyphs;... +%D +%D \stoptyping +%D +%D The \XML\ variant has very limited \XML\ parsing capabilities and +%D is meant as an experiment. + +\ifx\writestatus\undefined \else + + \writestatus{loading}{ConTeXt Support Macros / Patterns} + +\fi + +%D \CONTEXT: + +\ifx\startmapping\undefined \else \ifx\startencoding\undefined \else + + \def\fetchpatterntoken#1{\csname#1\endcsname} + +\fi \fi + +%D First we define the \ETEX\ variant. We cannot do that inside +%D the if statement because normal \TEX\ gets confused over the +%D csname test (which it does not see as if but it does see the +%D else's and fi's). + +\def\etexfetchpatterntoken#1% + {\csname + \ifcsname @pattok@#1\endcsname + @pattok@#1% + \else\ifcsname#1\endcsname + #1% + \else + @pattok@default% + \fi\fi + \endcsname} + +\ifx \fetchpatterntoken \undefined + + \ifx \eTeXversion \undefined + + \def\fetchpatterntoken#1% + {\csname + \expandafter\ifx\csname @pattok@#1\endcsname\relax + \expandafter\ifx\csname#1\endcsname\relax + @pattok@default% + \else + #1% + \fi + \else + @pattok@#1% + \fi + \endcsname} + + \else + + \let\fetchpatterntoken\etexfetchpatterntoken + + \fi + +\fi + +\def\definepatterntoken #1 #2 % + {\expandafter\def\csname @pattok@#1\endcsname{#2}} + +%D \TEX\ based: + +\bgroup \catcode`\[=\active + + \gdef\enablepatterntokens + {\catcode`\[=\active \let[\handlepatterntoken} + +\egroup + +\def\handlepatterntoken#1]% + {\fetchpatterntoken{#1}} + +%D \XML\ based: + +\bgroup \catcode`\<=\active \catcode`\&=\active + + \gdef\enablepatternxml + {\catcode`\<=\active + \catcode`\&=\active + \let&\handlepatternentity + \let<\handlepatternxml} + +\egroup + +\def\handlepatternentity#1;% + {\fetchpatterntoken{#1}} + +%D We use a very simple \XML\ parser, and we only trigger on the first +%D two characters of the tag name. Consider this feature a playground +%D (and a bit of a joke). + +\def\handlepatternxml#1#2% we only distinguish the first two chars + {\csname @patxml@\ifcsname @patxml@#1#2\endcsname#1#2\else de\fi\endcsname} + +\def\definepatternxml #1#2#3 #4% + {\expandafter\def\csname @patxml@#1#2\endcsname{#4}} + +\def\fetchpatternxml#1#2>% + {\bgroup + \long\def\next##1>{\egroup}% + \catcode`\<=2 % \@@endgroup + \afterassignment\next + #1\bgroup} + +\def\gobblepatternxml + {\bgroup + \catcode`\%=11 + \dogobblepatternxml} + +\long\def\dogobblepatternxml#1>% + {\egroup} + +%D Here are the default definitions. We don't catch empty elements. + +\definepatternxml patterns {\fetchpatternxml\patterns} +\definepatternxml hyphenations {\fetchpatternxml\hyphenation} +\definepatternxml pattern {\fetchpatternxml\patterns} +\definepatternxml hyphenation {\fetchpatternxml\hyphenation} +\definepatternxml default {\gobblepatternxml} + +\definepatterntoken default x + +\ifx\pattern \undefined \let\pattern \patterns \fi +\ifx\hyphenations\undefined \let\hyphenations\hyphenation \fi + +%D An example of usage in another format than \CONTEXT: +%D +%D \starttyping +%D \bgroup +%D +%D \lccode"E4="E4 \definepatterntoken adiaeresis ^^e4 +%D \lccode"F6="F6 \definepatterntoken odiaeresis ^^f6 +%D \lccode"FC="FC \definepatterntoken ediaeresis ^^fc +%D \lccode"FF="FF \definepatterntoken ssharp ^^ff +%D +%D \enablepatterntokens +%D \enablepatternxml +%D +%D \input lang-de.pat +%D \input lang-de.hyp +%D +%D \egroup +%D \stoptyping +%D +%D This is a minimal example for EC encoding, and of course +%D a couple of more language related settings need to take +%D place (like uc mappings). + +\endinput diff --git a/tex/context/base/supp-pdf.mkii b/tex/context/base/supp-pdf.mkii new file mode 100644 index 000000000..c54b0c6bc --- /dev/null +++ b/tex/context/base/supp-pdf.mkii @@ -0,0 +1,2187 @@ +%D \module +%D [ file=supp-pdf, +%D version=2006.09.02, % 2004.12.16, +%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. + +\ifx\writestatus\undefined + \immediate\write16{[Loading MPS to PDF converter (version 2006.09.02).]} +\else + \writestatus{loading}{ConTeXt Support Macros / PDF} +\fi + +%D This module is not optimized because it is used outside +%D \CONTEXT\ and we cannot forsee what interference will take +%D place. We no longer load supp-mis. I got too tired of +%D keeping track of interferences with non \CONTEXT\ usage so +%D I moved the necessary code in here and use a derived version +%D in \CONTEXT. When I have the time I will clean up some of the +%D code that is of no use for non||\CONTEXT\ users. + +\ifx\contextversion\undefined + + \chardef\mptopdfstoredatcode\catcode`\@ + + \catcode\string`@=11 + + \def\unprotect + {\let\@@mpstopdf@@unprotect \unprotect + \let\@@mpstopdf@@protect \protect + \edef\protect + {\noexpand \let \noexpand \protect \noexpand \@@mpstopdf@@protect + \noexpand \let \noexpand \unprotect \noexpand \@@mpstopdf@@unprotect + % context specific + \catcode\string`\noexpand @=\the\catcode\string`@ + \catcode\string`\noexpand !=\the\catcode\string`! + \catcode\string`\noexpand ?=\the\catcode\string`? + % latex specific + \catcode\string`\noexpand /=\the\catcode\string`/ + \catcode\string`\noexpand -=\the\catcode\string`- + \catcode\string`\noexpand :=\the\catcode\string`: + \catcode\string`\noexpand ;=\the\catcode\string`; + \catcode\string`\noexpand "=\the\catcode\string`" + \catcode\string`\noexpand <=\the\catcode\string`< + \catcode\string`\noexpand >=\the\catcode\string`> + \catcode\string`\noexpand `=\the\catcode\string``} + \catcode\string`@=11 \catcode\string`!=11 \catcode\string`?=11 + \catcode\string`/=12 \catcode\string`-=12 + \catcode\string`:=12 \catcode\string`;=12 + \catcode\string`>=12 \catcode\string`<=12 + \catcode\string`"=12 \catcode\string``=12 } + + \def\defineMPtoPDFfallbacks + {% shortcuts + \chardef\@@escape 0 + \chardef\@@begingroup 1 + \chardef\@@endgroup 2 + \chardef\@@endofline 5 + \chardef\@@ignore 9 + \chardef\@@space 10 + \chardef\@@letter 11 + \chardef\@@other 12 + \chardef\@@active 13 + \chardef\@@comment 14 + % placeholders + \ifx\withoutpt \undefined \let\withoutpt \@@mptopdf@@withoutpt \fi + \ifx\twodigitrounding \undefined \let\twodigitrounding \@@mptopdf@@twodigitrounding \fi + \ifx\forgetall \undefined \let\forgetall \@@mptopdf@@forgetall \fi + \ifx\uncatcodespecials \undefined \let\uncatcodespecials \@@mptopdf@@uncatcodespecials \fi + \ifx\setnaturalcatcodes\undefined \let\setnaturalcatcodes\@@mptopdf@@setnaturalcatcodes \fi + \ifx\dospecials \undefined \let\dospecials \@@mptopdf@@dospecials \fi} + + \def\@@mptopdf@@forgetall + {\parskip0pt\leftskip0pt\parindent0pt\everypar{}} + + \def\@@mptopdf@@twodigitrounding#1% + {#1}% + + \def\@@mptopdf@@uncatcodespecials + {\def\do##1{\catcode`##1=\@@other}\dospecials + \catcode`\ =\@@space + \catcode`\^^L=\@@ignore + \catcode`\^^M=\@@endofline + \catcode`\^^?=\@@ignore} + + \def\@@mptopdf@@setnaturalcatcodes + {\catcode`\!=\@@other \catcode`\?=\@@other \catcode`\@=\@@other + \catcode`\#=\@@other \catcode`\&=\@@other \catcode`\|=\@@other + \catcode`\$=\@@other \catcode`\^=\@@other \catcode`\_=\@@other + \catcode`\*=\@@other \catcode`\/=\@@other + \catcode`\-=\@@other \catcode`+=\@@other + \catcode`\==\@@other \catcode`\<=\@@other \catcode`\>=\@@other + \catcode`\"=\@@other \catcode`\'=\@@other \catcode`\`=\@@other + \catcode`\:=\@@other \catcode`\;=\@@other + \catcode`\,=\@@other \catcode`\.=\@@other \catcode`\~=\@@other + \catcode`\(=\@@other \catcode`\)=\@@other + \catcode`\{=\@@other \catcode`\}=\@@other + \catcode`\\=\@@other \catcode`\%=\@@other} + + \def\@@mptopdf@@dospecials + {\do\ \do\\\do\{\do\}\do\$% + \do\#\do\^\do\_\do\&\do\%% + \do\~\do\^^A\do\^^K} + + { + \catcode`\.=12 + \catcode`\p=12 + \catcode`\t=12 + \gdef\@@MPTOPDF@@WITHOUTPT#1pt{#1} + } + + \def\@@mptopdf@@withoutpt#1% + {\expandafter\@@MPTOPDF@@WITHOUTPT#1} + +% \def\@@mptopdf@@newabove#1#2% \dimen \name +% {#1#2% +% \ifnum\expandafter\gobblesixarguments\meaning#2>20\else +% \expandafter\@@mptopdf@@newabove\expandafter#1\expandafter#2% +% \fi} + + \def\@@mptopdf@@stripnewabove#1% + {\ifnum10<9#1 #1\else\expandafter\@@mptopdf@@stripnewabove\fi}% + + \def\@@mptopdf@@newabove\csname#1\endcsname#2% \dimen \name + {\csname#1\endcsname#2% + \ifnum\expandafter\@@mptopdf@@stripnewabove\meaning#2>20\else + \@@mptopdf@@newabove\csname#1\endcsname#2% + \fi} + + \@@mptopdf@@newabove \csname newcount\endcsname \scratchcounter + \@@mptopdf@@newabove \csname newdimen\endcsname \scratchdimen + \csname newbox\endcsname \scratchbox + + \expandafter \newif \csname ifdone\endcsname + + \catcode`\@=\mptopdfstoredatcode + +\else + + \let\defineMPtoPDFfallbacks\relax + +\fi + +%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.) + +%D Beware, we cannot use \type{\zeropoint} here since it may be +%D defined in the range \type{\dimen0} - 20 which we happen to use +%D as scratch registers; inside context we may consider +%D using dedicated registers. + +%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. + +\unprotect + +\ifx\PDFcode\undefined + \ifx\pdfliteral\undefined + \def\PDFcode#1{\special{PDF: #1}} + \else\ifx\pdfoutput\undefined + \def\PDFcode#1{\special{PDF: #1}} + \else\ifcase\pdfoutput + \def\PDFcode#1{\special{PDF: #1}} + \else % pdftex as well as in pdf mode + \let\PDFcode\pdfliteral + \fi\fi\fi +\else + % we probably use context +\fi + +%D First we define a handy constant: + +\bgroup \defineMPtoPDFfallbacks \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 + + \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\wd\scratchbox + \advance\hsize -#3 + \advance\hsize -#4 + \vsize\ht\scratchbox + \advance\vsize -#5 + \advance\vsize -#6 + \setbox\scratchbox\vbox to \vsize + {\vskip-#5\hbox to \hsize{\hskip-#3\box\scratchbox\hss}}% + \pdfxform\scratchbox + \pdfrefxform\pdflastxform + \egroup} + +\fi \fi + +%D If you want to save a few hash entries, you may prefer the +%D less readable alternatives, like: +%D +%D \starttyping +%D \def\pdfimage#1#% This one is less readable but needs no additional +%D {\bgroup % hash entry for the second stage macro. +%D \def\pdfimage##1% +%D {\immediate\pdfximage##1{#2}% +%D \pdfrefximage\pdflastximage\egroup}} +%D \stoptyping + +%D For old times sake we provide a few aliases. These will be +%D removed some day. + +\ifx\pdftexversion\undefined \else \ifnum\pdftexversion>13 + + \let\pdfform =\pdfxform + \let\pdflastform=\pdflastxform + \let\pdfrefform =\pdfrefxform + +\fi \fi + +%D The main conversion macro wraps the \PDF\ codes in a box +%D that is output as an object. The graphics are embedded +%D in~\type{q} and~\type{Q} and are scaled and positioned using +%D one transform call (\type{cm}). This saves some additional +%D scaling. + +%D \macros +%D {convertMPtoPDF} +%D +%D The next set of macros implements \METAPOST\ to \PDF\ +%D conversion. Because we want to test as fast as possible, we +%D first define the \POSTSCRIPT\ operators that \METAPOST\ +%D uses. We don't define irrelevant ones, because these are +%D skipped anyway. + +%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 +%D {xPSmoveto}}. For everyday documents with relatively +%D small graphics the gain in speed can be neglected. + +\def \PScurveto {curveto} +\def \PSlineto {lineto} +\def \PSmoveto {moveto} +\def \PSshowpage {showpage} +\def \PSnewpath {newpath} +\def \PSfshow {fshow} +\def \PSclosepath {closepath} +\def \PSfill {fill} +\def \PSstroke {stroke} +\def \PSclip {clip} +\def \PSrlineto {rlineto} +\def \PSsetlinejoin {setlinejoin} +\def \PSsetlinecap {setlinecap} +\def \PSsetmiterlimit {setmiterlimit} +\def \PSsetgray {setgray} +\def \PSsetrgbcolor {setrgbcolor} +\def \PSsetcmykcolor {setcmykcolor} +\def \PSsetdash {setdash} +\def \PSgsave {gsave} +\def \PSgrestore {grestore} +\def \PStranslate {translate} +\def \PSscale {scale} +\def \PSconcat {concat} +\def \PSdtransform {dtransform} +\def \PSsetlinewidth {setlinewidth} +\def \PSpop {pop} + +\def \PSnfont {nfont} % was needed for TUG98 proceedings +\def \PSspecial {special} % extensions to MetaPost + +%D A previous version set \type {%} to ignore, which +%D simplified the following definitions. At the start of +%D conversion the percent character was made active again. +%D Because the whole graphic is one paragraph (there are no +%D empty lines) this does not give the desired effect. This +%D went unnoticed untill Scott Pakin sent me a test file +%D percent characters in a string. So, from now on we have +%D to prefix the following strings with percentages. + +%D Some day I'll figure out a better solution (line by line reading +%D using \ETEX). + +\edef \PSBoundingBox {\letterpercent\letterpercent BoundingBox:} +\edef \PSHiResBoundingBox {\letterpercent\letterpercent HiResBoundingBox:} +\edef \PSExactBoundingBox {\letterpercent\letterpercent ExactBoundingBox:} +\edef \PSMetaPostSpecial {\letterpercent\letterpercent MetaPostSpecial:} +\edef \PSMetaPostSpecials {\letterpercent\letterpercent MetaPostSpecials:} +\edef \PSPage {\letterpercent\letterpercent Page:} +\edef \PSBeginProlog {\letterpercent\letterpercent BeginProlog} +\edef \PSEndProlog {\letterpercent\letterpercent EndProlog} +\edef \PSEof {\letterpercent\letterpercent EOF} + +%D By the way, the \type {setcmykcolor} operator is not +%D output by \METAPOST\ but can result from converting the +%D \cap{RGB} color specifications, as implemented in +%D \type{supp-mps}. + +%D In \POSTSCRIPT\ arguments precede the operators. Due to the +%D fact that in some translations we need access to those +%D arguments, and also because sometimes we have to skip them, +%D we stack them up. The stack is one||dimensional for non path +%D operators and two||dimensional for operators inside a path. +%D This is because we have to save the whole path for +%D (optional) postprocessing. Values are pushed onto the stack +%D by: +%D +%D \starttyping +%D \setMPargument {value} +%D \stoptyping +%D +%D They can be retrieved by the short named macros: +%D +%D \starttyping +%D \gMPa {number} +%D \gMPs {number} +%D \stoptyping +%D +%D When scanning a path specification, we also save the +%D operator, using +%D +%D \starttyping +%D \setMPkeyword {n} +%D \stoptyping +%D +%D The path drawing operators are coded for speed: \type{clip}, +%D \type{stroke}, \type{fill} and \type{fillstroke} become +%D 1, 2, 3 and~4. +%D +%D When processing the path this code can be retrieved +%D using +%D +%D \starttyping +%D \getMPkeyword % {n} +%D \stoptyping +%D +%D When setting an argument, the exact position on the stack +%D depends on the current value of the \COUNTERS\ +%D \type{\nofMPsegments} and \type{\nofMParguments}. + +\newcount\nofMPsegments +\newcount\nofMParguments + +%D These variables hold the coordinates. The argument part of +%D the stack is reset by: +%D +%D \starttyping +%D \resetMPstack +%D \stoptyping +%D +%D We use the prefix \type{@@MP} to keep the stack from +%D conflicting with existing macros. To speed up things a bit +%D more, we use the constant \type{\@@MP}. + +\def\@@MP{@@MP} + +\def\setMPargument% #1% + {\advance\nofMParguments 1 + \expandafter\def + \csname\@@MP\the\nofMPsegments\the\nofMParguments\endcsname} % {#1} + +\def\letMPargument + {\advance\nofMParguments 1 + \expandafter\let + \csname\@@MP\the\nofMPsegments\the\nofMParguments\endcsname} + +\def\setMPsequence#1 % + {\advance\nofMParguments 1 + \expandafter\def + \csname\@@MP\the\nofMPsegments\the\nofMParguments\endcsname{#1}% + \handleMPsequence} + +\def\gMPa#1% + {\csname\@@MP0\number#1\endcsname} + +\def\gMPs#1% + {\csname\@@MP\the\nofMPsegments\number#1\endcsname} + +\def\dogMPa#1% + {\expandafter\expandafter\expandafter\do\csname\@@MP0\number#1\endcsname} + +\def\setMPkeyword#1 % + {\expandafter\def\csname\@@MP\the\nofMPsegments0\endcsname{#1}% + \advance\nofMPsegments 1 + \nofMParguments0} + +\def\getMPkeyword% #1% + {\csname\@@MP\the\nofMPsegments0\endcsname} % {\csname\@@MP#10\endcsname} + +\def\docleanupMPargument#1% we need this because args can have [ or ] pre/appended + {\expandafter\edef\csname\@@MP\the\nofMPsegments\number#1\endcsname + {\csname\@@MP\the\nofMPsegments\number#1\endcsname}} + +%D When we reset the stack, we can assume that all further +%D comment is to be ignored and handled in strings. +%D By redefining the reset macro after the first call, we +%D save some run time. Only use this macro after all +%D comments are processed and use the simple alternative +%D when dealing with comments. + +\def\doresetMPstack + {\nofMParguments0\relax} + +\def\resetMPstack + {\let\handleMPgraphic\handleMPendgraphic + \let\resetMPstack\doresetMPstack + \resetMPstack} + +%D The arguments are saved with the preceding command +%D \type{\do}. By default this command expands to nothing, but +%D when we deal with strings it's used to strip off the +%D \type{(} and \type{)}. +%D +%D Strings are kind of tricky, because characters can be +%D passed verbatim \type{(hello)}, by octal number +%D \type{(\005)} or as command \type{(\()}. We therefore +%D cannot simply ignore \type{(} and \type{)}, the way we do +%D with \type{[} and \type{]}. Another complication is that +%D strings may contain characters that normally have a +%D special meaning in \TEX, like \type{$} and \type{{}}. +%D +%D A previous solution made \type{\} an active character and +%D let it look ahead for a number or characters. We had to +%D abandon this scheme because of the need for verbatim +%D support. The next solution involved some \CATCODE\ +%D trickery but works well. + +\def\octalMPcharacter#1#2#3% + {\char'#1#2#3\relax} + +%D curly braces and squarly brackets are stored in the argument stack +%D as part of strings, for instance in: +%D +%D \starttyping +%D /fshow {exch findfont exch scalefont setfont show}bind def +%D [3 3 ] 0 setdash +%D \stoptyping +%D +%D but we need to keep them in situation like +%D +%D \starttyping +%D ([bla bla] bla bla) ec-lmr10 9.96265 fshow +%D ({bla bla} bla bla) ec-lmr10 9.96265 fshow +%D \stoptyping +%D +%D So, when we store the snippets, we keep the special tokens, and +%D when needed we either ignore or obey them + +\bgroup +\defineMPtoPDFfallbacks +\catcode`\|=\@@comment +\catcode`\%=\@@active +\catcode`\[=\@@active +\catcode`\]=\@@active +\catcode`\{=\@@active +\catcode`\}=\@@active +\catcode`B=\@@begingroup +\catcode`E=\@@endgroup +\gdef\keepMPspecials| + B\let%\letterpercent| + \def[B\noexpand[E| + \def]B\noexpand]E| + \def{B\noexpand{E| + \def}B\noexpand}EE +\gdef\ignoreMPspecials| + B\let%\letterpercent| + \def[BE| + \def]BE| + \def{BE| + \def}BEE +\gdef\obeyMPspecials| + B\def%B\char 37\relax E| + \def[B\char 91\relax E| + \def]B\char 93\relax E| + \def{B\char123\relax E| + \def}B\char125\relax EE +\gdef\setMPspecials| + B\setnaturalcatcodes + \catcode`\\=\@@escape + \catcode`\%=\@@active + \catcode`\[=\@@active + \catcode`\]=\@@active + \catcode`\{=\@@active + \catcode`\}=\@@active + \lccode`\-=0 | latex sets this to `\- + \lccode`\%=`\% | otherwise it's seen as a number + \def\(B\char40\relax E| + \def\)B\char41\relax E| + \def\\B\char92\relax E| + \def\0B\octalMPcharacter0E| + \def\1B\octalMPcharacter1E| + \def\2B\octalMPcharacter2E| + \def\3B\octalMPcharacter3E| + \def\4B\octalMPcharacter4E| + \def\5B\octalMPcharacter5E| + \def\6B\octalMPcharacter6E| + \def\7B\octalMPcharacter7E| + \def\8B\octalMPcharacter8E| + \def\9B\octalMPcharacter9EE +\egroup + +%D We use the comment symbol as a sort of trigger. Beware! +%D The whole graphic is seen as on eparagraph, which means +%D that we cannot change the catcodes in between. + +\bgroup +\defineMPtoPDFfallbacks +\catcode`\%=\@@active +\gdef\startMPscanning{\let%=\startMPconversion} +\egroup + +%D In earlier versions we used the sequence +%D +%D \starttyping +%D \expandafter\handleMPsequence\input filename\relax +%D \stoptyping +%D +%D Persistent problems in \LATEX\ however forced us to use a +%D different scheme. Every \POSTSCRIPT\ file starts with a +%D \type{%}, so we temporary make this an active character +%D that starts the scanning and redefines itself. (The problem +%D originates in the redefinition by \LATEX\ of the +%D \type{\input} primitive.) + +\def\startMPconversion + {\keepMPspecials + \handleMPsequence} + +%D Here comes the main loop. Most arguments are numbers. This +%D means that they can be recognized by their \type{\lccode}. +%D This method saves a lot of processing time. We could +%D speed up the conversion by handling the \type{path} +%D seperately. + +\def\dohandleMPsequence#1% + {\ifdone + \ifcase\lccode`#1\relax + \expandafter\expandafter\expandafter\dohandleMPsequenceA + \else + \expandafter\expandafter\expandafter\dohandleMPsequenceB + \fi + \else + \expandafter\dohandleMPsequenceC + \fi#1} + +\let\dohandleMPsequenceA\setMPsequence + +\def\installMPSkeywordN#1#2% + {\expandafter\def\csname\@@MP:N:#1\endcsname{#2}} + +\def\installMPSshortcutN#1#2% todo: \let + {\expandafter\let\csname\@@MP:N:#1\expandafter\endcsname\csname\@@MP:N:#2\endcsname} + +\def\dohandleMPsequenceB#1 % + {\edef\somestring{#1}% + \ifcsname\@@MP:N:\somestring\endcsname + \csname\@@MP:N:\somestring\expandafter\endcsname + \else + \expandafter\handleMPgraphic + \fi + \handleMPsequence} + +\ifx\eTeXversion\undefined + \def\dohandleMPsequenceB#1 % + {\edef\somestring{#1}% + \expandafter\ifx\csname\@@MP:N:\somestring\endcsname\relax + \expandafter\handleMPgraphic + \else + \csname\@@MP:N:\somestring\expandafter\endcsname + \fi + \handleMPsequence} +\fi + +\installMPSkeywordN \PSmoveto + {\edef\lastMPmoveX{\gMPa1}% + \edef\lastMPmoveY{\gMPa2}% + \resetMPstack} +\installMPSkeywordN \PSnewpath + {\let\handleMPsequence\handleMPpath} +\installMPSkeywordN \PSgsave + {\PDFcode{q}% + \resetMPstack} +\installMPSkeywordN \PSgrestore + {\PDFcode{Q}% + \resetMPstack} +\installMPSkeywordN \PSdtransform % == setlinewidth + {\let\handleMPsequence\handleMPdtransform} + % after that we will encounter more tokens until setlinewidth+pop + % or pop+setlinewidth which we catch next; we explicitly need to + % reset the stack since [] n setdash may follow; a more clever + % approach would be to read on till the condition is met, but it's + % the only pop / setlinewidth we will encounter so ... +\installMPSkeywordN \PSsetlinewidth + {% already handled in dtransform + \resetMPstack} +\installMPSkeywordN \PSpop + {% already handled in dtransform + \resetMPstack} +\installMPSkeywordN \PSconcat + {\cleanupMPconcat + \PDFcode{\gMPa1 \gMPa2 \gMPa3 \gMPa4 \gMPa5 \gMPa6 cm}% + \resetMPstack} +\installMPSkeywordN \PSsetrgbcolor + {\handleMPrgbcolor + \resetMPstack} +\installMPSkeywordN \PSsetcmykcolor + {\handleMPcmykcolor + \resetMPstack} +\installMPSkeywordN \PSsetgray + {\handleMPgraycolor + \resetMPstack} +\installMPSkeywordN \PStranslate + {\PDFcode{1 0 0 1 \gMPa1 \gMPa2 cm}% + \resetMPstack} +\installMPSkeywordN \PSsetdash + {\handleMPsetdash + \resetMPstack} +\installMPSkeywordN \PSsetlinejoin + {\PDFcode{\gMPa1 j}% + \resetMPstack} +\installMPSkeywordN \PSsetmiterlimit + {\PDFcode{\gMPa1 M}% + \resetMPstack} +\installMPSkeywordN \PSfshow + {%\PDFcode{n}% removed ! + \handleMPfshow + \resetMPstack} +\installMPSkeywordN \PSsetlinecap + {\PDFcode{\gMPa1 J}% + \resetMPstack} +\installMPSkeywordN \PSrlineto + {\flushMPmoveto + \PDFcode{\!MP\lastMPmoveX\space\!MP\lastMPmoveY\space l S}% + \resetMPmoveto + \resetMPstack} +\installMPSkeywordN \PSscale + {\PDFcode{\gMPa1 0 0 \gMPa2 0 0 cm}% + \resetMPstack} +\installMPSkeywordN \PSspecial + {\handleMPspecialcommand + \resetMPstack} + +\installMPSshortcutN {n} \PSnewpath +\installMPSshortcutN {p} \PSclosepath +\installMPSshortcutN {l} \PSlineto +\installMPSshortcutN {r} \PSrlineto +\installMPSshortcutN {m} \PSmoveto +\installMPSshortcutN {c} \PScurveto +\installMPSshortcutN {C} \PSsetcmykcolor +\installMPSshortcutN {G} \PSsetgray +\installMPSshortcutN {R} \PSsetrgbcolor +\installMPSshortcutN {lj} \PSsetlinejoin +\installMPSshortcutN {ml} \PSsetmiterlimit +\installMPSshortcutN {lc} \PSsetlinecap +\installMPSshortcutN {sd} \PSsetdash +\installMPSshortcutN {S} \PSstroke +\installMPSshortcutN {F} \PSfill +\installMPSshortcutN {W} \PSclip + +\installMPSshortcutN {q} \PSgsave +\installMPSshortcutN {Q} \PSgrestore + +\installMPSshortcutN {s} \PSscale +\installMPSshortcutN {t} \PSconcat +\installMPSshortcutN {P} \PSshowpage + +\installMPSkeywordN {hlw} {\PDFcode{\gMPa1 w}\resetMPstack} +\installMPSkeywordN {vlw} {\PDFcode{\gMPa1 w}\resetMPstack} +\installMPSkeywordN {rd} {\PDFcode{[] 0 d}\resetMPstack} + +\def\dohandleMPsequenceC#1 % + {\edef\somestring{#1}% + \handleMPgraphic % {#1}% + \handleMPsequence} + +%D Since colors are not sensitive to transformations, they +%D are sometimes used for signaling. Therefore, we handle them +%D separately. The next macro can be redefined if needed. + +\def\handleMPrgbcolor + {\PDFcode{\!MPgMPa1 \!MPgMPa2 \!MPgMPa3 rg + \!MPgMPa1 \!MPgMPa2 \!MPgMPa3 RG}} + +\def\handleMPcmykcolor + {\PDFcode{\!MPgMPa1 \!MPgMPa2 \!MPgMPa3 \!MPgMPa4 k + \!MPgMPa1 \!MPgMPa2 \!MPgMPa3 \!MPgMPa4 K}} + +\def\handleMPgraycolor + {\PDFcode{\!MPgMPa1 g + \!MPgMPa1 G}} + +\def\handleMPspotcolor + {\PDFcode{0 g + 0 G}} + +%D Beginning and ending the graphics is taken care of by the +%D macro \type{\handleMPgraphic}, which is redefined when +%D the first graphics operator is met. + +\def\handleMPendgraphic % #1% + {\ifx\somestring\PSshowpage + \let\handleMPsequence\finishMPgraphic + \else\ifx\somestring\PSEof + \let\handleMPsequence\finishMPgraphic + \else + \letMPargument\somestring % {#1}% + \fi\fi} + +\def\handleMPbegingraphic % #1% + {\ifx\somestring\PSBoundingBox + \def\handleMPsequence{\handleMPboundingbox1}% + \else\ifx\somestring\PSHiResBoundingBox + \def\handleMPsequence{\handleMPboundingbox2}% + \else\ifx\somestring\PSExactBoundingBox + \def\handleMPsequence{\handleMPboundingbox3}% + \else\ifx\somestring\PSshowpage + \let\handleMPsequence\finishMPgraphic + \else\ifx\somestring\PSEof + \let\handleMPsequence\finishMPgraphic + \else\ifx\somestring\PSPage + \let\handleMPsequence\handleMPpage + \else\ifx\somestring\PSMetaPostSpecials + \let\handleMPsequence\handleMPspecialscomment + \else\ifx\somestring\PSMetaPostSpecial + \let\handleMPsequence\handleMPspecialcomment + \else\ifx\somestring\PSBeginProlog + \let\handleMPsequence\handleMPprolog + \else + \letMPargument\somestring % {#1}% + \fi\fi\fi\fi\fi\fi\fi\fi\fi} + +\let\handleMPgraphic=\handleMPbegingraphic + +%D New: we can best filter the prolog because nowdays it can contain +%D quite some code. + +% hm, catcode mess, so we need to tweak %'s catcode here +% \long\expandafter\def\expandafter\handleMPprolog\expandafter#\expandafter1\PSEndProlog% +% but today i'm not in the mood for ugly stuff + +\long\def\handleMPprolog#1EndProlog % + {\doresetMPstack + \let\handleMPsequence\dohandleMPsequence + \handleMPsequence} + +%D We check for three kind of bounding boxes: the normal one +%D and two high precision ones: +%D +%D \starttyping +%D BoundingBox: llx lly ucx ucy +%D HiResBoundingBox: llx lly ucx ucy +%D ExactBoundingBox: llx lly ucx ucy +%D \stoptyping +%D +%D The original as well as the recalculated dimensions are +%D saved for later use. + +\newif\ifskipemptyMPgraphic \skipemptyMPgraphicfalse + +\chardef\currentMPboundingbox=0 + +\def\handleMPboundingbox#1#2 #3 #4 #5 + {\ifnum#1>\currentMPboundingbox + \xdef\MPllx{#2}\xdef\MPlly{#3}% + \xdef\MPurx{#4}\xdef\MPury{#5}% + \dimen0=#2pt + \dimen0=-\MPxscale\dimen0 + \dimen2=#3pt + \dimen2=-\MPyscale\dimen2 + \xdef\MPxoffset{\withoutpt\the\dimen0}% + \xdef\MPyoffset{\withoutpt\the\dimen2}% + \dimen0=#2bp + \dimen0=-\dimen0 + \dimen2=#3bp + \dimen2=-\dimen2 + \advance\dimen0 #4bp + \dimen0=\MPxscale\dimen0 + \xdef\MPwidth{\the\dimen0}% + \advance\dimen2 #5bp + \xdef\MPyshift{\the\dimen2}% unscaled + \dimen2=\MPyscale\dimen2 + \xdef\MPheight{\the\dimen2}% + \chardef\currentMPboundingbox#1\relax + \fi + \doresetMPstack + \let\handleMPsequence\dohandleMPsequence + \let\next\handleMPsequence + \ifskipemptyMPgraphic + \ifdim\MPheight=0pt\relax\ifdim\MPwidth=0pt\relax + \def\next{\endinput\finishMPgraphic}% + \fi\fi + \fi + \next} + +%D Unless defined otherwise, we simply ignore specialcomments. + +\def\handleMPspecialcomment + {\doresetMPstack + \let\handleMPsequence\dohandleMPsequence + \handleMPsequence} + +\let\handleMPspecialscomment\handleMPspecialcomment + +%D We use the \type{page} comment as a signal that +%D stackbuilding can be started. + +\def\handleMPpage #1 #2 + {\doresetMPstack + \donetrue + \let\handleMPsequence\dohandleMPsequence + \handleMPsequence} + +%D The same applies to the special extensions. + +\def\handleMPspecialcommand + {\doresetMPstack + \let\handleMPsequence\dohandleMPsequence + \handleMPsequence} + +%D \METAPOST\ draws its dots by moving to a location and +%D invoking \type{0 0 rlineto}. This operator is not +%D available in \PDF. Our solution is straightforward: we draw +%D a line from $(current\_x, current\_y)$ to itself. This +%D means that the arguments of the preceding \type{moveto} have +%D to be saved. + +\def\lastMPmoveX{0} +\def\lastMPmoveY{0} + +%D These saved coordinates are also used when we handle the +%D texts. Text handling proved to be a bit of a nuisance, but +%D finally I saw the light. It proved that we also had to +%D take care of \type{(split arguments)}. + +% \def\setMPfshowfont#1#2% +% {\font\temp=#1\space at #2\relax\temp} + +% \startMPcode +% draw btex Ga toch effe f\kern0ptietsen?{}` etex ; +% \stopMPcode + +\newtoks \everyMPshowfont + +\def\setMPfshowfont#1#2% + {\font\temp=#1\space at #2\relax\temp + \the\everyMPshowfont} + +\let\MPfshowcommand\empty + +%D The next hackery handles characters one by one. We only support this +%D for the latest greatest \METAPOST\ binaries, the ones that escape +%D problematic chars. + +\def\doflushMPtext#1% + {\edef\!!stringa{#1}% + \expandafter\dodoflushMPtext\!!stringa\relax} + +\def\dodoflushMPtext + {\afterassignment\dododoflushMPtext\let\nexttoken=} + +\def\dododoflushMPtext + {\ifx\nexttoken\relax + % done + \else\ifx\nexttoken\char + \expandafter\expandafter\expandafter\dodododoflushMPtext + \else + {\nexttoken}% + \expandafter\expandafter\expandafter\dodoflushMPtext + \fi\fi} + +\def\dodododoflushMPtext + {\afterassignment\dododododoflushMPtext\scratchcounter} + +\def\dododododoflushMPtext + {{\char\scratchcounter}\let\next\dodoflushMPtext} + +\def\dohandleMPfshow + {\bgroup + \setbox\scratchbox\hbox + {\obeyMPspecials + \let\ \relax % mp breaks long lines and appends a \ + \edef\size{\gMPa\nofMParguments}% + \ifx\size\PSnfont % round font size (to pt) + \advance\nofMParguments -1 + \expandafter\scratchdimen\gMPa\nofMParguments pt\relax + \ifdim\scratchdimen<1pt + \def\size{1pt}% + \else + \advance\scratchdimen .5pt + \def\size##1.##2\relax{\def\size{##1pt}}% + \expandafter\size\the\scratchdimen\relax + \fi + \else + \edef\size{\size bp}% + \fi + \advance\nofMParguments -1 + %\font\temp=\gMPa\nofMParguments\space at \size + \let\temp\relax % to be sure + \setMPfshowfont{\gMPa\nofMParguments}\size + \advance\nofMParguments -1 + \temp + \MPfshowcommand + {\ifnum\nofMParguments=1 + \def\do(##1){##1}% + \doflushMPtext{\dogMPa1}% only latest mp gets this treatment + \else + % we need to catch ( a ) (a a a) (\123 \123 \123) etc + \scratchcounter1 + \def\dodo##1% Andreas Fieger's bug: (\304...) + {\edef\!!stringa{##1\empty\empty}% and another one: ( 11) -> \ifx 11 + \ifx\!!stringa\MPspacechar\MPspacechar\else\expandafter##1\fi}% + \def\do(##1{\dodo{##1}}% + \dogMPa\scratchcounter\MPspacechar + \let\do\relax + \loop + \advance\scratchcounter 1 + \ifnum\scratchcounter<\nofMParguments\relax + \gMPa\scratchcounter\MPspacechar + \repeat + \def\do##1){\dodo{##1}}% + \dogMPa\scratchcounter + \fi + \unskip}}% + \setbox\scratchbox\hbox + {\hskip\lastMPmoveX bp\raise\lastMPmoveY bp\box\scratchbox}% + \ht\scratchbox0pt% + \dp\scratchbox0pt% + \wd\scratchbox0pt% + \box\scratchbox + \egroup} + +\let\handleMPfshow\dohandleMPfshow % so we can overload this one later + +%D You could consider the following definition to be the most +%D natural one. + +% \def\MPspacechar{\space} % normal case + +\def\MPspacechar{\char32\relax} % old solution does not work with math + +%D However, the following implementation is more robust, since +%D some fonts have funny visible spaces in the space slot. This +%D gives a mismatch between the space that \METAPOST\ took into +%D account and the \quote {natural} space. This only happens in +%D labels, since \type {btex}||\type {etex} thingies don't have +%D spaces. This phenomena showed up when preparing the +%D \METAFUN\ manual, where Palatino fonts are used. We can +%D safely assume that \METAPOST\ considers \type {\char32} to +%D be the space. + +\def\MPspacechar{\setbox\scratchbox\hbox{\char32}\kern\wd\scratchbox} + +%D Well, this does not work with math fonts, so: + +\def\MPspacechar{\char32\relax} + +%D Most operators are just converted and keep their +%D arguments. Dashes however need a bit different treatment, +%D otherwise \PDF\ viewers complain loudly. Another +%D complication is that one argument comes after the \type{]}. +%D When reading the data, we simply ignore the array boundary +%D characters. We save ourselves some redundant newlines and +%D at the same time keep the output readable by packing the +%D literals. + +\def\handleMPsetdash + {\bgroup + \ignoreMPspecials + \def\somestring{[}% + \scratchcounter1 + \loop + \ifnum\scratchcounter<\nofMParguments + \edef\somestring{\somestring\space\gMPa\scratchcounter}% + \advance\scratchcounter 1 + \repeat + \edef\somestring{\somestring]\gMPa\scratchcounter\space d}% + \PDFcode{\somestring}% + \egroup} + +%D The \type{setlinewidth} commands looks a bit complicated. There are +%D two alternatives, that result in a similar look in both +%D $x$- and $y$-dorection. As John Hobby says: +%D +%D \startnarrower \switchtobodyfont[ss] +%D \starttyping +%D x 0 dtransform exch truncate exch idtransform pop setlinewidth +%D 0 y dtransform truncate idtransform setlinewidth pop +%D \stoptyping +%D +%D These are just fancy versions of \type{x setlinewidth} and +%D \type{y setlinewidth}. The \type{x 0 ...} form is used if +%D the path is {\em primarily vertical}. It rounds the width +%D so that vertical lines come out an integer number of pixels +%D wide in device space. The \type{0 y ...} form does the same +%D for paths that are {\em primarily horizontal}. The reason +%D why I did this is Knuth insists on getting exactly the +%D widths \TEX\ intends for the horizontal and vertical rules +%D in \type{btex...etex} output. (Note that PostScript scan +%D conversion rules cause a horizontal or vertical line of +%D integer width $n$ in device space to come out $n+1$ pixels +%D wide, regardless of the phase relative to the pixel grid.) +%D \stopnarrower +%D +%D The common operator in these sequences is \type{dtransform}, +%D so we can use this one to trigger setting the linewidth. + +\def\handleMPdtransform + {\ifdim\gMPa1 pt>0pt + \PDFcode{\gMPa1 w}% + \def\next##1 ##2 ##3 ##4 ##5 ##6 {\handleMPsequence}% + \else + \PDFcode{\gMPa2 w}% + \def\next##1 ##2 ##3 ##4 {\handleMPsequence}% + \fi + \let\handleMPsequence\dohandleMPsequence + \resetMPstack + \next} + +%D The most complicated command is \type{concat}. \METAPOST\ +%D applies this operator to \type{stroke}. At that moment the +%D points set by \type{curveto} and \type{moveto}, are already +%D fixed. In \PDF\ however the \type{cm} operator affects the +%D points as well as the pen (stroke). Like more \PDF\ +%D operators, \type{cm} is defined in a bit ambiguous way. +%D The only save route for non||circular penshapes, is saving +%D the path, recalculating the points and applying the +%D transformation matrix in such a way that we can be sure +%D that its behavior is well defined. This comes down to +%D inverting the path and applying \type{cm} to that path as +%D well as the pen. This all means that we have to save the +%D path. + +%D In \METAPOST\ there are three ways to handle a path $p$: +%D +%D \starttyping +%D draw p; fill p; filldraw p; +%D \stoptyping +%D +%D The last case outputs a \type{gsave fill grestore} before +%D \type{stroke}. Handling the path outside the main loops +%D saves about 40\% run time.\footnote{We can save some more by +%D following the \METAPOST\ output routine, but for the moment +%D we keep things simple.} Switching between the main loop and +%D the path loop is done by means of the recursely called +%D macro \type{\handleMPsequence}. + +\def\handleMPpath + {\chardef\finiMPpath0 + \let\closeMPpath\relax + \let\flushMPpath\flushnormalMPpath + \resetMPstack + \nofMPsegments1 + \let\handleMPsequence\dohandleMPpath + \dohandleMPpath} + +%D Most paths are drawn with simple round pens. Therefore we've +%D split up the routine in two. + +\def\flushnormalMPsegment + {\ifcase\getMPkeyword\relax + \PDFcode{\!MPgMPs1 \!MPgMPs2 l}% + \or + \PDFcode{\!MPgMPs1 \!MPgMPs2 \!MPgMPs3 \!MPgMPs4 \!MPgMPs5 \!MPgMPs6 c}% + \or + \PDFcode{\!MP\lastMPmoveX\space\!MP\lastMPmoveY\space l}% + \or + \edef\lastMPmoveX{\gMPs1}% evt \!MP here + \edef\lastMPmoveY{\gMPs2}% + \PDFcode{\!MP\lastMPmoveX\space \!MP\lastMPmoveY\space m}% + \fi} + +\def\flushconcatMPsegment + {\ifcase\getMPkeyword\relax + \doMPconcat{\gMPs1}\a{\gMPs2}\b% + \PDFcode{\!MP\a\space\!MP\b\space l}% + \or + \doMPconcat{\gMPs1}\a{\gMPs2}\b% + \doMPconcat{\gMPs3}\c{\gMPs4}\d% + \doMPconcat{\gMPs5}\e{\gMPs6}\f% + \PDFcode{\!MP\a\space\!MP\b\space + \!MP\c\space\!MP\d\space + \!MP\e\space\!MP\f\space c}% + \or + \bgroup + \noMPtranslate + \doMPconcat\lastMPmoveX\a\lastMPmoveY\b% + \PDFcode{\!MP\a\space\!MP\b\space l S}% + \egroup + \or + \edef\lastMPmoveX{\gMPs1}% + \edef\lastMPmoveY{\gMPs2}% + \doMPconcat\lastMPmoveX\a\lastMPmoveY\b% + \PDFcode{\!MP\a\space\!MP\b\space m}% + \fi} + +% \def\flushnormalMPpath +% {\scratchcounter\nofMPsegments +% \nofMPsegments 1 +% \loop +% \flushnormalMPsegment +% \advance\nofMPsegments 1 +% \ifnum\nofMPsegments<\scratchcounter +% \repeat} +% +% \def\flushconcatMPpath +% {\scratchcounter\nofMPsegments +% \nofMPsegments 1 +% \loop +% \flushconcatMPsegment +% \advance\nofMPsegments 1 +% \ifnum\nofMPsegments<\scratchcounter +% \repeat} +% +% an alternative is presented below: (no \def assignment) + +\def\doflushsomeMPpath + {\dodoflushsomeMPpath + \advance\nofMPsegments 1 + \ifnum\nofMPsegments<\scratchcounter + \expandafter\doflushsomeMPpath + \fi} + +\def\flushsomeMPpath + {\scratchcounter\nofMPsegments + \nofMPsegments 1 + \doflushsomeMPpath} + +\def\flushnormalMPpath{\let\dodoflushsomeMPpath\flushnormalMPsegment\flushsomeMPpath} + +%OLD \def\flushconcatMPpath{\let\dodoflushsomeMPpath\flushconcatMPsegment\flushsomeMPpath} + +%NEW pre-calculate 1/D so it needn't be repeated for each control point. + +\def\flushconcatMPpath + {\MPreciprocaldeterminant + \let\dodoflushsomeMPpath\flushconcatMPsegment\flushsomeMPpath} + +%D The transformation of the coordinates is handled by one of +%D the macros Tanmoy posted to the \PDFTEX\ mailing list. +%D I rewrote and optimized the original macro to suit the other +%D macros in this module. +%D +%D \starttyping +%D \doMPconcat {x position} \xresult {y position} \yresult +%D \stoptyping +%D +%D By setting the auxiliary \DIMENSIONS\ \type{\dimen0} upto +%D \type{\dimen10} only once per path, we save over 20\% run +%D time. Some more speed was gained by removing some parameter +%D passing. These macros can be optimized a bit more by using +%D more constants. There is however not much need for further +%D optimization because penshapes usually are round and +%D therefore need no transformation. Nevertheless we move the +%D factor to the outer level and use a bit different \type{pt} +%D removal macro. Although the values represent base points, +%D we converted them to pure points, simply because those can +%D be converted back. + +%OLD \mathchardef\MPconcatfactor=256 % beware don't remove spaces before it + +%OLD \def\doMPreducedimen#1 +%OLD {\count0\MPconcatfactor +%OLD \advance\dimen#1 \ifdim\dimen#1>0pt .5\else -.5\fi\count0 +%OLD \divide\dimen#1 \count0\relax} + +%OLD % too inaccurate (see old pragma logo) +%OLD +%OLD \def\doMPreducedimen#1 +%OLD {\count0=\MPconcatfactor +%OLD \divide\dimen#1 \count0\relax} + +%OLD \def\doMPreducedimen#1 +%OLD {\advance\dimen#1 \ifdim\dimen#1>0pt .5\else -.5\fi\MPconcatfactor +%OLD \divide\dimen#1 \MPconcatfactor} + +%D The transformation code is rewritten by Daniel H. Luecking who +%D describes his patch as follows: +%D +%D We would like to divide 1 by $X$, but all divisions are integer so +%D for accuracy we want to convert to large integers and make sure the +%D integer quotient has as many significant digits as possible. Thus we +%D need to replace $1/X$ with $M/N$ where $N$ is as large as possible +%D and $M/N$ is as large as possible. Also for simplicity $M$ should be +%D a power of 2. So we make $M = 2^{30}$ \footnote{$2^{31} - 1$ is the +%D largest legal integer. Using it (and simply ignoring the inaccuracy +%D caused by $-1$) turns out to be at least as accurate in all cases, +%D and more accurate in some.} (largest legal power of 2) and adjust +%D $X$ downward (if necessary) to the the range $1-2^{16}$. This gives +%D at least 15 significant binary digits, (almost as accurate as +%D \METAPOST\ for numbers near 1) or almost 5 significant figures +%D (decimal). + +\newcount\MPscratchCnt +\newdimen\MPscratchDim % will be assigned global + +\def\MPadjustdimen % sets \MPscratchDim and \MPscratchCnt + {\MPscratchCnt0 + \doMPadjustdimen} + +\def\doMPadjustdimen + {\ifdim\MPscratchDim>1pt + \divide\MPscratchDim 2 + \advance\MPscratchCnt 1 + \expandafter\doMPadjustdimen + \fi} + +%OLD \def\doMPexpanddimen#1 +%OLD {\multiply\dimen#1 \MPconcatfactor\relax} + +%D DHL: When viewed as an integer, $1 \hbox{pt}=2^{16}$ so $2^{32}/X$ +%D is the right way to do $(1 \hbox{pt})/(X \hbox{pt})$ and get the +%D answer in points. But we are limited to $2^{30}/X$. However, we +%D actually do $[ 2^{30} / (X/2^K) ]*2^{2-K}$ where $K$ is the number +%D of halvings it takes to bring $X$ below $1 \hbox{pt}$. If $K$ is 0 +%D or 1 we readjust by multiplying by 4 or 2, otherwise by halving +%D $(K-2)$ times \type {\MPscratchCnt} holds the value of $K$ from +%D \type {\MPadjustdimen}. + +\def\MPreadjustdimen % acts on \MPscratchDim and MPscratchCnt + {\ifcase\MPscratchCnt + \multiply\scratchdimen 4 + \or + \multiply\scratchdimen 2 + \else + \expandafter\doMPreadjustdimen + \fi} + +\def\doMPreadjustdimen + {\ifnum\MPscratchCnt>2 + \divide\scratchdimen 2 + \advance\MPscratchCnt -1 + \expandafter\doMPreadjustdimen + \fi} + +\def\MPreciprocaldeterminant + {\scratchdimen\withoutpt\the\dimen0 \dimen6 % s_x*s_y + \advance\scratchdimen - \withoutpt\the\dimen2 \dimen4 % s_x*s_y - r_x*r_y + \ifdim\scratchdimen<0pt % we need a positive dimension + \scratchdimen-\scratchdimen % for \MPadjustdimen (?) + \doMPreciprocal + \scratchdimen-\scratchdimen + \else + \doMPreciprocal + \fi + \edef\MPreciprocal{\withoutpt\the\scratchdimen}} + +\newcount\MPnumerator \MPnumerator = 1073741824 % 2^{30} + +% todo: dimexpr + +\def\doMPreciprocal % replace \scratchdimen with its reciprocal + {\ifdim\scratchdimen=1pt \else + \MPadjustdimen + \scratchcounter\MPnumerator + \divide\scratchcounter\scratchdimen + \scratchdimen1\scratchcounter % 1 needed ! + \MPreadjustdimen + \fi} + +%OLD \def\presetMPconcat +%OLD {\dimen 0=\gMPs1pt \doMPreducedimen 0 % r_x +%OLD \dimen 2=\gMPs2pt \doMPreducedimen 2 % s_x +%OLD \dimen 4=\gMPs3pt \doMPreducedimen 4 % s_y +%OLD \dimen 6=\gMPs4pt \doMPreducedimen 6 % r_y +%OLD \dimen 8=\gMPs5pt \doMPreducedimen 8 % t_x +%OLD \dimen10=\gMPs6pt \doMPreducedimen10 } % t_y +%OLD +%OLD \def\presetMPscale +%OLD {\dimen 0=\gMPs1pt \doMPreducedimen 0 +%OLD \dimen 2=0pt +%OLD \dimen 4=0pt +%OLD \dimen 6=\gMPs2pt \doMPreducedimen 6 +%OLD \dimen 8=0pt +%OLD \dimen10=0pt} + +\def\cleanupMPconcat + {\ignoreMPspecials + \docleanupMPargument1% + \docleanupMPargument6% + \keepMPspecials} + +\def\presetMPconcat + {\dimen 0=\gMPs1pt % s_x + \dimen 2=\gMPs2pt % r_x + \dimen 4=\gMPs3pt % r_y + \dimen 6=\gMPs4pt % s_y + \dimen 8=\gMPs5pt % t_x + \dimen10=\gMPs6pt} % t_y + +\def\presetMPscale + {\dimen 0=\gMPs1pt + \dimen 2=0pt + \dimen 4=0pt + \dimen 6=\gMPs2pt + \dimen 8=0pt + \dimen10=0pt} + +\def\noMPtranslate % use this one grouped + {\dimen 8=0pt % t_x + \dimen10=0pt} % t_y + +%D \starttyping +%D \def\doMPconcat#1#2#3#4% +%D {\dimen12=#1 pt \doMPreducedimen12 % p_x +%D \dimen14=#3 pt \doMPreducedimen14 % p_y +%D % +%D \dimen16 \dimen 0 +%D \multiply \dimen16 \dimen 6 +%D \dimen20 \dimen 2 +%D \multiply \dimen20 \dimen 4 +%D \advance \dimen16 -\dimen20 +%D % +%D \dimen18 \dimen12 +%D \multiply \dimen18 \dimen 6 +%D \dimen20 \dimen14 +%D \multiply \dimen20 \dimen 4 +%D \advance \dimen18 -\dimen20 +%D \dimen20 \dimen 4 +%D \multiply \dimen20 \dimen10 +%D \advance \dimen18 \dimen20 +%D \dimen20 \dimen 6 +%D \multiply \dimen20 \dimen 8 +%D \advance \dimen18 -\dimen20 +%D % +%D \multiply \dimen12 -\dimen 2 +%D \multiply \dimen14 \dimen 0 +%D \advance \dimen12 \dimen14 +%D \dimen20 \dimen 2 +%D \multiply \dimen20 \dimen 8 +%D \advance \dimen12 \dimen20 +%D \dimen20 \dimen 0 +%D \multiply \dimen20 \dimen10 +%D \advance \dimen12 -\dimen20 +%D % +%D \doMPreducedimen16 +%D \divide \dimen18 \dimen16 \doMPexpanddimen18 +%D \divide \dimen12 \dimen16 \doMPexpanddimen12 +%D % +%D \edef#2{\withoutpt\the\dimen18}% % p_x^\prime +%D \edef#4{\withoutpt\the\dimen12}} % p_y^\prime +%D \stoptyping + +%D The following optimization resulted from some tests by +%D and email exchanges with Sanjoy Mahajan. +%D +%D \starttyping +%D \def\doMPconcat#1#2#3#4% +%D {\dimen12=#1 pt \doMPreducedimen12 % p_x +%D \dimen14=#3 pt \doMPreducedimen14 % p_y +%D % +%D \dimen16 \dimen 0 +%D \multiply \dimen16 \dimen 6 +%D \dimen20 \dimen 2 +%D \multiply \dimen20 \dimen 4 +%D \advance \dimen16 -\dimen20 +%D % +%D \dimen18 \dimen12 +%D \multiply \dimen18 \dimen 6 +%D \dimen20 \dimen14 +%D \multiply \dimen20 \dimen 4 +%D \advance \dimen18 -\dimen20 +%D \dimen20 \dimen 4 +%D \multiply \dimen20 \dimen10 +%D \advance \dimen18 \dimen20 +%D \dimen20 \dimen 6 +%D \multiply \dimen20 \dimen 8 +%D \advance \dimen18 -\dimen20 +%D % +%D \multiply \dimen12 -\dimen 2 +%D \multiply \dimen14 \dimen 0 +%D \advance \dimen12 \dimen14 +%D \dimen20 \dimen 2 +%D \multiply \dimen20 \dimen 8 +%D \advance \dimen12 \dimen20 +%D \dimen20 \dimen 0 +%D \multiply \dimen20 \dimen10 +%D \advance \dimen12 -\dimen20 +%D % +%D %\ifdim\dimen16>1pt % oeps, can be < 1pt too +%D \ifdim\dimen16=1pt \else +%D \ifdim\dimen16>\MPconcatfactor pt +%D \doMPreducedimen16 +%D \divide \dimen18 \dimen16 \doMPexpanddimen18 +%D \divide \dimen12 \dimen16 \doMPexpanddimen12 +%D \else +%D \divide \dimen18 \dimen16 \doMPexpanddimen18 \doMPexpanddimen18 +%D \divide \dimen12 \dimen16 \doMPexpanddimen12 \doMPexpanddimen12 +%D \fi +%D \fi +%D % +%D \edef#2{\withoutpt\the\dimen18}% % p_x^\prime +%D \edef#4{\withoutpt\the\dimen12}} % p_y^\prime +%D \stoptyping +%D +%D But, this one is still too inaccurate, so we now have: + +% \def\doMPconcat#1#2#3#4% +% {\dimen12=#1pt % p_x +% \dimen14=#3pt % p_y +% % +% % we should test for >-1024 too, but for the moment take the gamble +% \chardef\MPfactor1\ifdim\dimen12<1024pt \ifdim\dimen14<1024pt 6\fi\fi +% % +% \multiply\dimen12 \MPfactor +% \multiply\dimen14 \MPfactor +% % +% \doMPreducedimen12 +% \doMPreducedimen14 +% % +% \dimen16 \dimen 0 +% \multiply \dimen16 \dimen 6 +% \dimen20 \dimen 2 +% \multiply \dimen20 \dimen 4 +% \advance \dimen16 -\dimen20 +% % +% \dimen18 \dimen12 +% \multiply \dimen18 \dimen 6 +% \dimen20 \dimen14 +% \multiply \dimen20 \dimen 4 +% \advance \dimen18 -\dimen20 +% \dimen20 \dimen 4 +% \multiply \dimen20 \dimen10 +% \advance \dimen18 \dimen20 +% \dimen20 \dimen 6 +% \multiply \dimen20 \dimen 8 +% \advance \dimen18 -\dimen20 +% % +% \multiply \dimen12 -\dimen 2 +% \multiply \dimen14 \dimen 0 +% \advance \dimen12 \dimen14 +% \dimen20 \dimen 2 +% \multiply \dimen20 \dimen 8 +% \advance \dimen12 \dimen20 +% \dimen20 \dimen 0 +% \multiply \dimen20 \dimen10 +% \advance \dimen12 -\dimen20 +% % +% \ifdim\dimen16=1pt \else +% \ifdim\dimen16>\MPconcatfactor pt +% \doMPreducedimen16 +% \divide \dimen18 \dimen16 \doMPexpanddimen18 +% \divide \dimen12 \dimen16 \doMPexpanddimen12 +% \else +% \divide \dimen18 \dimen16 \doMPexpanddimen18 \doMPexpanddimen18 +% \divide \dimen12 \dimen16 \doMPexpanddimen12 \doMPexpanddimen12 +% \fi +% \fi +% % +% \divide\dimen18 \MPfactor +% \divide\dimen12 \MPfactor +% % +% \edef#2{\withoutpt\the\dimen18}% % p_x^\prime +% \edef#4{\withoutpt\the\dimen12}} % p_y^\prime + +%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 +%D arithmetic instead of using real factors because it's faster. +%D However, the actual macros test slower, possibly because I've +%D omitted three nested loops. In my test files, my approach is more +%D accurate. It is also far simpler and overflow does not seem to be a +%D significant concern. The scale factors written by Metapost are (?) +%D always $<=1$ (it scales coordinates internally) and coordinates are +%D always likely to be less than \type {\maxdimen}. +%D +%D If this should ever cause problems, the scale factors can be reduced. + +% \def\doMPconcat#1#2#3#4% +% {\dimen12=#1pt % p_x % #1pt +% \dimen14=#3pt % p_y % #3pt +% \advance\dimen12 -\dimen8 % p_x - t_x +% \advance\dimen14 -\dimen10 % p_y - t_y +% \dimen18=\withoutpt\the\dimen6 \dimen12 % s_y(p_x - t_x) +% \advance\dimen18 -\withoutpt\the\dimen4 \dimen14 % - r_y(p_y-t_y) +% \dimen14=\withoutpt\the\dimen0 \dimen14 % s_x(p_y-t_y) +% \advance\dimen14 -\withoutpt\the\dimen2 \dimen12 % - r_x(p_x-t_x) +% % \MPscratchDim contains precomputed 1/D: +% \dimen18=\withoutpt\the\MPscratchDim \dimen18 +% \dimen14=\withoutpt\the\MPscratchDim \dimen14 +% \edef#2{\withoutpt\the\dimen18}% % p_x^\prime +% \edef#4{\withoutpt\the\dimen14}} % p_y^\prime + +\def\doMPconcat#1#2#3#4% + {\dimen12=#1pt % p_x % #1pt + \dimen14=#3pt % p_y % #3pt + \advance\dimen12 -\dimen8 % p_x - t_x + \advance\dimen14 -\dimen10 % p_y - t_y + \dimen18=\withoutpt\the\dimen6 \dimen12 % s_y(p_x - t_x) + \advance\dimen18 -\withoutpt\the\dimen4 \dimen14 % - r_y(p_y-t_y) + \dimen14=\withoutpt\the\dimen0 \dimen14 % s_x(p_y-t_y) + \advance\dimen14 -\withoutpt\the\dimen2 \dimen12 % - r_x(p_x-t_x) + % \MPreciprocal contains precomputed 1/D: + \dimen18=\MPreciprocal\dimen18 + \dimen14=\MPreciprocal\dimen14 + \edef#2{\withoutpt\the\dimen18}% % p_x^\prime + \edef#4{\withoutpt\the\dimen14}} % p_y^\prime + +% faster but not that often used +% +% \def\doMPconcat#1#2#3#4% +% {\dimen12\dimexpr#1\points-\dimen 8\relax % p_x-t_x +% \dimen14\dimexpr#3\points-\dimen10\relax % p_y-t_y +% \dimen18\dimexpr\withoutpt\the\dimen6\dimen12-\withoutpt\the\dimen4\dimen14\relax % s_y(p_x-t_x)-r_y(p_y-t_y) +% \dimen14\dimexpr\withoutpt\the\dimen0\dimen14-\withoutpt\the\dimen2\dimen12\relax % s_x(p_y-t_y)-r_x(p_x-t_x) +% \edef#2{\withoutpt\the\dimexpr\MPreciprocal\dimen18\relax}% % p_x^\prime +% \edef#4{\withoutpt\the\dimexpr\MPreciprocal\dimen14\relax}} % p_y^\prime + +%D One reason for Daniel to write this patch was that at small sizes +%D the accuracy was less than optimal. Here is a test that demonstrates +%D that his alternative is pretty good: +%D +%D \startlinecorrection +%D \startMPcode +%D for i = 5cm,1cm,5mm,1mm,.5mm,.1mm,.01mm : +%D draw fullcircle scaled i withpen pencircle xscaled (i/10) yscaled (i/20) rotated 45 ; +%D endfor ; +%D \stopMPcode +%D \stoplinecorrection + +%D The following explanation of the conversion process was +%D posted to the \PDFTEX\ mailing list by Tanmoy. The original +%D macro was part of a set of macro's that included sinus and +%D cosinus calculations as well as scaling and translating. The +%D \METAPOST\ to \PDF\ conversion however only needs +%D transformation. + +%M \start \switchtobodyfont [ss] + +%D Given a point $(U_x, U_y)$ in user coordinates, the business +%D of \POSTSCRIPT\ is to convert it to device space. Let us say +%D that the device space coordinates are $(D_x, D_y)$. Then, in +%D \POSTSCRIPT\ $(D_x, D_y)$ can be written in terms of +%D $(U_x, U_y)$ in matrix notation, either as +%D +%D \placeformula +%D \startformula +%D \pmatrix{D_x&D_y&1\cr} = \pmatrix{U_x&U_y&1\cr} +%D \pmatrix{s_x&r_x&0\cr +%D r_y&s_y&0\cr +%D t_x&t_y&1\cr} +%D \stopformula +%D +%D or +%D +%D \placeformula +%D \startformula +%D \pmatrix{D_x\cr D_y\cr 1} = \pmatrix{s_x&r_y&t_x\cr +%D r_x&s_y&t_y\cr +%D 0 &0 &1 \cr} +%D \pmatrix{U_x\cr +%D U_y\cr +%D 1 \cr} +%D \stopformula +%D +%D both of which is a shorthand for the same set of equations: +%D +%D \placeformula +%D \startformula +%D D_x = s_x U_x + r_y U_y + t_x +%D \stopformula +%D +%D \placeformula +%D \startformula +%D D_y = r_x U_x + s_y U_y + t_y +%D \stopformula +%D +%D which define what is called an `affine transformation'. +%D +%D \POSTSCRIPT\ represents the `transformation matrix' as a +%D six element matrix instead of a $3\times 3$ array because +%D three of the elements are always~0, 0 and~1. Thus the above +%D transformation is written in postscript as $[s_x\, r_x\, +%D r_y\, s_y\, t_x\, t_y]$. However, when doing any +%D calculations, it is useful to go back to the original +%D matrix notation (whichever: I will use the second) and +%D continue from there. +%D +%D As an example, if the current transformation matrix is +%D $[s_x\, r_x\, r_y\, s_y\, t_x\, t_y]$ and you say \typ{[a b +%D c d e f] concat}, this means: +%D +%D \startnarrower +%D Take the user space coordinates and transform them to an +%D intermediate set of coordinates using array $[a\, b\, c\, d\, +%D e\, f]$ as the transformation matrix. +%D +%D Take the intermediate set of coordinates and change them to +%D device coordinates using array $[s_x\, r_x\, r_y\, s_y\, t_x\, t_y]$ +%D as the transformation matrix. +%D \stopnarrower +%D +%D Well, what is the net effect? In matrix notation, it is +%D +%D \placeformula +%D \startformula +%D \pmatrix{I_x\cr I_y\cr 1\cr} = \pmatrix{a&c&e\cr +%D b&d&f\cr +%D 0&0&1\cr} +%D \pmatrix{U_x\cr +%D U_y\cr +%D 1 \cr} +%D \stopformula +%D +%D \placeformula +%D \startformula +%D \pmatrix{D_y\cr D_y\cr 1\cr} = \pmatrix{s_x&r_y&t_x\cr +%D r_x&s_y&t_y\cr +%D 0 &0 &1 \cr} +%D \pmatrix{I_x\cr +%D I_y\cr +%D 1 \cr} +%D \stopformula +%D +%D where $(I_x, I_y)$ is the intermediate coordinate. +%D +%D Now, the beauty of the matrix notation is that when there is +%D a chain of such matrix equations, one can always compose +%D them into one matrix equation using the standard matrix +%D composition law. The composite matrix from two matrices can +%D be derived very easily: the element in the $i$\high{th} +%D horizontal row and $j$\high{th} vertical column is +%D calculated by`multiplying' the $i$\high{th} row of the first +%D matrix and the $j$\high{th} column of the second matrix (and +%D summing over the elements). Thus, in the above: +%D +%D \placeformula +%D \startformula +%D \pmatrix{D_x\cr D_y\cr 1} = \pmatrix{s_x^\prime&r_y^\prime&t_x^\prime\cr +%D r_x^\prime&s_y^\prime&t_y^\prime\cr +%D 0 &0 &0 \cr} +%D \pmatrix{U_x\cr +%D U_y\cr +%D 1 \cr} +%D \stopformula +%D +%D with +%D +%D \placeformula +%D \startformula +%D \eqalign +%D {s_x^\prime & = s_x a + r_y b \cr +%D r_x^\prime & = r_x a + s_y b \cr +%D r_y^\prime & = s_x c + r_y d \cr +%D s_y^\prime & = r_x c + s_y d \cr +%D t_x^\prime & = s_x e + r_y f + t_x \cr +%D t_y^\prime & = r_x e + s_y f + t_y \cr} +%D \stopformula + +%D In fact, the same rule is true not only when one is going +%D from user coordinates to device coordinates, but whenever +%D one is composing two `transformations' together +%D (transformations are `associative'). Note that the formula +%D is not symmetric: you have to keep track of which +%D transformation existed before (i.e.\ the equivalent of +%D $[s_x\, r_x\, r_y\, s_y\, t_x\, t_y]$) and which was +%D specified later (i.e.\ the equivalent of $[a\, b\, c\, d\, +%D e\, f]$). Note also that the language can be rather +%D confusing: the one specified later `acts earlier', +%D converting the user space coordinates to intermediate +%D coordinates, which are then acted upon by the pre||existing +%D transformation. The important point is that order of +%D transformation matrices cannot be flipped (transformations +%D are not `commutative'). +%D +%D Now what does it mean to move a transformation matrix +%D before a drawing? What it means is that given a point +%D $(P_x, P_y)$ we need a different set of coordinates +%D $(P_x^\prime, P_y^\prime)$ such that if the transformation +%D acts on $(P_x^\prime, P_y^\prime)$, they produce $(P_x, +%D P_y)$. That is we need to solve the set of equations: +%D +%D \placeformula +%D \startformula +%D \pmatrix{P_x\cr P_y\cr 1\cr} = \pmatrix{s_x&r_y&t_x\cr +%D r_x&s_y&t_y\cr +%D 0 &0 &1 \cr} +%D \pmatrix{P_x^\prime\cr +%D P_y^\prime\cr +%D 1 \cr} +%D \stopformula +%D +%D Again matrix notation comes in handy (i.e. someone has +%D already solved the problem for us): we need the inverse +%D transformation matrix. The inverse transformation matrix can +%D be calculated very easily: +%D +%D \placeformula +%D \startformula +%D \pmatrix{P_x^\prime\cr P_y^\prime\cr 1\cr} = +%D \pmatrix{s_x^\prime&r_y^\prime&t_x^\prime\cr +%D r_x^\prime&s_y^\prime&t_y^\prime\cr +%D 0 &0 &1 \cr} +%D \pmatrix{P_x\cr +%D P_y\cr +%D 1 \cr} +%D \stopformula +%D +%D where, the inverse transformation matrix is given by +%D +%D \placeformula +%D \startformula +%D \eqalign +%D {D & = s_x s_y - r_x r_y \cr +%D s_x^\prime & = s_y / D \cr +%D s_y^\prime & = s_x / D \cr +%D r_x^\prime & = - r_x / D \cr +%D r_y^\prime & = - r_y / D \cr +%D t_x^\prime & = ( - s_y t_x + r_y t_y ) / D \cr +%D t_y^\prime & = ( r_x t_x - s_x t_y ) / D \cr} +%D \stopformula +%D +%D And you can see that when expanded out, this does +%D give the formulas: +%D +%D \placeformula +%D \startformula +%D P_x^\prime = { { s_y(p_x-t_x) + r_y(t_y-p_y) } \over +%D { s_x s_y-r_x r_y } } +%D \stopformula +%D +%D \placeformula +%D \startformula +%D P_y^\prime = { { s_x(p_y-t_y) + r_x(t_x-p_x) } \over +%D { s_x*s_y-r_x*r_y } } +%D \stopformula +%D +%D The code works by representing a real number by converting +%D it to a dimension to be put into a \DIMENSION\ register: 2.3 would +%D be represented as 2.3pt for example. In this scheme, +%D multiplying two numbers involves multiplying the \DIMENSION\ +%D registers and dividing by 65536. Accuracy demands that the +%D division be done as late as possible, but overflow +%D considerations need early division. +%D +%D Division involves dividing the two \DIMENSION\ registers and +%D multiplying the result by 65536. Again, accuracy would +%D demand that the numerator be multiplied (and|/|or the +%D denominator divided) early: but that can lead to overflow +%D which needs to be avoided. +%D +%D If nothing is known about the numbers to start with (in +%D concat), I have chosen to divide the 65536 as a 256 in each +%D operand. However, in the series calculating the sine and +%D cosine, I know that the terms are small (because I never +%D have an angle greater than 45 degrees), so I chose to +%D apportion the factor in a different way. + +%M \stop + +%D The path is output using the values saved on the stack. If +%D needed, all coordinates are recalculated. + +\def\finishMPpath + {\PDFcode{\ifcase\finiMPpath W n\or S\or f\or B\fi}} + +\def\processMPpath + {\checkMPpath + \ifcase\nofMPsegments\else + \flushMPpath + \closeMPpath + \finishMPpath + \fi + \let\handleMPsequence\dohandleMPsequence + \resetMPstack + \nofMPsegments0 + \handleMPsequence} + +%D The following \METAPOST\ code is quite valid but, when +%D processed and converted to \PDF, will make a file +%D unprintable on a Hewlett Packard printer (from Acrobat +%D $v<=5$). Who is to blame, the driver of the OS layer in +%D between, is hard to determine, so we add an additional +%D check. +%D +%D \starttyping +%D clip currentpicture to origin -- cycle ; +%D setbounds currentpicture to fullsquare scaled 5cm ; +%D \stoptyping + +\def\checkMPpath + {\ifcase\finiMPpath + \ifnum\nofMPsegments<3 % n is one ahead + \message{omitting zero clip path}% + \nofMPsegments0 + \fi + \fi} + +%D In \PDF\ the \type{cm} operator must precede the path +%D specification. We therefore can output the \type{cm} at +%D the moment we encounter it. + +\def\handleMPpathconcat + {\presetMPconcat + \PDFcode{\gMPs1 \gMPs2 \gMPs3 \gMPs4 \gMPs5 \gMPs6 cm}% + \resetMPstack} + +\def\handleMPpathscale + {\presetMPscale + \PDFcode{\gMPs1 0 0 \gMPs2 0 0 cm}% + \resetMPstack} + +%D This macro interprets the path and saves it as compact as +%D possible. + +\def\dohandleMPpath#1% + {\ifcase\lccode`#1\relax + \expandafter\dohandleMPpathA + \else + \expandafter\dohandleMPpathB + \fi#1} + +%\def\dohandleMPpathA#1 % +% {\setMPargument{#1}% +% \handleMPsequence} + +\let\dohandleMPpathA\setMPsequence + +% \def\dohandleMPpathB#1 % +% {\def\somestring{#1}% +% \ifx\somestring\PSlineto +% \setMPkeyword0 +% \else\ifx\somestring\PScurveto +% \setMPkeyword1 +% \else\ifx\somestring\PSrlineto +% \setMPkeyword2 +% \else\ifx\somestring\PSmoveto +% \setMPkeyword3 +% \else\ifx\somestring\PSclip +% % \chardef\finiMPpath0 % already +% \let\handleMPsequence\processMPpath +% \else\ifx\somestring\PSgsave +% \chardef\finiMPpath3 +% \else\ifx\somestring\PSgrestore +% \else\ifx\somestring\PSfill +% \ifcase\finiMPpath +% \chardef\finiMPpath2 +% \let\handleMPsequence\processMPpath +% \fi +% \else\ifx\somestring\PSstroke +% \ifcase\finiMPpath +% \chardef\finiMPpath1 +% \fi +% \let\handleMPsequence\processMPpath +% \else\ifx\somestring\PSclosepath +% \def\closeMPpath{\PDFcode{h}}% +% \else\ifx\somestring\PSconcat +% \cleanupMPconcat +% \let\flushMPpath\flushconcatMPpath +% \handleMPpathconcat +% \else\ifx\somestring\PSscale +% \let\flushMPpath\flushconcatMPpath +% \handleMPpathscale +% \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi +% \handleMPsequence} + +\def\installMPSkeywordP#1#2% + {\expandafter\def\csname\@@MP:P:#1\endcsname{#2}} + +\def\installMPSshortcutP#1#2% todo: \let + {\expandafter\let\csname\@@MP:P:#1\expandafter\endcsname\csname\@@MP:P:#2\endcsname} + +\def\dohandleMPpathB#1 % + {\def\somestring{#1}% + \ifcsname\@@MP:P:\somestring\endcsname + \csname\@@MP:P:\somestring\expandafter\endcsname + \fi + \handleMPsequence} + +\ifx\eTeXversion\undefined + \def\dohandleMPpathB#1 % + {\def\somestring{#1}% + \csname\@@MP:P:\somestring\endcsname + \handleMPsequence} +\fi + +\installMPSkeywordP \PSlineto + {\setMPkeyword0 } +\installMPSkeywordP \PScurveto + {\setMPkeyword1 } +\installMPSkeywordP \PSrlineto + {\setMPkeyword2 } +\installMPSkeywordP \PSmoveto + {\edef\lastMPmoveX{\gMPs1}% + \edef\lastMPmoveY{\gMPs2}% + \resetMPstack + \setMPkeyword3 } +\installMPSkeywordP \PSclip + {% \chardef\finiMPpath\zerocount % already + \let\handleMPsequence\processMPpath} +\installMPSkeywordP \PSgsave + {\chardef\finiMPpath3 } +\installMPSkeywordP \PSgrestore + {} +\installMPSkeywordP \PSfill + {\ifcase\finiMPpath + \chardef\finiMPpath2 + \let\handleMPsequence\processMPpath + \fi} +\installMPSkeywordP \PSstroke + {\ifcase\finiMPpath + \chardef\finiMPpath1 + \fi + \let\handleMPsequence\processMPpath} +\installMPSkeywordP \PSclosepath + {\def\closeMPpath{\PDFcode{h}}} +\installMPSkeywordP \PSconcat + {\cleanupMPconcat + \let\flushMPpath\flushconcatMPpath + \handleMPpathconcat} +\installMPSkeywordP \PSscale + {\let\flushMPpath\flushconcatMPpath + \handleMPpathscale} + +\installMPSshortcutP {l} \PSlineto +\installMPSshortcutP {r} \PSrlineto +\installMPSshortcutP {m} \PSmoveto +\installMPSshortcutP {c} \PScurveto + +\installMPSshortcutP {q} \PSgsave +\installMPSshortcutP {Q} \PSgrestore +\installMPSshortcutP {S} \PSstroke +\installMPSshortcutP {F} \PSfill +\installMPSshortcutP {B} \PSgsave +\installMPSshortcutP {W} \PSclip +\installMPSshortcutP {p} \PSclosepath + +\installMPSshortcutP {s} \PSscale +\installMPSshortcutP {t} \PSconcat + +%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=0 \fi + +\def\lastPDFMPobject{0} + +%D The additional code needed can be made available in the +%D (global) macro \type {\currentPDFresources}. + +\let\currentPDFresources\empty + +\newtoks\everyMPtoPDFconversion + +\def\convertMPtoPDF % #1#2#3% + {\bgroup + \defineMPtoPDFfallbacks + \ifx\pdfdecimaldigits\undefined\else \pdfdecimaldigits=5 \fi % new + \setbox\scratchbox\vbox\bgroup + \xdef\MPheight{0pt}% + \xdef\MPwidth {0pt}% + \forgetall + \offinterlineskip + \startMPresources + \doprocessMPtoPDFfile} % + +%D The next one is kind of private and probably will become obsolete): + +\def\processMPtoPDFfile % file xscale yscale + {\bgroup + \let\finishMPgraphic\egroup + \doprocessMPtoPDFfile} + +\let\setMPextensions\relax + +\def\doprocessMPtoPDFfile#1#2#3% file xscale yscale + {\setMPspecials + \setMPextensions + \the\everyMPtoPDFconversion + \catcode`\^^M=\@@endofline + \startMPscanning + \let\do\empty + \xdef\MPxscale{#2}% + \xdef\MPyscale{#3}% + \xdef\MPxoffset{0}% + \xdef\MPyoffset{0}% + \xdef\MPyshift{0pt}% + \donefalse + \let\handleMPsequence\dohandleMPsequence + \message{[MP to PDF]}% was: [MP to PDF #1] but there is a (#1) anyway + \input#1\relax} + +\def\PDFMPformoffset + {\ifx\objectoffset\undefined0pt\else\objectoffset\fi} + +\chardef\blackoutMPgraphic0 % in ConTeXt 1 + +\def\finishMPgraphic + {\stopMPresources + \egroup + \setbox\scratchbox\vbox + {\forgetall + \hbox + {\PDFcode{q \MPxscale\space 0 0 \MPyscale\space \MPxoffset\space \MPyoffset\space cm}% + \ifcase\blackoutMPgraphic\or\PDFcode{0 g 0 G}\fi + \lower\MPyshift\box\scratchbox % unscaled shift + \PDFcode{Q}}}% + \ht\scratchbox\MPheight + \wd\scratchbox\MPwidth + \dp\scratchbox0pt\relax + \dopackageMPgraphic\scratchbox + \egroup + \endinput} + +%D Alternative for \PDFTEX. We cannot come up with something more contexy +%D because this module is also used in \LATEX. + +\def\dopackageMPgraphic#1% #1 = boxregister + {%\ifx\pdfxform\undefined + % \chardef\makeMPintoPDFobject0 % no pdftex at all + %\else\ifx\pdftexversion\undefined + % \chardef\makeMPintoPDFobject0 % no pdftex at all + %\else\ifnum\pdftexversion<14 + % \chardef\makeMPintoPDFobject0 % no resource support + %\else + % % keep the default value + %\fi\fi\fi + \ifcase\makeMPintoPDFobject\or\or\ifx\currentPDFresources\empty\else + % an existing value of 2 signals object support (set elsewhere) + \chardef\makeMPintoPDFobject1 + \fi\fi + \ifcase\makeMPintoPDFobject + \box#1% + \or + \scratchdimen\PDFMPformoffset\relax + \ifdim\scratchdimen>0pt % 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>0pt % 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} +%D +%D Here are a few hooks for \CONTEXT\ specific things. + +\ifx\deleteMPgraphic\undefined + \def\deleteMPgraphic#1{} +\fi + +\ifx\startMPresources\undefined + \let\startMPresources\relax + \let\stopMPresources\relax +\fi + +%D \macros +%D {twodigitMPoutput} +%D +%D We can limit the precision to two digits after the comma +%D by saying: +%D +%D \starttyping +%D \twodigitMPoutput +%D \stoptyping +%D +%D This option only works in \CONTEXT\ combined with \ETEX. + +\def\twodigitMPoutput + {\let\!MP \twodigitrounding + \def\!MPgMPs##1{\twodigitrounding{\gMPs##1}}% + \def\!MPgMPa##1{\twodigitrounding{\gMPa##1}}} + +\let\!MP \empty +\let\!MPgMPa\gMPa +\let\!MPgMPs\gMPs + +%D This kind of conversion is possible because \METAPOST\ +%D does all the calculations. Converting other \POSTSCRIPT\ +%D files would drive both me and \TEX\ crazy. + +\protect \endinput diff --git a/tex/context/base/supp-pdf.tex b/tex/context/base/supp-pdf.tex new file mode 100644 index 000000000..2ae878067 --- /dev/null +++ b/tex/context/base/supp-pdf.tex @@ -0,0 +1 @@ +\input supp-pdf.mkii diff --git a/tex/context/base/supp-ran.lua b/tex/context/base/supp-ran.lua new file mode 100644 index 000000000..fe635fc7f --- /dev/null +++ b/tex/context/base/supp-ran.lua @@ -0,0 +1,67 @@ +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 random, randomseed, round, seed, last = math.random, math.randomseed, math.round, false, 1 +local texwrite = tex.write + +function math.setrandomseedi(n,comment) + if n <= 1 then + n = n*1073741823 -- maxcount + end + n = round(n) + if false then + logs.report("system","setting random seed to %s (%s)",n,comment or "normal") + end + randomseed(n) + last = random(0,1073741823) -- we need an initial value +end + +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.setrandomseedi(n) +end + +function commands.getrandomseed(n) + texwrite(last) +end + +-- maybe stack + +function commands.freezerandomseed(n) + -- print("<<<<",seed,last) + if seed == false or seed == nil then + seed = last + math.setrandomseedi(seed,"freeze",seed) + end + if n then + randomseed(n) + end +end + +function commands.defrostrandomseed() + -- print(">>>>",seed,last) + if seed ~= false then + math.setrandomseedi(seed,"defrost",seed) -- was last (bug) + 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..0c07099ed --- /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.mkii + +\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-spe.mkii b/tex/context/base/supp-spe.mkii new file mode 100644 index 000000000..8cb8e2ac1 --- /dev/null +++ b/tex/context/base/supp-spe.mkii @@ -0,0 +1,164 @@ +%D \module +%D [ file=supp-spe, +%D version=1997.07.05, +%D title=\CONTEXT\ Support Macros, +%D subtitle=Specials, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This module implements 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} + +\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 \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 \starttyping +%D \special{tag:arguments} +%D \stoptyping +%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 commands like: +%D +%D \startbuffer[tmp-1] +%D \redefinespecial a: \using#1\endspecial% +%D {let's execute special 'a:' using '#1'} +%D +%D \redefinespecial a \using#1\endspecial% +%D {let's execute special 'a' using '#1'} +%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. + +\def\@rds@{@rds@} + +\def\redefinespecial #1 {\setvalue{\@rds@#1}} + +%D \macros +%D {mimmickspecials} +%D +%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}. + +\def\mimmickspecials + {\let\special\domimmickspecial} + +%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. + +\def\domimmickspecial#1% + {\domimmickcolonspecial#1:\relax/:\relax/\end} + +\def\domimmickcolonspecial#1:#2#3:\relax/#4\end + {\ifx#2\relax + \domimmickspacespecial#1 \relax/ \relax/\end + \else + \dodomimmickspecial#1:\using#2#3\endspecial + \fi} + +\def\domimmickspacespecial#1 #2#3 \relax/#4\end + {\ifx#2\relax + \dodomimmickspecial#1\using\endspecial + \else + \dodomimmickspecial#1\using#2#3\endspecial + \fi} + +\def\dodomimmickspecial#1\using#2\endspecial + {\expandafter\ifx\csname\@rds@#1\endcsname\relax % \doifdefinedelse + \defaultspecial{#1 #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 previous definitions of tag~a. +%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 \typebuffer[tmp-2] +%D +%D Which results in: +%D +%D \startlines +%D \getbuffer[tmp-1] +%D \getbuffer[tmp-2] +%D \stoplines + +%D \macros +%D {mimmickspecial} +%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 +%D This can be handy when specials have much in common. + +\def\mimmickspecial #1 {\getvalue{\@rds@#1}} + +%D \macros +%D {normalspecial,defaultspecial} +%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 \starttyping +%D \def\defaultspecial#1{} +%D \stoptyping +%D +%D But here we default to idle. + +\let\normalspecial \special +\let\defaultspecial\special + +\protect \endinput diff --git a/tex/context/base/supp-tpi.mkii b/tex/context/base/supp-tpi.mkii new file mode 100644 index 000000000..9b2ac9328 --- /dev/null +++ b/tex/context/base/supp-tpi.mkii @@ -0,0 +1,353 @@ +%D \module +%D [ file=supp-tpi, +%D version=1997.07.05, +%D title=\CONTEXT\ Support Macros, +%D subtitle=\TPIC\ Conversion, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 modules implements the conversion of graphic \TPIC\ +%D specials using \METAPOST. +%D +%D We reimplement the \TPIC\ specials using the special +%D mimmicking mechanism implemented in the support module +%D \type{supp-spe} as well as the \METAPOST\ run||time support +%D implemented in \type{supp-mps}. + +\ifnum\texengine=\luatexengine + \endinput +\fi + +\ifx\undefined\writestatus \input supp-mis.mkii \relax \fi +\ifx\undefined\mimmickspecials \input supp-spe.mkii \relax \fi +\ifx\undefined\MPgraphicbox \input supp-mps.mkii \relax \fi +\ifx\undefined\dogetEPSboundingbox \input supp-eps.mkii \relax \fi + +\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. + +\unprotect + +%D When we want to mimmick \TPIC\ specials in \PDFTEX, we need +%D to map its graphic primitives into \PDF\ ones. The main +%D problem in doing so is that \PDF\ does not support b-splines +%D directly and also does not offer us something to draw arcs. +%D Of course all this scan be implemented in \TEX, and the +%D first implementation of this module did so, but the results +%D were not that satisfying. Not having used these specials +%D before, I had for instance to find out that the \TPIC\ +%D specials were not that unambiguesly defined. +%D +%D Then, while discussing something else, Sebastian Ratz told +%D me that the Web2c implementation that \PDFTEX\ is base upon, +%D offers some rather discutable, but nevertheless handy +%D feature: +%D +%D \starttyping +%D \write18{execute program with arguments} +%D \stoptyping +%D +%D Knowing this, I immediatelly decided to throw away the old +%D conversion macros and use the marvelous \METAPOST, \TEX\ +%D related, drawing program to do the conversion in as high a +%D quality as possible. +%D +%D implementation we're going to present here, not only uses +%D for drawing purposes, but also uses the more efficient +%D \METAPOST\ features to store the path. +%D +%D \in{Table}[tab:TPIC specials] lists the \TPIC\ specials as +%D mentioned in the \LATEX\ Graphics Companion and the +%D relevant part of the \DVIPS\ source. This list shows us +%D that we have to store the path before we can use it, simply +%D because we don't know in advance what actions to apply on +%D it. +%D +%D \placetable[here][tab:TPIC specials]{The \TPIC\ special syntax.} +%D \starttable[|||l|] +%D \HL +%D \NC \bf tag \NC \bf arguments \NC \bf meaning \NC\SR +%D \HL +%D \NC pn \NC $w$ \NC set linewidth \NC\FR +%D \NC pa \NC $x$ $y$ \NC add point to path \NC\MR +%D \NC fp \NC \NC draw/fill path \NC\MR +%D \NC ip \NC \NC fill path \NC\MR +%D \NC da \NC $l$ \NC draw dashed path \NC\MR +%D \NC dt \NC $l$ \NC draw doted path \NC\MR +%D \NC sp \NC $d$ \NC draw spline \NC\MR +%D \NC ar \NC $x$ $y$ $r_x$ $r_y$ $b$ $e$ \NC draw (partial) arc \NC\MR +%D \NC ia \NC $x$ $y$ $r_x$ $r_y$ $b$ $e$ \NC fill (partial) arc \NC\MR +%D \NC sh \NC $s$ \NC fill next path \NC\LR +%D \HL +%D \stoptable + +%D The first problem we have to take care of is the fact that +%D there is no decent begin or end of the drawing process +%D defined. We can however be quite sure that writers of +%D packages using these specials will put them into a box, +%D simply because else this is the most common used way to +%D treat something \TEX\ as as a whole, like: +%D +%D \starttyping +%D \hbox{\special{}\special{}...} +%D \stoptyping +%D +%D We just start a picture as soon as the first special is +%D encountered, so this becomes: +%D +%D \starttyping +%D \hbox{\openpicture\newspecial{}\newspecial{}... +%D \stoptyping + +%D The first step in opening the picture is to start a group. +%D Now we can savely use the egroup that closes the box to also +%D end the picture. + +% BETER: check for context and include mp-tool.mp + +\def\startTPICspecials + {\bgroup + \let\startTPICspecials\relax + \aftergroup\stopTPICspecials + \resetMPdrawing + \startMPdrawing + input mp-tool.mp; + pair p[]; + \stopMPdrawing} + +%D As soon as we begin a picture, we inhibit nesting by +%D relaxing the start macro. The first \METAPOST\ action we +%D take is declaring an array of pairs named $p$. + +%D Ending the picture is invoked by closing the current group. +%D Because the \TPIC\ picture comes out mirrored, we have to +%D reflect the current \METAPOST\ picture, stored in the system +%D variable {\it currentpicture}, around the $x$-axis. + +\def\stopTPICspecials + {\startMPdrawing + currentpicture:=currentpicture reflectedabout ((0,0),(4095,0)); + \stopMPdrawing + \MPdrawingdonetrue + \setbox\MPgraphicbox\hbox + {\getMPdrawing}% + \setbox\MPgraphicbox\hbox to \zeropoint + {\kern-\wd\MPgraphicbox + \vbox to \zeropoint{\box\MPgraphicbox\vss}\hss}% + \ht\MPgraphicbox\zeropoint + \wd\MPgraphicbox\zeropoint + \dp\MPgraphicbox\zeropoint + \box\MPgraphicbox + \egroup} + +%D Here the macro \type{\stopwritingMPgraphic} has to take care +%D of executing and including the \METAPOST\ code. + +%D We need to keep track of the number of elements that form +%D the path. This is needed because we don't know in advance +%D how the points are to be connected. + +\newcount\TPICcounter + +%D When a path is draw, we can connect the points using a +%D smooth curve of drawing straight lines. A closed path can be +%D drawn or filled. + +\newif\ifTPICdraw +\newif\ifTPICfill +\newif\ifTPICcurve + +%D The \TPIC\ specials permit specifying the line and fill +%D color as well as the linetype, which can be solid, dashed or +%D dotted. We'll save those specifications as a \METAPOST\ +%D string, using: + +\let\TPIClinetype =\empty +\let\TPICgrayscale=\empty + +%D The magic reduction factor $.07227$ is needed to map the +%D \TPIC\ $1/1000$ of an inch to \POSTSCRIPT\ points. We cannot +%D delegate this task to \METAPOST\ because this program does +%D not accept values greater than 4095. + +%D I won't discuss all the specifics used in implementing +%D the specials. The \METAPOST\ part is rather trivial. Many +%D specials have much in common, so the amout of code is not +%D that large. + +\redefinespecial pa \using#1 #2\endspecial + {\startTPICspecials + \bgroup + \global\advance\TPICcounter 1 + \dimen0=#1pt \dimen0=.07227\dimen0 + \dimen2=#2pt \dimen2=.07227\dimen2 + \startMPdrawing + p[\the\TPICcounter]:=(\the\dimen0,\the\dimen2); + \stopMPdrawing + \egroup} + +\redefinespecial pn \using#1\endspecial + {\startTPICspecials + \bgroup + \dimen0=#1pt \dimen0=.07227\dimen0 + \startMPdrawing + pickup pencircle scaled \the\dimen0; + \stopMPdrawing + \egroup} + +\redefinespecial sh \using#1\endspecial + {\startTPICspecials + \bgroup + \edef\g{#1}% + \edef\g{\ifx\g\empty.5\else#1\fi}% + \xdef\TPICgrayscale{withcolor (\g,\g,\g)}% + \egroup} + +\redefinespecial wh \using#1\endspecial + {\mimmickspecial sh \using0\endspecial} + +\redefinespecial bk \using#1\endspecial + {\mimmickspecial sh \using1\endspecial} + +\redefinespecial da \using#1\endspecial + {\startTPICspecials + \bgroup + \edef\l{#1}% + \ifx\l\empty + \gdef\TPIClinetype{dashed evenly}% + \else + \dimen0=#1in + \ifdim\dimen0<\!!zeropoint \dimen0=-\dimen0\fi + \edef\f{\the\dimen0 \space}% + \dimen0=.5\dimen0 + \edef\h{\the\dimen0 \space}% + \xdef\TPIClinetype{dashed dashpattern (on \h off \f on \h)}% + \fi + \egroup + \TPICcurvefalse\TPICdrawtrue + \drawTPICpath\using#1\endspecial} + +\redefinespecial dt \using#1\endspecial + {\startTPICspecials + \bgroup + \edef\l{#1}% + \xdef\TPIClinetype{dashed withdots \ifx\l\empty\else scaled #1in\fi}% + \egroup + \TPICcurvefalse\TPICdrawtrue + \drawTPICpath\using#1\endspecial} + +\redefinespecial fp \using#1\endspecial + {\startTPICspecials + \TPICcurvefalse\TPICdrawtrue + \ifdim0#1pt=\!!zeropoint + \drawTPICpath\using#1\endspecial + \else\ifdim0#1pt<\!!zeropoint + \mimmickspecial dt\using#1\endspecial + \else + \mimmickspecial da\using#1\endspecial + \fi\fi} + +\redefinespecial sp + {\startTPICspecials\TPICdrawtrue\TPICcurvetrue\drawTPICpath} + +\redefinespecial ip + {\startTPICspecials\TPICfilltrue\drawTPICpath} + +\redefinespecial ar + {\startTPICspecials\TPICdrawtrue\drawTPICarc} + +\redefinespecial ia + {\startTPICspecials\TPICfilltrue\drawTPICarc} + +%D These substitutes use two auxiliary macros that take care of +%D actually drawing the shape or arc. Here we use the stored +%D linetype (solid, dashed, dotted) and color (grayscale). + +\def\drawTPICpath\using#1\endspecial + {\bgroup + \ifTPICdraw + \def\TPICgrayscale{}% + \fi + \startMPdrawing + \ifTPICfill fill\fi\ifTPICdraw draw\fi\space + for i:=1 upto \the\TPICcounter-1: + p[i]\ifTPICcurve..\else--\fi + endfor + p[\the\TPICcounter] + \ifTPICfill\ifTPICcurve..\else--\fi cycle \fi + \TPIClinetype\space\TPICgrayscale; + \stopMPdrawing + \resetTPICvariables + \egroup} + +%D I have to admit that at the moment I wrote this macro, I +%D could not write this piece of \METAPOST. Fortunately +%D Thortsen Ohl promptly answered the question I posted to the +%D \METAFONT\ discussion list. + +\def\drawTPICarc\using#1 #2 #3 #4 #5 #6\endspecial + {\bgroup + \ifTPICdraw + \def\TPICgrayscale{}% + \fi + \dimen 0=#1pt\dimen 0=.07227\dimen 0 + \dimen 2=#2pt\dimen 2=.07227\dimen 2 + \dimen10=#3pt\dimen10=.14454\dimen10 + \dimen12=#4pt\dimen12=.14454\dimen12 + \dimen20=#5pt + \dimen22=#6pt + \startMPdrawing + \ifTPICfill fill\fi\ifTPICdraw draw\fi \space + \ifTPICfill\else subpath 4/3.14159*(\the\dimen20,\the\dimen22) of \fi + fullcircle xscaled \the\dimen10 \space yscaled \the\dimen12 \space + shifted (\the\dimen0,\the\dimen2) + \TPIClinetype \space \TPICgrayscale; + \stopMPdrawing + \resetTPICvariables + \egroup} + +%D Resetting the variables need to be done globally because we +%D cannot be sure if any further grouping is used by the +%D envelopping macros. + +\def\resetTPICvariables + {\global\TPICcounter\zerocount + \global\TPICfillfalse + \global\TPICdrawfalse + \global\let\TPIClinetype\empty + \global\let\TPICgrayscale\empty} + +%D I have to admit that by using the \METAPOST\ B‚zier cubics +%D routines these implementation does produce better curves +%D then most \DVI\ drivers do using the \TPIC\ prescribed +%D b-splines. Take for instance the sequence: +%D +%D \starttyping +%D \special{pa 2000 1000} +%D \special{pa 1000 2000} +%D \special{pa 0000 1000} +%D \special{pa 1000 0000} +%D \special{pa 2000 1000} +%D \special{sp} +%D \stoptyping +%D +%D One would expect that this code produced a closed circle, +%D but the curve that comes out using b-splines is far from +%D round. We can however savely asume that the arc producing +%D specials will be used for drawing circle fragments, while +%D the path specials will be used for arbitraty curves. And for +%D b-splines to produce nice curves, one will often use many +%D points to get the desired results. Therefore, using the +%D \METAPOST\ B‚zier curves will certainly produce similar and +%D even better graphics, except in those rare cases where one +%D uses delinberately the not that accurate features of +%D b-splines. Hereby the user is warned. + +\protect \endinput diff --git a/tex/context/base/supp-vis.tex b/tex/context/base/supp-vis.tex new file mode 100644 index 000000000..f38c8e1e3 --- /dev/null +++ b/tex/context/base/supp-vis.tex @@ -0,0 +1,1907 @@ +%D \module +%D [ file=supp-vis, +%D version=1996.10.21, +%D title=\CONTEXT\ Support Macros, +%D subtitle=Visualization, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% no longer generic, who cares ... + +%D \gdef\ShowBufferedExample% private typeseting macro +%D {\startlinecorrection +%D \bgroup +%D \setuptyping[margin=0pt,option=color] +%D \showmakeup +%D \centeredvcuetrue +%D \dontinterfere +%D \baselinerulefalse +%D \normalvbox +%D {\normalhbox to \hsize +%D {$\hsize=.5\hsize +%D \advance\hsize by -.5em +%D \normalvcenter{\vbox{\getbuffer}}\normalhss +%D \normalvcenter{\vbox{\dontshowcomposition\typebuffer}}$}} +%D \egroup +%D \stoplinecorrection} +%D +%D \gdef\ShowBufferedExampleBox% private typeseting macro +%D {\startlinecorrection +%D \bgroup +%D \setuptyping[margin=0pt,option=color] +%D \showmakeup +%D \centeredvcuetrue +%D \dontinterfere +%D \baselinerulefalse +%D \normalvbox +%D {\normalhbox to \hsize +%D {$\hsize=.5\hsize +%D \advance\hsize by -.5em +%D \normalvcenter{\baselineruletrue\vbox{\getbuffer}}\normalhss +%D \normalvcenter{\vbox{\dontshowcomposition\typebuffer}}$}} +%D \egroup +%D \stoplinecorrection} + +%D Although an integral part of \CONTEXT, this module is one +%D of the support modules. Its stand alone character permits +%D use in \PLAIN\ \TEX\ or \TEX\ based macropackages. +%D \ifCONTEXT \else If in some examples the verbatim listings +%D don't show up nice, this is due to processing by a system +%D that does not support buffering. In \CONTEXT\ we show the +%D commands in the margin, use bit more advanced way of +%D numbering, and typeset the source in \TEX nicolored +%D verbatim. Sorry for this inconvenience.\fi +%D +%D Depending on my personal needs and those of whoever uses it, +%D the macros will be improved in terms of visualization, +%D efficiency and compatibility. These rather low level +%D visualization macros are supplemented by ones that can +%D visualize baselines, the page layout and whatever deserves +%D attention. Most of those macros can be found in \type +%D {core-vis} and other core modules. Their integration in +%D \CONTEXT\ prohibits generic applications. + +\ifx \undefined \writestatus \input supp-mis.tex \fi + +%D One of the strong points of \TEX\ is abstraction of textual +%D input. When macros are defined well and do what we +%D want them to do, we will seldom need the tools present in +%D What You See Is What You Get systems. For instance, when +%D entering text we don't need rulers, because no manual +%D shifting and/or alignment of text is needed. On the other +%D hand, when we are designing macros or specifying layout +%D elements, some insight in \TEX's advanced spacing, kerning, +%D filling, boxing and punishment abilities will be handy. +%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} + +%D In this module we are going to redefine some \TEX\ +%D primitives and \PLAIN\ macro's. Their original meaning is +%D saved in macros with corresponding names, preceded by +%D \type{normal}. These original macros are (1)~used to +%D temporary restore the old values when needed and +%D (2)~used to prevent recursive calls in the macros that +%D replace them. + +\unprotect + +\let\visualvrule\vrule +\let\visualhrule\hrule + +%D \macros +%D {dontinterfere} +%D +%D Indentation, left and/or right skips, redefinition of +%D \type{\par} and assignments to \type{\everypar} can lead to +%D unwanted results. We can therefore turn all those things +%D off with \type{\dontinterfere}. + +\def\dontinterfere + {\everypar \emptytoks + \let\par \endgraf + \parindent\zeropoint + \parskip \zeropoint + \leftskip \zeropoint + \rightskip\zeropoint + \relax} + +%D \macros +%D {dontcomplain} +%D +%D In this module we do a lot of box manipulations. Because we +%D don't want to be confronted with to many over- and underfull +%D messages we introduce \type{\dontcomplain}. + +\def\dontcomplain + {\hbadness\!!tenthousand \vbadness\hbadness + \hfuzz \maxdimen \vfuzz \hfuzz} + +% This obsolete dutch name is sometimes uses in manual styles; when +% cleaning up the codebase I decided to move this definition here. + +\let\mindermeldingen\dontcomplain + +%D \macros +%D {normaloffinterlineskip} +%D +%D The next hack is needed because in \CONTEXT\ we redefine +%D \type{\offinterlineskip}. + +\ifx\undefined\normaloffinterlineskip + \let\normaloffinterlineskip\offinterlineskip +\fi + +%D \macros +%D {normalhbox, +%D normalvbox,normalvtop} +%D +%D There are three types of boxes, one horizontal and two +%D vertical in nature. As we will see later on, all three types +%D are to be handled according to their orientation and +%D baseline behavior. Especially \type{\vtop}'s need our +%D special attention. + +% already saved + +%D \macros +%D {normalhskip, +%D normalvskip} +%D +%D Next come the flexible skips, which come in two flavors +%D too. Like boxes these are handled with \TEX\ primitives. + +% already saved + +%D \macros +%D {normalpenalty, +%D normalkern} +%D +%D Both penalties and kerns are taken care of by mode sensitive +%D primitives. This means that when making them visible, we +%D have to take the current mode into account. + +% already saved + +%D \macros +%D {normalhglue, +%D normalvglue} +%D +%D Glues on the other hand are macro's defined in \PLAIN\ \TEX. +%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 + +%D \macros +%D {normalmkern, +%D normalmskip} +%D +%D Math mode has its own spacing primitives, preceded by +%D \type{m}. Due to the relation with the current font and the +%D way math is typeset, their unit \type{mu} is not compatible +%D with other dimensions. As a result, the visual appearance +%D of these primitives is kept primitive too. + +% already saved + +%D \macros +%D {hfilneg, +%D vfilneg} +%D +%D Fills can be made visible quite easy. We only need some +%D additional negation macros. Because \PLAIN\ \TEX\ only +%D offers \type{\hfilneg} and \type{\vfilneg}, we define our +%D own alternative double \type{ll}'ed ones. + +\def\hfilneg {\normalhskip\zeropoint \!!plus-1fil\relax} +\def\vfilneg {\normalvskip\zeropoint \!!plus-1fil\relax} +\def\hfillneg {\normalhskip\zeropoint \!!plus-1fill\relax} +\def\vfillneg {\normalvskip\zeropoint \!!plus-1fill\relax} +\def\hfilllneg{\normalhskip\zeropoint \!!plus-1filll\relax} +\def\vfilllneg{\normalvskip\zeropoint \!!plus-1filll\relax} + +%D \macros +%D {normalhss,normalhfil,normalhfill, +%D normalvss,normalvfil,normalvfill} +%D +%D The positive stretch primitives are used independant and in +%D combination with \type{\leaders}. + +% already saved + +%D \macros +%D {normalhfilneg,normalhfillneg, +%D normalvfilneg,normalvfillneg} +%D +%D Keep in mind that both \type{\hfillneg} and \type{\vfillneg} +%D are not part of \PLAIN\ \TEX\ and therefore not documented +%D in standard \TEX\ documentation. They can nevertheless be +%D used at will. + +\let\normalhfillneg = \hfillneg +\let\normalvfillneg = \vfillneg + +%D Visualization is not always wanted. Instead of turning this +%D option off in those (unpredictable) situations, we just +%D redefine a few \PLAIN\ macros. + +\ifx\tlap\undefined + + \def\rlap#1{\normalhbox to \zeropoint{#1\normalhss}} + \def\llap#1{\normalhbox to \zeropoint{\normalhss#1}} + \def\blap#1{\normalvbox to \zeropoint{#1\normalvss}} + \def\tlap#1{\normalvbox to \zeropoint{\normalvss#1}} + +\fi + +\ifx\contextversion\undefined \def~{\normalpenalty\!!tenthousand\ } \fi + +%D \macros +%D {makeruledbox} +%D +%D Ruled boxes can be typeset is many ways. Here we present +%D just one alternative. This implementation may be a little +%D complicated, but it supports all three kind of boxes. The +%D next command expects a \BOX\ specification, like: +%D +%D \starttyping +%D \makeruledbox0 +%D \stoptyping + +%D \macros +%D {baselinerule,baselinefill} +%D +%D We can make the baseline of a box visible, both dashed and +%D as a rule. The line is drawn on top of the baseline. All +%D we have to say is: +%D +%D \starttyping +%D \baselineruletrue +%D \baselinefilltrue +%D \stoptyping +%D +%D At the cost of some overhead these alternatives are +%D implemented using \type{\if}'s: + +\newif\ifbaselinerule \baselineruletrue +\newif\ifbaselinefill \baselinefillfalse + +%D \macros +%D {iftoprule,ifbottomrule,ifleftrule,ifrightrule} +%D +%D Rules can be turned on and off, but by default we have: +%D +%D \starttyping +%D \topruletrue +%D \bottomruletrue +%D \leftruletrue +%D \rightruletrue +%D \stoptyping +%D +%D As we see below: + +\newif\iftoprule \topruletrue +\newif\ifbottomrule \bottomruletrue +\newif\ifleftrule \leftruletrue +\newif\ifrightrule \rightruletrue + +%D \macros +%D {boxrulewidth} +%D +%D The width in the surrounding rules can be specified by +%D assigning an apropriate value to the dimension used. This +%D module defaults the width to: +%D +%D \starttyping +%D \boxrulewidth=.2pt +%D \stoptyping +%D +%D Although we are already low on \DIMENSIONS\ it's best to +%D spend one here, mainly because it enables easy manipulation, +%D like multiplication by a given factor. + +\newdimen\boxrulewidth \boxrulewidth=.2pt + +%D The core macro \type{\makeruledbox} looks a bit hefty. The +%D manipulation at the end is needed because we want to +%D preserve both the mode and the baseline. This means that +%D \type{\vtop}'s and \type{\vbox}'es behave the way we expect +%D them to do. +%D +%D \startlinecorrection +%D \hbox +%D {\ruledhbox to 5em{\strut test\normalhss}\hskip1em +%D \ruledvbox{\hsize 5em\strut test \par test\strut}\hskip1em +%D \ruledvtop{\hsize 5em\strut test \par test\strut}} +%D \stoplinecorrection +%D +%D The \type{\cleaders} part of the macro is responsible for +%D the visual baseline. The \type{\normalhfill} belongs to this +%D primitive too. By storing and restoring the height and depth +%D of box \type{#1}, we preserve the mode. + +\let\dowithruledbox\relax + +\let\ruledheight\!!zeropoint +\let\ruleddepth \!!zeropoint +\let\ruledwidth \!!zeropoint + +\def\makeruledbox#1% + {\edef\ruledheight{\the\ht#1}% + \edef\ruleddepth {\the\dp#1}% + \edef\ruledwidth {\the\wd#1}% + \setbox\scratchbox\normalvbox + {\dontcomplain + \normaloffinterlineskip + \visualhrule + \!!height\boxrulewidth + \iftoprule\else\!!width\zeropoint\fi + \normalvskip-\boxrulewidth + \normalhbox to \ruledwidth + {\visualvrule + \!!height\ruledheight + \!!depth\ruleddepth + \!!width\ifleftrule\else0\fi\boxrulewidth + \ifdim\ruledheight>\zeropoint \else \baselinerulefalse \fi + \ifdim\ruleddepth>\zeropoint \else \baselinerulefalse \fi + \ifbaselinerule + \ifdim\ruledwidth<20\boxrulewidth + \baselinefilltrue + \fi + \cleaders + \ifbaselinefill + \visualhrule + \!!height\boxrulewidth + \else + \normalhbox + {\normalhskip2.5\boxrulewidth + \visualvrule + \!!height\boxrulewidth + \!!width5\boxrulewidth + \normalhskip2.5\boxrulewidth}% + \fi + \fi + \normalhfill + \visualvrule + \!!width\ifrightrule\else0\fi\boxrulewidth}% + \normalvskip-\boxrulewidth + \visualhrule + \!!height\boxrulewidth + \ifbottomrule\else\!!width\zeropoint\fi}% + \wd#1\zeropoint + \setbox#1=\ifhbox#1\normalhbox\else\normalvbox\fi + {\normalhbox + {\box#1% + \lower\ruleddepth\normalhbox{\dowithruledbox{\box\scratchbox}}}}% + \ht#1=\ruledheight + \wd#1=\ruledwidth + \dp#1=\ruleddepth} + +%D Just in case one didn't notice: the rules are in fact layed +%D over the box. This way the contents of a box cannot +%D visually interfere with the rules around (upon) it. A more +%D advanced version of ruled boxes can be found in one of the +%D core modules of \CONTEXT. There we take offsets, color, +%D rounded corners, backgrounds and alignment into account too. + +%D \macros +%D {ruledhbox, +%D ruledvbox,ruledvtop, +%D ruledvcenter} +%D +%D These macro's can be used instead of \type{\hbox}, +%D \type{\vbox}, \type{\vtop} and, when in math mode, +%D \type{\vcenter}. They just do what their names state. Using +%D an auxiliary macro would save us a few words of memory, but +%D it would make their appearance even more obscure. +%D +%D \startbuffer +%D \hbox +%D {\strut +%D one +%D two +%D \hbox{three} +%D four +%D five} +%D \stopbuffer +%D +%D \ShowBufferedExampleBox + +\unexpanded\def\ruledhbox + {\normalhbox\bgroup + \dowithnextbox{\makeruledbox\nextbox\box\nextbox\egroup}% + \normalhbox} + +%D \startbuffer +%D \vbox +%D {\strut +%D first line \par +%D second line \par +%D third line \par +%D fourth line \par +%D fifth line +%D \strut } +%D \stopbuffer +%D +%D \ShowBufferedExampleBox + +\unexpanded\def\ruledvbox + {\normalvbox\bgroup + \dowithnextbox{\makeruledbox\nextbox\box\nextbox\egroup}% + \normalvbox} + +%D \startbuffer +%D \vtop +%D {\strut +%D first line \par +%D second line \par +%D third line \par +%D fourth line \par +%D fifth line +%D \strut } +%D \stopbuffer +%D +%D \ShowBufferedExampleBox + +\unexpanded\def\ruledvtop + {\normalvtop\bgroup + \dowithnextbox{\makeruledbox\nextbox\box\nextbox\egroup}% + \normalvtop} + +%D \startbuffer +%D \hbox +%D {$\vcenter{\hsize.2\hsize +%D alfa \par beta}$ +%D $\vcenter to 3cm{\hsize.2\hsize +%D alfa \par beta \par gamma}$ +%D $\vcenter{\hsize.2\hsize +%D alfa \par beta}$} +%D \stopbuffer +%D +%D \ShowBufferedExampleBox + +\unexpanded\def\ruledvcenter + {\normalvbox\bgroup + \dontinterfere + \dowithnextbox + {\scratchdimen.5\ht\nextbox + \advance\scratchdimen .5\dp\nextbox + \ht\nextbox\scratchdimen + \dp\nextbox\scratchdimen + \ruledhbox{\box\nextbox}% + \egroup}% + \normalvbox} + +%D \macros +%D {ruledbox, +%D setruledbox} +%D +%D Of the next two macros the first can be used to precede a +%D box of ones own choice. One can for instance prefix boxes +%D with \type{\ruledbox} and afterwards --- when the macro +%D satisfy the needs --- let it to \type{\relax}. +%D +%D \starttyping +%D \ruledbox\hbox{What rules do you mean?} +%D \stoptyping +%D +%D The macro \type{\setruledbox} can be used to directly +%D rule a box. +%D +%D \starttyping +%D \setruledbox12=\hbox{Who's talking about rules here?} +%D \stoptyping +%D +%D At the cost of some extra macros we can implement a +%D variant that does not need the~\type{=}, but we stick to: + +\unexpanded\def\ruledbox + {\dowithnextbox{\makeruledbox\nextbox\box\nextbox}} + +\def\setruledbox#1=% + {\dowithnextbox{\makeruledbox\nextbox\setbox#1\nextbox}} + +%D \macros +%D {investigateskip, +%D investigatecount, +%D investigatemuskip} +%D +%D Before we meet the visualizing macro's, we first implement +%D ourselves some handy utility ones. Just for the sake of +%D efficiency and readability, we introduce some status +%D variables, that tell us a bit more about the registers we +%D use: +%D +%D \starttyping +%D \ifflexible +%D \ifzero +%D \ifnegative +%D \ifpositive +%D \stoptyping +%D +%D These status variables are set when we call for one of the +%D investigation macros, e.g. +%D +%D \starttyping +%D \investigateskip\scratchskip +%D \stoptyping +%D +%D We use some dirty trick to check stretchability of \SKIPS. +%D Users of these macros are invited to study their exact +%D behavior first. The positive and negative states both +%D include zero and are in fact non-negative ($\geq0$) and +%D non-positive ($\leq0$) . + +\newif\ifflexible +\newif\ifzero +\newif\ifnegative +\newif\ifpositive + +\def\investigateskip#1% + {\relax + \scratchdimen#1\relax + \edef\!!stringa{\the\scratchdimen}% + \edef\!!stringb{\the#1}% + \ifx\!!stringa\!!stringb \flexiblefalse \else \flexibletrue \fi + \ifdim#1=\zeropoint\relax + \zerotrue \else + \zerofalse \fi + \ifdim#1<\zeropoint\relax + \positivefalse \else + \positivetrue \fi + \ifdim#1>\zeropoint\relax + \negativefalse \else + \negativetrue \fi} + +% etex +% +% \def\investigateskip#1% +% {\relax +% \ifdim\scratchskip=\zeropoint +% \ifdim\gluestretch\scratchskip=\zeropoint +% \ifdim\glueshrink\scratchskip=\zeropoint +% \flexiblefalse +% \else +% \flexibletrue +% \fi +% \else +% \flexibletrue +% \fi +% \else +% \flexibletrue +% \fi +% \ifdim#1=\zeropoint\relax +% \zerotrue \else +% \zerofalse \fi +% \ifdim#1<\zeropoint\relax +% \positivefalse \else +% \positivetrue \fi +% \ifdim#1>\zeropoint\relax +% \negativefalse \else +% \negativetrue \fi} + +\def\investigatecount#1% + {\relax + \flexiblefalse + \ifnum#1=\zerocount + \zerotrue \else + \zerofalse \fi + \ifnum#1<\zerocount + \positivefalse \else + \positivetrue \fi + \ifnum#1>\zerocount + \negativefalse \else + \negativetrue \fi} + +\def\investigatemuskip#1% + {\relax + \edef\!!stringa{\the\scratchmuskip}% + \edef\!!stringb{0mu}% + \def\!!stringc##1##2\\{##1}% + \expandafter\edef\expandafter\!!stringc\expandafter + {\expandafter\!!stringc\!!stringa\\}% + \edef\!!stringd{-}% + \flexiblefalse + \ifx\!!stringa\!!stringb + \zerotrue + \negativefalse + \positivefalse + \else + \zerofalse + \ifx\!!stringc\!!stringd + \positivefalse + \negativetrue + \else + \positivetrue + \negativefalse + \fi + \fi} + +%D Now the neccessary utility macros are defined, we can make a +%D start with the visualizing ones. The implementation of these +%D macros is a compromise between readability, efficiency of +%D coding and processing speed. Sometimes we do in steps what +%D could have been done in combination, sometimes we use a few +%D boxes more or less then actually needed, and more than once +%D one can find the same piece of rule drawing code twice. + +%D \macros +%D {ifcenteredvcue,normalvcue} +%D +%D Depending on the context, one can force visual vertical cues +%D being centered along \type{\hsize} or being put at the +%D current position. Although centering often looks better, +%D we've chosen the second alternative as default. The main +%D reason for doing so is that often when we don't set the +%D \type{\hsize} ourselves, \TEX\ takes the value of the +%D surrounding box. As a result the visual cues can migrate +%D outside the current context. +%D +%D This behavior is accomplished by a small but effective +%D auxiliary macro, which behavior can be influenced by the +%D boolean \type{\centeredvcue}. By saying +%D +%D \starttyping +%D \centeredvcuetrue +%D \stoptyping +%D +%D one turns centering on. As said, we turn it off. + +\newif\ifcenteredvcue \centeredvcuefalse + +\def\normalvcue#1% + {\normalhbox \ifcenteredvcue to \hsize \fi {\normalhss#1\normalhss}} + +%D We could have used the more robust version +%D +%D \starttyping +%D \def\normalvcue% +%D {\normalhbox \ifcenteredvcue to \hsize \fi +%D \bgroup\bgroup\normalhss +%D \aftergroup\normalhss\aftergroup\egroup +%D \let\next=} +%D \stoptyping +%D +%D or the probably best one: +%D +%D \starttyping +%D \def\normalvcue% +%D {\hbox \ifcenteredvcue to \hsize +%D \bgroup\bgroup\normalhss +%D \aftergroup\normalhss\aftergroup\egroup +%D \else +%D \bgroup +%D \fi +%D \let\next=} +%D \stoptyping +%D +%D Because we don't have to preserve \CATCODES\ and only use +%D small arguments, we stick to the first alternative. + +%D \macros +%D {testrulewidth} +%D +%D We build our visual cues out of rules. At the cost of a much +%D bigger \DVI\ file, this is to be prefered over using +%D characters (1)~because we cannot be sure of their +%D availability and (2)~because their dimensions are fixed. +%D +%D As with ruled boxes, we use a \DIMENSION\ to specify the +%D width of the ruled elements. This dimension defaults to: +%D +%D \starttyping +%D \testrulewidth=\boxrulewidth +%D \stoptyping +%D +%D Because we prefer whole numbers for specifying the +%D dimensions, we often use even multiples of +%D \type{\testrulewidth}. + +%D \macros +%D {visiblestretch} +%D +%D A second variable is introduced because of the stretch +%D components of \SKIPS. At the cost of some accuracy we can +%D make this stretch visible. +%D +%D \starttyping +%D \visiblestretchtrue +%D \stoptyping + +\newdimen\testrulewidth \testrulewidth=\boxrulewidth +\newif\ifvisiblestretch \visiblestretchfalse + +%D \macros +%D {ruledhss, +%D ruledhfil,ruledhfilneg, +%D ruledhfill,ruledhfillneg} +%D +%D We start with the easiest part, the fills. The scheme we +%D follow is {\em visual filling -- going back -- normal +%D filling}. Visualizing is implemented using \type{\cleaders}. +%D Because the \BOX\ that follows this command is constructed +%D only once, the \type{\copy} is not really a prerequisite. We +%D prefer using a \type{\normalhbox} here instead of a +%D \type{\hbox}. + +\def\setvisiblehfilbox#1\to#2#3#4% + {\setbox#1\normalhbox + {\visualvrule + \!!width #2\testrulewidth + \!!height#3\testrulewidth + \!!depth #4\testrulewidth}% + \smashbox#1} + +\def\doruledhfiller#1#2#3#4% + {#1#2% + \bgroup + \dontinterfere + \dontcomplain + \setvisiblehfilbox0\to{4}{#3}{#4}% + \setvisiblehfilbox2\to422% + \copy0\copy2 + \bgroup + \setvisiblehfilbox0\to422% + \cleaders + \normalhbox to 12\testrulewidth + {\normalhss\copy0\normalhss}% + #1% + \egroup + \setbox0\normalhbox + {\normalhskip-4\testrulewidth\copy0\copy2}% + \smashbox0% + \box0 + \egroup} + +%D The horizontal fillers differ in their boundary +%D visualization. Watch the small dots. Fillers can be +%D combined within reasonable margins. +%D +%D \startlinecorrection +%D \baselinerulefalse +%D \ruledhbox to \hsize +%D {\strut\type{\hss}\ruledhss test} +%D \stoplinecorrection +%D +%D \startlinecorrection +%D \baselinerulefalse +%D \ruledhbox to \hsize +%D {\strut\type{\hfil}\ruledhfil test} +%D \stoplinecorrection +%D +%D \startlinecorrection +%D \baselinerulefalse +%D \ruledhbox to \hsize +%D {\strut\type{\hfill}\ruledhfill test} +%D \stoplinecorrection +%D +%D \startlinecorrection +%D \baselinerulefalse +%D \ruledhbox to \hsize +%D {\strut +%D \type{\hfil}\type{\hfil}\ruledhfil\ruledhfil +%D test% +%D \ruledhfil\type{\hfil}} +%D \stoplinecorrection +%D +%D The negative counterparts are visualizes, but seldom +%D become visible, apart from their boundaries. +%D +%D \startlinecorrection +%D \baselinerulefalse +%D \ruledhbox to \hsize +%D {\strut\type{\hfilneg}\ruledhfilneg test} +%D \stoplinecorrection +%D +%D \startlinecorrection +%D \baselinerulefalse +%D \ruledhbox to \hsize +%D {\strut\type{\hfillneg}\ruledhfillneg test} +%D \stoplinecorrection +%D +%D Although leaders are used for visualizing, they are +%D visualized themselves correctly as the next example shows. +%D +%D \startlinecorrection +%D \baselinerulefalse +%D \ruledhbox to \hsize +%D {\strut\cleaders\normalhbox to 2em{\normalhss$\circ$\normalhss}\ruledhfill} +%D \stoplinecorrection +%D +%D All five substitutions use the same auxiliary macro. Watch +%D the positive first -- negative next approach. + +\unexpanded\def\ruledhss + {\doruledhfiller\normalhss\normalhfilneg{0}{0}} + +\unexpanded\def\ruledhfil + {\doruledhfiller\normalhfil\normalhfilneg{10}{-6}} + +\unexpanded\def\ruledhfill + {\doruledhfiller\normalhfill\normalhfillneg{18}{-14}} + +\unexpanded\def\ruledhfilneg + {\doruledhfiller\normalhfilneg\normalhfil{-6}{10}} + +\unexpanded\def\ruledhfillneg + {\doruledhfiller\normalhfillneg\normalhfill{-14}{18}} + +%D \macros +%D {ruledvss, +%D ruledvfil,ruledvfilneg, +%D ruledvfill,ruledvfillneg} +%D +%D The vertical mode commands adopt the same visualization +%D scheme, but are implemented in a slightly different way. + +\def\setvisiblevfilbox#1\to#2#3#4% + {\setbox#1\normalhbox + {\visualvrule + \!!width #2\testrulewidth + \!!height#3\testrulewidth + \!!depth #4\testrulewidth}% + \smashbox#1}% + +\def\doruledvfiller#1#2#3% + {#1#2% + \bgroup + \dontinterfere + \dontcomplain + \normaloffinterlineskip + \setvisiblevfilbox0\to422% + \setbox2\normalvcue + {\normalhskip -#3\testrulewidth\copy0}% + \smashbox2% + \copy2 + \bgroup + \setbox2\normalvcue + {\normalhskip -2\testrulewidth\copy0}% + \smashbox2% + \copy2 + \cleaders + \normalvbox to 12\testrulewidth + {\normalvss\copy2\normalvss}% + #1% + \setbox2\normalvbox + {\normalvskip-2\testrulewidth\copy2}% + \smashbox2% + \box2 + \egroup + \box2 + \egroup} + +%D Because they act the same as their horizontal counterparts +%D we only show a few examples. +%D +%D \startlinecorrection +%D \hbox to \hsize +%D {\dontinterfere +%D \baselinerulefalse +%D \centeredvcuetrue +%D \ruledvbox to 10ex +%D {\hsize.18\hsize +%D \type{\vss}\ruledvss last line}\normalhss +%D \ruledvbox to 10ex +%D {\hsize.18\hsize +%D \type{\vfil}\ruledvfil last line}\normalhss +%D \ruledvbox to 10ex +%D {\hsize.18\hsize +%D \type{\vfill}\ruledvfill last line}\normalhss +%D \ruledvbox to 10ex +%D {\hsize.18\hsize +%D \type{\vfilneg}\ruledvfilneg last line}\normalhss +%D \ruledvbox to 10ex +%D {\hsize.18\hsize +%D \type{\vfillneg}\ruledvfillneg last line}} +%D \stoplinecorrection +%D +%D Keep in mind that \type{\vfillneg} is not part of \PLAIN\ +%D \TEX, but are mimmicked by a macro. + +\unexpanded\def\ruledvss {\doruledvfiller\normalvss \normalvfilneg {2}} +\unexpanded\def\ruledvfil {\doruledvfiller\normalvfil \normalvfilneg {-4}} +\unexpanded\def\ruledvfill {\doruledvfiller\normalvfill \normalvfillneg{-12}} +\unexpanded\def\ruledvfilneg {\doruledvfiller\normalvfilneg \normalvfil {8}} +\unexpanded\def\ruledvfillneg{\doruledvfiller\normalvfillneg\normalvfill {16}} + +%D \macros +%D {ruledhskip} +%D +%D Skips differ from kerns in two important aspects: +%D +%D \startitemize[packed] +%D \item line and pagebreaks are allowed at a skip +%D \item skips can have a positive and/or negative +%D stretchcomponent +%D \stopitemize +%D +%D Stated a bit different: kerns are fixed skips at which no +%D line or pagebreak can occur. Because skips have a more open +%D character, they are visualized in a open way. +%D +%D \startbuffer +%D one +%D \hskip +30pt plus 5pt +%D two +%D \hskip +30pt +%D \hskip -10pt plus 5pt +%D three +%D \hskip 0pt +%D four +%D \hskip +30pt +%D five +%D \stopbuffer +%D +%D \ShowBufferedExample +%D +%D When skips have a stretch component, this is visualized by +%D means of a dashed line. Positive skips are on top of the +%D baseline, negative ones are below it. This way we can show +%D the combined results. An alternative visualization of +%D stretch could be drawing the mid line over a length of the +%D stretch, in positive or negative direction. + +\def\doruledhskip + {\relax + \dontinterfere + \dontcomplain + \investigateskip\scratchskip + \ifzero + \setbox0\normalhbox + {\normalhskip-\testrulewidth + \visualvrule + \!!width4\testrulewidth + \!!height16\testrulewidth + \!!depth16\testrulewidth}% + \else + \setbox0\normalhbox to \ifnegative-\fi\scratchskip + {\visualvrule + \!!width2\testrulewidth + \ifnegative\!!depth\else\!!height\fi16\testrulewidth + \cleaders + \visualhrule + \ifnegative + \!!depth2\testrulewidth + \!!height\zeropoint + \else + \!!height2\testrulewidth + \!!depth\zeropoint + \fi + \normalhfill + \ifflexible + \normalhskip\ifnegative\else-\fi\scratchskip + \normalhskip2\testrulewidth + \cleaders + \normalhbox + {\normalhskip 2\testrulewidth + \visualvrule + \!!width2\testrulewidth + \!!height\ifnegative-7\else9\fi\testrulewidth + \!!depth\ifnegative9\else-7\fi\testrulewidth + \normalhskip 2\testrulewidth}% + \normalhfill + \fi + \visualvrule + \!!width2\testrulewidth + \ifnegative\!!depth\else\!!height\fi16\testrulewidth}% + \setbox0\normalhbox + {\ifnegative\else\normalhskip-\scratchskip\fi + \box0}% + \fi + \smashbox0% + \ifvisiblestretch \else + \flexiblefalse + \fi + \ifflexible + % breaks ok but small displacements can occur + \skip2\scratchskip + \advance\skip2 -1\scratchskip + \divide\skip2 2 + \advance\scratchskip -\skip2 + \normalhskip\scratchskip + \normalpenalty\!!tenthousand + \box0 + \normalhskip\skip2 + \else + \normalhskip\scratchskip + \box0 + \fi + \egroup} + +\unexpanded\def\ruledhskip + {\bgroup + \afterassignment\doruledhskip + \scratchskip=} + +%D The visual skip is located at a feasible point. Normally +%D this does not interfere with the normaltypesetting process. +%D The next examples show (1)~the default behavior, (2)~the +%D (not entirely correct) distributed stretch and (3)~the way +%D the text is typeset without cues. +%D +%D \startbuffer +%D \dorecurse +%D {15} +%D {test\hskip1em plus .5em minus .5em +%D test\hskip2em +%D test} +%D \stopbuffer +%D +%D \startlinecorrection +%D \showmakeup +%D \getbuffer +%D \stoplinecorrection +%D +%D \startlinecorrection +%D \showmakeup +%D \visiblestretchtrue +%D \getbuffer +%D \stoplinecorrection +%D +%D \startlinecorrection +%D \getbuffer +%D \stoplinecorrection + +%D \macros +%D {ruledvskip} +%D +%D We are less fortunate when implementing the vertical skips. +%D This is a direct result of interference between the boxes that +%D visualize the skip and skip removal at a pagebreak. Normally +%D skips disappear at the top of a page, but not of course when +%D visualized in a \type{\vbox}. A quite perfect simulation +%D could have been built if we would have had available two +%D more primitives: \type{\hnop} and \type{\vnop}. These new +%D primitives could stand for boxes that are visible but are +%D not taken into account in any way. They are there for us, +%D but not for \TEX. +%D +%D \startbuffer +%D first line +%D \vskip +30pt plus 5pt +%D second line +%D \vskip +30pt +%D \vskip -10pt plus 5pt +%D third line +%D \par +%D fourth line +%D \vskip +30pt +%D fifth line +%D \vskip 0pt +%D sixth line +%D \stopbuffer +%D +%D \ShowBufferedExample +%D +%D We have to postpone \type{\prevdepth}. Although this +%D precaution probably is not completely waterproof, it works +%D quite well. + +\def\dodoruledvskip + {\nextdepth\prevdepth + \dontinterfere + \dontcomplain + \normaloffinterlineskip + \investigateskip\scratchskip + \ifzero + \setbox0\normalvcue + {\visualvrule + \!!width32\testrulewidth + \!!height2\testrulewidth + \!!depth2\testrulewidth}% + \else + \setbox0\normalvbox to \ifnegative-\fi\scratchskip + {\visualhrule + \!!width16\testrulewidth + \!!height2\testrulewidth + \ifflexible + \cleaders + \normalhbox to 16\testrulewidth + {\normalhss + \normalvbox + {\normalvskip 2\testrulewidth + \visualhrule + \!!width2\testrulewidth + \!!height2\testrulewidth + \normalvskip 2\testrulewidth}% + \normalhss}% + \normalvfill + \else + \normalvfill + \fi + \visualhrule + \!!width16\testrulewidth + \!!height2\testrulewidth}% + \setbox2\normalvbox to \ht0 + {\visualhrule + \!!width2\testrulewidth + \!!height\ht0}% + \ifnegative + \ht0\zeropoint + \setbox0\normalhbox + {\normalhskip2\testrulewidth % will be improved + \normalhskip-\wd0\box0}% + \fi + \smashbox0% + \smashbox2% + \setbox0\normalvcue + {\box2\box0}% + \setbox0\normalvbox + {\ifnegative\normalvskip\scratchskip\fi\box0}% + \smashbox0% + \fi + \ifvisiblestretch + \ifflexible + \skip2\scratchskip + \advance\skip2 -1\scratchskip + \divide\skip2 2 + \advance\scratchskip -\skip2 + \normalvskip\skip2 + \fi + \fi + \normalpenalty\!!tenthousand + \box0 + \prevdepth\nextdepth % not \dp0=\nextdepth + \normalvskip\scratchskip} + +%D We try to avoid interfering at the top of a page. Of course +%D we only do so when we are in the main vertical list. + +\def\doruledvskip + {\endgraf % \par + \ifdim\pagegoal=\maxdimen + \ifinner + \dodoruledvskip + \fi + \else + \dodoruledvskip + \fi + \egroup} + +\unexpanded\def\ruledvskip + {\bgroup + \afterassignment\doruledvskip + \scratchskip=} + +%D \macros +%D {ruledkern} +%D +%D The macros that implement the kerns are a bit more +%D complicated than needed, because they also serve the +%D visualization of glue, our \PLAIN\ defined kerns with +%D stretch or shrink. We've implemented both horizontal and +%D vertical kerns as ruled boxes. +%D +%D \startbuffer +%D one +%D \kern +30pt +%D two +%D \kern +30pt +%D \kern -10pt +%D three +%D \kern 0pt +%D four +%D \kern +30pt +%D five +%D \stopbuffer +%D +%D \ShowBufferedExample +%D +%D Positive and negative kerns are placed on top or below the +%D baseline, so we are able to track their added result. We +%D didn't mention spacings of 0~pt yet. Zero values are +%D visualized a bit different, because we want to see them +%D anyhow. + +\def\doruledhkern + {\dontinterfere + \dontcomplain + \baselinerulefalse + \investigateskip\scratchskip + \boxrulewidth2\testrulewidth + \ifzero + \setbox0\ruledhbox to 8\testrulewidth + {\visualvrule + \!!width\zeropoint + \!!height16\testrulewidth + \!!depth16\testrulewidth}% + \setbox0\normalhbox + {\normalhskip-4\testrulewidth\box0}% + \else + \setbox0\ruledhbox to \ifnegative-\fi\scratchskip + {\visualvrule + \!!width\zeropoint + \ifnegative\!!depth\else\!!height\fi16\testrulewidth + \ifflexible + \normalhskip2\testrulewidth + \cleaders + \normalhbox + {\normalhskip 2\testrulewidth + \visualvrule + \!!width2\testrulewidth + \!!height\ifnegative-7\else9\fi\testrulewidth + \!!depth\ifnegative9\else-7\fi\testrulewidth + \normalhskip 2\testrulewidth}% + \normalhfill + \else + \normalhfill + \fi}% + \testrulewidth2\testrulewidth + \setbox0\ruledhbox{\box0}% \make... + \fi + \smashbox0% + \normalpenalty\!!tenthousand + \normalhbox to \zeropoint + {\ifnegative\normalhskip1\scratchskip\fi + \box0}% + \afterwards\scratchskip + \egroup} + +\unexpanded\def\ruledhkern#1% + {\bgroup + \let\afterwards#1% + \afterassignment\doruledhkern + \scratchskip=} + +%D After having seen the horizontal ones, the vertical kerns +%D will not surprise us. In this example we use \type{\par} to +%D switch to vertical mode. +%D +%D \startbuffer +%D first line +%D \par \kern +30pt +%D second line +%D \par \kern +30pt +%D \par \kern -10pt +%D third line +%D \par +%D fourth line +%D \par \kern +30pt +%D fifth line +%D \par \kern 0pt +%D sixth line +%D \stopbuffer +%D +%D \ShowBufferedExample +%D +%D Like before, we have to postpone \type{\prevdepth}. If we +%D leave out this trick, we got ourselves some wrong spacing. + +\def\dodoruledvkern + {\nextdepth\prevdepth + \dontinterfere + \dontcomplain + \baselinerulefalse + \normaloffinterlineskip + \investigateskip\scratchskip + \boxrulewidth2\testrulewidth + \ifzero + \setbox0\ruledhbox to 32\testrulewidth + {\visualvrule + \!!width\zeropoint + \!!height4\testrulewidth + \!!depth4\testrulewidth}% + \else + \setbox0\ruledvbox to \ifnegative-\fi\scratchskip + {\hsize16\testrulewidth + \ifflexible + \cleaders + \normalhbox to 16\testrulewidth + {\normalhss + \normalvbox + {\normalvskip 2\testrulewidth + \visualhrule + \!!width2\testrulewidth + \!!height2\testrulewidth + \normalvskip 2\testrulewidth}% + \normalhss}% + \normalvfill + \else + \visualvrule + \!!width\zeropoint + \!!height\ifnegative-\fi\scratchskip + \normalhfill + \fi} + \fi + \testrulewidth2\testrulewidth + \setbox0\ruledvbox{\box0}% \make... + \smashbox0% + \setbox0\normalvbox + {\ifnegative\normalvskip\scratchskip\fi + \normalvcue + {\ifnegative\normalhskip-16\testrulewidth\fi\box0}}% + \smashbox0% + \normalpenalty\!!tenthousand + \box0 + \prevdepth\nextdepth} % not \dp0=\nextdepth + +\def\doruledvkern + {\ifdim\pagegoal=\maxdimen + \ifinner + \dodoruledvkern + \fi + \else + \dodoruledvkern + \fi + \afterwards\scratchskip + \egroup} + +\unexpanded\def\ruledvkern#1% + {\bgroup + \let\afterwards#1\relax + \afterassignment\doruledvkern + \scratchskip=} + +\unexpanded\def\ruledkern + {\ifvmode + \expandafter\ruledvkern + \else + \expandafter\ruledhkern + \fi + \normalkern} + +%D A a bit more \TEX nice solution is: +%D +%D \starttyping +%D \unexpanded\def\ruledkern% +%D {\csname ruled\ifvmode v\else h\fi kern\endcsname\normalkern} +%D \stoptyping + +%D \macros +%D {ruledhglue,ruledvglue} +%D +%D The non-primitive glue commands are treated as kerns with +%D stretch. This stretch is presented as a dashed line. I +%D have to admit that until now, I've never used these glue +%D commands. +%D +%D \startbuffer +%D one +%D \hglue +30pt plus 5pt +%D two +%D \hglue +30pt +%D \hglue -10pt plus 5pt +%D three +%D \hglue 0pt +%D four +%D \hglue +30pt +%D five +%D \stopbuffer +%D +%D \ShowBufferedExample + +\def\doruledhglue + {\leavevmode + \scratchcounter\spacefactor + \visualvrule\!!width\zeropoint + \normalpenalty\!!tenthousand + \ruledhkern\normalhskip\scratchskip + \spacefactor\scratchcounter + \egroup} + +\unexpanded\def\ruledhglue + {\bgroup + \afterassignment\doruledhglue\scratchskip=} + +%D \startbuffer +%D first line +%D \vglue +30pt plus 5pt +%D second line +%D \vglue +30pt +%D \vglue -10pt plus 5pt +%D third line +%D \par +%D fourth line +%D \vglue +30pt +%D fifth line +%D \vglue 0pt +%D sixth line +%D \stopbuffer +%D +%D \ShowBufferedExample + +\def\doruledvglue + {\endgraf % \par + \nextdepth\prevdepth + \visualhrule\!!height\zeropoint + \normalpenalty\!!tenthousand + \ruledvkern\normalvskip\scratchskip + \prevdepth\nextdepth + \egroup} + +\unexpanded\def\ruledvglue + {\bgroup + \afterassignment\doruledvglue\scratchskip=} + +%D \macros +%D {ruledmkern,ruledmskip} +%D +%D Mathematical kerns and skips are specified in mu. This +%D font related unit is incompatible with those of \DIMENSIONS\ +%D and \SKIPS. Because in math mode spacing is often a very +%D subtle matter, we've used a very simple, not overloaded way +%D to show them. + +\def\dodoruledmkern#1% + {\dontinterfere + \dontcomplain + \setbox0\normalhbox + {$\normalmkern\ifnegative-\fi\scratchmuskip$}% + \setbox0\normalhbox to \wd0 + {\visualvrule + \!!height16\testrulewidth + \!!depth16\testrulewidth + \!!width\testrulewidth + \leaders + \visualhrule + \!!height\ifpositive16\else-14\fi\testrulewidth + \!!depth\ifpositive-14\else16\fi\testrulewidth + \normalhfill + \ifflexible + \normalhskip-\wd0 + \leaders + \visualhrule + \!!height\testrulewidth + \!!depth\testrulewidth + \normalhfill + \fi + \visualvrule + \!!height16\testrulewidth + \!!depth16\testrulewidth + \!!width\testrulewidth}% + \smashbox0% + \ifnegative + #1\scratchmuskip + \box0 + \else + \box0 + #1\scratchmuskip + \fi + \egroup} + +%D \startbuffer +%D $a \mkern3mu = \mkern3mu +%D b \quad +%D \mkern-2mu + \mkern-2mu +%D \quad c$ +%D \stopbuffer +%D +%D \ShowBufferedExample + +\def\doruledmkern + {\investigatemuskip\scratchmuskip + \flexiblefalse + \dodoruledmkern\normalmkern} + +\unexpanded\def\ruledmkern + {\bgroup + \afterassignment\doruledmkern\scratchmuskip=} + +%D \startbuffer +%D $a \mskip3mu = \mskip3mu +%D b \quad +%D \mskip-2mu + \mskip-2mu +%D \quad c$ +%D \stopbuffer +%D +%D \ShowBufferedExample + +\def\doruledmskip + {\investigatemuskip\scratchmuskip + \flexibletrue + \dodoruledmkern\normalmskip} + +\unexpanded\def\ruledmskip + {\bgroup + \afterassignment\doruledmskip\scratchmuskip=} + +%D \macros +%D {penalty} +%D +%D After presenting fills, skip, kerns and glue we've come to +%D see penalties. In the first implementation --- most of the +%D time needed to develop this set of macros went into testing +%D different types of visualization --- penalties were mere +%D small blocks with one black half, depending on the sign. +%D This most recent version also gives an indication of the +%D amount of penalty. Penalties can go from less than $-10000$ +%D to over $+10000$, and their behavior is somewhat +%D non-lineair, with some values having special meanings. We +%D therefore decided not to use its value for a lineair +%D indicator. +%D +%D \startbuffer +%D one +%D \penalty +100 +%D two +%D \penalty +100 +%D \penalty -100 +%D three +%D \penalty 0 +%D four +%D \penalty +100 +%D five +%D \stopbuffer +%D +%D \ShowBufferedExample +%D +%D The small sticks at the side of the penalty indicate it +%D size. The next example shows the positive and negative +%D penalties of 0, 1, 10, 100, 1000 and 10000. +%D +%D \startlinecorrection +%D \hbox +%D {test \ruledhpenalty0 +%D test \ruledhpenalty1 +%D test \ruledhpenalty10 +%D test \ruledhpenalty100 +%D test \ruledhpenalty1000 +%D test \ruledhpenalty10000 +%D test} +%D \stoplinecorrection +%D +%D \blank +%D +%D \startlinecorrection +%D \hbox +%D {test \ruledhpenalty0 +%D test \ruledhpenalty-1 +%D test \ruledhpenalty-10 +%D test \ruledhpenalty-100 +%D test \ruledhpenalty-1000 +%D test \ruledhpenalty-10000 +%D test} +%D \stoplinecorrection +%D +%D \blank +%D +%D This way stacked penalties of different severance can be +%D shown in combination. +%D +%D test \ruledhpenalty10 \ruledhpenalty100 +%D test +%D test \ruledhpenalty1000 \ruledhpenalty-1000 +%D test + +\def\setruledpenaltybox#1#2#3#4#5#6% + {\setbox#1\normalhbox + {\ifnum#2=0 \else + \edef\sign + {\ifnum#2>0 +\else-\fi}% + \dimen0=\ifnum\sign#2>9999 + 28\else + \ifnum\sign#2>999 + 22\else + \ifnum\sign#2>99 + 16\else + \ifnum\sign#2>9 + 10\else + 4 + \fi\fi\fi\fi \testrulewidth + \ifnum#2<0 + \normalhskip-\dimen0 + \normalhskip-2\testrulewidth + \visualvrule + \!!width2\testrulewidth + \!!height#3\testrulewidth + \!!depth#4\testrulewidth + \fi + \visualvrule + \!!width\dimen0 + \!!height#5\testrulewidth + \!!depth#6\testrulewidth + \ifnum#2>0 + \visualvrule + \!!width2\testrulewidth + \!!height#3\testrulewidth + \!!depth#4\testrulewidth + \fi + \fi}% + \smashbox#1} + +\def\doruledhpenalty + {\dontinterfere + \dontcomplain + \investigatecount\scratchcounter + \testrulewidth2\testrulewidth + \boxrulewidth\testrulewidth + \setbox0\ruledhbox to 8\testrulewidth + {\ifnegative\else\normalhss\fi + \visualvrule + \!!depth8\testrulewidth + \!!width\ifzero0\else4\fi\testrulewidth + \ifpositive\else\normalhss\fi}% + \setruledpenaltybox{2}{\scratchcounter}{0}{8}{-3.5}{4.5}% + \normalpenalty\!!tenthousand + \setbox0\normalhbox + {\normalhskip-4\testrulewidth + \ifnegative + \box2\box0 + \else + \box0\box2 + \fi}% + \smashbox0% + \box0 + \normalpenalty\scratchcounter + \egroup} + +\unexpanded\def\ruledhpenalty + {\bgroup + \afterassignment\doruledhpenalty + \scratchcounter=} + +%D The size of a vertical penalty is also shown on the +%D horizontal axis. This way there is less interference with +%D the often preceding or following skips and kerns. +%D +%D \startbuffer +%D first line +%D \par \penalty +100 +%D second line +%D \par \penalty +100 +%D \par \penalty -100 +%D third line +%D \par \penalty 0 +%D fourth line +%D \par \penalty +100 +%D fifth line +%D \stopbuffer +%D +%D \ShowBufferedExample + +\def\doruledvpenalty + {\ifdim\pagegoal=\maxdimen + \else + \nextdepth\prevdepth + \dontinterfere + \dontcomplain + \investigatecount\scratchcounter + \testrulewidth2\testrulewidth + \boxrulewidth\testrulewidth + \setbox0\ruledhbox + {\visualvrule + \!!height4\testrulewidth + \!!depth4\testrulewidth + \!!width\zeropoint + \visualvrule + \!!height\ifnegative.5\else4\fi\testrulewidth + \!!depth\ifpositive.5\else4\fi\testrulewidth + \!!width8\testrulewidth}% + \setruledpenaltybox{2}{\scratchcounter}{4}{4}{.5}{.5}% + \setbox0\normalhbox + {\normalhskip-4\testrulewidth + \ifnegative + \box2\box0 + \else + \box0\box2 + \fi + \normalhss}% + \smashbox0% + \normalpenalty\!!tenthousand + \nointerlineskip + \dp0\nextdepth % not \prevdepth=\nextdepth + \normalvbox + {\normalvcue{\box0}}% + \fi + \normalpenalty\scratchcounter + \egroup} + +\unexpanded\def\ruledvpenalty + {\bgroup + \afterassignment\doruledvpenalty + \scratchcounter=} + +\unexpanded\def\ruledpenalty + {\ifvmode + \expandafter\ruledvpenalty + \else + \expandafter\ruledhpenalty + \fi} + +%D At the cost of some more tokens, a bit more clever +%D implementation would be: +%D +%D \starttyping +%D \unexpanded\def\ruledpenalty% +%D {\csname ruled\ifvmode v\else h\fi penalty\endcsname} +%D \stoptyping + +%D \macros +%D {showfils,dontshowfils, +%D showboxes,dontshowboxes, +%D showskips,dontshowskips, +%D showpenalties,dontshowpenalties} +%D +%D For those who want to manipulate the visual cues in detail, +%D we have grouped them. + +\newif\ifshowingcomposition % see later why we need this + +\def\showfils + {\showingcompositiontrue + \let\hss \ruledhss + \let\hfil \ruledhfil + \let\hfill \ruledhfill + \let\hfilneg \ruledhfilneg + \let\hfillneg \ruledhfillneg + \let\vss \ruledvss + \let\vfil \ruledvfil + \let\vfill \ruledvfill + \let\vfilneg \ruledvfilneg + \let\vfillneg \ruledvfillneg} + +\def\dontshowfils + {\let\hss \normalhss + \let\hfil \normalhfil + \let\hfill \normalhfill + \let\hfilneg \normalhfilneg + \let\hfillneg \normalhfillneg + \let\vss \normalvss + \let\vfil \normalvfil + \let\vfill \normalvfill + \let\vfilneg \normalvfilneg + \let\vfillneg \normalvfillneg} + +\def\showboxes + {\showingcompositiontrue + \baselineruletrue + \let\hbox \ruledhbox + \let\vbox \ruledvbox + \let\vtop \ruledvtop + \let\vcenter \ruledvcenter} + +\def\dontshowboxes + {\let\hbox \normalhbox + \let\vbox \normalvbox + \let\vtop \normalvtop + \let\vcenter \normalvcenter} + +\def\showskips + {\showingcompositiontrue + \let\hskip \ruledhskip + \let\vskip \ruledvskip + \let\kern \ruledkern + \let\mskip \ruledmskip + \let\mkern \ruledmkern + \let\hglue \ruledhglue + \let\vglue \ruledvglue} + +\def\dontshowskips + {\let\hskip \normalhskip + \let\vskip \normalvskip + \let\kern \normalkern + \let\mskip \normalmskip + \let\mkern \normalmkern + \let\hglue \normalhglue + \let\vglue \normalvglue} + +\def\showpenalties + {\showingcompositiontrue + \let\penalty \ruledpenalty} + +\def\dontshowpenalties + {\let\penalty \normalpenalty} + +%D \macros +%D {showcomposition,dontshowcomposition, +%D showingcomposition} +%D +%D All these nice options come together in three macros. One +%D for turning the options on, one for turning them off, and a +%D boolean for enabling the mechanism outside the scope of the +%D user. The first two macros only do their job when we are +%D actually showing the composition. +%D +%D \starttyping +%D \showingcompositiontrue +%D \showcomposition +%D \stoptyping +%D +%D Because the output routine can do tricky things, like +%D multiple column typesetting and manipulation of the +%D pagebody, shifting things around and so on, the macro +%D \type{\dontshowcomposition} best can be called when we enter +%D this routine. Too much visual cues just don't make sense. In +%D \CONTEXT\ this has been taken care of. + +\newif\ifshowingcomposition + +\def\showcomposition + {\ifshowingcomposition + \showfils + \showboxes + \showskips + \showpenalties + \fi} + +\def\dontshowcomposition + {\ifshowingcomposition + \dontshowfils + \dontshowboxes + \dontshowskips + \dontshowpenalties + \fi} + +%D \macros +%D {showmakeup, +%D defaulttestrulewidth} +%D +%D Just to make things even more easy, we have defined: +%D +%D \starttyping +%D \showmakeup +%D \stoptyping +%D +%D For the sake of those who don't (yet) use \CONTEXT\ we +%D preset \type{\defaulttestrulewidth} to the already set +%D value. Otherwise we default to a bodyfontsize related value. +%D +%D \starttyping +%D \def\defaulttestrulewidth{.2pt} +%D \stoptyping +%D +%D Beware, it's a macro not a \DIMENSION. + +\ifx\bodyfontsize\undefined + \edef\defaulttestrulewidth{\the\testrulewidth} +\else + \def\defaulttestrulewidth{.02\bodyfontsize} +\fi + +\def\showmakeup + {\testrulewidth\defaulttestrulewidth + \showingcompositiontrue + \showcomposition} + +\protect + +%D \ifCONTEXT \let\next=\relax \else \let\next=\endinput +%D The documented source you have been reading was processed +%D using some surrogate makeup. When this file is processed +%D in \CONTEXT, a few more examples show up here, like a local +%D table of contents and a local register. +%D \fi \next + +%D Lets end with some more advanced examples. +%D Definitions and enumerations come in many flavors. The +%D next one for instance is defined as: +%D +%D \starttyping +%D \definedescription[test][place=left,hang=3,width=6em] +%D \stoptyping +%D +%D When applied to some text, this would look like: +%D +%D \bgroup +%D \showmakeup +%D \definedescription[test][location=left,hang=3,width=6em] +%D +%D \test{visual\\debugger} I would be very pleased if \TEX\ +%D had two more primitives: \type{\vnop} and \type{\hnop}. Both +%D should act and show up as normal boxes, but stay invisible +%D for \TEX\ when it's doing calculations. The \type{\vnop} +%D for instance should not interact with the internal mechanism +%D responsible for the disappearing skips, kerns and penalties +%D at a pagebreak. As long as we don't have these two boxtypes, +%D visual debugging will never be perfect. +%D +%D \egroup +%D +%D The index to this section looks like: +%D +%D {\setupreferencing[prefixprefix=dummy]\showmakeup\placeindex[criterium=local]} +%D +%D Although not impressive examples or typesetting, both +%D show us how and where things happen. When somehow the last +%D lines in this two column index don't allign, then this is +%D due to some still unknown interference. + +\endinput diff --git a/tex/context/base/symb-cow.tex b/tex/context/base/symb-cow.tex new file mode 100644 index 000000000..c04ca0108 --- /dev/null +++ b/tex/context/base/symb-cow.tex @@ -0,0 +1,132 @@ +%D \module +%D [ file=symb-cow, +%D version=2006.06.23, +%D title=\CONTEXT\ Symbol Libraries, +%D subtitle=Cow 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. + +\loadmapfile[koeieletters.map] + +\definefontsynonym [Cows] [koeielett] +\definefontsynonym [CowsContour] [koeielett-contour] +\definefontsynonym [CowsLogo] [koeielogos] +\definefontsynonym [CowsLogoContour] [koeielogos-contour] + +\definecolor [lsky] [r=.6,g=.6,b=1] +\definecolor [dsky] [r=.1,g=.1,b=1] +\definecolor [lground] [r=.3,g=.9,b=.3] +\definecolor [dground] [r=0,g=.5,b=0] +\definecolor [cspots] [r=.33,g=.1,b=0] + +\definecolor [tlsky] [t=.5,a=1,r=.6,g=.6,b=1] +\definecolor [tdsky] [t=.5,a=1,r=.1,g=.1,b=1] +\definecolor [tlground] [t=.5,a=1,r=.3,g=.9,b=.3] +\definecolor [tdground] [t=.5,a=1,r=0,g=.5,b=0] +\definecolor [tcspots] [t=.5,a=1,r=.33,g=.1,b=0] + +\definepalet + [cow] + [normal=lground, + contour=dground, + sky=lsky] + +\def\CowNormal#1% + {\dontleavehmode\hbox{\color[cow:normal]{\getglyph{Cows}{#1}}}} + +\def\ScaledCowNormal#1#2% + {\dontleavehmode\hbox{\color[cow:normal]{\definedfont[Cows sa #1]#2}}} + +\def\ScaledCowOverlay#1#2% + {\dontleavehmode\hbox + {\color[cow:contour]{\hsmash{\definedfont[CowsContour sa #1]#2}}% + \color[cow:normal] {\definedfont[Cows sa #1]#2}}} + +\def\CowOverlay#1% + {\dontleavehmode\hbox + {\color[cow:contour]{\hsmash{\getglyph{CowsContour}{#1}}}% + \color[cow:normal] {\getglyph{Cows} {#1}}}} + +\def\CowContour#1% + {\dontleavehmode\hbox + {\color[cow:contour]{\hsmash{\getglyph{CowsLogoContour}{#1}}}% + \color[cow:normal] {\getglyph{CowsLogo} {#1}}}} + +\def\CowLogo #1{\getglyph{CowsLogo} {\char#1\relax}} +\def\CowContourLogo#1{\getglyph{CowsLogoContour}{\char#1\relax}} + +\chardef\CowPragmaNormal= 1 +\chardef\CowPragmaShaded=20 + +\startsymbolset[cownormal] + +\definesymbol[CowPragmaADE] [\CowLogo{0}] +\definesymbol[CowPragma] [\CowLogo{1}] +\definesymbol[CowConTeXt] [\CowLogo{2}] +\definesymbol[CowConTeXtComplete] [\CowLogo{3}] +\definesymbol[CowConTeXtShadow] [\CowLogo{4}] +\definesymbol[CowConTeXtContour] [\CowLogo{5}] +\definesymbol[CowConTeXtOutline] [\CowLogo{6}] +\definesymbol[CowConTeXtDots] [\CowLogo{7}] +\definesymbol[CowMP] [\CowLogo{8}] +\definesymbol[CowMPComplete] [\CowLogo{9}] +\definesymbol[CowTeX] [\CowLogo{10}] +\definesymbol[CowTeXComplete] [\CowLogo{11}] +\definesymbol[CowBoo] [\CowLogo{12}] +\definesymbol[CowCow] [\CowLogo{13}] +\definesymbol[CowExampleComplete] [\CowLogo{14}] +\definesymbol[CowFoxetComplete] [\CowLogo{15}] +\definesymbol[CowMetafun] [\CowLogo{16}] +\definesymbol[CowMetafunComplete] [\CowLogo{17}] +\definesymbol[CowTEXComplete] [\CowLogo{18}] +\definesymbol[CowWikiComplete] [\CowLogo{19}] +\definesymbol[CowPragmaADEComplete][\CowLogo{20}] +\definesymbol[CowPragmaComplete] [\CowLogo{21}] +\definesymbol[CowExample] [\CowLogo{22}] +\definesymbol[CowFoxet] [\CowLogo{23}] +\definesymbol[CowTEX] [\CowLogo{24}] +\definesymbol[CowWiki] [\CowLogo{25}] +\definesymbol[CowCowTeXtComplete] [\CowLogo{26}] +\definesymbol[CowCowTeXt] [\CowLogo{27}] + +\stopsymbolset + +\startsymbolset[cowcontour] + +\definesymbol[CowPragmaADE] [\CowContourLogo{0}] +\definesymbol[CowPragma] [\CowContourLogo{1}] +\definesymbol[CowConTeXt] [\CowContourLogo{2}] +\definesymbol[CowConTeXtComplete] [\CowContourLogo{3}] +\definesymbol[CowConTeXtShadow] [\CowContourLogo{4}] +\definesymbol[CowConTeXtContour] [\CowContourLogo{5}] +\definesymbol[CowConTeXtOutline] [\CowContourLogo{6}] +\definesymbol[CowConTeXtDots] [\CowContourLogo{7}] +\definesymbol[CowMP] [\CowContourLogo{8}] +\definesymbol[CowMPComplete] [\CowContourLogo{9}] +\definesymbol[CowTeX] [\CowContourLogo{10}] +\definesymbol[CowTeXComplete] [\CowContourLogo{11}] +\definesymbol[CowBoo] [\CowContourLogo{12}] +\definesymbol[CowCow] [\CowContourLogo{13}] +\definesymbol[CowExampleComplete] [\CowContourLogo{14}] +\definesymbol[CowFoxetComplete] [\CowContourLogo{15}] +\definesymbol[CowMetafun] [\CowContourLogo{16}] +\definesymbol[CowMetafunComplete] [\CowContourLogo{17}] +\definesymbol[CowTEXComplete] [\CowContourLogo{18}] +\definesymbol[CowWikiComplete] [\CowContourLogo{19}] +\definesymbol[CowPragmaADEComplete][\CowContourLogo{20}] +\definesymbol[CowPragmaComplete] [\CowContourLogo{21}] +\definesymbol[CowExample] [\CowContourLogo{22}] +\definesymbol[CowFoxet] [\CowContourLogo{23}] +\definesymbol[CowTEX] [\CowContourLogo{24}] +\definesymbol[CowWiki] [\CowContourLogo{25}] +\definesymbol[CowCowTeXtComplete] [\CowContourLogo{26}] +\definesymbol[CowCowTeXt] [\CowContourLogo{27}] + +\stopsymbolset + +\endinput diff --git a/tex/context/base/symb-eur.tex b/tex/context/base/symb-eur.tex new file mode 100644 index 000000000..400e88ac5 --- /dev/null +++ b/tex/context/base/symb-eur.tex @@ -0,0 +1,64 @@ +%D \module +%D [ file=symb-eur, +%D version=2000.06.22, +%D title=\CONTEXT\ Symbol Libraries, +%D subtitle=Adobe Euro Symbols, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\loadmapfile [original-adobe-euro.map] + +\definefontsynonym [EuroSerif] [eurose] +\definefontsynonym [EuroSerifBold] [euroseb] +\definefontsynonym [EuroSerifItalic] [eurosei] +\definefontsynonym [EuroSerifSlanted] [eurosei] +\definefontsynonym [EuroSerifBoldItalic] [eurosebi] +\definefontsynonym [EuroSerifBoldSlanted] [eurosebi] + +\definefontsynonym [EuroSans] [eurosa] +\definefontsynonym [EuroSansBold] [eurosab] +\definefontsynonym [EuroSansItalic] [eurosai] +\definefontsynonym [EuroSansSlanted] [eurosai] +\definefontsynonym [EuroSansBoldItalic] [eurosabi] +\definefontsynonym [EuroSansBoldSlanted] [eurosabi] + +\definefontsynonym [EuroMono] [euromo] +\definefontsynonym [EuroMonoBold] [euromob] +\definefontsynonym [EuroMonoSlanted] [euromoi] +\definefontsynonym [EuroMonoItalic] [euromoi] +\definefontsynonym [EuroMonoBoldItalic] [euromobi] +\definefontsynonym [EuroMonoBoldSlanted] [euromobi] + +\definesymbol [euro] [\getglyph{Euro}{\char160}] + +\startencoding[default] + \definecharacter texteuro {\symbol[euro]} +\stopencoding + +\unexpanded\def\euro{\doiftextelse\texteuro\texteuro{\symbol[euro]}} + +% ok for one font series, but not for mixed sets +% +% \unexpanded\def\euro +% {\doiftextelse \texteuro \texteuro +% {\unexpanded\def\euro{\symbol[euro]}\euro} + +%D The next table shows the complete set of symbols: +%D +%D \starttabulate[|l|c|c|c|c|c|c|] +%D \NC \NC \tex{tf} \NC \tex{bf} \NC \tex{sl} +%D \NC \tex{it} \NC \tex{bs} \NC \tex{bi} \NC\NR +%D \NC \rm Serif \NC \rm\tf\euro \NC \rm\bf\euro \NC \rm\sl\euro +%D \NC \rm\it\euro \NC \rm\bs\euro \NC \rm\bi\euro \NC\NR +%D \NC \ss Sans \NC \ss\tf\euro \NC \ss\bf\euro \NC \ss\sl\euro +%D \NC \ss\it\euro \NC \ss\bs\euro \NC \ss\bi\euro \NC\NR +%D \NC \tt Mono \NC \tt\tf\euro \NC \tt\bf\euro \NC \tt\sl\euro +%D \NC \tt\it\euro \NC \tt\bs\euro \NC \tt\bi\euro \NC\NR +%D \stoptabulate + +\endinput diff --git a/tex/context/base/symb-glm.tex b/tex/context/base/symb-glm.tex new file mode 100644 index 000000000..0b01ca7df --- /dev/null +++ b/tex/context/base/symb-glm.tex @@ -0,0 +1,79 @@ +%D \module +%D [ file=symb-glm, +%D version=2002.05.07, +%D title=\CONTEXT\ Symbol Libraries, +%D subtitle=Guillemots, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 Watch the \type {x} before the local symbols. + +% \loadmapfile [ec-public-lm.map] +% \loadmapfile [ec-lm.map] +\loadmapfile [lm-ec.map] + +% this used to be: +% +% \definefontsynonym [GuilSerif] [plr10] [encoding=ec] +% \definefontsynonym [GuilSerifBold] [plbx10] [encoding=ec] +% \definefontsynonym [GuilSerifItalic] [plti10] [encoding=ec] +% \definefontsynonym [GuilSerifSlanted] [plsl10] [encoding=ec] +% \definefontsynonym [GuilSerifBoldItalic] [plbxti10] [encoding=ec] +% \definefontsynonym [GuilSerifBoldSlanted] [plbxsl10] [encoding=ec] +% +% \definefontsynonym [GuilSans] [plss10] [encoding=ec] +% \definefontsynonym [GuilSansBold] [plssbx10] [encoding=ec] +% \definefontsynonym [GuilSansItalic] [plssi10] [encoding=ec] +% \definefontsynonym [GuilSansSlanted] [plssi10] [encoding=ec] +% \definefontsynonym [GuilSansBoldItalic] [plssbi10] [encoding=ec] +% \definefontsynonym [GuilSansBoldSlanted] [plssbi10] [encoding=ec] +% +% \definefontsynonym [GuilMono] [pltt10] [encoding=ec] +% +% but was also one of the reasons for triggering the lm project, so: + +\definefontsynonym [GuilSerif] [ec-lmr10] [encoding=ec] +\definefontsynonym [GuilSerifBold] [ec-lmbx10] [encoding=ec] +\definefontsynonym [GuilSerifItalic] [ec-lmti10] [encoding=ec] +\definefontsynonym [GuilSerifSlanted] [ec-lmsl10] [encoding=ec] +\definefontsynonym [GuilSerifBoldItalic] [ec-lmbxti10] [encoding=ec] +\definefontsynonym [GuilSerifBoldSlanted] [ec-lmbxsl10] [encoding=ec] + +\definefontsynonym [GuilSans] [ec-lmss10] [encoding=ec] +\definefontsynonym [GuilSansBold] [ec-lmssbx10] [encoding=ec] +\definefontsynonym [GuilSansItalic] [ec-lmssi10] [encoding=ec] +\definefontsynonym [GuilSansSlanted] [ec-lmssi10] [encoding=ec] +\definefontsynonym [GuilSansBoldItalic] [ec-lmssbi10] [encoding=ec] +\definefontsynonym [GuilSansBoldSlanted] [ec-lmssbi10] [encoding=ec] + +\definefontsynonym [GuilMono] [ec-lmtt10] [encoding=ec] +%definefontsynonym [GuilMonoBold] [ec-lmtt10] [encoding=ec] +%definefontsynonym [GuilMonoSlanted] [ec-lmtt10] [encoding=ec] +%definefontsynonym [GuilMonoItalic] [ec-lmtt10] [encoding=ec] +%definefontsynonym [GuilMonoBoldItalic] [ec-lmtt10] [encoding=ec] +%definefontsynonym [GuilMonoBoldSlanted] [ec-lmtt10] [encoding=ec] + +\definesymbol [xleftguillemot] [\getglyph{Guil}{\char19}] +\definesymbol [xrightguillemot] [\getglyph{Guil}{\char20}] + +\definesymbol [xguilsingleleft] [\getglyph{Guil}{\char14}] +\definesymbol [xguilsingleright] [\getglyph{Guil}{\char15}] + +%D A strange place, but okay (the \type {\relax} prevents space gobbling) + +\startencoding [default] + + \definecharacter leftguillemot {\symbol[xleftguillemot]\relax} + \definecharacter rightguillemot {\symbol[xrightguillemot]\relax} + + \definecharacter guilsingleleft {\symbol[xguilsingleleft]\relax} + \definecharacter guilsingleright {\symbol[xguilsingleright]\relax} + +\stopencoding + +\endinput diff --git a/tex/context/base/symb-ini.mkii b/tex/context/base/symb-ini.mkii new file mode 100644 index 000000000..f7bffd240 --- /dev/null +++ b/tex/context/base/symb-ini.mkii @@ -0,0 +1,281 @@ +%D \module +%D [ file=symb-ini, +%D version=1998.07.20, +%D title=\CONTEXT\ Symbol Libraries, +%D subtitle=Basic Symbols Commands, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 macros described here used to be part of the \type +%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} + +\unprotect + +%D \macros +%D {definesymbol, symbol} +%D +%D Converting numbers or levels into a character, romannumeral, +%D symbol or something else, is supported by many \CONTEXT\ +%D commands. Therefore we need a mechanism for linking such +%D numbers to their counterparts. +%D +%D First we take care of symbols. These are for instance used +%D in enumerations and itemizations. We have: +%D +%D \showsetup{definesymbol} +%D \showsetup{symbol} +%D +%D Symbols are simply linked to a tag. Such tags can be numbers +%D or strings. +%D +%D \starttyping +%D \definesymbol [1] [$\bullet$] +%D \definesymbol [level 5] [$\star$] +%D \stoptyping + +% ss:tag -> symbol +% ss:set:tag -> symbol out of set +% sstag -> list of symbols in set + +\def\definesymbol + {\dotripleempty\dodefinesymbol} + +% \def\dodefinesymbol[#1][#2][#3]% class name meaning +% {\ifthirdargument +% \setvalue{\??ss:#1:#2}{#3}% +% \doifsomething{#1}{\addvalue{\??ss*#1}{#2}}% +% \else +% \setvalue{\??ss:\currentsymboldef:#1}{#2}% +% \fi} + +\def\dodefinesymbol[#1][#2][#3]% class name meaning + {\ifthirdargument + \setvalue{\??ss:#1:#2}{#3}% + \doifsomething{#1}{\addvalue{\??ss*#1}{#2}}% + \else + \setvalue{\??ss:\currentsymboldef:#1}{#2}% + \addvalue{\??ss*\currentsymboldef}{#1}% + \fi} + +\def\doifinsymbolsetelse#1#2{\doifdefinedelse{\??ss:#1:#2}} +\def\doifinsymbolset #1#2{\doifdefined {\??ss:#1:#2}} +\def\doifsymbolsetelse #1{\doifdefinedelse{\??ss*#1}} + +\def\symbolset#1{\executeifdefined{\??ss*#1}\empty} % no [#1], to be used in commalists etc + +%D Since symbols are used frequently in interactive +%D documents, we speed up this one. Well, that was history, +%D since now we simplified things a bit, because the low +%D level macros have been sped up now and then. + +\unexpanded\def\symbol % This one always gobbles spaces, + {\dodoubleempty\dosymbol} % so never change it again! + +\newif\ifnosymbol \newtoks\everysymbol + +\def\dodosymbol#1#2% \relax's prevent lookahead problems + {\nosymbolfalse{\the\everysymbol\csname\??ss:#1:#2\endcsname\relax}\relax} + +\def\directsymbol#1#2% no \relax, there can be an argument, see lists + {\executeifdefined{\??ss:#1:#2}\firstofoneargument} + +% We support both: +% +% Test test \symbol[whatever]\ test \symbol[whatever]. +% Test test \symbol{whatever} test \symbol{whatever}. + +\def\dosymbol % so we also handle \symbol{name} + {\iffirstargument % which is nicer with following spaces + \expandafter\donormalsymbol + \else + \expandafter\dospecialsymbol + \fi} + +\def\dospecialsymbol[#1][#2]#3% + {\firstargumenttrue + \secondargumentfalse + \donormalsymbol[#3][]} + +\def\donormalsymbol[#1][#2]% + {\nosymboltrue + \ifsecondargument + \edef\currentsymbol{#2}% + \doifinsymbolset{#1}{#2}{\dodosymbol{#1}{#2}}% + \else + \edef\currentsymbol{#1}% + \fi + \ifnosymbol + \the\symbolsetups + \ifnosymbol + \redosymbol\currentsymbol + \fi + \fi} + +\def\fetchsymbol#1% + {\ifnosymbol + \doifinsymbolset{#1}\currentsymbol{\dodosymbol{#1}\currentsymbol}% + \fi} + +\def\redosymbol#1% +% {\doifinsymbolsetelse\empty{#1}{\dodosymbol\empty{#1}}{#1}} % more efficient: + {\doifinsymbolsetelse\empty{#1}{\dodosymbol\empty}\firstofoneargument{#1}} + +% % % % % +% this should go in symb-fig, to be loaded after core-fig + +%D \macros +%D {definefiguresymbol} +%D +%D To simplify defining figure symbols, we offer: +%D +%D \showsetup{definefiguresymbol} +%D +%D By default, such symbols scale along the current bodyfont +%D size or running font size (which is better). + +\def\defaultsymbolfactor{10} +\def\defaultsymbolheight{1.25ex} + +\def\figuresymbol + {\dodoubleempty\dofiguresymbol} + +\ifx\externalfigure \undefined \def\externalfigure[#1][#2]{#1} \fi +\ifx\resetexternalfigures\undefined \let\resetexternalfigures\relax \fi + +\def\dofiguresymbol[#1][% #2]% + {\externalfigure[#1][\c!reset=\v!yes,\c!symbol=\v!yes,\c!height=\defaultsymbolheight,}% #2]} + +\appendtoks \resetexternalfigures \to \everysymbol + +\def\definefiguresymbol + {\dotripleempty\dodefinefiguresymbol} + +\def\dodefinefiguresymbol[#1][#2][#3]% + {\ifsecondargument + \definesymbol[#1][{\dofiguresymbol[#2][#3]}]% + \fi} + +% but for the moment we keep it here +% % % % % % + +%\def\objectsymbol[#1]% +% {\dopresetfieldsymbol{#1}\dogetfieldsymbol{#1}} + +%D \macros +%D {doifsymboldefinedelse} +%D +%D A handy private one: + +% a bit messy + +\def\xfetchsymbol#1% + {\ifnosymbol + \doifinsymbolset{#1}\currentsymbol\nosymbolfalse + \fi} + +\def\xredosymbol#1% + {\doifinsymbolset\empty\currentsymbol\nosymbolfalse} + +\def\doifsymboldefinedelse#1% + {\bgroup + \edef\currentsymbol{#1}% + \let\fetchsymbol\xfetchsymbol + \nosymboltrue + \the\symbolsetups + \ifnosymbol + \xredosymbol\currentsymbol + \ifnosymbol + \egroup\@EAEAEA\secondoftwoarguments + \else + \egroup\@EAEAEA\firstoftwoarguments + \fi + \else + \egroup\@EA\firstoftwoarguments + \fi} + +%D \macros +%D {setupsymbolset,startsymbolset} +%D +%D From these macro definitions one can deduce that symbols can +%D be grouped in symbol sets: +%D +%D \starttyping +%D \startsymbolset [navigation 1] +%D \definefiguresymbol [Next] [mp-symb.1] +%D \definefiguresymbol [Prev] [mp-symb.2] +%D \stopsymbolset +%D \stoptyping +%D +%D Such a symbol can be typeset with: +%D +%D \starttyping +%D \setupsymbolset[navigation 1]\symbol[Next] +%D \stoptyping +%D +%D or simply: +%D +%D \starttyping +%D \symbol[navigation 1][Next] +%D \stoptyping +%D +%D Formally: +%D +%D \showsetup{setupsymbolset} +%D \showsetup{startsymbolset} + +\let\currentsymboldef\empty + +\def\startsymbolset[#1] + {\def\currentsymboldef{#1}} + +\def\stopsymbolset + {\let\currentsymboldef\empty} + +\newtoks\symbolsetups + +\def\setupsymbolset[#1]% + {\prependtoksonce\fetchsymbol{#1}\to\symbolsetups} + +\def\resetsymbolset + {\symbolsetups\emptytoks} + +\def\forcesymbolset[#1]% + {\symbolsetups{\fetchsymbol{#1}}} + +%D \macros +%D {showsymbolset} +%D +%D \showsetup{showsymbolset} + +\fetchruntimecommand \showsymbolset {\f!symbolprefix\s!run.mkii} + +%D \macros +%D {usesymbols} +%D +%D \showsetup{usesymbols} + +\def\dousesymbols#1% + {\makeshortfilename[\truefilename{\f!symbolprefix#1}]% + \startreadingfile + \readsysfile\shortfilename + {\showmessage\m!symbols1{#1}} + \donothing + \stopreadingfile} + +\def\usesymbols[#1]% + {\processcommalist[#1]\dousesymbols} + +%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. + +\protect \endinput diff --git a/tex/context/base/symb-ini.mkiv b/tex/context/base/symb-ini.mkiv new file mode 100644 index 000000000..f4f6bdd79 --- /dev/null +++ b/tex/context/base/symb-ini.mkiv @@ -0,0 +1,281 @@ +%D \module +%D [ file=symb-ini, +%D version=1998.07.20, +%D title=\CONTEXT\ Symbol Libraries, +%D subtitle=Basic Symbols Commands, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 macros described here used to be part of the \type +%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} + +\unprotect + +%D \macros +%D {definesymbol, symbol} +%D +%D Converting numbers or levels into a character, romannumeral, +%D symbol or something else, is supported by many \CONTEXT\ +%D commands. Therefore we need a mechanism for linking such +%D numbers to their counterparts. +%D +%D First we take care of symbols. These are for instance used +%D in enumerations and itemizations. We have: +%D +%D \showsetup{definesymbol} +%D \showsetup{symbol} +%D +%D Symbols are simply linked to a tag. Such tags can be numbers +%D or strings. +%D +%D \starttyping +%D \definesymbol [1] [$\bullet$] +%D \definesymbol [level 5] [$\star$] +%D \stoptyping + +% ss:tag -> symbol +% ss:set:tag -> symbol out of set +% sstag -> list of symbols in set + +\unexpanded\def\definesymbol + {\dotripleempty\dodefinesymbol} + +% \def\dodefinesymbol[#1][#2][#3]% class name meaning +% {\ifthirdargument +% \setvalue{\??ss:#1:#2}{#3}% +% \doifsomething{#1}{\addvalue{\??ss*#1}{#2}}% +% \else +% \setvalue{\??ss:\currentsymboldef:#1}{#2}% +% \fi} + +\def\dodefinesymbol[#1][#2][#3]% class name meaning + {\ifthirdargument + \setvalue{\??ss:#1:#2}{#3}% + \doifsomething{#1}{\addvalue{\??ss*#1}{#2}}% + \else + \setvalue{\??ss:\currentsymboldef:#1}{#2}% + \addvalue{\??ss*\currentsymboldef}{#1}% + \fi} + +\def\doifinsymbolsetelse#1#2{\doifdefinedelse{\??ss:#1:#2}} +\def\doifinsymbolset #1#2{\doifdefined {\??ss:#1:#2}} +\def\doifsymbolsetelse #1{\doifdefinedelse{\??ss*#1}} + +\def\symbolset#1{\executeifdefined{\??ss*#1}\empty} % no [#1], to be used in commalists etc + +%D Since symbols are used frequently in interactive +%D documents, we speed up this one. Well, that was history, +%D since now we simplified things a bit, because the low +%D level macros have been sped up now and then. + +\unexpanded\def\symbol % This one always gobbles spaces, + {\dodoubleempty\dosymbol} % so never change it again! + +\newif\ifnosymbol \newtoks\everysymbol + +\def\dodosymbol#1#2% \relax's prevent lookahead problems + {\nosymbolfalse{\the\everysymbol\csname\??ss:#1:#2\endcsname\relax}\relax} + +\def\directsymbol#1#2% no \relax, there can be an argument, see lists + {\executeifdefined{\??ss:#1:#2}\firstofoneargument} + +% We support both: +% +% Test test \symbol[whatever]\ test \symbol[whatever]. +% Test test \symbol{whatever} test \symbol{whatever}. + +\def\dosymbol % so we also handle \symbol{name} + {\iffirstargument % which is nicer with following spaces + \expandafter\donormalsymbol + \else + \expandafter\dospecialsymbol + \fi} + +\def\dospecialsymbol[#1][#2]#3% + {\firstargumenttrue + \secondargumentfalse + \donormalsymbol[#3][]} + +\def\donormalsymbol[#1][#2]% + {\nosymboltrue + \ifsecondargument + \edef\currentsymbol{#2}% + \doifinsymbolset{#1}{#2}{\dodosymbol{#1}{#2}}% + \else + \edef\currentsymbol{#1}% + \fi + \ifnosymbol + \the\symbolsetups + \ifnosymbol + \redosymbol\currentsymbol + \fi + \fi} + +\def\fetchsymbol#1% + {\ifnosymbol + \doifinsymbolset{#1}\currentsymbol{\dodosymbol{#1}\currentsymbol}% + \fi} + +\def\redosymbol#1% +% {\doifinsymbolsetelse\empty{#1}{\dodosymbol\empty{#1}}{#1}} % more efficient: + {\doifinsymbolsetelse\empty{#1}{\dodosymbol\empty}\firstofoneargument{#1}} + +% % % % % +% this should go in symb-fig, to be loaded after core-fig + +%D \macros +%D {definefiguresymbol} +%D +%D To simplify defining figure symbols, we offer: +%D +%D \showsetup{definefiguresymbol} +%D +%D By default, such symbols scale along the current bodyfont +%D size or running font size (which is better). + +\def\defaultsymbolfactor{10} +\def\defaultsymbolheight{1.25ex} + +\def\figuresymbol + {\dodoubleempty\dofiguresymbol} + +\ifx\externalfigure \undefined \def\externalfigure[#1][#2]{#1} \fi +\ifx\resetexternalfigures\undefined \let\resetexternalfigures\relax \fi + +\def\dofiguresymbol[#1][% #2]% + {\externalfigure[#1][\c!reset=\v!yes,\c!symbol=\v!yes,\c!height=\defaultsymbolheight,}% #2]} + +\appendtoks \resetexternalfigures \to \everysymbol + +\unexpanded\def\definefiguresymbol + {\dotripleempty\dodefinefiguresymbol} + +\def\dodefinefiguresymbol[#1][#2][#3]% + {\ifsecondargument + \definesymbol[#1][{\dofiguresymbol[#2][#3]}]% + \fi} + +% but for the moment we keep it here +% % % % % % + +%\def\objectsymbol[#1]% +% {\dopresetfieldsymbol{#1}\dogetfieldsymbol{#1}} + +%D \macros +%D {doifsymboldefinedelse} +%D +%D A handy private one: + +% a bit messy + +\def\xfetchsymbol#1% + {\ifnosymbol + \doifinsymbolset{#1}\currentsymbol\nosymbolfalse + \fi} + +\def\xredosymbol#1% + {\doifinsymbolset\empty\currentsymbol\nosymbolfalse} + +\def\doifsymboldefinedelse#1% + {\bgroup + \edef\currentsymbol{#1}% + \let\fetchsymbol\xfetchsymbol + \nosymboltrue + \the\symbolsetups + \ifnosymbol + \xredosymbol\currentsymbol + \ifnosymbol + \egroup\@EAEAEA\secondoftwoarguments + \else + \egroup\@EAEAEA\firstoftwoarguments + \fi + \else + \egroup\@EA\firstoftwoarguments + \fi} + +%D \macros +%D {setupsymbolset,startsymbolset} +%D +%D From these macro definitions one can deduce that symbols can +%D be grouped in symbol sets: +%D +%D \starttyping +%D \startsymbolset [navigation 1] +%D \definefiguresymbol [Next] [mp-symb.1] +%D \definefiguresymbol [Prev] [mp-symb.2] +%D \stopsymbolset +%D \stoptyping +%D +%D Such a symbol can be typeset with: +%D +%D \starttyping +%D \setupsymbolset[navigation 1]\symbol[Next] +%D \stoptyping +%D +%D or simply: +%D +%D \starttyping +%D \symbol[navigation 1][Next] +%D \stoptyping +%D +%D Formally: +%D +%D \showsetup{setupsymbolset} +%D \showsetup{startsymbolset} + +\let\currentsymboldef\empty + +\unexpanded\def\startsymbolset[#1] + {\def\currentsymboldef{#1}} + +\unexpanded\def\stopsymbolset + {\let\currentsymboldef\empty} + +\newtoks\symbolsetups + +\unexpanded\def\setupsymbolset[#1]% + {\prependtoksonce\fetchsymbol{#1}\to\symbolsetups} + +\def\resetsymbolset + {\symbolsetups\emptytoks} + +\def\forcesymbolset[#1]% + {\symbolsetups{\fetchsymbol{#1}}} + +%D \macros +%D {showsymbolset} +%D +%D \showsetup{showsymbolset} + +\fetchruntimecommand \showsymbolset {\f!symbolprefix\s!run.mkiv} + +%D \macros +%D {usesymbols} +%D +%D \showsetup{usesymbols} + +\def\dousesymbols#1% + {\makeshortfilename[\truefilename{\f!symbolprefix#1}]% + \startreadingfile + \readsysfile\shortfilename + {\showmessage\m!symbols1{#1}} + \donothing + \stopreadingfile} + +\def\usesymbols[#1]% + {\processcommalist[#1]\dousesymbols} + +%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. + +\protect \endinput diff --git a/tex/context/base/symb-jmn.tex b/tex/context/base/symb-jmn.tex new file mode 100644 index 000000000..1ed65d16e --- /dev/null +++ b/tex/context/base/symb-jmn.tex @@ -0,0 +1,204 @@ +%D \module +%D [ file=symb-jmn, +%D version=2004.08.02, +%D title=\CONTEXT\ Symbol Libraries, +%D subtitle=Special Navigational Symbols, +%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. + +%D This file defines a few navigational symbol vectors. The font used +%D here is designed by Janusz M.~Nowacki, one of the Polish Font +%D Gurus who made this font specially for me, hence the name. If you +%D you want to meet its designer, come to Bachotek! In case you're +%D not familiar with his work, take a look at the Antikwa, Iwona and +%D Kurier fonts! +%D +%D \usesymbols[jmn] +%D +%D \showsymbolset[navigation 1] +%D \showsymbolset[navigation 3] +%D \showsymbolset[navigation 2] +%D \showsymbolset[navigation 4] +%D +%D \page +%D \showfont[NavigationNormal] +%D \page +%D \showfont[NavigationShadowed] +%D \page + +% needed: +% +% - inverted crossed +% - curved diamond + +\unprotect + +\loadmapfile[original-base.map] % \loadmapfile [original-context-symbol.map] + +\ifnum\texengine=\luatexengine + \definefontsynonym[NavigationNormal] [hans.tfm] + \definefontsynonym[NavigationShadowed] [hans-sh.tfm] +\else + \definefontsynonym[NavigationNormal] [hans] + \definefontsynonym[NavigationShadowed] [hans-sh] +\fi + +\definefontsynonym[NavigationFont] [NavigationNormal] +%definefontsynonym[NavigationFont] [NavigationShadowed] + +\def\NavigationGlyph#1{\getglyph{NavigationFont}{\char#1}} + +\unprotect + +\startsymbolset [navigation 1] + + \definesymbol [\v!previouspage] [\NavigationGlyph {65}] + \definesymbol [\v!PreviousJump] [\NavigationGlyph{128}] + \definesymbol [\v!firstpage] [\NavigationGlyph{129}] + + \definesymbol [\v!nextpage] [\NavigationGlyph {66}] + \definesymbol [\v!NextJump] [\NavigationGlyph{130}] + \definesymbol [\v!lastpage] [\NavigationGlyph{131}] + + \definesymbol [\v!CloseDocument] [\NavigationGlyph{160}] + + \definesymbol [\v!firstsubpage] [\NavigationGlyph{178}] + \definesymbol [\v!previoussubpage] [\NavigationGlyph{208}] + \definesymbol [\v!nextsubpage] [\NavigationGlyph{209}] + \definesymbol [\v!lastsubpage] [\NavigationGlyph{178}] + + \definesymbol [\v!StartSound] [\NavigationGlyph {66}] + \definesymbol [\v!PauseSound] [\NavigationGlyph{168}] + \definesymbol [\v!StopSound] [\NavigationGlyph{170}] + + \definesymbol [\v!StartMovie] [\NavigationGlyph {66}] + \definesymbol [\v!PauseMovie] [\NavigationGlyph{168}] + \definesymbol [\v!StopMovie] [\NavigationGlyph{170}] + + \definesymbol [\v!StartRendering] [\NavigationGlyph {66}] + \definesymbol [\v!PauseRendering] [\NavigationGlyph{168}] + \definesymbol [\v!StopRendering] [\NavigationGlyph{170}] + \definesymbol [\v!ResumeRendering] [\NavigationGlyph {66}] + +\stopsymbolset + +\startsymbolset [navigation 2] + + \definesymbol [\v!previouspage] [\NavigationGlyph {67}] + \definesymbol [\v!PreviousJump] [\NavigationGlyph{132}] + \definesymbol [\v!firstpage] [\NavigationGlyph{133}] + + \definesymbol [\v!nextpage] [\NavigationGlyph {68}] + \definesymbol [\v!NextJump] [\NavigationGlyph{134}] + \definesymbol [\v!lastpage] [\NavigationGlyph{135}] + + \definesymbol [\v!CloseDocument] [\NavigationGlyph{160}] + + \definesymbol [\v!firstsubpage] [\NavigationGlyph{176}] + \definesymbol [\v!previoussubpage] [\NavigationGlyph{210}] + \definesymbol [\v!nextsubpage] [\NavigationGlyph{211}] + \definesymbol [\v!lastsubpage] [\NavigationGlyph{176}] + + \definesymbol [\v!StartSound] [\NavigationGlyph {68}] + \definesymbol [\v!PauseSound] [\NavigationGlyph{170}] + \definesymbol [\v!StopSound] [\NavigationGlyph{168}] + + \definesymbol [\v!StartMovie] [\NavigationGlyph {68}] + \definesymbol [\v!PauseMovie] [\NavigationGlyph{170}] + \definesymbol [\v!StopMovie] [\NavigationGlyph{168}] + + \definesymbol [\v!StartRendering] [\NavigationGlyph {68}] + \definesymbol [\v!PauseRendering] [\NavigationGlyph{170}] + \definesymbol [\v!StopRendering] [\NavigationGlyph{168}] + \definesymbol [\v!ResumeRendering] [\NavigationGlyph {68}] + +\stopsymbolset + +\startsymbolset [navigation 3] + + \definesymbol [\v!previouspage] [\NavigationGlyph {73}] + \definesymbol [\v!PreviousJump] [\NavigationGlyph{144}] + \definesymbol [\v!firstpage] [\NavigationGlyph{145}] + + \definesymbol [\v!nextpage] [\NavigationGlyph {74}] + \definesymbol [\v!NextJump] [\NavigationGlyph{146}] + \definesymbol [\v!lastpage] [\NavigationGlyph{147}] + + \definesymbol [\v!CloseDocument] [\NavigationGlyph{160}] + + \definesymbol [\v!firstsubpage] [\NavigationGlyph{178}] + \definesymbol [\v!previoussubpage] [\NavigationGlyph{212}] + \definesymbol [\v!nextsubpage] [\NavigationGlyph{213}] + \definesymbol [\v!lastsubpage] [\NavigationGlyph{178}] + + \definesymbol [\v!StartSound] [\NavigationGlyph {73}] + \definesymbol [\v!PauseSound] [\NavigationGlyph{168}] + \definesymbol [\v!StopSound] [\NavigationGlyph{170}] + + \definesymbol [\v!StartMovie] [\NavigationGlyph {73}] + \definesymbol [\v!PauseMovie] [\NavigationGlyph{168}] + \definesymbol [\v!StopMovie] [\NavigationGlyph{170}] + + \definesymbol [\v!StartRendering] [\NavigationGlyph {73}] + \definesymbol [\v!PauseRendering] [\NavigationGlyph{168}] + \definesymbol [\v!StopRendering] [\NavigationGlyph{170}] + \definesymbol [\v!ResumeRendering] [\NavigationGlyph {73}] + +\stopsymbolset + +% 1 left : 065 067 073 075 +% 2 left : 128 132 144 148 +% 3 left : 129 133 145 149 + +% 1 right : 066 068 074 076 +% 2 right : 130 134 146 150 +% 3 right : 131 135 147 151 + +% crossed : 160 160 160 160 +% opened : 152 152 156 156 +% closed : 154 154 158 158 + +% larrow : 208 210 212 214 +% rarrow : 209 211 213 215 +% barrow : 178 178 178 178 +% ocircle : 168 168 168 168 +% ccircle : 170 170 170 170 + +\startsymbolset [navigation 4] + + \definesymbol [\v!previouspage] [\NavigationGlyph {75}] + \definesymbol [\v!PreviousJump] [\NavigationGlyph{148}] + \definesymbol [\v!firstpage] [\NavigationGlyph{149}] + + \definesymbol [\v!nextpage] [\NavigationGlyph {76}] + \definesymbol [\v!NextJump] [\NavigationGlyph{150}] + \definesymbol [\v!lastpage] [\NavigationGlyph{151}] + + \definesymbol [\v!CloseDocument] [\NavigationGlyph{160}] + + \definesymbol [\v!firstsubpage] [\NavigationGlyph{176}] + \definesymbol [\v!previoussubpage] [\NavigationGlyph{214}] + \definesymbol [\v!nextsubpage] [\NavigationGlyph{215}] + \definesymbol [\v!lastsubpage] [\NavigationGlyph{176}] + + \definesymbol [\v!StartSound] [\NavigationGlyph {75}] + \definesymbol [\v!PauseSound] [\NavigationGlyph{170}] + \definesymbol [\v!StopSound] [\NavigationGlyph{168}] + + \definesymbol [\v!StartMovie] [\NavigationGlyph {75}] + \definesymbol [\v!PauseMovie] [\NavigationGlyph{170}] + \definesymbol [\v!StopMovie] [\NavigationGlyph{168}] + + \definesymbol [\v!StartRendering] [\NavigationGlyph {75}] + \definesymbol [\v!PauseRendering] [\NavigationGlyph{170}] + \definesymbol [\v!StopRendering] [\NavigationGlyph{168}] + \definesymbol [\v!ResumeRendering] [\NavigationGlyph {75}] + +\stopsymbolset + +\protect \endinput diff --git a/tex/context/base/symb-mis.tex b/tex/context/base/symb-mis.tex new file mode 100644 index 000000000..d108b8902 --- /dev/null +++ b/tex/context/base/symb-mis.tex @@ -0,0 +1,139 @@ +%D \module +%D [ file=symb-mis, +%D version=2002.05.07, +%D title=\CONTEXT\ Symbol Libraries, +%D subtitle=Miscelaneous, +%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. + +\unprotect + +%D We predefine some common symbols and conversions that will +%D be understood by many commands. + +% \mathematics no longer needed, although only math fonts might have these + +\definesymbol [\v!none] [] +\definesymbol [bullet] [\mathematics{\bullet}] +\definesymbol [dash] [\mathematics{-}] +\definesymbol [star] [\mathematics{\star}] +\definesymbol [triangle] [\mathematics{\triangleright}] +\definesymbol [circle] [\mathematics{\circ}] +\definesymbol [square] [\mathematics{\square}] +\definesymbol [diamond] [\mathematics{\diamond}] + +\definesymbol [smallcircle] [\hbox{\raise.1ex\hbox{\mathematics{\scriptscriptstyle\bigcirc}}}] +\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]}] +\definesymbol [4] [{\symbol[triangle]}] +\definesymbol [5] [{\symbol[circle]}] +\definesymbol [6] [{\symbol[medcircle]}] +\definesymbol [7] [{\symbol[bigcircle]}] +\definesymbol [8] [{\symbol[square]}] + +%D Special hyperlinks, namely those to pages or navigational +%D properties, are associated with symbols. + +\definesymbol [\v!firstpage] [\gotobegincharacter] +\definesymbol [\v!previouspage] [\gobackwardcharacter] +\definesymbol [\v!nextpage] [\goforwardcharacter] +\definesymbol [\v!lastpage] [\gotoendcharacter] +\definesymbol [\v!firstsubpage] [\gotobegincharacter] +\definesymbol [\v!previoussubpage] [\gobackwardcharacter] +\definesymbol [\v!nextsubpage] [\goforwardcharacter] +\definesymbol [\v!lastsubpage] [\gotoendcharacter] +\definesymbol [\v!PreviousJump] [\gobackjumpcharacter] +\definesymbol [\v!NextJump] [\goforjumpcharacter] +\definesymbol [\v!CloseDocument] [\closecharacter] + +\definesymbol [\v!first] [{\symbol[\v!firstpage]}] +\definesymbol [\v!previous] [{\symbol[\v!previouspage]}] +\definesymbol [\v!next] [{\symbol[\v!nextpage]}] +\definesymbol [\v!last] [{\symbol[\v!lastpage]}] +\definesymbol [\v!somewhere] [\gotosomewherecharacter] +\definesymbol [\v!nowhere] [\gonowherecharacter] + +\definesymbol [\v!backward] [{\symbol[\v!previouspage]}] +\definesymbol [\v!forward] [{\symbol[\v!nextpage]}] + +%D The next two symbols (\symbol[P] and \symbol[S]) are +%D variations in their math counterparts. The following ones +%D {\em do} scale. + +% todo : hook this into \textsection + +\definesymbol [S] [\getglyph{MathSymbol}{\char"78}] +\definesymbol [P] [\getglyph{MathSymbol}{\char"7B}] + +%D These symbols are taken from the Computer Moders Roman +%D symbol set or, when present, from the additional symbols of +%D the American Mathematical Society. Of course one can use +%D his or her own symbols by redefining them. + +\def\dogotocharacter#1#2#3% + {\ifx#1\undefined#2\else#3\fi} + +\def\gotobegincharacter + {\hbox + {\dogotocharacter\blacktriangleleft + {\setbox0\hbox{\mathematics{\triangleleft}}% + \vrule\!!width.085ex\!!height1.075\ht0\!!depth\dp0 + \kern-.11ex\box0} + {\setbox0\hbox{\mathematics{\blacktriangleleft}}% + \setbox2\hbox{\vrule\!!height\ht0\!!depth\dp0\!!width.25ex}% + \hbox{\lower.03ex\box2\kern-.35ex\box0}}}} + +\def\gotoendcharacter + {\hbox + {\dogotocharacter\blacktriangleright + {\setbox0\hbox{\mathematics{\triangleright}}% + \copy0\kern-.11ex + \vrule\!!width.085ex\!!height1.075\ht0\!!depth\dp0} + {\setbox0\hbox{\mathematics{\blacktriangleright}}% + \setbox2\hbox{\vrule\!!height\ht0\!!depth\dp0\!!width.25ex}% + \hbox{\box0\kern-.35ex\lower.03ex\box2}}}} + +\def\gobackwardcharacter + {\mathematics{\dogotocharacter\blacktriangleright\triangleleft\blacktriangleleft}} + +\def\goforwardcharacter + {\mathematics{\dogotocharacter\blacktriangleright\triangleright\blacktriangleright}} + +\def\gonowherecharacter + {\mathematics{\bullet}} + +\def\gotosomewherecharacter + {{\hbox{\hsmash{\symbol[\v!previous]}\symbol[\v!next]}}} + +\unexpanded\def\closecharacter + {\dogotocharacter\boxtimes + {\ruledhbox{\mathematics{\times}}} + {\mathematics{\boxtimes}}} + +\def\goforjumpcharacter + {\hbox{\goforwardcharacter \kern-.5em\goforwardcharacter}} + +\def\gobackjumpcharacter + {\hbox{\gobackwardcharacter\kern-.5em\gobackwardcharacter}} + +%D The next two symbols are for Daniel Flipo: + +\ifx\high \undefined \let\high \firstofoneargument \fi % todo +\ifx\notsmallcapped\undefined \let\notsmallcapped\firstofoneargument \fi % todo + +\definesymbol [Numero] [N\high{\notsmallcapped{o}\kern.2em}] +\definesymbol [numero] [n\high{\notsmallcapped{o}\kern.2em}] + +\def\Numero{\symbol[Numero]} +\def\numero{\symbol[numero]} + +\protect \endinput diff --git a/tex/context/base/symb-mvs.tex b/tex/context/base/symb-mvs.tex new file mode 100644 index 000000000..1dd3da0a0 --- /dev/null +++ b/tex/context/base/symb-mvs.tex @@ -0,0 +1,217 @@ +%D \module +%D [ file=symb-mvs, +%D version=2000.03.30, +%D title=\CONTEXT\ Symbol Libraries, +%D subtitle=Martin Vogels Symbole, +%D author=Tobias Burnus \& Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This module implements the Martin Vogel Symbole font +%D (marvosym). The names are derived from the \LATEX\ package +%D \type {marvosym} of Thomas Henlich. The symbols are +%D available as Type~1 font and are included in \TETEX\ and +%D \FPTEX\ distributions. +%D +%D This symbol font offers the signs of the zodiac, four +%D alternative the euro signs, some general office signs and +%D some more. +%D +%D The font was designed by Martin Vogel who can be reached at +%D \hyphenatedurl {martin.vogel@fh-bochum.de}. More information +%D can be found at \hyphenatedurl +%D {http://www.fh-bochum.de/fb1/vogel/marvosym.html}. The +%D conversion to Type~1 font was done by Thomas Henlich, who +%D can be reached at \hyphenatedurl +%D {thenlich@rcs.urz.tu-dresden.de}. +%D +%D This module is based on the current \CTAN\ version (as of +%D March 30, 2000) and is older than the TrueType version at +%D Martin Vogel's Homepage. The definitions in this module +%D reflect the \CTAN\ version. The font conversion was done by +%D Thomas Henlich using \type {ttf2pt1}, a program that can be +%D found at \hyphenatedurl +%D {http://www.netspace.net.au/~mheath/ttf2pt1/}. +%D +%D Using the new version of \type {marvosymb}, the MVzero will +%D has a slash and the FHBOLOGO, (wo)manface, and (wo)manfront +%D are replaced by other symbols. + +\loadmapfile[original-base.map] % \loadmapfile[original-vogel-symbol] + +\definefontsynonym [MartinVogel] [fmvr8x] + +\def\MartinVogelSymbol#1{\getglyph{MartinVogel}{\char#1}} + +% Astro signs and signs of the zodiac + +\startsymbolset [astronomic] + + \definesymbol [Sun] [\MartinVogelSymbol{192}] + \definesymbol [Moon] [\MartinVogelSymbol{193}] + \definesymbol [Mercury] [\MartinVogelSymbol{194}] + \definesymbol [Venus] [\MartinVogelSymbol{195}] + \definesymbol [Mars] [\MartinVogelSymbol{196}] + \definesymbol [Jupiter] [\MartinVogelSymbol{197}] + \definesymbol [Saturn] [\MartinVogelSymbol{198}] + \definesymbol [Uranus] [\MartinVogelSymbol{199}] + \definesymbol [Neptune] [\MartinVogelSymbol{200}] + \definesymbol [Pluto] [\MartinVogelSymbol{201}] + +\stopsymbolset + +\startsymbolset [zodiac] + + \definesymbol [Aries] [\MartinVogelSymbol{224}] + \definesymbol [Taurus] [\MartinVogelSymbol{225}] + \definesymbol [Gemini] [\MartinVogelSymbol{226}] + \definesymbol [Cancer] [\MartinVogelSymbol{227}] + \definesymbol [Leo] [\MartinVogelSymbol{228}] + \definesymbol [Virgo] [\MartinVogelSymbol{229}] + \definesymbol [Libra] [\MartinVogelSymbol{230}] + \definesymbol [Scorpio] [\MartinVogelSymbol{231}] + \definesymbol [Sagittarius] [\MartinVogelSymbol{232}] + \definesymbol [Capricorn] [\MartinVogelSymbol{233}] + \definesymbol [Aquarius] [\MartinVogelSymbol{234}] + \definesymbol [Pisces] [\MartinVogelSymbol{235}] + +\stopsymbolset + +% Euro signs and CE + +\startsymbolset [europe] + + \definesymbol [EUR] [\MartinVogelSymbol{164}] + \definesymbol [EURhv] [\MartinVogelSymbol {99}] + \definesymbol [EURcr] [\MartinVogelSymbol{100}] + \definesymbol [EURtm] [\MartinVogelSymbol{101}] + \definesymbol [CEsign] [\MartinVogelSymbol {67}] + +\stopsymbolset + +\startencoding[default] + + \definecharacter texteuro {\symbol[europe][EUR]} + +\stopencoding + +\unexpanded\def\euro{\doiftextelse{\texteuro}{\texteuro}{\symbol[europe][EUR]}} + +% Numbers 0 to 9, @, A and p + +% taco: are these more general, like also in zapf dingbats? + +\startsymbolset [martinvogel 1] + + \definesymbol [MVZero] [\MartinVogelSymbol {48}] + \definesymbol [MVOne] [\MartinVogelSymbol {49}] + \definesymbol [MVTwo] [\MartinVogelSymbol {50}] + \definesymbol [MVThree] [\MartinVogelSymbol {51}] + \definesymbol [MVFour] [\MartinVogelSymbol {52}] + \definesymbol [MVFive] [\MartinVogelSymbol {53}] + \definesymbol [MVSix] [\MartinVogelSymbol {54}] + \definesymbol [MVSeven] [\MartinVogelSymbol {55}] + \definesymbol [MVEight] [\MartinVogelSymbol {56}] + \definesymbol [MVNine] [\MartinVogelSymbol {57}] + \definesymbol [MVAt] [\MartinVogelSymbol {64}] + \definesymbol [MVA] [\MartinVogelSymbol{240}] + \definesymbol [MVp] [\MartinVogelSymbol{241}] + +\stopsymbolset + +% Office signs, crosses, circles, arrows + +\startsymbolset [martinvogel 2] + + \definesymbol [CheckedBox] [\MartinVogelSymbol {86}] + \definesymbol [CrossedBox] [\MartinVogelSymbol {88}] + \definesymbol [PointingHand] [\MartinVogelSymbol {90}] + \definesymbol [WritingHand] [\MartinVogelSymbol {98}] + \definesymbol [Heart] [\MartinVogelSymbol{140}] + \definesymbol [FlatSteel] [\MartinVogelSymbol{150}] + \definesymbol [Squarepipe] [\MartinVogelSymbol{151}] + \definesymbol [Rectpipe] [\MartinVogelSymbol{152}] + \definesymbol [Lsteel] [\MartinVogelSymbol{153}] + \definesymbol [TTsteel] [\MartinVogelSymbol{154}] + \definesymbol [Circpipe] [\MartinVogelSymbol{155}] + \definesymbol [Tsteel] [\MartinVogelSymbol{156}] + + \definesymbol [Stopsign] [\MartinVogelSymbol {33}] + \definesymbol [Beam] [\MartinVogelSymbol {34}] + \definesymbol [Bearing] [\MartinVogelSymbol {35}] + \definesymbol [Loosebearing] [\MartinVogelSymbol {36}] + \definesymbol [Fixedbearing] [\MartinVogelSymbol {37}] + \definesymbol [Lefttorque] [\MartinVogelSymbol {38}] + \definesymbol [Righttorque] [\MartinVogelSymbol {39}] + \definesymbol [Force] [\MartinVogelSymbol {40}] + \definesymbol [Lineload] [\MartinVogelSymbol {41}] + \definesymbol [Circles] [\MartinVogelSymbol {46}] + \definesymbol [Squaredot] [\MartinVogelSymbol{247}] + + \definesymbol [Correspondes] [\MartinVogelSymbol {61}] + \definesymbol [Vectorarrowhigh] [\MartinVogelSymbol {80}] + \definesymbol [Vectorarrow] [\MartinVogelSymbol{112}] + \definesymbol [Rightarrow] [\MartinVogelSymbol {62}] + \definesymbol [Lightning] [\MartinVogelSymbol {69}] + + \definesymbol [Snowflake] [\MartinVogelSymbol {42}] + \definesymbol [Kross] [\MartinVogelSymbol {43}] + \definesymbol [Cross] [\MartinVogelSymbol{134}] + \definesymbol [Celtcross] [\MartinVogelSymbol{135}] + \definesymbol [Ankh] [\MartinVogelSymbol{136}] + \definesymbol [Yingyang] [\MartinVogelSymbol {77}] + + \definesymbol [Pickup] [\MartinVogelSymbol {0}] % ? + \definesymbol [Letter] [\MartinVogelSymbol {66}] % ? + \definesymbol [Mobilephone] [\MartinVogelSymbol {72}] + \definesymbol [Telephone] [\MartinVogelSymbol {84}] + \definesymbol [fax] [\MartinVogelSymbol{116}] + \definesymbol [FAX] [\MartinVogelSymbol{117}] + \definesymbol [Faxmachine] [\MartinVogelSymbol{118}] + + \definesymbol [Clocklogo] [\MartinVogelSymbol {85}] + \definesymbol [Industry] [\MartinVogelSymbol {73}] + \definesymbol [Coffeecup] [\MartinVogelSymbol {75}] + \definesymbol [Info] [\MartinVogelSymbol{105}] + \definesymbol [Football] [\MartinVogelSymbol{111}] + \definesymbol [Frowny] [\MartinVogelSymbol{167}] + \definesymbol [Smiley] [\MartinVogelSymbol{169}] + \definesymbol [Bicycle] [\MartinVogelSymbol{174}] + + \definesymbol [Rightscissors] [\MartinVogelSymbol {81}] + \definesymbol [Leftscissors] [\MartinVogelSymbol {83}] + \definesymbol [Cutright] [\MartinVogelSymbol{113}] + \definesymbol [Cutleft] [\MartinVogelSymbol{115}] + \definesymbol [Kutline] [\MartinVogelSymbol {82}] % K ? + \definesymbol [Cutline] [\MartinVogelSymbol{114}] + +\stopsymbolset + +% FHBO (Fachhochschule Bochum), face, humans, bat + +\startsymbolset [martinvogel 3] + + \definesymbol [FHBOlogo] [\MartinVogelSymbol {70}] + \definesymbol [FHBOLOGO] [\MartinVogelSymbol{102}] + \definesymbol [Womanside] [\MartinVogelSymbol{204}] + \definesymbol [Manside] [\MartinVogelSymbol{205}] + \definesymbol [Womanfront] [\MartinVogelSymbol{206}] + \definesymbol [Manfront] [\MartinVogelSymbol{207}] + \definesymbol [Bat] [\MartinVogelSymbol{253}] + \definesymbol [Womanface] [\MartinVogelSymbol{254}] + \definesymbol [MartinVogel] [\MartinVogelSymbol{255}] + +\stopsymbolset + +%D \showsymbolset[astronomic] +%D \showsymbolset[zodiac] +%D \showsymbolset[europe] +%D \showsymbolset[martinvogel 1] +%D \showsymbolset[martinvogel 2] +%D \showsymbolset[martinvogel 3] + +\endinput diff --git a/tex/context/base/symb-nav.tex b/tex/context/base/symb-nav.tex new file mode 100644 index 000000000..90a798e01 --- /dev/null +++ b/tex/context/base/symb-nav.tex @@ -0,0 +1,126 @@ +%D \module +%D [ file=symb-nav, +%D version=1998.07.20, +%D title=\CONTEXT\ Symbol Libraries, +%D subtitle=Navigational Symbols, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 + +\loadmapfile[original-base.map] % \loadmapfile [original-context-symbol.map] + +\ifnum\texengine=\luatexengine + \definefontsynonym [ContextNavigation] [contnav.tfm] +\else + \definefontsynonym [ContextNavigation] [contnav] +\fi + +\def\ContextNavigationGlyph#1{\getglyph{ContextNavigation}{\char#1}} + +\startsymbolset [navigation 1] + + \definesymbol [\v!firstpage] [\ContextNavigationGlyph{3}] + \definesymbol [\v!previouspage] [\ContextNavigationGlyph{1}] + \definesymbol [\v!nextpage] [\ContextNavigationGlyph{2}] + \definesymbol [\v!lastpage] [\ContextNavigationGlyph{4}] + + \definesymbol [\v!PreviousJump] [\ContextNavigationGlyph{5}] + \definesymbol [\v!NextJump] [\ContextNavigationGlyph{6}] + + \definesymbol [\v!CloseDocument] [\ContextNavigationGlyph{7}] + + \definesymbol [\v!firstsubpage] [\ContextNavigationGlyph{3}] + \definesymbol [\v!previoussubpage] [\ContextNavigationGlyph{1}] + \definesymbol [\v!nextsubpage] [\ContextNavigationGlyph{2}] + \definesymbol [\v!lastsubpage] [\ContextNavigationGlyph{4}] + + \definesymbol [\v!StartSound] [\ContextNavigationGlyph{2}] + \definesymbol [\v!PauseSound] [\ContextNavigationGlyph{8}] + \definesymbol [\v!StopSound] [\ContextNavigationGlyph{7}] + + \definesymbol [\v!StartMovie] [\ContextNavigationGlyph{2}] + \definesymbol [\v!PauseMovie] [\ContextNavigationGlyph{8}] + \definesymbol [\v!StopMovie] [\ContextNavigationGlyph{7}] + + \definesymbol [\v!StartRendering] [\ContextNavigationGlyph{2}] + \definesymbol [\v!PauseRendering] [\ContextNavigationGlyph{8}] + \definesymbol [\v!StopRendering] [\ContextNavigationGlyph{7}] + \definesymbol [\v!ResumeRendering] [\ContextNavigationGlyph{2}] + +\stopsymbolset + +\startsymbolset [navigation 2] + + \definesymbol [\v!firstpage] [\ContextNavigationGlyph{103}] + \definesymbol [\v!previouspage] [\ContextNavigationGlyph{101}] + \definesymbol [\v!nextpage] [\ContextNavigationGlyph{102}] + \definesymbol [\v!lastpage] [\ContextNavigationGlyph{104}] + + \definesymbol [\v!PreviousJump] [\ContextNavigationGlyph{105}] + \definesymbol [\v!NextJump] [\ContextNavigationGlyph{106}] + + \definesymbol [\v!CloseDocument] [\ContextNavigationGlyph{107}] + + \definesymbol [\v!firstsubpage] [\ContextNavigationGlyph{103}] + \definesymbol [\v!previoussubpage] [\ContextNavigationGlyph{101}] + \definesymbol [\v!nextsubpage] [\ContextNavigationGlyph{102}] + \definesymbol [\v!lastsubpage] [\ContextNavigationGlyph{104}] + + \definesymbol [\v!StartSound] [\ContextNavigationGlyph{102}] + \definesymbol [\v!PauseSound] [\ContextNavigationGlyph{108}] + \definesymbol [\v!StopSound] [\ContextNavigationGlyph{107}] + + \definesymbol [\v!StartMovie] [\ContextNavigationGlyph{102}] + \definesymbol [\v!PauseMovie] [\ContextNavigationGlyph{108}] + \definesymbol [\v!StopMovie] [\ContextNavigationGlyph{107}] + + \definesymbol [\v!StartRendering] [\ContextNavigationGlyph{102}] + \definesymbol [\v!PauseRendering] [\ContextNavigationGlyph{108}] + \definesymbol [\v!StopRendering] [\ContextNavigationGlyph{107}] + \definesymbol [\v!ResumeRendering] [\ContextNavigationGlyph{102}] + +\stopsymbolset + +\startsymbolset [navigation 3] + + \definesymbol [\v!firstpage] [\ContextNavigationGlyph{203}] + \definesymbol [\v!previouspage] [\ContextNavigationGlyph{201}] + \definesymbol [\v!nextpage] [\ContextNavigationGlyph{202}] + \definesymbol [\v!lastpage] [\ContextNavigationGlyph{204}] + + \definesymbol [\v!PreviousJump] [\ContextNavigationGlyph{205}] + \definesymbol [\v!NextJump] [\ContextNavigationGlyph{206}] + + \definesymbol [\v!CloseDocument] [\ContextNavigationGlyph{207}] + + \definesymbol [\v!firstsubpage] [\ContextNavigationGlyph{203}] + \definesymbol [\v!previoussubpage] [\ContextNavigationGlyph{201}] + \definesymbol [\v!nextsubpage] [\ContextNavigationGlyph{202}] + \definesymbol [\v!lastsubpage] [\ContextNavigationGlyph{204}] + + \definesymbol [\v!StartSound] [\ContextNavigationGlyph{202}] + \definesymbol [\v!PauseSound] [\ContextNavigationGlyph{208}] + \definesymbol [\v!StopSound] [\ContextNavigationGlyph{207}] + + \definesymbol [\v!StartMovie] [\ContextNavigationGlyph{202}] + \definesymbol [\v!PauseMovie] [\ContextNavigationGlyph{208}] + \definesymbol [\v!StopMovie] [\ContextNavigationGlyph{207}] + + \definesymbol [\v!StartRendering] [\ContextNavigationGlyph{202}] + \definesymbol [\v!PauseRendering] [\ContextNavigationGlyph{208}] + \definesymbol [\v!StopRendering] [\ContextNavigationGlyph{207}] + \definesymbol [\v!ResumeRendering] [\ContextNavigationGlyph{202}] + +\stopsymbolset + +%D \showsymbolset[navigation 1] +%D \showsymbolset[navigation 2] +%D \showsymbolset[navigation 3] + +\protect \endinput diff --git a/tex/context/base/symb-run.mkii b/tex/context/base/symb-run.mkii new file mode 100644 index 000000000..4e714832c --- /dev/null +++ b/tex/context/base/symb-run.mkii @@ -0,0 +1,54 @@ +%D \module +%D [ file=symb-run, % code moved from symb-ini +%D version=1998.07.20, +%D title=\CONTEXT\ Symbol Libraries, +%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 + +\gdef\doshowsymbolset[#1][#2]% todo: make nicer, use legend or so + {\vbox\bgroup + \blank + \getparameters[\??ss][\c!n=5,#2]% + \forcesymbolset[#1]% + \doifsymbolsetelse{#1} + {\global\let\allfigures\empty + \doglobal\newcounter\figurecounter + \setupcolors[\c!state=\v!start]% to prevent mps color conversion + \dontcomplain + \def\doshowsymbols% global needed due to grouping in alignment + {\expanded{\globalprocesscommalist[\symbolset{#1}]}\docommand}% + \def\docommand##1% + {\vbox + {\forgetall + \tttf + \halign + {\hss\quad####\strut\quad\hss\cr + \symbol[##1]\quad{\red\ruledhbox{\black\symbol[##1]}}\cr + \tfx##1\cr}}% + \doglobal\increment\figurecounter + \ifnum\figurecounter=\@@ssn + \doglobal\newcounter\figurecounter + \def\next{\crcr\noalign{\vskip1ex}}% + \else + \def\next{&}% + \fi + \next}% + \tabskip\zeropoint \!!plus 1fill + \halign to \hsize + {&\hss##\hss\cr\doshowsymbols\crcr}}% + {}% + \blank + \egroup} + +\gdef\showsymbolset + {\dodoubleempty\doshowsymbolset} + +\protect \endinput diff --git a/tex/context/base/symb-run.mkiv b/tex/context/base/symb-run.mkiv new file mode 100644 index 000000000..4e714832c --- /dev/null +++ b/tex/context/base/symb-run.mkiv @@ -0,0 +1,54 @@ +%D \module +%D [ file=symb-run, % code moved from symb-ini +%D version=1998.07.20, +%D title=\CONTEXT\ Symbol Libraries, +%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 + +\gdef\doshowsymbolset[#1][#2]% todo: make nicer, use legend or so + {\vbox\bgroup + \blank + \getparameters[\??ss][\c!n=5,#2]% + \forcesymbolset[#1]% + \doifsymbolsetelse{#1} + {\global\let\allfigures\empty + \doglobal\newcounter\figurecounter + \setupcolors[\c!state=\v!start]% to prevent mps color conversion + \dontcomplain + \def\doshowsymbols% global needed due to grouping in alignment + {\expanded{\globalprocesscommalist[\symbolset{#1}]}\docommand}% + \def\docommand##1% + {\vbox + {\forgetall + \tttf + \halign + {\hss\quad####\strut\quad\hss\cr + \symbol[##1]\quad{\red\ruledhbox{\black\symbol[##1]}}\cr + \tfx##1\cr}}% + \doglobal\increment\figurecounter + \ifnum\figurecounter=\@@ssn + \doglobal\newcounter\figurecounter + \def\next{\crcr\noalign{\vskip1ex}}% + \else + \def\next{&}% + \fi + \next}% + \tabskip\zeropoint \!!plus 1fill + \halign to \hsize + {&\hss##\hss\cr\doshowsymbols\crcr}}% + {}% + \blank + \egroup} + +\gdef\showsymbolset + {\dodoubleempty\doshowsymbolset} + +\protect \endinput diff --git a/tex/context/base/symb-uni.tex b/tex/context/base/symb-uni.tex new file mode 100644 index 000000000..fcd613e7f --- /dev/null +++ b/tex/context/base/symb-uni.tex @@ -0,0 +1,1123 @@ +%D \module +%D [ file=symb-uni, +%D version=2004.11.15, +%D title=\CONTEXT\ Symbol Libraries, +%D subtitle=Unicode Symbols, +%D author=Adam T. Lindsay, +%D date=\currentdate, +%D copyright={Adam T. Lindsay / PRAGMA}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C prepared by Adam T. Lindsay. + +%D The content of this file originates from the Unicode standard, via some +%D original XSLT scripts and some hand-editing. This file is open for use +%D with the ConTeXt typesetting system. +%D +%D Adam considers the symbol names and categories to be stable, as they're +%D directly derived from the Unicode standard. +%D +%D \startitemize[packed] +%D \item Originated 2004-01-05 by Adam T. Lindsay +%D \item Updated 2004-01-16 with Unicode vector 0x27xx and some in +%D 215x and 246x +%D \item Updated 2004-11-15 to include default fonts for MacOSX and +%D \XETEX. +%D \stopitemize +%D +%D The following macros adapt to default fonts (that contain the characters) +%D in MacOSX. The font selection mechanism is likely to change once \XETEX\ +%D correctly supports \type{\doiffontcharelse}. + +\doifundefinedelse{XeTeXversion} + {\let\USymbChar \uchar + \let\USymbCharTwo \uchar + \let\USymbCharZapf\uchar} + {\def\USymbChar #1#2{\bgroup\UnicodeSymbolFont \uchar{#1}{#2}\relax\egroup} + \def\USymbCharTwo #1#2{\bgroup\UnicodeSymbolFontTwo \uchar{#1}{#2}\relax\egroup} + \def\USymbCharZapf#1#2{\bgroup\UnicodeSymbolFontZapf\uchar{#1}{#2}\relax\egroup} + \doifundefined{UnicodeSymbolFont} {\definefont[UnicodeSymbolFont] ["Apple Symbols" sa *]} + \doifundefined{UnicodeSymbolFontTwo} {\definefont[UnicodeSymbolFontTwo] ["Lucida Grande" sa *]} + \doifundefined{UnicodeSymbolFontZapf}{\definefont[UnicodeSymbolFontZapf]["Zapf Dingbats" sa *]}} + +\startsymbolset[Unicode Additional Punctuation] % 0x2000: Requires UnicodeRegular20 + + \definesymbol[Caret][\USymbChar{32}{56}] % CARET + \definesymbol[ReferenceMark][\USymbChar{32}{59}] % REFERENCE MARK + \definesymbol[DoubleExclamationMark][\USymbChar{32}{60}] % DOUBLE EXCLAMATION MARK + \definesymbol[Interrobang][\USymbChar{32}{61}] % INTERROBANG + \definesymbol[Overline][\USymbChar{32}{62}] % OVERLINE + \definesymbol[Undertie][\USymbChar{32}{63}] % UNDERTIE + \definesymbol[CharacterTie][\USymbChar{32}{64}] % CHARACTER TIE + \definesymbol[CaretInsertionPoint][\USymbChar{32}{65}] % CARET INSERTION POINT + \definesymbol[Asterism][\USymbChar{32}{66}] % ASTERISM + \definesymbol[HyphenBullet][\USymbChar{32}{67}] % HYPHEN BULLET + \definesymbol[FractionSlash][\USymbChar{32}{68}] % FRACTION SLASH + \definesymbol[LeftSquareBracketWithQuill][\USymbChar{32}{69}] % LEFT SQUARE BRACKET WITH QUILL + \definesymbol[RightSquareBracketWithQuill][\USymbChar{32}{70}] % RIGHT SQUARE BRACKET WITH QUILL + \definesymbol[QuestionExclamationMark][\USymbChar{32}{72}] % QUESTION EXCLAMATION MARK + \definesymbol[ExclamationQuestionMark][\USymbChar{32}{73}] % EXCLAMATION QUESTION MARK + \definesymbol[TironianSignEt][\USymbChar{32}{74}] % TIRONIAN SIGN ET + \definesymbol[ReversedPilcrowSign][\USymbChar{32}{75}] % REVERSED PILCROW SIGN + \definesymbol[BlackLeftwardsBullet][\USymbChar{32}{76}] % BLACK LEFTWARDS BULLET + \definesymbol[BlackRightwardsBullet][\USymbChar{32}{77}] % BLACK RIGHTWARDS BULLET + +\stopsymbolset + +\startsymbolset[Unicode Currency] % 0x20A0: Requires UnicodeRegular20 + + \definesymbol[Euro-currencySign][\USymbChar{32}{160}] % EURO-CURRENCY SIGN + \definesymbol[ColonSign][\USymbChar{32}{161}] % COLON SIGN + \definesymbol[CruzeiroSign][\USymbChar{32}{162}] % CRUZEIRO SIGN + \definesymbol[FrenchFrancSign][\USymbChar{32}{163}] % FRENCH FRANC SIGN + \definesymbol[LiraSign][\USymbChar{32}{164}] % LIRA SIGN + \definesymbol[MillSign][\USymbChar{32}{165}] % MILL SIGN + \definesymbol[NairaSign][\USymbChar{32}{166}] % NAIRA SIGN + \definesymbol[PesetaSign][\USymbChar{32}{167}] % PESETA SIGN + \definesymbol[RupeeSign][\USymbChar{32}{168}] % RUPEE SIGN + \definesymbol[WonSign][\USymbChar{32}{169}] % WON SIGN + \definesymbol[NewSheqelSign][\USymbChar{32}{170}] % NEW SHEQEL SIGN + \definesymbol[DongSign][\USymbChar{32}{171}] % DONG SIGN + \definesymbol[EuroSign][\USymbChar{32}{172}] % EURO SIGN + \definesymbol[KipSign][\USymbChar{32}{173}] % KIP SIGN + \definesymbol[TugrikSign][\USymbChar{32}{174}] % TUGRIK SIGN + \definesymbol[DrachmaSign][\USymbChar{32}{175}] % DRACHMA SIGN + \definesymbol[GermanPennySign][\USymbChar{32}{176}] % [Unassigned U+20B0] + \definesymbol[PfennigSign][\USymbChar{32}{176}] % Unofficial duplicate + \definesymbol[PesoSign][\USymbChar{32}{177}] % [Unassigned U+20B1] + +\stopsymbolset + + +\startsymbolset[Unicode Letterlike] % 0x2100: Requires UnicodeRegular21 + + \definesymbol[DegreeCelsius][\USymbChar{33}{3}] % DEGREE CELSIUS + \definesymbol[EulerConstant][\USymbChar{33}{7}] % EULER CONSTANT + \definesymbol[Scruple][\USymbChar{33}{8}] % SCRUPLE + \definesymbol[DegreeFahrenheit][\USymbChar{33}{9}] % DEGREE FAHRENHEIT + \definesymbol[PlanckConstant][\USymbChar{33}{14}] % PLANCK CONSTANT + \definesymbol[PlanckConstantOverTwoPi][\USymbChar{33}{15}] % PLANCK CONSTANT OVER TWO PI + \definesymbol[LBBarSymbol][\USymbChar{33}{20}] % L B BAR SYMBOL + \definesymbol[Versicle][\USymbChar{33}{35}] % VERSICLE + \definesymbol[OunceSign][\USymbChar{33}{37}] % OUNCE SIGN + \definesymbol[OhmSign][\USymbChar{33}{38}] % OHM SIGN + \definesymbol[InvertedOhmSign][\USymbChar{33}{39}] % INVERTED OHM SIGN + \definesymbol[KelvinSign][\USymbChar{33}{42}] % KELVIN SIGN + \definesymbol[AngstromSign][\USymbChar{33}{43}] % ANGSTROM SIGN + \definesymbol[EstimatedSymbol][\USymbChar{33}{46}] % ESTIMATED SYMBOL + +\stopsymbolset + +\startsymbolset[Unicode Letterlike Additional] % 0x2100: Requires UnicodeRegular21 + + \definesymbol[AccountOf][\USymbChar{33}{0}] % ACCOUNT OF + \definesymbol[AddressedToTheSubject][\USymbChar{33}{1}] % ADDRESSED TO THE SUBJECT + \definesymbol[CareOf][\USymbChar{33}{5}] % CARE OF + \definesymbol[CadaUna][\USymbChar{33}{6}] % CADA UNA + \definesymbol[CentreLineSymbol][\USymbChar{33}{4}] % CENTRE LINE SYMBOL + \definesymbol[NumeroSign][\USymbChar{33}{22}] % NUMERO SIGN + \definesymbol[SoundRecordingCopyright][\USymbChar{33}{23}] % SOUND RECORDING COPYRIGHT + \definesymbol[PrescriptionTake][\USymbChar{33}{30}] % PRESCRIPTION TAKE + \definesymbol[Response][\USymbChar{33}{31}] % RESPONSE + \definesymbol[ServiceMark][\USymbChar{33}{32}] % SERVICE MARK + \definesymbol[TelephoneSign][\USymbChar{33}{33}] % TELEPHONE SIGN + \definesymbol[TradeMarkSign][\USymbChar{33}{34}] % TRADE MARK SIGN + \definesymbol[InformationSource][\USymbChar{33}{57}] % INFORMATION SOURCE + \definesymbol[PropertyLine][\USymbChar{33}{74}] % [Unassigned U+214A] + +\stopsymbolset + +\startsymbolset[Unicode Script Letterlike] % 0x2100: Requires UnicodeRegular21 + + \definesymbol[ScriptSmallG][\USymbChar{33}{10}] % SCRIPT SMALL G + \definesymbol[ScriptCapitalH][\USymbChar{33}{11}] % SCRIPT CAPITAL H + \definesymbol[ScriptCapitalI][\USymbChar{33}{16}] % SCRIPT CAPITAL I + \definesymbol[ScriptCapitalL][\USymbChar{33}{18}] % SCRIPT CAPITAL L + \definesymbol[ScriptSmallL][\USymbChar{33}{19}] % SCRIPT SMALL L + \definesymbol[ScriptCapitalP][\USymbChar{33}{24}] % SCRIPT CAPITAL P + \definesymbol[ScriptCapitalR][\USymbChar{33}{27}] % SCRIPT CAPITAL R + \definesymbol[ScriptSmallE][\USymbChar{33}{47}] % SCRIPT SMALL E + \definesymbol[ScriptCapitalE][\USymbChar{33}{48}] % SCRIPT CAPITAL E + \definesymbol[ScriptCapitalF][\USymbChar{33}{49}] % SCRIPT CAPITAL F + \definesymbol[ScriptCapitalB][\USymbChar{33}{44}] % SCRIPT CAPITAL B + \definesymbol[ScriptCapitalM][\USymbChar{33}{51}] % SCRIPT CAPITAL M + \definesymbol[ScriptSmallO][\USymbChar{33}{52}] % SCRIPT SMALL O + +\stopsymbolset + +\startsymbolset[Unicode Hebrew Letterlike] % 0x2100: Requires UnicodeRegular21 + + \definesymbol[AlefSymbol][\USymbChar{33}{53}] % ALEF SYMBOL + \definesymbol[BetSymbol][\USymbChar{33}{54}] % BET SYMBOL + \definesymbol[GimelSymbol][\USymbChar{33}{55}] % GIMEL SYMBOL + \definesymbol[DaletSymbol][\USymbChar{33}{56}] % DALET SYMBOL + +\stopsymbolset + +\startsymbolset[Unicode Turned Letterlike] % 0x2100: Requires UnicodeRegular21 + + \definesymbol[RotatedCapitalQ][\USymbChar{33}{58}] % ROTATED CAPITAL Q + \definesymbol[TurnedSansSerifCapitalG][\USymbChar{33}{65}] % [Unassigned U+2141] + \definesymbol[TurnedSansSerifCapitalL][\USymbChar{33}{66}] % [Unassigned U+2142] + \definesymbol[ReversedSansSerifCapitalL][\USymbChar{33}{67}] % [Unassigned U+2143] + \definesymbol[TurnedSansSerifCapitalY][\USymbChar{33}{68}] % [Unassigned U+2144] + \definesymbol[TurnedAmpersand][\USymbChar{33}{75}] % [Unassigned U+214B] + \definesymbol[TurnedGreekSmallLetterIota][\USymbChar{33}{41}] % TURNED GREEK SMALL LETTER IOTA + \definesymbol[TurnedCapitalF][\USymbChar{33}{50}] % TURNED CAPITAL F + +\stopsymbolset + +\startsymbolset[Unicode Black-letter Letterlike] % 0x2100: Requires UnicodeRegular21 + + \definesymbol[BlackLetterCapitalH][\USymbChar{33}{12}] % BLACK-LETTER CAPITAL H + \definesymbol[BlackLetterCapitalI][\USymbChar{33}{17}] % BLACK-LETTER CAPITAL I + \definesymbol[BlackLetterCapitalR][\USymbChar{33}{28}] % BLACK-LETTER CAPITAL R + \definesymbol[BlackLetterCapitalZ][\USymbChar{33}{40}] % BLACK-LETTER CAPITAL Z + \definesymbol[BlackLetterCapitalC][\USymbChar{33}{45}] % BLACK-LETTER CAPITAL C + +\stopsymbolset + +\startsymbolset[Unicode Double-struck Letterlike Math] % 0x2100: Requires UnicodeRegular21 + + \definesymbol[DoubleStruckCapitalC][\USymbChar{33}{2}] % DOUBLE-STRUCK CAPITAL C + \definesymbol[DoubleStruckCapitalH][\USymbChar{33}{13}] % DOUBLE-STRUCK CAPITAL H + \definesymbol[DoubleStruckCapitalN][\USymbChar{33}{21}] % DOUBLE-STRUCK CAPITAL N + \definesymbol[DoubleStruckCapitalP][\USymbChar{33}{25}] % DOUBLE-STRUCK CAPITAL P + \definesymbol[DoubleStruckCapitalQ][\USymbChar{33}{26}] % DOUBLE-STRUCK CAPITAL Q + \definesymbol[DoubleStruckCapitalR][\USymbChar{33}{29}] % DOUBLE-STRUCK CAPITAL R + \definesymbol[DoubleStruckCapitalZ][\USymbChar{33}{36}] % DOUBLE-STRUCK CAPITAL Z + \definesymbol[DoubleStruckSmallGamma][\USymbChar{33}{61}] % [Unassigned U+213D] + \definesymbol[DoubleStruckCapitalGamma][\USymbChar{33}{62}] % [Unassigned U+213E] + \definesymbol[DoubleStruckCapitalPi][\USymbChar{33}{63}] % [Unassigned U+213F] + \definesymbol[DoubleStruckNArySummation][\USymbChar{33}{64}] % [Unassigned U+2140] + \definesymbol[DoubleStruckItalicCapitalD][\USymbChar{33}{69}] % [Unassigned U+2145] + \definesymbol[DoubleStruckItalicSmallD][\USymbChar{33}{70}] % [Unassigned U+2146] + \definesymbol[DoubleStruckItalicSmallE][\USymbChar{33}{71}] % [Unassigned U+2147] + \definesymbol[DoubleStruckItalicSmallI][\USymbChar{33}{72}] % [Unassigned U+2148] + \definesymbol[DoubleStruckItalicSmallJ][\USymbChar{33}{73}] % [Unassigned U+2149] + +\stopsymbolset + +\startsymbolset[Unicode Roman Numerals] % 0x2150: Requires UnicodeRegular21 + + \definesymbol[RomanNumeralOne][\USymbCharTwo{33}{96}] % ROMAN NUMERAL ONE + \definesymbol[RomanNumeralTwo][\USymbCharTwo{33}{97}] % ROMAN NUMERAL TWO + \definesymbol[RomanNumeralThree][\USymbCharTwo{33}{98}] % ROMAN NUMERAL THREE + \definesymbol[RomanNumeralFour][\USymbCharTwo{33}{99}] % ROMAN NUMERAL FOUR + \definesymbol[RomanNumeralFive][\USymbCharTwo{33}{100}] % ROMAN NUMERAL FIVE + \definesymbol[RomanNumeralSix][\USymbCharTwo{33}{101}] % ROMAN NUMERAL SIX + \definesymbol[RomanNumeralSeven][\USymbCharTwo{33}{102}] % ROMAN NUMERAL SEVEN + \definesymbol[RomanNumeralEight][\USymbCharTwo{33}{103}] % ROMAN NUMERAL EIGHT + \definesymbol[RomanNumeralNine][\USymbCharTwo{33}{104}] % ROMAN NUMERAL NINE + \definesymbol[RomanNumeralTen][\USymbCharTwo{33}{105}] % ROMAN NUMERAL TEN + \definesymbol[RomanNumeralEleven][\USymbCharTwo{33}{106}] % ROMAN NUMERAL ELEVEN + \definesymbol[RomanNumeralTwelve][\USymbCharTwo{33}{107}] % ROMAN NUMERAL TWELVE + \definesymbol[RomanNumeralFifty][\USymbCharTwo{33}{108}] % ROMAN NUMERAL FIFTY + \definesymbol[RomanNumeralOneHundred][\USymbCharTwo{33}{109}] % ROMAN NUMERAL ONE HUNDRED + \definesymbol[RomanNumeralFiveHundred][\USymbCharTwo{33}{110}] % ROMAN NUMERAL FIVE HUNDRED + \definesymbol[RomanNumeralOneThousand][\USymbCharTwo{33}{111}] % ROMAN NUMERAL ONE THOUSAND + \definesymbol[RomanNumeralOneThousandCD][\USymbCharTwo{33}{128}] % ROMAN NUMERAL ONE THOUSAND C D + \definesymbol[RomanNumeralFiveThousand][\USymbCharTwo{33}{129}] % ROMAN NUMERAL FIVE THOUSAND + \definesymbol[RomanNumeralTenThousand][\USymbCharTwo{33}{130}] % ROMAN NUMERAL TEN THOUSAND + \definesymbol[RomanNumeralReversedOneHundred][\USymbCharTwo{33}{131}] % ROMAN NUMERAL REVERSED ONE HUNDRED + +\stopsymbolset + +\startsymbolset[Unicode Small Roman Numerals] % 0x2150: Requires UnicodeRegular21 + + \definesymbol[SmallRomanNumeralOne][\USymbCharTwo{33}{112}] % SMALL ROMAN NUMERAL ONE + \definesymbol[SmallRomanNumeralTwo][\USymbCharTwo{33}{113}] % SMALL ROMAN NUMERAL TWO + \definesymbol[SmallRomanNumeralThree][\USymbCharTwo{33}{114}] % SMALL ROMAN NUMERAL THREE + \definesymbol[SmallRomanNumeralFour][\USymbCharTwo{33}{115}] % SMALL ROMAN NUMERAL FOUR + \definesymbol[SmallRomanNumeralFive][\USymbCharTwo{33}{116}] % SMALL ROMAN NUMERAL FIVE + \definesymbol[SmallRomanNumeralSix][\USymbCharTwo{33}{117}] % SMALL ROMAN NUMERAL SIX + \definesymbol[SmallRomanNumeralSeven][\USymbCharTwo{33}{118}] % SMALL ROMAN NUMERAL SEVEN + \definesymbol[SmallRomanNumeralEight][\USymbCharTwo{33}{119}] % SMALL ROMAN NUMERAL EIGHT + \definesymbol[SmallRomanNumeralNine][\USymbCharTwo{33}{120}] % SMALL ROMAN NUMERAL NINE + \definesymbol[SmallRomanNumeralTen][\USymbCharTwo{33}{121}] % SMALL ROMAN NUMERAL TEN + \definesymbol[SmallRomanNumeralEleven][\USymbCharTwo{33}{122}] % SMALL ROMAN NUMERAL ELEVEN + \definesymbol[SmallRomanNumeralTwelve][\USymbCharTwo{33}{123}] % SMALL ROMAN NUMERAL TWELVE + \definesymbol[SmallRomanNumeralFifty][\USymbCharTwo{33}{124}] % SMALL ROMAN NUMERAL FIFTY + \definesymbol[SmallRomanNumeralOneHundred][\USymbCharTwo{33}{125}] % SMALL ROMAN NUMERAL ONE HUNDRED + \definesymbol[SmallRomanNumeralFiveHundred][\USymbCharTwo{33}{126}] % SMALL ROMAN NUMERAL FIVE HUNDRED + \definesymbol[SmallRomanNumeralOneThousand][\USymbCharTwo{33}{127}] % SMALL ROMAN NUMERAL ONE THOUSAND + +\stopsymbolset + +\startsymbolset[Unicode Arrows] % 0x2190: Requires UnicodeRegular21 + + \definesymbol[LeftwardsArrow][\USymbChar{33}{144}] % LEFTWARDS ARROW + \definesymbol[UpwardsArrow][\USymbChar{33}{145}] % UPWARDS ARROW + \definesymbol[RightwardsArrow][\USymbChar{33}{146}] % RIGHTWARDS ARROW + \definesymbol[DownwardsArrow][\USymbChar{33}{147}] % DOWNWARDS ARROW + \definesymbol[LeftRightArrow][\USymbChar{33}{148}] % LEFT RIGHT ARROW + \definesymbol[UpDownArrow][\USymbChar{33}{149}] % UP DOWN ARROW + \definesymbol[NorthWestArrow][\USymbChar{33}{150}] % NORTH WEST ARROW + \definesymbol[NorthEastArrow][\USymbChar{33}{151}] % NORTH EAST ARROW + \definesymbol[SouthEastArrow][\USymbChar{33}{152}] % SOUTH EAST ARROW + \definesymbol[SouthWestArrow][\USymbChar{33}{153}] % SOUTH WEST ARROW + \definesymbol[LeftwardsArrowWithStroke][\USymbChar{33}{154}] % LEFTWARDS ARROW WITH STROKE + \definesymbol[RightwardsArrowWithStroke][\USymbChar{33}{155}] % RIGHTWARDS ARROW WITH STROKE + \definesymbol[LeftwardsWaveArrow][\USymbChar{33}{156}] % LEFTWARDS WAVE ARROW + \definesymbol[RightwardsWaveArrow][\USymbChar{33}{157}] % RIGHTWARDS WAVE ARROW + \definesymbol[LeftwardsTwoHeadedArrow][\USymbChar{33}{158}] % LEFTWARDS TWO HEADED ARROW + \definesymbol[UpwardsTwoHeadedArrow][\USymbChar{33}{159}] % UPWARDS TWO HEADED ARROW + \definesymbol[RightwardsTwoHeadedArrow][\USymbChar{33}{160}] % RIGHTWARDS TWO HEADED ARROW + \definesymbol[DownwardsTwoHeadedArrow][\USymbChar{33}{161}] % DOWNWARDS TWO HEADED ARROW + \definesymbol[LeftwardsArrowWithTail][\USymbChar{33}{162}] % LEFTWARDS ARROW WITH TAIL + \definesymbol[RightwardsArrowWithTail][\USymbChar{33}{163}] % RIGHTWARDS ARROW WITH TAIL + \definesymbol[LeftwardsArrowFromBar][\USymbChar{33}{164}] % LEFTWARDS ARROW FROM BAR + \definesymbol[UpwardsArrowFromBar][\USymbChar{33}{165}] % UPWARDS ARROW FROM BAR + \definesymbol[RightwardsArrowFromBar][\USymbChar{33}{166}] % RIGHTWARDS ARROW FROM BAR + \definesymbol[DownwardsArrowFromBar][\USymbChar{33}{167}] % DOWNWARDS ARROW FROM BAR + \definesymbol[UpDownArrowWithBase][\USymbChar{33}{168}] % UP DOWN ARROW WITH BASE + \definesymbol[LeftwardsArrowWithHook][\USymbChar{33}{169}] % LEFTWARDS ARROW WITH HOOK + \definesymbol[RightwardsArrowWithHook][\USymbChar{33}{170}] % RIGHTWARDS ARROW WITH HOOK + \definesymbol[LeftwardsArrowWithLoop][\USymbChar{33}{171}] % LEFTWARDS ARROW WITH LOOP + \definesymbol[RightwardsArrowWithLoop][\USymbChar{33}{172}] % RIGHTWARDS ARROW WITH LOOP + \definesymbol[LeftRightWaveArrow][\USymbChar{33}{173}] % LEFT RIGHT WAVE ARROW + \definesymbol[LeftRightArrowWithStroke][\USymbChar{33}{174}] % LEFT RIGHT ARROW WITH STROKE + \definesymbol[DownwardsZigzagArrow][\USymbChar{33}{175}] % DOWNWARDS ZIGZAG ARROW + \definesymbol[UpwardsArrowWithTipLeftwards][\USymbChar{33}{176}] % UPWARDS ARROW WITH TIP LEFTWARDS + \definesymbol[UpwardsArrowWithTipRightwards][\USymbChar{33}{177}] % UPWARDS ARROW WITH TIP RIGHTWARDS + \definesymbol[DownwardsArrowWithTipLeftwards][\USymbChar{33}{178}] % DOWNWARDS ARROW WITH TIP LEFTWARDS + \definesymbol[DownwardsArrowWithTipRightwards][\USymbChar{33}{179}] % DOWNWARDS ARROW WITH TIP RIGHTWARDS + \definesymbol[RightwardsArrowWithCornerDownwards][\USymbChar{33}{180}] % RIGHTWARDS ARROW WITH CORNER DOWNWARDS + \definesymbol[DownwardsArrowWithCornerLeftwards][\USymbChar{33}{181}] % DOWNWARDS ARROW WITH CORNER LEFTWARDS + \definesymbol[AnticlockwiseTopSemicircleArrow][\USymbChar{33}{182}] % ANTICLOCKWISE TOP SEMICIRCLE ARROW + \definesymbol[ClockwiseTopSemicircleArrow][\USymbChar{33}{183}] % CLOCKWISE TOP SEMICIRCLE ARROW + \definesymbol[NorthWestArrowToLongBar][\USymbChar{33}{184}] % NORTH WEST ARROW TO LONG BAR + \definesymbol[AnticlockwiseOpenCircleArrow][\USymbChar{33}{186}] % ANTICLOCKWISE OPEN CIRCLE ARROW + \definesymbol[ClockwiseOpenCircleArrow][\USymbChar{33}{187}] % CLOCKWISE OPEN CIRCLE ARROW + \definesymbol[LeftwardsHarpoonWithBarbUpwards][\USymbChar{33}{188}] % LEFTWARDS HARPOON WITH BARB UPWARDS + \definesymbol[LeftwardsHarpoonWithBarbDownwards][\USymbChar{33}{189}] % LEFTWARDS HARPOON WITH BARB DOWNWARDS + \definesymbol[UpwardsHarpoonWithBarbRightwards][\USymbChar{33}{190}] % UPWARDS HARPOON WITH BARB RIGHTWARDS + \definesymbol[UpwardsHarpoonWithBarbLeftwards][\USymbChar{33}{191}] % UPWARDS HARPOON WITH BARB LEFTWARDS + \definesymbol[RightwardsHarpoonWithBarbUpwards][\USymbChar{33}{192}] % RIGHTWARDS HARPOON WITH BARB UPWARDS + \definesymbol[RightwardsHarpoonWithBarbDownwards][\USymbChar{33}{193}] % RIGHTWARDS HARPOON WITH BARB DOWNWARDS + \definesymbol[DownwardsHarpoonWithBarbRightwards][\USymbChar{33}{194}] % DOWNWARDS HARPOON WITH BARB RIGHTWARDS + \definesymbol[DownwardsHarpoonWithBarbLeftwards][\USymbChar{33}{195}] % DOWNWARDS HARPOON WITH BARB LEFTWARDS + \definesymbol[LeftwardsSquiggleArrow][\USymbChar{33}{220}] % LEFTWARDS SQUIGGLE ARROW + \definesymbol[RightwardsSquiggleArrow][\USymbChar{33}{221}] % RIGHTWARDS SQUIGGLE ARROW + \definesymbol[UpwardsArrowWithDoubleStroke][\USymbChar{33}{222}] % UPWARDS ARROW WITH DOUBLE STROKE + \definesymbol[DownwardsArrowWithDoubleStroke][\USymbChar{33}{223}] % DOWNWARDS ARROW WITH DOUBLE STROKE + \definesymbol[LeftwardsDashedArrow][\USymbChar{33}{224}] % LEFTWARDS DASHED ARROW + \definesymbol[UpwardsDashedArrow][\USymbChar{33}{225}] % UPWARDS DASHED ARROW + \definesymbol[RightwardsDashedArrow][\USymbChar{33}{226}] % RIGHTWARDS DASHED ARROW + \definesymbol[DownwardsDashedArrow][\USymbChar{33}{227}] % DOWNWARDS DASHED ARROW + \definesymbol[LeftwardsArrowToBar][\USymbChar{33}{228}] % LEFTWARDS ARROW TO BAR + \definesymbol[RightwardsArrowToBar][\USymbChar{33}{229}] % RIGHTWARDS ARROW TO BAR + \definesymbol[LeftwardsWhiteArrow][\USymbChar{33}{230}] % LEFTWARDS WHITE ARROW + \definesymbol[UpwardsWhiteArrow][\USymbChar{33}{231}] % UPWARDS WHITE ARROW + \definesymbol[RightwardsWhiteArrow][\USymbChar{33}{232}] % RIGHTWARDS WHITE ARROW + \definesymbol[DownwardsWhiteArrow][\USymbChar{33}{233}] % DOWNWARDS WHITE ARROW + \definesymbol[UpwardsWhiteArrowFromBar][\USymbChar{33}{234}] % UPWARDS WHITE ARROW FROM BAR + \definesymbol[UpwardsWhiteArrowOnPedestal][\USymbChar{33}{235}] % UPWARDS WHITE ARROW ON PEDESTAL + \definesymbol[UpwardsWhiteArrowOnPedestalWithHorizontalBar][\USymbChar{33}{236}] % UPWARDS WHITE ARROW ON PEDESTAL WITH HORIZONTAL BAR + \definesymbol[UpwardsWhiteArrowOnPedestalWithVerticalBar][\USymbChar{33}{237}] % UPWARDS WHITE ARROW ON PEDESTAL WITH VERTICAL BAR + \definesymbol[RightwardsWhiteArrowFromWall][\USymbChar{33}{240}] % RIGHTWARDS WHITE ARROW FROM WALL + \definesymbol[NorthWestArrowToCorner][\USymbChar{33}{241}] % NORTH WEST ARROW TO CORNER + \definesymbol[SouthEastArrowToCorner][\USymbChar{33}{242}] % SOUTH EAST ARROW TO CORNER + \definesymbol[UpDownWhiteArrow][\USymbChar{33}{243}] % UP DOWN WHITE ARROW + +\stopsymbolset + +\startsymbolset[Unicode Multi Arrows] % 0x2190: Requires UnicodeRegular21 + + \definesymbol[LeftwardsArrowToBarOverRightwardsArrowToBar][\USymbChar{33}{185}] % LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR + \definesymbol[RightwardsArrowOverLeftwardsArrow][\USymbChar{33}{196}] % RIGHTWARDS ARROW OVER LEFTWARDS ARROW + \definesymbol[UpwardsArrowLeftwardsOfDownwardsArrow][\USymbChar{33}{197}] % UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW + \definesymbol[LeftwardsArrowOverRightwardsArrow][\USymbChar{33}{198}] % LEFTWARDS ARROW OVER RIGHTWARDS ARROW + \definesymbol[LeftwardsPairedArrows][\USymbChar{33}{199}] % LEFTWARDS PAIRED ARROWS + \definesymbol[UpwardsPairedArrows][\USymbChar{33}{200}] % UPWARDS PAIRED ARROWS + \definesymbol[RightwardsPairedArrows][\USymbChar{33}{201}] % RIGHTWARDS PAIRED ARROWS + \definesymbol[DownwardsPairedArrows][\USymbChar{33}{202}] % DOWNWARDS PAIRED ARROWS + \definesymbol[LeftwardsHarpoonOverRightwardsHarpoon][\USymbChar{33}{203}] % LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON + \definesymbol[RightwardsHarpoonOverLeftwardsHarpoon][\USymbChar{33}{204}] % RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON + \definesymbol[LeftwardsDoubleArrowWithStroke][\USymbChar{33}{205}] % LEFTWARDS DOUBLE ARROW WITH STROKE + \definesymbol[LeftRightDoubleArrowWithStroke][\USymbChar{33}{206}] % LEFT RIGHT DOUBLE ARROW WITH STROKE + \definesymbol[RightwardsDoubleArrowWithStroke][\USymbChar{33}{207}] % RIGHTWARDS DOUBLE ARROW WITH STROKE + \definesymbol[LeftwardsDoubleArrow][\USymbChar{33}{208}] % LEFTWARDS DOUBLE ARROW + \definesymbol[UpwardsDoubleArrow][\USymbChar{33}{209}] % UPWARDS DOUBLE ARROW + \definesymbol[RightwardsDoubleArrow][\USymbChar{33}{210}] % RIGHTWARDS DOUBLE ARROW + \definesymbol[DownwardsDoubleArrow][\USymbChar{33}{211}] % DOWNWARDS DOUBLE ARROW + \definesymbol[LeftRightDoubleArrow][\USymbChar{33}{212}] % LEFT RIGHT DOUBLE ARROW + \definesymbol[UpDownDoubleArrow][\USymbChar{33}{213}] % UP DOWN DOUBLE ARROW + \definesymbol[NorthWestDoubleArrow][\USymbChar{33}{214}] % NORTH WEST DOUBLE ARROW + \definesymbol[NorthEastDoubleArrow][\USymbChar{33}{215}] % NORTH EAST DOUBLE ARROW + \definesymbol[SouthEastDoubleArrow][\USymbChar{33}{216}] % SOUTH EAST DOUBLE ARROW + \definesymbol[SouthWestDoubleArrow][\USymbChar{33}{217}] % SOUTH WEST DOUBLE ARROW + \definesymbol[LeftwardsTripleArrow][\USymbChar{33}{218}] % LEFTWARDS TRIPLE ARROW + \definesymbol[RightwardsTripleArrow][\USymbChar{33}{219}] % RIGHTWARDS TRIPLE ARROW + \definesymbol[UpwardsWhiteDoubleArrow][\USymbChar{33}{238}] % UPWARDS WHITE DOUBLE ARROW + \definesymbol[UpwardsWhiteDoubleArrowOnPedestal][\USymbChar{33}{239}] % UPWARDS WHITE DOUBLE ARROW ON PEDESTAL + +\stopsymbolset + + +\startsymbolset[Unicode Optical Character Recognition] % 0x2440: Requires UnicodeRegular24 + + \definesymbol[OcrHook][\USymbChar{36}{64}] % OCR HOOK + \definesymbol[OcrChair][\USymbChar{36}{65}] % OCR CHAIR + \definesymbol[OcrFork][\USymbChar{36}{66}] % OCR FORK + \definesymbol[OcrInvertedFork][\USymbChar{36}{67}] % OCR INVERTED FORK + \definesymbol[OcrBeltBuckle][\USymbChar{36}{68}] % OCR BELT BUCKLE + \definesymbol[OcrBowTie][\USymbChar{36}{69}] % OCR BOW TIE + \definesymbol[OcrBranchBankIdentification][\USymbChar{36}{70}] % OCR BRANCH BANK IDENTIFICATION + \definesymbol[OcrAmountOfCheck][\USymbChar{36}{71}] % OCR AMOUNT OF CHECK + \definesymbol[OcrDash][\USymbChar{36}{72}] % OCR DASH + \definesymbol[OcrCustomerAccountNumber][\USymbChar{36}{73}] % OCR CUSTOMER ACCOUNT NUMBER + \definesymbol[OcrDoubleBackslash][\USymbChar{36}{74}] % OCR DOUBLE BACKSLASH + +\stopsymbolset + + +\startsymbolset[Unicode Box Drawing] % 0x2500: Requires UnicodeRegular25 + + \definesymbol[LightHorizontal][\USymbChar{37}{0}] % BOX DRAWINGS LIGHT HORIZONTAL + \definesymbol[HeavyHorizontal][\USymbChar{37}{1}] % BOX DRAWINGS HEAVY HORIZONTAL + \definesymbol[LightVertical][\USymbChar{37}{2}] % BOX DRAWINGS LIGHT VERTICAL + \definesymbol[HeavyVertical][\USymbChar{37}{3}] % BOX DRAWINGS HEAVY VERTICAL + \definesymbol[LightTripleDashHorizontal][\USymbChar{37}{4}] % BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL + \definesymbol[HeavyTripleDashHorizontal][\USymbChar{37}{5}] % BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL + \definesymbol[LightTripleDashVertical][\USymbChar{37}{6}] % BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL + \definesymbol[HeavyTripleDashVertical][\USymbChar{37}{7}] % BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL + \definesymbol[LightQuadrupleDashHorizontal][\USymbChar{37}{8}] % BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL + \definesymbol[HeavyQuadrupleDashHorizontal][\USymbChar{37}{9}] % BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL + \definesymbol[LightQuadrupleDashVertical][\USymbChar{37}{10}] % BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL + \definesymbol[HeavyQuadrupleDashVertical][\USymbChar{37}{11}] % BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL + \definesymbol[LightDownAndRight][\USymbChar{37}{12}] % BOX DRAWINGS LIGHT DOWN AND RIGHT + \definesymbol[DownLightAndRightHeavy][\USymbChar{37}{13}] % BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY + \definesymbol[DownHeavyAndRightLight][\USymbChar{37}{14}] % BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT + \definesymbol[HeavyDownAndRight][\USymbChar{37}{15}] % BOX DRAWINGS HEAVY DOWN AND RIGHT + \definesymbol[LightDownAndLeft][\USymbChar{37}{16}] % BOX DRAWINGS LIGHT DOWN AND LEFT + \definesymbol[DownLightAndLeftHeavy][\USymbChar{37}{17}] % BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY + \definesymbol[DownHeavyAndLeftLight][\USymbChar{37}{18}] % BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT + \definesymbol[HeavyDownAndLeft][\USymbChar{37}{19}] % BOX DRAWINGS HEAVY DOWN AND LEFT + \definesymbol[LightUpAndRight][\USymbChar{37}{20}] % BOX DRAWINGS LIGHT UP AND RIGHT + \definesymbol[UpLightAndRightHeavy][\USymbChar{37}{21}] % BOX DRAWINGS UP LIGHT AND RIGHT HEAVY + \definesymbol[UpHeavyAndRightLight][\USymbChar{37}{22}] % BOX DRAWINGS UP HEAVY AND RIGHT LIGHT + \definesymbol[HeavyUpAndRight][\USymbChar{37}{23}] % BOX DRAWINGS HEAVY UP AND RIGHT + \definesymbol[LightUpAndLeft][\USymbChar{37}{24}] % BOX DRAWINGS LIGHT UP AND LEFT + \definesymbol[UpLightAndLeftHeavy][\USymbChar{37}{25}] % BOX DRAWINGS UP LIGHT AND LEFT HEAVY + \definesymbol[UpHeavyAndLeftLight][\USymbChar{37}{26}] % BOX DRAWINGS UP HEAVY AND LEFT LIGHT + \definesymbol[HeavyUpAndLeft][\USymbChar{37}{27}] % BOX DRAWINGS HEAVY UP AND LEFT + \definesymbol[LightVerticalAndRight][\USymbChar{37}{28}] % BOX DRAWINGS LIGHT VERTICAL AND RIGHT + \definesymbol[VerticalLightAndRightHeavy][\USymbChar{37}{29}] % BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY + \definesymbol[UpHeavyAndRightDownLight][\USymbChar{37}{30}] % BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT + \definesymbol[DownHeavyAndRightUpLight][\USymbChar{37}{31}] % BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT + \definesymbol[VerticalHeavyAndRightLight][\USymbChar{37}{32}] % BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT + \definesymbol[DownLightAndRightUpHeavy][\USymbChar{37}{33}] % BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY + \definesymbol[UpLightAndRightDownHeavy][\USymbChar{37}{34}] % BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY + \definesymbol[HeavyVerticalAndRight][\USymbChar{37}{35}] % BOX DRAWINGS HEAVY VERTICAL AND RIGHT + \definesymbol[LightVerticalAndLeft][\USymbChar{37}{36}] % BOX DRAWINGS LIGHT VERTICAL AND LEFT + \definesymbol[VerticalLightAndLeftHeavy][\USymbChar{37}{37}] % BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY + \definesymbol[UpHeavyAndLeftDownLight][\USymbChar{37}{38}] % BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT + \definesymbol[DownHeavyAndLeftUpLight][\USymbChar{37}{39}] % BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT + \definesymbol[VerticalHeavyAndLeftLight][\USymbChar{37}{40}] % BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT + \definesymbol[DownLightAndLeftUpHeavy][\USymbChar{37}{41}] % BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY + \definesymbol[UpLightAndLeftDownHeavy][\USymbChar{37}{42}] % BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY + \definesymbol[HeavyVerticalAndLeft][\USymbChar{37}{43}] % BOX DRAWINGS HEAVY VERTICAL AND LEFT + \definesymbol[LightDownAndHorizontal][\USymbChar{37}{44}] % BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + \definesymbol[LeftHeavyAndRightDownLight][\USymbChar{37}{45}] % BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT + \definesymbol[RightHeavyAndLeftDownLight][\USymbChar{37}{46}] % BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT + \definesymbol[DownLightAndHorizontalHeavy][\USymbChar{37}{47}] % BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY + \definesymbol[DownHeavyAndHorizontalLight][\USymbChar{37}{48}] % BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT + \definesymbol[RightLightAndLeftDownHeavy][\USymbChar{37}{49}] % BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY + \definesymbol[LeftLightAndRightDownHeavy][\USymbChar{37}{50}] % BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY + \definesymbol[HeavyDownAndHorizontal][\USymbChar{37}{51}] % BOX DRAWINGS HEAVY DOWN AND HORIZONTAL + \definesymbol[LightUpAndHorizontal][\USymbChar{37}{52}] % BOX DRAWINGS LIGHT UP AND HORIZONTAL + \definesymbol[LeftHeavyAndRightUpLight][\USymbChar{37}{53}] % BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT + \definesymbol[RightHeavyAndLeftUpLight][\USymbChar{37}{54}] % BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT + \definesymbol[UpLightAndHorizontalHeavy][\USymbChar{37}{55}] % BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY + \definesymbol[UpHeavyAndHorizontalLight][\USymbChar{37}{56}] % BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT + \definesymbol[RightLightAndLeftUpHeavy][\USymbChar{37}{57}] % BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY + \definesymbol[LeftLightAndRightUpHeavy][\USymbChar{37}{58}] % BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY + \definesymbol[HeavyUpAndHorizontal][\USymbChar{37}{59}] % BOX DRAWINGS HEAVY UP AND HORIZONTAL + \definesymbol[LightVerticalAndHorizontal][\USymbChar{37}{60}] % BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + \definesymbol[LeftHeavyAndRightVerticalLight][\USymbChar{37}{61}] % BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT + \definesymbol[RightHeavyAndLeftVerticalLight][\USymbChar{37}{62}] % BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT + \definesymbol[VerticalLightAndHorizontalHeavy][\USymbChar{37}{63}] % BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY + \definesymbol[UpHeavyAndDownHorizontalLight][\USymbChar{37}{64}] % BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT + \definesymbol[DownHeavyAndUpHorizontalLight][\USymbChar{37}{65}] % BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT + \definesymbol[VerticalHeavyAndHorizontalLight][\USymbChar{37}{66}] % BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT + \definesymbol[LeftUpHeavyAndRightDownLight][\USymbChar{37}{67}] % BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT + \definesymbol[RightUpHeavyAndLeftDownLight][\USymbChar{37}{68}] % BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT + \definesymbol[LeftDownHeavyAndRightUpLight][\USymbChar{37}{69}] % BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT + \definesymbol[RightDownHeavyAndLeftUpLight][\USymbChar{37}{70}] % BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT + \definesymbol[DownLightAndUpHorizontalHeavy][\USymbChar{37}{71}] % BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY + \definesymbol[UpLightAndDownHorizontalHeavy][\USymbChar{37}{72}] % BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY + \definesymbol[RightLightAndLeftVerticalHeavy][\USymbChar{37}{73}] % BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY + \definesymbol[LeftLightAndRightVerticalHeavy][\USymbChar{37}{74}] % BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY + \definesymbol[HeavyVerticalAndHorizontal][\USymbChar{37}{75}] % BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL + \definesymbol[LightArcDownAndRight][\USymbChar{37}{109}] % BOX DRAWINGS LIGHT ARC DOWN AND RIGHT + \definesymbol[LightArcDownAndLeft][\USymbChar{37}{110}] % BOX DRAWINGS LIGHT ARC DOWN AND LEFT + \definesymbol[LightArcUpAndLeft][\USymbChar{37}{111}] % BOX DRAWINGS LIGHT ARC UP AND LEFT + \definesymbol[LightArcUpAndRight][\USymbChar{37}{112}] % BOX DRAWINGS LIGHT ARC UP AND RIGHT + \definesymbol[LightDiagonalUpperRightToLowerLeft][\USymbChar{37}{113}] % BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT + \definesymbol[LightDiagonalUpperLeftToLowerRight][\USymbChar{37}{114}] % BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT + \definesymbol[LightDiagonalCross][\USymbChar{37}{115}] % BOX DRAWINGS LIGHT DIAGONAL CROSS + \definesymbol[LightLeft][\USymbChar{37}{116}] % BOX DRAWINGS LIGHT LEFT + \definesymbol[LightUp][\USymbChar{37}{117}] % BOX DRAWINGS LIGHT UP + \definesymbol[LightRight][\USymbChar{37}{118}] % BOX DRAWINGS LIGHT RIGHT + \definesymbol[LightDown][\USymbChar{37}{119}] % BOX DRAWINGS LIGHT DOWN + \definesymbol[HeavyLeft][\USymbChar{37}{120}] % BOX DRAWINGS HEAVY LEFT + \definesymbol[HeavyUp][\USymbChar{37}{121}] % BOX DRAWINGS HEAVY UP + \definesymbol[HeavyRight][\USymbChar{37}{122}] % BOX DRAWINGS HEAVY RIGHT + \definesymbol[HeavyDown][\USymbChar{37}{123}] % BOX DRAWINGS HEAVY DOWN + \definesymbol[LightLeftAndHeavyRight][\USymbChar{37}{124}] % BOX DRAWINGS LIGHT LEFT AND HEAVY RIGHT + \definesymbol[LightUpAndHeavyDown][\USymbChar{37}{125}] % BOX DRAWINGS LIGHT UP AND HEAVY DOWN + \definesymbol[HeavyLeftAndLightRight][\USymbChar{37}{126}] % BOX DRAWINGS HEAVY LEFT AND LIGHT RIGHT + \definesymbol[HeavyUpAndLightDown][\USymbChar{37}{127}] % BOX DRAWINGS HEAVY UP AND LIGHT DOWN + +\stopsymbolset + +\startsymbolset[Unicode Circled Digits] % 0x2460: Requires UnicodeRegular24 + + \definesymbol[CircledOne][\USymbCharZapf{36}{96}] % CIRCLED DIGIT ONE + \definesymbol[CircledTwo][\USymbCharZapf{36}{97}] % CIRCLED DIGIT TWO + \definesymbol[CircledThree][\USymbCharZapf{36}{98}] % CIRCLED DIGIT THREE + \definesymbol[CircledFour][\USymbCharZapf{36}{99}] % CIRCLED DIGIT FOUR + \definesymbol[CircledFive][\USymbCharZapf{36}{100}] % CIRCLED DIGIT FIVE + \definesymbol[CircledSix][\USymbCharZapf{36}{101}] % CIRCLED DIGIT SIX + \definesymbol[CircledSeven][\USymbCharZapf{36}{102}] % CIRCLED DIGIT SEVEN + \definesymbol[CircledEight][\USymbCharZapf{36}{103}] % CIRCLED DIGIT EIGHT + \definesymbol[CircledNine][\USymbCharZapf{36}{104}] % CIRCLED DIGIT NINE + \definesymbol[CircledTen][\USymbCharZapf{36}{105}] % CIRCLED NUMBER TEN + +\stopsymbolset + +\startsymbolset[Unicode Double Box Drawing] % 0x2500: Requires UnicodeRegular25 + + \definesymbol[LightDoubleDashHorizontal][\USymbChar{37}{76}] % BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL + \definesymbol[HeavyDoubleDashHorizontal][\USymbChar{37}{77}] % BOX DRAWINGS HEAVY DOUBLE DASH HORIZONTAL + \definesymbol[LightDoubleDashVertical][\USymbChar{37}{78}] % BOX DRAWINGS LIGHT DOUBLE DASH VERTICAL + \definesymbol[HeavyDoubleDashVertical][\USymbChar{37}{79}] % BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL + \definesymbol[DoubleHorizontal][\USymbChar{37}{80}] % BOX DRAWINGS DOUBLE HORIZONTAL + \definesymbol[DoubleVertical][\USymbChar{37}{81}] % BOX DRAWINGS DOUBLE VERTICAL + \definesymbol[DownSingleAndRightDouble][\USymbChar{37}{82}] % BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + \definesymbol[DownDoubleAndRightSingle][\USymbChar{37}{83}] % BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + \definesymbol[DoubleDownAndRight][\USymbChar{37}{84}] % BOX DRAWINGS DOUBLE DOWN AND RIGHT + \definesymbol[DownSingleAndLeftDouble][\USymbChar{37}{85}] % BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + \definesymbol[DownDoubleAndLeftSingle][\USymbChar{37}{86}] % BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + \definesymbol[DoubleDownAndLeft][\USymbChar{37}{87}] % BOX DRAWINGS DOUBLE DOWN AND LEFT + \definesymbol[UpSingleAndRightDouble][\USymbChar{37}{88}] % BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + \definesymbol[UpDoubleAndRightSingle][\USymbChar{37}{89}] % BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + \definesymbol[DoubleUpAndRight][\USymbChar{37}{90}] % BOX DRAWINGS DOUBLE UP AND RIGHT + \definesymbol[UpSingleAndLeftDouble][\USymbChar{37}{91}] % BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + \definesymbol[UpDoubleAndLeftSingle][\USymbChar{37}{92}] % BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + \definesymbol[DoubleUpAndLeft][\USymbChar{37}{93}] % BOX DRAWINGS DOUBLE UP AND LEFT + \definesymbol[VerticalSingleAndRightDouble][\USymbChar{37}{94}] % BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + \definesymbol[VerticalDoubleAndRightSingle][\USymbChar{37}{95}] % BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + \definesymbol[DoubleVerticalAndRight][\USymbChar{37}{96}] % BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + \definesymbol[VerticalSingleAndLeftDouble][\USymbChar{37}{97}] % BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + \definesymbol[VerticalDoubleAndLeftSingle][\USymbChar{37}{98}] % BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + \definesymbol[DoubleVerticalAndLeft][\USymbChar{37}{99}] % BOX DRAWINGS DOUBLE VERTICAL AND LEFT + \definesymbol[DownSingleAndHorizontalDouble][\USymbChar{37}{100}] % BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + \definesymbol[DownDoubleAndHorizontalSingle][\USymbChar{37}{101}] % BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + \definesymbol[DoubleDownAndHorizontal][\USymbChar{37}{102}] % BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + \definesymbol[UpSingleAndHorizontalDouble][\USymbChar{37}{103}] % BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + \definesymbol[UpDoubleAndHorizontalSingle][\USymbChar{37}{104}] % BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + \definesymbol[DoubleUpAndHorizontal][\USymbChar{37}{105}] % BOX DRAWINGS DOUBLE UP AND HORIZONTAL + \definesymbol[VerticalSingleAndHorizontalDouble][\USymbChar{37}{106}] % BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + \definesymbol[VerticalDoubleAndHorizontalSingle][\USymbChar{37}{107}] % BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + \definesymbol[DoubleVerticalAndHorizontal][\USymbChar{37}{108}] % BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + +\stopsymbolset + +\startsymbolset[Unicode Block Elements] % 0x2580: Requires UnicodeRegular25 + + \definesymbol[UpperHalfBlock][\USymbChar{37}{128}] % UPPER HALF BLOCK + \definesymbol[LowerOneEighthBlock][\USymbChar{37}{129}] % LOWER ONE EIGHTH BLOCK + \definesymbol[LowerOneQuarterBlock][\USymbChar{37}{130}] % LOWER ONE QUARTER BLOCK + \definesymbol[LowerThreeEighthsBlock][\USymbChar{37}{131}] % LOWER THREE EIGHTHS BLOCK + \definesymbol[LowerHalfBlock][\USymbChar{37}{132}] % LOWER HALF BLOCK + \definesymbol[LowerFiveEighthsBlock][\USymbChar{37}{133}] % LOWER FIVE EIGHTHS BLOCK + \definesymbol[LowerThreeQuartersBlock][\USymbChar{37}{134}] % LOWER THREE QUARTERS BLOCK + \definesymbol[LowerSevenEighthsBlock][\USymbChar{37}{135}] % LOWER SEVEN EIGHTHS BLOCK + \definesymbol[FullBlock][\USymbChar{37}{136}] % FULL BLOCK + \definesymbol[LeftSevenEighthsBlock][\USymbChar{37}{137}] % LEFT SEVEN EIGHTHS BLOCK + \definesymbol[LeftThreeQuartersBlock][\USymbChar{37}{138}] % LEFT THREE QUARTERS BLOCK + \definesymbol[LeftFiveEighthsBlock][\USymbChar{37}{139}] % LEFT FIVE EIGHTHS BLOCK + \definesymbol[LeftHalfBlock][\USymbChar{37}{140}] % LEFT HALF BLOCK + \definesymbol[LeftThreeEighthsBlock][\USymbChar{37}{141}] % LEFT THREE EIGHTHS BLOCK + \definesymbol[LeftOneQuarterBlock][\USymbChar{37}{142}] % LEFT ONE QUARTER BLOCK + \definesymbol[LeftOneEighthBlock][\USymbChar{37}{143}] % LEFT ONE EIGHTH BLOCK + \definesymbol[RightHalfBlock][\USymbChar{37}{144}] % RIGHT HALF BLOCK + \definesymbol[UpperOneEighthBlock][\USymbChar{37}{148}] % UPPER ONE EIGHTH BLOCK + \definesymbol[RightOneEighthBlock][\USymbChar{37}{149}] % RIGHT ONE EIGHTH BLOCK + +\stopsymbolset + +\startsymbolset[Unicode Shade Characters] % 0x2580: Requires UnicodeRegular25 + + \definesymbol[LightShade][\USymbChar{37}{145}] % LIGHT SHADE + \definesymbol[MediumShade][\USymbChar{37}{146}] % MEDIUM SHADE + \definesymbol[DarkShade][\USymbChar{37}{147}] % DARK SHADE + +\stopsymbolset + +\startsymbolset[Unicode Terminal Graphics] % 0x2580: Requires UnicodeRegular25 + + \definesymbol[QuadrantLowerLeft][\USymbChar{37}{150}] % [Unassigned U+2596] + \definesymbol[QuadrantLowerRight][\USymbChar{37}{151}] % [Unassigned U+2597] + \definesymbol[QuadrantUpperLeft][\USymbChar{37}{152}] % [Unassigned U+2598] + \definesymbol[QuadrantUpperLeftAndLowerLeftAndLowerRight][\USymbChar{37}{153}] % [Unassigned U+2599] + \definesymbol[QuadrantUpperLeftAndLowerRight][\USymbChar{37}{154}] % [Unassigned U+259A] + \definesymbol[QuadrantUpperLeftAndUpperRightandLowerLeft][\USymbChar{37}{155}] % [Unassigned U+259B] + \definesymbol[QuadrantUpperLeftAndUpperRightAndLowerRight][\USymbChar{37}{156}] % [Unassigned U+259C] + \definesymbol[QuadrantUpperRight][\USymbChar{37}{157}] % [Unassigned U+259D] + \definesymbol[QuadrantUpperRightAndLowerLeft][\USymbChar{37}{158}] % [Unassigned U+259E] + \definesymbol[QuadrantUpperRightAndLowerLeftAndLowerRight][\USymbChar{37}{159}] % [Unassigned U+259F] + +\stopsymbolset + +\startsymbolset[Unicode Geometric Shapes] % 0x25A0: Requires UnicodeRegular25 + + \definesymbol[BlackSquare][\USymbChar{37}{160}] % BLACK SQUARE + \definesymbol[WhiteSquare][\USymbChar{37}{161}] % WHITE SQUARE + \definesymbol[WhiteSquareWithRoundedCorners][\USymbChar{37}{162}] % WHITE SQUARE WITH ROUNDED CORNERS + \definesymbol[WhiteSquareContainingBlackSmallSquare][\USymbChar{37}{163}] % WHITE SQUARE CONTAINING BLACK SMALL SQUARE + \definesymbol[SquareWithHorizontalFill][\USymbChar{37}{164}] % SQUARE WITH HORIZONTAL FILL + \definesymbol[SquareWithVerticalFill][\USymbChar{37}{165}] % SQUARE WITH VERTICAL FILL + \definesymbol[SquareWithOrthogonalCrosshatchFill][\USymbChar{37}{166}] % SQUARE WITH ORTHOGONAL CROSSHATCH FILL + \definesymbol[SquareWithUpperLeftToLowerRightFill][\USymbChar{37}{167}] % SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL + \definesymbol[SquareWithUpperRightToLowerLeftFill][\USymbChar{37}{168}] % SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL + \definesymbol[SquareWithDiagonalCrosshatchFill][\USymbChar{37}{169}] % SQUARE WITH DIAGONAL CROSSHATCH FILL + \definesymbol[BlackSmallSquare][\USymbChar{37}{170}] % BLACK SMALL SQUARE + \definesymbol[WhiteSmallSquare][\USymbChar{37}{171}] % WHITE SMALL SQUARE + \definesymbol[BlackRectangle][\USymbChar{37}{172}] % BLACK RECTANGLE + \definesymbol[WhiteRectangle][\USymbChar{37}{173}] % WHITE RECTANGLE + \definesymbol[BlackVerticalRectangle][\USymbChar{37}{174}] % BLACK VERTICAL RECTANGLE + \definesymbol[WhiteVerticalRectangle][\USymbChar{37}{175}] % WHITE VERTICAL RECTANGLE + \definesymbol[BlackParallelogram][\USymbChar{37}{176}] % BLACK PARALLELOGRAM + \definesymbol[WhiteParallelogram][\USymbChar{37}{177}] % WHITE PARALLELOGRAM + \definesymbol[BlackUpPointingTriangle][\USymbChar{37}{178}] % BLACK UP-POINTING TRIANGLE + \definesymbol[WhiteUpPointingTriangle][\USymbChar{37}{179}] % WHITE UP-POINTING TRIANGLE + \definesymbol[BlackUpPointingSmallTriangle][\USymbChar{37}{180}] % BLACK UP-POINTING SMALL TRIANGLE + \definesymbol[WhiteUpPointingSmallTriangle][\USymbChar{37}{181}] % WHITE UP-POINTING SMALL TRIANGLE + \definesymbol[BlackRightPointingTriangle][\USymbChar{37}{182}] % BLACK RIGHT-POINTING TRIANGLE + \definesymbol[WhiteRightPointingTriangle][\USymbChar{37}{183}] % WHITE RIGHT-POINTING TRIANGLE + \definesymbol[BlackRightPointingSmallTriangle][\USymbChar{37}{184}] % BLACK RIGHT-POINTING SMALL TRIANGLE + \definesymbol[WhiteRightPointingSmallTriangle][\USymbChar{37}{185}] % WHITE RIGHT-POINTING SMALL TRIANGLE + \definesymbol[BlackRightPointingPointer][\USymbChar{37}{186}] % BLACK RIGHT-POINTING POINTER + \definesymbol[WhiteRightPointingPointer][\USymbChar{37}{187}] % WHITE RIGHT-POINTING POINTER + \definesymbol[BlackDownPointingTriangle][\USymbChar{37}{188}] % BLACK DOWN-POINTING TRIANGLE + \definesymbol[WhiteDownPointingTriangle][\USymbChar{37}{189}] % WHITE DOWN-POINTING TRIANGLE + \definesymbol[BlackDownPointingSmallTriangle][\USymbChar{37}{190}] % BLACK DOWN-POINTING SMALL TRIANGLE + \definesymbol[WhiteDownPointingSmallTriangle][\USymbChar{37}{191}] % WHITE DOWN-POINTING SMALL TRIANGLE + \definesymbol[BlackLeftPointingTriangle][\USymbChar{37}{192}] % BLACK LEFT-POINTING TRIANGLE + \definesymbol[WhiteLeftPointingTriangle][\USymbChar{37}{193}] % WHITE LEFT-POINTING TRIANGLE + \definesymbol[BlackLeftPointingSmallTriangle][\USymbChar{37}{194}] % BLACK LEFT-POINTING SMALL TRIANGLE + \definesymbol[WhiteLeftPointingSmallTriangle][\USymbChar{37}{195}] % WHITE LEFT-POINTING SMALL TRIANGLE + \definesymbol[BlackLeftPointingPointer][\USymbChar{37}{196}] % BLACK LEFT-POINTING POINTER + \definesymbol[WhiteLeftPointingPointer][\USymbChar{37}{197}] % WHITE LEFT-POINTING POINTER + \definesymbol[BlackDiamond][\USymbChar{37}{198}] % BLACK DIAMOND + \definesymbol[WhiteDiamond][\USymbChar{37}{199}] % WHITE DIAMOND + \definesymbol[WhiteDiamondContainingBlackSmallDiamond][\USymbChar{37}{200}] % WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND + \definesymbol[Fisheye][\USymbChar{37}{201}] % FISHEYE + \definesymbol[Lozenge][\USymbChar{37}{202}] % LOZENGE + \definesymbol[WhiteCircle][\USymbChar{37}{203}] % WHITE CIRCLE + \definesymbol[DottedCircle][\USymbChar{37}{204}] % DOTTED CIRCLE + \definesymbol[CircleWithVerticalFill][\USymbChar{37}{205}] % CIRCLE WITH VERTICAL FILL + \definesymbol[Bullseye][\USymbChar{37}{206}] % BULLSEYE + \definesymbol[BlackCircle][\USymbChar{37}{207}] % BLACK CIRCLE + \definesymbol[CircleWithLeftHalfBlack][\USymbChar{37}{208}] % CIRCLE WITH LEFT HALF BLACK + \definesymbol[CircleWithRightHalfBlack][\USymbChar{37}{209}] % CIRCLE WITH RIGHT HALF BLACK + \definesymbol[CircleWithLowerHalfBlack][\USymbChar{37}{210}] % CIRCLE WITH LOWER HALF BLACK + \definesymbol[CircleWithUpperHalfBlack][\USymbChar{37}{211}] % CIRCLE WITH UPPER HALF BLACK + \definesymbol[CircleWithUpperRightQuadrantBlack][\USymbChar{37}{212}] % CIRCLE WITH UPPER RIGHT QUADRANT BLACK + \definesymbol[CircleWithAllButUpperLeftQuadrantBlack][\USymbChar{37}{213}] % CIRCLE WITH ALL BUT UPPER LEFT QUADRANT BLACK + \definesymbol[LeftHalfBlackCircle][\USymbChar{37}{214}] % LEFT HALF BLACK CIRCLE + \definesymbol[RightHalfBlackCircle][\USymbChar{37}{215}] % RIGHT HALF BLACK CIRCLE + \definesymbol[InverseBullet][\USymbChar{37}{216}] % INVERSE BULLET + \definesymbol[InverseWhiteCircle][\USymbChar{37}{217}] % INVERSE WHITE CIRCLE + \definesymbol[UpperHalfInverseWhiteCircle][\USymbChar{37}{218}] % UPPER HALF INVERSE WHITE CIRCLE + \definesymbol[LowerHalfInverseWhiteCircle][\USymbChar{37}{219}] % LOWER HALF INVERSE WHITE CIRCLE + \definesymbol[UpperLeftQuadrantCircularArc][\USymbChar{37}{220}] % UPPER LEFT QUADRANT CIRCULAR ARC + \definesymbol[UpperRightQuadrantCircularArc][\USymbChar{37}{221}] % UPPER RIGHT QUADRANT CIRCULAR ARC + \definesymbol[LowerRightQuadrantCircularArc][\USymbChar{37}{222}] % LOWER RIGHT QUADRANT CIRCULAR ARC + \definesymbol[LowerLeftQuadrantCircularArc][\USymbChar{37}{223}] % LOWER LEFT QUADRANT CIRCULAR ARC + \definesymbol[LowerHalfCircle][\USymbChar{37}{225}] % LOWER HALF CIRCLE + \definesymbol[BlackLowerRightTriangle][\USymbChar{37}{226}] % BLACK LOWER RIGHT TRIANGLE + \definesymbol[BlackLowerLeftTriangle][\USymbChar{37}{227}] % BLACK LOWER LEFT TRIANGLE + \definesymbol[BlackUpperLeftTriangle][\USymbChar{37}{228}] % BLACK UPPER LEFT TRIANGLE + \definesymbol[BlackUpperRightTriangle][\USymbChar{37}{229}] % BLACK UPPER RIGHT TRIANGLE + \definesymbol[WhiteBullet][\USymbChar{37}{230}] % WHITE BULLET + \definesymbol[SquareWithLeftHalfBlack][\USymbChar{37}{231}] % SQUARE WITH LEFT HALF BLACK + \definesymbol[SquareWithRightHalfBlack][\USymbChar{37}{232}] % SQUARE WITH RIGHT HALF BLACK + \definesymbol[SquareWithUpperLeftDiagonalHalfBlack][\USymbChar{37}{233}] % SQUARE WITH UPPER LEFT DIAGONAL HALF BLACK + \definesymbol[SquareWithLowerRightDiagonalHalfBlack][\USymbChar{37}{234}] % SQUARE WITH LOWER RIGHT DIAGONAL HALF BLACK + \definesymbol[WhiteSquareWithVerticalBisectingLine][\USymbChar{37}{235}] % WHITE SQUARE WITH VERTICAL BISECTING LINE + \definesymbol[WhiteUpPointingTriangleWithDot][\USymbChar{37}{236}] % WHITE UP-POINTING TRIANGLE WITH DOT + \definesymbol[UpPointingTriangleWithLeftHalfBlack][\USymbChar{37}{237}] % UP-POINTING TRIANGLE WITH LEFT HALF BLACK + \definesymbol[UpPointingTriangleWithRightHalfBlack][\USymbChar{37}{238}] % UP-POINTING TRIANGLE WITH RIGHT HALF BLACK + \definesymbol[LargeCircle][\USymbChar{37}{239}] % LARGE CIRCLE + \definesymbol[UpperLeftTriangle][\USymbChar{37}{248}] % [Unassigned U+25F8] + \definesymbol[UpperRightTriangle][\USymbChar{37}{249}] % [Unassigned U+25F9] + \definesymbol[LowerLeftTriangle][\USymbChar{37}{250}] % [Unassigned U+25FA] + \definesymbol[WhiteMediumSquare][\USymbChar{37}{251}] % [Unassigned U+25FB] + \definesymbol[BlackMediumSquare][\USymbChar{37}{252}] % [Unassigned U+25FC] + \definesymbol[WhiteMediumSmallSquare][\USymbChar{37}{253}] % [Unassigned U+25FD] + \definesymbol[BlackMediumSmallSquare][\USymbChar{37}{254}] % [Unassigned U+25FE] + \definesymbol[LowerRightTriangle][\USymbChar{37}{255}] % [Unassigned U+25FF] + +\stopsymbolset + +\startsymbolset[Unicode Control Code Graphics] % 0x25A0: Requires UnicodeRegular25 + + \definesymbol[WhiteSquareWithUpperLeftQuadrant][\USymbChar{37}{240}] % WHITE SQUARE WITH UPPER LEFT QUADRANT + \definesymbol[WhiteSquareWithLowerLeftQuadrant][\USymbChar{37}{241}] % WHITE SQUARE WITH LOWER LEFT QUADRANT + \definesymbol[WhiteSquareWithLowerRightQuadrant][\USymbChar{37}{242}] % WHITE SQUARE WITH LOWER RIGHT QUADRANT + \definesymbol[WhiteSquareWithUpperRightQuadrant][\USymbChar{37}{243}] % WHITE SQUARE WITH UPPER RIGHT QUADRANT + \definesymbol[WhiteCircleWithUpperLeftQuadrant][\USymbChar{37}{244}] % WHITE CIRCLE WITH UPPER LEFT QUADRANT + \definesymbol[WhiteCircleWithLowerLeftQuadrant][\USymbChar{37}{245}] % WHITE CIRCLE WITH LOWER LEFT QUADRANT + \definesymbol[WhiteCircleWithLowerRightQuadrant][\USymbChar{37}{246}] % WHITE CIRCLE WITH LOWER RIGHT QUADRANT + \definesymbol[WhiteCircleWithUpperRightQuadrant][\USymbChar{37}{247}] % WHITE CIRCLE WITH UPPER RIGHT QUADRANT + +\stopsymbolset + +\startsymbolset[Unicode Weather and Astrological] % 0x2600: Requires UnicodeRegular26 + + \definesymbol[BlackSunWithRays][\USymbChar{38}{0}] % BLACK SUN WITH RAYS + \definesymbol[Cloud][\USymbChar{38}{1}] % CLOUD + \definesymbol[Umbrella][\USymbChar{38}{2}] % UMBRELLA + \definesymbol[Snowman][\USymbChar{38}{3}] % SNOWMAN + \definesymbol[Comet][\USymbChar{38}{4}] % COMET + \definesymbol[BlackStar][\USymbChar{38}{5}] % BLACK STAR + \definesymbol[WhiteStar][\USymbChar{38}{6}] % WHITE STAR + \definesymbol[Lightning][\USymbChar{38}{7}] % LIGHTNING + \definesymbol[Thunderstorm][\USymbChar{38}{8}] % THUNDERSTORM + \definesymbol[Sun][\USymbChar{38}{9}] % SUN + \definesymbol[AscendingNode][\USymbChar{38}{10}] % ASCENDING NODE + \definesymbol[DescendingNode][\USymbChar{38}{11}] % DESCENDING NODE + \definesymbol[Conjunction][\USymbChar{38}{12}] % CONJUNCTION + \definesymbol[Opposition][\USymbChar{38}{13}] % OPPOSITION + \definesymbol[FirstQuarterMoon][\USymbChar{38}{61}] % FIRST QUARTER MOON + \definesymbol[LastQuarterMoon][\USymbChar{38}{62}] % LAST QUARTER MOON + \definesymbol[Mercury][\USymbChar{38}{63}] % MERCURY + \definesymbol[FemaleSign][\USymbChar{38}{64}] % FEMALE SIGN + \definesymbol[Earth][\USymbChar{38}{65}] % EARTH + \definesymbol[MaleSign][\USymbChar{38}{66}] % MALE SIGN + \definesymbol[Jupiter][\USymbChar{38}{67}] % JUPITER + \definesymbol[Saturn][\USymbChar{38}{68}] % SATURN + \definesymbol[Uranus][\USymbChar{38}{69}] % URANUS + \definesymbol[Neptune][\USymbChar{38}{70}] % NEPTUNE + \definesymbol[Pluto][\USymbChar{38}{71}] % PLUTO + +\stopsymbolset + +\startsymbolset[Unicode Miscellaneous] % 0x2600: Requires UnicodeRegular26 + + \definesymbol[BlackTelephone][\USymbChar{38}{14}] % BLACK TELEPHONE + \definesymbol[WhiteTelephone][\USymbChar{38}{15}] % WHITE TELEPHONE + \definesymbol[BallotBox][\USymbChar{38}{16}] % BALLOT BOX + \definesymbol[BallotBoxWithCheck][\USymbChar{38}{17}] % BALLOT BOX WITH CHECK + \definesymbol[BallotBoxWithX][\USymbChar{38}{18}] % BALLOT BOX WITH X + \definesymbol[Saltire][\USymbChar{38}{19}] % SALTIRE + \definesymbol[ReversedRotatedFloralHeartBullet][\USymbChar{38}{25}] % REVERSED ROTATED FLORAL HEART BULLET + \definesymbol[WheelOfDharma][\USymbChar{38}{56}] % WHEEL OF DHARMA + \definesymbol[WhiteFrowningFace][\USymbChar{38}{57}] % WHITE FROWNING FACE + \definesymbol[WhiteSmilingFace][\USymbChar{38}{58}] % WHITE SMILING FACE + \definesymbol[BlackSmilingFace][\USymbChar{38}{59}] % BLACK SMILING FACE + \definesymbol[WhiteSunWithRays][\USymbChar{38}{60}] % WHITE SUN WITH RAYS + \definesymbol[HotSprings][\USymbChar{38}{104}] % HOT SPRINGS + +\stopsymbolset + +\startsymbolset[Unicode Japanese Chess] % 0x2600: Requires UnicodeRegular26 + + \definesymbol[WhiteShogiPiece][\USymbChar{38}{22}] % [Unassigned U+2616] + \definesymbol[BlackShogiPiece][\USymbChar{38}{23}] % [Unassigned U+2617] + +\stopsymbolset + +\startsymbolset[Unicode Pointing Hand] % 0x2600: Requires UnicodeRegular26 + + \definesymbol[BlackLeftPointingIndex][\USymbChar{38}{26}] % BLACK LEFT POINTING INDEX + \definesymbol[BlackRightPointingIndex][\USymbChar{38}{27}] % BLACK RIGHT POINTING INDEX + \definesymbol[WhiteLeftPointingIndex][\USymbChar{38}{28}] % WHITE LEFT POINTING INDEX + \definesymbol[WhiteUpPointingIndex][\USymbChar{38}{29}] % WHITE UP POINTING INDEX + \definesymbol[WhiteRightPointingIndex][\USymbChar{38}{30}] % WHITE RIGHT POINTING INDEX + \definesymbol[WhiteDownPointingIndex][\USymbChar{38}{31}] % WHITE DOWN POINTING INDEX + +\stopsymbolset + +\startsymbolset[Unicode Warning Signs] % 0x2600: Requires UnicodeRegular26 + + \definesymbol[SkullAndCrossbones][\USymbChar{38}{32}] % SKULL AND CROSSBONES + \definesymbol[CautionSign][\USymbChar{38}{33}] % CAUTION SIGN + \definesymbol[RadioactiveSign][\USymbChar{38}{34}] % RADIOACTIVE SIGN + \definesymbol[BiohazardSign][\USymbChar{38}{35}] % BIOHAZARD SIGN + +\stopsymbolset + +\startsymbolset[Unicode Healing Signs] % 0x2600: Requires UnicodeRegular26 + \definesymbol[Caduceus][\USymbChar{38}{36}] % CADUCEUS + \definesymbol[Ankh][\USymbChar{38}{37}] % ANKH +\stopsymbolset + +\startsymbolset[Unicode Religious and Political] % 0x2600: Requires UnicodeRegular26 and 27 + + \definesymbol[OrthodoxCross][\USymbChar{38}{38}] % ORTHODOX CROSS + \definesymbol[ChiRho][\USymbChar{38}{39}] % CHI RHO + \definesymbol[CrossOfLorraine][\USymbChar{38}{40}] % CROSS OF LORRAINE + \definesymbol[CrossOfJerusalem][\USymbChar{38}{41}] % CROSS OF JERUSALEM + \definesymbol[StarAndCrescent][\USymbChar{38}{42}] % STAR AND CRESCENT + \definesymbol[FarsiSymbol][\USymbChar{38}{43}] % FARSI SYMBOL + \definesymbol[AdiShakti][\USymbChar{38}{44}] % ADI SHAKTI + \definesymbol[HammerAndSickle][\USymbChar{38}{45}] % HAMMER AND SICKLE + \definesymbol[PeaceSymbol][\USymbChar{38}{46}] % PEACE SYMBOL + \definesymbol[YinYang][\USymbChar{38}{47}] % YIN YANG + \definesymbol[WestSyriacCross][\USymbChar{38}{112}] % WEST SYRIAC CROSS + \definesymbol[EastSyriacCross][\USymbChar{38}{113}] % EAST SYRIAC CROSS +% 27xx starts here + \definesymbol[OutlinedGreekCross][\USymbCharZapf{39}{25}] % OUTLINED GREEK CROSS + \definesymbol[HeavyGreekCross][\USymbCharZapf{39}{26}] % HEAVY GREEK CROSS + \definesymbol[OpenCentreCross][\USymbCharZapf{39}{27}] % OPEN CENTRE CROSS + \definesymbol[HeavyOpenCentreCross][\USymbCharZapf{39}{28}] % HEAVY OPEN CENTRE CROSS + \definesymbol[LatinCross][\USymbCharZapf{39}{29}] % LATIN CROSS + \definesymbol[ShadowedWhiteLatinCross][\USymbCharZapf{39}{30}] % SHADOWED WHITE LATIN CROSS + \definesymbol[OutlinedLatinCross][\USymbCharZapf{39}{31}] % OUTLINED LATIN CROSS + \definesymbol[MalteseCross][\USymbCharZapf{39}{32}] % MALTESE CROSS + \definesymbol[StarOfDavid][\USymbCharZapf{39}{33}] % STAR OF DAVID + + +\stopsymbolset + +\startsymbolset[Unicode Trigram] % 0x2600: Requires UnicodeRegular26 + + \definesymbol[TrigramForHeaven][\USymbChar{38}{48}] % TRIGRAM FOR HEAVEN + \definesymbol[TrigramForLake][\USymbChar{38}{49}] % TRIGRAM FOR LAKE + \definesymbol[TrigramForFire][\USymbChar{38}{50}] % TRIGRAM FOR FIRE + \definesymbol[TrigramForThunder][\USymbChar{38}{51}] % TRIGRAM FOR THUNDER + \definesymbol[TrigramForWind][\USymbChar{38}{52}] % TRIGRAM FOR WIND + \definesymbol[TrigramForWater][\USymbChar{38}{53}] % TRIGRAM FOR WATER + \definesymbol[TrigramForMountain][\USymbChar{38}{54}] % TRIGRAM FOR MOUNTAIN + \definesymbol[TrigramForEarth][\USymbChar{38}{55}] % TRIGRAM FOR EARTH + +\stopsymbolset + +\startsymbolset[Unicode Zodiac] % 0x2600: Requires UnicodeRegular26 + + \definesymbol[Aries][\USymbChar{38}{72}] % ARIES + \definesymbol[Taurus][\USymbChar{38}{73}] % TAURUS + \definesymbol[Gemini][\USymbChar{38}{74}] % GEMINI + \definesymbol[Cancer][\USymbChar{38}{75}] % CANCER + \definesymbol[Leo][\USymbChar{38}{76}] % LEO + \definesymbol[Virgo][\USymbChar{38}{77}] % VIRGO + \definesymbol[Libra][\USymbChar{38}{78}] % LIBRA + \definesymbol[Scorpius][\USymbChar{38}{79}] % SCORPIUS + \definesymbol[Sagittarius][\USymbChar{38}{80}] % SAGITTARIUS + \definesymbol[Capricorn][\USymbChar{38}{81}] % CAPRICORN + \definesymbol[Aquarius][\USymbChar{38}{82}] % AQUARIUS + \definesymbol[Pisces][\USymbChar{38}{83}] % PISCES + +\stopsymbolset + +\startsymbolset[Unicode Chess] % 0x2600: Requires UnicodeRegular26 + + \definesymbol[WhiteChessKing][\USymbChar{38}{84}] % WHITE CHESS KING + \definesymbol[WhiteChessQueen][\USymbChar{38}{85}] % WHITE CHESS QUEEN + \definesymbol[WhiteChessRook][\USymbChar{38}{86}] % WHITE CHESS ROOK + \definesymbol[WhiteChessBishop][\USymbChar{38}{87}] % WHITE CHESS BISHOP + \definesymbol[WhiteChessKnight][\USymbChar{38}{88}] % WHITE CHESS KNIGHT + \definesymbol[WhiteChessPawn][\USymbChar{38}{89}] % WHITE CHESS PAWN + \definesymbol[BlackChessKing][\USymbChar{38}{90}] % BLACK CHESS KING + \definesymbol[BlackChessQueen][\USymbChar{38}{91}] % BLACK CHESS QUEEN + \definesymbol[BlackChessRook][\USymbChar{38}{92}] % BLACK CHESS ROOK + \definesymbol[BlackChessBishop][\USymbChar{38}{93}] % BLACK CHESS BISHOP + \definesymbol[BlackChessKnight][\USymbChar{38}{94}] % BLACK CHESS KNIGHT + \definesymbol[BlackChessPawn][\USymbChar{38}{95}] % BLACK CHESS PAWN + +\stopsymbolset + +\startsymbolset[Unicode Playing Card] % 0x2600: Requires UnicodeRegular26 + + \definesymbol[BlackSpadeSuit][\USymbChar{38}{96}] % BLACK SPADE SUIT + \definesymbol[WhiteHeartSuit][\USymbChar{38}{97}] % WHITE HEART SUIT + \definesymbol[WhiteDiamondSuit][\USymbChar{38}{98}] % WHITE DIAMOND SUIT + \definesymbol[BlackClubSuit][\USymbChar{38}{99}] % BLACK CLUB SUIT + \definesymbol[WhiteSpadeSuit][\USymbChar{38}{100}] % WHITE SPADE SUIT + \definesymbol[BlackHeartSuit][\USymbChar{38}{101}] % BLACK HEART SUIT + \definesymbol[BlackDiamondSuit][\USymbChar{38}{102}] % BLACK DIAMOND SUIT + \definesymbol[WhiteClubSuit][\USymbChar{38}{103}] % WHITE CLUB SUIT + +\stopsymbolset + +\startsymbolset[Unicode Musical] % 0x2600: Requires UnicodeRegular26 + + \definesymbol[QuarterNote][\USymbChar{38}{105}] % QUARTER NOTE + \definesymbol[EighthNote][\USymbChar{38}{106}] % EIGHTH NOTE + \definesymbol[BeamedEighthNotes][\USymbChar{38}{107}] % BEAMED EIGHTH NOTES + \definesymbol[BeamedSixteenthNotes][\USymbChar{38}{108}] % BEAMED SIXTEENTH NOTES + \definesymbol[MusicFlatSign][\USymbChar{38}{109}] % MUSIC FLAT SIGN + \definesymbol[MusicNaturalSign][\USymbChar{38}{110}] % MUSIC NATURAL SIGN + \definesymbol[MusicSharpSign][\USymbChar{38}{111}] % MUSIC SHARP SIGN + +\stopsymbolset + +\startsymbolset[Unicode Recycling] % 0x2600: Requires UnicodeRegular26 + + \definesymbol[UniversalRecycling][\USymbChar{38}{114}] % [Unassigned U+2672] + \definesymbol[Type1Plastics][\USymbChar{38}{115}] % [Unassigned U+2673] + \definesymbol[Type2Plastics][\USymbChar{38}{116}] % [Unassigned U+2674] + \definesymbol[Type3Plastics][\USymbChar{38}{117}] % [Unassigned U+2675] + \definesymbol[Type4Plastics][\USymbChar{38}{118}] % [Unassigned U+2676] + \definesymbol[Type5Plastics][\USymbChar{38}{119}] % [Unassigned U+2677] + \definesymbol[Type6Plastics][\USymbChar{38}{120}] % [Unassigned U+2678] + \definesymbol[Type7Plastics][\USymbChar{38}{121}] % [Unassigned U+2679] + \definesymbol[GenericMaterials][\USymbChar{38}{122}] % [Unassigned U+267A] + \definesymbol[BlackUniversalRecycling][\USymbChar{38}{123}] % [Unassigned U+267B] + \definesymbol[RecycledPaper][\USymbChar{38}{124}] % [Unassigned U+267C] + \definesymbol[PartiallyRecycledPaper][\USymbChar{38}{125}] % [Unassigned U+267D] + +\stopsymbolset + +\startsymbolset[Unicode Dice] % 0x2600: Requires UnicodeRegular26 + + \definesymbol[DieFace1][\USymbChar{38}{128}] % [Unassigned U+2680] + \definesymbol[DieFace2][\USymbChar{38}{129}] % [Unassigned U+2681] + \definesymbol[DieFace3][\USymbChar{38}{130}] % [Unassigned U+2682] + \definesymbol[DieFace4][\USymbChar{38}{131}] % [Unassigned U+2683] + \definesymbol[DieFace5][\USymbChar{38}{132}] % [Unassigned U+2684] + \definesymbol[DieFace6][\USymbChar{38}{133}] % [Unassigned U+2685] + +\stopsymbolset + +\startsymbolset[Unicode Go Markers] % 0x2600: Requires UnicodeRegular26 + + \definesymbol[WhiteCircleWithDotRight][\USymbChar{38}{134}] % [Unassigned U+2686] + \definesymbol[WhiteCircleWithTwoDots][\USymbChar{38}{135}] % [Unassigned U+2687] + \definesymbol[BlackCircleWithWhiteDotRight][\USymbChar{38}{136}] % [Unassigned U+2688] + \definesymbol[BlackCircleWithTwoWhiteDots][\USymbChar{38}{137}] % [Unassigned U+2689] + +\stopsymbolset + +\startsymbolset[Unicode Scissors] % 0x2700: Requires UnicodeRegular27 + + \definesymbol[UpperBladeScissors][\USymbCharZapf{39}{1}] % UPPER BLADE SCISSORS + \definesymbol[BlackScissors][\USymbCharZapf{39}{2}] % BLACK SCISSORS + \definesymbol[LowerBladeScissors][\USymbCharZapf{39}{3}] % LOWER BLADE SCISSORS + \definesymbol[WhiteScissors][\USymbCharZapf{39}{4}] % WHITE SCISSORS + +\stopsymbolset + +\startsymbolset[Unicode Dingbats] % 0x2700: Requires UnicodeRegular27 + + \definesymbol[TelephoneLocationSign][\USymbCharZapf{39}{6}] % TELEPHONE LOCATION SIGN + \definesymbol[TapeDrive][\USymbCharZapf{39}{7}] % TAPE DRIVE + \definesymbol[Airplane][\USymbCharZapf{39}{8}] % AIRPLANE + \definesymbol[Envelope][\USymbCharZapf{39}{9}] % ENVELOPE + \definesymbol[VictoryHand][\USymbCharZapf{39}{12}] % VICTORY HAND + \definesymbol[WritingHand][\USymbCharZapf{39}{13}] % WRITING HAND + \definesymbol[LowerRightPencil][\USymbCharZapf{39}{14}] % LOWER RIGHT PENCIL + \definesymbol[Pencil][\USymbCharZapf{39}{15}] % PENCIL + \definesymbol[UpperRightPencil][\USymbCharZapf{39}{16}] % UPPER RIGHT PENCIL + \definesymbol[WhiteNib][\USymbCharZapf{39}{17}] % WHITE NIB + \definesymbol[BlackNib][\USymbCharZapf{39}{18}] % BLACK NIB + \definesymbol[BlackDiamondMinusWhiteX][\USymbCharZapf{39}{86}] % BLACK DIAMOND MINUS WHITE X + +\stopsymbolset + +\startsymbolset[Unicode Checks and Xs] % 0x2700: Requires UnicodeRegular27 + + \definesymbol[CheckMark][\USymbCharZapf{39}{19}] % CHECK MARK + \definesymbol[HeavyCheckMark][\USymbCharZapf{39}{20}] % HEAVY CHECK MARK + \definesymbol[MultiplicationX][\USymbCharZapf{39}{21}] % MULTIPLICATION X + \definesymbol[HeavyMultiplicationX][\USymbCharZapf{39}{22}] % HEAVY MULTIPLICATION X + \definesymbol[BallotX][\USymbCharZapf{39}{23}] % BALLOT X + \definesymbol[HeavyBallotX][\USymbCharZapf{39}{24}] % HEAVY BALLOT X + +\stopsymbolset + +\startsymbolset[Unicode Stars] % 0x2700: Requires UnicodeRegular27 + + \definesymbol[FourTeardropSpokedAsterisk][\USymbCharZapf{39}{34}] % FOUR TEARDROP-SPOKED ASTERISK + \definesymbol[FourBalloonSpokedAsterisk][\USymbCharZapf{39}{35}] % FOUR BALLOON-SPOKED ASTERISK + \definesymbol[HeavyFourBalloonSpokedAsterisk][\USymbCharZapf{39}{36}] % HEAVY FOUR BALLOON-SPOKED ASTERISK + \definesymbol[FourClubSpokedAsterisk][\USymbCharZapf{39}{37}] % FOUR CLUB-SPOKED ASTERISK + \definesymbol[BlackFourPointedStar][\USymbCharZapf{39}{38}] % BLACK FOUR POINTED STAR + \definesymbol[WhiteFourPointedStar][\USymbCharZapf{39}{39}] % WHITE FOUR POINTED STAR + \definesymbol[StressOutlinedWhiteStar][\USymbCharZapf{39}{41}] % STRESS OUTLINED WHITE STAR + \definesymbol[CircledWhiteStar][\USymbCharZapf{39}{42}] % CIRCLED WHITE STAR + \definesymbol[OpenCentreBlackStar][\USymbCharZapf{39}{43}] % OPEN CENTRE BLACK STAR + \definesymbol[BlackCentreWhiteStar][\USymbCharZapf{39}{44}] % BLACK CENTRE WHITE STAR + \definesymbol[OutlinedBlackStar][\USymbCharZapf{39}{45}] % OUTLINED BLACK STAR + \definesymbol[HeavyOutlinedBlackStar][\USymbCharZapf{39}{46}] % HEAVY OUTLINED BLACK STAR + \definesymbol[PinwheelStar][\USymbCharZapf{39}{47}] % PINWHEEL STAR + \definesymbol[ShadowedWhiteStar][\USymbCharZapf{39}{48}] % SHADOWED WHITE STAR + \definesymbol[HeavyAsterisk][\USymbCharZapf{39}{49}] % HEAVY ASTERISK + \definesymbol[OpenCentreAsterisk][\USymbCharZapf{39}{50}] % OPEN CENTRE ASTERISK + \definesymbol[EightSpokedAsterisk][\USymbCharZapf{39}{51}] % EIGHT SPOKED ASTERISK + \definesymbol[EightPointedBlackStar][\USymbCharZapf{39}{52}] % EIGHT POINTED BLACK STAR + \definesymbol[EightPointedPinwheelStar][\USymbCharZapf{39}{53}] % EIGHT POINTED PINWHEEL STAR + \definesymbol[SixPointedBlackStar][\USymbCharZapf{39}{54}] % SIX POINTED BLACK STAR + \definesymbol[EightPointedRectilinearBlackStar][\USymbCharZapf{39}{55}] % EIGHT POINTED RECTILINEAR BLACK STAR + \definesymbol[HeavyEightPointedRectilinearBlackStar][\USymbCharZapf{39}{56}] % HEAVY EIGHT POINTED RECTILINEAR BLACK STAR + \definesymbol[TwelvePointedBlackStar][\USymbCharZapf{39}{57}] % TWELVE POINTED BLACK STAR + \definesymbol[SixteenPointedAsterisk][\USymbCharZapf{39}{58}] % SIXTEEN POINTED ASTERISK + \definesymbol[TeardropSpokedAsterisk][\USymbCharZapf{39}{59}] % TEARDROP-SPOKED ASTERISK + \definesymbol[OpenCentreTeardropSpokedAsterisk][\USymbCharZapf{39}{60}] % OPEN CENTRE TEARDROP-SPOKED ASTERISK + \definesymbol[HeavyTeardropSpokedAsterisk][\USymbCharZapf{39}{61}] % HEAVY TEARDROP-SPOKED ASTERISK + \definesymbol[SixPetalledBlackAndWhiteFlorette][\USymbCharZapf{39}{62}] % SIX PETALLED BLACK AND WHITE FLORETTE + \definesymbol[BlackFlorette][\USymbCharZapf{39}{63}] % BLACK FLORETTE + \definesymbol[WhiteFlorette][\USymbCharZapf{39}{64}] % WHITE FLORETTE + \definesymbol[EightPetalledOutlinedBlackFlorette][\USymbCharZapf{39}{65}] % EIGHT PETALLED OUTLINED BLACK FLORETTE + \definesymbol[CircledOpenCentreEightPointedStar][\USymbCharZapf{39}{66}] % CIRCLED OPEN CENTRE EIGHT POINTED STAR + \definesymbol[HeavyTeardropSpokedPinwheelAsterisk][\USymbCharZapf{39}{67}] % HEAVY TEARDROP-SPOKED PINWHEEL ASTERISK + \definesymbol[Sparkle][\USymbCharZapf{39}{71}] % SPARKLE + \definesymbol[HeavySparkle][\USymbCharZapf{39}{72}] % HEAVY SPARKLE + \definesymbol[Balloon-spokedAsterisk][\USymbCharZapf{39}{73}] % BALLOON-SPOKED ASTERISK + \definesymbol[EightTeardrop-spokedPropellerAsterisk][\USymbCharZapf{39}{74}] % EIGHT TEARDROP-SPOKED PROPELLER ASTERISK + \definesymbol[HeavyEightTeardrop-spokedPropellerAsterisk][\USymbCharZapf{39}{75}] % HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK + +\stopsymbolset + +\startsymbolset[Unicode Snowflakes] % 0x2700: Requires UnicodeRegular27 + + \definesymbol[Snowflake][\USymbCharZapf{39}{68}] % SNOWFLAKE + \definesymbol[TightTrifoliateSnowflake][\USymbCharZapf{39}{69}] % TIGHT TRIFOLIATE SNOWFLAKE + \definesymbol[HeavyChevronSnowflake][\USymbCharZapf{39}{70}] % HEAVY CHEVRON SNOWFLAKE + +\stopsymbolset + +\startsymbolset[Unicode Shadowed Shapes] % 0x2700: Requires UnicodeRegular27 + + \definesymbol[ShadowedWhiteCircle][\USymbCharZapf{39}{77}] % SHADOWED WHITE CIRCLE + \definesymbol[LowerRightDrop-shadowedWhiteSquare][\USymbCharZapf{39}{79}] % LOWER RIGHT DROP-SHADOWED WHITE SQUARE + \definesymbol[UpperRightDrop-shadowedWhiteSquare][\USymbCharZapf{39}{80}] % UPPER RIGHT DROP-SHADOWED WHITE SQUARE + \definesymbol[LowerRightShadowedWhiteSquare][\USymbCharZapf{39}{81}] % LOWER RIGHT SHADOWED WHITE SQUARE + \definesymbol[UpperRightShadowedWhiteSquare][\USymbCharZapf{39}{82}] % UPPER RIGHT SHADOWED WHITE SQUARE + +\stopsymbolset + +\startsymbolset[Unicode Bars] % 0x2700: Requires UnicodeRegular27 + + \definesymbol[LightVerticalBar][\USymbCharZapf{39}{88}] % LIGHT VERTICAL BAR + \definesymbol[MediumVerticalBar][\USymbCharZapf{39}{89}] % MEDIUM VERTICAL BAR + \definesymbol[HeavyVerticalBar][\USymbCharZapf{39}{90}] % HEAVY VERTICAL BAR + +\stopsymbolset + +\startsymbolset[Unicode Dingbat Punctuation] % 0x2700: Requires UnicodeRegular27 + + \definesymbol[HeavySingleTurnedCommaQuotationMark][\USymbCharZapf{39}{91}] % HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT + \definesymbol[HeavySingleCommaQuotationMark][\USymbCharZapf{39}{92}] % HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT + \definesymbol[HeavyDoubleTurnedCommaQuotationMark][\USymbCharZapf{39}{93}] % HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT + \definesymbol[HeavyDoubleCommaQuotationMark][\USymbCharZapf{39}{94}] % HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT + \definesymbol[CurvedStemParagraphSign][\USymbCharZapf{39}{97}] % CURVED STEM PARAGRAPH SIGN ORNAMENT + \definesymbol[HeavyExclamationMark][\USymbCharZapf{39}{98}] % HEAVY EXCLAMATION MARK ORNAMENT + \definesymbol[HeavyHeartExclamationMark][\USymbCharZapf{39}{99}] % HEAVY HEART EXCLAMATION MARK ORNAMENT + +\stopsymbolset + +\startsymbolset[Unicode Hearts] % 0x2700: Requires UnicodeRegular27 + + \definesymbol[HeavyBlackHeart][\USymbCharZapf{39}{100}] % HEAVY BLACK HEART + \definesymbol[RotatedHeavyBlackHeartBullet][\USymbCharZapf{39}{101}] % ROTATED HEAVY BLACK HEART BULLET + \definesymbol[FloralHeart][\USymbCharZapf{39}{102}] % FLORAL HEART + \definesymbol[RotatedFloralHeartBullet][\USymbCharZapf{39}{103}] % ROTATED FLORAL HEART BULLET + +\stopsymbolset + +\startsymbolset[Unicode Negative Circled Digits] % 0x2700: Requires UnicodeRegular27 + + \definesymbol[CircledOne][\USymbCharZapf{39}{118}] % DINGBAT NEGATIVE CIRCLED DIGIT ONE + \definesymbol[CircledTwo][\USymbCharZapf{39}{119}] % DINGBAT NEGATIVE CIRCLED DIGIT TWO + \definesymbol[CircledThree][\USymbCharZapf{39}{120}] % DINGBAT NEGATIVE CIRCLED DIGIT THREE + \definesymbol[CircledFour][\USymbCharZapf{39}{121}] % DINGBAT NEGATIVE CIRCLED DIGIT FOUR + \definesymbol[CircledFive][\USymbCharZapf{39}{122}] % DINGBAT NEGATIVE CIRCLED DIGIT FIVE + \definesymbol[CircledSix][\USymbCharZapf{39}{123}] % DINGBAT NEGATIVE CIRCLED DIGIT SIX + \definesymbol[CircledSeven][\USymbCharZapf{39}{124}] % DINGBAT NEGATIVE CIRCLED DIGIT SEVEN + \definesymbol[CircledEight][\USymbCharZapf{39}{125}] % DINGBAT NEGATIVE CIRCLED DIGIT EIGHT + \definesymbol[CircledNine][\USymbCharZapf{39}{126}] % DINGBAT NEGATIVE CIRCLED DIGIT NINE + \definesymbol[CircledTen][\USymbCharZapf{39}{127}] % DINGBAT NEGATIVE CIRCLED NUMBER TEN + +\stopsymbolset + +\startsymbolset[Unicode Circled Sans-serif Digits] % 0x2700: Requires UnicodeRegular27 + + \definesymbol[CircledOne][\USymbCharZapf{39}{128}] % DINGBAT CIRCLED SANS-SERIF DIGIT ONE + \definesymbol[CircledTwo][\USymbCharZapf{39}{129}] % DINGBAT CIRCLED SANS-SERIF DIGIT TWO + \definesymbol[CircledThree][\USymbCharZapf{39}{130}] % DINGBAT CIRCLED SANS-SERIF DIGIT THREE + \definesymbol[CircledFour][\USymbCharZapf{39}{131}] % DINGBAT CIRCLED SANS-SERIF DIGIT FOUR + \definesymbol[CircledFive][\USymbCharZapf{39}{132}] % DINGBAT CIRCLED SANS-SERIF DIGIT FIVE + \definesymbol[CircledSix][\USymbCharZapf{39}{133}] % DINGBAT CIRCLED SANS-SERIF DIGIT SIX + \definesymbol[CircledSeven][\USymbCharZapf{39}{134}] % DINGBAT CIRCLED SANS-SERIF DIGIT SEVEN + \definesymbol[CircledEight][\USymbCharZapf{39}{135}] % DINGBAT CIRCLED SANS-SERIF DIGIT EIGHT + \definesymbol[CircledNine][\USymbCharZapf{39}{136}] % DINGBAT CIRCLED SANS-SERIF DIGIT NINE + \definesymbol[CircledTen][\USymbCharZapf{39}{137}] % DINGBAT CIRCLED SANS-SERIF NUMBER TEN + +\stopsymbolset + +\startsymbolset[Unicode Negative Circled Sans-serif Digits] % 0x2700: Requires UnicodeRegular27 + + \definesymbol[CircledOne][\USymbCharZapf{39}{138}] % DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE + \definesymbol[CircledTwo][\USymbCharZapf{39}{139}] % DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT TWO + \definesymbol[CircledThree][\USymbCharZapf{39}{140}] % DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT THREE + \definesymbol[CircledFour][\USymbCharZapf{39}{141}] % DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FOUR + \definesymbol[CircledFive][\USymbCharZapf{39}{142}] % DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FIVE + \definesymbol[CircledSix][\USymbCharZapf{39}{143}] % DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SIX + \definesymbol[CircledSeven][\USymbCharZapf{39}{144}] % DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SEVEN + \definesymbol[CircledEight][\USymbCharZapf{39}{145}] % DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT EIGHT + \definesymbol[CircledNine][\USymbCharZapf{39}{146}] % DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE + \definesymbol[CircledTen][\USymbCharZapf{39}{147}] % DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN + +\stopsymbolset + +\startsymbolset[Unicode Dingbat Arrows] % 0x2700: Requires UnicodeRegular27 + + \definesymbol[HeavyWideHeadedRightwardsArrow][\USymbCharZapf{39}{148}] % HEAVY WIDE-HEADED RIGHTWARDS ARROW + \definesymbol[HeavySouthEastArrow][\USymbCharZapf{39}{152}] % HEAVY SOUTH EAST ARROW + \definesymbol[HeavyRightwardsArrow][\USymbCharZapf{39}{153}] % HEAVY RIGHTWARDS ARROW + \definesymbol[HeavyNorthEastArrow][\USymbCharZapf{39}{154}] % HEAVY NORTH EAST ARROW + \definesymbol[DraftingPointRightwardsArrow][\USymbCharZapf{39}{155}] % DRAFTING POINT RIGHTWARDS ARROW + \definesymbol[HeavyRoundTippedRightwardsArrow][\USymbCharZapf{39}{156}] % HEAVY ROUND-TIPPED RIGHTWARDS ARROW + \definesymbol[TriangleHeadedRightwardsArrow][\USymbCharZapf{39}{157}] % TRIANGLE-HEADED RIGHTWARDS ARROW + \definesymbol[HeavyTriangleHeadedRightwardsArrow][\USymbCharZapf{39}{158}] % HEAVY TRIANGLE-HEADED RIGHTWARDS ARROW + \definesymbol[DashedTriangleHeadedRightwardsArrow][\USymbCharZapf{39}{159}] % DASHED TRIANGLE-HEADED RIGHTWARDS ARROW + \definesymbol[HeavyDashedTriangleHeadedRightwardsArrow][\USymbCharZapf{39}{160}] % HEAVY DASHED TRIANGLE-HEADED RIGHTWARDS ARROW + \definesymbol[BlackRightwardsArrow][\USymbCharZapf{39}{161}] % BLACK RIGHTWARDS ARROW + \definesymbol[3DTopLightedRightwardsArrowhead][\USymbCharZapf{39}{162}] % THREE-D TOP-LIGHTED RIGHTWARDS ARROWHEAD + \definesymbol[3DBottomLightedRightwardsArrowhead][\USymbCharZapf{39}{163}] % THREE-D BOTTOM-LIGHTED RIGHTWARDS ARROWHEAD + \definesymbol[BlackRightwardsArrowhead][\USymbCharZapf{39}{164}] % BLACK RIGHTWARDS ARROWHEAD + \definesymbol[HeavyBlackCurvedDownwardsAndRightwardsArrow][\USymbCharZapf{39}{165}] % HEAVY BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW + \definesymbol[HeavyBlackCurvedUpwardsAndRightwardsArrow][\USymbCharZapf{39}{166}] % HEAVY BLACK CURVED UPWARDS AND RIGHTWARDS ARROW + \definesymbol[SquatBlackRightwardsArrow][\USymbCharZapf{39}{167}] % SQUAT BLACK RIGHTWARDS ARROW + \definesymbol[HeavyConcavePointedBlackRightwardsArrow][\USymbCharZapf{39}{168}] % HEAVY CONCAVE-POINTED BLACK RIGHTWARDS ARROW + \definesymbol[CircledHeavyWhiteRightwardsArrow][\USymbCharZapf{39}{178}] % CIRCLED HEAVY WHITE RIGHTWARDS ARROW + \definesymbol[OpenOutlinedRightwardsArrow][\USymbCharZapf{39}{190}] % OPEN-OUTLINED RIGHTWARDS ARROW + +\stopsymbolset + +\startsymbolset[Unicode Shadowed Arrows] % 0x2700: Requires UnicodeRegular27 + + \definesymbol[RightShadedWhiteRightwardsArrow][\USymbCharZapf{39}{169}] % RIGHT-SHADED WHITE RIGHTWARDS ARROW + \definesymbol[LeftShadedWhiteRightwardsArrow][\USymbCharZapf{39}{170}] % LEFT-SHADED WHITE RIGHTWARDS ARROW + \definesymbol[BackTiltedShadowedWhiteRightwardsArrow][\USymbCharZapf{39}{171}] % BACK-TILTED SHADOWED WHITE RIGHTWARDS ARROW + \definesymbol[FrontTiltedShadowedWhiteRightwardsArrow][\USymbCharZapf{39}{172}] % FRONT-TILTED SHADOWED WHITE RIGHTWARDS ARROW + \definesymbol[HeavyLowerRightShadowedWhiteRightwardsArrow][\USymbCharZapf{39}{173}] % HEAVY LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW + \definesymbol[HeavyUpperRightShadowedWhiteRightwardsArrow][\USymbCharZapf{39}{174}] % HEAVY UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW + \definesymbol[NotchedLowerRightShadowedWhiteRightwardsArrow][\USymbCharZapf{39}{175}] % NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW + \definesymbol[NotchedUpperRightShadowedWhiteRightwardsArrow][\USymbCharZapf{39}{177}] % NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW + +\stopsymbolset + +\startsymbolset[Unicode Tailed Arrows] % 0x2700: Requires UnicodeRegular27 + + \definesymbol[WhiteFeatheredRightwardsArrow][\USymbCharZapf{39}{179}] % WHITE-FEATHERED RIGHTWARDS ARROW + \definesymbol[BlackFeatheredSouthEastArrow][\USymbCharZapf{39}{180}] % BLACK-FEATHERED SOUTH EAST ARROW + \definesymbol[BlackFeatheredRightwardsArrow][\USymbCharZapf{39}{181}] % BLACK-FEATHERED RIGHTWARDS ARROW + \definesymbol[BlackFeatheredNorthEastArrow][\USymbCharZapf{39}{182}] % BLACK-FEATHERED NORTH EAST ARROW + \definesymbol[HeavyBlack-featheredSouthEastArrow][\USymbCharZapf{39}{183}] % HEAVY BLACK-FEATHERED SOUTH EAST ARROW + \definesymbol[HeavyBlackFeatheredRightwardsArrow][\USymbCharZapf{39}{184}] % HEAVY BLACK-FEATHERED RIGHTWARDS ARROW + \definesymbol[HeavyBlackFeatheredNorthEastArrow][\USymbCharZapf{39}{185}] % HEAVY BLACK-FEATHERED NORTH EAST ARROW + \definesymbol[TeardropBarbedRightwardsArrow][\USymbCharZapf{39}{186}] % TEARDROP-BARBED RIGHTWARDS ARROW + \definesymbol[HeavyTeardropShankedRightwardsArrow][\USymbCharZapf{39}{187}] % HEAVY TEARDROP-SHANKED RIGHTWARDS ARROW + \definesymbol[WedgeTailedRightwardsArrow][\USymbCharZapf{39}{188}] % WEDGE-TAILED RIGHTWARDS ARROW + \definesymbol[HeavyWedgeTailedRightwardsArrow][\USymbCharZapf{39}{189}] % HEAVY WEDGE-TAILED RIGHTWARDS ARROW + +\stopsymbolset + +\endinput diff --git a/tex/context/base/symb-was.tex b/tex/context/base/symb-was.tex new file mode 100644 index 000000000..d6c324864 --- /dev/null +++ b/tex/context/base/symb-was.tex @@ -0,0 +1,205 @@ +%D \module +%D [ file=symb-was, +%D version=2005.10.15, +%D title=\CONTEXT\ Symbol Libraries, +%D subtitle=Roland Waldi's Symbols (wasy-2), +%D author=Henning Hraban Ramm, +%D date=\currentdate, +%D copyright={public domain}] +%C +%C This module is in the public domain. + +%D This module implements the Roland Waldi Symbole font +%D (wasy). The names are derived from the \LATEX\ package +%D \type {wasysym} by Axel Kielhorn. The symbols are +%D available as Type~1 font and are included in \TEX\ distributions. +%D +%D This symbol font offers basic sets of astronomical, astrological, +%D geometrical, musical and general symbols, plus those needed +%D for the APL programming language and some more. +%D This module leaves out most of the math stuff, such as operators +%D and integrals. +%D +%D The font was designed by Robert Waldi and is in the public domain. +%D The PS Type 1 fonts are by Taco Hoekwater, \hyphenatedurl +%D {taco.hoekwater@wkap.nl}, and also in the public domain. +%D The wasysym \LATEX\ package is (c) Axel Kielhorn, \hyphenatedurl +%D {A.Kielhorn@web.de}, under the LaTeX Project Public License. +%D This stuff lives in \hyphenatedurl {http://dante.ctan.org/CTAN/fonts/wasy2/}. +%D +%D This \CONTEXT\ module is by Henning Hraban Ramm, \hyphenatedurl +%D {hraban@fiee.net}, given to the public domain as far as allowed +%D (some parts are copied from the \LATEX\ package). + +%D Slightly patched by HH. + +\loadmapfile[original-wasy.map] + +% there are also fonts for 6, 7, 8, 9 pt; how can we access these automatically? +% how about the bold wasy font? + +\definefontsynonym [WaldiSymbol] [wasy10] +\definefontsynonym [WaldiSymbolBold] [wasyb10] + +\def\WaldiSymbol#1{\getglyph{WaldiSymbol}{\char#1}} + +\def\wasy@over#1#2{{\setbox0\hbox{$#2$}\hbox to \wd0{\hss$#1$\hss}\kern-\wd0\box0}} + +% general symbols + +\startsymbolset [wasy general] + \definesymbol [male] [\WaldiSymbol {26}] + \definesymbol [female] [\WaldiSymbol {25}] + \definesymbol [currency] [\WaldiSymbol {27}] + \definesymbol [cent] [\WaldiSymbol{103}] + \definesymbol [lozenge] [\WaldiSymbol {53}] + \definesymbol [kreuz] [\WaldiSymbol {54}] + \definesymbol [smiley] [\WaldiSymbol {44}] + \definesymbol [blacksmiley] [\WaldiSymbol {45}] + \definesymbol [frownie] [\WaldiSymbol {47}] + \definesymbol [sun] [\WaldiSymbol {46}] + \definesymbol [checked] [\WaldiSymbol {8}] + \definesymbol [brokenvert] [\WaldiSymbol{124}] + \definesymbol [diameter] [\WaldiSymbol {31}] + \definesymbol [invdiameter] [\WaldiSymbol {21}] + \definesymbol [phone] [\WaldiSymbol {7}] + \definesymbol [recorder] [\WaldiSymbol {6}] + \definesymbol [clock] [\WaldiSymbol {28}] + \definesymbol [permil] [\WaldiSymbol{104}] + \definesymbol [bell] [\WaldiSymbol {10}] + \definesymbol [ataribox] [\WaldiSymbol{109}] + \definesymbol [pointer] [\WaldiSymbol {9}] + \definesymbol [lightning] [\WaldiSymbol {18}] + \definesymbol [agemO] [\WaldiSymbol {48}] +\stopsymbolset + +\startsymbolset [wasy music] + \definesymbol [eighthnote] [\WaldiSymbol{11}] + \definesymbol [quarternote] [\WaldiSymbol{12}] + \definesymbol [halfnote] [\WaldiSymbol{13}] + \definesymbol [fullnote] [\WaldiSymbol{14}] + \definesymbol [twonotes] [\WaldiSymbol{15}] +\stopsymbolset + +\startsymbolset [wasy astronomy] + \definesymbol [ascnode] [\WaldiSymbol{19}] + \definesymbol [descnode] [\WaldiSymbol{20}] + \definesymbol [astrosun] [\mathematics{\odot}] + \definesymbol [sun] [\WaldiSymbol{46}] % additional + \definesymbol [newmoon] [\WaldiSymbol{32}] + \definesymbol [fullmoon] [\WaldiSymbol{35}] + \definesymbol [rightmoon] [\WaldiSymbol{37}] + \definesymbol [leftmoon] [\WaldiSymbol{36}] + \definesymbol [vernal] [\WaldiSymbol{23}] + \definesymbol [mercury] [\WaldiSymbol{39}] + \definesymbol [mars] [\dontleavehmode\lower.2ex\hbox{\WaldiSymbol{26}}] + \definesymbol [saturn] [\WaldiSymbol{89}] + \definesymbol [neptune] [\WaldiSymbol{91}] + \definesymbol [earth] [\dontleavehmode\lower.3ex\hbox{\WaldiSymbol{38}}] + \definesymbol [venus] [\dontleavehmode\raise.2ex\hbox{\WaldiSymbol{25}}] + \definesymbol [jupiter] [\WaldiSymbol{88}] + \definesymbol [uranus] [\WaldiSymbol{90}] + \definesymbol [pluto] [\WaldiSymbol{92}] +\stopsymbolset + +\startsymbolset [wasy astrology] + \definesymbol [conjunction] [\WaldiSymbol {86}] + \definesymbol [opposition] [\WaldiSymbol {87}] + \definesymbol [aries] [\WaldiSymbol {23}] + \definesymbol [libra] [\WaldiSymbol {97}] + \definesymbol [taurus] [\WaldiSymbol {93}] + \definesymbol [scorpio] [\WaldiSymbol {98}] + \definesymbol [gemini] [\WaldiSymbol {94}] + \definesymbol [sagittarius] [\WaldiSymbol {99}] + \definesymbol [cancer] [\WaldiSymbol {95}] + \definesymbol [capricornus] [\WaldiSymbol{100}] + \definesymbol [leo] [\WaldiSymbol {19}] + \definesymbol [aquarius] [\WaldiSymbol{101}] + \definesymbol [virgo] [\WaldiSymbol {96}] + \definesymbol [pisces] [\WaldiSymbol{102}] +\stopsymbolset + +\startsymbolset [wasy geometry] + \definesymbol [fivestar] [\WaldiSymbol {69}] % HHR additional + \definesymbol [hexstar] [\WaldiSymbol {65}] + \definesymbol [varhexstar] [\WaldiSymbol {66}] + \definesymbol [davidsstar] [\WaldiSymbol {67}] + \definesymbol [Circle] [\WaldiSymbol {35}] + \definesymbol [CIRCLE] [\WaldiSymbol {32}] + \definesymbol [Leftcircle] [\WaldiSymbol {73}] + \definesymbol [LEFTCIRCLE] [\WaldiSymbol {71}] + \definesymbol [Rightcircle] [\WaldiSymbol {74}] + \definesymbol [RIGHTCIRCLE] [\WaldiSymbol {72}] + \definesymbol [LEFTcircle] [\dontleavehmode\hbox to \zeropoint{\WaldiSymbol{71}\hss}\WaldiSymbol{35}] + \definesymbol [RIGHTcircle] [\dontleavehmode\hbox to \zeropoint{\WaldiSymbol{72}\hss}\WaldiSymbol{35}] + \definesymbol [LEFTarrow] [\WaldiSymbol {16}] + \definesymbol [RIGHTarrow] [\WaldiSymbol {17}] + \definesymbol [UParrow] [\WaldiSymbol {75}] + \definesymbol [DOWNarrow] [\WaldiSymbol {76}] + \definesymbol [Box] [\WaldiSymbol {50}] + \definesymbol [APLbox] [\WaldiSymbol{126}] + \definesymbol [XBox] [\WaldiSymbol {52}] + \definesymbol [Bowtie] [\WaldiSymbol {49}] + \definesymbol [Diamond] [\WaldiSymbol {51}] + \definesymbol [octagon] [\WaldiSymbol {56}] + \definesymbol [hexagon] [\WaldiSymbol {55}] + \definesymbol [varhexagon] [\WaldiSymbol {57}] + \definesymbol [pentagon] [\WaldiSymbol {68}] + \definesymbol [pentastar] [\dontleavehmode\hbox to \zeropoint{\WaldiSymbol{68}\hss}\lower.04em\hbox{\WaldiSymbol{69}}] % HHR additional +\stopsymbolset + +\startsymbolset [wasy physics] + \definesymbol [varangle] [\WaldiSymbol{30}] + \definesymbol [invneg] [\WaldiSymbol{24}] + \definesymbol [leftturn] [\WaldiSymbol{34}] + \definesymbol [rightturn] [\WaldiSymbol{33}] + \definesymbol [diameter] [\WaldiSymbol{31}] + \definesymbol [invdiameter] [\WaldiSymbol{21}] % additional + \definesymbol [therefore] [\WaldiSymbol {5}] + \definesymbol [AC] [\mbox{\kern.05em\WaldiSymbol{58}\kern.05em}] + \definesymbol [HF] [\dontleavehmode + \lower.09em\hbox to \zeropoint{\kern.05em\WaldiSymbol{58}\hss}% + \raise.09em\hbox{\kern.05em\WaldiSymbol{58}\kern.05em}] + \definesymbol [VHF] [\WaldiSymbol{64}] + \definesymbol [photon] [\hbox{\WaldiSymbol{58}\WaldiSymbol{58}\WaldiSymbol{58}\WaldiSymbol{58}}] + \definesymbol [gluon] [\hbox{\WaldiSymbol{80}\WaldiSymbol{80}\WaldiSymbol{80}\WaldiSymbol{80}\WaldiSymbol{80}\WaldiSymbol{80}}] +\stopsymbolset + +\startsymbolset [wasy apl] + \definesymbol [APLup] [\WaldiSymbol{0}] + \definesymbol [APLdown] [\WaldiSymbol{70}] + \definesymbol [APLbox] [\WaldiSymbol{126}] + \definesymbol [APLinv] [\dontleavehmode\hbox to \zeropoint{$\div$\hss}\WaldiSymbol{126}] + \definesymbol [APLleftarrowbox] [\WaldiSymbol{112}] + \definesymbol [APLrightarrowbox][\WaldiSymbol{113}] + \definesymbol [APLuparrowbox] [\WaldiSymbol{110}] + \definesymbol [APLdownarrowbox] [\WaldiSymbol{111}] + \definesymbol [APLinput] [\WaldiSymbol{125}] + \definesymbol [APLminus] [\dontleavehmode\raise.7ex\hbox{$-$}] + \definesymbol [APLlog] [\WaldiSymbol{22}] + \definesymbol [APLstar] [\WaldiSymbol{69}] + \definesymbol [APLcomment] [\WaldiSymbol{127}] + \definesymbol [notslash] [\wasy@over{/}{-}] + \definesymbol [notbackslash] [\wasy@over{\backslash}{-}] + % + %definesymbol [APLvert] [\WaldiSymbol{}] + %definesymbol [APLnot] [\WaldiSymbol{}] + %definesymbol [APLcirc] [\WaldiSymbol{}] + % + % HH: messy, best define all combinations (todo) + % + \def\APLnot #1{\wasy@over{\sim }{#1}} + \def\APLcirc#1{\wasy@over{\circ}{#1}} + \def\APLvert#1{\wasy@over{\vert}{#1}} + % +\stopsymbolset + +%D \showsymbolset[wasy general] +%D \showsymbolset[wasy music] +%D \showsymbolset[wasy astronomy] +%D \showsymbolset[wasy astrology] +%D \showsymbolset[wasy geometry] +%D \showsymbolset[wasy physics] +%D \showsymbolset[wasy apl] + +\endinput diff --git a/tex/context/base/syst-aux.mkiv b/tex/context/base/syst-aux.mkiv new file mode 100644 index 000000000..fcc1ee88f --- /dev/null +++ b/tex/context/base/syst-aux.mkiv @@ -0,0 +1,7018 @@ +%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 +\def\!!plustwo {2} % alongside \plustwo +\def\!!plusthree {3} % alongside \plusthree + +\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} + +\let\nextparenthesischaractertoken( + +\long\def\doifnextparenthesiselse#1#2% + {\def\nextparenthesiscommandyes{#1}% + \def\nextparenthesiscommandnop{#2}% + \futurelet\nexttoken\inspectnextparenthesischaracter} +\def\inspectnextparenthesischaracter + {\ifx\nexttoken\blankspace + \@EA\reinspectnextparenthesischaracter + \else + \@EA\inspectnextparenthesischaracterindeed + \fi} +\def\inspectnextparenthesischaracterindeed + {\ifx\nexttoken\nextparenthesischaractertoken + \@EA\nextparenthesiscommandyes + \else + \@EA\nextparenthesiscommandnop + \fi} + +%D The next one is handy in predictable situations: + +\long\def\doiffastoptionalcheckelse#1#2% + {\def\nextoptionalcommandyes{#1}% + \def\nextoptionalcommandnop{#2}% + \futurelet\nexttoken\dodoiffastoptionalcheckelse} + +\def\dodoiffastoptionalcheckelse + {\ifx\nexttoken\nextoptionalcharactertoken + \expandafter\nextoptionalcommandyes + \else + \expandafter\nextoptionalcommandnop + \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} + +\def\setuvalue #1{\normalprotected\expandafter \def\csname#1\endcsname} +\def\setuevalue #1{\normalprotected\expandafter\edef\csname#1\endcsname} +\def\setugvalue #1{\normalprotected\expandafter\gdef\csname#1\endcsname} +\def\setuxvalue #1{\normalprotected\expandafter\xdef\csname#1\endcsname} + +%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 {unexpanded} +%D +%D Because we use this module only in \MKIV, we have removed the +%D old protection code. +%D +%D \starttyping +%D \unexpanded\def\somecommand{... ... ...} +%D \stoptyping +%D +%D This overloads the \ETEX\ primitive but as we already had an \MKII\ +%D solution we keep the same name for a similar mechanism. + +\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 +%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 + +\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}]} + +% \def\processcommacommand[#1]% +% {\edef\expandedcommacommand{#1% +% \ifx\expandedcommacommand\empty\else +% \doprocesscommacommand +% \fi} +% +% \def\doprocesscommacommand +% {\expandafter\processcommalist\expandafter[\expandedcommacommand]} + +%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 {startprocesscommalist,startprocesscommacommand} +%D +%D Two more: + +\long\unexpanded\def\startprocesscommalist[#1]#2\stopprocesscommalist + {\long\def\currentcommalistcommand##1{\def\currentcommalistitem{##1}#2}% + \processcommalist[#1]\currentcommalistcommand} + +\long\unexpanded\def\startprocesscommacommand[#1]#2\stopprocesscommacommand + {\long\def\currentcommalistcommand##1{\def\currentcommalistitem{##1}#2}% + \normalexpanded{\noexpand\processcommacommand[#1]}\currentcommalistcommand} + +%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} + +\unexpanded\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 + {\normalexpanded{\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\getxparameters {\dogetparameters\dosetxvalue} +\def\forgetparameters{\dogetparameters\doignorevalue} + +\let\getexpandedparameters=\geteparameters + +\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\@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 +%D {processassignmentlist,processassignmentcommand, +%D startprocessassignmentlist,startprocessassignmentcommand} +%D +%D For Wolfgang: +%D +%D \starttyping +%D \def\showpair#1#2{key:#1, value:#2\par} +%D \processassignmentlist[a=1,b=2]\showpair +%D \stoptyping +%D +%D We can optimize this one if needed but it's not a core macro so hardly +%D worth the trouble and tokens. + +\def\processassignmentlist[#1]#2% #2 == \command{key}{value] + {\def\doprocessassignmententry##1{#2}% {##2}{##3} % namespace is ignored + \dogetparameters\doprocessassignmententry[][#1]} + +\def\processassignmentcommand[#1]% + {\normalexpanded{\noexpand\processassignmentlist[#1]}} + +\long\unexpanded\def\startprocessassignmentlist[#1]#2\stopprocessassignmentlist + {\long\def\currentassignmentlistcommand##1##2{\def\currentassignmentlistkey{##1}\def\currentassignmentlistvalue{##2}#2}% + \processassignmentlist[#1]\currentassignmentlistcommand} + +\long\unexpanded\def\startprocessassignmentcommand[#1]#2\stopprocessassignmentcommand + {\long\def\currentassignmentlistcommand##1##2{\def\currentassignmentlistkey{##1}\def\currentassignmentlistvalue{##2}#2}% + \normalexpanded{\noexpand\processassignmentlist[#1]}\currentassignmentlistcommand} + +%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} + +\def\xdoget@e@parameters#1]% + {\let\dosetnvalue\setsomevalue + \let\setsomevalue\dosetevalue + \let\p!doassign\p!e!doassign + \let\setsomevalue\dosetevalue + \xprocesscommaitem#1,],\@relax@ + \let\p!doassign\p!n!doassign + \let\setsomevalue\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} + +\unexpanded\def\getfromcommalist[#1]#2[#3]% + {\let\commalistelement\empty + \commalistcounter#3\relax + \processcommalist[#1]\p!dogetfromcommalist} + +\unexpanded\def\getfromcommacommand[#1]% + {\normalexpanded{\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 \unexpanded\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% we can make dedicated doifnextoptional's + {\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[]}} + +\unexpanded\def\definecomplexorsimple#1% + {\unexpanded\edef#1% + {\noexpand\docomplexorsimple + \@EA\noexpand\csname\s!complex\strippedcsname#1\endcsname + \@EA\noexpand\csname\s!simple \strippedcsname#1\endcsname}} + +\unexpanded\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\dodogetgroupargumentB + {\ifcase\@@permitspacesbetweengroups + \expandafter\dodogetgroupargumentF + \else + \expandafter\dodogetgroupargumentD + \fi} + +\def\dodogetgroupargumentD + {\doshowargumenterror + \dogroupargumentnop\dodogetargument{}} + +% \def\dodogetgroupargumentE +% {\begingroup\def\\ {\endgroup\dogetgroupargument\dogroupargumentyes\dogroupargumentnop}\\} + +\begingroup + \def\\ {\dogetgroupargument\dogroupargumentyes\dogroupargumentnop} + \global\let\dodogetgroupargumentE\\ +\endgroup + +\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: + +\unexpanded\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 + +% \starttexdefinition test +% oeps +% \stoptexdefinition +% +% [\test] + +\bgroup \obeylines + +\gdef\starttexdefinition% + {\bgroup% + \obeylines% + \dostarttexdefinition} + +\gdef\dostarttexdefinition #1 + {\catcode13=\@@ignore% + \doifinstringelse\letterhash{\detokenize{#1}}\dodostarttexdefinition\nonostarttexdefinition#1 + } + +\long\gdef\dodostarttexdefinition#1 #2 + {\dododostarttexdefinition{#1}{#2}} + +\long\gdef\dododostarttexdefinition#1#2#3\stoptexdefinition% + {\egroup% + \long\setvalue{#1}#2{#3}} + +\long\gdef\nonostarttexdefinition#1 + {\nononostarttexdefinition{#1}{}} + +\long\gdef\nononostarttexdefinition#1#2#3\stoptexdefinition% + {\egroup% + \long\setvalue{#1}{#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\checkedstrippedcsname#1% this permits \strippedcsname{\xxx} and \strippedcsname{xxx} + {\expandafter\docheckedstrippedcsname\string#1} + +\def\docheckedstrippedcsname#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,then} +%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\setfalse#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 + +\let\then\relax % so that we can say: \ifnum1>2\then -) + +%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\normalexpanded{\noexpand\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 frequently 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\ydorecurse#1#2% + {\global\advance\outerrecurse \plusone + \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel + \let\recurselevel\!!plusone + \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#2}% + \expandrecursecontent + \@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname + \global\advance\outerrecurse \minusone} + +\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\normalexpanded{\noexpand\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\resetrecurselevel{\let\recurselevel\!!zerocount} + +\def\dodofastrecurse + {\ifnum\fastrecursecounter>\lastrecursecounter + % \resetrecurselevel % slows down + \else + \fastrecursebody + \advance\fastrecursecounter\steprecursecounter + \expandafter\dodofastrecurse + \fi} + +% \appendtoks \resetrecurselevel \to \everydump + +\everydump\expandafter{\the\everydump\resetrecurselevel} + +%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% + {\ifx#1\everypar\else\newtoks#1\fi% 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 + +\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 \unexpanded\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 \unexpanded\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} + +\def\HandleNoGroup % retrofit into mkii + {\ifnum\currentgrouptype=\@@semisimplegroup + \expandafter\HandleNoGroupA + \else + \expandafter\HandleNoGroupB + \fi} + +\long\def\HandleNoGroupA#1#2% + {\long\def\AfterGroup{#2\endgroup}% + \begingroup\aftergroup\AfterGroup#1} + +\long\def\HandleNoGroupB#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. + +\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 + \normalexpanded{\noexpand\dorecurse{\number-\number#1}}{#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} + +% better: \def\flushtoks#1{\normalexpanded{\noexpand\dodoglobal#1\emptytoks\the#\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 \unexpanded\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} + +\unexpanded\def\startlocal {\dostartglobaldefs>-} +\unexpanded\def\stoplocal {\dostopglobaldefs} +\unexpanded\def\startglobal {\dostartglobaldefs<+} +\unexpanded\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 \unexpanded\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 + +\unexpanded\def\startstrictinspectnextcharacter + {\let\inspectnextcharacter\strictinspectnextcharacter} + +\unexpanded\def\stopstrictinspectnextcharacter + {\let\inspectnextcharacter\normalinspectnextcharacter} + +\def\strictdoifnextoptionalelse#1#2% + {\startstrictinspectnextcharacter + \doifnextcharelse[{\stopstrictinspectnextcharacter#1}{\stopstrictinspectnextcharacter#2}} + +%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 + +\unexpanded\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 Ok, here's another one, slower but seldom used. This one scans the text. +%D +%D \starttabulate[|Tc|Tc|] +%D \NC pt \NC \doifdimenstringelse {pt}{yes}{no} \NC \NR +%D \NC 12pt \NC \doifdimenstringelse {-12pt}{yes}{no} \NC \NR +%D \NC 1pt \NC \doifdimenstringelse {1pt}{yes}{no} \NC \NR +%D \NC 12pt \NC \doifdimenstringelse {12pt}{yes}{no} \NC \NR +%D \NC 12.0pt \NC \doifdimenstringelse {12.0pt}{yes}{no} \NC \NR +%D \NC -.12pt \NC \doifdimenstringelse {-.12pt}{yes}{no} \NC \NR +%D \NC .12pt \NC \doifdimenstringelse {.12pt}{yes}{no} \NC \NR +%D \NC -12pt \NC \doifdimenstringelse {-12pt}{yes}{no} \NC \NR +%D \NC -12.0pt \NC \doifdimenstringelse{-12.0pt}{yes}{no} \NC \NR +%D \NC big \NC \doifdimenstringelse {big}{yes}{no} \NC \NR +%D \NC 10 \NC \doifdimenstringelse {10}{yes}{no} \NC \NR +%D \NC 1 \NC \doifdimenstringelse {1}{yes}{no} \NC \NR +%D \stoptabulate + +\def\doifdimenstringelse#1{\normalexpanded{\noexpand\dodimenteststageone#1}\empty\empty]} + +\def\dodimenteststageone #1#2{\csname d!1!\ifcsname d!1!#2\endcsname#2\else x\fi\endcsname#2} +\def\dodimenteststagetwo #1#2{\csname d!2!\ifcsname d!2!#2\endcsname#2\else x\fi\endcsname#2} +\def\dodimenteststagethree #1]{\csname d!3!\ifcsname d!3!#1\endcsname#1\else x\fi\endcsname} + +\expandafter\let\csname d!1!x\endcsname\dodimenteststagethree +\expandafter\let\csname d!2!x\endcsname\dodimenteststagethree +\expandafter\let\csname d!3!x\endcsname\secondoftwoarguments + +\expandafter\let\csname d!1!.\endcsname\dodimenteststagetwo +\expandafter\let\csname d!1!,\endcsname\dodimenteststagetwo +\expandafter\let\csname d!1!1\endcsname\dodimenteststageone +\expandafter\let\csname d!1!2\endcsname\dodimenteststageone +\expandafter\let\csname d!1!3\endcsname\dodimenteststageone +\expandafter\let\csname d!1!4\endcsname\dodimenteststageone +\expandafter\let\csname d!1!5\endcsname\dodimenteststageone +\expandafter\let\csname d!1!6\endcsname\dodimenteststageone +\expandafter\let\csname d!1!7\endcsname\dodimenteststageone +\expandafter\let\csname d!1!8\endcsname\dodimenteststageone +\expandafter\let\csname d!1!9\endcsname\dodimenteststageone +\expandafter\let\csname d!1!0\endcsname\dodimenteststageone + +\expandafter\let\csname d!2!1\endcsname\dodimenteststagetwo +\expandafter\let\csname d!2!2\endcsname\dodimenteststagetwo +\expandafter\let\csname d!2!3\endcsname\dodimenteststagetwo +\expandafter\let\csname d!2!4\endcsname\dodimenteststagetwo +\expandafter\let\csname d!2!5\endcsname\dodimenteststagetwo +\expandafter\let\csname d!2!6\endcsname\dodimenteststagetwo +\expandafter\let\csname d!2!7\endcsname\dodimenteststagetwo +\expandafter\let\csname d!2!8\endcsname\dodimenteststagetwo +\expandafter\let\csname d!2!9\endcsname\dodimenteststagetwo +\expandafter\let\csname d!2!0\endcsname\dodimenteststagetwo + +\expandafter\let\csname d!3!pt\endcsname\firstoftwoarguments +\expandafter\let\csname d!3!pc\endcsname\firstoftwoarguments +\expandafter\let\csname d!3!in\endcsname\firstoftwoarguments +\expandafter\let\csname d!3!bp\endcsname\firstoftwoarguments +\expandafter\let\csname d!3!cm\endcsname\firstoftwoarguments +\expandafter\let\csname d!3!mm\endcsname\firstoftwoarguments +\expandafter\let\csname d!3!dd\endcsname\firstoftwoarguments +\expandafter\let\csname d!3!cc\endcsname\firstoftwoarguments +\expandafter\let\csname d!3!sp\endcsname\firstoftwoarguments +\expandafter\let\csname d!3!ex\endcsname\firstoftwoarguments +\expandafter\let\csname d!3!em\endcsname\firstoftwoarguments +\expandafter\let\csname d!3!nd\endcsname\firstoftwoarguments +\expandafter\let\csname d!3!nc\endcsname\firstoftwoarguments + +%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 +% \def\elapsedseconds{\expandafter\withoutpt\the\dimexpr\elapsedtime sp\relax} + +\def\resettimer {\ctxlua{commands.resettimer()}} +\def\elapsedtime {\ctxlua{commands.elapsedtime()}} +\let\elapsedseconds \elapsedtime + +\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\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} + +%D \macros +%D {processwords} +%D +%D Not that sophisticated but sometimes users (like in metafun). + +\def\doprocesswords#1 #2\od + {\doifsomething{#1}{\processword{#1} \doprocesswords#2 \od}} + +\def\processwords#1% + {\doprocesswords#1 \od}% no \unskip + +\let\processword\relax + +% new +% +% \startnointerference +% all kind of code +% \stopnointerference + +\newbox\nointerferencebox + +\unexpanded\def\startnointerference % not even grouped ! + {\setbox\nointerferencebox\vbox + \bgroup} + +\unexpanded\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} + +%D A variant for \type {\executeifdefined}: + +\def\expandcheckedcsname#1#2#3% + {\csname#1\ifcsname#1#2\endcsname#2\else#3\fi\endcsname} + +\protect \endinput diff --git a/tex/context/base/syst-con.lua b/tex/context/base/syst-con.lua new file mode 100644 index 000000000..638f3c797 --- /dev/null +++ b/tex/context/base/syst-con.lua @@ -0,0 +1,25 @@ +if not modules then modules = { } end modules ['syst-con'] = { + version = 1.001, + comment = "companion to syst-con.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +converters = converters or { } + +--[[ldx-- +

For raw 8 bit characters, the offset is 0x110000 (bottom of plane 18) at +the top of 's char range but outside the unicode range.

+--ldx]]-- + +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 diff --git a/tex/context/base/syst-con.mkii b/tex/context/base/syst-con.mkii new file mode 100644 index 000000000..877aad32a --- /dev/null +++ b/tex/context/base/syst-con.mkii @@ -0,0 +1,243 @@ +%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 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 +%D expandable macros. + +\def\dolchexnumber#1\relax + {\ifcase#1 0\or 1\or 2\or 3\or 4\or 5\or 6\or 7\or + 8\or 9\or a\or b\or c\or d\or e\or f\else 0\fi} + +\def\douchexnumber#1\relax + {\ifcase#1 0\or 1\or 2\or 3\or 4\or 5\or 6\or 7\or + 8\or 9\or A\or B\or C\or D\or E\or F\else 0\fi} + +\def\dolchexnumbers#1\relax + {\ifcase#1 + 00\or 01\or 02\or 03\or 04\or 05\or 06\or 07\or 08\or 09\or 0a\or 0b\or 0c\or 0d\or 0e\or 0f\or + 10\or 11\or 12\or 13\or 14\or 15\or 16\or 17\or 18\or 19\or 1a\or 1b\or 1c\or 1d\or 1e\or 1f\or + 20\or 21\or 22\or 23\or 24\or 25\or 26\or 27\or 28\or 29\or 2a\or 2b\or 2c\or 2d\or 2e\or 2f\or + 30\or 31\or 32\or 33\or 34\or 35\or 36\or 37\or 38\or 39\or 3a\or 3b\or 3c\or 3d\or 3e\or 3f\or + 40\or 41\or 42\or 43\or 44\or 45\or 46\or 47\or 48\or 49\or 4a\or 4b\or 4c\or 4d\or 4e\or 4f\or + 50\or 51\or 52\or 53\or 54\or 55\or 56\or 57\or 58\or 59\or 5a\or 5b\or 5c\or 5d\or 5e\or 5f\or + 60\or 61\or 62\or 63\or 64\or 65\or 66\or 67\or 68\or 69\or 6a\or 6b\or 6c\or 6d\or 6e\or 6f\or + 70\or 71\or 72\or 73\or 74\or 75\or 76\or 77\or 78\or 79\or 7a\or 7b\or 7c\or 7d\or 7e\or 7f\or + 80\or 81\or 82\or 83\or 84\or 85\or 86\or 87\or 88\or 89\or 8a\or 8b\or 8c\or 8d\or 8e\or 8f\or + 90\or 91\or 92\or 93\or 94\or 95\or 96\or 97\or 98\or 99\or 9a\or 9b\or 9c\or 9d\or 9e\or 9f\or + a0\or a1\or a2\or a3\or a4\or a5\or a6\or a7\or a8\or a9\or aa\or ab\or ac\or ad\or ae\or af\or + b0\or b1\or b2\or b3\or b4\or b5\or b6\or b7\or b8\or b9\or ba\or bb\or bc\or bd\or be\or bf\or + c0\or c1\or c2\or c3\or c4\or c5\or c6\or c7\or c8\or c9\or ca\or cb\or cc\or cd\or ce\or cf\or + d0\or d1\or d2\or d3\or d4\or d5\or d6\or d7\or d8\or d9\or da\or db\or dc\or dd\or de\or df\or + 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\douchexnumbers#1\relax + {\ifcase#1 + 00\or 01\or 02\or 03\or 04\or 05\or 06\or 07\or 08\or 09\or 0A\or 0B\or 0C\or 0D\or 0E\or 0F\or + 10\or 11\or 12\or 13\or 14\or 15\or 16\or 17\or 18\or 19\or 1A\or 1B\or 1C\or 1D\or 1E\or 1F\or + 20\or 21\or 22\or 23\or 24\or 25\or 26\or 27\or 28\or 29\or 2A\or 2B\or 2C\or 2D\or 2E\or 2F\or + 30\or 31\or 32\or 33\or 34\or 35\or 36\or 37\or 38\or 39\or 3A\or 3B\or 3C\or 3D\or 3E\or 3F\or + 40\or 41\or 42\or 43\or 44\or 45\or 46\or 47\or 48\or 49\or 4A\or 4B\or 4C\or 4D\or 4E\or 4F\or + 50\or 51\or 52\or 53\or 54\or 55\or 56\or 57\or 58\or 59\or 5A\or 5B\or 5C\or 5D\or 5E\or 5F\or + 60\or 61\or 62\or 63\or 64\or 65\or 66\or 67\or 68\or 69\or 6A\or 6B\or 6C\or 6D\or 6E\or 6F\or + 70\or 71\or 72\or 73\or 74\or 75\or 76\or 77\or 78\or 79\or 7A\or 7B\or 7C\or 7D\or 7E\or 7F\or + 80\or 81\or 82\or 83\or 84\or 85\or 86\or 87\or 88\or 89\or 8A\or 8B\or 8C\or 8D\or 8E\or 8F\or + 90\or 91\or 92\or 93\or 94\or 95\or 96\or 97\or 98\or 99\or 9A\or 9B\or 9C\or 9D\or 9E\or 9F\or + A0\or A1\or A2\or A3\or A4\or A5\or A6\or A7\or A8\or A9\or AA\or AB\or AC\or AD\or AE\or AF\or + B0\or B1\or B2\or B3\or B4\or B5\or B6\or B7\or B8\or B9\or BA\or BB\or BC\or BD\or BE\or BF\or + C0\or C1\or C2\or C3\or C4\or C5\or C6\or C7\or C8\or C9\or CA\or CB\or CC\or CD\or CE\or CF\or + D0\or D1\or D2\or D3\or D4\or D5\or D6\or D7\or D8\or D9\or DA\or DB\or DC\or DD\or DE\or DF\or + 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 + 010\or 011\or 012\or 013\or 014\or 015\or 016\or 017\or + 020\or 021\or 022\or 023\or 024\or 025\or 026\or 027\or + 030\or 031\or 032\or 033\or 034\or 035\or 036\or 037\or + 040\or 041\or 042\or 043\or 044\or 045\or 046\or 047\or + 050\or 051\or 052\or 053\or 054\or 055\or 056\or 057\or + 060\or 061\or 062\or 063\or 064\or 065\or 066\or 067\or + 070\or 071\or 072\or 073\or 074\or 075\or 076\or 077\or + 100\or 101\or 102\or 103\or 104\or 105\or 106\or 107\or + 110\or 111\or 112\or 113\or 114\or 115\or 116\or 117\or + 120\or 121\or 122\or 123\or 124\or 125\or 126\or 127\or + 130\or 131\or 132\or 133\or 134\or 135\or 136\or 137\or + 140\or 141\or 142\or 143\or 144\or 145\or 146\or 147\or + 150\or 151\or 152\or 153\or 154\or 155\or 156\or 157\or + 160\or 161\or 162\or 163\or 164\or 165\or 166\or 167\or + 170\or 171\or 172\or 173\or 174\or 175\or 176\or 177\or + 200\or 201\or 202\or 203\or 204\or 205\or 206\or 207\or + 210\or 211\or 212\or 213\or 214\or 215\or 216\or 217\or + 220\or 221\or 222\or 223\or 224\or 225\or 226\or 227\or + 230\or 231\or 232\or 233\or 234\or 235\or 236\or 237\or + 240\or 241\or 242\or 243\or 244\or 245\or 246\or 247\or + 250\or 251\or 252\or 253\or 254\or 255\or 256\or 257\or + 260\or 261\or 262\or 263\or 264\or 265\or 266\or 267\or + 270\or 271\or 272\or 273\or 274\or 275\or 276\or 277\or + 300\or 301\or 302\or 303\or 304\or 305\or 306\or 307\or + 310\or 311\or 312\or 313\or 314\or 315\or 316\or 317\or + 320\or 321\or 322\or 323\or 324\or 325\or 326\or 327\or + 330\or 331\or 332\or 333\or 334\or 335\or 336\or 337\or + 340\or 341\or 342\or 343\or 344\or 345\or 346\or 347\or + 350\or 351\or 352\or 353\or 354\or 355\or 356\or 357\or + 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\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}} + +\setvalue{@@uc@@a}{A} \setvalue{@@uc@@A}{A} +\setvalue{@@uc@@b}{B} \setvalue{@@uc@@B}{B} +\setvalue{@@uc@@c}{C} \setvalue{@@uc@@C}{C} +\setvalue{@@uc@@d}{D} \setvalue{@@uc@@D}{D} +\setvalue{@@uc@@e}{E} \setvalue{@@uc@@E}{E} +\setvalue{@@uc@@f}{F} \setvalue{@@uc@@F}{F} + +\def\hexstringtonumber#1% {FF} + {\dohexstringtonumber#1} + +\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 + +\catcode`\^^@=12 % ascii null == ignored in plain +\catcode`\^^?=12 % ascii delete == invalid in plain + +\let\or\relax + +\xdef\rawcharacter{ ^^00\or} + +\dorecurse{255} + {\lccode`a=\recurselevel + \lowercase{\xdef\rawcharacter{\rawcharacter \string a\or}}} % string is needed for XeTeX + +\@EA\gdef\@EA\rawcharacter\@EA#\@EA1\@EA + {\@EA\ifcase\@EA#\@EA1\rawcharacter\fi} + +\egroup + +\protect \endinput diff --git a/tex/context/base/syst-con.mkiv b/tex/context/base/syst-con.mkiv new file mode 100644 index 000000000..f7d4150a6 --- /dev/null +++ b/tex/context/base/syst-con.mkiv @@ -0,0 +1,145 @@ +%D \module +%D [ file=syst-con, +%D version=2006.09.16, % real old stuff ... 2000.12.10 +%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. + +\registerctxluafile{syst-con}{1.001} + +\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. + +%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")}} + +%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-ext.mkii b/tex/context/base/syst-ext.mkii new file mode 100644 index 000000000..73fb98b72 --- /dev/null +++ b/tex/context/base/syst-ext.mkii @@ -0,0 +1,5025 @@ +%D \module +%D [ file=syst-ext, +%D version=1995.10.10, +%D title=\CONTEXT\ System 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 System Macros / Extras} + +%D In this second system module, we continue the definition of +%D some handy commands. + +\unprotect + +%D \macros +%D {rawgetparameters} +%D +%D A raw and dirty alternative for \type {\getparameters}; no +%D checking is done! + +% \def\rawgetparameters[#1][#2]% scheelt 5\% +% {\def\rawparameterprefix{#1}% +% \expandafter\rawsetparameter#2,]=,} + +\def\rawsetparameter#1=#2,% + {\if]#1\else + \expandafter\def\csname\rawparameterprefix#1\endcsname{#2}% + \expandafter\rawsetparameter + \fi} + +% the next one handles empty #1 okay: + +\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\doglobal + {\let\redoglobal\global + \def\dodoglobal{\resetglobal\global}} + +\def\resetglobal + {\let\redoglobal\relax + \let\dodoglobal\relax} + +\resetglobal + +%D New: + +\def\doglobal + {\ifx\redoglobal\relax + \let\redoglobal\global + \let\dodoglobal\@@dodoglobal + %\else + % \writestatus{system}{global not reset, warn me!}% + \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% + {\ifx#1\undefined + \expandafter\def + \else + \message{[\noexpand#1is already defined]}% + \expandafter\def\expandafter\gobbleddefinition + \fi#1} + +\def\redefine#1% + {\ifx#1\undefined\else + \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 + {\catcode13=\@@ignore% + \doifinstringelse\letterhash{\detokenize{#1}}\dodostarttexdefinition\nonostarttexdefinition#1 + } + +\long\gdef\dodostarttexdefinition#1 #2 + {\dododostarttexdefinition{#1}{#2}} + +\long\gdef\dododostarttexdefinition#1#2#3\stoptexdefinition% + {\egroup% + \long\setvalue{#1}#2{#3}} + +\long\gdef\nonostarttexdefinition#1 + {\nononostarttexdefinition{#1}{}} + +\long\gdef\nononostarttexdefinition#1#2#3\stoptexdefinition% + {\egroup% + \long\setvalue{#1}{#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} + +% This is the original implementation: +% +% \def\dodododoincrement(#1,#2)% +% {\ifx#1\undefined +% \redoglobal\let#1\zerocountervalue +% \else\ifx#1\relax % \csname...\endcsname +% \redoglobal\let#1\zerocountervalue +% \fi\fi +% \scratchcounter=#2\relax +% \scratchcounter=\incrementsign\scratchcounter +% \advance\scratchcounter #1\relax +% \dodoglobal\edef#1{\the\scratchcounter}} +% +% \def\dododoincrement#1% +% {\dodododoincrement(#1,1)} +% +% \def\dodoincrement(#1% +% {\doifnextcharelse,% +% {\dodododoincrement(#1}{\dodododoincrement(#1,1}} +% +% \def\doincrement#1% +% {\def\incrementsign{#1}% +% \doifnextcharelse(\dodoincrement\dododoincrement} +% +% \def\increment{\doincrement+} +% \def\decrement{\doincrement-} +% +% And this is the one optimized for speed: + +% maxcounter = 2\maxdimen=1 + +\def\!!zerocount {0} % alongside \zerocount +\def\!!minusone {-1} % alongside \minusone +\def\!!plusone {1} % alongside \plusone + +\beginTEX + +\def\dodoindecrement#1(#2,#3)% + {\ifx#2\undefined + \redoglobal\let#2\zerocountervalue + \else\ifx#2\relax % \csname...\endcsname + \redoglobal\let#2\zerocountervalue + \fi\fi + \scratchcounter#3\relax + \scratchcounter#1\scratchcounter + \advance\scratchcounter#2\relax + \dodoglobal\edef#2{\the\scratchcounter}} + +\def\dodoincrement(#1% + {\doifnextcharelse,{\dodoindecrement+(#1}{\dodoindecrement+(#1,1}} + +\def\dododecrement(#1% + {\doifnextcharelse,{\dodoindecrement-(#1}{\dodoindecrement-(#1,1}} + +\def\doincrement#1% 10% faster alternative + {\ifx#1\undefined + \dodoglobal\let#1\!!plusone + \else\ifx#1\relax % \csname...\endcsname + \dodoglobal\let#1\!!plusone + \else + \fastincrement#1% + \fi\fi} + +\def\dodecrement#1% 10% faster alternative + {\ifx#1\undefined + \dodoglobal\let#1\!!minusone + \else\ifx#1\relax % \csname...\endcsname + \dodoglobal\let#1\!!minusone + \else + \fastdecrement#1% + \fi\fi} + +\def\fastdecrement#1% 50% faster alternative + {\scratchcounter#1\advance\scratchcounter\minusone + \dodoglobal\edef#1{\the\scratchcounter}} + +\def\fastincrement#1% 50% faster alternative + {\scratchcounter#1\advance\scratchcounter\plusone + \dodoglobal\edef#1{\the\scratchcounter}} + +\endTEX + +\beginETEX \numexpr + +% \def\doindecrement#1#2% +% {\dodoglobal\edef#2% +% {\the\numexpr(\ifx#2\undefined\else\ifx#2\relax\else#2\fi\fi#11)}} +% +% \def\doincrement{\doindecrement+} +% \def\dodecrement{\doindecrement-} +% +% some 3\% faster: + +\def\doindecrement#1#2% + {\dodoglobal\edef#2% + {\the\numexpr\ifx#2\undefined\else\ifx#2\relax\else#2\fi\fi+#1\relax}} + +\def\doincrement{\doindecrement\plusone } +\def\dodecrement{\doindecrement\minusone} + +\def\dodoindecrement#1#2,#3)% + {\dodoglobal\edef#2% + {\the\numexpr\ifx#2\undefined\else\ifx#2\relax\else#2\fi\fi#1#3\relax}} + +\def\dodoincrement(#1% + {\doifnextcharelse,{\dodoindecrement+#1}{\dodoindecrement+#1,\plusone}} + +\def\dododecrement(#1% + {\doifnextcharelse,{\dodoindecrement-#1}{\dodoindecrement-#1,\plusone}} + +\def\fastincrement#1{\dodoglobal\edef#1{\the\numexpr#1+\plusone \relax}} +\def\fastdecrement#1{\dodoglobal\edef#1{\the\numexpr#1+\minusone\relax}} + +\endETEX + +\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% + {\ifx#1\undefined + \advance\maximumsignal 2sp % to be save in rounding + \edef#1{\the\maximumsignal}% + \fi} + +%D \macros +%D {newskimen} +%D +%D \TEX\ offers 256 \DIMENSIONS\ and \SKIPS. Unfortunately this +%D amount is too small to suit certain packages. Therefore when +%D possible one should use: +%D +%D \starttyping +%D \newskimen\tempskimen +%D \stoptyping +%D +%D This commands allocates a \DIMENSION\ or a \SKIP, depending +%D on the availability. One should be aware of the difference +%D between both. When searching for some glue \TEX\ goes on +%D searching till it's sure that no other glue component if +%D found. This search can be canceled by using \type{\relax} +%D when possible and needed. +%D +%D \starttyping +%D \def\newskimen#1% +%D {\ifx#1\undefined +%D \ifnum\count11>\count12 +%D \newskip#1\relax +%D \else +%D \newdimen#1\relax +%D \fi +%D \fi} +%D \stoptyping +%D +%D In order to make this macro work in plain \TEX\ too, we +%D use the following alternative, which fools \TEX\ about +%D the new commands being \type {\outer} ones. + +% \def\newskimen#1% +% {\ifx#1\undefined +% \csname new\ifnum\count11>\count12 skip\else dimen\fi\endcsname#1% +% \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 +%D +%D This expands to \type{\ifsomething}. +%D +%D \starttyping +%D \def\strippedcsname +%D {\expandafter\gobbleoneargument\string} +%D \stoptyping +%D +%D Slower but better: + +\ifx\letterbackslash\undefined + {\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% + {\ifundefined{normal\strippedcsname#1}% + \letvalue{normal\strippedcsname#1}#1% + \fi} + +%D \macros +%D {newconditional, +%D settrue, setfalse, +%D ifconditional,then} +%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\setfalse#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} + +\let\newconditional = \setfalse +\let\ifconditional = \ifcase + +\let\then\relax % so that we can say \ifnum1>2\then -) + +%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 + +%D Acceptable: +%D +%D \starttyping +%D \long\def\dostepwiserecurse#1#2#3% +%D {\let\nextrecurse\gobblefourarguments +%D \ifnum#3>0\relax\ifnum#2<#1\relax\else +%D \def\nextrecurse{\dosetstepwiserecurse>}% +%D \fi\fi +%D \ifnum#3<0\relax\ifnum#1<#2\relax\else +%D \def\nextrecurse{\dosetstepwiserecurse<}% +%D \fi\fi +%D \nextrecurse{#1}{#2}{#3}} +%D \stoptyping +%D +%D Better: +%D +%D \starttyping +%D \long\def\dostepwiserecurse#1#2#3% +%D {\let\nextrecurse\gobblefourarguments +%D \ifnum#3>0\relax \ifnum#2<#1\relax \else +%D \def\nextrecurse{\dosetstepwiserecurse>}% +%D \fi \else \ifnum#3<0\relax \ifnum#1<#2\relax \else +%D \def\nextrecurse{\dosetstepwiserecurse<}% +%D \fi \fi \fi +%D \nextrecurse{#1}{#2}{#3}} +%D +%D \def\@@irecurse{@@irecurse} % stepper +%D \def\@@nrecurse{@@nrecurse} % number of steps +%D \def\@@srecurse{@@srecurse} % step +%D \def\@@drecurse{@@drecurse} % direction, < or > +%D \def\@@arecurse{@@arecurse} % action +%D +%D \long\def\dosetstepwiserecurse#1#2#3#4#5% +%D {\global\advance\outerrecurse 1 +%D \setevalue{\@@drecurse\recursedepth}{#1}% +%D \setevalue{\@@irecurse\recursedepth}{\number#2}% +%D \setevalue{\@@nrecurse\recursedepth}{\number#3}% +%D \setevalue{\@@srecurse\recursedepth}{\number#4}% +%D \long\setvalue{\@@arecurse\recursedepth}{#5}% +%D \dodorecurse} +%D +%D \def\donorecurse +%D {} +%D +%D \def\dododorecurse +%D {\edef\recurselevel{\csname\@@irecurse\recursedepth\endcsname}% +%D \getvalue{\@@arecurse\recursedepth}% +%D \edef\recurselevel{\csname\@@irecurse\recursedepth\endcsname}% +%D \innerrecurse\recurselevel +%D \advance\innerrecurse \csname\@@srecurse\recursedepth\endcsname +%D \setevalue{\@@irecurse\recursedepth}{\the\innerrecurse}% +%D \dodorecurse} +%D +%D \def\dodorecurse +%D {\ifnum\csname\@@irecurse\recursedepth\endcsname +%D \csname\@@drecurse\recursedepth\endcsname +%D \csname\@@nrecurse\recursedepth\endcsname\relax +%D \expandafter\nododorecurse +%D \else +%D \expandafter\dododorecurse +%D \fi} +%D +%D \def\nododorecurse +%D {\global\advance\outerrecurse -1 +%D \edef\recurselevel{\csname\@@irecurse\recursedepth\endcsname}} +%D \stoptyping +%D +%D Cleaner and much faster: + +\def\@@irecurse{@@ir@@} % ecurse} % stepper +\def\@@arecurse{@@ar@@} % ecurse} % action + +% \mathchardef + +\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}}} + +\beginETEX \numexpr + +\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}} + +\endETEX + +\beginTEX + +\long\def\dodostepwiserecurse#1#2#3% from to step + {\ifnum#1>#2\relax + \@EA\nodostepwiserecurse + \else + \def\recurselevel{#1}% + \innerrecurse#1\advance\innerrecurse#3\relax + \@EAEAEA\redostepwiserecurse\@EA + \fi\@EA{\the\innerrecurse}{#2}{#3}} + +\endTEX + +\def\expandrecursecontent + {\csname\@@arecurse\recursedepth\endcsname} + +\def\redostepwiserecurse + {\expandrecursecontent\dodostepwiserecurse} + +\beginETEX \numexpr + +\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}} + +\endETEX + +\beginTEX + +\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}} + +\endTEX + +\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} + +\beginETEX \numexpr + +\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}} + +\endETEX + +\beginTEX + +\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}} + +\endTEX + +\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}. +%D +%D If we write this macros from scratch, we end up with +%D something like the ones described above: +%D +%D \starttyping +%D \def\@@eloop{@@eloop} % exit +%D \def\@@iloop{@@iloop} % stepper +%D \def\@@aloop{@@aloop} % action +%D +%D \newcount\outerloop +%D +%D \def\loopdepth% +%D {\the\outerloop} +%D +%D \def\exitloop% +%D {\setevalue{\@@eloop\loopdepth}{0}} +%D +%D \long\def\doloop#1% +%D {\global\advance\outerloop by 1 +%D \setevalue{\@@iloop\loopdepth}{1}% +%D \setevalue{\@@eloop\loopdepth}{1}% +%D \long\setvalue{\@@aloop\loopdepth}{#1}% +%D \dodoloop} +%D +%D \def\dodonoloop% +%D {\global\advance\outerloop by -1\relax} +%D +%D \def\dododoloop% +%D {\edef\looplevel{\getvalue{\@@iloop\loopdepth}}% +%D \innerrecurse=\looplevel +%D \advance\innerrecurse by 1 +%D \setevalue{\@@iloop\loopdepth}{\the\innerrecurse}% +%D \getvalue{\@@aloop\loopdepth}% +%D \edef\looplevel{\getvalue{\@@iloop\loopdepth}}% +%D \dodoloop} +%D +%D \def\dodoloop% +%D {\ifnum\getvalue{\@@eloop\loopdepth}=0 +%D \expandafter\dodonoloop +%D \else +%D \expandafter\dododoloop +%D \fi} +%D +%D \def\doloop% +%D {\dostepwiserecurse{1}{\maxdimen}{1}} +%D +%D \def\exitloop +%D {\setvalue{\@@irecurse\recursedepth}{\maxdimen}} +%D +%D \def\looplevel{\recurselevel} +%D \def\loopdepth{\recursedepth} +%D \stoptyping +%D +%D We don't have to declare new counters for \type{\looplevel} +%D and \type{\loopdepth} because we can use \type{\recurselevel} +%D and \type{\recursedepth}. +%D +%D We prefer however a more byte saving implementation, that +%D executes of course a bit slower. +%D +%D \starttyping +%D \def\doloop% +%D {\dostepwiserecurse1\maxdimen1} +%D +%D \def\exitloop% +%D {\letvalue{\@@irecurse\recursedepth}\maxdimen} +%D \stoptyping +%D +%D Although, the next version is faster because it used the +%D simple loop. + +\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 + +\beginETEX \numexpr + +\long\def\dodoloop#1% + {\def\recurselevel{#1}% + \@EA\redoloop\@EA{\the\numexpr\recurselevel+\plusone\relax}} + +\endETEX + +\beginTEX + +\long\def\dodoloop#1% + {\def\recurselevel{#1}% + \innerrecurse#1\advance\innerrecurse\plusone + \@EA\redoloop\@EA{\the\innerrecurse}} + +\endTEX + +\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 frequently 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\ydorecurse#1#2% + {\global\advance\outerrecurse \plusone + \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel + \let\recurselevel\!!plusone + \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#2}% + \expandrecursecontent + \@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname + \global\advance\outerrecurse \minusone} + +\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 + +%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\resetrecurselevel{\let\recurselevel\!!zerocount} + +\def\dodofastrecurse + {\ifnum\fastrecursecounter>\lastrecursecounter + % \resetrecurselevel % slows down + \else + \fastrecursebody + \advance\fastrecursecounter\steprecursecounter + \expandafter\dodofastrecurse + \fi} + +% \appendtoks \resetrecurselevel \to \everydump + +\everydump\expandafter{\the\everydump\resetrecurselevel} + +%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. +%D +%D The definition command \type{\DoWithEvery} will be quite +%D unreadable, so let's first show an implementation that +%D shows how things are done: +%D +%D \starttyping +%D \newtoks \everyline +%D \newtoks \oldeveryline +%D \newif \ifeveryline +%D +%D \def\DoWithEvery#1#2#3#4% +%D {#3\else\edef\next{\noexpand#2={\the#1}}\next\fi +%D \edef\next{\noexpand#1={\the#2\the\scratchtoks}}\next +%D #4} +%D +%D \def\doEveryLine% +%D {\DoWithEvery\everyline\oldeveryline\ifeveryline\everylinetrue} +%D +%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. + +% the old one +% +% \def\DoWithEvery#1% +% {\csname if\strippedcsname#1\endcsname \else +% \edef\next% +% {\@EA\noexpand\csname old\strippedcsname#1\endcsname= +% {\the#1}}% +% \next +% \fi +% \edef\next% +% {\noexpand#1= +% {\@EA\the\csname old\strippedcsname#1\endcsname\the\scratchtoks}}% +% \next +% \csname\strippedcsname#1true\endcsname} +% +% \def\dowithevery#1% +% {\@EA\afterassignment\csname do\strippedcsname#1\endcsname\scratchtoks} +% +% \def\newevery#1#2% +% {\ifx#1\undefined\newtoks#1\fi +% \ifx#2\relax\else\ifx#2\undefined +% \@EA\newtoks\csname old\strippedcsname#1\endcsname +% \@EA\newif \csname if\strippedcsname#1\endcsname +% \@EA\def \csname do\strippedcsname#2\endcsname{\DoWithEvery#1}% +% \def#2{\dowithevery#2}% +% \fi\fi} +% +% cleaner and more efficient + +%\def\dowithevery#1% +% {\def\dodowithevery% +% {\ifcase\csname c\strippedcsname#1\endcsname \expandafter\chardef +% \csname c\strippedcsname#1\endcsname=1 +% \csname t\strippedcsname#1\endcsname=#1% +% \fi +% \edef\next% +% {#1={\the\csname t\strippedcsname#1\endcsname\the\scratchtoks}}% +% \next}% +% \afterassignment\dodowithevery\scratchtoks} +% +% more efficient: + +\def\dodowithevery#1% + {\ifcase\csname c\strippedcsname#1\endcsname \expandafter\chardef + \csname c\strippedcsname#1\endcsname1 + \csname t\strippedcsname#1\endcsname#1% + \fi + \edef\next% + {#1{\the\csname t\strippedcsname#1\endcsname\the\scratchtoks}}% + \next} + +\def\dowithevery#1% + {\def\next{\dodowithevery#1}% + \afterassignment\next\scratchtoks} + +\bgroup \let\newtoks\relax % plain safe (\outer) + +\gdef\newevery#1#2% + {\ifx#1\undefined\csname newtoks\endcsname#1\fi % plain safe (\outer) + \ifx#2\relax\else\ifx#2\undefined + \expandafter\newtoks\csname t\strippedcsname#1\endcsname + \expandafter\chardef\csname c\strippedcsname#1\endcsname\zerocount + \def#2{\dowithevery#1}% + \fi\fi} + +\egroup + +%D The first \type {\outer} hack is needed to trick \TEX\ +%D into thinking that \type {\newtoks} is no outer macro, +%D the second hack is needed due to some funny interaction +%D between outer macros and \type {\if} at expansion time. + +%D This one permits definitions like: + +\newevery \everypar \EveryPar +\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. + +\beginTEX + +\def\doconvertargument#1>{} + +\def\convertedcommand + {\expandafter\doconvertargument\meaning} + +\long\def\convertargument#1\to#2% + {\long\def#2{#1}% saves a restore + \dodoglobal\edef#2{\convertedcommand#2}} + +\long\def\convertcommand#1\to#2% + {\dodoglobal\edef#2{\convertedcommand#1}} + +% no dodoglobal ! + +\long\def\defconvertedargument#1#2% less sensitive for \to + {\long\def#1{#2}% saves a restore + \edef#1{\convertedcommand#1}} + +\long\def\defconvertedcommand#1#2% less sensitive for \to + {\edef#1{\convertedcommand#2}} + +\long\def\gdefconvertedargument#1#2% less sensitive for \to + {\long\gdef#1{#2}% saves a restore + \xdef#1{\convertedcommand#1}} + +\long\def\gdefconvertedcommand#1#2% less sensitive for \to + {\xdef#1{\convertedcommand#2}} + +\endTEX + +\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 + +% not robust +% +% \def\doifassignmentelse% +% {\doifinstringelse{=}} +% +% readable +% +% \def\doifassignmentelse#1% +% {\convertargument#1\to\ascii +% \doifinstringelse{=}{\ascii}} + +\def\doifassignmentelse#1% + {\convertargument#1\to\ascii + \doifinstringelse=\ascii} + +%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% + {\convertargument#2\to\asciiafter + \@EA#1\@EA{\asciiafter}} + +%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). + +% command variant: one level expansion ! + +\beginETEX \detokenize + +\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}}} + +\endETEX + +%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} + +\beginETEX + +\def\showvalue#1% + {\ifcsname#1\endcsname + \expandafter\show\csname#1\endcsname + \else + \show\undefined + \fi} + +\endETEX + +\long\def\showargument#1% + {\defconvertedargument\ascii{#1}\ascii} + +%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. + +\def\@@doifsamestringelse#1#2% + {\edef\!!stringa{#1}% + \edef\!!stringb{#2}% + \convertcommand\!!stringa\to\!!stringa + \convertcommand\!!stringb\to\!!stringb + \ifx\!!stringa\!!stringb} + +\def\doifsamestringelse#1#2% + {\@@doifsamestringelse{#1}{#2}% + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +\def\doifsamestring#1#2% + {\@@doifsamestringelse{#1}{#2}% + \expandafter\firstofoneargument + \else + \expandafter\gobbleoneargument + \fi} + +\def\doifnotsamestring#1#2% + {\@@doifsamestringelse{#1}{#2}% + \expandafter\gobbleoneargument + \else + \expandafter\firstofoneargument + \fi} + +%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. + +\beginTEX + +\long\def\ConvertToConstant#1#2#3% + {\expandafter\defconvertedargument\expandafter\!!stringa\expandafter{#2}% + \expandafter\defconvertedargument\expandafter\!!stringb\expandafter{#3}% + #1{\!!stringa}{\!!stringb}} + +\endTEX + +\beginETEX \detokenize + +\long\def\ConvertToConstant#1#2#3% + {\edef\!!stringa{\expandafter\detokenize\expandafter{#2}}% + \edef\!!stringb{\expandafter\detokenize\expandafter{#3}}% + #1{\!!stringa}{\!!stringb}} + +\endETEX + +%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 One should say that the next implementation would suffice: +%D +%D \starttyping +%D \def\groupedcommand#1#2% +%D {\def\BeforeGroup{#1\ignorespaces}% +%D \def\AfterGroup{\unskip#2\egroup}% +%D \bgroup\bgroup +%D \aftergroup\AfterGroup +%D \afterassignment\BeforeGroup +%D \let\next=} +%D \stoptyping +%D +%D It did indeed, but one day we decided to support the +%D processing of boxes too: +%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. +%D +%D \starttyping +%D \long\unexpanded\def\groupedcommand#1#2% +%D {\bgroup +%D \long\def\BeforeGroup% +%D {\bgroup#1\bgroup\aftergroup\AfterGroup}% +%D \long\def\AfterGroup% +%D {#2\egroup\egroup}% +%D \afterassignment\BeforeGroup +%D \let\next=} +%D \stoptyping +%D +%D We used this method some time until the next alternative +%D was needed. From now on we support both +%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 These macros come together in: +%D +%D \starttyping +%D \long\unexpanded\def\groupedcommand#1#2% +%D {\def\dogroupedcommand% +%D {\ifx\next\bgroup +%D \let\next=\HandleGroup +%D \else +%D \let\next=\HandleNoGroup +%D \fi +%D \next{#1}{#2}}% +%D \futurelet\next\dogroupedcommand} +%D \stoptyping +%D +%D From the missing paragraph number one can deduce that the +%D last macro is not the real one yet. I considered it a +%D 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% +% {\bgroup +% \def\dogroupedcommand% +% {\ifx\next\bgroup +% \def\\{\egroup\HandleGroup{#1}{#2}}% +% \else\ifx\next\blankspace +% \def\\ {\egroup\groupedcommand{#1}{#2}}% +% \else +% \def\\{\egroup\HandleNoGroup{#1}{#2}}% +% \fi\fi +% \\}% +% \futurelet\next\dogroupedcommand} +% +% compatible ? + +\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 + +%D The original definition was: +%D +%D \starttyping +%D \def\doGotoPar +%D {\ifx\nextchar\blankspace +%D \@EA\GotoPar +%D \else\ifx\nextchar\endoflinetoken +%D \@EAEAEA\GotoPar +%D \else +%D \@EAEAEA\dodoGotoPar +%D \fi\fi} +%D +%D \def\dodoGotoPar +%D {\the\BeforePar +%D \BeforePar\emptytoks +%D \nextchar} +%D +%D \def\GotoPar +%D {\afterassignment\doGotoPar\let\nextchar=} +%D \stoptyping + +%D Its big brother \type{\GetPar} redefines the \type{\par} +%D primitive, which can lead to unexpected results, depending +%D in the context. +%D +%D \starttyping +%D \def\GetPar +%D {\expanded +%D {\BeforePar +%D {\the\BeforePar +%D \BeforePar\emptytoks +%D \bgroup +%D \def\par +%D {\egroup +%D \par +%D \the\AfterPar +%D \BeforePar\emptytoks +%D \AfterPar\emptytoks}}}% +%D \GotoPar} +%D \stoptyping + +%D However, we can implement a better alternative by using: +%D +%D \starttyping +%D \def\dowithpar#1#2% +%D {\def\handlepar##1\par{#1##1#2}% +%D \def\gobblepar\par{\dowithpar{#1}{#2}}% +%D \doifnextcharelse\par\gobblepar\handlepar} +%D \stoptyping +%D +%D Or, nicer + +\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} + +%D The previosuly defined macros now become: + +\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 +%D +%D We show two implementations, of which for the moment the +%D we prefier to use the second one: +%D +%D \starttyping +%D \def\dowithpargument#1% +%D {\def\dodowithpargument% +%D {\ifx\next\bgroup +%D \def\next{#1}% +%D \else +%D \def\next####1 \par{#1{####1}}% +%D \fi +%D \next}% +%D \futurelet\next\dodowithpargument} +%D \stoptyping +%D +%D A second and better implementation was: +%D +%D \starttyping +%D \def\dowithpargument#1% +%D {\def\nextpar##1 \par{#1{##1}}% +%D \def\nextarg##1{#1{##1}}% +%D \doifnextcharelse\bgroup +%D {\nextarg} +%D {\nextpar}} +%D \stoptyping +%D +%D We ended up with an alternative that also accepts en empty +%D argument. This command permits for instance chapters to +%D have no title. + +%\def\dowithpargument#1% +% {\def\nextpar##1 \par{#1{##1}}% +% \def\nextarg##1{#1{##1}}% +% \doifnextcharelse\bgroup +% {\nextarg} +% {\doifnextcharelse{\par} +% {#1{}} +% {\nextpar}}} + +\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 +%D +%D Again there are two implementations possible: +%D +%D \starttyping +%D \def\dowithwargument#1% +%D {\def\dodowithwargument% +%D {\ifx\next\bgroup +%D \def\next{#1}% +%D \else +%D \def\next####1 {#1{####1}}% +%D \fi +%D \next}% +%D \futurelet\next\dodowithwargument} +%D \stoptyping +%D +%D We've chosen: + +%\def\dowithwargument#1% +% {\def\nextwar##1 {#1{##1}}% +% \def\nextarg##1{#1{##1}}% +% \doifnextcharelse\bgroup +% {\nextarg} +% {\nextwar}} + +\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 +% #5{#1}% +% \else +% \dorecurse{#1}{#5{#2#3}}% +% \fi} +% +% more complex but better: + +% \long\def\dodorepeatwithcommand#1*#2#3*#4\relax#5% +% {\ifx#2\empty +% #5{#1}% +% \else\ifnum#1<\zerocount +% % a la etex +% % \dorecurse{-\numexpr(#1)}{#5{-#2#3}}% +% % indirect +% %\innerrecurse#1% +% %\expanded{\dorecurse{\number-\innerrecurse}}{#5{-#2#3}}% +% % safer: +% \bgroup\scratchcounter#1% +% \expanded{\egroup\noexpand\dorecurse{\number-\scratchcounter}}{#5{-#2#3}}% +% \else\ifx#2+% +% \dorecurse{#1}{#5{#3}}% +% \else +% \dorecurse{#1}{#5{#2#3}}% +% \fi\fi\fi} + +\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. +%D +%D A simple implementation, one that does not handle braces +%D at the outer level, is: +%D +%D \starttyping +%D \def\appendtoks#1\to#2% +%D {\scratchtoks={#1}% +%D \expanded{\dodoglobal\noexpand#2{\the#2\the\scratchtoks}}} +%D +%D \def\prependtoks#1\to#2% +%D {\scratchtoks={#1}% +%D \expanded{\dodoglobal\noexpand#2{\the\scratchtoks\the#2}}} +%D \stoptyping +%D +%D But here we prefer: + +\newtoks\@@scratchtoks + +% before we had the once only alternatives, we had: +% +% \def\appendtoks {\doappendtoks \relax} +% \def\prependtoks{\doprependtoks\relax} +% +% \long\def\doappendtoks#1\to#2% +% {\@@scratchtoks\@EA{\gobbleoneargument#1}% +% \expanded{\dodoglobal\noexpand#2{\the#2\the\@@scratchtoks}}} +% +% \long\def\doprependtoks#1\to#2% +% {\@@scratchtoks\@EA{\gobbleoneargument#1}% +% \expanded{\dodoglobal\noexpand#2{\the\@@scratchtoks\the#2}}} + +\def\appendtoks {\doappendtoks \relax} +\def\prependtoks {\doprependtoks \relax} +\def\appendtoksonce {\doappendtoksonce \relax} +\def\prependtoksonce{\doprependtoksonce\relax} + +% \def\dodoappendtoks#1% +% {\expanded{\dodoglobal\noexpand#1{\the#1\the\@@scratchtoks}}} +% +% \def\dodoprependtoks#1% +% {\expanded{\dodoglobal\noexpand#1{\the\@@scratchtoks\the#1}}} +% +% \long\def\doappendtoks#1\to% +% {\@@scratchtoks\@EA{\gobbleoneargument#1}\dodoappendtoks} +% +% \long\def\doprependtoks#1\to% +% {\@@scratchtoks\@EA{\gobbleoneargument#1}\dodoprependtoks} +% +% \long\def\doappendtoksonce#1\to#2% +% {\@@scratchtoks\@EA{\gobbleoneargument#1}% +% \doifintokselse\@@scratchtoks{#2}{}{\dodoappendtoks{#2}}} +% +% \long\def\doprependtoksonce#1\to#2% +% {\@@scratchtoks\@EA{\gobbleoneargument#1}% +% \doifintokselse\@@scratchtoks{#2}{}{\dodoprependtoks{#2}}} +% +% 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}} + +\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: +%D +%D \starttyping +%D \def\doifintokselse#1#2% #1 en #2 zijn toks +%D {\edef\!!stringa{\the#1}\convertcommand\!!stringa\to\asciia +%D \edef\!!stringb{\the#2}\convertcommand\!!stringb\to\asciib +%D \doifinstringelse\asciia\asciib} +%D \stoptyping +%D +%D Better: +%D +%D \starttyping +%D \def\doifintokselse#1#2% #1 en #2 zijn toks +%D {\edef\!!stringa{\the#1}\convertcommand\!!stringa\to\asciia +%D \edef\!!stringb{\the#2}\convertcommand\!!stringb\to\asciib +%D \doifstringinstringelse\asciia\asciib} +%D \stoptyping +%D +%D Even better: + +\beginETEX + + \def\doifintokselse#1#2% #1 en #2 zijn toks + {\@EA\convertargument\the#1\to\asciia + \@EA\convertargument\the#2\to\asciib + \doifstringinstringelse\asciia\asciib} + +\endETEX + +\beginTEX + + \def\doifintokselse#1#2% #1 en #2 zijn toks + {\edef\asciia{\the#1}\convertcommand\asciia\to\asciia + \edef\asciib{\the#2}\convertcommand\asciib\to\asciib + \doifstringinstringelse\asciia\asciib} + +\endTEX + +%D Also: + +\def\appendetoks #1\to{\expanded{\appendtoks #1}\to} +\def\prependetoks#1\to{\expanded{\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 doen +%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 +%D +%D We prefer the use of global counters. This means that we +%D have to load \PLAIN\ \TEX\ in a bit different way: +%D +%D \starttyping +%D \let\oldouter=\outer +%D \let\outer=\relax +%D \input plain.tex +%D \let\outer=\oldouter +%D +%D \def\newcount% +%D {\alloc@0\count\countdef\insc@unt} +%D \stoptyping +%D +%D First we show a solution in which we use real \COUNTERS. +%D Apart from some expansion, nothing special is done. +%D +%D \starttyping +%D \def\makecounter#1% +%D {\expandafter\newcount\csname#1\endcsname} +%D +%D \def\pluscounter#1% +%D {\global\advance\csname#1\endcsname by 1 } +%D +%D \def\minuscounter#1% +%D {\global\advance\csname#1\endcsname by -1 } +%D +%D \def\resetcounter#1% +%D {\expandafter\global\csname#1\endcsname=0 } +%D +%D \def\setcounter#1#2% +%D {\expandafter\global\csname#1\endcsname=#2 } +%D +%D \def\countervalue#1% +%D {\the\getvalue{#1}} +%D \stoptyping +%D +%D Because these macros are already an indirect way of working +%D with counters, there is no harm in using pseudo \COUNTERS\ +%D here: + +\def\makecounter#1% + {\letgvalue{#1}\zerocountervalue} % see earlier + +% \def\countervalue#1% +% {\getvalue{#1}} + +\let\countervalue\getvalue + +\def\pluscounter#1% + {\scratchcounter\getvalue{#1}% + \advance\scratchcounter \plusone + \setxvalue{#1}{\the\scratchcounter}} + +\def\minuscounter#1% + {\scratchcounter\getvalue{#1}% + \advance\scratchcounter \minusone + \setxvalue{#1}{\the\scratchcounter}} + +\def\resetcounter#1% + {\letgvalue{#1}\zerocountervalue} + +\def\setcounter#1#2% or: \setxvalue{#1}{\number#2} + {\scratchcounter#2% + \setxvalue{#1}{\the\scratchcounter}} + +\def\incrementcounter#1#2% #1 name #2 value + {\setxvalue{#1}{\the\numexpr\csname#1\endcsname+#2\relax}} + +\def\decrementcounter#1#2% #1 name #2 value + {\setxvalue{#1}{\the\numexpr\csname#1\endcsname-#2\relax}} + +%D \macros +%D {savecounter,restorecounter} +%D +%D These two commands can be used to save and restore counter +%D values. Only one level is saved. + +\def\savecounter#1% + {{\scratchcounter\getvalue {#1}\setxvalue{!#1}{\the\scratchcounter}}} + +\def\restorecounter#1% + {{\scratchcounter\getvalue{!#1}\setxvalue {#1}{\the\scratchcounter}}} + +% == {\setxvalue{#1}{\getvalue{!#1}}} + +%D The next \ETEX\ based solution is some 15\% faster, which +%D goes unnoticed in any normal run, simply because these +%D macros are not used milions of times. + +\beginETEX \numexpr + +\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}} + +\endETEX + +%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\\} + +% Ok, but not for all cases: +% +% \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 +% \edef#3{\ifx#3\empty\else#3#2\fi\asciia}% +% \let#4\asciib +% \fi}% +% \ifx#3\empty\let#3\asciic\fi} +% +% The next one is some 25\% faster, but it hardly matters because +% we seldom use this macro. +% +% \def\greedysplitstring#1\at#2\to#3\and#4% +% {\edef\asciib{#1}% +% \let\asciic\asciib +% \let#3\empty +% \let#4\empty +% \def\dogreedysplitstring +% {\expandafter\splitstring\asciib\at#2\to\asciia\and\asciib +% \ifx\asciib\empty +% \expandafter\dogreedysplitstring +% \else +% \edef#3{\ifx#3\empty\else#3#2\fi\asciia}% +% \let#4\asciib +% \fi}% +% \dogreedysplitstring +% \ifx#3\empty\let#3\asciic\fi} +% +% The better alternative: + +\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} +%D +%D The next alternatives are for Simon Pepping. This time +%D the result is empty when no split is done. + +% \def\beforetestandsplitstring#1\at#2\to#3% +% {\def\dosplitstring##1#2##2#2##3\\{\doifelsenothing +% {##3}{\let#3\empty}{\def#3{##1}}}% +% \@EA\dosplitstring#1#2#2\\} +% +% \def\aftertestandsplitstring#1\at#2\to#3% +% {\def\dosplitstring ##1#2##2@@@##3\\{\doifelsenothing +% {##3}{\let#3\empty}{\def#3{##2}}}% +% \@EA\dosplitstring #1@@@#2@@@\\} +% +% \def\testandsplitstring#1\at#2\to#3\and#4% +% {\def\dosplitstring##1#2##2#2##3\\{\doifelsenothing +% {##3}{\let#3\empty\let#4\empty}{\def#3{##1}\def#4{##2}}}% +% \@EA\dosplitstring#1#2#2\\} +% +% faster: + +\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% +% {\doifinstringelse{#1}{#2} +% {\beforesplitstring#2\at#1\to\!!stringa +% \aftersplitstring #2\at#1\to\!!stringb +% \edef#3{\!!stringa\!!stringb}% +% \removesubstring#1\from#3\to#3} +% {}} + +\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}} + +%D The old ones are: +%D +%D \starttyping +%D \def\addtocommalist#1#2% +%D {\ifx#2\empty +%D \dodoglobal\edef#2{#1}% +%D \else +%D \edef\!!stringa{#2,,}% +%D \beforesplitstring#2\at,,\to#2\relax +%D \ExpandBothAfter\doifinsetelse{#1}{#2} +%D {\resetglobal} +%D {\dodoglobal\edef#2{#2,#1}}% +%D \fi} +%D +%D \def\pretocommalist#1#2% +%D {\ifx#2\empty +%D \dodoglobal\edef#2{#1}% +%D \else +%D \edef\!!stringa{#2,,}% +%D \beforesplitstring#2\at,,\to#2\relax +%D \ExpandBothAfter\doifinsetelse{#1}{#2} +%D {\resetglobal} +%D {\dodoglobal\edef#2{#1,#2}}% +%D \fi} +%D +%D \def\doremovefromcommalist#1#2#3% nog \doglobal +%D {\edef\!!stringa{,,#3,,}% +%D \beforesplitstring\!!stringa\at,#1#2,\to\!!stringb +%D \aftersplitstring\!!stringa\at,#1#2,\to\!!stringc +%D \edef#3{\!!stringb,\!!stringc}% +%D \aftersplitstring#3\at,,\to#3\relax +%D \beforesplitstring#3\at,,\to#3} +%D +%D \def\removefromcommalist#1#2% +%D {\doremovefromcommalist{ }{#1}{#2}% +%D \doremovefromcommalist{}{#1}{#2}% +%D \dofrontstrip#2% +%D \dodoglobal\edef#2{#2}} +%D \stoptyping +%D +%D Significantly faster (especially for longer lists): + +\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% + {\expanded{\convertargument#1}\to\!!stringa + \expanded{\convertargument#2}\to\!!stringb + \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% +% {\expanded{\xsplitstring\noexpand#2{#1}}% +% \dodoglobal\edef#2% +% {\ifx\!!stringa\empty +% \!!stringb +% \else +% \@EA\acleanedupcommalist\!!stringa,,\relax +% \ifx\!!stringb\empty\else,\!!stringb\fi +% \fi}} + +\def\removefromcommalist#1#2% + {\rawdoifinsetelse{#1}#2% + {\expanded{\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 {startprocesscommalist,startprocesscommacommand} +%D +%D Two more: + +\long\def\startprocesscommalist[#1]#2\stopprocesscommalist + {\long\def\currentcommalistcommand##1{\def\currentcommalistitem{##1}#2}% + \processcommalist[#1]\currentcommalistcommand} + +\long\def\startprocesscommacommand[#1]#2\stopprocesscommacommand + {\long\def\currentcommalistcommand##1{\def\currentcommalistitem{##1}#2}% + \processcommacommand[#1]\currentcommalistcommand} + +%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% + {\begingroup + \scratchdimen#1\relax + \scratchdimen0.0351459804\scratchdimen % 2.54/72.27 + \withoutpt\the\scratchdimen cm% + \endgroup} + +%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\@s@{@s@} +% +% \beginTEX +% +% \def\globalpushmacro#1% we can use a faster incement here +% {\@EA\doglobal\@EA\increment\csname\@s@*\string#1\endcsname +% \global\@EA\let\csname\csname\@s@*\string#1\endcsname*\string#1\endcsname#1} +% +% \def\globalpopmacro#1% \global\let +% {\global\@EA\let\@EA#1\csname\csname\@s@*\string#1\endcsname*\string#1\endcsname +% \@EA\doglobal\@EA\decrement\csname\@s@*\string#1\endcsname} +% +% \def\localpushmacro#1% this one can be used to push a value over an \egroup +% {\@EA\doglobal\@EA\increment\csname\@s@**\string#1\endcsname +% \global\@EA\let\csname\csname\@s@**\string#1\endcsname**\string#1\endcsname#1} +% +% \def\localpopmacro#1% \local\let +% {\@EA\let\@EA#1\csname\csname\@s@**\string#1\endcsname**\string#1\endcsname +% \global\@EA\decrement\csname\@s@**\string#1\endcsname} +% +% \endTEX +% +% \beginETEX \newcount +% +% \def\globalpushmacro#1% +% {\ifcsname\@s@*\string#1\endcsname \else +% \@EA\newcount\csname\@s@*\string#1\endcsname +% \fi +% \global\advance\csname\@s@*\string#1\endcsname \plusone +% \global\@EA\let\csname\the\csname\@s@*\string#1\endcsname*\string#1\endcsname#1} +% +% \def\globalpopmacro#1% \global\let +% {\global\@EA\let\@EA#1\csname\the\csname\@s@*\string#1\endcsname*\string#1\endcsname +% \global\advance\csname\@s@*\string#1\endcsname \minusone} +% +% \def\localpushmacro#1% this one can be used to push a value over an \egroup +% {\ifcsname\@s@**\string#1\endcsname \else +% \@EA\newcount\csname\@s@**\string#1\endcsname +% \fi +% \global\advance\csname\@s@**\string#1\endcsname \plusone +% \global\@EA\let\csname\the\csname\@s@**\string#1\endcsname**\string#1\endcsname#1} +% +% \def\localpopmacro#1% \local\let +% {\@EA\let\@EA#1\csname\the\csname\@s@**\string#1\endcsname**\string#1\endcsname +% \global\advance\csname\@s@**\string#1\endcsname \minusone } +% +% \endETEX +% +% some 5% faster (used a lot in typescripts, so ...) + +\def\@sl@{@sl@} +\def\@sg@{@sg@} + +\let\@@pushedmacro\empty + +\beginTEX + +\def\globalpushmacro#1% we can use a faster incement here + {\xdef\@@pushedmacro{\string#1}% + \@EA\doglobal\@EA\increment\csname\@sg@\@@pushedmacro\endcsname + \global\@EA\let\csname\csname\@sg@\@@pushedmacro\endcsname\@@pushedmacro\endcsname#1} + +\def\globalpopmacro#1% + {\xdef\@@pushedmacro{\string#1}% + \global\@EA\let\@EA#1\csname\csname\@sg@\@@pushedmacro\endcsname\@@pushedmacro\endcsname + \@EA\doglobal\@EA\decrement\csname\@sg@\@@pushedmacro\endcsname} + +\def\localpushmacro#1% this one can be used to push a value over an \egroup + {\xdef\@@pushedmacro{\string#1}% + \@EA\doglobal\@EA\increment\csname\@sl@\@@pushedmacro\endcsname + \global\@EA\let\csname\csname\@sl@\@@pushedmacro\endcsname\@@pushedmacro\endcsname#1} + +\def\localpopmacro#1% + {\xdef\@@pushedmacro{\string#1}% + \@EA\let\@EA#1\csname\csname\@sl@\@@pushedmacro\endcsname\@@pushedmacro\endcsname + \global\@EA\decrement\csname\@sl@\@@pushedmacro\endcsname} + +\endTEX + +\beginETEX + +\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 } + +\endETEX + +% \let\pushmacro\globalpushmacro +% \let\popmacro \globalpopmacro + +\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% +% {\def\p!docommoncheck##1% +% {\doifnotinset{##1}{#2}{\donefalse}% +% \ifdone\else\quitcommalist\fi}% +% \donetrue +% \processcommalist[#1]\p!docommoncheck +% \ifdone#3\else#4\fi} + +\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% + {\def\dododoublewithset[##1][##2]% + {\doifsomething{##1} + {\def\dodododoublewithset####1{#2[####1][##2]}% + \processcommalist[##1]\dodododoublewithset}}% + #1\dododoublewithset} + +\def\dodoubleemptywithset {\dodoublewithset\dodoubleempty} +\def\dodoubleargumentwithset{\dodoublewithset\dodoubleargument} + +\def\dotriplewithset#1#2% + {\def\dodotriplewithset[##1][##2][##3]% + {\doifsomething{##1} + {\def\dododotriplewithset####1{#2[####1][##2][##3]}% + \processcommalist[##1]\dododotriplewithset}}% + #1\dodotriplewithset} + +\def\dotripleemptywithset {\dotriplewithset\dotripleempty} +\def\dotripleargumentwithset{\dotriplewithset\dotripleargument} + +%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{{}}. + +% keep this one: +% +% \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} +% +% the following is better (comes from syst-loc): + +\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% + {\ifundefined{#1}% + \def\next{#2}% + \else + \def\next{\getvalue{#1}}% + \fi + \next} + +%D Just for fun I times the next alternative: it was roughly +%D timed about 15\% faster than the default (10+ sec to 9 sec)! + +\beginTEX + +\def\executeifdefined#1% #2 / never change this one again + {\ifundefined{#1}% + \expandafter\secondoftwoarguments + \else + \expandafter\firstoftwoarguments + \fi + {\csname#1\endcsname}} + +\endTEX + +\beginETEX + +% \def\executeifdefined#1% #2 / never change this one again +% {\ifcsname#1\endcsname +% \expandafter\firstoftwoarguments +% \else +% \expandafter\secondoftwoarguments +% \fi +% {\csname#1\endcsname}} + +\def\executeifdefined#1% #2 / never change this one again + {\ifcsname#1\endcsname + \csname#1\expandafter\expandafter\expandafter\endcsname\expandafter\gobbleoneargument + \else + \expandafter\firstofoneargument + \fi} + +\endETEX + +% \letvalue{f }\firstofoneargument \def\executeifdefined#1{\csname\ifcsname#1\endcsname#1\else f \fi\endcsname} + +%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 {executeifdefinedcs} +%D +%D An also fully expandable variant is the following: +%D +%D \starttyping +%D \executeifdefinedcs{a}{b} +%D \stoptyping +%D +%D In dit geval zijn beide argumenten csnames. + +\def\executeifdefinedcs#1#2% + {\csname\ifundefined{#1}#2\else#1\fi\endcsname} + +%D We considered an alternative implementation accepting +%D commands directly, like: +%D +%D \starttyping +%D \executeifdefined\name\gobblefivearguments +%D \stoptyping +%D +%D For the moment we don't need this one, so we stick to the +%D faster one. + +%D \macros +%D {executeandforget} +%D +%D The following macros were requested by Simon. Watch the +%D global variant. +%D +%D \starttyping +%D \executeandforget\SomeCommand +%D \doglobal\executeandforget\AnotherCommand +%D \stoptyping + +\def\executeandforget#1% + {\global\let\@@expanded#1% + \dodoglobal\let#1\relax + \@@expanded} + +%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? + +% \long\def\doifsomespaceelse#1#2#3% +% {\def\p!doifsomespaceelse##1 ##2##3\war% +% {\if\noexpand##2@#3\else#2\fi}% +% \p!doifsomespaceelse#1 @ @\war} + +\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#3 #1#2\relax +% \else\if#1-% +% \dodoglobal\advance#3 #1#2\relax +% \else +% \dodoglobal#3=#1#2\relax +% \fi\fi} +% +% more fuzzy but also more efficient + +\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 First we show the simple alternative: +%D +%D \starttyping +%D \def\processseparatedlist[#1][#2]#3% +%D {\def\doprocessseparatedlist##1##2#2% +%D {\if]##1% +%D \let\next=\relax +%D \else\if]##2% +%D \let\next=\relax +%D \else\ifx\blankspace##2% +%D #3{##1}% +%D \let\next=\doprocessseparatedlist +%D \else +%D #3{##1##2}% +%D \let\next=\doprocessseparatedlist +%D \fi\fi\fi +%D \next}% +%D \doprocessseparatedlist#1#2]#2} +%D \stoptyping +%D +%D However, 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% +% {\if]##1% +% \let\dodoprocessseparatedlist\relax +% \else\if]##2% +% \let\dodoprocessseparatedlist\relax +% \else\ifx\blankspace##2% +% #4{##1}% +% \else +% #4{##1##2}% +% \fi\fi\fi +% \dodoprocessseparatedlist}% +% \@EA\dodoprocessseparatedlist\gobbleoneargument#1#3]#3} + +% testcase Vit Zyka: +% +% \def\Do#1{(#1)} +% 1\processseparatedlist[{aap noot}] [ ]\Do \par +% 2\processseparatedlist[{aap} {noot}][ ]\Do \par +% 3\processseparatedlist[aap {noot}] [ ]\Do \par +% 4\processseparatedlist[aap noot] [ ]\Do \par +% 5\processseparatedlist[aap;noot;a noot;noot a; noot a noot][;]\Do \par +% 6\processseparatedlist[][;]\Do \par +% 7\processseparatedlist[;][;]\Do \par + +\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 {dohonorgroupedargument} +% %D +% %D The previous macro uses yet another auxiliary macro to +% %D handle the special case. +% +% \def\dohonorgroupedargument#1[% +% {\doifnextbgroupelse{\dodohonorgroupedargument#1}{#1[}} +% +% \def\dodohonorgroupedargument#1#2% +% {#1[{{#2}}} + +%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} + +% too ugly +% +% %D \macros +% %D {DoAfterFi,DoAfterFiFi} +% %D +% %D Sometimes \type{\fi}'s can get into the way. We can reach +% %D over such a troublemaker with: +% %D +% %D \starttyping +% %D \DoAfterFi{some commands} +% %D \DoAfterFiFi{some commands} +% %D \stoptyping +% %D +% %D It saves us a \type{\next} construction. Skipping +% %D \type{\else...\fi} is more tricky, so this one is not +% %D provided. +% +% \def\DoAfterFi#1\fi{\fi#1} +% \def\DoAfterFiFi#1\fi#2\fi{\fi\fi#1} + +%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. + +% \def\ScaledPointsToBigPoints #1{\PointsToBigPoints {#1sp}} +% \def\ScaledPointsToWholeBigPoints#1{\PointsToWholeBigPoints{#1sp}} +% +% \def\PointsToBigPoints#1#2% +% {\scratchdimen#1% +% \scratchdimen.996264\scratchdimen +% \edef#2{\withoutpt\the\scratchdimen}} +% +% \def\PointsToWholeBigPoints#1#2% +% {\scratchdimen#1% +% \scratchdimen.996264\scratchdimen +% \scratchcounter\scratchdimen +% \advance\scratchcounter \medcard +% \divide\scratchcounter \maxcard +% \edef#2{\the\scratchcounter}} + +% \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 + +\beginTEX + + \def\PointsToBigPoints#1#2% + {\scratchdimen#1% + \scratchdimen.996264\scratchdimen + \edef#2{\withoutpt\the\scratchdimen}} + + \def\PointsToWholeBigPoints#1#2% + {\scratchdimen#1% + \scratchdimen.996264\scratchdimen + \scratchcounter\scratchdimen + \advance\scratchcounter \medcard + \divide\scratchcounter \maxcard + \edef#2{\the\scratchcounter}} + +\endTEX + +\beginETEX \dimexpr \numexpr + +% \def\PointsToBigPoints#1#2% +% {\edef#2{\withoutpt\the\dimexpr(.996264\dimexpr(#1))}} + +% \def\PointsToWholeBigPoints#1#2% +% {\edef#2{\the\numexpr(\numexpr(\dimexpr(.996264\dimexpr(#1)))/\maxcard)}} + + \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}} + +\endETEX + +\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} + +% Also ok, but more sensitive to lookahead expansion is: +% +% \def\dontleavehmode{\ifvmode \indent \fi} +% +% which assumes indent is kept unchanged. Protecting the macro is only +% possible in etex (watch out: \unexpanded in context is eq to \protected). +% +% \unexpanded \def\dontleavehmode{\ifvmode \indent \fi} % functional spec TH + +%D But, if you run a recent version of \TEX, we can use the new +%D primitive: + +\ifx\normalquitvmode\undefined \else \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 + {\edef#2{#1}\@EA\uppercase\@EA{\@EA\dodoglobal\@EA\edef\@EA#2\@EA{#2}}} + +\def\lowercasestring#1\to#2% first @EA redundant + {\edef#2{#1}\@EA\lowercase\@EA{\@EA\dodoglobal\@EA\edef\@EA#2\@EA{#2}}} + +%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 At first sight the next implementation will suffice, but +%D running this one shows that we loose the spaces. This is no +%D surprise because we grab arguments and spaces preceding those +%D are just ignored. +%D +%D \starttyping +%D \def\nohandletokens#1\end% +%D {} +%D +%D \def\dohandletokens#1#2\end% +%D {\ifx#1\endoftoken +%D \expandafter\nohandletokens +%D \else +%D \docommand{#1}% +%D \expandafter\dohandletokens +%D \fi +%D #2\end} +%D +%D \long\def\handletokens#1\with#2% +%D {\let\docommand=#2\relax +%D \dohandletokens#1\endoftoken\end} +%D \stoptyping +%D +%D A second approach therefore grabs the individual characters +%D by using \type{\afterassignment}, in which case the space is +%D read in as space. +%D +%D \starttyping +%D \def\dodohandletokens% +%D {\ifx\next\end \else +%D \docommand{\next}% +%D \expandafter\dohandletokens +%D \fi} +%D +%D \def\dohandletokens +%D {\afterassignment\dodohandletokens\let\next= } +%D +%D \long\def\handletokens#1\with#2% +%D {\let\docommand=#2% +%D \dohandletokens#1\end} +%D \stoptyping + +%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 \count +%D \counttokens string\to \count +%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% + {\redoglobal#3\zerocount + \def\!!stringa{#1}% + \def\!!stringb{\end}% + \def\docounttoken##1% obeys {} + {\def\!!stringc{##1}% + \ifx\!!stringb\!!stringc \else + \ifx\!!stringa\!!stringc + \dodoglobal\advance#3 \plusone + \fi + \expandafter\docounttoken + \fi}% + \docounttoken#2\end + \resetglobal} + +% \def\counttoken#1\in#2\to#3% +% {\redoglobal#3\zerocount +% \def\!!stringa{#1}% +% \def\docounttoken##1% obeys {} +% {\def\!!stringb{##1}% +% \ifx\!!stringa\!!stringb +% \dodoglobal\advance#3\plusone +% \fi}% +% \handletokens#1\with\docounttoken +% \resetglobal} + +\def\counttokens#1\to#2% + {\redoglobal#2\zerocount + \def\docounttoken##1{\dodoglobal\advance#2\plusone}% + \handletokens#1\with\docounttoken + \resetglobal} + +%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% + {\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} + +%D A previous version said \type{\docommand=#2}, but to enable +%D use in alignments, I decided to use another placeholder, one +%D that is not sensitive to the global assignment. + +%D This alternatives does not handle grouped tokens well, so +%D next we had (for a short moment): +%D +%D \starttyping +%D \def\dodohandletokens#1% +%D {\ifx\nexthandledtoken\blankspace +%D \dododohandletokens{ }% +%D \fi +%D \ifx#1\end \else +%D \dododohandletokens{#1}% +%D \expandafter\dohandletokens +%D \fi} +%D \stoptyping +%D +%D This one failed on a trailing space, something we +%D encounter in \JAVASCRIPT\ cleaning. +%D +%D \starttyping +%D \def\dodohandletokens#1% +%D {\ifx\nexthandledtoken\blankspace +%D \dododohandletokens{ }% +%D \fi +%D \ifx\nexthandledtoken\end \else +%D \dododohandletokens{#1}% +%D \expandafter\dohandletokens +%D \fi} +%D \stoptyping +%D +%D So, now we have: + +\def\dodohandletokens % can be sped up + {\ifx\nexthandledtoken\blankspace + \def\next * {\dododohandletokens{ }\dohandletokens}% + \else\ifx\nexthandledtoken\end + \let\next\gobbletwoarguments + \else + \long\def\next *##1{\dododohandletokens{##1}\dohandletokens}% + \fi\fi + \next *} + +%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% + {\edef\!!stringa{\the\globaldefs}% + \ifnum\globaldefs#10 + \globaldefs-\globaldefs + \fi + \advance\globaldefs#21 + \letvalue{@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} + +%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. + +\beginTEX + + \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\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} + +% \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 + +%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} + +%\beginTEX + +\def\doprocesscontent#1#2#3% + {\long\def\doprocesscontent##1#1% + {\endgroup\long\def#2{##1}#3}% + \doprocesscontent} + +%\endTEX + +% Hm. Side effect, spaces after \type{\test} in verbatim. +% must set eof token + +%\beginETEX \scantokens +% +%\def\doprocesscontent#1#2#3% +% {\long\def\doprocesscontent##1#1% +% {\egroup\long\def#2{\scantokens{##1}}#3}% +% \doprocesscontent} +% +%\endETEX + +%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. + +\def\donumericcompare#1#2% + {\doifnumberelse{#1} + {\doifnumberelse{#2} + {\ifnum#1>#2\relax + \comparedresult\plusone % #1 is larger + \else\ifnum#1<#2\relax + \comparedresult\plustwo % #2 is larger + \else + \comparedresult\zerocount % both are equal + \fi\fi} + {\comparedresult\plustwo}} + {\comparedresult\plusone}} + +%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} + +\def\strictdoifnextoptionalelse#1#2% + {\startstrictinspectnextcharacter + \doifnextcharelse[{\stopstrictinspectnextcharacter#1}{\stopstrictinspectnextcharacter#2}} + +%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. + +\def\verbatimstring#1% + {\convertargument#1\to\ascii\ascii} + +%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 + {\ifcase#1\or + \ifcase#2\or + \strippedcsname\firstofoneargument + \else + \strippedcsname\gobbleoneargument + \fi + \or + \ifcase#2\or + \strippedcsname\firstoftwoarguments + \or + \strippedcsname\secondoftwoarguments + \else + \strippedcsname\gobbletwoarguments + \fi + \or + \ifcase#2\or + \strippedcsname\firstofthreearguments + \or + \strippedcsname\secondofthreearguments + \or + \strippedcsname\thirdofthreearguments + \else + \strippedcsname\gobblethreearguments + \fi + \or + \ifcase#2\or + \strippedcsname\firstoffourarguments + \or + \strippedcsname\secondoffourarguments + \or + \strippedcsname\thirdoffourarguments + \or + \strippedcsname\fourthoffourarguments + \else + \strippedcsname\gobblefourarguments + \fi + \or + \ifcase#2\or + \strippedcsname\firstoffivearguments + \or + \strippedcsname\secondoffivearguments + \or + \strippedcsname\thirdoffivearguments + \or + \strippedcsname\fourthoffivearguments + \or + \strippedcsname\fifthoffivearguments + \else + \strippedcsname\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]% + {\setvalue{\??dm#1}{#2}} + +% #2 could be omitted, but we want to support spaces +% +% \setmeasure {x} {1cm} +% \setmeasure {xx} {1cm} +% \setmeasure {xxx}{1cm} + +\def\setmeasure #1#2{\setvalue{\??dm#1}{#2}} % quick way +\def\setemeasure#1#2{\setevalue{\??dm#1}{#2}} % quick way +\def\setgmeasure#1#2{\setgvalue{\??dm#1}{#2}} % quick way +\def\setxmeasure#1#2{\setxvalue{\??dm#1}{#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} + +\beginETEX + +\def\comparedimensioneps#1#2% + {\chardef\compresult + \ifdim\dimexpr(#1-#2)<\roudingeps + \zerocount + \else\ifdim\dimexpr(#2-#1)<\roudingeps + \zerocount + \else\ifdim#1<#2% + \plusone + \else + \plustwo + \fi\fi\fi} + +\endETEX + +\beginTEX + +\newdimen\comparedimen + +\def\comparedimensioneps#1#2% + {\comparedimen#1\advance\comparedimen-#2\relax + \chardef\compresult + \ifdim\comparedimen<\roudingeps + \zerocount + \else\ifdim-\comparedimen<\roudingeps + \zerocount + \else\ifdim#1<#2% + \plusone + \else + \plustwo + \fi\fi\fi} + +\endTEX + +\protect \endinput 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-gen.mkii b/tex/context/base/syst-gen.mkii new file mode 100644 index 000000000..0367ba4fd --- /dev/null +++ b/tex/context/base/syst-gen.mkii @@ -0,0 +1,4454 @@ +%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. + +% nagaan : \ifinstringelse in syst-ext.tex +% do => p! dodo pp! dododo ppp! +% todo: \donetrue etc local maken + +%D The following macros are responsible for the interaction +%D with \CONTEXT. These macros have proven their use. These +%D macros are optimized as far as possible within of course, +%D the know how of the author. +%D +%D In this module we also show some of the optimizations, +%D mainly because we don't want to forget them and start doing +%D things over and over again. If showing them has a learing +%D effect for others too, we've surved another purpose too. + +%D \macros +%D {abortinputifdefined} +%D +%D Because this module can be used in a different context, we +%D want to prevent it being loaded more than once. This can be +%D done using: +%D +%D \starttyping +%D \abortinputifdefined\command +%D \stoptyping +%D +%D where \type{\command} is a command defined in the module +%D to be loaded only once. +%D +%D \starttyping +%D \def\abortinputifdefined#1% +%D {\ifx#1\undefined +%D \let\next=\relax +%D \else +%D \let\next=\endinput +%D \fi +%D \next} +%D \stoptyping +%D +%D This macro can be speed up in terms of speed as well as +%D memory. Because this is a nice example of a bit strange +%D command (\type{\endinput}), we spend some more lines on this. +%D +%D If we perform such actions directly, we can say: +%D +%D \starttyping +%D \ifx\somecommand\undefined +%D \let\next=\relax +%D \else +%D \let\next=\endinput +%D \fi +%D \next +%D \stoptyping +%D +%D We need the \type{\next} because we need to end the +%D \type{\fi}. The efficient one is: +%D +%D \starttyping +%D \ifx\somecommand\undefined +%D \else +%D \expandafter\endinput +%D \fi +%D \stoptyping +%D +%D Because \type{\endinput} comes into action after the current +%D line, we can also say: +%D +%D \starttyping +%D \ifx\somecommand\undefined \else \endinput \fi +%D \stoptyping +%D +%D When we define a macro, we tend to use a format which +%D shows as besat as can how things are done. \TEX\ however +%D stores the definitions as a sequence of tokens, so in fact +%D we can use a formatted definition: + +\def\abortinputifdefined#1% + {\ifx#1\undefined \else + \endinput + \fi} + +%D which also works. Keep in mind that this is entirely due to +%D the fact that \type{\endinput} after the line, i.e. at the +%D end of the macro. We therefore can burry this primitive quite +%D deep in code. + +%D And because this module implements \type{\writestatus}, we +%D just say: + +% \abortinputifdefined\writestatus + +%D \macros +%D {overloaded, superseded, forwarded, predefined} +%D +%D This prefix is used as signal for the \CONTEXT\ dependency +%D checking features. The first four prefixes don't do anything +%D useful, apart from signaling parsers. + +\def\overloaded{} % local change at the macro level +\def\superseded{} % global change at the module level, replaces previous definitions +\def\predefined{} % defined (first) here, but may be redefined anytime (no need for \overloaded) +\def\forwarded {} % definition at the module level, only done when undefined + +\def\forwarded#1#2{\ifx#2\undefined\else\expandafter\gobbleforwarded\fi#1#2} + +\def\gobbleforwarded#1 + {} + +%D Normally we tell the users what module is being loaded. +%D However, the command that is needed for this is not yet +%D defined. +%D +%D \starttyping +%D \writestatus{laden}{Context Systeem Macros (a)} +%D \stoptyping + +%D The next few macros are needed in case this module is +%D used outside \CONTEXT. + +\ifx\beginTEX\undefined + \let\beginTEX\relax\let\endTEX\relax + \long\def\beginETEX #1\endETEX {} +\fi + +%D \macros +%D [protecting] +%D {protect,unprotect} +%D +%D We can shield macros from users by using some special +%D characters in their names. Some characters that are normally +%D no letters and therefore often used are: \type{@}, \type{!} +%D and \type{?}. Before and after the definition of protected +%D macros, we have to change the \CATCODE\ of these characters. +%D This is done by \type{\unprotect} and \type{\protect}, for +%D instance: +%D +%D \starttyping +%D \unprotect +%D \def\!test{test} +%D \protect +%D \stoptyping +%D +%D The defined command \type{\!test} can of course only be +%D called upon when we are in the \type{\unprotect}'ed state, +%D otherwise \TEX\ reads \type{\!} and probably complains +%D loudly about not being in math mode. +%D +%D Both commands can be used nested, but only the \CATCODE\ +%D of the outermost level is saved. We make use of +%D an auxilary macro \type{\doprotect} to prevent us from +%D conflicts with existing macro's \type{\protect}. When +%D nesting deeper than one level, the system shows the +%D protection level. + +\ifx\protectionlevel\undefined \newcount\protectionlevel \fi + +\ifx\protect\undefined + \def\protect{\writestatus{protection}{too much protection}} +\else + % a simple version is already defined +\fi + +\let\normalprotect\protect % only for latex + +%D Although we don't need the \type{%} after commands that +%D don't take arguments, unless lines are obeyed, I decided +%D to put it there as a reminder. I only mention this once. + +\ifx\unprotect\undefined + + \chardef\protectionthreshold=10 + + \def\saveprotectedcharacters + {\edef\doprotectcharacters + {\catcode`\noexpand @\the\catcode`@ + \catcode`\noexpand !\the\catcode`! + \catcode`\noexpand ?\the\catcode`? }} + + \def\setprotectedcharacters + {\catcode`@=11 + \catcode`!=11 + \catcode`?=11 } + + \def\unprotect + {\ifcase\protectionlevel + \saveprotectedcharacters + \let\protect\doprotect + \fi + \setprotectedcharacters + \advance\protectionlevel 1 + \ifnum\protectionlevel>\protectionthreshold + \reportunprotection + \fi} + + \def\doprotect + {\ifcase\protectionlevel\or + \doprotectcharacters + \let\doprotectcharacters\relax + \let\protect\normalprotect + \fi + \ifnum\protectionlevel>\protectionthreshold + \reportprotection + \fi + \advance\protectionlevel -1 } + + \def\reportunprotection {\writestatus{protection}{unprotect \protectionstate}} + \def\reportprotection {\writestatus{protection}{protect \protectionstate}} + \def\reportprotectionstate{\writestatus{protection}{state \protectionstate}} + + \def\protectionstate + {\the\protectionlevel + \ifcase\protectionthreshold + :\space + @=\the\catcode`@\space\space + !=\the\catcode`!\space\space + ?=\the\catcode`?% + \fi} + + \ifx\everyeof\undefined + \let\checkprotection\relax + \else + \def\checkprotection{\everyeof{\writestatus{protection}{state: \protectionstate}}} + \fi + +\else + + \let\reportprotectionstate\relax + +\fi + +%D Now it is defined, we can make use of this very useful +%D macro. + +\unprotect + +%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 +%D certain characters. Because we are not that good at 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 \macros +%D {normalspace} +%D +%D We often need a space as defined in \PLAIN\ \TEX. Because +%D we cannot be sure of \type{\space} is redefined, we define: + +\def\normalspace{ } + +%D \macros +%D {scratchcounter, +%D scratchdimen,scratchskip,scratchmuskip, +%D scratchbox, +%D scratchtoks} +%D +%D Because we often need counters on a temporary basis, we +%D define the \COUNTER\ \type{\scratchcounter}. This is a +%D real \COUNTER, and not a pseudo one, as we will meet +%D further on. We also define some other scratch registers. + +\chardef\newabovelimit=20 + +\def\stripnewabove#1% + {\ifnum10<9#1 #1\else\expandafter\stripnewabove\fi}% + +\def\newabove#1#2% \dimen \name + {#1#2% + \ifnum\expandafter\stripnewabove\meaning#2>\newabovelimit\else + \expandafter\newabove\expandafter#1\expandafter#2% + \fi} + +\newabove \newcount \scratchcounter \newabove \newcount \globalscratchcounter +\newabove \newdimen \scratchdimen \newabove \newdimen \globalscratchdimen +\newabove \newskip \scratchskip \newabove \newskip \globalscratchskip +\newabove \newmuskip \scratchmuskip \newabove \newmuskip \globalscratchmuskip +\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} + +\newif\ifdone + +%D \macros +%D {ifCONTEXT} +%D +%D In the system and support modules we sometimes show examples +%D that make use of core commands. We can skip those parts of +%D the documentation when we use another macropackage. Of +%D course we default to false. + +\newif \ifCONTEXT + +%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 \toksdef\!!toksa=0 \dimendef\!!dimena= 0 \chardef\!!boxa =0 +\newcount\!!countb \toksdef\!!toksb=2 \dimendef\!!dimenb= 2 \chardef\!!boxb =2 +\newcount\!!countc \toksdef\!!toksc=4 \dimendef\!!dimenc= 4 \chardef\!!boxc =4 +\newcount\!!countd \toksdef\!!toksd=6 \dimendef\!!dimend= 6 \chardef\!!boxd =6 +\newcount\!!counte \toksdef\!!tokse=8 \dimendef\!!dimene= 8 \chardef\!!boxe =8 +\newcount\!!countf \dimendef\!!dimenf=10 %skipdef\!!skipa=0 + \dimendef\!!dimeng=12 %skipdef\!!skipb=2 + \dimendef\!!dimenh=14 %skipdef\!!skipc=4 + \dimendef\!!dimeni=16 %skipdef\!!skipd=6 + \dimendef\!!dimenj=18 %skipdef\!!skipe=8 + \dimendef\!!dimenk=20 %skipdef\!!skipf=10 + +\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 + +\newif\if!!donea \newif\if!!doneb \newif\if!!donec +\newif\if!!doned \newif\if!!donee \newif\if!!donef + +\ifx\data\undefined \else \let\data \relax \fi % dep checker + +%D Beware: we don't reuse plain counters, too dangerous +%D when <= 20 (e.g. in supp-pdf this messed up things). + +\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!,@@,??} +%D +%D To save memory, we use constants (sometimes called +%D variables). Redefining these constants can have desastrous +%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 \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\ifx\nexttoken\charactertoken + \@EAEAEA\!!stringa + \else + \@EAEAEA\!!stringb + \fi\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\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 +%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}. The chain reaction is +%D visually compatible with the next sequence: +%D +%D \starttyping +%D \expandafter\def\reinspectnextcharacter % +%D {\futurelet\nexttoken\inspectnextcharacter} +%D \stoptyping +%D +%D However complicated it may look, I'm still glad I stumbled +%D into this construction. Saving and restoring \type {\:} is +%D needed when we use \PPCHTEX\ in \LATEX. + +\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, +%D getvalue, +%D resetvalue} +%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\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 Sometimes prefixing the macro with \type{\donottest} leads +%D to defining an auxiliary macro, like +%D +%D \starttyping +%D \def\dosomecommand {... ... ...} +%D \def\somecommand {\donottest\dosomecommand} +%D \stoptyping +%D +%D This double definition can be made transparant by using +%D \type{\unexpanded}, as in: +%D +%D \starttyping +%D \unexpanded\def\somecommand{... ... ...} +%D \stoptyping +%D +%D The protection mechanism uses: + +\beginTEX + +\def\dontprocesstest#1{==} +\def\doprocesstest #1{#1} + +\let\donottest=\doprocesstest + +\endTEX + +\beginETEX \detokenize + +\def\donottest#1{#1} % {\detokenize{#1}} + +\endETEX + +%D By the way, we use a placeholder because we don't want +%D interference when testing on empty strings. Using a +%D placeholder of 8~characters increases the processing time +%D of simple \type{\doifelse} tests by about 10 \%. When we +%D process the test, we have to remove the braces and +%D therefore explictly gobble \type{#1}. + +%D \macros +%D {honorunexpanded,forceunexpanded} +%D +%D The fact that many macros have the same prefix, could have +%D a negative impact on searching in the hash table. Because +%D some simple testing does not show differences, we just use: +%D +%D \starttyping +%D \def\unexpanded#1#2% +%D {\@EA#1\@EA#2\@EA{\@EA\donottest\csname\s!do\string#2\endcsname}% +%D \@EA#1\csname\s!do\string#2\endcsname} +%D \stoptyping +%D +%D Well, in fact we use the bit more versatile alternative. The +%D \type {\honorunexpanded} can be used to \type {\string} +%D the protected command, which by the way is seldom needed +%D in \CONTEXT. + +\beginTEX + +\def\dosetunexpanded#1#2% + {\@EA#1\@EA{\@EA#2\@EA}% + \@EA{\@EA\donottest\csname\s!do\@EA\string\csname#2\endcsname\endcsname}% + \@EA#1\@EA{\@EA\s!do\@EA\string\csname#2\endcsname}} + +\def\docomunexpanded#1#2% + {\@EA#1\@EA#2\@EA{\@EA\donottest\csname\s!do\string#2\endcsname}% + \@EA#1\csname\s!do\string#2\endcsname} + +\def\unexpanded#1% + {\def\dounexpanded + {\ifx\next\bgroup + \@EA\dosetunexpanded + \else + \@EA\docomunexpanded + \fi#1}% + \futurelet\next\dounexpanded} + +\def\honorunexpanded% for writing to a file or message + {\def\donottest##1{\expandafter\gobblethreearguments\string##1}} + +\def\forceunexpanded% for preventing expansion in \xdef + {\def\donottest##1% + {\expandafter\noexpand\csname\expandafter\gobblefourarguments\string##1\endcsname}} + +\def\resetunexpanded% + {\let\donottest\doprocesstest} + +\endTEX + +\beginETEX \protected + +\let \unexpanded \normalprotected +\let \honorunexpanded \empty % \relax +\let \forceunexpanded \empty % \relax +\let \resetunexpanded \empty % \relax + +\endETEX + +%D This one accepts the more direct \type{\def} and cousins +%D as well as the \CONTEXT\ specific \type{\setvalue} ones. +%D +%D And so the definition in our example turns out to be: +%D +%D \starttyping +%D \def\csname do\somecommand\endcsname{... ... ...} +%D \def\somecommand{\donottest\csname do\somecommand\endcsname} +%D \stoptyping +%D +%D In which \type{do\somecommand} is hidden from the user and +%D cannot lead to confusion. It's still permitted to define +%D auxiliary macros like \type{\dosomecommand}. +%D +%D When we are going to use e-\TEX, we'll probably end up +%D redefining some commands, but we can probably keep the +%D \type{\unexpanded} ones unchanged. + +%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 \ifx\NameB\undefined ... \else ... \fi +%D \stoptyping +%D +%D I became aware of this when I mistakenly testen the first +%D one against \type{\undefined}. When \TEX\ build a name using +%D \type{\csname} it automatically sets it to \type{\relax}, +%D which is definitely not the same as \type{\undefined}. The +%D quickest way to check these things is asking \TEX\ to show +%D the meaning of the names: +%D +%D \starttyping +%D \expandafter\show\csname NameA\endcsname +%D +%D \show\NameB +%D \stoptyping +%D +%D The main reason why this never will be a big problem is that +%D when one uses the \type{\csname} way, one probably has to do +%D with some macroname that always is dealt with that way. +%D Confusion can however arise when one applies both testing +%D methods to the same macroname. By the way, the assignment +%D of \type{\relax} obeys grouping. + +%D The first one gets rid of \type{#1}, but still expands to +%D something and the second one expands to \type{#1}. Because +%D we accept arguments between \type{{}}, we have to get rid +%D of one level of braces. +%D +%D Our first implementation of \type{\ifundefined} was +%D straightforward and readable: +%D +%D \starttyping +%D \def\ifundefined#1% +%D {\expandafter\ifx\csname#1\endcsname\relax}% +%D +%D \def\doifundefinedelse#1#2#3% +%D {\let\donottest=\dontprocesstest +%D \ifundefined{#1}% +%D \let\donottest=\doprocesstest#2% +%D \else +%D \let\donottest=\doprocesstest#3% +%D \fi} +%D +%D \def\doifdefinedelse#1#2#3% +%D {\doifundefinedelse{#1}{#3}{#2}} +%D +%D \def\doifundefined#1#2% +%D {\doifundefinedelse{#1}{#2}{}} +%D +%D \def\doifdefined#1#2% +%D {\doifundefinedelse{#1}{}{#2}} +%D +%D \def\doifalldefinedelse#1#2#3% +%D {\begingroup +%D \donetrue +%D \def\checkcommand##1% +%D {\doifundefined{##1}{\donefalse}}% +%D \processcommalist[#1]\checkcommand +%D \ifdone +%D \endgroup#2% +%D \else +%D \endgroup#3% +%D \fi} +%D \stoptyping +%D +%D When this module was optimized, timing showed that the +%D next alternative can be upto twice as fast, especially when +%D longer arguments are used. Watch how we reach over the +%D \type {\else} and \type {\fi}: this way they cannot get +%D into the way (and we can avoid those \type {\next} +%D hacks); I started using this method after I did some +%D speed optimization tests in the xtag modules; the +%D efficiency of such hacks depends on the length of the +%D argument etc. etc.) + +\beginTEX + +\def\ifundefined#1% + {\expandafter\ifx\csname#1\endcsname\relax} + +\def\p!doifundefined#1% + {\let\donottest\dontprocesstest + \expandafter\ifx\csname#1\endcsname\relax} + +\def\doifundefinedelse#1% + {\p!doifundefined{#1}% + \let\donottest\doprocesstest\@EA\firstoftwoarguments + \else + \let\donottest\doprocesstest\@EA\secondoftwoarguments + \fi} + +\def\doifdefinedelse#1% + {\p!doifundefined{#1}% + \let\donottest\doprocesstest\@EA\secondoftwoarguments + \else + \let\donottest\doprocesstest\@EA\firstoftwoarguments + \fi} + +\def\doifundefined#1% + {\p!doifundefined{#1}% + \let\donottest\doprocesstest\@EA\firstofoneargument + \else + \let\donottest\doprocesstest\@EA\gobbleoneargument + \fi} + +\def\doifdefined#1% + {\p!doifundefined{#1}% + \let\donottest\doprocesstest\@EA\gobbleoneargument + \else + \let\donottest\doprocesstest\@EA\firstofoneargument + \fi} + +\endTEX + +\beginETEX \ifcsname + +\def\ifundefined#1% ongelukkige naam + {\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} + +\endETEX + +%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: + +\beginTEX + +\def\letbeundefined#1% + {\expandafter\let\csname#1\endcsname\relax} + +\endTEX + +\beginETEX \undefined + +\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 +%D {\em is} defined! + +%D Before we start using this variant, we used another one, +%D which is even a bit faster. This one looked like: +%D +%D \starttyping +%D \def\p!doifundefined% +%D {\begingroup +%D \let\donottest=\dontprocesstest +%D \ifundefined} +%D +%D \def\doifundefinedelse#1#2#3% +%D {\p!doifundefined{#1}% +%D \endgroup#2% +%D \else +%D \endgroup#3% +%D \fi} +%D \stoptyping +%D +%D A even more previous version used \type{\bgroup} and +%D \type {\egroup}. In math mode however, \type{$1{x}2$} differs +%D from \type{$1x2$}. This can been seen when one compares the +%D output of: +%D +%D \starttyping +%D $\kern10pt\showthe\lastkern$ +%D $\kern10pt{\showthe\lastkern}$ +%D $\kern10pt\begingroup\showthe\lastkern\endgroup$ +%D \stoptyping +%D +%D Also in math mode, one can better use \type {\begingroup} +%D and companion instead of \type {\bgroup}. +%D +%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}. +%D Later, when we had optimized some macro's the grouped +%D solution turned out to be unsafe when typesetting this +%D documentation, especially when using \type{\globaldefs}. +%D +%D We still have to define \type{\doifalldefinedelse}. Watch +%D the use of grouping, which garantees local use of the +%D boolean \type{\ifdone}. + +\beginTEX + +\def\docheckonedefined#1% + {\ifundefined{#1}% + \donefalse + \fi} + +\def\doifalldefinedelse#1% + {\begingroup + \let\donottest\dontprocesstest + \donetrue + \processcommalist[#1]\docheckonedefined + \ifdone + \endgroup\let\donottest\doprocesstest + \expandafter\firstoftwoarguments + \else + \endgroup\let\donottest\doprocesstest + \expandafter\secondoftwoarguments + \fi} + +\endTEX + +\beginETEX \ifcsname + +\def\docheckonedefined#1% + {\unless\ifcsname#1\endcsname + \donefalse + \fi} + +\def\doifalldefinedelse#1% + {\begingroup + \donetrue \processcommalist[#1]\docheckonedefined + \ifdone + \endgroup\expandafter\firstoftwoarguments + \else + \endgroup\expandafter\secondoftwoarguments + \fi} + +\endETEX + +%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}. +%D +%D This implementatie does not use the construction which is +%D more robust for nested conditionals. +%D +%D \starttyping +%D \ifx\!!stringa\!!stringb +%D \def\next{#3}% +%D \else +%D \def\next{#4}% +%D \fi +%D \next +%D \stoptyping +%D +%D In practice, this alternative is at least 20\% slower than +%D the alternative used here. The few cases in which we +%D really need the \type{\next} construction, often need some +%D other precautions and or adaptions too. + +\beginTEX + +% \long\def\doif#1#2#3% +% {\let\donottest\dontprocesstest +% \edef\!!stringa{#1}% +% \edef\!!stringb{#2}% +% \let\donottest\doprocesstest +% \ifx\!!stringa\!!stringb +% #3% +% \fi} +% +% \long\def\doifnot#1#2#3% +% {\let\donottest\dontprocesstest +% \edef\!!stringa{#1}% +% \edef\!!stringb{#2}% +% \let\donottest\doprocesstest +% \ifx\!!stringa\!!stringb +% \else +% #3% +% \fi} +% +% \long\def\doifelse#1#2#3#4% +% {\let\donottest\dontprocesstest +% \edef\!!stringa{#1}% +% \edef\!!stringb{#2}% +% \let\donottest\doprocesstest +% \ifx\!!stringa\!!stringb +% #3% +% \else +% #4% +% \fi} + +%D Slightly faster on big arguments, as well as \type +%D {\next} avoiding: + +\long\def\doif#1#2% + {\let\donottest\dontprocesstest + \edef\!!stringa{#1}% + \edef\!!stringb{#2}% + \let\donottest\doprocesstest + \ifx\!!stringa\!!stringb + \expandafter\firstofoneargument + \else + \expandafter\gobbleoneargument + \fi} + +\long\def\doifnot#1#2% + {\let\donottest\dontprocesstest + \edef\!!stringa{#1}% + \edef\!!stringb{#2}% + \let\donottest\doprocesstest + \ifx\!!stringa\!!stringb + \expandafter\gobbleoneargument + \else + \expandafter\firstofoneargument + \fi} + + +\long\def\doifelse#1#2% + {\let\donottest\dontprocesstest + \edef\!!stringa{#1}% + \edef\!!stringb{#2}% + \let\donottest\doprocesstest + \ifx\!!stringa\!!stringb + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +\endTEX + +\beginETEX \protected + +% \long\def\doif#1#2#3% +% {\edef\!!stringa{#1}\edef\!!stringb{#2}% +% \ifx\!!stringa\!!stringb#3\fi} +% +% \long\def\doifnot#1#2#3% +% {\edef\!!stringa{#1}\edef\!!stringb{#2}% +% \unless\ifx\!!stringa\!!stringb#3\fi} +% +% \long\def\doifelse#1#2#3#4% +% {\edef\!!stringa{#1}\edef\!!stringb{#2}% +% \ifx\!!stringa\!!stringb#3\else#4\fi} + +%D Slightly faster on big arguments, as well as \type +%D {\next} avoiding: + +\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} + +\endETEX + +%D One could wonder why we don't follow the the same approach +%D as in \type{\doifdefined} c.s.\ and use \type{\begingroup} +%D and \type{\endgroup}. In this case, this alternative is +%D slower, which is probably due to the fact that more meanings +%D need to be restored. +%D +%D The in terms of memory more efficient alternative using a +%D auxiliary macro also proved to be slower, so we definitely +%D did not choose for: +%D +%D \starttyping +%D \def\p!doifelse#1#2% +%D {\let\donottest=\dontprocesstest +%D \edef\!!stringa{#1}% +%D \edef\!!stringb{#2}% +%D \let\donottest=\doprocesstest +%D \ifx\!!stringa\!!stringb} +%D +%D \long\def\doif#1#2#3% +%D {\p!doifelse{#1}{#2}#3\fi} +%D +%D \long\def\doifnot#1#2#3% +%D {\p!doifelse{#1}{#2}\else#3\fi} +%D +%D \long\def\doifelse#1#2#3#4% +%D {\p!doifelse{#1}{#2}#3\else#4\fi} +%D \stoptyping +%D +%D Optimizations like this are related of course to the +%D bottlenecks in \TEX. It seems that restoring saved meanings +%D and passing arguments takes some time. + +%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 +%D +%D The second argument is the comma separated set of strings. +%D +%D \starttyping +%D \long\def\doifinsetelse#1#2#3#4% +%D {\doifelse{#1}{} +%D {#4} +%D {\donefalse +%D \def\p!checkiteminset##1% +%D {\doif{#1}{##1} +%D {\donetrue +%D \let\p!checkiteminset=\gobbleoneargument}}% +%D \processcommalist[#2]\p!checkiteminset +%D \ifdone +%D #3% +%D \else +%D #4% +%D \fi}} +%D +%D \long\def\doifinset#1#2#3% +%D {\doifinsetelse{#1}{#2}{#3}{}} +%D +%D \long\def\doifnotinset#1#2#3% +%D {\doifinsetelse{#1}{#2}{}{#3}} +%D \stoptyping +%D +%D Because this macro is called quite often we've spent some +%D time optimizing it. This time, the gain in speed is due to +%D (1)~defining an external auxiliary macro, (2)~not calling +%D any other macros and (3)~minimizing the passing of +%D arguments. The gain in speed is impressive. + +% \def\p!dodocheckiteminset#1% +% {\edef\!!stringb{#1}% +% \ifx\!!stringa\!!stringb +% \donetrue +% \let\p!docheckiteminset\gobbleoneargument +% \fi} +% +% \beginTEX +% +% \def\p!doifinsetelse#1#2% +% {\let\donottest\dontprocesstest +% \donefalse +% \edef\!!stringa{#1}% +% \ifx\!!stringa\empty +% \else +% \let\p!docheckiteminset\p!dodocheckiteminset +% \processcommalist[#2]\p!docheckiteminset +% \fi +% \let\donottest\doprocesstest +% \ifdone} +% +% \endTEX +% +% \beginETEX \protected +% +% \def\p!doifinsetelse#1#2% +% {\donefalse +% \edef\!!stringa{#1}% +% \ifx\!!stringa\empty +% \else +% \let\p!docheckiteminset\p!dodocheckiteminset +% \processcommalist[#2]\p!docheckiteminset +% \fi +% \ifdone} +% +% \endETEX + +% then we had: +% +% \def\p!docheckiteminset#1% +% {\edef\!!stringb{#1}% +% \ifx\!!stringa\!!stringb +% \donetrue +% \expandafter\quitcommalist +% \fi} +% +% \beginTEX +% +% \def\p!doifinsetelse#1#2% +% {\let\donottest\dontprocesstest +% \donefalse +% \edef\!!stringa{#1}% +% \ifx\!!stringa\empty +% \else +% \processcommalist[#2]\p!docheckiteminset +% \fi +% \let\donottest\doprocesstest +% \ifdone} +% +% \endTEX +% +% % can be sped up with processnext... +% +% \beginETEX \protected +% +% \def\p!doifinsetelse#1#2% +% {\donefalse +% \edef\!!stringa{#1}% +% \ifx\!!stringa\empty +% \else +% \processcommalist[#2]\p!docheckiteminset +% \fi +% \ifdone} +% +% \endETEX +% +% \long\def\doifinsetelse#1#2% +% {\p!doifinsetelse{#1}{#2}% +% \expandafter\firstoftwoarguments +% \else +% \expandafter\secondoftwoarguments +% \fi} +% +% \long\def\doifinset#1#2% +% {\p!doifinsetelse{#1}{#2}% +% \expandafter\firstofoneargument +% \else +% \expandafter\gobbleoneargument +% \fi} +% +% \long\def\doifnotinset#1#2% +% {\p!doifinsetelse{#1}{#2}% +% \expandafter\gobbleoneargument +% \else +% \expandafter\firstofoneargument +% \fi} +% +% now we have + +\def\p!docheckiteminset#1% + {\edef\!!stringb{#1}% + \ifx\!!stringa\!!stringb + \donetrue + \expandafter\quitcommalist + \fi} + +\beginTEX + +\def\p!doifinsetelse#1#2#3#4% + {\let\donottest\dontprocesstest + \donefalse + \edef\!!stringa{#3}% + \ifx\!!stringa\empty + \else + \processcommalist[#4]\p!docheckiteminset + \fi + \let\donottest\doprocesstest + \ifdone\expandafter#1\else\expandafter#2\fi} + +\endTEX + +\beginETEX \protected + +\def\p!doifinsetelse#1#2#3#4% + {\donefalse + \edef\!!stringa{#3}% + \ifx\!!stringa\empty + \else + \processcommalist[#4]\p!docheckiteminset + \fi + \ifdone\expandafter#1\else\expandafter#2\fi} + +\endETEX + +\long\def\doifinsetelse + {\p!doifinsetelse\firstoftwoarguments\secondoftwoarguments} + +\long\def\doifinset + {\p!doifinsetelse\firstofoneargument\gobbleoneargument} + +\long\def\doifnotinset + {\p!doifinsetelse\gobbleoneargument\firstofoneargument} + +%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 +%D +%D We show the slower alternative first, because it shows us +%D how things are done. +%D +%D \starttyping +%D \long\def\doifcommonelse#1#2#3#4% +%D {\donefalse +%D \def\p!docommoncheck##1% +%D {\def\p!dodocommoncheck####1% +%D {\doif{####1}{##1} +%D {\donetrue +%D \def\commalistelement{##1}% +%D \let\p!docommoncheck=\gobbleoneargument +%D \let\p!dodocommoncheck=\gobbleoneargument}}% +%D \processcommalist[#2]\p!dodocommoncheck}% +%D \processcommalist[#1]\p!docommoncheck +%D \ifdone +%D #3% +%D \else +%D #4% +%D \fi} +%D +%D \long\def\doifcommon#1#2#3% +%D {\doifcommonelse{#1}{#2}{#3}{}} +%D +%D \long\def\doifnotcommon#1#2#3% +%D {\doifcommonelse{#1}{#2}{}{#3}} +%D \stoptyping +%D +%D The processing time is shortened by getting the auxiliary +%D macro to the outermost level and using less \type{\edef}'s. +%D Sometimes it makes more sence to define local macro's not +%D only because this way we can be sure that they are not +%D redefined, but also because it shows the dependance. In +%D compiled languages, this is no problem at all. It can even +%D save us bytes and processing time. In interpreted languages +%D like \TEX\ it nearly always slows down processing. + +% \def\p!dododocommoncheck#1% +% {\edef\!!stringb{#1}% +% \ifx\!!stringa\!!stringb +% \donetrue +% \let\p!docommoncheck\gobbleoneargument +% \let\p!dodocommoncheck\gobbleoneargument +% \fi} +% +% \beginTEX +% +% \def\p!doifcommonelse#1#2% +% {\donefalse +% \let\donottest\dontprocesstest +% \let\p!dodocommoncheck\p!dododocommoncheck +% \def\p!docommoncheck##1% +% {\edef\!!stringa{##1}% +% \def\commalistelement{##1}% +% \processcommalist[#2]\p!dodocommoncheck}% +% \processcommalist[#1]\p!docommoncheck +% \let\donottest\doprocesstest +% \ifdone} +% +% \endTEX +% +% \beginETEX \protected +% +% \def\p!doifcommonelse#1#2% +% {\donefalse +% \let\p!dodocommoncheck\p!dododocommoncheck +% \def\p!docommoncheck##1% +% {\edef\!!stringa{##1}% +% \def\commalistelement{##1}% +% \processcommalist[#2]\p!dodocommoncheck}% +% \processcommalist[#1]\p!docommoncheck +% \ifdone} +% +% \endETEX + +% \def\p!dodocommoncheck#1% +% {\edef\!!stringb{#1}% +% \ifx\!!stringa\!!stringb +% \donetrue +% \expandafter\quitprevcommalist +% \fi} +% +% \beginTEX +% +% \def\p!doifcommonelse#1#2% +% {\donefalse +% \let\donottest\dontprocesstest +% \def\p!docommoncheck##1% +% {\edef\!!stringa{##1}% +% \def\commalistelement{##1}% no let to stringa +% \processcommalist[#2]\p!dodocommoncheck}% +% \processcommalist[#1]\p!docommoncheck +% \let\donottest\doprocesstest +% \ifdone} +% +% \endTEX +% +% \beginETEX \protected +% +% \def\p!doifcommonelse#1#2% +% {\donefalse +% \def\p!docommoncheck##1% +% {\edef\!!stringa{##1}% +% \def\commalistelement{##1}% +% \processcommalist[#2]\p!dodocommoncheck}% +% \processcommalist[#1]\p!docommoncheck +% \ifdone} +% +% \endETEX +% +% \long\def\doifcommonelse#1#2% % #3#4% +% {\p!doifcommonelse{#1}{#2}% % #3\else#4\fi} +% \expandafter\firstoftwoarguments +% \else +% \expandafter\secondoftwoarguments +% \fi} +% +% \long\def\doifcommon#1#2% +% {\p!doifcommonelse{#1}{#2}% +% \expandafter\firstofoneargument +% \else +% \expandafter\gobbleoneargument +% \fi} +% +% \long\def\doifnotcommon#1#2% +% {\p!doifcommonelse{#1}{#2}% +% \expandafter\gobbleoneargument +% \else +% \expandafter\firstofoneargument +% \fi} + +% todo: use dedicated done + +\def\p!dodocommoncheck#1% + {\edef\!!stringb{#1}% + \ifx\!!stringa\!!stringb + \donetrue + \expandafter\quitprevcommalist + \fi} + +\beginTEX + +\def\p!doifcommonelse#1#2#3#4% + {\donefalse + \let\donottest\dontprocesstest + \def\p!docommoncheck##1% + {\edef\!!stringa{##1}% + \def\commalistelement{##1}% no let to stringa + \processcommalist[#4]\p!dodocommoncheck}% + \processcommalist[#3]\p!docommoncheck + \let\donottest\doprocesstest + \ifdone\expandafter#1\else\expandafter#2\fi} + +\endTEX + +\beginETEX \protected + +\def\p!doifcommonelse#1#2#3#4% + {\donefalse + \def\p!docommoncheck##1% + {\edef\!!stringa{##1}% + \def\commalistelement{##1}% + \processcommalist[#4]\p!dodocommoncheck}% + \processcommalist[#3]\p!docommoncheck + \ifdone\expandafter#1\else\expandafter#2\fi} + +\endETEX + +\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 +% \let\nextcommaitem\redoprocesscommaitem +% \else\ifx\nexttoken]% +% \let\nextcommaitem\gobbleoneargument +% \else +% \let\nextcommaitem\dododoprocesscommaitem +% \fi\fi +% \nextcommaitem} +% +% faster ? + +\def\dodoprocesscommaitem + {\ifx\nexttoken\blankspace + \@EA\redoprocesscommaitem + \else\ifx\nexttoken]% + \@EAEAEA\gobbleoneargument + \else + \@EAEAEA\dododoprocesscommaitem + \fi\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}]}. +%D +%D \starttyping +%D \def\processcommalist[% +%D {\futurelet\nexttoken\docheckcommaitem} +%D +%D \def\docheckcommaitem% +%D {\ifx\nexttoken]% +%D \let\nextcommaitem\gobbletwoarguments +%D \else\ifx\nexttoken\bgroup +%D \let\nextcommaitem\doprocesscommalistA +%D \else +%D \let\nextcommaitem\doprocesscommalistB +%D \fi\fi +%D \nextcommaitem} +%D +%D \def\doprocesscommalistA#1#2]#3% +%D {\global\advance\commalevel 1 +%D \long\expandafter\def\csname\s!next\the\commalevel\endcsname##1,% +%D {#3{##1}\doprocesscommaitem}% +%D \doprocesscommaitem{#1}#2,]\relax +%D \global\advance\commalevel -1 } +%D +%D \def\doprocesscommalistB#1]#2% +%D {\global\advance\commalevel 1 +%D \long\expandafter\def\csname\s!next\the\commalevel\endcsname##1,% +%D {#2{##1}\doprocesscommaitem}% +%D \doprocesscommaitem#1,]\relax +%D \global\advance\commalevel -1 } +%D \stoptyping +%D +%D However, this is not a the most straightforward solution! +%D We can misuse one of \TEX's hidden features, and prepend +%D and remove a \type {\relax}. By the way, although it +%D involves less testing, this cleaner alternative is not +%D faster. + +\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]}} + +%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. +%D +%D Even a quick glance at the macros below show some overlap, +%D which means that more efficient alternatives are possible. +%D Because these macro's are very sensitive to subtle changes, +%D we've decided to present the readable originals first +%D Maybe these these macros look complicated, but this is a +%D direct result of the support of nesting. Protection is only +%D applied in \type{\processaction}. +%D +%D \starttyping +%D \newcount\processlevel +%D +%D \def\processaction[#1]#2[#3]% +%D {\doifelse{#1}{} +%D {\def\p!compareprocessaction[##1=>##2]% +%D {\edef\!!stringa{##1}% +%D \ifx\!!stringa\s!default +%D \def\commalistelement{#1}% +%D ##2% +%D \fi}} +%D {\let\donottest=\dontprocesstest +%D \edef\!!stringb{#1}% +%D \let\donottest=\doprocesstest +%D \def\p!compareprocessaction[##1=>##2]% +%D {\edef\!!stringa{##1}% +%D \ifx\!!stringa\!!stringb +%D \def\commalistelement{#1}% +%D ##2% +%D \let\p!doprocessaction=\gobbleoneargument +%D \else\ifx\!!stringa\s!unknown +%D \def\commalistelement{#1}% +%D ##2% +%D \fi\fi}}% +%D \def\p!doprocessaction##1% +%D {\p!compareprocessaction[##1]}% +%D \processcommalist[#3]\p!doprocessaction} +%D +%D \def\processfirstactioninset[#1]#2[#3]% +%D {\doifelse{#1}{} +%D {\processaction[][#3]} +%D {\def\p!compareprocessaction[##1=>##2][##3]% +%D {\edef\!!stringa{##1}% +%D \edef\!!stringb{##3}% +%D \ifx\!!stringa\!!stringb +%D \def\commalistelement{##3}% +%D ##2% +%D \let\p!doprocessaction=\gobbleoneargument +%D \let\p!dodoprocessaction=\gobbleoneargument +%D \else\ifx\!!stringa\s!unknown +%D \def\commalistelement{##3}% +%D ##2% +%D \fi\fi}% +%D \def\p!doprocessaction##1% +%D {\def\p!dodoprocessaction####1% +%D {\p!compareprocessaction[####1][##1]}% +%D \processcommalist[#3]\p!dodoprocessaction}% +%D \processcommalist[#1]\p!doprocessaction}} +%D +%D \def\processallactionsinset[#1]#2[#3]% +%D {\doifelse{#1}{} +%D {\processaction[][#3]} +%D {\advance\processlevel by 1 +%D \def\p!compareprocessaction[##1=>##2][##3]% +%D {\edef\!!stringa{##1}% +%D \edef\!!stringb{##3}% +%D \ifx\!!stringa\!!stringb +%D \def\commalistelement{##3}% +%D ##2% +%D \let\p!dodoprocessaction=\gobbleoneargument +%D \else\ifx\!!stringa\s!unknown +%D \def\commalistelement{##3}% +%D ##2% +%D \fi\fi}% +%D \setvalue{\s!do\the\processlevel}##1% +%D {\def\p!dodoprocessaction####1% +%D {\p!compareprocessaction[####1][##1]}% +%D \processcommalist[#3]\p!dodoprocessaction}% +%D \processcommalist[#1]{\getvalue{\s!do\the\processlevel}}% +%D \advance\processlevel by -1 }} +%D \stoptyping +%D +%D The gain of speed in the (again) next implementation is +%D around 20\%, depending on the application. + +\newcount\processlevel + +\def\p!compareprocessactionA[#1=>#2][#3]% + {\edef\!!stringb{#1}% + \ifx\!!stringb\s!default + \let\commalistelement\empty + #2% + \fi} + +% \def\p!compareprocessactionB[#1=>#2][#3]% +% {\expandedaction\!!stringb{#1}% +% \ifx\!!stringa\!!stringb +% \def\commalistelement{#3}% +% #2% +% \let\p!doprocessaction\gobbleoneargument +% \else +% \edef\!!stringb{#1}% +% \ifx\!!stringb\s!unknown +% \def\commalistelement{#3}% beware of loops +% #2% +% \fi +% \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} + +\beginTEX + +\def\processaction[#1]#2[#3]% + {\let\donottest\dontprocesstest + \expandedaction\!!stringa{#1}% + \let\donottest\doprocesstest + \ifx\!!stringa\empty + \let\p!compareprocessaction\p!compareprocessactionA + \else + \let\p!compareprocessaction\p!compareprocessactionB + \fi + \def\p!doprocessaction##1% + {\p!compareprocessaction[##1][#1]}% + \processcommalist[#3]\p!doprocessaction + \expandactions} + +\endTEX + +\beginETEX \protected + +\def\processaction[#1]#2[#3]% faster version follows + {\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]}% + \processcommalist[#3]\p!doprocessaction + \expandactions} + +\endETEX + +% \def\p!compareprocessactionC[#1=>#2][#3]% +% {\expandedaction\!!stringa{#1}% +% \expandedaction\!!stringb{#3}% +% \ifx\!!stringa\!!stringb +% \def\commalistelement{#3}% +% #2% +% \let\p!doprocessaction\gobbleoneargument +% \let\p!dodoprocessaction\gobbleoneargument +% \else +% \edef\!!stringa{#1}% +% \ifx\!!stringa\s!unknown +% \def\commalistelement{#3}% +% #2% +% \fi +% \fi} + +\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]#2[#3]% faster version follows + {\expandedaction\!!stringa{#1}% + \ifx\!!stringa\empty + \processaction[][#3]% + \else + \def\p!doprocessaction##1% + {\def\p!dodoprocessaction####1% + {\p!compareprocessactionC[####1][##1]}% + \processcommalist[#3]\p!dodoprocessaction}% + \processcommalist[#1]\p!doprocessaction + \fi + \expandactions} + +% \def\p!compareprocessactionD[#1=>#2][#3]% +% {\expandedaction\!!stringa{#1}% +% \expandedaction\!!stringb{#3}% +% \ifx\!!stringa\!!stringb +% \def\commalistelement{#3}% +% #2% +% \let\p!dodoprocessaction\gobbleoneargument +% \else +% \edef\!!stringa{#1}% +% \ifx\!!stringa\s!unknown +% \def\commalistelement{#3}% +% #2% +% \fi +% \fi} + +\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]#2[#3]% faster version follows + {\expandedaction\!!stringa{#1}% + \ifx\!!stringa\empty + \processaction[][#3]% + \else + \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 + \fi + \expandactions} + +%D We can speed up these macros a bit when we use a dedicated +%D commalist processor, one that avoids passing the (often) +%D big action list. + +\beginTEX + +\def\processaction[#1]#2[% + {\let\donottest\dontprocesstest + \expandedaction\!!stringa{#1}% + \let\donottest\doprocesstest + \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[} + +\endTEX + +\beginETEX + +\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[} + +\endETEX + +\def\processfirstactionsinset[#1]% + {\expandedaction\!!stringa{#1}% + \ifx\!!stringa\empty + \expandafter\processaction + \else + \expandafter\processfirstactionsinsetindeed + \fi + [#1]} + +\def\processfirstactioninsetindeed[#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\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} + +\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 I do have an even faster version (saving 3 sec on a 13 +%D sec run for 50K invocations, but normally we don't have +%D that many calls and that alternative uses more macros and is +%D even less readable. What we did add, was \type {\@EA}, so +%D that we can pass a command. + +%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 +%D +%D An application of this command can be found further on. +%D Like before, we first show some alternatives, like the one +%D we started with: +%D +%D \starttyping +%D \long\def\p!doifinstringelse#1#2#3#4% +%D {\def\pp!doifinstringelse##1#1##2##3\war% +%D {\if##2@% +%D #4% +%D \else +%D #3% +%D \fi}% +%D \pp!doifinstringelse#2#1@@\war} +%D +%D \def\doifinstringelse% +%D {\ExpandBothAfter\p!doifinstringelse} +%D \stoptyping +%D +%D After this we came to: +%D +%D \starttyping +%D \def\p!doifinstringelse#1#2% +%D {\def\pp!doifinstringelse##1#1##2##3\war% +%D {\if##2@}% +%D \pp!doifinstringelse#2#1@@\war} +%D +%D \def\doifinstringelse#1#2#3#4% +%D {\ExpandBothAfter\p!doifinstringelse{#1}{#2}% +%D #4% +%D \else +%D #3% +%D \fi} +%D \stoptyping +%D +%D Sometimes the second argument is passed as a macro. By +%D postponing the expansion of this macro, we gain quite some +%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 + \@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} + +%D \starttyping +%D \beginTEX +%D +%D \long\def\p!doifinstringelse#1#2% +%D {\long\def\pp!doifinstringelse##1#1##2##3\war% +%D {\csname if\if##2@fals\else tru\fi e\endcsname}% +%D \expanded{\pp!doifinstringelse#2#1@@\noexpand\war}} % expand #2 here +%D +%D \endTEX +%D +%D \beginETEX \unless +%D +%D \long\def\p!doifinstringelse#1#2% +%D {\long\def\pp!doifinstringelse##1#1##2##3\war% +%D {\unless\if##2@}% +%D \expanded{\pp!doifinstringelse#2#1@@\noexpand\war}} % expand #2 here +%D +%D \endETEX +%D \stoptyping +%D +%D And then \unknown\ after a couple of years, we ran into a +%D situation where \type {##2} was something \type {{bla}}. So +%D finally we need to use an auxiliary macro, otherwise we get +%D funny strings in the output. + +% \long\def\p!doifinstringelse#1#2% ##2 can be {abc} +% {\long\@EA\def\@EA\pp!doifinstringelse\@EA##\@EA1#1##2##3\war % expand #1 here +% {\ppp!doifinstringelse##2\war}% +% \expanded{\pp!doifinstringelse#2#1@@\noexpand\war}} % expand #2 here +% +% \beginTEX +% +% \def\ppp!doifinstringelse#1#2\war% +% {\csname if\ifx#1@fals\else tru\fi e\endcsname}% +% +% \endTEX +% +% \beginETEX \unless +% +% \def\ppp!doifinstringelse#1#2\war% +% {\unless\ifx#1@} +% +% \endETEX + +\beginETEX + +\long\def\p!doifinstringelse#1#2% ##2 can be {abc} + {\long\@EA\def\@EA\pp!doifinstringelse\@EA##\@EA1#1##2##3\war % expand #1 here + {\unless\if##2@}% +% \expanded{\pp!doifinstringelse#2#1@@\noexpand\war}} % expand #2 here + \expanded{\pp!doifinstringelse#2#1}@@\war} % expand #2 here + +\endETEX + +\beginTEX + +\long\def\p!doifinstringelse#1#2% ##2 can be {abc} + {\long\@EA\def\@EA\pp!doifinstringelse\@EA##\@EA1#1##2##3\war % expand #1 here + {\csname if\if##2@fals\else tru\fi e\endcsname}% + %\expanded{\pp!doifinstringelse#2#1@@\noexpand\war}} % expand #2 here + \expanded{\pp!doifinstringelse#2#1}@@\war} % expand #2 here + +\endTEX + +%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. + +\beginTEX + +\long\def\p!doifincsnameelse#1#2% + {\long\def\pp!doifincsnameelse##1#1##2##3\war + {\csname if\if##2@fals\else tru\fi e\endcsname}% + \@EA\pp!doifincsnameelse#2#1@@\war} + +\endTEX + +\beginETEX \unless + +\long\def\p!doifincsnameelse#1#2% + {\long\def\pp!doifincsnameelse##1#1##2##3\war + {\unless\if##2@}% + \@EA\pp!doifincsnameelse#2#1@@\war} + +\endETEX + +\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. +%D +%D \starttyping +%D \long\def\doifnumberelse#1#2#3% +%D {\begingroup\donefalse +%D \ifcase1#1\or\or\or\or\or\or\or\or\or\else\donetrue\fi +%D \ifdone\endgroup#2\else\endgroup#3\fi} +%D \stoptyping +%D +%D Or better: +%D +%D \starttyping +%D \long\def\doifnumberelse#1% +%D {\begingroup\donefalse +%D \ifcase1#1\or\or\or\or\or\or\or\or\or\else\donetrue\fi +%D \ifdone +%D \endgroup\expandafter\firstoftwoarguments +%D \else +%D \endgroup\expandafter\secondoftwoarguments +%D \fi} +%D \stoptyping +%D +%D A previous implementation was: +%D +%D \starttyping +%D \long\def\doifnumberelse#1#2#3% +%D {\getfirstcharacter{#1}% +%D \@EA\p!doifinstringelse\@EA{\firstcharacter}{1234567890}% +%D #2% +%D \else +%D #3% +%D \fi} +%D \stoptyping +%D +%D And before we had \type{\p!doifinstringelse} available, we +%D used: +%D +%D \starttyping +%D \def\doifnumberelse#1% +%D {\getfirstcharacter{#1}% +%D \rawdoifinsetelse{\firstcharacter}{1,2,3,4,5,6,7,8,9,0}} +%D \stoptyping +%D +%D The implementation using \type {\ifcase} is much faster, but +%D the next one is not, not even when testing milion calls. +%D +%D \starttyping +%D \newif\ifitsanumber +%D +%D \long\def\isitanumber#1% +%D {\itsanumberfalse +%D \ifcase1#1\or\or\or\or\or\or\or\or\or\else\itsanumbertrue\fi} +%D +%D \long\def\doifnumberelse#1#2#3% +%D {\isitanumber{#1}\ifitsanumber#2\else#3\fi} +%D \stoptyping +%D +%D After a while the next evolved and this one is the one we +%D will use. This one is some 5\% faster than the group/done +%D one (partly because it does not have to pass arguments). +%D Even more important is that this alternative is fully +%D expandable! + +\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). +%D +%D The slow alternative looks like: +%D +%D \starttyping +%D \def\makerawcommalist[#1]#2% +%D {\def\appendtocommalist##1% +%D {\doifelse{#2}{} +%D {\edef#2{##1}} +%D {\edef#2{#2,##1}}}% +%D \def#2{}% +%D \processcommalist[#1]\appendtocommalist} +%D \stoptyping +%D +%D But we prefer: + +% \appendtocommalist is defined in syst-ext + +\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} + +% not needed +% +% \def\rawprocessallactionsinset[#1]#2[#3]% +% {\def\docommand##1% +% {\rawprocessaction[##1][#3]}% +% \processcommalist[#1]\docommand} + +%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 {processunexpandedcommalist} +% %D +% %D When processing commalists, the arguments are expanded. The +% %D main reason for doing so lays in the fact that these +% %D macros are used for interfacing. The next alternative can be used +% %D for +% %D +% %D \starttyping +% %D \processunexpandedcommalist +% %D [\alfa\beta,\gamma,\delta\epsilon] +% %D \handleitem +% %D \stoptyping +% %D +% %D This time nesting is not supported. +% +% %\def\processunexpandedcommaitem#1,% +% % {\if]\noexpand#1% +% % \let\nextcommaitem\relax +% % \else +% % \handleunexpandedcommaitem{#1}% +% % \let\nextcommaitem\processunexpandedcommaitem +% \fi +% \nextcommaitem} +% +% faster: +% +% \def\processunexpandedcommaitem#1,% +% {\if]\noexpand#1\else +% \handleunexpandedcommaitem{#1}% +% \expandafter\processunexpandedcommaitem +% \fi} +% +% \def\processunexpandedcommalist[#1]#2% +% {\def\handleunexpandedcommaitem{#2}% +% \processunexpandedcommaitem#1,],}% \relax} +% +% %D Or faster: +% +% \def\processunexpandedcommaitem#1,% +% {\if]\noexpand#1\else +% \handleunexpandedcommaitem{#1}% +% \expandafter\processunexpandedcommaitem +% \fi} + +%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\p!doassign#1[#2][#3=#4=#5]% +% {\let\donottest\dontprocesstest +% \edef\!!stringa{#5}% +% \let\!!stringb\relax +% \let\donottest\doprocesstest +% \ifx\!!stringa\!!stringb +% \showassignerror{#3}% +% \else +% #1{#2}{#3}{#4}% +% \fi} + +\def\p!doassign#1[#2][#3=#4=#5]% + {\ifx\empty#3\else % and definitely not \ifx#3\empty + \ifx\relax#5% + \showassignerror{#3}{\the\inputlineno\space(#2)}% + \else + #1{#2}{#3}{#4}% + \fi + \fi} + +\def\doassign [#1][#2]{\p!doassign\dosetvalue [#1][#2==\relax]} +\def\doeassign [#1][#2]{\p!doassign\dosetevalue [#1][#2==\relax]} +\def\undoassign[#1][#2]{\p!doassign\doresetvalue[#1][#2==\relax]} + +\def\doassignempty[#1][#2=#3]% + {\ifundefined{#1#2}\dosetvalue{#1}{#2}{#3}\fi} + +%D \macros +%D {processassignmentlist,processassignmentcommand, +%D startprocessassignmentlist,startprocessassignmentcommand} +%D +%D For Wolfgang: +%D +%D \starttyping +%D \def\showpair#1#2{key:#1, value:#2\par} +%D \processassignmentlist[a=1,b=2]\showpair +%D \stoptyping + +\def\processassignmentlist[#1]#2% #2 == \command{key}{value] + {\def\doprocessassignmententry##1{#2}% {##2}{##3} % namespace is ignored + \dogetparameters\doprocessassignmententry[][#1]} + +\def\processassignmentcommand[#1]% + {\normalexpanded{\noexpand\processassignmentlist[#1]}} + +\long\def\startprocessassignmentlist[#1]#2\stopprocessassignmentlist + {\long\def\currentassignmentlistcommand##1##2{\def\currentassignmentlistkey{##1}\def\currentassignmentlistvalue{##2}#2}% + \processassignmentlist[#1]\currentassignmentlistcommand} + +\long\def\startprocessassignmentcommand[#1]#2\stopprocessassignmentcommand + {\long\def\currentassignmentlistcommand##1##2{\def\currentassignmentlistkey{##1}\def\currentassignmentlistvalue{##2}#2}% + \normalexpanded{\noexpand\processassignmentlist[#1]}\currentassignmentlistcommand} + +%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. + +\def\dogetparameters#1[#2]#3[#4]% + {\def\p!dogetparameter##1% + {\p!doassign#1[#2][##1==\relax]}% + \processcommalist[#4]\p!dogetparameter} + +\def\getparameters {\dogetparameters\dosetvalue} +\def\geteparameters {\dogetparameters\dosetevalue} +\def\getgparameters {\dogetparameters\dosetgvalue} +\def\forgetparameters{\dogetparameters\doignorevalue} + +\let\getexpandedparameters=\geteparameters + +%D This one is slightly faster: + +\def\dogetparameters#1[#2]#3[#4% + {\if\noexpand#4]% + \expandafter\gobbleoneargument + \else + \def\p!dogetparameter##1{\p!doassign#1[#2][##1==\relax]}% + \expandafter\xdogetparameters + \fi#4} + +\def\xdogetparameters#1]% + {\processcommalist[#1]\p!dogetparameter} + +%D The next alternative is much faster but also uglier. Because +%D in \XML\ processing we will probably set much more parameters +%D than normally we need this faster one. + +\def\dogetparameters#1[#2]#3[#4% + {\if\noexpand#4]% + \expandafter\gobbleoneargument + \else + \def\p!dogetparameter{\p!doassign#1#2}% + \expandafter\xdogetparameters + \fi#4} + +\def\xdogetparameters#1]% + {\xprocesscommaitem#1,],\@relax@} + +% \long\def\xprocesscommaitem#1,#2% #2 takes space before , +% {\if]#1% +% \expandafter\gobbleoneargument +% \else +% \p!dogetparameter\@relax@#1==\@relax@ +% \expandafter\xprocesscommaitem +% \fi#2} + +\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} + +%D Here we use a slightly different assignment macro: + +% \def\p!doassign#1#2\@relax@#3=#4=#5\@relax@ +% {\ifx\@relax@#5\@EA\xshowassignerror\else\@EA#1\fi{#2}{#3}{#4}} + +% \def\p!doassign#1#2\@relax@#3=#4=#5\@relax@ +% {\ifx#5\empty\@EA\xshowassignerror\else\@EA#1\fi{#2}{#3}{#4}} + +\def\p!doassign#1#2\@relax@#3=#4=#5#6\@relax@ + {\ifx#5\empty + \@EA\xshowassignerror + \else\ifx#5=% + \@EAEAEA#1% + \else + \@EAEAEA\xshowassignerror + \fi\fi + {#2}{#3}{#4}} + +\def\xshowassignerror#1#2#3% + {\showassignerror{#2}{\the\inputlineno\space(#1)}} + +%D Now we also have to change the other macros that depend +%D on this low level one. + +% \def\doassign [#1][#2]{\p!doassign\dosetvalue #1\@relax@#2==\@relax@} +% \def\doeassign [#1][#2]{\p!doassign\dosetevalue #1\@relax@#2==\@relax@} +% \def\undoassign[#1][#2]{\p!doassign\doresetvalue#1\@relax@#2==\@relax@} + +\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@} + +%D When someone asked on the mailing list if it's possible to +%D use the current value of a parameter, Taco posted a small module. His +%D method had the disadvantage of making all assignments expanded and thereby +%D fragile. The following alternative uses a prefix. + +%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. + +\let\currentvalue\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\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\empty#3\empty + \@EA\xshowassignerror + \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% + \fi\fi + {#2}{#3}{#4}} + +\endTEX + +\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\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}} + +\endETEX + +%D We default to: + +\let\p!doassign\p!n!doassign + +%D And set: + +\let\currentvalue\empty + +%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}}% + %\def\docopyparameter##1{\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]% why so complicated, still needed? +% {\edef\commacommand{#1}% +% \toks0=\expandafter{\expandafter[\commacommand]}% +% \expandafter\getfromcommalist\the\toks0 } + +\def\getfromcommacommand[#1]% + {\expanded{\getfromcommalist[#1]}} + +%D Because 0, 1 and~2 are often asked for, we optimize this +%D macro for those cases. The indirect call however slows +%D down the other cases. +%D +%D \starttyping +%D \def\p!dogetfirstfromcommalist [#1,#2]{\def\commalistelement{#1}} +%D \def\p!dogetsecondfromcommalist[#1,#2,#3]{\def\commalistelement{#2}} +%D \let\p!dogetotherfromcommalist=\getfromcommalist +%D +%D \def\getfromcommalist[#1]#2[#3]% optimized for 0,1,2 +%D {\ifcase#3\relax +%D \let\commalistelement\empty +%D \or +%D \p!dogetfirstfromcommalist[#1,]% +%D \or +%D \p!dogetsecondfromcommalist[#1,,]% +%D \else +%D \p!dogetotherfromcommalist[#1][#3]% +%D \fi} +%D \stoptyping +%D +%D Even worse, this alternative does not strip preceding +%D spaces, which is what we want. So, we stick to the slow +%D alternative. + +%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}} + +% maybe better: +% +% {\@EA\edef\@EA#9\@EA{\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 {\chardef\expectedarguments 1 \dosingleempty } +\def\dodoubleargument {\chardef\expectedarguments 2 \dodoubleempty } +\def\dotripleargument {\chardef\expectedarguments 3 \dotripleempty } +\def\doquadrupleargument {\chardef\expectedarguments 4 \doquadrupleempty } +\def\doquintupleargument {\chardef\expectedarguments 5 \doquintupleempty } +\def\dosixtupleargument {\chardef\expectedarguments 6 \dosixtupleempty } +\def\doseventupleargument{\chardef\expectedarguments 7 \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}{#1 argument(s) expected in line #2}} + +% \long\def\dogetargument#1#2#3#4% redefined in mult-ini +% {\doifnextcharelse{#1} +% {\let\expectedarguments\noexpectedarguments +% #3\dodogetargument} +% {\ifnum\expectedarguments>\noexpectedarguments +% \showargumenterror{\expectedarguments} +% \fi +% \let\expectedarguments\noexpectedarguments +% #4\dodogetargument#1#2}} +% +% less to pass + +\def\doshowargumenterror + {\ifnum\expectedarguments>\noexpectedarguments + \showargumenterror{\number\expectedarguments}{\number\inputlineno}% + \fi + \noshowargumenterror} + +\def\noshowargumenterror + {\let\expectedarguments\noexpectedarguments} + +% \long\def\dogetargument#1#2#3#4% +% {\doifnextcharelse#1% +% {\noshowargumenterror#3\dodogetargument} +% {\doshowargumenterror#4\dodogetargument#1#2}} +% +% faster ? + +\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. + +% This method is needed when traditional tex is used with +% the efficient definition (marked **) below. + +% an old one: +% +% \def\setnameofcommand#1% handles {abc} as well as \abc +% {\begingroup +% \escapechar=-1 +% \globaldefs=0 % pretty important! +% \xdef\nameofcommand{\string#1}% +% \endgroup} +% +% \def\complexorsimple#1% +% {\setnameofcommand{#1}% +% \doifnextcharelse{[} +% {\firstargumenttrue \getvalue{\s!complex\nameofcommand}} +% {\firstargumentfalse\getvalue{\s!simple \nameofcommand}}} +% +% \def\complexorsimpleempty#1% +% {\setnameofcommand{#1}% +% \doifnextcharelse{[} +% {\firstargumenttrue \getvalue{\s!complex\nameofcommand}} +% {\firstargumentfalse\getvalue{\s!complex\nameofcommand}[]}} +% +% a newer one: + +\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. + +% See earlier. Because we don't want \type {\simple..} and +% \type {\complex..} commands to show up in expansions, we need +% to pass them as \type {simple..} and \type {complex..}. + +% \beginTEX +% +% \def\definewithnameofcommand#1#2% +% {\setnameofcommand{#2}% +% \@EA\def\@EA#2\@EA{\@EA\donottest\@EA#1\@EA{\nameofcommand}}} +% +% \def\definecomplexorsimple% +% {\definewithnameofcommand\complexorsimple} +% +% \def\definecomplexorsimpleempty% +% {\definewithnameofcommand\complexorsimpleempty} +% +% \endTEX +% +% \beginETEX \protected +% +% \def\definecomplexorsimple#1% +% {\normalprotected\def#1{\complexorsimple#1}} +% +% \def\definecomplexorsimpleempty#1% +% {\normalprotected\def#1{\complexorsimpleempty#1}} +% +% \endETEX + +% However, since this one uses an idirect method, things go +% okay (at the cost of extra macros). + +% \def\definecomplexorsimple#1% +% {\unexpanded\def#1{\complexorsimple#1}} +% +% \def\definecomplexorsimpleempty#1% +% {\unexpanded\def#1{\complexorsimpleempty#1}} +% +% faster, since no \strippedcsname needed in call, but more spacy + +\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 {definestartstopcommand} +%D +%D Those who get the creeps of expansion may skip the next +%D one. It's one of the most recent additions and concerns +%D \type{\start}||\type{\stop} pairs with complicated +%D arguments. +%D +%D We won't go into details here, but the general form of +%D this using this command is: +%D +%D \starttyping +%D \definestartstopcommand\somecommand\e!specifier{arg}{arg}% +%D {do something with arg} +%D \stoptyping +%D +%D This expands to something like: +%D +%D \starttyping +%D \def\somecommand arg \startspecifier arg \stopspecifier% +%D {do something with arg} +%D \stoptyping +%D +%D The arguments can be anything reasonable, but double +%D \type{#}'s are needed in the specification part, like: +%D +%D \starttyping +%D \definestartstopcommand\somecommand\e!specifier{[##1][##2]}{##3}% +%D {do #1 something #2 with #3 arg} +%D \stoptyping +%D +%D which becomes: +%D +%D \starttyping +%D \def\somecommand[#1][#2]\startspecifier#3\stopspecifier% +%D {do #1 something #2 with #3 arg} +%D \stoptyping +%D +%D We will see some real applications of this command in the +%D core modules. + +\def\definestartstopcommand#1#2#3#4% can be done with \expanded ot better, toks + {\def\!stringa{#3}% % but let's keep this unused one crappy + \def\!stringb{\e!start#2}% + \def\!stringc{#4}% + \def\!stringd{\e!stop#2}% + \@EA\@EA\@EA\@EA\@EA\@EA\@EA\@EA\@EA\@EA\@EA\@EA\@EA\@EA\@EA + \def\@EA\@EA\@EA\@EA\@EA\@EA\@EA\@EA\@EA\@EA\@EA\@EA\@EA\@EA\@EA + #1\@EA\@EA\@EA\@EA\@EA\@EA\@EA + \!stringa\@EA\@EA\@EA + \csname\@EA\@EA\@EA\!stringb\@EA\@EA\@EA\endcsname\@EA + \!stringc + \csname\!stringd\endcsname} + +%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 +%D where \type{\ineedONEargument} takes one and the others +%D two and three arguments. These macro's were first needed in +%D \PPCHTEX. +%D +%D \starttyping +%D \def\dogetgroupargument#1#2% redefined in mult-ini +%D {\def\nextnextargument% +%D {\ifx\nextargument\bgroup +%D \let\expectedarguments\noexpectedarguments +%D \def\nextargument{#1\dodogetargument}% +%D %\else\ifx\nextargument\lineending % this can be an option +%D % \def\nextargument{\begingroup\def\\ {\endgroup\dogetgroupargument#1#2}\\}% +%D %\else\ifx\nextargument\blankspace % but it may never be default +%D % \def\nextargument{\begingroup\def\\ {\endgroup\dogetgroupargument#1#2}\\}% +%D \else +%D \ifnum\expectedarguments>\noexpectedarguments +%D \writestatus +%D {setup} +%D {\the\expectedarguments\space argument(s) expected +%D in line \the\inputlineno\space}% +%D \fi +%D \let\expectedarguments\noexpectedarguments +%D \def\nextargument{#2\dodogetargument{}}% +%D \fi%\fi\fi % so let's get rid of it +%D \nextargument}% +%D \futurelet\nextargument\nextnextargument} +%D \stoptyping +%D +%D In order to catch \type {\nextargument}'s that expand to +%D \type {\if} and friends, in practice we will use a +%D slightly more complicated macro. + +\newtoks \everyrobusttest + +\everyrobusttest + {\let\if \relax + \let\ifcat \relax + \let\ifnum \relax + \let\ifdim \relax + \let\ifodd \relax + \let\ifvmode \relax + \let\ifhmode \relax + \let\ifmmode \relax + \let\ifinner \relax + \let\ifvoid \relax + \let\ifhbox \relax + \let\ifvbox \relax + \let\ifx \relax + \let\ifeof \relax + \let\iftrue \relax + \let\iffalse \relax + \let\ifcase \relax + \let\ifdefined \relax + \let\ifcsname \relax + \let\iffontchar \relax + \let\ifincsname \relax + \let\ifprimitive\relax + \let\ifabsnum \relax + \let\ifabsdim \relax + \let\else \relax + \let\or \relax + \let\fi \relax} + +\def\beginrobusttest + {\begingroup + \the\everyrobusttest} + +\let\endrobusttest\endgroup + +%D We can add additional definitions later when we have defined +%D \type {\appendtoks}. + +\def \permitspacesbetweengroups{\chardef\@@permitspacesbetweengroups=0 } +\def\dontpermitspacesbetweengroups{\chardef\@@permitspacesbetweengroups=1 } + +\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% + {\let\dogroupargumentyes#1% + \let\dogroupargumentnop#2% + \beginrobusttest\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 + +\ifx\writestring\undefined + + \newtoks\everywritestring + + \def\writedirect {\immediate\write\statuswrite} + \def\writeline {\writedirect{}} + \def\writestring#1{\begingroup\the\everywritestring\writedirect{#1}\endgroup} + +\fi + +%D First we present the normal \TEX\ variant, later we will +%D show the \ETEX-way. + + +\beginTEX + + \newcount\statuscounter + + \def\dosplitstatus#1% + {\advance\statuscounter \minusone + \ifcase\statuscounter + \expandafter\nosplitstatus + \else + \scratchtoks\@EA{\the\scratchtoks#1}% + \expandafter\dosplitstatus + \fi} + + \def\nosplitstatus#1\end + {} + + \def\writestatus#1#2% + {\begingroup + \scratchtoks\emptytoks + \statuscounter\statuswidth + \expandafter\dosplitstatus#1% + \space\space\space\space\space\space\space + \space\space\space\space\space\space\space + \space\space\space\space\space\space\end + \@EA\writestring\@EA{\the\scratchtoks\space:\space#2}% + \endgroup} + +\endTEX + +%D Because we're grouped, we could have initialized at forehand: +%D +%D \starttyping +%D \statuscounter\statuswidth +%D \stoptyping +%D +%D The next implementation saves only some 10 words of format +%D memory, but we hardly gain any speed. +%D +%D \starttyping +%D \def\dosplitstatus#1#2#3#4#5#6#7#8#9% +%D {#1#2#3#4#5#6#7#8#9\dodosplitstatus} +%D +%D \def\dodosplitstatus#1#2#3#4#5#6\end +%D {#1#2#3#4#5} +%D +%D \def\writestatus#1#2% +%D {\writestring +%D {\expandafter\dosplitstatus#1% +%D \space\space\space\space\space +%D \space\space\space\space\space +%D \space\space\space\space\space\end +%D \space:\space#2}} +%D \stoptyping + +%D Okay then, more obscure but slightly faster: no split grabs +%D the do split part and skipping the else branch has to happen +%D anyway, so: + +\beginTEX + + \def\dosplitstatus#1% + {\advance\statuscounter \minusone + \ifcase\statuscounter + \expandafter\nosplitstatus + \fi + \scratchtoks\@EA{\the\scratchtoks#1}% + \dosplitstatus} + +\endTEX + +%D The next (\ETEX\ specific) variant is twice as fast in 5/40 +%D situations, only gains some speed when multiple runs of large docs +%D are done; fully expandable, no statuscounter needed, no restore (due +%D to grouping) needed etc. + +\beginETEX \numexpr + + \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 + {} + +\endETEX + +%D \macros +%D {emptytoks} +%D +%D For this we need an empty token register, analogous +%D to \type {\empty}. + +\newtoks\emptytoks + +%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} + +%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\normalwritestatus\undefined + % for use within latex + \ifx\writestatus\undefined + \def\writestatus#1#2{\immediate\write16{#1 : #2}} + \fi +\else + \let\writestatus\normalwritestatus +\fi + +\def\writebanner{\writestring} + +\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{!}. + +\protect \endinput diff --git a/tex/context/base/syst-ini.tex b/tex/context/base/syst-ini.tex new file mode 100644 index 000000000..7c9d72127 --- /dev/null +++ b/tex/context/base/syst-ini.tex @@ -0,0 +1,888 @@ +%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 % beware, we use index 125 at the lua end +\countdef \maxcountervalue = 126 \maxcountervalue = "7FFFFFFF % beware, we use index 126 at the lua end +\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 +\newdimen\scaledpoint \scaledpoint = 1sp +\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. + +%D As we now have catc-* files, we also have more readable 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 {\currentgrouptype}. + +\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}. The \type +%D {\lastnodetype} primitive is \ETEX\ compliant. The valid range is +%D still -1 .. 15 and glyph nodes have number 0 (used to be char +%D node) and ligature nodes are mapped to 7. That way macro packages +%D can use the same symbolic names as in traditional \ETEX. Keep in +%D mind that the internal node numbers are different and that there +%D are more node types that 15. + +\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 \type {\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 + \ifdefined\pdfinclusioncopyfonts\else \newcount\pdfinclusioncopyfonts \fi \pdfinclusioncopyfonts\plusone + + \def\nopdfcompression {\pdfobjcompresslevel\zerocount \pdfcompresslevel\zerocount} + \def\maximumpdfcompression{\pdfobjcompresslevel\plusnine \pdfcompresslevel\plusnine } + \def\normalpdfcompression {\pdfobjcompresslevel\plusthree \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-ltx.tex b/tex/context/base/syst-ltx.tex new file mode 100644 index 000000000..ae89ff25b --- /dev/null +++ b/tex/context/base/syst-ltx.tex @@ -0,0 +1,56 @@ +%D \module +%D [ file=syst-ltx, +%D version=2009.10.13, +%D title=\CONTEXT\ System Macros, +%D subtitle=General, +%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 {newcommand} +%D +%D This module replaces \type {t-bibltx} and implements the +%D \LATEX\ newcommand (sort of). This command is not to be +%D used directly but only is there for the occasional +%D \BIBTEX\ file that uses it. +%D +%D \starttyping +%D \newcommand\oeps {oeps} +%D \newcommand\oeps[6] {oeps[#1]#6} +%D \newcommand\oeps[6][whatever]{oeps[#1]#6} +%D \stoptyping + +\unprotect + +\def\newcommand#1% + {\dotripleempty\donewcommand[#1]} + +\def\donewcommand + {\ifthirdargument + \expandafter\donewcommandtwo + \else\ifsecondargument + \expandafter\expandafter\expandafter\donewcommandone + \else + \expandafter\expandafter\expandafter\donewcommandzero + \fi\fi} + +\def\donewcommandzero[#1][#2][#3]% + {\long\def#1} + +\def\donewcommandone[#1][#2][#3]% + {\scratchtoks{\long\def#1}% + \dorecurse{#2}{\scratchtoks\expandafter{\the\scratchtoks######1}}% + \the\scratchtoks} + +\def\donewcommandtwo[#1][#2][#3]% + {\long\def#1{\doifnextcharelse[{\getvalue{>>\string#1>>}}{\getvalue{>>\string#1>>}[#3]}}% + \scratchtoks{\long\setvalue{>>\string#1>>}[##1]}% + \dostepwiserecurse{2}{#2}{1}{\scratchtoks\expandafter{\the\scratchtoks######1}}% + \the\scratchtoks} + +\protect \endinput diff --git a/tex/context/base/syst-lua.lua b/tex/context/base/syst-lua.lua new file mode 100644 index 000000000..640282953 --- /dev/null +++ b/tex/context/base/syst-lua.lua @@ -0,0 +1,109 @@ +if not modules then modules = { } end modules ['syst-lua'] = { + version = 1.001, + comment = "companion to syst-lua.mkiv", + 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, find = string.format, string.find +local lpegmatch = lpeg.match + +local ctxcatcodes = tex.ctxcatcodes + +commands = commands or { } cs = commands -- shorter + +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.writedebug(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.report(s,t,...) + commands.writestatus("!"..s,format(t,...)) +end + +local function testcase(b) + if b then -- faster with if than with expression + texsprint(ctxcatcodes,"\\firstoftwoarguments") + else + texsprint(ctxcatcodes,"\\secondoftwoarguments") + end +end + +commands.testcase = testcase +commands.doifelse = testcase + +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 + +function commands.boolcase(b) + if b then texwrite(1) else texwrite(0) end +end + +function commands.doifelsespaces(str) + return commands.doifelse(find(str,"^ +$")) +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 = lpegmatch(s,a) h[a] = ha end + if not hb then hb = lpegmatch(s,b) h[b] = hb end + for i=1,#ha do + for j=1,#hb do + if ha[i] == hb[j] then + return testcase(true) + end + end + end + return testcase(false) +end + +function commands.doifinsetelse(a,b) + local hb = h[b] + if not hb then hb = lpegmatch(s,b) h[b] = hb end + for i=1,#hb do + if a == hb[i] then + return testcase(true) + end + end + return 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 + +local pattern = lpeg.patterns.validdimen + +function commands.doifdimenstringelse(str) + testcase(lpegmatch(pattern,str)) +end diff --git a/tex/context/base/syst-lua.mkiv b/tex/context/base/syst-lua.mkiv new file mode 100644 index 000000000..40cd9f756 --- /dev/null +++ b/tex/context/base/syst-lua.mkiv @@ -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-new.mkii b/tex/context/base/syst-new.mkii new file mode 100644 index 000000000..53ba18ffd --- /dev/null +++ b/tex/context/base/syst-new.mkii @@ -0,0 +1,868 @@ +%D \module +%D [ file=syst-new, +%D version=1997.01.03, +%D title=\CONTEXT\ Support 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. + +%D Code from this module will move. For instance to +%D syst-dat.tex (datastructures). + +\unprotect + +% 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 + {\ifundefined{#1}\@EA\let\csname#1\endcsname\empty\fi + \expanded{\addtocommalist{#2}\@EA\noexpand\csname#1\endcsname}} + +% faster, and looks okay + +\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% + {\defconvertedargument#2{#1}% + \@EA\edef\@EA#2\@EA{\@EA\unspaced\@EA{#2}}} + +\def\unspaceafter#1#2% + {\edef\ascii{\dounspaced#2\end}\@EA#1\@EA{\ascii}} + +% etex, much faster +% +% \def\unspaceargument#1\to#2% +% {\scratchcounter\catcode'32\catcode32=\@@ignore +% \scantokens{\edef#2{#1}}% +% \catcode32=\scratchcounter} + +\def\unspaceafter#1#2% + {\edef\ascii{\dounspaced#2\end}\@EA#1\@EA{\ascii}} + +% sometimes handy: + +\def\doifhasspaceelse#1% + {\edef\!!stringa{#1}% + \expanded{\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\chardef\csname\@flg@#1\endcsname\zerocount} + +\def\resetflag#1% + {\@EA\dodoglobal\@EA\chardef\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] + {\@EAEAEA\def\@EA\csname\@EA#1\@EA#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\doifnonzeropositiveelse#1#2#3% +% {\bgroup +% \setbox\scratchbox=\hbox{\scratchcounter=0#1}% +% \ifdim\wd\scratchbox=\!!zeropoint\egroup#2\else\egroup#3\fi} +% +% \def\dodoifnonzeropositiveelse#1#2\end#3#4% +% {\egroup +% \ifx#1\relax#3\else#4\fi} +% +% \def\doifnonzeropositiveelse#1% +% {\bgroup +% \afterassignment\dodoifnonzeropositiveelse\scratchcounter=0#1\relax\empty\end} + +\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\zeropoint \!!plus \onepoint \!!minus \onepoint + \advance\scratchskip#1\relax % \relax is realy needed here + \expandafter\SPLITSKIP\the\scratchskip} + +{\catcode`\.=\@@other + \catcode`\p=\@@other + \catcode`\l=\@@other + \catcode`\u=\@@other + \catcode`\s=\@@other + \catcode`\m=\@@other + \catcode`\i=\@@other + \catcode`\n=\@@other + \catcode`\t=\@@other + \gdef\SPLITSKIP#1pt plus #2pt minus #3pt% + {\DOSPLITSKIP#1 #2 #3 }} + +% \def\DOSPLITSKIP#1 #2 #3 +% {\dimen0=#1pt\dimen2=#2pt\dimen4=#3pt +% \advance\dimen2 -\onepoint +% \advance\dimen4 -\onepoint} + +\def\DOSPLITSKIP#1 #2 #3 + {\dimen0=#1\onepoint + \dimen2=\dimexpr#2\onepoint-\onepoint\relax + \dimen4=\dimexpr#3\onepoint-\onepoint\relax} + +% \def\minimaxskip#1#2% +% {\splitskip#2\relax +% \scratchdimen=#2\relax +% #2=\scratchdimen +% \advance#2 by #1\relax} +% +% \def\maximizeskip% +% {\minimaxskip{-\dimen4}} +% +% \def\maximizeskip% +% {\minimaxskip{\dimen2}} +% +% \def\maximizespacing% +% {\maximizeskip\blankskipamount +% \maximizeskip\parskip +% \maximizeskip\ctxparskip +% \maximizeskip\baselineskip +% \maximizeskip\bigskipamount +% \maximizeskip\medskipamount +% \maximizeskip\smallskipamount} + +\newcount\modcounter + +%\def\DoMod #1by#2to#3% +% {\modcounter#1\divide\modcounter#2\multiply\modcounter#2% +% #3#1\advance#3 -\modcounter} +% +%\def\DoDiv #1by#2to#3% +% {#3#1\divide#3 #2\relax} + +\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} + +%D Standaard kan een spatie (zoals ~) uitrekken. Dit is in +%D overzichten niet altijd de bedoeling, vandaar: + +% \def\fixedspace{\hskip\interwordspace\relax} + +%\def\ExpandSecondAfter#1#2#3% +% {\!!toksa={#2}% +% \edef\!!stringa{#3}% +% \edef\expanded% +% {\noexpand#1{\the\!!toksa}{\!!stringa}}% +% \expanded} +% +%\def\ExpandThirdAfter#1#2#3#4% +% {\!!toksa={#2}% +% \!!toksb={#3}% +% \edef\!!stringa{#4}% +% \edef\expanded% +% {\noexpand#1{\the\!!toksa}{\the\!!toksb}{\!!stringa}}% +% \expanded} + +%\def\indirect#1#2#3% +% {\@EA#1\@EA#2\@EA{\@EA#3\csname\s!do\string#2\endcsname}% +% \@EA#1\csname\s!do\string#2\endcsname} +% +%\def\doubleemptied#1#2#3% +% {\indirect#1#2\dodoublempty} +% +%\indirect\def\stelietsin\dodoubleempty[#1][#2]% +% {...} +% +%\doubleemptied\def\stelietsin[#1][#2]% +% {...} + +% in mult-set +% +%\def\defaultsetup{def} +% +%\def\selectdefaultsetup#1#2% +% {\writestatus{setup}{choose #1 setupfile}% +% \bgroup +% \endlinechar=-1 +% \global\read16 to \usersetup +% \egroup +% \ifx\usersetup\empty +% \let\usersetup=\defaultsetup +% \fi +% \readfile{#2\usersetup}{}{}% +% \writestatus{setup}{loading #1 setupfile #2\usersetup}} + +% awaiting the definitive implementation + +\ifx\resettimer\undefined + \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}} + +% \edef\elapsedtime{\expandafter\withoutpt\the\dimexpr\elapsedtime\relax s}% +% \writestatus\m!systems{feature test done (\elapsedtime)}% + +\def\testfeatureonce#1#2% + {\let\wait\relax\testfeature{#1}{#2}\end} + +%D \macros +%D {adddimenregister,adddimenmacro} +%D +%D Instead of using numerous \type {\advance}'s, one can use +%D the next macros to add|/|subtract a series of dimensions +%D to a register or macro. +%D +%D \starttyping +%D \adddimenregister 10pt 5pt \paperwidth \to \somedimen +%D \adddimenmacro 10pt 5pt \paperwidth \to \bagger +%D \stoptyping + +% \newdimen\dimentoaddto + +% \def\adddimenregister#1\to#2% will be obsolete once full etex +% {\begingroup +% #2=\zeropoint +% \dimentoaddto\zeropoint +% \def\docommand% +% {\advance#2 \dimentoaddto +% \futurelet\next\dodocommand}% +% \def\dodocommand% +% {\ifx\next\relax +% \expanded{\endgroup#2=\the#2}% +% \else +% \@EA\afterassignment\@EA\docommand\@EA\dimentoaddto +% \fi}% +% \docommand#1\relax} + +% \def\adddimenmacro#1\to#2% +% {\adddimenregister#1\to\scratchdimen +% \edef#2{\the\scratchdimen}} + +%D \macros +%D {freezedimenmacro} +%D +%D This macro is use as: +%D +%D \starttyping +%D \freezedimenmacro\leftmargindistance +%D \stoptyping + +% \def\freezedimenmacro#1% +% {\scratchdimen#1\edef#1{\the\scratchdimen}} + +\def\freezedimenmacro#1% + {\edef#1{\the\dimexpr#1}} + +%D The next one is slower: +%D +%D \starttyping +%D \def\freezedimenmacro#1{\edef#1{\the\dimexpr(#1)}} +%D \stoptyping + +% \newcount\rawrecursecounter +% +% \def\rawrecurselevel{\the\rawrecursecounter}% +% +% \def\dorawrecurse#1#2% +% {\rawrecursecounter\plusone +% \let\oldrecurselevel\recurselevel +% \let\recurselevel\rawrecurselevel +% \def\dodorawrecurse +% {\ifnum\rawrecursecounter>#1\relax +% \let\recurselevel\oldrecurselevel +% \else +% #2\advance\rawrecursecounter \plusone +% \expandafter\dodorawrecurse +% \fi}% +% \dodorawrecurse} + +%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} + +\beginTEX + +\def\ifusage#1% + {\@EA\ifx\csname#1\endcsname\relax + \resetusage{#1}% + \fi + \csname#1\endcsname} + +\endTEX + +\beginETEX \ifcsname + +\def\ifusage#1% + {\ifcsname#1\endcsname\else + \resetusage{#1}% + \fi + \csname#1\endcsname} + +\endETEX + +%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\def\dowithstringed#1#2#3#4% " ' space +% {\if#4"\@EA#1\else\if#4'\@EAEAEA#2\else\@EAEAEA#3\fi\fi#4} +% +% \def\unstringed +% {\dowithstringed\unstringdouble\unstringsingle\unstringspaced} +% +% \long\def\unstringdouble"#1"{#1} +% \long\def\unstringsingle'#1'{#1} +% \long\def\unstringspaced #1 {#1} +% +% \def\grabstring +% {\dowithstringed\grabstringdouble\grabstringsingle\grabstringspaced} +% +% \def\dowithgrabbedstring#1% +% {\def\@@dowithgrabbedstring{#1}% +% \afterassignment\@@dowithgrabbedstring\grabstring} +% +% \long\def\grabstringdouble"#1"{\scratchtoks{#1}} +% \long\def\grabstringsingle'#1'{\scratchtoks{#1}} +% \long\def\grabstringspaced #1 {\scratchtoks{#1}} + +\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} + +% for Simon ; watch how we make them fully expandable (i.e. +% no \type {\relax}es) popping up + +\def\@do@the@number@#1\relax#2\end{#1} + +\def\@the@number@#1{\@EA\@do@the@number@\number#1\relax\end} + +\def\doifnum#1#2% + {\ifnum#1=\@the@number@{#2} % space needed + \expandafter\firstofoneargument + \else + \expandafter\gobbleoneargument + \fi} + +\def\doifnotnum#1#2% + {\ifnum#1=\@the@number@{#2} % space needed + \expandafter\gobbleoneargument + \else + \expandafter\firstofoneargument + \fi} + +\def\doifelsenum#1#2% + {\ifnum#1=\@the@number@{#2} % space needed + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +% \edef\xxxx{\doifnum{1}{2}{no}} \show \xxxx +% \edef\xxxx{\doifnum{2}{2}{yes}} \show \xxxx +% \scratchcounter0 \edef\xxxx{\doifnum{1}{\scratchcounter}{no}} \show \xxxx +% \scratchcounter1 \edef\xxxx{\doifnum{1}{\scratchcounter}{yes}} \show \xxxx + +\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]% + {\expanded{\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]% + {\expanded{\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]% + {\expanded{\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 + {\bgroup + \defconvertedcommand\ascii{#1}% + \global\let\globalascii\empty + \donefalse + \expandafter\handletokens\ascii\with\dostripstring + \egroup + \let#1\globalascii} + +\def\dostripstring#1% + {\ifx#1\blankspace + \donetrue + \else + \ifdone\ifx\globalascii\empty\else + \xdef\globalascii{\globalascii\space}% + \donefalse + \fi\fi + \xdef\globalascii{\globalascii#1}% + \fi} + +%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 + +\beginETEX \numexpr + +\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} + +\endETEX + +\beginTEX + +\def\uncompresslist[#1]% + {\def\uncompressedlist{#1}} + +\endTEX + +%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 + {\setbox\nointerferencebox\vbox + \bgroup} + +\def\stopnointerference + {\egroup + \setbox\nointerferencebox\emptybox} + +\protect \endinput + + +% \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} diff --git a/tex/context/base/syst-pln.tex b/tex/context/base/syst-pln.tex new file mode 100644 index 000000000..f2b6129ff --- /dev/null +++ b/tex/context/base/syst-pln.tex @@ -0,0 +1,118 @@ +%D \module +%D [ file=syst-pln, +%D version=2001.11.16, % 1999.03.17, % an oldie: 1995.10.10 +%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. + +\unprotect + +%D This module set a couple of variables to the plain \TEX\ +%D values. Later they might be overloaded. + +%D Build||in numeric variables. + +\adjdemerits = 10000 +\binoppenalty = 700 +\brokenpenalty = 100 +\clubpenalty = 150 +%day = 0 +\defaulthyphenchar = `\- +\defaultskewchar = -1 +\delimiterfactor = 901 +\displaywidowpenalty = 50 +\doublehyphendemerits = 10000 +%endlinechar = `\^^M +\errorcontextlines = 5 +%escapechar = `\\ +\exhyphenpenalty = 50 +%fam = 0 +\finalhyphendemerits = 5000 +%floatingpenalty = 0 +%globaldefs = 0 +%hangafter = 1 +\hbadness = 1000 +%holdinginserts = 0 +\hyphenpenalty = 50 +%interlinepenalty = 0 +%language = 0 +\lefthyphenmin = 2 +\linepenalty = 10 +%looseness = 0 +%mag = 1000 +%maxdeadcycles = 25 +%month = 0 +%newlinechar = -1 % commented i.e. no plain value +%outputpenalty = 0 +%pausing = 0 +%postdisplaypenalty = 0 +\predisplaypenalty = 10000 +\pretolerance = 100 +\relpenalty = 500 +\righthyphenmin = 3 +\showboxbreadth = 5 +\showboxdepth = 3 +%time = 0 +\tolerance = 200 +%tracingcommands = 0 +\tracinglostchars = 1 +%tracingmacros = 0 +%tracingonline = 0 +%tracingoutput = 0 +%tracingpages = 0 +%tracingparagraphs = 0 +%tracingrestores = 0 +%tracingstats = 0 +\uchyph = 1 +\vbadness = 1000 +\widowpenalty = 150 +%year = 0 + +%D Build in dimension variables. + +\abovedisplayshortskip = 0pt plus 3pt +\abovedisplayskip = 12pt plus 3pt minus 9pt +%baselineskip = 0pt +\belowdisplayshortskip = 7pt plus 3pt minus 4pt +\belowdisplayskip = 12pt plus 3pt minus 9pt +\boxmaxdepth = \maxdimen +\delimitershortfall = 5pt +%displayindent = 0pt +%displaywidth = 0pt +%hangindent = 0pt +\hfuzz = 0.1pt +%hoffset = 0pt +\hsize = 6.5in +%leftskip = 0pt +%lineskip = 0pt +%lineskiplimit = 0pt +%mathsurround = 0pt +\maxdepth = 4pt +\medmuskip = 4mu plus 2mu minus 4mu +\nulldelimiterspace = 1.2pt +\overfullrule = 5pt +\parfillskip = 0pt plus 1fil +\parindent = 20pt +\parskip = 0pt plus 1pt +%predisplaysize = 0pt +%rightskip = 0pt +\scriptspace = 0.5pt +%spaceskip = 0pt +\splitmaxdepth = \maxdimen +\splittopskip = 10pt +%tabskip = 0pt +\thickmuskip = 5mu plus 5mu +\thinmuskip = 3mu +\topskip = 10pt +\vfuzz = 0.1pt +%voffset = 0pt +\vsize = 8.9in +%xspaceskip = 0pt + +\protect \endinput diff --git a/tex/context/base/syst-rtp.mkii b/tex/context/base/syst-rtp.mkii new file mode 100644 index 000000000..a1c6abe2e --- /dev/null +++ b/tex/context/base/syst-rtp.mkii @@ -0,0 +1,18 @@ +%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. + +\unprotect + +\def\executesystemcommand{\immediate\write18} + +\protect \endinput diff --git a/tex/context/base/syst-rtp.mkiv b/tex/context/base/syst-rtp.mkiv new file mode 100644 index 000000000..36ce8edb1 --- /dev/null +++ b/tex/context/base/syst-rtp.mkiv @@ -0,0 +1,18 @@ +%D \module +%D [ file=syst-rtp, +%D version=2006.10.13, +%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. + +\unprotect + +\def\executesystemcommand#1{\ctxlua{os.execute([[#1]])}} + +\protect \endinput diff --git a/tex/context/base/syst-str.mkii b/tex/context/base/syst-str.mkii new file mode 100644 index 000000000..3e6d043e3 --- /dev/null +++ b/tex/context/base/syst-str.mkii @@ -0,0 +1,124 @@ +%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. + +\unprotect + +%D We need a convenient way to change lccode vectors. + +\dostepwiserecurse{0}{255}{1} + {\@EA\chardef\csname-\recurselevel\endcsname\recurselevel} + +\newtoks\withminorcharacters +\newtoks\withlowercharacters +\newtoks\withuppercharacters + +\dostepwiserecurse{0}{31}{1} + {\expanded + {\appendtoks\noexpand\withcharacter\csname-\recurselevel\endcsname + \noexpand\to\withminorcharacters}} + +\dostepwiserecurse{32}{127}{1} + {\expanded + {\appendtoks\noexpand\withcharacter\csname-\recurselevel\endcsname + \noexpand\to\withlowercharacters}} + +\dostepwiserecurse{128}{255}{1} + {\expanded + {\appendtoks\noexpand\withcharacter\csname-\recurselevel\endcsname + \noexpand\to\withuppercharacters}} + +\chardef\obeyedlccode=`. % so <32 and >127 chars become . + +%D \macros +%D {retainlccodes} +%D +%D One way of manipulating characters is changing the their +%D \type{\lccode} and applying \type{\lowcase}. An example of +%D this can be found in \type{spec-mis}. + +\def\setownlccode #1{\lccode#1#1} +\def\setobeyedlccode#1{\lccode#1\obeyedlccode} + +\def\obeylccodes + {\let\withcharacter\setownlccode + \the\withlowercharacters + \let\withcharacter\setobeyedlccode + \the\withminorcharacters + \the\withuppercharacters + \relax} + +\def\retainlccodes + {\let\withcharacter\setownlccode + \the\withlowercharacters + \the\withminorcharacters + \the\withuppercharacters + \relax} + +%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 + \edef\ascii{#1}% + \retainlccodes + \def\docommand##1{\lccode\expandafter`\csname##1\endcsname=\expandafter`\csname#3\endcsname}% + \handletokens#2\with\docommand + \lowercase\@EA{\@EA\xdef\@EA\globalascii\@EA{\ascii}}% + \egroup + \dodoglobal\let#1\globalascii} + +% \bgroup +% \catcode`\ =\@@other % needed in order to get it visible +% \lccode`\ =`\- +% \lowercase{\xdef\globalascii{aap noot}}% +% \egroup +% +% [\globalascii] {\tttf [\globalascii]} +% +% interesting: +% +% \setvalue{xxx}{oeps} +% \setvalue{test-test}{\getvalue{xxx}oeps} +% \bgroup\lccode`\ =`\-\lowercase{\egroup\csname test test\endcsname} +% +% \setvalue{test\string~test}{\getvalue{xxx}oeps} +% \bgroup\lccode`\ =`\~\lowercase{\egroup\csname test test\endcsname} +% +% \bgroup\catcode`\~=\@@letter\lowercase{\egroup\csname test~test\endcsname} + +\def\separatestring#1\to#2% + {\bgroup + \retainlccodes + \lccode `\ =`\,% + % when typesetting: \catcode`\ =\@@other + \edef\ascii{#1}% + \lowercase\@EA{\@EA\xdef\@EA\globalascii\@EA{\ascii}}% + \egroup + \let#2\globalascii} + +\def\unspacefilename#1\to#2% + {\bgroup + \def\obeyedspace{-}% + \sanitizefilename#1\to\ascii + \retainlccodes + \lccode `\ =`\-% + % when typesetting: \catcode`\ =\@@other + \lowercase\@EA{\@EA\xdef\@EA\globalascii\@EA{\ascii}}% + \egroup + \let#2\globalascii} + +\protect \endinput diff --git a/tex/context/base/syst-str.mkiv b/tex/context/base/syst-str.mkiv new file mode 100644 index 000000000..57d76dc03 --- /dev/null +++ b/tex/context/base/syst-str.mkiv @@ -0,0 +1,36 @@ +%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. + +\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")))}}} + +\def\separatestring#1\to#2% + {\dodoglobal\def#2{\ctxlua{tex.sprint((string.gsub(\!!bs#1\!!es,"\letterpercent s+",",")))}}} + +\def\unspacefilename#1\to#2% + {\dodoglobal\def#2{\ctxlua{tex.sprint((string.gsub(\!!bs#1\!!es,"\letterpercent s+","-")))}}} + +\protect \endinput diff --git a/tex/context/base/syst-tex.mkii b/tex/context/base/syst-tex.mkii new file mode 100644 index 000000000..a8aea2683 --- /dev/null +++ b/tex/context/base/syst-tex.mkii @@ -0,0 +1,314 @@ +%D \module +%D [ file=syst-tex, +%D version=1999.03.17, % an oldie: 1995.10.10 +%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 file is used by mptopdf. + +%D We've build \CONTEXT\ on top of \PLAIN\ \TEX. Because we +%D want to make the format file as independant as possible of +%D machine dependant font encodings, we have to bypass the +%D loading of fonts. +%D +%D Let's start at the beginning. Because \PLAIN\ is not yet +%D loaded we have to define some \CATCODES\ ourselves. + +\catcode`\{=1 % left brace is begin-group character +\catcode`\}=2 % right brace is end-group character +\catcode`\#=6 % hash mark is macro parameter character +\catcode`\^=7 % circumflex is for superscripts + +%D To prevent all kind of end||of||file problems, for the +%D moment we simply ignore the Control~Z token. + +\catcode`\^^Z=9 + +%D We are going to report to the user what we are skipping. + +\def\skipmessage#1{\immediate\write16{skipping #1 in plain}} + +%D We want to be able to use the \type{\newsomething} +%D declarations not only on the \type{\outer} level. This can +%D be done by redefining \type{\outer} so we have to save its +%D original meaning. + +\let\normalouter = \outer +\let\outer = \relax + +%D We also want to postpone the loading of hyphenation patters, +%D so we redefine and therefore save \type{\input}. + +\let\normalinput = \input +\def\input #1 {\skipmessage{\string\input}} + +%D Finaly are going to we redefine some font specification +%D commands and that's why we save them too. The redefinitions +%D are straightforward because the macros have to do nothing +%D but skipping. + +\let\normalskewchar = \skewchar +\def\skewchar #1=#2 {\skipmessage{\string\skewchar}} + +\let\normaltextfont = \textfont +\let\normalscriptfont = \scriptfont +\let\normalscriptscriptfont = \scriptscriptfont + +\def\textfont #1=#2{\skipmessage{\string\textfont}} +\def\scriptfont #1=#2{\skipmessage{\string\scriptfont}} +\def\scriptscriptfont #1=#2{\skipmessage{\string\scriptscriptfont}} + +%D The redefinition of \type{\font} is a bit more complicated, +%D because in version 3.14159 a scaled specification was +%D introduced. + +\let\normalfont = \font + +\def\skipscaled scaled #1 {} + +\long\def\font#1=#2 #3% + {\ifx#3s% + \skipmessage{scaled \string\font}% + \let\next\skipscaled + \else + \skipmessage{\string\font}% + \let\next\relax + \fi + \next#3} + +% or: +% +% \long\def\font#1=#2 #3% +% {\ifx#3s% +% \skipmessage{scaled \string\font}% +% \expandafter\skipscaled +% \else +% \skipmessage{\string\font}% +% \fi +% #3} + +%D Relaxing some font switching macros is needed because we +%D don't want any error messages during loading. These +%D unharmfull messages could be ingored. +%D +%D The next substitution is needed for determining +%D \type{\p@renwd} in the macro \type{\bordermatrix}. + +\def\tenex#1% + {\skipmessage{used \string\tenex}\hskip8.75002pt} + +%D We need to define \type{\tenrm} for switching to +%D \type{\rm}. + +\def\tenrm% + {\skipmessage{\string\tenrm}} + +%D In \CONTEXT\ all \PLAIN\ \TEX\ fonts are available, just +%D like \type{\p@renwd}. We only postpone loading them until +%D they are actually needed. + +%D By bypassing fonts, some definitions become less valid so +%D we have to redefine them afterwards. +%D +%D \starttyping +%D \let\normalbordermatrix=\bordermatrix +%D +%D \def\bordermatrix% +%D {\bgroup +%D \setbox0=\hbox{\getvalue{\textface\c!mm\c!ex}B}% +%D \global\p@renwd=\wd0\relax +%D \egroup +%D \normalbordermatrix} +%D \stoptyping + +%D Now we are ready for loading \PLAIN\ \TEX. Of couse we use +%D \type{\normalinput} and not \type{\input}. + +\normalinput plain.tex \let\normalfmtversion\fmtversion + +%D We have to take care of unwanted \PDFTEX\ +%D initializations. We just want to default to \DVI\ output. + +\ifx\pdftexversion\undefined + \chardef\pdfoutput=0 +\else + \pdfoutput=0 +\fi + +%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 + +\egroup + +% \ifx\eTeXversion\undefined +% \long\def\onlyTEX #1{#1} +% \long\def\onlyETEX#1{} +% \else +% \long\def\only TEX#1{} +% \long\def\onlyETEX#1{#1} +% \fi + +%D Well, this redefintion of \type {\input} fails on \ETEX, +%D because of some \type {\cs\fi} constructs. So now we use: + +% \beginETEX etex.src etexdefs.lib +% +% \def\input#1% +% {\bgroup +% \skipmessage{\string\input}% +% \expandafter\ifx\expandafter#1\csname l@ngdefnfile\endcsname +% \let\input\egroup +% \else +% \def\input##1 {\egroup}% +% \fi +% \input} +% +% \normalinput etex.src \relax +% \normalinput etexdefs.lib \relax +% +% \let\fmtversion\normalfmtversion +% +% \savinghyphcodes=1 +% +% \endETEX +% +% \ifx\normalprotected \undefined \let\normalprotected \protected \fi +% \ifx\normalunexpanded\undefined \let\normalunexpanded\unexpanded \fi +% \ifx\normalexpanded \undefined \let\normalexpanded \expanded \fi + +\beginETEX \savinghyphcodes + + \savinghyphcodes=1 + +\endETEX + +%D We restore some redefined primitives to their old meaning. + +\let\font = \normalfont +\let\skewchar = \normalskewchar +\let\textfont = \normaltextfont +\let\scriptfont = \normalscriptfont +\let\scriptscriptfont = \normalscriptscriptfont +\let\input = \normalinput +\let\outer = \normalouter + +%D We reset some of the used auxiliary macro's to +%D \type{\undefined}. One never knows what testing on them is +%D done elsewhere. + +\let\skipmessage = \undefined +\let\skipscaled = \undefined +\let\normalfont = \undefined +\let\normalskewchar = \undefined +\let\normaltextfont = \undefined +\let\normalscriptfont = \undefined +\let\normalscriptscriptfont = \undefined + +% \let\normalinput = \undefined +% \let\normalouter = \undefined + +%D We want a bit more statistics and some less logging info +%D in the \type{log} file. + +\def\wlog#1{} + +% \let\normalwlog\wlog +% +% \def\wlog#1{\normalwlog{system (\string\wlog) : #1}} + +%D To prevent clashes, we slightly redefine the phantom +%D macros: we let them hide their behaviour by grouping. + +\catcode`@=11 + +%D Somehow this one does not work ok in math mode: + +\def\ph@nt% + {\bgroup + \ifmmode + \expandafter\mathpalette\expandafter\mathph@nt + \else + \expandafter\makeph@nt + \fi} + +\def\finph@nt% + {\setbox\tw@\null + \ifv@ \ht\tw@\ht\z@ \dp\tw@\dp\z@ \fi + \ifh@ \wd\tw@\wd\z@ \fi + \box\tw@ + \egroup} + +%D But this one does work. + +\def\ph@nt% + {\ifmmode + \expandafter\mathpalette\expandafter\mathph@nt + \else + \bgroup\expandafter\makeph@nt + \fi} + +\def\finph@nt% + {\setbox\tw@\null + \ifv@ \ht\tw@\ht\z@ \dp\tw@\dp\z@ \fi + \ifh@ \wd\tw@\wd\z@ \fi + \box\tw@ + \ifmmode\else\egroup\fi} + +\catcode`@=12 + +%D Just for tracing purposes wet set: + +\tracingstats=1 + +%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} + +\endinput diff --git a/tex/context/base/tabl-com.mkii b/tex/context/base/tabl-com.mkii new file mode 100644 index 000000000..892905f6c --- /dev/null +++ b/tex/context/base/tabl-com.mkii @@ -0,0 +1,21 @@ +%D \module +%D [ file=tabl-com, +%D version=2009.08.22, +%D title=\CONTEXT\ Table Macros, +%D subtitle=Common Code, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Common Code} + +\unprotect + +\let\NC\relax +\let\NR\relax + +\protect \endinput diff --git a/tex/context/base/tabl-com.mkiv b/tex/context/base/tabl-com.mkiv new file mode 100644 index 000000000..892905f6c --- /dev/null +++ b/tex/context/base/tabl-com.mkiv @@ -0,0 +1,21 @@ +%D \module +%D [ file=tabl-com, +%D version=2009.08.22, +%D title=\CONTEXT\ Table Macros, +%D subtitle=Common Code, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 / Common Code} + +\unprotect + +\let\NC\relax +\let\NR\relax + +\protect \endinput diff --git a/tex/context/base/tabl-ltb.mkii b/tex/context/base/tabl-ltb.mkii new file mode 100644 index 000000000..095e30e2b --- /dev/null +++ b/tex/context/base/tabl-ltb.mkii @@ -0,0 +1,866 @@ +%D \module +%D [ file=tabl-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} + +% will go away: + +\def\processlinetableXMLfile#1% + {\bgroup + \let\startlinetable\donothing + \let\stoplinetable \donothing + \startlinetableanalysis\processXMLfile{#1}\stoplinetableanalysis + \startlinetablerun \processXMLfile{#1}\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-ltb.mkiv b/tex/context/base/tabl-ltb.mkiv new file mode 100644 index 000000000..7d3fab0df --- /dev/null +++ b/tex/context/base/tabl-ltb.mkiv @@ -0,0 +1,866 @@ +%D \module +%D [ file=tabl-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 + +\unexpanded\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}}} + +\unexpanded\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} + +% \unexpanded\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 + +\unexpanded\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} + +% \unexpanded\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} + +\unexpanded\def\startlinetablepart + {\global\linetablesubcol\zerocount + \setbox\scratchbox\hbox\bgroup + \doconvertfont{\linetablerparameter\c!style}% + \startcolor[\linetablerparameter\c!color]% + \ignorespaces} + +\unexpanded\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) + +\unexpanded\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} + +\unexpanded\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} + +\unexpanded\def\startlinetable + {\startlinetablerun} + +\unexpanded\def\stoplinetable + {\stoplinetablerun} + +\unexpanded\def\startlinetableanalysis + {\bgroup + \linetableprerolltrue + \trialtypesettingtrue + \startlinetablerun} + +\unexpanded\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\unexpanded\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} + +% will go away: + +\def\processlinetableXMLfile#1% + {\bgroup + \let\startlinetable\donothing + \let\stoplinetable \donothing + \startlinetableanalysis\processXMLfile{#1}\stoplinetableanalysis + \startlinetablerun \processXMLfile{#1}\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..0bfcc20c6 --- /dev/null +++ b/tex/context/base/tabl-ntb.mkii @@ -0,0 +1,1586 @@ +%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\dimen2>\zeropoint % see natural-003 + \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 + \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..b24eaa85d --- /dev/null +++ b/tex/context/base/tabl-ntb.mkiv @@ -0,0 +1,1622 @@ +%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\iftightTBLrowspan \tightTBLrowspantrue + +\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 + +%D By default rowspans are tight but you can change that: +%D +%D \startbuffer +%D \bTABLE +%D \bTR[height=20pt] \bTH 1. col \eTH \bTH 2. col \eTH \eTR +%D \bTR[height=20pt] \bTD 1 row in 1. col \eTD \bTD[nr=2] 2 rows in 2. col \eTD \eTR +%D \bTR[height=20pt] \bTD[nr=2] 2 rows in 1. col\eTD \eTR +%D \bTR[height=20pt] \bTD[nr=3] 3 rows in 2. col \eTD \eTR +%D \bTR[height=20pt] \bTD 1 row in 1. col \eTD \eTR +%D \bTR[height=20pt] \bTD 1 row in 1. col \eTD \eTR +%D \eTABLE +%D +%D \bTABLE +%D \bTR[height=20pt] \bTH 2. col \eTH \bTH 1. col \eTH \eTR +%D \bTR[height=20pt] \bTD[nr=2] 2 rows in 2. col \eTD \bTD 1 row in 1. col \eTD \eTR +%D \bTR[height=20pt] \bTD[nr=2] 2 rows in 1. col\eTD \eTR +%D \bTR[height=20pt] \bTD[nr=3] 3 rows in 2. col \eTD \eTR +%D \bTR[height=20pt] \bTD 1 row in 1. col \eTD \eTR +%D \bTR[height=20pt] \bTD 1 row in 1. col \eTD \eTR +%D \eTABLE +%D \stopbuffer +%D +%D \typebuffer +%D +%D \getbuffer +%D +%D With \type {\tightTBLrowspanfalse} we get: +%D +%D \start \tightTBLrowspanfalse \getbuffer \stop + +\unexpanded\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% + {\unexpanded\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]% + \ifx\tbltblsetups\empty\else + \doprocesslocalsetups\tbltblsetups + \fi + \hsize\tbltbltextwidth + \processaction + [\tbltblsplit] + [ \v!yes=>\enableTBLbreaktrue, + \v!repeat=>\enableTBLbreaktrue\multipleTBLheadstrue, + \v!auto=>\ifinsidesplitfloat\enableTBLbreaktrue\fi] + \processaction + [\tbltblheader] + [\v!repeat=>\multipleTBLheadstrue]% + \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 + % tracing + % \iftrue + % \blank \tttf + % \dorecurse\maximumrow + % {\row\recurselevel\relax + % \dorecurse\maximumcol + % {\col\recurselevel\relax + % [r=\the\row,c=\the\col,h=\the\dimexpr\gettblht\row\col,w=\the\dimexpr\gettblwd\row\col]}% + % \par}% + % \blank + % \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}% + % \iftrue + % \bgroup\tbox{\tttf[\number\tblrow]}\egroup + % \fi + \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\directgotobox{\box\scratchbox}[\!!stringa]}% to be checked + \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\dimen2>\zeropoint % new: test on natural-003 + \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 + \iftightTBLrowspan + \settblhei\xrowTBL{\the\dimen2}% + \fi + \fi\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 % todo: tableparameter etc + [\@@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!setups=, + \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 + +\unexpanded\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.mkii b/tex/context/base/tabl-nte.mkii new file mode 100644 index 000000000..cde64a033 --- /dev/null +++ b/tex/context/base/tabl-nte.mkii @@ -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-nte.mkiv b/tex/context/base/tabl-nte.mkiv new file mode 100644 index 000000000..cde64a033 --- /dev/null +++ b/tex/context/base/tabl-nte.mkiv @@ -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.mkii b/tex/context/base/tabl-pln.mkii new file mode 100644 index 000000000..39bb50f23 --- /dev/null +++ b/tex/context/base/tabl-pln.mkii @@ -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-pln.mkiv b/tex/context/base/tabl-pln.mkiv new file mode 100644 index 000000000..39bb50f23 --- /dev/null +++ b/tex/context/base/tabl-pln.mkiv @@ -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.mkii b/tex/context/base/tabl-tab.mkii new file mode 100644 index 000000000..e3bfca9c3 --- /dev/null +++ b/tex/context/base/tabl-tab.mkii @@ -0,0 +1,2515 @@ +%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. + +% \starttable[|||] +% \HL +% \VL test \VS test \VL \FR +% \VL test \VD test \VL \MR +% \VL test \VT test \VL \LR +% \HL +% \stoptable + +% 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-tab.mkiv b/tex/context/base/tabl-tab.mkiv new file mode 100644 index 000000000..d926dab98 --- /dev/null +++ b/tex/context/base/tabl-tab.mkiv @@ -0,0 +1,2516 @@ +%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. + +% \starttable[|||] +% \HL +% \VL test \VS test \VL \FR +% \VL test \VD test \VL \MR +% \VL test \VT test \VL \LR +% \HL +% \stoptable + +% 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{\startcolor[#1]} a{\stopcolor}} + +%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 + +\unexpanded\def\starttable + {\bgroup + \let\stoptable\dostoptable + \doif\@@tisplit\v!auto + {\ifinsidesplitfloat\let\@@tisplit\v!yes\fi}% + \doifinsetelse\@@tisplit{\v!yes,\v!repeat} + {\unexpanded\def\stoptable{\stoptables\egroup}% + \starttables} + {\doifelsenothing\@@tiframe + {\ifinsidefloat\else\startbaselinecorrection\fi} + {\startframedcontent[\@@tiframe]}% + \postponenotes + \firststagestartTABLE}} + +% We cannot define \unexpanded\def\dostoptable a ssomehow lookahead +% in alignments fail then, so we relax it and define it locally. + +\let\stoptabel\relax + +\def\dostoptable + {\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: + +\unexpanded\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 + +\unexpanded\def\starttables + {\bgroup + \let\stoptables\dostoptables + \splittablestrue + \doifelse\@@tisplit\v!repeat + {\settrue \tablerepeathead\settrue \tablerepeattail} + {\setfalse\tablerepeathead\setfalse\tablerepeattail}% + \flushnotes + \setbox\tablecontentbox\vbox\bgroup + \forgetall + \global\TABLEinbreakfalse + \firststagestartTABLE} + +\let\stoptables\relax % needed for \noalign + +\def\dostoptables + {\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 + {\long\def\csname\e!start\v!tablehead\endcsname##1\csname\e!stop\v!tablehead\endcsname% + {\noexpand\setTABLEhead##1\noexpand\end}} + +\expanded + {\long\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 + +\long\def\dosetTABLEhead[#1][#2]#3\end{\setvalue{@@TABLEhead#1}{\TABLEnoalign{\global\settrue\someTABLEhead}#3}} +\long\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} + +\unexpanded\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 + +% \unexpanded\def\defineTABLErules +% {\let\VL\TableVL +% \let\VC\TableVC +% \let\HL\TableHL +% \let\HC\TableHC} + +\unexpanded\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}{\startcolor[#1]}% + \global\setvalue{eVC\the\currentTABLEcolumn}{\stopcolor}% + \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{\startcolor[#1]}% + \gdef\stopHCcommand {\stopcolor}}% + \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 + +\unexpanded\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 + +% \unexpanded\def\defineTABLEdivisions +% {\global\TABLEdivisionfalse % in start +% \let\DL\TableDL +% \let\DC\TableDC +% \let\DV\TableDV +% \let\VD\TableDV +% \let\DR\TableDR} + +\unexpanded\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 + +\unexpanded\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\startcolor \stopcolor [#1,\lastTABLEc,,]} + +\gdef\docomplexTableRASTER[#1]% + {\dodocomplexTableGL\startraster\stopraster[#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} + +\unexpanded\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}} + +\unexpanded\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. + +\unexpanded\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 + {\unexpanded\def\startglobalTABLEcolor{\startcolor[\@@tirulecolor]}% + \unexpanded\def\stopglobalTABLEcolor {\stopcolor}}% + % 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\strutheightfactor} + {\let\StrutHeightFactor\@@tiheight}% + \doifelse\@@tidepth\v!strut + {\let\StrutDepthFactor\strutdepthfactor} + {\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.mkii b/tex/context/base/tabl-tbl.mkii new file mode 100644 index 000000000..09fa4105c --- /dev/null +++ b/tex/context/base/tabl-tbl.mkii @@ -0,0 +1,1440 @@ +%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 % overloaded in anch-pgr + {\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 + +\newtoks\everyaftertabulaterow + +\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 + {\the\everyaftertabulaterow}% + \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 + \vskip1\topskip\allowbreak\vskip-1\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-tbl.mkiv b/tex/context/base/tabl-tbl.mkiv new file mode 100644 index 000000000..400d8a659 --- /dev/null +++ b/tex/context/base/tabl-tbl.mkiv @@ -0,0 +1,1516 @@ +%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 + +% todo: \aligntab \alignmark (after 0.60 is out) + +\unprotect + +%D I can probably reimplement this using a \LUA||\TEX\ combination +%D but it does not pay of in development time. If I need something +%D else I will write it from scratch anyway. + +% 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 \tabulatexwidth +\newdimen \tabulatewidth +\newdimen \tabulateunit +\newdimen \tabulatemaxpheight + +\newbox \tabulatebox + +% [|lg{.}|] => \NG 12.34 \NC + +\gdef\handletabulatecharalign#1 % space delimited ! + {\edef\alignmentclass{\the\tabulatecolumn}% + \edef\alignmentcharacter{\csname\??tt:a:\the\tabulatecolumn\endcsname}% + \ifcase\tabulatepass\or + \setfirstpasscharacteralign\checkalignment{#1}% + \fi % force hsize + \setsecondpasscharacteralign\checkalignment{#1}} + +\def\noftabcolumns{16} + +\def\tablebox#1% + {\csname\??tt:b:\number#1\endcsname} + +\def\initializetablebox#1% also used elsewhere + {\ifcsname\??tt:b:\number#1\endcsname + \global\setbox\csname\??tt:b:\number#1\endcsname\emptybox + \else + \expandafter\newbox\csname\??tt:b:\number#1\endcsname + \fi} + +\def\initializetableboxes#1% + {\scratchcounter#1\relax + \doinitializetableboxes} + +\def\doinitializetableboxes + {\ifnum\scratchcounter>\zerocount + \initializetablebox\scratchcounter + \advance\scratchcounter\minusone + \expandafter\doinitializetableboxes + \fi} + +\initializetableboxes\noftabcolumns + +\def\dodotabulatenobreak + {\nobreak + \iftracetabulate + \red\hrule\!!height.5\linewidth\!!depth.5\linewidth + \par + \kern-\linewidth + \nobreak + \fi} + +\def\dotabulatenobreak + {\noalign{\dodotabulatenobreak}} + +\unexpanded\def\notabulatehook + {} + +\unexpanded\def\checktabulatehook + {\ifnum\tabulatetype<\plustwo + \glet\tabulatehook\notabulatehook + \else + \glet\tabulatehook\dotabulatehook + \fi} + +\unexpanded\def\checktabulatesetups + {\csname\??tt:s:\the\tabulatecolumn\endcsname} + +\let\pretabrule \donothing +\let\posttabrule\donothing + +% 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 + +% \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}% +% % +% \@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{\??tt:a:\tabulatecolumns} +% %\doifdefinedelse{\??tt:a:\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} +% +% speedup: + +% is grouping really needed here? + +\unexpanded\def\beforetabulateentry{\ignorespaces\tabulatehook} +\unexpanded\def\aftertabulateentry {\unskip\unskip\ifmmode\else\endgraf\fi} + +\unexpanded\def\beginreshapedtabulatepar + {\dowithnextbox + {\ctxlua{commands.doreshapeframedbox(\number\nextbox)}\ifvmode\unvbox\else\box\fi\nextbox} + \vbox\bgroup} + +\let\endreshapedtabulatepar\egroup + +\def\dodosettabulatepreamble#1#2% only makes sense for many tabulates + {\normalexpanded{\!!toksa{\the\!!toksa + &\hskip\pretabskip\noexpand\pretabrule##&% + % \ignorespaces + \global\tabulatecolumn\the\tabulatecolumns\relax + \checktabulatesetups % unexpandable + \checktabulatehook % unexpandable + \ifzeropt\tabulatewidth + \ifcase\tabulatemodus\else + \noexpand\autotabulatetrue + \fi + \else + \ifnum\tabulatemodus=\zerocount + \hbox to + \else + \hsize + \fi + \the\tabulatewidth + \fi + \bgroup + \noexpand\bbskip + \bgroup % we cannot combine the if because a cell may have only one ## + \noexpand#1% + \ifcase\tabulatereshape\else + \beginreshapedtabulatepar + \fi + \noexpand\ifnum\noexpand\tabulatetype=\plusone\noexpand\else + \the\tabulatebmath % maybe later? + \the\tabulatefont + \the\tabulatesettings + \the\tabulatebefore + \noexpand\fi + % grouping needs to be outside macros (or expandable), nice test + % example \NC \string & \NC which will fail otherwise (mk) + \bgroup + \beforetabulateentry + ##% + \aftertabulateentry + \egroup + \noexpand\ifnum\noexpand\tabulatetype=\plusone\noexpand\else + \the\tabulateafter + \the\tabulateemath + \noexpand\fi + \ifcase\tabulatereshape\else + \endreshapedtabulatepar + \fi + \noexpand#2% + \egroup + \egroup + &\noexpand\posttabrule\hskip\postabskip##% + }}% + \appendtoks\NC\to\tabulatedummy + \let\bbskip\empty % ? + \def\pretabskip{.5\tabulateunit}% + \let\postabskip\pretabskip + \let\gettabulateexit\dogettabulateexit + \tabulatewidth\zeropoint} + +\setvalue{\??tt>\meaning x}{\let\tabulatealign\zerocount\settabulatepreamble} % internal +\setvalue{\??tt>\meaning l}{\let\tabulatealign\plusone\settabulatepreamble} +\setvalue{\??tt>\meaning r}{\let\tabulatealign\plustwo\settabulatepreamble} +\setvalue{\??tt>\meaning c}{\let\tabulatealign\plusthree\settabulatepreamble} +\setvalue{\??tt>\meaning p}{\gettabulateparagraph} +\setvalue{\??tt>\meaning s}{\gettabulatesetups} +\setvalue{\??tt>\meaning w}{\gettabulatewidth} +\setvalue{\??tt>\meaning f}{\gettabulatefont} +\setvalue{\??tt>\meaning B}{\tabulatefont{\bf}\settabulatepreamble} +\setvalue{\??tt>\meaning I}{\tabulatefont{\it}\settabulatepreamble} +\setvalue{\??tt>\meaning S}{\tabulatefont{\sl}\settabulatepreamble} +\setvalue{\??tt>\meaning T}{\tabulatefont{\tt}\settabulatepreamble} +\setvalue{\??tt>\meaning R}{\tabulatefont{\rm}\settabulatepreamble} +\setvalue{\??tt>\meaning m}{\tabulatebmath{$}\tabulateemath{$}\settabulatepreamble} +\setvalue{\??tt>\meaning M}{\tabulatebmath{$\displaystyle}\tabulateemath{$}\settabulatepreamble} +\setvalue{\??tt>\meaning h}{\gettabulatehook} +\setvalue{\??tt>\meaning b}{\gettabulatebefore} +\setvalue{\??tt>\meaning a}{\gettabulateafter} +\setvalue{\??tt>\meaning i}{\gettabulatepreskip} +\setvalue{\??tt>\meaning j}{\gettabulateposskip} +\setvalue{\??tt>\meaning k}{\gettabulatepreposskip} +\setvalue{\??tt>\meaning X}{\gettabulateexit} % internal +\setvalue{\??tt>\meaning e}{\appendtoks\global\tabulateequaltrue\to\tabulatesettings\settabulatepreamble} +\setvalue{\??tt>\meaning ~}{\appendtoks\fixedspaces\to\tabulatesettings\settabulatepreamble} +\setvalue{\??tt>\meaning g}{\gettabulatealign} +\setvalue{\??tt>\meaning .}{\gettabulatealign.} +\setvalue{\??tt>\meaning ,}{\gettabulatealign,} + +\setvalue{\??tt>\s!unknown}{\message{unknown preamble key [\meaning\next]}\settabulatepreamble} +\letvalue{\??tt>\meaning\relax}\donothing + +\def\dosettabulatepreamble + {\csname\??tt>\ifcsname\??tt>\meaning\next\endcsname\meaning\next\else\s!unknown\fi\endcsname} + +\def\dogettabulateexit + {\let\postabskip\!!zeropoint + \settabulatepreamble} + +\let\gettabulateexit\dogettabulateexit + +\def\gettabulatepreskip#1% + {\doifnumberelse{#1} + {\edef\pretabskip{\the\dimexpr#1\tabulateunit}\let\next\empty} + {\edef\pretabskip{\the\dimexpr.5\tabulateunit}\def\next{#1}}% + \@EA\settabulatepreamble\next} + +\def\gettabulateposskip#1% + {\doifnumberelse{#1} + {\edef\postabskip{\the\dimexpr#1\tabulateunit}\let\next\empty} + {\edef\postabskip{\the\dimexpr.5\tabulateunit}\def\next{#1}}% + \let\gettabulateexit\settabulatepreamble + \@EA\settabulatepreamble\next} + +\def\gettabulatepreposskip#1% + {\doifnumberelse{#1} + {\edef\pretabskip{\the\dimexpr#1\tabulateunit}\let\next\empty} + {\edef\pretabskip{\the\dimexpr.5\tabulateunit}\def\next{#1}}% + \let\postabskip\pretabskip + \let\gettabulateexit\settabulatepreamble + \@EA\settabulatepreamble\next} + +\def\gettabulatesetups#1% + {\setvalue{\??tt:s:\the\tabulatecolumns}{\setups[#1]}% + \settabulatepreamble} + +\def\gettabulatehook#1% + {\setvalue{\??tt:h:\the\tabulatecolumns}{#1}% + \settabulatepreamble} + +\def\gettabulatealign#1% + {\setvalue{\??tt:a:\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 + \doifnextparenthesiselse\dogettabulatewidth\settabulatepreamble} + +\def\gettabulateparagraph + {\doifnextparenthesiselse + {\let\tabulatemodus\plusone + \let\tabulatedimen\plusone + \dogettabulatewidth} + {\let\tabulatemodus\plustwo + \let\tabulatedimen\zerocount + \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 % can be made faster + [#1]% + [ \v!fit=>\let\tabulatemodus\plusthree, + \v!fixed=>\let\tabulatemodus\plusthree + \tabulatenopbreaktrue, + \v!auto=>\let\tabulatemodus\plusthree + \let\tabulatereshape\plusone, + \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 + +\def\tabulatebskipraggedright {\bskip\tabulateraggedright } +\def\tabulatebskipraggedleft {\bskip\tabulateraggedleft } +\def\tabulatebskipraggedcenter{\bskip\tabulateraggedcenter} + +\def\tabulatesetpreamblewidthnormal + {\ifcase\tabulatealign\relax + \dodosettabulatepreamble\empty \tabulatehss \or + \dodosettabulatepreamble\empty \tabulatehss \or + \dodosettabulatepreamble\tabulatehss\empty \or + \dodosettabulatepreamble\tabulatehss\tabulatehss \fi} + +\def\tabulatesetpreamblewidthfixed + {\ifcase\tabulatealign\relax + \dodosettabulatepreamble\bskip \eskip \or + \dodosettabulatepreamble\tabulatebskipraggedright \eskip \or + \dodosettabulatepreamble\tabulatebskipraggedleft \eskip \or + \dodosettabulatepreamble\tabulatebskipraggedcenter\eskip \fi} + +\def\tabulatesetpreamblewidthauto + {\global\advance\nofautotabulate\plusone + \ifcase\tabulatealign\relax + \dodosettabulatepreamble\bskip \eskip \or + \dodosettabulatepreamble\tabulatebskipraggedright \eskip \or + \dodosettabulatepreamble\tabulatebskipraggedleft \eskip \or + \dodosettabulatepreamble\tabulatebskipraggedcenter\eskip \fi} + +\def\tabulatesetpreamblewidthsimple + {\dodosettabulatepreamble\xbskip\xeskip} + +\bgroup \catcode`\|=\@@other + +\gdef\nexttabulate#1|% + {\let\tabulatealign\@@tabulatealign + \let\tabulatemodus\zerocount + \let\tabulatedimen\zerocount + \let\tabulatereshape\zerocount + \tabulatebefore\emptytoks + \tabulateafter\emptytoks + \tabulatebmath\emptytoks + \tabulateemath\emptytoks + \tabulatefont\emptytoks + \tabulatesettings\emptytoks + \global\advance\tabulatecolumns\plusone + \expandafter\let\csname\??tt:s:\the\tabulatecolumns\endcsname\donothing + \settabulatepreamble#1\relax\relax % permits i without n + \ifcase\tabulatemodus\relax + \tabulatesetpreamblewidthnormal + \or % fixed width + \tabulatesetpreamblewidthfixed + \or % auto width + \tabulatesetpreamblewidthauto + \or % simple + \tabulatesetpreamblewidthsimple + \fi + \futurelet\next\donexttabulate} + +\egroup + +\def\donexttabulate + {\ifx\next\relax\else + \expandafter\nexttabulate + \fi} + +\def\splitofftabulatebox % overloaded in anch-pgr + {\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 {\csname\??tt:h:\the\tabulatecolumn\endcsname} +\def\dotabulatealign{\csname\??tt:a:\the\tabulatecolumn\endcsname} + +\def\resettabulatepheight + {\global\tabulateminplines\plusone + \ifdim\tabulatemaxpheight>\zeropoint + \getnoflines\tabulatemaxpheight + \global\tabulatemaxplines\noflines + \else + \global\tabulatemaxplines\zerocount + \fi + \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}} + +\def\dohandletabulatepbreak + {\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} + +\def\handletabulatepbreak + {\TABLEnoalign{\dohandletabulatepbreak}} + +%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 + \ifcsname\??tt#1::\c!unit\endcsname \else + \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]% + \fi + \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\processtabulateheadcontent + {\TABLEnoalign{\global\settrue\tabulatesomeamble}% + \csname\??tt\currenttabulate-\v!header\endcsname + \TABLEnoalign{\global\setfalse\tabulatesomeamble}}% + +\def\processtabulatetailcontent + {\TABLEnoalign{\global\settrue\tabulatesomeamble}% + \csname\??tt\currenttabulate-\v!footer\endcsname + \TABLEnoalign{\global\setfalse\tabulatesomeamble}}% + +\def\checkfulltabulatecontent % - needed, else confusion with \c!header + {\ifcsname\??tt\currenttabulate-\v!header\endcsname + \let\tabulateheadcontent\processtabulateheadcontent + \else + \let\tabulateheadcontent\empty + \fi + \ifcsname\??tt\currenttabulate-\v!footer\endcsname + \let\tabulatetailcontent\processtabulatetailcontent + \else + \let\tabulatetailcontent\empty + \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]% + {\csname\e!start#1::\ifcsname\e!start#1::#2\endcsname#2\fi\endcsname} + +\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\doparsetabulate + {\futurelet\next\dodoparsetabulate} + +% \def\dodoparsetabulate % \@EAEAEA gebruiken +% {\ifx\next\relax +% % exit +% \else\ifx*\next +% \let\next\dorepeatparsetabulate +% \else\ifx\bgroup\next +% \let\next\dododoparsetabulate +% \else +% \let\next\dodododoparsetabulate +% \fi\fi\fi +% \next}% + +\def\dorepeatparsetabulate*#1#2% + {\dorecurse{#1}{\!!toksb\expandafter{\the\!!toksb#2}}% \dorecurse{#1}{\appendtoks#2\to\!!toksb}% + \doparsetabulate} + +\def\dododoparsetabulate#1% + {\!!toksb\expandafter{\the\!!toksb{#1}}% \appendtoks{#1}\to\!!toksb + \doparsetabulate} + +\def\dodododoparsetabulate#1% + {\!!toksb\expandafter{\the\!!toksb#1}% \appendtoks#1\to\!!toksb + \doparsetabulate} + +\letvalue{\??tt<\meaning *}\dorepeatparsetabulate +\letvalue{\??tt<\meaning \bgroup}\dododoparsetabulate +\letvalue{\??tt<\meaning \relax}\donothing +\letvalue{\??tt<\s!unknown }\dodododoparsetabulate + +\def\dodoparsetabulate + {\csname\??tt<\ifcsname\??tt<\meaning\next\endcsname\meaning\next\else\s!unknown\fi\endcsname} + +\setvalue{\??tt:\c!split:\v!yes }{\splittabulatetrue} +\setvalue{\??tt:\c!split:\v!repeat}{\splittabulatetrue} +\setvalue{\??tt:\c!split:\v!no }{\splittabulatefalse} +\setvalue{\??tt:\c!split:\v!auto }{\ifinsidefloat\ifinsidesplitfloat\else\splittabulatefalse\fi\fi} + +\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 + \csname\??tt:\c!split:\tabulateparameter\c!split\endcsname + \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 + \doifelsevalue{\??tt\currenttabulate\c!indenting}\v!yes + {\edef\tabulateindent{\the\dimexpr\leftskip+\hangindent+\parindent}}% \ctxparindent + {\edef\tabulateindent{\the\dimexpr\leftskip+\hangindent }}% + \global\tabulatecolumn\zerocount + \!!toksb\emptytoks + \bgroup + \@@useotherbar + \normalexpanded{\egroup\noexpand\doparsetabulate#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 % can be sped up (will do when used frequently) + {\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 % used in styles ! + +%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 + \glet\registertabulateparoptions\empty + \else + % unsafe in crossing pages, at each b... + % \glet\registertabulateparoptions\empty + \fi + \fi} + +\appendtoks + \glet\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} + +\newtoks\everyaftertabulaterow + +\def\tabulatebskipone {\setbox\tabulatebox\vbox\bgroup\glet\tabulatehook\notabulatehook} +\def\tabulateeskipone {\par\egroup\glet\tabulatehook\dotabulatehook} +\def\tabulatexbskipone{\hbox\bgroup\vbox\bgroup\glet\tabulatehook\notabulatehook} +\def\tabulatexeskipone{\par\egroup\egroup\glet\tabulatehook\dotabulatehook} + +\def\tabulatebaselinecorrection + {\def\dobaselinecorrection % todo: mkiv + {\vskip-\prevdepth + \vskip\strutdp + \vskip\strutdp}% + \baselinecorrection} + +\unexpanded\def\tabulateNCone{\tabulatenormalcolumn0} +\unexpanded\def\tabulateRCone{\tabulatenormalcolumn1} +\unexpanded\def\tabulateHCone{\tabulatenormalcolumn2} +\unexpanded\def\tabulateEQone{\tabulateequalcolumn 0} +\unexpanded\def\tabulateRQone{\tabulateequalcolumn 1} +\unexpanded\def\tabulateHQone{\tabulateequalcolumn 2} +\unexpanded\def\tabulateNGone{\NC\handletabulatecharalign} +\unexpanded\def\tabulateNNone{\NC\handletabulatedigits} % new, undocumented, test first +\unexpanded\def\tabulateNDone{\NC\handletabulatedigits} % same, for old times sake +\unexpanded\def\tabulateHRone{\doHR\zerocount} +\unexpanded\def\tabulateHLone{\doHL\zerocount} + +\unexpanded\def\tabulateNRone % next row + {\global\advance\noftabulatelines\plusone + \global\tabulatefirstflushedfalse + \global\tabulateequalfalse + \global\tabulatecolumn\zerocount + \resettabulatepheight + \unskip\unskip\crcr\flushtabulated + \TABLEnoalign{\the\everyaftertabulaterow}% + \TABLEnoalign{\checktabulatepenaltiesa}} + +\def\checktabulatepenaltiesa + {\iftolerantTABLEbreak\else + \ifnum\totalnoftabulatelines=\plusone + % \allowbreak + \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 + \fi + \global\tabulatefirstflushedfalse} + +\def\tabulatebbskiptwo + {\ifvoid\tablebox\tabulatecolumn + \ifx\flushtabulatedindeed\empty\else + \setbox0\hbox + \fi + \fi} + +\def\tabulatebskiptwoeskip + {\par\egroup + \settabulatepheight + \glet\tabulatehook\dotabulatehook + \splitofftabulatebox} + +\def\tabulatebskiptwo + {\ifvoid\tablebox\tabulatecolumn + \global\setbox\tablebox\tabulatecolumn\vbox + \bgroup + \glet\tabulatehook\notabulatehook + \ifautotabulate\hsize\tabulatewidth\fi + % \begstrut % interferes with pre-\pars + % evt: \appendtoks\begstrut\to\everypar + \ignorespaces + \let\eskip\tabulatebskiptwoeskip + \else + \let\eskip\empty + \dontcomplain + \glet\tabulatehook\dotabulatehook + \expandafter\splitofftabulatebox + \fi} + +\def\tabulatexbskiptwo{\bskip} +\def\tabulatexeskiptwo{\eskip} + +% \def\tabulateflushtabulatedtwo +% {\TABLEnoalign % noalign % no interference ! +% {\glet\flushtabulatedindeed\empty +% \global\tabulatecolumn\zerocount +% \handletabulatepbreak +% \dorecurse\tabulatecolumns % was: \noftabcolumns +% {\ifvoid\tablebox\recurselevel\else +% \gdef\flushtabulatedindeed{\the\tabulatedummy}% +% \fi}% +% \global\tabulatefirstflushedtrue}% +% \flushtabulatedindeed} + +\def\dotabulateflushtabulatedtwo + {\glet\flushtabulatedindeed\empty + \global\tabulatecolumn\zerocount + \handletabulatepbreak + \dorecurse\tabulatecolumns % was: \noftabcolumns + {\ifvoid\tablebox\recurselevel\else + \gdef\flushtabulatedindeed{\the\tabulatedummy}% + \fi}% + \global\tabulatefirstflushedtrue} + +\def\tabulateflushtabulatedtwo + {\TABLEnoalign{\dotabulateflushtabulatedtwo}% + \flushtabulatedindeed} + +\def\tabulatebskipthree + {\vtop\bgroup + \ifautotabulate\hsize\tabulatewidth\fi + % \begstrut % interferes with pre-\pars + % evt: \appendtoks\begstrut\to\everypar + \ignorespaces} + +\def\tabulateeskipthree % vertical strut added august 2003 + {\par\verticalstrut\vskip-\struttotal\egroup} + +\def\tabulatedoHLfour#1% #1 ignored + {\TABLEnoalign + {\csname + \ifnum\noftabulatelines=\zerocount F\else + \ifnum\noftabulatelines=\totalnoftabulatelines L\else + M\fi\fi + L\endcsname}}% + +\def\tabulatedoHRfour#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}} + +\def\tabulateFLfive{\TABLEnoalign + {\ifinsidefloat\else + \doifemptyvalue{\??tt\currenttabulate\c!before} % no expansion + {\tabulatebaselinecorrection}% + \fi + \dotabulaterule + \dotabulatenobreak + \dotabulateruleseperator + \prevdepth\strutdp + \dotabulatenobreak}} + +% see *** +% +% \enabletrackers[nodes.page_vspacing] +% \starttext +% \starttabulate[||] \dorecurse{100}{\NC Eins \NC \NR \HL} \stoptabulate +% \stoptext + +\def\tabulateMLfive{\TABLEnoalign + {\dotabulateruleseperator + \dotabulaterule + \ifnum\noftabulatelines>\plusone + \ifnum\noftabulatelines<\minusnoftabulatelines + % *** somehow topskip messes up as it's intercepted + % \vskip \topskip\allowbreak\vskip- \topskip + % messy anyhow so this needs to be improved, so for + % the momenet we keep this bugged variant + \vskip1\topskip\allowbreak\vskip-1\topskip + \vskip-\tabulateparameter\c!rulethickness + \dotabulaterule + \fi + \fi + \dotabulateruleseperator}} + +\def\tabulateLLfive{\TABLEnoalign + {\dotabulatenobreak + \dotabulateruleseperator + \dotabulatenobreak + \dotabulaterule + \ifinsidefloat\else + \doifemptyvalue{\??tt\currenttabulate\c!after} % no expansion + {\vskip\strutdp + \verticalstrut + \vskip-\struttotal}% + \fi}} + +\def\tabulateHLfive + {\doHL\zerocount} + +\def\tabulaterule {\HR}% a rule with lineheight +\def\tabulateline {\HL}% just a spaced rule +\def\tabulateautorule{\doHR\plusone}% +\def\tabulateautoline{\doHL\plusone}% + +\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}% + \let\pretabskip\!!zeropoint + \def\postabskip{.5\tabulateunit}% + \global\tabulatecolumns\zerocount + \global\nofautotabulate\zerocount + \global\noftabulatelines\zerocount + \totalnoftabulatelines\noftabulatelines + \minusnoftabulatelines\noftabulatelines + \global\tabulatepwidth\zeropoint + \global\tabulatexwidth\zeropoint + \global\tabulateequalfalse + \resettabulatepheight + \ifinsidesplitfloat + \donetrue + \else\ifinsidefloat + \donefalse + \else + \donetrue + \fi\fi + \ifdone + \chardef\tabulaterepeathead\executeifdefined{\??tt:\c!header:\tabulateparameter\c!header}\zerocount + \fi + \let\NC\tabulateNCone + \let\RC\tabulateRCone + \let\HC\tabulateHCone + \let\EQ\tabulateEQone + \let\RQ\tabulateRQone + \let\HQ\tabulateHQone + \let\NG\tabulateNGone + \let\NN\tabulateNNone + \let\ND\tabulateNDone + \let\HR\tabulateHRone + \let\HL\tabulateHLone + \let\NR\tabulateNRone + \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 + \glet\flushtabulated\empty + \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 + \nexttabulate #1X|\relax + \edef\totaltabulatecolumns{\the\numexpr3*\tabulatecolumns+4}% + \tabulatewidth\zeropoint + \initializetableboxes\tabulatecolumns + \appendtoks&##\global\advance\tabulatecolumn\plusone\to\!!toksa + \appendtoks\NC\unskip\unskip\crcr\flushtabulated\to\tabulatedummy % no count + \global\tabulatecolumn\zerocount + \resettabulatepheight + \let\bskip \tabulatebskipone + \let\eskip \tabulateeskipone + \let\xbskip\tabulatexbskipone + \let\xeskip\tabulatexeskipone + \glet\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\dimexpr\hsize-\wd0-\tabulatepwidth-\tabulatexwidth\relax + \ifnum\nofautotabulate>\zerocount + \divide\tabulatewidth \nofautotabulate\relax + \fi + \fi + \let\xbskip\tabulatexbskiptwo + \let\xeskip\tabulatexeskiptwo + \ifsplittabulate + \splittopskip\strutht + \glet\flushtabulatedindeed\empty + \let\bbskip\tabulatebbskiptwo + \let\bskip\tabulatebskiptwo + \glet\flushtabulated\tabulateflushtabulatedtwo + \else + % tabhook op alles ? + \let\bskip\tabulatebskipthree + \let\eskip\tabulateeskipthree + \fi + \totalnoftabulatelines\noftabulatelines + \minusnoftabulatelines\numexpr\noftabulatelines+\minusone\relax + \global\noftabulatelines\zerocount + \let\doHL\tabulatedoHLfour + \let\doHR\tabulatedoHRfour + \doifelsevalue{\??tt\currenttabulate\c!rule}\v!line + {\let\HL\HR + \let\tabulateautoline\tabulateautorule + \let\tabulateline\tabulaterule}% + {\let\HL\tabulateHLfive}% + \let\FL\tabulateFLfive + \let\ML\tabulateMLfive + \let\LL\tabulateLLfive + \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 + {\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 + +\unexpanded\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.mkii b/tex/context/base/tabl-tsp.mkii new file mode 100644 index 000000000..49bb7ad90 --- /dev/null +++ b/tex/context/base/tabl-tsp.mkii @@ -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/tabl-tsp.mkiv b/tex/context/base/tabl-tsp.mkiv new file mode 100644 index 000000000..9ceb3af6e --- /dev/null +++ b/tex/context/base/tabl-tsp.mkiv @@ -0,0 +1,429 @@ +%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} + +% \def\s!noftablesplits{nofsplittables} + +\definenumber % we need a nicer name like nofsplittables, we then also need to set \s!parent + [\??si] + [\c!way=\v!by\v!text, + \c!conversion=\@@siconversion] + +\unexpanded\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..aaa97ec49 --- /dev/null +++ b/tex/context/base/task-ini.lua @@ -0,0 +1,94 @@ +if not modules then modules = { } end modules ['task-ini'] = { + version = 1.001, + comment = "companion to task-ini.mkiv", + 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 +-- +-- we can disable more handlers and enable then when really used (*) + +tasks.appendaction("processors", "normalizers", "fonts.collections.process") -- todo +tasks.appendaction("processors", "normalizers", "fonts.checkers.missing") -- disabled + +tasks.appendaction("processors", "characters", "chars.handle_mirroring") -- disabled +tasks.appendaction("processors", "characters", "chars.handle_casing") -- disabled +tasks.appendaction("processors", "characters", "chars.handle_digits") -- disabled +tasks.appendaction("processors", "characters", "chars.handle_breakpoints") -- disabled +tasks.appendaction("processors", "characters", "scripts.preprocess") + +tasks.appendaction("processors", "words", "kernel.hyphenation") -- always on +tasks.appendaction("processors", "words", "languages.words.check") -- disabled + +tasks.appendaction("processors", "fonts", "nodes.process_characters") -- maybe todo +tasks.appendaction("processors", "fonts", "nodes.inject_kerns") -- maybe todo +tasks.appendaction("processors", "fonts", "nodes.protect_glyphs", nil, "nohead") -- maybe todo +tasks.appendaction("processors", "fonts", "kernel.ligaturing") -- always on +tasks.appendaction("processors", "fonts", "kernel.kerning") -- always on +tasks.appendaction("processors", "fonts", "nodes.stripping.process") -- disabled (might move) + +tasks.appendaction("processors", "lists", "lists.handle_spacing") -- disabled +tasks.appendaction("processors", "lists", "lists.handle_kerning") -- disabled + +tasks.appendaction("shipouts", "normalizers", "nodes.cleanup_page") -- maybe todo +tasks.appendaction("shipouts", "normalizers", "nodes.add_references") -- disabled +tasks.appendaction("shipouts", "normalizers", "nodes.add_destinations") -- disabled +tasks.appendaction("shipouts", "normalizers", "nodes.rules.process") -- disabled +tasks.appendaction("shipouts", "normalizers", "nodes.shifts.process") -- disabled + +tasks.appendaction("shipouts", "finishers", "shipouts.handle_color") -- disabled +tasks.appendaction("shipouts", "finishers", "shipouts.handle_transparency") -- disabled +tasks.appendaction("shipouts", "finishers", "shipouts.handle_colorintent") -- disabled +tasks.appendaction("shipouts", "finishers", "shipouts.handle_negative") -- disabled +tasks.appendaction("shipouts", "finishers", "shipouts.handle_effect") -- disabled +tasks.appendaction("shipouts", "finishers", "shipouts.handle_viewerlayer") -- disabled + +tasks.appendaction("math", "normalizers", "noads.relocate_characters", nil, "nohead") -- always on +tasks.appendaction("math", "normalizers", "noads.resize_characters", nil, "nohead") -- always on +tasks.appendaction("math", "normalizers", "noads.respace_characters", nil, "nohead") -- always on + +tasks.appendaction("math", "builders", "noads.mlist_to_hlist") -- always on + +-- quite experimental + +tasks.appendaction("finalizers", "lists", "nodes.repackage_graphicvadjust") -- todo + +-- rather new + +tasks.appendaction("mvlbuilders", "normalizers", "nodes.migrate_outwards") +tasks.appendaction("mvlbuilders", "normalizers", "nodes.handle_page_spacing") -- last ! + +tasks.appendaction("vboxbuilders", "normalizers", "nodes.handle_vbox_spacing") + +-- speedup: only kick in when used + +tasks.disableaction("processors", "fonts.checkers.missing") +tasks.disableaction("processors", "chars.handle_breakpoints") +tasks.disableaction("processors", "chars.handle_casing") +tasks.disableaction("processors", "chars.handle_digits") +tasks.disableaction("processors", "chars.handle_mirroring") +tasks.disableaction("processors", "languages.words.check") +tasks.disableaction("processors", "lists.handle_spacing") +tasks.disableaction("processors", "lists.handle_kerning") +tasks.disableaction("processors", "nodes.stripping.process") + +tasks.disableaction("shipouts", "nodes.rules.process") +tasks.disableaction("shipouts", "nodes.shifts.process") +tasks.disableaction("shipouts", "shipouts.handle_color") +tasks.disableaction("shipouts", "shipouts.handle_transparency") +tasks.disableaction("shipouts", "shipouts.handle_colorintent") +tasks.disableaction("shipouts", "shipouts.handle_effect") +tasks.disableaction("shipouts", "shipouts.handle_negative") +tasks.disableaction("shipouts", "shipouts.handle_viewerlayer") + +tasks.disableaction("shipouts", "nodes.add_references") +tasks.disableaction("shipouts", "nodes.add_destinations") + +tasks.disableaction("mvlbuilders", "nodes.migrate_outwards") + +callbacks.freeze("find_.*_file", "find file using resolver") +callbacks.freeze("read_.*_file", "read file at once") +callbacks.freeze("open_.*_file", "open file for reading") diff --git a/tex/context/base/task-ini.mkiv b/tex/context/base/task-ini.mkiv new file mode 100644 index 000000000..ef32ee87d --- /dev/null +++ b/tex/context/base/task-ini.mkiv @@ -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-pic.tex b/tex/context/base/thrd-pic.tex new file mode 100644 index 000000000..3c25d8a81 --- /dev/null +++ b/tex/context/base/thrd-pic.tex @@ -0,0 +1,3694 @@ +% Since this file is not available in every distribution, we +% have copied the original in this file. The manuals to +% Wichura's PiCTeX and TaBlE packages are not available on +% line and are distributed by respectively the TeX Users Group +% and Personal TeX Inc. + +% We've patched this file for catcode ! because in luatex we use +% catcode tables and using unprotect/protect is cleaner. + +% This is PiCTeX, Version 1.1 9/21/87 + +% CAVEAT: The PiCTeX manual often has a more lucid explanation +% of any given topic than you will find in the internal documentation +% of the macros. + +% PiCTeX's commands can be classified into two groups: (1) public (or +% external), and (2) private (or internal). The public macros are +% discussed at length in the manual. The only discussion of the private +% macros is the internal documentation. The private macros all have +% names beginning with an exclamation point (!) of category code 11. +% Since in normal usage "!" has category code 12, these macros can't +% be accessed or modified by the general user. + +% The macros are organized into thematically related groups. For example, +% the macros dealing with dots & dashes are all in the DASHPATTERN group. +% The table below shows which macros are in which groups. The table +% covers all public macros, and many (but not all) of PiCTeX's upper level +% private macros. Following the table, the various groups are listed +% in the order in which they appear in the table. + +% *********************** TABLE OF GROUPS OF MACROS ********************** + +% HACKS: Utility macros +% \PiC +% \PiCTeX +% \placevalueinpts +% \!!loop +% \!cfor +% \!copylist +% \!ecfor +% \!etfor +% \!getnext +% \!getnextvalueof +% \!ifempty +% \!ifnextchar +% \!leftappend +% \!listaddon +% \!loop +% \!lop +% \!mlap +% \!not +% \!removept +% \!rightappend +% \!tfor +% \!vmlap +% \!wlet + +% ALLOCATION: Allocates registers + +% AREAS: Deals with plot areas +% \axis +% \grid +% \invisibleaxes +% \normalgraphs +% \plotheading +% \setplotarea +% \visibleaxes + +% ARROWS: Draws arrows +% \arrow +% \betweenarrows + +% BARS: Draws bars +% \putbar +% \setbars + +% BOXES: Draws rectangles +% \frame +% \putrectangle +% \rectangle +% \shaderectangleson +% \shaderectanglesoff + +% CURVES: Upper level plot commands +% \hshade +% \plot +% \sethistograms +% \setlinear +% \setquadratic +% \vshade + +% DASHPATTERNS: Sets up dash patterns +% \findlength +% \setdashes +% \setdashesnear +% \setdashpattern +% \setdots +% \setdotsnear +% \setsolid +% \!dashingoff +% \!dashingon + +% DIVISION: Does long division of dimension registers +% \Divide +% \!divide + +% ELLIPSES: Draws ellipses and circles +% \circulararc +% \ellipticalarc + +% RULES: Draws rules, i.e., horizontal & vertical lines +% \putrule +% \!putdashedhline +% \!putdashedvline +% \!puthline +% \!putsolidhline +% \!putsolidvline +% \!putvline + +% LINEAR ARC: Draws straight lines -- solid and dashed +% \inboundscheckoff +% \inboundscheckon +% \!advancedashing +% \!drawlinearsegment +% \!initinboundscheck +% \!linearsolid +% \!lineardashed +% \!ljoin +% \!plotifinbounds +% \!start + +% LOGTEN: Log_10 function +% \!logten + +% PICTURES: Basic setups for PiCtures; \put commands +% \accountingoff +% \accountingon +% \beginpicture +% \endpicture +% \endpicturesave +% \lines +% \multiput +% \put +% \setcoordinatemode +% \setcoordinatesystem +% \setdimensionmode +% \stack +% \Lines +% \Xdistance +% \Ydistance +% \!dimenput +% \!ifcoordmode +% \!ifdimenmode +% \!setcoordmode +% \!setdimenmode +% \!setputobject + +% PLOTTING: Things to do with plotting +% \dontsavelinesandcurves +% \replot +% \savelinesandcurves +% \setplotsymbol +% \writesavefile +% \!plot + +% PYTHAGORAS: Euclidean distance function +% \placehypotenuse +% \!Pythag + +% QUADRATIC ARC: Draws a quadratic arc +% \!qjoin + +% ROTATIONS: Handles rotations +% \startrotation +% \stoprotation +% \!rotateaboutpivot +% \!rotateonly + +% SHADING: Handles shading +% \setshadegrid +% \setshadesymbol +% \!lshade +% \!qshade +% \!starthshade +% \!startvshade + +% TICKS: Draws ticks on graphs +% \gridlines +% \loggedticks +% \nogridlines +% \ticksin +% \ticksout +% \unloggesticks + +% ***************** END OF TABLE OF GROUPS OF MACROS ******************** + + +% \catcode`!=11 % ***** THIS MUST NEVER BE OMITTED + +\unprotect + +% ******************************* +% *** HACKS (Utility macros) *** +% ******************************* + +% ** User commands +% ** \PiC{P\kern-.12em\lower.5ex\hbox{I}\kern-.075emC} +% ** \PiCTeX{\PiC\kern-.11em\TeX} +% ** \placevalueinpts of in {CONTROL SEQUENCE} + +% ** Internal commands +% ** \!ifnextchar{CHARACTER}{TRUE ACTION}{FALSE ACTION} +% ** \!tfor NAME := LIST \do {BODY} +% ** \!etfor NAME:= LIST \do {BODY} +% ** \!cfor NAME := LIST \do {BODY} +% ** \!ecfor NAME:= LIST \do {BODY} +% ** \!ifempty{MACRO}{TRUE ACTION}{FALSE ACTION} +% ** \!getnext\\ITEMfrom\LIST +% ** \!getnextvalueof\DIMEN\from\LIST +% ** \!copylist\LISTMACRO_A\to\LISTMACRO_B +% ** \!wlet\CONTROL_SEQUENCE_A=\CONTROL_SEQUENCE_B +% ** \!listaddon ITEM LIST +% ** \!rightappendITEM\withCS\to\LISTMACRO +% ** \!leftappendITEM\withCS\to\LISTMACRO +% ** \!lop\LISTMACRO\to\ITEM +% ** \!loop ... repeat +% ** \!!loop ... repeat +% ** \!removept{DIMENSION REGISTER}{CONTROL SEQUENCE} +% ** \!mlap{...} +% ** \!vmlap{...} +% ** \!not{TEK if-CONDITION} + +% ** First, here are the the PiCTeX logo, and the syllable PiC: +\def\PiC{P\kern-.12em\lower.5ex\hbox{I}\kern-.075emC} +\def\PiCTeX{\PiC\kern-.11em\TeX} + +% ** The following macro expands to parameter #2 or parameter #3 according to +% ** whether the next non-blank character following the macro is or is not #1. +% ** Blanks following the macro are gobbled. +\def\!ifnextchar#1#2#3{% + \let\!testchar=#1% + \def\!first{#2}% + \def\!second{#3}% + \futurelet\!nextchar\!testnext} +\def\!testnext{% + \ifx \!nextchar \!spacetoken + \let\!next=\!skipspacetestagain + \else + \ifx \!nextchar \!testchar + \let\!next=\!first + \else + \let\!next=\!second + \fi + \fi + \!next} +\def\\{\!skipspacetestagain} + \expandafter\def\\ {\futurelet\!nextchar\!testnext} +\def\\{\let\!spacetoken= } \\ % ** set \spacetoken to a space token + + +% ** Borrow the "tfor" macro from Latex: +% ** \!tfor NAME := LIST \do {BODY} +% ** if, before expansion, LIST = T1 ... Tn, where each Ti is a token +% ** or {...}, then executes BODY n times, with NAME = Ti on the +% ** i-th iteration. Works for n=0. +\def\!tfor#1:=#2\do#3{% + \edef\!fortemp{#2}% + \ifx\!fortemp\!empty + \else + \!tforloop#2\!nil\!nil\!!#1{#3}% + \fi} +\def\!tforloop#1#2\!!#3#4{% + \def#3{#1}% + \ifx #3\!nnil + \let\!nextwhile=\!fornoop + \else + #4\relax + \let\!nextwhile=\!tforloop + \fi + \!nextwhile#2\!!#3{#4}} + + +% ** \!etfor NAME:= LIST\do {BODY} +% ** This is like \!cfor, but LIST is any balanced token list whose complete +% ** expansion has the form T1 ... Tn +\def\!etfor#1:=#2\do#3{% + \def\!!tfor{\!tfor#1:=}% + \edef\!!!tfor{#2}% + \expandafter\!!tfor\!!!tfor\do{#3}} + + +% ** modify the Latex \tfor (token-for) loop to a \cfor (comma-for) loop. +% ** \!cfor NAME := LIST \do {BODY} +% ** if, before expansion, LIST = a1,a2,...an, then executes BODY n times, +% ** with NAME = ai on the i-th iteration. Works for n=0. +\def\!cfor#1:=#2\do#3{% + \edef\!fortemp{#2}% + \ifx\!fortemp\!empty + \else + \!cforloop#2,\!nil,\!nil\!!#1{#3}% + \fi} +\def\!cforloop#1,#2\!!#3#4{% + \def#3{#1}% + \ifx #3\!nnil + \let\!nextwhile=\!fornoop + \else + #4\relax + \let\!nextwhile=\!cforloop + \fi + \!nextwhile#2\!!#3{#4}} + + +% ** \!ecfor NAME:= LIST\do {BODY} +% ** This is like \!cfor, but LIST is any balanced token list whose complete +% ** expansion has the form a1,a2,...,an. +\def\!ecfor#1:=#2\do#3{% + \def\!!cfor{\!cfor#1:=}% + \edef\!!!cfor{#2}% + \expandafter\!!cfor\!!!cfor\do{#3}} + + +\def\!empty{} +\def\!nnil{\!nil} +\def\!fornoop#1\!!#2#3{} + + +% ** \!ifempty{ARG}{TRUE ACTION}{FALSE ACTION} +\def\!ifempty#1#2#3{% + \edef\!emptyarg{#1}% + \ifx\!emptyarg\!empty + #2% + \else + #3% + \fi} + +% ** \!getnext\\ITEMfrom\LIST +% ** \LIST has the form \\{item1}\\{item2}\\{item3}...\\{itemk} +% ** This routine sets \ITEM to item1, and cycles \LIST to +% ** \\{item2}\\{item3}...\\{itemk}\\{item1} +\def\!getnext#1\from#2{% + \expandafter\!gnext#2\!#1#2}% +\def\!gnext\\#1#2\!#3#4{% + \def#3{#1}% + \def#4{#2\\{#1}}% + \ignorespaces} + + +% ** \!getnextvalueof\DIMEN\from\LIST +% ** Similar to !getnext. +% ** \LIST has the form \\{dimen1}\\{dimen2}\\{dimen3} ... +% ** \DIMEN is a dimension register +% ** Works also for counts +% +\def\!getnextvalueof#1\from#2{% + \expandafter\!gnextv#2\!#1#2}% +\def\!gnextv\\#1#2\!#3#4{% + #3=#1% + \def#4{#2\\{#1}}% + \ignorespaces} + + +% ** \!copylist\LISTMACROA\to\LISTMACROB +% ** makes the replacement text of LISTMACRO B identical to that of +% ** list macro A. +\def\!copylist#1\to#2{% + \expandafter\!!copylist#1\!#2} +\def\!!copylist#1\!#2{% + \def#2{#1}\ignorespaces} + + +% ** \!wlet\CSA=\CSB +% ** lets control sequence \CSB = control sequence \CSA, and writes a +% ** message to that effect in the log file using plain TEK's \wlog +\def\!wlet#1=#2{% + \let#1=#2 + \wlog{\string#1=\string#2}} + +% ** \!listaddon ITEM LIST +% ** LIST <-- LIST \\ ITEM +\def\!listaddon#1#2{% + \expandafter\!!listaddon#2\!{#1}#2} +\def\!!listaddon#1\!#2#3{% + \def#3{#1\\#2}} + +% ** \!rightappendITEM\to\LISTMACRO +% ** \LISTMACRO --> \LISTMACRO\\{ITEM} +%\def\!rightappend#1\to#2{\expandafter\!!rightappend#2\!{#1}#2} +%\def\!!rightappend#1\!#2#3{\def#3{#1\\{#2}}} + + +% ** \!rightappendITEM\withCS\to\LISTMACRO +% ** \LISTMACRO --> \LISTMACRO||CS||{ITEM} +\def\!rightappend#1\withCS#2\to#3{\expandafter\!!rightappend#3\!#2{#1}#3} +\def\!!rightappend#1\!#2#3#4{\def#4{#1#2{#3}}} + + +% ** \!leftappendITEM\withCS\to\LISTMACRO +% ** \LISTMACRO --> CS||{ITEM}||\LISTMACRO +\def\!leftappend#1\withCS#2\to#3{\expandafter\!!leftappend#3\!#2{#1}#3} +\def\!!leftappend#1\!#2#3#4{\def#4{#2{#3}#1}} + + +% ** \!lop\LISTMACRO\to\ITEM +% ** \\{item1}\\{item2}\\{item3} ... --> \\{item2}\\{item3} ... +% ** item1 --> \ITEM +\def\!lop#1\to#2{\expandafter\!!lop#1\!#1#2} +\def\!!lop\\#1#2\!#3#4{\def#4{#1}\def#3{#2}} + + +% ** \!placeNUMBER\of\LISTMACRO\in\ITEM +% ** the NUMBERth item of \LISTMACRO --> replacement text of \ITEM +%\def\!place#1\of#2\in#3{\def#3{\outofrange}% +%{\count0=#1\def\\##1{\advance\count0-1 \ifnum\count0=0 \gdef#3{##1}\fi}#2}} + + +% ** Following code converts a commalist to a list macro, with all items +% ** fully expanded. +%\!ecfor\item:=\commalist\do{\expandafter\!rightappend\item\to\list} + + +% ** \!loop ... repeat +% ** This is exactly like TEX's \loop ... repeat. It can be used in nesting +% ** two loops, without puting the inner one inside a group. +\def\!loop#1\repeat{\def\!body{#1}\!iterate} +\def\!iterate{\!body\let\!next=\!iterate\else\let\!next=\relax\fi\!next} + +% ** \!!loop ... repeat +% ** This is exactly like TEX's \loop ... repeat. It can be used in nesting +% ** two loops, without puting the inner one inside a group. +\def\!!loop#1\repeat{\def\!!body{#1}\!!iterate} +\def\!!iterate{\!!body\let\!!next=\!!iterate\else\let\!!next=\relax\fi\!!next} +% (\multiput uses \!!loop) + +% ** \!removept{DIMENREG}{\CS} +% ** Defines the control sequence CS to be the value (in points) in the +% ** dimension register DIMENREG (but without the "pt" TEK usually adds) +% ** E.g., after \dimen0=12.3pt \!removept\dimen0\A, \A expands to 12.3 +\def\!removept#1#2{\edef#2{\expandafter\!!removePT\the#1}} +{\catcode`p=12 \catcode`t=12 \gdef\!!removePT#1pt{#1}} + +% ** \pladevalueinpts of in {CONTROL SEQUENCE} +\def\placevalueinpts of <#1> in #2 {% + \!removept{#1}{#2}} + +% ** \!mlap{...} \!vmlap{...} +% ** Center ... in a box of width 0. +\def\!mlap#1{\hbox to 0pt{\hss#1\hss}} +\def\!vmlap#1{\vbox to 0pt{\vss#1\vss}} + +% ** \!not{TEK if-CONDITION} +% ** By a TEK if-CONDITION is meant something like +% ** \ifnum\N<0, or \ifdim\A>\B +% ** \!not produces an if-condition which is false if the original condition +% ** is true, and true if the original condition is false. +\def\!not#1{% + #1\relax + \!switchfalse + \else + \!switchtrue + \fi + \if!switch + \ignorespaces} + + +% ******************* +% *** ALLOCATIONS *** +% ******************* + +% This section allocates all the registers PiCTeX uses. Following +% each allocation is a string of the form ....N.D...L......... ; +% the various letters show which sections of PiCTeX make explicit +% reference to that register, according to the following code: + +% H Hacks +% A Areas +% W arroWs +% B Bars +% X boXes +% C Curves +% D Dashpattterns +% V diVision +% E Ellipses +% U rUles +% L Linear arc +% G loGten +% P Pictures +% O plOtting +% Y pYthagoras +% Q Quadratic arc +% R Rotations +% S Shading +% T Ticks + +% Turn off messages from TeX's allocation macros +\let\!!!wlog=\wlog % "\wlog" is defined in plain TeX +\def\wlog#1{} + +\newdimen\headingtoplotskip %.A................. +\newdimen\linethickness %.A..X....U........T +\newdimen\longticklength %.A................T +\newdimen\plotsymbolspacing %......D...L....Q... +\newdimen\shortticklength %.A................T +\newdimen\stackleading %.A..........P...... +\newdimen\tickstovaluesleading %.A................T +\newdimen\totalarclength %......D...L....Q... +\newdimen\valuestolabelleading %.A................. + +\newbox\!boxA %.AW...............T +\newbox\!boxB %..W................ +\newbox\!picbox %............P...... +\newbox\!plotsymbol %..........L..O..... +\newbox\!putobject %............PO...S. +\newbox\!shadesymbol %.................S. + +\newcount\!countA %.A....D..UL....Q.ST +\newcount\!countB %......D..U.....Q.ST +\newcount\!countC %...............Q..T +\newcount\!countD %................... +\newcount\!countE %.............O....T +\newcount\!countF %.............O....T +\newcount\!countG %..................T +\newcount\!fiftypt %.........U......... +\newcount\!intervalno %..........L....Q... +\newcount\!npoints %..........L........ +\newcount\!nsegments %.........U......... +\newcount\!ntemp %............P...... +\newcount\!parity %.................S. +\newcount\!scalefactor %..................T +\newcount\!tfs %.......V........... +\newcount\!tickcase %..................T + +\newdimen\!Xleft %............P...... +\newdimen\!Xright %............P...... +\newdimen\!Xsave %.A................T +\newdimen\!Ybot %............P...... +\newdimen\!Ysave %.A................T +\newdimen\!Ytop %............P...... +\newdimen\!angle %........E.......... +\newdimen\!arclength %..W......UL....Q... +\newdimen\!areabloc %.A........L........ +\newdimen\!arealloc %.A........L........ +\newdimen\!arearloc %.A........L........ +\newdimen\!areatloc %.A........L........ +\newdimen\!bshrinkage %.................S. +\newdimen\!checkbot %..........L........ +\newdimen\!checkleft %..........L........ +\newdimen\!checkright %..........L........ +\newdimen\!checktop %..........L........ +\newdimen\!dimenA %.AW.X.DVEUL..OYQRST +\newdimen\!dimenB %....X.DVEU...O.QRS. +\newdimen\!dimenC %..W.X.DVEU......RS. +\newdimen\!dimenD %..W.X.DVEU....Y.RS. +\newdimen\!dimenE %..W........G..YQ.S. +\newdimen\!dimenF %...........G..YQ.S. +\newdimen\!dimenG %...........G..YQ.S. +\newdimen\!dimenH %...........G..Y..S. +\newdimen\!dimenI %...BX.........Y.... +\newdimen\!distacross %..........L....Q... +\newdimen\!downlength %..........L........ +\newdimen\!dp %.A..X.......P....S. +\newdimen\!dshade %.................S. +\newdimen\!dxpos %..W......U..P....S. +\newdimen\!dxprime %...............Q... +\newdimen\!dypos %..WB.....U..P...... +\newdimen\!dyprime %...............Q... +\newdimen\!ht %.A..X.......P....S. +\newdimen\!leaderlength %......D..U......... +\newdimen\!lshrinkage %.................S. +\newdimen\!midarclength %...............Q... +\newdimen\!offset %.A................T +\newdimen\!plotheadingoffset %.A................. +\newdimen\!plotsymbolxshift %..........L..O..... +\newdimen\!plotsymbolyshift %..........L..O..... +\newdimen\!plotxorigin %..........L..O..... +\newdimen\!plotyorigin %..........L..O..... +\newdimen\!rootten %...........G....... +\newdimen\!rshrinkage %.................S. +\newdimen\!shadesymbolxshift %.................S. +\newdimen\!shadesymbolyshift %.................S. +\newdimen\!tenAa %...........G....... +\newdimen\!tenAc %...........G....... +\newdimen\!tenAe %...........G....... +\newdimen\!tshrinkage %.................S. +\newdimen\!uplength %..........L........ +\newdimen\!wd %....X.......P....S. +\newdimen\!wmax %...............Q... +\newdimen\!wmin %...............Q... +\newdimen\!xB %...............Q... +\newdimen\!xC %...............Q... +\newdimen\!xE %..W.....E.L....Q.S. +\newdimen\!xM %..W.....E......Q.S. +\newdimen\!xS %..W.....E.L....Q.S. +\newdimen\!xaxislength %.A................T +\newdimen\!xdiff %..........L........ +\newdimen\!xleft %............P...... +\newdimen\!xloc %..WB.....U.......S. +\newdimen\!xorigin %.A........L.P....S. +\newdimen\!xpivot %................R.. +\newdimen\!xpos %..........L.P..Q.ST +\newdimen\!xprime %...............Q... +\newdimen\!xright %............P...... +\newdimen\!xshade %.................S. +\newdimen\!xshift %..W.........PO...S. +\newdimen\!xtemp %............P...... +\newdimen\!xunit %.AWBX...EUL.P..QRS. +\newdimen\!xxE %........E.......... +\newdimen\!xxM %........E.......... +\newdimen\!xxS %........E.......... +\newdimen\!xxloc %..WB....EU......... +\newdimen\!yB %...............Q... +\newdimen\!yC %...............Q... +\newdimen\!yE %..W.....E.L....Q... +\newdimen\!yM %..W.....E......Q... +\newdimen\!yS %..W.....E.L....Q... +\newdimen\!yaxislength %.A................T +\newdimen\!ybot %............P...... +\newdimen\!ydiff %..........L........ +\newdimen\!yloc %..WB.....U.......S. +\newdimen\!yorigin %.A........L.P....S. +\newdimen\!ypivot %................R.. +\newdimen\!ypos %..........L.P..Q.ST +\newdimen\!yprime %...............Q... +\newdimen\!yshade %.................S. +\newdimen\!yshift %..W.........PO...S. +\newdimen\!ytemp %............P...... +\newdimen\!ytop %............P...... +\newdimen\!yunit %.AWBX...EUL.P..QRS. +\newdimen\!yyE %........E.......... +\newdimen\!yyM %........E.......... +\newdimen\!yyS %........E.......... +\newdimen\!yyloc %..WB....EU......... +\newdimen\!zpt %.AWBX.DVEULGP.YQ.ST + +\newif\if!axisvisible %.A................. +\newif\if!gridlinestoo %..................T +\newif\if!keepPO %................... +\newif\if!placeaxislabel %.A................. +\newif\if!switch %H.................. +\newif\if!xswitch %.A................T + +\newtoks\!axisLaBeL %.A................. +\newtoks\!keywordtoks %.A................. + +\newwrite\!replotfile %.............O..... + +\newhelp\!keywordhelp{The keyword mentioned in the error message in unknown. +Replace NEW KEYWORD in the indicated response by the keyword that +should have been specified.} %.A................. + +% The following commands assign alternate names to some of the +% above registers. "\!wlet" is defined in Hacks. +\!wlet\!!origin=\!xM %.A................T +\!wlet\!!unit=\!uplength %.A................T +\!wlet\!Lresiduallength=\!dimenG %.........U......... +\!wlet\!Rresiduallength=\!dimenF %.........U......... +\!wlet\!axisLength=\!distacross %.A................T +\!wlet\!axisend=\!ydiff %.A................T +\!wlet\!axisstart=\!xdiff %.A................T +\!wlet\!axisxlevel=\!arclength %.A................T +\!wlet\!axisylevel=\!downlength %.A................T +\!wlet\!beta=\!dimenE %...............Q... +\!wlet\!gamma=\!dimenF %...............Q... +\!wlet\!shadexorigin=\!plotxorigin %.................S. +\!wlet\!shadeyorigin=\!plotyorigin %.................S. +\!wlet\!ticklength=\!xS %..................T +\!wlet\!ticklocation=\!xE %..................T +\!wlet\!ticklocationincr=\!yE %..................T +\!wlet\!tickwidth=\!yS %..................T +\!wlet\!totalleaderlength=\!dimenE %.........U......... +\!wlet\!xone=\!xprime %....X.............. +\!wlet\!xtwo=\!dxprime %....X.............. +\!wlet\!ySsave=\!yM %................... +\!wlet\!ybB=\!yB %.................S. +\!wlet\!ybC=\!yC %.................S. +\!wlet\!ybE=\!yE %.................S. +\!wlet\!ybM=\!yM %.................S. +\!wlet\!ybS=\!yS %.................S. +\!wlet\!ybpos=\!yyloc %.................S. +\!wlet\!yone=\!yprime %....X.............. +\!wlet\!ytB=\!xB %.................S. +\!wlet\!ytC=\!xC %.................S. +\!wlet\!ytE=\!downlength %.................S. +\!wlet\!ytM=\!arclength %.................S. +\!wlet\!ytS=\!distacross %.................S. +\!wlet\!ytpos=\!xxloc %.................S. +\!wlet\!ytwo=\!dyprime %....X.............. + + +% Initial values for registers +\!zpt=0pt % static +\!xunit=1pt +\!yunit=1pt +\!arearloc=\!xunit +\!areatloc=\!yunit +\!dshade=5pt +\!leaderlength=24in +\!tfs=256 % static +\!wmax=5.3pt % static +\!wmin=2.7pt % static +\!xaxislength=\!xunit +\!xpivot=\!zpt +\!yaxislength=\!yunit +\!ypivot=\!zpt +\plotsymbolspacing=.4pt + \!dimenA=50pt \!fiftypt=\!dimenA % static + +\!rootten=3.162278pt % static +\!tenAa=8.690286pt % static (A5) +\!tenAc=2.773839pt % static (A3) +\!tenAe=2.543275pt % static (A1) + +% Initial values for control sequences +\def\!cosrotationangle{1} %................R.. +\def\!sinrotationangle{0} %................R.. +\def\!xpivotcoord{0} %................R.. +\def\!xref{0} %............P...... +\def\!xshadesave{0} %.................S. +\def\!ypivotcoord{0} %................R.. +\def\!yref{0} %............P...... +\def\!yshadesave{0} %.................S. +\def\!zero{0} %..................T + +% Reset TeX to report allocations +\let\wlog=\!!!wlog +% ************************************* +% *** AREAS: Deals with plot areas *** +% ************************************* +% +% ** User commands +% ** \setplotarea x from LEFT XCOORD to RIGTH XCOORD, y from BOTTOM YCOORD +% ** to TOP YCOORD +% ** \axis BOTTOM-LEFT-TOP-RIGHT [SHIFTEDTO xy=COORD] [VISIBLE-INVISIBLE] +% ** [LABEL {label}] [TICKS] / +% ** \visibleaxes +% ** \invisibleaxes +% ** \plotheading {HEADING} +% ** \grid {# of columns} {# of rows} +% ** \normalgraphs + +% ** \normalgraphs +% ** Sets defaults for graph setup. See Subsection 3.4 of manual. +\def\normalgraphs{% + \longticklength=.4\baselineskip + \shortticklength=.25\baselineskip + \tickstovaluesleading=.25\baselineskip + \valuestolabelleading=.8\baselineskip + \linethickness=.4pt + \stackleading=.17\baselineskip + \headingtoplotskip=1.5\baselineskip + \visibleaxes + \ticksout + \nogridlines + \unloggedticks} +% +% ** \setplotarea x from LEFT XCOORD to RIGTH XCOORD, y from BOTTOM YCOORD +% ** to TOP YCOORD +% ** Reserves space in PICBOX for a rectangular box with the indicated +% ** coordinates. Must be specified before calls to \axis, +% ** \grid, \plotheading. +% ** See Subsection 3.1 of the manual. +\def\setplotarea x from #1 to #2, y from #3 to #4 {% + \!arealloc=\!M{#1}\!xunit \advance \!arealloc -\!xorigin + \!areabloc=\!M{#3}\!yunit \advance \!areabloc -\!yorigin + \!arearloc=\!M{#2}\!xunit \advance \!arearloc -\!xorigin + \!areatloc=\!M{#4}\!yunit \advance \!areatloc -\!yorigin + \!initinboundscheck + \!xaxislength=\!arearloc \advance\!xaxislength -\!arealloc + \!yaxislength=\!areatloc \advance\!yaxislength -\!areabloc + \!plotheadingoffset=\!zpt + \!dimenput {{\setbox0=\hbox{}\wd0=\!xaxislength\ht0=\!yaxislength\box0}} + [bl] (\!arealloc,\!areabloc)} +% +% ** \visibleaxes, \invisibleaxes +% ** Switches for setting visibility of subsequent axes. +% ** See Subsection 3.2 of the manual. +\def\visibleaxes{% + \def\!axisvisibility{\!axisvisibletrue}} +\def\invisibleaxes{% + \def\!axisvisibility{\!axisvisiblefalse}} +% +% ** The next few macros enable the user to fix up an erroneous keyword +% ** in the \axis command. +% \newhelp is in ALLOCATIONS +% \newhelp\!keywordhelp{The keyword mentioned in the error message in unknown. +% Replace NEW KEYWORD in the indicated response by the keyword that +% should have been specified.} + +\def\!fixkeyword#1{% + \errhelp=\!keywordhelp + \errmessage{Unrecognized keyword `#1': \the\!keywordtoks{NEW KEYWORD}'}} + +% \newtoks\!keywordtoks In ALLOCATIONS. +\!keywordtoks={enter `i\fixkeyword} + +\def\fixkeyword#1{% + \!nextkeyword#1 } + +% ** \axis BOTTOM-LEFT-TOP-RIGHT [SHIFTEDTO xy=COORD] [VISIBLE-INVISIBLE] +% ** [LABEL {label}] [TICKS] / +% ** Exactly one of the keywords BOTTOM, LEFT, TOP, RIGHT must be +% ** specified. Axis is drawn along the indicated edge of the current +% ** plot area, shifted if the SHIFTEDTO option is used, visible or +% ** invisible according the selected option, with an optional LABEL, +% ** and optional TICKS (see ticks.tex for the options avialabel with +% ** TICKS). The TICKS option must be the last one specified. The \axis +% ** MUST be terminated with a / followed by a space. +% ** See Subsection 3.2 of the manual for more information. + +% ** The various options of the \axis command are processed by the +% ** \!nextkeyword macro defined below. For example, +% ** `\!nextkeyword shiftedto ' expands to `\!axisshiftedto'. +\def\axis {% + \def\!nextkeyword##1 {% + \expandafter\ifx\csname !axis##1\endcsname \relax + \def\!next{\!fixkeyword{##1}}% + \else + \def\!next{\csname !axis##1\endcsname}% + \fi + \!next}% + \!offset=\!zpt + \!axisvisibility + \!placeaxislabelfalse + \!nextkeyword} + +% ** This and the various macros that follow handle the keyword +% ** specifications on the \axis command +% ** See Subsection 3.2 of the manual. +\def\!axisbottom{% + \!axisylevel=\!areabloc + \def\!tickxsign{0}% + \def\!tickysign{-}% + \def\!axissetup{\!axisxsetup}% + \def\!axislabeltbrl{t}% + \!nextkeyword} + +\def\!axistop{% + \!axisylevel=\!areatloc + \def\!tickxsign{0}% + \def\!tickysign{+}% + \def\!axissetup{\!axisxsetup}% + \def\!axislabeltbrl{b}% + \!nextkeyword} + +\def\!axisleft{% + \!axisxlevel=\!arealloc + \def\!tickxsign{-}% + \def\!tickysign{0}% + \def\!axissetup{\!axisysetup}% + \def\!axislabeltbrl{r}% + \!nextkeyword} + +\def\!axisright{% + \!axisxlevel=\!arearloc + \def\!tickxsign{+}% + \def\!tickysign{0}% + \def\!axissetup{\!axisysetup}% + \def\!axislabeltbrl{l}% + \!nextkeyword} + +\def\!axisshiftedto#1=#2 {% + \if 0\!tickxsign + \!axisylevel=\!M{#2}\!yunit + \advance\!axisylevel -\!yorigin + \else + \!axisxlevel=\!M{#2}\!xunit + \advance\!axisxlevel -\!xorigin + \fi + \!nextkeyword} + +\def\!axisvisible{% + \!axisvisibletrue + \!nextkeyword} + +\def\!axisinvisible{% + \!axisvisiblefalse + \!nextkeyword} + +\def\!axislabel#1 {% + \!axisLaBeL={#1}% + \!placeaxislabeltrue + \!nextkeyword} + +\expandafter\def\csname !axis/\endcsname{% + \!axissetup % This could done already by "ticks"; if so, now \relax + \if!placeaxislabel + \!placeaxislabel + \fi + \if +\!tickysign % ** (A "top" axis) + \!dimenA=\!axisylevel + \advance\!dimenA \!offset % ** dimA = top of the axis structure + \advance\!dimenA -\!areatloc % ** dimA = excess over the plot area + \ifdim \!dimenA>\!plotheadingoffset + \!plotheadingoffset=\!dimenA % ** Greatest excess over the plot area + \fi + \fi} + +% ** \grid {c} {r} +% ** Partitions the plot area into c columns and r rows; see Subsection 3.3 +% ** of the manual. +% ** (Other grid patterns can be drawn with the TICKS option of the \axis +% ** command. +\def\grid #1 #2 {% + \!countA=#1\advance\!countA 1 + \axis bottom invisible ticks length <\!zpt> andacross quantity {\!countA} / + \!countA=#2\advance\!countA 1 + \axis left invisible ticks length <\!zpt> andacross quantity {\!countA} / } + +% ** \plotheading{HEADING} +% ** Places HEADING centered above the top of the plotarea (and above +% ** any top axis ticks marks, tick labels, and axis label); see +% ** Subsection 3.3 of the manual. +\def\plotheading#1 {% + \advance\!plotheadingoffset \headingtoplotskip + \!dimenput {#1} [B] <.5\!xaxislength,\!plotheadingoffset> + (\!arealloc,\!areatloc)} + +% ** From here on, the routines are internal. +\def\!axisxsetup{% + \!axisxlevel=\!arealloc + \!axisstart=\!arealloc + \!axisend=\!arearloc + \!axisLength=\!xaxislength + \!!origin=\!xorigin + \!!unit=\!xunit + \!xswitchtrue + \if!axisvisible + \!makeaxis + \fi} + +\def\!axisysetup{% + \!axisylevel=\!areabloc + \!axisstart=\!areabloc + \!axisend=\!areatloc + \!axisLength=\!yaxislength + \!!origin=\!yorigin + \!!unit=\!yunit + \!xswitchfalse + \if!axisvisible + \!makeaxis + \fi} + +\def\!makeaxis{% + \setbox\!boxA=\hbox{% (Make a pseudo-y[x] tick for an x[y]-axis) + \beginpicture + \!setdimenmode + \setcoordinatesystem point at {\!zpt} {\!zpt} + \putrule from {\!zpt} {\!zpt} to + {\!tickysign\!tickysign\!axisLength} + {\!tickxsign\!tickxsign\!axisLength} + \endpicturesave <\!Xsave,\!Ysave>}% + \wd\!boxA=\!zpt + \!placetick\!axisstart} + +\def\!placeaxislabel{% + \advance\!offset \valuestolabelleading + \if!xswitch + \!dimenput {\the\!axisLaBeL} [\!axislabeltbrl] + <.5\!axisLength,\!tickysign\!offset> (\!axisxlevel,\!axisylevel) + \advance\!offset \!dp % ** advance offset by the "tallness" + \advance\!offset \!ht % ** of the label + \else + \!dimenput {\the\!axisLaBeL} [\!axislabeltbrl] + <\!tickxsign\!offset,.5\!axisLength> (\!axisxlevel,\!axisylevel) + \fi + \!axisLaBeL={}} + + +% ******************************* +% *** ARROWS (Draws arrows) *** +% ******************************* +% +% ** User commands +% ** \arrow [MID FRACTION, BASE FRACTION] +% ** [] from XFROM YFROM to XTO YTO +% ** \betweenarrows {TEXT} [orientation & shift] from XFROM YFROM to XTO YTO + +% ** \arrow [MID FRACTION, BASE FRACTION] +% ** [] from XFROM YFROM to XTO YTO +% ** Draws an arrow from (XFROM,YFROM) to (XTO,YTO). The arrow head +% ** is constructed two quadratic arcs, which extend back a distance +% ** ARROW HEAD LENGTH (a dimension) on both sides of the arrow shaft. +% ** All the way back the arcs are a distance BASE FRACTION*ARROW HEAD +% ** LENGTH apart, while half-way back they are a distance MID FRACTION* +% ** ARROW HEAD LENGTH apart. is optional, and has +% ** its usual interpreation. See Subsection 5.4 of the manual. + +\def\arrow <#1> [#2,#3]{% + \!ifnextchar<{\!arrow{#1}{#2}{#3}}{\!arrow{#1}{#2}{#3}<\!zpt,\!zpt> }} + +\def\!arrow#1#2#3<#4,#5> from #6 #7 to #8 #9 {% +% +% ** convert to dimensions + \!xloc=\!M{#8}\!xunit + \!yloc=\!M{#9}\!yunit + \!dxpos=\!xloc \!dimenA=\!M{#6}\!xunit \advance \!dxpos -\!dimenA + \!dypos=\!yloc \!dimenA=\!M{#7}\!yunit \advance \!dypos -\!dimenA + \let\!MAH=\!M% ** save current c/d mode + \!setdimenmode% ** go into dimension mode +% + \!xshift=#4\relax \!yshift=#5\relax% ** pick up shift + \!reverserotateonly\!xshift\!yshift% ** back rotate shift + \advance\!xshift\!xloc \advance\!yshift\!yloc +% +% ** draw shaft of arrow + \!xS=-\!dxpos \advance\!xS\!xshift + \!yS=-\!dypos \advance\!yS\!yshift + \!start (\!xS,\!yS) + \!ljoin (\!xshift,\!yshift) +% +% ** find 32*cosine and 32*sine of angle of rotation + \!Pythag\!dxpos\!dypos\!arclength + \!divide\!dxpos\!arclength\!dxpos + \!dxpos=32\!dxpos \!removept\!dxpos\!!cos + \!divide\!dypos\!arclength\!dypos + \!dypos=32\!dypos \!removept\!dypos\!!sin +% +% ** construct arrowhead + \!halfhead{#1}{#2}{#3}% ** draw half of arrow head + \!halfhead{#1}{-#2}{-#3}% ** draw other half +% + \let\!M=\!MAH% ** restore old c/d mode + \ignorespaces} +% +% ** draw half of arrow head + \def\!halfhead#1#2#3{% + \!dimenC=-#1% + \divide \!dimenC 2 % ** half way back + \!dimenD=#2\!dimenC% ** half the mid width + \!rotate(\!dimenC,\!dimenD)by(\!!cos,\!!sin)to(\!xM,\!yM) + \!dimenC=-#1% ** all the way back + \!dimenD=#3\!dimenC + \!dimenD=.5\!dimenD% ** half the full width + \!rotate(\!dimenC,\!dimenD)by(\!!cos,\!!sin)to(\!xE,\!yE) + \!start (\!xshift,\!yshift) + \advance\!xM\!xshift \advance\!yM\!yshift + \advance\!xE\!xshift \advance\!yE\!yshift + \!qjoin (\!xM,\!yM) (\!xE,\!yE) + \ignorespaces} + + +% ** \betweenarrows {TEXT} [orientation & shift] from XFROM YFROM to XTO YTO +% ** Makes things like <--- text --->, using arrow heads from TeX's fonts. +% ** See Subsection 5.4 of the manual. +\def\betweenarrows #1#2 from #3 #4 to #5 #6 {% + \!xloc=\!M{#3}\!xunit \!xxloc=\!M{#5}\!xunit% + \!yloc=\!M{#4}\!yunit \!yyloc=\!M{#6}\!yunit% + \!dxpos=\!xxloc \advance\!dxpos by -\!xloc + \!dypos=\!yyloc \advance\!dypos by -\!yloc + \advance\!xloc .5\!dxpos + \advance\!yloc .5\!dypos +% + \let\!MBA=\!M% ** save current coord\dimen mode + \!setdimenmode% ** express locations in dimens + \ifdim\!dypos=\!zpt + \ifdim\!dxpos<\!zpt \!dxpos=-\!dxpos \fi + \put {\!lrarrows{\!dxpos}{#1}}#2{} at {\!xloc} {\!yloc} + \else + \ifdim\!dxpos=\!zpt + \ifdim\!dypos<\!zpt \!dypos=-\!zpt \fi + \put {\!udarrows{\!dypos}{#1}}#2{} at {\!xloc} {\!yloc} + \fi + \fi + \let\!M=\!MBA% ** restore previous c/d mode + \ignorespaces} + +% ** Subroutine for left-right between arrows +\def\!lrarrows#1#2{% #1=width, #2=text + {\setbox\!boxA=\hbox{$\mkern-2mu\mathord-\mkern-2mu$}% + \setbox\!boxB=\hbox{$\leftarrow$}\!dimenE=\ht\!boxB + \setbox\!boxB=\hbox{}\ht\!boxB=2\!dimenE + \hbox to #1{$\mathord\leftarrow\mkern-6mu + \cleaders\copy\!boxA\hfil + \mkern-6mu\mathord-$% + \kern.4em $\vcenter{\box\!boxB}$$\vcenter{\hbox{#2}}$\kern.4em + $\mathord-\mkern-6mu + \cleaders\copy\!boxA\hfil + \mkern-6mu\mathord\rightarrow$}}} + +% ** Subroutine for up-down between arrows +\def\!udarrows#1#2{% #1=width, #2=text + {\setbox\!boxB=\hbox{#2}% + \setbox\!boxA=\hbox to \wd\!boxB{\hss$\vert$\hss}% + \!dimenE=\ht\!boxA \advance\!dimenE \dp\!boxA \divide\!dimenE 2 + \vbox to #1{\offinterlineskip + \vskip .05556\!dimenE + \hbox to \wd\!boxB{\hss$\mkern.4mu\uparrow$\hss}\vskip-\!dimenE + \cleaders\copy\!boxA\vfil + \vskip-\!dimenE\copy\!boxA + \vskip\!dimenE\copy\!boxB\vskip.4em + \copy\!boxA\vskip-\!dimenE + \cleaders\copy\!boxA\vfil + \vskip-\!dimenE \hbox to \wd\!boxB{\hss$\mkern.4mu\downarrow$\hss} + \vskip .05556\!dimenE}}} + + +% *************************** +% *** BARS (Draws bars) *** +% *************************** +% +% ** User commands: +% ** \putbar [] breadth from XSTART YSTART +% ** to XEND YEND +% ** \setbars [] breadth baseline at XY = COORD +% ** [baselabels ([B_ORIENTATION_x,B_ORIENTATION_y] )] +% ** [endlabels ([E_ORIENTATION_x,E_ORIENTATION_y] )] + + +% ** \putbar [] breadth from XSTART YSTART +% ** to XEND YEND +% ** Either XSTART=XEND or YSTART=YEND. Draws a rectangle between +% ** (XSTART,YSTART) & (XEND,YEND). The "depth" of the rectangle +% ** is determined by those two plot positions; its other +% ** dimension "breadth" is specified by the dimension BREADTH. +% ** See Subsection 4.2 of the manual. +\def\putbar#1breadth <#2> from #3 #4 to #5 #6 {% + \!xloc=\!M{#3}\!xunit \!xxloc=\!M{#5}\!xunit% + \!yloc=\!M{#4}\!yunit \!yyloc=\!M{#6}\!yunit% + \!dypos=\!yyloc \advance\!dypos by -\!yloc + \!dimenI=#2 +% + \ifdim \!dimenI=\!zpt % ** If 0 breadth + \putrule#1from {#3} {#4} to {#5} {#6} % ** Then draw line + \else % ** Else, put in a rectangle + \let\!MBar=\!M% ** save current c/d mode + \!setdimenmode % ** go into dimension mode + \divide\!dimenI 2 + \ifdim \!dypos=\!zpt + \advance \!yloc -\!dimenI % ** Equal y coordinates + \advance \!yyloc \!dimenI + \else + \advance \!xloc -\!dimenI % ** Equal x coordinates + \advance \!xxloc \!dimenI + \fi + \putrectangle#1corners at {\!xloc} {\!yloc} and {\!xxloc} {\!yyloc} + \let\!M=\!MBar % ** restore c/d mode + \fi + \ignorespaces} + + +% ** \setbars [] breadth baseline at XY = COORD +% ** [baselabels ([B_ORIENTATION_x,B_ORIENTATION_y] )] +% ** [endlabels ([E_ORIENTATION_x,E_ORIENTATION_y] )] +% ** This command puts PiCTeX into the bar graph drawing mode described +% ** in Subsection 4.4 of the manual. +\def\setbars#1breadth <#2> baseline at #3 = #4 {% + \edef\!barshift{#1}% + \edef\!barbreadth{#2}% + \edef\!barorientation{#3}% + \edef\!barbaseline{#4}% + \def\!bardobaselabel{\!bardoendlabel}% + \def\!bardoendlabel{\!barfinish}% + \let\!drawcurve=\!barcurve + \!setbars} +\def\!setbars{% + \futurelet\!nextchar\!!setbars} +\def\!!setbars{% + \if b\!nextchar + \def\!!!setbars{\!setbarsbget}% + \else + \if e\!nextchar + \def\!!!setbars{\!setbarseget}% + \else + \def\!!!setbars{\relax}% + \fi + \fi + \!!!setbars} +\def\!setbarsbget baselabels (#1) {% + \def\!barbaselabelorientation{#1}% + \def\!bardobaselabel{\!!bardobaselabel}% + \!setbars} +\def\!setbarseget endlabels (#1) {% + \edef\!barendlabelorientation{#1}% + \def\!bardoendlabel{\!!bardoendlabel}% + \!setbars} + +% ** \!barcurve +% ** Draws a bargraph with preset values of barshift, barbreadth, +% ** barorientation (x or y) and barbaseline (coordinate) +\def\!barcurve #1 #2 {% + \if y\!barorientation + \def\!basexarg{#1}% + \def\!baseyarg{\!barbaseline}% + \else + \def\!basexarg{\!barbaseline}% + \def\!baseyarg{#2}% + \fi + \expandafter\putbar\!barshift breadth <\!barbreadth> from {\!basexarg} + {\!baseyarg} to {#1} {#2} + \def\!endxarg{#1}% + \def\!endyarg{#2}% + \!bardobaselabel} + +\def\!!bardobaselabel "#1" {% + \put {#1}\!barbaselabelorientation{} at {\!basexarg} {\!baseyarg} + \!bardoendlabel} + +\def\!!bardoendlabel "#1" {% + \put {#1}\!barendlabelorientation{} at {\!endxarg} {\!endyarg} + \!barfinish} + +\def\!barfinish{% + \!ifnextchar/{\!finish}{\!barcurve}} + + +% ******************************** +% *** BOXES (Draws rectangles) *** +% ******************************** +% +% ** User commands: +% ** \putrectangle [] corners at XCOORD1 YCOORD1 +% ** and XCOORD2 YCOORD2 +% ** \shaderectangleson +% ** \shaderectanglesoff +% ** \frame [] {TEXT} +% ** \rectangle +% +% +% ** \putrectangle [] corners at XCOORD1 YCOORD1 +% ** and XCOORD2 YCOORD2 +% ** Draws a rectangle with corners at (X1,Y1), (X2,Y1), (X1,Y2), (X2,Y2) +% ** Lines have thickness \linethickness, and overlap at the corners. +% ** The optional field functions as with a \put command. +% ** See Subsection 4.2 of the manual. +\def\putrectangle{% + \!ifnextchar<{\!putrectangle}{\!putrectangle<\!zpt,\!zpt> }} +\def\!putrectangle<#1,#2> corners at #3 #4 and #5 #6 {% +% +% ** get locations + \!xone=\!M{#3}\!xunit \!xtwo=\!M{#5}\!xunit% + \!yone=\!M{#4}\!yunit \!ytwo=\!M{#6}\!yunit% + \ifdim \!xtwo<\!xone + \!dimenI=\!xone \!xone=\!xtwo \!xtwo=\!dimenI + \fi + \ifdim \!ytwo<\!yone + \!dimenI=\!yone \!yone=\!ytwo \!ytwo=\!dimenI + \fi + \!dimenI=#1\relax \advance\!xone\!dimenI \advance\!xtwo\!dimenI + \!dimenI=#2\relax \advance\!yone\!dimenI \advance\!ytwo\!dimenI + \let\!MRect=\!M% ** save current coord/dimen mode + \!setdimenmode +% +% ** shade rectangle if appropriate + \!shaderectangle +% +% ** draw horizontal edges + \!dimenI=.5\linethickness + \advance \!xone -\!dimenI% ** adjust x-location to overlap corners + \advance \!xtwo \!dimenI% ** ditto + \putrule from {\!xone} {\!yone} to {\!xtwo} {\!yone} + \putrule from {\!xone} {\!ytwo} to {\!xtwo} {\!ytwo} +% +% ** draw vertical edges + \advance \!xone \!dimenI% ** restore original x-values + \advance \!xtwo -\!dimenI% + \advance \!yone -\!dimenI% ** adjust y-location to overlap corners + \advance \!ytwo \!dimenI% ** ditto + \putrule from {\!xone} {\!yone} to {\!xone} {\!ytwo} + \putrule from {\!xtwo} {\!yone} to {\!xtwo} {\!ytwo} +% + \let\!M=\!MRect% ** restore coord/dimen mode + \ignorespaces} + +% ** \shaderectangleson +% ** Subsequent rectangles will be shaded according to +% ** the current shading pattern. Affects \putrectangle, \putbar, +% ** \frame, \sethistograms, and \setbars. See Subsection 7.5 of the manual. +\def\shaderectangleson{% + \def\!shaderectangle{\!!shaderectangle}% + \ignorespaces} +% ** \shaderectanglesoff +% ** Suppresses \shaderectangleson. The default. +\def\shaderectanglesoff{% + \def\!shaderectangle{}% + \ignorespaces} + +\shaderectanglesoff + +% ** The following internal routine shades the current rectangle, when +% ** \!shaderectangle = \!!shaderectangle . +\def\!!shaderectangle{% + \!dimenA=\!xtwo \advance \!dimenA -\!xone + \!dimenB=\!ytwo \advance \!dimenB -\!yone + \ifdim \!dimenA<\!dimenB + \!startvshade (\!xone,\!yone,\!ytwo) + \!lshade (\!xtwo,\!yone,\!ytwo) + \else + \!starthshade (\!yone,\!xone,\!xtwo) + \!lshade (\!ytwo,\!xone,\!xtwo) + \fi + \ignorespaces} + +% ** \frame [] {TEXT} +% ** Draws a frame of thickness linethickness about the box enclosing +% ** TEXT; the frame is separated from the box by a distance of +% ** SEPARATION. The result is an hbox with the same baseline as TEXT. +% ** If is omitted, you get the effect of <0pt>. +% ** See Subsection 4.2 of the manual. +\def\frame{% + \!ifnextchar<{\!frame}{\!frame<\!zpt> }} +\long\def\!frame<#1> #2{% + \beginpicture + \setcoordinatesystem units <1pt,1pt> point at 0 0 + \put {#2} [Bl] at 0 0 + \!dimenA=#1\relax + \!dimenB=\!wd \advance \!dimenB \!dimenA + \!dimenC=\!ht \advance \!dimenC \!dimenA + \!dimenD=\!dp \advance \!dimenD \!dimenA + \let\!MFr=\!M + \!setdimenmode + \putrectangle corners at {-\!dimenA} {-\!dimenD} and {\!dimenB} {\!dimenC} + \!setcoordmode + \let\!M=\!MFr + \endpicture + \ignorespaces} + +% ** \rectangle +% ** Constructs a rectangle of width WIDTH and heigth HEIGHT. +% ** See Subsection 4.2 of the manual. +\def\rectangle <#1> <#2> {% + \setbox0=\hbox{}\wd0=#1\ht0=#2\frame {\box0}} + + +% ********************************************* +% *** CURVES (Upper level \plot commands) *** +% ********************************************* +% +% ** User commands +% ** \plot DATA / +% ** \plot "FILE NAME" +% ** \setquadratic +% ** \setlinear +% ** \sethistograms +% ** \vshade ... +% ** \hshade ... + +% \plot: multi-purpose command. Draws histograms, bar graphs, piecewise-linear +% or piecewise quadratic curves, depending on the setting of \!drawcurve. +% See Subsections 4.3-4.5, 5.1, 5.2 of the manual. +\def\plot{% + \!ifnextchar"{\!plotfromfile}{\!drawcurve}} +\def\!plotfromfile"#1"{% + \expandafter\!drawcurve \normalinput #1 /} + +% Command to set piecewise quadratic mode +% See Subsections 5.1, 7.3, and 7.4 of the manual. +\def\setquadratic{% + \let\!drawcurve=\!qcurve + \let\!!Shade=\!!qShade + \let\!!!Shade=\!!!qShade} + +% Command to set piecewise linear mode +% See Subsections 5.1, 7.3, and 7.4 of the manual. +\def\setlinear{% + \let\!drawcurve=\!lcurve + \let\!!Shade=\!!lShade + \let\!!!Shade=\!!!lShade} + +% Command to set histogram mode +% See Subsection 4.3 of the manual. +\def\sethistograms{% + \let\!drawcurve=\!hcurve} + +% Commands to cycle through list of coordinates in piecewise quadratic +% interpolation mode +\def\!qcurve #1 #2 {% + \!start (#1,#2) + \!Qjoin} +\def\!Qjoin#1 #2 #3 #4 {% + \!qjoin (#1,#2) (#3,#4) % \!qjoin is defined in QUADRATIC + \!ifnextchar/{\!finish}{\!Qjoin}} + +% Commands to cycle through list of coordinates in piecewise linear +% interpolation mode +\def\!lcurve #1 #2 {% + \!start (#1,#2) + \!Ljoin} +\def\!Ljoin#1 #2 {% + \!ljoin (#1,#2) % \!ljoin is defined in LINEAR + \!ifnextchar/{\!finish}{\!Ljoin}} + +\def\!finish/{\ignorespaces} + +% Command to cycle through list of coordinates in histogram mode +\def\!hcurve #1 #2 {% + \edef\!hxS{#1}% + \edef\!hyS{#2}% + \!hjoin} +\def\!hjoin#1 #2 {% + \putrectangle corners at {\!hxS} {\!hyS} and {#1} {#2} + \edef\!hxS{#1}% + \!ifnextchar/{\!finish}{\!hjoin}} + + +% \vshade: See Subsection 7.3 of the manual. +\def\vshade #1 #2 #3 {% + \!startvshade (#1,#2,#3) + \!Shadewhat} + +% \hshade: See Subsection 7.4 of the manual. +\def\hshade #1 #2 #3 {% + \!starthshade (#1,#2,#3) + \!Shadewhat} + +% Commands to cycle through coordinates and optional "edge effect" +% fields while shading. +\def\!Shadewhat{% + \futurelet\!nextchar\!Shade} +\def\!Shade{% + \if <\!nextchar + \def\!nextShade{\!!Shade}% + \else + \if /\!nextchar + \def\!nextShade{\!finish}% + \else + \def\!nextShade{\!!!Shade}% + \fi + \fi + \!nextShade} +\def\!!lShade<#1> #2 #3 #4 {% + \!lshade <#1> (#2,#3,#4) % \!lshade is defined in SHADING + \!Shadewhat} +\def\!!!lShade#1 #2 #3 {% + \!lshade (#1,#2,#3) + \!Shadewhat} +\def\!!qShade<#1> #2 #3 #4 #5 #6 #7 {% + \!qshade <#1> (#2,#3,#4) (#5,#6,#7) % \!qshade is defined in SHADING + \!Shadewhat} +\def\!!!qShade#1 #2 #3 #4 #5 #6 {% + \!qshade (#1,#2,#3) (#4,#5,#6) + \!Shadewhat} + +% ** Set default interpolation mode +\setlinear + + +% ******************************************** +% *** DASHPATTERNS (Sets up dash patterns) *** +% ******************************************** + +% ** User commands: +% ** \setdashpattern +% ** \setdots +% ** \setdotsnear for +% ** \setdashes +% ** \setdashesnear for +% ** \setsolid +% ** \findlength {CURVE CMDS} + +% ** Internal commands: +% ** \!dashingon +% ** \!dashingoff + +% ** Dash patterns are specified by a balanced token list whose complete +% ** expansion has the form: DIMEN1,DIMEN2,DIMEN3,DIMEN4,... ; this produces +% ** an arc of length DIMEN1, a skip of length DIMEN2, an arc of length +% ** DIMEN3, a skip of length DIMEN4, ... . Any number of DIMEN values may +% ** be given. The pattern is repeated as many times (perhaps fractional) +% ** as necessary to draw the curve. +% ** A dash pattern remains in effect until it is overridden by a call to +% ** \setdashpattern, or to \setdots, \setdotsnear ... , \setdashes, +% ** \setdashesnear ... , or \setsolid. +% ** Solid lines are the default. + + +% ** \def\setdashpattern +% ** The following routine converts a balanced list of tokens whose +% ** complete expansion has the form DIMEN1,DIMEN2, ... , DIMENk into +% ** three list macros that are used in drawing dashed rules and curves: +% ** !Flist: \!Rule{DIMEN1}\!Skip{DIMEN2}\!Rule{DIMEN3}\!Skip{DIMEN4} ... +% ** !Blist: ...\!Skip{DIMEN4}\!Rule{DIMEN3}\!Skip{DIMEN2}\!Rule{DIMEN1} +% ** !UDlist: \\{DIMEN1}\\{DIMEN2}\\{DIMEN3}\\{DIMEN4} ...; +% ** calculates \!leaderlength := DIMEN1 + ... + DIMENk; and +% ** sets the curve drawing routines to dash mode. +% ** Those lists are used by the curve drawing routines. +% ** Dimenj ... may be given as an explicit dimension (e.g., 5pt), or +% ** as an expression involving a dimension register (e.g., -2.5\dimen0). +% ** See Subsection 6.2 of the manual +\def\setdashpattern <#1>{% + \def\!Flist{}\def\!Blist{}\def\!UDlist{}% + \!countA=0 + \!ecfor\!item:=#1\do{% + \!dimenA=\!item\relax + \expandafter\!rightappend\the\!dimenA\withCS{\\}\to\!UDlist% + \advance\!countA 1 + \ifodd\!countA + \expandafter\!rightappend\the\!dimenA\withCS{\!Rule}\to\!Flist% + \expandafter\!leftappend\the\!dimenA\withCS{\!Rule}\to\!Blist% + \else + \expandafter\!rightappend\the\!dimenA\withCS{\!Skip}\to\!Flist% + \expandafter\!leftappend\the\!dimenA\withCS{\!Skip}\to\!Blist% + \fi}% + \!leaderlength=\!zpt + \def\!Rule##1{\advance\!leaderlength ##1}% + \def\!Skip##1{\advance\!leaderlength ##1}% + \!Flist% + \ifdim\!leaderlength>\!zpt + \else + \def\!Flist{\!Skip{24in}}\def\!Blist{\!Skip{24in}}\ignorespaces + \def\!UDlist{\\{\!zpt}\\{24in}}\ignorespaces + \!leaderlength=24in + \fi + \!dashingon} + + +% ** \!dashingon -- puts the curve drawing routines into dash mode +% ** \!dashingoff -- puts the curve drawing routines into solid mode +% ** These are internal commands, invoked by \setdashpattern and \setsolid +\def\!dashingon{% + \def\!advancedashing{\!!advancedashing}% + \def\!drawlinearsegment{\!lineardashed}% + \def\!puthline{\!putdashedhline}% + \def\!putvline{\!putdashedvline}% +% \def\!putsline{\!putdashedsline}% + \ignorespaces}% +\def\!dashingoff{% + \def\!advancedashing{\relax}% + \def\!drawlinearsegment{\!linearsolid}% + \def\!puthline{\!putsolidhline}% + \def\!putvline{\!putsolidvline}% +% \def\!putsline{\!putsolidsline}% + \ignorespaces} + + +% ** \setdots -- sets up a dot/skip pattern where dot (actually +% ** the current plotsymbol) is plunked down once for every LENGTH +% ** traveled along the curve. LENGTH defaults to 5pt. +% ** See Subsection 6.1 of the manual. +\def\setdots{% + \!ifnextchar<{\!setdots}{\!setdots<5pt>}} +\def\!setdots<#1>{% + \!dimenB=#1\advance\!dimenB -\plotsymbolspacing + \ifdim\!dimenB<\!zpt + \!dimenB=\!zpt + \fi +\setdashpattern <\plotsymbolspacing,\!dimenB>} + +% ** \setdotsnear for +% ** sets up a dot pattern where the dots are approximately LENGTH apart, +% ** the total length of the pattern is ARC LENGTH, and the pattern +% ** begins and ends with a dot. See Subsection 6.3 of the manual. +\def\setdotsnear <#1> for <#2>{% + \!dimenB=#2\relax \advance\!dimenB -.05pt + \!dimenC=#1\relax \!countA=\!dimenC + \!dimenD=\!dimenB \advance\!dimenD .5\!dimenC \!countB=\!dimenD + \divide \!countB \!countA + \ifnum 1>\!countB + \!countB=1 + \fi + \divide\!dimenB \!countB + \setdots <\!dimenB>} + +% ** \setdashes -- sets up a dash/skip pattern where the dash +% ** and the skip are each of length LENGTH (the dash is formed by +% ** plunking down the current plotsymbol over an arc of length LENGTH +% ** and so may actually be longer than LENGTH. LENGTH defaults to 5pt. +% ** See Subsection 6.1 of the manual. +\def\setdashes{% + \!ifnextchar<{\!setdashes}{\!setdashes<5pt>}} +\def\!setdashes<#1>{\setdashpattern <#1,#1>} + +% ** \setdashesnear ... +% ** Like \setdotsnear; the pattern begins and ends with a dash. +% ** See Subsection 6.3 of the manual. +\def\setdashesnear <#1> for <#2>{% + \!dimenB=#2\relax + \!dimenC=#1\relax \!countA=\!dimenC + \!dimenD=\!dimenB \advance\!dimenD .5\!dimenC \!countB=\!dimenD + \divide \!countB \!countA + \ifodd \!countB + \else + \advance \!countB 1 + \fi + \divide\!dimenB \!countB + \setdashes <\!dimenB>} + +% ** \setsolid -- puts the curve drawing routines in "solid line" mode, +% ** the default mode. See Subsection 6.1 of the manual. +\def\setsolid{% + \def\!Flist{\!Rule{24in}}\def\!Blist{\!Rule{24in}}% + \def\!UDlist{\\{24in}\\{\!zpt}}% + \!dashingoff} +\setsolid + +% ** \findlength {CURVE CMDS} +% ** PiCTeX executes the \start, \ljoin, and \qjoin cmds comprising +% ** CURVE CMDS without plotting anything, but stashes the length +% ** of the phantom curve away in \totalarclength. +% ** See Subsection 6.3 of the manual. +\def\findlength#1{% + \begingroup + \setdashpattern <0pt, \maxdimen> + \setplotsymbol ({}) + \dontsavelinesandcurves + #1% + \endgroup + \ignorespaces} + + +% ************************************************************* +% *** DIVISION (Does long division of dimension registers) *** +% ************************************************************* + +% ** User command: +% ** \Divide {DIVIDEND} by {DIVISOR} forming {RESULT} + +% ** Internal command +% ** \!divide{DIVIDEND}{DIVISOR}{RESULT} + +% ** \!divide DIVIDEND [by] DIVISOR [to get] ANSWER +% ** Divides the dimension DIVIDEND by the dimension DIVISOR, placing the +% ** quotient in the dimension register ANSWER. Values are understood to +% ** be in points. E.g. 12.5pt/1.4pt=8.92857pt. +% ** Quotient is accurate to 1/65536pt=2**[-16]pt +% ** |DIVISOR| should be < 2048pt (about 28 inches). +\def\!divide#1#2#3{% + \!dimenB=#1% ** dimB holds current remainder (r) + \!dimenC=#2% ** dimC holds divisor (d) + \!dimenD=\!dimenB% ** dimD holds quotient q=r/d for this + \divide \!dimenD \!dimenC% ** step, in units of scaled pts + \!dimenA=\!dimenD% ** dimA eventually holds answer (a) + \multiply\!dimenD \!dimenC% ** r <-- r - dq + \advance\!dimenB -\!dimenD% ** First step complete. Have integer part +% ** of a, and corresponding remainder. + \!dimenD=\!dimenC% ** Temporarily use dimD to hold |d| + \ifdim\!dimenD<\!zpt \!dimenD=-\!dimenD + \fi + \ifdim\!dimenD<64pt% ** Branch on the magnitude of |d| + \!divstep[\!tfs]\!divstep[\!tfs]% + \else + \!!divide + \fi + #3=\!dimenA\ignorespaces} + +% ** The following code handles divisors d with +% ** (1) .88in = 64pt <= d < 256pt = 3.54in +% ** (2) 3.54in = 256pt <= d < 2048pt = 28.34in +% ** Anything bigger than that may result in an overflow condition. +% ** For our purposes, we should never even see case (2). +\def\!!divide{% + \ifdim\!dimenD<256pt + \!divstep[64]\!divstep[32]\!divstep[32]% + \else + \!divstep[8]\!divstep[8]\!divstep[8]\!divstep[8]\!divstep[8]% + \!dimenA=2\!dimenA + \fi} + + +% ** The following macro does the real long division work. +\def\!divstep[#1]{% ** #1 = "B" + \!dimenB=#1\!dimenB% ** r <-- B*r + \!dimenD=\!dimenB% ** dimD holds quotient q=r/d for this + \divide \!dimenD by \!dimenC% ** step, in units of scaled pts + \!dimenA=#1\!dimenA% ** a <-- B*a + q + \advance\!dimenA by \!dimenD% + \multiply\!dimenD by \!dimenC% ** r <-- r - dq + \advance\!dimenB by -\!dimenD} + +% ** \Divide: See Subsection 9.3 of the manual. +\def\Divide <#1> by <#2> forming <#3> {% + \!divide{#1}{#2}{#3}} + + +% ********************************************* +% *** ELLIPSES (Draws ellipses and circles) *** +% ********************************************* + +% ** User commands +% ** \ellipticalarc axes ratio A:B DEGREES degrees from XSTART YSTART +% ** center at XCENTER YCENTER +% ** \circulararc DEGREES degrees from XSTART YSTART +% ** center at XCENTER YCENTER + +% ** Internal command +% ** \!sinandcos{32*ANGLE in radians}{32*SIN}{32*COS} + + +% ** \ellipticalarc axes ratio A:B DEGREES degrees from XSTART YSTART +% ** center at XCENTER YCENTER +% ** Draws a elliptical arc starting at the coordinate point (XSTART,YSTART). +% ** The center of the ellipse of which the arc is a segment is at +% ** (XCENTER,YCENTER). +% ** The arc extends through an angle of DEGREES degrees (may be + or -). +% ** A:B is the ratio of the length of the xaxis to the length of +% ** the yaxis of the ellipse +% ** Sqrt{[(XSTART-XCENTER)/A]**2 + [(YSTART-YCENTER)/B]**2} +% ** must be < 512pt (about 7in). +% ** Doesn't modify the dimensions (ht, dp, wd) of the PiCture under +% ** construction. + +% ** \circulararc -- See Subsection 5.3 of the manual. +\def\circulararc{% + \ellipticalarc axes ratio 1:1 } + +% ** \ellipticalarc -- See Subsection 5.3 of the manual. +\def\ellipticalarc axes ratio #1:#2 #3 degrees from #4 #5 center at #6 #7 {% + \!angle=#3pt\relax% ** get angle + \ifdim\!angle>\!zpt + \def\!sign{}% ** counterclockwise + \else + \def\!sign{-}\!angle=-\!angle% ** clockwise + \fi + \!xxloc=\!M{#6}\!xunit% ** convert CENTER to dimension + \!yyloc=\!M{#7}\!yunit + \!xxS=\!M{#4}\!xunit% ** get STARTing point on rim of ellipse + \!yyS=\!M{#5}\!yunit + \advance\!xxS -\!xxloc% ** make center of ellipse (0,0) + \advance\!yyS -\!yyloc + \!divide\!xxS{#1pt}\!xxS % ** scale point on ellipse to point on + \!divide\!yyS{#2pt}\!yyS % corresponding circle +% + \let\!MC=\!M% ** save current c/d mode + \!setdimenmode% ** go into dimension mode +% + \!xS=#1\!xxS \advance\!xS\!xxloc + \!yS=#2\!yyS \advance\!yS\!yyloc + \!start (\!xS,\!yS)% + \!loop\ifdim\!angle>14.9999pt% ** draw in major portion of ellipse + \!rotate(\!xxS,\!yyS)by(\!cos,\!sign\!sin)to(\!xxM,\!yyM) + \!rotate(\!xxM,\!yyM)by(\!cos,\!sign\!sin)to(\!xxE,\!yyE) + \!xM=#1\!xxM \advance\!xM\!xxloc \!yM=#2\!yyM \advance\!yM\!yyloc + \!xE=#1\!xxE \advance\!xE\!xxloc \!yE=#2\!yyE \advance\!yE\!yyloc + \!qjoin (\!xM,\!yM) (\!xE,\!yE) + \!xxS=\!xxE \!yyS=\!yyE + \advance \!angle -15pt + \repeat + \ifdim\!angle>\!zpt% ** complete remaining arc, if any + \!angle=100.53096\!angle% ** convert angle to radians, divide + \divide \!angle 360 % ** by 2, and multiply by 32 + \!sinandcos\!angle\!!sin\!!cos% ** get 32*sin & 32*cos + \!rotate(\!xxS,\!yyS)by(\!!cos,\!sign\!!sin)to(\!xxM,\!yyM) + \!rotate(\!xxM,\!yyM)by(\!!cos,\!sign\!!sin)to(\!xxE,\!yyE) + \!xM=#1\!xxM \advance\!xM\!xxloc \!yM=#2\!yyM \advance\!yM\!yyloc + \!xE=#1\!xxE \advance\!xE\!xxloc \!yE=#2\!yyE \advance\!yE\!yyloc + \!qjoin (\!xM,\!yM) (\!xE,\!yE) + \fi +% + \let\!M=\!MC% ** restore c/d mode + \ignorespaces}% ** if appropriate + + +% ** \!rotate(XREG,YREG)by(32cos,32sin)to(XXREG,YYREG) +% ** rotates (XREG,YREG) by angle with specfied scaled cos & sin to +% ** (XXREG,YYREG). Uses \!dimenA & \!dimenB as scratch registers. +\def\!rotate(#1,#2)by(#3,#4)to(#5,#6){% + \!dimenA=#3#1\advance \!dimenA -#4#2% ** Rcos(x+t)=Rcosx*cost - Rsinx*sint + \!dimenB=#3#2\advance \!dimenB #4#1% ** Rsin(x+t)=Rsinx*cost + Rcosx*sint + \divide \!dimenA 32 \divide \!dimenB 32 + #5=\!dimenA #6=\!dimenB + \ignorespaces} +\def\!sin{4.17684}% ** 32*sin(pi/24) (pi/24=7.5deg) +\def\!cos{31.72624}% ** 32*cos(pi/24) + + +% ** \!sinandcos{32*ANGLE in radians}{\SINCS}{\COSCS} +% ** Computes the 32*sine and 32*cosine of a small ANGLE expressed in +% ** radians/32 and puts these values in the replacement texts of +% ** \SINCS and \COSCS +\def\!sinandcos#1#2#3{% + \!dimenD=#1% ** angle is expressed in radians/32: 1pt = 1/32rad + \!dimenA=\!dimenD% ** dimA will eventually contain 32sin(angle)in pts + \!dimenB=32pt% ** dimB will eventually contain 32cos(angle)in pts + \!removept\!dimenD\!value% ** get value of 32*angle, without "pt" + \!dimenC=\!dimenD% ** holds 32*angle**i/i! in pts + \!dimenC=\!value\!dimenC \divide\!dimenC by 64 % ** now 32*angle**2/2 + \advance\!dimenB by -\!dimenC% ** 32-32*angle**2/2 + \!dimenC=\!value\!dimenC \divide\!dimenC by 96 % ** now 32*angle**3/3! + \advance\!dimenA by -\!dimenC% ** now 32*(angle-angle**3/6) + \!dimenC=\!value\!dimenC \divide\!dimenC by 128 % ** now 32*angle**4/4! + \advance\!dimenB by \!dimenC% + \!removept\!dimenA#2% ** set 32*sin(angle) + \!removept\!dimenB#3% ** set 32*cos(angle) + \ignorespaces} + + +% ***************************************************************** +% *** RULES (Draws rules, i.e., horizontal & vertical lines) *** +% ***************************************************************** + +% ** User command: +% ** \putrule [] from XCOORD1 YCOORD1 +% ** to XCOORD2 YCOORD2 + +% ** Internal commands: +% ** \!puthline [] (h = horizontal) +% ** Set by dashpat to either: \!putsolidhline or \!putdashedhline +% ** \!putvline [] (v = vertical) +% ** Either: \!putsolidvline or \!putdashedvline + + +% ** \putrule [] from XCOORD1 YCOORD1 +% ** to XCOORD2 YCOORD2 +% ** Draws a rule -- dashed or solid depending on the current dash pattern -- +% ** from (X1,Y1) to (X2,Y2). Uses TEK's \hrule & \vrule & \leaders +% ** constructions to handle horizontal & vertical lines efficiently both +% ** in terms of execution time and space in the DVI file. +% ** See Subsection 4.1 of the manual. +\def\putrule#1from #2 #3 to #4 #5 {% + \!xloc=\!M{#2}\!xunit \!xxloc=\!M{#4}\!xunit% + \!yloc=\!M{#3}\!yunit \!yyloc=\!M{#5}\!yunit% + \!dxpos=\!xxloc \advance\!dxpos by -\!xloc + \!dypos=\!yyloc \advance\!dypos by -\!yloc +% + \ifdim\!dypos=\!zpt + \def\!!Line{\!puthline{#1}}\ignorespaces + \else + \ifdim\!dxpos=\!zpt + \def\!!Line{\!putvline{#1}}\ignorespaces + \else + \def\!!Line{} + \fi + \fi + \let\!ML=\!M% ** save current coord\dimen mode + \!setdimenmode% ** express locations in dimens + \!!Line% + \let\!M=\!ML% ** restore previous c/d mode + \ignorespaces} + + +% ** \!putsolidhline [] +% ** Place horizontal solid line +\def\!putsolidhline#1{% + \ifdim\!dxpos>\!zpt + \put{\!hline\!dxpos}#1[l] at {\!xloc} {\!yloc} + \else + \put{\!hline{-\!dxpos}}#1[l] at {\!xxloc} {\!yyloc} + \fi + \ignorespaces} + +% ** \!putsolidvline [shifted ] +% ** Place vertical solid line +\def\!putsolidvline#1{% + \ifdim\!dypos>\!zpt + \put{\!vline\!dypos}#1[b] at {\!xloc} {\!yloc} + \else + \put{\!vline{-\!dypos}}#1[b] at {\!xxloc} {\!yyloc} + \fi + \ignorespaces} + +\def\!hline#1{\hbox to #1{\leaders \hrule height\linethickness\hfill}} +\def\!vline#1{\vbox to #1{\leaders \vrule width\linethickness\vfill}} + + +% ** \!putdashedhline [] +% ** Place dashed horizontal line +\def\!putdashedhline#1{% + \ifdim\!dxpos>\!zpt + \!DLsetup\!Flist\!dxpos + \put{\hbox to \!totalleaderlength{\!hleaders}\!hpartialpattern\!Rtrunc} + #1[l] at {\!xloc} {\!yloc} + \else + \!DLsetup\!Blist{-\!dxpos} + \put{\!hpartialpattern\!Ltrunc\hbox to \!totalleaderlength{\!hleaders}} + #1[r] at {\!xloc} {\!yloc} + \fi + \ignorespaces} + +% ** \!putdashedhline [] +% ** Place dashed vertical line +\def\!putdashedvline#1{% + \!dypos=-\!dypos% ** vertical leaders go from top to bottom + \ifdim\!dypos>\!zpt + \!DLsetup\!Flist\!dypos + \put{\vbox{\vbox to \!totalleaderlength{\!vleaders} + \!vpartialpattern\!Rtrunc}}#1[t] at {\!xloc} {\!yloc} + \else + \!DLsetup\!Blist{-\!dypos} + \put{\vbox{\!vpartialpattern\!Ltrunc + \vbox to \!totalleaderlength{\!vleaders}}}#1[b] at {\!xloc} {\!yloc} + \fi + \ignorespaces} + + +% ** The rest of the macros in this section are subroutines used by +% ** \!putdashedhline and \!putdashedvline. +\def\!DLsetup#1#2{% ** Dashed-Line set up + \let\!RSlist=#1% ** set !Rule-Skip list + \!countB=#2% ** convert rule length to integer (number of sps) + \!countA=\!leaderlength% ** ditto, leaderlength + \divide\!countB by \!countA% ** number of complete leader units + \!totalleaderlength=\!countB\!leaderlength + \!Rresiduallength=#2% + \advance \!Rresiduallength by -\!totalleaderlength% \** excess length + \!Lresiduallength=\!leaderlength + \advance \!Lresiduallength by -\!Rresiduallength + \ignorespaces} + +\def\!hleaders{% + \def\!Rule##1{\vrule height\linethickness width##1}% + \def\!Skip##1{\hskip##1}% + \leaders\hbox{\!RSlist}\hfill} + +\def\!hpartialpattern#1{% + \!dimenA=\!zpt \!dimenB=\!zpt + \def\!Rule##1{#1{##1}\vrule height\linethickness width\!dimenD}% + \def\!Skip##1{#1{##1}\hskip\!dimenD}% + \!RSlist} + +\def\!vleaders{% + \def\!Rule##1{\hrule width\linethickness height##1}% + \def\!Skip##1{\vskip##1}% + \leaders\vbox{\!RSlist}\vfill} + +\def\!vpartialpattern#1{% + \!dimenA=\!zpt \!dimenB=\!zpt + \def\!Rule##1{#1{##1}\hrule width\linethickness height\!dimenD}% + \def\!Skip##1{#1{##1}\vskip\!dimenD}% + \!RSlist} + +\def\!Rtrunc#1{\!trunc{#1}>\!Rresiduallength} +\def\!Ltrunc#1{\!trunc{#1}<\!Lresiduallength} + +\def\!trunc#1#2#3{% + \!dimenA=\!dimenB + \advance\!dimenB by #1% + \!dimenD=\!dimenB \ifdim\!dimenD#2#3\!dimenD=#3\fi + \!dimenC=\!dimenA \ifdim\!dimenC#2#3\!dimenC=#3\fi + \advance \!dimenD by -\!dimenC} + + +% **************************************************************** +% *** LINEAR ARC (Draws straight lines -- solid and dashed) *** +% **************************************************************** + +% ** User commands +% ** \inboundscheckoff +% ** \inboundscheckon + +% ** Internal commands +% ** \!start (XCOORD,YCOORD) +% ** \!ljoin (XCOORD,YCOORD) +% ** \!drawlinearsegment -- set by \dashpat to either +% ** \!linearsolid or \!lineardashed +% ** \!advancedashing -- set by \dashpat to either +% ** \relax or \!!advancedashing +% ** \!plotifinbounds -- set by \inboundscheck off/on to either +% ** \!plot or \!!plotifinbounds +% ** \!initinboundscheck -- set by \inboundscheck off/on to either +% ** \relax or \!!initinboundscheck + + +% \plotsymbolspacing ** distance between consecutive plot positions +% \!xS ** starting x +% \!yS ** starting y +% \!xE ** ending x +% \!yE ** ending y +% \!xdiff ** x_end - x_start +% \!ydiff ** y_end - y_start +% \!distacross ** how far along curve next point to be plotted is +% \!arclength ** approximate length of arc for current interval +% \!downlength ** remaining length for "pen" to be down +% \!uplength ** length for "pen" to be down +% \!intervalno ** counts segments to curve +% \totalarclength ** cumulative distance along curve +% \!npoints ** approximately (arc length / plotsymbolspacing) + +% ** Calls -- \!Pythag, \!divide, \!plot + + +% ** \!start (XCOORD,YCOORD) +% ** Sets initial point for linearly (or quadratically) interpolated curve +\def\!start (#1,#2){% + \!plotxorigin=\!xorigin \advance \!plotxorigin by \!plotsymbolxshift + \!plotyorigin=\!yorigin \advance \!plotyorigin by \!plotsymbolyshift + \!xS=\!M{#1}\!xunit \!yS=\!M{#2}\!yunit + \!rotateaboutpivot\!xS\!yS + \!copylist\!UDlist\to\!!UDlist% **\!UDlist has the form \\{dimen1}\\{dimen2}.. +% ** Routine will draw dashed line with pen +% ** down for dimen1, up for dimen2, ... + \!getnextvalueof\!downlength\from\!!UDlist + \!distacross=\!zpt% ** 1st point goes at start of curve + \!intervalno=0 % ** initialize interval counter + \global\totalarclength=\!zpt% ** initialize distance traveled along curve + \ignorespaces} + + +% ** \!ljoin (XCOORD,YCOORD) +% ** Draws a straight line starting at the last point specified +% ** by the most recent \!start, \!ljoin, or \!qjoin, and +% ** ending at (XCOORD,YCOORD). +\def\!ljoin (#1,#2){% + \advance\!intervalno by 1 + \!xE=\!M{#1}\!xunit \!yE=\!M{#2}\!yunit + \!rotateaboutpivot\!xE\!yE + \!xdiff=\!xE \advance \!xdiff by -\!xS%** xdiff = xE - xS + \!ydiff=\!yE \advance \!ydiff by -\!yS%** ydiff = yE - yS + \!Pythag\!xdiff\!ydiff\!arclength% ** arclength = sqrt(xdiff**2+ydiff**2) + \global\advance \totalarclength by \!arclength% + \!drawlinearsegment% ** set by dashpat to \!linearsolid or \!lineardashed + \!xS=\!xE \!yS=\!yE% ** shift ending points to starting points + \ignorespaces} + + +% ** The following routine is used to draw a "solid" line between (xS,yS) +% ** and (xE,yE). Points are spaced nearly every \plotsymbolspacing length +% ** along the line. +\def\!linearsolid{% + \!npoints=\!arclength + \!countA=\plotsymbolspacing + \divide\!npoints by \!countA% ** now #pts =. arclength/plotsymbolspacing + \ifnum \!npoints<1 + \!npoints=1 + \fi + \divide\!xdiff by \!npoints + \divide\!ydiff by \!npoints + \!xpos=\!xS \!ypos=\!yS +% + \loop\ifnum\!npoints>-1 + \!plotifinbounds + \advance \!xpos by \!xdiff + \advance \!ypos by \!ydiff + \advance \!npoints by -1 + \repeat + \ignorespaces} + + +% ** The following routine is used to draw a dashed line between (xS,yS) +% ** and (xE,yE). The dash pattern continues from the previous segment. +\def\!lineardashed{% +% ** + \ifdim\!distacross>\!arclength + \advance \!distacross by -\!arclength %nothing to plot in this interval +% + \else +% + \loop\ifdim\!distacross<\!arclength +% ** plot point, interpolating linearly in x and y + \!divide\!distacross\!arclength\!dimenA% ** dimA = across/arclength + \!removept\!dimenA\!t% ** \!t holds value in dimA, without the "pt" + \!xpos=\!t\!xdiff \advance \!xpos by \!xS + \!ypos=\!t\!ydiff \advance \!ypos by \!yS + \!plotifinbounds + \advance\!distacross by \plotsymbolspacing + \!advancedashing + \repeat +% + \advance \!distacross by -\!arclength% ** prepare for next interval + \fi + \ignorespaces} + + +\def\!!advancedashing{% + \advance\!downlength by -\plotsymbolspacing + \ifdim \!downlength>\!zpt + \else + \advance\!distacross by \!downlength + \!getnextvalueof\!uplength\from\!!UDlist + \advance\!distacross by \!uplength + \!getnextvalueof\!downlength\from\!!UDlist + \fi} + + +% ** \inboundscheckoff & \inboundscheckon: See Subsection 5.5 of the manual. +\def\inboundscheckoff{% + \def\!plotifinbounds{\!plot(\!xpos,\!ypos)}% + \def\!initinboundscheck{\relax}\ignorespaces} +\def\inboundscheckon{% + \def\!plotifinbounds{\!!plotifinbounds}% + \def\!initinboundscheck{\!!initinboundscheck}% + \!initinboundscheck\ignorespaces} +\inboundscheckoff + +% ** The following code plots the current point only if it falls in the +% ** current plotarea. It doesn't matter if the coordinate system has +% ** changed since the plotarea was set up. However, shifts of the plot +% ** are ignored (how the plotsymbol stands relative to its plot position is +% ** unknown anyway). +\def\!!plotifinbounds{% + \ifdim \!xpos<\!checkleft + \else + \ifdim \!xpos>\!checkright + \else + \ifdim \!ypos<\!checkbot + \else + \ifdim \!ypos>\!checktop + \else + \!plot(\!xpos,\!ypos) + \fi + \fi + \fi + \fi} + + +\def\!!initinboundscheck{% + \!checkleft=\!arealloc \advance\!checkleft by \!xorigin + \!checkright=\!arearloc \advance\!checkright by \!xorigin + \!checkbot=\!areabloc \advance\!checkbot by \!yorigin + \!checktop=\!areatloc \advance\!checktop by \!yorigin} + + +% ********************************* +% *** LOGTEN (Log_10 function) *** +% ********************************* +% +% ** \!logten{X} +% ** Calculates log_10 of X. X and LOG10(X) are in fixed point notation. +% ** X must be positive; it may have an optional `+' sign; any number +% ** of digits may be specified for X. The absolute error in LOG10(X) is +% ** less than .0001 (probably < .00006). That's about as good as you +% ** hope for, since TEX only operates to 5 figures after the decimal +% ** point anyway. + +% \!rootten=3.162278pt **** These are values are set in ALLOCATIONS +% \!tenAe=2.543275pt (=A5) +% \!tenAc=2.773839pt (=A3) +% \!tenAa=8.690286pt (=A1) + +\def\!logten#1#2{% + \expandafter\!!logten#1\!nil + \!removept\!dimenF#2% + \ignorespaces} + +\def\!!logten#1#2\!nil{% + \if -#1% + \!dimenF=\!zpt + \def\!next{\ignorespaces}% + \else + \if +#1% + \def\!next{\!!logten#2\!nil}% + \else + \if .#1% + \def\!next{\!!logten0.#2\!nil}% + \else + \def\!next{\!!!logten#1#2..\!nil}% + \fi + \fi + \fi + \!next} + +\def\!!!logten#1#2.#3.#4\!nil{% + \!dimenF=1pt % ** DimF holds log10 original argument + \if 0#1% + \!!logshift#3pt % ** Argument < 1 + \else % ** Argument >= 1 + \!logshift#2/% ** Shift decimal pt as many places + \!dimenE=#1.#2#3pt % ** as there are figures in #2 + \fi % ** Now dimE holds revised X want log10 of + \ifdim \!dimenE<\!rootten% ** Transform X to XX between sqrt(10) + \multiply \!dimenE 10 % ** and 10*sqrt(10) + \advance \!dimenF -1pt + \fi + \!dimenG=\!dimenE% ** dimG <- (XX + 10) + \advance\!dimenG 10pt + \advance\!dimenE -10pt % ** dimE <- (XX - 10) + \multiply\!dimenE 10 % ** dimE = 10*(XX-10) + \!divide\!dimenE\!dimenG\!dimenE% ** Now dimE=10t==10*(XX-10)/(XX+10) + \!removept\!dimenE\!t% ** !t=10t, with "pt" removed + \!dimenG=\!t\!dimenE% ** dimG=100t**2 + \!removept\!dimenG\!tt% ** !tt=100t**2, with "pt" removed + \!dimenH=\!tt\!tenAe% ** dimH=10*a5*(10t)**2 /100 + \divide\!dimenH 100 + \advance\!dimenH \!tenAc% ** ditto + 10*a3 + \!dimenH=\!tt\!dimenH% ** ditto * (10t)**2 /100 + \divide\!dimenH 100 + \advance\!dimenH \!tenAa% ** ditto + 10*a1 + \!dimenH=\!t\!dimenH% ** ditto * 10t / 100 + \divide\!dimenH 100 % ** Now dimH = log10(XX) - 1 + \advance\!dimenF \!dimenH}% ** dimF = log10(X) + +\def\!logshift#1{% + \if #1/% + \def\!next{\ignorespaces}% + \else + \advance\!dimenF 1pt + \def\!next{\!logshift}% + \fi + \!next} + + \def\!!logshift#1{% + \advance\!dimenF -1pt + \if 0#1% + \def\!next{\!!logshift}% + \else + \if p#1% + \!dimenF=1pt + \def\!next{\!dimenE=1p}% + \else + \def\!next{\!dimenE=#1.}% + \fi + \fi + \!next} + + +% *********************************************************** +% *** PICTURES (Basic setups for PiCtures; \put commands) *** +% *********************************************************** + +% ** User Commands: +% ** \beginpicture +% ** \endpicture +% ** \endpicturesave +% ** \setcoordinatesystem units point at XREF YREF +% ** \put {OBJECT} [ORIENTATION] at XCOORD YCOORD +% ** \multiput {OJBECT} [ORIENTATION] ) at +% ** XCOORD YCOORD +% ** *NUMBER_OF_TIMES DXCOORD DYCOORD / +% ** \accountingon +% ** \accountingoff +% ** \stack [ORIENTATION] {LIST OF ITEMS} +% ** \lines [ORIENTATION] {LINES} +% ** \Lines [ORIENTATION] {LINES} +% ** \setdimensionmode +% ** \setcoordinatemode +% ** \Xdistance +% ** \Ydistance + +% ** Internal commands: +% ** \!setputobject{OBJECT}{[ORIENTATION]} +% ** \!dimenput{OBJECT}[ORIENTATION](XDIMEN,YDIMEN) +% ** \!setdimenmode +% ** \!setcoordmode +% ** \!ifdimenmode +% ** \!ifcoordmode + + +% ** \beginpicture +% ** \endpicture +% ** \endpicturesave +% ** \beginpicture ... \endpicture creates an hbox. Objects are +% ** placed in this box using the \put command and the like (see below). +% ** The location of an object is specified in terms of coordinate system(s) +% ** established by \setcoordinatesystem. Each coordinate system (there +% ** might be just one) specifies the length of 1 horizontal unit, the length +% ** of 1 vertical unit, and the coordinates of a "reference point". The +% ** reference points of various coordinate systems will be in the same +% ** physical location. The macros keep track of the size of the objects +% ** and their locations. The resulting hbox is the smallest hbox which +% ** encloses all the objects, and whose TEK reference point is the point +% ** on the left edge of the box closest vertically to the PICTEX reference +% ** point. Using \endpicturesave, you can (globally) save the distance TEK's +% ** reference point is to the right (respectively, up from) PICTEX's +% ** reference point in the dimension register \XREG (respectively \YREG). +% ** You can then \put the picture OBJECT into a larger picture so that its +% ** reference point is at (XCOORD,YCOORD) with the command +% ** \put {picture OBJECT} [Bl] <\XREG, \YREG> at XCOORD YCOORD + +% ** \beginpicture : See Subsection 1.1 of the manual. +\def\beginpicture{% + \setbox\!picbox=\hbox\bgroup% + \!xleft=\maxdimen + \!xright=-\maxdimen + \!ybot=\maxdimen + \!ytop=-\maxdimen} + +% ** \endpicture : See Subsection 1.1 of the manual. +\def\endpicture{% + \ifdim\!xleft=\maxdimen% ** check if nothing was put in picbox + \!xleft=\!zpt \!xright=\!zpt \!ybot=\!zpt \!ytop=\!zpt + \fi + \global\!Xleft=\!xleft \global\!Xright=\!xright + \global\!Ybot=\!ybot \global\!Ytop=\!ytop + \egroup% + \ht\!picbox=\!Ytop \dp\!picbox=-\!Ybot + \ifdim\!Ybot>\!zpt + \else + \ifdim\!Ytop<\!zpt + \!Ybot=\!Ytop + \else + \!Ybot=\!zpt + \fi + \fi + \hbox{\kern-\!Xleft\lower\!Ybot\box\!picbox\kern\!Xright}} + +% ** \endpicturesave : See Subsection 8.4 of the manual. +\def\endpicturesave <#1,#2>{% + \endpicture \global #1=\!Xleft \global #2=\!Ybot \ignorespaces} + + +% ** \setcoordinatesystem units +% ** point at XREF YREF +% ** Each of `units ' and `point at XREF YREF' +% ** are optional. +% ** Unit lengths must be given in dimensions (e.g., <10pt,1in>). +% ** Default unit lengths are 1pt, 1pt, or previous unit lengths. +% ** Reference point is specified in current units (e.g., 3 5 ). +% ** Default reference point is 0 0 , or previous reference point. +% ** Unit lengths and reference points obey TEX's scoping rules. +% ** See Subsection 1.2 of the manual. +\def\setcoordinatesystem{% + \!ifnextchar{u}{\!getlengths } + {\!getlengths units <\!xunit,\!yunit>}} +\def\!getlengths units <#1,#2>{% + \!xunit=#1\relax + \!yunit=#2\relax + \!ifcoordmode + \let\!SCnext=\!SCccheckforRP + \else + \let\!SCnext=\!SCdcheckforRP + \fi + \!SCnext} +\def\!SCccheckforRP{% + \!ifnextchar{p}{\!cgetreference } + {\!cgetreference point at {\!xref} {\!yref} }} +\def\!cgetreference point at #1 #2 {% + \edef\!xref{#1}\edef\!yref{#2}% + \!xorigin=\!xref\!xunit \!yorigin=\!yref\!yunit + \!initinboundscheck % ** See linear.tex + \ignorespaces} +\def\!SCdcheckforRP{% + \!ifnextchar{p}{\!dgetreference}% + {\ignorespaces}} +\def\!dgetreference point at #1 #2 {% + \!xorigin=#1\relax \!yorigin=#2\relax + \ignorespaces} + + +% ** \put {OBJECT} [XY] at (XCOORD,YCOORD) +% ** `[XY]' and `' are optional. +% ** First OBJECT is placed in an hbox (the "objectbox") and then a +% ** "reference point" is assigned to the objectbox as follows: +% ** [1] first, the reference point is taken to be the center of the box; +% ** [2] next, centering is overridden by the specifications +% ** X=l -- reference point along the left edge of the objectbox +% ** X=r -- reference point along the right edge of the objectbox +% ** Y=b -- reference point along the bottom edge of the objectbox +% ** Y=B -- reference point along the Baseline of the objectbox +% ** Y=t -- reference point along the top edge of the objectbox; +% ** [3] finally the reference point is shifted left by XDIMEN, down +% ** by YDIMEN (both default to 0pt). +% ** The objectbox is placed within PICBOX with its reference point at +% ** (XCOORD,YCOORD). +% ** If OBJECT is a saved box, say box0, you have to write +% ** \put{\box0}... or \put{\copy0}... +% ** The objectbox is void after the put. +% ** See Subsection 2.1 of the manual. +\long\def\put#1#2 at #3 #4 {% + \!setputobject{#1}{#2}% + \!xpos=\!M{#3}\!xunit \!ypos=\!M{#4}\!yunit + \!rotateaboutpivot\!xpos\!ypos% + \advance\!xpos -\!xorigin \advance\!xpos -\!xshift + \advance\!ypos -\!yorigin \advance\!ypos -\!yshift + \kern\!xpos\raise\!ypos\box\!putobject\kern-\!xpos% + \!doaccounting\ignorespaces} + +% ** \multiput etc. Like \put. The objectbox is not voided until the +% ** termininating /, and is placed repeatedly with: +% ** XCOORD YCOORD -- the objectbox is put down with its reference point +% ** at (XCOORD,YCOORD); +% ** *N DXCOORD DYCOORD -- each of N times the current +% ** (xcoord,ycoord) is incremented by (DXCOORD,DYCOORD), and the +% ** objectbox is put down with its reference point at (xcoord,ycoord) +% ** (This specification has to follow an XCOORD YCOORD pair) +% ** See Subsection 2.2 of the manual. +\long\def\multiput #1#2 at {% + \!setputobject{#1}{#2}% + \!ifnextchar"{\!putfromfile}{\!multiput}} +\def\!putfromfile"#1"{% + \expandafter\!multiput \normalinput #1 /} +\def\!multiput{% + \futurelet\!nextchar\!!multiput} +\def\!!multiput{% + \if *\!nextchar + \def\!nextput{\!alsoby}% + \else + \if /\!nextchar + \def\!nextput{\!finishmultiput}% + \else + \def\!nextput{\!alsoat}% + \fi + \fi + \!nextput} +\def\!finishmultiput/{% + \setbox\!putobject=\hbox{}% + \ignorespaces} + +% ** \!alsoat XCOORD YCOORD +% ** The objectbox is put down with reference point at XCOORD,YCOORD +\def\!alsoat#1 #2 {% + \!xpos=\!M{#1}\!xunit \!ypos=\!M{#2}\!yunit + \!rotateaboutpivot\!xpos\!ypos% + \advance\!xpos -\!xorigin \advance\!xpos -\!xshift + \advance\!ypos -\!yorigin \advance\!ypos -\!yshift + \kern\!xpos\raise\!ypos\copy\!putobject\kern-\!xpos% + \!doaccounting + \!multiput} + +% ** \!alsoby*N DXCOORD DYCOORD +% ** N times, the current (XCOORD,YCOORD) is advanced by (DXCOORD,DYCOORD), +% ** and the current (shifted, oriented) OBJECT is put down. +\def\!alsoby*#1 #2 #3 {% + \!dxpos=\!M{#2}\!xunit \!dypos=\!M{#3}\!yunit + \!rotateonly\!dxpos\!dypos + \!ntemp=#1% + \!!loop\ifnum\!ntemp>0 + \advance\!xpos by \!dxpos \advance\!ypos by \!dypos + \kern\!xpos\raise\!ypos\copy\!putobject\kern-\!xpos% + \advance\!ntemp by -1 + \repeat + \!doaccounting + \!multiput} + +% ** \accountingoff : Suspends PiCTeX's accounting of the aggregate +% ** size of the picture box. +% ** \accounting on : Reinstates accounting. +% ** See Subsection 8.2 of the manual. +\def\accountingon{\def\!doaccounting{\!!doaccounting}\ignorespaces} +\def\accountingoff{\def\!doaccounting{}\ignorespaces} +\accountingon +\def\!!doaccounting{% + \!xtemp=\!xpos + \!ytemp=\!ypos + \ifdim\!xtemp<\!xleft + \!xleft=\!xtemp + \fi + \advance\!xtemp by \!wd + \ifdim\!xright<\!xtemp + \!xright=\!xtemp + \fi + \advance\!ytemp by -\!dp + \ifdim\!ytemp<\!ybot + \!ybot=\!ytemp + \fi + \advance\!ytemp by \!dp + \advance\!ytemp by \!ht + \ifdim\!ytemp>\!ytop + \!ytop=\!ytemp + \fi} + +\long\def\!setputobject#1#2{% + \setbox\!putobject=\hbox{#1}% + \!ht=\ht\!putobject \!dp=\dp\!putobject \!wd=\wd\!putobject + \wd\!putobject=\!zpt + \!xshift=.5\!wd \!yshift=.5\!ht \advance\!yshift by -.5\!dp + \edef\!putorientation{#2}% + \expandafter\!SPOreadA\!putorientation[]\!nil% + \expandafter\!SPOreadB\!putorientation<\!zpt,\!zpt>\!nil\ignorespaces} + +\def\!SPOreadA#1[#2]#3\!nil{\!etfor\!orientation:=#2\do\!SPOreviseshift} + +\def\!SPOreadB#1<#2,#3>#4\!nil{\advance\!xshift by -#2\advance\!yshift by -#3} + +\def\!SPOreviseshift{% + \if l\!orientation + \!xshift=\!zpt + \else + \if r\!orientation + \!xshift=\!wd + \else + \if b\!orientation + \!yshift=-\!dp + \else + \if B\!orientation + \!yshift=\!zpt + \else + \if t\!orientation + \!yshift=\!ht + \fi + \fi + \fi + \fi + \fi} + + +% ** \!dimenput{OBJECT} [XY] (XLOC,YLOC) +% ** This is an internal put routine, similar to \put, except that +% ** XLOC=distance right from reference point, YLOC=distance up from +% ** reference point. XLOC and YLOC are dimensions, so this routine +% ** is completely independent of the current coordinate system. +% ** This routine does NOT do ROTATIONS. +\long\def\!dimenput#1#2(#3,#4){% + \!setputobject{#1}{#2}% + \!xpos=#3\advance\!xpos by -\!xshift + \!ypos=#4\advance\!ypos by -\!yshift + \kern\!xpos\raise\!ypos\box\!putobject\kern-\!xpos% + \!doaccounting\ignorespaces} + + +% ** The following macros permit the picture drawing routines to be used +% ** either in the default "coordinate mode", or in "dimension mode". +% ** In coordinate mode \!M(1.5,\!xunit) expands to 1.5\!xunit +% ** In dimension mode \!M(1.5pt,\!xunit) expands to 1.5pt +% ** Dimension mode is useful in coding macros. +% ** Any special purpose picture macro that sets dimension mode should +% ** reset coordinate mode before completion. +% ** See Subsection 9.2 of the manual. +\def\!setdimenmode{% + \let\!M=\!M!!\ignorespaces} +\def\!setcoordmode{% + \let\!M=\!M!\ignorespaces} +\def\!ifcoordmode{% + \ifx \!M \!M!} +\def\!ifdimenmode{% + \ifx \!M \!M!!} +\def\!M!#1#2{#1#2} +\def\!M!!#1#2{#1} +\!setcoordmode +\let\setdimensionmode=\!setdimenmode +\let\setcoordinatemode=\!setcoordmode + +% ** \Xdistance{XCOORD}, \Ydistance{YCOORD} are the horizontal and +% ** vertical distances from the origin (0,0) to the point +% ** (XCOORD,YCOORD) in the current coordinate system. +% ** See Subsection 9.2 of the manual. +\def\Xdistance#1{% + \!M{#1}\!xunit + \ignorespaces} +\def\Ydistance#1{% + \!M{#1}\!yunit + \ignorespaces} + +% ** The following macros -- \stack, \line, and \Lines -- are useful for +% ** annotating PiCtures. They can be used outside the \beginpicture ... +% ** \endpicture environment. + +% ** \stack [POSITIONING] {VALUESLIST} +% ** Builds a vertical stack of the values in VALUESLIST. Values in +% ** VALUESLIST are separated by commas. In the resulting stack, values are +% ** centered by default, and positioned flush left (right) if +% ** POSITIONING = l (r). Values are separated vertically by LEADING, +% ** which defaults to \stackleading. +% ** See Subsection 2.3 of the manual. +\def\stack{% + \!ifnextchar[{\!stack}{\!stack[c]}} +\def\!stack[#1]{% + \let\!lglue=\hfill \let\!rglue=\hfill + \expandafter\let\csname !#1glue\endcsname=\relax + \!ifnextchar<{\!!stack}{\!!stack<\stackleading>}} +\def\!!stack<#1>#2{% + \vbox{\def\!valueslist{}\!ecfor\!value:=#2\do{% + \expandafter\!rightappend\!value\withCS{\\}\to\!valueslist}% + \!lop\!valueslist\to\!value + \let\\=\cr\lineskiplimit=\maxdimen\lineskip=#1% + \baselineskip=-1000pt\halign{\!lglue##\!rglue\cr \!value\!valueslist\cr}}% + \ignorespaces} + +% ** \lines [POSITIONING] {LINES} +% ** Builds a vertical array of the lines in LINES. Each line in LINES +% ** is terminated by a \cr. In the resulting array, lines are +% ** centered by default, and positioned flush left (right) if +% ** POSITIONING = l (r). The lines in the array are subject to TeX's +% ** usual spacing rules: in particular the baselines are ordinarily an equal +% ** distance apart. The baseline of the array is the baseline of the +% ** the bottom line. +% ** See Subsection 2.3 of the manual. +\def\lines{% + \!ifnextchar[{\!lines}{\!lines[c]}} +\def\!lines[#1]#2{% + \let\!lglue=\hfill \let\!rglue=\hfill + \expandafter\let\csname !#1glue\endcsname=\relax + \vbox{\halign{\!lglue##\!rglue\cr #2\crcr}}% + \ignorespaces} + +% ** \Lines [POSITIONING] {LINES} +% ** Like \lines, but the baseline of the array is the baseline of the +% ** top line. See Subsection 2.3 of the manual. +\def\Lines{% + \!ifnextchar[{\!Lines}{\!Lines[c]}} +\def\!Lines[#1]#2{% + \let\!lglue=\hfill \let\!rglue=\hfill + \expandafter\let\csname !#1glue\endcsname=\relax + \vtop{\halign{\!lglue##\!rglue\cr #2\crcr}}% + \ignorespaces} + + +% ********************************************* +% *** PLOTTING (Things to do with plotting) *** +% ********************************************* + +% ** User commands +% ** \setplotsymbol ({PLOTSYMBOL} [ORIENTATION] ) +% ** \savelinesandcurves on "FILE_NAME" +% ** \dontsavelinesandcurves +% ** \writesavefile {MESSAGE} +% ** \replot {FILE_NAME} + +% ** Internal command +% ** \!plot(XDIMEN,YDIMEN) + +% ** \setplotsymbol ({PLOTSYMBOL} [ ] < , >) +% ** Save PLOTSYMBOL away in an hbox for use with curve plotting routines +% ** See Subsection 5.2 of the manual. +\def\setplotsymbol(#1#2){% + \!setputobject{#1}{#2} + \setbox\!plotsymbol=\box\!putobject% + \!plotsymbolxshift=\!xshift + \!plotsymbolyshift=\!yshift + \ignorespaces} + +\setplotsymbol({\fiverm .})% ** initialize plotsymbol + + +% ** \!plot is either \!!plot (when no lines and curves are being saved) or +% ** \!!!plot (when lines and curves are being saved) + +% ** \!!plot(XDIMEN,YDIMEN) +% ** Places the current plotsymbol a horizontal distance=XDIMEN-xorigin +% ** and a vertical distance=YDIMEN-yorigin from the current +% ** reference point. +\def\!!plot(#1,#2){% + \!dimenA=-\!plotxorigin \advance \!dimenA by #1% ** over + \!dimenB=-\!plotyorigin \advance \!dimenB by #2% ** up + \kern\!dimenA\raise\!dimenB\copy\!plotsymbol\kern-\!dimenA% + \ignorespaces} + +% ** \!!!plot(XDIMEN,YDIMEN) +% ** Like \!!plot, but also saves the plot location in units of +% ** scaled point, on file `replotfile' +\def\!!!plot(#1,#2){% + \!dimenA=-\!plotxorigin \advance \!dimenA by #1% ** over + \!dimenB=-\!plotyorigin \advance \!dimenB by #2% ** up + \kern\!dimenA\raise\!dimenB\copy\!plotsymbol\kern-\!dimenA% + \!countE=\!dimenA + \!countF=\!dimenB + \immediate\write\!replotfile{\the\!countE,\the\!countF.}% + \ignorespaces} + + +% ** \savelinesandcurves on "FILE_NAME" +% ** Switch to save locations used for plotting lines and curves +% ** (No advantage in saving locations for solid lines; however +% ** replotting curve locations speeds things up by a factor of about 4. +% ** \dontsavelinesandcurves +% ** Terminates \savelinesandcurves. The default. +% ** See Subsection 5.6 of the manual. +\def\savelinesandcurves on "#1" {% + \immediate\closeout\!replotfile + \immediate\openout\!replotfile=#1% + \let\!plot=\!!!plot} + +\def\dontsavelinesandcurves {% + \let\!plot=\!!plot} +\dontsavelinesandcurves + +% ** \writesavefile {MESSAGE} +% ** The message is preceded by a "%", so that it won't interfere +% ** with replotting. +% ** See Subsection 5.6 of the manual. +{\catcode`\%=11\xdef\!Commentsignal{%}} +\def\writesavefile#1 {% + \immediate\write\!replotfile{\!Commentsignal #1}% + \ignorespaces} + +% ** \replot "FILE_NAME" +% ** Replots the locations saved earlier under \savelinesandcurves +% ** on "FILE_NAME" +% ** See Subsection 5.6 of the manual. +\def\replot"#1" {% + \expandafter\!replot\normalinput #1 /} +\def\!replot#1,#2. {% + \!dimenA=#1sp + \kern\!dimenA\raise#2sp\copy\!plotsymbol\kern-\!dimenA + \futurelet\!nextchar\!!replot} +\def\!!replot{% + \if /\!nextchar + \def\!next{\!finish}% + \else + \def\!next{\!replot}% + \fi + \!next} +% ************************************************** +% *** PYTHAGORAS (Euclidean distance function) *** +% ************************************************** + +% ** User command: +% ** \placehypotenuse for and in + +% ** Internal command: +% ** \!Pythag{X}{Y}{Z} +% ** Input X,Y are dimensions, or dimension registers. +% ** Output Z == sqrt(X**2+Y**2) must be a dimension register. +% ** Assumes that |X|+|Y| < 2048pt (about 28in). + +% ** Without loss of generality, suppose x>0, y>0. Put s = x+y, +% ** z = sqrt(x**2+y**2). Then z = s*f, where f = sqrt(t**2 + (1-t)**2) +% ** = sqrt((1+tau**2)/2), where t = x/s and tau = 2(t-1/2) . + +% ** Uses the \!divide macro (which uses registers \!dimenA--\!dimenD. +% ** Uses the \!removept macro (e.g., 123.45pt --> 123.45) +% ** Uses registers \!dimenE--\!dimenI. +\def\!Pythag#1#2#3{% + \!dimenE=#1\relax + \ifdim\!dimenE<\!zpt + \!dimenE=-\!dimenE + \fi% ** dimE = |x| + \!dimenF=#2\relax + \ifdim\!dimenF<\!zpt + \!dimenF=-\!dimenF + \fi% ** dimF = |y| + \advance \!dimenF by \!dimenE% ** dimF = s = |x|+|y| + \ifdim\!dimenF=\!zpt + \!dimenG=\!zpt% ** dimG = z = sqrt(x**2+y**2) + \else + \!divide{8\!dimenE}\!dimenF\!dimenE% ** now dimE = 8t = (8|x|)/s + \advance\!dimenE by -4pt% ** 8tau = (8t-4)*2 + \!dimenE=2\!dimenE% ** (tau = 2*t - 1) + \!removept\!dimenE\!!t% ** 8tau, without "pt" + \!dimenE=\!!t\!dimenE% ** (8tau)**2, in pts + \advance\!dimenE by 64pt% ** u = [64 + (8tau)**2]/2 + \divide \!dimenE by 2% ** [u = (8f)**2] + \!dimenH=7pt% ** initial guess g at sqrt(u) + \!!Pythag\!!Pythag\!!Pythag% ** 3 iterations give sqrt(u) + \!removept\!dimenH\!!t% ** 8f=sqrt(u), without "pt" + \!dimenG=\!!t\!dimenF% ** z = (8f)*s/8 + \divide\!dimenG by 8 + \fi + #3=\!dimenG + \ignorespaces} + +\def\!!Pythag{% ** Newton-Raphson for sqrt + \!divide\!dimenE\!dimenH\!dimenI% ** v = u/g + \advance\!dimenH by \!dimenI% ** g <-- (g + u/g)/2 + \divide\!dimenH by 2} + +% ** \placehypotenuse for and in +% ** See Subsection 9.3 of the manual. +\def\placehypotenuse for <#1> and <#2> in <#3> {% + \!Pythag{#1}{#2}{#3}} + + +% ********************************************** +% *** QUADRATIC ARC (Draws a quadratic arc) *** +% ********************************************** + +% ** Internal command +% ** \!qjoin (XCOORD1,YCOORD1) (XCOORD2,YCOORD2) + +% ** \!qjoin (XCOORD1,YCOORD1) (XCOORD2,YCOORD2) +% ** Draws an arc starting at the (last) point specified by the most recent +% ** \!qjoin, or \!ljoin, or \!start and passing through (X_1,Y_1), (X_2,Y_2). +% ** Uses quadratic interpolation in both x and y: +% ** x(t), 0 <= t <= 1, interpolates x_0, x_1, x_2 at t=0, .5, 1 +% ** y(t), 0 <= t <= 1, interpolates y_0, y_1, y_2 at t=0, .5, 1 + +\def\!qjoin (#1,#2) (#3,#4){% + \advance\!intervalno by 1 + \!ifcoordmode + \edef\!xmidpt{#1}\edef\!ymidpt{#2}% + \else + \!dimenA=#1\relax \edef\!xmidpt{\the\!dimenA}% + \!dimenA=#2\relax \edef\!xmidpt{\the\!dimenA}% + \fi + \!xM=\!M{#1}\!xunit \!yM=\!M{#2}\!yunit \!rotateaboutpivot\!xM\!yM + \!xE=\!M{#3}\!xunit \!yE=\!M{#4}\!yunit \!rotateaboutpivot\!xE\!yE +% +% ** Find coefficients for x(t)=a_x + b_x*t + c_x*t**2 + \!dimenA=\!xM \advance \!dimenA by -\!xS% ** dimA = I = xM - xS + \!dimenB=\!xE \advance \!dimenB by -\!xM% ** dimB = II = xE-xM + \!xB=3\!dimenA \advance \!xB by -\!dimenB% ** b=3I-II + \!xC=2\!dimenB \advance \!xC by -2\!dimenA% ** c=2(II-I) +% +% ** Find coefficients for y(t)=y_x + b_y*t + c_y*t**2 + \!dimenA=\!yM \advance \!dimenA by -\!yS% + \!dimenB=\!yE \advance \!dimenB by -\!yM% + \!yB=3\!dimenA \advance \!yB by -\!dimenB% + \!yC=2\!dimenB \advance \!yC by -2\!dimenA% +% +% ** Use Simpson's rule to calculate arc length over [0,1/2]: +% ** arc length = 1/2[1/6 f(0) + 4/6 f(1/4) + 1/6 f(1/2)] +% ** with f(t) = sqrt(x'(t)**2 + y'(t)**2). + \!xprime=\!xB \!yprime=\!yB% ** x'(t) = b + 2ct + \!dxprime=.5\!xC \!dyprime=.5\!yC% ** dt=1/4 ==> dx'(t) = c/2 + \!getf \!midarclength=\!dimenA + \!getf \advance \!midarclength by 4\!dimenA + \!getf \advance \!midarclength by \!dimenA + \divide \!midarclength by 12 +% +% ** Get arc length over [0,1]. + \!arclength=\!dimenA + \!getf \advance \!arclength by 4\!dimenA + \!getf \advance \!arclength by \!dimenA + \divide \!arclength by 12% ** Now have arc length over [1/2,1] + \advance \!arclength by \!midarclength + \global\advance \totalarclength by \!arclength +% +% +% ** Check to see if there's anything to plot in this interval + \ifdim\!distacross>\!arclength + \advance \!distacross by -\!arclength% ** nothing +% + \else + \!initinverseinterp% ** initialize for inverse interpolation on arc length + \loop\ifdim\!distacross<\!arclength% ** loop over points on arc + \!inverseinterp% ** find t such that arc length[0,t] = distacross, +% ** using inverse quadratic interpolation +% ** now evaluate x(t)=(c*t + b)*t + a + \!xpos=\!t\!xC \advance\!xpos by \!xB + \!xpos=\!t\!xpos \advance \!xpos by \!xS +% ** evaluate y(t) + \!ypos=\!t\!yC \advance\!ypos by \!yB + \!ypos=\!t\!ypos \advance \!ypos by \!yS + \!plotifinbounds% ** plot point if in bounds + \advance\!distacross \plotsymbolspacing%** advance arc length for next pt + \!advancedashing% ** see "linear" + \repeat +% + \advance \!distacross by -\!arclength% ** prepare for next interval + \fi +% + \!xS=\!xE% ** shift ending points to starting points + \!yS=\!yE + \ignorespaces} + + +% ** \!getf -- Calculates sqrt(x'(t)**2 + y'(t)**2) and advances +% ** x'(t) and y'(t) +\def\!getf{\!Pythag\!xprime\!yprime\!dimenA% + \advance\!xprime by \!dxprime + \advance\!yprime by \!dyprime} + + +% ** \!initinverseinterp -- initializes for inverse quadratic interpolation +% ** of arc length provided 1/3 < midarclength/arclength < 2/3; otherwise +% ** initializes for inverse linear interpolation. +\def\!initinverseinterp{% + \ifdim\!arclength>\!zpt + \!divide{8\!midarclength}\!arclength\!dimenE% ** dimE=8w=8r/s, where r +% ** = midarclength, s=arclength +% ** Test for w out of range: w<1/3 or w>2/3 + \ifdim\!dimenE<\!wmin \!setinverselinear + \else + \ifdim\!dimenE>\!wmax \!setinverselinear + \else% ** w in range: initialize + \def\!inverseinterp{\!inversequad}\ignorespaces +% +% ** Calculate the coefficients \!beta and \!gamma of the quadratic +% ** t = \!beta*v + \!gamma*v**2 +% ** taking the values t=0, 1/2, 1 at v=0, w==r/s, 1 respectively: +% ** \!beta = (1/2 - w**2)/[w(1-w)] +% ** \!gamma = 1 - beta. +% + \!removept\!dimenE\!Ew% ** 8w, without "pt" + \!dimenF=-\!Ew\!dimenE% ** -(8w)**2 + \advance\!dimenF by 32pt% ** 32 - (8w)**2 + \!dimenG=8pt + \advance\!dimenG by -\!dimenE% ** 8 - 8w + \!dimenG=\!Ew\!dimenG% ** (8w)*(8-8w) + \!divide\!dimenF\!dimenG\!beta% ** beta = (32-(8w)**2)/(8w(8-8w)) +% ** = (1/2 - w**2)/(w(1-w)) + \!gamma=1pt + \advance \!gamma by -\!beta% ** gamma = 1-beta + \fi% ** end of the \ifdim\!dimenE>\!wmax + \fi% ** end of the \ifdim\!dimenE<\!wmin + \fi% ** end of the \ifdim\!arclength>\!zpt + \ignorespaces} + + +% ** For 0 <= t <= 1, let AL(t) = arclength[0,t]/arclength[0,1]; note +% ** AL(0)=0, AL(1/2)=midarclength/arclength, AL(1)=1. This routine +% ** calculates an approximation to AL^{-1}(distance across/arclength), +% ** using the assumption that AL^{-1} is quadratic. Specifically, +% ** it finds t such that +% ** AL^{-1}(v) =. t = v*(\!beta + \!gamma*v) +% ** where \!beta and \!gamma are set by \!initinv, and where +% ** v=distance across/arclength +\def\!inversequad{% + \!divide\!distacross\!arclength\!dimenG% ** dimG = v = distacross/arclength + \!removept\!dimenG\!v% ** v, without "pt" + \!dimenG=\!v\!gamma% ** gamma*v + \advance\!dimenG by \!beta% ** beta + gamma*v + \!dimenG=\!v\!dimenG% ** t = v*(beta + gamma*v) + \!removept\!dimenG\!t}% ** t, without "pt" + + +% ** When w <= 1/3 or w >= 2/3, the following routine writes (using +% ** plain TEK's \wlog command) a warning message on the user's log file, +% ** and initializes for inverse linear interpolation on arc length. +\def\!setinverselinear{% + \def\!inverseinterp{\!inverselinear}% + \divide\!dimenE by 8 \!removept\!dimenE\!t + \!countC=\!intervalno \multiply \!countC 2 + \!countB=\!countC \advance \!countB -1 + \!countA=\!countB \advance \!countA -1 + \wlog{\the\!countB th point (\!xmidpt,\!ymidpt) being plotted + doesn't lie in the}% + \wlog{ middle third of the arc between the \the\!countA th + and \the\!countC th points:}% + \wlog{ [arc length \the\!countA\space to \the\!countB]/[arc length + \the \!countA\space to \the\!countC]=\!t.}% + \ignorespaces} + +% ** Inverse linear interpolation +\def\!inverselinear{% + \!divide\!distacross\!arclength\!dimenG + \!removept\!dimenG\!t} + + +% ************************************** +% ** ROTATIONS (Handles rotations) *** +% ************************************** + +% ** User commands +% ** \startrotation [by COS_OF_ANGLE SIN_OF_ANGLE] [about XPIVOT YPIVOT] +% ** \stoprotation + +% ** \startrotation [by COS_OF_ANGLE SIN_OF_ANGLE] [about XPIVOT YPIVOT] +% ** Future (XCOORD,YCOORD)'s will be rotated about (XPIVOT,YPIVOT) +% ** by the angle with the give COS and SIN. Both fields are optional. +% ** [COS,SIN] defaults to previous value, or (1,0). +% ** (XPIVOT,YPIVOT) defaults to previous value, or (0,0) +% ** You can't change the coordinate system in the scope of a rotation. +% ** See Subsection 9.1 of the manual. +\def\startrotation{% + \let\!rotateaboutpivot=\!!rotateaboutpivot + \let\!rotateonly=\!!rotateonly + \!ifnextchar{b}{\!getsincos }% + {\!getsincos by {\!cosrotationangle} {\!sinrotationangle} }} +\def\!getsincos by #1 #2 {% + \edef\!cosrotationangle{#1}% + \edef\!sinrotationangle{#2}% + \!ifcoordmode + \let\!ROnext=\!ccheckforpivot + \else + \let\!ROnext=\!dcheckforpivot + \fi + \!ROnext} +\def\!ccheckforpivot{% + \!ifnextchar{a}{\!cgetpivot}% + {\!cgetpivot about {\!xpivotcoord} {\!ypivotcoord} }} +\def\!cgetpivot about #1 #2 {% + \edef\!xpivotcoord{#1}% + \edef\!ypivotcoord{#2}% + \!xpivot=#1\!xunit \!ypivot=#2\!yunit + \ignorespaces} +\def\!dcheckforpivot{% + \!ifnextchar{a}{\!dgetpivot}{\ignorespaces}} +\def\!dgetpivot about #1 #2 {% + \!xpivot=#1\relax \!ypivot=#2\relax + \ignorespaces} + + +% ** Following terminates rotation. +% ** See Subsection 9.1 of the manual. +\def\stoprotation{% + \let\!rotateaboutpivot=\!!!rotateaboutpivot + \let\!rotateonly=\!!!rotateonly + \ignorespaces} + +% ** !!rotateaboutpivot{XREG}{YREG} +% ** XREG <-- xpvt + cos(angle)*(XREG-xpvt) - sin(angle)*(YREG-ypvt) +% ** YREG <-- ypvt + cos(angle)*(YREG-ypvt) + sin(angle)*(XREG-xpvt) +% ** XREG,YREG are dimension registers. Can't be \!dimenA to \!dimenD +\def\!!rotateaboutpivot#1#2{% + \!dimenA=#1\relax \advance\!dimenA -\!xpivot + \!dimenB=#2\relax \advance\!dimenB -\!ypivot + \!dimenC=\!cosrotationangle\!dimenA + \advance \!dimenC -\!sinrotationangle\!dimenB + \!dimenD=\!cosrotationangle\!dimenB + \advance \!dimenD \!sinrotationangle\!dimenA + \advance\!dimenC \!xpivot \advance\!dimenD \!ypivot + #1=\!dimenC #2=\!dimenD + \ignorespaces} + +% ** \!!rotateonly{XREG}{YREG} +% ** Like \!!rotateaboutpivot, but with a pivot of (0,0) +\def\!!rotateonly#1#2{% + \!dimenA=#1\relax \!dimenB=#2\relax + \!dimenC=\!cosrotationangle\!dimenA + \advance \!dimenC -\!rotsign\!sinrotationangle\!dimenB + \!dimenD=\!cosrotationangle\!dimenB + \advance \!dimenD \!rotsign\!sinrotationangle\!dimenA + #1=\!dimenC #2=\!dimenD + \ignorespaces} +\def\!rotsign{} +\def\!!!rotateaboutpivot#1#2{\relax} +\def\!!!rotateonly#1#2{\relax} +\stoprotation + +\def\!reverserotateonly#1#2{% + \def\!rotsign{-}% + \!rotateonly{#1}{#2}% + \def\!rotsign{}% + \ignorespaces} + + +% ********************************** +% *** SHADING (Handles shading) *** +% ********************************** + +% ** User commands +% ** \setshadegrid [span ] [point at XSHADE YSHADE] +% ** \setshadesymbol [] ({SHADESYMBOL} +% ** [ORIENTATION]) + +% ** Internal commands: +% ** \!startvshade (xS,ybS,ytS) +% ** \!starthshade (yS,xlS,xrS) +% ** \!lshade [] +% ** ** when shading vertically: +% ** [the region from (xS,ybS,ytS) to] (xE,ybE,ytE) +% ** ** when shading horizontally: +% ** [the region from (yS,xlS,xrS) to] (yE,xlE,xrE) +% ** \!qshade [] +% ** ** when shading vertically: +% ** [the region from (xS,ybS,ytS) to] (xM,ybM,ytM) (xE,ybE,ytE) +% ** ** when shading horizontally: +% ** [the region from (yS,xlS,xrS) to] (yM,xlM,xrM) (yE,xlE,xrE) +% ** \!lattice{ANCHOR}{SPAN}{LOCATION}{INDEX}{LATTICE LOCATION} +% ** \!override{NOMINAL DIMEN}{REPLACEMENT DIMEN}{DIMEN} + + +% ** The shading routine can operate either in a "vertical mode" or a +% ** "horizontal mode". In vertical mode, the region to be shaded is specified +% ** in the form +% ** {(x,y): xl <= x <= xr & yb(x) <= y <= yt(x)} +% ** where yb and yt are functions of x. In horizontal mode, the region +% ** is specified in the form +% ** {(x,y): yb <= y <= yt & xl(y) <= x <= xr(y)}. +% ** The functions yb and yt may be either both linear or both quadratic; +% ** similarly for xl and xr. A region with say, piecewise quadratic bottom +% ** and top boundaries, can be shaded by consecutive (vertical) \!qshades, +% ** proceeding from left to right. Similarly, a region with piecewise +% ** quadratic left and right boundaries can be shaded by consecutive +% ** (horizontal) \!qshades, proceeding from bottom to top. More complex +% ** regions can be shaded by partitioning them into appropriate subregions, +% ** and shading those. + +% ** Shading is accomplished by placing a user-selected shading symbol at +% ** those points of a regular grid which fall within the region to be +% ** shaded. This region can be "shrunk" so that a largish shading symbol +% ** will not extend outside it. Shrinking is accomplished by specifying +% ** shrinkages for the left, right, bottom, and top boundaries, in a manner +% ** discussed further below. + +% ** \shades and \!joins MUST NOT be intermingled. Finish drawing a curve +% ** before starting to shade a region, and finish shading a region before +% ** starting to draw a curve. + + +% ** \setshadegrid [span ] [point at XSHADE YSHADE] +% ** The shading symbol is placed down on the points of a grid centered +% ** at the coordinate point (XSHADE,YSHADE). The grid points are of the +% ** form (j*SPAN,k*SPAN), with j+k even. SPAN is specified +% ** as a dimension. +% ** (XSHADE,YSHADE) defaults to previous (XSHADE,YSHADE) (or (0,0) if none) +% ** SPAN defaults to previous span (or 5pt if none) +% ** See Subsection 7.2 of the manual. +\def\setshadegrid{% + \!ifnextchar{s}{\!getspan } + {\!getspan span <\!dshade>}} +\def\!getspan span <#1>{% + \!dshade=#1\relax + \!ifcoordmode + \let\!GRnext=\!GRccheckforAP + \else + \let\!GRnext=\!GRdcheckforAP + \fi + \!GRnext} +\def\!GRccheckforAP{% + \!ifnextchar{p}{\!cgetanchor } + {\!cgetanchor point at {\!xshadesave} {\!yshadesave} }} +\def\!cgetanchor point at #1 #2 {% + \edef\!xshadesave{#1}\edef\!yshadesave{#2}% + \!xshade=\!xshadesave\!xunit \!yshade=\!yshadesave\!yunit + \ignorespaces} +\def\!GRdcheckforAP{% + \!ifnextchar{p}{\!dgetanchor}% + {\ignorespaces}} +\def\!dgetanchor point at #1 #2 {% + \!xshade=#1\relax \!yshade=#2\relax + \ignorespaces} + +% ** \setshadesymbol [] ({SHADESYMBOL} +% ** [ORIENTATION]) +% ** Saves SHADESYMBOL away in an hbox for use with shading routines. +% ** A shade symbol will not be plotted if its plot position comes within +% ** distance LS of the left boundary, RS of the right boundary, TS of the +% ** top boundary, BS of the bottom boundary. These parameters have +% ** default values that should work in most cases (see below). +% ** To override a default value, specify the replacement value +% ** in the appropriate subfield of the shrinkages field. +% ** 0pt may be coded as "z" (without the quotes). To accept a +% ** default value, leave the field empty. Thus +% ** [,z,,5pt] sets LS=default, RS=0pt, BS=default, TS=5pt . +% ** Skipping the shrinkages field accepts all the defaults. +% ** See Subsection 7.1 of the manual. +\def\setshadesymbol{% + \!ifnextchar<{\!setshadesymbol}{\!setshadesymbol<,,,> }} + +\def\!setshadesymbol <#1,#2,#3,#4> (#5#6){% +% ** set the shadesymbol + \!setputobject{#5}{#6}% + \setbox\!shadesymbol=\box\!putobject% + \!shadesymbolxshift=\!xshift \!shadesymbolyshift=\!yshift +% +% ** set the shrinkages + \!dimenA=\!xshift \advance\!dimenA \!smidge% ** default LS = xshift - smidge + \!override\!dimenA{#1}\!lshrinkage% + \!dimenA=\!wd \advance \!dimenA -\!xshift% ** default RS = width - xshift + \advance\!dimenA \!smidge% - smidge + \!override\!dimenA{#2}\!rshrinkage + \!dimenA=\!dp \advance \!dimenA \!yshift% ** default BS = depth + yshift + \advance\!dimenA \!smidge% - smidge + \!override\!dimenA{#3}\!bshrinkage + \!dimenA=\!ht \advance \!dimenA -\!yshift% ** default TS = height - yshift + \advance\!dimenA \!smidge% - smidge + \!override\!dimenA{#4}\!tshrinkage + \ignorespaces} +\def\!smidge{-.2pt}% + +% ** \!override{NOMINAL DIMEN}{REPLACEMENT DIMEN}{DIMEN} +% ** Overrides the NOMINAL DIMEN by the REPLACEMENT DIMEN to produce DIMEN, +% ** according to the following rules: +% ** REPLACEMENT DIMEN empty: DIMEN <-- NOMINAL DIMEN +% ** REPLACEMENT DIMEN z: DIMEN <-- 0pt +% ** otherwise: DIMEN <-- REPLACEMENT DIMEN +% ** DIMEN must be a dimension register +\def\!override#1#2#3{% + \edef\!!override{#2}% + \ifx \!!override\empty + #3=#1\relax + \else + \if z\!!override + #3=\!zpt + \else + \ifx \!!override\!blankz + #3=\!zpt + \else + #3=#2\relax + \fi + \fi + \fi + \ignorespaces} +\def\!blankz{ z} + +\setshadesymbol ({\fiverm .})% ** initialize plotsymbol +% ** \fivesy ^^B is a small cross + + +% ** \!startvshade [at] (xS,ybS,ytS) +% ** Initiates vertical shading mode +\def\!startvshade#1(#2,#3,#4){% + \let\!!xunit=\!xunit% + \let\!!yunit=\!yunit% + \let\!!xshade=\!xshade% + \let\!!yshade=\!yshade% + \def\!getshrinkages{\!vgetshrinkages}% + \let\!setshadelocation=\!vsetshadelocation% + \!xS=\!M{#2}\!!xunit + \!ybS=\!M{#3}\!!yunit + \!ytS=\!M{#4}\!!yunit + \!shadexorigin=\!xorigin \advance \!shadexorigin \!shadesymbolxshift + \!shadeyorigin=\!yorigin \advance \!shadeyorigin \!shadesymbolyshift + \ignorespaces} + +% ** \!starthshade [at] (yS,xlS,xrS) +% ** Initiates horizontal shading mode +\def\!starthshade#1(#2,#3,#4){% + \let\!!xunit=\!yunit% + \let\!!yunit=\!xunit% + \let\!!xshade=\!yshade% + \let\!!yshade=\!xshade% + \def\!getshrinkages{\!hgetshrinkages}% + \let\!setshadelocation=\!hsetshadelocation% + \!xS=\!M{#2}\!!xunit + \!ybS=\!M{#3}\!!yunit + \!ytS=\!M{#4}\!!yunit + \!shadexorigin=\!xorigin \advance \!shadexorigin \!shadesymbolxshift + \!shadeyorigin=\!yorigin \advance \!shadeyorigin \!shadesymbolyshift + \ignorespaces} + + +% ** \!lattice{ANCHOR}{SPAN}{LOCATION}{INDEX}{LATTICE LOCATION} +% ** Consider the lattice with points ANCHOR + j*SPAN. This routine determines +% ** the index k of the smallest lattice point >= LOCATION, and sets +% ** LATTICE LOCATION = ANCHOR + k*SPAN. +% ** INDEX is assumed to be a count register, LATTICE LOCATION a dimen reg. +\def\!lattice#1#2#3#4#5{% + \!dimenA=#1% ** dimA = ANCHOR + \!dimenB=#2% ** dimB = SPAN (assumed > 0pt) + \!countB=\!dimenB% ** ctB = SPAN, as a count +% +% ** Determine index of smallest lattice point >= LOCATION + \!dimenC=#3% ** dimC = LOCATION + \advance\!dimenC -\!dimenA% ** now dimC = LOCATION-ANCHOR + \!countA=\!dimenC% ** ctA = above, as a count + \divide\!countA \!countB% ** now ctA = desired index, if dimC <= 0 + \ifdim\!dimenC>\!zpt + \!dimenD=\!countA\!dimenB% ** (tentative k)*span + \ifdim\!dimenD<\!dimenC% ** if this is false, ctA = desired index + \advance\!countA 1 % ** if true, have to add 1 + \fi + \fi +% + \!dimenC=\!countA\!dimenB% ** lattice location = anchor + ctA*span + \advance\!dimenC \!dimenA + #4=\!countA% ** the desired index + #5=\!dimenC% ** corresponding lattice location + \ignorespaces} + + +% ** \!qshade [with shrinkages] [[LS,RS,BS,TS]] +% ***** during vertical shading: +% ** [the region from (xS,ybS,ytS) to] (xM,ybM,ytM) [and] (xE,ybE,ytE) +% ** Shades the region {(x,y): xS <= x <= xE, yb(x) <= y <= yt(x)}, where +% ** yb is the quadratic thru (xS,ybS) & (xM,ybM) & (xE,ybE) +% ** yt is the quadratic thru (xS,ytS) & (xM,ybM) & (xE,ytE) +% ** xS,ybS,ytS are either given by \!startvshade or carried over +% ** as the ending values of the immediately preceding \!qshade. +% ** For the interpretation of LS, RS, BS, & TS, see \setshadesymbol. The +% ** values set there can be overridden, for the course of this \!qshade +% ** only, in the same manner as overrides are specified for +% ** \setshadesymbol. +% ***** during horizontal shading: +% ** [the region from (yS,xlS,xrS) to] (yM,xlM,xrM) [and] (yE,xlE,xrE) +\def\!qshade#1(#2,#3,#4)#5(#6,#7,#8){% + \!xM=\!M{#2}\!!xunit + \!ybM=\!M{#3}\!!yunit + \!ytM=\!M{#4}\!!yunit + \!xE=\!M{#6}\!!xunit + \!ybE=\!M{#7}\!!yunit + \!ytE=\!M{#8}\!!yunit + \!getcoeffs\!xS\!ybS\!xM\!ybM\!xE\!ybE\!ybB\!ybC%**Get coefficients B & C for + \!getcoeffs\!xS\!ytS\!xM\!ytM\!xE\!ytE\!ytB\!ytC%**y=y0 + B(x-X0) + C(x-X0)**2 + \def\!getylimits{\!qgetylimits}% + \!shade{#1}\ignorespaces} + +% ** \!lshade ... (xE,ybE,ytE) +% ** This is like \!qshade, but the top and bottom boundaries are linear, +% ** rather than quadratic. +\def\!lshade#1(#2,#3,#4){% + \!xE=\!M{#2}\!!xunit + \!ybE=\!M{#3}\!!yunit + \!ytE=\!M{#4}\!!yunit + \!dimenE=\!xE \advance \!dimenE -\!xS% ** xE-xS + \!dimenC=\!ytE \advance \!dimenC -\!ytS% ** ytE-ytS + \!divide\!dimenC\!dimenE\!ytB% ** ytB = (ytE-ytS)/(xE-xS) + \!dimenC=\!ybE \advance \!dimenC -\!ybS% ** ybE-ybS + \!divide\!dimenC\!dimenE\!ybB% ** ybB = (ybE-ybS)/(xE-xS) + \def\!getylimits{\!lgetylimits}% + \!shade{#1}\ignorespaces} + +% ** \!getcoeffs{X0}{Y0}{X1}{Y1}{X2}{Y2}{B}{C} +% ** Finds B and C such that the quadratic y = Y0 + B(x-X0) + C(x-X0)**2 +% ** passes through (X1,Y1) and (X2,Y2): when X0=0=Y0, the formulas are: +% ** B = S1 - X1*C, C = (S2-S1)/X2 +% ** with +% ** S1 = Y1/X1, S2 = (Y2-Y1)/(X2-X1). +\def\!getcoeffs#1#2#3#4#5#6#7#8{% + \!dimenC=#4\advance \!dimenC -#2% ** dimC=Y1-Y0 + \!dimenE=#3\advance \!dimenE -#1% ** dimE=X1-X0 + \!divide\!dimenC\!dimenE\!dimenF% ** dimF=S1 + \!dimenC=#6\advance \!dimenC -#4% ** dimC=Y2-Y1 + \!dimenH=#5\advance \!dimenH -#3% ** dimH=X2-X1 + \!divide\!dimenC\!dimenH\!dimenG% ** dimG=S2 + \advance\!dimenG -\!dimenF% ** dimG=S2-S1 + \advance \!dimenH \!dimenE% ** dimH=X2-X0 + \!divide\!dimenG\!dimenH#8% ** C=(S2-S1)/(X2-X0) + \!removept#8\!t% ** C, without "pt" + #7=-\!t\!dimenE% ** -C*(X1-X0) + \advance #7\!dimenF% ** B=S1-C*(X1-X0) + \ignorespaces} + + +\def\!shade#1{% +% ** Get LS,RS,BS,TS for this panel + \!getshrinkages#1<,,,>\!nil% % ** now effective LS=dimE, RS=dimF, +% ** BS=dimG, TS=dimH + \advance \!dimenE \!xS% ** now dimE=xS+LS + \!lattice\!!xshade\!dshade\!dimenE% ** set parity=index of left-mst x-lattice + \!parity\!xpos% ** point >= xS+LS, xpos=its location + \!dimenF=-\!dimenF% ** set dimF=xE-RS + \advance\!dimenF \!xE +% + \!loop\!not{\ifdim\!xpos>\!dimenF}% ** loop over x-lattice points <= xE-RS + \!shadecolumn% + \advance\!xpos \!dshade% ** move over to next column + \advance\!parity 1% ** increase index of x-point + \repeat +% + \!xS=\!xE% ** shift ending values to starting values + \!ybS=\!ybE + \!ytS=\!ytE + \ignorespaces} + + +\def\!vgetshrinkages#1<#2,#3,#4,#5>#6\!nil{% + \!override\!lshrinkage{#2}\!dimenE + \!override\!rshrinkage{#3}\!dimenF + \!override\!bshrinkage{#4}\!dimenG + \!override\!tshrinkage{#5}\!dimenH + \ignorespaces} +\def\!hgetshrinkages#1<#2,#3,#4,#5>#6\!nil{% + \!override\!lshrinkage{#2}\!dimenG + \!override\!rshrinkage{#3}\!dimenH + \!override\!bshrinkage{#4}\!dimenE + \!override\!tshrinkage{#5}\!dimenF + \ignorespaces} + + +\def\!shadecolumn{% + \!dxpos=\!xpos + \advance\!dxpos -\!xS% ** dx = x - xS + \!removept\!dxpos\!dx% ** ditto, without "pt" + \!getylimits% ** get top and bottom y-values + \advance\!ytpos -\!dimenH% ** less TS + \advance\!ybpos \!dimenG% ** plus BS + \!yloc=\!!yshade% ** get anchor point for this column + \ifodd\!parity + \advance\!yloc \!dshade + \fi + \!lattice\!yloc{2\!dshade}\!ybpos% + \!countA\!ypos% ** ypos=smallest y point for this column + \!dimenA=-\!shadexorigin \advance \!dimenA \!xpos% ** over + \loop\!not{\ifdim\!ypos>\!ytpos}% ** loop over ypos <= yt(t) + \!setshadelocation% ** vmode: xloc=xpos, yloc=ypos +% ** hmode: xloc=ypos, yloc=xpos + \!rotateaboutpivot\!xloc\!yloc% + \!dimenA=-\!shadexorigin \advance \!dimenA \!xloc% ** over + \!dimenB=-\!shadeyorigin \advance \!dimenB \!yloc% ** up + \kern\!dimenA \raise\!dimenB\copy\!shadesymbol \kern-\!dimenA + \advance\!ypos 2\!dshade + \repeat + \ignorespaces} + +\def\!qgetylimits{% + \!dimenA=\!dx\!ytC + \advance\!dimenA \!ytB% ** yt(t)=ytS + dx*(Bt + dx*Ct) + \!ytpos=\!dx\!dimenA + \advance\!ytpos \!ytS + \!dimenA=\!dx\!ybC + \advance\!dimenA \!ybB% ** yb(t)=ybS + dx*(Bb + dx*Cb) + \!ybpos=\!dx\!dimenA + \advance\!ybpos \!ybS} + +\def\!lgetylimits{% + \!ytpos=\!dx\!ytB% ** yt(t)=ytS + dx*Bt + \advance\!ytpos \!ytS + \!ybpos=\!dx\!ybB% ** yb(t)=ybS + dx*Bb + \advance\!ybpos \!ybS} + +\def\!vsetshadelocation{% ** vmode: xloc=xpos, yloc=ypos + \!xloc=\!xpos + \!yloc=\!ypos} +\def\!hsetshadelocation{% ** hmode: xloc=ypos, yloc=xpos + \!xloc=\!ypos + \!yloc=\!xpos} + + +% ************************************** +% *** TICKS (Draws ticks on graphs) *** +% ************************************** + +% ** User commands +% ** \ticksout +% ** \ticksin +% ** \gridlines +% ** \nogridlines +% ** \loggedticks +% ** \unloggesticks +% ** See Subsection 3.4 of the manual + +% ** The following is an option of the \axis command +% ** ticks +% ** [in] [out] +% ** [long] [short] [length ] +% ** [width ] +% ** [andacross] [butnotacross] +% ** [logged] [unlogged] +% ** [unlabeled] [numbered] [withvalues VALUE1 VALUE2 ... VALUEk / ] +% ** [quantity Q] [at LOC1 LOC2 ... LOCk / ] [from LOC1 to LOC2 by +% ** LOC_INCREMENT] +% ** See Subsection 3.2 of the manual for the rules. + +% ** The various options of the tick field are processed by the +% ** \!nextkeyword command defined below. +% ** For example, `\!nextkeyword short ' expands to `\!ticksshort', +% ** while `\!nextkeyword withvalues' expands to `\!tickswithvalues'. + +\def\!axisticks {% + \def\!nextkeyword##1 {% + \expandafter\ifx\csname !ticks##1\endcsname \relax + \def\!next{\!fixkeyword{##1}}% + \else + \def\!next{\csname !ticks##1\endcsname}% + \fi + \!next}% + \!axissetup + \def\!axissetup{\relax}% + \edef\!ticksinoutsign{\!ticksinoutSign}% + \!ticklength=\longticklength + \!tickwidth=\linethickness + \!gridlinestatus + \!setticktransform + \!maketick + \!tickcase=0 + \def\!LTlist{}% + \!nextkeyword} + +\def\ticksout{% + \def\!ticksinoutSign{+}} +\def\ticksin{% + \def\!ticksinoutSign{-}} +\ticksout + +\def\gridlines{% + \def\!gridlinestatus{\!gridlinestootrue}} +\def\nogridlines{% + \def\!gridlinestatus{\!gridlinestoofalse}} +\nogridlines + +\def\loggedticks{% + \def\!setticktransform{\let\!ticktransform=\!logten}} +\def\unloggedticks{% + \def\!setticktransform{\let\!ticktransform=\!donothing}} +\def\!donothing#1#2{\def#2{#1}} +\unloggedticks + +% ** \!ticks/ : terminates read of tick options +\expandafter\def\csname !ticks/\endcsname{% + \!not {\ifx \!LTlist\empty} + \!placetickvalues + \fi + \def\!tickvalueslist{}% + \def\!LTlist{}% + \expandafter\csname !axis/\endcsname} + +\def\!maketick{% + \setbox\!boxA=\hbox{% + \beginpicture + \!setdimenmode + \setcoordinatesystem point at {\!zpt} {\!zpt} + \linethickness=\!tickwidth + \ifdim\!ticklength>\!zpt + \putrule from {\!zpt} {\!zpt} to + {\!ticksinoutsign\!tickxsign\!ticklength} + {\!ticksinoutsign\!tickysign\!ticklength} + \fi + \if!gridlinestoo + \putrule from {\!zpt} {\!zpt} to + {-\!tickxsign\!xaxislength} {-\!tickysign\!yaxislength} + \fi + \endpicturesave <\!Xsave,\!Ysave>}% + \wd\!boxA=\!zpt} + +\def\!ticksin{% + \def\!ticksinoutsign{-}% + \!maketick + \!nextkeyword} + +\def\!ticksout{% + \def\!ticksinoutsign{+}% + \!maketick + \!nextkeyword} + +\def\!tickslength<#1> {% + \!ticklength=#1\relax + \!maketick + \!nextkeyword} + +\def\!tickslong{% + \!tickslength<\longticklength> } + +\def\!ticksshort{% + \!tickslength<\shortticklength> } + +\def\!tickswidth<#1> {% + \!tickwidth=#1\relax + \!maketick + \!nextkeyword} + +\def\!ticksandacross{% + \!gridlinestootrue + \!maketick + \!nextkeyword} + +\def\!ticksbutnotacross{% + \!gridlinestoofalse + \!maketick + \!nextkeyword} + +\def\!tickslogged{% + \let\!ticktransform=\!logten + \!nextkeyword} + +\def\!ticksunlogged{% + \let\!ticktransform=\!donothing + \!nextkeyword} + +\def\!ticksunlabeled{% + \!tickcase=0 + \!nextkeyword} + +\def\!ticksnumbered{% + \!tickcase=1 + \!nextkeyword} + +\def\!tickswithvalues#1/ {% + \edef\!tickvalueslist{#1! /}% + \!tickcase=2 + \!nextkeyword} + +\def\!ticksquantity#1 {% + \ifnum #1>1 + \!updatetickoffset + \!countA=#1\relax + \advance \!countA -1 + \!ticklocationincr=\!axisLength + \divide \!ticklocationincr \!countA + \!ticklocation=\!axisstart + \loop \!not{\ifdim \!ticklocation>\!axisend} + \!placetick\!ticklocation + \ifcase\!tickcase + \relax % Case 0: no labels + \or + \relax % Case 1: numbered -- not available here + \or + \expandafter\!gettickvaluefrom\!tickvalueslist + \edef\!tickfield{{\the\!ticklocation}{\!value}}% + \expandafter\!listaddon\expandafter{\!tickfield}\!LTlist% + \fi + \advance \!ticklocation \!ticklocationincr + \repeat + \fi + \!nextkeyword} + +\def\!ticksat#1 {% + \!updatetickoffset + \edef\!Loc{#1}% + \if /\!Loc + \def\next{\!nextkeyword}% + \else + \!ticksincommon + \def\next{\!ticksat}% + \fi + \next} + +\def\!ticksfrom#1 to #2 by #3 {% + \!updatetickoffset + \edef\!arg{#3}% + \expandafter\!separate\!arg\!nil + \!scalefactor=1 + \expandafter\!countfigures\!arg/ + \edef\!arg{#1}% + \!scaleup\!arg by\!scalefactor to\!countE + \edef\!arg{#2}% + \!scaleup\!arg by\!scalefactor to\!countF + \edef\!arg{#3}% + \!scaleup\!arg by\!scalefactor to\!countG + \loop \!not{\ifnum\!countE>\!countF} + \ifnum\!scalefactor=1 + \edef\!Loc{\the\!countE}% + \else + \!scaledown\!countE by\!scalefactor to\!Loc + \fi + \!ticksincommon + \advance \!countE \!countG + \repeat + \!nextkeyword} + +\def\!updatetickoffset{% + \!dimenA=\!ticksinoutsign\!ticklength + \ifdim \!dimenA>\!offset + \!offset=\!dimenA + \fi} + +\def\!placetick#1{% + \if!xswitch + \!xpos=#1\relax + \!ypos=\!axisylevel + \else + \!xpos=\!axisxlevel + \!ypos=#1\relax + \fi + \advance\!xpos \!Xsave + \advance\!ypos \!Ysave + \kern\!xpos\raise\!ypos\copy\!boxA\kern-\!xpos + \ignorespaces} + +\def\!gettickvaluefrom#1 #2 /{% + \edef\!value{#1}% + \edef\!tickvalueslist{#2 /}% + \ifx \!tickvalueslist\!endtickvaluelist + \!tickcase=0 + \fi} +\def\!endtickvaluelist{! /} + +\def\!ticksincommon{% + \!ticktransform\!Loc\!t + \!ticklocation=\!t\!!unit + \advance\!ticklocation -\!!origin + \!placetick\!ticklocation + \ifcase\!tickcase + \relax % Case 0: no labels + \or % Case 1: numbered + \ifdim\!ticklocation<-\!!origin + \edef\!Loc{$\!Loc$}% + \fi + \edef\!tickfield{{\the\!ticklocation}{\!Loc}}% + \expandafter\!listaddon\expandafter{\!tickfield}\!LTlist% + \or % Case 2: labeled + \expandafter\!gettickvaluefrom\!tickvalueslist + \edef\!tickfield{{\the\!ticklocation}{\!value}}% + \expandafter\!listaddon\expandafter{\!tickfield}\!LTlist% + \fi} + +\def\!separate#1\!nil{% + \!ifnextchar{-}{\!!separate}{\!!!separate}#1\!nil} +\def\!!separate-#1\!nil{% + \def\!sign{-}% + \!!!!separate#1..\!nil} +\def\!!!separate#1\!nil{% + \def\!sign{+}% + \!!!!separate#1..\!nil} +\def\!!!!separate#1.#2.#3\!nil{% + \def\!arg{#1}% + \ifx\!arg\!empty + \!countA=0 + \else + \!countA=\!arg + \fi + \def\!arg{#2}% + \ifx\!arg\!empty + \!countB=0 + \else + \!countB=\!arg + \fi} + +\def\!countfigures#1{% + \if #1/% + \def\!next{\ignorespaces}% + \else + \multiply\!scalefactor 10 + \def\!next{\!countfigures}% + \fi + \!next} + +\def\!scaleup#1by#2to#3{% + \expandafter\!separate#1\!nil + \multiply\!countA #2\relax + \advance\!countA \!countB + \if -\!sign + \!countA=-\!countA + \fi + #3=\!countA + \ignorespaces} + +\def\!scaledown#1by#2to#3{% + \!countA=#1\relax% ** get original # + \ifnum \!countA<0 % ** take abs value, + \def\!sign{-}% ** remember sign + \!countA=-\!countA + \else + \def\!sign{}% + \fi + \!countB=\!countA% ** copy |#| + \divide\!countB #2\relax% ** integer part (|#|/sf) + \!countC=\!countB% ** get sf * (|#|/sf) + \multiply\!countC #2\relax + \advance \!countA -\!countC% ** ctA is now remainder + \edef#3{\!sign\the\!countB.}% ** +- integerpart. + \!countC=\!countA % ** Tack on proper number + \ifnum\!countC=0 % ** of zeros after . + \!countC=1 + \fi + \multiply\!countC 10 + \!loop \ifnum #2>\!countC + \edef#3{#3\!zero}% + \multiply\!countC 10 + \repeat + \edef#3{#3\the\!countA}% ** Add on rest of remainder + \ignorespaces} + +\def\!placetickvalues{% + \advance\!offset \tickstovaluesleading + \if!xswitch + \setbox\!boxA=\hbox{% + \def\\##1##2{% + \!dimenput {##2} [B] (##1,\!axisylevel)}% + \beginpicture + \!LTlist + \endpicturesave <\!Xsave,\!Ysave>}% + \!dimenA=\!axisylevel + \advance\!dimenA -\!Ysave + \advance\!dimenA \!tickysign\!offset + \if -\!tickysign + \advance\!dimenA -\ht\!boxA + \else + \advance\!dimenA \dp\!boxA + \fi + \advance\!offset \ht\!boxA + \advance\!offset \dp\!boxA + \!dimenput {\box\!boxA} [Bl] <\!Xsave,\!Ysave> (\!zpt,\!dimenA) + \else + \setbox\!boxA=\hbox{% + \def\\##1##2{% + \!dimenput {##2} [r] (\!axisxlevel,##1)}% + \beginpicture + \!LTlist + \endpicturesave <\!Xsave,\!Ysave>}% + \!dimenA=\!axisxlevel + \advance\!dimenA -\!Xsave + \advance\!dimenA \!tickxsign\!offset + \if -\!tickxsign + \advance\!dimenA -\wd\!boxA + \fi + \advance\!offset \wd\!boxA + \!dimenput {\box\!boxA} [Bl] <\!Xsave,\!Ysave> (\!dimenA,\!zpt) + \fi} + + +\normalgraphs + +% \catcode`!=12 % ***** THIS MUST NEVER BE OMITTED + +\protect \endinput diff --git a/tex/context/base/thrd-ran.mkii b/tex/context/base/thrd-ran.mkii new file mode 100644 index 000000000..276a4f624 --- /dev/null +++ b/tex/context/base/thrd-ran.mkii @@ -0,0 +1,168 @@ +% Since we cannot be sure that this file is available at any +% system, we have copied the original in this file. These +% macros are encapsulates and extended in supp-ran.tex. +% +% This module is slightly recoded to bring it more in tune +% with \CONTEXT's scratch registers and protection mechanisms. + +% RANDOM.TEX v.1 (Donald Arseneau) +% Generating "random" numbers in TeX. +% +% Random integers are generated in the range 1 to 2147483646 by the +% macro \nextrandom. The result is returned in the counter \randomi. +% Do not change \randomi except, perhaps, to initialize it at some +% random value. If you do not initialize it, it will be initialized +% using the time and date. (This is a sparse initialization, giving +% fewer than a million different starting values, but you should use +% other sources of numbers if they are available--just remember that +% most of the numbers available to TeX are not at all random.) +% +% The \nextrandom command is not very useful by itself, unless you +% have exactly 2147483646 things to choose from. Much more useful +% is the \setrannum command which sets a given counter to a random +% value within a specified range. There are three parameters: +% \setrannum {} {} {}. For example, to +% simulate a die-roll: \setrannum{\die}{1}{6} \ifcase\die... . +% +% If you need random numbers that are not integers, you will have to +% use dimen registers and \setrandimen. For example, to set a random +% page width: \setrandimen \hsize{3in}{6.5in}. The "\pointless" macro +% will remove the "pt" that TeX gives so you can use the dimensions +% as pure `real' numbers. In that case, specify the range in pt units. +% For example, +% +% \setrandimen\answer{2.71828pt}{3.14159pt} +% The answer is \pointless\answer. +% +% The random number generator is the one by Lewis, Goodman, and Miller +% (1969) and used as "ran0" in "Numerical Recipies" using Schrage's +% method for avoiding overflows. The multiplier is 16807 (7^5), the +% added constant is 0, and the modulus is 2147483647 (2^{31}-1). The +% range of integers generated is 1 - 2147483646. A smaller range would +% reduce the complexity of the macros a bit, but not much--most of the +% code deals with initialization and type-conversion. On the other hand, +% the large range may be wasted due to the sparse seed initialization. + +% original code +% +% \newcount\randomi % the random number seed (while executing) +% \global\randomi\catcode`\@ % scratch variable during definitions +% \catcode`\@=11 +% +% \def\nextrandom{\begingroup +% \ifnum\randomi<\plusone % then initialize with time +% \global\randomi\time +% \global\multiply\randomi388 \global\advance\randomi\year +% \global\multiply\randomi31 \global\advance\randomi\day +% \global\multiply\randomi97 \global\advance\randomi\month +% \message{Randomizer initialized to \the\randomi.}% +% \nextrandom \nextrandom \nextrandom +% \fi +% \count@ii\randomi +% \divide\count@ii 127773 % modulus = multiplier * 127773 + 2836 +% \count@\count@ii +% \multiply\count@ii 127773 +% \global\advance\randomi-\count@ii % random mod 127773 +% \global\multiply\randomi 16807 +% \multiply\count@ 2836 +% \global\advance\randomi-\count@ +% \ifnum\randomi<\z@ \global\advance\randomi 2147483647\relax\fi +% \endgroup +% } +% +% \countdef\count@ii=2 % use only in boxes! +% \ifx\@tempcnta\undefined \csname newcount\endcsname \@tempcnta \fi +% \ifx\@tempcntb\undefined \csname newcount\endcsname \@tempcntb \fi +% +% \def\setrannum#1#2#3{% count register, minimum, maximum +% \@tempcnta#3\advance\@tempcnta-#2\advance\@tempcnta\@ne +% \@tempcntb 2147483645 % = m - 2 = 2^{31} - 3 +% \divide\@tempcntb\@tempcnta +% \getr@nval +% \advance\ranval#2\relax +% #1\ranval +% } +% +% \def\setrandim#1#2#3{% dimen register, minimum length, maximum length +% \dimen@#2\dimen@ii#3\relax +% \setrannum\ranval\dimen@\dimen@ii +% #1\ranval sp\relax +% } +% +% \def\getr@nval{% The values in \@tempcnta and \@tempcntb are parameters +% \nextrandom +% \ranval\randomi \advance\ranval\m@ne \divide\ranval\@tempcntb +% \ifnum\ranval<\@tempcnta\else \expandafter\getr@nval \fi +% } +% +% %D The next macro is not needed in \CONTEXT, which provides +% %D the \type {\withoutpt} macro. +% %D +% %D \starttyping +% %D \def\pointless{\expandafter\PoinTless\the} +% %D {\catcode`p=12 \catcode`t=12 \gdef\PoinTless#1pt{#1}} +% %D \stoptyping +% +% \catcode`\@=\randomi +% \global\randomi=0 +% \newcount\ranval + +% the recoded version, using \CONTEXT\ methods and variables; +% the magic is kept untouched + +\unprotect + +\newcount\randomi % the random number seed (while executing) +\newcount\ranval + +\ifx\m!systems\undefined \def\m!systems{systems} \fi + +\def\nextrandom + {\begingroup + \ifnum\randomi<\plusone % then initialize with time + \global\randomi\time + \global\multiply\randomi388 \global\advance\randomi\year + \global\multiply\randomi 31 \global\advance\randomi\day + \global\multiply\randomi 97 \global\advance\randomi\month + \writestatus\m!systems{randomizer starts with \the\randomi}% + \nextrandom \nextrandom \nextrandom + \fi + \!!countd\randomi + \divide\!!countd 127773 % modulus = multiplier * 127773 + 2836 + \!!countc\!!countd + \multiply\!!countd 127773 + \global\advance\randomi-\!!countd % random mod 127773 + \global\multiply\randomi 16807 + \multiply\!!countc 2836 + \global\advance\randomi-\!!countc\relax + \ifnum\randomi<\zerocount + \global\advance\randomi 2147483647 + \fi + \endgroup} + +\def\setrannum#1#2#3% count register, minimum, maximum + {\!!counta#3% + \advance\!!counta-#2% + \advance\!!counta\plusone + \!!countb 2147483645 % = m - 2 = 2^{31} - 3 + \divide\!!countb\!!counta + \getr@nval + \advance\ranval#2% + #1\ranval} + +\def\setrandim#1#2#3% dimen register, minimum length, maximum length + {\!!dimenc#2% + \!!dimend#3% + \setrannum\ranval\!!dimenc\!!dimend + #1\ranval\s!sp\relax} % \s!sp not needed + +\def\getr@nval % The values in \!!counta and \!!countb are parameters + {\nextrandom + \ranval\randomi + \advance\ranval\minusone + \divide\ranval\!!countb + \ifnum\ranval<\!!counta \else + \expandafter\getr@nval + \fi} + +\protect \endinput diff --git a/tex/context/base/thrd-tab.tex b/tex/context/base/thrd-tab.tex new file mode 100644 index 000000000..dd3838ce2 --- /dev/null +++ b/tex/context/base/thrd-tab.tex @@ -0,0 +1,2006 @@ +% Since this file is not available in every distribution, we +% have copied the original in this file. The manuals to +% Wichura's PiCTeX and TaBlE packages are not available on +% line and are distributed by respectively the TeX Users Group +% and Personal TeX Inc. Many macros of TaBlE are overloaded +% and/or extended in core-tab.tex. The extensions concern +% splitting over pages, color and consistent spacing. + +% We've patched this file for catcode ! because in luatex we use +% catcode tables and using unprotect/protect is cleaner. Late +% 2007 we also decided no longer to treat quotes and bars the +% TaBLe way and instead of messy pushing and popping of catcodes +% we commented a couple of lines here. We just assume that the +% template has no active bar and quote. Inside tables we now +% have the regular meaning of active bars in ConTeXt. More +% drastic extensions and patched can be found in core-tab.tex. + +% TABLE 1.0 +% Copyright Michael J. Wichura August 1988 (patched by Hans Hagen) + +% The TABLE macros are divided into sections, roughly according to +% function: + +% Section Name Function +% a Allocation Allocates storage registers for parameters. +% f Format Reads format section; builds preamble for \halign; +% processes \ReFormat command. +% g Get Value Converts "spec"'s (as in spec_{LT}) to +% corresponding "values"'s (as in value_{LT}). +% h Hacks Utility macros; error messages; miscellaneous commands. +% k Keys Definition and scanning of format keys. +% n Numeric Macros for TABLE's numeric format. +% s Struts Macros for struts. +% t Tables Sets up \halign for table; end-of-row processing; +% alternate vertical rules; spanning; horizontal +% lines; stretching and shrinking; repositioning +% commands. + +% The name of each internal macro begins with the prefix "\!t", the +% "!" having category code 11, followed by the letter of the section +% in which the macro is defined. For example, a macro beginning "\!th" +% is defined in Section h (Hacks). There a few exceptions: +% the general purpose macros "\!ttemp", "\!ttempa", "\!ttempb", and +% "\!tnext" are repeatedly defined on the spot as the need arises. + +% External macros (and active characters) are defined in the following +% sections: +% Macro Section +% " t +% \- t +% \= t +% \ActivateBarAndQuote h +% \AugmentedTableStrut s +% \BackSpace h +% \BeginFormat f +% \BeginTable t +% \BeginTableParBox a +% \Center t +% \ColumnWidthFactor a +% \ColumnWidthUnit a +% \DQuote h +% \EndFormat k (\EndFormat is actually a key) +% \EndTable t +% \EndTableParBox a +% \Enlarge s +% \enlarge s +% \EveryTable a +% \EveryTableParBox a +% \Expand t +% \InterColumnSpaceFactor a +% \InterColumnSpaceUnit a +% \JustCenter t +% \JustLeft t +% \JustRight t +% \KernFactor a +% \KernUnit a +% \Left t +% \LeftTabskip a +% \LineThicknessFactor a +% \LineThicknessUnit a +% \LongLines t +% \Lower h +% \MakeStrut s +% \NewFormatKey k +% \NormalCWU a +% \NormalICSU a +% \NormalKU a +% \NormalLTU a +% \NormalSU a +% \NormalTableUnits a +% \OpenUp s +% \PseudoVrule t +% \Raise h +% \ReadFormatKeys k +% \ReFormat f +% \Right t +% \RightTabskip a +% \SetTableToWidth t +% \Smash h +% \StandardTableStrut s +% \StrutDepthFactor a +% \StrutHeightFactor a +% \StrutUnit a +% \TaBlE h +% \TracingFormats a +% \TracingKeys a +% \Use t +% \use t +% \VBar h +% \Vspace h +% \VspaceFactor a +% \WidenTableBy t +% \\ t +% \_ t +% \| t +% | t +% ~ t + +\unprotect + +% \catcode `\!=11 +% \catcode `\@=11 + +\newif\ifh@ % normally in plain tex +\newif\ifv@ % normally in plain tex + +% Don't try to read the TABLE macros until after you've read the +% TABLE manual. The internal documentation of the macros is +% sketchy; you need the manual to understand what's going on. +% You should also review the material on \halign s in the TeXbook, +% since TABLE uses an \halign to perform its alignments. + +% In studying the TABLE macros, you should start by skimming the +% macros in the "miscellaneous hacks", "error messages", and "loops" +% subsections of Section h, as well as the "\GetValue" macro in +% Section g; these macros are called many times by the other macros. +% To continue with a "bottom-up" approach, read next Sections k, +% f, and t. (Top-downers should reverse the order.) The other +% Sections can be looked at as the need arises. + +% ********************************************************************* +% SECTION A: ALLOCATION +% ********************************************************************* + +\let\!tacr=\\ % Save meaning of \\ (Needed if TABLE is used with LaTeX + +% ********************************************************************* +% TABLE PARAMETERS: Units +% ********************************************************************* + +\newdimen\LineThicknessUnit +\newdimen\StrutUnit +\newskip \InterColumnSpaceUnit +\newdimen\ColumnWidthUnit +\newdimen\KernUnit + +\let\!taLTU=\LineThicknessUnit % Used in preamble +\let\!taCWU=\ColumnWidthUnit % Used in preamble +\let\!taKU =\KernUnit % Used in preamble + +\newtoks\NormalTLTU +\newtoks\NormalTSU +\newtoks\NormalTICSU +\newtoks\NormalTCWU +\newtoks\NormalTKU + +% NOTE: The user should modify the following DEFAULTS to suit his/her +% taste, and output device: +%\def\PixelsPerInch{300} +\NormalTLTU={1in \divide \LineThicknessUnit by 300 } +\NormalTSU ={\normalbaselineskip + \divide \StrutUnit by 11 } % 11 = 8+3 = NormalT Height+Depth Factors +\NormalTICSU={.5em plus 1fil minus .25em} % .5em = width of a digit +\NormalTCWU ={.5em} +\NormalTKU ={.5em} + +\def\NormalTableUnits{% + \LineThicknessUnit =\the\NormalTLTU + \StrutUnit =\the\NormalTSU + \InterColumnSpaceUnit=\the\NormalTICSU + \ColumnWidthUnit =\the\NormalTCWU + \KernUnit =\the\NormalTKU} + +\NormalTableUnits + +% The user should issue \NormalTableUnits when setting a table +% in a different point size, since the Table...Units themselves +% are static while the Normal...Units vary with the point size. + + +% ********************************************************************* +% TABLE PARAMETERS: Factors +% ********************************************************************* + +\newcount\LineThicknessFactor +\newcount\StrutHeightFactor +\newcount\StrutDepthFactor +\newcount\InterColumnSpaceFactor +\newcount\ColumnWidthFactor +\newcount\KernFactor +\newcount\VspaceFactor + +% DEFAULTS: +\LineThicknessFactor =2 +\StrutHeightFactor =8 +\StrutDepthFactor =3 +\InterColumnSpaceFactor =3 +\ColumnWidthFactor =10 +\KernFactor =1 +\VspaceFactor =2 + + +% ********************************************************************* +% DIAGNOSTIC PARAMETERS +% ********************************************************************* + +\newcount\TracingKeys % >=1 reports new keys, >=2 reports key usage +\newcount\TracingFormats % >=1 reports templates for columns + % >=2 reports \halign preamble + + +% ********************************************************************* +% PARBLOCK PARAMETERS +% ********************************************************************* + +\def\BeginTableParBox#1{% + \vtop\bgroup + \hsize=#1 + \normalbaselines + \let~=\!ttTie + \let\-=\!ttDH + \the\EveryTableParBox} + +\def\EndTableParBox{% + \MakeStrut{0pt}{\StrutDepthFactor\StrutUnit} + \egroup} % finishes the \vtop begun by \BeginTableParbox + +\newtoks\EveryTableParBox +\EveryTableParBox={% + \parindent=0pt + \raggedright + \rightskip=0pt plus 4em % Provide more stretch + \relax} + + +% ********************************************************************* +% EVERY TABLE TOKENS +% ********************************************************************* + +\newtoks\EveryTable +\newtoks\!taTableSpread + + +% ********************************************************************* +% Extreme left- and right- tabskips +% ********************************************************************* + +\newskip\LeftTabskip +\newskip\RightTabskip + + +% ********************************************************************* +% INTERNAL VARIABLES +% ********************************************************************* + +\newcount\!taCountA +\newcount\!taColumnNumber +\newcount\!taRecursionLevel % (Initially 0) + +\newdimen\!taDimenA % used by \Enlarge +\newdimen\!taDimenB % used by \Enlarge +\newdimen\!taDimenC % used by numeric.tex +\newdimen\!taMinimumColumnWidth + +\newtoks\!taToksA + +\newtoks\!taPreamble +\newtoks\!taDataColumnTemplate +\newtoks\!taRuleColumnTemplate +\newtoks\!taOldRuleColumnTemplate +\newtoks\!taLeftGlue +\newtoks\!taRightGlue + +\newskip\!taLastRegularTabskip + +\newif\if!taDigit +\newif\if!taBeginFormat +\newif\if!taOnceOnlyTabskip + + + +% ********************************************************************* +% SECTION H: HACKS +% ********************************************************************* + +% **************************************************************** +% TABLE LOGO +% **************************************************************** +\def\TaBlE{% + T\kern-.27em\lower.5ex\hbox{A}\kern-.18em B\kern-.1em + \lower.5ex\hbox{L}\kern-.075em E} + + +% **************************************************************** +% ACTIVE CHARACTERS +% **************************************************************** + +% ACTIVATE BAR AND QUOTE: Makes | and " active if they aren't +% already active (in which case the user will probably have given +% them special meanings); definitions are provided which effectively +% undoes the activeness outside a Table. + +{\catcode`\|=13 \catcode`\"=13 + \gdef\ActivateBarAndQuote{% + \ifnum \catcode`\|=13 + \else + \catcode`\|=13 + \def|{% + \ifmmode + \vert + \else + \char`\| + \fi}% + \fi + \ifnum \catcode`\"=13 + \else + \catcode`\"=13 + \def"{\char`\"}% + \fi}} + +% **************************************************************** +% Macros for | and " having category code 12. +% **************************************************************** +{\catcode `\|=12 \catcode `\"=12 +\gdef\VBar{|} +\gdef\DQuote{"}} + + +% **************************************************************** +% MISCELANEOUS HACKS +% **************************************************************** + +% MESSAGE : Writes out to terminal and log file. +\def\!thMessage#1{\immediate\write16{#1}\ignorespaces} + +% X: Abbreviation for expandafter +\let\!thx=\expandafter + +% GOBBLE: Eats next token +\def\!thGobble#1{} + +% SPACE TOKEN +\def\\{\let\!thSpaceToken= }\\ + +% HEIGHT, DEPTH, AND WIDTH +\def\!thHeight{height} +\def\!thDepth{depth} +\def\!thWidth{width} + +% TOKSEDEF =: Places , fully expanded a la \edef, in the specified . +\def\!thToksEdef#1=#2{% + \edef\!ttemp{#2}% + #1\!thx{\!ttemp}% + \ignorespaces} + + +% **************************************************************** +% ERROR MESSAGES +% **************************************************************** + +% STORE ERROR MSG +% Replacement text of is a macro with Message +% as its name. E.g., after \StoreErrorMsg\Help{Type }, +% \Help expands to "\Type " +\def\!thStoreErrorMsg#1#2{% + \toks0 =\!thx{\csname #2\endcsname}% + \edef#1{\the\toks0 }} + +% READ ERROR MSG +% Continuing the above example, \ReadErrorMsg\Help produces "Type " +\def\!thReadErrorMsg#1{% + \!thx\!thx\!thx\!thGobble\!thx\string #1} + +% ERROR +\def\!thError#1#2{% + \begingroup + \newlinechar=`\^^J% + \edef\!ttemp{#2}% + \errhelp=\!thx{\!ttemp}% + \!thMessage{% + ^^J\!thReadErrorMsg\!thErrorMsgA + ^^J\!thReadErrorMsg\!thErrorMsgB}% + \errmessage{#1}% + \endgroup} + +% TEXT FOR ERROR MESSAGE +\!thStoreErrorMsg\!thErrorMsgA{% + TABLE error; see manual for explanation.} +\!thStoreErrorMsg\!thErrorMsgB{% + Type \space H \space for immediate help.} + +% GET REPLACEMENT +% must be a control sequence +\def\!thGetReplacement#1#2{% + \begingroup + \!thMessage{#1} + \endlinechar=-1 + \global\read16 to#2% + \endgroup} + + +% **************************************************************** +% LOOP MACRO +% **************************************************************** + +% LOOP ... REPEAT macro from TUGboat Vol 8 #2: 1987 +% Syntax is like that of plain TeX's \loop ... \repeat macro +\def\!thLoop#1\repeat{% + \def\!thIterate{% + #1% + \!thx \!thIterate + \fi}% + \!thIterate + \let\!thIterate\relax} + + +% *************************************************************** +% VERTICALLY-CENTERED SMASH +% *************************************************************** + +% SMASH: Like TeX's \smash, only the argument +% is centered vertically before its height and depth are smashed to 0pt. +\def\Smash{% + \relax + \ifmmode + \expandafter\mathpalette + \expandafter\!thDoMathVCS + \else + \expandafter\!thDoVCS + \fi} + +% DO VCS +\def\!thDoVCS#1{% + \setbox\zerocount\hbox{#1}% + \!thFinishVCS} + +% DO MATH VCS +\def\!thDoMathVCS#1#2{% + \setbox\zerocount\hbox{$\mathsurround\zeropoint#1{#2}$}% + \!thFinishVCS} + +% FINISH VCS +\def\!thFinishVCS{% + \vbox to\zeropoint{\vss\box\zerocount\vss}} + + +% *************************************************************** +% RAISE AND LOWER +% *************************************************************** + +% Like TeX's \raise and \lower, except: (1) The first argument +% to these commands is a dimension expressed in TABLE's usual conventions; +% the default is (StrutHeightFactor+StrutDepthFactor)*StrutUnit/2 +% (2) like \smash, these commands function in math mode as well +% as horizontal mode; (3) again like \smash, the result is declared +% to have height and depth 0pt + +% Examples \Raise2{Stuff}: "Stuff" is raised 2*StrutUnit +% \Raise {Stuff}: "Stuff" is raised a half-line +% $\Lower(10pt){\alpha}$: "$\alpha$" is lowered 10 points + +% RAISE +\def\Raise{% + \def\!thSign{+}% + \!tgGetValue\!thSetDimen} + +% LOWER +\def\Lower{% + \def\!thSign{-}% + \!tgGetValue\!thSetDimen} + +% SET DIMEN +\def\!thSetDimen{% + \ifnum \!tgCode=1 + \ifx \!tgValue\empty + \!taDimenA \StrutHeightFactor\StrutUnit + \advance \!taDimenA \StrutDepthFactor\StrutUnit + \divide \!taDimenA 2 + \else + \!taDimenA \!tgValue\StrutUnit + \fi + \else + \!taDimenA \!tgValue + \fi + \!taDimenA=\!thSign\!taDimenA\relax + % + % BRANCH ON MODE + \ifmmode + \expandafter\mathpalette + \expandafter\!thDoMathRaise + \else + \expandafter\!thDoSimpleRaise + \fi} + +% DO SIMPLE RAISE +\def\!thDoSimpleRaise#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\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\zerocount\zeropoint + \dp\zerocount\zeropoint + \box\zerocount} + + +% *************************************************************** +% BACK SPACE +% *************************************************************** +\def\BackSpace{% + \!tgGetValue\!thKernBack} + +\def\!thKernBack{% + \kern - + \ifnum \!tgCode=1 + \ifx \!tgValue\empty + \the\KernFactor + \else + \!tgValue % user-specified integer + \fi + \KernUnit + \else + \!tgValue % user-specified dimension + \fi + \ignorespaces}% + + +% *************************************************************** +% Vspace +% *************************************************************** +\def\Vspace{% + \noalign + \bgroup + \!tgGetValue\!thVspace} + +\def\!thVspace{% + \vskip + \ifnum \!tgCode=1 + \ifx \!tgValue\empty + \the\VspaceFactor + \else + \!tgValue % user-specified integer + \fi + \StrutUnit + \else + \!tgValue % user-specified skip + \fi + \egroup} % Ends the \noalign + +% ********************************************************************* +% SECTION F: FORMAT +% ********************************************************************* + +% As explained in Section 3.3 of the manual, TABLE alternates each +% of the user's "data" columns with a "rule" column; moreover, TABLE +% places a "dummy data" column at the left and right of a table. +% A table with n nominal data columns therefore actually has a +% total of +% n (nominal data columns) +% +(n+1) (rule columns) +% + 2 (dummy data columns) +% ____ +% 2n+3 +% columns. + +% FORMATs job is to create an \halign preamble for the alignment +% of these (2n+3) columns. The preamble consists of templates +% for the various columns, strung together with &'s and interlaced +% with \tabskip glue specifications. + +% FORMAT constructs the template for a nomimal data column according +% to the user-specified format keys. As the keys are read from left +% to right, the template is built up "from the inside out" (as +% illustrated in Section 3.1.9 of the manual), the inner-most part +% being the "#" sign. A "|" in the format terminates template +% building; the completed template is adjoined to preamble along +% with the template for the following rule column. + +% Minimum column widths, if specified, are implemented by creating +% an "artificial row" with data entries of the form +% \hskip . +% This row has zero height and depth and is completely invisible. + + +% BEGIN FORMAT +\def\BeginFormat{% + %catcode`\|=12 % Inhibit expansion if | immediately follows a + %catcode`\"=12 % read by \getvalue. + \!taPreamble={}% + \!taColumnNumber=0 + \skip0 =\InterColumnSpaceUnit + \multiply\skip0 \InterColumnSpaceFactor + \divide\skip0 2 + \!taRuleColumnTemplate=\!thx{% + \!thx\tabskip\the\skip0 }% + \!taLastRegularTabskip=\skip0 + \!taOnceOnlyTabskipfalse + \!taBeginFormattrue % Used to intercept key "]" + \def\!tfRowOfWidths{}% Artificial Table Row with horizontal struts + % to enforce specified minimum column widths + \ReadFormatKeys} + +% SET (MINIMUM COLUMN) WIDTH: Invoked by the key "w". +\def\!tfSetWidth{% + \ifx \!tfRowOfWidths \empty % true if no prior "w" keys + \ifnum \!taColumnNumber>0 % true if "w" key is to right of first "|" + \begingroup % RowOfWidths={&\omit || n copies of + % &\omit&\omit}, where n = number of columns + \!taCountA=1 % to the left of this one + \aftergroup \edef \aftergroup \!tfRowOfWidths \aftergroup {% + \aftergroup &\aftergroup \omit + \!thLoop + \ifnum \!taCountA<\!taColumnNumber + \advance\!taCountA 1 + \aftergroup \!tfAOAO + \repeat + \aftergroup }% + \endgroup + \fi + \fi + \ifx [\!ttemp % \!tgGetValue sets \!ttemp = token after w + \!thx\!tfSetWidthText + \else + \!thx\!tfSetWidthValue + \fi} + +% AOAO = (Apersand Omit Ampersand Omit) +\def\!tfAOAO{% + &\omit&\omit} + +% SET WIDTH TEXT +\def\!tfSetWidthText [#1]{% #1 = specified text + \def\!tfWidthText{#1}% + \ReadFormatKeys} + +% SET WIDTH VALUE +\def\!tfSetWidthValue{% + \!taMinimumColumnWidth = + \ifnum \!tgCode=1 + \ifx\!tgValue\empty % Use default multiplier if user didn't specify one + \ColumnWidthFactor + \else + \!tgValue + \fi + \ColumnWidthUnit + \else + \!tgValue + \fi + \def\!tfWidthText{}% Override possible prior `w[sample entry]' + \ReadFormatKeys} + + +% SET TABSKIP: Invoked by the tabskip keys "t" and "o" +\def\!tfSetTabskip{% + \ifnum \!tgCode=1 + \skip0 =\InterColumnSpaceUnit + \multiply\skip0 + \ifx \!tgValue\empty + \InterColumnSpaceFactor % Default integer + \else + \!tgValue % User-specified integer + \fi + \else + \skip0 =\!tgValue % User-specified + \fi + \divide\skip0 by 2 + \ifnum\!taColumnNumber=0 + \!thToksEdef\!taRuleColumnTemplate={% + \the\!taRuleColumnTemplate + \tabskip \the\skip0 } + \else + \!thToksEdef\!taDataColumnTemplate={% + \the\!taDataColumnTemplate + \tabskip \the\skip0 } + \fi + \if!taOnceOnlyTabskip + % % Tabskip used at right of this col only + \else + \!taLastRegularTabskip=\skip0 % Remember this Tabskip, for possible + \fi % restoration after a subsequent"OnceOnly" + \ReadFormatKeys} + + +% SET VRULE: Invoked by the key "|" +\def\!tfSetVrule{% + \!thToksEdef\!taRuleColumnTemplate={% + \noexpand\hfil + \noexpand\vrule + \noexpand\!thWidth + \ifnum \!tgCode=1 + \ifx \!tgValue\empty + \the\LineThicknessFactor % Default integer + \else + \!tgValue % User-specified integer + \fi + \!taLTU % \LineThicknessUnit + \else + \!tgValue % User-specified dimension + \fi + ####% + \noexpand\hfil + \the\!taRuleColumnTemplate} % has \tabskips, when column number=0 + \!tfAdjoinPriorColumn} + +% SET ALTERNATE VRULE: Invoked by the key "\|", in the form +% \|{